[
  {
    "path": ".gitignore",
    "content": "data\n.idea\n*.iml\ntatami.iml\ntatami.ipr\ntatami.iws\n.classpath\n.project\n.settings\ntarget\nnode_modules/\nweb/node_modules/\nsrc/main/webapp/WEB-INF/generated-wro4j\n.merge_file*\n.DS_Store\nphantomjsdriver.log\n*.log\nweb/src/main/webapp/app/**/*.CONCAT.js\nweb/src/main/webapp/app/**/*.min.html\nweb/src/main/webapp/app/**/*.min.js\nweb/src/main/webapp/app/**/*.MIN.css\nweb/src/main/webapp/app/**/*.min.css\nweb/src/main/webapp/css/tatami.min.css\nsrc/main/webapp/app/shared/footer/FooterView.html.sed.del\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "Contributing to Tatami\n=========================\n\nOpen Source\n------------------\n\nTatami is an Open Source project, which uses the Apache 2 [http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)\nlicense. If you contribute to Tatami, you agree that your code belongs to the Tatami project and follows this license.\n\nSubmitting code\n------------------\n\n* Create a [GitHub account](https://github.com/signup/free).\n* [Submit a ticket for your issue](https://github.com/ippontech/tatami/issues), assuming one does not already exist.\n  * Clearly describe the issue including steps to reproduce it, when it is a bug.\n* Fork the repository on GitHub.\n* Make commits of logical units.\n* Make sure your commit messages include the ticket number you have created. Github should automatically link\nyour changes with the ticket.\n* Make sure you have added the necessary tests for your changes.\n* Run _all_ the tests to assure nothing else was accidentally broken.\n* Push your changes in your fork of the repository.\n* Submit a pull request to [the repository in the ippontech organization](https://github.com/ippontech/tatami).\n  * If you need help about making a pull request, [here is the documentation](https://help.github.com/articles/using-pull-requests).\n* Your code will be automatically built by [Buildhive](https://buildhive.cloudbees.com/job/ippontech/job/tatami/). Your\npull request should have a Buildhive comment a few minutes after your commit.\n\n"
  },
  {
    "path": "README.md",
    "content": "Tatami\n================\n\nPresentation\n------------------\n\nTatami is an Open Source enterprise social network.\n\nA public installation of Tatami is provided by [Ippon Technologies](http://www.ippon.fr) at : [https://tatami.ippon.fr](https://tatami.ippon.fr)\n\nTatami is made with the following technologies :\n\n- HTML5, [AngularJS](https://angularjs.org/) and [Twitter Bootstrap](http://twitter.github.com/bootstrap/)\n- [The Spring Framework](http://www.springsource.org/)\n- [Apache Cassandra](http://cassandra.apache.org/)\n- [Elastic Search](http://www.elasticsearch.org/)\n\nTatami is developed by [Ippon Technologies](http://www.ippon.fr)\n\n\nInstallation for developers\n---------------------------------------\n\n### 5 minute installation\n\n- Clone, fork or download the source code from this Github page\n- Install [Maven 3](http://maven.apache.org/)\n- Install [npm](https://www.npmjs.com/)\n- Point your terminal to the directory you cloned Tatami to.\n    - `cd web`\n    - Type `npm install`\n    - You may need to give root user permissions: `sudo !!`\n    - `cd ..`\n- Run Cassandra with Maven : `mvn cassandra:run`\n- Run Jetty from tatami/web with Maven: `mvn jetty:run`\n- Connect to the application at http://127.0.0.1:8080\n\n\nTo create users, use the registration form. As we have not configured a SMTP server (you can configure it in src/main/resources/META-INF/tatami/tatami.properties - see below \"installation for production use\" for more options), the validation URL as well as the password will not be e-mailed to you, but you can see them in the log (look at the Jetty console output).\n\n### Using Tomcat instead of Jetty\n\nIf you want to use Tomcat instead of Jetty (which works better in development mode on Windows), just use :\n\n- Run Tomcat from Maven : `mvn tomcat7:run`\n\n### Maven tuning and troubleshooting\n\nIf you run into some Permgen or OutOfMemory errors, you can configure your Maven settings accordingly :\n```\nexport MAVEN_OPTS=\"-XX:PermSize=64m -XX:MaxPermSize=128m -Xms256m -Xmx1024m\"\n```\n\nIf you want to debug remotely the application with your IDE, set up your MAVEN_OPTS :\n```\nexport MAVEN_OPTS=\"$MAVEN_OPTS -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n\"\n```\n\n### Cassandra troubleshooting\n\nOn Mac OS X, you should use JDK 6 and not JDK 7, see [issue #281](https://github.com/ippontech/tatami/issues/281#issuecomment-12430701).\n\n\nHow to Contribute\n---------------------------------------\nIn order to assure code quality, Ippon manages the pull requests for the project, and upholds certain rules regarding how individuals may contribute. \nYou may find these rules in your Tatami installation in the file `CONTRIBUTING.md`.\n\n\nInstallation for production use\n---------------------------------------\n\n### Cassandra installation\n\n- Download [Apache Cassandra](http://cassandra.apache.org/)\n- Install Cassandra : the application will work fine with just one node, but ideally you should have a cluster with at least 3 or 5 nodes\n- Cassandra is configured with its cassandra.yaml file : don't forget to backup your \"data\" and \"commitlog\" directories\n\n### Tatami installation\n\nIn order to use a stable version, use one of the [available tags](https://github.com/ippontech/tatami/tags).\n\nTatami can be configured with the src/main/resources/META-INF/tatami/tatami.properties file. You can configure this file in 2 ways :\n\n- Edit the file in your own Tatami fork\n- Properties in this file are replaced at build time by Maven : you can set up your own Maven profile with your specific properties\n\nOnce Tatami is started, you will be able to check your properties at runtime in the Administration page.\n\nTo deploy Tatami :\n\n- Create the Tatami WAR file : `mvn package`\n- The WAR file will be called \"root.war\", as Tatami should be run as the root application (on the \"/\" Web context)\n- Deploy the WAR file on your favorite Java EE server\n- The WAR has been tested on Jetty 8 and Tomcat 7, and should work fine on all Java EE servers\n\nUpgrading from a previous version\n---------------------------------------\n\nUpgrading is normally just a matter of using a newer version of the application.\n\nSometimes, you will need to update the Cassandra keyspace: upgrade scripts are available in the src/main/cql/upgrade directory.\n\nLaunching stress tests\n---------------------------------------\n\nStress tests are done with [Apache JMeter](http://jmeter.apache.org/).\n\n- Launch Cassandra\n- Run Tatami from Maven with the `stress-tests` profile : `mvn jetty:run -Pstress-tests`\n- Launch JMeter\n- Run the `src/test/jmeter/tatami-create-users.jmx` script : it will create 200 normal users, which each has 200 follower users\n- Run the stress test : `src/test/jmeter/tatami-stress-test.jmx`\n\nLaunching functional tests\n---------------------------------------\n\nFunctional tests are a work in progress, you do not have to run them in order to use the application.\n\nRequirement : all components must run on localhost :\n\n- for LDAP authentication, the tests starts the LDAP server that the Tatami server will use\n- for fixture setup and assertions, the test connects directly to the local cassandra\n\nLaunching UI Tests from maven :\n\n- add this profile on your settings.xml :\n```xml\n<profile>\n  <id>tatami</id>\n  <activation>\n    <activeByDefault>true</activeByDefault>\n  </activation>\n  <properties>\n    <webdriver.chrome.driver>C:\\path\\to\\chromedriver.exe</webdriver.chrome.driver><!--optional-->\n    <google.password>xxxx</google.password>\n    <google.email>xxx@xxx.fr</google.email>\n  </properties>\n</profile>\n```\n\n- Run Maven with this command : `mvn clean verify -Puitest`\n\nLaunching UI Tests from maven with Chrome :\n\n- install ChromeDriver in your system\n- configure the property \"webdriver.chrome.driver\" in your settings pointing to your chrome driver install directory\n- add `-Dgeb.env=chrome` to the maven command above\n\nLaunching UI Tests from your IDE :\n\n- Enable a groovy plugin on your IDE\n- Activate maven profile \"uitest\" or add src/integration/* in your classpath\n- Run Tatami with Maven : `mvn cassandra:delete cassandra:start jetty:run -Djetty.scanIntervalSeconds=0 -Puitest`\n- Run Specs (in src\\integration\\java\\fr\\ippon\\tatami\\uitest) as Junit Tests from your IDE\n  => you have to set adequate system properties to your running configurations (the same as those that are necessary in setting.xml for maven : see above)\n\n\nThanks\n------\n\nJetbrains is providing us free [Intellij IDEA](http://www.jetbrains.com/idea/) licenses, \nwhich definitely allows us to be more productive and have more fun on the project!\n\nYourKit is kindly supporting open source projects with its full-featured Java Profiler.\nYourKit, LLC is the creator of innovative and intelligent tools for profiling\nJava and .NET applications. Take a look at YourKit's leading software products:\n[YourKit Java Profiler](http://www.yourkit.com/java/profiler/index.jsp) and\n[YourKit .NET Profiler](http://www.yourkit.com/.net/profiler/index.jsp).\n\nLicense\n-------\n\nCopyright © 2012-2015 [Ippon Technologies](http://www.ippon.fr)\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this application except in compliance with the License.\nYou may obtain a copy of the License at\n\n[http://www.apache.org/licenses/LICENSE-2.0](http://www.apache.org/licenses/LICENSE-2.0)\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
  },
  {
    "path": "etc/installation/ubuntu/files/maven/settings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<settings xmlns=\"http://maven.apache.org/SETTINGS/1.0.0\"\n          xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n          xsi:schemaLocation=\"http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd\">\n\n    <localRepository>/opt/tatami/maven/repository</localRepository>\n\n    <pluginGroups></pluginGroups>\n\n    <proxies></proxies>\n\n    <servers></servers>\n\n    <mirrors></mirrors>\n\n    <profiles></profiles>\n\n    <!-- activeProfiles\n     | List of profiles that are active for all builds.\n     |\n    <activeProfiles>\n      <activeProfile>alwaysActiveProfile</activeProfile>\n      <activeProfile>anotherAlwaysActiveProfile</activeProfile>\n    </activeProfiles>\n    -->\n</settings>"
  },
  {
    "path": "etc/installation/ubuntu/install.sh",
    "content": "#!/bin/sh\n#\n# description: Installs Tatami on Ubuntu\n# This script must be run by the \"root\" user.\n# Run this script directly by typing :\n# ﻿curl -L https://github.com/ippontech/tatami/raw/master/etc/installation/ubuntu/install.sh | sudo bash\n#\n# - Tatami is installed in the \"/opt/tatami\" directory\n# - Tatami is run by the \"tatami\" user\n#\necho \"Welcome to the Tatami installer\"\n\n#################################\n# Variables\n#################################\necho \"Setting up variables\"\nexport USER=tatami\nexport TATAMI_DIR=/opt/tatami\nexport MAVEN_VERSION=3.0.4\nexport JETTY_VERSION=8.1.8.v20121106\n\n#################################\n# Install missing packages\n#################################\necho \"Installing missing packages\"\napt-get install git-core curl wget -y --force-yes\n\n#################################\n# Install Java\n#################################\nwget https://github.com/flexiondotorg/oab-java6/raw/0.2.6/oab-java.sh -O oab-java.sh\nchmod +x oab-java.sh\nsudo ./oab-java.sh\nrm oab-java.sh\nsudo apt-get install sun-java6-jdk -y\n\n#################################\n# Create directories & users\n#################################\necho \"Creating directories and users\"\nuseradd -m -s /bin/bash $USER\n\nmkdir -p $TATAMI_DIR\nmkdir -p $TATAMI_DIR/application\nmkdir -p $TATAMI_DIR/maven\nmkdir -p $TATAMI_DIR/data\nmkdir -p $TATAMI_DIR/data/elasticsearch\nmkdir -p $TATAMI_DIR/log\nmkdir -p $TATAMI_DIR/log/elasticsearch\n\n#################################\n## Download Application\n#################################\necho \"Getting the application from Github\"\ncd $TATAMI_DIR/application\n\ngit clone https://github.com/ippontech/tatami.git\n\n#################################\n## Install Cassandra\n#################################\ncd $TATAMI_DIR\n\necho \"Installing JNA\"\nsudo apt-get install libjna-java -y\n\necho \"Configuring OS limits\"\ncp /etc/security/limits.conf /etc/security/limits.conf.original\n\necho \"* soft nofile 32768\" | sudo tee -a /etc/security/limits.conf\necho \"* hard nofile 32768\" | sudo tee -a /etc/security/limits.conf\necho \"root soft nofile 32768\" | sudo tee -a /etc/security/limits.conf\necho \"root hard nofile 32768\" | sudo tee -a /etc/security/limits.conf\n\necho \"* soft nofile 32768\"  >> /etc/security/limits.conf\necho \"* hard nofile 32768\"  >> /etc/security/limits.conf\necho \"root soft nofile 32768\"  >> /etc/security/limits.conf\necho \"root hard nofile 32768\"  >> /etc/security/limits.conf\necho \"* soft memlock unlimited\"  >> /etc/security/limits.conf\necho \"* hard memlock unlimited\"  >> /etc/security/limits.conf\necho \"root soft memlock unlimited\"  >> /etc/security/limits.conf\necho \"root hard memlock unlimited\"  >> /etc/security/limits.conf\necho \"* soft as unlimited\"  >> /etc/security/limits.conf\necho \"* hard as unlimited\"  >> /etc/security/limits.conf\necho \"root soft as unlimited\"  >> /etc/security/limits.conf\necho \"root hard as unlimited\"  >> /etc/security/limits.conf\n\nsysctl -w vm.max_map_count=131072\n\nsudo swapoff --all\n\n# Cassandra Installation\necho \"Installing Cassandra\"\necho \"deb http://debian.datastax.com/community stable main\"  >> /etc/apt/sources.list\ncurl -L http://debian.datastax.com/debian/repo_key | sudo apt-key add -\nsudo apt-get update\nsudo apt-get install python-cql dsc1.1 -y\nsudo apt-get install opscenter-free -y\n\nsudo service opscenterd start\n\n#################################\n## Install Jetty\n#################################\necho \"Installing Jetty\"\ncd $TATAMI_DIR\n\nsysctl -w net.core.rmem_max=16777216\nsysctl -w net.core.wmem_max=16777216\nsysctl -w net.ipv4.tcp_rmem=\"4096 87380 16777216\"\nsysctl -w net.ipv4.tcp_wmem=\"4096 16384 16777216\"\nsysctl -w net.core.somaxconn=4096\nsysctl -w net.core.netdev_max_backlog=16384\nsysctl -w net.ipv4.tcp_max_syn_backlog=8192\nsysctl -w net.ipv4.tcp_syncookies=1\nsysctl -w net.ipv4.ip_local_port_range=\"1024 65535\"\nsysctl -w net.ipv4.tcp_tw_recycle=1\nsysctl -w net.ipv4.tcp_congestion_control=cubic\n\nwget http://central.maven.org/maven2/org/mortbay/jetty/dist/jetty-deb/$JETTY_VERSION/jetty-deb-$JETTY_VERSION.deb\ndpkg -i jetty-deb-$JETTY_VERSION.deb\nrm -f jetty-deb-$JETTY_VERSION.deb\nrm -rf /opt/jetty/webapps/*\n\n#################################\n## Install Maven\n#################################\necho \"Installing Maven\"\n\ncd $TATAMI_DIR/maven\n\nwget http://mirrors.linsrv.net/apache/maven/maven-3/$MAVEN_VERSION/binaries/apache-maven-$MAVEN_VERSION-bin.tar.gz\ntar -xzf apache-maven-$MAVEN_VERSION-bin.tar.gz\nrm -f apache-maven-$MAVEN_VERSION-bin.tar.gz\nln -s $TATAMI_DIR/maven/apache-maven-$MAVEN_VERSION $TATAMI_DIR/maven/current\n\n# Configure Maven for the tatami user\necho \"# Begin tatami configuration\" ﻿>> /home/tatami/.profile\necho \"export M2_HOME=/opt/tatami/maven/current\" >> /home/tatami/.profile\necho \"export PATH=/opt/tatami/maven/current/bin:$PATH\" >> /home/tatami/.profile\necho \"export MAVEN_OPTS=\\\"-XX:MaxPermSize=64m -Xms256m -Xmx1024m\\\"\" >> /home/tatami/.profile\necho \"# End tatami configuration\" ﻿>> /home/tatami/.profile\n\n# Configure Maven repository\nmkdir -p $TATAMI_DIR/maven/repository\ncp $TATAMI_DIR/application/tatami/etc/installation/ubuntu/files/maven/settings.xml $TATAMI_DIR/maven/apache-maven-$MAVEN_VERSION/conf\n\n#################################\n## Install & run Application\n#################################\nchown -R $USER $TATAMI_DIR\n./update.sh\n\n#################################\n## Post install\n#################################\n"
  },
  {
    "path": "etc/installation/ubuntu/uninstall.sh",
    "content": "#!/bin/sh\n#\n# description: Uninstalls Tatami on Ubuntu\n# This script must be run by the \"root\" user.\n#\n# Run this script directly by typing :\n# ﻿curl -L https://github.com/ippontech/tatami/raw/master/etc/installation/ubuntu/uninstall.sh | sudo bash\n#\n# - Deletes the \"/opt/tatami\"\n# - Deletes the \"tatami\" user\n\necho \"Tatami uninstaller\"\n\nmv /etc/security/limits.conf.original /etc/security/limits.conf\n\nuserdel -f -r tatami\n\necho \"Delete Tatami directory\"\nrm -rf /opt/tatami"
  },
  {
    "path": "etc/installation/ubuntu/update.sh",
    "content": "#!/bin/sh\n#\n# description: Updates Tatami from Git\n# This script must be run by the \"tatami\" user, who must be a sudoer.\necho \"Welcome to the Tatami updater\"\n\n#################################\n# Variables\n#################################\necho \"Setting up variables\"\nexport USER=tatami\nexport TATAMI_DIR=/opt/tatami\n\n#################################\n# Update application\n#################################\ncd $TATAMI_DIR/application/tatami\ngit pull\ncd /opt/tatami/application/tatami && mvn -Pprod -DskipTests clean package\nsudo /etc/init.d/jetty stop\nsudo cp /opt/tatami/application/tatami/target/root.war /opt/jetty/webapps/root.war\nsudo /etc/init.d/jetty start\n"
  },
  {
    "path": "jenkinsScripts/insertGoogleAuthKeys.sh",
    "content": "#!/bin/bash\n\n#Insert google auth variables into the build. \ngoogleKey=$1\ngoogleSecret=$2\nnewServer=$3\n\n\nusage='startTatami <googleKey> <googleSecret> <serverURL>'\n\nif [ \"$#\" -ne 3 ]; then\n\techo \"Need 3 paremeters\"\n        echo \"$usage\"\n        exit 1\nfi\n\n\nreplaceKey='${tatami.google.clientId}'\nreplaceSecret='${tatami.google.clientSecret}'\noldServer=\"<tatami.url>http:\\/\\/localhost:8080<\\/tatami.url>\"\n\nfind ../src -name *security.xml | xargs sed -i \"s/$replaceSecret/$googleSecret/g\" \nfind ../src -name *security.xml | xargs sed -i \"s/$replaceKey/$googleKey/g\" \nsed -i \"s/$oldServer/$newServer/g\" ../pom.xml\n\n\n"
  },
  {
    "path": "jenkinsScripts/restoreDatabase.sh",
    "content": "#!/bin/bash\n\nrm -rf ../target/cassandra || true\nrm -rf ./target/elasticsearch || true\n\ntar -zxvf save.tar.gz -C ../target/\ntar -zxvf db.tar.gz -C ./target/\n\nrm -f save.tar.gz || true\n"
  },
  {
    "path": "jenkinsScripts/saveDatabase.sh",
    "content": "#!/bin/bash\n\ntar -zcvf save.tar.gz ../target/cassandra ../target/elasticsearch\ntar -zcvf db.tar.gz ./target/elasticsearch\n"
  },
  {
    "path": "jenkinsScripts/startTatami.sh",
    "content": "#!/bin/bash\n\n#Insert google Authentication keys.\n./insertGoogleAuthKeys.sh $1 $2 $3\n\nif [ $? -ne 0 ]; then\n    exit 1\nfi\n\n#Start cassandra\nmvn -f ../pom.xml cassandra:run 2> cassandra.error >cassandra.log &\necho \"$!\" >tatamiPID\n\n#start jetty\nmvn -f ../pom.xml jetty:run 2> jetty.error >jetty.log &\necho \"$!\" >> tatamiPID\n\n"
  },
  {
    "path": "jenkinsScripts/stopTatami.sh",
    "content": "#!/bin/bash\ncat tatamiPID | xargs kill || true\nrm tatamiPID || true\n"
  },
  {
    "path": "mobile/.bowerrc",
    "content": "{\n  \"directory\": \"www/lib\"\n}\n"
  },
  {
    "path": "mobile/.editorconfig",
    "content": "# http://editorconfig.org\nroot = true\n\n[*]\ncharset = utf-8\nindent_style = space\nindent_size = 4\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[*.md]\ninsert_final_newline = false\ntrim_trailing_whitespace = false"
  },
  {
    "path": "mobile/.gitignore",
    "content": "# Specifies intentionally untracked files to ignore when using Git\n# http://git-scm.com/docs/gitignore\n\nwww/lib/\nnode_modules/\nplatforms/\nplugins/\n"
  },
  {
    "path": "mobile/README.md",
    "content": "Tatami Mobile Beta\n==================\n\nIf interested in the mobile beta, follow these steps:\n\nPrepare Project\n---------------\n\n- Clone, fork or download the source code from this Github page\n- Install [Maven](http://maven.apache.org/)\n- Install [Ionic](http://ionicframework.com/)\n    - `npm install -g cordova ionic`\n- Point your terminal to the directory you cloned Tatami to.\n    - `cd mobile`\n- Run Maven : `mvn -Pmobile-prod install`\n\nDeploy to Device\n----------------\n\n### iOS\n- Open Xcode\n- Open `tatami/mobile/platforms/ios/Tatami.xcodeproj`\n- Connect device\n- Click play on top left\n\n\n### Android\n\n- Connect device\n- Run the following command\n    - `ionic build android && ionic run android`\n\n"
  },
  {
    "path": "mobile/bower.json",
    "content": "{\n  \"name\": \"tatami\",\n  \"private\": \"true\",\n  \"devDependencies\": {\n    \"ionic\": \"~1.2.4\",\n    \"angular-mocks\": \"1.4.3\",\n    \"angular-marked\": \"~1.0.1\",\n    \"angular-animate\": \"~1.5.3\",\n    \"angular-sanitize\": \"~1.5.3\",\n    \"angular-resource\": \"~1.5.3\",\n    \"ngCordova\": \"~0.1.24-alpha\",\n    \"angular-translate\": \"~2.11.0\",\n    \"angular-translate-interpolation-messageformat\": \"~2.11.0\",\n    \"angular-translate-loader-partial\": \"~2.11.0\",\n    \"messageformat\": \"~0.3.1\"\n  },\n  \"resolutions\": {\n    \"angular-sanitize\": \"~1.5.3\",\n    \"angular-animate\": \"~1.5.3\",\n    \"ionic-toast\": \"v0.2.0\"\n  },\n  \"dependencies\": {\n    \"ionic-toast\": \"^0.4.1\"\n  }\n}\n"
  },
  {
    "path": "mobile/config.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<widget id=\"com.ippon.tatami.mobile\" version=\"1.0.1\" xmlns=\"http://www.w3.org/ns/widgets\" xmlns:cdv=\"http://cordova.apache.org/ns/1.0\">\n  <name>Tatami</name>\n  <description>\n        The Tatami mobile app is designed to access the Tatami API, and it is an open source, enterprise social media platform.\n    </description>\n  <author email=\"tatami-dev@ippon.fr\">\n      Ippon Technology, Inc\n    </author>\n  <content src=\"index.html\"/>\n  <access origin=\"*\"/>\n  <preference name=\"webviewbounce\" value=\"false\"/>\n  <preference name=\"UIWebViewBounce\" value=\"false\"/>\n  <preference name=\"DisallowOverscroll\" value=\"true\"/>\n  <preference name=\"android-minSdkVersion\" value=\"16\"/>\n  <preference name=\"BackupWebStorage\" value=\"none\"/>\n  <preference name=\"SplashScreen\" value=\"screen\"/>\n  <preference name=\"SplashScreenDelay\" value=\"3000\"/>\n  <feature name=\"StatusBar\">\n    <param name=\"ios-package\" value=\"CDVStatusBar\" onload=\"true\"/>\n  </feature>\n  <platform name=\"ios\">\n    <icon src=\"resources/ios/icon/icon.png\" width=\"57\" height=\"57\"/>\n    <icon src=\"resources/ios/icon/icon@2x.png\" width=\"114\" height=\"114\"/>\n    <icon src=\"resources/ios/icon/icon-40.png\" width=\"40\" height=\"40\"/>\n    <icon src=\"resources/ios/icon/icon-40@2x.png\" width=\"80\" height=\"80\"/>\n    <icon src=\"resources/ios/icon/icon-50.png\" width=\"50\" height=\"50\"/>\n    <icon src=\"resources/ios/icon/icon-50@2x.png\" width=\"100\" height=\"100\"/>\n    <icon src=\"resources/ios/icon/icon-60.png\" width=\"60\" height=\"60\"/>\n    <icon src=\"resources/ios/icon/icon-60@2x.png\" width=\"120\" height=\"120\"/>\n    <icon src=\"resources/ios/icon/icon-60@3x.png\" width=\"180\" height=\"180\"/>\n    <icon src=\"resources/ios/icon/icon-72.png\" width=\"72\" height=\"72\"/>\n    <icon src=\"resources/ios/icon/icon-72@2x.png\" width=\"144\" height=\"144\"/>\n    <icon src=\"resources/ios/icon/icon-76.png\" width=\"76\" height=\"76\"/>\n    <icon src=\"resources/ios/icon/icon-76@2x.png\" width=\"152\" height=\"152\"/>\n    <icon src=\"resources/ios/icon/icon-small.png\" width=\"29\" height=\"29\"/>\n    <icon src=\"resources/ios/icon/icon-small@2x.png\" width=\"58\" height=\"58\"/>\n    <icon src=\"resources/ios/icon/icon-small@3x.png\" width=\"87\" height=\"87\"/>\n    <splash src=\"resources/ios/splash/Default-568h@2x~iphone.png\" width=\"640\" height=\"1136\"/>\n    <splash src=\"resources/ios/splash/Default-667h.png\" width=\"750\" height=\"1334\"/>\n    <splash src=\"resources/ios/splash/Default-736h.png\" width=\"1242\" height=\"2208\"/>\n    <splash src=\"resources/ios/splash/Default-Landscape-736h.png\" width=\"2208\" height=\"1242\"/>\n    <splash src=\"resources/ios/splash/Default-Landscape@2x~ipad.png\" width=\"2048\" height=\"1536\"/>\n    <splash src=\"resources/ios/splash/Default-Landscape~ipad.png\" width=\"1024\" height=\"768\"/>\n    <splash src=\"resources/ios/splash/Default-Portrait@2x~ipad.png\" width=\"1536\" height=\"2048\"/>\n    <splash src=\"resources/ios/splash/Default-Portrait~ipad.png\" width=\"768\" height=\"1024\"/>\n    <splash src=\"resources/ios/splash/Default@2x~iphone.png\" width=\"640\" height=\"960\"/>\n    <splash src=\"resources/ios/splash/Default~iphone.png\" width=\"320\" height=\"480\"/>\n  </platform>\n  <platform name=\"android\">\n    <icon src=\"resources/android/icon/drawable-ldpi-icon.png\" density=\"ldpi\"/>\n    <icon src=\"resources/android/icon/drawable-mdpi-icon.png\" density=\"mdpi\"/>\n    <icon src=\"resources/android/icon/drawable-hdpi-icon.png\" density=\"hdpi\"/>\n    <icon src=\"resources/android/icon/drawable-xhdpi-icon.png\" density=\"xhdpi\"/>\n    <icon src=\"resources/android/icon/drawable-xxhdpi-icon.png\" density=\"xxhdpi\"/>\n    <icon src=\"resources/android/icon/drawable-xxxhdpi-icon.png\" density=\"xxxhdpi\"/>\n    <splash src=\"resources/android/splash/drawable-land-ldpi-screen.png\" density=\"land-ldpi\"/>\n    <splash src=\"resources/android/splash/drawable-land-mdpi-screen.png\" density=\"land-mdpi\"/>\n    <splash src=\"resources/android/splash/drawable-land-hdpi-screen.png\" density=\"land-hdpi\"/>\n    <splash src=\"resources/android/splash/drawable-land-xhdpi-screen.png\" density=\"land-xhdpi\"/>\n    <splash src=\"resources/android/splash/drawable-land-xxhdpi-screen.png\" density=\"land-xxhdpi\"/>\n    <splash src=\"resources/android/splash/drawable-land-xxxhdpi-screen.png\" density=\"land-xxxhdpi\"/>\n    <splash src=\"resources/android/splash/drawable-port-ldpi-screen.png\" density=\"port-ldpi\"/>\n    <splash src=\"resources/android/splash/drawable-port-mdpi-screen.png\" density=\"port-mdpi\"/>\n    <splash src=\"resources/android/splash/drawable-port-hdpi-screen.png\" density=\"port-hdpi\"/>\n    <splash src=\"resources/android/splash/drawable-port-xhdpi-screen.png\" density=\"port-xhdpi\"/>\n    <splash src=\"resources/android/splash/drawable-port-xxhdpi-screen.png\" density=\"port-xxhdpi\"/>\n    <splash src=\"resources/android/splash/drawable-port-xxxhdpi-screen.png\" density=\"port-xxxhdpi\"/>\n  </platform>\n  <icon src=\"resources/android/icon/drawable-xhdpi-icon.png\"/>\n</widget>\n"
  },
  {
    "path": "mobile/gulpfile.js",
    "content": "var gulp = require('gulp');\nvar gutil = require('gulp-util');\nvar bower = require('bower');\nvar concat = require('gulp-concat');\nvar sass = require('gulp-sass');\nvar minifyCss = require('gulp-minify-css');\nvar rename = require('gulp-rename');\nvar sh = require('shelljs');\nvar replace = require('replace');\n\nvar paths = {\n    sass: ['./scss/**/*.scss'],\n    css: ['./www/css/*.css']\n};\n\ngulp.task('default', ['sass', 'css']);\n\ngulp.task('sass', function(done) {\n  gulp.src('./scss/ionic.app.scss')\n    .pipe(sass())\n    .on('error', sass.logError)\n    .pipe(gulp.dest('./www/css/'))\n    .pipe(minifyCss({\n      keepSpecialComments: 0\n    }))\n    .pipe(rename({ extname: '.min.css' }))\n    .pipe(gulp.dest('./www/css/'))\n    .on('end', done);\n});\n\ngulp.task('css', function(done) {\n    gulp.src('./www/css/style.css')\n        .pipe(minifyCss({\n            keepSpecialComments: 0\n        }))\n        .pipe(rename({ extname: '.min.css' }))\n        .pipe(gulp.dest('./www/css/'))\n        .on('end', done);\n});\n\ngulp.task('watch', function() {\n    gulp.watch(paths.sass, ['sass']);\n    gulp.watch(paths.css, ['css']);\n});\n\ngulp.task('install', ['git-check'], function() {\n  return bower.commands.install()\n    .on('log', function(data) {\n      gutil.log('bower', gutil.colors.cyan(data.id), data.message);\n    });\n});\n\ngulp.task('git-check', function(done) {\n  if (!sh.which('git')) {\n    console.log(\n      '  ' + gutil.colors.red('Git is not installed.'),\n      '\\n  Git, the version control system, is required to download Ionic.',\n      '\\n  Download git here:', gutil.colors.cyan('http://git-scm.com/downloads') + '.',\n      '\\n  Once git is installed, run \\'' + gutil.colors.cyan('gulp install') + '\\' again.'\n    );\n    process.exit(1);\n  }\n  done();\n});\n\nvar replaceFiles = ['./www/app/tatami.endpoint.js'];\n\ngulp.task('dev', function() {\n    return replace({\n        regex: 'http://tatami.ippon.fr|http://10.1.10.202:8100',\n        replacement: 'http://localhost:8100',\n        paths: replaceFiles,\n        recursive: false,\n        silent: false\n    });\n});\n\ngulp.task('device-dev', function() {\n    return replace({\n        regex: 'http://localhost:8100|http://tatami.ippon.fr',\n        replacement: 'http://10.1.10.202:8100',\n        paths: replaceFiles,\n        recursive: false,\n        silent: false\n    });\n});\n\ngulp.task('prod', function() {\n    return replace({\n        regex: 'http://localhost:8100|http://10.1.10.202:8100',\n        replacement: 'http://tatami.ippon.fr',\n        paths: replaceFiles,\n        recursive: false,\n        silent: false\n    });\n});\n"
  },
  {
    "path": "mobile/hooks/README.md",
    "content": "<!--\n#\n# Licensed to the Apache Software Foundation (ASF) under one\n# or more contributor license agreements.  See the NOTICE file\n# distributed with this work for additional information\n# regarding copyright ownership.  The ASF licenses this file\n# to you under the Apache License, Version 2.0 (the\n# \"License\"); you may not use this file except in compliance\n# with the License.  You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing,\n# software distributed under the License is distributed on an\n# \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n#  KIND, either express or implied.  See the License for the\n# specific language governing permissions and limitations\n# under the License.\n#\n-->\n# Cordova Hooks\n\nThis directory may contain scripts used to customize cordova commands. This\ndirectory used to exist at `.cordova/hooks`, but has now been moved to the\nproject root. Any scripts you add to these directories will be executed before\nand after the commands corresponding to the directory name. Useful for\nintegrating your own build systems or integrating with version control systems.\n\n__Remember__: Make your scripts executable.\n\n## Hook Directories\nThe following subdirectories will be used for hooks:\n\n    after_build/\n    after_compile/\n    after_docs/\n    after_emulate/\n    after_platform_add/\n    after_platform_rm/\n    after_platform_ls/\n    after_plugin_add/\n    after_plugin_ls/\n    after_plugin_rm/\n    after_plugin_search/\n    after_prepare/\n    after_run/\n    after_serve/\n    before_build/\n    before_compile/\n    before_docs/\n    before_emulate/\n    before_platform_add/\n    before_platform_rm/\n    before_platform_ls/\n    before_plugin_add/\n    before_plugin_ls/\n    before_plugin_rm/\n    before_plugin_search/\n    before_prepare/\n    before_run/\n    before_serve/\n    pre_package/ <-- Windows 8 and Windows Phone only.\n\n## Script Interface\n\nAll scripts are run from the project's root directory and have the root directory passes as the first argument. All other options are passed to the script using environment variables:\n\n* CORDOVA_VERSION - The version of the Cordova-CLI.\n* CORDOVA_PLATFORMS - Comma separated list of platforms that the command applies to (e.g.: android, ios).\n* CORDOVA_PLUGINS - Comma separated list of plugin IDs that the command applies to (e.g.: org.apache.cordova.file, org.apache.cordova.file-transfer)\n* CORDOVA_HOOK - Path to the hook that is being executed.\n* CORDOVA_CMDLINE - The exact command-line arguments passed to cordova (e.g.: cordova run ios --emulate)\n\nIf a script returns a non-zero exit code, then the parent cordova command will be aborted.\n\n\n## Writing hooks\n\nWe highly recommend writting your hooks using Node.js so that they are\ncross-platform. Some good examples are shown here:\n\n[http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/](http://devgirl.org/2013/11/12/three-hooks-your-cordovaphonegap-project-needs/)\n\n"
  },
  {
    "path": "mobile/hooks/after_prepare/010_add_platform_class.js",
    "content": "#!/usr/bin/env node\n\n// Add Platform Class\n// v1.0\n// Automatically adds the platform class to the body tag\n// after the `prepare` command. By placing the platform CSS classes\n// directly in the HTML built for the platform, it speeds up\n// rendering the correct layout/style for the specific platform\n// instead of waiting for the JS to figure out the correct classes.\n\nvar fs = require('fs');\nvar path = require('path');\n\nvar rootdir = process.argv[2];\n\nfunction addPlatformBodyTag(indexPath, platform) {\n  // add the platform class to the body tag\n  try {\n    var platformClass = 'platform-' + platform;\n    var cordovaClass = 'platform-cordova platform-webview';\n\n    var html = fs.readFileSync(indexPath, 'utf8');\n\n    var bodyTag = findBodyTag(html);\n    if(!bodyTag) return; // no opening body tag, something's wrong\n\n    if(bodyTag.indexOf(platformClass) > -1) return; // already added\n\n    var newBodyTag = bodyTag;\n\n    var classAttr = findClassAttr(bodyTag);\n    if(classAttr) {\n      // body tag has existing class attribute, add the classname\n      var endingQuote = classAttr.substring(classAttr.length-1);\n      var newClassAttr = classAttr.substring(0, classAttr.length-1);\n      newClassAttr += ' ' + platformClass + ' ' + cordovaClass + endingQuote;\n      newBodyTag = bodyTag.replace(classAttr, newClassAttr);\n\n    } else {\n      // add class attribute to the body tag\n      newBodyTag = bodyTag.replace('>', ' class=\"' + platformClass + ' ' + cordovaClass + '\">');\n    }\n\n    html = html.replace(bodyTag, newBodyTag);\n\n    fs.writeFileSync(indexPath, html, 'utf8');\n\n    process.stdout.write('add to body class: ' + platformClass + '\\n');\n  } catch(e) {\n    process.stdout.write(e);\n  }\n}\n\nfunction findBodyTag(html) {\n  // get the body tag\n  try{\n    return html.match(/<body(?=[\\s>])(.*?)>/gi)[0];\n  }catch(e){}\n}\n\nfunction findClassAttr(bodyTag) {\n  // get the body tag's class attribute\n  try{\n    return bodyTag.match(/ class=[\"|'](.*?)[\"|']/gi)[0];\n  }catch(e){}\n}\n\nif (rootdir) {\n\n  // go through each of the platform directories that have been prepared\n  var platforms = (process.env.CORDOVA_PLATFORMS ? process.env.CORDOVA_PLATFORMS.split(',') : []);\n\n  for(var x=0; x<platforms.length; x++) {\n    // open up the index.html file at the www root\n    try {\n      var platform = platforms[x].trim().toLowerCase();\n      var indexPath;\n\n      if(platform == 'android') {\n        indexPath = path.join('platforms', platform, 'assets', 'www', 'index.html');\n      } else {\n        indexPath = path.join('platforms', platform, 'www', 'index.html');\n      }\n\n      if(fs.existsSync(indexPath)) {\n        addPlatformBodyTag(indexPath, platform);\n      }\n\n    } catch(e) {\n      process.stdout.write(e);\n    }\n  }\n\n}\n"
  },
  {
    "path": "mobile/ionic.project",
    "content": "{\n    \"name\": \"mobile\",\n    \"app_id\": \"\",\n    \"proxies\": [\n        {\n            \"path\": \"/tatami\",\n            \"proxyUrl\": \"http://localhost:8080/tatami\"\n        },\n        {\n            \"path\": \"/assets\",\n            \"proxyUrl\": \"http://localhost:8080/assets\"\n        }\n  ],\n  \"gulpStartupTasks\": [\n    \"sass\",\n    \"watch\"\n  ],\n  \"watchPatterns\": [\n    \"www/**/*\",\n    \"!www/lib/**/*\"\n  ]\n}\n"
  },
  {
    "path": "mobile/karma.ci.conf.js",
    "content": "// Karma configuration\n// Generated on Wed May 06 2015 15:23:11 GMT-0400 (EDT)\n\nmodule.exports = function (config) {\n    config.set({\n\n        // base path that will be used to resolve all patterns (eg. files, exclude)\n        basePath: '',\n\n\n        // frameworks to use\n        // available frameworks: https://npmjs.org/browse/keyword/karma-adapter\n        frameworks: ['jasmine'],\n\n        // list of files / patterns to load in the browser\n        files: [\n            \"www/lib/ionic/release/js/ionic.bundle.js\",\n            \"www/lib/ionic/js/angular/angular-resource.js\",\n            \"www/lib/angular-mocks/angular-mocks.js\",\n            \"www/test/javascript/**/*.js\"\n        ],\n\n\n        // list of files to exclude\n        exclude: [\n            '**/*.swp'\n        ],\n\n\n        // preprocess matching files before serving them to the browser\n        // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor\n        preprocessors: {\n            'src/**/*.js': ['coverage']\n        },\n\n\n        // test results reporter to use\n        // possible values: 'dots', 'progress'\n        // available reporters: https://npmjs.org/browse/keyword/karma-reporter\n        reporters: ['dots', 'jenkins', 'coverage', 'progress'],\n\n        jenkinsReporter: {\n            outputFile: 'target/test-results/karma/TESTS-resuts.xml'\n        },\n\n        coverageReporter: {\n            dir: 'target/test-results/coverage',\n\n            reporters: [\n                {type: 'lcov', subdir: 'report-lcov'}\n            ]\n        },\n\n        // web server port\n        port: 9876,\n\n\n        // enable / disable colors in the output (reporters and logs)\n        colors: true,\n\n\n        // level of logging\n        // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG\n        logLevel: config.LOG_INFO,\n\n\n        // enable / disable watching file and executing tests whenever any file changes\n        autoWatch: false,\n\n\n        // start these browsers\n        // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher\n        browsers: ['PhantomJS'],\n\n\n        // Continuous Integration mode\n        // if true, Karma captures browsers, runs the tests and exits\n        singleRun: true\n    });\n};\n"
  },
  {
    "path": "mobile/package.json",
    "content": "{\n  \"name\": \"mobile\",\n  \"version\": \"1.1.1\",\n  \"description\": \"mobile: An Ionic project\",\n  \"dependencies\": {\n    \"gulp\": \"^3.5.6\",\n    \"gulp-concat\": \"^2.2.0\",\n    \"gulp-minify-css\": \"^0.3.0\",\n    \"gulp-rename\": \"^1.2.0\",\n    \"gulp-sass\": \"^2.0.4\",\n    \"replace\": \"^0.3.0\"\n  },\n  \"devDependencies\": {\n    \"bower\": \"^1.3.3\",\n    \"gulp-util\": \"^2.2.14\",\n    \"karma\": \"^0.13.19\",\n    \"karma-jasmine\": \"^0.3.6\",\n    \"jasmine-core\": \"^2.3.4\",\n    \"karma-chrome-launcher\": \"^0.2.0\",\n    \"karma-cli\": \"^0.1.1\",\n    \"karma-coverage\": \"^0.5.2\",\n    \"karma-firefox-launcher\": \"^0.1.6\",\n    \"karma-ie-launcher\": \"^0.2.0\",\n    \"karma-jenkins-reporter\": \"0.0.2\",\n    \"karma-jshint\": \"^0.1.0\",\n    \"karma-junit-reporter\": \"^0.3.6\",\n    \"karma-phantomjs-launcher\": \"^0.2.1\",\n    \"karma-safari-launcher\": \"^0.1.1\",\n    \"phantomjs\": \"^1.9.18\",\n    \"shelljs\": \"^0.3.0\"\n  },\n  \"cordovaPlugins\": [\n    \"cordova-plugin-device\",\n    \"cordova-plugin-console\",\n    \"cordova-plugin-splashscreen\",\n    \"cordova-plugin-statusbar\",\n    \"ionic-plugin-keyboard\",\n    \"cordova-plugin-inappbrowser\",\n    \"cordova-plugin-camera\",\n    {\n      \"locator\": \"https://github.com/apache/cordova-plugin-whitelist.git\",\n      \"id\": \"cordova-plugin-whitelist\"\n    },\n    \"cordova-plugin-file-transfer\"\n  ],\n  \"cordovaPlatforms\": [\n    \"android\",\n    \"ios\"\n  ]\n}\n"
  },
  {
    "path": "mobile/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <artifactId>tatami</artifactId>\n        <groupId>fr.ippon.tatami</groupId>\n        <version>4.0.5</version>\n    </parent>\n\n    <modelVersion>4.0.0</modelVersion>\n    <artifactId>mobile</artifactId>\n\n    <dependencies>\n        <dependency>\n            <groupId>fr.ippon.tatami</groupId>\n            <artifactId>services</artifactId>\n            <version>4.0.5</version>\n        </dependency>\n        <dependency>\n            <groupId>fr.ippon.tatami</groupId>\n            <artifactId>services</artifactId>\n            <version>4.0.5</version>\n            <type>test-jar</type>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n\n    <profiles>\n        <profile>\n            <id>dev</id>\n            <build>\n                <plugins>\n                    <plugin>\n                        <groupId>org.codehaus.mojo</groupId>\n                        <artifactId>exec-maven-plugin</artifactId>\n                        <version>1.2.1</version>\n                        <executions>\n                            <execution>\n                                <id>gulp</id>\n                                <phase>install</phase>\n                                <goals>\n                                    <goal>exec</goal>\n                                </goals>\n                                <configuration>\n                                    <executable>${project.npm.bin}/gulp</executable>\n                                    <arguments>\n                                        <argument>dev</argument>\n                                    </arguments>\n                                </configuration>\n                            </execution>\n                            <execution>\n                                <id>ionic</id>\n                                <phase>install</phase>\n                                <goals>\n                                    <goal>exec</goal>\n                                </goals>\n                                <configuration>\n                                    <executable>ionic</executable>\n                                    <arguments>\n                                        <argument>serve</argument>\n                                        <argument>-l</argument>\n                                    </arguments>\n                                </configuration>\n                            </execution>\n                        </executions>\n                    </plugin>\n                </plugins>\n            </build>\n\n        </profile>\n        <profile>\n            <id>device-dev</id>\n            <build>\n                <plugins>\n                    <plugin>\n                        <groupId>org.codehaus.mojo</groupId>\n                        <artifactId>exec-maven-plugin</artifactId>\n                        <version>1.2.1</version>\n                        <executions>\n                            <execution>\n                                <phase>install</phase>\n                                <goals>\n                                    <goal>exec</goal>\n                                </goals>\n                                <configuration>\n                                    <executable>${project.npm.bin}/gulp</executable>\n                                    <arguments>\n                                        <argument>device-dev</argument>\n                                    </arguments>\n                                </configuration>\n                            </execution>\n                        </executions>\n                    </plugin>\n                </plugins>\n            </build>\n\n        </profile>\n\n        <profile>\n            <id>mobile-prod</id>\n            <build>\n                <plugins>\n                    <plugin>\n                        <groupId>org.codehaus.mojo</groupId>\n                        <artifactId>exec-maven-plugin</artifactId>\n                        <version>1.2.1</version>\n                        <executions>\n                            <execution>\n                                <id>gulp</id>\n                                <phase>install</phase>\n                                <goals>\n                                    <goal>exec</goal>\n                                </goals>\n                                <configuration>\n                                    <executable>${project.npm.bin}/gulp</executable>\n                                    <arguments>\n                                        <argument>prod</argument>\n                                    </arguments>\n                                </configuration>\n                            </execution>\n                            <execution>\n                                <id>ionic</id>\n                                <phase>install</phase>\n                                <goals>\n                                    <goal>exec</goal>\n                                </goals>\n                                <configuration>\n                                    <executable>ionic</executable>\n                                    <arguments>\n                                        <argument>build</argument>\n                                    </arguments>\n                                </configuration>\n                            </execution>\n\n                        </executions>\n                    </plugin>\n                </plugins>\n\n            </build>\n\n        </profile>\n    </profiles>\n\n    <build>\n        <finalName>tatami-mobile-${project.version}</finalName>\n        <plugins>\n\t<plugin>\n                <artifactId>maven-clean-plugin</artifactId>\n                <version>2.6.1</version>\n                <configuration>\n                    <filesets>\n                        <fileset>\n                            <directory>${project.basedir}/node_modules/</directory>\n                            <followSymlinks>false</followSymlinks>\n                        </fileset>\n                    </filesets>\n                </configuration>\n            </plugin>        \n\t<plugin>\n\t\t<groupId>org.codehaus.mojo</groupId>\n\t\t<artifactId>exec-maven-plugin</artifactId>\n\t\t<version>1.2.1</version>\n\t\t<executions>\n\t\t\t<execution>\n\t\t\t\t<id>install-npm-mobile-dependencies</id>\n\t\t\t\t<phase>generate-sources</phase>\n\t\t\t\t<configuration>\n\t\t\t\t\t<executable>npm</executable>\n\t\t\t\t\t<arguments>\n\t\t\t\t\t\t<argument>install</argument>\n\t\t\t\t\t</arguments>\n\t\t\t\t</configuration>\n\t\t\t\t<goals>\n\t\t\t\t\t<goal>exec</goal>\n\t\t\t\t</goals>\n\t\t\t</execution>\n\t\t</executions>\n\t</plugin>    \n\t<plugin>\n                <groupId>com.kelveden</groupId>\n                <artifactId>maven-karma-plugin</artifactId>\n                <version>1.6</version>\n                <executions>\n                    <execution>\n                        <phase>test</phase>\n                        <goals>\n                            <goal>start</goal>\n                        </goals>\n                    </execution>\n                </executions>\n                <configuration>\n                    <karmaExecutable>${project.basedir}/node_modules/.bin/karma</karmaExecutable>\n                    <configFile>${project.basedir}/karma.ci.conf.js</configFile>\n                </configuration>\n            </plugin>\n\n        </plugins>\n    </build>\n</project>\n"
  },
  {
    "path": "mobile/scss/ionic.app.scss",
    "content": "/*\nTo customize the look and feel of Ionic, you can override the variables\nin ionic's _variables.scss file.\n\nFor example, you might change some of the default colors:\n\n$light:                           #fff !default;\n$stable:                          #f8f8f8 !default;\n$positive:                        #387ef5 !default;\n$calm:                            #11c1f3 !default;\n$balanced:                        #33cd5f !default;\n$energized:                       #ffc900 !default;\n$assertive:                       #ef473a !default;\n$royal:                           #886aea !default;\n$dark:                            #444 !default;\n*/\n\n// The path for our ionicons font files, relative to the built CSS in www/css\n$ionicons-font-path: \"../lib/ionic/release/fonts\" !default;\n\n// Include all of Ionic\n@import \"../www/lib/ionic/release/css/ionic\";\n\n.platform-ios {\n    .tatami-location {\n        @extend .ion-ios-location;\n    }\n}\n\n.platform-android {\n    .tatami-location {\n        @extend .ion-android-locate;\n    }\n}\n\n.item-image i:last-child {\n    position: absolute;\n    border-radius: 50%;\n    width: 20px;\n    height: 20px;\n    background-color: black;\n    top: 15px;\n    right: 15px;\n}\n\n.link-span {\n    cursor: pointer;\n    color: #387ef5;\n}\n\n.center {\n    margin-left: auto;\n    margin-right: auto;\n    display: block;\n}\n\np ul {\n    list-style-type: disc !important;\n    list-style-position: inside !important;\n}\n\n//#list ul {\n//    margin-top: 30px;\n//}\n//#list ul li {\n//    text-align: left;\n//    list-style: disc;\n//    margin: 10px 0px;\n//}\n"
  },
  {
    "path": "mobile/www/app/components/follow/follow.html",
    "content": "<ion-view>\n    <ion-tabs class=\"tabs-icon-top tabs-color-active-positive\">\n\n        <ion-tab title=\"{{ 'tab.suggested.title' | translate }}\" icon-off=\"ion-ios-personadd-outline\" icon-on=\"ion-ios-personadd\" ui-sref=\"suggested\">\n            <ion-nav-view name=\"suggested\"></ion-nav-view>\n        </ion-tab>\n\n        <ion-tab title=\"{{ 'tab.following' | translate }}\" icon-off=\"ion-ios-people-outline\" icon-on=\"ion-ios-people\" ui-sref=\"following\">\n            <ion-nav-view name=\"following\"></ion-nav-view>\n        </ion-tab>\n\n        <ion-tab title=\"{{ 'tab.follower' | translate }}\" icon-off=\"ion-person-stalker\" icon-on=\"ion-person-stalker\" ui-sref=\"follower\">\n            <ion-nav-view name=\"follower\"></ion-nav-view>\n        </ion-tab>\n\n    </ion-tabs>\n</ion-view>\n"
  },
  {
    "path": "mobile/www/app/components/follow/follow.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .config(followConfig);\n\n    followConfig.$inject = ['$stateProvider'];\n    function followConfig($stateProvider) {\n        $stateProvider\n            .state('follow', {\n                url: '/follow',\n                parent: 'tatami',\n                abstract: true,\n                templateUrl: 'app/components/follow/follow.html',\n                resolve: {\n                    currentUser: getCurrentUser,\n                    translatePartialLoader: getTranslatePartialLoader\n                }\n            });\n\n        getCurrentUser.$inject = ['ProfileService'];\n        function  getCurrentUser(ProfileService) {\n            return ProfileService.get().$promise;\n        }\n\n        getTranslatePartialLoader.$inject = ['$translate', '$translatePartialLoader'];\n        function getTranslatePartialLoader($translate, $translatePartialLoader) {\n            $translatePartialLoader.addPart('follow');\n            return $translate.refresh();\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/follow/follower/follower.controller.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .controller('FollowerCtrl', followerCtrl);\n\n    followerCtrl.$inject = ['followers', 'TatamiUserRefresherService', 'currentUser'];\n    function followerCtrl(followers, TatamiUserRefresherService, currentUser) {\n        var vm = this;\n        vm.followers = followers;\n        vm.getNewFollowers = getNewFollowers;\n\n        function getNewFollowers() {\n            TatamiUserRefresherService.refreshFollowers(currentUser).then(setUsers);\n        }\n\n        setUsers.$inject = ['followers'];\n        function setUsers(followers) {\n            vm.followers = followers;\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/follow/follower/follower.html",
    "content": "<ion-view view-title=\"{{ 'tab.follower' | translate }}\">\n    <ion-content class=\"tatami-header tatami-footer\" ng-style=\"{'background-color':'#f5f5f5'}\">\n        <ion-refresher on-refresh=\"vm.getNewFollowers()\"></ion-refresher>\n        <ion-list>\n            <div ng-repeat=\"user in vm.followers\">\n                <tatami-user user=\"user\"></tatami-user>\n            </div>\n        </ion-list>\n    </ion-content>\n</ion-view>\n"
  },
  {
    "path": "mobile/www/app/components/follow/follower/follower.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .config(config);\n\n    config.$inject = ['$stateProvider'];\n    function config($stateProvider) {\n        $stateProvider\n            .state('follower', {\n                url: '/follower',\n                parent: 'follow',\n                views: {\n                    'follower': {\n                        templateUrl: 'app/components/follow/follower/follower.html',\n                        controller: 'FollowerCtrl',\n                        controllerAs: 'vm'\n                    }\n                },\n                resolve: {\n                    followers: followers\n                }\n            });\n    }\n\n    followers.$inject = ['UserService', 'currentUser'];\n    function followers(UserService, currentUser) {\n        return UserService.getFollowers({ username: currentUser.username }).$promise;\n    }\n\n    angular.module('tatami')\n        .run(run);\n\n    run.$inject = ['TatamiState'];\n    function run(TatamiState) {\n        TatamiState.addProfileState('follower', 'follow');\n        TatamiState.addConversationState('follower', 'follow');\n        TatamiState.addTagState('follower', 'follow');\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/follow/following/following.controller.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .controller('FollowingCtrl', FollowingCtrl);\n\n    FollowingCtrl.$inject = ['following', 'TatamiUserRefresherService', 'currentUser'];\n\n    function FollowingCtrl(following, TatamiUserRefresherService, currentUser) {\n        var vm = this;\n        vm.following = following;\n        vm.getNewFollowing = getNewFollowing;\n\n        function getNewFollowing() {\n            TatamiUserRefresherService.refreshFollowing(currentUser).then(setUsers);\n        }\n\n        setUsers.$inject = ['following'];\n        function setUsers(following) {\n            vm.following = following;\n        }\n    }\n\n})();\n\n"
  },
  {
    "path": "mobile/www/app/components/follow/following/following.html",
    "content": "<ion-view view-title=\"{{ 'tab.following' | translate }}\">\n    <ion-content class=\"tatami-header tatami-footer\" ng-style=\"{'background-color':'#f5f5f5'}\">\n        <ion-refresher on-refresh=\"vm.getNewFollowing()\"></ion-refresher>\n        <ion-list>\n            <div ng-repeat=\"user in vm.following\">\n                <tatami-user user=\"user\"></tatami-user>\n            </div>\n        </ion-list>\n    </ion-content>\n</ion-view>\n"
  },
  {
    "path": "mobile/www/app/components/follow/following/following.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .config(config);\n\n    config.$inject = ['$stateProvider'];\n    function config($stateProvider) {\n        $stateProvider\n            .state('following', {\n                url: '/following',\n                parent: 'follow',\n                views: {\n                    'following': {\n                        templateUrl: 'app/components/follow/following/following.html',\n                        controller: 'FollowingCtrl',\n                        controllerAs: 'vm'\n                    }\n                },\n                resolve: {\n                    following: getFollowing\n                }\n            });\n    }\n\n    getFollowing.$inject = ['UserService', 'currentUser'];\n    function getFollowing(UserService, currentUser) {\n        return UserService.getFollowing({ username: currentUser.username }).$promise;\n    }\n\n    angular.module('tatami')\n        .run(run);\n\n    run.$inject = ['TatamiState'];\n    function run(TatamiState) {\n        TatamiState.addProfileState('following', 'follow');\n        TatamiState.addConversationState('following', 'follow');\n        TatamiState.addTagState('following', 'follow');\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/follow/suggested/suggested.controller.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .controller('SuggestedCtrl', suggestedCtrl);\n\n    suggestedCtrl.$inject = ['suggested', 'TatamiUserRefresherService'];\n    function suggestedCtrl(suggested, TatamiUserRefresherService) {\n        var vm = this;\n\n        vm.suggested = suggested;\n\n        vm.getNewSuggested = getNewSuggested;\n\n        function getNewSuggested() {\n            TatamiUserRefresherService.refreshSuggested().$promise.then(updateUsers);\n        }\n\n        updateUsers.$inject = ['suggested'];\n        function updateUsers(suggested) {\n            vm.suggested = suggested;\n        }\n    }\n})();\n\n"
  },
  {
    "path": "mobile/www/app/components/follow/suggested/suggested.html",
    "content": "<ion-view view-title=\"{{ 'tab.suggested.who' | translate }}\">\n    <ion-content class=\"tatami-header tatami-footer\" ng-style=\"{'background-color':'#f5f5f5'}\">\n        <ion-refresher on-refresh=\"vm.getNewSuggested()\"></ion-refresher>\n        <ion-list>\n            <div ng-repeat=\"user in vm.suggested\">\n                <tatami-user user=\"user\"></tatami-user>\n            </div>\n        </ion-list>\n    </ion-content>\n</ion-view>\n"
  },
  {
    "path": "mobile/www/app/components/follow/suggested/suggested.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .config(config);\n\n    config.$inject = ['$stateProvider'];\n    function config($stateProvider) {\n        $stateProvider\n            .state('suggested', {\n                url: '/suggested',\n                parent: 'follow',\n                views: {\n                    'suggested': {\n                        templateUrl: 'app/components/follow/suggested/suggested.html',\n                        controller: 'SuggestedCtrl',\n                        controllerAs: 'vm'\n                    }\n                },\n                resolve: {\n                    suggested: getSuggested\n                }\n            });\n    }\n\n    getSuggested.$inject = ['UserService'];\n    function getSuggested(UserService) {\n        return UserService.getSuggestions().$promise;\n    }\n\n    angular.module('tatami')\n        .run(run);\n\n    run.$inject = ['TatamiState'];\n    function run(TatamiState) {\n        TatamiState.addProfileState('suggested', 'follow');\n        TatamiState.addConversationState('suggested', 'follow');\n        TatamiState.addTagState('suggested', 'follow');\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/home/favorites/favorites.controller.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .controller('FavoritesCtrl', favoritesCtrl);\n\n    favoritesCtrl.$inject = ['favorites', 'currentUser', 'TatamiStatusRefresherService', '$q'];\n    function favoritesCtrl(favorites, currentUser, TatamiStatusRefresherService, $q) {\n        var vm = this;\n        vm.favorites = favorites;\n        vm.currentUser = currentUser;\n        vm.getNewStatuses = getNewStatuses;\n        vm.getEmpty = getEmpty;\n\n        function getNewStatuses() {\n            return TatamiStatusRefresherService.refreshFavorites();\n        }\n\n        getEmpty.$inject = ['finalStatus'];\n        function getEmpty(finalStatus) {\n            var deferred = $q.defer();\n            deferred.resolve([]);\n            return deferred.promise;\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/home/favorites/favorites.html",
    "content": "<ion-view view-title=\"{{ 'tab.favorites' | translate }}\" ng-style=\"{'background-color':'#f5f5f5'}\">\n    <tatami-status-list statuses=\"vm.favorites\"\n                        current-user=\"vm.currentUser\"\n                        tatami-refresher=\"vm.getNewStatuses()\"\n                        tatami-infinite-refresher=\"vm.getEmpty(finalStatus)\"></tatami-status-list>\n</ion-view>\n"
  },
  {
    "path": "mobile/www/app/components/home/favorites/favorites.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .config(config);\n\n    config.$inject = ['$stateProvider'];\n    function config($stateProvider) {\n        $stateProvider\n            .state('favorites', {\n                url: '/favorites',\n                parent: 'home',\n                views: {\n                    'favorites': {\n                        templateUrl: 'app/components/home/favorites/favorites.html',\n                        controller: 'FavoritesCtrl',\n                        controllerAs: 'vm'\n                    }\n                },\n                resolve: {\n                    favorites: favorites\n                }\n            });\n\n        favorites.$inject = ['HomeService'];\n        function favorites(HomeService) {\n            return HomeService.getFavorites().$promise;\n        }\n    }\n\n    angular.module('tatami')\n        .run(run);\n\n    run.$inject = ['TatamiState'];\n    function run(TatamiState) {\n        TatamiState.addProfileState('favorites', 'home');\n        TatamiState.addConversationState('favorites', 'home');\n        TatamiState.addTagState('favorites', 'home');\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/home/home.html",
    "content": "<ion-tabs class=\"tabs-icon-top tabs-color-active-positive\">\n    <!-- Dashboard Tab -->\n    <ion-tab title=\"{{ 'tab.timeline' | translate }}\"\n             icon-off=\"ion-ios-list-outline\"\n             icon-on=\"ion-ios-list\"\n             ui-sref=\"timeline\">\n        <ion-nav-view name=\"timeline\"></ion-nav-view>\n    </ion-tab>\n\n    <!-- Chats Tab -->\n    <ion-tab title=\"{{ 'tab.mentions' | translate }}\"\n             icon-off=\"ion-ios-chatbubble-outline\"\n             icon-on=\"ion-ios-chatbubble\"\n             ui-sref=\"mentions\">\n        <ion-nav-view name=\"mentions\"></ion-nav-view>\n    </ion-tab>\n\n    <!-- Account Tab -->\n    <ion-tab title=\"{{ 'tab.favorites' | translate }}\"\n             icon-off=\"ion-android-star-outline\"\n             icon-on=\"ion-android-star\"\n             ui-sref=\"favorites\">\n        <ion-nav-view name=\"favorites\"></ion-nav-view>\n    </ion-tab>\n\n    <ion-tab title=\"{{ 'tab.more' | translate }}\"\n             icon-off=\"ion-navicon-round\"\n             icon-on=\"ion-navicon-round\"\n             ui-sref=\"more\">\n        <ion-nav-view name=\"more\"></ion-nav-view>\n    </ion-tab>\n\n</ion-tabs>\n"
  },
  {
    "path": "mobile/www/app/components/home/home.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .config(homeConfig);\n\n    homeConfig.$inject = ['$stateProvider'];\n    function homeConfig($stateProvider) {\n        $stateProvider\n            .state('home', {\n                parent: 'tatami',\n                abstract: true,\n                url: '/home',\n                templateUrl: 'app/components/home/home.html',\n                resolve: {\n                    currentUser: getCurrentUser,\n                    translatePartialLoader: getTranslatePartialLoader\n                }\n            })\n    }\n\n    getCurrentUser.$inject = ['ProfileService'];\n    function getCurrentUser(ProfileService) {\n        return ProfileService.get().$promise.then(function(currentUser) {\n            console.log(currentUser);\n            return currentUser;\n        });\n    }\n\n    getTranslatePartialLoader.$inject = ['$translate', '$translatePartialLoader'];\n    function getTranslatePartialLoader($translate, $translatePartialLoader) {\n        $translatePartialLoader.addPart('home');\n        return $translate.refresh();\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/home/mentions/mentions.controller.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .controller('MentionsCtrl', mentionsCtrl);\n\n    mentionsCtrl.$inject = ['mentioned', 'currentUser', 'TatamiStatusRefresherService'];\n    function mentionsCtrl(mentioned, currentUser, TatamiStatusRefresherService) {\n        var vm = this;\n        vm.mentioned = mentioned;\n        vm.currentUser = currentUser;\n\n        vm.remove = remove;\n        vm.getNewStatuses = getNewStatuses;\n        vm.getOldStatuses = getOldStatuses;\n\n        remove.$inject = ['mention'];\n        function remove(mention) {\n            vm.mentioned.splice(vm.mentioned.indexOf(mention), 1);\n        }\n\n        function getNewStatuses() {\n            return TatamiStatusRefresherService.refreshMentions();\n        }\n\n        getOldStatuses.$inject = ['finalStatus'];\n        function getOldStatuses(finalStatus) {\n            return TatamiStatusRefresherService.getOldMentions(finalStatus);\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/home/mentions/mentions.html",
    "content": "<ion-view view-title=\"{{ 'tab.mentions' | translate }}\" ng-style=\"{'background-color':'#f5f5f5'}\">\n    <tatami-status-list statuses=\"vm.mentioned\"\n                        current-user=\"vm.currentUser\"\n                        tatami-refresher=\"vm.getNewStatuses()\"\n                        tatami-infinite-refresher=\"vm.getOldStatuses(finalStatus)\"></tatami-status-list>\n</ion-view>\n"
  },
  {
    "path": "mobile/www/app/components/home/mentions/mentions.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .config(config);\n\n    config.$inject = ['$stateProvider'];\n    function config($stateProvider) {\n        $stateProvider\n            .state('mentions', {\n                url: '/mentions',\n                parent: 'home',\n                views: {\n                    'mentions': {\n                        templateUrl: 'app/components/home/mentions/mentions.html',\n                        controller: 'MentionsCtrl',\n                        controllerAs: 'vm'\n                    }\n                },\n                resolve: {\n                    mentioned: mentioned\n                }\n            });\n    }\n\n    angular.module('tatami')\n        .run(run);\n\n    run.$inject = ['TatamiState'];\n    function run(TatamiState) {\n        TatamiState.addProfileState('mentions', 'home');\n        TatamiState.addConversationState('mentions', 'home');\n        TatamiState.addTagState('mentions', 'home');\n    }\n\n    mentioned.$inject = ['HomeService'];\n    function mentioned(HomeService) {\n        return HomeService.getMentions().$promise;\n    }\n\n})();\n\n"
  },
  {
    "path": "mobile/www/app/components/home/more/all_users/all.users.controller.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .controller('AllUsersController', allUsersController);\n\n    allUsersController.$inject = ['currentUser', 'TatamiUserRefresherService', '$scope', '$timeout'];\n    function allUsersController(currentUser, TatamiUserRefresherService, $scope, $timeout) {\n        var vm = this;\n        vm.currentUser = currentUser;\n        vm.users = [];\n        vm.isFinished = false;\n\n        vm.getNextUsers = getNextUsers;\n\n        function getNextUsers() {\n            return TatamiUserRefresherService.getNextUsers(vm.users.length).then(addUsers);\n        }\n\n        addUsers.$inject = ['users'];\n        function addUsers(nextUsers) {\n            $timeout(function() {\n                $scope.$apply(function() {\n                    vm.users.push.apply(vm.users, nextUsers);\n                    vm.isFinished = nextUsers.length === 0;\n                });\n            })\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/home/more/all_users/all.users.html",
    "content": "<ion-view view-title=\"{{ 'more.allUsers' | translate }}\">\n    <ion-content class=\"tatami-header tatami-footer\" ng-style=\"{'background-color':'#f5f5f5'}\">\n        <ion-list ng-init=\"vm.getAllUsers()\">\n            <div ng-repeat=\"user in vm.users\">\n                <tatami-user user=\"user\" current-user=\"vm.currentUser\"></tatami-user>\n            </div>\n        </ion-list>\n        <ion-infinite-scroll ng-if=\"!vm.isFinished\" on-infinite=\"vm.getNextUsers()\"></ion-infinite-scroll>\n    </ion-content>\n</ion-view>\n"
  },
  {
    "path": "mobile/www/app/components/home/more/all_users/all.users.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .config(config);\n\n    config.$inject = ['$stateProvider'];\n    function config($stateProvider) {\n\n        $stateProvider\n            .state('allusers', {\n                url: '/allusers',\n                parent: 'more',\n                views: {\n                    'more@home': {\n                        templateUrl: 'app/components/home/more/all_users/all.users.html',\n                        controller: 'AllUsersController',\n                        controllerAs: 'vm'\n                    }\n                }\n            });\n    }\n\n    angular.module('tatami')\n        .run(run);\n\n    run.$inject = ['TatamiState'];\n    function run(TatamiState) {\n        TatamiState.addProfileState('allusers', 'home');\n        TatamiState.addConversationState('allusers', 'home');\n        TatamiState.addTagState('allusers', 'home');\n    }\n\n})();\n"
  },
  {
    "path": "mobile/www/app/components/home/more/blocked_users/blocked.users.controller.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .controller('BlockedUsersController', blockedUsersController);\n\n    blockedUsersController.$inject = ['$scope', 'currentUser', 'BlockService'];\n    function blockedUsersController($scope, currentUser, BlockService) {\n        var vm = this;\n        vm.currentUser = currentUser;\n        vm.blockedUsers = [];\n\n        vm.updateUser = updateUser;\n        vm.getBlockedUsersForUser = getBlockedUsersForUser;\n        vm.hasBlockedUsers = hasBlockedUsers;\n\n        function updateUser() {\n            BlockService.updateBlockedUser(\n                {username: vm.status.username}\n            );\n        }\n\n        function getBlockedUsersForUser() {\n            BlockService.getBlockedUsersForUser(\n                {username: vm.currentUser.username},\n                function (response) {\n                    vm.blockedUsers = response;\n                }\n            );\n            $scope.$broadcast('scroll.refreshComplete');\n        }\n\n        function  hasBlockedUsers() {\n            return vm.blockedUsers.length>0;\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/home/more/blocked_users/blocked.users.html",
    "content": "<ion-view view-title=\"{{ 'more.blockedUsers.title' | translate }}\">\n    <ion-content ng-style=\"{'background-color':'#f5f5f5'}\">\n        <ion-refresher on-refresh=\"vm.getBlockedUsersForUser()\"></ion-refresher>\n        <ion-list ng-init=\"vm.getBlockedUsersForUser()\">\n            <div class=\"text-center\" ng-if=\"!vm.hasBlockedUsers()\" translate=\"more.blockedUsers.no\" ng-style=\"{'color':'#ababab','padding':'40px'}\"/>\n            <div ng-if=\"vm.hasBlockedUsers()\" ng-repeat=\"blockeduser in vm.blockedUsers\">\n                <tatami-user user=\"blockeduser\"></tatami-user>\n            </div>\n        </ion-list>\n    </ion-content>\n</ion-view>\n"
  },
  {
    "path": "mobile/www/app/components/home/more/blocked_users/blocked.users.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .config(config);\n\n    config.$inject = ['$stateProvider'];\n    function config($stateProvider) {\n\n        $stateProvider\n            .state('blockedusers', {\n                url: '/blockedusers',\n                parent: 'more',\n                views: {\n                    'more@home': {\n                        templateUrl: 'app/components/home/more/blocked_users/blocked.users.html',\n                        controller: 'BlockedUsersController',\n                        controllerAs: 'vm'\n                    }\n                }\n            });\n    }\n\n    angular.module('tatami')\n        .run(run);\n\n    run.$inject = ['TatamiState'];\n    function run(TatamiState) {\n        TatamiState.addProfileState('blockedusers', 'home');\n        TatamiState.addConversationState('blockedusers', 'home');\n        TatamiState.addTagState('blockedusers', 'home');\n    }\n\n})();\n"
  },
  {
    "path": "mobile/www/app/components/home/more/company/company-timeline.html",
    "content": "<ion-view view-title=\"{{ 'more.company' | translate }}\" ng-style=\"{'background-color':'#f5f5f5'}\">\n    <tatami-status-list statuses=\"vm.statuses\"\n                        current-user=\"vm.currentUser\"\n                        tatami-refresher=\"vm.getNewStatuses()\"\n                        tatami-infinite-refresher=\"vm.getOldStatuses(finalStatus)\"></tatami-status-list>\n</ion-view>\n"
  },
  {
    "path": "mobile/www/app/components/home/more/company/company.timeline.controller.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .controller('CompanyTimelineCtrl', companyTimelineCtrl);\n\n    companyTimelineCtrl.$inject = ['statuses', 'currentUser', 'TatamiStatusRefresherService'];\n    function companyTimelineCtrl(statuses, currentUser, TatamiStatusRefresherService) {\n        var vm = this;\n        vm.statuses = statuses;\n        vm.currentUser = currentUser;\n\n        vm.getNewStatuses = getNewStatuses;\n        vm.getOldStatuses = getOldStatuses;\n\n        function getNewStatuses() {\n            return TatamiStatusRefresherService.refreshCompanyTimeline();\n        }\n\n        getOldStatuses.$inject = ['finalStatus'];\n        function getOldStatuses(finalStatus) {\n            return TatamiStatusRefresherService.getOldFromCompanyTimeline(finalStatus);\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/home/more/company/company.timeline.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .config(config);\n\n    config.$inject = ['$stateProvider'];\n    function config($stateProvider) {\n\n        $stateProvider\n            .state('company', {\n                url: '/company/timeline',\n                parent: 'more',\n                views: {\n                    'more@home': {\n                        templateUrl: 'app/components/home/more/company/company-timeline.html',\n                        controller: 'CompanyTimelineCtrl',\n                        controllerAs: 'vm'\n                    }\n                },\n                resolve: {\n                    statuses: getStatuses\n                }\n            });\n\n        getStatuses.$inject = ['HomeService'];\n        function getStatuses(HomeService) {\n            return HomeService.getCompanyTimeline().$promise;\n        }\n    }\n\n    angular.module('tatami')\n        .run(run);\n\n    run.$inject = ['TatamiState'];\n    function run(TatamiState) {\n        TatamiState.addProfileState('company', 'home');\n        TatamiState.addConversationState('company', 'home');\n        TatamiState.addTagState('company', 'home');\n    }\n\n})();\n"
  },
  {
    "path": "mobile/www/app/components/home/more/more.controller.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .controller('MoreController', moreController);\n\n    moreController.$inject = [\n        '$state',\n        '$localStorage',\n        'currentUser'\n    ];\n    function moreController($state, $localStorage, currentUser) {\n        var vm = this;\n\n        vm.currentUser = currentUser;\n        vm.logout = logout;\n        vm.goToCompanyTimeline = goToCompanyTimeline;\n        vm.goToSettings = goToSettings;\n        vm.goToBlockedUsers = goToBlockedUsers;\n        vm.goToAllUsers = goToAllUsers;\n        vm.goToReportedStatus = goToReportedStatus;\n\n        function logout() {\n            $localStorage.signOut();\n            $state.go('login');\n        }\n\n        function goToCompanyTimeline() {\n            $state.go('company');\n        }\n\n        function goToSettings() {\n            $state.go('settings');\n        }\n\n        function goToBlockedUsers(){\n            $state.go('blockedusers');\n        }\n\n        function goToReportedStatus(){\n            $state.go('reportedStatus')\n        }\n\n        function goToAllUsers() {\n            $state.go('allusers')\n        }\n\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/home/more/more.html",
    "content": "<ion-view view-title=\"{{ 'tab.more' | translate }}\">\n    <ion-content class=\"tatami-header tatami-footer\" ng-style=\"{'background-color':'#f5f5f5'}\">\n        <ion-list>\n            <div>\n                <tatami-user user=\"vm.currentUser\" current-user=\"vm.currentUser\"></tatami-user>\n            </div>\n            <ion-item ng-click=\"vm.goToCompanyTimeline()\" class=\"text-center\">\n                <span class=\"ion-briefcase calm padding-right\"></span>&nbsp;\n                <span class=\"calm\" translate=\"more.company\">Company Timeline</span>\n            </ion-item>\n            <ion-item class=\"text-center\" ng-click=\"vm.goToAllUsers()\">\n                <span class=\"ion-earth padding-right\"></span>\n                <span translate=\"more.allUsers\">All users</span>\n            </ion-item>\n            <ion-item class=\"item-divider\"></ion-item>\n            <ion-item ng-click=\"vm.goToSettings()\" class=\"text-center\">\n                <span class=\"ion-gear-a padding-right\"></span>&nbsp;\n                <span translate=\"more.settings\">Settings</span>\n            </ion-item>\n            <ion-item class=\"text-center\" ng-click=\"vm.goToBlockedUsers()\">\n                <span class=\"ion-close-circled padding-right\"></span>\n                <span translate=\"more.blockedUsers.title\">Manage your blocked users</span>\n            </ion-item>\n            <ion-item ng-if=\"vm.currentUser.isAdmin\" class=\"text-center\" ng-click=\"vm.goToReportedStatus()\">\n                <span class=\"ion-alert-circled\"></span>\n                <span translate=\"more.reportedStatus.title\">Reported Statuses</span>\n            </ion-item>\n            <ion-item class=\"item-divider\"></ion-item>\n            <ion-item ng-click=\"vm.logout()\" class=\"text-center\">\n                <span class=\"ion-power padding-right assertive\"></span>&nbsp;\n                <span class=\"assertive\" translate=\"more.logout\">Logout</span>\n            </ion-item>\n        </ion-list>\n    </ion-content>\n</ion-view>\n"
  },
  {
    "path": "mobile/www/app/components/home/more/more.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .config(moreConfig);\n\n    moreConfig.$inject = ['$stateProvider'];\n    function moreConfig($stateProvider) {\n        $stateProvider\n            .state('more', {\n                url: '/more',\n                parent: 'home',\n                views: {\n                    'more': {\n                        templateUrl: 'app/components/home/more/more.html',\n                        controller: 'MoreController',\n                        controllerAs: 'vm'\n                    }\n                },\n                resolve: {\n                    translatePartialLoader: getTranslatePartialLoader\n                }\n            });\n\n        getTranslatePartialLoader.$inject = ['$translate', '$translatePartialLoader'];\n        function getTranslatePartialLoader($translate, $translatePartialLoader) {\n            $translatePartialLoader.addPart('more');\n            return $translate.refresh();\n        }\n    }\n\n    angular.module('tatami')\n        .run(run);\n\n    run.$inject = ['TatamiState'];\n    function run(TatamiState) {\n        TatamiState.addProfileState('more', 'home');\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/home/more/reportedStatus/reportedStatus.controller.js",
    "content": "/**\n * Created by emilyklein on 7/11/16.\n */\n(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .controller('ReportedStatusController', reportedStatusController);\n\n    reportedStatusController.$inject = ['$state', '$scope', 'currentUser', 'ReportService', '$ionicPopup', '$translate', 'ToastService'];\n    function reportedStatusController($state, $scope, currentUser, ReportService, $ionicPopup, $translate, ToastService) {\n        var vm = this;\n\n        vm.reportedStatuses = [];\n        vm.currentUser = currentUser;\n\n        vm.getReportedStatuses = getReportedStatuses;\n        vm.hasReportedStatus = hasReportedStatus;\n        vm.approveStatus = approveStatus;\n        vm.deleteStatus = deleteStatus;\n\n        function reportStatus() {\n            ReportService.reportStatus({statusId: vm.status.statusId});\n            $ionicPopup.alert({\n                title: 'Report',\n                template: '<span translate=\"status.reportMessage\"></span>'\n            });\n        }\n\n        goToProfile.$inject = ['username'];\n        function goToProfile(username) {\n            var destinationState = $state.current.name.split('.')[0] + '.profile';\n            $state.go(destinationState, { username : username });\n        }\n\n        function getReportedStatuses(){\n            ReportService.getReportedStatuses(null, function(response){\n                    vm.reportedStatuses = response;\n                }\n            );\n            $scope.$broadcast('scroll.refreshComplete');\n        }\n\n        function deleteStatus(statusId){\n            var confirmPopup = $ionicPopup.confirm({\n                title: 'Delete Status',\n                template: '<span translate=\"status.reportStatus.delete\"></span>'\n            });\n            confirmPopup.then(deleted);\n            deleted.$inject = ['decision'];\n            function deleted(decision) {\n                if(decision) {\n                    ReportService.deleteStatus({statusId: statusId}, function () {\n                        ToastService.display('status.reportStatus.deleteToast');\n                        }\n                    );\n                    $state.go($state.current, {}, {reload: true});\n                }\n            }\n        }\n\n        function approveStatus(statusId){\n            var confirmPopup = $ionicPopup.confirm({\n                title: 'Approve Status',\n                template: '<span translate=\"status.reportStatus.approve\"></span>'\n            });\n            confirmPopup.then(approved);\n            approved.$inject = ['decision'];\n            function approved(decision) {\n                if(decision) {\n                    ReportService.approveStatus({statusId: statusId}, function () {\n                        ToastService.display('status.reportStatus.approveToast');\n                        }\n                    );\n                    $state.go($state.current, {}, {reload: true});\n                }\n            }\n        }\n\n        remove.$inject = ['status'];\n        function remove(status) {\n            vm.statuses.splice(vm.statuses.indexOf(status), 1);\n        }\n\n        function  hasReportedStatus() {\n            return vm.reportedStatuses.length > 0\n        }\n    }\n})();\n\n\n"
  },
  {
    "path": "mobile/www/app/components/home/more/reportedStatus/reportedStatus.html",
    "content": "<ion-view view-title=\"{{ 'more.reportedStatus.title' | translate }}\">\n    <ion-content class=\"tatami-header tatami-footer\">\n        <ion-refresher on-refresh=\"vm.getReportedStatuses()\"></ion-refresher>\n        <ion-list ng-init=\"vm.getReportedStatuses()\">\n            <ion-item ng-if=\"vm.hasReportedStatus()\" ng-repeat=\"status in vm.reportedStatuses\" >\n                <tatami-status status = \"status\" current-user = \"vm.currentUser\" on-delete = \"vm.remove(status)\"></tatami-status>\n                <div class=\"row\">\n                    <div class=\"col-25 button button-clear ion-checkmark-round\" ng-click=\"vm.approveStatus(status.statusId)\"></div>\n                    <div class=\"col-25 button button-clear ion-close-round\" ng-click=\"vm.deleteStatus(status.statusId)\"></div>\n                </div>\n            </ion-item>\n            <div class=\"text-center\" ng-if=\"!vm.hasReportedStatus()\" translate=\"more.reportedStatus.no\" ng-style=\"{'color':'#ababab','padding':'40px'}\"/>\n        </ion-list>\n    </ion-content>\n</ion-view>\n"
  },
  {
    "path": "mobile/www/app/components/home/more/reportedStatus/reportedStatus.js",
    "content": "/**\n * Created by emilyklein on 7/11/16.\n */\n(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .config(config);\n\n    config.$inject = ['$stateProvider'];\n    function config($stateProvider) {\n\n        $stateProvider\n            .state('reportedStatus', {\n                cache: false,\n                url: '/reportedStatus',\n                parent: 'more',\n                views: {\n                    'more@home': {\n                        templateUrl: 'app/components/home/more/reportedStatus/reportedStatus.html',\n                        controller: 'ReportedStatusController',\n                        controllerAs: 'vm'\n                    }\n                }\n            });\n    }\n\n    angular.module('tatami')\n        .run(run);\n\n    run.$inject = ['TatamiState'];\n    function run(TatamiState) {\n        TatamiState.addProfileState('reportedStatus', 'home');\n        TatamiState.addConversationState('reportedStatus', 'home');\n        TatamiState.addTagState('reportedStatus', 'home');\n    }\n\n})();\n"
  },
  {
    "path": "mobile/www/app/components/home/more/settings/settings.controller.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .controller('SettingsController', settingsController);\n\n    settingsController.$inject = ['$scope', '$translate', 'currentUser'];\n    function settingsController($scope, $translate, currentUser) {\n        var vm = this;\n        vm.currentUser = currentUser;\n\n        vm.language = window.localStorage.getItem('language');\n\n        vm.languages = [\n            {\n                langKey: 'en',\n                translateKey: 'more.language.english'\n            },\n            {\n                langKey: 'fr',\n                translateKey: 'more.language.french'\n            }\n        ];\n\n        $scope.$watch('vm.language', updateLanguage);\n\n        function updateLanguage(language) {\n            $translate.use(language);\n            window.localStorage.setItem('language', language);\n        }\n\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/home/more/settings/settings.html",
    "content": "<ion-view view-title=\"{{ 'more.settings' | translate }}\">\n    <ion-content ng-style=\"{'background-color':'#f5f5f5'}\">\n        <ion-list>\n            <ion-item class=\"item-divider\" translate=\"more.language.change\"></ion-item>\n            <ion-radio ng-repeat=\"language in vm.languages\"\n                       ng-model=\"vm.language\"\n                       ng-value=\"language.langKey\">\n                {{ language.translateKey | translate }}\n            </ion-radio>\n        </ion-list>\n    </ion-content>\n</ion-view>\n"
  },
  {
    "path": "mobile/www/app/components/home/more/settings/settings.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .config(config);\n\n    config.$inject = ['$stateProvider'];\n    function config($stateProvider) {\n\n        $stateProvider\n            .state('settings', {\n                url: '/settings',\n                parent: 'more',\n                views: {\n                    'more@home': {\n                        templateUrl: 'app/components/home/more/settings/settings.html',\n                        controller: 'SettingsController',\n                        controllerAs: 'vm'\n                    }\n                }\n            });\n    }\n\n    angular.module('tatami')\n        .run(run);\n\n    run.$inject = ['TatamiState'];\n    function run(TatamiState) {\n        TatamiState.addProfileState('settings', 'home');\n        TatamiState.addConversationState('settings', 'home');\n        TatamiState.addTagState('settings', 'home');\n    }\n\n})();\n"
  },
  {
    "path": "mobile/www/app/components/home/timeline/timeline.controller.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .controller('TimelineCtrl', timelineCtrl);\n\n    timelineCtrl.$inject = ['statuses', 'currentUser', 'TatamiStatusRefresherService'];\n    function timelineCtrl(statuses, currentUser, TatamiStatusRefresherService) {\n        var vm = this;\n\n        vm.statuses = statuses;\n        vm.currentUser = currentUser;\n        vm.getNewStatuses = getNewStatuses;\n        vm.getOldStatuses = getOldStatuses;\n\n        function getNewStatuses() {\n            return TatamiStatusRefresherService.refreshHomeTimeline();\n        }\n\n        getOldStatuses.$inject = ['finalStatus'];\n        function getOldStatuses(finalStatus) {\n            return TatamiStatusRefresherService.getOldFromHomeTimeline(finalStatus);\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/home/timeline/timeline.html",
    "content": "<ion-view view-title=\"{{ 'tab.timeline' | translate }}\" ng-style=\"{'background-color':'#f5f5f5'}\">\n    <tatami-status-list statuses=\"vm.statuses\"\n                        current-user=\"vm.currentUser\"\n                        tatami-refresher=\"vm.getNewStatuses()\"\n                        tatami-infinite-refresher=\"vm.getOldStatuses(finalStatus)\"></tatami-status-list>\n</ion-view>\n"
  },
  {
    "path": "mobile/www/app/components/home/timeline/timeline.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .config(config);\n\n    config.$inject = ['$stateProvider'];\n    function config($stateProvider) {\n\n        $stateProvider\n            .state('timeline', {\n                url: '/timeline',\n                parent: 'home',\n                views: {\n                    'timeline': {\n                        templateUrl: 'app/components/home/timeline/timeline.html',\n                        controller: 'TimelineCtrl',\n                        controllerAs: 'vm'\n                    }\n                },\n                resolve: {\n                    statuses: getStatuses\n                }\n            });\n\n        getStatuses.$inject = ['StatusService'];\n        function getStatuses(StatusService) {\n            return StatusService.getHomeTimeline().$promise;\n        }\n    }\n\n    angular.module('tatami')\n        .run(run);\n\n    run.$inject = ['TatamiState'];\n    function run(TatamiState) {\n        TatamiState.addProfileState('timeline', 'home');\n        TatamiState.addConversationState('timeline', 'home');\n        TatamiState.addTagState('timeline', 'home');\n    }\n\n})();\n"
  },
  {
    "path": "mobile/www/app/components/login/login.controller.js",
    "content": "(function () {\n    'use strict';\n\n    angular.module('tatami')\n        .controller('LoginCtrl', loginCtrl);\n\n    loginCtrl.$inject = [\n        'TatamiEndpoint',\n        '$scope',\n        '$state',\n        '$http',\n        '$localStorage',\n        '$ionicLoading',\n        'PathService',\n        '$ionicHistory',\n        'ToastService'\n    ];\n    function loginCtrl(TatamiEndpoint, $scope, $state, $http, $localStorage, $ionicLoading, PathService, $ionicHistory, ToastService) {\n\n        var vm = this;\n\n        $scope.$on(\"$ionicView.enter\", function () {\n            $ionicHistory.clearCache();\n            $ionicHistory.clearHistory();\n            var newEndpoint = TatamiEndpoint.getEndpoint();\n            if (vm.lastEndpoint.url !== newEndpoint.url) {\n                vm.lastEndpoint.url = newEndpoint.url;\n                vm.failed = false;\n            }\n        });\n\n        vm.user = {\n            remember: false\n        };\n        vm.failed = false;\n        vm.login = login;\n        vm.tryGoogleLogin = tryGoogleLogin;\n        vm.goToServerConfig = goToServerConfig;\n        vm.lastEndpoint = {url: ''};\n\n        function login() {\n            var data = \"j_username=\" + encodeURIComponent(vm.user.email) + \"&j_password=\"\n                + encodeURIComponent(vm.user.password);\n            return $http.post('/tatami/rest/authentication', data, {\n                headers: {\n                    \"Content-Type\": \"application/x-www-form-urlencoded\",\n                    \"Accept\": \"application/json\"\n                }\n            }).success(function (data) {\n                $localStorage.set('token', data.token);\n                vm.user = {remember: false};\n                $state.go('timeline');\n            }).error(function () {\n                vm.failed = true;\n            });\n        }\n\n        function tryGoogleLogin() {\n            $http({\n                url: '/tatami/rest/client/id',\n                method: 'GET'\n            }).then(function (data) {\n                var clientId;\n                if (data && data.data && data.data.stringList) {\n                    // Old tatami return the clientId in the stringList property\n                    clientId = data.data.stringList[0];\n                } else if (data && data.data && data.data.clientId) {\n                    clientId = data.data.clientId;\n                }\n\n                // Do Google login or display an error message\n                if (clientId) {\n                    googleLogin(clientId);\n                } else {\n                    ToastService.display('login.googleUnavaible');\n                }\n            }, function () {\n                ToastService.display('login.googleUnavaible');\n            });\n        }\n\n        function googleLogin(clientId) {\n            var emailScope = 'https://www.googleapis.com/auth/plus.profile.emails.read';\n            var profileScope = 'https://www.googleapis.com/auth/plus.me';\n            var googleUrl = 'https://accounts.google.com/o/oauth2/auth?' +\n                'client_id=' + clientId + '&' +\n                'redirect_uri=http://localhost/callback&' +\n                'scope=' + emailScope + ' ' + profileScope + '&' +\n                'approval_prompt=force&response_type=code&access_type=offline';\n\n            var ref = window.open(googleUrl, '_blank', 'location=no');\n\n            ref.addEventListener('loadstart', onStart);\n\n            onStart.$inject = ['event'];\n            function onStart(event) {\n                if (event.url.indexOf('http://localhost/callback') === 0) {\n                    ref.close();\n                    $ionicLoading.show({\n                        template: '<span translate=\"login.progress\">Login in progress...</span>',\n                        hideOnStateChange: true\n                    });\n                    var requestToken = event.url.split(\"code=\")[1];\n                    $http({\n                        url: '/tatami/rest/oauth/token',\n                        method: 'POST',\n                        headers: {\n                            'x-auth-code-header': requestToken\n                        }\n                    }).then(onSuccess, onFail);\n                }\n            }\n\n            onSuccess.$inject = ['result'];\n            function onSuccess(result) {\n                $localStorage.set('token', result.data.token);\n                $state.go('timeline');\n            }\n\n            onFail.$inject = ['failure'];\n            function onFail() {\n                vm.failed = true;\n            }\n        }\n\n        function goToServerConfig() {\n            $state.go('server');\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/login/login.html",
    "content": "<ion-view name=\"login-view\" view-title=\"{{ 'login.title' | translate }}\" hide-back-button=\"true\">\n    <ion-content class=\"has-header\" scroll=\"false\">\n        <form ng-submit=\"vm.login()\">\n            <div class=\"list list-inset\">\n                <label class=\"item item-input\">\n                    <input type=\"text\" autocapitalize=\"off\" autocorrect=\"off\" placeholder=\"{{ 'login.email' | translate }}\" ng-model=\"vm.user.email\">\n                </label>\n                <label class=\"item item-input\">\n                    <input type=\"password\" placeholder=\"{{ 'login.password' | translate }}\" ng-model=\"vm.user.password\">\n                </label>\n            </div>\n\n            <div align=\"center\">\n                <label class=\"toggle v-align\">\n                    <input type=\"checkbox\" ng-model=\"vm.tos\">\n                    <div class=\"track\">\n                        <div class=\"handle\"></div>\n                    </div>\n                </label>\n                <span translate=\"login.accept\"></span>\n                <a href=\"http://tatami.ippon.fr/#/about/tos\" translate=\"login.tos\"></a>\n            </div>\n            <div class=\"row\">\n                <div class=\"col col-50\">\n                    <button ng-disabled=\"!vm.user.email && !vm.user.password || !vm.tos\"\n                            translate=\"login.title\"\n                            class=\"button button-block button-calm\"\n                            type=\"submit\">\n                        Login\n                    </button>\n                </div>\n                <div class=\"col col-50\">\n                    <button ng-disabled=\"!vm.tos\"\n                            ng-click=\"vm.tryGoogleLogin()\"\n                            translate=\"login.google\"\n                            class=\"button button-block button-stable\"\n                            type=\"button\">\n                        Google Login\n                    </button>\n                </div>\n            </div>\n            <div class=\"row\">\n                <button class=\"button button-block button-stable\"\n                        type=\"button\"\n                        ng-click=\"vm.goToServerConfig()\">\n                    <span>{{ 'login.changeServer' | translate }}</span>\n                </button>\n            </div>\n\n            <div ng-show=\"vm.failed\" class=\"bar bar-assertive\">\n                <h1 class=\"title\" translate=\"login.failed\">Failed to log in!</h1>\n            </div>\n        </form>\n    </ion-content>\n</ion-view>\n"
  },
  {
    "path": "mobile/www/app/components/login/login.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .config(config);\n\n    config.$inject = ['$stateProvider'];\n    function config($stateProvider) {\n        $stateProvider\n            .state('login', {\n                url: '/login',\n                parent: 'tatami',\n                templateUrl: 'app/components/login/login.html',\n                controller: 'LoginCtrl',\n                controllerAs: 'vm',\n                resolve: {\n                    translatePartialLoader: getTranslatePartialLoader\n                }\n            });\n\n        getTranslatePartialLoader.$inject = ['$translate', '$translatePartialLoader'];\n        function getTranslatePartialLoader($translate, $translatePartialLoader) {\n            $translatePartialLoader.addPart('login');\n            return $translate.refresh();\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/login/server/server.controller.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .controller('ServerController', serverController);\n\n    serverController.$inject = [\n        '$state',\n        '$http',\n        '$ionicHistory',\n        '$translate',\n        '$ionicPopup',\n        'PathService',\n        'TatamiEndpoint'\n    ];\n    function serverController($state, $http, $ionicHistory, $translate, $ionicPopup, PathService, TatamiEndpoint) {\n        var vm = this;\n\n        vm.endpoint = TatamiEndpoint.getEndpoint().url || TatamiEndpoint.getDefault().url;\n        vm.success = true;\n        vm.previous = vm.endpoint;\n\n        vm.updateEndpoint = updateEndpoint;\n        vm.useDefaultEndpoint = useDefaultEndpoint;\n        vm.isLastAttempt = isLastAttempt;\n\n        function updateEndpoint() {\n            TatamiEndpoint.setEndpoint(vm.endpoint);\n            $http({\n                url: '/tatami/rest/client/id',\n                method: 'GET'\n            }).then(success, error);\n        }\n\n        function success(result) {\n            vm.success = true;\n            vm.previous = vm.endpoint;\n\n            var alertPopup = $ionicPopup.alert({\n                title: $translate.instant('server.endpoint.authenticate.title'),\n                template: '<span translate=\"server.endpoint.authenticate.body\"></span>'\n            });\n\n            alertPopup.then($state.go('login'));\n        }\n\n        function error(result) {\n            vm.success = false;\n            vm.previous = vm.endpoint;\n\n            $ionicPopup.alert({\n                title: $translate.instant('server.endpoint.error.title'),\n                template: '<span translate=\"server.endpoint.error.body\"></span>'\n            });\n\n            TatamiEndpoint.reset();\n        }\n\n        function isLastAttempt() {\n            return vm.previous === vm.endpoint;\n        }\n\n        function useDefaultEndpoint() {\n            vm.endpoint = TatamiEndpoint.getDefault().url;\n            updateEndpoint();\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/login/server/server.html",
    "content": "<ion-view view-title=\"\">\n    <ion-content ng-style=\"{'background-color':'#f5f5f5'}\">\n        <ion-list>\n            <ion-item class=\"item-divider item-button-right\" translate=\"server.endpoint.change\"></ion-item>\n            <ion-item class=\"item-input-inset\">\n                <label class=\"item-input-wrapper\">\n                    <input\n                        class=\"item-input-wrapper\"\n                        type=\"text\"\n                           autocapitalize=\"off\"\n                           autocorrect=\"off\"\n                           ng-model=\"vm.endpoint\"\n                           placeholder=\"{{ 'server.endpoint.title' | translate }}\">\n                </label>\n                <button class=\"button button-small\"\n                        ng-class=\"{ 'button-balanced': vm.isLastAttempt() && vm.success,\n                                    'button-assertive': vm.isLastAttempt() && !vm.success }\"\n                        ng-disabled=\"vm.isLastAttempt()\"\n                        ng-click=\"vm.updateEndpoint()\">\n                    <span ng-if=\"vm.isLastAttempt()\"\n                          ng-class=\"{ 'ion-checkmark-round': vm.success,\n                                      'ion-close-round': !vm.success }\"></span>\n                    <span ng-if=\"!vm.isLastAttempt()\">Submit</span>\n                </button>\n            </ion-item>\n            <ion-item ng-click=\"vm.useDefaultEndpoint()\"\n                      class=\"text-center\"\n                      translate=\"server.endpoint.default\"></ion-item>\n        </ion-list>\n    </ion-content>\n</ion-view>\n"
  },
  {
    "path": "mobile/www/app/components/login/server/server.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .config(config);\n\n    config.$inject = ['$stateProvider'];\n    function config($stateProvider) {\n        $stateProvider\n            .state('server', {\n                url: '/server',\n                parent: 'login',\n                views: {\n                    '@tatami': {\n                        templateUrl: 'app/components/login/server/server.html',\n                        controller: 'ServerController',\n                        controllerAs: 'vm'\n                    }\n                },\n                resolve: {\n                    translatePartialLoader: getTranslatePartialLoader\n                }\n            });\n\n        getTranslatePartialLoader.$inject = ['$translate', '$translatePartialLoader'];\n        function getTranslatePartialLoader($translate, $translatePartialLoader) {\n            $translatePartialLoader.addPart('server');\n            $translate.refresh();\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/post/post.controller.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .controller('PostCtrl', postCtrl);\n\n    postCtrl.$inject = [\n        'StatusService',\n        'PathService',\n        '$ionicHistory',\n        '$state',\n        '$cordovaCamera',\n        '$q',\n        '$ionicLoading',\n        '$ionicPopup',\n        'repliedToStatus',\n        '$scope',\n        '$cordovaGeolocation',\n        'ToastService'\n    ];\n    function postCtrl(StatusService, PathService, $ionicHistory, $state, $cordovaCamera, $q, $ionicLoading, $ionicPopup, repliedToStatus, $scope, $cordovaGeolocation, ToastService) {\n        var vm = this;\n        vm.charCount = 750;\n        vm.status = {\n            content: repliedToStatus ? '@' + repliedToStatus.username : '',\n            statusPrivate: repliedToStatus ? repliedToStatus.private : false,\n            replyTo: repliedToStatus ? repliedToStatus.statusId : '',\n            replyToUsername: repliedToStatus ? repliedToStatus.username : '',\n            attachmentIds: [],\n            geoLocalization: \"\"\n        };\n        vm.images = [];\n        vm.isPosting = false;\n        vm.remainingLength = vm.charCount;\n        vm.newLineCount = 0; //This field takes into consideration the '\\n' character that counts for 2 chars in the database.\n        vm.pasteFlag = false;\n        vm.shareLocation = false;\n\n        vm.post = post;\n        vm.reset = reset;\n        vm.close = close;\n        vm.getPicture = getPicture;\n        vm.getPictureFromLibrary = getPictureFromLibrary;\n        vm.remove = remove;\n        vm.paste = paste;\n        vm.updateLocation = updateLocation;\n        vm.updatePrivate = updatePrivate;\n\n        function post() {\n            upload().then(createPost);\n        }\n\n        function createPost(attachmentIds) {\n            vm.status.attachmentIds = attachmentIds;\n            StatusService.save(vm.status, function() {\n                reset();\n                $ionicHistory.clearCache();\n                $state.go('timeline');\n            });\n        }\n\n        function reset() {\n            vm.status = {\n                content: '',\n                statusPrivate: false,\n                attachmentIds: [],\n                geoLocalization: \"\"\n            };\n            vm.images = [];\n            vm.isPosting = false;\n            vm.shareLocation = false;\n        }\n\n        function close() {\n            $ionicHistory.goBack();\n            reset();\n        }\n\n        function getPicture() {\n            var options = {\n                quality: 10,\n                correctOrientation : true\n            };\n\n            $cordovaCamera.getPicture(options).then(store);\n        }\n\n        function getPictureFromLibrary() {\n            var options = {\n                quality: 10,\n                sourceType: Camera.PictureSourceType.PHOTOLIBRARY,\n                correctOrientation: true\n            };\n\n            $cordovaCamera.getPicture(options).then(store);\n        }\n\n        function store(fileUri) {\n            vm.images.push(fileUri);\n        }\n\n        function upload() {\n            var promises = [];\n            vm.isPosting = true;\n\n            var options = new FileUploadOptions();\n            var fileTransfer = new FileTransfer();\n            angular.forEach(vm.images, function(image) {\n                var deferred = $q.defer();\n                options.fileKey = 'uploadFile';\n                options.fileName = image.substr(image.lastIndexOf('/') + 1);\n\n                $ionicLoading.show({\n                    template: '<span translate=\"post.progress\">Post in progress...</span>',\n                    hideOnStateChange: true\n                });\n\n                fileTransfer.upload(image, '/tatami/rest/fileupload', onSuccess, onFail, options);\n                promises.push(deferred.promise);\n\n                function onSuccess(result) {\n                    var jsonResult = JSON.parse(result.response)[0];\n                    deferred.resolve(jsonResult.attachmentId);\n                }\n\n                function onFail(failure) {\n                    $ionicLoading.hide();\n\n                    var popupError = $ionicPopup.alert({\n                        title: 'Error',\n                        template: '<span translate=\"post.error.message\"></span>'\n                    });\n\n                    popupError.then(goToTimeline);\n\n                    function goToTimeline() {\n                        reset();\n                        $state.go('timeline');\n                    }\n\n                    deferred.resolve(failure);\n                }\n            });\n\n            return $q.all(promises);\n        }\n\n        function remove(index) {\n            vm.images.splice(index, 1);\n        }\n\n        function updateRemainingLength(statusContent) {\n            vm.remainingLength = vm.charCount - statusContent.length - vm.newLineCount;\n        }\n\n        function updateNewLineCount(statusContent) {\n            vm.newLineCount = (statusContent.match(/\\n/g) || []).length;\n        }\n\n        $scope.$watch('vm.status.content', function (newValue) {\n            if (newValue) {\n                updateNewLineCount(newValue);\n                updateRemainingLength(newValue);\n                if(vm.remainingLength < 0){\n                    if(vm.pasteFlag){\n                        $ionicLoading.show({\n                            template: '<span translate=\"post.error.truncated\"></span>',\n                            duration: 2500\n                        });\n                        vm.pasteFlag = false;\n                    }\n                    vm.status.content = newValue.slice(0, vm.charCount - vm.newLineCount);\n                    updateNewLineCount(vm.status.content);\n                    updateRemainingLength(vm.status.content);\n                }\n            } else {\n                vm.remainingLength = vm.charCount;\n                vm.newLineCount = 0;\n            }\n        });\n\n        function paste(){\n            vm.pasteFlag = true;\n        }\n\n        function updateLocation() {\n            vm.shareLocation = !vm.shareLocation;\n            if(vm.shareLocation){\n                var posOptions = {timeout: 5000, enableHighAccuracy: false};\n                $cordovaGeolocation\n                    .getCurrentPosition(posOptions)\n                    .then(function (position) {\n                        vm.status.geoLocalization = position.coords.latitude + \", \" + position.coords.longitude;\n                        ToastService.display('post.location.share');\n                    }, function() {\n                        vm.shareLocation = !vm.shareLocation;\n                        ToastService.display('post.location.fail');\n                    });\n            } else {\n                vm.status.geoLocalization = \"\";\n            }\n        }\n\n        function updatePrivate(){\n            vm.status.statusPrivate = !vm.status.statusPrivate;\n            vm.status.statusPrivate ? ToastService.display('post.private.yes') : ToastService.display('post.private.no');\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/post/post.html",
    "content": "<ion-view view-title=\"{{ 'post.title' | translate }}\" hide-back-button=\"true\">\n    <ion-nav-buttons side=\"secondary\">\n        <button class=\"button button-clear button-small icon ion-close-round\" style=\"opacity:0.4;\" ng-click=\"vm.close()\">\n        </button>\n    </ion-nav-buttons>\n    <ion-content class=\"has-subfooter\">\n        <form name=\"newPost\" novalidate=\"\">\n            <ion-item>\n                <ion-textarea>\n                        <textarea ng-model=\"vm.status.content\"\n                                  rows=\"15\"\n                                  placeholder=\"{{ 'post.message' | translate }}\"\n                                  ng-required=\"true\"\n                                  ng-trim=\"false\"\n                                  ng-paste=\"vm.paste()\"\n                                  style=\"width: 100%; height: 100%;\">\n                            </textarea>\n                </ion-textarea>\n            </ion-item>\n        </form>\n        <span ng-repeat=\"image in vm.images track by $index\">\n            <div class=\"list card\">\n                <div class=\"item item-image\">\n                    <img class=\"center\" ng-show=\"vm.images.length > 0\" ng-src=\"{{ image }}\">\n                    <i class=\"icon ion-close-round light\" ng-click=\"vm.remove($index)\"></i>\n                </div>\n            </div>\n        </span>\n    </ion-content>\n    <ion-footer-bar align-title=\"right\" tatami-post-bar-attach=\"true\" class=\"bar-subfooter\">\n        <div class=\"row\" style=\"width:50%;\">\n            <button class=\"col-33 button button-clear icon ion-camera\" ng-click=\"vm.getPicture()\"></button>\n            <button class=\"col-33 button button-clear icon ion-images\" ng-click=\"vm.getPictureFromLibrary()\"></button>\n            <button class=\"col-33 button button-clear icon ion-location\"\n                    ng-click=\"vm.updateLocation()\"\n                    ng-class=\"{ 'button-calm' : vm.shareLocation, 'button-stable' : !vm.shareLocation }\"></button>\n            <button class=\"col-33 button button-clear icon ion-locked\"\n                    ng-click=\"vm.updatePrivate()\"\n                    ng-class=\"{ 'button-calm' : vm.status.statusPrivate, 'button-stable' : !vm.status.statusPrivate }\"></button>\n        </div>\n\n        <h1 class=\"title\">{{vm.remainingLength}}</h1>\n        <button class=\"button button-positive\"\n                translate=\"post.title\"\n                ng-disabled=\"vm.status.content.length === 0 || !vm.status.content || vm.isPosting\"\n                ng-click=\"vm.post()\">\n            Post\n        </button>\n    </ion-footer-bar>\n</ion-view>\n"
  },
  {
    "path": "mobile/www/app/components/post/post.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .config(postConfig);\n\n    postConfig.$inject = ['$stateProvider'];\n    function postConfig($stateProvider) {\n        $stateProvider\n            .state('post', {\n                url: '/post/:statusId',\n                parent: 'tatami',\n                templateUrl: 'app/components/post/post.html',\n                controller: 'PostCtrl',\n                controllerAs: 'vm',\n\n                resolve: {\n                    repliedToStatus: getRepliedToStatus,\n                    translatePartialProvider: getTranslatePartialLoader\n                }\n            })\n    }\n\n    getRepliedToStatus.$inject = ['StatusService', '$stateParams'];\n    function getRepliedToStatus(StatusService, $stateParams) {\n        if($stateParams.statusId) {\n            return StatusService.get({ statusId: $stateParams.statusId }).$promise;\n        }\n    }\n\n    getTranslatePartialLoader.$inject = ['$translate', '$translatePartialLoader'];\n    function getTranslatePartialLoader($translate, $translatePartialLoader) {\n        $translatePartialLoader.addPart('post');\n        return $translate.refresh();\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/components/post/postbar.directive.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .directive('tatamiPostBarAttach', tatamiPostBar);\n\n    function tatamiPostBar() {\n        var directive = {\n            restrict: 'A',\n            link: link\n        };\n\n        return directive;\n    }\n\n    function link(scope, element, attrs) {\n        ionic.on('native.keyboardshow', onShow, window);\n        ionic.on('native.keyboardhide', onHide, window);\n\n        //deprecated\n        ionic.on('native.showkeyboard', onShow, window);\n        ionic.on('native.hidekeyboard', onHide, window);\n\n\n        var scrollCtrl;\n\n        function onShow(e) {\n            if (ionic.Platform.isAndroid() && !ionic.Platform.isFullScreen) {\n                return;\n            }\n\n\n            if(attrs['tatamiPostBarAttach'] === 'true') {\n                var subheaderOffset = 43;\n            }\n            //for testing\n            var keyboardHeight = e.keyboardHeight || e.detail.keyboardHeight;\n            element.css('bottom', (keyboardHeight + subheaderOffset) + \"px\");\n            scrollCtrl = element.controller('$ionicScroll');\n            if (scrollCtrl) {\n                scrollCtrl.scrollView.__container.style.bottom = subheaderOffset + keyboardHeight + keyboardAttachGetClientHeight(element[0]) + \"px\";\n            }\n        }\n\n        function onHide() {\n            if (ionic.Platform.isAndroid() && !ionic.Platform.isFullScreen) {\n                return;\n            }\n\n            element.css('bottom', '');\n            if (scrollCtrl) {\n                scrollCtrl.scrollView.__container.style.bottom = '';\n            }\n        }\n\n        scope.$on('$destroy', function() {\n            ionic.off('native.keyboardshow', onShow, window);\n            ionic.off('native.keyboardhide', onHide, window);\n\n            //deprecated\n            ionic.off('native.showkeyboard', onShow, window);\n            ionic.off('native.hidekeyboard', onHide, window);\n        });\n\n        function keyboardAttachGetClientHeight(element) {\n            return element.clientHeight;\n        }\n\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/config/marked.config.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .config(markedConfig);\n\n    markedConfig.$inject = ['markedProvider'];\n    function markedConfig(markedProvider) {\n        markedProvider.setOptions({\n            gfm: true,\n            pedantic: false,\n            sanitize: true,\n            highlight: null,\n            urls: {\n                youtube : function(text, url){\n                    var cap;\n                    if((cap = /(youtu\\.be\\/|youtube\\.com\\/(watch\\?(.*&)?v=|(embed|v)\\/))([^\\?&\"'>]+)/.exec(url))){\n                        return '<iframe width=\"420\" height=\"315\" src=\"https://www.youtube.com/embed/' +\n                            cap[5] +\n                            '\" frameborder=\"0\" allowfullscreen></iframe>';\n                    }\n                },\n                vimeo : function(text, url){\n                    var cap;\n                    if((cap = /^.*(vimeo\\.com\\/)((channels\\/[A-z]+\\/)|(groups\\/[A-z]+\\/videos\\/))?([0-9]+)/.exec(url))){\n                        return '<iframe src=\"https://player.vimeo.com/video/' +\n                            cap[5] +\n                            '\" width=\"500\" height=\"281\" frameborder=\"0\" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>';\n                    }\n                },\n                dailymotion : function(text, url){\n                    var cap;\n                    if((cap = /^.+dailymotion.com\\/(video|hub)\\/([^_]+)[^#]*(#video=([^_&]+))?/.exec(url))){\n                        return '<iframe frameborder=\"0\" width=\"480\" height=\"271\" src=\"https://www.dailymotion.com/embed/video/' +\n                            cap[2] +\n                            '\"></iframe>';\n                    }\n                },\n                gist : function(text, url){\n                    var cap;\n                    if((cap = /^.+gist.github.com\\/(([A-z0-9-]+)\\/)?([0-9A-z]+)/.exec(url))){\n                        $.ajax({\n                            url: cap[0] + '.json',\n                            dataType: 'jsonp',\n                            success: function(response){\n                                if(response.stylesheet && $('link[href=\"' + response.stylesheet + '\"]').length === 0){\n                                    var l = document.createElement(\"link\"),\n                                        head = document.getElementsByTagName(\"head\")[0];\n\n                                    l.type = \"text/css\";\n                                    l.rel = \"stylesheet\";\n                                    l.href = response.stylesheet;\n                                    head.insertBefore(l, head.firstChild);\n                                }\n                                var $elements = $('.gist' + cap[3]);\n                                $elements.html(response.div);\n                            }\n                        });\n                        return '<div class=\"gist' + cap[3] + '\"/>';\n                    }\n                }\n            }\n        });\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/config/marked.filter.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .filter('markdown', markdown);\n\n    markdown.$inject = ['$sce'];\n    function markdown($sce) {\n        return function(content) {\n            return content ? marked(content) : '';\n        };\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/config/tatami.marked.js",
    "content": "/**\n * marked - a markdown parser\n * Copyright (c) 2011-2013, Christopher Jeffrey. (MIT Licensed)\n * https://github.com/chjj/marked\n */\n\n;(function() {\n\n    /**\n     * Block-Level Grammar\n     */\n\n    var block = {\n        newline: /^\\n+/,\n        code: /^( {4}[^\\n]+\\n*)+/,\n        fences: noop,\n        hr: /^( *[-*_]){3,} *(?:\\n+|$)/,\n        heading: /^ *(#{1,6} ) *([^\\n]+?) *#* *(?:\\n+|$)/,\n        nptable: noop,\n        lheading: /^([^\\n]+)\\n *(=|-){3,} *\\n*/,\n        blockquote: /^( *>[^\\n]+(\\n[^\\n]+)*\\n*)+/,\n        list: /^( *)(bull) [\\s\\S]+?(?:hr|\\n{2,}(?! )(?!\\1bull )\\n*|\\s*$)/,\n        html: /^ *(?:comment|closed|closing) *(?:\\n{2,}|\\s*$)/,\n        def: /^ *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +[\"(]([^\\n]+)[\")])? *(?:\\n+|$)/,\n        table: noop,\n        paragraph: /^((?:[^\\n]+\\n?(?!hr|heading|lheading|blockquote|tag|def))+)\\n*/,\n        text: /^[^\\n]+/\n    };\n\n    block.bullet = /(?:[*+-]|\\d+\\.)/;\n    block.item = /^( *)(bull) [^\\n]*(?:\\n(?!\\1bull )[^\\n]*)*/;\n    block.item = replace(block.item, 'gm')\n    (/bull/g, block.bullet)\n    ();\n\n    block.list = replace(block.list)\n    (/bull/g, block.bullet)\n    ('hr', /\\n+(?=(?: *[-*_]){3,} *(?:\\n+|$))/)\n    ();\n\n    block._tag = '(?!(?:'\n        + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'\n        + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'\n        + '|span|br|wbr|ins|del|img)\\\\b)\\\\w+(?!:/|@)\\\\b';\n\n    block.html = replace(block.html)\n    ('comment', /<!--[\\s\\S]*?-->/)\n    ('closed', /<(tag)[\\s\\S]+?<\\/\\1>/)\n    ('closing', /<tag(?:\"[^\"]*\"|'[^']*'|[^'\">])*?>/)\n    (/tag/g, block._tag)\n    ();\n\n    block.paragraph = replace(block.paragraph)\n    ('hr', block.hr)\n    ('heading', block.heading)\n    ('lheading', block.lheading)\n    ('blockquote', block.blockquote)\n    ('tag', '<' + block._tag)\n    ('def', block.def)\n    ();\n\n    /**\n     * Normal Block Grammar\n     */\n\n    block.normal = merge({}, block);\n\n    /**\n     * GFM Block Grammar\n     */\n\n    block.gfm = merge({}, block.normal, {\n        fences: /^ *(`{3,}|~{3,}) *(\\w+)? *\\n([\\s\\S]+?)\\s*\\1 *(?:\\n+|$)/,\n        paragraph: /^/\n    });\n\n    block.gfm.paragraph = replace(block.paragraph)\n    ('(?!', '(?!' + block.gfm.fences.source.replace('\\\\1', '\\\\2') + '|')\n    ();\n\n    /**\n     * GFM + Tables Block Grammar\n     */\n\n    block.tables = merge({}, block.gfm, {\n        nptable: /^ *(\\S.*\\|.*)\\n *([-:]+ *\\|[-| :]*)\\n((?:.*\\|.*(?:\\n|$))*)\\n*/,\n        table: /^ *\\|(.+)\\n *\\|( *[-:]+[-| :]*)\\n((?: *\\|.*(?:\\n|$))*)\\n*/\n    });\n\n    /**\n     * Block Lexer\n     */\n\n    function Lexer(options) {\n        this.tokens = [];\n        this.tokens.links = {};\n        this.options = options || marked.defaults;\n        this.rules = block.normal;\n\n        if (this.options.gfm) {\n            if (this.options.tables) {\n                this.rules = block.tables;\n            } else {\n                this.rules = block.gfm;\n            }\n        }\n    }\n\n    /**\n     * Expose Block Rules\n     */\n\n    Lexer.rules = block;\n\n    /**\n     * Static Lex Method\n     */\n\n    Lexer.lex = function(src, options) {\n        var lexer = new Lexer(options);\n        return lexer.lex(src);\n    };\n\n    /**\n     * Preprocessing\n     */\n\n    Lexer.prototype.lex = function(src) {\n        src = src\n            .replace(/\\r\\n|\\r/g, '\\n')\n            .replace(/\\t/g, '    ')\n            .replace(/\\u00a0/g, ' ')\n            .replace(/\\u2424/g, '\\n');\n\n        return this.token(src, true);\n    };\n\n    /**\n     * Lexing\n     */\n\n    Lexer.prototype.token = function(src, top) {\n        var src = src.replace(/^ +$/gm, '')\n            , next\n            , loose\n            , cap\n            , bull\n            , b\n            , item\n            , space\n            , i\n            , l;\n\n        while (src) {\n            // newline\n            if (cap = this.rules.newline.exec(src)) {\n                src = src.substring(cap[0].length);\n                if (cap[0].length > 1) {\n                    this.tokens.push({\n                        type: 'space'\n                    });\n                }\n            }\n\n            // code\n            if (cap = this.rules.code.exec(src)) {\n                src = src.substring(cap[0].length);\n                cap = cap[0].replace(/^ {4}/gm, '');\n                this.tokens.push({\n                    type: 'code',\n                    text: !this.options.pedantic\n                        ? cap.replace(/\\n+$/, '')\n                        : cap\n                });\n                continue;\n            }\n\n            // fences (gfm)\n            if (cap = this.rules.fences.exec(src)) {\n                src = src.substring(cap[0].length);\n                this.tokens.push({\n                    type: 'code',\n                    lang: cap[2],\n                    text: cap[3]\n                });\n                continue;\n            }\n\n            // heading\n            if (cap = this.rules.heading.exec(src)) {\n                src = src.substring(cap[0].length);\n                this.tokens.push({\n                    type: 'heading',\n                    depth: cap[1].length,\n                    text: cap[2]\n                });\n                continue;\n            }\n\n            // table no leading pipe (gfm)\n            if (top && (cap = this.rules.nptable.exec(src))) {\n                src = src.substring(cap[0].length);\n\n                item = {\n                    type: 'table',\n                    header: cap[1].replace(/^ *| *\\| *$/g, '').split(/ *\\| */),\n                    align: cap[2].replace(/^ *|\\| *$/g, '').split(/ *\\| */),\n                    cells: cap[3].replace(/\\n$/, '').split('\\n')\n                };\n\n                for (i = 0; i < item.align.length; i++) {\n                    if (/^ *-+: *$/.test(item.align[i])) {\n                        item.align[i] = 'right';\n                    } else if (/^ *:-+: *$/.test(item.align[i])) {\n                        item.align[i] = 'center';\n                    } else if (/^ *:-+ *$/.test(item.align[i])) {\n                        item.align[i] = 'left';\n                    } else {\n                        item.align[i] = null;\n                    }\n                }\n\n                for (i = 0; i < item.cells.length; i++) {\n                    item.cells[i] = item.cells[i].split(/ *\\| */);\n                }\n\n                this.tokens.push(item);\n\n                continue;\n            }\n\n            // lheading\n            if (cap = this.rules.lheading.exec(src)) {\n                src = src.substring(cap[0].length);\n                this.tokens.push({\n                    type: 'heading',\n                    depth: cap[2] === '=' ? 1 : 2,\n                    text: cap[1]\n                });\n                continue;\n            }\n\n            // hr\n            if (cap = this.rules.hr.exec(src)) {\n                src = src.substring(cap[0].length);\n                this.tokens.push({\n                    type: 'hr'\n                });\n                continue;\n            }\n\n            // blockquote\n            if (cap = this.rules.blockquote.exec(src)) {\n                src = src.substring(cap[0].length);\n\n                this.tokens.push({\n                    type: 'blockquote_start'\n                });\n\n                cap = cap[0].replace(/^ *> ?/gm, '');\n\n                // Pass `top` to keep the current\n                // \"toplevel\" state. This is exactly\n                // how markdown.pl works.\n                this.token(cap, top);\n\n                this.tokens.push({\n                    type: 'blockquote_end'\n                });\n\n                continue;\n            }\n\n            // list\n            if (cap = this.rules.list.exec(src)) {\n                src = src.substring(cap[0].length);\n\n                this.tokens.push({\n                    type: 'list_start',\n                    ordered: isFinite(cap[2])\n                });\n\n                // Get each top-level item.\n                cap = cap[0].match(this.rules.item);\n\n                // Get bullet.\n                if (this.options.smartLists) {\n                    bull = block.bullet.exec(cap[0])[0];\n                }\n\n                next = false;\n                l = cap.length;\n                i = 0;\n\n                for (; i < l; i++) {\n                    item = cap[i];\n\n                    // Remove the list item's bullet\n                    // so it is seen as the next token.\n                    space = item.length;\n                    item = item.replace(/^ *([*+-]|\\d+\\.) +/, '');\n\n                    // Outdent whatever the\n                    // list item contains. Hacky.\n                    if (~item.indexOf('\\n ')) {\n                        space -= item.length;\n                        item = !this.options.pedantic\n                            ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')\n                            : item.replace(/^ {1,4}/gm, '');\n                    }\n\n                    // Determine whether the next list item belongs here.\n                    // Backpedal if it does not belong in this list.\n                    if (this.options.smartLists && i !== l - 1) {\n                        b = block.bullet.exec(cap[i+1])[0];\n                        if (bull !== b && !(bull[1] === '.' && b[1] === '.')) {\n                            src = cap.slice(i + 1).join('\\n') + src;\n                            i = l - 1;\n                        }\n                    }\n\n                    // Determine whether item is loose or not.\n                    // Use: /(^|\\n)(?! )[^\\n]+\\n\\n(?!\\s*$)/\n                    // for discount behavior.\n                    loose = next || /\\n\\n(?!\\s*$)/.test(item);\n                    if (i !== l - 1) {\n                        next = item[item.length-1] === '\\n';\n                        if (!loose) loose = next;\n                    }\n\n                    this.tokens.push({\n                        type: loose\n                            ? 'loose_item_start'\n                            : 'list_item_start'\n                    });\n\n                    // Recurse.\n                    this.token(item, false);\n\n                    this.tokens.push({\n                        type: 'list_item_end'\n                    });\n                }\n\n                this.tokens.push({\n                    type: 'list_end'\n                });\n\n                continue;\n            }\n\n            // html\n            if (cap = this.rules.html.exec(src)) {\n                src = src.substring(cap[0].length);\n                this.tokens.push({\n                    type: this.options.sanitize\n                        ? 'paragraph'\n                        : 'html',\n                    pre: cap[1] === 'pre',\n                    text: cap[0]\n                });\n                continue;\n            }\n\n            // def\n            if (top && (cap = this.rules.def.exec(src))) {\n                src = src.substring(cap[0].length);\n                this.tokens.links[cap[1].toLowerCase()] = {\n                    href: cap[2],\n                    title: cap[3]\n                };\n                continue;\n            }\n\n            // table (gfm)\n            if (top && (cap = this.rules.table.exec(src))) {\n                src = src.substring(cap[0].length);\n\n                item = {\n                    type: 'table',\n                    header: cap[1].replace(/^ *| *\\| *$/g, '').split(/ *\\| */),\n                    align: cap[2].replace(/^ *|\\| *$/g, '').split(/ *\\| */),\n                    cells: cap[3].replace(/(?: *\\| *)?\\n$/, '').split('\\n')\n                };\n\n                for (i = 0; i < item.align.length; i++) {\n                    if (/^ *-+: *$/.test(item.align[i])) {\n                        item.align[i] = 'right';\n                    } else if (/^ *:-+: *$/.test(item.align[i])) {\n                        item.align[i] = 'center';\n                    } else if (/^ *:-+ *$/.test(item.align[i])) {\n                        item.align[i] = 'left';\n                    } else {\n                        item.align[i] = null;\n                    }\n                }\n\n                for (i = 0; i < item.cells.length; i++) {\n                    item.cells[i] = item.cells[i]\n                        .replace(/^ *\\| *| *\\| *$/g, '')\n                        .split(/ *\\| */);\n                }\n\n                this.tokens.push(item);\n\n                continue;\n            }\n\n            // top-level paragraph\n            if (top && (cap = this.rules.paragraph.exec(src))) {\n                src = src.substring(cap[0].length);\n                this.tokens.push({\n                    type: 'paragraph',\n                    text: cap[1][cap[1].length-1] === '\\n'\n                        ? cap[1].slice(0, -1)\n                        : cap[1]\n                });\n                continue;\n            }\n\n            // text\n            if (cap = this.rules.text.exec(src)) {\n                // Top-level should never reach here.\n                src = src.substring(cap[0].length);\n                this.tokens.push({\n                    type: 'text',\n                    text: cap[0]\n                });\n                continue;\n            }\n\n            if (src) {\n                throw new\n                    Error('Infinite loop on byte: ' + src.charCodeAt(0));\n            }\n        }\n\n        return this.tokens;\n    };\n\n    /**\n     * Inline-Level Grammar\n     */\n\n    var inline = {\n        escape: /^\\\\([\\\\`*{}\\[\\]()#+\\-.!_>])/,\n        autolink: /^<([^ >]+(@|:\\/)[^ >]+)>/,\n        url: noop,\n        tag: /^<!--[\\s\\S]*?-->|^<\\/?\\w+(?:\"[^\"]*\"|'[^']*'|[^'\">])*?>/,\n        link: /^!?\\[(inside)\\]\\(href\\)/,\n        reflink: /^!?\\[(inside)\\]\\s*\\[([^\\]]*)\\]/,\n        nolink: /^!?\\[((?:\\[[^\\]]*\\]|[^\\[\\]])*)\\]/,\n        strong: /^__([\\s\\S]+?)__(?!_)|^\\*\\*([\\s\\S]+?)\\*\\*(?!\\*)/,\n        em: /^\\b_((?:__|[\\s\\S])+?)_\\b|^\\*((?:\\*\\*|[\\s\\S])+?)\\*(?!\\*)/,\n        code: /^(`+)\\s*([\\s\\S]*?[^`])\\s*\\1(?!`)/,\n        br: /^ {2,}\\n(?!\\s*$)/,\n        mail: /^([^\\s !\"#$%'()*+,.\\/:;<=>?@\\\\\\[\\]\\^_`{|}~-]+(@|:\\/)[^\\s !\"#$%'()*+,.\\/:;<=>?@\\\\\\[\\]\\^_`{|}~-]+.[^\\s !\"#$%'()*+,.\\/:;<=>?@\\\\\\[\\]\\^_`{|}~-]+)/,\n        mention: /^@([A-Za-z0-9!#$%&'*+\\/=?\\^_`{|}~\\-]+(?:\\.[A-Za-z0-9!#$%&'*+\\/=?\\^_`{|}~\\-]+)*(?!\\*))/,\n        tags:   /^#([^\\s!\"#$%'()*+,.\\/:;<=>?@\\\\\\[\\]\\^_`{|}~-]+(?:\\.[\\^!\"#$%'()*+,.\\/:;<=>?@\\\\\\[\\]\\^_`{|}~-]+)*)(?!\\*)/,\n        del: noop,\n        text: /^[\\s\\S]+?(?=[\\\\<!\\[_*`]| {2,}\\n|$)/\n    };\n\n    inline._inside = /(?:\\[[^\\]]*\\]|[^\\]]|\\](?=[^\\[]*\\]))*/;\n    inline._href = /\\s*<?([^\\s]*?)>?(?:\\s+['\"]([\\s\\S]*?)['\"])?\\s*/;\n\n    inline.link = replace(inline.link)\n    ('inside', inline._inside)\n    ('href', inline._href)\n    ();\n\n    inline.reflink = replace(inline.reflink)\n    ('inside', inline._inside)\n    ();\n\n    /**\n     * Normal Inline Grammar\n     */\n\n    inline.normal = merge({}, inline);\n\n    /**\n     * Pedantic Inline Grammar\n     */\n\n    inline.pedantic = merge({}, inline.normal, {\n        strong: /^__(?=\\S)([\\s\\S]*?\\S)__(?!_)|^\\*\\*(?=\\S)([\\s\\S]*?\\S)\\*\\*(?!\\*)/,\n        em: /^_(?=\\S)([\\s\\S]*?\\S)_(?!_)|^\\*(?=\\S)([\\s\\S]*?\\S)\\*(?!\\*)/\n    });\n\n    /**\n     * GFM Inline Grammar\n     */\n\n    inline.gfm = merge({}, inline.normal, {\n        escape: replace(inline.escape)('])', '~|])')(),\n        url: /^(https?:\\/\\/[^\\s<]+[^<.,:;\"')\\]\\s])/,\n        del: /^~~(?=\\S)([\\s\\S]*?\\S)~~/,\n        text: replace(inline.text)\n        (']|', '#@~]|')\n        ('|', '|https?://|')\n        ('|', '||')\n        ()\n    });\n\n    /**\n     * GFM + Line Breaks Inline Grammar\n     */\n\n    inline.breaks = merge({}, inline.gfm, {\n        br: replace(inline.br)('{2,}', '*')(),\n        text: replace(inline.gfm.text)('{2,}', '*')()\n    });\n\n    /**\n     * Inline Lexer & Compiler\n     */\n\n    function InlineLexer(links, options) {\n        this.options = options || marked.defaults;\n        this.links = links;\n        this.rules = inline.normal;\n\n        if (!this.links) {\n            throw new\n                Error('Tokens array requires a `links` property.');\n        }\n\n        if (this.options.gfm) {\n            if (this.options.breaks) {\n                this.rules = inline.breaks;\n            } else {\n                this.rules = inline.gfm;\n            }\n        } else if (this.options.pedantic) {\n            this.rules = inline.pedantic;\n        }\n    }\n\n    /**\n     * Expose Inline Rules\n     */\n\n    InlineLexer.rules = inline;\n\n    /**\n     * Static Lexing/Compiling Method\n     */\n\n    InlineLexer.output = function(src, links, options) {\n        var inline = new InlineLexer(links, options);\n        return inline.output(src);\n    };\n\n    /**\n     * Lexing/Compiling\n     */\n\n    InlineLexer.prototype.output = function(src) {\n        var out = ''\n            , link\n            , text\n            , href\n            , cap;\n\n        while (src) {\n            // escape\n            if (cap = this.rules.escape.exec(src)) {\n                src = src.substring(cap[0].length);\n                out += cap[1];\n                continue;\n            }\n\n            // autolink\n            if (cap = this.rules.autolink.exec(src)) {\n                src = src.substring(cap[0].length);\n                if (cap[2] === '@') {\n                    text = cap[1][6] === ':'\n                        ? this.mangle(cap[1].substring(7))\n                        : this.mangle(cap[1]);\n                    href = this.mangle('mailto:') + text;\n                } else {\n                    href = escape(cap[1]);\n                    text = shortenUrl(href);\n                }\n                out += '<a href=\"'\n                    + href\n                    + '\" target=\"_blank\">'\n                    + text\n                    + '</a>';\n                continue;\n            }\n\n            // autolink\n            if (cap = this.rules.mail.exec(src)) {\n                src = src.substring(cap[0].length);\n                if (cap[2] === '@') {\n                    text = cap[1][6] === ':'\n                        ? this.mangle(cap[1].substring(7))\n                        : this.mangle(cap[1]);\n                    href = this.mangle('mailto:') + text;\n                } else {\n                    href = escape(cap[1]);\n                    text = shortenUrl(href);\n                }\n                out += '<a href=\"'\n                    + href\n                    + '\" target=\"_blank\">'\n                    + text\n                    + '</a>';\n                continue;\n            }\n\n            // url (gfm)\n            if (cap = this.rules.url.exec(src)) {\n                var html;\n                src = src.substring(cap[0].length);\n                href = escape(cap[1]);\n                text = shortenUrl(href);\n                for(var key in this.options.urls){\n                    html = this.options.urls[key](text, href);\n                    if(html){\n                        out += html;\n                        break;\n                    }\n                }\n                if(!html)\n                    out += '<a target=\"_blank\" href=\"'\n                        + href\n                        + '\" target=\"_blank\">'\n                        + text\n                        + '</a>';\n                continue;\n            }\n\n            // tag\n            if (cap = this.rules.tag.exec(src)) {\n                src = src.substring(cap[0].length);\n                out += this.options.sanitize\n                    ? escape(cap[0])\n                    : cap[0];\n                continue;\n            }\n\n            // link\n            if (cap = this.rules.link.exec(src)) {\n                src = src.substring(cap[0].length);\n                out += this.outputLink(cap, {\n                    href: cap[2],\n                    title: cap[3]\n                });\n                continue;\n            }\n\n            // reflink, nolink\n            if ((cap = this.rules.reflink.exec(src))\n                || (cap = this.rules.nolink.exec(src))) {\n                src = src.substring(cap[0].length);\n                link = (cap[2] || cap[1]).replace(/\\s+/g, ' ');\n                link = this.links[link.toLowerCase()];\n                if (!link || !link.href) {\n                    out += cap[0][0];\n                    src = cap[0].substring(1) + src;\n                    continue;\n                }\n                out += this.outputLink(cap, link);\n                continue;\n            }\n\n            // strong\n            if (cap = this.rules.strong.exec(src)) {\n                src = src.substring(cap[0].length);\n                out += '<strong>'\n                    + this.output(cap[2] || cap[1])\n                    + '</strong>';\n                continue;\n            }\n\n            // em\n            if (cap = this.rules.em.exec(src)) {\n                src = src.substring(cap[0].length);\n                out += '<em>'\n                    + this.output(cap[2] || cap[1])\n                    + '</em>';\n                continue;\n            }\n\n            // code\n            if (cap = this.rules.code.exec(src)) {\n                src = src.substring(cap[0].length);\n                out += '<code>'\n                    + escape(cap[2], true)\n                    + '</code>';\n                continue;\n            }\n\n            // mention\n            if (cap = inline.mention.exec(src)) {\n                src = src.substring(cap[0].length);\n                out += '<span class=\"link-span\" ng-click=\"vm.goToProfile(\\'' + cap[1] + '\\')\">'\n                    + cap[0]\n                    + '</span>';\n                continue;\n            }\n\n            // tags\n            if (cap = inline.tags.exec(src)) {\n                src = src.substring(cap[0].length);\n                out += '<span class=\"link-span\"' + ' ng-click=\"vm.goToTagTimeline(\\'' + cap[1] + '\\')\">' + cap[0] + '</span>';\n                continue;\n            }\n\n            // br\n            if (cap = this.rules.br.exec(src)) {\n                src = src.substring(cap[0].length);\n                out += '<br>';\n                continue;\n            }\n\n            // del (gfm)\n            if (cap = this.rules.del.exec(src)) {\n                src = src.substring(cap[0].length);\n                out += '<del>'\n                    + this.output(cap[1])\n                    + '</del>';\n                continue;\n            }\n\n            // text\n            if (cap = this.rules.text.exec(src)) {\n                src = src.substring(cap[0].length);\n                out += escape(cap[0]);\n                continue;\n            }\n\n            if (src) {\n                throw new\n                    Error('Infinite loop on byte: ' + src.charCodeAt(0));\n            }\n        }\n\n        return out;\n    };\n\n    /**\n     * Compile Link\n     */\n\n    InlineLexer.prototype.outputLink = function(cap, link) {\n        if (cap[0][0] !== '!') {\n            return '<a target=\"_blank\" href=\"'\n                + escape(link.href)\n                + '\"'\n                + (link.title\n                    ? ' title=\"'\n                + escape(link.title)\n                + '\"'\n                    : '')\n                + '>'\n                + this.output(cap[1])\n                + '</a>';\n        } else {\n            return '<img src=\"'\n                + escape(link.href)\n                + '\" alt=\"'\n                + escape(cap[1])\n                + '\"'\n                + (link.title\n                    ? ' title=\"'\n                + escape(link.title)\n                + '\"'\n                    : '')\n                + '>';\n        }\n    };\n\n    /**\n     * Mangle Links\n     */\n\n    InlineLexer.prototype.mangle = function(text) {\n        var out = ''\n            , l = text.length\n            , i = 0\n            , ch;\n\n        for (; i < l; i++) {\n            ch = text.charCodeAt(i);\n            if (Math.random() > 0.5) {\n                ch = 'x' + ch.toString(16);\n            }\n            out += '&#' + ch + ';';\n        }\n\n        return out;\n    };\n\n    /**\n     * Parsing & Compiling\n     */\n\n    function Parser(options) {\n        this.tokens = [];\n        this.token = null;\n        this.options = options || marked.defaults;\n    }\n\n    /**\n     * Static Parse Method\n     */\n\n    Parser.parse = function(src, options) {\n        var parser = new Parser(options);\n        return parser.parse(src);\n    };\n\n    /**\n     * Parse Loop\n     */\n\n    Parser.prototype.parse = function(src) {\n        this.inline = new InlineLexer(src.links, this.options);\n        this.tokens = src.reverse();\n\n        var out = '';\n        while (this.next()) {\n            out += this.tok();\n        }\n\n        return out;\n    };\n\n    /**\n     * Next Token\n     */\n\n    Parser.prototype.next = function() {\n        return this.token = this.tokens.pop();\n    };\n\n    /**\n     * Preview Next Token\n     */\n\n    Parser.prototype.peek = function() {\n        return this.tokens[this.tokens.length-1] || 0;\n    };\n\n    /**\n     * Parse Text Tokens\n     */\n\n    Parser.prototype.parseText = function() {\n        var body = this.token.text;\n\n        while (this.peek().type === 'text') {\n            body += '\\n' + this.next().text;\n        }\n\n        return this.inline.output(body);\n    };\n\n    /**\n     * Parse Current Token\n     */\n\n    Parser.prototype.tok = function() {\n        switch (this.token.type) {\n            case 'space': {\n                return '';\n            }\n            case 'hr': {\n                return '<hr>\\n';\n            }\n            case 'heading': {\n                return '<h'\n                    + this.token.depth\n                    + '>'\n                    + this.inline.output(this.token.text)\n                    + '</h'\n                    + this.token.depth\n                    + '>\\n';\n            }\n            case 'code': {\n                if (this.options.highlight) {\n                    var code = this.options.highlight(this.token.text, this.token.lang);\n                    if (code != null && code !== this.token.text) {\n                        this.token.escaped = true;\n                        this.token.text = code;\n                    }\n                }\n\n                if (!this.token.escaped) {\n                    this.token.text = escape(this.token.text, true);\n                }\n\n                return '<pre><code'\n                    + (this.token.lang\n                        ? ' class=\"'\n                    + this.options.langPrefix\n                    + this.token.lang\n                    + '\"'\n                        : '')\n                    + '>'\n                    + this.token.text\n                    + '</code></pre>\\n';\n            }\n            case 'table': {\n                var body = ''\n                    , heading\n                    , i\n                    , row\n                    , cell\n                    , j;\n\n                // header\n                body += '<thead>\\n<tr>\\n';\n                for (i = 0; i < this.token.header.length; i++) {\n                    heading = this.inline.output(this.token.header[i]);\n                    body += this.token.align[i]\n                        ? '<th align=\"' + this.token.align[i] + '\">' + heading + '</th>\\n'\n                        : '<th>' + heading + '</th>\\n';\n                }\n                body += '</tr>\\n</thead>\\n';\n\n                // body\n                body += '<tbody>\\n'\n                for (i = 0; i < this.token.cells.length; i++) {\n                    row = this.token.cells[i];\n                    body += '<tr>\\n';\n                    for (j = 0; j < row.length; j++) {\n                        cell = this.inline.output(row[j]);\n                        body += this.token.align[j]\n                            ? '<td align=\"' + this.token.align[j] + '\">' + cell + '</td>\\n'\n                            : '<td>' + cell + '</td>\\n';\n                    }\n                    body += '</tr>\\n';\n                }\n                body += '</tbody>\\n';\n\n                return '<table>\\n'\n                    + body\n                    + '</table>\\n';\n            }\n            case 'blockquote_start': {\n                var body = '';\n\n                while (this.next().type !== 'blockquote_end') {\n                    body += this.tok();\n                }\n\n                return '<blockquote>\\n'\n                    + body\n                    + '</blockquote>\\n';\n            }\n            case 'list_start': {\n                var type = this.token.ordered ? 'ol' : 'ul'\n                    , body = '';\n\n                while (this.next().type !== 'list_end') {\n                    body += this.tok();\n                }\n\n                return '<'\n                    + type\n                    + '>\\n'\n                    + body\n                    + '</'\n                    + type\n                    + '>\\n';\n            }\n            case 'list_item_start': {\n                var body = '';\n\n                while (this.next().type !== 'list_item_end') {\n                    body += this.token.type === 'text'\n                        ? this.parseText()\n                        : this.tok();\n                }\n\n                return '<li>'\n                    + body\n                    + '</li>\\n';\n            }\n            case 'loose_item_start': {\n                var body = '';\n\n                while (this.next().type !== 'list_item_end') {\n                    body += this.tok();\n                }\n\n                return '<li>'\n                    + body\n                    + '</li>\\n';\n            }\n            case 'html': {\n                return !this.token.pre && !this.options.pedantic\n                    ? this.inline.output(this.token.text)\n                    : this.token.text;\n            }\n            case 'paragraph': {\n                return '<p>'\n                    + this.inline.output(this.token.text)\n                    + '</p>\\n';\n            }\n            case 'text': {\n                return '<p>'\n                    + this.parseText()\n                    + '</p>\\n';\n            }\n        }\n    };\n\n    /**\n     * Helpers\n     */\n\n    function escape(html, encode) {\n        return html\n            .replace(!encode ? /&(?!#?\\w+;)/g : /&/g, '&amp;')\n            .replace(/</g, '&lt;')\n            .replace(/>/g, '&gt;')\n            .replace(/\"/g, '&quot;')\n            .replace(/'/g, '&#39;');\n    }\n\n    function shortenUrl(url) {\n        if (url.length < 67) {\n            return url;\n        } else {\n            return url.substring(0, 64) + \"...\";\n        }\n    }\n\n    function replace(regex, opt) {\n        regex = regex.source;\n        opt = opt || '';\n        return function self(name, val) {\n            if (!name) return new RegExp(regex, opt);\n            val = val.source || val;\n            val = val.replace(/(^|[^\\[])\\^/g, '$1');\n            regex = regex.replace(name, val);\n            return self;\n        };\n    }\n\n    function noop() {}\n    noop.exec = noop;\n\n    function merge(obj) {\n        var i = 1\n            , target\n            , key;\n\n        for (; i < arguments.length; i++) {\n            target = arguments[i];\n            for (key in target) {\n                if (Object.prototype.hasOwnProperty.call(target, key)) {\n                    obj[key] = target[key];\n                }\n            }\n        }\n\n        return obj;\n    }\n\n    /**\n     * Marked\n     */\n\n    function marked(src, opt) {\n        try {\n            if (opt) opt = merge({}, marked.defaults, opt);\n            return Parser.parse(Lexer.lex(src, opt), opt);\n        } catch (e) {\n            e.message += '\\nPlease report this to https://github.com/chjj/marked.';\n            if ((opt || marked.defaults).silent) {\n                return '<p>An error occured:</p><pre>'\n                    + escape(e.message + '', true)\n                    + '</pre>';\n            }\n            throw e;\n        }\n    }\n\n    /**\n     * Options\n     */\n\n    marked.options =\n        marked.setOptions = function(opt) {\n            merge(marked.defaults, opt);\n            return marked;\n        };\n\n    marked.defaults = {\n        gfm: true,\n        tables: true,\n        breaks: false,\n        pedantic: false,\n        sanitize: false,\n        // urls : [function(text, url){ return 'html'; }]\n        smartLists: false,\n        silent: false,\n        highlight: null,\n        langPrefix: 'lang-'\n    };\n\n    /**\n     * Expose\n     */\n\n    marked.Parser = Parser;\n    marked.parser = Parser.parse;\n\n    marked.Lexer = Lexer;\n    marked.lexer = Lexer.lex;\n\n    marked.InlineLexer = InlineLexer;\n    marked.inlineLexer = InlineLexer.output;\n\n    marked.parse = marked;\n\n    if (typeof exports === 'object') {\n        module.exports = marked;\n    } else if (typeof define === 'function' && define.amd) {\n        define(function() { return marked; });\n    } else {\n        this.marked = marked;\n    }\n\n}).call(function() {\n    return this || (typeof window !== 'undefined' ? window : global);\n}());\n"
  },
  {
    "path": "mobile/www/app/shared/interceptor/auth.interceptor.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .factory('authInterceptor', authInterceptor)\n        .factory('authExpiredInterceptor', authExpiredInterceptor)\n        .factory('endpointInterceptor', endpointInterceptor);\n\n    authInterceptor.$inject = ['$rootScope', '$q', '$location', '$localStorage'];\n    function authInterceptor($rootScope, $q, $location, $localStorage) {\n        var interceptor = {\n            request: request\n        };\n\n        return interceptor;\n\n        request.$inject = ['config'];\n        function request(config) {\n            config.headers = config.headers || {};\n            var token = $localStorage.get('token');\n\n            if (token && token.expires && token.expires > new Date().getTime()) {\n                config.headers['x-auth-token'] = token.token;\n            }\n\n            return config;\n        }\n    }\n\n    authExpiredInterceptor.$inject = ['$q', '$localStorage', '$injector'];\n    function authExpiredInterceptor($q, $localStorage, $injector) {\n        var interceptor = {\n            responseError: responseError\n        };\n\n        return interceptor;\n\n        responseError.$inject = ['response'];\n        function responseError(response) {\n            if(response.status === 401 && (response.data.error == 'invalid_token' || response.data.error == 'Unauthorized')) {\n                $localStorage.signOut();\n                var $state = $injector.get('$state');\n                $state.go('login');\n            }\n\n            return $q.reject(response);\n        }\n    }\n\n    /* endpointInterceptor built to replace PathService.buildPath(resource)\n     *\n     * Old implementation was causing issues - for some reason, REST path requests randomly started getting cached\n     * so an attempt to access /rest/authentication wouldn't reach buildPath but would return the endpoint used initially\n     * This interceptor never caches, so it's a better implementation.\n     * \n     * NOTE: Only make requests to server beginning with \"/\"; only access documents locally using the first folder and\n     * NOT \"/\"; static url requests (i.e. to google.com) should begin with http://, NEVER \"/\".\n     *\n     * ONLY USE \"/\" AS FIRST CHARACTER OF REQUESTS IF YOU NEED THE ENDPOINT URL TO BE A PREFIX\n     */\n    endpointInterceptor.$inject = ['$localStorage'];\n    function endpointInterceptor($localStorage) {\n        var interceptor = {\n            request: request\n        };\n\n        return interceptor;\n\n        request.$inject = ['config'];\n        function request(config) {\n            if(config.url.indexOf(\"/\") == 0) {\n                config.url = $localStorage.get('endpoint').url + config.url;\n            }\n\n            return config;\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/providers/provider.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami.providers', []);\n\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/providers/tatami.state.provider.js",
    "content": "(function() {\n    'use strict';\n\n    // This will dynamically create any tab substates inside the current tab. If in the timeline tab, we will\n    // create a timeline.status state\n    angular.module('tatami.providers')\n        .provider('TatamiState', tatamiState);\n\n    tatamiState.$inject = ['$stateProvider'];\n    function tatamiState($stateProvider) {\n        this.$get = tatamiStateHelper;\n\n        function tatamiStateHelper() {\n\n            var profileViewConfig = {\n                templateUrl: 'app/shared/state/profile/profile.html',\n                controller: 'ProfileCtrl',\n                controllerAs: 'vm'\n            };\n\n            var profileViews = [];\n            profileViews['suggested@follow'] = { 'suggested@follow': profileViewConfig };\n            profileViews['following@follow'] = { 'following@follow': profileViewConfig };\n            profileViews['follower@follow'] = { 'follower@follow': profileViewConfig };\n            profileViews['timeline@home'] = { 'timeline@home': profileViewConfig };\n            profileViews['mentions@home'] = { 'mentions@home': profileViewConfig };\n            profileViews['favorites@home'] = { 'favorites@home': profileViewConfig };\n            profileViews['more@home'] = { 'more@home': profileViewConfig };\n            profileViews['company@home'] = { 'more@home': profileViewConfig };\n            profileViews['blockedusers@home'] = { 'more@home': profileViewConfig };\n            profileViews['allusers@home'] = { 'more@home': profileViewConfig };\n\n            var conversationViewConfig = {\n                templateUrl: 'app/shared/state/conversation/conversation.html',\n                controller: 'ConversationCtrl',\n                controllerAs: 'vm'\n            };\n\n            var conversationViews = [];\n            conversationViews['suggested@follow'] = { 'suggested@follow': conversationViewConfig };\n            conversationViews['following@follow'] = { 'following@follow': conversationViewConfig };\n            conversationViews['follower@follow'] = { 'follower@follow': conversationViewConfig };\n            conversationViews['timeline@home'] = { 'timeline@home': conversationViewConfig };\n            conversationViews['mentions@home'] = { 'mentions@home': conversationViewConfig };\n            conversationViews['favorites@home'] = { 'favorites@home': conversationViewConfig };\n            conversationViews['company@home'] = { 'more@home': conversationViewConfig };\n            conversationViews['blockedusers@home'] = { 'more@home': profileViewConfig };\n            conversationViews['allusers@home'] = { 'more@home': profileViewConfig };\n\n            var tagViewConfig = {\n                templateUrl: 'app/shared/state/tag/tag.html',\n                controller: 'TagCtrl',\n                controllerAs: 'vm'\n            };\n\n            var tagViews = [];\n            tagViews['suggested@follow'] = { 'suggested@follow': tagViewConfig };\n            tagViews['following@follow'] = { 'following@follow': tagViewConfig };\n            tagViews['follower@follow'] = { 'follower@follow': tagViewConfig };\n            tagViews['timeline@home'] = { 'timeline@home': tagViewConfig };\n            tagViews['mentions@home'] = { 'mentions@home': tagViewConfig };\n            tagViews['favorites@home'] = { 'favorites@home': tagViewConfig };\n            tagViews['company@home'] = { 'more@home': tagViewConfig };\n            tagViews['blockedusers@home'] = { 'more@home': profileViewConfig };\n            tagViews['allusers@home'] = { 'more@home': profileViewConfig };\n\n            var service = {\n                addProfileState: addProfileState,\n                addConversationState: addConversationState,\n                addTagState: addTagState\n            };\n\n            addProfileState.$inject = ['prefixName', 'parentName'];\n            function addProfileState(prefixName, parentName) {\n                $stateProvider.state(prefixName + '.profile', {\n                    url: '/profile/:username',\n                    views: profileViews[prefixName + '@' + parentName],\n                    resolve: {\n                        user: getUser,\n                        statuses: getStatuses,\n                        currentUser: getCurrentUser\n                    }\n                });\n\n                getUser.$inject = ['UserService', '$stateParams'];\n                function getUser(UserService, $stateParams) {\n                    return UserService.get({ username : $stateParams.username }).$promise;\n                }\n\n                getStatuses.$inject = ['user', 'StatusService'];\n                function getStatuses(user, StatusService) {\n                    return StatusService.getUserTimeline({ username: user.username }).$promise;\n                }\n\n                getCurrentUser.$inject = ['currentUser'];\n                function getCurrentUser(currentUser) {\n                    return currentUser;\n                }\n            }\n\n            addConversationState.$inject = ['prefixName', 'parentName'];\n            function addConversationState(prefixName, parentName) {\n                $stateProvider.state(prefixName + '.conversation', {\n                    url: '/conversation/:statusId',\n                    views: conversationViews[prefixName + '@' + parentName],\n                    resolve: {\n                        originalStatus: getOriginalStatus,\n                        conversation: getConversation\n                    }\n                });\n\n                getOriginalStatus.$inject = ['StatusService', '$stateParams'];\n                function getOriginalStatus(StatusService, $stateParams) {\n                    return StatusService.get({ statusId : $stateParams.statusId }).$promise;\n                }\n\n                getConversation.$inject = ['StatusService', '$stateParams'];\n                function getConversation(StatusService, $stateParams) {\n                    return StatusService.getDetails({ statusId : $stateParams.statusId }).$promise;\n                }\n            }\n\n            addTagState.$inject = ['prefixName', 'parentName'];\n            function addTagState(prefixName, parentName) {\n                $stateProvider.state(prefixName + '.tag', {\n                    url: '/tag/:tag',\n                    views: tagViews[prefixName + '@' + parentName],\n                    resolve: {\n                        tag: getTag,\n                        statuses: getStatuses\n                    }\n                });\n\n                getTag.$inject = ['$stateParams'];\n                function getTag($stateParams) {\n                    return $stateParams.tag;\n                }\n\n                getStatuses.$inject = ['TagService', '$stateParams'];\n                function getStatuses(TagService, $stateParams) {\n                    return TagService.getTagTimeline({ tag: $stateParams.tag }).$promise;\n                }\n            }\n\n            return service;\n\n        }\n    }\n\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/services/HomeService.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami.services')\n        .factory('HomeService', homeService);\n\n    homeService.$inject = ['$resource', 'PathService'];\n    function homeService($resource, PathService) {\n        return $resource(null, null,\n            {\n                'getMentions': {\n                    method: 'GET', isArray: true, url: '/tatami/rest/mentions',\n                    transformResponse: responseTransform\n                },\n                'getFavorites': {\n                    method: 'GET', isArray: true, url: '/tatami/rest/favorites',\n                    transformResponse: responseTransform\n                },\n                'getCompanyTimeline': {\n                    method: 'GET', isArray: true, url: '/tatami/rest/company',\n                    transformResponse: responseTransform\n                }\n            });\n\n        responseTransform.$inject = ['statuses'];\n        function responseTransform(statuses) {\n            statuses = angular.fromJson(statuses);\n\n            for(var i = 0; i < statuses.length; i++) {\n                statuses[i]['avatarURL'] = PathService.getAvatar(statuses[i]);\n\n                if(statuses[i].geoLocalization) {\n                    var latitude = statuses[i].geoLocalization.split(',')[0].trim();\n                    var longitude = statuses[i].geoLocalization.split(',')[1].trim();\n                    statuses[i]['locationURL'] =\n                        'https://www.openstreetmap.org/?mlon='\n                        + longitude + '&mlat=' + latitude;\n                }\n            }\n\n            return statuses;\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/services/ProfileService.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami.services')\n        .factory('ProfileService', profileService);\n\n    profileService.$inject = ['$resource', 'PathService'];\n\n    function profileService($resource, PathService) {\n        return $resource('/tatami/rest/account/profile', null,\n            {\n                'get': {\n                    method: 'GET',\n                    transformResponse: function (profile) {\n                        profile = angular.fromJson(profile);\n                        profile['avatarURL'] = PathService.getAvatar(profile);\n                        return profile;\n                    }\n                },\n                'update': {\n                    method: 'PUT',\n                    transformRequest: function (profile) {\n                        delete profile['avatarURL'];\n                        return angular.toJson(profile);\n                    }\n                }\n            });\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/services/StatusService.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami.services')\n        .factory('StatusService', statusService);\n\n    statusService.$inject = ['$resource', 'PathService'];\n    function statusService($resource, PathService) {\n        var responseTransform = function (statuses) {\n            statuses = angular.fromJson(statuses);\n\n            for (var i = 0; i < statuses.length; i++) {\n                statuses[i]['avatarURL'] = PathService.getAvatar(statuses[i]);\n\n                if (statuses[i].geoLocalization) {\n                    var latitude = statuses[i].geoLocalization.split(',')[0].trim();\n                    var longitude = statuses[i].geoLocalization.split(',')[1].trim();\n                    statuses[i]['locationURL'] =\n                        'https://www.openstreetmap.org/?mlon='\n                        + longitude + '&mlat=' + latitude;\n                }\n            }\n\n            return statuses;\n        };\n        return $resource('/tatami/rest/statuses/:statusId', null,\n            {\n                'get': {\n                    method: 'GET',\n                    cache: false,\n                    transformResponse: function (status) {\n                        status = angular.fromJson(status);\n\n                        status.avatarURL = PathService.getAvatar(status);\n\n                        if (status.geoLocalization) {\n                            var latitude = status.geoLocalization.split(',')[0].trim();\n                            var longitude = status.geoLocalization.split(',')[1].trim();\n                            status['locationURL'] =\n                                'https://www.openstreetmap.org/?mlon='\n                                + longitude + '&mlat=' + latitude;\n                        }\n\n                        return status;\n                    }\n                },\n                'getHomeTimeline': {\n                    method: 'GET',\n                    isArray: true,\n                    url: '/tatami/rest/statuses/home_timeline',\n                    cache: false,\n                    transformResponse: responseTransform\n                },\n                'getUserTimeline': {\n                    method: 'GET',\n                    isArray: true,\n                    params: {username: '@username'},\n                    url: '/tatami/rest/statuses/:username/timeline',\n                    cache: false,\n                    transformResponse: responseTransform\n                },\n                'getDetails': {\n                    method: 'GET',\n                    params: {statusId: '@statusId'},\n                    url: '/tatami/rest/statuses/details/:statusId',\n                    cache: false,\n                    transformResponse: function (details) {\n                        details = angular.fromJson(details);\n\n                        for (var i = 0; i < details.discussionStatuses.length; i++) {\n                            details.discussionStatuses[i]['avatarURL'] = PathService.getAvatar(details.discussionStatuses[i]);\n\n                            if (details.discussionStatuses[i].geoLocalization) {\n                                var latitude = details.discussionStatuses[i].geoLocalization.split(',')[0].trim();\n                                var longitude = details.discussionStatuses[i].geoLocalization.split(',')[1].trim();\n                                details.discussionStatuses[i]['locationURL'] =\n                                    'https://www.openstreetmap.org/?mlon='\n                                    + longitude + '&mlat=' + latitude;\n                            }\n                        }\n\n                        for (var i = 0; i < details.sharedByLogins.length; i++) {\n                            details.sharedByLogins[i]['avatarURL'] = PathService.getAvatar(details.sharedByLogins[i]);\n                        }\n\n                        return details;\n                    }\n                },\n                'update': {method: 'PATCH', cache: false, params: {statusId: '@statusId'}},\n                'announce': {method: 'PATCH', cache: false, params: {params: '@statusId'}},\n                'hideStatus': {\n                    method: 'POST',\n                    params: {statusId: '@statusId'},\n                    cache: false,\n                    url: '/tatami/rest/statuses/hide/:statusId'\n                }\n            });\n\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/services/UserService.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami.services')\n        .factory('UserService', userService);\n\n    userService.$inject = ['$resource', 'PathService'];\n    function userService($resource, PathService) {\n        var responseTransform = function (users) {\n            users = angular.fromJson(users);\n\n            for (var i = 0; i < users.length; i++) {\n                users[i]['avatarURL'] = PathService.getAvatar(users[i]);\n            }\n\n            return users;\n        };\n        return $resource('/tatami/rest/users/:username', null,\n            {\n                'get': {\n                    method: 'GET', params: {username: '@username'},\n                    cache: false,\n                    transformResponse: function (user) {\n                        user = angular.fromJson(user);\n                        user['avatarURL'] = PathService.getAvatar(user);\n                        return user;\n                    }\n                },\n                'query': {\n                    method: 'GET',\n                    isArray: true,\n                    url: '/tatami/rest/users',\n                    transformResponse: responseTransform\n                },\n                'getFollowing': {\n                    method: 'GET',\n                    isArray: true,\n                    params: {username: '@username'},\n                    url: '/tatami/rest/users/:username/friends',\n                    transformResponse: responseTransform\n                },\n                'getFollowers': {\n                    method: 'GET',\n                    isArray: true,\n                    params: {username: '@username'},\n                    url: '/tatami/rest/users/:username/followers',\n                    transformResponse: responseTransform\n                },\n                'getSuggestions': {\n                    method: 'GET',\n                    isArray: true,\n                    url: '/tatami/rest/users/suggestions',\n                    transformResponse: function (suggestions) {\n                        suggestions = angular.fromJson(suggestions);\n\n                        for (var i = 0; i < suggestions.length; i++) {\n                            suggestions[i]['avatarURL'] = PathService.getAvatar(suggestions[i]);\n                            suggestions[i]['followingUser'] = false;\n                        }\n\n                        return suggestions;\n                    }\n                },\n                'follow': {\n                    method: 'PATCH',\n                    params: {username: '@username'}\n                },\n                'searchUsers': {\n                    method: 'GET',\n                    isArray: true,\n                    url: '/tatami/rest/users/:term',\n                    transformResponse: responseTransform\n                },\n                'deactivate': {\n                    method: 'PATCH',\n                    params: {username: '@username'}\n                }\n            });\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/services/account.service.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami.services')\n        .factory('AccountService', accountService);\n\n    accountService.$inject = ['$resource', 'PathService'];\n    function accountService($resource, PathService) {\n\n        return $resource('/tatami/rest/account/admin', null, null);\n    }\n\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/services/block.service.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami.services')\n        .factory('BlockService', blockService);\n\n    blockService.$inject = ['$resource', 'PathService'];\n    function blockService($resource, PathService) {\n\n        var responseTransform = function (users) {\n            users = angular.fromJson(users);\n\n            for (var i = 0; i < users.length; i++) {\n                users[i]['avatarURL'] = PathService.getAvatar(users[i]);\n            }\n            return users;\n        };\n\n        return $resource(null, null,\n            {\n                'getBlockedUsersForUser': {\n                    method: 'GET',\n                    isArray: true,\n                    params: {username: '@username'},\n                    url: '/tatami/rest/block/blockedusers/:username',\n                    transformResponse: responseTransform\n                },\n                'updateBlockedUser': {\n                    method: 'PATCH',\n                    params: { username: '@username'},\n                    url: '/tatami/rest/block/update/:username',\n                    transformResponse: function (blockedUser) {\n                        blockedUser = angular.fromJson(blockedUser);\n                        return blockedUser;\n                    }\n                }\n            });\n\n    }\n\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/services/localStorage.service.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami.services')\n        .factory('$localStorage', localStorage);\n\n    localStorage.$inject = ['$window'];\n    function localStorage($window) {\n        var service = {\n            get: getFromLocalStorage,\n            set: setFromLocalStorage,\n            signOut: clearToken\n        };\n\n        return service;\n\n        getFromLocalStorage.$inject = ['key'];\n        function getFromLocalStorage(key) {\n            if(isLocalStorageUndefined(key)) {\n                return undefined;\n            }\n            return JSON.parse($window.localStorage[key] || '{}');\n        }\n\n        setFromLocalStorage.$inject = ['key', 'value'];\n        function setFromLocalStorage(key, value) {\n            $window.localStorage[key] = JSON.stringify(value);\n        }\n\n        function clearToken() {\n            $window.localStorage.removeItem('token');\n        }\n\n        isLocalStorageUndefined.$inject = ['key'];\n        function isLocalStorageUndefined(key) {\n            return $window.localStorage.length === 0 || $window.localStorage[key] === 'undefined';\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/services/path.service.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami.services')\n        .factory('PathService', avatarService);\n\n    avatarService.$inject = ['TatamiEndpoint'];\n    function avatarService(TatamiEndpoint) {\n        var service = {\n            getAvatar: getAvatar\n        };\n\n        return service;\n\n        getAvatar.$inject = ['user'];\n        function getAvatar(user) {\n            return TatamiEndpoint.getEndpoint().url + (user.avatar && user.avatar !== '' ? '/tatami/avatar/' + user.avatar + '/photo.jpg' : '/assets/img/default_image_profile.png');\n        }\n\n        //buildPath() removed - REST endpoints being accessed were being cached, leading to issues when swapping endpoints\n        //new implementation intercepts url requests beginning with \"/\" and tacks on the current endpoint url as a prefix\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/services/report.service.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami.services')\n        .factory('ReportService', reportService);\n\n    reportService.$inject = ['$resource', 'PathService'];\n    function reportService($resource, PathService) {\n\n        var responseTransform = function (statuses) {\n            statuses = angular.fromJson(statuses);\n\n            for (var i = 0; i < statuses.length; i++) {\n                statuses[i]['avatarURL'] = PathService.getAvatar(statuses[i]);\n\n            }\n\n            return statuses;\n        };\n\n        return $resource('/tatami/rest/statuses/report/:statusId', null,\n            {\n                'reportStatus': {\n                    method: 'POST',\n                    params: {statusId: '@statusId'}\n                },\n                'getReportedStatuses': {\n                    method: 'GET',\n                    isArray: true,\n                    url: '/tatami/rest/statuses/report/reportedList',\n                    transformResponse: responseTransform\n                },\n                'approveStatus': {\n                    method : 'DELETE',\n                    params: {statusId: '@statusId'}\n                },\n                'deleteStatus': {\n                    method: 'PUT',\n                    params: {statusId: '@statusId'}\n                }\n            });\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/services/service.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami.services', []);\n\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/services/tag.service.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami.services')\n        .factory('TagService', tagService);\n\n    tagService.$inject = ['$resource', 'PathService'];\n    function tagService($resource, PathService) {\n        return $resource('/tatami/rest/tags', null,\n            {\n                'get': { method:'GET', params: { tag: '@tag' }, url: '/tatami/rest/tags/:tag' },\n                'getTagTimeline': {\n                    method:'GET', isArray: true, params: { tag: '@tag' }, url: '/tatami/rest/tags/:tag/tag_timeline',\n                    transformResponse: function(statuses) {\n                        statuses = angular.fromJson(statuses);\n\n                        for(var i = 0; i < statuses.length; i++) {\n                            statuses[i]['avatarURL'] = PathService.getAvatar(statuses[i]);\n\n                            if(statuses[i].geoLocalization) {\n                                var latitude = statuses[i].geoLocalization.split(',')[0].trim();\n                                var longitude = statuses[i].geoLocalization.split(',')[1].trim();\n                                statuses[i]['locationURL'] =\n                                    'https://www.openstreetmap.org/?mlon='\n                                    + longitude + '&mlat=' + latitude;\n                            }\n                        }\n\n                        return statuses;\n                    }\n                },\n                'follow': { method:'PUT', params: { tag: '@tag' }, url: '/tatami/rest/tags/:tag' },\n                'getPopular': { method: 'GET', isArray: true, url: '/tatami/rest/tags/popular' }\n            });\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/services/toast.service.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami.services')\n        .factory('ToastService', ToastService);\n\n    ToastService.$inject = ['$window', '$translate', 'ionicToast'];\n    function ToastService($window, $translate, ionicToast) {\n\n        var service = {\n            display: displayToast\n        };\n\n        return service;\n\n        function displayToast(toastMessage){\n            $translate(toastMessage).then(function(msg){\n                if (ionic.Platform.isIOS()){\n                    ionicToast.show(msg, 'top', false, 2000);\n                }\n                else{\n                    ionicToast.show(msg, 'bottom', false, 2000);\n                }\n            });\n        }\n\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/state/conversation/conversation.controller.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .controller('ConversationCtrl', conversationCtrl);\n\n    conversationCtrl.$inject = ['$ionicPopup', '$ionicHistory', '$state', 'originalStatus', 'conversation', 'currentUser'];\n    function conversationCtrl($ionicPopup, $ionicHistory, $state, originalStatus, conversation, currentUser) {\n        var vm = this;\n        vm.conversation = buildStatusList();\n        vm.currentUser = currentUser;\n\n        function buildStatusList() {\n            try {\n                return conversation.discussionStatuses.concat(originalStatus).sort(byDate);\n            } catch (error) {\n                var deletedPopup = $ionicPopup.alert({\n                    title: 'Status Not Found!',\n                    template: 'The original status has been deleted. <br>Returning to previous state.'\n                });\n\n                deletedPopup.then(goBack);\n            }\n        }\n\n        function goBack() {\n            $ionicHistory.goBack();\n        }\n\n        byDate.$inject = ['first', 'second'];\n        function byDate(first, second) {\n            return first.statusDate - second.statusDate;\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/state/conversation/conversation.html",
    "content": "<ion-view view-title=\"{{ 'conversation.title' | translate }}\">\n        <tatami-status-list statuses=\"vm.conversation\"\n                            current-user=\"vm.currentUser\"></tatami-status-list>\n</ion-view>\n"
  },
  {
    "path": "mobile/www/app/shared/state/profile/profile.controller.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .controller('ProfileCtrl', profileCtrl);\n\n    profileCtrl.$inject = ['$ionicPopover', '$ionicPopup', '$scope', '$translate', 'user', 'statuses', 'currentUser', 'TatamiStatusRefresherService', 'UserService', 'BlockService'];\n    function profileCtrl($ionicPopover, $ionicPopup, $scope, $translate, user, statuses, currentUser, TatamiStatusRefresherService, UserService, BlockService) {\n        var vm = this;\n        vm.user = user;\n        vm.statuses = statuses;\n        vm.currentUser = currentUser;\n        vm.isCurrentUser = (vm.currentUser.username === vm.user.username);\n        vm.customHeight = (vm.currentUser.isAdmin) ? {'height': '120px'} : {'height': '70px'}; //Adapts the height of the popover depending on the role because a different number of buttons is displayed\n\n        vm.followUser = followUser;\n        vm.getNewStatuses = getNewStatuses;\n        vm.toggleActivateUser = toggleActivateUser;\n        vm.blockUser = blockUser;\n\n        function getNewStatuses() {\n            return TatamiStatusRefresherService.refreshUserTimeline(user).then(setStatuses);\n        }\n\n        setStatuses.$inject = ['statuses'];\n        function setStatuses(statuses) {\n            vm.statuses = statuses;\n        }\n\n        function followUser() {\n            UserService.follow({ username : vm.user.username }, { friend: !vm.user.friend, friendShip: true },\n                function() {\n                    vm.user.friend = !vm.user.friend;\n                });\n        }\n\n        function toggleActivateUser() {\n            var confirmPopup;\n            if (vm.user.activated) {\n                confirmPopup = $ionicPopup.confirm({\n                    title: $translate.instant('user.deactivate.title'),\n                    template: '<span translate=\"user.deactivate.confirmation\"></span>'\n                });\n            } else {\n                confirmPopup = $ionicPopup.confirm({\n                    title: $translate.instant('user.reactivate.title'),\n                    template: '<span translate=\"user.reactivate.confirmation\"></span>'\n                });\n            }\n\n            confirmPopup.then(checkDelete);\n\n            checkDelete.$inject = ['decision'];\n            function checkDelete(decision) {\n                if(decision) {\n                    UserService.deactivate({ username : vm.user.username }, {activate: true},\n                        function() {\n                            vm.user.activated = !vm.user.activated;\n                        });\n                }\n            }\n        }\n\n        function blockUser() {\n            var confirmPopup = $ionicPopup.confirm({\n                title: $translate.instant('user.block.title'),\n                template: '<span translate=\"user.block.confirmation\"></span>'\n            });\n\n            confirmPopup.then(checkDelete);\n\n            checkDelete.$inject = ['decision'];\n            function checkDelete(decision) {\n                if(decision) {\n                    BlockService.updateBlockedUser( {username: vm.user.username }, function () {\n                            ToastService.display('user.block.success');\n                        }\n                    );\n                }\n            }\n\n        }\n\n        $ionicPopover.fromTemplateUrl('app/shared/state/profile/userOptionsMenu.html', {\n            scope: $scope\n        }).then(function(popover) {\n            $scope.popover = popover;\n        });\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/state/profile/profile.html",
    "content": "<ion-view view-title=\"@{{ vm.user.username }}\">\n    <ion-nav-buttons side=\"secondary\">\n        <button class=\"button ion-gear-a\"\n                ng-if=\"!vm.isCurrentUser\"\n                style=\"font-size: 30px;\"\n                ng-click=\"popover.show($event)\"></button>\n        <button class=\"button ion-person-add\"\n                ng-if=\"!vm.isCurrentUser\"\n                ng-class=\"{ 'button-calm' : vm.user.friend, 'button-stable button-outline' : !vm.user.friend }\"\n                style=\"font-size: 30px;\"\n                ng-click=\"vm.followUser()\"></button>\n    </ion-nav-buttons>\n    <ion-content class=\"tatami-header tatami-footer\" ng-style=\"{'background-color':'#f5f5f5'}\">\n        <ion-refresher on-refresh=\"vm.getNewStatuses()\"></ion-refresher>\n        <tatami-user-detail user=\"vm.user\"></tatami-user-detail>\n        <ion-list>\n            <ion-item ng-repeat=\"status in vm.statuses\">\n                <tatami-status status=\"status\" current-user=\"vm.currentUser\"></tatami-status>\n            </ion-item>\n        </ion-list>\n    </ion-content>\n</ion-view>\n"
  },
  {
    "path": "mobile/www/app/shared/state/profile/userOptionsMenu.html",
    "content": "<ion-popover-view ng-style=\"vm.customHeight\" scroll=\"false\">\n    <ion-content>\n        <div class=\"list\" ng-click=\"popover.hide()\">\n            <a class=\"item assertive\" target=\"_blank\" ng-click=\"vm.blockUser()\">\n                <span class=\"ion-close-circled padding-right\"></span>\n                <span translate=\"user.profile.options.block\"></span>\n            </a>\n            <a class=\"item assertive\" ng-if=\"vm.currentUser.isAdmin && vm.user.activated\" ng-click=\"vm.toggleActivateUser()\" >\n                <span class=\"ion-trash-a padding-right\"></span>\n                <span translate=\"user.profile.options.deactivate\"></span>\n            </a>\n            <a class=\"item calm\" ng-if=\"vm.currentUser.isAdmin && !vm.user.activated\" ng-click=\"vm.toggleActivateUser()\" >\n                <span class=\"ion-trash-a padding-right\"></span>\n                <span translate=\"user.profile.options.reactivate\"></span>\n            </a>\n        </div>\n    </ion-content>\n</ion-popover-view>\n"
  },
  {
    "path": "mobile/www/app/shared/state/tag/tag.controller.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .controller('TagCtrl', tagCtrl);\n\n    tagCtrl.$inject = ['tag', 'statuses', 'currentUser', 'TatamiStatusRefresherService'];\n    function tagCtrl(tag, statuses, currentUser, TatamiStatusRefresherService) {\n        var vm = this;\n        vm.tag = tag;\n        vm.statuses = statuses;\n        vm.currentUser = currentUser;\n        vm.getNewStatuses = getNewStatuses;\n        vm.getOldStatuses = getOldStatuses;\n\n        function getNewStatuses() {\n            return TatamiStatusRefresherService.refreshTagTimeline(vm.tag);\n        }\n\n        getOldStatuses.$inject = ['finalStatus'];\n        function getOldStatuses(finalStatus) {\n            return TatamiStatusRefresherService.getOldTags(finalStatus, vm.tag)\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/state/tag/tag.html",
    "content": "<ion-view view-title=\"#{{ vm.tag }}\">\n    <tatami-status-list statuses=\"vm.statuses\"\n                        current-user=\"vm.currentUser\"\n                        tatami-refresher=\"vm.getNewStatuses()\"\n                        tatami-infinite-refresher=\"vm.getOldStatuses(finalStatus)\"></tatami-status-list>\n</ion-view>\n"
  },
  {
    "path": "mobile/www/app/shared/status/blockUserMenu.html",
    "content": "<ion-popover-view ng-style=\"vm.customHeight\">\n    <ion-content>\n        <div class=\"list\" ng-click=\"popover.hide()\">\n            <a class=\"item\"  ng-if=\"vm.currentUser.isAdmin\" ng-click=\"vm.announceStatus()\" >\n                <span class=\"ion-speakerphone padding-right\"></span>\n                <span class=\"right\" translate=\"status.announcement.action\"></span>\n            </a>\n            <a class=\"item\" target=\"_blank\" ng-click=\"vm.hideStatus()\">\n                <span class=\"ion-minus-round padding-right\"></span>\n                <span translate=\"status.hide.action\" right></span>\n            </a>\n            <a class=\"item\" target=\"_blank\" ng-click=\"vm.reportStatus()\">\n                <span class=\"ion-alert padding-right\"></span>\n                <span class=\"html-editor-align-right\" translate=\"status.block.reportStatus\"></span>\n            </a>\n            <a class=\"item\" target=\"_blank\" ng-click=\"vm.blockUser()\">\n                <span class=\"ion-close-circled padding-right\"></span>\n                <span translate=\"status.block.blockUser\"></span>\n            </a>\n            <a class=\"item assertive\" ng-if=\"vm.currentUser.isAdmin\" ng-click=\"vm.remove()\" >\n                <span class=\"ion-trash-a padding-right\"></span>\n                <span translate=\"status.block.delete\"></span>\n            </a>\n        </div>\n    </ion-content>\n</ion-popover-view>\n"
  },
  {
    "path": "mobile/www/app/shared/status/list/status-list.html",
    "content": "<ion-content class=\"tatami-header tatami-footer\">\n    <ion-refresher ng-if=\"!vm.$state.includes('*.conversation')\" on-refresh=\"vm.getNewStatuses()\"></ion-refresher>\n    <ion-list>\n        <ion-item ng-repeat=\"status in vm.statuses\">\n            <tatami-status status=\"status\" current-user=\"vm.currentUser\" on-delete=\"vm.remove(status)\"></tatami-status>\n        </ion-item>\n        <div class=\"text-center\" ng-if=\"!vm.statuses.length\" translate=\"status.noContent\" ng-style=\"{'color':'#ababab','padding':'40px'}\"/>\n    </ion-list>\n    <ion-infinite-scroll ng-if=\"!vm.finishedTimeline && !vm.$state.includes('*.conversation')\" on-infinite=\"vm.getNewInfiniteScrollStatuses()\"></ion-infinite-scroll>\n</ion-content>\n"
  },
  {
    "path": "mobile/www/app/shared/status/list/status.list.directive.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .directive('tatamiStatusList', tatamiStatusList);\n\n    function tatamiStatusList() {\n        var directive = {\n            restrict: 'E',\n            scope: {\n                statuses: '=',\n                currentUser: '=',\n                tatamiRefresher: '&',\n                tatamiInfiniteRefresher: '&'\n            },\n            controller: controller,\n            controllerAs: 'vm',\n            templateUrl: 'app/shared/status/list/status-list.html'\n        };\n\n        return directive;\n    }\n\n    controller.$inject = ['$scope', '$state'];\n    function controller($scope, $state) {\n        var vm = this;\n        vm.statuses = $scope.statuses;\n        vm.currentUser = $scope.currentUser;\n        vm.$state = $state;\n        vm.getNewStatuses = getNewStatuses;\n        vm.getNewInfiniteScrollStatuses = getNewInfiniteScrollStatuses;\n        vm.remove = remove;\n        vm.finishedTimeline = vm.statuses && vm.statuses.length < 20;\n\n        function getNewStatuses() {\n            $scope.tatamiRefresher().then(setStatuses);\n        }\n\n        function getNewInfiniteScrollStatuses() {\n            if(vm.statuses && vm.statuses.length > 0) {\n                var lastStatus = vm.statuses[vm.statuses.length - 1].timelineId;\n                $scope.tatamiInfiniteRefresher({ finalStatus: lastStatus }).then(addNewStatuses);\n            }\n        }\n\n        remove.$inject = ['status'];\n        function remove(status) {\n            vm.statuses.splice(vm.statuses.indexOf(status), 1);\n        }\n\n        setStatuses.$inject = ['statuses'];\n        function setStatuses(statuses) {\n            vm.statuses = statuses;\n        }\n\n        addNewStatuses.$inject = ['oldStatuses'];\n        function addNewStatuses(oldStatuses) {\n            if(oldStatuses.length === 0) {\n                vm.finishedTimeline = true;\n            }\n\n            vm.statuses.push.apply(vm.statuses, oldStatuses);\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/status/status.directive.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .directive('tatamiStatus', tatamiStatus);\n\n    function tatamiStatus() {\n        var directive = {\n            restrict: 'E',\n            scope: {\n                status: '=',\n                currentUser: '=',\n                onDelete: '&'\n            },\n            controller: controller,\n            controllerAs: 'vm',\n            templateUrl: 'app/shared/status/status.html'\n        };\n\n        return directive;\n    }\n\n    controller.$inject = ['$scope', '$state', '$ionicPopup', '$ionicPopover', '$filter', '$sce', 'StatusService', 'PathService', 'BlockService', '$translate', 'ReportService', 'ToastService', 'TatamiEndpoint'];\n    function controller($scope, $state, $ionicPopup, $ionicPopover, $filter, $sce, StatusService, PathService, BlockService, $translate, ReportService, ToastService, TatamiEndpoint) {\n        var vm = this;\n\n        vm.state = $state.current.name;\n        vm.status = $scope.status;\n        vm.status.content = $filter('markdown')(vm.status.content);\n\n        vm.currentUser = $scope.currentUser;\n        vm.isAdmin = $scope.currentUser.isAdmin;\n        vm.customHeight = (vm.isAdmin)? {'height': '270px'} : {'height': '170px'}; //Adapts the height of the popover depending on the role because a different number of buttons is displayed\n        vm.remove = remove;\n        vm.favorite = favorite;\n        vm.isCurrentUser = !vm.currentUser || vm.currentUser.username === vm.status.username;\n        vm.postReply = postReply;\n        vm.goToConversation = goToConversation;\n        vm.goToProfile = goToProfile;\n        vm.goToTagTimeline = goToTagTimeline;\n        vm.shareStatus = shareStatus;\n        vm.buildAttachmentUrl = buildAttachmentUrl;\n        vm.blockUser = blockUser;\n        vm.reportStatus = reportStatus;\n        vm.hideStatus = hideStatus;\n        vm.announceStatus = announceStatus;\n        vm.tatamEndpoint = TatamiEndpoint.getEndpoint().url;\n\n        function remove() {\n            var confirmPopup = $ionicPopup.confirm({\n                title: 'Delete',\n                template: '<span translate=\"status.delete\"></span>'\n            });\n\n            confirmPopup.then(checkDelete);\n\n            checkDelete.$inject = ['decision'];\n            function checkDelete(decision) {\n                if(decision) {\n                    StatusService.delete({ statusId : vm.status.statusId }, function() {\n                        $scope.onDelete(vm.status);\n                    });\n                }\n            }\n\n        }\n\n        function favorite() {\n            StatusService.update({ statusId: vm.status.statusId }, { favorite: !vm.status.favorite }, function (status) {\n                setStatus(status);\n                if(vm.status.favorite){\n                    ToastService.display('status.favorite.add');\n                } else {\n                    ToastService.display('status.favorite.remove');\n                }\n            });\n        }\n\n        function postReply() {\n            $state.go('post', { statusId : vm.status.statusId });\n        }\n\n        goToConversation.$inject = ['statusId'];\n        function goToConversation(statusId) {\n            var destinationState = $state.current.name.split('.')[0] + '.conversation';\n            $state.go(destinationState, { statusId : statusId });\n        }\n\n        goToProfile.$inject = ['username'];\n        function goToProfile(username) {\n            var destinationState = $state.current.name.split('.')[0] + '.profile';\n            $state.go(destinationState, { username : username });\n        }\n\n        goToTagTimeline.$inject = ['tag'];\n        function goToTagTimeline(tag) {\n            var destinationState = $state.current.name.split('.')[0] + '.tag';\n            $state.go(destinationState, { tag: tag });\n        }\n\n        function shareStatus() {\n            StatusService.update({statusId: vm.status.statusId}, {shared: !vm.status.shareByMe}, function(status){\n                setStatus(status);\n                ToastService.display('status.share.toast');\n            });\n        }\n\n        function reportStatus() {\n            var confirmPopup = $ionicPopup.confirm({\n                title: 'Report Status',\n                template: '<span translate=\"status.reportStatus.message\"></span>'\n            });\n            confirmPopup.then(reported);\n            reported.$inject = ['decision'];\n            function reported(decision) {\n                if(decision) {\n                    ReportService.reportStatus({statusId: vm.status.statusId}, function () {\n                        ToastService.display('status.reportStatus.toast');\n                        }\n                    );\n                }\n            }\n\n        }\n\n        setStatus.$inject = ['status'];\n        function setStatus(status) {\n            vm.status = status;\n        }\n\n        buildAttachmentUrl.$inject = ['attachment'];\n        function buildAttachmentUrl(attachment) {\n            var location = TatamiEndpoint.getEndpoint().url;\n            return location + '/tatami/file/' + attachment.attachmentId + '/' + attachment.filename;\n        }\n\n        $ionicPopover.fromTemplateUrl('app/shared/status/blockUserMenu.html', {\n            scope: $scope\n        }).then(function(popover) {\n            $scope.popover = popover;\n        });\n\n        function blockUser() {\n            var confirmPopup = $ionicPopup.confirm({\n                title: 'Block User',\n                template: '<span translate=\"user.block.confirmation\"></span>'\n            });\n\n            confirmPopup.then(checkDelete);\n\n            checkDelete.$inject = ['decision'];\n            function checkDelete(decision) {\n                if(decision) {\n                    BlockService.updateBlockedUser( {username: vm.status.username }, function () {\n                        ToastService.display('user.block.success');\n                        }\n                    );\n                    $state.go($state.current, {}, {reload: true});\n                    // $scope.onDelete(vm.status);\n                }\n            }\n        }\n\n        function hideStatus() {\n            StatusService.hideStatus({statusId: vm.status.statusId}, function () {\n                $scope.onDelete(vm.status);\n                ToastService.display('status.hide.toast');\n            });\n        }\n\n        function announceStatus() {\n            StatusService.update({statusId: vm.status.statusId}, {announced: true}, function(){\n                setStatus;\n                ToastService.display('status.announcement.toast');\n            });\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/status/status.html",
    "content": "<span>\n    <div class=\"item-avatar item-text-wrap tatami-avatar\">\n        <img ng-src=\"{{ vm.status.avatarURL }}\"/>\n        <p ng-if=\"status.type == 'SHARE'\">\n            <span class=\"ion-share\">&nbsp;</span>\n            <a ng-click=\"vm.goToProfile(vm.status.sharedByUsername)\">\n                <span class=\"text-muted\">@{{ vm.status.sharedByUsername }}</span>\n            </a>\n            <span translate=\"status.share.title\">share</span>\n            <br>\n        </p>\n        <p ng-if=\"status.type == 'ANNOUNCEMENT'\">\n            <span class=\"ion-speakerphone\">&nbsp;</span>\n            <a ng-click=\"vm.goToProfile(vm.status.sharedByUsername)\">\n                <span class=\"text-muted\">@{{ vm.status.sharedByUsername }}</span>\n            </a>\n            <span translate=\"status.announcement.title\">share</span>\n            <br>\n        </p>\n\n        <div class=\"profile-name\">\n            <a ng-click=\"vm.goToProfile(vm.status.username)\">\n                <h2 class=\"inline\">{{vm.status.firstName}} {{vm.status.lastName}}</h2>\n                <span class=\"inline subheading\">&nbsp;&#183; @{{vm.status.username}}</span>\n            </a>\n            <p>\n                <span class=\"date padding-right\">{{vm.status.prettyPrintStatusDate}}</span>\n                <a ng-if=\"vm.status.locationURL\" class=\"ion-location\" ng-href=\"{{ vm.status.locationURL }}\" target=\"_blank\"></a>\n            </p>\n        </div>\n    </div>\n\n    <div class=\"item-body item-text-wrap\">\n        <span ng-if=\"vm.status.type == 'MENTION_SHARE'\" class=\"ion-share\">&nbsp;</span>\n        <span ng-if=\"vm.status.type == 'MENTION_FRIEND'\" class=\"ion-person\">&nbsp;</span>\n        <span ng-if=\"status.type == 'MENTION_SHARE'\" translate=\"status.share.mention\">Your status has been shared</span>\n        <span ng-if=\"status.type == 'MENTION_FRIEND'\" translate=\"status.follower\">New follower</span>\n        <p compile=\"vm.status.content\"></p>\n        <p ng-if=\"vm.status.replyToUsername\" style=\"font-size: small\">\n            <span class=\"ion-reply\"></span>\n            <span translate=\"status.reply\">In reply to </span>\n            <span class=\"link-span\" ng-click=\"vm.goToConversation(vm.status.replyTo)\">@{{ vm.status.replyToUsername }}</span>\n        </p>\n        <p ng-if=\"vm.status.statusPrivate\" style=\"font-size: small\">\n            <span class=\"ion-locked padding-right\"></span>\n            <span translate=\"status.private\"></span>\n        </p>\n        <span ng-repeat=\"attachment in vm.status.attachments\" >\n            <img ng-if=\"attachment.filename.endsWith('.jpg') || attachment.filename.endsWith('.gif') || attachment.filename.endsWith('.jpeg') || attachment.filename.endsWith('.png')\"\n                 class=\"tatami-attached-image\" ng-src=\"{{ vm.tatamEndpoint }}/tatami/file/{{ attachment.attachmentId }}/{{ attachment.filename }}\" />\n        </span>\n        <!--No view exists to display them-->\n        <p ng-repeat=\"attachment in vm.status.attachments\">\n            <a ng-href=\"{{ vm.buildAttachmentUrl(attachment) }}\">\n                <i class=\"ion-document-text\"></i> {{ attachment.filename }}\n            </a>\n        </p>\n    </div>\n    <div ng-if = \"vm.state != 'reportedStatus'\" class=\"row\">\n        <div class=\"col-25 button button-clear ion-reply tatami-button\" ng-click=\"vm.postReply()\"></div>\n        <div class=\"col-25 button button-clear ion-star tatami-button\" ng-click=\"vm.favorite()\" ng-class=\"{ 'button-energized': vm.status.favorite }\"></div>\n        <div class=\"col-25 button button-clear ion-share tatami-button\" ng-if=\"!vm.isCurrentUser\" ng-click=\"vm.shareStatus()\" ng-class=\"{ 'button-calm': vm.status.shareByMe }\"></div>\n        <div class=\"col-25 button button-clear ion-more tatami-button\" ng-if=\"!vm.isCurrentUser\" ng-click=\"popover.show($event)\"></div>\n        <div class=\"col-25 button button-clear ion-trash-a tatami-button\" ng-if=\"vm.isCurrentUser\" ng-click=\"vm.remove()\"></div>\n    </div>\n</span>\n\n\n"
  },
  {
    "path": "mobile/www/app/shared/status/status.refresher.service.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .factory('TatamiStatusRefresherService', tatamiStatusRefresherService);\n\n    tatamiStatusRefresherService.$inject = ['$rootScope', 'StatusService', 'HomeService', 'TagService'];\n    function tatamiStatusRefresherService($rootScope, StatusService, HomeService, TagService) {\n        var service = {\n            refreshHomeTimeline: refreshHomeTimeline,\n            refreshCompanyTimeline: refreshCompanyTimeline,\n            refreshMentions: refreshMentions,\n            refreshFavorites: refreshFavorites,\n            refreshUserTimeline: refreshUserTimeline,\n            refreshTagTimeline: refreshTagTimeline,\n            getOldFromHomeTimeline: getOldFromHomeTimeline,\n            getOldFromCompanyTimeline: getOldFromCompanyTimeline,\n            getOldMentions: getOldMentions,\n            getOldTags: getOldTags\n        };\n\n        return service;\n\n        function refreshHomeTimeline() {\n            return StatusService.getHomeTimeline().$promise.then(updateStatuses);\n        }\n\n        function refreshCompanyTimeline() {\n            return HomeService.getCompanyTimeline().$promise.then(updateStatuses);\n        }\n\n        refreshUserTimeline.$inject = ['user'];\n        function refreshUserTimeline(user) {\n            return StatusService.getUserTimeline({ username : user.username }).$promise.then(updateStatuses);\n        }\n\n        function refreshMentions() {\n            return HomeService.getMentions().$promise.then(updateStatuses);\n        }\n\n        function refreshFavorites() {\n            return HomeService.getFavorites().$promise.then(updateStatuses);\n        }\n\n        refreshTagTimeline.$inject = ['tag'];\n        function refreshTagTimeline(tag) {\n            return TagService.getTagTimeline({ tag: tag }).$promise.then(updateStatuses);\n        }\n\n        getOldFromHomeTimeline.$inject = ['finalStatus'];\n        function getOldFromHomeTimeline(finalStatus) {\n            return StatusService.getHomeTimeline({ finish: finalStatus }).$promise.then(updateInfiniteStatuses);\n        }\n\n        getOldFromCompanyTimeline.$inject = ['finalStatus'];\n        function getOldFromCompanyTimeline(finalStatus) {\n            return HomeService.getCompanyTimeline({ finish: finalStatus }).$promise.then(updateInfiniteStatuses);\n        }\n\n        getOldMentions.$inject = ['finalStatus'];\n        function getOldMentions(finalStatus) {\n            return HomeService.getMentions({ finish: finalStatus }).$promise.then(updateInfiniteStatuses);\n        }\n\n        getOldTags.$inject = ['finalStatus', 'tag'];\n        function getOldTags(finalStatus, tag) {\n            return TagService.getTagTimeline({ tag: tag, finish: finalStatus }).$promise.then(updateInfiniteStatuses);\n        }\n\n        updateStatuses.$inject = ['statuses'];\n        function updateStatuses(statuses) {\n            $rootScope.$broadcast('scroll.refreshComplete');\n\n            return statuses;\n        }\n\n        updateInfiniteStatuses.$inject = ['statuses'];\n        function updateInfiniteStatuses(statuses) {\n            $rootScope.$broadcast('scroll.infiniteScrollComplete');\n\n            return statuses;\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/user/user-detail.html",
    "content": "<ion-item>\n    <div class=\"row\">\n        <div class=\"col\">\n            <img ng-src=\"{{ vm.user.avatarURL }}\" class=\"center\" height=\"200px\" width=\"200px\" style=\"border-radius: 15px;\">\n        </div>\n    </div>\n\n    <div class=\"profile-name text-center\">\n        <h2>{{ vm.user.firstName + ' ' + vm.user.lastName }}</h2>\n        <h3>@{{ vm.user.username }}</h3>\n    </div>\n</ion-item>\n"
  },
  {
    "path": "mobile/www/app/shared/user/user.detail.directive.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .directive('tatamiUserDetail', tatamiUserDetail);\n\n    function tatamiUserDetail() {\n        var directive = {\n            restrict: 'E',\n            scope: {\n                user: '='\n            },\n            controller: controller,\n            controllerAs: 'vm',\n            templateUrl: 'app/shared/user/user-detail.html'\n        };\n\n        return directive;\n    }\n\n    controller.$inject = ['$scope'];\n    function controller($scope) {\n        var vm = this;\n        vm.user = $scope.user;\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/user/user.directive.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .directive('tatamiUser', tatamiUser);\n\n    tatamiUser.$inject = [];\n    function tatamiUser() {\n        var directive = {\n            restrict: 'E',\n            scope: {\n                user: '=',\n                currentUser: '='\n            },\n            controller: controller,\n            controllerAs: 'vm',\n            templateUrl: 'app/shared/user/user.html'\n        };\n\n        return directive;\n    }\n\n    controller.$inject = ['$scope', '$state', 'UserService', 'BlockService', '$ionicPopup', '$ionicListDelegate'];\n    function controller($scope, $state, UserService, BlockService, $ionicPopup, $ionicListDelegate) {\n        var vm = this;\n\n        vm.currentUser = $scope.currentUser;\n        vm.user = $scope.user;\n        vm.$state = $state;\n        vm.followUser = followUser;\n        vm.goToProfile = goToProfile;\n        vm.updateBlockUser = updateBlockUser;\n        vm.toggleActivateUser = toggleActivateUser;\n\n        function followUser() {\n            UserService.follow({ username : vm.user.username }, { friend: !vm.user.friend, friendShip: true },\n                function() {\n                    vm.user.friend = !vm.user.friend;\n                });\n        }\n\n        function goToProfile(username) {\n            var destinationState = $state.current.name.split('.')[0] + '.profile';\n            $state.go(destinationState, { username : username });\n            $ionicListDelegate.closeOptionButtons();\n        }\n\n        function updateBlockUser() {\n            BlockService.updateBlockedUser(\n                {username: vm.user.username },\n                function () {\n                    if(vm.user.blocked){\n                        $ionicPopup.alert({\n                            template: '<span translate=\"user.unblock.success\"></span>'\n                        });\n                    } else{\n                        $ionicPopup.alert({\n                            template: '<span translate=\"user.block.success\"></span>'\n                        });\n                    }\n                    vm.user.blocked = !vm.user.blocked;\n                }\n            );\n            $ionicListDelegate.closeOptionButtons();\n        }\n\n        function toggleActivateUser() {\n            var confirmPopup;\n            if(vm.user.activated){\n               confirmPopup = $ionicPopup.confirm({\n                    title: 'Deactivate user',\n                    template: '<span translate=\"user.deactivate.confirmation\"></span>'\n                });\n            } else {\n                confirmPopup = $ionicPopup.confirm({\n                    title: 'Activate user',\n                    template: '<span translate=\"user.reactivate.confirmation\"></span>'\n                });\n            }\n            confirmPopup.then(toggle);\n            toggle.$inject = ['decision'];\n            function toggle(decision) {\n                if(decision) {\n                    UserService.deactivate({ username : vm.user.username }, {activate: true},\n                        function() {\n                            vm.user.activated = !vm.user.activated;\n                        }\n                    );\n                }\n            }\n            $ionicListDelegate.closeOptionButtons();\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/user/user.html",
    "content": "<ion-item class=\"item-remove-animate item-avatar item-icon-right\" ng-click=\"vm.goToProfile(vm.user.username)\">\n    <img ng-src=\"{{ vm.user.avatarURL }}\"/>\n    <div class=\"profile-name\">\n        <h2 class=\"inline\">{{ vm.user.firstName }} {{ vm.user.lastName }}</h2>\n        <span class=\"inline subheading\">@{{ vm.user.username }}</span>\n        <i class=\"icon ion-chevron-right icon-accessory\"></i>\n    </div>\n    <ion-option-button class=\"button-positive\"\n                       ng-show=\"(vm.$state.includes('follow') || vm.$state.includes('allusers')) && !vm.user.you\"\n                       ng-click=\"vm.followUser(user)\">\n                {{ (vm.user.friend ? 'user.unfollow' : 'user.follow') | translate }}\n    </ion-option-button>\n    <ion-option-button class=\"button-positive\"\n                       ng-show=\"vm.$state.includes('blockedusers')\"\n                       ng-click=\"vm.updateBlockUser()\">\n                {{ (vm.user.blocked ? 'user.unblock.title' : 'user.block.title') | translate }}\n    </ion-option-button>\n    <ion-option-button class=\"button-assertive\"\n                           ng-show=\"(vm.$state.includes('allusers') && vm.currentUser.isAdmin) && !vm.user.you\"\n                           ng-click=\"vm.toggleActivateUser()\">\n        {{ (vm.user.activated ? 'user.deactivate.title' : 'user.reactivate.title') | translate }}\n    </ion-option-button>\n    <!--The ion-option-buttons are included in <span></span> because of an ionic bug : if the ion-options button contain an -->\n    <!--ng-if directive and an ng-click directive, then ng-click action from both the ion-item and the ion-option-button will be triggered.-->\n</ion-item>\n"
  },
  {
    "path": "mobile/www/app/shared/user/user.refresher.service.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami.services')\n        .factory('TatamiUserRefresherService', tatamiUserRefresherService);\n\n    tatamiUserRefresherService.$inject = ['$rootScope', 'UserService'];\n    function tatamiUserRefresherService($rootScope, UserService) {\n        var service = {\n            refreshSuggested: refreshSuggested,\n            refreshFollowers: refreshFollowers,\n            refreshFollowing: refreshFollowing,\n            getNextUsers: getNextUsers,\n            updateInfiniteUsers: updateInfiniteUsers\n        };\n\n        return service;\n\n        function refreshSuggested() {\n            return UserService.getSuggestions().$promise.then(updateUsers);\n        }\n\n        refreshFollowers.$inject = ['currentUser'];\n        function refreshFollowers(currentUser) {\n            return UserService.getFollowers({ username: currentUser.username }).$promise.then(updateUsers);\n        }\n\n        refreshFollowing.$inject = ['currentUser'];\n        function refreshFollowing(currentUser) {\n            return UserService.getFollowing({ username: currentUser.username }).$promise.then(updateUsers);\n        }\n\n        updateUsers.$inject = ['users'];\n        function updateUsers(users) {\n            $rootScope.$broadcast('scroll.refreshComplete');\n\n            return users;\n\n        }\n\n        getNextUsers.$inject = ['usersCount'];\n        function getNextUsers(usersCount) {\n            return UserService.query({ pagination: usersCount }).$promise.then(updateInfiniteUsers);\n        }\n\n        updateInfiniteUsers.$inject = ['users'];\n        function updateInfiniteUsers(users) {\n            $rootScope.$broadcast('scroll.infiniteScrollComplete');\n\n            return users;\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/user/users.directive.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .directive('tatamiUser', tatamiUser);\n\n    tatamiUser.$inject = ['$state'];\n    function tatamiUser($state) {\n        var directive = {\n            restrict: 'E',\n            scope: {\n                user: '='\n            },\n            controller: controller,\n            controllerAs: 'vm',\n            templateUrl: 'app/shared/user/users.html'\n        };\n\n        return directive;\n    }\n\n    controller.$inject = ['$scope', '$state', 'UserService'];\n    function controller($scope, $state, UserService) {\n        var vm = this;\n\n        vm.user = $scope.user;\n        vm.followUser = followUser;\n        function followUser() {\n            UserService.follow({ username : vm.user.username }, { friend: !vm.user.friend, friendShip: true },\n                function() {\n                    $state.reload();\n                });\n        }\n\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/shared/user/users.html",
    "content": "<ion-item class=\"item-remove-animate item-avatar item-icon-right\" ui-sref=\"profile({ username: vm.user.username })\">\n    <!--<tatami-user user=\"user\"></tatami-user>-->\n    <img ng-src=\"{{ vm.user.avatarURL }}\" />\n\n    <div class=\"profile-name\">\n        <h2 class=\"inline\">{{ vm.user.firstName }} {{ vm.user.lastName }}</h2>\n        <span class=\"inline subheading\">@{{ vm.user.username }}</span>\n        <button class=\"button button-small button-outline button-positive pull-right\" ng-if=\"!vm.user.you\" ng-click=\"vm.followUser(user)\">\n            <span ng-class=\"vm.user.friend ? 'ion-minus' : 'ion-plus'\"></span>\n        </button>\n        <i class=\"icon ion-chevron-right icon-accessory\"></i>\n    </div>\n</ion-item>\n"
  },
  {
    "path": "mobile/www/app/tatami.controller.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami')\n        .controller('TatamiCtrl', tatamiCtrl);\n\n    tatamiCtrl.$inject = ['$state'];\n    function tatamiCtrl($state) {\n        var vm = this;\n        vm.$state = $state;\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/tatami.endpoint.js",
    "content": "(function() {\n    'use strict';\n    var defaultEndpoint = {url: 'http://tatami.ippon.fr'};\n    var endpoint;\n\n    angular.module('tatami')\n        .factory('TatamiEndpoint', tatamiEndpoint);\n\n    tatamiEndpoint.$inject = ['$localStorage'];\n    function tatamiEndpoint($localStorage) {\n        var service = {\n            getEndpoint: getEndpoint,\n            setEndpoint: setEndpoint,\n            getDefault: getDefaultEndpoint,\n            reset: reset\n        };\n\n        endpoint = $localStorage.get('endpoint');\n        if(!endpoint || !endpoint.url) {\n            $localStorage.signOut();\n            endpoint = {url: defaultEndpoint.url};\n            $localStorage.set('endpoint', endpoint);\n        }\n\n        return service;\n\n        function getEndpoint() {\n            return endpoint;\n        }\n\n        setEndpoint.$inject = ['updated'];\n        function setEndpoint(updated) {\n            endpoint.url = updated;\n            $localStorage.set('endpoint', endpoint);\n        }\n\n        function getDefaultEndpoint() {\n            return defaultEndpoint;\n        }\n\n        function reset() {\n            setEndpoint(defaultEndpoint.url);\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/app/tatami.html",
    "content": "<ion-header-bar align-title=\"center\" class=\"bar-header bar-dark\">\n    <div class=\"buttons\" ng-if=\"!vm.$state.includes('login') && !vm.$state.includes('follow')\">\n        <a ui-sref=\"suggested\">\n            <button class=\"button button-clear ion-android-person-add\"></button>\n        </a>\n    </div>\n    <div class=\"buttons\" ng-if=\"vm.$state.includes('follow')\">\n        <a ui-sref=\"timeline\">\n            <button class=\"button button-clear ion-ios-list\"></button>\n        </a>\n    </div>\n    <div class=\"title\">\n        <span>\n            <img class=\"title-image\" src=\"img/logo.png\" />\n        </span>\n    </div>\n    <div class=\"buttons\" ng-if=\"!(vm.$state.includes('login') || vm.$state.includes('post'))\">\n        <a ui-sref=\"post\">\n            <button class=\"button button-clear ion-android-create\"></button>\n        </a>\n    </div>\n</ion-header-bar>\n\n<ion-nav-bar align-title=\"center\" class=\"bar-subheader bar-stable\">\n    <ion-nav-back-button></ion-nav-back-button>\n</ion-nav-bar>\n\n<ion-nav-view></ion-nav-view>\n"
  },
  {
    "path": "mobile/www/app/tatamiApp.js",
    "content": "(function() {\n    'use strict';\n\n    angular.module('tatami', [\n        'ionic',\n        'tatami.services',\n        'tatami.providers',\n        'ngResource',\n        'ngCordova',\n        'hc.marked',\n        'pascalprecht.translate',\n        'ionic-toast'\n    ]);\n\n    angular.module('tatami')\n        .run(tatamiRun)\n        .config(tatamiConfig);\n\n    tatamiRun.$inject = ['$ionicPlatform', '$state', '$localStorage', '$ionicHistory', '$translate', 'PathService', 'TatamiEndpoint', '$http'];\n    function tatamiRun($ionicPlatform, $state, $localStorage, $ionicHistory, $translate, PathService, TatamiEndpoint, $http) {\n\n        $ionicPlatform.ready(function () {\n            // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard\n            // for form inputs)\n\n            if (window.cordova && window.cordova.plugins && window.cordova.plugins.Keyboard) {\n                cordova.plugins.Keyboard.disableScroll(true);\n            }\n            if (window.StatusBar) {\n                // org.apache.cordova.statusbar required\n                if ($ionicPlatform.is('android')) {\n                    StatusBar.backgroundColorByHexString('#444444');\n                } else {\n                    StatusBar.backgroundColorByName('white');\n                }\n            }\n\n            // first, the endpoint (when TatamiEndpoint is injected) gets set up or reset\n            // based on whether or not it's been set before\n            // then, we check is the (new) default endpoint live?\n            $http({\n                url: '/tatami/rest/client/id',\n                method: 'GET'\n            }).then(function(result) {\n                // if the endpoint is live...\n                if (isValidToken()) {\n                    // ...and the token is valid, go to the timeline\n                    $state.go('timeline');\n                } else {\n                    // ...and the token is invalid, trash it and log the user out\n                    $localStorage.signOut();\n                    logout();\n                }\n            }, function(result) {\n                // if the endpoint is invalid/down, the token is worthless now, so trash it,\n                // log out, and reset endpoint to default\n                $localStorage.signOut();\n                TatamiEndpoint.reset();\n                logout();\n            });\n        });\n\n        $ionicPlatform.on('resume', function resume() {\n            if (!isValidToken()) {\n                $localStorage.signOut();\n                logout();\n            }\n        });\n\n        function logout() {\n            $localStorage.signOut();\n            $ionicHistory.clearCache();\n            $state.go('login');\n        }\n\n        function isValidToken() {\n            var token = $localStorage.get('token');\n            return token && token.expires && token.expires > new Date().getTime()\n        }\n\n        var absolutePathChecker = new RegExp('^(?:[a-z]+:)?//', 'i');\n        document.onclick = function (e) {\n            e = e ||  window.event;\n            var element = e.target || e.srcElement;\n\n            if (element.tagName == 'A' && absolutePathChecker.test(element.href)) {\n                window.open(element.href, \"_blank\", \"location=yes,presentationstyle=pagesheet,EnableViewPortScale=yes\");\n                return false;\n            }\n        };\n    }\n\n    tatamiConfig.$inject = [\n        '$resourceProvider',\n        '$stateProvider',\n        '$translateProvider',\n        '$compileProvider',\n        '$httpProvider'\n    ];\n    function tatamiConfig($resourceProvider, $stateProvider, $translateProvider, $compileProvider, $httpProvider) {\n        $compileProvider.imgSrcSanitizationWhitelist(/^\\s*(https?|ftp|mailto|file|tel):/);\n        $resourceProvider.defaults.stripTrailingSlashes = false;\n\n        $stateProvider\n        // setup an abstract state for the tabs directive\n            .state('tatami', {\n                url: '',\n                abstract: true,\n                templateUrl: 'app/tatami.html',\n                controller: 'TatamiCtrl',\n                controllerAs: 'vm',\n                resolve: {\n                    translatePartialLoader: getTranslationPartialLoader\n                }\n            });\n\n        getTranslationPartialLoader.$inject = ['$translate', '$translatePartialLoader'];\n        function getTranslationPartialLoader($translate, $translatePartialLoader) {\n            $translatePartialLoader.addPart('user');\n            $translatePartialLoader.addPart('status');\n            $translatePartialLoader.addPart('conversation');\n            return $translate.refresh();\n        }\n\n        $httpProvider.interceptors.push('authInterceptor');\n        $httpProvider.interceptors.push('authExpiredInterceptor');\n        $httpProvider.interceptors.push('endpointInterceptor');\n\n        $translateProvider.useLoader('$translatePartialLoader', {\n            urlTemplate: 'i18n/{lang}/{part}.json'\n        });\n\n        var usedLanguage = window.localStorage.getItem('language') || navigator.language.split('-')[0] || 'en';\n        window.localStorage.setItem('language', usedLanguage);\n\n        $translateProvider.preferredLanguage(usedLanguage);\n        $translateProvider.use(usedLanguage);\n        $translateProvider.useSanitizeValueStrategy('escaped');\n        $translateProvider.addInterpolation('$translateMessageFormatInterpolation');\n\n        $compileProvider.directive('compile', compile);\n\n        compile.$inject = ['$compile'];\n        function compile($compile) {\n            return directive;\n\n            directive.$inject = ['scope', 'element', 'attrs'];\n            function directive(scope, element, attrs) {\n                var ensureCompileRunsOnce = scope.$watch(\n                    function(scope) {\n                        return scope.$eval(attrs.compile);\n                    },\n                    function(value) {\n                        element.html(value);\n\n                        $compile(element.contents())(scope);\n\n                        ensureCompileRunsOnce();\n                    }\n                );\n            }\n        }\n    }\n})();\n"
  },
  {
    "path": "mobile/www/css/ionic.app.css",
    "content": "@charset \"UTF-8\";\n/*\nTo customize the look and feel of Ionic, you can override the variables\nin ionic's _variables.scss file.\n\nFor example, you might change some of the default colors:\n\n$light:                           #fff !default;\n$stable:                          #f8f8f8 !default;\n$positive:                        #387ef5 !default;\n$calm:                            #11c1f3 !default;\n$balanced:                        #33cd5f !default;\n$energized:                       #ffc900 !default;\n$assertive:                       #ef473a !default;\n$royal:                           #886aea !default;\n$dark:                            #444 !default;\n*/\n/*!\n * Copyright 2015 Drifty Co.\n * http://drifty.com/\n *\n * Ionic, v1.2.4\n * A powerful HTML5 mobile app framework.\n * http://ionicframework.com/\n *\n * By @maxlynch, @benjsperry, @adamdbradley <3\n *\n * Licensed under the MIT license. Please see LICENSE for more information.\n *\n */\n/*!\n  Ionicons, v2.0.1\n  Created by Ben Sperry for the Ionic Framework, http://ionicons.com/\n  https://twitter.com/benjsperry  https://twitter.com/ionicframework\n  MIT License: https://github.com/driftyco/ionicons\n\n  Android-style icons originally built by Google’s\n  Material Design Icons: https://github.com/google/material-design-icons\n  used under CC BY http://creativecommons.org/licenses/by/4.0/\n  Modified icons to fit ionicon’s grid from original.\n*/\n@font-face {\n  font-family: \"Ionicons\";\n  src: url(\"../fonts/ionicons.eot?v=2.0.1\");\n  src: url(\"../fonts/ionicons.eot?v=2.0.1#iefix\") format(\"embedded-opentype\"), url(\"../fonts/ionicons.ttf?v=2.0.1\") format(\"truetype\"), url(\"../fonts/ionicons.woff?v=2.0.1\") format(\"woff\"), url(\"../fonts/ionicons.woff\") format(\"woff\"), url(\"../fonts/ionicons.svg?v=2.0.1#Ionicons\") format(\"svg\");\n  font-weight: normal;\n  font-style: normal; }\n\n.ion, .ionicons,\n.ion-alert:before,\n.ion-alert-circled:before,\n.ion-android-add:before,\n.ion-android-add-circle:before,\n.ion-android-alarm-clock:before,\n.ion-android-alert:before,\n.ion-android-apps:before,\n.ion-android-archive:before,\n.ion-android-arrow-back:before,\n.ion-android-arrow-down:before,\n.ion-android-arrow-dropdown:before,\n.ion-android-arrow-dropdown-circle:before,\n.ion-android-arrow-dropleft:before,\n.ion-android-arrow-dropleft-circle:before,\n.ion-android-arrow-dropright:before,\n.ion-android-arrow-dropright-circle:before,\n.ion-android-arrow-dropup:before,\n.ion-android-arrow-dropup-circle:before,\n.ion-android-arrow-forward:before,\n.ion-android-arrow-up:before,\n.ion-android-attach:before,\n.ion-android-bar:before,\n.ion-android-bicycle:before,\n.ion-android-boat:before,\n.ion-android-bookmark:before,\n.ion-android-bulb:before,\n.ion-android-bus:before,\n.ion-android-calendar:before,\n.ion-android-call:before,\n.ion-android-camera:before,\n.ion-android-cancel:before,\n.ion-android-car:before,\n.ion-android-cart:before,\n.ion-android-chat:before,\n.ion-android-checkbox:before,\n.ion-android-checkbox-blank:before,\n.ion-android-checkbox-outline:before,\n.ion-android-checkbox-outline-blank:before,\n.ion-android-checkmark-circle:before,\n.ion-android-clipboard:before,\n.ion-android-close:before,\n.ion-android-cloud:before,\n.ion-android-cloud-circle:before,\n.ion-android-cloud-done:before,\n.ion-android-cloud-outline:before,\n.ion-android-color-palette:before,\n.ion-android-compass:before,\n.ion-android-contact:before,\n.ion-android-contacts:before,\n.ion-android-contract:before,\n.ion-android-create:before,\n.ion-android-delete:before,\n.ion-android-desktop:before,\n.ion-android-document:before,\n.ion-android-done:before,\n.ion-android-done-all:before,\n.ion-android-download:before,\n.ion-android-drafts:before,\n.ion-android-exit:before,\n.ion-android-expand:before,\n.ion-android-favorite:before,\n.ion-android-favorite-outline:before,\n.ion-android-film:before,\n.ion-android-folder:before,\n.ion-android-folder-open:before,\n.ion-android-funnel:before,\n.ion-android-globe:before,\n.ion-android-hand:before,\n.ion-android-hangout:before,\n.ion-android-happy:before,\n.ion-android-home:before,\n.ion-android-image:before,\n.ion-android-laptop:before,\n.ion-android-list:before,\n.ion-android-locate:before,\n.platform-android .tatami-location:before,\n.ion-android-lock:before,\n.ion-android-mail:before,\n.ion-android-map:before,\n.ion-android-menu:before,\n.ion-android-microphone:before,\n.ion-android-microphone-off:before,\n.ion-android-more-horizontal:before,\n.ion-android-more-vertical:before,\n.ion-android-navigate:before,\n.ion-android-notifications:before,\n.ion-android-notifications-none:before,\n.ion-android-notifications-off:before,\n.ion-android-open:before,\n.ion-android-options:before,\n.ion-android-people:before,\n.ion-android-person:before,\n.ion-android-person-add:before,\n.ion-android-phone-landscape:before,\n.ion-android-phone-portrait:before,\n.ion-android-pin:before,\n.ion-android-plane:before,\n.ion-android-playstore:before,\n.ion-android-print:before,\n.ion-android-radio-button-off:before,\n.ion-android-radio-button-on:before,\n.ion-android-refresh:before,\n.ion-android-remove:before,\n.ion-android-remove-circle:before,\n.ion-android-restaurant:before,\n.ion-android-sad:before,\n.ion-android-search:before,\n.ion-android-send:before,\n.ion-android-settings:before,\n.ion-android-share:before,\n.ion-android-share-alt:before,\n.ion-android-star:before,\n.ion-android-star-half:before,\n.ion-android-star-outline:before,\n.ion-android-stopwatch:before,\n.ion-android-subway:before,\n.ion-android-sunny:before,\n.ion-android-sync:before,\n.ion-android-textsms:before,\n.ion-android-time:before,\n.ion-android-train:before,\n.ion-android-unlock:before,\n.ion-android-upload:before,\n.ion-android-volume-down:before,\n.ion-android-volume-mute:before,\n.ion-android-volume-off:before,\n.ion-android-volume-up:before,\n.ion-android-walk:before,\n.ion-android-warning:before,\n.ion-android-watch:before,\n.ion-android-wifi:before,\n.ion-aperture:before,\n.ion-archive:before,\n.ion-arrow-down-a:before,\n.ion-arrow-down-b:before,\n.ion-arrow-down-c:before,\n.ion-arrow-expand:before,\n.ion-arrow-graph-down-left:before,\n.ion-arrow-graph-down-right:before,\n.ion-arrow-graph-up-left:before,\n.ion-arrow-graph-up-right:before,\n.ion-arrow-left-a:before,\n.ion-arrow-left-b:before,\n.ion-arrow-left-c:before,\n.ion-arrow-move:before,\n.ion-arrow-resize:before,\n.ion-arrow-return-left:before,\n.ion-arrow-return-right:before,\n.ion-arrow-right-a:before,\n.ion-arrow-right-b:before,\n.ion-arrow-right-c:before,\n.ion-arrow-shrink:before,\n.ion-arrow-swap:before,\n.ion-arrow-up-a:before,\n.ion-arrow-up-b:before,\n.ion-arrow-up-c:before,\n.ion-asterisk:before,\n.ion-at:before,\n.ion-backspace:before,\n.ion-backspace-outline:before,\n.ion-bag:before,\n.ion-battery-charging:before,\n.ion-battery-empty:before,\n.ion-battery-full:before,\n.ion-battery-half:before,\n.ion-battery-low:before,\n.ion-beaker:before,\n.ion-beer:before,\n.ion-bluetooth:before,\n.ion-bonfire:before,\n.ion-bookmark:before,\n.ion-bowtie:before,\n.ion-briefcase:before,\n.ion-bug:before,\n.ion-calculator:before,\n.ion-calendar:before,\n.ion-camera:before,\n.ion-card:before,\n.ion-cash:before,\n.ion-chatbox:before,\n.ion-chatbox-working:before,\n.ion-chatboxes:before,\n.ion-chatbubble:before,\n.ion-chatbubble-working:before,\n.ion-chatbubbles:before,\n.ion-checkmark:before,\n.ion-checkmark-circled:before,\n.ion-checkmark-round:before,\n.ion-chevron-down:before,\n.ion-chevron-left:before,\n.ion-chevron-right:before,\n.ion-chevron-up:before,\n.ion-clipboard:before,\n.ion-clock:before,\n.ion-close:before,\n.ion-close-circled:before,\n.ion-close-round:before,\n.ion-closed-captioning:before,\n.ion-cloud:before,\n.ion-code:before,\n.ion-code-download:before,\n.ion-code-working:before,\n.ion-coffee:before,\n.ion-compass:before,\n.ion-compose:before,\n.ion-connection-bars:before,\n.ion-contrast:before,\n.ion-crop:before,\n.ion-cube:before,\n.ion-disc:before,\n.ion-document:before,\n.ion-document-text:before,\n.ion-drag:before,\n.ion-earth:before,\n.ion-easel:before,\n.ion-edit:before,\n.ion-egg:before,\n.ion-eject:before,\n.ion-email:before,\n.ion-email-unread:before,\n.ion-erlenmeyer-flask:before,\n.ion-erlenmeyer-flask-bubbles:before,\n.ion-eye:before,\n.ion-eye-disabled:before,\n.ion-female:before,\n.ion-filing:before,\n.ion-film-marker:before,\n.ion-fireball:before,\n.ion-flag:before,\n.ion-flame:before,\n.ion-flash:before,\n.ion-flash-off:before,\n.ion-folder:before,\n.ion-fork:before,\n.ion-fork-repo:before,\n.ion-forward:before,\n.ion-funnel:before,\n.ion-gear-a:before,\n.ion-gear-b:before,\n.ion-grid:before,\n.ion-hammer:before,\n.ion-happy:before,\n.ion-happy-outline:before,\n.ion-headphone:before,\n.ion-heart:before,\n.ion-heart-broken:before,\n.ion-help:before,\n.ion-help-buoy:before,\n.ion-help-circled:before,\n.ion-home:before,\n.ion-icecream:before,\n.ion-image:before,\n.ion-images:before,\n.ion-information:before,\n.ion-information-circled:before,\n.ion-ionic:before,\n.ion-ios-alarm:before,\n.ion-ios-alarm-outline:before,\n.ion-ios-albums:before,\n.ion-ios-albums-outline:before,\n.ion-ios-americanfootball:before,\n.ion-ios-americanfootball-outline:before,\n.ion-ios-analytics:before,\n.ion-ios-analytics-outline:before,\n.ion-ios-arrow-back:before,\n.ion-ios-arrow-down:before,\n.ion-ios-arrow-forward:before,\n.ion-ios-arrow-left:before,\n.ion-ios-arrow-right:before,\n.ion-ios-arrow-thin-down:before,\n.ion-ios-arrow-thin-left:before,\n.ion-ios-arrow-thin-right:before,\n.ion-ios-arrow-thin-up:before,\n.ion-ios-arrow-up:before,\n.ion-ios-at:before,\n.ion-ios-at-outline:before,\n.ion-ios-barcode:before,\n.ion-ios-barcode-outline:before,\n.ion-ios-baseball:before,\n.ion-ios-baseball-outline:before,\n.ion-ios-basketball:before,\n.ion-ios-basketball-outline:before,\n.ion-ios-bell:before,\n.ion-ios-bell-outline:before,\n.ion-ios-body:before,\n.ion-ios-body-outline:before,\n.ion-ios-bolt:before,\n.ion-ios-bolt-outline:before,\n.ion-ios-book:before,\n.ion-ios-book-outline:before,\n.ion-ios-bookmarks:before,\n.ion-ios-bookmarks-outline:before,\n.ion-ios-box:before,\n.ion-ios-box-outline:before,\n.ion-ios-briefcase:before,\n.ion-ios-briefcase-outline:before,\n.ion-ios-browsers:before,\n.ion-ios-browsers-outline:before,\n.ion-ios-calculator:before,\n.ion-ios-calculator-outline:before,\n.ion-ios-calendar:before,\n.ion-ios-calendar-outline:before,\n.ion-ios-camera:before,\n.ion-ios-camera-outline:before,\n.ion-ios-cart:before,\n.ion-ios-cart-outline:before,\n.ion-ios-chatboxes:before,\n.ion-ios-chatboxes-outline:before,\n.ion-ios-chatbubble:before,\n.ion-ios-chatbubble-outline:before,\n.ion-ios-checkmark:before,\n.ion-ios-checkmark-empty:before,\n.ion-ios-checkmark-outline:before,\n.ion-ios-circle-filled:before,\n.ion-ios-circle-outline:before,\n.ion-ios-clock:before,\n.ion-ios-clock-outline:before,\n.ion-ios-close:before,\n.ion-ios-close-empty:before,\n.ion-ios-close-outline:before,\n.ion-ios-cloud:before,\n.ion-ios-cloud-download:before,\n.ion-ios-cloud-download-outline:before,\n.ion-ios-cloud-outline:before,\n.ion-ios-cloud-upload:before,\n.ion-ios-cloud-upload-outline:before,\n.ion-ios-cloudy:before,\n.ion-ios-cloudy-night:before,\n.ion-ios-cloudy-night-outline:before,\n.ion-ios-cloudy-outline:before,\n.ion-ios-cog:before,\n.ion-ios-cog-outline:before,\n.ion-ios-color-filter:before,\n.ion-ios-color-filter-outline:before,\n.ion-ios-color-wand:before,\n.ion-ios-color-wand-outline:before,\n.ion-ios-compose:before,\n.ion-ios-compose-outline:before,\n.ion-ios-contact:before,\n.ion-ios-contact-outline:before,\n.ion-ios-copy:before,\n.ion-ios-copy-outline:before,\n.ion-ios-crop:before,\n.ion-ios-crop-strong:before,\n.ion-ios-download:before,\n.ion-ios-download-outline:before,\n.ion-ios-drag:before,\n.ion-ios-email:before,\n.ion-ios-email-outline:before,\n.ion-ios-eye:before,\n.ion-ios-eye-outline:before,\n.ion-ios-fastforward:before,\n.ion-ios-fastforward-outline:before,\n.ion-ios-filing:before,\n.ion-ios-filing-outline:before,\n.ion-ios-film:before,\n.ion-ios-film-outline:before,\n.ion-ios-flag:before,\n.ion-ios-flag-outline:before,\n.ion-ios-flame:before,\n.ion-ios-flame-outline:before,\n.ion-ios-flask:before,\n.ion-ios-flask-outline:before,\n.ion-ios-flower:before,\n.ion-ios-flower-outline:before,\n.ion-ios-folder:before,\n.ion-ios-folder-outline:before,\n.ion-ios-football:before,\n.ion-ios-football-outline:before,\n.ion-ios-game-controller-a:before,\n.ion-ios-game-controller-a-outline:before,\n.ion-ios-game-controller-b:before,\n.ion-ios-game-controller-b-outline:before,\n.ion-ios-gear:before,\n.ion-ios-gear-outline:before,\n.ion-ios-glasses:before,\n.ion-ios-glasses-outline:before,\n.ion-ios-grid-view:before,\n.ion-ios-grid-view-outline:before,\n.ion-ios-heart:before,\n.ion-ios-heart-outline:before,\n.ion-ios-help:before,\n.ion-ios-help-empty:before,\n.ion-ios-help-outline:before,\n.ion-ios-home:before,\n.ion-ios-home-outline:before,\n.ion-ios-infinite:before,\n.ion-ios-infinite-outline:before,\n.ion-ios-information:before,\n.ion-ios-information-empty:before,\n.ion-ios-information-outline:before,\n.ion-ios-ionic-outline:before,\n.ion-ios-keypad:before,\n.ion-ios-keypad-outline:before,\n.ion-ios-lightbulb:before,\n.ion-ios-lightbulb-outline:before,\n.ion-ios-list:before,\n.ion-ios-list-outline:before,\n.ion-ios-location:before,\n.platform-ios .tatami-location:before,\n.ion-ios-location-outline:before,\n.ion-ios-locked:before,\n.ion-ios-locked-outline:before,\n.ion-ios-loop:before,\n.ion-ios-loop-strong:before,\n.ion-ios-medical:before,\n.ion-ios-medical-outline:before,\n.ion-ios-medkit:before,\n.ion-ios-medkit-outline:before,\n.ion-ios-mic:before,\n.ion-ios-mic-off:before,\n.ion-ios-mic-outline:before,\n.ion-ios-minus:before,\n.ion-ios-minus-empty:before,\n.ion-ios-minus-outline:before,\n.ion-ios-monitor:before,\n.ion-ios-monitor-outline:before,\n.ion-ios-moon:before,\n.ion-ios-moon-outline:before,\n.ion-ios-more:before,\n.ion-ios-more-outline:before,\n.ion-ios-musical-note:before,\n.ion-ios-musical-notes:before,\n.ion-ios-navigate:before,\n.ion-ios-navigate-outline:before,\n.ion-ios-nutrition:before,\n.ion-ios-nutrition-outline:before,\n.ion-ios-paper:before,\n.ion-ios-paper-outline:before,\n.ion-ios-paperplane:before,\n.ion-ios-paperplane-outline:before,\n.ion-ios-partlysunny:before,\n.ion-ios-partlysunny-outline:before,\n.ion-ios-pause:before,\n.ion-ios-pause-outline:before,\n.ion-ios-paw:before,\n.ion-ios-paw-outline:before,\n.ion-ios-people:before,\n.ion-ios-people-outline:before,\n.ion-ios-person:before,\n.ion-ios-person-outline:before,\n.ion-ios-personadd:before,\n.ion-ios-personadd-outline:before,\n.ion-ios-photos:before,\n.ion-ios-photos-outline:before,\n.ion-ios-pie:before,\n.ion-ios-pie-outline:before,\n.ion-ios-pint:before,\n.ion-ios-pint-outline:before,\n.ion-ios-play:before,\n.ion-ios-play-outline:before,\n.ion-ios-plus:before,\n.ion-ios-plus-empty:before,\n.ion-ios-plus-outline:before,\n.ion-ios-pricetag:before,\n.ion-ios-pricetag-outline:before,\n.ion-ios-pricetags:before,\n.ion-ios-pricetags-outline:before,\n.ion-ios-printer:before,\n.ion-ios-printer-outline:before,\n.ion-ios-pulse:before,\n.ion-ios-pulse-strong:before,\n.ion-ios-rainy:before,\n.ion-ios-rainy-outline:before,\n.ion-ios-recording:before,\n.ion-ios-recording-outline:before,\n.ion-ios-redo:before,\n.ion-ios-redo-outline:before,\n.ion-ios-refresh:before,\n.ion-ios-refresh-empty:before,\n.ion-ios-refresh-outline:before,\n.ion-ios-reload:before,\n.ion-ios-reverse-camera:before,\n.ion-ios-reverse-camera-outline:before,\n.ion-ios-rewind:before,\n.ion-ios-rewind-outline:before,\n.ion-ios-rose:before,\n.ion-ios-rose-outline:before,\n.ion-ios-search:before,\n.ion-ios-search-strong:before,\n.ion-ios-settings:before,\n.ion-ios-settings-strong:before,\n.ion-ios-shuffle:before,\n.ion-ios-shuffle-strong:before,\n.ion-ios-skipbackward:before,\n.ion-ios-skipbackward-outline:before,\n.ion-ios-skipforward:before,\n.ion-ios-skipforward-outline:before,\n.ion-ios-snowy:before,\n.ion-ios-speedometer:before,\n.ion-ios-speedometer-outline:before,\n.ion-ios-star:before,\n.ion-ios-star-half:before,\n.ion-ios-star-outline:before,\n.ion-ios-stopwatch:before,\n.ion-ios-stopwatch-outline:before,\n.ion-ios-sunny:before,\n.ion-ios-sunny-outline:before,\n.ion-ios-telephone:before,\n.ion-ios-telephone-outline:before,\n.ion-ios-tennisball:before,\n.ion-ios-tennisball-outline:before,\n.ion-ios-thunderstorm:before,\n.ion-ios-thunderstorm-outline:before,\n.ion-ios-time:before,\n.ion-ios-time-outline:before,\n.ion-ios-timer:before,\n.ion-ios-timer-outline:before,\n.ion-ios-toggle:before,\n.ion-ios-toggle-outline:before,\n.ion-ios-trash:before,\n.ion-ios-trash-outline:before,\n.ion-ios-undo:before,\n.ion-ios-undo-outline:before,\n.ion-ios-unlocked:before,\n.ion-ios-unlocked-outline:before,\n.ion-ios-upload:before,\n.ion-ios-upload-outline:before,\n.ion-ios-videocam:before,\n.ion-ios-videocam-outline:before,\n.ion-ios-volume-high:before,\n.ion-ios-volume-low:before,\n.ion-ios-wineglass:before,\n.ion-ios-wineglass-outline:before,\n.ion-ios-world:before,\n.ion-ios-world-outline:before,\n.ion-ipad:before,\n.ion-iphone:before,\n.ion-ipod:before,\n.ion-jet:before,\n.ion-key:before,\n.ion-knife:before,\n.ion-laptop:before,\n.ion-leaf:before,\n.ion-levels:before,\n.ion-lightbulb:before,\n.ion-link:before,\n.ion-load-a:before,\n.ion-load-b:before,\n.ion-load-c:before,\n.ion-load-d:before,\n.ion-location:before,\n.ion-lock-combination:before,\n.ion-locked:before,\n.ion-log-in:before,\n.ion-log-out:before,\n.ion-loop:before,\n.ion-magnet:before,\n.ion-male:before,\n.ion-man:before,\n.ion-map:before,\n.ion-medkit:before,\n.ion-merge:before,\n.ion-mic-a:before,\n.ion-mic-b:before,\n.ion-mic-c:before,\n.ion-minus:before,\n.ion-minus-circled:before,\n.ion-minus-round:before,\n.ion-model-s:before,\n.ion-monitor:before,\n.ion-more:before,\n.ion-mouse:before,\n.ion-music-note:before,\n.ion-navicon:before,\n.ion-navicon-round:before,\n.ion-navigate:before,\n.ion-network:before,\n.ion-no-smoking:before,\n.ion-nuclear:before,\n.ion-outlet:before,\n.ion-paintbrush:before,\n.ion-paintbucket:before,\n.ion-paper-airplane:before,\n.ion-paperclip:before,\n.ion-pause:before,\n.ion-person:before,\n.ion-person-add:before,\n.ion-person-stalker:before,\n.ion-pie-graph:before,\n.ion-pin:before,\n.ion-pinpoint:before,\n.ion-pizza:before,\n.ion-plane:before,\n.ion-planet:before,\n.ion-play:before,\n.ion-playstation:before,\n.ion-plus:before,\n.ion-plus-circled:before,\n.ion-plus-round:before,\n.ion-podium:before,\n.ion-pound:before,\n.ion-power:before,\n.ion-pricetag:before,\n.ion-pricetags:before,\n.ion-printer:before,\n.ion-pull-request:before,\n.ion-qr-scanner:before,\n.ion-quote:before,\n.ion-radio-waves:before,\n.ion-record:before,\n.ion-refresh:before,\n.ion-reply:before,\n.ion-reply-all:before,\n.ion-ribbon-a:before,\n.ion-ribbon-b:before,\n.ion-sad:before,\n.ion-sad-outline:before,\n.ion-scissors:before,\n.ion-search:before,\n.ion-settings:before,\n.ion-share:before,\n.ion-shuffle:before,\n.ion-skip-backward:before,\n.ion-skip-forward:before,\n.ion-social-android:before,\n.ion-social-android-outline:before,\n.ion-social-angular:before,\n.ion-social-angular-outline:before,\n.ion-social-apple:before,\n.ion-social-apple-outline:before,\n.ion-social-bitcoin:before,\n.ion-social-bitcoin-outline:before,\n.ion-social-buffer:before,\n.ion-social-buffer-outline:before,\n.ion-social-chrome:before,\n.ion-social-chrome-outline:before,\n.ion-social-codepen:before,\n.ion-social-codepen-outline:before,\n.ion-social-css3:before,\n.ion-social-css3-outline:before,\n.ion-social-designernews:before,\n.ion-social-designernews-outline:before,\n.ion-social-dribbble:before,\n.ion-social-dribbble-outline:before,\n.ion-social-dropbox:before,\n.ion-social-dropbox-outline:before,\n.ion-social-euro:before,\n.ion-social-euro-outline:before,\n.ion-social-facebook:before,\n.ion-social-facebook-outline:before,\n.ion-social-foursquare:before,\n.ion-social-foursquare-outline:before,\n.ion-social-freebsd-devil:before,\n.ion-social-github:before,\n.ion-social-github-outline:before,\n.ion-social-google:before,\n.ion-social-google-outline:before,\n.ion-social-googleplus:before,\n.ion-social-googleplus-outline:before,\n.ion-social-hackernews:before,\n.ion-social-hackernews-outline:before,\n.ion-social-html5:before,\n.ion-social-html5-outline:before,\n.ion-social-instagram:before,\n.ion-social-instagram-outline:before,\n.ion-social-javascript:before,\n.ion-social-javascript-outline:before,\n.ion-social-linkedin:before,\n.ion-social-linkedin-outline:before,\n.ion-social-markdown:before,\n.ion-social-nodejs:before,\n.ion-social-octocat:before,\n.ion-social-pinterest:before,\n.ion-social-pinterest-outline:before,\n.ion-social-python:before,\n.ion-social-reddit:before,\n.ion-social-reddit-outline:before,\n.ion-social-rss:before,\n.ion-social-rss-outline:before,\n.ion-social-sass:before,\n.ion-social-skype:before,\n.ion-social-skype-outline:before,\n.ion-social-snapchat:before,\n.ion-social-snapchat-outline:before,\n.ion-social-tumblr:before,\n.ion-social-tumblr-outline:before,\n.ion-social-tux:before,\n.ion-social-twitch:before,\n.ion-social-twitch-outline:before,\n.ion-social-twitter:before,\n.ion-social-twitter-outline:before,\n.ion-social-usd:before,\n.ion-social-usd-outline:before,\n.ion-social-vimeo:before,\n.ion-social-vimeo-outline:before,\n.ion-social-whatsapp:before,\n.ion-social-whatsapp-outline:before,\n.ion-social-windows:before,\n.ion-social-windows-outline:before,\n.ion-social-wordpress:before,\n.ion-social-wordpress-outline:before,\n.ion-social-yahoo:before,\n.ion-social-yahoo-outline:before,\n.ion-social-yen:before,\n.ion-social-yen-outline:before,\n.ion-social-youtube:before,\n.ion-social-youtube-outline:before,\n.ion-soup-can:before,\n.ion-soup-can-outline:before,\n.ion-speakerphone:before,\n.ion-speedometer:before,\n.ion-spoon:before,\n.ion-star:before,\n.ion-stats-bars:before,\n.ion-steam:before,\n.ion-stop:before,\n.ion-thermometer:before,\n.ion-thumbsdown:before,\n.ion-thumbsup:before,\n.ion-toggle:before,\n.ion-toggle-filled:before,\n.ion-transgender:before,\n.ion-trash-a:before,\n.ion-trash-b:before,\n.ion-trophy:before,\n.ion-tshirt:before,\n.ion-tshirt-outline:before,\n.ion-umbrella:before,\n.ion-university:before,\n.ion-unlocked:before,\n.ion-upload:before,\n.ion-usb:before,\n.ion-videocamera:before,\n.ion-volume-high:before,\n.ion-volume-low:before,\n.ion-volume-medium:before,\n.ion-volume-mute:before,\n.ion-wand:before,\n.ion-waterdrop:before,\n.ion-wifi:before,\n.ion-wineglass:before,\n.ion-woman:before,\n.ion-wrench:before,\n.ion-xbox:before {\n  display: inline-block;\n  font-family: \"Ionicons\";\n  speak: none;\n  font-style: normal;\n  font-weight: normal;\n  font-variant: normal;\n  text-transform: none;\n  text-rendering: auto;\n  line-height: 1;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale; }\n\n.ion-alert:before {\n  content: \"\"; }\n\n.ion-alert-circled:before {\n  content: \"\"; }\n\n.ion-android-add:before {\n  content: \"\"; }\n\n.ion-android-add-circle:before {\n  content: \"\"; }\n\n.ion-android-alarm-clock:before {\n  content: \"\"; }\n\n.ion-android-alert:before {\n  content: \"\"; }\n\n.ion-android-apps:before {\n  content: \"\"; }\n\n.ion-android-archive:before {\n  content: \"\"; }\n\n.ion-android-arrow-back:before {\n  content: \"\"; }\n\n.ion-android-arrow-down:before {\n  content: \"\"; }\n\n.ion-android-arrow-dropdown:before {\n  content: \"\"; }\n\n.ion-android-arrow-dropdown-circle:before {\n  content: \"\"; }\n\n.ion-android-arrow-dropleft:before {\n  content: \"\"; }\n\n.ion-android-arrow-dropleft-circle:before {\n  content: \"\"; }\n\n.ion-android-arrow-dropright:before {\n  content: \"\"; }\n\n.ion-android-arrow-dropright-circle:before {\n  content: \"\"; }\n\n.ion-android-arrow-dropup:before {\n  content: \"\"; }\n\n.ion-android-arrow-dropup-circle:before {\n  content: \"\"; }\n\n.ion-android-arrow-forward:before {\n  content: \"\"; }\n\n.ion-android-arrow-up:before {\n  content: \"\"; }\n\n.ion-android-attach:before {\n  content: \"\"; }\n\n.ion-android-bar:before {\n  content: \"\"; }\n\n.ion-android-bicycle:before {\n  content: \"\"; }\n\n.ion-android-boat:before {\n  content: \"\"; }\n\n.ion-android-bookmark:before {\n  content: \"\"; }\n\n.ion-android-bulb:before {\n  content: \"\"; }\n\n.ion-android-bus:before {\n  content: \"\"; }\n\n.ion-android-calendar:before {\n  content: \"\"; }\n\n.ion-android-call:before {\n  content: \"\"; }\n\n.ion-android-camera:before {\n  content: \"\"; }\n\n.ion-android-cancel:before {\n  content: \"\"; }\n\n.ion-android-car:before {\n  content: \"\"; }\n\n.ion-android-cart:before {\n  content: \"\"; }\n\n.ion-android-chat:before {\n  content: \"\"; }\n\n.ion-android-checkbox:before {\n  content: \"\"; }\n\n.ion-android-checkbox-blank:before {\n  content: \"\"; }\n\n.ion-android-checkbox-outline:before {\n  content: \"\"; }\n\n.ion-android-checkbox-outline-blank:before {\n  content: \"\"; }\n\n.ion-android-checkmark-circle:before {\n  content: \"\"; }\n\n.ion-android-clipboard:before {\n  content: \"\"; }\n\n.ion-android-close:before {\n  content: \"\"; }\n\n.ion-android-cloud:before {\n  content: \"\"; }\n\n.ion-android-cloud-circle:before {\n  content: \"\"; }\n\n.ion-android-cloud-done:before {\n  content: \"\"; }\n\n.ion-android-cloud-outline:before {\n  content: \"\"; }\n\n.ion-android-color-palette:before {\n  content: \"\"; }\n\n.ion-android-compass:before {\n  content: \"\"; }\n\n.ion-android-contact:before {\n  content: \"\"; }\n\n.ion-android-contacts:before {\n  content: \"\"; }\n\n.ion-android-contract:before {\n  content: \"\"; }\n\n.ion-android-create:before {\n  content: \"\"; }\n\n.ion-android-delete:before {\n  content: \"\"; }\n\n.ion-android-desktop:before {\n  content: \"\"; }\n\n.ion-android-document:before {\n  content: \"\"; }\n\n.ion-android-done:before {\n  content: \"\"; }\n\n.ion-android-done-all:before {\n  content: \"\"; }\n\n.ion-android-download:before {\n  content: \"\"; }\n\n.ion-android-drafts:before {\n  content: \"\"; }\n\n.ion-android-exit:before {\n  content: \"\"; }\n\n.ion-android-expand:before {\n  content: \"\"; }\n\n.ion-android-favorite:before {\n  content: \"\"; }\n\n.ion-android-favorite-outline:before {\n  content: \"\"; }\n\n.ion-android-film:before {\n  content: \"\"; }\n\n.ion-android-folder:before {\n  content: \"\"; }\n\n.ion-android-folder-open:before {\n  content: \"\"; }\n\n.ion-android-funnel:before {\n  content: \"\"; }\n\n.ion-android-globe:before {\n  content: \"\"; }\n\n.ion-android-hand:before {\n  content: \"\"; }\n\n.ion-android-hangout:before {\n  content: \"\"; }\n\n.ion-android-happy:before {\n  content: \"\"; }\n\n.ion-android-home:before {\n  content: \"\"; }\n\n.ion-android-image:before {\n  content: \"\"; }\n\n.ion-android-laptop:before {\n  content: \"\"; }\n\n.ion-android-list:before {\n  content: \"\"; }\n\n.ion-android-locate:before, .platform-android .tatami-location:before {\n  content: \"\"; }\n\n.ion-android-lock:before {\n  content: \"\"; }\n\n.ion-android-mail:before {\n  content: \"\"; }\n\n.ion-android-map:before {\n  content: \"\"; }\n\n.ion-android-menu:before {\n  content: \"\"; }\n\n.ion-android-microphone:before {\n  content: \"\"; }\n\n.ion-android-microphone-off:before {\n  content: \"\"; }\n\n.ion-android-more-horizontal:before {\n  content: \"\"; }\n\n.ion-android-more-vertical:before {\n  content: \"\"; }\n\n.ion-android-navigate:before {\n  content: \"\"; }\n\n.ion-android-notifications:before {\n  content: \"\"; }\n\n.ion-android-notifications-none:before {\n  content: \"\"; }\n\n.ion-android-notifications-off:before {\n  content: \"\"; }\n\n.ion-android-open:before {\n  content: \"\"; }\n\n.ion-android-options:before {\n  content: \"\"; }\n\n.ion-android-people:before {\n  content: \"\"; }\n\n.ion-android-person:before {\n  content: \"\"; }\n\n.ion-android-person-add:before {\n  content: \"\"; }\n\n.ion-android-phone-landscape:before {\n  content: \"\"; }\n\n.ion-android-phone-portrait:before {\n  content: \"\"; }\n\n.ion-android-pin:before {\n  content: \"\"; }\n\n.ion-android-plane:before {\n  content: \"\"; }\n\n.ion-android-playstore:before {\n  content: \"\"; }\n\n.ion-android-print:before {\n  content: \"\"; }\n\n.ion-android-radio-button-off:before {\n  content: \"\"; }\n\n.ion-android-radio-button-on:before {\n  content: \"\"; }\n\n.ion-android-refresh:before {\n  content: \"\"; }\n\n.ion-android-remove:before {\n  content: \"\"; }\n\n.ion-android-remove-circle:before {\n  content: \"\"; }\n\n.ion-android-restaurant:before {\n  content: \"\"; }\n\n.ion-android-sad:before {\n  content: \"\"; }\n\n.ion-android-search:before {\n  content: \"\"; }\n\n.ion-android-send:before {\n  content: \"\"; }\n\n.ion-android-settings:before {\n  content: \"\"; }\n\n.ion-android-share:before {\n  content: \"\"; }\n\n.ion-android-share-alt:before {\n  content: \"\"; }\n\n.ion-android-star:before {\n  content: \"\"; }\n\n.ion-android-star-half:before {\n  content: \"\"; }\n\n.ion-android-star-outline:before {\n  content: \"\"; }\n\n.ion-android-stopwatch:before {\n  content: \"\"; }\n\n.ion-android-subway:before {\n  content: \"\"; }\n\n.ion-android-sunny:before {\n  content: \"\"; }\n\n.ion-android-sync:before {\n  content: \"\"; }\n\n.ion-android-textsms:before {\n  content: \"\"; }\n\n.ion-android-time:before {\n  content: \"\"; }\n\n.ion-android-train:before {\n  content: \"\"; }\n\n.ion-android-unlock:before {\n  content: \"\"; }\n\n.ion-android-upload:before {\n  content: \"\"; }\n\n.ion-android-volume-down:before {\n  content: \"\"; }\n\n.ion-android-volume-mute:before {\n  content: \"\"; }\n\n.ion-android-volume-off:before {\n  content: \"\"; }\n\n.ion-android-volume-up:before {\n  content: \"\"; }\n\n.ion-android-walk:before {\n  content: \"\"; }\n\n.ion-android-warning:before {\n  content: \"\"; }\n\n.ion-android-watch:before {\n  content: \"\"; }\n\n.ion-android-wifi:before {\n  content: \"\"; }\n\n.ion-aperture:before {\n  content: \"\"; }\n\n.ion-archive:before {\n  content: \"\"; }\n\n.ion-arrow-down-a:before {\n  content: \"\"; }\n\n.ion-arrow-down-b:before {\n  content: \"\"; }\n\n.ion-arrow-down-c:before {\n  content: \"\"; }\n\n.ion-arrow-expand:before {\n  content: \"\"; }\n\n.ion-arrow-graph-down-left:before {\n  content: \"\"; }\n\n.ion-arrow-graph-down-right:before {\n  content: \"\"; }\n\n.ion-arrow-graph-up-left:before {\n  content: \"\"; }\n\n.ion-arrow-graph-up-right:before {\n  content: \"\"; }\n\n.ion-arrow-left-a:before {\n  content: \"\"; }\n\n.ion-arrow-left-b:before {\n  content: \"\"; }\n\n.ion-arrow-left-c:before {\n  content: \"\"; }\n\n.ion-arrow-move:before {\n  content: \"\"; }\n\n.ion-arrow-resize:before {\n  content: \"\"; }\n\n.ion-arrow-return-left:before {\n  content: \"\"; }\n\n.ion-arrow-return-right:before {\n  content: \"\"; }\n\n.ion-arrow-right-a:before {\n  content: \"\"; }\n\n.ion-arrow-right-b:before {\n  content: \"\"; }\n\n.ion-arrow-right-c:before {\n  content: \"\"; }\n\n.ion-arrow-shrink:before {\n  content: \"\"; }\n\n.ion-arrow-swap:before {\n  content: \"\"; }\n\n.ion-arrow-up-a:before {\n  content: \"\"; }\n\n.ion-arrow-up-b:before {\n  content: \"\"; }\n\n.ion-arrow-up-c:before {\n  content: \"\"; }\n\n.ion-asterisk:before {\n  content: \"\"; }\n\n.ion-at:before {\n  content: \"\"; }\n\n.ion-backspace:before {\n  content: \"\"; }\n\n.ion-backspace-outline:before {\n  content: \"\"; }\n\n.ion-bag:before {\n  content: \"\"; }\n\n.ion-battery-charging:before {\n  content: \"\"; }\n\n.ion-battery-empty:before {\n  content: \"\"; }\n\n.ion-battery-full:before {\n  content: \"\"; }\n\n.ion-battery-half:before {\n  content: \"\"; }\n\n.ion-battery-low:before {\n  content: \"\"; }\n\n.ion-beaker:before {\n  content: \"\"; }\n\n.ion-beer:before {\n  content: \"\"; }\n\n.ion-bluetooth:before {\n  content: \"\"; }\n\n.ion-bonfire:before {\n  content: \"\"; }\n\n.ion-bookmark:before {\n  content: \"\"; }\n\n.ion-bowtie:before {\n  content: \"\"; }\n\n.ion-briefcase:before {\n  content: \"\"; }\n\n.ion-bug:before {\n  content: \"\"; }\n\n.ion-calculator:before {\n  content: \"\"; }\n\n.ion-calendar:before {\n  content: \"\"; }\n\n.ion-camera:before {\n  content: \"\"; }\n\n.ion-card:before {\n  content: \"\"; }\n\n.ion-cash:before {\n  content: \"\"; }\n\n.ion-chatbox:before {\n  content: \"\"; }\n\n.ion-chatbox-working:before {\n  content: \"\"; }\n\n.ion-chatboxes:before {\n  content: \"\"; }\n\n.ion-chatbubble:before {\n  content: \"\"; }\n\n.ion-chatbubble-working:before {\n  content: \"\"; }\n\n.ion-chatbubbles:before {\n  content: \"\"; }\n\n.ion-checkmark:before {\n  content: \"\"; }\n\n.ion-checkmark-circled:before {\n  content: \"\"; }\n\n.ion-checkmark-round:before {\n  content: \"\"; }\n\n.ion-chevron-down:before {\n  content: \"\"; }\n\n.ion-chevron-left:before {\n  content: \"\"; }\n\n.ion-chevron-right:before {\n  content: \"\"; }\n\n.ion-chevron-up:before {\n  content: \"\"; }\n\n.ion-clipboard:before {\n  content: \"\"; }\n\n.ion-clock:before {\n  content: \"\"; }\n\n.ion-close:before {\n  content: \"\"; }\n\n.ion-close-circled:before {\n  content: \"\"; }\n\n.ion-close-round:before {\n  content: \"\"; }\n\n.ion-closed-captioning:before {\n  content: \"\"; }\n\n.ion-cloud:before {\n  content: \"\"; }\n\n.ion-code:before {\n  content: \"\"; }\n\n.ion-code-download:before {\n  content: \"\"; }\n\n.ion-code-working:before {\n  content: \"\"; }\n\n.ion-coffee:before {\n  content: \"\"; }\n\n.ion-compass:before {\n  content: \"\"; }\n\n.ion-compose:before {\n  content: \"\"; }\n\n.ion-connection-bars:before {\n  content: \"\"; }\n\n.ion-contrast:before {\n  content: \"\"; }\n\n.ion-crop:before {\n  content: \"\"; }\n\n.ion-cube:before {\n  content: \"\"; }\n\n.ion-disc:before {\n  content: \"\"; }\n\n.ion-document:before {\n  content: \"\"; }\n\n.ion-document-text:before {\n  content: \"\"; }\n\n.ion-drag:before {\n  content: \"\"; }\n\n.ion-earth:before {\n  content: \"\"; }\n\n.ion-easel:before {\n  content: \"\"; }\n\n.ion-edit:before {\n  content: \"\"; }\n\n.ion-egg:before {\n  content: \"\"; }\n\n.ion-eject:before {\n  content: \"\"; }\n\n.ion-email:before {\n  content: \"\"; }\n\n.ion-email-unread:before {\n  content: \"\"; }\n\n.ion-erlenmeyer-flask:before {\n  content: \"\"; }\n\n.ion-erlenmeyer-flask-bubbles:before {\n  content: \"\"; }\n\n.ion-eye:before {\n  content: \"\"; }\n\n.ion-eye-disabled:before {\n  content: \"\"; }\n\n.ion-female:before {\n  content: \"\"; }\n\n.ion-filing:before {\n  content: \"\"; }\n\n.ion-film-marker:before {\n  content: \"\"; }\n\n.ion-fireball:before {\n  content: \"\"; }\n\n.ion-flag:before {\n  content: \"\"; }\n\n.ion-flame:before {\n  content: \"\"; }\n\n.ion-flash:before {\n  content: \"\"; }\n\n.ion-flash-off:before {\n  content: \"\"; }\n\n.ion-folder:before {\n  content: \"\"; }\n\n.ion-fork:before {\n  content: \"\"; }\n\n.ion-fork-repo:before {\n  content: \"\"; }\n\n.ion-forward:before {\n  content: \"\"; }\n\n.ion-funnel:before {\n  content: \"\"; }\n\n.ion-gear-a:before {\n  content: \"\"; }\n\n.ion-gear-b:before {\n  content: \"\"; }\n\n.ion-grid:before {\n  content: \"\"; }\n\n.ion-hammer:before {\n  content: \"\"; }\n\n.ion-happy:before {\n  content: \"\"; }\n\n.ion-happy-outline:before {\n  content: \"\"; }\n\n.ion-headphone:before {\n  content: \"\"; }\n\n.ion-heart:before {\n  content: \"\"; }\n\n.ion-heart-broken:before {\n  content: \"\"; }\n\n.ion-help:before {\n  content: \"\"; }\n\n.ion-help-buoy:before {\n  content: \"\"; }\n\n.ion-help-circled:before {\n  content: \"\"; }\n\n.ion-home:before {\n  content: \"\"; }\n\n.ion-icecream:before {\n  content: \"\"; }\n\n.ion-image:before {\n  content: \"\"; }\n\n.ion-images:before {\n  content: \"\"; }\n\n.ion-information:before {\n  content: \"\"; }\n\n.ion-information-circled:before {\n  content: \"\"; }\n\n.ion-ionic:before {\n  content: \"\"; }\n\n.ion-ios-alarm:before {\n  content: \"\"; }\n\n.ion-ios-alarm-outline:before {\n  content: \"\"; }\n\n.ion-ios-albums:before {\n  content: \"\"; }\n\n.ion-ios-albums-outline:before {\n  content: \"\"; }\n\n.ion-ios-americanfootball:before {\n  content: \"\"; }\n\n.ion-ios-americanfootball-outline:before {\n  content: \"\"; }\n\n.ion-ios-analytics:before {\n  content: \"\"; }\n\n.ion-ios-analytics-outline:before {\n  content: \"\"; }\n\n.ion-ios-arrow-back:before {\n  content: \"\"; }\n\n.ion-ios-arrow-down:before {\n  content: \"\"; }\n\n.ion-ios-arrow-forward:before {\n  content: \"\"; }\n\n.ion-ios-arrow-left:before {\n  content: \"\"; }\n\n.ion-ios-arrow-right:before {\n  content: \"\"; }\n\n.ion-ios-arrow-thin-down:before {\n  content: \"\"; }\n\n.ion-ios-arrow-thin-left:before {\n  content: \"\"; }\n\n.ion-ios-arrow-thin-right:before {\n  content: \"\"; }\n\n.ion-ios-arrow-thin-up:before {\n  content: \"\"; }\n\n.ion-ios-arrow-up:before {\n  content: \"\"; }\n\n.ion-ios-at:before {\n  content: \"\"; }\n\n.ion-ios-at-outline:before {\n  content: \"\"; }\n\n.ion-ios-barcode:before {\n  content: \"\"; }\n\n.ion-ios-barcode-outline:before {\n  content: \"\"; }\n\n.ion-ios-baseball:before {\n  content: \"\"; }\n\n.ion-ios-baseball-outline:before {\n  content: \"\"; }\n\n.ion-ios-basketball:before {\n  content: \"\"; }\n\n.ion-ios-basketball-outline:before {\n  content: \"\"; }\n\n.ion-ios-bell:before {\n  content: \"\"; }\n\n.ion-ios-bell-outline:before {\n  content: \"\"; }\n\n.ion-ios-body:before {\n  content: \"\"; }\n\n.ion-ios-body-outline:before {\n  content: \"\"; }\n\n.ion-ios-bolt:before {\n  content: \"\"; }\n\n.ion-ios-bolt-outline:before {\n  content: \"\"; }\n\n.ion-ios-book:before {\n  content: \"\"; }\n\n.ion-ios-book-outline:before {\n  content: \"\"; }\n\n.ion-ios-bookmarks:before {\n  content: \"\"; }\n\n.ion-ios-bookmarks-outline:before {\n  content: \"\"; }\n\n.ion-ios-box:before {\n  content: \"\"; }\n\n.ion-ios-box-outline:before {\n  content: \"\"; }\n\n.ion-ios-briefcase:before {\n  content: \"\"; }\n\n.ion-ios-briefcase-outline:before {\n  content: \"\"; }\n\n.ion-ios-browsers:before {\n  content: \"\"; }\n\n.ion-ios-browsers-outline:before {\n  content: \"\"; }\n\n.ion-ios-calculator:before {\n  content: \"\"; }\n\n.ion-ios-calculator-outline:before {\n  content: \"\"; }\n\n.ion-ios-calendar:before {\n  content: \"\"; }\n\n.ion-ios-calendar-outline:before {\n  content: \"\"; }\n\n.ion-ios-camera:before {\n  content: \"\"; }\n\n.ion-ios-camera-outline:before {\n  content: \"\"; }\n\n.ion-ios-cart:before {\n  content: \"\"; }\n\n.ion-ios-cart-outline:before {\n  content: \"\"; }\n\n.ion-ios-chatboxes:before {\n  content: \"\"; }\n\n.ion-ios-chatboxes-outline:before {\n  content: \"\"; }\n\n.ion-ios-chatbubble:before {\n  content: \"\"; }\n\n.ion-ios-chatbubble-outline:before {\n  content: \"\"; }\n\n.ion-ios-checkmark:before {\n  content: \"\"; }\n\n.ion-ios-checkmark-empty:before {\n  content: \"\"; }\n\n.ion-ios-checkmark-outline:before {\n  content: \"\"; }\n\n.ion-ios-circle-filled:before {\n  content: \"\"; }\n\n.ion-ios-circle-outline:before {\n  content: \"\"; }\n\n.ion-ios-clock:before {\n  content: \"\"; }\n\n.ion-ios-clock-outline:before {\n  content: \"\"; }\n\n.ion-ios-close:before {\n  content: \"\"; }\n\n.ion-ios-close-empty:before {\n  content: \"\"; }\n\n.ion-ios-close-outline:before {\n  content: \"\"; }\n\n.ion-ios-cloud:before {\n  content: \"\"; }\n\n.ion-ios-cloud-download:before {\n  content: \"\"; }\n\n.ion-ios-cloud-download-outline:before {\n  content: \"\"; }\n\n.ion-ios-cloud-outline:before {\n  content: \"\"; }\n\n.ion-ios-cloud-upload:before {\n  content: \"\"; }\n\n.ion-ios-cloud-upload-outline:before {\n  content: \"\"; }\n\n.ion-ios-cloudy:before {\n  content: \"\"; }\n\n.ion-ios-cloudy-night:before {\n  content: \"\"; }\n\n.ion-ios-cloudy-night-outline:before {\n  content: \"\"; }\n\n.ion-ios-cloudy-outline:before {\n  content: \"\"; }\n\n.ion-ios-cog:before {\n  content: \"\"; }\n\n.ion-ios-cog-outline:before {\n  content: \"\"; }\n\n.ion-ios-color-filter:before {\n  content: \"\"; }\n\n.ion-ios-color-filter-outline:before {\n  content: \"\"; }\n\n.ion-ios-color-wand:before {\n  content: \"\"; }\n\n.ion-ios-color-wand-outline:before {\n  content: \"\"; }\n\n.ion-ios-compose:before {\n  content: \"\"; }\n\n.ion-ios-compose-outline:before {\n  content: \"\"; }\n\n.ion-ios-contact:before {\n  content: \"\"; }\n\n.ion-ios-contact-outline:before {\n  content: \"\"; }\n\n.ion-ios-copy:before {\n  content: \"\"; }\n\n.ion-ios-copy-outline:before {\n  content: \"\"; }\n\n.ion-ios-crop:before {\n  content: \"\"; }\n\n.ion-ios-crop-strong:before {\n  content: \"\"; }\n\n.ion-ios-download:before {\n  content: \"\"; }\n\n.ion-ios-download-outline:before {\n  content: \"\"; }\n\n.ion-ios-drag:before {\n  content: \"\"; }\n\n.ion-ios-email:before {\n  content: \"\"; }\n\n.ion-ios-email-outline:before {\n  content: \"\"; }\n\n.ion-ios-eye:before {\n  content: \"\"; }\n\n.ion-ios-eye-outline:before {\n  content: \"\"; }\n\n.ion-ios-fastforward:before {\n  content: \"\"; }\n\n.ion-ios-fastforward-outline:before {\n  content: \"\"; }\n\n.ion-ios-filing:before {\n  content: \"\"; }\n\n.ion-ios-filing-outline:before {\n  content: \"\"; }\n\n.ion-ios-film:before {\n  content: \"\"; }\n\n.ion-ios-film-outline:before {\n  content: \"\"; }\n\n.ion-ios-flag:before {\n  content: \"\"; }\n\n.ion-ios-flag-outline:before {\n  content: \"\"; }\n\n.ion-ios-flame:before {\n  content: \"\"; }\n\n.ion-ios-flame-outline:before {\n  content: \"\"; }\n\n.ion-ios-flask:before {\n  content: \"\"; }\n\n.ion-ios-flask-outline:before {\n  content: \"\"; }\n\n.ion-ios-flower:before {\n  content: \"\"; }\n\n.ion-ios-flower-outline:before {\n  content: \"\"; }\n\n.ion-ios-folder:before {\n  content: \"\"; }\n\n.ion-ios-folder-outline:before {\n  content: \"\"; }\n\n.ion-ios-football:before {\n  content: \"\"; }\n\n.ion-ios-football-outline:before {\n  content: \"\"; }\n\n.ion-ios-game-controller-a:before {\n  content: \"\"; }\n\n.ion-ios-game-controller-a-outline:before {\n  content: \"\"; }\n\n.ion-ios-game-controller-b:before {\n  content: \"\"; }\n\n.ion-ios-game-controller-b-outline:before {\n  content: \"\"; }\n\n.ion-ios-gear:before {\n  content: \"\"; }\n\n.ion-ios-gear-outline:before {\n  content: \"\"; }\n\n.ion-ios-glasses:before {\n  content: \"\"; }\n\n.ion-ios-glasses-outline:before {\n  content: \"\"; }\n\n.ion-ios-grid-view:before {\n  content: \"\"; }\n\n.ion-ios-grid-view-outline:before {\n  content: \"\"; }\n\n.ion-ios-heart:before {\n  content: \"\"; }\n\n.ion-ios-heart-outline:before {\n  content: \"\"; }\n\n.ion-ios-help:before {\n  content: \"\"; }\n\n.ion-ios-help-empty:before {\n  content: \"\"; }\n\n.ion-ios-help-outline:before {\n  content: \"\"; }\n\n.ion-ios-home:before {\n  content: \"\"; }\n\n.ion-ios-home-outline:before {\n  content: \"\"; }\n\n.ion-ios-infinite:before {\n  content: \"\"; }\n\n.ion-ios-infinite-outline:before {\n  content: \"\"; }\n\n.ion-ios-information:before {\n  content: \"\"; }\n\n.ion-ios-information-empty:before {\n  content: \"\"; }\n\n.ion-ios-information-outline:before {\n  content: \"\"; }\n\n.ion-ios-ionic-outline:before {\n  content: \"\"; }\n\n.ion-ios-keypad:before {\n  content: \"\"; }\n\n.ion-ios-keypad-outline:before {\n  content: \"\"; }\n\n.ion-ios-lightbulb:before {\n  content: \"\"; }\n\n.ion-ios-lightbulb-outline:before {\n  content: \"\"; }\n\n.ion-ios-list:before {\n  content: \"\"; }\n\n.ion-ios-list-outline:before {\n  content: \"\"; }\n\n.ion-ios-location:before, .platform-ios .tatami-location:before {\n  content: \"\"; }\n\n.ion-ios-location-outline:before {\n  content: \"\"; }\n\n.ion-ios-locked:before {\n  content: \"\"; }\n\n.ion-ios-locked-outline:before {\n  content: \"\"; }\n\n.ion-ios-loop:before {\n  content: \"\"; }\n\n.ion-ios-loop-strong:before {\n  content: \"\"; }\n\n.ion-ios-medical:before {\n  content: \"\"; }\n\n.ion-ios-medical-outline:before {\n  content: \"\"; }\n\n.ion-ios-medkit:before {\n  content: \"\"; }\n\n.ion-ios-medkit-outline:before {\n  content: \"\"; }\n\n.ion-ios-mic:before {\n  content: \"\"; }\n\n.ion-ios-mic-off:before {\n  content: \"\"; }\n\n.ion-ios-mic-outline:before {\n  content: \"\"; }\n\n.ion-ios-minus:before {\n  content: \"\"; }\n\n.ion-ios-minus-empty:before {\n  content: \"\"; }\n\n.ion-ios-minus-outline:before {\n  content: \"\"; }\n\n.ion-ios-monitor:before {\n  content: \"\"; }\n\n.ion-ios-monitor-outline:before {\n  content: \"\"; }\n\n.ion-ios-moon:before {\n  content: \"\"; }\n\n.ion-ios-moon-outline:before {\n  content: \"\"; }\n\n.ion-ios-more:before {\n  content: \"\"; }\n\n.ion-ios-more-outline:before {\n  content: \"\"; }\n\n.ion-ios-musical-note:before {\n  content: \"\"; }\n\n.ion-ios-musical-notes:before {\n  content: \"\"; }\n\n.ion-ios-navigate:before {\n  content: \"\"; }\n\n.ion-ios-navigate-outline:before {\n  content: \"\"; }\n\n.ion-ios-nutrition:before {\n  content: \"\"; }\n\n.ion-ios-nutrition-outline:before {\n  content: \"\"; }\n\n.ion-ios-paper:before {\n  content: \"\"; }\n\n.ion-ios-paper-outline:before {\n  content: \"\"; }\n\n.ion-ios-paperplane:before {\n  content: \"\"; }\n\n.ion-ios-paperplane-outline:before {\n  content: \"\"; }\n\n.ion-ios-partlysunny:before {\n  content: \"\"; }\n\n.ion-ios-partlysunny-outline:before {\n  content: \"\"; }\n\n.ion-ios-pause:before {\n  content: \"\"; }\n\n.ion-ios-pause-outline:before {\n  content: \"\"; }\n\n.ion-ios-paw:before {\n  content: \"\"; }\n\n.ion-ios-paw-outline:before {\n  content: \"\"; }\n\n.ion-ios-people:before {\n  content: \"\"; }\n\n.ion-ios-people-outline:before {\n  content: \"\"; }\n\n.ion-ios-person:before {\n  content: \"\"; }\n\n.ion-ios-person-outline:before {\n  content: \"\"; }\n\n.ion-ios-personadd:before {\n  content: \"\"; }\n\n.ion-ios-personadd-outline:before {\n  content: \"\"; }\n\n.ion-ios-photos:before {\n  content: \"\"; }\n\n.ion-ios-photos-outline:before {\n  content: \"\"; }\n\n.ion-ios-pie:before {\n  content: \"\"; }\n\n.ion-ios-pie-outline:before {\n  content: \"\"; }\n\n.ion-ios-pint:before {\n  content: \"\"; }\n\n.ion-ios-pint-outline:before {\n  content: \"\"; }\n\n.ion-ios-play:before {\n  content: \"\"; }\n\n.ion-ios-play-outline:before {\n  content: \"\"; }\n\n.ion-ios-plus:before {\n  content: \"\"; }\n\n.ion-ios-plus-empty:before {\n  content: \"\"; }\n\n.ion-ios-plus-outline:before {\n  content: \"\"; }\n\n.ion-ios-pricetag:before {\n  content: \"\"; }\n\n.ion-ios-pricetag-outline:before {\n  content: \"\"; }\n\n.ion-ios-pricetags:before {\n  content: \"\"; }\n\n.ion-ios-pricetags-outline:before {\n  content: \"\"; }\n\n.ion-ios-printer:before {\n  content: \"\"; }\n\n.ion-ios-printer-outline:before {\n  content: \"\"; }\n\n.ion-ios-pulse:before {\n  content: \"\"; }\n\n.ion-ios-pulse-strong:before {\n  content: \"\"; }\n\n.ion-ios-rainy:before {\n  content: \"\"; }\n\n.ion-ios-rainy-outline:before {\n  content: \"\"; }\n\n.ion-ios-recording:before {\n  content: \"\"; }\n\n.ion-ios-recording-outline:before {\n  content: \"\"; }\n\n.ion-ios-redo:before {\n  content: \"\"; }\n\n.ion-ios-redo-outline:before {\n  content: \"\"; }\n\n.ion-ios-refresh:before {\n  content: \"\"; }\n\n.ion-ios-refresh-empty:before {\n  content: \"\"; }\n\n.ion-ios-refresh-outline:before {\n  content: \"\"; }\n\n.ion-ios-reload:before {\n  content: \"\"; }\n\n.ion-ios-reverse-camera:before {\n  content: \"\"; }\n\n.ion-ios-reverse-camera-outline:before {\n  content: \"\"; }\n\n.ion-ios-rewind:before {\n  content: \"\"; }\n\n.ion-ios-rewind-outline:before {\n  content: \"\"; }\n\n.ion-ios-rose:before {\n  content: \"\"; }\n\n.ion-ios-rose-outline:before {\n  content: \"\"; }\n\n.ion-ios-search:before {\n  content: \"\"; }\n\n.ion-ios-search-strong:before {\n  content: \"\"; }\n\n.ion-ios-settings:before {\n  content: \"\"; }\n\n.ion-ios-settings-strong:before {\n  content: \"\"; }\n\n.ion-ios-shuffle:before {\n  content: \"\"; }\n\n.ion-ios-shuffle-strong:before {\n  content: \"\"; }\n\n.ion-ios-skipbackward:before {\n  content: \"\"; }\n\n.ion-ios-skipbackward-outline:before {\n  content: \"\"; }\n\n.ion-ios-skipforward:before {\n  content: \"\"; }\n\n.ion-ios-skipforward-outline:before {\n  content: \"\"; }\n\n.ion-ios-snowy:before {\n  content: \"\"; }\n\n.ion-ios-speedometer:before {\n  content: \"\"; }\n\n.ion-ios-speedometer-outline:before {\n  content: \"\"; }\n\n.ion-ios-star:before {\n  content: \"\"; }\n\n.ion-ios-star-half:before {\n  content: \"\"; }\n\n.ion-ios-star-outline:before {\n  content: \"\"; }\n\n.ion-ios-stopwatch:before {\n  content: \"\"; }\n\n.ion-ios-stopwatch-outline:before {\n  content: \"\"; }\n\n.ion-ios-sunny:before {\n  content: \"\"; }\n\n.ion-ios-sunny-outline:before {\n  content: \"\"; }\n\n.ion-ios-telephone:before {\n  content: \"\"; }\n\n.ion-ios-telephone-outline:before {\n  content: \"\"; }\n\n.ion-ios-tennisball:before {\n  content: \"\"; }\n\n.ion-ios-tennisball-outline:before {\n  content: \"\"; }\n\n.ion-ios-thunderstorm:before {\n  content: \"\"; }\n\n.ion-ios-thunderstorm-outline:before {\n  content: \"\"; }\n\n.ion-ios-time:before {\n  content: \"\"; }\n\n.ion-ios-time-outline:before {\n  content: \"\"; }\n\n.ion-ios-timer:before {\n  content: \"\"; }\n\n.ion-ios-timer-outline:before {\n  content: \"\"; }\n\n.ion-ios-toggle:before {\n  content: \"\"; }\n\n.ion-ios-toggle-outline:before {\n  content: \"\"; }\n\n.ion-ios-trash:before {\n  content: \"\"; }\n\n.ion-ios-trash-outline:before {\n  content: \"\"; }\n\n.ion-ios-undo:before {\n  content: \"\"; }\n\n.ion-ios-undo-outline:before {\n  content: \"\"; }\n\n.ion-ios-unlocked:before {\n  content: \"\"; }\n\n.ion-ios-unlocked-outline:before {\n  content: \"\"; }\n\n.ion-ios-upload:before {\n  content: \"\"; }\n\n.ion-ios-upload-outline:before {\n  content: \"\"; }\n\n.ion-ios-videocam:before {\n  content: \"\"; }\n\n.ion-ios-videocam-outline:before {\n  content: \"\"; }\n\n.ion-ios-volume-high:before {\n  content: \"\"; }\n\n.ion-ios-volume-low:before {\n  content: \"\"; }\n\n.ion-ios-wineglass:before {\n  content: \"\"; }\n\n.ion-ios-wineglass-outline:before {\n  content: \"\"; }\n\n.ion-ios-world:before {\n  content: \"\"; }\n\n.ion-ios-world-outline:before {\n  content: \"\"; }\n\n.ion-ipad:before {\n  content: \"\"; }\n\n.ion-iphone:before {\n  content: \"\"; }\n\n.ion-ipod:before {\n  content: \"\"; }\n\n.ion-jet:before {\n  content: \"\"; }\n\n.ion-key:before {\n  content: \"\"; }\n\n.ion-knife:before {\n  content: \"\"; }\n\n.ion-laptop:before {\n  content: \"\"; }\n\n.ion-leaf:before {\n  content: \"\"; }\n\n.ion-levels:before {\n  content: \"\"; }\n\n.ion-lightbulb:before {\n  content: \"\"; }\n\n.ion-link:before {\n  content: \"\"; }\n\n.ion-load-a:before {\n  content: \"\"; }\n\n.ion-load-b:before {\n  content: \"\"; }\n\n.ion-load-c:before {\n  content: \"\"; }\n\n.ion-load-d:before {\n  content: \"\"; }\n\n.ion-location:before {\n  content: \"\"; }\n\n.ion-lock-combination:before {\n  content: \"\"; }\n\n.ion-locked:before {\n  content: \"\"; }\n\n.ion-log-in:before {\n  content: \"\"; }\n\n.ion-log-out:before {\n  content: \"\"; }\n\n.ion-loop:before {\n  content: \"\"; }\n\n.ion-magnet:before {\n  content: \"\"; }\n\n.ion-male:before {\n  content: \"\"; }\n\n.ion-man:before {\n  content: \"\"; }\n\n.ion-map:before {\n  content: \"\"; }\n\n.ion-medkit:before {\n  content: \"\"; }\n\n.ion-merge:before {\n  content: \"\"; }\n\n.ion-mic-a:before {\n  content: \"\"; }\n\n.ion-mic-b:before {\n  content: \"\"; }\n\n.ion-mic-c:before {\n  content: \"\"; }\n\n.ion-minus:before {\n  content: \"\"; }\n\n.ion-minus-circled:before {\n  content: \"\"; }\n\n.ion-minus-round:before {\n  content: \"\"; }\n\n.ion-model-s:before {\n  content: \"\"; }\n\n.ion-monitor:before {\n  content: \"\"; }\n\n.ion-more:before {\n  content: \"\"; }\n\n.ion-mouse:before {\n  content: \"\"; }\n\n.ion-music-note:before {\n  content: \"\"; }\n\n.ion-navicon:before {\n  content: \"\"; }\n\n.ion-navicon-round:before {\n  content: \"\"; }\n\n.ion-navigate:before {\n  content: \"\"; }\n\n.ion-network:before {\n  content: \"\"; }\n\n.ion-no-smoking:before {\n  content: \"\"; }\n\n.ion-nuclear:before {\n  content: \"\"; }\n\n.ion-outlet:before {\n  content: \"\"; }\n\n.ion-paintbrush:before {\n  content: \"\"; }\n\n.ion-paintbucket:before {\n  content: \"\"; }\n\n.ion-paper-airplane:before {\n  content: \"\"; }\n\n.ion-paperclip:before {\n  content: \"\"; }\n\n.ion-pause:before {\n  content: \"\"; }\n\n.ion-person:before {\n  content: \"\"; }\n\n.ion-person-add:before {\n  content: \"\"; }\n\n.ion-person-stalker:before {\n  content: \"\"; }\n\n.ion-pie-graph:before {\n  content: \"\"; }\n\n.ion-pin:before {\n  content: \"\"; }\n\n.ion-pinpoint:before {\n  content: \"\"; }\n\n.ion-pizza:before {\n  content: \"\"; }\n\n.ion-plane:before {\n  content: \"\"; }\n\n.ion-planet:before {\n  content: \"\"; }\n\n.ion-play:before {\n  content: \"\"; }\n\n.ion-playstation:before {\n  content: \"\"; }\n\n.ion-plus:before {\n  content: \"\"; }\n\n.ion-plus-circled:before {\n  content: \"\"; }\n\n.ion-plus-round:before {\n  content: \"\"; }\n\n.ion-podium:before {\n  content: \"\"; }\n\n.ion-pound:before {\n  content: \"\"; }\n\n.ion-power:before {\n  content: \"\"; }\n\n.ion-pricetag:before {\n  content: \"\"; }\n\n.ion-pricetags:before {\n  content: \"\"; }\n\n.ion-printer:before {\n  content: \"\"; }\n\n.ion-pull-request:before {\n  content: \"\"; }\n\n.ion-qr-scanner:before {\n  content: \"\"; }\n\n.ion-quote:before {\n  content: \"\"; }\n\n.ion-radio-waves:before {\n  content: \"\"; }\n\n.ion-record:before {\n  content: \"\"; }\n\n.ion-refresh:before {\n  content: \"\"; }\n\n.ion-reply:before {\n  content: \"\"; }\n\n.ion-reply-all:before {\n  content: \"\"; }\n\n.ion-ribbon-a:before {\n  content: \"\"; }\n\n.ion-ribbon-b:before {\n  content: \"\"; }\n\n.ion-sad:before {\n  content: \"\"; }\n\n.ion-sad-outline:before {\n  content: \"\"; }\n\n.ion-scissors:before {\n  content: \"\"; }\n\n.ion-search:before {\n  content: \"\"; }\n\n.ion-settings:before {\n  content: \"\"; }\n\n.ion-share:before {\n  content: \"\"; }\n\n.ion-shuffle:before {\n  content: \"\"; }\n\n.ion-skip-backward:before {\n  content: \"\"; }\n\n.ion-skip-forward:before {\n  content: \"\"; }\n\n.ion-social-android:before {\n  content: \"\"; }\n\n.ion-social-android-outline:before {\n  content: \"\"; }\n\n.ion-social-angular:before {\n  content: \"\"; }\n\n.ion-social-angular-outline:before {\n  content: \"\"; }\n\n.ion-social-apple:before {\n  content: \"\"; }\n\n.ion-social-apple-outline:before {\n  content: \"\"; }\n\n.ion-social-bitcoin:before {\n  content: \"\"; }\n\n.ion-social-bitcoin-outline:before {\n  content: \"\"; }\n\n.ion-social-buffer:before {\n  content: \"\"; }\n\n.ion-social-buffer-outline:before {\n  content: \"\"; }\n\n.ion-social-chrome:before {\n  content: \"\"; }\n\n.ion-social-chrome-outline:before {\n  content: \"\"; }\n\n.ion-social-codepen:before {\n  content: \"\"; }\n\n.ion-social-codepen-outline:before {\n  content: \"\"; }\n\n.ion-social-css3:before {\n  content: \"\"; }\n\n.ion-social-css3-outline:before {\n  content: \"\"; }\n\n.ion-social-designernews:before {\n  content: \"\"; }\n\n.ion-social-designernews-outline:before {\n  content: \"\"; }\n\n.ion-social-dribbble:before {\n  content: \"\"; }\n\n.ion-social-dribbble-outline:before {\n  content: \"\"; }\n\n.ion-social-dropbox:before {\n  content: \"\"; }\n\n.ion-social-dropbox-outline:before {\n  content: \"\"; }\n\n.ion-social-euro:before {\n  content: \"\"; }\n\n.ion-social-euro-outline:before {\n  content: \"\"; }\n\n.ion-social-facebook:before {\n  content: \"\"; }\n\n.ion-social-facebook-outline:before {\n  content: \"\"; }\n\n.ion-social-foursquare:before {\n  content: \"\"; }\n\n.ion-social-foursquare-outline:before {\n  content: \"\"; }\n\n.ion-social-freebsd-devil:before {\n  content: \"\"; }\n\n.ion-social-github:before {\n  content: \"\"; }\n\n.ion-social-github-outline:before {\n  content: \"\"; }\n\n.ion-social-google:before {\n  content: \"\"; }\n\n.ion-social-google-outline:before {\n  content: \"\"; }\n\n.ion-social-googleplus:before {\n  content: \"\"; }\n\n.ion-social-googleplus-outline:before {\n  content: \"\"; }\n\n.ion-social-hackernews:before {\n  content: \"\"; }\n\n.ion-social-hackernews-outline:before {\n  content: \"\"; }\n\n.ion-social-html5:before {\n  content: \"\"; }\n\n.ion-social-html5-outline:before {\n  content: \"\"; }\n\n.ion-social-instagram:before {\n  content: \"\"; }\n\n.ion-social-instagram-outline:before {\n  content: \"\"; }\n\n.ion-social-javascript:before {\n  content: \"\"; }\n\n.ion-social-javascript-outline:before {\n  content: \"\"; }\n\n.ion-social-linkedin:before {\n  content: \"\"; }\n\n.ion-social-linkedin-outline:before {\n  content: \"\"; }\n\n.ion-social-markdown:before {\n  content: \"\"; }\n\n.ion-social-nodejs:before {\n  content: \"\"; }\n\n.ion-social-octocat:before {\n  content: \"\"; }\n\n.ion-social-pinterest:before {\n  content: \"\"; }\n\n.ion-social-pinterest-outline:before {\n  content: \"\"; }\n\n.ion-social-python:before {\n  content: \"\"; }\n\n.ion-social-reddit:before {\n  content: \"\"; }\n\n.ion-social-reddit-outline:before {\n  content: \"\"; }\n\n.ion-social-rss:before {\n  content: \"\"; }\n\n.ion-social-rss-outline:before {\n  content: \"\"; }\n\n.ion-social-sass:before {\n  content: \"\"; }\n\n.ion-social-skype:before {\n  content: \"\"; }\n\n.ion-social-skype-outline:before {\n  content: \"\"; }\n\n.ion-social-snapchat:before {\n  content: \"\"; }\n\n.ion-social-snapchat-outline:before {\n  content: \"\"; }\n\n.ion-social-tumblr:before {\n  content: \"\"; }\n\n.ion-social-tumblr-outline:before {\n  content: \"\"; }\n\n.ion-social-tux:before {\n  content: \"\"; }\n\n.ion-social-twitch:before {\n  content: \"\"; }\n\n.ion-social-twitch-outline:before {\n  content: \"\"; }\n\n.ion-social-twitter:before {\n  content: \"\"; }\n\n.ion-social-twitter-outline:before {\n  content: \"\"; }\n\n.ion-social-usd:before {\n  content: \"\"; }\n\n.ion-social-usd-outline:before {\n  content: \"\"; }\n\n.ion-social-vimeo:before {\n  content: \"\"; }\n\n.ion-social-vimeo-outline:before {\n  content: \"\"; }\n\n.ion-social-whatsapp:before {\n  content: \"\"; }\n\n.ion-social-whatsapp-outline:before {\n  content: \"\"; }\n\n.ion-social-windows:before {\n  content: \"\"; }\n\n.ion-social-windows-outline:before {\n  content: \"\"; }\n\n.ion-social-wordpress:before {\n  content: \"\"; }\n\n.ion-social-wordpress-outline:before {\n  content: \"\"; }\n\n.ion-social-yahoo:before {\n  content: \"\"; }\n\n.ion-social-yahoo-outline:before {\n  content: \"\"; }\n\n.ion-social-yen:before {\n  content: \"\"; }\n\n.ion-social-yen-outline:before {\n  content: \"\"; }\n\n.ion-social-youtube:before {\n  content: \"\"; }\n\n.ion-social-youtube-outline:before {\n  content: \"\"; }\n\n.ion-soup-can:before {\n  content: \"\"; }\n\n.ion-soup-can-outline:before {\n  content: \"\"; }\n\n.ion-speakerphone:before {\n  content: \"\"; }\n\n.ion-speedometer:before {\n  content: \"\"; }\n\n.ion-spoon:before {\n  content: \"\"; }\n\n.ion-star:before {\n  content: \"\"; }\n\n.ion-stats-bars:before {\n  content: \"\"; }\n\n.ion-steam:before {\n  content: \"\"; }\n\n.ion-stop:before {\n  content: \"\"; }\n\n.ion-thermometer:before {\n  content: \"\"; }\n\n.ion-thumbsdown:before {\n  content: \"\"; }\n\n.ion-thumbsup:before {\n  content: \"\"; }\n\n.ion-toggle:before {\n  content: \"\"; }\n\n.ion-toggle-filled:before {\n  content: \"\"; }\n\n.ion-transgender:before {\n  content: \"\"; }\n\n.ion-trash-a:before {\n  content: \"\"; }\n\n.ion-trash-b:before {\n  content: \"\"; }\n\n.ion-trophy:before {\n  content: \"\"; }\n\n.ion-tshirt:before {\n  content: \"\"; }\n\n.ion-tshirt-outline:before {\n  content: \"\"; }\n\n.ion-umbrella:before {\n  content: \"\"; }\n\n.ion-university:before {\n  content: \"\"; }\n\n.ion-unlocked:before {\n  content: \"\"; }\n\n.ion-upload:before {\n  content: \"\"; }\n\n.ion-usb:before {\n  content: \"\"; }\n\n.ion-videocamera:before {\n  content: \"\"; }\n\n.ion-volume-high:before {\n  content: \"\"; }\n\n.ion-volume-low:before {\n  content: \"\"; }\n\n.ion-volume-medium:before {\n  content: \"\"; }\n\n.ion-volume-mute:before {\n  content: \"\"; }\n\n.ion-wand:before {\n  content: \"\"; }\n\n.ion-waterdrop:before {\n  content: \"\"; }\n\n.ion-wifi:before {\n  content: \"\"; }\n\n.ion-wineglass:before {\n  content: \"\"; }\n\n.ion-woman:before {\n  content: \"\"; }\n\n.ion-wrench:before {\n  content: \"\"; }\n\n.ion-xbox:before {\n  content: \"\"; }\n\n/**\n * Resets\n * --------------------------------------------------\n * Adapted from normalize.css and some reset.css. We don't care even one\n * bit about old IE, so we don't need any hacks for that in here.\n *\n * There are probably other things we could remove here, as well.\n *\n * normalize.css v2.1.2 | MIT License | git.io/normalize\n\n * Eric Meyer's Reset CSS v2.0 (http://meyerweb.com/eric/tools/css/reset/)\n * http://cssreset.com\n */\nhtml, body, div, span, applet, object, iframe,\nh1, h2, h3, h4, h5, h6, p, blockquote, pre,\na, abbr, acronym, address, big, cite, code,\ndel, dfn, em, img, ins, kbd, q, s, samp,\nsmall, strike, strong, sub, sup, tt, var,\nb, i, u, center,\ndl, dt, dd, ol, ul, li,\nfieldset, form, label, legend,\ntable, caption, tbody, tfoot, thead, tr, th, td,\narticle, aside, canvas, details, embed, fieldset,\nfigure, figcaption, footer, header, hgroup,\nmenu, nav, output, ruby, section, summary,\ntime, mark, audio, video {\n  margin: 0;\n  padding: 0;\n  border: 0;\n  vertical-align: baseline;\n  font: inherit;\n  font-size: 100%; }\n\nol, ul {\n  list-style: none; }\n\nblockquote, q {\n  quotes: none; }\n\nblockquote:before, blockquote:after,\nq:before, q:after {\n  content: '';\n  content: none; }\n\n/**\n * Prevent modern browsers from displaying `audio` without controls.\n * Remove excess height in iOS 5 devices.\n */\naudio:not([controls]) {\n  display: none;\n  height: 0; }\n\n/**\n * Hide the `template` element in IE, Safari, and Firefox < 22.\n */\n[hidden],\ntemplate {\n  display: none; }\n\nscript {\n  display: none !important; }\n\n/* ==========================================================================\n   Base\n   ========================================================================== */\n/**\n * 1. Set default font family to sans-serif.\n * 2. Prevent iOS text size adjust after orientation change, without disabling\n *  user zoom.\n */\nhtml {\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n  font-family: sans-serif;\n  /* 1 */\n  -webkit-text-size-adjust: 100%;\n  -ms-text-size-adjust: 100%;\n  /* 2 */\n  -webkit-text-size-adjust: 100%;\n  /* 2 */ }\n\n/**\n * Remove default margin.\n */\nbody {\n  margin: 0;\n  line-height: 1; }\n\n/**\n * Remove default outlines.\n */\na,\nbutton,\n:focus,\na:focus,\nbutton:focus,\na:active,\na:hover {\n  outline: 0; }\n\n/* *\n * Remove tap highlight color\n */\na {\n  -webkit-user-drag: none;\n  -webkit-tap-highlight-color: transparent;\n  -webkit-tap-highlight-color: transparent; }\n\na[href]:hover {\n  cursor: pointer; }\n\n/* ==========================================================================\n   Typography\n   ========================================================================== */\n/**\n * Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.\n */\nb,\nstrong {\n  font-weight: bold; }\n\n/**\n * Address styling not present in Safari 5 and Chrome.\n */\ndfn {\n  font-style: italic; }\n\n/**\n * Address differences between Firefox and other browsers.\n */\nhr {\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n  height: 0; }\n\n/**\n * Correct font family set oddly in Safari 5 and Chrome.\n */\ncode,\nkbd,\npre,\nsamp {\n  font-size: 1em;\n  font-family: monospace, serif; }\n\n/**\n * Improve readability of pre-formatted text in all browsers.\n */\npre {\n  white-space: pre-wrap; }\n\n/**\n * Set consistent quote types.\n */\nq {\n  quotes: \"\\201C\" \"\\201D\" \"\\2018\" \"\\2019\"; }\n\n/**\n * Address inconsistent and variable font size in all browsers.\n */\nsmall {\n  font-size: 80%; }\n\n/**\n * Prevent `sub` and `sup` affecting `line-height` in all browsers.\n */\nsub,\nsup {\n  position: relative;\n  vertical-align: baseline;\n  font-size: 75%;\n  line-height: 0; }\n\nsup {\n  top: -0.5em; }\n\nsub {\n  bottom: -0.25em; }\n\n/**\n * Define consistent border, margin, and padding.\n */\nfieldset {\n  margin: 0 2px;\n  padding: 0.35em 0.625em 0.75em;\n  border: 1px solid #c0c0c0; }\n\n/**\n * 1. Correct `color` not being inherited in IE 8/9.\n * 2. Remove padding so people aren't caught out if they zero out fieldsets.\n */\nlegend {\n  padding: 0;\n  /* 2 */\n  border: 0;\n  /* 1 */ }\n\n/**\n * 1. Correct font family not being inherited in all browsers.\n * 2. Correct font size not being inherited in all browsers.\n * 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.\n * 4. Remove any default :focus styles\n * 5. Make sure webkit font smoothing is being inherited\n * 6. Remove default gradient in Android Firefox / FirefoxOS\n */\nbutton,\ninput,\nselect,\ntextarea {\n  margin: 0;\n  /* 3 */\n  font-size: 100%;\n  /* 2 */\n  font-family: inherit;\n  /* 1 */\n  outline-offset: 0;\n  /* 4 */\n  outline-style: none;\n  /* 4 */\n  outline-width: 0;\n  /* 4 */\n  -webkit-font-smoothing: inherit;\n  /* 5 */\n  background-image: none;\n  /* 6 */ }\n\n/**\n * Address Firefox 4+ setting `line-height` on `input` using `importnt` in\n * the UA stylesheet.\n */\nbutton,\ninput {\n  line-height: normal; }\n\n/**\n * Address inconsistent `text-transform` inheritance for `button` and `select`.\n * All other form control elements do not inherit `text-transform` values.\n * Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+.\n * Correct `select` style inheritance in Firefox 4+ and Opera.\n */\nbutton,\nselect {\n  text-transform: none; }\n\n/**\n * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n *  and `video` controls.\n * 2. Correct inability to style clickable `input` types in iOS.\n * 3. Improve usability and consistency of cursor style between image-type\n *  `input` and others.\n */\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  cursor: pointer;\n  /* 3 */\n  -webkit-appearance: button;\n  /* 2 */ }\n\n/**\n * Re-set default cursor for disabled elements.\n */\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default; }\n\n/**\n * 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.\n * 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome\n *  (include `-moz` to future-proof).\n */\ninput[type=\"search\"] {\n  -webkit-box-sizing: content-box;\n  /* 2 */\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n  -webkit-appearance: textfield;\n  /* 1 */ }\n\n/**\n * Remove inner padding and search cancel button in Safari 5 and Chrome\n * on OS X.\n */\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none; }\n\n/**\n * Remove inner padding and border in Firefox 4+.\n */\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  padding: 0;\n  border: 0; }\n\n/**\n * 1. Remove default vertical scrollbar in IE 8/9.\n * 2. Improve readability and alignment in all browsers.\n */\ntextarea {\n  overflow: auto;\n  /* 1 */\n  vertical-align: top;\n  /* 2 */ }\n\nimg {\n  -webkit-user-drag: none; }\n\n/* ==========================================================================\n   Tables\n   ========================================================================== */\n/**\n * Remove most spacing between table cells.\n */\ntable {\n  border-spacing: 0;\n  border-collapse: collapse; }\n\n/**\n * Scaffolding\n * --------------------------------------------------\n */\n*,\n*:before,\n*:after {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box; }\n\nhtml {\n  overflow: hidden;\n  -ms-touch-action: pan-y;\n  touch-action: pan-y; }\n\nbody,\n.ionic-body {\n  -webkit-touch-callout: none;\n  -webkit-font-smoothing: antialiased;\n  font-smoothing: antialiased;\n  -webkit-text-size-adjust: none;\n  -moz-text-size-adjust: none;\n  text-size-adjust: none;\n  -webkit-tap-highlight-color: transparent;\n  -webkit-tap-highlight-color: transparent;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  overflow: hidden;\n  margin: 0;\n  padding: 0;\n  color: #000;\n  word-wrap: break-word;\n  font-size: 14px;\n  font-family: -apple-system;\n  font-family: \"-apple-system\", \"Helvetica Neue\", \"Roboto\", \"Segoe UI\", sans-serif;\n  line-height: 20px;\n  text-rendering: optimizeLegibility;\n  -webkit-backface-visibility: hidden;\n  -webkit-user-drag: none;\n  -ms-content-zooming: none; }\n\nbody.grade-b,\nbody.grade-c {\n  text-rendering: auto; }\n\n.content {\n  position: relative; }\n\n.scroll-content {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  overflow: hidden;\n  margin-top: -1px;\n  padding-top: 1px;\n  margin-bottom: -1px;\n  width: auto;\n  height: auto; }\n\n.menu .scroll-content.scroll-content-false {\n  z-index: 11; }\n\n.scroll-view {\n  position: relative;\n  display: block;\n  overflow: hidden;\n  margin-top: -1px; }\n\n.scroll-view.overflow-scroll {\n  position: relative; }\n\n.scroll-view.scroll-x {\n  overflow-x: scroll;\n  overflow-y: hidden; }\n\n.scroll-view.scroll-y {\n  overflow-x: hidden;\n  overflow-y: scroll; }\n\n.scroll-view.scroll-xy {\n  overflow-x: scroll;\n  overflow-y: scroll; }\n\n/**\n * Scroll is the scroll view component available for complex and custom\n * scroll view functionality.\n */\n.scroll {\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n  -webkit-touch-callout: none;\n  -webkit-text-size-adjust: none;\n  -moz-text-size-adjust: none;\n  text-size-adjust: none;\n  -webkit-transform-origin: left top;\n  transform-origin: left top; }\n\n/**\n * Set ms-viewport to prevent MS \"page squish\" and allow fluid scrolling\n * https://msdn.microsoft.com/en-us/library/ie/hh869615(v=vs.85).aspx\n */\n@-ms-viewport {\n  width: device-width; }\n\n.scroll-bar {\n  position: absolute;\n  z-index: 9999; }\n\n.ng-animate .scroll-bar {\n  visibility: hidden; }\n\n.scroll-bar-h {\n  right: 2px;\n  bottom: 3px;\n  left: 2px;\n  height: 3px; }\n\n.scroll-bar-h .scroll-bar-indicator {\n  height: 100%; }\n\n.scroll-bar-v {\n  top: 2px;\n  right: 3px;\n  bottom: 2px;\n  width: 3px; }\n\n.scroll-bar-v .scroll-bar-indicator {\n  width: 100%; }\n\n.scroll-bar-indicator {\n  position: absolute;\n  border-radius: 4px;\n  background: rgba(0, 0, 0, 0.3);\n  opacity: 1;\n  -webkit-transition: opacity 0.3s linear;\n  transition: opacity 0.3s linear; }\n\n.scroll-bar-indicator.scroll-bar-fade-out {\n  opacity: 0; }\n\n.platform-android .scroll-bar-indicator {\n  border-radius: 0; }\n\n.grade-b .scroll-bar-indicator,\n.grade-c .scroll-bar-indicator {\n  background: #aaa; }\n\n.grade-b .scroll-bar-indicator.scroll-bar-fade-out,\n.grade-c .scroll-bar-indicator.scroll-bar-fade-out {\n  -webkit-transition: none;\n  transition: none; }\n\nion-infinite-scroll {\n  height: 60px;\n  width: 100%;\n  display: block;\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-direction: normal;\n  -webkit-box-orient: horizontal;\n  -webkit-flex-direction: row;\n  -moz-flex-direction: row;\n  -ms-flex-direction: row;\n  flex-direction: row;\n  -webkit-box-pack: center;\n  -ms-flex-pack: center;\n  -webkit-justify-content: center;\n  -moz-justify-content: center;\n  justify-content: center;\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  align-items: center; }\n\nion-infinite-scroll .icon {\n  color: #666666;\n  font-size: 30px;\n  color: #666666; }\n\nion-infinite-scroll:not(.active) .spinner,\nion-infinite-scroll:not(.active) .icon:before {\n  display: none; }\n\n.overflow-scroll {\n  overflow-x: hidden;\n  overflow-y: scroll;\n  -webkit-overflow-scrolling: touch;\n  -ms-overflow-style: -ms-autohiding-scrollbar;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  position: absolute; }\n\n.overflow-scroll.pane {\n  overflow-x: hidden;\n  overflow-y: scroll; }\n\n.overflow-scroll .scroll {\n  position: static;\n  height: 100%;\n  -webkit-transform: translate3d(0, 0, 0); }\n\n.overflow-scroll.keyboard-up:not(.keyboard-up-confirm) {\n  overflow: hidden; }\n\n/* If you change these, change platform.scss as well */\n.has-header {\n  top: 44px; }\n\n.no-header {\n  top: 0; }\n\n.has-subheader {\n  top: 88px; }\n\n.has-tabs-top {\n  top: 93px; }\n\n.has-header.has-subheader.has-tabs-top {\n  top: 137px; }\n\n.has-footer {\n  bottom: 44px; }\n\n.has-subfooter {\n  bottom: 88px; }\n\n.has-tabs,\n.bar-footer.has-tabs {\n  bottom: 49px; }\n\n.has-tabs.pane,\n.bar-footer.has-tabs.pane {\n  bottom: 49px;\n  height: auto; }\n\n.bar-subfooter.has-tabs {\n  bottom: 93px; }\n\n.has-footer.has-tabs {\n  bottom: 93px; }\n\n.pane {\n  -webkit-transform: translate3d(0, 0, 0);\n  transform: translate3d(0, 0, 0);\n  -webkit-transition-duration: 0;\n  transition-duration: 0;\n  z-index: 1; }\n\n.view {\n  z-index: 1; }\n\n.pane,\n.view {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  background-color: #fff;\n  overflow: hidden; }\n\n.view-container {\n  position: absolute;\n  display: block;\n  width: 100%;\n  height: 100%; }\n\n/**\n * Typography\n * --------------------------------------------------\n */\np {\n  margin: 0 0 10px; }\n\nsmall {\n  font-size: 85%; }\n\ncite {\n  font-style: normal; }\n\n.text-left {\n  text-align: left; }\n\n.text-right {\n  text-align: right; }\n\n.text-center {\n  text-align: center; }\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n  color: #000;\n  font-weight: 500;\n  font-family: \"-apple-system\", \"Helvetica Neue\", \"Roboto\", \"Segoe UI\", sans-serif;\n  line-height: 1.2; }\n\nh1 small, h2 small, h3 small, h4 small, h5 small, h6 small,\n.h1 small, .h2 small, .h3 small, .h4 small, .h5 small, .h6 small {\n  font-weight: normal;\n  line-height: 1; }\n\nh1, .h1,\nh2, .h2,\nh3, .h3 {\n  margin-top: 20px;\n  margin-bottom: 10px; }\n\nh1:first-child, .h1:first-child,\nh2:first-child, .h2:first-child,\nh3:first-child, .h3:first-child {\n  margin-top: 0; }\n\nh1 + h1, h1 + .h1,\nh1 + h2, h1 + .h2,\nh1 + h3, h1 + .h3, .h1 + h1, .h1 + .h1,\n.h1 + h2, .h1 + .h2,\n.h1 + h3, .h1 + .h3,\nh2 + h1,\nh2 + .h1,\nh2 + h2,\nh2 + .h2,\nh2 + h3,\nh2 + .h3, .h2 + h1, .h2 + .h1,\n.h2 + h2, .h2 + .h2,\n.h2 + h3, .h2 + .h3,\nh3 + h1,\nh3 + .h1,\nh3 + h2,\nh3 + .h2,\nh3 + h3,\nh3 + .h3, .h3 + h1, .h3 + .h1,\n.h3 + h2, .h3 + .h2,\n.h3 + h3, .h3 + .h3 {\n  margin-top: 10px; }\n\nh4, .h4,\nh5, .h5,\nh6, .h6 {\n  margin-top: 10px;\n  margin-bottom: 10px; }\n\nh1, .h1 {\n  font-size: 36px; }\n\nh2, .h2 {\n  font-size: 30px; }\n\nh3, .h3 {\n  font-size: 24px; }\n\nh4, .h4 {\n  font-size: 18px; }\n\nh5, .h5 {\n  font-size: 14px; }\n\nh6, .h6 {\n  font-size: 12px; }\n\nh1 small, .h1 small {\n  font-size: 24px; }\n\nh2 small, .h2 small {\n  font-size: 18px; }\n\nh3 small, .h3 small,\nh4 small, .h4 small {\n  font-size: 14px; }\n\ndl {\n  margin-bottom: 20px; }\n\ndt,\ndd {\n  line-height: 1.42857; }\n\ndt {\n  font-weight: bold; }\n\nblockquote {\n  margin: 0 0 20px;\n  padding: 10px 20px;\n  border-left: 5px solid gray; }\n\nblockquote p {\n  font-weight: 300;\n  font-size: 17.5px;\n  line-height: 1.25; }\n\nblockquote p:last-child {\n  margin-bottom: 0; }\n\nblockquote small {\n  display: block;\n  line-height: 1.42857; }\n\nblockquote small:before {\n  content: '\\2014 \\00A0'; }\n\nq:before,\nq:after,\nblockquote:before,\nblockquote:after {\n  content: \"\"; }\n\naddress {\n  display: block;\n  margin-bottom: 20px;\n  font-style: normal;\n  line-height: 1.42857; }\n\na {\n  color: #387ef5; }\n\na.subdued {\n  padding-right: 10px;\n  color: #888;\n  text-decoration: none; }\n\na.subdued:hover {\n  text-decoration: none; }\n\na.subdued:last-child {\n  padding-right: 0; }\n\n/**\n * Action Sheets\n * --------------------------------------------------\n */\n.action-sheet-backdrop {\n  -webkit-transition: background-color 150ms ease-in-out;\n  transition: background-color 150ms ease-in-out;\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: 11;\n  width: 100%;\n  height: 100%;\n  background-color: transparent; }\n\n.action-sheet-backdrop.active {\n  background-color: rgba(0, 0, 0, 0.4); }\n\n.action-sheet-wrapper {\n  -webkit-transform: translate3d(0, 100%, 0);\n  transform: translate3d(0, 100%, 0);\n  -webkit-transition: all cubic-bezier(0.36, 0.66, 0.04, 1) 500ms;\n  transition: all cubic-bezier(0.36, 0.66, 0.04, 1) 500ms;\n  position: absolute;\n  bottom: 0;\n  left: 0;\n  right: 0;\n  width: 100%;\n  max-width: 500px;\n  margin: auto; }\n\n.action-sheet-up {\n  -webkit-transform: translate3d(0, 0, 0);\n  transform: translate3d(0, 0, 0); }\n\n.action-sheet {\n  margin-left: 8px;\n  margin-right: 8px;\n  width: auto;\n  z-index: 11;\n  overflow: hidden; }\n\n.action-sheet .button {\n  display: block;\n  padding: 1px;\n  width: 100%;\n  border-radius: 0;\n  border-color: #d1d3d6;\n  background-color: transparent;\n  color: #007aff;\n  font-size: 21px; }\n\n.action-sheet .button:hover {\n  color: #007aff; }\n\n.action-sheet .button.destructive {\n  color: #ff3b30; }\n\n.action-sheet .button.destructive:hover {\n  color: #ff3b30; }\n\n.action-sheet .button.active, .action-sheet .button.activated {\n  box-shadow: none;\n  border-color: #d1d3d6;\n  color: #007aff;\n  background: #e4e5e7; }\n\n.action-sheet-has-icons .icon {\n  position: absolute;\n  left: 16px; }\n\n.action-sheet-title {\n  padding: 16px;\n  color: #8f8f8f;\n  text-align: center;\n  font-size: 13px; }\n\n.action-sheet-group {\n  margin-bottom: 8px;\n  border-radius: 4px;\n  background-color: #fff;\n  overflow: hidden; }\n\n.action-sheet-group .button {\n  border-width: 1px 0px 0px 0px; }\n\n.action-sheet-group .button:first-child:last-child {\n  border-width: 0; }\n\n.action-sheet-options {\n  background: #f1f2f3; }\n\n.action-sheet-cancel .button {\n  font-weight: 500; }\n\n.action-sheet-open {\n  pointer-events: none; }\n\n.action-sheet-open.modal-open .modal {\n  pointer-events: none; }\n\n.action-sheet-open .action-sheet-backdrop {\n  pointer-events: auto; }\n\n.platform-android .action-sheet-backdrop.active {\n  background-color: rgba(0, 0, 0, 0.2); }\n\n.platform-android .action-sheet {\n  margin: 0; }\n\n.platform-android .action-sheet .action-sheet-title,\n.platform-android .action-sheet .button {\n  text-align: left;\n  border-color: transparent;\n  font-size: 16px;\n  color: inherit; }\n\n.platform-android .action-sheet .action-sheet-title {\n  font-size: 14px;\n  padding: 16px;\n  color: #666; }\n\n.platform-android .action-sheet .button.active,\n.platform-android .action-sheet .button.activated {\n  background: #e8e8e8; }\n\n.platform-android .action-sheet-group {\n  margin: 0;\n  border-radius: 0;\n  background-color: #fafafa; }\n\n.platform-android .action-sheet-cancel {\n  display: none; }\n\n.platform-android .action-sheet-has-icons .button {\n  padding-left: 56px; }\n\n.backdrop {\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: 11;\n  width: 100%;\n  height: 100%;\n  background-color: rgba(0, 0, 0, 0.4);\n  visibility: hidden;\n  opacity: 0;\n  -webkit-transition: 0.1s opacity linear;\n  transition: 0.1s opacity linear; }\n\n.backdrop.visible {\n  visibility: visible; }\n\n.backdrop.active {\n  opacity: 1; }\n\n/**\n * Bar (Headers and Footers)\n * --------------------------------------------------\n */\n.bar {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-transform: translate3d(0, 0, 0);\n  transform: translate3d(0, 0, 0);\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n  position: absolute;\n  right: 0;\n  left: 0;\n  z-index: 9;\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n  padding: 5px;\n  width: 100%;\n  height: 44px;\n  border-width: 0;\n  border-style: solid;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid #ddd;\n  background-color: white;\n  /* border-width: 1px will actually create 2 device pixels on retina */\n  /* this nifty trick sets an actual 1px border on hi-res displays */\n  background-size: 0; }\n\n@media (min--moz-device-pixel-ratio: 1.5), (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5), (min-resolution: 144dpi), (min-resolution: 1.5dppx) {\n  .bar {\n    border: none;\n    background-image: linear-gradient(0deg, #ddd, #ddd 50%, transparent 50%);\n    background-position: bottom;\n    background-size: 100% 1px;\n    background-repeat: no-repeat; } }\n\n.bar.bar-clear {\n  border: none;\n  background: none;\n  color: #fff; }\n\n.bar.bar-clear .button {\n  color: #fff; }\n\n.bar.bar-clear .title {\n  color: #fff; }\n\n.bar.item-input-inset .item-input-wrapper {\n  margin-top: -1px; }\n\n.bar.item-input-inset .item-input-wrapper input {\n  padding-left: 8px;\n  width: 94%;\n  height: 28px;\n  background: transparent; }\n\n.bar.bar-light {\n  border-color: #ddd;\n  background-color: white;\n  background-image: linear-gradient(0deg, #ddd, #ddd 50%, transparent 50%);\n  color: #444; }\n\n.bar.bar-light .title {\n  color: #444; }\n\n.bar.bar-light.bar-footer {\n  background-image: linear-gradient(180deg, #ddd, #ddd 50%, transparent 50%); }\n\n.bar.bar-stable {\n  border-color: #b2b2b2;\n  background-color: #f8f8f8;\n  background-image: linear-gradient(0deg, #b2b2b2, #b2b2b2 50%, transparent 50%);\n  color: #444; }\n\n.bar.bar-stable .title {\n  color: #444; }\n\n.bar.bar-stable.bar-footer {\n  background-image: linear-gradient(180deg, #b2b2b2, #b2b2b2 50%, transparent 50%); }\n\n.bar.bar-positive {\n  border-color: #0c60ee;\n  background-color: #387ef5;\n  background-image: linear-gradient(0deg, #0c60ee, #0c60ee 50%, transparent 50%);\n  color: #fff; }\n\n.bar.bar-positive .title {\n  color: #fff; }\n\n.bar.bar-positive.bar-footer {\n  background-image: linear-gradient(180deg, #0c60ee, #0c60ee 50%, transparent 50%); }\n\n.bar.bar-calm {\n  border-color: #0a9dc7;\n  background-color: #11c1f3;\n  background-image: linear-gradient(0deg, #0a9dc7, #0a9dc7 50%, transparent 50%);\n  color: #fff; }\n\n.bar.bar-calm .title {\n  color: #fff; }\n\n.bar.bar-calm.bar-footer {\n  background-image: linear-gradient(180deg, #0a9dc7, #0a9dc7 50%, transparent 50%); }\n\n.bar.bar-assertive {\n  border-color: #e42112;\n  background-color: #ef473a;\n  background-image: linear-gradient(0deg, #e42112, #e42112 50%, transparent 50%);\n  color: #fff; }\n\n.bar.bar-assertive .title {\n  color: #fff; }\n\n.bar.bar-assertive.bar-footer {\n  background-image: linear-gradient(180deg, #e42112, #e42112 50%, transparent 50%); }\n\n.bar.bar-balanced {\n  border-color: #28a54c;\n  background-color: #33cd5f;\n  background-image: linear-gradient(0deg, #28a54c, #28a54c 50%, transparent 50%);\n  color: #fff; }\n\n.bar.bar-balanced .title {\n  color: #fff; }\n\n.bar.bar-balanced.bar-footer {\n  background-image: linear-gradient(180deg, #28a54c, #0c60ee 50%, transparent 50%); }\n\n.bar.bar-energized {\n  border-color: #e6b500;\n  background-color: #ffc900;\n  background-image: linear-gradient(0deg, #e6b500, #e6b500 50%, transparent 50%);\n  color: #fff; }\n\n.bar.bar-energized .title {\n  color: #fff; }\n\n.bar.bar-energized.bar-footer {\n  background-image: linear-gradient(180deg, #e6b500, #e6b500 50%, transparent 50%); }\n\n.bar.bar-royal {\n  border-color: #6b46e5;\n  background-color: #886aea;\n  background-image: linear-gradient(0deg, #6b46e5, #6b46e5 50%, transparent 50%);\n  color: #fff; }\n\n.bar.bar-royal .title {\n  color: #fff; }\n\n.bar.bar-royal.bar-footer {\n  background-image: linear-gradient(180deg, #6b46e5, #6b46e5 50%, transparent 50%); }\n\n.bar.bar-dark {\n  border-color: #111;\n  background-color: #444444;\n  background-image: linear-gradient(0deg, #111, #111 50%, transparent 50%);\n  color: #fff; }\n\n.bar.bar-dark .title {\n  color: #fff; }\n\n.bar.bar-dark.bar-footer {\n  background-image: linear-gradient(180deg, #111, #111 50%, transparent 50%); }\n\n.bar .title {\n  display: block;\n  position: absolute;\n  top: 0;\n  right: 0;\n  left: 0;\n  z-index: 0;\n  overflow: hidden;\n  margin: 0 10px;\n  min-width: 30px;\n  height: 43px;\n  text-align: center;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  font-size: 17px;\n  font-weight: 500;\n  line-height: 44px; }\n\n.bar .title.title-left {\n  text-align: left; }\n\n.bar .title.title-right {\n  text-align: right; }\n\n.bar .title a {\n  color: inherit; }\n\n.bar .button, .bar button {\n  z-index: 1;\n  padding: 0 8px;\n  min-width: initial;\n  min-height: 31px;\n  font-weight: 400;\n  font-size: 13px;\n  line-height: 32px; }\n\n.bar .button.button-icon:before,\n.bar .button .icon:before, .bar .button.icon:before, .bar .button.icon-left:before, .bar .button.icon-right:before, .bar button.button-icon:before,\n.bar button .icon:before, .bar button.icon:before, .bar button.icon-left:before, .bar button.icon-right:before {\n  padding-right: 2px;\n  padding-left: 2px;\n  font-size: 20px;\n  line-height: 32px; }\n\n.bar .button.button-icon, .bar button.button-icon {\n  font-size: 17px; }\n\n.bar .button.button-icon .icon:before, .bar .button.button-icon:before, .bar .button.button-icon.icon-left:before, .bar .button.button-icon.icon-right:before, .bar button.button-icon .icon:before, .bar button.button-icon:before, .bar button.button-icon.icon-left:before, .bar button.button-icon.icon-right:before {\n  vertical-align: top;\n  font-size: 32px;\n  line-height: 32px; }\n\n.bar .button.button-clear, .bar button.button-clear {\n  padding-right: 2px;\n  padding-left: 2px;\n  font-weight: 300;\n  font-size: 17px; }\n\n.bar .button.button-clear .icon:before, .bar .button.button-clear.icon:before, .bar .button.button-clear.icon-left:before, .bar .button.button-clear.icon-right:before, .bar button.button-clear .icon:before, .bar button.button-clear.icon:before, .bar button.button-clear.icon-left:before, .bar button.button-clear.icon-right:before {\n  font-size: 32px;\n  line-height: 32px; }\n\n.bar .button.back-button, .bar button.back-button {\n  display: block;\n  margin-right: 5px;\n  padding: 0;\n  white-space: nowrap;\n  font-weight: 400; }\n\n.bar .button.back-button.active, .bar .button.back-button.activated, .bar button.back-button.active, .bar button.back-button.activated {\n  opacity: 0.2; }\n\n.bar .button-bar > .button,\n.bar .buttons > .button {\n  min-height: 31px;\n  line-height: 32px; }\n\n.bar .button-bar + .button,\n.bar .button + .button-bar {\n  margin-left: 5px; }\n\n.bar .buttons,\n.bar .buttons.primary-buttons,\n.bar .buttons.secondary-buttons {\n  display: inherit; }\n\n.bar .buttons span {\n  display: inline-block; }\n\n.bar .buttons-left span {\n  margin-right: 5px;\n  display: inherit; }\n\n.bar .buttons-right span {\n  margin-left: 5px;\n  display: inherit; }\n\n.bar .title + .button:last-child,\n.bar > .button + .button:last-child,\n.bar > .button.pull-right,\n.bar .buttons.pull-right,\n.bar .title + .buttons {\n  position: absolute;\n  top: 5px;\n  right: 5px;\n  bottom: 5px; }\n\n.platform-android .nav-bar-has-subheader .bar {\n  background-image: none; }\n\n.platform-android .bar .back-button .icon:before {\n  font-size: 24px; }\n\n.platform-android .bar .title {\n  font-size: 19px;\n  line-height: 44px; }\n\n.bar-light .button {\n  border-color: transparent;\n  background-color: white;\n  color: #444; }\n\n.bar-light .button:hover {\n  color: #444;\n  text-decoration: none; }\n\n.bar-light .button.active, .bar-light .button.activated {\n  background-color: #fafafa; }\n\n.bar-light .button.button-clear {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  color: #444;\n  font-size: 17px; }\n\n.bar-light .button.button-icon {\n  border-color: transparent;\n  background: none; }\n\n.bar-stable .button {\n  border-color: transparent;\n  background-color: #f8f8f8;\n  color: #444; }\n\n.bar-stable .button:hover {\n  color: #444;\n  text-decoration: none; }\n\n.bar-stable .button.active, .bar-stable .button.activated {\n  background-color: #e5e5e5; }\n\n.bar-stable .button.button-clear {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  color: #444;\n  font-size: 17px; }\n\n.bar-stable .button.button-icon {\n  border-color: transparent;\n  background: none; }\n\n.bar-positive .button {\n  border-color: transparent;\n  background-color: #387ef5;\n  color: #fff; }\n\n.bar-positive .button:hover {\n  color: #fff;\n  text-decoration: none; }\n\n.bar-positive .button.active, .bar-positive .button.activated {\n  background-color: #0c60ee; }\n\n.bar-positive .button.button-clear {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  color: #fff;\n  font-size: 17px; }\n\n.bar-positive .button.button-icon {\n  border-color: transparent;\n  background: none; }\n\n.bar-calm .button {\n  border-color: transparent;\n  background-color: #11c1f3;\n  color: #fff; }\n\n.bar-calm .button:hover {\n  color: #fff;\n  text-decoration: none; }\n\n.bar-calm .button.active, .bar-calm .button.activated {\n  background-color: #0a9dc7; }\n\n.bar-calm .button.button-clear {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  color: #fff;\n  font-size: 17px; }\n\n.bar-calm .button.button-icon {\n  border-color: transparent;\n  background: none; }\n\n.bar-assertive .button {\n  border-color: transparent;\n  background-color: #ef473a;\n  color: #fff; }\n\n.bar-assertive .button:hover {\n  color: #fff;\n  text-decoration: none; }\n\n.bar-assertive .button.active, .bar-assertive .button.activated {\n  background-color: #e42112; }\n\n.bar-assertive .button.button-clear {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  color: #fff;\n  font-size: 17px; }\n\n.bar-assertive .button.button-icon {\n  border-color: transparent;\n  background: none; }\n\n.bar-balanced .button {\n  border-color: transparent;\n  background-color: #33cd5f;\n  color: #fff; }\n\n.bar-balanced .button:hover {\n  color: #fff;\n  text-decoration: none; }\n\n.bar-balanced .button.active, .bar-balanced .button.activated {\n  background-color: #28a54c; }\n\n.bar-balanced .button.button-clear {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  color: #fff;\n  font-size: 17px; }\n\n.bar-balanced .button.button-icon {\n  border-color: transparent;\n  background: none; }\n\n.bar-energized .button {\n  border-color: transparent;\n  background-color: #ffc900;\n  color: #fff; }\n\n.bar-energized .button:hover {\n  color: #fff;\n  text-decoration: none; }\n\n.bar-energized .button.active, .bar-energized .button.activated {\n  background-color: #e6b500; }\n\n.bar-energized .button.button-clear {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  color: #fff;\n  font-size: 17px; }\n\n.bar-energized .button.button-icon {\n  border-color: transparent;\n  background: none; }\n\n.bar-royal .button {\n  border-color: transparent;\n  background-color: #886aea;\n  color: #fff; }\n\n.bar-royal .button:hover {\n  color: #fff;\n  text-decoration: none; }\n\n.bar-royal .button.active, .bar-royal .button.activated {\n  background-color: #6b46e5; }\n\n.bar-royal .button.button-clear {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  color: #fff;\n  font-size: 17px; }\n\n.bar-royal .button.button-icon {\n  border-color: transparent;\n  background: none; }\n\n.bar-dark .button {\n  border-color: transparent;\n  background-color: #444444;\n  color: #fff; }\n\n.bar-dark .button:hover {\n  color: #fff;\n  text-decoration: none; }\n\n.bar-dark .button.active, .bar-dark .button.activated {\n  background-color: #262626; }\n\n.bar-dark .button.button-clear {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  color: #fff;\n  font-size: 17px; }\n\n.bar-dark .button.button-icon {\n  border-color: transparent;\n  background: none; }\n\n.bar-header {\n  top: 0;\n  border-top-width: 0;\n  border-bottom-width: 1px; }\n\n.bar-header.has-tabs-top {\n  border-bottom-width: 0px;\n  background-image: none; }\n\n.tabs-top .bar-header {\n  border-bottom-width: 0px;\n  background-image: none; }\n\n.bar-footer {\n  bottom: 0;\n  border-top-width: 1px;\n  border-bottom-width: 0;\n  background-position: top;\n  height: 44px; }\n\n.bar-footer.item-input-inset {\n  position: absolute; }\n\n.bar-tabs {\n  padding: 0; }\n\n.bar-subheader {\n  top: 44px;\n  display: block;\n  height: 44px; }\n\n.bar-subfooter {\n  bottom: 44px;\n  display: block;\n  height: 44px; }\n\n.nav-bar-block {\n  position: absolute;\n  top: 0;\n  right: 0;\n  left: 0;\n  z-index: 9; }\n\n.bar .back-button.hide,\n.bar .buttons .hide {\n  display: none; }\n\n.nav-bar-tabs-top .bar {\n  background-image: none; }\n\n/**\n * Tabs\n * --------------------------------------------------\n * A navigation bar with any number of tab items supported.\n */\n.tabs {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-direction: normal;\n  -webkit-box-orient: horizontal;\n  -webkit-flex-direction: horizontal;\n  -moz-flex-direction: horizontal;\n  -ms-flex-direction: horizontal;\n  flex-direction: horizontal;\n  -webkit-box-pack: center;\n  -ms-flex-pack: center;\n  -webkit-justify-content: center;\n  -moz-justify-content: center;\n  justify-content: center;\n  -webkit-transform: translate3d(0, 0, 0);\n  transform: translate3d(0, 0, 0);\n  border-color: #b2b2b2;\n  background-color: #f8f8f8;\n  background-image: linear-gradient(0deg, #b2b2b2, #b2b2b2 50%, transparent 50%);\n  color: #444;\n  position: absolute;\n  bottom: 0;\n  z-index: 5;\n  width: 100%;\n  height: 49px;\n  border-style: solid;\n  border-top-width: 1px;\n  background-size: 0;\n  line-height: 49px; }\n\n.tabs .tab-item .badge {\n  background-color: #444;\n  color: #f8f8f8; }\n\n@media (min--moz-device-pixel-ratio: 1.5), (-webkit-min-device-pixel-ratio: 1.5), (min-device-pixel-ratio: 1.5), (min-resolution: 144dpi), (min-resolution: 1.5dppx) {\n  .tabs {\n    padding-top: 2px;\n    border-top: none !important;\n    border-bottom: none;\n    background-position: top;\n    background-size: 100% 1px;\n    background-repeat: no-repeat; } }\n\n/* Allow parent element of tabs to define color, or just the tab itself */\n.tabs-light > .tabs,\n.tabs.tabs-light {\n  border-color: #ddd;\n  background-color: #fff;\n  background-image: linear-gradient(0deg, #ddd, #ddd 50%, transparent 50%);\n  color: #444; }\n\n.tabs-light > .tabs .tab-item .badge,\n.tabs.tabs-light .tab-item .badge {\n  background-color: #444;\n  color: #fff; }\n\n.tabs-stable > .tabs,\n.tabs.tabs-stable {\n  border-color: #b2b2b2;\n  background-color: #f8f8f8;\n  background-image: linear-gradient(0deg, #b2b2b2, #b2b2b2 50%, transparent 50%);\n  color: #444; }\n\n.tabs-stable > .tabs .tab-item .badge,\n.tabs.tabs-stable .tab-item .badge {\n  background-color: #444;\n  color: #f8f8f8; }\n\n.tabs-positive > .tabs,\n.tabs.tabs-positive {\n  border-color: #0c60ee;\n  background-color: #387ef5;\n  background-image: linear-gradient(0deg, #0c60ee, #0c60ee 50%, transparent 50%);\n  color: #fff; }\n\n.tabs-positive > .tabs .tab-item .badge,\n.tabs.tabs-positive .tab-item .badge {\n  background-color: #fff;\n  color: #387ef5; }\n\n.tabs-calm > .tabs,\n.tabs.tabs-calm {\n  border-color: #0a9dc7;\n  background-color: #11c1f3;\n  background-image: linear-gradient(0deg, #0a9dc7, #0a9dc7 50%, transparent 50%);\n  color: #fff; }\n\n.tabs-calm > .tabs .tab-item .badge,\n.tabs.tabs-calm .tab-item .badge {\n  background-color: #fff;\n  color: #11c1f3; }\n\n.tabs-assertive > .tabs,\n.tabs.tabs-assertive {\n  border-color: #e42112;\n  background-color: #ef473a;\n  background-image: linear-gradient(0deg, #e42112, #e42112 50%, transparent 50%);\n  color: #fff; }\n\n.tabs-assertive > .tabs .tab-item .badge,\n.tabs.tabs-assertive .tab-item .badge {\n  background-color: #fff;\n  color: #ef473a; }\n\n.tabs-balanced > .tabs,\n.tabs.tabs-balanced {\n  border-color: #28a54c;\n  background-color: #33cd5f;\n  background-image: linear-gradient(0deg, #28a54c, #28a54c 50%, transparent 50%);\n  color: #fff; }\n\n.tabs-balanced > .tabs .tab-item .badge,\n.tabs.tabs-balanced .tab-item .badge {\n  background-color: #fff;\n  color: #33cd5f; }\n\n.tabs-energized > .tabs,\n.tabs.tabs-energized {\n  border-color: #e6b500;\n  background-color: #ffc900;\n  background-image: linear-gradient(0deg, #e6b500, #e6b500 50%, transparent 50%);\n  color: #fff; }\n\n.tabs-energized > .tabs .tab-item .badge,\n.tabs.tabs-energized .tab-item .badge {\n  background-color: #fff;\n  color: #ffc900; }\n\n.tabs-royal > .tabs,\n.tabs.tabs-royal {\n  border-color: #6b46e5;\n  background-color: #886aea;\n  background-image: linear-gradient(0deg, #6b46e5, #6b46e5 50%, transparent 50%);\n  color: #fff; }\n\n.tabs-royal > .tabs .tab-item .badge,\n.tabs.tabs-royal .tab-item .badge {\n  background-color: #fff;\n  color: #886aea; }\n\n.tabs-dark > .tabs,\n.tabs.tabs-dark {\n  border-color: #111;\n  background-color: #444;\n  background-image: linear-gradient(0deg, #111, #111 50%, transparent 50%);\n  color: #fff; }\n\n.tabs-dark > .tabs .tab-item .badge,\n.tabs.tabs-dark .tab-item .badge {\n  background-color: #fff;\n  color: #444; }\n\n.tabs-striped .tabs {\n  background-color: white;\n  background-image: none;\n  border: none;\n  border-bottom: 1px solid #ddd;\n  padding-top: 2px; }\n\n.tabs-striped .tab-item.tab-item-active, .tabs-striped .tab-item.active, .tabs-striped .tab-item.activated {\n  margin-top: -2px;\n  border-style: solid;\n  border-width: 2px 0 0 0;\n  border-color: #444; }\n\n.tabs-striped .tab-item.tab-item-active .badge, .tabs-striped .tab-item.active .badge, .tabs-striped .tab-item.activated .badge {\n  top: 2px;\n  opacity: 1; }\n\n.tabs-striped.tabs-light .tabs {\n  background-color: #fff; }\n\n.tabs-striped.tabs-light .tab-item {\n  color: rgba(68, 68, 68, 0.4);\n  opacity: 1; }\n\n.tabs-striped.tabs-light .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-striped.tabs-light .tab-item.tab-item-active, .tabs-striped.tabs-light .tab-item.active, .tabs-striped.tabs-light .tab-item.activated {\n  margin-top: -2px;\n  color: #444;\n  border-style: solid;\n  border-width: 2px 0 0 0;\n  border-color: #444; }\n\n.tabs-striped.tabs-top .tab-item.tab-item-active .badge, .tabs-striped.tabs-top .tab-item.active .badge, .tabs-striped.tabs-top .tab-item.activated .badge {\n  top: 4%; }\n\n.tabs-striped.tabs-stable .tabs {\n  background-color: #f8f8f8; }\n\n.tabs-striped.tabs-stable .tab-item {\n  color: rgba(68, 68, 68, 0.4);\n  opacity: 1; }\n\n.tabs-striped.tabs-stable .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-striped.tabs-stable .tab-item.tab-item-active, .tabs-striped.tabs-stable .tab-item.active, .tabs-striped.tabs-stable .tab-item.activated {\n  margin-top: -2px;\n  color: #444;\n  border-style: solid;\n  border-width: 2px 0 0 0;\n  border-color: #444; }\n\n.tabs-striped.tabs-top .tab-item.tab-item-active .badge, .tabs-striped.tabs-top .tab-item.active .badge, .tabs-striped.tabs-top .tab-item.activated .badge {\n  top: 4%; }\n\n.tabs-striped.tabs-positive .tabs {\n  background-color: #387ef5; }\n\n.tabs-striped.tabs-positive .tab-item {\n  color: rgba(255, 255, 255, 0.4);\n  opacity: 1; }\n\n.tabs-striped.tabs-positive .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-striped.tabs-positive .tab-item.tab-item-active, .tabs-striped.tabs-positive .tab-item.active, .tabs-striped.tabs-positive .tab-item.activated {\n  margin-top: -2px;\n  color: #fff;\n  border-style: solid;\n  border-width: 2px 0 0 0;\n  border-color: #fff; }\n\n.tabs-striped.tabs-top .tab-item.tab-item-active .badge, .tabs-striped.tabs-top .tab-item.active .badge, .tabs-striped.tabs-top .tab-item.activated .badge {\n  top: 4%; }\n\n.tabs-striped.tabs-calm .tabs {\n  background-color: #11c1f3; }\n\n.tabs-striped.tabs-calm .tab-item {\n  color: rgba(255, 255, 255, 0.4);\n  opacity: 1; }\n\n.tabs-striped.tabs-calm .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-striped.tabs-calm .tab-item.tab-item-active, .tabs-striped.tabs-calm .tab-item.active, .tabs-striped.tabs-calm .tab-item.activated {\n  margin-top: -2px;\n  color: #fff;\n  border-style: solid;\n  border-width: 2px 0 0 0;\n  border-color: #fff; }\n\n.tabs-striped.tabs-top .tab-item.tab-item-active .badge, .tabs-striped.tabs-top .tab-item.active .badge, .tabs-striped.tabs-top .tab-item.activated .badge {\n  top: 4%; }\n\n.tabs-striped.tabs-assertive .tabs {\n  background-color: #ef473a; }\n\n.tabs-striped.tabs-assertive .tab-item {\n  color: rgba(255, 255, 255, 0.4);\n  opacity: 1; }\n\n.tabs-striped.tabs-assertive .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-striped.tabs-assertive .tab-item.tab-item-active, .tabs-striped.tabs-assertive .tab-item.active, .tabs-striped.tabs-assertive .tab-item.activated {\n  margin-top: -2px;\n  color: #fff;\n  border-style: solid;\n  border-width: 2px 0 0 0;\n  border-color: #fff; }\n\n.tabs-striped.tabs-top .tab-item.tab-item-active .badge, .tabs-striped.tabs-top .tab-item.active .badge, .tabs-striped.tabs-top .tab-item.activated .badge {\n  top: 4%; }\n\n.tabs-striped.tabs-balanced .tabs {\n  background-color: #33cd5f; }\n\n.tabs-striped.tabs-balanced .tab-item {\n  color: rgba(255, 255, 255, 0.4);\n  opacity: 1; }\n\n.tabs-striped.tabs-balanced .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-striped.tabs-balanced .tab-item.tab-item-active, .tabs-striped.tabs-balanced .tab-item.active, .tabs-striped.tabs-balanced .tab-item.activated {\n  margin-top: -2px;\n  color: #fff;\n  border-style: solid;\n  border-width: 2px 0 0 0;\n  border-color: #fff; }\n\n.tabs-striped.tabs-top .tab-item.tab-item-active .badge, .tabs-striped.tabs-top .tab-item.active .badge, .tabs-striped.tabs-top .tab-item.activated .badge {\n  top: 4%; }\n\n.tabs-striped.tabs-energized .tabs {\n  background-color: #ffc900; }\n\n.tabs-striped.tabs-energized .tab-item {\n  color: rgba(255, 255, 255, 0.4);\n  opacity: 1; }\n\n.tabs-striped.tabs-energized .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-striped.tabs-energized .tab-item.tab-item-active, .tabs-striped.tabs-energized .tab-item.active, .tabs-striped.tabs-energized .tab-item.activated {\n  margin-top: -2px;\n  color: #fff;\n  border-style: solid;\n  border-width: 2px 0 0 0;\n  border-color: #fff; }\n\n.tabs-striped.tabs-top .tab-item.tab-item-active .badge, .tabs-striped.tabs-top .tab-item.active .badge, .tabs-striped.tabs-top .tab-item.activated .badge {\n  top: 4%; }\n\n.tabs-striped.tabs-royal .tabs {\n  background-color: #886aea; }\n\n.tabs-striped.tabs-royal .tab-item {\n  color: rgba(255, 255, 255, 0.4);\n  opacity: 1; }\n\n.tabs-striped.tabs-royal .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-striped.tabs-royal .tab-item.tab-item-active, .tabs-striped.tabs-royal .tab-item.active, .tabs-striped.tabs-royal .tab-item.activated {\n  margin-top: -2px;\n  color: #fff;\n  border-style: solid;\n  border-width: 2px 0 0 0;\n  border-color: #fff; }\n\n.tabs-striped.tabs-top .tab-item.tab-item-active .badge, .tabs-striped.tabs-top .tab-item.active .badge, .tabs-striped.tabs-top .tab-item.activated .badge {\n  top: 4%; }\n\n.tabs-striped.tabs-dark .tabs {\n  background-color: #444; }\n\n.tabs-striped.tabs-dark .tab-item {\n  color: rgba(255, 255, 255, 0.4);\n  opacity: 1; }\n\n.tabs-striped.tabs-dark .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-striped.tabs-dark .tab-item.tab-item-active, .tabs-striped.tabs-dark .tab-item.active, .tabs-striped.tabs-dark .tab-item.activated {\n  margin-top: -2px;\n  color: #fff;\n  border-style: solid;\n  border-width: 2px 0 0 0;\n  border-color: #fff; }\n\n.tabs-striped.tabs-top .tab-item.tab-item-active .badge, .tabs-striped.tabs-top .tab-item.active .badge, .tabs-striped.tabs-top .tab-item.activated .badge {\n  top: 4%; }\n\n.tabs-striped.tabs-background-light .tabs {\n  background-color: #fff;\n  background-image: none; }\n\n.tabs-striped.tabs-background-stable .tabs {\n  background-color: #f8f8f8;\n  background-image: none; }\n\n.tabs-striped.tabs-background-positive .tabs {\n  background-color: #387ef5;\n  background-image: none; }\n\n.tabs-striped.tabs-background-calm .tabs {\n  background-color: #11c1f3;\n  background-image: none; }\n\n.tabs-striped.tabs-background-assertive .tabs {\n  background-color: #ef473a;\n  background-image: none; }\n\n.tabs-striped.tabs-background-balanced .tabs {\n  background-color: #33cd5f;\n  background-image: none; }\n\n.tabs-striped.tabs-background-energized .tabs {\n  background-color: #ffc900;\n  background-image: none; }\n\n.tabs-striped.tabs-background-royal .tabs {\n  background-color: #886aea;\n  background-image: none; }\n\n.tabs-striped.tabs-background-dark .tabs {\n  background-color: #444;\n  background-image: none; }\n\n.tabs-striped.tabs-color-light .tab-item {\n  color: rgba(255, 255, 255, 0.4);\n  opacity: 1; }\n\n.tabs-striped.tabs-color-light .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-striped.tabs-color-light .tab-item.tab-item-active, .tabs-striped.tabs-color-light .tab-item.active, .tabs-striped.tabs-color-light .tab-item.activated {\n  margin-top: -2px;\n  color: #fff;\n  border: 0 solid #fff;\n  border-top-width: 2px; }\n\n.tabs-striped.tabs-color-light .tab-item.tab-item-active .badge, .tabs-striped.tabs-color-light .tab-item.active .badge, .tabs-striped.tabs-color-light .tab-item.activated .badge {\n  top: 2px;\n  opacity: 1; }\n\n.tabs-striped.tabs-color-stable .tab-item {\n  color: rgba(248, 248, 248, 0.4);\n  opacity: 1; }\n\n.tabs-striped.tabs-color-stable .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-striped.tabs-color-stable .tab-item.tab-item-active, .tabs-striped.tabs-color-stable .tab-item.active, .tabs-striped.tabs-color-stable .tab-item.activated {\n  margin-top: -2px;\n  color: #f8f8f8;\n  border: 0 solid #f8f8f8;\n  border-top-width: 2px; }\n\n.tabs-striped.tabs-color-stable .tab-item.tab-item-active .badge, .tabs-striped.tabs-color-stable .tab-item.active .badge, .tabs-striped.tabs-color-stable .tab-item.activated .badge {\n  top: 2px;\n  opacity: 1; }\n\n.tabs-striped.tabs-color-positive .tab-item {\n  color: rgba(56, 126, 245, 0.4);\n  opacity: 1; }\n\n.tabs-striped.tabs-color-positive .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-striped.tabs-color-positive .tab-item.tab-item-active, .tabs-striped.tabs-color-positive .tab-item.active, .tabs-striped.tabs-color-positive .tab-item.activated {\n  margin-top: -2px;\n  color: #387ef5;\n  border: 0 solid #387ef5;\n  border-top-width: 2px; }\n\n.tabs-striped.tabs-color-positive .tab-item.tab-item-active .badge, .tabs-striped.tabs-color-positive .tab-item.active .badge, .tabs-striped.tabs-color-positive .tab-item.activated .badge {\n  top: 2px;\n  opacity: 1; }\n\n.tabs-striped.tabs-color-calm .tab-item {\n  color: rgba(17, 193, 243, 0.4);\n  opacity: 1; }\n\n.tabs-striped.tabs-color-calm .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-striped.tabs-color-calm .tab-item.tab-item-active, .tabs-striped.tabs-color-calm .tab-item.active, .tabs-striped.tabs-color-calm .tab-item.activated {\n  margin-top: -2px;\n  color: #11c1f3;\n  border: 0 solid #11c1f3;\n  border-top-width: 2px; }\n\n.tabs-striped.tabs-color-calm .tab-item.tab-item-active .badge, .tabs-striped.tabs-color-calm .tab-item.active .badge, .tabs-striped.tabs-color-calm .tab-item.activated .badge {\n  top: 2px;\n  opacity: 1; }\n\n.tabs-striped.tabs-color-assertive .tab-item {\n  color: rgba(239, 71, 58, 0.4);\n  opacity: 1; }\n\n.tabs-striped.tabs-color-assertive .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-striped.tabs-color-assertive .tab-item.tab-item-active, .tabs-striped.tabs-color-assertive .tab-item.active, .tabs-striped.tabs-color-assertive .tab-item.activated {\n  margin-top: -2px;\n  color: #ef473a;\n  border: 0 solid #ef473a;\n  border-top-width: 2px; }\n\n.tabs-striped.tabs-color-assertive .tab-item.tab-item-active .badge, .tabs-striped.tabs-color-assertive .tab-item.active .badge, .tabs-striped.tabs-color-assertive .tab-item.activated .badge {\n  top: 2px;\n  opacity: 1; }\n\n.tabs-striped.tabs-color-balanced .tab-item {\n  color: rgba(51, 205, 95, 0.4);\n  opacity: 1; }\n\n.tabs-striped.tabs-color-balanced .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-striped.tabs-color-balanced .tab-item.tab-item-active, .tabs-striped.tabs-color-balanced .tab-item.active, .tabs-striped.tabs-color-balanced .tab-item.activated {\n  margin-top: -2px;\n  color: #33cd5f;\n  border: 0 solid #33cd5f;\n  border-top-width: 2px; }\n\n.tabs-striped.tabs-color-balanced .tab-item.tab-item-active .badge, .tabs-striped.tabs-color-balanced .tab-item.active .badge, .tabs-striped.tabs-color-balanced .tab-item.activated .badge {\n  top: 2px;\n  opacity: 1; }\n\n.tabs-striped.tabs-color-energized .tab-item {\n  color: rgba(255, 201, 0, 0.4);\n  opacity: 1; }\n\n.tabs-striped.tabs-color-energized .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-striped.tabs-color-energized .tab-item.tab-item-active, .tabs-striped.tabs-color-energized .tab-item.active, .tabs-striped.tabs-color-energized .tab-item.activated {\n  margin-top: -2px;\n  color: #ffc900;\n  border: 0 solid #ffc900;\n  border-top-width: 2px; }\n\n.tabs-striped.tabs-color-energized .tab-item.tab-item-active .badge, .tabs-striped.tabs-color-energized .tab-item.active .badge, .tabs-striped.tabs-color-energized .tab-item.activated .badge {\n  top: 2px;\n  opacity: 1; }\n\n.tabs-striped.tabs-color-royal .tab-item {\n  color: rgba(136, 106, 234, 0.4);\n  opacity: 1; }\n\n.tabs-striped.tabs-color-royal .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-striped.tabs-color-royal .tab-item.tab-item-active, .tabs-striped.tabs-color-royal .tab-item.active, .tabs-striped.tabs-color-royal .tab-item.activated {\n  margin-top: -2px;\n  color: #886aea;\n  border: 0 solid #886aea;\n  border-top-width: 2px; }\n\n.tabs-striped.tabs-color-royal .tab-item.tab-item-active .badge, .tabs-striped.tabs-color-royal .tab-item.active .badge, .tabs-striped.tabs-color-royal .tab-item.activated .badge {\n  top: 2px;\n  opacity: 1; }\n\n.tabs-striped.tabs-color-dark .tab-item {\n  color: rgba(68, 68, 68, 0.4);\n  opacity: 1; }\n\n.tabs-striped.tabs-color-dark .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-striped.tabs-color-dark .tab-item.tab-item-active, .tabs-striped.tabs-color-dark .tab-item.active, .tabs-striped.tabs-color-dark .tab-item.activated {\n  margin-top: -2px;\n  color: #444;\n  border: 0 solid #444;\n  border-top-width: 2px; }\n\n.tabs-striped.tabs-color-dark .tab-item.tab-item-active .badge, .tabs-striped.tabs-color-dark .tab-item.active .badge, .tabs-striped.tabs-color-dark .tab-item.activated .badge {\n  top: 2px;\n  opacity: 1; }\n\n.tabs-background-light .tabs,\n.tabs-background-light > .tabs {\n  background-color: #fff;\n  background-image: linear-gradient(0deg, #ddd, #ddd 50%, transparent 50%);\n  border-color: #ddd; }\n\n.tabs-background-stable .tabs,\n.tabs-background-stable > .tabs {\n  background-color: #f8f8f8;\n  background-image: linear-gradient(0deg, #b2b2b2, #b2b2b2 50%, transparent 50%);\n  border-color: #b2b2b2; }\n\n.tabs-background-positive .tabs,\n.tabs-background-positive > .tabs {\n  background-color: #387ef5;\n  background-image: linear-gradient(0deg, #0c60ee, #0c60ee 50%, transparent 50%);\n  border-color: #0c60ee; }\n\n.tabs-background-calm .tabs,\n.tabs-background-calm > .tabs {\n  background-color: #11c1f3;\n  background-image: linear-gradient(0deg, #0a9dc7, #0a9dc7 50%, transparent 50%);\n  border-color: #0a9dc7; }\n\n.tabs-background-assertive .tabs,\n.tabs-background-assertive > .tabs {\n  background-color: #ef473a;\n  background-image: linear-gradient(0deg, #e42112, #e42112 50%, transparent 50%);\n  border-color: #e42112; }\n\n.tabs-background-balanced .tabs,\n.tabs-background-balanced > .tabs {\n  background-color: #33cd5f;\n  background-image: linear-gradient(0deg, #28a54c, #28a54c 50%, transparent 50%);\n  border-color: #28a54c; }\n\n.tabs-background-energized .tabs,\n.tabs-background-energized > .tabs {\n  background-color: #ffc900;\n  background-image: linear-gradient(0deg, #e6b500, #e6b500 50%, transparent 50%);\n  border-color: #e6b500; }\n\n.tabs-background-royal .tabs,\n.tabs-background-royal > .tabs {\n  background-color: #886aea;\n  background-image: linear-gradient(0deg, #6b46e5, #6b46e5 50%, transparent 50%);\n  border-color: #6b46e5; }\n\n.tabs-background-dark .tabs,\n.tabs-background-dark > .tabs {\n  background-color: #444;\n  background-image: linear-gradient(0deg, #111, #111 50%, transparent 50%);\n  border-color: #111; }\n\n.tabs-color-light .tab-item {\n  color: rgba(255, 255, 255, 0.4);\n  opacity: 1; }\n\n.tabs-color-light .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-color-light .tab-item.tab-item-active, .tabs-color-light .tab-item.active, .tabs-color-light .tab-item.activated {\n  color: #fff;\n  border: 0 solid #fff; }\n\n.tabs-color-light .tab-item.tab-item-active .badge, .tabs-color-light .tab-item.active .badge, .tabs-color-light .tab-item.activated .badge {\n  opacity: 1; }\n\n.tabs-color-stable .tab-item {\n  color: rgba(248, 248, 248, 0.4);\n  opacity: 1; }\n\n.tabs-color-stable .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-color-stable .tab-item.tab-item-active, .tabs-color-stable .tab-item.active, .tabs-color-stable .tab-item.activated {\n  color: #f8f8f8;\n  border: 0 solid #f8f8f8; }\n\n.tabs-color-stable .tab-item.tab-item-active .badge, .tabs-color-stable .tab-item.active .badge, .tabs-color-stable .tab-item.activated .badge {\n  opacity: 1; }\n\n.tabs-color-positive .tab-item {\n  color: rgba(56, 126, 245, 0.4);\n  opacity: 1; }\n\n.tabs-color-positive .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-color-positive .tab-item.tab-item-active, .tabs-color-positive .tab-item.active, .tabs-color-positive .tab-item.activated {\n  color: #387ef5;\n  border: 0 solid #387ef5; }\n\n.tabs-color-positive .tab-item.tab-item-active .badge, .tabs-color-positive .tab-item.active .badge, .tabs-color-positive .tab-item.activated .badge {\n  opacity: 1; }\n\n.tabs-color-calm .tab-item {\n  color: rgba(17, 193, 243, 0.4);\n  opacity: 1; }\n\n.tabs-color-calm .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-color-calm .tab-item.tab-item-active, .tabs-color-calm .tab-item.active, .tabs-color-calm .tab-item.activated {\n  color: #11c1f3;\n  border: 0 solid #11c1f3; }\n\n.tabs-color-calm .tab-item.tab-item-active .badge, .tabs-color-calm .tab-item.active .badge, .tabs-color-calm .tab-item.activated .badge {\n  opacity: 1; }\n\n.tabs-color-assertive .tab-item {\n  color: rgba(239, 71, 58, 0.4);\n  opacity: 1; }\n\n.tabs-color-assertive .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-color-assertive .tab-item.tab-item-active, .tabs-color-assertive .tab-item.active, .tabs-color-assertive .tab-item.activated {\n  color: #ef473a;\n  border: 0 solid #ef473a; }\n\n.tabs-color-assertive .tab-item.tab-item-active .badge, .tabs-color-assertive .tab-item.active .badge, .tabs-color-assertive .tab-item.activated .badge {\n  opacity: 1; }\n\n.tabs-color-balanced .tab-item {\n  color: rgba(51, 205, 95, 0.4);\n  opacity: 1; }\n\n.tabs-color-balanced .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-color-balanced .tab-item.tab-item-active, .tabs-color-balanced .tab-item.active, .tabs-color-balanced .tab-item.activated {\n  color: #33cd5f;\n  border: 0 solid #33cd5f; }\n\n.tabs-color-balanced .tab-item.tab-item-active .badge, .tabs-color-balanced .tab-item.active .badge, .tabs-color-balanced .tab-item.activated .badge {\n  opacity: 1; }\n\n.tabs-color-energized .tab-item {\n  color: rgba(255, 201, 0, 0.4);\n  opacity: 1; }\n\n.tabs-color-energized .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-color-energized .tab-item.tab-item-active, .tabs-color-energized .tab-item.active, .tabs-color-energized .tab-item.activated {\n  color: #ffc900;\n  border: 0 solid #ffc900; }\n\n.tabs-color-energized .tab-item.tab-item-active .badge, .tabs-color-energized .tab-item.active .badge, .tabs-color-energized .tab-item.activated .badge {\n  opacity: 1; }\n\n.tabs-color-royal .tab-item {\n  color: rgba(136, 106, 234, 0.4);\n  opacity: 1; }\n\n.tabs-color-royal .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-color-royal .tab-item.tab-item-active, .tabs-color-royal .tab-item.active, .tabs-color-royal .tab-item.activated {\n  color: #886aea;\n  border: 0 solid #886aea; }\n\n.tabs-color-royal .tab-item.tab-item-active .badge, .tabs-color-royal .tab-item.active .badge, .tabs-color-royal .tab-item.activated .badge {\n  opacity: 1; }\n\n.tabs-color-dark .tab-item {\n  color: rgba(68, 68, 68, 0.4);\n  opacity: 1; }\n\n.tabs-color-dark .tab-item .badge {\n  opacity: 0.4; }\n\n.tabs-color-dark .tab-item.tab-item-active, .tabs-color-dark .tab-item.active, .tabs-color-dark .tab-item.activated {\n  color: #444;\n  border: 0 solid #444; }\n\n.tabs-color-dark .tab-item.tab-item-active .badge, .tabs-color-dark .tab-item.active .badge, .tabs-color-dark .tab-item.activated .badge {\n  opacity: 1; }\n\nion-tabs.tabs-color-active-light .tab-item {\n  color: #444; }\n\nion-tabs.tabs-color-active-light .tab-item.tab-item-active, ion-tabs.tabs-color-active-light .tab-item.active, ion-tabs.tabs-color-active-light .tab-item.activated {\n  color: #fff; }\n\nion-tabs.tabs-color-active-stable .tab-item {\n  color: #444; }\n\nion-tabs.tabs-color-active-stable .tab-item.tab-item-active, ion-tabs.tabs-color-active-stable .tab-item.active, ion-tabs.tabs-color-active-stable .tab-item.activated {\n  color: #f8f8f8; }\n\nion-tabs.tabs-color-active-positive .tab-item {\n  color: #444; }\n\nion-tabs.tabs-color-active-positive .tab-item.tab-item-active, ion-tabs.tabs-color-active-positive .tab-item.active, ion-tabs.tabs-color-active-positive .tab-item.activated {\n  color: #387ef5; }\n\nion-tabs.tabs-color-active-calm .tab-item {\n  color: #444; }\n\nion-tabs.tabs-color-active-calm .tab-item.tab-item-active, ion-tabs.tabs-color-active-calm .tab-item.active, ion-tabs.tabs-color-active-calm .tab-item.activated {\n  color: #11c1f3; }\n\nion-tabs.tabs-color-active-assertive .tab-item {\n  color: #444; }\n\nion-tabs.tabs-color-active-assertive .tab-item.tab-item-active, ion-tabs.tabs-color-active-assertive .tab-item.active, ion-tabs.tabs-color-active-assertive .tab-item.activated {\n  color: #ef473a; }\n\nion-tabs.tabs-color-active-balanced .tab-item {\n  color: #444; }\n\nion-tabs.tabs-color-active-balanced .tab-item.tab-item-active, ion-tabs.tabs-color-active-balanced .tab-item.active, ion-tabs.tabs-color-active-balanced .tab-item.activated {\n  color: #33cd5f; }\n\nion-tabs.tabs-color-active-energized .tab-item {\n  color: #444; }\n\nion-tabs.tabs-color-active-energized .tab-item.tab-item-active, ion-tabs.tabs-color-active-energized .tab-item.active, ion-tabs.tabs-color-active-energized .tab-item.activated {\n  color: #ffc900; }\n\nion-tabs.tabs-color-active-royal .tab-item {\n  color: #444; }\n\nion-tabs.tabs-color-active-royal .tab-item.tab-item-active, ion-tabs.tabs-color-active-royal .tab-item.active, ion-tabs.tabs-color-active-royal .tab-item.activated {\n  color: #886aea; }\n\nion-tabs.tabs-color-active-dark .tab-item {\n  color: #fff; }\n\nion-tabs.tabs-color-active-dark .tab-item.tab-item-active, ion-tabs.tabs-color-active-dark .tab-item.active, ion-tabs.tabs-color-active-dark .tab-item.activated {\n  color: #444; }\n\n.tabs-top.tabs-striped {\n  padding-bottom: 0; }\n\n.tabs-top.tabs-striped .tab-item {\n  background: transparent;\n  -webkit-transition: color .1s ease;\n  -moz-transition: color .1s ease;\n  -ms-transition: color .1s ease;\n  -o-transition: color .1s ease;\n  transition: color .1s ease; }\n\n.tabs-top.tabs-striped .tab-item.tab-item-active, .tabs-top.tabs-striped .tab-item.active, .tabs-top.tabs-striped .tab-item.activated {\n  margin-top: 1px;\n  border-width: 0px 0px 2px 0px !important;\n  border-style: solid; }\n\n.tabs-top.tabs-striped .tab-item.tab-item-active > .badge, .tabs-top.tabs-striped .tab-item.tab-item-active > i, .tabs-top.tabs-striped .tab-item.active > .badge, .tabs-top.tabs-striped .tab-item.active > i, .tabs-top.tabs-striped .tab-item.activated > .badge, .tabs-top.tabs-striped .tab-item.activated > i {\n  margin-top: -1px; }\n\n.tabs-top.tabs-striped .tab-item .badge {\n  -webkit-transition: color .2s ease;\n  -moz-transition: color .2s ease;\n  -ms-transition: color .2s ease;\n  -o-transition: color .2s ease;\n  transition: color .2s ease; }\n\n.tabs-top.tabs-striped:not(.tabs-icon-left):not(.tabs-icon-top) .tab-item.tab-item-active .tab-title, .tabs-top.tabs-striped:not(.tabs-icon-left):not(.tabs-icon-top) .tab-item.tab-item-active i, .tabs-top.tabs-striped:not(.tabs-icon-left):not(.tabs-icon-top) .tab-item.active .tab-title, .tabs-top.tabs-striped:not(.tabs-icon-left):not(.tabs-icon-top) .tab-item.active i, .tabs-top.tabs-striped:not(.tabs-icon-left):not(.tabs-icon-top) .tab-item.activated .tab-title, .tabs-top.tabs-striped:not(.tabs-icon-left):not(.tabs-icon-top) .tab-item.activated i {\n  display: block;\n  margin-top: -1px; }\n\n.tabs-top.tabs-striped.tabs-icon-left .tab-item {\n  margin-top: 1px; }\n\n.tabs-top.tabs-striped.tabs-icon-left .tab-item.tab-item-active .tab-title, .tabs-top.tabs-striped.tabs-icon-left .tab-item.tab-item-active i, .tabs-top.tabs-striped.tabs-icon-left .tab-item.active .tab-title, .tabs-top.tabs-striped.tabs-icon-left .tab-item.active i, .tabs-top.tabs-striped.tabs-icon-left .tab-item.activated .tab-title, .tabs-top.tabs-striped.tabs-icon-left .tab-item.activated i {\n  margin-top: -0.1em; }\n\n/* Allow parent element to have tabs-top */\n/* If you change this, change platform.scss as well */\n.tabs-top > .tabs,\n.tabs.tabs-top {\n  top: 44px;\n  padding-top: 0;\n  background-position: bottom;\n  border-top-width: 0;\n  border-bottom-width: 1px; }\n\n.tabs-top > .tabs .tab-item.tab-item-active .badge, .tabs-top > .tabs .tab-item.active .badge, .tabs-top > .tabs .tab-item.activated .badge,\n.tabs.tabs-top .tab-item.tab-item-active .badge,\n.tabs.tabs-top .tab-item.active .badge,\n.tabs.tabs-top .tab-item.activated .badge {\n  top: 4%; }\n\n.tabs-top ~ .bar-header {\n  border-bottom-width: 0; }\n\n.tab-item {\n  -webkit-box-flex: 1;\n  -webkit-flex: 1;\n  -moz-box-flex: 1;\n  -moz-flex: 1;\n  -ms-flex: 1;\n  flex: 1;\n  display: block;\n  overflow: hidden;\n  max-width: 150px;\n  height: 100%;\n  color: inherit;\n  text-align: center;\n  text-decoration: none;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n  font-weight: 400;\n  font-size: 14px;\n  font-family: \"-apple-system\", \"Helvetica Neue\", \"Roboto\", \"Segoe UI\", sans-serif;\n  opacity: 0.7; }\n\n.tab-item:hover {\n  cursor: pointer; }\n\n.tab-item.tab-hidden {\n  display: none; }\n\n.tabs-item-hide > .tabs,\n.tabs.tabs-item-hide {\n  display: none; }\n\n.tabs-icon-top > .tabs .tab-item,\n.tabs-icon-top.tabs .tab-item,\n.tabs-icon-bottom > .tabs .tab-item,\n.tabs-icon-bottom.tabs .tab-item {\n  font-size: 10px;\n  line-height: 14px; }\n\n.tab-item .icon {\n  display: block;\n  margin: 0 auto;\n  height: 32px;\n  font-size: 32px; }\n\n.tabs-icon-left.tabs .tab-item,\n.tabs-icon-left > .tabs .tab-item,\n.tabs-icon-right.tabs .tab-item,\n.tabs-icon-right > .tabs .tab-item {\n  font-size: 10px; }\n\n.tabs-icon-left.tabs .tab-item .icon, .tabs-icon-left.tabs .tab-item .tab-title,\n.tabs-icon-left > .tabs .tab-item .icon,\n.tabs-icon-left > .tabs .tab-item .tab-title,\n.tabs-icon-right.tabs .tab-item .icon,\n.tabs-icon-right.tabs .tab-item .tab-title,\n.tabs-icon-right > .tabs .tab-item .icon,\n.tabs-icon-right > .tabs .tab-item .tab-title {\n  display: inline-block;\n  vertical-align: top;\n  margin-top: -.1em; }\n\n.tabs-icon-left.tabs .tab-item .icon:before, .tabs-icon-left.tabs .tab-item .tab-title:before,\n.tabs-icon-left > .tabs .tab-item .icon:before,\n.tabs-icon-left > .tabs .tab-item .tab-title:before,\n.tabs-icon-right.tabs .tab-item .icon:before,\n.tabs-icon-right.tabs .tab-item .tab-title:before,\n.tabs-icon-right > .tabs .tab-item .icon:before,\n.tabs-icon-right > .tabs .tab-item .tab-title:before {\n  font-size: 24px;\n  line-height: 49px; }\n\n.tabs-icon-left > .tabs .tab-item .icon,\n.tabs-icon-left.tabs .tab-item .icon {\n  padding-right: 3px; }\n\n.tabs-icon-right > .tabs .tab-item .icon,\n.tabs-icon-right.tabs .tab-item .icon {\n  padding-left: 3px; }\n\n.tabs-icon-only > .tabs .icon,\n.tabs-icon-only.tabs .icon {\n  line-height: inherit; }\n\n.tab-item.has-badge {\n  position: relative; }\n\n.tab-item .badge {\n  position: absolute;\n  top: 4%;\n  right: 33%;\n  right: calc(50% - 26px);\n  padding: 1px 6px;\n  height: auto;\n  font-size: 12px;\n  line-height: 16px; }\n\n/* Navigational tab */\n/* Active state for tab */\n.tab-item.tab-item-active,\n.tab-item.active,\n.tab-item.activated {\n  opacity: 1; }\n\n.tab-item.tab-item-active.tab-item-light,\n.tab-item.active.tab-item-light,\n.tab-item.activated.tab-item-light {\n  color: #fff; }\n\n.tab-item.tab-item-active.tab-item-stable,\n.tab-item.active.tab-item-stable,\n.tab-item.activated.tab-item-stable {\n  color: #f8f8f8; }\n\n.tab-item.tab-item-active.tab-item-positive,\n.tab-item.active.tab-item-positive,\n.tab-item.activated.tab-item-positive {\n  color: #387ef5; }\n\n.tab-item.tab-item-active.tab-item-calm,\n.tab-item.active.tab-item-calm,\n.tab-item.activated.tab-item-calm {\n  color: #11c1f3; }\n\n.tab-item.tab-item-active.tab-item-assertive,\n.tab-item.active.tab-item-assertive,\n.tab-item.activated.tab-item-assertive {\n  color: #ef473a; }\n\n.tab-item.tab-item-active.tab-item-balanced,\n.tab-item.active.tab-item-balanced,\n.tab-item.activated.tab-item-balanced {\n  color: #33cd5f; }\n\n.tab-item.tab-item-active.tab-item-energized,\n.tab-item.active.tab-item-energized,\n.tab-item.activated.tab-item-energized {\n  color: #ffc900; }\n\n.tab-item.tab-item-active.tab-item-royal,\n.tab-item.active.tab-item-royal,\n.tab-item.activated.tab-item-royal {\n  color: #886aea; }\n\n.tab-item.tab-item-active.tab-item-dark,\n.tab-item.active.tab-item-dark,\n.tab-item.activated.tab-item-dark {\n  color: #444; }\n\n.item.tabs {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  padding: 0; }\n\n.item.tabs .icon:before {\n  position: relative; }\n\n.tab-item.disabled,\n.tab-item[disabled] {\n  opacity: .4;\n  cursor: default;\n  pointer-events: none; }\n\n.nav-bar-tabs-top.hide ~ .view-container .tabs-top .tabs {\n  top: 0; }\n\n.pane[hide-nav-bar=\"true\"] .has-tabs-top {\n  top: 49px; }\n\n/**\n * Menus\n * --------------------------------------------------\n * Side panel structure\n */\n.menu {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  z-index: 0;\n  overflow: hidden;\n  min-height: 100%;\n  max-height: 100%;\n  width: 275px;\n  background-color: #fff; }\n\n.menu .scroll-content {\n  z-index: 10; }\n\n.menu .bar-header {\n  z-index: 11; }\n\n.menu-content {\n  -webkit-transform: none;\n  transform: none;\n  box-shadow: -1px 0px 2px rgba(0, 0, 0, 0.2), 1px 0px 2px rgba(0, 0, 0, 0.2); }\n\n.menu-open .menu-content .pane,\n.menu-open .menu-content .scroll-content {\n  pointer-events: none; }\n\n.menu-open .menu-content .scroll-content .scroll {\n  pointer-events: none; }\n\n.menu-open .menu-content .scroll-content:not(.overflow-scroll) {\n  overflow: hidden; }\n\n.grade-b .menu-content,\n.grade-c .menu-content {\n  -webkit-box-sizing: content-box;\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n  right: -1px;\n  left: -1px;\n  border-right: 1px solid #ccc;\n  border-left: 1px solid #ccc;\n  box-shadow: none; }\n\n.menu-left {\n  left: 0; }\n\n.menu-right {\n  right: 0; }\n\n.aside-open.aside-resizing .menu-right {\n  display: none; }\n\n.menu-animated {\n  -webkit-transition: -webkit-transform 200ms ease;\n  transition: transform 200ms ease; }\n\n/**\n * Modals\n * --------------------------------------------------\n * Modals are independent windows that slide in from off-screen.\n */\n.modal-backdrop,\n.modal-backdrop-bg {\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: 10;\n  width: 100%;\n  height: 100%; }\n\n.modal-backdrop-bg {\n  pointer-events: none; }\n\n.modal {\n  display: block;\n  position: absolute;\n  top: 0;\n  z-index: 10;\n  overflow: hidden;\n  min-height: 100%;\n  width: 100%;\n  background-color: #fff; }\n\n@media (min-width: 680px) {\n  .modal {\n    top: 20%;\n    right: 20%;\n    bottom: 20%;\n    left: 20%;\n    min-height: 240px;\n    width: 60%; }\n  .modal.ng-leave-active {\n    bottom: 0; }\n  .platform-ios.platform-cordova .modal-wrapper .modal .bar-header:not(.bar-subheader) {\n    height: 44px; }\n  .platform-ios.platform-cordova .modal-wrapper .modal .bar-header:not(.bar-subheader) > * {\n    margin-top: 0; }\n  .platform-ios.platform-cordova .modal-wrapper .modal .tabs-top > .tabs,\n  .platform-ios.platform-cordova .modal-wrapper .modal .tabs.tabs-top {\n    top: 44px; }\n  .platform-ios.platform-cordova .modal-wrapper .modal .has-header,\n  .platform-ios.platform-cordova .modal-wrapper .modal .bar-subheader {\n    top: 44px; }\n  .platform-ios.platform-cordova .modal-wrapper .modal .has-subheader {\n    top: 88px; }\n  .platform-ios.platform-cordova .modal-wrapper .modal .has-header.has-tabs-top {\n    top: 93px; }\n  .platform-ios.platform-cordova .modal-wrapper .modal .has-header.has-subheader.has-tabs-top {\n    top: 137px; }\n  .modal-backdrop-bg {\n    -webkit-transition: opacity 300ms ease-in-out;\n    transition: opacity 300ms ease-in-out;\n    background-color: #000;\n    opacity: 0; }\n  .active .modal-backdrop-bg {\n    opacity: 0.5; } }\n\n.modal-open {\n  pointer-events: none; }\n\n.modal-open .modal,\n.modal-open .modal-backdrop {\n  pointer-events: auto; }\n\n.modal-open.loading-active .modal,\n.modal-open.loading-active .modal-backdrop {\n  pointer-events: none; }\n\n/**\n * Popovers\n * --------------------------------------------------\n * Popovers are independent views which float over content\n */\n.popover-backdrop {\n  position: fixed;\n  top: 0;\n  left: 0;\n  z-index: 10;\n  width: 100%;\n  height: 100%;\n  background-color: transparent; }\n\n.popover-backdrop.active {\n  background-color: rgba(0, 0, 0, 0.1); }\n\n.popover {\n  position: absolute;\n  top: 25%;\n  left: 50%;\n  z-index: 10;\n  display: block;\n  margin-top: 12px;\n  margin-left: -110px;\n  height: 280px;\n  width: 220px;\n  background-color: #fff;\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4);\n  opacity: 0; }\n\n.popover .item:first-child {\n  border-top: 0; }\n\n.popover .item:last-child {\n  border-bottom: 0; }\n\n.popover.popover-bottom {\n  margin-top: -12px; }\n\n.popover,\n.popover .bar-header {\n  border-radius: 2px; }\n\n.popover .scroll-content {\n  z-index: 1;\n  margin: 2px 0; }\n\n.popover .bar-header {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0; }\n\n.popover .has-header {\n  border-top-right-radius: 0;\n  border-top-left-radius: 0; }\n\n.popover-arrow {\n  display: none; }\n\n.platform-ios .popover {\n  box-shadow: 0 0 40px rgba(0, 0, 0, 0.08);\n  border-radius: 10px; }\n\n.platform-ios .popover .bar-header {\n  -webkit-border-top-right-radius: 10px;\n  border-top-right-radius: 10px;\n  -webkit-border-top-left-radius: 10px;\n  border-top-left-radius: 10px; }\n\n.platform-ios .popover .scroll-content {\n  margin: 8px 0;\n  border-radius: 10px; }\n\n.platform-ios .popover .scroll-content.has-header {\n  margin-top: 0; }\n\n.platform-ios .popover-arrow {\n  position: absolute;\n  display: block;\n  top: -17px;\n  width: 30px;\n  height: 19px;\n  overflow: hidden; }\n\n.platform-ios .popover-arrow:after {\n  position: absolute;\n  top: 12px;\n  left: 5px;\n  width: 20px;\n  height: 20px;\n  background-color: #fff;\n  border-radius: 3px;\n  content: '';\n  -webkit-transform: rotate(-45deg);\n  transform: rotate(-45deg); }\n\n.platform-ios .popover-bottom .popover-arrow {\n  top: auto;\n  bottom: -10px; }\n\n.platform-ios .popover-bottom .popover-arrow:after {\n  top: -6px; }\n\n.platform-android .popover {\n  margin-top: -32px;\n  background-color: #fafafa;\n  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35); }\n\n.platform-android .popover .item {\n  border-color: #fafafa;\n  background-color: #fafafa;\n  color: #4d4d4d; }\n\n.platform-android .popover.popover-bottom {\n  margin-top: 32px; }\n\n.platform-android .popover-backdrop,\n.platform-android .popover-backdrop.active {\n  background-color: transparent; }\n\n.popover-open {\n  pointer-events: none; }\n\n.popover-open .popover,\n.popover-open .popover-backdrop {\n  pointer-events: auto; }\n\n.popover-open.loading-active .popover,\n.popover-open.loading-active .popover-backdrop {\n  pointer-events: none; }\n\n@media (min-width: 680px) {\n  .popover {\n    width: 360px;\n    margin-left: -180px; } }\n\n/**\n * Popups\n * --------------------------------------------------\n */\n.popup-container {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  right: 0;\n  background: transparent;\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-pack: center;\n  -ms-flex-pack: center;\n  -webkit-justify-content: center;\n  -moz-justify-content: center;\n  justify-content: center;\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  align-items: center;\n  z-index: 12;\n  visibility: hidden; }\n\n.popup-container.popup-showing {\n  visibility: visible; }\n\n.popup-container.popup-hidden .popup {\n  -webkit-animation-name: scaleOut;\n  animation-name: scaleOut;\n  -webkit-animation-duration: 0.1s;\n  animation-duration: 0.1s;\n  -webkit-animation-timing-function: ease-in-out;\n  animation-timing-function: ease-in-out;\n  -webkit-animation-fill-mode: both;\n  animation-fill-mode: both; }\n\n.popup-container.active .popup {\n  -webkit-animation-name: superScaleIn;\n  animation-name: superScaleIn;\n  -webkit-animation-duration: 0.2s;\n  animation-duration: 0.2s;\n  -webkit-animation-timing-function: ease-in-out;\n  animation-timing-function: ease-in-out;\n  -webkit-animation-fill-mode: both;\n  animation-fill-mode: both; }\n\n.popup-container .popup {\n  width: 250px;\n  max-width: 100%;\n  max-height: 90%;\n  border-radius: 0px;\n  background-color: rgba(255, 255, 255, 0.9);\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-direction: normal;\n  -webkit-box-orient: vertical;\n  -webkit-flex-direction: column;\n  -moz-flex-direction: column;\n  -ms-flex-direction: column;\n  flex-direction: column; }\n\n.popup-container input,\n.popup-container textarea {\n  width: 100%; }\n\n.popup-head {\n  padding: 15px 10px;\n  border-bottom: 1px solid #eee;\n  text-align: center; }\n\n.popup-title {\n  margin: 0;\n  padding: 0;\n  font-size: 15px; }\n\n.popup-sub-title {\n  margin: 5px 0 0 0;\n  padding: 0;\n  font-weight: normal;\n  font-size: 11px; }\n\n.popup-body {\n  padding: 10px;\n  overflow: auto; }\n\n.popup-buttons {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-direction: normal;\n  -webkit-box-orient: horizontal;\n  -webkit-flex-direction: row;\n  -moz-flex-direction: row;\n  -ms-flex-direction: row;\n  flex-direction: row;\n  padding: 10px;\n  min-height: 65px; }\n\n.popup-buttons .button {\n  -webkit-box-flex: 1;\n  -webkit-flex: 1;\n  -moz-box-flex: 1;\n  -moz-flex: 1;\n  -ms-flex: 1;\n  flex: 1;\n  display: block;\n  min-height: 45px;\n  border-radius: 2px;\n  line-height: 20px;\n  margin-right: 5px; }\n\n.popup-buttons .button:last-child {\n  margin-right: 0px; }\n\n.popup-open {\n  pointer-events: none; }\n\n.popup-open.modal-open .modal {\n  pointer-events: none; }\n\n.popup-open .popup-backdrop, .popup-open .popup {\n  pointer-events: auto; }\n\n/**\n * Loading\n * --------------------------------------------------\n */\n.loading-container {\n  position: absolute;\n  left: 0;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  z-index: 13;\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-pack: center;\n  -ms-flex-pack: center;\n  -webkit-justify-content: center;\n  -moz-justify-content: center;\n  justify-content: center;\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  align-items: center;\n  -webkit-transition: 0.2s opacity linear;\n  transition: 0.2s opacity linear;\n  visibility: hidden;\n  opacity: 0; }\n\n.loading-container:not(.visible) .icon,\n.loading-container:not(.visible) .spinner {\n  display: none; }\n\n.loading-container.visible {\n  visibility: visible; }\n\n.loading-container.active {\n  opacity: 1; }\n\n.loading-container .loading {\n  padding: 20px;\n  border-radius: 5px;\n  background-color: rgba(0, 0, 0, 0.7);\n  color: #fff;\n  text-align: center;\n  text-overflow: ellipsis;\n  font-size: 15px; }\n\n.loading-container .loading h1, .loading-container .loading h2, .loading-container .loading h3, .loading-container .loading h4, .loading-container .loading h5, .loading-container .loading h6 {\n  color: #fff; }\n\n/**\n * Items\n * --------------------------------------------------\n */\n.item {\n  border-color: #ddd;\n  background-color: #fff;\n  color: #444;\n  position: relative;\n  z-index: 2;\n  display: block;\n  margin: -1px;\n  padding: 16px;\n  border-width: 1px;\n  border-style: solid;\n  font-size: 16px; }\n\n.item h2 {\n  margin: 0 0 2px 0;\n  font-size: 16px;\n  font-weight: normal; }\n\n.item h3 {\n  margin: 0 0 4px 0;\n  font-size: 14px; }\n\n.item h4 {\n  margin: 0 0 4px 0;\n  font-size: 12px; }\n\n.item h5, .item h6 {\n  margin: 0 0 3px 0;\n  font-size: 10px; }\n\n.item p {\n  color: #666;\n  font-size: 14px;\n  margin-bottom: 2px; }\n\n.item h1:last-child,\n.item h2:last-child,\n.item h3:last-child,\n.item h4:last-child,\n.item h5:last-child,\n.item h6:last-child,\n.item p:last-child {\n  margin-bottom: 0; }\n\n.item .badge {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  position: absolute;\n  top: 16px;\n  right: 32px; }\n\n.item.item-button-right .badge {\n  right: 67px; }\n\n.item.item-divider .badge {\n  top: 8px; }\n\n.item .badge + .badge {\n  margin-right: 5px; }\n\n.item.item-light {\n  border-color: #ddd;\n  background-color: #fff;\n  color: #444; }\n\n.item.item-stable {\n  border-color: #b2b2b2;\n  background-color: #f8f8f8;\n  color: #444; }\n\n.item.item-positive {\n  border-color: #0c60ee;\n  background-color: #387ef5;\n  color: #fff; }\n\n.item.item-calm {\n  border-color: #0a9dc7;\n  background-color: #11c1f3;\n  color: #fff; }\n\n.item.item-assertive {\n  border-color: #e42112;\n  background-color: #ef473a;\n  color: #fff; }\n\n.item.item-balanced {\n  border-color: #28a54c;\n  background-color: #33cd5f;\n  color: #fff; }\n\n.item.item-energized {\n  border-color: #e6b500;\n  background-color: #ffc900;\n  color: #fff; }\n\n.item.item-royal {\n  border-color: #6b46e5;\n  background-color: #886aea;\n  color: #fff; }\n\n.item.item-dark {\n  border-color: #111;\n  background-color: #444;\n  color: #fff; }\n\n.item[ng-click]:hover {\n  cursor: pointer; }\n\n.list-borderless .item,\n.item-borderless {\n  border-width: 0; }\n\n.item.active,\n.item.activated,\n.item-complex.active .item-content,\n.item-complex.activated .item-content,\n.item .item-content.active,\n.item .item-content.activated {\n  border-color: #ccc;\n  background-color: #D9D9D9; }\n\n.item.active.item-complex > .item-content,\n.item.activated.item-complex > .item-content,\n.item-complex.active .item-content.item-complex > .item-content,\n.item-complex.activated .item-content.item-complex > .item-content,\n.item .item-content.active.item-complex > .item-content,\n.item .item-content.activated.item-complex > .item-content {\n  border-color: #ccc;\n  background-color: #D9D9D9; }\n\n.item.active.item-light,\n.item.activated.item-light,\n.item-complex.active .item-content.item-light,\n.item-complex.activated .item-content.item-light,\n.item .item-content.active.item-light,\n.item .item-content.activated.item-light {\n  border-color: #ccc;\n  background-color: #fafafa; }\n\n.item.active.item-light.item-complex > .item-content,\n.item.activated.item-light.item-complex > .item-content,\n.item-complex.active .item-content.item-light.item-complex > .item-content,\n.item-complex.activated .item-content.item-light.item-complex > .item-content,\n.item .item-content.active.item-light.item-complex > .item-content,\n.item .item-content.activated.item-light.item-complex > .item-content {\n  border-color: #ccc;\n  background-color: #fafafa; }\n\n.item.active.item-stable,\n.item.activated.item-stable,\n.item-complex.active .item-content.item-stable,\n.item-complex.activated .item-content.item-stable,\n.item .item-content.active.item-stable,\n.item .item-content.activated.item-stable {\n  border-color: #a2a2a2;\n  background-color: #e5e5e5; }\n\n.item.active.item-stable.item-complex > .item-content,\n.item.activated.item-stable.item-complex > .item-content,\n.item-complex.active .item-content.item-stable.item-complex > .item-content,\n.item-complex.activated .item-content.item-stable.item-complex > .item-content,\n.item .item-content.active.item-stable.item-complex > .item-content,\n.item .item-content.activated.item-stable.item-complex > .item-content {\n  border-color: #a2a2a2;\n  background-color: #e5e5e5; }\n\n.item.active.item-positive,\n.item.activated.item-positive,\n.item-complex.active .item-content.item-positive,\n.item-complex.activated .item-content.item-positive,\n.item .item-content.active.item-positive,\n.item .item-content.activated.item-positive {\n  border-color: #0c60ee;\n  background-color: #0c60ee; }\n\n.item.active.item-positive.item-complex > .item-content,\n.item.activated.item-positive.item-complex > .item-content,\n.item-complex.active .item-content.item-positive.item-complex > .item-content,\n.item-complex.activated .item-content.item-positive.item-complex > .item-content,\n.item .item-content.active.item-positive.item-complex > .item-content,\n.item .item-content.activated.item-positive.item-complex > .item-content {\n  border-color: #0c60ee;\n  background-color: #0c60ee; }\n\n.item.active.item-calm,\n.item.activated.item-calm,\n.item-complex.active .item-content.item-calm,\n.item-complex.activated .item-content.item-calm,\n.item .item-content.active.item-calm,\n.item .item-content.activated.item-calm {\n  border-color: #0a9dc7;\n  background-color: #0a9dc7; }\n\n.item.active.item-calm.item-complex > .item-content,\n.item.activated.item-calm.item-complex > .item-content,\n.item-complex.active .item-content.item-calm.item-complex > .item-content,\n.item-complex.activated .item-content.item-calm.item-complex > .item-content,\n.item .item-content.active.item-calm.item-complex > .item-content,\n.item .item-content.activated.item-calm.item-complex > .item-content {\n  border-color: #0a9dc7;\n  background-color: #0a9dc7; }\n\n.item.active.item-assertive,\n.item.activated.item-assertive,\n.item-complex.active .item-content.item-assertive,\n.item-complex.activated .item-content.item-assertive,\n.item .item-content.active.item-assertive,\n.item .item-content.activated.item-assertive {\n  border-color: #e42112;\n  background-color: #e42112; }\n\n.item.active.item-assertive.item-complex > .item-content,\n.item.activated.item-assertive.item-complex > .item-content,\n.item-complex.active .item-content.item-assertive.item-complex > .item-content,\n.item-complex.activated .item-content.item-assertive.item-complex > .item-content,\n.item .item-content.active.item-assertive.item-complex > .item-content,\n.item .item-content.activated.item-assertive.item-complex > .item-content {\n  border-color: #e42112;\n  background-color: #e42112; }\n\n.item.active.item-balanced,\n.item.activated.item-balanced,\n.item-complex.active .item-content.item-balanced,\n.item-complex.activated .item-content.item-balanced,\n.item .item-content.active.item-balanced,\n.item .item-content.activated.item-balanced {\n  border-color: #28a54c;\n  background-color: #28a54c; }\n\n.item.active.item-balanced.item-complex > .item-content,\n.item.activated.item-balanced.item-complex > .item-content,\n.item-complex.active .item-content.item-balanced.item-complex > .item-content,\n.item-complex.activated .item-content.item-balanced.item-complex > .item-content,\n.item .item-content.active.item-balanced.item-complex > .item-content,\n.item .item-content.activated.item-balanced.item-complex > .item-content {\n  border-color: #28a54c;\n  background-color: #28a54c; }\n\n.item.active.item-energized,\n.item.activated.item-energized,\n.item-complex.active .item-content.item-energized,\n.item-complex.activated .item-content.item-energized,\n.item .item-content.active.item-energized,\n.item .item-content.activated.item-energized {\n  border-color: #e6b500;\n  background-color: #e6b500; }\n\n.item.active.item-energized.item-complex > .item-content,\n.item.activated.item-energized.item-complex > .item-content,\n.item-complex.active .item-content.item-energized.item-complex > .item-content,\n.item-complex.activated .item-content.item-energized.item-complex > .item-content,\n.item .item-content.active.item-energized.item-complex > .item-content,\n.item .item-content.activated.item-energized.item-complex > .item-content {\n  border-color: #e6b500;\n  background-color: #e6b500; }\n\n.item.active.item-royal,\n.item.activated.item-royal,\n.item-complex.active .item-content.item-royal,\n.item-complex.activated .item-content.item-royal,\n.item .item-content.active.item-royal,\n.item .item-content.activated.item-royal {\n  border-color: #6b46e5;\n  background-color: #6b46e5; }\n\n.item.active.item-royal.item-complex > .item-content,\n.item.activated.item-royal.item-complex > .item-content,\n.item-complex.active .item-content.item-royal.item-complex > .item-content,\n.item-complex.activated .item-content.item-royal.item-complex > .item-content,\n.item .item-content.active.item-royal.item-complex > .item-content,\n.item .item-content.activated.item-royal.item-complex > .item-content {\n  border-color: #6b46e5;\n  background-color: #6b46e5; }\n\n.item.active.item-dark,\n.item.activated.item-dark,\n.item-complex.active .item-content.item-dark,\n.item-complex.activated .item-content.item-dark,\n.item .item-content.active.item-dark,\n.item .item-content.activated.item-dark {\n  border-color: #000;\n  background-color: #262626; }\n\n.item.active.item-dark.item-complex > .item-content,\n.item.activated.item-dark.item-complex > .item-content,\n.item-complex.active .item-content.item-dark.item-complex > .item-content,\n.item-complex.activated .item-content.item-dark.item-complex > .item-content,\n.item .item-content.active.item-dark.item-complex > .item-content,\n.item .item-content.activated.item-dark.item-complex > .item-content {\n  border-color: #000;\n  background-color: #262626; }\n\n.item,\n.item h1,\n.item h2,\n.item h3,\n.item h4,\n.item h5,\n.item h6,\n.item p,\n.item-content,\n.item-content h1,\n.item-content h2,\n.item-content h3,\n.item-content h4,\n.item-content h5,\n.item-content h6,\n.item-content p {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap; }\n\na.item {\n  color: inherit;\n  text-decoration: none; }\n\na.item:hover, a.item:focus {\n  text-decoration: none; }\n\n/**\n * Complex Items\n * --------------------------------------------------\n * Adding .item-complex allows the .item to be slidable and\n * have options underneath the button, but also requires an\n * additional .item-content element inside .item.\n * Basically .item-complex removes any default settings which\n * .item added, so that .item-content looks them as just .item.\n */\n.item-complex,\na.item.item-complex,\nbutton.item.item-complex {\n  padding: 0; }\n\n.item-complex .item-content,\n.item-radio .item-content {\n  position: relative;\n  z-index: 2;\n  padding: 16px 49px 16px 16px;\n  border: none;\n  background-color: #fff; }\n\na.item-content {\n  display: block;\n  color: inherit;\n  text-decoration: none; }\n\n.item-text-wrap .item,\n.item-text-wrap .item-content,\n.item-text-wrap,\n.item-text-wrap h1,\n.item-text-wrap h2,\n.item-text-wrap h3,\n.item-text-wrap h4,\n.item-text-wrap h5,\n.item-text-wrap h6,\n.item-text-wrap p,\n.item-complex.item-text-wrap .item-content,\n.item-body h1,\n.item-body h2,\n.item-body h3,\n.item-body h4,\n.item-body h5,\n.item-body h6,\n.item-body p {\n  overflow: visible;\n  white-space: normal; }\n\n.item-complex.item-text-wrap,\n.item-complex.item-text-wrap h1,\n.item-complex.item-text-wrap h2,\n.item-complex.item-text-wrap h3,\n.item-complex.item-text-wrap h4,\n.item-complex.item-text-wrap h5,\n.item-complex.item-text-wrap h6,\n.item-complex.item-text-wrap p {\n  overflow: visible;\n  white-space: normal; }\n\n.item-complex.item-light > .item-content {\n  border-color: #ddd;\n  background-color: #fff;\n  color: #444; }\n\n.item-complex.item-light > .item-content.active, .item-complex.item-light > .item-content:active {\n  border-color: #ccc;\n  background-color: #fafafa; }\n\n.item-complex.item-light > .item-content.active.item-complex > .item-content, .item-complex.item-light > .item-content:active.item-complex > .item-content {\n  border-color: #ccc;\n  background-color: #fafafa; }\n\n.item-complex.item-stable > .item-content {\n  border-color: #b2b2b2;\n  background-color: #f8f8f8;\n  color: #444; }\n\n.item-complex.item-stable > .item-content.active, .item-complex.item-stable > .item-content:active {\n  border-color: #a2a2a2;\n  background-color: #e5e5e5; }\n\n.item-complex.item-stable > .item-content.active.item-complex > .item-content, .item-complex.item-stable > .item-content:active.item-complex > .item-content {\n  border-color: #a2a2a2;\n  background-color: #e5e5e5; }\n\n.item-complex.item-positive > .item-content {\n  border-color: #0c60ee;\n  background-color: #387ef5;\n  color: #fff; }\n\n.item-complex.item-positive > .item-content.active, .item-complex.item-positive > .item-content:active {\n  border-color: #0c60ee;\n  background-color: #0c60ee; }\n\n.item-complex.item-positive > .item-content.active.item-complex > .item-content, .item-complex.item-positive > .item-content:active.item-complex > .item-content {\n  border-color: #0c60ee;\n  background-color: #0c60ee; }\n\n.item-complex.item-calm > .item-content {\n  border-color: #0a9dc7;\n  background-color: #11c1f3;\n  color: #fff; }\n\n.item-complex.item-calm > .item-content.active, .item-complex.item-calm > .item-content:active {\n  border-color: #0a9dc7;\n  background-color: #0a9dc7; }\n\n.item-complex.item-calm > .item-content.active.item-complex > .item-content, .item-complex.item-calm > .item-content:active.item-complex > .item-content {\n  border-color: #0a9dc7;\n  background-color: #0a9dc7; }\n\n.item-complex.item-assertive > .item-content {\n  border-color: #e42112;\n  background-color: #ef473a;\n  color: #fff; }\n\n.item-complex.item-assertive > .item-content.active, .item-complex.item-assertive > .item-content:active {\n  border-color: #e42112;\n  background-color: #e42112; }\n\n.item-complex.item-assertive > .item-content.active.item-complex > .item-content, .item-complex.item-assertive > .item-content:active.item-complex > .item-content {\n  border-color: #e42112;\n  background-color: #e42112; }\n\n.item-complex.item-balanced > .item-content {\n  border-color: #28a54c;\n  background-color: #33cd5f;\n  color: #fff; }\n\n.item-complex.item-balanced > .item-content.active, .item-complex.item-balanced > .item-content:active {\n  border-color: #28a54c;\n  background-color: #28a54c; }\n\n.item-complex.item-balanced > .item-content.active.item-complex > .item-content, .item-complex.item-balanced > .item-content:active.item-complex > .item-content {\n  border-color: #28a54c;\n  background-color: #28a54c; }\n\n.item-complex.item-energized > .item-content {\n  border-color: #e6b500;\n  background-color: #ffc900;\n  color: #fff; }\n\n.item-complex.item-energized > .item-content.active, .item-complex.item-energized > .item-content:active {\n  border-color: #e6b500;\n  background-color: #e6b500; }\n\n.item-complex.item-energized > .item-content.active.item-complex > .item-content, .item-complex.item-energized > .item-content:active.item-complex > .item-content {\n  border-color: #e6b500;\n  background-color: #e6b500; }\n\n.item-complex.item-royal > .item-content {\n  border-color: #6b46e5;\n  background-color: #886aea;\n  color: #fff; }\n\n.item-complex.item-royal > .item-content.active, .item-complex.item-royal > .item-content:active {\n  border-color: #6b46e5;\n  background-color: #6b46e5; }\n\n.item-complex.item-royal > .item-content.active.item-complex > .item-content, .item-complex.item-royal > .item-content:active.item-complex > .item-content {\n  border-color: #6b46e5;\n  background-color: #6b46e5; }\n\n.item-complex.item-dark > .item-content {\n  border-color: #111;\n  background-color: #444;\n  color: #fff; }\n\n.item-complex.item-dark > .item-content.active, .item-complex.item-dark > .item-content:active {\n  border-color: #000;\n  background-color: #262626; }\n\n.item-complex.item-dark > .item-content.active.item-complex > .item-content, .item-complex.item-dark > .item-content:active.item-complex > .item-content {\n  border-color: #000;\n  background-color: #262626; }\n\n/**\n * Item Icons\n * --------------------------------------------------\n */\n.item-icon-left .icon,\n.item-icon-right .icon {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  align-items: center;\n  position: absolute;\n  top: 0;\n  height: 100%;\n  font-size: 32px; }\n\n.item-icon-left .icon:before,\n.item-icon-right .icon:before {\n  display: block;\n  width: 32px;\n  text-align: center; }\n\n.item .fill-icon {\n  min-width: 30px;\n  min-height: 30px;\n  font-size: 28px; }\n\n.item-icon-left {\n  padding-left: 54px; }\n\n.item-icon-left .icon {\n  left: 11px; }\n\n.item-complex.item-icon-left {\n  padding-left: 0; }\n\n.item-complex.item-icon-left .item-content {\n  padding-left: 54px; }\n\n.item-icon-right {\n  padding-right: 54px; }\n\n.item-icon-right .icon {\n  right: 11px; }\n\n.item-complex.item-icon-right {\n  padding-right: 0; }\n\n.item-complex.item-icon-right .item-content {\n  padding-right: 54px; }\n\n.item-icon-left.item-icon-right .icon:first-child {\n  right: auto; }\n\n.item-icon-left.item-icon-right .icon:last-child,\n.item-icon-left .item-delete .icon {\n  left: auto; }\n\n.item-icon-left .icon-accessory,\n.item-icon-right .icon-accessory {\n  color: #ccc;\n  font-size: 16px; }\n\n.item-icon-left .icon-accessory {\n  left: 3px; }\n\n.item-icon-right .icon-accessory {\n  right: 3px; }\n\n/**\n * Item Button\n * --------------------------------------------------\n * An item button is a child button inside an .item (not the entire .item)\n */\n.item-button-left {\n  padding-left: 72px; }\n\n.item-button-left > .button,\n.item-button-left .item-content > .button {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  align-items: center;\n  position: absolute;\n  top: 8px;\n  left: 11px;\n  min-width: 34px;\n  min-height: 34px;\n  font-size: 18px;\n  line-height: 32px; }\n\n.item-button-left > .button .icon:before,\n.item-button-left .item-content > .button .icon:before {\n  position: relative;\n  left: auto;\n  width: auto;\n  line-height: 31px; }\n\n.item-button-left > .button > .button,\n.item-button-left .item-content > .button > .button {\n  margin: 0px 2px;\n  min-height: 34px;\n  font-size: 18px;\n  line-height: 32px; }\n\n.item-button-right,\na.item.item-button-right,\nbutton.item.item-button-right {\n  padding-right: 80px; }\n\n.item-button-right > .button,\n.item-button-right .item-content > .button,\n.item-button-right > .buttons,\n.item-button-right .item-content > .buttons {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  align-items: center;\n  position: absolute;\n  top: 8px;\n  right: 16px;\n  min-width: 34px;\n  min-height: 34px;\n  font-size: 18px;\n  line-height: 32px; }\n\n.item-button-right > .button .icon:before,\n.item-button-right .item-content > .button .icon:before,\n.item-button-right > .buttons .icon:before,\n.item-button-right .item-content > .buttons .icon:before {\n  position: relative;\n  left: auto;\n  width: auto;\n  line-height: 31px; }\n\n.item-button-right > .button > .button,\n.item-button-right .item-content > .button > .button,\n.item-button-right > .buttons > .button,\n.item-button-right .item-content > .buttons > .button {\n  margin: 0px 2px;\n  min-width: 34px;\n  min-height: 34px;\n  font-size: 18px;\n  line-height: 32px; }\n\n.item-avatar,\n.item-avatar .item-content,\n.item-avatar-left,\n.item-avatar-left .item-content {\n  padding-left: 72px;\n  min-height: 72px; }\n\n.item-avatar > img:first-child,\n.item-avatar .item-image,\n.item-avatar .item-content > img:first-child,\n.item-avatar .item-content .item-image,\n.item-avatar-left > img:first-child,\n.item-avatar-left .item-image,\n.item-avatar-left .item-content > img:first-child,\n.item-avatar-left .item-content .item-image {\n  position: absolute;\n  top: 16px;\n  left: 16px;\n  max-width: 40px;\n  max-height: 40px;\n  width: 100%;\n  height: 100%;\n  border-radius: 50%; }\n\n.item-avatar-right,\n.item-avatar-right .item-content {\n  padding-right: 72px;\n  min-height: 72px; }\n\n.item-avatar-right > img:first-child,\n.item-avatar-right .item-image,\n.item-avatar-right .item-content > img:first-child,\n.item-avatar-right .item-content .item-image {\n  position: absolute;\n  top: 16px;\n  right: 16px;\n  max-width: 40px;\n  max-height: 40px;\n  width: 100%;\n  height: 100%;\n  border-radius: 50%; }\n\n.item-thumbnail-left,\n.item-thumbnail-left .item-content {\n  padding-top: 8px;\n  padding-left: 106px;\n  min-height: 100px; }\n\n.item-thumbnail-left > img:first-child,\n.item-thumbnail-left .item-image,\n.item-thumbnail-left .item-content > img:first-child,\n.item-thumbnail-left .item-content .item-image {\n  position: absolute;\n  top: 10px;\n  left: 10px;\n  max-width: 80px;\n  max-height: 80px;\n  width: 100%;\n  height: 100%; }\n\n.item-avatar.item-complex,\n.item-avatar-left.item-complex,\n.item-thumbnail-left.item-complex {\n  padding-top: 0;\n  padding-left: 0; }\n\n.item-thumbnail-right,\n.item-thumbnail-right .item-content {\n  padding-top: 8px;\n  padding-right: 106px;\n  min-height: 100px; }\n\n.item-thumbnail-right > img:first-child,\n.item-thumbnail-right .item-image,\n.item-thumbnail-right .item-content > img:first-child,\n.item-thumbnail-right .item-content .item-image {\n  position: absolute;\n  top: 10px;\n  right: 10px;\n  max-width: 80px;\n  max-height: 80px;\n  width: 100%;\n  height: 100%; }\n\n.item-avatar-right.item-complex,\n.item-thumbnail-right.item-complex {\n  padding-top: 0;\n  padding-right: 0; }\n\n.item-image {\n  padding: 0;\n  text-align: center; }\n\n.item-image img:first-child, .item-image .list-img {\n  width: 100%;\n  vertical-align: middle; }\n\n.item-body {\n  overflow: auto;\n  padding: 16px;\n  text-overflow: inherit;\n  white-space: normal; }\n\n.item-body h1, .item-body h2, .item-body h3, .item-body h4, .item-body h5, .item-body h6, .item-body p {\n  margin-top: 16px;\n  margin-bottom: 16px; }\n\n.item-divider {\n  padding-top: 8px;\n  padding-bottom: 8px;\n  min-height: 30px;\n  background-color: #f5f5f5;\n  color: #222;\n  font-weight: 500; }\n\n.platform-ios .item-divider-platform,\n.item-divider-ios {\n  padding-top: 26px;\n  text-transform: uppercase;\n  font-weight: 300;\n  font-size: 13px;\n  background-color: #efeff4;\n  color: #555; }\n\n.platform-android .item-divider-platform,\n.item-divider-android {\n  font-weight: 300;\n  font-size: 13px; }\n\n.item-note {\n  float: right;\n  color: #aaa;\n  font-size: 14px; }\n\n.item-left-editable .item-content,\n.item-right-editable .item-content {\n  -webkit-transition-duration: 250ms;\n  transition-duration: 250ms;\n  -webkit-transition-timing-function: ease-in-out;\n  transition-timing-function: ease-in-out;\n  -webkit-transition-property: -webkit-transform;\n  -moz-transition-property: -moz-transform;\n  transition-property: transform; }\n\n.list-left-editing .item-left-editable .item-content,\n.item-left-editing.item-left-editable .item-content {\n  -webkit-transform: translate3d(50px, 0, 0);\n  transform: translate3d(50px, 0, 0); }\n\n.item-remove-animate.ng-leave {\n  -webkit-transition-duration: 300ms;\n  transition-duration: 300ms; }\n\n.item-remove-animate.ng-leave .item-content, .item-remove-animate.ng-leave:last-of-type {\n  -webkit-transition-duration: 300ms;\n  transition-duration: 300ms;\n  -webkit-transition-timing-function: ease-in;\n  transition-timing-function: ease-in;\n  -webkit-transition-property: all;\n  transition-property: all; }\n\n.item-remove-animate.ng-leave.ng-leave-active .item-content {\n  opacity: 0;\n  -webkit-transform: translate3d(-100%, 0, 0) !important;\n  transform: translate3d(-100%, 0, 0) !important; }\n\n.item-remove-animate.ng-leave.ng-leave-active:last-of-type {\n  opacity: 0; }\n\n.item-remove-animate.ng-leave.ng-leave-active ~ ion-item:not(.ng-leave) {\n  -webkit-transform: translate3d(0, -webkit-calc(-100% + 1px), 0);\n  transform: translate3d(0, calc(-100% + 1px), 0);\n  -webkit-transition-duration: 300ms;\n  transition-duration: 300ms;\n  -webkit-transition-timing-function: cubic-bezier(0.25, 0.81, 0.24, 1);\n  transition-timing-function: cubic-bezier(0.25, 0.81, 0.24, 1);\n  -webkit-transition-property: all;\n  transition-property: all; }\n\n.item-left-edit {\n  -webkit-transition: all ease-in-out 125ms;\n  transition: all ease-in-out 125ms;\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 0;\n  width: 50px;\n  height: 100%;\n  line-height: 100%;\n  display: none;\n  opacity: 0;\n  -webkit-transform: translate3d(-21px, 0, 0);\n  transform: translate3d(-21px, 0, 0); }\n\n.item-left-edit .button {\n  height: 100%; }\n\n.item-left-edit .button.icon {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  align-items: center;\n  position: absolute;\n  top: 0;\n  height: 100%; }\n\n.item-left-edit.visible {\n  display: block; }\n\n.item-left-edit.visible.active {\n  opacity: 1;\n  -webkit-transform: translate3d(8px, 0, 0);\n  transform: translate3d(8px, 0, 0); }\n\n.list-left-editing .item-left-edit {\n  -webkit-transition-delay: 125ms;\n  transition-delay: 125ms; }\n\n.item-delete .button.icon {\n  color: #ef473a;\n  font-size: 24px; }\n\n.item-delete .button.icon:hover {\n  opacity: .7; }\n\n.item-right-edit {\n  -webkit-transition: all ease-in-out 250ms;\n  transition: all ease-in-out 250ms;\n  position: absolute;\n  top: 0;\n  right: 0;\n  z-index: 3;\n  width: 75px;\n  height: 100%;\n  background: inherit;\n  padding-left: 20px;\n  display: block;\n  opacity: 0;\n  -webkit-transform: translate3d(75px, 0, 0);\n  transform: translate3d(75px, 0, 0); }\n\n.item-right-edit .button {\n  min-width: 50px;\n  height: 100%; }\n\n.item-right-edit .button.icon {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  align-items: center;\n  position: absolute;\n  top: 0;\n  height: 100%;\n  font-size: 32px; }\n\n.item-right-edit.visible {\n  display: block; }\n\n.item-right-edit.visible.active {\n  opacity: 1;\n  -webkit-transform: translate3d(0, 0, 0);\n  transform: translate3d(0, 0, 0); }\n\n.item-reorder .button.icon {\n  color: #444;\n  font-size: 32px; }\n\n.item-reordering {\n  position: absolute;\n  left: 0;\n  top: 0;\n  z-index: 9;\n  width: 100%;\n  box-shadow: 0px 0px 10px 0px #aaa; }\n\n.item-reordering .item-reorder {\n  z-index: 9; }\n\n.item-placeholder {\n  opacity: 0.7; }\n\n/**\n * The hidden right-side buttons that can be exposed under a list item\n * with dragging.\n */\n.item-options {\n  position: absolute;\n  top: 0;\n  right: 0;\n  z-index: 1;\n  height: 100%; }\n\n.item-options .button {\n  height: 100%;\n  border: none;\n  border-radius: 0;\n  display: -webkit-inline-box;\n  display: -webkit-inline-flex;\n  display: -moz-inline-flex;\n  display: -ms-inline-flexbox;\n  display: inline-flex;\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  align-items: center; }\n\n.item-options .button:before {\n  margin: 0 auto; }\n\n/**\n * Lists\n * --------------------------------------------------\n */\n.list {\n  position: relative;\n  padding-top: 1px;\n  padding-bottom: 1px;\n  padding-left: 0;\n  margin-bottom: 20px; }\n\n.list:last-child {\n  margin-bottom: 0px; }\n\n.list:last-child.card {\n  margin-bottom: 40px; }\n\n/**\n * List Header\n * --------------------------------------------------\n */\n.list-header {\n  margin-top: 20px;\n  padding: 5px 15px;\n  background-color: transparent;\n  color: #222;\n  font-weight: bold; }\n\n.card.list .list-item {\n  padding-right: 1px;\n  padding-left: 1px; }\n\n/**\n * Cards and Inset Lists\n * --------------------------------------------------\n * A card and list-inset are close to the same thing, except a card as a box shadow.\n */\n.card,\n.list-inset {\n  overflow: hidden;\n  margin: 20px 10px;\n  border-radius: 2px;\n  background-color: #fff; }\n\n.card {\n  padding-top: 1px;\n  padding-bottom: 1px;\n  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); }\n\n.card .item {\n  border-left: 0;\n  border-right: 0; }\n\n.card .item:first-child {\n  border-top: 0; }\n\n.card .item:last-child {\n  border-bottom: 0; }\n\n.padding .card, .padding .list-inset {\n  margin-left: 0;\n  margin-right: 0; }\n\n.card .item:first-child,\n.list-inset .item:first-child,\n.padding > .list .item:first-child {\n  border-top-left-radius: 2px;\n  border-top-right-radius: 2px; }\n\n.card .item:first-child .item-content,\n.list-inset .item:first-child .item-content,\n.padding > .list .item:first-child .item-content {\n  border-top-left-radius: 2px;\n  border-top-right-radius: 2px; }\n\n.card .item:last-child,\n.list-inset .item:last-child,\n.padding > .list .item:last-child {\n  border-bottom-right-radius: 2px;\n  border-bottom-left-radius: 2px; }\n\n.card .item:last-child .item-content,\n.list-inset .item:last-child .item-content,\n.padding > .list .item:last-child .item-content {\n  border-bottom-right-radius: 2px;\n  border-bottom-left-radius: 2px; }\n\n.card .item:last-child,\n.list-inset .item:last-child {\n  margin-bottom: -1px; }\n\n.card .item,\n.list-inset .item,\n.padding > .list .item,\n.padding-horizontal > .list .item {\n  margin-right: 0;\n  margin-left: 0; }\n\n.card .item.item-input input,\n.list-inset .item.item-input input,\n.padding > .list .item.item-input input,\n.padding-horizontal > .list .item.item-input input {\n  padding-right: 44px; }\n\n.padding-left > .list .item {\n  margin-left: 0; }\n\n.padding-right > .list .item {\n  margin-right: 0; }\n\n/**\n * Badges\n * --------------------------------------------------\n */\n.badge {\n  background-color: transparent;\n  color: #AAAAAA;\n  z-index: 1;\n  display: inline-block;\n  padding: 3px 8px;\n  min-width: 10px;\n  border-radius: 10px;\n  vertical-align: baseline;\n  text-align: center;\n  white-space: nowrap;\n  font-weight: bold;\n  font-size: 14px;\n  line-height: 16px; }\n\n.badge:empty {\n  display: none; }\n\n.tabs .tab-item .badge.badge-light,\n.badge.badge-light {\n  background-color: #fff;\n  color: #444; }\n\n.tabs .tab-item .badge.badge-stable,\n.badge.badge-stable {\n  background-color: #f8f8f8;\n  color: #444; }\n\n.tabs .tab-item .badge.badge-positive,\n.badge.badge-positive {\n  background-color: #387ef5;\n  color: #fff; }\n\n.tabs .tab-item .badge.badge-calm,\n.badge.badge-calm {\n  background-color: #11c1f3;\n  color: #fff; }\n\n.tabs .tab-item .badge.badge-assertive,\n.badge.badge-assertive {\n  background-color: #ef473a;\n  color: #fff; }\n\n.tabs .tab-item .badge.badge-balanced,\n.badge.badge-balanced {\n  background-color: #33cd5f;\n  color: #fff; }\n\n.tabs .tab-item .badge.badge-energized,\n.badge.badge-energized {\n  background-color: #ffc900;\n  color: #fff; }\n\n.tabs .tab-item .badge.badge-royal,\n.badge.badge-royal {\n  background-color: #886aea;\n  color: #fff; }\n\n.tabs .tab-item .badge.badge-dark,\n.badge.badge-dark {\n  background-color: #444;\n  color: #fff; }\n\n.button .badge {\n  position: relative;\n  top: -1px; }\n\n/**\n * Slide Box\n * --------------------------------------------------\n */\n.slider {\n  position: relative;\n  visibility: hidden;\n  overflow: hidden; }\n\n.slider-slides {\n  position: relative;\n  height: 100%; }\n\n.slider-slide {\n  position: relative;\n  display: block;\n  float: left;\n  width: 100%;\n  height: 100%;\n  vertical-align: top; }\n\n.slider-slide-image > img {\n  width: 100%; }\n\n.slider-pager {\n  position: absolute;\n  bottom: 20px;\n  z-index: 1;\n  width: 100%;\n  height: 15px;\n  text-align: center; }\n\n.slider-pager .slider-pager-page {\n  display: inline-block;\n  margin: 0px 3px;\n  width: 15px;\n  color: #000;\n  text-decoration: none;\n  opacity: 0.3; }\n\n.slider-pager .slider-pager-page.active {\n  -webkit-transition: opacity 0.4s ease-in;\n  transition: opacity 0.4s ease-in;\n  opacity: 1; }\n\n.slider-slide.ng-enter, .slider-slide.ng-leave, .slider-slide.ng-animate,\n.slider-pager-page.ng-enter,\n.slider-pager-page.ng-leave,\n.slider-pager-page.ng-animate {\n  -webkit-transition: none !important;\n  transition: none !important; }\n\n.slider-slide.ng-animate,\n.slider-pager-page.ng-animate {\n  -webkit-animation: none 0s;\n  animation: none 0s; }\n\n/**\n * Swiper 3.2.7\n * Most modern mobile touch slider and framework with hardware accelerated transitions\n *\n * http://www.idangero.us/swiper/\n *\n * Copyright 2015, Vladimir Kharlampidi\n * The iDangero.us\n * http://www.idangero.us/\n *\n * Licensed under MIT\n *\n * Released on: December 7, 2015\n */\n.swiper-container {\n  margin: 0 auto;\n  position: relative;\n  overflow: hidden;\n  /* Fix of Webkit flickering */\n  z-index: 1; }\n\n.swiper-container-no-flexbox .swiper-slide {\n  float: left; }\n\n.swiper-container-vertical > .swiper-wrapper {\n  -webkit-box-orient: vertical;\n  -moz-box-orient: vertical;\n  -ms-flex-direction: column;\n  -webkit-flex-direction: column;\n  flex-direction: column; }\n\n.swiper-wrapper {\n  position: relative;\n  width: 100%;\n  height: 100%;\n  z-index: 1;\n  display: -webkit-box;\n  display: -moz-box;\n  display: -ms-flexbox;\n  display: -webkit-flex;\n  display: flex;\n  -webkit-transition-property: -webkit-transform;\n  -moz-transition-property: -moz-transform;\n  -o-transition-property: -o-transform;\n  -ms-transition-property: -ms-transform;\n  transition-property: transform;\n  -webkit-box-sizing: content-box;\n  -moz-box-sizing: content-box;\n  box-sizing: content-box; }\n\n.swiper-container-android .swiper-slide,\n.swiper-wrapper {\n  -webkit-transform: translate3d(0px, 0, 0);\n  -moz-transform: translate3d(0px, 0, 0);\n  -o-transform: translate(0px, 0px);\n  -ms-transform: translate3d(0px, 0, 0);\n  transform: translate3d(0px, 0, 0); }\n\n.swiper-container-multirow > .swiper-wrapper {\n  -webkit-box-lines: multiple;\n  -moz-box-lines: multiple;\n  -ms-flex-wrap: wrap;\n  -webkit-flex-wrap: wrap;\n  flex-wrap: wrap; }\n\n.swiper-container-free-mode > .swiper-wrapper {\n  -webkit-transition-timing-function: ease-out;\n  -moz-transition-timing-function: ease-out;\n  -ms-transition-timing-function: ease-out;\n  -o-transition-timing-function: ease-out;\n  transition-timing-function: ease-out;\n  margin: 0 auto; }\n\n.swiper-slide {\n  display: block;\n  -webkit-flex-shrink: 0;\n  -ms-flex: 0 0 auto;\n  flex-shrink: 0;\n  width: 100%;\n  height: 100%;\n  position: relative; }\n\n/* Auto Height */\n.swiper-container-autoheight,\n.swiper-container-autoheight .swiper-slide {\n  height: auto; }\n\n.swiper-container-autoheight .swiper-wrapper {\n  -webkit-box-align: start;\n  -ms-flex-align: start;\n  -webkit-align-items: flex-start;\n  align-items: flex-start;\n  -webkit-transition-property: -webkit-transform, height;\n  -moz-transition-property: -moz-transform;\n  -o-transition-property: -o-transform;\n  -ms-transition-property: -ms-transform;\n  transition-property: transform, height; }\n\n/* a11y */\n.swiper-container .swiper-notification {\n  position: absolute;\n  left: 0;\n  top: 0;\n  pointer-events: none;\n  opacity: 0;\n  z-index: -1000; }\n\n/* IE10 Windows Phone 8 Fixes */\n.swiper-wp8-horizontal {\n  -ms-touch-action: pan-y;\n  touch-action: pan-y; }\n\n.swiper-wp8-vertical {\n  -ms-touch-action: pan-x;\n  touch-action: pan-x; }\n\n/* Arrows */\n.swiper-button-prev,\n.swiper-button-next {\n  position: absolute;\n  top: 50%;\n  width: 27px;\n  height: 44px;\n  margin-top: -22px;\n  z-index: 10;\n  cursor: pointer;\n  -moz-background-size: 27px 44px;\n  -webkit-background-size: 27px 44px;\n  background-size: 27px 44px;\n  background-position: center;\n  background-repeat: no-repeat; }\n\n.swiper-button-prev.swiper-button-disabled,\n.swiper-button-next.swiper-button-disabled {\n  opacity: 0.35;\n  cursor: auto;\n  pointer-events: none; }\n\n.swiper-button-prev,\n.swiper-container-rtl .swiper-button-next {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E\");\n  left: 10px;\n  right: auto; }\n\n.swiper-button-prev.swiper-button-black,\n.swiper-container-rtl .swiper-button-next.swiper-button-black {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E\"); }\n\n.swiper-button-prev.swiper-button-white,\n.swiper-container-rtl .swiper-button-next.swiper-button-white {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E\"); }\n\n.swiper-button-next,\n.swiper-container-rtl .swiper-button-prev {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E\");\n  right: 10px;\n  left: auto; }\n\n.swiper-button-next.swiper-button-black,\n.swiper-container-rtl .swiper-button-prev.swiper-button-black {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E\"); }\n\n.swiper-button-next.swiper-button-white,\n.swiper-container-rtl .swiper-button-prev.swiper-button-white {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E\"); }\n\n/* Pagination Styles */\n.swiper-pagination {\n  position: absolute;\n  text-align: center;\n  -webkit-transition: 300ms;\n  -moz-transition: 300ms;\n  -o-transition: 300ms;\n  transition: 300ms;\n  -webkit-transform: translate3d(0, 0, 0);\n  -ms-transform: translate3d(0, 0, 0);\n  -o-transform: translate3d(0, 0, 0);\n  transform: translate3d(0, 0, 0);\n  z-index: 10; }\n\n.swiper-pagination.swiper-pagination-hidden {\n  opacity: 0; }\n\n.swiper-pagination-bullet {\n  width: 8px;\n  height: 8px;\n  display: inline-block;\n  border-radius: 100%;\n  background: #000;\n  opacity: 0.2; }\n\nbutton.swiper-pagination-bullet {\n  border: none;\n  margin: 0;\n  padding: 0;\n  box-shadow: none;\n  -moz-appearance: none;\n  -ms-appearance: none;\n  -webkit-appearance: none;\n  appearance: none; }\n\n.swiper-pagination-clickable .swiper-pagination-bullet {\n  cursor: pointer; }\n\n.swiper-pagination-white .swiper-pagination-bullet {\n  background: #fff; }\n\n.swiper-pagination-bullet-active {\n  opacity: 1; }\n\n.swiper-pagination-white .swiper-pagination-bullet-active {\n  background: #fff; }\n\n.swiper-pagination-black .swiper-pagination-bullet-active {\n  background: #000; }\n\n.swiper-container-vertical > .swiper-pagination {\n  right: 10px;\n  top: 50%;\n  -webkit-transform: translate3d(0px, -50%, 0);\n  -moz-transform: translate3d(0px, -50%, 0);\n  -o-transform: translate(0px, -50%);\n  -ms-transform: translate3d(0px, -50%, 0);\n  transform: translate3d(0px, -50%, 0); }\n\n.swiper-container-vertical > .swiper-pagination .swiper-pagination-bullet {\n  margin: 5px 0;\n  display: block; }\n\n.swiper-container-horizontal > .swiper-pagination {\n  bottom: 10px;\n  left: 0;\n  width: 100%; }\n\n.swiper-container-horizontal > .swiper-pagination .swiper-pagination-bullet {\n  margin: 0 5px; }\n\n/* 3D Container */\n.swiper-container-3d {\n  -webkit-perspective: 1200px;\n  -moz-perspective: 1200px;\n  -o-perspective: 1200px;\n  perspective: 1200px; }\n\n.swiper-container-3d .swiper-wrapper,\n.swiper-container-3d .swiper-slide,\n.swiper-container-3d .swiper-slide-shadow-left,\n.swiper-container-3d .swiper-slide-shadow-right,\n.swiper-container-3d .swiper-slide-shadow-top,\n.swiper-container-3d .swiper-slide-shadow-bottom,\n.swiper-container-3d .swiper-cube-shadow {\n  -webkit-transform-style: preserve-3d;\n  -moz-transform-style: preserve-3d;\n  -ms-transform-style: preserve-3d;\n  transform-style: preserve-3d; }\n\n.swiper-container-3d .swiper-slide-shadow-left,\n.swiper-container-3d .swiper-slide-shadow-right,\n.swiper-container-3d .swiper-slide-shadow-top,\n.swiper-container-3d .swiper-slide-shadow-bottom {\n  position: absolute;\n  left: 0;\n  top: 0;\n  width: 100%;\n  height: 100%;\n  pointer-events: none;\n  z-index: 10; }\n\n.swiper-container-3d .swiper-slide-shadow-left {\n  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.5)), to(transparent));\n  /* Safari 4+, Chrome */\n  background-image: -webkit-linear-gradient(right, rgba(0, 0, 0, 0.5), transparent);\n  /* Chrome 10+, Safari 5.1+, iOS 5+ */\n  background-image: -moz-linear-gradient(right, rgba(0, 0, 0, 0.5), transparent);\n  /* Firefox 3.6-15 */\n  background-image: -o-linear-gradient(right, rgba(0, 0, 0, 0.5), transparent);\n  /* Opera 11.10-12.00 */\n  background-image: linear-gradient(to left, rgba(0, 0, 0, 0.5), transparent);\n  /* Firefox 16+, IE10, Opera 12.50+ */ }\n\n.swiper-container-3d .swiper-slide-shadow-right {\n  background-image: -webkit-gradient(linear, right top, left top, from(rgba(0, 0, 0, 0.5)), to(transparent));\n  /* Safari 4+, Chrome */\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5), transparent);\n  /* Chrome 10+, Safari 5.1+, iOS 5+ */\n  background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.5), transparent);\n  /* Firefox 3.6-15 */\n  background-image: -o-linear-gradient(left, rgba(0, 0, 0, 0.5), transparent);\n  /* Opera 11.10-12.00 */\n  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5), transparent);\n  /* Firefox 16+, IE10, Opera 12.50+ */ }\n\n.swiper-container-3d .swiper-slide-shadow-top {\n  background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.5)), to(transparent));\n  /* Safari 4+, Chrome */\n  background-image: -webkit-linear-gradient(bottom, rgba(0, 0, 0, 0.5), transparent);\n  /* Chrome 10+, Safari 5.1+, iOS 5+ */\n  background-image: -moz-linear-gradient(bottom, rgba(0, 0, 0, 0.5), transparent);\n  /* Firefox 3.6-15 */\n  background-image: -o-linear-gradient(bottom, rgba(0, 0, 0, 0.5), transparent);\n  /* Opera 11.10-12.00 */\n  background-image: linear-gradient(to top, rgba(0, 0, 0, 0.5), transparent);\n  /* Firefox 16+, IE10, Opera 12.50+ */ }\n\n.swiper-container-3d .swiper-slide-shadow-bottom {\n  background-image: -webkit-gradient(linear, left bottom, left top, from(rgba(0, 0, 0, 0.5)), to(transparent));\n  /* Safari 4+, Chrome */\n  background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.5), transparent);\n  /* Chrome 10+, Safari 5.1+, iOS 5+ */\n  background-image: -moz-linear-gradient(top, rgba(0, 0, 0, 0.5), transparent);\n  /* Firefox 3.6-15 */\n  background-image: -o-linear-gradient(top, rgba(0, 0, 0, 0.5), transparent);\n  /* Opera 11.10-12.00 */\n  background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5), transparent);\n  /* Firefox 16+, IE10, Opera 12.50+ */ }\n\n/* Coverflow */\n.swiper-container-coverflow .swiper-wrapper {\n  /* Windows 8 IE 10 fix */\n  -ms-perspective: 1200px; }\n\n/* Fade */\n.swiper-container-fade.swiper-container-free-mode .swiper-slide {\n  -webkit-transition-timing-function: ease-out;\n  -moz-transition-timing-function: ease-out;\n  -ms-transition-timing-function: ease-out;\n  -o-transition-timing-function: ease-out;\n  transition-timing-function: ease-out; }\n\n.swiper-container-fade .swiper-slide {\n  pointer-events: none; }\n\n.swiper-container-fade .swiper-slide .swiper-slide {\n  pointer-events: none; }\n\n.swiper-container-fade .swiper-slide-active,\n.swiper-container-fade .swiper-slide-active .swiper-slide-active {\n  pointer-events: auto; }\n\n/* Cube */\n.swiper-container-cube {\n  overflow: visible; }\n\n.swiper-container-cube .swiper-slide {\n  pointer-events: none;\n  visibility: hidden;\n  -webkit-transform-origin: 0 0;\n  -moz-transform-origin: 0 0;\n  -ms-transform-origin: 0 0;\n  transform-origin: 0 0;\n  -webkit-backface-visibility: hidden;\n  -moz-backface-visibility: hidden;\n  -ms-backface-visibility: hidden;\n  backface-visibility: hidden;\n  width: 100%;\n  height: 100%;\n  z-index: 1; }\n\n.swiper-container-cube.swiper-container-rtl .swiper-slide {\n  -webkit-transform-origin: 100% 0;\n  -moz-transform-origin: 100% 0;\n  -ms-transform-origin: 100% 0;\n  transform-origin: 100% 0; }\n\n.swiper-container-cube .swiper-slide-active,\n.swiper-container-cube .swiper-slide-next,\n.swiper-container-cube .swiper-slide-prev,\n.swiper-container-cube .swiper-slide-next + .swiper-slide {\n  pointer-events: auto;\n  visibility: visible; }\n\n.swiper-container-cube .swiper-slide-shadow-top,\n.swiper-container-cube .swiper-slide-shadow-bottom,\n.swiper-container-cube .swiper-slide-shadow-left,\n.swiper-container-cube .swiper-slide-shadow-right {\n  z-index: 0;\n  -webkit-backface-visibility: hidden;\n  -moz-backface-visibility: hidden;\n  -ms-backface-visibility: hidden;\n  backface-visibility: hidden; }\n\n.swiper-container-cube .swiper-cube-shadow {\n  position: absolute;\n  left: 0;\n  bottom: 0px;\n  width: 100%;\n  height: 100%;\n  background: #000;\n  opacity: 0.6;\n  -webkit-filter: blur(50px);\n  filter: blur(50px);\n  z-index: 0; }\n\n/* Scrollbar */\n.swiper-scrollbar {\n  border-radius: 10px;\n  position: relative;\n  -ms-touch-action: none;\n  background: rgba(0, 0, 0, 0.1); }\n\n.swiper-container-horizontal > .swiper-scrollbar {\n  position: absolute;\n  left: 1%;\n  bottom: 3px;\n  z-index: 50;\n  height: 5px;\n  width: 98%; }\n\n.swiper-container-vertical > .swiper-scrollbar {\n  position: absolute;\n  right: 3px;\n  top: 1%;\n  z-index: 50;\n  width: 5px;\n  height: 98%; }\n\n.swiper-scrollbar-drag {\n  height: 100%;\n  width: 100%;\n  position: relative;\n  background: rgba(0, 0, 0, 0.5);\n  border-radius: 10px;\n  left: 0;\n  top: 0; }\n\n.swiper-scrollbar-cursor-drag {\n  cursor: move; }\n\n/* Preloader */\n.swiper-lazy-preloader {\n  width: 42px;\n  height: 42px;\n  position: absolute;\n  left: 50%;\n  top: 50%;\n  margin-left: -21px;\n  margin-top: -21px;\n  z-index: 10;\n  -webkit-transform-origin: 50%;\n  -moz-transform-origin: 50%;\n  transform-origin: 50%;\n  -webkit-animation: swiper-preloader-spin 1s steps(12, end) infinite;\n  -moz-animation: swiper-preloader-spin 1s steps(12, end) infinite;\n  animation: swiper-preloader-spin 1s steps(12, end) infinite; }\n\n.swiper-lazy-preloader:after {\n  display: block;\n  content: \"\";\n  width: 100%;\n  height: 100%;\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E\");\n  background-position: 50%;\n  -webkit-background-size: 100%;\n  background-size: 100%;\n  background-repeat: no-repeat; }\n\n.swiper-lazy-preloader-white:after {\n  background-image: url(\"data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%23fff'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E\"); }\n\n@-webkit-keyframes swiper-preloader-spin {\n  100% {\n    -webkit-transform: rotate(360deg); } }\n\n@keyframes swiper-preloader-spin {\n  100% {\n    transform: rotate(360deg); } }\n\nion-slides {\n  width: 100%;\n  height: 100%;\n  display: block; }\n\n.slide-zoom {\n  display: block;\n  width: 100%;\n  text-align: center; }\n\n.swiper-container {\n  width: 100%;\n  height: 100%;\n  padding: 0;\n  overflow: hidden; }\n\n.swiper-wrapper {\n  position: absolute;\n  left: 0;\n  top: 0;\n  width: 100%;\n  height: 100%;\n  padding: 0; }\n\n.swiper-slide {\n  width: 100%;\n  height: 100%;\n  box-sizing: border-box;\n  /* Center slide text vertically */ }\n\n.swiper-slide img {\n  width: auto;\n  height: auto;\n  max-width: 100%;\n  max-height: 100%; }\n\n.scroll-refresher {\n  position: absolute;\n  top: -60px;\n  right: 0;\n  left: 0;\n  overflow: hidden;\n  margin: auto;\n  height: 60px; }\n\n.scroll-refresher .ionic-refresher-content {\n  position: absolute;\n  bottom: 15px;\n  left: 0;\n  width: 100%;\n  color: #666666;\n  text-align: center;\n  font-size: 30px; }\n\n.scroll-refresher .ionic-refresher-content .text-refreshing,\n.scroll-refresher .ionic-refresher-content .text-pulling {\n  font-size: 16px;\n  line-height: 16px; }\n\n.scroll-refresher .ionic-refresher-content.ionic-refresher-with-text {\n  bottom: 10px; }\n\n.scroll-refresher .icon-refreshing,\n.scroll-refresher .icon-pulling {\n  width: 100%;\n  -webkit-backface-visibility: hidden;\n  backface-visibility: hidden;\n  -webkit-transform-style: preserve-3d;\n  transform-style: preserve-3d; }\n\n.scroll-refresher .icon-pulling {\n  -webkit-animation-name: refresh-spin-back;\n  animation-name: refresh-spin-back;\n  -webkit-animation-duration: 200ms;\n  animation-duration: 200ms;\n  -webkit-animation-timing-function: linear;\n  animation-timing-function: linear;\n  -webkit-animation-fill-mode: none;\n  animation-fill-mode: none;\n  -webkit-transform: translate3d(0, 0, 0) rotate(0deg);\n  transform: translate3d(0, 0, 0) rotate(0deg); }\n\n.scroll-refresher .icon-refreshing,\n.scroll-refresher .text-refreshing {\n  display: none; }\n\n.scroll-refresher .icon-refreshing {\n  -webkit-animation-duration: 1.5s;\n  animation-duration: 1.5s; }\n\n.scroll-refresher.active .icon-pulling:not(.pulling-rotation-disabled) {\n  -webkit-animation-name: refresh-spin;\n  animation-name: refresh-spin;\n  -webkit-transform: translate3d(0, 0, 0) rotate(-180deg);\n  transform: translate3d(0, 0, 0) rotate(-180deg); }\n\n.scroll-refresher.active.refreshing {\n  -webkit-transition: -webkit-transform 0.2s;\n  transition: -webkit-transform 0.2s;\n  -webkit-transition: transform 0.2s;\n  transition: transform 0.2s;\n  -webkit-transform: scale(1, 1);\n  transform: scale(1, 1); }\n\n.scroll-refresher.active.refreshing .icon-pulling,\n.scroll-refresher.active.refreshing .text-pulling {\n  display: none; }\n\n.scroll-refresher.active.refreshing .icon-refreshing,\n.scroll-refresher.active.refreshing .text-refreshing {\n  display: block; }\n\n.scroll-refresher.active.refreshing.refreshing-tail {\n  -webkit-transform: scale(0, 0);\n  transform: scale(0, 0); }\n\n.overflow-scroll > .scroll {\n  -webkit-overflow-scrolling: touch;\n  width: 100%; }\n\n.overflow-scroll > .scroll.overscroll {\n  position: fixed;\n  right: 0;\n  left: 0; }\n\n.overflow-scroll.padding > .scroll.overscroll {\n  padding: 10px; }\n\n@-webkit-keyframes refresh-spin {\n  0% {\n    -webkit-transform: translate3d(0, 0, 0) rotate(0); }\n  100% {\n    -webkit-transform: translate3d(0, 0, 0) rotate(180deg); } }\n\n@keyframes refresh-spin {\n  0% {\n    transform: translate3d(0, 0, 0) rotate(0); }\n  100% {\n    transform: translate3d(0, 0, 0) rotate(180deg); } }\n\n@-webkit-keyframes refresh-spin-back {\n  0% {\n    -webkit-transform: translate3d(0, 0, 0) rotate(180deg); }\n  100% {\n    -webkit-transform: translate3d(0, 0, 0) rotate(0); } }\n\n@keyframes refresh-spin-back {\n  0% {\n    transform: translate3d(0, 0, 0) rotate(180deg); }\n  100% {\n    transform: translate3d(0, 0, 0) rotate(0); } }\n\n/**\n * Spinners\n * --------------------------------------------------\n */\n.spinner {\n  stroke: #444;\n  fill: #444; }\n\n.spinner svg {\n  width: 28px;\n  height: 28px; }\n\n.spinner.spinner-light {\n  stroke: #fff;\n  fill: #fff; }\n\n.spinner.spinner-stable {\n  stroke: #f8f8f8;\n  fill: #f8f8f8; }\n\n.spinner.spinner-positive {\n  stroke: #387ef5;\n  fill: #387ef5; }\n\n.spinner.spinner-calm {\n  stroke: #11c1f3;\n  fill: #11c1f3; }\n\n.spinner.spinner-balanced {\n  stroke: #33cd5f;\n  fill: #33cd5f; }\n\n.spinner.spinner-assertive {\n  stroke: #ef473a;\n  fill: #ef473a; }\n\n.spinner.spinner-energized {\n  stroke: #ffc900;\n  fill: #ffc900; }\n\n.spinner.spinner-royal {\n  stroke: #886aea;\n  fill: #886aea; }\n\n.spinner.spinner-dark {\n  stroke: #444;\n  fill: #444; }\n\n.spinner-android {\n  stroke: #4b8bf4; }\n\n.spinner-ios,\n.spinner-ios-small {\n  stroke: #69717d; }\n\n.spinner-spiral .stop1 {\n  stop-color: #fff;\n  stop-opacity: 0; }\n\n.spinner-spiral.spinner-light .stop1 {\n  stop-color: #444; }\n\n.spinner-spiral.spinner-light .stop2 {\n  stop-color: #fff; }\n\n.spinner-spiral.spinner-stable .stop2 {\n  stop-color: #f8f8f8; }\n\n.spinner-spiral.spinner-positive .stop2 {\n  stop-color: #387ef5; }\n\n.spinner-spiral.spinner-calm .stop2 {\n  stop-color: #11c1f3; }\n\n.spinner-spiral.spinner-balanced .stop2 {\n  stop-color: #33cd5f; }\n\n.spinner-spiral.spinner-assertive .stop2 {\n  stop-color: #ef473a; }\n\n.spinner-spiral.spinner-energized .stop2 {\n  stop-color: #ffc900; }\n\n.spinner-spiral.spinner-royal .stop2 {\n  stop-color: #886aea; }\n\n.spinner-spiral.spinner-dark .stop2 {\n  stop-color: #444; }\n\n/**\n * Forms\n * --------------------------------------------------\n */\nform {\n  margin: 0 0 1.42857; }\n\nlegend {\n  display: block;\n  margin-bottom: 1.42857;\n  padding: 0;\n  width: 100%;\n  border: 1px solid #ddd;\n  color: #444;\n  font-size: 21px;\n  line-height: 2.85714; }\n\nlegend small {\n  color: #f8f8f8;\n  font-size: 1.07143; }\n\nlabel,\ninput,\nbutton,\nselect,\ntextarea {\n  font-weight: normal;\n  font-size: 14px;\n  line-height: 1.42857; }\n\ninput,\nbutton,\nselect,\ntextarea {\n  font-family: \"-apple-system\", \"Helvetica Neue\", \"Roboto\", \"Segoe UI\", sans-serif; }\n\n.item-input {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  align-items: center;\n  position: relative;\n  overflow: hidden;\n  padding: 6px 0 5px 16px; }\n\n.item-input input {\n  -webkit-border-radius: 0;\n  border-radius: 0;\n  -webkit-box-flex: 1;\n  -webkit-flex: 1 220px;\n  -moz-box-flex: 1;\n  -moz-flex: 1 220px;\n  -ms-flex: 1 220px;\n  flex: 1 220px;\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n  margin: 0;\n  padding-right: 24px;\n  background-color: transparent; }\n\n.item-input .button .icon {\n  -webkit-box-flex: 0;\n  -webkit-flex: 0 0 24px;\n  -moz-box-flex: 0;\n  -moz-flex: 0 0 24px;\n  -ms-flex: 0 0 24px;\n  flex: 0 0 24px;\n  position: static;\n  display: inline-block;\n  height: auto;\n  text-align: center;\n  font-size: 16px; }\n\n.item-input .button-bar {\n  -webkit-border-radius: 0;\n  border-radius: 0;\n  -webkit-box-flex: 1;\n  -webkit-flex: 1 0 220px;\n  -moz-box-flex: 1;\n  -moz-flex: 1 0 220px;\n  -ms-flex: 1 0 220px;\n  flex: 1 0 220px;\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none; }\n\n.item-input .icon {\n  min-width: 14px; }\n\n.platform-windowsphone .item-input input {\n  flex-shrink: 1; }\n\n.item-input-inset {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  align-items: center;\n  position: relative;\n  overflow: hidden;\n  padding: 10.66667px; }\n\n.item-input-wrapper {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-flex: 1;\n  -webkit-flex: 1 0;\n  -moz-box-flex: 1;\n  -moz-flex: 1 0;\n  -ms-flex: 1 0;\n  flex: 1 0;\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  align-items: center;\n  -webkit-border-radius: 4px;\n  border-radius: 4px;\n  padding-right: 8px;\n  padding-left: 8px;\n  background: #eee; }\n\n.item-input-inset .item-input-wrapper input {\n  padding-left: 4px;\n  height: 29px;\n  background: transparent;\n  line-height: 18px; }\n\n.item-input-wrapper ~ .button {\n  margin-left: 10.66667px; }\n\n.input-label {\n  display: table;\n  padding: 7px 10px 7px 0px;\n  max-width: 200px;\n  width: 35%;\n  color: #444;\n  font-size: 16px; }\n\n.placeholder-icon {\n  color: #aaa; }\n\n.placeholder-icon:first-child {\n  padding-right: 6px; }\n\n.placeholder-icon:last-child {\n  padding-left: 6px; }\n\n.item-stacked-label {\n  display: block;\n  background-color: transparent;\n  box-shadow: none; }\n\n.item-stacked-label .input-label, .item-stacked-label .icon {\n  display: inline-block;\n  padding: 4px 0 0 0px;\n  vertical-align: middle; }\n\n.item-stacked-label input,\n.item-stacked-label textarea {\n  -webkit-border-radius: 2px;\n  border-radius: 2px;\n  padding: 4px 8px 3px 0;\n  border: none;\n  background-color: #fff; }\n\n.item-stacked-label input {\n  overflow: hidden;\n  height: 46px; }\n\n.item-select.item-stacked-label select {\n  position: relative;\n  padding: 0px;\n  max-width: 90%;\n  direction: ltr;\n  white-space: pre-wrap;\n  margin: -3px; }\n\n.item-floating-label {\n  display: block;\n  background-color: transparent;\n  box-shadow: none; }\n\n.item-floating-label .input-label {\n  position: relative;\n  padding: 5px 0 0 0;\n  opacity: 0;\n  top: 10px;\n  -webkit-transition: opacity 0.15s ease-in, top 0.2s linear;\n  transition: opacity 0.15s ease-in, top 0.2s linear; }\n\n.item-floating-label .input-label.has-input {\n  opacity: 1;\n  top: 0;\n  -webkit-transition: opacity 0.15s ease-in, top 0.2s linear;\n  transition: opacity 0.15s ease-in, top 0.2s linear; }\n\ntextarea,\ninput[type=\"text\"],\ninput[type=\"password\"],\ninput[type=\"datetime\"],\ninput[type=\"datetime-local\"],\ninput[type=\"date\"],\ninput[type=\"month\"],\ninput[type=\"time\"],\ninput[type=\"week\"],\ninput[type=\"number\"],\ninput[type=\"email\"],\ninput[type=\"url\"],\ninput[type=\"search\"],\ninput[type=\"tel\"],\ninput[type=\"color\"] {\n  display: block;\n  padding-top: 2px;\n  padding-left: 0;\n  height: 34px;\n  color: #111;\n  vertical-align: middle;\n  font-size: 14px;\n  line-height: 16px; }\n\n.platform-ios input[type=\"datetime-local\"],\n.platform-ios input[type=\"date\"],\n.platform-ios input[type=\"month\"],\n.platform-ios input[type=\"time\"],\n.platform-ios input[type=\"week\"],\n.platform-android input[type=\"datetime-local\"],\n.platform-android input[type=\"date\"],\n.platform-android input[type=\"month\"],\n.platform-android input[type=\"time\"],\n.platform-android input[type=\"week\"] {\n  padding-top: 8px; }\n\n.item-input input,\n.item-input textarea {\n  width: 100%; }\n\ntextarea {\n  padding-left: 0; }\n\ntextarea::-moz-placeholder {\n  color: #aaaaaa; }\n\ntextarea:-ms-input-placeholder {\n  color: #aaaaaa; }\n\ntextarea::-webkit-input-placeholder {\n  color: #aaaaaa;\n  text-indent: -3px; }\n\ntextarea {\n  height: auto; }\n\ntextarea,\ninput[type=\"text\"],\ninput[type=\"password\"],\ninput[type=\"datetime\"],\ninput[type=\"datetime-local\"],\ninput[type=\"date\"],\ninput[type=\"month\"],\ninput[type=\"time\"],\ninput[type=\"week\"],\ninput[type=\"number\"],\ninput[type=\"email\"],\ninput[type=\"url\"],\ninput[type=\"search\"],\ninput[type=\"tel\"],\ninput[type=\"color\"] {\n  border: 0; }\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 0;\n  line-height: normal; }\n\n.item-input input[type=\"file\"],\n.item-input input[type=\"image\"],\n.item-input input[type=\"submit\"],\n.item-input input[type=\"reset\"],\n.item-input input[type=\"button\"],\n.item-input input[type=\"radio\"],\n.item-input input[type=\"checkbox\"] {\n  width: auto; }\n\ninput[type=\"file\"] {\n  line-height: 34px; }\n\n.previous-input-focus,\n.cloned-text-input + input,\n.cloned-text-input + textarea {\n  position: absolute !important;\n  left: -9999px;\n  width: 200px; }\n\ninput::-moz-placeholder,\ntextarea::-moz-placeholder {\n  color: #aaaaaa; }\n\ninput:-ms-input-placeholder,\ntextarea:-ms-input-placeholder {\n  color: #aaaaaa; }\n\ninput::-webkit-input-placeholder,\ntextarea::-webkit-input-placeholder {\n  color: #aaaaaa;\n  text-indent: 0; }\n\ninput[disabled],\nselect[disabled],\ntextarea[disabled],\ninput[readonly]:not(.cloned-text-input),\ntextarea[readonly]:not(.cloned-text-input),\nselect[readonly] {\n  background-color: #f8f8f8;\n  cursor: not-allowed; }\n\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"][readonly],\ninput[type=\"checkbox\"][readonly] {\n  background-color: transparent; }\n\n/**\n * Checkbox\n * --------------------------------------------------\n */\n.checkbox {\n  position: relative;\n  display: inline-block;\n  padding: 7px 7px;\n  cursor: pointer; }\n\n.checkbox input:before,\n.checkbox .checkbox-icon:before {\n  border-color: #ddd; }\n\n.checkbox input:checked:before,\n.checkbox input:checked + .checkbox-icon:before {\n  background: #387ef5;\n  border-color: #387ef5; }\n\n.checkbox-light input:before,\n.checkbox-light .checkbox-icon:before {\n  border-color: #ddd; }\n\n.checkbox-light input:checked:before,\n.checkbox-light input:checked + .checkbox-icon:before {\n  background: #ddd;\n  border-color: #ddd; }\n\n.checkbox-stable input:before,\n.checkbox-stable .checkbox-icon:before {\n  border-color: #b2b2b2; }\n\n.checkbox-stable input:checked:before,\n.checkbox-stable input:checked + .checkbox-icon:before {\n  background: #b2b2b2;\n  border-color: #b2b2b2; }\n\n.checkbox-positive input:before,\n.checkbox-positive .checkbox-icon:before {\n  border-color: #387ef5; }\n\n.checkbox-positive input:checked:before,\n.checkbox-positive input:checked + .checkbox-icon:before {\n  background: #387ef5;\n  border-color: #387ef5; }\n\n.checkbox-calm input:before,\n.checkbox-calm .checkbox-icon:before {\n  border-color: #11c1f3; }\n\n.checkbox-calm input:checked:before,\n.checkbox-calm input:checked + .checkbox-icon:before {\n  background: #11c1f3;\n  border-color: #11c1f3; }\n\n.checkbox-assertive input:before,\n.checkbox-assertive .checkbox-icon:before {\n  border-color: #ef473a; }\n\n.checkbox-assertive input:checked:before,\n.checkbox-assertive input:checked + .checkbox-icon:before {\n  background: #ef473a;\n  border-color: #ef473a; }\n\n.checkbox-balanced input:before,\n.checkbox-balanced .checkbox-icon:before {\n  border-color: #33cd5f; }\n\n.checkbox-balanced input:checked:before,\n.checkbox-balanced input:checked + .checkbox-icon:before {\n  background: #33cd5f;\n  border-color: #33cd5f; }\n\n.checkbox-energized input:before,\n.checkbox-energized .checkbox-icon:before {\n  border-color: #ffc900; }\n\n.checkbox-energized input:checked:before,\n.checkbox-energized input:checked + .checkbox-icon:before {\n  background: #ffc900;\n  border-color: #ffc900; }\n\n.checkbox-royal input:before,\n.checkbox-royal .checkbox-icon:before {\n  border-color: #886aea; }\n\n.checkbox-royal input:checked:before,\n.checkbox-royal input:checked + .checkbox-icon:before {\n  background: #886aea;\n  border-color: #886aea; }\n\n.checkbox-dark input:before,\n.checkbox-dark .checkbox-icon:before {\n  border-color: #444; }\n\n.checkbox-dark input:checked:before,\n.checkbox-dark input:checked + .checkbox-icon:before {\n  background: #444;\n  border-color: #444; }\n\n.checkbox input:disabled:before,\n.checkbox input:disabled + .checkbox-icon:before {\n  border-color: #ddd; }\n\n.checkbox input:disabled:checked:before,\n.checkbox input:disabled:checked + .checkbox-icon:before {\n  background: #ddd; }\n\n.checkbox.checkbox-input-hidden input {\n  display: none !important; }\n\n.checkbox input,\n.checkbox-icon {\n  position: relative;\n  width: 28px;\n  height: 28px;\n  display: block;\n  border: 0;\n  background: transparent;\n  cursor: pointer;\n  -webkit-appearance: none; }\n\n.checkbox input:before,\n.checkbox-icon:before {\n  display: table;\n  width: 100%;\n  height: 100%;\n  border-width: 1px;\n  border-style: solid;\n  border-radius: 28px;\n  background: #fff;\n  content: ' ';\n  -webkit-transition: background-color 20ms ease-in-out;\n  transition: background-color 20ms ease-in-out; }\n\n.checkbox input:checked:before,\ninput:checked + .checkbox-icon:before {\n  border-width: 2px; }\n\n.checkbox input:after,\n.checkbox-icon:after {\n  -webkit-transition: opacity 0.05s ease-in-out;\n  transition: opacity 0.05s ease-in-out;\n  -webkit-transform: rotate(-45deg);\n  transform: rotate(-45deg);\n  position: absolute;\n  top: 33%;\n  left: 25%;\n  display: table;\n  width: 14px;\n  height: 6px;\n  border: 1px solid #fff;\n  border-top: 0;\n  border-right: 0;\n  content: ' ';\n  opacity: 0; }\n\n.platform-android .checkbox-platform input:before,\n.platform-android .checkbox-platform .checkbox-icon:before,\n.checkbox-square input:before,\n.checkbox-square .checkbox-icon:before {\n  border-radius: 2px;\n  width: 72%;\n  height: 72%;\n  margin-top: 14%;\n  margin-left: 14%;\n  border-width: 2px; }\n\n.platform-android .checkbox-platform input:after,\n.platform-android .checkbox-platform .checkbox-icon:after,\n.checkbox-square input:after,\n.checkbox-square .checkbox-icon:after {\n  border-width: 2px;\n  top: 19%;\n  left: 25%;\n  width: 13px;\n  height: 7px; }\n\n.platform-android .item-checkbox-right .checkbox-square .checkbox-icon::after {\n  top: 31%; }\n\n.grade-c .checkbox input:after,\n.grade-c .checkbox-icon:after {\n  -webkit-transform: rotate(0);\n  transform: rotate(0);\n  top: 3px;\n  left: 4px;\n  border: none;\n  color: #fff;\n  content: '\\2713';\n  font-weight: bold;\n  font-size: 20px; }\n\n.checkbox input:checked:after,\ninput:checked + .checkbox-icon:after {\n  opacity: 1; }\n\n.item-checkbox {\n  padding-left: 60px; }\n\n.item-checkbox.active {\n  box-shadow: none; }\n\n.item-checkbox .checkbox {\n  position: absolute;\n  top: 50%;\n  right: 8px;\n  left: 8px;\n  z-index: 3;\n  margin-top: -21px; }\n\n.item-checkbox.item-checkbox-right {\n  padding-right: 60px;\n  padding-left: 16px; }\n\n.item-checkbox-right .checkbox input,\n.item-checkbox-right .checkbox-icon {\n  float: right; }\n\n/**\n * Toggle\n * --------------------------------------------------\n */\n.item-toggle {\n  pointer-events: none; }\n\n.toggle {\n  position: relative;\n  display: inline-block;\n  pointer-events: auto;\n  margin: -5px;\n  padding: 5px; }\n\n.toggle input:checked + .track {\n  border-color: #4cd964;\n  background-color: #4cd964; }\n\n.toggle.dragging .handle {\n  background-color: #f2f2f2 !important; }\n\n.toggle.toggle-light input:checked + .track {\n  border-color: #ddd;\n  background-color: #ddd; }\n\n.toggle.toggle-stable input:checked + .track {\n  border-color: #b2b2b2;\n  background-color: #b2b2b2; }\n\n.toggle.toggle-positive input:checked + .track {\n  border-color: #387ef5;\n  background-color: #387ef5; }\n\n.toggle.toggle-calm input:checked + .track {\n  border-color: #11c1f3;\n  background-color: #11c1f3; }\n\n.toggle.toggle-assertive input:checked + .track {\n  border-color: #ef473a;\n  background-color: #ef473a; }\n\n.toggle.toggle-balanced input:checked + .track {\n  border-color: #33cd5f;\n  background-color: #33cd5f; }\n\n.toggle.toggle-energized input:checked + .track {\n  border-color: #ffc900;\n  background-color: #ffc900; }\n\n.toggle.toggle-royal input:checked + .track {\n  border-color: #886aea;\n  background-color: #886aea; }\n\n.toggle.toggle-dark input:checked + .track {\n  border-color: #444;\n  background-color: #444; }\n\n.toggle input {\n  display: none; }\n\n/* the track appearance when the toggle is \"off\" */\n.toggle .track {\n  -webkit-transition-timing-function: ease-in-out;\n  transition-timing-function: ease-in-out;\n  -webkit-transition-duration: 0.3s;\n  transition-duration: 0.3s;\n  -webkit-transition-property: background-color, border;\n  transition-property: background-color, border;\n  display: inline-block;\n  box-sizing: border-box;\n  width: 51px;\n  height: 31px;\n  border: solid 2px #e6e6e6;\n  border-radius: 20px;\n  background-color: #fff;\n  content: ' ';\n  cursor: pointer;\n  pointer-events: none; }\n\n/* Fix to avoid background color bleeding */\n/* (occured on (at least) Android 4.2, Asus MeMO Pad HD7 ME173X) */\n.platform-android4_2 .toggle .track {\n  -webkit-background-clip: padding-box; }\n\n/* the handle (circle) thats inside the toggle's track area */\n/* also the handle's appearance when it is \"off\" */\n.toggle .handle {\n  -webkit-transition: 0.3s cubic-bezier(0, 1.1, 1, 1.1);\n  transition: 0.3s cubic-bezier(0, 1.1, 1, 1.1);\n  -webkit-transition-property: background-color, transform;\n  transition-property: background-color, transform;\n  position: absolute;\n  display: block;\n  width: 27px;\n  height: 27px;\n  border-radius: 27px;\n  background-color: #fff;\n  top: 7px;\n  left: 7px;\n  box-shadow: 0 2px 7px rgba(0, 0, 0, 0.35), 0 1px 1px rgba(0, 0, 0, 0.15); }\n\n.toggle .handle:before {\n  position: absolute;\n  top: -4px;\n  left: -21.5px;\n  padding: 18.5px 34px;\n  content: \" \"; }\n\n.toggle input:checked + .track .handle {\n  -webkit-transform: translate3d(20px, 0, 0);\n  transform: translate3d(20px, 0, 0);\n  background-color: #fff; }\n\n.item-toggle.active {\n  box-shadow: none; }\n\n.item-toggle,\n.item-toggle.item-complex .item-content {\n  padding-right: 99px; }\n\n.item-toggle.item-complex {\n  padding-right: 0; }\n\n.item-toggle .toggle {\n  position: absolute;\n  top: 10px;\n  right: 16px;\n  z-index: 3; }\n\n.toggle input:disabled + .track {\n  opacity: .6; }\n\n.toggle-small .track {\n  border: 0;\n  width: 34px;\n  height: 15px;\n  background: #9e9e9e; }\n\n.toggle-small input:checked + .track {\n  background: rgba(0, 150, 137, 0.5); }\n\n.toggle-small .handle {\n  top: 2px;\n  left: 4px;\n  width: 21px;\n  height: 21px;\n  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25); }\n\n.toggle-small input:checked + .track .handle {\n  -webkit-transform: translate3d(16px, 0, 0);\n  transform: translate3d(16px, 0, 0);\n  background: #009689; }\n\n.toggle-small.item-toggle .toggle {\n  top: 19px; }\n\n.toggle-small .toggle-light input:checked + .track {\n  background-color: rgba(221, 221, 221, 0.5); }\n\n.toggle-small .toggle-light input:checked + .track .handle {\n  background-color: #ddd; }\n\n.toggle-small .toggle-stable input:checked + .track {\n  background-color: rgba(178, 178, 178, 0.5); }\n\n.toggle-small .toggle-stable input:checked + .track .handle {\n  background-color: #b2b2b2; }\n\n.toggle-small .toggle-positive input:checked + .track {\n  background-color: rgba(56, 126, 245, 0.5); }\n\n.toggle-small .toggle-positive input:checked + .track .handle {\n  background-color: #387ef5; }\n\n.toggle-small .toggle-calm input:checked + .track {\n  background-color: rgba(17, 193, 243, 0.5); }\n\n.toggle-small .toggle-calm input:checked + .track .handle {\n  background-color: #11c1f3; }\n\n.toggle-small .toggle-assertive input:checked + .track {\n  background-color: rgba(239, 71, 58, 0.5); }\n\n.toggle-small .toggle-assertive input:checked + .track .handle {\n  background-color: #ef473a; }\n\n.toggle-small .toggle-balanced input:checked + .track {\n  background-color: rgba(51, 205, 95, 0.5); }\n\n.toggle-small .toggle-balanced input:checked + .track .handle {\n  background-color: #33cd5f; }\n\n.toggle-small .toggle-energized input:checked + .track {\n  background-color: rgba(255, 201, 0, 0.5); }\n\n.toggle-small .toggle-energized input:checked + .track .handle {\n  background-color: #ffc900; }\n\n.toggle-small .toggle-royal input:checked + .track {\n  background-color: rgba(136, 106, 234, 0.5); }\n\n.toggle-small .toggle-royal input:checked + .track .handle {\n  background-color: #886aea; }\n\n.toggle-small .toggle-dark input:checked + .track {\n  background-color: rgba(68, 68, 68, 0.5); }\n\n.toggle-small .toggle-dark input:checked + .track .handle {\n  background-color: #444; }\n\n/**\n * Radio Button Inputs\n * --------------------------------------------------\n */\n.item-radio {\n  padding: 0; }\n\n.item-radio:hover {\n  cursor: pointer; }\n\n.item-radio .item-content {\n  /* give some room to the right for the checkmark icon */\n  padding-right: 64px; }\n\n.item-radio .radio-icon {\n  /* checkmark icon will be hidden by default */\n  position: absolute;\n  top: 0;\n  right: 0;\n  z-index: 3;\n  visibility: hidden;\n  padding: 14px;\n  height: 100%;\n  font-size: 24px; }\n\n.item-radio input {\n  /* hide any radio button inputs elements (the ugly circles) */\n  position: absolute;\n  left: -9999px; }\n\n.item-radio input:checked + .radio-content .item-content {\n  /* style the item content when its checked */\n  background: #f7f7f7; }\n\n.item-radio input:checked + .radio-content .radio-icon {\n  /* show the checkmark icon when its checked */\n  visibility: visible; }\n\n/**\n * Range\n * --------------------------------------------------\n */\n.range input {\n  display: inline-block;\n  overflow: hidden;\n  margin-top: 5px;\n  margin-bottom: 5px;\n  padding-right: 2px;\n  padding-left: 1px;\n  width: auto;\n  height: 43px;\n  outline: none;\n  background: -webkit-gradient(linear, 50% 0%, 50% 100%, color-stop(0%, #ccc), color-stop(100%, #ccc));\n  background: linear-gradient(to right, #ccc 0%, #ccc 100%);\n  background-position: center;\n  background-size: 99% 2px;\n  background-repeat: no-repeat;\n  -webkit-appearance: none;\n  /*\n   &::-ms-track{\n     background: transparent;\n     border-color: transparent;\n     border-width: 11px 0 16px;\n     color:transparent;\n     margin-top:20px;\n   }\n   &::-ms-thumb {\n     width: $range-slider-width;\n     height: $range-slider-height;\n     border-radius: $range-slider-border-radius;\n     background-color: $toggle-handle-off-bg-color;\n     border-color:$toggle-handle-off-bg-color;\n     box-shadow: $range-slider-box-shadow;\n     margin-left:1px;\n     margin-right:1px;\n     outline:none;\n   }\n   &::-ms-fill-upper {\n     height: $range-track-height;\n     background:$range-default-track-bg;\n   }\n   */ }\n\n.range input::-moz-focus-outer {\n  /* hide the focus outline in Firefox */\n  border: 0; }\n\n.range input::-webkit-slider-thumb {\n  position: relative;\n  width: 28px;\n  height: 28px;\n  border-radius: 50%;\n  background-color: #fff;\n  box-shadow: 0 0 2px rgba(0, 0, 0, 0.3), 0 3px 5px rgba(0, 0, 0, 0.2);\n  cursor: pointer;\n  -webkit-appearance: none;\n  border: 0; }\n\n.range input::-webkit-slider-thumb:before {\n  /* what creates the colorful line on the left side of the slider */\n  position: absolute;\n  top: 13px;\n  left: -2001px;\n  width: 2000px;\n  height: 2px;\n  background: #444;\n  content: ' '; }\n\n.range input::-webkit-slider-thumb:after {\n  /* create a larger (but hidden) hit area */\n  position: absolute;\n  top: -15px;\n  left: -15px;\n  padding: 30px;\n  content: ' '; }\n\n.range input::-ms-fill-lower {\n  height: 2px;\n  background: #444; }\n\n.range {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  align-items: center;\n  padding: 2px 11px; }\n\n.range.range-light input::-webkit-slider-thumb:before {\n  background: #ddd; }\n\n.range.range-light input::-ms-fill-lower {\n  background: #ddd; }\n\n.range.range-stable input::-webkit-slider-thumb:before {\n  background: #b2b2b2; }\n\n.range.range-stable input::-ms-fill-lower {\n  background: #b2b2b2; }\n\n.range.range-positive input::-webkit-slider-thumb:before {\n  background: #387ef5; }\n\n.range.range-positive input::-ms-fill-lower {\n  background: #387ef5; }\n\n.range.range-calm input::-webkit-slider-thumb:before {\n  background: #11c1f3; }\n\n.range.range-calm input::-ms-fill-lower {\n  background: #11c1f3; }\n\n.range.range-balanced input::-webkit-slider-thumb:before {\n  background: #33cd5f; }\n\n.range.range-balanced input::-ms-fill-lower {\n  background: #33cd5f; }\n\n.range.range-assertive input::-webkit-slider-thumb:before {\n  background: #ef473a; }\n\n.range.range-assertive input::-ms-fill-lower {\n  background: #ef473a; }\n\n.range.range-energized input::-webkit-slider-thumb:before {\n  background: #ffc900; }\n\n.range.range-energized input::-ms-fill-lower {\n  background: #ffc900; }\n\n.range.range-royal input::-webkit-slider-thumb:before {\n  background: #886aea; }\n\n.range.range-royal input::-ms-fill-lower {\n  background: #886aea; }\n\n.range.range-dark input::-webkit-slider-thumb:before {\n  background: #444; }\n\n.range.range-dark input::-ms-fill-lower {\n  background: #444; }\n\n.range .icon {\n  -webkit-box-flex: 0;\n  -webkit-flex: 0;\n  -moz-box-flex: 0;\n  -moz-flex: 0;\n  -ms-flex: 0;\n  flex: 0;\n  display: block;\n  min-width: 24px;\n  text-align: center;\n  font-size: 24px; }\n\n.range input {\n  -webkit-box-flex: 1;\n  -webkit-flex: 1;\n  -moz-box-flex: 1;\n  -moz-flex: 1;\n  -ms-flex: 1;\n  flex: 1;\n  display: block;\n  margin-right: 10px;\n  margin-left: 10px; }\n\n.range-label {\n  -webkit-box-flex: 0;\n  -webkit-flex: 0 0 auto;\n  -moz-box-flex: 0;\n  -moz-flex: 0 0 auto;\n  -ms-flex: 0 0 auto;\n  flex: 0 0 auto;\n  display: block;\n  white-space: nowrap; }\n\n.range-label:first-child {\n  padding-left: 5px; }\n\n.range input + .range-label {\n  padding-right: 5px;\n  padding-left: 0; }\n\n.platform-windowsphone .range input {\n  height: auto; }\n\n/**\n * Select\n * --------------------------------------------------\n */\n.item-select {\n  position: relative; }\n\n.item-select select {\n  -webkit-appearance: none;\n  -moz-appearance: none;\n  appearance: none;\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  right: 0;\n  padding: 0 48px 0 16px;\n  max-width: 65%;\n  border: none;\n  background: #fff;\n  color: #333;\n  text-indent: .01px;\n  text-overflow: '';\n  white-space: nowrap;\n  font-size: 14px;\n  cursor: pointer;\n  direction: rtl; }\n\n.item-select select::-ms-expand {\n  display: none; }\n\n.item-select option {\n  direction: ltr; }\n\n.item-select:after {\n  position: absolute;\n  top: 50%;\n  right: 16px;\n  margin-top: -3px;\n  width: 0;\n  height: 0;\n  border-top: 5px solid;\n  border-right: 5px solid transparent;\n  border-left: 5px solid transparent;\n  color: #999;\n  content: \"\";\n  pointer-events: none; }\n\n.item-select.item-light select {\n  background: #fff;\n  color: #444; }\n\n.item-select.item-stable select {\n  background: #f8f8f8;\n  color: #444; }\n\n.item-select.item-stable:after, .item-select.item-stable .input-label {\n  color: #666666; }\n\n.item-select.item-positive select {\n  background: #387ef5;\n  color: #fff; }\n\n.item-select.item-positive:after, .item-select.item-positive .input-label {\n  color: #fff; }\n\n.item-select.item-calm select {\n  background: #11c1f3;\n  color: #fff; }\n\n.item-select.item-calm:after, .item-select.item-calm .input-label {\n  color: #fff; }\n\n.item-select.item-assertive select {\n  background: #ef473a;\n  color: #fff; }\n\n.item-select.item-assertive:after, .item-select.item-assertive .input-label {\n  color: #fff; }\n\n.item-select.item-balanced select {\n  background: #33cd5f;\n  color: #fff; }\n\n.item-select.item-balanced:after, .item-select.item-balanced .input-label {\n  color: #fff; }\n\n.item-select.item-energized select {\n  background: #ffc900;\n  color: #fff; }\n\n.item-select.item-energized:after, .item-select.item-energized .input-label {\n  color: #fff; }\n\n.item-select.item-royal select {\n  background: #886aea;\n  color: #fff; }\n\n.item-select.item-royal:after, .item-select.item-royal .input-label {\n  color: #fff; }\n\n.item-select.item-dark select {\n  background: #444;\n  color: #fff; }\n\n.item-select.item-dark:after, .item-select.item-dark .input-label {\n  color: #fff; }\n\nselect[multiple], select[size] {\n  height: auto; }\n\n/**\n * Progress\n * --------------------------------------------------\n */\nprogress {\n  display: block;\n  margin: 15px auto;\n  width: 100%; }\n\n/**\n * Buttons\n * --------------------------------------------------\n */\n.button {\n  border-color: transparent;\n  background-color: #f8f8f8;\n  color: #444;\n  position: relative;\n  display: inline-block;\n  margin: 0;\n  padding: 0 12px;\n  min-width: 52px;\n  min-height: 47px;\n  border-width: 1px;\n  border-style: solid;\n  border-radius: 4px;\n  vertical-align: top;\n  text-align: center;\n  text-overflow: ellipsis;\n  font-size: 16px;\n  line-height: 42px;\n  cursor: pointer; }\n\n.button:hover {\n  color: #444;\n  text-decoration: none; }\n\n.button.active, .button.activated {\n  background-color: #e5e5e5; }\n\n.button:after {\n  position: absolute;\n  top: -6px;\n  right: -6px;\n  bottom: -6px;\n  left: -6px;\n  content: ' '; }\n\n.button .icon {\n  vertical-align: top;\n  pointer-events: none; }\n\n.button .icon:before, .button.icon:before, .button.icon-left:before, .button.icon-right:before {\n  display: inline-block;\n  padding: 0 0 1px 0;\n  vertical-align: inherit;\n  font-size: 24px;\n  line-height: 41px;\n  pointer-events: none; }\n\n.button.icon-left:before {\n  float: left;\n  padding-right: .2em;\n  padding-left: 0; }\n\n.button.icon-right:before {\n  float: right;\n  padding-right: 0;\n  padding-left: .2em; }\n\n.button.button-block, .button.button-full {\n  margin-top: 10px;\n  margin-bottom: 10px; }\n\n.button.button-light {\n  border-color: transparent;\n  background-color: #fff;\n  color: #444; }\n\n.button.button-light:hover {\n  color: #444;\n  text-decoration: none; }\n\n.button.button-light.active, .button.button-light.activated {\n  background-color: #fafafa; }\n\n.button.button-light.button-clear {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  color: #ddd; }\n\n.button.button-light.button-icon {\n  border-color: transparent;\n  background: none; }\n\n.button.button-light.button-outline {\n  border-color: #ddd;\n  background: transparent;\n  color: #ddd; }\n\n.button.button-light.button-outline.active, .button.button-light.button-outline.activated {\n  background-color: #ddd;\n  box-shadow: none;\n  color: #fff; }\n\n.button.button-stable {\n  border-color: transparent;\n  background-color: #f8f8f8;\n  color: #444; }\n\n.button.button-stable:hover {\n  color: #444;\n  text-decoration: none; }\n\n.button.button-stable.active, .button.button-stable.activated {\n  background-color: #e5e5e5; }\n\n.button.button-stable.button-clear {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  color: #b2b2b2; }\n\n.button.button-stable.button-icon {\n  border-color: transparent;\n  background: none; }\n\n.button.button-stable.button-outline {\n  border-color: #b2b2b2;\n  background: transparent;\n  color: #b2b2b2; }\n\n.button.button-stable.button-outline.active, .button.button-stable.button-outline.activated {\n  background-color: #b2b2b2;\n  box-shadow: none;\n  color: #fff; }\n\n.button.button-positive {\n  border-color: transparent;\n  background-color: #387ef5;\n  color: #fff; }\n\n.button.button-positive:hover {\n  color: #fff;\n  text-decoration: none; }\n\n.button.button-positive.active, .button.button-positive.activated {\n  background-color: #0c60ee; }\n\n.button.button-positive.button-clear {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  color: #387ef5; }\n\n.button.button-positive.button-icon {\n  border-color: transparent;\n  background: none; }\n\n.button.button-positive.button-outline {\n  border-color: #387ef5;\n  background: transparent;\n  color: #387ef5; }\n\n.button.button-positive.button-outline.active, .button.button-positive.button-outline.activated {\n  background-color: #387ef5;\n  box-shadow: none;\n  color: #fff; }\n\n.button.button-calm {\n  border-color: transparent;\n  background-color: #11c1f3;\n  color: #fff; }\n\n.button.button-calm:hover {\n  color: #fff;\n  text-decoration: none; }\n\n.button.button-calm.active, .button.button-calm.activated {\n  background-color: #0a9dc7; }\n\n.button.button-calm.button-clear {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  color: #11c1f3; }\n\n.button.button-calm.button-icon {\n  border-color: transparent;\n  background: none; }\n\n.button.button-calm.button-outline {\n  border-color: #11c1f3;\n  background: transparent;\n  color: #11c1f3; }\n\n.button.button-calm.button-outline.active, .button.button-calm.button-outline.activated {\n  background-color: #11c1f3;\n  box-shadow: none;\n  color: #fff; }\n\n.button.button-assertive {\n  border-color: transparent;\n  background-color: #ef473a;\n  color: #fff; }\n\n.button.button-assertive:hover {\n  color: #fff;\n  text-decoration: none; }\n\n.button.button-assertive.active, .button.button-assertive.activated {\n  background-color: #e42112; }\n\n.button.button-assertive.button-clear {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  color: #ef473a; }\n\n.button.button-assertive.button-icon {\n  border-color: transparent;\n  background: none; }\n\n.button.button-assertive.button-outline {\n  border-color: #ef473a;\n  background: transparent;\n  color: #ef473a; }\n\n.button.button-assertive.button-outline.active, .button.button-assertive.button-outline.activated {\n  background-color: #ef473a;\n  box-shadow: none;\n  color: #fff; }\n\n.button.button-balanced {\n  border-color: transparent;\n  background-color: #33cd5f;\n  color: #fff; }\n\n.button.button-balanced:hover {\n  color: #fff;\n  text-decoration: none; }\n\n.button.button-balanced.active, .button.button-balanced.activated {\n  background-color: #28a54c; }\n\n.button.button-balanced.button-clear {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  color: #33cd5f; }\n\n.button.button-balanced.button-icon {\n  border-color: transparent;\n  background: none; }\n\n.button.button-balanced.button-outline {\n  border-color: #33cd5f;\n  background: transparent;\n  color: #33cd5f; }\n\n.button.button-balanced.button-outline.active, .button.button-balanced.button-outline.activated {\n  background-color: #33cd5f;\n  box-shadow: none;\n  color: #fff; }\n\n.button.button-energized {\n  border-color: transparent;\n  background-color: #ffc900;\n  color: #fff; }\n\n.button.button-energized:hover {\n  color: #fff;\n  text-decoration: none; }\n\n.button.button-energized.active, .button.button-energized.activated {\n  background-color: #e6b500; }\n\n.button.button-energized.button-clear {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  color: #ffc900; }\n\n.button.button-energized.button-icon {\n  border-color: transparent;\n  background: none; }\n\n.button.button-energized.button-outline {\n  border-color: #ffc900;\n  background: transparent;\n  color: #ffc900; }\n\n.button.button-energized.button-outline.active, .button.button-energized.button-outline.activated {\n  background-color: #ffc900;\n  box-shadow: none;\n  color: #fff; }\n\n.button.button-royal {\n  border-color: transparent;\n  background-color: #886aea;\n  color: #fff; }\n\n.button.button-royal:hover {\n  color: #fff;\n  text-decoration: none; }\n\n.button.button-royal.active, .button.button-royal.activated {\n  background-color: #6b46e5; }\n\n.button.button-royal.button-clear {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  color: #886aea; }\n\n.button.button-royal.button-icon {\n  border-color: transparent;\n  background: none; }\n\n.button.button-royal.button-outline {\n  border-color: #886aea;\n  background: transparent;\n  color: #886aea; }\n\n.button.button-royal.button-outline.active, .button.button-royal.button-outline.activated {\n  background-color: #886aea;\n  box-shadow: none;\n  color: #fff; }\n\n.button.button-dark {\n  border-color: transparent;\n  background-color: #444;\n  color: #fff; }\n\n.button.button-dark:hover {\n  color: #fff;\n  text-decoration: none; }\n\n.button.button-dark.active, .button.button-dark.activated {\n  background-color: #262626; }\n\n.button.button-dark.button-clear {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  color: #444; }\n\n.button.button-dark.button-icon {\n  border-color: transparent;\n  background: none; }\n\n.button.button-dark.button-outline {\n  border-color: #444;\n  background: transparent;\n  color: #444; }\n\n.button.button-dark.button-outline.active, .button.button-dark.button-outline.activated {\n  background-color: #444;\n  box-shadow: none;\n  color: #fff; }\n\n.button-small {\n  padding: 2px 4px 1px;\n  min-width: 28px;\n  min-height: 30px;\n  font-size: 12px;\n  line-height: 26px; }\n\n.button-small .icon:before, .button-small.icon:before, .button-small.icon-left:before, .button-small.icon-right:before {\n  font-size: 16px;\n  line-height: 19px;\n  margin-top: 3px; }\n\n.button-large {\n  padding: 0 16px;\n  min-width: 68px;\n  min-height: 59px;\n  font-size: 20px;\n  line-height: 53px; }\n\n.button-large .icon:before, .button-large.icon:before, .button-large.icon-left:before, .button-large.icon-right:before {\n  padding-bottom: 2px;\n  font-size: 32px;\n  line-height: 51px; }\n\n.button-icon {\n  -webkit-transition: opacity 0.1s;\n  transition: opacity 0.1s;\n  padding: 0 6px;\n  min-width: initial;\n  border-color: transparent;\n  background: none; }\n\n.button-icon.button.active, .button-icon.button.activated {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  opacity: 0.3; }\n\n.button-icon .icon:before, .button-icon.icon:before {\n  font-size: 32px; }\n\n.button-clear {\n  -webkit-transition: opacity 0.1s;\n  transition: opacity 0.1s;\n  padding: 0 6px;\n  max-height: 42px;\n  border-color: transparent;\n  background: none;\n  box-shadow: none; }\n\n.button-clear.button-clear {\n  border-color: transparent;\n  background: none;\n  box-shadow: none;\n  color: #b2b2b2; }\n\n.button-clear.button-icon {\n  border-color: transparent;\n  background: none; }\n\n.button-clear.active, .button-clear.activated {\n  opacity: 0.3; }\n\n.button-outline {\n  -webkit-transition: opacity 0.1s;\n  transition: opacity 0.1s;\n  background: none;\n  box-shadow: none; }\n\n.button-outline.button-outline {\n  border-color: #b2b2b2;\n  background: transparent;\n  color: #b2b2b2; }\n\n.button-outline.button-outline.active, .button-outline.button-outline.activated {\n  background-color: #b2b2b2;\n  box-shadow: none;\n  color: #fff; }\n\n.padding > .button.button-block:first-child {\n  margin-top: 0; }\n\n.button-block {\n  display: block;\n  clear: both; }\n\n.button-block:after {\n  clear: both; }\n\n.button-full,\n.button-full > .button {\n  display: block;\n  margin-right: 0;\n  margin-left: 0;\n  border-right-width: 0;\n  border-left-width: 0;\n  border-radius: 0; }\n\nbutton.button-block,\nbutton.button-full,\n.button-full > button.button,\ninput.button.button-block {\n  width: 100%; }\n\na.button {\n  text-decoration: none; }\n\na.button .icon:before, a.button.icon:before, a.button.icon-left:before, a.button.icon-right:before {\n  margin-top: 2px; }\n\n.button.disabled,\n.button[disabled] {\n  opacity: .4;\n  cursor: default !important;\n  pointer-events: none; }\n\n/**\n * Button Bar\n * --------------------------------------------------\n */\n.button-bar {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  -webkit-box-flex: 1;\n  -webkit-flex: 1;\n  -moz-box-flex: 1;\n  -moz-flex: 1;\n  -ms-flex: 1;\n  flex: 1;\n  width: 100%; }\n\n.button-bar.button-bar-inline {\n  display: block;\n  width: auto;\n  *zoom: 1; }\n\n.button-bar.button-bar-inline:before, .button-bar.button-bar-inline:after {\n  display: table;\n  content: \"\";\n  line-height: 0; }\n\n.button-bar.button-bar-inline:after {\n  clear: both; }\n\n.button-bar.button-bar-inline > .button {\n  width: auto;\n  display: inline-block;\n  float: left; }\n\n.button-bar > .button {\n  -webkit-box-flex: 1;\n  -webkit-flex: 1;\n  -moz-box-flex: 1;\n  -moz-flex: 1;\n  -ms-flex: 1;\n  flex: 1;\n  display: block;\n  overflow: hidden;\n  padding: 0 16px;\n  width: 0;\n  border-width: 1px 0px 1px 1px;\n  border-radius: 0;\n  text-align: center;\n  text-overflow: ellipsis;\n  white-space: nowrap; }\n\n.button-bar > .button:before,\n.button-bar > .button .icon:before {\n  line-height: 44px; }\n\n.button-bar > .button:first-child {\n  border-radius: 4px 0px 0px 4px; }\n\n.button-bar > .button:last-child {\n  border-right-width: 1px;\n  border-radius: 0px 4px 4px 0px; }\n\n.button-bar > .button:only-child {\n  border-radius: 4px; }\n\n.button-bar > .button-small:before,\n.button-bar > .button-small .icon:before {\n  line-height: 28px; }\n\n/**\n * Grid\n * --------------------------------------------------\n * Using flexbox for the grid, inspired by Philip Walton:\n * http://philipwalton.github.io/solved-by-flexbox/demos/grids/\n * By default each .col within a .row will evenly take up\n * available width, and the height of each .col with take\n * up the height of the tallest .col in the same .row.\n */\n.row {\n  display: -webkit-box;\n  display: -webkit-flex;\n  display: -moz-box;\n  display: -moz-flex;\n  display: -ms-flexbox;\n  display: flex;\n  padding: 5px;\n  width: 100%; }\n\n.row-wrap {\n  -webkit-flex-wrap: wrap;\n  -moz-flex-wrap: wrap;\n  -ms-flex-wrap: wrap;\n  flex-wrap: wrap; }\n\n.row-no-padding {\n  padding: 0; }\n\n.row-no-padding > .col {\n  padding: 0; }\n\n.row + .row {\n  margin-top: -5px;\n  padding-top: 0; }\n\n.col {\n  -webkit-box-flex: 1;\n  -webkit-flex: 1;\n  -moz-box-flex: 1;\n  -moz-flex: 1;\n  -ms-flex: 1;\n  flex: 1;\n  display: block;\n  padding: 5px;\n  width: 100%; }\n\n/* Vertically Align Columns */\n/* .row-* vertically aligns every .col in the .row */\n.row-top {\n  -webkit-box-align: start;\n  -ms-flex-align: start;\n  -webkit-align-items: flex-start;\n  -moz-align-items: flex-start;\n  align-items: flex-start; }\n\n.row-bottom {\n  -webkit-box-align: end;\n  -ms-flex-align: end;\n  -webkit-align-items: flex-end;\n  -moz-align-items: flex-end;\n  align-items: flex-end; }\n\n.row-center {\n  -webkit-box-align: center;\n  -ms-flex-align: center;\n  -webkit-align-items: center;\n  -moz-align-items: center;\n  align-items: center; }\n\n.row-stretch {\n  -webkit-box-align: stretch;\n  -ms-flex-align: stretch;\n  -webkit-align-items: stretch;\n  -moz-align-items: stretch;\n  align-items: stretch; }\n\n.row-baseline {\n  -webkit-box-align: baseline;\n  -ms-flex-align: baseline;\n  -webkit-align-items: baseline;\n  -moz-align-items: baseline;\n  align-items: baseline; }\n\n/* .col-* vertically aligns an individual .col */\n.col-top {\n  -webkit-align-self: flex-start;\n  -moz-align-self: flex-start;\n  -ms-flex-item-align: start;\n  align-self: flex-start; }\n\n.col-bottom {\n  -webkit-align-self: flex-end;\n  -moz-align-self: flex-end;\n  -ms-flex-item-align: end;\n  align-self: flex-end; }\n\n.col-center {\n  -webkit-align-self: center;\n  -moz-align-self: center;\n  -ms-flex-item-align: center;\n  align-self: center; }\n\n/* Column Offsets */\n.col-offset-10 {\n  margin-left: 10%; }\n\n.col-offset-20 {\n  margin-left: 20%; }\n\n.col-offset-25 {\n  margin-left: 25%; }\n\n.col-offset-33, .col-offset-34 {\n  margin-left: 33.3333%; }\n\n.col-offset-50 {\n  margin-left: 50%; }\n\n.col-offset-66, .col-offset-67 {\n  margin-left: 66.6666%; }\n\n.col-offset-75 {\n  margin-left: 75%; }\n\n.col-offset-80 {\n  margin-left: 80%; }\n\n.col-offset-90 {\n  margin-left: 90%; }\n\n/* Explicit Column Percent Sizes */\n/* By default each grid column will evenly distribute */\n/* across the grid. However, you can specify individual */\n/* columns to take up a certain size of the available area */\n.col-10 {\n  -webkit-box-flex: 0;\n  -webkit-flex: 0 0 10%;\n  -moz-box-flex: 0;\n  -moz-flex: 0 0 10%;\n  -ms-flex: 0 0 10%;\n  flex: 0 0 10%;\n  max-width: 10%; }\n\n.col-20 {\n  -webkit-box-flex: 0;\n  -webkit-flex: 0 0 20%;\n  -moz-box-flex: 0;\n  -moz-flex: 0 0 20%;\n  -ms-flex: 0 0 20%;\n  flex: 0 0 20%;\n  max-width: 20%; }\n\n.col-25 {\n  -webkit-box-flex: 0;\n  -webkit-flex: 0 0 25%;\n  -moz-box-flex: 0;\n  -moz-flex: 0 0 25%;\n  -ms-flex: 0 0 25%;\n  flex: 0 0 25%;\n  max-width: 25%; }\n\n.col-33, .col-34 {\n  -webkit-box-flex: 0;\n  -webkit-flex: 0 0 33.3333%;\n  -moz-box-flex: 0;\n  -moz-flex: 0 0 33.3333%;\n  -ms-flex: 0 0 33.3333%;\n  flex: 0 0 33.3333%;\n  max-width: 33.3333%; }\n\n.col-40 {\n  -webkit-box-flex: 0;\n  -webkit-flex: 0 0 40%;\n  -moz-box-flex: 0;\n  -moz-flex: 0 0 40%;\n  -ms-flex: 0 0 40%;\n  flex: 0 0 40%;\n  max-width: 40%; }\n\n.col-50 {\n  -webkit-box-flex: 0;\n  -webkit-flex: 0 0 50%;\n  -moz-box-flex: 0;\n  -moz-flex: 0 0 50%;\n  -ms-flex: 0 0 50%;\n  flex: 0 0 50%;\n  max-width: 50%; }\n\n.col-60 {\n  -webkit-box-flex: 0;\n  -webkit-flex: 0 0 60%;\n  -moz-box-flex: 0;\n  -moz-flex: 0 0 60%;\n  -ms-flex: 0 0 60%;\n  flex: 0 0 60%;\n  max-width: 60%; }\n\n.col-66, .col-67 {\n  -webkit-box-flex: 0;\n  -webkit-flex: 0 0 66.6666%;\n  -moz-box-flex: 0;\n  -moz-flex: 0 0 66.6666%;\n  -ms-flex: 0 0 66.6666%;\n  flex: 0 0 66.6666%;\n  max-width: 66.6666%; }\n\n.col-75 {\n  -webkit-box-flex: 0;\n  -webkit-flex: 0 0 75%;\n  -moz-box-flex: 0;\n  -moz-flex: 0 0 75%;\n  -ms-flex: 0 0 75%;\n  flex: 0 0 75%;\n  max-width: 75%; }\n\n.col-80 {\n  -webkit-box-flex: 0;\n  -webkit-flex: 0 0 80%;\n  -moz-box-flex: 0;\n  -moz-flex: 0 0 80%;\n  -ms-flex: 0 0 80%;\n  flex: 0 0 80%;\n  max-width: 80%; }\n\n.col-90 {\n  -webkit-box-flex: 0;\n  -webkit-flex: 0 0 90%;\n  -moz-box-flex: 0;\n  -moz-flex: 0 0 90%;\n  -ms-flex: 0 0 90%;\n  flex: 0 0 90%;\n  max-width: 90%; }\n\n/* Responsive Grid Classes */\n/* Adding a class of responsive-X to a row */\n/* will trigger the flex-direction to */\n/* change to column and add some margin */\n/* to any columns in the row for clearity */\n@media (max-width: 567px) {\n  .responsive-sm {\n    -webkit-box-direction: normal;\n    -moz-box-direction: normal;\n    -webkit-box-orient: vertical;\n    -moz-box-orient: vertical;\n    -webkit-flex-direction: column;\n    -ms-flex-direction: column;\n    flex-direction: column; }\n  .responsive-sm .col, .responsive-sm .col-10, .responsive-sm .col-20, .responsive-sm .col-25, .responsive-sm .col-33, .responsive-sm .col-34, .responsive-sm .col-50, .responsive-sm .col-66, .responsive-sm .col-67, .responsive-sm .col-75, .responsive-sm .col-80, .responsive-sm .col-90 {\n    -webkit-box-flex: 1;\n    -webkit-flex: 1;\n    -moz-box-flex: 1;\n    -moz-flex: 1;\n    -ms-flex: 1;\n    flex: 1;\n    margin-bottom: 15px;\n    margin-left: 0;\n    max-width: 100%;\n    width: 100%; } }\n\n@media (max-width: 767px) {\n  .responsive-md {\n    -webkit-box-direction: normal;\n    -moz-box-direction: normal;\n    -webkit-box-orient: vertical;\n    -moz-box-orient: vertical;\n    -webkit-flex-direction: column;\n    -ms-flex-direction: column;\n    flex-direction: column; }\n  .responsive-md .col, .responsive-md .col-10, .responsive-md .col-20, .responsive-md .col-25, .responsive-md .col-33, .responsive-md .col-34, .responsive-md .col-50, .responsive-md .col-66, .responsive-md .col-67, .responsive-md .col-75, .responsive-md .col-80, .responsive-md .col-90 {\n    -webkit-box-flex: 1;\n    -webkit-flex: 1;\n    -moz-box-flex: 1;\n    -moz-flex: 1;\n    -ms-flex: 1;\n    flex: 1;\n    margin-bottom: 15px;\n    margin-left: 0;\n    max-width: 100%;\n    width: 100%; } }\n\n@media (max-width: 1023px) {\n  .responsive-lg {\n    -webkit-box-direction: normal;\n    -moz-box-direction: normal;\n    -webkit-box-orient: vertical;\n    -moz-box-orient: vertical;\n    -webkit-flex-direction: column;\n    -ms-flex-direction: column;\n    flex-direction: column; }\n  .responsive-lg .col, .responsive-lg .col-10, .responsive-lg .col-20, .responsive-lg .col-25, .responsive-lg .col-33, .responsive-lg .col-34, .responsive-lg .col-50, .responsive-lg .col-66, .responsive-lg .col-67, .responsive-lg .col-75, .responsive-lg .col-80, .responsive-lg .col-90 {\n    -webkit-box-flex: 1;\n    -webkit-flex: 1;\n    -moz-box-flex: 1;\n    -moz-flex: 1;\n    -ms-flex: 1;\n    flex: 1;\n    margin-bottom: 15px;\n    margin-left: 0;\n    max-width: 100%;\n    width: 100%; } }\n\n/**\n * Utility Classes\n * --------------------------------------------------\n */\n.hide {\n  display: none; }\n\n.opacity-hide {\n  opacity: 0; }\n\n.grade-b .opacity-hide,\n.grade-c .opacity-hide {\n  opacity: 1;\n  display: none; }\n\n.show {\n  display: block; }\n\n.opacity-show {\n  opacity: 1; }\n\n.invisible {\n  visibility: hidden; }\n\n.keyboard-open .hide-on-keyboard-open {\n  display: none; }\n\n.keyboard-open .tabs.hide-on-keyboard-open + .pane .has-tabs,\n.keyboard-open .bar-footer.hide-on-keyboard-open + .pane .has-footer {\n  bottom: 0; }\n\n.inline {\n  display: inline-block; }\n\n.disable-pointer-events {\n  pointer-events: none; }\n\n.enable-pointer-events {\n  pointer-events: auto; }\n\n.disable-user-behavior {\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n  -webkit-touch-callout: none;\n  -webkit-tap-highlight-color: transparent;\n  -webkit-tap-highlight-color: transparent;\n  -webkit-user-drag: none;\n  -ms-touch-action: none;\n  -ms-content-zooming: none; }\n\n.click-block {\n  position: absolute;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  opacity: 0;\n  z-index: 99999;\n  -webkit-transform: translate3d(0, 0, 0);\n  transform: translate3d(0, 0, 0);\n  overflow: hidden; }\n\n.click-block-hide {\n  -webkit-transform: translate3d(-9999px, 0, 0);\n  transform: translate3d(-9999px, 0, 0); }\n\n.no-resize {\n  resize: none; }\n\n.block {\n  display: block;\n  clear: both; }\n\n.block:after {\n  display: block;\n  visibility: hidden;\n  clear: both;\n  height: 0;\n  content: \".\"; }\n\n.full-image {\n  width: 100%; }\n\n.clearfix {\n  *zoom: 1; }\n\n.clearfix:before, .clearfix:after {\n  display: table;\n  content: \"\";\n  line-height: 0; }\n\n.clearfix:after {\n  clear: both; }\n\n/**\n * Content Padding\n * --------------------------------------------------\n */\n.padding {\n  padding: 10px; }\n\n.padding-top,\n.padding-vertical {\n  padding-top: 10px; }\n\n.padding-right,\n.padding-horizontal {\n  padding-right: 10px; }\n\n.padding-bottom,\n.padding-vertical {\n  padding-bottom: 10px; }\n\n.padding-left,\n.padding-horizontal {\n  padding-left: 10px; }\n\n/**\n * Scrollable iFrames\n * --------------------------------------------------\n */\n.iframe-wrapper {\n  position: fixed;\n  -webkit-overflow-scrolling: touch;\n  overflow: scroll; }\n\n.iframe-wrapper iframe {\n  height: 100%;\n  width: 100%; }\n\n/**\n * Rounded\n * --------------------------------------------------\n */\n.rounded {\n  border-radius: 4px; }\n\n/**\n * Utility Colors\n * --------------------------------------------------\n * Utility colors are added to help set a naming convention. You'll\n * notice we purposely do not use words like \"red\" or \"blue\", but\n * instead have colors which represent an emotion or generic theme.\n */\n.light, a.light {\n  color: #fff; }\n\n.light-bg {\n  background-color: #fff; }\n\n.light-border {\n  border-color: #ddd; }\n\n.stable, a.stable {\n  color: #f8f8f8; }\n\n.stable-bg {\n  background-color: #f8f8f8; }\n\n.stable-border {\n  border-color: #b2b2b2; }\n\n.positive, a.positive {\n  color: #387ef5; }\n\n.positive-bg {\n  background-color: #387ef5; }\n\n.positive-border {\n  border-color: #0c60ee; }\n\n.calm, a.calm {\n  color: #11c1f3; }\n\n.calm-bg {\n  background-color: #11c1f3; }\n\n.calm-border {\n  border-color: #0a9dc7; }\n\n.assertive, a.assertive {\n  color: #ef473a; }\n\n.assertive-bg {\n  background-color: #ef473a; }\n\n.assertive-border {\n  border-color: #e42112; }\n\n.balanced, a.balanced {\n  color: #33cd5f; }\n\n.balanced-bg {\n  background-color: #33cd5f; }\n\n.balanced-border {\n  border-color: #28a54c; }\n\n.energized, a.energized {\n  color: #ffc900; }\n\n.energized-bg {\n  background-color: #ffc900; }\n\n.energized-border {\n  border-color: #e6b500; }\n\n.royal, a.royal {\n  color: #886aea; }\n\n.royal-bg {\n  background-color: #886aea; }\n\n.royal-border {\n  border-color: #6b46e5; }\n\n.dark, a.dark {\n  color: #444; }\n\n.dark-bg {\n  background-color: #444; }\n\n.dark-border {\n  border-color: #111; }\n\n[collection-repeat] {\n  /* Position is set by transforms */\n  left: 0 !important;\n  top: 0 !important;\n  position: absolute !important;\n  z-index: 1; }\n\n.collection-repeat-container {\n  position: relative;\n  z-index: 1; }\n\n.collection-repeat-after-container {\n  z-index: 0;\n  display: block;\n  /* when scrolling horizontally, make sure the after container doesn't take up 100% width */ }\n\n.collection-repeat-after-container.horizontal {\n  display: inline-block; }\n\n[ng\\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak,\n.x-ng-cloak, .ng-hide:not(.ng-hide-animate) {\n  display: none !important; }\n\n/**\n * Platform\n * --------------------------------------------------\n * Platform specific tweaks\n */\n.platform-ios.platform-cordova:not(.fullscreen) .bar-header:not(.bar-subheader) {\n  height: 64px; }\n\n.platform-ios.platform-cordova:not(.fullscreen) .bar-header:not(.bar-subheader).item-input-inset .item-input-wrapper {\n  margin-top: 19px !important; }\n\n.platform-ios.platform-cordova:not(.fullscreen) .bar-header:not(.bar-subheader) > * {\n  margin-top: 20px; }\n\n.platform-ios.platform-cordova:not(.fullscreen) .tabs-top > .tabs,\n.platform-ios.platform-cordova:not(.fullscreen) .tabs.tabs-top {\n  top: 64px; }\n\n.platform-ios.platform-cordova:not(.fullscreen) .has-header,\n.platform-ios.platform-cordova:not(.fullscreen) .bar-subheader {\n  top: 64px; }\n\n.platform-ios.platform-cordova:not(.fullscreen) .has-subheader {\n  top: 108px; }\n\n.platform-ios.platform-cordova:not(.fullscreen) .has-header.has-tabs-top {\n  top: 113px; }\n\n.platform-ios.platform-cordova:not(.fullscreen) .has-header.has-subheader.has-tabs-top {\n  top: 157px; }\n\n.platform-ios.platform-cordova .popover .bar-header:not(.bar-subheader) {\n  height: 44px; }\n\n.platform-ios.platform-cordova .popover .bar-header:not(.bar-subheader).item-input-inset .item-input-wrapper {\n  margin-top: -1px; }\n\n.platform-ios.platform-cordova .popover .bar-header:not(.bar-subheader) > * {\n  margin-top: 0; }\n\n.platform-ios.platform-cordova .popover .has-header,\n.platform-ios.platform-cordova .popover .bar-subheader {\n  top: 44px; }\n\n.platform-ios.platform-cordova .popover .has-subheader {\n  top: 88px; }\n\n.platform-ios.platform-cordova.status-bar-hide {\n  margin-bottom: 20px; }\n\n@media (orientation: landscape) {\n  .platform-ios.platform-browser.platform-ipad {\n    position: fixed; } }\n\n.platform-c:not(.enable-transitions) * {\n  -webkit-transition: none !important;\n  transition: none !important; }\n\n.slide-in-up {\n  -webkit-transform: translate3d(0, 100%, 0);\n  transform: translate3d(0, 100%, 0); }\n\n.slide-in-up.ng-enter,\n.slide-in-up > .ng-enter {\n  -webkit-transition: all cubic-bezier(0.1, 0.7, 0.1, 1) 400ms;\n  transition: all cubic-bezier(0.1, 0.7, 0.1, 1) 400ms; }\n\n.slide-in-up.ng-enter-active,\n.slide-in-up > .ng-enter-active {\n  -webkit-transform: translate3d(0, 0, 0);\n  transform: translate3d(0, 0, 0); }\n\n.slide-in-up.ng-leave,\n.slide-in-up > .ng-leave {\n  -webkit-transition: all ease-in-out 250ms;\n  transition: all ease-in-out 250ms; }\n\n@-webkit-keyframes scaleOut {\n  from {\n    -webkit-transform: scale(1);\n    opacity: 1; }\n  to {\n    -webkit-transform: scale(0.8);\n    opacity: 0; } }\n\n@keyframes scaleOut {\n  from {\n    transform: scale(1);\n    opacity: 1; }\n  to {\n    transform: scale(0.8);\n    opacity: 0; } }\n\n@-webkit-keyframes superScaleIn {\n  from {\n    -webkit-transform: scale(1.2);\n    opacity: 0; }\n  to {\n    -webkit-transform: scale(1);\n    opacity: 1; } }\n\n@keyframes superScaleIn {\n  from {\n    transform: scale(1.2);\n    opacity: 0; }\n  to {\n    transform: scale(1);\n    opacity: 1; } }\n\n[nav-view-transition=\"ios\"] [nav-view=\"entering\"],\n[nav-view-transition=\"ios\"] [nav-view=\"leaving\"] {\n  -webkit-transition-duration: 500ms;\n  transition-duration: 500ms;\n  -webkit-transition-timing-function: cubic-bezier(0.36, 0.66, 0.04, 1);\n  transition-timing-function: cubic-bezier(0.36, 0.66, 0.04, 1);\n  -webkit-transition-property: opacity, -webkit-transform, box-shadow;\n  transition-property: opacity, transform, box-shadow; }\n\n[nav-view-transition=\"ios\"][nav-view-direction=\"forward\"], [nav-view-transition=\"ios\"][nav-view-direction=\"back\"] {\n  background-color: #000; }\n\n[nav-view-transition=\"ios\"] [nav-view=\"active\"],\n[nav-view-transition=\"ios\"][nav-view-direction=\"forward\"] [nav-view=\"entering\"],\n[nav-view-transition=\"ios\"][nav-view-direction=\"back\"] [nav-view=\"leaving\"] {\n  z-index: 3; }\n\n[nav-view-transition=\"ios\"][nav-view-direction=\"back\"] [nav-view=\"entering\"],\n[nav-view-transition=\"ios\"][nav-view-direction=\"forward\"] [nav-view=\"leaving\"] {\n  z-index: 2; }\n\n[nav-bar-transition=\"ios\"] .title,\n[nav-bar-transition=\"ios\"] .buttons,\n[nav-bar-transition=\"ios\"] .back-text {\n  -webkit-transition-duration: 500ms;\n  transition-duration: 500ms;\n  -webkit-transition-timing-function: cubic-bezier(0.36, 0.66, 0.04, 1);\n  transition-timing-function: cubic-bezier(0.36, 0.66, 0.04, 1);\n  -webkit-transition-property: opacity, -webkit-transform;\n  transition-property: opacity, transform; }\n\n[nav-bar-transition=\"ios\"] [nav-bar=\"active\"],\n[nav-bar-transition=\"ios\"] [nav-bar=\"entering\"] {\n  z-index: 10; }\n\n[nav-bar-transition=\"ios\"] [nav-bar=\"active\"] .bar,\n[nav-bar-transition=\"ios\"] [nav-bar=\"entering\"] .bar {\n  background: transparent; }\n\n[nav-bar-transition=\"ios\"] [nav-bar=\"cached\"] {\n  display: block; }\n\n[nav-bar-transition=\"ios\"] [nav-bar=\"cached\"] .header-item {\n  display: none; }\n\n[nav-view-transition=\"android\"] [nav-view=\"entering\"],\n[nav-view-transition=\"android\"] [nav-view=\"leaving\"] {\n  -webkit-transition-duration: 200ms;\n  transition-duration: 200ms;\n  -webkit-transition-timing-function: cubic-bezier(0.4, 0.6, 0.2, 1);\n  transition-timing-function: cubic-bezier(0.4, 0.6, 0.2, 1);\n  -webkit-transition-property: -webkit-transform;\n  transition-property: transform; }\n\n[nav-view-transition=\"android\"] [nav-view=\"active\"],\n[nav-view-transition=\"android\"][nav-view-direction=\"forward\"] [nav-view=\"entering\"],\n[nav-view-transition=\"android\"][nav-view-direction=\"back\"] [nav-view=\"leaving\"] {\n  z-index: 3; }\n\n[nav-view-transition=\"android\"][nav-view-direction=\"back\"] [nav-view=\"entering\"],\n[nav-view-transition=\"android\"][nav-view-direction=\"forward\"] [nav-view=\"leaving\"] {\n  z-index: 2; }\n\n[nav-bar-transition=\"android\"] .title,\n[nav-bar-transition=\"android\"] .buttons {\n  -webkit-transition-duration: 200ms;\n  transition-duration: 200ms;\n  -webkit-transition-timing-function: cubic-bezier(0.4, 0.6, 0.2, 1);\n  transition-timing-function: cubic-bezier(0.4, 0.6, 0.2, 1);\n  -webkit-transition-property: opacity;\n  transition-property: opacity; }\n\n[nav-bar-transition=\"android\"] [nav-bar=\"active\"],\n[nav-bar-transition=\"android\"] [nav-bar=\"entering\"] {\n  z-index: 10; }\n\n[nav-bar-transition=\"android\"] [nav-bar=\"active\"] .bar,\n[nav-bar-transition=\"android\"] [nav-bar=\"entering\"] .bar {\n  background: transparent; }\n\n[nav-bar-transition=\"android\"] [nav-bar=\"cached\"] {\n  display: block; }\n\n[nav-bar-transition=\"android\"] [nav-bar=\"cached\"] .header-item {\n  display: none; }\n\n[nav-swipe=\"fast\"] [nav-view],\n[nav-swipe=\"fast\"] .title,\n[nav-swipe=\"fast\"] .buttons,\n[nav-swipe=\"fast\"] .back-text {\n  -webkit-transition-duration: 50ms;\n  transition-duration: 50ms;\n  -webkit-transition-timing-function: linear;\n  transition-timing-function: linear; }\n\n[nav-swipe=\"slow\"] [nav-view],\n[nav-swipe=\"slow\"] .title,\n[nav-swipe=\"slow\"] .buttons,\n[nav-swipe=\"slow\"] .back-text {\n  -webkit-transition-duration: 160ms;\n  transition-duration: 160ms;\n  -webkit-transition-timing-function: linear;\n  transition-timing-function: linear; }\n\n[nav-view=\"cached\"],\n[nav-bar=\"cached\"] {\n  display: none; }\n\n[nav-view=\"stage\"] {\n  opacity: 0;\n  -webkit-transition-duration: 0;\n  transition-duration: 0; }\n\n[nav-bar=\"stage\"] .title,\n[nav-bar=\"stage\"] .buttons,\n[nav-bar=\"stage\"] .back-text {\n  position: absolute;\n  opacity: 0;\n  -webkit-transition-duration: 0s;\n  transition-duration: 0s; }\n\n.item-image i:last-child {\n  position: absolute;\n  border-radius: 50%;\n  width: 20px;\n  height: 20px;\n  background-color: black;\n  top: 15px;\n  right: 15px; }\n\n.link-span {\n  cursor: pointer;\n  color: #387ef5; }\n\n.center {\n  margin-left: auto;\n  margin-right: auto;\n  display: block; }\n\np ul {\n  list-style-type: disc !important;\n  list-style-position: inside !important; }\n"
  },
  {
    "path": "mobile/www/css/style.css",
    "content": "/* General classes */\n.pull-right {\n    float:right;\n}\n.clearfix {\n    clear:both;\n}\n.subheading, .date {\n    font-size:12px;\n    font-style:italic;\n}\n\n.center {\n    margin-left: auto;\n    margin-right: auto;\n    display: block;\n}\n\n/* More specific to sections of app */\n.profile-name .subheading, .profile-name .date {\n    vertical-align: top;\n}\n\ndiv .tatami-avatar {\n    min-height: 42px;\n}\n\n.tatami-attached-image{\n    height: auto;\n    max-width: 350px;\n}\n\n.bar .bar-header .title {\n    left:0!important;\n    right:0!important;\n}\n.bar .bar-header .title a {\n    text-decoration: none;\n}\n.bar .bar-header .title img {\n    margin: 0 auto;\n    vertical-align: middle;\n}\n\n/* Platform specific styles */\n.platform-ios .tab-nav.tabs {\n    bottom:43px;\n}\n\n.platform-ios .bar.bar-footer {\n    bottom: 43px; !important;\n}\n\n.platform-ios .tatami-header {\n    top: 64px;\n}\n\n.platform-ios .tatami-footer {\n    bottom: 88px;\n}\n\n.platform-android .tatami-header {\n    top: 88px;\n}\n\n.platform-android .tatami-footer {\n    bottom: 44px;\n}\n\n.v-align {\n    vertical-align: middle !important;\n}\n\n"
  },
  {
    "path": "mobile/www/i18n/en/conversation.json",
    "content": "{\n    \"conversation\": {\n        \"title\": \"Conversation\"\n    }\n}\n"
  },
  {
    "path": "mobile/www/i18n/en/follow.json",
    "content": "{\n    \"tab\": {\n        \"follower\": \"Followers\",\n        \"following\": \"Following\",\n        \"suggested\": {\n            \"title\": \"Suggested\",\n            \"who\": \"Who to Follow\"\n        }\n    }\n}\n"
  },
  {
    "path": "mobile/www/i18n/en/home.json",
    "content": "{\n    \"tab\": {\n        \"timeline\": \"Timeline\",\n        \"mentions\": \"Mentions\",\n        \"favorites\": \"Favorites\",\n        \"more\": \"More\"\n    },\n    \"noContent\" : \"No content found\"\n\n}\n"
  },
  {
    "path": "mobile/www/i18n/en/login.json",
    "content": "{\n    \"login\": {\n        \"title\": \"Login\",\n        \"email\": \"E-mail\",\n        \"password\": \"Password\",\n        \"google\": \"Google Login\",\n        \"success\": \"Logged In!\",\n        \"failed\": \"Failed to log in!\",\n        \"progress\": \"Login in progress...\",\n        \"googleUnavaible\": \"Google Login unavailable\",\n        \"tos\": \"Terms of Service\",\n        \"accept\": \"Accept\",\n        \"changeServer\": \"Change Tatami server\",\n        \"endpoint\": {\n            \"current\": \"Current Server:\"\n        }\n    }\n}\n"
  },
  {
    "path": "mobile/www/i18n/en/more.json",
    "content": "{\n    \"more\": {\n        \"title\": \"More Options\",\n        \"company\": \"Company Timeline\",\n        \"settings\": \"Settings\",\n        \"blockedUsers\": {\n            \"title\": \"Blocked Users\",\n            \"no\": \"You don't have any blocked users\"\n        },\n        \"reportedStatus\":{\n            \"title\": \"Reported Statuses\",\n            \"no\": \"You don't have any reported statuses\"\n        },\n        \"logout\": \"Logout\",\n        \"language\": {\n            \"change\": \"Language\",\n            \"english\": \"English\",\n            \"french\": \"French\"\n        },\n        \"allUsers\": \"All Users\"\n    }\n\n}\n"
  },
  {
    "path": "mobile/www/i18n/en/post.json",
    "content": "{\n    \"post\": {\n        \"title\": \"Post\",\n        \"message\": \"Post Here...\",\n        \"progress\": \"Post in progress...\",\n        \"error\": {\n            \"message\": \"Something went wrong. Returning to Timeline\",\n            \"truncated\": \"Your post has been truncated to remain under the max length.\"\n        },\n        \"location\": {\n            \"share\": \"You will share your location\",\n            \"unshare\": \"You won't share your location\",\n            \"fail\": \"Location failure. Please check that your GPS is enabled on your device\"\n        },\n        \"private\": {\n            \"yes\": \"Your message will be private\",\n            \"no\": \"Your message will be public\"\n        }\n    }\n}\n"
  },
  {
    "path": "mobile/www/i18n/en/server.json",
    "content": "{\n    \"server\": {\n        \"success\": \"Logged In!\",\n        \"failed\": \"Failed to log in!\",\n        \"progress\": \"Login in progress...\",\n        \"endpoint\": {\n            \"title\": \"Server\",\n            \"current\": \"Current Server:\",\n            \"change\": \"Change Server\",\n            \"error\": {\n                \"title\": \"Error\",\n                \"body\": \"Failed to change endpoint - cannot reach server.\"\n            },\n            \"authenticate\": {\n                \"title\": \"Success\",\n                \"body\": \"Endpoint changed - please reauthenticate with the new server.\"\n            },\n            \"default\": \"Use default server\"\n        }\n    }\n}\n"
  },
  {
    "path": "mobile/www/i18n/en/status.json",
    "content": "{\n    \"status\": {\n        \"share\": {\n            \"title\": \"shared\",\n            \"mention\": \"Your status has been shared\",\n            \"toast\": \"You have shared this status\",\n            \"action\": \"Share status\"\n        },\n        \"reply\": \"In reply to \",\n        \"follower\": \"New follower\",\n        \"delete\": \"Are you sure you want to delete this status?\",\n        \"report\" : \"Report\",\n        \"reportMessage\": \"This status has been reported\",\n        \"reportStatus\":{\n            \"message\": \"Are you sure you want to report this status? This action cannot be undone.\",\n            \"toast\": \"Status has been reported\",\n            \"approve\": \"Are you sure you approve this status? It will continue to be displayed on the Company Timeline.\",\n            \"approveToast\": \"Status has been approved\",\n            \"delete\": \"Are you sure you want to delete this status? This action cannot be undone.\",\n            \"deleteToast\": \"Status has been deleted\"\n        },\n        \"block\": {\n            \"reportStatus\": \"Report status\",\n            \"blockUser\": \"Block user\",\n            \"delete\": \"Delete\"\n        },\n        \"announcement\": {\n            \"title\": \"announced\",\n            \"mention\": \"Your status has been announced\",\n            \"toast\": \"You have announced this status\",\n            \"action\": \"Announce status\"\n        },\n        \"hide\": {\n            \"action\": \"Hide status\",\n            \"toast\": \"This status has been removed from your timeline\"\n        },\n        \"favorite\": {\n            \"add\": \"This status has been added to your favorites\",\n            \"remove\": \"This status has been removed from your favorites\"\n        },\n        \"private\": \"Private message\",\n        \"noContent\" : \"No content found\"\n    }\n}\n"
  },
  {
    "path": "mobile/www/i18n/en/user.json",
    "content": "{\n    \"user\": {\n        \"profile\": {\n            \"title\": \"Profile\",\n            \"options\": {\n                \"block\": \"Block User\",\n                \"deactivate\": \"Deactivate User\",\n                \"reactivate\": \"Reactivate User\"\n            }\n        },\n        \"follow\": \"Follow\",\n        \"unfollow\": \"Unfollow\",\n        \"block\":{\n            \"success\": \"You have blocked this user\",\n            \"title\": \"Block\",\n            \"confirmation\": \"Are you sure you want to block this user? You won't be able to see their posts anymore.\"\n        } ,\n        \"unblock\": {\n            \"success\": \"You have unblocked this user\",\n            \"title\": \"Unblock\"\n        },\n        \"reactivate\": {\n            \"title\": \"Reactivate\",\n            \"confirmation\": \"Are you sure you want to reactivate this user?\"\n        },\n        \"deactivate\": {\n            \"title\": \"Deactivate\",\n            \"confirmation\": \"Are you sure you want to deactivate this user? They won't be able to log in to Tatami.\"\n        }\n    }\n}\n"
  },
  {
    "path": "mobile/www/i18n/fr/conversation.json",
    "content": "{\n    \"conversation\": {\n        \"title\": \"Conversation\"\n    }\n}\n"
  },
  {
    "path": "mobile/www/i18n/fr/follow.json",
    "content": "{\n    \"tab\": {\n        \"follower\": \"Abonnés\",\n        \"following\": \"Abonnement\",\n        \"suggested\": {\n            \"title\": \"Recommandé\",\n            \"who\": \"Qui suivre\"\n        }\n    }\n}\n"
  },
  {
    "path": "mobile/www/i18n/fr/home.json",
    "content": "{\n    \"tab\": {\n        \"timeline\": \"Timeline\",\n        \"mentions\": \"Mentions\",\n        \"favorites\": \"Favoris\",\n        \"more\": \"Plus\"\n    },\n    \"noContent\" : \"Cette section est actuellement vide\"\n}\n"
  },
  {
    "path": "mobile/www/i18n/fr/login.json",
    "content": "{\n    \"login\": {\n        \"title\": \"Login\",\n        \"email\": \"E-mail\",\n        \"password\": \"Mot de passe\",\n        \"google\": \"Google Login\",\n        \"success\": \"Connexion effectuée !\",\n        \"failed\": \"Echec de connexion\",\n        \"progress\": \"Connexion en cours...\",\n        \"googleUnavaible\": \"Google Login indisponible\",\n        \"tos\": \"conditions d'utilisation\",\n        \"accept\": \"Accepter les\",\n        \"changeServer\": \"Changer le serveur Tatami\",\n        \"endpoint\": {\n            \"current\": \"Serveur Actuel:\"\n        }\n    }\n}\n"
  },
  {
    "path": "mobile/www/i18n/fr/more.json",
    "content": "{\n    \"more\": {\n        \"title\": \"Plus d'options\",\n        \"company\": \"Timeline de l'entreprise\",\n        \"settings\": \"Paramètres\",\n        \"blockedUsers\": {\n            \"title\": \"Gérer vos utilisateurs bloqués\",\n            \"no\": \"Vous n'avez bloqué aucun utilisateur\"\n        },\n        \"reportedStatus\": {\n            \"title\": \"Statuts signalés\",\n            \"no\": \"Aucun statut n'a été signalé\"\n        },\n        \"logout\": \"Déconnexion\",\n        \"language\": {\n            \"change\": \"Langue\",\n            \"english\": \"Anglais\",\n            \"french\": \"Français\"\n        },\n        \"allUsers\": \"Tous les utilisateurs\"\n    }\n\n}\n"
  },
  {
    "path": "mobile/www/i18n/fr/post.json",
    "content": "{\n    \"post\": {\n        \"title\": \"Post\",\n        \"message\": \"Ecrivez votre message ici...\",\n        \"progress\": \"Publication en cours...\",\n        \"error\": {\n            \"message\": \"Un problème est survenu. Retour à la Timeline.\",\n            \"truncated\": \"Votre message a été tronqué afin de respecter la longueur maximale autorisée\"\n        },\n        \"location\": {\n            \"share\": \"Votre position sera partagée\",\n            \"unshare\": \"Votre position ne sera pas partagée\",\n            \"fail\": \"Echec de la localisation. Vérifiez que le GPS de votre téléphone est activé\"\n        },\n        \"private\": {\n            \"yes\": \"Votre message sera privé\",\n            \"no\": \"Votre message sera public\"\n        }\n    }\n}\n"
  },
  {
    "path": "mobile/www/i18n/fr/server.json",
    "content": "{\n    \"server\": {\n        \"success\": \"Connexion effectuée !\",\n        \"failed\": \"Echec de connexion\",\n        \"progress\": \"Connexion en cours...\",\n        \"endpoint\": {\n            \"title\": \"Serveur\",\n            \"current\": \"Serveur Actuel:\",\n            \"change\": \"Changer de serveur\",\n            \"error\": {\n                \"title\": \"Échec de la modification du serveur\",\n                \"body\": \"Serveur inaccessible.\"\n            },\n            \"authenticate\": {\n                \"title\": \"Changement de serveur effectué\",\n                \"body\": \"Veuillez-vous identifier avec le nouveau serveur.\"\n            },\n            \"default\": \"Utiliser le serveur par défaut\"\n        }\n    }\n}\n"
  },
  {
    "path": "mobile/www/i18n/fr/status.json",
    "content": "{\n    \"status\": {\n        \"share\": {\n            \"title\": \"a partagé\",\n            \"mention\": \"Votre statut a été partagé\",\n            \"toast\": \"Vous avez partagé ce statut\",\n            \"action\": \"Partager\"\n        },\n        \"reply\": \"En réponse à \",\n        \"follower\": \"Nouvel abonné\",\n        \"delete\": \"Êtes-vous sûr de vouloir supprimer ce statut ?\",\n        \"report\" : \"Supprimer\",\n        \"reportMessage\": \"Ce statut a été signalé\",\n        \"reportStatus\":{\n            \"message\": \"Êtes-vous sûr de vouloir signaler ce statut?\",\n            \"toast\": \"Vous avez signalé ce statut\",\n            \"approve\": \"Êtes-vous sûr de vouloir approuver cette publication ? Cela ne modifiera pas son apparition sur Tatami.\",\n            \"approveToast\": \"Vous avez approuvé ce statut\",\n            \"delete\": \"Êtes-vous sûr de vouloir supprimer ce statut ? Cette action est irréversible.\",\n            \"deleteToast\": \"Vous avez supprimé ce statut\"\n        },\n        \"block\": {\n            \"reportStatus\": \"Signaler ce statut\",\n            \"blockUser\": \"Bloquer cet utilisateur\",\n            \"delete\": \"Supprimer\"\n        },\n        \"announcement\": {\n            \"title\": \"a annoncé\",\n            \"mention\": \"Votre status a été annoncé\",\n            \"toast\": \"Vous avez annoncé ce statut\",\n            \"action\": \"Annoncer\"\n        },\n        \"hide\": {\n            \"action\": \"Cacher ce statut\",\n            \"toast\": \"Ce statut a été supprimé de votre timeline\"\n        },\n        \"favorite\": {\n            \"add\": \"Ce statut a été ajouté à vos favoris\",\n            \"remove\": \"Ce statut a été supprimé de vos favoris\"\n        },\n        \"private\": \"Message privé\",\n        \"noContent\" : \"Cette section est actuellement vide\"\n    }\n}\n"
  },
  {
    "path": "mobile/www/i18n/fr/user.json",
    "content": "{\n    \"user\": {\n        \"profile\": {\n            \"title\": \"Profil\",\n            \"options\": {\n                \"block\": \"Bloquer cet utilisateur\",\n                \"deactivate\": \"Désactiver cet utilisateur\",\n                \"reactivate\": \"Réactiver cet utilisateur\"\n            }\n        },\n        \"follow\": \"S'abonner\",\n        \"unfollow\": \"Se désabonner\",\n        \"block\":{\n            \"success\": \"Vous avez bloqué cet utilisateur\",\n            \"title\": \"Bloquer\",\n            \"confirmation\": \"Êtes-vous sûr de vouloir bloquer cet utilisateur ? Vous ne verrez plus ses publications.\"\n        } ,\n        \"unblock\": {\n            \"success\": \"Vous avez débloqué cet utilisateur.\",\n            \"title\": \"Débloquer\"\n        },\n        \"reactivate\": {\n            \"title\": \"Réactiver\",\n            \"confirmation\": \"Êtes-vous sûr de vouloir réactiver cet utilisateur ?\"\n        },\n        \"deactivate\": {\n            \"title\": \"Désactiver\",\n            \"confirmation\": \"Êtes-vous sûr de vouloir désactiver cet utilisateur ? Il ne pourra plus se connecter à Tatami.\"\n        }\n    }\n}\n"
  },
  {
    "path": "mobile/www/index.html",
    "content": "<!DOCTYPE html>\n<html>\n    <head>\n        <meta charset=\"utf-8\">\n        <meta name=\"viewport\" content=\"initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width\">\n        <meta http-equiv=\"Content-Security-Policy\" content=\"*\">\n        <title></title>\n\n        <link href=\"lib/ionic/release/css/ionic.min.css\" rel=\"stylesheet\">\n        <link href=\"css/style.min.css\" rel=\"stylesheet\">\n\n        <!-- compiled css output -->\n        <link href=\"css/ionic.app.css\" rel=\"stylesheet\">\n\n        <!-- ionic/angularjs js -->\n        <script src=\"lib/ionic/release/js/ionic.bundle.js\"></script>\n        <script src=\"lib/angular-resource/angular-resource.js\"></script>\n        <script src=\"lib/ngCordova/dist/ng-cordova.js\"></script>\n        <script src=\"lib/angular-marked/dist/angular-marked.js\"></script>\n        <script src=\"lib/angular-translate/angular-translate.js\"></script>\n        <script src=\"lib/messageformat/messageformat.js\"></script>\n        <script src=\"lib/angular-translate-interpolation-messageformat/angular-translate-interpolation-messageformat.js\"></script>\n        <script src=\"lib/angular-translate-loader-partial/angular-translate-loader-partial.js\"></script>\n        <script src=\"lib/ionic-toast/dist/ionic-toast.bundle.min.js\"></script>\n\n        <!-- cordova script (this will be a 404 during development) -->\n        <script src=\"cordova.js\"></script>\n\n        <!-- your app's js -->\n        <script src=\"app/tatamiApp.js\"></script>\n        <script src=\"app/tatami.endpoint.js\"></script>\n        <script src=\"app/tatami.controller.js\"></script>\n\n        <script src=\"app/components/login/login.js\"></script>\n        <script src=\"app/components/login/login.controller.js\"></script>\n\n        <script src=\"app/components/login/server/server.js\"></script>\n        <script src=\"app/components/login/server/server.controller.js\"></script>\n\n        <script src=\"app/components/home/home.js\"></script>\n        <script src=\"app/components/home/timeline/timeline.js\"></script>\n        <script src=\"app/components/home/timeline/timeline.controller.js\"></script>\n        <script src=\"app/components/home/mentions/mentions.js\"></script>\n        <script src=\"app/components/home/mentions/mentions.controller.js\"></script>\n        <script src=\"app/components/home/favorites/favorites.js\"></script>\n        <script src=\"app/components/home/favorites/favorites.controller.js\"></script>\n\n        <script src=\"app/components/home/more/more.js\"></script>\n        <script src=\"app/components/home/more/more.controller.js\"></script>\n        <script src=\"app/components/home/more/company/company.timeline.js\"></script>\n        <script src=\"app/components/home/more/company/company.timeline.controller.js\"></script>\n        <script src=\"app/components/home/more/settings/settings.js\"></script>\n        <script src=\"app/components/home/more/settings/settings.controller.js\"></script>\n        <script src=\"app/components/home/more/blocked_users/blocked.users.js\"></script>\n        <script src=\"app/components/home/more/blocked_users/blocked.users.controller.js\"></script>\n        <script src=\"app/components/home/more/reportedStatus/reportedStatus.js\"></script>\n        <script src=\"app/components/home/more/reportedStatus/reportedStatus.controller.js\"></script>\n        <script src=\"app/components/home/more/all_users/all.users.js\"></script>\n        <script src=\"app/components/home/more/all_users/all.users.controller.js\"></script>\n\n        <script src=\"app/components/follow/follow.js\"></script>\n        <script src=\"app/components/follow/suggested/suggested.js\"></script>\n        <script src=\"app/components/follow/suggested/suggested.controller.js\"></script>\n        <script src=\"app/components/follow/follower/follower.js\"></script>\n        <script src=\"app/components/follow/follower/follower.controller.js\"></script>\n        <script src=\"app/components/follow/following/following.js\"></script>\n        <script src=\"app/components/follow/following/following.controller.js\"></script>\n\n        <script src=\"app/components/post/post.js\"></script>\n        <script src=\"app/components/post/post.controller.js\"></script>\n\n        <script src=\"app/shared/providers/provider.js\"></script>\n        <script src=\"app/shared/providers/tatami.state.provider.js\"></script>\n\n        <script src=\"app/shared/interceptor/auth.interceptor.js\"></script>\n\n        <script src=\"app/shared/services/service.js\"></script>\n        <script src=\"app/shared/services/StatusService.js\"></script>\n        <script src=\"app/shared/services/ProfileService.js\"></script>\n        <script src=\"app/shared/services/UserService.js\"></script>\n        <script src=\"app/shared/services/HomeService.js\"></script>\n        <script src=\"app/shared/services/path.service.js\"></script>\n        <script src=\"app/shared/services/localStorage.service.js\"></script>\n        <script src=\"app/shared/services/tag.service.js\"></script>\n        <script src=\"app/shared/services/block.service.js\"></script>\n        <script src=\"app/shared/services/toast.service.js\"></script>\n        <script src=\"app/shared/services/report.service.js\"></script>\n        <script src=\"app/shared/services/account.service.js\"></script>\n        <script src=\"app/shared/services/report.service.js\"></script>\n\n\n        <script src=\"app/shared/state/profile/profile.controller.js\"></script>\n        <script src=\"app/shared/state/conversation/conversation.controller.js\"></script>\n        <script src=\"app/shared/state/tag/tag.controller.js\"></script>\n\n        <script src=\"app/shared/status/list/status.list.directive.js\"></script>\n        <script src=\"app/shared/status/status.directive.js\"></script>\n        <script src=\"app/shared/status/status.refresher.service.js\"></script>\n        <script src=\"app/shared/user/user.refresher.service.js\"></script>\n        <script src=\"app/shared/user/user.directive.js\"></script>\n        <script src=\"app/shared/user/user.detail.directive.js\"></script>\n        <script src=\"app/components/post/postbar.directive.js\"></script>\n\n        <script src=\"app/shared/config/tatami.marked.js\"></script>\n        <script src=\"app/shared/config/marked.filter.js\"></script>\n        <script src=\"app/shared/config/marked.config.js\"></script>\n    </head>\n    <body ng-app=\"tatami\">\n        <!--\n          The nav bar that will be updated as we navigate between views.\n        -->\n        <ion-nav-view></ion-nav-view>\n    </body>\n</html>\n"
  },
  {
    "path": "mobile/www/test/javascript/components/profile/profile.controller.spec.js",
    "content": "describe(\"License controller test\", function() {\n\n    beforeEach(inject(function(_$controller_) {\n        $controller = _$controller_;\n    }));\n    it('SANITY', function(){\n        expect(true).toBeTruthy();\n    });\n});\n"
  },
  {
    "path": "pom.xml",
    "content": "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n    xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n    <groupId>fr.ippon.tatami</groupId>\n    <artifactId>tatami</artifactId>\n    <version>4.0.5</version>\n\n    <modules>\n        <module>web</module>\n        <module>services</module>\n        <module>tatamibot</module>\n        <module>mobile</module>\n    </modules>\n\n    <packaging>pom</packaging>\n\n    <description>Tatami is an enterprise micro-blogging platform</description>\n    <inceptionYear>2012</inceptionYear>\n    <url>https://github.com/ippontech/tatami</url>\n    <organization>\n        <name>Ippon Technologies</name>\n        <url>http://www.ippon.fr</url>\n    </organization>\n    <licenses>\n        <license>\n            <name>Apache License, Version 2.0</name>\n            <url>http://www.apache.org/licenses/LICENSE-2.0</url>\n            <distribution>repo</distribution>\n        </license>\n    </licenses>\n    <issueManagement>\n        <system>GitHub</system>\n        <url>https://github.com/ippontech/tatami/issues</url>\n    </issueManagement>\n    <scm>\n        <url>http://github.com/ippontech/tatami</url>\n        <connection>scm:git:git@github.com:ippontech/tatami.git</connection>\n    </scm>\n\n    <profiles>\n        <profile>\n            <id>default</id>\n            <activation>\n                <activeByDefault>true</activeByDefault>\n            </activation>\n            <properties>\n                <!-- Spring profiles available : tatamibot, metrics, apple-push -->\n                <spring.profiles.active></spring.profiles.active>\n            </properties>\n        </profile>\n\n        <profile>\n            <id>elasticsearch-remote</id>\n            <properties>\n                <!-- Spring profiles available : tatamibot, metrics, apple-push -->\n                <spring.profiles.active></spring.profiles.active>\n                <tatami.elasticsearch.engine.mode>remote</tatami.elasticsearch.engine.mode>\n                <tatami.elasticsearch.path.data>target/elasticsearch</tatami.elasticsearch.path.data>\n                <tatami.elasticsearch.path.log>target/elasticsearch/log</tatami.elasticsearch.path.log>\n                <tatami.elasticsearch.http.enabled>true</tatami.elasticsearch.http.enabled>\n            </properties>\n        </profile>\n        <profile>\n            <id>preprod</id>\n            <properties>\n                <!-- Spring profiles available : tatamibot, metrics, apple-push -->\n                <spring.profiles.active>apple-push</spring.profiles.active>\n                <jetty.scanIntervalSeconds>0</jetty.scanIntervalSeconds>\n                <logback.loglevel>DEBUG</logback.loglevel>\n                <logback.appender>PAPERTRAIL</logback.appender>\n                <logback.syslogHost>logs.papertrailapp.com</logback.syslogHost>\n                <logback.syslogHost.port>38143</logback.syslogHost.port>\n                <ehcache.maxBytesLocalHeap>128M</ehcache.maxBytesLocalHeap>\n                <tatami.url>http://sandbox.tatamisoft.com</tatami.url>\n                <tatami.smtp.host>localhost</tatami.smtp.host>\n                <tatami.smtp.port>25</tatami.smtp.port>\n                <tatami.smtp.from>tatami@ippon.fr</tatami.smtp.from>\n                <tatami.wro4j.enabled>true</tatami.wro4j.enabled>\n                <tatami.message.reloading.enabled>false</tatami.message.reloading.enabled>\n            </properties>\n        </profile>\n        <profile>\n            <id>prod</id>\n            <properties>\n                <!-- Spring profiles available : tatamibot, metrics, apple-push -->\n                <spring.profiles.active></spring.profiles.active>\n                <jetty.port>80</jetty.port>\n                <jetty.scanIntervalSeconds>0</jetty.scanIntervalSeconds>\n                <logback.loglevel>INFO</logback.loglevel>\n                <logback.appender>PAPERTRAIL</logback.appender>\n                <logback.syslogHost>logs.papertrailapp.com</logback.syslogHost>\n                <logback.syslogHost.port>38143</logback.syslogHost.port>\n                <ehcache.maxBytesLocalHeap>512M</ehcache.maxBytesLocalHeap>\n                <tatami.url>http://tatami.ippon.fr</tatami.url>\n                <tatami.ldapauth.url>ldap://10.55.0.4:389</tatami.ldapauth.url>\n                <tatami.smtp.host>localhost</tatami.smtp.host>\n                <tatami.smtp.port>25</tatami.smtp.port>\n                <tatami.smtp.from>tatami@ippon.fr</tatami.smtp.from>\n                <tatami.google.analytics.key>UA-10959780-3</tatami.google.analytics.key>\n                <tatami.wro4j.enabled>true</tatami.wro4j.enabled>\n                <tatami.message.reloading.enabled>false</tatami.message.reloading.enabled>\n                <tatami.connection.security>https</tatami.connection.security>\n                <tatami.elasticsearch.engine.mode>embedded</tatami.elasticsearch.engine.mode>\n                <tatami.elasticsearch.path.data>/opt/tatami/data/elasticsearch</tatami.elasticsearch.path.data>\n                <tatami.elasticsearch.path.log>/opt/tatami/log/elasticsearch</tatami.elasticsearch.path.log>\n                <tatami.elasticsearch.http.enabled>false</tatami.elasticsearch.http.enabled>\n                <tatami.automatic.registration>false</tatami.automatic.registration>\n                <tatami.metrics.graphite.host></tatami.metrics.graphite.host>\n                <tatami.metrics.graphite.port>2003</tatami.metrics.graphite.port>\n            </properties>\n            <build>\n                <plugins>\n                    <plugin>\n                        <groupId>org.mortbay.jetty</groupId>\n                        <artifactId>jetty-maven-plugin</artifactId>\n                        <version>${maven.jetty.version}</version>\n                        <configuration>\n                            <scanIntervalSeconds>${jetty.scanIntervalSeconds}</scanIntervalSeconds>\n                            <stopKey>stop-jetty</stopKey>\n                            <stopPort>9999</stopPort>\n                            <systemProperties>\n                                <systemProperty>\n                                    <name>jetty.port</name>\n                                    <value>${jetty.port}</value>\n                                </systemProperty>\n                            </systemProperties>\n                        </configuration>\n                        <executions>\n                            <execution>\n                                <id>start-jetty</id>\n                                <phase>pre-integration-test</phase>\n                                <goals>\n                                    <!-- <goal>run-exploded</goal> -->\n                                    <goal>run</goal>\n                                </goals>\n                                <configuration>\n                                    <scanIntervalSeconds>0</scanIntervalSeconds>\n                                    <daemon>true</daemon>\n                                </configuration>\n                            </execution>\n                            <execution>\n                                <id>stop-jetty</id>\n                                <phase>post-integration-test</phase>\n                                <goals>\n                                    <goal>stop</goal>\n                                </goals>\n                            </execution>\n                        </executions>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.codehaus.mojo</groupId>\n                        <artifactId>exec-maven-plugin</artifactId>\n                        <version>1.2.1</version>\n                        <executions>\n                            <execution>\n                                <id>insert-version</id>\n                                <phase>generate-sources</phase>\n                                <configuration>\n                                    <executable>scripts/insertBuildVersion.sh</executable>\n                                    <arguments>\n                                        <argument>${project.version}</argument>\n                                        <argument>${buildNumber}</argument>\n                                    </arguments>\n                                </configuration>\n                                <goals>\n                                    <goal>exec</goal>\n                                </goals>\n                            </execution>\n                        </executions>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n        <profile>\n            <id>stress-tests</id>\n            <properties>\n                <!-- Spring profiles available : tatamibot, metrics, apple-push -->\n                <spring.profiles.active></spring.profiles.active>\n                <jetty.scanIntervalSeconds>0</jetty.scanIntervalSeconds>\n                <logback.loglevel>WARN</logback.loglevel>\n                <logback.appender>CONSOLE</logback.appender>\n                <ehcache.maxBytesLocalHeap>64M</ehcache.maxBytesLocalHeap>\n                <tatami.automatic.registration>true</tatami.automatic.registration>\n            </properties>\n        </profile>\n        <profile>\n            <id>uitest</id>\n            <properties>\n                <!-- Spring profiles available : tatamibot, metrics, apple-push -->\n                <spring.profiles.active></spring.profiles.active>\n            </properties>\n            <build>\n                <testResources>\n                    <testResource>\n                        <directory>services/test/resources</directory>\n                    </testResource>\n                    <testResource>\n                        <directory>src/integration/resources</directory>\n                    </testResource>\n                </testResources>\n                <plugins>\n                    <plugin>\n                        <groupId>org.codehaus.mojo</groupId>\n                        <artifactId>build-helper-maven-plugin</artifactId>\n                        <version>1.4</version>\n                        <executions>\n                            <execution>\n                                <id>add-uitests-source</id>\n                                <goals>\n                                    <goal>add-test-source</goal>\n                                </goals>\n                                <configuration>\n                                    <sources>\n                                        <source>${basedir}/src/integration/java</source>\n                                    </sources>\n                                </configuration>\n                            </execution>\n                        </executions>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.codehaus.gmaven</groupId>\n                        <artifactId>gmaven-plugin</artifactId>\n                        <version>1.4</version>\n                        <configuration>\n                            <providerSelection>1.8</providerSelection>\n                            <sources>\n                                <fileset>\n                                    <directory>${basedir}/src/integration/java</directory>\n                                    <includes>\n                                        <include>**/*.groovy</include>\n                                    </includes>\n                                </fileset>\n                            </sources>\n                        </configuration>\n                        <executions>\n                            <execution>\n                                <goals>\n                                    <goal>testCompile</goal>\n                                </goals>\n                            </execution>\n                        </executions>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-failsafe-plugin</artifactId>\n                        <version>2.12.3</version>\n                        <configuration>\n                            <testSourceDirectory>${basedir}/src/integration/java</testSourceDirectory>\n                            <includes>\n                                <include>**/*Spec.*</include>\n                            </includes>\n                            <systemPropertyVariables>\n                                <!-- <geb.build.baseUrl>http://localhost:8080/</geb.build.baseUrl> -->\n                                <geb.build.reportsDir>target/test-reports/geb</geb.build.reportsDir>\n                                <webdriver.chrome.driver>${webdriver.chrome.driver}</webdriver.chrome.driver>\n                                <google.password>${google.password}</google.password>\n                                <google.email>${google.email}</google.email>\n                            </systemPropertyVariables>\n                        </configuration>\n                        <executions>\n                            <execution>\n                                <goals>\n                                    <goal>integration-test</goal>\n                                    <goal>verify</goal>\n                                </goals>\n                            </execution>\n                        </executions>\n                    </plugin>\n                    <plugin>\n                        <groupId>org.codehaus.mojo</groupId>\n                        <artifactId>cassandra-maven-plugin</artifactId>\n                        <version>${maven.cassandra.version}</version>\n                        <executions>\n                            <execution>\n                                <id>start-cassandra</id>\n                                <phase>pre-integration-test</phase>\n                                <goals>\n                                    <goal>start</goal>\n                                </goals>\n                            </execution>\n                        </executions>\n                    </plugin>\n                </plugins>\n            </build>\n            <dependencies>\n                <dependency>\n                    <groupId>org.codehaus.groovy</groupId>\n                    <artifactId>groovy-all</artifactId>\n                    <version>1.8.1</version>\n                </dependency>\n                <dependency>\n                    <groupId>org.spockframework</groupId>\n                    <artifactId>spock-core</artifactId>\n                    <version>0.6-groovy-1.8</version>\n                    <scope>test</scope>\n                </dependency>\n                <dependency>\n                    <groupId>org.codehaus.geb</groupId>\n                    <artifactId>geb-spock</artifactId>\n                    <version>0.7.1</version>\n                    <scope>test</scope>\n                </dependency>\n                <dependency>\n                    <groupId>org.seleniumhq.selenium</groupId>\n                    <artifactId>selenium-firefox-driver</artifactId>\n                    <version>${selenium.version}</version>\n                    <scope>test</scope>\n                </dependency>\n                <dependency>\n                    <groupId>org.seleniumhq.selenium</groupId>\n                    <artifactId>selenium-htmlunit-driver</artifactId>\n                    <version>${selenium.version}</version>\n                    <scope>test</scope>\n                </dependency>\n                <dependency>\n                    <groupId>org.seleniumhq.selenium</groupId>\n                    <artifactId>selenium-chrome-driver</artifactId>\n                    <version>${selenium.version}</version>\n                    <scope>test</scope>\n                </dependency>\n                <dependency>\n                    <groupId>org.seleniumhq.selenium</groupId>\n                    <artifactId>selenium-support</artifactId>\n                    <version>${selenium.version}</version>\n                    <scope>test</scope>\n                </dependency>\n                <dependency>\n                    <groupId>org.apache.directory.server</groupId>\n                    <artifactId>apacheds-all</artifactId>\n                    <version>1.5.5</version>\n                    <!-- Don't change this version ! It breaks the code -->\n                    <scope>test</scope>\n                    <exclusions>\n                        <exclusion>\n                            <groupId>org.apache.directory.shared</groupId>\n                            <artifactId>shared-ldap</artifactId>\n                        </exclusion>\n                    </exclusions>\n                </dependency>\n            </dependencies>\n        </profile>\n    </profiles>\n\n    <properties>\n        <!-- Default project properties -->\n        <jetty.port>8080</jetty.port>\n        <jetty.scanIntervalSeconds>1</jetty.scanIntervalSeconds>\n        <logback.loglevel>DEBUG</logback.loglevel>\n        <logback.appender>CONSOLE</logback.appender>\n        <logback.syslogHost>localhost</logback.syslogHost>\n        <ehcache.maxBytesLocalHeap>64M</ehcache.maxBytesLocalHeap>\n        <tatami.version>${project.version}</tatami.version>\n        <tatami.url>http://localhost:8080</tatami.url>\n        <tatami.ldapauth.url>ldap://directory:389</tatami.ldapauth.url>\n        <tatami.ldapauth.searchbase>dc=ippon,dc=fr</tatami.ldapauth.searchbase>\n        <tatami.ldapauth.searchfilter>(uid={0})</tatami.ldapauth.searchfilter>\n        <tatami.smtp.host></tatami.smtp.host>\n        <tatami.smtp.port></tatami.smtp.port>\n        <tatami.smtp.user></tatami.smtp.user>\n        <tatami.smtp.password></tatami.smtp.password>\n        <tatami.smtp.from>tatami@localhost</tatami.smtp.from>\n        <tatami.smtp.tls></tatami.smtp.tls>\n        <tatami.google.analytics.key></tatami.google.analytics.key>\n        <tatami.wro4j.enabled>false</tatami.wro4j.enabled>\n        <tatami.message.reloading.enabled>true</tatami.message.reloading.enabled>\n        <tatami.connection.security>any</tatami.connection.security>\n        <tatami.elasticsearch.engine.mode>embedded</tatami.elasticsearch.engine.mode>\n        <tatami.elasticsearch.path.data>target/elasticsearch</tatami.elasticsearch.path.data>\n        <tatami.elasticsearch.path.log>target/elasticsearch/log</tatami.elasticsearch.path.log>\n        <tatami.elasticsearch.http.enabled>true</tatami.elasticsearch.http.enabled>\n        <tatami.automatic.registration>false</tatami.automatic.registration>\n        <tatami.metrics.graphite.host></tatami.metrics.graphite.host>\n        <tatami.metrics.graphite.port>2003</tatami.metrics.graphite.port>\n\n        <tatami.google.clientId></tatami.google.clientId>\n        <tatami.google.clientSecret></tatami.google.clientSecret>\n        <tatami.token.validityInSeconds>2592000</tatami.token.validityInSeconds>\n\n        <!--Test configurations: Sonar, unit test, code coverage -->\n\n        <project.npm.bin>${project.basedir}/node_modules/.bin</project.npm.bin>\n        <project.testresult.directory>${project.build.directory}/test-results</project.testresult.directory>\n        <sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>\n        <sonar.java.codeCoveragePlugin>jacoco</sonar.java.codeCoveragePlugin>\n        <sonar.surefire.reportsPath>${project.testresult.directory}/surefire-reports</sonar.surefire.reportsPath>\n        <sonar.jacoco.reportPath>${project.testresult.directory}/coverage/jacoco/jacoco.exec</sonar.jacoco.reportPath>\n        <sonar.jacoco.itReportPath>${project.testresult.directory}/coverage/jacoco/jacoco-it.exec</sonar.jacoco.itReportPath>\n\n\n        <sonar.sources>${project.basedir}/src/main/</sonar.sources>\n        <sonar.tests>${project.basedir}/src/test/</sonar.tests>\n        <sonar.javascript.lcov.reportPath>${project.testresult.directory}/coverage/report-lcov/lcov.info</sonar.javascript.lcov.reportPath>\n        <sonar.javascript.jstestdriver.reportsPath>${project.testresult.directory}/karma</sonar.javascript.jstestdriver.reportsPath>\n\n        <sonar.exclusions>src/main/webapp/assets/**.*</sonar.exclusions>\n        <!-- Configuration -->\n        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\n        <java.version>1.6</java.version>\n\n        <!-- Dependencies -->\n        <spring.version>3.2.3.RELEASE</spring.version>\n        <spring.security.version>3.1.3.RELEASE</spring.security.version>\n        <elasticsearch.version>0.20.6</elasticsearch.version>\n        <aspectj.version>1.6.11</aspectj.version>\n        <slf4j.version>1.7.5</slf4j.version>\n        <logback.version>1.0.13</logback.version>\n        <httpclient.core.version>4.2.2</httpclient.core.version> <!-- pour compatiblité selenium -->\n        <httpclient.client.version>4.2.2</httpclient.client.version> <!-- pour compatiblité selenium -->\n        <cassandra.version>1.2.6</cassandra.version>\n        <hector.version>1.1-4</hector.version>\n        <hector.mapper.version>3.1-09</hector.mapper.version>\n        <persistence.api.version>1.0.2</persistence.api.version>\n        <javax.inject.version>1</javax.inject.version>\n        <javax.servlet.api.version>3.0.1</javax.servlet.api.version>\n        <javax.validation.api.version>1.0.0.GA</javax.validation.api.version>\n        <hibernate.validator.version>4.3.0.Final</hibernate.validator.version>\n        <jstl.version>1.2</jstl.version>\n        <jackson.version>2.1.2</jackson.version>\n        <jodatime.version>2.1</jodatime.version>\n        <commons.lang.version>2.6</commons.lang.version>\n        <commons.io.version>2.3</commons.io.version>\n        <junit.version>4.11</junit.version>\n        <hamcrest.version>1.3</hamcrest.version>\n        <awaitility.version>1.3.5</awaitility.version>\n        <cassandra.unit.version>1.2.0.1</cassandra.unit.version>\n        <mockito.version>1.9.0</mockito.version>\n        <rome.version>1.0</rome.version>\n        <pegdown.version>1.2.1</pegdown.version>\n        <velocity.version>1.7</velocity.version>\n        <yammer.metrics.version>2.2.0</yammer.metrics.version>\n        <camel.version>2.11.0</camel.version>\n\n        <selenium.version>2.31.0</selenium.version>\n\n        <!-- Maven plugins -->\n        <maven.compiler.version>3.0</maven.compiler.version>\n        <maven.enforcer.version>1.2</maven.enforcer.version>\n        <maven.surefire.version>2.14</maven.surefire.version>\n        <maven.war.version>2.3</maven.war.version>\n        <maven.jetty.version>8.1.13.v20130916</maven.jetty.version>\n        <maven.cassandra.version>1.2.1-1</maven.cassandra.version>\n        <maven.wro4j.version>1.7.0</maven.wro4j.version>\n        <maven-eclipse-plugin.version>2.9</maven-eclipse-plugin.version>\n        <netbeans.hint.deploy.server>Tomcat</netbeans.hint.deploy.server>\n    </properties>\n\n    <repositories>\n\n        <repository>\n            <id>sonatype-releases</id>\n            <name>Sonatype Releases Repository</name>\n            <url>http://oss.sonatype.org/content/repositories/releases/</url>\n        </repository>\n        <repository>\n            <id>sonatype-nexus-snapshots</id>\n            <name>Sonatype Nexus Snapshots</name>\n            <url>https://oss.sonatype.org/content/repositories/snapshots</url>\n            <releases>\n                <enabled>false</enabled>\n            </releases>\n            <snapshots>\n                <enabled>true</enabled>\n            </snapshots>\n        </repository>\n    </repositories>\n\n    <prerequisites>\n        <maven>3.1.0</maven>\n    </prerequisites>\n\n    <dependencies>\n        <dependency>\n            <groupId>com.google.api-client</groupId>\n            <artifactId>google-api-client</artifactId>\n            <version>1.20.0</version>\n        </dependency>\n        <dependency>\n            <groupId>com.google.apis</groupId>\n            <artifactId>google-api-services-plus</artifactId>\n            <version>v1-rev345-1.21.0</version>\n        </dependency>\n        <dependency>\n            <groupId>com.fasterxml.jackson.datatype</groupId>\n            <artifactId>jackson-datatype-json-org</artifactId>\n            <version>${jackson.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.fasterxml.jackson.datatype</groupId>\n            <artifactId>jackson-datatype-hppc</artifactId>\n            <version>${jackson.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.fasterxml.jackson.datatype</groupId>\n            <artifactId>jackson-datatype-joda</artifactId>\n            <version>${jackson.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.notnoop.apns</groupId>\n            <artifactId>apns</artifactId>\n            <version>0.2.3</version>\n        </dependency>\n        <dependency>\n            <groupId>com.yammer.metrics</groupId>\n            <artifactId>metrics-core</artifactId>\n            <version>${yammer.metrics.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.yammer.metrics</groupId>\n            <artifactId>metrics-ehcache</artifactId>\n            <version>${yammer.metrics.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.yammer.metrics</groupId>\n            <artifactId>metrics-graphite</artifactId>\n            <version>${yammer.metrics.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.yammer.metrics</groupId>\n            <artifactId>metrics-servlet</artifactId>\n            <version>${yammer.metrics.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.yammer.metrics</groupId>\n            <artifactId>metrics-spring</artifactId>\n            <version>${yammer.metrics.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.yammer.metrics</groupId>\n            <artifactId>metrics-web</artifactId>\n            <version>${yammer.metrics.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>commons-fileupload</groupId>\n            <artifactId>commons-fileupload</artifactId>\n            <version>1.2.2</version>\n        </dependency>\n        <dependency>\n            <groupId>commons-io</groupId>\n            <artifactId>commons-io</artifactId>\n            <version>${commons.io.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>commons-lang</groupId>\n            <artifactId>commons-lang</artifactId>\n            <version>${commons.lang.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>javax.inject</groupId>\n            <artifactId>javax.inject</artifactId>\n            <version>${javax.inject.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>javax.persistence</groupId>\n            <artifactId>persistence-api</artifactId>\n            <version>${persistence.api.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>javax.servlet</groupId>\n            <artifactId>javax.servlet-api</artifactId>\n            <version>${javax.servlet.api.version}</version>\n            <scope>provided</scope>\n        </dependency>\n        <dependency>\n            <groupId>javax.servlet</groupId>\n            <artifactId>jstl</artifactId>\n            <version>${jstl.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>javax.validation</groupId>\n            <artifactId>validation-api</artifactId>\n            <version>${javax.validation.api.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>joda-time</groupId>\n            <artifactId>joda-time</artifactId>\n            <version>${jodatime.version}</version>\n        </dependency>\n\n        <dependency>\n            <groupId>ch.qos.logback</groupId>\n            <artifactId>logback-core</artifactId>\n            <version>${logback.version}</version>\n        </dependency>\n\n        <dependency>\n            <groupId>ch.qos.logback</groupId>\n            <artifactId>logback-classic</artifactId>\n            <version>${logback.version}</version>\n        </dependency>\n\n        <dependency>\n            <groupId>net.sf.ehcache</groupId>\n            <artifactId>ehcache-core</artifactId>\n            <version>2.6.5</version>\n        </dependency>\n        <dependency>\n            <groupId>net.sf.ehcache</groupId>\n            <artifactId>ehcache-web</artifactId>\n            <version>2.0.4</version>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.camel</groupId>\n            <artifactId>camel-core</artifactId>\n            <version>${camel.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.camel</groupId>\n            <artifactId>camel-spring</artifactId>\n            <version>${camel.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.camel</groupId>\n            <artifactId>camel-script</artifactId>\n            <version>${camel.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.camel</groupId>\n            <artifactId>camel-rss</artifactId>\n            <version>${camel.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.camel</groupId>\n            <artifactId>camel-twitter</artifactId>\n            <version>${camel.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.camel</groupId>\n            <artifactId>camel-stream</artifactId>\n            <version>${camel.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.httpcomponents</groupId>\n            <artifactId>httpcore</artifactId>\n            <version>${httpclient.core.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.httpcomponents</groupId>\n            <artifactId>httpclient</artifactId>\n            <version>${httpclient.client.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.geronimo.javamail</groupId>\n            <artifactId>geronimo-javamail_1.4_mail</artifactId>\n            <version>1.8.2</version>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.openjpa</groupId>\n            <artifactId>openjpa</artifactId>\n            <version>2.1.0</version>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.velocity</groupId>\n            <artifactId>velocity</artifactId>\n            <version>${velocity.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.aspectj</groupId>\n            <artifactId>aspectjrt</artifactId>\n            <version>${aspectj.version}</version>\n            <type>jar</type>\n            <scope>compile</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.aspectj</groupId>\n            <artifactId>aspectjweaver</artifactId>\n            <version>${aspectj.version}</version>\n            <type>jar</type>\n            <scope>compile</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.atmosphere</groupId>\n            <artifactId>atmosphere-annotations</artifactId>\n            <version>1.1.0.RC3</version>\n        </dependency>\n        <dependency>\n            <groupId>org.elasticsearch</groupId>\n            <artifactId>elasticsearch</artifactId>\n            <version>${elasticsearch.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.hectorclient</groupId>\n            <artifactId>hector-core</artifactId>\n            <version>${hector.version}</version>\n            <exclusions>\n                <exclusion>\n                    <groupId>javax.servlet</groupId>\n                    <artifactId>servlet-api</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>org.hectorclient</groupId>\n            <artifactId>hector-object-mapper</artifactId>\n            <version>${hector.mapper.version}</version>\n            <exclusions>\n                <exclusion>\n                    <groupId>org.mortbay.jetty</groupId>\n                    <artifactId>servlet-api</artifactId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>org.hibernate</groupId>\n            <artifactId>hibernate-validator</artifactId>\n            <version>${hibernate.validator.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.pegdown</groupId>\n            <artifactId>pegdown</artifactId>\n            <version>${pegdown.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.slf4j</groupId>\n            <artifactId>slf4j-api</artifactId>\n            <version>${slf4j.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.slf4j</groupId>\n            <artifactId>jcl-over-slf4j</artifactId>\n            <version>${slf4j.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-aop</artifactId>\n            <version>${spring.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-beans</artifactId>\n            <version>${spring.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-context</artifactId>\n            <version>${spring.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-context-support</artifactId>\n            <version>${spring.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-core</artifactId>\n            <version>${spring.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-orm</artifactId>\n            <version>${spring.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-tx</artifactId>\n            <version>${spring.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-web</artifactId>\n            <version>${spring.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-webmvc</artifactId>\n            <version>${spring.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.security</groupId>\n            <artifactId>spring-security-core</artifactId>\n            <version>${spring.security.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.security</groupId>\n            <artifactId>spring-security-config</artifactId>\n            <version>${spring.security.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.security</groupId>\n            <artifactId>spring-security-crypto</artifactId>\n            <version>${spring.security.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.security</groupId>\n            <artifactId>spring-security-ldap</artifactId>\n            <version>${spring.security.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.security</groupId>\n            <artifactId>spring-security-openid</artifactId>\n            <version>${spring.security.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.security</groupId>\n            <artifactId>spring-security-taglibs</artifactId>\n            <version>${spring.security.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework.security</groupId>\n            <artifactId>spring-security-web</artifactId>\n            <version>${spring.security.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>org.pac4j</groupId>\n            <artifactId>pac4j-oauth</artifactId>\n            <version>1.6.0</version>\n        </dependency>\n        <dependency>\n            <groupId>org.pac4j</groupId>\n            <artifactId>spring-security-pac4j</artifactId>\n            <version>1.2.4</version>\n        </dependency>\n        <dependency>\n            <groupId>rome</groupId>\n            <artifactId>rome</artifactId>\n            <version>${rome.version}</version>\n        </dependency>\n\n        <!-- Test dependencies -->\n\n        <dependency>\n            <groupId>org.apache.cassandra</groupId>\n            <artifactId>cassandra-all</artifactId>\n            <version>${cassandra.version}</version>\n            <exclusions>\n                <exclusion>\n                    <groupId>javax.servlet</groupId>\n                    <artifactId>servlet-api</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.mortbay.jetty</groupId>\n                    <artifactId>servlet-api</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.mortbay.jetty</groupId>\n                    <artifactId>jetty</artifactId>\n                </exclusion>\n                <exclusion>\n                    <groupId>org.mortbay.jetty</groupId>\n                    <artifactId>jetty-util</artifactId>\n                </exclusion>\n            </exclusions>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>com.jayway.jsonpath</groupId>\n            <artifactId>json-path</artifactId>\n            <version>0.8.1</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.springframework</groupId>\n            <artifactId>spring-test</artifactId>\n            <version>${spring.version}</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.hamcrest</groupId>\n            <artifactId>hamcrest-core</artifactId>\n            <version>${hamcrest.version}</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.hamcrest</groupId>\n            <artifactId>hamcrest-library</artifactId>\n            <version>${hamcrest.version}</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>junit</groupId>\n            <artifactId>junit</artifactId>\n            <version>${junit.version}</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>com.jayway.awaitility</groupId>\n            <artifactId>awaitility</artifactId>\n            <version>${awaitility.version}</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.cassandraunit</groupId>\n            <artifactId>cassandra-unit</artifactId>\n            <version>${cassandra.unit.version}</version>\n            <scope>test</scope>\n            <exclusions>\n                <exclusion>\n                    <artifactId>hamcrest-all</artifactId>\n                    <groupId>org.hamcrest</groupId>\n                </exclusion>\n            </exclusions>\n        </dependency>\n        <dependency>\n            <groupId>org.mockito</groupId>\n            <artifactId>mockito-all</artifactId>\n            <version>${mockito.version}</version>\n            <scope>test</scope>\n        </dependency>\n        <dependency>\n            <groupId>org.apache.camel</groupId>\n            <artifactId>camel-test</artifactId>\n            <version>${camel.version}</version>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n    <build>\n        <!-- Tatami must be configured at the root context (/) of the application server -->\n        <finalName>root</finalName>\n        <resources>\n            <resource>\n                <directory>src/main/resources</directory>\n                <filtering>true</filtering>\n                <includes>\n                    <include>**/*</include>\n                </includes>\n            </resource>\n        </resources>\n        <plugins>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <version>${maven.compiler.version}</version>\n                <configuration>\n                    <source>${java.version}</source>\n                    <target>${java.version}</target>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-enforcer-plugin</artifactId>\n                <version>${maven.enforcer.version}</version>\n                <executions>\n                    <execution>\n                        <id>enforce-versions</id>\n                        <goals>\n                            <goal>enforce</goal>\n                        </goals>\n                        <configuration>\n                            <rules>\n                                <requireMavenVersion>\n                                    <version>[3.0.0,)</version>\n                                </requireMavenVersion>\n                                <requireJavaVersion>\n                                    <version>[1.6.0,)</version>\n                                </requireJavaVersion>\n                            </rules>\n                        </configuration>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.codehaus.mojo</groupId>\n                <artifactId>buildnumber-maven-plugin</artifactId>\n                <version>1.1</version>\n                <configuration>\n                    <shortRevisionLength>7</shortRevisionLength>\n                </configuration>\n                <executions>\n                    <execution>\n                        <phase>validate</phase>\n                        <goals>\n                            <goal>create</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-surefire-plugin</artifactId>\n                <version>${maven.surefire.version}</version>\n                <configuration>\n                    <reportsDirectory>${project.testresult.directory}/surefire-reports</reportsDirectory>\n                    <argLine>-XX:MaxPermSize=128m -Xmx256m ${surefireArgLine}</argLine>\n                    <skipTests>${skip.unit.tests}</skipTests>\n                    <!-- Force alphabetical order to have a reproducible build -->\n                    <runOrder>alphabetical</runOrder>\n                    <!--\n                      <runOrder>reversealphabetical</runOrder>\n                      -->\n                </configuration>\n            </plugin>\n\n            <!-- Cassandra must be configured before jetty ... -->\n            <plugin>\n                <groupId>org.codehaus.mojo</groupId>\n                <artifactId>cassandra-maven-plugin</artifactId>\n                <version>${maven.cassandra.version}</version>\n                <dependencies>\n                    <dependency>\n                        <groupId>org.apache.cassandra</groupId>\n                        <artifactId>cassandra-all</artifactId>\n                        <version>${cassandra.version}</version>\n                    </dependency>\n                </dependencies>\n            </plugin>\n            <plugin>\n                <groupId>org.mortbay.jetty</groupId>\n                <artifactId>jetty-maven-plugin</artifactId>\n                <version>${maven.jetty.version}</version>\n                <configuration>\n                    <scanIntervalSeconds>${jetty.scanIntervalSeconds}</scanIntervalSeconds>\n                    <stopKey>stop-jetty</stopKey>\n                    <stopPort>9999</stopPort>\n                    <systemProperties>\n                        <systemProperty>\n                            <name>jetty.port</name>\n                            <value>${jetty.port}</value>\n                        </systemProperty>\n                        <systemProperty>\n                            <name>spring.profiles.active</name>\n                            <value>${spring.profiles.active}</value>\n                        </systemProperty>\n                    </systemProperties>\n                    <webApp>\n                        <contextPath>/</contextPath>\n                    </webApp>\n                </configuration>\n            </plugin>\n\n            <plugin>\n                <groupId>org.apache.tomcat.maven</groupId>\n                <artifactId>tomcat7-maven-plugin</artifactId>\n                <version>2.1</version>\n                <configuration>\n                    <path>/</path>\n                    <contextReloadable>true</contextReloadable>\n                    <protocol>org.apache.coyote.http11.Http11NioProtocol</protocol>\n                    <systemProperties>\n                        <spring.profiles.active>${spring.profiles.active}</spring.profiles.active>\n                    </systemProperties>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-eclipse-plugin</artifactId>\n                <version>${maven-eclipse-plugin.version}</version>\n                <configuration>\n                    <downloadSources>true</downloadSources>\n                    <downloadJavadocs>true</downloadJavadocs>\n                    <additionalConfig>\n                        <file>\n                            <name>.settings/org.eclipse.core.resources.prefs</name>\n                            <content>\n                                <![CDATA[eclipse.preferences.version=1${line.separator}encoding//src/main/webapp/WEB-INF/messages/messages_en.properties=UTF-8${line.separator}encoding//src/main/webapp/WEB-INF/messages/messages_fr.properties=UTF-8${line.separator}encoding/<project>=${project.build.sourceEncoding}${line.separator}]]>\n                            </content>\n                        </file>\n                    </additionalConfig>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.codehaus.mojo</groupId>\n                <artifactId>sonar-maven-plugin</artifactId>\n                <version>2.5</version>\n            </plugin>\n            <plugin>\n                <groupId>org.jacoco</groupId>\n                <artifactId>jacoco-maven-plugin</artifactId>\n                <version>0.7.4.201502262128</version>\n                <executions>\n                    <execution>\n                        <id>pre-unit-tests</id>\n                        <goals>\n                            <goal>prepare-agent</goal>\n                        </goals>\n                        <configuration>\n                            <!-- Sets the path to the file which contains the execution data. -->\n                            <destFile>${project.testresult.directory}/coverage/jacoco/jacoco.exec</destFile>\n                            <!-- Sets the name of the property containing the settings for JaCoCo runtime agent. -->\n                            <propertyName>surefireArgLine</propertyName>\n                        </configuration>\n                    </execution>\n                    <!-- Ensures that the code coverage report for unit tests is created after unit tests have been run -->\n                    <execution>\n                        <id>post-unit-test</id>\n                        <phase>test</phase>\n                        <goals>\n                            <goal>report</goal>\n                        </goals>\n                        <configuration>\n                            <dataFile>${project.testresult.directory}/coverage/jacoco/jacoco.exec</dataFile>\n                            <outputDirectory>${project.testresult.directory}/coverage/jacoco</outputDirectory>\n                        </configuration>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n        <pluginManagement>\n            <plugins>\n                <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->\n                <plugin>\n                    <groupId>org.eclipse.m2e</groupId>\n                    <artifactId>lifecycle-mapping</artifactId>\n                    <version>1.0.0</version>\n                    <configuration>\n                        <lifecycleMappingMetadata>\n                            <pluginExecutions>\n                                <pluginExecution>\n                                    <pluginExecutionFilter>\n                                        <groupId>ro.isdc.wro4j</groupId>\n                                        <artifactId>\n                                            wro4j-maven-plugin\n                                        </artifactId>\n                                        <versionRange>\n                                            [1.4.7,)\n                                        </versionRange>\n                                        <goals>\n                                            <goal>run</goal>\n                                        </goals>\n                                    </pluginExecutionFilter>\n                                    <action>\n                                        <ignore></ignore>\n                                    </action>\n                                </pluginExecution>\n                                <pluginExecution>\n                                    <pluginExecutionFilter>\n                                        <groupId>\n                                            org.codehaus.gmaven\n                                        </groupId>\n                                        <artifactId>\n                                            gmaven-plugin\n                                        </artifactId>\n                                        <versionRange>\n                                            [1.4,)\n                                        </versionRange>\n                                        <goals>\n                                            <goal>testCompile</goal>\n                                        </goals>\n                                    </pluginExecutionFilter>\n                                    <action>\n                                        <ignore></ignore>\n                                    </action>\n                                </pluginExecution>\n                            </pluginExecutions>\n                        </lifecycleMappingMetadata>\n                    </configuration>\n                </plugin>\n            </plugins>\n        </pluginManagement>\n    </build>\n</project>\n"
  },
  {
    "path": "scripts/insertBuildVersion.sh",
    "content": "#!/bin/bash\n\ndarwin=false;\n\ncase \"`uname`\" in\n    Darwin*) darwin=true ;;\nesac\n\nif $darwin; then\n    sedi=\"sed -i .sed.del\"\nelse\n    sedi=\"sed -i\"\nfi\n\n\nfind . -name FooterView.html | xargs $sedi \"s/<pom>version<\\/pom>/$1/\"\nfind . -name FooterView.html | xargs $sedi \"s/<pom>build<\\/pom>/$2/\"\nfind . -name HomeSidebarView.html | xargs $sedi \"s/<pom>version<\\/pom>/$1/\"\nfind . -name HomeSidebarView.html | xargs $sedi \"s/<pom>build<\\/pom>/$2/\"\n\nif $darwin; then\n    find . -name FooterView.html.sed.del | xargs rm\n    find . -name HomeSidebarView.html.sed.del | xargs rm\nfi\n\n"
  },
  {
    "path": "services/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <artifactId>tatami</artifactId>\n        <groupId>fr.ippon.tatami</groupId>\n        <version>4.0.5</version>\n    </parent>\n\n    <modelVersion>4.0.0</modelVersion>\n    <artifactId>services</artifactId>\n\n    <build>\n     <finalName>tatami-services-${project.version}</finalName>\n        <plugins>\n            <!-- Generate test jar too -->\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-jar-plugin</artifactId>\n                <version>2.4</version>\n                <executions>\n                    <execution>\n                        <goals>\n                            <goal>test-jar</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-remote-resources-plugin</artifactId>\n                <version>1.5</version>\n                <executions>\n                    <execution>\n                        <goals>\n                            <goal>bundle</goal>\n                        </goals>\n                        <configuration>\n                            <includes>\n                                <include>**/*.xml</include>\n                                <include>**/tatami/**/*</include>\n                            </includes>\n                        </configuration>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n</project>"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/config/ApplicationConfiguration.java",
    "content": "package fr.ippon.tatami.config;\n\nimport org.apache.thrift.transport.TTransportException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.context.annotation.*;\nimport org.springframework.core.env.Environment;\n\nimport javax.annotation.PostConstruct;\nimport javax.inject.Inject;\nimport java.io.IOException;\n\n@Configuration\n@PropertySource({\"classpath:/META-INF/tatami/tatami.properties\",\n        \"classpath:/META-INF/tatami/customization.properties\"})\n@ComponentScan(basePackages = {\n        \"fr.ippon.tatami.repository\",\n        \"fr.ippon.tatami.service\",\n        \"fr.ippon.tatami.security\"})\n@Import(value = {\n        AsyncConfiguration.class,\n        CacheConfiguration.class,\n        CassandraConfiguration.class,\n        SearchConfiguration.class,\n        MailConfiguration.class,\n        MetricsConfiguration.class})\n@ImportResource(\"classpath:META-INF/spring/applicationContext-*.xml\")\npublic class ApplicationConfiguration {\n\n    private final Logger log = LoggerFactory.getLogger(ApplicationConfiguration.class);\n\n    @Inject\n    private Environment env;\n\n    /**\n     * Initializes Tatami.\n     * <p/>\n     * Spring profiles can be configured with a system property -Dspring.profiles.active=your-active-profile\n     * <p/>\n     * Available profiles are :\n     * - \"apple-push\" : for enabling Apple Push notifications\n     * - \"metrics\" : for enabling Yammer Metrics\n     * - \"tatamibot\" : for enabling the Tatami bot\n     */\n    @PostConstruct\n    public void initTatami() throws IOException, TTransportException {\n        log.debug(\"Looking for Spring profiles... Available profiles are \\\"metrics\\\", \\\"tatamibot\\\" and \\\"apple-push\\\"\");\n        if (env.getActiveProfiles().length == 0) {\n            log.debug(\"No Spring profile configured, running with default configuration\");\n        } else {\n            for (String profile : env.getActiveProfiles()) {\n                log.debug(\"Detected Spring profile : \" + profile);\n            }\n        }\n        Constants.VERSION = env.getRequiredProperty(\"tatami.version\");\n        Constants.GOOGLE_ANALYTICS_KEY = env.getProperty(\"tatami.google.analytics.key\");\n\n        log.info(\"Tatami v. {} started!\", Constants.VERSION);\n        log.debug(\"Google Analytics key : {}\", Constants.GOOGLE_ANALYTICS_KEY);\n\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/config/AsyncConfiguration.java",
    "content": "package fr.ippon.tatami.config;\n\nimport fr.ippon.tatami.service.SearchService;\nimport fr.ippon.tatami.service.elasticsearch.ElasticsearchSearchService;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.scheduling.annotation.AsyncConfigurer;\nimport org.springframework.scheduling.annotation.EnableAsync;\nimport org.springframework.scheduling.annotation.EnableScheduling;\nimport org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;\n\nimport java.util.concurrent.Executor;\n\n\n@Configuration\n@EnableAsync\n@EnableScheduling\npublic class AsyncConfiguration implements AsyncConfigurer {\n\n    private final Logger log = LoggerFactory.getLogger(AsyncConfiguration.class);\n\n    @Bean\n    public SearchService searchService() {\n        return new ElasticsearchSearchService();\n    }\n\n    @Override\n    public Executor getAsyncExecutor() {\n        log.debug(\"Creating Async Task Executor\");\n        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();\n        executor.setCorePoolSize(2);\n        executor.setMaxPoolSize(50);\n        executor.setQueueCapacity(10000);\n        executor.setThreadNamePrefix(\"TatamiExecutor-\");\n        executor.initialize();\n        return executor;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/config/CacheConfiguration.java",
    "content": "package fr.ippon.tatami.config;\n\nimport com.yammer.metrics.ehcache.InstrumentedEhcache;\nimport net.sf.ehcache.Cache;\nimport net.sf.ehcache.Ehcache;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.cache.CacheManager;\nimport org.springframework.cache.annotation.EnableCaching;\nimport org.springframework.cache.ehcache.EhCacheCacheManager;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\nimport javax.annotation.PreDestroy;\nimport javax.inject.Inject;\n\n@Configuration\n@EnableCaching\npublic class CacheConfiguration {\n\n    private final Logger log = LoggerFactory.getLogger(CacheConfiguration.class);\n\n    private net.sf.ehcache.CacheManager cacheManager;\n\n    @Inject\n    private Environment env;\n\n    @PreDestroy\n    public void destroy() {\n        log.info(\"Closing Ehcache\");\n        cacheManager.shutdown();\n    }\n\n    @Bean\n    public CacheManager cacheManager() {\n        cacheManager = new net.sf.ehcache.CacheManager();\n\n        if (env.acceptsProfiles(Constants.SPRING_PROFILE_METRICS)) {\n            log.debug(\"Ehcache Metrics monitoring enabled\");\n\n            Cache statusCache = cacheManager.getCache(\"status-cache\");\n            Ehcache decoratedStatusCache = InstrumentedEhcache.instrument(statusCache);\n            cacheManager.replaceCacheWithDecoratedCache(statusCache, decoratedStatusCache);\n\n            Cache userCache = cacheManager.getCache(\"user-cache\");\n            Ehcache decoratedUserCache = InstrumentedEhcache.instrument(userCache);\n            cacheManager.replaceCacheWithDecoratedCache(userCache, decoratedUserCache);\n\n            Cache attachmentCache = cacheManager.getCache(\"attachment-cache\");\n            Ehcache decoratedAttachmentCache = InstrumentedEhcache.instrument(attachmentCache);\n            cacheManager.replaceCacheWithDecoratedCache(attachmentCache, decoratedAttachmentCache);\n\n            Cache friendsCache = cacheManager.getCache(\"friends-cache\");\n            Ehcache decoratedFriendsCache = InstrumentedEhcache.instrument(friendsCache);\n            cacheManager.replaceCacheWithDecoratedCache(friendsCache, decoratedFriendsCache);\n\n            Cache followersCache = cacheManager.getCache(\"followers-cache\");\n            Ehcache decoratedFollowersCache = InstrumentedEhcache.instrument(followersCache);\n            cacheManager.replaceCacheWithDecoratedCache(followersCache, decoratedFollowersCache);\n\n            Cache groupCache = cacheManager.getCache(\"group-cache\");\n            Ehcache decoratedGroupCache = InstrumentedEhcache.instrument(groupCache);\n            cacheManager.replaceCacheWithDecoratedCache(groupCache, decoratedGroupCache);\n\n            Cache groupUserCache = cacheManager.getCache(\"group-user-cache\");\n            Ehcache decoratedGroupUserCache = InstrumentedEhcache.instrument(groupUserCache);\n            cacheManager.replaceCacheWithDecoratedCache(groupUserCache, decoratedGroupUserCache);\n        }\n        EhCacheCacheManager ehCacheManager = new EhCacheCacheManager();\n        ehCacheManager.setCacheManager(cacheManager);\n        return ehCacheManager;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/config/CassandraConfiguration.java",
    "content": "package fr.ippon.tatami.config;\n\nimport me.prettyprint.cassandra.connection.HOpTimer;\nimport me.prettyprint.cassandra.connection.MetricsOpTimer;\nimport me.prettyprint.cassandra.model.ConfigurableConsistencyLevel;\nimport me.prettyprint.cassandra.service.CassandraHostConfigurator;\nimport me.prettyprint.cassandra.service.ThriftCfDef;\nimport me.prettyprint.cassandra.service.ThriftCluster;\nimport me.prettyprint.cassandra.service.ThriftKsDef;\nimport me.prettyprint.hector.api.Cluster;\nimport me.prettyprint.hector.api.HConsistencyLevel;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.ddl.ColumnFamilyDefinition;\nimport me.prettyprint.hector.api.ddl.ComparatorType;\nimport me.prettyprint.hector.api.ddl.KeyspaceDefinition;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hom.EntityManagerImpl;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\nimport javax.annotation.PreDestroy;\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Cassandra configuration file.\n *\n * @author Julien Dubois\n */\n@Configuration\npublic class CassandraConfiguration {\n\n    private final Logger log = LoggerFactory.getLogger(CassandraConfiguration.class);\n\n    @Inject\n    private Environment env;\n\n    private Cluster myCluster;\n\n    @PreDestroy\n    public void destroy() {\n        log.info(\"Closing Hector connection pool\");\n        myCluster.getConnectionManager().shutdown();\n        HFactory.shutdownCluster(myCluster);\n    }\n\n    @Bean\n    public Keyspace keyspaceOperator() {\n        log.info(\"Configuring Cassandra keyspace\");\n        String cassandraHost = env.getProperty(\"cassandra.host\");\n        String cassandraClusterName = env.getProperty(\"cassandra.clusterName\");\n        String cassandraKeyspace = env.getProperty(\"cassandra.keyspace\");\n\n        CassandraHostConfigurator cassandraHostConfigurator = new CassandraHostConfigurator(cassandraHost);\n        cassandraHostConfigurator.setMaxActive(100);\n        if (env.acceptsProfiles(Constants.SPRING_PROFILE_METRICS)) {\n            log.debug(\"Cassandra Metrics monitoring enabled\");\n            HOpTimer hOpTimer = new MetricsOpTimer(cassandraClusterName);\n            cassandraHostConfigurator.setOpTimer(hOpTimer);\n        }\n        ThriftCluster cluster = new ThriftCluster(cassandraClusterName, cassandraHostConfigurator);\n        this.myCluster = cluster; // Keep a pointer to the cluster, as Hector is buggy and can't find it again...\n        ConfigurableConsistencyLevel consistencyLevelPolicy = new ConfigurableConsistencyLevel();\n        consistencyLevelPolicy.setDefaultReadConsistencyLevel(HConsistencyLevel.ONE);\n\n        KeyspaceDefinition keyspaceDef = cluster.describeKeyspace(cassandraKeyspace);\n        if (keyspaceDef == null) {\n            log.warn(\"Keyspace \\\" {} \\\" does not exist, creating it!\", cassandraKeyspace);\n            keyspaceDef = new ThriftKsDef(cassandraKeyspace);\n            cluster.addKeyspace(keyspaceDef, true);\n\n            addColumnFamily(cluster, ColumnFamilyKeys.USER_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.FRIENDS_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.FOLLOWERS_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.STATUS_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.DOMAIN_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.REGISTRATION_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.RSS_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.MAILDIGEST_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.SHARES_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.DISCUSSION_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.USER_TAGS_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.TAG_FOLLOWERS_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.GROUP_MEMBERS_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.USER_GROUPS_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.GROUP_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.GROUP_DETAILS_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.ATTACHMENT_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.AVATAR_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.DOMAIN_CONFIGURATION_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.TATAMIBOT_CONFIGURATION_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.APPLE_DEVICE_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.BLOCK_USERS_CF, 0);\n            addColumnFamily(cluster, ColumnFamilyKeys.STATUS_REPORT_CF, 0);\n\n            addColumnFamilySortedbyUUID(cluster, ColumnFamilyKeys.TIMELINE_CF, 0);\n            addColumnFamilySortedbyUUID(cluster, ColumnFamilyKeys.TIMELINE_SHARES_CF, 0);\n            addColumnFamilySortedbyUUID(cluster, ColumnFamilyKeys.MENTIONLINE_CF, 0);\n            addColumnFamilySortedbyUUID(cluster, ColumnFamilyKeys.USERLINE_CF, 0);\n            addColumnFamilySortedbyUUID(cluster, ColumnFamilyKeys.USERLINE_SHARES_CF, 0);\n            addColumnFamilySortedbyUUID(cluster, ColumnFamilyKeys.FAVLINE_CF, 0);\n            addColumnFamilySortedbyUUID(cluster, ColumnFamilyKeys.TAGLINE_CF, 0);\n            addColumnFamilySortedbyUUID(cluster, ColumnFamilyKeys.TRENDS_CF, 0);\n            addColumnFamilySortedbyUUID(cluster, ColumnFamilyKeys.USER_TRENDS_CF, 0);\n            addColumnFamilySortedbyUUID(cluster, ColumnFamilyKeys.GROUPLINE_CF, 0);\n            addColumnFamilySortedbyUUID(cluster, ColumnFamilyKeys.USER_ATTACHMENT_CF, 0);\n            addColumnFamilySortedbyUUID(cluster, ColumnFamilyKeys.STATUS_ATTACHMENT_CF, 0);\n            addColumnFamilySortedbyUUID(cluster, ColumnFamilyKeys.DOMAINLINE_CF, 0);\n            addColumnFamilySortedbyUUID(cluster, ColumnFamilyKeys.DOMAIN_TATAMIBOT_CF, 0);\n\n            addColumnFamilyCounter(cluster, ColumnFamilyKeys.COUNTER_CF, 0);\n            addColumnFamilyCounter(cluster, ColumnFamilyKeys.TAG_COUNTER_CF, 0);\n            addColumnFamilyCounter(cluster, ColumnFamilyKeys.GROUP_COUNTER_CF, 0);\n            addColumnFamilyCounter(cluster, ColumnFamilyKeys.DAYLINE_CF, 0);\n\n            //Tatami Bot CF\n            addColumnFamily(cluster, ColumnFamilyKeys.TATAMIBOT_DUPLICATE_CF, 0);\n        } else {\n            /*\n            This case only concerns the creation of new CF that didn't exist in the previous version of Tatami.\n            As we cannot afford to drop the keyspace in production, this case is an update of the database that\n            should be executed only one time in production.\n             */\n            List<ColumnFamilyDefinition> lcf = keyspaceDef.getCfDefs();\n            List<String> lcfNames = new ArrayList<String>();\n            for(ColumnFamilyDefinition cfd : lcf){\n                lcfNames.add(cfd.getName());\n            }\n            // The new tables\n            if(!lcfNames.contains(ColumnFamilyKeys.BLOCK_USERS_CF)){\n                addColumnFamily(cluster, ColumnFamilyKeys.BLOCK_USERS_CF, 0);\n                log.debug(\"{} column family successfully created\", ColumnFamilyKeys.BLOCK_USERS_CF);\n\n            }\n            if(!lcfNames.contains(ColumnFamilyKeys.STATUS_REPORT_CF)){\n                addColumnFamily(cluster, ColumnFamilyKeys.STATUS_REPORT_CF, 0);\n                log.debug(\"{} column family successfully created\", ColumnFamilyKeys.STATUS_REPORT_CF);\n            }\n        }\n        return HFactory.createKeyspace(cassandraKeyspace, cluster, consistencyLevelPolicy);\n    }\n\n    @Bean\n    public EntityManagerImpl entityManager(Keyspace keyspace) {\n        String[] packagesToScan = {\"fr.ippon.tatami.domain\", \"fr.ippon.tatami.bot.config\"};\n        return new EntityManagerImpl(keyspace, packagesToScan);\n    }\n\n    private void addColumnFamily(ThriftCluster cluster, String cfName, int rowCacheKeysToSave) {\n\n        String cassandraKeyspace = this.env.getProperty(\"cassandra.keyspace\");\n\n        ColumnFamilyDefinition cfd =\n                HFactory.createColumnFamilyDefinition(cassandraKeyspace, cfName);\n\n        cfd.setRowCacheKeysToSave(rowCacheKeysToSave);\n        cluster.addColumnFamily(cfd);\n    }\n\n    private void addColumnFamilySortedbyUUID(ThriftCluster cluster, String cfName, int rowCacheKeysToSave) {\n\n        String cassandraKeyspace = this.env.getProperty(\"cassandra.keyspace\");\n\n        ColumnFamilyDefinition cfd =\n                HFactory.createColumnFamilyDefinition(cassandraKeyspace, cfName);\n\n        cfd.setRowCacheKeysToSave(rowCacheKeysToSave);\n        cfd.setComparatorType(ComparatorType.UUIDTYPE);\n        cluster.addColumnFamily(cfd);\n    }\n\n\n    private void addColumnFamilyCounter(ThriftCluster cluster, String cfName, int rowCacheKeysToSave) {\n        String cassandraKeyspace = this.env.getProperty(\"cassandra.keyspace\");\n\n        ThriftCfDef cfd =\n                new ThriftCfDef(cassandraKeyspace, cfName, ComparatorType.UTF8TYPE);\n\n        cfd.setRowCacheKeysToSave(rowCacheKeysToSave);\n        cfd.setDefaultValidationClass(ComparatorType.COUNTERTYPE.getClassName());\n        cluster.addColumnFamily(cfd);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/config/ColumnFamilyKeys.java",
    "content": "package fr.ippon.tatami.config;\n\n/**\n * @author Julien Dubois\n */\npublic class ColumnFamilyKeys {\n\n    private ColumnFamilyKeys() {\n\n    }\n\n    public static final String USER_CF = \"User\";\n\n    public static final String FRIENDS_CF = \"Friends\";\n\n    public static final String FOLLOWERS_CF = \"Followers\";\n\n    public static final String STATUS_CF = \"Status\";\n\n    public static final String SHARES_CF = \"Shares\";\n\n    public static final String DISCUSSION_CF = \"Discussion\";\n\n    public static final String DAYLINE_CF = \"Dayline\";\n\n    public static final String FAVLINE_CF = \"Favline\";\n\n    public static final String TAGLINE_CF = \"Tagline\";\n\n    public static final String TIMELINE_CF = \"Timeline\";\n\n    public static final String TIMELINE_SHARES_CF = \"TimelineShares\";\n\n    public static final String MENTIONLINE_CF = \"Mentionline\";\n\n    public static final String USERLINE_CF = \"Userline\";\n\n    public static final String USERLINE_SHARES_CF = \"UserlineShares\";\n\n    public static final String COUNTER_CF = \"Counter\";\n\n    public static final String DOMAIN_CF = \"Domain\";\n\n    public static final String REGISTRATION_CF = \"Registration\";\n\n    public static final String RSS_CF = \"Rss\";\n\n    public static final String MAILDIGEST_CF = \"MailDigest\";\n\n    public static final String TRENDS_CF = \"Trends\";\n\n    public static final String TAG_FOLLOWERS_CF = \"TagFollowers\";\n\n    public static final String USER_TAGS_CF = \"UserTags\";\n\n    public static final String TAG_COUNTER_CF = \"TagCounter\";\n\n    public static final String USER_TRENDS_CF = \"UserTrends\";\n\n    public static final String GROUP_CF = \"Group\";\n\n    public static final String GROUP_DETAILS_CF = \"GroupDetails\";\n\n    public static final String GROUP_MEMBERS_CF = \"GroupMembers\";\n\n    public static final String USER_GROUPS_CF = \"UserGroups\";\n\n    public static final String GROUP_COUNTER_CF = \"GroupCounter\";\n\n    public static final String GROUPLINE_CF = \"Groupline\";\n\n    public static final String TATAMIBOT_DUPLICATE_CF = \"TatamiBotDuplicate\";\n\n    public static final String ATTACHMENT_CF = \"Attachment\";\n\n    public static final String USER_ATTACHMENT_CF = \"UserAttachments\";\n\n    public static final String STATUS_ATTACHMENT_CF = \"StatusAttachments\";\n\n    public static final String DOMAIN_CONFIGURATION_CF = \"DomainConfiguration\";\n\n    public static final String DOMAINLINE_CF = \"Domainline\";\n\n    public static final String DOMAIN_TATAMIBOT_CF = \"DomainTatamibot\";\n\n    public static final String TATAMIBOT_CONFIGURATION_CF = \"TatamibotConfiguration\";\n\n    public static final String AVATAR_CF = \"Avatar\";\n\n    public static final String APPLE_DEVICE_CF = \"AppleDevice\";\n\n    public static final String APPLE_DEVICE_USER_CF = \"AppleDeviceUser\";\n\n    public static final String BLOCK_USERS_CF = \"UsersBlocked\";\n\n    public static final String STATUS_REPORT_CF = \"ReportedStatus\";\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/config/Constants.java",
    "content": "package fr.ippon.tatami.config;\n\n/**\n * Application constants.\n */\npublic class Constants {\n\n    private Constants() {\n    }\n\n    public static final String SPRING_PROFILE_METRICS = \"metrics\";\n\n    public static final String REMOTE_ENGINE = \"remote\";\n\n    public static final String EMBEDDED_ENGINE = \"embedded\";\n\n    public static String VERSION = null;\n\n    public static String GOOGLE_ANALYTICS_KEY = null;\n\n    public static final int PAGINATION_SIZE = 50;\n\n    public static final String TATAMIBOT_NAME = \"tatamibot\";\n\n    public static final int AVATAR_SIZE = 200;\n\n    /**\n     * Cassandra : number of columns to return when not doing a name-based template\n     */\n    public static final int CASSANDRA_MAX_COLUMNS = 10000;\n\n    /**\n     * Cassandra : number of rows to return\n     */\n    public static final int CASSANDRA_MAX_ROWS = 10000;\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/config/DispatcherServletConfig.java",
    "content": "package fr.ippon.tatami.config;\r\n\r\nimport fr.ippon.tatami.web.syndic.SyndicView;\r\nimport org.apache.commons.lang.CharEncoding;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\nimport org.springframework.context.MessageSource;\r\nimport org.springframework.context.annotation.*;\r\nimport org.springframework.context.support.ReloadableResourceBundleMessageSource;\r\nimport org.springframework.core.env.Environment;\r\nimport org.springframework.web.multipart.MultipartResolver;\r\nimport org.springframework.web.multipart.commons.CommonsMultipartResolver;\r\nimport org.springframework.web.servlet.HandlerExceptionResolver;\r\nimport org.springframework.web.servlet.ModelAndView;\r\nimport org.springframework.web.servlet.View;\r\nimport org.springframework.web.servlet.ViewResolver;\r\nimport org.springframework.web.servlet.config.annotation.EnableWebMvc;\r\nimport org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;\r\nimport org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;\r\nimport org.springframework.web.servlet.i18n.LocaleChangeInterceptor;\r\nimport org.springframework.web.servlet.i18n.SessionLocaleResolver;\r\nimport org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;\r\nimport org.springframework.web.servlet.view.ContentNegotiatingViewResolver;\r\nimport org.springframework.web.servlet.view.JstlView;\r\nimport org.springframework.web.servlet.view.UrlBasedViewResolver;\r\nimport org.springframework.web.servlet.view.json.MappingJackson2JsonView;\r\n\r\nimport javax.inject.Inject;\r\nimport javax.servlet.http.HttpServletRequest;\r\nimport javax.servlet.http.HttpServletResponse;\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\n@Configuration\r\n@ComponentScan(\"fr.ippon.tatami.web\")\r\n@EnableWebMvc\r\n@PropertySource({\"classpath:/META-INF/tatami/tatami.properties\",\r\n        \"classpath:/META-INF/tatami/customization.properties\"})\r\n@ImportResource(\"classpath:META-INF/spring/applicationContext-metrics.xml\")\r\npublic class DispatcherServletConfig extends WebMvcConfigurerAdapter {\r\n\r\n    private final Logger log = LoggerFactory.getLogger(DispatcherServletConfig.class);\r\n\r\n    @Inject\r\n    private Environment env;\r\n\r\n    @Bean\r\n    public ViewResolver ContentNegotiatingViewResolver() {\r\n        log.debug(\"Configuring the ContentNegotiatingViewResolver\");\r\n        ContentNegotiatingViewResolver viewResolver = new ContentNegotiatingViewResolver();\r\n        List<ViewResolver> viewResolvers = new ArrayList<ViewResolver>();\r\n\r\n        UrlBasedViewResolver urlBasedViewResolver = new UrlBasedViewResolver();\r\n        urlBasedViewResolver.setViewClass(JstlView.class);\r\n        urlBasedViewResolver.setPrefix(\"/WEB-INF/pages/\");\r\n        urlBasedViewResolver.setSuffix(\".jsp\");\r\n        viewResolvers.add(urlBasedViewResolver);\r\n\r\n        viewResolver.setViewResolvers(viewResolvers);\r\n\r\n        List<View> defaultViews = new ArrayList<View>();\r\n        defaultViews.add(new MappingJackson2JsonView());\r\n        defaultViews.add(syndicView());\r\n        viewResolver.setDefaultViews(defaultViews);\r\n\r\n        return viewResolver;\r\n    }\r\n\r\n    @Bean\r\n    public SyndicView syndicView() {\r\n        return new SyndicView();\r\n    }\r\n\r\n    @Bean\r\n    public SessionLocaleResolver localeResolver() {\r\n        return new SessionLocaleResolver();\r\n    }\r\n\r\n    @Bean\r\n    public LocaleChangeInterceptor localeChangeInterceptor() {\r\n        log.debug(\"Configuring localeChangeInterceptor\");\r\n        LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();\r\n        localeChangeInterceptor.setParamName(\"language\");\r\n        return localeChangeInterceptor;\r\n    }\r\n\r\n    @Bean\r\n    public MessageSource messageSource() {\r\n        log.debug(\"Loading MessageSources\");\r\n        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();\r\n        messageSource.setBasename(\"/WEB-INF/messages/messages\");\r\n        messageSource.setDefaultEncoding(CharEncoding.UTF_8);\r\n        if (\"true\".equals(env.getProperty(\"tatami.message.reloading.enabled\"))) {\r\n            messageSource.setCacheSeconds(1);\r\n        }\r\n        return messageSource;\r\n    }\r\n\r\n    @Bean\r\n    public MultipartResolver multipartResolver() {\r\n        CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();\r\n        Long maxSize = Long.parseLong(env.getProperty(\"file.max.size\"));\r\n        multipartResolver.setMaxUploadSize(maxSize); // 10 Mo max file size by default\r\n        return multipartResolver;\r\n    }\r\n\r\n    @Bean\r\n    public RequestMappingHandlerMapping requestMappingHandlerMapping() {\r\n        log.debug(\"Creating requestMappingHandlerMapping\");\r\n        RequestMappingHandlerMapping requestMappingHandlerMapping = new RequestMappingHandlerMapping();\r\n        requestMappingHandlerMapping.setUseSuffixPatternMatch(false);\r\n        Object[] interceptors = {localeChangeInterceptor()};\r\n        requestMappingHandlerMapping.setInterceptors(interceptors);\r\n        return requestMappingHandlerMapping;\r\n    }\r\n\r\n    @Override\r\n    public void addResourceHandlers(ResourceHandlerRegistry registry) {\r\n        log.debug(\"Adding static resource handlers\");\r\n\r\n        registry.addResourceHandler(\"/static-wro4j/\" + env.getProperty(\"tatami.version\") + \"/**\")\r\n                .addResourceLocations(\"/WEB-INF/generated-wro4j/\")\r\n                .setCachePeriod(60 * 60 * 24 * 30);\r\n\r\n        registry.addResourceHandler(\"/css/**\")\r\n                .addResourceLocations(\"/css/\")\r\n                .setCachePeriod(60 * 60 * 24 * 30);\r\n\r\n        registry.addResourceHandler(\"/static/\" + env.getProperty(\"tatami.version\") + \"/**\")\r\n                .addResourceLocations(\"/js/\")\r\n                .setCachePeriod(60 * 60 * 24 * 30);\r\n    }\r\n\r\n    @Override\r\n    public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {\r\n        exceptionResolvers.add(new HandlerExceptionResolver() {\r\n\r\n            @Override\r\n            public ModelAndView resolveException(HttpServletRequest request,\r\n                                                 HttpServletResponse response,\r\n                                                 Object handler,\r\n                                                 Exception ex) {\r\n                try {\r\n                    if (log.isErrorEnabled()) {\r\n                        log.error(\"An error has occured : \" + ex.getMessage());\r\n                        ex.printStackTrace();\r\n                    }\r\n                    response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);\r\n                    return new ModelAndView();\r\n                } catch (Exception handlerException) {\r\n                    log.warn(\"Handling of [\" + ex.getClass().getName() + \"] resulted in Exception\", handlerException);\r\n                }\r\n                return null;\r\n            }\r\n        });\r\n    }\r\n}\r\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/config/GroupRoles.java",
    "content": "package fr.ippon.tatami.config;\n\n/**\n * Constants for groupe roles.\n */\npublic class GroupRoles {\n\n    private GroupRoles() {\n    }\n\n    public static final String ADMIN = \"ADMIN\";\n\n    public static final String MEMBER = \"MEMBER\";\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/config/MailConfiguration.java",
    "content": "package fr.ippon.tatami.config;\n\nimport org.apache.commons.lang.CharEncoding;\nimport org.apache.velocity.app.VelocityEngine;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.context.MessageSource;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.context.support.ReloadableResourceBundleMessageSource;\nimport org.springframework.ui.velocity.VelocityEngineFactoryBean;\n\nimport java.io.IOException;\nimport java.util.Properties;\n\n/**\n * Configuration for velocity template and i18n for emails.\n *\n * @author Pierre Rust\n */\n@Configuration\npublic class MailConfiguration {\n\n    private static final Logger log = LoggerFactory.getLogger(MailConfiguration.class);\n\n    @Bean\n    public VelocityEngine velocityEngine() throws IOException {\n        log.debug(\"Starting Velocity Engine\");\n        VelocityEngineFactoryBean factory = new VelocityEngineFactoryBean();\n        Properties props = new Properties();\n\n        props.put(\"resource.loader\", \"class\");\n        props.put(\"class.resource.loader.class\", \"org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader\");\n\n        // necessary to get logs on templates's error\n        props.put(\"runtime.log.logsystem.class\", \"org.apache.velocity.runtime.log.Log4JLogChute\");\n        props.put(\"runtime.log.error.stacktrace\", \"true\");\n        props.put(\"runtime.log.warn.stacktrace\", \"true\");\n        props.put(\"runtime.log.info.stacktrace\", \"true\");\n        props.put(\"runtime.log.invalid.reference\", \"true\");\n        // TODO : FileResourceLoader could be used to externalize templates\n\n        // enable relative includes\n        props.put(\"eventhandler.include.class\", \"org.apache.velocity.app.event.implement.IncludeRelativePath\");\n\n        factory.setVelocityProperties(props);\n        return factory.createVelocityEngine();\n    }\n\n    @Bean\n    public MessageSource mailMessageSource() {\n        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();\n        messageSource.setBasename(\"classpath:/META-INF/tatami/mails/messages/messages\");\n        messageSource.setDefaultEncoding(CharEncoding.UTF_8);\n        log.info(\"loading non-reloadable mail messages resources\");\n        return messageSource;\n    }\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/config/MetricsConfiguration.java",
    "content": "package fr.ippon.tatami.config;\n\nimport com.yammer.metrics.HealthChecks;\nimport com.yammer.metrics.reporting.GraphiteReporter;\nimport fr.ippon.tatami.config.metrics.CassandraHealthCheck;\nimport fr.ippon.tatami.config.metrics.JavaMailHealthCheck;\nimport fr.ippon.tatami.service.MailService;\nimport me.prettyprint.hector.api.Keyspace;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\nimport javax.annotation.PostConstruct;\nimport javax.inject.Inject;\nimport java.util.concurrent.TimeUnit;\n\n@Configuration\npublic class MetricsConfiguration {\n\n    private final Logger log = LoggerFactory.getLogger(MetricsConfiguration.class);\n\n    @Inject\n    private Environment env;\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Inject\n    private MailService mailService;\n\n    @PostConstruct\n    public void initMetrics() {\n        if (env.acceptsProfiles(Constants.SPRING_PROFILE_METRICS)) {\n            log.debug(\"Initializing Metrics healthchecks\");\n            HealthChecks.register(new CassandraHealthCheck(keyspaceOperator));\n            HealthChecks.register(new JavaMailHealthCheck(mailService));\n\n            String graphiteHost = env.getProperty(\"tatami.metrics.graphite.host\");\n            if (graphiteHost != null) {\n                log.debug(\"Initializing Metrics Graphite reporting\");\n                Integer graphitePort = env.getProperty(\"tatami.metrics.graphite.port\", Integer.class);\n                GraphiteReporter.enable(1,\n                        TimeUnit.MINUTES,\n                        graphiteHost,\n                        graphitePort);\n            } else {\n                log.warn(\"Graphite server is not configured, unable to send any data to Graphite\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/config/SearchConfiguration.java",
    "content": "package fr.ippon.tatami.config;\n\nimport fr.ippon.tatami.service.elasticsearch.ElasticsearchEngine;\nimport fr.ippon.tatami.service.elasticsearch.EmbeddedElasticsearchEngine;\nimport fr.ippon.tatami.service.elasticsearch.RemoteElasticsearchEngine;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.context.annotation.Bean;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.core.env.Environment;\n\nimport javax.inject.Inject;\n\n/**\n * Search configuration, with Elastic Search.\n */\n@Configuration\npublic class SearchConfiguration {\n\n    private final Logger log = LoggerFactory.getLogger(SearchConfiguration.class);\n\n    @Inject\n    private Environment env;\n\n    @Bean\n    public ElasticsearchEngine elasticsearchEngine() {\n        log.info(\"Starting Elasticsearch\");\n        String mode = env.getRequiredProperty(\"elasticsearch.engine.mode\");\n        if (Constants.REMOTE_ENGINE.equalsIgnoreCase(mode)) {\n            return new RemoteElasticsearchEngine();\n        } else if (Constants.EMBEDDED_ENGINE.equalsIgnoreCase(mode)) {\n            return new EmbeddedElasticsearchEngine();\n        } else {\n            //Log do not support log.fatal\n            log.error(\"Elasticsearch engine mode is not defined, please configure the \\\"elasticsearch.engine.mode\\\" property\");\n            throw new IllegalArgumentException(\"Elasticsearch engine mode \" + mode + \" not defined\");\n        }\n    }\n\n    @Bean\n    public String indexNamePrefix() {\n        return env.getProperty(\"elasticsearch.indexNamePrefix\");\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/config/metrics/CassandraHealthCheck.java",
    "content": "package fr.ippon.tatami.config.metrics;\n\nimport com.yammer.metrics.core.HealthCheck;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.exceptions.HectorException;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.DOMAIN_CF;\nimport static me.prettyprint.hector.api.factory.HFactory.createRangeSlicesQuery;\n\n/**\n * Metrics HealthCheck for Cassandra.\n */\npublic class CassandraHealthCheck extends HealthCheck {\n\n    private final Keyspace keyspaceOperator;\n\n    public CassandraHealthCheck(Keyspace keyspaceOperator) {\n        super(\"Cassandra\");\n        this.keyspaceOperator = keyspaceOperator;\n    }\n\n    @Override\n    public Result check() throws Exception {\n        try {\n            createRangeSlicesQuery(keyspaceOperator,\n                    StringSerializer.get(), StringSerializer.get(), StringSerializer.get())\n                    .setColumnFamily(DOMAIN_CF)\n                    .setRange(null, null, false, 1)\n                    .execute()\n                    .get();\n            return Result.healthy();\n        } catch (HectorException he) {\n            return Result.unhealthy(\"Cannot connect to Cassandra Cluster : \" + keyspaceOperator.getKeyspaceName());\n        }\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/config/metrics/JavaMailHealthCheck.java",
    "content": "package fr.ippon.tatami.config.metrics;\n\nimport com.yammer.metrics.core.HealthCheck;\nimport fr.ippon.tatami.service.MailService;\n\n/**\n * Metrics HealthCheck for JavaMail.\n */\npublic class JavaMailHealthCheck extends HealthCheck {\n\n    private final MailService mailService;\n\n    public JavaMailHealthCheck(MailService mailService) {\n        super(\"JavaMail\");\n        this.mailService = mailService;\n    }\n\n    @Override\n    public Result check() throws Exception {\n        if (mailService.connectSmtpServer()) {\n            return Result.healthy();\n        } else {\n            return Result.unhealthy(\"Cannot connect to Mail server\");\n        }\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/domain/Attachment.java",
    "content": "package fr.ippon.tatami.domain;\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\nimport org.joda.time.DateTime;\nimport org.joda.time.format.DateTimeFormatter;\nimport org.joda.time.format.DateTimeFormatterBuilder;\n\nimport java.io.Serializable;\nimport java.util.Date;\n\npublic class Attachment implements Serializable {\n\n    private static final DateTimeFormatter oldDateFormatter = new DateTimeFormatterBuilder()\n            .appendDayOfMonth(1)\n            .appendLiteral(' ')\n            .appendMonthOfYearShortText()\n            .appendLiteral(' ')\n            .appendYear(4, 4)\n            .toFormatter();\n\n    private String attachmentId;\n\n    private String filename;\n\n    @JsonIgnore\n    private Date creationDate;\n\n    private String prettyPrintCreationDate;\n\n    @JsonIgnore\n    private byte[] content;\n    \n    @JsonIgnore\n    private byte[] thumbnail;\n    \n    private boolean hasThumbnail = false;\n\n    private long size;\n\n    public String getAttachmentId() {\n        return attachmentId;\n    }\n\n    public void setAttachmentId(String attachmentId) {\n        this.attachmentId = attachmentId;\n    }\n\n    public String getFilename() {\n        return filename;\n    }\n\n    public void setFilename(String filename) {\n        this.filename = filename;\n    }\n\n    public Date getCreationDate() {\n        return creationDate;\n    }\n\n    public void setCreationDate(Date creationDate) {\n        this.creationDate = creationDate;\n        DateTime dateTime = new DateTime(creationDate);\n        this.prettyPrintCreationDate = oldDateFormatter.print(dateTime);\n    }\n\n    public String getPrettyPrintCreationDate() {\n        return prettyPrintCreationDate;\n    }\n\n    public void setPrettyPrintCreationDate(String prettyPrintCreationDate) {\n        this.prettyPrintCreationDate = prettyPrintCreationDate;\n    }\n\n    public byte[] getContent() {\n        return content;\n    }\n\n    public void setContent(byte[] content) {\n        this.content = content;\n    }\n    \n    public byte[] getThumbnail() {\n    \treturn thumbnail;\n    }\n    \n    public void setThumbnail(byte[] thumbnail) {\n    \tthis.thumbnail = thumbnail;\n    }\n    \n    public boolean getHasThumbnail() {\n    \treturn this.hasThumbnail;\n    }\n    \n    public void setHasThumbnail(boolean hasThumbnail) {\n    \tthis.hasThumbnail = hasThumbnail;\n    }\n\n    public long getSize() {\n        return size;\n    }\n\n    public void setSize(long size) {\n        this.size = size;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        Attachment that = (Attachment) o;\n\n        return attachmentId.equals(that.attachmentId);\n\n    }\n\n    @Override\n    public int hashCode() {\n        return attachmentId.hashCode();\n    }\n\n    @Override\n    public String toString() {\n        return \"Attachment{\" +\n                \"attachmentId='\" + attachmentId + '\\'' +\n                \", filename='\" + filename + '\\'' +\n                \", prettyPrintCreationDate='\" + prettyPrintCreationDate + '\\'' +\n                \", size=\" + size +\n                '}';\n    }\n}"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/domain/Avatar.java",
    "content": "package fr.ippon.tatami.domain;\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\n\nimport java.io.Serializable;\nimport java.util.Date;\n\npublic class Avatar implements Serializable {\n\n    private String avatarId;\n\n    private String filename;\n\n    @JsonIgnore\n    private Date creationDate;\n\n    @JsonIgnore\n    private byte[] content;\n\n    private long size;\n\n    public String getAvatarId() {\n        return avatarId;\n    }\n\n    public void setAvatarId(String AvatarId) {\n        this.avatarId = AvatarId;\n    }\n\n    public String getFilename() {\n        return filename;\n    }\n\n    public void setFilename(String filename) {\n        this.filename = filename;\n    }\n\n    public Date getCreationDate() {\n        return creationDate;\n    }\n\n    public void setCreationDate(Date creationDate) {\n        this.creationDate = creationDate;\n    }\n\n    public byte[] getContent() {\n        return content;\n    }\n\n    public void setContent(byte[] content) {\n        this.content = content;\n    }\n\n    public long getSize() {\n        return size;\n    }\n\n    public void setSize(long size) {\n        this.size = size;\n    }\n\n    @Override\n    public int hashCode() {\n        return avatarId.hashCode();\n    }\n\n    @Override\n    public String toString() {\n        return \"Avatar{\" +\n                \"avatarId='\" + avatarId + '\\'' +\n                \", filename='\" + filename + '\\'' +\n                \", CreationDate='\" + creationDate + '\\'' +\n                \", size=\" + size +\n                '}';\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/domain/DigestType.java",
    "content": "package fr.ippon.tatami.domain;\n\n/**\n * @author Pierre Rust\n */\npublic enum DigestType {\n\n    WEEKLY_DIGEST(\"WEEKLY\"),\n    DAILY_DIGEST(\"DAILY\");\n\n    private DigestType(final String text) {\n        this.text = text;\n    }\n\n    private final String text;\n\n    /* (non-Javadoc)\n     * @see java.lang.Enum#toString()\n     */\n    @Override\n    public String toString() {\n        return text;\n    }\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/domain/Domain.java",
    "content": "package fr.ippon.tatami.domain;\n\nimport java.io.Serializable;\n\n/**\n * A domain is a domain name (e.g. \"ippon.fr\"), and represents a company.\n */\npublic class Domain implements Serializable, Comparable<Domain> {\n\n    private String name;\n\n    private int numberOfUsers;\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public int getNumberOfUsers() {\n        return numberOfUsers;\n    }\n\n    public void setNumberOfUsers(int numberOfUsers) {\n        this.numberOfUsers = numberOfUsers;\n    }\n\n    @Override\n    public int compareTo(Domain other) {\n        return this.name.compareTo(other.name);\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) {\n            return true;\n        } else if (o == null || getClass() != o.getClass()) {\n            return false;\n        }\n\n        Domain domain = (Domain) o;\n\n        return name.equals(domain.name);\n\n    }\n\n    @Override\n    public int hashCode() {\n        return name.hashCode();\n    }\n\n    @Override\n    public String toString() {\n        return \"Domain{\" +\n                \"name='\" + name + '\\'' +\n                \", numberOfUsers=\" + numberOfUsers +\n                '}';\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/domain/DomainConfiguration.java",
    "content": "package fr.ippon.tatami.domain;\n\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.Serializable;\nimport java.util.Properties;\n\nimport javax.persistence.Column;\nimport javax.persistence.Entity;\nimport javax.persistence.Id;\nimport javax.persistence.Table;\n\nimport org.apache.commons.io.IOUtils;\n\n/**\n * The configuration for a specific domain.\n *\n * @author Julien Dubois\n */\n@Entity\n@Table(name = \"DomainConfiguration\")\npublic class DomainConfiguration implements Serializable {\n\n    public static class SubscriptionAndStorageSizeOptions {\n\n        public static String BASICSIZE = \"10\";\n\n        public static String PREMIUMSIZE = \"1000\";\n\n        public static String IPPONSIZE = \"100000\";\n        \n        public static String BASICSUSCRIPTION = \"0\";\n\n        public static String PREMIUMSUSCRIPTION = \"1\";\n\n        public static String IPPONSUSCRIPTION = \"-1\";\n                \n        static{\n            InputStream inputStream=null;\n            try{\n            \t\n                \n                \n                inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(\"META-INF/tatami/tatami.properties\");\n                \n                Properties props = new Properties();\n                props.load(inputStream);\n\t\t\t    \n\t\t\t    String basicSize = \"storage.basic.max.size\";\n                String premiumSize = \"storage.premium.max.size\";\n                String ipponSize = \"storage.ippon.max.size\";\n                String basicSuscription = \"suscription.level.free\";\n                String premiumSuscription = \"suscription.level.premium\";\n                String ipponSuscription = \"suscription.level.ippon\";\n                if(!props.containsKey(basicSize) || !props.containsKey(premiumSize) \n                \t\t|| !props.containsKey(ipponSize) || !props.containsKey(basicSuscription) \n                \t\t|| !props.containsKey(premiumSuscription) || !props.containsKey(ipponSuscription))\n                    throw new IllegalStateException(\"Property not found\");\n                BASICSIZE= props.getProperty(basicSize);\n                PREMIUMSIZE= props.getProperty(premiumSize);\n                IPPONSIZE= props.getProperty(ipponSize);\n                BASICSUSCRIPTION= props.getProperty(basicSuscription);\n                PREMIUMSUSCRIPTION= props.getProperty(premiumSuscription);\n                IPPONSUSCRIPTION= props.getProperty(ipponSuscription);\n                \n            } catch(IOException e){\n                throw new IllegalStateException(e);\n            }finally{\n                // apache commons / IO\n                IOUtils.closeQuietly(inputStream);\n            }\n        }\n        \n\n    }\n\n    @Id\n    private String domain;\n\n    @Column(name = \"subscriptionLevel\")\n    private String subscriptionLevel;\n\n    @Column(name = \"storageSize\")\n    private String storageSize;\n\n    @Column(name = \"adminLogin\")\n    private String adminLogin;\n    \n    public String getDomain() {\n        return domain;\n    }\n\n    public void setDomain(String domain) {\n        this.domain = domain;\n    }\n\n    public String getSubscriptionLevel() {\n        return subscriptionLevel;\n    }\n\n    public void setSubscriptionLevel(String subscriptionLevel) {\n        this.subscriptionLevel = subscriptionLevel;\n    }\n\n    public String getStorageSize() {\n        return storageSize;\n    }\n\n    public long getStorageSizeAsLong() {\n        try {\n            return Long.parseLong(this.storageSize) * 1000000;\n        } catch (NumberFormatException nfe) {\n            return Long.parseLong(SubscriptionAndStorageSizeOptions.BASICSIZE) * 1000000;\n        }\n    }\n\n    public void setStorageSize(String storageSize) {\n        this.storageSize = storageSize;\n    }\n\n    public String getAdminLogin() {\n        return adminLogin;\n    }\n\n    public void setAdminLogin(String adminLogin) {\n        this.adminLogin = adminLogin;\n    }\n\n    @Override\n    public String toString() {\n        return \"DomainConfiguration{\" +\n                \"domain='\" + domain + '\\'' +\n                \", subscriptionLevel='\" + subscriptionLevel + '\\'' +\n                \", storageSize='\" + storageSize + '\\'' +\n                \", adminLogin='\" + adminLogin + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/domain/Group.java",
    "content": "package fr.ippon.tatami.domain;\n\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\n\nimport java.io.Serializable;\n\n/**\n * A group.\n */\npublic class Group implements Comparable<Group>, Serializable, Cloneable {\n\n    private String groupId;\n\n    private boolean publicGroup;\n\n    private boolean archivedGroup;\n\n    private String name;\n\n    private String description;\n\n    @JsonIgnore\n    private String domain;\n\n    private long counter;\n\n    private boolean member;\n\n    private boolean administrator;\n\n    public String getGroupId() {\n        return groupId;\n    }\n\n    public void setGroupId(String groupId) {\n        this.groupId = groupId;\n    }\n\n    public boolean isPublicGroup() {\n        return publicGroup;\n    }\n\n    public void setPublicGroup(boolean publicGroup) {\n        this.publicGroup = publicGroup;\n    }\n\n    public boolean isArchivedGroup() {\n        return archivedGroup;\n    }\n\n    public void setArchivedGroup(boolean archivedGroup) {\n        this.archivedGroup = archivedGroup;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getDescription() {\n        return description;\n    }\n\n    public void setDescription(String description) {\n        this.description = description;\n    }\n\n    public String getDomain() {\n        return domain;\n    }\n\n    public void setDomain(String domain) {\n        this.domain = domain;\n    }\n\n    public long getCounter() {\n        return counter;\n    }\n\n    public void setCounter(long counter) {\n        this.counter = counter;\n    }\n\n    public boolean isMember() {\n        return member;\n    }\n\n    public void setMember(boolean member) {\n        this.member = member;\n    }\n\n    public boolean isAdministrator() {\n        return administrator;\n    }\n\n    public void setAdministrator(boolean administrator) {\n        this.administrator = administrator;\n    }\n\n    @Override\n    public int compareTo(Group o) {\n        if (this.getName() == null) {\n            return -1;\n        }\n        if (o.getName() == null) {\n            return 1;\n        }\n        if (this.getName().equals(o.getName())) {\n            return this.getGroupId().compareTo(o.getGroupId()); // To display duplicates\n        }\n        return this.getName().compareTo(o.getName());\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        Group group = (Group) o;\n\n        return groupId.equals(group.groupId);\n\n    }\n\n    @Override\n    public int hashCode() {\n        return groupId.hashCode();\n    }\n\n    @Override\n    public String toString() {\n        return \"Group{\" +\n                \"groupId='\" + groupId + '\\'' +\n                \", publicGroup=\" + publicGroup +\n                \", archivedGroup=\" + archivedGroup +\n                \", name='\" + name + '\\'' +\n                \", domain='\" + domain + '\\'' +\n                \", counter=\" + counter +\n                \", member=\" + member +\n                \", administrator=\" + administrator +\n                '}';\n    }\n\n    @Override\n    public Object clone() {\n        Group clone = null;\n        try {\n            clone = (Group) super.clone();\n        } catch (CloneNotSupportedException cnse) {\n            cnse.printStackTrace(System.err);\n        }\n        return clone;\n    }\n\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/domain/User.java",
    "content": "package fr.ippon.tatami.domain;\n\nimport com.fasterxml.jackson.annotation.JsonIgnore;\nimport fr.ippon.tatami.domain.validation.ContraintsUserCreation;\nimport org.hibernate.validator.constraints.Email;\nimport org.hibernate.validator.constraints.NotEmpty;\n\nimport javax.persistence.Column;\nimport javax.persistence.Entity;\nimport javax.persistence.Id;\nimport javax.persistence.Table;\nimport javax.validation.constraints.NotNull;\nimport javax.validation.constraints.Size;\nimport javax.validation.groups.Default;\nimport java.io.Serializable;\n\n/**\n * A user.\n *\n * @author Julien Dubois\n */\n@Entity\n@Table(name = \"User\")\npublic class User implements Serializable {\n\n    @NotEmpty(message = \"Login is mandatory.\", groups = {ContraintsUserCreation.class, Default.class})\n    @NotNull(message = \"Login is mandatory.\", groups = {ContraintsUserCreation.class, Default.class})\n    @Email(message = \"Email is invalid.\")\n    @Id\n    @JsonIgnore\n    private String login;\n\n    @Column(name = \"password\")\n    @JsonIgnore\n    private String password;\n\n    @Column(name = \"username\")\n    private String username;\n\n    @Column(name = \"domain\")\n    @JsonIgnore\n    private String domain;\n\n    @Column(name = \"avatar\")\n    private String avatar;\n\n    @Size(min = 0, max = 50)\n    @Column(name = \"firstName\")\n    private String firstName;\n\n    @Size(min = 0, max = 50)\n    @Column(name = \"lastName\")\n    private String lastName;\n\n    @Size(min = 0, max = 100)\n    @Column(name = \"jobTitle\")\n    private String jobTitle;\n\n    @Size(min = 0, max = 20)\n    @Column(name = \"phoneNumber\")\n    private String phoneNumber;\n\n    @Column(name = \"openIdUrl\")\n    @JsonIgnore\n    private String openIdUrl;\n\n    @Column(name = \"preferences_mention_email\")\n    @JsonIgnore\n    private Boolean preferencesMentionEmail;\n\n    @Column(name = \"rssUid\")\n    @JsonIgnore\n    private String rssUid;\n\n    @Column(name = \"weekly_digest_subscription\")\n    @JsonIgnore\n    private Boolean weeklyDigestSubscription;\n\n    @Column(name = \"daily_digest_subscription\")\n    @JsonIgnore\n    private Boolean dailyDigestSubscription;\n\n    @Column(name = \"attachmentsSize\")\n    private long attachmentsSize;\n\n    @Column(name=\"activated\")\n    private Boolean activated=true;\n\n    private long statusCount;\n\n    private long friendsCount;\n\n    private long followersCount;\n\n    private Boolean isAdmin = false;\n\n    public Boolean getActivated() {\n        return activated;\n    }\n\n    public void setActivated(Boolean activated) {\n        this.activated = activated;\n    }\n\n    public String getLogin() {\n        return login;\n    }\n\n    public void setLogin(String login) {\n        this.login = login;\n    }\n\n    public String getPassword() {\n        return password;\n    }\n\n    public void setPassword(String password) {\n        this.password = password;\n    }\n\n    public String getUsername() {\n        return username;\n    }\n\n    public void setUsername(String username) {\n        this.username = username;\n    }\n\n    public String getDomain() {\n        return domain;\n    }\n\n    public void setDomain(String domain) {\n        this.domain = domain;\n    }\n\n    public String getAvatar() {\n        return avatar;\n    }\n\n    public void setAvatar(String avatar) {\n        this.avatar = avatar;\n    }\n\n    public String getFirstName() {\n        return firstName;\n    }\n\n    public void setFirstName(String firstName) {\n        this.firstName = firstName;\n    }\n\n    public String getLastName() {\n        return lastName;\n    }\n\n    public void setLastName(String lastName) {\n        this.lastName = lastName;\n    }\n\n    public String getJobTitle() {\n        return jobTitle;\n    }\n\n    public void setJobTitle(String jobTitle) {\n        this.jobTitle = jobTitle;\n    }\n\n    public String getPhoneNumber() {\n        return phoneNumber;\n    }\n\n    public void setPhoneNumber(String phoneNumber) {\n        this.phoneNumber = phoneNumber;\n    }\n\n    public String getOpenIdUrl() {\n        return openIdUrl;\n    }\n\n    public void setOpenIdUrl(String openIdUrl) {\n        this.openIdUrl = openIdUrl;\n    }\n\n    public Boolean getPreferencesMentionEmail() {\n        return preferencesMentionEmail;\n    }\n\n    public void setPreferencesMentionEmail(Boolean preferencesMentionEmail) {\n        this.preferencesMentionEmail = preferencesMentionEmail;\n    }\n\n    public long getAttachmentsSize() {\n        return attachmentsSize;\n    }\n\n    public void setAttachmentsSize(long attachmentsSize) {\n        this.attachmentsSize = attachmentsSize < 0 ? 0 : attachmentsSize;\n    }\n\n    public String getRssUid() {\n        return rssUid;\n    }\n\n    public void setRssUid(String rssUid) {\n        this.rssUid = rssUid;\n    }\n\n    public long getStatusCount() {\n        return statusCount;\n    }\n\n    public void setStatusCount(long statusCount) {\n        this.statusCount = statusCount;\n    }\n\n    public long getFriendsCount() {\n        return friendsCount;\n    }\n\n    public void setFriendsCount(long friendsCount) {\n        this.friendsCount = friendsCount;\n    }\n\n    public long getFollowersCount() {\n        return followersCount;\n    }\n\n    public void setFollowersCount(long followersCount) {\n        this.followersCount = followersCount;\n    }\n\n    public Boolean getIsAdmin() { return isAdmin; }\n\n    public void setIsAdmin(boolean isAdmin) { this.isAdmin = isAdmin; }\n\n    public Boolean getWeeklyDigestSubscription() {\n        return weeklyDigestSubscription;\n    }\n\n    public void setWeeklyDigestSubscription(Boolean weeklyDigestSubscription) {\n        this.weeklyDigestSubscription = weeklyDigestSubscription;\n    }\n\n    public Boolean getDailyDigestSubscription() {\n        return dailyDigestSubscription;\n    }\n\n    public void setDailyDigestSubscription(Boolean dailyDigestSubscription) {\n        this.dailyDigestSubscription = dailyDigestSubscription;\n    }\n\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        User user = (User) o;\n\n        return login.equals(user.login);\n\n    }\n\n    @Override\n    public int hashCode() {\n        return login.hashCode();\n    }\n\n    @Override\n    public String toString() {\n        return \"User{\" +\n                \"login='\" + login + '\\'' +\n                \", password='\" + password + '\\'' +\n                \", username='\" + username + '\\'' +\n                \", domain='\" + domain + '\\'' +\n                \", avatar='\" + avatar + '\\'' +\n                \", firstName='\" + firstName + '\\'' +\n                \", lastName='\" + lastName + '\\'' +\n                \", jobTitle='\" + jobTitle + '\\'' +\n                \", phoneNumber='\" + phoneNumber + '\\'' +\n                \", openIdUrl='\" + openIdUrl + '\\'' +\n                \", preferencesMentionEmail=\" + preferencesMentionEmail +\n                \", rssUid=\" + rssUid +\n                \", dailyDigestSubscription=\" + dailyDigestSubscription +\n                \", weeklyDigestSubscription=\" + weeklyDigestSubscription +\n                \", attachmentsSize=\" + attachmentsSize +\n                \", activated=\" + activated +\n                \", statusCount=\" + statusCount +\n                \", friendsCount=\" + friendsCount +\n                \", followersCount=\" + followersCount +\n                '}';\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/domain/UserStatusStat.java",
    "content": "package fr.ippon.tatami.domain;\n\nimport java.io.Serializable;\n\npublic class UserStatusStat implements Comparable<UserStatusStat>, Serializable {\n\n    private String username;\n\n    private Long statusCount;\n\n    public UserStatusStat(String username, Long count) {\n        assert username != null && count != null;\n        this.username = username;\n        this.statusCount = count;\n    }\n\n    public String getUsername() {\n        return username;\n    }\n\n    public void setUsername(String username) {\n        this.username = username;\n    }\n\n    public Long getStatusCount() {\n        return statusCount;\n    }\n\n    public void setStatusCount(Long count) {\n        this.statusCount = count;\n    }\n\n    @Override\n    public int compareTo(UserStatusStat o) {\n        return this.username.compareTo(o.username);\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        UserStatusStat that = (UserStatusStat) o;\n\n        return username.equals(that.username);\n\n    }\n\n    @Override\n    public int hashCode() {\n        return username.hashCode();\n    }\n\n    @Override\n    public String toString() {\n        return \"UserStatusStat{\" +\n                \"username='\" + username + '\\'' +\n                \", statusCount=\" + statusCount +\n                '}';\n    }\n}"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/domain/status/AbstractStatus.java",
    "content": "package fr.ippon.tatami.domain.status;\n\nimport javax.validation.constraints.NotNull;\nimport java.io.Serializable;\nimport java.util.Date;\n\n/**\n * Parent class for all statuses.\n */\npublic abstract class AbstractStatus implements Serializable {\n\n    private String statusId;\n\n    @NotNull\n    private StatusType type;\n\n    @NotNull\n    private String login;\n\n    @NotNull\n    private String username;\n\n    @NotNull\n    private String domain;\n\n    private Date statusDate;\n\n    public String getGeoLocalization() {\n        return geoLocalization;\n    }\n\n    public void setGeoLocalization(String geoLocalization) {\n        this.geoLocalization = geoLocalization;\n    }\n\n    private String geoLocalization;\n\n    private boolean removed;\n\n    public String getStatusId() {\n        return statusId;\n    }\n\n    public void setStatusId(String statusId) {\n        this.statusId = statusId;\n    }\n\n    public StatusType getType() {\n        return type;\n    }\n\n    public void setType(StatusType type) {\n        this.type = type;\n    }\n\n    public String getLogin() {\n        return login;\n    }\n\n    public void setLogin(String login) {\n        this.login = login;\n    }\n\n    public String getUsername() {\n        return username;\n    }\n\n    public void setUsername(String username) {\n        this.username = username;\n    }\n\n    public String getDomain() {\n        return domain;\n    }\n\n    public void setDomain(String domain) {\n        this.domain = domain;\n    }\n\n    public Date getStatusDate() {\n        return statusDate;\n    }\n\n    public void setStatusDate(Date statusDate) {\n        this.statusDate = statusDate;\n    }\n\n    public boolean isRemoved() {\n        return removed;\n    }\n\n    public void setRemoved(boolean removed) {\n        this.removed = removed;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        AbstractStatus that = (AbstractStatus) o;\n\n        if (statusId != null ? !statusId.equals(that.statusId) : that.statusId != null) return false;\n\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        return statusId != null ? statusId.hashCode() : 0;\n    }\n\n    @Override\n    public String toString() {\n        return \"AbstractStatus{\" +\n                \"statusId='\" + statusId + '\\'' +\n                \", type=\" + type +\n                \", login='\" + login + '\\'' +\n                \", username='\" + username + '\\'' +\n                \", domain='\" + domain + '\\'' +\n                \", statusDate=\" + statusDate +\n                \", geoLocalization='\" + geoLocalization + '\\'' +\n                \", removed=\" + removed +\n                '}';\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/domain/status/Announcement.java",
    "content": "package fr.ippon.tatami.domain.status;\n\n/**\n * An announcement.\n */\npublic class Announcement extends Share {\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/domain/status/MentionFriend.java",
    "content": "package fr.ippon.tatami.domain.status;\n\n/**\n * Mention a user that someone started following him.\n */\npublic class MentionFriend extends AbstractStatus {\n\n    private String followerLogin;\n\n    public String getFollowerLogin() {\n        return followerLogin;\n    }\n\n    public void setFollowerLogin(String followerLogin) {\n        this.followerLogin = followerLogin;\n    }\n\n    @Override\n    public String toString() {\n        return \"MentionFriend{\" +\n                \"followerLogin='\" + followerLogin + '\\'' +\n                \"} \" + super.toString();\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/domain/status/MentionShare.java",
    "content": "package fr.ippon.tatami.domain.status;\n\n/**\n * Mention a user that one of his statuses was shared.\n */\npublic class MentionShare extends Share {\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/domain/status/Share.java",
    "content": "package fr.ippon.tatami.domain.status;\n\n/**\n * A status that is shared.\n */\npublic class Share extends AbstractStatus {\n\n    private String originalStatusId;\n\n    public String getOriginalStatusId() {\n        return originalStatusId;\n    }\n\n    public void setOriginalStatusId(String originalStatusId) {\n        this.originalStatusId = originalStatusId;\n    }\n\n    @Override\n    public String toString() {\n        return \"Share{\" +\n                \"originalStatusId='\" + originalStatusId + '\\'' +\n                \"} \" + super.toString();\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/domain/status/Status.java",
    "content": "package fr.ippon.tatami.domain.status;\n\nimport fr.ippon.tatami.domain.Attachment;\nimport org.hibernate.validator.constraints.NotEmpty;\n\nimport javax.validation.constraints.NotNull;\nimport javax.validation.constraints.Size;\nimport java.util.Collection;\n\n/**\n * A status.\n *\n * @author Julien Dubois\n */\npublic class Status extends AbstractStatus {\n\n    private String groupId;\n\n    private Boolean statusPrivate;\n\n    private Boolean hasAttachments;\n\n    private Collection<Attachment> attachments;\n\n    @NotNull\n    @NotEmpty(message = \"Content field is mandatory.\")\n    @Size(min = 1, max = 2048)\n    private String content;\n\n    /**\n     * If this status is a reply, the statusId of the original status.\n     */\n    private String discussionId;\n\n    /**\n     * If this status is a reply, the statusId of the status that is being replied to.\n     */\n    private String replyTo;\n\n    /**\n     * If this status is a reply, the username of the status that is being replied to.\n     */\n    private String replyToUsername;\n\n    private boolean detailsAvailable;\n\n    private Boolean removed;\n\n    public String getGroupId() {\n        return groupId;\n    }\n\n    public void setGroupId(String groupId) {\n        this.groupId = groupId;\n    }\n\n    public Boolean getStatusPrivate() {\n        return statusPrivate;\n    }\n\n    public void setStatusPrivate(Boolean statusPrivate) {\n        this.statusPrivate = statusPrivate;\n    }\n\n    public Boolean getHasAttachments() {\n        return hasAttachments;\n    }\n\n    public void setHasAttachments(Boolean hasAttachments) {\n        this.hasAttachments = hasAttachments;\n    }\n\n    public Collection<Attachment> getAttachments() {\n        return attachments;\n    }\n\n    public void setAttachments(Collection<Attachment> attachments) {\n        this.attachments = attachments;\n    }\n\n    public String getContent() {\n        return content;\n    }\n\n    public void setContent(String content) {\n        this.content = content;\n    }\n\n    public String getDiscussionId() {\n        return discussionId;\n    }\n\n    public void setDiscussionId(String discussionId) {\n        this.discussionId = discussionId;\n    }\n\n    public String getReplyTo() {\n        return replyTo;\n    }\n\n    public void setReplyTo(String replyTo) {\n        this.replyTo = replyTo;\n    }\n\n    public String getReplyToUsername() {\n        return replyToUsername;\n    }\n\n    public void setReplyToUsername(String replyToUsername) {\n        this.replyToUsername = replyToUsername;\n    }\n\n    public boolean isDetailsAvailable() {\n        return detailsAvailable;\n    }\n\n    public void setDetailsAvailable(boolean detailsAvailable) {\n        this.detailsAvailable = detailsAvailable;\n    }\n\n    public Boolean getRemoved() {\n        return removed;\n    }\n\n    public void setRemoved(Boolean removed) {\n        this.removed = removed;\n    }\n\n    @Override\n    public String toString() {\n        return \"Status{\" +\n                \"groupId='\" + groupId + '\\'' +\n                \", statusPrivate=\" + statusPrivate +\n                \", hasAttachments=\" + hasAttachments +\n                \", attachments=\" + attachments +\n                \", content='\" + content + '\\'' +\n                \", discussionId='\" + discussionId + '\\'' +\n                \", replyTo='\" + replyTo + '\\'' +\n                \", replyToUsername='\" + replyToUsername + '\\'' +\n                \", detailsAvailable=\" + detailsAvailable +\n                \", removed=\" + removed +\n                '}';\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/domain/status/StatusDetails.java",
    "content": "package fr.ippon.tatami.domain.status;\n\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.service.dto.StatusDTO;\n\nimport java.io.Serializable;\nimport java.util.Collection;\n\n/**\n * Extended information for a status.\n * - Lists the discussion related to this status\n * - Lists the users who shared this status\n */\npublic class StatusDetails implements Serializable {\n\n    private String statusId;\n\n    private Collection<StatusDTO> discussionStatuses;\n\n    private Collection<User> sharedByLogins;\n\n    public String getStatusId() {\n        return statusId;\n    }\n\n    public void setStatusId(String statusId) {\n        this.statusId = statusId;\n    }\n\n    public Collection<StatusDTO> getDiscussionStatuses() {\n        return discussionStatuses;\n    }\n\n    public void setDiscussionStatuses(Collection<StatusDTO> discussionStatuses) {\n        this.discussionStatuses = discussionStatuses;\n    }\n\n    public Collection<User> getSharedByLogins() {\n        return sharedByLogins;\n    }\n\n    public void setSharedByLogins(Collection<User> sharedByLogins) {\n        this.sharedByLogins = sharedByLogins;\n    }\n\n    @Override\n    public String toString() {\n        return \"StatusDetails{\" +\n                \"StatusId='\" + statusId + '\\'' +\n                \", discussionStatuses=\" + discussionStatuses +\n                \", sharedByLogins=\" + sharedByLogins +\n                '}';\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/domain/status/StatusType.java",
    "content": "package fr.ippon.tatami.domain.status;\n\npublic enum StatusType {\n    STATUS,\n    SHARE,\n    ANNOUNCEMENT,\n    MENTION_FRIEND,\n    MENTION_SHARE\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/domain/validation/ContraintsAttachmentCreation.java",
    "content": "package fr.ippon.tatami.domain.validation;\n\npublic interface ContraintsAttachmentCreation {\n\n}"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/domain/validation/ContraintsUserCreation.java",
    "content": "package fr.ippon.tatami.domain.validation;\n\n/**\n * Bean Validation group used to validate the creation of a user.\n *\n * @author Julien Dubois\n */\npublic interface ContraintsUserCreation {\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/AppleDeviceRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.Collection;\n\npublic interface AppleDeviceRepository {\n\n    void createAppleDevice(String login, String deviceId);\n\n    void removeAppleDevice(String login, String deviceId);\n\n    Collection<String> findAppleDevices(String login);\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/AppleDeviceUserRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\npublic interface AppleDeviceUserRepository {\n\n    void createAppleDeviceForUser(String deviceId, String login);\n\n    void removeAppleDeviceForUser(String deviceId);\n\n    String findLoginForDeviceId(String deviceId);\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/AttachmentRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.domain.Attachment;\n\npublic interface AttachmentRepository {\n\n    void createAttachment(Attachment attach);\n\n    void deleteAttachment(Attachment attach);\n\n    /**\n     * Finds an attachment, including its content (the file data).\n     */\n    Attachment findAttachmentById(String attachmentId);\n\n    /**\n     * Only fetch the attachment metadata : file name & size, but not its content.\n     */\n    Attachment findAttachmentMetadataById(String attachmentId);\n    \n    /**\n     * Update the thumbnail of the given attachment\n     */\n    Attachment updateThumbnail(Attachment attach);\n}"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/AvatarRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.domain.Avatar;\n\npublic interface AvatarRepository {\n\n    void createAvatar(Avatar avatar);\n\n    void removeAvatar(String avatarId);\n\n    Avatar findAvatarById(String avatarId);\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/BlockRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.domain.User;\n\nimport java.util.Collection;\n\n/**\n *This repository stores the the relationships blockingUser-blockedUser.\n * Similar strucure as the FriendRepository.\n */\npublic interface BlockRepository {\n\n    void blockUser(String currentUserLogin, String blockedUserLogin);\n\n    void unblockUser(String currentUserLogin, String unblockedUserLogin);\n\n    Collection<String> getUsersBlockedBy(String userLogin);\n\n    boolean isBlocked(String blockingLogin, String blockedLogin);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/CounterRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\n/**\n * The Counter Repository.\n *\n * @author Julien Dubois\n */\npublic interface CounterRepository {\n\n    void incrementFollowersCounter(String login);\n\n    void incrementFriendsCounter(String login);\n\n    void incrementStatusCounter(String login);\n\n    void decrementFollowersCounter(String login);\n\n    void decrementFriendsCounter(String login);\n\n    void decrementStatusCounter(String login);\n\n    long getFollowersCounter(String login);\n\n    long getFriendsCounter(String login);\n\n    long getStatusCounter(String login);\n\n    void createFollowersCounter(String login);\n\n    void createFriendsCounter(String login);\n\n    void createStatusCounter(String login);\n\n    void deleteCounters(String login);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/DaylineRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.domain.UserStatusStat;\nimport fr.ippon.tatami.domain.status.Status;\n\nimport java.util.Collection;\n\n/**\n * The Dayline Repository, which stores statistics per day.\n *\n * @author Julien Dubois\n */\npublic interface DaylineRepository {\n\n    /**\n     * Add a status to the repository.\n     */\n    void addStatusToDayline(Status status, String day);\n\n    /**\n     * Get the statistics for one day, in the form &lt;username, number of status updates&gt;.\n     */\n    Collection<UserStatusStat> getDayline(String domain, String day);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/DiscussionRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.Collection;\n\n/**\n * The StatusDetails Repository.\n *\n * @author Julien Dubois\n */\npublic interface DiscussionRepository {\n\n    void addReplyToDiscussion(String originalStatusId, String replyStatusId);\n\n    Collection<String> findStatusIdsInDiscussion(String originalStatusId);\n\n    boolean hasReply(String statusId);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/DomainConfigurationRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.domain.DomainConfiguration;\n\n/**\n * The DomainConfiguraiton Repository.\n *\n * @author Julien Dubois\n */\npublic interface DomainConfigurationRepository {\n\n    void updateDomainConfiguration(DomainConfiguration domainConfiguration);\n\n    DomainConfiguration findDomainConfigurationByDomain(String domain);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/DomainRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.domain.Domain;\n\nimport java.util.List;\nimport java.util.Set;\n\n/**\n * The Domain Repository.\n *\n * @author Julien Dubois\n */\npublic interface DomainRepository {\n\n    void addUserInDomain(String domain, String login);\n\n    void updateUserInDomain(String domain, String login);\n\n    void deleteUserInDomain(String domain, String login);\n\n    List<String> getLoginsInDomain(String domain, int pagination);\n\n    List<String> getLoginsInDomain(String domain);\n\n    Set<Domain> getAllDomains();\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/DomainlineRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * The Domainline Repository.\n *\n * @author Julien Dubois\n */\npublic interface DomainlineRepository {\n\n    /**\n     * Add a status to the Domain line.\n     */\n    void addStatusToDomainline(String domain, String statusId);\n\n    /**\n     * Remove a collection of statuses from the Domain line.\n     */\n    void removeStatusFromDomainline(String domain, Collection<String> statusIdsToDelete);\n\n    /**\n     * The Domainline : the public status for a domain.\n     * - The name is the statusId of the statuses\n     * - Value is always null\n     */\n    List<String> getDomainline(String domain, int size, String start, String finish);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/FavoritelineRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.List;\n\n/**\n * The Favoriteline Repository.\n *\n * @author Julien Dubois\n */\npublic interface FavoritelineRepository {\n\n    void addStatusToFavoriteline(String login, String statusId);\n\n    void removeStatusFromFavoriteline(String login, String statusId);\n\n    void deleteFavoriteline(String login);\n\n    /**\n     * The favoriteline : the statuses fovorited by the user.\n     * - The key is the statusId of the statuses\n     * - The value is always null\n     */\n    List<String> getFavoriteline(String login);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/FollowerRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.Collection;\n\n/**\n * The Follower Repository.\n *\n * @author Julien Dubois\n */\npublic interface FollowerRepository {\n\n    void addFollower(String login, String followerLogin);\n\n    void removeFollower(String login, String followerLogin);\n\n    Collection<String> findFollowersForUser(String login);\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/FriendRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.List;\n\n/**\n * The Friend Repository.\n *\n * @author Julien Dubois\n */\npublic interface FriendRepository {\n\n    void addFriend(String login, String friendLogin);\n\n    void removeFriend(String login, String friendLogin);\n\n    List<String> findFriendsForUser(String login);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/GroupCounterRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\n/**\n * The Group Counter Repository.\n *\n * @author Julien Dubois\n */\npublic interface GroupCounterRepository {\n\n    long getGroupCounter(String domain, String groupId);\n\n    void incrementGroupCounter(String domain, String groupId);\n\n    void decrementGroupCounter(String domain, String groupId);\n\n    void deleteGroupCounter(String domain, String groupId);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/GroupDetailsRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.domain.Group;\n\n/**\n * The Group Details Repository.\n *\n * @author Julien Dubois\n */\npublic interface GroupDetailsRepository {\n\n    void createGroupDetails(String groupId, String name, String description, boolean publicGroup);\n\n    Group getGroupDetails(String groupId);\n\n    void editGroupDetails(String groupId, String name, String description, boolean archivedGroup);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/GroupMembersRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.Map;\n\n/**\n * The Group members Repository.\n *\n * @author Julien Dubois\n */\npublic interface GroupMembersRepository {\n\n    void addMember(String groupId, String login);\n\n    void addAdmin(String groupId, String login);\n\n    void removeMember(String groupId, String login);\n\n    Map<String, String> findMembers(String groupId);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/GroupRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.domain.Group;\n\n/**\n * The Group Repository.\n *\n * @author Julien Dubois\n */\npublic interface GroupRepository {\n\n    String createGroup(String domain);\n\n    Group getGroupById(String domain, String groupId);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/GrouplineRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * The Groupline Repository.\n *\n * @author Julien Dubois\n */\npublic interface GrouplineRepository {\n\n    /**\n     * Add a status to the Group line.\n     */\n    void addStatusToGroupline(String groupId, String statusId);\n\n    /**\n     * Remove a collection of statuses from the Group line.\n     */\n    void removeStatusesFromGroupline(String groupId, Collection<String> statusIdsToDelete);\n\n    /**\n     * The Groupline : the statuses for a given group.\n     * - The name is the statusId of the statuses\n     * - Value is always null\n     */\n    List<String> getGroupline(String groupId, int size, String start, String finish);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/IdempotentRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\n/**\n * Used to de-deplucate Camel messages.\n */\npublic interface IdempotentRepository extends org.apache.camel.spi.IdempotentRepository<String> {\n\n    @Override\n    boolean add(String key);\n\n    @Override\n    boolean contains(String key);\n\n    @Override\n    boolean remove(String key);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/MailDigestRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.domain.DigestType;\n\nimport java.util.List;\n\n/**\n * Provide access to digest subscription info.\n * <p/>\n * Subscription are organized by digest type and domain (in order to allow\n * domain-level configuration).\n *\n * @author Pierre Rust\n */\npublic interface MailDigestRepository {\n\n    /**\n     * Subscribe an user to email digest.\n     */\n    void subscribeToDigest(DigestType digestType, String login, String domain, String day);\n\n    /**\n     * Un-subscribe an user from a domain.\n     */\n    void unsubscribeFromDigest(DigestType digestType, String login, String domain, String day);\n\n    /**\n     * Retrieves the list of logins in a domain subscribed to a given digest type.\n     */\n    List<String> getLoginsRegisteredToDigest(DigestType digestType, String domain, String day, int pagination);\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/MentionlineRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * The Mentionline Repository.\n *\n * @author Julien Dubois\n */\npublic interface MentionlineRepository {\n\n    /**\n     * Add a status to the Mention line.\n     */\n    void addStatusToMentionline(String mentionedLogin, String statusId);\n\n    /**\n     * Remove a collection of statuses from the Mention line.\n     */\n    void removeStatusesFromMentionline(String mentionedLogin, Collection<String> statusIdsToDelete);\n\n    /**\n     * The mention line : the mentions for a given user.\n     * - The name is the statusId of the statuses\n     * - Value is always null\n     */\n    List<String> getMentionline(String login, int size, String start, String finish);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/RegistrationRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.Map;\n\n/**\n * The Registration Repository.\n *\n * @author Julien Dubois\n */\npublic interface RegistrationRepository {\n\n    String generateRegistrationKey(String login);\n\n    String getLoginByRegistrationKey(String registrationKey);\n\n    /**\n     * !! For testing purpose only !!\n     */\n    Map<String, String> _getAllRegistrationKeyByLogin();\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/ResolvedReportRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.Collection;\n\n/**\n * Created by emilyklein on 7/13/16.\n */\npublic interface ResolvedReportRepository {\n\n    void resolvedReport (String reportingUser, String reportedStatusId, Long timeReported, String adminResolved, String actionTaken);\n\n    Collection<String> findResolvedReportsById(String statusId);\n\n    boolean hasBeenResolved(String statusId);\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/RssUidRepository.java",
    "content": "package fr.ippon.tatami.repository;\r\n\r\n/**\r\n * The Rss Uid Repository.\r\n * </p>\r\n * The RSS uid is used to build an anonymous url to a RSS channel\r\n * representing an user timeline.\r\n *\r\n * @author Pierre Rust\r\n */\r\npublic interface RssUidRepository {\r\n\r\n    String generateRssUid(String login);\r\n\r\n    void removeRssUid(String rssUid);\r\n\r\n    String getLoginByRssUid(String rssUid);\r\n}\r\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/SharesRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.Collection;\n\n/**\n * The StatusDetails Repository.\n *\n * @author Julien Dubois\n */\npublic interface SharesRepository {\n\n    void newShareByLogin(String statusId, String sharedByLogin);\n\n    Collection<String> findLoginsWhoSharedAStatus(String statusId);\n\n    boolean hasBeenShared(String statusId);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/StatusAttachmentRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.Collection;\n\n/**\n * Stores attachment IDs for a status.\n */\npublic interface StatusAttachmentRepository {\n\n    void addAttachmentId(String statusId, String attachmentId);\n\n    void removeAttachmentId(String statusId, String attachmentId);\n\n    Collection<String> findAttachmentIds(String statusId);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/StatusReportRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.Collection;\nimport java.util.List;\n\npublic interface StatusReportRepository {\n\n    void reportStatus (String domain,  String reportedStatusId, String reportingLogin);\n\n    void unreportStatus (String domain,  String reportedStatusId);\n\n    List<String> findReportedStatuses(String domain);\n\n    String findUserHavingReported(String domain, String statusId);\n\n    boolean hasBeenReportedByUser(String domain, String reportedStatusId, String login);\n\n}"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/StatusRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.domain.status.*;\n\nimport javax.validation.ConstraintViolationException;\nimport java.util.Collection;\n\n/**\n * The Status Repository.\n *\n * @author Julien Dubois\n */\npublic interface StatusRepository {\n\n    Status createStatus(String login,\n                        boolean statusPrivate,\n                        Group group,\n                        Collection<String> attachmentIds,\n                        String content,\n                        String discussionId,\n                        String replyTo,\n                        String replyToUsername,\n                        String geoLocalization) throws ConstraintViolationException;\n\n    Share createShare(String login,\n                      String originalStatusId);\n\n    Announcement createAnnouncement(String login,\n                                    String originalStatusId);\n\n    MentionFriend createMentionFriend(String login,\n                                      String followerLogin);\n\n    MentionShare createMentionShare(String login,\n                                    String originalStatusId);\n\n    void removeStatus(AbstractStatus status);\n\n    /**\n     * Retrieve a persisted status.\n     *\n     * @return null if status was removed\n     */\n    AbstractStatus findStatusById(String statusId);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/TagCounterRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\n/**\n * The Tag Counter Repository.\n *\n * @author Julien Dubois\n */\npublic interface TagCounterRepository {\n\n    long getTagCounter(String domain, String tag);\n\n    void incrementTagCounter(String domain, String tag);\n\n    void decrementTagCounter(String domain, String tag);\n\n    void deleteTagCounter(String domain, String tag);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/TagFollowerRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.Collection;\n\n/**\n * Specific Follower repository for tags.\n */\npublic interface TagFollowerRepository {\n\n    void addFollower(String domain, String tag, String login);\n\n    void removeFollower(String domain, String tag, String login);\n\n    Collection<String> findFollowers(String domain, String tag);\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/TaglineRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.domain.status.Status;\n\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * The Tagline Repository.\n *\n * @author Julien Dubois\n */\npublic interface TaglineRepository {\n\n    /**\n     * Add a status to the Tag line.\n     */\n    void addStatusToTagline(String tag, Status status);\n\n    /**\n     * Remove a collection of statuses from the Tag line.\n     */\n    void removeStatusesFromTagline(String tag, String domain, Collection<String> statusIdsToDelete);\n\n    /**\n     * The tagline : the statuses for a given tag.\n     * - The name is the statusId of the statuses\n     * - Value is always null\n     */\n    List<String> getTagline(String domain, String tag, int size, String start, String finish);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/TimelineRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.domain.status.Announcement;\nimport fr.ippon.tatami.domain.status.Share;\n\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * The Timeline Repository.\n * <p/>\n * A Timeline is the list of statuses that a user sees, which includes :\n * - The statuses from the people he follows\n * - His own statuses\n * - Statuses that were shared by the people he follows or by himself\n *\n * @author Julien Dubois\n */\npublic interface TimelineRepository {\n\n    boolean isStatusInTimeline(String login, String statusId);\n\n    void addStatusToTimeline(String login, String statusId);\n\n    void removeStatusesFromTimeline(String login, Collection<String> statusIdsToDelete);\n\n    void shareStatusToTimeline(String sharedByLogin, String timelineLogin, Share share);\n\n    void announceStatusToTimeline(String announcedByLogin, List<String> logins, Announcement announcement);\n\n    void deleteTimeline(String login);\n\n    /**\n     * The user timeline : the user's statuses, and statuses from users he follows.\n     * - The key is the statusId of the statuses\n     * - The value is always null\n     */\n    List<String> getTimeline(String login, int size, String start, String finish);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/TrendRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * The Trends repository : stores and retrieves tags trends.\n */\npublic interface TrendRepository {\n\n    void addTag(String domain, String tag);\n\n    List<String> getRecentTags(String domain);\n\n    List<String> getRecentTags(String domain, int maxNumber);\n\n    Collection<String> getDomainTags(String domain);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/UserAttachmentRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.Collection;\n\n/**\n * Stores attachment IDs for a user.\n */\npublic interface UserAttachmentRepository {\n\n    void addAttachmentId(String login, String attachmentId);\n\n    void removeAttachmentId(String login, String attachmentId);\n\n    Collection<String> findAttachmentIds(String login, int pagination, String finish);\n\n    Collection<String> findAttachmentIds(String login);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/UserGroupRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * The User group Repository.\n *\n * @author Julien Dubois\n */\npublic interface UserGroupRepository {\n\n    void addGroupAsMember(String login, String groupId);\n\n    void addGroupAsAdmin(String login, String groupId);\n\n    void removeGroup(String login, String groupId);\n\n    List<String> findGroups(String login);\n\n    Collection<String> findGroupsAsAdmin(String login);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/UserRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.domain.User;\n\nimport javax.validation.ConstraintViolationException;\n\n/**\n * The User Repository.\n *\n * @author Julien Dubois\n */\npublic interface UserRepository {\n\n    void createUser(User user);\n\n    void updateUser(User user) throws ConstraintViolationException, IllegalArgumentException;\n\n    void deleteUser(User user);\n\n    void desactivateUser( User user );\n\n    void reactivateUser( User user );\n\n    User findUserByLogin(String login);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/UserTagRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.Collection;\n\n/**\n * Specific Friend repository for tags.\n */\npublic interface UserTagRepository {\n\n    void addTag(String login, String tag);\n\n    void removeTag(String login, String tag);\n\n    Collection<String> findTags(String login);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/UserTrendRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport java.util.Collection;\nimport java.util.Date;\nimport java.util.List;\n\n/**\n * The User Trends repository : stores user trends.\n */\npublic interface UserTrendRepository {\n\n    void addTag(String login, String tag);\n\n    List<String> getRecentTags(String login);\n\n    Collection<String> getUserRecentTags(String login, Date endDate, int nbRecentTags);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/UserlineRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.domain.status.Share;\n\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * The Userline Repository.\n * <p/>\n * A Userline is the list of statuses updated by a user (including the statuses he shared).\n *\n * @author Julien Dubois\n */\npublic interface UserlineRepository {\n\n    /**\n     * Add a status to the user line.\n     */\n    void addStatusToUserline(String login, String statusId);\n\n    /**\n     * Remove a collection of statuses from the user line.\n     */\n    void removeStatusesFromUserline(String login, Collection<String> statusIdsToDelete);\n\n    void shareStatusToUserline(String currentLogin, Share share);\n\n    void deleteUserline(String login);\n\n    /**\n     * The userline : the user's statuses.\n     * - The key is the statusId of the statuses\n     * - The value is always null\n     */\n    List<String> getUserline(String login, int size, String start, String finish);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/AbstractCassandraFollowerRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.config.Constants;\nimport me.prettyprint.cassandra.serializers.LongSerializer;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.cassandra.service.template.ColumnFamilyResult;\nimport me.prettyprint.cassandra.service.template.ColumnFamilyTemplate;\nimport me.prettyprint.cassandra.service.template.ThriftColumnFamilyTemplate;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\n\nimport javax.annotation.PostConstruct;\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Calendar;\nimport java.util.Collection;\n\n/**\n * Abstract class for managing followers : users who follow another user or a tag.\n */\npublic abstract class AbstractCassandraFollowerRepository {\n\n    private ColumnFamilyTemplate<String, String> template;\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @PostConstruct\n    public void init() {\n        template = new ThriftColumnFamilyTemplate<String, String>(keyspaceOperator,\n                getFollowersCF(),\n                StringSerializer.get(),\n                StringSerializer.get());\n\n        template.setCount(Constants.CASSANDRA_MAX_COLUMNS);\n    }\n\n    void addFollower(String key, String followerKey) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(key, getFollowersCF(), HFactory.createColumn(followerKey,\n                Calendar.getInstance().getTimeInMillis(), StringSerializer.get(), LongSerializer.get()));\n    }\n\n    void removeFollower(String key, String followerKey) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.delete(key, getFollowersCF(), followerKey, StringSerializer.get());\n    }\n\n    Collection<String> findFollowers(String key) {\n        ColumnFamilyResult<String, String> result = template.queryColumns(key);\n        Collection<String> followers = new ArrayList<String>();\n        for (String columnName : result.getColumnNames()) {\n            followers.add(columnName);\n        }\n        return followers;\n    }\n\n    protected abstract String getFollowersCF();\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/AbstractCassandraFriendRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.config.Constants;\nimport me.prettyprint.cassandra.serializers.LongSerializer;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.cassandra.service.template.ColumnFamilyResult;\nimport me.prettyprint.cassandra.service.template.ColumnFamilyTemplate;\nimport me.prettyprint.cassandra.service.template.ThriftColumnFamilyTemplate;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\n\nimport javax.annotation.PostConstruct;\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Calendar;\nimport java.util.List;\n\n/**\n * Abstract class for managing friends : users or tags that a user follows.\n */\npublic abstract class AbstractCassandraFriendRepository {\n\n    private ColumnFamilyTemplate<String, String> friendsTemplate;\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @PostConstruct\n    public void init() {\n        friendsTemplate = new ThriftColumnFamilyTemplate<String, String>(keyspaceOperator,\n                getFriendsCF(),\n                StringSerializer.get(),\n                StringSerializer.get());\n\n        friendsTemplate.setCount(Constants.CASSANDRA_MAX_COLUMNS);\n    }\n\n    void addFriend(String key, String friendKey) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(key, getFriendsCF(), HFactory.createColumn(friendKey,\n                Calendar.getInstance().getTimeInMillis(), StringSerializer.get(), LongSerializer.get()));\n    }\n\n    void removeFriend(String key, String friendKey) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.delete(key, getFriendsCF(), friendKey, StringSerializer.get());\n    }\n\n    List<String> findFriends(String key) {\n        ColumnFamilyResult<String, String> result = friendsTemplate.queryColumns(key);\n        List<String> friends = new ArrayList<String>();\n        for (String columnName : result.getColumnNames()) {\n            friends.add(columnName);\n        }\n        return friends;\n    }\n\n    protected abstract String getFriendsCF();\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/AbstractCassandraLineRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.domain.status.Share;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.cassandra.serializers.UUIDSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.ColumnSlice;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport me.prettyprint.hector.api.query.ColumnQuery;\nimport me.prettyprint.hector.api.query.QueryResult;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.UUID;\n\nimport static me.prettyprint.hector.api.factory.HFactory.createSliceQuery;\n\n/**\n * This abstract class contains commun functions for Timeline and Userline.\n * <p/>\n * Timeline and Userline have the same structure :\n * - Key : login\n * - Name : status Id\n * - Value : \"\"\n *\n * @author Julien Dubois\n */\npublic abstract class AbstractCassandraLineRepository {\n\n    private final Logger log = LoggerFactory.getLogger(AbstractCassandraLineRepository.class);\n\n    @Inject\n    protected Keyspace keyspaceOperator;\n\n    /**\n     * Add a status to the CF.\n     */\n    protected void addStatus(String key, String cf, String statusId) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(key, cf, HFactory.createColumn(UUID.fromString(statusId),\n                \"\", UUIDSerializer.get(), StringSerializer.get()));\n    }\n\n    /**\n     * Add a status with a time-to-live.\n     */\n    protected void addStatus(String key, String cf, String statusId, int ttl) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(key, cf, HFactory.createColumn(UUID.fromString(statusId),\n                \"\", ttl, UUIDSerializer.get(), StringSerializer.get()));\n    }\n\n    /**\n     * Remove a collection of statuses.\n     */\n    protected void removeStatuses(String key, String cf, Collection<String> statusIdsToDelete) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        for (String statusId : statusIdsToDelete) {\n            mutator.addDeletion(key, cf, UUID.fromString(statusId), UUIDSerializer.get());\n        }\n        mutator.execute();\n    }\n\n    List<String> getLineFromCF(String cf, String login, int size, String start, String finish) {\n        List<HColumn<UUID, String>> result;\n        if (finish != null) {\n            ColumnSlice<UUID, String> query = createSliceQuery(keyspaceOperator,\n                    StringSerializer.get(), UUIDSerializer.get(), StringSerializer.get())\n                    .setColumnFamily(cf)\n                    .setKey(login)\n                    .setRange(UUID.fromString(finish), null, true, size)\n                    .execute()\n                    .get();\n\n            result = query.getColumns().subList(1, query.getColumns().size());\n        } else if (start != null) {\n            ColumnSlice<UUID, String> query = createSliceQuery(keyspaceOperator,\n                    StringSerializer.get(), UUIDSerializer.get(), StringSerializer.get())\n                    .setColumnFamily(cf)\n                    .setKey(login)\n                    .setRange(null, UUID.fromString(start), true, size)\n                    .execute()\n                    .get();\n\n            int maxIndex = query.getColumns().size() - 1;\n            if (maxIndex < 0) {\n                maxIndex = 0;\n            }\n            result = query.getColumns().subList(0, maxIndex);\n        } else {\n            ColumnSlice<UUID, String> query = createSliceQuery(keyspaceOperator,\n                    StringSerializer.get(), UUIDSerializer.get(), StringSerializer.get())\n                    .setColumnFamily(cf)\n                    .setKey(login)\n                    .setRange(null, null, true, size)\n                    .execute()\n                    .get();\n\n            result = query.getColumns();\n        }\n\n        List<String> line = new ArrayList<String>();\n        for (HColumn<UUID, String> column : result) {\n            line.add(column.getName().toString());\n        }\n        return line;\n    }\n\n    void shareStatus(String login,\n                     Share share,\n                     String columnFamily,\n                     String sharesColumnFamily) {\n\n        QueryResult<HColumn<UUID, String>> isStatusAlreadyinTimeline =\n                findByLoginAndStatusId(columnFamily, login, UUID.fromString(share.getOriginalStatusId()));\n\n        if (isStatusAlreadyinTimeline.get() == null) {\n            QueryResult<HColumn<UUID, String>> isStatusAlreadyShared =\n                    findByLoginAndStatusId(sharesColumnFamily, login, UUID.fromString(share.getOriginalStatusId()));\n\n            if (isStatusAlreadyShared.get() == null) {\n                Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n\n                mutator.insert(login, columnFamily, HFactory.createColumn(UUID.fromString(share.getStatusId()),\n                        \"\", UUIDSerializer.get(), StringSerializer.get()));\n\n                mutator.insert(login, sharesColumnFamily, HFactory.createColumn(UUID.fromString(share.getOriginalStatusId()),\n                        \"\", UUIDSerializer.get(), StringSerializer.get()));\n            } else {\n\n                log.debug(\"Shared status {} is already shared in {}\", share.getOriginalStatusId(), columnFamily);\n\n            }\n        } else {\n\n            log.debug(\"Shared status {} is already present in {}\", share.getOriginalStatusId(), columnFamily);\n\n        }\n    }\n\n    QueryResult<HColumn<UUID, String>> findByLoginAndStatusId(String columnFamily, String login, UUID statusId) {\n        ColumnQuery<String, UUID, String> columnQuery =\n                HFactory.createColumnQuery(keyspaceOperator, StringSerializer.get(),\n                        UUIDSerializer.get(), StringSerializer.get());\n\n        columnQuery.setColumnFamily(columnFamily).setKey(login).setName(statusId);\n        return columnQuery.execute();\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraAppleDeviceRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.repository.AppleDeviceRepository;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.ColumnSlice;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Repository;\nimport fr.ippon.tatami.config.ColumnFamilyKeys;\n\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Collection;\n\nimport static me.prettyprint.hector.api.factory.HFactory.createSliceQuery;\n\n/**\n * Cassandra implementation of the AppleDevice repository.\n * <p/>\n * Maps users to Apple device ids.\n * <p/>\n * Structure :\n * - Key = login\n * - Name = apple device id\n * - Value = \"\"\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraAppleDeviceRepository implements AppleDeviceRepository {\n\n    private final Logger log = LoggerFactory.getLogger(CassandraAppleDeviceRepository.class);\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    public void createAppleDevice(String login, String deviceId) {\n        log.debug(\"Creating Apple Device for user {} : {}\", login, deviceId);\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(login, ColumnFamilyKeys.APPLE_DEVICE_CF, HFactory.createColumn(deviceId,\n                \"\", StringSerializer.get(), StringSerializer.get()));\n    }\n\n    @Override\n    public void removeAppleDevice(String login, String deviceId) {\n        log.debug(\"Deleting Apple Device for user {} : {}\", login, deviceId);\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.delete(login, ColumnFamilyKeys.APPLE_DEVICE_CF, deviceId, StringSerializer.get());\n    }\n\n    @Override\n    public Collection<String> findAppleDevices(String login) {\n        Collection<String> deviceIds = new ArrayList<String>();\n        ColumnSlice<String, String> result = createSliceQuery(keyspaceOperator,\n                StringSerializer.get(), StringSerializer.get(), StringSerializer.get())\n                .setColumnFamily(ColumnFamilyKeys.APPLE_DEVICE_CF)\n                .setKey(login)\n                .setRange(null, null, false, Integer.MAX_VALUE)\n                .execute()\n                .get();\n\n        for (HColumn<String, String> column : result.getColumns()) {\n            deviceIds.add(column.getName());\n        }\n        return deviceIds;\n    }\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraAppleDeviceUserRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.repository.AppleDeviceUserRepository;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport me.prettyprint.hector.api.query.ColumnQuery;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Repository;\n\nimport javax.inject.Inject;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.APPLE_DEVICE_USER_CF;\n\n/**\n * Cassandra implementation of the AppleDeviceUser repository.\n * <p/>\n * Maps Apple device ids to users.\n * <p/>\n * Structure :\n * - Key = apple device id\n * - Name = USER_LOGIN\n * - Value = user login\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraAppleDeviceUserRepository implements AppleDeviceUserRepository {\n\n    private final Logger log = LoggerFactory.getLogger(CassandraAppleDeviceUserRepository.class);\n\n    private static final String USER_LOGIN = \"USER_LOGIN\";\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    public void createAppleDeviceForUser(String deviceId, String login) {\n        log.debug(\"Mapping Apple device id to user {} : {}\", deviceId, login);\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(deviceId, APPLE_DEVICE_USER_CF, HFactory.createColumn(USER_LOGIN,\n                login, StringSerializer.get(), StringSerializer.get()));\n    }\n\n    @Override\n    public void removeAppleDeviceForUser(String deviceId) {\n        log.debug(\"Removing mapping of Apple device id {}\", deviceId);\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.addDeletion(deviceId, APPLE_DEVICE_USER_CF);\n        mutator.execute();\n    }\n\n    @Override\n    public String findLoginForDeviceId(String deviceId) {\n        log.debug(\"Finding user of Apple device id {}\", deviceId);\n        ColumnQuery<String, String, String> query = HFactory.createStringColumnQuery(keyspaceOperator);\n        HColumn<String, String> column =\n                query.setColumnFamily(APPLE_DEVICE_USER_CF)\n                        .setKey(deviceId)\n                        .setName(USER_LOGIN)\n                        .execute()\n                        .get();\n\n        if (column != null) {\n            return column.getValue();\n        } else {\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraAttachmentRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.domain.Attachment;\nimport fr.ippon.tatami.repository.AttachmentRepository;\nimport me.prettyprint.cassandra.serializers.BytesArraySerializer;\nimport me.prettyprint.cassandra.serializers.DateSerializer;\nimport me.prettyprint.cassandra.serializers.LongSerializer;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.cassandra.utils.TimeUUIDUtils;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport me.prettyprint.hector.api.query.ColumnQuery;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.cache.annotation.CacheEvict;\nimport org.springframework.cache.annotation.Cacheable;\nimport org.springframework.stereotype.Repository;\n\nimport javax.inject.Inject;\n\nimport java.util.Date;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.ATTACHMENT_CF;\n\n@Repository\npublic class CassandraAttachmentRepository implements AttachmentRepository {\n\n    private final Logger log = LoggerFactory.getLogger(CassandraAttachmentRepository.class);\n\n    private final String CONTENT = \"content\";\n    private final String THUMBNAIL = \"thumbnail\";\n    private final String FILENAME = \"filename\";\n    private final String SIZE = \"size\";\n    private final String CREATION_DATE = \"creation_date\";\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    public void createAttachment(Attachment attachment) {\n\n        String attachmentId = TimeUUIDUtils.getUniqueTimeUUIDinMillis().toString();\n        log.debug(\"Creating attachment : {}\", attachment);\n\n        attachment.setAttachmentId(attachmentId);\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n\n        mutator.insert(attachmentId, ATTACHMENT_CF, HFactory.createColumn(CONTENT,\n                attachment.getContent(), StringSerializer.get(), BytesArraySerializer.get()));\n\n        mutator.insert(attachmentId, ATTACHMENT_CF, HFactory.createColumn(THUMBNAIL,\n        \t\tattachment.getThumbnail(), StringSerializer.get(), BytesArraySerializer.get()));\n        \n        mutator.insert(attachmentId, ATTACHMENT_CF, HFactory.createColumn(FILENAME,\n                attachment.getFilename(), StringSerializer.get(), StringSerializer.get()));\n\n        mutator.insert(attachmentId, ATTACHMENT_CF, HFactory.createColumn(SIZE,\n                attachment.getSize(), StringSerializer.get(), LongSerializer.get()));\n\n        mutator.insert(attachmentId, ATTACHMENT_CF, HFactory.createColumn(CREATION_DATE,\n                attachment.getCreationDate(), StringSerializer.get(), DateSerializer.get()));\n\n    }\n\n    @Override\n    @CacheEvict(value = \"attachment-cache\", key = \"#attachment.attachmentId\")\n    public void deleteAttachment(Attachment attachment) {\n        log.debug(\"Deleting attachment : {}\", attachment);\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.addDeletion(attachment.getAttachmentId(), ATTACHMENT_CF);\n        mutator.execute();\n    }\n\n    @Override\n    @Cacheable(\"attachment-cache\")\n    public Attachment findAttachmentById(String attachmentId) {\n        if (attachmentId == null) {\n            return null;\n        }\n\n        log.debug(\"Finding attachment : {}\", attachmentId);\n\n        Attachment attachment = this.findAttachmentMetadataById(attachmentId);\n\n        if (attachment == null) {\n            return null;\n        }\n\n        ColumnQuery<String, String, byte[]> queryAttachment = HFactory.createColumnQuery(keyspaceOperator,\n                StringSerializer.get(), StringSerializer.get(), BytesArraySerializer.get());\n\n        HColumn<String, byte[]> columnAttachment =\n                queryAttachment.setColumnFamily(ATTACHMENT_CF)\n                        .setKey(attachmentId)\n                        .setName(CONTENT)\n                        .execute()\n                        .get();\n\n        attachment.setContent(columnAttachment.getValue());\n        \n        ColumnQuery<String, String, byte[]> queryThumbnail = HFactory.createColumnQuery(keyspaceOperator,\n        \t\tStringSerializer.get(), StringSerializer.get(), BytesArraySerializer.get());\n        \n        HColumn<String, byte[]> columnThumbnail =\n        \t\tqueryThumbnail.setColumnFamily(ATTACHMENT_CF)\n        \t\t\t\t.setKey(attachmentId)\n        \t\t\t\t.setName(THUMBNAIL)\n        \t\t\t\t.execute()\n        \t\t\t\t.get();\n        if(columnThumbnail != null && columnThumbnail.getValue().length > 0) {\n        \tattachment.setThumbnail(columnThumbnail.getValue());\n        \tattachment.setHasThumbnail(true);\n        }\n        else {\n        \tattachment.setHasThumbnail(false);\n        }\n        return attachment;\n    }\n\n    @Override\n    public Attachment findAttachmentMetadataById(String attachmentId) {\n        if (attachmentId == null) {\n            return null;\n        }\n        Attachment attachment = new Attachment();\n        attachment.setAttachmentId(attachmentId);\n\n        ColumnQuery<String, String, String> queryFilename = HFactory.createColumnQuery(keyspaceOperator,\n                StringSerializer.get(), StringSerializer.get(), StringSerializer.get());\n\n        HColumn<String, String> columnFilename =\n                queryFilename.setColumnFamily(ATTACHMENT_CF)\n                        .setKey(attachmentId)\n                        .setName(FILENAME)\n                        .execute()\n                        .get();\n\n        if (columnFilename != null && columnFilename.getValue() != null) {\n            attachment.setFilename(columnFilename.getValue());\n        } else {\n            return null;\n        }\n\n        ColumnQuery<String, String, Long> querySize = HFactory.createColumnQuery(keyspaceOperator,\n                StringSerializer.get(), StringSerializer.get(), LongSerializer.get());\n\n        HColumn<String, Long> columnSize =\n                querySize.setColumnFamily(ATTACHMENT_CF)\n                        .setKey(attachmentId)\n                        .setName(SIZE)\n                        .execute()\n                        .get();\n\n        if (columnSize != null && columnSize.getValue() != null) {\n            attachment.setSize(columnSize.getValue());\n        } else {\n            return null;\n        }\n\n        ColumnQuery<String, String, Date> queryCreationDate = HFactory.createColumnQuery(keyspaceOperator,\n                StringSerializer.get(), StringSerializer.get(), DateSerializer.get());\n\n        HColumn<String, Date> columnCreationDate =\n                queryCreationDate.setColumnFamily(ATTACHMENT_CF)\n                        .setKey(attachmentId)\n                        .setName(CREATION_DATE)\n                        .execute()\n                        .get();\n\n        if (columnCreationDate != null && columnCreationDate.getValue() != null) {\n            attachment.setCreationDate(columnCreationDate.getValue());\n        } else {\n            attachment.setCreationDate(new Date());\n        }\n\n        return attachment;\n    }\n\n\t@Override\n\tpublic Attachment updateThumbnail(Attachment attach) {\n\t\tlog.debug(\"Updating thumbnail : {}\", attach);\n\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        \n        mutator.insert(attach.getAttachmentId(), ATTACHMENT_CF, HFactory.createColumn(THUMBNAIL,\n        \t\tattach.getThumbnail(), StringSerializer.get(), BytesArraySerializer.get()));\n        return attach;\n\t}\n}"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraAvatarRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.domain.Avatar;\nimport fr.ippon.tatami.repository.AvatarRepository;\nimport me.prettyprint.cassandra.serializers.BytesArraySerializer;\nimport me.prettyprint.cassandra.serializers.DateSerializer;\nimport me.prettyprint.cassandra.serializers.LongSerializer;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.cassandra.utils.TimeUUIDUtils;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport me.prettyprint.hector.api.query.ColumnQuery;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.cache.annotation.CacheEvict;\nimport org.springframework.cache.annotation.Cacheable;\nimport org.springframework.stereotype.Repository;\n\nimport javax.inject.Inject;\nimport java.util.Date;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.AVATAR_CF;\n\n@Repository\npublic class CassandraAvatarRepository implements AvatarRepository {\n\n    private final Logger log = LoggerFactory.getLogger(CassandraAttachmentRepository.class);\n\n    private final String CONTENT = \"content\";\n    private final String FILENAME = \"filename\";\n    private final String SIZE = \"size\";\n    private final String CREATION_DATE = \"creation_date\";\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    public void createAvatar(Avatar avatar) {\n\n        String avatarId = TimeUUIDUtils.getUniqueTimeUUIDinMillis().toString();\n        log.debug(\"Creating avatar : {}\", avatar);\n\n\n        avatar.setAvatarId(avatarId);\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n\n        mutator.insert(avatarId, AVATAR_CF, HFactory.createColumn(CONTENT,\n                avatar.getContent(), StringSerializer.get(), BytesArraySerializer.get()));\n\n        mutator.insert(avatarId, AVATAR_CF, HFactory.createColumn(FILENAME,\n                avatar.getFilename(), StringSerializer.get(), StringSerializer.get()));\n\n        mutator.insert(avatarId, AVATAR_CF, HFactory.createColumn(SIZE,\n                avatar.getSize(), StringSerializer.get(), LongSerializer.get()));\n\n        mutator.insert(avatarId, AVATAR_CF, HFactory.createColumn(CREATION_DATE,\n                avatar.getCreationDate(), StringSerializer.get(), DateSerializer.get()));\n\n    }\n\n    @Override\n    @CacheEvict(value = \"avatar-cache\")\n    public void removeAvatar(String avatarId) {\n        log.debug(\"Avatar deleted : {}\", avatarId);\n\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.addDeletion(avatarId, AVATAR_CF);\n        mutator.execute();\n    }\n\n    @Override\n    @Cacheable(\"avatar-cache\")\n    public Avatar findAvatarById(String avatarId) {\n        if (avatarId == null) {\n            return null;\n        }\n        log.debug(\"Finding avatar : {}\", avatarId);\n\n        Avatar avatar = this.findAttachmentMetadataById(avatarId);\n\n        if (avatar == null) {\n            return null;\n        }\n\n        ColumnQuery<String, String, byte[]> queryAttachment = HFactory.createColumnQuery(keyspaceOperator,\n                StringSerializer.get(), StringSerializer.get(), BytesArraySerializer.get());\n\n        HColumn<String, byte[]> columnAttachment =\n                queryAttachment.setColumnFamily(AVATAR_CF)\n                        .setKey(avatarId)\n                        .setName(CONTENT)\n                        .execute()\n                        .get();\n\n        avatar.setContent(columnAttachment.getValue());\n        return avatar;\n    }\n\n\n    Avatar findAttachmentMetadataById(String avatarId) {\n        if (avatarId == null) {\n            return null;\n        }\n        Avatar avatar = new Avatar();\n        avatar.setAvatarId(avatarId);\n\n        ColumnQuery<String, String, String> queryFilename = HFactory.createColumnQuery(keyspaceOperator,\n                StringSerializer.get(), StringSerializer.get(), StringSerializer.get());\n\n        HColumn<String, String> columnFilename =\n                queryFilename.setColumnFamily(AVATAR_CF)\n                        .setKey(avatarId)\n                        .setName(FILENAME)\n                        .execute()\n                        .get();\n\n        if (columnFilename != null && columnFilename.getValue() != null) {\n            avatar.setFilename(columnFilename.getValue());\n        } else {\n            return null;\n        }\n\n        ColumnQuery<String, String, Long> querySize = HFactory.createColumnQuery(keyspaceOperator,\n                StringSerializer.get(), StringSerializer.get(), LongSerializer.get());\n\n        HColumn<String, Long> columnSize =\n                querySize.setColumnFamily(AVATAR_CF)\n                        .setKey(avatarId)\n                        .setName(SIZE)\n                        .execute()\n                        .get();\n\n        if (columnSize != null && columnSize.getValue() != null) {\n            avatar.setSize(columnSize.getValue());\n        } else {\n            return null;\n        }\n\n        ColumnQuery<String, String, Date> queryCreationDate = HFactory.createColumnQuery(keyspaceOperator,\n                StringSerializer.get(), StringSerializer.get(), DateSerializer.get());\n\n        HColumn<String, Date> columnCreationDate =\n                queryCreationDate.setColumnFamily(AVATAR_CF)\n                        .setKey(avatarId)\n                        .setName(CREATION_DATE)\n                        .execute()\n                        .get();\n\n        if (columnCreationDate != null && columnCreationDate.getValue() != null) {\n            avatar.setCreationDate(columnCreationDate.getValue());\n        } else {\n            avatar.setCreationDate(new Date());\n        }\n\n        return avatar;\n    }\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraBlockRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.config.Constants;\nimport fr.ippon.tatami.repository.BlockRepository;\nimport me.prettyprint.cassandra.serializers.LongSerializer;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.cassandra.service.template.ColumnFamilyResult;\nimport me.prettyprint.cassandra.service.template.ColumnFamilyTemplate;\nimport me.prettyprint.cassandra.service.template.ThriftColumnFamilyTemplate;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport org.springframework.stereotype.Repository;\n\nimport javax.annotation.PostConstruct;\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Calendar;\nimport java.util.Collection;\nimport java.util.List;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.BLOCK_USERS_CF;\n/**\n * Created by matthieudelafourniere on 7/7/16.\n */\n\n@Repository\npublic class CassandraBlockRepository implements BlockRepository {\n\n    private ColumnFamilyTemplate<String, String> blockedUsersTemplate;\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @PostConstruct\n    public void init() {\n        blockedUsersTemplate = new ThriftColumnFamilyTemplate<String, String>(keyspaceOperator,\n                BLOCK_USERS_CF,\n                StringSerializer.get(),\n                StringSerializer.get());\n\n        blockedUsersTemplate.setCount(Constants.CASSANDRA_MAX_COLUMNS);\n    }\n\n    @Override\n    public void blockUser(String currentUserLogin, String blockedUserLogin) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(currentUserLogin, BLOCK_USERS_CF, HFactory.createColumn(blockedUserLogin,\n                Calendar.getInstance().getTimeInMillis(), StringSerializer.get(), LongSerializer.get()));\n    }\n\n    @Override\n    public void unblockUser(String currentUserLogin, String unblockedUserLogin) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.delete(currentUserLogin, BLOCK_USERS_CF, unblockedUserLogin, StringSerializer.get());\n\n    }\n\n    @Override\n    public Collection<String> getUsersBlockedBy(String userLogin) {\n        ColumnFamilyResult<String, String> result = blockedUsersTemplate.queryColumns(userLogin);\n        Collection<String> blockedUsers = new ArrayList<String>();\n        for (String columnName : result.getColumnNames()) {\n            blockedUsers.add(columnName);\n        }\n        return blockedUsers;\n    }\n\n    @Override\n    public boolean isBlocked(String blockingLogin, String blockedLogin) {\n        Collection<String> blockedEmails = getUsersBlockedBy(blockingLogin);\n        return blockedEmails.contains(blockedLogin);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraCounterRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.repository.CounterRepository;\nimport me.prettyprint.cassandra.model.thrift.ThriftCounterColumnQuery;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.HCounterColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport me.prettyprint.hector.api.query.CounterQuery;\nimport org.springframework.cache.annotation.CacheEvict;\nimport org.springframework.stereotype.Repository;\nimport fr.ippon.tatami.config.ColumnFamilyKeys;\n\nimport javax.inject.Inject;\n\nimport static me.prettyprint.hector.api.factory.HFactory.createCounterColumn;\n\n/**\n * Cassandra implementation of the Counter repository.\n * <p/>\n * Structure :\n * - Key = login\n * - Name = counterId\n * - Value = count\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraCounterRepository implements CounterRepository {\n\n    private static final String STATUS_COUNTER = \"STATUS_COUNTER\";\n\n    private static final String FOLLOWERS_COUNTER = \"FOLLOWERS_COUNTER\";\n\n    private static final String FRIENDS_COUNTER = \"FRIENDS_COUNTER\";\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    @CacheEvict(value = \"user-cache\", key = \"#login\")\n    public void incrementFollowersCounter(String login) {\n        incrementCounter(FOLLOWERS_COUNTER, login);\n    }\n\n    @Override\n    @CacheEvict(value = {\"user-cache\", \"suggest-users-cache\"}, key = \"#login\")\n    public void incrementFriendsCounter(String login) {\n        incrementCounter(FRIENDS_COUNTER, login);\n    }\n\n    @Override\n    @CacheEvict(value = \"user-cache\", key = \"#login\")\n    public void incrementStatusCounter(String login) {\n        incrementCounter(STATUS_COUNTER, login);\n    }\n\n    @Override\n    @CacheEvict(value = \"user-cache\", key = \"#login\")\n    public void decrementFollowersCounter(String login) {\n        decrementCounter(FOLLOWERS_COUNTER, login);\n    }\n\n    @Override\n    @CacheEvict(value = \"user-cache\", key = \"#login\")\n    public void decrementFriendsCounter(String login) {\n        decrementCounter(FRIENDS_COUNTER, login);\n    }\n\n    @Override\n    @CacheEvict(value = \"user-cache\", key = \"#login\")\n    public void decrementStatusCounter(String login) {\n        decrementCounter(STATUS_COUNTER, login);\n    }\n\n    @Override\n    public long getFollowersCounter(String login) {\n        return getCounter(FOLLOWERS_COUNTER, login);\n    }\n\n    @Override\n    public long getFriendsCounter(String login) {\n        return getCounter(FRIENDS_COUNTER, login);\n    }\n\n    @Override\n    public long getStatusCounter(String login) {\n        return getCounter(STATUS_COUNTER, login);\n    }\n\n    @Override\n    public void createFollowersCounter(String login) {\n        createCounter(FOLLOWERS_COUNTER, login);\n    }\n\n    @Override\n    public void createFriendsCounter(String login) {\n        createCounter(FRIENDS_COUNTER, login);\n    }\n\n    @Override\n    public void createStatusCounter(String login) {\n        createCounter(STATUS_COUNTER, login);\n    }\n\n    @Override\n    public void deleteCounters(String login) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.addCounterDeletion(login, ColumnFamilyKeys.COUNTER_CF, STATUS_COUNTER, StringSerializer.get());\n        mutator.addCounterDeletion(login, ColumnFamilyKeys.COUNTER_CF, FOLLOWERS_COUNTER, StringSerializer.get());\n        mutator.addCounterDeletion(login, ColumnFamilyKeys.COUNTER_CF, FRIENDS_COUNTER, StringSerializer.get());\n        mutator.execute();\n    }\n\n    private void createCounter(String counterName, String login) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insertCounter(login, ColumnFamilyKeys.COUNTER_CF,\n                createCounterColumn(counterName, 0));\n    }\n\n    private void incrementCounter(String counterName, String login) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.incrementCounter(login, ColumnFamilyKeys.COUNTER_CF, counterName, 1);\n    }\n\n    private void decrementCounter(String counterName, String login) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.decrementCounter(login, ColumnFamilyKeys.COUNTER_CF, counterName, 1);\n    }\n\n    private long getCounter(String counterName, String login) {\n        CounterQuery<String, String> counter =\n                new ThriftCounterColumnQuery<String, String>(keyspaceOperator,\n                        StringSerializer.get(),\n                        StringSerializer.get());\n\n        counter.setColumnFamily(ColumnFamilyKeys.COUNTER_CF).setKey(login).setName(counterName);\n        HCounterColumn<String> counterColumn = counter.execute().get();\n        if (counterColumn == null) {\n            return 0;\n        } else {\n            return counterColumn.getValue();\n        }\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraDaylineRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.domain.UserStatusStat;\nimport fr.ippon.tatami.domain.status.Status;\nimport fr.ippon.tatami.repository.DaylineRepository;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.CounterSlice;\nimport me.prettyprint.hector.api.beans.HCounterColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport me.prettyprint.hector.api.query.SliceCounterQuery;\nimport org.springframework.cache.annotation.Cacheable;\nimport org.springframework.stereotype.Repository;\n\nimport javax.inject.Inject;\nimport java.util.Collection;\nimport java.util.TreeSet;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.DAYLINE_CF;\nimport static me.prettyprint.hector.api.factory.HFactory.createCounterSliceQuery;\n\n/**\n * Cassandra implementation of the user repository.\n * <p/>\n * Structure :\n * - Key = day + domain\n * - Name = username\n * - Value = count\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraDaylineRepository implements DaylineRepository {\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    public void addStatusToDayline(Status status, String day) {\n        String key = getKey(status.getDomain(), day);\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.incrementCounter(key, DAYLINE_CF, status.getUsername(), 1);\n    }\n\n    @Override\n    @Cacheable(\"dayline-cache\")\n    public Collection<UserStatusStat> getDayline(String domain, String day) {\n        String key = getKey(domain, day);\n        Collection<UserStatusStat> results = new TreeSet<UserStatusStat>();\n        SliceCounterQuery<String, String> query = createCounterSliceQuery(keyspaceOperator,\n                StringSerializer.get(), StringSerializer.get())\n                .setColumnFamily(DAYLINE_CF)\n                .setRange(null, null, false, Integer.MAX_VALUE)\n                .setKey(key);\n\n        CounterSlice<String> queryResult = query.execute().get();\n\n        for (HCounterColumn<String> column : queryResult.getColumns()) {\n            UserStatusStat stat = new UserStatusStat(column.getName(), column.getValue());\n            results.add(stat);\n        }\n        return results;\n    }\n\n    /**\n     * Generates the key for this column family.\n     */\n    private String getKey(String domain, String day) {\n        return day + \"-\" + domain;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraDiscussionRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.repository.DiscussionRepository;\nimport me.prettyprint.cassandra.serializers.LongSerializer;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.ColumnSlice;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport org.springframework.cache.annotation.CacheEvict;\nimport org.springframework.stereotype.Repository;\n\nimport javax.inject.Inject;\nimport java.util.Calendar;\nimport java.util.Collection;\nimport java.util.LinkedHashSet;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.DISCUSSION_CF;\nimport static me.prettyprint.hector.api.factory.HFactory.createSliceQuery;\n\n/**\n * Cassandra implementation of the StatusDetails repository.\n * <p/>\n * Structure :\n * - Key = originial status Id\n * - Name = time\n * - Value = reply status Id\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraDiscussionRepository implements DiscussionRepository {\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    @CacheEvict(value = \"status-cache\", key = \"#originalStatusId\")\n    public void addReplyToDiscussion(String originalStatusId, String replyStatusId) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(originalStatusId, DISCUSSION_CF,\n                HFactory.createColumn(\n                        Calendar.getInstance().getTimeInMillis(),\n                        replyStatusId,\n                        LongSerializer.get(),\n                        StringSerializer.get()));\n    }\n\n    @Override\n    public Collection<String> findStatusIdsInDiscussion(String originalStatusId) {\n        ColumnSlice<Long, String> result = createSliceQuery(keyspaceOperator,\n                StringSerializer.get(), LongSerializer.get(), StringSerializer.get())\n                .setColumnFamily(DISCUSSION_CF)\n                .setKey(originalStatusId)\n                .setRange(null, null, false, Integer.MAX_VALUE)\n                .execute()\n                .get();\n\n        Collection<String> statusIds = new LinkedHashSet<String>();\n        for (HColumn<Long, String> column : result.getColumns()) {\n            statusIds.add(column.getValue());\n        }\n        return statusIds;\n    }\n\n    @Override\n    public boolean hasReply(String statusId) {\n        int zeroOrOne = HFactory.createCountQuery(keyspaceOperator, StringSerializer.get(), LongSerializer.get())\n                .setColumnFamily(DISCUSSION_CF)\n                .setKey(statusId)\n                .setRange(null, null, 1)\n                .execute()\n                .get();\n\n        return zeroOrOne > 0;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraDomainConfigurationRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport javax.inject.Inject;\n\nimport me.prettyprint.hom.EntityManagerImpl;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Repository;\n\nimport fr.ippon.tatami.domain.DomainConfiguration;\nimport fr.ippon.tatami.repository.DomainConfigurationRepository;\n\n/**\n * Cassandra implementation of the DomainConfiguration repository.\n *\n * @author Julien Dubois\n */\n\n@Repository\npublic class CassandraDomainConfigurationRepository implements DomainConfigurationRepository {\n\n    private final Logger log = LoggerFactory.getLogger(CassandraDomainConfigurationRepository.class);\n    \n    @Inject\n    private EntityManagerImpl em;\n\n    @Override\n    public void updateDomainConfiguration(DomainConfiguration domainConfiguration) {\n        setDefaultValues(domainConfiguration);\n        em.persist(domainConfiguration);\n    }\n\n    @Override\n    public DomainConfiguration findDomainConfigurationByDomain(String domain) {\n        DomainConfiguration domainConfiguration;\n        try {\n            domainConfiguration = em.find(DomainConfiguration.class, domain);\n        } catch (Exception e) {\n\n            log.debug(\"Exception while looking for domain {} : {}\", domain, e.toString());\n\n            return null;\n        }\n        if (domainConfiguration == null) {\n            domainConfiguration = new DomainConfiguration();\n            domainConfiguration.setDomain(domain);\n            setDefaultValues(domainConfiguration);\n            em.persist(domainConfiguration);\n        }\n        if (domain.equals(\"ippon.fr\")) {\n            domainConfiguration.setSubscriptionLevel(DomainConfiguration.SubscriptionAndStorageSizeOptions.IPPONSUSCRIPTION);\n            domainConfiguration.setStorageSize(DomainConfiguration.SubscriptionAndStorageSizeOptions.IPPONSIZE);\n        }\n        return domainConfiguration;\n    }\n\n    private void setDefaultValues(DomainConfiguration domainConfiguration) {\n        if (domainConfiguration.getStorageSize() == null) {\n            domainConfiguration.setStorageSize(DomainConfiguration.SubscriptionAndStorageSizeOptions.BASICSIZE);\n        }\n        if (domainConfiguration.getSubscriptionLevel() == null) {\n            domainConfiguration.setSubscriptionLevel(DomainConfiguration.SubscriptionAndStorageSizeOptions.BASICSUSCRIPTION);\n        }\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraDomainRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.config.Constants;\nimport fr.ippon.tatami.domain.Domain;\nimport fr.ippon.tatami.repository.DomainRepository;\nimport me.prettyprint.cassandra.serializers.LongSerializer;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.ColumnSlice;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.beans.OrderedRows;\nimport me.prettyprint.hector.api.beans.Row;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport me.prettyprint.hector.api.query.QueryResult;\nimport me.prettyprint.hector.api.query.RangeSlicesQuery;\nimport org.springframework.stereotype.Repository;\n\nimport javax.inject.Inject;\nimport java.util.*;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.DOMAIN_CF;\nimport static me.prettyprint.hector.api.factory.HFactory.createRangeSlicesQuery;\nimport static me.prettyprint.hector.api.factory.HFactory.createSliceQuery;\n\n/**\n * Cassandra implementation of the Domain repository.\n * <p/>\n * Structure :\n * - Key = domain\n * - Name = login\n * - Value = time\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraDomainRepository implements DomainRepository {\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    public void addUserInDomain(String domain, String login) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(domain, DOMAIN_CF, HFactory.createColumn(login,\n                Calendar.getInstance().getTimeInMillis(), StringSerializer.get(), LongSerializer.get()));\n    }\n\n    @Override\n    public void updateUserInDomain(String domain, String login) {\n        this.addUserInDomain(domain, login);\n    }\n\n    @Override\n    public void deleteUserInDomain(String domain, String login) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.delete(domain, DOMAIN_CF, login, StringSerializer.get());\n    }\n\n    @Override\n    public List<String> getLoginsInDomain(String domain, int pagination) {\n        int maxColumns = pagination + Constants.PAGINATION_SIZE;\n        List<String> logins = new ArrayList<String>();\n        ColumnSlice<String, String> result = createSliceQuery(keyspaceOperator,\n                StringSerializer.get(), StringSerializer.get(), StringSerializer.get())\n                .setColumnFamily(DOMAIN_CF)\n                .setKey(domain)\n                .setRange(null, null, false, maxColumns)\n                .execute()\n                .get();\n\n        int index = 0;\n        for (HColumn<String, String> column : result.getColumns()) {\n            // We take one more item, to display (or not) the \"next\" button if there is an item after the displayed list.\n            if (index > maxColumns) {\n                break;\n            }\n            if (index >= pagination) {\n                logins.add(column.getName());\n            }\n            index++;\n        }\n        return logins;\n    }\n\n    @Override\n    public List<String> getLoginsInDomain(String domain) {\n        List<String> logins = new ArrayList<String>();\n        ColumnSlice<String, String> result = createSliceQuery(keyspaceOperator,\n                StringSerializer.get(), StringSerializer.get(), StringSerializer.get())\n                .setColumnFamily(DOMAIN_CF)\n                .setKey(domain)\n                .setRange(null, null, false, Integer.MAX_VALUE)\n                .execute()\n                .get();\n\n        for (HColumn<String, String> column : result.getColumns()) {\n            logins.add(column.getName());\n        }\n        return logins;\n    }\n\n    @Override\n    public Set<Domain> getAllDomains() {\n        Set<Domain> domains = new HashSet<Domain>();\n        RangeSlicesQuery<String, String, String> query = createRangeSlicesQuery(keyspaceOperator,\n                StringSerializer.get(), StringSerializer.get(), StringSerializer.get())\n                .setColumnFamily(DOMAIN_CF)\n                .setRange(null, null, false, Integer.MAX_VALUE)\n                .setRowCount(Constants.CASSANDRA_MAX_ROWS);\n\n        QueryResult<OrderedRows<String, String, String>> result = query.execute();\n        List<Row<String, String, String>> rows = result.get().getList();\n        for (Row<String, String, String> row : rows) {\n            Domain domain = new Domain();\n            domain.setName(row.getKey());\n            domain.setNumberOfUsers(row.getColumnSlice().getColumns().size());\n\n            domains.add(domain);\n        }\n        return domains;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraDomainlineRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.repository.DomainlineRepository;\nimport me.prettyprint.hector.api.Keyspace;\nimport org.springframework.stereotype.Repository;\n\nimport javax.inject.Inject;\nimport java.util.Collection;\nimport java.util.List;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.DOMAINLINE_CF;\n\n/**\n * Cassandra implementation of the Domain line repository.\n * <p/>\n * Structure :\n * - Key = domain\n * - Name = statusId\n * - Value = \"\"\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraDomainlineRepository extends AbstractCassandraLineRepository implements DomainlineRepository {\n\n    private final static int COLUMN_TTL = 60 * 60 * 24 * 30; // The column is stored for 30 days.\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    public void addStatusToDomainline(String domain, String statusId) {\n        addStatus(domain, DOMAINLINE_CF, statusId, COLUMN_TTL);\n    }\n\n    @Override\n    public void removeStatusFromDomainline(String domain, Collection<String> statusIdsToDelete) {\n        removeStatuses(domain, DOMAINLINE_CF, statusIdsToDelete);\n    }\n\n    @Override\n    public List<String> getDomainline(String domain, int size, String start, String finish) {\n        return getLineFromCF(DOMAINLINE_CF, domain, size, start, finish);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraFavoritelineRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.repository.FavoritelineRepository;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.cassandra.serializers.UUIDSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.ColumnSlice;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport org.springframework.cache.annotation.CacheEvict;\nimport org.springframework.cache.annotation.Cacheable;\nimport org.springframework.stereotype.Repository;\n\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.UUID;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.FAVLINE_CF;\nimport static me.prettyprint.hector.api.factory.HFactory.createSliceQuery;\n\n/**\n * Cassandra implementation of the favoriteline repository.\n * <p/>\n * Structure :\n * - Key = login\n * - Name = statusId\n * - Value = \"\"\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraFavoritelineRepository implements FavoritelineRepository {\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    @CacheEvict(value = \"favorites-cache\", key = \"#login\")\n    public void addStatusToFavoriteline(String login, String statusId) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(login, FAVLINE_CF, HFactory.createColumn(UUID.fromString(statusId), \"\",\n                UUIDSerializer.get(), StringSerializer.get()));\n    }\n\n    @Override\n    @CacheEvict(value = \"favorites-cache\", key = \"#login\")\n    public void removeStatusFromFavoriteline(String login, String statusId) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.delete(login, FAVLINE_CF, UUID.fromString(statusId), UUIDSerializer.get());\n    }\n\n    @Override\n    @Cacheable(\"favorites-cache\")\n    public List<String> getFavoriteline(String login) {\n        List<String> line = new ArrayList<String>();\n        ColumnSlice<UUID, String> result = createSliceQuery(keyspaceOperator,\n                StringSerializer.get(), UUIDSerializer.get(), StringSerializer.get())\n                .setColumnFamily(FAVLINE_CF)\n                .setKey(login)\n                .setRange(null, null, true, 50)\n                .execute()\n                .get();\n\n        for (HColumn<UUID, String> column : result.getColumns()) {\n            line.add(column.getName().toString());\n        }\n        return line;\n    }\n\n    @Override\n    public void deleteFavoriteline(String login) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.addDeletion(login, FAVLINE_CF);\n        mutator.execute();\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraFollowerRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.repository.FollowerRepository;\nimport org.springframework.cache.annotation.CacheEvict;\nimport org.springframework.cache.annotation.Cacheable;\nimport org.springframework.stereotype.Repository;\nimport fr.ippon.tatami.config.ColumnFamilyKeys;\n\nimport java.util.Collection;\n\n/**\n * Cassandra implementation of the Follower repository.\n * <p/>\n * Structure :\n * - Key = login\n * - Name = follower login\n * - Value = time\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraFollowerRepository extends AbstractCassandraFollowerRepository implements FollowerRepository {\n\n    @Override\n    @CacheEvict(value = \"followers-cache\", key = \"#login\")\n    public void addFollower(String login, String followerLogin) {\n        super.addFollower(login, followerLogin);\n    }\n\n    @Override\n    @CacheEvict(value = \"followers-cache\", key = \"#login\")\n    public void removeFollower(String login, String followerLogin) {\n        super.removeFollower(login, followerLogin);\n    }\n\n    @Override\n    @Cacheable(\"followers-cache\")\n    public Collection<String> findFollowersForUser(String login) {\n        return super.findFollowers(login);\n    }\n\n    @Override\n    public String getFollowersCF() {\n        return ColumnFamilyKeys.FOLLOWERS_CF;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraFriendRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.repository.FriendRepository;\nimport org.springframework.cache.annotation.CacheEvict;\nimport org.springframework.cache.annotation.Cacheable;\nimport org.springframework.stereotype.Repository;\n\nimport java.util.List;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.FRIENDS_CF;\n\n/**\n * Cassandra implementation of the Friend repository.\n * <p/>\n * Structure :\n * - Key = login\n * - Name = friend login\n * - Value = time\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraFriendRepository extends AbstractCassandraFriendRepository implements FriendRepository {\n\n    @Override\n    @CacheEvict(value = \"friends-cache\", key = \"#login\")\n    public void addFriend(String login, String friendLogin) {\n        super.addFriend(login, friendLogin);\n    }\n\n    @Override\n    @CacheEvict(value = \"friends-cache\", key = \"#login\")\n    public void removeFriend(String login, String friendLogin) {\n        super.removeFriend(login, friendLogin);\n    }\n\n    @Override\n    @Cacheable(\"friends-cache\")\n    public List<String> findFriendsForUser(String login) {\n        return super.findFriends(login);\n    }\n\n    @Override\n    public String getFriendsCF() {\n        return FRIENDS_CF;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraGroupCounterRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.repository.GroupCounterRepository;\nimport me.prettyprint.cassandra.model.thrift.ThriftCounterColumnQuery;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport me.prettyprint.hector.api.query.CounterQuery;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Repository;\n\nimport javax.inject.Inject;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.GROUP_COUNTER_CF;\n\n/**\n * Cassandra implementation of the Group Counter repository.\n * <p/>\n * Structure :\n * - Key = domain\n * - Name = groupId\n * - Value = count\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraGroupCounterRepository implements GroupCounterRepository {\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    public long getGroupCounter(String domain, String groupId) {\n        CounterQuery<String, String> counter =\n                new ThriftCounterColumnQuery<String, String>(keyspaceOperator,\n                        StringSerializer.get(),\n                        StringSerializer.get());\n\n        counter.setColumnFamily(GROUP_COUNTER_CF).setKey(domain).setName(groupId);\n        return counter.execute().get().getValue();\n    }\n\n    protected final Logger log = LoggerFactory.getLogger(this.getClass().getCanonicalName());\n\n    @Override\n    public void incrementGroupCounter(String domain, String groupId) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.incrementCounter(domain, GROUP_COUNTER_CF, groupId, 1);\n    }\n\n    @Override\n    public void decrementGroupCounter(String domain, String groupId) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.decrementCounter(domain, GROUP_COUNTER_CF, groupId, 1);\n    }\n\n    @Override\n    public void deleteGroupCounter(String domain, String groupId) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.addCounterDeletion(domain, GROUP_COUNTER_CF, groupId, StringSerializer.get());\n        mutator.execute();\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraGroupDetailsRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.repository.GroupDetailsRepository;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.ColumnSlice;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport org.springframework.stereotype.Repository;\n\nimport javax.inject.Inject;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.GROUP_DETAILS_CF;\nimport static me.prettyprint.hector.api.factory.HFactory.createSliceQuery;\n\n/**\n * Cassandra implementation of the Group Details repository.\n * <p/>\n * Structure :\n * - Key = Group ID\n * - Name / Value pairs of group details\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraGroupDetailsRepository implements GroupDetailsRepository {\n\n    private static final String NAME = \"name\";\n    private static final String DESCRIPTION = \"description\";\n    private static final String PUBLIC_GROUP = \"publicGroup\";\n    private static final String ARCHIVED_GROUP = \"archivedGroup\";\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    public void createGroupDetails(String groupId, String name, String description, boolean publicGroup) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(groupId, GROUP_DETAILS_CF, HFactory.createColumn(NAME,\n                name, StringSerializer.get(), StringSerializer.get()));\n        mutator.insert(groupId, GROUP_DETAILS_CF, HFactory.createColumn(DESCRIPTION,\n                description, StringSerializer.get(), StringSerializer.get()));\n        mutator.insert(groupId, GROUP_DETAILS_CF, HFactory.createColumn(PUBLIC_GROUP,\n                (Boolean.valueOf(publicGroup)).toString(), StringSerializer.get(), StringSerializer.get()));\n        mutator.insert(groupId, GROUP_DETAILS_CF, HFactory.createColumn(ARCHIVED_GROUP,\n                Boolean.FALSE.toString(), StringSerializer.get(), StringSerializer.get()));\n    }\n\n    @Override\n    public void editGroupDetails(String groupId, String name, String description, boolean archivedGroup) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(groupId, GROUP_DETAILS_CF, HFactory.createColumn(NAME,\n                name, StringSerializer.get(), StringSerializer.get()));\n        mutator.insert(groupId, GROUP_DETAILS_CF, HFactory.createColumn(DESCRIPTION,\n                description, StringSerializer.get(), StringSerializer.get()));\n        mutator.insert(groupId, GROUP_DETAILS_CF, HFactory.createColumn(ARCHIVED_GROUP,\n                (Boolean.valueOf(archivedGroup)).toString(), StringSerializer.get(), StringSerializer.get()));\n    }\n\n    @Override\n    public Group getGroupDetails(String groupId) {\n        Group group = new Group();\n        group.setGroupId(groupId);\n        group.setPublicGroup(false);\n        ColumnSlice<String, String> result = createSliceQuery(keyspaceOperator,\n                StringSerializer.get(), StringSerializer.get(), StringSerializer.get())\n                .setColumnFamily(GROUP_DETAILS_CF)\n                .setKey(groupId)\n                .setRange(null, null, false, 4)\n                .execute()\n                .get();\n\n        for (HColumn<String, String> column : result.getColumns()) {\n            if (column.getName().equals(NAME)) {\n                group.setName(column.getValue());\n            } else if (column.getName().equals(DESCRIPTION)) {\n                group.setDescription(column.getValue());\n            } else if (column.getName().equals(PUBLIC_GROUP)) {\n                if (column.getValue().equals(Boolean.TRUE.toString())) {\n                    group.setPublicGroup(true);\n                }\n            } else if (column.getName().equals(ARCHIVED_GROUP)) {\n                if (column.getValue().equals(Boolean.TRUE.toString())) {\n                    group.setArchivedGroup(true);\n                }\n            }\n        }\n        return group;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraGroupMembersRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.config.GroupRoles;\nimport fr.ippon.tatami.repository.GroupMembersRepository;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.ColumnSlice;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport org.springframework.stereotype.Repository;\n\nimport javax.inject.Inject;\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.GROUP_MEMBERS_CF;\nimport static me.prettyprint.hector.api.factory.HFactory.createSliceQuery;\n\n/**\n * Cassandra implementation of the Group members repository.\n * <p/>\n * Structure :\n * - Key = group ID\n * - Name = login\n * - Value = role\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraGroupMembersRepository implements GroupMembersRepository {\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    public void addMember(String groupId, String login) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(groupId, GROUP_MEMBERS_CF, HFactory.createColumn(login,\n                GroupRoles.MEMBER, StringSerializer.get(), StringSerializer.get()));\n    }\n\n    @Override\n    public void addAdmin(String groupId, String login) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(groupId, GROUP_MEMBERS_CF, HFactory.createColumn(login,\n                GroupRoles.ADMIN, StringSerializer.get(), StringSerializer.get()));\n    }\n\n    @Override\n    public void removeMember(String groupId, String login) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.delete(groupId, GROUP_MEMBERS_CF, login, StringSerializer.get());\n    }\n\n    @Override\n    public Map<String, String> findMembers(String groupId) {\n        Map<String, String> members = new HashMap<String, String>();\n        ColumnSlice<String, String> result = createSliceQuery(keyspaceOperator,\n                StringSerializer.get(), StringSerializer.get(), StringSerializer.get())\n                .setColumnFamily(GROUP_MEMBERS_CF)\n                .setKey(groupId)\n                .setRange(null, null, false, Integer.MAX_VALUE)\n                .execute()\n                .get();\n\n        for (HColumn<String, String> column : result.getColumns()) {\n            members.put(column.getName(), column.getValue());\n        }\n        return members;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraGroupRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.repository.GroupRepository;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.cassandra.utils.TimeUUIDUtils;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport me.prettyprint.hector.api.query.ColumnQuery;\nimport org.springframework.stereotype.Repository;\n\nimport javax.inject.Inject;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.GROUP_CF;\n\n/**\n * Cassandra implementation of the Group repository.\n * <p/>\n * Structure :\n * - Key = domain\n * - Name = Group ID\n * - Value = \"\"\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraGroupRepository implements GroupRepository {\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    public String createGroup(String domain) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        String groupId = TimeUUIDUtils.getUniqueTimeUUIDinMillis().toString();\n        mutator.insert(domain, GROUP_CF, HFactory.createColumn(groupId,\n                \"\", StringSerializer.get(), StringSerializer.get()));\n\n        return groupId;\n    }\n\n    @Override\n    public Group getGroupById(String domain, String groupId) {\n        ColumnQuery<String, String, String> query = HFactory.createStringColumnQuery(keyspaceOperator);\n        HColumn<String, String> column =\n                query.setColumnFamily(GROUP_CF)\n                        .setKey(domain)\n                        .setName(groupId)\n                        .execute()\n                        .get();\n\n        if (column != null) {\n            Group group = new Group();\n            group.setDomain(domain);\n            group.setGroupId(groupId);\n            return group;\n        } else {\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraGrouplineRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.repository.GrouplineRepository;\nimport me.prettyprint.hector.api.Keyspace;\nimport org.springframework.stereotype.Repository;\nimport fr.ippon.tatami.config.ColumnFamilyKeys;\n\nimport javax.inject.Inject;\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * Cassandra implementation of the Group line repository.\n * <p/>\n * Structure :\n * - Key = groupId\n * - Name = statusId\n * - Value = \"\"\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraGrouplineRepository extends AbstractCassandraLineRepository implements GrouplineRepository {\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    public void addStatusToGroupline(String groupId, String statusId) {\n        addStatus(groupId, ColumnFamilyKeys.GROUPLINE_CF, statusId);\n    }\n\n    @Override\n    public void removeStatusesFromGroupline(String groupId, Collection<String> statusIdsToDelete) {\n        removeStatuses(groupId, ColumnFamilyKeys.GROUPLINE_CF, statusIdsToDelete);\n    }\n\n    @Override\n    public List<String> getGroupline(String groupId, int size, String start, String finish) {\n        return getLineFromCF(ColumnFamilyKeys.GROUPLINE_CF, groupId, size, start, finish);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraIdempotentRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport me.prettyprint.hector.api.query.ColumnQuery;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Component;\nimport fr.ippon.tatami.repository.IdempotentRepository;\n\nimport javax.inject.Inject;\n\n/**\n * Used to de-deplucate Camel messages.\n */\n@Component\npublic class CassandraIdempotentRepository implements IdempotentRepository {\n\n    private final Logger log = LoggerFactory.getLogger(CassandraIdempotentRepository.class);\n\n    private final static String KEY = \"Default\";\n\n    private final static String TATAMIBOT_DUPLICATE_CF = \"TatamiBotDuplicate\";\n\n    private final static int COLUMN_TTL = 60 * 60 * 24 * 30; // The column is stored for 30 days.\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    public boolean add(String key) {\n        if (contains(key)) {\n            log.debug(\"Duplicate message detected!\");\n            return false;\n        } else {\n            log.debug(\"Adding new message to the idempotent repository\");\n            HColumn<String, String> column =\n                    HFactory.createColumn(\n                            key,\n                            \"\",\n                            COLUMN_TTL,\n                            StringSerializer.get(),\n                            StringSerializer.get());\n\n            Mutator<String> mutator =\n                    HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n\n            mutator.insert(KEY, TATAMIBOT_DUPLICATE_CF, column);\n            return true;\n        }\n    }\n\n    @Override\n    public boolean contains(String key) {\n\n        log.debug(\"Test message duplication with key : {}\", key);\n        ColumnQuery<String, String, String> query = HFactory.createStringColumnQuery(keyspaceOperator);\n\n        HColumn<String, String> column =\n                query.setColumnFamily(TATAMIBOT_DUPLICATE_CF)\n                        .setKey(KEY)\n                        .setName(key)\n                        .execute()\n                        .get();\n\n        return column != null;\n    }\n\n    @Override\n    public boolean remove(String key) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.delete(KEY, TATAMIBOT_DUPLICATE_CF, key, StringSerializer.get());\n        return true;\n    }\n\n    @Override\n    public boolean confirm(String key) {\n        return true; // noop\n    }\n\n    @Override\n    public void start() throws Exception {\n    }\n\n    @Override\n    public void stop() throws Exception {\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraMailDigestRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.config.Constants;\nimport fr.ippon.tatami.domain.DigestType;\nimport fr.ippon.tatami.repository.MailDigestRepository;\nimport me.prettyprint.cassandra.serializers.LongSerializer;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.ColumnSlice;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport org.springframework.stereotype.Repository;\nimport fr.ippon.tatami.config.ColumnFamilyKeys;\n\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Calendar;\nimport java.util.List;\n\nimport static me.prettyprint.hector.api.factory.HFactory.createSliceQuery;\n\n/**\n * MailDigestRepository implementation for cassandra\n * <p/>\n * Structure :\n * - Key = digestType_[day]_domain\n * - Name = login\n * - Value = time\n * <p/>\n * Note : in the key, the [day] part is only used for weekly digest and\n * represents the day the user subscribed to the digest.\n *\n * @author Pierre Rust\n */\n@Repository\npublic class CassandraMailDigestRepository implements MailDigestRepository {\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    public void subscribeToDigest(DigestType digestType, String login, String domain, String day) {\n\n        Calendar cal = Calendar.getInstance();\n\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(buildKey(digestType, domain, day), ColumnFamilyKeys.MAILDIGEST_CF,\n                HFactory.createColumn(login, cal.getTimeInMillis(), StringSerializer.get(), LongSerializer.get()));\n    }\n\n    @Override\n    public void unsubscribeFromDigest(DigestType digestType, String login, String domain, String day) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.delete(buildKey(digestType, domain, day), ColumnFamilyKeys.MAILDIGEST_CF, login, StringSerializer.get());\n    }\n\n    @Override\n    public List<String> getLoginsRegisteredToDigest(DigestType digestType, String domain,\n                                                    String day, int pagination) {\n\n        List<String> logins = new ArrayList<String>();\n        ColumnSlice<String, String> result = createSliceQuery(keyspaceOperator,\n                StringSerializer.get(), StringSerializer.get(), StringSerializer.get())\n                .setColumnFamily(ColumnFamilyKeys.MAILDIGEST_CF)\n                .setKey(buildKey(digestType, domain, day))\n                .setRange(null, null, false, Integer.MAX_VALUE)\n                .execute()\n                .get();\n\n        int index = 0;\n        for (HColumn<String, String> column : result.getColumns()) {\n            // We take one more item, to display (or not) the \"next\" button if there is an item after the displayed list.\n            if (index > pagination + Constants.PAGINATION_SIZE) {\n                break;\n            }\n            if (index >= pagination) {\n                logins.add(column.getName());\n            }\n            index++;\n        }\n        return logins;\n    }\n\n    /**\n     * @return the row key\n     */\n    private String buildKey(DigestType digestType, String domain, String day) {\n        String key;\n        if (DigestType.WEEKLY_DIGEST == digestType) {\n            key = digestType.toString() + \"_\" + day + \"_\" + domain;\n        } else {\n            key = digestType + \"_\" + domain;\n        }\n        return key;\n    }\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraMentionlineRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.repository.MentionlineRepository;\nimport org.springframework.stereotype.Repository;\nimport fr.ippon.tatami.config.ColumnFamilyKeys;\n\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * Cassandra implementation of the Userline repository.\n * <p/>\n * Structure :\n * - Key : login\n * - Name : status Id\n * - Value : \"\"\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraMentionlineRepository extends AbstractCassandraLineRepository implements MentionlineRepository {\n\n    @Override\n    public void addStatusToMentionline(String mentionedLogin, String statusId) {\n        addStatus(mentionedLogin, ColumnFamilyKeys.MENTIONLINE_CF, statusId);\n    }\n\n    @Override\n    public void removeStatusesFromMentionline(String mentionedLogin, Collection<String> statusIdsToDelete) {\n        removeStatuses(mentionedLogin, ColumnFamilyKeys.MENTIONLINE_CF, statusIdsToDelete);\n    }\n\n    @Override\n    public List<String> getMentionline(String login, int size, String start, String finish) {\n        return getLineFromCF(ColumnFamilyKeys.MENTIONLINE_CF, login, size, start, finish);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraRegistrationRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport com.google.common.collect.Maps;\nimport fr.ippon.tatami.repository.RegistrationRepository;\nimport fr.ippon.tatami.service.util.RandomUtil;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.ColumnSlice;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport me.prettyprint.hector.api.query.ColumnQuery;\nimport me.prettyprint.hector.api.query.SliceQuery;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Repository;\n\nimport javax.inject.Inject;\nimport java.util.List;\nimport java.util.Map;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.REGISTRATION_CF;\n\n/**\n * Cassandra implementation of the Registration repository.\n * <p/>\n * Structure :\n * - Key = \"registration_key\"\n * - Name = key\n * - Value = login\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraRegistrationRepository implements RegistrationRepository {\n\n    private static final Logger log = LoggerFactory.getLogger(CassandraRegistrationRepository.class);\n\n    private final static String ROW_KEY = \"registration_key\";\n\n    private final static int COLUMN_TTL = 60 * 60 * 24 * 2; // The column is stored for 2 days.\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    public String generateRegistrationKey(String login) {\n        String key = RandomUtil.generateRegistrationKey();\n        HColumn<String, String> column = HFactory.createColumn(key,\n                login, COLUMN_TTL, StringSerializer.get(), StringSerializer.get());\n\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(ROW_KEY, REGISTRATION_CF, column);\n        return key;\n    }\n\n    @Override\n    public String getLoginByRegistrationKey(String registrationKey) {\n        ColumnQuery<String, String, String> query = HFactory.createStringColumnQuery(keyspaceOperator);\n        HColumn<String, String> column =\n                query.setColumnFamily(REGISTRATION_CF)\n                        .setKey(ROW_KEY)\n                        .setName(registrationKey)\n                        .execute()\n                        .get();\n\n        if (column != null) {\n            return column.getValue();\n        } else {\n            return null;\n        }\n    }\n\n    /**\n     * !! For testing purpose only !!\n     * This method is not efficient and is limited to 10000 registrations.\n     * Other limitation : if a login is associated to multiple registrationKey\n     */\n    public Map<String, String> _getAllRegistrationKeyByLogin() {\n        log.warn(\"Calling _getAllRegistrationKeyByLogin() is only for testing purposes!\");\n        Map<String, String> registrationKeyByLogin = Maps.newHashMap();\n        SliceQuery<String, String, String> sliceQuery = HFactory.createSliceQuery(keyspaceOperator,\n                StringSerializer.get(), StringSerializer.get(), StringSerializer.get());\n\n        ColumnSlice<String, String> columnSlice =\n                sliceQuery.setColumnFamily(REGISTRATION_CF)\n                        .setKey(ROW_KEY)\n                        .setRange(null, null, false, 10000)\n                        .execute().get();\n\n        List<HColumn<String, String>> columns = columnSlice.getColumns();\n\n        for (HColumn<String, String> hColumn : columns) {\n            // WARN : here we don't handle multiple registrationKey for one login\n            registrationKeyByLogin.put(hColumn.getValue(), hColumn.getName());\n            log.debug(\"Key={}|Value={}\", hColumn.getValue(), hColumn.getName());\n        }\n        return registrationKeyByLogin;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraRssUidRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\r\n\r\nimport fr.ippon.tatami.repository.RssUidRepository;\r\nimport fr.ippon.tatami.service.util.RandomUtil;\r\nimport me.prettyprint.cassandra.serializers.StringSerializer;\r\nimport me.prettyprint.hector.api.Keyspace;\r\nimport me.prettyprint.hector.api.beans.HColumn;\r\nimport me.prettyprint.hector.api.factory.HFactory;\r\nimport me.prettyprint.hector.api.mutation.Mutator;\r\nimport me.prettyprint.hector.api.query.ColumnQuery;\r\nimport org.springframework.stereotype.Repository;\r\n\r\nimport javax.inject.Inject;\r\n\r\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.RSS_CF;\r\n\r\n/**\r\n * Cassandra implementation of the RssUid repository.\r\n * <p/>\r\n * Structure : - Key = \"rss_uid\" - Name = key - Value = login\r\n *\r\n * @author Pierre Rust\r\n */\r\n@Repository\r\npublic class CassandraRssUidRepository implements RssUidRepository {\r\n\r\n    private final static String ROW_KEY = \"rss_uid\";\r\n\r\n    @Inject\r\n    private Keyspace keyspaceOperator;\r\n\r\n    @Override\r\n    public String generateRssUid(String login) {\r\n        String key = RandomUtil.generateRegistrationKey();\r\n        HColumn<String, String> column = HFactory.createColumn(key,\r\n                login, StringSerializer.get(), StringSerializer.get());\r\n\r\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\r\n        mutator.insert(ROW_KEY, RSS_CF, column);\r\n        return key;\r\n    }\r\n\r\n    @Override\r\n    public String getLoginByRssUid(String rssUid) {\r\n        ColumnQuery<String, String, String> query = HFactory.createStringColumnQuery(keyspaceOperator);\r\n        HColumn<String, String> column =\r\n                query.setColumnFamily(RSS_CF)\r\n                        .setKey(ROW_KEY)\r\n                        .setName(rssUid)\r\n                        .execute()\r\n                        .get();\r\n\r\n        if (column != null) {\r\n            return column.getValue();\r\n        } else {\r\n            return null;\r\n        }\r\n    }\r\n\r\n    @Override\r\n    public void removeRssUid(String rssUid) {\r\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\r\n        mutator.delete(ROW_KEY, RSS_CF, rssUid, StringSerializer.get());\r\n    }\r\n}\r\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraSharesRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.repository.SharesRepository;\nimport me.prettyprint.cassandra.serializers.LongSerializer;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.ColumnSlice;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport org.springframework.cache.annotation.CacheEvict;\nimport org.springframework.cache.annotation.Cacheable;\nimport org.springframework.stereotype.Repository;\n\nimport javax.inject.Inject;\nimport java.util.Calendar;\nimport java.util.Collection;\nimport java.util.LinkedHashSet;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.SHARES_CF;\nimport static me.prettyprint.hector.api.factory.HFactory.createSliceQuery;\n\n/**\n * Cassandra implementation of the Shares repository.\n * Lists the shares for a given status.\n * <p/>\n * Structure :\n * - Key = status Id\n * - Name = time\n * - Value = login who shared this status\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraSharesRepository implements SharesRepository {\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    @CacheEvict(value = \"shared-cache\", key = \"#statusId\")\n    public void newShareByLogin(String statusId, String sharedByLogin) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(statusId, SHARES_CF,\n                HFactory.createColumn(\n                        Calendar.getInstance().getTimeInMillis(),\n                        sharedByLogin,\n                        LongSerializer.get(),\n                        StringSerializer.get()));\n    }\n\n   @Override\n   @Cacheable(\"shared-cache\")\n    public Collection<String> findLoginsWhoSharedAStatus(String statusId) {\n        ColumnSlice<Long, String> result = createSliceQuery(keyspaceOperator,\n                StringSerializer.get(), LongSerializer.get(), StringSerializer.get())\n                .setColumnFamily(SHARES_CF)\n                .setKey(statusId)\n                .setRange(null, null, false, 100) // Limit to 100 logins\n                .execute()\n                .get();\n\n        Collection<String> sharedByLogins = new LinkedHashSet<String>();\n        for (HColumn<Long, String> column : result.getColumns()) {\n            sharedByLogins.add(column.getValue());\n        }\n        return sharedByLogins;\n    }\n\n    @Override\n    public boolean hasBeenShared(String statusId) {\n        int zeroOrOne = HFactory.createCountQuery(keyspaceOperator, StringSerializer.get(), LongSerializer.get())\n                .setColumnFamily(SHARES_CF)\n                .setKey(statusId)\n                .setRange(null, null, 1)\n                .execute()\n                .get();\n\n        return zeroOrOne > 0;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraStatusAttachmentRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.config.Constants;\nimport fr.ippon.tatami.repository.StatusAttachmentRepository;\nimport me.prettyprint.cassandra.serializers.LongSerializer;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.cassandra.serializers.UUIDSerializer;\nimport me.prettyprint.cassandra.service.template.ColumnFamilyResult;\nimport me.prettyprint.cassandra.service.template.ColumnFamilyTemplate;\nimport me.prettyprint.cassandra.service.template.ThriftColumnFamilyTemplate;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport org.springframework.stereotype.Repository;\n\nimport javax.annotation.PostConstruct;\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Calendar;\nimport java.util.Collection;\nimport java.util.UUID;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.STATUS_ATTACHMENT_CF;\n\n/**\n * Cassandra implementation of the StatusAttachmentRepository repository.\n * <p/>\n * Structure :\n * - Key = statusId\n * - Name = attachmentId\n * - Value = time\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraStatusAttachmentRepository\n        implements StatusAttachmentRepository {\n\n    private ColumnFamilyTemplate<String, UUID> attachmentsTemplate;\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @PostConstruct\n    public void init() {\n        attachmentsTemplate = new ThriftColumnFamilyTemplate<String, UUID>(keyspaceOperator,\n                STATUS_ATTACHMENT_CF,\n                StringSerializer.get(),\n                UUIDSerializer.get());\n\n        attachmentsTemplate.setCount(Constants.CASSANDRA_MAX_COLUMNS);\n    }\n\n    @Override\n    public void addAttachmentId(String statusId, String attachmentId) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(statusId, STATUS_ATTACHMENT_CF, HFactory.createColumn(UUID.fromString(attachmentId),\n                Calendar.getInstance().getTimeInMillis(), UUIDSerializer.get(), LongSerializer.get()));\n    }\n\n    @Override\n    public void removeAttachmentId(String statusId, String attachmentId) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.delete(statusId, STATUS_ATTACHMENT_CF, UUID.fromString(attachmentId), UUIDSerializer.get());\n    }\n\n    @Override\n    public Collection<String> findAttachmentIds(String statusId) {\n        ColumnFamilyResult<String, UUID> result = attachmentsTemplate.queryColumns(statusId);\n        Collection<String> attachmentIds = new ArrayList<String>();\n        for (UUID columnName : result.getColumnNames()) {\n            attachmentIds.add(columnName.toString());\n        }\n        return attachmentIds;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraStatusReportRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.config.Constants;\nimport fr.ippon.tatami.config.GroupRoles;\nimport fr.ippon.tatami.repository.StatusReportRepository;\nimport me.prettyprint.cassandra.serializers.LongSerializer;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.cassandra.service.ColumnSliceIterator;\nimport me.prettyprint.cassandra.service.template.ColumnFamilyResult;\nimport me.prettyprint.cassandra.service.template.ColumnFamilyTemplate;\nimport me.prettyprint.cassandra.service.template.ColumnFamilyUpdater;\nimport me.prettyprint.cassandra.service.template.ThriftColumnFamilyTemplate;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.ColumnSlice;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.exceptions.HectorException;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport me.prettyprint.hector.api.query.SliceQuery;\nimport org.springframework.stereotype.Repository;\n\nimport javax.annotation.PostConstruct;\nimport javax.inject.Inject;\nimport java.util.*;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.GROUP_MEMBERS_CF;\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.STATUS_REPORT_CF;\nimport static me.prettyprint.hector.api.factory.HFactory.createSliceQuery;\n\n\n@Repository\npublic class CassandraStatusReportRepository implements StatusReportRepository {\n\n    private ColumnFamilyTemplate<String, String> reportedStatusTemplate;\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @PostConstruct\n    public void init() {\n        reportedStatusTemplate = new ThriftColumnFamilyTemplate<String, String>(keyspaceOperator,\n                STATUS_REPORT_CF,\n                StringSerializer.get(),\n                StringSerializer.get());\n        reportedStatusTemplate.setCount(Constants.CASSANDRA_MAX_COLUMNS);\n    }\n\n    @Override\n    public void reportStatus(String domain,  String reportedStatusId, String reportingLogin) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(domain, STATUS_REPORT_CF, HFactory.createStringColumn(reportedStatusId, reportingLogin));\n    }\n\n    @Override\n    public void unreportStatus(String domain,  String reportedStatusId) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.delete(domain, STATUS_REPORT_CF, reportedStatusId, StringSerializer.get());\n    }\n\n    @Override\n    public List<String> findReportedStatuses(String domain) {\n        SliceQuery<String, String, String> query = HFactory.createSliceQuery(keyspaceOperator, StringSerializer.get(),\n                StringSerializer.get(), StringSerializer.get()).\n                setKey(domain).setColumnFamily(STATUS_REPORT_CF);\n\n        ColumnSliceIterator<String, String, String> iterator =\n                new ColumnSliceIterator<String, String, String>(query, null, \"\\uFFFF\", false);\n\n        List<String> reportedStatuses = new ArrayList<String>();\n        while (iterator.hasNext()) {\n            reportedStatuses.add(iterator.next().getName());\n        }\n        return reportedStatuses;\n    }\n\n    public String findUserHavingReported(String domain, String statusId){\n        ColumnFamilyResult<String, String> res = reportedStatusTemplate.queryColumns(domain);\n        return res.getString(statusId);\n    }\n\n    @Override\n    public boolean hasBeenReportedByUser(String domain, String reportedStatusId, String login) {\n        return login.equals(reportedStatusTemplate.queryColumns(domain).getString(reportedStatusId));\n    }\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraStatusRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.domain.Attachment;\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.repository.*;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.cassandra.service.template.ColumnFamilyResult;\nimport me.prettyprint.cassandra.service.template.ColumnFamilyTemplate;\nimport me.prettyprint.cassandra.service.template.ColumnFamilyUpdater;\nimport me.prettyprint.cassandra.service.template.ThriftColumnFamilyTemplate;\nimport me.prettyprint.cassandra.utils.TimeUUIDUtils;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport org.apache.commons.lang.StringUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.cache.annotation.CacheEvict;\nimport org.springframework.cache.annotation.Cacheable;\nimport org.springframework.stereotype.Repository;\nimport fr.ippon.tatami.config.ColumnFamilyKeys;\nimport fr.ippon.tatami.domain.status.*;\n\nimport javax.annotation.PostConstruct;\nimport javax.inject.Inject;\nimport javax.validation.*;\nimport java.util.*;\n\n/**\n * Cassandra implementation of the status repository.\n * <p/>\n * Timeline and Userline have the same structure :\n * - Key : login\n * - Name : status Id\n * - Value : \"\"\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraStatusRepository implements StatusRepository {\n\n    private final Logger log = LoggerFactory.getLogger(CassandraStatusRepository.class);\n\n    private static final String LOGIN = \"login\";\n    private static final String TYPE = \"type\";\n    private static final String USERNAME = \"username\";\n    private static final String DOMAIN = \"domain\";\n    private static final String STATUS_DATE = \"statusDate\";\n\n    //Normal status\n    private static final String STATUS_PRIVATE = \"statusPrivate\";\n    private static final String GROUP_ID = \"groupId\";\n    private static final String HAS_ATTACHMENTS = \"hasAttachments\";\n    private static final String CONTENT = \"content\";\n    private static final String DISCUSSION_ID = \"discussionId\";\n    private static final String REPLY_TO = \"replyTo\";\n    private static final String REPLY_TO_USERNAME = \"replyToUsername\";\n    private static final String REMOVED = \"removed\";\n    private static final String GEO_LOCALIZATION = \"geoLocalization\";\n\n    //Share, Mention Share & Announcement\n    private static final String ORIGINAL_STATUS_ID = \"originalStatusId\";\n\n    //Mention Friend\n    private static final String FOLLOWER_LOGIN = \"followerLogin\";\n\n    //Bean validation\n    private static final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();\n    private static final Validator validator = factory.getValidator();\n\n    //Cassandra Template\n    ColumnFamilyTemplate<String, String> template;\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Inject\n    private DiscussionRepository discussionRepository;\n\n    @Inject\n    private SharesRepository sharesRepository;\n\n    @Inject\n    private StatusAttachmentRepository statusAttachmentRepository;\n\n    @Inject\n    private AttachmentRepository attachmentRepository;\n\n\n    @PostConstruct\n    public void init() {\n        template =\n                new ThriftColumnFamilyTemplate<String, String>(\n                        keyspaceOperator,\n                        ColumnFamilyKeys.STATUS_CF,\n                        StringSerializer.get(),\n                        StringSerializer.get());\n    }\n\n\n    @Override\n    public Status createStatus(String login,\n                               boolean statusPrivate,\n                               Group group,\n                               Collection<String> attachmentIds,\n                               String content,\n                               String discussionId,\n                               String replyTo,\n                               String replyToUsername,\n                               String geoLocalization)\n            throws ConstraintViolationException {\n\n        Status status = new Status();\n        status.setLogin(login);\n        status.setType(StatusType.STATUS);\n        String username = DomainUtil.getUsernameFromLogin(login);\n        status.setUsername(username);\n        String domain = DomainUtil.getDomainFromLogin(login);\n        status.setDomain(domain);\n\n        status.setContent(content);\n\n        Set<ConstraintViolation<Status>> constraintViolations = validator.validate(status);\n        if (!constraintViolations.isEmpty()) {\n            if (log.isDebugEnabled()) {\n                for (ConstraintViolation cv : constraintViolations) {\n                    log.debug(\"Constraint violation: {}\", cv.getMessage());\n                }\n            }\n            throw new ConstraintViolationException(new HashSet<ConstraintViolation<?>>(constraintViolations));\n        }\n\n        ColumnFamilyUpdater<String, String> updater = this.createBaseStatus(status);\n\n        updater.setString(CONTENT, content);\n\n        status.setStatusPrivate(statusPrivate);\n        updater.setBoolean(STATUS_PRIVATE, statusPrivate);\n\n        if (group != null) {\n            String groupId = group.getGroupId();\n            status.setGroupId(groupId);\n            updater.setString(GROUP_ID, groupId);\n        }\n\n        if (attachmentIds != null && attachmentIds.size() > 0) {\n            status.setHasAttachments(true);\n            updater.setBoolean(HAS_ATTACHMENTS, true);\n        }\n\n        if (discussionId != null) {\n            status.setDiscussionId(discussionId);\n            updater.setString(DISCUSSION_ID, discussionId);\n        }\n\n        if (replyTo != null) {\n            status.setReplyTo(replyTo);\n            updater.setString(REPLY_TO, replyTo);\n        }\n\n        if (replyToUsername != null) {\n            status.setReplyToUsername(replyToUsername);\n            updater.setString(REPLY_TO_USERNAME, replyToUsername);\n        }\n        if(geoLocalization!=null) {\n            status.setGeoLocalization(geoLocalization);\n            updater.setString(GEO_LOCALIZATION, geoLocalization);\n        }\n\n        log.debug(\"Persisting Status : {}\", status);\n\n\n        template.update(updater);\n        return status;\n    }\n\n    @Override\n    public Share createShare(String login, String originalStatusId) {\n        Share share = new Share();\n        share.setLogin(login);\n        share.setType(StatusType.SHARE);\n        String username = DomainUtil.getUsernameFromLogin(login);\n        share.setUsername(username);\n        String domain = DomainUtil.getDomainFromLogin(login);\n        share.setDomain(domain);\n        ColumnFamilyUpdater<String, String> updater = this.createBaseStatus(share);\n\n        updater.setString(ORIGINAL_STATUS_ID, originalStatusId);\n        share.setOriginalStatusId(originalStatusId);\n\n        log.debug(\"Persisting Share : {}\", share);\n\n        template.update(updater);\n        return share;\n    }\n\n    @Override\n    public Announcement createAnnouncement(String login, String originalStatusId) {\n        Announcement announcement = new Announcement();\n        announcement.setLogin(login);\n        announcement.setType(StatusType.ANNOUNCEMENT);\n        String username = DomainUtil.getUsernameFromLogin(login);\n        announcement.setUsername(username);\n        String domain = DomainUtil.getDomainFromLogin(login);\n        announcement.setDomain(domain);\n        ColumnFamilyUpdater<String, String> updater = this.createBaseStatus(announcement);\n\n        updater.setString(ORIGINAL_STATUS_ID, originalStatusId);\n        announcement.setOriginalStatusId(originalStatusId);\n\n        log.debug(\"Persisting Announcement : {}\", announcement);\n\n        template.update(updater);\n        return announcement;\n    }\n\n    @Override\n    public MentionFriend createMentionFriend(String login, String followerLogin) {\n        MentionFriend mentionFriend = new MentionFriend();\n        mentionFriend.setLogin(login);\n        mentionFriend.setType(StatusType.MENTION_FRIEND);\n        String username = DomainUtil.getUsernameFromLogin(login);\n        mentionFriend.setUsername(username);\n        String domain = DomainUtil.getDomainFromLogin(login);\n        mentionFriend.setDomain(domain);\n        ColumnFamilyUpdater<String, String> updater = this.createBaseStatus(mentionFriend);\n\n        updater.setString(FOLLOWER_LOGIN, followerLogin);\n\n\n        log.debug(\"Persisting MentionFriend : {}\", mentionFriend);\n\n        template.update(updater);\n        return mentionFriend;\n    }\n\n    @Override\n    public MentionShare createMentionShare(String login, String originalStatusId) {\n        MentionShare mentionShare = new MentionShare();\n        mentionShare.setLogin(login);\n        mentionShare.setType(StatusType.MENTION_SHARE);\n        String username = DomainUtil.getUsernameFromLogin(login);\n        mentionShare.setUsername(username);\n        String domain = DomainUtil.getDomainFromLogin(login);\n        mentionShare.setDomain(domain);\n        ColumnFamilyUpdater<String, String> updater = this.createBaseStatus(mentionShare);\n\n        updater.setString(ORIGINAL_STATUS_ID, originalStatusId);\n        mentionShare.setOriginalStatusId(originalStatusId);\n\n\n        log.debug(\"Persisting MentionShare : {}\", mentionShare);\n\n        template.update(updater);\n        return mentionShare;\n    }\n\n    private ColumnFamilyUpdater<String, String> createBaseStatus(AbstractStatus abstractStatus) {\n        // Generate statusId and statusDate for all statuses\n        String statusId = TimeUUIDUtils.getUniqueTimeUUIDinMillis().toString();\n        abstractStatus.setStatusId(statusId);\n        ColumnFamilyUpdater<String, String> updater = template.createUpdater(statusId);\n\n        Date statusDate = Calendar.getInstance().getTime();\n        updater.setDate(STATUS_DATE, statusDate);\n        abstractStatus.setStatusDate(statusDate);\n\n        // Persist common data : login, username, domain, type\n        String login = abstractStatus.getLogin();\n        if (login == null) {\n            throw new IllegalStateException(\"Login cannot be null for status: \" + abstractStatus);\n        }\n        updater.setString(LOGIN, login);\n\n        String username = abstractStatus.getUsername();\n        if (username == null) {\n            throw new IllegalStateException(\"Username cannot be null for status: \" + abstractStatus);\n        }\n        updater.setString(USERNAME, username);\n\n        String domain = abstractStatus.getDomain();\n        if (domain == null) {\n            throw new IllegalStateException(\"Domain cannot be null for status: \" + abstractStatus);\n        }\n        updater.setString(DOMAIN, domain);\n\n        updater.setString(TYPE, abstractStatus.getType().name());\n\n        return updater;\n    }\n\n\n    @Override\n    @Cacheable(\"status-cache\")\n    public AbstractStatus findStatusById(String statusId) {\n        if (statusId == null || statusId.equals(\"\")) {\n            return null;\n        }\n        if (log.isTraceEnabled()) {\n            log.trace(\"Finding status : \" + statusId);\n        }\n\n        ColumnFamilyResult<String, String> result = template.queryColumns(statusId);\n\n        if (result.hasResults() == false) {\n            return null; // No status was found\n        }\n        AbstractStatus status = null;\n        String type = result.getString(TYPE);\n        if (type == null || type.equals(StatusType.STATUS.name())) {\n            status = findStatus(result, statusId);\n        } else if (type.equals(StatusType.SHARE.name())) {\n            status = findShare(result);\n        } else if (type.equals(StatusType.ANNOUNCEMENT.name())) {\n            status = findAnnouncement(result);\n        } else if (type.equals(StatusType.MENTION_FRIEND.name())) {\n            status = findMentionFriend(result);\n        } else if (type.equals(StatusType.MENTION_SHARE.name())) {\n            status = findMentionShare(result);\n        } else {\n            throw new IllegalStateException(\"Status has an unknown type: \" + type);\n        }\n        if (status == null) { // Status was not found, or was removed\n            return null;\n        }\n        status.setStatusId(statusId);\n        status.setLogin(result.getString(LOGIN));\n        status.setUsername(result.getString(USERNAME));\n\n        String domain = result.getString(DOMAIN);\n        if (domain != null) {\n            status.setDomain(domain);\n        } else {\n            throw new IllegalStateException(\"Status cannot have a null domain: \" + status);\n        }\n\n        status.setStatusDate(result.getDate(STATUS_DATE));\n        Boolean removed = result.getBoolean(REMOVED);\n        if (removed != null) {\n            status.setRemoved(removed);\n        }\n        return status;\n    }\n\n    private Status findStatus(ColumnFamilyResult<String, String> result, String statusId) {\n        Status status = new Status();\n        status.setStatusId(statusId);\n        status.setType(StatusType.STATUS);\n        status.setContent(result.getString(CONTENT));\n        status.setStatusPrivate(result.getBoolean(STATUS_PRIVATE));\n        status.setGroupId(result.getString(GROUP_ID));\n        status.setHasAttachments(result.getBoolean(HAS_ATTACHMENTS));\n        status.setDiscussionId(result.getString(DISCUSSION_ID));\n        status.setReplyTo(result.getString(REPLY_TO));\n        status.setReplyToUsername(result.getString(REPLY_TO_USERNAME));\n        status.setGeoLocalization(result.getString(GEO_LOCALIZATION));\n        status.setRemoved(result.getBoolean(REMOVED));\n        if (status.getRemoved() == Boolean.TRUE) {\n            return null;\n        }\n        status.setDetailsAvailable(computeDetailsAvailable(status));\n        if (status.getHasAttachments() != null && status.getHasAttachments()) {\n            Collection<String> attachmentIds = statusAttachmentRepository.findAttachmentIds(statusId);\n            Collection<Attachment> attachments = new ArrayList<Attachment>();\n            for (String attachmentId : attachmentIds) {\n                Attachment attachment = attachmentRepository.findAttachmentMetadataById(attachmentId);\n                if (attachment != null) {\n                    // We copy everything excepted the attachment content, as we do not want it in the status cache\n                    Attachment attachmentCopy = new Attachment();\n                    attachmentCopy.setAttachmentId(attachmentId);\n                    attachmentCopy.setSize(attachment.getSize());\n                    attachmentCopy.setFilename(attachment.getFilename());\n                    attachments.add(attachment);\n                }\n            }\n            status.setAttachments(attachments);\n        }\n        return status;\n    }\n\n    private Share findShare(ColumnFamilyResult<String, String> result) {\n        Share share = new Share();\n        share.setType(StatusType.SHARE);\n        share.setOriginalStatusId(result.getString(ORIGINAL_STATUS_ID));\n        return share;\n    }\n\n    private Announcement findAnnouncement(ColumnFamilyResult<String, String> result) {\n        Announcement announcement = new Announcement();\n        announcement.setType(StatusType.ANNOUNCEMENT);\n        announcement.setOriginalStatusId(result.getString(ORIGINAL_STATUS_ID));\n        return announcement;\n    }\n\n    private MentionFriend findMentionFriend(ColumnFamilyResult<String, String> result) {\n        MentionFriend mentionFriend = new MentionFriend();\n        mentionFriend.setType(StatusType.MENTION_FRIEND);\n        mentionFriend.setFollowerLogin(result.getString(FOLLOWER_LOGIN));\n        return mentionFriend;\n    }\n\n    private MentionShare findMentionShare(ColumnFamilyResult<String, String> result) {\n        MentionShare mentionShare = new MentionShare();\n        mentionShare.setType(StatusType.MENTION_SHARE);\n        mentionShare.setOriginalStatusId(result.getString(ORIGINAL_STATUS_ID));\n        return mentionShare;\n    }\n\n    @Override\n    @CacheEvict(value = \"status-cache\", key = \"#status.statusId\")\n    public void removeStatus(AbstractStatus status) {\n        log.debug(\"Removing Status : {}\", status);\n\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.addDeletion(status.getStatusId(), ColumnFamilyKeys.STATUS_CF);\n        mutator.execute();\n    }\n\n    private boolean computeDetailsAvailable(Status status) {\n        boolean detailsAvailable = false;\n        if (status.getType().equals(StatusType.STATUS)) {\n            if (StringUtils.isNotBlank(status.getReplyTo())) {\n                detailsAvailable = true;\n            } else if (discussionRepository.hasReply(status.getStatusId())) {\n                detailsAvailable = true;\n            } else if (sharesRepository.hasBeenShared(status.getStatusId())) {\n                detailsAvailable = true;\n            }\n        }\n        return detailsAvailable;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraTagCounterRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.repository.TagCounterRepository;\nimport me.prettyprint.cassandra.model.thrift.ThriftCounterColumnQuery;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport me.prettyprint.hector.api.query.CounterQuery;\nimport org.springframework.stereotype.Repository;\n\nimport javax.inject.Inject;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.TAG_COUNTER_CF;\n\n/**\n * Cassandra implementation of the Tag Counter repository.\n * <p/>\n * Structure :\n * - Key = tag + domain\n * - Name = TAG_COUNTER\n * - Value = count\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraTagCounterRepository implements TagCounterRepository {\n\n    private static final String TAG_COUNTER = \"TAG_COUNTER\";\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    public long getTagCounter(String domain, String tag) {\n        CounterQuery<String, String> counter =\n                new ThriftCounterColumnQuery<String, String>(keyspaceOperator,\n                        StringSerializer.get(),\n                        StringSerializer.get());\n\n        counter.setColumnFamily(TAG_COUNTER_CF).setKey(getKey(domain, tag)).setName(TAG_COUNTER);\n        return counter.execute().get().getValue();\n    }\n\n    @Override\n    public void incrementTagCounter(String domain, String tag) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.incrementCounter(getKey(domain, tag), TAG_COUNTER_CF, TAG_COUNTER, 1);\n    }\n\n    @Override\n    public void decrementTagCounter(String domain, String tag) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.decrementCounter(getKey(domain, tag), TAG_COUNTER_CF, TAG_COUNTER, 1);\n    }\n\n    @Override\n    public void deleteTagCounter(String domain, String tag) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.addCounterDeletion(getKey(domain, tag), TAG_COUNTER_CF, TAG_COUNTER, StringSerializer.get());\n        mutator.execute();\n    }\n\n    /**\n     * Generates the key for this column family.\n     */\n    private String getKey(String domain, String tag) {\n        return tag.toLowerCase() + \"-\" + domain;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraTagFollowerRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.repository.TagFollowerRepository;\nimport org.springframework.stereotype.Repository;\nimport fr.ippon.tatami.config.ColumnFamilyKeys;\n\nimport java.util.Collection;\n\n/**\n * Cassandra implementation of the Follower repository.\n * <p/>\n * Structure :\n * - Key = tag + domain\n * - Name = follower login\n * - Value = time\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraTagFollowerRepository\n        extends AbstractCassandraFollowerRepository\n        implements TagFollowerRepository {\n\n    @Override\n    public void addFollower(String domain, String tag, String login) {\n        super.addFollower(getKey(domain, tag), login);\n    }\n\n    @Override\n    public void removeFollower(String domain, String tag, String login) {\n        super.removeFollower(getKey(domain, tag), login);\n    }\n\n    @Override\n    public Collection<String> findFollowers(String domain, String tag) {\n        return super.findFollowers(getKey(domain, tag));\n    }\n\n    @Override\n    public String getFollowersCF() {\n        return ColumnFamilyKeys.TAG_FOLLOWERS_CF;\n    }\n\n    /**\n     * Generates the key for this column family.\n     */\n    private String getKey(String domain, String tag) {\n        return tag.toLowerCase() + \"-\" + domain;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraTaglineRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.domain.status.Status;\nimport fr.ippon.tatami.repository.TaglineRepository;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.cassandra.serializers.UUIDSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport org.springframework.stereotype.Repository;\n\nimport javax.inject.Inject;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.UUID;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.TAGLINE_CF;\n\n/**\n * Cassandra implementation of the Tag line repository.\n * <p/>\n * Structure :\n * - Key = tag + domain\n * - Name = statusId\n * - Value = \"\"\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraTaglineRepository extends AbstractCassandraLineRepository implements TaglineRepository {\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    public void addStatusToTagline(String tag, Status status) {\n        addStatus(getKey(status.getDomain(), tag), TAGLINE_CF, status.getStatusId());\n    }\n\n    @Override\n    public void removeStatusesFromTagline(String tag, String domain, Collection<String> statusIdsToDelete) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        for (String statusId : statusIdsToDelete) {\n            mutator.addDeletion(\n                    getKey(domain, tag),\n                    TAGLINE_CF,\n                    UUID.fromString(statusId),\n                    UUIDSerializer.get());\n\n        }\n        mutator.execute();\n\n    }\n\n    @Override\n    public List<String> getTagline(String domain, String tag, int size, String start, String finish) {\n        return getLineFromCF(TAGLINE_CF, getKey(domain, tag), size, start, finish);\n    }\n\n    /**\n     * Generates the key for this column family.\n     */\n    private String getKey(String domain, String tag) {\n        return tag.toLowerCase() + \"-\" + domain;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraTimelineRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.domain.status.Announcement;\nimport fr.ippon.tatami.domain.status.Share;\nimport fr.ippon.tatami.repository.TimelineRepository;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.cassandra.serializers.UUIDSerializer;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport me.prettyprint.hector.api.query.QueryResult;\nimport org.springframework.stereotype.Repository;\n\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.UUID;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.TIMELINE_CF;\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.TIMELINE_SHARES_CF;\n\n/**\n * Cassandra implementation of the Timeline repository.\n * <p/>\n * Structure :\n * - Key : login\n * - Name : status Id\n * - Value : \"\"\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraTimelineRepository extends AbstractCassandraLineRepository implements TimelineRepository {\n\n    @Override\n    public boolean isStatusInTimeline(String login, String statusId) {\n        QueryResult<HColumn<UUID, String>> isStatusAlreadyinTimeline =\n                findByLoginAndStatusId(TIMELINE_CF, login, UUID.fromString(statusId));\n\n        return isStatusAlreadyinTimeline.get() != null;\n    }\n\n    @Override\n    public void addStatusToTimeline(String login, String statusId) {\n        addStatus(login, TIMELINE_CF, statusId);\n    }\n\n    @Override\n    public void removeStatusesFromTimeline(String login, Collection<String> statusIdsToDelete) {\n        removeStatuses(login, TIMELINE_CF, statusIdsToDelete);\n    }\n\n    @Override\n    public void shareStatusToTimeline(String sharedByLogin, String timelineLogin, Share share) {\n        shareStatus(timelineLogin, share, TIMELINE_CF, TIMELINE_SHARES_CF);\n    }\n\n    @Override\n    public void announceStatusToTimeline(String announcedByLogin, List<String> logins, Announcement announcement) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n\n        for (String login : logins) {\n            mutator.addInsertion(login, TIMELINE_CF, HFactory.createColumn(UUID.fromString(announcement.getStatusId()),\n                    \"\", UUIDSerializer.get(), StringSerializer.get()));\n        }\n        mutator.execute();\n    }\n\n    @Override\n    public List<String> getTimeline(String login, int size, String start, String finish) {\n        return getLineFromCF(TIMELINE_CF, login, size, start, finish);\n    }\n\n    @Override\n    public void deleteTimeline(String login) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.addDeletion(login, TIMELINE_CF);\n        mutator.execute();\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraTrendRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.repository.TrendRepository;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.cassandra.serializers.UUIDSerializer;\nimport me.prettyprint.cassandra.utils.TimeUUIDUtils;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.ColumnSlice;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport org.springframework.cache.annotation.CacheEvict;\nimport org.springframework.cache.annotation.Cacheable;\nimport org.springframework.stereotype.Repository;\nimport org.springframework.util.Assert;\n\nimport javax.inject.Inject;\nimport java.util.*;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.TRENDS_CF;\nimport static me.prettyprint.hector.api.factory.HFactory.createSliceQuery;\n\n/**\n * Cassandra implementation of the Trends repository.\n * <p/>\n * Structure :\n * - Key = domain\n * - Name = date\n * - Value = tag\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraTrendRepository implements TrendRepository {\n\n    private final static int COLUMN_TTL = 60 * 60 * 24 * 30; // The column is stored for 30 days.\n\n    private final static int TRENDS_NUMBER_OF_TAGS = 100;\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    @CacheEvict(value = \"domain-tags-cache\", key = \"#domain\")\n    public void addTag(String domain, String tag) {\n        HColumn<UUID, String> column =\n                HFactory.createColumn(\n                        TimeUUIDUtils.getUniqueTimeUUIDinMillis(),\n                        tag,\n                        COLUMN_TTL,\n                        UUIDSerializer.get(),\n                        StringSerializer.get());\n\n        Mutator<String> mutator =\n                HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n\n        mutator.insert(domain, TRENDS_CF, column);\n    }\n\n    @Override\n    public List<String> getRecentTags(String domain) {\n        return getRecentTags(domain, TRENDS_NUMBER_OF_TAGS);\n    }\n\n    @Override\n    public List<String> getRecentTags(String domain, int maxNumber) {\n        ColumnSlice<UUID, String> query = createSliceQuery(keyspaceOperator,\n                StringSerializer.get(), UUIDSerializer.get(), StringSerializer.get())\n                .setColumnFamily(TRENDS_CF)\n                .setKey(domain)\n                .setRange(null, null, true, maxNumber)\n                .execute()\n                .get();\n\n        List<String> result = new ArrayList<String>();\n        String tag;\n        for (HColumn<UUID, String> column : query.getColumns()) {\n            tag = column.getValue();\n            result.add(tag);\n        }\n        return result;\n    }\n\n    @Cacheable(value = \"domain-tags-cache\", key = \"#domain\")\n    public Collection<String> getDomainTags(String domain) {\n        Assert.hasLength(domain);\n\n        final ColumnSlice<UUID, String> query = createSliceQuery(keyspaceOperator,\n                StringSerializer.get(), UUIDSerializer.get(), StringSerializer.get())\n                .setColumnFamily(TRENDS_CF)\n                .setKey(domain)\n                .setRange(null, null, true, TRENDS_NUMBER_OF_TAGS)\n                .execute()\n                .get();\n\n        final Map<String, String> result = new HashMap<String, String>();\n        String tag;\n        for (HColumn<UUID, String> column : query.getColumns()) {\n            tag = column.getValue();\n            result.put(tag.toLowerCase(), tag);\n        }\n        return result.values();\n    }\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraUserAttachmentRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.config.Constants;\nimport fr.ippon.tatami.repository.UserAttachmentRepository;\nimport me.prettyprint.cassandra.serializers.LongSerializer;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.cassandra.serializers.UUIDSerializer;\nimport me.prettyprint.cassandra.service.template.ColumnFamilyResult;\nimport me.prettyprint.cassandra.service.template.ColumnFamilyTemplate;\nimport me.prettyprint.cassandra.service.template.ThriftColumnFamilyTemplate;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.ColumnSlice;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport org.springframework.stereotype.Repository;\nimport fr.ippon.tatami.config.ColumnFamilyKeys;\n\nimport javax.annotation.PostConstruct;\nimport javax.inject.Inject;\nimport java.util.*;\n\nimport static me.prettyprint.hector.api.factory.HFactory.createSliceQuery;\n\n/**\n * Cassandra implementation of the UserAttachment repository.\n * <p/>\n * Structure :\n * - Key = login\n * - Name = attachmentId\n * - Value = time\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraUserAttachmentRepository\n        implements UserAttachmentRepository {\n\n    private ColumnFamilyTemplate<String, UUID> attachmentsTemplate;\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @PostConstruct\n    public void init() {\n        attachmentsTemplate = new ThriftColumnFamilyTemplate<String, UUID>(keyspaceOperator,\n                ColumnFamilyKeys.USER_ATTACHMENT_CF,\n                StringSerializer.get(),\n                UUIDSerializer.get());\n\n        attachmentsTemplate.setCount(Constants.CASSANDRA_MAX_COLUMNS);\n    }\n\n    @Override\n    public void addAttachmentId(String login, String attachmentId) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(login, ColumnFamilyKeys.USER_ATTACHMENT_CF, HFactory.createColumn(UUID.fromString(attachmentId),\n                Calendar.getInstance().getTimeInMillis(), UUIDSerializer.get(), LongSerializer.get()));\n    }\n\n    @Override\n    public void removeAttachmentId(String login, String attachmentId) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.delete(login, ColumnFamilyKeys.USER_ATTACHMENT_CF, UUID.fromString(attachmentId), UUIDSerializer.get());\n    }\n\n    @Override\n    public Collection<String> findAttachmentIds(String login, int pagination, String finish) {\n        List<HColumn<UUID, Long>> result;\n        if (finish != null) {\n        ColumnSlice<UUID, Long> query = createSliceQuery(keyspaceOperator,\n                StringSerializer.get(), UUIDSerializer.get(), LongSerializer.get())\n                .setColumnFamily(ColumnFamilyKeys.USER_ATTACHMENT_CF)\n                .setKey(login)\n                .setRange(UUID.fromString(finish), null, true, pagination)\n                .execute()\n                .get();\n\n        result = query.getColumns();\n        }  else {\n            ColumnSlice<UUID, Long> query = createSliceQuery(keyspaceOperator,\n                    StringSerializer.get(), UUIDSerializer.get(), LongSerializer.get())\n                    .setColumnFamily(ColumnFamilyKeys.USER_ATTACHMENT_CF)\n                    .setKey(login)\n                    .setRange(null, null, true, pagination)\n                    .execute()\n                    .get();\n\n            result = query.getColumns();\n        }\n\n        Collection<String> attachmentIds = new ArrayList<String>();\n        int index = 0;\n        for (HColumn<UUID, Long> column : result) {\n            attachmentIds.add(column.getName().toString());\n            index++;\n        }\n        return attachmentIds;\n    }\n\n    @Override\n    public Collection<String> findAttachmentIds(String login) {\n        ColumnFamilyResult<String, UUID> result = attachmentsTemplate.queryColumns(login);\n        Collection<String> attachmentIds = new ArrayList<String>();\n        for (UUID columnName : result.getColumnNames()) {\n            attachmentIds.add(columnName.toString());\n        }\n        return attachmentIds;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraUserGroupRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.config.GroupRoles;\nimport fr.ippon.tatami.repository.UserGroupRepository;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.ColumnSlice;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport org.springframework.stereotype.Repository;\n\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.USER_GROUPS_CF;\nimport static me.prettyprint.hector.api.factory.HFactory.createSliceQuery;\n\n/**\n * Cassandra implementation of the User groups repository.\n * <p/>\n * Structure :\n * - Key = login\n * - Name = group ID\n * - Value = role\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraUserGroupRepository implements UserGroupRepository {\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    public void addGroupAsMember(String login, String groupId) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(login, USER_GROUPS_CF, HFactory.createColumn(groupId,\n                GroupRoles.MEMBER, StringSerializer.get(), StringSerializer.get()));\n    }\n\n    @Override\n    public void addGroupAsAdmin(String login, String groupId) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(login, USER_GROUPS_CF, HFactory.createColumn(groupId,\n                GroupRoles.ADMIN, StringSerializer.get(), StringSerializer.get()));\n    }\n\n    @Override\n    public void removeGroup(String login, String groupId) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.delete(login, USER_GROUPS_CF, groupId, StringSerializer.get());\n    }\n\n    @Override\n    public List<String> findGroups(String login) {\n        List<String> groups = new ArrayList<String>();\n        ColumnSlice<String, String> result = createSliceQuery(keyspaceOperator,\n                StringSerializer.get(), StringSerializer.get(), StringSerializer.get())\n                .setColumnFamily(USER_GROUPS_CF)\n                .setKey(login)\n                .setRange(null, null, false, Integer.MAX_VALUE)\n                .execute()\n                .get();\n\n        for (HColumn<String, String> column : result.getColumns()) {\n            groups.add(column.getName());\n        }\n        return groups;\n    }\n\n    @Override\n    public Collection<String> findGroupsAsAdmin(String login) {\n        List<String> groups = new ArrayList<String>();\n        ColumnSlice<String, String> result = createSliceQuery(keyspaceOperator,\n                StringSerializer.get(), StringSerializer.get(), StringSerializer.get())\n                .setColumnFamily(USER_GROUPS_CF)\n                .setKey(login)\n                .setRange(null, null, false, Integer.MAX_VALUE)\n                .execute()\n                .get();\n\n        for (HColumn<String, String> column : result.getColumns()) {\n            if (column.getValue() != null && column.getValue().equals(GroupRoles.ADMIN)) {\n                groups.add(column.getName());\n            }\n        }\n        return groups;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraUserRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.domain.validation.ContraintsUserCreation;\nimport fr.ippon.tatami.repository.CounterRepository;\nimport fr.ippon.tatami.repository.UserRepository;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport me.prettyprint.hom.EntityManagerImpl;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.cache.annotation.CacheEvict;\nimport org.springframework.cache.annotation.Cacheable;\nimport org.springframework.stereotype.Repository;\nimport fr.ippon.tatami.config.ColumnFamilyKeys;\n\nimport javax.inject.Inject;\nimport javax.validation.*;\nimport java.util.HashSet;\nimport java.util.Set;\n\n/**\n * Cassandra implementation of the user repository.\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraUserRepository implements UserRepository {\n\n    private final Logger log = LoggerFactory.getLogger(CassandraUserRepository.class);\n\n    @Inject\n    private EntityManagerImpl em;\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Inject\n    private CounterRepository counterRepository;\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    private static final ValidatorFactory factory = Validation.buildDefaultValidatorFactory();\n    private static final Validator validator = factory.getValidator();\n\n    @Override\n    @CacheEvict(value = \"user-cache\", key = \"#user.login\")\n    public void createUser(User user) {\n\n        log.debug(\"Creating user : {}\", user);\n\n        Set<ConstraintViolation<User>> constraintViolations = validator.validate(user, ContraintsUserCreation.class);\n        if (!constraintViolations.isEmpty()) {\n            throw new ConstraintViolationException(new HashSet<ConstraintViolation<?>>(constraintViolations));\n        }\n        em.persist(user);\n    }\n\n    @Override\n    @CacheEvict(value = \"user-cache\", key = \"#user.login\", beforeInvocation = true)\n    public void updateUser(User user) throws ConstraintViolationException, IllegalArgumentException {\n        log.debug(\"Updating user : {}\", user);\n        Set<ConstraintViolation<User>> constraintViolations = validator.validate(user);\n        if (!constraintViolations.isEmpty()) {\n            throw new ConstraintViolationException(new HashSet<ConstraintViolation<?>>(constraintViolations));\n        }\n        em.persist(user);\n    }\n\n    @Override\n    @CacheEvict(value = \"user-cache\", key = \"#user.login\")\n    public void deleteUser(User user) {\n        log.debug(\"Deleting user : {}\", user);\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.addDeletion(user.getLogin(), ColumnFamilyKeys.USER_CF);\n        mutator.execute();\n    }\n\n    @Override\n    @Cacheable(\"user-cache\")\n    public User findUserByLogin(String login) {\n        User user;\n        try {\n            user = em.find(User.class, login);\n        } catch (Exception e) {\n            log.debug(\"Exception while looking for user {} : {}\", login, e.toString());\n            return null;\n        }\n        if (user != null) {\n            user.setStatusCount(counterRepository.getStatusCounter(login));\n            user.setFollowersCount(counterRepository.getFollowersCounter(login));\n            user.setFriendsCount(counterRepository.getFriendsCounter(login));\n            user.setIsAdmin(authenticationService.isCurrentUserInRole(\"ROLE_ADMIN\"));\n        }\n        return user;\n    }\n\n    @Override\n    @CacheEvict(value = \"user-cache\", key = \"#user.login\")\n    public void desactivateUser( User user ) {\n        user.setActivated(false);\n        em.persist(user);\n    }\n\n    @Override\n    @CacheEvict(value = \"user-cache\", key = \"#user.login\")\n    public void reactivateUser( User user ) {\n        user.setActivated(true);\n        em.persist(user);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraUserTagRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.repository.UserTagRepository;\nimport org.springframework.stereotype.Repository;\nimport fr.ippon.tatami.config.ColumnFamilyKeys;\n\nimport java.util.Collection;\n\n/**\n * Cassandra implementation of the TagFriend repository.\n * <p/>\n * Structure :\n * - Key = login\n * - Name = tag + domain\n * - Value = time\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraUserTagRepository\n        extends AbstractCassandraFriendRepository\n        implements UserTagRepository {\n\n    @Override\n    public void addTag(String login, String friendTag) {\n        super.addFriend(login, friendTag);\n    }\n\n    @Override\n    public void removeTag(String login, String friendTag) {\n        super.removeFriend(login, friendTag);\n    }\n\n    @Override\n    public Collection<String> findTags(String login) {\n        return super.findFriends(login);\n    }\n\n    @Override\n    public String getFriendsCF() {\n        return ColumnFamilyKeys.USER_TAGS_CF;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraUserTrendRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.repository.UserTrendRepository;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.cassandra.serializers.UUIDSerializer;\nimport me.prettyprint.cassandra.utils.TimeUUIDUtils;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.ColumnSlice;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport org.springframework.stereotype.Repository;\nimport fr.ippon.tatami.config.ColumnFamilyKeys;\n\nimport javax.inject.Inject;\nimport java.util.*;\n\nimport static me.prettyprint.hector.api.factory.HFactory.createSliceQuery;\n\n/**\n * Cassandra implementation of the User Trends repository.\n * <p/>\n * Structure :\n * - Key = login\n * - Name = date\n * - Value = tag\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraUserTrendRepository implements UserTrendRepository {\n\n    private final static int COLUMN_TTL = 60 * 60 * 24 * 90; // The column is stored for 90 days.\n\n    private final static int TRENDS_NUMBER_OF_TAGS = 50;\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Override\n    public void addTag(String login, String tag) {\n        HColumn<UUID, String> column =\n                HFactory.createColumn(\n                        TimeUUIDUtils.getUniqueTimeUUIDinMillis(),\n                        tag,\n                        COLUMN_TTL,\n                        UUIDSerializer.get(),\n                        StringSerializer.get());\n\n        Mutator<String> mutator =\n                HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n\n        mutator.insert(login, ColumnFamilyKeys.USER_TRENDS_CF, column);\n    }\n\n    @Override\n    public List<String> getRecentTags(String login) {\n        ColumnSlice<UUID, String> query = createSliceQuery(keyspaceOperator,\n                StringSerializer.get(), UUIDSerializer.get(), StringSerializer.get())\n                .setColumnFamily(ColumnFamilyKeys.USER_TRENDS_CF)\n                .setKey(login)\n                .setRange(null, null, true, TRENDS_NUMBER_OF_TAGS)\n                .execute()\n                .get();\n\n        List<String> result = new ArrayList<String>();\n        for (HColumn<UUID, String> column : query.getColumns()) {\n            String tag = column.getValue();\n            result.add(tag);\n        }\n        return result;\n    }\n\n    @Override\n    public Collection<String> getUserRecentTags(String login, Date endDate,\n                                                int nbRecentTags) {\n        ColumnSlice<UUID, String> query = createSliceQuery(keyspaceOperator,\n                StringSerializer.get(), UUIDSerializer.get(), StringSerializer.get())\n                .setColumnFamily(ColumnFamilyKeys.USER_TRENDS_CF)\n                .setKey(login)\n                .setRange(null, TimeUUIDUtils.getTimeUUID(endDate.getTime()), true, nbRecentTags)\n                .execute()\n                .get();\n        Map<String, String> result = new HashMap<String, String>();\n        String tag;\n        for (HColumn<UUID, String> column : query.getColumns()) {\n            tag = column.getValue();\n            result.put(tag.toLowerCase(), tag);\n        }\n        return result.values();\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraUserlineRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.domain.status.Share;\nimport fr.ippon.tatami.repository.UserlineRepository;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport org.springframework.stereotype.Repository;\n\nimport java.util.Collection;\nimport java.util.List;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.USERLINE_CF;\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.USERLINE_SHARES_CF;\n\n/**\n * Cassandra implementation of the Userline repository.\n * <p/>\n * Structure :\n * - Key : login\n * - Name : status Id\n * - Value : \"\"\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraUserlineRepository extends AbstractCassandraLineRepository implements UserlineRepository {\n\n    @Override\n    public void addStatusToUserline(String login, String statusId) {\n        addStatus(login,USERLINE_CF, statusId);\n    }\n\n    @Override\n    public void removeStatusesFromUserline(String login, Collection<String> statusIdsToDelete) {\n        removeStatuses(login, USERLINE_CF, statusIdsToDelete);\n    }\n\n    @Override\n    public void shareStatusToUserline(String currentLogin, Share share) {\n        shareStatus(currentLogin, share, USERLINE_CF, USERLINE_SHARES_CF);\n    }\n\n    @Override\n    public List<String> getUserline(String login, int size, String start, String finish) {\n        return getLineFromCF(USERLINE_CF, login, size, start, finish);\n    }\n\n    @Override\n    public void deleteUserline(String login) {\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.addDeletion(login, USERLINE_CF);\n        mutator.execute();\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/security/AjaxAuthenticationFailureHandler.java",
    "content": "package fr.ippon.tatami.security;\n\nimport org.springframework.security.core.AuthenticationException;\nimport org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;\nimport org.springframework.stereotype.Component;\n\nimport javax.servlet.ServletException;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.IOException;\n\n/**\n * Returns a 401 error code (Unauthorized) to the client, when Ajax authentication fails.\n */\n@Component\npublic class AjaxAuthenticationFailureHandler extends SimpleUrlAuthenticationFailureHandler {\n\n    @Override\n    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,\n        AuthenticationException exception) throws IOException, ServletException {\n\n        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, \"Authentication failed\");\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/security/AjaxAuthenticationSuccessHandler.java",
    "content": "package fr.ippon.tatami.security;\n\nimport org.springframework.security.core.Authentication;\nimport org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;\nimport org.springframework.stereotype.Component;\n\nimport javax.servlet.ServletException;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.IOException;\n\n/**\n * Spring Security success handler, specialized for Ajax requests.\n */\n@Component\npublic class AjaxAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {\n\n    @Override\n    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,\n        Authentication authentication)\n        throws IOException, ServletException {\n\n        response.setStatus(HttpServletResponse.SC_OK);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/security/AjaxLogoutSuccessHandler.java",
    "content": "package fr.ippon.tatami.security;\n\nimport org.springframework.security.core.Authentication;\nimport org.springframework.security.web.authentication.AbstractAuthenticationTargetUrlRequestHandler;\nimport org.springframework.security.web.authentication.logout.LogoutSuccessHandler;\nimport org.springframework.stereotype.Component;\n\nimport javax.servlet.ServletException;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.IOException;\n\n/**\n * Spring Security logout handler, specialized for Ajax requests.\n */\n@Component\npublic class AjaxLogoutSuccessHandler extends AbstractAuthenticationTargetUrlRequestHandler\n    implements LogoutSuccessHandler {\n\n    @Override\n    public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response,\n        Authentication authentication)\n        throws IOException, ServletException {\n        response.setStatus(HttpServletResponse.SC_OK);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/security/AuthenticationService.java",
    "content": "package fr.ippon.tatami.security;\n\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.UserRepository;\nimport org.springframework.security.core.Authentication;\nimport org.springframework.security.core.authority.SimpleGrantedAuthority;\nimport org.springframework.security.core.context.SecurityContext;\nimport org.springframework.security.core.context.SecurityContextHolder;\nimport org.springframework.security.core.userdetails.UserDetails;\nimport org.springframework.stereotype.Service;\n\nimport javax.inject.Inject;\n\n/**\n * This service is user to find the current user.\n *\n * @author Julien Dubois\n */\n@Service\npublic class AuthenticationService {\n\n    @Inject\n    private UserRepository userRepository;\n\n    public User getCurrentUser() {\n        SecurityContext securityContext = SecurityContextHolder.getContext();\n\n        UserDetails springSecurityUser =\n                (UserDetails) securityContext\n                        .getAuthentication().getPrincipal();\n\n        return userRepository.findUserByLogin(springSecurityUser.getUsername());\n    }\n\n    public static boolean isCurrentUserInRole(String authority) {\n        SecurityContext securityContext = SecurityContextHolder.getContext();\n        Authentication authentication = securityContext.getAuthentication();\n        if (authentication != null) {\n            if (authentication.getPrincipal() instanceof UserDetails) {\n                UserDetails springSecurityUser = (UserDetails) authentication.getPrincipal();\n                return springSecurityUser.getAuthorities().contains(new SimpleGrantedAuthority(authority));\n            }\n        }\n        return false;\n    }\n\n    public boolean hasAuthenticatedUser() {\n        SecurityContext securityContext = SecurityContextHolder.getContext();\n        return (securityContext.getAuthentication() != null);\n    }\n}"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/security/DomainViolationException.java",
    "content": "package fr.ippon.tatami.security;\n\n/**\n * This exception is thrown when a user tries to see a status from another domain.\n *\n * @author Julien Dubois\n */\npublic class DomainViolationException extends RuntimeException {\n\n    public DomainViolationException() {\n    }\n\n    public DomainViolationException(String s) {\n        super(s);\n    }\n\n    public DomainViolationException(String s, Throwable throwable) {\n        super(s, throwable);\n    }\n\n    public DomainViolationException(Throwable throwable) {\n        super(throwable);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/security/GoogleApiAuthenticationProvider.java",
    "content": "package fr.ippon.tatami.security;\n\nimport org.pac4j.springframework.security.authentication.ClientAuthenticationToken;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.security.authentication.AuthenticationProvider;\nimport org.springframework.security.core.Authentication;\n\npublic class GoogleApiAuthenticationProvider implements AuthenticationProvider {\n\n    Logger logger = LoggerFactory.getLogger(GoogleApiAuthenticationProvider.class);\n\n    @Override\n    public Authentication authenticate(Authentication authentication) {\n        if(!this.supports(authentication.getClass())) {\n            logger.debug(\"unsupported authentication class : {}\", authentication.getClass());\n            return null;\n        } else {\n            logger.debug(\"authentication : {}\", authentication);\n\n            GoogleAuthenticationToken result = (GoogleAuthenticationToken) authentication;\n            result.setDetails(authentication.getDetails());\n            return result;\n        }\n    }\n\n    @Override\n    public boolean supports(Class<?> authentication) {\n        return GoogleAuthenticationToken.class.isAssignableFrom(authentication);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/security/GoogleAuthenticationProvider.java",
    "content": "package fr.ippon.tatami.security;\n\nimport com.google.inject.Inject;\nimport org.pac4j.core.client.Client;\nimport org.pac4j.core.client.Clients;\nimport org.pac4j.core.context.WebContext;\nimport org.pac4j.core.credentials.Credentials;\nimport org.pac4j.core.profile.UserProfile;\nimport org.pac4j.springframework.security.authentication.ClientAuthenticationToken;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.security.authentication.AuthenticationProvider;\nimport org.springframework.security.core.Authentication;\nimport org.springframework.security.core.AuthenticationException;\nimport org.springframework.security.core.userdetails.AuthenticationUserDetailsService;\nimport org.springframework.security.core.userdetails.UserDetails;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\n\n/**\n *\n */\npublic class GoogleAuthenticationProvider implements AuthenticationProvider {\n    private static final Logger logger = LoggerFactory.getLogger(GoogleAuthenticationProvider.class);\n\n    // In our case, the only actual client is the google client\n    @Inject\n    private Clients clients;\n\n    // Get/Create new user\n    @Inject\n    private AuthenticationUserDetailsService<ClientAuthenticationToken> userDetailsService;\n\n    public GoogleAuthenticationProvider() {\n\n    }\n\n    @Override\n    public Authentication authenticate(Authentication authentication) throws AuthenticationException {\n        logger.debug(\"authentication : {}\", authentication);\n        if(!this.supports(authentication.getClass())) {\n            logger.debug(\"unsupported authentication class : {}\", authentication.getClass());\n            return null;\n        } else {\n            ClientAuthenticationToken token = (ClientAuthenticationToken)authentication;\n            Credentials credentials = (Credentials)authentication.getCredentials();\n            logger.debug(\"credentials : {}\", credentials);\n            String clientName = token.getClientName();\n            Client client = this.clients.findClient(clientName);\n            UserProfile userProfile = client.getUserProfile(credentials, (WebContext)null);\n            logger.debug(\"userProfile : {}\", userProfile);\n            Object authorities = new ArrayList();\n            ClientAuthenticationToken result = null;\n            logger.debug(\"userDetailsService: {}\", this.userDetailsService);\n            result = new ClientAuthenticationToken(credentials, clientName, userProfile, (Collection)null);\n            UserDetails userDetails = this.userDetailsService.loadUserDetails(result);\n            logger.debug(\"userDetails : {}\", userDetails);\n            if(userDetails != null) {\n                authorities = userDetails.getAuthorities();\n                logger.debug(\"authorities : {}\", authorities);\n            }\n            GoogleAuthenticationToken res = new GoogleAuthenticationToken(userDetails, clientName, (Collection)authorities);\n\n\n            logger.debug(\"Client name : {}\", clientName); // -> Google2Client\n            logger.debug(\"Client Credentials: {}\", credentials); // -> OAuth Credentials\n            logger.debug(\"Client Profile: {}\", userProfile); // -> GoogleProfile, i.e. data from google\n            res.setDetails(authentication.getDetails());\n            logger.debug(\"result : {}\", res);\n            return res;\n        }\n    }\n\n    public UserDetails createPrincipal() {\n        return null;\n    }\n\n    @Override\n    public boolean supports(Class<?> authentication) {\n        return ClientAuthenticationToken.class.isAssignableFrom(authentication);\n    }\n\n    public void setUserDetailsService(AuthenticationUserDetailsService<ClientAuthenticationToken> userDetailsService) {\n        this.userDetailsService = userDetailsService;\n    }\n\n    public AuthenticationUserDetailsService<ClientAuthenticationToken> getUserDetailsService() {\n        return this.userDetailsService;\n    }\n\n    public void setClients(Clients clients) {\n        this.clients = clients;\n    }\n    public Clients getClients() {\n        return clients;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/security/GoogleAuthenticationToken.java",
    "content": "package fr.ippon.tatami.security;\n\nimport org.springframework.security.authentication.AbstractAuthenticationToken;\nimport org.springframework.security.core.GrantedAuthority;\n\nimport java.util.Collection;\n\n/**\n * Pac4j uses the ClientAuthenticationToken, where the principal is a string, but\n * our AuthenticationService expects a UsersDetails object for the principal. This\n * class handles this, it takes the ClientAuthenticationToken, and makes it fix what\n * we expect.\n */\npublic class GoogleAuthenticationToken extends AbstractAuthenticationToken {\n    private final Object principal;\n    private Object credentials;\n\n    public GoogleAuthenticationToken(Object principal) {\n        this(principal, null);\n    }\n\n    public GoogleAuthenticationToken(Object principal, Object credentials) {\n        super((Collection)null);\n        this.principal = principal;\n        this.credentials = credentials;\n        this.setAuthenticated(false);\n    }\n\n    public GoogleAuthenticationToken(Object principal, Object credentials, Collection<? extends GrantedAuthority> authorities) {\n        super(authorities);\n        this.principal = principal;\n        this.credentials = credentials;\n        super.setAuthenticated(true);\n    }\n\n    @Override\n    public Object getCredentials() {\n        return this.credentials;\n    }\n\n    @Override\n    public Object getPrincipal() {\n        return this.principal;\n    }\n\n    @Override\n    public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {\n        if(isAuthenticated) {\n            throw new IllegalArgumentException(\"Cannot set this token to trusted - use constructor which takes a GrantedAuthority list instead\");\n        } else {\n            super.setAuthenticated(false);\n        }\n    }\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/security/GoogleAutoRegisteringUserDetailsService.java",
    "content": "package fr.ippon.tatami.security;\n\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.DomainRepository;\nimport fr.ippon.tatami.service.UserService;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport org.pac4j.springframework.security.authentication.ClientAuthenticationToken;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.security.core.userdetails.AuthenticationUserDetailsService;\nimport org.springframework.security.core.userdetails.UserDetails;\nimport org.springframework.security.core.userdetails.UsernameNotFoundException;\nimport org.springframework.stereotype.Component;\n\nimport javax.inject.Inject;\n\n/**\n *\n */\n@Component\npublic class GoogleAutoRegisteringUserDetailsService implements AuthenticationUserDetailsService<ClientAuthenticationToken> {\n    private final Logger log = LoggerFactory.getLogger(GoogleAutoRegisteringUserDetailsService.class);\n\n    private static final String EMAIL_ATTRIBUTE = \"email\";\n    private static final String FIRSTNAME_ATTRIBUTE = \"given_name\";\n    private static final String LASTNAME_ATTRIBUTE = \"family_name\";\n    private static final String FULLNAME_ATTRIBUTE = \"name\";\n\n    @Inject\n    private UserService userService;\n\n    @Inject\n    private DomainRepository domainRepository;\n\n    @Inject\n    private TatamiUserDetailsService userDetailsService; // => handles grantedAuthorities\n\n    @Override\n    public UserDetails loadUserDetails(ClientAuthenticationToken token) throws UsernameNotFoundException {\n        String login = getAttributeValue(token, EMAIL_ATTRIBUTE);\n\n        if (login == null) {\n            String msg = \"OAuth response did not contain the user email\";\n            log.error(msg);\n            throw new UsernameNotFoundException(msg);\n        }\n        if (!login.contains(\"@\")) {\n            log.debug(\"User login {} from OAuth response is incorrect.\", login);\n            throw new UsernameNotFoundException(\"OAuth response did not contains a valid user email\");\n        }\n\n        // Automatically create OpenId users in Tatami :\n        UserDetails userDetails;\n        try {\n            userDetails = userDetailsService.loadUserByUsername(login);\n            // ensure that this user has access to its domain if it has been created before\n            domainRepository.updateUserInDomain(DomainUtil.getDomainFromLogin(login), login);\n\n        } catch (UsernameNotFoundException e) {\n            log.info(\"User with login : \\\"{}\\\" doesn't exist yet in Tatami database - creating it...\", login);\n            userDetails = getNewlyCreatedUserDetails(token);\n        }\n        return userDetails;\n    }\n\n    private org.springframework.security.core.userdetails.User getNewlyCreatedUserDetails(ClientAuthenticationToken token) {\n        String login = getAttributeValue(token, EMAIL_ATTRIBUTE);\n        String firstName = getAttributeValue(token, FIRSTNAME_ATTRIBUTE);\n        String lastName = getAttributeValue(token, LASTNAME_ATTRIBUTE);\n\n        String fullName = getAttributeValue(token, FULLNAME_ATTRIBUTE);\n        if (firstName == null && lastName == null) {\n            // if we haven't first nor last name, we use fullName as last name to begin with :\n            lastName = fullName;\n        }\n\n        User user = new User();\n        // Note : The email could change... and the OpenId not\n        // moreover an OpenId account could potentially be associated with several email addresses\n        // so we store it for future use case :\n\n        user.setLogin(login);\n        user.setFirstName(firstName);\n        user.setLastName(lastName);\n        log.debug(\"User: {}\", user);\n        userService.createUser(user);\n\n        return userDetailsService.getTatamiUserDetails(login, user.getPassword());\n    }\n\n    private String getAttributeValue(ClientAuthenticationToken token, String name) {\n        return (String) token.getUserProfile().getAttributes().get(name);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/security/Http401UnauthorizedEntryPoint.java",
    "content": "package fr.ippon.tatami.security;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.security.core.AuthenticationException;\nimport org.springframework.security.web.AuthenticationEntryPoint;\nimport org.springframework.stereotype.Component;\n\nimport javax.servlet.ServletException;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.IOException;\n\n/**\n * Returns a 401 error code (Unauthorized) to the client.\n */\n@Component\npublic class Http401UnauthorizedEntryPoint implements AuthenticationEntryPoint {\n\n    private final Logger log = LoggerFactory.getLogger(Http401UnauthorizedEntryPoint.class);\n\n    /**\n     * Always returns a 401 error code to the client.\n     */\n    @Override\n    public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException arg2)\n        throws IOException,\n            ServletException {\n\n        log.debug(\"Pre-authenticated entry point called. Rejecting access\");\n        response.sendError(HttpServletResponse.SC_UNAUTHORIZED, \"Access Denied\");\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/security/OpenIdAutoRegisteringUserDetailsService.java",
    "content": "package fr.ippon.tatami.security;\n\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.DomainRepository;\nimport fr.ippon.tatami.service.UserService;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.security.core.userdetails.AuthenticationUserDetailsService;\nimport org.springframework.security.core.userdetails.UserDetails;\nimport org.springframework.security.core.userdetails.UsernameNotFoundException;\nimport org.springframework.security.openid.OpenIDAttribute;\nimport org.springframework.security.openid.OpenIDAuthenticationToken;\nimport org.springframework.stereotype.Component;\n\nimport javax.inject.Inject;\nimport java.util.List;\n\n/**\n * UserDetails Service to be used with OpenId authentication.\n * It auto-registers the user based on its \"email\" OpenId attribute\n * (that must have been asked to the OpenId provider).\n *\n * @author Fabien Arrault\n */\n@Component\npublic class OpenIdAutoRegisteringUserDetailsService implements\n        AuthenticationUserDetailsService<OpenIDAuthenticationToken> {\n\n    private static final String EMAIL_ATTRIBUTE = \"email\";\n    private static final String FIRSTNAME_ATTRIBUTE = \"firstname\";\n    private static final String LASTNAME_ATTRIBUTE = \"lastname\";\n    private static final String FULLNAME_ATTRIBUTE = \"fullname\";\n\n    private final Logger log = LoggerFactory.getLogger(OpenIdAutoRegisteringUserDetailsService.class);\n\n    @Inject\n    private UserService userService;\n\n    @Inject\n    private DomainRepository domainRepository;\n\n    @Inject\n    private TatamiUserDetailsService userDetailsService; // => handles grantedAuthorities\n\n    @Override\n    public UserDetails loadUserDetails(OpenIDAuthenticationToken token) throws UsernameNotFoundException {\n\n        String login = getAttributeValue(token, EMAIL_ATTRIBUTE);\n        // Important security assumption : here we are trusting the OpenID provider\n        // to give us an email that has already been verified to belong to the user\n\n        if (login == null) {\n            String msg = \"OpendId response did not contain the user email\";\n            log.error(msg);\n            throw new UsernameNotFoundException(msg);\n        }\n        if (!login.contains(\"@\")) {\n            log.debug(\"User login {} from OpenId response is incorrect.\", login);\n            throw new UsernameNotFoundException(\"OpendId response did not contains a valid user email\");\n        }\n\n        // Automatically create OpenId users in Tatami :\n        UserDetails userDetails;\n        try {\n            userDetails = userDetailsService.loadUserByUsername(login);\n            // ensure that this user has access to its domain if it has been created before\n            domainRepository.updateUserInDomain(DomainUtil.getDomainFromLogin(login), login);\n\n        } catch (UsernameNotFoundException e) {\n            log.info(\"User with login : \\\"{}\\\" doesn't exist yet in Tatami database - creating it...\", login);\n            userDetails = getNewlyCreatedUserDetails(token);\n        }\n        return userDetails;\n    }\n\n    private org.springframework.security.core.userdetails.User getNewlyCreatedUserDetails(OpenIDAuthenticationToken token) {\n        String login = getAttributeValue(token, EMAIL_ATTRIBUTE);\n        String firstName = getAttributeValue(token, FIRSTNAME_ATTRIBUTE);\n        String lastName = getAttributeValue(token, LASTNAME_ATTRIBUTE);\n\n        String fullName = getAttributeValue(token, FULLNAME_ATTRIBUTE);\n        if (firstName == null && lastName == null) {\n            // if we haven't first nor last name, we use fullName as last name to begin with :\n            lastName = fullName;\n        }\n\n        User user = new User();\n        // Note : The email could change... and the OpenId not\n        // moreover an OpenId account could potentially be associated with several email addresses\n        // so we store it for future use case :\n        user.setOpenIdUrl(token.getName());\n\n        user.setLogin(login);\n        user.setFirstName(firstName);\n        user.setLastName(lastName);\n        userService.createUser(user);\n\n        return userDetailsService.getTatamiUserDetails(login, user.getPassword());\n    }\n\n    private String getAttributeValue(OpenIDAuthenticationToken token, String name) {\n        String value = null;\n        for (OpenIDAttribute attribute : token.getAttributes()) {\n            if (name.equals(attribute.getName())) {\n                List<String> values = attribute.getValues();\n                String firstValue = values.isEmpty() ? null : values.iterator().next();\n                value = firstValue;\n                break;\n            }\n        }\n        return value;\n    }\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/security/TatamiAuthenticationSuccessHandler.java",
    "content": "package fr.ippon.tatami.security;\n\nimport fr.ippon.tatami.repository.AppleDeviceRepository;\nimport fr.ippon.tatami.repository.AppleDeviceUserRepository;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.security.core.Authentication;\nimport org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;\nimport org.springframework.security.web.savedrequest.HttpSessionRequestCache;\nimport org.springframework.security.web.savedrequest.RequestCache;\nimport org.springframework.security.web.savedrequest.SavedRequest;\nimport org.springframework.stereotype.Component;\nimport org.springframework.util.StringUtils;\n\nimport javax.inject.Inject;\nimport javax.servlet.ServletException;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.IOException;\n\n/**\n * Tatami specific Spring Security success handler, that understands Ajax requests.\n */\n@Component\npublic class TatamiAuthenticationSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {\n\n    private final Logger log = LoggerFactory.getLogger(TatamiAuthenticationSuccessHandler.class);\n\n    private RequestCache requestCache = new HttpSessionRequestCache();\n\n    @Inject\n    private AppleDeviceRepository appleDeviceRepository;\n\n    @Inject\n    private AppleDeviceUserRepository appleDeviceUserRepository;\n\n    @Override\n    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,\n                                        Authentication authentication) throws ServletException, IOException {\n        SavedRequest savedRequest = requestCache.getRequest(request, response);\n\n        manageAppleDevice(authentication.getName(), request.getParameter(\"device_token\"));\n\n        if (savedRequest == null) {\n            super.onAuthenticationSuccess(request, response, authentication);\n            return;\n        }\n        if (savedRequest.getHeaderNames().contains(\"X-Requested-With\") &&\n                \"XMLHttpRequest\".equals(savedRequest.getHeaderValues(\"X-Requested-With\").get(0))) {\n\n            requestCache.removeRequest(request, response);\n            clearAuthenticationAttributes(request);\n            response.sendRedirect(getDefaultTargetUrl());\n            return;\n        }\n\n        String targetUrlParameter = getTargetUrlParameter();\n        if (isAlwaysUseDefaultTargetUrl() || (targetUrlParameter != null && StringUtils.hasText(request.getParameter(targetUrlParameter)))) {\n            requestCache.removeRequest(request, response);\n            super.onAuthenticationSuccess(request, response, authentication);\n\n            return;\n        }\n\n        clearAuthenticationAttributes(request);\n\n        // Use the DefaultSavedRequest URL\n        String targetUrl = savedRequest.getRedirectUrl();\n        getRedirectStrategy().sendRedirect(request, response, targetUrl);\n    }\n\n    public void setRequestCache(RequestCache requestCache) {\n        this.requestCache = requestCache;\n    }\n\n    private void manageAppleDevice(String login, String deviceToken) {\n        if (deviceToken == null) {\n            return;\n        }\n        log.debug(\"Device token: {}\", deviceToken);\n        String deviceId = deviceToken.substring(1, deviceToken.length() - 1);\n        log.debug(\"Device Id: {}\", deviceId);\n        String existingDeviceLogin = appleDeviceUserRepository.findLoginForDeviceId(deviceId);\n        if (existingDeviceLogin != null) {\n            appleDeviceRepository.removeAppleDevice(existingDeviceLogin, deviceId);\n            appleDeviceUserRepository.removeAppleDeviceForUser(deviceId);\n        }\n        appleDeviceUserRepository.createAppleDeviceForUser(deviceId, login);\n        appleDeviceRepository.createAppleDevice(login, deviceId);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/security/TatamiLdapAuthenticationProvider.java",
    "content": "package fr.ippon.tatami.security;\n\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.DomainRepository;\nimport fr.ippon.tatami.service.UserService;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport org.apache.commons.lang.StringUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.security.authentication.BadCredentialsException;\nimport org.springframework.security.authentication.InternalAuthenticationServiceException;\nimport org.springframework.security.authentication.UsernamePasswordAuthenticationToken;\nimport org.springframework.security.core.Authentication;\nimport org.springframework.security.core.AuthenticationException;\nimport org.springframework.security.ldap.authentication.LdapAuthenticationProvider;\nimport org.springframework.security.ldap.authentication.LdapAuthenticator;\n\nimport javax.inject.Inject;\n\n/**\n * Tatami specific LdapAuthenticationProvider.\n *\n * @author Julien Dubois\n */\npublic class TatamiLdapAuthenticationProvider extends LdapAuthenticationProvider {\n\n    private final Logger log = LoggerFactory.getLogger(TatamiLdapAuthenticationProvider.class);\n\n    @Inject\n    private UserService userService;\n\n    @Inject\n    private DomainRepository domainRepository;\n\n    @Inject\n    private TatamiUserDetailsService userDetailsService; // => handles grantedAuthorities\n\n    /**\n     * The domain on which this provider is suitable to authenticate user\n     */\n    private String managedDomain;\n\n    public TatamiLdapAuthenticationProvider(LdapAuthenticator authenticator, String managedDomain) {\n        super(authenticator);\n        if (StringUtils.isEmpty(managedDomain)) {\n            throw new IllegalArgumentException(\"You must provide a managedDomain on this TatamiLdapAuthenticationProvider\");\n        }\n        this.managedDomain = managedDomain;\n    }\n\n    private boolean canHandleAuthentication(Authentication authentication) {\n        String login = authentication.getName();\n        if (!login.contains(\"@\")) {\n            log.debug(\"User login {} is incorrect.\", login);\n\n            throw new BadCredentialsException(messages.getMessage(\n                    \"LdapAuthenticationProvider.badCredentials\", \"Bad credentials\"));\n        }\n        String domain = DomainUtil.getDomainFromLogin(login);\n        return domain.equalsIgnoreCase(managedDomain);\n    }\n\n    @Override\n    public Authentication authenticate(Authentication authentication) throws AuthenticationException {\n        if (!canHandleAuthentication(authentication)) {\n            return null; // this provider is not suitable for this domain\n        }\n\n        log.debug(\"Authenticating {} with LDAP\", authentication.getName());\n        String login = authentication.getName().toLowerCase();\n        String username = DomainUtil.getUsernameFromLogin(login);\n\n        // Use temporary token to use username, and not login to authenticate on ldap :\n        UsernamePasswordAuthenticationToken tmpAuthentication =\n                new UsernamePasswordAuthenticationToken(username, authentication.getCredentials(), null);\n\n        try {\n            super.authenticate(tmpAuthentication);\n        } catch (InternalAuthenticationServiceException iase) {\n            // Without this : there is no log when the ldap server or the ldap configuration is broken : \n            log.error(\"Internal Error while authenticating \" + authentication.getName() + \" with LDAP\", iase);\n            throw iase;\n        }\n\n        //Automatically create LDAP users in Tatami\n        User user = userService.getUserByLogin(login);\n        if (user == null) {\n            user = new User();\n            user.setLogin(login);\n            userService.createUser(user);\n        } else {\n            // ensure that this user has access to its domain if it has been created before\n            domainRepository.updateUserInDomain(user.getDomain(), user.getLogin());\n        }\n\n        // The real authentication object uses the login, and not the username\n        org.springframework.security.core.userdetails.User realUser = userDetailsService.getTatamiUserDetails(login,\n                authentication.getCredentials().toString());\n\n        return\n                new UsernamePasswordAuthenticationToken(realUser, authentication.getCredentials(),\n                        realUser.getAuthorities());\n\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/security/TatamiUserDetailsService.java",
    "content": "package fr.ippon.tatami.security;\n\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.service.UserService;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\nimport org.springframework.security.core.GrantedAuthority;\nimport org.springframework.security.core.authority.SimpleGrantedAuthority;\nimport org.springframework.security.core.userdetails.UserDetails;\nimport org.springframework.security.core.userdetails.UserDetailsService;\nimport org.springframework.security.core.userdetails.UsernameNotFoundException;\nimport org.springframework.stereotype.Component;\n\nimport javax.annotation.PostConstruct;\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\n\n/**\n * Finds a user in Cassandra.\n *\n * @author Julien Dubois\n */\n@Component(\"userDetailsService\")\npublic class TatamiUserDetailsService implements UserDetailsService {\n\n    private final Logger log = LoggerFactory.getLogger(TatamiUserDetailsService.class);\n\n    private final Collection<GrantedAuthority> userGrantedAuthorities = new ArrayList<GrantedAuthority>();\n\n    private final Collection<GrantedAuthority> adminGrantedAuthorities = new ArrayList<GrantedAuthority>();\n\n    private Collection<String> adminUsers = null;\n\n    @Inject\n    private UserService userService;\n\n    @Inject\n    Environment env;\n\n    @PostConstruct\n    public void init() {\n        if (userGrantedAuthorities.size() == 0) { // to prevent a bug that makes this bean initialized twice\n            //Roles for \"normal\" users\n            GrantedAuthority roleUser = new SimpleGrantedAuthority(\"ROLE_USER\");\n            userGrantedAuthorities.add(roleUser);\n\n            //Roles for \"admin\" users, configured in tatami.properties\n            GrantedAuthority roleAdmin = new SimpleGrantedAuthority(\"ROLE_ADMIN\");\n            adminGrantedAuthorities.add(roleUser);\n            adminGrantedAuthorities.add(roleAdmin);\n\n            String adminUsersList = env.getProperty(\"tatami.admin.users\");\n            String[] adminUsersArray = adminUsersList.split(\",\");\n            adminUsers = new ArrayList<String>(Arrays.asList(adminUsersArray));\n            if (log.isDebugEnabled()) {\n                for (String admin : adminUsers) {\n                    log.debug(\"Initialization : user \\\"{}\\\" is an administrator\", admin);\n                }\n            }\n        }\n    }\n\n    @Override\n    public UserDetails loadUserByUsername(final String login) throws UsernameNotFoundException {\n        log.debug(\"Authenticating {} with Cassandra\", login);\n        String lowercaseLogin = login.toLowerCase();\n        User userFromCassandra = userService.getUserByLogin(lowercaseLogin);\n        if (userFromCassandra == null) {\n            throw new UsernameNotFoundException(\"User \" + lowercaseLogin + \" was not found in Cassandra\");\n        }\n        else if ( userFromCassandra.getActivated() != null && userFromCassandra.getActivated() == false ) {\n            throw new UsernameNotFoundException(\"User \" + lowercaseLogin + \" is deactivated. Contact administrator for further details.\" );\n        }\n        return getTatamiUserDetails(lowercaseLogin, userFromCassandra.getPassword());\n    }\n\n    protected org.springframework.security.core.userdetails.User getTatamiUserDetails(String login, String password) {\n        Collection<GrantedAuthority> grantedAuthorities;\n        if (adminUsers.contains(login)) {\n            log.debug(\"User \\\"{}\\\" is an administrator\", login);\n\n            grantedAuthorities = adminGrantedAuthorities;\n        } else {\n            grantedAuthorities = userGrantedAuthorities;\n        }\n\n        return new org.springframework.security.core.userdetails.User(login, password,\n                grantedAuthorities);\n    }\n\n    public Collection<String> getAdminUsers() {\n        return adminUsers;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/security/xauth/Token.java",
    "content": "package fr.ippon.tatami.security.xauth;\n\n/**\n * The security token.\n */\npublic class Token {\n\n    String token;\n    long expires;\n\n    public Token(String token, long expires){\n        this.token = token;\n        this.expires = expires;\n    }\n\n    public String getToken() {\n        return token;\n    }\n\n    public long getExpires() {\n        return expires;\n    }\n}"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/security/xauth/TokenProvider.java",
    "content": "package fr.ippon.tatami.security.xauth;\n\nimport org.springframework.security.core.userdetails.UserDetails;\nimport org.springframework.security.crypto.codec.Hex;\n\nimport java.security.MessageDigest;\nimport java.security.NoSuchAlgorithmException;\n\npublic class TokenProvider {\n\n    private final String secretKey;\n    private final int tokenValidity;\n\n    public TokenProvider(String secretKey, int tokenValidity) {\n        this.secretKey = secretKey;\n        this.tokenValidity = tokenValidity;\n    }\n\n    public Token createToken(UserDetails userDetails) {\n        long expires = System.currentTimeMillis() + 1000L * tokenValidity;\n        String token = userDetails.getUsername() + \":\" + expires + \":\" + computeSignature(userDetails, expires);\n        return new Token(token, expires);\n    }\n\n    public String computeSignature(UserDetails userDetails, long expires) {\n        StringBuilder signatureBuilder = new StringBuilder();\n        signatureBuilder.append(userDetails.getUsername()).append(\":\");\n        signatureBuilder.append(expires).append(\":\");\n        signatureBuilder.append(userDetails.getPassword()).append(\":\");\n        signatureBuilder.append(secretKey);\n\n        MessageDigest digest;\n        try {\n            digest = MessageDigest.getInstance(\"MD5\");\n        } catch (NoSuchAlgorithmException e) {\n            throw new IllegalStateException(\"No MD5 algorithm available!\");\n        }\n        return new String(Hex.encode(digest.digest(signatureBuilder.toString().getBytes())));\n    }\n\n    public String getUserNameFromToken(String authToken) {\n        if (null == authToken) {\n            return null;\n        }\n        String[] parts = authToken.split(\":\");\n        return parts[0];\n    }\n\n    public boolean validateToken(String authToken, UserDetails userDetails) {\n        String[] parts = authToken.split(\":\");\n        long expires = Long.parseLong(parts[1]);\n        String signature = parts[2];\n        String signatureToMatch = computeSignature(userDetails, expires);\n        return expires >= System.currentTimeMillis() && constantTimeEquals(signature, signatureToMatch);\n    }\n\n    /**\n     * String comparison that doesn't stop at the first character that is different but instead always\n     * iterates the whole string length to prevent timing attacks.\n     */\n    private boolean constantTimeEquals(String a, String b) {\n        if (a.length() != b.length()) {\n            return false;\n        } else {\n            int equal = 0;\n            for (int i = 0; i < a.length(); i++) {\n                equal |= a.charAt(i) ^ b.charAt(i);\n            }\n            return equal == 0;\n        }\n    }\n\n}"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/security/xauth/XAuthTokenFilter.java",
    "content": "package fr.ippon.tatami.security.xauth;\n\nimport org.springframework.security.authentication.UsernamePasswordAuthenticationToken;\nimport org.springframework.security.core.context.SecurityContextHolder;\nimport org.springframework.security.core.userdetails.UserDetails;\nimport org.springframework.security.core.userdetails.UserDetailsService;\nimport org.springframework.util.StringUtils;\nimport org.springframework.web.filter.GenericFilterBean;\n\nimport javax.servlet.FilterChain;\nimport javax.servlet.ServletException;\nimport javax.servlet.ServletRequest;\nimport javax.servlet.ServletResponse;\nimport javax.servlet.http.HttpServletRequest;\nimport java.io.IOException;\n\n/**\n * Filters incoming requests and installs a Spring Security principal\n * if a header corresponding to a valid user is found.\n */\npublic class XAuthTokenFilter extends GenericFilterBean {\n\n    public final static String XAUTH_TOKEN_HEADER_NAME = \"x-auth-token\";\n\n    private UserDetailsService detailsService;\n\n    private TokenProvider tokenProvider;\n\n    public XAuthTokenFilter(UserDetailsService detailsService, TokenProvider tokenProvider) {\n        this.detailsService = detailsService;\n        this.tokenProvider = tokenProvider;\n    }\n\n    @Override\n    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {\n        try {\n            HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;\n            String authToken = httpServletRequest.getHeader(XAUTH_TOKEN_HEADER_NAME);\n            if (StringUtils.hasText(authToken) && authToken.split(\":\").length > 1) {\n                String username = this.tokenProvider.getUserNameFromToken(authToken);\n                UserDetails details = this.detailsService.loadUserByUsername(username);\n                if (this.tokenProvider.validateToken(authToken, details)) {\n                    UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(details, details.getPassword(), details.getAuthorities());\n                    SecurityContextHolder.getContext().setAuthentication(token);\n                }\n            }\n            filterChain.doFilter(servletRequest, servletResponse);\n        } catch (Exception ex) {\n            throw new RuntimeException(ex);\n        }\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/AdminService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.domain.Domain;\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.domain.status.AbstractStatus;\nimport fr.ippon.tatami.domain.status.Status;\nimport fr.ippon.tatami.domain.status.StatusType;\nimport fr.ippon.tatami.repository.DomainRepository;\nimport fr.ippon.tatami.repository.StatusRepository;\nimport fr.ippon.tatami.repository.UserRepository;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.OrderedRows;\nimport me.prettyprint.hector.api.beans.Row;\nimport me.prettyprint.hector.api.query.QueryResult;\nimport me.prettyprint.hector.api.query.RangeSlicesQuery;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\nimport org.springframework.security.access.prepost.PreAuthorize;\nimport org.springframework.stereotype.Service;\n\nimport javax.inject.Inject;\nimport java.util.*;\n\nimport static fr.ippon.tatami.config.ColumnFamilyKeys.STATUS_CF;\nimport static me.prettyprint.hector.api.factory.HFactory.createRangeSlicesQuery;\n\n/**\n * Administration service. Only users with the \"admin\" role should access it.\n *\n * @author Julien Dubois\n */\n@Service\n@PreAuthorize(\"hasRole('ROLE_ADMIN')\")\npublic class AdminService {\n\n    private static final Logger log = LoggerFactory.getLogger(AdminService.class);\n\n    @Inject\n    private DomainRepository domainRepository;\n\n    @Inject\n    private SearchService searchService;\n\n    @Inject\n    private UserRepository userRepository;\n\n    @Inject\n    private StatusRepository statusRepository;\n\n    @Inject\n    private GroupService groupService;\n\n    @Inject\n    private Environment env;\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    public Collection<Domain> getAllDomains() {\n        return domainRepository.getAllDomains();\n    }\n\n    public Map<String, String> getEnvProperties() {\n        log.trace(\"AdminService.getEnvProperties() enter\");\n        Map<String, String> properties = new LinkedHashMap<String, String>();\n        loadProperty(properties, \"tatami.version\");\n        loadProperty(properties, \"tatami.wro4j.enabled\");\n        loadProperty(properties, \"tatami.google.analytics.key\");\n        loadProperty(properties, \"tatami.message.reloading.enabled\");\n        loadProperty(properties, \"smtp.host\");\n        loadProperty(properties, \"cassandra.host\");\n        loadProperty(properties, \"search.engine\");\n        loadProperty(properties, \"lucene.path\");\n        loadProperty(properties, \"elasticsearch.indexNamePrefix\");\n        loadProperty(properties, \"elasticsearch.cluster.name\");\n        loadProperty(properties, \"elasticsearch.cluster.nodes\");\n        loadProperty(properties, \"elasticsearch.cluster.default.communication.port\");\n        log.trace(\"AdminService.getEnvProperties() return\");\n        return properties;\n    }\n\n    private void loadProperty(Map<String, String> properties, String key) {\n        try {\n            properties.put(key, env.getProperty(key));\n        } catch (Exception e) {\n            properties.put(key, \"(Invalid value)\");\n        }\n    }\n\n    /**\n     * Rebuilds the Search Engine Index.\n     * <p>\n     * This could be a huge batch process : it does not use a Repository for performance reasons.\n     * </p>\n     */\n    public void rebuildIndex() {\n        log.info(\"Search engine Index rebuild triggered.\");\n        log.debug(\"Deleting Index\");\n        if (searchService.reset()) {\n            log.info(\"Search engine Index deleted.\");\n        } else {\n            log.error(\"An error has occured while deleting the Search Engine Index. \" +\n                    \"Full rebuild of the index cancelled.\");\n\n            return;\n        }\n\n        //Rebuild the user Index\n        log.debug(\"Rebuilding the user & group Indexes\");\n        long fullIndexStartTime = Calendar.getInstance().getTimeInMillis();\n        Collection<Domain> domains = domainRepository.getAllDomains();\n        int groupCount = 0;\n        for (Domain domain : domains) {\n            log.debug(\"Indexing domain: \" + domain.getName());\n            List<String> logins = domainRepository.getLoginsInDomain(domain.getName());\n            Collection<User> users = new ArrayList<User>();\n            for (String login : logins) {\n                User user = userRepository.findUserByLogin(login);\n                if (user == null) {\n                    log.warn(\"User defined in domain was not found in the user respository: \" + login);\n                } else {\n                    log.debug(\"Indexing user: {}\", login);\n                    users.add(user);\n                    Collection<Group> groups = groupService.getGroupsWhereUserIsAdmin(user);\n                    for (Group group : groups) {\n                        searchService.addGroup(group);\n                        groupCount++;\n                    }\n                }\n            }\n            searchService.addUsers(users);\n            log.info(\"The search engine indexed \" + logins.size() + \" users.\");\n        }\n        log.info(\"The search engine indexed \" + groupCount + \" groups.\");\n\n        //Rebuild the status Index\n        log.info(\"Rebuilding the status Index\");\n        String startKey = null;\n        boolean moreStatus = true;\n        while (moreStatus) {\n            long startTime = Calendar.getInstance().getTimeInMillis();\n            RangeSlicesQuery<String, String, String> query = createRangeSlicesQuery(keyspaceOperator,\n                    StringSerializer.get(), StringSerializer.get(), StringSerializer.get())\n                    .setColumnFamily(STATUS_CF)\n                    .setRange(\"statusId\", \"statusId\", false, 1)\n                    .setKeys(startKey, null)\n                    .setRowCount(1001);\n\n            QueryResult<OrderedRows<String, String, String>> result = query.execute();\n            List<Row<String, String, String>> rows = result.get().getList();\n            if (rows.size() == 1001) { // Calculate the pagination\n                startKey = rows.get(1000).getKey();\n                rows = rows.subList(0, 1000);\n            } else {\n                moreStatus = false;\n            }\n            Collection<Status> statuses = new ArrayList<Status>();\n            for (Row<String, String, String> row : rows) {\n                AbstractStatus abstractStatus = statusRepository.findStatusById(row.getKey()); // This makes 2 calls to the same row\n                if (abstractStatus != null && // if a status has been removed, it is returned as null\n                        abstractStatus.getType().equals(StatusType.STATUS)) { // Only index standard statuses\n\n                    Status status = (Status) abstractStatus;\n                    if (status.getStatusPrivate() == null || !status.getStatusPrivate()) {\n                        statuses.add(status);\n                    }\n                }\n            }\n            searchService.addStatuses(statuses); // This should be batched for optimum performance\n            log.info(\"The search engine indexed \" + statuses.size() + \" statuses in \" + (Calendar.getInstance().getTimeInMillis() - startTime) + \" ms.\");\n        }\n        log.info(\"Search engine index rebuilt in \" + (Calendar.getInstance().getTimeInMillis() - fullIndexStartTime) + \" ms.\");\n    }\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/ApplePushService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport com.notnoop.apns.APNS;\nimport com.notnoop.apns.ApnsService;\nimport com.notnoop.exceptions.NetworkIOException;\nimport fr.ippon.tatami.domain.status.Status;\nimport fr.ippon.tatami.repository.AppleDeviceRepository;\nimport fr.ippon.tatami.repository.AppleDeviceUserRepository;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.context.annotation.Profile;\nimport org.springframework.core.env.Environment;\nimport org.springframework.scheduling.annotation.Scheduled;\nimport org.springframework.stereotype.Service;\n\nimport javax.annotation.PostConstruct;\nimport javax.inject.Inject;\nimport java.util.Collection;\nimport java.util.Date;\nimport java.util.Map;\n\n/**\n * Notifies users with iOS push notifications.\n */\n@Service\n@Profile(\"apple-push\")\npublic class ApplePushService {\n\n    private static final Logger log = LoggerFactory.getLogger(ApplePushService.class);\n\n    private ApnsService apnsService;\n\n    @Inject\n    private Environment env;\n\n    @Inject\n    private AppleDeviceRepository appleDeviceRepository;\n\n    @Inject\n    private AppleDeviceUserRepository appleDeviceUserRepository;\n\n    @PostConstruct\n    public void init() {\n        log.info(\"Creating Apple Push Service\");\n        String certificate = env.getRequiredProperty(\"apple.push.certificate\");\n        String password = env.getRequiredProperty(\"apple.push.password\");\n        apnsService =\n                APNS.newService()\n                        .withCert(certificate, password)\n                        .withSandboxDestination()\n                        .build();\n\n        try {\n            apnsService.testConnection();\n            log.info(\"Apple Push Service is OK\");\n        } catch (NetworkIOException nioe) {\n            log.warn(\"Apple Push Service is NOT OK\");\n        }\n    }\n\n    /**\n     * Notifies the user with APNS.\n     */\n    public void notifyUser(String login, Status status) {\n        log.debug(\"Notifying user with Apple Push: {}\", login);\n        try {\n            String message =\n                    \"@\" +\n                            status.getUsername() +\n                            \"\\n\" +\n                            status.getContent();\n\n            if (message.length() > 256) {\n                message = message.substring(0, 252) + \"...\";\n            }\n\n            String payload =\n                    APNS.newPayload()\n                            .alertBody(message).build();\n\n            Collection<String> deviceIds = appleDeviceRepository.findAppleDevices(login);\n            for (String deviceId : deviceIds) {\n                log.debug(\"Notifying user : {} - device : {}\", login, deviceId);\n                apnsService.push(deviceId, payload);\n            }\n\n        } catch (Exception e) {\n            log.warn(\"Apple Push error: \" + e.getMessage());\n        }\n    }\n\n    /**\n     * Check Apple feedback service for inactive devices.\n     */\n    @Scheduled(cron = \"0 0 23 * * ?\")\n    public void feedbackService() {\n        log.info(\"Checking the Apple Feedback Service for inactive devices\");\n        try {\n            Map<String, Date> inactiveDevices = apnsService.getInactiveDevices();\n            for (String deviceId : inactiveDevices.keySet()) {\n                log.debug(\"Device {} is inactive\", deviceId);\n                String login = appleDeviceUserRepository.findLoginForDeviceId(deviceId);\n                log.debug(\"Removing device for user {}\" + login);\n                appleDeviceRepository.removeAppleDevice(login, deviceId);\n                appleDeviceUserRepository.removeAppleDeviceForUser(deviceId);\n            }\n        } catch (Exception e) {\n            log.warn(\"Apple Feedback Service error: \" + e.getMessage());\n        }\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/AtmosphereService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.domain.status.AbstractStatus;\nimport fr.ippon.tatami.service.dto.StatusDTO;\nimport fr.ippon.tatami.web.atmosphere.TatamiNotification;\nimport org.atmosphere.cpr.Broadcaster;\nimport org.atmosphere.cpr.BroadcasterFactory;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Service;\n\nimport javax.inject.Inject;\n\n@Service\npublic class AtmosphereService {\n\n    private static final Logger log = LoggerFactory.getLogger(AtmosphereService.class);\n\n    @Inject\n    private TimelineService timelineService;\n\n    /**\n     * Notifies the user with Atmosphere.\n     */\n    public void notifyUser(String login, AbstractStatus abstractStatus) {\n        log.debug(\"Notifying user: {}\", login);\n        StatusDTO statusDTO = timelineService.getStatus(abstractStatus.getStatusId());\n        TatamiNotification notification = new TatamiNotification();\n        notification.setLogin(login);\n        notification.setStatusDTO(statusDTO);\n        try {\n            Broadcaster broadcaster =\n                    BroadcasterFactory\n                            .getDefault()\n                            .lookup(\"/realtime/statuses/home_timeline/\" + login, true);\n\n            if (broadcaster != null) {\n                broadcaster.broadcast(notification);\n            } else {\n                log.info(\"Notification error, the broadcaster is null\");\n            }\n        } catch (Exception e) {\n            log.warn(\"Notification error: \" + e.getMessage());\n        }\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/AttachmentService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport java.awt.image.BufferedImage;\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\n\nimport javax.imageio.ImageIO;\nimport javax.inject.Inject;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\nimport org.springframework.stereotype.Service;\n\nimport fr.ippon.tatami.domain.Attachment;\nimport fr.ippon.tatami.domain.DomainConfiguration;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.AttachmentRepository;\nimport fr.ippon.tatami.repository.DomainConfigurationRepository;\nimport fr.ippon.tatami.repository.UserAttachmentRepository;\nimport fr.ippon.tatami.repository.UserRepository;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.exception.StorageSizeException;\n\n\n@Service\npublic class AttachmentService {\n\n    private static final Logger log = LoggerFactory.getLogger(AttachmentService.class);\n\n    @Inject\n    private AttachmentRepository attachmentRepository;\n\n    @Inject\n    private UserAttachmentRepository userAttachmentRepository;\n\n    @Inject\n    private DomainConfigurationRepository domainConfigurationRepository;\n\n    @Inject\n    private UserRepository userRepository;\n\n    @Inject\n    private AuthenticationService authenticationService;\n    \n    @Inject\n    private Environment env;\n\n    public String createAttachment(Attachment attachment) throws StorageSizeException {\n\n        User currentUser = authenticationService.getCurrentUser();\n        DomainConfiguration domainConfiguration =\n                domainConfigurationRepository.findDomainConfigurationByDomain(currentUser.getDomain());\n\n        long newAttachmentsSize = currentUser.getAttachmentsSize() + attachment.getSize();\n        if (newAttachmentsSize > domainConfiguration.getStorageSizeAsLong()) {\n            log.info(\"User \" + currentUser.getLogin() +\n                    \" has tried to exceed his storage capacity. current storage=\" +\n                    currentUser.getAttachmentsSize() +\n                    \", storage capacity=\" +\n                    domainConfiguration.getStorageSizeAsLong());\n\n            throw new StorageSizeException(\"User storage exceeded for user \" + currentUser.getLogin());\n        }\n        \n        attachment.setThumbnail(computeThumbnail(attachment));\n        \n        attachmentRepository.createAttachment(attachment);\n        userAttachmentRepository.addAttachmentId(authenticationService.getCurrentUser().getLogin(),\n                attachment.getAttachmentId());\n\n        // Refresh user data, to reduce the risk of errors\n        currentUser = authenticationService.getCurrentUser();\n        currentUser.setAttachmentsSize(currentUser.getAttachmentsSize() + attachment.getSize());\n        userRepository.updateUser(currentUser);\n        return attachment.getAttachmentId();\n    }\n\n    public Attachment getAttachmentById(String attachmentId) {\n        Attachment attachment =  attachmentRepository.findAttachmentById(attachmentId);\n        //Computing the thumbnail if it does not exists\n        if(! attachment.getHasThumbnail()) {\n        \tattachment.setThumbnail(computeThumbnail(attachment));\n        \tattachmentRepository.updateThumbnail(attachment);\n        }\n        return attachment;\n    }\n\n    public Collection<String> getAttachmentIdsForCurrentUser(int pagination, String finish) {\n        Collection<String> attachmentIds =\n                userAttachmentRepository.\n                        findAttachmentIds(authenticationService.getCurrentUser().getLogin(), pagination,finish);\n\n        log.debug(\"Collection of attachments : {}\", attachmentIds.size());\n\n        return attachmentIds;\n    }\n\n    public void deleteAttachment(Attachment attachment) {\n        log.debug(\"Removing attachment : {}\", attachment);\n        User currentUser = authenticationService.getCurrentUser();\n\n        for (String attachmentIdTest : userAttachmentRepository.findAttachmentIds(currentUser.getLogin())) {\n            if (attachmentIdTest.equals(attachment.getAttachmentId())) {\n                userAttachmentRepository.removeAttachmentId(currentUser.getLogin(), attachment.getAttachmentId());\n                attachmentRepository.deleteAttachment(attachment);\n                // Refresh user data, to reduce the risk of errors\n                currentUser = authenticationService.getCurrentUser();\n                long newAttachmentsSize = currentUser.getAttachmentsSize() - attachment.getSize();\n                currentUser.setAttachmentsSize(newAttachmentsSize);\n                userRepository.updateUser(currentUser);\n                break;\n            }\n        }\n    }\n\n    public Collection<Long> getDomainQuota() {\n        User currentUser = authenticationService.getCurrentUser();\n        DomainConfiguration domainConfiguration =\n                domainConfigurationRepository.findDomainConfigurationByDomain(currentUser.getDomain());\n\n        Long domainQuota = domainConfiguration.getStorageSizeAsLong();\n        Long userQuota = currentUser.getAttachmentsSize();\n\n        Long quota = (userQuota * 100) / domainQuota;\n\n        Collection<Long> taux = new ArrayList<Long>();\n        taux.add(quota);\n\n        log.debug(\"Domain quota attachments : {}\", quota);\n\n        return taux;\n    }\n    \n    private byte[] computeThumbnail(Attachment attachment) {\n    \tbyte[] result = new byte[0];\n    \t\n    \tString[] imagesExtensions = env.getProperty(\"tatami.attachment.thumbnail.extensions\").split(\",\");\n    \tfor(String ext : imagesExtensions) {\n    \t\tif(attachment.getFilename().endsWith(ext)) {\n    \t\t\tattachment.setHasThumbnail(true);\n    \t\t\tbreak;\n    \t\t}\n    \t}\n    \tif(attachment.getHasThumbnail()) {\n    \t\ttry {\n    \t\t\tBufferedImage thumbnail = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);\n\t\t\t\tthumbnail.createGraphics()\n\t\t\t\t\t\t.drawImage(ImageIO\n\t\t\t\t\t\t\t\t.read(new ByteArrayInputStream(attachment.getContent()))\n    \t\t\t\t\t\t\t.getScaledInstance(100, 100, BufferedImage.SCALE_SMOOTH), 0, 0, null);\n\t\t\t\tByteArrayOutputStream baos = new ByteArrayOutputStream();\n\t\t\t\tImageIO.write(thumbnail, \"png\", baos);\n\t\t\t\tbaos.flush();\n\t\t\t\tresult = baos.toByteArray();\n    \t\t} catch(IOException e) {\n    \t\t\tlog.error(\"Error creating thumbnail for attachment \"+attachment.getAttachmentId());\n    \t\t}\n    \t}\n    \treturn result;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/AvatarService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.config.Constants;\nimport fr.ippon.tatami.domain.Avatar;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.AvatarRepository;\nimport fr.ippon.tatami.repository.DomainConfigurationRepository;\nimport fr.ippon.tatami.repository.UserRepository;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Service;\n\nimport javax.imageio.ImageIO;\nimport javax.inject.Inject;\nimport java.awt.*;\nimport java.awt.image.BufferedImage;\nimport java.io.ByteArrayInputStream;\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\n\n@Service\npublic class AvatarService {\n\n    private static final Logger log = LoggerFactory.getLogger(AvatarService.class);\n\n    @Inject\n    private AvatarRepository avatarRepository;\n\n    @Inject\n    private DomainConfigurationRepository domainConfigurationRepository;\n\n    @Inject\n    private UserRepository userRepository;\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    public String createAvatar(Avatar avatar) {\n\n        User currentUser = authenticationService.getCurrentUser();\n\n        if (currentUser.getAvatar() != null && !(\"\").equals(currentUser.getAvatar())) {\n            deleteAvatar(currentUser.getAvatar());\n        }\n\n        try {\n            avatar.setContent(scaleImage(avatar.getContent()));\n        } catch (IOException e) {\n            log.info(\"Avatar could not be resized : \" + e.getMessage());\n            return null;\n        }\n\n        avatarRepository.createAvatar(avatar);\n\n        log.debug(\"Avatar created : {}\", avatar);\n\n        return avatar.getAvatarId();\n    }\n\n    public Avatar getAvatarById(String avatartId) {\n        log.debug(\"Get Avatar Id : {}\", avatartId);\n        return avatarRepository.findAvatarById(avatartId);\n    }\n\n    public void deleteAvatar(String avatarId) {\n        avatarRepository.removeAvatar(avatarId);\n\n        User currentUser = authenticationService.getCurrentUser();\n        userRepository.updateUser(currentUser);\n    }\n\n    private byte[] scaleImage(byte[] data) throws IOException {\n        ByteArrayInputStream in = new ByteArrayInputStream(data);\n\n        BufferedImage img = ImageIO.read(in);\n        int width = Constants.AVATAR_SIZE;\n        int height = Constants.AVATAR_SIZE;\n\n        Image image = img.getScaledInstance(width, height, Image.SCALE_SMOOTH);\n        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);\n        bufferedImage.getGraphics().drawImage(image, 0, 0, new Color(0, 0, 0), null);\n        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();\n        ImageIO.write(bufferedImage, \"jpg\", byteArrayOutputStream);\n\n        log.debug(\"New Byte size of Avatar : {} Kbits\", byteArrayOutputStream.size() / 1024);\n\n        return byteArrayOutputStream.toByteArray();\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/BlockService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.BlockRepository;\nimport fr.ippon.tatami.repository.UserRepository;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Service;\n\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Collection;\n\n/**\n * Created by matthieudelafourniere on 7/7/16.\n */\n@Service\npublic class BlockService {\n\n    private final Logger log = LoggerFactory.getLogger(BlockService.class);\n\n    @Inject\n    private BlockRepository blockRepository;\n\n    @Inject\n    private UserRepository userRepository;\n\n    public void blockUser(String currentLogin, String blockedLogin){\n        log.debug(currentLogin + \" is blocking \" + blockedLogin);\n        blockRepository.blockUser(currentLogin, blockedLogin);\n    }\n\n    public void unblockUser(String currentLogin, String unblockedLogin){\n        log.debug(currentLogin + \" is unblocking \" + unblockedLogin);\n        blockRepository.unblockUser(currentLogin, unblockedLogin);\n    }\n\n    public Collection<String> getUsersBlockedLoginForUser(String login){\n        return blockRepository.getUsersBlockedBy(login);\n    }\n\n    public Collection<User> getUsersBlockedForUser(String login){\n        Collection<String> blockedUsersLogins = getUsersBlockedLoginForUser(login);\n        Collection<User> blockedUsers = new ArrayList<User>();\n        for (String blockedLogin : blockedUsersLogins) {\n            User user = userRepository.findUserByLogin(blockedLogin);\n            if(user != null){\n                blockedUsers.add(user);\n            }\n        }\n        log.debug(\"Getting users blocked by {}\", login);\n        return blockedUsers;\n    }\n\n    public boolean isBlocked(String blockerLogin, String blockedLogin){\n        return blockRepository.isBlocked(blockerLogin, blockedLogin);\n    }\n}"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/CounterService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.repository.CounterRepository;\nimport org.springframework.stereotype.Service;\n\nimport javax.inject.Inject;\n\n/**\n * Manages the application's counters.\n *\n * @author François Descamps\n */\n@Service\npublic class CounterService {\n\n    @Inject\n    private CounterRepository counterRepository;\n\n    public long getNbStatus(String login) {\n        return counterRepository.getStatusCounter(login);\n    }\n\n    public long getNbFollowed(String login) {\n        return counterRepository.getFriendsCounter(login);\n    }\n\n    public long getNbFollowers(String login) {\n        return counterRepository.getFollowersCounter(login);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/FriendshipService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.domain.status.MentionFriend;\nimport fr.ippon.tatami.repository.*;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Service;\n\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * Manages the user's frienships.\n * <p/>\n * - A friend is someone you follow\n * - A follower is someone that follows you\n *\n * @author Julien Dubois\n */\n@Service\npublic class FriendshipService {\n\n    private final Logger log = LoggerFactory.getLogger(FriendshipService.class);\n\n    @Inject\n    private UserRepository userRepository;\n\n    @Inject\n    private FollowerRepository followerRepository;\n\n    @Inject\n    private FriendRepository friendRepository;\n\n    @Inject\n    private CounterRepository counterRepository;\n\n    @Inject\n    private StatusRepository statusRepository;\n\n    @Inject\n    private MentionlineRepository mentionlineRepository;\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    /**\n     * Follow a user.\n     *\n     * @return true if the operation succeeds, false otherwise\n     */\n    public boolean followUser(String usernameToFollow) {\n        log.debug(\"Following user : {}\", usernameToFollow);\n        User currentUser = authenticationService.getCurrentUser();\n        String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());\n        String loginToFollow = DomainUtil.getLoginFromUsernameAndDomain(usernameToFollow, domain);\n        User followedUser = userRepository.findUserByLogin(loginToFollow);\n        if (followedUser != null && !followedUser.equals(currentUser)) {\n            if (counterRepository.getFriendsCounter(currentUser.getLogin()) > 0) {\n                for (String alreadyFollowingTest : friendRepository.findFriendsForUser(currentUser.getLogin())) {\n                    if (alreadyFollowingTest.equals(loginToFollow)) {\n                        log.debug(\"User {} already follows user {}\", currentUser.getLogin(), followedUser.getLogin());\n                        return false;\n                    }\n                }\n            }\n            friendRepository.addFriend(currentUser.getLogin(), followedUser.getLogin());\n            counterRepository.incrementFriendsCounter(currentUser.getLogin());\n            followerRepository.addFollower(followedUser.getLogin(), currentUser.getLogin());\n            counterRepository.incrementFollowersCounter(followedUser.getLogin());\n            // mention the friend that the user has started following him\n            MentionFriend mentionFriend = statusRepository.createMentionFriend(followedUser.getLogin(), currentUser.getLogin());\n            mentionlineRepository.addStatusToMentionline(mentionFriend.getLogin(), mentionFriend.getStatusId());\n            log.debug(\"User {} now follows user {} \", currentUser.getLogin(), followedUser.getLogin());\n            return true;\n        } else {\n            log.debug(\"Followed user does not exist : \" + loginToFollow);\n            return false;\n        }\n    }\n\n    /**\n     * Un-follow a user.\n     *\n     * @return true if the operation succeeds, false otherwise\n     */\n    public boolean unfollowUser(String usernameToUnfollow) {\n        log.debug(\"Removing followed user : {}\", usernameToUnfollow);\n        User currentUser = authenticationService.getCurrentUser();\n        String loginToUnfollow = this.getLoginFromUsername(usernameToUnfollow);\n        User userToUnfollow = userRepository.findUserByLogin(loginToUnfollow);\n        return unfollowUser(currentUser, userToUnfollow);\n    }\n\n    /**\n     * Un-follow a user.\n     *\n     * @return true if the operation succeeds, false otherwise\n     */\n    public boolean unfollowUser(User currentUser, User userToUnfollow) {\n        if (userToUnfollow != null) {\n            String loginToUnfollow = userToUnfollow.getLogin();\n            boolean userAlreadyFollowed = false;\n            for (String alreadyFollowingTest : friendRepository.findFriendsForUser(currentUser.getLogin())) {\n                if (alreadyFollowingTest.equals(loginToUnfollow)) {\n                    userAlreadyFollowed = true;\n                }\n            }\n            if (userAlreadyFollowed) {\n                friendRepository.removeFriend(currentUser.getLogin(), loginToUnfollow);\n                counterRepository.decrementFriendsCounter(currentUser.getLogin());\n                followerRepository.removeFollower(loginToUnfollow, currentUser.getLogin());\n                counterRepository.decrementFollowersCounter(loginToUnfollow);\n                log.debug(\"User {} has stopped following user {}\", currentUser.getLogin(), loginToUnfollow);\n                return true;\n            } else {\n                return false;\n            }\n        } else {\n            log.debug(\"Followed user does not exist.\");\n            return false;\n        }\n    }\n\n    public List<String> getFriendIdsForUser(String login) {\n        log.debug(\"Retrieving friends for user : {}\", login);\n        return friendRepository.findFriendsForUser(login);\n    }\n\n    public Collection<String> getFollowerIdsForUser(String login) {\n        log.debug(\"Retrieving followed users : {}\", login);\n        return followerRepository.findFollowersForUser(login);\n    }\n\n    public Collection<User> getFriendsForUser(String username) {\n        String login = this.getLoginFromUsername(username);\n        Collection<String> friendLogins = friendRepository.findFriendsForUser(login);\n        Collection<User> friends = new ArrayList<User>();\n        for (String friendLogin : friendLogins) {\n            User friend = userRepository.findUserByLogin(friendLogin);\n            friends.add(friend);\n        }\n        return friends;\n    }\n\n    public Collection<User> getFollowersForUser(String username) {\n        String login = this.getLoginFromUsername(username);\n        Collection<String> followersLogins = followerRepository.findFollowersForUser(login);\n        Collection<User> followers = new ArrayList<User>();\n        for (String followerLogin : followersLogins) {\n            User follower = userRepository.findUserByLogin(followerLogin);\n            followers.add(follower);\n        }\n        return followers;\n    }\n\n    /**\n     * Finds if the \"userLogin\" user is followed by the current user.\n     */\n    public boolean isFollowed(String userLogin) {\n        log.debug(\"Retrieving if you follow this user : {}\", userLogin);\n        boolean isFollowed = false;\n        User user = authenticationService.getCurrentUser();\n        if (null != user && !userLogin.equals(user.getLogin())) {\n            Collection<String> users = getFollowerIdsForUser(userLogin);\n            if (null != users && users.size() > 0) {\n                for (String follower : users) {\n                    if (follower.equals(user.getLogin())) {\n                        isFollowed = true;\n                        break;\n                    }\n                }\n            }\n        }\n        return isFollowed;\n    }\n\n    /**\n     * Finds if  the current user user follow the \"userLogin\".\n     */\n    public boolean isFollowing(String userLogin) {\n        log.debug(\"Retrieving if you follow this user : {}\", userLogin);\n        boolean isFollowing = false;\n        User user = authenticationService.getCurrentUser();\n        if (null != user && !userLogin.equals(user.getLogin())) {\n            Collection<User> users = getFriendsForUser(user.getUsername());\n            if (null != users && users.size() > 0) {\n                for (User follower : users) {\n                    if (follower.getUsername().equals(userLogin)) {\n                        isFollowing = true;\n                        break;\n                    }\n                }\n            }\n        }\n        return isFollowing;\n    }\n\n    private String getLoginFromUsername(String username) {\n        User currentUser = authenticationService.getCurrentUser();\n        String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());\n        return DomainUtil.getLoginFromUsernameAndDomain(username, domain);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/GroupService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.*;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.dto.UserGroupDTO;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.cache.annotation.CacheEvict;\nimport org.springframework.cache.annotation.Cacheable;\nimport org.springframework.stereotype.Service;\n\nimport javax.inject.Inject;\nimport java.util.Collection;\nimport java.util.Map;\nimport java.util.TreeSet;\n\n/**\n * Service bean for managing groups.\n */\n@Service\npublic class GroupService {\n\n    private final Logger log = LoggerFactory.getLogger(GroupService.class);\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    @Inject\n    private GroupRepository groupRepository;\n\n    @Inject\n    private GroupDetailsRepository groupDetailsRepository;\n\n    @Inject\n    private GroupMembersRepository groupMembersRepository;\n\n    @Inject\n    private GroupCounterRepository groupCounterRepository;\n\n    @Inject\n    private UserGroupRepository userGroupRepository;\n\n    @Inject\n    private UserRepository userRepository;\n\n    @Inject\n    private SearchService searchService;\n\n    @Inject\n    private FriendRepository friendRepository;\n\n    @CacheEvict(value = \"group-user-cache\", allEntries = true)\n    public void createGroup(String name, String description, boolean publicGroup) {\n        log.debug(\"Creating group : {}\", name);\n        User currentUser = authenticationService.getCurrentUser();\n        String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());\n        String groupId = groupRepository.createGroup(domain);\n        groupDetailsRepository.createGroupDetails(groupId, name, description, publicGroup);\n        groupMembersRepository.addAdmin(groupId, currentUser.getLogin());\n        groupCounterRepository.incrementGroupCounter(domain, groupId);\n        userGroupRepository.addGroupAsAdmin(currentUser.getLogin(), groupId);\n        Group group = getGroupById(domain, groupId);\n        searchService.addGroup(group);\n    }\n\n    @CacheEvict(value = {\"group-user-cache\", \"group-cache\"}, allEntries = true)\n    public void editGroup(Group group) {\n        log.debug(\"Editing group : {}\", group.getGroupId());\n        groupDetailsRepository.editGroupDetails(group.getGroupId(),\n                group.getName(),\n                group.getDescription(),\n                group.isArchivedGroup());\n        searchService.removeGroup(group);\n        searchService.addGroup(group);\n    }\n\n    public Collection<UserGroupDTO> getMembersForGroup(String groupId, String login) {\n        Map<String, String> membersMap = groupMembersRepository.findMembers(groupId);\n        Collection<String> friendLogins = friendRepository.findFriendsForUser(login);\n        Collection<UserGroupDTO> userGroupDTOs = new TreeSet<UserGroupDTO>();\n        for (Map.Entry<String, String> member : membersMap.entrySet()) {\n            UserGroupDTO dto = new UserGroupDTO();\n            User user = userRepository.findUserByLogin(member.getKey());\n            dto.setLogin(user.getLogin());\n            dto.setUsername(user.getUsername());\n            dto.setAvatar(user.getAvatar());\n            dto.setFirstName(user.getFirstName());\n            dto.setLastName(user.getLastName());\n            dto.setRole(member.getValue());\n            dto.setActivated(user.getActivated());\n            if (friendLogins.contains(user.getLogin())) {\n                dto.setFriend(true);\n            }\n            if (login.equals(user.getLogin())) {\n                dto.setYou(true);\n            }\n            userGroupDTOs.add(dto);\n        }\n        return userGroupDTOs;\n    }\n\n\n\n\n    public UserGroupDTO getMembersForGroup(String groupId, User userWanted) {\n        Map<String, String> membersMap = groupMembersRepository.findMembers(groupId);\n        for (Map.Entry<String, String> member : membersMap.entrySet()) {\n            User user = userRepository.findUserByLogin(member.getKey());\n            if (user.getLogin() == userWanted.getLogin()) {\n                UserGroupDTO dto = new UserGroupDTO();\n                dto.setLogin(user.getLogin());\n                dto.setUsername(user.getUsername());\n                dto.setAvatar(user.getAvatar());\n                dto.setFirstName(user.getFirstName());\n                dto.setLastName(user.getLastName());\n                dto.setRole(member.getValue());\n                return dto;\n            }\n        }\n        return null;\n    }\n\n\n    @Cacheable(value = \"group-user-cache\", key = \"#user.login\")\n    public Collection<Group> getGroupsForUser(User user) {\n        Collection<String> groupIds = userGroupRepository.findGroups(user.getLogin());\n        return buildGroupIdsList(groupIds);\n    }\n\n    @Cacheable(value = \"group-user-cache\", key = \"#user.login\")\n    public Collection<Group> getGroupsOfUser(User user) {\n        Collection<String> groupIds = userGroupRepository.findGroups(user.getLogin());\n        return getGroupDetails(user, groupIds);\n    }\n\n\n    @Cacheable(value = \"group-cache\")\n    public Group getGroupById(String domain, String groupId) {\n        return internalGetGroupById(domain, groupId);\n    }\n\n    public Collection<Group> getGroupsWhereUserIsAdmin(User user) {\n        Collection<String> groupIds = userGroupRepository.findGroupsAsAdmin(user.getLogin());\n        return getGroupDetails(user, groupIds);\n    }\n\n    private Collection<Group> getGroupDetails(User currentUser, Collection<String> groupIds) {\n        String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());\n        Collection<Group> groups = new TreeSet<Group>();\n        for (String groupId : groupIds) {\n            Group group = internalGetGroupById(domain, groupId);\n            groups.add(group);\n        }\n        return groups;\n    }\n\n    public Collection<Group> getGroupsWhereCurrentUserIsAdmin() {\n        User currentUser = authenticationService.getCurrentUser();\n        return getGroupsWhereUserIsAdmin(currentUser);\n    }\n\n    private Group internalGetGroupById(String domain, String groupId) {\n        Group group = groupRepository.getGroupById(domain, groupId);\n        Group groupDetails = groupDetailsRepository.getGroupDetails(groupId);\n        group.setName(groupDetails.getName());\n        group.setPublicGroup(groupDetails.isPublicGroup());\n        group.setArchivedGroup(groupDetails.isArchivedGroup());\n        group.setDescription(groupDetails.getDescription());\n        long counter = groupCounterRepository.getGroupCounter(domain, groupId);\n        group.setCounter(counter);\n        return group;\n    }\n\n    @CacheEvict(value = {\"group-user-cache\", \"group-cache\"}, allEntries = true)\n    public void addMemberToGroup(User user, Group group) {\n        String groupId = group.getGroupId();\n        Collection<String> userCurrentGroupIds = userGroupRepository.findGroups(user.getLogin());\n        boolean userIsAlreadyAMember = false;\n        for (String testGroupId : userCurrentGroupIds) {\n            if (testGroupId.equals(groupId)) {\n                userIsAlreadyAMember = true;\n            }\n        }\n        if (!userIsAlreadyAMember) {\n            groupMembersRepository.addMember(groupId, user.getLogin());\n            log.debug(\"user=\" + user);\n            groupCounterRepository.incrementGroupCounter(user.getDomain(), groupId);\n            userGroupRepository.addGroupAsMember(user.getLogin(), groupId);\n        } else {\n            log.debug(\"User {} is already a member of group {}\", user.getLogin(), group.getName());\n        }\n    }\n\n    @CacheEvict(value = {\"group-user-cache\", \"group-cache\"}, allEntries = true)\n    public void removeMemberFromGroup(User user, Group group) {\n        String groupId = group.getGroupId();\n        Collection<String> userCurrentGroupIds = userGroupRepository.findGroups(user.getLogin());\n        boolean userIsAlreadyAMember = false;\n        for (String testGroupId : userCurrentGroupIds) {\n            if (testGroupId.equals(groupId)) {\n                userIsAlreadyAMember = true;\n            }\n        }\n        if (userIsAlreadyAMember) {\n            groupMembersRepository.removeMember(groupId, user.getLogin());\n            groupCounterRepository.decrementGroupCounter(user.getDomain(), groupId);\n            userGroupRepository.removeGroup(user.getLogin(), groupId);\n        } else {\n            log.debug(\"User {} is not a member of group {}\", user.getLogin(), group.getName());\n        }\n    }\n\n\n    public Collection<Group> buildGroupList(Collection<Group> groups) {\n        User currentUser = authenticationService.getCurrentUser();\n        return buildGroupList(currentUser, groups);\n    }\n\n    public Collection<Group> buildGroupList(User user, Collection<Group> groups) {\n\n        for (Group group : groups) {\n            buildGroup(user, group);\n        }\n\n        return groups;\n    }\n\n    public Group buildGroup(Group group) {\n        User currentUser = authenticationService.getCurrentUser();\n        return buildGroup(currentUser, group);\n    }\n\n    private Group getGroupFromUser(User currentUser, String groupId) {\n        Collection<Group> groups = getGroupsOfUser(currentUser);\n        for (Group testGroup : groups) {\n            if (testGroup.getGroupId().equals(groupId)) {\n                return testGroup;\n            }\n        }\n        return null;\n    }\n\n    private boolean isGroupManagedByCurrentUser(Group group) {\n        Collection<Group> groups = getGroupsWhereCurrentUserIsAdmin();\n        boolean isGroupManagedByCurrentUser = false;\n        for (Group testGroup : groups) {\n            if (testGroup.getGroupId().equals(group.getGroupId())) {\n                isGroupManagedByCurrentUser = true;\n                break;\n            }\n        }\n        return isGroupManagedByCurrentUser;\n    }\n\n    public Group buildGroup(User user, Group group) {\n        if(group != null ) {\n            if (isGroupManagedByCurrentUser(group)) {\n                group.setAdministrator(true);\n                group.setMember(true);\n            }\n            else if(group.isPublicGroup()) {\n                Group result = getGroupFromUser(user, group.getGroupId());\n                group.setAdministrator(false); // If we made it here, the user is not an admin\n                if (result != null) {\n                    group.setMember(true); // We found a group, so the user is a member\n                }\n                else {\n                    group.setMember(false); // Since no group was found, the user is not a member\n                }\n            }\n            else {\n                Group result = getGroupFromUser(user, group.getGroupId());\n                group.setAdministrator(false); // If we make it here, the user is not an admin\n                if (result == null) {\n                    log.info(\"Permission denied! User {} tried to access group ID = {} \", user.getLogin(), group.getGroupId());\n                    group.setMember(false); // No group found, therefore the user is not a member\n                    return null;\n                } else {\n                    group.setMember(true); // Since a group was found, we know the user is a member\n                }\n            }\n            long counter = 0;\n            for ( UserGroupDTO userGroup :  getMembersForGroup(group.getGroupId(),authenticationService.getCurrentUser().getLogin()) ) {\n                if(userGroup.isActivated()) {\n                    counter++;\n                }\n            }\n            group.setCounter(counter);\n        }\n        return group;\n    }\n\n    public Collection<Group> buildGroupIdsList(Collection<String> groupIds) {\n        Collection<Group> groups = new TreeSet<Group>();\n        for (String groupId : groupIds) {\n            groups.add(buildGroupIds(groupId));\n        }\n        return groups;\n    }\n\n    public Group buildGroupIds(String groupId) {\n        User currentUser = authenticationService.getCurrentUser();\n        return buildGroupIds(currentUser, groupId);\n    }\n\n    public Group buildGroupIds(User user, String groupId) {\n        String domain = DomainUtil.getDomainFromLogin(user.getLogin());\n        Group group = getGroupById(domain, groupId);\n        return buildGroup(group);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/MailDigestService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.domain.DigestType;\nimport fr.ippon.tatami.domain.Domain;\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.DomainRepository;\nimport fr.ippon.tatami.repository.MailDigestRepository;\nimport fr.ippon.tatami.repository.UserRepository;\nimport fr.ippon.tatami.service.dto.StatusDTO;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.scheduling.annotation.Scheduled;\nimport org.springframework.stereotype.Service;\n\nimport javax.inject.Inject;\nimport java.io.PrintWriter;\nimport java.io.StringWriter;\nimport java.util.*;\n\n/**\n * This service generates digest emails for subscribed users.\n *\n * @author Pierre Rust\n */\n@Service\npublic class MailDigestService {\n\n    private static final Logger log = LoggerFactory.getLogger(MailDigestService.class);\n\n    private final static int MAX_STATUS_DAILY_DIGEST = 10;\n    private final static int MAX_STATUS_WEEKLY_DIGEST = 10;\n\n    @Inject\n    private MailDigestRepository mailDigestRepository;\n\n    @Inject\n    private DomainRepository domainRepository;\n\n    @Inject\n    private UserRepository userRepository;\n\n    @Inject\n    private TimelineService timelineService;\n\n    @Inject\n    private MailService mailService;\n\n    @Inject\n    private SuggestionService suggestionService;\n\n    /**\n     * Sends daily digest. Must be run every day\n     */\n    @Scheduled(cron = \"0 0 22 * * ?\")\n    public void dailyDigest() {\n        log.info(\"Starting Daily digest mail process \");\n        Set<Domain> domains = domainRepository.getAllDomains();\n\n        String day = String.valueOf(Calendar.getInstance().get(Calendar.DAY_OF_WEEK));\n\n        for (Domain d : domains) {\n            log.info(\"Sending daily digest for domain {} and day {}\", d, day);\n            int pagination = 0;\n            List<String> logins;\n            do {\n                logins = mailDigestRepository.getLoginsRegisteredToDigest(\n                        DigestType.DAILY_DIGEST, d.getName(), day, pagination);\n                pagination = pagination + logins.size();\n\n                for (String login : logins) {\n                    try {\n                        handleDailyDigestPageForLogin(login);\n                    } catch (Exception e) {\n                        log.warn(\"An error has occured when generating daily digest for user \" + login + \": \" + e.getMessage());\n                        StringWriter stack = new StringWriter();\n                        PrintWriter pw = new PrintWriter(stack);\n                        e.printStackTrace(pw);\n                        log.debug(\"{}\", stack.toString());\n                    }\n                }\n            } while (logins.size() > 0);\n        }\n    }\n\n    /**\n     * Sends weekly digest.\n     * <p/>\n     * Will run every mondayday and send mails to all registered users\n     * <p/>\n     * If this is too many mails, this method could be tuned to\n     * distribute the load on every day of the week by only sending\n     * mails to users who have subscribed that same day.\n     */\n    @Scheduled(cron = \"0 0 01 ? * MON\")\n    public void weeklyDigest() {\n        log.info(\"Starting Weekly digest mail process \");\n\n        Set<Domain> domains = domainRepository.getAllDomains();\n\n        // sent digest for all domains\n        // for users that have register any day of the week\n        for (int i = 1; i < 8; ++i) {\n            String day = String.valueOf(i);\n\n            for (Domain d : domains) {\n                log.info(\"Sending weekly digest for domain {} and day {}\", d, i);\n                int pagination = 0;\n                List<String> logins;\n                do {\n                    logins = mailDigestRepository.getLoginsRegisteredToDigest(\n                            DigestType.WEEKLY_DIGEST, d.getName(),\n                            day, pagination);\n                    pagination = pagination + logins.size();\n\n                    for (String login : logins) {\n                        try {\n                            handleWeeklyDigestPageForLogin(login);\n                        } catch (Exception e) {\n                            log.warn(\"An error has occured when generating weekly digest for user \" + login + \": \" + e.getMessage());\n                            StringWriter stack = new StringWriter();\n                            PrintWriter pw = new PrintWriter(stack);\n                            e.printStackTrace(pw);\n                            log.debug(\"{}\", stack.toString());\n                        }\n                    }\n                } while (logins.size() > 0);\n            }\n        }\n    }\n\n    /**\n     * Fetch all necessary info for a daily digest mail\n     * and delegate the sending operation to mailService.\n     */\n    private void handleDailyDigestPageForLogin(String login) {\n        log.info(\"Preparing weekly digest for user \" + login);\n\n        User user = userRepository.findUserByLogin(login);\n\n        // we want statuses for the past 24 hours\n        Calendar cal = Calendar.getInstance();\n        cal.add(Calendar.DATE, -1);\n        Date yesterday = cal.getTime();\n\n        List<StatusDTO> digestStatuses = new ArrayList<StatusDTO>(MAX_STATUS_DAILY_DIGEST);\n        int nbStatusTotal = getStatusesForDigest(user, yesterday, MAX_STATUS_DAILY_DIGEST, digestStatuses);\n\n        Collection<User> suggestedUsers = suggestionService.suggestUsers(user.getLogin());\n\n        // TODO : we could look for popular messages\n        // especially if the user\n        // does not have anything in it's timeline and there are no suggested users for him\n\n        mailService.sendDailyDigestEmail(user, digestStatuses, nbStatusTotal, suggestedUsers);\n    }\n\n    /**\n     * Fetch all necessary info for a weekly digest mail\n     * and delegate the sending operation to mailService.\n     */\n    private void handleWeeklyDigestPageForLogin(String login) {\n        log.info(\"Preparing weekly digest for user \" + login);\n\n        User user = userRepository.findUserByLogin(login);\n\n        // we want statuses for the past week\n        Calendar cal = Calendar.getInstance();\n        cal.add(Calendar.DATE, -7);\n        Date lastWeek = cal.getTime();\n\n        List<StatusDTO> digestStatuses = new ArrayList<StatusDTO>(MAX_STATUS_WEEKLY_DIGEST);\n        int nbStatusTotal = getStatusesForDigest(user, lastWeek, MAX_STATUS_WEEKLY_DIGEST, digestStatuses);\n\n\n        Collection<User> suggestedUsers = suggestionService.suggestUsers(user.getLogin());\n        Collection<Group> suggestedGroups = suggestionService.suggestGroups(user.getLogin());\n\n        mailService.sendWeeklyDigestEmail(user, digestStatuses, nbStatusTotal,\n                suggestedUsers, suggestedGroups);\n    }\n\n    /**\n     * Build a list containing an extract of the status from an user timeline,\n     * except its own, since a given date.\n     *\n     * @param user           the user\n     * @param since_date     date since\n     * @param nbStatus       number of status to include in the extract\n     * @param digestStatuses selected status will be added to this list (ordered by date)\n     * @return the number of statuses\n     */\n    private int getStatusesForDigest(final User user, final Date since_date,\n                                     int nbStatus, List<StatusDTO> digestStatuses) {\n        String finish = null;\n        boolean dateReached = false;\n        List<StatusDTO> allStatuses = new ArrayList<StatusDTO>(50);\n\n        // collect all statuses since 'since_date' from the timeline\n        while (!dateReached) {\n            Collection<StatusDTO> statuses = timelineService.getUserTimeline(user.getLogin(), 200, null, finish);\n            statuses.size();\n            int count = 0;\n            if (statuses.isEmpty()) {\n                dateReached = true;\n            }\n\n            for (StatusDTO status : statuses) {\n                if (status.getStatusDate().before(since_date)) {\n                    dateReached = true;\n                    break;\n                } else {\n                    // Do not includes user's own status in digest\n                    if (!status.getUsername().equals(user.getUsername())) {\n                        allStatuses.add(status);\n                    }\n                }\n                count++;\n                if (count == statuses.size() && !dateReached) {\n                    finish = status.getStatusId();\n                }\n            }\n        }\n\n        int nbStatusTotal = allStatuses.size();\n        if (nbStatusTotal > 0) {\n\n            // now select some of theses statuses\n            if (allStatuses.size() > nbStatus) {\n                Collections.shuffle(allStatuses);\n                digestStatuses.addAll(allStatuses.subList(0, nbStatus));\n                Collections.sort(digestStatuses, new Comparator<StatusDTO>() {\n                    @Override\n                    public int compare(StatusDTO statusDTO, StatusDTO statusDTO2) {\n                        return statusDTO.getStatusDate().compareTo(statusDTO2.getStatusDate());\n                    }\n                });\n            } else {\n                digestStatuses.addAll(allStatuses);\n            }\n        }\n        return nbStatusTotal;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/MailService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.domain.status.AbstractStatus;\nimport fr.ippon.tatami.domain.status.Status;\nimport fr.ippon.tatami.repository.DomainRepository;\nimport fr.ippon.tatami.repository.UserRepository;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.security.TatamiUserDetailsService;\nimport fr.ippon.tatami.service.dto.StatusDTO;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport org.apache.velocity.app.VelocityEngine;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.context.MessageSource;\nimport org.springframework.core.env.Environment;\nimport org.springframework.mail.MailException;\nimport org.springframework.mail.SimpleMailMessage;\nimport org.springframework.mail.javamail.JavaMailSenderImpl;\nimport org.springframework.scheduling.annotation.Async;\nimport org.springframework.stereotype.Service;\nimport org.springframework.ui.velocity.VelocityEngineUtils;\n\nimport javax.annotation.PostConstruct;\nimport javax.inject.Inject;\nimport javax.mail.MessagingException;\nimport java.util.*;\n\n/**\n * Send e-mails.\n * <p/>\n * Templates are implemented with velocity.\n * Emails localisation is based on system locale, this could be improved by storing a preferred locale\n * for each user.\n *\n * @author Julien Dubois\n */\n@Service\npublic class MailService {\n\n    private static final Logger log = LoggerFactory.getLogger(MailService.class);\n\n    @Inject\n    private Environment env;\n\n    @Inject\n    private MessageSource mailMessageSource;\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    @Inject\n    private UserService userService;\n\n    @Inject\n    private DomainRepository domainRepository;\n\n    private String host;\n\n    private int port;\n\n    private String smtpUser;\n\n    private String smtpPassword;\n\n    private String smtpTls;\n\n    private String from;\n\n    private String tatamiUrl;\n\n    private Locale locale;\n\n    // TODO: this can be used for external mail template configuration\n    private final String templateRoot = \"/META-INF/tatami/mails/\";\n    private final String templateSuffix = \"Email\";\n\n    @Inject\n    private VelocityEngine velocityEngine;\n\n    @Inject\n    private TatamiUserDetailsService tatamiUserDetailsService;\n\n    @PostConstruct\n    public void init() {\n        this.host = env.getProperty(\"smtp.host\");\n        if (!env.getProperty(\"smtp.port\").equals(\"\")) {\n            this.port = env.getProperty(\"smtp.port\", Integer.class);\n        }\n        this.smtpUser = env.getProperty(\"smtp.user\");\n        this.smtpPassword = env.getProperty(\"smtp.password\");\n        this.smtpTls = env.getProperty(\"smtp.tls\");\n        this.from = env.getProperty(\"smtp.from\");\n        this.tatamiUrl = env.getProperty(\"tatami.url\");\n\n        // TODO : we should probably let the user choose which language he wants to use for email, and store this as a preference\n        this.locale = Locale.getDefault();\n    }\n\n    @Async\n    public void sendRegistrationEmail(String registrationKey, User user) {\n\n        String registrationUrl = tatamiUrl + \"/#/register?key=\" + registrationKey;\n        log.debug(\"Sending registration e-mail to User '{}', Url='{}' \" +\n                \"with locale : '{}'\", user.getLogin(), registrationUrl, locale);\n\n        Map<String, Object> model = new HashMap<String, Object>();\n        model.put(\"user\", user);\n        model.put(\"registrationUrl\", registrationUrl);\n\n        sendTextFromTemplate(user.getLogin(), model, \"registration\", this.locale);\n    }\n\n    @Async\n    public void sendInvitationEmail(String email, User user) {\n        log.debug(\"Sending invitation e-mail to email '{}'\", email);\n\n        Map<String, Object> model = new HashMap<String, Object>();\n        model.put(\"user\", user.getLogin());\n        model.put(\"invitationUrl\", tatamiUrl);\n\n        sendTextFromTemplate(user.getLogin(), model, \"invitationMessage\", this.locale);\n    }\n\n    @Async\n    public void sendLostPasswordEmail(String registrationKey, User user) {\n\n        String url = tatamiUrl + \"/#/register?key=\" + registrationKey;\n        log.debug(\"Sending lost password e-mail to User '{}', Url='{}' with locale : '{}'\", user.getLogin(), url, locale);\n\n        Map<String, Object> model = new HashMap<String, Object>();\n        model.put(\"user\", user);\n        model.put(\"reinitUrl\", url);\n\n        sendTextFromTemplate(user.getLogin(), model, \"lostPassword\", this.locale);\n    }\n\n    @Async\n    public void sendValidationEmail(User user, String password) {\n        log.debug(\"Sending validation e-mail to User '{}', non-encrypted Password='{}' \" +\n                \"with locale : '{}'\", user.getLogin(), password, locale);\n\n        Map<String, Object> model = new HashMap<String, Object>();\n        model.put(\"user\", user);\n        model.put(\"password\", password);\n\n        sendTextFromTemplate(user.getLogin(), model, \"validation\", this.locale);\n    }\n\n    @Async\n    public void sendPasswordReinitializedEmail(User user, String password) {\n        log.debug(\"Sending password re-initialization e-mail to User '{}', non-encrypted Password='{}' \" +\n                \"with locale : '{}'\", user.getLogin(), password, locale);\n\n        Map<String, Object> model = new HashMap<String, Object>();\n        model.put(\"user\", user);\n        model.put(\"password\", password);\n\n        sendTextFromTemplate(user.getLogin(), model, \"passwordReinitialized\", this.locale);\n    }\n\n    @Async\n    public void sendUserPrivateMessageEmail(User mentionnedUser, Status status) {\n        log.debug(\"Sending Private Message e-mail to User '{}' \" +\n                \"with locale : '{}'\", mentionnedUser.getLogin(), locale);\n        String url = tatamiUrl + \"/#/home/status/\" + status.getStatusId();\n\n        Map<String, Object> model = new HashMap<String, Object>();\n        model.put(\"user\", mentionnedUser);\n        model.put(\"status\", status);\n        model.put(\"statusUrl\", url);\n\n        sendTextFromTemplate(mentionnedUser.getLogin(), model, \"userPrivateMessage\", this.locale);\n    }\n\n    @Async\n    public void sendUserMentionEmail(User mentionnedUser, Status status) {\n        log.debug(\"Sending Mention e-mail to User '{}' with locale : '{}'\", mentionnedUser.getLogin(), locale);\n        String url = tatamiUrl + \"/#/home/status/\" + status.getStatusId();\n\n        Map<String, Object> model = new HashMap<String, Object>();\n        model.put(\"user\", mentionnedUser);\n        model.put(\"status\", status);\n        model.put(\"statusUrl\", url);\n\n        sendTextFromTemplate(mentionnedUser.getLogin(), model, \"userMention\", this.locale);\n    }\n\n    @Async\n    public void sendDailyDigestEmail(User user, List<StatusDTO> statuses, int nbStatus,\n                                     Collection<User> suggestedUsers) {\n        log.debug(\"Sending daily digest e-mail to User '{}'\", user.getLogin());\n\n        Map<String, Object> model = new HashMap<String, Object>();\n        model.put(\"user\", user);\n        model.put(\"tatamiUrl\", tatamiUrl);\n        model.put(\"statuses\", statuses);\n        model.put(\"nbStatus\", nbStatus);\n        model.put(\"suggestedUsers\", suggestedUsers);\n\n        sendTextFromTemplate(user.getLogin(), model, \"dailyDigest\", this.locale);\n    }\n\n\n    @Async\n    public void sendWeeklyDigestEmail(User user, List<StatusDTO> statuses, int nbStatus,\n                                      Collection<User> suggestedUsers,\n                                      Collection<Group> suggestedGroup) {\n        log.debug(\"Sending weekly digest e-mail to User '{}'\", user.getLogin());\n\n        Map<String, Object> model = new HashMap<String, Object>();\n        model.put(\"user\", user);\n        model.put(\"tatamiUrl\", tatamiUrl);\n        model.put(\"statuses\", statuses);\n        model.put(\"nbStatus\", nbStatus);\n        model.put(\"suggestedUsers\", suggestedUsers);\n        model.put(\"suggestedGroups\", suggestedGroup);\n\n        sendTextFromTemplate(user.getLogin(), model, \"weeklyDigest\", this.locale);\n    }\n\n    @Async\n    public void sendReportedStatusEmail(String emailReporting, AbstractStatus status) {\n        log.debug(\"Sending reported status e-mail to User '{}' with locale : '{}'\", locale);\n        String url = tatamiUrl + \"/#/home/status/\" + status.getStatusId();\n\n        Map<String, Object> model = new HashMap<String, Object>();\n        model.put(\"status\", status);\n        model.put(\"statusUrl\", url);\n\n        for(String email : tatamiUserDetailsService.getAdminUsers()) {\n            sendTextFromTemplate(email, model, \"reportedStatus\", this.locale);\n        }\n    }\n\n    @Async\n    public void sendDeactivatedEmail(String email) {\n        log.debug(\"Sending deactivation e-mail to User '{}' with locale : '{}'\", email, locale);\n        Map<String, Object> model = new HashMap<String, Object>();\n        model.put(\"deactivatedEmail\", email);\n        model.put(\"username\", DomainUtil.getUsernameFromLogin(email));\n        sendTextFromTemplate(email, model, \"deactivatedUser\", this.locale);\n    }\n\n    public boolean connectSmtpServer() {\n        if (host != null && !host.equals(\"\")) {\n            JavaMailSenderImpl sender = configureJavaMailSender();\n            try {\n                sender.getSession().getTransport().connect();\n                return true;\n            } catch (MessagingException e) {\n                return false;\n            }\n        } else {\n            return false;\n        }\n    }\n\n    private void sendEmail(String email, String subject, String text) {\n        if (host != null && !host.equals(\"\")) {\n            JavaMailSenderImpl sender = configureJavaMailSender();\n            SimpleMailMessage message = new SimpleMailMessage();\n            message.setTo(email);\n            message.setFrom(from);\n            message.setSubject(subject);\n            message.setText(text);\n            try {\n                sender.send(message);\n                log.debug(\"Sent e-mail to User '{}'!\", email);\n            } catch (MailException e) {\n                log.warn(\"Warning! SMTP server error, could not send e-mail.\");\n                log.debug(\"SMTP Error : {}\", e.getMessage());\n                log.debug(\"Did you configure your SMTP settings in /META-INF/tatami/tatami.properties ?\");\n            }\n        } else {\n            log.debug(\"SMTP server is not configured in /META-INF/tatami/tatami.properties\");\n        }\n    }\n\n    private JavaMailSenderImpl configureJavaMailSender() {\n        JavaMailSenderImpl sender = new JavaMailSenderImpl();\n        sender.setHost(host);\n        sender.setPort(port);\n        sender.setUsername(smtpUser);\n        sender.setPassword(smtpPassword);\n        if (smtpTls != null && !smtpTls.equals(\"\")) {\n            Properties sendProperties = new Properties();\n            sendProperties.setProperty(\"mail.smtp.starttls.enable\", \"true\");\n            sender.setJavaMailProperties(sendProperties);\n        }\n        return sender;\n    }\n\n    /**\n     * Generate and send the mail corresponding to the given template.\n     */\n    private void sendTextFromTemplate(String email, Map<String, Object> model, String template, Locale locale) {\n        model.put(\"messages\", mailMessageSource);\n        model.put(\"locale\", locale);\n\n        String subject = mailMessageSource.getMessage(template + \".title\", null, locale);\n        String text = VelocityEngineUtils.mergeTemplateIntoString(velocityEngine, templateRoot + template + templateSuffix,\n                \"utf-8\", model);\n        log.debug(\"e-mail text  '{}\", text);\n\n        sendEmail(email, subject, text);\n    }\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/MentionService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.domain.status.Status;\nimport fr.ippon.tatami.repository.MentionlineRepository;\nimport fr.ippon.tatami.repository.UserRepository;\nimport org.springframework.beans.factory.annotation.Autowired;\nimport org.springframework.stereotype.Service;\n\nimport javax.inject.Inject;\n\n/**\n * Notifies a user when he is mentionned.\n */\n@Service\npublic class MentionService {\n\n    @Inject\n    private MentionlineRepository mentionlineRepository;\n\n    @Inject\n    private MailService mailService;\n\n    @Autowired(required = false)\n    private ApplePushService applePushService;\n\n    @Inject\n    private UserRepository userRepository;\n\n    /**\n     * A status that mentions a user is put in the user's mentionline and in his timeline.\n     * The mentioned user can also be notified by email.\n     */\n    public void mentionUser(String mentionedLogin, Status status) {\n        mentionlineRepository.addStatusToMentionline(mentionedLogin, status.getStatusId());\n\n        User mentionnedUser = userRepository.findUserByLogin(mentionedLogin);\n\n        if (mentionnedUser != null && (mentionnedUser.getPreferencesMentionEmail() == null || mentionnedUser.getPreferencesMentionEmail().equals(true))) {\n            if (status.getStatusPrivate()) { // Private status\n                mailService.sendUserPrivateMessageEmail(mentionnedUser, status);\n                if (applePushService != null) {\n                    applePushService.notifyUser(mentionedLogin, status);\n                }\n            } else {\n                mailService.sendUserMentionEmail(mentionnedUser, status);\n                if (applePushService != null) {\n                    applePushService.notifyUser(mentionedLogin, status);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/SearchService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.domain.status.Status;\n\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * Service used to search statuses and users.\n */\npublic interface SearchService {\n\n    public static final int DEFAULT_PAGE_SIZE = 20;\n    public static final int DEFAULT_TOP_N_SEARCH_USER = 8;\n\n    /**\n     * Reset the search engine.\n     * <p/>\n     * This is used to do a full reindexation of all the data.\n     *\n     * @return if the reset was completed OK\n     */\n    boolean reset();\n\n    /**\n     * Add a status to the index.\n     *\n     * @param status the status to add : can't be null\n     */\n    void addStatus(Status status);\n\n    void addStatuses(Collection<Status> statuses);\n\n    /**\n     * Delete a status from the index.\n     *\n     * @param status the status to delete\n     */\n    void removeStatus(Status status);\n\n    /**\n     * Search an item in the index.\n     *\n     * @param query the query : mandatory\n     * @param page  the page to return\n     * @param size  the size of a page\n     */\n    List<String> searchStatus(String domain,\n                              String query,\n                              int page,\n                              int size);\n\n\n    /**\n     * Add a user to the index.\n     *\n     * @param user the user to add : can't be null\n     */\n    void addUser(User user);\n\n    void addUsers(Collection<User> users);\n\n    void removeUser(User user);\n\n    Collection<String> searchUserByPrefix(String domain,\n                                          String prefix);\n\n    void addGroup(Group group);\n\n    void removeGroup(Group group);\n\n    Collection<Group> searchGroupByPrefix(String domain, String prefix, int size);\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/StatsService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.domain.UserStatusStat;\nimport fr.ippon.tatami.repository.DaylineRepository;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport org.springframework.stereotype.Service;\n\nimport javax.inject.Inject;\nimport java.text.SimpleDateFormat;\nimport java.util.Collection;\nimport java.util.Date;\n\n@Service\npublic class StatsService {\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    @Inject\n    private DaylineRepository daylineRepository;\n\n    static final SimpleDateFormat DAYLINE_KEY_FORMAT = new SimpleDateFormat(\"ddMMyyyy\");\n\n    /**\n     * The dayline contains a day's status.\n     *\n     * @return a status list\n     */\n    public Collection<UserStatusStat> getDayline() {\n        Date today = new Date();\n        return getDayline(today);\n    }\n\n    /**\n     * The dayline contains a day's status.\n     *\n     * @param date the day to retrieve the status of\n     * @return a status list\n     */\n    public Collection<UserStatusStat> getDayline(Date date) {\n        if (date == null) {\n            date = new Date();\n        }\n        User currentUser = authenticationService.getCurrentUser();\n        String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());\n        String day = DAYLINE_KEY_FORMAT.format(date);\n        return daylineRepository.getDayline(domain, day);\n    }\n}"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/StatusUpdateService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.config.Constants;\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.domain.status.*;\nimport fr.ippon.tatami.repository.*;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.dto.StatusDTO;\nimport fr.ippon.tatami.service.exception.ArchivedGroupException;\nimport fr.ippon.tatami.service.exception.ReplyStatusException;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport org.apache.camel.util.Time;\nimport org.apache.commons.lang.StringEscapeUtils;\nimport org.apache.openjpa.jdbc.kernel.exps.Abs;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Service;\n\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Calendar;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n@Service\npublic class StatusUpdateService {\n\n    private static final Logger log = LoggerFactory.getLogger(StatusUpdateService.class);\n\n    private static final Pattern PATTERN_LOGIN = Pattern.compile(\"@[^\\\\s,\\\\p{Punct}]+\");\n\n    private static final Pattern PATTERN_HASHTAG = Pattern.compile(\"(^|\\\\s)#([^\\\\s !\\\"#$%&\\'()*+,./:;<=>?@\\\\\\\\\\\\[\\\\]^_`{|}~-]+)\");\n\n    @Inject\n    private FollowerRepository followerRepository;\n\n    @Inject\n    private TagFollowerRepository tagFollowerRepository;\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    @Inject\n    private DaylineRepository daylineRepository;\n\n    @Inject\n    private StatusRepository statusRepository;\n\n    @Inject\n    private TimelineRepository timelineRepository;\n\n    @Inject\n    private MentionService mentionService;\n\n    @Inject\n    private UserlineRepository userlineRepository;\n\n    @Inject\n    private TaglineRepository taglineRepository;\n\n    @Inject\n    private TagCounterRepository tagCounterRepository;\n\n    @Inject\n    private UserGroupRepository userGroupRepository;\n\n    @Inject\n    private GrouplineRepository grouplineRepository;\n\n    @Inject\n    private GroupMembersRepository groupMembersRepository;\n\n    @Inject\n    private GroupService groupService;\n\n    @Inject\n    private TrendRepository trendsRepository;\n\n    @Inject\n    private UserTrendRepository userTrendRepository;\n\n    @Inject\n    private DiscussionRepository discussionRepository;\n\n    @Inject\n    private CounterRepository counterRepository;\n\n    @Inject\n    private SearchService searchService;\n\n    @Inject\n    private DomainlineRepository domainlineRepository;\n\n    @Inject\n    private StatusAttachmentRepository statusAttachmentRepository;\n\n    @Inject\n    private AtmosphereService atmosphereService;\n\n    @Inject\n    private MailService mailService;\n\n    @Inject\n    private StatusReportRepository statusReportRepository;\n\n    @Inject\n    private BlockRepository blockRepository;\n\n    @Inject\n    private TimelineService timelineService;\n\n    public void postStatus(String content, boolean statusPrivate, Collection<String> attachmentIds, String geoLocalization) {\n        createStatus(content, statusPrivate, null, \"\", \"\", \"\", attachmentIds, null, geoLocalization);\n    }\n\n    public void postStatus(String content, boolean statusPrivate, Collection<String> attachmentIds) {\n        createStatus(content, statusPrivate, null, \"\", \"\", \"\", attachmentIds);\n    }\n\n    public void postStatusToGroup(String content, Group group, Collection<String> attachmentIds, String geoLocalization) {\n        createStatus(content, false, group, \"\", \"\", \"\", attachmentIds, null, geoLocalization);\n    }\n\n    public void postStatusAsUser(String content, User user) {\n        createStatus(content, false, null, \"\", \"\", \"\", null, user, null);\n    }\n\n    public void replyToStatus(String content, String replyTo, Collection<String> attachmentIds) throws ArchivedGroupException, ReplyStatusException {\n        AbstractStatus abstractStatus = statusRepository.findStatusById(replyTo);\n        if (abstractStatus != null &&\n                !abstractStatus.getType().equals(StatusType.STATUS) &&\n                !abstractStatus.getType().equals(StatusType.SHARE) &&\n                !abstractStatus.getType().equals(StatusType.ANNOUNCEMENT)) {\n\n            log.debug(\"Cannot reply to a status of this type\");\n            throw new ReplyStatusException();\n        }\n        if (abstractStatus != null &&\n                abstractStatus.getType().equals(StatusType.SHARE)) {\n\n            log.debug(\"Replacing the share by the original status\");\n            Share share = (Share) abstractStatus;\n            AbstractStatus abstractRealStatus = statusRepository.findStatusById(share.getOriginalStatusId());\n            abstractStatus = abstractRealStatus;\n        } else if (abstractStatus != null &&\n                abstractStatus.getType().equals(StatusType.ANNOUNCEMENT)) {\n\n            log.debug(\"Replacing the announcement by the original status\");\n            Announcement announcement = (Announcement) abstractStatus;\n            AbstractStatus abstractRealStatus = statusRepository.findStatusById(announcement.getOriginalStatusId());\n            abstractStatus = abstractRealStatus;\n        }\n\n        Status status = (Status) abstractStatus;\n        Group group = null;\n        if (status.getGroupId() != null) {\n            group = groupService.getGroupById(status.getDomain(), status.getGroupId());\n\n            if (group.isArchivedGroup()) {\n                throw new ArchivedGroupException();\n            }\n        }\n        if (!status.getReplyTo().equals(\"\")) {\n            log.debug(\"Replacing the status by the status at the origin of the discussion\");\n            // Original status is also a reply, replying to the real original status instead\n            AbstractStatus abstractRealOriginalStatus = statusRepository.findStatusById(status.getDiscussionId());\n            if (abstractRealOriginalStatus == null ||\n                    !abstractRealOriginalStatus.getType().equals(StatusType.STATUS)) {\n\n                throw new ReplyStatusException();\n            }\n            Status realOriginalStatus = (Status) abstractRealOriginalStatus;\n\n            Status replyStatus = createStatus(\n                    content,\n                    realOriginalStatus.getStatusPrivate(),\n                    group,\n                    realOriginalStatus.getStatusId(),\n                    status.getStatusId(),\n                    status.getUsername(),\n                    attachmentIds);\n\n            discussionRepository.addReplyToDiscussion(realOriginalStatus.getStatusId(), replyStatus.getStatusId());\n        } else {\n            log.debug(\"Replying directly to the status at the origin of the disucssion\");\n            // The original status of the discussion is the one we reply to\n            Status replyStatus =\n                    createStatus(content,\n                            status.getStatusPrivate(),\n                            group,\n                            status.getStatusId(),\n                            status.getStatusId(),\n                            status.getUsername(),\n                            attachmentIds);\n\n            discussionRepository.addReplyToDiscussion(status.getStatusId(), replyStatus.getStatusId());\n        }\n    }\n\n    private Status createStatus(String content,\n                                boolean statusPrivate,\n                                Group group,\n                                String discussionId,\n                                String replyTo,\n                                String replyToUsername,\n                                Collection<String> attachmentIds) {\n\n        return createStatus(\n                content,\n                statusPrivate,\n                group,\n                discussionId,\n                replyTo,\n                replyToUsername,\n                attachmentIds,\n                null, null);\n    }\n\n    private Status createStatus(String content,\n                                boolean statusPrivate,\n                                Group group,\n                                String discussionId,\n                                String replyTo,\n                                String replyToUsername,\n                                Collection<String> attachmentIds,\n                                User user,\n                                String geoLocalization) {\n\n        content = StringEscapeUtils.unescapeHtml(content);\n        long startTime = 0;\n        if (log.isInfoEnabled()) {\n            startTime = Calendar.getInstance().getTimeInMillis();\n            log.debug(\"Creating new status : {}\", content);\n        }\n        String currentLogin;\n        if (user == null) {\n            currentLogin = authenticationService.getCurrentUser().getLogin();\n        } else {\n            currentLogin = user.getLogin();\n        }\n        String domain = DomainUtil.getDomainFromLogin(currentLogin);\n\n        Status status =\n                statusRepository.createStatus(currentLogin,\n                        statusPrivate,\n                        group,\n                        attachmentIds,\n                        content,\n                        discussionId,\n                        replyTo,\n                        replyToUsername,\n                        geoLocalization);\n\n        if (attachmentIds != null && attachmentIds.size() > 0) {\n            for (String attachmentId : attachmentIds) {\n                statusAttachmentRepository.addAttachmentId(status.getStatusId(),\n                        attachmentId);\n            }\n        }\n\n        // add status to the timeline\n        addStatusToTimelineAndNotify(currentLogin, status);\n\n        if (status.getStatusPrivate()) { // Private status\n            // add status to the mentioned users' timeline\n            manageMentions(status, null, currentLogin, domain, new ArrayList<String>());\n\n        } else { // Public status\n            Collection<String> followersForUser = followerRepository.findFollowersForUser(currentLogin);\n\n            // add status to the dayline, userline\n            String day = StatsService.DAYLINE_KEY_FORMAT.format(status.getStatusDate());\n            daylineRepository.addStatusToDayline(status, day);\n            userlineRepository.addStatusToUserline(status.getLogin(), status.getStatusId());\n\n            // add the status to the group line and group followers\n            manageGroups(status, group, followersForUser);\n\n            // tag managgement\n            manageStatusTags(status, group);\n\n            // add status to the mentioned users' timeline\n            manageMentions(status, group, currentLogin, domain, followersForUser);\n\n            // Increment status count for the current user\n            counterRepository.incrementStatusCounter(currentLogin);\n\n            // Add to the searchStatus engine\n            searchService.addStatus(status);\n\n            // add status to the company wall\n            addToCompanyWall(status, group);\n        }\n\n        if (log.isInfoEnabled()) {\n            long finishTime = Calendar.getInstance().getTimeInMillis();\n            log.info(\"Status created in \" + (finishTime - startTime) + \"ms.\");\n        }\n        return status;\n    }\n\n    private void manageGroups(Status status, Group group, Collection<String> followersForUser) {\n        if (group != null) {\n            grouplineRepository.addStatusToGroupline(group.getGroupId(), status.getStatusId());\n            Collection<String> groupMemberLogins = groupMembersRepository.findMembers(group.getGroupId()).keySet();\n            // For all people following the group\n            for (String groupMemberLogin : groupMemberLogins) {\n                addStatusToTimelineAndNotify(groupMemberLogin, status);\n            }\n            if (isPublicGroup(group)) { // for people not following the group but following the user\n                for (String followerLogin : followersForUser) {\n                    if (!groupMemberLogins.contains(followerLogin)) {\n                        addStatusToTimelineAndNotify(followerLogin, status);\n                    }\n                }\n            }\n        } else { // only people following the user\n            for (String followerLogin : followersForUser) {\n                addStatusToTimelineAndNotify(followerLogin, status);\n            }\n        }\n    }\n\n\n    private void addToCompanyWall(Status status, Group group) {\n        if (isPublicGroup(group)) {\n            domainlineRepository.addStatusToDomainline(status.getDomain(), status.getStatusId());\n        }\n    }\n\n    /**\n     * Parses the status to find tags, and add those tags to the TagLine and the Trends.\n     * <p/>\n     * The Tatami Bot is a specific use case : as it sends a lot of statuses, it may pollute the global trends,\n     * so it is excluded from it.\n     */\n    private void manageStatusTags(Status status, Group group) {\n        Matcher m = PATTERN_HASHTAG.matcher(status.getContent());\n        while (m.find()) {\n            String tag = m.group(2);\n            if (tag != null && !tag.isEmpty() && !tag.contains(\"#\")) {\n                log.debug(\"Found tag : {}\", tag);\n                taglineRepository.addStatusToTagline(tag, status);\n                tagCounterRepository.incrementTagCounter(status.getDomain(), tag);\n                //Excludes the Tatami Bot from the global trend\n                if (!status.getUsername().equals(Constants.TATAMIBOT_NAME)) {\n                    trendsRepository.addTag(status.getDomain(), tag);\n                }\n                userTrendRepository.addTag(status.getLogin(), tag);\n\n                // Add the status to all users following this tag\n                addStatusToTagFollowers(status, group, tag);\n            }\n        }\n    }\n\n    private void manageMentions(Status status, Group group, String currentLogin, String domain, Collection<String> followersForUser) {\n        Matcher m = PATTERN_LOGIN.matcher(status.getContent());\n        while (m.find()) {\n            String mentionedUsername = extractUsernameWithoutAt(m.group());\n            if (mentionedUsername != null &&\n                    !mentionedUsername.equals(currentLogin) &&\n                    !followersForUser.contains(mentionedUsername)) {\n\n                log.debug(\"Mentionning : {}\", mentionedUsername);\n                String mentionedLogin =\n                        DomainUtil.getLoginFromUsernameAndDomain(mentionedUsername, domain);\n\n                // If this is a private group, and if the mentioned user is not in the group, he will not see the status\n                if (!isPublicGroup(group)) {\n                    Collection<String> groupIds = userGroupRepository.findGroups(mentionedLogin);\n                    if (groupIds.contains(group.getGroupId())) { // The user is part of the private group\n                        mentionUser(mentionedLogin, status);\n                    }\n                } else { // This is a public status\n                    mentionUser(mentionedLogin, status);\n                }\n            }\n        }\n    }\n\n    private void addStatusToTagFollowers(Status status, Group group, String tag) {\n        Collection<String> followersForTag =\n                tagFollowerRepository.findFollowers(status.getDomain(), tag);\n\n        if (isPublicGroup(group)) { // This is a public status\n            for (String followerLogin : followersForTag) {\n                addStatusToTimelineAndNotify(followerLogin, status);\n            }\n        } else {  // This is a private status\n            for (String followerLogin : followersForTag) {\n                Collection<String> groupIds = userGroupRepository.findGroups(followerLogin);\n                if (groupIds.contains(group.getGroupId())) { // The user is part of the private group\n                    addStatusToTimelineAndNotify(followerLogin, status);\n                }\n            }\n        }\n    }\n\n    /**\n     * A status that mentions a user is put in the user's mentionline and in his timeline.\n     * The mentioned user can also be notified by email or iOS push.\n     */\n    private void mentionUser(String mentionedLogin, Status status) {\n        addStatusToTimelineAndNotify(mentionedLogin, status);\n        mentionService.mentionUser(mentionedLogin, status);\n    }\n\n    private String extractUsernameWithoutAt(String dest) {\n        return dest.substring(1, dest.length());\n    }\n\n    private boolean isPublicGroup(Group group) {\n        return group == null || group.isPublicGroup();\n    }\n\n    /**\n     * Adds the status to the timeline and notifies the user with Atmosphere.\n     */\n    private void addStatusToTimelineAndNotify(String login, Status status) {\n        timelineRepository.addStatusToTimeline(login, status.getStatusId());\n        atmosphereService.notifyUser(login, status);\n    }\n\n    public void reportStatus(String reportingLogin, String statusId) {\n        log.debug(\"Reported Status: \", statusId);\n        String domain = DomainUtil.getDomainFromLogin(reportingLogin);\n        statusReportRepository.reportStatus(domain, statusId, reportingLogin);\n        mailService.sendReportedStatusEmail(reportingLogin, statusRepository.findStatusById(statusId));\n\n    }\n\n    private List<String> getAllReportedStatuses(String domain){\n        return statusReportRepository.findReportedStatuses(domain);\n    }\n\n    public Collection<StatusDTO> findReportedStatuses (){\n        List<String> reportedStatusId = getAllReportedStatuses(authenticationService.getCurrentUser().getDomain());\n        return timelineService.buildStatusList(reportedStatusId);\n    }\n    public void approveReportedStatus(String statusId){\n        if(authenticationService.hasAuthenticatedUser() && authenticationService.isCurrentUserInRole(\"ROLE_ADMIN\")){\n            log.debug(\"Admin approving reported status {}\", statusId );\n            User currentUser = authenticationService.getCurrentUser();\n            statusReportRepository.unreportStatus(currentUser.getDomain(), statusId);\n        } else {\n            log.warn(\"Attempt to approve reported status {} but is not admin\", statusId);\n        }\n    }\n\n    public void deleteReportedStatus(String statusId){\n        if(authenticationService.hasAuthenticatedUser() && authenticationService.isCurrentUserInRole(\"ROLE_ADMIN\")){\n            log.debug(\"Admin deleting reported status {}\", statusId );\n            User currentUser = authenticationService.getCurrentUser();\n            statusReportRepository.unreportStatus(currentUser.getDomain(), statusId);\n            timelineService.removeStatus(statusId);\n        } else {\n            log.warn(\"Attempt to delete reported status {} but is not admin\", statusId);\n        }\n    }\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/SuggestionService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.UserGroupRepository;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport org.springframework.cache.annotation.Cacheable;\nimport org.springframework.stereotype.Service;\n\nimport javax.inject.Inject;\nimport java.util.*;\n\nimport static fr.ippon.tatami.service.util.AnalysisUtil.findMostUsedKeys;\nimport static fr.ippon.tatami.service.util.AnalysisUtil.incrementKeyCounterInMap;\nimport static fr.ippon.tatami.service.util.AnalysisUtil.reduceCollectionSize;\n\n/**\n * Analyses data to find suggestions of users, groups... for the current user.\n */\n@Service\npublic class SuggestionService {\n\n    private static final int SAMPLE_SIZE = 20;\n\n    private static final int SUB_SAMPLE_SIZE = 100;\n\n    private static final int SUGGESTIONS_SIZE = 3;\n\n    @Inject\n    private FriendshipService friendshipService;\n\n    @Inject\n    private UserGroupRepository userGroupRepository;\n\n    @Inject\n    private UserService userService;\n\n    @Inject\n    private GroupService groupService;\n\n    /**\n     * Size of the sample data used to find the suggestions.\n     */\n\n    @Cacheable(\"suggest-users-cache\")\n    public Collection<User> suggestUsers(String login) {\n        Map<String, Integer> userCount = new HashMap<String, Integer>();\n        List<String> friendIds = friendshipService.getFriendIdsForUser(login);\n        List<String> sampleFriendIds = reduceCollectionSize(friendIds, SAMPLE_SIZE);\n        for (String friendId : sampleFriendIds) {\n            List<String> friendsOfFriend = friendshipService.getFriendIdsForUser(friendId);\n            friendsOfFriend = reduceCollectionSize(friendsOfFriend, SUB_SAMPLE_SIZE);\n            for (String friendOfFriend : friendsOfFriend) {\n                if (!friendIds.contains(friendOfFriend) && !friendOfFriend.equals(login)) {\n                    incrementKeyCounterInMap(userCount, friendOfFriend);\n                }\n            }\n        }\n        List<String> mostFollowedUsers = findMostUsedKeys(userCount);\n        List<User> userSuggestions = new ArrayList<User>();\n        for (String mostFollowedUser : mostFollowedUsers) {\n            User suggestion = userService.getUserByLogin(mostFollowedUser);\n            if ( suggestion.getActivated() ){\n                userSuggestions.add(suggestion);\n            }\n        }\n        if (userSuggestions.size() > SUGGESTIONS_SIZE) {\n            return userSuggestions.subList(0, SUGGESTIONS_SIZE);\n        } else {\n            return userSuggestions;\n        }\n    }\n\n    @Cacheable(\"suggest-groups-cache\")\n    public Collection<Group> suggestGroups(String login) {\n        Map<String, Integer> groupCount = new HashMap<String, Integer>();\n        List<String> groupIds = userGroupRepository.findGroups(login);\n        List<String> friendIds = friendshipService.getFriendIdsForUser(login);\n        friendIds = reduceCollectionSize(friendIds, SAMPLE_SIZE);\n        for (String friendId : friendIds) {\n            List<String> groupsOfFriend = userGroupRepository.findGroups(friendId);\n            for (String groupOfFriend : groupsOfFriend) {\n                if (!groupIds.contains(groupOfFriend)) {\n                    incrementKeyCounterInMap(groupCount, groupOfFriend);\n                }\n            }\n        }\n        List<String> mostFollowedGroups = findMostUsedKeys(groupCount);\n        List<Group> groupSuggestions = new ArrayList<Group>();\n        String domain = DomainUtil.getDomainFromLogin(login);\n        for (String mostFollowedGroup : mostFollowedGroups) {\n            Group suggestion = groupService.getGroupById(domain, mostFollowedGroup);\n            if (suggestion.isPublicGroup()) { // Only suggest public groups for the moment\n                groupSuggestions.add(suggestion);\n            }\n        }\n        if (groupSuggestions.size() > SUGGESTIONS_SIZE) {\n            return groupSuggestions.subList(0, SUGGESTIONS_SIZE);\n        } else {\n            return groupSuggestions;\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/TagMembershipService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.TagFollowerRepository;\nimport fr.ippon.tatami.repository.UserTagRepository;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport fr.ippon.tatami.web.rest.dto.Tag;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Service;\n\nimport javax.inject.Inject;\n\n/**\n * Manages the tag memberships.\n * <p/>\n * - A tag follower is someone who follows a tag\n * - A user tag is a tag followed by a user\n *\n * @author Julien Dubois\n */\n@Service\npublic class TagMembershipService {\n\n    private final Logger log = LoggerFactory.getLogger(TagMembershipService.class);\n\n    @Inject\n    private TagFollowerRepository tagFollowerRepository;\n\n    @Inject\n    private UserTagRepository userTagRepository;\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    public boolean followTag(Tag tag) {\n        log.debug(\"Following tag : {}\", tag);\n        User currentUser = authenticationService.getCurrentUser();\n        for (String alreadyFollowingTest : userTagRepository.findTags(currentUser.getLogin())) {\n            if (alreadyFollowingTest.equals(tag.getName())) {\n                log.debug(\"User {} already follows tag {}\", currentUser.getLogin(), tag);\n                return false;\n            }\n        }\n        String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());\n        userTagRepository.addTag(currentUser.getLogin(), tag.getName());\n        tagFollowerRepository.addFollower(domain, tag.getName(), currentUser.getLogin());\n        log.debug(\"User \" + currentUser.getLogin() +\n                \" now follows tag \" + tag);\n\n        return true;\n    }\n\n    public boolean unfollowTag(Tag tag) {\n        log.debug(\"Removing followed tag : {}\", tag);\n        User currentUser = authenticationService.getCurrentUser();\n        boolean tagAlreadyFollowed = false;\n        for (String alreadyFollowingTest : userTagRepository.findTags(currentUser.getLogin())) {\n            if (alreadyFollowingTest.equals(tag.getName())) {\n                tagAlreadyFollowed = true;\n            }\n        }\n        if (tagAlreadyFollowed) {\n            String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());\n            userTagRepository.removeTag(currentUser.getLogin(), tag.getName());\n            tagFollowerRepository.removeFollower(domain, tag.getName(), currentUser.getLogin());\n            log.debug(\"User \" + currentUser.getLogin() +\n                    \" has stopped following tag \" + tag);\n\n            return true;\n        } else {\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/TimelineService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.*;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.security.DomainViolationException;\nimport fr.ippon.tatami.service.dto.StatusDTO;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Service;\nimport fr.ippon.tatami.domain.status.*;\n\nimport javax.inject.Inject;\nimport java.util.*;\n\n/**\n * Manages the timeline.\n *\n * @author Julien Dubois\n */\n@Service\npublic class TimelineService {\n\n    private static final Logger log = LoggerFactory.getLogger(TimelineService.class);\n\n    private static final String hashtagDefault = \"---\";\n\n    @Inject\n    private UserService userService;\n\n    @Inject\n    private StatusRepository statusRepository;\n\n    @Inject\n    private SharesRepository sharesRepository;\n\n    @Inject\n    private DiscussionRepository discussionRepository;\n\n    @Inject\n    private CounterRepository counterRepository;\n\n    @Inject\n    private TimelineRepository timelineRepository;\n\n    @Inject\n    private MentionlineRepository mentionlineRepository;\n\n    @Inject\n    private UserlineRepository userlineRepository;\n\n    @Inject\n    private FavoritelineRepository favoritelineRepository;\n\n    @Inject\n    private TaglineRepository taglineRepository;\n\n    @Inject\n    private GrouplineRepository grouplineRepository;\n\n    @Inject\n    private DomainlineRepository domainlineRepository;\n\n    @Inject\n    private DomainRepository domainRepository;\n\n    @Inject\n    private FollowerRepository followerRepository;\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    @Inject\n    private GroupService groupService;\n\n    @Inject\n    private SearchService searchService;\n\n    @Inject\n    private AtmosphereService atmosphereService;\n\n    @Inject\n    private BlockService blockService;\n\n    public StatusDTO getStatus(String statusId) {\n        List<String> line = new ArrayList<String>();\n        line.add(statusId);\n        Collection<StatusDTO> statusCollection = buildStatusList(line);\n        if (statusCollection.isEmpty()) {\n            return null;\n        } else {\n            StatusDTO statusDTO = statusCollection.iterator().next();\n            // Private message check\n            if (statusDTO.isStatusPrivate()) {\n                String login = authenticationService.getCurrentUser().getLogin();\n                if (!timelineRepository.isStatusInTimeline(login, statusId)) {\n                    log.info(\"User \" + login + \" tried to access private message ID \" + statusId);\n                    return null;\n                }\n            }\n            return statusDTO;\n        }\n    }\n\n    /**\n     * Get the details for a status\n     * - Who shared this status\n     * - The discussion in which this status belongs to\n     */\n    public StatusDetails getStatusDetails(String statusId) {\n        log.debug(\"Looking for status details\");\n        StatusDetails details = new StatusDetails();\n\n        AbstractStatus abstractStatus = statusRepository.findStatusById(statusId);\n        if (abstractStatus == null) {\n            log.debug(\"Status could not be found\");\n            return null;\n        }\n        Status status = null;\n        if (abstractStatus.getType() == null || abstractStatus.getType().equals(StatusType.STATUS)) {\n            status = (Status) abstractStatus;\n        } else if (abstractStatus.getType().equals(StatusType.SHARE)) {\n            Share share = (Share) abstractStatus;\n            AbstractStatus originalStatus = statusRepository.findStatusById(share.getOriginalStatusId());\n            if (originalStatus == null) {\n                log.debug(\"Original Status could not be found\");\n                return details;\n            } else if (originalStatus.getType() != null && !originalStatus.getType().equals(StatusType.STATUS)) {\n                log.debug(\"Original status does not have the correct type\");\n                return details;\n            }\n            status = (Status) originalStatus;\n        } else if (abstractStatus.getType().equals(StatusType.ANNOUNCEMENT)) {\n            Announcement announcement = (Announcement) abstractStatus;\n            AbstractStatus originalStatus = statusRepository.findStatusById(announcement.getOriginalStatusId());\n            if (originalStatus == null) {\n                log.debug(\"Original Status could not be found\");\n                return details;\n            } else if (originalStatus.getType() != null && !originalStatus.getType().equals(StatusType.STATUS)) {\n                log.debug(\"Original status does not have the correct type\");\n                return details;\n            }\n            status = (Status) originalStatus;\n        } else {\n            log.debug(\"Status does not have the correct type\");\n            return details;\n        }\n        details.setStatusId(status.getStatusId());\n\n        // Shares management\n        Collection<String> sharedByLogins = sharesRepository.findLoginsWhoSharedAStatus(status.getStatusId());\n        details.setSharedByLogins(userService.getUsersByLogin(sharedByLogins));\n        log.debug(\"Status shared by {} users\", sharedByLogins.size());\n\n        // Discussion management\n        Collection<String> statusIdsInDiscussion = new LinkedHashSet<String>();\n        String replyTo = status.getReplyTo();\n        if (replyTo != null && !replyTo.equals(\"\")) { // If this is a reply, get the original discussion\n            // Add the original discussion\n            statusIdsInDiscussion.add(status.getDiscussionId());\n            // Add the replies\n            statusIdsInDiscussion.addAll(discussionRepository.findStatusIdsInDiscussion(status.getDiscussionId()));\n            // Remove the current status from the list\n            statusIdsInDiscussion.remove(status.getStatusId());\n        } else { // This is the original discussion\n            // Add the replies\n            statusIdsInDiscussion.addAll(discussionRepository.findStatusIdsInDiscussion(status.getStatusId()));\n        }\n\n        // Transform the Set to a Map<String, String>\n        List<String> line = new ArrayList<String>();\n        for (String statusIdInDiscussion : statusIdsInDiscussion) {\n            line.add(statusIdInDiscussion);\n        }\n        // Enrich the details object with the complete statuses in the discussion\n        Collection<StatusDTO> statusesInDiscussion = buildStatusList(line);\n        details.setDiscussionStatuses(statusesInDiscussion);\n        return details;\n    }\n\n    public Collection<StatusDTO> buildStatusList(List<String> line) {\n        User currentUser = null;\n        Collection<Group> usergroups;\n        List<String> favoriteLine;\n        if (authenticationService.hasAuthenticatedUser()) {\n            currentUser = authenticationService.getCurrentUser();\n            usergroups = groupService.getGroupsForUser(currentUser);\n            favoriteLine = favoritelineRepository.getFavoriteline(currentUser.getLogin());\n        } else {\n            usergroups = Collections.emptyList();\n            favoriteLine = Collections.emptyList();\n        }\n        Collection<StatusDTO> statuses = new ArrayList<StatusDTO>(line.size());\n        for (String statusId : line) {\n            AbstractStatus abstractStatus = statusRepository.findStatusById(statusId);\n            if (abstractStatus != null) {\n                User statusUser = userService.getUserByLogin(abstractStatus.getLogin());\n                if (statusUser != null) {\n                    // Security check\n                    // bypass the security check when no user is logged in \n                    // => for non-authenticated rss access \n                    if ((currentUser != null) && !statusUser.getDomain().equals(currentUser.getDomain())) {\n                        throw new DomainViolationException(\"User \" + currentUser + \" tried to access \" +\n                                \" status : \" + abstractStatus);\n                    }\n\n                    StatusDTO statusDTO = new StatusDTO();\n                    statusDTO.setStatusId(abstractStatus.getStatusId());\n                    statusDTO.setStatusDate(abstractStatus.getStatusDate());\n                    statusDTO.setGeoLocalization(abstractStatus.getGeoLocalization());\n                    statusDTO.setActivated(statusUser.getActivated());\n                    StatusType type = abstractStatus.getType();\n                    if (type == null) {\n                        statusDTO.setType(StatusType.STATUS);\n                    } else {\n                        statusDTO.setType(abstractStatus.getType());\n                    }\n\n                    if (abstractStatus.getType().equals(StatusType.SHARE)) {\n                        Share share = (Share) abstractStatus;\n                        AbstractStatus originalStatus = statusRepository.findStatusById(share.getOriginalStatusId());\n                        if (originalStatus != null) { // Find the original status\n                            statusDTO.setTimelineId(share.getStatusId());\n                            statusDTO.setSharedByUsername(share.getUsername());\n                            statusUser = userService.getUserByLogin(originalStatus.getLogin());\n                            addStatusToLine(statuses, statusDTO, originalStatus, statusUser, usergroups, favoriteLine);\n                        } else {\n                            log.debug(\"Original status has been deleted\");\n                        }\n                    } else if (abstractStatus.getType().equals(StatusType.MENTION_SHARE)) {\n                        MentionShare mentionShare = (MentionShare) abstractStatus;\n                        AbstractStatus originalStatus = statusRepository.findStatusById(mentionShare.getOriginalStatusId());\n                        if (originalStatus != null) { // Find the status that was shared\n                            statusDTO.setTimelineId(mentionShare.getStatusId());\n                            statusDTO.setSharedByUsername(mentionShare.getUsername());\n                            statusUser = userService.getUserByLogin(mentionShare.getLogin());\n                            addStatusToLine(statuses, statusDTO, originalStatus, statusUser, usergroups, favoriteLine);\n                        } else {\n                            log.debug(\"Mentioned status has been deleted\");\n                        }\n                    } else if (abstractStatus.getType().equals(StatusType.MENTION_FRIEND)) {\n                        MentionFriend mentionFriend = (MentionFriend) abstractStatus;\n                        statusDTO.setTimelineId(mentionFriend.getStatusId());\n                        //statusDTO.setSharedByUsername(mentionFriend.getUsername());\n                        statusUser = userService.getUserByLogin(mentionFriend.getFollowerLogin());\n                        statusDTO.setFirstName(statusUser.getFirstName());\n                        statusDTO.setLastName(statusUser.getLastName());\n                        statusDTO.setAvatar(statusUser.getAvatar());\n                        statusDTO.setUsername(statusUser.getUsername());\n                        statuses.add(statusDTO);\n                    } else if (abstractStatus.getType().equals(StatusType.ANNOUNCEMENT)) {\n                        Announcement announcement = (Announcement) abstractStatus;\n                        AbstractStatus originalStatus = statusRepository.findStatusById(announcement.getOriginalStatusId());\n                        if (originalStatus != null) { // Find the status that was announced\n                            statusDTO.setTimelineId(announcement.getStatusId());\n                            statusDTO.setSharedByUsername(announcement.getUsername());\n                            statusUser = userService.getUserByLogin(originalStatus.getLogin());\n                            addStatusToLine(statuses, statusDTO, originalStatus, statusUser, usergroups, favoriteLine);\n                        } else {\n                            log.debug(\"Announced status has been deleted\");\n                        }\n                    } else { // Normal status\n                        statusDTO.setTimelineId(abstractStatus.getStatusId());\n                        addStatusToLine(statuses, statusDTO, abstractStatus, statusUser, usergroups, favoriteLine);\n                    }\n                } else {\n                    log.debug(\"Deleted user : {}\", abstractStatus.getLogin());\n                }\n            } else {\n                log.debug(\"Deleted status : {}\", statusId);\n            }\n        }\n\n        for(StatusDTO statusDTO : statuses)\n            statusDTO.setShareByMe(shareByMe(statusDTO));\n\n        return statuses;\n    }\n\n    //@Cacheable(\"isSharedByMe\")\n    private Boolean shareByMe(StatusDTO statusDTO)\n    {\n        Boolean isSharedByMe;\n\n        Collection<String> loginWhoShare = sharesRepository.findLoginsWhoSharedAStatus(statusDTO.getStatusId());\n        User currentUser = authenticationService.getCurrentUser();\n        if(loginWhoShare.contains(currentUser.getLogin()) )\n            isSharedByMe = true;\n        else if(currentUser.getUsername().equals(statusDTO.getSharedByUsername())) //Greg ce n'est pas normal de devoir faire ça\n            isSharedByMe = true;\n        else\n            isSharedByMe = false;\n\n        return isSharedByMe;\n    }\n\n    /**\n     * Find old statuses.\n     *\n     * Statuses might not be up to date on the current line : they might have been deleted, or the user has lost the\n     * permission to see them.\n     */\n    private Collection<String> findStatusesToCleanUp(List<String> statuses, Collection<StatusDTO> dtos) {\n        Collection<String> statusIdsToCleanUp = new ArrayList<String>();\n        for (String statusId : statuses) {\n            boolean statusToDelete = true;\n            for (StatusDTO statusDTO : dtos) {\n                if (statusDTO.getStatusId().equals(statusId)) {\n                    statusToDelete = false;\n                }\n            }\n            if (statusToDelete) {\n                statusIdsToCleanUp.add(statusId);\n            }\n        }\n        return statusIdsToCleanUp;\n    }\n\n    private void addStatusToLine(Collection<StatusDTO> line,\n                                 StatusDTO statusDTO,\n                                 AbstractStatus abstractStatus,\n                                 User statusUser,\n                                 Collection<Group> usergroups,\n                                 List<String> favoriteLine) {\n\n        Status status = (Status) abstractStatus;\n        // Group check\n        boolean hiddenStatus = false;\n        if (status.getGroupId() != null) {\n            statusDTO.setGroupId(status.getGroupId());\n            Group group = groupService.getGroupById(statusUser.getDomain(), statusDTO.getGroupId());\n            // if this is a private group and the user is not part of it, he cannot see the status\n            if (!group.isPublicGroup() && !usergroups.contains(group)) {\n                hiddenStatus = true;\n            } else {\n                statusDTO.setPublicGroup(group.isPublicGroup());\n                statusDTO.setGroupName(group.getName());\n            }\n        }\n\n        if (!hiddenStatus) {\n            if (status.getHasAttachments() != null && status.getHasAttachments()) {\n                statusDTO.setAttachments(status.getAttachments());\n            }\n            statusDTO.setContent(status.getContent());\n            statusDTO.setUsername(statusUser.getUsername());\n            if (status.getStatusPrivate() == null) {\n                statusDTO.setStatusPrivate(false);\n            } else {\n                statusDTO.setStatusPrivate(status.getStatusPrivate());\n            }\n            statusDTO.setReplyTo(status.getReplyTo());\n            statusDTO.setReplyToUsername(status.getReplyToUsername());\n            if (favoriteLine.contains(statusDTO.getStatusId())) {\n                statusDTO.setFavorite(true);\n            } else {\n                statusDTO.setFavorite(false);\n            }\n            statusDTO.setFirstName(statusUser.getFirstName());\n            statusDTO.setLastName(statusUser.getLastName());\n            statusDTO.setAvatar(statusUser.getAvatar());\n            statusDTO.setDetailsAvailable(status.isDetailsAvailable());\n            line.add(statusDTO);\n        }\n    }\n\n    /**\n     * The mentionline contains a statuses where the current user is mentioned.\n     *\n     * @return a status list\n     */\n    public Collection<StatusDTO> getMentionline(int nbStatus, String start, String finish) {\n        User currentUser = authenticationService.getCurrentUser();\n        List<String> statuses =\n                mentionlineRepository.getMentionline(currentUser.getLogin(), nbStatus, start, finish);\n\n        Collection<StatusDTO> dtos = buildStatusList(statuses);\n        if (statuses.size() != dtos.size()) {\n            Collection<String> statusIdsToDelete = findStatusesToCleanUp(statuses, dtos);\n            mentionlineRepository.removeStatusesFromMentionline(currentUser.getLogin(), statusIdsToDelete);\n            return getMentionline(nbStatus, start, finish);\n        }\n        dtos = filterStatusFromBlockedUsers(dtos);\n        return dtos;\n    }\n\n    /**\n     * The tagline contains a tag's statuses\n     *\n     * @param tag      the tag to retrieve the timeline of\n     * @param nbStatus the number of status to retrieve, starting from most recent ones\n     * @return a status list\n     */\n    public Collection<StatusDTO> getTagline(String tag, int nbStatus, String start, String finish) {\n        if (tag == null || tag.isEmpty()) {\n            tag = hashtagDefault;\n        }\n        User currentUser = authenticationService.getCurrentUser();\n        String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());\n        List<String> statuses = taglineRepository.getTagline(domain, tag, nbStatus, start, finish);\n\n        Collection<StatusDTO> dtos = buildStatusList(statuses);\n        if (statuses.size() != dtos.size()) {\n            Collection<String> statusIdsToDelete = findStatusesToCleanUp(statuses, dtos);\n            taglineRepository.removeStatusesFromTagline(tag, domain, statusIdsToDelete);\n            return getTagline(tag, nbStatus, start, finish);\n        }\n        dtos = filterStatusFromBlockedUsers(dtos);\n        return dtos;\n    }\n\n    /**\n     * The groupline contains a group's statuses.\n     *\n     * @return a status list\n     */\n    public Collection<StatusDTO> getGroupline(String groupId, Integer nbStatus, String start, String finish) {\n        List<String> statuses = grouplineRepository.getGroupline(groupId, nbStatus, start, finish);\n        Collection<StatusDTO> dtos = buildStatusList(statuses);\n        if (statuses.size() != dtos.size()) {\n            Collection<String> statusIdsToDelete = findStatusesToCleanUp(statuses, dtos);\n            grouplineRepository.removeStatusesFromGroupline(groupId, statusIdsToDelete);\n            return getGroupline(groupId, nbStatus, start, finish);\n        }\n        dtos = filterStatusFromBlockedUsers(dtos);\n        return dtos;\n    }\n\n    /**\n     * The timeline contains the user's status merged with his friends status\n     *\n     * @param nbStatus the number of status to retrieve, starting from most recent ones\n     * @return a status list\n     */\n    public Collection<StatusDTO> getTimeline(int nbStatus, String start, String finish) {\n        String login = authenticationService.getCurrentUser().getLogin();\n        return getUserTimeline(login, nbStatus, start, finish);\n    }\n\n    /**\n     * The timeline contains the user's status merged with his friends status.\n     *\n     * getUserTimeline returns the time line for an arbitrary user (and not only\n     * the logged-in user).\n     *\n     * This is used for RSS syndication.\n     *\n     * @param login    of the user we want the timeline of\n     * @param nbStatus the number of status to retrieve, starting from most recent ones\n     * @return a status list\n     */\n    public Collection<StatusDTO> getUserTimeline(String login, int nbStatus, String start, String finish) {\n        List<String> statuses =\n                timelineRepository.getTimeline(login, nbStatus, start, finish);\n\n        Collection<StatusDTO> dtos = buildStatusList(statuses);\n        if (statuses.size() != dtos.size()) {\n            Collection<String> statusIdsToDelete = findStatusesToCleanUp(statuses, dtos);\n            timelineRepository.removeStatusesFromTimeline(login, statusIdsToDelete);\n            return getTimeline(nbStatus, start, finish);\n        }\n        dtos = filterStatusFromBlockedUsers(dtos);\n        return dtos;\n    }\n\n    /**\n     * The domainline contains all the public statuses of the domain (status with no group, or\n     * in a public group), for the last 30 days.\n     *\n     * @param nbStatus the number of status to retrieve, starting from most recent ones\n     * @return a status list\n     */\n    public Collection<StatusDTO> getDomainline(int nbStatus, String start, String finish) {\n        User currentUser = authenticationService.getCurrentUser();\n        String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());\n        List<String> statuses =\n                domainlineRepository.getDomainline(domain, nbStatus, start, finish);\n\n        Collection<StatusDTO> dtos = buildStatusList(statuses);\n        if (statuses.size() != dtos.size()) {\n            Collection<String> statusIdsToDelete = findStatusesToCleanUp(statuses, dtos);\n            domainlineRepository.removeStatusFromDomainline(domain, statusIdsToDelete);\n            return getDomainline(nbStatus, start, finish);\n        }\n        dtos = filterStatusFromBlockedUsers(dtos);\n        return dtos;\n    }\n\n\n    /**\n     * The userline contains the user's own status\n     *\n     * @param username the user to retrieve the userline of\n     * @param nbStatus the number of status to retrieve, starting from most recent ones\n     * @return a status list\n     */\n    public Collection<StatusDTO> getUserline(String username, int nbStatus, String start, String finish) {\n        String login;\n        User currentUser = authenticationService.getCurrentUser();\n        if (username == null || username.isEmpty()) { // current user\n            login = currentUser.getLogin();\n        } else {  // another user, in the same domain\n            String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());\n            login = DomainUtil.getLoginFromUsernameAndDomain(username, domain);\n        }\n        List<String> statuses = userlineRepository.getUserline(login, nbStatus, start, finish);\n        Collection<StatusDTO> dtos = buildStatusList(statuses);\n        if (statuses.size() != dtos.size()) {\n            Collection<String> statusIdsToDelete = findStatusesToCleanUp(statuses, dtos);\n            userlineRepository.removeStatusesFromUserline(login, statusIdsToDelete);\n            return getUserline(username, nbStatus, start, finish);\n        }\n        dtos = filterStatusFromBlockedUsers(dtos);\n        return dtos;\n    }\n\n    public void removeStatus(String statusId) {\n        log.debug(\"Removing status : {}\", statusId);\n        AbstractStatus abstractStatus = statusRepository.findStatusById(statusId);\n        if (abstractStatus != null && abstractStatus.getType().equals(StatusType.STATUS)) {\n            Status status = (Status) abstractStatus;\n            User currentUser = authenticationService.getCurrentUser();\n            if (status.getLogin().equals(currentUser.getLogin()) || authenticationService.isCurrentUserInRole(\"ROLE_ADMIN\")) {\n                statusRepository.removeStatus(status);\n                counterRepository.decrementStatusCounter(currentUser.getLogin());\n                searchService.removeStatus(status);\n            }\n        } else if (abstractStatus.getType().equals(StatusType.ANNOUNCEMENT)) {\n            User currentUser = authenticationService.getCurrentUser();\n            if (abstractStatus.getLogin().equals(currentUser.getLogin())) {\n                statusRepository.removeStatus(abstractStatus);\n            }\n        } else if(abstractStatus.getType().equals(StatusType.SHARE) && authenticationService.isCurrentUserInRole(\"ROLE_ADMIN\")) {\n            Share currentShare = (Share) abstractStatus;\n            // We delete the original status\n            String originalStatusId = currentShare.getOriginalStatusId();\n            removeStatus(originalStatusId);\n        } else {\n            log.debug(\"Cannot remove status of this type\");\n        }\n    }\n\n    public void shareStatus(String statusId) {\n        log.debug(\"Share status : {}\", statusId);\n        String currentLogin = this.authenticationService.getCurrentUser().getLogin();\n        AbstractStatus abstractStatus = statusRepository.findStatusById(statusId);\n        if (abstractStatus != null) {\n            if (abstractStatus.getType().equals(StatusType.STATUS)) {\n                Status status = (Status) abstractStatus;\n                internalShareStatus(currentLogin, status);\n            } else if (abstractStatus.getType().equals(StatusType.SHARE)) {\n                Share currentShare = (Share) abstractStatus;\n                // We share the original status\n                Status originalStatus = (Status) statusRepository.findStatusById(currentShare.getOriginalStatusId());\n                internalShareStatus(currentLogin, originalStatus);\n            } else {\n                log.warn(\"Cannot share this type of status: \" + abstractStatus);\n            }\n        } else {\n            log.debug(\"Cannot share this status, as it does not exist: {}\", abstractStatus);\n        }\n    }\n\n    private void internalShareStatus(String currentLogin, Status status) {\n        // create share\n        Share share = statusRepository.createShare(currentLogin, status.getStatusId());\n\n        // add status to the user's userline and timeline\n        userlineRepository.shareStatusToUserline(currentLogin, share);\n        shareStatusToTimelineAndNotify(currentLogin, currentLogin, share);\n        // add status to the follower's timelines\n        Collection<String> followersForUser = followerRepository.findFollowersForUser(currentLogin);\n        for (String followerLogin : followersForUser) {\n            shareStatusToTimelineAndNotify(currentLogin, followerLogin, share);\n        }\n        // update the status details to add this share\n        sharesRepository.newShareByLogin(status.getStatusId(), currentLogin);\n        // mention the status' author that the user has shared his status\n        MentionShare mentionShare = statusRepository.createMentionShare(currentLogin, status.getStatusId());\n        mentionlineRepository.addStatusToMentionline(status.getLogin(), mentionShare.getStatusId());\n    }\n\n    public void addFavoriteStatus(String statusId) {\n        log.debug(\"Favorite status : {}\", statusId);\n        AbstractStatus abstractStatus = statusRepository.findStatusById(statusId);\n        if (abstractStatus.getType().equals(StatusType.STATUS)) {\n            String login = authenticationService.getCurrentUser().getLogin();\n            favoritelineRepository.addStatusToFavoriteline(login, statusId);\n        } else if(abstractStatus.getType().equals(StatusType.SHARE)){\n            Share currentShare = (Share) abstractStatus;\n            // We add the original status the favorites\n            String login = authenticationService.getCurrentUser().getLogin();\n            favoritelineRepository.addStatusToFavoriteline(login, currentShare.getOriginalStatusId());\n        } else {\n            log.warn(\"Cannot favorite this type of status: \" + abstractStatus);\n        }\n    }\n\n    public void removeFavoriteStatus(String statusId) {\n        log.debug(\"Un-favorite status : {}\", statusId);\n        AbstractStatus abstractStatus = statusRepository.findStatusById(statusId);\n        if (abstractStatus.getType().equals(StatusType.STATUS)) {\n            User currentUser = authenticationService.getCurrentUser();\n            favoritelineRepository.removeStatusFromFavoriteline(currentUser.getLogin(), statusId);\n        } else {\n            log.warn(\"Cannot un-favorite this type of status: \" + abstractStatus);\n        }\n    }\n\n    public void announceStatus(String statusId) {\n        log.debug(\"Announce status : {}\", statusId);\n        String currentLogin = this.authenticationService.getCurrentUser().getLogin();\n        AbstractStatus abstractStatus = statusRepository.findStatusById(statusId);\n        if (abstractStatus != null) {\n            if (abstractStatus.getType().equals(StatusType.STATUS)) {\n                Status status = (Status) abstractStatus;\n                internalAnnounceStatus(currentLogin, status);\n            } else if (abstractStatus.getType().equals(StatusType.SHARE)) {\n                Share currentShare = (Share) abstractStatus;\n                // We announce the original status\n                Status originalStatus = (Status) statusRepository.findStatusById(currentShare.getOriginalStatusId());\n                internalAnnounceStatus(currentLogin, originalStatus);\n            } else {\n                log.warn(\"Cannot announce this type of status: \" + abstractStatus);\n            }\n        } else {\n            log.debug(\"Cannot announce this status, as it does not exist: {}\", abstractStatus);\n        }\n    }\n\n    private void internalAnnounceStatus(String currentLogin, Status status) {\n        // create announcement\n        Announcement announcement = statusRepository.createAnnouncement(currentLogin, status.getStatusId());\n\n        // add status to everyone's timeline\n        String domain = DomainUtil.getDomainFromLogin(currentLogin);\n        List<String> logins = domainRepository.getLoginsInDomain(domain);\n        timelineRepository.announceStatusToTimeline(currentLogin, logins, announcement);\n        for (String login : logins) {\n            atmosphereService.notifyUser(login, announcement);\n        }\n    }\n\n    /**\n     * The favline contains the user's favorites status\n     *\n     * @return a status list\n     */\n    public Collection<StatusDTO> getFavoritesline() {\n        String currentLogin = authenticationService.getCurrentUser().getLogin();\n        List<String> statuses = favoritelineRepository.getFavoriteline(currentLogin);\n        Collection<StatusDTO> dtos = buildStatusList(statuses);\n        if (statuses.size() != dtos.size()) {\n            Collection<String> statusIdsToDelete = findStatusesToCleanUp(statuses, dtos);\n            for (String statusId : statusIdsToDelete) {\n                favoritelineRepository.removeStatusFromFavoriteline(currentLogin, statusId);\n            }\n            return getFavoritesline();\n        }\n        dtos = filterStatusFromBlockedUsers(dtos);\n        return dtos;\n    }\n\n    /**\n     * Adds the status to the timeline and notifies the user with Atmosphere.\n     */\n    private void shareStatusToTimelineAndNotify(String sharedByLogin, String timelineLogin, Share share) {\n        timelineRepository.shareStatusToTimeline(sharedByLogin, timelineLogin, share);\n        atmosphereService.notifyUser(timelineLogin, share);\n    }\n\n    private Collection<StatusDTO> filterStatusFromBlockedUsers(Collection<StatusDTO> dtos){\n        if(authenticationService.hasAuthenticatedUser()) {\n            User currentUser = authenticationService.getCurrentUser();\n            String currentLogin = currentUser.getLogin();\n            String domain = DomainUtil.getDomainFromLogin(currentLogin);\n            Collection<String> blockedUsers = blockService.getUsersBlockedLoginForUser(currentLogin);\n            Collection<StatusDTO> newDtos = new ArrayList<StatusDTO>();\n            for (StatusDTO dto : dtos) {\n                if (!blockedUsers.contains(dto.getUsername() + \"@\" + domain)) {\n                    newDtos.add(dto);\n                }\n            }\n            return newDtos;\n        }\n        return dtos;\n    }\n\n    public void hideStatus(String statusId) {\n        log.debug(\"Hiding status from timeline : {}\", statusId);\n        User currentUser = authenticationService.getCurrentUser();\n        String login = currentUser.getLogin();\n        Collection<String> statusIds = new ArrayList<String>();\n        statusIds.add(statusId);\n        timelineRepository.removeStatusesFromTimeline(login,statusIds);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/TrendService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.repository.TrendRepository;\nimport fr.ippon.tatami.repository.UserTrendRepository;\nimport fr.ippon.tatami.web.rest.dto.Trend;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.cache.annotation.Cacheable;\nimport org.springframework.stereotype.Service;\nimport org.springframework.util.Assert;\n\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashMap;\nimport java.util.List;\n\nimport static fr.ippon.tatami.service.util.AnalysisUtil.findMostUsedKeys;\nimport static fr.ippon.tatami.service.util.AnalysisUtil.incrementKeyCounterInMap;\n\n/**\n * Analyzes trends (tags going up or down depending on the current time).\n */\n@Service\npublic class TrendService {\n\n    private final Logger log = LoggerFactory.getLogger(TrendService.class);\n\n    private static final int TRENDS_SIZE = 8;\n\n    @Inject\n    private TrendRepository trendRepository;\n\n    @Inject\n    private UserTrendRepository userTrendRepository;\n\n    @Cacheable(\"trends-cache\")\n    public List<Trend> getCurrentTrends(String domain) {\n        List<String> tags = trendRepository.getRecentTags(domain);\n        return calculateTrends(tags);\n    }\n\n    public Collection<String> searchTags(String domain, String startWith, int size) {\n        Assert.hasLength(startWith);\n        Collection<String> allTags = trendRepository.getDomainTags(domain);\n        Collection<String> matchingTags = new ArrayList<String>();\n        String startWithLowered = startWith.toLowerCase();\n        int counter = 0;\n        for (String tag : allTags) {\n            if (tag.toLowerCase().startsWith(startWithLowered)) {\n                matchingTags.add(tag);\n                counter++;\n            }\n            if (counter == size) {\n                break;\n            }\n        }\n        return matchingTags;\n    }\n\n    @Cacheable(\"user-trends-cache\")\n    public List<Trend> getTrendsForUser(String login) {\n        List<String> tags = userTrendRepository.getRecentTags(login);\n        return calculateTrends(tags);\n    }\n\n    private List<Trend> calculateTrends(List<String> tags) {\n        log.debug(\"All tags: {}\", tags);\n        HashMap<String, Integer> totalTagsCount = new HashMap<String, Integer>();\n        HashMap<String, Integer> recentTagsCount = new HashMap<String, Integer>();\n        HashMap<String, Integer> oldTagsCount = new HashMap<String, Integer>();\n        int currentPosition = 0;\n        int middlePosition = tags.size() / 2;\n        for (String tag : tags) {\n            incrementKeyCounterInMap(totalTagsCount, tag);\n            if (currentPosition <= middlePosition) {\n                incrementKeyCounterInMap(recentTagsCount, tag);\n            } else {\n                incrementKeyCounterInMap(oldTagsCount, tag);\n            }\n            currentPosition++;\n        }\n        List<String> mostUsedTags = findMostUsedKeys(totalTagsCount);\n        List<Trend> trends = new ArrayList<Trend>();\n        for (String tag : mostUsedTags) {\n            Trend trend = new Trend();\n            trend.setTag(tag);\n            Integer recentCount = recentTagsCount.get(tag);\n            Integer oldCount = oldTagsCount.get(tag);\n            if (oldCount != null) {\n                if (recentCount != null) {\n                    if (recentCount >= oldCount) {\n                        trend.setTrendingUp(true);\n                    } else {\n                        trend.setTrendingUp(false);\n                    }\n                } else {\n                    trend.setTrendingUp(false);\n                }\n            } else {\n                trend.setTrendingUp(true);\n            }\n            trends.add(trend);\n        }\n        if (trends.size() > TRENDS_SIZE) {\n            return trends.subList(0, TRENDS_SIZE);\n        } else {\n            return trends;\n        }\n    }\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/UserService.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.config.Constants;\nimport fr.ippon.tatami.domain.DigestType;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.*;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.dto.UserDTO;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport fr.ippon.tatami.service.util.RandomUtil;\nimport org.springframework.security.access.annotation.Secured;\n\nimport org.apache.commons.lang.StringUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\nimport org.springframework.security.crypto.password.StandardPasswordEncoder;\nimport org.springframework.stereotype.Service;\nimport org.springframework.cache.annotation.CacheEvict;\n\nimport javax.inject.Inject;\nimport javax.validation.ConstraintViolationException;\nimport java.util.ArrayList;\nimport java.util.Calendar;\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * Manages the application's users.\n *\n * @author Julien Dubois\n */\n@Service\npublic class UserService {\n\n    private final Logger log = LoggerFactory.getLogger(UserService.class);\n\n    @Inject\n    private UserRepository userRepository;\n\n    @Inject\n    private DomainRepository domainRepository;\n\n    @Inject\n    private FriendshipService friendshipService;\n\n    @Inject\n    private FriendRepository friendRepository;\n\n    @Inject\n    private BlockService blockService;\n\n    @Inject\n    private FollowerRepository followerRepository;\n\n    @Inject\n    private CounterRepository counterRepository;\n\n    @Inject\n    private FavoritelineRepository favoritelineRepository;\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    @Inject\n    private MailService mailService;\n\n    @Inject\n    private TimelineRepository timelineRepository;\n\n    @Inject\n    private UserlineRepository userlineRepository;\n\n    @Inject\n    private RegistrationRepository registrationRepository;\n\n    @Inject\n    private RssUidRepository rssUidRepository;\n\n    @Inject\n    private SearchService searchService;\n\n    @Inject\n    private MailDigestRepository mailDigestRepository;\n\n    @Inject\n    Environment env;\n\n    public User getUserByLogin(String login) {\n        return userRepository.findUserByLogin(login);\n    }\n\n    public String getLoginByRssUid(String rssUid) {\n        return rssUidRepository.getLoginByRssUid(rssUid);\n    }\n\n    public User getUserByUsername(String username) {\n        User currentUser = authenticationService.getCurrentUser();\n        String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());\n        String login = DomainUtil.getLoginFromUsernameAndDomain(username, domain);\n        return getUserByLogin(login);\n    }\n\n    /**\n     * Return a collection of Users based on their username (ie : uid)\n     *\n     * @param logins the collection : must not be null\n     * @return a Collection of User\n     */\n    public Collection<User> getUsersByLogin(Collection<String> logins) {\n        final Collection<User> users = new ArrayList<User>();\n        User user;\n        for (String login : logins) {\n            user = userRepository.findUserByLogin(login);\n            if (user != null) {\n                users.add(user);\n            }\n        }\n        return users;\n    }\n\n    public List<User> getUsersForCurrentDomain(int pagination) {\n        User currentUSer = authenticationService.getCurrentUser();\n        String domain = DomainUtil.getDomainFromLogin(currentUSer.getLogin());\n        List<String> logins = domainRepository.getLoginsInDomain(domain, pagination);\n        List<User> users = new ArrayList<User>();\n        for (String login : logins) {\n            User user = getUserByLogin(login);\n            users.add(user);\n        }\n        return users;\n    }\n\n    public void updateUser(User user) {\n        User currentUser = authenticationService.getCurrentUser();\n        user.setLogin(currentUser.getLogin());\n        user.setUsername(currentUser.getUsername());\n        user.setDomain(currentUser.getDomain());\n        user.setAvatar(currentUser.getAvatar());\n        user.setAttachmentsSize(currentUser.getAttachmentsSize());\n        try {\n            userRepository.updateUser(user);\n            searchService.removeUser(user);\n            searchService.addUser(user);\n        } catch (ConstraintViolationException cve) {\n            log.info(\"Constraint violated while updating user \" + user + \" : \" + cve);\n            throw cve;\n        }\n    }\n\n    public void updatePassword(User user) {\n        User currentUser = authenticationService.getCurrentUser();\n        String password = user.getPassword();\n        StandardPasswordEncoder encoder = new StandardPasswordEncoder();\n        String encryptedPassword = encoder.encode(password);\n        currentUser.setPassword(encryptedPassword);\n        log.debug(\"Password encrypted to : {}\", encryptedPassword);\n        try {\n            userRepository.updateUser(currentUser);\n        } catch (ConstraintViolationException cve) {\n            log.info(\"Constraint violated while updating user \" + user + \" : \" + cve);\n            throw cve;\n        }\n    }\n\n    public void createUser(User user) {\n        String login = user.getLogin();\n\n        String username = DomainUtil.getUsernameFromLogin(login);\n        String domain = DomainUtil.getDomainFromLogin(login);\n        domainRepository.addUserInDomain(domain, login);\n\n        // If the user is using OpenID or LDAP, the password is not set.\n        // In this case, we generate a random password as Spring Security requires the user\n        // to have a non-null password (and it is of course a better security than no password)\n        if (user.getPassword() == null) {\n            String password = RandomUtil.generatePassword();\n            StandardPasswordEncoder encoder = new StandardPasswordEncoder();\n            String encryptedPassword = encoder.encode(password);\n            user.setPassword(encryptedPassword);\n        }\n\n        user.setUsername(username);\n        user.setDomain(domain);\n        user.setFirstName(StringUtils.defaultString(user.getFirstName()));\n        user.setLastName(StringUtils.defaultString(user.getLastName()));\n        user.setJobTitle(\"\");\n        user.setAvatar(\"\");\n        user.setPhoneNumber(\"\");\n        user.setPreferencesMentionEmail(true);\n        user.setWeeklyDigestSubscription(true);\n\n        counterRepository.createStatusCounter(user.getLogin());\n        counterRepository.createFriendsCounter(user.getLogin());\n        counterRepository.createFollowersCounter(user.getLogin());\n        userRepository.createUser(user);\n\n        // Add to the searchStatus engine\n        searchService.addUser(user);\n\n        log.debug(\"Created User : {}\", user.toString());\n    }\n\n    public void createTatamibot(String domain) {\n        String login = DomainUtil.getLoginFromUsernameAndDomain(Constants.TATAMIBOT_NAME, domain);\n        User tatamiBotUser = new User();\n        tatamiBotUser.setLogin(login);\n        this.createUser(tatamiBotUser);\n        tatamiBotUser.setPreferencesMentionEmail(false);\n        tatamiBotUser.setWeeklyDigestSubscription(false);\n        tatamiBotUser.setJobTitle(\"I am just a robot\");\n        userRepository.updateUser(tatamiBotUser);\n        log.debug(\"Created Tatami Bot user for domain : {}\", domain);\n    }\n\n    public void deleteUser(User user) {\n        // Unfollow this user\n        Collection<String> followersIds = friendshipService.getFollowerIdsForUser(user.getLogin());\n        for (String followerId : followersIds) {\n            User follower = getUserByLogin(followerId);\n            friendshipService.unfollowUser(follower, user);\n        }\n        log.debug(\"Delete user step 1 : Unfollowed user \" + user.getLogin());\n\n        // Unfollow friends\n        Collection<String> friendsIds = friendshipService.getFriendIdsForUser(user.getLogin());\n        for (String friendId : friendsIds) {\n            User friend = getUserByLogin(friendId);\n            friendshipService.unfollowUser(user, friend);\n        }\n        log.debug(\"Delete user step 2 : user \" + user.getLogin() + \" has no more friends.\");\n\n        // Delete userline, tagLine...\n        favoritelineRepository.deleteFavoriteline(user.getLogin());\n        timelineRepository.deleteTimeline(user.getLogin());\n        userlineRepository.deleteUserline(user.getLogin());\n        log.debug(\"Delete user step 3 : user \" + user.getLogin() + \" has no more lines.\");\n\n        // Remove from domain\n        String domain = DomainUtil.getDomainFromLogin(user.getLogin());\n        domainRepository.deleteUserInDomain(domain, user.getLogin());\n        log.debug(\"Delete user step 4 : user \" + user.getLogin() + \" has no domain.\");\n\n        // Delete counters\n        counterRepository.deleteCounters(user.getLogin());\n        log.debug(\"Delete user step 5 : user \" + user.getLogin() + \" has no counter.\");\n\n        // Delete user\n        userRepository.deleteUser(user);\n        log.debug(\"Delete user step 6 : user \" + user.getLogin() + \" is deleted.\");\n\n        // Tweets are not deleted, but are not available to users anymore (unless the same user is created again)\n\n        log.debug(\"User \" + user.getLogin() + \"has been successfully deleted !\");\n    }\n\n    /**\n     * Set activated Field to false.\n     */\n    @Secured(\"ROLE_ADMIN\")\n    @CacheEvict(value = {\"group-user-cache\", \"group-cache\",\"suggest-users-cache\"}, allEntries = true)\n    public boolean desactivateUser( String username ) {\n        User user = getUserByUsername(username);\n        if ( user != null ) {\n\n            // Desactivate/Activate User\n            if ( user.getActivated() ) {\n                userRepository.desactivateUser(user);\n                favoritelineRepository.deleteFavoriteline(user.getLogin());\n                mailService.sendDeactivatedEmail(user.getLogin());\n                log.debug(\"User \" + user.getLogin() + \" has been successfully desactivated !\");\n            }\n\n            else {\n                userRepository.reactivateUser(user);\n                log.debug(\"User \" + user.getLogin() + \" has been successfully reactivated !\");\n            }\n\n            return true;\n        }\n        log.debug(\"User \" + user.getLogin() + \" NOT FOUND !\");\n        return false;\n    }\n    /**\n     * Creates a User and sends a registration e-mail.\n     */\n    public void registerUser(User user) {\n        String registrationKey = registrationRepository.generateRegistrationKey(user.getLogin());\n        mailService.sendRegistrationEmail(registrationKey, user);\n    }\n\n    public void lostPassword(User user) {\n        String registrationKey = registrationRepository.generateRegistrationKey(user.getLogin());\n        mailService.sendLostPasswordEmail(registrationKey, user);\n    }\n\n    public String validateRegistration(String key) {\n        log.debug(\"Validating registration for key {}\", key);\n        String login = registrationRepository.getLoginByRegistrationKey(key);\n        String password = RandomUtil.generatePassword();\n        StandardPasswordEncoder encoder = new StandardPasswordEncoder();\n        String encryptedPassword = encoder.encode(password);\n        if (login != null) {\n            User existingUser = getUserByLogin(login);\n            if (existingUser != null) {\n                log.debug(\"Reinitializing password for user {}\", login);\n                existingUser.setPassword(encryptedPassword);\n                userRepository.updateUser(existingUser);\n                mailService.sendPasswordReinitializedEmail(existingUser, password);\n            } else {\n                log.debug(\"Validating user {}\", login);\n                User user = new User();\n                user.setLogin(login);\n                user.setPassword(encryptedPassword);\n                createUser(user);\n                mailService.sendValidationEmail(user, password);\n            }\n        }\n        return login;\n    }\n\n    /**\n     * update registration to weekly digest email.\n     */\n    public void updateWeeklyDigestRegistration(boolean registration) {\n        User currentUser = authenticationService.getCurrentUser();\n        currentUser.setWeeklyDigestSubscription(registration);\n        String day = String.valueOf(Calendar.getInstance().get(Calendar.DAY_OF_WEEK));\n\n        if (registration) {\n            mailDigestRepository.subscribeToDigest(DigestType.WEEKLY_DIGEST, currentUser.getLogin(),\n                    currentUser.getDomain(), day);\n        } else {\n            mailDigestRepository.unsubscribeFromDigest(DigestType.WEEKLY_DIGEST, currentUser.getLogin(),\n                    currentUser.getDomain(), day);\n        }\n\n        log.debug(\"Updating weekly digest preferences : \" +\n                \"weeklyDigest={} for user {}\", registration, currentUser.getLogin());\n        try {\n            userRepository.updateUser(currentUser);\n        } catch (ConstraintViolationException cve) {\n            log.info(\"Constraint violated while updating preferences : \" + cve);\n            throw cve;\n        }\n    }\n\n    /**\n     * Update registration to daily digest email.\n     */\n    public void updateDailyDigestRegistration(boolean registration) {\n        User currentUser = authenticationService.getCurrentUser();\n        currentUser.setDailyDigestSubscription(registration);\n        String day = String.valueOf(Calendar.getInstance().get(Calendar.DAY_OF_WEEK));\n\n        if (registration) {\n            mailDigestRepository.subscribeToDigest(DigestType.DAILY_DIGEST, currentUser.getLogin(),\n                    currentUser.getDomain(), day);\n        } else {\n            mailDigestRepository.unsubscribeFromDigest(DigestType.DAILY_DIGEST, currentUser.getLogin(),\n                    currentUser.getDomain(), day);\n        }\n\n        log.debug(\"Updating daily digest preferences : dailyDigest={} for user {}\", registration, currentUser.getLogin());\n        try {\n            userRepository.updateUser(currentUser);\n        } catch (ConstraintViolationException cve) {\n            log.info(\"Constraint violated while updating preferences : \" + cve);\n            throw cve;\n        }\n    }\n\n    /**\n     * Activate of de-activate rss publication for the timeline.\n     *\n     * @return the rssUid used for rss publication, empty if no publication\n     */\n    public String updateRssTimelinePreferences(boolean booleanPreferencesRssTimeline) {\n\n        User currentUser = authenticationService.getCurrentUser();\n        String rssUid = currentUser.getRssUid();\n        if (booleanPreferencesRssTimeline) {\n            // if we already have an rssUid it means it's already activated :\n            // nothing to do, we do not want to change it\n\n            if ((rssUid == null) || rssUid.equals(\"\")) {\n                // Activate rss feed publication.\n                rssUid = rssUidRepository.generateRssUid(currentUser.getLogin());\n                currentUser.setRssUid(rssUid);\n                log.debug(\"Updating rss timeline preferences : rssUid={}\", rssUid);\n\n                try {\n                    userRepository.updateUser(currentUser);\n                } catch (ConstraintViolationException cve) {\n                    log.info(\"Constraint violated while updating preferences : \" + cve);\n                    throw cve;\n                }\n            }\n\n        } else {\n\n            // Remove current rssUid from both CF!\n            if ((rssUid != null) && (!rssUid.isEmpty())) {\n                rssUidRepository.removeRssUid(rssUid);\n                rssUid = \"\";\n                currentUser.setRssUid(rssUid);\n                log.debug(\"Updating rss timeline preferences : rssUid={}\", rssUid);\n\n                try {\n                    userRepository.updateUser(currentUser);\n                } catch (ConstraintViolationException cve) {\n                    log.info(\"Constraint violated while updating preferences : \" + cve);\n                    throw cve;\n                }\n            }\n        }\n        return rssUid;\n    }\n\n    /**\n     * Is the domain managed by a LDAP repository?\n     */\n    public boolean isDomainHandledByLDAP(String domain) {\n        String domainHandledByLdap = env.getProperty(\"tatami.ldapauth.domain\");\n        return domain.equalsIgnoreCase(domainHandledByLdap);\n    }\n\n    public Collection<UserDTO> buildUserDTOList(Collection<User> users) {\n        User currentUser = authenticationService.getCurrentUser();\n        Collection<String> currentFriendLogins = friendRepository.findFriendsForUser(currentUser.getLogin());\n        Collection<String> currentFollowersLogins = followerRepository.findFollowersForUser(currentUser.getLogin());\n        Collection<String> currentBlockedUsersLogins = blockService.getUsersBlockedLoginForUser(currentUser.getLogin());\n        Collection<UserDTO> userDTOs = new ArrayList<UserDTO>();\n        for (User user : users) {\n            UserDTO userDTO = getUserDTOFromUser(user);\n            userDTO.setYou(user.equals(currentUser));\n            if (!userDTO.isYou()) {\n                userDTO.setFriend(currentFriendLogins.contains(user.getLogin()));\n                userDTO.setFollower(currentFollowersLogins.contains(user.getLogin()));\n                userDTO.setBlocked(currentBlockedUsersLogins.contains(user.getLogin()));\n            }\n            userDTOs.add(userDTO);\n        }\n        return userDTOs;\n    }\n\n\n\n    public UserDTO buildUserDTO(User user) {\n        User currentUser = authenticationService.getCurrentUser();\n        UserDTO userDTO = getUserDTOFromUser(user);\n        userDTO.setYou(user.equals(currentUser));\n        if (!userDTO.isYou()) {\n            Collection<String> currentFriendLogins = friendRepository.findFriendsForUser(currentUser.getLogin());\n            Collection<String> currentFollowersLogins = followerRepository.findFollowersForUser(currentUser.getLogin());\n            Collection<String> currentBlockedUsersLogins = blockService.getUsersBlockedLoginForUser(currentUser.getLogin());\n            userDTO.setFriend(currentFriendLogins.contains(user.getLogin()));\n            userDTO.setFollower(currentFollowersLogins.contains(user.getLogin()));\n            userDTO.setBlocked(currentBlockedUsersLogins.contains(user.getLogin()));\n        }\n        return userDTO;\n    }\n\n    private UserDTO getUserDTOFromUser(User user) {\n        UserDTO friend = new UserDTO();\n        friend.setLogin(user.getLogin());\n        friend.setUsername(user.getUsername());\n        friend.setAvatar(user.getAvatar());\n        friend.setFirstName(user.getFirstName());\n        friend.setLastName(user.getLastName());\n        friend.setJobTitle(user.getJobTitle());\n        friend.setPhoneNumber(user.getPhoneNumber());\n        friend.setAttachmentsSize(user.getAttachmentsSize());\n        friend.setStatusCount(user.getStatusCount());\n        friend.setFriendsCount(user.getFriendsCount());\n        friend.setFollowersCount(user.getFollowersCount());\n        friend.setActivated(user.getActivated());\n        return friend;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/dto/StatusDTO.java",
    "content": "package fr.ippon.tatami.service.dto;\n\nimport fr.ippon.tatami.domain.Attachment;\nimport fr.ippon.tatami.domain.status.StatusType;\nimport org.joda.time.DateTime;\nimport org.joda.time.Period;\nimport org.joda.time.format.DateTimeFormatter;\nimport org.joda.time.format.DateTimeFormatterBuilder;\nimport org.joda.time.format.ISODateTimeFormat;\n\nimport java.io.Serializable;\nimport java.util.Calendar;\nimport java.util.Collection;\nimport java.util.Date;\n\n/**\n * DTO to present a \"complete\" status to the presentation layer.\n */\npublic class StatusDTO implements Serializable {\n\n    private static final DateTimeFormatter iso8601Formatter = ISODateTimeFormat.dateTime();\n\n    private static final DateTimeFormatter basicDateFormatter = new DateTimeFormatterBuilder()\n            .appendDayOfMonth(1)\n            .appendLiteral(' ')\n            .appendMonthOfYearShortText()\n            .toFormatter();\n\n    private static final DateTimeFormatter oldDateFormatter = new DateTimeFormatterBuilder()\n            .appendDayOfMonth(1)\n            .appendLiteral(' ')\n            .appendMonthOfYearShortText()\n            .appendLiteral(' ')\n            .appendYear(4, 4)\n            .toFormatter();\n\n    private String statusId;\n\n    /**\n     * The timelineId is used on the client side :\n     * - When this is an original status, timelineId = statusId\n     * - When this is a shared status, timelineId = the id of this share in the user's timeline\n     */\n    private String timelineId;\n\n    private StatusType type;\n\n    private String username;\n\n    private boolean statusPrivate;\n\n    private boolean activated;\n\n    private String groupId;\n\n    private String groupName;\n\n    private String geoLocalization;\n\n    private boolean publicGroup;\n\n    private Collection<Attachment> attachments;\n\n    private Collection<String> attachmentIds;\n\n    private String content;\n\n    private Date statusDate;\n\n    private String iso8601StatusDate;\n\n    private String prettyPrintStatusDate;\n\n    /**\n     * If this status is a reply, the statusId of the original status.\n     */\n    private String replyTo;\n\n    /**\n     * If this status is a reply, the username who posted the original status.\n     */\n    private String replyToUsername;\n\n    private String firstName;\n\n    private String lastName;\n\n    private String avatar;\n\n    private boolean favorite;\n\n    private boolean detailsAvailable;\n\n    /**\n     * If this status was shared, username of the user who shared it.\n     */\n    private String sharedByUsername;\n\n    private boolean shareByMe;\n\n    public boolean isActivated() {\n        return activated;\n    }\n\n    public void setActivated(boolean activated) {\n        this.activated = activated;\n    }\n\n    public boolean isShareByMe() {\n        return shareByMe;\n    }\n\n    public void setShareByMe(boolean shareByMe) {\n        this.shareByMe = shareByMe;\n    }\n\n    public String getISO8601StatusDate() {\n        return this.iso8601StatusDate;\n    }\n\n    public String getPrettyPrintStatusDate() {\n        return this.prettyPrintStatusDate;\n    }\n\n    public String getStatusId() {\n        return statusId;\n    }\n\n    public void setStatusId(String statusId) {\n        this.statusId = statusId;\n    }\n\n    public String getTimelineId() {\n        return timelineId;\n    }\n\n    public void setTimelineId(String timelineId) {\n        this.timelineId = timelineId;\n    }\n\n    public StatusType getType() {\n        return type;\n    }\n\n    public void setType(StatusType type) {\n        this.type = type;\n    }\n\n    public String getUsername() {\n        return username;\n    }\n\n    public void setUsername(String username) {\n        this.username = username;\n    }\n\n    public boolean isStatusPrivate() {\n        return statusPrivate;\n    }\n\n    public void setStatusPrivate(boolean statusPrivate) {\n        this.statusPrivate = statusPrivate;\n    }\n\n    public String getGroupId() {\n        return groupId;\n    }\n\n    public void setGroupId(String groupId) {\n        this.groupId = groupId;\n    }\n\n    public String getGroupName() {\n        return groupName;\n    }\n\n    public void setGroupName(String groupName) {\n        this.groupName = groupName;\n    }\n\n    public boolean isPublicGroup() {\n        return publicGroup;\n    }\n\n    public void setPublicGroup(boolean publicGroup) {\n        this.publicGroup = publicGroup;\n    }\n\n    public Collection<String> getAttachmentIds() {\n        return attachmentIds;\n    }\n\n    public void setAttachmentIds(Collection<String> attachmentIds) {\n        this.attachmentIds = attachmentIds;\n    }\n\n    public Collection<Attachment> getAttachments() {\n        return attachments;\n    }\n\n    public void setAttachments(Collection<Attachment> attachments) {\n        this.attachments = attachments;\n    }\n\n    public String getContent() {\n        return content;\n    }\n\n    public void setContent(String content) {\n        this.content = content;\n    }\n\n    public Date getStatusDate() {\n        return statusDate;\n    }\n\n    public void setStatusDate(Date statusDate) {\n        this.statusDate = statusDate;\n        if (statusDate != null) {\n            DateTime dateTime = new DateTime(statusDate);\n            Period period =\n                    new Period(statusDate.getTime(),\n                            Calendar.getInstance().getTimeInMillis());\n\n            if (period.getMonths() < 1) { // Only format if it is more than 1 month old\n                this.iso8601StatusDate = iso8601Formatter.print(dateTime);\n            } else {\n                this.iso8601StatusDate = \"\";\n            }\n\n            if (period.getYears() == 0) { // Only print the year if it is more than 1 year old\n                this.prettyPrintStatusDate = basicDateFormatter.print(dateTime);\n            } else {\n                this.prettyPrintStatusDate = oldDateFormatter.print(dateTime);\n            }\n        } else {\n            this.iso8601StatusDate = \"\";\n            this.prettyPrintStatusDate = \"\";\n        }\n    }\n\n    public String getReplyTo() {\n        return replyTo;\n    }\n\n    public void setReplyTo(String replyTo) {\n        this.replyTo = replyTo;\n    }\n\n    public String getReplyToUsername() {\n        return replyToUsername;\n    }\n\n    public void setReplyToUsername(String replyToUsername) {\n        this.replyToUsername = replyToUsername;\n    }\n\n    public String getFirstName() {\n        return firstName;\n    }\n\n    public void setFirstName(String firstName) {\n        this.firstName = firstName;\n    }\n\n    public String getLastName() {\n        return lastName;\n    }\n\n    public void setLastName(String lastName) {\n        this.lastName = lastName;\n    }\n\n    public String getAvatar() {\n        return avatar;\n    }\n\n    public void setAvatar(String avatar) {\n        this.avatar = avatar;\n    }\n\n    public boolean isFavorite() {\n        return favorite;\n    }\n\n    public void setFavorite(boolean favorite) {\n        this.favorite = favorite;\n    }\n\n    public boolean isDetailsAvailable() {\n        return detailsAvailable;\n    }\n\n    public void setDetailsAvailable(boolean detailsAvailable) {\n        this.detailsAvailable = detailsAvailable;\n    }\n\n    public String getSharedByUsername() {\n        return sharedByUsername;\n    }\n\n    public void setSharedByUsername(String sharedByUsername) {\n        this.sharedByUsername = sharedByUsername;\n    }\n\n    public String getGeoLocalization() {\n        return geoLocalization;\n    }\n\n    public void setGeoLocalization(String geoLocalization) {\n        this.geoLocalization = geoLocalization;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        StatusDTO status = (StatusDTO) o;\n\n        return !(statusId != null ? !statusId.equals(status.statusId) : status.statusId != null);\n\n    }\n\n    @Override\n    public int hashCode() {\n        return statusId != null ? statusId.hashCode() : 0;\n    }\n\n    @Override\n    public String toString() {\n        return \"StatusDTO{\" +\n                \"statusId='\" + statusId + '\\'' +\n                \", timelineId='\" + timelineId + '\\'' +\n                \", type=\" + type +\n                \", username='\" + username + '\\'' +\n                \", statusPrivate=\" + statusPrivate +\n                \", groupId='\" + groupId + '\\'' +\n                \", groupName='\" + groupName + '\\'' +\n                \", geoLocalization='\" + geoLocalization + '\\'' +\n                \", publicGroup=\" + publicGroup +\n                \", attachments=\" + attachments +\n                \", attachmentIds=\" + attachmentIds +\n                \", content='\" + content + '\\'' +\n                \", statusDate=\" + statusDate +\n                \", iso8601StatusDate='\" + iso8601StatusDate + '\\'' +\n                \", prettyPrintStatusDate='\" + prettyPrintStatusDate + '\\'' +\n                \", replyTo='\" + replyTo + '\\'' +\n                \", replyToUsername='\" + replyToUsername + '\\'' +\n                \", firstName='\" + firstName + '\\'' +\n                \", lastName='\" + lastName + '\\'' +\n                \", avatar='\" + avatar + '\\'' +\n                \", favorite=\" + favorite +\n                \", detailsAvailable=\" + detailsAvailable +\n                \", sharedByUsername='\" + sharedByUsername + '\\'' +\n                \", shareByMe='\" + shareByMe + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/dto/UserDTO.java",
    "content": "package fr.ippon.tatami.service.dto;\n\nimport java.io.Serializable;\n\n/**\n * DTO to present a \"complete\" status to the presentation layer.\n */\npublic class UserDTO implements Serializable {\n\n    private String login;\n\n    private String username;\n\n    private String avatar;\n\n    private String firstName;\n\n    private String lastName;\n\n    private String jobTitle;\n\n    private String phoneNumber;\n\n    private long attachmentsSize;\n\n    private long statusCount;\n\n    private long friendsCount;\n\n    private long followersCount;\n\n    private boolean isFriend = false;\n\n    private boolean isFollower = false;\n\n    private boolean isYou = false;\n\n    private boolean isActivated=true;\n\n    private boolean isBlocked = false;\n\n    private boolean isAdmin = false;\n\n    public boolean isActivated() {\n        return isActivated;\n    }\n\n    public void setActivated(boolean activated) {\n        this.isActivated = activated;\n    }\n\n    public String getUsername() {\n        return username;\n    }\n\n    public void setUsername(String username) {\n        this.username = username;\n    }\n\n    public String getAvatar() {\n        return avatar;\n    }\n\n    public void setAvatar(String avatar) {\n        this.avatar = avatar;\n    }\n\n    public String getFirstName() {\n        return firstName;\n    }\n\n    public void setFirstName(String firstName) {\n        this.firstName = firstName;\n    }\n\n    public String getLastName() {\n        return lastName;\n    }\n\n    public void setLastName(String lastName) {\n        this.lastName = lastName;\n    }\n\n    public String getJobTitle() {\n        return jobTitle;\n    }\n\n    public void setJobTitle(String jobTitle) {\n        this.jobTitle = jobTitle;\n    }\n\n    public String getPhoneNumber() {\n        return phoneNumber;\n    }\n\n    public void setPhoneNumber(String phoneNumber) {\n        this.phoneNumber = phoneNumber;\n    }\n\n    public long getAttachmentsSize() {\n        return attachmentsSize;\n    }\n\n    public void setAttachmentsSize(long attachmentsSize) {\n        this.attachmentsSize = attachmentsSize;\n    }\n\n    public long getStatusCount() {\n        return statusCount;\n    }\n\n    public void setStatusCount(long statusCount) {\n        this.statusCount = statusCount;\n    }\n\n    public long getFriendsCount() {\n        return friendsCount;\n    }\n\n    public void setFriendsCount(long friendsCount) {\n        this.friendsCount = friendsCount;\n    }\n\n    public long getFollowersCount() {\n        return followersCount;\n    }\n\n    public void setFollowersCount(long followersCount) {\n        this.followersCount = followersCount;\n    }\n\n    public boolean isFriend() {\n        return isFriend;\n    }\n\n    public void setFriend(boolean friend) {\n        isFriend = friend;\n    }\n\n    public boolean isFollower() {\n        return isFollower;\n    }\n\n    public void setFollower(boolean follower) {\n        isFollower = follower;\n    }\n\n    public boolean isYou() {\n        return isYou;\n    }\n\n    public void setYou(boolean you) {\n        isYou = you;\n    }\n\n    public boolean isBlocked() {\n        return isBlocked;\n    }\n\n    public void setBlocked(boolean blocked) {\n        isBlocked = blocked;\n    }\n\n    public boolean getIsAdmin() { return isAdmin; }\n\n    public void setIsAdmin(boolean isAdmin) { this.isAdmin = isAdmin; }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        UserDTO user = (UserDTO) o;\n\n        return !(username != null ? !username.equals(user.username) : user.username != null);\n\n    }\n\n    @Override\n    public int hashCode() {\n        return username != null ? username.hashCode() : 0;\n    }\n\n    @Override\n    public String toString() {\n        return \"UserDTO{\" +\n                \"username='\" + username + '\\'' +\n                \", avatar='\" + avatar + '\\'' +\n                \", login='\" + login + '\\'' +\n                \", firstName='\" + firstName + '\\'' +\n                \", lastName=\" + lastName + '\\'' +\n                \", jobTitle='\" + jobTitle + '\\'' +\n                \", phoneNumber='\" + phoneNumber + '\\'' +\n                \", attachmentsSize=\" + attachmentsSize +\n                \", statusCount=\" + statusCount +\n                \", friendsCount=\" + friendsCount +\n                \", followersCount=\" + followersCount +\n                \", isFriend=\" + isFriend +\n                \", isFollower=\" + isFollower +\n                \", isYou=\" + isYou +\n                \", isBlocked=\" + isBlocked +\n                \", activated=\" + isActivated +\n                '}';\n    }\n\n    public String getLogin() {\n        return login;\n    }\n\n    public void setLogin(String login) {\n        this.login = login;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/dto/UserGroupDTO.java",
    "content": "package fr.ippon.tatami.service.dto;\n\nimport java.io.Serializable;\n\n/**\n * DTO to manage a user in a group.\n */\npublic class UserGroupDTO implements Comparable<UserGroupDTO>, Serializable {\n\n    private String login;\n\n    private String avatar;\n\n    private String username;\n\n    private String firstName;\n\n    private String lastName;\n\n    private String role;\n\n    private Boolean isMember = true;\n\n    private boolean friend;\n\n    private boolean activated;\n\n    private boolean you;\n\n    public boolean isActivated() {\n        return activated;\n    }\n\n    public void setActivated(boolean activated) {\n        this.activated = activated;\n    }\n\n    public String getLogin() {\n        return login;\n    }\n\n    public void setLogin(String login) {\n        this.login = login;\n    }\n\n    public String getAvatar() {\n        return avatar;\n    }\n\n    public void setAvatar(String avatar) {\n        this.avatar = avatar;\n    }\n\n    public String getUsername() {\n        return username;\n    }\n\n    public void setUsername(String username) {\n        this.username = username;\n    }\n\n    public String getFirstName() {\n        return firstName;\n    }\n\n    public void setFirstName(String firstName) {\n        this.firstName = firstName;\n    }\n\n    public String getLastName() {\n        return lastName;\n    }\n\n    public void setLastName(String lastName) {\n        this.lastName = lastName;\n    }\n\n    public String getRole() {\n        return role;\n    }\n\n    public void setRole(String role) {\n        this.role = role;\n    }\n\n    public Boolean getIsMember() {\n        return isMember;\n    }\n\n    public void setIsMember(Boolean isMember) {\n        this.isMember = isMember;\n    }\n\n    public boolean isFriend() {\n        return friend;\n    }\n\n    public void setFriend(boolean friend) {\n        this.friend = friend;\n    }\n\n    public boolean isYou() {\n        return you;\n    }\n\n    public void setYou(boolean you) {\n        this.you = you;\n    }\n\n    @Override\n    public int compareTo(UserGroupDTO o) {\n        return this.username.compareTo(o.getUsername());\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        UserGroupDTO userGroupDTO = (UserGroupDTO) o;\n\n        return login.equals(userGroupDTO.login);\n\n    }\n\n    @Override\n    public int hashCode() {\n        return login.hashCode();\n    }\n\n    @Override\n    public String toString() {\n        return \"UserGroupDTO{\" +\n                \"login='\" + login + '\\'' +\n                \", avatar='\" + avatar + '\\'' +\n                \", username='\" + username + '\\'' +\n                \", firstName='\" + firstName + '\\'' +\n                \", lastName='\" + lastName + '\\'' +\n                \", isMember=\" + isMember +\n                \", role='\" + role + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/elasticsearch/ElasticsearchEngine.java",
    "content": "package fr.ippon.tatami.service.elasticsearch;\n\nimport org.elasticsearch.client.Client;\n\n/**\n * Elasticsearch engine.\n */\npublic interface ElasticsearchEngine {\n\n    /**\n     * @return Elasticsearch client.\n     */\n    Client client();\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/elasticsearch/ElasticsearchSearchService.java",
    "content": "package fr.ippon.tatami.service.elasticsearch;\n\nimport com.fasterxml.jackson.databind.JsonNode;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport com.fasterxml.jackson.databind.node.ObjectNode;\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.domain.status.Status;\nimport fr.ippon.tatami.repository.GroupDetailsRepository;\nimport fr.ippon.tatami.service.SearchService;\nimport org.apache.commons.lang.StringUtils;\nimport org.elasticsearch.ElasticSearchException;\nimport org.elasticsearch.action.ActionListener;\nimport org.elasticsearch.action.admin.indices.create.CreateIndexRequestBuilder;\nimport org.elasticsearch.action.bulk.BulkItemResponse;\nimport org.elasticsearch.action.bulk.BulkRequestBuilder;\nimport org.elasticsearch.action.bulk.BulkResponse;\nimport org.elasticsearch.action.delete.DeleteResponse;\nimport org.elasticsearch.action.index.IndexRequestBuilder;\nimport org.elasticsearch.action.index.IndexResponse;\nimport org.elasticsearch.action.search.SearchRequestBuilder;\nimport org.elasticsearch.action.search.SearchResponse;\nimport org.elasticsearch.client.Client;\nimport org.elasticsearch.common.xcontent.XContentBuilder;\nimport org.elasticsearch.common.xcontent.XContentFactory;\nimport org.elasticsearch.indices.IndexMissingException;\nimport org.elasticsearch.search.SearchHit;\nimport org.elasticsearch.search.SearchHits;\nimport org.elasticsearch.search.sort.SortBuilders;\nimport org.elasticsearch.search.sort.SortOrder;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.cache.annotation.Cacheable;\nimport org.springframework.scheduling.annotation.Async;\nimport org.springframework.util.Assert;\n\nimport javax.annotation.PostConstruct;\nimport javax.inject.Inject;\nimport java.io.IOException;\nimport java.net.URL;\nimport java.util.*;\n\nimport static org.elasticsearch.index.query.FilterBuilders.termFilter;\nimport static org.elasticsearch.index.query.QueryBuilders.matchQuery;\n\npublic class ElasticsearchSearchService implements SearchService {\n\n    private static final Logger log = LoggerFactory.getLogger(ElasticsearchSearchService.class);\n\n    private static final String ALL_FIELD = \"_all\";\n\n    private static final List<String> TYPES = Collections.unmodifiableList(Arrays.asList(\"user\", \"status\", \"group\"));\n\n    @Inject\n    private ElasticsearchEngine engine;\n\n    @Inject\n    private String indexNamePrefix;\n\n    @Inject\n    private GroupDetailsRepository groupDetailsRepository;\n\n    private Client client() {\n        return engine.client();\n    }\n\n    private String indexName(String type) {\n        return StringUtils.isEmpty(indexNamePrefix) ? type : indexNamePrefix + '-' + type;\n    }\n\n    @PostConstruct\n    private void init() {\n        for (String type : TYPES) {\n            if (!client().admin().indices().prepareExists(indexName(type)).execute().actionGet().exists()) {\n                log.info(\"Index {} does not exists in Elasticsearch, creating it!\", indexName(type));\n                createIndex();\n            }\n        }\n    }\n\n    @Override\n    public boolean reset() {\n        log.info(\"Reseting ElasticSearch Index\");\n        if (deleteIndex()) {\n            return createIndex();\n        } else {\n            log.warn(\"ElasticSearch Index could not be reset!\");\n            return false;\n        }\n    }\n\n    /**\n     * Delete the tatami index.\n     *\n     * @return {@code true} if the index is deleted or didn't exist.\n     */\n    private boolean deleteIndex() {\n        for (String type : TYPES) {\n            try {\n                boolean ack = client().admin().indices().prepareDelete(indexName(type)).execute().actionGet().acknowledged();\n                if (!ack) {\n                    log.error(\"Elasticsearch Index wasn't deleted !\");\n                    return false;\n                }\n            } catch (IndexMissingException e) {\n                // Failling to delete a missing index is supposed to be valid\n                log.warn(\"Elasticsearch Index \" + indexName(type) + \" missing, it was not deleted\");\n\n            } catch (ElasticSearchException e) {\n                log.error(\"Elasticsearch Index \" + indexName(type) + \" was not deleted\", e);\n                return false;\n            }\n        }\n        log.debug(\"Elasticsearch Index deleted!\");\n        return true;\n    }\n\n    /**\n     * Create the tatami index.\n     *\n     * @return {@code true} if an error occurs during the creation.\n     */\n    private boolean createIndex() {\n        for (String type : TYPES) {\n            try {\n                CreateIndexRequestBuilder createIndex = client().admin().indices().prepareCreate(indexName(type));\n                URL mappingUrl = getClass().getClassLoader().getResource(\"META-INF/elasticsearch/index/\" + type + \".json\");\n\n                ObjectMapper jsonMapper = new ObjectMapper();\n                JsonNode indexConfig = jsonMapper.readTree(mappingUrl);\n                JsonNode indexSettings = indexConfig.get(\"settings\");\n                if (indexSettings != null && indexSettings.isObject()) {\n                    createIndex.setSettings(jsonMapper.writeValueAsString(indexSettings));\n                }\n\n                JsonNode mappings = indexConfig.get(\"mappings\");\n                if (mappings != null && mappings.isObject()) {\n                    for (Iterator<Map.Entry<String, JsonNode>> i = mappings.fields(); i.hasNext(); ) {\n                        Map.Entry<String, JsonNode> field = i.next();\n                        ObjectNode mapping = jsonMapper.createObjectNode();\n                        mapping.put(field.getKey(), field.getValue());\n                        createIndex.addMapping(field.getKey(), jsonMapper.writeValueAsString(mapping));\n                    }\n                }\n\n                boolean ack = createIndex.execute().actionGet().acknowledged();\n                if (!ack) {\n                    log.error(\"Cannot create index \" + indexName(type));\n                    return false;\n                }\n\n            } catch (ElasticSearchException e) {\n                log.error(\"Cannot create index \" + indexName(type), e);\n                return false;\n\n            } catch (IOException e) {\n                log.error(\"Cannot create index \" + indexName(type), e);\n                return false;\n            }\n        }\n        return true;\n    }\n\n    private final ElasticsearchMapper<Status> statusMapper = new ElasticsearchMapper<Status>() {\n        @Override\n        public String id(Status status) {\n            return status.getStatusId();\n        }\n\n        @Override\n        public String type() {\n            return \"status\";\n        }\n\n        @Override\n        public String prefixSearchSortField() {\n            return null;\n        }\n\n        @Override\n        public XContentBuilder toJson(Status status) throws IOException {\n            XContentBuilder source = XContentFactory.jsonBuilder()\n                    .startObject()\n                    .field(\"statusId\", status.getStatusId())\n                    .field(\"domain\", status.getDomain())\n                    .field(\"username\", status.getUsername())\n                    .field(\"statusDate\", status.getStatusDate())\n                    .field(\"content\", status.getContent());\n\n            if (status.getGroupId() != null) {\n                Group group = groupDetailsRepository.getGroupDetails(status.getGroupId());\n                source.field(\"groupId\", status.getGroupId());\n                source.field(\"publicGroup\", group.isPublicGroup());\n            }\n            return source.endObject();\n        }\n    };\n\n    @Override\n    @Async\n    public void addStatus(Status status) {\n        index(status, statusMapper);\n    }\n\n    @Override\n    public void addStatuses(Collection<Status> statuses) {\n        indexAll(statuses, statusMapper);\n    }\n\n\n    @Override\n    public void removeStatus(Status status) {\n        Assert.notNull(status, \"status cannot be null\");\n        delete(status, statusMapper);\n    }\n\n    @Override\n    public List<String> searchStatus(final String domain,\n                                     final String query,\n                                     int page,\n                                     int size) {\n\n        Assert.notNull(query);\n        Assert.notNull(domain);\n\n        if (page < 0) {\n            page = 0; //Default value\n        }\n        if (size <= 0) {\n            size = SearchService.DEFAULT_PAGE_SIZE;\n        }\n\n        try {\n            SearchRequestBuilder searchRequest = client().prepareSearch(indexName(statusMapper.type()))\n                    .setTypes(statusMapper.type())\n                    .setQuery(matchQuery(ALL_FIELD, query))\n                    .setFilter(termFilter(\"domain\", domain))\n                    .addFields()\n                    .setFrom(page * size)\n                    .setSize(size)\n                    .addSort(\"statusDate\", SortOrder.DESC);\n\n            if (log.isTraceEnabled()) {\n                log.trace(\"elasticsearch query : \" + searchRequest);\n            }\n            SearchResponse searchResponse = searchRequest.execute().actionGet();\n\n            SearchHits searchHits = searchResponse.hits();\n            Long hitsNumber = searchHits.totalHits();\n            if (hitsNumber == 0) {\n                return Collections.emptyList();\n            }\n\n            SearchHit[] hits = searchHits.hits();\n            List<String> items = new ArrayList<String>(hits.length);\n            for (SearchHit hit : hits) {\n                items.add(hit.getId());\n            }\n\n            log.debug(\"search status with words ({}) = {}\", query, items);\n            return items;\n\n        } catch (IndexMissingException e) {\n            log.warn(\"The index \" + indexName(statusMapper.type()) + \" was not found in the Elasticsearch cluster.\");\n            return Collections.emptyList();\n\n        } catch (ElasticSearchException e) {\n            log.error(\"Error happened while searching status in index \" + indexName(statusMapper.type()));\n            return Collections.emptyList();\n        }\n    }\n\n    private final ElasticsearchMapper<User> userMapper = new ElasticsearchMapper<User>() {\n        @Override\n        public String id(User user) {\n            return user.getLogin();\n        }\n\n        @Override\n        public String type() {\n            return \"user\";\n        }\n\n        @Override\n        public String prefixSearchSortField() {\n            return \"username\";\n        }\n\n        @Override\n        public XContentBuilder toJson(User user) throws IOException {\n            return XContentFactory.jsonBuilder()\n                    .startObject()\n                    .field(\"login\", user.getLogin())\n                    .field(\"domain\", user.getDomain())\n                    .field(\"username\", user.getUsername())\n                    .field(\"firstName\", user.getFirstName())\n                    .field(\"lastName\", user.getLastName())\n                    .endObject();\n        }\n    };\n\n    @Override\n    @Async\n    public void addUser(final User user) {\n        Assert.notNull(user, \"user cannot be null\");\n        index(user, userMapper);\n    }\n\n    @Override\n    public void addUsers(Collection<User> users) {\n        indexAll(users, userMapper);\n    }\n\n    @Override\n    public void removeUser(User user) {\n        delete(user, userMapper);\n    }\n\n\n    @Override\n    @Cacheable(\"user-prefix-cache\")\n    public Collection<String> searchUserByPrefix(String domain, String prefix) {\n        return searchByPrefix(domain, prefix, DEFAULT_TOP_N_SEARCH_USER, userMapper);\n    }\n\n    private final ElasticsearchMapper<Group> groupMapper = new ElasticsearchMapper<Group>() {\n        @Override\n        public String id(Group group) {\n            return group.getGroupId();\n        }\n\n        @Override\n        public String type() {\n            return \"group\";\n        }\n\n        @Override\n        public String prefixSearchSortField() {\n            return \"name-not-analyzed\";\n        }\n\n        @Override\n        public XContentBuilder toJson(Group group) throws IOException {\n            return XContentFactory.jsonBuilder()\n                    .startObject()\n                    .field(\"domain\", group.getDomain())\n                    .field(\"groupId\", group.getGroupId())\n                    .field(\"name\", group.getName())\n                    .field(\"description\", group.getDescription())\n                    .endObject();\n        }\n    };\n\n    @Override\n    @Async\n    public void addGroup(Group group) {\n        index(group, groupMapper);\n    }\n\n    @Override\n    public void removeGroup(Group group) {\n        delete(group, groupMapper);\n    }\n\n    @Override\n    @Cacheable(\"group-prefix-cache\")\n    public Collection<Group> searchGroupByPrefix(String domain, String prefix, int size) {\n        Collection<String> ids = searchByPrefix(domain, prefix, size, groupMapper);\n        List<Group> groups = new ArrayList<Group>(ids.size());\n        for (String id : ids) {\n            groups.add(groupDetailsRepository.getGroupDetails(id));\n        }\n        return groups;\n    }\n\n    /**\n     * Indexes an object to elasticsearch.\n     * This method is asynchronous.\n     *\n     * @param object Object to index.\n     * @param mapper Converter to JSON.\n     */\n    private <T> void index(T object, ElasticsearchMapper<T> mapper) {\n        Assert.notNull(object);\n        Assert.notNull(mapper);\n\n        final String type = mapper.type();\n        final String id = mapper.id(object);\n        try {\n            final XContentBuilder source = mapper.toJson(object);\n\n            log.debug(\"Ready to index the {} id {} into Elasticsearch: {}\", type, id, stringify(source));\n            client().prepareIndex(indexName(type), type, id).setSource(source).execute(new ActionListener<IndexResponse>() {\n                @Override\n                public void onResponse(IndexResponse response) {\n                    log.debug(type + \" id \" + id + \" was \" + (response.version() == 1 ? \"indexed\" : \"updated\") + \" into Elasticsearch\");\n                }\n\n                @Override\n                public void onFailure(Throwable e) {\n                    log.error(\"The \" + type + \" id \" + id + \" wasn't indexed : \" + stringify(source), e);\n                }\n            });\n\n        } catch (IOException e) {\n            log.error(\"The \" + type + \" id \" + id + \" wasn't indexed\", e);\n        }\n    }\n\n    /**\n     * Indexes an collection of objects to elasticsearch.\n     * This method is synchronous.\n     *\n     * @param collection Object to index.\n     * @param adapter    Converter to JSON.\n     */\n    private <T> void indexAll(Collection<T> collection, ElasticsearchMapper<T> adapter) {\n        Assert.notNull(collection);\n        Assert.notNull(adapter);\n\n        if (collection.isEmpty())\n            return;\n\n        String type = adapter.type();\n        BulkRequestBuilder request = client().prepareBulk();\n\n        for (T object : collection) {\n            String id = adapter.id(object);\n            try {\n                XContentBuilder source = adapter.toJson(object);\n                IndexRequestBuilder indexRequest = client().prepareIndex(indexName(type), type, id).setSource(source);\n                request.add(indexRequest);\n\n            } catch (IOException e) {\n                log.error(\"The \" + type + \" of id \" + id + \" wasn't indexed\", e);\n            }\n        }\n\n        log.debug(\"Ready to index {} {} into Elasticsearch.\", collection.size(), type);\n\n        BulkResponse response = request.execute().actionGet();\n        if (response.hasFailures()) {\n            int errorCount = 0;\n            for (BulkItemResponse itemResponse : response) {\n                if (itemResponse.failed()) {\n                    log.error(\"The \" + type + \" of id \" + itemResponse.getId() + \" wasn't indexed in bulk operation: \" + itemResponse.getFailureMessage());\n                    ++errorCount;\n                }\n            }\n            log.error(errorCount + \" \" + type + \" where not indexed in bulk operation.\");\n\n        } else {\n            log.debug(\"{} {} indexed into Elasticsearch in bulk operation.\", collection.size(), type);\n        }\n    }\n\n    /**\n     * delete a document.\n     * This method is asynchronous.\n     *\n     * @param object Object to index.\n     * @param mapper Converter to JSON.\n     */\n    private <T> void delete(T object, ElasticsearchMapper<T> mapper) {\n        Assert.notNull(object);\n        Assert.notNull(mapper);\n\n        final String id = mapper.id(object);\n        final String type = mapper.type();\n\n        log.debug(\"Ready to delete the {} of id {} from Elasticsearch: \", type, id);\n\n        client().prepareDelete(indexName(type), type, id).execute(new ActionListener<DeleteResponse>() {\n            @Override\n            public void onResponse(DeleteResponse deleteResponse) {\n                if (log.isDebugEnabled()) {\n                    if (deleteResponse.notFound()) {\n                        log.debug(\"{} of id {} was not found therefore not deleted.\", type, id);\n                    } else {\n                        log.debug(\"{} of id {} was deleted from Elasticsearch.\", type, id);\n                    }\n                }\n            }\n\n            @Override\n            public void onFailure(Throwable e) {\n                log.error(\"The \" + type + \" of id \" + id + \" wasn't deleted from Elasticsearch.\", e);\n            }\n        });\n    }\n\n    private Collection<String> searchByPrefix(String domain, String prefix, int size, ElasticsearchMapper<?> mapper) {\n        try {\n\n            SearchRequestBuilder searchRequest = client().prepareSearch(indexName(mapper.type()))\n                    .setTypes(mapper.type())\n                    .setQuery(matchQuery(\"prefix\", prefix))\n                    .setFilter(termFilter(\"domain\", domain))\n                    .addFields()\n                    .setFrom(0)\n                    .setSize(size)\n                    .addSort(SortBuilders.fieldSort(mapper.prefixSearchSortField()).order(SortOrder.ASC));\n\n            if (log.isTraceEnabled()) {\n                log.trace(\"elasticsearch query : \" + searchRequest);\n            }\n            SearchResponse searchResponse = searchRequest\n                    .execute()\n                    .actionGet();\n\n            SearchHits searchHits = searchResponse.hits();\n            if (searchHits.totalHits() == 0)\n                return Collections.emptyList();\n\n            SearchHit[] hits = searchHits.hits();\n            final List<String> ids = new ArrayList<String>(hits.length);\n            for (SearchHit hit : hits) {\n                ids.add(hit.getId());\n            }\n\n            log.debug(\"search \" + mapper.type() + \" by prefix(\\\"\" + domain + \"\\\", \\\"\" + prefix + \"\\\") = result : \" + ids);\n            return ids;\n\n        } catch (IndexMissingException e) {\n            log.warn(\"The index \" + indexName(mapper.type()) + \" was not found in the Elasticsearch cluster.\");\n            return Collections.emptyList();\n\n        } catch (ElasticSearchException e) {\n            log.error(\"Error while searching user by prefix in index \" + indexName(mapper.type()), e);\n            return Collections.emptyList();\n        }\n\n    }\n\n    /**\n     * Stringify a document source for logging purpose.\n     *\n     * @param source Source of the document.\n     * @return A string representation of the document only valid for logging purpose.\n     */\n    private String stringify(XContentBuilder source) {\n        try {\n            return source.prettyPrint().string();\n        } catch (IOException e) {\n            return \"\";\n        }\n    }\n\n    /**\n     * Used to transform an object to it's indexed representation.\n     */\n    private static interface ElasticsearchMapper<T> {\n        /**\n         * Provides object id;\n         *\n         * @param o object.\n         * @return object id.\n         */\n        String id(T o);\n\n        /**\n         * Provides index type of this mapping.\n         *\n         * @return The elasticsearch index type of the object.\n         */\n        String type();\n\n        /**\n         * @return The name of the field to sort by in search by prefix.\n         */\n        String prefixSearchSortField();\n\n        /**\n         * Convert object to it's indexable JSON document representation.\n         *\n         * @param o object.\n         * @return Document\n         * @throws IOException If the creation of the JSON document failed.\n         */\n        XContentBuilder toJson(T o) throws IOException;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/elasticsearch/EmbeddedElasticsearchEngine.java",
    "content": "package fr.ippon.tatami.service.elasticsearch;\n\nimport org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse;\nimport org.elasticsearch.client.Client;\nimport org.elasticsearch.node.Node;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport javax.annotation.PostConstruct;\nimport javax.annotation.PreDestroy;\n\nimport static org.elasticsearch.common.settings.ImmutableSettings.settingsBuilder;\nimport static org.elasticsearch.node.NodeBuilder.nodeBuilder;\n\n/**\n * Transport client configuration.\n */\npublic class EmbeddedElasticsearchEngine implements ElasticsearchEngine {\n\n    private final Logger log = LoggerFactory.getLogger(EmbeddedElasticsearchEngine.class);\n\n    private Node node;\n\n    @PostConstruct\n    private void init() {\n        log.info(\"Initializing Elasticsearch embedded cluster...\");\n\n        node = nodeBuilder()\n                .loadConfigSettings(false)\n                .settings(settingsBuilder().loadFromClasspath(\"META-INF/elasticsearch/elasticsearch-embedded.yml\"))\n                .node();\n\n        // Looking for nodes configuration\n        if (log.isInfoEnabled()) {\n            final NodesInfoResponse nir =\n                    client().admin().cluster().prepareNodesInfo().execute().actionGet();\n\n            log.info(\"Elasticsearch client is now connected to the \" + nir.nodes().length + \" node(s) cluster named \\\"\"\n                    + nir.clusterName() + \"\\\"\");\n        }\n    }\n\n    @PreDestroy\n    private void close() {\n        log.info(\"Closing Elasticsearch embedded cluster\");\n        node.close();\n    }\n\n    public Client client() {\n        return node.client();\n    }\n}"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/elasticsearch/RemoteElasticsearchEngine.java",
    "content": "package fr.ippon.tatami.service.elasticsearch;\n\nimport org.elasticsearch.action.admin.cluster.node.info.NodesInfoRequest;\nimport org.elasticsearch.action.admin.cluster.node.info.NodesInfoResponse;\nimport org.elasticsearch.client.Client;\nimport org.elasticsearch.client.transport.TransportClient;\nimport org.elasticsearch.common.settings.ImmutableSettings;\nimport org.elasticsearch.common.settings.Settings;\nimport org.elasticsearch.common.transport.InetSocketTransportAddress;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\n\nimport javax.annotation.PostConstruct;\nimport javax.annotation.PreDestroy;\nimport javax.inject.Inject;\n\n/**\n * Transport client configuration.\n */\npublic class RemoteElasticsearchEngine implements ElasticsearchEngine {\n\n    private static final Logger log = LoggerFactory.getLogger(RemoteElasticsearchEngine.class);\n\n    @Inject\n    private Environment env;\n\n    private TransportClient client;\n\n    @PostConstruct\n    private void init() {\n        log.info(\"Initializing Elasticsearch remote client...\");\n\n        Settings settings = ImmutableSettings.settingsBuilder()\n                .put(\"cluster.name\", env.getRequiredProperty(\"elasticsearch.cluster.name\"))\n                .build();\n        client = new TransportClient(settings, false);\n\n        // Looking for nodes configuration\n        String nodes = env.getRequiredProperty(\"elasticsearch.cluster.nodes\");\n        String[] nodesAddresses = nodes.split(\",\");\n        if (nodesAddresses.length == 0) {\n            throw new IllegalStateException(\"ES client must have at least one node to connect to\");\n        }\n\n        for (String nodeAddress : nodesAddresses) {\n            client.addTransportAddress(parseAddress(nodeAddress));\n        }\n\n        if (log.isInfoEnabled()) {\n            NodesInfoResponse nir =\n                    client.admin().cluster().nodesInfo(new NodesInfoRequest()).actionGet();\n\n            log.info(\"Elasticsearch client is now connected to the \" + nir.nodes().length + \" node(s) cluster named \\\"\"\n                    + nir.clusterName() + \"\\\"\");\n        }\n    }\n\n    @PreDestroy\n    private void close() {\n        log.info(\"Closing Elasticsearch remote client\");\n        client.close();\n    }\n\n    public Client client() {\n        return client;\n    }\n\n    private InetSocketTransportAddress parseAddress(String address) {\n        String[] addressItems = address.split(\":\", 2);\n        int port = Integer.parseInt(addressItems.length > 1 ? addressItems[1] : env.getRequiredProperty(\"elasticsearch.cluster.default.communication.port\"));\n        return new InetSocketTransportAddress(addressItems[0], port);\n    }\n}"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/exception/ArchivedGroupException.java",
    "content": "package fr.ippon.tatami.service.exception;\n\n/**\n * This exception is thrown when a user tries to post a message to an archived group.\n *\n * @author Julien Dubois\n */\npublic class ArchivedGroupException extends Exception {\n\n    public ArchivedGroupException() {\n    }\n\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/exception/ReplyStatusException.java",
    "content": "package fr.ippon.tatami.service.exception;\n\n/**\n * This exception is thrown when a user tries to reply to a status that does not exist.\n *\n * @author Julien Dubois\n */\npublic class ReplyStatusException extends Exception {\n\n    public ReplyStatusException() {\n    }\n\n    public ReplyStatusException(String s) {\n        super(s);\n    }\n\n    public ReplyStatusException(String s, Throwable throwable) {\n        super(s, throwable);\n    }\n\n    public ReplyStatusException(Throwable throwable) {\n        super(throwable);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/exception/StorageSizeException.java",
    "content": "package fr.ippon.tatami.service.exception;\n\n/**\n * This exception is thrown when a user tries to exceed his storage size.\n *\n * @author Julien Dubois\n */\npublic class StorageSizeException extends Exception {\n\n    public StorageSizeException(String s) {\n        super(s);\n    }\n\n    public StorageSizeException(Throwable throwable) {\n        super(throwable);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/util/AnalysisUtil.java",
    "content": "package fr.ippon.tatami.service.util;\n\nimport java.util.*;\n\n/**\n * Common functions for analysing key trends, user & group suggestions.\n */\npublic class AnalysisUtil {\n\n    private static final int RESULTS_SIZE = 20;\n\n    public static void incrementKeyCounterInMap(Map<String, Integer> map, String key) {\n        if (map.containsKey(key)) {\n            Integer total = map.get(key);\n            total++;\n            map.put(key, total);\n        } else {\n            map.put(key, 1);\n        }\n    }\n\n    public static List<String> findMostUsedKeys(Map<String, Integer> totalTagsCount) {\n        ValueComparator valueComparator = new ValueComparator(totalTagsCount);\n        TreeMap<String, Integer> orderedTags =\n                new TreeMap<String, Integer>(valueComparator);\n\n        orderedTags.putAll(totalTagsCount);\n        List<String> mostUsedTags = new ArrayList<String>();\n        for (int i = 0; i <= RESULTS_SIZE; i++) {\n            Map.Entry<String, Integer> firstEntry = orderedTags.pollFirstEntry();\n            if (firstEntry != null) {\n                mostUsedTags.add(firstEntry.getKey());\n            }\n        }\n        return mostUsedTags;\n    }\n\n    public static List<String> reduceCollectionSize(List<String> list, int size) {\n        if (list.size() < size) {\n            return list;\n        }\n        Collections.shuffle(list);\n        return list.subList(0, size - 1);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/util/DomainUtil.java",
    "content": "package fr.ippon.tatami.service.util;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\n/**\n * Utility class for managing the user domain.\n *\n * @author Julien Dubois\n */\npublic class DomainUtil {\n\n    private final Logger log = LoggerFactory.getLogger(DomainUtil.class);\n\n    private DomainUtil() {\n    }\n\n    public static String getDomainFromLogin(String login) {\n        if (login == null) {\n            return null;\n        }\n        return login.substring(login.indexOf(\"@\") + 1, login.length());\n    }\n\n    public static String getLoginFromUsernameAndDomain(String username, String domain) {\n        return username + \"@\" + domain;\n    }\n\n    public static String getUsernameFromLogin(String login) {\n        if (login == null) {\n            return null;\n        }\n        return login.substring(0, login.indexOf(\"@\"));\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/util/RandomUtil.java",
    "content": "package fr.ippon.tatami.service.util;\n\nimport org.apache.commons.lang.RandomStringUtils;\n\n/**\n * Utility class for generating random Strings.\n *\n * @author Julien Dubois\n */\npublic class RandomUtil {\n\n    private RandomUtil() {\n    }\n\n    public static String generatePassword() {\n        return RandomStringUtils.randomAlphanumeric(20);\n    }\n\n    public static String generateRegistrationKey() {\n        return RandomStringUtils.randomNumeric(20);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/service/util/ValueComparator.java",
    "content": "package fr.ippon.tatami.service.util;\n\nimport java.util.Comparator;\nimport java.util.Map;\n\n/**\n * Used to sort a Map by its values.\n */\npublic class ValueComparator implements Comparator<String> {\n\n    Map<String, Integer> base;\n\n    public ValueComparator(Map<String, Integer> base) {\n        this.base = base;\n    }\n\n    // This comparator is not consistent with equals, as we do not want to merge keys\n    public int compare(String a, String b) {\n        if (base.get(a) >= base.get(b)) {\n            return -1;\n        } else {\n            return 1;\n        }\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/web/atmosphere/TatamiNotification.java",
    "content": "package fr.ippon.tatami.web.atmosphere;\n\nimport fr.ippon.tatami.service.dto.StatusDTO;\n\nimport java.io.Serializable;\n\n/**\n * Tatami notification : contains the user to be notified and the StatusDTO to display.\n */\npublic class TatamiNotification implements Serializable {\n\n    private String login;\n\n    private StatusDTO statusDTO;\n\n    public String getLogin() {\n        return login;\n    }\n\n    public void setLogin(String login) {\n        this.login = login;\n    }\n\n    public StatusDTO getStatusDTO() {\n        return statusDTO;\n    }\n\n    public void setStatusDTO(StatusDTO statusDTO) {\n        this.statusDTO = statusDTO;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (!(o instanceof TatamiNotification)) return false;\n\n        TatamiNotification that = (TatamiNotification) o;\n\n        if (!login.equals(that.login)) return false;\n        if (!statusDTO.equals(that.statusDTO)) return false;\n\n        return true;\n    }\n\n    @Override\n    public int hashCode() {\n        int result = login.hashCode();\n        result = 31 * result + statusDTO.hashCode();\n        return result;\n    }\n\n    @Override\n    public String toString() {\n        return \"TatamiNotification{\" +\n                \"login='\" + login + '\\'' +\n                \", statusDTO=\" + statusDTO +\n                \"} \" + super.toString();\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/web/rest/dto/ActionStatus.java",
    "content": "package fr.ippon.tatami.web.rest.dto;\n\nimport java.io.Serializable;\n\n/**\n * Reply to a Status.\n */\npublic class ActionStatus implements Serializable {\n\n    private Boolean favorite = null;\n\n    private Boolean shared = null;\n\n    private Boolean announced = null;\n\n    public Boolean isFavorite() {\n        return favorite;\n    }\n\n    public void setFavorite(Boolean favorite) {\n        this.favorite = favorite;\n    }\n\n    public Boolean isShared() {\n        return shared;\n    }\n\n    public void setShared(Boolean shared) {\n        this.shared = shared;\n    }\n\n    public Boolean isAnnounced() {\n        return announced;\n    }\n\n    public void setAnnounced(Boolean announced) {\n        this.announced = announced;\n    }\n\n    @Override\n    public String toString() {\n        return \"ActionStatus{\" +\n                \"favorite=\" + favorite +\n                \", shared=\" + shared +\n                \", announced=\" + announced +\n                \"} \" + super.toString();\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/web/rest/dto/EmailAndUsername.java",
    "content": "package fr.ippon.tatami.web.rest.dto;\n\nimport java.io.Serializable;\n\n/**\n * DTO containing the user name and e-mail.\n */\npublic class EmailAndUsername implements Serializable {\n    private String email;\n    private String username;\n\n    public String getEmail() {\n        return email;\n    }\n\n    public void setEmail(String email) {\n        this.email = email;\n    }\n\n    public String getUsername() {\n        return username;\n    }\n\n    public void setUsername(String username) {\n        this.username = username;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/web/rest/dto/Preferences.java",
    "content": "package fr.ippon.tatami.web.rest.dto;\n\nimport fr.ippon.tatami.domain.User;\nimport org.apache.commons.lang.StringUtils;\n\nimport java.io.Serializable;\n\n/**\n * Stores a user's preferences.\n */\npublic class Preferences implements Serializable {\n\n    private Boolean mentionEmail = false;\n\n    private Boolean weeklyDigest = false;\n\n    private Boolean dailyDigest = false;\n\n    private Boolean rssUidActive = false;\n\n    private String rssUid;\n\n    public Preferences() {\n\n    }\n\n    public Preferences(User user) {\n        this.mentionEmail = user.getPreferencesMentionEmail();\n        this.weeklyDigest = user.getWeeklyDigestSubscription();\n        this.dailyDigest = user.getDailyDigestSubscription();\n        if (!StringUtils.isEmpty(user.getRssUid())) {\n            this.rssUidActive = true;\n            this.rssUid = user.getRssUid();\n        }\n    }\n\n    public Boolean getMentionEmail() {\n        return mentionEmail;\n    }\n\n    public void setMentionEmail(Boolean mentionEmail) {\n        this.mentionEmail = mentionEmail;\n    }\n\n    public Boolean getRssUidActive() {\n        return this.rssUidActive;\n    }\n\n    public void setRssUidActive(boolean rssUidActive) {\n        this.rssUidActive = rssUidActive;\n    }\n\n    public String getRssUid() {\n        return rssUid;\n    }\n\n    public void setRssUid(String rssUid) {\n        this.rssUid = rssUid;\n    }\n\n    public Boolean getWeeklyDigest() {\n        return weeklyDigest;\n    }\n\n    public void setWeeklyDigest(Boolean weeklyDigest) {\n        this.weeklyDigest = weeklyDigest;\n    }\n\n    public Boolean getDailyDigest() {\n        return dailyDigest;\n    }\n\n    public void setDailyDigest(Boolean dailyDigest) {\n        this.dailyDigest = dailyDigest;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/web/rest/dto/Reply.java",
    "content": "package fr.ippon.tatami.web.rest.dto;\n\nimport java.io.Serializable;\n\n/**\n * Reply to a Status.\n */\npublic class Reply implements Serializable {\n\n    private String statusId;\n\n    private String content;\n\n    public String getStatusId() {\n        return statusId;\n    }\n\n    public void setStatusId(String statusId) {\n        this.statusId = statusId;\n    }\n\n    public String getContent() {\n        return content;\n    }\n\n    public void setContent(String content) {\n        this.content = content;\n    }\n\n    @Override\n    public String toString() {\n        return \"Reply{\" +\n                \"statusId='\" + statusId + '\\'' +\n                \", content='\" + content + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/web/rest/dto/SearchResults.java",
    "content": "package fr.ippon.tatami.web.rest.dto;\n\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.service.dto.UserDTO;\n\nimport java.io.Serializable;\nimport java.util.Collection;\n\n/**\n * Search result for the global search engine.\n */\npublic class SearchResults implements Serializable {\n\n    private Collection<Tag> tags;\n\n    private Collection<UserDTO> users;\n\n    private Collection<Group> groups;\n\n    public Collection<Tag> getTags() {\n        return tags;\n    }\n\n    public void setTags(Collection<Tag> tags) {\n        this.tags = tags;\n    }\n\n    public Collection<UserDTO> getUsers() {\n        return users;\n    }\n\n    public void setUsers(Collection<UserDTO> users) {\n        this.users = users;\n    }\n\n    public Collection<Group> getGroups() {\n        return groups;\n    }\n\n    public void setGroups(Collection<Group> groups) {\n        this.groups = groups;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/web/rest/dto/Tag.java",
    "content": "package fr.ippon.tatami.web.rest.dto;\n\nimport java.io.Serializable;\n\n/**\n * A Tag.\n */\npublic class Tag implements Serializable {\n\n    private String name;\n\n    private boolean followed;\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public boolean isFollowed() {\n        return followed;\n    }\n\n    public void setFollowed(boolean followed) {\n        this.followed = followed;\n    }\n\n    private boolean trendingUp = false;\n\n    public boolean isTrendingUp() {\n        return trendingUp;\n    }\n\n    public void setTrendingUp(boolean trendingUp) {\n        this.trendingUp = trendingUp;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        Tag tag = (Tag) o;\n\n        return name.equals(tag.name);\n\n    }\n\n    @Override\n    public int hashCode() {\n        return name.hashCode();\n    }\n\n    @Override\n    public String toString() {\n        return \"Tag{\" +\n                \"name='\" + name + '\\'' +\n                \", followed='\" + followed + '\\'' +\n                \", trendingUp='\" + trendingUp + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/web/rest/dto/Trend.java",
    "content": "package fr.ippon.tatami.web.rest.dto;\n\nimport java.io.Serializable;\n\n/**\n * A trend : a tag that is trending up or down.\n */\npublic class Trend implements Serializable {\n\n    private String tag;\n\n    private boolean trendingUp;\n\n    public boolean isTrendingUp() {\n        return trendingUp;\n    }\n\n    public void setTrendingUp(boolean trendingUp) {\n        this.trendingUp = trendingUp;\n    }\n\n    public String getTag() {\n        return tag;\n    }\n\n    public void setTag(String tag) {\n        this.tag = tag;\n    }\n\n    @Override\n    public boolean equals(Object o) {\n        if (this == o) return true;\n        if (o == null || getClass() != o.getClass()) return false;\n\n        Trend trend = (Trend) o;\n\n        return tag.equals(trend.tag);\n\n    }\n\n    @Override\n    public int hashCode() {\n        return tag.hashCode();\n    }\n\n    @Override\n    public String toString() {\n        return \"Trend{\" +\n                \"tag='\" + tag + '\\'' +\n                \", trendingUp=\" + trendingUp +\n                '}';\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/web/rest/dto/UserActionStatus.java",
    "content": "package fr.ippon.tatami.web.rest.dto;\n\nimport java.io.Serializable;\n\n/**\n * This class is used in order to specify the action of PATCH request (cf vUserList.js).\n * The action can be \"addFriend\" ( friendShip = true ) or \"activate/desactivate\" ( activate = true ).\n */\npublic class UserActionStatus implements Serializable {\n\n    private Boolean activate = null;\n\n    private Boolean friendShip = null;\n\n    private Boolean isFriend = null;\n\n    public Boolean getFriend() {\n        return isFriend;\n    }\n\n    public void setFriend(Boolean friend) {\n        isFriend = friend;\n    }\n    public Boolean getFriendShip() {\n        return friendShip;\n    }\n\n    public void setFriendShip(Boolean friendShip) {\n        this.friendShip = friendShip;\n    }\n\n    public Boolean getActivate() {\n        return activate;\n    }\n\n    public void setActivate(Boolean activate) {\n        this.activate = activate;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/web/rest/dto/UserPassword.java",
    "content": "package fr.ippon.tatami.web.rest.dto;\n\nimport java.io.Serializable;\n\n/**\n * Form bean used to change the user's password.\n */\npublic class UserPassword implements Serializable {\n\n    private String oldPassword;\n\n    private String newPassword;\n\n    private String newPasswordConfirmation;\n\n    public String getOldPassword() {\n        return oldPassword;\n    }\n\n    public void setOldPassword(String oldPassword) {\n        this.oldPassword = oldPassword;\n    }\n\n    public String getNewPassword() {\n        return newPassword;\n    }\n\n    public void setNewPassword(String newPassword) {\n        this.newPassword = newPassword;\n    }\n\n    public String getNewPasswordConfirmation() {\n        return newPasswordConfirmation;\n    }\n\n    public void setNewPasswordConfirmation(String newPasswordConfirmation) {\n        this.newPasswordConfirmation = newPasswordConfirmation;\n    }\n\n    @Override\n    public String toString() {\n        return \"UserPassword{\" +\n                \"oldPassword='\" + oldPassword + '\\'' +\n                \", newPassword='\" + newPassword + '\\'' +\n                \", newPasswordConfirmation='\" + newPasswordConfirmation + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/web/syndic/SyndicTimelineController.java",
    "content": "/*\n * To change this template, choose Tools | Templates\n * and open the template in the editor.\n */\npackage fr.ippon.tatami.web.syndic;\n\nimport fr.ippon.tatami.service.TimelineService;\nimport fr.ippon.tatami.service.UserService;\nimport fr.ippon.tatami.service.dto.StatusDTO;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.context.MessageSource;\nimport org.springframework.context.i18n.LocaleContextHolder;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.PathVariable;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.ResponseBody;\nimport org.springframework.web.servlet.ModelAndView;\n\nimport javax.inject.Inject;\nimport java.util.Collection;\nimport java.util.Locale;\n\n/**\n * @author Pierre Rust\n */\n@Controller\npublic class SyndicTimelineController {\n\n    private final Logger log = LoggerFactory.getLogger(SyndicTimelineController.class);\n\n    @Inject\n    private TimelineService timelineService;\n\n    @Inject\n    private UserService userService;\n\n    @Inject\n    private MessageSource messageSource;\n\n    /**\n     * GET  /syndic/{rssUid} -> get the latest statuses from user username\n     * corresponding to the uid\n     */\n    @RequestMapping(value = \"/syndic/{rssUid}\",\n            method = RequestMethod.GET,\n            produces = \"application/rss+xml\")\n    @ResponseBody\n    public ModelAndView listStatusForUser(@PathVariable String rssUid) {\n\n        String login = userService.getLoginByRssUid(rssUid);\n\n        if (login == null) {\n            throw new UnknownRssChannelException(\"Could not find requested rss channel\");\n        }\n        int count = 20; //Default value\n\n        log.debug(\"RSS request to get someone's status (login={}).\", login);\n        Collection<StatusDTO> statuses = timelineService.getUserTimeline(login, count, null, null);\n\n        ModelAndView mav = new ModelAndView(\"syndicView\");\n\n        //  i18n\n        Locale locale = LocaleContextHolder.getLocale();\n        Object[] params = {login};\n        String feedTitle = messageSource.getMessage(\"tatami.rss.timeline.title\", params, locale);\n        String feedDesc = messageSource.getMessage(\"tatami.rss.timeline.description\", params, locale);\n\n        mav.addObject(\"feedTitle\", feedTitle);\n        mav.addObject(\"feedDescription\", feedDesc);\n        mav.addObject(\"statusBaseLink\", \"/tatami/home/\");\n\n        // the link must point the actual content and not to the rss channel\n        mav.addObject(\"feedLink\", \"/tatami/\");\n        mav.addObject(\"feedContent\", statuses);\n\n        return mav;\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/web/syndic/SyndicView.java",
    "content": "package fr.ippon.tatami.web.syndic;\n\nimport com.sun.syndication.feed.rss.Channel;\nimport com.sun.syndication.feed.rss.Content;\nimport com.sun.syndication.feed.rss.Item;\nimport fr.ippon.tatami.service.dto.StatusDTO;\nimport org.pegdown.PegDownProcessor;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.web.servlet.view.feed.AbstractRssFeedView;\n\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * View used to generate the RSS stream corresponding to the timeline\n *\n * @author Pierre Rust\n */\npublic class SyndicView extends AbstractRssFeedView {\n\n    private final Logger log = LoggerFactory.getLogger(SyndicView.class);\n\n    @Override\n    protected void buildFeedMetadata(Map<String, Object> model, Channel feed, HttpServletRequest request) {\n        // this is mandatory: a feed with no title is invalid and is not rendered \n        // by the actual view implementation\n\n        String title = (String) model.get(\"feedTitle\");\n        if (title == null) {\n            title = \"This RSS feed does not exist.\";\n        }\n        String description = (String) model.get(\"feedDescription\");\n        if (description == null) {\n            description = \"Either you typed a wrong URL, or the feed was removed by the user to which it belongs.\";\n        }\n        String link = (String) model.get(\"feedLink\");\n        if (link == null) {\n            link = \"\";\n        }\n\n        feed.setTitle(title);\n        feed.setDescription(description);\n        feed.setLink(link);\n        feed.setEncoding(\"UTF-8\");\n\n        super.buildFeedMetadata(model, feed, request);\n    }\n\n    @Override\n    @SuppressWarnings(\"unchecked\")\n    protected List<Item> buildFeedItems(Map<String, Object> model, HttpServletRequest hsr, HttpServletResponse hsr1) throws Exception {\n        List<Item> items = new ArrayList<Item>();\n        Collection<StatusDTO> listContent = (Collection<StatusDTO>) model.get(\"feedContent\");\n        if (listContent == null) {\n            return items;\n        }\n        String statusBaseLink = (String) model.get(\"statusBaseLink\");\n        for (StatusDTO tempContent : listContent) {\n\n            Item item = new Item();\n\n            String statusText = tempContent.getContent();\n\n            PegDownProcessor processor = new PegDownProcessor();\n            String htmlText = processor.markdownToHtml(statusText);\n            log.debug(\"feed html content {}\", htmlText);\n            // url handling  for mention & tags\n            htmlText = convertLinks(htmlText);\n\n            Content content = new Content();\n            content.setType(Content.HTML);\n            content.setValue(htmlText);\n            item.setContent(content);\n\n            // build link for the status\n            StringBuilder linkBuilder = new StringBuilder(statusBaseLink);\n            linkBuilder\n                    .append(\"status/\")\n                    .append(tempContent.getStatusId());\n\n            item.setTitle(statusText.substring(0, Math.min(30, statusText.length())));\n            item.setLink(linkBuilder.toString());\n            item.setPubDate(tempContent.getStatusDate());\n\n            items.add(item);\n        }\n        return items;\n    }\n\n    /**\n     * convert #tag and @mention to html links\n     *\n     * @param htmlText the original text\n     * @return html with converted links\n     */\n    private String convertLinks(String htmlText) {\n        // inside status : users (mention) & tags\n        // the regexp are converted from tatami customized marked.js\n        Pattern p = Pattern.compile(\"@([A-Za-z0-9!#$%'*+\\\\/=?\\\\^_`{|}~\\\\-]+(?:\\\\.[A-Za-z0-9!#$%'*+\\\\/=?\\\\^_`{|}~\\\\-]+)*)\");\n        Matcher m = p.matcher(htmlText);\n        StringBuffer mentionSb = new StringBuffer();\n        while (m.find()) {\n            m.appendReplacement(mentionSb, \"<a href='/tatami/home/users/$1' >$0</a>\");\n        }\n        m.appendTail(mentionSb);\n\n        p = Pattern.compile(\"#([^\\\\s!\\\"&#$%'()*+,./:;<=>?@\\\\\\\\\\\\[\\\\]^_`{|}~-]+(?:\\\\.[^\\\\s !\\\"&#$%'()*+,./:;<=>?@\\\\\\\\\\\\[\\\\]^_`{|}~-]+)*)\");\n        m = p.matcher(mentionSb.toString());\n        StringBuffer tagSb = new StringBuffer();\n        while (m.find()) {\n            m.appendReplacement(tagSb, \"<a href='/tatami/home/tags/$1' >$0</a>\");\n        }\n        m.appendTail(tagSb);\n        return tagSb.toString();\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/fr/ippon/tatami/web/syndic/UnknownRssChannelException.java",
    "content": "/*\n * To change this template, choose Tools | Templates\n * and open the template in the editor.\n */\npackage fr.ippon.tatami.web.syndic;\n\nimport org.springframework.http.HttpStatus;\nimport org.springframework.web.bind.annotation.ResponseStatus;\n\n/**\n * @author Pierre Rust\n */\n@ResponseStatus(value = HttpStatus.NOT_FOUND)\npublic class UnknownRssChannelException extends RuntimeException {\n\n    public UnknownRssChannelException(String msg) {\n        super(msg);\n    }\n}\n"
  },
  {
    "path": "services/src/main/java/me/prettyprint/hom/CassandraPersistenceProvider.java",
    "content": "package me.prettyprint.hom;\n\nimport org.apache.openjpa.persistence.EntityManagerFactoryImpl;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport javax.persistence.EntityManagerFactory;\nimport javax.persistence.spi.PersistenceProvider;\nimport javax.persistence.spi.PersistenceUnitInfo;\nimport java.util.Map;\n\n/**\n * This is a temporary hack : this class is needed at startup by the HOM configuration,\n * but is not provided (and anyway HOM doesn't use it...).\n */\npublic class CassandraPersistenceProvider implements PersistenceProvider {\n    private static final Logger log = LoggerFactory.getLogger(CassandraPersistenceProvider.class);\n\n    private Map<String, Object> defProperties;\n\n    public CassandraPersistenceProvider() {\n    }\n\n    public CassandraPersistenceProvider(Map<String, Object> map) {\n        this.defProperties = map;\n    }\n\n    @Override\n    public EntityManagerFactory createContainerEntityManagerFactory(\n            PersistenceUnitInfo info, Map map) {\n        log.debug(\"creating EntityManagerFactory {} with properties {} \", null, map);\n        return null;\n    }\n\n    @Override\n    public EntityManagerFactory createEntityManagerFactory(String emName, Map map) {\n        log.debug(\"creating EntityManagerFactory {} with properties {} \", emName, map);\n        if (map == null || map.isEmpty()) {\n            return new EntityManagerFactoryImpl();\n        }\n        return new EntityManagerFactoryImpl();\n    }\n\n}\n"
  },
  {
    "path": "services/src/main/resources/META-INF/elasticsearch/elasticsearch-embedded.yml",
    "content": "##################### ElasticSearch Configuration For Embedded Cluster #####################\n\n# This file contains the configuration of the embedded elasticsearch cluster,\n\ncluster.name: tatamiCluster\nnode:\n  local: true\n  name: \"tatami-embedded-node\"\n\npath:\n  data: ${tatami.elasticsearch.path.data}/data\n  work: ${tatami.elasticsearch.path.data}/work\n  logs: ${tatami.elasticsearch.path.log}\n\nhttp.enabled: ${tatami.elasticsearch.http.enabled}\n\n"
  },
  {
    "path": "services/src/main/resources/META-INF/elasticsearch/index/group.json",
    "content": "{\n    \"settings\": {\n        \"number_of_shards\": 1,\n        \"number_of_replicas\": 0,\n        \"analysis\": {\n            \"analyzer\": {\n                \"default\": {\n                    \"type\": \"custom\",\n                    \"tokenizer\": \"standard\",\n                    \"filter\": [\"lowercase\", \"stop_francais\", \"fr_stemmer\", \"asciifolding\", \"elision\"]\n                },\n                \"lowercase\": {\n                    \"type\": \"custom\",\n                    \"tokenizer\": \"keyword\",\n                    \"filter\": [\"lowercase\" ]\n                },\n                \"prefixIndex\" : {\n                    \"type\" : \"custom\",\n                    \"tokenizer\" : \"standard\",\n                    \"filter\" : [ \"standard\", \"lowercase\", \"asciifolding\", \"elision\", \"edgeNGram\" ]\n                },\n                \"prefixSearch\" : {\n                    \"type\" : \"custom\",\n                    \"tokenizer\" : \"standard\",\n                    \"filter\" : [ \"standard\", \"lowercase\", \"asciifolding\", \"elision\" ]\n                }\n            },\n            \"filter\": {\n                \"stop_francais\": {\n                    \"type\": \"stop\",\n                    \"stopwords\": [\"_french_\"]\n                },\n                \"fr_stemmer\": {\n                    \"type\": \"stemmer\",\n                    \"name\": \"french\"\n                },\n                \"elision\": {\n                    \"type\": \"elision\",\n                    \"articles\": [\"l\", \"m\", \"t\", \"qu\", \"n\", \"s\", \"j\", \"d\"]\n                },\n                \"edgeNGram\" : {\n                    \"type\" : \"edgeNGram\",\n                    \"min_gram\" : 1,\n                    \"max_gram\" : 30\n                }\n            }\n        }\n    },\n    \"mappings\": {\n        \"group\": {\n            \"properties\": {\n                \"groupId\": {\n                    \"type\": \"string\",\n                    \"index\": \"not_analyzed\",\n                    \"include_in_all\": false\n                },\n                \"domain\": {\n                    \"type\": \"string\",\n                    \"analyzer\": \"lowercase\"\n                },\n                \"name\": {\n                    \"type\": \"multi_field\",\n                    \"path\": \"just_name\",\n                    \"fields\": {\n                        \"name\": {\n                            \"type\": \"string\"\n                        },\n                        \"name-not-analyzed\": {\n                            \"type\": \"string\",\n                            \"analyzer\": \"lowercase\"\n                        },\n                        \"prefix\" : {\n                            \"type\" : \"string\",\n                            \"index_analyzer\" : \"prefixIndex\",\n                            \"search_analyzer\" : \"prefixSearch\"\n                        }\n                    }\n                },\n                \"description\": {\n                    \"type\": \"string\"\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "services/src/main/resources/META-INF/elasticsearch/index/status.json",
    "content": "{\n    \"settings\": {\n        \"number_of_shards\": 1,\n        \"number_of_replicas\": 0,\n        \"analysis\": {\n            \"analyzer\": {\n                \"default\": {\n                    \"type\": \"custom\",\n                    \"tokenizer\": \"standard\",\n                    \"filter\": [\"lowercase\", \"stop_francais\", \"fr_stemmer\", \"asciifolding\", \"elision\"]\n                },\n                \"lowercase\": {\n                    \"type\": \"custom\",\n                    \"tokenizer\": \"keyword\",\n                    \"filter\": [\"lowercase\" ]\n                }\n\n            },\n            \"filter\": {\n                \"stop_francais\": {\n                    \"type\": \"stop\",\n                    \"stopwords\": [\"_french_\"]\n                },\n                \"fr_stemmer\": {\n                    \"type\": \"stemmer\",\n                    \"name\": \"french\"\n                },\n                \"elision\": {\n                    \"type\": \"elision\",\n                    \"articles\": [\"l\", \"m\", \"t\", \"qu\", \"n\", \"s\", \"j\", \"d\"]\n                }\n            }\n        }\n    },\n    \"mappings\": {\n        \"status\": {\n            \"properties\": {\n                \"statusId\": {\n                    \"type\": \"string\",\n                    \"index\": \"not_analyzed\",\n                    \"include_in_all\": false\n                },\n                \"domain\": {\n                    \"type\": \"string\",\n                    \"analyzer\": \"lowercase\",\n                    \"include_in_all\": false\n                },\n                \"groupId\": {\n                    \"type\": \"string\",\n                    \"index\": \"not_analyzed\",\n                    \"include_in_all\": false\n                },\n                \"publicGroup\": {\n                    \"type\": \"boolean\",\n                    \"include_in_all\": false\n                },\n                \"username\": {\n                    \"type\": \"string\",\n                    \"analyzer\": \"lowercase\"\n                },\n                \"content\": {\n                    \"type\": \"string\"\n                },\n                \"statusDate\": {\n                    \"type\": \"date\",\n                    \"include_in_all\": false\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "services/src/main/resources/META-INF/elasticsearch/index/user.json",
    "content": "{\n    \"settings\": {\n        \"number_of_shards\": 1,\n        \"number_of_replicas\" : 0,\n        \"analysis\": {\n            \"analyzer\": {\n                \"default\": {\n                    \"type\": \"custom\",\n                    \"tokenizer\": \"standard\",\n                    \"filter\": [ \"lowercase\", \"stop_francais\", \"fr_stemmer\", \"asciifolding\", \"elision\" ]\n                },\n                \"lowercase\": {\n                    \"type\": \"custom\",\n                    \"tokenizer\": \"keyword\",\n                    \"filter\": [ \"lowercase\" ]\n                },\n                \"prefixIndex\" : {\n                    \"type\" : \"custom\",\n                    \"tokenizer\" : \"standard\",\n                    \"filter\" : [ \"standard\", \"lowercase\", \"asciifolding\", \"elision\", \"edgeNGram\" ]\n                },\n                \"prefixSearch\" : {\n                    \"type\" : \"custom\",\n                    \"tokenizer\" : \"standard\",\n                    \"filter\" : [ \"standard\", \"lowercase\", \"asciifolding\", \"elision\" ]\n                }\n            },\n            \"filter\": {\n                \"stop_francais\": {\n                    \"type\": \"stop\",\n                    \"stopwords\": [ \"_french_\" ]\n                },\n                \"fr_stemmer\": {\n                    \"type\": \"stemmer\",\n                    \"name\": \"french\"\n                },\n                \"elision\": {\n                    \"type\": \"elision\",\n                    \"articles\": [ \"l\", \"m\", \"t\", \"qu\", \"n\", \"s\", \"j\", \"d\" ]\n                },\n                \"edgeNGram\" : {\n                    \"type\" : \"edgeNGram\",\n                    \"min_gram\" : 1,\n                    \"max_gram\" : 30\n                }\n            }\n        }\n    },\n    \"mappings\": {\n        \"user\": {\n            \"properties\": {\n                \"login\": {\n                    \"type\": \"string\",\n                    \"analyzer\": \"lowercase\",\n                    \"include_in_all\": false\n                },\n                \"domain\": {\n                    \"type\": \"string\",\n                    \"analyzer\": \"lowercase\",\n                    \"include_in_all\": false\n                },\n                \"username\": {\n                    \"type\" : \"multi_field\",\n                    \"path\" : \"just_name\",\n                    \"fields\" : {\n                        \"username\": {\n                            \"type\" : \"string\",\n                            \"analyzer\" : \"lowercase\"\n                        },\n                        \"prefix\" : {\n                            \"type\" : \"string\",\n                            \"index_analyzer\" : \"prefixIndex\",\n                            \"search_analyzer\" : \"prefixSearch\"\n                        }\n                    }\n                },\n                \"firstName\": {\n                    \"type\" : \"multi_field\",\n                    \"path\" : \"just_name\",\n                    \"fields\" : {\n                        \"firstName\": {\n                            \"type\": \"string\",\n                            \"analyzer\" : \"default\"\n                        },\n                        \"prefix\" : {\n                            \"type\" : \"string\",\n                            \"index_analyzer\" : \"prefixIndex\",\n                            \"search_analyzer\" : \"prefixSearch\"\n                        }\n                    }\n                },\n                \"lastName\": {\n                    \"type\" : \"multi_field\",\n                    \"path\" : \"just_name\",\n                    \"fields\" : {\n                        \"lastName\": {\n                            \"type\": \"string\",\n                            \"analyzer\" : \"default\"\n                        },\n                        \"prefix\" : {\n                            \"type\" : \"string\",\n                            \"index_analyzer\" : \"prefixIndex\",\n                            \"search_analyzer\" : \"prefixSearch\"\n                        }\n                    }\n                }\n            }\n         }\n    }\n}"
  },
  {
    "path": "services/src/main/resources/META-INF/elasticsearch/logging.yml",
    "content": "rootLogger: WARN, file\nlogger:\n  # log action execution errors for easier debugging\n  action: DEBUG\n  # reduce the logging for aws, too much is logged under the default INFO\n  com.amazonaws: WARN\n\n  # gateway\n  #gateway: DEBUG\n  #index.gateway: DEBUG\n\n  # peer shard recovery\n  #indices.recovery: DEBUG\n\n  # discovery\n  #discovery: TRACE\n\n  index.search.slowlog: TRACE, index_search_slow_log_file\n\nadditivity:\n  index.search.slowlog: false\n\nappender:\n  console:\n    type: console\n    layout:\n      type: consolePattern\n      conversionPattern: \"[%d{ISO8601}][%-5p][%-25c] %m%n\"\n\n  file:\n    type: dailyRollingFile\n    file: ${path.logs}/${cluster.name}.log\n    datePattern: \"'.'yyyy-MM-dd\"\n    layout:\n      type: pattern\n      conversionPattern: \"[%d{ISO8601}][%-5p][%-25c] %m%n\"\n\n  index_search_slow_log_file:\n    type: dailyRollingFile\n    file: ${path.logs}/${cluster.name}_index_search_slowlog.log\n    datePattern: \"'.'yyyy-MM-dd\"\n    layout:\n      type: pattern\n      conversionPattern: \"[%d{ISO8601}][%-5p][%-25c] %m%n\"\n"
  },
  {
    "path": "services/src/main/resources/META-INF/spring/applicationContext-metrics.xml",
    "content": "<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n       xmlns:metrics=\"http://www.yammer.com/schema/metrics\"\n       xsi:schemaLocation=\"\n           http://www.yammer.com/schema/metrics http://www.yammer.com/schema/metrics/metrics.xsd\n           http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd\"\n        profile=\"metrics\">\n\n    <metrics:metrics-registry id=\"metrics\"/>\n    <metrics:health-check-registry id=\"health\"/>\n\n    <metrics:annotation-driven proxy-target-class=\"true\" health-check-registry=\"health\" metrics-registry=\"metrics\"/>\n\n    <metrics:jmx-reporter id=\"metricsJmxReporter\" metrics-registry=\"metrics\"/>\n</beans>"
  },
  {
    "path": "services/src/main/resources/META-INF/spring/applicationContext-security.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!--suppress SpringSecurityFiltersConfiguredInspection, SpringFacetInspection -->\n<beans:beans xmlns=\"http://www.springframework.org/schema/security\"\n             xmlns:beans=\"http://www.springframework.org/schema/beans\"\n             xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n             xmlns:context=\"http://www.springframework.org/schema/context\"\n             xsi:schemaLocation=\"http://www.springframework.org/schema/beans\n\t\t\t\thttp://www.springframework.org/schema/beans/spring-beans-3.1.xsd\n\t\t\t\thttp://www.springframework.org/schema/security\n\t\t\t\thttp://www.springframework.org/schema/security/spring-security-3.1.xsd\n\t\t\t\thttp://www.springframework.org/schema/context\n\t\t\t\thttp://www.springframework.org/schema/context/spring-context-3.1.xsd\">\n\n    <context:property-placeholder location=\"classpath:/META-INF/tatami/tatami.properties\"/>\n\n    <global-method-security pre-post-annotations=\"enabled\"/>\n\n    <http pattern=\"/tatami/static-wro4j/**\" security=\"none\"/>\n    <http pattern=\"/tatami/static/**\" security=\"none\"/>\n    <http pattern=\"/tatami/login*\" security=\"none\"/>\n    <http pattern=\"/tatami/syndic/**\" security=\"none\"/>\n    <http pattern=\"/tatami/register/**\" security=\"none\"/>\n    <http pattern=\"/tatami/lostpassword/**\" security=\"none\"/>\n\n    <http pattern=\"/tatami/j_spring_pac4j_security_check\" use-expressions=\"true\" entry-point-ref=\"googleEntryPoint\">\n        <intercept-url pattern=\"/tatami/j_spring_pac4j_security_check\" access=\"isAuthenticated()\"/>\n    </http>\n\n\n    <http auto-config=\"true\" use-expressions=\"true\" create-session=\"ifRequired\">\n        <custom-filter after=\"BASIC_AUTH_FILTER\" ref=\"clientFilter\" />\n        <custom-filter before=\"BASIC_AUTH_FILTER\" ref=\"xAuthTokenFilter\" />\n        <remember-me key=\"tatamiRememberKey\" token-validity-seconds=\"1209599\"/>\n        <intercept-url pattern=\"/tatami/presentation\" access=\"permitAll()\"/>\n        <intercept-url pattern=\"/tatami/tos\" access=\"permitAll()\"/>\n        <intercept-url pattern=\"/tatami/license\" access=\"permitAll()\"/>\n        <intercept-url pattern=\"/tatami/404-error\" access=\"permitAll()\"/>\n        <intercept-url pattern=\"/tatami/500-error\" access=\"permitAll()\"/>\n        <intercept-url pattern=\"/tatami/rest/users\" method=\"POST\" access=\"permitAll()\"/>\n        <intercept-url pattern=\"/tatami/rest/oauth/token\" method=\"POST\" access=\"permitAll()\"/>\n        <intercept-url pattern=\"/tatami/rest/client/id\" method=\"GET\" access=\"permitAll()\"/>\n        <intercept-url pattern=\"/tatami/rest/authentication\" method=\"POST\" access=\"permitAll()\"/>\n\n        <intercept-url pattern=\"/metrics/**\" access=\"hasRole('ROLE_ADMIN')\"/>\n        <intercept-url pattern=\"/**\" access=\"isAuthenticated()\"/>\n        <access-denied-handler error-page=\"/tatami/login\"/>\n        <form-login\n                login-page=\"/tatami/login\"\n                login-processing-url=\"/tatami/authentication\"\n                authentication-success-handler-ref=\"ajaxAuthenticationSuccessHandler\"\n                authentication-failure-handler-ref=\"ajaxAuthenticationFailureHandler\"/>\n\n        <logout logout-url=\"/tatami/logout\"\n                success-handler-ref=\"ajaxLogoutSuccessHandler\"/>\n        <session-management invalid-session-url=\"/tatami/login\"/>\n\n        <!--<form-login-->\n                <!--login-processing-url=\"/tatami/authentication\"-->\n                <!--login-page=\"/tatami/login\"-->\n                <!--authentication-failure-url=\"/tatami/login?action=loginFailure\"-->\n                <!--default-target-url=\"/tatami/\"-->\n                <!--authentication-success-handler-ref=\"tatamiAuthenticationSuccessHandler\"/>-->\n    </http>\n\n    <beans:bean id=\"ajaxAuthenticationSuccessHandler\" class=\"fr.ippon.tatami.security.AjaxAuthenticationSuccessHandler\"/>\n    <beans:bean id=\"ajaxAuthenticationFailureHandler\" class=\"fr.ippon.tatami.security.AjaxAuthenticationFailureHandler\"/>\n    <beans:bean id=\"ajaxLogoutSuccessHandler\" class=\"fr.ippon.tatami.security.AjaxLogoutSuccessHandler\"/>\n    <beans:bean id=\"authenticationEntryPoint\" class=\"fr.ippon.tatami.security.Http401UnauthorizedEntryPoint\"/>\n\n    <authentication-manager alias=\"authenticationManager\">\n        <authentication-provider ref=\"googleApiAuthProvider\" />\n        <authentication-provider ref=\"daoAuthenticationProvider\"/>\n        <authentication-provider ref=\"ldapAuthenticationProvider\"/>\n        <authentication-provider ref=\"googleAuthProvider\"/>\n    </authentication-manager>\n\n    <beans:bean id=\"xAuthTokenFilter\" class=\"fr.ippon.tatami.security.xauth.XAuthTokenFilter\">\n        <beans:constructor-arg ref=\"userDetailsService\"></beans:constructor-arg>\n        <beans:constructor-arg ref=\"tokenProvider\"></beans:constructor-arg>\n    </beans:bean>\n\n    <beans:bean id=\"tokenProvider\" class=\"fr.ippon.tatami.security.xauth.TokenProvider\">\n        <beans:constructor-arg name=\"secretKey\" value=\"${tatami.google.clientSecret}\"></beans:constructor-arg>\n        <beans:constructor-arg name=\"tokenValidity\" value=\"${tatami.token.validityInSeconds}\"></beans:constructor-arg>\n    </beans:bean>\n\n    <beans:bean id=\"googleApiAuthProvider\" class=\"fr.ippon.tatami.security.GoogleApiAuthenticationProvider\"></beans:bean>\n\n\n    <!-- Defining our client -->\n    <beans:bean id=\"googleClient\" class=\"org.pac4j.oauth.client.Google2Client\">\n        <!-- tatami.google.clientId and tatami.google.clientSecret must be set in pom.xml -->\n        <beans:property name=\"key\" value=\"${tatami.google.clientId}\"/>\n        <beans:property name=\"secret\" value=\"${tatami.google.clientSecret}\"/>\n    </beans:bean>\n\n    <beans:bean id=\"clients\" class=\"org.pac4j.core.client.Clients\">\n        <!-- The callback url registered with google must be value with ?client_name=Google2Client appended -->\n        <beans:property name=\"callbackUrl\" value=\"${tatami.url}/tatami/callback\"/>\n        <beans:property name=\"clients\">\n            <beans:list>\n                <beans:ref bean=\"googleClient\"/>\n            </beans:list>\n        </beans:property>\n    </beans:bean>\n\n    <beans:bean id=\"clientFilter\" class=\"org.pac4j.springframework.security.web.ClientAuthenticationFilter\">\n        <beans:constructor-arg value=\"/tatami/callback\"/>\n        <beans:property name=\"clients\" ref=\"clients\"/>\n        <beans:property name=\"authenticationManager\" ref=\"authenticationManager\"/>\n    </beans:bean>\n\n    <beans:bean id=\"googleAuthProvider\" class=\"fr.ippon.tatami.security.GoogleAuthenticationProvider\">\n        <beans:property name=\"clients\" ref=\"clients\"/>\n        <beans:property name=\"userDetailsService\" ref=\"googleAutoRegisteringUserDetailsService\"/>\n    </beans:bean>\n\n    <beans:bean id=\"googleEntryPoint\" class=\"org.pac4j.springframework.security.web.ClientAuthenticationEntryPoint\">\n        <beans:property name=\"client\" ref=\"googleClient\"/>\n    </beans:bean>\n\n    <beans:bean id=\"daoAuthenticationProvider\"\n                class=\"org.springframework.security.authentication.dao.DaoAuthenticationProvider\">\n        <beans:property name=\"userDetailsService\" ref=\"userDetailsService\"/>\n        <beans:property name=\"passwordEncoder\">\n            <beans:bean class=\"org.springframework.security.crypto.password.StandardPasswordEncoder\"/>\n        </beans:property>\n    </beans:bean>\n\n    <beans:bean id=\"ldapContextSource\"\n                class=\"org.springframework.security.ldap.DefaultSpringSecurityContextSource\">\n        <beans:constructor-arg value=\"${tatami.ldapauth.url}\"/>\n    </beans:bean>\n\n    <beans:bean id=\"ldapAuthenticationProvider\" class=\"fr.ippon.tatami.security.TatamiLdapAuthenticationProvider\">\n        <beans:constructor-arg>\n            <beans:bean class=\"org.springframework.security.ldap.authentication.BindAuthenticator\">\n                <beans:constructor-arg ref=\"ldapContextSource\"/>\n                <beans:property name=\"userSearch\">\n                    <beans:bean class=\"org.springframework.security.ldap.search.FilterBasedLdapUserSearch\">\n                        <beans:constructor-arg value=\"${tatami.ldapauth.searchbase}\"/>\n                        <beans:constructor-arg value=\"${tatami.ldapauth.searchfilter}\"/>\n                        <beans:constructor-arg ref=\"ldapContextSource\"/>\n                    </beans:bean>\n                </beans:property>\n            </beans:bean>\n        </beans:constructor-arg>\n        <beans:constructor-arg value=\"${tatami.ldapauth.domain}\"/>\n    </beans:bean>\n\n</beans:beans>\n"
  },
  {
    "path": "services/src/main/resources/META-INF/tatami/customization.properties",
    "content": "\n# list of authorized themes :\n# useful if you have only a few official company themes and must restrict your users to these\n#tatami.authorized.theme=bootstrap,cerulean,cosmo,journal,readable,simplex,spacelab,spruce,superhero,united\n\n"
  },
  {
    "path": "services/src/main/resources/META-INF/tatami/mails/common",
    "content": "#**\n * msg\n *\n * Shorthand macro to retrieve locale sensitive message from messages_xxx.properties\n *#\n#macro( msg $key )$messages.getMessage($key, null, $locale)#end\n\n"
  },
  {
    "path": "services/src/main/resources/META-INF/tatami/mails/dailyDigestEmail",
    "content": "#parse(\"common\")\n#msg(\"dailyDigest.greeting\") ${user.Login},\n\n#if ($statuses.size() == 1)\n#msg(\"dailyDigest.textOneMessages1\")\n\n\n   #msg(\"dailyDigest.from\") @$statuses[0].Username\n   $statuses[0].Content\n#elseif ($statuses.size() > 1)\n#if (${nbStatus} >10 )\n#msg(\"dailyDigest.textSeveralMessagesSelection1\") ${nbStatus} #msg(\"dailyDigest.textSeveralMessagesSelection2\")\n#else\n#msg(\"dailyDigest.textSeveralMessages1\") ${nbStatus} #msg(\"dailyDigest.textSeveralMessages2\")\n#end\n\n#foreach( $status in $statuses )\n * #msg(\"dailyDigest.from\") @$status.Username\n   $status.Content\n\n#end\n#msg(\"dailyDigest.textSeveralMessages3\")\n\n#else\n#msg(\"dailyDigest.textNoMessage\")\n#end\n\n#if ($suggestedUsers.size()== 1)\n    #msg(\"dailyDigest.oneSuggestedUsers1\")\n\n#elseif ($suggestedUsers.size() > 1)\n#msg(\"dailyDigest.suggestedUsers1\")\n\n#foreach( $suggestedUser in $suggestedUsers )\n * $suggestedUser.Username\n#end\n#else\n#msg(\"dailyDigest.noSuggestedUsers\")\n#end\n\n\n#msg(\"dailyDigest.urlText\")\n\n$tatamiUrl\n\n#msg(\"dailyDigest.endText1\")\n\n\n#msg(\"email.signature\")"
  },
  {
    "path": "services/src/main/resources/META-INF/tatami/mails/deactivatedUserEmail",
    "content": "#parse(\"common\")\n#msg(\"deactivatedUser.greeting\") ${username},\n\n#msg(\"deactivatedUser.text1\")\n\n#msg(\"deactivatedUser.text2\")\n\n#msg(\"deactivatedUser.text3\")\n\n#msg(\"email.signature\")\n"
  },
  {
    "path": "services/src/main/resources/META-INF/tatami/mails/invitationMessageEmail",
    "content": "#parse(\"common\")\n#msg(\"invitationMessage.greeting\"),\n\n${user} #msg(\"invitationMessage.text1\")\n\n#msg(\"invitationMessage.text2\")\n\n${invitationUrl}\n\n#msg(\"invitationMessage.text3\")\n\n#msg(\"email.signature\")"
  },
  {
    "path": "services/src/main/resources/META-INF/tatami/mails/lostPasswordEmail",
    "content": "#parse(\"common\")\n#msg(\"lostPassword.greeting\") ${user.Login},\n\n#msg(\"lostPassword.text1\")\n\n#msg(\"lostPassword.text2\")\n\n${reinitUrl}\n\n#msg(\"lostPassword.text3\")\n\n#msg(\"lostPassword.text4\")\n\n#msg(\"email.signature\")"
  },
  {
    "path": "services/src/main/resources/META-INF/tatami/mails/messages/messages_en.properties",
    "content": "email.signature=Ippon Technologies\n\nregistration.title=Tatami Registration\nregistration.greeting=Dear\nregistration.text1=Your Tatami account has been created, please click on the URL below to activate it:\nregistration.text2=Regards,\n\nlostPassword.title=Tatami Forgotten Password\nlostPassword.greeting=Dear\nlostPassword.text1=Someone asked to reset your password.\nlostPassword.text2=If you want to reset your password, please click on the link below:\nlostPassword.text3=If you do not want to reset your password, you can safely ignore this message.\nlostPassword.text4=Regards,\n\nvalidation.title=Tatami Account Confirmed\nvalidation.greeting=Dear\nvalidation.text1=Your Tatami account has been confirmed, here is your password:\nvalidation.text2=Regards,\n\npasswordReinitialized.title=Tatami Password Reset\npasswordReinitialized.greeting=Dear\npasswordReinitialized.text1=Your Tatami password has been reset, here is your new password:\npasswordReinitialized.text2=Regards,\n\nuserPrivateMessage.title=You received a private message on Tatami\nuserPrivateMessage.greeting=Dear\nuserPrivateMessage.text1=You received a private message on Tatami from\nuserPrivateMessage.text2=You can see this status on Tatami:\nuserPrivateMessage.text3=Regards,\n\nuserMention.title=Someone mentioned you on Tatami\nuserMention.greeting=Dear\nuserMention.text1=Someone mentioned you on Tatami:\nuserMention.text2=You can see this status on Tatami:\nuserMention.text3=Regards,\n\nreportedStatus.title=Reported Status on Tatami\nreportedStatus.greeting=Dear admin,\nreportedStatus.text1=Someone reported a status on Tatami:\nreportedStatus.text2=You can see this status on Tatami:\nreportedStatus.text3=Regards,\n\ndeactivatedUser.title=Your Account is Deactivated\ndeactivatedUser.greeting=Dear\ndeactivatedUser.text1=An admin has deactivated your account.\ndeactivatedUser.text2=Please contact your administrator for more details.\ndeactivatedUser.text3=Regards,\n\n\ninvitationMessage.title=One of your co-workers invited you to Tatami\ninvitationMessage.greeting=Hello,\ninvitationMessage.text1=invited you to Tatami, your company's social network.\ninvitationMessage.text2=You can register on:\ninvitationMessage.text3=Regards,\n\ndailyDigest.title=Tatami Daily Digest\ndailyDigest.greeting=Dear\ndailyDigest.from=from\ndailyDigest.textOneMessages1=You have one message in your timeline today:\ndailyDigest.textSeveralMessages1=You have\ndailyDigest.textSeveralMessages2=messages in your timeline today.\ndailyDigest.textSeveralMessages3=Login to Tatami to read your other messages.\ndailyDigest.textSeveralMessagesSelection1=You have\ndailyDigest.textSeveralMessagesSelection2=message in your timeline today. Here are some of them:\ndailyDigest.textNoMessage=There are no messages in your timeline today.\ndailyDigest.oneSuggestedUsers1=Suggested users you might want to follow:\ndailyDigest.suggestedUsers1=To get more interesting updates, you may want to follow these users:\ndailyDigest.noSuggestedUsers=You can find more interesting people on Tatami.\ndailyDigest.endText1=See you tomorrow for more updates\ndailyDigest.urlText=Don't miss anything, go to Tatami!\n\nweeklyDigest.title=Tatami Weekly Digest\nweeklyDigest.greeting=Dear\nweeklyDigest.from=from\nweeklyDigest.textOneMessages1=You have one message in your timeline:\nweeklyDigest.textSeveralMessages1=You have\nweeklyDigest.textSeveralMessages2=messages in your timeline.\nweeklyDigest.textSeveralMessages3=Login to Tatami to read your other messages.\nweeklyDigest.textSeveralMessagesSelection1=You have\nweeklyDigest.textSeveralMessagesSelection2=message in your timeline today. Here are some of them:\nweeklyDigest.textNoMessage=There are no messages in your timeline.\nweeklyDigest.oneSuggestedUsers1=Suggested users you might want to follow:\nweeklyDigest.suggestedUsers1=To get more interesting updates, you may want to follow these users:\nweeklyDigest.noSuggestedUsers=You can find more interesting people on Tatami.\nweeklyDigest.oneSuggestedGroups1=To get more interesting updates, you may want to join this group:\nweeklyDigest.suggestedGroups1=To get more interesting updates, you may want to join to these groups:\nweeklyDigest.noSuggestedGroups=You can find more interesting groups on Tatami.\nweeklyDigest.endText1=See you next week for more updates\nweeklyDigest.urlText=Don't miss anything, go to Tatami!\n"
  },
  {
    "path": "services/src/main/resources/META-INF/tatami/mails/messages/messages_fr.properties",
    "content": "email.signature=Ippon Technologies.\n\nregistration.title=Activation de votre compte Tatami\nregistration.greeting=Cher\nregistration.text1=Votre compte Tatami a été créé, pour l'activer merci de cliquer sur le lien ci-dessous :\nregistration.text2=Cordialement,\n\nlostPassword.title=Perte de votre mot de passe Tatami\nlostPassword.greeting=Cher\nlostPassword.text1=Une ré-initialisation de votre mot de passe a été demandée\nlostPassword.text2=Si vous souhaitez ré-initialiser votre mot de passe, cliquez sur le lien ci-dessous :\nlostPassword.text3=Si vous ne souhaitez pas ré-initialiser votre mot de passe, vous pouvez ignorer ce message.\nlostPassword.text4=Cordialement,\n\nvalidation.title=validation de votre compte Tatami\nvalidation.greeting=Cher\nvalidation.text1=Votre compte Tatami a été validé, voici votre mot de passe :\nvalidation.text2=Cordialement,\n\npasswordReinitialized.title=Ré-initialisation de votre mot de passe Tatami\npasswordReinitialized.greeting=Cher\npasswordReinitialized.text1=Votre mot de passe Tatami a été ré-initialisé, voici votre nouveau mot de passe :\npasswordReinitialized.text2=Cordialement,\n\nuserPrivateMessage.title=Vous avez reçu un message privé sur Tatami\nuserPrivateMessage.greeting=Cher\nuserPrivateMessage.text1=Vous avez reçu un message privé sur Tatami de la part de\nuserPrivateMessage.text2=Pour voir ce message sur Tatami :\nuserPrivateMessage.text3=Cordialement,\n\nuserMention.title=Vous avez été mentionné sur Tatami\nuserMention.greeting=Cher\nuserMention.text1=Vous avez été mentionné sur Tatami :\nuserMention.text2=Pour voir ce message sur Tatami :\nuserMention.text3=Cordialement,\n\nreportedStatus.title=Statut Signalé sur Tatami\nreportedStatus.greeting=Cher Admin\nreportedStatus.text1=Quelqu'un a signalé un statut sur Tatami\nreportedStatus.text2=Pour voir ce message sur Tatami:\nreportedStatus.text3=Cordialement,\n\ndeactivatedUser.title=Your Account is Deactivated\ndeactivatedUser.greeting=Cher\ndeactivatedUser.text1=An admin has deactivated your account.\ndeactivatedUser.text2=Please contact your administrator for more details.\ndeactivatedUser.text3=Cordialement,\n\ninvitationMessage.title=Un de vos collègues vous a invité sur Tatami\ninvitationMessage.greeting=Bonjour\ninvitationMessage.text1=vous a invité sur Tatami, votre réseau social d'entreprise.\ninvitationMessage.text2=Pour vous enregistrer, cliquez ici :\ninvitationMessage.text3=Cordialement,\n\ndailyDigest.title=Tatami - Résumé quotidien de votre actualité\ndailyDigest.greeting=Bonjour\ndailyDigest.from=de\ndailyDigest.textOneMessages1=Vous avez un message aujourd'hui \\:\ndailyDigest.textSeveralMessages1=Vous avez\ndailyDigest.textSeveralMessages2=messages aujourd'hui.\ndailyDigest.textSeveralMessages3=Pour voir vos autres messages, connectez vous sur tatami !\ndailyDigest.textSeveralMessagesSelection1=Vous avez\ndailyDigest.textSeveralMessagesSelection2=messages aujourd'hui. En voici une sélection :\ndailyDigest.textNoMessage=Vous n'avez pas de message aujourd'hui.\ndailyDigest.oneSuggestedUsers1=Pour avoir un visions plus riche de l'actualité, nous vous conseillons de vous abonner à l'utilisateur suivant :\ndailyDigest.suggestedUsers1=Pour avoir un visions plus riche de l'actualité, nous vous conseillons de vous abonner aux utilisateurs suivants :\ndailyDigest.noSuggestedUsers=Vous pouvez trouver plus de personnes à suivre sur tatami.\ndailyDigest.endText1=merci et à demain,\ndailyDigest.urlText=Ne manquez rien de l'actualité, connectez vous sur Tatami !\n\nweeklyDigest.title=Tatami - Résumé hebdomadaire de votre actualité\nweeklyDigest.greeting=Bonjour\nweeklyDigest.from=de\nweeklyDigest.textOneMessages1=Vous avez reçu un message cette semaine \\:\nweeklyDigest.textSeveralMessages1=Vous avez reçu\nweeklyDigest.textSeveralMessages2=messages cette semaine.\nweeklyDigest.textSeveralMessages3=Pour voir vos autres messages, connectez vous sur tatami !\nweeklyDigest.textSeveralMessagesSelection1=Vous avez reçu\nweeklyDigest.textSeveralMessagesSelection2=messages cette semaine. En voici une sélection :\nweeklyDigest.textNoMessage=Vous n'avez pas reçu de message cette semaine.\nweeklyDigest.oneSuggestedUsers1=Pour avoir un visions plus riche de l'actualité, nous vous conseillons de vous abonner à l'utilisateur suivant :\nweeklyDigest.suggestedUsers1=Pour avoir un visions plus riche de l'actualité, nous vous conseillons de vous abonner aux utilisateurs suivants :\nweeklyDigest.noSuggestedUsers=Vous pouvez trouver plus de personnes à suivre sur tatami.\nweeklyDigest.oneSuggestedGroups1=Pour avoir un visions plus riche de l'actualité, nous vous conseillons de vous inscrire au groupe suivant :\nweeklyDigest.suggestedGroups1=Pour avoir un visions plus riche de l'actualité, nous vous conseillons de vous inscrire aux groupes suivants :\nweeklyDigest.noSuggestedGroups=Vous pouvez trouver plus de groupes à suivre sur tatami.\nweeklyDigest.endText1=merci et à la semaine prochaine,\nweeklyDigest.urlText=Ne manquez rien de l'actualité, connectez vous sur Tatami !\n"
  },
  {
    "path": "services/src/main/resources/META-INF/tatami/mails/passwordReinitializedEmail",
    "content": "#parse(\"common\")\n#msg(\"passwordReinitialized.greeting\") ${user.Login},\n\n#msg(\"passwordReinitialized.text1\")\n\n${password}\n\n#msg(\"passwordReinitialized.text2\")\n\n#msg(\"email.signature\")"
  },
  {
    "path": "services/src/main/resources/META-INF/tatami/mails/registrationEmail",
    "content": "#parse(\"./common\")\n#msg(\"registration.greeting\") ${user.Login},\n\n#msg(\"registration.text1\")\n\n${registrationUrl}\n\n#msg(\"registration.text2\")\n\n#msg(\"email.signature\")\n\n"
  },
  {
    "path": "services/src/main/resources/META-INF/tatami/mails/reportedStatusEmail",
    "content": "#parse(\"common\")\n#msg(\"reportedStatus.greeting\"),\n\n#msg(\"reportedStatus.text1\")\n${status.Content}\n\n#msg(\"reportedStatus.text2\")\n\n${statusUrl}\n\n#msg(\"reportedStatus.text3\")\n\n#msg(\"email.signature\")\n"
  },
  {
    "path": "services/src/main/resources/META-INF/tatami/mails/userMentionEmail",
    "content": "#parse(\"common\")\n#msg(\"userMention.greeting\") ${user.Username},\n\n#msg(\"userMention.text1\")\n\n@${status.Username}\n${status.Content}\n\n#msg(\"userMention.text2\")\n\n${statusUrl}\n\n#msg(\"userMention.text3\")\n\n#msg(\"email.signature\")\n"
  },
  {
    "path": "services/src/main/resources/META-INF/tatami/mails/userPrivateMessageEmail",
    "content": "#parse(\"common\")\n#msg(\"userPrivateMessage.greeting\") ${user.Username},\n\n#msg(\"userPrivateMessage.text1\") @${status.Username} :\n\n${status.Content}\n\n#msg(\"userPrivateMessage.text2\")\n\n${statusUrl}\n\n#msg(\"userPrivateMessage.text3\")\n\n#msg(\"email.signature\")\n\n\n"
  },
  {
    "path": "services/src/main/resources/META-INF/tatami/mails/validationEmail",
    "content": "#parse(\"common\")\n#msg(\"validation.greeting\") ${user.Login},\n\n#msg(\"validation.text1\")\n\n${password}\n\n#msg(\"validation.text2\")\n\n#msg(\"email.signature\")"
  },
  {
    "path": "services/src/main/resources/META-INF/tatami/mails/weeklyDigestEmail",
    "content": "#parse(\"common\")\n#msg(\"weeklyDigest.greeting\") ${user.Login},\n\n#if ($statuses.size() == 1)\n#msg(\"weeklyDigest.textOneMessages1\")\n\n\n    #msg(\"weeklyDigest.from\") @$statuses[0].Username\n    $statuses[0].Content\n#elseif ($statuses.size() > 1)\n#if (${nbStatus} >10 )\n#msg(\"weeklyDigest.textSeveralMessagesSelection1\") ${nbStatus} #msg(\"weeklyDigest.textSeveralMessagesSelection2\")\n#else\n#msg(\"weeklyDigest.textSeveralMessages1\") ${nbStatus} #msg(\"weeklyDigest.textSeveralMessages2\")\n#end\n\n#foreach( $status in $statuses )\n    * #msg(\"weeklyDigest.from\") @$status.Username\n        $status.Content\n\n#end\n#msg(\"weeklyDigest.textSeveralMessages3\")\n\n#else\n#msg(\"weeklyDigest.textNoMessage\")\n#end\n\n#if ($suggestedUsers.size()== 1)\n#msg(\"weeklyDigest.oneSuggestedUsers1\")\n\n#elseif ($suggestedUsers.size() > 1)\n#msg(\"weeklyDigest.suggestedUsers1\")\n\n#foreach( $suggestedUser in $suggestedUsers )\n    * $suggestedUser.Username\n#end\n#else\n#msg(\"weeklyDigest.noSuggestedUsers\")\n#end\n\n#if ($suggestedGroups.size()== 1)\n#msg(\"weeklyDigest.oneSuggestedGroups1\")\n\n#elseif ($suggestedGroups.size() > 1)\n#msg(\"weeklyDigest.suggestedGroups1\")\n\n#foreach( $suggestedGroup in $suggestedGroups )\n    * $suggestedGroup.Name\n      $suggestedGroup.Description\n#end\n#else\n#msg(\"weeklyDigest.noSuggestedGroups\")\n#end\n\n#msg(\"weeklyDigest.urlText\")\n\n$tatamiUrl\n\n#msg(\"weeklyDigest.endText1\")\n\n\n#msg(\"email.signature\")"
  },
  {
    "path": "services/src/main/resources/META-INF/tatami/tatami.properties",
    "content": "# tatami.version is used to version static resources and thus enable a long cache value.\ntatami.version=${tatami.version}\ntatami.url=${tatami.url}\n\n#Web app configuration\ntatami.wro4j.enabled=${tatami.wro4j.enabled}\ntatami.google.analytics.key=${tatami.google.analytics.key}\ntatami.message.reloading.enabled=${tatami.message.reloading.enabled}\n# Spring Security channel security, see http://static.springsource.org/spring-security/site/docs/3.1.x/reference/ns-config.html#ns-requires-channel\ntatami.connection.security=${tatami.connection.security}\n# Automatically register users. WARNING : should only be set to true for testing the application\ntatami.automatic.registration=${tatami.automatic.registration}\n\n#Monitoring using Yammer Metrics\ntatami.metrics.graphite.host=${tatami.metrics.graphite.host}\ntatami.metrics.graphite.port=${tatami.metrics.graphite.port}\n\n#User configuration\ntatami.admin.users=jdubois@ippon.fr,julien.dubois@gmail.com,vdebelil@ippon.fr,ggruel@ippon.fr,snomis@ippon.fr,rlheritier@ippon.fr,jrisch@ippon.fr,bscott@ippon.fr,khegeland@ippon.fr\ntatami.ldapauth.domain=ippon.fr\ntatami.ldapauth.url=${tatami.ldapauth.url}\ntatami.ldapauth.searchbase=${tatami.ldapauth.searchbase}\ntatami.ldapauth.searchfilter=${tatami.ldapauth.searchfilter}\n\n#Attachment thumbnail generation\n#Files extension for which we create thumbnails, comma separated\ntatami.attachment.thumbnail.extensions=.gif,.jpg,.jpeg,.png\n\ntatami.google.clientId=${tatami.google.clientId}\ntatami.google.clientSecret=${tatami.google.clientSecret}\n\n#E-mail configuration\nsmtp.host=${tatami.smtp.host}\nsmtp.port=${tatami.smtp.port}\nsmtp.user=${tatami.smtp.user}\nsmtp.password=${tatami.smtp.password}\nsmtp.from=${tatami.smtp.from}\nsmtp.tls=${tatami.smtp.tls}\n\n#Apple push notifications\napple.push.certificate=${apple.push.certificate}\napple.push.password=${apple.push.password}\n\n#Cassandra configuration\ncassandra.host=127.0.0.1:9160\ncassandra.clusterName=Tatami cluster\ncassandra.keyspace=tatami\n\n# Search engine configuration : you can use either Elastic Search in embedded or in remote mode\n# - In embedded mode, Elastic Search runs inside Tatami : this is useful for development, test, and small installations\n# - In remote mode, Elastic Search runs as a separate node (or even cluster), which is useful for large installations\n#\n# You can change this configuration mode later : a full reindex of the search engine can be triggered on the\n# administration page\nelasticsearch.engine.mode=${tatami.elasticsearch.engine.mode}\n\nelasticsearch.indexNamePrefix=tatami\n# Must be the same as the ES cluster.name variable (see elasticsearch.yml)\nelasticsearch.cluster.name=tatamiCluster\n#Cluster nodes example: elasticsearch.cluster.nodes=10.160.0.12,10.160.0.13:9300\nelasticsearch.cluster.nodes=127.0.0.1:9300\nelasticsearch.cluster.default.communication.port=9300\n\n#Tatami Bot configuration\nfr.ippon.tatami.bot.enabled=${fr.ippon.tatami.bot.enabled}\n\n#File & account size configuration\n#in bytes\nfile.max.size=10000000\n#in Mb\nstorage.basic.max.size=10\nstorage.premium.max.size=1000\nstorage.ippon.max.size=100000\n#\n#SubscriptionLevel\nsuscription.level.free=0\nsuscription.level.premium=1\nsuscription.level.ippon=-1\n"
  },
  {
    "path": "services/src/main/resources/ehcache.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<ehcache xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:noNamespaceSchemaLocation=\"http://ehcache.org/ehcache.xsd\"\n         name=\"CM1\"\n         updateCheck=\"false\"\n         maxBytesLocalHeap=\"${ehcache.maxBytesLocalHeap}\">\n\n    <diskStore path=\"java.io.tmpdir\"/>\n\n    <defaultCache\n            eternal=\"false\"\n            overflowToDisk=\"false\"\n            />\n\n    <cache name=\"status-cache\"/>\n\n    <cache name=\"user-cache\"/>\n\n    <cache name=\"user-prefix-cache\"/>\n\n    <cache name=\"group-prefix-cache\"/>\n\n    <cache name=\"group-user-cache\"/>\n\n    <cache name=\"group-cache\"/>\n\n    <cache name=\"favorites-cache\"/>\n\n    <cache name=\"shared-cache\"/>\n\n    <cache name=\"friends-cache\"/>\n\n    <cache name=\"followers-cache\"/>\n\n    <cache name=\"dayline-cache\"\n           timeToLiveSeconds=\"60\">\n    </cache>\n\n    <cache name=\"trends-cache\"\n           timeToLiveSeconds=\"300\">\n    </cache>\n\n    <cache name=\"user-trends-cache\"\n           timeToLiveSeconds=\"300\">\n    </cache>\n\n    <cache name=\"domain-tags-cache\"\n           timeToLiveSeconds=\"300\">\n    </cache>\n\n    <cache name=\"suggest-users-cache\"\n           timeToLiveSeconds=\"1800\">\n    </cache>\n\n    <cache name=\"suggest-groups-cache\"\n           timeToLiveSeconds=\"1800\">\n    </cache>\n\n    <cache name=\"avatar-cache\"\n           timeToIdleSeconds=\"1800\"/>\n\n    <cache name=\"attachment-cache\"\n           maxBytesLocalHeap=\"75%\"\n           timeToIdleSeconds=\"600\"/>\n\n</ehcache>\n\n"
  },
  {
    "path": "services/src/main/resources/logback.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<configuration scan=\"true\">\n    <appender name=\"CONSOLE\" class=\"ch.qos.logback.core.ConsoleAppender\">\n        <encoder>\n            <charset>utf-8</charset>\n            <Pattern>[%p] %c - %m%n</Pattern>\n        </encoder>\n    </appender>\n\n    <appender name=\"SYNC_PAPERTRAIL\" class=\"ch.qos.logback.classic.net.SyslogAppender\">\n        <syslogHost>${logback.syslogHost}</syslogHost>\n        <port>${logback.syslogHost.port}</port>\n        <facility>LOCAL7</facility>\n        <suffixPattern>[%thread] %logger %msg</suffixPattern>\n    </appender>\n\n    <appender name=\"PAPERTRAIL\" class=\"ch.qos.logback.classic.AsyncAppender\">\n        <appender-ref ref=\"SYNC_PAPERTRAIL\"/>\n    </appender>\n\n    <logger name=\"fr.ippon.tatami\" level=\"${logback.loglevel}\"/>\n    <logger name=\"ch.qos.logback\" level=\"WARN\"/>\n    <logger name=\"com.yammer.metrics\" level=\"WARN\"/>\n    <logger name=\"com.notnoop\" level=\"WARN\"/>\n    <logger name=\"me.prettyprint\" level=\"WARN\"/>\n    <logger name=\"net.sf.ehcache\" level=\"WARN\"/>\n    <logger name=\"netty\" level=\"WARN\"/>\n    <logger name=\"org.apache\" level=\"WARN\"/>\n    <logger name=\"org.atmosphere\" level=\"WARN\"/>\n    <logger name=\"org.elasticsearch\" level=\"WARN\"/>\n    <logger name=\"org.hibernate.validator\" level=\"WARN\"/>\n    <logger name=\"org.openid4java\" level=\"WARN\"/>\n    <logger name=\"org.springframework\" level=\"WARN\"/>\n    <logger name=\"org.springframework.web\" level=\"WARN\"/>\n    <logger name=\"org.springframework.security\" level=\"WARN\"/>\n    <logger name=\"org.springframework.cache\" level=\"WARN\"/>\n    <logger name=\"ro.isdc\" level=\"WARN\"/>\n\n    <root level=\"${logback.loglevel}\">\n        <appender-ref ref=\"${logback.appender}\"/>\n    </root>\n\n</configuration>\n"
  },
  {
    "path": "services/src/main/webapp/app/shared/services/AuthenticationService.js",
    "content": "TatamiApp.factory('AuthenticationService', ['$rootScope', '$state', 'UserSession', function($rootScope, $state, UserSession) {\n    return {\n        authenticate: function() {\n            return UserSession.authenticate().then(function(result) {\n                if(result !== null && result.action === null && $state.current.data && !$state.current.data.public) {\n                    // User isn't login in. Change the session token, and redirect to login\n                    UserSession.clearSession();\n                    $state.go('tatami.login.main');\n                }\n            }); \n        }\n    }\n}]);"
  },
  {
    "path": "services/src/main/webapp/app/shared/services/GeolocService.js",
    "content": "/**\n * This service is used to handle getting the geolocalisation of a user\n */\n\nTatamiApp.factory('GeolocalisationService', function() {\n    return {\n        \n        /**\n         * Uses HTML5 to get geolocation information from the user\n         * @returns If geolocation data can be found for the user\n         *              then we return the position in the form\n         *              \"lat, lon\"\n         *          Otherwise, we return the empty string.\n         */\n        getGeolocalisation: function(callback) {\n            if(navigator.geolocation){\n                navigator.geolocation.getCurrentPosition(function(position) {\n                    callback(position);\n                });\n            }\n        },\n\n        /**\n         * Returns a string with the location data based on the openstreetmap website\n         * @param position The users position\n         * @returns {string} The URL to openstreetmaps\n         */\n        getGeolocUrl: function(position) {\n            var latitude = position.split(',')[0].trim();\n            var longitude = position.split(',')[1].trim();\n            return 'https://www.openstreetmap.org/?mlon=' + longitude + '&mlat=' + latitude;\n        }\n    }\n});"
  },
  {
    "path": "services/src/main/webapp/app/shared/services/GroupService.js",
    "content": "TatamiApp.factory('GroupService', ['$resource', function($resource) {\n    return $resource('/tatami/rest/groups/:groupId', null,\n    {\n        'getStatuses': { \n            method: 'GET',\n            isArray: true,\n            params: { groupId: '@groupId' },\n            url: '/tatami/rest/groups/:groupId/timeline',\n            transformResponse: function(statuses) {\n                statuses = angular.fromJson(statuses);\n\n                for(var i = 0; i < statuses.length; i++) {\n                    statuses[i]['avatarURL'] = statuses[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + statuses[i].avatar + '/photo.jpg';\n\n                    if(statuses[i].geoLocalization) {\n                        var latitude = statuses[i].geoLocalization.split(',')[0].trim();\n                        var longitude = statuses[i].geoLocalization.split(',')[1].trim();\n                        statuses[i]['locationURL'] = \n                            'https://www.openstreetmap.org/?mlon='\n                            + longitude + '&mlat=' + latitude;\n                    }\n                }\n\n                return statuses;\n            }\n        },\n        'getMembers': { \n            method: 'GET',\n            isArray: true,\n            params: { groupId: '@groupId' },\n            url: '/tatami/rest/groups/:groupId/members/',\n            transformResponse: function(users) {\n                users = angular.fromJson(users);\n\n                for(var i = 0; i < users.length; i++) {\n                    users[i]['avatarURL'] = users[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + users[i].avatar + '/photo.jpg';\n                }\n\n                return users;\n            }\n        },\n        'getRecommendations': { method: 'GET', isArray: true, url: '/tatami/rest/groupmemberships/suggestions' },\n        'join': { method: 'PUT', params: { groupId: '@groupId', username: '@username' }, url: '/tatami/rest/groups/:groupId/members/:username' },\n        'leave': { method: 'DELETE', params: { groupId: '@groupId', username: '@username' }, url: '/tatami/rest/groups/:groupId/members/:username' },\n        'update': { method: 'PUT', params: { groupId: '@groupId' }, url: '/tatami/rest/groups/:groupId' }\n    });\n}]);"
  },
  {
    "path": "services/src/main/webapp/app/shared/services/HomeService.js",
    "content": "TatamiApp.factory('HomeService', ['$resource', function($resource) {\n    var responseTransform = function(statuses) {\n        statuses = angular.fromJson(statuses);\n\n        for(var i = 0; i < statuses.length; i++) {\n            statuses[i]['avatarURL'] = statuses[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + statuses[i].avatar + '/photo.jpg';\n\n            if(statuses[i].geoLocalization) {\n                var latitude = statuses[i].geoLocalization.split(',')[0].trim();\n                var longitude = statuses[i].geoLocalization.split(',')[1].trim();\n                statuses[i]['locationURL'] = \n                    'https://www.openstreetmap.org/?mlon='\n                    + longitude + '&mlat=' + latitude;\n            }\n        }\n\n        return statuses;\n    };\n\n    return $resource(null, null,\n    {\n        'getMentions': { \n            method: 'GET', isArray: true, url: '/tatami/rest/mentions',\n            transformResponse: responseTransform\n        },\n        'getFavorites': { \n            method: 'GET', isArray: true, url: '/tatami/rest/favorites',\n            transformResponse: responseTransform\n        },\n        'getCompanyTimeline': { \n            method: 'GET', isArray: true, url: '/tatami/rest/company',\n            transformResponse: responseTransform\n        }\n     });\n}]);"
  },
  {
    "path": "services/src/main/webapp/app/shared/services/ProfileService.js",
    "content": "angular.module('TatamiApp.services', [])\n    .factory('ProfileService', ['$resource', function ($resource) {\n        return $resource('/tatami/rest/account/profile', null,\n            {\n                'get': {\n                    method: 'GET',\n                    transformResponse: function (profile) {\n                        var parsedProfile = {};\n                        try {\n                            parsedProfile = angular.fromJson(profile);\n                        } catch(e) {\n                            parsedProfile = {};\n                        }\n                        parsedProfile['avatarURL'] = parsedProfile.avatar === '' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + parsedProfile.avatar + '/photo.jpg';\n                        return parsedProfile;\n                    }\n                },\n                'update': {\n                    method: 'PUT',\n                    transformRequest: function (profile) {\n                        delete profile['avatarURL'];\n                        return angular.toJson(profile);\n                    }\n                }\n            });\n    }]);\n"
  },
  {
    "path": "services/src/main/webapp/app/shared/services/SearchService.js",
    "content": "TatamiApp.factory('SearchService', ['$resource', function($resource) {\n    var responseTransform = function(users) {\n        users = angular.fromJson(users);\n\n        for(var i = 0; i < users.length; i++) {\n            users[i]['avatarURL'] = users[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + users[i].avatar + '/photo.jpg';\n        }\n\n        return users;\n    };\n\n    return $resource('/tatami/rest/search/:term', { term: '@term' },\n    {\n        'query': { \n            method: 'GET', isArray: true, transformResponse: responseTransform\n        },\n        'get': {\n            method: 'GET', transformResponse: responseTransform\n        }\n    });\n}]);"
  },
  {
    "path": "services/src/main/webapp/app/shared/services/StatusService.js",
    "content": "TatamiApp.factory('StatusService', ['$resource', function($resource) {\n    var responseTransform = function(statuses) {\n        statuses = angular.fromJson(statuses);\n\n        for(var i = 0; i < statuses.length; i++) {\n            statuses[i]['avatarURL'] = statuses[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + statuses[i].avatar + '/photo.jpg';\n\n            if(statuses[i].geoLocalization) {\n                var latitude = statuses[i].geoLocalization.split(',')[0].trim();\n                var longitude = statuses[i].geoLocalization.split(',')[1].trim();\n                statuses[i]['locationURL'] =\n                    'https://www.openstreetmap.org/?mlon='\n                    + longitude + '&mlat=' + latitude;\n            }\n        }\n\n        return statuses;\n    };\n\n    return $resource('/tatami/rest/statuses/:statusId', null,\n    {\n        'get': {\n            method: 'GET',\n            transformResponse: function(status) {\n                status = angular.fromJson(status);\n\n                status.avatarURL = status.avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + status.avatar + '/photo.jpg';\n\n                if(status.geoLocalization) {\n                    var latitude = status.geoLocalization.split(',')[0].trim();\n                    var longitude = status.geoLocalization.split(',')[1].trim();\n                    status['locationURL'] =\n                        'https://www.openstreetmap.org/?mlon='\n                        + longitude + '&mlat=' + latitude;\n                }\n\n                return status;\n             }\n        },\n        'getHomeTimeline': {\n            method: 'GET', isArray: true, url: '/tatami/rest/statuses/home_timeline',\n            transformResponse: responseTransform\n        },\n        'getUserTimeline': {\n            method: 'GET', isArray: true, params: { username: '@username' }, url: '/tatami/rest/statuses/:username/timeline',\n            transformResponse: responseTransform\n        },\n        'getDetails': {\n            method: 'GET', params: { statusId: '@statusId' }, url: '/tatami/rest/statuses/details/:statusId',\n            transformResponse: function(details) {\n                details = angular.fromJson(details);\n\n                for(var i = 0; i < details.discussionStatuses.length; i++) {\n                    details.discussionStatuses[i]['avatarURL'] = details.discussionStatuses[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + details.discussionStatuses[i].avatar + '/photo.jpg';\n\n                    if(details.discussionStatuses[i].geoLocalization) {\n                        var latitude = details.discussionStatuses[i].geoLocalization.split(',')[0].trim();\n                        var longitude = details.discussionStatuses[i].geoLocalization.split(',')[1].trim();\n                        details.discussionStatuses[i]['locationURL'] =\n                            'https://www.openstreetmap.org/?mlon='\n                            + longitude + '&mlat=' + latitude;\n                    }\n                }\n\n                for(var i = 0; i < details.sharedByLogins.length; i++) {\n                    details.sharedByLogins[i]['avatarURL'] = details.sharedByLogins[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + details.sharedByLogins[i].avatar + '/photo.jpg';\n                }\n\n                return details;\n            }\n        },\n        'update': { method: 'PATCH', params: { statusId: '@statusId' } },\n        'announce': { method: 'PATCH', params: { params: '@statusId' } }\n    });\n}]);\n"
  },
  {
    "path": "services/src/main/webapp/app/shared/services/TagService.js",
    "content": "TatamiApp.factory('TagService', ['$resource', function($resource) {\n    return $resource('/tatami/rest/tags', null,\n    {   \n        'get': { method:'GET', params: { tag: '@tag' }, url: '/tatami/rest/tags/:tag' },\n        'getTagTimeline': { \n            method:'GET', isArray: true, params: { tag: '@tag' }, url: '/tatami/rest/tags/:tag/tag_timeline',\n            transformResponse: function(statuses) {\n                statuses = angular.fromJson(statuses);\n\n                for(var i = 0; i < statuses.length; i++) {\n                    statuses[i]['avatarURL'] = statuses[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + statuses[i].avatar + '/photo.jpg';\n\n                    if(statuses[i].geoLocalization) {\n                        var latitude = statuses[i].geoLocalization.split(',')[0].trim();\n                        var longitude = statuses[i].geoLocalization.split(',')[1].trim();\n                        statuses[i]['locationURL'] = \n                            'https://www.openstreetmap.org/?mlon='\n                            + longitude + '&mlat=' + latitude;\n                    }\n                }\n\n                return statuses;\n            }\n        },\n        'follow': { method:'PUT', params: { tag: '@tag' }, url: '/tatami/rest/tags/:tag' },\n        'getPopular': { method: 'GET', isArray: true, url: '/tatami/rest/tags/popular' }\n    });\n}]);"
  },
  {
    "path": "services/src/main/webapp/app/shared/services/TopPostersService.js",
    "content": "TatamiApp.factory('TopPostersService', ['$resource', function($resource) {\n    return $resource('/tatami/rest/stats/day');\n}]);"
  },
  {
    "path": "services/src/main/webapp/app/shared/services/UserService.js",
    "content": "TatamiApp.factory('UserService', ['$resource', function($resource) {\n    var responseTransform = function(users) {\n        users = angular.fromJson(users);\n\n        for(var i = 0; i < users.length; i++) {\n            users[i]['avatarURL'] = users[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + users[i].avatar + '/photo.jpg';\n        }\n\n        return users;\n    };\n\n    return $resource('/tatami/rest/users/:username', null,\n    { \n        'get': { \n            method: 'GET', params: { username: '@username' },\n            transformResponse: function(user) {\n                user = angular.fromJson(user);\n                user['avatarURL'] = user.avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + user.avatar + '/photo.jpg';\n                return user;\n            }\n        },\n        'query': { \n            method: 'GET', isArray: true, url: '/tatami/rest/users',\n            transformResponse: responseTransform\n        },\n        'getFollowing': { \n            method: 'GET', isArray: true, params: { username: '@username' }, url: '/tatami/rest/users/:username/friends',\n            transformResponse: responseTransform\n        },\n        'getFollowers': { \n            method: 'GET', isArray: true, params: { username: '@username' }, url: '/tatami/rest/users/:username/followers',\n            transformResponse: responseTransform\n        },\n        'getSuggestions': { \n            method: 'GET', isArray: true, url: '/tatami/rest/users/suggestions', \n            transformResponse: function(suggestions) {\n                suggestions = angular.fromJson(suggestions);\n\n                for(var i = 0; i < suggestions.length; i++) {\n                    suggestions[i]['avatarURL'] = suggestions[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + suggestions[i].avatar + '/photo.jpg';\n                    suggestions[i]['followingUser'] = false;\n                }\n\n                return suggestions;\n            }\n        },\n        'follow': { method: 'PATCH', params: { username: '@username' } },\n        'searchUsers': { method: 'GET', isArray: true, url: '/tatami/rest/users/:term', transformResponse: responseTransform },\n        'deactivate': { method: 'PATCH', params: { username: '@username' } }\n    });\n}]);"
  },
  {
    "path": "services/src/main/webapp/app/shared/services/UserSession.js",
    "content": "TatamiApp.factory('UserSession', ['$q', '$window', 'ProfileService', 'localStorageService', function($q, $window, ProfileService, localStorageService) {\n    var user;\n    var authenticated = false;\n\n    return {\n        isAuthenticated: function() {\n            return localStorageService.get('token') === \"true\";\n        },\n\n        isUserResolved: function() {\n            return angular.isDefined(user);\n        },\n\n        setLoginState: function(loggedIn) {\n            localStorageService.set('token', loggedIn);\n        },\n\n        clearSession: function() {\n            localStorageService.clearAll();\n        },\n\n        getUser: function() {\n            return user;\n        },\n\n        authenticate: function(force) {\n            var deferred = $q.defer();\n\n            if(force) {\n                user = undefined;\n            }\n\n            if(this.isUserResolved() && user.action !== null) {\n                deferred.resolve(user);\n                return deferred.promise;\n            }\n\n            ProfileService.get(function(data) {\n                // Success\n                user = data;\n                authenticated = true;\n                deferred.resolve(user);\n            }, function() {\n                // Error\n                user = null;\n                authenticated = false;\n                deferred.resolve(user);\n            });\n\n            return deferred.promise;\n        }\n    }\n}]);\n"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/AbstractCassandraTatamiTest.java",
    "content": "package fr.ippon.tatami;\n\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.CounterRepository;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport fr.ippon.tatami.test.application.ApplicationTestConfiguration;\nimport fr.ippon.tatami.test.application.WebApplicationTestConfiguration;\nimport org.cassandraunit.DataLoader;\nimport org.cassandraunit.dataset.json.ClassPathJsonDataSet;\nimport org.cassandraunit.utils.EmbeddedCassandraServerHelper;\nimport org.elasticsearch.client.Client;\nimport org.elasticsearch.common.settings.ImmutableSettings;\nimport org.elasticsearch.node.Node;\nimport org.elasticsearch.node.NodeBuilder;\nimport org.junit.AfterClass;\nimport org.junit.BeforeClass;\nimport org.junit.runner.RunWith;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.test.context.ContextConfiguration;\nimport org.springframework.test.context.ContextHierarchy;\nimport org.springframework.test.context.junit4.SpringJUnit4ClassRunner;\nimport org.springframework.test.context.web.WebAppConfiguration;\n\nimport javax.inject.Inject;\n\n@RunWith(SpringJUnit4ClassRunner.class)\n@WebAppConfiguration\n@ContextHierarchy({\n        @ContextConfiguration(\n                name = \"root\",\n                classes = ApplicationTestConfiguration.class),\n        @ContextConfiguration(\n                name = \"dispatcher\",\n                classes = WebApplicationTestConfiguration.class\n        )\n})\npublic abstract class AbstractCassandraTatamiTest {\n\n    protected final Logger log = LoggerFactory.getLogger(this.getClass().getCanonicalName());\n\n    private static boolean isInitialized = false;\n\n    private static final Object lock = new Object();\n\n    protected static Client client = null;\n\n    @Inject\n    private CounterRepository counterRepository;\n\n    @BeforeClass\n    public static void beforeClass() throws Exception {\n        synchronized (lock) {\n            if (!isInitialized) {\n                EmbeddedCassandraServerHelper.startEmbeddedCassandra();\n                // create structure and load data\n                String clusterName = \"Tatami cluster\";\n                String host = \"localhost:9171\";\n                DataLoader dataLoader = new DataLoader(clusterName, host);\n                dataLoader.load(new ClassPathJsonDataSet(\"dataset/dataset.json\"));\n\n                final ImmutableSettings.Builder builder = ImmutableSettings.settingsBuilder();\n                builder.put(\"cluster.name\", clusterName);\n\n                final Node node = NodeBuilder.nodeBuilder().settings(builder.build()).local(true).node();\n                client = node.client();\n\n                isInitialized = true;\n            }\n        }\n    }\n\n    @AfterClass\n    public static void afterClass() throws Exception {\n        if (client != null) {\n            client.close();\n        }\n    }\n\n    protected User constructAUser(String login, String firstName, String lastName) {\n        User user = new User();\n        user.setLogin(login);\n        user.setPassword(\"\");\n        user.setUsername(DomainUtil.getUsernameFromLogin(login));\n        user.setDomain(DomainUtil.getDomainFromLogin(login));\n        user.setFirstName(firstName);\n        user.setLastName(lastName);\n        user.setJobTitle(\"web developer\");\n        counterRepository.createStatusCounter(user.getLogin());\n        counterRepository.createFriendsCounter(user.getLogin());\n        counterRepository.createFollowersCounter(user.getLogin());\n        return user;\n    }\n\n    protected User constructAUser(String login) {\n        return constructAUser(login, null, null);\n    }\n\n}"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/repository/MailDigestRepositoryTest.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.AbstractCassandraTatamiTest;\nimport fr.ippon.tatami.domain.DigestType;\nimport org.junit.Test;\n\nimport javax.inject.Inject;\nimport java.util.Calendar;\nimport java.util.List;\n\nimport static org.hamcrest.Matchers.notNullValue;\nimport static org.junit.Assert.assertThat;\nimport static org.junit.Assert.assertTrue;\n\n/**\n * @author Pierre Rust\n */\npublic class MailDigestRepositoryTest extends AbstractCassandraTatamiTest {\n\n    @Inject\n    public MailDigestRepository mailDigestRepository;\n\n\n    @Test\n    public void shouldGetAUserRepositoryInjected() {\n        assertThat(mailDigestRepository, notNullValue());\n    }\n\n    @Test\n    public void shouldInsertWeeklySubscription() {\n\n        log.debug(\"In shouldInsertWeeklySubscription\");\n\n        String login = \"nuuser@ippon.fr\";\n        String domain = \"ippon.fr\";\n        String day = String.valueOf(Calendar.getInstance().get(Calendar.DAY_OF_WEEK));\n\n        mailDigestRepository.subscribeToDigest(DigestType.WEEKLY_DIGEST, login, domain, day);\n\n        List<String> logins = mailDigestRepository.getLoginsRegisteredToDigest(DigestType.WEEKLY_DIGEST, domain, day, 0);\n        assertThat(logins, notNullValue());\n        assertTrue(logins.contains(login));\n\n    }\n\n    @Test\n    public void shouldInsertDailySubscription() {\n        log.debug(\"In shouldInsertDailySubscription\");\n\n        String login = \"nuuser@ippon.fr\";\n        String domain = \"ippon.fr\";\n        String day = String.valueOf(Calendar.getInstance().get(Calendar.DAY_OF_WEEK));\n\n\n        mailDigestRepository.subscribeToDigest(DigestType.DAILY_DIGEST, login, domain, day);\n\n        List<String> logins = mailDigestRepository.getLoginsRegisteredToDigest(DigestType.DAILY_DIGEST, domain, day, 0);\n        assertThat(logins, notNullValue());\n        assertTrue(logins.contains(login));\n\n    }\n\n    @Test\n    public void shouldRemoveWeeklySubscription() {\n        log.debug(\"In shouldRemoveWeeklySubscription\");\n\n        String login = \"nuuser@ippon.fr\";\n        String domain = \"ippon.fr\";\n        String day = String.valueOf(Calendar.getInstance().get(Calendar.DAY_OF_WEEK));\n\n        mailDigestRepository.unsubscribeFromDigest(DigestType.WEEKLY_DIGEST, login, domain, day);\n\n        List<String> logins = mailDigestRepository.getLoginsRegisteredToDigest(DigestType.WEEKLY_DIGEST, domain, day, 0);\n        assertThat(logins, notNullValue());\n        assertTrue(!logins.contains(login));\n\n    }\n\n    @Test\n    public void shouldRemoveDailySubscription() {\n        log.debug(\"In shouldRemoveDailySubscription\");\n\n        String login = \"nuuser@ippon.fr\";\n        String domain = \"ippon.fr\";\n        String day = String.valueOf(Calendar.getInstance().get(Calendar.DAY_OF_WEEK));\n\n        mailDigestRepository.unsubscribeFromDigest(DigestType.DAILY_DIGEST, login, domain, day);\n\n        List<String> logins = mailDigestRepository.getLoginsRegisteredToDigest(DigestType.DAILY_DIGEST, domain, day, 0);\n        assertThat(logins, notNullValue());\n        assertTrue(!logins.contains(login));\n\n    }\n}\n"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/repository/StatusReportRepositoryTest.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.AbstractCassandraTatamiTest;\nimport org.junit.Test;\n\nimport javax.inject.Inject;\nimport java.util.Collection;\n\nimport static junit.framework.TestCase.*;\n\npublic class StatusReportRepositoryTest extends AbstractCassandraTatamiTest {\n\n    @Inject\n    public StatusReportRepository statusReportRepository;\n\n    @Test\n    public void reportNewStatus() {\n\n        String reportingLogin = \"user@localhost\";\n        String reportedStatusId = \"status-id\";\n        String login = \"emily@localhost\";\n        String domain = \"localhost\";\n\n        int sizeOfReported = statusReportRepository.findReportedStatuses(domain).size();\n\n        statusReportRepository.reportStatus(domain, reportedStatusId, reportingLogin);\n        Collection<String> reportedStatuses = statusReportRepository.findReportedStatuses(domain);\n        String reporter = statusReportRepository.findUserHavingReported(domain, reportedStatusId);\n\n        //Now it should be equal to 1, since I added 1 reported status...\n        assertEquals(sizeOfReported + 1, reportedStatuses.size());\n        assertEquals(reporter, reportingLogin);\n\n        assertFalse(statusReportRepository.hasBeenReportedByUser(domain, reportedStatusId, login));\n        assertTrue(statusReportRepository.hasBeenReportedByUser(domain, reportedStatusId, reportingLogin));\n\n        sizeOfReported = statusReportRepository.findReportedStatuses(domain).size();\n        statusReportRepository.unreportStatus(domain, reportedStatusId);\n        reportedStatuses = statusReportRepository.findReportedStatuses(domain);\n        assertEquals(sizeOfReported - 1, reportedStatuses.size());\n\n    }\n\n\n\n}\n"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/repository/StatusRepositoryTest.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.AbstractCassandraTatamiTest;\nimport fr.ippon.tatami.domain.status.Status;\nimport org.junit.Test;\n\nimport javax.inject.Inject;\nimport javax.validation.ConstraintViolationException;\nimport javax.validation.ValidationException;\nimport java.util.ArrayList;\n\nimport static org.hamcrest.Matchers.notNullValue;\nimport static org.junit.Assert.assertThat;\n\npublic class StatusRepositoryTest extends AbstractCassandraTatamiTest {\n\n    @Inject\n    public StatusRepository statusRepository;\n\n    @Test\n    public void shouldGetAStatusRepositoryInjected() {\n        assertThat(statusRepository, notNullValue());\n    }\n\n    @Test\n    public void shouldCreateAStatus() {\n        String login = \"jdubois@ippon.fr\";\n        String content = \"content\";\n\n        Status created = statusRepository.createStatus(login, false, null, new ArrayList<String>(),\n                content, \"\", \"\", \"\", \"48.54654, 3.87987987\");\n        assertThat(created, notNullValue());\n    }\n\n    @Test(expected = ValidationException.class)\n    public void shouldNotCreateAStatusBecauseLoginNull() {\n        String login = null;\n        String content = \"content\";\n\n        Status status = new Status();\n        status.setContent(content);\n        status.setLogin(login);\n\n        statusRepository.createStatus(login, false, null, new ArrayList<String>(),\n                content, \"\", \"\", \"\", null);\n    }\n\n    @Test(expected = ConstraintViolationException.class)\n    public void shouldNotCreateAStatusBecauseContentNull() {\n        String login = \"jdubois@ippon.fr\";\n        String username = \"jdubois\";\n        String domain = \"ippon.fr\";\n        String content = null;\n\n        Status status = new Status();\n        status.setContent(content);\n        status.setLogin(login);\n\n        statusRepository.createStatus(login, false, null, new ArrayList<String>(),\n                content, \"\", \"\", \"\", null);\n    }\n\n    @Test(expected = ConstraintViolationException.class)\n    public void shouldNotCreateAStatusBecauseContentEmpty() {\n        String login = \"jdubois@ippon.fr\";\n        String username = \"jdubois\";\n        String domain = \"ippon.fr\";\n        String content = \"\";\n\n        Status status = new Status();\n        status.setContent(content);\n        status.setLogin(login);\n\n        statusRepository.createStatus(login, false, null, new ArrayList<String>(),\n                content, \"\", \"\", \"\", null);\n    }\n\n    @Test(expected = ConstraintViolationException.class)\n    public void shouldNotCreateAStatusBecauseContentTooLarge() {\n        String tmp = \"0123456789\";\n        String content = \"\";\n        for (int i = 0; i < 410; i++) {\n            content += tmp;\n        }\n\n        Status status = new Status();\n        status.setContent(content);\n        String login = \"jdubois@ippon.fr\";\n        String username = \"jdubois\";\n        String domain = \"ippon.fr\";\n\n        statusRepository.createStatus(login, false, null, new ArrayList<String>(),\n                content, \"\", \"\", \"\", null);\n    }\n}"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/repository/TagFollowerRepositoryTest.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.AbstractCassandraTatamiTest;\nimport org.junit.Test;\n\nimport javax.inject.Inject;\nimport java.util.Collection;\n\nimport static org.junit.Assert.assertEquals;\n\npublic class TagFollowerRepositoryTest extends AbstractCassandraTatamiTest {\n\n    @Inject\n    public TagFollowerRepository tagFollowerRepository;\n\n    @Test\n    public void addNewFollowerForTag() {\n        String domain = \"ippon.fr\";\n        String login = \"jdubois@ippon.fr\";\n        String tag = \"tag\";\n        Collection<String> followers = tagFollowerRepository.findFollowers(domain, tag);\n        assertEquals(0, followers.size());\n        tagFollowerRepository.addFollower(domain, tag, login);\n        followers = tagFollowerRepository.findFollowers(domain, tag);\n        assertEquals(1, followers.size());\n        assertEquals(login, followers.iterator().next());\n    }\n}"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/repository/UserRepositoryTest.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.AbstractCassandraTatamiTest;\nimport fr.ippon.tatami.domain.User;\nimport org.junit.Test;\n\nimport javax.inject.Inject;\nimport javax.validation.ConstraintViolationException;\nimport javax.validation.ValidationException;\n\nimport static org.hamcrest.Matchers.notNullValue;\nimport static org.junit.Assert.assertThat;\n\npublic class UserRepositoryTest extends AbstractCassandraTatamiTest {\n\n    @Inject\n    private UserRepository userRepository;\n\n    @Inject\n    private CounterRepository counterRepository;\n\n    @Test\n    public void shouldGetAUserRepositoryInjected() {\n        assertThat(userRepository, notNullValue());\n    }\n\n    @Test\n    public void shouldCreateAUser() {\n        String login = \"nuuser@ippon.fr\";\n        String firstName = \"New\";\n        String lastName = \"User\";\n        String avatar = \"newAvatar\";\n\n        User user = new User();\n        user.setLogin(login);\n        user.setFirstName(firstName);\n        user.setPassword(\"\");\n        user.setLastName(lastName);\n        user.setAvatar(avatar);\n\n        counterRepository.createStatusCounter(user.getLogin());\n        counterRepository.createFriendsCounter(user.getLogin());\n        counterRepository.createFollowersCounter(user.getLogin());\n        userRepository.createUser(user);\n\n        assertThat(userRepository.findUserByLogin(\"nuuser@ippon.fr\"), notNullValue());\n    }\n\n    @Test(expected = ValidationException.class)\n    public void shouldNotCreateAUserBecauseLoginNull() {\n        String login = null;\n        String firstName = \"New\";\n        String lastName = \"User\";\n        String avatar = \"newAvatar\";\n\n        User user = new User();\n        user.setLogin(login);\n        user.setFirstName(firstName);\n        user.setLastName(lastName);\n        user.setAvatar(avatar);\n\n        userRepository.createUser(user);\n    }\n\n    @Test(expected = ConstraintViolationException.class)\n    public void shouldNotCreateAUserBecauseLoginEmpty() {\n        String login = \"\";\n        String firstName = \"New\";\n        String lastName = \"User\";\n        String avatar = \"newAvatar\";\n\n        User user = new User();\n        user.setLogin(login);\n        user.setFirstName(firstName);\n        user.setLastName(lastName);\n        user.setAvatar(avatar);\n\n        userRepository.createUser(user);\n    }\n\n    @Test(expected = ValidationException.class)\n    public void shouldNotUpdateAUserBecauseLoginNull() {\n        String login = null;\n        String firstName = \"New\";\n        String lastName = \"User\";\n        String avatar = \"newAvatar\";\n\n        User user = new User();\n        user.setLogin(login);\n        user.setFirstName(firstName);\n        user.setLastName(lastName);\n        user.setAvatar(avatar);\n\n        userRepository.updateUser(user);\n    }\n\n    @Test(expected = ConstraintViolationException.class)\n    public void shouldNotUpdateAUserBecauseLoginEmpty() {\n        String login = \"\";\n        String firstName = \"New\";\n        String lastName = \"User\";\n        String avatar = \"newAvatar\";\n\n        User user = new User();\n        user.setLogin(login);\n        user.setFirstName(firstName);\n        user.setLastName(lastName);\n        user.setAvatar(avatar);\n\n        userRepository.updateUser(user);\n    }\n\n    @Test(expected = ConstraintViolationException.class)\n    public void shouldNotUpdateAUserBecauseEmailInvalid() {\n        String login = \"nuser_ippon.fr\";\n        String firstName = \"New\";\n        String lastName = \"User\";\n        String avatar = \"newAvatar\";\n\n        User user = new User();\n        user.setLogin(login);\n        user.setFirstName(firstName);\n        user.setLastName(lastName);\n        user.setAvatar(avatar);\n\n        userRepository.updateUser(user);\n    }\n\n    @Test(expected = ValidationException.class)\n    public void shouldNotUpdateAUserBecauseLastNameNull() {\n        String login = \"nuser_ippon.fr\";\n        String firstName = \"fs\";\n        String lastName = null;\n        String email = \"nuser_ippon.fr\";\n        String avatar = \"newAvatar\";\n\n        User user = new User();\n        user.setLogin(login);\n        user.setFirstName(firstName);\n        user.setLastName(lastName);\n        user.setAvatar(avatar);\n\n        userRepository.updateUser(user);\n    }\n\n    @Test(expected = ConstraintViolationException.class)\n    public void shouldNotUpdateAUserBecauseLastNameEmpty() {\n        String login = \"nuser_ippon.fr\";\n        String firstName = \"eee\";\n        String lastName = \"\";\n        String avatar = \"newAvatar\";\n\n        User user = new User();\n        user.setLogin(login);\n        user.setFirstName(firstName);\n        user.setLastName(lastName);\n        user.setAvatar(avatar);\n\n        userRepository.updateUser(user);\n    }\n\n    @Test(expected = ConstraintViolationException.class)\n    public void shouldNotUpdateAUserBecauseLastNameWithSeventeenCharacters() {\n        String login = \"nuser_ippon.fr\";\n        String firstName = \"eeee\";\n        String lastName = \"12345678901234567\";\n        String avatar = \"newAvatar\";\n\n        User user = new User();\n        user.setLogin(login);\n        user.setFirstName(firstName);\n        user.setLastName(lastName);\n        user.setAvatar(avatar);\n\n        userRepository.updateUser(user);\n    }\n\n    @Test(expected = ValidationException.class)\n    public void shouldNotUpdateAUserBecauseFirstNameNull() {\n        String login = \"nuser_ippon.fr\";\n        String firstName = null;\n        String lastName = \"User\";\n        String email = \"nuser_ippon.fr\";\n        String avatar = \"newAvatar\";\n\n        User user = new User();\n        user.setLogin(login);\n        user.setFirstName(firstName);\n        user.setLastName(lastName);\n        user.setAvatar(avatar);\n\n        userRepository.updateUser(user);\n    }\n\n    @Test(expected = ConstraintViolationException.class)\n    public void shouldNotUpdateAUserBecauseFirstNameEmpty() {\n        String login = \"nuser_ippon.fr\";\n        String firstName = \"\";\n        String lastName = \"User\";\n        String email = \"nuser_ippon.fr\";\n        String avatar = \"newAvatar\";\n\n        User user = new User();\n        user.setLogin(login);\n        user.setFirstName(firstName);\n        user.setLastName(lastName);\n        user.setAvatar(avatar);\n\n        userRepository.updateUser(user);\n    }\n\n    @Test(expected = ConstraintViolationException.class)\n    public void shouldNotUpdateAUserBecauseFirstNameWithSeventeenCharacters() {\n        String login = \"nuser_ippon.fr\";\n        String firstName = \"12345678901234567\";\n        String lastName = \"User\";\n        String avatar = \"newAvatar\";\n\n        User user = new User();\n        user.setLogin(login);\n        user.setFirstName(firstName);\n        user.setLastName(lastName);\n        user.setAvatar(avatar);\n\n        userRepository.updateUser(user);\n    }\n}"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/service/FriendshipServiceTest.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.AbstractCassandraTatamiTest;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport org.junit.Test;\nimport org.springframework.test.util.ReflectionTestUtils;\n\nimport javax.inject.Inject;\n\nimport static org.hamcrest.Matchers.is;\nimport static org.hamcrest.Matchers.notNullValue;\nimport static org.junit.Assert.*;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\n\npublic class FriendshipServiceTest extends AbstractCassandraTatamiTest {\n\n    @Inject\n    public UserService userService;\n\n    @Inject\n    public FriendshipService friendshipService;\n\n    @Test\n    public void shouldGetAUserServiceInjected() {\n        assertThat(userService, notNullValue());\n    }\n\n    @Test\n    public void shouldGetAFollowerServiceInjected() {\n        assertThat(friendshipService, notNullValue());\n    }\n\n    @Test\n    public void shouldFollowUser() {\n\n        mockAuthentication(\"userWhoWantToFollow@ippon.fr\");\n\n        User userWhoWillBeFollowed = new User();\n        userWhoWillBeFollowed.setLogin(\"userWhoWillBeFollowed@ippon.fr\");\n        userService.createUser(userWhoWillBeFollowed);\n        userWhoWillBeFollowed.setDailyDigestSubscription(false);\n        userWhoWillBeFollowed.setWeeklyDigestSubscription(false);\n        userService.updateUser(userWhoWillBeFollowed);\n\n        User userWhoFollow = userService.getUserByUsername(\"userWhoWantToFollow\");\n        assertThat(userWhoFollow.getFriendsCount(), is(0L));\n\n        assertTrue(friendshipService.followUser(\"userWhoWillBeFollowed\"));\n\n        /* verify */\n        userWhoFollow = userService.getUserByUsername(\"userWhoWantToFollow\");\n        assertThat(userWhoFollow.getFriendsCount(), is(1L));\n\n        User userWhoIsFollowed = userService.getUserByUsername(\"userWhoWillBeFollowed\");\n        assertThat(userWhoIsFollowed.getFollowersCount(), is(1L));\n\n        // Clean up\n        friendshipService.unfollowUser(\"userWhoWillBeFollowed\");\n    }\n\n    @Test\n    public void shouldNotFollowUserBecauseUserDoesNotExist() {\n\n        mockAuthentication(\"userWhoWantToFollow@ippon.fr\");\n\n        assertFalse(friendshipService.followUser(\"unknownUser\"));\n\n        /* verify */\n        User userWhoFollow = userService.getUserByUsername(\"userWhoWantToFollow\");\n        assertThat(userWhoFollow.getFriendsCount(), is(0L));\n    }\n\n    @Test\n    public void shouldNotFollowUserBecauseUserIsAlreadyFollowed() throws Exception {\n\n        mockAuthentication(\"userWhoFollow@ippon.fr\");\n\n        assertFalse(friendshipService.followUser(\"userWhoIsFollowed\"));\n\n        /* verify */\n        User userWhoFollow = userService.getUserByUsername(\"userWhoFollow\");\n        assertThat(userWhoFollow.getFriendsCount(), is(1L));\n        assertThat(userWhoFollow.getFollowersCount(), is(0L));\n\n        User userWhoIsFollowed = userService.getUserByUsername(\"userWhoIsFollowed\");\n        assertThat(userWhoIsFollowed.getFriendsCount(), is(0L));\n        assertThat(userWhoIsFollowed.getFollowersCount(), is(1L));\n    }\n\n    @Test\n    public void shouldNotFollowUserBecauseSameUser() throws Exception {\n\n        mockAuthentication(\"userWhoWantToFollow@ippon.fr\");\n\n        User userWhoFollow = userService.getUserByUsername(\"userWhoWantToFollow\");\n        assertThat(userWhoFollow.getFriendsCount(), is(0L));\n        assertThat(userWhoFollow.getFollowersCount(), is(0L));\n\n        assertFalse(friendshipService.followUser(\"userWhoWantToFollow\"));\n\n        /* verify */\n        userWhoFollow = userService.getUserByUsername(\"userWhoWantToFollow\");\n        assertThat(userWhoFollow.getFriendsCount(), is(0L));\n        assertThat(userWhoFollow.getFollowersCount(), is(0L));\n    }\n\n    @Test\n    public void shouldForgetUser() {\n        mockAuthentication(\"userWhoWantToForget@ippon.fr\");\n\n        User userWhoWantToForget = userService.getUserByUsername(\"userWhoWantToForget\");\n        assertThat(userWhoWantToForget.getFriendsCount(), is(1L));\n\n        User userToForget = new User();\n        userToForget.setLogin(\"userToForget@ippon.fr\");\n        userService.createUser(userToForget);\n        userToForget.setDailyDigestSubscription(false);\n        userToForget.setWeeklyDigestSubscription(false);\n        userService.updateUser(userToForget);\n\n        assertTrue(friendshipService.unfollowUser(\"userToForget\"));\n        userWhoWantToForget = userService.getUserByUsername(\"userWhoWantToForget\");\n        assertThat(userWhoWantToForget.getFriendsCount(), is(0L));\n        User userWhoIsForgotten = userService.getUserByUsername(\"userToForget\");\n        assertThat(userWhoIsForgotten.getFollowersCount(), is(0L));\n    }\n\n    @Test\n    public void shouldNotForgetUserBecauseUserDoesNotExist() {\n        mockAuthentication(\"userWhoWantToForget@ippon.fr\");\n\n        assertFalse(friendshipService.unfollowUser(\"unknownUser\"));\n\n        /* verify */\n        User userWhoWantToForget = userService.getUserByUsername(\"userWhoWantToForget\");\n        assertThat(userWhoWantToForget.getFriendsCount(), is(0L));\n    }\n\n    private void mockAuthentication(String login) {\n        User authenticateUser = constructAUser(login);\n        AuthenticationService mockAuthenticationService = mock(AuthenticationService.class);\n        when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser);\n        ReflectionTestUtils.setField(friendshipService, \"authenticationService\", mockAuthenticationService);\n        ReflectionTestUtils.setField(userService, \"authenticationService\", mockAuthenticationService);\n    }\n}"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/service/GroupServiceTest.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.AbstractCassandraTatamiTest;\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.dto.UserGroupDTO;\nimport org.junit.Test;\nimport org.springframework.test.util.ReflectionTestUtils;\n\nimport javax.inject.Inject;\nimport java.util.Collection;\n\nimport static org.junit.Assert.*;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\n\npublic class GroupServiceTest extends AbstractCassandraTatamiTest {\n\n    @Inject\n    public UserService userService;\n\n    @Inject\n    public GroupService groupService;\n\n    @Test\n    public void createAndGetGroup() {\n        mockAuthentication(\"uuser@ippon.fr\");\n        User user = userService.getUserByLogin(\"uuser@ippon.fr\");\n        String groupName = \"Group name\";\n        String groupDescription = \"Group description\";\n        boolean publicGroup = true;\n        groupService.createGroup(groupName, groupDescription, publicGroup);\n        Collection<Group> groups = groupService.getGroupsForUser(user);\n        assertEquals(1, groups.size());\n\n        String groupId = groups.iterator().next().getGroupId();\n\n        Group group = groupService.getGroupById(\"ippon.fr\", groupId);\n        assertEquals(groupName, group.getName());\n        assertEquals(groupDescription, group.getDescription());\n        assertTrue(group.isPublicGroup());\n        assertFalse(group.isArchivedGroup());\n    }\n\n    @Test\n    public void createGroup() {\n        mockAuthentication(\"jdubois@ippon.fr\");\n\n        User user = userService.getUserByLogin(\"jdubois@ippon.fr\");\n        assertEquals(0, groupService.getGroupsForUser(user).size());\n\n        String groupName = \"Group name\";\n        String groupDescription = \"Group description\";\n        boolean publicGroup = true;\n        groupService.createGroup(groupName, groupDescription, publicGroup);\n        Collection<Group> groups = groupService.getGroupsForUser(user);\n        assertEquals(1, groups.size());\n\n        Group group = groups.iterator().next();\n        assertEquals(groupName, group.getName());\n        assertEquals(groupDescription, group.getDescription());\n        assertTrue(group.isPublicGroup());\n        assertFalse(group.isArchivedGroup());\n    }\n\n    @Test\n    public void addAndRemoveGroupMember() {\n        mockAuthentication(\"userWithStatus@ippon.fr\");\n\n        User user = userService.getUserByLogin(\"userWithStatus@ippon.fr\");\n        assertEquals(0, groupService.getGroupsForUser(user).size());\n\n        String groupName = \"Group name\";\n        String groupDescription = \"Group description\";\n        boolean publicGroup = true;\n        groupService.createGroup(groupName, groupDescription, publicGroup);\n        Collection<Group> groups = groupService.getGroupsForUser(user);\n        assertEquals(1, groups.size());\n        Group group = groups.iterator().next();\n        String groupId = group.getGroupId();\n\n        User member = userService.getUserByLogin(\"userWhoPostStatus@ippon.fr\");\n\n        assertEquals(1, groupService.getGroupsForUser(user).size());\n        assertEquals(0, groupService.getGroupsForUser(member).size());\n\n        Collection<UserGroupDTO> members = groupService.getMembersForGroup(groupId, user.getLogin());\n        assertEquals(1, members.size());\n\n        groupService.addMemberToGroup(member, group);\n        members = groupService.getMembersForGroup(groupId, user.getLogin());\n        assertEquals(2, members.size());\n\n        assertEquals(1, groupService.getGroupsForUser(user).size());\n        assertEquals(1, groupService.getGroupsForUser(member).size());\n\n        groupService.removeMemberFromGroup(member, group);\n        members = groupService.getMembersForGroup(groupId, user.getLogin());\n        assertEquals(1, members.size());\n\n        assertEquals(1, groupService.getGroupsForUser(user).size());\n        assertEquals(0, groupService.getGroupsForUser(member).size());\n\n        // Clean up\n        groupService.removeMemberFromGroup(user, group);\n        assertEquals(0, groupService.getGroupsForUser(user).size());\n    }\n\n    private void mockAuthentication(String login) {\n        User authenticateUser = constructAUser(login);\n        AuthenticationService mockAuthenticationService = mock(AuthenticationService.class);\n        when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser);\n        ReflectionTestUtils.setField(groupService, \"authenticationService\", mockAuthenticationService);\n        ReflectionTestUtils.setField(userService, \"authenticationService\", mockAuthenticationService);\n    }\n}"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/service/MailDigestServiceTest.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.AbstractCassandraTatamiTest;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport org.junit.Before;\nimport org.junit.FixMethodOrder;\nimport org.junit.Test;\nimport org.junit.runners.MethodSorters;\nimport org.mockito.ArgumentCaptor;\nimport org.mockito.InjectMocks;\nimport org.mockito.Mock;\nimport org.mockito.MockitoAnnotations;\nimport org.springframework.test.util.ReflectionTestUtils;\n\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport static org.hamcrest.CoreMatchers.is;\nimport static org.junit.Assert.assertThat;\nimport static org.mockito.Matchers.any;\nimport static org.mockito.Matchers.anyCollection;\nimport static org.mockito.Matchers.anyInt;\nimport static org.mockito.Matchers.anyList;\nimport static org.mockito.Mockito.*;\n\n/**\n * @author Pierre Rust\n */\n@SuppressWarnings(\"unchecked\")\n@FixMethodOrder(MethodSorters.NAME_ASCENDING)\npublic class MailDigestServiceTest extends AbstractCassandraTatamiTest {\n\n    @Mock\n    MailService mailServiceMock;\n\n    // Note : see the mail text in the console, you need to comment out the InjectMocks annotation\n    // the test will fail but it's still useful during development if you want to work on the template\n    @Inject\n    @InjectMocks\n    public MailDigestService mailDigestService;\n\n    @Inject\n    public UserService userService;\n\n    @Inject\n    public TimelineService timelineService;\n\n    @Inject\n    public StatusUpdateService statusUpdateService;\n\n    @Inject\n    public FriendshipService friendshipService;\n\n    static final String DAILY_DIGEST_USER = \"userWhoSubscribeToDigests@ippon.fr\";\n    static final String WEEKLY_DIGEST_USER = \"userWhoSubscribeToWeeklyDigests@ippon.fr\";\n\n    @Before\n    public void initMocks() {\n        // we need to call initMocks explicitly because we use\n        // SpringJUnit4ClassRunner instead of MockitoJUnitRunner\n        // (to get spring injection before mockito mocking with @InjectMocks)\n        MockitoAnnotations.initMocks(this);\n\n        // reset users registrations : \n        mockAuthenticationOnUserService(DAILY_DIGEST_USER);\n        userService.updateDailyDigestRegistration(false);\n\n        mockAuthenticationOnUserService(WEEKLY_DIGEST_USER);\n        userService.updateWeeklyDigestRegistration(false);\n    }\n\n    @Test\n    public void order_00_shouldNotGenerateDailyDigest() {\n        log.debug(\"In shouldNotGenerateDailyDigest\");\n\n        // Test data set has no user subscribed to weekly Digest\n        // no mail should be sent.\n        mailDigestService.dailyDigest();\n        verifyZeroInteractions(mailServiceMock);\n    }\n\n    @Test\n    public void order_01_shouldNotGenerateWeeklyDigest() {\n        log.debug(\"In shouldNotGenerateWeeklyDigest\");\n\n        // Test data set has no user subscribed to weekly Digest\n        // no mail should be sent.\n        mailDigestService.dailyDigest();\n        verifyZeroInteractions(mailServiceMock);\n    }\n\n    @Test\n    public void order_03_shouldGenerateDailyDigestNoMessage() {\n        log.debug(\"In shouldGenerateDailyDigestNoMessage\");\n\n        mockAuthenticationOnUserService(DAILY_DIGEST_USER);\n        userService.updateDailyDigestRegistration(true);\n\n        ArgumentCaptor<List> statuses = ArgumentCaptor.forClass(List.class);\n\n        mailDigestService.dailyDigest();\n\n        verify(mailServiceMock).sendDailyDigestEmail(any(User.class), statuses.capture(), anyInt(),\n                anyCollection());\n        assertThat(statuses.getValue().size() == 0, is(true));\n    }\n\n\n    @Test\n    public void order_04_shouldGenerateDailyDigestOneMessage() {\n        log.debug(\"In shouldGenerateDailyDigestOneMessage\");\n\n        mockAuthenticationOnUserService(DAILY_DIGEST_USER);\n        userService.updateDailyDigestRegistration(true);\n\n        mockAuthenticationOnFriendshipService(DAILY_DIGEST_USER);\n        friendshipService.followUser(\"userWhoPostForDigests\");\n\n        mockAuthenticationOnTimelineServiceWithACurrentUser(\"userWhoPostForDigests@ippon.fr\");\n        mockAuthenticationOnStatusUpdateServiceWithACurrentUser(\"userWhoPostForDigests@ippon.fr\");\n        String content = \"voilà un message qui devrait se retrouver dans le digest ! \";\n        statusUpdateService.postStatus(content, false, new ArrayList<String>());\n\n        ArgumentCaptor<List> statuses = ArgumentCaptor.forClass(List.class);\n\n        mailDigestService.dailyDigest();\n\n        verify(mailServiceMock).sendDailyDigestEmail(any(User.class), statuses.capture(), anyInt(),\n                anyCollection());\n        assertThat(statuses.getValue().size() == 1, is(true));\n    }\n\n\n    @Test\n    public void order_04_shouldGenerateDailyDigestWithTwoMessages() {\n        log.debug(\"In shouldGenerateDailyDigestWithTwoMessages\");\n\n        mockAuthenticationOnUserService(DAILY_DIGEST_USER);\n        userService.updateDailyDigestRegistration(true);\n\n        mockAuthenticationOnFriendshipService(DAILY_DIGEST_USER);\n        friendshipService.followUser(\"userWhoPostForDigests\");\n\n        mockAuthenticationOnTimelineServiceWithACurrentUser(\"userWhoPostForDigests@ippon.fr\");\n        mockAuthenticationOnStatusUpdateServiceWithACurrentUser(\"userWhoPostForDigests@ippon.fr\");\n        String content2 = \"voilà un message 2 qui devrait se retrouver dans le digest ! \";\n        statusUpdateService.postStatus(content2, false, new ArrayList<String>());\n\n        ArgumentCaptor<List> statuses = ArgumentCaptor.forClass(List.class);\n\n        mailDigestService.dailyDigest();\n\n        verify(mailServiceMock).sendDailyDigestEmail(any(User.class), statuses.capture(), anyInt(),\n                anyCollection());\n        assertThat(statuses.getValue().size() == 2, is(true));\n    }\n\n    @Test\n    public void order_05_shouldGenerateDailyDigestWithManyMessages() {\n        log.debug(\"In shouldGenerateDailyDigestWithManyMessages\");\n\n        mockAuthenticationOnUserService(DAILY_DIGEST_USER);\n        userService.updateDailyDigestRegistration(true);\n\n        mockAuthenticationOnFriendshipService(DAILY_DIGEST_USER);\n        friendshipService.followUser(\"userWhoPostForDigests\");\n\n        mockAuthenticationOnTimelineServiceWithACurrentUser(\"userWhoPostForDigests@ippon.fr\");\n        mockAuthenticationOnStatusUpdateServiceWithACurrentUser(\"userWhoPostForDigests@ippon.fr\");\n        for (int i = 0; i < 20; i++) {\n            String content2 = \"voilà un message \" + i + \" qui devrait se retrouver dans le digest ! \";\n            statusUpdateService.postStatus(content2, false, new ArrayList<String>());\n        }\n\n        ArgumentCaptor<List> statuses = ArgumentCaptor.forClass(List.class);\n\n        mailDigestService.dailyDigest();\n\n        verify(mailServiceMock).sendDailyDigestEmail(any(User.class), statuses.capture(), anyInt(),\n                anyCollection());\n        assertThat(statuses.getValue().size() == 10, is(true));\n    }\n\n\n    @Test\n    public void order_06_shouldGenerateWeeklyDigest() {\n        log.debug(\"In shouldGenerateWeeklyDigest\");\n\n        mockAuthenticationOnUserService(WEEKLY_DIGEST_USER);\n        userService.updateWeeklyDigestRegistration(true);\n\n        mailDigestService.weeklyDigest();\n        verify(mailServiceMock).sendWeeklyDigestEmail(any(User.class), anyList(), anyInt(),\n                anyCollection(), anyCollection());\n    }\n\n\n    @Test\n    public void order_07_shouldGenerateWeeklyDigestNoMessage() {\n        log.debug(\"In shouldGenerateWeeklyDigestNoMessage\");\n\n        mockAuthenticationOnUserService(WEEKLY_DIGEST_USER);\n        userService.updateWeeklyDigestRegistration(true);\n\n        ArgumentCaptor<List> statuses = ArgumentCaptor.forClass(List.class);\n\n        mailDigestService.weeklyDigest();\n\n        verify(mailServiceMock).sendWeeklyDigestEmail(any(User.class), statuses.capture(), anyInt(),\n                anyCollection(), anyCollection());\n        assertThat(statuses.getValue().size() == 0, is(true));\n    }\n\n\n    @Test\n    public void order_08_shouldGenerateWeeklyDigestOneMessage() {\n        log.debug(\"In shouldGenerateWeeklyDigestOneMessage\");\n\n        mockAuthenticationOnUserService(WEEKLY_DIGEST_USER);\n        userService.updateWeeklyDigestRegistration(true);\n\n        mockAuthenticationOnFriendshipService(WEEKLY_DIGEST_USER);\n        friendshipService.followUser(\"userWhoPostForDigests\");\n\n        mockAuthenticationOnTimelineServiceWithACurrentUser(\"userWhoPostForDigests@ippon.fr\");\n        mockAuthenticationOnStatusUpdateServiceWithACurrentUser(\"userWhoPostForDigests@ippon.fr\");\n        String content = \"voilà un message qui devrait se retrouver dans le digest ! \";\n        statusUpdateService.postStatus(content, false, new ArrayList<String>());\n\n        ArgumentCaptor<List> statuses = ArgumentCaptor.forClass(List.class);\n\n        mailDigestService.weeklyDigest();\n\n        verify(mailServiceMock).sendWeeklyDigestEmail(any(User.class), statuses.capture(), anyInt(),\n                anyCollection(), anyCollection());\n        assertThat(statuses.getValue().size() == 1, is(true));\n    }\n\n\n    @Test\n    public void order_09_shouldGenerateWeeklyDigestWithTwoMessages() {\n        log.debug(\"In shouldGenerateWeeklyDigestWithTwoMessages\");\n\n        mockAuthenticationOnUserService(WEEKLY_DIGEST_USER);\n        userService.updateWeeklyDigestRegistration(true);\n\n        mockAuthenticationOnFriendshipService(WEEKLY_DIGEST_USER);\n        friendshipService.followUser(\"userWhoPostForDigests\");\n\n        mockAuthenticationOnTimelineServiceWithACurrentUser(\"userWhoPostForDigests@ippon.fr\");\n        mockAuthenticationOnStatusUpdateServiceWithACurrentUser(\"userWhoPostForDigests@ippon.fr\");\n        String content2 = \"voilà un message 2 qui devrait se retrouver dans le digest ! \";\n        statusUpdateService.postStatus(content2, false, new ArrayList<String>());\n\n        ArgumentCaptor<List> statuses = ArgumentCaptor.forClass(List.class);\n\n        mailDigestService.weeklyDigest();\n\n        verify(mailServiceMock).sendWeeklyDigestEmail(any(User.class), statuses.capture(), anyInt(),\n                anyCollection(), anyCollection());\n        assertThat(statuses.getValue().size() == 2, is(true));\n    }\n\n    @Test\n    public void order_10_shouldGenerateWeeklyDigestWithManyMessages() {\n        log.debug(\"In shouldGenerateWeeklyDigestWithManyMessages\");\n\n        mockAuthenticationOnUserService(WEEKLY_DIGEST_USER);\n        userService.updateWeeklyDigestRegistration(true);\n\n        mockAuthenticationOnFriendshipService(WEEKLY_DIGEST_USER);\n        friendshipService.followUser(\"userWhoPostForDigests\");\n\n        mockAuthenticationOnTimelineServiceWithACurrentUser(\"userWhoPostForDigests@ippon.fr\");\n        mockAuthenticationOnStatusUpdateServiceWithACurrentUser(\"userWhoPostForDigests@ippon.fr\");\n        for (int i = 0; i < 20; i++) {\n            String content2 = \"voilà un message \" + i + \" qui devrait se retrouver dans le digest ! \";\n            statusUpdateService.postStatus(content2, false, new ArrayList<String>());\n        }\n\n        ArgumentCaptor<List> statuses = ArgumentCaptor.forClass(List.class);\n\n        mailDigestService.weeklyDigest();\n\n        verify(mailServiceMock).sendWeeklyDigestEmail(any(User.class), statuses.capture(), anyInt(),\n                anyCollection(), anyCollection());\n        assertThat(statuses.getValue().size() == 10, is(true));\n    }\n\n    private void mockAuthenticationOnUserService(String login) {\n        User authenticateUser = constructAUser(login);\n        AuthenticationService mockAuthenticationService = mock(AuthenticationService.class);\n        when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser);\n        ReflectionTestUtils.setField(userService, \"authenticationService\", mockAuthenticationService);\n    }\n\n    private void mockAuthenticationOnFriendshipService(String login) {\n        User authenticateUser = constructAUser(login);\n        AuthenticationService mockAuthenticationService = mock(AuthenticationService.class);\n        when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser);\n        ReflectionTestUtils.setField(friendshipService, \"authenticationService\", mockAuthenticationService);\n        ReflectionTestUtils.setField(userService, \"authenticationService\", mockAuthenticationService);\n    }\n\n    private void mockAuthenticationOnTimelineServiceWithACurrentUser(String login) {\n        User authenticateUser = constructAUser(login);\n        AuthenticationService mockAuthenticationService = mock(AuthenticationService.class);\n        when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser);\n        ReflectionTestUtils.setField(timelineService, \"authenticationService\", mockAuthenticationService);\n    }\n\n    private void mockAuthenticationOnStatusUpdateServiceWithACurrentUser(String login) {\n        User authenticateUser = constructAUser(login);\n        AuthenticationService mockAuthenticationService = mock(AuthenticationService.class);\n        when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser);\n        ReflectionTestUtils.setField(statusUpdateService, \"authenticationService\", mockAuthenticationService);\n    }\n}\n"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/service/StatsServiceTest.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.AbstractCassandraTatamiTest;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.domain.UserStatusStat;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport org.junit.Test;\nimport org.springframework.test.util.ReflectionTestUtils;\n\nimport javax.inject.Inject;\nimport java.util.Calendar;\nimport java.util.Collection;\n\nimport static org.hamcrest.Matchers.is;\nimport static org.hamcrest.Matchers.notNullValue;\nimport static org.junit.Assert.assertThat;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\n\npublic class StatsServiceTest extends AbstractCassandraTatamiTest {\n\n    @Inject\n    public StatsService statsService;\n\n    @Test\n    public void shouldGetDayline() throws Exception {\n        mockAuthenticationOnStatsServiceWithACurrentUser(\"userWithStatus@ippon.fr\");\n        Calendar cal = Calendar.getInstance();\n        cal.set(2012, 04, 19);\n        Collection<UserStatusStat> stats = statsService.getDayline(cal.getTime());\n        assertThat(stats, notNullValue());\n        assertThat(stats.size(), is(1));\n\n        UserStatusStat userStat = (UserStatusStat) stats.toArray()[0];\n        assertThat(userStat.getUsername(), is(\"userWithStatus\"));\n        assertThat(userStat.getStatusCount(), is(1L));\n    }\n\n    private void mockAuthenticationOnStatsServiceWithACurrentUser(String login) {\n        User authenticateUser = constructAUser(login);\n        AuthenticationService mockAuthenticationService = mock(AuthenticationService.class);\n        when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser);\n        ReflectionTestUtils.setField(statsService, \"authenticationService\", mockAuthenticationService);\n    }\n}\n"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/service/StatusDeletionTest.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.AbstractCassandraTatamiTest;\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.dto.StatusDTO;\nimport org.junit.Test;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.test.util.ReflectionTestUtils;\n\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Iterator;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\n\npublic class StatusDeletionTest extends AbstractCassandraTatamiTest {\n\n    private static final Logger log = LoggerFactory.getLogger(StatusDeletionTest.class);\n\n    @Inject\n    public TimelineService timelineService;\n\n    @Inject\n    public StatusUpdateService statusUpdateService;\n\n    @Inject\n    public GroupService groupService;\n\n    @Inject\n    public UserService userService;\n\n    @Test\n    public void deleteOneStatus() throws Exception {\n        String login = \"userWithStatus@ippon.fr\";\n        String username = \"userWithStatus\";\n        mockAuthenticationOnTimelineServiceWithACurrentUser(login);\n        Collection<StatusDTO> timelineStatuses = timelineService.getTimeline(10, null, null);\n        assertEquals(2, timelineStatuses.size());\n        Collection<StatusDTO> userlineStatuses = timelineService.getUserline(username, 10, null, null);\n        assertEquals(2, userlineStatuses.size());\n\n        String content = \"temporary status\";\n        statusUpdateService.postStatus(content, false, new ArrayList<String>(), null);\n\n        timelineStatuses = timelineService.getTimeline(10, null, null);\n        assertEquals(3, timelineStatuses.size());\n        StatusDTO temporaryStatus = timelineStatuses.iterator().next();\n        assertEquals(\"temporary status\", temporaryStatus.getContent());\n        userlineStatuses = timelineService.getUserline(username, 10, null, null);\n        assertEquals(3, userlineStatuses.size());\n\n        timelineService.removeStatus(temporaryStatus.getStatusId());\n        timelineStatuses = timelineService.getTimeline(10, null, null);\n        assertEquals(2, timelineStatuses.size());\n        userlineStatuses = timelineService.getUserline(username, 10, null, null);\n        assertEquals(2, userlineStatuses.size());\n    }\n\n    @Test\n    public void deleteManyStatuses() throws Exception {\n        String login = \"userWithStatus@ippon.fr\";\n        String username = \"userWithStatus\";\n        mockAuthenticationOnTimelineServiceWithACurrentUser(login);\n        Collection<StatusDTO> timelineStatuses = timelineService.getTimeline(10, null, null);\n        assertEquals(2, timelineStatuses.size());\n        Collection<StatusDTO> userlineStatuses = timelineService.getUserline(username, 10, null, null);\n        assertEquals(2, userlineStatuses.size());\n\n        for (int i = 0; i < 10; i++) {\n            String content = \"temporary status \" + i;\n            statusUpdateService.postStatus(content, false, new ArrayList<String>(),null);\n        }\n\n        timelineStatuses = timelineService.getTimeline(10, null, null);\n        assertEquals(10, timelineStatuses.size());\n        userlineStatuses = timelineService.getUserline(username, 10, null, null);\n        assertEquals(10, userlineStatuses.size());\n        Iterator<StatusDTO> iterator = timelineStatuses.iterator();\n        for (int i = 9; i >= 0; i--) {\n            StatusDTO temporaryStatus = iterator.next();\n            assertEquals(\"temporary status \" + i, temporaryStatus.getContent());\n            timelineService.removeStatus(temporaryStatus.getStatusId());\n        }\n\n        timelineStatuses = timelineService.getTimeline(10, null, null);\n        assertEquals(2, timelineStatuses.size());\n        userlineStatuses = timelineService.getUserline(username, 10, null, null);\n        assertEquals(2, userlineStatuses.size());\n    }\n\n    @Test\n    public void deleteManyStatusesWithTag() throws Exception {\n        String login = \"userWithStatus@ippon.fr\";\n        mockAuthenticationOnTimelineServiceWithACurrentUser(login);\n        Collection<StatusDTO> tagStatuses = timelineService.getTagline(\"ippon\", 10, null, null);\n        assertEquals(2, tagStatuses.size());\n\n        for (int i = 0; i < 10; i++) {\n            String content = \"temporary status \" + i +  \" #ippon\";\n            statusUpdateService.postStatus(content, false, new ArrayList<String>(),null);\n        }\n\n        tagStatuses = timelineService.getTagline(\"ippon\", 10, null, null);\n        assertEquals(10, tagStatuses.size());\n        Iterator<StatusDTO> iterator = tagStatuses.iterator();\n        for (int i = 9; i >= 0; i--) {\n            StatusDTO temporaryStatus = iterator.next();\n            assertEquals(\"temporary status \" + i + \" #ippon\", temporaryStatus.getContent());\n            timelineService.removeStatus(temporaryStatus.getStatusId());\n        }\n\n        tagStatuses = timelineService.getTagline(\"ippon\", 10, null, null);\n        assertEquals(2, tagStatuses.size());\n    }\n\n    @Test\n    public void deleteManyStatusesInAGroup() throws Exception {\n        String login = \"uuser@ippon.fr\";\n        mockAuthenticationOnTimelineServiceWithACurrentUser(login);\n        User user = userService.getUserByLogin(login);\n        int userGroupSize = groupService.getGroupsForUser(user).size();\n\n        String groupName = \"Group with messages to delete\";\n        String groupDescription = \"Group description\";\n        boolean publicGroup = true;\n        groupService.createGroup(groupName, groupDescription, publicGroup);\n        Collection<Group> groups = groupService.getGroupsForUser(user);\n        assertEquals(userGroupSize + 1, groups.size());\n\n        Group group = groups.iterator().next();\n\n        Collection<StatusDTO> groupStatuses = timelineService.getGroupline(group.getGroupId(), 10, null, null);\n        assertEquals(0, groupStatuses.size());\n\n        for (int i = 0; i < 12; i++) {\n            String content = \"temporary status \" + i;\n            statusUpdateService.postStatusToGroup(content, group, new ArrayList<String>(), \"1,2\");\n        }\n\n        groupStatuses = timelineService.getGroupline(group.getGroupId(), 10, null, null);\n        assertEquals(10, groupStatuses.size());\n        Iterator<StatusDTO> iterator = groupStatuses.iterator();\n        for (int i = 11; i >= 2; i--) {\n            StatusDTO temporaryStatus = iterator.next();\n            assertEquals(\"temporary status \" + i, temporaryStatus.getContent());\n            timelineService.removeStatus(temporaryStatus.getStatusId());\n        }\n\n        groupStatuses = timelineService.getGroupline(group.getGroupId(), 10, null, null);\n        assertEquals(2, groupStatuses.size());\n\n        // Clean up\n        groupService.removeMemberFromGroup(user, group);\n        assertEquals(userGroupSize, groupService.getGroupsForUser(user).size());\n    }\n\n    @Test\n    public void deleteFavoriteStatuses() throws Exception {\n        String login = \"userWithStatus@ippon.fr\";\n        mockAuthenticationOnTimelineServiceWithACurrentUser(login);\n        Collection<StatusDTO> timelineStatuses = timelineService.getTimeline(10, null, null);\n        assertEquals(2, timelineStatuses.size());\n        Collection<StatusDTO> favoriteStatuses = timelineService.getFavoritesline();\n        assertEquals(0, favoriteStatuses.size());\n\n        for (int i = 0; i < 10; i++) {\n            String content = \"temporary status \" + i +  \" #ippon\";\n            statusUpdateService.postStatus(content, false, new ArrayList<String>(),null);\n        }\n\n        timelineStatuses = timelineService.getTimeline(10, null, null);\n        assertEquals(10, timelineStatuses.size());\n        favoriteStatuses = timelineService.getFavoritesline();\n        assertEquals(0, favoriteStatuses.size());\n\n        Iterator<StatusDTO> iterator = timelineStatuses.iterator();\n        for (int i = 9; i >= 0; i--) {\n            StatusDTO temporaryStatus = iterator.next();\n            timelineService.addFavoriteStatus(temporaryStatus.getStatusId());\n        }\n        favoriteStatuses = timelineService.getFavoritesline();\n        assertEquals(10, favoriteStatuses.size());\n\n        iterator = timelineStatuses.iterator();\n        for (int i = 9; i >= 0; i--) {\n            StatusDTO temporaryStatus = iterator.next();\n            assertEquals(\"temporary status \" + i + \" #ippon\", temporaryStatus.getContent());\n            timelineService.removeStatus(temporaryStatus.getStatusId());\n        }\n\n        timelineStatuses = timelineService.getTimeline(10, null, null);\n        assertEquals(2, timelineStatuses.size());\n        favoriteStatuses = timelineService.getFavoritesline();\n        assertEquals(0, favoriteStatuses.size());\n    }\n\n    @Test\n    public void deleteMentionnedStatuses() throws Exception {\n        String userWhoMentions = \"userWithStatus@ippon.fr\";\n        mockAuthenticationOnTimelineServiceWithACurrentUser(userWhoMentions);\n        Collection<StatusDTO> timelineStatuses = timelineService.getTimeline(10, null, null);\n        assertEquals(2, timelineStatuses.size());\n\n        String userWhoIsMentionned = \"uuser@ippon.fr\";\n        mockAuthenticationOnTimelineServiceWithACurrentUser(userWhoIsMentionned);\n        Collection<StatusDTO> mentionStatuses = timelineService.getMentionline(10, null, null);\n        assertEquals(0, mentionStatuses.size());\n\n        mockAuthenticationOnTimelineServiceWithACurrentUser(userWhoMentions);\n        for (int i = 0; i < 10; i++) {\n            String content = \"Hello @uuser \" + i;\n            statusUpdateService.postStatus(content, false, new ArrayList<String>(),null);\n        }\n\n        timelineStatuses = timelineService.getTimeline(10, null, null);\n        assertEquals(10, timelineStatuses.size());\n\n        mockAuthenticationOnTimelineServiceWithACurrentUser(userWhoIsMentionned);\n        mentionStatuses = timelineService.getMentionline(10, null, null);\n        assertEquals(10, mentionStatuses.size());\n\n        mockAuthenticationOnTimelineServiceWithACurrentUser(userWhoMentions);\n        Iterator<StatusDTO> iterator = timelineStatuses.iterator();\n        for (int i = 9; i >= 0; i--) {\n            StatusDTO temporaryStatus = iterator.next();\n            assertEquals(\"Hello @uuser \" + i, temporaryStatus.getContent());\n            timelineService.removeStatus(temporaryStatus.getStatusId());\n        }\n\n        timelineStatuses = timelineService.getTimeline(10, null, null);\n        assertEquals(2, timelineStatuses.size());\n\n        mockAuthenticationOnTimelineServiceWithACurrentUser(userWhoIsMentionned);\n        mentionStatuses = timelineService.getMentionline(10, null, null);\n        assertEquals(0, mentionStatuses.size());\n    }\n\n    private void mockAuthenticationOnTimelineServiceWithACurrentUser(String login) {\n        User authenticateUser = constructAUser(login);\n        AuthenticationService mockAuthenticationService = mock(AuthenticationService.class);\n        when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser);\n        ReflectionTestUtils.setField(timelineService, \"authenticationService\", mockAuthenticationService);\n        ReflectionTestUtils.setField(statusUpdateService, \"authenticationService\", mockAuthenticationService);\n        ReflectionTestUtils.setField(groupService, \"authenticationService\", mockAuthenticationService);\n        ReflectionTestUtils.setField(userService, \"authenticationService\", mockAuthenticationService);\n    }\n\n}"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/service/StatusUpdateServiceTest.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.AbstractCassandraTatamiTest;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.domain.status.Status;\nimport fr.ippon.tatami.repository.MentionlineRepository;\nimport fr.ippon.tatami.repository.StatusRepository;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.dto.StatusDTO;\nimport org.junit.Test;\nimport org.springframework.test.util.ReflectionTestUtils;\n\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\n\nimport static org.hamcrest.Matchers.is;\nimport static org.hamcrest.Matchers.notNullValue;\nimport static org.junit.Assert.assertThat;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\n\npublic class StatusUpdateServiceTest extends AbstractCassandraTatamiTest {\n\n    @Inject\n    public TimelineService timelineService;\n\n    @Inject\n    public StatusUpdateService statusUpdateService;\n\n    @Inject\n    public MentionlineRepository mentionlineRepository;\n\n    @Inject\n    public StatusRepository statusRepository;\n\n    @Test\n    public void shouldPostStatus() throws Exception {\n        String username = \"userWhoPostStatus\";\n        mockAuthenticationOnTimelineServiceWithACurrentUser(\"userWhoPostStatus@ippon.fr\");\n        mockAuthenticationOnStatusUpdateServiceWithACurrentUser(\"userWhoPostStatus@ippon.fr\");\n        String content = \"Longue vie au Ch'ti Jug\";\n\n        statusUpdateService.postStatus(content, false, new ArrayList<String>(), null);\n\n        /* verify */\n        Collection<StatusDTO> statusFromUserline = timelineService.getUserline(\"userWhoPostStatus\", 10, null, null);\n        assertThatNewTestIsPosted(username, content, statusFromUserline);\n\n        Collection<StatusDTO> statusFromTimeline = timelineService.getTimeline(10, null, null);\n        assertThatNewTestIsPosted(username, content, statusFromTimeline);\n\n        Collection<StatusDTO> statusFromUserlineOfAFollower = timelineService.getUserline(\"userWhoReadStatus\", 10, null, null);\n        assertThat(statusFromUserlineOfAFollower.isEmpty(), is(true));\n\n    }\n\n    @Test\n    public void shouldMentionUser() throws Exception {\n        mockAuthenticationOnTimelineServiceWithACurrentUser(\"other@ippon.fr\");\n        mockAuthenticationOnStatusUpdateServiceWithACurrentUser(\"other@ippon.fr\");\n        String content = \"Hello @jane! @john ! world\";\n\n        statusUpdateService.postStatus(content, false, new ArrayList<String>(), null);\n\n        List<String> janeMentions = mentionlineRepository.getMentionline(\"jane@ippon.fr\", 10, null, null);\n        assertThat(janeMentions.size(), is(1));\n\n        Status status = (Status) statusRepository.findStatusById(janeMentions.get(0));\n        assertThat(status.getContent(), is(content));\n\n        List<String> johnMentions = mentionlineRepository.getMentionline(\"john@ippon.fr\", 10, null, null);\n        assertThat(johnMentions.size(), is(1));\n    }\n\n    private void assertThatNewTestIsPosted(String username, String content, Collection<StatusDTO> statuses) {\n        assertThat(statuses, notNullValue());\n        assertThat(statuses.size(), is(1));\n        StatusDTO status = (StatusDTO) statuses.toArray()[0];\n        assertThat(status.getUsername(), is(username));\n        assertThat(status.getContent(), is(content));\n    }\n\n    private void mockAuthenticationOnTimelineServiceWithACurrentUser(String login) {\n        User authenticateUser = constructAUser(login);\n        AuthenticationService mockAuthenticationService = mock(AuthenticationService.class);\n        when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser);\n        ReflectionTestUtils.setField(timelineService, \"authenticationService\", mockAuthenticationService);\n    }\n\n    private void mockAuthenticationOnStatusUpdateServiceWithACurrentUser(String login) {\n        User authenticateUser = constructAUser(login);\n        AuthenticationService mockAuthenticationService = mock(AuthenticationService.class);\n        when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser);\n        ReflectionTestUtils.setField(statusUpdateService, \"authenticationService\", mockAuthenticationService);\n    }\n}"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/service/TagMembershipServiceTest.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.AbstractCassandraTatamiTest;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.web.rest.dto.Tag;\nimport org.junit.Test;\nimport org.springframework.test.util.ReflectionTestUtils;\n\nimport javax.inject.Inject;\n\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertTrue;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\n\npublic class TagMembershipServiceTest extends AbstractCassandraTatamiTest {\n\n    @Inject\n    public UserService userService;\n\n    @Inject\n    public TagMembershipService tagMembershipService;\n\n    @Test\n    public void shouldFollowTag() {\n        mockAuthentication(\"uuser@ippon.fr\");\n\n        Tag tag = new Tag();\n        tag.setName(\"test\");\n        assertTrue(tagMembershipService.followTag(tag));\n        assertTrue(tagMembershipService.unfollowTag(tag));\n    }\n\n    @Test\n    public void shouldNotFollowTagTwice() {\n        mockAuthentication(\"uuser@ippon.fr\");\n\n        Tag tag = new Tag();\n        tag.setName(\"test\");\n        assertTrue(tagMembershipService.followTag(tag));\n        assertFalse(tagMembershipService.followTag(tag));\n        assertTrue(tagMembershipService.unfollowTag(tag));\n    }\n\n    @Test\n    public void shouldNotUnfollowUnknownTag() {\n        mockAuthentication(\"uuser@ippon.fr\");\n\n        Tag tag = new Tag();\n        tag.setName(\"test\");\n        assertFalse(tagMembershipService.unfollowTag(tag));\n    }\n\n    private void mockAuthentication(String login) {\n        User authenticateUser = constructAUser(login);\n        AuthenticationService mockAuthenticationService = mock(AuthenticationService.class);\n        when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser);\n        ReflectionTestUtils.setField(tagMembershipService, \"authenticationService\", mockAuthenticationService);\n        ReflectionTestUtils.setField(userService, \"authenticationService\", mockAuthenticationService);\n    }\n}"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/service/TimelineServiceTest.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.AbstractCassandraTatamiTest;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.dto.StatusDTO;\nimport org.junit.Test;\nimport org.springframework.test.util.ReflectionTestUtils;\n\nimport javax.inject.Inject;\nimport java.util.Collection;\n\nimport static org.hamcrest.Matchers.is;\nimport static org.hamcrest.Matchers.notNullValue;\nimport static org.junit.Assert.assertThat;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\n\npublic class TimelineServiceTest extends AbstractCassandraTatamiTest {\n\n    @Inject\n    public TimelineService timelineService;\n\n    @Test\n    public void shouldGetUserline() throws Exception {\n        String username = \"userWithStatus\";\n        String login = \"userWithStatus@ippon.fr\";\n        mockAuthenticationOnTimelineServiceWithACurrentUser(login);\n        Collection<StatusDTO> status = timelineService.getUserline(username, 10, null, null);\n        assertThatLineForUserWithStatusIsOk(username, status);\n    }\n\n    @Test\n    public void shouldGetAuthenticateUserUserlineWithNullLoginSet() throws Exception {\n        String login = \"userWithStatus@ippon.fr\";\n        mockAuthenticationOnTimelineServiceWithACurrentUser(\"userWithStatus@ippon.fr\");\n        Collection<StatusDTO> status = timelineService.getUserline(null, 10, null, null);\n        assertThatLineForUserWithStatusIsOk(\"userWithStatus\", status);\n    }\n\n    @Test\n    public void shouldGetAuthenticateUserUserlineWithEmptyLoginSet() throws Exception {\n        String username = \"userWithStatus\";\n        mockAuthenticationOnTimelineServiceWithACurrentUser(\"userWithStatus@ippon.fr\");\n        Collection<StatusDTO> status = timelineService.getUserline(\"\", 10, null, null);\n        assertThatLineForUserWithStatusIsOk(username, status);\n    }\n\n    @Test\n    public void shouldGetTimeline() throws Exception {\n        String login = \"userWithStatus@ippon.fr\";\n        String username = \"userWithStatus\";\n        mockAuthenticationOnTimelineServiceWithACurrentUser(login);\n        Collection<StatusDTO> status = timelineService.getTimeline(10, null, null);\n        assertThatLineForUserWithStatusIsOk(username, status);\n    }\n\n    @Test\n    public void shouldGetTagline() throws Exception {\n        String login = \"userWithStatus@ippon.fr\";\n        String username = \"userWithStatus\";\n        mockAuthenticationOnTimelineServiceWithACurrentUser(login);\n        String hashtag = \"ippon\";\n        Collection<StatusDTO> status = timelineService.getTagline(hashtag, 10, null, null);\n        assertThatLineForUserWithStatusIsOk(username, status);\n    }\n\n    private void mockAuthenticationOnTimelineServiceWithACurrentUser(String login) {\n        User authenticateUser = constructAUser(login);\n        AuthenticationService mockAuthenticationService = mock(AuthenticationService.class);\n        when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser);\n        ReflectionTestUtils.setField(timelineService, \"authenticationService\", mockAuthenticationService);\n    }\n\n    private void assertThatLineForUserWithStatusIsOk(String username, Collection<StatusDTO> status) {\n        assertThat(status, notNullValue());\n        assertThat(status.size(), is(2));\n\n        StatusDTO firstStatus = (StatusDTO) status.toArray()[0];\n        assertThat(firstStatus.getStatusId(), is(\"fa2bd770-9848-11e1-a6ca-e0f847068d52\"));\n        assertThat(firstStatus.getUsername(), is(username));\n        assertThat(firstStatus.getContent(), is(\"Tatami is an enterprise social network\"));\n\n        StatusDTO secondStatus = (StatusDTO) status.toArray()[1];\n        assertThat(secondStatus.getStatusId(), is(\"f97d6470-9847-11e1-a6ca-e0f847068d52\"));\n        assertThat(secondStatus.getUsername(), is(username));\n        assertThat(secondStatus.getContent(), is(\"Tatami is fully Open Source\"));\n\n    }\n}"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/service/TrendServiceTest.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.AbstractCassandraTatamiTest;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.web.rest.dto.Trend;\nimport org.junit.Test;\nimport org.springframework.test.util.ReflectionTestUtils;\n\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Collection;\n\nimport static org.junit.Assert.*;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\n\npublic class TrendServiceTest extends AbstractCassandraTatamiTest {\n\n    @Inject\n    public StatusUpdateService statusUpdateService;\n\n    @Inject\n    public TrendService trendService;\n\n    @Test\n    public void testSearchTags() {\n        mockAuthentication(\"currentuser@domain.com\");\n        String domain = \"domain.com\";\n        Collection<String> tags = trendService.searchTags(domain, \"Te\", 1);\n        assertEquals(0, tags.size());\n        tags = trendService.searchTags(domain, \"Test\", 1);\n        assertEquals(0, tags.size());\n        statusUpdateService.postStatus(\"Message #Test\", false, new ArrayList<String>(), null);\n        tags = trendService.searchTags(domain, \"Te\", 1);\n        assertEquals(1, tags.size());\n        tags = trendService.searchTags(domain, \"Test\", 1);\n        assertEquals(1, tags.size());\n    }\n\n    @Test\n    public void testCurrentTrends() {\n        mockAuthentication(\"currentuser@domain.com\");\n        String domain = \"domain.com\";\n        Collection<Trend> trends = trendService.getCurrentTrends(domain);\n        for (Trend trend : trends) {\n            if (trend.getTag().equals(\"TheTrend\")) {\n                fail(\"#TheTrend shoud not be trending yet\");\n            }\n        }\n        for (int i = 0; i < 5; i++) {\n            statusUpdateService.postStatus(\"Trending message \" + i + \" #Trending\", false, new ArrayList<String>(), null);\n        }\n        trends = trendService.getCurrentTrends(domain);\n        boolean foundTrend = false;\n        for (Trend trend : trends) {\n            if (trend.getTag().equals(\"Trending\")) {\n                foundTrend = true;\n                assertTrue(trend.isTrendingUp());\n            }\n        }\n        if (!foundTrend) {\n            fail(\"#Trending should have been trending\");\n        }\n        for (int i = 0; i < 7; i++) {\n            statusUpdateService.postStatus(\"New trending message \" + i + \" #NewTrend\", false, new ArrayList<String>(), null);\n        }\n        trends = trendService.getCurrentTrends(domain);\n        foundTrend = false;\n        boolean foundNewTrend = false;\n        for (Trend trend : trends) {\n            if (trend.getTag().equals(\"Trending\")) {\n                foundTrend = true;\n                assertFalse(trend.isTrendingUp());\n            } else if (trend.getTag().equals(\"NewTrend\")) {\n                foundNewTrend = true;\n                assertTrue(trend.isTrendingUp());\n            }\n        }\n        if (!foundTrend) {\n            fail(\"#Trending should have been trending\");\n        }\n        if (!foundNewTrend) {\n            fail(\"#NewTrend should have been trending\");\n        }\n    }\n\n    @Test\n    public void testUserTrends() {\n        String login = \"currentuser@domain.com\";\n        mockAuthentication(login);\n        Collection<Trend> trends = trendService.getTrendsForUser(login);\n        for (Trend trend : trends) {\n            if (trend.getTag().equals(\"MyTrend\")) {\n                fail(\"#MyTrend shoud not be trending yet\");\n            }\n        }\n        for (int i = 0; i < 5; i++) {\n            statusUpdateService.postStatus(\"User trending message \" + i + \" #MyTrend\", false, new ArrayList<String>(), null);\n        }\n        trends = trendService.getTrendsForUser(login);\n        boolean foundTrend = false;\n        for (Trend trend : trends) {\n            if (trend.getTag().equals(\"MyTrend\")) {\n                foundTrend = true;\n                assertTrue(trend.isTrendingUp());\n            }\n        }\n        if (!foundTrend) {\n            fail(\"#MyTrend should have been trending\");\n        }\n    }\n\n    @Test\n    public void testPrivateMessagesNotInTrends() {\n        String login = \"currentuser@domain.com\";\n        mockAuthentication(login);\n\n        for (int i = 0; i < 5; i++) {\n            statusUpdateService.postStatus(\"@anotheruser private message \" + i + \" #NoTrend\", true, new ArrayList<String>(), null);\n        }\n\n        Collection<Trend> trends = trendService.getCurrentTrends(\"domain.com\");\n        boolean foundTrend = false;\n        for (Trend trend : trends) {\n            if (trend.getTag().equals(\"NoTrend\")) {\n                foundTrend = true;\n            }\n        }\n        if (foundTrend) {\n            fail(\"#NoTrend should not have been trending\");\n        }\n\n        trendService.getTrendsForUser(login);\n        foundTrend = false;\n        for (Trend trend : trends) {\n            if (trend.getTag().equals(\"NoTrend\")) {\n                foundTrend = true;\n            }\n        }\n        if (foundTrend) {\n            fail(\"#NoTrend should not have been trending\");\n        }\n    }\n\n    private void mockAuthentication(String login) {\n        User authenticateUser = constructAUser(login);\n        AuthenticationService mockAuthenticationService = mock(AuthenticationService.class);\n        when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser);\n        ReflectionTestUtils.setField(statusUpdateService, \"authenticationService\", mockAuthenticationService);\n    }\n}"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/service/UserServiceTest.java",
    "content": "package fr.ippon.tatami.service;\n\nimport fr.ippon.tatami.AbstractCassandraTatamiTest;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.dto.UserDTO;\nimport org.junit.Test;\nimport org.springframework.test.util.ReflectionTestUtils;\n\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Collection;\n\nimport static org.hamcrest.Matchers.*;\nimport static org.junit.Assert.*;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\n\npublic class UserServiceTest extends AbstractCassandraTatamiTest {\n\n    @Inject\n    public UserService userService;\n\n    @Test\n    public void shouldGetAUserServiceInjected() {\n        assertThat(userService, notNullValue());\n    }\n\n    @Test\n    public void shouldGetAUserByLogin() {\n        User user = userService.getUserByLogin(\"jdubois@ippon.fr\");\n        assertThat(user, notNullValue());\n        assertThat(user.getAvatar(), is(\"avatar\"));\n        assertThat(user.getFirstName(), is(\"Julien\"));\n        assertThat(user.getLastName(), is(\"Dubois\"));\n    }\n\n    @Test\n    public void shouldNotGetAUserByLogin() {\n        User user = userService.getUserByLogin(\"unknownUserLogin\");\n        assertThat(user, nullValue());\n    }\n\n    @Test\n    public void shouldGetAUserProfileByLogin() {\n        mockAuthenticationOnUserService(\"jdubois@ippon.fr\");\n        User user = userService.getUserByUsername(\"jdubois\");\n        assertThat(user.getStatusCount(), is(2L));\n        assertThat(user.getFollowersCount(), is(3L));\n        assertThat(user.getFriendsCount(), is(4L));\n    }\n\n    @Test\n    public void shouldNotGetAUserProfileByLogin() {\n        User user = userService.getUserByUsername(\"unknownUserLogin\");\n        assertThat(user, nullValue());\n    }\n\n    @Test\n    public void shouldUpdateUser() {\n        String login = \"uuser@ippon.fr\";\n        String firstName = \"UpdatedFirstName\";\n        String lastName = \"UpdatedLastName\";\n        User userToUpdate = constructAUser(login, firstName, lastName);\n\n        mockAuthenticationOnUserService(login);\n\n        userService.updateUser(userToUpdate);\n\n        User updatedUser = userService.getUserByLogin(login);\n\n        assertThat(updatedUser.getFirstName(), is(firstName));\n        assertThat(updatedUser.getLastName(), is(lastName));\n\n    }\n\n    @Test\n    public void createUserWithUsernameAndDomain() {\n        mockAuthenticationOnUserService(\"currentuser@domain.com\");\n\n        String login = \"username@domain.com\";\n        User user = new User();\n        user.setLogin(login);\n        userService.createUser(user);\n\n        User createdUser = userService.getUserByUsername(\"username\");\n\n        assertThat(createdUser.getUsername(), is(\"username\"));\n        assertThat(createdUser.getDomain(), is(\"domain.com\"));\n        assertNotNull(createdUser.getPassword());\n        assertThat(createdUser.getPassword().length(), is(80)); // Size of the encrypted password\n    }\n\n    @Test\n    public void shouldCreateAUser() {\n        mockAuthenticationOnUserService(\"currentuser@ippon.fr\");\n        String login = \"nuser@ippon.fr\";\n        String firstName = \"New\";\n        String lastName = \"User\";\n        String avatar = \"newAvatar\";\n\n        User user = new User();\n        user.setLogin(login);\n        user.setFirstName(firstName);\n        user.setLastName(lastName);\n        user.setAvatar(avatar);\n\n        userService.createUser(user);\n\n        /* verify */\n        User userToBeTheSame = userService.getUserByUsername(\"nuser\");\n        assertThat(userToBeTheSame.getLogin(), is(user.getLogin()));\n        assertThat(userToBeTheSame.getFirstName(), is(user.getFirstName()));\n        assertThat(userToBeTheSame.getLastName(), is(user.getLastName()));\n        assertThat(userToBeTheSame.getAvatar(), is(user.getAvatar()));\n        assertThat(userToBeTheSame.getStatusCount(), is(0L));\n        assertThat(userToBeTheSame.getFollowersCount(), is(0L));\n        assertThat(userToBeTheSame.getFriendsCount(), is(0L));\n    }\n\n\n    @Test\n    public void shouldRegisterUserToWeeklyEmailDigest() {\n        String login = \"uuser@ippon.fr\";\n\n        mockAuthenticationOnUserService(login);\n\n        userService.updateWeeklyDigestRegistration(true);\n        User updatedUser = userService.getUserByLogin(login);\n\n        assertTrue(updatedUser.getWeeklyDigestSubscription());\n\n        userService.updateWeeklyDigestRegistration(false);\n        updatedUser = userService.getUserByLogin(login);\n\n        assertFalse(updatedUser.getWeeklyDigestSubscription());\n    }\n\n\n    @Test\n    public void shouldRegisterUserToDailyEmailDigest() {\n        String login = \"uuser@ippon.fr\";\n\n        mockAuthenticationOnUserService(login);\n\n        userService.updateDailyDigestRegistration(true);\n        User updatedUser = userService.getUserByLogin(login);\n\n        assertTrue(updatedUser.getDailyDigestSubscription());\n\n        userService.updateDailyDigestRegistration(false);\n        updatedUser = userService.getUserByLogin(login);\n\n        assertFalse(updatedUser.getDailyDigestSubscription());\n    }\n\n    @Test\n    public void testGetUsersByLogin() {\n        String login1 = \"uuser@ippon.fr\";\n        String login2 = \"jdubois@ippon.fr\";\n\n        Collection<String> logins = new ArrayList<String>();\n        logins.add(login1);\n        logins.add(login2);\n\n        mockAuthenticationOnUserService(login2);\n\n        Collection<User> users = userService.getUsersByLogin(logins);\n\n        assertEquals(2, users.size());\n    }\n\n    @Test\n    public void testGetUsersForCurrentDomain() {\n        mockAuthenticationOnUserService(\"jdubois@ippon.fr\");\n        Collection<User> users = userService.getUsersForCurrentDomain(0);\n        assertTrue(users.size() > 10);\n    }\n\n    @Test\n    public void testUpdatePassword() {\n        String login = \"jdubois@ippon.fr\";\n        mockAuthenticationOnUserService(login);\n\n        User testUser = userService.getUserByLogin(login);\n        assertNull(testUser.getPassword());\n\n        testUser.setPassword(\"newPassword\");\n        userService.updatePassword(testUser);\n\n        testUser = userService.getUserByLogin(login);\n        assertNotNull(testUser.getPassword());\n        assertNotEquals(\"newPassword\", testUser.getPassword());\n    }\n\n    @Test\n    public void testBuildUserDTOList() {\n        String login = \"jdubois@ippon.fr\";\n        mockAuthenticationOnUserService(login);\n\n        User testUser = userService.getUserByLogin(login);\n        Collection<User> users = new ArrayList<User>();\n        users.add(testUser);\n\n        Collection<UserDTO> userDTOs = userService.buildUserDTOList(users);\n\n        assertEquals(1, userDTOs.size());\n        UserDTO dto = userDTOs.iterator().next();\n\n        assertEquals(\"Julien\", dto.getFirstName());\n        assertEquals(3, dto.getFollowersCount());\n        assertEquals(4, dto.getFriendsCount());\n\n    }\n\n    private void mockAuthenticationOnUserService(String login) {\n        User authenticateUser = constructAUser(login);\n        AuthenticationService mockAuthenticationService = mock(AuthenticationService.class);\n        when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser);\n        ReflectionTestUtils.setField(userService, \"authenticationService\", mockAuthenticationService);\n    }\n\n}"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/service/elasticsearch/ElasticsearchSearchServiceTest.java",
    "content": "//package fr.ippon.tatami.service.elasticsearch;\n//\n//import fr.ippon.tatami.AbstractCassandraTatamiTest;\n//import fr.ippon.tatami.service.AdminService;\n//import fr.ippon.tatami.service.SearchService;\n//import org.junit.Test;\n//import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;\n//import org.springframework.security.core.Authentication;\n//import org.springframework.security.core.GrantedAuthority;\n//import org.springframework.security.core.authority.SimpleGrantedAuthority;\n//import org.springframework.security.core.context.SecurityContextHolder;\n//\n//import javax.inject.Inject;\n//import java.util.ArrayList;\n//import java.util.Collection;\n//\n//import static org.junit.Assert.assertEquals;\n//\n//public class ElasticsearchSearchServiceTest extends AbstractCassandraTatamiTest {\n//\n//    @Inject\n//    private AdminService adminService;\n//\n//    @Inject\n//    private SearchService searchService;\n//\n//    @Test\n//    public void resetElasticSearch() throws InterruptedException {\n//        // The user needs to have the admin role\n//        GrantedAuthority adminAuthority = new SimpleGrantedAuthority(\"ROLE_ADMIN\");\n//        Collection<GrantedAuthority> grantedAuthorities = new ArrayList<GrantedAuthority>();\n//        grantedAuthorities.add(adminAuthority);\n//\n//        org.springframework.security.core.userdetails.User userDetails =\n//                new org.springframework.security.core.userdetails.User(\"tatami@ippon.fr\", \"\", grantedAuthorities);\n//\n//        Authentication authentication =\n//                new UsernamePasswordAuthenticationToken(userDetails,\n//                        userDetails.getPassword(),\n//                        userDetails.getAuthorities());\n//\n//        SecurityContextHolder.getContext().setAuthentication(authentication);\n//\n//        // Clean the index if needed\n//        searchService.reset();\n//\n//        // Test the user index\n//        Collection<String> users = searchService.searchUserByPrefix(\"ippon.fr\", \"jdub\");\n//        assertEquals(0, users.size());\n//\n//        adminService.rebuildIndex();\n//\n//        // Test every 100ms, for 30 seconds : this is the time for Elastic Search to index everything\n//        for (int i = 0; i < 100; i++) {\n//            Thread.sleep(300 * i);\n//            users = searchService.searchUserByPrefix(\"ippon.fr\", \"jdub\");\n//            if (users.size() > 0) {\n//                break;\n//            }\n//        }\n//\n//        assertEquals(1, users.size());\n//        assertEquals(\"jdubois@ippon.fr\", users.iterator().next());\n//    }\n//}\n"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/test/MockUtils.java",
    "content": "package fr.ippon.tatami.test;\r\n\r\nimport org.mockito.internal.util.MockUtil;\r\n\r\nimport java.util.concurrent.Callable;\r\n\r\npublic class MockUtils {\r\n\r\n    /**\r\n     * @param mock a Mockito mock\r\n     * @return\r\n     */\r\n    public static int getNumberOfInvocation(Object mock) {\r\n        // WARNING : we use internal mockito code here :\r\n        return new MockUtil().getMockHandler(mock).getInvocationContainer().getInvocations().size();\r\n    }\r\n\r\n    /**\r\n     * To be used with Awaitility.await().until(xxx)\r\n     *\r\n     * @param mock\r\n     * @param minInvocationCount\r\n     * @return\r\n     */\r\n    public static Callable<Boolean> mockCalledCallable(final Object mock, final int minInvocationCount) {\r\n        return new Callable<Boolean>() {\r\n            public Boolean call() throws Exception {\r\n                int nbCalls = getNumberOfInvocation(mock);\r\n                return nbCalls >= minInvocationCount;\r\n            }\r\n        };\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/test/application/ApplicationTestConfiguration.java",
    "content": "package fr.ippon.tatami.test.application;\n\nimport fr.ippon.tatami.config.AsyncConfiguration;\nimport fr.ippon.tatami.config.CassandraConfiguration;\nimport fr.ippon.tatami.config.MailConfiguration;\nimport fr.ippon.tatami.config.SearchConfiguration;\nimport org.apache.thrift.transport.TTransportException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.context.annotation.*;\n\nimport javax.annotation.PostConstruct;\nimport java.io.IOException;\n\n@Configuration\n@PropertySource(\"classpath:/tatami/tatami-test.properties\")\n@ComponentScan(basePackages = {\"fr.ippon.tatami.repository\", \"fr.ippon.tatami.service\", \"fr.ippon.tatami.security\"})\n@Import(value = {AsyncConfiguration.class,\n        CassandraConfiguration.class,\n        SearchConfiguration.class,\n        MailConfiguration.class})\n@ImportResource({\"classpath:META-INF/spring/applicationContext-security.xml\"})\npublic class ApplicationTestConfiguration {\n\n    private final Logger log = LoggerFactory.getLogger(ApplicationTestConfiguration.class);\n\n    @PostConstruct\n    public void initTatami() throws IOException, TTransportException {\n        this.log.info(\"Tatami test context started!\");\n    }\n}\n"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/test/application/WebApplicationTestConfiguration.java",
    "content": "package fr.ippon.tatami.test.application;\n\nimport fr.ippon.tatami.config.DispatcherServletConfig;\nimport org.apache.thrift.transport.TTransportException;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.context.annotation.Configuration;\nimport org.springframework.context.annotation.Import;\nimport org.springframework.test.context.web.WebAppConfiguration;\n\nimport javax.annotation.PostConstruct;\nimport java.io.IOException;\n\n@WebAppConfiguration\n@Configuration\n@Import(value = {DispatcherServletConfig.class})\npublic class WebApplicationTestConfiguration {\n\n    private final Logger log = LoggerFactory.getLogger(WebApplicationTestConfiguration.class);\n\n    @PostConstruct\n    public void initTatami() throws IOException, TTransportException {\n        this.log.info(\"Tatami Web test context started!\");\n    }\n}\n"
  },
  {
    "path": "services/src/test/java/fr/ippon/tatami/web/syndic/SyndicTimelineControllerTest.java",
    "content": "//package fr.ippon.tatami.web.syndic;\n//\n//import com.fasterxml.jackson.databind.ObjectMapper;\n//import fr.ippon.tatami.AbstractCassandraTatamiTest;\n//import fr.ippon.tatami.domain.User;\n//import fr.ippon.tatami.security.AuthenticationService;\n//import fr.ippon.tatami.service.StatusUpdateService;\n//import fr.ippon.tatami.service.TimelineService;\n//import fr.ippon.tatami.service.UserService;\n//import fr.ippon.tatami.service.dto.StatusDTO;\n//import fr.ippon.tatami.web.rest.AccountController;\n//import fr.ippon.tatami.web.rest.TimelineController;\n//import fr.ippon.tatami.web.rest.dto.Preferences;\n//import org.apache.commons.lang.CharEncoding;\n//import org.junit.Before;\n//import org.junit.Test;\n//import org.springframework.context.i18n.LocaleContextHolder;\n//import org.springframework.context.support.ReloadableResourceBundleMessageSource;\n//import org.springframework.core.env.Environment;\n//import org.springframework.http.MediaType;\n//import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;\n//import org.springframework.security.core.Authentication;\n//import org.springframework.security.core.GrantedAuthority;\n//import org.springframework.security.core.context.SecurityContextHolder;\n//import org.springframework.test.util.ReflectionTestUtils;\n//import org.springframework.test.web.servlet.MockMvc;\n//import org.springframework.test.web.servlet.setup.MockMvcBuilders;\n//import org.springframework.web.servlet.ModelAndView;\n//\n//import javax.inject.Inject;\n//import java.util.ArrayList;\n//import java.util.Collection;\n//import java.util.Locale;\n//\n//import static org.junit.Assert.assertEquals;\n//import static org.mockito.Mockito.mock;\n//import static org.mockito.Mockito.when;\n//import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;\n//import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;\n//import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;\n//\n//public class SyndicTimelineControllerTest extends AbstractCassandraTatamiTest {\n//\n//    @Inject\n//    private TimelineService timelineService;\n//\n//    @Inject\n//    private StatusUpdateService statusUpdateService;\n//\n//    @Inject\n//    private UserService userService;\n//\n//    @Inject\n//    Environment env;\n//\n//    private MockMvc mockMvc;\n//\n//    private MockMvc timelineMockMvc;\n//\n//    private MockMvc accountMockMvc;\n//\n//    private static final String username = \"timelineUser\";\n//\n//    @Before\n//    public void setup() {\n//\n//        TimelineController timelineController = new TimelineController();\n//        ReflectionTestUtils.setField(timelineController, \"timelineService\", timelineService);\n//        ReflectionTestUtils.setField(timelineController, \"statusUpdateService\", statusUpdateService);\n//\n//        User authenticateUser = constructAUser(username + \"@ippon.fr\");\n//        AuthenticationService mockAuthenticationService = mock(AuthenticationService.class);\n//        when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser);\n//        ReflectionTestUtils.setField(timelineController, \"authenticationService\", mockAuthenticationService);\n//        ReflectionTestUtils.setField(userService, \"authenticationService\", mockAuthenticationService);\n//        ReflectionTestUtils.setField(timelineService, \"authenticationService\", mockAuthenticationService);\n//        ReflectionTestUtils.setField(statusUpdateService, \"authenticationService\", mockAuthenticationService);\n//        this.timelineMockMvc = MockMvcBuilders.standaloneSetup(timelineController).build();\n//\n//        AccountController accountController = new AccountController();\n//        ReflectionTestUtils.setField(accountController, \"userService\", userService);\n//        ReflectionTestUtils.setField(accountController, \"env\", env);\n//        ReflectionTestUtils.setField(accountController, \"authenticationService\", mockAuthenticationService);\n//        this.accountMockMvc = MockMvcBuilders.standaloneSetup(accountController).build();\n//\n//        SyndicTimelineController syndicTimelineController = new SyndicTimelineController();\n//        ReflectionTestUtils.setField(syndicTimelineController, \"timelineService\", timelineService);\n//        ReflectionTestUtils.setField(syndicTimelineController, \"userService\", userService);\n//\n//        ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();\n//        messageSource.setBasename(\"file:src/main/webapp/WEB-INF/messages/messages\");\n//        messageSource.setDefaultEncoding(CharEncoding.UTF_8);\n//        ReflectionTestUtils.setField(syndicTimelineController, \"messageSource\", messageSource);\n//        this.mockMvc = MockMvcBuilders.standaloneSetup(syndicTimelineController).build();\n//    }\n//\n//    @Test\n//    @SuppressWarnings(\"unchecked\")\n//    public void testStatusUpdate() throws Exception {\n//        LocaleContextHolder.setLocale(Locale.US);\n//\n//        // Post content\n//        timelineMockMvc.perform(post(\"/rest/statuses/\")\n//                .contentType(MediaType.APPLICATION_JSON)\n//                .content(\"{\\\"content\\\":\\\"Test status for RSS syndication\\\"}\"))\n//                .andExpect(status().isOk());\n//\n//        // Get a RSS stream that is not correct\n//\n//        mockMvc.perform(get(\"/syndic/12345\"))\n//                .andExpect(status().isNotFound());\n//\n//        // Enable RSS for this user\n//        org.springframework.security.core.userdetails.User userDetails =\n//                new org.springframework.security.core.userdetails.User(username, \"\", new ArrayList<GrantedAuthority>());\n//\n//        Authentication authentication =\n//                new UsernamePasswordAuthenticationToken(userDetails,\n//                        userDetails.getPassword(),\n//                        userDetails.getAuthorities());\n//\n//        SecurityContextHolder.getContext().setAuthentication(authentication);\n//        accountMockMvc.perform(post(\"/rest/account/preferences\")\n//                .contentType(MediaType.APPLICATION_JSON)\n//                .content(\"{\\\"mentionEmail\\\":true,\" +\n//                        \"\\\"weeklyDigest\\\":false,\" +\n//                        \"\\\"dailyDigest\\\":false,\" +\n//                        \"\\\"rssUidActive\\\":true,\" +\n//                        \"\\\"rssUid\\\":\\\"\\\"}\"))\n//                .andExpect(status().isOk());\n//\n//        //Get RSS ID\n//        String preferencesAsJson = accountMockMvc.perform(get(\"/rest/account/preferences\")\n//                .accept(MediaType.APPLICATION_JSON))\n//                .andExpect(status().isOk())\n//                .andExpect(content().contentType(\"application/json\"))\n//                .andExpect(jsonPath(\"$.rssUidActive\").value(true))\n//                .andReturn().getResponse().getContentAsString();\n//\n//        Preferences preferences = new ObjectMapper().readValue(preferencesAsJson, Preferences.class);\n//\n//        String rssId = preferences.getRssUid();\n//\n//        ModelAndView result = mockMvc.perform(get(\"/syndic/\" + rssId))\n//                .andExpect(status().isOk())\n//                .andReturn().getModelAndView();\n//\n//        Collection<StatusDTO> statuses = (Collection<StatusDTO>) result.getModel().get(\"feedContent\");\n//        assertEquals(\"Test status for RSS syndication\", statuses.iterator().next().getContent());\n//\n//    }\n//}\n"
  },
  {
    "path": "services/src/test/jmeter/tatami-create-users.jmx",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<jmeterTestPlan version=\"1.2\" properties=\"2.4\" jmeter=\"2.9 r1437961\">\n  <hashTree>\n    <TestPlan guiclass=\"TestPlanGui\" testclass=\"TestPlan\" testname=\"Tatami test plan\" enabled=\"true\">\n      <stringProp name=\"TestPlan.comments\">Use the &quot;stress-test&quot; Maven profile to use this plan</stringProp>\n      <boolProp name=\"TestPlan.functional_mode\">false</boolProp>\n      <boolProp name=\"TestPlan.serialize_threadgroups\">false</boolProp>\n      <elementProp name=\"TestPlan.user_defined_variables\" elementType=\"Arguments\" guiclass=\"ArgumentsPanel\" testclass=\"Arguments\" testname=\"Variables pré-définies\" enabled=\"true\">\n        <collectionProp name=\"Arguments.arguments\"/>\n      </elementProp>\n      <stringProp name=\"TestPlan.user_define_classpath\"></stringProp>\n    </TestPlan>\n    <hashTree>\n      <ThreadGroup guiclass=\"ThreadGroupGui\" testclass=\"ThreadGroup\" testname=\"Tatami User\" enabled=\"true\">\n        <stringProp name=\"ThreadGroup.on_sample_error\">continue</stringProp>\n        <elementProp name=\"ThreadGroup.main_controller\" elementType=\"LoopController\" guiclass=\"LoopControlPanel\" testclass=\"LoopController\" testname=\"Contrôleur Boucle\" enabled=\"true\">\n          <boolProp name=\"LoopController.continue_forever\">false</boolProp>\n          <stringProp name=\"LoopController.loops\">1</stringProp>\n        </elementProp>\n        <stringProp name=\"ThreadGroup.num_threads\">1</stringProp>\n        <stringProp name=\"ThreadGroup.ramp_time\">1</stringProp>\n        <longProp name=\"ThreadGroup.start_time\">1333013329000</longProp>\n        <longProp name=\"ThreadGroup.end_time\">1333013329000</longProp>\n        <boolProp name=\"ThreadGroup.scheduler\">false</boolProp>\n        <stringProp name=\"ThreadGroup.duration\"></stringProp>\n        <stringProp name=\"ThreadGroup.delay\"></stringProp>\n      </ThreadGroup>\n      <hashTree>\n        <Arguments guiclass=\"ArgumentsPanel\" testclass=\"Arguments\" testname=\"User variables\" enabled=\"true\">\n          <collectionProp name=\"Arguments.arguments\">\n            <elementProp name=\"userNumber\" elementType=\"Argument\">\n              <stringProp name=\"Argument.name\">userNumber</stringProp>\n              <stringProp name=\"Argument.value\">199</stringProp>\n              <stringProp name=\"Argument.metadata\">=</stringProp>\n            </elementProp>\n            <elementProp name=\"followerNumber\" elementType=\"Argument\">\n              <stringProp name=\"Argument.name\">followerNumber</stringProp>\n              <stringProp name=\"Argument.value\">199</stringProp>\n              <stringProp name=\"Argument.metadata\">=</stringProp>\n            </elementProp>\n          </collectionProp>\n        </Arguments>\n        <hashTree/>\n        <ConfigTestElement guiclass=\"HttpDefaultsGui\" testclass=\"ConfigTestElement\" testname=\"Default HTTP parameters\" enabled=\"true\">\n          <elementProp name=\"HTTPsampler.Arguments\" elementType=\"Arguments\" guiclass=\"HTTPArgumentsPanel\" testclass=\"Arguments\" testname=\"Variables pré-définies\" enabled=\"true\">\n            <collectionProp name=\"Arguments.arguments\"/>\n          </elementProp>\n          <stringProp name=\"HTTPSampler.domain\">127.0.0.1</stringProp>\n          <stringProp name=\"HTTPSampler.port\">8080</stringProp>\n          <stringProp name=\"HTTPSampler.connect_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.response_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.protocol\"></stringProp>\n          <stringProp name=\"HTTPSampler.contentEncoding\"></stringProp>\n          <stringProp name=\"HTTPSampler.path\">/tatami</stringProp>\n          <stringProp name=\"HTTPSampler.implementation\">Java</stringProp>\n          <stringProp name=\"HTTPSampler.concurrentPool\">4</stringProp>\n        </ConfigTestElement>\n        <hashTree/>\n        <CookieManager guiclass=\"CookiePanel\" testclass=\"CookieManager\" testname=\"Cookie manager\" enabled=\"true\">\n          <collectionProp name=\"CookieManager.cookies\"/>\n          <boolProp name=\"CookieManager.clearEachIteration\">false</boolProp>\n        </CookieManager>\n        <hashTree/>\n        <LoopController guiclass=\"LoopControlPanel\" testclass=\"LoopController\" testname=\"User registrations\" enabled=\"true\">\n          <boolProp name=\"LoopController.continue_forever\">true</boolProp>\n          <stringProp name=\"LoopController.loops\">${__BeanShell(Integer.parseInt(vars.get(&quot;userNumber&quot;))+1)}</stringProp>\n        </LoopController>\n        <hashTree>\n          <CounterConfig guiclass=\"CounterConfigGui\" testclass=\"CounterConfig\" testname=\"Counter\" enabled=\"true\">\n            <stringProp name=\"CounterConfig.start\">0</stringProp>\n            <stringProp name=\"CounterConfig.end\">${userNumber}</stringProp>\n            <stringProp name=\"CounterConfig.incr\">1</stringProp>\n            <stringProp name=\"CounterConfig.name\">userCount</stringProp>\n            <stringProp name=\"CounterConfig.format\"></stringProp>\n            <boolProp name=\"CounterConfig.per_user\">true</boolProp>\n            <boolProp name=\"CounterConfig.reset_on_tg_iteration\">true</boolProp>\n          </CounterConfig>\n          <hashTree/>\n          <HTTPSamplerProxy guiclass=\"HttpTestSampleGui\" testclass=\"HTTPSamplerProxy\" testname=\"Registration\" enabled=\"true\">\n            <elementProp name=\"HTTPsampler.Arguments\" elementType=\"Arguments\" guiclass=\"HTTPArgumentsPanel\" testclass=\"Arguments\" testname=\"Variables pré-définies\" enabled=\"true\">\n              <collectionProp name=\"Arguments.arguments\">\n                <elementProp name=\"email\" elementType=\"HTTPArgument\">\n                  <boolProp name=\"HTTPArgument.always_encode\">false</boolProp>\n                  <stringProp name=\"Argument.value\">user${userCount}@test.com</stringProp>\n                  <stringProp name=\"Argument.metadata\">=</stringProp>\n                  <boolProp name=\"HTTPArgument.use_equals\">true</boolProp>\n                  <stringProp name=\"Argument.name\">email</stringProp>\n                </elementProp>\n                <elementProp name=\"password\" elementType=\"HTTPArgument\">\n                  <boolProp name=\"HTTPArgument.always_encode\">false</boolProp>\n                  <stringProp name=\"Argument.value\">test</stringProp>\n                  <stringProp name=\"Argument.metadata\">=</stringProp>\n                  <boolProp name=\"HTTPArgument.use_equals\">true</boolProp>\n                  <stringProp name=\"Argument.name\">password</stringProp>\n                </elementProp>\n              </collectionProp>\n            </elementProp>\n            <stringProp name=\"HTTPSampler.domain\"></stringProp>\n            <stringProp name=\"HTTPSampler.port\"></stringProp>\n            <stringProp name=\"HTTPSampler.connect_timeout\"></stringProp>\n            <stringProp name=\"HTTPSampler.response_timeout\"></stringProp>\n            <stringProp name=\"HTTPSampler.protocol\"></stringProp>\n            <stringProp name=\"HTTPSampler.contentEncoding\"></stringProp>\n            <stringProp name=\"HTTPSampler.path\">/tatami/register/automatic</stringProp>\n            <stringProp name=\"HTTPSampler.method\">POST</stringProp>\n            <boolProp name=\"HTTPSampler.follow_redirects\">true</boolProp>\n            <boolProp name=\"HTTPSampler.auto_redirects\">false</boolProp>\n            <boolProp name=\"HTTPSampler.use_keepalive\">true</boolProp>\n            <boolProp name=\"HTTPSampler.DO_MULTIPART_POST\">false</boolProp>\n            <boolProp name=\"HTTPSampler.monitor\">false</boolProp>\n            <stringProp name=\"HTTPSampler.embedded_url_re\"></stringProp>\n          </HTTPSamplerProxy>\n          <hashTree/>\n        </hashTree>\n        <LoopController guiclass=\"LoopControlPanel\" testclass=\"LoopController\" testname=\"Followers creation\" enabled=\"true\">\n          <boolProp name=\"LoopController.continue_forever\">true</boolProp>\n          <stringProp name=\"LoopController.loops\">${__BeanShell(Integer.parseInt(vars.get(&quot;followerNumber&quot;))+1)}</stringProp>\n        </LoopController>\n        <hashTree>\n          <CounterConfig guiclass=\"CounterConfigGui\" testclass=\"CounterConfig\" testname=\"Counter\" enabled=\"true\">\n            <stringProp name=\"CounterConfig.start\">0</stringProp>\n            <stringProp name=\"CounterConfig.end\">${followerNumber}</stringProp>\n            <stringProp name=\"CounterConfig.incr\">1</stringProp>\n            <stringProp name=\"CounterConfig.name\">followerCount</stringProp>\n            <stringProp name=\"CounterConfig.format\"></stringProp>\n            <boolProp name=\"CounterConfig.per_user\">true</boolProp>\n            <boolProp name=\"CounterConfig.reset_on_tg_iteration\">true</boolProp>\n          </CounterConfig>\n          <hashTree/>\n          <HTTPSamplerProxy guiclass=\"HttpTestSampleGui\" testclass=\"HTTPSamplerProxy\" testname=\"Registration\" enabled=\"true\">\n            <elementProp name=\"HTTPsampler.Arguments\" elementType=\"Arguments\" guiclass=\"HTTPArgumentsPanel\" testclass=\"Arguments\" testname=\"Variables pré-définies\" enabled=\"true\">\n              <collectionProp name=\"Arguments.arguments\">\n                <elementProp name=\"email\" elementType=\"HTTPArgument\">\n                  <boolProp name=\"HTTPArgument.always_encode\">false</boolProp>\n                  <stringProp name=\"Argument.value\">userfollower${followerCount}@test.com</stringProp>\n                  <stringProp name=\"Argument.metadata\">=</stringProp>\n                  <boolProp name=\"HTTPArgument.use_equals\">true</boolProp>\n                  <stringProp name=\"Argument.name\">email</stringProp>\n                </elementProp>\n                <elementProp name=\"password\" elementType=\"HTTPArgument\">\n                  <boolProp name=\"HTTPArgument.always_encode\">false</boolProp>\n                  <stringProp name=\"Argument.value\">test</stringProp>\n                  <stringProp name=\"Argument.metadata\">=</stringProp>\n                  <boolProp name=\"HTTPArgument.use_equals\">true</boolProp>\n                  <stringProp name=\"Argument.name\">password</stringProp>\n                </elementProp>\n              </collectionProp>\n            </elementProp>\n            <stringProp name=\"HTTPSampler.domain\"></stringProp>\n            <stringProp name=\"HTTPSampler.port\"></stringProp>\n            <stringProp name=\"HTTPSampler.connect_timeout\"></stringProp>\n            <stringProp name=\"HTTPSampler.response_timeout\"></stringProp>\n            <stringProp name=\"HTTPSampler.protocol\"></stringProp>\n            <stringProp name=\"HTTPSampler.contentEncoding\"></stringProp>\n            <stringProp name=\"HTTPSampler.path\">/tatami/register/automatic</stringProp>\n            <stringProp name=\"HTTPSampler.method\">POST</stringProp>\n            <boolProp name=\"HTTPSampler.follow_redirects\">true</boolProp>\n            <boolProp name=\"HTTPSampler.auto_redirects\">false</boolProp>\n            <boolProp name=\"HTTPSampler.use_keepalive\">true</boolProp>\n            <boolProp name=\"HTTPSampler.DO_MULTIPART_POST\">false</boolProp>\n            <boolProp name=\"HTTPSampler.monitor\">false</boolProp>\n            <stringProp name=\"HTTPSampler.embedded_url_re\"></stringProp>\n          </HTTPSamplerProxy>\n          <hashTree/>\n          <HTTPSamplerProxy guiclass=\"HttpTestSampleGui\" testclass=\"HTTPSamplerProxy\" testname=\"Authentication\" enabled=\"true\">\n            <elementProp name=\"HTTPsampler.Arguments\" elementType=\"Arguments\" guiclass=\"HTTPArgumentsPanel\" testclass=\"Arguments\" testname=\"Variables pré-définies\" enabled=\"true\">\n              <collectionProp name=\"Arguments.arguments\">\n                <elementProp name=\"j_username\" elementType=\"HTTPArgument\">\n                  <boolProp name=\"HTTPArgument.always_encode\">false</boolProp>\n                  <stringProp name=\"Argument.value\">userfollower${followerCount}@test.com</stringProp>\n                  <stringProp name=\"Argument.metadata\">=</stringProp>\n                  <boolProp name=\"HTTPArgument.use_equals\">true</boolProp>\n                  <stringProp name=\"Argument.name\">j_username</stringProp>\n                </elementProp>\n                <elementProp name=\"j_password\" elementType=\"HTTPArgument\">\n                  <boolProp name=\"HTTPArgument.always_encode\">false</boolProp>\n                  <stringProp name=\"Argument.value\">test</stringProp>\n                  <stringProp name=\"Argument.metadata\">=</stringProp>\n                  <boolProp name=\"HTTPArgument.use_equals\">true</boolProp>\n                  <stringProp name=\"Argument.name\">j_password</stringProp>\n                </elementProp>\n              </collectionProp>\n            </elementProp>\n            <stringProp name=\"HTTPSampler.domain\"></stringProp>\n            <stringProp name=\"HTTPSampler.port\"></stringProp>\n            <stringProp name=\"HTTPSampler.connect_timeout\"></stringProp>\n            <stringProp name=\"HTTPSampler.response_timeout\"></stringProp>\n            <stringProp name=\"HTTPSampler.protocol\"></stringProp>\n            <stringProp name=\"HTTPSampler.contentEncoding\"></stringProp>\n            <stringProp name=\"HTTPSampler.path\">/tatami/authentication</stringProp>\n            <stringProp name=\"HTTPSampler.method\">POST</stringProp>\n            <boolProp name=\"HTTPSampler.follow_redirects\">true</boolProp>\n            <boolProp name=\"HTTPSampler.auto_redirects\">false</boolProp>\n            <boolProp name=\"HTTPSampler.use_keepalive\">true</boolProp>\n            <boolProp name=\"HTTPSampler.DO_MULTIPART_POST\">false</boolProp>\n            <boolProp name=\"HTTPSampler.monitor\">false</boolProp>\n            <stringProp name=\"HTTPSampler.embedded_url_re\"></stringProp>\n          </HTTPSamplerProxy>\n          <hashTree/>\n          <LoopController guiclass=\"LoopControlPanel\" testclass=\"LoopController\" testname=\"Follow each user\" enabled=\"true\">\n            <boolProp name=\"LoopController.continue_forever\">true</boolProp>\n            <stringProp name=\"LoopController.loops\">${__BeanShell(Integer.parseInt(vars.get(&quot;userNumber&quot;))+1)}</stringProp>\n          </LoopController>\n          <hashTree>\n            <CounterConfig guiclass=\"CounterConfigGui\" testclass=\"CounterConfig\" testname=\"Counter\" enabled=\"true\">\n              <stringProp name=\"CounterConfig.start\">0</stringProp>\n              <stringProp name=\"CounterConfig.end\">${userNumber}</stringProp>\n              <stringProp name=\"CounterConfig.incr\">1</stringProp>\n              <stringProp name=\"CounterConfig.name\">userToFollowCount</stringProp>\n              <stringProp name=\"CounterConfig.format\"></stringProp>\n              <boolProp name=\"CounterConfig.per_user\">true</boolProp>\n              <boolProp name=\"CounterConfig.reset_on_tg_iteration\">true</boolProp>\n            </CounterConfig>\n            <hashTree/>\n            <HTTPSamplerProxy guiclass=\"HttpTestSampleGui\" testclass=\"HTTPSamplerProxy\" testname=\"Follow user\" enabled=\"true\">\n              <boolProp name=\"HTTPSampler.postBodyRaw\">true</boolProp>\n              <elementProp name=\"HTTPsampler.Arguments\" elementType=\"Arguments\">\n                <collectionProp name=\"Arguments.arguments\">\n                  <elementProp name=\"\" elementType=\"HTTPArgument\">\n                    <boolProp name=\"HTTPArgument.always_encode\">false</boolProp>\n                    <stringProp name=\"Argument.value\">{&quot;username&quot;:&quot;user${userToFollowCount}&quot;}</stringProp>\n                    <stringProp name=\"Argument.metadata\">=</stringProp>\n                  </elementProp>\n                </collectionProp>\n              </elementProp>\n              <stringProp name=\"HTTPSampler.domain\"></stringProp>\n              <stringProp name=\"HTTPSampler.port\"></stringProp>\n              <stringProp name=\"HTTPSampler.connect_timeout\"></stringProp>\n              <stringProp name=\"HTTPSampler.response_timeout\"></stringProp>\n              <stringProp name=\"HTTPSampler.protocol\"></stringProp>\n              <stringProp name=\"HTTPSampler.contentEncoding\"></stringProp>\n              <stringProp name=\"HTTPSampler.path\">/tatami/rest/friendships/create</stringProp>\n              <stringProp name=\"HTTPSampler.method\">POST</stringProp>\n              <boolProp name=\"HTTPSampler.follow_redirects\">true</boolProp>\n              <boolProp name=\"HTTPSampler.auto_redirects\">false</boolProp>\n              <boolProp name=\"HTTPSampler.use_keepalive\">true</boolProp>\n              <boolProp name=\"HTTPSampler.DO_MULTIPART_POST\">false</boolProp>\n              <boolProp name=\"HTTPSampler.monitor\">false</boolProp>\n              <stringProp name=\"HTTPSampler.embedded_url_re\"></stringProp>\n            </HTTPSamplerProxy>\n            <hashTree>\n              <HeaderManager guiclass=\"HeaderPanel\" testclass=\"HeaderManager\" testname=\"HTTP header manager\" enabled=\"true\">\n                <collectionProp name=\"HeaderManager.headers\">\n                  <elementProp name=\"\" elementType=\"Header\">\n                    <stringProp name=\"Header.name\">Content-Type</stringProp>\n                    <stringProp name=\"Header.value\">application/json; charset=UTF-8</stringProp>\n                  </elementProp>\n                  <elementProp name=\"\" elementType=\"Header\">\n                    <stringProp name=\"Header.name\">Accept</stringProp>\n                    <stringProp name=\"Header.value\">application/json</stringProp>\n                  </elementProp>\n                </collectionProp>\n              </HeaderManager>\n              <hashTree/>\n            </hashTree>\n          </hashTree>\n          <HTTPSamplerProxy guiclass=\"HttpTestSampleGui\" testclass=\"HTTPSamplerProxy\" testname=\"logout\" enabled=\"true\">\n            <elementProp name=\"HTTPsampler.Arguments\" elementType=\"Arguments\" guiclass=\"HTTPArgumentsPanel\" testclass=\"Arguments\" testname=\"Variables pré-définies\" enabled=\"true\">\n              <collectionProp name=\"Arguments.arguments\"/>\n            </elementProp>\n            <stringProp name=\"HTTPSampler.domain\"></stringProp>\n            <stringProp name=\"HTTPSampler.port\"></stringProp>\n            <stringProp name=\"HTTPSampler.connect_timeout\"></stringProp>\n            <stringProp name=\"HTTPSampler.response_timeout\"></stringProp>\n            <stringProp name=\"HTTPSampler.protocol\"></stringProp>\n            <stringProp name=\"HTTPSampler.contentEncoding\"></stringProp>\n            <stringProp name=\"HTTPSampler.path\">/tatami/logout</stringProp>\n            <stringProp name=\"HTTPSampler.method\">GET</stringProp>\n            <boolProp name=\"HTTPSampler.follow_redirects\">true</boolProp>\n            <boolProp name=\"HTTPSampler.auto_redirects\">false</boolProp>\n            <boolProp name=\"HTTPSampler.use_keepalive\">true</boolProp>\n            <boolProp name=\"HTTPSampler.DO_MULTIPART_POST\">false</boolProp>\n            <boolProp name=\"HTTPSampler.monitor\">false</boolProp>\n            <stringProp name=\"HTTPSampler.embedded_url_re\"></stringProp>\n          </HTTPSamplerProxy>\n          <hashTree/>\n        </hashTree>\n        <ResultCollector guiclass=\"StatVisualizer\" testclass=\"ResultCollector\" testname=\"Aggregate report\" enabled=\"true\">\n          <boolProp name=\"ResultCollector.error_logging\">false</boolProp>\n          <objProp>\n            <name>saveConfig</name>\n            <value class=\"SampleSaveConfiguration\">\n              <time>true</time>\n              <latency>true</latency>\n              <timestamp>true</timestamp>\n              <success>true</success>\n              <label>true</label>\n              <code>true</code>\n              <message>true</message>\n              <threadName>true</threadName>\n              <dataType>true</dataType>\n              <encoding>false</encoding>\n              <assertions>true</assertions>\n              <subresults>true</subresults>\n              <responseData>false</responseData>\n              <samplerData>false</samplerData>\n              <xml>true</xml>\n              <fieldNames>false</fieldNames>\n              <responseHeaders>false</responseHeaders>\n              <requestHeaders>false</requestHeaders>\n              <responseDataOnError>false</responseDataOnError>\n              <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>\n              <assertionsResultsToSave>0</assertionsResultsToSave>\n              <bytes>true</bytes>\n            </value>\n          </objProp>\n          <stringProp name=\"filename\"></stringProp>\n        </ResultCollector>\n        <hashTree/>\n        <ResultCollector guiclass=\"ViewResultsFullVisualizer\" testclass=\"ResultCollector\" testname=\"Arbre de résultats\" enabled=\"false\">\n          <boolProp name=\"ResultCollector.error_logging\">false</boolProp>\n          <objProp>\n            <name>saveConfig</name>\n            <value class=\"SampleSaveConfiguration\">\n              <time>true</time>\n              <latency>true</latency>\n              <timestamp>true</timestamp>\n              <success>true</success>\n              <label>true</label>\n              <code>true</code>\n              <message>true</message>\n              <threadName>true</threadName>\n              <dataType>true</dataType>\n              <encoding>false</encoding>\n              <assertions>true</assertions>\n              <subresults>true</subresults>\n              <responseData>false</responseData>\n              <samplerData>false</samplerData>\n              <xml>false</xml>\n              <fieldNames>false</fieldNames>\n              <responseHeaders>false</responseHeaders>\n              <requestHeaders>false</requestHeaders>\n              <responseDataOnError>false</responseDataOnError>\n              <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>\n              <assertionsResultsToSave>0</assertionsResultsToSave>\n              <bytes>true</bytes>\n            </value>\n          </objProp>\n          <stringProp name=\"filename\"></stringProp>\n        </ResultCollector>\n        <hashTree/>\n      </hashTree>\n    </hashTree>\n  </hashTree>\n</jmeterTestPlan>\n"
  },
  {
    "path": "services/src/test/jmeter/tatami-stress-test.jmx",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<jmeterTestPlan version=\"1.2\" properties=\"2.4\" jmeter=\"2.9 r1437961\">\n  <hashTree>\n    <TestPlan guiclass=\"TestPlanGui\" testclass=\"TestPlan\" testname=\"Tatami test plan\" enabled=\"true\">\n      <stringProp name=\"TestPlan.comments\">Use the &quot;stress-test&quot; Maven profile to use this plan</stringProp>\n      <boolProp name=\"TestPlan.functional_mode\">false</boolProp>\n      <boolProp name=\"TestPlan.serialize_threadgroups\">false</boolProp>\n      <elementProp name=\"TestPlan.user_defined_variables\" elementType=\"Arguments\" guiclass=\"ArgumentsPanel\" testclass=\"Arguments\" testname=\"Variables pré-définies\" enabled=\"true\">\n        <collectionProp name=\"Arguments.arguments\"/>\n      </elementProp>\n      <stringProp name=\"TestPlan.user_define_classpath\"></stringProp>\n    </TestPlan>\n    <hashTree>\n      <ThreadGroup guiclass=\"ThreadGroupGui\" testclass=\"ThreadGroup\" testname=\"Tatami Users\" enabled=\"true\">\n        <stringProp name=\"ThreadGroup.on_sample_error\">continue</stringProp>\n        <elementProp name=\"ThreadGroup.main_controller\" elementType=\"LoopController\" guiclass=\"LoopControlPanel\" testclass=\"LoopController\" testname=\"Contrôleur Boucle\" enabled=\"true\">\n          <boolProp name=\"LoopController.continue_forever\">false</boolProp>\n          <stringProp name=\"LoopController.loops\">20</stringProp>\n        </elementProp>\n        <stringProp name=\"ThreadGroup.num_threads\">200</stringProp>\n        <stringProp name=\"ThreadGroup.ramp_time\">10</stringProp>\n        <longProp name=\"ThreadGroup.start_time\">1333013329000</longProp>\n        <longProp name=\"ThreadGroup.end_time\">1333013329000</longProp>\n        <boolProp name=\"ThreadGroup.scheduler\">false</boolProp>\n        <stringProp name=\"ThreadGroup.duration\"></stringProp>\n        <stringProp name=\"ThreadGroup.delay\"></stringProp>\n      </ThreadGroup>\n      <hashTree>\n        <GaussianRandomTimer guiclass=\"GaussianRandomTimerGui\" testclass=\"GaussianRandomTimer\" testname=\"Compteur de temps aléatoire gaussien\" enabled=\"true\">\n          <stringProp name=\"ConstantTimer.delay\">300</stringProp>\n          <stringProp name=\"RandomTimer.range\">100.0</stringProp>\n        </GaussianRandomTimer>\n        <hashTree/>\n        <CounterConfig guiclass=\"CounterConfigGui\" testclass=\"CounterConfig\" testname=\"UserCount\" enabled=\"true\">\n          <stringProp name=\"CounterConfig.start\">0</stringProp>\n          <stringProp name=\"CounterConfig.end\">200</stringProp>\n          <stringProp name=\"CounterConfig.incr\">1</stringProp>\n          <stringProp name=\"CounterConfig.name\">userCount</stringProp>\n          <stringProp name=\"CounterConfig.format\"></stringProp>\n          <boolProp name=\"CounterConfig.per_user\">false</boolProp>\n        </CounterConfig>\n        <hashTree/>\n        <ConfigTestElement guiclass=\"HttpDefaultsGui\" testclass=\"ConfigTestElement\" testname=\"Default HTTP parameters\" enabled=\"true\">\n          <elementProp name=\"HTTPsampler.Arguments\" elementType=\"Arguments\" guiclass=\"HTTPArgumentsPanel\" testclass=\"Arguments\" testname=\"Variables pré-définies\" enabled=\"true\">\n            <collectionProp name=\"Arguments.arguments\"/>\n          </elementProp>\n          <stringProp name=\"HTTPSampler.domain\">127.0.0.1</stringProp>\n          <stringProp name=\"HTTPSampler.port\">8080</stringProp>\n          <stringProp name=\"HTTPSampler.connect_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.response_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.protocol\"></stringProp>\n          <stringProp name=\"HTTPSampler.contentEncoding\"></stringProp>\n          <stringProp name=\"HTTPSampler.path\">/tatami</stringProp>\n          <stringProp name=\"HTTPSampler.implementation\">Java</stringProp>\n          <stringProp name=\"HTTPSampler.concurrentPool\">4</stringProp>\n        </ConfigTestElement>\n        <hashTree/>\n        <CookieManager guiclass=\"CookiePanel\" testclass=\"CookieManager\" testname=\"Cookie manager\" enabled=\"true\">\n          <collectionProp name=\"CookieManager.cookies\"/>\n          <boolProp name=\"CookieManager.clearEachIteration\">false</boolProp>\n        </CookieManager>\n        <hashTree/>\n        <HTTPSamplerProxy guiclass=\"HttpTestSampleGui\" testclass=\"HTTPSamplerProxy\" testname=\"Login page\" enabled=\"true\">\n          <elementProp name=\"HTTPsampler.Arguments\" elementType=\"Arguments\" guiclass=\"HTTPArgumentsPanel\" testclass=\"Arguments\" testname=\"Variables pré-définies\" enabled=\"true\">\n            <collectionProp name=\"Arguments.arguments\"/>\n          </elementProp>\n          <stringProp name=\"HTTPSampler.domain\"></stringProp>\n          <stringProp name=\"HTTPSampler.port\"></stringProp>\n          <stringProp name=\"HTTPSampler.connect_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.response_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.protocol\"></stringProp>\n          <stringProp name=\"HTTPSampler.contentEncoding\"></stringProp>\n          <stringProp name=\"HTTPSampler.path\">/tatami/login</stringProp>\n          <stringProp name=\"HTTPSampler.method\">GET</stringProp>\n          <boolProp name=\"HTTPSampler.follow_redirects\">true</boolProp>\n          <boolProp name=\"HTTPSampler.auto_redirects\">false</boolProp>\n          <boolProp name=\"HTTPSampler.use_keepalive\">true</boolProp>\n          <boolProp name=\"HTTPSampler.DO_MULTIPART_POST\">false</boolProp>\n          <boolProp name=\"HTTPSampler.monitor\">false</boolProp>\n          <stringProp name=\"HTTPSampler.embedded_url_re\"></stringProp>\n        </HTTPSamplerProxy>\n        <hashTree/>\n        <HTTPSamplerProxy guiclass=\"HttpTestSampleGui\" testclass=\"HTTPSamplerProxy\" testname=\"Registration\" enabled=\"false\">\n          <elementProp name=\"HTTPsampler.Arguments\" elementType=\"Arguments\" guiclass=\"HTTPArgumentsPanel\" testclass=\"Arguments\" testname=\"Variables pré-définies\" enabled=\"true\">\n            <collectionProp name=\"Arguments.arguments\">\n              <elementProp name=\"email\" elementType=\"HTTPArgument\">\n                <boolProp name=\"HTTPArgument.always_encode\">false</boolProp>\n                <stringProp name=\"Argument.value\">user${userCount}@test.com</stringProp>\n                <stringProp name=\"Argument.metadata\">=</stringProp>\n                <boolProp name=\"HTTPArgument.use_equals\">true</boolProp>\n                <stringProp name=\"Argument.name\">email</stringProp>\n              </elementProp>\n              <elementProp name=\"password\" elementType=\"HTTPArgument\">\n                <boolProp name=\"HTTPArgument.always_encode\">false</boolProp>\n                <stringProp name=\"Argument.value\">test</stringProp>\n                <stringProp name=\"Argument.metadata\">=</stringProp>\n                <boolProp name=\"HTTPArgument.use_equals\">true</boolProp>\n                <stringProp name=\"Argument.name\">password</stringProp>\n              </elementProp>\n            </collectionProp>\n          </elementProp>\n          <stringProp name=\"HTTPSampler.domain\"></stringProp>\n          <stringProp name=\"HTTPSampler.port\"></stringProp>\n          <stringProp name=\"HTTPSampler.connect_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.response_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.protocol\"></stringProp>\n          <stringProp name=\"HTTPSampler.contentEncoding\"></stringProp>\n          <stringProp name=\"HTTPSampler.path\">/tatami/register/automatic</stringProp>\n          <stringProp name=\"HTTPSampler.method\">POST</stringProp>\n          <boolProp name=\"HTTPSampler.follow_redirects\">true</boolProp>\n          <boolProp name=\"HTTPSampler.auto_redirects\">false</boolProp>\n          <boolProp name=\"HTTPSampler.use_keepalive\">true</boolProp>\n          <boolProp name=\"HTTPSampler.DO_MULTIPART_POST\">false</boolProp>\n          <boolProp name=\"HTTPSampler.monitor\">false</boolProp>\n          <stringProp name=\"HTTPSampler.embedded_url_re\"></stringProp>\n        </HTTPSamplerProxy>\n        <hashTree/>\n        <HTTPSamplerProxy guiclass=\"HttpTestSampleGui\" testclass=\"HTTPSamplerProxy\" testname=\"Authentication\" enabled=\"true\">\n          <elementProp name=\"HTTPsampler.Arguments\" elementType=\"Arguments\" guiclass=\"HTTPArgumentsPanel\" testclass=\"Arguments\" testname=\"Variables pré-définies\" enabled=\"true\">\n            <collectionProp name=\"Arguments.arguments\">\n              <elementProp name=\"j_username\" elementType=\"HTTPArgument\">\n                <boolProp name=\"HTTPArgument.always_encode\">false</boolProp>\n                <stringProp name=\"Argument.value\">user${userCount}@test.com</stringProp>\n                <stringProp name=\"Argument.metadata\">=</stringProp>\n                <boolProp name=\"HTTPArgument.use_equals\">true</boolProp>\n                <stringProp name=\"Argument.name\">j_username</stringProp>\n              </elementProp>\n              <elementProp name=\"j_password\" elementType=\"HTTPArgument\">\n                <boolProp name=\"HTTPArgument.always_encode\">false</boolProp>\n                <stringProp name=\"Argument.value\">test</stringProp>\n                <stringProp name=\"Argument.metadata\">=</stringProp>\n                <boolProp name=\"HTTPArgument.use_equals\">true</boolProp>\n                <stringProp name=\"Argument.name\">j_password</stringProp>\n              </elementProp>\n            </collectionProp>\n          </elementProp>\n          <stringProp name=\"HTTPSampler.domain\"></stringProp>\n          <stringProp name=\"HTTPSampler.port\"></stringProp>\n          <stringProp name=\"HTTPSampler.connect_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.response_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.protocol\"></stringProp>\n          <stringProp name=\"HTTPSampler.contentEncoding\"></stringProp>\n          <stringProp name=\"HTTPSampler.path\">/tatami/authentication</stringProp>\n          <stringProp name=\"HTTPSampler.method\">POST</stringProp>\n          <boolProp name=\"HTTPSampler.follow_redirects\">true</boolProp>\n          <boolProp name=\"HTTPSampler.auto_redirects\">false</boolProp>\n          <boolProp name=\"HTTPSampler.use_keepalive\">true</boolProp>\n          <boolProp name=\"HTTPSampler.DO_MULTIPART_POST\">false</boolProp>\n          <boolProp name=\"HTTPSampler.monitor\">false</boolProp>\n          <stringProp name=\"HTTPSampler.embedded_url_re\"></stringProp>\n        </HTTPSamplerProxy>\n        <hashTree/>\n        <HTTPSamplerProxy guiclass=\"HttpTestSampleGui\" testclass=\"HTTPSamplerProxy\" testname=\"Home page\" enabled=\"true\">\n          <elementProp name=\"HTTPsampler.Arguments\" elementType=\"Arguments\" guiclass=\"HTTPArgumentsPanel\" testclass=\"Arguments\" testname=\"Variables pré-définies\" enabled=\"true\">\n            <collectionProp name=\"Arguments.arguments\"/>\n          </elementProp>\n          <stringProp name=\"HTTPSampler.domain\"></stringProp>\n          <stringProp name=\"HTTPSampler.port\"></stringProp>\n          <stringProp name=\"HTTPSampler.connect_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.response_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.protocol\"></stringProp>\n          <stringProp name=\"HTTPSampler.contentEncoding\"></stringProp>\n          <stringProp name=\"HTTPSampler.path\">/tatami/</stringProp>\n          <stringProp name=\"HTTPSampler.method\">GET</stringProp>\n          <boolProp name=\"HTTPSampler.follow_redirects\">true</boolProp>\n          <boolProp name=\"HTTPSampler.auto_redirects\">false</boolProp>\n          <boolProp name=\"HTTPSampler.use_keepalive\">true</boolProp>\n          <boolProp name=\"HTTPSampler.DO_MULTIPART_POST\">false</boolProp>\n          <boolProp name=\"HTTPSampler.monitor\">false</boolProp>\n          <stringProp name=\"HTTPSampler.embedded_url_re\"></stringProp>\n        </HTTPSamplerProxy>\n        <hashTree/>\n        <HTTPSamplerProxy guiclass=\"HttpTestSampleGui\" testclass=\"HTTPSamplerProxy\" testname=\"GET Profile\" enabled=\"true\">\n          <elementProp name=\"HTTPsampler.Arguments\" elementType=\"Arguments\" guiclass=\"HTTPArgumentsPanel\" testclass=\"Arguments\" testname=\"Variables pré-définies\" enabled=\"true\">\n            <collectionProp name=\"Arguments.arguments\"/>\n          </elementProp>\n          <stringProp name=\"HTTPSampler.domain\"></stringProp>\n          <stringProp name=\"HTTPSampler.port\"></stringProp>\n          <stringProp name=\"HTTPSampler.connect_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.response_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.protocol\"></stringProp>\n          <stringProp name=\"HTTPSampler.contentEncoding\"></stringProp>\n          <stringProp name=\"HTTPSampler.path\">/tatami/rest/account/profile</stringProp>\n          <stringProp name=\"HTTPSampler.method\">GET</stringProp>\n          <boolProp name=\"HTTPSampler.follow_redirects\">true</boolProp>\n          <boolProp name=\"HTTPSampler.auto_redirects\">false</boolProp>\n          <boolProp name=\"HTTPSampler.use_keepalive\">true</boolProp>\n          <boolProp name=\"HTTPSampler.DO_MULTIPART_POST\">false</boolProp>\n          <boolProp name=\"HTTPSampler.monitor\">false</boolProp>\n          <stringProp name=\"HTTPSampler.embedded_url_re\"></stringProp>\n        </HTTPSamplerProxy>\n        <hashTree/>\n        <HTTPSamplerProxy guiclass=\"HttpTestSampleGui\" testclass=\"HTTPSamplerProxy\" testname=\"GET Trends\" enabled=\"true\">\n          <elementProp name=\"HTTPsampler.Arguments\" elementType=\"Arguments\" guiclass=\"HTTPArgumentsPanel\" testclass=\"Arguments\" testname=\"Variables pré-définies\" enabled=\"true\">\n            <collectionProp name=\"Arguments.arguments\"/>\n          </elementProp>\n          <stringProp name=\"HTTPSampler.domain\"></stringProp>\n          <stringProp name=\"HTTPSampler.port\"></stringProp>\n          <stringProp name=\"HTTPSampler.connect_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.response_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.protocol\"></stringProp>\n          <stringProp name=\"HTTPSampler.contentEncoding\"></stringProp>\n          <stringProp name=\"HTTPSampler.path\">/tatami/rest/trends</stringProp>\n          <stringProp name=\"HTTPSampler.method\">GET</stringProp>\n          <boolProp name=\"HTTPSampler.follow_redirects\">true</boolProp>\n          <boolProp name=\"HTTPSampler.auto_redirects\">false</boolProp>\n          <boolProp name=\"HTTPSampler.use_keepalive\">true</boolProp>\n          <boolProp name=\"HTTPSampler.DO_MULTIPART_POST\">false</boolProp>\n          <boolProp name=\"HTTPSampler.monitor\">false</boolProp>\n          <stringProp name=\"HTTPSampler.embedded_url_re\"></stringProp>\n        </HTTPSamplerProxy>\n        <hashTree/>\n        <HTTPSamplerProxy guiclass=\"HttpTestSampleGui\" testclass=\"HTTPSamplerProxy\" testname=\"GET Group memberships\" enabled=\"true\">\n          <elementProp name=\"HTTPsampler.Arguments\" elementType=\"Arguments\" guiclass=\"HTTPArgumentsPanel\" testclass=\"Arguments\" testname=\"Variables pré-définies\" enabled=\"true\">\n            <collectionProp name=\"Arguments.arguments\"/>\n          </elementProp>\n          <stringProp name=\"HTTPSampler.domain\"></stringProp>\n          <stringProp name=\"HTTPSampler.port\"></stringProp>\n          <stringProp name=\"HTTPSampler.connect_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.response_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.protocol\"></stringProp>\n          <stringProp name=\"HTTPSampler.contentEncoding\"></stringProp>\n          <stringProp name=\"HTTPSampler.path\">/tatami/rest/groupmemberships/lookup?screen_name=user${userCount}</stringProp>\n          <stringProp name=\"HTTPSampler.method\">GET</stringProp>\n          <boolProp name=\"HTTPSampler.follow_redirects\">true</boolProp>\n          <boolProp name=\"HTTPSampler.auto_redirects\">false</boolProp>\n          <boolProp name=\"HTTPSampler.use_keepalive\">true</boolProp>\n          <boolProp name=\"HTTPSampler.DO_MULTIPART_POST\">false</boolProp>\n          <boolProp name=\"HTTPSampler.monitor\">false</boolProp>\n          <stringProp name=\"HTTPSampler.embedded_url_re\"></stringProp>\n        </HTTPSamplerProxy>\n        <hashTree/>\n        <HTTPSamplerProxy guiclass=\"HttpTestSampleGui\" testclass=\"HTTPSamplerProxy\" testname=\"GET show\" enabled=\"true\">\n          <elementProp name=\"HTTPsampler.Arguments\" elementType=\"Arguments\" guiclass=\"HTTPArgumentsPanel\" testclass=\"Arguments\" testname=\"Variables pré-définies\" enabled=\"true\">\n            <collectionProp name=\"Arguments.arguments\"/>\n          </elementProp>\n          <stringProp name=\"HTTPSampler.domain\"></stringProp>\n          <stringProp name=\"HTTPSampler.port\"></stringProp>\n          <stringProp name=\"HTTPSampler.connect_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.response_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.protocol\"></stringProp>\n          <stringProp name=\"HTTPSampler.contentEncoding\"></stringProp>\n          <stringProp name=\"HTTPSampler.path\">/tatami/rest/users/show?screen_name=user${userCount}</stringProp>\n          <stringProp name=\"HTTPSampler.method\">GET</stringProp>\n          <boolProp name=\"HTTPSampler.follow_redirects\">true</boolProp>\n          <boolProp name=\"HTTPSampler.auto_redirects\">false</boolProp>\n          <boolProp name=\"HTTPSampler.use_keepalive\">true</boolProp>\n          <boolProp name=\"HTTPSampler.DO_MULTIPART_POST\">false</boolProp>\n          <boolProp name=\"HTTPSampler.monitor\">false</boolProp>\n          <stringProp name=\"HTTPSampler.embedded_url_re\"></stringProp>\n        </HTTPSamplerProxy>\n        <hashTree/>\n        <HTTPSamplerProxy guiclass=\"HttpTestSampleGui\" testclass=\"HTTPSamplerProxy\" testname=\"GET suggestions\" enabled=\"true\">\n          <elementProp name=\"HTTPsampler.Arguments\" elementType=\"Arguments\" guiclass=\"HTTPArgumentsPanel\" testclass=\"Arguments\" testname=\"Variables pré-définies\" enabled=\"true\">\n            <collectionProp name=\"Arguments.arguments\"/>\n          </elementProp>\n          <stringProp name=\"HTTPSampler.domain\"></stringProp>\n          <stringProp name=\"HTTPSampler.port\"></stringProp>\n          <stringProp name=\"HTTPSampler.connect_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.response_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.protocol\"></stringProp>\n          <stringProp name=\"HTTPSampler.contentEncoding\"></stringProp>\n          <stringProp name=\"HTTPSampler.path\">/tatami/rest/users/suggestions</stringProp>\n          <stringProp name=\"HTTPSampler.method\">GET</stringProp>\n          <boolProp name=\"HTTPSampler.follow_redirects\">true</boolProp>\n          <boolProp name=\"HTTPSampler.auto_redirects\">false</boolProp>\n          <boolProp name=\"HTTPSampler.use_keepalive\">true</boolProp>\n          <boolProp name=\"HTTPSampler.DO_MULTIPART_POST\">false</boolProp>\n          <boolProp name=\"HTTPSampler.monitor\">false</boolProp>\n          <stringProp name=\"HTTPSampler.embedded_url_re\"></stringProp>\n        </HTTPSamplerProxy>\n        <hashTree/>\n        <HTTPSamplerProxy guiclass=\"HttpTestSampleGui\" testclass=\"HTTPSamplerProxy\" testname=\"GET Status\" enabled=\"true\">\n          <elementProp name=\"HTTPsampler.Arguments\" elementType=\"Arguments\" guiclass=\"HTTPArgumentsPanel\" testclass=\"Arguments\" testname=\"Variables pré-définies\" enabled=\"true\">\n            <collectionProp name=\"Arguments.arguments\"/>\n          </elementProp>\n          <stringProp name=\"HTTPSampler.domain\"></stringProp>\n          <stringProp name=\"HTTPSampler.port\"></stringProp>\n          <stringProp name=\"HTTPSampler.connect_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.response_timeout\"></stringProp>\n          <stringProp name=\"HTTPSampler.protocol\"></stringProp>\n          <stringProp name=\"HTTPSampler.contentEncoding\"></stringProp>\n          <stringProp name=\"HTTPSampler.path\">/tatami/rest/statuses/home_timeline</stringProp>\n          <stringProp name=\"HTTPSampler.method\">GET</stringProp>\n          <boolProp name=\"HTTPSampler.follow_redirects\">true</boolProp>\n          <boolProp name=\"HTTPSampler.auto_redirects\">false</boolProp>\n          <boolProp name=\"HTTPSampler.use_keepalive\">true</boolProp>\n          <boolProp name=\"HTTPSampler.DO_MULTIPART_POST\">false</boolProp>\n          <boolProp name=\"HTTPSampler.monitor\">false</boolProp>\n          <stringProp name=\"HTTPSampler.embedded_url_re\"></stringProp>\n        </HTTPSamplerProxy>\n        <hashTree/>\n        <LoopController guiclass=\"LoopControlPanel\" testclass=\"LoopController\" testname=\"Status loop\" enabled=\"true\">\n          <boolProp name=\"LoopController.continue_forever\">true</boolProp>\n          <stringProp name=\"LoopController.loops\">5</stringProp>\n        </LoopController>\n        <hashTree>\n          <CounterConfig guiclass=\"CounterConfigGui\" testclass=\"CounterConfig\" testname=\"Counter\" enabled=\"true\">\n            <stringProp name=\"CounterConfig.start\">0</stringProp>\n            <stringProp name=\"CounterConfig.end\"></stringProp>\n            <stringProp name=\"CounterConfig.incr\">1</stringProp>\n            <stringProp name=\"CounterConfig.name\">statusCount</stringProp>\n            <stringProp name=\"CounterConfig.format\"></stringProp>\n            <boolProp name=\"CounterConfig.per_user\">true</boolProp>\n            <boolProp name=\"CounterConfig.reset_on_tg_iteration\">true</boolProp>\n          </CounterConfig>\n          <hashTree/>\n          <HTTPSamplerProxy guiclass=\"HttpTestSampleGui\" testclass=\"HTTPSamplerProxy\" testname=\"POST new Status\" enabled=\"true\">\n            <boolProp name=\"HTTPSampler.postBodyRaw\">true</boolProp>\n            <elementProp name=\"HTTPsampler.Arguments\" elementType=\"Arguments\">\n              <collectionProp name=\"Arguments.arguments\">\n                <elementProp name=\"\" elementType=\"HTTPArgument\">\n                  <boolProp name=\"HTTPArgument.always_encode\">false</boolProp>\n                  <stringProp name=\"Argument.value\">{&quot;content&quot;:&quot;test status ${userCount} - ${statusCount} #tag @user0&quot;}</stringProp>\n                  <stringProp name=\"Argument.metadata\">=</stringProp>\n                </elementProp>\n              </collectionProp>\n            </elementProp>\n            <stringProp name=\"HTTPSampler.domain\"></stringProp>\n            <stringProp name=\"HTTPSampler.port\"></stringProp>\n            <stringProp name=\"HTTPSampler.connect_timeout\"></stringProp>\n            <stringProp name=\"HTTPSampler.response_timeout\"></stringProp>\n            <stringProp name=\"HTTPSampler.protocol\"></stringProp>\n            <stringProp name=\"HTTPSampler.contentEncoding\"></stringProp>\n            <stringProp name=\"HTTPSampler.path\">/tatami/rest/statuses/update</stringProp>\n            <stringProp name=\"HTTPSampler.method\">POST</stringProp>\n            <boolProp name=\"HTTPSampler.follow_redirects\">true</boolProp>\n            <boolProp name=\"HTTPSampler.auto_redirects\">false</boolProp>\n            <boolProp name=\"HTTPSampler.use_keepalive\">true</boolProp>\n            <boolProp name=\"HTTPSampler.DO_MULTIPART_POST\">false</boolProp>\n            <boolProp name=\"HTTPSampler.monitor\">false</boolProp>\n            <stringProp name=\"HTTPSampler.embedded_url_re\"></stringProp>\n          </HTTPSamplerProxy>\n          <hashTree>\n            <HeaderManager guiclass=\"HeaderPanel\" testclass=\"HeaderManager\" testname=\"HTTP header manager\" enabled=\"true\">\n              <collectionProp name=\"HeaderManager.headers\">\n                <elementProp name=\"\" elementType=\"Header\">\n                  <stringProp name=\"Header.name\">Content-Type</stringProp>\n                  <stringProp name=\"Header.value\">application/json; charset=UTF-8</stringProp>\n                </elementProp>\n                <elementProp name=\"\" elementType=\"Header\">\n                  <stringProp name=\"Header.name\">Accept</stringProp>\n                  <stringProp name=\"Header.value\">application/json</stringProp>\n                </elementProp>\n              </collectionProp>\n            </HeaderManager>\n            <hashTree/>\n          </hashTree>\n          <LoopController guiclass=\"LoopControlPanel\" testclass=\"LoopController\" testname=\"Contrôleur Boucle\" enabled=\"true\">\n            <boolProp name=\"LoopController.continue_forever\">true</boolProp>\n            <stringProp name=\"LoopController.loops\">10</stringProp>\n          </LoopController>\n          <hashTree>\n            <HTTPSamplerProxy guiclass=\"HttpTestSampleGui\" testclass=\"HTTPSamplerProxy\" testname=\"GET Status\" enabled=\"true\">\n              <elementProp name=\"HTTPsampler.Arguments\" elementType=\"Arguments\" guiclass=\"HTTPArgumentsPanel\" testclass=\"Arguments\" testname=\"Variables pré-définies\" enabled=\"true\">\n                <collectionProp name=\"Arguments.arguments\"/>\n              </elementProp>\n              <stringProp name=\"HTTPSampler.domain\"></stringProp>\n              <stringProp name=\"HTTPSampler.port\"></stringProp>\n              <stringProp name=\"HTTPSampler.connect_timeout\"></stringProp>\n              <stringProp name=\"HTTPSampler.response_timeout\"></stringProp>\n              <stringProp name=\"HTTPSampler.protocol\"></stringProp>\n              <stringProp name=\"HTTPSampler.contentEncoding\"></stringProp>\n              <stringProp name=\"HTTPSampler.path\">/tatami/rest/statuses/home_timeline</stringProp>\n              <stringProp name=\"HTTPSampler.method\">GET</stringProp>\n              <boolProp name=\"HTTPSampler.follow_redirects\">true</boolProp>\n              <boolProp name=\"HTTPSampler.auto_redirects\">false</boolProp>\n              <boolProp name=\"HTTPSampler.use_keepalive\">true</boolProp>\n              <boolProp name=\"HTTPSampler.DO_MULTIPART_POST\">false</boolProp>\n              <boolProp name=\"HTTPSampler.monitor\">false</boolProp>\n              <stringProp name=\"HTTPSampler.embedded_url_re\"></stringProp>\n            </HTTPSamplerProxy>\n            <hashTree/>\n          </hashTree>\n        </hashTree>\n        <ResultCollector guiclass=\"StatVisualizer\" testclass=\"ResultCollector\" testname=\"Aggregate report\" enabled=\"true\">\n          <boolProp name=\"ResultCollector.error_logging\">false</boolProp>\n          <objProp>\n            <name>saveConfig</name>\n            <value class=\"SampleSaveConfiguration\">\n              <time>true</time>\n              <latency>true</latency>\n              <timestamp>true</timestamp>\n              <success>true</success>\n              <label>true</label>\n              <code>true</code>\n              <message>true</message>\n              <threadName>true</threadName>\n              <dataType>true</dataType>\n              <encoding>false</encoding>\n              <assertions>true</assertions>\n              <subresults>true</subresults>\n              <responseData>false</responseData>\n              <samplerData>false</samplerData>\n              <xml>true</xml>\n              <fieldNames>false</fieldNames>\n              <responseHeaders>false</responseHeaders>\n              <requestHeaders>false</requestHeaders>\n              <responseDataOnError>false</responseDataOnError>\n              <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>\n              <assertionsResultsToSave>0</assertionsResultsToSave>\n              <bytes>true</bytes>\n            </value>\n          </objProp>\n          <stringProp name=\"filename\"></stringProp>\n        </ResultCollector>\n        <hashTree/>\n        <ResultCollector guiclass=\"ViewResultsFullVisualizer\" testclass=\"ResultCollector\" testname=\"Arbre de résultats\" enabled=\"false\">\n          <boolProp name=\"ResultCollector.error_logging\">false</boolProp>\n          <objProp>\n            <name>saveConfig</name>\n            <value class=\"SampleSaveConfiguration\">\n              <time>true</time>\n              <latency>true</latency>\n              <timestamp>true</timestamp>\n              <success>true</success>\n              <label>true</label>\n              <code>true</code>\n              <message>true</message>\n              <threadName>true</threadName>\n              <dataType>true</dataType>\n              <encoding>false</encoding>\n              <assertions>true</assertions>\n              <subresults>true</subresults>\n              <responseData>false</responseData>\n              <samplerData>false</samplerData>\n              <xml>false</xml>\n              <fieldNames>false</fieldNames>\n              <responseHeaders>false</responseHeaders>\n              <requestHeaders>false</requestHeaders>\n              <responseDataOnError>false</responseDataOnError>\n              <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage>\n              <assertionsResultsToSave>0</assertionsResultsToSave>\n              <bytes>true</bytes>\n            </value>\n          </objProp>\n          <stringProp name=\"filename\"></stringProp>\n        </ResultCollector>\n        <hashTree/>\n      </hashTree>\n    </hashTree>\n  </hashTree>\n</jmeterTestPlan>\n"
  },
  {
    "path": "services/src/test/resources/dataset/dataset.json",
    "content": "{\n    \"name\":\"tatami\",\n    \"columnFamilies\":[\n        {\n            \"name\":\"User\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UTF8Type\",\n            \"defaultColumnValueType\":\"UTF8Type\",\n            \"rows\":[\n                {\n                    \"key\":\"jdubois@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"avatar\",\n                            \"value\":\"avatar\"\n                        },\n                        {\n                            \"name\":\"firstName\",\n                            \"value\":\"Julien\"\n                        },\n                        {\n                            \"name\":\"lastName\",\n                            \"value\":\"Dubois\"\n                        },\n                        {\n                            \"name\":\"username\",\n                            \"value\":\"jdubois\"\n                        },\n                        {\n                            \"name\":\"domain\",\n                            \"value\":\"ippon.fr\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"uuser@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"avatar\",\n                            \"value\":\"avatar\"\n                        },\n                        {\n                            \"name\":\"firstName\",\n                            \"value\":\"Update\"\n                        },\n                        {\n                            \"name\":\"lastName\",\n                            \"value\":\"User\"\n                        },\n                        {\n                            \"name\":\"username\",\n                            \"value\":\"uuser\"\n                        },\n                        {\n                            \"name\":\"domain\",\n                            \"value\":\"ippon.fr\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"timelineUser@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"avatar\",\n                            \"value\":\"avatar\"\n                        },\n                        {\n                            \"name\":\"firstName\",\n                            \"value\":\"User\"\n                        },\n                        {\n                            \"name\":\"lastName\",\n                            \"value\":\"TimelineUser\"\n                        },\n                        {\n                            \"name\":\"username\",\n                            \"value\":\"timelineUser\"\n                        },\n                        {\n                            \"name\":\"domain\",\n                            \"value\":\"ippon.fr\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoHasGroup@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"avatar\",\n                            \"value\":\"avatar\"\n                        },\n                        {\n                            \"name\":\"firstName\",\n                            \"value\":\"User\"\n                        },\n                        {\n                            \"name\":\"lastName\",\n                            \"value\":\"WhoHasGroup\"\n                        },\n                        {\n                            \"name\":\"username\",\n                            \"value\":\"userWhoHasGroup\"\n                        },\n                        {\n                            \"name\":\"domain\",\n                            \"value\":\"ippon.fr\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoWantToFollow@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"avatar\",\n                            \"value\":\"avatar\"\n                        },\n                        {\n                            \"name\":\"firstName\",\n                            \"value\":\"User\"\n                        },\n                        {\n                            \"name\":\"lastName\",\n                            \"value\":\"WhoWantToFollow\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoWillBeFollowed@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"avatar\",\n                            \"value\":\"avatar\"\n                        },\n                        {\n                            \"name\":\"firstName\",\n                            \"value\":\"User\"\n                        },\n                        {\n                            \"name\":\"lastName\",\n                            \"value\":\"WhoWillBeFollowed\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoFollow@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"avatar\",\n                            \"value\":\"avatar\"\n                        },\n                        {\n                            \"name\":\"firstName\",\n                            \"value\":\"User\"\n                        },\n                        {\n                            \"name\":\"lastName\",\n                            \"value\":\"WhoFollow\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoIsFollowed@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"avatar\",\n                            \"value\":\"avatar\"\n                        },\n                        {\n                            \"name\":\"firstName\",\n                            \"value\":\"User\"\n                        },\n                        {\n                            \"name\":\"lastName\",\n                            \"value\":\"WhoIsFollowed\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoWantToForget@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"avatar\",\n                            \"value\":\"avatar\"\n                        },\n                        {\n                            \"name\":\"firstName\",\n                            \"value\":\"User\"\n                        },\n                        {\n                            \"name\":\"lastName\",\n                            \"value\":\"WhoWantToForget\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userToForget@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"avatar\",\n                            \"value\":\"avatar\"\n                        },\n                        {\n                            \"name\":\"firstName\",\n                            \"value\":\"User\"\n                        },\n                        {\n                            \"name\":\"lastName\",\n                            \"value\":\"ToForget\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWithStatus@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"username\",\n                            \"value\":\"userWithStatus\"\n                        },\n                        {\n                            \"name\":\"domain\",\n                            \"value\":\"ippon.fr\"\n                        },\n                        {\n                            \"name\":\"avatar\",\n                            \"value\":\"avatar\"\n                        },\n                        {\n                            \"name\":\"firstName\",\n                            \"value\":\"User\"\n                        },\n                        {\n                            \"name\":\"lastName\",\n                            \"value\":\"WithUserline\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoPostStatus@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"username\",\n                            \"value\":\"userWhoPostStatus\"\n                        },\n                        {\n                            \"name\":\"domain\",\n                            \"value\":\"ippon.fr\"\n                        },\n                        {\n                            \"name\":\"avatar\",\n                            \"value\":\"avatar\"\n                        },\n                        {\n                            \"name\":\"firstName\",\n                            \"value\":\"User\"\n                        },\n                        {\n                            \"name\":\"lastName\",\n                            \"value\":\"WhoPostStatus\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoReadStatus@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"avatar\",\n                            \"value\":\"avatar\"\n                        },\n                        {\n                            \"name\":\"firstName\",\n                            \"value\":\"User\"\n                        },\n                        {\n                            \"name\":\"lastName\",\n                            \"value\":\"WhoReadStatus\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoShouldBeFoundBySimilarSearch@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"avatar\",\n                            \"value\":\"avatar\"\n                        },\n                        {\n                            \"name\":\"firstName\",\n                            \"value\":\"User\"\n                        },\n                        {\n                            \"name\":\"lastName\",\n                            \"value\":\"WhoShouldBeFoundBySimilarSearch\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoSubscribeToDigests@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"username\",\n                            \"value\":\"userWhoSubscribeToDigests\"\n                        },\n                        {\n                            \"name\":\"domain\",\n                            \"value\":\"ippon.fr\"\n                        },\n                        {\n                            \"name\":\"avatar\",\n                            \"value\":\"avatar\"\n                        },\n                        {\n                            \"name\":\"firstName\",\n                            \"value\":\"User\"\n                        },\n                        {\n                            \"name\":\"lastName\",\n                            \"value\":\"WhoSubscribeToDigests\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoPostForDigests@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"username\",\n                            \"value\":\"userWhoPostForDigests\"\n                        },\n                        {\n                            \"name\":\"domain\",\n                            \"value\":\"ippon.fr\"\n                        },\n                        {\n                            \"name\":\"avatar\",\n                            \"value\":\"avatar\"\n                        },\n                        {\n                            \"name\":\"firstName\",\n                            \"value\":\"User\"\n                        },\n                        {\n                            \"name\":\"lastName\",\n                            \"value\":\"WhoPostForDigests\"\n                        }\n                    ]\n                }\n            ]\n        },\n        {\n            \"name\":\"Domain\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UTF8Type\",\n            \"rows\" : [\n                {\n                    \"key\":\"ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"jdubois@ippon.fr\",\n                            \"value\":\"\"\n                        },\n                        {\n                            \"name\":\"uuser@ippon.fr\",\n                            \"value\":\"\"\n                        },\n                        {\n                            \"name\":\"timelineUser@ippon.fr\",\n                            \"value\":\"\"\n                        },\n                        {\n                            \"name\":\"userWhoHasGroup@ippon.fr\",\n                            \"value\":\"\"\n                        },\n                        {\n                            \"name\":\"userWhoWantToFollow@ippon.fr\",\n                            \"value\":\"\"\n                        },\n                        {\n                            \"name\":\"userWhoWillBeFollowed@ippon.fr\",\n                            \"value\":\"\"\n                        },\n                        {\n                            \"name\":\"userWhoFollow@ippon.fr\",\n                            \"value\":\"\"\n                        },\n                        {\n                            \"name\":\"userWhoIsFollowed@ippon.fr\",\n                            \"value\":\"\"\n                        },\n                        {\n                            \"name\":\"userWhoWantToForget@ippon.fr\",\n                            \"value\":\"\"\n                        },\n                        {\n                            \"name\":\"userToForget@ippon.fr\",\n                            \"value\":\"\"\n                        },\n                        {\n                            \"name\":\"userWithStatus@ippon.fr\",\n                            \"value\":\"\"\n                        },\n                        {\n                            \"name\":\"userWhoPostStatus@ippon.fr\",\n                            \"value\":\"\"\n                        },\n                        {\n                            \"name\":\"userWhoReadStatus@ippon.fr\",\n                            \"value\":\"\"\n                        },\n                        {\n                            \"name\":\"userWhoShouldBeFoundBySimilarSearch@ippon.fr\",\n                            \"value\":\"\"\n                        },\n                        {\n                            \"name\": \"userWhoSubscribeToDigests@ippon.fr\",\n                            \"value\": \"\"\n                        },\n                        {\n                            \"name\":\"userWhoPostForDigests@ippon.fr\",\n                            \"value\" : \"\"\n                        }\n                    ]\n                }\n\n\n\n            ]\n        },\n        {\n            \"name\" : \"MailDigest\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UTF8Type\"\n        },\n        {\n            \"name\":\"Counter\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UTF8Type\",\n            \"defaultColumnValueType\":\"CounterColumnType\",\n            \"rows\":[\n                {\n                    \"key\":\"jdubois@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"STATUS_COUNTER\",\n                            \"value\":\"2\"\n                        },\n                        {\n                            \"name\":\"FOLLOWERS_COUNTER\",\n                            \"value\":\"3\"\n                        },\n                        {\n                            \"name\":\"FRIENDS_COUNTER\",\n                            \"value\":\"4\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"timelineUser@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"STATUS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FOLLOWERS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FRIENDS_COUNTER\",\n                            \"value\":\"0\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoHasGroup@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"STATUS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FOLLOWERS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FRIENDS_COUNTER\",\n                            \"value\":\"0\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoWantToFollow@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"STATUS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FOLLOWERS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FRIENDS_COUNTER\",\n                            \"value\":\"0\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoWillBeFollowed@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"STATUS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FOLLOWERS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FRIENDS_COUNTER\",\n                            \"value\":\"0\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoFollow@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"STATUS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FOLLOWERS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FRIENDS_COUNTER\",\n                            \"value\":\"1\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoIsFollowed@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"STATUS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FOLLOWERS_COUNTER\",\n                            \"value\":\"1\"\n                        },\n                        {\n                            \"name\":\"FRIENDS_COUNTER\",\n                            \"value\":\"0\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoWantToForget@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"STATUS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FOLLOWERS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FRIENDS_COUNTER\",\n                            \"value\":\"1\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userToForget@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"STATUS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FOLLOWERS_COUNTER\",\n                            \"value\":\"1\"\n                        },\n                        {\n                            \"name\":\"FRIENDS_COUNTER\",\n                            \"value\":\"0\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWithStatus@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"STATUS_COUNTER\",\n                            \"value\":\"2\"\n                        },\n                        {\n                            \"name\":\"FOLLOWERS_COUNTER\",\n                            \"value\":\"1\"\n                        },\n                        {\n                            \"name\":\"FRIENDS_COUNTER\",\n                            \"value\":\"0\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoPostStatus@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"STATUS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FOLLOWERS_COUNTER\",\n                            \"value\":\"1\"\n                        },\n                        {\n                            \"name\":\"FRIENDS_COUNTER\",\n                            \"value\":\"0\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoReadStatus@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"STATUS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FOLLOWERS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FRIENDS_COUNTER\",\n                            \"value\":\"1\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoSubscribeToDigests@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"STATUS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FOLLOWERS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FRIENDS_COUNTER\",\n                            \"value\":\"0\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoPostForDigests@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"STATUS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FOLLOWERS_COUNTER\",\n                            \"value\":\"0\"\n                        },\n                        {\n                            \"name\":\"FRIENDS_COUNTER\",\n                            \"value\":\"0\"\n                        }\n                    ]\n                }\n            ]\n        },\n        {\n            \"name\":\"Friends\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UTF8Type\",\n            \"defaultColumnValueType\":\"LongType\",\n            \"rows\":[\n                {\n                    \"key\":\"userWhoFollow@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"userWhoIsFollowed@ippon.fr\",\n                            \"value\":\"0\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoWantToForget@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"userToForget@ippon.fr\",\n                            \"value\":\"0\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"userWhoReadStatus@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"userWhoPostStatus@ippon.fr\",\n                            \"value\":\"0\"\n                        }\n                    ]\n                }\n            ]\n        },\n        {\n            \"name\":\"Followers\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UTF8Type\",\n            \"defaultColumnValueType\":\"LongType\",\n            \"rows\":[\n                {\n                    \"key\":\"userWhoPostStatus@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"userWhoReadStatus@ippon.fr\",\n                            \"value\":\"0\"\n                        }\n                    ]\n                }\n            ]\n        },\n        {\n            \"name\":\"Favline\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UUIDType\",\n            \"defaultColumnValueType\":\"UTF8Type\",\n            \"rows\":[\n                {\n                    \"key\":\"userWhoPostStatus@ippon.fr\"\n                }\n            ]\n        },\n        {\n            \"name\":\"Dayline\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UTF8Type\",\n            \"defaultColumnValueType\":\"CounterColumnType\",\n            \"rows\":[\n                {\n                    \"key\":\"19052012-ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"userWithStatus\",\n                            \"value\":\"1\"\n                        }\n                    ]\n                }\n            ]\n        },\n        {\n            \"name\":\"Tagline\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UUIDType\",\n            \"defaultColumnValueType\":\"UTF8Type\",\n            \"rows\":[\n                {\n                    \"key\":\"ippon-ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"fa2bd770-9848-11e1-a6ca-e0f847068d52\",\n                            \"value\":\"\"\n                        },\n                        {\n                            \"name\":\"f97d6470-9847-11e1-a6ca-e0f847068d52\",\n                            \"value\":\"\"\n                        }\n                    ]\n                }\n            ]\n        },\n        {\n            \"name\":\"Timeline\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UUIDType\",\n            \"defaultColumnValueType\":\"UTF8Type\",\n            \"rows\":[\n                {\n                    \"key\":\"userWithStatus@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"fa2bd770-9848-11e1-a6ca-e0f847068d52\",\n                            \"value\":\"\"\n                        },\n                        {\n                            \"name\":\"f97d6470-9847-11e1-a6ca-e0f847068d52\",\n                            \"value\":\"\"\n                        }\n                    ]\n                }\n            ]\n        },\n        {\n            \"name\":\"Userline\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UUIDType\",\n            \"defaultColumnValueType\":\"UTF8Type\",\n            \"rows\":[\n                {\n                    \"key\":\"userWithStatus@ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"fa2bd770-9848-11e1-a6ca-e0f847068d52\",\n                            \"value\":\"\"\n                        },\n                        {\n                            \"name\":\"f97d6470-9847-11e1-a6ca-e0f847068d52\",\n                            \"value\":\"\"\n                        }\n                    ]\n                }\n            ]\n        },\n        {\n            \"name\":\"Domainline\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UUIDType\",\n            \"defaultColumnValueType\":\"UTF8Type\"\n        },\n        {\n            \"name\":\"Status\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UTF8Type\",\n            \"rows\":[\n                {\n                    \"key\":\"fa2bd770-9848-11e1-a6ca-e0f847068d52\",\n                    \"columns\":[\n                        {\n                            \"name\":\"login\",\n                            \"value\":\"utf8(userWithStatus@ippon.fr)\"\n                        },\n                        {\n                            \"name\":\"username\",\n                            \"value\":\"utf8(userWithStatus)\"\n                        },\n                        {\n                            \"name\":\"domain\",\n                            \"value\":\"utf8(ippon.fr)\"\n                        },\n                        {\n                            \"name\":\"content\",\n                            \"value\":\"utf8(Tatami is an enterprise social network)\"\n                        },\n                        {\n                            \"name\":\"statusDate\",\n                            \"value\":\"utf8(10/03/2012)\"\n                        }\n                    ]\n                },\n                {\n                    \"key\":\"f97d6470-9847-11e1-a6ca-e0f847068d52\",\n                    \"columns\":[\n                        {\n                            \"name\":\"login\",\n                            \"value\":\"utf8(userWithStatus@ippon.fr)\"\n                        },\n                        {\n                            \"name\":\"username\",\n                            \"value\":\"utf8(userWithStatus)\"\n                        },\n                        {\n                            \"name\":\"domain\",\n                            \"value\":\"utf8(ippon.fr)\"\n                        },\n                        {\n                            \"name\":\"content\",\n                            \"value\":\"utf8(Tatami is fully Open Source)\"\n                        },\n                        {\n                            \"name\":\"statusDate\",\n                            \"value\":\"utf8(11/03/2012)\"\n                        }\n                    ]\n                }\n            ]\n        },\n        {\n            \"name\":\"Discussion\",\n            \"keyType\":\"BytesType\",\n            \"comparatorType\":\"BytesType\",\n            \"defaultColumnValueType\":\"BytesType\"\n        },\n        {\n            \"name\":\"Shares\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UTF8Type\",\n            \"defaultColumnValueType\":\"UTF8Type\",\n            \"rows\":[\n                {\n                    \"key\":\"f97d6470-9847-11e1-a6ca-dummy1\",\n                    \"columns\":[\n                        {\n                            \"name\":\"111111111\",\n                            \"value\":\"utf8(john_doe)\"\n                        }\n                    ]\n                }\n            ]\n        },\n        {\n            \"name\":\"TagFollowers\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UTF8Type\",\n            \"defaultColumnValueType\":\"LongType\",\n            \"rows\":[\n                {\n                    \"key\":\"test-ippon.fr\",\n                    \"columns\":[\n                        {\n                            \"name\":\"jdubois@ippon.fr\",\n                            \"value\":\"0\"\n                        }\n                    ]\n                }\n            ]\n        },\n        {\n            \"name\":\"Group\",\n            \"keyType\":\"BytesType\",\n            \"comparatorType\":\"BytesType\",\n            \"defaultColumnValueType\":\"BytesType\"\n        },\n        {\n            \"name\":\"GroupCounter\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UTF8Type\",\n            \"defaultColumnValueType\":\"CounterColumnType\"\n        },\n        {\n            \"name\":\"GroupDetails\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UTF8Type\",\n            \"defaultColumnValueType\":\"UTF8Type\"\n        },\n        {\n            \"name\":\"UserGroups\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UTF8Type\",\n            \"defaultColumnValueType\":\"UTF8Type\"\n        },\n        {\n            \"name\":\"GroupMembers\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UTF8Type\",\n            \"defaultColumnValueType\":\"UTF8Type\"\n        },\n        {\n            \"name\":\"Trends\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UUIDType\",\n            \"defaultColumnValueType\":\"UTF8Type\"\n        },\n        {\n            \"name\":\"UserTrends\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UUIDType\",\n            \"defaultColumnValueType\":\"UTF8Type\"\n        },\n        {\n            \"name\":\"TagCounter\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UTF8Type\",\n            \"defaultColumnValueType\":\"CounterColumnType\"\n        },\n        {\n            \"name\":\"Mentionline\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UUIDType\",\n            \"defaultColumnValueType\":\"UTF8Type\"\n        },\n        {\n            \"name\":\"Groupline\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UUIDType\",\n            \"defaultColumnValueType\":\"UTF8Type\"\n        },\n        {\n            \"name\":\"Rss\",\n            \"keyType\":\"BytesType\",\n            \"comparatorType\":\"BytesType\",\n            \"defaultColumnValueType\":\"BytesType\"\n        },\n        {\n            \"name\":\"Registration\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"BytesType\",\n            \"defaultColumnValueType\":\"BytesType\"\n        },\n        {\n            \"name\":\"UserTags\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UTF8Type\"\n        },\n        {\n            \"name\":\"UsersBlocked\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UTF8Type\",\n            \"defaultColumnValueType\":\"LongType\"\n        },\n        {\n            \"name\":\"ReportedStatus\",\n            \"keyType\":\"UTF8Type\",\n            \"comparatorType\":\"UTF8Type\",\n            \"defaultColumnValueType\":\"UTF8Type\"\n        }\n    ]\n}"
  },
  {
    "path": "services/src/test/resources/logback.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\n<configuration scan=\"true\">\n    <appender name=\"CONSOLE\" class=\"ch.qos.logback.core.ConsoleAppender\">\n        <encoder>\n            <charset>utf-8</charset>\n            <Pattern>[%p] %c - %m%n</Pattern>\n        </encoder>\n    </appender>\n\n    <logger name=\"fr.ippon.tatami\" level=\"DEBUG\"/>\n    <logger name=\"ch.qos.logback\" level=\"WARN\"/>\n    <logger name=\"com.yammer.metrics\" level=\"WARN\"/>\n    <logger name=\"com.notnoop\" level=\"WARN\"/>\n    <logger name=\"me.prettyprint\" level=\"WARN\"/>\n    <logger name=\"net.sf.ehcache\" level=\"WARN\"/>\n    <logger name=\"netty\" level=\"WARN\"/>\n    <logger name=\"org.apache\" level=\"WARN\"/>\n    <logger name=\"org.atmosphere\" level=\"WARN\"/>\n    <logger name=\"org.elasticsearch\" level=\"WARN\"/>\n    <logger name=\"org.hibernate.validator\" level=\"WARN\"/>\n    <logger name=\"org.openid4java\" level=\"WARN\"/>\n    <logger name=\"org.springframework\" level=\"WARN\"/>\n    <logger name=\"org.springframework.web\" level=\"WARN\"/>\n    <logger name=\"org.springframework.security\" level=\"WARN\"/>\n    <logger name=\"org.springframework.cache\" level=\"WARN\"/>\n    <logger name=\"ro.isdc\" level=\"WARN\"/>\n\n    <root level=\"DEBUG\">\n        <appender-ref ref=\"CONSOLE\"/>\n    </root>\n\n</configuration>"
  },
  {
    "path": "services/src/test/resources/tatami/tatami-test.properties",
    "content": "# tatami.version can (should) be used to version static resources and thus enable a long cache value.\ntatami.version=1.0-SNAPSHOT\ntatami.url=https://tatami.ippon.fr\n\n#User configuration\ntatami.admin.users=tatami@ippon.fr\n\n#E-mail configuration\nsmtp.host=mail.ippon.fr\nsmtp.port=25\nsmtp.user=\nsmtp.password=\nsmtp.from=tatami@ippon.fr\n\n#Cassandra configuration\ncassandra.host=localhost:9171\ncassandra.cluster=Tatami cluster\ncassandra.keyspace=tatami\n\n#Elastic Search configuration\nelasticsearch.engine.mode=embedded\n\nelasticsearch.indexNamePrefix=tatami\nelasticsearch.cluster.name=tatamiCluster\nelasticsearch.cluster.nodes=127.0.0.1\nelasticsearch.cluster.default.communication.port=9300\n"
  },
  {
    "path": "src/integration/java/fr/ippon/tatami/test/support/LdapTestServer.java",
    "content": "/*\r\n * Licensed to the Apache Software Foundation (ASF) under one\r\n * or more contributor license agreements.  See the NOTICE file\r\n * distributed with this work for additional information\r\n * regarding copyright ownership.  The ASF licenses this file\r\n * to you under the Apache License, Version 2.0 (the\r\n * \"License\"); you may not use this file except in compliance\r\n * with the License.  You may obtain a copy of the License at\r\n *\r\n *  http://www.apache.org/licenses/LICENSE-2.0\r\n *\r\n * Unless required by applicable law or agreed to in writing,\r\n * software distributed under the License is distributed on an\r\n * \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\r\n * KIND, either express or implied.  See the License for the\r\n * specific language governing permissions and limitations\r\n * under the License.\r\n */\r\npackage fr.ippon.tatami.test.support;\r\n\r\nimport java.io.BufferedReader;\r\nimport java.io.File;\r\nimport java.io.InputStream;\r\nimport java.io.InputStreamReader;\r\nimport java.util.ArrayList;\r\nimport java.util.List;\r\n\r\nimport org.apache.commons.io.FileUtils;\r\nimport org.apache.directory.server.core.DefaultDirectoryService;\r\nimport org.apache.directory.server.core.DirectoryService;\r\nimport org.apache.directory.server.core.entry.ServerEntry;\r\nimport org.apache.directory.server.core.partition.Partition;\r\nimport org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmPartition;\r\nimport org.apache.directory.server.ldap.LdapServer;\r\nimport org.apache.directory.server.protocol.shared.transport.TcpTransport;\r\nimport org.apache.directory.shared.ldap.entry.Entry;\r\nimport org.apache.directory.shared.ldap.entry.EntryAttribute;\r\nimport org.apache.directory.shared.ldap.entry.Modification;\r\nimport org.apache.directory.shared.ldap.entry.ModificationOperation;\r\nimport org.apache.directory.shared.ldap.entry.Value;\r\nimport org.apache.directory.shared.ldap.entry.client.ClientModification;\r\nimport org.apache.directory.shared.ldap.entry.client.DefaultClientAttribute;\r\nimport org.apache.directory.shared.ldap.exception.LdapNameNotFoundException;\r\nimport org.apache.directory.shared.ldap.ldif.LdifEntry;\r\nimport org.apache.directory.shared.ldap.ldif.LdifReader;\r\nimport org.apache.directory.shared.ldap.name.LdapDN;\r\nimport org.elasticsearch.common.collect.Lists;\r\n\r\n/**\r\n * An embedded ldap test server Based on\r\n * http://directory.apache.org/apacheds/1.5/41-embedding-apacheds-into-an-application.html\r\n */\r\npublic class LdapTestServer {\r\n    /**\r\n     * The directory service\r\n     */\r\n    private DirectoryService service;\r\n\r\n    public DirectoryService getService() {\r\n        return service;\r\n    }\r\n\r\n    /**\r\n     * The LDAP server\r\n     */\r\n    private LdapServer server;\r\n\r\n    private static File workingDir = new File(\"target/ldapServer\");\r\n\r\n    private Partition addPartition(String partitionId, String partitionDn) throws Exception {\r\n        // Create a new partition named 'ippon'.\r\n        Partition partition = new JdbmPartition();\r\n        partition.setId(partitionId);\r\n        partition.setSuffix(partitionDn);\r\n        service.addPartition(partition);\r\n\r\n        return partition;\r\n    }\r\n\r\n    public void start() throws Exception {\r\n        // Initialize the LDAP service\r\n        service = new DefaultDirectoryService();\r\n\r\n        service.setWorkingDirectory(workingDir);\r\n\r\n        // Disable the ChangeLog system\r\n        service.getChangeLog().setEnabled(false);\r\n        service.setDenormalizeOpAttrsEnabled(true);\r\n\r\n        Partition ipponPartition = addPartition(\"ippon\", \"dc=ippon,dc=fr\");\r\n\r\n        // And start the service\r\n        service.startup();\r\n\r\n        // Inject the ippon root entry if it does not already exist\r\n        try {\r\n            service.getAdminSession().lookup(ipponPartition.getSuffixDn());\r\n            System.out.printf(\"Root %s found ! %n\", ipponPartition.getSuffixDn());\r\n        } catch (LdapNameNotFoundException lnnfe) {\r\n            System.out.printf(\"Root %s not found ! creating it ... %n\", ipponPartition.getSuffixDn());\r\n\r\n            LdapDN dnippon = new LdapDN(\"dc=ippon,dc=fr\");\r\n            ServerEntry entryippon = service.newEntry(dnippon);\r\n            entryippon.add(\"objectClass\", \"top\", \"domain\", \"extensibleObject\");\r\n            entryippon.add(\"dc\", \"ippon\");\r\n            service.getAdminSession().add(entryippon);\r\n\r\n            System.out.printf(\"Importing some data ... %n\", ipponPartition.getSuffixDn());\r\n            InputStream is = this.getClass().getResource(\"ipponTestLdapExport.ldif\").openStream();\r\n            LdifReader ldifReader = new LdifReader(is);\r\n            for (LdifEntry entry : ldifReader) {\r\n                injectEntry(entry, service);\r\n            }\r\n            is.close();\r\n\r\n        }\r\n\r\n        // service LDAP :\r\n        server = new LdapServer();\r\n        // int serverPort = 10389;\r\n        int serverPort = 389;\r\n        server.setTransports(new TcpTransport(serverPort));\r\n        server.setDirectoryService(service);\r\n\r\n        server.start();\r\n    }\r\n\r\n    public void replaceAttribute(String dn, String attName, String value) throws Exception {\r\n        LdapDN ldapDN = new LdapDN(dn);\r\n        EntryAttribute attribute = new DefaultClientAttribute(attName, value);\r\n        Modification m = new ClientModification(ModificationOperation.REPLACE_ATTRIBUTE, attribute);\r\n        List<Modification> l = Lists.newArrayList(m);\r\n        service.getAdminSession().modify(ldapDN, l);\r\n    }\r\n\r\n    private static void injectEntry(LdifEntry entry, DirectoryService service) throws Exception {\r\n        if (entry.isChangeAdd()) {\r\n            ServerEntry serverEntry = service.newEntry(entry.getDn());\r\n            for (EntryAttribute entryAttribute : entry.getEntry()) {\r\n                List<Value<?>> allValue = new ArrayList<Value<?>>();\r\n                for (Value<?> value : entryAttribute) {\r\n                    allValue.add(value);\r\n                }\r\n                serverEntry.add(entryAttribute.getId(), allValue.toArray(new Value[0]));\r\n            }\r\n            service.getAdminSession().add(serverEntry);\r\n            // service.getAdminSession().add( new DefaultServerEntry( service.getSchemaManager(), entry.getEntry() ) );\r\n        } else if (entry.isChangeModify()) {\r\n            // not used, not tested ...\r\n            service.getAdminSession().modify(entry.getDn(), entry.getModificationItems());\r\n        } else {\r\n            throw new IllegalArgumentException(\"bug\");\r\n        }\r\n    }\r\n\r\n    public void stop() throws Exception {\r\n        server.stop();\r\n        service.shutdown();\r\n    }\r\n\r\n    /**\r\n     * Creates a new instance of EmbeddedADS. It initializes the directory service.\r\n     *\r\n     * @throws Exception If something went wrong\r\n     */\r\n    public LdapTestServer() throws Exception {\r\n    }\r\n\r\n    /**\r\n     * Main class. We just do a lookup on the server to check that it's available.\r\n     * <p/>\r\n     * FIXME : in Eclipse : when running this classes as \"Java Application\", target/test-classes is not added in the classpath\r\n     * resulting in a java.lang.ClassNotFoundException ...\r\n     *\r\n     * @param args Not used.\r\n     * @throws Exception\r\n     */\r\n    public static void main(String[] args) throws Exception {\r\n        FileUtils.deleteDirectory(workingDir);\r\n\r\n        LdapTestServer ads = null;\r\n        try {\r\n            // Create the server\r\n            ads = new LdapTestServer();\r\n            ads.start();\r\n\r\n            // Read an entry\r\n            Entry result = ads.service.getAdminSession().lookup(new LdapDN(\"dc=ippon,dc=fr\"));\r\n\r\n            // And print it if available\r\n            System.out.println(\"Found entry : \" + result);\r\n\r\n        } catch (Exception e) {\r\n            // Ok, we have something wrong going on ...\r\n            e.printStackTrace();\r\n        }\r\n        System.out.println(\"Press enter\");\r\n        new BufferedReader(new InputStreamReader(System.in)).readLine();\r\n        ads.stop();\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "src/integration/java/fr/ippon/tatami/test/support/LdapTestServerJunitLauncher.java",
    "content": "package fr.ippon.tatami.test.support;\r\n\r\nimport org.junit.Test;\r\n\r\nimport static org.junit.Assert.*;\r\n\r\n/**\r\n * In Eclipse : when running LdapTestServer as \"Java Application\", target/test-classes is not added in the classpath\r\n * resulting in a java.lang.ClassNotFoundException ...\r\n * This is a workaround ...\r\n * <p/>\r\n * Note : this class name does NOT end with *Test (not to be executed by surefire maven plugin)\r\n */\r\npublic class LdapTestServerJunitLauncher {\r\n\r\n    @Test\r\n    public void test() throws Exception {\r\n        LdapTestServer.main(null);\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "src/integration/java/fr/ippon/tatami/uitest/AuthenticationSpec.groovy",
    "content": "package fr.ippon.tatami.uitest\r\n\r\nimport pages.*\r\nimport pages.google.*\r\nimport spock.lang.Shared\r\nimport fr.ippon.tatami.test.support.LdapTestServer\r\nimport fr.ippon.tatami.uitest.support.TatamiBaseGebSpec\r\n\r\nclass AuthenticationSpec extends TatamiBaseGebSpec {\r\n\t\r\n\t@Shared\r\n\tdef newUid\r\n\r\n\tstatic LdapTestServer ldapTestServer\r\n\tdef setupSpec() {\r\n\t\t// It only works if Tatami server is on the same host as the test ...\r\n\t\t// AND tatami server points to localhost to reach the ldap server !\r\n\t\t// TODO : fix tatami configuration !\r\n\t\t// TODO : put this into maven\r\n\t\tldapTestServer = new LdapTestServer();\r\n\t\tldapTestServer.start();\r\n\t\t\r\n\t\tnewUid = \"john_doe_${new Date().time}\".toString()\r\n\t\tldapTestServer.replaceAttribute(\"cn=john_doe,dc=ippon,dc=fr\", \"uid\", newUid)\r\n\t\t\r\n\t\tprintln \"ldap entry patched\"\r\n\t\t\r\n\t}\r\n\t\r\n\tdef cleanupSpec() {\r\n\t\tldapTestServer.stop();\r\n\t\tldapTestServer = null;\r\n\t}\r\n\t\t\t\r\n    def \"login as admin with ldap\"() {\r\n        given:\r\n        to LoginPage\r\n        verifyAt() \r\n\t\t\r\n        when:\r\n        loginForm.with {\r\n            j_username = \"jdubois@ippon.fr\"\r\n            j_password = \"ippon\"\r\n        }\r\n         \r\n        and:\r\n        loginButton.click()\r\n\t\t\r\n        then:\r\n        waitFor { at HomePage }\r\n\t\t\r\n\t\tand:\r\n\t\tadminLink.isPresent();\r\n\t\t\r\n    }\r\n\t\r\n\t// auto-registration with ldap : \r\n\tdef \"login as normal new user with ldap\"() {\r\n\t\t\t\t\r\n\t\tgiven:\r\n\t\tto LoginPage\r\n\t\tverifyAt()\r\n\t\t\r\n\t\twhen:\r\n\t\tdef username = \"$newUid@ippon.fr\"\r\n\t\tloginForm.with {\r\n//\t\t\tj_username = \"john_doe@ippon.fr\"\r\n\t\t\tj_username = username \r\n\t\t\tj_password = \"john\"\r\n\t\t}\r\n\t\t \r\n\t\tand:\r\n\t\tloginButton.click()\r\n\t\t \r\n\t\tthen:\r\n\t\twaitFor { at HomePage }\r\n\t\t\r\n        newUserWizard.isPresent()\r\n        // TODO : fill wizards\r\n\t\t\r\n\t\t! adminLink.isPresent()\r\n\t\tif(realBrowser()) {\r\n\t\t\t// doesn't work with htmlDriver (when javascript is disabled at least) :\r\n\t\t\tassert updateStatus !=null\r\n\t\t}\r\n\t}\r\n\t\r\n\t// TODO : should we explicitly test that new openid user can login (auto-registration) ?\r\n\t\r\n\tdef \"login as normal existing user with google\"() {\r\n\t\tgiven:\r\n\t\tdef googleEmail = System.getProperty(\"google.email\")\r\n\t\tdef googlePassword = System.getProperty(\"google.password\")\r\n\t\tassert googleEmail !=null\r\n\t\tassert googlePassword !=null\r\n\t\tto LoginPage\r\n\t\tverifyAt()\r\n\t\t// and google account not already accepting localhost ...\r\n\t\t\t\t\r\n\t\twhen: \"click on goodle authentication button\"\r\n\t\tgoogleButton.click()\r\n\t\t\r\n\t\tthen :\r\n\t\twaitFor { at GoogleAuthenticationPage }\r\n\t\t\r\n\t\twhen : \"enter credentials on google\"\r\n\t\tloginForm.with {\r\n\t\t\tEmail = googleEmail\r\n\t\t\tPasswd = googlePassword\r\n\t\t}\r\n\t\tloginButton.click()\r\n\t\t\r\n\t\tthen:\r\n\t\twaitFor { at GoogleOpenIdPage }\r\n\t\t\r\n\r\n\t\twhen: \"Authorize localhost to receive openid authentication on google\" \r\n\t\trememberChoicesCB.value(false)\r\n\t\tapproveButton.click()\r\n\t\t \r\n\t\tthen:\r\n\t\twaitFor { at HomePage } // Note : If it's a new user, the \"new user wizard\" will also shows up ... \r\n\t\t! adminLink.isPresent()\r\n\t\r\n\t}\r\n\t\r\n}"
  },
  {
    "path": "src/integration/java/fr/ippon/tatami/uitest/NewRegistrationSpec.groovy",
    "content": "package fr.ippon.tatami.uitest\r\n\r\nimport pages.*\r\nimport fr.ippon.tatami.uitest.support.TatamiBaseGebSpec\r\n\r\nclass NewRegistrationSpec extends TatamiBaseGebSpec {\r\n\t\r\n\tdef \"existing user can't register\"() {\r\n\t\tgiven:\r\n\t\tto LoginPage\r\n\t\tverifyAt()\r\n\t\tdef existingUserEmail = \"john_doe@ippon.fr\"\r\n//\t\taccountUtils.assertUserExists(existingUserEmail);\r\n        accountUtils.createUserIfNecessary(existingUserEmail);\r\n\t\t// TODO : use org.cassandraunit.DataLoader instead to create user before the test ?\r\n\t\t\r\n\t\twhen:\r\n\t\tregistrationForm.email = existingUserEmail\r\n\t\tregistrationButton.click()\r\n\t\t\r\n\t\tthen:\r\n\t\twaitFor { at LoginPage }\r\n\t\terrorAlert.isPresent()\r\n\t}\r\n\t\r\n    def \"register with new user email\"() {\r\n        given:\r\n        to LoginPage\r\n        verifyAt() \r\n\t\tdef newUserEmail = \"new_user_${new Date().time}@domain.fr\"\r\n\t\t\r\n        when: \"Filling register form\"\r\n        registrationForm.email = newUserEmail\r\n\t\tand: \"submit register form\"\r\n        registrationButton.click()\r\n\t\t\r\n        then: \"I'm at LoginPage with msg 'registration sent'\"\r\n        waitFor { at LoginPage }\r\n\t\t! errorAlert.isPresent()\r\n\t\tinfoAlert.isPresent()\r\n\t\t\r\n\t\twhen: \"Clicking on registration link (normally sent by email)\"\r\n\t\tdef registrationKey = registrationUtils.getRegistrationKeyByLogin(newUserEmail)\n//\t\tgo \"tatami/register?key=$registrationKey\"\r\n\t\tto([key:registrationKey], EmailVerifiedPage)\r\n\t\tverifyAt()\r\n\t\t\r\n\t\tthen: \"New user exist in DB\"\r\n\t\taccountUtils.assertUserExists(newUserEmail);\r\n\t\t\r\n\t\t// TODO : just testing for existence of user in DB is ok or should I try to log ? how ? password is encrypted in database\r\n//\t\twhen: \"Login with newly generated password\"\r\n//\t\t\r\n//\t\tto LoginPage\r\n//\t\tverifyAt()\r\n//\t\tpassword = \"\" // read or set in database ... \r\n//\t\tloginForm.with {\r\n//\t\t\tj_username = newUserEmail\r\n//\t\t\tj_password = password\r\n//\t\t}\r\n//\t\tloginButton.click()\r\n//\t\t \r\n//\t\tthen:\r\n//\t\twaitFor { at HomePage }\r\n//\t\t\r\n    }\r\n\t\r\n}"
  },
  {
    "path": "src/integration/java/fr/ippon/tatami/uitest/support/AccountUtils.groovy",
    "content": "package fr.ippon.tatami.uitest.support;\r\n\r\nimport Constants;\r\nimport User;\r\nimport CassandraCounterRepository;\r\nimport CassandraUserRepository;\r\n\r\n@Singleton\r\npublic class AccountUtils {\r\n\r\n    CassandraUserRepository getUserRepository() {\r\n        def keyspaceOperator = CassandraAccessUtils.instance.keyspaceOperator\r\n        def em = CassandraAccessUtils.instance.entityManager\r\n        def counterRepository = new CassandraCounterRepository(keyspaceOperator:keyspaceOperator)\r\n        def repository = new CassandraUserRepository(keyspaceOperator:keyspaceOperator,em:em,counterRepository:counterRepository)\r\n        return repository\r\n    }\r\n    \r\n    boolean userExists(String login) {\r\n        def userExists = getUserRepository().findUserByLogin(login) != null\r\n        return userExists;\r\n    }\r\n    \t\r\n\tvoid assertUserExists(String login) {\r\n\t\tassert userExists(login)\r\n\t}\r\n    \r\n    void createUserIfNecessary(String login) {\r\n        if(! userExists(login)) {\r\n            User user = new User()\r\n            user.setLogin(login);\r\n            user.setTheme(Constants.DEFAULT_THEME);\r\n            getUserRepository().createUser(user)\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "src/integration/java/fr/ippon/tatami/uitest/support/CassandraAccessUtils.groovy",
    "content": "package fr.ippon.tatami.uitest.support;\r\n\r\nimport static ColumnFamilyKeys.REGISTRATION_CF;\r\nimport me.prettyprint.cassandra.serializers.StringSerializer;\r\nimport me.prettyprint.hector.api.Keyspace;\r\nimport me.prettyprint.hector.api.beans.ColumnSlice;\r\nimport me.prettyprint.hector.api.beans.HColumn;\r\nimport me.prettyprint.hector.api.factory.HFactory;\r\nimport me.prettyprint.hector.api.query.ColumnQuery;\r\nimport me.prettyprint.hom.EntityManagerImpl;\r\n\r\nimport org.springframework.core.env.Environment;\r\nimport org.springframework.core.env.MapPropertySource;\r\nimport org.springframework.core.env.StandardEnvironment;\r\n\r\nimport CassandraConfiguration;\r\n\r\n@Singleton(lazy=true)\r\npublic class CassandraAccessUtils {\r\n\r\n\tKeyspace keyspaceOperator\r\n\tEntityManagerImpl entityManager\r\n\t\r\n\tCassandraAccessUtils() {\r\n\t\t// TODO : use tatami.properties or tatami-uitest.properties ?\r\n\t\tStandardEnvironment env = new StandardEnvironment()\r\n\t\tdef properties = [\r\n\t\t\t\t\"cassandra.host\" : \"127.0.0.1:9160\",\r\n\t\t\t\t\"cassandra.clusterName\" : \"Tatami cluster\",\r\n\t\t\t\t\"cassandra.keyspace\" : \"tatami\"\r\n\t\t\t\t]\r\n\t\tdef propSource = new MapPropertySource(\"testProps\",properties);\r\n\t\tenv.getPropertySources().addFirst(propSource)\r\n\t\tCassandraConfiguration configuration = new CassandraConfiguration();\r\n\t\tconfiguration.env = env\r\n\t\tkeyspaceOperator =  configuration.keyspaceOperator()\r\n\t\tentityManager =  configuration.entityManager(keyspaceOperator)\r\n\t}\r\n\t\r\n\r\n}\r\n"
  },
  {
    "path": "src/integration/java/fr/ippon/tatami/uitest/support/RegistrationUtils.groovy",
    "content": "package fr.ippon.tatami.uitest.support;\r\n\r\nimport CassandraRegistrationRepository;\r\n\r\n@Singleton\r\npublic class RegistrationUtils {\r\n\t\r\n\tString getRegistrationKeyByLogin(String login) {\r\n\t\tdef keyspaceOperator = CassandraAccessUtils.getInstance().getKeyspaceOperator()\r\n\t\tdef repository = new CassandraRegistrationRepository(keyspaceOperator:keyspaceOperator)\r\n\t\t\r\n\t\tdef registrationsByLogin = repository._getAllRegistrationKeyByLogin()\r\n\t\treturn registrationsByLogin[login]\t\t\r\n\t}\r\n}\r\n"
  },
  {
    "path": "src/integration/java/fr/ippon/tatami/uitest/support/TatamiBaseGebSpec.groovy",
    "content": "package fr.ippon.tatami.uitest.support;\r\n\r\nimport org.openqa.selenium.htmlunit.HtmlUnitDriver;\r\n\r\nimport geb.spock.GebSpec;\r\n\r\npublic abstract class TatamiBaseGebSpec extends GebSpec {\r\n\t\r\n\tstatic {\r\n//\t\t// TODO : il doit y avoir un moyen plus simple/propre de choisir le driver : (cf GebConfig aussi)\r\n//\t\t// by default we use HtmlUnit (cf GebConfig.groovy )\r\n//\t\t// FIXME : delete this :\r\n//\t\tif(!System.getProperty('gev.env')) {\r\n//\t\t\tSystem.setProperty('geb.env',\"chrome\")\r\n////\t\t\tSystem.setProperty('geb.env',\"firefox\")\r\n//\t\t}\r\n\t}\r\n\t\r\n\tboolean realBrowser() {\r\n\t\t! (getBrowser().getDriver() instanceof HtmlUnitDriver)\r\n\t}\r\n\t\r\n\tRegistrationUtils getRegistrationUtils() {\r\n\t\treturn RegistrationUtils.getInstance();\r\n\t}\r\n\tAccountUtils getAccountUtils() {\r\n\t\treturn AccountUtils.getInstance();\r\n\t}\r\n\t\r\n}\r\n"
  },
  {
    "path": "src/integration/java/pages/EmailVerifiedPage.groovy",
    "content": "package pages\r\n\r\nimport geb.Page;\r\n\r\nclass EmailVerifiedPage extends Page {\r\n    static url = \"tatami/register\" // to be use with a param 'key' ?key=86273322226868972417\"\r\n \r\n    static at = { $(\"p\",text:contains(\"Your password will be e-mailed to you\"))}\r\n \r\n}\r\n"
  },
  {
    "path": "src/integration/java/pages/HomePage.groovy",
    "content": "package pages\r\n\r\nimport geb.Page;\r\n\r\nclass HomePage extends TatamiBasePage {\r\n    static url = \"tatami/\"\r\n \r\n    static at = { profileContent != null } // sometimes I got an error here ?!\r\n                // TODO : add \" or newUserWizard != null\" if necessary\r\n \r\n    static content = {\r\n\t\t// défini dans la classe mère :\r\n//\t\tdropDownMenu\r\n//    \tadminLink\r\n\r\n\t\tprofileContent { $(\"div#profileContent\") }\r\n\t  \r\n\t\t// les contenus ci-dessous ne sont accessibles qu'avec le javascript puisque les div sont chargés vides ... // TODO : tjs vrai ?\r\n\t\tupdateStatus { $(\"textarea#updateStatusContent\") }\r\n        \r\n        newUserWizard { $(\"div#modal-welcome\") }\r\n\t\t\r\n    }\r\n}"
  },
  {
    "path": "src/integration/java/pages/LoginPage.groovy",
    "content": "package pages\r\n \r\nimport geb.Page\r\n \r\nclass LoginPage extends Page {\r\n    static url = \"tatami/login\"\r\n \r\n    static at = { $(\"h1\",text:contains(\"Welcome to Tatami\")) }\r\n \r\n    static content = {\r\n\t\t\r\n\t\terrorAlert(required:false) { $(\"div.alert-error\",text:contains(\"e-mail address is already in used\")) }\r\n\t\tinfoAlert(required:false) { $(\"div.alert-info\",text:contains(\"registration e-mail\")) }\r\n\t\t\r\n\t\tregistrationForm { $(\"#registrationForm\") }\r\n\t\tregistrationButton { $(\"#registrationButton\") }\r\n\t\t\r\n        loginForm { $(\"#loginForm\") }\r\n\t\tloginButton { $(\"#loginButton\") }\r\n//\t\tgoogleForm { $(\"#googleForm\") }\r\n\t\tgoogleButton { $(\"#proceed_google\") }\r\n    }\r\n}"
  },
  {
    "path": "src/integration/java/pages/TatamiBasePage.groovy",
    "content": "package pages\r\n\r\nimport geb.Page;\r\n\r\nclass TatamiBasePage extends Page {\r\n\r\n\tstatic content = {\r\n\t\tdropDownMenu { $(\"ul.dropdown-menu\") } // <ul class=\"dropdown-menu\">\r\n\t\tadminLink(required: false) {\r\n\t\t\t// <a href=\"/tatami/admin\"> // href returns absolute url so we need to filter with endsWith ...\r\n\t\t\tdropDownMenu.find(\"a\",href:endsWith('/tatami/admin'))\r\n\t\t}\r\n\t}\r\n\t\r\n}\r\n"
  },
  {
    "path": "src/integration/java/pages/google/GoogleAuthenticationPage.groovy",
    "content": "package pages.google\r\n\r\nimport geb.Browser;\r\nimport geb.Page\r\n\r\nclass GoogleAuthenticationPage extends Page {\r\n\r\n\tstatic at = {\r\n\t\tloginForm.isPresent()\r\n\t}\r\n\t\r\n\tstatic content = {\r\n\t\tloginForm { $(\"form#gaia_loginform\") }\r\n\t\tloginButton { $(\"input#signIn\") }\r\n\t}\r\n}\r\n"
  },
  {
    "path": "src/integration/java/pages/google/GoogleOpenIdPage.groovy",
    "content": "package pages.google\r\n\r\nimport geb.Page\r\n\r\nclass GoogleOpenIdPage extends Page {\r\n\r\n\tstatic at = {\r\n\t\tapproveButton.isPresent()\r\n\t}\r\n\t\r\n\tstatic content = {\r\n\t\tloginForm { $(\"form\") }\t\t\r\n\t\trememberChoicesCB { $(\"input#remember_choices_checkbox\") }\r\n\t\tapproveButton { $(\"#approve_button\") }\r\n\t}\r\n}\r\n"
  },
  {
    "path": "src/integration/resources/GebConfig.groovy",
    "content": "/*\r\n This is the Geb configuration file.\r\n See: http://www.gebish.org/manual/current/configuration.html\r\n */\r\n\r\nimport org.openqa.selenium.Capabilities;\r\nimport org.openqa.selenium.htmlunit.HtmlUnitDriver\r\nimport org.openqa.selenium.remote.DesiredCapabilities;\r\nimport org.openqa.selenium.firefox.FirefoxDriver\r\nimport org.openqa.selenium.firefox.FirefoxProfile\r\nimport org.openqa.selenium.chrome.ChromeDriver\r\nimport org.openqa.selenium.chrome.ChromeOptions\r\n\r\nimport com.gargoylesoftware.htmlunit.BrowserVersion\r\n\r\nbaseUrl = \"http://localhost:8080/\"\r\n\r\ndef forcedLocale = \"en\"\r\n\r\n//// See: http://code.google.com/p/selenium/wiki/HtmlUnitDriver\r\n//driver = {\r\n//\tdef browserVersion = BrowserVersion.getDefault()\r\n//\tbrowserVersion.setSystemLanguage(forcedLocale)\r\n//\tbrowserVersion.setBrowserLanguage(forcedLocale)\r\n//\tbrowserVersion.setUserLanguage(forcedLocale)\r\n//\tdef driver = new HtmlUnitDriver(browserVersion)\r\n////\tdriver.javascriptEnabled = true // raphael.js fails to be executed by HtmlUnitDriver\r\n//\tdriver\r\n//}\r\n\r\nFirefoxProfile p = new FirefoxProfile();\r\np.setPreference( \"intl.accept_languages\", forcedLocale );\r\ndriver = { new FirefoxDriver(p) }\r\n\r\nenvironments {\r\n\r\n\t// run as “mvn -Dgeb.env=chrome test”\r\n\t// See: http://code.google.com/p/selenium/wiki/ChromeDriver\r\n\tchrome {\r\n\t\tif(!System.getProperty('webdriver.chrome.driver')) {\r\n\t\t\tSystem.setProperty('webdriver.chrome.driver',\"C:\\\\products\\\\chromedriver_win_22_0_1203_0b\\\\chromedriver.exe\")\r\n\t\t}\t\t\r\n\t\tDesiredCapabilities capabilities = new DesiredCapabilities()\r\n\t\t// available capabilities can be find in %USER_HOME%\\AppData\\Local\\Google\\Chrome\\User Data\\default\\preferences\r\n\t\tdef prefs = [\"intl.accept_languages\":forcedLocale] // Map\r\n\t\tcapabilities.setCapability(\"chrome.prefs\",prefs);\r\n\t\tdriver = { new ChromeDriver(capabilities) }\r\n\t}\r\n\r\n\t// run as “mvn -Dgeb.env=firefox test”\r\n\t// See: http://code.google.com/p/selenium/wiki/FirefoxDriver\r\n\tfirefox {\r\n\t\tFirefoxProfile profile = new FirefoxProfile();\r\n\t\tprofile.setPreference( \"intl.accept_languages\", forcedLocale );\r\n\t\tdriver = { new FirefoxDriver(profile) }\r\n\t}\r\n\r\n}\r\n\r\n"
  },
  {
    "path": "src/integration/resources/fr/ippon/tatami/test/support/ipponTestLdapExport.ldif",
    "content": "version: 1\r\n\r\ndn: cn=tatami,dc=ippon,dc=fr\r\nobjectClass: organizationalPerson\r\nobjectClass: person\r\nobjectClass: inetOrgPerson\r\nobjectClass: top\r\ncn: tatami\r\nsn: tatami\r\nuid: tatami\r\nuserPassword:: e1NIQX1sK2lzNUhobFUya1BoTWh4V1pVMnZmSUIvZ289\r\n\r\ndn: cn=jdubois,dc=ippon,dc=fr\r\nobjectClass: organizationalPerson\r\nobjectClass: person\r\nobjectClass: inetOrgPerson\r\nobjectClass: top\r\ncn: jdubois\r\nsn: jdubois\r\nuid: jdubois\r\nuserPassword:: e1NIQX1sK2lzNUhobFUya1BoTWh4V1pVMnZmSUIvZ289\r\n\r\ndn: cn=john_doe,dc=ippon,dc=fr\r\nobjectClass: organizationalPerson\r\nobjectClass: person\r\nobjectClass: inetOrgPerson\r\nobjectClass: top\r\ncn: john_doe\r\nsn: john_doe\r\nuid: john_doe\r\nuserPassword:: e1NIQX1wUjNhZkgvMUMySHE2Z1JFTng5S2FwTUI1UUU9\r\n"
  },
  {
    "path": "src/main/cql/install.cql",
    "content": "create keyspace tatami\n  with placement_strategy = 'SimpleStrategy'\n  and strategy_options = {replication_factor : 1}\n  and durable_writes = true;\n\nuse tatami;\n\ncreate column family Counter\n  with column_type = 'Standard'\n  and comparator = 'UTF8Type'\n  and default_validation_class = 'CounterColumnType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Dayline\n  with column_type = 'Standard'\n  and comparator = 'UTF8Type'\n  and default_validation_class = 'CounterColumnType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Discussion\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Domain\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Favline\n  with column_type = 'Standard'\n  and comparator = 'UUIDType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Followers\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Friends\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Registration\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Rss\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family MailDigest\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Shares\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Status\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Tagline\n  with column_type = 'Standard'\n  and comparator = 'UUIDType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Timeline\n  with column_type = 'Standard'\n  and comparator = 'UUIDType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family TimelineShares\n  with column_type = 'Standard'\n  and comparator = 'UUIDType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family User\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Userline\n  with column_type = 'Standard'\n  and comparator = 'UUIDType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family UserlineShares\n  with column_type = 'Standard'\n  and comparator = 'UUIDType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Trends\n  with column_type = 'Standard'\n  and comparator = 'UUIDType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family TagFollowers\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family UserTags\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family TagCounter\n  with column_type = 'Standard'\n  and comparator = 'UTF8Type'\n  and default_validation_class = 'CounterColumnType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family UserTrends\n  with column_type = 'Standard'\n  and comparator = 'UUIDType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Mentionline\n  with column_type = 'Standard'\n  and comparator = 'UUIDType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Group\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family GroupDetails\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family GroupMembers\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family UserGroups\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family GroupCounter\n  with column_type = 'Standard'\n  and comparator = 'UTF8Type'\n  and default_validation_class = 'CounterColumnType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Groupline\n  with column_type = 'Standard'\n  and comparator = 'UUIDType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family TatamiBotDuplicate\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Attachment\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family UserAttachments\n  with column_type = 'Standard'\n  and comparator = 'UUIDType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family StatusAttachments\n  with column_type = 'Standard'\n  and comparator = 'UUIDType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family DomainConfiguration\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Domainline\n  with column_type = 'Standard'\n  and comparator = 'UUIDType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family DomainTatamibot\n  with column_type = 'Standard'\n  and comparator = 'UUIDType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family TatamibotConfiguration\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Avatar\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family AppleDevice\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family AppleDeviceUser\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\n\n"
  },
  {
    "path": "src/main/cql/upgrade/upgrade_from_1.0.27_to_2.0.0.cql",
    "content": "create column family Rss\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Attachment\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family UserAttachments\n  with column_type = 'Standard'\n  and comparator = 'UUIDType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family StatusAttachments\n  with column_type = 'Standard'\n  and comparator = 'UUIDType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family DomainConfiguration\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family MailDigest\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n"
  },
  {
    "path": "src/main/cql/upgrade/upgrade_from_2.0.0_to_2.1.0.cql",
    "content": "create column family Domainline\n  with column_type = 'Standard'\n  and comparator = 'UUIDType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n"
  },
  {
    "path": "src/main/cql/upgrade/upgrade_from_2.1.3_to_2.2.0.cql",
    "content": "create column family DomainTatamibot\n  with column_type = 'Standard'\n  and comparator = 'UUIDType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family TatamibotConfiguration\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family Avatar\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\n"
  },
  {
    "path": "src/main/cql/upgrade/upgrade_from_3.0.26_to_3.0.27.cql",
    "content": "create column family AppleDevice\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\ncreate column family AppleDeviceUser\n  with column_type = 'Standard'\n  and comparator = 'BytesType'\n  and default_validation_class = 'BytesType'\n  and key_validation_class = 'BytesType'\n  and read_repair_chance = 1.0\n  and dclocal_read_repair_chance = 0.0\n  and gc_grace = 864000\n  and min_compaction_threshold = 4\n  and max_compaction_threshold = 32\n  and replicate_on_write = true\n  and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n  and caching = 'KEYS_ONLY'\n  and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};\n\n create column family UsersBlocked\n    with column_type = 'Standard'\n    and comparator = 'BytesType'\n    and default_validation_class = 'BytesType'\n    and key_validation_class = 'BytesType'\n    and read_repair_chance = 1.0\n    and dclocal_read_repair_chance = 0.0\n    and gc_grace = 864000\n    and min_compaction_threshold = 4\n    and max_compaction_threshold = 32\n    and replicate_on_write = true\n    and compaction_strategy = 'org.apache.cassandra.db.compaction.SizeTieredCompactionStrategy'\n    and caching = 'KEYS_ONLY'\n    and compression_options = {'sstable_compression' : 'org.apache.cassandra.io.compress.SnappyCompressor'};"
  },
  {
    "path": "tatamibot/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <artifactId>tatami</artifactId>\n        <groupId>fr.ippon.tatami</groupId>\n        <version>4.0.5</version>\n    </parent>\n    <modelVersion>4.0.0</modelVersion>\n\n    <artifactId>tatamibot</artifactId>\n\n    <dependencies>\n        <dependency>\n            <groupId>fr.ippon.tatami</groupId>\n            <artifactId>services</artifactId>\n            <version>4.0.5</version>\n        </dependency>\n    </dependencies>\n    <build>\n        <finalName>tatamibot-${project.version}</finalName>\n    </build>\n\n</project>"
  },
  {
    "path": "tatamibot/src/main/java/fr/ippon/tatami/bot/Tatamibot.java",
    "content": "package fr.ippon.tatami.bot;\n\nimport fr.ippon.tatami.bot.config.TatamibotConfiguration;\nimport fr.ippon.tatami.bot.route.GitHubRouteBuilder;\nimport fr.ippon.tatami.bot.route.RssRouteBuilder;\nimport fr.ippon.tatami.bot.route.SourceRouteBuilderBase;\nimport fr.ippon.tatami.bot.route.TwitterRouteBuilder;\nimport fr.ippon.tatami.config.Constants;\nimport fr.ippon.tatami.domain.Domain;\nimport fr.ippon.tatami.repository.DomainRepository;\nimport fr.ippon.tatami.repository.TatamibotConfigurationRepository;\nimport fr.ippon.tatami.service.UserService;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport org.apache.camel.builder.RouteBuilder;\nimport org.apache.camel.spi.IdempotentRepository;\nimport org.joda.time.DateTime;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Component;\n\nimport javax.inject.Inject;\n\n/**\n * The Tatami Robot.\n */\n@Component\npublic class Tatamibot extends RouteBuilder {\n\n    private static final Logger log = LoggerFactory.getLogger(Tatamibot.class);\n\n\n    @Inject\n    private IdempotentRepository<String> idempotentRepository;\n\n    @Inject\n    private DomainRepository domainRepository;\n\n    @Inject\n    private TatamibotConfigurationRepository tatamibotConfigurationRepository;\n\n    @Inject\n    private UserService userService;\n\n    @Override\n    public void configure() {\n\n        log.info(\"Configuring the Tatami Bot\");\n        for (Domain domain : domainRepository.getAllDomains()) {\n            log.debug(\"Configuring Bot for domain {}\", domain.getName());\n            String tatamiBotLogin = getTatamiBotLogin(domain);\n\n            for (TatamibotConfiguration configuration :\n                    tatamibotConfigurationRepository.findTatamibotConfigurationsByDomain(domain.getName())) {\n\n                log.debug(\"Configuring Bot : {}\", configuration);\n\n\n                SourceRouteBuilderBase subBuilder = null;\n                if (configuration.getType().equals(TatamibotConfiguration.TatamibotType.RSS)) {\n                    subBuilder = new RssRouteBuilder();\n\n                } else if (configuration.getType().equals(TatamibotConfiguration.TatamibotType.TWITTER)) {\n                    subBuilder = new TwitterRouteBuilder();\n\n                } else if (configuration.getType().equals(TatamibotConfiguration.TatamibotType.GIT)) {\n                    subBuilder = new GitHubRouteBuilder();\n                }\n\n                if (subBuilder != null) {\n                    subBuilder.setConfiguration(configuration);\n                    subBuilder.setTatamiBotLogin(tatamiBotLogin);\n                    subBuilder.setIdempotentRepository(idempotentRepository);\n                    addRoutesToContext(subBuilder);\n                }\n            }\n        }\n    }\n\n    private void addRoutesToContext(RouteBuilder builder) {\n        try {\n            getContext().addRoutes(builder);\n        } catch (Exception e) {\n            throw new RuntimeException(\"Unexpected error when configuring a route\", e);\n        }\n    }\n\n    private String getTatamiBotLogin(Domain domain) {\n        String tatamiBotLogin = DomainUtil.getLoginFromUsernameAndDomain(Constants.TATAMIBOT_NAME, domain.getName());\n        automaticBotCreation(domain, tatamiBotLogin);\n        return tatamiBotLogin;\n    }\n\n    private void automaticBotCreation(Domain domain, String tatamiBotLogin) {\n        if (userService.getUserByLogin(tatamiBotLogin) == null) {\n            log.info(\"Tatami Bot user does not exist for domain \" + domain.getName() + \" - creating it\");\n            userService.createTatamibot(domain.getName());\n            if (\"ippon.fr\".equals(domain.getName())){\n                log.info(\"Creating a default RSS robot for ippon.fr\");\n                TatamibotConfiguration configuration = new TatamibotConfiguration();\n                configuration.setType(TatamibotConfiguration.TatamibotType.RSS);\n                configuration.setDomain(\"ippon.fr\");\n                configuration.setUrl(\"http://feeds.feedburner.com/LeBlogDesExpertsJ2ee?format=xml\");\n                configuration.setPollingDelay(60);\n                DateTime lastUpdateDate = DateTime.parse(\"2013-01-01T00:00:00\");\n                configuration.setLastUpdateDate(lastUpdateDate.toDate());\n                configuration.setTag(\"BlogIppon\");\n                tatamibotConfigurationRepository.insertTatamibotConfiguration(configuration);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tatamibot/src/main/java/fr/ippon/tatami/bot/config/TatamibotConfiguration.java",
    "content": "package fr.ippon.tatami.bot.config;\n\nimport org.joda.time.DateTime;\nimport org.joda.time.format.DateTimeFormatter;\nimport org.joda.time.format.ISODateTimeFormat;\n\nimport javax.persistence.Column;\nimport javax.persistence.Entity;\nimport javax.persistence.Id;\nimport javax.persistence.Table;\nimport java.util.Date;\n\n/**\n * Configuration class for the Tatamibot.\n */\n@Entity\n@Table(name = \"TatamibotConfiguration\")\npublic class TatamibotConfiguration {\n\n    public static class TatamibotType {\n\n        public static final String RSS = \"RSS\";\n\n        public static final String TWITTER = \"TWITTER\";\n\n        public static final String GIT = \"GIT\";\n\n    }\n\n    @Column(name = \"id\")\n    @Id\n    private String tatamibotConfigurationId;\n\n    @Column(name = \"domain\")\n    private String domain;\n\n    @Column(name = \"type\")\n    private String type;\n\n    @Column(name = \"url\")\n    private String url;\n\n    /**\n     * How often the source is polled, in seconds. Default is 5 minutes.\n     */\n    @Column(name = \"pollingDelay\")\n    private Integer pollingDelay = 60 * 5;\n\n    @Column(name = \"tag\")\n    private String tag;\n\n    @Column(name = \"lastUpdateDate\")\n    private Date lastUpdateDate;\n\n    public String getTatamibotConfigurationId() {\n        return tatamibotConfigurationId;\n    }\n\n    public void setTatamibotConfigurationId(String tatamibotConfigurationId) {\n        this.tatamibotConfigurationId = tatamibotConfigurationId;\n    }\n\n    public String getDomain() {\n        return domain;\n    }\n\n    public void setDomain(String domain) {\n        this.domain = domain;\n    }\n\n    public String getType() {\n        return type;\n    }\n\n    public void setType(String type) {\n        this.type = type;\n    }\n\n    public String getUrl() {\n        return url;\n    }\n\n    public void setUrl(String url) {\n        this.url = url;\n    }\n\n    public Integer getPollingDelay() {\n        return pollingDelay;\n    }\n\n    public void setPollingDelay(Integer pollingDelay) {\n        this.pollingDelay = pollingDelay;\n    }\n\n    public String getTag() {\n        return tag;\n    }\n\n    public void setTag(String tag) {\n        this.tag = tag;\n    }\n\n    public String getISOLastUpdateDate() {\n        DateTime dt = new DateTime(lastUpdateDate);\n        DateTimeFormatter fmt = ISODateTimeFormat.dateTime();\n        return fmt.print(dt);\n    }\n\n    public Date getLastUpdateDate() {\n        return lastUpdateDate;\n    }\n\n    public void setLastUpdateDate(Date lastUpdateDate) {\n        this.lastUpdateDate = lastUpdateDate;\n    }\n\n    @Override\n    public String toString() {\n        return \"TatamibotConfiguration{\" +\n                \"tatamibotConfigurationId='\" + tatamibotConfigurationId + '\\'' +\n                \", domain='\" + domain + '\\'' +\n                \", type='\" + type + '\\'' +\n                \", url=\" + url +\n                \", pollingDelay=\" + pollingDelay +\n                \", tag=\" + tag +\n                \", lastUpdateDate=\" + lastUpdateDate +\n                \"} \" + super.toString();\n    }\n}\n"
  },
  {
    "path": "tatamibot/src/main/java/fr/ippon/tatami/bot/processor/LastUpdateDateTatamibotConfigurationUpdater.java",
    "content": "package fr.ippon.tatami.bot.processor;\r\n\r\nimport fr.ippon.tatami.bot.config.TatamibotConfiguration;\r\nimport fr.ippon.tatami.repository.TatamibotConfigurationRepository;\r\nimport org.apache.camel.Header;\r\nimport org.springframework.stereotype.Component;\r\n\r\nimport javax.inject.Inject;\r\nimport java.util.Date;\r\n\r\n@Component\r\npublic class LastUpdateDateTatamibotConfigurationUpdater {\r\n\r\n    @Inject\r\n    private TatamibotConfigurationRepository tatamibotConfigurationRepository;\r\n\r\n    public void updateLastDate(@Header(\"tatamibotLastUpdateDate\") Date lastUpdateDate,\r\n                               @Header(\"tatamibotConfiguration\") TatamibotConfiguration tatamibotConfigurationUsedByRoute) {\r\n\r\n        String tatamibotConfigurationId = tatamibotConfigurationUsedByRoute.getTatamibotConfigurationId();\r\n\r\n        TatamibotConfiguration lastTatamibotConfiguration = tatamibotConfigurationRepository\r\n                .findTatamibotConfigurationById(tatamibotConfigurationId);\r\n\r\n        lastTatamibotConfiguration.setLastUpdateDate(lastUpdateDate);\r\n        tatamibotConfigurationRepository.updateTatamibotConfiguration(lastTatamibotConfiguration);\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "tatamibot/src/main/java/fr/ippon/tatami/bot/processor/TatamiStatusProcessor.java",
    "content": "package fr.ippon.tatami.bot.processor;\n\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.service.StatusUpdateService;\nimport fr.ippon.tatami.service.UserService;\nimport org.apache.camel.Body;\nimport org.apache.camel.Header;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Component;\n\nimport javax.inject.Inject;\n\n@Component\npublic class TatamiStatusProcessor {\n\n    private final Logger log = LoggerFactory.getLogger(TatamiStatusProcessor.class);\n\n    @Inject\n    private StatusUpdateService statusUpdateService;\n\n    @Inject\n    private UserService userService;\n\n    public void sendStatus(@Body String content, @Header(\"login\") String login) throws Exception {\n\n        User tatamiBotUser = userService.getUserByLogin(login);\n\n        log.debug(\"Posting content to Tatami : {}\", content);\n\n\n        // TODO : handle posting in group ...\n\n        statusUpdateService.postStatusAsUser(content, tatamiBotUser);\n\n    }\n}\n"
  },
  {
    "path": "tatamibot/src/main/java/fr/ippon/tatami/bot/route/CommonRouteBuilder.java",
    "content": "package fr.ippon.tatami.bot.route;\r\n\r\nimport com.google.common.base.Strings;\r\nimport fr.ippon.tatami.bot.config.TatamibotConfiguration;\r\nimport fr.ippon.tatami.bot.processor.LastUpdateDateTatamibotConfigurationUpdater;\r\nimport fr.ippon.tatami.bot.processor.TatamiStatusProcessor;\r\nimport org.apache.camel.Body;\r\nimport org.apache.camel.Header;\r\nimport org.apache.camel.builder.RouteBuilder;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\nimport org.springframework.stereotype.Component;\r\n\r\nimport javax.inject.Inject;\r\n\r\n@Component // This one IS a component as it is a singleton \r\npublic class CommonRouteBuilder extends RouteBuilder {\r\n\r\n    private static final Logger log = LoggerFactory.getLogger(CommonRouteBuilder.class);\r\n\r\n    @Inject\r\n    private TatamiStatusProcessor tatamiStatusProcessor;\r\n\r\n    @Inject\r\n    private LastUpdateDateTatamibotConfigurationUpdater lastUpdateDateTatamibotConfigurationUpdater;\r\n\r\n    @Override\r\n    public void configure() {\r\n\r\n        // Final endpoint used to send status to Tatami : \r\n\r\n        from(\"direct:toTatami\"). // TODO : switch from direct: endpoint to an asynchronous one : seda: or jms: (for throttling in particular)\r\n                bean(new TagAppender()).\r\n                bean(tatamiStatusProcessor).\r\n                bean(lastUpdateDateTatamibotConfigurationUpdater);\r\n\r\n    }\r\n\r\n    public static class TagAppender {\r\n        public String process(@Body String body, @Header(\"tatamibotConfiguration\") TatamibotConfiguration configuration) throws Exception {\r\n            if (!Strings.isNullOrEmpty(configuration.getTag())) {\r\n                body = body + \" #\" + configuration.getTag();\r\n            }\r\n            return body;\r\n        }\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "tatamibot/src/main/java/fr/ippon/tatami/bot/route/GitHubRouteBuilder.java",
    "content": "package fr.ippon.tatami.bot.route;\r\n\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\n//@Component ==> disabling component scanning as we create instances of this builder programmatically\r\npublic class GitHubRouteBuilder extends SourceRouteBuilderBase {\r\n\r\n    private static final Logger log = LoggerFactory.getLogger(GitHubRouteBuilder.class);\r\n\r\n    @Override\r\n    public void configure() {\r\n\r\n//      log.info(\"Configuring Github support\");\r\n        //https://github.com/eclipse/egit-github/tree/master/org.eclipse.egit.github.core\r\n    }\r\n}\r\n"
  },
  {
    "path": "tatamibot/src/main/java/fr/ippon/tatami/bot/route/RssRouteBuilder.java",
    "content": "package fr.ippon.tatami.bot.route;\r\n\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\n//@Component // ==> disabling component scanning as we create instances of this builder programmatically\r\n//@Scope(\"prototype\") // <<<===  TODO : configure it with Spring !! using prototype scope : WARN testability ! \r\npublic class RssRouteBuilder extends SourceRouteBuilderBase {\r\n\r\n    private static final Logger log = LoggerFactory.getLogger(RssRouteBuilder.class);\r\n\r\n    @Override\r\n    public void configure() {\r\n\r\n        log.debug(\"Configuring a RSS support for domain {}\", configuration.getDomain());\r\n\r\n        from(getRssEndpointUri()). // return a single SyndFeed each time (with a single SyndEntry)\r\n                id(\"rss-\" + configuration.getDomain()).\r\n                transform(simple(\"[${body.entries[0].title}](${body.entries[0].link})\")).\r\n                setHeader(\"login\", simple(tatamiBotLogin)).\r\n                setHeader(\"tatamibotConfiguration\", constant(configuration)).\r\n                // extraction of publishedDate  TODO : in original code the date was put through JodaTime : why ???\r\n                        setHeader(\"tatamibotLastUpdateDate\", simple(\"header.CamelRssFeed.publishedDate\")).\r\n                idempotentConsumer(simple(\"${header.tatamibotConfiguration.domain}-${body}\"), idempotentRepository).\r\n                to(\"direct:toTatami\");\r\n    }\r\n\r\n    /* pp */ String getRssEndpointUri() {\r\n        return \"rss:\" +\r\n                configuration.getUrl() +\r\n                (configuration.getUrl().contains(\"?\") ? \"&\" : \"?\") + \"lastUpdate=\" +\r\n                configuration.getISOLastUpdateDate() +\r\n                \"&consumer.delay=\" +\r\n                configuration.getPollingDelay() * 1000 +\r\n                \"&throttleEntries=false\";\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "tatamibot/src/main/java/fr/ippon/tatami/bot/route/SourceRouteBuilderBase.java",
    "content": "package fr.ippon.tatami.bot.route;\r\n\r\nimport fr.ippon.tatami.bot.config.TatamibotConfiguration;\r\nimport org.apache.camel.builder.RouteBuilder;\r\nimport org.apache.camel.spi.IdempotentRepository;\r\n\r\npublic abstract class SourceRouteBuilderBase extends RouteBuilder {\r\n\r\n    protected IdempotentRepository<String> idempotentRepository;\r\n    protected TatamibotConfiguration configuration;\r\n    protected String tatamiBotLogin;\r\n\r\n    public SourceRouteBuilderBase() {\r\n    }\r\n\r\n    public IdempotentRepository<String> getIdempotentRepository() {\r\n        return idempotentRepository;\r\n    }\r\n\r\n    public void setIdempotentRepository(IdempotentRepository<String> idempotentRepository) {\r\n        this.idempotentRepository = idempotentRepository;\r\n    }\r\n\r\n    public TatamibotConfiguration getConfiguration() {\r\n        return configuration;\r\n    }\r\n\r\n    public void setConfiguration(TatamibotConfiguration configuration) {\r\n        this.configuration = configuration;\r\n    }\r\n\r\n    public String getTatamiBotLogin() {\r\n        return tatamiBotLogin;\r\n    }\r\n\r\n    public void setTatamiBotLogin(String tatamiBotLogin) {\r\n        this.tatamiBotLogin = tatamiBotLogin;\r\n    }\r\n\r\n}"
  },
  {
    "path": "tatamibot/src/main/java/fr/ippon/tatami/bot/route/TwitterRouteBuilder.java",
    "content": "package fr.ippon.tatami.bot.route;\r\n\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\n//@Component ==> disabling component scanning as we create instances of this builder programmatically\r\npublic class TwitterRouteBuilder extends SourceRouteBuilderBase {\r\n\r\n    private static final Logger log = LoggerFactory.getLogger(TwitterRouteBuilder.class);\r\n\r\n    @Override\r\n    public void configure() {\r\n\r\n        log.debug(\"Configuring a Twitter support for domain {}\", configuration.getDomain());\r\n\r\n        from(getTwitterEndpointUri()).\r\n                id(\"twitter-\" + configuration.getDomain()).\r\n                setHeader(\"login\", simple(tatamiBotLogin)).\r\n                setHeader(\"tatamibotConfiguration\", constant(configuration)).\r\n                idempotentConsumer(simple(\"${header.tatamibotConfiguration.domain}-${body}\"), idempotentRepository).\r\n                to(\"direct:toTatami\");\r\n    }\r\n\r\n    String getTwitterEndpointUri() {\r\n        String twitterUser = \"?\";\r\n        String twitterConsumerKey = \"?\";\r\n        String twitterConsumerSecret = \"?\";\r\n        String twitterAccessToken = \"?\";\r\n        String twitterAccessTokenSecret = \"?\";\r\n\r\n        return \"twitter://timeline/user?user=\" + twitterUser +\r\n                \"&type=polling&delay=60&consumerKey=\" + twitterConsumerKey +\r\n                \"&consumerSecret=\" + twitterConsumerSecret +\r\n                \"&accessToken=\" + twitterAccessToken +\r\n                \"&accessTokenSecret=\" + twitterAccessTokenSecret;\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "tatamibot/src/main/java/fr/ippon/tatami/repository/TatamibotConfigurationRepository.java",
    "content": "package fr.ippon.tatami.repository;\n\nimport fr.ippon.tatami.bot.config.TatamibotConfiguration;\n\nimport java.util.Collection;\n\n/**\n * The Tatami Bot configuration Repository.\n *\n * @author Julien Dubois\n */\npublic interface TatamibotConfigurationRepository {\n\n    void insertTatamibotConfiguration(TatamibotConfiguration tatamibotConfiguration);\n\n    void updateTatamibotConfiguration(TatamibotConfiguration tatamibotConfiguration);\n\n    TatamibotConfiguration findTatamibotConfigurationById(String tatamibotConfigurationId);\n\n    Collection<TatamibotConfiguration> findTatamibotConfigurationsByDomain(String domain);\n}\n"
  },
  {
    "path": "tatamibot/src/main/java/fr/ippon/tatami/repository/cassandra/CassandraTatamibotConfigurationRepository.java",
    "content": "package fr.ippon.tatami.repository.cassandra;\n\nimport fr.ippon.tatami.bot.config.TatamibotConfiguration;\nimport fr.ippon.tatami.repository.TatamibotConfigurationRepository;\nimport me.prettyprint.cassandra.serializers.StringSerializer;\nimport me.prettyprint.cassandra.serializers.UUIDSerializer;\nimport me.prettyprint.cassandra.utils.TimeUUIDUtils;\nimport me.prettyprint.hector.api.Keyspace;\nimport me.prettyprint.hector.api.beans.ColumnSlice;\nimport me.prettyprint.hector.api.beans.HColumn;\nimport me.prettyprint.hector.api.factory.HFactory;\nimport me.prettyprint.hector.api.mutation.Mutator;\nimport me.prettyprint.hom.EntityManagerImpl;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Repository;\nimport fr.ippon.tatami.config.ColumnFamilyKeys;\n\nimport javax.inject.Inject;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.Set;\nimport java.util.UUID;\n\nimport static me.prettyprint.hector.api.factory.HFactory.createSliceQuery;\n\n/**\n * Cassandra implementation of CassandraTatamibotConfigurationRepository.\n * <p/>\n * <p/>\n * This uses two CF\n * <p/>\n * DomainTatamibot :\n * - Key : domain\n * - Name : TatamibotConfiguration Id\n * - Value : \"\"\n * <p/>\n * TatamibotConfiguration, managed by Hector Object Mapper\n * - Key : Tatamibot Id\n * - Name : Key\n * - Value : Value\n *\n * @author Julien Dubois\n */\n@Repository\npublic class CassandraTatamibotConfigurationRepository implements TatamibotConfigurationRepository {\n\n    private final Logger log = LoggerFactory.getLogger(CassandraTatamibotConfigurationRepository.class);\n\n    @Inject\n    private Keyspace keyspaceOperator;\n\n    @Inject\n    private EntityManagerImpl em;\n\n    @Override\n    public void insertTatamibotConfiguration(TatamibotConfiguration tatamibotConfiguration) {\n        UUID tatamibotConfigurationId = TimeUUIDUtils.getUniqueTimeUUIDinMillis();\n        Mutator<String> mutator = HFactory.createMutator(keyspaceOperator, StringSerializer.get());\n        mutator.insert(\n                tatamibotConfiguration.getDomain(),\n                ColumnFamilyKeys.DOMAIN_TATAMIBOT_CF,\n                HFactory.createColumn(\n                        tatamibotConfigurationId,\n                        \"\",\n                        UUIDSerializer.get(),\n                        StringSerializer.get()));\n\n        tatamibotConfiguration.setTatamibotConfigurationId(tatamibotConfigurationId.toString());\n        em.persist(tatamibotConfiguration);\n    }\n\n    @Override\n    public void updateTatamibotConfiguration(TatamibotConfiguration tatamibotConfiguration) {\n        em.persist(tatamibotConfiguration);\n    }\n\n    @Override\n    public TatamibotConfiguration findTatamibotConfigurationById(String tatamibotConfigurationId) {\n        return em.find(TatamibotConfiguration.class, tatamibotConfigurationId);\n    }\n\n    @Override\n    public Collection<TatamibotConfiguration> findTatamibotConfigurationsByDomain(String domain) {\n\n        Set<TatamibotConfiguration> configurations = new HashSet<TatamibotConfiguration>();\n\n        ColumnSlice<UUID, String> results = HFactory.createSliceQuery(keyspaceOperator,\n                StringSerializer.get(), UUIDSerializer.get(), StringSerializer.get())\n                .setColumnFamily(ColumnFamilyKeys.DOMAIN_TATAMIBOT_CF)\n                .setKey(domain)\n                .setRange(null, null, false, Integer.MAX_VALUE)\n                .execute()\n                .get();\n\n        for (HColumn<UUID, String> column : results.getColumns()) {\n            String tatamibotConfigurationId = column.getName().toString();\n            TatamibotConfiguration configuration = em.find(TatamibotConfiguration.class, tatamibotConfigurationId);\n            configurations.add(configuration);\n        }\n        return configurations;\n    }\n}\n"
  },
  {
    "path": "tatamibot/src/main/java/fr/ippon/tatami/web/bot/TatamibotController.java",
    "content": "package fr.ippon.tatami.web.bot;\n\nimport fr.ippon.tatami.bot.config.TatamibotConfiguration;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.TatamibotConfigurationRepository;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.ResponseBody;\n\nimport javax.inject.Inject;\nimport java.util.Collection;\n\n/**\n * @author Julien Dubois\n */\n@Controller\npublic class TatamibotController {\n\n    private final Logger log = LoggerFactory.getLogger(TatamibotController.class);\n\n    @Inject\n    private TatamibotConfigurationRepository tatamibotConfigurationRepository;\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    @RequestMapping(value = \"/rest/tatamibot/configurations\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    public Collection<TatamibotConfiguration> getConfigurations() {\n        User currentUser = authenticationService.getCurrentUser();\n        return tatamibotConfigurationRepository.findTatamibotConfigurationsByDomain(currentUser.getDomain());\n    }\n}\n"
  },
  {
    "path": "tatamibot/src/main/resources/META-INF/spring/applicationContext-tatamibot.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<beans xmlns=\"http://www.springframework.org/schema/beans\"\n       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n       xmlns:context=\"http://www.springframework.org/schema/context\"\n       xsi:schemaLocation=\"http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd\n         http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd\"\n       profile=\"tatamibot\">\n\n    <context:component-scan base-package=\"fr.ippon.tatami.bot\"/>\n\n    <camelContext id=\"camel\" xmlns=\"http://camel.apache.org/schema/spring\">\n        <contextScan/>\n        <threadPoolProfile id=\"threalPoolDefaultProfile\"\n                           defaultProfile=\"true\"\n                           poolSize=\"5\" keepAliveTime=\"25\" maxPoolSize=\"15\" maxQueueSize=\"250\" rejectedPolicy=\"Abort\"/>\n    </camelContext>\n\n</beans>\n"
  },
  {
    "path": "tatamibot/src/test/java/fr/ippon/tatami/bot/TatamibotTest.java",
    "content": "package fr.ippon.tatami.bot;\r\n\r\nimport com.jayway.awaitility.Awaitility;\r\nimport fr.ippon.tatami.bot.config.TatamibotConfiguration;\r\nimport fr.ippon.tatami.bot.processor.LastUpdateDateTatamibotConfigurationUpdater;\r\nimport fr.ippon.tatami.bot.processor.TatamiStatusProcessor;\r\nimport fr.ippon.tatami.bot.route.CommonRouteBuilder;\r\nimport fr.ippon.tatami.domain.Domain;\r\nimport fr.ippon.tatami.domain.User;\r\nimport fr.ippon.tatami.repository.DomainRepository;\r\nimport fr.ippon.tatami.repository.TatamibotConfigurationRepository;\r\nimport fr.ippon.tatami.service.StatusUpdateService;\r\nimport fr.ippon.tatami.service.UserService;\r\nimport fr.ippon.tatami.test.MockUtils;\r\nimport org.apache.camel.Route;\r\nimport org.apache.camel.model.FromDefinition;\r\nimport org.apache.camel.model.RouteDefinition;\r\nimport org.apache.camel.processor.idempotent.MemoryIdempotentRepository;\r\nimport org.apache.camel.test.junit4.CamelTestSupport;\r\nimport org.hamcrest.CoreMatchers;\r\nimport org.hamcrest.collection.IsCollectionWithSize;\r\nimport org.joda.time.DateTime;\r\nimport org.junit.Assert;\r\nimport org.junit.Before;\r\nimport org.junit.Test;\r\nimport org.mockito.*;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\nimport org.springframework.test.util.ReflectionTestUtils;\r\n\r\nimport java.util.List;\r\nimport java.util.concurrent.Callable;\r\n\r\nimport static com.google.common.collect.Sets.newHashSet;\r\nimport static com.jayway.awaitility.Awaitility.await;\r\nimport static org.hamcrest.CoreMatchers.is;\r\nimport static org.hamcrest.collection.IsCollectionWithSize.hasSize;\r\nimport static org.mockito.Mockito.*;\r\n\r\npublic class TatamibotTest extends CamelTestSupport {\r\n\r\n    private static final Logger log = LoggerFactory.getLogger(TatamibotTest.class);\r\n\r\n    @Mock\r\n    private DomainRepository domainRepository;\r\n\r\n    @Mock\r\n    private TatamibotConfigurationRepository tatamibotConfigurationRepository;\r\n\r\n    @Mock\r\n    private UserService userService;\r\n\r\n    @Mock\r\n    private StatusUpdateService statusUpdateService;\r\n\r\n    @InjectMocks\r\n    private Tatamibot bot;\r\n\r\n    @InjectMocks\r\n    private TatamiStatusProcessor processor; // real one here ...\r\n\r\n    @InjectMocks\r\n    private LastUpdateDateTatamibotConfigurationUpdater lastUpdateDateTatamibotConfigurationUpdater;\r\n\r\n    private CommonRouteBuilder commonRouteBuilder;\r\n\r\n    User tatamibotUser = new User();\r\n\r\n    private MemoryIdempotentRepository idempotentRepository;\r\n\r\n\r\n    @Before\r\n    public void setup() throws Exception {\r\n\r\n        idempotentRepository = new MemoryIdempotentRepository();\r\n        processor = new TatamiStatusProcessor();\r\n        lastUpdateDateTatamibotConfigurationUpdater = new LastUpdateDateTatamibotConfigurationUpdater();\r\n        bot = new Tatamibot();\r\n        MockitoAnnotations.initMocks(this); // init bot and processor with mock dependency\r\n        ReflectionTestUtils.setField(bot, \"idempotentRepository\", idempotentRepository);\r\n\r\n        commonRouteBuilder = new CommonRouteBuilder();\r\n        ReflectionTestUtils.setField(commonRouteBuilder, \"tatamiStatusProcessor\", processor);\r\n        ReflectionTestUtils.setField(commonRouteBuilder, \"lastUpdateDateTatamibotConfigurationUpdater\", lastUpdateDateTatamibotConfigurationUpdater);\r\n\r\n        // common mock configuration :\r\n        Mockito.when(userService.getUserByLogin(\"tatamibot@ippon.fr\")).thenReturn(tatamibotUser);\r\n        Mockito.when(tatamibotConfigurationRepository.findTatamibotConfigurationById(Mockito.anyString())).thenReturn(new TatamibotConfiguration());\r\n    }\r\n\r\n    @Test\r\n    public void testRssRouteOnly() throws Exception {\r\n\r\n        TatamibotConfiguration configuration = getRssBotConfiguration();\r\n        configuration.setTag(\"BlogIppon\");  // <<<  ==== TAG \r\n\r\n        setupAndLaunchContext(configuration);\r\n\r\n        Awaitility.await().until(statusUpdateServiceWasCallAtLeast3Times());\r\n\r\n        String msg1 = \"[Ippevent Mobilité – Applications mobiles – ouverture des inscriptions](http://feedproxy.google.com/~r/LeBlogDesExpertsJ2ee/~3/GcJYERHTfoQ/)\";\r\n        String msg2 = \"[Business – Ippon Technologies acquiert Atomes et renforce son offre Cloud](http://feedproxy.google.com/~r/LeBlogDesExpertsJ2ee/~3/wK-Y47WGZBQ/)\";\r\n        String msg3 = \"[Les Méthodes Agiles – Définition de l’Agilité](http://feedproxy.google.com/~r/LeBlogDesExpertsJ2ee/~3/hSqyt1MCOoo/)\";\r\n\r\n        Mockito.verify(statusUpdateService).postStatusAsUser(msg1 + \" #BlogIppon\", tatamibotUser);\r\n        Mockito.verify(statusUpdateService).postStatusAsUser(msg2 + \" #BlogIppon\", tatamibotUser);\r\n        Mockito.verify(statusUpdateService).postStatusAsUser(msg3 + \" #BlogIppon\", tatamibotUser);\r\n        Mockito.verifyNoMoreInteractions(statusUpdateService);\r\n\r\n        // TODO : the repository is updated three times ... \r\n        ArgumentCaptor<TatamibotConfiguration> argumentCaptor = ArgumentCaptor.forClass(TatamibotConfiguration.class);\r\n        Mockito.verify(tatamibotConfigurationRepository, Mockito.times(3)).updateTatamibotConfiguration(argumentCaptor.capture());\r\n        TatamibotConfiguration value = argumentCaptor.getValue();\r\n        Assert.assertThat(value.getLastUpdateDate(), CoreMatchers.is(DateTime.parse(\"2012-12-17T17:35:51Z\").toDate()));\r\n\r\n        Assert.assertTrue(idempotentRepository.contains(\"ippon.fr-\" + msg1));\r\n    }\r\n\r\n    private Callable<Boolean> statusUpdateServiceWasCallAtLeast3Times() {\r\n        return MockUtils.mockCalledCallable(statusUpdateService, 3);\r\n    }\r\n\r\n    @Override\r\n    public boolean isUseAdviceWith() {\r\n        return true; // returning true here to force CamelTestSupport NOT to start camel context\r\n    }\r\n\r\n    private void setupAndLaunchContext(TatamibotConfiguration configuration) throws Exception {\r\n        Domain domain = new Domain();\r\n        domain.setName(\"ippon.fr\");\r\n\r\n        Mockito.when(domainRepository.getAllDomains()).thenReturn(newHashSet(domain));\r\n        Mockito.when(tatamibotConfigurationRepository.findTatamibotConfigurationsByDomain(\"ippon.fr\")).thenReturn(newHashSet(configuration));\r\n\r\n        // Note : we have to configure the context ourself as the mocks are used during route creation ..  \r\n        context.addRoutes(commonRouteBuilder);\r\n        context.addRoutes(bot);\r\n\r\n        // Fix initial delay to speed up tests by 1s\r\n        for (RouteDefinition routeDefinition : context.getRouteDefinitions()) {\r\n            for (FromDefinition fromDefinition : routeDefinition.getInputs()) {\r\n                String uri = fromDefinition.getUri();\r\n                if (uri.startsWith(\"rss:\")) {\r\n                    fromDefinition.setUri(uri + \"&consumer.initialDelay=0\");\r\n                }\r\n            }\r\n        }\r\n\r\n        context.start();\r\n\r\n        List<Route> routes = context.getRoutes();\r\n        Assert.assertThat(routes, IsCollectionWithSize.hasSize(2));\r\n//        assertThat(routes.get(0).get, hasItems());\r\n    }\r\n\r\n\r\n    private TatamibotConfiguration getRssBotConfiguration() {\r\n        final String fileUrl = this.getClass().getResource(\"route/rss.xml\").toExternalForm();\r\n\r\n        TatamibotConfiguration configuration = new TatamibotConfiguration();\r\n        configuration.setTatamibotConfigurationId(\"TEST_CONFIG_ID\");\r\n        configuration.setType(TatamibotConfiguration.TatamibotType.RSS);\r\n        configuration.setDomain(\"ippon.fr\");\r\n//        configuration.setUrl(\"http://feeds.feedburner.com/LeBlogDesExpertsJ2ee?format=xml\");\r\n        configuration.setUrl(fileUrl);\r\n        configuration.setPollingDelay(60); // not used here\r\n        configuration.setLastUpdateDate(DateTime.parse(\"2010-01-01T00:00:00\").toDate());\r\n        return configuration;\r\n    }\r\n}\r\n"
  },
  {
    "path": "tatamibot/src/test/java/fr/ippon/tatami/bot/route/CommonRouteBuilderTest.java",
    "content": "package fr.ippon.tatami.bot.route;\r\n\r\nimport fr.ippon.tatami.bot.config.TatamibotConfiguration;\r\nimport fr.ippon.tatami.bot.processor.LastUpdateDateTatamibotConfigurationUpdater;\r\nimport fr.ippon.tatami.bot.processor.TatamiStatusProcessor;\r\nimport fr.ippon.tatami.test.MockUtils;\r\nimport org.apache.camel.builder.RouteBuilder;\r\nimport org.apache.camel.test.junit4.CamelTestSupport;\r\nimport org.junit.Test;\r\nimport org.mockito.InjectMocks;\r\nimport org.mockito.Mock;\r\nimport org.mockito.MockitoAnnotations;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.util.Date;\r\nimport java.util.HashMap;\r\nimport java.util.Map;\r\nimport java.util.concurrent.Callable;\r\n\r\nimport static com.jayway.awaitility.Awaitility.await;\r\nimport static org.mockito.Mockito.verify;\r\n\r\npublic class CommonRouteBuilderTest extends CamelTestSupport {\r\n\r\n    private static final Logger log = LoggerFactory.getLogger(CommonRouteBuilderTest.class);\r\n\r\n    private static Date value = new Date();\r\n\r\n    @Mock\r\n    private TatamiStatusProcessor tatamiStatusProcessor;\r\n\r\n    @Mock\r\n    private LastUpdateDateTatamibotConfigurationUpdater lastUpdateDateTatamibotConfigurationUpdater;\r\n\r\n    @InjectMocks\r\n    private CommonRouteBuilder sut;\r\n\r\n    @Override\r\n    // Called during @Before handling of the super class ...\r\n    protected RouteBuilder createRouteBuilder() throws Exception {\r\n        MockitoAnnotations.initMocks(this);\r\n\r\n        return sut;\r\n    }\r\n\r\n    @Test\r\n    public void commonRouteSendStatusAndUpdateConfiguration() throws Exception {\r\n        TatamibotConfiguration configuration = new TatamibotConfiguration();\r\n        configuration.setTag(\"MyTag\");\r\n\r\n        sendAMessage(configuration);\r\n\r\n        await().until(lastProcessorWasCalled());\r\n\r\n        verify(tatamiStatusProcessor).sendStatus(\"The content #MyTag\", \"bot@ippon.fr\");\r\n        verify(lastUpdateDateTatamibotConfigurationUpdater).updateLastDate(value, configuration);\r\n\r\n    }\r\n\r\n    @Test\r\n    public void commonRouteShouldAddTagIfPresent() throws Exception {\r\n        TatamibotConfiguration configuration = new TatamibotConfiguration();\r\n        configuration.setTag(\"MyTag\");\r\n\r\n        sendAMessage(configuration);\r\n\r\n        await().until(lastProcessorWasCalled());\r\n\r\n        verify(tatamiStatusProcessor).sendStatus(\"The content #MyTag\", \"bot@ippon.fr\");\r\n    }\r\n\r\n\r\n    @Test\r\n    public void commonRouteDoesNotModifyMessageIfTagIsAbsent() throws Exception {\r\n        TatamibotConfiguration configuration = new TatamibotConfiguration();\r\n\r\n        sendAMessage(configuration);\r\n\r\n        await().until(lastProcessorWasCalled());\r\n\r\n        verify(tatamiStatusProcessor).sendStatus(\"The content\", \"bot@ippon.fr\");\r\n    }\r\n\r\n    private void sendAMessage(TatamibotConfiguration configuration) {\r\n        Map<String, Object> headers = new HashMap<String, Object>();\r\n        headers.put(\"tatamibotConfiguration\", configuration);\r\n        headers.put(\"login\", \"bot@ippon.fr\");\r\n        headers.put(\"tatamibotLastUpdateDate\", value);\r\n        template.sendBodyAndHeaders(\"direct:toTatami\", \"The content\", headers);\r\n    }\r\n\r\n    private Callable<Boolean> lastProcessorWasCalled() {\r\n//        return MockUtils.mockCalledCallable(tatamiStatusProcessor, 1);\r\n        return MockUtils.mockCalledCallable(lastUpdateDateTatamibotConfigurationUpdater, 1);\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "tatamibot/src/test/java/fr/ippon/tatami/bot/route/RssRouteBuilderCamelTest.java",
    "content": "package fr.ippon.tatami.bot.route;\r\n\r\nimport com.google.common.collect.Lists;\r\nimport fr.ippon.tatami.bot.config.TatamibotConfiguration;\r\nimport org.apache.camel.builder.AdviceWithRouteBuilder;\r\nimport org.joda.time.DateTime;\r\nimport org.junit.Test;\r\n\r\nimport java.util.List;\r\n\r\nimport static com.jayway.awaitility.Awaitility.await;\r\nimport static com.jayway.awaitility.Awaitility.to;\r\nimport static org.hamcrest.CoreMatchers.equalTo;\r\nimport static org.hamcrest.CoreMatchers.is;\r\nimport static org.hamcrest.Matchers.greaterThanOrEqualTo;\r\nimport static org.hamcrest.collection.IsCollectionWithSize.hasSize;\r\n\r\npublic class RssRouteBuilderCamelTest extends SourceRouteBuilderBaseCamelTest<RssRouteBuilder> {\r\n\r\n    public RssRouteBuilderCamelTest() {\r\n        super(RssRouteBuilder.class);\r\n    }\r\n\r\n    @Test\r\n    public void testRssRoute() throws Exception {\r\n        launchContext();\r\n\r\n        await().untilCall(to(messages).size(), is(greaterThanOrEqualTo(3)));\r\n\r\n        assertThat(messages, hasSize(3));\r\n        assertThat(messages, // in order ...\r\n                is(equalTo((List<String>) Lists.newArrayList(\r\n                        \"[Ippevent Mobilité – Applications mobiles – ouverture des inscriptions](http://feedproxy.google.com/~r/LeBlogDesExpertsJ2ee/~3/GcJYERHTfoQ/)\",\r\n                        \"[Business – Ippon Technologies acquiert Atomes et renforce son offre Cloud](http://feedproxy.google.com/~r/LeBlogDesExpertsJ2ee/~3/wK-Y47WGZBQ/)\",\r\n                        \"[Les Méthodes Agiles – Définition de l’Agilité](http://feedproxy.google.com/~r/LeBlogDesExpertsJ2ee/~3/hSqyt1MCOoo/)\"))));\r\n    }\r\n\r\n    // ---\r\n\r\n    @Override\r\n    protected void launchContext() throws Exception {\r\n        String routeDefId = \"rss-ippon.fr\"; // spécifique rss\r\n        context.getRouteDefinition(routeDefId).adviceWith(context, new AdviceWithRouteBuilder() {\r\n            @Override\r\n            public void configure() throws Exception {\r\n                String originalUri = getOriginalRoute().getInputs().get(0).getUri();\r\n                replaceFromWith(originalUri + \"consumer.initialDelay=0\");   // spécifique rss ??? \r\n            }\r\n        });\r\n\r\n        context.start(); // necessary because of isUseAdviceWith=true\r\n    }\r\n\r\n    @Override\r\n    protected String getFirstMsgBody() {\r\n        return \"[Ippevent Mobilité – Applications mobiles – ouverture des inscriptions](http://feedproxy.google.com/~r/LeBlogDesExpertsJ2ee/~3/GcJYERHTfoQ/)\";\r\n    }\r\n\r\n    @Override\r\n    protected TatamibotConfiguration getBotConfiguration() {\r\n        final String fileUrl = this.getClass().getResource(\"rss.xml\").toExternalForm(); // spécifique ...\r\n\r\n        TatamibotConfiguration configuration = new TatamibotConfiguration();\r\n        configuration.setTatamibotConfigurationId(\"TEST_CONFIG_ID\");\r\n        configuration.setType(TatamibotConfiguration.TatamibotType.RSS);     // spécifique ... mais pas utilisé ici\r\n        configuration.setDomain(\"ippon.fr\");\r\n//      configuration.setUrl(\"http://feeds.feedburner.com/LeBlogDesExpertsJ2ee?format=xml\");\r\n        configuration.setUrl(fileUrl);\r\n        configuration.setPollingDelay(60); // not used here\r\n        configuration.setLastUpdateDate(DateTime.parse(\"2010-01-01T00:00:00\").toDate());\r\n        return configuration;\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "tatamibot/src/test/java/fr/ippon/tatami/bot/route/RssRouteBuilderUnitTest.java",
    "content": "package fr.ippon.tatami.bot.route;\r\n\r\nimport fr.ippon.tatami.bot.config.TatamibotConfiguration;\r\nimport org.joda.time.DateTime;\r\nimport org.junit.Test;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport static org.hamcrest.Matchers.startsWith;\r\nimport static org.junit.Assert.assertThat;\r\n\r\npublic class RssRouteBuilderUnitTest {\r\n\r\n    private static final Logger log = LoggerFactory.getLogger(RssRouteBuilderUnitTest.class);\r\n\r\n    RssRouteBuilder sut = new RssRouteBuilder();\r\n\r\n    @Test\r\n    public void getRssEndpointUri_handlesUrlWithParameters() {\r\n        sut.setConfiguration(getRssBotConfiguration(\"http://feeds.feedburner.com/LeBlogDesExpertsJ2ee?format=xml\"));\r\n\r\n        String uri = sut.getRssEndpointUri();\r\n\r\n        assertThat(uri, startsWith(\"rss:http://feeds.feedburner.com/LeBlogDesExpertsJ2ee?format=xml&lastUpdate=\"));\r\n    }\r\n\r\n    @Test\r\n    public void getRssEndpointUri_handlesUrlWithoutParameter() {\r\n        sut.setConfiguration(getRssBotConfiguration(\"http://whatever\"));\r\n\r\n        String uri = sut.getRssEndpointUri();\r\n\r\n        assertThat(uri, startsWith(\"rss:http://whatever?lastUpdate=\"));\r\n    }\r\n\r\n    private TatamibotConfiguration getRssBotConfiguration(String url) {\r\n        TatamibotConfiguration configuration = new TatamibotConfiguration();\r\n        configuration.setTatamibotConfigurationId(\"TEST_CONFIG_ID\");\r\n        configuration.setType(TatamibotConfiguration.TatamibotType.RSS);     // spécifique ... mais pas utilisé ici\r\n        configuration.setDomain(\"ippon.fr\");\r\n        configuration.setUrl(url);\r\n        configuration.setPollingDelay(60); // not used here\r\n        configuration.setLastUpdateDate(DateTime.parse(\"2010-01-01T00:00:00\").toDate());\r\n        return configuration;\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "tatamibot/src/test/java/fr/ippon/tatami/bot/route/SourceRouteBuilderBaseCamelTest.java",
    "content": "package fr.ippon.tatami.bot.route;\r\n\r\nimport com.google.common.collect.Lists;\r\nimport fr.ippon.tatami.bot.config.TatamibotConfiguration;\r\nimport org.apache.camel.Exchange;\r\nimport org.apache.camel.Message;\r\nimport org.apache.camel.Processor;\r\nimport org.apache.camel.builder.RouteBuilder;\r\nimport org.apache.camel.processor.idempotent.MemoryIdempotentRepository;\r\nimport org.apache.camel.spi.IdempotentRepository;\r\nimport org.apache.camel.test.junit4.CamelTestSupport;\r\nimport org.junit.Test;\r\nimport org.mockito.Mockito;\r\nimport org.mockito.MockitoAnnotations;\r\nimport org.mockito.Spy;\r\nimport org.slf4j.Logger;\r\nimport org.slf4j.LoggerFactory;\r\n\r\nimport java.util.Date;\r\nimport java.util.List;\r\n\r\nimport static com.jayway.awaitility.Awaitility.await;\r\nimport static com.jayway.awaitility.Awaitility.to;\r\nimport static org.hamcrest.CoreMatchers.is;\r\nimport static org.hamcrest.CoreMatchers.notNullValue;\r\nimport static org.hamcrest.Matchers.greaterThanOrEqualTo;\r\n\r\npublic abstract class SourceRouteBuilderBaseCamelTest<T extends SourceRouteBuilderBase> extends CamelTestSupport {\r\n\r\n    protected final Logger log = LoggerFactory.getLogger(this.getClass());\r\n\r\n    protected List<String> messages = Lists.newArrayList();\r\n    private List<Message> camelMessages = Lists.newArrayList();\r\n\r\n    private TatamibotConfiguration botConfiguration;\r\n\r\n    @Spy\r\n    private IdempotentRepository<String> idempotentRepository = new MemoryIdempotentRepository();\r\n\r\n    private SourceRouteBuilderBase sut;\r\n\r\n    protected boolean disableDateHeaderTest = false;\r\n\r\n    private Class<T> builderType;\r\n\r\n    public SourceRouteBuilderBaseCamelTest(Class<T> builderType) {\r\n        super();\r\n        this.builderType = builderType;\r\n    }\r\n\r\n    @Override\r\n    protected RouteBuilder[] createRouteBuilders() throws Exception {\r\n\r\n        MockitoAnnotations.initMocks(this);\r\n\r\n        RouteBuilder commonRoutebuilder = new RouteBuilder() {\r\n            @Override\r\n            public void configure() throws Exception {\r\n                from(\"direct:toTatami\").process(new Processor() {\r\n                    @Override\r\n                    public void process(Exchange exchange) throws Exception {\r\n                        Message in = exchange.getIn();\r\n                        camelMessages.add(in);\r\n                        messages.add((String) in.getBody(String.class));\r\n                    }\r\n                });\r\n            }\r\n        };\r\n\r\n        botConfiguration = getBotConfiguration();\r\n\r\n//        sut = new RssRouteBuilder(); // spécifique ...\r\n        sut = builderType.newInstance();\r\n        sut.setIdempotentRepository(idempotentRepository);\r\n        sut.setTatamiBotLogin(\"bot@ippon.fr\");\r\n        sut.setConfiguration(botConfiguration);\r\n\r\n        return new RouteBuilder[]{commonRoutebuilder, sut};\r\n    }\r\n\r\n    @Override\r\n    public boolean isUseAdviceWith() {\r\n        return true;\r\n    }\r\n\r\n    @Test\r\n    public void shouldConformToSourceRouteBuilderBaseRequirements() throws Exception {\r\n        launchContext();\r\n\r\n        await().untilCall(to(messages).size(), is(greaterThanOrEqualTo(1)));\r\n\r\n        // behaviour of a SourceRouteBuilderBase\r\n        // Some headers must be provided :\r\n        Message firstCamelMsg = camelMessages.get(0);\r\n        assertThat(firstCamelMsg.getHeader(\"login\", String.class), is(\"bot@ippon.fr\"));\r\n        assertThat(firstCamelMsg.getHeader(\"tatamibotConfiguration\", TatamibotConfiguration.class), is(botConfiguration));\r\n\r\n        // Question : is it specific to rss ?\r\n        if (!disableDateHeaderTest) {\r\n            assertThat(firstCamelMsg.getHeader(\"tatamibotLastUpdateDate\", Date.class), is(notNullValue()));\r\n        }\r\n\r\n        // idempotentRepository must be called :\r\n        String msg = getFirstMsgBody();\r\n        Mockito.verify(idempotentRepository).add(\"ippon.fr-\" + msg);\r\n\r\n    }\r\n\r\n    protected abstract TatamibotConfiguration getBotConfiguration();\r\n\r\n    protected abstract void launchContext() throws Exception;\r\n\r\n    protected abstract String getFirstMsgBody();\r\n}\r\n"
  },
  {
    "path": "tatamibot/src/test/java/fr/ippon/tatami/bot/route/TwitterRouteBuilderCamelTest.java",
    "content": "package fr.ippon.tatami.bot.route;\r\n\r\n\r\nimport fr.ippon.tatami.bot.config.TatamibotConfiguration;\r\nimport org.apache.camel.builder.AdviceWithRouteBuilder;\r\nimport org.joda.time.DateTime;\r\nimport org.junit.Test;\r\nimport twitter4j.Status;\r\nimport twitter4j.User;\r\n\r\nimport java.text.ParseException;\r\nimport java.text.SimpleDateFormat;\r\nimport java.util.Date;\r\nimport java.util.Locale;\r\nimport java.util.TimeZone;\r\n\r\nimport static com.jayway.awaitility.Awaitility.await;\r\nimport static com.jayway.awaitility.Awaitility.to;\r\nimport static org.hamcrest.CoreMatchers.is;\r\nimport static org.hamcrest.Matchers.greaterThanOrEqualTo;\r\nimport static org.hamcrest.collection.IsCollectionWithSize.hasSize;\r\nimport static org.mockito.Mockito.mock;\r\nimport static org.mockito.Mockito.when;\r\n\r\n/**\r\n * This test only tests the route, the twitter input-connector is mocked\r\n */\r\npublic class TwitterRouteBuilderCamelTest extends SourceRouteBuilderBaseCamelTest<TwitterRouteBuilder> {\r\n\r\n    public TwitterRouteBuilderCamelTest() {\r\n        super(TwitterRouteBuilder.class);\r\n\r\n//        TimeZone.setDefault(TimeZone.getTimeZone(\"PST\"));\r\n\r\n        disableDateHeaderTest = true;\r\n    }\r\n\r\n    @Test\r\n    public void testTwitterRoute() throws Exception {\r\n\r\n        launchContext();\r\n\r\n        await().untilCall(to(messages).size(), is(greaterThanOrEqualTo(1)));\r\n\r\n        assertThat(messages, hasSize(1));\r\n        assertThat(messages.get(0), is(getFirstMsgBody()));\r\n    }\r\n\r\n    // ---\r\n\r\n    @Override\r\n    protected String getFirstMsgBody() {\r\n        // computing timezone in under to allow the test to run in remote CI server (which is in another timezone)\r\n        String timezone = TimeZone.getDefault().getDisplayName(false, TimeZone.SHORT, Locale.US); // From Date.toString() ...\r\n        return \"Sat Jan 05 12:34:00 \" + timezone + \" 2013 (ippontech) a first tweet\";\r\n    }\r\n\r\n    @Override\r\n    protected void launchContext() throws Exception {\r\n\r\n        // we replace the input (twitter connector) of the route with a \"direct\" endpoint :\r\n\r\n        String routeDefId = \"twitter-ippon.fr\";\r\n        context.getRouteDefinition(routeDefId).adviceWith(context, new AdviceWithRouteBuilder() {\r\n            @Override\r\n            public void configure() throws Exception {\r\n                replaceFromWith(\"direct:twitterRouteTest\");\r\n            }\r\n        });\r\n\r\n        context.start(); // necessary because of isUseAdviceWith=true\r\n\r\n        simulateInputMessage();\r\n    }\r\n\r\n    private void simulateInputMessage() throws ParseException {\r\n        Status fakeStatus = fakeTwitterStatus(\"2013/01/05 12:34\", \"ippontech\", \"a first tweet\");\r\n        template.sendBody(\"direct:twitterRouteTest\", fakeStatus);\r\n    }\r\n\r\n    private Status fakeTwitterStatus(String createdAtAsStr, String screenName, String text) throws ParseException {\r\n        // cf {@link TwitterConverter.toString} : we only need date, user and text at the moment\r\n        User user = mock(User.class);\r\n        when(user.getScreenName()).thenReturn(screenName);\r\n        Status status = mock(Status.class);\r\n        Date createdAt = new SimpleDateFormat(\"yyyy/MM/dd HH:mm\").parse(createdAtAsStr);\r\n        when(status.getUser()).thenReturn(user);\r\n        when(status.getCreatedAt()).thenReturn(createdAt);\r\n        when(status.getText()).thenReturn(text);\r\n\r\n        return status;\r\n    }\r\n\r\n    @Override\r\n    protected TatamibotConfiguration getBotConfiguration() {\r\n\r\n        TatamibotConfiguration configuration = new TatamibotConfiguration();\r\n        configuration.setTatamibotConfigurationId(\"TEST_CONFIG_ID\");\r\n        configuration.setType(TatamibotConfiguration.TatamibotType.TWITTER);\r\n        configuration.setDomain(\"ippon.fr\");\r\n//        configuration.setUrl(\"??\");\r\n        configuration.setPollingDelay(60); // not used here\r\n        configuration.setLastUpdateDate(DateTime.parse(\"2010-01-01T00:00:00\").toDate());\r\n        return configuration;\r\n    }\r\n\r\n\r\n}\r\n"
  },
  {
    "path": "tatamibot/src/test/java/fr/ippon/tatami/test/MockUtils.java",
    "content": "package fr.ippon.tatami.test;\r\n\r\nimport org.mockito.internal.util.MockUtil;\r\n\r\nimport java.util.concurrent.Callable;\r\n\r\npublic class MockUtils {\r\n\r\n    /**\r\n     * @param mock a Mockito mock\r\n     * @return\r\n     */\r\n    public static int getNumberOfInvocation(Object mock) {\r\n        // WARNING : we use internal mockito code here :\r\n        return new MockUtil().getMockHandler(mock).getInvocationContainer().getInvocations().size();\r\n    }\r\n\r\n    /**\r\n     * To be used with Awaitility.await().until(xxx)\r\n     *\r\n     * @param mock\r\n     * @param minInvocationCount\r\n     * @return\r\n     */\r\n    public static Callable<Boolean> mockCalledCallable(final Object mock, final int minInvocationCount) {\r\n        return new Callable<Boolean>() {\r\n            public Boolean call() throws Exception {\r\n                int nbCalls = getNumberOfInvocation(mock);\r\n                return nbCalls >= minInvocationCount;\r\n            }\r\n        };\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "tatamibot/src/test/resources/fr/ippon/tatami/bot/route/rss.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<?xml-stylesheet type=\"text/xsl\" media=\"screen\" href=\"/~d/styles/rss2frenchfull.xsl\"?><?xml-stylesheet type=\"text/css\" media=\"screen\" href=\"http://feeds.feedburner.com/~d/styles/itemcontent.css\"?><rss xmlns:content=\"http://purl.org/rss/1.0/modules/content/\" xmlns:wfw=\"http://wellformedweb.org/CommentAPI/\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\" xmlns:atom=\"http://www.w3.org/2005/Atom\" xmlns:sy=\"http://purl.org/rss/1.0/modules/syndication/\" xmlns:slash=\"http://purl.org/rss/1.0/modules/slash/\" xmlns:feedburner=\"http://rssnamespace.org/feedburner/ext/1.0\" version=\"2.0\">\r\n\r\n<channel>\r\n    <title>Blog d’Ippon Technologies</title>\r\n    \r\n    <link>http://blog.ippon.fr</link>\r\n    <description>Les experts Java EE, Portail et SOA</description>\r\n    <lastBuildDate>Mon, 17 Dec 2012 17:35:51 +0000</lastBuildDate>\r\n    <language>fr-FR</language>\r\n    <sy:updatePeriod>hourly</sy:updatePeriod>\r\n    <sy:updateFrequency>1</sy:updateFrequency>\r\n    <generator>http://wordpress.org/?v=3.4.2</generator>\r\n        <atom10:link xmlns:atom10=\"http://www.w3.org/2005/Atom\" rel=\"self\" type=\"application/rss+xml\" href=\"http://feeds.feedburner.com/LeBlogDesExpertsJ2ee\" /><feedburner:info uri=\"leblogdesexpertsj2ee\" /><atom10:link xmlns:atom10=\"http://www.w3.org/2005/Atom\" rel=\"hub\" href=\"http://pubsubhubbub.appspot.com/\" /><feedburner:feedFlare href=\"http://add.my.yahoo.com/content?lg=fr&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2FLeBlogDesExpertsJ2ee\" src=\"http://us.i1.yimg.com/us.yimg.com/i/us/my/bn/intatm_fr_1.gif\">Subscribe with Mon Yahoo!</feedburner:feedFlare><feedburner:feedFlare href=\"http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FLeBlogDesExpertsJ2ee\" src=\"http://www.newsgator.com/images/ngsub1.gif\">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href=\"http://www.bloglines.com/sub/http://feeds.feedburner.com/LeBlogDesExpertsJ2ee\" src=\"http://www.bloglines.com/images/sub_modern11.gif\">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href=\"http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FLeBlogDesExpertsJ2ee\" src=\"http://www.netvibes.com/img/add2netvibes.gif\">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href=\"http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FLeBlogDesExpertsJ2ee\" src=\"http://buttons.googlesyndication.com/fusion/add.gif\">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href=\"http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FLeBlogDesExpertsJ2ee\" src=\"http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif\">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href=\"http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2FLeBlogDesExpertsJ2ee\" src=\"http://plusmo.com/res/graphics/fbplusmo.gif\">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href=\"http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2FLeBlogDesExpertsJ2ee\" src=\"http://img.tfd.com/hp/addToTheFreeDictionary.gif\">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href=\"http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2FLeBlogDesExpertsJ2ee\" src=\"http://www.bitty.com/img/bittychicklet_91x17.gif\">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href=\"http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2FLeBlogDesExpertsJ2ee\" src=\"http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw\">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href=\"http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FLeBlogDesExpertsJ2ee\" src=\"http://image.excite.co.uk/mix/addtomix.gif\">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href=\"http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FLeBlogDesExpertsJ2ee\" src=\"http://www.webwag.com/images/wwgthis.gif\">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href=\"http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FLeBlogDesExpertsJ2ee\" src=\"http://www.podcastready.com/images/podcastready_button.gif\">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href=\"http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2FLeBlogDesExpertsJ2ee\" src=\"http://www.wikio.com/shared/img/add2wikio.gif\">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href=\"http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2FLeBlogDesExpertsJ2ee\" src=\"http://www.dailyrotation.com/rss-dr2.gif\">Subscribe with Daily Rotation</feedburner:feedFlare><item>\r\n        <title>Les Méthodes Agiles – Définition de l’Agilité</title>\r\n        <link>http://feedproxy.google.com/~r/LeBlogDesExpertsJ2ee/~3/hSqyt1MCOoo/</link>\r\n        <comments>http://blog.ippon.fr/2012/12/07/gestion-projet-methodes-agiles/#comments</comments>\r\n        <pubDate>Fri, 07 Dec 2012 08:15:10 +0000</pubDate>\r\n        <dc:creator>Communication Ippon Technologies</dc:creator>\r\n                <category><![CDATA[Expertise Java]]></category>\r\n        <category><![CDATA[agile]]></category>\r\n        <category><![CDATA[gestion de projet]]></category>\r\n        <category><![CDATA[nantes]]></category>\r\n        <category><![CDATA[Scrum]]></category>\r\n\r\n        <guid isPermaLink=\"false\">http://blog.ippon.fr/?p=7154</guid>\r\n        <description><![CDATA[<p>Ippon Technologies revient sur l&#8217;Agile Tour de Nantes&#8230;</p> <p>Notre reporter a été demander aux participants ce qu&#8217;évoque pour eux &#8216;l&#8217;Agilité&#8217;&#8230; Des réponses aussi riches et personnelles que surprenantes!</p> <p></p> ]]></description>\r\n            <content:encoded><![CDATA[<p>Ippon Technologies revient sur l&#8217;Agile Tour de Nantes&#8230;</p>\r\n<p>Notre reporter a été demander aux participants ce qu&#8217;évoque pour eux &#8216;l&#8217;Agilité&#8217;&#8230; Des réponses aussi riches et personnelles que surprenantes!</p>\r\n<p><iframe frameborder=\"0\" height=\"360\" src=\"http://www.youtube.com/embed/Uun_dQ16JTA\" width=\"640\"></iframe></p>\r\n<!-- Start Shareaholic ClassicBookmarks Automatic --><!-- End Shareaholic ClassicBookmarks Automatic --><img src=\"http://feeds.feedburner.com/~r/LeBlogDesExpertsJ2ee/~4/hSqyt1MCOoo\" height=\"1\" width=\"1\"/>]]></content:encoded>\r\n            <wfw:commentRss>http://blog.ippon.fr/2012/12/07/gestion-projet-methodes-agiles/feed/</wfw:commentRss>\r\n        <slash:comments>0</slash:comments>\r\n        <feedburner:origLink>http://blog.ippon.fr/2012/12/07/gestion-projet-methodes-agiles/</feedburner:origLink></item>\r\n        <item>\r\n        <title>Business – Ippon Technologies acquiert Atomes et renforce son offre Cloud</title>\r\n        <link>http://feedproxy.google.com/~r/LeBlogDesExpertsJ2ee/~3/wK-Y47WGZBQ/</link>\r\n        <comments>http://blog.ippon.fr/2012/12/05/ippon-technologies-acquiert-atomes-et-renforce-son-offre-cloud/#comments</comments>\r\n        <pubDate>Wed, 05 Dec 2012 07:50:49 +0000</pubDate>\r\n        <dc:creator>Geoffray GRUEL</dc:creator>\r\n                <category><![CDATA[Cloud]]></category>\r\n        <category><![CDATA[Devops]]></category>\r\n        <category><![CDATA[Expertise Java]]></category>\r\n        <category><![CDATA[acquisition]]></category>\r\n        <category><![CDATA[atomes]]></category>\r\n        <category><![CDATA[hébergement]]></category>\r\n        <category><![CDATA[hybride]]></category>\r\n        <category><![CDATA[serveur]]></category>\r\n\r\n        <guid isPermaLink=\"false\">http://blog.ippon.fr/?p=7131</guid>\r\n        <description><![CDATA[<p>Nous n&#8217;avons pas pour habitude d&#8217;utiliser le blog pour des news business mais celle-ci mérite un billet dans cette arène technique car Ippon Technologies vient d&#8217;acquérir un hébergeur spécialisé Java, pour renforcer ses offres Run, Cloud et Devops.</p> <p>Le choix d’Ippon Technologies s’est naturellement porté sur Atomes &#8211; http://www.atomes.com -, l’hébergeur Java de référence en <span style=\"color:#777\"> . . . &#8594; Lire la suite: <a href=\"http://blog.ippon.fr/2012/12/05/ippon-technologies-acquiert-atomes-et-renforce-son-offre-cloud/\">Business &#8211; Ippon Technologies acquiert Atomes et renforce son offre Cloud</a></span>]]></description>\r\n            <content:encoded><![CDATA[<p>Nous n&#8217;avons pas pour habitude d&#8217;utiliser le blog pour des news business mais celle-ci mérite un billet dans cette arène technique car Ippon Technologies vient d&#8217;acquérir un hébergeur spécialisé Java, pour renforcer ses offres Run, Cloud et Devops.</p>\r\n<div>\r\n<p>Le choix d’Ippon Technologies s’est naturellement porté sur Atomes &#8211; <a title=\"Atomes\" href=\"http://www.atomes.com/accueil\" target=\"_blank\">http://www.atomes.com</a> -, l’hébergeur Java de référence en France, qui dispose d’une expertise logicielle Java / JVM en plus de l’expertise système / matériel / réseau. C’est aussi le fruit d’une collaboration de plus de 4 ans entre les deux entreprises, qui ont déjà plusieurs succès en commun à leurs actifs : CCIP, Carrefour, Dhatim, Groupe La Poste, Intellinium&#8230;,sur des applications Java critiques avec des solutions intégrées telles que Liferay ou Alfresco.</p>\r\n<div>\r\n<p>Atomes est le spécialiste de l’hébergement et de l’infogérance d’applications Java EE en France. La société gère les infrastructures nécessaires à la mise en ligne d’applications Java EE critiques. Depuis 2007, Atomes accompagne ses clients dans le cycle d’exploitation de leurs services : conception, installation, paramétrage, exploitation, réversibilité.</p>\r\n<p>L’une de ses forces d&#8217;Atomes réside dans la lecture critique d’une «Stack-Trace» : en cas d’incident de production, cette expertise fait toute la différence avec un hébergeur classique car en plus d’une résolution rapide de l’incident, ses experts apportent une réponse qualifiée aux équipes de développement.<br />\r\nAtomes dispose par ailleurs d’une infrastructure de haut niveau : Datacenters de tiers III et tiers IV, Cloud privé OpenStack et Xen Cloud Platform, provisioning d’infrastructures Puppet, monitoring de dernière génération, haute-disponibilité, PRA et sécurité.</p>\r\n</div>\r\n<p>Dès aujourd’hui, Atomes porte l’offre Devops, Run et Cloud au sein du groupe Ippon Technologies, proposant ainsi à nos clients :</p>\r\n<ul>\r\n<li>Des services d’hébergement à la demande : virtualisé, dédié, cloud privé, cloud public,</li>\r\n<li>Des services d’infogérance 24/7,</li>\r\n<li>Des services de conseil sur les sujets Run, Devops et Cloud.</li>\r\n</ul>\r\n<p>Ippon Technologies va donc attaquer 2013 avec :</p>\r\n<ul>\r\n<li>Une offre front renforcée par <a href=\"http://www.ippon-mobile.fr/\" target=\"_blank\">Ippon Mobile</a>,</li>\r\n<li>Une offre back solide qui est le point fort historique d&#8217;Ippon et que nous avons pu renforcer avec par exemple un <a href=\"http://tatami.ippon.fr/tatami/presentation\" target=\"_blank\">Tatami</a> déployé en SaaS sur Cassandra,</li>\r\n<li>Une offre hébergement et cloud renforcée par <a href=\"http://www.atomes.com/accueil\" target=\"_blank\">Atomes</a>.</li>\r\n<li>Nos offres Agile et Devops (avec des inputs Ippon et Atomes) qui viennent soutenir tous ces projets.</li>\r\n</ul>\r\n<p>Cette couverture du cycle complet en Java va permettre à Ippon Technologies de se positionner en tant que partenaire &#8220;end to end&#8221; des projets critiques de nos clients en 2013. Nous pouvons nous engager du Design jusqu&#8217;au Run avec une offre 100% Ippon et des garanties fortes en terme de &#8220;Time To Market&#8221;.</p>\r\n<p>Vous verrez donc au fil des semaines de nouveaux articles sur le blog sur des sujets Cloud et Devops autour de Puppet, Xen ou OpenStack.</p>\r\n<p>Si vous souhaitez de plus amples informations sur cette offre n&#8217;hésitez pas à nous contacter :</p>\r\n<ul>\r\n<li>Business : Geoffray Gruel &#8211; ggruel(at)ippon.fr</li>\r\n<li>Technique : Yann Vigara &#8211; yvigara(at)atomes.com</li>\r\n</ul>\r\n</div>\r\n<!-- Start Shareaholic ClassicBookmarks Automatic --><!-- End Shareaholic ClassicBookmarks Automatic --><img src=\"http://feeds.feedburner.com/~r/LeBlogDesExpertsJ2ee/~4/wK-Y47WGZBQ\" height=\"1\" width=\"1\"/>]]></content:encoded>\r\n            <wfw:commentRss>http://blog.ippon.fr/2012/12/05/ippon-technologies-acquiert-atomes-et-renforce-son-offre-cloud/feed/</wfw:commentRss>\r\n        <slash:comments>0</slash:comments>\r\n        <feedburner:origLink>http://blog.ippon.fr/2012/12/05/ippon-technologies-acquiert-atomes-et-renforce-son-offre-cloud/</feedburner:origLink></item>\r\n        <item>\r\n        <title>Ippevent Mobilité – Applications mobiles – ouverture des inscriptions</title>\r\n        <link>http://feedproxy.google.com/~r/LeBlogDesExpertsJ2ee/~3/GcJYERHTfoQ/</link>\r\n        <comments>http://blog.ippon.fr/2012/12/03/ippevent-mobilite-applications-mobiles-ouverture-des-inscriptions/#comments</comments>\r\n        <pubDate>Mon, 03 Dec 2012 17:00:05 +0000</pubDate>\r\n        <dc:creator>Communication Ippon Technologies</dc:creator>\r\n                <category><![CDATA[Expertise Java]]></category>\r\n        <category><![CDATA[application mobile]]></category>\r\n        <category><![CDATA[développement]]></category>\r\n        <category><![CDATA[ios]]></category>\r\n        <category><![CDATA[Ippevent]]></category>\r\n        <category><![CDATA[POC]]></category>\r\n\r\n        <guid isPermaLink=\"false\">http://blog.ippon.fr/?p=7143</guid>\r\n        <description><![CDATA[ <p>Ippon Technologies vous accueille le Jeudi 20 décembre 2012 à partir de 19h00 pour une soirée Mobile First dans les locaux d&#8217;Ippon Technologies.</p> <p>Les consultants mobiles d&#8217;Ippon reviennent sur les grands projets qui ont rythmé l&#8217;année.</p> <p>Vous découvrirez des projets sous iOs, Android&#8230; Des applications natives et hybrides&#8230; Un socle d&#8217;architecture&#8230;.le tout appliqué au <span style=\"color:#777\"> . . . &#8594; Lire la suite: <a href=\"http://blog.ippon.fr/2012/12/03/ippevent-mobilite-applications-mobiles-ouverture-des-inscriptions/\">Ippevent Mobilité &#8211; Applications mobiles &#8211; ouverture des inscriptions</a></span>]]></description>\r\n            <content:encoded><![CDATA[<div style=\"width: 100%; text-align: left;\">\r\n<p>Ippon Technologies vous accueille <strong>le Jeudi 20 décembre 2012 à partir de 19h00</strong> pour une soirée Mobile First dans les locaux d&#8217;Ippon Technologies.</p>\r\n<p>Les consultants mobiles d&#8217;Ippon reviennent sur les grands projets qui ont rythmé l&#8217;année.</p>\r\n<p>Vous découvrirez des projets sous iOs, Android&#8230; Des applications natives et hybrides&#8230; Un socle d&#8217;architecture&#8230;.le tout appliqué au secteur des médias, de centres commerciaux et à l&#8217;environnement bancaire.</p>\r\n<p><strong>Programme de la soirée :</strong></p>\r\n<p>- <strong>&#8220;Le développement natif iOS versus développement d&#8217;application mobile hybride&#8221;</strong> par Nicolas Guillot, consultant mobile.</p>\r\n<p><a title=\"site information judopro\" href=\"http://www.judopro.fr/\" target=\"_blank\">Judopro</a> est à la fois une application native (iPad) et hybride (Android). Il vous présentera les principaux écueils rencontrés. Pour finir, il effectuera un comparatif des deux techniques de développement.</p>\r\n<p>- <strong>&#8220;L&#8217;adaptation des services métiers pour le développement mobile&#8221;</strong> par Lorys Pognon, architecte mobile.</p>\r\n<p>Lorys s&#8217;appuyera sur un projet de mise en place de l&#8217;architecture d’un socle pour les futurs développements sous iOS pour un environnement bancaire</p>\r\n<p>- <strong>&#8220;Application iOs de services au sein des centres commerciaux&#8221;</strong> par Raphaël Despinasse, Scrum Master.</p>\r\n<p>Les 3 interventions seront suivies d&#8217;un buffet pour continuer à échanger dans un cadre Encore plus convivial.</p>\r\n</div>\r\n<div style=\"width: 100%; text-align: left;\"><iframe frameborder=\"0\" height=\"214\" marginheight=\"5\" marginwidth=\"5\" scrolling=\"auto\" src=\"http://www.eventbrite.com/tickets-external?eid=4964954312&amp;ref=etckt&amp;v=2\" width=\"100%\"></iframe></div>\r\n<div style=\"font-family: Helvetica, Arial; font-size: 10px; padding: 5px 0 5px; margin: 2px; width: 100%; text-align: left;\"><a style=\"color: #ddd; text-decoration: none;\" href=\"http://www.eventbrite.com/r/etckt\" target=\"_blank\">Vendre des billets en ligne</a> <span style=\"color: #ddd;\">à travers</span> <a style=\"color: #ddd; text-decoration: none;\" href=\"http://www.eventbrite.com?ref=etckt\" target=\"_blank\">Eventbrite</a></div>\r\n<div style=\"font-family: Helvetica, Arial; font-size: 10px; padding: 5px 0 5px; margin: 2px; width: 100%; text-align: left;\">\r\n<p><strong>L&#8217;essentiel </strong></p>\r\n<p>Ippevent &#8211; Retour d&#8217;expérience Applications Mobiles</p>\r\n<p>Date : Jeudi 20 décembre 2012</p>\r\n<p>Heure : 19h00 &#8211; 22h00</p>\r\n<p>Lieu : Ippon Technologies &#8211; 90 rue Baudin, Levallois Perret</p>\r\n<p>Comment venir : Métro Pont de Levallois (l.3) &#8211; Transilien Clichy Levallois</p>\r\n<p>Des questions ? marketing@ippon.fr</p>\r\n<p>Suivez-nous : <a title=\"twitter ippon technologies\" href=\"https://twitter.com/ippontech\" target=\"_blank\">@ippontech</a> &#8211; <a title=\"blog ippon technologies\" href=\"http://blog.ippon.fr/\" target=\"_blank\">http://blog.ippon.fr/</a> &#8211; <a title=\"Ippon Mobile\" href=\"http://www.ippon-mobile.fr/\" target=\"_blank\">www.ippon-mobile.fr</a></p>\r\n</div>\r\n<!-- Start Shareaholic ClassicBookmarks Automatic --><!-- End Shareaholic ClassicBookmarks Automatic --><img src=\"http://feeds.feedburner.com/~r/LeBlogDesExpertsJ2ee/~4/GcJYERHTfoQ\" height=\"1\" width=\"1\"/>]]></content:encoded>\r\n            <wfw:commentRss>http://blog.ippon.fr/2012/12/03/ippevent-mobilite-applications-mobiles-ouverture-des-inscriptions/feed/</wfw:commentRss>\r\n        <slash:comments>0</slash:comments>\r\n        <feedburner:origLink>http://blog.ippon.fr/2012/12/03/ippevent-mobilite-applications-mobiles-ouverture-des-inscriptions/</feedburner:origLink></item>\r\n    </channel>\r\n</rss>\r\n"
  },
  {
    "path": "web/gruntfile.js",
    "content": "module.exports = function(grunt) {\n    require('load-grunt-tasks')(grunt);\n\n    var jsFiles = [\n        \"/assets/bower_components/angular/angular.min.js\",\n        \"/assets/bower_components/angular-touch/angular-touch.min.js\",\n        \"/assets/bower_components/angular-resource/angular-resource.min.js\",\n        \"/assets/bower_components/angular-sanitize/angular-sanitize.min.js\",\n        \"/assets/bower_components/angular-ui-router/release/angular-ui-router.min.js\",\n        \"/assets/bower_components/angular-translate/angular-translate.min.js\",\n        \"/assets/bower_components/angular-cookies/angular-cookies.min.js\",\n        \"/assets/bower_components/angular-translate-storage-cookie/angular-translate-storage-cookie.min.js\",\n        \"/assets/vendor/js/marked/marked.min.js\",\n        \"/assets/bower_components/moment/min/moment.min.js\",\n        \"/assets/bower_components/moment/locale/fr.js\",\n        \"/assets/bower_components/angular-moment/angular-moment.min.js\",\n        \"/assets/bower_components/ngInfiniteScroll/build/ng-infinite-scroll.min.js\",\n        \"/assets/bower_components/angular-bootstrap/ui-bootstrap.min.js\",\n        \"/assets/bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js\",\n        \"/assets/bower_components/ment.io/dist/mentio.js\",\n        \"/assets/bower_components/angular-animate/angular-animate.min.js\",\n        \"/assets/bower_components/ngtoast/dist/ngToast.min.js\",\n        \"/assets/bower_components/ng-file-upload/angular-file-upload-shim.min.js\",\n        \"/assets/bower_components/ng-file-upload/angular-file-upload.min.js\",\n        \"/assets/bower_components/openlayers/OpenLayers.min.js\",\n        \"/assets/bower_components/angular-local-storage/dist/angular-local-storage.min.js\",\n        \"/assets/bower_components/jquery/dist/jquery.min.js\",\n        \"/assets/vendor/css/bootstrap/js/bootstrap.min.js\",\n        \"/assets/bower_components/bootstrap-tour/build/js/bootstrap-tour.min.js\",\n        \"/assets/bower_components/angular-bootstrap-tour/dist/angular-bootstrap-tour.js\",\n        \"/app/TatamiApp.js\",\n        \"/app/shared/topMenu/TopMenuModule.js\",\n        \"/app/components/login/LoginModule.js\",\n        \"/app/components/about/AboutModule.js\",\n        \"/app/components/home/HomeModule.js\",\n        \"/app/components/account/AccountModule.js\",\n        \"/app/components/admin/AdminModule.js\",\n        \"/app/components/about/license/LicenseController.js\",\n        \"/app/shared/sidebars/home/HomeSidebarModule.js\",\n        \"/app/shared/sidebars/home/HomeSidebarController.js\",\n        \"/app/shared/sidebars/profile/ProfileSidebarModule.js\",\n        \"/app/shared/sidebars/profile/ProfileSidebarController.js\",\n        \"/app/components/home/tag/TagHeaderController.js\",\n        \"/app/components/home/search/SearchHeaderController.js\",\n        \"/app/components/home/group/GroupHeaderController.js\",\n        \"/app/components/home/profile/ProfileHeaderController.js\",\n        \"/app/components/home/status/StatusController.js\",\n        \"/app/shared/lists/status/withoutContext/StatusListController.js\",\n        \"/app/shared/lists/user/UserListController.js\",\n        \"/app/shared/topMenu/post/PostModule.js\",\n        \"/app/shared/topMenu/post/PostController.js\",\n        \"/app/shared/footer/FooterModule.js\",\n        \"/app/shared/footer/FooterController.js\",\n        \"/app/components/home/welcome/WelcomeController.js\",\n        \"/app/components/admin/AdminController.js\",\n        \"/app/components/admin/AdminService.js\",\n        \"/app/components/account/AccountController.js\",\n        \"/app/components/account/FormController.js\",\n        \"/app/components/account/profile/ProfileModule.js\",\n        \"/app/components/account/profile/ProfileController.js\",\n        \"/app/components/account/preferences/PreferencesModule.js\",\n        \"/app/components/account/preferences/PreferencesController.js\",\n        \"/app/components/account/preferences/PreferencesService.js\",\n        \"/app/components/account/password/PasswordModule.js\",\n        \"/app/components/account/password/PasswordController.js\",\n        \"/app/components/account/password/PasswordService.js\",\n        \"/app/components/account/files/FilesModule.js\",\n        \"/app/components/account/files/FilesController.js\",\n        \"/app/components/account/files/FilesService.js\",\n        \"/app/components/account/users/UsersModule.js\",\n        \"/app/components/account/users/UsersController.js\",\n        \"/app/components/account/groups/GroupsModule.js\",\n        \"/app/components/account/groups/GroupsController.js\",\n        \"/app/components/account/groups/manage/GroupsManageController.js\",\n        \"/app/components/account/groups/creation/GroupsCreateController.js\",\n        \"/app/components/account/groups/list/GroupListController.js\",\n        \"/app/components/account/tags/TagsModule.js\",\n        \"/app/components/account/tags/TagsController.js\",\n        \"/app/components/account/topPosters/TopPostersModule.js\",\n        \"/app/components/account/topPosters/TopPostersController.js\",\n        \"/app/components/login/LoginModule.js\",\n        \"/app/components/login/manual/ManualLoginController.js\",\n        \"/app/components/login/recoverPassword/RecoverPasswordController.js\",\n        \"/app/components/login/register/RegisterController.js\",\n        \"/app/components/login/google/GoogleLoginController.js\",\n        \"/app/components/login/email/EmailRegistrationController.js\",\n        \"/app/components/login/RegistrationService.js\",\n        \"/app/shared/configs/MarkedConfig.js\",\n        \"/app/shared/configs/MomentConfig.js\",\n        \"/app/shared/configs/TranslateConfig.js\",\n        \"/app/shared/filters/MarkdownFilter.js\",\n        \"/app/shared/filters/EmoticonFilter.js\",\n        \"/app/shared/filters/PlaceholderFilter.js\",\n        \"/app/shared/services/HomeService.js\",\n        \"/app/shared/services/StatusService.js\",\n        \"/app/shared/services/ProfileService.js\",\n        \"/app/shared/services/UserService.js\",\n        \"/app/shared/services/GroupService.js\",\n        \"/app/shared/services/TagService.js\",\n        \"/app/shared/services/GeolocService.js\",\n        \"/app/shared/services/SearchService.js\",\n        \"/app/shared/services/TopPostersService.js\",\n        \"/app/shared/services/UserSession.js\",\n        \"/app/shared/services/AuthenticationService.js\",\n        \"/app/shared/topMenu/TopMenuController.js\"\n    ]\n\n    var cssFiles = [\n        \"assets/bower_components/ment.io/ment.io/styles.css\",\n        \"assets/bower_components/ngtoast/dist/ngToast.min.css\",\n        \"assets/vendor/css/bootstrap/css/bootstrap.css\",\n        \"assets/bower_components/bootstrap-tour/build/css/bootstrap-tour.css\"\n    ]\n\n\n\n    var prepareMinification = function(prepFiles, prefixPath) {\n        var result = [];\n        for(var file = 0; file < prepFiles.length; ++file) {\n            result.push(prefixPath + prepFiles[file]);\n        }\n        return result;\n    }\n\n    var prepareTags = function(prepFiles, open, close) {\n        var result = '';\n        var end = '\\n\\t';\n        for(var file = 0; file < prepFiles.length; ++file) {\n            if(file == prepFiles.length-1) { end = ''; }\n            result += open + prepFiles[file] + close + end;\n        }\n        return result;\n    }\n\n    var filePrefix = 'src/main/webapp/';\n\n    grunt.initConfig({\n        template: {\n            prepareMinIndex: {\n                options: {\n                    data: {\n                        jsTags: '<script src=\"TATAMI.CONCAT.js\"></script>',\n                        cssTags: '<link href=\"/css/CSSMIN.css\" rel=\"stylesheet\" type=\"text/css\">'\n                    }\n                },\n                files: {\n                    'src/main/webapp/index.html': ['src/main/webapp/index.html.tpl']\n                }\n            },\n            prepareDevIndex: {\n                options: {\n                    data: {\n                        jsTags: prepareTags(jsFiles, '<script src=\"', '\"></script>'),\n                        cssTags: prepareTags(cssFiles, '<link href=\"', '\" rel=\"stylesheet\" type=\"text/css\">')\n                    }\n                },\n                files: {\n                    'src/main/webapp/index.html': ['src/main/webapp/index.html.tpl']\n                }\n            }\n        },\n        clean: [\n            'src/main/webapp/TATAMI.CONCAT.js',\n            'src/main/webapp/css/CSSMIN.css',\n            '**/*.min.html',\n            'src/main/webapp/index.html'],\n        uglify: {\n            options: {\n                mangle: false\n            },\n            BuildingTatamiConcat: {\n                files: {\n                    'src/main/webapp/TATAMI.CONCAT.js': prepareMinification(jsFiles, filePrefix)\n                }\n            }\n        },\n        cssmin: {\n            target: {\n                files: { //tatami.css should not be minified-- it breaks.\n                    'src/main/webapp/css/CSSMIN.css': prepareMinification(cssFiles, filePrefix)\n                }\n            }\n        },\n        htmlmin: {\n            dist: {\n                options: {\n                    removeComments: true,\n                    collapseWhitespace: true\n                },\n                files: {// 'destination': 'source'\n                    'src/main/webapp/app/components/about/tos/ToSView.min.html': 'src/main/webapp/app/components/about/tos/ToSView.html',\n                    'src/main/webapp/app/components/about/license/LicenseView.min.html': 'src/main/webapp/app/components/about/license/LicenseView.html',\n                    'src/main/webapp/app/components/about/presentation/PresentationView.min.html': 'src/main/webapp/app/components/about/presentation/PresentationView.html',\n                    'src/main/webapp/app/components/account/AccountView.min.html': 'src/main/webapp/app/components/account/AccountView.html',\n                    'src/main/webapp/app/components/account/profile/ProfileView.min.html': 'src/main/webapp/app/components/account/profile/ProfileView.html',\n                    'src/main/webapp/app/components/account/preferences/PreferencesView.min.html':'src/main/webapp/app/components/account/preferences/PreferencesView.html',\n                    'src/main/webapp/app/components/account/password/PasswordView.min.html': 'src/main/webapp/app/components/account/password/PasswordView.html',\n                    'src/main/webapp/app/components/account/files/FilesView.min.html':'src/main/webapp/app/components/account/files/FilesView.html',\n                    'src/main/webapp/app/components/account/FormView.min.html':'src/main/webapp/app/components/account/FormView.html',\n                    'src/main/webapp/app/components/account/users/UsersView.min.html':'src/main/webapp/app/components/account/users/UsersView.html',\n                    'src/main/webapp/app/components/account/groups/GroupsView.min.html':'src/main/webapp/app/components/account/groups/GroupsView.html',\n                    'src/main/webapp/app/components/account/groups/creation/GroupsCreateView.min.html':'src/main/webapp/app/components/account/groups/creation/GroupsCreateView.html',\n                    'src/main/webapp/app/components/account/groups/list/GroupsListView.min.html':'src/main/webapp/app/components/account/groups/list/GroupsListView.html',\n                    'src/main/webapp/app/components/account/groups/manage/GroupsManageView.min.html':'src/main/webapp/app/components/account/groups/manage/GroupsManageView.html',\n                    'src/main/webapp/app/components/account/tags/TagsView.min.html':'src/main/webapp/app/components/account/tags/TagsView.html',\n                    'src/main/webapp/app/components/account/topPosters/TopPostersView.min.html':'src/main/webapp/app/components/account/topPosters/TopPostersView.html',\n                    'src/main/webapp/app/components/admin/AdminView.min.html':'src/main/webapp/app/components/admin/AdminView.html',\n                    'src/main/webapp/app/components/home/HomeView.min.html':'src/main/webapp/app/components/home/HomeView.html',\n                    'src/main/webapp/app/components/home/status/StatusView.min.html':'src/main/webapp/app/components/home/status/StatusView.html',\n                    'src/main/webapp/app/components/home/search/SearchHeaderView.min.html':'src/main/webapp/app/components/home/search/SearchHeaderView.html',\n                    'src/main/webapp/app/components/home/tag/TagHeaderView.min.html':'src/main/webapp/app/components/home/tag/TagHeaderView.html',\n                    'src/main/webapp/app/shared/lists/status/withoutContext/StatusListView.min.html':'src/main/webapp/app/shared/lists/status/withoutContext/StatusListView.html',\n                    'src/main/webapp/app/shared/sidebars/home/HomeSidebarView.min.html':'src/main/webapp/app/shared/sidebars/home/HomeSidebarView.html',\n                    'src/main/webapp/app/components/home/timeline/TimelineHeaderView.min.html':'src/main/webapp/app/components/home/timeline/TimelineHeaderView.html',\n                    'src/main/webapp/app/components/home/welcome/WelcomeView.min.html':'src/main/webapp/app/components/home/welcome/WelcomeView.html',\n                    'src/main/webapp/app/shared/lists/user/UserListView.min.html':'src/main/webapp/app/shared/lists/user/UserListView.html',\n                    'src/main/webapp/app/components/home/group/GroupHeaderView.min.html':'src/main/webapp/app/components/home/group/GroupHeaderView.html',\n                    'src/main/webapp/app/shared/topMenu/post/PostView.min.html':'src/main/webapp/app/shared/topMenu/post/PostView.html',\n                    'src/main/webapp/app/shared/sidebars/profile/ProfileSidebarView.min.html':'src/main/webapp/app/shared/sidebars/profile/ProfileSidebarView.html',\n                    'src/main/webapp/app/components/home/profile/ProfileHeaderView.min.html':'src/main/webapp/app/components/home/profile/ProfileHeaderView.html',\n                    //Login Module\n                    'src/main/webapp/app/components/login/LoginView.min.html':'src/main/webapp/app/components/login/LoginView.html',\n                    'src/main/webapp/app/components/login/manual/ManualLoginView.min.html':'src/main/webapp/app/components/login/manual/ManualLoginView.html',\n                    'src/main/webapp/app/components/login/recoverPassword/RecoverPasswordView.min.html':'src/main/webapp/app/components/login/recoverPassword/RecoverPasswordView.html',\n                    'src/main/webapp/app/components/login/google/GoogleLoginView.min.html':'src/main/webapp/app/components/login/google/GoogleLoginView.html',\n                    'src/main/webapp/app/components/login/register/RegisterView.min.html':'src/main/webapp/app/components/login/register/RegisterView.html',\n                    'src/main/webapp/app/components/login/email/EmailRegistration.min.html':'src/main/webapp/app/components/login/email/EmailRegistration.html',\n                    //TatamiApp module\n                    'src/main/webapp/app/shared/topMenu/TopMenuView.min.html':'src/main/webapp/app/shared/topMenu/TopMenuView.html',\n                    'src/main/webapp/app/shared/footer/FooterView.min.html':'src/main/webapp/app/shared/footer/FooterView.html',\n                    'src/main/webapp/app/shared/error/404View.min.html':'src/main/webapp/app/shared/error/404View.html',\n                    'src/main/webapp/app/shared/error/500View.min.html':'src/main/webapp/app/shared/error/500View.html'\n\n                }\n            }\n        },\n        concurrent: {\n            minifyTarget: ['template:prepareMinIndex', 'cssmin', 'htmlmin', 'uglify'],\n            devTarget: ['template:prepareDevIndex', 'htmlmin']\n        }\n\n   } );\n    grunt.loadNpmTasks('grunt-template');\n    grunt.loadNpmTasks('grunt-contrib-clean');\n    grunt.loadNpmTasks('grunt-contrib-uglify');\n    grunt.loadNpmTasks('grunt-contrib-cssmin');\n    grunt.loadNpmTasks('grunt-contrib-htmlmin');\n    grunt.registerTask('minify', ['clean','concurrent:minifyTarget']);\n    grunt.registerTask('dev', ['clean', 'concurrent:devTarget']);\n};"
  },
  {
    "path": "web/karma.ci.conf.js",
    "content": "// Karma configuration\n// Generated on Wed May 06 2015 15:23:11 GMT-0400 (EDT)\n\nmodule.exports = function(config) {\n  config.set({\n\n    // base path that will be used to resolve all patterns (eg. files, exclude)\n    basePath: '',\n\n\n    // frameworks to use\n    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter\n    frameworks: ['jasmine'],\n\n    // list of files / patterns to load in the browser\n    files: [\n        \"src/main/webapp/assets/bower_components/angular/angular.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-mocks/angular-mocks.js\",\n        \"src/main/webapp/assets/bower_components/angular-route/angular-route.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-touch/angular-touch.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-resource/angular-resource.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-sanitize/angular-sanitize.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-ui-router/release/angular-ui-router.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-translate/angular-translate.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-cookies/angular-cookies.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-translate-storage-cookie/angular-translate-storage-cookie.min.js\",\n        \"src/main/webapp/assets/vendor/js/marked/marked.min.js\",\n        \"src/main/webapp/assets/bower_components/moment/min/moment.min.js\",\n        \"src/main/webapp/assets/bower_components/moment/locale/fr.js\",\n        \"src/main/webapp/assets/bower_components/angular-moment/angular-moment.min.js\",\n        \"src/main/webapp/assets/bower_components/ngInfiniteScroll/build/ng-infinite-scroll.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-bootstrap/ui-bootstrap.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js\",\n        \"src/main/webapp/assets/bower_components/ment.io/dist/mentio.js\",\n        \"src/main/webapp/assets/bower_components/angular-animate/angular-animate.min.js\",\n        \"src/main/webapp/assets/bower_components/ngtoast/dist/ngToast.min.js\",\n        \"src/main/webapp/assets/bower_components/ng-file-upload/angular-file-upload-shim.min.js\",\n        \"src/main/webapp/assets/bower_components/ng-file-upload/angular-file-upload.min.js\",\n        \"src/main/webapp/assets/bower_components/openlayers/OpenLayers.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-local-storage/dist/angular-local-storage.min.js\",\n        \"src/main/webapp/assets/bower_components/jquery/dist/jquery.min.js\",\n        \"src/main/webapp/assets/vendor/css/bootstrap/js/bootstrap.min.js\",\n        \"src/main/webapp/assets/bower_components/bootstrap-tour/build/js/bootstrap-tour.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-bootstrap-tour/dist/angular-bootstrap-tour.js\",\n        \"src/main/webapp/app/TatamiApp.js\",\n        \"src/main/webapp/app/shared/topMenu/TopMenuModule.js\",\n        \"src/main/webapp/app/components/login/LoginModule.js\",\n        \"src/main/webapp/app/components/about/AboutModule.js\",\n        \"src/main/webapp/app/components/home/HomeModule.js\",\n        \"src/main/webapp/app/components/account/AccountModule.js\",\n        \"src/main/webapp/app/components/admin/AdminModule.js\",\n        \"src/main/webapp/app/components/about/license/LicenseController.js\",\n        \"src/main/webapp/app/shared/sidebars/home/HomeSidebarModule.js\",\n        \"src/main/webapp/app/shared/sidebars/home/HomeSidebarController.js\",\n        \"src/main/webapp/app/shared/sidebars/profile/ProfileSidebarModule.js\",\n        \"src/main/webapp/app/shared/sidebars/profile/ProfileSidebarController.js\",\n        \"src/main/webapp/app/components/home/tag/TagHeaderController.js\",\n        \"src/main/webapp/app/components/home/search/SearchHeaderController.js\",\n        \"src/main/webapp/app/components/home/group/GroupHeaderController.js\",\n        \"src/main/webapp/app/components/home/profile/ProfileHeaderController.js\",\n        \"src/main/webapp/app/components/home/status/StatusController.js\",\n        \"src/main/webapp/app/shared/lists/status/withoutContext/StatusListController.js\",\n        \"src/main/webapp/app/shared/lists/user/UserListController.js\",\n        \"src/main/webapp/app/shared/topMenu/post/PostModule.js\",\n        \"src/main/webapp/app/shared/topMenu/post/PostController.js\",\n        \"src/main/webapp/app/components/home/welcome/WelcomeController.js\",\n        \"src/main/webapp/app/components/admin/AdminController.js\",\n        \"src/main/webapp/app/components/admin/AdminService.js\",\n        \"src/main/webapp/app/components/account/AccountController.js\",\n        \"src/main/webapp/app/components/account/FormController.js\",\n        \"src/main/webapp/app/components/account/profile/ProfileModule.js\",\n        \"src/main/webapp/app/components/account/profile/ProfileController.js\",\n        \"src/main/webapp/app/components/account/preferences/PreferencesModule.js\",\n        \"src/main/webapp/app/components/account/preferences/PreferencesController.js\",\n        \"src/main/webapp/app/components/account/preferences/PreferencesService.js\",\n        \"src/main/webapp/app/components/account/password/PasswordModule.js\",\n        \"src/main/webapp/app/components/account/password/PasswordController.js\",\n        \"src/main/webapp/app/components/account/password/PasswordService.js\",\n        \"src/main/webapp/app/components/account/files/FilesModule.js\",\n        \"src/main/webapp/app/components/account/files/FilesController.js\",\n        \"src/main/webapp/app/components/account/files/FilesService.js\",\n        \"src/main/webapp/app/components/account/users/UsersModule.js\",\n        \"src/main/webapp/app/components/account/users/UsersController.js\",\n        \"src/main/webapp/app/components/account/groups/GroupsModule.js\",\n        \"src/main/webapp/app/components/account/groups/GroupsController.js\",\n        \"src/main/webapp/app/components/account/groups/manage/GroupsManageController.js\",\n        \"src/main/webapp/app/components/account/groups/creation/GroupsCreateController.js\",\n        \"src/main/webapp/app/components/account/groups/list/GroupListController.js\",\n        \"src/main/webapp/app/components/account/tags/TagsModule.js\",\n        \"src/main/webapp/app/components/account/tags/TagsController.js\",\n        \"src/main/webapp/app/components/account/topPosters/TopPostersModule.js\",\n        \"src/main/webapp/app/components/account/topPosters/TopPostersController.js\",\n        \"src/main/webapp/app/components/login/LoginModule.js\",\n        \"src/main/webapp/app/components/login/manual/ManualLoginController.js\",\n        \"src/main/webapp/app/components/login/recoverPassword/RecoverPasswordController.js\",\n        \"src/main/webapp/app/components/login/register/RegisterController.js\",\n        \"src/main/webapp/app/components/login/google/GoogleLoginController.js\",\n        \"src/main/webapp/app/components/login/email/EmailRegistrationController.js\",\n        \"src/main/webapp/app/components/login/RegistrationService.js\",\n        \"src/main/webapp/app/shared/configs/MarkedConfig.js\",\n        \"src/main/webapp/app/shared/configs/MomentConfig.js\",\n        \"src/main/webapp/app/shared/configs/TranslateConfig.js\",\n        \"src/main/webapp/app/shared/filters/MarkdownFilter.js\",\n        \"src/main/webapp/app/shared/filters/EmoticonFilter.js\",\n        \"src/main/webapp/app/shared/filters/PlaceholderFilter.js\",\n        \"src/main/webapp/app/shared/services/HomeService.js\",\n        \"src/main/webapp/app/shared/services/StatusService.js\",\n        \"src/main/webapp/app/shared/services/ProfileService.js\",\n        \"src/main/webapp/app/shared/services/UserService.js\",\n        \"src/main/webapp/app/shared/services/GroupService.js\",\n        \"src/main/webapp/app/shared/services/TagService.js\",\n        \"src/main/webapp/app/shared/services/GeolocService.js\",\n        \"src/main/webapp/app/shared/services/SearchService.js\",\n        \"src/main/webapp/app/shared/services/TopPostersService.js\",\n        \"src/main/webapp/app/shared/services/UserSession.js\",\n        \"src/main/webapp/app/shared/services/AuthenticationService.js\",\n        \"src/main/webapp/app/shared/topMenu/TopMenuController.js\",\n\n        \"src/test/javascript/**/*.js\"\n    ],\n\n\n    // list of files to exclude\n    exclude: [\n      '**/*.swp'\n    ],\n\n\n    // preprocess matching files before serving them to the browser\n    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor\n    preprocessors: {\n        'src/**/*.js': ['coverage']\n    },\n\n\n    // test results reporter to use\n    // possible values: 'dots', 'progress'\n    // available reporters: https://npmjs.org/browse/keyword/karma-reporter\n    reporters: ['dots', 'jenkins','coverage', 'progress'],\n\n    jenkinsReporter: {\n        outputFile: 'target/test-results/karma/TESTS-resuts.xml'\n    },\n\n    coverageReporter: {\n        dir: 'target/test-results/coverage',\n\n        reporters: [\n            { type: 'lcov', subdir: 'report-lcov'}\n        ]\n    },\n\n    // web server port\n    port: 9876,\n\n\n    // enable / disable colors in the output (reporters and logs)\n    colors: true,\n\n\n    // level of logging\n    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG\n    logLevel: config.LOG_INFO,\n\n\n    // enable / disable watching file and executing tests whenever any file changes\n    autoWatch: false,\n\n\n    // start these browsers\n    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher\n    browsers: ['PhantomJS'],\n\n\n    // Continuous Integration mode\n    // if true, Karma captures browsers, runs the tests and exits\n    singleRun: true\n  });\n};\n"
  },
  {
    "path": "web/karma.conf.js",
    "content": "// Karma configuration\n// Generated on Wed May 06 2015 15:23:11 GMT-0400 (EDT)\n\nmodule.exports = function(config) {\n  config.set({\n\n    // base path that will be used to resolve all patterns (eg. files, exclude)\n    basePath: '',\n\n\n    // frameworks to use\n    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter\n    frameworks: ['jasmine'],\n \n    // list of files / patterns to load in the browser\n    files: [\n        \"src/main/webapp/assets/bower_components/angular/angular.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-mocks/angular-mocks.js\",\n        \"src/main/webapp/assets/bower_components/angular-route/angular-route.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-touch/angular-touch.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-resource/angular-resource.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-sanitize/angular-sanitize.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-ui-router/release/angular-ui-router.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-translate/angular-translate.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-cookies/angular-cookies.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-translate-storage-cookie/angular-translate-storage-cookie.min.js\",\n        \"src/main/webapp/assets/vendor/js/marked/marked.min.js\",\n        \"src/main/webapp/assets/bower_components/moment/min/moment.min.js\",\n        \"src/main/webapp/assets/bower_components/moment/locale/fr.js\",\n        \"src/main/webapp/assets/bower_components/angular-moment/angular-moment.min.js\",\n        \"src/main/webapp/assets/bower_components/ngInfiniteScroll/build/ng-infinite-scroll.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-bootstrap/ui-bootstrap.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js\",\n        \"src/main/webapp/assets/bower_components/ment.io/dist/mentio.js\",\n        \"src/main/webapp/assets/bower_components/angular-animate/angular-animate.min.js\",\n        \"src/main/webapp/assets/bower_components/ngtoast/dist/ngToast.min.js\",\n        \"src/main/webapp/assets/bower_components/ng-file-upload/angular-file-upload-shim.min.js\",\n        \"src/main/webapp/assets/bower_components/ng-file-upload/angular-file-upload.min.js\",\n        \"src/main/webapp/assets/bower_components/openlayers/OpenLayers.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-local-storage/dist/angular-local-storage.min.js\",\n        \"src/main/webapp/assets/bower_components/jquery/dist/jquery.min.js\",\n        \"src/main/webapp/assets/vendor/css/bootstrap/js/bootstrap.min.js\",\n        \"src/main/webapp/assets/bower_components/bootstrap-tour/build/js/bootstrap-tour.min.js\",\n        \"src/main/webapp/assets/bower_components/angular-bootstrap-tour/dist/angular-bootstrap-tour.js\",\n        \"src/main/webapp/app/TatamiApp.js\",\n        \"src/main/webapp/app/shared/topMenu/TopMenuModule.js\",\n        \"src/main/webapp/app/components/login/LoginModule.js\",\n        \"src/main/webapp/app/components/about/AboutModule.js\",\n        \"src/main/webapp/app/components/home/HomeModule.js\",\n        \"src/main/webapp/app/components/account/AccountModule.js\",\n        \"src/main/webapp/app/components/admin/AdminModule.js\",\n        \"src/main/webapp/app/components/about/license/LicenseController.js\",\n        \"src/main/webapp/app/shared/sidebars/home/HomeSidebarModule.js\",\n        \"src/main/webapp/app/shared/sidebars/home/HomeSidebarController.js\",\n        \"src/main/webapp/app/shared/sidebars/profile/ProfileSidebarModule.js\",\n        \"src/main/webapp/app/shared/sidebars/profile/ProfileSidebarController.js\",\n        \"src/main/webapp/app/components/home/tag/TagHeaderController.js\",\n        \"src/main/webapp/app/components/home/search/SearchHeaderController.js\",\n        \"src/main/webapp/app/components/home/group/GroupHeaderController.js\",\n        \"src/main/webapp/app/components/home/profile/ProfileHeaderController.js\",\n        \"src/main/webapp/app/components/home/status/StatusController.js\",\n        \"src/main/webapp/app/shared/lists/status/withoutContext/StatusListController.js\",\n        \"src/main/webapp/app/shared/lists/user/UserListController.js\",\n        \"src/main/webapp/app/shared/topMenu/post/PostModule.js\",\n        \"src/main/webapp/app/shared/topMenu/post/PostController.js\",\n        \"src/main/webapp/app/components/home/welcome/WelcomeController.js\",\n        \"src/main/webapp/app/components/admin/AdminController.js\",\n        \"src/main/webapp/app/components/admin/AdminService.js\",\n        \"src/main/webapp/app/components/account/AccountController.js\",\n        \"src/main/webapp/app/components/account/FormController.js\",\n        \"src/main/webapp/app/components/account/profile/ProfileModule.js\",\n        \"src/main/webapp/app/components/account/profile/ProfileController.js\",\n        \"src/main/webapp/app/components/account/preferences/PreferencesModule.js\",\n        \"src/main/webapp/app/components/account/preferences/PreferencesController.js\",\n        \"src/main/webapp/app/components/account/preferences/PreferencesService.js\",\n        \"src/main/webapp/app/components/account/password/PasswordModule.js\",\n        \"src/main/webapp/app/components/account/password/PasswordController.js\",\n        \"src/main/webapp/app/components/account/password/PasswordService.js\",\n        \"src/main/webapp/app/components/account/files/FilesModule.js\",\n        \"src/main/webapp/app/components/account/files/FilesController.js\",\n        \"src/main/webapp/app/components/account/files/FilesService.js\",\n        \"src/main/webapp/app/components/account/users/UsersModule.js\",\n        \"src/main/webapp/app/components/account/users/UsersController.js\",\n        \"src/main/webapp/app/components/account/groups/GroupsModule.js\",\n        \"src/main/webapp/app/components/account/groups/GroupsController.js\",\n        \"src/main/webapp/app/components/account/groups/manage/GroupsManageController.js\",\n        \"src/main/webapp/app/components/account/groups/creation/GroupsCreateController.js\",\n        \"src/main/webapp/app/components/account/groups/list/GroupListController.js\",\n        \"src/main/webapp/app/components/account/tags/TagsModule.js\",\n        \"src/main/webapp/app/components/account/tags/TagsController.js\",\n        \"src/main/webapp/app/components/account/topPosters/TopPostersModule.js\",\n        \"src/main/webapp/app/components/account/topPosters/TopPostersController.js\",\n        \"src/main/webapp/app/components/login/LoginModule.js\",\n        \"src/main/webapp/app/components/login/manual/ManualLoginController.js\",\n        \"src/main/webapp/app/components/login/recoverPassword/RecoverPasswordController.js\",\n        \"src/main/webapp/app/components/login/register/RegisterController.js\",\n        \"src/main/webapp/app/components/login/google/GoogleLoginController.js\",\n        \"src/main/webapp/app/components/login/email/EmailRegistrationController.js\",\n        \"src/main/webapp/app/components/login/RegistrationService.js\",\n        \"src/main/webapp/app/shared/configs/MarkedConfig.js\",\n        \"src/main/webapp/app/shared/configs/MomentConfig.js\",\n        \"src/main/webapp/app/shared/configs/TranslateConfig.js\",\n        \"src/main/webapp/app/shared/filters/MarkdownFilter.js\",\n        \"src/main/webapp/app/shared/filters/EmoticonFilter.js\",\n        \"src/main/webapp/app/shared/filters/PlaceholderFilter.js\",\n        \"src/main/webapp/app/shared/services/HomeService.js\",\n        \"src/main/webapp/app/shared/services/StatusService.js\",\n        \"src/main/webapp/app/shared/services/ProfileService.js\",\n        \"src/main/webapp/app/shared/services/UserService.js\",\n        \"src/main/webapp/app/shared/services/GroupService.js\",\n        \"src/main/webapp/app/shared/services/TagService.js\",\n        \"src/main/webapp/app/shared/services/GeolocService.js\",\n        \"src/main/webapp/app/shared/services/SearchService.js\",\n        \"src/main/webapp/app/shared/services/TopPostersService.js\",\n        \"src/main/webapp/app/shared/services/UserSession.js\",\n        \"src/main/webapp/app/shared/services/AuthenticationService.js\",\n        \"src/main/webapp/app/shared/topMenu/TopMenuController.js\",\n\n        \"src/test/javascript/**/*.js\"\n    ],\n\n\n    // list of files to exclude\n    exclude: [\n      '**/*.swp'\n    ],\n\n\n    // preprocess matching files before serving them to the browser\n    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor\n    preprocessors: {\n    },\n\n\n    // test results reporter to use\n    // possible values: 'dots', 'progress'\n    // available reporters: https://npmjs.org/browse/keyword/karma-reporter\n    reporters: ['dots', 'progress' ],\n\n\n    htmlReporter: {\n        outputFile: 'target/test-results/karma/results.html'\n    },\n    // web server port\n    port: 9876,\n\n\n    // enable / disable colors in the output (reporters and logs)\n    colors: true,\n\n\n    // level of logging\n    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG\n    logLevel: config.LOG_INFO,\n\n\n    // enable / disable watching file and executing tests whenever any file changes\n    autoWatch: true,\n\n\n    // start these browsers\n    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher\n    browsers: ['PhantomJS'],\n\n\n    // Continuous Integration mode\n    // if true, Karma captures browsers, runs the tests and exits\n    singleRun: false\n  });\n};\n"
  },
  {
    "path": "web/package.json",
    "content": "{\n  \"name\": \"Tatami\",\n  \"description\": \"\",\n  \"version\": \"4.0.1\",\n  \"private\": true,\n  \"devDependencies\": {\n    \"bower\": \"^1.5.3\",\n    \"grunt\": \"^0.4.5\",\n    \"grunt-cli\": \"^0.1.13\",\n    \"grunt-concat\": \"^0.1.6\",\n    \"grunt-concurrent\": \"^1.0.0\",\n    \"grunt-contrib-clean\": \"^0.6.0\",\n    \"grunt-contrib-cssmin\": \"^0.12.2\",\n    \"grunt-contrib-htmlmin\": \"^0.4.0\",\n    \"grunt-contrib-uglify\": \"^0.9.1\",\n    \"grunt-template\": \"^0.2.3\",\n    \"jasmine-core\": \"^2.3.4\",\n    \"karma\": \"^0.13.10\",\n    \"karma-chrome-launcher\": \"^0.2.0\",\n    \"karma-cli\": \"^0.1.1\",\n    \"karma-coverage\": \"^0.5.2\",\n    \"karma-firefox-launcher\": \"^0.1.6\",\n    \"karma-ie-launcher\": \"^0.2.0\",\n    \"karma-jasmine\": \"^0.3.6\",\n    \"karma-jenkins-reporter\": \"0.0.2\",\n    \"karma-jshint\": \"^0.1.0\",\n    \"karma-junit-reporter\": \"^0.3.6\",\n    \"karma-phantomjs-launcher\": \"^0.2.1\",\n    \"karma-safari-launcher\": \"^0.1.1\",\n    \"load-grunt-tasks\": \"^3.3.0\",\n    \"phantomjs\": \"^1.9.18\"\n  }\n}\n"
  },
  {
    "path": "web/pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <parent>\n        <artifactId>tatami</artifactId>\n        <groupId>fr.ippon.tatami</groupId>\n        <version>4.0.5</version>\n    </parent>\n\n    <modelVersion>4.0.0</modelVersion>\n    <packaging>war</packaging>\n    <artifactId>web</artifactId>\n\n    <dependencies>\n        <dependency>\n            <groupId>fr.ippon.tatami</groupId>\n            <artifactId>services</artifactId>\n            <version>4.0.5</version>\n        </dependency>\n        <dependency>\n            <groupId>fr.ippon.tatami</groupId>\n            <artifactId>services</artifactId>\n            <version>4.0.5</version>\n            <type>test-jar</type>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n\n    <profiles>\n        <profile>\n            <id>default</id>\n            <activation>\n                <activeByDefault>true</activeByDefault>\n            </activation>\n            <build>\n                <plugins>\n                    <plugin>\n                        <groupId>org.codehaus.mojo</groupId>\n                        <artifactId>exec-maven-plugin</artifactId>\n                        <version>1.2.1</version>\n                        <executions>\n                            <execution>\n                                <phase>compile</phase>\n                                <goals>\n                                    <goal>exec</goal>\n                                </goals>\n                                <configuration>\n                                    <executable>${project.npm.bin}/grunt</executable>\n                                    <arguments>\n                                        <argument>dev</argument>\n                                    </arguments>\n                                </configuration>\n                            </execution>\n                        </executions>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n        <profile>\n            <id>uglified</id>\n            <build>\n                <plugins>\n                    <plugin>\n                        <groupId>org.codehaus.mojo</groupId>\n                        <artifactId>exec-maven-plugin</artifactId>\n                        <version>1.2.1</version>\n                        <executions>\n                            <execution>\n                                <phase>compile</phase>\n                                <goals>\n                                    <goal>exec</goal>\n                                </goals>\n                                <configuration>\n                                    <executable>${project.npm.bin}/grunt</executable>\n                                    <arguments>\n                                        <argument>minify</argument>\n                                    </arguments>\n                                </configuration>\n                            </execution>\n                        </executions>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n    </profiles>\n    <build>\n        <finalName>tatami-${project.version}</finalName>\n        <plugins>\n            <plugin>\n                <groupId>com.kelveden</groupId>\n                <artifactId>maven-karma-plugin</artifactId>\n                <version>1.6</version>\n                <executions>\n                    <execution>\n                        <phase>test</phase>\n                        <goals>\n                            <goal>start</goal>\n                        </goals>\n                    </execution>\n                </executions>\n                <configuration>\n                    <karmaExecutable>${project.basedir}/node_modules/.bin/karma</karmaExecutable>\n                    <configFile>${project.basedir}/karma.ci.conf.js</configFile>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-war-plugin</artifactId>\n                <version>${maven.war.version}</version>\n                <configuration>\n                    <archive>\n                        <manifest>\n                            <addDefaultImplementationEntries>true</addDefaultImplementationEntries>\n                        </manifest>\n                        <manifestEntries>\n                            <Implementation-Version>${project.version}</Implementation-Version>\n                            <git-SHA-1>${buildNumber}</git-SHA-1>\n                            <Implementation-Timestamp>${maven.build.timestamp}</Implementation-Timestamp>\n                        </manifestEntries>\n                    </archive>\n                    <webResources>\n                        <resource>\n                            <directory>src/main/webapp/WEB-INF</directory>\n                            <targetPath>WEB-INF</targetPath>\n                            <includes>\n                                <include>web.xml</include>\n                            </includes>\n                            <filtering>true</filtering>\n                        </resource>\n                    </webResources>\n                </configuration>\n            </plugin>\n            <plugin>\n                <artifactId>maven-clean-plugin</artifactId>\n                <version>2.6.1</version>\n                <configuration>\n                    <filesets>\n                        <fileset>\n                            <directory>${project.basedir}/node_modules/</directory>\n                            <followSymlinks>false</followSymlinks>\n                        </fileset>\n                    </filesets>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.codehaus.mojo</groupId>\n                <artifactId>exec-maven-plugin</artifactId>\n                <version>1.2.1</version>\n                <executions>\n                    <execution>\n                        <id>install-npm-dependencies</id>\n                        <phase>generate-sources</phase>\n                        <configuration>\n                            <executable>npm</executable>\n                            <arguments>\n                                <argument>install</argument>\n                            </arguments>\n                        </configuration>\n                        <goals>\n                            <goal>exec</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-remote-resources-plugin</artifactId>\n                <version>1.5</version>\n                <executions>\n                    <execution>\n                        <goals>\n                            <goal>process</goal>\n                        </goals>\n                        <configuration>\n                            <resourceBundles>\n                                <resourceBundle>fr.ippon.tatami:services:${project.version}</resourceBundle>\n                            </resourceBundles>\n                        </configuration>\n                    </execution>\n                </executions>\n            </plugin>\n        </plugins>\n    </build>\n</project>\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/atmosphere/RealtimeService.java",
    "content": "package fr.ippon.tatami.web.atmosphere;\n\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport org.atmosphere.config.service.ManagedService;\nimport org.atmosphere.cpr.AtmosphereResource;\nimport org.atmosphere.cpr.AtmosphereResponse;\nimport org.atmosphere.cpr.Broadcaster;\nimport org.atmosphere.cpr.BroadcasterFactory;\nimport org.atmosphere.handler.OnMessage;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\n\nimport java.io.IOException;\n\n@ManagedService(\n        path = \"/realtime/statuses/home_timeline\")\npublic class RealtimeService extends OnMessage<TatamiNotification> {\n\n    private static final Logger log = LoggerFactory.getLogger(RealtimeService.class);\n\n    private static final ObjectMapper jsonObjectMapper = new ObjectMapper();\n\n    @Override\n    public void onOpen(AtmosphereResource resource) throws IOException {\n        log.debug(\"Opening Atmosphere connection\");\n\n        String broadcasterName = \"/realtime/statuses/home_timeline/\" +\n                resource.getRequest().getRemoteUser();\n\n        log.debug(\"Subscribing this resource to broadcaster: {}\", broadcasterName);\n        Broadcaster b =\n                BroadcasterFactory.getDefault().lookup(broadcasterName, true);\n\n        b.addAtmosphereResource(resource);\n    }\n\n    @Override\n    public void onResume(AtmosphereResponse response) throws IOException {\n        log.debug(\"Resuming Atmosphere connection\");\n    }\n\n    @Override\n    public void onTimeout(AtmosphereResponse response) throws IOException {\n        log.debug(\"Atmosphere connection timeout\");\n    }\n\n    @Override\n    public void onDisconnect(AtmosphereResponse response) throws IOException {\n        log.debug(\"Closing Atmosphere connection\");\n    }\n\n    @Override\n    public void onMessage(AtmosphereResponse response, TatamiNotification notification) throws IOException {\n        log.debug(\"Received Atmosphere message: {}\", notification);\n        String json = jsonObjectMapper.writeValueAsString(notification);\n        response.getWriter().write(json);\n    }\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/controller/ErrorController.java",
    "content": "package fr.ippon.tatami.web.controller;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\nimport javax.servlet.http.HttpServletRequest;\n\n/**\n * @author Julien Dubois\n */\n@Controller\npublic class ErrorController {\n\n    private final Logger log = LoggerFactory.getLogger(ErrorController.class);\n\n    @RequestMapping(value = \"/errors/404\")\n    public String pageNotFound(HttpServletRequest request) {\n        log.debug(\"404 error : {}\", request.getAttribute(\"javax.servlet.forward.request_uri\"));\n        return \"errors/404\";\n    }\n\n    @RequestMapping(value = \"/errors/500\")\n    public String internalServerError(HttpServletRequest request) {\n        log.debug(\"500 error !\");\n        return \"errors/500\";\n    }\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/controller/HomeController.java",
    "content": "package fr.ippon.tatami.web.controller;\n\nimport fr.ippon.tatami.config.Constants;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.UserService;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\nimport org.springframework.security.crypto.password.StandardPasswordEncoder;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.PathVariable;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.RequestParam;\nimport org.springframework.web.servlet.ModelAndView;\n\nimport javax.inject.Inject;\n\n/**\n * @author Julien Dubois\n */\n@Controller\npublic class HomeController {\n\n    private final Logger log = LoggerFactory.getLogger(HomeController.class);\n\n    @Inject\n    private UserService userService;\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    @Inject\n    private Environment env;\n\n    @RequestMapping(value = \"/login\", method = RequestMethod.GET)\n    public ModelAndView login(@RequestParam(required = false) String action) {\n        ModelAndView mv = new ModelAndView(\"login\");\n        mv.addObject(\"action\", action);\n        return mv;\n    }\n\n    @RequestMapping(value = {\"/\", \"/home/**\", \"/home\", \"/home/\"}, method = RequestMethod.GET)\n    public ModelAndView home(@RequestParam(required = false) String ios) {\n        ModelAndView mv = new ModelAndView(\"home\");\n        User currentUser = authenticationService.getCurrentUser();\n        mv.addObject(\"user\", currentUser);\n        if (ios == null) {\n            mv.addObject(\"ios\", false);\n        } else {\n            mv.addObject(\"ios\", true);\n        }\n        return mv;\n    }\n\n    @RequestMapping(value = \"/register\", method = RequestMethod.POST)\n    public String register(@RequestParam String email) {\n        email = email.toLowerCase();\n        if (userService.getUserByLogin(email) != null) {\n            return \"redirect:/tatami/login?action=registerFailure\";\n        }\n        User user = new User();\n        user.setLogin(email);\n        userService.registerUser(user);\n        return \"redirect:/tatami/login?action=register\";\n    }\n\n    @RequestMapping(value = \"/register\", method = RequestMethod.GET)\n    public ModelAndView validateRegistration(@RequestParam String key) {\n        ModelAndView mv = new ModelAndView(\"register\");\n        String login = userService.validateRegistration(key);\n        mv.addObject(\"login\", login);\n        return mv;\n    }\n\n    @RequestMapping(value = \"/register/automatic\", method = RequestMethod.POST)\n    public String automaticRegistration(@RequestParam String email, @RequestParam String password) {\n        String enabled = env.getProperty(\"tatami.automatic.registration\");\n        if (enabled != null && !enabled.equals(\"true\")) {\n            log.warn(\"Automatic registration should not have been called.\");\n            return \"redirect:/tatami/login\";\n        }\n        if (email == null || email.equals(\"\")) {\n            return \"redirect:/tatami/login\";\n        }\n        email = email.toLowerCase();\n        if (userService.getUserByLogin(email) != null) {\n            log.debug(\"User {} already exists.\", email);\n            return \"redirect:/tatami/login\";\n        }\n        if (email.equals(Constants.TATAMIBOT_NAME)) {\n            log.debug(\"E-mail {} can only be used by the Tatami Bot.\", email);\n            return \"redirect:/tatami/login\";\n        }\n        log.debug(\"Creating user {}\", email);\n        User user = new User();\n        user.setLogin(email);\n        StandardPasswordEncoder encoder = new StandardPasswordEncoder();\n        String encryptedPassword = encoder.encode(password);\n        user.setPassword(encryptedPassword);\n        userService.createUser(user);\n        return \"redirect:/tatami/login\";\n    }\n\n    @RequestMapping(value = \"/lostpassword\", method = RequestMethod.POST)\n    public String lostPassword(@RequestParam String email) {\n        email = email.toLowerCase();\n        User user = userService.getUserByLogin(email);\n        if (user == null) {\n            return \"redirect:/tatami/login?action=lostPasswordFailure\";\n        }\n        if (userService.isDomainHandledByLDAP(user.getDomain())) {\n            return \"redirect:/tatami/login?action=ldapPasswordFailure\";\n        }\n        userService.lostPassword(user);\n        return \"redirect:/tatami/login?action=lostPassword\";\n    }\n\n\n    @RequestMapping(value = \"/tos\", method = RequestMethod.GET)\n    public String termsOfService() {\n        return \"terms_of_service\";\n    }\n\n    @RequestMapping(value = \"/presentation\", method = RequestMethod.GET)\n    public String presentation() {\n        return \"presentation\";\n    }\n\n    @RequestMapping(value = \"/license\", method = RequestMethod.GET)\n    public String license() {\n        return \"license\";\n    }\n\n    /**\n     * This maps any GET request to /tatami/customization/[subpath]\n     * to the jsp named /customization/[subpath].jsp.\n     * <p/>\n     * It allows adding easily new pages with tatamiCustomization\n     */\n    @RequestMapping(value = \"/customization/{subPath}\", method = RequestMethod.GET)\n    public String anyOtherSubPath(@PathVariable String subPath) {\n        return \"/customization/\" + subPath;\n    }\n}"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/controller/Pac4JSecurityCheckController.java",
    "content": "package fr.ippon.tatami.web.controller;\n\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@Controller\npublic class Pac4JSecurityCheckController {\t\n    @RequestMapping(value = \"/j_spring_pac4j_security_check\")\n    public String googleCheck() {\n        return \"redirect:/#/home\";\n    }\n\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/fileupload/FileController.java",
    "content": "package fr.ippon.tatami.web.fileupload;\n\nimport com.yammer.metrics.annotation.Timed;\n\nimport fr.ippon.tatami.domain.Attachment;\nimport fr.ippon.tatami.domain.Avatar;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.UserRepository;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.AttachmentService;\nimport fr.ippon.tatami.service.AvatarService;\nimport fr.ippon.tatami.service.UserService;\nimport fr.ippon.tatami.service.exception.StorageSizeException;\n\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.*;\nimport org.springframework.web.multipart.MultipartFile;\nimport org.springframework.web.servlet.ModelAndView;\n\nimport javax.annotation.PostConstruct;\nimport javax.inject.Inject;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\n\nimport java.io.IOException;\nimport java.net.URLEncoder;\nimport java.util.ArrayList;\nimport java.util.Date;\nimport java.util.List;\n\n@Controller\npublic class FileController {\n\n    private static final Logger log = LoggerFactory.getLogger(FileController.class);\n\n\n    private static final String HEADER_EXPIRES = \"Expires\";\n\n    private static final String HEADER_CACHE_CONTROL = \"Cache-Control\";\n\n    private static final int CACHE_SECONDS = 60 * 60 * 24 * 30;\n\n    private static final String HEADER_ETAG = \"ETag\";\n\n    private static final String HEADER_IF_NONE_MATCH = \"If-None-Match\";\n\n    private String tatamiUrl;\n\n    @Inject\n    private Environment env;\n\n    @Inject\n    private AttachmentService attachmentService;\n\n    @Inject\n    private AvatarService avatarService;\n\n    @Inject\n    private UserService userService;\n\n    @Inject\n    private UserRepository userRepository;\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    @PostConstruct\n    public void init() {\n        this.tatamiUrl = env.getProperty(\"tatami.url\");\n    }\n\n    @RequestMapping(value = \"/file/{attachmentId}/*\",\n            method = RequestMethod.GET)\n    @Timed\n    public void download(@PathVariable(\"attachmentId\") String attachmentId,\n                         HttpServletRequest request,\n                         HttpServletResponse response) throws IOException {\n\n        // Cache the file in the browser\n        response.setDateHeader(HEADER_EXPIRES, System.currentTimeMillis() + CACHE_SECONDS * 1000L);\n        response.setHeader(HEADER_CACHE_CONTROL, \"max-age=\" + CACHE_SECONDS + \", must-revalidate\");\n\n        // Put the file in the response\n        Attachment attachment = attachmentService.getAttachmentById(attachmentId);\n        if (attachment == null) {\n            response.setStatus(HttpServletResponse.SC_NOT_FOUND);\n            response.sendRedirect(\"/tatami/file/file_not_found\");\n        } else {\n            // ETag support\n            response.setHeader(HEADER_ETAG, attachmentId); // The attachmentId is unique and should not be modified\n            String requestETag = request.getHeader(HEADER_IF_NONE_MATCH);\n            if (requestETag != null && requestETag.equals(attachmentId)) {\n                response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);\n            } else {\n                try {\n                    byte[] fileContent = attachment.getContent();\n                    response.getOutputStream().write(fileContent);\n                } catch (IOException e) {\n                    log.info(\"Error writing file to output stream. {}\", e.getMessage());\n                }\n            }\n        }\n\n        try {\n            response.flushBuffer();\n        } catch (IOException e) {\n            log.info(\"Error flushing the output stream. {}\", e.getMessage());\n        }\n\n    }\n    \n    @RequestMapping(value = \"/thumbnail/{attachmentId}/*\",\n\t\t\tmethod = RequestMethod.GET)\n    @Timed\n    public void thumbnail(@PathVariable(\"attachmentId\") String attachmentId,\n            \t\t\t  HttpServletRequest request,\n            \t\t\t  HttpServletResponse response) throws IOException {\n    \t// Cache the file in the browser\n        response.setDateHeader(HEADER_EXPIRES, System.currentTimeMillis() + CACHE_SECONDS * 1000L);\n        response.setHeader(HEADER_CACHE_CONTROL, \"max-age=\" + CACHE_SECONDS + \", must-revalidate\");\n\n        // Put the file in the response\n        Attachment attachment = attachmentService.getAttachmentById(attachmentId);\n        if (attachment == null || attachment.getThumbnail().length == 0) {\n            response.setStatus(HttpServletResponse.SC_NOT_FOUND);\n            response.sendRedirect(\"/tatami/file/file_not_found\");\n        } else {\n            // ETag support\n            response.setHeader(HEADER_ETAG, attachmentId); // The attachmentId is unique and should not be modified\n            String requestETag = request.getHeader(HEADER_IF_NONE_MATCH);\n            if (requestETag != null && requestETag.equals(attachmentId)) {\n                response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);\n            } else {\n                try {\n                    byte[] fileContent = attachment.getThumbnail();\n                    response.getOutputStream().write(fileContent);\n                } catch (IOException e) {\n                    log.info(\"Error writing file to output stream. {}\", e.getMessage());\n                }\n            }\n        }\n\n        try {\n            response.flushBuffer();\n        } catch (IOException e) {\n            log.info(\"Error flushing the output stream. {}\", e.getMessage());\n        }\n    }\n\n\n\n    @RequestMapping(value = \"/avatar/{avatarId}/*\",\n            method = RequestMethod.GET)\n    @Timed\n    public void getAvatar(@PathVariable(\"avatarId\") String avatarId,\n                          HttpServletRequest request,\n                          HttpServletResponse response) throws IOException {\n\n        // Cache the file in the browser\n        response.setDateHeader(HEADER_EXPIRES, System.currentTimeMillis() + CACHE_SECONDS * 1000L);\n        response.setHeader(HEADER_CACHE_CONTROL, \"max-age=\" + CACHE_SECONDS + \", must-revalidate\");\n\n        // Put the file in the response\n        Avatar avatar = avatarService.getAvatarById(avatarId);\n        if (avatarId == null) {\n            response.setStatus(HttpServletResponse.SC_NOT_FOUND);\n        } else {\n            // ETag support\n            response.setHeader(HEADER_ETAG, avatarId); // The attachmentId is unique and should not be modified\n            String requestETag = request.getHeader(HEADER_IF_NONE_MATCH);\n            if (requestETag != null && requestETag.equals(avatarId)) {\n                response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);\n            } else {\n                try {\n                    byte[] fileContent = avatar.getContent();\n                    response.getOutputStream().write(fileContent);\n                } catch (IOException e) {\n                    log.info(\"Error writing file to output stream. {}\", e.getMessage());\n                }\n            }\n        }\n        try {\n            response.flushBuffer();\n\n        } catch (IOException e) {\n            log.info(\"Error flushing the output stream. {}\", e.getMessage());\n        }\n    }\n\n    @RequestMapping(value = \"/rest/fileupload/avatar\",\n            method = RequestMethod.POST)\n    @ResponseBody\n    @Timed\n    public List<UploadedFile> uploadAvatar(\n            @RequestParam(\"uploadFile\") MultipartFile file) throws IOException {\n\n        Avatar avatar = new Avatar();\n        avatar.setContent(file.getBytes());\n        avatar.setFilename(file.getOriginalFilename());\n        avatar.setSize(file.getSize());\n        avatar.setCreationDate(new Date());\n\n        avatarService.createAvatar(avatar);\n\n        List<UploadedFile> uploadedFiles = new ArrayList<UploadedFile>();\n        UploadedFile uploadedFile = new UploadedFile(\n                avatar.getAvatarId(),\n                file.getOriginalFilename(),\n                Long.valueOf(file.getSize()).intValue(),\n                tatamiUrl + \"/tatami/avatar/\" + avatar.getAvatarId() + \"/\" + file.getOriginalFilename());\n\n        log.info(\"Avatar url : {}/tatami/avatar/{}/{}\", tatamiUrl, avatar.getAvatarId(), file.getOriginalFilename());\n\n        uploadedFiles.add(uploadedFile);\n\n        User user = authenticationService.getCurrentUser();\n        user.setAvatar(avatar.getAvatarId());\n\n        userRepository.updateUser(user);\n\n        return uploadedFiles;\n\n    }\n\t\n\t    @RequestMapping(value = \"/rest/fileupload/avatarIE\", headers = \"content-type=multipart/*\",\n            method = RequestMethod.POST)\n    @ResponseBody\n    @Timed\n    public void uploadAvatarIE(\n            @RequestParam(\"uploadFile\") MultipartFile file) throws IOException {\n\n        Avatar avatar = new Avatar();\n        avatar.setContent(file.getBytes());\n        avatar.setFilename(file.getOriginalFilename());\n        avatar.setSize(file.getSize());\n        avatar.setCreationDate(new Date());\n\n        avatarService.createAvatar(avatar);\n\n        log.info(\"Avatar url : {}/tatami/avatar/{}/{}\", tatamiUrl, avatar.getAvatarId(), file.getOriginalFilename());\n\n        User user = authenticationService.getCurrentUser();\n        user.setAvatar(avatar.getAvatarId());\n\n        userRepository.updateUser(user);\n\n    }\n\n\n    @RequestMapping(value = \"/rest/fileupload\", method = RequestMethod.POST)\n    @ResponseBody\n    @Timed\n    public List<UploadedFile> upload(@RequestParam(\"uploadFile\") MultipartFile file)\n            throws IOException, StorageSizeException {\n\n        Attachment attachment = new Attachment();\n        attachment.setContent(file.getBytes());\n        attachment.setFilename(file.getName());\n        attachment.setSize(file.getSize());\n        attachment.setFilename(file.getOriginalFilename());\n        attachment.setCreationDate(new Date());\n\n        attachmentService.createAttachment(attachment);\n\n        log.debug(\"Created attachment : {}\", attachment.getAttachmentId());\n\n        List<UploadedFile> uploadedFiles = new ArrayList<UploadedFile>();\n        UploadedFile uploadedFile = new UploadedFile(\n                attachment.getAttachmentId(),\n                file.getOriginalFilename(),\n                Long.valueOf(file.getSize()).intValue(),\n                tatamiUrl + \"/tatami/file/\" + attachment.getAttachmentId() + \"/\" + file.getOriginalFilename());\n\n        uploadedFiles.add(uploadedFile);\n        return uploadedFiles;\n    }\n\t\n\t@RequestMapping(value = \"/rest/fileuploadIE\", headers = \"content-type=multipart/*\",\n    \t\tmethod = RequestMethod.POST, produces = \"text/html\")\n    @ResponseBody\n    @Timed\n    public String uploadIE(@RequestParam(\"uploadFile\") MultipartFile file)\n            throws IOException, StorageSizeException {\n\n        Attachment attachment = new Attachment();\n        attachment.setContent(file.getBytes());\n        attachment.setFilename(file.getName());\n        attachment.setSize(file.getSize());\n        attachment.setFilename(file.getOriginalFilename());\n        attachment.setCreationDate(new Date());\n\n        attachmentService.createAttachment(attachment);\n\n        log.debug(\"Created attachment : {}\", attachment.getAttachmentId());\n        \n        String result = attachment.getAttachmentId()+\":::\"+file.getOriginalFilename()+\":::\"+file.getSize(); \n        \n        return URLEncoder.encode(result, \"UTF-8\");\n\t\t\n    }\n\n    @RequestMapping(value = \"/file/file_not_found\",\n            method = RequestMethod.GET)\n    @Timed\n    public ModelAndView FileNotFound() {\n        log.debug(\"File not found !\");\n        return new ModelAndView(\"errors/file_not_found\");\n    }\n\n\n}"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/fileupload/Message.java",
    "content": "package fr.ippon.tatami.web.fileupload;\n\nimport java.io.Serializable;\n\npublic class Message implements Serializable {\n\n    private String owner;\n    private String description;\n    private String filename;\n\n    public Message() {\n        super();\n    }\n\n    public Message(String owner, String description, String filename) {\n        super();\n        this.owner = owner;\n        this.description = description;\n        this.filename = filename;\n    }\n\n    public String getOwner() {\n        return owner;\n    }\n\n    public void setOwner(String owner) {\n        this.owner = owner;\n    }\n\n    public String getDescription() {\n        return description;\n    }\n\n    public void setDescription(String description) {\n        this.description = description;\n    }\n\n    public String getFilename() {\n        return filename;\n    }\n\n    public void setFilename(String filename) {\n        this.filename = filename;\n    }\n\n    @Override\n    public String toString() {\n        return \"Message{\" +\n                \"owner='\" + owner + '\\'' +\n                \", description='\" + description + '\\'' +\n                \", filename='\" + filename + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/fileupload/StatusResponse.java",
    "content": "package fr.ippon.tatami.web.fileupload;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * A POJO containing the status of an action and a {@link java.util.List} of messages.\n * This is mainly used as a DTO for the presentation layer\n */\npublic class StatusResponse {\n\n    private Boolean success;\n    private final List<String> message;\n\n    public StatusResponse() {\n        this.message = new ArrayList<String>();\n    }\n\n    public StatusResponse(Boolean success) {\n        super();\n        this.success = success;\n        this.message = new ArrayList<String>();\n    }\n\n    public StatusResponse(Boolean success, String message) {\n        super();\n        this.success = success;\n        this.message = new ArrayList<String>();\n        this.message.add(message);\n    }\n\n    public StatusResponse(Boolean success, List<String> message) {\n        super();\n        this.success = success;\n        this.message = message;\n    }\n\n    public Boolean getSuccess() {\n        return success;\n    }\n\n    public void setSuccess(Boolean success) {\n        this.success = success;\n    }\n\n    public List<String> getMessage() {\n        return message;\n    }\n\n    public void setMessage(String message) {\n        this.message.add(message);\n    }\n\n    @Override\n    public String toString() {\n        return \"StatusResponse{\" +\n                \"success=\" + success +\n                \", message=\" + message +\n                '}';\n    }\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/fileupload/UploadedFile.java",
    "content": "package fr.ippon.tatami.web.fileupload;\n\nimport java.io.Serializable;\n\npublic class UploadedFile implements Serializable {\n\n    private String attachmentId;\n    private String name;\n    private Integer size;\n    private String url;\n    private String thumbnail_url;\n    private String delete_url;\n    private String delete_type;\n\n    public UploadedFile() {\n        super();\n    }\n\n    public UploadedFile(String attachmentId, String name, Integer size, String url) {\n        super();\n        this.attachmentId = attachmentId;\n        this.name = name;\n        this.size = size;\n        this.url = url;\n    }\n\n    public UploadedFile(String attachmentId, String name, Integer size, String url,\n                        String thumbnail_url, String delete_url, String delete_type) {\n        super();\n        this.attachmentId = attachmentId;\n        this.name = name;\n        this.size = size;\n        this.url = url;\n        this.thumbnail_url = thumbnail_url;\n        this.delete_url = delete_url;\n        this.delete_type = delete_type;\n    }\n\n    public String getAttachmentId() {\n        return attachmentId;\n    }\n\n    public void setAttachmentId(String attachmentId) {\n        this.attachmentId = attachmentId;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public Integer getSize() {\n        return size;\n    }\n\n    public void setSize(Integer size) {\n        this.size = size;\n    }\n\n    public String getUrl() {\n        return url;\n    }\n\n    public void setUrl(String url) {\n        this.url = url;\n    }\n\n    public String getThumbnail_url() {\n        return thumbnail_url;\n    }\n\n    public void setThumbnail_url(String thumbnail_url) {\n        this.thumbnail_url = thumbnail_url;\n    }\n\n    public String getDelete_url() {\n        return delete_url;\n    }\n\n    public void setDelete_url(String delete_url) {\n        this.delete_url = delete_url;\n    }\n\n    public String getDelete_type() {\n        return delete_type;\n    }\n\n    public void setDelete_type(String delete_type) {\n        this.delete_type = delete_type;\n    }\n\n    @Override\n    public String toString() {\n        return \"UploadedFile{\" +\n                \"attachmentId='\" + attachmentId + '\\'' +\n                \"name='\" + name + '\\'' +\n                \", size=\" + size +\n                \", url='\" + url + '\\'' +\n                \", thumbnail_url='\" + thumbnail_url + '\\'' +\n                \", delete_url='\" + delete_url + '\\'' +\n                \", delete_type='\" + delete_type + '\\'' +\n                '}';\n    }\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/filter/IeRefreshWrapper.java",
    "content": "package fr.ippon.tatami.web.filter;\n\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletRequestWrapper;\n\npublic class IeRefreshWrapper extends HttpServletRequestWrapper {\n \n\tprivate String accept; \n\t\n    public IeRefreshWrapper(HttpServletRequest request) {\n        super(request);\n        if (request.getHeader(\"accept\").equals(\"*/*\")) {\n        \taccept =  \"application/x-ms-application, image/jpeg, application/xaml+xml, image/gif, image/pjpeg, application/x-ms-xbap, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*\";\n        } else {\n        \taccept = request.getHeader(\"accept\");\n        }\n    }\n    \n    public String getHeader(String name) {\n        return (name != \"Accept\" && name != \"accept\") ? super.getHeader(name) : accept;\n    }\n \n}"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/filter/TatamiGzipFilter.java",
    "content": "package fr.ippon.tatami.web.filter;\n\nimport net.sf.ehcache.constructs.web.filter.GzipFilter;\n\nimport javax.servlet.FilterChain;\nimport javax.servlet.http.HttpServletRequest;\nimport javax.servlet.http.HttpServletResponse;\n\n/**\n * Provides GZIP compression of responses, based on ehcache's GzipFilter.\n */\npublic class TatamiGzipFilter extends GzipFilter {\n\n    @Override\n    protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws Exception {\n\n        if(\"*/*\".equals(request.getHeader(\"accept\"))) {\n            IeRefreshWrapper requestIE = new IeRefreshWrapper(request);\n            chain.doFilter(requestIE, response);\n        } else {\n            //otherwise, continue on in the chain with the ServletRequest and ServletResponse objects\n        \tchain.doFilter(request, response);\n        }\n    }\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/init/WebConfigurer.java",
    "content": "package fr.ippon.tatami.web.init;\n\nimport com.yammer.metrics.reporting.AdminServlet;\nimport com.yammer.metrics.web.DefaultWebappMetricsFilter;\nimport fr.ippon.tatami.config.ApplicationConfiguration;\nimport fr.ippon.tatami.config.Constants;\nimport fr.ippon.tatami.config.DispatcherServletConfig;\nimport org.atmosphere.cache.UUIDBroadcasterCache;\nimport org.atmosphere.cpr.AtmosphereServlet;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\nimport org.springframework.web.context.WebApplicationContext;\nimport org.springframework.web.context.support.AnnotationConfigWebApplicationContext;\nimport org.springframework.web.context.support.WebApplicationContextUtils;\nimport org.springframework.web.filter.DelegatingFilterProxy;\nimport org.springframework.web.servlet.DispatcherServlet;\n\nimport javax.servlet.*;\nimport java.util.EnumSet;\n\n/**\n * Configuration of web application with Servlet 3.0 APIs.<br>\n * <p/>\n * This class is to be used as a standard listener within a web.xml.\n * To optimise startup time, you can completely disable classpath scanning :\n * <ul>\n * <li>with metadata-complete=\"true\" global attribute\n * <li>with an empty &lt;absolute-ordering&gt; ( it's necessary with Jetty at least <b>TODO</b> : test with other\n * containers )\n * </ul>\n * <p/>\n * See web.xml :\n * <p/>\n * <pre>\n *   &lt;web-app xmlns=\"http://java.sun.com/xml/ns/javaee\"\n *          xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n *          xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\"\n *          version=\"3.0\"\n *          metadata-complete=\"true\">\n *\n * \t&lt;!--\n * \tRemove classpath scanning (from servlet 3.0) in order to speed jetty startup :\n * \tmetadata-complete=\"true\" above + empty absolute ordering below\n * \t-->\n * \t&lt;absolute-ordering>\n * \t\t&lt;!--\n * \t\t Empty absolute ordering is necessary to completely desactivate classpath scanning\n * \t\t  -->\n * \t&lt;/absolute-ordering>\n *\n *     &lt;display-name>Tatami&lt;/display-name>\n *\n *     &lt;!-- All the Servlets and Filters are configured by this ServletContextListener : -->\n *     &lt;listener>\n *         &lt;listener-class>fr.ippon.tatami.web.init.WebConfigurer&lt;/listener-class>\n *     &lt;/listener>\n *\n * &lt;/web-app>\n * </pre>\n *\n * @author Fabien Arrault\n */\npublic class WebConfigurer implements ServletContextListener {\n\n    private final Logger log = LoggerFactory.getLogger(WebConfigurer.class);\n\n    @Override\n    public void contextInitialized(ServletContextEvent sce) {\n        ServletContext servletContext = sce.getServletContext();\n        log.info(\"Web application configuration\");\n\n        log.debug(\"Configuring Spring root application context\");\n        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();\n        rootContext.register(ApplicationConfiguration.class);\n        rootContext.refresh();\n\n        servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, rootContext);\n\n        EnumSet<DispatcherType> disps = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD, DispatcherType.ASYNC);\n\n        log.debug(\"Configuring Spring Web application context\");\n        AnnotationConfigWebApplicationContext dispatcherServletConfig = new AnnotationConfigWebApplicationContext();\n        dispatcherServletConfig.setParent(rootContext);\n        dispatcherServletConfig.register(DispatcherServletConfig.class);\n\n        log.debug(\"Registering Spring MVC Servlet\");\n        ServletRegistration.Dynamic dispatcherServlet = servletContext.addServlet(\"dispatcher\", new DispatcherServlet(\n                dispatcherServletConfig));\n        dispatcherServlet.addMapping(\"/tatami/*\");\n        dispatcherServlet.setLoadOnStartup(1);\n\n        log.debug(\"Registering Spring Security Filter\");\n        FilterRegistration.Dynamic springSecurityFilter = servletContext.addFilter(\"springSecurityFilterChain\",\n                new DelegatingFilterProxy());\n\n        springSecurityFilter.setAsyncSupported(true);\n\n        initAtmosphereServlet(servletContext);\n\n        Environment env = rootContext.getBean(Environment.class);\n        if (env.acceptsProfiles(Constants.SPRING_PROFILE_METRICS)) {\n            initMetricsServlet(servletContext, disps, dispatcherServlet);\n            springSecurityFilter.addMappingForServletNames(disps, true, \"dispatcher\", \"atmosphereServlet\", \"metricsAdminServlet\");\n        } else {\n            springSecurityFilter.addMappingForServletNames(disps, true, \"dispatcher\", \"atmosphereServlet\");\n        }\n\n        log.debug(\"Web application fully configured\");\n    }\n\n    private void initMetricsServlet(ServletContext servletContext, EnumSet<DispatcherType> disps, ServletRegistration.Dynamic dispatcherServlet) {\n        log.debug(\"Setting Metrics profile for the Web ApplicationContext\");\n\n        log.debug(\"Registering Metrics Filter\");\n        FilterRegistration.Dynamic metricsFilter = servletContext.addFilter(\"webappMetricsFilter\",\n                new DefaultWebappMetricsFilter());\n        metricsFilter.addMappingForUrlPatterns(disps, true, \"/*\");\n\n        log.debug(\"Registering Metrics Admin Servlet\");\n        ServletRegistration.Dynamic metricsAdminServlet =\n                servletContext.addServlet(\"metricsAdminServlet\", new AdminServlet());\n        metricsAdminServlet.addMapping(\"/metrics/*\");\n        dispatcherServlet.setLoadOnStartup(2);\n    }\n\n    private void initAtmosphereServlet(ServletContext servletContext) {\n        log.debug(\"Registering Atmosphere Servlet\");\n        ServletRegistration.Dynamic atmosphereServlet =\n                servletContext.addServlet(\"atmosphereServlet\", new AtmosphereServlet());\n\n        atmosphereServlet.setAsyncSupported(true);\n        atmosphereServlet.setInitParameter(\"org.atmosphere.cpr.packages\", \"fr.ippon.tatami.web.atmosphere\");\n        atmosphereServlet.setInitParameter(\"org.atmosphere.cpr.broadcasterCacheClass\", UUIDBroadcasterCache.class.getName());\n        atmosphereServlet.setInitParameter(\"org.atmosphere.cpr.broadcaster.shareableThreadPool\", \"true\");\n        atmosphereServlet.setInitParameter(\"org.atmosphere.cpr.broadcaster.maxProcessingThreads\", \"10\");\n        atmosphereServlet.setInitParameter(\"org.atmosphere.cpr.broadcaster.maxAsyncWriteThreads\", \"10\");\n\n        atmosphereServlet.setLoadOnStartup(3);\n        atmosphereServlet.addMapping(\"/realtime/*\");\n    }\n\n    @Override\n    public void contextDestroyed(ServletContextEvent sce) {\n        log.info(\"Destroying Web application\");\n        WebApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(sce.getServletContext());\n        AnnotationConfigWebApplicationContext gwac = (AnnotationConfigWebApplicationContext) ac;\n        gwac.close();\n        log.debug(\"Web application destroyed\");\n    }\n\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/rest/AccountController.java",
    "content": "package fr.ippon.tatami.web.rest;\n\nimport com.yammer.metrics.annotation.Timed;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.UserService;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport fr.ippon.tatami.web.rest.dto.Preferences;\nimport fr.ippon.tatami.web.rest.dto.UserPassword;\nimport org.apache.commons.lang.StringEscapeUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\nimport org.springframework.security.authentication.UsernamePasswordAuthenticationToken;\nimport org.springframework.security.core.Authentication;\nimport org.springframework.security.core.context.SecurityContextHolder;\nimport org.springframework.security.crypto.password.StandardPasswordEncoder;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.RequestBody;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.ResponseBody;\n\nimport javax.inject.Inject;\nimport javax.servlet.http.HttpServletResponse;\nimport javax.validation.ConstraintViolationException;\n\n/*\n * REST controller for managing users.\n * @author Arthur Weber\n */\n@Controller\npublic class AccountController {\n\n    private static final Logger log = LoggerFactory.getLogger(AccountController.class);\n\n    @Inject\n    private UserService userService;\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    @Inject\n    Environment env;\n    /*\n     * GET /account/admin -> Determines if the current account is an admin\n     */\n    @RequestMapping(value = \"/rest/account/admin\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public String isAdmin() {\n        log.debug(\"REST request to determine if user is an admin\");\n        org.springframework.security.core.userdetails.User securityUser =\n                (org.springframework.security.core.userdetails.User)\n                        SecurityContextHolder.getContext().getAuthentication().getPrincipal();\n\n        return \"{ \\\"roles\\\": \\\"\" + securityUser.getAuthorities().toString() + \"\\\" }\";\n   }\n\n    /**\n     * GET  /account/profile -> get account's profile\n     */\n    @RequestMapping(value = \"/rest/account/profile\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public User getProfile() {\n        log.debug(\"REST request to get account's profile\");\n        User currentUser = authenticationService.getCurrentUser();\n        return userService.getUserByLogin(currentUser.getLogin());\n    }\n\n    /**\n     * PUT  /account/profile -> get account's profile\n     */\n    @RequestMapping(value = \"/rest/account/profile\",\n            method = RequestMethod.PUT)\n    @ResponseBody\n    @Timed\n    public User updateUserProfile(@RequestBody User updatedUser, HttpServletResponse response) {\n        User currentUser = authenticationService.getCurrentUser();\n        currentUser.setFirstName(updatedUser.getFirstName().replace(\"<\", \" \"));\n        currentUser.setLastName(updatedUser.getLastName().replace(\"<\", \" \"));\n        currentUser.setJobTitle(StringEscapeUtils.escapeHtml(updatedUser.getJobTitle().replace(\"<\", \" \")));\n        currentUser.setPhoneNumber(updatedUser.getPhoneNumber().replace(\"<\", \" \"));\n        try {\n            userService.updateUser(currentUser);\n        } catch (ConstraintViolationException cve) {\n            response.setStatus(HttpServletResponse.SC_FORBIDDEN);\n            return null;\n        }\n        log.debug(\"User updated : {}\", currentUser);\n        return currentUser;\n    }\n\n    @RequestMapping(value = \"/rest/account/profile\",\n            method = RequestMethod.DELETE)\n    @Timed\n    public void suppressUserProfile() {\n        User currentUser = authenticationService.getCurrentUser();\n        log.debug(\"Suppression du compte utilisateur : {}\", currentUser);\n        userService.deleteUser(currentUser);\n    }\n\n\n    /**\n     * GET  /account/preferences -> get account's preferences\n     */\n    @RequestMapping(value = \"/rest/account/preferences\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Preferences getPreferences() {\n        log.debug(\"REST request to get account's preferences\");\n        User currentUser = authenticationService.getCurrentUser();\n        User user = userService.getUserByLogin(currentUser.getLogin());\n\n       return new Preferences(user);\n    }\n\n    /**\n     * POST  /account/preferences -> update account's preferences\n     */\n    @RequestMapping(value = \"/rest/account/preferences\",\n            method = RequestMethod.POST,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Preferences updatePreferences(@RequestBody Preferences newPreferences, HttpServletResponse response) {\n        log.debug(\"REST request to set account's preferences\");\n        Preferences preferences = null;\n        try {\n            User currentUser = authenticationService.getCurrentUser();\n            currentUser.setPreferencesMentionEmail(newPreferences.getMentionEmail());\n            currentUser.setDailyDigestSubscription(newPreferences.getDailyDigest());\n            currentUser.setWeeklyDigestSubscription(newPreferences.getWeeklyDigest());\n\n            String rssUid = userService.updateRssTimelinePreferences(newPreferences.getRssUidActive());\n            currentUser.setRssUid(rssUid);\n\n            preferences = new Preferences(currentUser);\n\n            userService.updateUser(currentUser);\n            userService.updateDailyDigestRegistration(newPreferences.getDailyDigest());\n            userService.updateWeeklyDigestRegistration(newPreferences.getWeeklyDigest());\n\n            org.springframework.security.core.userdetails.User securityUser =\n                    (org.springframework.security.core.userdetails.User)\n                            SecurityContextHolder.getContext().getAuthentication().getPrincipal();\n            log.debug(\"User roles : {}\", securityUser);\n\n            Authentication authentication =\n                    new UsernamePasswordAuthenticationToken(securityUser,\n                            securityUser.getPassword(),\n                            securityUser.getAuthorities());\n\n            SecurityContextHolder.getContext().setAuthentication(authentication);\n\n            log.debug(\"User updated : {}\", currentUser);\n        } catch (Exception e) {\n            log.debug(\"Error during setting preferences\", e);\n            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);\n        }\n            return preferences;\n\n    }\n\n\n    /**\n     * GET  /account/password -> throws an error if the password is managed by LDAP\n     */\n    @RequestMapping(value = \"/rest/account/password\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public UserPassword isPasswordManagedByLDAP(HttpServletResponse response) {\n        User currentUser = authenticationService.getCurrentUser();\n        String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());\n        if (userService.isDomainHandledByLDAP(domain)) {\n            response.setStatus(HttpServletResponse.SC_FORBIDDEN);\n            return null;\n        } else {\n            return new UserPassword();\n        }\n    }\n\n    /**\n     * GET  /account/preferences -> get account's preferences\n     */\n    @RequestMapping(value = \"/rest/account/password\",\n            method = RequestMethod.POST,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public UserPassword setPassword(@RequestBody UserPassword userPassword, HttpServletResponse response) {\n       log.debug(\"REST request to set account's password\");\n        try {\n            User currentUser = authenticationService.getCurrentUser();\n            StandardPasswordEncoder encoder = new StandardPasswordEncoder();\n\n            if (!encoder.matches(userPassword.getOldPassword(), currentUser.getPassword())) {\n                log.debug(\"The old password is incorrect : {}\", userPassword.getOldPassword());\n                throw new Exception(\"oldPassword\");\n            }\n\n            if (!userPassword.getNewPassword().equals(userPassword.getNewPasswordConfirmation())) {\n                throw new Exception(\"newPasswordConfirmation\");\n            }\n\n            currentUser.setPassword(userPassword.getNewPassword());\n\n            userService.updatePassword(currentUser);\n\n            log.debug(\"User password updated : {}\", currentUser);\n            return new UserPassword();\n        } catch (Exception e) {\n            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);\n            return null;\n        }\n    }\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/rest/AttachmentController.java",
    "content": "package fr.ippon.tatami.web.rest;\n\nimport com.yammer.metrics.annotation.Timed;\nimport fr.ippon.tatami.domain.Attachment;\nimport fr.ippon.tatami.service.AttachmentService;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.*;\n\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Collection;\n\n@Controller\npublic class AttachmentController {\n\n    @Inject\n    private AttachmentService attachmentService;\n\n    /**\n     * GET  /attachments -> get the attachments list\n     */\n    @RequestMapping(value = \"/rest/attachments\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<Attachment> getAttachments(\n            @RequestParam(required = false) Integer pagination,\n            @RequestParam(required = false) String finish) {\n\n        if (pagination == null) {\n            pagination = 10;\n        }\n\n        Collection<String> attachmentIds =\n                attachmentService.getAttachmentIdsForCurrentUser(pagination, finish);\n\n        Collection<Attachment> attachments =\n                new ArrayList<Attachment>();\n\n        for (String attachmentId : attachmentIds) {\n            attachments.add(attachmentService.getAttachmentById(attachmentId));\n        }\n\n        return attachments;\n    }\n\n    /**\n     * GET  /attachment/{attachmentId} -> get a specific attachment\n     */\n    @RequestMapping(value = \"/rest/attachments/{attachmentId}\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Attachment getAttachmentById(@PathVariable(\"attachmentId\") String attachmentId) {\n        return attachmentService.getAttachmentById(attachmentId);\n    }\n\n    /**\n     * DELETE /attachment/{attachmentId} -> delete a specific attachment\n     */\n    @RequestMapping(value = \"/rest/attachments/{attachmentId}\",\n            method = RequestMethod.DELETE,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Attachment DeleteAttachment(@PathVariable(\"attachmentId\") String attachmentId) {\n        Attachment attachment = attachmentService.getAttachmentById(attachmentId);\n        attachmentService.deleteAttachment(attachment);\n        return attachment;\n    }\n\n    /**\n     * GET /attachment/quota -> get quota in % for the domain\n     */\n    @RequestMapping(value = \"/rest/attachments/quota\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    public Collection<Long> getDomainQuota() {\n        return attachmentService.getDomainQuota();\n    }\n\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/rest/BlockController.java",
    "content": "package fr.ippon.tatami.web.rest;\n\n/**\n * Created by matthieudelafourniere on 7/7/16.\n */\n\n\nimport com.yammer.metrics.annotation.Timed;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.UserRepository;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.BlockService;\nimport fr.ippon.tatami.service.UserService;\nimport fr.ippon.tatami.service.dto.UserDTO;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.security.core.userdetails.UserDetailsService;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.PathVariable;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.ResponseBody;\n\nimport javax.inject.Inject;\nimport javax.servlet.http.HttpServletResponse;\nimport java.util.Collection;\n\n/**\n * REST controller for blocking/unblocking users.\n */\n@Controller\npublic class BlockController {\n    private final Logger log = LoggerFactory.getLogger(BlockController.class);\n\n    @Inject\n    private BlockService blockService;\n\n    @Inject\n    UserService userService;\n\n    @Inject\n    UserRepository userRepository;\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n\n    @RequestMapping(value = \"/rest/block/blockedusers/{username}\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @Timed\n    @ResponseBody\n    public Collection<UserDTO> getBlockedUsersForUser(@PathVariable String username, HttpServletResponse response) {\n\n        User currentUser = authenticationService.getCurrentUser();\n        if (currentUser == null) {\n            response.setStatus(HttpServletResponse.SC_NOT_FOUND);\n            return null;\n        }\n        String login = username + \"@\" + currentUser.getDomain();\n\n        Collection<User> blockedUsers = blockService.getUsersBlockedForUser(login);\n\n        return userService.buildUserDTOList(blockedUsers);\n    }\n\n\n    /**\n     * Method used by current user. Switch the blocked/unblocked status of the clicked user.\n     * @param username (of the clicked user)\n     * @return\n     */\n    @RequestMapping(value = \"/rest/block/update/{username}\",\n            method = RequestMethod.PATCH)\n    @Timed\n    @ResponseBody\n    public UserDTO updateBlockedUser(@PathVariable(\"username\") String username) {\n        User currentUser = authenticationService.getCurrentUser();\n        String login = username + \"@\" + currentUser.getDomain();\n        UserDTO toReturn = userService.buildUserDTO(userRepository.findUserByLogin(login));\n        if(  blockService.isBlocked(currentUser.getLogin(),toReturn.getLogin())  ) {\n            blockService.unblockUser(currentUser.getLogin(), toReturn.getLogin());\n        }\n        else {\n            blockService.blockUser(currentUser.getLogin(), toReturn.getLogin());\n        }\n        return toReturn;\n    }\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/rest/CompanyWallController.java",
    "content": "package fr.ippon.tatami.web.rest;\n\nimport com.yammer.metrics.annotation.Timed;\nimport fr.ippon.tatami.service.TimelineService;\nimport fr.ippon.tatami.service.dto.StatusDTO;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.RequestParam;\nimport org.springframework.web.bind.annotation.ResponseBody;\n\nimport javax.inject.Inject;\nimport java.util.Collection;\n\n/**\n * REST controller for getting the company wall.\n *\n * @author Julien Dubois\n */\n@Controller\npublic class CompanyWallController {\n\n    private final Logger log = LoggerFactory.getLogger(CompanyWallController.class);\n\n    @Inject\n    private TimelineService timelineService;\n\n    /**\n     * GET  /company -> get the public statuses of the current company\n     */\n    @RequestMapping(value = \"/rest/company\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<StatusDTO> getCompanyWall(@RequestParam(required = false) Integer count,\n                                                @RequestParam(required = false) String start,\n                                                @RequestParam(required = false) String finish) {\n\n        if (count == null) {\n            count = 20;\n        }\n        try {\n            return timelineService.getDomainline(count, start, finish);\n        } catch (NumberFormatException e) {\n            log.warn(\"Page size undefined ; sizing to default\", e);\n            return timelineService.getDomainline(20, start, finish);\n        }\n    }\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/rest/FavoritesController.java",
    "content": "package fr.ippon.tatami.web.rest;\n\nimport com.yammer.metrics.annotation.Timed;\nimport fr.ippon.tatami.service.TimelineService;\nimport fr.ippon.tatami.service.dto.StatusDTO;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.PathVariable;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.ResponseBody;\n\nimport javax.inject.Inject;\nimport java.util.Collection;\n\n/**\n * REST controller for managing favorites.\n *\n * @author Julien Dubois\n */\n@Controller\npublic class FavoritesController {\n\n    private final Logger log = LoggerFactory.getLogger(FavoritesController.class);\n\n    @Inject\n    private TimelineService timelineService;\n\n    /**\n     * GET  /favorites -> get the favorite status of the current user\n     */\n    @RequestMapping(value = \"/rest/favorites\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<StatusDTO> listFavoriteStatus() {\n        log.debug(\"REST request to get the favorite status of the current user.\");\n        return timelineService.getFavoritesline();\n    }\n\n    /**\n     * POST /favorites/create/:id -> Favorites the status\n     */\n    @RequestMapping(value = \"/rest/favorites/create/{statusId}\",\n            method = RequestMethod.POST)\n    @ResponseBody\n    public void favoriteStatus(@PathVariable(\"statusId\") String statusId) {\n        log.debug(\"REST request to like status : {}\", statusId);\n        timelineService.addFavoriteStatus(statusId);\n    }\n\n    /**\n     * POST /favorites/destroy/:id -> Unfavorites the status\n     */\n    @RequestMapping(value = \"/rest/favorites/destroy/{statusId}\",\n            method = RequestMethod.POST)\n    @ResponseBody\n    public void unfavoriteStatus(@PathVariable(\"statusId\") String statusId) {\n        log.debug(\"REST request to unlike status : {}\", statusId);\n        timelineService.removeFavoriteStatus(statusId);\n    }\n\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/rest/FriendshipController.java",
    "content": "package fr.ippon.tatami.web.rest;\n\nimport com.yammer.metrics.annotation.Timed;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.service.FriendshipService;\nimport fr.ippon.tatami.service.MailService;\nimport fr.ippon.tatami.service.UserService;\nimport fr.ippon.tatami.service.dto.UserDTO;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.*;\n\nimport javax.inject.Inject;\nimport javax.servlet.http.HttpServletResponse;\nimport java.util.Collection;\n\n/**\n * REST controller for managing friendships.\n *\n * @author Julien Dubois\n */\n@Controller\npublic class FriendshipController {\n\n    private final Logger log = LoggerFactory.getLogger(UserController.class);\n\n    @Inject\n    private FriendshipService friendshipService;\n\n    @Inject\n    private UserService userService;\n\n    @Inject\n    private MailService mailService;\n\n    @RequestMapping(value = \"/rest/users/{username}/friends\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @Timed\n    @ResponseBody\n    public Collection<UserDTO> getFriends(@PathVariable String username, HttpServletResponse response) {\n        User user = userService.getUserByUsername(username);\n        if (user == null) {\n            response.setStatus(HttpServletResponse.SC_NOT_FOUND);\n            return null;\n        }\n        Collection<User> friends = friendshipService.getFriendsForUser(username);\n\n        return userService.buildUserDTOList(friends);\n    }\n\n    @RequestMapping(value = \"/rest/users/{username}/followers\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @Timed\n    @ResponseBody\n    public Collection<UserDTO> getFollowers(@PathVariable String username, HttpServletResponse response) {\n        User user = userService.getUserByUsername(username);\n        if (user == null) {\n            response.setStatus(HttpServletResponse.SC_NOT_FOUND);\n            return null;\n        }\n        Collection<User> friends = friendshipService.getFollowersForUser(username);\n\n        return userService.buildUserDTOList(friends);\n    }\n\n    /**\n     * Added an \"action\" parameter to specify which type of PATCH we should do (Activate / Follow ).\n     */\n    @RequestMapping(value = \"/rest/users/{username}\",\n            method = RequestMethod.PATCH)\n    @Timed\n    @ResponseBody\n    public UserDTO updateFriend(@RequestBody fr.ippon.tatami.web.rest.dto.UserActionStatus action, @PathVariable(\"username\") String username) {\n        if ( action.getFriendShip() != null && action.getFriendShip() ) {\n            if ( action.getFriend() ) {\n                friendshipService.followUser(username);\n            } else {\n                friendshipService.unfollowUser(username);\n            }\n        }\n        else if ( action.getActivate() != null &&  action.getActivate()) {\n            this.log.debug(\"REST request to desactivate Profile : {}\", username);\n            userService.desactivateUser(username);\n//            User user = userService.getUserByUsername(username);\n//            mailService.sendDeactivatedEmail(user.getLogin());\n        }\n        return userService.buildUserDTO(userService.getUserByUsername(username));\n    }\n\n    /**\n     * WARNING! This is the old API, only used by the admin console\n     * <p/>\n     * POST /friendships/create -> follow user\n     */\n    @RequestMapping(value = \"/rest/friendships/create\",\n            method = RequestMethod.POST,\n            consumes = \"application/json\")\n    @ResponseBody\n    @Timed\n    @Deprecated\n    public boolean followUser(@RequestBody User user, HttpServletResponse response) {\n        log.debug(\"REST request to follow username : {}\", user.getUsername());\n        boolean success = friendshipService.followUser(user.getUsername());\n        if (!success) {\n            response.setStatus(HttpServletResponse.SC_NOT_FOUND);\n        }\n        return success;\n    }\n\n\n    /**\n     * WARNING! This is the old API, only used by the admin console\n     * <p/>\n     * POST /friendships/destroy -> unfollow user\n     */\n    @RequestMapping(value = \"/rest/friendships/destroy\",\n            method = RequestMethod.POST,\n            consumes = \"application/json\")\n    @ResponseBody\n    @Timed\n    @Deprecated\n    public boolean unfollowUser(@RequestBody User user, HttpServletResponse response) {\n        log.debug(\"REST request to unfollow username  : {}\", user.getUsername());\n        boolean success = friendshipService.unfollowUser(user.getUsername());\n        if (!success) {\n            response.setStatus(HttpServletResponse.SC_NOT_FOUND);\n        }\n        return success;\n    }\n\n    /**\n     * WARNING! This is the old API, only used by the admin console\n     * <p/>\n     * GET /friendships -> is the user a friend ?\n     */\n    @RequestMapping(value = \"/rest/friendships\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    @Deprecated\n    public Boolean followUser(@RequestParam(\"screen_name\") String username) {\n        if (log.isDebugEnabled()) {\n            log.debug(\"REST request to get friendship status : \" + username);\n        }\n        return friendshipService.isFollowing(username);\n    }\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/rest/GroupController.java",
    "content": "package fr.ippon.tatami.web.rest;\n\nimport com.yammer.metrics.annotation.Timed;\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.GroupService;\nimport fr.ippon.tatami.service.SuggestionService;\nimport fr.ippon.tatami.service.TimelineService;\nimport fr.ippon.tatami.service.UserService;\nimport fr.ippon.tatami.service.dto.StatusDTO;\nimport fr.ippon.tatami.service.dto.UserGroupDTO;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.*;\n\nimport javax.inject.Inject;\nimport javax.servlet.http.HttpServletResponse;\nimport java.util.ArrayList;\nimport java.util.Collection;\n\n/**\n * REST controller for managing groups.\n *\n * @author Julien Dubois\n */\n@Controller\npublic class GroupController {\n\n    private final Logger log = LoggerFactory.getLogger(GroupController.class);\n\n    @Inject\n    private TimelineService timelineService;\n\n    @Inject\n    private GroupService groupService;\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    @Inject\n    private UserService userService;\n\n    @Inject\n    private SuggestionService suggestionService;\n\n\n\n    /**\n     * Get groups of the current user.\n     */\n    @RequestMapping(value = \"/rest/groups\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<Group> getGroups() {\n        User currentUser = authenticationService.getCurrentUser();\n        return groupService.getGroupsForUser(currentUser);\n    }\n\n\n    /**\n     * GET  /group/:groupId -> returns the group with the requested id\n     */\n    @RequestMapping(value = \"/rest/groups/{groupId}\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Group getGroup(@PathVariable(\"groupId\") String groupId) {\n        User currentUser = authenticationService.getCurrentUser();\n        String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());\n        Group publicGroup = groupService.getGroupById(domain, groupId);\n        if (publicGroup != null && publicGroup.isPublicGroup()) {\n            Group result = getGroupFromUser(currentUser, groupId);\n            Group groupClone = (Group) publicGroup.clone();\n            if (result != null) {\n                groupClone.setMember(true);\n            }\n            if (isGroupManagedByCurrentUser(publicGroup)) {\n                groupClone.setAdministrator(true);\n            }\n            return groupClone;\n        } else {\n            Group result = getGroupFromUser(currentUser, groupId);\n            Group groupClone = null;\n            if (result == null) {\n                log.info(\"Permission denied! User {} tried to access group ID = {} \", currentUser.getLogin(), groupId);\n                return null;\n            } else {\n                groupClone = (Group) result.clone();\n                groupClone.setMember(true);\n                if (isGroupManagedByCurrentUser(publicGroup)) {\n                    groupClone.setAdministrator(true);\n                }\n            }\n            return groupClone;\n        }\n    }\n\n\n\n\n    /**\n     * PUT  /group/:groupId -> update the group with the requested id\n     */\n    @RequestMapping(value = \"/rest/groups/{groupId}\",\n            method = RequestMethod.PUT,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Group updateGroup(@PathVariable(\"groupId\") String groupId, @RequestBody Group groupEdit, HttpServletResponse response) {\n        Group group = getGroup(groupId);\n\n        if (group != null) {\n            if (!isGroupManagedByCurrentUser(group)) {\n                response.setStatus(HttpServletResponse.SC_FORBIDDEN);\n                return null;\n            } else {\n                group.setDomain(authenticationService.getCurrentUser().getDomain());\n                group.setName(groupEdit.getName());\n                group.setDescription(groupEdit.getDescription());\n                group.setArchivedGroup(groupEdit.isArchivedGroup());\n                groupService.editGroup(group);\n                return group;\n            }\n        } else {\n            response.setStatus(HttpServletResponse.SC_NOT_FOUND);\n            return null;\n        }\n    }\n\n\n\n\n\n\n    @RequestMapping(value = \"/rest/groups/{groupId}/timeline\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<StatusDTO> listStatusForGroup(@PathVariable(value = \"groupId\") String groupId,\n                                                    @RequestParam(required = false) Integer count,\n                                                    @RequestParam(required = false) String start,\n                                                    @RequestParam(required = false) String finish) {\n\n        log.debug(\"REST request to get statuses for group : {}\", groupId);\n        if (groupId == null) {\n            return new ArrayList<StatusDTO>();\n        }\n        if (count == null) {\n            count = 20;\n        }\n        Group group = this.getGroup(groupId);\n        if (group == null) {\n            return new ArrayList<StatusDTO>();\n        } else {\n            return timelineService.getGroupline(groupId, count, start, finish);\n        }\n    }\n\n    /**\n     * GET  /groupmemberships/lookup -> return extended data about the user's groups\n     */\n    @RequestMapping(value = \"/rest/groupmemberships/lookup\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<Group> getUserGroups(@RequestParam(\"screen_name\") String username) {\n        User user = userService.getUserByUsername(username);\n        if (user == null) {\n            log.debug(\"Trying to find group for non-existing username = {}\", username);\n            return new ArrayList<Group>();\n        }\n        return groupService.getGroupsForUser(user);\n    }\n\n\n\n    /**\n     * Get groups where the current user is admin.\n     */\n    @RequestMapping(value = \"/rest/admin/groups\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<Group> getAdminGroups() {\n        return groupService.getGroupsWhereCurrentUserIsAdmin();\n    }\n\n    /**\n     * POST create new group.\n     */\n    @RequestMapping(value = \"/rest/groups\",\n            method = RequestMethod.POST,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Group createGroup(HttpServletResponse response, @RequestBody Group group) {\n        if (group.getName() != null && !group.getName().equals(\"\")) {\n            groupService.createGroup(group.getName(), group.getDescription(), group.isPublicGroup());\n        } else {\n            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);\n        }\n        return group;\n    }\n\n    /**\n     * GET  /groupmemberships/suggestions -> suggest groups to join\n     */\n    @RequestMapping(value = \"/rest/groupmemberships/suggestions\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<Group> suggestions() {\n        String login = authenticationService.getCurrentUser().getLogin();\n        return groupService.buildGroupList(suggestionService.suggestGroups(login));\n    }\n\n\n    /**\n     * GET  /groups/{groupId}/members/ -> members of the group\n     */\n    @RequestMapping(value = \"/rest/groups/{groupId}/members/\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<UserGroupDTO> getGroupsUsers(HttpServletResponse response, @PathVariable(\"groupId\") String groupId) {\n\n        User currentUser = authenticationService.getCurrentUser();\n        Group currentGroup = groupService.getGroupById(currentUser.getDomain(), groupId);\n\n        Collection<UserGroupDTO> users = null;\n\n        if (currentUser == null) {\n            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // Authentication required\n        } else if (currentGroup == null) {\n            response.setStatus(HttpServletResponse.SC_NOT_FOUND); // Resource not found\n        } else {\n            users = groupService.getMembersForGroup(groupId, currentUser.getLogin());\n        }\n        return users;\n    }\n\n    /**\n     * GET  /groups/{groupId}/members/{userUsername} -> get a member to group status\n     */\n    @RequestMapping(value = \"/rest/groups/{groupId}/members/{username}\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public UserGroupDTO getUserToGroup(HttpServletResponse response, @PathVariable(\"groupId\") String groupId, @PathVariable(\"username\") String username) {\n\n        User currentUser = authenticationService.getCurrentUser();\n        Group currentGroup = groupService.getGroupById(currentUser.getDomain(), groupId);\n\n        Collection<UserGroupDTO> users = null;\n\n        if (currentUser == null) {\n            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // Authentication required\n        } else if (currentGroup == null) {\n            response.setStatus(HttpServletResponse.SC_NOT_FOUND); // Resource not found\n        } else {\n            users = groupService.getMembersForGroup(groupId, currentUser.getLogin());\n        }\n\n        for (UserGroupDTO user : users) {\n            if (user.getLogin().equals(currentUser.getLogin())) {\n                return user;\n            }\n        }\n\n        UserGroupDTO currentUserDTO = new UserGroupDTO();\n        currentUserDTO.setLogin(currentUser.getLogin());\n        currentUserDTO.setUsername(currentUser.getUsername());\n        currentUserDTO.setAvatar(currentUser.getAvatar());\n        currentUserDTO.setFirstName(currentUser.getFirstName());\n        currentUserDTO.setLastName(currentUser.getLastName());\n        currentUserDTO.setIsMember(false);\n\n        return currentUserDTO;\n    }\n\n    /**\n     * PUT  /groups/{groupId}/members/{userUsername} -> add a member to group\n     */\n    @RequestMapping(value = \"/rest/groups/{groupId}/members/{username}\",\n            method = RequestMethod.PUT,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public UserGroupDTO addUserToGroup(HttpServletResponse response, @PathVariable(\"groupId\") String groupId, @PathVariable(\"username\") String username) {\n\n        User currentUser = authenticationService.getCurrentUser();\n        Group currentGroup = groupService.getGroupById(currentUser.getDomain(), groupId);\n        User userToAdd = userService.getUserByUsername(username);\n\n        UserGroupDTO dto = null;\n\n        if (currentUser == null) {\n            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // Authentication required\n        } else if (currentGroup == null || userToAdd == null) {\n            response.setStatus(HttpServletResponse.SC_NOT_FOUND); // Resource not found\n        } else {\n            if (isGroupManagedByCurrentUser(currentGroup) && !currentUser.equals(userToAdd)) {\n                groupService.addMemberToGroup(userToAdd, currentGroup);\n                dto = groupService.getMembersForGroup(groupId, userToAdd);\n            } else if (currentGroup.isPublicGroup() && currentUser.equals(userToAdd) && !isGroupManagedByCurrentUser(currentGroup)) {\n                groupService.addMemberToGroup(userToAdd, currentGroup);\n                dto = groupService.getMembersForGroup(groupId, userToAdd);\n            } else {\n                response.setStatus(HttpServletResponse.SC_FORBIDDEN);\n            }\n        }\n        return dto;\n    }\n\n    /**\n     * DELETE  /groups/{groupId}/members/{userUsername} -> remove a member to group\n     */\n    @RequestMapping(value = \"/rest/groups/{groupId}/members/{username}\",\n            method = RequestMethod.DELETE,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public boolean removeUserFromGroup(HttpServletResponse response, @PathVariable(\"groupId\") String groupId, @PathVariable(\"username\") String username) {\n\n        User currentUser = authenticationService.getCurrentUser();\n        Group currentGroup = groupService.getGroupById(currentUser.getDomain(), groupId);\n        User userToremove = userService.getUserByUsername(username);\n\n        UserGroupDTO dto = null;\n\n        if (currentUser == null) {\n            response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // Authentication required\n            return false;\n        } else if (currentGroup == null || userToremove == null) {\n            response.setStatus(HttpServletResponse.SC_NOT_FOUND); // Resource not found\n            return false;\n        } else {\n            if (isGroupManagedByCurrentUser(currentGroup) && !currentUser.equals(userToremove)) {\n                groupService.removeMemberFromGroup(userToremove, currentGroup);\n                groupService.getMembersForGroup(groupId, userToremove);\n            } else if (currentGroup.isPublicGroup() && currentUser.equals(userToremove) && !isGroupManagedByCurrentUser(currentGroup)) {\n                groupService.removeMemberFromGroup(userToremove, currentGroup);\n                groupService.getMembersForGroup(groupId, userToremove);\n            } else {\n                response.setStatus(HttpServletResponse.SC_FORBIDDEN);\n                return false;\n            }\n        }\n        return true;\n    }\n\n    private boolean isGroupManagedByCurrentUser(Group group) {\n        Collection<Group> groups = groupService.getGroupsWhereCurrentUserIsAdmin();\n        boolean isGroupManagedByCurrentUser = false;\n        for (Group testGroup : groups) {\n            if (testGroup.getGroupId().equals(group.getGroupId())) {\n                isGroupManagedByCurrentUser = true;\n                break;\n            }\n        }\n        return isGroupManagedByCurrentUser;\n    }\n\n    private Group getGroupFromUser(User currentUser, String groupId) {\n        Collection<Group> groups = groupService.getGroupsForUser(currentUser);\n        for (Group testGroup : groups) {\n            if (testGroup.getGroupId().equals(groupId)) {\n                return testGroup;\n            }\n        }\n        return null;\n    }\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/rest/MentionsController.java",
    "content": "package fr.ippon.tatami.web.rest;\n\nimport com.yammer.metrics.annotation.Timed;\nimport fr.ippon.tatami.service.TimelineService;\nimport fr.ippon.tatami.service.dto.StatusDTO;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.RequestParam;\nimport org.springframework.web.bind.annotation.ResponseBody;\n\nimport javax.inject.Inject;\nimport java.util.Collection;\n\n/**\n * REST controller for getting the mention line.\n *\n * @author Julien Dubois\n */\n@Controller\npublic class MentionsController {\n\n    private final Logger log = LoggerFactory.getLogger(MentionsController.class);\n\n    @Inject\n    private TimelineService timelineService;\n\n    /**\n     * GET  /mentions -> get the mentions for the current user\n     */\n    @RequestMapping(value = \"/rest/mentions\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<StatusDTO> listMentionStatus(@RequestParam(required = false) Integer count,\n                                                   @RequestParam(required = false) String start,\n                                                   @RequestParam(required = false) String finish) {\n\n        if (count == null) {\n            count = 20;\n        }\n        try {\n            return timelineService.getMentionline(count, start, finish);\n        } catch (NumberFormatException e) {\n            log.warn(\"Page size undefined ; sizing to default\", e);\n            return timelineService.getMentionline(20, start, finish);\n        }\n    }\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/rest/SearchController.java",
    "content": "package fr.ippon.tatami.web.rest;\n\nimport com.yammer.metrics.annotation.Timed;\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.UserTagRepository;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.*;\nimport fr.ippon.tatami.service.dto.StatusDTO;\nimport fr.ippon.tatami.service.dto.UserDTO;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport fr.ippon.tatami.web.rest.dto.SearchResults;\nimport fr.ippon.tatami.web.rest.dto.Tag;\nimport org.apache.commons.lang.StringUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.RequestParam;\nimport org.springframework.web.bind.annotation.ResponseBody;\n\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.List;\n\n/**\n * Search engine controller.\n */\n@Controller\npublic class SearchController {\n\n    private final Logger log = LoggerFactory.getLogger(SearchController.class);\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    @Inject\n    private SearchService searchService;\n\n    @Inject\n    private TimelineService timelineService;\n\n    @Inject\n    private UserService userService;\n\n    @Inject\n    private GroupService groupService;\n\n    @Inject\n    private TrendService trendService;\n\n    @Inject\n    private UserTagRepository userTagRepository;\n\n    /**\n     * GET  /search/all?q=tatami -> search users, tags, groups for \"tatami\"\n     */\n    @RequestMapping(value = \"/rest/search/all\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public SearchResults search(@RequestParam(value = \"q\", required = false, defaultValue = \"\") String q) {\n        SearchResults searchResults = new SearchResults();\n        searchResults.setTags(this.searchRecentTags(q));\n        searchResults.setUsers(this.searchUsers(q));\n        searchResults.setGroups(this.searchGroups(q));\n        return searchResults;\n    }\n\n\n    /**\n     * GET  /search/status?q=tatami -> get the status where \"tatami\" appears\n     */\n    @RequestMapping(value = \"/rest/search/status\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<StatusDTO> listStatusForUser(@RequestParam(value = \"q\", required = false, defaultValue = \"\") String query,\n                                                   @RequestParam(value = \"page\", required = false, defaultValue = \"0\") Integer page,\n                                                   @RequestParam(value = \"rpp\", required = false, defaultValue = \"20\") Integer rpp) {\n\n        log.debug(\"REST request to search status containing these words ({}).\", query);\n        final User currentUser = authenticationService.getCurrentUser();\n        String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());\n        List<String> line;\n        if (StringUtils.isNotBlank(query)) {\n            line = searchService.searchStatus(domain, query, page, rpp);\n        } else {\n            line = Collections.emptyList();\n        }\n        return timelineService.buildStatusList(line);\n    }\n\n\n    /**\n     * GET  /search/tags\" -> search tags<br>\n     *\n     * @return a Collection of tags matching the query\n     */\n    @RequestMapping(value = \"/rest/search/tags\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<Tag> searchRecentTags(@RequestParam(\"q\") String query) {\n        String prefix = query.toLowerCase();\n        String currentLogin = authenticationService.getCurrentUser().getLogin();\n        String domain = DomainUtil.getDomainFromLogin(currentLogin);\n        Collection<String> followedTags = userTagRepository.findTags(currentLogin);\n        Collection<String> trends = trendService.searchTags(domain, prefix, 5);\n        Collection<Tag> tags = new ArrayList<Tag>();\n\n        if (query != null && !query.equals(\"\")) {\n            this.log.debug(\"REST request to find tags starting with : {}\", prefix);\n            for (String trend : trends) {\n                Tag tag = new Tag();\n                tag.setName(trend);\n                if (followedTags.contains(trend)) {\n                    tag.setFollowed(true);\n                }\n                tags.add(tag);\n            }\n\n        }\n        return tags;\n    }\n\n    /**\n     * GET  /search/groups\" -> search groups<br>\n     *\n     * @return a Collection of groups matching the query\n     */\n    @RequestMapping(value = \"/rest/search/groups\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<Group> searchGroups(@RequestParam(\"q\") String query) {\n        String prefix = query.toLowerCase();\n        String currentLogin = authenticationService.getCurrentUser().getLogin();\n        String domain = DomainUtil.getDomainFromLogin(currentLogin);\n        Collection<Group> groups;\n        if (query != null && !query.equals(\"\")) {\n            this.log.debug(\"REST request to find groups starting with : {}\", prefix);\n            groups = searchService.searchGroupByPrefix(domain, prefix, 5);\n        } else {\n            groups = new ArrayList<Group>();\n        }\n        return groupService.buildGroupList(groups);\n    }\n\n    /**\n     * GET  /search/users\" -> search user by username<br>\n     * Should return a collection of users matching the query.<br>\n     * The collection doesn't contain the current user even if he matches the query.<br>\n     * If nothing matches, an empty collection (but not null) is returned.<br>\n     *\n     * @param query the query\n     * @return a Collection of User\n     */\n    @RequestMapping(value = \"/rest/search/users\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<UserDTO> searchUsers(@RequestParam(\"q\") String query) {\n        String prefix = query.toLowerCase();\n\n        User currentUser = authenticationService.getCurrentUser();\n        String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());\n        Collection<String> logins = searchService.searchUserByPrefix(domain, prefix);\n        Collection<User> users;\n\n        if (query != null && !query.equals(\"\")) {\n            this.log.debug(\"REST request to find users starting with : {}\", prefix);\n            users = userService.getUsersByLogin(logins);\n        } else {\n            users = new ArrayList<User>();\n        }\n        return userService.buildUserDTOList(users);\n\n    }\n\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/rest/StatsController.java",
    "content": "package fr.ippon.tatami.web.rest;\n\nimport fr.ippon.tatami.domain.UserStatusStat;\nimport fr.ippon.tatami.service.StatsService;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.ResponseBody;\n\nimport javax.inject.Inject;\nimport java.util.Collection;\n\n/**\n * REST controller for managing stats.\n *\n * @author Julien Dubois\n */\n@Controller\npublic class StatsController {\n\n    private final Logger log = LoggerFactory.getLogger(StatsController.class);\n\n    @Inject\n    private StatsService statsService;\n\n    /**\n     * GET  /stats/day -> statistics for today\n     */\n    @RequestMapping(value = \"/rest/stats/day\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    public Collection<UserStatusStat> listDayStatusStats() {\n        log.debug(\"REST request to get the users stats.\");\n        return statsService.getDayline();\n    }\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/rest/TagController.java",
    "content": "package fr.ippon.tatami.web.rest;\n\nimport com.yammer.metrics.annotation.Timed;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.UserTagRepository;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.TagMembershipService;\nimport fr.ippon.tatami.service.TimelineService;\nimport fr.ippon.tatami.service.TrendService;\nimport fr.ippon.tatami.service.UserService;\nimport fr.ippon.tatami.service.dto.StatusDTO;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport fr.ippon.tatami.web.rest.dto.Tag;\nimport fr.ippon.tatami.web.rest.dto.Trend;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.*;\n\nimport javax.inject.Inject;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.List;\n\n/**\n * REST controller for managing tags.\n *\n * @author Julien Dubois\n */\n@Controller\npublic class TagController {\n\n    private final Logger log = LoggerFactory.getLogger(TagController.class);\n\n    @Inject\n    private TimelineService timelineService;\n\n    @Inject\n    private TagMembershipService tagMembershipService;\n\n    @Inject\n    private TrendService trendService;\n\n    @Inject\n    private UserTagRepository userTagRepository;\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    @Inject\n    private UserService userService;\n\n    /**\n     * GET  /rest/tags/{tagName}/tag_timeline -> get the latest status for a given tag\n     */\n    @RequestMapping(value = \"/rest/tags/{tagName}/tag_timeline\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<StatusDTO> listStatusForTag(@PathVariable String tagName,\n                                                  @RequestParam(required = false) Integer count,\n                                                  @RequestParam(required = false) String start,\n                                                  @RequestParam(required = false) String finish) {\n\n        log.debug(\"REST request to get statuses for tag : {}\", tagName);\n        if (count == null) {\n            count = 20;\n        }\n        try {\n            return timelineService.getTagline(tagName, count, start, finish);\n        } catch (NumberFormatException e) {\n            log.warn(\"Page size undefined ; sizing to default\", e);\n            return timelineService.getTagline(tagName, 20, start, finish);\n        }\n    }\n\n    /**\n     * WARNING! This is the old API, only used by the admin console\n     * <p/>\n     * POST /tagmemberships/create -> follow tag\n     */\n    @RequestMapping(value = \"/rest/tagmemberships/create\",\n            method = RequestMethod.POST,\n            consumes = \"application/json\")\n    @ResponseBody\n    @Timed\n    @Deprecated\n    public boolean followTag(@RequestBody Tag tag) {\n        log.debug(\"REST request to follow tag : {}\", tag);\n        return tagMembershipService.followTag(tag);\n    }\n\n    /**\n     * WARNING! This is the old API, only used by the admin console\n     * <p/>\n     * POST /tagmemberships/destroy -> unfollow tag\n     */\n    @RequestMapping(value = \"/rest/tagmemberships/destroy\",\n            method = RequestMethod.POST,\n            consumes = \"application/json\")\n    @ResponseBody\n    @Timed\n    @Deprecated\n    public boolean unfollowTag(@RequestBody Tag tag) {\n        log.debug(\"REST request to unfollow tag  : {}\", tag);\n        return tagMembershipService.unfollowTag(tag);\n    }\n\n    /**\n     * POST /tagmemberships/lookup -> looks up the tag for the user\n     */\n    @RequestMapping(value = \"/rest/tagmemberships/lookup\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Tag lookupTag(@RequestParam(\"tag_name\") String tagname) {\n        User currentUser = authenticationService.getCurrentUser();\n        Collection<String> followedTags = userTagRepository.findTags(currentUser.getLogin());\n        Tag tag = new Tag();\n        tag.setName(tagname);\n        if (followedTags.contains(tagname)) {\n            tag.setFollowed(true);\n        }\n        return tag;\n    }\n\n    /**\n     * GET  /tagmemberships/list -> get the tags followed by the current user\n     */\n    @RequestMapping(value = \"/rest/tagmemberships/list\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<Tag> getFollowedTags() {\n        User currentUser = authenticationService.getCurrentUser();\n        Collection<String> followedTags = userTagRepository.findTags(currentUser.getLogin());\n        Collection<Tag> tags = new ArrayList<Tag>();\n        for (String followedTag : followedTags) {\n            Tag tag = new Tag();\n            tag.setName(followedTag);\n            tag.setFollowed(true);\n            tags.add(tag);\n        }\n        return tags;\n    }\n\n    /**\n     * GET  /tags/popular -> get the list of popular tags\n     */\n    @RequestMapping(value = \"/rest/tags/popular\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<Tag> getPopularTags() {\n        User currentUser = authenticationService.getCurrentUser();\n        String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());\n        List<Trend> trends = trendService.getCurrentTrends(domain);\n        Collection<String> followedTags = userTagRepository.findTags(currentUser.getLogin());\n        Collection<Tag> tags = new ArrayList<Tag>();\n        for (Trend trend : trends) {\n            Tag tag = new Tag();\n            tag.setName(trend.getTag());\n            if (followedTags.contains(trend.getTag())) {\n                tag.setFollowed(true);\n            }\n            tags.add(tag);\n        }\n        return tags;\n    }\n\n\n    @RequestMapping(value = \"/rest/tags\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<Tag> getTags(@RequestParam(required = false, value = \"popular\") String popular,\n                                   @RequestParam(required = false, value = \"user\") String username,\n                                   @RequestParam(required = false, value = \"search\") String search) {\n        Collection<Tag> tags = new ArrayList<Tag>();\n        User currentUser = authenticationService.getCurrentUser();\n        String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());\n        Collection<String> followedTags = userTagRepository.findTags(currentUser.getLogin());\n        Collection<String> tagNames;\n\n        if (popular != null) {\n            List<Trend> trends;\n            User user = null;\n            if (username != null) user = userService.getUserByUsername(username);\n            if (user != null) {\n                trendService.getTrendsForUser(user.getLogin());\n                trends = trendService.getTrendsForUser(user.getLogin());\n            } else {\n                trends = trendService.getCurrentTrends(domain);\n            }\n\n            for (Trend trend : trends) {\n                Tag tag = new Tag();\n                tag.setName(trend.getTag());\n                tag.setTrendingUp(trend.isTrendingUp());\n                tags.add(tag);\n            }\n        } else if (search != null && !search.isEmpty()) {\n            String prefix = search.toLowerCase();\n            tagNames = trendService.searchTags(domain, prefix, 5);\n            for (String tagName : tagNames) {\n                Tag tag = new Tag();\n                tag.setName(tagName);\n                tags.add(tag);\n            }\n        } else {\n            tagNames = userTagRepository.findTags(currentUser.getLogin());\n            for (String tagName : tagNames) {\n                Tag tag = new Tag();\n                tag.setName(tagName);\n                tags.add(tag);\n            }\n        }\n\n        for (Tag tag : tags) {\n            if (followedTags.contains(tag.getName())) {\n                tag.setFollowed(true);\n            }\n        }\n\n        return tags;\n    }\n\n\n    @RequestMapping(value = \"/rest/tags/{tag}\",\n            method = RequestMethod.PUT,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Tag updateTag(@RequestBody Tag tag) {\n        if (tag.isFollowed()) {\n            tagMembershipService.followTag(tag);\n        } else {\n            tagMembershipService.unfollowTag(tag);\n        }\n        return tag;\n    }\n\n\n    @RequestMapping(value = \"/rest/tags/{tag}\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Tag getTag(@PathVariable(\"tag\") String tagName) {\n        User currentUser = authenticationService.getCurrentUser();\n        Collection<String> followedTags = userTagRepository.findTags(currentUser.getLogin());\n        Tag tag = new Tag();\n        tag.setName(tagName);\n        if (followedTags.contains(tagName)) {\n            tag.setFollowed(true);\n        }\n        return tag;\n    }\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/rest/TimelineController.java",
    "content": "package fr.ippon.tatami.web.rest;\n\nimport com.yammer.metrics.annotation.Timed;\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.domain.status.AbstractStatus;\nimport fr.ippon.tatami.domain.status.StatusDetails;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.GroupService;\nimport fr.ippon.tatami.service.StatusUpdateService;\nimport fr.ippon.tatami.service.TimelineService;\nimport fr.ippon.tatami.service.dto.StatusDTO;\nimport fr.ippon.tatami.service.exception.ArchivedGroupException;\nimport fr.ippon.tatami.service.exception.ReplyStatusException;\nimport fr.ippon.tatami.web.rest.dto.ActionStatus;\nimport org.apache.commons.lang.StringEscapeUtils;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.*;\nimport twitter4j.StatusUpdate;\n\nimport javax.inject.Inject;\nimport javax.servlet.http.HttpServletResponse;\nimport java.io.PrintWriter;\nimport java.io.StringWriter;\nimport java.util.ArrayList;\nimport java.util.Collection;\n\n/**\n * REST controller for managing status.\n *\n * @author Julien Dubois\n */\n@Controller\npublic class TimelineController {\n\n    private final Logger log = LoggerFactory.getLogger(TimelineController.class);\n\n    @Inject\n    private TimelineService timelineService;\n\n    @Inject\n    private StatusUpdateService statusUpdateService;\n\n    @Inject\n    private GroupService groupService;\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    /**\n     * GET  /statuses/details/:id -> returns the details for a status, specified by the id parameter\n     */\n    @RequestMapping(value = \"/rest/statuses/details/{statusId}\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    public StatusDetails getStatusDetails(@PathVariable(\"statusId\") String statusId) {\n        log.debug(\"REST request to get status details Id : {}\", statusId);\n        return timelineService.getStatusDetails(statusId);\n    }\n\n\n    /**\n     * Report a status\n     */\n    @RequestMapping(value = \"/rest/statuses/report/{statusId}\",\n            method = RequestMethod.POST)\n    @ResponseBody\n    public void reportStatus(@PathVariable(\"statusId\") String statusId) {\n        log.debug(\"REST request to report a status details Id : {}\", statusId);\n        statusUpdateService.reportStatus(authenticationService.getCurrentUser().getLogin(), statusId);\n    }\n\n    /**\n     * Report a status\n     */\n    @RequestMapping(value = \"/rest/statuses/report/reportedList\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    public Collection<StatusDTO> getReportStatuses() {\n        log.debug(\"REST request to get all reports\");\n\n        Collection<StatusDTO> reportedStatusList = statusUpdateService.findReportedStatuses();\n        return reportedStatusList;\n    }\n\n    @RequestMapping(value = \"/rest/statuses/report/{statusId}\",\n            method = RequestMethod.PUT)\n    @ResponseBody\n    public void deleteReportedStatus(@PathVariable(\"statusId\") String statusId) {\n        log.debug(\"REST request to delete a status Id : {}\", statusId);\n        statusUpdateService.deleteReportedStatus(statusId);\n    }\n\n    @RequestMapping(value = \"/rest/statuses/report/{statusId}\",\n            method = RequestMethod.DELETE)\n    @ResponseBody\n    public void approveReportedStatus(@PathVariable(\"statusId\") String statusId) {\n        log.debug(\"REST request to approve a status Id : {}\", statusId);\n        statusUpdateService.approveReportedStatus(statusId);\n    }\n\n\n\n    /**\n     * GET  /statuses/home_timeline -> get the latest statuses from the current user\n     */\n    @RequestMapping(value = \"/rest/statuses/home_timeline\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<StatusDTO> listStatus(@RequestParam(required = false) Integer count,\n                                            @RequestParam(required = false) String start,\n                                            @RequestParam(required = false) String finish) {\n        if (count == null || count == 0) {\n            count = 20; //Default value\n        }\n        try {\n            return timelineService.getTimeline(count, start, finish);\n        } catch (Exception e) {\n            StringWriter stack = new StringWriter();\n            PrintWriter pw = new PrintWriter(stack);\n            e.printStackTrace(pw);\n            log.debug(\"{}\", stack.toString());\n            return null;\n        }\n    }\n\n    /**\n     * GET  /statuses/user_timeline?screen_name=jdubois -> get the latest statuses from user \"jdubois\"\n     */\n    @RequestMapping(value = \"/rest/statuses/{username}/timeline\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    public Collection<StatusDTO> listStatusForUser(@PathVariable(\"username\") String username,\n                                                   @RequestParam(required = false) Integer count,\n                                                   @RequestParam(required = false) String start,\n                                                   @RequestParam(required = false) String finish) {\n\n        if (count == null || count == 0) {\n            count = 20; //Default value\n        }\n        log.debug(\"REST request to get someone's status (username={}).\", username);\n        if (username == null || username.length() == 0) {\n            return new ArrayList<StatusDTO>();\n        }\n        try {\n            return timelineService.getUserline(username, count, start, finish);\n        } catch (Exception e) {\n            if (log.isDebugEnabled()) {\n                e.printStackTrace();\n            }\n            return new ArrayList<StatusDTO>();\n        }\n    }\n\n    @RequestMapping(value = \"/rest/statuses/{statusId}\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    public StatusDTO getStatus(@PathVariable(\"statusId\") String statusId) {\n        log.debug(\"REST request to get status Id : {}\", statusId);\n        return timelineService.getStatus(statusId);\n    }\n\n    @RequestMapping(value = \"/rest/statuses/{statusId}\",\n            method = RequestMethod.DELETE)\n    public void deleteStatus(@PathVariable(\"statusId\") String statusId) {\n        log.debug(\"REST request to get status Id : {}\", statusId);\n        timelineService.removeStatus(statusId);\n    }\n\n    @RequestMapping(value = \"/rest/statuses/{statusId}\",\n            method = RequestMethod.PATCH)\n    @ResponseBody\n    public StatusDTO updateStatus(@RequestBody ActionStatus action, @PathVariable(\"statusId\") String statusId) {\n        try {\n            StatusDTO status = timelineService.getStatus(statusId);\n            if (action.isFavorite() != null && status.isFavorite() != action.isFavorite()) {\n                if (action.isFavorite()) {\n                    timelineService.addFavoriteStatus(statusId);\n                } else {\n                    timelineService.removeFavoriteStatus(statusId);\n                }\n                status.setFavorite(action.isFavorite());\n            }\n            if (action.isShared() != null && action.isShared()) {\n                timelineService.shareStatus(statusId);\n                status.setShareByMe(action.isShared());\n            }\n            if (action.isAnnounced() != null && action.isAnnounced()) {\n                timelineService.announceStatus(statusId);\n            }\n            return status;\n        } catch (Exception e) {\n            StringWriter stack = new StringWriter();\n            PrintWriter pw = new PrintWriter(stack);\n            e.printStackTrace(pw);\n            log.debug(\"{}\", stack.toString());\n            return null;\n        }\n    }\n\n    /**\n     * POST /statuses/ -> create a new Status\n     */\n    @RequestMapping(value = \"/rest/statuses/\",\n            method = RequestMethod.POST,\n            produces = \"application/json\")\n    @Timed\n    public String postStatus(@RequestBody StatusDTO status, HttpServletResponse response) throws ArchivedGroupException, ReplyStatusException {\n        log.debug(\"REST request to add status : {}\", status.getContent());\n        String escapedContent = StringEscapeUtils.escapeHtml(status.getContent());\n        Collection<String> attachmentIds = status.getAttachmentIds();\n\n        if (status.getReplyTo() != null && !status.getReplyTo().isEmpty()) {\n            log.debug(\"Creating a reply to : {}\", status.getReplyTo());\n            statusUpdateService.replyToStatus(escapedContent, status.getReplyTo(), attachmentIds);\n        } else if (status.isStatusPrivate() || status.getGroupId() == null || status.getGroupId().equals(\"\")) {\n            log.debug(\"Private status\");\n            statusUpdateService.postStatus(escapedContent, status.isStatusPrivate(), attachmentIds, status.getGeoLocalization());\n        } else {\n            User currentUser = authenticationService.getCurrentUser();\n            Collection<Group> groups = groupService.getGroupsForUser(currentUser);\n            Group group = null;\n            for (Group testGroup : groups) {\n                if (testGroup.getGroupId().equals(status.getGroupId())) {\n                    group = testGroup;\n                    break;\n                }\n            }\n            if (group == null) {\n                log.info(\"Permission denied! User {} tried to access \" +\n                        \"group ID = {}\", currentUser.getLogin(), status.getGroupId());\n                response.setStatus(HttpServletResponse.SC_FORBIDDEN);\n            } else if (group.isArchivedGroup()) {\n                log.info(\"Archived group! User {} tried to post a message to archived \" +\n                        \"group ID = {}\", currentUser.getLogin(), status.getGroupId());\n                response.setStatus(HttpServletResponse.SC_FORBIDDEN);\n            } else {\n                statusUpdateService.postStatusToGroup(escapedContent, group, attachmentIds, status.getGeoLocalization());\n            }\n        }\n        return \"{}\";\n    }\n\n    /**\n     * POST /statuses/hide -> hide the status from the current user timeline\n     */\n    @RequestMapping(value = \"/rest/statuses/hide/{statusId}\",\n            method = RequestMethod.POST)\n    public void hideStatus(@PathVariable(\"statusId\") String statusId) {\n        log.debug(\"REST request to hide status Id : {}\", statusId);\n        timelineService.hideStatus(statusId);\n    }\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/rest/TrendController.java",
    "content": "package fr.ippon.tatami.web.rest;\n\nimport com.yammer.metrics.annotation.Timed;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.TrendService;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport fr.ippon.tatami.web.rest.dto.Trend;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.RequestParam;\nimport org.springframework.web.bind.annotation.ResponseBody;\n\nimport javax.inject.Inject;\nimport java.util.List;\n\n/**\n * REST controller for managing trends.\n *\n * @author Julien Dubois\n */\n@Controller\npublic class TrendController {\n\n    private final Logger log = LoggerFactory.getLogger(TrendController.class);\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    @Inject\n    private TrendService trendService;\n\n    /**\n     * GET  /trends -> get the tag trends\n     */\n    @RequestMapping(value = \"/rest/trends\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public List<Trend> getTrends() {\n\n        String currentLogin = authenticationService.getCurrentUser().getLogin();\n        String domain = DomainUtil.getDomainFromLogin(currentLogin);\n        return trendService.getCurrentTrends(domain);\n    }\n\n    /**\n     * GET  /users/trends ->  get the user trends\n     */\n    @RequestMapping(value = \"/rest/user/trends\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public List<Trend> getUserTrends(@RequestParam(\"screen_name\") String username) {\n        String currentLogin = authenticationService.getCurrentUser().getLogin();\n        String domain = DomainUtil.getDomainFromLogin(currentLogin);\n        return trendService.getTrendsForUser(DomainUtil.getLoginFromUsernameAndDomain(username, domain));\n    }\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/rest/UserController.java",
    "content": "package fr.ippon.tatami.web.rest;\n\nimport com.yammer.metrics.annotation.Timed;\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.SearchService;\nimport fr.ippon.tatami.service.SuggestionService;\nimport fr.ippon.tatami.service.UserService;\nimport fr.ippon.tatami.service.dto.UserDTO;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.web.bind.annotation.*;\n\nimport javax.inject.Inject;\nimport javax.servlet.http.HttpServletResponse;\nimport java.util.Collection;\n\n/**\n * REST controller for managing users.\n *\n * @author Julien Dubois\n */\n@Controller\npublic class UserController {\n\n    private final Logger log = LoggerFactory.getLogger(UserController.class);\n\n    @Inject\n    private UserService userService;\n\n    @Inject\n    private AuthenticationService authenticationService;\n\n    @Inject\n    private SearchService searchService;\n\n    @Inject\n    private SuggestionService suggestionService;\n\n    /**\n     * GET  /rest/users/:username -> get the \"jdubois\" user\n     */\n    @RequestMapping(value = \"/rest/users/{username}\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public UserDTO getUser(@PathVariable(\"username\") String username) {\n        this.log.debug(\"REST request to get Profile : {}\", username);\n        User user = userService.getUserByUsername(username);\n\n        return userService.buildUserDTO(user);\n    }\n\n    /**\n     * GET  /users/suggestions -> suggest users to follow\n     */\n    @RequestMapping(value = \"/rest/users/suggestions\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<User> suggestions() {\n        String login = authenticationService.getCurrentUser().getLogin();\n        return suggestionService.suggestUsers(login);\n    }\n\n    /**\n     * GET  /rest/users/search -> search users by prefix<br>\n     * Should return a collection of users matching the query.<br>\n     * The collection doesn't contain the current user even if he matches the query.<br>\n     * If nothing matches, an empty collection (but not null) is returned.<br>\n     *\n     * @param query the query\n     * @return a Collection of User\n     */\n    @RequestMapping(value = \"/rest/users/search\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<User> searchUsers(@RequestParam(\"q\") String query) {\n        String prefix = query.toLowerCase();\n        this.log.debug(\"REST request to find users starting with : {}\", prefix);\n        User currentUser = authenticationService.getCurrentUser();\n        String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());\n        Collection<String> logins = searchService.searchUserByPrefix(domain, prefix);\n        return userService.getUsersByLogin(logins);\n    }\n\n    /**\n     * GET  /users -> Get all users of domain\n     */\n    @RequestMapping(value = \"/rest/users\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @ResponseBody\n    @Timed\n    public Collection<UserDTO> getAll(@RequestParam(required = false) Integer pagination) {\n        if (pagination == null) {\n            pagination = 0;\n        }\n        return userService.buildUserDTOList(userService.getUsersForCurrentDomain(pagination));\n    }\n\n    /**\n     * POST  /users -> Register new user\n     */\n    @RequestMapping(value = \"/rest/users\",\n            method = RequestMethod.POST,\n            produces = \"application/json\")\n    @ResponseBody\n    public void register(@RequestParam String email, HttpServletResponse response) {\n        email = email.toLowerCase();\n        if (userService.getUserByLogin(email) != null) {\n            response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);\n            return;\n        }\n        User user = new User();\n        user.setLogin(email);\n        userService.registerUser(user);\n        response.setStatus(HttpServletResponse.SC_CREATED);\n    }\n\n\n}\n"
  },
  {
    "path": "web/src/main/java/fr/ippon/tatami/web/rest/UserXAuthController.java",
    "content": "package fr.ippon.tatami.web.rest;\n\nimport com.google.api.client.auth.oauth2.TokenResponse;\nimport com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest;\nimport com.google.api.client.googleapis.auth.oauth2.GoogleCredential;\nimport com.google.api.client.http.HttpTransport;\nimport com.google.api.client.http.javanet.NetHttpTransport;\nimport com.google.api.client.json.jackson2.JacksonFactory;\nimport com.google.api.services.plus.Plus;\nimport com.google.api.services.plus.model.Person;\nimport com.yammer.metrics.annotation.Timed;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.DomainRepository;\nimport fr.ippon.tatami.security.GoogleAuthenticationToken;\nimport fr.ippon.tatami.security.xauth.Token;\nimport fr.ippon.tatami.security.xauth.TokenProvider;\nimport fr.ippon.tatami.service.UserService;\nimport fr.ippon.tatami.service.util.DomainUtil;\nimport org.slf4j.Logger;\nimport org.slf4j.LoggerFactory;\nimport org.springframework.core.env.Environment;\nimport org.springframework.security.authentication.AuthenticationManager;\nimport org.springframework.security.authentication.UsernamePasswordAuthenticationToken;\nimport org.springframework.security.core.Authentication;\nimport org.springframework.security.core.context.SecurityContextHolder;\nimport org.springframework.security.core.userdetails.UserDetails;\nimport org.springframework.security.core.userdetails.UserDetailsService;\nimport org.springframework.security.core.userdetails.UsernameNotFoundException;\nimport org.springframework.stereotype.Controller;\nimport org.springframework.util.StringUtils;\nimport org.springframework.web.bind.annotation.RequestMapping;\nimport org.springframework.web.bind.annotation.RequestMethod;\nimport org.springframework.web.bind.annotation.RequestParam;\n\nimport javax.inject.Inject;\nimport javax.servlet.ServletRequest;\nimport javax.servlet.http.HttpServletRequest;\nimport java.io.IOException;\nimport java.util.ArrayList;\nimport java.util.Collection;\n\n@Controller\npublic class UserXAuthController {\n\n    private static final Logger log = LoggerFactory.getLogger(UserXAuthController.class);\n\n    private static final String GOOGLE_AUTH_CODE_HEADER_NAME = \"x-auth-code-header\";\n\n    @Inject\n    private UserService userService;\n\n    @Inject\n    private TokenProvider tokenProvider;\n\n    @Inject\n    private UserDetailsService userDetailsService;\n\n    @Inject\n    private DomainRepository domainRepository;\n\n    @Inject\n    private AuthenticationManager authenticationManager;\n\n    @Inject\n    Environment env;\n\n    /**\n     * GET /rest/client/id -> Gets the client id\n     */\n    @RequestMapping(value = \"/rest/client/id\",\n            method = RequestMethod.GET,\n            produces = \"application/json\")\n    @Timed\n    public Collection<String> getClientId() {\n\n        String clientId = env.getProperty(\"tatami.google.clientId\");\n        Collection<String> clientList = new ArrayList<String>();\n        clientList.add(clientId);\n        return clientList;\n    }\n\n    /**\n     * POST /rest/oauth/token -> Gets a token based on the users google information\n     */\n    @RequestMapping(value = \"/rest/oauth/token\",\n            method = RequestMethod.POST)\n    @Timed\n    public Token getGoogleUser(ServletRequest servletRequest) {\n        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;\n        String authorizationCode = httpServletRequest.getHeader(GOOGLE_AUTH_CODE_HEADER_NAME);\n\n        Token authToken = null;\n        if(StringUtils.hasText(authorizationCode)){\n            try {\n                Person user = getGoogleUserInfo(authorizationCode);\n                UserDetails userDetails = getUserDetails(user);\n                GoogleAuthenticationToken token = new GoogleAuthenticationToken(userDetails);\n                authToken = tokenProvider.createToken(userDetails);\n                Authentication authentication = authenticationManager.authenticate(token);\n                SecurityContextHolder.getContext().setAuthentication(authentication);\n            } catch (IOException ioe) {\n                log.error(\"{}\", ioe);\n            }\n        }\n        return authToken;\n    }\n\n    @RequestMapping(value = \"/rest/authentication\",\n            method = RequestMethod.POST)\n    @Timed\n    public Token authorize(@RequestParam String j_username, @RequestParam String j_password) {\n        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(j_username, j_password);\n        Authentication authentication = authenticationManager.authenticate(token);\n        SecurityContextHolder.getContext().setAuthentication(authentication);\n        UserDetails details = userDetailsService.loadUserByUsername(j_username);\n        return tokenProvider.createToken(details);\n    }\n\n    private Person getGoogleUserInfo(String authorizationCode) throws IOException {\n        String clientId = env.getProperty(\"tatami.google.clientId\");\n        String clientSecret = env.getProperty(\"tatami.google.clientSecret\");\n\n        HttpTransport transport = new NetHttpTransport();\n        JacksonFactory jacksonFactory = new JacksonFactory();\n\n\n        TokenResponse accessCode = new GoogleAuthorizationCodeTokenRequest(transport, jacksonFactory,\n                clientId, clientSecret, authorizationCode, \"http://localhost/callback\")\n                .execute();\n\n        GoogleCredential googleCredential = new GoogleCredential.Builder()\n                .setJsonFactory(new JacksonFactory())\n                .setTransport(transport)\n                .setClientSecrets(clientId, clientSecret)\n                .build()\n                .setFromTokenResponse(accessCode);\n\n        Plus plus = new Plus.Builder(transport, jacksonFactory, googleCredential)\n                .setApplicationName(\"Tatami\")\n                .build();\n        return plus.people().get(\"me\").execute();\n    }\n\n    private UserDetails getUserDetails(Person user)  throws UsernameNotFoundException {\n        String login = user.getEmails().get(0).getValue();\n\n        if(login == null) {\n            String msg = \"OAuth response did not contain the user email\";\n            log.error(msg);\n            throw new UsernameNotFoundException(msg);\n        }\n\n        if(!login.contains(\"@\")) {\n            log.debug(\"User login {} from OAuth response is incorrect.\", login);\n            throw new UsernameNotFoundException(\"OAuth response did not contains a valid user email\");\n        }\n\n        UserDetails userDetails;\n        try {\n            userDetails = userDetailsService.loadUserByUsername(login);\n            domainRepository.updateUserInDomain(DomainUtil.getDomainFromLogin(login), login);\n        } catch (UsernameNotFoundException e) {\n            log.info(\"User with login : \\\"{}\\\" doesn't exist yet in Tatami database - creating it...\", login);\n            userDetails = getNewlyCreatedUserDetails(user);\n        }\n        return userDetails;\n    }\n\n    private UserDetails getNewlyCreatedUserDetails(Person user) {\n        String login = user.getEmails().get(0).getValue();\n        String firstName = user.getName().getGivenName();\n        String lastName = user.getName().getFamilyName();\n\n        User createdUser = new User();\n\n        createdUser.setLogin(login);\n        createdUser.setFirstName(firstName);\n        createdUser.setLastName(lastName);\n\n        userService.createUser(createdUser);\n        return userDetailsService.loadUserByUsername(createdUser.getLogin());\n    }\n}\n"
  },
  {
    "path": "web/src/main/webapp/.bowerrc",
    "content": "{\n  \"directory\" : \"assets/bower_components\"\n}"
  },
  {
    "path": "web/src/main/webapp/WEB-INF/messages/messages_en.properties",
    "content": "tatami.copyright=Copyright 2012\ntatami.ippon.technologies=Ippon Technologies\ntatami.github.fork=Fork Tatami on Github\ntatami.github.issues=Submit a bug\ntatami.ippon.website=Ippon Technologies Website\ntatami.ippon.blog=Ippon Technologies Blog\ntatami.ippon.twitter.follow=Follow @ippontech on Twitter\ntatami.title=Tatami\ntatami.profile=Profile\ntatami.home=Home\ntatami.menu.about=About\ntatami.menu.presentation=Presentation\ntatami.menu.tos=Terms of service\ntatami.menu.language=Language\ntatami.menu.language.en=English\ntatami.menu.language.fr=Francais\ntatami.menu.license=Source code license\ntatami.search.placeholder=Search\ntatami.search.button=Search\ntatami.search.filter=Enter your search\ntatami.logout=Logout\ntatami.login=E-mail\ntatami.username=User name\ntatami.password=Password\ntatami.404=Page not found.\ntatami.500=An error has occurred.\ntatami.file.not.found=The requested file does not exist. It was probably deleted by its owner.\ntatami.form.success=The form has been successfully saved.\ntatami.form.error=Failed to saved form.\n\ntatami.login.modal.timeout.title=Warning\ntatami.login.modal.timeout.message=You were disconnected. Sign in again to use Tatami.\ntatami.login.modal.timeout.close=Close\n\ntatami.register.title=You don't have an account (yet)\ntatami.register.text.1=To create an account in Tatami, please register your e-mail address.\ntatami.register.text.2=A confirmation message will be sent to the e-mail address you provided.\ntatami.register.text.3=Depending on your e-mail address' domain name, you will join your company's private space. For example, users with an email@ippon.fr address will join Ippon's private space\ntatami.register.text.4=If you are the first employee of your company to join Tatami, your company's private space will be automatically created.\ntatami.register=Register\ntatami.register.msg=Thank you! A registration e-mail has been sent to you.\ntatami.register.msg.error=This e-mail address is already in used by a Tatami user.\ntatami.register.validation.title=E-mail validation\ntatami.register.validation.error=You e-mail could not be validated. Please use the registration form to register your e-mail.\ntatami.register.validation.ok=Your e-mail has been validated. Your password will be e-mailed to you.\ntatami.register.home=Go to the home page\n\ntatami.lost.password.title=Have you forgotten your password?\ntatami.lost.password.button=Ask for a new password\ntatami.lost.password.msg=An e-mail has been sent to you, with instructions to generate a new password.\ntatami.lost.password.msg.error=This e-mail address is not registered in Tatami.\ntatami.ldap.password.msg.error=This account is managed by your LDAP server, you cannot generate a new password with Tatami.\n\ntatami.authentification=You already have an account\ntatami.authentificate=Authenticate\ntatami.authentification.error=Your authentication has failed! Are you sure you used the correct password?\ntatami.authentication.google.title=Google Apps authentication\ntatami.authentication.google.desc.1=This feature is for enterprise Google Apps users, who have their enterprise domain name managed by Google Apps. For more information on Google Apps, follow this link :\ntatami.authentication.google.desc.2=Whether or not you already have a Tatami account, you can sign in with your Google Apps account.\ntatami.authentication.google.desc.3=Your email will be provided by Google and your domain name will be used to make you join the corresponding private space.\ntatami.authentication.google.submit=Authentication with Google Apps\ntatami.authentication.cgv=Terms of Service\ntatami.remember.password.time=Remember me\ntatami.cg=Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\ntatami.license.text=Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this application except in compliance with the License. You may obtain a copy of the License at\ntatami.license=Source Code License\ntatami.presentation=Welcome to Tatami, an Open Source enterprise social network\ntatami.presentation.moreinfo=See a detailed presentation of Tatami\ntatami.status.update=Update your status\ntatami.status.editor=Edit\ntatami.status.preview=Preview\ntatami.status.update.to=Send a status update\ntatami.status.private=Private message\ntatami.status.geoLocalization=Geolocalization\ntatami.status.update.drop.file=Drop your files here\ntatami.status.reply=Reply to this status\ntatami.status.reply.action=Reply\ntatami.user.favoritestatus=Favorites\ntatami.mentions=Mentions\ntatami.tags=Tags\ntatami.tag=Tag\ntatami.search=Search\ntatami.who.is.online.title=Who is online?\ntatami.find.title=Find a user\ntatami.find.username=Username\ntatami.find.action=Find\ntatami.follow.suggestions=Who to follow?\ntatami.follow.nobody=No new user to follow today.\ntatami.statistics=Statistics\ntatami.user.informations=Informations\ntatami.trends.title=Trends\ntatami.trends.user.title=User trends\n\ntatami.new.status=Update\ntatami.status.characters.left=Characters left:\ntatami.status.update.success=Your status has been updated!\ntatami.status.help.title=Help\ntatami.status.help=<ul><li>You can use <b>#tags</b> by adding a <b>#</b> before a keyword</li><li>To mention a user, use his <b>@username</b></li><li>To write rich content, you can use the <a href='http://en.wikipedia.org/wiki/Markdown' target='_blank'>MarkDown</a> syntax, for example *text* to have a text in <i>italic</i> or **text** to have a text in <b>bold</b>.</li><li>If you write a link like http://www.ippon.fr, it will be automatically clickable</li><li>If you add a link to YouTube, Dailymotion or Vimeo, the online video will be automatically displayed</li><li>If you add a link to a <a href='https://gist.github.com/' target='_blank'>Gist</a>, its source code will be automatically displayed</li></ul>\ntatami.timeline=Timeline\n\ntatami.user.picture=Photo\ntatami.user.picture.button=Drop your photo here to update it\ntatami.user.picture.buttonIE=Select a photo to update your profile\ntatami.user.picture.buttonIE-ok=Photo updated!\ntatami.user.upload.buttonIE-ok=Select files to attach to your Tatam.\ntatami.user.upload.buttonIE-ko=An error occurred. Free some space in your account and try again.\ntatami.user.upload.choose=Choose a file\ntatami.user.email=E-mail\ntatami.user.firstName=First name\ntatami.user.lastName=Last name\ntatami.user.jobTitle=Job title\ntatami.user.phoneNumber=Phone number\ntatami.user.follow=Follow\ntatami.user.followed=Followed\ntatami.user.follows.you=follows you\ntatami.badge.status=Status\ntatami.badge.followed=Followed\ntatami.badge.followers=Followers\ntatami.user.undefined=User undefined.\ntatami.user.send=Send\ntatami.user.status=Status\ntatami.user=User\n\ntatami.user.file.name=Filename\ntatami.user.file.size=Size\ntatami.user.file.creation.date=Date\ntatami.user.file.preview=Preview\ntatami.user.file.delete.success=Your file has been deleted\ntatami.user.file.delete.error=Failed to delete your file\n\ntatami.menu.search=Search...\ntatami.menu.account=Account\ntatami.menu.profile=Profile\ntatami.menu.groups=Groups\ntatami.menu.password=Password\ntatami.menu.files=Files\ntatami.menu.directory=Users\ntatami.menu.tags=Tags\ntatami.menu.status.of.the.day=Statuses of the day\ntatami.menu.company.wall=Company wall\ntatami.menu.preferences=Preferences\ntatami.menu.groups.directory=Groups directory\n\ntatami.form.previous=Previous\ntatami.form.next=Next\ntatami.form.save=Save\ntatami.form.cancel=Cancel\ntatami.form.finish=Finish\n\ntatami.account.update.title=User profile\ntatami.account.update.legend=Update your profile\ntatami.user.update.success=Your profile has been successfully updated.\ntatami.user.update.error=An error has occurred!\ntatami.user.suppress=Delete the current user account\ntatami.user.suppress.confirmation=You are about to delete your account. Are you sure?\ntatami.user.password.legend=Update your password\ntatami.user.password.ldap=Your password is managed by an LDAP server, you cannot update it with Tatami.\ntatami.user.password.success=Your password has been successfully updated.\ntatami.user.old.password=Old password\ntatami.user.old.password.error=The old password is incorrect.\ntatami.user.new.password=New password\ntatami.user.new.password.confirmation=New password confirmation\ntatami.user.new.password.confirmation.error=The new password confirmation is incorrect\n\ntatami.preferences.notifications=Notifications\ntatami.preferences.notifications.email.mention=Get notified by e-mail when you are mentioned\ntatami.preferences.notifications.email.dailyDigest=Get a daily digest e-mail\ntatami.preferences.notifications.email.weeklyDigest=Get a weekly digest e-mail\ntatami.preferences.notifications.rss.timeline=Allow RSS feed publication of your timeline\ntatami.preferences.success=Your preferences have been saved\n\ntatami.user.profile.show=Show profile of\ntatami.user.profile.yourProfil=Your profile\ntatami.user.status.show=View\ntatami.user.status.details=Details\ntatami.user.status.reply=Reply\ntatami.user.status.share=Share\ntatami.user.status.share.success=Status successfully shared!\ntatami.user.status.favorite=Favorite\ntatami.user.status.delete=Delete\ntatami.user.status.announce=Announce\ntatami.user.status.replyto=In reply to\ntatami.user.status.shared.by=Shared by\ntatami.user.status.announced.by=Announced by\ntatami.user.shared.you=has shared your status\ntatami.user.followed.you=has followed you\ntatami.user.profile.edit=Edit my profile\ntatami.user.search.searchInStatus=Statuses with\ntatami.user.activate=Activate\ntatami.user.desactivate=Deactivate\ntatami.user.desactivate.msg=This user is deactivated\ntatami.user.desactivate.msg2= ( Deactivated user )\n\ntatami.timeline.refresh=Refresh\ntatami.timeline.message=New message\ntatami.timeline.messages=New messages\ntatami.timeline.next=More\n\ntatami.timeline.shares=Shared by\n\ntatami.user.status.confirm.announce=Are you sure you want to send this status to everyone?\ntatami.user.status.confirm.delete=Are you sure you want to delete this status?\n\ntatami.group.name=Group\ntatami.group.counter=Members\ntatami.group.add=Create a new group\ntatami.group.add.title=Name of the group\ntatami.group.add.description=Description\ntatami.group.add.access=Access\ntatami.group.add.public=Public\ntatami.group.add.private=Private\ntatami.group.add.archived=Archived\ntatami.group.add.public.alert=Warning! If this group is public, everybody can access it\ntatami.group.add.success=Group created successfully\ntatami.group.archive=Do you want to archive this group?\ntatami.group.archive.true=Yes, this group should be archived\ntatami.group.archive.false=No, this group is still in use\ntatami.group.archive.alert=Archived groups are read-only\ntatami.group.list=Your groups\ntatami.group.edit.link=Manage\ntatami.group.edit.quit=Quit\ntatami.group.edit.success=Group updated successfully\ntatami.group.edit.list=Group members\ntatami.group.join.group=Join\ntatami.group.edit.details=Update group details\ntatami.group.edit.member.add.success=User successfully added\ntatami.group.edit.member.add.error=User could not be added!\ntatami.group.edit.member.remove.success=User successfully removed\ntatami.group.edit.member.add.no.user=You must enter a user name\ntatami.group.edit.member.add.wrong.user=This user name does not exist\ntatami.group.edit.member.add=Add a member\ntatami.group.edit.member.delete=Remove\ntatami.group.role=Role\ntatami.group.role.admin=Administrator\ntatami.group.role.member=Member\ntatami.group.select=Select a group on the \"Groups\" menu on the left\ntatami.group.members.list=Members list\n\ntatami.presentation.title=What is Tatami?\n\ntatami.presentation.row1.title=A private, enterprise social network\ntatami.presentation.row1.1=Update your status to inform your co-workers\ntatami.presentation.row1.2=Subscribe to other employees' time lines\ntatami.presentation.row1.3=Share important information to your followers\ntatami.presentation.row1.4=Discuss and reply to your colleagues\ntatami.presentation.row1.5=Put important information into favorites\ntatami.presentation.row1.6=Search useful information with our integrated search engine\ntatami.presentation.row1.7=Use hashtags to find related information\ntatami.presentation.row1.8=Go to your co-workers' profiles to see what they are working on\ntatami.presentation.row1.9=English and French versions available, adding other languages is easy\n\ntatami.presentation.row2.title=Works on all devices!\ntatami.presentation.row2.1=Dynamic Web application (HTML5) : nothing to install, excepted a modern browser!\ntatami.presentation.row2.2=Works on mobile devices, tablets, or standard computers : the application adapts itself automatically to your device's screen\ntatami.presentation.row2.3=Stay connected with your enterprise wherever you are\n\ntatami.presentation.row3.title=Easy installation and integration with your company's IT infrastructure\ntatami.presentation.row3.1=Standard Java application\ntatami.presentation.row3.2=Your data belongs to you, not to your SaaS vendor!\ntatami.presentation.row3.3=Integrates with your LDAP directory\ntatami.presentation.row3.4=Integrates with Google Apps\ntatami.presentation.row3.5=Fully Open Source, with a business-friendly Apache 2 license\ntatami.presentation.row3.6=Easy to extend or modify according to your needs\ntatami.presentation.row3.7=High performance (based on Apache Cassandra), even on small hardware\ntatami.presentation.row3.8=Join the project and submit patches on our Github page:\n\ntatami.presentation.row4.title=Also available in SaaS mode, fully managed by Ippon Technologies\ntatami.presentation.row4.1=If you do not want to install Tatami in your company, it's easy to use directly\ntatami.presentation.row4.2=Secured multi-enterprise mode: every company has its own private space\ntatami.presentation.row4.3=256 bits SSL cryptography: all data transfers are fully secured\n\ntatami.presentation.row5.title=Need more information on our product?\ntatami.presentation.row5.1=Our sales team is looking forward to hearing from you! Call us at +33 01 46 12 48 48 or e-mail us at\n\ntatami.account.users.myfriends=My friends\ntatami.account.users.recommended=Recommended\ntatami.account.users.all=Users\ntatami.account.groups.mygroups=My groups\ntatami.account.groups.recommended=Recommended\ntatami.account.tags.mytags=My tags\ntatami.account.tags.recommended=Recommended\n\ntatami.rss.timeline.title=Timeline for user {0}\ntatami.rss.timeline.description=Tatami timeline for user {0}\ntatami.preferences.notifications.rss.timeline.link=Link to your timeline RSS stream\ntatami.logo=Ippon Technologies Logo\n\ntatami.welcome.title=Welcome to Tatami\ntatami.welcome.description=Your timeline is empty! Do you need help to learn how to use Tatami? Please click on the button below to launch a presentation.\ntatami.welcome.launch=Launch presentation\n\ntatami.help=Help\ntatami.help.end=End\ntatami.help.next=Next &raquo;\ntatami.help.previous=&laquo; Prev\n\ntatami.help.home.presentation.title=<b>Help</b>\ntatami.help.home.presentation.content=Welcome to the online help!<br/><p>Follow the next steps for a tour of the main Tatami features.</p>\n\ntatami.help.home.timeline.title=<b>Timeline</b>\ntatami.help.home.timeline.content=This is your timeline. It displays all messages \\\n  <ul>\\\n  <li>mentioning you or sent privately to you</li>\\\n  <li>sent by users you follow</li>\\\n  <li>sent by yourself</li>\\\n  <li>sent to group you are subscribed to</li></ul> \\\n  <p>If it's empty, don't worry, it will get updated as soon as you start following other users!</p>\\\n  <p>When viewing a message, you can reply to it and mark it as favorite to find it easily later.</p>\\\n  <p>If a message had already got some replies, you can see them all by clicking on details: this makes it easier to follow conversation on Tatami.</p>\n\ntatami.help.home.updatestatus.title=<b>Sending messages</b>\ntatami.help.home.updatestatus.content=Here is where you write messages you want to share \\\n  <ul><li>all messages are public by default. They will be delivered to all users who follow you </li> \\\n  <li>when writing a message you should use <i>#hashtags</i>: this simply means adding a \\'#\\' at the beginning of important words that can be used to find your message </li> \\\n  <li>when mentioning, or replying to, other users, you should add a @ at the beginning of their name : they will be notified that you are talking to them </li> \\\n  </ul>\n\ntatami.help.home.groups.title=<b>Groups</b>\ntatami.help.home.groups.content=This is the list of groups you are a member of. \\\n  <p>You can find, and subscribe to, public group in the Account/Groups page (top-right menu).</p>\\\n  <p>There are also private groups : for these you cannot subscribe : the owner of the group must add you as a member.</p>\n\ntatami.help.home.follow-suggest.title=<b>Suggested users</b>\ntatami.help.home.follow-suggest.content=<p>This is a list of users who share common interests with you and who you could follow.</p>\\\n  <p>If you are a new user, this list is probably empty: Tatami needs some time to learn who you are in order to suggest you relevant users.</p>\\\n  <p>And don't forget to use #hashtags in your messages, it makes everything easier!</p>\n\ntatami.help.home.profileTrends.title=<b>Trends</b>\ntatami.help.home.profileTrends.content=<p>This list represents the #hashtag that are currently the most often used on Tatami. Use this to discover what's going on and what are the hottest topics on Tatami !</p>\ntatami.tatam.publish=Publish\ntatami.status.options=Options\ntatami.tatam.mandatory=Comment is mandatory\n"
  },
  {
    "path": "web/src/main/webapp/WEB-INF/messages/messages_fr.properties",
    "content": "tatami.copyright=Copyright 2012t\ntatami.ippon.technologies=Ippon Technologies\ntatami.github.fork=Forker Tatami sur Github\ntatami.github.issues=Signaler un bug\ntatami.ippon.website=Site Web d'Ippon Technologies\ntatami.ippon.blog=Blog d'Ippon Technologies\ntatami.ippon.twitter.follow=Suivre @ippontech sur Twitter\ntatami.title=Tatami\ntatami.profile=Profil\ntatami.home=Accueil\ntatami.menu.about=A Propos\ntatami.menu.presentation=Présentation\ntatami.menu.tos=Conditions générales de vente\ntatami.menu.language=Langue\ntatami.menu.language.en=English\ntatami.menu.language.fr=Français\ntatami.menu.license=Licence du code source\ntatami.search.placeholder=Rechercher\ntatami.search.button=Rechercher\ntatami.search.filter=Entrez votre recherche\ntatami.logout=Déconnexion\ntatami.login=E-mail\ntatami.username=Nom d'utilisateur\ntatami.password=Mot de Passe\ntatami.404=Page non trouvée.\ntatami.500=Une erreur s'est produite.\ntatami.file.not.found=Le fichier demandé n'existe pas. Il a probablement été supprimé par son propriétaire.\ntatami.form.success=Le formulaire a été correctement enregistré.\ntatami.form.error=Une erreur s'est produite lors de l'enregistrement du formulaire.\n\ntatami.login.modal.timeout.title=Attention\ntatami.login.modal.timeout.message=Vous avez été déconnecté. Vous devez vous identifier à nouveau pour accéder à Tatami\ntatami.login.modal.timeout.close=Fermer\n\ntatami.register.title=Vous n'avez pas (encore) de compte\ntatami.register.text.1=Pour créer votre compte Tatami, merci de renseigner votre adresse e-mail.\ntatami.register.text.2=Un message de confirmation sera envoyé à l'adresse e-mail que vous avez fournie.\ntatami.register.text.3=En fonction du nom de domaine de votre adresse e-mail, vous rejoindrez alors l'espace privé de votre entreprise. Par exemple, les utilisateurs avec une adresse de type email@ippon.fr rejoindront l'espace privé d'Ippon Technologies.\ntatami.register.text.4=Si vous êtes le premier employé de votre société à rejoindre Tatami, un espace privé pour votre société sera automatiquement créé.\ntatami.register=Enregistrement\ntatami.register.msg=Merci ! Un e-mail d'inscription vient de vous être envoyé.\ntatami.register.msg.error=Cette adresse e-mail est déjà utilisée par un utilisateur de Tatami.\ntatami.register.validation.title=Validation de votre adresse e-mail\ntatami.register.validation.error=Votre adresse e-mail n'a pas pu être validée. Merci d'utiliser à nouveau notre formulaire d'enregistrement.\ntatami.register.validation.ok=Votre adresse e-mail a été validée. Vous allez recevoir votre mot de passe par e-mail.\ntatami.register.home=Aller à la page d'accueil\n\ntatami.lost.password.title=Vous avez oublié votre mot de passe ?\ntatami.lost.password.button=Demander un nouveau mot de passe\ntatami.lost.password.msg=Un e-mail vous a été envoyé, vous expliquant comment réinitialiser votre mot de passe.\ntatami.lost.password.msg.error=Cette adresse e-mail n'est pas enregistrée dans Tatami.\ntatami.ldap.password.msg.error=Ce compte est géré via votre annuaire LDAP, vous ne pouvez pas réinitialiser votre mot de passe avec Tatami.\n\ntatami.authentification=Vous avez déjà un compte\ntatami.authentificate=Se Connecter\ntatami.authentification.error=Votre authentification a échoué ! Votre mot de passe est-il correct ?\ntatami.authentication.google.title=Authentification Google Apps\ntatami.authentication.google.desc.1=Cette fonctionnalité concerne les utilisateurs professionnels de Google Apps, et qui ont le nom de domaine de leur société associé à leur compte Google Apps. Pour plus d'informations sur Google Apps, suivez ce lien :\ntatami.authentication.google.desc.2=Que vous ayez déjà un compte Tatami ou non, vous pouvez vous connecter avec votre compte Google Apps.\ntatami.authentication.google.desc.3=Votre email sera demandé à Google et votre nom de domaine sera utilisé pour vous faire rejoindre l'espace privé correspondant.\ntatami.authentication.google.submit=Connexion avec Google Apps\ntatami.authentication.cgv=Conditions générales de vente\ntatami.remember.password.time=Se souvenir de moi\ntatami.cg=Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.\ntatami.license.text=Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this application except in compliance with the License. You may obtain a copy of the License at\ntatami.license=Licence du code source\ntatami.presentation=Bienvenue sur Tatami, un réseau social d'entreprise Open Source\ntatami.presentation.moreinfo=Voir une présentation détaillée de Tatami\ntatami.status.update=Mettre à jour votre statut\ntatami.status.editor=Edition\ntatami.status.preview=Prévisualisation\ntatami.status.update.to=Envoyer une mise à jour du statut\ntatami.status.private=Message privé\ntatami.status.geoLocalization=Géolocaliser\ntatami.status.update.drop.file=Déposez vos fichiers ici\ntatami.status.reply=Répondre à ce statut\ntatami.status.reply.action=Répondre\ntatami.user.favoritestatus=Favoris\ntatami.mentions=Mentions\ntatami.tags=Tags\ntatami.tag=Tag\ntatami.search=Recherche\ntatami.who.is.online.title=Qui est en ligne ?\ntatami.find.title=Chercher un utilisateur\ntatami.find.username=Identifiant utilisateur\ntatami.find.action=Chercher\ntatami.follow.suggestions=Qui suivre ?\ntatami.follow.nobody=Personne à suivre aujourd'hui.\ntatami.statistics=Statistiques\ntatami.user.informations=Informations\ntatami.trends.title=Tendances\ntatami.trends.user.title=Tendances pour l'utilisateur\n\ntatami.new.status=Nouveau\ntatami.status.characters.left=Caractères restants :\ntatami.status.update.success=Votre statut a été mis à jour !  \ntatami.status.help.title=Aide\ntatami.status.help=<ul><li>Vous pouvez utiliser des <b>#tags</b> en ajoutant un <b>#</b> devant un mot-clef</li><li>Pour mentionner un utilisateur, utilisez son <b>@nom_utilisateur</b></li><li>Pour enrichir votre texte, vous pouvez utiliser la syntaxe <a href='http://fr.wikipedia.org/wiki/Markdown' target='_blank'>MarkDown</a>, par exemple *texte* pour écrire en <i>italique</i> ou **texte** pour écrire en <b>gras</b>.</li><li>Si vous écrivez un lien de type http://www.ippon.fr, il sera automatiquement cliquable</li><li>Si vous ajoutez un lien provenant de YouTube, Dailymotion ou Vimeo, la vidéo en ligne sera automatiquement insérée</li><li>Si vous ajoutez un lien pointant vers un <a href='https://gist.github.com/' target='_blank'>Gist</a>, le code source sera automatiquement affiché</li></ul>\ntatami.timeline=Actualité\n\ntatami.user.picture=Photo\ntatami.user.picture.button=Déposez votre photo dans le cadre pour la mettre à jour\ntatami.user.picture.buttonIE=Sélectionnez une photo pour mettre à jour votre profil.\ntatami.user.picture.buttonIE-ok=Photo mise à jour correctement.\ntatami.user.upload.buttonIE-ok=Sélectionnez des fichiers à ajouter à votre message.\ntatami.user.upload.buttonIE-ko=Une erreur s'est produite, pensez à supprimer des anciens fichiers dans votre compte.\ntatami.user.upload.choose=Choisir un fichier\ntatami.user.email=E-mail\ntatami.user.firstName=Prénom\ntatami.user.lastName=Nom\ntatami.user.jobTitle=Fonction\ntatami.user.phoneNumber=Numéro de téléphone\ntatami.user.follow=Suivre\ntatami.user.followed=Abonné\ntatami.user.follows.you=vous suit\ntatami.badge.status=Statuts\ntatami.badge.followed=Abonnements\ntatami.badge.followers=Abonnés\ntatami.user.undefined=Utilisateur inconnu.\ntatami.user.send=Envoi\ntatami.user.status=Statut\ntatami.user=Utilisateurs\n\ntatami.user.file.name=Nom du fichier\ntatami.user.file.size=Taille\ntatami.user.file.creation.date=Date\ntatami.user.file.preview=Aperçu\ntatami.user.file.delete.success=Votre fichier a été supprimé\ntatami.user.file.delete.error=Votre fichier n'a pas été supprimé\n\ntatami.menu.search=Recherche...\ntatami.menu.account=Compte\ntatami.menu.profile=Profil\ntatami.menu.groups=Groupes\ntatami.menu.password=Mot de passe\ntatami.menu.files=Fichiers\ntatami.menu.directory=Utilisateurs\ntatami.menu.tags=Tags\ntatami.menu.status.of.the.day=Messages du jour\ntatami.menu.company.wall=Mur de l'entreprise\ntatami.menu.preferences=Préférences\ntatami.menu.groups.directory=Annuaire des groupes\n\ntatami.form.previous=Précédent\ntatami.form.next=Suivant\ntatami.form.save=Sauvegarder\ntatami.form.cancel=Annuler\ntatami.form.finish=Fin\n\ntatami.account.update.title=Profil utilisateur\ntatami.account.update.legend=Mise à jour du profil\ntatami.user.update.success=Votre profil a été mis à jour.\ntatami.user.update.error=Une erreur s'est produite !\ntatami.user.suppress=Destruction du compte utilisateur\ntatami.user.suppress.confirmation=Etes-vous sûr de vouloir détruire votre compte ?\ntatami.user.password.legend=Mise à jour de votre mot de passe\ntatami.user.password.ldap=Votre mot de passe est géré par LDAP, vous ne pouvez pas le modifier via Tatami.\ntatami.user.password.success=Votre mot de passe a été mis à jour.\ntatami.user.old.password=Ancien mot de passe\ntatami.user.old.password.error=Ancien mot de passe incorrect\ntatami.user.new.password=Nouveau mot de passe\ntatami.user.new.password.confirmation.error=La confirmation du nouveau mot de passe est incorrecte\ntatami.user.new.password.confirmation=Confirmation du mot de passe\n\ntatami.preferences.notifications=Notifications\ntatami.preferences.notifications.email.mention=Recevoir un e-mail lorsqu'on vous mentionne\ntatami.preferences.notifications.email.dailyDigest=Recevoir un résumé quotidien de votre actualité\ntatami.preferences.notifications.email.weeklyDigest=Recevoir un résumé hebdomadaire de votre actualité\ntatami.preferences.notifications.rss.timeline=Autoriser la publication d'un flux RSS de votre actualité\ntatami.preferences.success=Vos préférences ont été sauvegardées\n\ntatami.user.profile.show=Profil de\ntatami.user.profile.yourProfil=Votre profil\ntatami.user.status.show=Voir\ntatami.user.status.details=Détails\ntatami.user.status.reply=Répondre\ntatami.user.status.share=Partager\ntatami.user.status.share.success=Message partagé !\ntatami.user.status.favorite=Favori\ntatami.user.status.delete=Supprimer\ntatami.user.status.announce=Annoncer\ntatami.user.status.replyto=En réponse à\ntatami.user.status.shared.by=Partagé par\ntatami.user.status.announced.by=Annoncé par\ntatami.user.shared.you=a partagé votre message\ntatami.user.followed.you=vous a suivi\ntatami.user.profile.edit=Editer mon profil\ntatami.user.search.searchInStatus=Messages contenant\ntatami.user.activate=Activer\ntatami.user.desactivate=Désactiver\ntatami.user.desactivate.msg=Cet utilisateur est désactivé\ntatami.user.desactivate.msg2= ( Utilisateur désactivé )\n\ntatami.timeline.refresh=Rafraîchir\ntatami.timeline.message=Nouveau message\ntatami.timeline.messages=Nouveaux messages\ntatami.timeline.next=Plus\n\ntatami.timeline.shares=Partagé par\n\ntatami.user.status.confirm.announce=Etes-vous certain de vouloir envoyer ce message à tout le monde ?\ntatami.user.status.confirm.delete=Etes-vous certain de vouloir supprimer ce message ?\n\ntatami.group.name=Groupe\ntatami.group.counter=Membres\ntatami.group.add=Créer un nouveau groupe\ntatami.group.add.title=Nom du groupe\ntatami.group.add.description=Description\ntatami.group.add.access=Accès\ntatami.group.add.public=Public\ntatami.group.add.private=Privé\ntatami.group.add.archived=Archivé\ntatami.group.add.public.alert=Attention ! Si ce groupe est public, tout le monde y aura accès\ntatami.group.add.success=Groupe créé avec succès\ntatami.group.archive=Voulez-vous archiver ce groupe ?\ntatami.group.archive.true=Oui, ce groupe doit être archivé\ntatami.group.archive.false=Non, ce groupe est toujours utilisé\ntatami.group.archive.alert=Les groupes archivés sont en lecture seule\ntatami.group.list=Vos groupes\ntatami.group.edit.link=Gestion\ntatami.group.edit.quit=Quitter\ntatami.group.join.group=Rejoindre\ntatami.group.edit.success=Groupe mis à jour avec succès\ntatami.group.edit.details=Modifier les détails du groupe\ntatami.group.edit.list=Liste des membres\ntatami.group.edit.member.add.success=Utilisateur ajouté avec succès\ntatami.group.edit.member.add.error=L'utilisateur n'a pas pu être ajouté !\ntatami.group.edit.member.remove.success=L'utilisateur ne fait plus partie du groupe\ntatami.group.edit.member.add.no.user=Vous devez entrer le nom d'un utilisateur\ntatami.group.edit.member.add.wrong.user=Cet utilisateur n'existe pas\ntatami.group.edit.member.add=Ajouter un membre\ntatami.group.edit.member.delete=Enlever\ntatami.group.role=Role\ntatami.group.role.admin=Administrateur\ntatami.group.role.member=Membre\ntatami.group.select=Sélectionnez un groupe dans le menu \"Groupes\" à gauche\ntatami.group.members.list=Liste des membres\n\ntatami.presentation.title=Qu'est-ce que Tatami ?\n\ntatami.presentation.row1.title=Un réseau social d'entreprise privé\ntatami.presentation.row1.1=Mettre à jour votre statut pour que vos collègues soient informés\ntatami.presentation.row1.2=S'abonner aux fils d'information de vos collègues\ntatami.presentation.row1.3=Renvoyer les informations importantes aux personnes qui vous suivent\ntatami.presentation.row1.4=Discuter et répondre à vos collègues\ntatami.presentation.row1.5=Mettre en favori les informations essentielles\ntatami.presentation.row1.6=Rechercher l'information utile grâce à notre moteur de recherche intégré\ntatami.presentation.row1.7=Utiliser des hashtags pour découvrir des informations connexes\ntatami.presentation.row1.8=Aller sur les profils de vos collègues pour voir ce sur quoi ils travaillent\ntatami.presentation.row1.9=Versions Française et Anglaise disponibles, de nouvelles langues sont simples à ajouter\n\ntatami.presentation.row2.title=Fonctionne partout !\ntatami.presentation.row2.1=Application Web entièrement dynamique (HTML5) : rien à installer, à part un navigateur Web moderne !\ntatami.presentation.row2.2=Fonctionne sur tout support : mobile, tablette, ou PC \"classique\", l'application s'adapte automatiquement à l'écran\ntatami.presentation.row2.3=Restez connecté à votre entreprise où que vous soyez\n\ntatami.presentation.row3.title=S'installe facilement et s'intègre sans problème dans votre SI\ntatami.presentation.row3.1=Application Java standard\ntatami.presentation.row3.2=Contrairement aux solutions SaaS, vos données vous appartiennent entièrement !\ntatami.presentation.row3.3=S'intègre avec votre serveur LDAP\ntatami.presentation.row3.4=S'intègre avec Google Apps\ntatami.presentation.row3.5=Entièrement Open Source, sous licence Apache 2 (dite \"business friendly\")\ntatami.presentation.row3.6=Simple à étendre ou à modifier en fonction de vos besoins\ntatami.presentation.row3.7=Peu gourmande en ressources et très performante (basée sur Apache Cassandra)\ntatami.presentation.row3.8=Participez au développement et proposez des corrections via notre page Github :\n\ntatami.presentation.row4.title=Disponible également en version hébergée, entièrement gérée par Ippon Technologies\ntatami.presentation.row4.1=Si vous ne voulez pas installer Tatami chez vous, rien de plus simple que d'utiliser directement\ntatami.presentation.row4.2=Mode multi-entreprise sécurisé : chaque entreprise dispose de son propre espace\ntatami.presentation.row4.3=Chiffrage SSL fort (256 bits) en standard : tous les transferts de données sont sécurisés\n\ntatami.presentation.row5.title=Une question ?\ntatami.presentation.row5.1=Notre équipe commerciale reste à votre écoute - Téléphonez-nous au 01 46 12 48 48 ou envoyez-nous un e-mail à\n\ntatami.account.users.myfriends=Mes amis\ntatami.account.users.recommended=Recommandés\ntatami.account.users.all=Utilisateurs\ntatami.account.groups.mygroups=Mes groupes\ntatami.account.groups.recommended=Recommandés\ntatami.account.tags.mytags=Mes tags\ntatami.account.tags.recommended=Recommandés\n\ntatami.rss.timeline.title=Actualité de {0}\ntatami.rss.timeline.description=Actualité Tatami de {0}\ntatami.preferences.notifications.rss.timeline.link=Lien vers le flux RSS de votre actualité\ntatami.logo=Ippon Technologies\n\ntatami.welcome.title=Bienvenue sur Tatami\ntatami.welcome.description=Votre actualité est vide ! Avez-vous besoin d'aide pour apprendre à utiliser Tatami ? Si oui, cliquez sur le bouton pour lancer la présentation.\ntatami.welcome.launch=Lancer la présentation\n\ntatami.help=Aide\ntatami.help.end=Terminer\ntatami.help.next=Suivant &raquo;\ntatami.help.previous=&laquo; Précédent\n\ntatami.help.home.presentation.title=<b>Aide</b>\ntatami.help.home.presentation.content=Bienvenue dans l'aide !<br/><p>Nous allons vous guider à travers les principales fonctionnalités de Tatami.</p>\n\ntatami.help.home.timeline.title=<b>Actualité</b>\ntatami.help.home.timeline.content=Cette zone représente votre actualité. Elle contient tous les messages\\\n  <ul>\\\n  <li>que vous avez postés vous-même,</li>\\\n  <li>dans lesquels vous êtes cité, ou qui vous ont été envoyés en privé,</li>\\\n  <li>postés par les utilisateurs que vous suivez,</li>\\\n  <li>postés dans un groupe dont vous faites partie.</li></ul> \\\n  <p>Ne vous inquiétez pas si cette liste est vide, elle se remplira dès que vous aurez commencé à suivre d'autres utilisateurs !</p>\\\n  <p>Pour chacun des messages de cette liste, vous pouvez répondre et le marquer comme favori, afin de le retouver facilement plus tard.</p>\\\n  <p>Si un message a déjà eu des réponses, vous pouvez toutes les afficher en cliquant sur \\'<i class=\\'icon-search\\'></i>Détails' : cela permet de suivre facilement des conversations sur Tatami.</p>\n\ntatami.help.home.updatestatus.title=<b>Poster des messages</b>\ntatami.help.home.updatestatus.content=C'est ici que vous rédigez les messages que vous voulez poster \\\n  <ul><li>tous les messages sont publics par défaut. Ils seront envoyés à tous les utilisateurs qui vous suivent,</li> \\\n  <li>quand vous rédigez un message, il est conseillé d'utiliser des <i>#hashtags</i> : il s'agit simplement d'ajouter le caractère \\'#\\' au début des mots importants qui pourront être utilisés pour retrouver votre message, </li> \\\n  <li>lorsque vous mentionnez un utilisateur ou que vous répondez à quelqu'un, il faut faire précéder son nom du symbol \\'@\\' : il sera ainsi notifié que quelqu'un lui parle.</li> \\\n  </ul>\n\ntatami.help.home.groups.title=<b>Groupes</b>\ntatami.help.home.groups.content=Voici la liste des groupes dont vous faites partie. \\\n  <p>Vous pouvez trouver la liste des groupes publics auxquels vous inscrire dans la page <i>\\'Compte/Groupe\\'</i> (dans le menu en haut à droite).</p>\\\n  <p>Il existe aussi des groupes privés : vous ne pouvez pas vous y inscrire vous même, seul le propriétaire d'un groupe privé peut vous déclarer comme membre de ce groupe.</p>\\\n\ntatami.help.home.follow-suggest.title=<b>Utilisateurs suggérés</b>\ntatami.help.home.follow-suggest.content=<p>Cette liste vous propose des utilisateurs qui partagent les mêmes centres d'intérêts que vous et que vous pourriez éventuellement suivre.</p>\\\n  <p>Si vous êtes un nouvel utilisateur, cette liste est probablement vide : Tatami a besoin d'un peu de temps pour apprendre qui vous êtes et vous proposer des utilisateurs similaires.</p>\\\n  <p>Et surtout, n'oubliez pas de poster des messages et d'utiliser des #hashtags, cela permet à Tatami de vous proposer plus rapidement des utilisateurs à suivre !</p>\n\ntatami.help.home.profileTrends.title=<b>Tendances</b>\ntatami.help.home.profileTrends.content=<p>Cette liste représente les #hashtag les plus utilisés ces derniers jours sur Tatami. Utilisez-la pour découvrir les dernières tendances et les sujets que vous ne connaissez pas !</p>\ntatami.tatam.publish=Publier\ntatami.status.options=Options\ntatami.tatam.mandatory=Commentaire obligatoire\n"
  },
  {
    "path": "web/src/main/webapp/WEB-INF/pages/errors/404.jsp",
    "content": "<%@ taglib prefix=\"sec\" uri=\"http://www.springframework.org/security/tags\" %>\n<%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\" %>\n<%@ taglib prefix=\"fmt\" uri=\"http://java.sun.com/jsp/jstl/fmt\" %>\n\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<jsp:include page=\"../includes/header.jsp\"/>\n\n<body>\n\n<jsp:include page=\"../includes/topmenu.jsp\"/>\n\n<div id=\"mainPanel\" class=\"container\">\n    <div class=\"row\">\n        <div class=\"offset2 span8 text-center\">\n            <h1><fmt:message key=\"tatami.404\"/></h1>\n           <img src=\"/img/404-error.jpg\">\n       </div>\n    </div>\n</div>\n\n<jsp:include page=\"../includes/footer.jsp\"/>\n\n</body>\n</html>"
  },
  {
    "path": "web/src/main/webapp/WEB-INF/pages/errors/500.jsp",
    "content": "<%@ taglib prefix=\"sec\" uri=\"http://www.springframework.org/security/tags\" %>\n<%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\" %>\n<%@ taglib prefix=\"fmt\" uri=\"http://java.sun.com/jsp/jstl/fmt\" %>\n\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<jsp:include page=\"../includes/header.jsp\"/>\n\n<body>\n\n<jsp:include page=\"../includes/topmenu.jsp\"/>\n\n<div id=\"mainPanel\" class=\"container\">\n    <div class=\"row\">\n        <div class=\"offset2 span8 text-center\">\n            <h1><fmt:message key=\"tatami.500\"/></h1>\n           <img src=\"/img/500-error.jpg\">\n       </div>\n    </div>\n</div>\n\n<jsp:include page=\"../includes/footer.jsp\"/>\n\n</body>\n</html>"
  },
  {
    "path": "web/src/main/webapp/WEB-INF/pages/errors/file_not_found.jsp",
    "content": "<%@ taglib prefix=\"sec\" uri=\"http://www.springframework.org/security/tags\" %>\n<%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\" %>\n<%@ taglib prefix=\"fmt\" uri=\"http://java.sun.com/jsp/jstl/fmt\" %>\n\n<!DOCTYPE html>\n<html lang=\"en\">\n\n<jsp:include page=\"../includes/header.jsp\"/>\n\n<body>\n\n<jsp:include page=\"../includes/topmenu.jsp\"/>\n\n<div id=\"mainPanel\" class=\"container\">\n    <div class=\"row\">\n        <div class=\"offset2 span8 text-center\">\n            <h2><fmt:message key=\"tatami.file.not.found\"/></h2>\n            <img src=\"/img/404-error.jpg\">\n        </div>\n    </div>\n</div>\n\n<jsp:include page=\"../includes/footer.jsp\"/>\n\n</body>\n</html>"
  },
  {
    "path": "web/src/main/webapp/WEB-INF/pages/home.jsp",
    "content": "<%@ page language=\"java\" pageEncoding=\"UTF-8\" contentType=\"text/html; charset=utf-8\" %>\n<html>\n<head>\n    <title></title>\n    <script type=\"text/javascript\">window.location.href = '<%=request.getContextPath()%>/#/home'</script>\n</head>\n<body>\nIf you are not redirected automatically, click\n<a href=\"<%=request.getContextPath()%>/#/home\">here</a>.\n</body>\n</html>"
  },
  {
    "path": "web/src/main/webapp/WEB-INF/pages/includes/footer.jsp",
    "content": "<%@ taglib prefix=\"fmt\" uri=\"http://java.sun.com/jsp/jstl/fmt\" %>\n<%@ taglib prefix=\"sec\" uri=\"http://www.springframework.org/security/tags\" %>\n<%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\" %>\n\n<c:if test=\"${wro4jEnabled eq false}\">\n    <script src=\"/js/vendor/jquery.js\"></script>\n    <script src=\"/js/vendor/bootstrap.js\"></script>\n    <script src=\"/js/vendor/bootstrap-tour.js\"></script>\n    <script src=\"/js/vendor/underscore.js\"></script>\n    <script src=\"/js/vendor/underscore-polyfill.js\"></script>\n    <script src=\"/js/vendor/backbone.js\"></script>\n    <script src=\"/js/vendor/marked.js\"></script>\n    <script src=\"/js/vendor/backbone.marionette.js\"></script>\n    <script src=\"/js/vendor/modernizr.js\"></script>\n    <script src=\"/js/vendor/jquery.ui.widget.js\"></script>\n    <script src=\"/js/vendor/jquery.iframe-transport.js\"></script>\n    <script src=\"/js/vendor/jquery.fileupload.js\"></script>\n    <script src=\"/js/vendor/jquery.atmosphere.js\"></script>\n    <script src=\"/js/vendor/jquery-timeago.js\"></script>\n    <script src=\"/js/vendor/jquery.placeholder.js\"></script>\n    <script src=\"/js/app/plugins/tatami.atmosphere.js\"></script>\n    <script src=\"/js/app/plugins/bootstrap-filestyle.min.js\"></script>\n    <script src=\"/js/vendor/jquery.jgrowl.js\"></script>\n</c:if>\n<c:if test=\"${wro4jEnabled eq true}\">\n    <script src=\"/tatami/static-wro4j/${version}/tatami-vendor.js\"></script>\n</c:if>\n\n"
  },
  {
    "path": "web/src/main/webapp/WEB-INF/pages/includes/header.jsp",
    "content": "<%@ taglib prefix=\"sec\" uri=\"http://www.springframework.org/security/tags\" %>\n<%@ taglib prefix=\"fmt\" uri=\"http://java.sun.com/jsp/jstl/fmt\" %>\n<%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\" %>\n<%@ page import=\"Constants\" %>\n<%\n    String version = Constants.VERSION;\n    request.setAttribute(\"version\", version);\n    String googleAnalyticsKey = Constants.GOOGLE_ANALYTICS_KEY;\n    request.setAttribute(\"googleAnalyticsKey\", googleAnalyticsKey);\n%>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <title><fmt:message key=\"tatami.title\"/></title>\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale = 1,user-scalable=no,maximum-scale=1.0\">\n    <meta name=\"description\" content=\"\">\n    <meta name=\"author\" content=\"Ippon Technologies\">\n\n    <link href=\"/css/vendor/css/bootstrap.css\" rel=\"stylesheet\">\n    <link href=\"/css/tatami.css\" rel=\"stylesheet\">\n    <!--[if IE]>\n        <link rel=\"stylesheet\" type=\"text/css\" href=\"/css/ie-only.css\" />\n    <![endif]-->\n    <link href=\"/css/vendor/css/jQueryjGrowl.css\" rel=\"stylesheet\">\n\n\n\n    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->\n\n    <!--[if lt IE 7]>\n    <link rel=\"stylesheet\" href=\"http://blueimp.github.com/cdn/css/bootstrap-ie6.min.css\">\n    <![endif]-->\n    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->\n    <!--[if lt IE 9]>\n    <script src=\"/js/vendor/respond.js\"></script>\n    <script src=\"//html5shim.googlecode.com/svn/trunk/html5.js\"></script>\n    <![endif]-->\n\n    <!-- Le fav and touch icons -->\n\n    <link rel=\"apple-touch-icon\" href=\"/img/apple-touch-icon.png\">\n    <link rel=\"apple-touch-startup-image\" href=\"/img/startup.png\">\n    <link rel=\"shortcut icon\" type=\"image/png\" href=\"/img/company-logo.ico\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n\n    <c:if test=\"${googleAnalyticsKey ne ''}\">\n        <script type=\"text/javascript\">\n            var _gaq = _gaq || [];\n            _gaq.push(['_setAccount', '${googleAnalyticsKey}']);\n            _gaq.push(['_trackPageview']);\n            (function() {\n                var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;\n                ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';\n                var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);\n            })();\n        </script>\n    </c:if>\n\n    <sec:authorize ifAnyGranted=\"ROLE_USER\">\n        <c:if test=\"${not empty user.rssUid}\">\n            <link rel=\"alternate\" type=\"application/rss+xml\" title=\"RSS\"\n                  href=\"/tatami/syndic/${user.rssUid}\" />\n        </c:if>\n    </sec:authorize>\n\n    <script type=\"text/javascript\">\n        var username = \"${user.username}\";\n        <c:if test=\"${ios == null}\">\n            var ios = false;\n        </c:if>\n        <c:if test=\"${ios != null}\">\n            var ios = ${ios};\n        </c:if>\n        var ie = (function(){\n            var v = 3, div = document.createElement('div'), a = div.all || [];\n            while (div.innerHTML = '<!--[if gt IE '+(++v)+']><br><![endif]-->', a[0]); \n            if (Function('/*@cc_on return document.documentMode===10@*/')()){\n                v = 10;\n            }\n            return v > 4 ? v : !v;\n        }());\n    </script>\n\n</head>"
  },
  {
    "path": "web/src/main/webapp/WEB-INF/pages/includes/help-home.jsp",
    "content": "<%@ taglib prefix=\"fmt\" uri=\"http://java.sun.com/jsp/jstl/fmt\" %>\n<%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\" %>\n\n\n<script >\n    jQuery(function($) {\n        var tour = new Tour({\n            labels: {\n                end: '<fmt:message key=\"tatami.help.end\"/>',\n                next: '<fmt:message key=\"tatami.help.next\"/>',\n                prev: '<fmt:message key=\"tatami.help.previous\"/>'\n            },\n            backdrop: true,\n            useLocalStorage: true\n        });\n\n        tour.addStep({\n            element: \"#help-tour\",\n            placement: \"bottom\",\n            stepId: \"presentationHelp\",\n            title: \"<fmt:message key=\"tatami.help.home.presentation.title\"/>\",\n            content: \"<fmt:message key=\"tatami.help.home.presentation.content\"/>\"\n        });\n\n        tour.addStep({\n            element: \"#tatamiBody\",\n            placement: \"left\",\n            stepId: \"timelineHelp\",\n            title: \"<fmt:message key=\"tatami.help.home.timeline.title\"/>\",\n            content: \"<fmt:message key=\"tatami.help.home.timeline.content\"/>\"\n        });\n\n        tour.addStep({\n            element: \"#editTatam\",\n            placement: \"left\",\n            stepId: \"updateStatusContentHelp\",\n            title: \"<fmt:message key=\"tatami.help.home.updatestatus.title\"/>\",\n            content: \"<fmt:message key=\"tatami.help.home.updatestatus.content\"/>\"\n        });\n\n        tour.addStep({\n            element: \"#groups-list-title\",\n            placement: \"right\",\n            stepId: \"groupsHelp\",\n            title: \"<fmt:message key=\"tatami.help.home.groups.title\"/>\",\n            content: \"<fmt:message key=\"tatami.help.home.groups.content\"/>\",\n            container: \"#tatamiBody\"\n        });\n\n        tour.addStep({\n            element: \"#follow-suggest-title\",\n            placement: \"right\",\n            stepId: \"follow-suggestHelp\",\n            title: \"<fmt:message key=\"tatami.help.home.follow-suggest.title\"/>\",\n            content: \"<fmt:message key=\"tatami.help.home.follow-suggest.content\"/>\",\n            container: \"#tatamiBody\"\n        });\n\n        tour.addStep({\n            element: \"#profile-trends-title\",\n            placement: \"right\",\n            stepId: \"profileTrendsHelp\",\n            title: \"<fmt:message key=\"tatami.help.home.profileTrends.title\"/>\",\n            content: \"<fmt:message key=\"tatami.help.home.profileTrends.content\"/>\",\n            container: \"#tatamiBody\"\n        });\n\n\n        $(\"#help-menu\").show();\n\n        $(\"#help-tour\").click(function (e) {\n            e.preventDefault();\n            tour.setCurrentStep(0);\n            tour.start(true);\n            $(this).parents(\".alert\").alert(\"close\");\n        });\n    });\n\n</script>\n"
  },
  {
    "path": "web/src/main/webapp/WEB-INF/pages/includes/navigation-admin.jsp",
    "content": "\n<%@ taglib prefix=\"fmt\" uri=\"http://java.sun.com/jsp/jstl/fmt\" %>\n<%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\" %>\n\n\n    <div class=\"col-span-4\">\n        <div class=\"tabbable alert alert-status\">\n            <ul class=\"adminMenu nav nav-pills nav-stacked nomargin\">\n                <li class=\"active\">\n                    <a href=\"#profile\">\n                        <i class=\"glyphicon glyphicon-user\"></i> <fmt:message key=\"tatami.menu.profile\"/>\n                    </a>\n                </li>\n                <li>\n                    <a href=\"#preferences\">\n                        <i class=\"glyphicon glyphicon-picture\"></i> <fmt:message key=\"tatami.menu.preferences\"/>\n                    </a>\n                </li>\n                <li>\n                    <a href=\"#password\">\n                        <i class=\"glyphicon glyphicon-lock\"></i> <fmt:message key=\"tatami.menu.password\"/>\n                    </a>\n                </li>\n                <li>\n                    <a href=\"#files\">\n                        <i class=\"glyphicon glyphicon-file\"></i> <fmt:message key=\"tatami.menu.files\"/>\n                    </a>\n                </li>\n                <li>\n                    <a href=\"#users\">\n                        <i class=\"glyphicon glyphicon-globe\"></i> <fmt:message key=\"tatami.menu.directory\"/>\n                    </a>\n                </li>\n                <li>\n                    <a href=\"#groups\">\n                        <i class=\"glyphicon glyphicon-th-large\"></i> <fmt:message key=\"tatami.menu.groups\"/>\n                    </a>\n                </li>\n                <li>\n                    <a href=\"#tags\">\n                        <i class=\"glyphicon glyphicon-tags\"></i> <fmt:message key=\"tatami.menu.tags\"/>\n                    </a>\n                </li>\n                <li>\n                    <a href=\"#status_of_the_day\">\n                        <i class=\"glyphicon glyphicon-signal\"></i> <fmt:message key=\"tatami.menu.status.of.the.day\"/>\n                    </a>\n                </li>\n            </ul>\n        </div>\n    </div>\n\n"
  },
  {
    "path": "web/src/main/webapp/WEB-INF/pages/includes/template-search-engine.jsp",
    "content": "<%@ taglib prefix=\"fmt\" uri=\"http://java.sun.com/jsp/jstl/fmt\" %>\n<%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\" %>\n\n<script type=\"text/template\" id=\"search-category\">\n<@ if(cat.category == 'tags') {@>\n    <li class=\"category <@= cat.category @>\"><i class=\"icon-tags\"></i></li>\n<@} else if(cat.category == 'users') { @>\n    <li class=\"category <@= cat.category @>\"><i class=\"icon-user\"></i></li>\n<@} else { @>\n    <li class=\"category <@= cat.category @>\"><i class=\"icon-th-large\"></i></li>\n<@}@>\n</script>\n\n<script type=\"text/template\" id=\"search-category-item\">\n<@ if(item.category == 'tags') {@>\n    <li class=\"\" data-value=\"<@= item.label @>\">\n        <a href=\"#\"><@= item.label @></a>\n    </li>\n<@} else if(item.category == 'users') { @>\n    <li class=\"item users\" data-value=\"<@= item.label @>\">\n        <img class=\"avatar avatar-small\"\n            <@ if (item.avatar == null || item.avatar == '') { @>\n            src=\"/img/default_image_profile.png\"\n            <@ } else { @>\n            src=\"/tatami/avatar/<@= item.avatar @>/photo.jpg\"\n            <@ } @>\n             alt=\"\"/>\n        <h4><a href=\"#\"><@= item.fullName @></a></h4>\n        <p><@= item.label @></p>\n    </li>\n<@} else { @>\n    <li class=\"item groups\" data-value=\"<@= item.label @>\" rel=\"<@= item.id @>\">\n        <img src=\"/img/default_image_profile.png\" width=\"30px\" height=\"30px\">\n        <h4><a href=\"#\"><@= item.label @></a></h4>\n        <p><@= item.nb @> <fmt:message key=\"tatami.group.counter\"/></p>\n    </li>\n<@}@>\n</script>"
  },
  {
    "path": "web/src/main/webapp/WEB-INF/pages/includes/templates-admin.jsp",
    "content": "<%@ taglib prefix=\"fmt\" uri=\"http://java.sun.com/jsp/jstl/fmt\" %>\n<%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\" %>\n\n<script type=\"text/template\" id=\"accountProfile\" >\n     <h2>\n        <fmt:message key=\"tatami.account.update.title\"/>\n    </h2>\n             </br>\n    <fieldset class=\"form-horizontal row-fluid\">\n    <@ if (!ie || ie>9){ @>\n    <div class=\"control-group dashed\">\n        <label class=\"control-label\">\n\n        </label>\n\n          <div class=\"controls\">\n            <div id=\"updateAvatar\" class=\"dropzone well\">\n                <img class=\"nomargin avatar\" src=\"<@= avatar @>\" alt=\"\"/>\n                <p class=little-padding-top><fmt:message key=\"tatami.user.picture.button\" /></p>\n                <input id=\"avatarFile\" type=\"file\" name=\"uploadFile\" data-url=\"/tatami/rest/fileupload/avatar\"/>\n            </div>\n            <div class=\"attachmentBar progress progress-striped active\" style=\"display: none;\">\n                <div class=\"bar progress-bar progress-bar-info\" style=\"width: 0%;\"></div>\n            </div>\n        </div>\n    </div>\n    <@ } else { @>\n         <label class=\"control-label\">\n\n        </label>\n          <div class=\"controlsIE\">\n            <p><fmt:message key=\"tatami.user.picture.buttonIE\" /></p>\n            <input id=\"avatarFile\" type=\"file\" name=\"uploadFile\" data-url=\"/tatami/rest/fileupload/avatarIE\" class=\"filestyle\" data-classButton=\"btn btn-primary\" data-input=\"false\" data-buttonText=\"Photo\" data-icon=\"false\"/>\n            <span class=\"glyphicon glyphicon-search\"></span>\n            <span class=\"upload-ok\"><fmt:message key=\"tatami.user.picture.buttonIE-ok\" /></span>\n            <span class=\"upload-ko\"><fmt:message key=\"tatami.user.picture.buttonIE-ko\" /></span>\n          </div>\n    <@ } @>\n\n    </fieldset>\n\n    <fieldset class=\"form-horizontal row-fluid\">\n        <legend>\n            <fmt:message key=\"tatami.account.update.legend\"/>\n        </legend>\n\n        <div class=\"control-group\">\n            <label class=\"control-label\">\n                <fmt:message key=\"tatami.user.email\"/>\n            </label>\n\n            <div class=\"controls\">\n                <input name=\"login\" type=\"text\" disabled=\"true\" class=\"col-span-12\" value=\"<@= login @>\"/>\n            </div>\n        </div>\n\n\n        <div class=\"control-group\">\n            <label class=\"control-label\" for=\"firstName\">\n                <fmt:message key=\"tatami.user.firstName\"/>\n            </label>\n\n            <div class=\"controls\">\n                <input name=\"firstName\" type=\"text\" size=\"15\" maxlength=\"40\" class=\"input-xlarge col-span-12\" value=\"<@= firstName @>\"/>\n            </div>\n        </div>\n\n        <div class=\"control-group\">\n            <label class=\"control-label\" for=\"lastName\">\n                <fmt:message key=\"tatami.user.lastName\"/>\n            </label>\n\n            <div class=\"controls\">\n                <input name=\"lastName\" type=\"text\" id=\"lastName\" size=\"15\" maxlength=\"40\" class=\"input-xlarge col-span-12\" value=\"<@= lastName @>\"/>\n            </div>\n        </div>\n\n        <div class=\"control-group\">\n            <label class=\"control-label\" for=\"jobTitle\">\n                <fmt:message key=\"tatami.user.jobTitle\"/>\n            </label>\n\n            <div class=\"controls\">\n                <input name=\"jobTitle\" type=\"text\" size=\"15\" maxlength=\"100\" class=\"input-xlarge col-span-12\" value=\"<@= jobTitle @>\"/>\n            </div>\n        </div>\n\n        <div class=\"control-group\">\n            <label class=\"control-label\" for=\"phoneNumber\">\n                <fmt:message key=\"tatami.user.phoneNumber\"/>\n            </label>\n\n            <div class=\"controls\">\n                <input name=\"phoneNumber\" type=\"text\" size=\"10\" maxlength=\"20\" class=\"input-xlarge col-span-12\" value=\"<@= phoneNumber @> \"/>\n            </div>\n        </div>\n\n        <div class=\"return\"/>\n\n        <div class=\"form-actions\">\n            <button type=\"submit\" class=\"input-xlarge btn btn-primary btn-block\">\n                <fmt:message key=\"tatami.form.save\"/>\n            </button>\n        </div>\n    </fieldset>\n</script>\n\n<script type=\"text/template\" id=\"accountDestroy\">\n    <fieldset class=\"form-horizontal row-fluid\">\n        <legend><fmt:message key=\"tatami.user.suppress\"/></legend>\n        <div class=\"return\"/>\n        <div class=\"form-actions\">\n            <button type=\"submit\" class=\"input-xlarge btn btn-danger btn-block\" onclick=\"return(confirm('<fmt:message key=\"tatami.user.suppress.confirmation\"/>'));\">\n                <fmt:message key=\"tatami.user.suppress\"/>\n            </button>\n        </div>\n    </fieldset>\n</script>\n\n<script type=\"text/template\" id=\"accountPreferences\">\n    <h2>\n        <fmt:message key=\"tatami.menu.preferences\"/>\n    </h2>\n\n        <legend>\n            <fmt:message key=\"tatami.preferences.notifications\"/>\n        </legend>\n\n        <div class=\"control-group\">\n            <div class=\"controls\">\n                <label class=\"checkbox\">\n                    <input name=\"mentionEmail\" type=\"checkbox\" <@   if(mentionEmail){ @> checked=\"true\" <@ } @>/> <fmt:message key=\"tatami.preferences.notifications.email.mention\"/>\n                </label>\n            </div>\n            <div class=\"controls\">\n                <label class=\"checkbox\">\n                    <input name=\"dailyDigest\" type=\"checkbox\" <@ if(dailyDigest){ @> checked=\"true\" <@ } @>/> <fmt:message key=\"tatami.preferences.notifications.email.dailyDigest\"/>\n                </label>\n            </div>\n            <div class=\"controls\">\n                <label class=\"checkbox\">\n                    <input name=\"weeklyDigest\" type=\"checkbox\" <@ if(weeklyDigest){ @> checked=\"true\" <@ } @>/> <fmt:message key=\"tatami.preferences.notifications.email.weeklyDigest\"/>\n                </label>\n            </div>\n            <div class=\"controls\">\n                <label class=\"checkbox\">\n                    <input name=\"rssUidActive\" type=\"checkbox\" <@ if (rssUidActive) {@> checked=\"true\" <@ } @>/>  <fmt:message key=\"tatami.preferences.notifications.rss.timeline\"/>\n                </label>\n                <@ if (rssUidActive) { @> <a href=\"/tatami/syndic/<@=rssUid@>\" ><fmt:message key=\"tatami.preferences.notifications.rss.timeline.link\"/> </a><@ } @>\n            </div>\n        </div>\n    </fieldset>\n\n    <fieldset>\n        <div class=\"return\"/>\n        <div class=\"form-actions\">\n            <button type=\"submit\" class=\"input-xlarge btn btn-primary btn-block\">\n                <fmt:message key=\"tatami.form.save\"/>\n            </button>\n        </div>\n    </fieldset>\n\n</script>\n\n<script type=\"text/template\" id=\"accountNewPasswordConfirmation\">\n    <fmt:message key=\"tatami.user.new.password.confirmation.error\"/>\n</script>\n\n<script type=\"text/template\" id=\"accountPassword\">\n    <h2>\n        <fmt:message key=\"tatami.menu.password\"/>\n    </h2>\n\n    <fieldset>\n        <legend>\n            <fmt:message key=\"tatami.user.password.legend\"/>\n        </legend>\n\n        <div class=\"control-group\">\n            <label class=\"control-label\" for=\"oldPassword\">\n                <fmt:message key=\"tatami.user.old.password\"/>\n            </label>\n\n            <div class=\"controls\">\n                <input name=\"oldPassword\" type=\"password\" required=\"required\" size=\"15\" maxlength=\"40\" class=\"input-xlarge col-span-12\" />\n            </div>\n        </div>\n\n        <div class=\"control-group\">\n            <label class=\"control-label\" for=\"newPassword\">\n                <fmt:message key=\"tatami.user.new.password\"/>\n            </label>\n\n            <div class=\"controls\">\n                <input name=\"newPassword\" type=\"password\" required=\"required\" ize=\"15\" maxlength=\"40\" class=\"input-xlarge col-span-12\"/>\n            </div>\n        </div>\n\n        <div class=\"control-group\">\n            <label class=\"control-label\" for=\"newPasswordConfirmation\">\n                <fmt:message key=\"tatami.user.new.password.confirmation\"/>\n            </label>\n\n            <div class=\"controls\">\n                <input name=\"newPasswordConfirmation\" type=\"password\" required=\"required\" size=\"15\" maxlength=\"40\" class=\"input-xlarge col-span-12\"/>\n            </div>\n        </div>\n        <div class=\"return\"/>\n        <div class=\"form-actions\">\n            <button type=\"submit\" class=\"btn btn-primary btn-block\">\n                <fmt:message key=\"tatami.form.save\"/>\n            </button>\n        </div>\n    </fieldset>\n\n</script>\n\n<script type=\"text/template\" id=\"form-ldap\">\n    <fmt:message key=\"tatami.user.password.ldap\"/>\n</script>\n\n<script type=\"text/template\" id=\"users-menu\">\n    <ul class=\"nav nav-tabs\">\n        <li>\n            <a href =\"#users\">\n                <fmt:message key=\"tatami.account.users.myfriends\"/>\n            </a>\n        </li>\n        <li>\n            <a href =\"#users/recommended\">\n                <fmt:message key=\"tatami.account.users.recommended\"/>\n            </a>\n        </li>\n        <li>\n            <a href =\"#users/search\">\n                <fmt:message key=\"tatami.search.placeholder\"/>\n            </a>\n        </li>\n    </ul>\n</script>\n\n<script type=\"text/template\" id=\"groups-menu\">\n    <ul class=\"nav nav-tabs\">\n        <li>\n            <a href =\"#groups\">\n                <fmt:message key=\"tatami.account.groups.mygroups\"/>\n            </a>\n        </li>\n        <li>\n            <a href =\"#groups/recommended\">\n                <fmt:message key=\"tatami.trends.title\"/>\n            </a>\n        </li>\n        <li>\n            <a href =\"#groups/search\">\n                <fmt:message key=\"tatami.search.placeholder\"/>\n            </a>\n        </li>\n    </ul>\n</script>\n\n<script type=\"text/template\" id=\"groups-form\">\n    <h2>\n        <fmt:message key=\"tatami.group.name\"/>\n    </h2>\n    <@ if (typeof groupId === 'undefined') { @>\n        <button class=\"show btn btn-xlarge btn-block btn-primary\" type=\"button\">\n            <fmt:message key=\"tatami.group.add\"/>\n        </button>\n    <@ } @>\n    <fieldset <@ if (typeof groupId === 'undefined') { @>class=\"hide\" <@ } @>>\n        <legend>\n            <@ if (typeof groupId === 'undefined') { @>\n                <fmt:message key=\"tatami.group.add\"/>\n            <@ } else { @>\n                <fmt:message key=\"tatami.group.edit.details\"/>\n            <@ } @>\n        </legend>\n        <div class=\"control-group\">\n            <label class=\"control-label\" for=\"name\">\n                <fmt:message key=\"tatami.group.add.title\"/>\n            </label>\n\n            <div class=\"controls\">\n                <input name=\"name\" type=\"text\" required=\"required\" size=\"30\" maxlength=\"50\" class=\"input-xlarge col-span-12\" value=\"<@= name @>\" />\n            </div>\n        </div>\n\n        <div class=\"control-group\">\n            <label class=\"control-label\" for=\"description\">\n                <fmt:message key=\"tatami.group.add.description\"/>\n            </label>\n\n            <div class=\"controls\">\n                <textarea name=\"description\" class=\"input-xlarge col-span-12\"><@= description @></textarea>\n            </div>\n        </div>\n\n        <@ if (typeof groupId === 'undefined') { @>\n            <div class=\"control-group\">\n                <label class=\"control-label\" for=\"publicGroup\">\n                    <fmt:message key=\"tatami.group.add.access\"/>\n                </label>\n\n                <div class=\"controls\">\n                    <label class=\"radio\">\n                    <input type=\"radio\" name=\"publicGroup\" value=\"public\" <@ if (publicGroup) { @> checked<@ } @> required>\n                    <fmt:message key=\"tatami.group.add.public\"/>\n                    </label>\n                    <label class=\"radio\">\n                    <input type=\"radio\" name=\"publicGroup\" value=\"private\" <@ if (!publicGroup) { @> checked<@ } @> required>\n                    <fmt:message key=\"tatami.group.add.private\"/>\n                    </label>\n                </div>\n            </div>\n\n            <div class=\"alertColor\">\n                <i class=\"glyphicon glyphicon-warning-sign\"></i>\n                <fmt:message key=\"tatami.group.add.public.alert\"/>\n            </div>\n        <@ } else { @>\n            <div class=\"control-group\">\n                <label class=\"control-label\" for=\"archivedGroup\">\n                    <fmt:message key=\"tatami.group.archive\"/>\n                </label>\n\n                <div class=\"controls\">\n                    <label class=\"radio\">\n                        <input type=\"radio\" name=\"archivedGroup\" value=\"true\" <@ if (archivedGroup) { @> checked<@ } @> required>\n                        <fmt:message key=\"tatami.group.archive.true\"/>\n                    </label>\n                    <label class=\"radio\">\n                        <input type=\"radio\" name=\"archivedGroup\" value=\"false\" <@ if (!archivedGroup) { @> checked<@ } @> required>\n                        <fmt:message key=\"tatami.group.archive.false\"/>\n                    </label>\n                </div>\n            </div>\n\n            <div class=\"alert\">\n                <i class=\"icon-warning-sign\"></i>\n                <fmt:message key=\"tatami.group.archive.alert\"/>\n            </div>\n        <@ } @>\n\n        <br/>\n        <div class=\"return\"/>\n        <br/>\n        <div class=\"form-actions\">\n            <@ if (typeof groupId === 'undefined') { @>\n                <button type=\"submit\" class=\"btn btn-success col-span-7 little-marge-right\">\n                    <fmt:message key=\"tatami.form.save\"/>\n                </button>\n                <button type=\"reset\" class=\"btn btn-danger col-span-4\">\n                    <fmt:message key=\"tatami.form.cancel\"/>\n                </button>\n            <@ } else { @>\n                <button type=\"submit\" class=\"btn btn-success col-span-12\">\n                    <fmt:message key=\"tatami.form.save\"/>\n                </button>\n            <@ } @>\n        </div>\n\n    </fieldset>\n\n\n\n</script>\n\n<script type=\"text/template\" id=\"groups-form-adduser\">\n    <fieldset>\n        <legend>\n                <fmt:message key=\"tatami.group.edit.member.add\"/>\n        </legend>\n        <div class=\"control-group\">\n            <label class=\"control-label\" for=\"username\">\n                <fmt:message key=\"tatami.username\"/>\n            </label>\n\n            <div class=\"controls\">\n                <input name=\"username\" type=\"text\" autocomplete=\"off\" required=\"required\" class=\"input-xlarge col-span-12\"/>\n            </div>\n        </div>\n        <br/>\n        <div class=\"return\"/>\n        <br/>\n        <div class=\"form-actions\">\n            <button type=\"submit\" class=\"btn btn-success col-span-12\">\n                <fmt:message key=\"tatami.form.save\"/>\n            </button>\n        </div>\n\n    </fieldset>\n\n\n</script>\n\n\n<script type=\"text/template\" id=\"groups-item\">\n    <@ if(name) { @><!-- Afin que les groupes privés dont le nom est caché n apparaissent pas -->\n    <td>\n        <a href=\"/tatami/home/groups/<@= groupId @>\" title=\"<@= description @>\"><@= name @></a>\n    </td>\n    <td>\n        <@ if(publicGroup && !archivedGroup) { @>\n            <span class=\"label labelSizeNormal label-warning\"><fmt:message key=\"tatami.group.add.public\"/></span>\n        <@ } else if(publicGroup && archivedGroup || !publicGroup && archivedGroup) { @>\n            <span class=\"label labelSizeNormal\"><fmt:message key=\"tatami.group.add.archived\"/></span>\n        <@ } else {@>\n            <span class=\"label labelSizeNormal label-info\"><fmt:message key=\"tatami.group.add.private\"/></span>\n        <@ } @>\n    </td>\n    <td>\n        <@= counter  @>\n    </td>\n      <td>\n          <@ if(publicGroup && !administrator) { @>\n          <a class=\"btn-title toggleGroup pull-right label labelSizeNormal <@= (member)?'label-info':'' @>\">\n              <@ if(member) { @>\n              <span class=\"glyphicon glyphicon-minus\"> <span class=\"hidden-phone\"><fmt:message key=\"tatami.user.followed\"/></span></span>\n              <@ } else { @>\n              <span class=\"glyphicon glyphicon-plus\"> <span class=\"hidden-phone\"><fmt:message key=\"tatami.user.follow\"/></span></span>\n              <@ } @>\n          </a>\n          <@ } else if(administrator) { @>\n          <a href=\"/tatami/account/#/groups/<@= groupId @>\"  class=\"btn-title toggleTag pull-right label labelSizeNormal label-info hidden-phone\">\n              <span class=\"glyphicon glyphicon-th-large\"> <span><fmt:message key=\"tatami.group.edit.link\"/></span></span>\n          </a>\n          <@ } @>\n      </td>\n    <@ } @>\n</script>\n\n<script type=\"text/template\" id=\"usergroup-item\">\n    <td style=\"text-align: left\">\n        <div class='pull-left background-image-fffix little-marge-right'>\n\n            <img class=\"img-rounded img-medium\" style=\"background-image: url(<@= avatarURL @>);\"></img>\n        </div>\n        <h4>\n            <@  if(!activated) { @>\n            <span>\n                <span class=\"glyphicon glyphicon-off\">\n                   <fmt:message key=\"tatami.user.desactivate.msg\"/>\n                </span>\n            </span>\n            <@ } @>\n            <a href=\"/tatami/home/#/users/<@= username @>\">\n                <strong>\n                    <@= fullName @>\n                </strong>\n            </a>\n            <br>\n            <a href=\"/tatami/home/#/users/<@= username @>\">\n                <small>\n                    @<@= username @>\n                </small>\n            </a>\n        </h4>\n\n    </td>\n\n    <td>\n        <@ if(role === 'ADMIN'){ @>\n        <fmt:message key=\"tatami.group.role.admin\"/>\n        <@ } else { @>\n        <fmt:message key=\"tatami.group.role.member\"/>\n        <@ } @>\n    </td>\n    <td>\n       \n            <@ if (window.username !== username) { @>\n                <button type=\"button\" class=\"btn btn-success input-block-level delete\">\n                    <fmt:message key=\"tatami.group.edit.member.delete\"/>\n                </button>\n            <@ } @>\n       \n    </td>\n</script>\n\n<script type=\"text/template\" id=\"tags-menu\">\n    <ul class=\"nav nav-tabs\">\n        <li>\n            <a href =\"#tags\">\n                <fmt:message key=\"tatami.account.tags.mytags\"/>\n            </a>\n        </li>\n        <li>\n            <a href =\"#tags/recommended\">\n                <fmt:message key=\"tatami.trends.title\"/>\n            </a>\n        </li>\n        <li>\n            <a href =\"#tags/search\">\n                <fmt:message key=\"tatami.search.placeholder\"/>\n            </a>\n        </li>\n    </ul>\n</script>\n\n<script type=\"text/template\" id=\"tags-item\">\n    <td>\n        <a href=\"/tatami/home/#/tags/<@= name @>\" title=\"<@= name @>\">#<@= name @></a>\n    </td>\n    <td class=\"follow\">\n        <a class=\"btn-title toggleTag pull-right label labelSizeNormal <@= (followed)?'label-info':'' @> \">\n            <@ if(followed) { @>\n            <span class=\"glyphicon glyphicon-minus\"> <span class=\"hidden-phone\"><fmt:message key=\"tatami.user.followed\"/></span></span>\n            <@ } else { @>\n            <span class=\"glyphicon glyphicon-plus\"> <span class=\"hidden-phone\"><fmt:message key=\"tatami.user.follow\"/></span></span>\n            <@ } @>\n        </a>\n    </td>\n\n\n</script>\n\n<script type=\"text/template\" id=\"files-quota\">\n\n    <div class=\"progress\">\n        <@ if(quota < 50){@>\n        <div class=\"progress-bar progress-bar-success\" style=\"width: <@= quota @>%;\">\n        <@ }else if(quota > 50 && quota < 80) {@>\n        <div class=\"progress-bar progress-bar-warning\" style=\"width: <@= quota @>%;\">\n        <@ }else{@>\n        <div class=\"progress-bar progress-bar-danger\" style=\"width: <@= quota @>%;\">\n        <@ }@>\n        <span class=\"quota\"><@=  quota @>%</span>\n    </div>          </div>\n</script>\n\n<script type=\"text/template\" id=\"files-menu\">\n    <h2><fmt:message key=\"tatami.menu.files\"/></h2>\n    <span class=\"file-infos\"></span>\n</script>\n\n<script type=\"text/template\" id=\"FilesListTemplate\">\n    <table class=\"table noCollapse\">\n        <tr>\n            <th style=\"border-top :0\">  </th>\n            <th style=\"border-top :0\"><b><fmt:message key=\"tatami.user.file.name\"/></b></th>\n            <th style=\"border-top :0\"><b><fmt:message key=\"tatami.user.file.size\"/></b></th>\n            <th style=\"border-top :0\"><b><fmt:message key=\"tatami.user.file.creation.date\"/></b></th>\n            <th style=\"border-top :0\">  </th>\n        </tr>\n        <tbody class=\"items\">\n        </tbody>\n    </table>\n\n</script>\n\n<script type=\"text/template\" id=\"FileItemTemplate\">\n    <td><@ if(hasThumbnail) { @>\n\t\t\t<a href=\"/tatami/file/<@= attachmentId @>/<@= filename @>\" target=\"_blank\"><img src=\"/tatami/thumbnail/<@= attachmentId @>/<@= filename @>\" /></a>\n\t\t<@ } else { @>\n\t\t\t<a href=\"/tatami/file/<@= attachmentId @>/<@= filename @>\" target=\"_blank\"><img src=\"/img/document_icon.png\" /></a>\n\t\t<@ } @>\n\t</td>\n    <td><a href=\"/tatami/file/<@= attachmentId @>/<@= filename @>\" target=\"_blank\"><@= filename @></a></td>\n    <td><@= (size/1000) @> kb</td>\n    <td><@= prettyPrintCreationDate @> </td>\n    <td>\n        <span class=\"btn btn-primary btn-block\">\n            <fmt:message key=\"tatami.user.status.delete\"/>\n        </span>\n    </td>\n</script>\n\n<script type=\"text/template\" id=\"search-filter\">\n    <input id=\"block_filter\" type=\"text\" class=\"search-query col-span-12\" name=\"result_filter\" autocomplete=\"off\" placeholder=\"<fmt:message key=\"tatami.search.filter\"/>\">\n</script>\n\n\n<script type=\"text/template\" id=\"form-success-label\">\n    <fmt:message key=\"tatami.form.success\"/>\n</script>\n\n<script type=\"text/template\" id=\"form-error-label\">\n    <fmt:message key=\"tatami.form.error\"/>\n</script>\n\n<script type=\"text/template\" id=\"groups-form-adduser-success-label\">\n    <fmt:message key=\"tatami.group.edit.member.add.success\"/>\n</script>\n\n<script type=\"text/template\" id=\"groups-form-adduser-error-label\">\n    <fmt:message key=\"tatami.group.edit.member.add.error\"/>\n</script>\n\n<script type=\"text/template\" id=\"delete-file-success-label\">\n    <fmt:message key=\"tatami.user.file.delete.success\"/>\n</script>\n\n<script type=\"text/template\" id=\"delete-file-error-label\">\n    <fmt:message key=\"tatami.user.file.delete.error\"/>\n</script>"
  },
  {
    "path": "web/src/main/webapp/WEB-INF/pages/includes/templates.jsp",
    "content": "<%@ taglib prefix=\"sec\" uri=\"http://www.springframework.org/security/tags\" %>\n<%@ taglib prefix=\"fmt\" uri=\"http://java.sun.com/jsp/jstl/fmt\" %>\n<%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\" %>\n\n\n<script type=\"text/template\" id=\"TagsHeader\">\n    <h3>\n      <span class=\"text-center\"><strong><fmt:message key=\"tatami.tag\"/> : #<@= name @></strong></span>\n      <a class=\"btn-title toggleTag pull-right label <@= (followed)?'label-info':'' @> \">\n      <@ if(followed) { @>\n        <span class=\"glyphicon glyphicon-minus\"> <span class=\"hidden-phone\"><fmt:message key=\"tatami.user.followed\"/></span></span>\n      <@ } else { @>\n        <span class=\"glyphicon glyphicon-plus\"> <span class=\"hidden-phone\"><fmt:message key=\"tatami.user.follow\"/></span></span>\n      <@ } @>\n      </a>\n    </h3>\n</script>\n<script type=\"text/template\" id=\"GroupsHeader\">\n    <h3>\n        <span class=\"text-center\"><strong><fmt:message key=\"tatami.group.name\"/> : <@= name @></strong></span>\n        <@ if(publicGroup && !administrator) { @>\n            <a class=\"btn-title toggleTag pull-right label <@= (member)?'label-info':'' @>\">\n                <@ if(member) { @>\n                  <span class=\"glyphicon glyphicon-minus\"> <span class=\"hidden-phone\"><fmt:message key=\"tatami.user.followed\"/></span></span>\n                <@ } else { @>\n                  <span class=\"glyphicon glyphicon-plus\"> <span class=\"hidden-phone\"><fmt:message key=\"tatami.user.follow\"/></span></span>\n                <@ } @>\n            </a>\n        <@ } else if(administrator) { @>\n            <a href=\"/tatami/account/#/groups/<@= groupId @>\" class=\"btn-title toggleTag pull-right label label-info hidden-phone\">\n                <span class=\"glyphicon glyphicon-th-large\"> <span><fmt:message key=\"tatami.group.edit.link\"/></span></span>\n            </a>\n        <@ } @>\n    </h3>\n</script>\n<script type=\"text/template\" id=\"SearchHeader\">\n    <h3><strong> <fmt:message key=\"tatami.user.search.searchInStatus\"/> :  \"<@= input @>\"</strong></h3>\n</script>\n<script type=\"text/template\" id=\"ProfileHeader\">\n    <@ if(!you) { @>\n    <h3><strong><fmt:message key=\"tatami.user.profile.show\"/> : @<@= username @> </strong><@ if(!activated) { @><span><i><fmt:message key=\"tatami.user.desactivate.msg2\"/></i></span><@ } @>\n        <@if(follower){ @> (<fmt:message key=\"tatami.user.follows.you\"/>) <@ }@>\n            <a class=\"btn-title toggleFriend pull-right label <@= (friend)?'label-info':'' @>\">\n                <@ if(friend) { @>\n                  <span class=\"glyphicon glyphicon-minus\"> <span class=\"hidden-phone\"><fmt:message key=\"tatami.user.followed\"/></span></span>\n                <@ } else { @>\n                <span class=\"glyphicon glyphicon-plus\"> <span class=\"hidden-phone\"><fmt:message key=\"tatami.user.follow\"/></span></span>\n                <@ } @>\n            </a>\n        <@ } else {@>\n        <h3><strong><fmt:message key=\"tatami.user.profile.yourProfil\"/></strong></h3>\n        <@ } @>\n\n    </h3>\n</script>\n<script type=\"text/template\" id=\"CardProfile\">\n    <div class=\"page-header\">\n        <h4 class=\"profile-card background-image-fffix\">\n            <div class=\"img img-rounded img-medium pull-left\" style=\"background-image: url(<@= avatarURL @>);\"/>\n            <a href=\"#users/<@= username @>\">\n                <strong>\n                    <@= fullName @>\n                </strong>\n            </a>\n            <br>\n            <a href=\"#users/<@= username @>\">\n                <small>\n                    @<@= username @>\n                </small>\n            </a>\n        </h4>\n    </div>\n</script>\n<script type=\"text/template\" id=\"TagTrends\">\n    <div class=\"well well-small\">\n        <h4 id=\"profile-trends-title\">\n            <span class=\"glyphicon glyphicon-fire\"></span>\n            &nbsp;<fmt:message key=\"tatami.trends.title\"/>\n        </h4>\n        <div class=\"items\">\n        </div>\n    </div>\n</script>\n<script type=\"text/template\" id=\"TagTrendItems\">\n    <span class=\"little-padding toggleTag pointer pull-right label <@= (followed)?'label-info':'' @>\">\n        <span class=\"glyphicon glyphicon-<@= (followed)?'minus':'plus' @>\"></span>\n    </span>\n    <span class=\"glyphicon glyphicon-arrow-<@= (trendingUp)? 'up': 'down' @>\"></span>\n    <a href=\"#tags/<@= name @>\">#<@= name @></a>\n</script>\n<script type=\"text/template\" id=\"StatusItem\">\n    <@if(root){ @>\n        <div id=\"before\">\n\n        </div>\n    <@ } @>\n    <div id=\"current\">\n        <div class='pull-left background-image-fffix statusitem-img'>\n            <@ if (type == 'MENTION_SHARE') { @>\n                <span class=\"glyphicon glyphicon-retweet\"></span>\n            <@ } else if (type == 'MENTION_FRIEND') { @>\n                <span class=\"glyphicon glyphicon-download\"></span>\n            <@ } else { @>\n                <div class=\"img img-rounded <@= root?'img-medium':'img-reply' @>\" style=\"background-image: url(<@= avatarURL @>);\" />\n            <@ } @>\n        </div>\n        <div id=\"status-content-container\">\n\n            <div class=\"pull-right text-right\">\n                <abbr class=\"timeago\" title=\"<@= iso8601StatusDate @>\"><@= prettyPrintStatusDate @></abbr>\n                <@ if(geoLocalizationURL) { @>\n                    <a  class=\"glyphicon glyphicon-map-marker\" href=\"<@= geoLocalizationURL @>\" target=\"_blank\"></a>\n                <@ } @>\n            </div>\n            <h5 class=\"statusitem-name\">\n                <strong><a href=\"#users/<@= username @>\"><@= fullName @></a></strong>\n                <small><a href=\"#users/<@= username @>\">@<@= username @></a></small>\n                <@ if (type == 'MENTION_SHARE') { @>\n                    <fmt:message key=\"tatami.user.shared.you\"/>\n                <@ } else if (type == 'MENTION_FRIEND') { @>\n                    <fmt:message key=\"tatami.user.followed.you\"/>\n                <@ } @>\n            </h5>\n            <div class=\"markdown <@ if (type == 'MENTION_SHARE') { @>mention-share<@ } @>\">\n                <@= marked(content) @>\n            </div>\n            <small> \n                <@ if (groupId) { @>\n                    <a class=\"label <@ if (publicGroup) { @>label-info<@ } else { @>label-warning<@ } @>\" href=\"#groups/<@= groupId @>\">\n                        <@= groupName @>\n                    </a>\n                    <br/>\n                <@ } @>           \n                <@ if (statusPrivate == true) { @>\n                <span class=\"glyphicon glyphicon-lock\"></span> <fmt:message key=\"tatami.status.private\"/>&nbsp;\n                <br/>\n                <@ } @>\n                <@ if (replyTo != '') { @>\n                    <span class=\"glyphicon glyphicon-share-alt\"></span> <fmt:message key=\"tatami.user.status.replyto\"/> <a href=\"#status/<@= replyTo @>\">@<@= replyToUsername @></a></br>\n                <@ } @>\n                <@ if ((type == 'STATUS' || type == 'SHARE') && sharedByUsername != null && sharedByUsername != false) { @>\n                    <span class=\"glyphicon glyphicon-retweet\"></span> <fmt:message key=\"tatami.user.status.shared.by\"/> <a href=\"#users/<@= sharedByUsername @>\">@<@= sharedByUsername @></a></br>\n                <@ } @>\n\n                <@ if ((type == 'ANNOUNCEMENT')) { @>\n                    <span class=\"glyphicon glyphicon-bullhorn\"></span> <fmt:message key=\"tatami.user.status.announced.by\"/> <a href=\"#users/<@= sharedByUsername @>\">@<@= sharedByUsername @></a></br>\n                <@ } @>\n                <div class=\"attachments\"/>   \n                <div id=\"share\">\n\n                </div>\n            </small>\n            <@  if(!activated) { @>\n                <div class=\"little-marge-top\">\n                <span class=\"glyphicon glyphicon-off\">\n                   <fmt:message key=\"tatami.user.desactivate.msg\"/>\n                </span>\n                </div>\n            <@ } @>\n        </div>\n        <div id=\"geolocalizationInStatus\">\n\n        </div>\n        <div id=\"preview\">\n\n        </div>\n\n        <div id=\"buttons\" class=\"mediumHeight little-marge-top\">\n\n        </div>\n    </div>\n\n    <@if(root){ @>      \n        <div id=\"after\">\n\n        </div>\n    <@ } @>\n</script>\n<script type=\"text/template\" id=\"ImageSlider\">\n    <div class=\"slider-container\">\n        <div class=\"slider-container-header\"><button type=\"button\" class=\"slider-button slider-button-close\" data-dismiss=\"modal\" aria-hidden=\"true\">&times;</button></div>                \n        <div class=\"slider-container-img\"><img src=\"/tatami/file/<@= attachmentsImage[current].attachmentId @>/<@= attachmentsImage[current].filename @>\"></div>\n        <a class=\"slider-button slider-button-left\">&lt;</a>\n        <a class=\"slider-button slider-button-right\">&gt;</a>\n    </div>\n</script>\n<script type=\"text/template\" id=\"ImagePreview\"> \n    <div class=\"image-preview-container\"> \n    <@ for(index in attachmentsImage){ @>\n    <@   if(index < 4){ @>                    \n            <div class=\"<@= attachmentsImage.length<2?'image-preview-element-1':'image-preview-element' @>\">\n        <@ if(!ios){ @>\n            <img src=\"/tatami/file/<@= attachmentsImage[index].attachmentId @>/<@= attachmentsImage[index].filename @>\" class=\"slide-img slide-img-n<@= index @>\">\n        <@ } else { @>\n            <a href=\"/tatami/file/<@= attachmentsImage[index].attachmentId @>/<@= attachmentsImage[index].filename @>\" class=\"btn-link status-action\" target=\"_blank\"><img src=\"/tatami/file/<@= attachmentsImage[index].attachmentId @>/<@= attachmentsImage[index].filename @>\"></a>\n        <@ } @>            \n            </div>\n    <@  } } @>\n    </div>\n</div>\n</script>\n\n<script type=\"text/template\" id=\"GeolocPreview\">\n        <div id=\"geolocMapPreview\" style=\"height:250px; width:250px\"></div>\n         <div class=\"itemGregou\">\n             <span id=\"testItem\">Test affichage de la region</span>\n         </div>\n</script>\n\n<script type=\"text/template\" id=\"StatusFooters\">\n<@ if (ios) { @>\n    <div class=\"statusitem-footer\"> \n<@ } else { @>\n    <small class=\"statusitem-footer\"> \n<@ } @>  \n        <a href=\"#status/<@= statusId @>\" class=\"btn-link status-action button-ios\" >\n            <i class=\"glyphicon glyphicon-eye-open\"></i> <fmt:message key=\"tatami.user.status.show\"/>\n        </a>\n        <@ if (ios) { @>\n            <button class=\"btn-link status-action button-ios\">\n                <a href=\"tatami://sendResponse?replyTo=<@= statusId @>&replyToUsername=<@= username @>&groupId=<@= groupId @>\">\n                    <i class=\"glyphicon glyphicon-comment\"></i> <fmt:message key=\"tatami.user.status.reply\"/>\n                </a>\n            </button>\n        <@ } else { @>\n            <button class=\"btn-link status-action status-action-reply button-ios\">\n                <i class=\"glyphicon glyphicon-comment\"></i> <fmt:message key=\"tatami.user.status.reply\"/>\n            </button>\n        <@ } @>\n\n        <@ if (!shareByMe) { @>\n            <@ if (Tatami.app.user.get('username') !== username && statusPrivate == false && groupId == '' && type != 'ANNOUNCEMENT') { @>\n            <button class=\"btn-link status-action status-action-share button-ios\" success-text=\"<fmt:message key=\"tatami.user.status.share.success\"/>\">\n                <i class=\"glyphicon glyphicon-retweet\"></i> <fmt:message key=\"tatami.user.status.share\"/>\n            </button>\n            <@ } }@>\n            <button class=\"btn-link status-action status-action-favorite button-ios\">\n                <i class=\"glyphicon glyphicon-star\"></i> <fmt:message key=\"tatami.user.status.favorite\"/>\n            </button>\n            <sec:authorize ifAnyGranted=\"ROLE_ADMIN\">\n                <@ if (statusPrivate == false && groupId == '') { @>\n                <button class=\"btn-link status-action status-action-announce button-ios\"\n                        confirmation-text='<p><fmt:message key=\"tatami.user.status.confirm.announce\"/></p><p class=\"text-center\">\n                                             <a class=\"btn btn-default status-action-announce-cancel\" href=\"#\"><fmt:message key=\"tatami.form.cancel\"/></a>\n                                             <a class=\"btn btn-danger status-action-announce-confirm\" href=\"#\"><fmt:message key=\"tatami.user.status.announce\"/></a>\n                                             </p>'>\n                    <i class=\"glyphicon glyphicon-bullhorn\"></i> <fmt:message key=\"tatami.user.status.announce\"/>\n                </button>\n                <@ } @>\n            </sec:authorize>\n            <@ if (Tatami.app.user.get('username') == username) { @>\n            <button class=\"btn-link status-action status-action-delete button-ios\"\n                    confirmation-text='<p><fmt:message key=\"tatami.user.status.confirm.delete\"/></p><p class=\"text-center\">\n                                         <button class=\"btn btn-default status-action-delete-cancel\" href=\"#\"><fmt:message key=\"tatami.form.cancel\"/></button>\n                                         <button class=\"btn btn-danger status-action-delete-confirm\" href=\"#\"><fmt:message key=\"tatami.user.status.delete\"/></button>\n                                         </p>'>\n                <i class=\"glyphicon glyphicon-trash\"></i> <fmt:message key=\"tatami.user.status.delete\"/>\n            </button>\n        <@ } @>        \n<@ if (ios) { @>\n    </div> \n<@ } else { @>\n    </small> \n<@ } @>\n</script>\n<script type=\"text/template\" id=\"StatusShares\">\n        <fmt:message key=\"tatami.user.status.shared.by\"/>\n        <span class=\"badge\">\n               <@= sharesCount @>\n        </span> :\n</script>\n<script type=\"text/template\" id=\"StatusShareItems\">\n    <div class=\"img img-rounded img-small share-img-fffix\" style=\"background-image: url(<@= avatarURL @>);\" />\n</script>\n<script type=\"text/template\" id=\"HomeSide\">\n    <section class='hidden-phone card-profile'></section>\n    <section class='hidden-phone groups'></section>\n    <section class='hidden-phone who-to-follow'></section>\n    <section class='hidden-phone tag-trends'></section>\n</script>\n<script type=\"text/template\" id=\"HomeBody\">\n    <ul class=\"homebody-nav nav nav-justified\">\n        <li>\n            <a href=\"#timeline\">\n                <i class=\"glyphicon glyphicon-th-list\"></i> <fmt:message key=\"tatami.timeline\"/>\n            </a>\n        </li>\n        <li>\n            <a href=\"#mentions\">\n                <i class=\"glyphicon glyphicon-user\"></i> <fmt:message key=\"tatami.mentions\"/>\n            </a>\n        </li>\n        <li>\n            <a href=\"#favorites\">\n                <i class=\"glyphicon glyphicon-star\"></i> <fmt:message key=\"tatami.user.favoritestatus\"/>\n            </a>\n        </li>\n    </ul>\n    <section class=\"tatams-content tatams-margin\">\n    <@ if (!ios) { @>\n        <div class=\"tatams-content-title\">\n            <h3>\n                <@ if (tabName == 'timeline' ) { @><fmt:message key=\"tatami.timeline\"/><@ } @>\n                <@ if (tabName == 'mentions' ) { @><fmt:message key=\"tatami.mentions\"/><@ } @>\n                <@ if (tabName == 'favorites' ) { @><fmt:message key=\"tatami.user.favoritestatus\"/><@ } @>\n            </h3>\n        </div>\n    <@ } @>\n        <section class=\"tatams-container\">\n        </section>\n        <section class=\"welcome\">\n        </section>\n    </section>\n</script>\n<script type=\"text/template\" id=\"TagsBody\">\n    <section class=\"tatams-content\">\n        <@ if(ios) { @>\n        <ul class=\"homebody-nav nav nav-justified\">\n            <li>\n                <a href=\"#timeline\">\n                    <i class=\"glyphicon glyphicon-th-list\"></i> <fmt:message key=\"tatami.timeline\"/>\n                </a>\n            </li>\n        </ul>\n        <@ } @>\n        <div class=\"tatams-content-title\">\n\n        </div>\n        <section class=\"tatams-container\">\n        </section>\n    </section>\n</script>\n<script type=\"text/template\" id=\"SearchBody\">\n    <@ if(ios) { @>\n    <ul class=\"homebody-nav nav nav-justified\">\n        <li>\n            <a href=\"#timeline\">\n                <i class=\"glyphicon glyphicon-th-list\"></i> <fmt:message key=\"tatami.timeline\"/>\n            </a>\n        </li>\n    </ul>\n    <@ } @>\n    <section class=\"tatams-content\">\n        <div class=\"tatams-content-title\">\n\n        </div>\n        <section class=\"tatams-container\">\n        </section>\n    </section>\n</script>\n<script type=\"text/template\" id=\"StatusTimelineRegion\">\n    <section class='refresh-button pointer'></section>\n    <section class='timeline'></section>\n</script>\n<script type=\"text/template\" id=\"StatusUpdateButton\">\n    <@ if (count == 0) { @>\n\n    <@} else if (count == 1) { @>\n        <span class=\"badge\"><@= count @></span>\n        <fmt:message key=\"tatami.timeline.message\"/>\n    <@ } else { @>\n     <span class=\"badge\"><@= count @></span>\n        <fmt:message key=\"tatami.timeline.messages\"/>\n    <@ } @>\n</script>\n<script type=\"text/template\" id=\"Welcome\">\n    <div id=\"WelcomeModal\" class=\"modal fade\">\n        <div class=\"modal-dialog\">\n            <div class=\"modal-content\">\n                <div class=\"modal-header\">\n                    <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">&times;</button>\n                    <h4 class=\"modal-title\"><fmt:message key=\"tatami.welcome.title\"/></h4>\n                </div>\n                <div class=\"modal-body\">\n                    <div class=\"row\">\n                        <div class=\"col col-span6\">\n                            <img src=\"/img/welcome.jpg\" class=\"pull-left\">\n                        </div>\n                        <div class=\"col col-span6\">\n                            <br/><br/><h2><fmt:message key=\"tatami.welcome.title\"/></h2><p><fmt:message key=\"tatami.welcome.description\"/></p>\n                        </div>\n                    </div>\n                <div class=\"modal-footer\">\n                    <button type=\"button\" class=\"btn btn-default hide-welcome\" data-dismiss=\"modal\"><fmt:message key=\"tatami.form.cancel\"/></button>\n                    <button type=\"button\" class=\"btn btn-primary launch-help\"><fmt:message key=\"tatami.welcome.launch\"/></button>\n                </div>\n            </div>\n        </div>\n    </div>\n</script>\n<script type=\"text/template\" id=\"StatusEdit\">\n    <div class=\"modal-dialog\">\n        <div class=\"modal-content\">\n            <div class=\"modal-header\">\n                <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">&times;</button>\n            <h4 class=\"modal-title\"><fmt:message key=\"tatami.status.update\"/></h4>\n        </div>\n        <div class=\"modal-body\">\n            <a class=\"edit-tatam-float-right\">\n                <i class=\"glyphicon glyphicon-edit close hide\" title=\"<fmt:message key=\"tatami.status.editor\"/>\"></i><i class=\"glyphicon glyphicon-eye-open close\" title=\"<fmt:message key=\"tatami.status.preview\"/>\"></i>\n            </a>\n            <fieldset class=\"edit-tatam row-fluid\">\n                <textarea name=\"content\" placeholder=\"<fmt:message key=\"tatami.status.update\"/>\" maxlength=\"750\" rows=\"5\" required=\"required\"></textarea>\n                <em>\n                    <fmt:message key=\"tatami.status.characters.left\"/>\n                    <span class=\"countstatus badge\">751</span>\n                </em>\n            </fieldset>\n            <fieldset class=\"preview-tatam row-fluid hide\">\n                <div class=\"well well-small markdown\"/>\n            </fieldset>\n            <fieldset class=\"reply row-fluid\">\n                <legend>\n                    <fmt:message key=\"tatami.status.reply\"/>\n                </legend>\n                <div class=\"tatam-reply\"/>\n            </fieldset>\n            <fieldset class=\"row-fluid\">\n                <legend>\n                    <fmt:message key=\"tatami.status.options\"/>\n                </legend>\n                    <div class=\"controls groups\">\n                        <@ if (!ie || ie > 9){ @>\n                            <div id=\"GeolocImpossible\"></div> <p></p>\n                            <div data-toggle=\"collapse\" data-target=\"#geolocalisationCheckbox\">\n                                <div class=\"controls geoLocalization\" id=\"geolocCheckboxDiv\">\n                                    <label class=\"checkbox\">\n                                    <input id=\"statusGeoLocalization\" name=\"statusGeoLocalization\" type=\"checkbox\" value=\"true\"> <span class=\"glyphicon glyphicon-map-marker\"></span> <fmt:message key=\"tatami.status.geoLocalization\"/>\n                                    </label>\n                                </div>\n                            <div id=\"geolocalisationCheckbox\" class=\"collapse\">\n                                <div id=\"basicMap\" style=\"height:250px; width:250px\"></div>\n                                    <div class=\"geolocMap\">\n                                    </div>\n                                </div>\n                            </div>\n                        <@ } @>\n                            <label class=\"control-label\"><fmt:message key=\"tatami.group.name\"/></label>\n                            <select name=\"groupId\">\n                                <option value=\"\"></option>\n                                <@ for (index in groups) { @>\n                                    <option value=\"<@= groups[index].groupId @>\" <@ if(groupId === groups[index].groupId ){ @>selected=\"selected\"<@ } @>>\n                                        <@= groups[index].name @>\n                                    </option>\n                                <@ } @>\n                            </select>\n                        </div>\n                        <@ if (!ie || ie > 9){ @>\n                        <div class=\"controls status-files\">\n                            <label>\n                                <fmt:message key=\"tatami.menu.files\"/>\n                            </label>\n                            <div class=\"attachmentBar progress progress-striped active\" style=\"display: none;\">\n                                <div class=\"bar progress-bar progress-bar-info\" style=\"width: 0%;\"></div>\n                            </div>\n                            <div class=\"dropzone well\"><fmt:message key=\"tatami.status.update.drop.file\"/></div>\n                            <input style=\"display: none;\" class=\"updateStatusFileupload\" type=\"file\" name=\"uploadFile\" data-url=\"/tatami/rest/fileupload\" multiple/>\n                            <div class=\"fileUploadResults wrap\">\n\n                            </div>\n                        </div>\n                        <@ } else { @>\n                            <label class=\"control-label\"></label>\n                            <div class=\"controlsIE\">\n\t\t\t\t\t\t\t<span class=\"hidden-label choose-label\"><fmt:message key=\"tatami.user.upload.choose\" /></span>\n                            <p><fmt:message key=\"tatami.user.upload.buttonIE-ok\" /></p>\n                                <input id=\"tatamFile\" type=\"file\" name=\"uploadFile\" data-url=\"/tatami/rest/fileuploadIE\" class=\"filestyle\" data-classButton=\"btn btn-primary\" data-input=\"false\" data-buttonText=\"\" data-icon=\"false\"/>\n                            <span class=\"glyphicon glyphicon-search ok-ko\"></span>\n                            <div class=\"fileUploadResults wrap\">\n                                <span class=\"upload-ko\"><fmt:message key=\"tatami.user.upload.buttonIE-ko\" /></span>\n                            </div>\n                        <@ } @>\n                <div class=\"controls status-private\">\n                    <label class=\"checkbox\">\n                        <input id=\"statusPrivate\" name=\"statusPrivate\" type=\"checkbox\" value=\"true\"> <span class=\"glyphicon glyphicon-lock\"></span> <fmt:message key=\"tatami.status.private\"/>\n                    </label>\n                </div>\n            </fieldset>\n        </div>\n        <div class=\"modal-footer\">\n            <a class=\"btn\" data-dismiss=\"modal\" aria-hidden=\"true\">\n                <fmt:message key=\"tatami.form.cancel\"/>\n            </a>\n            <span class=\"hidden-label submit-label\"><fmt:message key=\"tatami.form.save\"/></span>\n            <span class=\"hidden-label tatam-mandatory\"><fmt:message key=\"tatami.tatam.mandatory\"/></span>\n            <input type=\"submit\" class=\"btn btn-primary submit\" data-buttonText=\"\">\n        </div>\n    </div>\n</script>\n<script type=\"text/template\" id=\"Groups\">\n    <div class=\"well well-small\">\n        <h4 id=\"groups-list-title\">\n            <span class=\"glyphicon glyphicon-list-alt\"></span>\n            &nbsp;<fmt:message key=\"tatami.account.groups.mygroups\"/>\n        </h4>\n        <div class=\"items\">\n        </div>\n    </div>\n</script>\n<script type=\"text/template\" id=\"GroupItems\">\n    <a href=\"#groups/<@= groupId @>\"><@= name @></a>\n</script>\n<script type=\"text/template\" id=\"StatusAttachmentItems\">\n        <a href=\"/tatami/file/<@= attachmentId @>/<@= filename @>\" class=\"btn-link status-action\" target=\"_blank\">\n            <i class=\"glyphicon glyphicon-file\"></i> <@= filename @>\n        </a>\n</script>\n<script type=\"text/template\" id=\"search-category\">\n    <@ if(cat.category == 'tags') {@>\n        <li class=\"category <@= cat.category @>\"><span class=\"glyphicon glyphicon-tags\"></span></li>\n    <@} else if(cat.category == 'users') { @>\n        <li class=\"category <@= cat.category @>\"><span class=\"glyphicon glyphicon-user\"></span></li>\n    <@} else { @>\n        <li class=\"category <@= cat.category @>\"><span class=\"glyphicon glyphicon-th-large\"></span></i></li>\n    <@}@>\n</script>\n<script type=\"text/template\" id=\"search-category-item\">\n    <@ if(item.category == 'tags') {@>\n        <li class=\"item tags\" data-value=\"<@= item.label @>\">\n            <a href=\"#\"><@= item.label @></a>\n        </li>\n    <@} else if(item.category == 'users') { @>\n        <li class=\"item users background-image-fffix\" data-value=\"<@= item.label @>\">\n            <div class=\"img img-rounded img-small\" style=\"background-image: url(<@= item.avatarURL @>);\" />\n            <h4><a href=\"#\"><@= item.fullName @></a></h4>\n            <p><@= item.label @></p>\n            <@ if(!item.activated) { @><span class=\"\"><i><fmt:message key=\"tatami.user.desactivate.msg2\"/></i></span><@ } @>\n        </li>\n    <@} else if(item.label) { @>\n        <li class=\"item groups background-image-fffix\" data-value=\"<@= item.label @>\" rel=\"<@= item.id @>\">\n            <h4 class=\"smallPaddingLeft\"><a href=\"#\"><@= item.label @></a></h4>\n            <p><@= item.nb @> <fmt:message key=\"tatami.group.counter\"/></p>\n        </li>\n    <@}@>\n</script>\n<script type=\"text/template\" id=\"ProfileActions\">\n</script>\n<script type=\"text/template\" id=\"ProfileStats\">\n    <div class=\"well well-small\">\n        <h4>\n            <span class=\"glyphicon glyphicon-signal\"></span>\n            <fmt:message key=\"tatami.statistics\"/>\n        </h4>\n\n        <div>\n            <p>\n                <strong>\n                    <fmt:message key=\"tatami.badge.status\"/> :\n                </strong>\n                <a href=\"#users/<@= username @>\">\n                    <span class=\"badge\"><@= statusCount @></span>\n                </a>\n            </p>\n\n            <p>\n                <strong>\n                    <fmt:message key=\"tatami.badge.followed\"/> :\n                </strong>\n                <a href=\"#users/<@= username @>/friends\">\n                    <span class=\"badge\"><@= friendsCount @></span>\n                </a>\n            </p>\n\n            <p>\n                <strong>\n                    <fmt:message key=\"tatami.badge.followers\"/> :\n                </strong>\n                <a href=\"#users/<@= username @>/followers\">\n                    <span class=\"badge\"><@= followersCount @></span>\n                </a>\n            </p>\n        </div>\n    </div>\n</script>\n<script type=\"text/template\" id=\"ProfileInformations\">\n    <h4 class=\"profile-card background-image-fffix\">\n        <div class=\"img img-rounded img-big\" style=\"background-image: url(<@= avatarURL @>);\" />\n    </h4>\n    <div class=\"well well-small\">\n        <h4>\n            <span class=\"glyphicon glyphicon-user\"></span>\n            <fmt:message key=\"tatami.user.informations\"/>\n        </h4>\n\n        <p>\n            <strong>\n                <fmt:message key=\"tatami.user.firstName\"/> :\n            </strong>\n            <@= firstName @>\n        </p>\n\n        <p>\n            <strong>\n                <fmt:message key=\"tatami.user.lastName\"/> :\n            </strong>\n            <@= lastName @>\n        </p>\n\n        <p>\n            <strong>\n                <fmt:message key=\"tatami.user.email\"/> :\n            </strong>\n            <@= login @>\n        </p>\n\n        <p>\n            <strong>\n                <fmt:message key=\"tatami.user.jobTitle\"/> :\n            </strong>\n            <@= jobTitle @>\n        </p>\n\n        <p>\n            <strong>\n                <fmt:message key=\"tatami.user.phoneNumber\"/> :\n            </strong>\n            <@= phoneNumber @>\n        </p>\n    </div>\n</script>\n<script type=\"text/template\" id=\"ProfileSide\">\n    <section class=\"actions\"/>\n    <section class=\"hidden-phone informations\"/>\n    <section class=\"hidden-phone stats\"/>\n    <section class=\"hidden-phone tagTrends\"/>\n</script>\n<script type=\"text/template\" id=\"TagTrendsProfile\">\n    <div class=\"well well-small\">\n        <h4>\n            <span class=\"glyphicon glyphicon-fire\"></span>\n            &nbsp;<fmt:message key=\"tatami.trends.title\"/>\n        </h4>\n        <div class=\"items\">\n        </div>\n    </div>\n</script>\n<script type=\"text/template\" id=\"ProfileBody\">\n    <@ if(ios) { @>\n    <ul class=\"homebody-nav nav nav-justified\">\n        <li>\n            <a href=\"#timeline\">\n                <i class=\"glyphicon glyphicon-th-list\"></i> <fmt:message key=\"tatami.timeline\"/>\n            </a>\n        </li>\n    </ul>\n    <@ } @>\n    <ul class=\"homebody-nav nav nav-tabs-inverse nav-justified\">\n        <li class=\"timeline\">\n            <a href=\"#users/<@= user @>\">\n                <i class=\"glyphicon glyphicon-th-list\"></i> <fmt:message key=\"tatami.badge.status\"/>\n            </a>\n        </li>\n        <li class=\"friends\">\n            <a href=\"#users/<@= user @>/friends\">\n                <i class=\"glyphicon glyphicon-upload\"></i> <fmt:message key=\"tatami.badge.followed\"/>\n            </a>\n        </li>\n        <li class=\"followers\">\n            <a href=\"#users/<@= user @>/followers\">\n                <i class=\"glyphicon glyphicon-download\"></i> <fmt:message key=\"tatami.badge.followers\"/>\n            </a>\n        </li>\n    </ul>\n    <section class=\"tatams-content tatams-margin\">\n        <div class=\"tatams-content-title\">\n\n        </div>\n        <section class=\"tatams-container\">\n        </section>\n    </section> \n</script>\n<script type=\"text/template\" id=\"GroupsBody\">\n    <@ if(ios) { @>\n    <ul class=\"homebody-nav nav nav-justified\">\n        <li>\n            <a href=\"#timeline\">\n                <i class=\"glyphicon glyphicon-th-list\"></i> <fmt:message key=\"tatami.timeline\"/>\n            </a>\n        </li>\n    </ul>\n    <@ } @>\n    <ul class=\"homebody-nav nav nav-tabs-inverse nav-justified\">\n        <li class=\"timeline\">\n            <a href=\"#groups/<@= group @>\">\n                <i class=\"glyphicon glyphicon-th-list\"></i> <fmt:message key=\"tatami.badge.status\"/>\n            </a>\n        </li>\n        <li class=\"members\">\n            <a href=\"#groups/<@= group @>/members\">\n                <i class=\"glyphicon glyphicon-user\"></i> <fmt:message key=\"tatami.group.members.list\"/>\n            </a>\n        </li>\n    </ul>\n    <section class=\"tatams-content tatams-margin\">\n        <div class=\"tatams-content-title\">\n\n        </div>\n        <section class=\"tatams-container\">\n        </section>\n    </section> \n</script>\n<script type=\"text/template\" id=\"UserItems\">\n    <div class='pull-left background-image-fffix'>\n        <div class=\"img img-rounded img-medium\" style=\"background-image: url(<@= avatarURL @>);\" />\n    </div>\n    <h4>\n       <@  if(!activated) { @>\n        <span>\n            <span class=\"glyphicon glyphicon-off\">\n               <fmt:message key=\"tatami.user.desactivate.msg\"/>\n            </span>\n        </span>\n        <@ } @>\n        <@ if(!you) { @>\n            <span class=\"toggleFriend pointer pull-right label <@ if(friend) { @>label-info<@ } @>\">\n                <span class=\"glyphicon glyphicon-<@= (friend)? 'minus':'plus'@>\"></span>\n            </span>\n        <@ } @>\n        <a href=\"/tatami/home/#/users/<@= username @>\">\n            <strong>\n                <@= fullName @>\n            </strong>\n        </a>\n        <br>\n        <a href=\"/tatami/home/#/users/<@= username @>\">\n            <small>\n                @<@= username @>\n            </small>\n        </a>\n        <@ if(desactivable) { @>\n        <sec:authorize ifAnyGranted=\"ROLE_ADMIN\">\n            <span class=\"desactivateUser pointer pull-right label label-<@ if(activated) { @>danger<@ } else {@>success<@} @>\">\n              <span class=\"glyphicon glyphicon-<@= (activated)? 'minus':'plus'@>\">\n                  <@= (activated)? '<fmt:message key=\"tatami.user.desactivate\"/>':'<fmt:message key=\"tatami.user.activate\"/>'@>\n              </span>\n            </span>\n        </sec:authorize>\n        <@ } @>\n    </h4>\n</script>\n<script type=\"text/template\" id=\"UserItemsMini\">\n    <div class='pull-left background-image-fffix'>\n        <div class=\"img img-rounded img-small\" style=\"background-image: url(<@= avatarURL @>);\" />\n    </div>\n    <h6>\n        <@ if(!you) { @>\n            <span class=\"toggleFriend pointer pull-right label <@ if(friend) { @>label-info<@ } @>\">\n                <span class=\"glyphicon glyphicon-<@= (friend)? 'minus':'plus'@>\"></span>\n            </span>\n        <@ } @>\n        <@ if(fullName){ @>\n            <a href=\"#users/<@= username @>\">\n                <strong>\n                    <@= fullName @>\n                </strong>\n            </a>\n            <br>\n        <@ } @>\n        <a href=\"#users/<@= username @>\">\n            <small>\n                @<@= username @>\n            </small>\n        </a>\n    </h6>\n</script>\n<script type=\"text/template\" id=\"WhoToFollow\">\n    <div class=\"well well-small\">\n        <h4 id=\"follow-suggest-title\">\n            <span class=\"glyphicon glyphicon-random\"></span>\n            &nbsp;<fmt:message key=\"tatami.follow.suggestions\"/>\n        </h4>\n        <div class=\"items\">\n        </div>\n    </div>\n</script>\n\n<script type=\"text/html\" id=\"TagsListTemplate\">\n    <table class=\"table noCollapse\">\n         <tr>\n            <th style=\"border-top :0\"><fmt:message key=\"tatami.tag\"/></th>\n            <th style=\"border-top :0\" />\n         </tr>\n        <tbody class=\"items\">\n        </tbody>\n    </table>\n\n</script>\n\n<script type=\"text/html\" id=\"GroupsSuscribeTemplate\">\n    <table class=\"table noCollapse\">\n        <tr>\n            <th style=\"border-top :0\"><fmt:message key=\"tatami.group.name\"/></th>\n            <th style=\"border-top :0\"><fmt:message key=\"tatami.group.add.access\"/></th>\n            <th style=\"border-top :0\"><fmt:message key=\"tatami.group.counter\"/></th>\n            <th style=\"border-top :0\"></th>\n        </tr>\n        <tbody class=\"items\">\n        </tbody>\n    </table>\n</script>\n\n<script type=\"text/html\" id=\"UserGroupList\">\n    <table class=\"table noCollapse\">\n        <tr>\n            <th style=\"border-top :0\"><fmt:message key=\"tatami.username\"/></th>\n            <th style=\"border-top :0\"><fmt:message key=\"tatami.group.role\"/></th>\n            <th style=\"border-top :0\"></th>\n        </tr>\n        <tbody class=\"items\">\n        </tbody>\n    </table>\n\n</script>"
  },
  {
    "path": "web/src/main/webapp/WEB-INF/pages/includes/topavatar.jsp",
    "content": "\n<%@ taglib prefix=\"fmt\" uri=\"http://java.sun.com/jsp/jstl/fmt\" %>\n<%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\" %>\n\n<div class=\"nomargin well row avatar-float-left-container\">\n    <div class=\"col-span-5 text-center\">\n        <a href=\"/tatami/home/users/${user.username}/\">\n            <c:if test=\"${empty user.avatar}\">\n                <img class=\"pull-left nomargin avatar avatar-float-left\" src=\"/img/default_image_profile.png\" alt=\"\">\n            </c:if>\n            <c:if test=\"${not empty user.avatar}\">\n                <img class=\"pull-left nomargin avatar avatar-float-left\" src=\"/tatami/avatar/${user.avatar}/photo.jpg\" alt=\"\">\n            </c:if>\n            <h3 class=\"user-profile\">${user.firstName} ${user.lastName}</h3>\n            <p>@${user.username}</p>\n        </a>\n    </div>\n</div>"
  },
  {
    "path": "web/src/main/webapp/WEB-INF/pages/includes/topmenu.jsp",
    "content": "<%@ taglib prefix=\"sec\" uri=\"http://www.springframework.org/security/tags\" %>\n<%@ taglib prefix=\"fmt\" uri=\"http://java.sun.com/jsp/jstl/fmt\" %>\n<%@ taglib prefix=\"c\" uri=\"http://java.sun.com/jsp/jstl/core\" %>\n\n<c:if test=\"${ios == null || !ios}\">\n    <div id=\"navbar\" class=\"navbar noRadius\">\n        <button type=\"button\" class=\"navbar-toggle collapsed\" data-toggle=\"collapse\" data-target=\".navbar-responsive-collapse\">\n            <span class=\"icon-bar\"></span>\n            <span class=\"icon-bar\"></span>\n            <span class=\"icon-bar\"></span>\n        </button>\n        <a class=\"navbar-brand\" href=\"/tatami/home\">\n            <img src=\"/img/company-logo.png\" alt=\"<fmt:message key=\"tatami.logo\"/>\">\n            <fmt:message key=\"tatami.title\"/>\n        </a>\n    <c:if test=\"${currentPage != null && currentPage == 'home'}\">\n        <button type=\"button\" class=\"editTatam btn btn-primary navbar-toggle navbar-edit\">\n            <i class=\"close glyphicon glyphicon-pencil\"></i>\n        </button>\n    </c:if>\n        <div class=\"nav-collapse navbar-responsive-collapse collapse\">\n            <ul class=\"nav\">\n                <li>\n                    <c:if test=\"${currentPage != null && currentPage == 'home'}\">\n                      <a href=\"#/home/timeline\">\n                    </c:if>\n                    <c:if test=\"${currentPage == null || currentPage != 'home'}\">\n                      <a href=\"/tatami/home/timeline\">\n                    </c:if>\n                    <span>\n                        <span class=\"glyphicon glyphicon-th-list\"></span>\n                        <span class=\"hidden-tablet\">\n                            <fmt:message key=\"tatami.timeline\"/>\n                        </span>\n                    </span>\n                    </a>\n                </li>\n                <li class=\"dropdown pointer\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\">\n                    <span>\n                        <span class=\"glyphicon glyphicon-info-sign\"></span>\n                        <span class=\"hidden-tablet\">\n                            <fmt:message key=\"tatami.menu.about\"/>\n                        </span>\n                        <b class=\"caret\"></b>\n                    </span>\n                    </a>\n                    <ul class=\"dropdown-menu closed\">\n                        <li>\n                            <a href=\"/tatami/presentation\">\n                                <span class=\"glyphicon glyphicon-eye-open\"></span>\n                                <fmt:message key=\"tatami.menu.presentation\"/>\n                            </a>\n                        </li>\n                        <li>\n                            <a href=\"/tatami/tos\">\n                                <span class=\"glyphicon glyphicon-briefcase\"></span>\n                                <fmt:message key=\"tatami.menu.tos\"/>\n                            </a>\n                        </li>\n                        <li class=\"dropdown-submenu\">\n                            <a>\n                                <span class=\"glyphicon glyphicon-flag\"></span>\n                                <fmt:message key=\"tatami.menu.language\"/>\n                            </a>\n                            <ul class=\"dropdown-menu\">\n                                <li>\n                                    <a href=\"?language=en\">\n                                        <fmt:message key=\"tatami.menu.language.en\"/>\n                                    </a>\n                                </li>\n                                <li>\n                                    <a href=\"?language=fr\">\n                                        <fmt:message key=\"tatami.menu.language.fr\"/>\n                                    </a>\n                                </li>\n                            </ul>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"/tatami/license\">\n                                <span class=\"glyphicon glyphicon-info-sign\"></span>\n                                <fmt:message key=\"tatami.menu.license\"/>\n                            </a>\n                        </li>\n                        <li>\n                            <a href=\"https://github.com/ippontech/tatami/issues\" target=\"_blank\">\n                                <span class=\"glyphicon glyphicon-inbox\"></span>\n                                <fmt:message key=\"tatami.github.issues\"/>\n                            </a>\n                        </li>\n                        <li>\n                            <a href=\"https://github.com/ippontech/tatami\" target=\"_blank\">\n                                <span class=\"glyphicon glyphicon-wrench\"></span>\n                                <fmt:message key=\"tatami.github.fork\"/>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"http://www.ippon.fr/\" target=\"_blank\">\n                                <span class=\"glyphicon glyphicon-exclamation-sign\"></span>\n                                <fmt:message key=\"tatami.ippon.website\"/>\n                            </a>\n                        </li>\n                        <li>\n                            <a href=\"http://blog.ippon.fr/\" target=\"_blank\">\n                                <span class=\"glyphicon glyphicon-pencil\"></span>\n                                <fmt:message key=\"tatami.ippon.blog\"/>\n                            </a>\n                        </li>\n                        <li>\n                            <a href=\"https://twitter.com/ippontech\" target=\"_blank\">\n                                <span class=\"glyphicon glyphicon-bullhorn\"></span>\n                                <fmt:message key=\"tatami.ippon.twitter.follow\"/>\n                            </a>\n                        </li>\n                    </ul>\n                </li>\n            </ul>\n\n            <c:if test=\"${currentPage != null && currentPage == 'home'}\">\n            <sec:authorize ifAnyGranted=\"ROLE_USER\">\n            <ul class=\"nav pull-right\">\n                <li class=\"dropdown pointer\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\">\n                    <span>\n                        <span class=\"glyphicon glyphicon-user\"></span>\n                        <span class=\"hidden-tablet\">\n                            <fmt:message key=\"tatami.menu.account\"/>\n                        </span>\n                        <b class=\"caret\"></b>\n                    </span>\n                    </a>\n                    <ul class=\"dropdown-menu\">\n                        <li>\n                            <a href=\"/tatami/account/#/profile\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                <fmt:message key=\"tatami.menu.profile\"/>\n                            </a>\n                        </li>\n                        <li>\n                            <a href=\"/tatami/account/#/preferences\">\n                                <span class=\"glyphicon glyphicon-picture\"></span>\n                                <fmt:message key=\"tatami.menu.preferences\"/>\n                            </a>\n                        </li>\n                        <li>\n                            <a href=\"/tatami/account/#/password\">\n                                <span class=\"glyphicon glyphicon-lock\"></span>\n                                <fmt:message key=\"tatami.menu.password\"/>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"/tatami/account/#/files\">\n                                <span class=\"glyphicon glyphicon-file\"></span>\n                                <fmt:message key=\"tatami.menu.files\"/>\n                            </a>\n                            <a href=\"/tatami/account/#/users\">\n                                <span class=\"glyphicon glyphicon-globe\"></span>\n                                <fmt:message key=\"tatami.menu.directory\"/>\n                            </a>\n                            <a href=\"/tatami/account/#/groups\">\n                                <span class=\"glyphicon glyphicon-th-large\"></span>\n                                <fmt:message key=\"tatami.menu.groups\"/>\n                            </a>\n                            <a href=\"/tatami/account/#/tags\">\n                                <span class=\"glyphicon glyphicon-tags\"></span>\n                                <fmt:message key=\"tatami.menu.tags\"/>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"/tatami/account/#/status_of_the_day\">\n                                <span class=\"glyphicon glyphicon-signal\"></span>\n                                <fmt:message key=\"tatami.menu.status.of.the.day\"/>\n                            </a>\n                            <a href=\"/tatami/home#company\">\n                                <span class=\"glyphicon glyphicon-briefcase\"></span>\n                                <fmt:message key=\"tatami.menu.company.wall\"/>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a href=\"/tatami/logout\">\n                                <span class=\"glyphicon glyphicon-off\"></span>\n                                <fmt:message key=\"tatami.logout\"/>\n                            </a>\n                        </li>\n                    </ul>\n                </li>\n                <li class=\"hidden-phone\">\n                    <button id=\"editTatam\" class=\"editTatam btn btn-primary navbar-form\">\n                        <i class=\"glyphicon glyphicon-pencil\"></i>\n                        <span class=\"visible-desktop\">\n                            <fmt:message key=\"tatami.tatam.publish\"/>\n                        </span>\n                    </button>\n                </li>\n            </ul>\n            <ul class=\"nav pull-right\">\n                <li>\n                    <a href=\"#\" id=\"help-tour\">\n                        <span>\n                            <span class=\"glyphicon glyphicon-question-sign\"></span>\n                            <span class=\"hidden-tablet\">\n                                <fmt:message key=\"tatami.status.help.title\"/>\n                            </span>\n                        </span>\n                    </a>\n                </li>\n            </ul>\n            <form id=\"searchform\" class=\"navbar-form pull-right col-span-4\" action=\"\">\n                <input name=\"search\" type=\"text\" class=\"col-span-12\" id=\"searchinput\" placeholder=\"<fmt:message key=\"tatami.search.placeholder\"/>\" autocomplete=\"off\">\n                <span class=\"deleteicon\"><i class=\"glyphicon glyphicon-remove-sign\"></i></span>\n            </form>\n            </sec:authorize>\n            </c:if>\n        </div>\n    </div>\n</c:if>"
  },
  {
    "path": "web/src/main/webapp/WEB-INF/pages/login.jsp",
    "content": "<%@ page language=\"java\" pageEncoding=\"UTF-8\" contentType=\"text/html; charset=utf-8\" %>\n<html>\n<head>\n    <title></title>\n    <script type=\"text/javascript\">window.location.href = '<%=request.getContextPath()%>/#/login'</script>\n</head>\n<body>\nIf you are not redirected automatically, click\n<a href=\"<%=request.getContextPath()%>/#/login\">here</a>.\n</body>\n</html>"
  },
  {
    "path": "web/src/main/webapp/WEB-INF/web.xml",
    "content": "<web-app xmlns=\"http://java.sun.com/xml/ns/javaee\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd\"\n         version=\"3.0\"\n         metadata-complete=\"true\">\n\n    <!--\n     Remove classpath scanning (from servlet 3.0) in order to speed jetty startup :\n     metadata-complete=\"true\" above + empty absolute ordering below\n     -->\n    <absolute-ordering>\n        <!--\n           Empty absolute ordering is necessary to completely desactivate classpath scanning\n            -->\n    </absolute-ordering>\n\n    <display-name>Tatami</display-name>\n\n    <!-- All the Servlets and Filters are configured by this ServletContextListener : -->\n    <listener>\n        <listener-class>fr.ippon.tatami.web.init.WebConfigurer</listener-class>\n    </listener>\n\n    <filter>\n        <filter-name>GzipFilter</filter-name>\n        <filter-class>fr.ippon.tatami.web.filter.TatamiGzipFilter</filter-class>\n    </filter>\n    \n    <filter>\n    \t<filter-name>CharacterEncodingFilter</filter-name>\n    \t<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>\n    \t<init-param>\n    \t\t<param-name>encoding</param-name>\n    \t\t<param-value>UTF-8</param-value>\n    \t</init-param>\n    \t<init-param>\n    \t\t<param-name>forceEncoding</param-name>\n    \t\t<param-value>true</param-value>\n    \t</init-param>\n    </filter>\n    \n    <filter-mapping>\n    \t<filter-name>CharacterEncodingFilter</filter-name>\n    \t<url-pattern>/*</url-pattern>\n    </filter-mapping>\n\n    <filter-mapping>\n        <filter-name>GzipFilter</filter-name>\n        <url-pattern>/*</url-pattern>\n    </filter-mapping>\n\n    <error-page>\n        <error-code>500</error-code>\n        <location>/tatami/errors/500</location>\n    </error-page>\n\n    <error-page>\n        <error-code>404</error-code>\n        <location>/tatami/errors/404</location>\n    </error-page>\n\n</web-app>"
  },
  {
    "path": "web/src/main/webapp/app/TatamiApp.js",
    "content": "var TatamiApp = angular.module('TatamiApp', [\n    'TopMenuModule',\n    'LoginModule',\n    'HomeModule',\n    'AccountModule',\n    'AboutModule',\n    'AdminModule',\n    'FooterModule',\n    'ngResource',\n    'ngTouch',\n    'ngCookies',\n    'pascalprecht.translate',\n    'ui.router',\n    'ui.bootstrap',\n    'mentio',\n    'LocalStorageModule',\n    'bm.bsTour',\n    'TatamiApp.services'\n]);\n\nTatamiApp.run(['$rootScope', '$state', function($rootScope, $state) {\n    $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState) {\n        if($state.includes('tatami.home') && toState !== fromState) {\n            document.body.scrollTop = document.documentElement.scrollTop = 0;\n        }\n    });\n}]);\n\nTatamiApp.run(['$rootScope', '$state', '$stateParams', 'AuthenticationService', 'UserSession', function($rootScope, $state, $stateParams, AuthenticationService, UserSession) {\n    // Make state information available to $rootScope, and thus $scope in our controllers\n    $rootScope.$state = $state;\n    $rootScope.$stateParams = $stateParams;\n\n    // When the app is started, determine if the user is authenticated, if so, send them to home timeline\n    UserSession.authenticate().then(function(result) {\n        if(result !== null) {\n            // We aren't logged in, clear the old session, and send the user to the login page\n            if(result.action === null) {\n                if(angular.isDefined($state.current.data) && !$state.current.data.public) {\n                    UserSession.clearSession();\n                    $state.go('tatami.login.main');\n                }\n                // If we are trying to access a state that is public, allow user\n                if(angular.isDefined($rootScope.destinationState)) {\n                    $state.go($rootScope.destinationState, $rootScope.destinationParams);\n                }\n                else {\n                    // The destination state is undefined -- This is the first time accessing the site\n                    UserSession.clearSession();\n                    $state.go('tatami.login.main');\n                }\n            }\n\n            // We are logged in, but the session hasn't been set, so we set it\n            if(angular.isDefined(result.username)) {\n                if(!UserSession.isAuthenticated()) {\n                    UserSession.setLoginState(true);\n                }\n                // If there is no destination state, send user to timeline, since they are logged in\n                if(!angular.isDefined($rootScope.destinationState)) {\n                    $state.go('tatami.home.home.timeline');\n                }\n            }\n        }\n        else {\n            $state.go('tatami.login.main');\n        }\n    });\n\n    $rootScope.$on('$stateChangeError', function(event) {\n        event.preventDefault();\n        $state.transitionTo('tatami.login.main', null, { location: false });\n    });\n\n    $rootScope.$on('$stateChangeStart', function(event, toState, toStateParams) {\n        $rootScope.destinationState = toState;\n        $rootScope.destinationParams = toStateParams;\n\n        // If the user is logged in, we allow them to go where they intend to\n        if(UserSession.isAuthenticated()) {\n            return;\n        }\n\n        if(toState.data && toState.data.public) {\n            return;\n        }\n\n        // The user is not logged in, and trying to access a state that requires them to be logged in\n        // Stash the state they tried to access\n        $rootScope.returnToState = toState;\n        $rootScope.returnToParams = toStateParams;\n\n        // Go to login page\n        event.preventDefault();\n        $state.go('tatami.login.main');\n    });\n}]);\n\nTatamiApp.config(['$resourceProvider', '$locationProvider', '$urlRouterProvider', '$stateProvider',\n    function($resourceProvider, $locationProvider, $urlRouterProvider, $stateProvider) {\n\n        // Don't strip trailing slashes from REST URLs\n        $resourceProvider.defaults.stripTrailingSlashes = false;\n\n        $stateProvider\n            .state('tatami', {\n                url: '',\n                abstract: true,\n                views: {\n                    'topMenu@': {\n                        templateUrl: 'app/shared/topMenu/TopMenuView.min.html',\n                        controller: 'TopMenuController'\n                    },\n                    '': {\n                        templateUrl: 'index.html'\n                    },\n                    'footer@': {\n                        templateUrl: 'app/shared/footer/FooterView.min.html',\n                        controller: 'FooterController'\n                    }\n                },\n                resolve: {\n                    authorize: ['AuthenticationService', function(AuthenticationService) {\n                        return AuthenticationService.authenticate();\n                    }]\n                },\n                data: {\n                    public: false,\n                    roles: [\"ROLE_USER\"]\n                }\n            })\n            .state('tatami.pageNotFound', {\n                templateUrl: 'app/shared/error/404View.min.html',\n                data: {\n                    public: true\n                }\n            })\n            .state('tatami.accessdenied', {\n                templateUrl: 'app/shared/error/500View.min.html',\n                data: {\n                    public: true\n                }\n            });\n}]);\n"
  },
  {
    "path": "web/src/main/webapp/app/components/about/AboutModule.js",
    "content": "var AboutModule = angular.module('AboutModule', []);\n\nAboutModule.config(['$stateProvider', function($stateProvider) {\n\n    $stateProvider\n        .state('tatami.about',{\n            url: '/about',\n            abstract: true,\n            templateUrl: 'app/components/about/AboutView.html'\n        })\n        .state('tatami.about.presentation', {\n            url: '/presentation',\n            views: {\n                'aboutBody': {\n                    templateUrl: 'app/components/about/presentation/PresentationView.min.html'\n                }\n            },\n            data: {\n                public: true\n            }\n        })\n        .state('tatami.about.tos', {\n            url: '/tos',\n            views: {\n                'aboutBody': {\n                    templateUrl: 'app/components/about/tos/ToSView.min.html'\n                }\n            },\n            data: {\n                public: true\n            }\n        })\n        .state('tatami.about.license', {\n            url: '/license',\n            views: {\n                'aboutBody': {\n                    templateUrl: 'app/components/about/license/LicenseView.min.html',\n                    controller: 'LicenseController'\n                }\n            },\n            data: {\n                public: true\n            }\n        });\n\n}]);\n"
  },
  {
    "path": "web/src/main/webapp/app/components/about/AboutView.html",
    "content": "<div ui-view=\"aboutBody\" id=\"mainPanel\" class=\"container\"></div>"
  },
  {
    "path": "web/src/main/webapp/app/components/about/license/LicenseController.js",
    "content": "AboutModule.controller('LicenseController', ['$scope',\n    function($scope) {\n        $scope.time=\" 2012-\"+new Date().getFullYear()+\" \";\n        $(\"#endYear\").html($scope.time);\n    }\n]);"
  },
  {
    "path": "web/src/main/webapp/app/components/about/license/LicenseView.html",
    "content": "<div class=\"col-offset-2 col-span-8\">\n    <h1 translate=\"tatami.about.license.title\"></h1>\n    <p>\n        <span translate=\"tatami.about.license.copyright\"></span>&copy;<ins id=\"endYear\"> 2012 </ins>\n        <a href=\"http://www.ippon.fr\">Ippon Technologies</a>\n    </p>\n    <p>Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this application except in compliance with the License. You may obtain a copy of the License at</p>\n    <p>\n        <a href=\"https://www.apache.org/licenses/LICENSE-2.0\"></a>\n        <a href=\"https://www.apache.org/licenses/LICENSE-2.0\">https://www.apache.org/licenses/LICENSE-2.0</a>\n    </p>\n    <p>Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.</p>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/about/presentation/PresentationView.html",
    "content": "<div class=\"row\">\n    <div class=\"offset2 span8\">\n        <h1 translate=\"tatami.about.presentation.title\"></h1>\n        <br><br>\n    </div>\n</div>\n<div class=\"row\">\n    <div class=\"col-span-4\"><img src=\"/assets/img/presentation_tatami.jpg\" width=\"400\" height=\"267\" title=\"Tatami\"></div>\n    <div class=\"col-span-8\">\n        <br>\n        <p>\n        <h2 translate=\"tatami.about.presentation.row1.title\"></h2>\n        </p>\n        <ul>\n            <li translate=\"tatami.about.presentation.row1.line1\"></li>\n            <li translate=\"tatami.about.presentation.row1.line2\"></li>\n            <li translate=\"tatami.about.presentation.row1.line3\"></li>\n            <li translate=\"tatami.about.presentation.row1.line4\"></li>\n            <li translate=\"tatami.about.presentation.row1.line5\"></li>\n            <li translate=\"tatami.about.presentation.row1.line6\"></li>\n            <li translate=\"tatami.about.presentation.row1.line7\"></li>\n            <li translate=\"tatami.about.presentation.row1.line8\"></li>\n            <li translate=\"tatami.about.presentation.row1.line9\"></li>\n        </ul>\n    </div>\n</div>\n<div class=\"row\">\n    <div class=\"col-span-8\">\n        <br>\n        <br>\n        <br>\n        <p>\n        <h2 translate=\"tatami.about.presentation.row2.title\"></h2>\n        </p>\n        <ul>\n            <li translate=\"tatami.about.presentation.row2.line1\"></li>\n            <li translate=\"tatami.about.presentation.row2.line2\"></li>\n            <li translate=\"tatami.about.presentation.row2.line3\"></li>\n        </ul>\n    </div>\n    <div class=\"col-span-4\"><img src=\"/assets/img/presentation_devices.jpg\" width=\"200\" height=\"267\" title=\"{{ 'tatami.about.presentation.devices' | translate }}\"></div>\n</div>\n<div class=\"row\">\n    <br>\n    <br>\n    <br>\n    <div class=\"col-span-8\"><img src=\"/assets/img/presentation_opensource.jpg\" width=\"250\" height=\"216\" title=\"{{ 'tatami.about.presentation.openSource' | translate }}\"></div>\n    <div class=\"col-span-4\">\n        <p>\n        <h2 translate=\"tatami.about.presentation.row3.title\"></h2>\n        </p>\n        <ul>\n            <li translate=\"tatami.about.presentation.row3.line1\"></li>\n            <li translate=\"tatami.about.presentation.row3.line2\"></li>\n            <li translate=\"tatami.about.presentation.row3.line3\"></li>\n            <li translate=\"tatami.about.presentation.row3.line4\"></li>\n            <li translate=\"tatami.about.presentation.row3.line5\"></li>\n            <li translate=\"tatami.about.presentation.row3.line6\"></li>\n            <li translate=\"tatami.about.presentation.row3.line7\"></li>\n            <li>\n                <span translate=\"tatami.about.presentation.row3.line8\"></span>\n                <a href=\"https://github.com/ippontech/tatami\">https://github.com/ippontech/tatami</a>\n            </li>\n        </ul>\n    </div>\n</div>\n<br>\n<br>\n<div class=\"row\">\n    <div class=\"col-span-8\">\n        <p>\n        <h2 translate=\"tatami.about.presentation.row4.title\"></h2>\n        </p>\n        <ul>\n            <li>\n                <span translate=\"tatami.about.presentation.row4.line1\"></span>\n                <a href=\"https://tatami.ippon.fr\">https://tatami.ippon.fr</a>\n            </li>\n            <li translate=\"tatami.about.presentation.row4.line2\"></li>\n            <li translate=\"tatami.about.presentation.row4.line3\"></li>\n        </ul>\n    </div>\n    <div class=\"col-span-4\"><img src=\"/assets/img/company-logo-bookmark.png\" width=\"150\" height=\"148\" title=\"{{ 'tatami.menu.logo' | translate }}\"></div>\n</div>\n<div class=\"row\">\n    <div class=\"col-span-12\">\n        <p>\n        <h2 translate=\"tatami.about.presentation.row5.title\"></h2>\n        </p>\n        <ul>\n            <li>\n                <span translate=\"tatami.about.presentation.row5.line1\"></span>\n                <a href=\"mailto:commercial@ippon.fr\">commercial@ippon.fr</a>\n            </li>\n        </ul>\n    </div>\n</div>\n<br>\n<br>\n<br>\n<br>"
  },
  {
    "path": "web/src/main/webapp/app/components/about/tos/ToSView.html",
    "content": "<!-- Update the link to the TOS under the General section once the AngularJS version is hosted by Ippon. -->\n\n<div>\n    <!-- class=\"col-offset-2 col-span-8\" -->\n    <h1 translate=\"tatami.about.tos.title\"></h1>\n    <h2>1 - General</h2>\n    <ol>\n        <li>By using any of the Ippon Technologies products, software, or services available at *.ippon.fr (collectively referred to as \"Services\") provided by Ippon Techonologies (\"Ippon\"), you agree to be bound by the following terms and conditions (\"Terms of Service\").</li>\n        <li>Ippon reserves the right to update and change the Terms of Service at any time without notice. You can review the most current version of the Terms of Service at: <a href=\"https://tatami.ippon.fr/tatami/tos\">https://tatami.ippon.fr/tatami/tos</a></li>\n        <li>The failure of Ippon to exercise or enforce any right or provision of the Terms of Service shall not constitute a waiver of such right or provision.</li>\n        <li>You agree that Ippon owns all legal rights in the Service. You must not remove, modify or obscure any legal notices. You are not entitled to use Ippon's trademarks (especially \"Ippon Technologies\"), trade names, brands, domain names, or other distinctive brand features.</li>\n        <li>Violation of any of the terms below can result in the termination of your account or access to the Services. Violation of any of the terms will also terminate your usage rights of the Services.</li>\n        <li>If a provision of this agreement is or becomes illegal, invalid or unenforceable in any jurisdiction, that shall not affect: (i) the validity or enforceability in that jurisdiction of any other provision of this agreement; or (ii) the validity or enforceability in other jurisdictions of that or any other provision of this agreement.</li>\n        <li>These Terms of Service constitute the entire agreement between you and Ippon und replace all previous agreements under this title. There are no verbal subsidiary agreements.</li>\n        <li>These Terms of Service, and your relationship with Ippon under these Terms of Service, shall be governed by the laws of France. You and Ippon agree to submit to the exclusive jurisdiction of the courts located in France to resolve any legal matter arising from the Terms of Service.</li>\n    </ol>\n    <h2>2 - Provision of the Services by Ippon Technologies</h2>\n    <ol>\n        <li>Your use of the Services is at your sole risk. The Services are provided on an \"as is\" and \"as available\" basis.</li>\n        <li>Ippon does not warrant that (i) the Services will meet your requirements or expectations, (ii) the Services will be delivered uninterrupted, timely, secure, or error-free, (iii) the results that may be obtained from the use of the Services will be accurate or reliable, (iv) any errors in the Services will be corrected.</li>\n        <li>You understand and agree that Ippon shall not be liable for any direct, indirect, incidental, special, consequential or exemplary damages, including but not limited to any loss of profit, loss of goodwill, loss of business reputation, loss of data, cost of procurement of substitute goods or Services, or other intangible loss, resulting from: (i) the use or the inability to use the Services; (ii) any changes which Ippon may make to the Services, or any permanent or temporary cessation in the provision of the Services; (iii) unauthorized access to or alteration of your transmissions or data; (iv) the deletion of, corruption of, or failure to store, any content and other communications data maintained or transmitted by or through the use of the Services; (v) or any other matter relating to the Services.</li>\n        <li>Technical support is provided on a best-effort basis and only by e-mail.</li>\n        <li>You understand that Ippon can use third parties (e.g., hosting partners) to provide the necessary resources (e.g., hardware, software, networking, storage, etc.) to run the Services.</li>\n        <li>Ippon may stop, remove, modify, or add (permanently or temporarily) Services (or features within Services) at Ippon's sole discretion. Any new, changed, or removed features are subject to the Terms of Service. Continued use of the Services after any such changes constitute your consent to the changes.</li>\n    </ol>\n    <h2>3 - Use of the Services by You</h2>\n    <ol>\n        <li>You agree to use the Services only for purposes that are permitted by (i) the Terms of Service and (ii) any applicable law, regulation or generally accepted practices or guidelines in the relevant jurisdictions.</li>\n        <li>For certain services, Ippon may offer or require you to register for an account. You ensure that all registration information you provide will always be valid, correct, and up to date. You are responsible for maintaining the security of your account and password. Accounts registered by bots or other automated methods are not permitted.</li>\n        <li>For certain services, Ippon may offer to upload your personal profile photo. You are responsible to not upload an abusive photo, to not infringe on any copyrights or trademarks, and to not use a design which other Ippon users may deem offensive.</li>\n        <li>For certain services, Ippon may offer to define a personal URL (web address). You understand that Ippon can rename or reject your personal URL, e.g., if you intentionally or unintentionally interfere with a trademark owner or because your personal URL is deemed offensive.</li>\n        <li>You agree that you will not impersonate another person.</li>\n        <li>You agree that you will not engage in any activity that interferes with or disrupts the Services (or the servers and networks which are connected to the Services).</li>\n        <li>You agree that you will not reproduce, duplicate, copy, sell, trade or resell the Services for any purpose without the express written permission by Ippon.</li>\n        <li>You agree that you are solely responsible for (and that Ippon has no responsibility to you or to any third party for) any breach of your obligations under the Terms of Service and for the consequences (including any loss or damage which Ippon may suffer) of any such breach.</li>\n        <li>Ippon reserves the right (but has no obligation) to pre-screen, review, flag, filter, modify, refuse or remove any or all content or account from any of the Services at Ippon's sole discretion. You understand that by using the Services you may be exposed to content that you may find offensive, indecent or objectionable and that, in this respect, you use the Services at your own risk.</li>\n    </ol>\n    <h2>4 - Advertisements</h2>\n    <ol>\n        <li>Some of the Services are supported by advertising revenue and may display advertisements and promotions. These advertisements may be targeted to the content of information stored on or made available to the Services.</li>\n        <li>The manner, mode and extent of advertising on the Services are subject to change without specific notice to you.</li>\n        <li>You agree that Ippon may place such advertising on the Services.</li>\n        <li>You must not block such advertising.</li>\n    </ol>\n    <h2>5 - API Terms</h2>\n    <ol>\n        <li>Any use of the application programming interface (API) is bound by the terms of this agreement plus the following specific terms:</li>\n        <li>Abuse or excessively frequent requests via the API may result in the temporary or permanent suspension of access to the API. Ippon determines abuse or excessive usage of the API at its sole discretion.</li>\n        <li>Ippon reserves the right at any time to modify or discontinue, temporarily or permanently, your access to the API (or any part thereof) with or without notice. Ippon especially reserves the right to limit the number of requests via the API to a certain upper limit per time interval.</li>\n        <li>Your use of the API is free of charge up to a certain extent. Larger amounts of API transactions will be charged.</li>\n        <li>Ippon reserves the right to change the API's pricing model at any time. In such a case, you will of course be free to discontinue using the API.</li>\n        <li>As a user of the API, you may, within your product, indicate that your product utilizes the Ippon API. At other places or in other contexts, however, you may not use either the Ippon Technologies brand name or the Ippon Technologies logo. In particular, you may not use either the Ippon Technologies brand or the Ippon Technologies logo in the name of your product.</li>\n    </ol>\n    <h4>Effective: August 7th, 2012</h4>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/account/AccountController.js",
    "content": "AccountModule.controller('AccountController', ['$scope', '$location', 'profileInfo', function($scope, $location, profileInfo) {\n    $scope.profile = profileInfo;\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/AccountModule.js",
    "content": "var AccountModule = angular.module('AccountModule', [\n    'ProfileModule',\n    'PreferencesModule',\n    'PasswordModule',\n    'FilesModule',\n    'UsersModule',\n    'GroupsModule',\n    'TagsModule',\n    'TopPostersModule',\n    'ngToast'\n]);\n\nAccountModule.config(['$stateProvider', '$urlRouterProvider', function($stateProvider) {\n    $stateProvider\n        .state('tatami.account',{\n            url: '/account',\n            abstract: true,\n            templateUrl: 'app/components/account/AccountView.min.html',\n            resolve: {\n                profileInfo: ['ProfileService', function(ProfileService) {\n                    return ProfileService.get().$promise;\n                }],\n                userRoles: ['$http', function($http) {\n                    return $http({ method: 'GET', url: '/tatami/rest/account/admin' }).then(function(result) {\n                        return result.data;\n                    });\n                }]\n            },\n            controller: 'AccountController'\n        })\n        .state('tatami.account.profile', {\n            url: '/profile',\n            templateUrl: 'app/components/account/profile/ProfileView.min.html',\n            resolve: {\n                userLogin: ['UserService', 'profileInfo', function(UserService, profileInfo) {\n                    return UserService.get({ username: profileInfo.username }).$promise;\n                }]\n            },\n            controller: 'ProfileController'\n        })\n        .state('tatami.account.preferences', {\n            url: '/preferences',\n            templateUrl: 'app/components/account/preferences/PreferencesView.min.html',\n            resolve: {\n                prefs: ['PreferencesService', function(PreferencesService) {\n                    return PreferencesService.get().$promise;\n                }]\n            },\n            controller: 'PreferencesController'\n        })\n        .state('tatami.account.password', {\n            url: '/password',\n            templateUrl: 'app/components/account/password/PasswordView.min.html',\n            controller: 'PasswordController'\n        })\n        .state('tatami.account.files', {\n            url: '/files',\n            templateUrl: 'app/components/account/files/FilesView.min.html',\n            resolve: {\n                FilesService: 'FilesService',\n                attachmentQuota: function(FilesService) {\n                    return FilesService.getQuota().$promise;\n                },\n\n                fileList: function(FilesService) {\n                    return FilesService.query().$promise;\n                }\n            },\n            controller: 'FilesController'\n        })\n        .state('tatami.account.users', {\n            url: '/users',\n            templateUrl: 'app/components/account/FormView.min.html',\n            controller: 'FormController'\n        })\n        .state('tatami.account.users.following', {\n            url: '/following',\n            templateUrl: 'app/components/account/users/UsersView.html',\n            resolve: {\n                usersList: ['profileInfo', 'UserService', function(profileInfo, UserService) {\n                    return UserService.getFollowing({ username: profileInfo.username }).$promise;\n                }]\n            },\n            controller: 'UsersController'\n        })\n        .state('tatami.account.users.recommended', {\n            url: '/recommended',\n            templateUrl: 'app/components/account/users/UsersView.min.html',\n            resolve: {\n                usersList: ['UserService', function(UserService) {\n                    UserService.getSuggestions().$promise;\n                }]\n            },\n            controller: 'UsersController'\n        })\n        .state('tatami.account.users.search', {\n            url: '/search/:q',\n            templateUrl: 'app/components/account/users/UsersView.min.html',\n            resolve: {\n                usersList: ['SearchService', '$stateParams', function(SearchService, $stateParams) {\n                    return SearchService.query({ term: 'users', q: $stateParams.q }).$promise;\n                }]\n            },\n            controller: 'UsersController'\n        })\n        .state('tatami.account.groups', {\n            url: '/groups',\n            templateUrl: 'app/components/account/FormView.min.html',\n            controller: 'FormController'\n        })\n        .state('tatami.account.groups.main', {\n            url: '',\n            templateUrl: 'app/components/account/groups/GroupsView.min.html',\n            controller: 'GroupController'\n        })\n        .state('tatami.account.groups.main.top', {\n            url: '',\n            views: {\n                'create@tatami.account.groups.main': {\n                    templateUrl: 'app/components/account/groups/creation/GroupsCreateView.min.html',\n                    controller: 'GroupsCreateController'\n                }\n            }\n        })\n        .state('tatami.account.groups.main.top.list', {\n            url: '',\n            views: {\n                'list@tatami.account.groups.main': {\n                    templateUrl: 'app/components/account/groups/list/GroupsListView.min.html',\n                    resolve: {\n                        userGroups: ['GroupService', function(GroupService) {\n                            return GroupService.query().$promise;\n                        }]\n                    },\n                    controller: 'GroupsController'\n                }\n            }\n        })\n        .state('tatami.account.groups.main.top.recommended', {\n            url: '/recommended',\n            views: {\n                'list@tatami.account.groups.main': {\n                    templateUrl: 'app/components/account/groups/list/GroupsListView.min.html',\n                    resolve: {\n                        userGroups: ['GroupService', function(GroupService) {\n                            return GroupService.getRecommendations().$promise;\n                        }]\n                    },\n                    controller: 'GroupsController'\n                }\n            }\n        })\n        .state('tatami.account.groups.main.top.search', {\n            url: '/search/:q',\n            views: {\n                'list@tatami.account.groups.main': {\n                    templateUrl: 'app/components/account/groups/list/GroupsListView.min.html',\n                    resolve: {\n                        userGroups: ['SearchService', '$stateParams', function(SearchService, $stateParams) {\n                            return SearchService.query({ term: 'groups', q: $stateParams.q }).$promise;\n                        }]\n                    },\n                    controller: 'GroupsController'\n                }\n            }\n        })\n        .state('tatami.account.groups.manage', {\n            url:'/:groupId',\n            templateUrl: 'app/components/account/groups/manage/GroupsManageView.min.html',\n            resolve: {\n                group: ['GroupService', '$stateParams', function(GroupService, $stateParams) {\n                    return GroupService.get({ groupId: $stateParams.groupId }).$promise;\n                }],\n\n                members: ['GroupService', '$stateParams', function(GroupService, $stateParams) {\n                    return GroupService.getMembers({ groupId: $stateParams.groupId }).$promise;\n                }]\n            },\n            controller:'GroupsManageController'\n        })\n        .state('tatami.account.tags', {\n            url:'/tags',\n            templateUrl: 'app/components/account/FormView.min.html',\n            controller: 'FormController'\n        })\n        .state('tatami.account.tags.following', {\n            url: '/following',\n            templateUrl: 'app/components/account/tags/TagsView.min.html',\n            resolve: {\n                tagList: ['TagService', function(TagService) {\n                    return TagService.query().$promise;\n                }]\n            },\n            controller: 'TagsController'\n        })\n        .state('tatami.account.tags.trends', {\n            url: '/trends',\n            templateUrl: 'app/components/account/tags/TagsView.min.html',\n            resolve: {\n                tagList: ['TagService', function(TagService) {\n                    return TagService.getPopular().$promise;\n                }]\n            },\n            controller: 'TagsController'\n        })\n        .state('tatami.account.tags.search', {\n            url: '/search/:q',\n            templateUrl: 'app/components/account/tags/TagsView.min.html',\n            resolve: {\n                tagList: ['SearchService', '$stateParams', function(SearchService, $stateParams) {\n                    if($stateParams.q.length === 0) {\n                        return {};\n                    }\n                    else {\n                        return SearchService.query({ term: 'tags', q: $stateParams.q }).$promise;\n                    }\n                }]\n            },\n            controller: 'TagsController'\n        })\n        .state('tatami.account.topPosters', {\n            url: '/top',\n            templateUrl: 'app/components/account/topPosters/TopPostersView.min.html',\n            resolve: {\n                topPosters: ['TopPostersService', function(TopPostersService) {\n                    // Get the {username, count} pairs for all the top posters\n                    return TopPostersService.query().$promise;\n                }],\n\n                users: ['topPosters', 'UserService', '$q', function(topPosters, UserService, $q) {\n                    // For all the {user, count} pairs, find the user data\n                    var temp = [];\n                    for(var i = 0; i < topPosters.length; ++i) {\n                        // Store the result as a promise\n                        temp.push(UserService.get({ username: topPosters[i].username }).$promise);\n                        temp[i].statusCount = topPosters[i].statusCount;\n                    }\n                    // return all promises\n                    return $q.all(temp);\n                }],\n\n                userData: ['topPosters', 'users', function(topPosters, users) {\n                    var statusCounts = [];\n                    // We want to associate the {username, count} pairs from the original to the user data, index based\n                    // on username.\n                    for(var i = 0; i < topPosters.length; ++i) {\n                        statusCounts[topPosters[i].username] = topPosters[i].statusCount;\n                    }\n\n                    var temp = [];\n                    for(var x = 0; x < users.length; ++x) {\n                        // Create the current user to contain the user data, and how many posts they've made today\n                        var curUser = {};\n                        curUser.info = users[x];\n                        curUser.statusCount = statusCounts[users[x].username];\n                        temp.push(curUser);\n                    }\n                    return temp;\n                }]\n            },\n            controller: 'TopPostersController'\n        });\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/AccountView.html",
    "content": "<div>\n    <div id=\"mainPanel\" class=\"container\">\n        <br>\n        <div class=\"row\">\n            <!-- The nagivation sidebar -->\n            <div id=\"navigation\">\n                <div>\n                    <div class=\"col-span-4 alert\">\n                        <div id=\"avatar\">\n                            <div class=\"row text-center nomargin avatar-float-center-container\">\n                                <div>\n                                    <img class=\"nomargin avatar img-rounded\" ng-src=\"{{ profile.avatarURL }}\">\n                                </div>\n                                <br>\n                                <div>\n                                    <a ui-sref=\"tatami.home.profile.statuses({ username: profile.username })\">\n                                        <h3 class=\"user-profile\">{{ profile.firstName + ' ' + profile.lastName }}</h3>\n                                    </a>\n                                    <a ui-sref=\"tatami.home.profile.statuses({ username: profile.username })\">\n                                        <p>@{{ profile.username }}</p>\n                                    </a>\n                                </div>\n                            </div>\n                        </div>\n                        <div class=\"tabbable alert alert-status\">\n                            <ul class=\"adminMenu nav nav-pills nav-stacked nomargin\">\n                                <li ui-sref-active=\"active\">\n                                    <a ui-sref=\"tatami.account.profile\">\n                                        <span class=\"glyphicon glyphicon-user\"></span>\n                                        <span translate=\"tatami.account.profile.title\"></span>\n                                    </a>\n                                </li>\n                                <li ui-sref-active=\"active\">\n                                    <a ui-sref=\"tatami.account.preferences\">\n                                        <span class=\"glyphicon glyphicon-cog\"></span>\n                                        <span translate=\"tatami.account.preferences.title\"></span>\n                                    </a>\n                                </li>\n                                <li ui-sref-active=\"active\">\n                                    <a ui-sref=\"tatami.account.password\">\n                                        <span class=\"glyphicon glyphicon-lock\"></span>\n                                        <span translate=\"tatami.account.password.title\"></span>\n                                    </a>\n                                </li>\n                                <li ui-sref-active=\"active\">\n                                    <a ui-sref=\"tatami.account.files\">\n                                        <span class=\"glyphicon glyphicon-file\"></span>\n                                        <span translate=\"tatami.account.files.title\"></span>\n                                    </a>\n                                </li>\n                                <li ng-class=\"{ 'active': $state.current.name.indexOf('tatami.account.users') != -1 }\">\n                                    <a ui-sref=\"tatami.account.users\">\n                                        <span class=\"glyphicon glyphicon-globe\"></span>\n                                        <span translate=\"tatami.account.users.title\"></span>\n                                    </a>\n                                </li>\n                                <li ng-class=\"{ 'active': $state.current.name.indexOf('tatami.account.groups') != -1 }\">\n                                    <a ui-sref=\"tatami.account.groups\">\n                                        <span class=\"glyphicon glyphicon-th-large\"></span>\n                                        <span translate=\"tatami.account.groups.title\"></span>\n                                    </a>\n                                </li>\n                                <li ng-class=\"{ 'active': $state.current.name.indexOf('tatami.account.tags') != -1 }\">\n                                    <a ui-sref=\"tatami.account.tags\">\n                                        <span class=\"glyphicon glyphicon-tags\"></span>\n                                        <span translate=\"tatami.account.tags.title\"></span>\n                                    </a>\n                                </li>\n                                <li ui-sref-active=\"active\">\n                                    <a ui-sref=\"tatami.account.topPosters\">\n                                        <span class=\"glyphicon glyphicon-signal\"></span>\n                                        <span translate=\"tatami.account.topPosters.title\"></span>\n                                    </a>\n                                </li>\n                            </ul>\n                        </div>\n                    </div>\n                </div>\n            </div>\n            <div ui-view></div>\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/account/FormController.js",
    "content": "AccountModule.controller('FormController', ['$scope', function($scope) {\n    // Forwards from the parent state to the default child state.\n    $scope.$on('$stateChangeSuccess', function(event, toState) {\n        if(toState.name === 'tatami.account.groups') {\n            $scope.$state.go('tatami.account.groups.main.top.list');\n        }\n        else if(toState.name === 'tatami.account.tags') {\n            $scope.$state.go('tatami.account.tags.following');\n        }\n        else if(toState.name === 'tatami.account.users') {\n            $scope.$state.go('tatami.account.users.following');\n        }\n    });\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/FormView.html",
    "content": "<div class=\"col-span-8\">\n    <div class=\"alert alert-status\">\n        <div>\n            <ui-view></ui-view>\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/account/files/FilesController.js",
    "content": "FilesModule.controller('FilesController', [\n    '$scope',\n    '$translate',\n    'FilesService',\n    'attachmentQuota',\n    'fileList',\n    'ngToast',\n    function($scope, $translate, FilesService, attachmentQuota, fileList, ngToast) {\n\n    // Initialize stuff\n    $scope.quota = attachmentQuota[0];\n    $scope.fileList = fileList;\n\n    /**\n     * Allows us to delete the supplied attachment\n     * @param attachment\n     */\n    $scope.delete = function(attachment, removalIndex) {\n        FilesService.delete({attachmentId: attachment}, { },\n            function() {\n                $scope.fileList.splice(removalIndex, 1);\n                $scope.$state.reload();\n                ngToast.create($translate.instant('tatami.form.deleted'));\n            });\n    };\n\n    $scope.getImgPath = function(thumbnail, attachmentId, filename) {\n        if(thumbnail) {\n            return '/tatami/thumbnail/' + attachmentId + '/' + filename;\n        }\n        else {\n            return '/img/document_icon.png';\n        }\n    };\n\n    $scope.setColor = function() {\n        if($scope.quota <= 100 && $scope.quota >= 80) {\n            return \"progress-bar progress-bar-danger\";\n        }\n        else if($scope.quota < 80 && $scope.quota > 50) {\n            return \"progress-bar progress-bar-warning\";\n        }\n        else {\n             return \"progress-bar progress-bar-success\";\n        }\n    };\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/files/FilesModule.js",
    "content": "var FilesModule = angular.module('FilesModule', []);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/files/FilesService.js",
    "content": "FilesModule.factory('FilesService', function($resource) {\n    return $resource(\n        '/tatami/rest/attachments/:attachmentId',\n        { },\n        {\n            'getQuota': { method: 'GET', isArray: true, url: '/tatami/rest/attachments/quota' }\n        });\n});"
  },
  {
    "path": "web/src/main/webapp/app/components/account/files/FilesView.html",
    "content": "<div class=\"col-span-8\">\n    <div class=\"alert alert-status\">\n        <div >\n            <h2 translate=\"tatami.account.files.title\"></h2>\n            <span class=\"file-infos\"></span>\n        </div>\n        <div>\n            <div class=\"progress\">\n                <!-- progress-bar-danger = red (80-100)\n                     progress-bar-warning = orange (50-79)\n                     progress-bar-success = green (0-50)\n                -->\n                <div ng-class=\"setColor()\" style=\"width: {{quota}}%;\">\n                    <span class=\"quota\">{{ quota }}%</span>\n                </div>\n            </div>\n        </div>\n        <div>\n            <table class=\"table noCollapse\">\n                <tbody>\n                    <tr>\n                        <th style=\"border-top :0\">  </th>\n                        <th style=\"border-top :0\"><b translate=\"tatami.account.files.filename\"></b></th>\n                        <th style=\"border-top :0\"><b translate=\"tatami.account.files.size\"></b></th>\n                        <th style=\"border-top :0\"><b translate=\"tatami.account.files.date\"></b></th>\n                        <th style=\"border-top :0\">  </th>\n                    </tr>\n                </tbody>\n                <tbody class=\"items\">\n                    <tr ng-repeat=\"file in fileList\">\n                        <td>\n                            <a ng-href=\"/tatami/file/{{ file.attachmentId }}/{{ file.filename }}\" target=\"_blank\">\n                                <img ng-src=\"{{ getImgPath(file.hasThumbnail, file.attachmentId, file.filename) }}\">\n                            </a>\n                        </td>\n                        <td>\n                            <a ng-href=\"/tatami/file/{{ file.attachmentId }}/{{ file.filename }}\" target=\"_blank\">{{ file.filename }}</a>\n                        </td>\n                        <td>{{ file.size / 1000 }} kb</td>\n                        <td>{{ file.prettyPrintCreationDate }}</td>\n                        <td>\n                            <button class=\"btn btn-danger btn-block\" translate=\"tatami.account.files.delete\" ng-click=\"delete(file.attachmentId, $index)\" type=\"button\"></button>\n                        </td>\n                    </tr>\n                </tbody>\n            </table>\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/account/groups/GroupsController.js",
    "content": "GroupsModule.controller('GroupsController', [\n    '$scope',\n    'GroupService',\n    'SearchService',\n    'userGroups',\n    'profileInfo',\n    function($scope, GroupService, SearchService, userGroups, profileInfo) {\n        $scope.userGroups = userGroups;\n\n        /**\n         * Determines the current look of the group page\n         * When createGroup is true, we display the group creation view\n         */\n        $scope.current = {\n            searchString: $scope.$stateParams.q\n        };\n\n        $scope.search = function() {\n            // Update the route\n            $scope.$state.transitionTo('tatami.account.groups.main.top.search',\n                { q: $scope.current.searchString },\n                { location: true, inherit: true, relative: $scope.$state.$current, notify: false });\n\n            // Update the group data\n            SearchService.query({term: 'groups', q: $scope.current.searchString }, function(result) {\n                // Now update the user groups\n                $scope.userGroups = result;\n            });\n        };\n\n        $scope.joinLeaveGroup = function(group) {\n            if(!group.member) {\n                GroupService.join(\n                    { groupId: group.groupId, username: profileInfo.username },\n                    null,\n                    function(response) {\n                        if(response.isMember) {\n                            $scope.$state.reload();\n                        }\n                    }\n                );\n            }\n\n            else {\n                GroupService.leave(\n                    { groupId: group.groupId, username: profileInfo.username },\n                    null,\n                    function(response) {\n                        if(response) {\n                            $scope.$state.reload();\n                        }\n                    }\n                );\n            }\n        };\n    }\n]);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/groups/GroupsModule.js",
    "content": "var GroupsModule = angular.module('GroupsModule', []);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/groups/GroupsView.html",
    "content": "<div>\n    <form class=\"form-horizontal row-fluid\">\n        <h2 translate=\"tatami.account.groups.title\"></h2>\n\n        <div ui-view=\"create\"></div>\n\n        <div class=\"tabMenu\">\n            <ul class=\"nav nav-tabs\">\n                <li ng-class=\"{ 'active': $state.current.name === 'tatami.account.groups.main.top.list' }\">\n                    <a ui-sref=\"tatami.account.groups.main.top.list\" translate=\"tatami.account.groups.myGroups\">\n                    </a>\n                </li>\n                <li ng-class=\"{ 'active': $state.current.name === 'tatami.account.groups.main.top.recommended' }\">\n                    <a ui-sref=\"tatami.account.groups.main.top.recommended\" translate=\"tatami.account.groups.recommended\" ng-click=\"display()\">\n                    </a>\n                </li>\n                <li ng-class=\"{ 'active': $state.current.name === 'tatami.account.groups.main.top.search' }\">\n                    <a ui-sref=\"tatami.account.groups.main.top.search\" translate=\"tatami.account.groups.search\">\n                    </a>\n                </li>\n            </ul>\n        </div>\n\n        <div ui-view=\"list\"></div>\n    </form>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/account/groups/creation/GroupsCreateController.js",
    "content": "GroupsModule.controller('GroupsCreateController', ['$scope', '$translate', 'GroupService', 'ngToast', function($scope, $translate, GroupService, ngToast) {\n    $scope.current = {};\n    /**\n     * When creating a group, the POST requires this payload\n     * @type {{name: string, description: string, publicGroup: boolean, archivedGroup: boolean}}\n     */\n    $scope.groups = {\n        name: \"\",\n        description: \"\",\n        publicGroup: true,\n        archivedGroup: false\n    };\n\n    /**\n     * Allows the user to toggle the group creation view\n     */\n    $scope.newGroup = function() {\n        $scope.current.createGroup = !$scope.current.createGroup;\n    };\n\n    /**\n     * Allows the user to cancel group creation\n     */\n    $scope.cancelGroupCreate = function() {\n        $scope.reset();\n    };\n\n    /**\n     * Resets the group creation view\n     */\n    $scope.reset = function() {\n        $scope.groups = {};\n        $scope.current.createGroup = false;\n    };\n\n    /**\n     * Creates a new group on the server\n     */\n    $scope.createNewGroup = function() {\n        GroupService.save($scope.groups, function() {\n            $scope.reset();\n            $scope.$state.reload();\n            // Alert user of new group creation\n            ngToast.create({\n                content: $translate.instant('tatami.account.groups.save')\n            });\n        }, function() {\n            ngToast.create({\n                content: $translate.instant('tatami.form.fail'),\n                class: 'danger'\n            });\n        });\n    };\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/groups/creation/GroupsCreateView.html",
    "content": "<div>\n    <button class=\"show btn btn-xlarge btn-block btn-primary\" type=\"button\" translate=\"tatami.account.groups.createNewGroup\" ng-click=\"newGroup()\"></button>\n\n    <fieldset class=\"hide\" style=\"display: block;\" ng-show=\"current.createGroup\">\n        <legend translate=\"tatami.account.groups.create\"></legend>\n        <div class=\"control-group\">\n            <label class=\"control-label\" for=\"name\" translate=\"tatami.account.groups.name\"></label>\n            <div class=\"controls\">\n                <input name=\"name\" type=\"text\" required=\"required\" size=\"30\" maxlength=\"50\" class=\"input-xlarge col-span-12\" value=\"\" ng-model=\"groups.name\">\n            </div>\n        </div>\n\n        <div class=\"control-group\">\n            <label class=\"control-label\" for=\"description\" translate=\"tatami.account.groups.description\"></label>\n            <div class=\"controls\">\n                <textarea name=\"description\" class=\"input-xlarge col-span-12\" ng-model=\"groups.description\"></textarea>\n            </div>\n        </div>\n\n\n        <div class=\"control-group\">\n            <label class=\"control-label\" for=\"publicGroup\" translate=\"tatami.account.groups.access\"></label>\n\n            <div class=\"controls\">\n                <label class=\"radio\">\n                    <input type=\"radio\" name=\"publicGroup\" value=\"true\" ng-checked=\"true\" required=\"\" ng-model=\"groups.publicGroup\"> {{ 'tatami.account.groups.public' | translate }}\n                </label>\n                <label class=\"radio\">\n                    <input type=\"radio\" name=\"publicGroup\" value=\"false\" required=\"\" ng-model=\"groups.publicGroup\"> {{ 'tatami.account.groups.private' | translate }}\n                </label>\n            </div>\n        </div>\n\n        <div class=\"alertColor\">\n            <span class=\"glyphicon glyphicon-warning-sign\"></span>\n            <span translate=\"tatami.account.groups.publicWarning\"></span>\n        </div>\n        <br>\n        <div class=\"return\"></div>\n        <br>\n        <div class=\"form-actions\">\n            <button type=\"submit\" class=\"btn btn-primary col-span-7 little-marge-right\" translate=\"tatami.account.groups.create\" ng-click=\"createNewGroup()\"></button>\n            <button type=\"reset\" class=\"btn btn-default col-span-4\" translate=\"tatami.form.cancel\" ng-click=\"cancelGroupCreate()\"></button>\n        </div>\n    </fieldset>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/account/groups/list/GroupListController.js",
    "content": "GroupsModule.controller('GroupController', ['$scope', function($scope) {\n    if($scope.$state.name === 'tatami.account.groups.main') {\n        $scope.$state.go('tatami.account.groups.main.top.list');\n    }\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/groups/list/GroupsListView.html",
    "content": "<div>\n    <form class=\"row-fluid littleMargeBot\">\n        <input ng-show=\"$state.is('tatami.account.groups.main.top.search')\" ng-model=\"current.searchString\" ng-trim=\"false\" ng-change=\"search()\" id=\"block_filter\" type=\"text\" class=\"search-query col-span-12\" name=\"result_filter\" autocomplete=\"off\" placeholder=\"{{ 'tatami.account.groups.search' | translate }}\">\n    </form>\n    <table class=\"table noCollapse\">\n        <tbody>\n            <tr>\n                <th style=\"border-top: 0\" translate=\"tatami.account.groups.name\"></th>\n                <th style=\"border-top: 0\" translate=\"tatami.account.groups.access\"></th>\n                <th style=\"border-top: 0\" translate=\"tatami.account.groups.members\"></th>\n                <th style=\"border-top: 0\"></th>\n            </tr>\n        </tbody>\n        <tbody class=\"items\">\n            <div>\n                <tr ng-repeat=\"group in userGroups\">\n                    <td>\n                        <a ui-sref=\"tatami.home.home.group.statuses({ groupId: group.groupId })\">{{ group.name }}</a>\n                    </td>\n                    <td>\n                        <span ng-show=\"group.publicGroup && !group.archivedGroup\" class=\"label labelSizeNormal label-warning\" translate=\"tatami.account.groups.public\"></span>\n                        <span ng-show=\"!group.publicGroup && !group.archivedGroup\" class=\"label labelSizeNormal label-info\" translate=\"tatami.account.groups.private\"></span>\n                        <span ng-show=\"group.archivedGroup\" class=\"label labelSizeNormal\" translate=\"tatami.account.groups.archived\"></span>\n                    </td>\n                    <td>\n                        {{ group.counter }}\n                    </td>\n                    <td>\n                        <span ng-if=\"group.administrator\">\n                            <button type=\"button\" ui-sref=\"tatami.account.groups.manage({ groupId: group.groupId })\" class=\"pull-right btn btn-primary hidden-phone\">\n                                <span class=\"glyphicon glyphicon-th-large\"></span>\n                                <span translate=\"tatami.account.groups.manage\"></span>\n                            </button>\n                        </span>\n\n                        <button type=\"button\" ng-if=\"!group.administrator\" ng-click=\"joinLeaveGroup(group)\" ng-init=\"hover = false\" ng-mouseenter=\"hover = true\" ng-mouseleave=\"hover = false\" class=\"btn btn-sm pull-right\" ng-class=\"{ 'btn-danger': group.member && hover, 'btn-info': group.member && !hover }\">\n                            <span class=\"glyphicon\" ng-class=\"group.member ? 'glyphicon-minus' : 'glyphicon-plus'\">\n                                <span ng-if=\"!group.member\" class=\"hidden-phone\" translate=\"tatami.account.groups.join\"></span>\n                                <span ng-if=\"group.member && !hover\" class=\"hidden-phone\" translate=\"tatami.account.groups.joined\"></span>\n                                <span ng-if=\"group.member && hover\" class=\"hidden-phone\" translate=\"tatami.account.groups.leave\"></span>\n                            </span>\n                        </button>\n                    </td>\n                </tr>\n            </div>\n        </tbody>\n    </table>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/account/groups/manage/GroupsManageController.js",
    "content": "GroupsModule.controller('GroupsManageController', ['$scope', 'group', 'GroupService', 'UserService', 'members', function($scope, group, GroupService, UserService, members) {\n    $scope.group = group;\n    $scope.members = members;\n    $scope.searchedMembers = {};\n\n    $scope.current = { searchString: '' };\n\n    $scope.updateGroup = function() {\n        GroupService.update( { groupId: $scope.group.groupId }, $scope.group);\n    };\n\n    $scope.removeUser = function(member) {\n        GroupService.leave(\n            { groupId: $scope.group.groupId, username: member.username },\n            null,\n            function() {\n                $scope.$state.reload();\n            }\n        );\n    };\n\n    $scope.search = function() {\n        if($scope.current.searchString) {\n            UserService.searchUsers({ term: 'search', q: $scope.current.searchString }, function(result) {\n                $scope.searchedMembers = result;\n            });\n        }\n        else {\n            $scope.searchedMembers = {};\n        }\n    };\n\n    $scope.addUser = function(member) {\n        GroupService.join(\n            { groupId: $scope.group.groupId, username: member.username },\n            null,\n            function() {\n                $scope.$state.reload();\n            }\n        );\n    };\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/groups/manage/GroupsManageView.html",
    "content": "<div>\n    <form class=\"form-horizontal row-fluid\">\n        <h2 translate=\"tatami.account.groups.title\"></h2>\n        <fieldset>\n            <legend translate=\"tatami.account.groups.update\"></legend>\n            <div class=\"control-group\">\n                <label class=\"control-label\" for=\"name\" translate=\"tatami.account.groups.name\"></label>\n                <div class=\"controls\">\n                    <input name=\"name\" type=\"text\" required=\"required\" size=\"30\" maxlength=\"50\" class=\"input-xlarge col-span-12\" ng-model=\"group.name\">\n                </div>\n            </div>\n            <div class=\"control-group\">\n                <label class=\"control-label\" for=\"description\" translate=\"tatami.account.groups.description\"></label>\n                <div class=\"controls\">\n                    <textarea name=\"description\" class=\"input-xlarge col-span-12\" ng-model=\"group.description\"></textarea>\n                </div>\n            </div>\n            <div class=\"control-group\">\n                <label class=\"control-label\" for=\"archivedGroup\" translate=\"tatami.account.groups.archive\"></label>\n                <div class=\"controls\">\n                    <label class=\"radio\">\n                    <input type=\"radio\" name=\"archivedGroup\" ng-value=\"true\" ng-model=\"group.archivedGroup\" required=\"\">\n                    {{ 'tatami.account.groups.allowArchive' | translate }}\n                    </label>\n                    <label class=\"radio\">\n                    <input type=\"radio\" name=\"archivedGroup\" ng-value=\"false\" ng-model=\"group.archivedGroup\" required=\"\">\n                    {{ 'tatami.account.groups.denyArchive' | translate }}\n                    </label>\n                </div>\n            </div>\n            <div class=\"alert alertColor\">\n                <span class=\"glyphicon glyphicon-warning-sign\"></span>\n                <span translate=\"tatami.account.groups.archiveWarning\"></span>\n            </div>\n            <br>\n            <div class=\"return\"></div>\n            <br>\n            <div class=\"form-actions\">\n                <button ng-click=\"updateGroup()\" type=\"submit\" class=\"btn btn-primary col-span-12\" translate=\"tatami.form.save\"></button>\n            </div>\n        </fieldset>\n    </form>\n    <div class=\"useritem\">\n        <table class=\"table noCollapse\">\n            <tbody>\n                <tr>\n                    <th style=\"border-top: 0\" translate=\"tatami.account.groups.username\"></th>\n                    <th style=\"border-top: 0\" translate=\"tatami.account.groups.role\"></th>\n                    <th style=\"border-top: 0\"></th>\n                </tr>\n            </tbody>\n            <tbody class=\"items\">\n                <tr ng-repeat=\"member in members\">\n                    <td style=\"text-align: left\">\n                        <div class=\"pull-left background-image-fffix little-marge-right\">\n                            <img class=\"img-rounded img-medium\" ng-style=\"{ 'background-image': 'url(' + member.avatarURL + ')' }\">\n                        </div>\n                        <h4>\n                            <a ui-sref=\"tatami.home.profile.statuses({ username: member.username })\">\n                                <strong>\n                                    {{ member.firstName + ' ' + member.lastName }}\n                                </strong>\n                            </a>\n                            <br>\n                            <a ui-sref=\"tatami.home.profile.statuses({ username: member.username })\">\n                                <small>\n                                    @{{ member.username }}\n                                </small>\n                            </a>\n                        </h4>\n                    </td>\n                    <td>\n                        {{ 'tatami.account.groups.' + member.role | lowercase | translate }}\n                    </td>\n                    <td ng-show=\"member.role === 'MEMBER'\">\n                        <button ng-click=\"removeUser(member)\" class=\"pull-right btn btn-danger hidden-phone\" type=\"button\">\n                            <span translate=\"tatami.account.groups.remove\"></span>\n                        </button>\n                        <!-- <button ng-click=\"removeUser(member)\" type=\"button\" class=\"btn btn-danger input-block-level glyphicon-minus delete\" translate=\"\"></button> -->\n                    </td>\n                </tr>\n            </tbody>\n        </table>\n    </div>\n    <form class=\"form-horizontal row-fluid\">\n        <fieldset>\n            <legend translate=\"tatami.account.groups.addMember\"></legend>\n            <div class=\"control-group\">\n                <label class=\"control-label\" for=\"username\" translate=\"tatami.account.groups.username\"></label>\n                <div class=\"controls\">\n                    <input name=\"username\" ng-model=\"current.searchString\" ng-trim=\"false\" ng-change=\"search()\" type=\"text\" autocomplete=\"off\" required=\"required\" class=\"input-xlarge col-span-12\">\n                    <!--\n                    <ul class=\"typeahead dropdown-menu\" style=\"top: 34px; left: 180px;\">\n                        <li data-value=\"2\" class=\"active\">\n                            <a href=\"#\">\n                                <img class=\"avatar img-rounded img-small\" src=\"/img/default_image_profile.png\">\n                                    @<strong>2</strong> - Bob loblaw\n                            </a>\n                        </li>\n                    </ul>\n                    -->\n                    <table class=\"table\">\n                        <tbody>\n                        <tr ng-repeat=\"member in searchedMembers\">\n                            <td style=\"text-align: left\">\n                                <div class=\"pull-left background-image-fffix little-marge-right\">\n                                    <img class=\"img-rounded img-medium\" ng-style=\"{ 'background-image': 'url(' + member.avatarURL + ')' }\">\n                                </div>\n                                <h4>\n                                    <a ui-sref=\"tatami.home.profile.statuses({ username: member.username })\">\n                                        <strong>\n                                            {{ member.firstName + ' ' + member.lastName }}\n                                        </strong>\n                                    </a>\n                                    <br>\n                                    <a ui-sref=\"tatami.home.profile.statuses({ username: member.username })\">\n                                        <small>\n                                            @{{ member.username }}\n                                        </small>\n                                    </a>\n                                </h4>\n                            </td>\n                            <td>\n                                <button ng-click=\"addUser(member)\" class=\"pull-right btn btn-primary hidden-phone\" type=\"button\">\n                                    <span translate=\"tatami.account.groups.add\"></span>\n                                </button>\n                                <!-- <button ng-click=\"addUser(member)\" type=\"button\" class=\"btn btn-success input-block-level glyphicon-plus delete\" translate=\"tatami.account.groups.add\"></button> -->\n                            </td>\n                        </tr>\n                        </tbody>\n                    </table>\n                </div>\n            </div>\n            <br>\n            <div class=\"return\"></div>\n            <!--\n            <br>\n            <div class=\"form-actions\">\n                <button type=\"submit\" class=\"btn btn-success col-span-12\" translate=\"tatami.form.save\"></button>\n            </div>\n            -->\n        </fieldset>\n    </form>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/account/password/PasswordController.js",
    "content": "PasswordModule.controller('PasswordController', ['$scope', '$translate', 'PasswordService', 'ngToast', function($scope, $translate, PasswordService, ngToast) {\n    $scope.password = {\n        oldPassword: '',\n        newPassword: '',\n        newPasswordConfirmation: ''\n    };\n\n    /**\n     * These booleans will determine whether popovers should be displayed\n     */\n    $scope.status = {\n        oldEmpty: false,\n        newEmpty: false,\n        confirmWrong: false,\n        confirmChange: false\n    };\n\n    $scope.changePassword = function() {\n        if($scope.password.oldPassword === '') {\n            // Display a popover on Old password field\n            $scope.status.oldEmpty = true;\n        }\n        else if($scope.password.newPassword === '') {\n            // Display a popover on the new password field\n            $scope.status.newEmpty = true;\n        }\n        else if($scope.password.newPassword !== $scope.password.newPasswordConfirmation) {\n            // Display a popover on password confirmation\n            $scope.status.confirmWrong = true;\n        }\n        else {\n            // Everything is alright, we can send the new password\n            PasswordService.save($scope.password, function() {\n                // Clear the fields after we have changed the password\n                $scope.reset();\n                // Alert user that the password has been changed\n                ngToast.create($translate.instant('tatami.account.password.save'));\n\n            }, function() {\n                ngToast.create({\n                    content: $translate.instant('tatami.form.fail'),\n                    class: 'danger'\n                });\n            });\n        }\n    };\n\n    $scope.reset = function() {\n        $scope.password = {};\n        $scope.status.oldEmpty = false;\n        $scope.status.newEmpty = false;\n        $scope.status.confirmWrong = false;\n    };\n}]);\n"
  },
  {
    "path": "web/src/main/webapp/app/components/account/password/PasswordModule.js",
    "content": "var PasswordModule = angular.module('PasswordModule', []);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/password/PasswordService.js",
    "content": "PasswordModule.factory('PasswordService', function($resource) {\n    return $resource('/tatami/rest/account/password');\n});"
  },
  {
    "path": "web/src/main/webapp/app/components/account/password/PasswordView.html",
    "content": "<div class=\"col-span-8\">\n    <div class=\"alert alert-status\">\n        <div>\n            <form class=\"form-horizontal row-fluid\">\n                <h2 translate=\"tatami.account.password.title\"></h2>\n                <fieldset>\n                    <legend translate=\"tatami.account.password.update\"></legend>\n                    <div class=\"control-group\">\n                        <label class=\"control-label\" translate=\"tatami.account.password.old\"></label>\n                        <div class=\"controls\">\n                            <input type=\"password\" required=\"required\" size=\"15\" maxlength=\"40\" class=\"input-xlarge col-span-12\" ng-model=\"password.oldPassword\">\n                        </div>\n                    </div>\n                    <div class=\"control-group\">\n                        <label class=\"control-label\" translate=\"tatami.account.password.new\"></label>\n                        <div class=\"controls\">\n                            <input type=\"password\" required=\"required\" ize=\"15\" maxlength=\"40\" class=\"input-xlarge col-span-12\" ng-model=\"password.newPassword\">\n                        </div>\n                    </div>\n                    <div class=\"control-group\">\n                        <label class=\"control-label\" translate=\"tatami.account.password.confirm\"></label>\n                        <div class=\"controls\">\n                            <input type=\"password\" required=\"required\" size=\"15\" maxlength=\"40\" class=\"input-xlarge col-span-12\" ng-model=\"password.newPasswordConfirmation\">\n                        </div>\n                    </div>\n                    <div class=\"return\"></div>\n                    <div class=\"form-actions\">\n                        <button type=\"submit\" class=\"btn btn-primary btn-block\" translate=\"tatami.form.save\" ng-click=\"changePassword()\"></button>\n                    </div>\n                </fieldset>\n            </form>\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/account/preferences/PreferencesController.js",
    "content": "PreferencesModule.controller('PreferencesController', [\n    '$scope',\n    '$translate',\n    'PreferencesService',\n    'prefs',\n    'ngToast',\n    function($scope, $translate, PreferencesService, prefs, ngToast) {\n\n        $scope.prefs = prefs;\n\n        // Update user preferences\n        $scope.savePrefs = function() {\n            $scope.validatePrefs();\n            PreferencesService.save($scope.prefs, function() {\n                ngToast.create($translate.instant('tatami.account.preferences.save'));\n            }, function() {\n                ngToast.create({\n                    content: $translate.instant('tatami.form.fail'),\n                    class: 'danger'\n                });\n            });\n        };\n\n        $scope.validatePrefs = function() {\n            for(var pref in $scope.prefs) {\n                if($scope.prefs.hasOwnProperty(pref) && $scope.prefs[pref] === null) {\n                    if('rssUid' === $scope.prefs[pref]) {\n                        continue;\n                    }\n                    $scope.prefs[pref] = false;\n                }\n            }\n        };\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/preferences/PreferencesModule.js",
    "content": "var PreferencesModule = angular.module('PreferencesModule', []);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/preferences/PreferencesService.js",
    "content": "PreferencesModule.factory('PreferencesService', function($resource) {\n    return $resource('/tatami/rest/account/preferences');\n});"
  },
  {
    "path": "web/src/main/webapp/app/components/account/preferences/PreferencesView.html",
    "content": "<div class=\"col-span-8\">\n    <div class=\"alert alert-status\">\n        <div>\n            <form class=\"form-horizontal row-fluid\">\n                <h2 translate=\"tatami.account.preferences.title\"></h2>\n                <legend translate=\"tatami.account.preferences.notifications\"></legend>\n                <div class=\"control-group\">\n                    <div class=\"controls\">\n                        <label class=\"checkbox\">\n                        <input name=\"mentionEmail\" type=\"checkbox\" ng-model=\"prefs.mentionEmail\" ng-checked=\"prefs.mentionEmail\">{{ 'tatami.account.preferences.notification.email.mention' | translate }}\n                        </label>\n                    </div>\n                    <div class=\"controls\">\n                        <label class=\"checkbox\">\n                        <input name=\"dailyDigest\" type=\"checkbox\" ng-model=\"prefs.dailyDigest\" ng-checked=\"prefs.dailyDigest\"> {{ 'tatami.account.preferences.notification.email.dailyDigest' | translate }}\n                        </label>\n                    </div>\n                    <div class=\"controls\">\n                        <label class=\"checkbox\">\n                        <input name=\"weeklyDigest\" type=\"checkbox\" ng-model=\"prefs.weeklyDigest\" ng-checked=\"prefs.weeklyDigest\"> {{ 'tatami.account.preferences.notification.email.weeklyDigest' | translate }}\n                        </label>\n                    </div>\n                    <div class=\"controls\">\n                        <label class=\"checkbox\">\n                        <input name=\"rssUidActive\" type=\"checkbox\" ng-model=\"prefs.rssUidActive\" ng-checked=\"prefs.rssUidActive\"> {{ 'tatami.account.preferences.notification.rss.timeline' | translate }}\n                        </label>\n                        <a ng-if=\"prefs.rssUidActive\" href=\"/tatami/syndic/{{ prefs.rssUid }}\">{{ 'tatami.account.preferences.notification.rss.link' | translate }}</a>\n                    </div>\n                </div>\n                <fieldset>\n                    <div class=\"return\"></div>\n                    <div class=\"form-actions\">\n                        <button type=\"submit\" class=\"input-xlarge btn btn-primary btn-block\" ng-click=\"savePrefs()\" translate=\"tatami.form.save\"></button>\n                    </div>\n                </fieldset>\n            </form>\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/account/profile/ProfileController.js",
    "content": "ProfileModule.controller('ProfileController', ['$scope', '$upload', '$translate', 'ProfileService', 'profileInfo', 'userLogin', 'ngToast',\n    function($scope, $upload, $translate, ProfileService, profileInfo, userLogin, ngToast) {\n\n        // Current state of the view\n        $scope.current = {\n            avatar: []\n        };\n\n        // Status of the current upload\n        $scope.uploadStatus = {\n            isUploading: false,\n            progress: 0\n        };\n\n        // Resolve the user data, profileInfo is inherited from account state\n        // Since profileInfo is a resolve from the parent state, updating the model will cause\n        // the first and last name in the side bar and text area to sync. Is this undesired?\n        $scope.userProfile = profileInfo;\n        $scope.userLogin = userLogin.login;\n\n        // Update the user information\n        $scope.updateUser = function() {\n            ProfileService.update($scope.userProfile, function() {\n                ngToast.create({\n                    content: $translate.instant('tatami.account.profile.save')\n                });\n            }, function() {\n                ngToast.create({\n                    content: $translate.instant('tatami.form.fail'),\n                    class: 'danger'\n                });\n            });\n        };\n\n        // Handle user avatar changes based on drag and drop\n        $scope.$watch('current.avatar', function() {\n            for(var i = 0; i < $scope.current.avatar.length; ++i){\n                var file = $scope.current.avatar[i];\n                $scope.uploadStatus.isUploading = true;\n                $scope.upload = $upload.upload({\n                    url: '/tatami/rest/fileupload/avatar',\n                    file: file,\n                    fileFormDataName: 'uploadFile'\n                }).progress(function(evt) {\n                    $scope.uploadStatus.progress = parseInt(100.0 * evt.loaded / evt.total);\n                }).success(function() {\n                    $scope.uploadStatus.isUploading = false;\n                    $scope.uploadStatus.progress = 0;\n                    $scope.$state.reload();\n                }).error(function() {\n                    $scope.uploadStatus.isUploading = false;\n                    $scope.uploadStatus.progress = 0;\n                });\n            }\n        });\n    }\n]);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/profile/ProfileModule.js",
    "content": "var ProfileModule = angular.module('ProfileModule', []);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/profile/ProfileView.html",
    "content": "<div class=\"col-span-8\">\n    <div class=\"alert alert-status\">\n        <div>\n            <form>\n                <h2 translate=\"tatami.account.profile.title\"></h2>\n                <fieldset class=\"form-horizontal row-fluid\">\n                    <div class=\"control-group dashed\">\n                        <label class=\"control-label\"></label>\n                        <div class=\"controls\">\n                            <div class=\"dropzone well\" ng-file-select ng-file-drop ng-model=\"current.avatar\">\n                                <p class=\"little-padding-top\" translate=\"tatami.account.profile.dropPhoto\"></p>\n                                <!--\n                                <input id=\"avatarFile\" type=\"file\" name=\"uploadFile\" data-url=\"/tatami/rest/fileupload/avatar\">\n                                -->\n                            </div>\n                            <div ng-style=\"{ visibility: uploadStatus.isUploading ? 'visible': 'hidden' }\" class=\"attachmentBar progress progress-striped active\">\n                                <div class=\"bar progress-bar progress-bar-info\" style=\"width: {{ uploadStatus.progress }}%;\"></div>\n                            </div>\n                        </div>\n                    </div>\n                </fieldset>\n                <fieldset class=\"form-horizontal row-fluid\">\n                    <legend translate=\"tatami.account.profile.update\"></legend>\n                    <div class=\"control-group\">\n                        <label class=\"control-label\" for=\"login\" translate=\"tatami.account.profile.email\"></label>\n                        <div class=\"controls\">\n                            <input name=\"login\" type=\"text\" disabled=\"true\" class=\"col-span-12\" ng-model=\"userLogin\">\n                        </div>\n                    </div>\n                    <div class=\"control-group\">\n                        <label class=\"control-label\" for=\"firstName\" translate=\"tatami.account.profile.firstName\">\n                        </label>\n                        <div class=\"controls\">\n                            <input name=\"firstName\" type=\"text\" size=\"15\" maxlength=\"40\" class=\"input-xlarge col-span-12\" ng-model=\"userProfile.firstName\">\n                        </div>\n                    </div>\n                    <div class=\"control-group\">\n                        <label class=\"control-label\" for=\"lastName\" translate=\"tatami.account.profile.lastName\"></label>\n                        <div class=\"controls\">\n                            <input name=\"lastName\" type=\"text\" id=\"lastName\" size=\"15\" maxlength=\"40\" class=\"input-xlarge col-span-12\" ng-model=\"userProfile.lastName\">\n                        </div>\n                    </div>\n                    <div class=\"control-group\">\n                        <label class=\"control-label\" for=\"jobTitle\" translate=\"tatami.account.profile.jobTitle\"></label>\n                        <div class=\"controls\">\n                            <input name=\"jobTitle\" type=\"text\" size=\"15\" maxlength=\"100\" class=\"input-xlarge col-span-12\" ng-model=\"userProfile.jobTitle\">\n                        </div>\n                    </div>\n                    <div class=\"control-group\">\n                        <label class=\"control-label\" for=\"phoneNumber\" translate=\"tatami.account.profile.phoneNumber\"></label>\n                        <div class=\"controls\">\n                            <input name=\"phoneNumber\" type=\"text\" size=\"10\" maxlength=\"20\" class=\"input-xlarge col-span-12\" ng-model=\"userProfile.phoneNumber\">\n                        </div>\n                    </div>\n                    <div class=\"return\"></div>\n                    <div class=\"form-actions\">\n                        <button type=\"submit\" class=\"input-xlarge btn btn-primary btn-block\" translate=\"tatami.form.save\" ng-click=\"updateUser()\"></button>\n                    </div>\n                </fieldset>\n            </form>\n            <!-- Disabled for now until backend handles deleting accounts properly\n            <form>\n                <fieldset class=\"form-horizontal row-fluid\">\n                    <legend translate=\"tatami.account.profile.delete\"></legend>\n                    <div class=\"return\"></div>\n                    <div class=\"form-actions\">\n                        <button type=\"submit\" class=\"input-xlarge btn btn-danger btn-block\" ng-click=\"deleteUser(('tatami.account.profile.confirmDelete' | translate))\" translate=\"tatami.account.profile.delete\">\n                        </button>\n                    </div>\n                </fieldset>\n            </form>\n            -->\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/account/tags/TagsController.js",
    "content": "TagsModule.controller('TagsController', [\n    '$scope',\n    'TagService',\n    'SearchService',\n    'tagList',\n    function($scope, TagService, SearchService, tagList) {\n        $scope.current = {\n            searchString: ''\n        };\n\n        $scope.tags = tagList;\n\n\n        /**\n         * Follows an unfollowed tag, or unfollows a followed tag, depending on the current state\n         * @param tag\n         */\n\n        $scope.followTag = function(tag, index) {\n            TagService.follow(\n                { tag: tag.name },\n                { name: tag.name, followed: !tag.followed, trendingUp: tag.trendingUp },\n                function(response) {\n                    $scope.tags[index].followed = response.followed;\n            });\n        };\n\n        $scope.search = function() {\n            // Update the route\n            $scope.$state.transitionTo('tatami.account.tags.search',\n                { q: $scope.current.searchString },\n                { location: true, inherit: true, relative: $scope.$state.$current, notify: false });\n\n            // Update the tag data data\n            if($scope.current.searchString.length === 0) {\n                $scope.tags = {};\n            }\n            else{\n                SearchService.query({term: 'tags', q: $scope.current.searchString }, function(result) {\n                    // Now update the tags\n                    $scope.tags = result;\n                });\n            }\n        };\n    }\n]);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/tags/TagsModule.js",
    "content": "var TagsModule = angular.module('TagsModule', []);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/tags/TagsView.html",
    "content": "<div>\n    <h2 translate=\"tatami.account.tags.title\"></h2>\n    <div class=\"tabMenu\">\n        <ul class=\"nav nav-tabs\">\n            <li ng-class=\"{ 'active': $state.current.name === 'tatami.account.tags.following' }\">\n                <a ui-sref=\"tatami.account.tags.following\" translate=\"tatami.account.tags.following\"></a>\n            </li>\n            <li ng-class=\"{ 'active': $state.current.name === 'tatami.account.tags.trends' }\">\n                <a ui-sref=\"tatami.account.tags.trends\" translate=\"tatami.account.tags.trends\"></a>\n            </li>\n            <li ng-class=\"{ 'active': $state.current.name === 'tatami.account.tags.search' }\">\n                <a ui-sref=\"tatami.account.tags.search\" translate=\"tatami.account.tags.search\"></a>\n            </li>\n        </ul>\n    </div>\n    <div>\n        <form class=\"row-fluid littleMargeBot\">\n            <input ng-show=\"$state.current.name === 'tatami.account.tags.search'\" ng-model=\"current.searchString\" ng-trim=\"false\" ng-change=\"search()\" id=\"block_filter\" type=\"text\" class=\"search-query col-span-12\" name=\"result_filter\" autocomplete=\"off\" placeholder=\"{{ 'tatami.account.tags.search' | translate }}\">\n        </form>\n        <table class=\"table noCollapse\">\n            <tbody>\n                <tr>\n                    <th style=\"border-top :0\" translate=\"tatami.account.tags.tag\"></th>\n                    <th style=\"border-top :0\"></th>\n                </tr>\n            </tbody>\n            <tbody class=\"items\">\n                <div>\n                    <tr ng-repeat=\"tag in tags\">\n                        <td>\n                            <a ui-sref=\"tatami.home.home.tag({ tag: tag.name })\" title=\"{{ tag.name }}\">#{{ tag.name }}</a>\n                        </td>\n                        <td class=\"follow\">\n                            <button type=\"button\" ng-click=\"followTag(tag, $index)\" ng-init=\"hover = false\" ng-mouseenter=\"hover = true\" ng-mouseleave=\"hover = false\" class=\"btn btn-sm pull-right\" ng-class=\"{ 'btn-danger': tag.followed && hover, 'btn-info': tag.followed && !hover }\">\n                                <span class=\"glyphicon\" ng-class=\"tag.followed ? 'glyphicon-minus' : 'glyphicon-plus'\">\n                                    <span ng-if=\"!tag.followed\" class=\"hidden-phone\" translate=\"tatami.home.tag.follow\"></span>\n                                    <span ng-if=\"tag.followed && !hover\" class=\"hidden-phone\" translate=\"tatami.home.tag.following\"></span>\n                                    <span ng-if=\"tag.followed && hover\" class=\"hidden-phone\" translate=\"tatami.home.tag.unfollow\"></span>\n                                </span>\n                            </button>\n                        </td>\n                    </tr>\n                </div>\n            </tbody>\n        </table>\n    </div>\n</div>\n"
  },
  {
    "path": "web/src/main/webapp/app/components/account/topPosters/TopPostersController.js",
    "content": "TopPostersModule.controller('TopPostersController', ['$scope', 'topPosters', 'UserService', 'userData', function($scope, topPosters, UserService, userData) {\n    $scope.topPosters = userData;\n\n    $scope.topPosters.sort(function(a, b) {\n        return a.statusCount < b.statusCount ? 1 : -1;\n    });\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/topPosters/TopPostersModule.js",
    "content": "var TopPostersModule = angular.module('TopPostersModule', []);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/topPosters/TopPostersView.html",
    "content": "<div class=\"col-span-8\">\n    <div class=\"alert alert-status\">\n        <div>\n            <h2 translate=\"tatami.account.topPosters.title\"></h2>\n            <div class=\"useritem\">\n                <table class=\"table noCollapse\">\n                    <tbody>\n                    <tr>\n                        <th style=\"border-top: 0\" translate=\"tatami.account.topPosters.username\"></th>\n                        <th style=\"border-top: 0\" translate=\"tatami.account.topPosters.count\"></th>\n                        <th style=\"border-top: 0\"></th>\n                    </tr>\n                    </tbody>\n                    <tbody class=\"items\">\n                    <tr ng-repeat=\"user in topPosters\">\n                        <td style=\"text-align: left\">\n                            <div class=\"pull-left background-image-fffix little-marge-right\">\n                                <img class=\"img-rounded img-medium\" ng-style=\"{ 'background-image': 'url(' + user.info.avatarURL + ')' }\">\n                            </div>\n                            <h4>\n                                <a ui-sref=\"tatami.home.profile.statuses({ username: user.info.username })\">\n                                    <strong>\n                                        {{ user.info.firstName + ' ' + user.info.lastName }}\n                                    </strong>\n                                </a>\n                                <br>\n                                <a ui-sref=\"tatami.home.profile.statuses({ username: user.info.username })\">\n                                    <small>\n                                        @{{ user.info.username }}\n                                    </small>\n                                </a>\n                            </h4>\n                        </td>\n                        <td>\n                            {{ user.statusCount }}\n                        </td>\n                    </tr>\n                    </tbody>\n                </table>\n            </div>\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/account/users/UsersController.js",
    "content": "UsersModule.controller('UsersController', ['$scope', 'usersList', 'SearchService', 'UserService', 'userRoles', function($scope, usersList, SearchService, UserService, userRoles) {\n    $scope.isAdmin = userRoles.roles.indexOf('ROLE_ADMIN') !== -1;\n    /**\n     * Information about the current state of the view\n     * @type {{searchString: string}}\n     */\n    $scope.current = {\n        searchString: $scope.$stateParams.q\n    };\n\n    // usersList is resolved during routing\n    $scope.usersList = usersList;\n\n    $scope.deactivate = function(user, index) {\n        UserService.deactivate({ username: user.username }, { activate: true }, function(response) {\n            $scope.usersList[index].activated = response.activated;\n        });\n    };\n\n    /**\n     * Change the state (so the url contains the search parameter), and updates\n     * the user data based on the search term.\n     */\n    $scope.search = function() {\n        // Update the route\n        $scope.$state.transitionTo('tatami.account.users.search',\n            { q: $scope.current.searchString },\n            { location: true, inherit: true, relative: $scope.$state.$current, notify: false });\n\n        // Now update the users based on the search term\n        SearchService.query({ term: 'users', q: $scope.current.searchString }, function(result) {\n            $scope.usersList = result;\n        });\n    };\n\n    $scope.followUser = function(user) {\n        UserService.follow({ username: user.username }, { friend: !user.friend, friendShip: true },\n            function() {\n                $scope.$state.reload();\n            }\n        );\n    };\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/users/UsersModule.js",
    "content": "var UsersModule = angular.module('UsersModule', []);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/users/UsersView.html",
    "content": "<div>\n    <h2 translate=\"tatami.account.users.title\"></h2>\n    <div class=\"tabMenu\">\n        <ul class=\"nav nav-tabs\">\n            <li ng-class=\"{ 'active': $state.current.name === 'tatami.account.users.following' }\">\n                <a ui-sref=\"tatami.account.users.following\" translate=\"tatami.account.users.following\"></a>\n            </li>\n            <li ng-class=\"{ 'active': $state.current.name === 'tatami.account.users.recommended' }\">\n                <a ui-sref=\"tatami.account.users.recommended\" translate=\"tatami.account.users.recommended\"></a>\n            </li>\n            <li ng-class=\"{ 'active': $state.current.name === 'tatami.account.users.search' }\">\n                <a ui-sref=\"tatami.account.users.search\" translate=\"tatami.account.users.search\"></a>\n            </li>\n        </ul>\n    </div>\n    <div>\n        <form class=\"row-fluid littleMargeBot\">\n            <input ng-show=\"$state.current.name === 'tatami.account.users.search'\" ng-model=\"current.searchString\" ng-trim=\"false\" ng-change=\"search()\" id=\"block_filter\" type=\"text\" class=\"search-query col-span-12\" name=\"result_filter\" autocomplete=\"off\" placeholder=\"{{ 'tatami.account.users.search' | translate }}\">\n        </form>\n        <div ng-repeat=\"user in usersList\">\n            <div class=\"useritem\">\n                <div class=\"pull-left background-image-fffix\">\n                    <div class=\"img img-rounded img-medium\" ng-style=\"{ 'background-image': 'url(' + user.avatarURL + ')' }\"></div>\n                </div>\n                <h4>\n                    <span ng-if=\"!user.you\" ng-click=\"followUser(user, $index)\" ng-init=\"hover = false\" ng-mouseenter=\"hover = true\" ng-mouseleave=\"hover = false\" class=\"pointer pull-right label\" ng-class=\"{ 'label-danger': user.friend && hover, 'label-info': user.friend && !hover }\">\n                        <span class=\"glyphicon\" ng-class=\"user.friend ? 'glyphicon-minus' : 'glyphicon-plus'\"></span>\n                    </span>\n                    <span ng-show=\"!user.activated\">\n                        <span ng-class=\"!user.activated ? 'badge hidden-phone progress-bar-danger' : ''\" class=\"glyphicon glyphicon-off\">\n                            {{ 'tatami.account.users.deactivated' | translate }}\n                        </span>\n                    </span>\n                    <a ui-sref=\"tatami.home.profile.statuses({ username: user.username })\">\n                        <strong>\n                            {{ user.firstName + ' ' + user.lastName }}\n                        </strong>\n                    </a>\n                    <br>\n                    <a ui-sref=\"tatami.home.profile.statuses({ username: user.username })\">\n                        <small>\n                            @{{ user.username }}\n                        </small>\n                    </a>\n                    <span ng-click=\"deactivate(user, $index)\" ng-show=\"isAdmin && user.activated && !user.you\" class=\"pointer pull-right label label-danger\">\n                        <span class=\"glyphicon glyphicon-minus\" translate=\"tatami.admin.deactivate\"></span>\n                    </span>\n                    <span ng-click=\"deactivate(user, $index)\" ng-show=\"isAdmin && !user.activated && !user.you\" class=\"pointer pull-right label label-info\">\n                        <span class=\"glyphicon glyphicon-plus\" translate=\"tatami.admin.activate\"></span>\n                    </span>\n                </h4>\n            </div>\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/account/users/directives/UserAccountController.js",
    "content": "UsersModule.factory('UserAccountController', ['$scope', function() {\n\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/account/users/directives/UserAccountDirective.js",
    "content": "UsersModule.directive('tatamiAccountUser', function() {\n    return {\n        restrict: 'E',\n        controller: 'UsersController',\n        scope: {\n            user: '=',\n            isAdmin: '='\n        },\n        templateUrl: '/app/components/account/users/directives/UserAccountView.html'\n    };\n\n});"
  },
  {
    "path": "web/src/main/webapp/app/components/account/users/directives/UserAccountView.html",
    "content": "<div class=\"useritem\">\n    <div class=\"pull-left background-image-fffix\">\n        <div class=\"img img-rounded img-medium\" ng-style=\"{ 'background-image': 'url(' + user.avatarURL + ')' }\"></div>\n    </div>\n    <h4>\n        <span ng-if=\"!user.you\" ng-click=\"followUser(user, $index)\" ng-init=\"hover = false\" ng-mouseenter=\"hover = true\" ng-mouseleave=\"hover = false\" class=\"pointer pull-right label\" ng-class=\"{ 'label-danger': user.friend && hover, 'label-info': user.friend && !hover }\">\n            <span class=\"glyphicon\" ng-class=\"user.friend ? 'glyphicon-minus' : 'glyphicon-plus'\"></span>\n        </span>\n        <span ng-show=\"!user.activated\">\n            <span class=\"glyphicon glyphicon-off\">\n                {{ 'tatami.account.users.deactivated' | translate }}\n            </span>\n        </span>\n        <a ui-sref=\"tatami.home.profile.statuses({ username: user.username })\">\n            <strong>\n                {{ user.firstName + ' ' + user.lastName }}\n            </strong>\n        </a>\n        <br>\n        <a ui-sref=\"tatami.home.profile.statuses({ username: user.username })\">\n            <small>\n                @{{ user.username }}\n            </small>\n        </a>\n        <span ng-click=\"deactivate(user)\" ng-show=\"isAdmin && user.activated && !user.you\" class=\"pointer pull-right label label-danger\">\n            <span class=\"glyphicon glyphicon-minus\" translate=\"tatami.admin.deactivate\"></span>\n        </span>\n        <span ng-click=\"deactivate(user)\" ng-show=\"isAdmin && !user.activated && !user.you\" class=\"pointer pull-right label label-info\">\n            <span class=\"glyphicon glyphicon-plus\" translate=\"tatami.admin.activate\"></span>\n        </span>\n    </h4>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/admin/AdminController.js",
    "content": "AdminModule.controller('AdminController', [\n    '$scope',\n    '$translate',\n    'AdminService',\n    'adminData',\n    function($scope, $translate, AdminService, adminData) {\n        $scope.adminData = adminData;\n\n        $scope.reindex = function() {\n            if(confirm($translate.instant('tatami.admin.confirm'))) {\n                AdminService.save({ options: 'reindex' });\n                $scope.$state.go('admin', { message: 'reindex' });\n            }\n        };\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/admin/AdminModule.js",
    "content": "var AdminModule = angular.module('AdminModule', []);\n\nAdminModule.config(['$stateProvider', '$urlRouterProvider', function($stateProvider) {\n    $stateProvider\n        .state('admin',{\n            url: '/admin?message',\n            templateUrl: '/app/components/admin/AdminView.min.html',\n            resolve: {\n                adminData: ['AdminService', '$state', function(AdminService, $state) {\n                    return AdminService.get().$promise.then(function(success) {\n                        return success;\n                    }, function(err) {\n                        if(err.status === 500) {\n                            $state.transitionTo('tatami.accessdenied', null, { location: false });\n                        }\n                    });\n                }]\n            },\n            controller: 'AdminController'\n        });\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/admin/AdminService.js",
    "content": "AdminModule.factory('AdminService', ['$resource', function($resource) {\n    return $resource('/tatami/admin/:options', { options: '@options' });\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/admin/AdminView.html",
    "content": "<div id=\"mainPanel\" class=\"container\">\n    <div ng-show=\"$stateParams.message === 'reindex'\" class=\"alert alert-success\" translate=\"tatami.admin.success\"></div>\n    <div class=\"row\">\n        <div class=\"col-span-12\">\n            <h1 translate=\"tatami.admin.title\"></h1>\n        </div>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-span-12\">\n            <div class=\"row-fluid\">\n                <div class=\"tab-content col-span-12\">\n                    <h2 translate=\"tatami.admin.registered\"></h2>\n                    <table class=\"table table-striped\">\n                        <thead>\n                        <tr>\n                            <th translate=\"tatami.admin.domain\"></th>\n                            <th translate=\"tatami.admin.count\"></th>\n                        </tr>\n                        </thead>\n                        <tbody>\n                            <tr ng-repeat=\"domain in adminData.domains\">\n                                <td>\n                                    {{ domain.name }}\n                                </td>\n                                <td>\n                                    {{ domain.numberOfUsers }}\n                                </td>\n                            </tr>\n                        </tbody>\n                    </table>\n                </div>\n            </div>\n        </div>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-span-12\">\n            <div class=\"row-fluid\">\n                <div class=\"tab-content col-span-12\">\n                    <h2 translate=\"tatami.admin.environment\"></h2>\n                    <table class=\"table table-striped\">\n                        <thead>\n                            <tr>\n                                <th translate=\"tatami.admin.property\"></th>\n                                <th translate=\"tatami.admin.value\"></th>\n                            </tr>\n                        </thead>\n                        <tbody>\n                            <tr ng-repeat=\"(key, value) in adminData.properties\">\n                                <td>\n                                    {{ key }}\n                                </td>\n                                <td>\n                                    {{ value }}\n                                </td>\n                            </tr>\n                        </tbody>\n                    </table>\n                </div>\n            </div>\n        </div>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-span-12\">\n            <h2 translate=\"tatami.admin.reindex\"></h2>\n\n            <form class=\"form-horizontal\">\n                <fieldset>\n                    <div class=\"form-actions\">\n                        <button type=\"submit\" class=\"input-xlarge btn btn-danger\" ng-click=\"reindex()\" translate=\"tatami.admin.reindex\"></button>\n                    </div>\n                </fieldset>\n            </form>\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/home/HomeModule.js",
    "content": "var HomeModule = angular.module('HomeModule', [\n    'HomeSidebarModule',\n    'ProfileSidebarModule',\n    'ngSanitize',\n    'angularMoment',\n    'infinite-scroll'\n]);\n\nHomeModule.run(['UserSession', '$rootScope', '$location', '$interval', '$state', '$document', function (UserSession, $rootScope, $location, $interval, $state) {\n    $interval(function () {\n        //if the user is logged in, not at the login page, and inactive...\n        if (UserSession.isAuthenticated() && UserSession.isUserResolved()) {\n            try {\n                UserSession.authenticate(true);\n            } catch (err) {\n                UserSession.clearSession();\n                $state.go('tatami.login.main');\n                alert('User logged out due to session expiration.');\n            }\n        }\n    }, 1000 * 60 * 10); //10 minutes\n}]);\n\nHomeModule.config(['$stateProvider', function ($stateProvider) {\n    $stateProvider\n        .state('tatami.home', {\n            url: '/home',\n            abstract: true,\n            templateUrl: 'app/components/home/HomeView.min.html',\n            resolve: {\n                profile: ['ProfileService', function (ProfileService) {\n                    return ProfileService.get().$promise;\n                }],\n\n                userRoles: ['$http', function ($http) {\n                    return $http({method: 'GET', url: '/tatami/rest/account/admin'}).then(function (result) {\n                        return result.data;\n                    });\n                }]\n            }\n        })\n        .state('tatami.home.status', {\n            url: '/status/:statusId',\n            views: {\n                'homeBodyContent@tatami.home': {\n                    templateUrl: 'app/components/home/status/StatusView.min.html',\n                    controller: 'StatusController'\n                }\n            },\n            resolve: {\n                status: ['StatusService', '$stateParams', '$q', function (StatusService, $stateParams, $q) {\n                    return StatusService.get({statusId: $stateParams.statusId})\n                        .$promise.then(\n                        function (response) {\n                            if (angular.equals({}, response.toJSON())) {\n                                return $q.reject();\n                            }\n                            return response;\n                        });\n                }],\n                context: ['StatusService', '$stateParams', function (StatusService, $stateParams) {\n                    return StatusService.getDetails({statusId: $stateParams.statusId}).$promise;\n                }]\n            }\n        })\n        .state('tatami.home.search', {\n            url: '/search/:searchTerm',\n            views: {\n                'homeBodyHeader@tatami.home': {\n                    templateUrl: 'app/components/home/search/SearchHeaderView.min.html',\n                    controller: 'SearchHeaderController'\n                },\n                'homeBodyContent@tatami.home': {\n                    templateUrl: 'app/shared/lists/status/withoutContext/StatusListView.min.html',\n                    controller: 'StatusListController'\n                }\n            },\n            resolve: {\n                statuses: ['SearchService', '$stateParams', function (SearchService, $stateParams) {\n                    return SearchService.query({term: 'status', q: $stateParams.searchTerm}).$promise;\n                }],\n                showModal: function () {\n                    return false;\n                }\n            }\n        })\n        //state for all views that use home sidebar\n        .state('tatami.home.home', {\n            url: '^/home',\n            abstract: true,\n            resolve: {\n                groups: ['GroupService', function (GroupService) {\n                    return GroupService.query().$promise;\n                }],\n                tags: ['TagService', function (TagService) {\n                    return TagService.query({popular: true}).$promise;\n                }],\n                suggestions: ['UserService', function (UserService) {\n                    return UserService.getSuggestions().$promise;\n                }],\n                showModal: function () {\n                    return false;\n                }\n            }\n        })\n        .state('tatami.home.home.timeline', {\n            url: '/timeline',\n            views: {\n                'homeSide@tatami.home': {\n                    templateUrl: 'app/shared/sidebars/home/HomeSidebarView.min.html',\n                    controller: 'HomeSidebarController'\n                },\n                'homeBodyHeader@tatami.home': {\n                    templateUrl: 'app/components/home/timeline/TimelineHeaderView.min.html'\n                },\n                'homeBodyContent@tatami.home': {\n                    templateUrl: 'app/shared/lists/status/withoutContext/StatusListView.min.html',\n                    controller: 'StatusListController'\n                }\n            },\n            resolve: {\n                statuses: ['StatusService', function (StatusService) {\n                    return StatusService.getHomeTimeline().$promise;\n                }],\n                showModal: ['statuses', function (statuses) {\n                    return statuses.length === 0;\n                }]\n            }\n        })\n        .state('tatami.home.home.timeline.presentation', {\n            url: '',\n            onEnter: ['$stateParams', '$modal', function ($stateParams, $modal) {\n                $modal.open({\n                    templateUrl: 'app/components/home/welcome/WelcomeView.min.html',\n                    controller: 'WelcomeController'\n                });\n            }]\n        })\n        .state('tatami.home.home.mentions', {\n            url: '/mentions',\n            views: {\n                'homeSide@tatami.home': {\n                    templateUrl: 'app/shared/sidebars/home/HomeSidebarView.min.html',\n                    controller: 'HomeSidebarController'\n                },\n                'homeBodyHeader@tatami.home': {\n                    templateUrl: 'app/components/home/timeline/TimelineHeaderView.min.html'\n                },\n                'homeBodyContent@tatami.home': {\n                    templateUrl: 'app/shared/lists/status/withoutContext/StatusListView.min.html',\n                    controller: 'StatusListController'\n                }\n            },\n            resolve: {\n                statuses: ['HomeService', function (HomeService) {\n                    return HomeService.getMentions().$promise;\n                }]\n\n            }\n        })\n        .state('tatami.home.home.favorites', {\n            url: '/favorites',\n            views: {\n                'homeSide@tatami.home': {\n                    templateUrl: 'app/shared/sidebars/home/HomeSidebarView.min.html',\n                    controller: 'HomeSidebarController'\n                },\n                'homeBodyHeader@tatami.home': {\n                    templateUrl: 'app/components/home/timeline/TimelineHeaderView.min.html'\n                },\n                'homeBodyContent@tatami.home': {\n                    templateUrl: 'app/shared/lists/status/withoutContext/StatusListView.min.html',\n                    controller: 'StatusListController'\n                }\n            },\n            resolve: {\n                statuses: ['HomeService', function (HomeService) {\n                    return HomeService.getFavorites().$promise;\n                }]\n            }\n        })\n        .state('tatami.home.home.company', {\n            url: '/company',\n            views: {\n                'homeSide@tatami.home': {\n                    templateUrl: 'app/shared/sidebars/home/HomeSidebarView.min.html',\n                    controller: 'HomeSidebarController'\n                },\n                'homeBodyHeader@tatami.home': {\n                    templateUrl: 'app/components/home/timeline/TimelineHeaderView.min.html'\n                },\n                'homeBodyContent@tatami.home': {\n                    templateUrl: 'app/shared/lists/status/withoutContext/StatusListView.min.html',\n                    controller: 'StatusListController'\n                }\n            },\n            resolve: {\n                statuses: ['HomeService', function (HomeService) {\n                    return HomeService.getCompanyTimeline().$promise;\n                }]\n            }\n        })\n        .state('tatami.home.home.tag', {\n            url: '/tag/:tag',\n            views: {\n                'homeSide@tatami.home': {\n                    templateUrl: 'app/shared/sidebars/home/HomeSidebarView.min.html',\n                    controller: 'HomeSidebarController'\n                },\n                'homeBodyHeader@tatami.home': {\n                    templateUrl: 'app/components/home/tag/TagHeaderView.min.html',\n                    controller: 'TagHeaderController'\n                },\n                'homeBodyContent@tatami.home': {\n                    templateUrl: 'app/shared/lists/status/withoutContext/StatusListView.min.html',\n                    controller: 'StatusListController'\n                }\n            },\n            resolve: {\n                tag: ['TagService', '$stateParams', function (TagService, $stateParams) {\n                    return TagService.get({tag: $stateParams.tag}).$promise;\n                }],\n                statuses: ['TagService', '$stateParams', function (TagService, $stateParams) {\n                    return TagService.getTagTimeline({tag: $stateParams.tag}).$promise;\n                }]\n            }\n        })\n        .state('tatami.home.home.group', {\n            url: '/group/:groupId',\n            abstract: true,\n            resolve: {\n                group: ['GroupService', '$stateParams', function (GroupService, $stateParams) {\n                    return GroupService.get({groupId: $stateParams.groupId}).$promise;\n                }]\n            }\n        })\n        .state('tatami.home.home.group.statuses', {\n            url: '/statuses',\n            views: {\n                'homeSide@tatami.home': {\n                    templateUrl: 'app/shared/sidebars/home/HomeSidebarView.min.html',\n                    controller: 'HomeSidebarController'\n                },\n                'homeBodyHeader@tatami.home': {\n                    templateUrl: 'app/components/home/group/GroupHeaderView.min.html',\n                    controller: 'GroupHeaderController'\n                },\n                'homeBodyContent@tatami.home': {\n                    templateUrl: 'app/shared/lists/status/withoutContext/StatusListView.min.html',\n                    controller: 'StatusListController'\n                }\n            },\n            resolve: {\n                statuses: ['GroupService', '$stateParams', function (GroupService, $stateParams) {\n                    return GroupService.getStatuses({groupId: $stateParams.groupId}).$promise;\n                }]\n            }\n        })\n        .state('tatami.home.home.group.members', {\n            url: '/members',\n            views: {\n                'homeSide@tatami.home': {\n                    templateUrl: 'app/shared/sidebars/home/HomeSidebarView.min.html',\n                    controller: 'HomeSidebarController'\n                },\n                'homeBodyHeader@tatami.home': {\n                    templateUrl: 'app/components/home/group/GroupHeaderView.min.html',\n                    controller: 'GroupHeaderController'\n                },\n                'homeBodyContent@tatami.home': {\n                    templateUrl: 'app/shared/lists/user/UserListView.min.html',\n                    controller: 'UserListController'\n                }\n            },\n            resolve: {\n                users: ['GroupService', '$stateParams', function (GroupService, $stateParams) {\n                    return GroupService.getMembers({groupId: $stateParams.groupId}).$promise;\n                }]\n            }\n        })\n        //state for all views that use profile sidebar\n        .state('tatami.home.profile', {\n            url: '/profile/:username',\n            abstract: true,\n            resolve: {\n                user: ['UserService', '$stateParams', function (UserService, $stateParams) {\n                    return UserService.get({username: $stateParams.username}).$promise;\n                }],\n                tags: ['TagService', '$stateParams', function (TagService, $stateParams) {\n                    return TagService.query({popular: true, user: $stateParams.username}).$promise;\n                }]\n            }\n        })\n        .state('tatami.home.profile.statuses', {\n            url: '/statuses',\n            views: {\n                'homeSide@tatami.home': {\n                    templateUrl: 'app/shared/sidebars/profile/ProfileSidebarView.min.html',\n                    controller: 'ProfileSidebarController'\n                },\n                'homeBodyHeader@tatami.home': {\n                    templateUrl: 'app/components/home/profile/ProfileHeaderView.min.html',\n                    controller: 'ProfileHeaderController'\n                },\n                'homeBodyContent@tatami.home': {\n                    templateUrl: 'app/shared/lists/status/withoutContext/StatusListView.min.html',\n                    controller: 'StatusListController'\n                }\n            },\n            resolve: {\n                statuses: ['StatusService', '$stateParams', function (StatusService, $stateParams) {\n                    return StatusService.getUserTimeline({username: $stateParams.username}).$promise;\n                }],\n                showModal: function () {\n                    return false;\n                }\n            }\n        })\n        .state('tatami.home.profile.following', {\n            url: '/following',\n            views: {\n                'homeSide@tatami.home': {\n                    templateUrl: 'app/shared/sidebars/profile/ProfileSidebarView.min.html',\n                    controller: 'ProfileSidebarController'\n                },\n                'homeBodyHeader@tatami.home': {\n                    templateUrl: 'app/components/home/profile/ProfileHeaderView.min.html',\n                    controller: 'ProfileHeaderController'\n                },\n                'homeBodyContent@tatami.home': {\n                    templateUrl: 'app/shared/lists/user/UserListView.min.html',\n                    controller: 'UserListController'\n                }\n            },\n            resolve: {\n                users: ['UserService', '$stateParams', function (UserService, $stateParams) {\n                    return UserService.getFollowing({username: $stateParams.username}).$promise;\n                }]\n            }\n        })\n        .state('tatami.home.profile.followers', {\n            url: '/followers',\n            views: {\n                'homeSide@tatami.home': {\n                    templateUrl: 'app/shared/sidebars/profile/ProfileSidebarView.min.html',\n                    controller: 'ProfileSidebarController'\n                },\n                'homeBodyHeader@tatami.home': {\n                    templateUrl: 'app/components/home/profile/ProfileHeaderView.min.html',\n                    controller: 'ProfileHeaderController'\n                },\n                'homeBodyContent@tatami.home': {\n                    templateUrl: 'app/shared/lists/user/UserListView.min.html',\n                    controller: 'UserListController'\n                }\n            },\n            resolve: {\n                users: ['UserService', '$stateParams', function (UserService, $stateParams) {\n                    return UserService.getFollowers({username: $stateParams.username}).$promise;\n                }]\n            }\n        });\n}\n]);"
  },
  {
    "path": "web/src/main/webapp/app/components/home/HomeView.html",
    "content": "<div>\n    <div class=\"row\">\n        <aside ui-view=\"homeSide\" id=\"tatamiSide\" class=\"col-span-3\"></aside>\n        <section ui-view=\"homeBody\" id=\"tatamiBody\" class=\"col-span-6\">\n            <div ui-view=\"homeBodyHeader\"></div>\n            <div ui-view=\"homeBodyContent\"></div>\n        </section>\n    </div>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/home/group/GroupHeaderController.js",
    "content": "HomeModule.controller('GroupHeaderController', ['$scope', 'GroupService', 'profile', 'group',\n    function($scope, GroupService, profile, group) {\n        $scope.profile = profile;\n        $scope.group = group;\n\n        $scope.joinLeaveGroup = function() {\n            if(!$scope.group.member) {\n                GroupService.join(\n                    { groupId: $scope.group.groupId, username: $scope.profile.username },\n                    null,\n                    function(response) {\n                        if(response.isMember) {\n                            $scope.group.member = response.isMember;\n                            $scope.$state.reload();\n                        }\n                    }\n                );\n            }\n\n            else {\n                GroupService.leave(\n                    { groupId: $scope.group.groupId, username: $scope.profile.username },\n                    null,\n                    function(response) {\n                        if(response) {\n                            $scope.group.member = !response;\n                            $scope.$state.reload();\n                        }\n                    }\n                );\n            }\n        };\n    }\n]);"
  },
  {
    "path": "web/src/main/webapp/app/components/home/group/GroupHeaderView.html",
    "content": "<div>\n    <ul class=\"homebody-nav nav nav-justified\">\n        <li ui-sref-active=\"active\">\n            <a ui-sref=\"tatami.home.home.group.statuses\">\n            <i class=\"glyphicon glyphicon-th-list\"></i>\n            <span translate=\"tatami.home.group.statuses\"></span>\n            </a>\n        </li>\n        <li ui-sref-active=\"active\">\n            <a ui-sref=\"tatami.home.home.group.members\">\n            <i class=\"glyphicon glyphicon-user\"></i>\n            <span translate=\"tatami.home.group.members\"></span>\n            </a>\n        </li>\n    </ul>\n    <section class=\"tatams-content tatams-margin\">\n        <div class=\"tatams-content-title\">\n            <h3>\n                <strong>{{ group.name }}: </strong>\n                <span ng-if=\"$state.includes('tatami.home.home.group.statuses')\">\n                    <strong ng-if=\"group.description\">{{ group.description }}</strong>\n                    <strong ng-if=\"!group.description\" translate=\"tatami.home.group.statuses\"></strong>\n                </span>\n                <span ng-if=\"$state.includes('tatami.home.home.group.members')\">\n                    <strong ng-if=\"group.counter == 1\" translate=\"tatami.home.group.membersSingular\"></strong>\n                    <strong ng-if=\"group.counter > 1\" translate=\"tatami.home.group.membersPlural\" translate-values=\"{ amount: group.counter }\"></strong>\n                </span>\n                <span ng-if=\"group.administrator\">\n                    <button ui-sref=\"tatami.account.groups.manage({ groupId: group.groupId })\" class=\"pull-right btn btn-sm btn-primary hidden-phone\" type=\"button\">\n                        <span class=\"glyphicon glyphicon-th-large\"></span>\n                        <span translate=\"tatami.home.group.manage\"></span>\n                    </button>\n                </span>\n                <span ng-if=\"!group.administrator\">\n                    <button type=\"button\" ng-click=\"joinLeaveGroup()\" ng-init=\"hover = false\" ng-mouseenter=\"hover = true\" ng-mouseleave=\"hover = false\" class=\"btn btn-sm pull-right\" ng-class=\"{ 'btn-danger': group.member && hover, 'btn-info': group.member && !hover }\">\n                        <span class=\"glyphicon\" ng-class=\"group.member ? 'glyphicon-minus' : 'glyphicon-plus'\">\n                            <span ng-if=\"!group.member\" class=\"hidden-phone\" translate=\"tatami.home.group.join\"></span>\n                            <span ng-if=\"group.member && !hover\" class=\"hidden-phone\" translate=\"tatami.home.group.joined\"></span>\n                            <span ng-if=\"group.member && hover\" class=\"hidden-phone\" translate=\"tatami.home.group.leave\"></span>\n                        </span>\n                    </button>\n                </span>\n            </h3>\n        </div>\n    </section>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/home/profile/ProfileHeaderController.js",
    "content": "HomeModule.controller('ProfileHeaderController', ['$scope', 'UserService', 'user',\n    function($scope, UserService, user) {\n        $scope.user = user;\n\n        $scope.followUnfollowUser = function() {\n            UserService.follow(\n                { username: $scope.user.username },\n                { friend: !$scope.user.friend, friendShip: true },\n                function(response) {\n                    $scope.user.friend = response.friend;\n                    $scope.$state.reload();\n            });\n        };\n    }\n]);"
  },
  {
    "path": "web/src/main/webapp/app/components/home/profile/ProfileHeaderView.html",
    "content": "<div>\n    <ul class=\"homebody-nav nav nav-justified\">\n        <li ui-sref-active=\"active\">\n            <a ui-sref=\"tatami.home.profile.statuses\">\n            <i class=\"glyphicon glyphicon-th-list\"></i>\n            <span translate=\"tatami.home.profile.statuses\"></span>\n            </a>\n        </li>\n        <li ui-sref-active=\"active\">\n            <a ui-sref=\"tatami.home.profile.following\">\n            <i class=\"glyphicon glyphicon-user\"></i>\n            <span translate=\"tatami.home.profile.following\"></span>\n            </a>\n        </li>\n        <li ui-sref-active=\"active\">\n            <a ui-sref=\"tatami.home.profile.followers\">\n            <i class=\"glyphicon glyphicon-user\"></i>\n            <span translate=\"tatami.home.profile.followers\"></span>\n            </a>\n        </li>\n    </ul>\n    <section class=\"tatams-content tatams-margin\">\n        <div class=\"tatams-content-title\">\n            <h3>\n                <span ng-if=\"$state.includes('tatami.home.profile.statuses')\">\n                    <span ng-if=\"user.you\">\n                        <strong ng-if=\"user.statusCount == 1\" translate=\"tatami.home.profile.youStatusesSingular\"></strong>\n                        <strong ng-if=\"user.statusCount <= 0 || user.statusCount > 1\" translate=\"tatami.home.profile.youStatusesPlural\" translate-values=\"{ amount: user.statusCount }\"></strong>\n                    </span>\n                    <span ng-if=\"!user.you\">\n                        <strong ng-if=\"user.statusCount == 1\" translate=\"tatami.home.profile.userStatusesSingular\" translate-values=\"{ username: user.username }\"></strong>\n                        <strong ng-if=\"user.statusCount <= 0 || user.statusCount > 1\" translate=\"tatami.home.profile.userStatusesPlural\" translate-values=\"{ username: user.username, amount: user.statusCount }\"></strong>\n                    </span>\n                    <span ng-if=\"user.follower\" class=\"badge hidden-phone\">\n                        {{ 'tatami.home.profile.followsYou' | translate | uppercase }}\n                    </span>\n                    <span ng-if=\"!user.activated\" class=\"badge hidden-phone progress-bar-danger\">\n                        {{ 'tatami.home.profile.deactivatedUser' | translate | uppercase }}\n                    </span>\n                </span>\n\n                <span ng-if=\"$state.includes('tatami.home.profile.following')\">\n                    <span ng-if=\"user.you\">\n                        <strong ng-if=\"user.friendsCount == 1\" translate=\"tatami.home.profile.youFollowingSingular\"></strong>\n                        <strong ng-if=\"user.friendsCount <= 0 || user.friendsCount > 1\" translate=\"tatami.home.profile.youFollowingPlural\" translate-values=\"{ amount: user.friendsCount }\"></strong>\n                    </span>\n                    <span ng-if=\"!user.you\">\n                        <strong ng-if=\"user.friendsCount == 1\" translate=\"tatami.home.profile.userFollowingSingular\" translate-values=\"{ username: user.username }\"></strong>\n                        <strong ng-if=\"user.friendsCount <= 0 || user.friendsCount > 1\" translate=\"tatami.home.profile.userFollowingPlural\" translate-values=\"{ username: user.username, amount: user.friendsCount }\"></strong>\n                    </span>\n                    <span ng-if=\"user.follower\" class=\"badge hidden-phone\">\n                        {{ 'tatami.home.profile.followsYou' | translate | uppercase }}\n                    </span>\n                    <span ng-if=\"!user.activated\" class=\"badge hidden-phone progress-bar-danger\">\n                        {{ 'tatami.home.profile.deactivatedUser' | translate | uppercase }}\n                    </span>\n                </span>\n\n                <span ng-if=\"$state.includes('tatami.home.profile.followers')\">\n                    <span ng-if=\"user.you\">\n                        <strong ng-if=\"user.followersCount == 1\" translate=\"tatami.home.profile.youFollowersSingular\"></strong>\n                        <strong ng-if=\"user.followersCount <= 0 || user.followersCount > 1\" translate=\"tatami.home.profile.youFollowersPlural\" translate-values=\"{ amount: user.followersCount }\"></strong>\n                    </span>\n                    <span ng-if=\"!user.you\">\n                        <strong ng-if=\"user.followersCount == 1\" translate=\"tatami.home.profile.userFollowersSingular\" translate-values=\"{ username: user.username }\"></strong>\n                        <strong ng-if=\"user.followersCount <= 0 || user.followersCount > 1\" translate=\"tatami.home.profile.userFollowersPlural\" translate-values=\"{ username: user.username, amount: user.followersCount }\"></strong>\n                    </span>\n                    <span ng-if=\"user.follower\" class=\"badge hidden-phone\">\n                        {{ 'tatami.home.profile.followsYou' | translate | uppercase }}\n                    </span>\n                    <span ng-if=\"!user.activated\" class=\"badge hidden-phone progress-bar-danger\">\n                        {{ 'tatami.home.profile.deactivatedUser' | translate | uppercase }}\n                    </span>\n                </span>\n\n                <span ng-if=\"!user.you\">\n                    <button type=\"button\" ng-click=\"followUnfollowUser()\" ng-init=\"hover = false\" ng-mouseenter=\"hover = true\" ng-mouseleave=\"hover = false\" class=\"btn btn-sm pull-right\" ng-class=\"{ 'btn-danger': user.friend && hover, 'btn-info': user.friend && !hover }\">\n                        <span class=\"glyphicon\" ng-class=\"user.friend ? 'glyphicon-minus' : 'glyphicon-plus'\">\n                            <span ng-if=\"!user.friend\" class=\"hidden-phone\" translate=\"tatami.home.profile.follow\"></span>\n                            <span ng-if=\"user.friend && !hover\" class=\"hidden-phone\" translate=\"tatami.home.profile.following\"></span>\n                            <span ng-if=\"user.friend && hover\" class=\"hidden-phone\" translate=\"tatami.home.profile.unfollow\"></span>\n                        </span>\n                    </button>\n                </span>\n            </h3>\n        </div>\n    </section>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/home/search/SearchHeaderController.js",
    "content": "HomeModule.controller('SearchHeaderController', ['$scope', '$stateParams',\n    function($scope, $stateParams) {\n        $scope.searchTerm = $stateParams.searchTerm;\n    }\n]);"
  },
  {
    "path": "web/src/main/webapp/app/components/home/search/SearchHeaderView.html",
    "content": "<div>\n    <ul class=\"homebody-nav nav nav-justified\">\n        <li ui-sref-active=\"active\">\n            <a ui-sref=\"tatami.home.search\">\n            <i class=\"glyphicon glyphicon-search\"></i>\n            <span translate=\"tatami.home.searchPage.title\"></span>\n            </a>\n        </li>\n    </ul>\n    <section class=\"tatams-content tatams-margin\">\n        <div class=\"tatams-content-title\">\n            <h3>\n                <strong translate=\"tatami.home.searchPage.statusesWith\"></strong>\n                <strong>\"{{ searchTerm }}\"</strong>\n            </h3>\n        </div>\n    </section>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/home/status/StatusController.js",
    "content": "HomeModule.controller('StatusController', [\n    '$scope',\n    '$translate',\n    'StatusService',\n    'profile',\n    'status',\n    'context',\n    'userRoles',\n    function($scope, $translate, StatusService, profile, status, context, userRoles) {\n        $scope.isAdmin = userRoles.roles.indexOf('ROLE_ADMIN') !== -1;\n\n        $scope.profile = profile;\n\n        if(context.discussionStatuses.length === 0) {\n            $scope.statuses = [status];\n        } else {\n            $scope.statuses = context.discussionStatuses;\n        }\n        try {\n          for(var i = 0; i <= context.discussionStatuses.length; i++) {\n              if (status.statusDate < $scope.statuses[i].statusDate) {\n                  $scope.statuses.splice(i, 0, status);\n                  break;\n              }\n          }\n        } catch(err) {\n            $scope.statuses.push(status);\n        }\n\n        $scope.isOneDayOrMore = function(date) {\n            return moment().diff(moment(date), 'days', true) >= 1;\n        };\n\n        $scope.getLanguageKey = function() {\n            return $translate.use();\n        };\n\n        $scope.openReplyModal = function(status) {\n            $scope.$state.go($scope.$state.current.name + '.post', { statusIdReply: status.statusId });\n        };\n\n        $scope.favoriteStatus = function(status, index) {\n            StatusService.update({ statusId: status.statusId }, { favorite: !status.favorite },\n                function(response) {\n                    $scope.statuses[index].favorite = response.favorite;\n            });\n        };\n\n        $scope.shareStatus = function(status, index) {\n            StatusService.update({ statusId: status.statusId }, { shared: !status.shareByMe },\n                function(response) {\n                    $scope.statuses[index].shareByMe = response.shareByMe;\n            });\n        };\n\n        $scope.announceStatus = function(status) {\n            StatusService.update({ statusId: status.statusId }, { announced: true },\n                function() {\n                    $scope.$state.reload();\n            });\n        };\n\n        $scope.deleteStatus = function(status, index) {\n            // Need a confirmation modal here\n            StatusService.delete({ statusId: status.statusId }, null,\n                function() {\n                    if($scope.$stateParams.statusId === status.statusId) {\n                        $scope.$state.transitionTo('tatami.home.home.timeline');\n                    } else {\n                        $scope.statuses.splice(index, 1);\n                    }\n            });\n        };\n\n        $scope.getShares = function(status, index) {\n            if(status.type === 'STATUS' && status.shares === null) {\n                StatusService.getDetails({ statusId: status.statusId }, null,\n                    function(response) {\n                        $scope.statuses[index].shares = response.sharedByLogins;\n                });\n            }\n        };\n    }\n]);"
  },
  {
    "path": "web/src/main/webapp/app/components/home/status/StatusView.html",
    "content": "<section class=\"tatams-container\">\n    <section class=\"timeline\">\n        <div class=\"tatams\" ng-repeat=\"status in statuses\">\n            <div ng-class=\"{ 'tatam-background': status.statusId != $stateParams.statusId, 'status-top-rounded': $index == 0 && $index != statuses.length - 1, 'status-bottom-rounded': $index == statuses.length - 1 && $index != 0, 'status-both-rounded': $index == 0 && $index == statuses.length - 1 }\" class=\"tatam pointer tatam-border-lr\" style=\"display: block;\">\n                <div id=\"current\" ng-mouseenter=\"showButtonRow = true\" ng-mouseleave=\"showButtonRow = false\">\n                    <div ng-class=\"{ 'favorite': status.favorite, 'share': status.shareByMe, 'both': status.favorite && status.shareByMe }\">\n                        <div class=\"pull-left background-image-fffix statusitem-img\">\n                            <a ui-sref=\"tatami.home.profile.statuses({ username: status.username })\">\n                                <div class=\"img img-rounded img-medium\" ng-style=\"{ 'background-image': 'url(' + status.avatarURL + ')' }\"></div>\n                            </a>\n                        </div>\n                        <div class=\"status-content-container\" ng-init=\"expanded = false\" ng-click=\"getShares(status, $index); expanded = !expanded\">\n                            <h5 class=\"statusitem-name\">\n                                <small ng-if=\"status.type == 'SHARE'\">\n                                    <span class=\"glyphicon glyphicon-retweet\">&nbsp;</span>\n                                    <a ui-sref=\"tatami.home.profile.statuses({ username: status.username })\">\n                                        <span class=\"text-muted\">@{{ status.sharedByUsername }}</span>\n                                    </a>\n                                    <span translate=\"tatami.home.status.shared\"></span>\n                                    <br>\n                                </small>\n                                <span ng-if=\"status.type == 'MENTION_SHARE'\" class=\"glyphicon glyphicon-retweet\">&nbsp;</span>\n                                <span ng-if=\"status.type == 'MENTION_FRIEND'\" class=\"glyphicon glyphicon-user\">&nbsp;</span>\n                                <a ui-sref=\"tatami.home.profile.statuses({ username: status.username })\">\n                                    <strong>{{ status.firstName + ' ' + status.lastName }}</strong>\n                                    <small>@{{ status.username }}</small>\n                                </a>\n                                <span ng-if=\"status.type == 'MENTION_SHARE'\" translate=\"tatami.home.status.sharedYour\"></span>\n                                <span ng-if=\"status.type == 'MENTION_FRIEND'\" translate=\"tatami.home.status.followed\"></span>\n                                <small> · </small>\n                                <!-- Replace hover title with hover bubble -->\n                                <a ui-sref=\"tatami.home.status({ statusId: status.statusId })\">\n                                    <!--English-->\n                                    <small ng-if=\"!isOneDayOrMore(status.statusDate) && getLanguageKey() == 'en'\" title=\"{{ status.statusDate | amDateFormat:'h:mm A - D MMM YYYY' }}\" am-time-ago=\"status.statusDate\"></small>\n                                    <small ng-if=\"isOneDayOrMore(status.statusDate) && getLanguageKey() == 'en'\" title=\"{{ status.statusDate | amDateFormat:'h:mm A - D MMM YYYY' }}\">{{ status.statusDate | amDateFormat:'MMM D' }}</small>\n                                    <!--French-->\n                                    <small ng-if=\"!isOneDayOrMore(status.statusDate) && getLanguageKey() == 'fr'\" title=\"{{ status.statusDate | amDateFormat:'HH:mm - D MMMM YYYY' }}\" am-time-ago=\"status.statusDate\"></small>\n                                    <small ng-if=\"isOneDayOrMore(status.statusDate) && getLanguageKey() == 'fr'\" title=\"{{ status.statusDate | amDateFormat:'HH:mm - D MMMM YYYY' }}\">{{ status.statusDate | amDateFormat:'D MMMM' }}</small>\n                                </a>\n                                <a ng-if=\"status.locationURL\" class=\"glyphicon glyphicon-map-marker\" ng-href=\"{{ status.locationURL }}\" target=\"_blank\"></a>\n                            </h5>\n                            \n                            <div class=\"markdown\" ng-class=\"{ 'mention-share': status.type == 'MENTION_SHARE' }\" ng-bind-html=\"status.content | emoticon | markdown\"></div>\n\n                            <small ng-if=\"status.groupId\">\n                                <a class=\"label\" ng-class=\"{ 'label-info': !status.publicGroup, 'label-warning': status.publicGroup }\" ui-sref=\"tatami.home.home.group.statuses({ groupId: status.groupId })\">\n                                {{ status.groupName }}\n                                </a>\n                                <br>\n                            </small>\n\n                            <small ng-if=\"status.statusPrivate\">\n                                <span class=\"glyphicon glyphicon-lock\"></span>\n                                <span translate=\"tatami.home.status.private\"></span>\n                                <br>\n                            </small>\n\n                            <small ng-if=\"status.type === 'ANNOUNCEMENT'\">\n                                <span class=\"glyphicon glyphicon-bullhorn\">\n                                    {{ 'tatami.home.status.isAnnounced' | translate }}\n                                </span>\n                                <a ui-sref=\"tatami.home.status({ statusId: status.sharedByUsername })\">@{{ status.sharedByUsername }}</a>\n                            </small>\n\n                            <small ng-if=\"status.replyTo && status.type !== 'ANNOUNCEMENT'\">\n                                <span class=\"glyphicon glyphicon-share-alt\"></span>\n                                <span translate=\"tatami.home.status.replyTo\"></span>\n                                <a ui-sref=\"tatami.home.status({ statusId: status.replyTo })\">@{{ status.replyToUsername }}</a>\n                                <br>\n                            </small>\n\n                            <small ng-if=\"!status.activated && status.type !== 'ANNOUNCEMENT'\">\n                                <div class=\"badge hidden-phone progress-bar-danger\">\n                                    <span class=\"glyphicon glyphicon-off\"></span>\n                                    <span translate=\"tatami.account.users.deactivated\"></span>\n                                </div>\n                            </small>\n\n                            <small>\n                                <div class=\"attachments\">\n                                    <div>\n                                        <span ng-repeat=\"attachment in status.attachments\">\n                                        <a href=\"/tatami/file/{{ attachment.attachmentId }}/{{ attachment.filename }}\" class=\"btn-link status-action\" target=\"_blank\">\n                                        <i class=\"glyphicon glyphicon-file\"></i> {{ attachment.filename }}\n                                        </a>\n                                        </span>\n                                    </div>\n                                </div>\n\n                                <div ng-show=\"expanded && status.shares != null && status.shares.length != 0\" id=\"share\">\n                                    <span translate=\"tatami.home.status.shares\"></span>\n                                    <span class=\"badge\">{{ status.shares.length }}</span>\n                                    <div>\n                                        <span ng-repeat=\"user in status.shares\">\n                                            <a ui-sref=\"tatami.home.profile.statuses({ username: user.username })\">\n                                                <div class=\"img img-rounded img-small share-img-fffix\" ng-attr-title=\"@{{ user.username }}\" ng-style=\"{ 'background-image': 'url(' + user.avatarURL + ')' }\"></div>\n                                            </a>\n                                        </span>\n                                    </div>\n                                </div>\n                            </small>\n                        </div>\n\n                        <div ng-if=\"status.type == 'STATUS' || status.type == 'SHARE' || status.type == 'ANNOUNCEMENT'\" ng-style=\"{ visibility: showButtonRow ? 'visible': 'hidden' }\" style=\"display: block;\" class=\"mediumHeight little-marge-top buttons\">\n                            <div>\n                                <small class=\"statusitem-footer\">\n                                    <span>\n                                        <button ng-click=\"openReplyModal(status)\" class=\"btn-link status-action status-action-reply button-ios\">\n                                            <i class=\"glyphicon glyphicon-comment\"></i>\n                                            <span translate=\"tatami.home.status.reply\"></span>\n                                        </button>\n                                        <button ng-if=\"status.username != profile.username && !status.shareByMe && !status.statusPrivate\" ng-click=\"shareStatus(status, $index)\" class=\"btn-link status-action status-action-share button-ios\">\n                                            <i class=\"glyphicon glyphicon-retweet\"></i>\n                                            <span translate=\"tatami.home.status.share\"></span>\n                                        </button>\n                                        <button ng-click=\"favoriteStatus(status, $index)\" class=\"btn-link status-action status-action-favorite button-ios\">\n                                            <i class=\"glyphicon glyphicon-star\"></i>\n                                            <span translate=\"tatami.home.status.favorite\"></span>\n                                        </button>\n                                        <button ng-if=\"isAdmin && status.groupId === null\" ng-click=\"announceStatus(status)\" class=\"btn-link status-action status-action-announce button-ios\">\n                                            <i class=\"glyphicon glyphicon-bullhorn\"></i>\n                                            <span translate=\"tatami.home.status.announce\"></span>\n                                        </button>\n                                        <button ng-if=\"status.username == profile.username\" ng-click=\"deleteStatus(status, $index, ('tatami.status.confirmDelete' | translate))\" class=\"btn-link status-action status-action-delete button-ios\">\n                                            <i class=\"glyphicon glyphicon-trash\"></i>\n                                            <span translate=\"tatami.home.status.delete\"></span>\n                                        </button>\n                                    </span>\n                                    <span ng-if=\"status.replyTo\" class=\"pull-right\">\n                                        <a ui-sref=\"tatami.home.status({ statusId: status.statusId })\" class=\"btn-link status-action button-ios\">\n                                            <span translate=\"tatami.home.status.viewConversation\"></span>\n                                        </a>\n                                    </span>\n                                </small>\n                            </div>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n    </section>\n</section>"
  },
  {
    "path": "web/src/main/webapp/app/components/home/tag/TagHeaderController.js",
    "content": "HomeModule.controller('TagHeaderController', ['$scope', 'TagService', 'tag',\n    function($scope, TagService, tag) {\n        $scope.tag = tag;\n\n        $scope.followUnfollowTag = function() {\n            TagService.follow(\n                { tag: $scope.tag.name },\n                { name: $scope.tag.name, followed: !$scope.tag.followed, trendingUp: $scope.tag.trendingUp },\n                function(response) {\n                    $scope.tag.followed = response.followed;\n                    $scope.$state.reload();\n                }\n            );\n        };\n    }\n]);"
  },
  {
    "path": "web/src/main/webapp/app/components/home/tag/TagHeaderView.html",
    "content": "<div>\n    <ul class=\"homebody-nav nav nav-justified\">\n        <li ui-sref-active=\"active\">\n            <a ui-sref=\"tatami.home.home.tag\">\n            <i class=\"glyphicon glyphicon-tag\"></i>\n            <span translate=\"tatami.home.tag.title\"></span>\n            </a>\n        </li>\n    </ul>\n    <section class=\"tatams-content tatams-margin\">\n        <div class=\"tatams-content-title\">\n            <h3>\n                <strong ng-if=\"$state.includes('tatami.home.home.tag')\">#{{ tag.name }}</strong>\n                <button type=\"button\" ng-click=\"followUnfollowTag()\" ng-init=\"hover = false\" ng-mouseenter=\"hover = true\" ng-mouseleave=\"hover = false\" class=\"btn btn-sm toggleTag pull-right\" ng-class=\"{ 'btn-danger': tag.followed && hover, 'btn-info': tag.followed && !hover }\">\n                    <span class=\"glyphicon\" ng-class=\"tag.followed ? 'glyphicon-minus' : 'glyphicon-plus'\">\n                        <span ng-if=\"!tag.followed\" class=\"hidden-phone\" translate=\"tatami.home.tag.follow\"></span>\n                        <span ng-if=\"tag.followed && !hover\" class=\"hidden-phone\" translate=\"tatami.home.tag.following\"></span>\n                        <span ng-if=\"tag.followed && hover\" class=\"hidden-phone\" translate=\"tatami.home.tag.unfollow\"></span>\n                    </span>\n                </button>\n            </h3>\n        </div>\n    </section>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/home/timeline/TimelineHeaderView.html",
    "content": "<div>\n    <ul class=\"homebody-nav nav nav-justified\">\n        <li ui-sref-active=\"active\">\n            <a ui-sref=\"tatami.home.home.timeline\">\n                <span class=\"glyphicon glyphicon-th-list\"></span>\n                <span translate=\"tatami.home.timeline\"></span>\n            </a>\n        </li>\n        <li ui-sref-active=\"active\">\n            <a ui-sref=\"tatami.home.home.mentions\">\n                <span class=\"glyphicon glyphicon-comment\"></span>\n                <span translate=\"tatami.home.mentions\"></span>\n            </a>\n        </li>\n        <li ui-sref-active=\"active\">\n            <a ui-sref=\"tatami.home.home.favorites\">\n                <span class=\"glyphicon glyphicon-star\"></span>\n                <span translate=\"tatami.home.favorites\"></span>\n            </a>\n        </li>\n    </ul>\n    <section class=\"tatams-content tatams-margin\">\n        <div class=\"tatams-content-title\">\n            <h3 tour-step\n                order=\"1\"\n                title=\"<b>{{ 'tatami.welcome.timeline.title' | translate }}</b>\"\n                content=\"{{ 'tatami.welcome.timeline.line1' | translate }}\n                <ul>\n                    <li>{{ 'tatami.welcome.timeline.bulletPoint1' | translate }}</li>\n                    <li>{{ 'tatami.welcome.timeline.bulletPoint2' | translate }}</li>\n                    <li>{{ 'tatami.welcome.timeline.bulletPoint3' | translate }}</li>\n                    <li>{{ 'tatami.welcome.timeline.bulletPoint4' | translate }}</li>\n                </ul>\n                <p>{{ 'tatami.welcome.timeline.afterBP1' | translate }}</p>\n                <p>{{ 'tatami.welcome.timeline.afterBP2' | translate }}</p>\n                <p>{{ 'tatami.welcome.timeline.afterBP3' | translate }}</p>\n                <br>\"\n                placement=\"left\"\n                skip=\"false\"\n                on-end=\"onTourEnd(tour)\">\n                <strong ng-if=\"$state.includes('tatami.home.home.timeline')\" translate=\"tatami.home.timeline\"></strong>\n                <strong ng-if=\"$state.includes('tatami.home.home.mentions')\" translate=\"tatami.home.mentions\"></strong>\n                <strong ng-if=\"$state.includes('tatami.home.home.favorites')\" translate=\"tatami.home.favorites\"></strong>\n                <strong ng-if=\"$state.includes('tatami.home.home.company')\" translate=\"tatami.home.companyTimeline\"></strong>\n            </h3>\n        </div>\n    </section>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/home/welcome/WelcomeController.js",
    "content": "HomeModule.controller('WelcomeController', ['$scope', '$modalInstance', '$rootScope', function($scope, $modalInstance, $rootScope) {\n    $scope.close = function() {\n        $modalInstance.dismiss();\n    };\n\n    $scope.launchPresentation = function() {\n        $rootScope.$broadcast('start-tour');\n        $modalInstance.dismiss();\n    };\n\n    // Handles closing the modal via escape and clicking outside the modal\n    $modalInstance.result.finally(function() {\n        $scope.$state.go('tatami.home.home.timeline');\n    });\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/home/welcome/WelcomeView.html",
    "content": "<!--\n<div>\n    <div id=\"WelcomeModal\" class=\"modal fade in\" aria-hidden=\"false\" style=\"display: block;\">\n        <div class=\"modal-dialog\">\n        -->\n<div>\n    <div class=\"modal-content\">\n        <div class=\"modal-header\">\n            <button ng-click=\"close()\" type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\">×</button>\n            <h4 class=\"modal-title\" translate=\"tatami.welcome.title\"></h4>\n        </div>\n        <div class=\"modal-body\">\n            <div class=\"row\">\n                <div class=\"col col-span6\">\n                    <img src=\"/img/welcome.jpg\" class=\"pull-left\">\n                </div>\n                <div class=\"col col-span6\">\n                    <br>\n                    <br>\n                    <h2 translate=\"tatami.welcome.title\"></h2>\n                    <p translate=\"tatami.welcome.message\"></p>\n                </div>\n            </div>\n            <div class=\"modal-footer\">\n                <button ng-click=\"close()\" type=\"button\" class=\"btn btn-default hide-welcome\" data-dismiss=\"modal\" translate=\"tatami.form.cancel\"></button>\n                <button ng-click=\"launchPresentation()\" type=\"button\" class=\"btn btn-primary launch-help\" translate=\"tatami.welcome.presentation\"></button>\n            </div>\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/login/LoginController.js",
    "content": "LoginModule.controller('LoginController', ['$scope', function($scope) {\n    console.log('here');\n    $scope.loginFailed = false;\n}]);\n"
  },
  {
    "path": "web/src/main/webapp/app/components/login/LoginModule.js",
    "content": "var LoginModule = angular.module('LoginModule', []);\n\nLoginModule.config(['$stateProvider', function($stateProvider) {\n    $stateProvider\n        .state('tatami.login', {\n            url: '',\n            abstract: true,\n            templateUrl: 'app/components/login/LoginView.min.html',\n        })\n        .state('tatami.login.main', {\n            url: '/login?action',\n            views: {\n                'manualLogin': {\n                    templateUrl: '/app/components/login/manual/ManualLoginView.min.html',\n                    controller: 'ManualLoginController'\n                },\n                'recoverPassword': {\n                    templateUrl: '/app/components/login/recoverPassword/RecoverPasswordView.min.html',\n                    controller: 'RecoverPasswordController'\n                },\n                'googleLogin': {\n                    templateUrl: '/app/components/login/google/GoogleLoginView.min.html',\n                    controller: 'GoogleLoginController'\n                },\n                'register': {\n                    templateUrl: '/app/components/login/register/RegisterView.min.html',\n                    controller: 'RegisterController'\n                }\n            },\n            data: {\n                public: true\n            }\n        })\n        .state('tatami.registration', {\n            url: '/register?key',\n            templateUrl: '/app/components/login/email/EmailRegistration.min.html',\n            controller: 'EmailRegistrationController',\n            resolve: {\n                update: ['RegistrationService', '$stateParams', function(RegistrationService, $stateParams) {\n                    return RegistrationService.getUpdate({ register: 'register', key: $stateParams.key }).$promise;\n                }]\n            },\n            data: {\n                public: true\n            }\n        });\n}]);\n"
  },
  {
    "path": "web/src/main/webapp/app/components/login/LoginView.html",
    "content": "<div id=\"mainPanel\" class=\"container well well-sm\">\n    <div class=\"text-center well well-sm\">\n        <h1 translate=\"tatami.login.mainTitle\"></h1>\n        <h3 translate=\"tatami.login.subtitle\"></h3>\n        <a ui-sref=\"tatami.about.presentation\"><h4 translate=\"tatami.login.moreInfo\"></h4></a>\n    </div>\n    <div ng-show=\"loginFailed\" class=\"alert alert-danger\" translate=\"tatami.login.fail\"></div>\n    <div ng-show=\"$stateParams.action === 'lostPassword'\" class=\"alert alert-info\" translate=\"tatami.login.passwordEmailSent\"></div>\n    <div ng-show=\"$stateParams.action === 'lostPasswordFailure'\" class=\"alert alert-danger\" translate=\"tatami.login.unregisteredEmail\"></div>\n    <div ng-show=\"$stateParams.action === 'register'\" class=\"alert alert-info\" translate=\"tatami.login.registrationEmail\"></div>\n    <div ng-show=\"$stateParams.action === 'registerFailure'\" class=\"alert alert-danger\" translate=\"tatami.login.registrationFailure\"></div>\n    <div class=\"col-span-12\">\n\n\n        <div ui-view=\"googleLogin\"></div>\n        <div class=\"col-span-4\">\n            <div ui-view=\"manualLogin\"></div>\n            <div ui-view=\"recoverPassword\"></div>\n        </div>\n        <div ui-view=\"register\"></div>\n\n        <div class=\"panel-body\"></div>\n    </div>\n</div>\n"
  },
  {
    "path": "web/src/main/webapp/app/components/login/RegistrationService.js",
    "content": "LoginModule.factory('RegistrationService', ['$resource', function($resource) {\n    return $resource('/tatami/:register', null, {\n        'resetPassword': {\n            method: 'POST',\n            url: '/tatami/lostpassword',\n            headers : {'Content-Type': 'application/x-www-form-urlencoded'}\n        },\n        'getUpdate': {\n            method: 'GET'\n        },\n        'registerUser': {\n            method: 'POST',\n            url: '/tatami/register',\n            headers: {'Content-Type': 'application/x-www-form-urlencoded'}\n        }\n    });\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/login/email/EmailRegistration.html",
    "content": "<div id=\"mainPanel\" class=\"container\">\n    <div class=\"row\">\n        <div class=\"col-offset-2 col-span-8\">\n            <h1 translate=\"tatami.login.validation\"></h1>\n\n\n\n            <p translate=\"tatami.login.passwordSuccess\"></p>\n\n        </div>\n    </div>\n    <div class=\"row\">\n        <div class=\"col-offset-4 col-span-2\">\n            <br>\n            <br>\n            <a ui-sref=\"tatami.login.main\" translate=\"tatami.login.returnHome\"></a>\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/login/email/EmailRegistrationController.js",
    "content": "LoginModule.controller('EmailRegistrationController', [function() {\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/login/google/GoogleLoginController.js",
    "content": "LoginModule.controller('GoogleLoginController', ['$scope', '$http', 'UserSession', function($scope, $http, UserSession) {\n\n        if (UserSession.isAuthenticated()){\n            $scope.$state.go('tatami.home.home.timeline');\n        }\n    $scope.logout = function() {\n        $http.get('/tatami/logout')\n            .success(function() {\n                UserSession.clearSession();\n                $scope.$state.go('tatami.login.main');\n            });\n    };\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/login/google/GoogleLoginView.html",
    "content": "<div class=\"col-span-4\">\n    <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <h4 class=\"panel-title text-center\" translate=\"tatami.login.googleApps.title\"></h4>\n        </div>\n        <div class=\"panel-body\">\n            <form form=\"submit\" action=\"/tatami/j_spring_pac4j_security_check\" method=\"post\" accept-charset=\"utf-8\">\n                <fieldset>\n                    <div class=\"control-group\">\n                        <button type=\"submit\" id=\"proceed_google\" class=\"btn btn-primary btn-block\" translate=\"tatami.login.googleApps.login\"></button>\n                    </div>\n                </fieldset>\n            </form>\n            <div class=\"control-group\">\n                <button type=\"button\" class=\"btn btn-info btn-block little-padding text-center\" ui-sref=\"tatami.about.tos\" translate=\"tatami.login.tos\"></button>\n            </div>\n            <ul class=\"list-group\">\n                <li class=\"list-group-item\">\n                    <p translate=\"tatami.login.googleApps.line1\"></p>\n                    <a href=\"https://www.google.com/work/apps/business/\">\n                        <p translate=\"tatami.login.googleApps.link\"></p>\n                    </a>\n                    <p translate=\"tatami.login.googleApps.line2\"></p>\n                    <p translate=\"tatami.login.googleApps.line3\"></p>\n                </li>\n            </ul>\n        </div>\n    </div>\n</div>\n<!--\n<div class=\"col-span-4\">\n    <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <h4 class=\"panel-title text-center\" translate=\"tatami.login.googleApps.title\"></h4>\n        </div>\n        <div class=\"panel-body\">\n            <form class=\"well\" action=\"/tatami/j_spring_openid_security_check\" method=\"post\" accept-charset=\"utf-8\">\n                <fieldset>\n                    <div class=\"controle-group\">\n                        <input class=\"col-span-12\" name=\"openid_identifier\" size=\"50\"\n                               maxlength=\"100\" type=\"hidden\"\n                               value=\"https://www.google.com/accounts/o8/id\"/>\n                    </div>\n                    <div class=\"control-group\">\n                        <button type=\"submit\" id=\"proceed_google\" class=\"btn btn-primary btn-block\" translate=\"tatami.login.googleApps.login\"></button>\n                    </div>\n                </fieldset>\n            </form>\n            <div class=\"control-group\">\n                <button type=\"button\" class=\"btn btn-info btn-block little-padding text-center\" ui-sref=\"tatami.about.tos\" translate=\"tatami.login.tos\"></button>\n            </div>\n            <ul class=\"list-group\">\n                <li class=\"list-group-item\">\n                    <p translate=\"tatami.login.googleApps.line1\"></p>\n                    <a href=\"https://www.google.com/work/apps/business/\">\n                        <p translate=\"tatami.login.googleApps.link\"></p>\n                    </a>\n                    <p translate=\"tatami.login.googleApps.line2\"></p>\n                    <p translate=\"tatami.login.googleApps.line3\"></p>\n                </li>\n            </ul>\n        </div>\n    </div>\n</div>\n-->\n<!--\n<form class=\"well\" action=\"/tatami/j_spring_openid_security_check\" method=\"post\" accept-charset=\"utf-8\">\n    <fieldset class=\"row-fluid\">\n        <div class=\"controle-group\">\n            <input class=\"col-span-12\" name=\"openid_identifier\" size=\"50\"\n                   maxlength=\"100\" type=\"hidden\"\n                   value=\"https://www.google.com/accounts/o8/id\"/>\n        </div>\n        <div class=\"controle-group\">\n            <button id=\"proceed_google\" type=\"submit\" class=\"col-span-12 btn btn-success\">\n                <fmt:message key=\"tatami.authentication.google.submit\"/>\n            </button>\n        </div>\n        <div class=\"controle-group\">\n            <div class=\"text-center\">(<a href=\"/tatami/tos\"><fmt:message key=\"tatami.authentication.cgv\"/></a>)\n            </div>\n        </div>\n    </fieldset>\n</form>\n-->"
  },
  {
    "path": "web/src/main/webapp/app/components/login/manual/ManualLoginController.js",
    "content": "LoginModule.controller('ManualLoginController', ['$scope', '$rootScope', '$http', 'AuthenticationService', 'UserSession', function ($scope, $rootScope, $http, AuthenticationService, UserSession) {\n    $scope.user = {};\n    $scope.login = function () {\n        $http({\n            method: 'POST',\n            url: '/tatami/authentication',\n            transformRequest: function (obj) {\n                var str = [];\n                for (var p in obj)\n                    str.push(encodeURIComponent(p) + \"=\" + encodeURIComponent(obj[p]));\n                return str.join(\"&\");\n            },\n            data: {\n                j_username: $scope.user.email,\n                j_password: $scope.user.password,\n                _spring_security_remember_me: $scope.user.remember\n            },\n            headers: {'Content-Type': 'application/x-www-form-urlencoded'}\n        })\n            .success(function (data) {\n                if (data.action === 'loginFailure') {\n                    $scope.$state.go('tatami.login.main', {action: data.action});\n                }\n                else {\n                    // The user has logged in, authenticate them\n                    UserSession.setLoginState(true);\n\n                    // Redirect the user to the state they tried to access now that they are logged in\n                    if (angular.isDefined($rootScope.returnToState) || angular.isDefined($rootScope.returnToStateParams)) {\n                        // redirect to previous state\n                        $scope.$state.go($rootScope.returnToState.name, $rootScope.returnToParams);\n                    }\n\n                    // If they were not trying to access a specific state, send them to the home state\n                    else {\n                        $scope.$state.go('tatami.home.home.timeline');\n                    }\n\n                }\n            })\n            .error(function (data) {\n                console.log('showing banner');\n                $scope.loginFailed = true;\n            });\n    };\n}]);\n"
  },
  {
    "path": "web/src/main/webapp/app/components/login/manual/ManualLoginView.html",
    "content": "<div class=\"panel panel-default\">\n    <div class=\"panel-heading\">\n        <h4 class=\"panel-title text-center\" translate=\"tatami.login.title\"></h4>\n    </div>\n    <div class=\"panel-body\">\n        <form ng-submit=\"login()\" accept-charset=\"utf-8\" id=\"loginForm\">\n            <fieldset>\n                <div class=\"control-group\">\n                    <input id=\"j_username\" name=\"j_username\" type=\"email\" ng-model=\"user.email\" required=\"required\" placeholder=\"{{ 'tatami.login.email' | translate }}\" autofocus>\n                </div>\n                <div class=\"control-group\">\n                    <input id=\"j_password\" name=\"j_password\" type=\"password\" ng-model=\"user.password\" required=\"required\" placeholder=\"{{ 'tatami.login.password' | translate }}\">\n                </div>\n                <div class=\"control-group\">\n                    <input id=\"_spring_security_remember_me\" ng-model=\"user.remember\" name=\"_spring_security_remember_me\" type=\"checkbox\">\n                    <span translate=\"tatami.login.remember\"></span>\n                </div>\n                <button type=\"submit\" id=\"loginButton\" class=\"btn btn-primary btn-block text-center\" translate=\"tatami.login.title\"></button>\n            </fieldset>\n        </form>\n        <!--\n        <form action=\"/tatami/authentication\" method=\"post\" accept-charset=\"utf-8\" id=\"loginForm\">\n            <fieldset>\n                <div class=\"control-group\">\n                    <input id=\"j_username\" name=\"j_username\" type=\"email\" required=\"required\" placeholder=\"{{ 'tatami.login.email' | translate }}\" autofocus>\n                </div>\n                <div class=\"control-group\">\n                    <input id=\"j_password\" name=\"j_password\" type=\"password\" required=\"required\" placeholder=\"{{ 'tatami.login.password' | translate }}\">\n                </div>\n                <div class=\"control-group\">\n                    <input id=\"_spring_security_remember_me\" name=\"_spring_security_remember_me\" type=\"checkbox\">\n                    <span translate=\"tatami.login.remember\"></span>\n                </div>\n                <button type=\"submit\" id=\"loginButton\" class=\"btn btn-primary btn-block text-center\" translate=\"tatami.login.title\"></button>\n            </fieldset>\n        </form>\n        -->\n    </div>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/login/recoverPassword/RecoverPasswordController.js",
    "content": "LoginModule.controller('RecoverPasswordController', ['$scope', 'RegistrationService', function($scope, RegistrationService) {\n    $scope.user = {};\n\n    $scope.resetPassword = function() {\n        var data = 'email=' + $scope.user.email;\n        RegistrationService.resetPassword(data).$promise.then(function(success) {\n            $scope.$state.go('tatami.login.main', { action: success.action });\n            $scope.user.email = '';\n        }, function(err) {\n            console.log(err);\n        });\n    };\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/login/recoverPassword/RecoverPasswordView.html",
    "content": "<div class=\"panel panel-default\">\n    <div class=\"panel-heading\">\n        <h4 class=\"panel-title text-center\" translate=\"tatami.login.forgotPassword\"></h4>\n    </div>\n    <div class=\"panel-body\">\n        <form ng-submit=\"resetPassword()\" accept-charset=\"utf-8\">\n            <fieldset>\n                <div class=\"control-group\">\n                    <input ng-model=\"user.email\" name=\"email\" type=\"email\" required=\"required\" placeholder=\"{{ 'tatami.login.email' | translate }}\">\n                </div>\n                <button type=\"submit\" class=\"btn btn-primary btn-block text-center\" translate=\"tatami.login.resetPassword\"></button>\n            </fieldset>\n        </form>\n    </div>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/components/login/register/RegisterController.js",
    "content": "LoginModule.controller('RegisterController', ['$scope', 'RegistrationService', function($scope, RegistrationService) {\n    $scope.user = {};\n\n    $scope.registerUser = function() {\n        var data = 'email=' + $scope.user.email;\n        RegistrationService.registerUser(data).$promise.then(function(success) {\n            $scope.$state.go('tatami.login.main', { action: success.action });\n            $scope.user.email = '';\n        }, function(err) {\n            console.log(err);\n        });\n    };\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/components/login/register/RegisterView.html",
    "content": "<div class=\"col-span-4\">\n    <div class=\"panel panel-default\">\n        <div class=\"panel-heading\">\n            <h4 class=\"panel-title text-center\" translate=\"tatami.login.register.title\"></h4>\n        </div>\n        <div class=\"panel-body\">\n            <ul class=\"list-group\">\n                <li class=\"list-group-item\">\n                    <p translate=\"tatami.login.register.line1\"></p>\n                    <p translate=\"tatami.login.register.line2\"></p>\n                    <p translate=\"tatami.login.register.line3\"></p>\n                </li>\n            </ul>\n            <form ng-submit=\"registerUser()\" accept-charset=\"utf-8\" id=\"registrationForm\">\n                <fieldset>\n                    <div class=\"control-group\">\n                        <input ng-model=\"user.email\" name=\"email\" type=\"email\" required=\"required\" placeholder=\"{{ 'tatami.login.email' | translate }}\">\n                    </div>\n                    <div class=\"control-group\">\n                        <button type=\"submit\" id=\"registrationButton\" class=\"btn btn-primary btn-block text-center\" translate=\"tatami.login.register.title\"></button>\n                    </div>\n                </fieldset>\n            </form>\n            <button type=\"button\" class=\"btn btn-info btn-block little-padding text-center\" ui-sref=\"tatami.about.tos\" translate=\"tatami.login.tos\"></button>\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/shared/configs/MarkedConfig.js",
    "content": "marked.setOptions({\n    gfm: true,\n    pedantic: false,\n    sanitize: true,\n    highlight: null,\n    urls: {\n        youtube : function(text, url){\n            var cap;\n            if((cap = /(youtu\\.be\\/|youtube\\.com\\/(watch\\?(.*&)?v=|(embed|v)\\/))([^\\?&\"'>]+)/.exec(url))){\n                return '<iframe width=\"420\" height=\"315\" src=\"https://www.youtube.com/embed/' +\n                    cap[5] +\n                    '\" frameborder=\"0\" allowfullscreen></iframe>';\n            }\n        },\n        vimeo : function(text, url){\n            var cap;\n            if((cap = /^.*(vimeo\\.com\\/)((channels\\/[A-z]+\\/)|(groups\\/[A-z]+\\/videos\\/))?([0-9]+)/.exec(url))){\n                return '<iframe src=\"https://player.vimeo.com/video/' +\n                    cap[5] +\n                    '\" width=\"500\" height=\"281\" frameborder=\"0\" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>';\n            }\n        },\n        dailymotion : function(text, url){\n            var cap;\n            if((cap = /^.+dailymotion.com\\/(video|hub)\\/([^_]+)[^#]*(#video=([^_&]+))?/.exec(url))){\n                return '<iframe frameborder=\"0\" width=\"480\" height=\"271\" src=\"https://www.dailymotion.com/embed/video/' +\n                    cap[2] +\n                    '\"></iframe>';\n            }\n        },\n        gist : function(text, url){\n            var cap;\n            if((cap = /^.+gist.github.com\\/(([A-z0-9-]+)\\/)?([0-9A-z]+)/.exec(url))){\n                $.ajax({\n                    url: cap[0] + '.json',\n                    dataType: 'jsonp',\n                    success: function(response){\n                        if(response.stylesheet && $('link[href=\"' + response.stylesheet + '\"]').length === 0){\n                            var l = document.createElement(\"link\"),\n                                head = document.getElementsByTagName(\"head\")[0];\n\n                            l.type = \"text/css\";\n                            l.rel = \"stylesheet\";\n                            l.href = response.stylesheet;\n                            head.insertBefore(l, head.firstChild);\n                        }\n                        var $elements = $('.gist' + cap[3]);\n                        $elements.html(response.div);\n                    }\n                });\n                return '<div class=\"gist' + cap[3] + '\"/>';\n            }\n        }\n    }\n});"
  },
  {
    "path": "web/src/main/webapp/app/shared/configs/MomentConfig.js",
    "content": "TatamiApp.run(['$translate', 'amMoment', function($translate, amMoment) {\n    amMoment.changeLocale($translate.use());\n}]);\n\nmoment.locale('en', {\n    relativeTime : {\n        future: \"\",\n        past:   \"%s\",\n        s:  \"1s\",\n        m:  \"1m\",\n        mm: \"%dm\",\n        h:  \"1h\",\n        hh: \"%dh\",\n        d:  \"1d\",\n        dd: \"%dd\",\n        M:  \"1mo\",\n        MM: \"%dmo\",\n        y:  \"1y\",\n        yy: \"%dy\"\n    }\n});\n\nmoment.locale('fr', {\n    relativeTime : {\n        future: \"\",\n        past:   \"%s\",\n        s:  \"1 s\",\n        m:  \"1 min\",\n        mm: \"%d min\",\n        h:  \"1 h\",\n        hh: \"%d h\",\n        d:  \"1 j\",\n        dd: \"%d j\",\n        M:  \"1 m\",\n        MM: \"%d m\",\n        y:  \"1 a\",\n        yy: \"%d a\"\n    }\n});"
  },
  {
    "path": "web/src/main/webapp/app/shared/configs/TranslateConfig.js",
    "content": "TatamiApp.config(['$translateProvider', function($translateProvider) {\n\n    $translateProvider.translations('en', {\n        'tatami': {\n            'pageNotFound': 'Page not found.',\n            'error': 'An error has occurred.',\n\n            'welcome': {\n                'title': 'Welcome to Tatami',\n                'message': 'Your timeline is empty! Do you need help to learn how to use Tatami? Please click on the button below to launch a presentation.',\n                'presentation': 'Launch presentation',\n                'help': {\n                    'title': 'Help',\n                    'line1': 'Welcome to the online help!',\n                    'line2':' Follow the next steps for a tour of the main Tatami features.'\n                },\n                'timeline': {\n                    'title': 'Timeline',\n                    'line1': 'This is your timeline. It displays all messages',\n                    'bulletPoint1': 'mentioning you or sent privately to you',\n                    'bulletPoint2': 'sent by users you follow',\n                    'bulletPoint3': 'sent by yourself',\n                    'bulletPoint4': 'sent to group you are subscribed to',\n                    'afterBP1': 'If it\\'s empty, don\\'t worry, it will get updated as soon as you start following other users!',\n                    'afterBP2': 'When viewing a message, you can reply to it and mark it as a favorite to find it easily later.',\n                    'afterBP3': 'If a message already has some replies, you can see them all by clicking on the timestamp or clicking \\'View Conversation\\'.'\n                },\n                'post': {\n                    'title': 'Posting Messages',\n                    'line1': 'Here is where you write messages you want to share',\n                    'bulletPoint1': 'All messages are public by default. They will be delivered to all users who follow you.',\n                    'bulletPoint2': 'When writing a message you should use <\\i>#hashtags</i>. This simply means adding a # at the beginning of important words that can be used to find your message.',\n                    'bulletPoint3': 'When mentioning or replying to other users you should add a @ at the beginning of their name. They will be notified that you are talking to them.'\n                },\n                'groups': {\n                    'title': 'Groups',\n                    'line1': 'This is the list of groups you are a member of.',\n                    'line2': 'You can find and subscribe to public groups in the Account/Groups page (top-right menu).',\n                    'line3': 'There are also private groups. You cannot subscribe to these. The owner of the group must add you as a member.'\n                },\n                'trends': {\n                    'title': 'Trends',\n                    'line1': 'This list represents the #hashtags that are currently the most often used on Tatami. Use this to discover what\\'s going on and what are the hottest topics on Tatami!'\n                },\n                'whoToFollow': {\n                    'title': 'Who To Follow',\n                    'line1': 'This is a list of users who share common interests with you and who you could follow.',\n                    'line2': 'If you are a new user, this list is probably empty. Tatami needs some time to learn who you are in order to suggest relevant users.',\n                    'line3': 'And don\\'t forget to use #hashtags in your messages. It makes everything easier!'\n                },\n                'next': 'Next',\n                'previous': 'Prev',\n                'end': 'End'\n            },\n\n            // Login View\n            'login': {\n                'title': 'Login',\n                'mainTitle': 'Welcome to Tatami',\n                'subtitle': 'An open source enterprise social network',\n                'moreInfo': 'More Info',\n                'email': 'Email',\n                'password': 'Password',\n                'remember': 'Remember me',\n                'forgotPassword': 'Forgot your password?',\n                'resetPassword': 'Reset password',\n                'tos': 'Terms of Service',\n                'fail': 'Your authentication has failed! Are you sure you used the correct password?',\n                'passwordEmailSent': 'An email has been sent to you, with instructions to generate a new password.',\n                'unregisteredEmail': 'This email address is not registered in Tatami.',\n                'registrationFailure': 'User registration failed. That email already is in use.',\n                'register': {\n                    'title': 'Register',\n                    'line1': 'A confirmation email will be sent to the address you provide.',\n                    'line2': \"Your email's domain will determine the company space you join. For example, users with an email@ippon.fr address will join Ippon's private space.\",\n                    'line3': \"If you are the first employee of your company to join Tatami, your company's private space will be automatically created.\"\n                },\n                'googleApps': {\n                    'title': 'Google Apps Login',\n                    'line1': 'This feature is for Google Apps for Work users, who have their work domain name managed by Google Apps.',\n                    'link': 'For more information on Google Apps for Work click here.',\n                    'line2': 'Whether or not you already have a Tatami account, you can sign in with your Google Apps account.',\n                    'line3': \"Your email will be provided by Google and your email's domain name will be used to allow you to join your company's private space.\",\n                    'login': 'Login using Google Apps'\n                },\n                'validation': 'E-mail validation',\n                'passwordSuccess': 'Your email has been validated. Your password will be emailed to you.',\n                'returnHome': 'Go to the home page',\n                'registrationEmail': 'Thank you! A registration email has been sent to you.'\n            },\n\n            'about': {\n                // Presentation Page\n                'presentation': {\n                    'title': 'What is Tatami?',\n                    'devices': 'Devices',\n                    'openSource': 'Open Source',\n                    'row1': {\n                        'title': 'A private, enterprise social network',\n                        'line1': 'Update your status to inform your co-workers',\n                        'line2': \"Subscribe to other employees' time lines\",\n                        'line3': 'Share important information to your followers',\n                        'line4': 'Discuss and reply to your colleagues',\n                        'line5': 'Put important information into favorites',\n                        'line6': 'Search useful information with our integrated search engine',\n                        'line7': 'Use hashtags to find related information',\n                        'line8': \"Go to your co-workers' profiles to see what they are working on\",\n                        'line9': 'English and French versions available, adding other languages is easy'\n                    },\n                    'row2': {\n                        'title': 'Works on all devices!',\n                        'line1': 'Dynamic web application (HTML5): nothing to install, except a modern browser!',\n                        'line2': \"Works on mobile devices, tablets, or standard computers: the application adapts itself automatically to your device's screen\",\n                        'line3': 'Stay connected with your enterprise wherever you are'\n                    },\n                    'row3': {\n                        'title': \"Easy installation and integration with your company's IT infrastructure\",\n                        'line1': 'Standard Java application',\n                        'line2': 'Your data belongs to you, not to your SaaS vendor!',\n                        'line3': 'Integrates with your LDAP directory',\n                        'line4': 'Integrates with Google Apps',\n                        'line5': 'Fully Open Source, with a business-friendly Apache 2.0 license',\n                        'line6': 'Easy to extend or modify according to your needs',\n                        'line7': 'High performance (based on Apache Cassandra), even on small hardware',\n                        'line8': 'Join the project and submit patches on our Github page:'\n                    },\n                    'row4': {\n                        'title': \"Also available in SaaS mode, fully managed by Ippon Technologies\",\n                        'line1': \"If you do not want to install Tatami in your company, it's easy to use directly\",\n                        'line2': 'Secured multi-enterprise mode: every company has its own private space',\n                        'line3': '256 bits SSL encryption: all data transfers are fully secured'\n                    },\n                    'row5': {\n                        'title': 'Need more information on our product?',\n                        'line1': 'Our sales team is looking forward to hearing from you! Call us at +33 01 46 12 48 48 or email us at'\n                    }\n                },\n\n                // Terms of Service Page\n                'tos': {\n                    'title': 'Terms of Service'\n                },\n\n                // License Page\n                'license': {\n                    'title': 'Source Code License',\n                    'copyright': 'Copyright'\n                }\n            },\n\n            // Home View\n            'home': {\n                'timeline': 'Timeline',\n                'mentions': 'Mentions',\n                'favorites': 'Favorites',\n                'companyTimeline': 'Company Timeline',\n\n                'newMessage': 'New Message',\n                'newMessages': 'New Messages',\n\n                //Top Menu\n                'menu': {\n                    'logo': 'Ippon Technologies Logo',\n                    'title': 'Tatami',\n                    'about': {\n                        'title': 'About',\n                        'version' : 'Version',\n                        'presentation': 'Presentation',\n                        'tos': 'Terms of Service',\n                        'language': {\n                            'language': 'Language',\n                            'en': 'English',\n                            'fr': 'Français'\n                        },\n                        'license': 'Source Code License',\n                        'github': {\n                            'issues': 'Submit a Bug Report',\n                            'fork': 'Fork Tatami on Github'\n                        },\n                        'ippon': {\n                            'website': 'Ippon Technologies Website',\n                            'blog': 'Ippon Technologies Blog',\n                            'twitter': 'Follow @ippontech on Twitter'\n                        }\n                    },\n                    'search': 'Search',\n                    'help': 'Help',\n                    'account': {\n                        'title': 'Account',\n                        'companyTimeline': 'Company Timeline',\n                        'logout': 'Logout'\n                    }\n                },\n\n                // Post Modal\n                'post': {\n                    'mandatory': 'Comment is mandatory',\n                    'content': {\n                        'mandatory': 'Please fill out this field.'\n                    },\n                    'update': 'Update your status',\n                    'replyTo': 'Reply',\n                    'preview': 'Preview',\n                    'edit': 'Edit',\n                    'characters': {\n                        'left': 'Characters Left:'\n                    },\n                    'options': 'Options',\n                    'shareLocation': 'Share Location',\n                    'group': 'Group',\n                    'reply': 'Reply to this status',\n                    'files': 'Files',\n                    'drop': {\n                        'file': 'Drop your files here'\n                    },\n                    'markdown': 'Markdown Supported',\n                    'button': 'Post'\n                },\n\n                // Home Sidebar View\n                'sidebar': {\n                    'myGroups': 'My Groups',\n                    'whoToFollow': 'Who To Follow',\n                    'trends': 'Trends',\n                    'public': 'PUB',\n                    'private': 'PVT',\n                    'archived': 'ARC',\n                    'administrator': 'A',\n                    'publicToolTip': 'Public Group',\n                    'privateToolTip': 'Private Group',\n                    'archivedToolTip': 'Archived Group',\n                    'administratorToolTip': 'You administer this group.'\n                },\n\n                // Status List item or User List item\n                'status': {\n                    'replyTo': 'In reply to',\n                    'private': 'Private Message',\n                    'reply': 'Reply',\n                    'share': 'Share',\n                    'favorite': 'Favorite',\n                    'delete': 'Delete',\n                    'confirmDelete': 'Are you sure you want to delete this status?',\n                    'sharedYour': 'shared your status',\n                    'followed': 'followed you',\n                    'shared': 'shared',\n                    'groupAdmin': 'Group Administrator',\n                    'announce': 'Announce',\n                    'isAnnounced': 'Announced by',\n                    'viewConversation': 'View Conversation',\n                    'shares': 'Shares'\n                },\n\n                // Tag View\n                'tag': {\n                    'title': 'Tag',\n                    'follow': 'Follow',\n                    'following': 'Following',\n                    'unfollow': 'Unfollow'\n                },\n\n                // Group View\n                'group': {\n                    'join': 'Join',\n                    'joined': 'Joined',\n                    'leave': 'Leave',\n                    'manage': 'Manage',\n                    'statuses': 'Statuses',\n                    'members': 'Members',\n                    'membersSingular': '1 Member',\n                    'membersPlural': '{{ amount }} Members'\n                },\n\n                // Profile View\n                'profile': {\n                    'statuses': 'Statuses',\n                    'following': 'Following',\n                    'followers': 'Followers',\n                    'follow': 'Follow',\n                    'unfollow': 'Unfollow',\n                    'followsYou': 'Follows You',\n\n                    'youStatusesSingular': 'Your 1 status',\n                    'youStatusesPlural': 'Your {{ amount }} statuses',\n                    'youFollowingSingular': 'You follow 1 person',\n                    'youFollowingPlural': 'You follow {{ amount }} people',\n                    'youFollowersSingular': 'Your 1 follower',\n                    'youFollowersPlural': 'Your {{ amount }} followers',\n\n                    'userStatusesSingular': '@{{ username }} posted 1 status',\n                    'userStatusesPlural': '@{{ username }} posted {{ amount }} statuses',\n                    'userFollowingSingular': '@{{ username }} follows 1 person',\n                    'userFollowingPlural': '@{{ username }} follows {{ amount }} people',\n                    'userFollowersSingular': '@{{ username }} has 1 follower',\n                    'userFollowersPlural': '@{{ username }} has {{ amount }} followers',\n\n                    'deactivatedUser': 'Deactivated User',\n\n                    // Profile Sidebar View\n                    'sidebar': {\n                        'information': 'Information',\n                        'statistics': 'Statistics',\n                        'firstName': 'First Name',\n                        'lastName': 'Last Name',\n                        'email': 'Email',\n                        'jobTitle': 'Job Title',\n                        'phoneNumber': 'Phone Number',\n                        'statuses': 'Statuses',\n                        'following': 'Following',\n                        'followers': 'Followers',\n                        'trends': 'Trends'\n                    }\n                },\n\n                'searchPage': {\n                    'title': 'Search',\n                    'statusesWith': 'Statuses with'\n                }\n            },\n\n            //Account View\n            'account': {\n                // Profile Tab\n                'profile': {\n                    'title': 'Profile',\n                    'dropPhoto': 'Drop your photo here to update it',\n                    'update': 'Update your profile',\n                    'email': 'Email',\n                    'firstName': 'First Name',\n                    'lastName': 'Last Name',\n                    'jobTitle': 'Job Title',\n                    'phoneNumber': 'Phone Number',\n                    'delete': 'Delete your account',\n                    'confirmDelete': 'You are about to delete your account. Are you sure?',\n                    'save': 'Your profile has been saved'\n                },\n\n                // Preferences Tab\n                'preferences': {\n                    'title': 'Preferences',\n                    'notifications': 'Notifications',\n                    'notification': {\n                        'email': {\n                            'mention': 'Get notified by email when you are mentioned',\n                            'dailyDigest': 'Get a daily digest email',\n                            'weeklyDigest': 'Get a weekly digest email'\n                        },\n                        'rss': {\n                            'timeline': 'Allow RSS feed publication of your timeline',\n                            'link': 'Link to your timeline RSS stream'\n                        }\n                    },\n                    'save': 'Your preferences have been saved'\n                },\n\n                // Password Tab\n                'password': {\n                    'title': 'Password',\n                    'update': 'Update your password',\n                    'old': 'Old Password',\n                    'new': 'New Password',\n                    'confirm': 'Confirm New Password',\n                    'save': 'Your password has been changed'\n                },\n\n                // Files Tab\n                'files': {\n                    'title': 'Files',\n                    'filename': 'Filename',\n                    'size': 'Size',\n                    'date': 'Date',\n                    'delete': 'Delete'\n                },\n\n                // Users Tab\n                'users': {\n                    'title': 'Users',\n                    'following': 'Following',\n                    'recommended': 'Recommended',\n                    'search': 'Search',\n                    'deactivated': 'This user is deactivated'\n                },\n\n                // Groups Tab\n                'groups': {\n                    'title': 'Groups',\n                    'createNewGroup': 'Create a new group',\n                    'name': 'Name',\n                    'description': 'Description',\n                    'public': 'Public',\n                    'private': 'Private',\n                    'publicWarning': 'Warning: If this group is public, everybody can access it',\n                    'create': 'Create',\n                    'myGroups': 'My Groups',\n                    'recommended': 'Recommended',\n                    'search': 'Search',\n                    'group': 'Group',\n                    'access': 'Access',\n                    'members': 'Members',\n                    'manage': 'Manage',\n                    'update': 'Update group details',\n                    'archive': 'Do you want to archive this group?',\n                    'allowArchive': 'Yes, this group should be archived',\n                    'denyArchive': 'No, this group is still in use',\n                    'archiveWarning': 'Warning: Archived groups are read-only',\n                    'addMember': 'Add a member',\n                    'username': 'Username',\n                    'role': 'Role',\n                    'admin': 'Administrator',\n                    'member': 'Member',\n                    'join': 'Join',\n                    'joined': 'Joined',\n                    'leave': 'Leave',\n                    'archived': 'Archived',\n                    'add': 'Add',\n                    'remove': 'Remove',\n                    'save': 'Your group has been created'\n                },\n\n                // Tags Tab\n                'tags': {\n                    'title': 'Tags',\n                    'trends': 'Trends',\n                    'search': 'Search',\n                    'tag': 'Tag',\n                    'follow': 'Follow',\n                    'following': 'Following',\n                    'unfollow': 'Unfollow'\n                },\n\n                // Top Posters Tab\n                'topPosters': {\n                    'title': 'Top Posters',\n                    'username': 'Username',\n                    'count': 'Status Count'\n                }\n            },\n\n            'form': {\n                'cancel': 'Cancel',\n                'save': 'Save',\n                'success': 'The form has been successfully saved.',\n                'fail': 'Failed to save form.',\n                'deleted': 'Your file has been deleted.'\n            },\n\n            'admin': {\n                'title': 'Administration Dashboard',\n                'registered': 'Registered Enterprises',\n                'domain': 'Domain',\n                'count': '# of users',\n                'environment': 'Environnement Variables (from tatami.properties)',\n                'propery': 'Property',\n                'value': 'Value',\n                'reindex': 'Re-index Search Engine',\n                'confirm': 'Are you sure you want to re-index Search Engine?',\n                'success': 'Search engine re-indexation has succeeded.',\n                'deactivate': 'Deactivate',\n                'activate': 'Activate'\n            }\n        }\n    });\n\n    $translateProvider.translations('fr', {\n        'tatami': {\n            'error': 'Il y a une erreur',\n            'pageNotFound': 'Page non trouvée.',\n\n            'welcome': {\n                'title': 'Bienvenue sur Tatami',\n                'message': 'Votre timeline est vide! Avez-vous besoin d\\'aide pour apprendre à utilizer Tatami? Veuillez cliquer sur le bouton ci-dessous pour lancer une présentation.',\n                'presentation': 'Lancer la présentation',\n                'help': {\n                    'title': 'Aide',\n                    'line1': 'Bienvenue sur l\\'aide en ligne!',\n                    'line2':' Suivez les étapes suivantes pour une présentation des principales caractéristiques de Tatami .'\n                },\n                'timeline': {\n                    'title': 'Timeline',\n                    'line1': 'Ceci est votre timeline. Il affiche tous les messages',\n                    'bulletPoint1': 'vous mentionner ou envoyé en privé à vous',\n                    'bulletPoint2': 'envoyé par les utilisateurs que vous suivez',\n                    'bulletPoint3': 'envoyé par vous-même ',\n                    'bulletPoint4': 'envoyé à un groupe auquel vous êtes abonné(e)',\n                    'afterBP1': 'Si elle est vide, ne vous inquiétez pas, elle sera mise à jour dès que vous commencez à suivre d\\'autres utilisateurs!',\n                    'afterBP2': 'Lors de l\\'affichage d\\'un message, vous pouvez y répondre et le marquer comme favori pour le retrouver plus facilement.',\n                    'afterBP3': 'Si un message avait déjà obtenu quelques réponses, vous pouvez voir tous les détails en cliquant sur detail : ce sera plus facile de suivre la conversation sur Tatami.'\n                },\n                'post': {\n                    'title': 'Envoyer un message',\n                    'line1': 'C\\'est ici que vous écrivez les messages que vous souhaitez partager',\n                    'bulletPoint1': 'tous les messages sont publics par défaut. Ils seront affichés à tous les utilisateurs qui vous suivent',\n                    'bulletPoint2': 'pour écrire un message, vous pouvez utiliser de #hashtags : cela signifie tout simplement l\\'ajout d\\'un «#» au début des mots importants qui peuvent ensuite être utilisé pour trouver votre message',\n                    'bulletPoint3': 'pour mentionner ou répondre à d\\'autres utilisateurs, vous devez ajouter un @ au début de leur nom : ils seront informés que vous vous adressez à eux'\n                },\n                'groups': {\n                    'title': 'Groupes',\n                    'line1': 'Ceci est la liste des groupes auquel vous appartenez.',\n                    'line2': 'Vous pouvez trouver et vous abonner à des groupe public dans la page Account/Groupes (menu en haut à droite).',\n                    'line3': 'Il y a aussi des groupes privés : vous ne pouvez pas vous y inscrire;  le propriétaire du groupe doit vous ajouter en tant que membre.'\n                },\n                'trends': {\n                    'title': 'Tendances',\n                    'line1': 'Cette liste représente les #hashtag qui sont les plus souvent utilisés sur Tatami. Utilisez-la pour découvrir ce qui ce passe et quels sont les sujets les plus chauds sur Tatami!'\n                },\n                'whoToFollow': {\n                    'title': 'Utilisateurs suggérées',\n                    'line1': 'Ceci est une liste d\\'utilisateurs qui partagent des intérêts communs avec vous et que vous pourriez suivre.',\n                    'line2': 'Si vous êtes un nouvel utilisateur, cette liste est probablement vide : Tatami a besoin de temps pour apprendre qui vous êtes afin de vous proposer des utilisateurs',\n                    'line3': 'Et n\\'oubliez pas d\\'utiliser des #hashtags dans vos messages, cela rend tout plus facile !'\n                },\n                'next': 'Suivant',\n                'previous': 'Précédent',\n                'end': 'Fin'\n            },\n\n            // Login View\n            'login': {\n                'title': 'Login',\n                'mainTitle': 'Bienvenue sur Tatami',\n                'subtitle': 'Un réseau social d\\'entreprise open source',\n                'moreInfo': 'Plus d\\'info',\n                'email': 'Email',\n                'password': 'Mot de passe',\n                'remember': 'Se souvenir de moi',\n                'forgotPassword': 'Mot de passe oublié ?',\n                'resetPassword': 'Nouveau mot de passe',\n                'tos': 'Conditions de service',\n                'fail': 'Votre authentification a échoué ! Etes-vous sûr que vous avez utilisé un mot de passe correct ?',\n                'passwordEmailSent': 'Un email vous a été envoyé, avec des instructions pour créer un nouveau mot de passe.',\n                'unregisteredEmail': 'Cette adresse email n\\'est pas enregistrée dans Tatami.',\n                'register': {\n                    'title': 'Enregistré',\n                    'line1': 'Un email de confirmation sera envoyé à l\\'adresse fournie.',\n                    'line2': \"Le domaine de votre email détermine l'espace de l'entreprise que vous allez rejoindre. Par exemple, les utilisateurs ayant une adresse email@ippon.fr vont joindre l'espace privé Ippon.\",\n                    'line3': \"Si vous êtes le premier employé de votre entreprise à se joindre à Tatami, l'espace privé de votre entreprise sera automatiquement créé.\"\n                },\n                'googleApps': {\n                    'title': 'Google Apps Login',\n                    'line1': 'Cette fonction est pour les utilisateurs de Google Apps for Work, qui ont leur nom de domaine de travail géré par Google Apps.',\n                    'link': 'Pour plus d\\'informations sur Google Apps for Work, cliquez ici.',\n                    'line2': 'Que vous ayez déjà ou pas un compte, vous pouvez vous connecter avec votre compte Google Apps.',\n                    'line3': \"Votre email sera fourni par Google et le nom du domaine de votre email sera utilisé pour vous permettre de rejoindre l'espace privé de votre entreprise.\",\n                    'login': 'Login avec Google Apps'\n                },\n\n                'validation': 'Validation email',\n                'passwordSuccess': 'Votre email a été validé. Votre mot de passe vous sera envoyé par email.',\n                'returnHome': 'Allez à la page d\\'accueil',\n                'registrationEmail': 'Merci ! Un e-mail de confirmation vous a été envoyé.'\n            },\n\n            'about': {\n                // Presentation Page\n                'presentation': {\n                    'title': 'Qu\\'est-ce que Tatami ?',\n                    'devices': 'Appareils',\n                    'openSource': 'Open Source',\n                    'row1': {\n                        'title': 'Un réseau social d\\'entreprise privé',\n                        'line1': 'Mettre à jour votre statut afin d\\'informer vos collègues',\n                        'line2': \"S'abonner aux timelines des autres employés\",\n                        'line3': 'Partager des informations importantes aux personnes qui vous suivent',\n                        'line4': 'Discuter et répondre à vos collègues',\n                        'line5': 'Ajouter des informations importantes dans vos favoris',\n                        'line6': 'Chercher des informations utiles avec notre moteur de recherche intégré',\n                        'line7': 'Utiliser les #hashtags lors de votre recherche',\n                        'line8': \"Aller voir le profil de vos collègues et découvrez ce sur quoi ils travaillent\",\n                        'line9': 'Tatami est disponible en français et en anglais. Il est facile d\\'ajouter d\\'autres langues'\n                    },\n                    'row2': {\n                        'title': 'Fonctionne partout !',\n                        'line1': 'Application web dynamique (HTML5): rien à installer, un navigateur moderne suffit !',\n                        'line2': \"Fonctionne sur les appareils mobiles, des tablettes ou des ordinateurs: l'application s'adapte automatiquement à l'écran de votre appareil\",\n                        'line3': 'Restez connecté avec votre entreprise où que vous soyez'\n                    },\n                    'row3': {\n                        'title': \"Installation et intégration facile avec l'infrastructure informatique de votre entreprise\",\n                        'line1': 'Application standard Java',\n                        'line2': 'Vos données vous appartiennent et ne sont pas à votre fournisseur SaaS !',\n                        'line3': 'Intégration avec votre dossier LDAP',\n                        'line4': 'Intégration avec Google Apps',\n                        'line5': 'Entièrement Open Source, avec une licence Apache 2.0, facile à utiliser pour les entreprises',\n                        'line6': 'Facile à étendre ou modifier selon vos besoins',\n                        'line7': 'Haute performance (basé sur Cassandra d\\'Apache), même sur les petites configurations',\n                        'line8': 'Rejoignez le projet et proposer des patches sur notre page Github:'\n                    },\n                    'row4': {\n                        'title': \"Egalement disponible en mode SaaS, entièrement géré par Ippon Technologies\",\n                        'line1': \"Si vous ne souhaitez pas installer Tatami dans votre entreprise, il est facile de l'utiliser directement\",\n                        'line2': 'Mode multi-entreprise sécurisé : chaque entreprise dispose de son propre espace privé',\n                        'line3': 'Cryptage SSL 256 bits : tous les transferts de données sont entièrement sécurisé'\n                    },\n                    'row5': {\n                        'title': 'Besoin de plus d\\'informations sur notre produit ?',\n                        'line1': 'Notre équipe de vente est impatiente de vous entendre! Appelez-nous au +33 1 46 12 48 48 ou par email à'\n                    }\n                },\n\n                // Terms of Service Page\n                'tos': {\n                    'title': 'Conditions de service'\n                },\n\n                // License Page\n                'license': {\n                    'title': 'Licence du code source',\n                    'copyright': 'Droits d\\'auteur'\n                }\n            },\n\n            // Home View\n            'home': {\n                'timeline': 'Timeline',\n                'mentions': 'Mentions',\n                'favorites': 'Favoris',\n                'companyTimeline': 'Timeline de votre entreprise',\n\n                'newMessage': 'Nouveau Message',\n                'newMessages': 'Nouveaux Messages',\n\n                //Top Menu\n                'menu': {\n                    'logo': 'Ippon Technologies Logo',\n                    'title': 'Tatami',\n                    'about': {\n                        'title': 'Information',\n                        'version' : 'Version',\n                        'presentation': 'Présentation',\n                        'tos': 'Conditions générales d\\'utilisation',\n                        'language': {\n                            'language': 'Language',\n                            'en': 'English',\n                            'fr': 'Français'\n                        },\n                        'license': 'Licence du source code',\n                        'github': {\n                            'issues': 'Envoyer un rapport de bug',\n                            'fork': 'Fork Tatami sur Github'\n                        },\n                        'ippon': {\n                            'website': 'Site d\\'Ippon Technologies',\n                            'blog': 'Blog d\\'Ippon Technologies',\n                            'twitter': 'Suivez @ippontech sur Twitter'\n                        }\n                    },\n                    'search': 'Recherchez',\n                    'help': 'Aide',\n                    'account': {\n                        'title': 'Compte',\n                        'companyTimeline': 'Timeline de votre enterprise',\n                        'logout': 'Déconnexion'\n                    }\n                },\n\n                // Post Modal\n                'post': {\n                    'mandatory': 'Commentaire obligatoire',\n                    'content': {\n                        'mandatory': 'Veuillez remplir ce champ..'\n                    },\n                    'update': 'Mettre à jour votre statut',\n                    'replyTo': 'Répondre',\n                    'preview': 'Prévisualisation',\n                    'edit': 'Éditer',\n                    'characters': {\n                        'left': 'Caractères restants :'\n                    },\n                    'options': 'Options',\n                    'shareLocation': 'Partager votre localisation',\n                    'group': 'Groupe',\n                    'reply': 'Répondre à ce statut',\n                    'files': 'Fichiers',\n                    'drop': {\n                        'file': 'Déposez vos fichiers ici'\n                    },\n                    'markdown': 'Markdown Supported',\n                    'button': 'Post'\n                },\n\n                // Home Sidebar View\n                'sidebar': {\n                    'myGroups': 'Mes Groupes',\n                    'whoToFollow': 'Qui Suivre',\n                    'trends': 'Tendances',\n                    'public': 'PUB',\n                    'private': 'PVT',\n                    'archived': 'ARC',\n                    'administrator': 'A',\n                    'publicToolTip': 'Groupe public',\n                    'privateToolTip': 'Groupe privé',\n                    'archivedToolTip': 'Groupe archivé',\n                    'administratorToolTip': 'Vous administrez ce groupe.'\n                },\n\n                // Status List item or User List item\n                'status': {\n                    'replyTo': 'En réponse à',\n                    'private': 'Message privé',\n                    'reply': 'Répondre',\n                    'share': 'Partager',\n                    'favorite': 'Favoris',\n                    'delete': 'Supprimer',\n                    'confirmDelete': 'Êtes-vous sûr de vouloir supprimer ce statut ?',\n                    'sharedYour': 'a partagé votre statut',\n                    'followed': 'vous suit',\n                    'shared': 'partagé',\n                    'groupAdmin': 'Administrateur du groupe',\n                    'announce': 'Annoncer',\n                    'isAnnounced': 'Annoncé par',\n                    'viewConversation': 'Voir La Conversation',\n                    'shares': 'Partages'\n                },\n\n                // Tag View\n                'tag': {\n                    'title': 'Tag',\n                    'follow': 'Abonnés',\n                    'following': 'Abonnements',\n                    'unfollow': 'Se désabonner'\n                },\n\n                // Group View\n                'group': {\n                    'join': 'Joindre',\n                    'joined': 'a rejoins',\n                    'leave': 'Quitter',\n                    'manage': 'Gérer',\n                    'statuses': 'Statuts',\n                    'members': 'Membres',\n                    'membersSingular': '1 Membre',\n                    'membersPlural': '{{ amount }} Membres'\n                },\n\n                // Profile View\n                'profile': {\n                    'statuses': 'Statuts',\n                    'following': 'Abonnement',\n                    'followers': 'Abonnés',\n                    'follow': 'Suivre',\n                    'unfollow': 'Se désabonner',\n                    'followsYou': 'Vous suit',\n\n                    'youStatusesSingular': 'Votre statut',\n                    'youStatusesPlural': 'Vos {{ amount }} statuts',\n                    'youFollowingSingular': 'Vous êtes abonné(e) à 1 personne',\n                    'youFollowingPlural': 'Vous êtes abonné(e) à {{ amount }} personnes',\n                    'youFollowersSingular': '1 personne vous suit',\n                    'youFollowersPlural': '{{ amount }} personnes vous suivent',\n\n                    'userStatusesSingular': '@{{ username }} a partagé un statut',\n                    'userStatusesPlural': '@{{ username }} a partagé {{ amount }} statuts',\n                    'userFollowingSingular': '@{{ username }} suit 1 personne',\n                    'userFollowingPlural': '@{{ username }} suit {{ amount }} personnes',\n                    'userFollowersSingular': '@{{ username }} a 1 abonnement',\n                    'userFollowersPlural': '@{{ username }} a {{ amount }} abonnements',\n\n                    'deactivatedUser': 'Utilisateur désactivé',\n\n                    // Profile Sidebar View\n                    'sidebar': {\n                        'information': 'Information',\n                        'statistics': 'Statistiques',\n                        'firstName': 'Prénom',\n                        'lastName': 'Nom',\n                        'email': 'Email',\n                        'jobTitle': 'Titre',\n                        'phoneNumber': 'Numéro de téléphone',\n                        'statuses': 'Statuts',\n                        'following': 'Abonnement',\n                        'followers': 'Abonné',\n                        'trends': 'Tendances'\n                    }\n                },\n\n                'searchPage': {\n                    'title': 'Recherchez',\n                    'statusesWith': 'Statuts avec'\n                }\n            },\n\n            //Account View\n            'account': {\n                // Profile Tab\n                'profile': {\n                    'title': 'Profil',\n                    'dropPhoto': 'Déposez votre photo ici pour la mettre à jour',\n                    'update': 'Mettez à jour votre profil',\n                    'email': 'Email',\n                    'firstName': 'Prénom',\n                    'lastName': 'Nom',\n                    'jobTitle': 'Intitulé de poste',\n                    'phoneNumber': 'Numéro de téléphone',\n                    'delete': 'Supprimer votre compte',\n                    'confirmDelete': 'Vous êtes sur le point de supprimer votre compte. Êtes-vous sûr?',\n                    'save': 'Votre profil a été sauvé'\n                },\n\n                // Preferences Tab\n                'preferences': {\n                    'title': 'Préférences',\n                    'notifications': 'Notifications',\n                    'notification': {\n                        'email': {\n                            'mention': 'Recevez une notification par email lorsque vous êtes mentionné',\n                            'dailyDigest': 'Obtenez un résumé quotidien email',\n                            'weeklyDigest': 'Obtenez un sommaire hebdomadaire email'\n                        },\n                        'rss': {\n                            'timeline': 'Autoriser la publication RSS de votre fil d\\'actualité',\n                            'link': 'Lien de votre RSS fils d\\'actualité'\n                        }\n                    },\n                    'save': 'Vos préférences ont été enregistrées'\n                },\n\n                // Password Tab\n                'password': {\n                    'title': 'Mot de passe',\n                    'update': 'Changez votre mot de passe',\n                    'old': 'Ancien mot de passe',\n                    'new': 'Nouveau mot de passe',\n                    'confirm': 'Confirmer votre nouveau mot de passe',\n                    'save': 'Votre mot de passe a été changé'\n                },\n\n                // Files Tab\n                'files': {\n                    'title': 'Fichier',\n                    'filename': 'Nom de fichier',\n                    'size': 'Taille',\n                    'date': 'Date',\n                    'delete': 'Supprimer'\n                },\n\n                // Users Tab\n                'users': {\n                    'title': 'Utilisateur',\n                    'following': 'Abonné',\n                    'recommended': 'Recommandé',\n                    'search': 'Rechercher',\n                    'deactivated': 'Cet utilisateur est désactivé'\n                },\n\n                // Groups Tab\n                'groups': {\n                    'title': 'Groupes',\n                    'createNewGroup': 'Créer un nouveau groupe',\n                    'name': 'Nom',\n                    'description': 'Description',\n                    'public': 'Public',\n                    'private': 'Privé',\n                    'publicWarning': 'Attention: Si ce groupe est public, tout le monde peut y accéder',\n                    'create': 'Créer',\n                    'myGroups': 'Mes Groupes',\n                    'recommended': 'Recommandé',\n                    'search': 'Rechercher',\n                    'group': 'Groupe',\n                    'access': 'Accès',\n                    'members': 'Membres',\n                    'manage': 'Gérer',\n                    'update': 'Mettre à jour les détails de votre groupe',\n                    'archive': 'Voulez-vous archiver ce groupe?',\n                    'allowArchive': 'Oui, ce groupe devrait être archivé',\n                    'denyArchive': 'Non, ce groupe est encore utilisé',\n                    'archiveWarning': 'Attention : les groupe archivés sont en lecture seule',\n                    'addMember': 'Ajouter un membre',\n                    'username': 'Username',\n                    'role': 'Rôle',\n                    'admin': 'Administrator',\n                    'member': 'Membre',\n                    'join': 'Joindre',\n                    'joined': 'Rejoint',\n                    'leave': 'Quitter',\n                    'archived': 'Archivé',\n                    'add': 'Ajouter',\n                    'remove': 'Supprimer',\n                    'save': 'Votre groupe a été créé'\n                },\n\n                // Tags Tab\n                'tags': {\n                    'title': 'Tags',\n                    'trends': 'Tendances',\n                    'search': 'Rechercher',\n                    'tag': 'Tag',\n                    'follow': 'Abonné',\n                    'following': 'Abonnement',\n                    'unfollow': 'Se désabonner'\n                },\n\n                // Top Posters Tab\n                'topPosters': {\n                    'title': 'Top Posters',\n                    'username': 'Nom',\n                    'count': 'Nombre de Statuts'\n                }\n            },\n\n            'form': {\n                'cancel': 'Annuler',\n                'save': 'Sauvegarder',\n                'success': 'Le formulaire a été enregistré avec succès.',\n                'fail': 'Impossible de sauvegarder le formulaire.',\n                'deleted': 'Votre fichier a été supprimé.'\n            },\n\n            'admin': {\n                'title': 'Dashboard d\\'administration',\n                'registered': 'Entreprises enregistrées',\n                'domain': 'Domaine',\n                'count': '# d\\'utilisateur(s)',\n                'environment': 'Variables d\\'environnement (de tatami.properties)',\n                'propery': 'Property',\n                'value': 'Valeur',\n                'reindex': 'Ré-indexation du moteur de recherche',\n                'confirm': 'Êtes-vous sûr que vous voulez ré-indexer les moteurs de recherche?',\n                'success': 'La ré-indexation du moteur de recherche a réussi.',\n                'deactivate': 'Désactiver',\n                'activate': 'Activer'\n            }\n        }\n    });\n\n    $translateProvider.useCookieStorage();\n    $translateProvider.registerAvailableLanguageKeys(['en', 'fr']);\n    $translateProvider.fallbackLanguage('en');\n    $translateProvider.determinePreferredLanguage();\n}]);\n"
  },
  {
    "path": "web/src/main/webapp/app/shared/error/404View.html",
    "content": "<div id=\"mainPanel\" class=\"container\">\n    <div class=\"row\">\n        <div class=\"offset2 span8 text-center\">\n            <h1 translate=\"tatami.pageNotFound\"></h1>\n            <img src=\"/img/404-error.jpg\">\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/shared/error/500View.html",
    "content": "<div id=\"mainPanel\" class=\"container\">\n    <div class=\"row\">\n        <div class=\"offset2 span8 text-center\">\n            <h1 translate=\"tatami.error\"></h1>\n            <img src=\"/img/500-error.jpg\">\n        </div>\n    </div>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/shared/filters/EmoticonFilter.js",
    "content": "TatamiApp.filter('emoticon', function() {\n    return function(content) {\n        if(content === null || angular.isUndefined(content)) {\n            return content;\n        }\n\n        var emoticons = {\n            '>:(': '/assets/img/emoticons/angry.png',\n            ':$': '/assets/img/emoticons/blushing.png',\n            '8)': '/assets/img/emoticons/cool.png',\n            'B)': '/assets/img/emoticons/cool.png',\n            \":'(\": '/assets/img/emoticons/crying.png',\n            ':(': '/assets/img/emoticons/frowning.png',\n            ':o': '/assets/img/emoticons/gasping.png',\n            ':O': '/assets/img/emoticons/gasping.png',\n            ':D': '/assets/img/emoticons/grinning.png',\n            '<3': '/assets/img/emoticons/heart.png',\n            'XD': '/assets/img/emoticons/laughing.png',\n            ':x': '/assets/img/emoticons/lips_sealed.png',\n            ':X': '/assets/img/emoticons/lips_sealed.png',\n            ':#': '/assets/img/emoticons/lips_sealed.png',\n            '>:D': '/assets/img/emoticons/malicious.png',\n            ':3': '/assets/img/emoticons/naww.png',\n            ':)': '/assets/img/emoticons/smiling.png',\n            ':|': '/assets/img/emoticons/speechless.png',\n            '>:)': '/assets/img/emoticons/spiteful.png',\n            'o_O': '/assets/img/emoticons/surprised.png',\n            'D:': '/assets/img/emoticons/terrified.png',\n            ':-1:': '/assets/img/emoticons/thumbs_down.png',\n            ':+1:': '/assets/img/emoticons/thumbs_up.png',\n            'XP': '/assets/img/emoticons/tongue_out_laughing.png',\n            ':p': '/assets/img/emoticons/tongue_out.png',\n            ':P': '/assets/img/emoticons/tongue_out.png',\n            ':/': '/assets/img/emoticons/unsure.png',\n            ';)': '/assets/img/emoticons/winking_grinning.png',\n            ';p': '/assets/img/emoticons/winking_tongue_out.png',\n            ';P': '/assets/img/emoticons/winking_tongue_out.png',\n            ':t': '/assets/img/emoticons/trollface.png',\n            ':T': '/assets/img/emoticons/trollface.png',\n            '(troll)': '/assets/img/emoticons/trollface.png'\n        };\n\n        function escapeRegExp(str) {\n            return str.replace(/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]/g, '\\\\$&');\n        }\n\n        for(var key in emoticons) {\n            var reg = new RegExp('(^| )' + escapeRegExp(key) + '($| )');\n            content = content.replace(reg, ' ![' + key + '](' + emoticons[key] + ') ');\n        }\n\n        return content;\n    };\n});"
  },
  {
    "path": "web/src/main/webapp/app/shared/filters/MarkdownFilter.js",
    "content": "TatamiApp.filter('markdown', ['$sce', function($sce) {\n    return function(content) {\n        return content ? $sce.trustAsHtml(marked(content)) : '';\n    };\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/shared/filters/PlaceholderFilter.js",
    "content": "TatamiApp.filter('placeholderFilter', ['$translate', function($translate) {\n    return function(isReply) {\n        if(isReply) {\n            return \"\";\n        }\n        else {\n            return $translate.instant('tatami.home.post.update');\n        }\n    };\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/shared/footer/FooterController.js",
    "content": "FooterModule.controller('FooterController', ['$scope', function($scope) {\n\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/shared/footer/FooterModule.js",
    "content": "var FooterModule = angular.module('FooterModule', []);"
  },
  {
    "path": "web/src/main/webapp/app/shared/footer/FooterView.html",
    "content": "<div ng-if=\"!$state.includes('tatami.home')\" style=\"opacity: 0.5; text-align:center;\">\n    Version: <pom>version</pom>, Build: <pom>build</pom>\n</div>\n"
  },
  {
    "path": "web/src/main/webapp/app/shared/lists/status/withContext/StatusListContextController.js",
    "content": "HomeModule.controller('StatusListContextController', [\n    '$scope',\n    '$q',\n    '$timeout',\n    '$window',\n    '$translate',\n    'StatusService',\n    'HomeService',\n    'TagService',\n    'GroupService',\n    'profile',\n    'statuses',\n    'statusesWithContext',\n    'userRoles',\n    'showModal',\n    function($scope, $q, $timeout, $window, $translate, StatusService, HomeService, TagService, GroupService, profile, statuses, statusesWithContext, userRoles, showModal) {\n        if(showModal && $scope.$state.is('tatami.home.home.timeline')) {\n            $scope.$state.go('tatami.home.home.timeline.presentation');\n        }\n\n        $scope.isAdmin = userRoles.roles.indexOf('ROLE_ADMIN') !== -1;\n\n        $scope.profile = profile;\n        $scope.statusesWithContext = statusesWithContext;\n        $scope.busy = false;\n\n        if(statuses.length === 0) {\n            $scope.end = true;\n        } else {\n            $scope.end = false;\n            $scope.finish = statuses[statuses.length - 1].timelineId;\n        }\n\n        /* Begin Polling Related Code */\n\n        $scope.newMessages = null;\n        $window.document.title = 'Tatami';\n\n        if($scope.$state.is('tatami.home.home.timeline') ||\n           $scope.$state.is('tatami.home.home.company')) {\n            var requestNewStatuses = function() {\n                // In milliseconds\n                var pollingDelay = 20000;\n\n                $scope.poller = $timeout(function() {\n                    var args = {};\n\n                    if($scope.statuses.length !== 0) {\n                        args = { start: statuses[0].timelineId };\n                    }\n\n                    var success = function(response) {\n                        if(response.length > 0) {\n                            $scope.newMessages = response.length;\n                            $window.document.title = 'Tatami (' + $scope.newMessages + ')';\n                        }\n                        requestNewStatuses();\n                    };\n\n                    var error = function() {\n                        requestNewStatuses();\n                    };\n\n                    if($scope.$state.is('tatami.home.home.timeline')) {\n                        StatusService.getHomeTimeline(args, success, error);\n                    }\n\n                    else if($scope.$state.is('tatami.home.home.company')) {\n                        HomeService.getCompanyTimeline(args, success, error);\n                    }\n                }, pollingDelay);\n            };\n\n            requestNewStatuses();\n\n            $scope.$on('$destroy', function() {\n                $timeout.cancel($scope.poller);\n            });\n        }\n        \n        /* End Polling Related Code */ \n\n        /* Begin Infinite Scrolling Related Code */\n\n        var organizeStatuses = function(statuses, context) {\n            var statusesWithContext = [];\n\n            // Fill array with context statuses\n            for(i = 0; i < context.length; i++) {\n                if(context[i] !== null) {\n                    statusesWithContext.push({ status: context[i], replies: [] });\n                }\n            }\n\n            var individualStatuses = [];\n\n            // Attach replies to corresponding context status\n            for(i = 0; i < statuses.length; i++) {\n                if(statuses[i].replyTo) {\n                    for(j = 0; j < statusesWithContext.length; j++) {\n                        if(statuses[i].replyTo === statusesWithContext[j].status.statusId) {\n                            statusesWithContext[j].replies.unshift(statuses[i]);\n                            break;\n                        }\n\n                        // If the context reply doesn't exist, then make the reply an individual status\n                        if(j === statusesWithContext.length - 1) {\n                            individualStatuses.push(statuses[i]);\n                            break;\n                        }\n                    }\n                } else {\n                    var addIt = true;\n                    // Check current timeline\n                    for(j = 0; j < $scope.statusesWithContext.length; j++) {\n                        // If the status isn't already in the timeline as a\n                        // context status, then add it to individualStatuses\n                        if(statuses[i].statusId === $scope.statusesWithContext[j].status.statusId) {\n                            addIt = false;\n                            break;\n                        }\n                    }\n                    // Check new timeline chunk\n                    for(j = 0; j < statusesWithContext.length; j++) {\n                        // If the status isn't already in the timeline as a\n                        // context status, then add it to individualStatuses\n                        if(statuses[i].statusId === statusesWithContext[j].status.statusId) {\n                            addIt = false;\n                            break;\n                        }\n                    }\n                    if(addIt) {\n                        individualStatuses.push(statuses[i]);\n                    }\n                }\n            }\n\n            // Put remaining individual statuses (ones that aren't replies) into the timeline\n            for(i = 0; i < individualStatuses.length; i++) {\n                // If the timeline is empty, put in a status\n                if(statusesWithContext.length === 0) {\n                    statusesWithContext.push({ status: individualStatuses[i], replies: null });\n                    continue;\n                }\n\n                for(var j = 0; j <= statusesWithContext.length; j++) {\n                    try {\n                        // If the status block has replies, we need to check the \n                        // last reply's post date/time, because that is the latest status in the block.\n                        // We order the timeline by the latest status in the block.\n                        if(statusesWithContext[j].replies !== null && statusesWithContext[j].replies.length !== 0) {\n                            var index = statusesWithContext[j].replies.length - 1;\n                            if(statusesWithContext[j].replies[index].statusDate < individualStatuses[i].statusDate) {\n                                statusesWithContext.splice(j, 0, { status: individualStatuses[i], replies: null });\n                                break;\n                            }\n                        } else {\n                            // Otherwise compare using the date of the individual status\n                            if(statusesWithContext[j].status.statusDate < individualStatuses[i].statusDate) {\n                                statusesWithContext.splice(j, 0, { status: individualStatuses[i], replies: null });\n                                break;\n                            }\n                        }\n                    } catch(err) {\n                        // For statuses that are at the end (bottom) of the timeline\n                        statusesWithContext.push({ status: individualStatuses[i], replies: null });\n                        break;\n                    }\n                }\n            }\n\n            for(var i = 0; i < statusesWithContext.length; i++) {\n                $scope.statusesWithContext.push(statusesWithContext[i]);\n            }\n\n            $scope.finish = statuses[statuses.length - 1].timelineId;\n            $scope.busy = false;\n        };\n\n        var getContext = function(statuses) {\n            if(statuses.length === 0) {\n                // reached end of list\n                $scope.end = true;\n                return;\n            }\n\n            var temp = new Set();\n            var context = [];\n\n            for(var i = 0; i < statuses.length; i++) {\n                if(statuses[i].replyTo && !temp.has(statuses[i].replyTo)) {\n                    temp.add(statuses[i].replyTo);\n                    context.push(StatusService.get({ statusId: statuses[i].replyTo })\n                        .$promise.then(\n                            function(response) {\n                                if(angular.equals({}, response.toJSON())) {\n                                    return $q.when(null);\n                                }\n                            return response;\n                    }));\n                }\n            }\n\n            $q.all(context).then(function(context) {\n                organizeStatuses(statuses, context);\n            });\n        };\n\n        $scope.requestOldStatuses = function() {\n            if($scope.busy || $scope.end) {\n                return;\n            }\n\n            $scope.busy = true;\n\n            if($scope.$state.is('tatami.home.home.timeline')) {\n                StatusService.getHomeTimeline({ finish: $scope.finish }, getContext);\n            }\n\n            else if($scope.$state.is('tatami.home.home.company')) {\n                HomeService.getCompanyTimeline({ finish: $scope.finish }, getContext);\n            }\n        };\n\n        /* End Infinite Scrolling Related Code */\n        \n        $scope.isOneDayOrMore = function(date) {\n            return moment().diff(moment(date), 'days', true) >= 1;\n        };\n\n        $scope.getLanguageKey = function() {\n            return $translate.use();\n        };\n\n        $scope.openReplyModal = function(status) {\n            $scope.$state.go($scope.$state.current.name + '.post', { statusId: status.statusId });\n        };\n\n        $scope.favoriteStatus = function(status) {\n            StatusService.update({ statusId: status.statusId }, { favorite: !status.favorite }, \n                function() {\n                    $scope.$state.reload();\n            });\n        };\n\n        $scope.shareStatus = function(status) {\n            StatusService.update({ statusId: status.statusId }, { shared: !status.shareByMe }, \n                function() {\n                    $scope.$state.reload();\n            });\n        };\n\n        $scope.announceStatus = function(status) {\n            StatusService.update({ statusId: status.statusId }, { announced: true },\n                function() {\n                    $scope.$state.reload();\n            });\n        };\n\n        $scope.deleteStatus = function(status) {\n            // Need a confirmation modal here\n            StatusService.delete({ statusId: status.statusId }, null,\n                function() {\n                    $scope.$state.reload();\n            });\n        };\n\n        $scope.getShares = function(status, firstIndex, secondIndex) {\n            if(status.type === 'STATUS' && status.shares === null) {\n                StatusService.getDetails({ statusId: status.statusId }, null,\n                    function(response) {\n                        if(secondIndex === null) {\n                            $scope.statusesWithContext[firstIndex].status.shares = response.sharedByLogins;\n                        } else {\n                            $scope.statusesWithContext[firstIndex]['replies'][secondIndex].shares = response.sharedByLogins;\n                        }\n                });\n            }\n        };\n    }\n]);"
  },
  {
    "path": "web/src/main/webapp/app/shared/lists/status/withContext/StatusListContextView.html",
    "content": "<section class=\"tatams-container\">\n    <section ng-if=\"newMessages\" ui-sref=\"tatami.home.home.timeline\" ui-sref-opts=\"{ reload: true }\" class=\"refresh-button pointer\">\n        <div class=\"text-center refresh-button-style\">\n            <span class=\"badge\">{{ newMessages }}</span>\n            <span ng-if=\"newMessages == 1\" translate=\"tatami.home.newMessage\"></span>\n            <span ng-if=\"newMessages > 1\" translate=\"tatami.home.newMessages\"></span>\n        </div>\n    </section>\n    <section class=\"timeline\" infinite-scroll=\"requestOldStatuses()\" infinite-scroll-disabled=\"busy\">\n        <div class=\"tatams\" ng-repeat=\"statusBlock in statusesWithContext\">\n            <div class=\"tatam pointer tatam-border-lr tatam-hover\" style=\"display: block;\">\n                <div id=\"current\" ng-mouseenter=\"showButtonRow = true\" ng-mouseleave=\"showButtonRow = false\">\n                    \n                    <div ng-class=\"{ 'favorite': statusBlock.status.favorite, 'share': statusBlock.status.shareByMe, 'both': statusBlock.status.favorite && statusBlock.status.shareByMe }\">\n                        <div class=\"pull-left background-image-fffix statusitem-img\">\n                            <a ui-sref=\"tatami.home.profile.statuses({ username: statusBlock.status.username })\">\n                                <div class=\"img img-rounded img-medium\" ng-style=\"{ 'background-image': 'url(' + statusBlock.status.avatarURL + ')' }\"></div>\n                            </a>\n                        </div>\n                        <div class=\"status-content-container\" ng-init=\"expanded = false\" ng-click=\"getShares(statusBlock.status, $index, null); expanded = !expanded\">\n                            <h5 class=\"statusitem-name\">\n                                <small ng-if=\"statusBlock.status.type == 'SHARE'\">\n                                    <span class=\"glyphicon glyphicon-retweet\">&nbsp;</span>\n                                    <a ui-sref=\"tatami.home.profile.statuses({ username: statusBlock.status.username })\">\n                                        <span class=\"text-muted\">@{{ statusBlock.status.sharedByUsername }}</span>\n                                    </a>\n                                    <span translate=\"tatami.home.status.shared\"></span>\n                                    <br>\n                                </small>\n                                <span ng-if=\"statusBlock.status.type == 'MENTION_SHARE'\" class=\"glyphicon glyphicon-retweet\">&nbsp;</span>\n                                <span ng-if=\"statusBlock.status.type == 'MENTION_FRIEND'\" class=\"glyphicon glyphicon-user\">&nbsp;</span>\n                                <a ui-sref=\"tatami.home.profile.statuses({ username: statusBlock.status.username })\">\n                                    <strong>{{ statusBlock.status.firstName + ' ' + statusBlock.status.lastName }}</strong>\n                                    <small>@{{ statusBlock.status.username }}</small>\n                                </a>\n                                <span ng-if=\"statusBlock.status.type == 'MENTION_SHARE'\" translate=\"tatami.home.status.sharedYour\"></span>\n                                <span ng-if=\"statusBlock.status.type == 'MENTION_FRIEND'\" translate=\"tatami.home.status.followed\"></span>\n                                <small> · </small>\n                                <!-- Replace hover title with hover bubble -->\n                                <a ui-sref=\"tatami.home.status({ statusId: statusBlock.status.statusId })\">\n                                    <!--English-->\n                                    <small ng-if=\"!isOneDayOrMore(statusBlock.status.statusDate) && getLanguageKey() == 'en'\" title=\"{{ statusBlock.status.statusDate | amDateFormat:'h:mm A - D MMM YYYY' }}\" am-time-ago=\"statusBlock.status.statusDate\"></small>\n                                    <small ng-if=\"isOneDayOrMore(statusBlock.status.statusDate) && getLanguageKey() == 'en'\" title=\"{{ statusBlock.status.statusDate | amDateFormat:'h:mm A - D MMM YYYY' }}\">{{ statusBlock.status.statusDate | amDateFormat:'MMM D' }}</small>\n                                    <!--French-->\n                                    <small ng-if=\"!isOneDayOrMore(statusBlock.status.statusDate) && getLanguageKey() == 'fr'\" title=\"{{ statusBlock.status.statusDate | amDateFormat:'HH:mm - D MMMM YYYY' }}\" am-time-ago=\"statusBlock.status.statusDate\"></small>\n                                    <small ng-if=\"isOneDayOrMore(statusBlock.status.statusDate) && getLanguageKey() == 'fr'\" title=\"{{ statusBlock.status.statusDate | amDateFormat:'HH:mm - D MMMM YYYY' }}\">{{ statusBlock.status.statusDate | amDateFormat:'D MMMM' }}</small>\n                                </a>\n                                <a ng-if=\"statusBlock.status.locationURL\" class=\"glyphicon glyphicon-map-marker\" ng-href=\"{{ statusBlock.status.locationURL }}\" target=\"_blank\"></a>\n                            </h5>\n                            \n                            <div class=\"markdown\" ng-class=\"{ 'mention-share': statusBlock.status.type == 'MENTION_SHARE' }\" ng-bind-html=\"statusBlock.status.content | emoticon | markdown\"></div>\n\n                            <small ng-if=\"statusBlock.status.groupId\">\n                                <a class=\"label\" ng-class=\"{ 'label-info': !statusBlock.status.publicGroup, 'label-warning': statusBlock.status.publicGroup }\" ui-sref=\"tatami.home.home.group.statuses({ groupId: statusBlock.status.groupId })\">\n                                {{ statusBlock.status.groupName }}\n                                </a>\n                                <br>\n                            </small>\n\n                            <small ng-if=\"statusBlock.status.statusPrivate\">\n                                <span class=\"glyphicon glyphicon-lock\"></span>\n                                <span translate=\"tatami.home.status.private\"></span>\n                                <br>\n                            </small>\n\n                            <small ng-if=\"statusBlock.status.type === 'ANNOUNCEMENT'\">\n                                <span class=\"glyphicon glyphicon-bullhorn\">\n                                    {{ 'tatami.home.status.isAnnounced' | translate }}\n                                </span>\n                                <a ui-sref=\"tatami.home.status({ statusId: statusBlock.status.sharedByUsername })\">@{{ statusBlock.status.sharedByUsername }}</a>\n                            </small>\n\n                            <small ng-if=\"statusBlock.status.replyTo && statusBlock.status.type !== 'ANNOUNCEMENT'\">\n                                <span class=\"glyphicon glyphicon-share-alt\"></span>\n                                <span translate=\"tatami.home.status.replyTo\"></span>\n                                <a ui-sref=\"tatami.home.status({ statusId: statusBlock.status.replyTo })\">@{{ statusBlock.status.replyToUsername }}</a>\n                                <br>\n                            </small>\n\n                            <small ng-if=\"!statusBlock.status.activated && statusBlock.status.type !== 'ANNOUNCEMENT'\">\n                                <div class=\"badge hidden-phone progress-bar-danger\">\n                                    <span class=\"glyphicon glyphicon-off\"></span>\n                                    <span translate=\"tatami.account.users.deactivated\"></span>\n                                </div>\n                            </small>\n\n                            <small>\n                                <div class=\"attachments\">\n                                    <div>\n                                        <span ng-repeat=\"attachment in statusBlock.status.attachments\">\n                                        <a href=\"/tatami/file/{{ attachment.attachmentId }}/{{ attachment.filename }}\" class=\"btn-link status-action\" target=\"_blank\">\n                                            <i class=\"glyphicon glyphicon-file\"></i> {{ attachment.filename }}\n                                        </a>\n                                        </span>\n                                    </div>\n                                </div>\n\n                                <div ng-show=\"expanded && statusBlock.status.shares != null && statusBlock.status.shares.length != 0\" id=\"share\">\n                                    <span translate=\"tatami.home.status.shares\"></span>\n                                    <span class=\"badge\">{{ statusBlock.status.shares.length }}</span>\n                                    <div>\n                                        <span ng-repeat=\"user in statusBlock.status.shares\">\n                                            <a ui-sref=\"tatami.home.profile.statuses({ username: user.username })\">\n                                                <div class=\"img img-rounded img-small share-img-fffix\" ng-attr-title=\"@{{ user.username }}\" ng-style=\"{ 'background-image': 'url(' + user.avatarURL + ')' }\"></div>\n                                            </a>\n                                        </span>\n                                    </div>\n                                </div>\n                            </small>\n                        </div>\n\n                        <div ng-if=\"statusBlock.status.type == 'STATUS' || statusBlock.status.type == 'SHARE' || statusBlock.status.type == 'ANNOUNCEMENT'\" ng-style=\"{ visibility: showButtonRow ? 'visible': 'hidden' }\" style=\"display: block;\" class=\"mediumHeight little-marge-top buttons\">\n                            <div>\n                                <small class=\"statusitem-footer\">\n                                    <span>\n                                        <button ng-click=\"openReplyModal(statusBlock.status)\" class=\"btn-link status-action status-action-reply button-ios\">\n                                            <i class=\"glyphicon glyphicon-comment\"></i>\n                                            <span translate=\"tatami.home.status.reply\"></span>\n                                        </button>\n                                        <button ng-if=\"statusBlock.status.username != profile.username && !statusBlock.status.shareByMe && !statusBlock.status.statusPrivate\" ng-click=\"shareStatus(statusBlock.status)\" class=\"btn-link status-action status-action-share button-ios\">\n                                            <i class=\"glyphicon glyphicon-retweet\"></i>\n                                            <span translate=\"tatami.home.status.share\"></span>\n                                        </button>\n                                        <button ng-click=\"favoriteStatus(statusBlock.status)\" class=\"btn-link status-action status-action-favorite button-ios\">\n                                            <i class=\"glyphicon glyphicon-star\"></i>\n                                            <span translate=\"tatami.home.status.favorite\"></span>\n                                        </button>\n                                        <button ng-if=\"isAdmin && statusBlock.status.groupId === null\" ng-click=\"announceStatus(statusBlock.status)\" class=\"btn-link status-action status-action-announce button-ios\">\n                                            <i class=\"glyphicon glyphicon-bullhorn\"></i>\n                                            <span translate=\"tatami.home.status.announce\"></span>\n                                        </button>\n                                        <button ng-if=\"statusBlock.status.username == profile.username\" ng-click=\"deleteStatus(statusBlock.status, ('tatami.status.confirmDelete' | translate))\" class=\"btn-link status-action status-action-delete button-ios\">\n                                            <i class=\"glyphicon glyphicon-trash\"></i>\n                                            <span translate=\"tatami.home.status.delete\"></span>\n                                        </button>\n                                    </span>\n                                    <span ng-if=\"statusBlock.status.replyTo\" class=\"pull-right\">\n                                        <a ui-sref=\"tatami.home.status({ statusId: statusBlock.status.statusId })\" class=\"btn-link status-action button-ios\">\n                                            <span translate=\"tatami.home.status.viewConversation\"></span>\n                                        </a>\n                                    </span>\n                                </small>\n                            </div>\n                        </div>\n\n                        <div ng-if=\"statusBlock.replies\">\n                            <br>\n                        </div>\n                    </div>\n\n                    <div ng-repeat=\"status in statusBlock.replies\">\n                        <div ng-class=\"{ 'favorite': status.favorite, 'share': status.shareByMe, 'both': status.favorite && status.shareByMe }\" class=\"indent\">\n                            <div class=\"pull-left background-image-fffix statusitem-img\">\n                                <a ui-sref=\"tatami.home.profile.statuses({ username: status.username })\">\n                                    <div class=\"img img-rounded img-medium\" ng-style=\"{ 'background-image': 'url(' + status.avatarURL + ')' }\"></div>\n                                </a>\n                            </div>\n                            <div class=\"status-content-container\" ng-init=\"expanded = false\" ng-click=\"getShares(status, $parent.$index, $index); expanded = !expanded\">\n                                <h5 class=\"statusitem-name\">\n                                    <small ng-if=\"status.type == 'SHARE'\">\n                                        <span class=\"glyphicon glyphicon-retweet\">&nbsp;</span>\n                                        <a ui-sref=\"tatami.home.profile.statuses({ username: status.username })\">\n                                            <span class=\"text-muted\">@{{ status.sharedByUsername }}</span>\n                                        </a>\n                                        <span translate=\"tatami.home.status.shared\"></span>\n                                        <br>\n                                    </small>\n                                    <span ng-if=\"status.type == 'MENTION_SHARE'\" class=\"glyphicon glyphicon-retweet\">&nbsp;</span>\n                                    <span ng-if=\"status.type == 'MENTION_FRIEND'\" class=\"glyphicon glyphicon-user\">&nbsp;</span>\n                                    <a ui-sref=\"tatami.home.profile.statuses({ username: status.username })\">\n                                        <strong>{{ status.firstName + ' ' + status.lastName }}</strong>\n                                        <small>@{{ status.username }}</small>\n                                    </a>\n                                    <span ng-if=\"status.type == 'MENTION_SHARE'\" translate=\"tatami.home.status.sharedYour\"></span>\n                                    <span ng-if=\"status.type == 'MENTION_FRIEND'\" translate=\"tatami.home.status.followed\"></span>\n                                    <small> · </small>\n                                    <!-- Replace hover title with hover bubble -->\n                                    <a ui-sref=\"tatami.home.status({ statusId: status.statusId })\">\n                                        <!--English-->\n                                        <small ng-if=\"!isOneDayOrMore(status.statusDate) && getLanguageKey() == 'en'\" title=\"{{ status.statusDate | amDateFormat:'h:mm A - D MMM YYYY' }}\" am-time-ago=\"status.statusDate\"></small>\n                                        <small ng-if=\"isOneDayOrMore(status.statusDate) && getLanguageKey() == 'en'\" title=\"{{ status.statusDate | amDateFormat:'h:mm A - D MMM YYYY' }}\">{{ status.statusDate | amDateFormat:'MMM D' }}</small>\n                                        <!--French-->\n                                        <small ng-if=\"!isOneDayOrMore(status.statusDate) && getLanguageKey() == 'fr'\" title=\"{{ status.statusDate | amDateFormat:'HH:mm - D MMMM YYYY' }}\" am-time-ago=\"status.statusDate\"></small>\n                                        <small ng-if=\"isOneDayOrMore(status.statusDate) && getLanguageKey() == 'fr'\" title=\"{{ status.statusDate | amDateFormat:'HH:mm - D MMMM YYYY' }}\">{{ status.statusDate | amDateFormat:'D MMMM' }}</small>\n                                    </a>\n                                    <a ng-if=\"status.locationURL\" class=\"glyphicon glyphicon-map-marker\" ng-href=\"{{ status.locationURL }}\" target=\"_blank\"></a>\n                                </h5>\n                                \n                                <div class=\"markdown\" ng-class=\"{ 'mention-share': status.type == 'MENTION_SHARE' }\" ng-bind-html=\"status.content | emoticon | markdown\"></div>\n\n                                <small ng-if=\"status.groupId\">\n                                    <a class=\"label\" ng-class=\"{ 'label-info': !status.publicGroup, 'label-warning': status.publicGroup }\" ui-sref=\"tatami.home.home.group.statuses({ groupId: status.groupId })\">\n                                    {{ status.groupName }}\n                                    </a>\n                                    <br>\n                                </small>\n\n                                <small ng-if=\"status.statusPrivate\">\n                                    <span class=\"glyphicon glyphicon-lock\"></span>\n                                    <span translate=\"tatami.home.status.private\"></span>\n                                    <br>\n                                </small>\n\n                                <small ng-if=\"status.type === 'ANNOUNCEMENT'\">\n                                    <span class=\"glyphicon glyphicon-bullhorn\">\n                                        {{ 'tatami.home.status.isAnnounced' | translate }}\n                                    </span>\n                                    <a ui-sref=\"tatami.home.status({ statusId: status.sharedByUsername })\">@{{ status.sharedByUsername }}</a>\n                                </small>\n\n                                <small ng-if=\"status.replyTo && status.type !== 'ANNOUNCEMENT'\">\n                                    <span class=\"glyphicon glyphicon-share-alt\"></span>\n                                    <span translate=\"tatami.home.status.replyTo\"></span>\n                                    <a ui-sref=\"tatami.home.status({ statusId: status.replyTo })\">@{{ status.replyToUsername }}</a>\n                                    <br>\n                                </small>\n\n                                <small ng-if=\"!status.activated && status.type !== 'ANNOUNCEMENT'\">\n                                    <div class=\"badge hidden-phone progress-bar-danger\">\n                                        <span class=\"glyphicon glyphicon-off\"></span>\n                                        <span translate=\"tatami.account.users.deactivated\"></span>\n                                    </div>\n                                </small>\n\n                                <small>\n                                    <div class=\"attachments\">\n                                        <div>\n                                            <span ng-repeat=\"attachment in status.attachments\">\n                                            <a ng-href=\"/tatami/file/{{ attachment.attachmentId }}/{{ attachment.filename }}\" class=\"btn-link status-action\" target=\"_blank\">\n                                                <i class=\"glyphicon glyphicon-file\"></i> {{ attachment.filename }}\n                                            </a>\n                                            </span>\n                                        </div>\n                                    </div>\n\n                                    <div ng-show=\"expanded && status.shares != null && status.shares.length != 0\" id=\"share\">\n                                        <span translate=\"tatami.home.status.shares\"></span>\n                                        <span class=\"badge\">{{ status.shares.length }}</span>\n                                        <div>\n                                            <span ng-repeat=\"user in status.shares\">\n                                                <a ui-sref=\"tatami.home.profile.statuses({ username: user.username })\">\n                                                    <div class=\"img img-rounded img-small share-img-fffix\" ng-attr-title=\"@{{ user.username }}\" ng-style=\"{ 'background-image': 'url(' + user.avatarURL + ')' }\"></div>\n                                                </a>\n                                            </span>\n                                        </div>\n                                    </div>\n                                </small>\n                            </div>\n\n                            <div ng-if=\"status.type == 'STATUS' || status.type == 'SHARE' || status.type == 'ANNOUNCEMENT'\" ng-style=\"{ visibility: showButtonRow ? 'visible': 'hidden' }\" style=\"display: block;\" class=\"mediumHeight little-marge-top buttons\">\n                                <div>\n                                    <small class=\"statusitem-footer\">\n                                        <span>\n                                            <button ng-click=\"openReplyModal(status)\" class=\"btn-link status-action status-action-reply button-ios\">\n                                                <i class=\"glyphicon glyphicon-comment\"></i>\n                                                <span translate=\"tatami.home.status.reply\"></span>\n                                            </button>\n                                            <button ng-if=\"status.username != profile.username && !status.shareByMe && !status.statusPrivate\" ng-click=\"shareStatus(status)\" class=\"btn-link status-action status-action-share button-ios\">\n                                                <i class=\"glyphicon glyphicon-retweet\"></i>\n                                                <span translate=\"tatami.home.status.share\"></span>\n                                            </button>\n                                            <button ng-click=\"favoriteStatus(status)\" class=\"btn-link status-action status-action-favorite button-ios\">\n                                                <i class=\"glyphicon glyphicon-star\"></i>\n                                                <span translate=\"tatami.home.status.favorite\"></span>\n                                            </button>\n                                            <button ng-if=\"isAdmin && status.groupId === null\" ng-click=\"announceStatus(status)\" class=\"btn-link status-action status-action-announce button-ios\">\n                                                <i class=\"glyphicon glyphicon-bullhorn\"></i>\n                                                <span translate=\"tatami.home.status.announce\"></span>\n                                            </button>\n                                            <button ng-if=\"status.username == profile.username\" ng-click=\"deleteStatus(status, ('tatami.status.confirmDelete' | translate))\" class=\"btn-link status-action status-action-delete button-ios\">\n                                                <i class=\"glyphicon glyphicon-trash\"></i>\n                                                <span translate=\"tatami.home.status.delete\"></span>\n                                            </button>\n                                        </span>\n                                        <span ng-if=\"status.replyTo\" class=\"pull-right\">\n                                            <a ui-sref=\"tatami.home.status({ statusId: status.statusId })\" class=\"btn-link status-action button-ios\">\n                                                <span translate=\"tatami.home.status.viewConversation\"></span>\n                                            </a>\n                                        </span>\n                                    </small>\n                                </div>\n                            </div>\n\n                            <div ng-if=\"$index != statusBlock.replies.length - 1\">\n                                <br>\n                            </div>\n                        </div>\n                    </div>\n\n                </div>\n            </div>\n        </div>\n    </section>\n</section>"
  },
  {
    "path": "web/src/main/webapp/app/shared/lists/status/withoutContext/StatusListController.js",
    "content": "HomeModule.controller('StatusListController', [\n    '$scope',\n    '$timeout',\n    '$window',\n    '$translate',\n    'StatusService',\n    'HomeService',\n    'TagService',\n    'GroupService',\n    'profile',\n    'statuses',\n    'userRoles',\n    'showModal',\n    function($scope, $timeout, $window, $translate, StatusService, HomeService, TagService, GroupService, profile, statuses, userRoles, showModal) {\n        if(showModal && $scope.$state.is('tatami.home.home.timeline')) {\n            $scope.$state.go('tatami.home.home.timeline.presentation');\n        }\n\n        $scope.isAdmin = userRoles.roles.indexOf('ROLE_ADMIN') !== -1;\n\n        $scope.profile = profile;\n        $scope.statuses = statuses;\n        $scope.busy = false;\n\n        if($scope.statuses.length === 0) {\n            $scope.end = true;\n        } else {\n            $scope.end = false;\n            $scope.finish = $scope.statuses[$scope.statuses.length - 1].timelineId;\n        }\n\n        /* Begin Polling Related Code */\n\n        $scope.newMessages = null;\n        $window.document.title = 'Tatami';\n\n        var requestNewStatuses = function() {\n            // In milliseconds\n            var pollingDelay = 20000;\n\n            $scope.poller = $timeout(function() {\n                var args = null;\n\n                if($scope.statuses.length > 0) {\n                    if($scope.$state.is('tatami.home.home.tag')) {\n                        args = { tag: $scope.$stateParams.tag, start: statuses[0].timelineId };\n                    }\n\n                    else if($scope.$state.is('tatami.home.home.group.statuses')) {\n                        args = { groupId: $scope.$stateParams.groupId, start: statuses[0].timelineId };\n                    }\n\n                    else if($scope.$state.is('tatami.home.profile.statuses')) {\n                        args = { username: $scope.$stateParams.username, start: statuses[0].timelineId };\n                    }\n\n                    else {\n                        args = { start: statuses[0].timelineId };\n                    }\n                }\n                else {\n                    if($scope.$state.is('tatami.home.home.tag')) {\n                        args = { tag: $scope.$stateParams.tag };\n                    }\n\n                    else if($scope.$state.is('tatami.home.home.group.statuses')) {\n                        args = { groupId: $scope.$stateParams.groupId };\n                    }\n\n                    else if($scope.$state.is('tatami.home.profile.statuses')) {\n                        args = { username: $scope.$stateParams.username };\n                    }\n\n                    else {\n                        args = {};\n                    }\n                }\n\n                var success = function(response) {\n                    if(response.length > 0) {\n                        $scope.newMessages = response;\n                        $window.document.title = 'Tatami (' + $scope.newMessages.length + ')';\n                    }\n                    requestNewStatuses();\n                };\n\n                var error = function() {\n                    requestNewStatuses();\n                };\n\n                if($scope.$state.is('tatami.home.home.timeline')) {\n                    StatusService.getHomeTimeline(args, success, error);\n                }\n\n                else if($scope.$state.is('tatami.home.home.mentions')) {\n                    HomeService.getMentions(args, success, error);\n                }\n\n                else if($scope.$state.is('tatami.home.home.company')) {\n                    HomeService.getCompanyTimeline(args, success, error);\n                }\n\n                else if($scope.$state.is('tatami.home.home.tag')) {\n                    TagService.getTagTimeline(args, success, error);\n                }\n\n                else if($scope.$state.is('tatami.home.home.group.statuses')) {\n                    GroupService.getStatuses(args, success, error);\n                }\n\n                else if($scope.$state.is('tatami.home.profile.statuses')) {\n                    StatusService.getUserTimeline(args, success, error);\n                }\n            }, pollingDelay);\n        };\n\n        requestNewStatuses();\n\n        $scope.$on('$destroy', function() {\n            $timeout.cancel($scope.poller);\n        });\n\n        $scope.loadNewStatuses = function() {\n            for(var i = $scope.newMessages.length - 1; i >= 0 ; i--) {\n                $scope.statuses.unshift($scope.newMessages[i]);\n            }\n\n            $scope.newMessages = null;\n            $window.document.title = 'Tatami';\n        };\n\n        /* End Polling Related Code */\n\n        /* Begin Infinite Scrolling Related Code */\n\n        $scope.requestOldStatuses = function() {\n            if($scope.busy || $scope.end) {\n                return;\n            }\n\n            $scope.busy = true;\n\n            if($scope.$state.is('tatami.home.home.timeline')) {\n                StatusService.getHomeTimeline({ finish: $scope.finish }, loadOldStatuses);\n            }\n\n            else if($scope.$state.is('tatami.home.home.company')) {\n                HomeService.getCompanyTimeline({ finish: $scope.finish }, loadOldStatuses);\n            }\n\n            else if($scope.$state.is('tatami.home.home.mentions')) {\n                HomeService.getMentions({ finish: $scope.finish }, loadOldStatuses);\n            }\n\n            /*\n                Favorites are limited to 50 total per user. All 50 are loaded\n                from the favorites REST endpoint at once. There is no way to use\n                &finish=timelineId for favorites as of now in the backend.\n\n                Keep this commented out until the backend is changed to allow\n                for more than 50 favorites and adding &finish=timelineId to the\n                REST url.\n            */\n\n            else if($scope.$state.is('tatami.home.home.tag')) {\n                TagService.getTagTimeline({ tag: $scope.$stateParams.tag, finish: $scope.finish }, loadOldStatuses);\n            }\n\n            else if($scope.$state.is('tatami.home.home.group.statuses')) {\n                GroupService.getStatuses({ groupId: $scope.$stateParams.groupId, finish: $scope.finish }, loadOldStatuses);\n            }\n\n            else if($scope.$state.is('tatami.home.profile.statuses')) {\n                StatusService.getUserTimeline({ username: $scope.$stateParams.username, finish: $scope.finish }, loadOldStatuses);\n            }\n        };\n\n        var loadOldStatuses = function(statuses) {\n            if(statuses.length === 0){\n                $scope.end = true; // reached end of list\n                return;\n            }\n\n            for(var i = 0; i < statuses.length; i++) {\n                $scope.statuses.push(statuses[i]);\n            }\n\n            $scope.finish = $scope.statuses[$scope.statuses.length - 1].timelineId;\n            $scope.busy = false;\n        };\n\n        /* End Infinite Scrolling Related Code */\n\n        $scope.isOneDayOrMore = function(date) {\n            return moment().diff(moment(date), 'days', true) >= 1;\n        };\n\n        $scope.getLanguageKey = function() {\n            return $translate.use();\n        };\n\n        $scope.openReplyModal = function(status) {\n            $scope.$state.go($scope.$state.current.name + '.post', { statusId: status.statusId });\n        };\n\n        $scope.favoriteStatus = function(status, index) {\n            StatusService.update({ statusId: status.statusId }, { favorite: !status.favorite }, \n                function(response) {\n                    $scope.statuses[index].favorite = response.favorite;\n            });\n        };\n\n        $scope.shareStatus = function(status, index) {\n            StatusService.update({ statusId: status.statusId }, { shared: !status.shareByMe }, \n                function(response) {\n                    $scope.statuses[index].shareByMe = response.shareByMe;\n            });\n        };\n\n        $scope.announceStatus = function(status) {\n            StatusService.update({ statusId: status.statusId }, { announced: true },\n                function() {\n                    $scope.$state.reload();\n\n            });\n        };\n\n        $scope.deleteStatus = function(status, index) {\n            // Need a confirmation modal here\n            StatusService.delete({ statusId: status.statusId }, null,\n                function() {\n                    $scope.statuses.splice(index, 1);\n            });\n        };\n\n        $scope.getShares = function(status, index) {\n            if(status.type === 'STATUS' && status.shares === null) {\n                StatusService.getDetails({ statusId: status.statusId }, null,\n                    function(response) {\n                        $scope.statuses[index].shares = response.sharedByLogins;\n                });\n            }\n        };\n    }\n]);"
  },
  {
    "path": "web/src/main/webapp/app/shared/lists/status/withoutContext/StatusListView.html",
    "content": "<section class=\"tatams-container\">\n    <section ng-if=\"newMessages\" ng-click=\"loadNewStatuses()\" class=\"refresh-button pointer\">\n        <div class=\"text-center refresh-button-style\">\n            <span class=\"badge\">{{ newMessages.length }}</span>\n            <span ng-if=\"newMessages.length == 1\" translate=\"tatami.home.newMessage\"></span>\n            <span ng-if=\"newMessages.length > 1\" translate=\"tatami.home.newMessages\"></span>\n        </div>\n    </section>\n    <section class=\"timeline\" infinite-scroll=\"requestOldStatuses()\" infinite-scroll-disabled=\"busy\">\n        <div class=\"tatams\" ng-repeat=\"status in statuses\">\n            <div class=\"tatam pointer tatam-border-lr tatam-hover\" style=\"display: block;\">\n                <div id=\"current\" ng-mouseenter=\"showButtonRow = true\" ng-mouseleave=\"showButtonRow = false\">\n\n                    <div ng-class=\"{ 'favorite': status.favorite, 'share': status.shareByMe, 'both': status.favorite && status.shareByMe }\">\n                        <div class=\"pull-left background-image-fffix statusitem-img\">\n                            <a ui-sref=\"tatami.home.profile.statuses({ username: status.username })\">\n                                <div class=\"img img-rounded img-medium\" ng-style=\"{ 'background-image': 'url(' + status.avatarURL + ')' }\"></div>\n                            </a>\n                        </div>\n                        <div class=\"status-content-container\" ng-init=\"expanded = false\" ng-click=\"getShares(status, $index); expanded = !expanded\">\n                            <h5 class=\"statusitem-name\">\n                                <small ng-if=\"status.type == 'SHARE'\">\n                                    <span class=\"glyphicon glyphicon-retweet\">&nbsp;</span>\n                                    <a ui-sref=\"tatami.home.profile.statuses({ username: status.username })\">\n                                        <span class=\"text-muted\">@{{ status.sharedByUsername }}</span>\n                                    </a>\n                                    <span translate=\"tatami.home.status.shared\"></span>\n                                    <br>\n                                </small>\n                                <span ng-if=\"status.type == 'MENTION_SHARE'\" class=\"glyphicon glyphicon-retweet\">&nbsp;</span>\n                                <span ng-if=\"status.type == 'MENTION_FRIEND'\" class=\"glyphicon glyphicon-user\">&nbsp;</span>\n                                <a ui-sref=\"tatami.home.profile.statuses({ username: status.username })\">\n                                    <strong>{{ status.firstName + ' ' + status.lastName }}</strong>\n                                    <small>@{{ status.username }}</small>\n                                </a>\n                                <span ng-if=\"status.type == 'MENTION_SHARE'\" translate=\"tatami.home.status.sharedYour\"></span>\n                                <span ng-if=\"status.type == 'MENTION_FRIEND'\" translate=\"tatami.home.status.followed\"></span>\n                                <small> · </small>\n                                <!-- Replace hover title with hover bubble -->\n                                <a ui-sref=\"tatami.home.status({ statusId: status.statusId })\">\n                                    <!--English-->\n                                    <small ng-if=\"!isOneDayOrMore(status.statusDate) && getLanguageKey() == 'en'\" title=\"{{ status.statusDate | amDateFormat:'h:mm A - D MMM YYYY' }}\" am-time-ago=\"status.statusDate\"></small>\n                                    <small ng-if=\"isOneDayOrMore(status.statusDate) && getLanguageKey() == 'en'\" title=\"{{ status.statusDate | amDateFormat:'h:mm A - D MMM YYYY' }}\">{{ status.statusDate | amDateFormat:'MMM D' }}</small>\n                                    <!--French-->\n                                    <small ng-if=\"!isOneDayOrMore(status.statusDate) && getLanguageKey() == 'fr'\" title=\"{{ status.statusDate | amDateFormat:'HH:mm - D MMMM YYYY' }}\" am-time-ago=\"status.statusDate\"></small>\n                                    <small ng-if=\"isOneDayOrMore(status.statusDate) && getLanguageKey() == 'fr'\" title=\"{{ status.statusDate | amDateFormat:'HH:mm - D MMMM YYYY' }}\">{{ status.statusDate | amDateFormat:'D MMMM' }}</small>\n                                </a>\n                                <a ng-if=\"status.locationURL\" class=\"glyphicon glyphicon-map-marker\" ng-href=\"{{ status.locationURL }}\" target=\"_blank\"></a>\n                            </h5>\n\n                            <div class=\"markdown\" ng-class=\"{ 'mention-share': status.type == 'MENTION_SHARE' }\" ng-bind-html=\"status.content | emoticon | markdown\"></div>\n\n                            <small ng-if=\"status.groupId\">\n                                <a class=\"label\" ng-class=\"{ 'label-info': !status.publicGroup, 'label-warning': status.publicGroup }\" ui-sref=\"tatami.home.home.group.statuses({ groupId: status.groupId })\">\n                                {{ status.groupName }}\n                                </a>\n                                <br>\n                            </small>\n\n                            <small ng-if=\"status.statusPrivate\">\n                                <span class=\"glyphicon glyphicon-lock\"></span>\n                                <span translate=\"tatami.home.status.private\"></span>\n                                <br>\n                            </small>\n\n                            <small ng-if=\"status.type === 'ANNOUNCEMENT'\">\n                                <span class=\"glyphicon glyphicon-bullhorn\">\n                                    {{ 'tatami.home.status.isAnnounced' | translate }}\n                                </span>\n                                <a ui-sref=\"tatami.home.status({ statusId: status.sharedByUsername })\">@{{ status.sharedByUsername }}</a>\n                            </small>\n\n                            <small ng-if=\"status.replyTo && status.type !== 'ANNOUNCEMENT'\">\n                                <span class=\"glyphicon glyphicon-share-alt\"></span>\n                                <span translate=\"tatami.home.status.replyTo\"></span>\n                                <a ui-sref=\"tatami.home.status({ statusId: status.replyTo })\">@{{ status.replyToUsername }}</a>\n                                <br>\n                            </small>\n\n                            <small ng-if=\"!status.activated && status.type !== 'ANNOUNCEMENT'\">\n                                <div class=\"badge hidden-phone progress-bar-danger\">\n                                    <span class=\"glyphicon glyphicon-off\"></span>\n                                    <span translate=\"tatami.account.users.deactivated\"></span>\n                                </div>\n                            </small>\n\n                            <small>\n                                <div class=\"attachments\">\n                                    <div>\n                                        <span ng-repeat=\"attachment in status.attachments\">\n                                        <a ng-href=\"/tatami/file/{{ attachment.attachmentId }}/{{ attachment.filename }}\" class=\"btn-link status-action\" target=\"_blank\">\n                                            <i class=\"glyphicon glyphicon-file\"></i> {{ attachment.filename }}\n                                        </a>\n                                        </span>\n                                    </div>\n                                </div>\n\n                                <div ng-show=\"expanded && status.shares != null && status.shares.length != 0\" id=\"share\">\n                                    <span translate=\"tatami.home.status.shares\"></span>\n                                    <span class=\"badge\">{{ status.shares.length }}</span>\n                                    <div>\n                                        <span ng-repeat=\"user in status.shares\">\n                                            <a ui-sref=\"tatami.home.profile.statuses({ username: user.username })\">\n                                                <div class=\"img img-rounded img-small share-img-fffix\" ng-attr-title=\"@{{ user.username }}\" ng-style=\"{ 'background-image': 'url(' + user.avatarURL + ')' }\"></div>\n                                            </a>\n                                        </span>\n                                    </div>\n                                </div>\n                            </small>\n                        </div>\n\n                        <div ng-if=\"status.type == 'STATUS' || status.type == 'SHARE' || status.type == 'ANNOUNCEMENT'\" ng-style=\"{ visibility: showButtonRow ? 'visible': 'hidden' }\" style=\"display: block;\" class=\"mediumHeight little-marge-top buttons\">\n                            <div>\n                                <small class=\"statusitem-footer\">\n                                    <span>\n                                        <button ng-click=\"openReplyModal(status)\" class=\"btn-link status-action status-action-reply button-ios\">\n                                            <i class=\"glyphicon glyphicon-comment\"></i>\n                                            <span translate=\"tatami.home.status.reply\"></span>\n                                        </button>\n                                        <button ng-if=\"status.username != profile.username && !status.shareByMe && !status.statusPrivate\" ng-click=\"shareStatus(status, $index)\" class=\"btn-link status-action status-action-share button-ios\">\n                                            <i class=\"glyphicon glyphicon-retweet\"></i>\n                                            <span translate=\"tatami.home.status.share\"></span>\n                                        </button>\n                                        <button ng-click=\"favoriteStatus(status, $index)\" class=\"btn-link status-action status-action-favorite button-ios\">\n                                            <i class=\"glyphicon glyphicon-star\"></i>\n                                            <span translate=\"tatami.home.status.favorite\"></span>\n                                        </button>\n                                        <button ng-if=\"isAdmin && status.groupId === null\" ng-click=\"announceStatus(status)\" class=\"btn-link status-action status-action-announce button-ios\">\n                                            <i class=\"glyphicon glyphicon-bullhorn\"></i>\n                                            <span translate=\"tatami.home.status.announce\"></span>\n                                        </button>\n                                        <button ng-if=\"status.username == profile.username\" ng-click=\"deleteStatus(status, $index,('tatami.status.confirmDelete' | translate))\" class=\"btn-link status-action status-action-delete button-ios\">\n                                            <i class=\"glyphicon glyphicon-trash\"></i>\n                                            <span translate=\"tatami.home.status.delete\"></span>\n                                        </button>\n                                    </span>\n                                    <span ng-if=\"status.replyTo\" class=\"pull-right\">\n                                        <a ui-sref=\"tatami.home.status({ statusId: status.statusId })\" class=\"btn-link status-action button-ios\">\n                                            <span translate=\"tatami.home.status.viewConversation\"></span>\n                                        </a>\n                                    </span>\n                                </small>\n                            </div>\n                        </div>\n                    </div>\n\n                </div>\n            </div>\n        </div>\n    </section>\n</section>"
  },
  {
    "path": "web/src/main/webapp/app/shared/lists/user/UserListController.js",
    "content": "HomeModule.controller('UserListController', ['$scope', 'UserService', 'users',\n    function($scope, UserService, users) {\n        $scope.users = users;\n\n        $scope.followUser = function(user, index) {\n            UserService.follow({ username: user.username }, { friend: !user.friend, friendShip: true }, \n                function(response) {\n                    $scope.users[index].friend = response.friend;\n                    $scope.$state.reload();\n            });\n        };\n    }\n]);"
  },
  {
    "path": "web/src/main/webapp/app/shared/lists/user/UserListView.html",
    "content": "<section class=\"tatams-container\">\n    <section class=\"timeline\">\n        <div class=\"useritem\" ng-repeat=\"user in users\">\n            <div class='pull-left background-image-fffix'>\n                <a ui-sref=\"tatami.home.profile.statuses({ username: user.username })\">\n                    <div class=\"img img-rounded img-medium\" ng-style=\"{ 'background-image': 'url(' + user.avatarURL + ')' }\"></div>\n                </a>\n            </div>\n            <h4>\n                <span ng-if=\"!user.you\" ng-click=\"followUser(user, $index)\" ng-init=\"hover = false\" ng-mouseenter=\"hover = true\" ng-mouseleave=\"hover = false\" class=\"pointer pull-right label\" ng-class=\"{ 'label-danger': user.friend && hover, 'label-info': user.friend && !hover }\">\n                    <span class=\"glyphicon\" ng-class=\"user.friend ? 'glyphicon-minus' : 'glyphicon-plus'\"></span>\n                </span>\n                \n                <a ui-sref=\"tatami.home.profile.statuses({ username: user.username })\">\n                    <strong>\n                        {{ user.firstName + ' ' + user.lastName }}\n                    </strong>\n                </a>\n\n                <a ui-sref=\"tatami.home.profile.statuses({ username: user.username })\">\n                    <small>\n                        @{{ user.username }}\n                    </small>\n                </a>\n\n                <div class=\"text-muted\">\n                    {{ user.jobTitle }}\n                </div>\n\n                <div ng-if=\"user.role == 'ADMIN'\" class=\"text-muted\" translate=\"tatami.home.status.groupAdmin\"></div>\n            </h4>\n        </div>\n    </section>\n</section>"
  },
  {
    "path": "web/src/main/webapp/app/shared/services/AuthenticationService.js",
    "content": "TatamiApp.factory('AuthenticationService', ['$rootScope', '$state', 'UserSession', function($rootScope, $state, UserSession) {\n    return {\n        authenticate: function() {\n            return UserSession.authenticate().then(function(result) {\n                if(result !== null && result.action === null && $state.current.data && !$state.current.data.public) {\n                    // User isn't login in. Change the session token, and redirect to login\n                    UserSession.clearSession();\n                    $state.go('tatami.login.main');\n                }\n            });\n        }\n    }\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/shared/services/GeolocService.js",
    "content": "/**\n * This service is used to handle getting the geolocalisation of a user\n */\n\nTatamiApp.factory('GeolocalisationService', function() {\n    return {\n        \n        /**\n         * Uses HTML5 to get geolocation information from the user\n         * @returns If geolocation data can be found for the user\n         *              then we return the position in the form\n         *              \"lat, lon\"\n         *          Otherwise, we return the empty string.\n         */\n        getGeolocalisation: function(callback) {\n            if(navigator.geolocation){\n                navigator.geolocation.getCurrentPosition(function(position) {\n                    callback(position);\n                });\n            }\n        },\n\n        /**\n         * Returns a string with the location data based on the openstreetmap website\n         * @param position The users position\n         * @returns {string} The URL to openstreetmaps\n         */\n        getGeolocUrl: function(position) {\n            var latitude = position.split(',')[0].trim();\n            var longitude = position.split(',')[1].trim();\n            return 'https://www.openstreetmap.org/?mlon=' + longitude + '&mlat=' + latitude;\n        }\n    }\n});"
  },
  {
    "path": "web/src/main/webapp/app/shared/services/GroupService.js",
    "content": "TatamiApp.factory('GroupService', ['$resource', function($resource) {\n    return $resource('/tatami/rest/groups/:groupId', null,\n    {\n        'getStatuses': { \n            method: 'GET',\n            isArray: true,\n            params: { groupId: '@groupId' },\n            url: '/tatami/rest/groups/:groupId/timeline',\n            transformResponse: function(statuses) {\n                statuses = angular.fromJson(statuses);\n\n                for(var i = 0; i < statuses.length; i++) {\n                    statuses[i]['avatarURL'] = statuses[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + statuses[i].avatar + '/photo.jpg';\n\n                    if(statuses[i].geoLocalization) {\n                        var latitude = statuses[i].geoLocalization.split(',')[0].trim();\n                        var longitude = statuses[i].geoLocalization.split(',')[1].trim();\n                        statuses[i]['locationURL'] = \n                            'https://www.openstreetmap.org/?mlon='\n                            + longitude + '&mlat=' + latitude;\n                    }\n                }\n\n                return statuses;\n            }\n        },\n        'getMembers': { \n            method: 'GET',\n            isArray: true,\n            params: { groupId: '@groupId' },\n            url: '/tatami/rest/groups/:groupId/members/',\n            transformResponse: function(users) {\n                users = angular.fromJson(users);\n\n                for(var i = 0; i < users.length; i++) {\n                    users[i]['avatarURL'] = users[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + users[i].avatar + '/photo.jpg';\n                }\n\n                return users;\n            }\n        },\n        'getRecommendations': { method: 'GET', isArray: true, url: '/tatami/rest/groupmemberships/suggestions' },\n        'join': { method: 'PUT', params: { groupId: '@groupId', username: '@username' }, url: '/tatami/rest/groups/:groupId/members/:username' },\n        'leave': { method: 'DELETE', params: { groupId: '@groupId', username: '@username' }, url: '/tatami/rest/groups/:groupId/members/:username' },\n        'update': { method: 'PUT', params: { groupId: '@groupId' }, url: '/tatami/rest/groups/:groupId' }\n    });\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/shared/services/HomeService.js",
    "content": "TatamiApp.factory('HomeService', ['$resource', function($resource) {\n    var responseTransform = function(statuses) {\n        statuses = angular.fromJson(statuses);\n\n        for(var i = 0; i < statuses.length; i++) {\n            statuses[i]['avatarURL'] = statuses[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + statuses[i].avatar + '/photo.jpg';\n\n            if(statuses[i].geoLocalization) {\n                var latitude = statuses[i].geoLocalization.split(',')[0].trim();\n                var longitude = statuses[i].geoLocalization.split(',')[1].trim();\n                statuses[i]['locationURL'] = \n                    'https://www.openstreetmap.org/?mlon='\n                    + longitude + '&mlat=' + latitude;\n            }\n        }\n\n        return statuses;\n    };\n\n    return $resource(null, null,\n    {\n        'getMentions': { \n            method: 'GET', isArray: true, url: '/tatami/rest/mentions',\n            transformResponse: responseTransform\n        },\n        'getFavorites': { \n            method: 'GET', isArray: true, url: '/tatami/rest/favorites',\n            transformResponse: responseTransform\n        },\n        'getCompanyTimeline': { \n            method: 'GET', isArray: true, url: '/tatami/rest/company',\n            transformResponse: responseTransform\n        }\n     });\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/shared/services/ProfileService.js",
    "content": "angular.module('TatamiApp.services', [])\n    .factory('ProfileService', ['$resource', function ($resource) {\n        return $resource('/tatami/rest/account/profile', null,\n            {\n                'get': {\n                    method: 'GET',\n                    transformResponse: function (profile) {\n                        var parsedProfile = {};\n                        try {\n                            parsedProfile = angular.fromJson(profile);\n                        } catch(e) {\n                            parsedProfile = {};\n                        }\n                        parsedProfile['avatarURL'] = parsedProfile.avatar === '' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + parsedProfile.avatar + '/photo.jpg';\n                        return parsedProfile;\n                    }\n                },\n                'update': {\n                    method: 'PUT',\n                    transformRequest: function (profile) {\n                        delete profile['avatarURL'];\n                        return angular.toJson(profile);\n                    }\n                }\n            });\n    }]);\n"
  },
  {
    "path": "web/src/main/webapp/app/shared/services/SearchService.js",
    "content": "TatamiApp.factory('SearchService', ['$resource', function($resource) {\n    var responseTransform = function(users) {\n        users = angular.fromJson(users);\n\n        for(var i = 0; i < users.length; i++) {\n            users[i]['avatarURL'] = users[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + users[i].avatar + '/photo.jpg';\n        }\n\n        return users;\n    };\n\n    return $resource('/tatami/rest/search/:term', { term: '@term' },\n    {\n        'query': { \n            method: 'GET', isArray: true, transformResponse: responseTransform\n        },\n        'get': {\n            method: 'GET', transformResponse: responseTransform\n        }\n    });\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/shared/services/StatusService.js",
    "content": "TatamiApp.factory('StatusService', ['$resource', function($resource) {\n    var responseTransform = function(statuses) {\n        statuses = angular.fromJson(statuses);\n\n        for(var i = 0; i < statuses.length; i++) {\n            statuses[i]['avatarURL'] = statuses[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + statuses[i].avatar + '/photo.jpg';\n\n            if(statuses[i].geoLocalization) {\n                var latitude = statuses[i].geoLocalization.split(',')[0].trim();\n                var longitude = statuses[i].geoLocalization.split(',')[1].trim();\n                statuses[i]['locationURL'] =\n                    'https://www.openstreetmap.org/?mlon='\n                    + longitude + '&mlat=' + latitude;\n            }\n        }\n\n        return statuses;\n    };\n\n    return $resource('/tatami/rest/statuses/:statusId', null,\n    {\n        'get': {\n            method: 'GET',\n            transformResponse: function(status) {\n                status = angular.fromJson(status);\n\n                status.avatarURL = status.avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + status.avatar + '/photo.jpg';\n\n                if(status.geoLocalization) {\n                    var latitude = status.geoLocalization.split(',')[0].trim();\n                    var longitude = status.geoLocalization.split(',')[1].trim();\n                    status['locationURL'] =\n                        'https://www.openstreetmap.org/?mlon='\n                        + longitude + '&mlat=' + latitude;\n                }\n\n                return status;\n             }\n        },\n        'getHomeTimeline': {\n            method: 'GET', isArray: true, url: '/tatami/rest/statuses/home_timeline',\n            transformResponse: responseTransform\n        },\n        'getUserTimeline': {\n            method: 'GET', isArray: true, params: { username: '@username' }, url: '/tatami/rest/statuses/:username/timeline',\n            transformResponse: responseTransform\n        },\n        'getDetails': {\n            method: 'GET', params: { statusId: '@statusId' }, url: '/tatami/rest/statuses/details/:statusId',\n            transformResponse: function(details) {\n                details = angular.fromJson(details);\n\n                for(var i = 0; i < details.discussionStatuses.length; i++) {\n                    details.discussionStatuses[i]['avatarURL'] = details.discussionStatuses[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + details.discussionStatuses[i].avatar + '/photo.jpg';\n\n                    if(details.discussionStatuses[i].geoLocalization) {\n                        var latitude = details.discussionStatuses[i].geoLocalization.split(',')[0].trim();\n                        var longitude = details.discussionStatuses[i].geoLocalization.split(',')[1].trim();\n                        details.discussionStatuses[i]['locationURL'] =\n                            'https://www.openstreetmap.org/?mlon='\n                            + longitude + '&mlat=' + latitude;\n                    }\n                }\n\n                for(var i = 0; i < details.sharedByLogins.length; i++) {\n                    details.sharedByLogins[i]['avatarURL'] = details.sharedByLogins[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + details.sharedByLogins[i].avatar + '/photo.jpg';\n                }\n\n                return details;\n            }\n        },\n        'update': { method: 'PATCH', params: { statusId: '@statusId' } },\n        'announce': { method: 'PATCH', params: { params: '@statusId' } }\n    });\n}]);\n"
  },
  {
    "path": "web/src/main/webapp/app/shared/services/TagService.js",
    "content": "TatamiApp.factory('TagService', ['$resource', function($resource) {\n    return $resource('/tatami/rest/tags', null,\n    {   \n        'get': { method:'GET', params: { tag: '@tag' }, url: '/tatami/rest/tags/:tag' },\n        'getTagTimeline': { \n            method:'GET', isArray: true, params: { tag: '@tag' }, url: '/tatami/rest/tags/:tag/tag_timeline',\n            transformResponse: function(statuses) {\n                statuses = angular.fromJson(statuses);\n\n                for(var i = 0; i < statuses.length; i++) {\n                    statuses[i]['avatarURL'] = statuses[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + statuses[i].avatar + '/photo.jpg';\n\n                    if(statuses[i].geoLocalization) {\n                        var latitude = statuses[i].geoLocalization.split(',')[0].trim();\n                        var longitude = statuses[i].geoLocalization.split(',')[1].trim();\n                        statuses[i]['locationURL'] = \n                            'https://www.openstreetmap.org/?mlon='\n                            + longitude + '&mlat=' + latitude;\n                    }\n                }\n\n                return statuses;\n            }\n        },\n        'follow': { method:'PUT', params: { tag: '@tag' }, url: '/tatami/rest/tags/:tag' },\n        'getPopular': { method: 'GET', isArray: true, url: '/tatami/rest/tags/popular' }\n    });\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/shared/services/TopPostersService.js",
    "content": "TatamiApp.factory('TopPostersService', ['$resource', function($resource) {\n    return $resource('/tatami/rest/stats/day');\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/shared/services/UserService.js",
    "content": "TatamiApp.factory('UserService', ['$resource', function($resource) {\n    var responseTransform = function(users) {\n        users = angular.fromJson(users);\n\n        for(var i = 0; i < users.length; i++) {\n            users[i]['avatarURL'] = users[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + users[i].avatar + '/photo.jpg';\n        }\n\n        return users;\n    };\n\n    return $resource('/tatami/rest/users/:username', null,\n    { \n        'get': { \n            method: 'GET', params: { username: '@username' },\n            transformResponse: function(user) {\n                user = angular.fromJson(user);\n                user['avatarURL'] = user.avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + user.avatar + '/photo.jpg';\n                return user;\n            }\n        },\n        'query': { \n            method: 'GET', isArray: true, url: '/tatami/rest/users',\n            transformResponse: responseTransform\n        },\n        'getFollowing': { \n            method: 'GET', isArray: true, params: { username: '@username' }, url: '/tatami/rest/users/:username/friends',\n            transformResponse: responseTransform\n        },\n        'getFollowers': { \n            method: 'GET', isArray: true, params: { username: '@username' }, url: '/tatami/rest/users/:username/followers',\n            transformResponse: responseTransform\n        },\n        'getSuggestions': { \n            method: 'GET', isArray: true, url: '/tatami/rest/users/suggestions', \n            transformResponse: function(suggestions) {\n                suggestions = angular.fromJson(suggestions);\n\n                for(var i = 0; i < suggestions.length; i++) {\n                    suggestions[i]['avatarURL'] = suggestions[i].avatar==='' ? '/assets/img/default_image_profile.png' : '/tatami/avatar/' + suggestions[i].avatar + '/photo.jpg';\n                    suggestions[i]['followingUser'] = false;\n                }\n\n                return suggestions;\n            }\n        },\n        'follow': { method: 'PATCH', params: { username: '@username' } },\n        'searchUsers': { method: 'GET', isArray: true, url: '/tatami/rest/users/:term', transformResponse: responseTransform },\n        'deactivate': { method: 'PATCH', params: { username: '@username' } }\n    });\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/shared/services/UserSession.js",
    "content": "TatamiApp.factory('UserSession', ['$q', '$window', 'ProfileService', 'localStorageService', function($q, $window, ProfileService, localStorageService) {\n    var user;\n    var authenticated = false;\n\n    return {\n        isAuthenticated: function() {\n            return localStorageService.get('token') === \"true\";\n        },\n\n        isUserResolved: function() {\n            return angular.isDefined(user);\n        },\n\n        setLoginState: function(loggedIn) {\n            localStorageService.set('token', loggedIn);\n        },\n\n        clearSession: function() {\n            localStorageService.clearAll();\n        },\n\n        getUser: function() {\n            return user;\n        },\n\n        authenticate: function(force) {\n            var deferred = $q.defer();\n\n            if(force) {\n                user = undefined;\n            }\n\n            if(this.isUserResolved() && user.action !== null) {\n                deferred.resolve(user);\n                return deferred.promise;\n            }\n\n            ProfileService.get(function(data) {\n                // Success\n                user = data;\n                authenticated = true;\n                deferred.resolve(user);\n            }, function() {\n                // Error\n                user = null;\n                authenticated = false;\n                deferred.resolve(user);\n            });\n\n            return deferred.promise;\n        }\n    }\n}]);\n"
  },
  {
    "path": "web/src/main/webapp/app/shared/sidebars/home/HomeSidebarController.js",
    "content": "HomeSidebarModule.controller('HomeSidebarController', ['$scope', 'UserService', 'TagService', 'profile', 'groups', 'suggestions', 'tags',\n    function($scope, UserService, TagService, profile, groups, suggestions, tags) {\n        $scope.profile = profile;\n        $scope.groups = groups;\n        $scope.suggestions = suggestions;\n        $scope.tags = tags;\n\n        $scope.followUser = function(suggestion, index) {\n            UserService.follow({ username: suggestion.username }, { friend: !suggestion.followingUser, friendShip: true }, \n                function(response) {\n                    $scope.suggestions[index].followingUser = response.friend;\n            });\n        };\n\n        $scope.followTag = function(tag, index) {\n            TagService.follow({ tag: tag.name }, { name: tag.name, followed: !tag.followed, trendingUp: tag.trendingUp }, \n                function(response) { \n                    $scope.tags[index].followed = response.followed;\n                    $scope.$state.reload();\n            });\n        };\n    }\n]);"
  },
  {
    "path": "web/src/main/webapp/app/shared/sidebars/home/HomeSidebarModule.js",
    "content": "var HomeSidebarModule = angular.module('HomeSidebarModule', []);"
  },
  {
    "path": "web/src/main/webapp/app/shared/sidebars/home/HomeSidebarView.html",
    "content": "<div>\n    <section class=\"hidden-phone card-profile\">\n        <div class=\"page-header\">\n            <h4 class=\"profile-card background-image-fffix\">\n                <div class=\"img img-rounded pull-left\" ng-init=\"click = false\" ng-click=\"click = !click\" ng-class=\"click ? 'img-big' : 'img-medium-big'\" ng-style=\"{ 'background-image': 'url(' + profile.avatarURL + ')' }\"></div>\n            </h4>\n        </div>\n        <div class=\"well well-sm little-padding\">\n            <div>\n                <a class=\"h3\" ui-sref=\"tatami.home.profile.statuses({ username: profile.username })\">\n                    <strong>{{ profile.firstName + ' ' + profile.lastName }}</strong>\n                </a>\n            </div>\n            <div>                \n                <a class=\"h5 text-muted\" ui-sref=\"tatami.home.profile.statuses({ username: profile.username })\">\n                    @{{ profile.username }}\n                </a>\n            </div>\n        </div>\n    </section>\n    <section class=\"hidden-phone groups\">\n        <div class=\"panel panel-default\">\n            <div tour-step\n                 order=\"3\"\n                 title=\"<b>{{ 'tatami.welcome.groups.title' | translate }}</b>\"\n                 content=\"{{ 'tatami.welcome.groups.line1' | translate }}\n                         <p>{{ 'tatami.welcome.groups.line2' | translate }}</p>\n                         <p>{{ 'tatami.welcome.groups.line3' | translate }}</p>\n                         <br>\"\n                 placement=\"right\"\n                 skip=\"false\"\n                 on-end=\"onTourEnd(tour)\"\n                 class=\"panel-heading\">\n                <span class=\"glyphicon glyphicon-th-large\"></span>\n                <span translate=\"tatami.home.sidebar.myGroups\"></span>\n            </div>\n            <table class=\"table table-condensed nomargin\">\n                <tr ng-repeat=\"group in groups\">\n                    <td>\n                        <a ui-sref=\"tatami.home.home.group.statuses({ groupId: group.groupId })\">{{ group.name }}</a>\n                    </td>\n                    <td class=\"text-right\" nowrap>\n                        <span ng-if=\"group.publicGroup\" class=\"label label-warning\" title=\"{{ 'tatami.home.sidebar.publicToolTip' | translate }}\"><small translate=\"tatami.home.sidebar.public\"></small></span>\n                        <span ng-if=\"!group.publicGroup\" class=\"label label-info\" title=\"{{ 'tatami.home.sidebar.privateToolTip' | translate }}\"><small translate=\"tatami.home.sidebar.private\"></small></span>\n                        <span ng-if=\"group.archivedGroup\" class=\"label label-default\" title=\"{{ 'tatami.home.sidebar.archivedToolTip' | translate }}\"><small translate=\"tatami.home.sidebar.archived\"></small></span>\n                        <span ng-if=\"group.administrator\" class=\"label label-danger\" title=\"{{ 'tatami.home.sidebar.administratorToolTip' | translate }}\"><small translate=\"tatami.home.sidebar.administrator\"></small></span>\n                    </td>\n                </tr>\n            </table>\n        </div>\n    </section>\n    <section class=\"hidden-phone tag-trends\">\n        <div class=\"panel panel-default\">\n            <div tour-step\n                 order=\"4\"\n                 title=\"<b>{{ 'tatami.welcome.trends.title' | translate }}</b>\"\n                 content=\"{{ 'tatami.welcome.trends.line1' | translate }}\"\n                 placement=\"right\"\n                 skip=\"false\"\n                 on-end=\"onTourEnd(tour)\"\n                class=\"panel-heading\">\n                <span class=\"glyphicon glyphicon-fire\"></span>\n                <span translate=\"tatami.home.sidebar.trends\"></span>\n            </div>\n            <div class=\"panel-body items\">\n                <div ng-repeat=\"tag in tags\">\n                    <span ng-click=\"followTag(tag, $index)\" ng-init=\"hover = false\" ng-mouseenter=\"hover = true\" ng-mouseleave=\"hover = false\" class=\"label little-padding pointer pull-right\" ng-class=\"{ 'label-danger': tag.followed && hover, 'label-info': tag.followed && !hover }\">\n                        <span class=\"glyphicon\" ng-class=\"tag.followed ? 'glyphicon-minus' : 'glyphicon-plus'\"></span>\n                    </span>\n                    <span class=\"glyphicon\" ng-class=\"tag.trendingUp ? 'glyphicon-arrow-up' : 'glyphicon-arrow-down'\"></span>\n                    <a ui-sref=\"tatami.home.home.tag({ tag: tag.name })\">#{{ tag.name }}</a>\n                </div>\n            </div>\n        </div>\n    </section>\n    <section class=\"hidden-phone who-to-follow\">\n        <div class=\"panel panel-default\">\n            <div tour-step\n                 order=\"5\"\n                 title=\"<b>{{ 'tatami.welcome.whoToFollow.title' | translate }}</b>\"\n                 content=\"{{ 'tatami.welcome.whoToFollow.line1' | translate }}\n                         <p>{{ 'tatami.welcome.whoToFollow.line2' | translate }}</p>\n                         <p>{{ 'tatami.welcome.whoToFollow.line3' | translate }}</p>\n                         <br>\"\n                placement=\"right\"\n                skip=\"false\"\n                on-end=\"onTourEnd(tour)\"\n                class=\"panel-heading\">\n                <span class=\"glyphicon glyphicon-user\"></span>\n                <span translate=\"tatami.home.sidebar.whoToFollow\"></span>\n            </div>\n            <div class=\"panel-body items useritemmini\" ng-repeat=\"suggestion in suggestions\">\n                <h6>\n                    <span ng-click=\"followUser(suggestion, $index)\" class=\"pointer pull-right label\" ng-class=\"{ 'label-info': suggestion.followingUser }\">\n                        <span class=\"glyphicon\" ng-class=\"suggestion.followingUser ? 'glyphicon-minus' : 'glyphicon-plus'\"></span>\n                    </span>\n                    <a ui-sref=\"tatami.home.profile.statuses({ username: suggestion.username })\">\n                        <span class='pull-left background-image-fffix'>\n                            <img class=\"img-rounded img-small\" ng-style=\"{ 'background-image': 'url(' + suggestion.avatarURL + ')' }\">\n                        </span>\n                    </a>&nbsp;\n                    <a ui-sref=\"tatami.home.profile.statuses({ username: suggestion.username })\">\n                        <strong>{{ suggestion.firstName + ' ' + suggestion.lastName }}</strong>\n                    </a>\n                    <br>&nbsp;\n                    <a ui-sref=\"tatami.home.profile.statuses({ username: suggestion.username })\">\n                        <small>@{{ suggestion.username }}</small>\n                    </a>\n                </h6>\n            </div>\n        </div>\n        <div style=\"opacity: 0.5; text-align:center;\">\n            Version: <pom>version</pom>, Build: <pom>build</pom>\n        </div>\n    </section>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/shared/sidebars/profile/ProfileSidebarController.js",
    "content": "ProfileSidebarModule.controller('ProfileSidebarController', ['$scope', 'TagService', 'user', 'tags',\n    function($scope, TagService, user, tags) {\n        $scope.user = user;\n        $scope.tags = tags;\n\n        $scope.followTag = function(tag, index) {\n            TagService.follow({ tag: tag.name }, { name: tag.name, followed: !tag.followed, trendingUp: tag.trendingUp }, \n                function(response) {\n                    $scope.tags[index].followed = response.followed;\n            });\n        }\n    }\n]);"
  },
  {
    "path": "web/src/main/webapp/app/shared/sidebars/profile/ProfileSidebarModule.js",
    "content": "var ProfileSidebarModule = angular.module('ProfileSidebarModule', []);"
  },
  {
    "path": "web/src/main/webapp/app/shared/sidebars/profile/ProfileSidebarView.html",
    "content": "<div>\n    <section class=\"hidden-phone profile\">\n        <div class=\"page-header\">\n            <h4 class=\"profile-card background-image-fffix\">\n                <div class=\"img img-rounded img-big pull-left\" ng-style=\"{ 'background-image': 'url(' + user.avatarURL + ')' }\"></div>\n            </h4>\n        </div>\n        <div class=\"well well-sm little-padding\">\n            <div>\n                <a class=\"h3\" ui-sref=\"tatami.home.profile.statuses({ username: user.username })\">\n                    <strong>{{ user.firstName + ' ' + user.lastName }}</strong>\n                </a>\n            </div>\n            <div>                \n                <a class=\"h5 text-muted\" ui-sref=\"tatami.home.profile.statuses({ username: user.username })\">\n                    @{{ user.username }}\n                </a>\n            </div>\n        </div>\n        <div class=\"panel panel-default\">\n            <div class=\"panel-heading\">\n                <span class=\"glyphicon glyphicon-user\"></span>\n                <span translate=\"tatami.home.profile.sidebar.information\"></span>\n            </div>\n            <div class=\"panel-body\">\n                <p>\n                    <strong translate=\"tatami.home.profile.sidebar.firstName\"></strong>:\n                    {{ user.firstName }}\n                </p>\n                <p>\n                    <strong translate=\"tatami.home.profile.sidebar.lastName\"></strong>:\n                    {{ user.lastName }}\n                </p>\n                <p>\n                    <strong translate=\"tatami.home.profile.sidebar.jobTitle\"></strong>:\n                    {{ user.jobTitle }}\n                </p>\n                <p>\n                    <strong translate=\"tatami.home.profile.sidebar.email\"></strong>:\n                    <a ng-href=\"mailto:{{ user.login }}\">{{ user.login }}</a>\n                </p>\n                <p>\n                    <strong translate=\"tatami.home.profile.sidebar.phoneNumber\"></strong>:\n                    {{ user.phoneNumber }}\n                </p>\n            </div>\n        </div>\n    </section>\n    <section class=\"hidden-phone tag-trends\">\n        <div class=\"panel panel-default\">\n            <div class=\"panel-heading\">\n                <span class=\"glyphicon glyphicon-fire\"></span>\n                <span translate=\"tatami.home.profile.sidebar.trends\"></span>\n            </div>\n            <div class=\"panel-body items\">\n                <div ng-repeat=\"tag in tags\">\n                    <span ng-click=\"followTag(tag, $index)\" ng-init=\"hover = false\" ng-mouseenter=\"hover = true\" ng-mouseleave=\"hover = false\" class=\"little-padding pointer pull-right label\" ng-class=\"{ 'label-danger': tag.followed && hover, 'label-info': tag.followed && !hover }\">\n                        <span class=\"glyphicon\" ng-class=\"tag.followed ? 'glyphicon-minus' : 'glyphicon-plus'\"></span>\n                    </span>\n                    <span class=\"glyphicon\" ng-class=\"tag.trendingUp ? 'glyphicon-arrow-up' : 'glyphicon-arrow-down'\"></span>\n                    <a ui-sref=\"tatami.home.home.tag({ tag: tag.name })\">#{{ tag.name }}</a>\n                </div>\n            </div>\n        </div>\n    </section>\n</div>"
  },
  {
    "path": "web/src/main/webapp/app/shared/topMenu/SearchView.html",
    "content": "<a>\n    <div class=\"category groups\" ng-if=\"match.model.groupId\">\n        <span class=\"glyphicon glyphicon-th-large\">\n            {{ match.model.name }}\n        </span>\n    </div>\n    <div class=\"category users\" ng-if=\"match.model.login\">\n        <span class=\"glyphicon glyphicon-user\">\n            @{{match.model.username}}\n        </span>\n    </div>\n    <div class=\"category tags\" ng-if=\"!match.model.groupId && match.model.name\">\n        <span class=\"glyphicon glyphicon-tags background-color:\">\n            #{{match.model.name}}\n        </span>\n    </div>\n</a>"
  },
  {
    "path": "web/src/main/webapp/app/shared/topMenu/TopMenuController.js",
    "content": "TopMenuModule.controller('TopMenuController', [\n    '$scope',\n    '$window',\n    '$http',\n    '$translate',\n    'amMoment',\n    'UserSession',\n    'SearchService',\n    function($scope, $window, $http, $translate, amMoment, UserSession, SearchService) {\n        $scope.current = {};\n        $scope.current.searchString = '';\n\n        $scope.$on('start-tour', function() {\n            $scope.tour.restart(true);\n        });\n\n        $scope.changeLanguage = function(key) {\n            $translate.use(key);\n            amMoment.changeLocale(key);\n        };\n\n        $scope.openPostModal = function() {\n            $scope.$state.go($scope.$state.current.name + '.post');\n        };\n\n        $scope.logout = function() {\n            $http.get('/tatami/logout')\n                .success(function() {\n                    UserSession.clearSession();\n                    $scope.$state.go('tatami.login.main');\n                    $scope.searchString = '';\n                });\n        };\n\n        // Method to redirect to blog based on language. \n        $scope.goToBlog = function() {\n            var lang = $translate.use();\n            // If it fails to detect the one being used, it will look for the proposed one.\n            // Useful in asynchronous scenarios.\n            if (lang !== 'fr' && lang !== 'en') {\n            lang = $translate.proposedLanguage();\n        }\n           switch(lang) {\n               case 'fr':\n                   window.open(\"http://blog.ippon.fr/\");\n                   break;\n               default:\n                   window.open('http://www.ipponusa.com/blog/');\n                   break;\n           }\n        };\n\n        $scope.getResults = function(searchString) {\n            return SearchService.get({ term: 'all', q: searchString }).$promise.then(function(result) {\n                if(angular.isDefined(result.groups[0])) {\n                    result.groups[0].firstGroup = true;\n                }\n                if(angular.isDefined(result.tags[0])) {\n                    result.tags[0].firstTag = true;\n                }\n                if(angular.isDefined(result.users[0])) {\n                    result.users[0].firstUser = true;\n                }\n\n                return result.groups.concat(result.users.concat(result.tags));\n            })\n        };\n\n        $scope.changeInput = function(param) {\n            $scope.searchString = param;\n        };\n\n        $scope.searchStatuses = function(e) {\n            // If the enter key is pressed\n            if(e.keyCode === 13) {\n                $scope.$state.go('tatami.home.search', { searchTerm: $scope.searchString });\n            }\n        };\n\n        $scope.goToPage = function($item) {\n            if($item.groupId) {\n                $scope.$state.go('tatami.home.home.group.statuses', { groupId: $item.groupId });\n            }\n            else if($item.login) {\n                $scope.$state.go('tatami.home.profile.statuses', { username: $item.username });\n            }\n            else if(!$item.groupId) {\n                $scope.$state.go('tatami.home.home.tag', { tag: $item.name })\n            }\n        };\n}]);"
  },
  {
    "path": "web/src/main/webapp/app/shared/topMenu/TopMenuModule.js",
    "content": "var TopMenuModule = angular.module('TopMenuModule', ['PostModule']);"
  },
  {
    "path": "web/src/main/webapp/app/shared/topMenu/TopMenuView.html",
    "content": "<div id=\"navbar\" class=\"navbar noRadius\">\n    <button type=\"button\" class=\"navbar-toggle collapsed\" data-toggle=\"collapse\" data-target=\".navbar-responsive-collapse\">\n        <span class=\"icon-bar\"></span>\n        <span class=\"icon-bar\"></span>\n        <span class=\"icon-bar\"></span>\n    </button>\n\n    <!-- Change ui-sref that goes to root state -->\n    <a class=\"navbar-brand\" ui-sref=\"tatami.home.home.timeline\">\n        <img title=\"{{ 'tatami.home.menu.logo' | translate }}\" src=\"/assets/img/company-logo.png\">\n        <span translate=\"tatami.home.menu.title\"></span>\n    </a>\n\n    <button ng-if=\"$state.includes('tatami.home')\" ng-click=\"openPostModal()\" type=\"button\" class=\"btn btn-primary navbar-toggle navbar-edit\">\n        <i class=\"close glyphicon glyphicon-pencil\"></i>\n    </button>\n\n    <div class=\"nav-collapse navbar-responsive-collapse collapse\">\n        <ul class=\"nav\">\n            <li>\n                <a ui-sref=\"tatami.home.home.timeline\">\n                    <span>\n                        <span class=\"glyphicon glyphicon-th-list\"></span>\n                        <span translate=\"tatami.home.timeline\" class=\"hidden-tablet\"></span>\n                    </span>\n                </a>\n            </li>\n            <li class=\"dropdown pointer\">\n                <a class=\"dropdown-toggle\" data-toggle=\"dropdown\">\n                <span>\n                    <span class=\"glyphicon glyphicon-info-sign\"></span>\n                    <span translate=\"tatami.home.menu.about.title\" class=\"hidden-tablet\"></span>\n                    <b class=\"caret\"></b>\n                </span>\n                </a>\n                <ul class=\"dropdown-menu closed\">\n                    <li>\n                        <a ui-sref=\"tatami.about.presentation\">\n                            <span class=\"glyphicon glyphicon-eye-open\"></span>\n                            <span translate=\"tatami.home.menu.about.presentation\"></span>\n                        </a>\n                    </li>\n                    <li>\n                        <a ui-sref=\"tatami.about.tos\">\n                            <span class=\"glyphicon glyphicon-briefcase\"></span>\n                            <span translate=\"tatami.home.menu.about.tos\"></span>\n                        </a>\n                    </li>\n                    <li class=\"dropdown-submenu\">\n                        <a>\n                            <span class=\"glyphicon glyphicon-flag\"></span>\n                            <span translate=\"tatami.home.menu.about.language\"></span>\n                        </a>\n                        <ul class=\"dropdown-menu\">\n                            <li>\n                                <a ng-click=\"changeLanguage('en')\" translate=\"tatami.home.menu.about.language.en\"></a>\n                            </li>\n                            <li>\n                                <a ng-click=\"changeLanguage('fr')\" translate=\"tatami.home.menu.about.language.fr\"></a>\n                            </li>\n                        </ul>\n                    </li>\n                    <li class=\"divider\"></li>\n                    <li>\n                        <a ui-sref=\"tatami.about.license\">\n                            <span class=\"glyphicon glyphicon-info-sign\"></span>\n                            <span translate=\"tatami.home.menu.about.license\"></span>\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"https://github.com/ippontech/tatami/issues\" target=\"_blank\">\n                            <span class=\"glyphicon glyphicon-inbox\"></span>\n                            <span translate=\"tatami.home.menu.about.github.issues\"></span>\n                        </a>\n                    </li>\n                    <li>\n                        <a href=\"https://github.com/ippontech/tatami\" target=\"_blank\">\n                            <span class=\"glyphicon glyphicon-wrench\"></span>\n                            <span translate=\"tatami.home.menu.about.github.fork\"></span>\n                        </a>\n                    </li>\n                    <li class=\"divider\"></li>\n\n                    <li>\n                        <a href=\"http://www.ippon.fr\" target=\"_blank\">\n                            <span class=\"glyphicon glyphicon-exclamation-sign\"></span>\n                            <span translate=\"tatami.home.menu.about.ippon.website\"></span>\n                        </a>\n                    </li>\n                    <li><a ng-click='goToBlog()'>\n                                <span class=\"glyphicon glyphicon-pencil\"></span>\n                                <span translate=\"tatami.home.menu.about.ippon.blog\"></span>\n                            </a>\n                    </li>\n                    <li>\n                        <a href=\"https://twitter.com/ippontech\" target=\"_blank\">\n                            <span class=\"glyphicon glyphicon-bullhorn\"></span>\n                            <span translate=\"tatami.home.menu.about.ippon.twitter\"></span>\n                        </a>\n                    </li>\n                </ul>\n            </li>\n        </ul>\n\n        <ul ng-if=\"$state.includes('tatami.account')\" class=\"nav pull-right\">\n            <li>\n                <a id=\"logout\" ng-click=\"logout()\">\n                    <span class=\"glyphicon glyphicon-off\"></span>\n                    <span translate=\"tatami.home.menu.account.logout\"></span>\n                </a>\n            </li>\n        </ul>\n\n        <div ng-if=\"$state.includes('tatami.home')\">\n            <ul class=\"nav pull-right\">\n                <li class=\"dropdown pointer\">\n                    <a class=\"dropdown-toggle\" data-toggle=\"dropdown\">\n                    <span>\n                        <span class=\"glyphicon glyphicon-user\"></span>\n                        <span translate=\"tatami.home.menu.account.title\" class=\"hidden-tablet\"></span>\n                        <b class=\"caret\"></b>\n                    </span>\n                    </a>\n                    <ul class=\"dropdown-menu\">\n                        <li>\n                            <a ui-sref=\"tatami.account.profile\">\n                                <span class=\"glyphicon glyphicon-user\"></span>\n                                <span translate=\"tatami.account.profile.title\"></span>\n                            </a>\n                        </li>\n                        <li>\n                            <a ui-sref=\"tatami.account.preferences\">\n                                <span class=\"glyphicon glyphicon-cog\"></span>\n                                <span translate=\"tatami.account.preferences.title\"></span>\n                            </a>\n                        </li>\n                        <li>\n                            <a ui-sref=\"tatami.account.password\">\n                                <span class=\"glyphicon glyphicon-lock\"></span>\n                                <span translate=\"tatami.account.password.title\"></span>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a ui-sref=\"tatami.account.files\">\n                                <span class=\"glyphicon glyphicon-file\"></span>\n                                <span translate=\"tatami.account.files.title\"></span>\n                            </a>\n                            <a ui-sref=\"tatami.account.users\">\n                                <span class=\"glyphicon glyphicon-globe\"></span>\n                                <span translate=\"tatami.account.users.title\"></span>\n                            </a>\n                            <a ui-sref=\"tatami.account.groups\">\n                                <span class=\"glyphicon glyphicon-th-large\"></span>\n                                <span translate=\"tatami.account.groups.title\"></span>\n                            </a>\n                            <a ui-sref=\"tatami.account.tags\">\n                                <span class=\"glyphicon glyphicon-tags\"></span>\n                                <span translate=\"tatami.account.tags.title\"></span>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a ui-sref=\"tatami.account.topPosters\">\n                                <span class=\"glyphicon glyphicon-signal\"></span>\n                                <span translate=\"tatami.account.topPosters.title\"></span>\n                            </a>\n                            <a ui-sref=\"tatami.home.home.company\">\n                                <span class=\"glyphicon glyphicon-briefcase\"></span>\n                                <span translate=\"tatami.home.menu.account.companyTimeline\"></span>\n                            </a>\n                        </li>\n                        <li class=\"divider\"></li>\n                        <li>\n                            <a ng-click=\"logout()\">\n                                <span class=\"glyphicon glyphicon-off\"></span>\n                                <span translate=\"tatami.home.menu.account.logout\"></span>\n                            </a>\n                        </li>\n                    </ul>\n                </li>\n                <li class=\"hidden-phone\">\n                    <button tour-step\n                            order=\"2\"\n                            title=\"{{ 'tatami.welcome.post.title' | translate }}\"\n                            content=\"\n                            {{ 'tatami.welcome.post.line1' | translate }}\n                            <ul>\n                                <li>{{ 'tatami.welcome.post.bulletPoint1' | translate }}</li>\n                                <li>{{ 'tatami.welcome.post.bulletPoint2' | translate }}</li>\n                                <li>{{ 'tatami.welcome.post.bulletPoint3' | translate }}</li>\n                            </ul>\n                            <br>\"\n                            placement=\"left\"\n                            skip=\"false\"\n                            on-end=\"onTourEnd(tour)\"\n                            class=\"btn btn-primary navbar-form\"\n                            ng-click=\"openPostModal()\">\n                        <i class=\"glyphicon glyphicon-pencil\"></i>\n                        <span translate=\"tatami.home.post.button\" class=\"visible-desktop\"></span>\n                    </button>\n                </li>\n            </ul>\n            <ul class=\"nav pull-right\">\n                <li tour-step\n                    order=\"0\"\n                    title=\"{{ 'tatami.welcome.help.title' | translate }}\"\n                    content=\"{{ 'tatami.welcome.help.line1' | translate }}\n                    <br>\n                    <p>{{ 'tatami.welcome.help.line2' | translate }}</p>\n                    <br>\"\n                    navigation=\"\"\n                    placement=\"bottom\"\n                    ng-click=\"tour.restart(true)\"\n                    skip=\"false\"\n                    on-end=\"onTourEnd(tour)\">\n                    <a id=\"help-tour\">\n                        <span>\n                            <span class=\"glyphicon glyphicon-question-sign\"></span>\n                            <span translate=\"tatami.home.menu.help\" class=\"hidden-tablet\"></span>\n                        </span>\n                    </a>\n                </li>\n            </ul>\n            <div name=\"search\" class=\"navbar-form pull-right col-span-4\">\n                <!--\n                <input name=\"search\" ng-model=\"searchBar\" mentio mentio-items=\"results\" mentio-search=\"getResults(term)\" type=\"text\" class=\"col-span-12\" autocomplete=\"off\" placeholder=\"{{ 'tatami.home.menu.search' | translate }}\">\n                -->\n\n                <input name=\"searchBar\" ng-keypress=\"searchStatuses($event)\" ng-model=\"searchString\" ng-change=\"changeInput(searchString)\" typeahead-focus-first=\"false\" typeahead=\"(val.name === undefined ? '@' + val.username : val.groupId === undefined ? '#' + val.name : val.name) for val in getResults($viewValue)\" typeahead-on-select=\"goToPage($item, $model, $label)\" typeahead-template-url=\"/app/shared/topMenu/SearchView.html\" type=\"text\" class=\"col-span-12\" autocomplete=\"off\" placeholder=\"{{ 'tatami.home.menu.search' | translate }}\">\n            </div>\n        </div>\n    </div>\n</div>\n"
  },
  {
    "path": "web/src/main/webapp/app/shared/topMenu/post/DropdownTagTemplate.html",
    "content": "<ul class=\"list-group user-search\">\n    <li mentio-menu-item=\"tag\" ng-repeat=\"tag in items\" class=\"list-group-item\">\n        <span class=\"text-primary\" ng-bind-html=\"tag.name | mentioHighlight:typedTerm:'menu-highlighted' | unsafe\"></span>\n    </li>\n</ul>"
  },
  {
    "path": "web/src/main/webapp/app/shared/topMenu/post/DropdownUserTemplate.html",
    "content": "<ul class=\"list-group user-search\">\n    <li mentio-menu-item=\"person\" ng-repeat=\"person in items\" class=\"list-group-item\">\n        <span class=\"text-primary\" ng-bind-html=\"person.username | mentioHighlight:typedTerm:'menu-highlighted' | unsafe\"></span>\n    </li>\n</ul>"
  },
  {
    "path": "web/src/main/webapp/app/shared/topMenu/post/PostController.js",
    "content": "/**\n * The purpose of this controller is to collect and maintain data in the status\n * creation window.\n */\n\nPostModule.controller('PostController', [\n    '$scope',\n    '$modalInstance',\n    '$translate',\n    '$upload',\n    'StatusService',\n    'GeolocalisationService',\n    'groups',\n    'curStatus',\n    'SearchService',\n    '$stateParams',\n    function($scope, $modalInstance, $translate, $upload, StatusService, GeolocalisationService, groups, curStatus, SearchService, $stateParams) {\n        $scope.isOneDayOrMore = function(date) {\n            return moment().diff(moment(date), 'days', true) >= 1;\n        };\n\n        $scope.getLanguageKey = function() {\n            return $translate.use();\n        };\n\n        $scope.determineTitle = function() {\n            if(angular.isDefined(curStatus)) {\n                return 'tatami.home.post.replyTo'\n            }\n            else {\n                return 'tatami.home.post.update'\n            }\n        };\n\n        $scope.notArchived = function(groups) {\n            var filteredGroups = [];\n            for(var group in groups) {\n                if(!group.archivedGroup) {\n                    filteredGroups.push(group);\n                }\n            }\n            return filteredGroups;\n        };\n\n        $scope.current = {  // This is the current instance of the status window\n            preview: false, // Determines if the status is being previewed by the user\n            geoLoc: false,  // Determine if the geolocalization checkbox is checked\n            groups: groups, // The groups the user belongs to\n            reply: false,   // Determine if this status is a reply to another user\n            uploadDone: true,// If the file upload is done, we should not show the progess bar\n            uploadProgress: 0,// The progress of the file currently being uploaded\n            upload: [],\n            contentEmpty: true,\n            files: [],\n            attachments: []\n        };\n\n        $scope.status = {   // This is the current user status information\n            content: \"\",    // The content contained in this status\n            groupId: \"\",    // The groupId that this status is being broadcast to\n            replyTo: \"\",     // The user we are replying to\n            attachmentIds: [], // An array of all the attachments contained in the status\n            geoLocalization: \"\", // The geographical location of the user when posting the status\n            statusPrivate: false // Determines whether the status is private\n        };\n\n        $scope.charCount = 750;\n\n        $scope.uploadStatus = {\n            isUploading: false,\n            progress: 0\n        };\n\n        /**\n         * Watches the current.files ng-model and handles uploads\n         */\n        $scope.$watch('current.files', function() {\n            if($scope.current.files !== null) {\n                for(var i = 0; i < $scope.current.files.length; ++i) {\n                    var file = $scope.current.files[i];\n                    $scope.uploadStatus.isUploading = true;\n                    $scope.upload = $upload.upload({\n                        url: '/tatami/rest/fileupload',\n                        file: file,\n                        fileFormDataName: 'uploadFile'\n                    }).progress(function(evt) {\n                        $scope.uploadStatus.progress = parseInt(100.0 * evt.loaded / evt.total);\n                    }).success(function(data) {\n                        $scope.current.attachments.push(data[0]);\n                        $scope.uploadStatus.isUploading = false;\n                        $scope.uploadStatus.progress = 0;\n                        $scope.status.attachmentIds.push(data[0].attachmentId);\n                    }).error(function() {\n                        $scope.uploadStatus.isUploading = false;\n                        $scope.uploadStatus.progress = 0;\n                    })\n                }\n            }\n        });\n        $scope.fileSize = function(file) {\n            if(file.size / 1000 < 1000) {\n                return parseInt(file.size / 1000) + \"K\";\n\n            }\n            else{\n                return parseInt(file.size / 1000000) + \"M\";\n            }\n        };\n        /**\n         * In order to set reply to a status, we must be able to set current status\n         * after an asynchronous get request.\n         */\n        $modalInstance.setCurrentStatus = function(status) {\n            var defined = angular.isDefined(status);\n            $scope.current.reply = defined;\n            $scope.currentStatus = defined ? status : {};\n            if(defined) {\n                $scope.status.content = '@' + $scope.currentStatus.username + ' ';\n                $scope.status.replyTo = status.statusId;\n            }\n            else {\n                $scope.currentStatus.avatarURL = '/assets/img/default_image_profile.png';\n            }\n        };\n\n        $modalInstance.setCurrentStatus(curStatus);\n\n        $scope.closeModal = function() {\n            $modalInstance.dismiss();\n            $scope.reset();\n            $scope.$state.go('^');\n        };\n\n        //Handles closing the modal via escape and clicking outside the modal\n        $modalInstance.result.finally(function() {\n            $scope.$state.go('^');\n        });\n\n\n        /**\n         *\n         * @param param String argument representing the most up to date status content\n         *\n         * Simple function to change the current status content\n         */\n        $scope.statusChange = function(param) {\n            $scope.status.content = param;\n        };\n\n        $scope.fetchUsers = function(term) {\n            return SearchService.query({ 'term': 'users', q: term }, function(result) {\n                $scope.users = result;\n            })\n        };\n\n        $scope.selectUser = function(item) {\n            return '@' + item.username;\n        };\n\n        $scope.fetchTags = function(term) {\n            if(term.length > 0) {\n                return SearchService.query({ 'term': 'tags', q: term }, function(result) {\n                    $scope.tags = result;\n                });\n            }\n\n        };\n\n        $scope.selectTag = function(item) {\n            return '#' + item.name;\n        };\n\n\n        /**\n         * Resets any previously set status data\n         */\n        $scope.reset = function() {\n            $scope.current.preview = false;\n            $scope.current.geoLoc = false;\n            $scope.current.uploadDone = true;\n            $scope.current.uploadProgress = 0;\n\n            $scope.status.content = \"\";\n            $scope.status.groupId = \"\";\n            $scope.status.attachmentIds = [];\n            $scope.status.geoLocalization = \"\";\n            $scope.status.replyTo = \"\";\n            $scope.status.statusPrivate = false;\n        };\n\n\n        /**\n         * Create a new status based on the current data in the controller.\n         * Uses the StatusService for this purpose, and we do nothing if no\n         * content has been provided by the user.\n         */\n        var isAlreadyPosting=false;\n        $scope.newStatus = function() {\n            if($scope.status.content.trim().length !== 0 && !isAlreadyPosting) {\n                isAlreadyPosting=true;\n                $scope.status.content = $scope.status.content.trim();\n                StatusService.save($scope.status, function() {\n                    $modalInstance.close();\n                    $modalInstance.result.then(function() {\n                        $scope.$state.transitionTo($scope.$state.current.name.split('.post')[0], $stateParams, { reload: true });\n                    });\n                    $scope.reset();\n                })\n            }\n        };\n\n        /** Geolocalization based functions **/\n\n        /**\n         * Determine whether the user means to use location data on the current status\n         */\n        $scope.updateLocation = function() {\n            if($scope.current.geoLoc) {\n                GeolocalisationService.getGeolocalisation($scope.getLocationString);\n            } else {\n                $scope.status.geoLocalization = \"\";\n            }\n        };\n\n        /**\n         * Callback function used in getGeolocalisation. This function sets the status geolocation,\n         * and brings up a map.\n         */\n        $scope.getLocationString = function(position) {\n            $scope.status.geoLocalization = position.coords.latitude + \", \" + position.coords.longitude;\n            $scope.initMap();\n        };\n\n        /**\n         * Create a map displaying the users current location in the status\n         */\n        $scope.initMap = function() {\n            if ($scope.current.geoLoc) {\n                var geoLocalization = $scope.status.geoLocalization;\n                var latitude = geoLocalization.split(',')[0].trim();\n                var longitude = geoLocalization.split(',')[1].trim();\n\n                var map = new OpenLayers.Map(\"simpleMap\");\n                var fromProjection = new OpenLayers.Projection(\"EPSG:4326\");// Transform from WGS 1984\n                var toProjection = new OpenLayers.Projection(\"EPSG:900913\");// to Spherical Mercator Projection\n                var lonLat = new OpenLayers.LonLat(parseFloat(longitude), parseFloat(latitude)).transform(fromProjection, toProjection);\n                var mapnik = new OpenLayers.Layer.OSM();\n                var position = lonLat;\n                var zoom = 12;\n\n                map.addLayer(mapnik);\n                var markers = new OpenLayers.Layer.Markers(\"Markers\");\n                map.addLayer(markers);\n                markers.addMarker(new OpenLayers.Marker(lonLat));\n                map.setCenter(position, zoom);\n            }\n        }\n    }\n]);"
  },
  {
    "path": "web/src/main/webapp/app/shared/topMenu/post/PostModule.js",
    "content": "var PostModule = angular.module('PostModule', ['angularFileUpload', 'ui.router']);\n\nPostModule.config(['$stateProvider', function ($stateProvider) {\n    var onEnterArray = ['$stateParams', '$modal', function ($stateParams, $modal) {\n        $modal.open({\n            templateUrl: '/app/shared/topMenu/post/PostView.min.html',\n            controller: 'PostController',\n            backdrop: 'static',\n            keyboard: true,\n            resolve: {\n                curStatus: ['StatusService', function (StatusService) {\n                    if ($stateParams.statusId !== null) {\n                        return StatusService.get({statusId: $stateParams.statusId}).$promise;\n                    }\n                }],\n                groups: ['GroupService', function (GroupService) {\n                    return GroupService.query().$promise;\n                }]\n            }\n        });\n    }];\n\n    var onEnterArrayStatusView = ['$stateParams', '$modal', function ($stateParams, $modal) {\n        $modal.open({\n            templateUrl: '/app/shared/topMenu/post/PostView.min.html',\n            controller: 'PostController',\n            backdrop: 'static',\n            keyboard: true,\n            resolve: {\n                curStatus: ['StatusService', function (StatusService) {\n                    if ($stateParams.statusIdReply !== null) {\n                        return StatusService.get({statusId: $stateParams.statusIdReply}).$promise;\n                    }\n                }],\n                groups: ['GroupService', function (GroupService) {\n                    return GroupService.query().$promise;\n                }]\n            }\n        });\n    }];\n\n    $stateProvider\n        .state('tatami.home.status.post', {\n            url: '',\n            params: {\n                'statusIdReply': null\n            },\n            onEnter: onEnterArrayStatusView\n        })\n        .state('tatami.home.search.post', {\n            url: '',\n            params: {\n                'statusId': null\n            },\n            onEnter: onEnterArray\n        })\n        .state('tatami.home.home.timeline.post', {\n            url: '',\n            params: {\n                'statusId': null\n            },\n            onEnter: onEnterArray\n        })\n        .state('tatami.home.home.mentions.post', {\n            url: '',\n            params: {\n                'statusId': null\n            },\n            onEnter: onEnterArray\n        })\n        .state('tatami.home.home.favorites.post', {\n            url: '',\n            params: {\n                'statusId': null\n            },\n            onEnter: onEnterArray\n        })\n        .state('tatami.home.home.company.post', {\n            url: '',\n            params: {\n                'statusId': null\n            },\n            onEnter: onEnterArray\n        })\n        .state('tatami.home.home.tag.post', {\n            url: '',\n            params: {\n                'statusId': null\n            },\n            onEnter: onEnterArray\n        })\n        .state('tatami.home.home.group.statuses.post', {\n            url: '',\n            params: {\n                'statusId': null\n            },\n            onEnter: onEnterArray\n        })\n        .state('tatami.home.home.group.members.post', {\n            url: '',\n            params: {\n                'statusId': null\n            },\n            onEnter: onEnterArray\n        })\n        .state('tatami.home.profile.statuses.post', {\n            url: '',\n            params: {\n                'statusId': null\n            },\n            onEnter: onEnterArray\n        })\n        .state('tatami.home.profile.following.post', {\n            url: '',\n            params: {\n                'statusId': null\n            },\n            onEnter: onEnterArray\n        })\n        .state('tatami.home.profile.followers.post', {\n            url: '',\n            params: {\n                'statusId': null\n            },\n            onEnter: onEnterArray\n        });\n}\n]);\n"
  },
  {
    "path": "web/src/main/webapp/app/shared/topMenu/post/PostView.html",
    "content": "<div>\n    <div class=\"modal-header\">\n        <button type=\"button\" class=\"close\" data-dismiss=\"modal\" aria-hidden=\"true\" ng-click=\"closeModal()\"><span class=\"glyphicon glyphicon-remove\"></span></button>\n        <h4 class=\"modal-title\">{{ determineTitle() | translate }}</h4>\n    </div>\n    <div class=\"modal-body\">\n        <a ng-click=\"current.preview = !current.preview\" class=\"edit-tatam-float-right\">\n            <i ng-if=\"current.preview\" class=\"glyphicon glyphicon-edit close\" title=\"{{ 'tatami.home.post.edit' | translate }}\"></i>\n            <i ng-if=\"!current.preview\" class=\"glyphicon glyphicon-eye-open close\" title=\"{{ 'tatami.home.post.preview' | translate }}\"></i>\n        </a>\n        <fieldset ng-if=\"!current.preview\" class=\"edit-tatam row-fluid\">\n\n            <textarea mentio\n                      mentio-typed-text=\"result\"\n                      mentio-require-leading-space=\"true\"\n                      mentio-id=\"'postContent'\"\n                      mentio-items=\"users\"\n                      mentio-search=\"fetchUsers(term)\"\n                      mentio-select=\"selectUser(item)\"\n                      mentio-template-url=\"/app/shared/topMenu/post/DropdownUserTemplate.html\"\n                      ng-trim=\"false\"\n                      popover=\"{{ 'tatami.home.post.content.mandatory' | translate }}\"\n                      popover-placement=\"bottom\"\n                      popover-trigger=\"current.contentEmpty\"\n                      ng-model=\"status.content\"\n                      ng-change=\"statusChange(status.content)\"\n                      placeholder=\"{{ current.reply | placeholderFilter }}\"\n                      maxlength=\"750\"\n                      rows=\"5\"\n                      required=\"required\">\n            </textarea>\n\n            <mentio-menu mentio-for=\"'postContent'\"\n                         mentio-trigger-char=\"'#'\"\n                         mentio-template-url=\"/app/shared/topMenu/post/DropdownTagTemplate.html\"\n                         mentio-search=\"fetchTags(term)\"\n                         mentio-select=\"selectTag(item)\"\n                         mentio-items=\"tags\">\n            </mentio-menu>\n            <div>\n                {{ 'tatami.home.post.characters.left' | translate }}\n                <span class=\"countstatus badge\">{{ charCount - status.content.length }}</span>\n                <a class=\"pull-right\" target=\"_blank\" href=\"https://help.github.com/articles/markdown-basics/\" translate=\"tatami.home.post.markdown\"></a>\n            </div>\n        </fieldset>\n        <fieldset ng-if=\"current.preview\" class=\"preview-tatam row-fluid\">\n            <div class=\"well well-small markdown\" ng-bind-html=\"status.content | emoticon | markdown\"></div>\n        </fieldset>\n        <fieldset ng-show=\"current.reply\" class=\"reply row-fluid\">\n            <legend translate=\"tatami.home.post.reply\">\n            </legend>\n            <!-- Start of reply section -->\n            <div ng-show=\"current.reply\" class=\"tatam pointer discussion tatam-border-lr tatam-hover\" style=\"display: block;\">\n                <div id=\"current\" ng-mouseenter=\"showButtonRow = true\" ng-mouseleave=\"showButtonRow = false\" ng-class=\"{ 'favorite': currentStatus.favorite, 'share': currentStatus.shareByMe, 'both': currentStatus.favorite && currentStatus.shareByMe }\">\n                    <div class=\"pull-left background-image-fffix statusitem-img\">\n                        <a ui-sref=\"tatami.home.profile.statuses({ username: currentStatus.username })\">\n                            <div class=\"img img-rounded img-medium\" ng-style=\"{ 'background-image': 'url(' + currentStatus.avatarURL + ')' }\"></div>\n                        </a>\n                    </div>\n                    <div class=\"status-content-container\">\n                        <h5 class=\"statusitem-name\">\n                            <a ui-sref=\"tatami.home.profile.statuses({ username: currentStatus.username })\">\n                                <strong>{{ currentStatus.firstName + ' ' + currentStatus.lastName }}</strong>\n                                <small>@{{ currentStatus.username }}</small>\n                            </a>\n                            <small> · </small>\n                            <!-- Replace hover title with hover bubble -->\n                            <a ui-sref=\"tatami.home.status({ status: currentStatus.statusId })\">\n                                <!--English-->\n                                <small ng-if=\"!isOneDayOrMore(currentStatus.statusDate) && getLanguageKey() == 'en'\" title=\"{{ currentStatus.statusDate | amDateFormat:'h:mm A - D MMM YYYY' }}\" am-time-ago=\"currentStatus.statusDate\"></small>\n                                <small ng-if=\"isOneDayOrMore(currentStatus.statusDate) && getLanguageKey() == 'en'\" title=\"{{ currentStatus.statusDate | amDateFormat:'h:mm A - D MMM YYYY' }}\">{{ currentStatus.statusDate | amDateFormat:'MMM D' }}</small>\n                                <!--French-->\n                                <small ng-if=\"!isOneDayOrMore(currentStatus.statusDate) && getLanguageKey() == 'fr'\" title=\"{{ currentStatus.statusDate | amDateFormat:'HH:mm - D MMMM YYYY' }}\" am-time-ago=\"currentStatus.statusDate\"></small>\n                                <small ng-if=\"isOneDayOrMore(currentStatus.statusDate) && getLanguageKey() == 'fr'\" title=\"{{ currentStatus.statusDate | amDateFormat:'HH:mm - D MMMM YYYY' }}\">{{ currentStatus.statusDate | amDateFormat:'D MMMM' }}</small>\n                            </a>\n                            <a ng-if=\"currentStatus.locationURL\" class=\"glyphicon glyphicon-map-marker\" ng-href=\"{{ currentStatus.locationURL }}\" target=\"_blank\"></a>\n                        </h5>\n                        \n                        <div class=\"markdown\" ng-bind-html=\"currentStatus.content | emoticon | markdown\"></div>\n\n                        <small ng-if=\"currentStatus.groupId\">\n                            <a class=\"label\" ng-class=\"{ 'label-info': !status.publicGroup, 'label-warning': status.publicGroup }\" ui-sref=\"tatami.home.home.group.statuses({ groupId: currentStatus.groupId })\">\n                            {{ currentStatus.groupName }}\n                            </a>\n                            <br>\n                        </small>\n\n                        <small ng-if=\"currentStatus.statusPrivate\">\n                            <span class=\"glyphicon glyphicon-lock\"></span>\n                            <span translate=\"tatami.home.status.private\"></span>\n                            <br>\n                        </small>\n\n                        <small ng-if=\"currentStatus.replyTo\">\n                            <span class=\"glyphicon glyphicon-share-alt\"></span>\n                            <span translate=\"tatami.home.status.replyTo\"></span>\n                            <a ui-sref=\"tatami.home.status({ status: currentStatus.replyTo })\">@{{ currentStatus.replyToUsername }}</a>\n                            <br>\n                        </small>\n\n                        <small>\n                            <div class=\"attachments\">\n                                <div>\n                                    <span ng-repeat=\"attachment in currentStatus.attachments\">\n                                    <a href=\"/tatami/file/{{ attachment.attachmentId }}/{{ attachment.filename }}\" class=\"btn-link status-action\" target=\"_blank\">\n                                    <i class=\"glyphicon glyphicon-file\"></i> {{ attachment.filename }}\n                                    </a>\n                                    </span>\n                                </div>\n                            </div>\n                        </small>\n                    </div>\n                </div>\n            </div>\n        </fieldset>\n        <fieldset class=\"row-fluid\">\n            <legend translate=\"tatami.home.post.options\"></legend>\n            <div ng-show=\"!current.reply\">\n                <label>\n                    <input type=\"checkbox\" ng-model=\"current.geoLoc\" ng-change=\"updateLocation()\">\n                    <span class=\"glyphicon glyphicon-map-marker\" translate=\"tatami.home.post.shareLocation\"></span>\n                </label>\n                <div ng-if=\"current.geoLoc\">\n                    <!-- Was width:250px, changed it to 500 -->\n                    <div id=\"simpleMap\" style=\"height:250px; width:500px\"></div>\n                    <div class=\"geolocMap\">\n                    </div>\n                </div>\n            </div>\n            <div ng-show=\"!current.reply && current.groups.length > 0\">\n                <label class=\"control-label\" translate=\"tatami.home.post.group\"></label>\n\n                <select ng-model=\"status.groupId\" ng-options=\"group.groupId as group.name for group in current.groups | filter: { archivedGroup: false }\">\n                    <option></option>\n                </select>\n            </div>\n            <!--\n            <div class=\"controls groups\">\n                <div id=\"GeolocImpossible\"></div> <p></p>\n                <div data-toggle=\"collapse\" >\n                    <div class=\"controls geoLocalization\" >\n                        <label class=\"checkbox\">\n                            <input type=\"checkbox\"> <span class=\"glyphicon glyphicon-map-marker\"></span> <fmt:message key=\"tatami.post.geoLocalization\"/>\n                        </label>\n                    </div>\n                    <div id=\"geolocalisationCheckbox\" ng-if=\"current.geoLoc\">\n                        <div id=\"basicMap\" style=\"height:250px; width:250px\"></div>\n                        <div class=\"geolocMap\">\n                        </div>\n                    </div>\n                </div>\n                <label class=\"control-label\"><fmt:message key=\"tatami.group.name\"/></label>\n                <select name=\"groupId\">\n                    <option value=\"\"></option>\n                    <option value=\"<@= groups[index].groupId @>\">\n                    </option>\n                </select>\n            </div>-->\n            <div class=\"controls status-files\" ng-file-drop ng-file-select ng-model=\"current.files\" ng-multiple=\"true\">\n                <label translate=\"tatami.home.post.files\">\n\n                </label>\n                <div ng-show=\"uploadStatus.isUploading\" class=\"attachmentBar progress progress-striped active\">\n                    <div class=\"bar progress-bar progress-bar-info\" style=\"width: {{uploadStatus.progress}}%;\"></div>\n                </div>\n                <div class=\"dropzone well\" file-dropzone translate=\"tatami.home.post.drop.file\">\n\n                </div>\n\n                <div ng-show=\"current.attachments.length != 0\" ng-repeat=\"attachment in current.attachments\">\n                    <p>\n                        {{ attachment.name }} ({{ fileSize(attachment) }})\n                    </p>\n                </div>\n                <!--\n                <input style=\"display: none;\" class=\"updateStatusFileupload\" type=\"file\" name=\"uploadFile\" data-url=\"/tatami/rest/fileupload\" multiple/>\n                -->\n                <!--\n                <div class=\"fileUploadResults wrap\">\n\n                </div>\n                -->\n            </div>\n            <!--\n            <label class=\"control-label\"></label>\n            <div class=\"controlsIE\">\n                <span class=\"hidden-label choose-label\"><fmt:message key=\"tatami.user.upload.choose\" /></span>\n                <p><fmt:message key=\"tatami.user.upload.buttonIE-ok\" /></p>\n                <input id=\"tatamFile\" type=\"file\" name=\"uploadFile\" data-url=\"/tatami/rest/fileuploadIE\" class=\"filestyle\" data-classButton=\"btn btn-primary\" data-input=\"false\" data-buttonText=\"\" data-icon=\"false\"/>\n                <span class=\"glyphicon glyphicon-search ok-ko\"></span>\n                <div class=\"fileUploadResults wrap\">\n                    <span class=\"upload-ko\">\n                        <fmt:message key=\"tatami.user.upload.buttonIE-ko\" />\n                    </span>\n                </div>\n                -->\n            <div ng-show=\"!current.reply\" class=\"controls status-private\">\n                <label class=\"checkbox\">\n                    <input ng-model=\"status.statusPrivate\" id=\"statusPrivate\" name=\"statusPrivate\" type=\"checkbox\" value=\"true\">\n                    <span class=\"glyphicon glyphicon-lock\" translate=\"tatami.home.status.private\"></span>\n                </label>\n            </div>\n        </fieldset>\n    </div>\n    <div class=\"modal-footer\">\n        <a class=\"btn\" aria-hidden=\"true\" ng-click=\"closeModal()\" translate=\"tatami.form.cancel\"></a>\n        <span class=\"hidden-label submit-label\" translate=\"tatami.home.post.button\"></span>\n        <span class=\"hidden-label tatam-mandatory\" translate=\"tatami.home.post.mandatory\"></span>\n        <input ng-click=\"newStatus()\" type=\"submit\" class=\"btn btn-primary submit\" value=\"{{ 'tatami.home.post.button' | translate }}\">\n    </div>\n</div>"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular/.bower.json",
    "content": "{\n  \"name\": \"angular\",\n  \"version\": \"1.3.15\",\n  \"main\": \"./angular.js\",\n  \"ignore\": [],\n  \"dependencies\": {},\n  \"homepage\": \"https://github.com/angular/bower-angular\",\n  \"_release\": \"1.3.15\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"v1.3.15\",\n    \"commit\": \"ba7abcfa409ba852146e6ba206693cf7bac3e359\"\n  },\n  \"_source\": \"git://github.com/angular/bower-angular.git\",\n  \"_target\": \"1.3.15\",\n  \"_originalSource\": \"angular\"\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular/README.md",
    "content": "# packaged angular\n\nThis repo is for distribution on `npm` and `bower`. The source for this module is in the\n[main AngularJS repo](https://github.com/angular/angular.js).\nPlease file issues and pull requests against that repo.\n\n## Install\n\nYou can install this package either with `npm` or with `bower`.\n\n### npm\n\n```shell\nnpm install angular\n```\n\nThen add a `<script>` to your `index.html`:\n\n```html\n<script src=\"/node_modules/angular/angular.js\"></script>\n```\n\nOr `require('angular')` from your code.\n\n### bower\n\n```shell\nbower install angular\n```\n\nThen add a `<script>` to your `index.html`:\n\n```html\n<script src=\"/bower_components/angular/angular.js\"></script>\n```\n\n## Documentation\n\nDocumentation is available on the\n[AngularJS docs site](http://docs.angularjs.org/).\n\n## License\n\nThe MIT License\n\nCopyright (c) 2010-2015 Google, Inc. http://angularjs.org\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular/angular-csp.css",
    "content": "/* Include this file in your html if you are using the CSP mode. */\n\n@charset \"UTF-8\";\n\n[ng\\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak],\n.ng-cloak, .x-ng-cloak,\n.ng-hide:not(.ng-hide-animate) {\n  display: none !important;\n}\n\nng\\:form {\n  display: block;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular/bower.json",
    "content": "{\n  \"name\": \"angular\",\n  \"version\": \"1.3.15\",\n  \"main\": \"./angular.js\",\n  \"ignore\": [],\n  \"dependencies\": {\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular/index.js",
    "content": "require('./angular');\nmodule.exports = angular;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular/package.json",
    "content": "{\n  \"name\": \"angular\",\n  \"version\": \"1.3.15\",\n  \"description\": \"HTML enhanced for web apps\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/angular/angular.js.git\"\n  },\n  \"keywords\": [\n    \"angular\",\n    \"framework\",\n    \"browser\",\n    \"client-side\"\n  ],\n  \"author\": \"Angular Core Team <angular-core+npm@google.com>\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/angular/angular.js/issues\"\n  },\n  \"homepage\": \"http://angularjs.org\"\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-animate/.bower.json",
    "content": "{\n  \"name\": \"angular-animate\",\n  \"version\": \"1.3.15\",\n  \"main\": \"./angular-animate.js\",\n  \"ignore\": [],\n  \"dependencies\": {\n    \"angular\": \"1.3.15\"\n  },\n  \"homepage\": \"https://github.com/angular/bower-angular-animate\",\n  \"_release\": \"1.3.15\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"v1.3.15\",\n    \"commit\": \"30fb369974560dbeb8a5311861c124e094944dab\"\n  },\n  \"_source\": \"git://github.com/angular/bower-angular-animate.git\",\n  \"_target\": \"~1.3.15\",\n  \"_originalSource\": \"angular-animate\",\n  \"_direct\": true\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-animate/README.md",
    "content": "# packaged angular-animate\n\nThis repo is for distribution on `npm` and `bower`. The source for this module is in the\n[main AngularJS repo](https://github.com/angular/angular.js/tree/master/src/ngAnimate).\nPlease file issues and pull requests against that repo.\n\n## Install\n\nYou can install this package either with `npm` or with `bower`.\n\n### npm\n\n```shell\nnpm install angular-animate\n```\n\nThen add `ngAnimate` as a dependency for your app:\n\n```javascript\nangular.module('myApp', [require('angular-animate')]);\n```\n\n### bower\n\n```shell\nbower install angular-animate\n```\n\nThen add a `<script>` to your `index.html`:\n\n```html\n<script src=\"/bower_components/angular-animate/angular-animate.js\"></script>\n```\n\nThen add `ngAnimate` as a dependency for your app:\n\n```javascript\nangular.module('myApp', ['ngAnimate']);\n```\n\n## Documentation\n\nDocumentation is available on the\n[AngularJS docs site](http://docs.angularjs.org/api/ngAnimate).\n\n## License\n\nThe MIT License\n\nCopyright (c) 2010-2015 Google, Inc. http://angularjs.org\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-animate/bower.json",
    "content": "{\n  \"name\": \"angular-animate\",\n  \"version\": \"1.3.15\",\n  \"main\": \"./angular-animate.js\",\n  \"ignore\": [],\n  \"dependencies\": {\n    \"angular\": \"1.3.15\"\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-animate/index.js",
    "content": "require('./angular-animate');\nmodule.exports = 'ngAnimate';\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-animate/package.json",
    "content": "{\n  \"name\": \"angular-animate\",\n  \"version\": \"1.3.15\",\n  \"description\": \"AngularJS module for animations\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/angular/angular.js.git\"\n  },\n  \"keywords\": [\n    \"angular\",\n    \"framework\",\n    \"browser\",\n    \"animation\",\n    \"client-side\"\n  ],\n  \"author\": \"Angular Core Team <angular-core+npm@google.com>\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/angular/angular.js/issues\"\n  },\n  \"homepage\": \"http://angularjs.org\"\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-bootstrap/.bower.json",
    "content": "{\n  \"author\": {\n    \"name\": \"https://github.com/angular-ui/bootstrap/graphs/contributors\"\n  },\n  \"name\": \"angular-bootstrap\",\n  \"keywords\": [\n    \"angular\",\n    \"angular-ui\",\n    \"bootstrap\"\n  ],\n  \"license\": \"MIT\",\n  \"ignore\": [],\n  \"description\": \"Native AngularJS (Angular) directives for Bootstrap.\",\n  \"version\": \"0.12.1\",\n  \"main\": [\n    \"./ui-bootstrap-tpls.js\"\n  ],\n  \"dependencies\": {\n    \"angular\": \">=1 <1.3.0\"\n  },\n  \"homepage\": \"https://github.com/angular-ui/bootstrap-bower\",\n  \"_release\": \"0.12.1\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"0.12.1\",\n    \"commit\": \"ab14fbaaf3d592f8e76018f0666c5af6f68ebaa3\"\n  },\n  \"_source\": \"git://github.com/angular-ui/bootstrap-bower.git\",\n  \"_target\": \"~0.12.1\",\n  \"_originalSource\": \"angular-bootstrap\",\n  \"_direct\": true\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-bootstrap/bower.json",
    "content": "{\n    \"author\": {\n        \"name\": \"https://github.com/angular-ui/bootstrap/graphs/contributors\"\n    },\n    \"name\": \"angular-bootstrap\",\n    \"keywords\": [\n        \"angular\",\n        \"angular-ui\",\n        \"bootstrap\"\n    ],\n    \"license\": \"MIT\",\n    \"ignore\": [],\n    \"description\": \"Native AngularJS (Angular) directives for Bootstrap.\",\n    \"version\": \"0.12.1\",\n    \"main\": [\"./ui-bootstrap-tpls.js\"],\n    \"dependencies\": {\n        \"angular\": \">=1 <1.3.0\"\n    }    \n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-bootstrap-tour/.bower.json",
    "content": "{\n  \"name\": \"angular-bootstrap-tour\",\n  \"version\": \"0.3.2\",\n  \"main\": \"dist/angular-bootstrap-tour.js\",\n  \"ignore\": [\n    \".editorconfig\",\n    \".gitattributes\",\n    \".gitignore\",\n    \".jshintrc\",\n    \".npmignore\",\n    \".travis.yml\",\n    \".umd\",\n    \"gulpfile.js\",\n    \"npm-shrinkwrap.json\",\n    \"package.json\"\n  ],\n  \"dependencies\": {\n    \"angular\": \"~1.2.23\",\n    \"bootstrap-tour\": \"~0.9.3\",\n    \"jquery\": \"1.11.1\",\n    \"bootstrap\": \"3.0.3\",\n    \"angular-route\": \"1.2.16\"\n  },\n  \"devDependencies\": {\n    \"html5shiv\": \"~3.7.2\",\n    \"respond\": \"~1.4.2\"\n  },\n  \"resolutions\": {\n    \"angular\": \"1.2.16\"\n  },\n  \"homepage\": \"https://github.com/benmarch/angular-bootstrap-tour\",\n  \"_release\": \"0.3.2\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"0.3.2\",\n    \"commit\": \"ff18966e4ede35f952517fee34f7dd73afa7a467\"\n  },\n  \"_source\": \"git://github.com/benmarch/angular-bootstrap-tour.git\",\n  \"_target\": \"~0.3.2\",\n  \"_originalSource\": \"angular-bootstrap-tour\",\n  \"_direct\": true\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-bootstrap-tour/README.md",
    "content": "# angular-bootstrap-tour\n[![Bower Version][bower-image]][bower-url]\n\n## About\n\nThis is a simple Angular wrapper around [Bootstrap Tour](http://www.bootstraptour.com).\nSimply add the \"tour\" directive anywhere, and add the \"tour-step\" directive to any element within \"tour\" that needs a tip.\n\nAll [options](http://bootstraptour.com/api/) are available by adding the corresponding attributes to the directive element.\n\nThere is also a \"skip\" option that if evaluates to true, will skip over the step.\n\nThis repository was scaffolded with [generator-microjs](https://github.com/daniellmb/generator-microjs).\n\n## Getting Started\nGet the package:\n\n    bower install angular-bootstrap-tour\n\nAdd the script tags:\n\n    <script src=\"bower_components/jquery/dist/jquery.js\"></script>\n    <script src=\"bower_components/angular/angular.js\"></script>\n    <script src=\"bower_components/bootstrap/dist/js/bootstrap.js\"></script>\n    <script src=\"bower_components/bootstrap-tour/build/js/bootstrap-tour.js\"></script>\n    <script src=\"bower_components/angular-bootstrap-tour/dist/angular-bootstrap-tour.js\"></script>\n\nAnd the Bootstrap Tour CSS (or create your own):\n\n    <link rel=\"stylesheet\" href=\"bower_components/bootstrap-tour/build/css/bootstrap-tour.css\" />\n\nThen add the module to your app:\n\n    angular.module('myApp', ['bm.bsTour']);\n    \n## Configuration\n    \nThe TourConfigProvider allows you to set a couple options:\n- `prefixOptions` {boolean, default: false} if set to true will require directive options to be prefixed to avoid conflicts\n- `prefix` {string, default: 'bsTour'} the prefix to use if `prefixOptions` is set to `true`\n\nUse `TourConfigProvider.set(<option>, <value>)` in your app's config block to change the settings\n\nYou can use either `tour` and `tourStep` or `bsTour` and `bsTourStep` as directive names without changing config.\n\n## Examples\n\n    <div tour placement=\"top\" on-end=\"onTourEnd(tour)\" after-get-state=\"afterGetStateFunction\" template-url=\"tour_template.html\">\n        <div id=\"mainMenu\" tour-step title=\"Main Menu\" content=\"{{mainMenuDescription}}\" order=\"0\" skip=\"pageName !== 'home'\">\n            ...\n        </div>\n\n        ...\n\n    </div>\n\n\n### Tour Directive\n\nThe tour directive creates a wrapper that contains all tour steps, and adds the tour object to the scope. If no options are specified, they all default to Bootstrap Tour's defaults.\nValues of event handler options will be evaluated against the tour's scope. For the afterGetState, afterSetState, and afterRemoveState, the value should\nevaluate to a function that takes 2 arguments, key and value. The container option should be a CSS selector, and defaults to \"body\".\nYou can also pass an object to the tour-options attribute that will override any other attribute options.\n\n### TourStep Directive\n\nThe tour-step directive takes all the options available in Bootstrap Tour, with a few alterations. Instead of next and prev options, just use the \"order\" option.\nOrder is used as a weighting (0 is first) and the plugin will dynamically determine which ones come before and after. If order is ommitted, it will default to 0.\nMultiple steps can have the same order, and those will display in the order that they are linked (usually the order in which they appear in the DOM.)\nIf order is omitted from all tour-steps, the order will be whatever order in which they are linked. Steps can be skipped by passing the \"skip\" option an expression that evaluates to a boolean.\nThe expression is evaluated before each step, so it can be a dynamic expression. This is useful if you have steps in a global layout, but only want to show them on the home page.\nSteps that are on hidden elements will not be shown. (Hidden means truly hidden, not obscured.)\nThe title and contents options are watched, so an interpolated value can be passed.\n\n## Compatibility\n\nI have tested it and found it working in the following browsers:\n\n- IE8, 9, 10, 11\n- Firefox 32\n- Chrome 37\n- Safari 7\n\n\n## TODO's\n\n- Write some tests!! (Come on Ben, stop being lazy ;p)\n\n## Build It Yourself\n\nAssuming you have Node, grunt, and bower installed:\n\n    npm install\n\n    bower install\n\n    grunt\n    \n## Demo\n    \nI have set up a simple demo using the Bootswatch Cerulean demo page (one of my favorite themes.) To run the demo run `grunt demo` and open demo/index.html in the browser.\n\n\n## Notes\n\nI am using this in a personal project, but I haven't needed to use all the Bootstrap Tour options. This means that some of them might not be working\ndue to the option values either not being passed correctly, or not being passed as interpolated values.\nIf you run across any issues please report them with an example and I will fix them ASAP, or fork me and create a PR.\nYou can now pass a template URL to either the tour or tour-step directives, and the template will be linked to whichever scope the template is specified on.\n(ie. if you add the template URL to the tour directive, it will always use the tour directive's scope, if you add it to a step, it will use the step's scope.)\nAlternatively, you can specify an expression that evaluates to a string that will be used as the template (using the \"template\" attribute.)\n\nThanks and enjoy!\n\n## License\n\n(The MIT License)\n\nCopyright (c) 2014  \n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n'Software'), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n\n\n[build-url]: https://travis-ci.org/benmarch/angular-bootstrap-tour\n[build-image]: http://img.shields.io/travis/benmarch/angular-bootstrap-tour.png\n\n[gpa-url]: https://codeclimate.com/github/benmarch/angular-bootstrap-tour\n[gpa-image]: https://codeclimate.com/github/benmarch/angular-bootstrap-tour.png\n\n[coverage-url]: https://codeclimate.com/github/benmarch/angular-bootstrap-tour/code?sort=covered_percent&sort_direction=desc\n[coverage-image]: https://codeclimate.com/github/benmarch/angular-bootstrap-tour/coverage.png\n\n[depstat-url]: https://david-dm.org/benmarch/angular-bootstrap-tour\n[depstat-image]: https://david-dm.org/benmarch/angular-bootstrap-tour.png?theme=shields.io\n\n[issues-url]: https://github.com/benmarch/angular-bootstrap-tour/issues\n[issues-image]: http://img.shields.io/github/issues/benmarch/angular-bootstrap-tour.png\n\n[bower-url]: http://bower.io/search/?q=angular-bootstrap-tour\n[bower-image]: https://badge.fury.io/bo/angular-bootstrap-tour.png\n\n[downloads-url]: https://www.npmjs.org/package/angular-bootstrap-tour\n[downloads-image]: http://img.shields.io/npm/dm/angular-bootstrap-tour.png\n\n[npm-url]: https://www.npmjs.org/package/angular-bootstrap-tour\n[npm-image]: https://badge.fury.io/js/angular-bootstrap-tour.png\n\n[irc-url]: http://webchat.freenode.net/?channels=angular-bootstrap-tour\n[irc-image]: http://img.shields.io/badge/irc-%23angular-bootstrap-tour-brightgreen.png\n\n[gitter-url]: https://gitter.im/benmarch/angular-bootstrap-tour\n[gitter-image]: http://img.shields.io/badge/gitter-benmarch/angular-bootstrap-tour-brightgreen.png\n\n[tip-url]: https://www.gittip.com/benmarch\n[tip-image]: http://img.shields.io/gittip/benmarch.png\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-bootstrap-tour/app/angular-bootstrap-tour.js",
    "content": "/* global Tour: false */\n\n\n\n(function angularBootstrapTour(app) {\n    'use strict';\n\n}(angular.module('bm.bsTour', [])));\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-bootstrap-tour/app/tour_config_provider.js",
    "content": "/* global angular: false */\n\n(function (app) {\n    'use strict';\n\n    app.provider('TourConfig', [function () {\n\n        var config = {\n            prefixOptions: false,\n            prefix: 'bsTour'\n        };\n\n        this.set = function (option, value) {\n            config[option] = value;\n        };\n\n        this.$get = [function () {\n\n            var service = {};\n\n            service.get = function (option) {\n                return config[option];\n            };\n\n            return service;\n\n        }];\n\n    }]);\n\n}(angular.module('bm.bsTour')));\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-bootstrap-tour/app/tour_controller.js",
    "content": "/* global angular: false */\n\n(function (app) {\n    'use strict';\n\n    app.controller('TourController', ['$filter', '$timeout', function ($filter, $timeout) {\n\n        var self = this,\n            steps = [],\n            tour,\n            newStepFound = angular.noop,\n            dummyStep = {};\n\n                function orderSteps(steps) {\n            var ordered = $filter('orderBy')(steps, 'order');\n\n            angular.forEach(ordered, function (step, index) {\n                step.next = ordered[index + 1] ? index + 1 : - 1;\n                step.prev = index - 1;\n            });\n\n            return ordered;\n        }\n\n                self.refreshTour = function () {\n            steps = steps.filter(function (step) {\n                return step !== dummyStep;\n            });\n            if (steps[0] && steps[0].redirectPrev) {\n                steps.unshift(dummyStep);\n            }\n            if (steps[steps.length-1] && steps[steps.length-1].redirectNext) {\n                steps.push(dummyStep);\n            }\n            if (tour) {\n                tour._options.steps = [];\n                tour.addSteps(orderSteps(steps));\n            }\n        };\n\n                self.addStep = function (step) {\n            if (~steps.indexOf(step)) {\n                return;\n            }\n\n            steps.push(step);\n            self.refreshTour();\n            newStepFound(step);\n        };\n\n                self.removeStep = function (step) {\n            if (!~steps.indexOf(step)) {\n                return;\n            }\n\n            steps.splice(steps.indexOf(step), 1);\n            self.refreshTour();\n        };\n\n                self.getSteps = function () {\n            return steps;\n        };\n\n                self.waitFor = function (waitForStep) {\n            tour.end();\n            newStepFound = function (step) {\n                if (step.stepId === waitForStep) {\n                    tour.setCurrentStep(steps.indexOf(step));\n                    $timeout(function () {\n                        tour.start(true);\n                    });\n                }\n            };\n        };\n\n                self.init = function (options) {\n            options.steps = orderSteps(steps);\n            tour = new Tour(options);\n            return tour;\n        };\n\n\n    }]);\n\n}(angular.module('bm.bsTour')));\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-bootstrap-tour/app/tour_directive.js",
    "content": "/* global angular: false */\n\n(function (app) {\n    'use strict';\n\n    function directive () {\n        return ['TourHelpers', function (TourHelpers) {\n\n            return {\n                restrict: 'EA',\n                scope: true,\n                controller: 'TourController',\n                link: function (scope, element, attrs, ctrl) {\n                    var tour = {},\n                        templateReady,\n                        events = 'onStart onEnd afterGetState afterSetState afterRemoveState onShow onShown onHide onHidden onNext onPrev onPause onResume'.split(' '),\n                        options = 'name container keyboard storage debug redirect duration basePath backdrop orphan'.split(' ');\n                    TourHelpers.attachInterpolatedValues(attrs, tour, options);\n                    TourHelpers.attachEventHandlers(scope, attrs, tour, events);\n                    templateReady = TourHelpers.attachTemplate(scope, attrs, tour);\n                    scope.$watchCollection(ctrl.getSteps, function (steps) {\n                        scope.stepCount = steps.length;\n                    });\n                    if (attrs.tourOptions) {\n                        angular.extend(tour, scope.$eval(attrs.tourOptions));\n                    }\n\n                    if (attrs[TourHelpers.getAttrName('options')]) {\n                        angular.extend(tour, scope.$eval(attrs[TourHelpers.getAttrName('options')]));\n                    }\n                    templateReady.then(function () {\n                        scope.tour = ctrl.init(tour);\n                        scope.tour.refresh = ctrl.refreshTour;\n                    });\n\n                }\n            };\n\n        }];\n    }\n\n    app.directive('tour', directive());\n    app.directive('bsTour', directive());\n\n}(angular.module('bm.bsTour')));\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-bootstrap-tour/app/tour_helpers.js",
    "content": "/* global angular: false */\n\n(function (app) {\n    'use strict';\n\n    app.factory('TourHelpers', ['$templateCache', '$http', '$compile', 'TourConfig', '$q', function ($templateCache, $http, $compile, TourConfig, $q) {\n\n        var helpers = {},\n            safeApply;\n\n                safeApply = helpers.safeApply = function(scope, fn) {\n            var phase = scope.$$phase;\n            if (phase === '$apply' || phase === '$digest') {\n                if (fn && (typeof(fn) === 'function')) {\n                    fn();\n                }\n            } else {\n                scope.$apply(fn);\n            }\n        };\n\n                function compileTemplate(template, scope) {\n            return function (/*index, step*/) {\n                var $template = angular.element(template); //requires jQuery\n                safeApply(scope, function () {\n                    $compile($template)(scope);\n                });\n                return $template;\n            };\n\n        }\n\n                function lookupTemplate(templateUrl, scope) {\n\n            return $http.get(templateUrl, {\n                cache: $templateCache\n            }).success(function (template) {\n                if (template) {\n                    return compileTemplate(template, scope);\n                }\n                return '';\n            });\n\n        }\n\n                function stringToBoolean(string) {\n            if (string === 'true') {\n                return true;\n            } else if (string === 'false') {\n                return false;\n            }\n\n            return string;\n        }\n\n                helpers.attachTemplate = function (scope, attrs, options) {\n\n            var deferred = $q.defer(),\n                template;\n\n            if (attrs[helpers.getAttrName('template')]) {\n                template = compileTemplate(scope.$eval(attrs[helpers.getAttrName('template')]), scope);\n                options.template = template;\n                deferred.resolve(template);\n            } else if (attrs[helpers.getAttrName('templateUrl')]) {\n                lookupTemplate(attrs[helpers.getAttrName('templateUrl')], scope).then(function (template) {\n                    if (template) {\n                        options.template = template;\n                        deferred.resolve(template);\n                    }\n                });\n            } else {\n                deferred.resolve();\n            }\n\n            return deferred.promise;\n\n        };\n\n                helpers.attachEventHandlers = function (scope, attrs, options, events) {\n\n            angular.forEach(events, function (eventName) {\n                if (attrs[helpers.getAttrName(eventName)]) {\n                    options[eventName] = function (tour) {\n                        safeApply(scope, function () {\n                            scope.$eval(attrs[helpers.getAttrName(eventName)]);\n                        });\n                    };\n                }\n            });\n\n        };\n\n                helpers.attachInterpolatedValues = function (attrs, options, keys) {\n\n            angular.forEach(keys, function (key) {\n                if (attrs[helpers.getAttrName(key)]) {\n                    options[key] = stringToBoolean(attrs[helpers.getAttrName(key)]);\n                    attrs.$observe(helpers.getAttrName(key), function (newValue) {\n                        options[key] = stringToBoolean(newValue);\n                    });\n                }\n            });\n\n        };\n\n                helpers.getAttrName = function (option) {\n            if (TourConfig.get('prefixOptions')) {\n                return TourConfig.get('prefix') + option.charAt(0).toUpperCase() + option.substr(1);\n            } else {\n                return option;\n            }\n        };\n\n        return helpers;\n\n    }]);\n\n}(angular.module('bm.bsTour')));\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-bootstrap-tour/app/tour_step_directive.js",
    "content": "/* global angular: false */\n\n(function (app) {\n    'use strict';\n\n    function directive() {\n        return ['TourHelpers', '$location', function (TourHelpers, $location) {\n\n            return {\n                restrict: 'EA',\n                scope: true,\n                require: '^tour',\n                link: function (scope, element, attrs, ctrl) {\n                    var step = {\n                            element: element,\n                            stepId: attrs.tourStep\n                        },\n                        events = 'onShow onShown onHide onHidden onNext onPrev onPause onResume'.split(' '),\n                        options = 'content title path animation container placement backdrop redirect orphan reflex duration nextStep prevStep nextPath prevPath'.split(' '),\n                        orderWatch,\n                        skipWatch,\n                        templateReady;\n                    TourHelpers.attachInterpolatedValues(attrs, step, options);\n                    orderWatch = attrs.$observe(TourHelpers.getAttrName('order'), function (order) {\n                        step.order = !isNaN(order*1) ? order*1 : 0;\n                        ctrl.refreshTour();\n                    });\n                    TourHelpers.attachEventHandlers(scope, attrs, step, events);\n                    templateReady = TourHelpers.attachTemplate(scope, attrs, step);\n                    function stepIsSkipped() {\n                        var skipped;\n                        if (attrs[TourHelpers.getAttrName('skip')]) {\n                            skipped = scope.$eval(attrs[TourHelpers.getAttrName('skip')]);\n                        }\n                        if (!skipped) {\n                            skipped = !!step.path || (element.is(':hidden') && !attrs.availableWhenHidden);\n                        }\n                        return skipped;\n                    }\n                    skipWatch = scope.$watch(stepIsSkipped, function (skip) {\n                        if (skip) {\n                            ctrl.removeStep(step);\n                        } else {\n                            ctrl.addStep(step);\n                        }\n                    });\n\n                    scope.$on('$destroy', function () {\n                        ctrl.removeStep(step);\n                        orderWatch();\n                        skipWatch();\n                    });\n                    if (attrs[TourHelpers.getAttrName('options')]) {\n                        angular.extend(step, scope.$eval(attrs[TourHelpers.getAttrName('options')]));\n                    }\n                    function setRedirect(direction, path, targetName) {\n                        var oldHandler = step[direction];\n                        step[direction] = function (tour) {\n                            if (oldHandler) {\n                                oldHandler(tour);\n                            }\n                            ctrl.waitFor(targetName);\n\n                            TourHelpers.safeApply(scope, function () {\n                                $location.path(path);\n                            });\n                        };\n                    }\n                    if (step.nextPath) {\n                        step.redirectNext = true;\n                        setRedirect('onNext', step.nextPath, step.nextStep);\n                    }\n                    if (step.prevPath) {\n                        step.redirectPrev = true;\n                        setRedirect('onPrev', step.prevPath, step.prevStep);\n                    }\n                    templateReady.then(function () {\n                        ctrl.addStep(step);\n                    });\n\n                }\n            };\n\n        }];\n    }\n\n    app.directive('tourStep', directive());\n    app.directive('bsTourStep', directive());\n\n}(angular.module('bm.bsTour')));\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-bootstrap-tour/bower.json",
    "content": "{\n  \"name\": \"angular-bootstrap-tour\",\n  \"version\": \"0.3.2\",\n  \"main\": \"dist/angular-bootstrap-tour.js\",\n  \"ignore\": [\n    \".editorconfig\",\n    \".gitattributes\",\n    \".gitignore\",\n    \".jshintrc\",\n    \".npmignore\",\n    \".travis.yml\",\n    \".umd\",\n    \"gulpfile.js\",\n    \"npm-shrinkwrap.json\",\n    \"package.json\"\n  ],\n  \"dependencies\": {\n    \"angular\": \"~1.2.23\",\n    \"bootstrap-tour\": \"~0.9.3\",\n    \"jquery\": \"1.11.1\",\n    \"bootstrap\": \"3.0.3\",\n    \"angular-route\": \"1.2.16\"\n  },\n  \"devDependencies\": {\n    \"html5shiv\": \"~3.7.2\",\n    \"respond\": \"~1.4.2\"\n  },\n  \"resolutions\": {\n    \"angular\": \"1.2.16\"\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-bootstrap-tour/demo/angular-bootstrap-tour.js",
    "content": "/* global Tour: false */\n\n\n\n(function angularBootstrapTour(app) {\n    'use strict';\n\n}(angular.module('bm.bsTour', [])));\n\n/* global angular: false */\n\n(function (app) {\n    'use strict';\n\n    app.provider('TourConfig', [function () {\n\n        var config = {\n            prefixOptions: false,\n            prefix: 'bsTour'\n        };\n\n        this.set = function (option, value) {\n            config[option] = value;\n        };\n\n        this.$get = [function () {\n\n            var service = {};\n\n            service.get = function (option) {\n                return config[option];\n            };\n\n            return service;\n\n        }];\n\n    }]);\n\n}(angular.module('bm.bsTour')));\n\n/* global angular: false */\n\n(function (app) {\n    'use strict';\n\n    app.controller('TourController', ['$filter', '$timeout', function ($filter, $timeout) {\n\n        var self = this,\n            steps = [],\n            tour,\n            newStepFound = angular.noop,\n            dummyStep = {};\n\n                function orderSteps(steps) {\n            var ordered = $filter('orderBy')(steps, 'order');\n\n            angular.forEach(ordered, function (step, index) {\n                step.next = ordered[index + 1] ? index + 1 : - 1;\n                step.prev = index - 1;\n            });\n\n            return ordered;\n        }\n\n                self.refreshTour = function () {\n            steps = steps.filter(function (step) {\n                return step !== dummyStep;\n            });\n            if (steps[0] && steps[0].redirectPrev) {\n                steps.unshift(dummyStep);\n            }\n            if (steps[steps.length-1] && steps[steps.length-1].redirectNext) {\n                steps.push(dummyStep);\n            }\n            if (tour) {\n                tour._options.steps = [];\n                tour.addSteps(orderSteps(steps));\n            }\n        };\n\n                self.addStep = function (step) {\n            if (~steps.indexOf(step)) {\n                return;\n            }\n\n            steps.push(step);\n            self.refreshTour();\n            newStepFound(step);\n        };\n\n                self.removeStep = function (step) {\n            if (!~steps.indexOf(step)) {\n                return;\n            }\n\n            steps.splice(steps.indexOf(step), 1);\n            self.refreshTour();\n        };\n\n                self.getSteps = function () {\n            return steps;\n        };\n\n                self.waitFor = function (waitForStep) {\n            tour.end();\n            newStepFound = function (step) {\n                if (step.stepId === waitForStep) {\n                    tour.setCurrentStep(steps.indexOf(step));\n                    $timeout(function () {\n                        tour.start(true);\n                    });\n                }\n            };\n        };\n\n                self.init = function (options) {\n            options.steps = orderSteps(steps);\n            tour = new Tour(options);\n            return tour;\n        };\n\n\n    }]);\n\n}(angular.module('bm.bsTour')));\n\n/* global angular: false */\n\n(function (app) {\n    'use strict';\n\n    function directive () {\n        return ['TourHelpers', function (TourHelpers) {\n\n            return {\n                restrict: 'EA',\n                scope: true,\n                controller: 'TourController',\n                link: function (scope, element, attrs, ctrl) {\n                    var tour = {},\n                        templateReady,\n                        events = 'onStart onEnd afterGetState afterSetState afterRemoveState onShow onShown onHide onHidden onNext onPrev onPause onResume'.split(' '),\n                        options = 'name container keyboard storage debug redirect duration basePath backdrop orphan'.split(' ');\n                    TourHelpers.attachInterpolatedValues(attrs, tour, options);\n                    TourHelpers.attachEventHandlers(scope, attrs, tour, events);\n                    templateReady = TourHelpers.attachTemplate(scope, attrs, tour);\n                    scope.$watchCollection(ctrl.getSteps, function (steps) {\n                        scope.stepCount = steps.length;\n                    });\n                    if (attrs.tourOptions) {\n                        angular.extend(tour, scope.$eval(attrs.tourOptions));\n                    }\n\n                    if (attrs[TourHelpers.getAttrName('options')]) {\n                        angular.extend(tour, scope.$eval(attrs[TourHelpers.getAttrName('options')]));\n                    }\n                    templateReady.then(function () {\n                        scope.tour = ctrl.init(tour);\n                        scope.tour.refresh = ctrl.refreshTour;\n                    });\n\n                }\n            };\n\n        }];\n    }\n\n    app.directive('tour', directive());\n    app.directive('bsTour', directive());\n\n}(angular.module('bm.bsTour')));\n\n/* global angular: false */\n\n(function (app) {\n    'use strict';\n\n    app.factory('TourHelpers', ['$templateCache', '$http', '$compile', 'TourConfig', '$q', function ($templateCache, $http, $compile, TourConfig, $q) {\n\n        var helpers = {},\n            safeApply;\n\n                safeApply = helpers.safeApply = function(scope, fn) {\n            var phase = scope.$$phase;\n            if (phase === '$apply' || phase === '$digest') {\n                if (fn && (typeof(fn) === 'function')) {\n                    fn();\n                }\n            } else {\n                scope.$apply(fn);\n            }\n        };\n\n                function compileTemplate(template, scope) {\n            return function (/*index, step*/) {\n                var $template = angular.element(template); //requires jQuery\n                safeApply(scope, function () {\n                    $compile($template)(scope);\n                });\n                return $template;\n            };\n\n        }\n\n                function lookupTemplate(templateUrl, scope) {\n\n            return $http.get(templateUrl, {\n                cache: $templateCache\n            }).success(function (template) {\n                if (template) {\n                    return compileTemplate(template, scope);\n                }\n                return '';\n            });\n\n        }\n\n                function stringToBoolean(string) {\n            if (string === 'true') {\n                return true;\n            } else if (string === 'false') {\n                return false;\n            }\n\n            return string;\n        }\n\n                helpers.attachTemplate = function (scope, attrs, options) {\n\n            var deferred = $q.defer(),\n                template;\n\n            if (attrs[helpers.getAttrName('template')]) {\n                template = compileTemplate(scope.$eval(attrs[helpers.getAttrName('template')]), scope);\n                options.template = template;\n                deferred.resolve(template);\n            } else if (attrs[helpers.getAttrName('templateUrl')]) {\n                lookupTemplate(attrs[helpers.getAttrName('templateUrl')], scope).then(function (template) {\n                    if (template) {\n                        options.template = template;\n                        deferred.resolve(template);\n                    }\n                });\n            } else {\n                deferred.resolve();\n            }\n\n            return deferred.promise;\n\n        };\n\n                helpers.attachEventHandlers = function (scope, attrs, options, events) {\n\n            angular.forEach(events, function (eventName) {\n                if (attrs[helpers.getAttrName(eventName)]) {\n                    options[eventName] = function (tour) {\n                        safeApply(scope, function () {\n                            scope.$eval(attrs[helpers.getAttrName(eventName)]);\n                        });\n                    };\n                }\n            });\n\n        };\n\n                helpers.attachInterpolatedValues = function (attrs, options, keys) {\n\n            angular.forEach(keys, function (key) {\n                if (attrs[helpers.getAttrName(key)]) {\n                    options[key] = stringToBoolean(attrs[helpers.getAttrName(key)]);\n                    attrs.$observe(helpers.getAttrName(key), function (newValue) {\n                        options[key] = stringToBoolean(newValue);\n                    });\n                }\n            });\n\n        };\n\n                helpers.getAttrName = function (option) {\n            if (TourConfig.get('prefixOptions')) {\n                return TourConfig.get('prefix') + option.charAt(0).toUpperCase() + option.substr(1);\n            } else {\n                return option;\n            }\n        };\n\n        return helpers;\n\n    }]);\n\n}(angular.module('bm.bsTour')));\n\n/* global angular: false */\n\n(function (app) {\n    'use strict';\n\n    function directive() {\n        return ['TourHelpers', '$location', function (TourHelpers, $location) {\n\n            return {\n                restrict: 'EA',\n                scope: true,\n                require: '^tour',\n                link: function (scope, element, attrs, ctrl) {\n                    var step = {\n                            element: element,\n                            stepId: attrs.tourStep\n                        },\n                        events = 'onShow onShown onHide onHidden onNext onPrev onPause onResume'.split(' '),\n                        options = 'content title path animation container placement backdrop redirect orphan reflex duration nextStep prevStep nextPath prevPath'.split(' '),\n                        orderWatch,\n                        skipWatch,\n                        templateReady;\n                    TourHelpers.attachInterpolatedValues(attrs, step, options);\n                    orderWatch = attrs.$observe(TourHelpers.getAttrName('order'), function (order) {\n                        step.order = !isNaN(order*1) ? order*1 : 0;\n                        ctrl.refreshTour();\n                    });\n                    TourHelpers.attachEventHandlers(scope, attrs, step, events);\n                    templateReady = TourHelpers.attachTemplate(scope, attrs, step);\n                    function stepIsSkipped() {\n                        var skipped;\n                        if (attrs[TourHelpers.getAttrName('skip')]) {\n                            skipped = scope.$eval(attrs[TourHelpers.getAttrName('skip')]);\n                        }\n                        if (!skipped) {\n                            skipped = !!step.path || (element.is(':hidden') && !attrs.availableWhenHidden);\n                        }\n                        return skipped;\n                    }\n                    skipWatch = scope.$watch(stepIsSkipped, function (skip) {\n                        if (skip) {\n                            ctrl.removeStep(step);\n                        } else {\n                            ctrl.addStep(step);\n                        }\n                    });\n\n                    scope.$on('$destroy', function () {\n                        ctrl.removeStep(step);\n                        orderWatch();\n                        skipWatch();\n                    });\n                    if (attrs[TourHelpers.getAttrName('options')]) {\n                        angular.extend(step, scope.$eval(attrs[TourHelpers.getAttrName('options')]));\n                    }\n                    function setRedirect(direction, path, targetName) {\n                        var oldHandler = step[direction];\n                        step[direction] = function (tour) {\n                            if (oldHandler) {\n                                oldHandler(tour);\n                            }\n                            ctrl.waitFor(targetName);\n\n                            TourHelpers.safeApply(scope, function () {\n                                $location.path(path);\n                            });\n                        };\n                    }\n                    if (step.nextPath) {\n                        step.redirectNext = true;\n                        setRedirect('onNext', step.nextPath, step.nextStep);\n                    }\n                    if (step.prevPath) {\n                        step.redirectPrev = true;\n                        setRedirect('onPrev', step.prevPath, step.prevStep);\n                    }\n                    templateReady.then(function () {\n                        ctrl.addStep(step);\n                    });\n\n                }\n            };\n\n        }];\n    }\n\n    app.directive('tourStep', directive());\n    app.directive('bsTourStep', directive());\n\n}(angular.module('bm.bsTour')));\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-bootstrap-tour/dist/angular-bootstrap-tour.js",
    "content": "/* global Tour: false */\n\n\n\n(function angularBootstrapTour(app) {\n    'use strict';\n\n}(angular.module('bm.bsTour', [])));\n\n/* global angular: false */\n\n(function (app) {\n    'use strict';\n\n    app.provider('TourConfig', [function () {\n\n        var config = {\n            prefixOptions: false,\n            prefix: 'bsTour'\n        };\n\n        this.set = function (option, value) {\n            config[option] = value;\n        };\n\n        this.$get = [function () {\n\n            var service = {};\n\n            service.get = function (option) {\n                return config[option];\n            };\n\n            return service;\n\n        }];\n\n    }]);\n\n}(angular.module('bm.bsTour')));\n\n/* global angular: false */\n\n(function (app) {\n    'use strict';\n\n    app.controller('TourController', ['$filter', '$timeout', function ($filter, $timeout) {\n\n        var self = this,\n            steps = [],\n            tour,\n            newStepFound = angular.noop,\n            dummyStep = {};\n\n                function orderSteps(steps) {\n            var ordered = $filter('orderBy')(steps, 'order');\n\n            angular.forEach(ordered, function (step, index) {\n                step.next = ordered[index + 1] ? index + 1 : - 1;\n                step.prev = index - 1;\n            });\n\n            return ordered;\n        }\n\n                self.refreshTour = function () {\n            steps = steps.filter(function (step) {\n                return step !== dummyStep;\n            });\n            if (steps[0] && steps[0].redirectPrev) {\n                steps.unshift(dummyStep);\n            }\n            if (steps[steps.length-1] && steps[steps.length-1].redirectNext) {\n                steps.push(dummyStep);\n            }\n            if (tour) {\n                tour._options.steps = [];\n                tour.addSteps(orderSteps(steps));\n            }\n        };\n\n                self.addStep = function (step) {\n            if (~steps.indexOf(step)) {\n                return;\n            }\n\n            steps.push(step);\n            self.refreshTour();\n            newStepFound(step);\n        };\n\n                self.removeStep = function (step) {\n            if (!~steps.indexOf(step)) {\n                return;\n            }\n\n            steps.splice(steps.indexOf(step), 1);\n            self.refreshTour();\n        };\n\n                self.getSteps = function () {\n            return steps;\n        };\n\n                self.waitFor = function (waitForStep) {\n            tour.end();\n            newStepFound = function (step) {\n                if (step.stepId === waitForStep) {\n                    tour.setCurrentStep(steps.indexOf(step));\n                    $timeout(function () {\n                        tour.start(true);\n                    });\n                }\n            };\n        };\n\n                self.init = function (options) {\n            options.steps = orderSteps(steps);\n            tour = new Tour(options);\n            return tour;\n        };\n\n\n    }]);\n\n}(angular.module('bm.bsTour')));\n\n/* global angular: false */\n\n(function (app) {\n    'use strict';\n\n    function directive () {\n        return ['TourHelpers', function (TourHelpers) {\n\n            return {\n                restrict: 'EA',\n                scope: true,\n                controller: 'TourController',\n                link: function (scope, element, attrs, ctrl) {\n                    var tour = {},\n                        templateReady,\n                        events = 'onStart onEnd afterGetState afterSetState afterRemoveState onShow onShown onHide onHidden onNext onPrev onPause onResume'.split(' '),\n                        options = 'name container keyboard storage debug redirect duration basePath backdrop orphan'.split(' ');\n                    TourHelpers.attachInterpolatedValues(attrs, tour, options);\n                    TourHelpers.attachEventHandlers(scope, attrs, tour, events);\n                    templateReady = TourHelpers.attachTemplate(scope, attrs, tour);\n                    scope.$watchCollection(ctrl.getSteps, function (steps) {\n                        scope.stepCount = steps.length;\n                    });\n                    if (attrs.tourOptions) {\n                        angular.extend(tour, scope.$eval(attrs.tourOptions));\n                    }\n\n                    if (attrs[TourHelpers.getAttrName('options')]) {\n                        angular.extend(tour, scope.$eval(attrs[TourHelpers.getAttrName('options')]));\n                    }\n                    templateReady.then(function () {\n                        scope.tour = ctrl.init(tour);\n                        scope.tour.refresh = ctrl.refreshTour;\n                    });\n\n                }\n            };\n\n        }];\n    }\n\n    app.directive('tour', directive());\n    app.directive('bsTour', directive());\n\n}(angular.module('bm.bsTour')));\n\n/* global angular: false */\n\n(function (app) {\n    'use strict';\n\n    app.factory('TourHelpers', ['$templateCache', '$http', '$compile', 'TourConfig', '$q', function ($templateCache, $http, $compile, TourConfig, $q) {\n\n        var helpers = {},\n            safeApply;\n\n                safeApply = helpers.safeApply = function(scope, fn) {\n            var phase = scope.$$phase;\n            if (phase === '$apply' || phase === '$digest') {\n                if (fn && (typeof(fn) === 'function')) {\n                    fn();\n                }\n            } else {\n                scope.$apply(fn);\n            }\n        };\n\n                function compileTemplate(template, scope) {\n            return function (/*index, step*/) {\n                var $template = angular.element(template); //requires jQuery\n                safeApply(scope, function () {\n                    $compile($template)(scope);\n                });\n                return $template;\n            };\n\n        }\n\n                function lookupTemplate(templateUrl, scope) {\n\n            return $http.get(templateUrl, {\n                cache: $templateCache\n            }).success(function (template) {\n                if (template) {\n                    return compileTemplate(template, scope);\n                }\n                return '';\n            });\n\n        }\n\n                function stringToBoolean(string) {\n            if (string === 'true') {\n                return true;\n            } else if (string === 'false') {\n                return false;\n            }\n\n            return string;\n        }\n\n                helpers.attachTemplate = function (scope, attrs, options) {\n\n            var deferred = $q.defer(),\n                template;\n\n            if (attrs[helpers.getAttrName('template')]) {\n                template = compileTemplate(scope.$eval(attrs[helpers.getAttrName('template')]), scope);\n                options.template = template;\n                deferred.resolve(template);\n            } else if (attrs[helpers.getAttrName('templateUrl')]) {\n                lookupTemplate(attrs[helpers.getAttrName('templateUrl')], scope).then(function (template) {\n                    if (template) {\n                        options.template = template;\n                        deferred.resolve(template);\n                    }\n                });\n            } else {\n                deferred.resolve();\n            }\n\n            return deferred.promise;\n\n        };\n\n                helpers.attachEventHandlers = function (scope, attrs, options, events) {\n\n            angular.forEach(events, function (eventName) {\n                if (attrs[helpers.getAttrName(eventName)]) {\n                    options[eventName] = function (tour) {\n                        safeApply(scope, function () {\n                            scope.$eval(attrs[helpers.getAttrName(eventName)]);\n                        });\n                    };\n                }\n            });\n\n        };\n\n                helpers.attachInterpolatedValues = function (attrs, options, keys) {\n\n            angular.forEach(keys, function (key) {\n                if (attrs[helpers.getAttrName(key)]) {\n                    options[key] = stringToBoolean(attrs[helpers.getAttrName(key)]);\n                    attrs.$observe(helpers.getAttrName(key), function (newValue) {\n                        options[key] = stringToBoolean(newValue);\n                    });\n                }\n            });\n\n        };\n\n                helpers.getAttrName = function (option) {\n            if (TourConfig.get('prefixOptions')) {\n                return TourConfig.get('prefix') + option.charAt(0).toUpperCase() + option.substr(1);\n            } else {\n                return option;\n            }\n        };\n\n        return helpers;\n\n    }]);\n\n}(angular.module('bm.bsTour')));\n\n/* global angular: false */\n\n(function (app) {\n    'use strict';\n\n    function directive() {\n        return ['TourHelpers', '$location', function (TourHelpers, $location) {\n\n            return {\n                restrict: 'EA',\n                scope: true,\n                require: '^tour',\n                link: function (scope, element, attrs, ctrl) {\n                    var step = {\n                            element: element,\n                            stepId: attrs.tourStep\n                        },\n                        events = 'onShow onShown onHide onHidden onNext onPrev onPause onResume'.split(' '),\n                        options = 'content title path animation container placement backdrop redirect orphan reflex duration nextStep prevStep nextPath prevPath'.split(' '),\n                        orderWatch,\n                        skipWatch,\n                        templateReady;\n                    TourHelpers.attachInterpolatedValues(attrs, step, options);\n                    orderWatch = attrs.$observe(TourHelpers.getAttrName('order'), function (order) {\n                        step.order = !isNaN(order*1) ? order*1 : 0;\n                        ctrl.refreshTour();\n                    });\n                    TourHelpers.attachEventHandlers(scope, attrs, step, events);\n                    templateReady = TourHelpers.attachTemplate(scope, attrs, step);\n                    function stepIsSkipped() {\n                        var skipped;\n                        if (attrs[TourHelpers.getAttrName('skip')]) {\n                            skipped = scope.$eval(attrs[TourHelpers.getAttrName('skip')]);\n                        }\n                        if (!skipped) {\n                        }\n                        return skipped;\n                    }\n                    skipWatch = scope.$watch(stepIsSkipped, function (skip) {\n                        if (skip) {\n                            ctrl.removeStep(step);\n                        } else {\n                            ctrl.addStep(step);\n                        }\n                    });\n\n                    scope.$on('$destroy', function () {\n                        ctrl.removeStep(step);\n                        orderWatch();\n                        skipWatch();\n                    });\n                    if (attrs[TourHelpers.getAttrName('options')]) {\n                        angular.extend(step, scope.$eval(attrs[TourHelpers.getAttrName('options')]));\n                    }\n                    function setRedirect(direction, path, targetName) {\n                        var oldHandler = step[direction];\n                        step[direction] = function (tour) {\n                            if (oldHandler) {\n                                oldHandler(tour);\n                            }\n                            ctrl.waitFor(targetName);\n\n                            TourHelpers.safeApply(scope, function () {\n                                $location.path(path);\n                            });\n                        };\n                    }\n                    if (step.nextPath) {\n                        step.redirectNext = true;\n                        setRedirect('onNext', step.nextPath, step.nextStep);\n                    }\n                    if (step.prevPath) {\n                        step.redirectPrev = true;\n                        setRedirect('onPrev', step.prevPath, step.prevStep);\n                    }\n                    templateReady.then(function () {\n                        ctrl.addStep(step);\n                    });\n\n                }\n            };\n\n        }];\n    }\n\n    app.directive('tourStep', directive());\n    app.directive('bsTourStep', directive());\n\n}(angular.module('bm.bsTour')));\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-bootstrap-tour/gruntfile.js",
    "content": "'use strict';\n\nmodule.exports = function (grunt) {\n    var config = {\n        app: 'app',\n        dist: 'dist'\n    };\n\n    require('load-grunt-tasks')(grunt);\n    require('time-grunt')(grunt);\n\n    grunt.initConfig({\n        config: config,\n\n        jshint: {\n            options: {\n                jshintrc: '.jshintrc'\n            },\n            all: [\n                'Gruntfile.js',\n                '<%= config.app %>/**/*.js',\n                'test/spec/**/*.js'\n            ]\n        },\n\n        karma: {\n            unit: {\n                configFile: 'karma.conf.js'\n            }\n        },\n\n        concat: {\n            angular: {\n                src: ['<%= config.app %>/angular-bootstrap-tour.js', '<%= config.app %>/**/*.js'],\n                dest: '<%= config.dist %>/angular-bootstrap-tour.js'\n            }\n        },\n\n        uglify: {\n            angular: {\n                src: '<%= config.dist %>/angular-bootstrap-tour.js',\n                dest: '<%= config.dist %>/angular-bootstrap-tour.min.js'\n            }\n        },\n\n        copy: {\n            demo: {\n                files: [\n                    {\n                        src: 'dist/angular-bootstrap-tour.js',\n                        dest: 'demo/angular-bootstrap-tour.js'\n                    }\n                ]\n            }\n        },\n        wiredep: {\n            test: {\n                src: 'karma.conf.js',\n                devDependencies: true,\n                fileTypes: {\n                    js: {\n                        block: /(([\\s\\t]*)\\/\\/\\s*bower:*(\\S*))(\\n|\\r|.)*?(\\/\\/\\s*endbower)/gi,\n                        detect: {\n                            js: /'(.*\\.js)'/gi\n                        },\n                        replace: {\n                            js: '\\'{{filePath}}\\','\n                        }\n                    }\n                }\n            },\n\n            demo: {\n                src: 'demo/index.html',\n                devDependencies: true,\n                ignorePath: '../',\n                exclude: [\n                    'bootstrap.css',\n                    'bootstrap-tour-standalone.js',\n                    'bootstrap-tour-standalone.css',\n                    'respond.src.js'\n                ]\n            }\n        },\n\n\n        bower_main: {\n            demo: {\n                options: {\n                    dest: 'demo/bower_components'\n                }\n            }\n        }\n    });\n\n    grunt.registerTask('test', [\n        'karma:unit'\n    ]);\n\n    grunt.registerTask('build', [\n        'concat',\n        'uglify'\n    ]);\n\n    grunt.registerTask('demo', [\n        'build',\n        'bower_main:demo',\n        'wiredep:demo',\n        'copy:demo'\n    ]);\n\n    grunt.registerTask('default', [\n        'jshint',\n        'test',\n        'build'\n    ]);\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-bootstrap-tour/karma.conf.js",
    "content": "\nmodule.exports = function(config) {\n    config.set({\n        basePath: '',\n        frameworks: ['jasmine'],\n        files: [\n            'bower_components/jquery/dist/jquery.js',\n            'bower_components/angular/angular.js',\n            'bower_components/bootstrap/dist/js/bootstrap.js',\n            'bower_components/bootstrap-tour/build/js/bootstrap-tour.js',\n            'bower_components/bootstrap-tour/build/js/bootstrap-tour-standalone.js',\n            'app/angular-bootstrap-tour.js',\n            'app/**/*.js',\n            'test/spec/**/*.js'\n        ],\n        exclude: [],\n        preprocessors: {\n            'src/**/*.js': ['coverage']\n        },\n        reporters: ['dots', 'junit', 'coverage', 'growl'],\n\n        htmlReporter: {\n            outputDir: 'test/results',\n            templatePath: 'node_modules/karma-html-reporter/jasmine_template.html'\n        },\n\n        junitReporter: {\n            outputFile: 'test/results/karma.xml'\n        },\n        port: 9876,\n        colors: true,\n        logLevel: config.LOG_INFO,\n        autoWatch: false,\n        browsers: ['PhantomJS'],\n        singleRun: true\n    });\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-bootstrap-tour/test/spec/angular-bootstrap-tour.spec.js",
    "content": "'use strict';\n\n/*global angularBootstrapTour*/\ndescribe('angular-bootstrap-tour.js', function () {\n  beforeEach(function () {\n  });\n\n  it('should have a working test harness', function () {\n    expect(true).not.toBe(false);\n  });\n\n});"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-cookies/.bower.json",
    "content": "{\n  \"name\": \"angular-cookies\",\n  \"version\": \"1.3.15\",\n  \"main\": \"./angular-cookies.js\",\n  \"ignore\": [],\n  \"dependencies\": {\n    \"angular\": \"1.3.15\"\n  },\n  \"homepage\": \"https://github.com/angular/bower-angular-cookies\",\n  \"_release\": \"1.3.15\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"v1.3.15\",\n    \"commit\": \"846700fd8e45eefa1a43cf1865bcb7aaf95a68e0\"\n  },\n  \"_source\": \"git://github.com/angular/bower-angular-cookies.git\",\n  \"_target\": \">=1.2.26 <=1.4\",\n  \"_originalSource\": \"angular-cookies\"\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-cookies/README.md",
    "content": "# packaged angular-cookies\n\nThis repo is for distribution on `npm` and `bower`. The source for this module is in the\n[main AngularJS repo](https://github.com/angular/angular.js/tree/master/src/ngCookies).\nPlease file issues and pull requests against that repo.\n\n## Install\n\nYou can install this package either with `npm` or with `bower`.\n\n### npm\n\n```shell\nnpm install angular-cookies\n```\n\nThen add `ngCookies` as a dependency for your app:\n\n```javascript\nangular.module('myApp', [require('angular-cookies')]);\n```\n\n### bower\n\n```shell\nbower install angular-cookies\n```\n\nAdd a `<script>` to your `index.html`:\n\n```html\n<script src=\"/bower_components/angular-cookies/angular-cookies.js\"></script>\n```\n\nThen add `ngCookies` as a dependency for your app:\n\n```javascript\nangular.module('myApp', ['ngCookies']);\n```\n\n## Documentation\n\nDocumentation is available on the\n[AngularJS docs site](http://docs.angularjs.org/api/ngCookies).\n\n## License\n\nThe MIT License\n\nCopyright (c) 2010-2015 Google, Inc. http://angularjs.org\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-cookies/bower.json",
    "content": "{\n  \"name\": \"angular-cookies\",\n  \"version\": \"1.3.15\",\n  \"main\": \"./angular-cookies.js\",\n  \"ignore\": [],\n  \"dependencies\": {\n    \"angular\": \"1.3.15\"\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-cookies/index.js",
    "content": "require('./angular-cookies');\nmodule.exports = 'ngCookies';\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-cookies/package.json",
    "content": "{\n  \"name\": \"angular-cookies\",\n  \"version\": \"1.3.15\",\n  \"description\": \"AngularJS module for cookies\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/angular/angular.js.git\"\n  },\n  \"keywords\": [\n    \"angular\",\n    \"framework\",\n    \"browser\",\n    \"cookies\",\n    \"client-side\"\n  ],\n  \"author\": \"Angular Core Team <angular-core+npm@google.com>\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/angular/angular.js/issues\"\n  },\n  \"homepage\": \"http://angularjs.org\"\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-mocks/.bower.json",
    "content": "{\n  \"name\": \"angular-mocks\",\n  \"version\": \"1.3.15\",\n  \"main\": \"./angular-mocks.js\",\n  \"ignore\": [],\n  \"dependencies\": {\n    \"angular\": \"1.3.15\"\n  },\n  \"homepage\": \"https://github.com/angular/bower-angular-mocks\",\n  \"_release\": \"1.3.15\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"v1.3.15\",\n    \"commit\": \"1ffdfef850b10d40f2838c1bba41a95755c2d8da\"\n  },\n  \"_source\": \"git://github.com/angular/bower-angular-mocks.git\",\n  \"_target\": \"~1.3.15\",\n  \"_originalSource\": \"angular-mocks\",\n  \"_direct\": true\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-mocks/README.md",
    "content": "# packaged angular-mocks\n\nThis repo is for distribution on `npm` and `bower`. The source for this module is in the\n[main AngularJS repo](https://github.com/angular/angular.js/tree/master/src/ngMock).\nPlease file issues and pull requests against that repo.\n\n## Install\n\nYou can install this package either with `npm` or with `bower`.\n\n### npm\n\n```shell\nnpm install angular-mocks\n```\n\nYou can `require` ngMock modules:\n\n```js\nvar angular = require('angular');\nangular.module('myMod', [\n  require('angular-animate'),\n  require('angular-mocks/ngMock')\n  require('angular-mocks/ngAnimateMock')\n]);\n```\n\n### bower\n\n```shell\nbower install angular-mocks\n```\n\nThe mocks are then available at `bower_components/angular-mocks/angular-mocks.js`.\n\n## Documentation\n\nDocumentation is available on the\n[AngularJS docs site](https://docs.angularjs.org/guide/unit-testing).\n\n## License\n\nThe MIT License\n\nCopyright (c) 2010-2015 Google, Inc. http://angularjs.org\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-mocks/angular-mocks.js",
    "content": "(function(window, angular, undefined) {\n\n'use strict';\n\nangular.mock = {};\n\nangular.mock.$BrowserProvider = function() {\n  this.$get = function() {\n    return new angular.mock.$Browser();\n  };\n};\n\nangular.mock.$Browser = function() {\n  var self = this;\n\n  this.isMock = true;\n  self.$$url = \"http://server/\";\n  self.$$lastUrl = self.$$url; // used by url polling fn\n  self.pollFns = [];\n  self.$$completeOutstandingRequest = angular.noop;\n  self.$$incOutstandingRequestCount = angular.noop;\n\n  self.onUrlChange = function(listener) {\n    self.pollFns.push(\n      function() {\n        if (self.$$lastUrl !== self.$$url || self.$$state !== self.$$lastState) {\n          self.$$lastUrl = self.$$url;\n          self.$$lastState = self.$$state;\n          listener(self.$$url, self.$$state);\n        }\n      }\n    );\n\n    return listener;\n  };\n\n  self.$$checkUrlChange = angular.noop;\n\n  self.cookieHash = {};\n  self.lastCookieHash = {};\n  self.deferredFns = [];\n  self.deferredNextId = 0;\n\n  self.defer = function(fn, delay) {\n    delay = delay || 0;\n    self.deferredFns.push({time:(self.defer.now + delay), fn:fn, id: self.deferredNextId});\n    self.deferredFns.sort(function(a, b) { return a.time - b.time;});\n    return self.deferredNextId++;\n  };\n\n\n    self.defer.now = 0;\n\n\n  self.defer.cancel = function(deferId) {\n    var fnIndex;\n\n    angular.forEach(self.deferredFns, function(fn, index) {\n      if (fn.id === deferId) fnIndex = index;\n    });\n\n    if (fnIndex !== undefined) {\n      self.deferredFns.splice(fnIndex, 1);\n      return true;\n    }\n\n    return false;\n  };\n\n\n    self.defer.flush = function(delay) {\n    if (angular.isDefined(delay)) {\n      self.defer.now += delay;\n    } else {\n      if (self.deferredFns.length) {\n        self.defer.now = self.deferredFns[self.deferredFns.length - 1].time;\n      } else {\n        throw new Error('No deferred tasks to be flushed');\n      }\n    }\n\n    while (self.deferredFns.length && self.deferredFns[0].time <= self.defer.now) {\n      self.deferredFns.shift().fn();\n    }\n  };\n\n  self.$$baseHref = '/';\n  self.baseHref = function() {\n    return this.$$baseHref;\n  };\n};\nangular.mock.$Browser.prototype = {\n\n  poll: function poll() {\n    angular.forEach(this.pollFns, function(pollFn) {\n      pollFn();\n    });\n  },\n\n  addPollFn: function(pollFn) {\n    this.pollFns.push(pollFn);\n    return pollFn;\n  },\n\n  url: function(url, replace, state) {\n    if (angular.isUndefined(state)) {\n      state = null;\n    }\n    if (url) {\n      this.$$url = url;\n      this.$$state = angular.copy(state);\n      return this;\n    }\n\n    return this.$$url;\n  },\n\n  state: function() {\n    return this.$$state;\n  },\n\n  cookies:  function(name, value) {\n    if (name) {\n      if (angular.isUndefined(value)) {\n        delete this.cookieHash[name];\n      } else {\n        if (angular.isString(value) &&       //strings only\n            value.length <= 4096) {          //strict cookie storage limits\n          this.cookieHash[name] = value;\n        }\n      }\n    } else {\n      if (!angular.equals(this.cookieHash, this.lastCookieHash)) {\n        this.lastCookieHash = angular.copy(this.cookieHash);\n        this.cookieHash = angular.copy(this.cookieHash);\n      }\n      return this.cookieHash;\n    }\n  },\n\n  notifyWhenNoOutstandingRequests: function(fn) {\n    fn();\n  }\n};\n\n\n\n\nangular.mock.$ExceptionHandlerProvider = function() {\n  var handler;\n\n    this.mode = function(mode) {\n\n    switch (mode) {\n      case 'log':\n      case 'rethrow':\n        var errors = [];\n        handler = function(e) {\n          if (arguments.length == 1) {\n            errors.push(e);\n          } else {\n            errors.push([].slice.call(arguments, 0));\n          }\n          if (mode === \"rethrow\") {\n            throw e;\n          }\n        };\n        handler.errors = errors;\n        break;\n      default:\n        throw new Error(\"Unknown mode '\" + mode + \"', only 'log'/'rethrow' modes are allowed!\");\n    }\n  };\n\n  this.$get = function() {\n    return handler;\n  };\n\n  this.mode('rethrow');\n};\n\n\nangular.mock.$LogProvider = function() {\n  var debug = true;\n\n  function concat(array1, array2, index) {\n    return array1.concat(Array.prototype.slice.call(array2, index));\n  }\n\n  this.debugEnabled = function(flag) {\n    if (angular.isDefined(flag)) {\n      debug = flag;\n      return this;\n    } else {\n      return debug;\n    }\n  };\n\n  this.$get = function() {\n    var $log = {\n      log: function() { $log.log.logs.push(concat([], arguments, 0)); },\n      warn: function() { $log.warn.logs.push(concat([], arguments, 0)); },\n      info: function() { $log.info.logs.push(concat([], arguments, 0)); },\n      error: function() { $log.error.logs.push(concat([], arguments, 0)); },\n      debug: function() {\n        if (debug) {\n          $log.debug.logs.push(concat([], arguments, 0));\n        }\n      }\n    };\n\n        $log.reset = function() {\n            $log.log.logs = [];\n            $log.info.logs = [];\n            $log.warn.logs = [];\n            $log.error.logs = [];\n              $log.debug.logs = [];\n    };\n\n        $log.assertEmpty = function() {\n      var errors = [];\n      angular.forEach(['error', 'warn', 'info', 'log', 'debug'], function(logLevel) {\n        angular.forEach($log[logLevel].logs, function(log) {\n          angular.forEach(log, function(logItem) {\n            errors.push('MOCK $log (' + logLevel + '): ' + String(logItem) + '\\n' +\n                        (logItem.stack || ''));\n          });\n        });\n      });\n      if (errors.length) {\n        errors.unshift(\"Expected $log to be empty! Either a message was logged unexpectedly, or \" +\n          \"an expected log message was not checked and removed:\");\n        errors.push('');\n        throw new Error(errors.join('\\n---------\\n'));\n      }\n    };\n\n    $log.reset();\n    return $log;\n  };\n};\n\n\nangular.mock.$IntervalProvider = function() {\n  this.$get = ['$browser', '$rootScope', '$q', '$$q',\n       function($browser,   $rootScope,   $q,   $$q) {\n    var repeatFns = [],\n        nextRepeatId = 0,\n        now = 0;\n\n    var $interval = function(fn, delay, count, invokeApply) {\n      var iteration = 0,\n          skipApply = (angular.isDefined(invokeApply) && !invokeApply),\n          deferred = (skipApply ? $$q : $q).defer(),\n          promise = deferred.promise;\n\n      count = (angular.isDefined(count)) ? count : 0;\n      promise.then(null, null, fn);\n\n      promise.$$intervalId = nextRepeatId;\n\n      function tick() {\n        deferred.notify(iteration++);\n\n        if (count > 0 && iteration >= count) {\n          var fnIndex;\n          deferred.resolve(iteration);\n\n          angular.forEach(repeatFns, function(fn, index) {\n            if (fn.id === promise.$$intervalId) fnIndex = index;\n          });\n\n          if (fnIndex !== undefined) {\n            repeatFns.splice(fnIndex, 1);\n          }\n        }\n\n        if (skipApply) {\n          $browser.defer.flush();\n        } else {\n          $rootScope.$apply();\n        }\n      }\n\n      repeatFns.push({\n        nextTime:(now + delay),\n        delay: delay,\n        fn: tick,\n        id: nextRepeatId,\n        deferred: deferred\n      });\n      repeatFns.sort(function(a, b) { return a.nextTime - b.nextTime;});\n\n      nextRepeatId++;\n      return promise;\n    };\n        $interval.cancel = function(promise) {\n      if (!promise) return false;\n      var fnIndex;\n\n      angular.forEach(repeatFns, function(fn, index) {\n        if (fn.id === promise.$$intervalId) fnIndex = index;\n      });\n\n      if (fnIndex !== undefined) {\n        repeatFns[fnIndex].deferred.reject('canceled');\n        repeatFns.splice(fnIndex, 1);\n        return true;\n      }\n\n      return false;\n    };\n\n        $interval.flush = function(millis) {\n      now += millis;\n      while (repeatFns.length && repeatFns[0].nextTime <= now) {\n        var task = repeatFns[0];\n        task.fn();\n        task.nextTime += task.delay;\n        repeatFns.sort(function(a, b) { return a.nextTime - b.nextTime;});\n      }\n      return millis;\n    };\n\n    return $interval;\n  }];\n};\n\n\n/* jshint -W101 */\n/* The R_ISO8061_STR regex is never going to fit into the 100 char limit!\n * This directive should go inside the anonymous function but a bug in JSHint means that it would\n * not be enacted early enough to prevent the warning.\n */\nvar R_ISO8061_STR = /^(\\d{4})-?(\\d\\d)-?(\\d\\d)(?:T(\\d\\d)(?:\\:?(\\d\\d)(?:\\:?(\\d\\d)(?:\\.(\\d{3}))?)?)?(Z|([+-])(\\d\\d):?(\\d\\d)))?$/;\n\nfunction jsonStringToDate(string) {\n  var match;\n  if (match = string.match(R_ISO8061_STR)) {\n    var date = new Date(0),\n        tzHour = 0,\n        tzMin  = 0;\n    if (match[9]) {\n      tzHour = int(match[9] + match[10]);\n      tzMin = int(match[9] + match[11]);\n    }\n    date.setUTCFullYear(int(match[1]), int(match[2]) - 1, int(match[3]));\n    date.setUTCHours(int(match[4] || 0) - tzHour,\n                     int(match[5] || 0) - tzMin,\n                     int(match[6] || 0),\n                     int(match[7] || 0));\n    return date;\n  }\n  return string;\n}\n\nfunction int(str) {\n  return parseInt(str, 10);\n}\n\nfunction padNumber(num, digits, trim) {\n  var neg = '';\n  if (num < 0) {\n    neg =  '-';\n    num = -num;\n  }\n  num = '' + num;\n  while (num.length < digits) num = '0' + num;\n  if (trim)\n    num = num.substr(num.length - digits);\n  return neg + num;\n}\n\n\nangular.mock.TzDate = function(offset, timestamp) {\n  var self = new Date(0);\n  if (angular.isString(timestamp)) {\n    var tsStr = timestamp;\n\n    self.origDate = jsonStringToDate(timestamp);\n\n    timestamp = self.origDate.getTime();\n    if (isNaN(timestamp))\n      throw {\n        name: \"Illegal Argument\",\n        message: \"Arg '\" + tsStr + \"' passed into TzDate constructor is not a valid date string\"\n      };\n  } else {\n    self.origDate = new Date(timestamp);\n  }\n\n  var localOffset = new Date(timestamp).getTimezoneOffset();\n  self.offsetDiff = localOffset * 60 * 1000 - offset * 1000 * 60 * 60;\n  self.date = new Date(timestamp + self.offsetDiff);\n\n  self.getTime = function() {\n    return self.date.getTime() - self.offsetDiff;\n  };\n\n  self.toLocaleDateString = function() {\n    return self.date.toLocaleDateString();\n  };\n\n  self.getFullYear = function() {\n    return self.date.getFullYear();\n  };\n\n  self.getMonth = function() {\n    return self.date.getMonth();\n  };\n\n  self.getDate = function() {\n    return self.date.getDate();\n  };\n\n  self.getHours = function() {\n    return self.date.getHours();\n  };\n\n  self.getMinutes = function() {\n    return self.date.getMinutes();\n  };\n\n  self.getSeconds = function() {\n    return self.date.getSeconds();\n  };\n\n  self.getMilliseconds = function() {\n    return self.date.getMilliseconds();\n  };\n\n  self.getTimezoneOffset = function() {\n    return offset * 60;\n  };\n\n  self.getUTCFullYear = function() {\n    return self.origDate.getUTCFullYear();\n  };\n\n  self.getUTCMonth = function() {\n    return self.origDate.getUTCMonth();\n  };\n\n  self.getUTCDate = function() {\n    return self.origDate.getUTCDate();\n  };\n\n  self.getUTCHours = function() {\n    return self.origDate.getUTCHours();\n  };\n\n  self.getUTCMinutes = function() {\n    return self.origDate.getUTCMinutes();\n  };\n\n  self.getUTCSeconds = function() {\n    return self.origDate.getUTCSeconds();\n  };\n\n  self.getUTCMilliseconds = function() {\n    return self.origDate.getUTCMilliseconds();\n  };\n\n  self.getDay = function() {\n    return self.date.getDay();\n  };\n  if (self.toISOString) {\n    self.toISOString = function() {\n      return padNumber(self.origDate.getUTCFullYear(), 4) + '-' +\n            padNumber(self.origDate.getUTCMonth() + 1, 2) + '-' +\n            padNumber(self.origDate.getUTCDate(), 2) + 'T' +\n            padNumber(self.origDate.getUTCHours(), 2) + ':' +\n            padNumber(self.origDate.getUTCMinutes(), 2) + ':' +\n            padNumber(self.origDate.getUTCSeconds(), 2) + '.' +\n            padNumber(self.origDate.getUTCMilliseconds(), 3) + 'Z';\n    };\n  }\n  var unimplementedMethods = ['getUTCDay',\n      'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds',\n      'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear',\n      'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds',\n      'setYear', 'toDateString', 'toGMTString', 'toJSON', 'toLocaleFormat', 'toLocaleString',\n      'toLocaleTimeString', 'toSource', 'toString', 'toTimeString', 'toUTCString', 'valueOf'];\n\n  angular.forEach(unimplementedMethods, function(methodName) {\n    self[methodName] = function() {\n      throw new Error(\"Method '\" + methodName + \"' is not implemented in the TzDate mock\");\n    };\n  });\n\n  return self;\n};\nangular.mock.TzDate.prototype = Date.prototype;\n/* jshint +W101 */\n\nangular.mock.animate = angular.module('ngAnimateMock', ['ng'])\n\n  .config(['$provide', function($provide) {\n\n    var reflowQueue = [];\n    $provide.value('$$animateReflow', function(fn) {\n      var index = reflowQueue.length;\n      reflowQueue.push(fn);\n      return function cancel() {\n        reflowQueue.splice(index, 1);\n      };\n    });\n\n    $provide.decorator('$animate', ['$delegate', '$$asyncCallback', '$timeout', '$browser',\n                            function($delegate,   $$asyncCallback,   $timeout,   $browser) {\n      var animate = {\n        queue: [],\n        cancel: $delegate.cancel,\n        enabled: $delegate.enabled,\n        triggerCallbackEvents: function() {\n          $$asyncCallback.flush();\n        },\n        triggerCallbackPromise: function() {\n          $timeout.flush(0);\n        },\n        triggerCallbacks: function() {\n          this.triggerCallbackEvents();\n          this.triggerCallbackPromise();\n        },\n        triggerReflow: function() {\n          angular.forEach(reflowQueue, function(fn) {\n            fn();\n          });\n          reflowQueue = [];\n        }\n      };\n\n      angular.forEach(\n        ['animate','enter','leave','move','addClass','removeClass','setClass'], function(method) {\n        animate[method] = function() {\n          animate.queue.push({\n            event: method,\n            element: arguments[0],\n            options: arguments[arguments.length - 1],\n            args: arguments\n          });\n          return $delegate[method].apply($delegate, arguments);\n        };\n      });\n\n      return animate;\n    }]);\n\n  }]);\n\n\nangular.mock.dump = function(object) {\n  return serialize(object);\n\n  function serialize(object) {\n    var out;\n\n    if (angular.isElement(object)) {\n      object = angular.element(object);\n      out = angular.element('<div></div>');\n      angular.forEach(object, function(element) {\n        out.append(angular.element(element).clone());\n      });\n      out = out.html();\n    } else if (angular.isArray(object)) {\n      out = [];\n      angular.forEach(object, function(o) {\n        out.push(serialize(o));\n      });\n      out = '[ ' + out.join(', ') + ' ]';\n    } else if (angular.isObject(object)) {\n      if (angular.isFunction(object.$eval) && angular.isFunction(object.$apply)) {\n        out = serializeScope(object);\n      } else if (object instanceof Error) {\n        out = object.stack || ('' + object.name + ': ' + object.message);\n      } else {\n        out = angular.toJson(object, true);\n      }\n    } else {\n      out = String(object);\n    }\n\n    return out;\n  }\n\n  function serializeScope(scope, offset) {\n    offset = offset ||  '  ';\n    var log = [offset + 'Scope(' + scope.$id + '): {'];\n    for (var key in scope) {\n      if (Object.prototype.hasOwnProperty.call(scope, key) && !key.match(/^(\\$|this)/)) {\n        log.push('  ' + key + ': ' + angular.toJson(scope[key]));\n      }\n    }\n    var child = scope.$$childHead;\n    while (child) {\n      log.push(serializeScope(child, offset + '  '));\n      child = child.$$nextSibling;\n    }\n    log.push('}');\n    return log.join('\\n' + offset);\n  }\n};\n\nangular.mock.$HttpBackendProvider = function() {\n  this.$get = ['$rootScope', '$timeout', createHttpBackendMock];\n};\n\nfunction createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {\n  var definitions = [],\n      expectations = [],\n      responses = [],\n      responsesPush = angular.bind(responses, responses.push),\n      copy = angular.copy;\n\n  function createResponse(status, data, headers, statusText) {\n    if (angular.isFunction(status)) return status;\n\n    return function() {\n      return angular.isNumber(status)\n          ? [status, data, headers, statusText]\n          : [200, status, data, headers];\n    };\n  }\n  function $httpBackend(method, url, data, callback, headers, timeout, withCredentials) {\n    var xhr = new MockXhr(),\n        expectation = expectations[0],\n        wasExpected = false;\n\n    function prettyPrint(data) {\n      return (angular.isString(data) || angular.isFunction(data) || data instanceof RegExp)\n          ? data\n          : angular.toJson(data);\n    }\n\n    function wrapResponse(wrapped) {\n      if (!$browser && timeout) {\n        timeout.then ? timeout.then(handleTimeout) : $timeout(handleTimeout, timeout);\n      }\n\n      return handleResponse;\n\n      function handleResponse() {\n        var response = wrapped.response(method, url, data, headers);\n        xhr.$$respHeaders = response[2];\n        callback(copy(response[0]), copy(response[1]), xhr.getAllResponseHeaders(),\n                 copy(response[3] || ''));\n      }\n\n      function handleTimeout() {\n        for (var i = 0, ii = responses.length; i < ii; i++) {\n          if (responses[i] === handleResponse) {\n            responses.splice(i, 1);\n            callback(-1, undefined, '');\n            break;\n          }\n        }\n      }\n    }\n\n    if (expectation && expectation.match(method, url)) {\n      if (!expectation.matchData(data))\n        throw new Error('Expected ' + expectation + ' with different data\\n' +\n            'EXPECTED: ' + prettyPrint(expectation.data) + '\\nGOT:      ' + data);\n\n      if (!expectation.matchHeaders(headers))\n        throw new Error('Expected ' + expectation + ' with different headers\\n' +\n                        'EXPECTED: ' + prettyPrint(expectation.headers) + '\\nGOT:      ' +\n                        prettyPrint(headers));\n\n      expectations.shift();\n\n      if (expectation.response) {\n        responses.push(wrapResponse(expectation));\n        return;\n      }\n      wasExpected = true;\n    }\n\n    var i = -1, definition;\n    while ((definition = definitions[++i])) {\n      if (definition.match(method, url, data, headers || {})) {\n        if (definition.response) {\n          ($browser ? $browser.defer : responsesPush)(wrapResponse(definition));\n        } else if (definition.passThrough) {\n          $delegate(method, url, data, callback, headers, timeout, withCredentials);\n        } else throw new Error('No response defined !');\n        return;\n      }\n    }\n    throw wasExpected ?\n        new Error('No response defined !') :\n        new Error('Unexpected request: ' + method + ' ' + url + '\\n' +\n                  (expectation ? 'Expected ' + expectation : 'No more request expected'));\n  }\n\n    $httpBackend.when = function(method, url, data, headers) {\n    var definition = new MockHttpExpectation(method, url, data, headers),\n        chain = {\n          respond: function(status, data, headers, statusText) {\n            definition.passThrough = undefined;\n            definition.response = createResponse(status, data, headers, statusText);\n            return chain;\n          }\n        };\n\n    if ($browser) {\n      chain.passThrough = function() {\n        definition.response = undefined;\n        definition.passThrough = true;\n        return chain;\n      };\n    }\n\n    definitions.push(definition);\n    return chain;\n  };\n\n  \n  \n  \n  \n  \n    createShortMethods('when');\n\n\n    $httpBackend.expect = function(method, url, data, headers) {\n    var expectation = new MockHttpExpectation(method, url, data, headers),\n        chain = {\n          respond: function(status, data, headers, statusText) {\n            expectation.response = createResponse(status, data, headers, statusText);\n            return chain;\n          }\n        };\n\n    expectations.push(expectation);\n    return chain;\n  };\n\n\n  \n  \n  \n  \n  \n  \n    createShortMethods('expect');\n\n\n    $httpBackend.flush = function(count, digest) {\n    if (digest !== false) $rootScope.$digest();\n    if (!responses.length) throw new Error('No pending request to flush !');\n\n    if (angular.isDefined(count) && count !== null) {\n      while (count--) {\n        if (!responses.length) throw new Error('No more pending request to flush !');\n        responses.shift()();\n      }\n    } else {\n      while (responses.length) {\n        responses.shift()();\n      }\n    }\n    $httpBackend.verifyNoOutstandingExpectation(digest);\n  };\n\n\n    $httpBackend.verifyNoOutstandingExpectation = function(digest) {\n    if (digest !== false) $rootScope.$digest();\n    if (expectations.length) {\n      throw new Error('Unsatisfied requests: ' + expectations.join(', '));\n    }\n  };\n\n\n    $httpBackend.verifyNoOutstandingRequest = function() {\n    if (responses.length) {\n      throw new Error('Unflushed requests: ' + responses.length);\n    }\n  };\n\n\n    $httpBackend.resetExpectations = function() {\n    expectations.length = 0;\n    responses.length = 0;\n  };\n\n  return $httpBackend;\n\n\n  function createShortMethods(prefix) {\n    angular.forEach(['GET', 'DELETE', 'JSONP', 'HEAD'], function(method) {\n     $httpBackend[prefix + method] = function(url, headers) {\n       return $httpBackend[prefix](method, url, undefined, headers);\n     };\n    });\n\n    angular.forEach(['PUT', 'POST', 'PATCH'], function(method) {\n      $httpBackend[prefix + method] = function(url, data, headers) {\n        return $httpBackend[prefix](method, url, data, headers);\n      };\n    });\n  }\n}\n\nfunction MockHttpExpectation(method, url, data, headers) {\n\n  this.data = data;\n  this.headers = headers;\n\n  this.match = function(m, u, d, h) {\n    if (method != m) return false;\n    if (!this.matchUrl(u)) return false;\n    if (angular.isDefined(d) && !this.matchData(d)) return false;\n    if (angular.isDefined(h) && !this.matchHeaders(h)) return false;\n    return true;\n  };\n\n  this.matchUrl = function(u) {\n    if (!url) return true;\n    if (angular.isFunction(url.test)) return url.test(u);\n    if (angular.isFunction(url)) return url(u);\n    return url == u;\n  };\n\n  this.matchHeaders = function(h) {\n    if (angular.isUndefined(headers)) return true;\n    if (angular.isFunction(headers)) return headers(h);\n    return angular.equals(headers, h);\n  };\n\n  this.matchData = function(d) {\n    if (angular.isUndefined(data)) return true;\n    if (data && angular.isFunction(data.test)) return data.test(d);\n    if (data && angular.isFunction(data)) return data(d);\n    if (data && !angular.isString(data)) {\n      return angular.equals(angular.fromJson(angular.toJson(data)), angular.fromJson(d));\n    }\n    return data == d;\n  };\n\n  this.toString = function() {\n    return method + ' ' + url;\n  };\n}\n\nfunction createMockXhr() {\n  return new MockXhr();\n}\n\nfunction MockXhr() {\n  MockXhr.$$lastInstance = this;\n\n  this.open = function(method, url, async) {\n    this.$$method = method;\n    this.$$url = url;\n    this.$$async = async;\n    this.$$reqHeaders = {};\n    this.$$respHeaders = {};\n  };\n\n  this.send = function(data) {\n    this.$$data = data;\n  };\n\n  this.setRequestHeader = function(key, value) {\n    this.$$reqHeaders[key] = value;\n  };\n\n  this.getResponseHeader = function(name) {\n    var header = this.$$respHeaders[name];\n    if (header) return header;\n\n    name = angular.lowercase(name);\n    header = this.$$respHeaders[name];\n    if (header) return header;\n\n    header = undefined;\n    angular.forEach(this.$$respHeaders, function(headerVal, headerName) {\n      if (!header && angular.lowercase(headerName) == name) header = headerVal;\n    });\n    return header;\n  };\n\n  this.getAllResponseHeaders = function() {\n    var lines = [];\n\n    angular.forEach(this.$$respHeaders, function(value, key) {\n      lines.push(key + ': ' + value);\n    });\n    return lines.join('\\n');\n  };\n\n  this.abort = angular.noop;\n}\n\n\n\nangular.mock.$TimeoutDecorator = ['$delegate', '$browser', function($delegate, $browser) {\n\n    $delegate.flush = function(delay) {\n    $browser.defer.flush(delay);\n  };\n\n    $delegate.verifyNoPendingTasks = function() {\n    if ($browser.deferredFns.length) {\n      throw new Error('Deferred tasks to flush (' + $browser.deferredFns.length + '): ' +\n          formatPendingTasksAsString($browser.deferredFns));\n    }\n  };\n\n  function formatPendingTasksAsString(tasks) {\n    var result = [];\n    angular.forEach(tasks, function(task) {\n      result.push('{id: ' + task.id + ', ' + 'time: ' + task.time + '}');\n    });\n\n    return result.join(', ');\n  }\n\n  return $delegate;\n}];\n\nangular.mock.$RAFDecorator = ['$delegate', function($delegate) {\n  var queue = [];\n  var rafFn = function(fn) {\n    var index = queue.length;\n    queue.push(fn);\n    return function() {\n      queue.splice(index, 1);\n    };\n  };\n\n  rafFn.supported = $delegate.supported;\n\n  rafFn.flush = function() {\n    if (queue.length === 0) {\n      throw new Error('No rAF callbacks present');\n    }\n\n    var length = queue.length;\n    for (var i = 0; i < length; i++) {\n      queue[i]();\n    }\n\n    queue = [];\n  };\n\n  return rafFn;\n}];\n\nangular.mock.$AsyncCallbackDecorator = ['$delegate', function($delegate) {\n  var callbacks = [];\n  var addFn = function(fn) {\n    callbacks.push(fn);\n  };\n  addFn.flush = function() {\n    angular.forEach(callbacks, function(fn) {\n      fn();\n    });\n    callbacks = [];\n  };\n  return addFn;\n}];\n\nangular.mock.$RootElementProvider = function() {\n  this.$get = function() {\n    return angular.element('<div ng-app></div>');\n  };\n};\n\nangular.mock.$ControllerDecorator = ['$delegate', function($delegate) {\n  return function(expression, locals, later, ident) {\n    if (later && typeof later === 'object') {\n      var create = $delegate(expression, locals, true, ident);\n      angular.extend(create.instance, later);\n      return create();\n    }\n    return $delegate(expression, locals, later, ident);\n  };\n}];\n\n\nangular.module('ngMock', ['ng']).provider({\n  $browser: angular.mock.$BrowserProvider,\n  $exceptionHandler: angular.mock.$ExceptionHandlerProvider,\n  $log: angular.mock.$LogProvider,\n  $interval: angular.mock.$IntervalProvider,\n  $httpBackend: angular.mock.$HttpBackendProvider,\n  $rootElement: angular.mock.$RootElementProvider\n}).config(['$provide', function($provide) {\n  $provide.decorator('$timeout', angular.mock.$TimeoutDecorator);\n  $provide.decorator('$$rAF', angular.mock.$RAFDecorator);\n  $provide.decorator('$$asyncCallback', angular.mock.$AsyncCallbackDecorator);\n  $provide.decorator('$rootScope', angular.mock.$RootScopeDecorator);\n  $provide.decorator('$controller', angular.mock.$ControllerDecorator);\n}]);\n\nangular.module('ngMockE2E', ['ng']).config(['$provide', function($provide) {\n  $provide.decorator('$httpBackend', angular.mock.e2e.$httpBackendDecorator);\n}]);\n\n\n\n\n\n\n\n\n\nangular.mock.e2e = {};\nangular.mock.e2e.$httpBackendDecorator =\n  ['$rootScope', '$timeout', '$delegate', '$browser', createHttpBackendMock];\n\n\nangular.mock.$RootScopeDecorator = ['$delegate', function($delegate) {\n\n  var $rootScopePrototype = Object.getPrototypeOf($delegate);\n\n  $rootScopePrototype.$countChildScopes = countChildScopes;\n  $rootScopePrototype.$countWatchers = countWatchers;\n\n  return $delegate;\n\n    function countChildScopes() {\n    var count = 0; // exclude the current scope\n    var pendingChildHeads = [this.$$childHead];\n    var currentScope;\n\n    while (pendingChildHeads.length) {\n      currentScope = pendingChildHeads.shift();\n\n      while (currentScope) {\n        count += 1;\n        pendingChildHeads.push(currentScope.$$childHead);\n        currentScope = currentScope.$$nextSibling;\n      }\n    }\n\n    return count;\n  }\n\n\n    function countWatchers() {\n    var count = this.$$watchers ? this.$$watchers.length : 0; // include the current scope\n    var pendingChildHeads = [this.$$childHead];\n    var currentScope;\n\n    while (pendingChildHeads.length) {\n      currentScope = pendingChildHeads.shift();\n\n      while (currentScope) {\n        count += currentScope.$$watchers ? currentScope.$$watchers.length : 0;\n        pendingChildHeads.push(currentScope.$$childHead);\n        currentScope = currentScope.$$nextSibling;\n      }\n    }\n\n    return count;\n  }\n}];\n\n\nif (window.jasmine || window.mocha) {\n\n  var currentSpec = null,\n      annotatedFunctions = [],\n      isSpecRunning = function() {\n        return !!currentSpec;\n      };\n\n  angular.mock.$$annotate = angular.injector.$$annotate;\n  angular.injector.$$annotate = function(fn) {\n    if (typeof fn === 'function' && !fn.$inject) {\n      annotatedFunctions.push(fn);\n    }\n    return angular.mock.$$annotate.apply(this, arguments);\n  };\n\n\n  (window.beforeEach || window.setup)(function() {\n    annotatedFunctions = [];\n    currentSpec = this;\n  });\n\n  (window.afterEach || window.teardown)(function() {\n    var injector = currentSpec.$injector;\n\n    annotatedFunctions.forEach(function(fn) {\n      delete fn.$inject;\n    });\n\n    angular.forEach(currentSpec.$modules, function(module) {\n      if (module && module.$$hashKey) {\n        module.$$hashKey = undefined;\n      }\n    });\n\n    currentSpec.$injector = null;\n    currentSpec.$modules = null;\n    currentSpec = null;\n\n    if (injector) {\n      injector.get('$rootElement').off();\n      injector.get('$browser').pollFns.length = 0;\n    }\n    angular.forEach(angular.element.fragments, function(val, key) {\n      delete angular.element.fragments[key];\n    });\n\n    MockXhr.$$lastInstance = null;\n\n    angular.forEach(angular.callbacks, function(val, key) {\n      delete angular.callbacks[key];\n    });\n    angular.callbacks.counter = 0;\n  });\n\n    window.module = angular.mock.module = function() {\n    var moduleFns = Array.prototype.slice.call(arguments, 0);\n    return isSpecRunning() ? workFn() : workFn;\n    function workFn() {\n      if (currentSpec.$injector) {\n        throw new Error('Injector already created, can not register a module!');\n      } else {\n        var modules = currentSpec.$modules || (currentSpec.$modules = []);\n        angular.forEach(moduleFns, function(module) {\n          if (angular.isObject(module) && !angular.isArray(module)) {\n            modules.push(function($provide) {\n              angular.forEach(module, function(value, key) {\n                $provide.value(key, value);\n              });\n            });\n          } else {\n            modules.push(module);\n          }\n        });\n      }\n    }\n  };\n\n  \n\n\n  var ErrorAddingDeclarationLocationStack = function(e, errorForStack) {\n    this.message = e.message;\n    this.name = e.name;\n    if (e.line) this.line = e.line;\n    if (e.sourceId) this.sourceId = e.sourceId;\n    if (e.stack && errorForStack)\n      this.stack = e.stack + '\\n' + errorForStack.stack;\n    if (e.stackArray) this.stackArray = e.stackArray;\n  };\n  ErrorAddingDeclarationLocationStack.prototype.toString = Error.prototype.toString;\n\n  window.inject = angular.mock.inject = function() {\n    var blockFns = Array.prototype.slice.call(arguments, 0);\n    var errorForStack = new Error('Declaration Location');\n    return isSpecRunning() ? workFn.call(currentSpec) : workFn;\n    function workFn() {\n      var modules = currentSpec.$modules || [];\n      var strictDi = !!currentSpec.$injectorStrict;\n      modules.unshift('ngMock');\n      modules.unshift('ng');\n      var injector = currentSpec.$injector;\n      if (!injector) {\n        if (strictDi) {\n          angular.forEach(modules, function(moduleFn) {\n            if (typeof moduleFn === \"function\") {\n              angular.injector.$$annotate(moduleFn);\n            }\n          });\n        }\n        injector = currentSpec.$injector = angular.injector(modules, strictDi);\n        currentSpec.$injectorStrict = strictDi;\n      }\n      for (var i = 0, ii = blockFns.length; i < ii; i++) {\n        if (currentSpec.$injectorStrict) {\n          injector.annotate(blockFns[i]);\n        }\n        try {\n          /* jshint -W040 *//* Jasmine explicitly provides a `this` object when calling functions */\n          injector.invoke(blockFns[i] || angular.noop, this);\n          /* jshint +W040 */\n        } catch (e) {\n          if (e.stack && errorForStack) {\n            throw new ErrorAddingDeclarationLocationStack(e, errorForStack);\n          }\n          throw e;\n        } finally {\n          errorForStack = null;\n        }\n      }\n    }\n  };\n\n\n  angular.mock.inject.strictDi = function(value) {\n    value = arguments.length ? !!value : true;\n    return isSpecRunning() ? workFn() : workFn;\n\n    function workFn() {\n      if (value !== currentSpec.$injectorStrict) {\n        if (currentSpec.$injector) {\n          throw new Error('Injector already created, can not modify strict annotations');\n        } else {\n          currentSpec.$injectorStrict = value;\n        }\n      }\n    }\n  };\n}\n\n\n})(window, window.angular);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-mocks/bower.json",
    "content": "{\n  \"name\": \"angular-mocks\",\n  \"version\": \"1.3.15\",\n  \"main\": \"./angular-mocks.js\",\n  \"ignore\": [],\n  \"dependencies\": {\n    \"angular\": \"1.3.15\"\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-mocks/ngAnimateMock.js",
    "content": "require('./angular-mocks');\nmodule.exports = 'ngAnimateMock';\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-mocks/ngMock.js",
    "content": "require('./angular-mocks');\nmodule.exports = 'ngMock';\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-mocks/ngMockE2E.js",
    "content": "require('./angular-mocks');\nmodule.exports = 'ngMockE2E';\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-mocks/package.json",
    "content": "{\n  \"name\": \"angular-mocks\",\n  \"version\": \"1.3.15\",\n  \"description\": \"AngularJS mocks for testing\",\n  \"main\": \"angular-mocks.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/angular/angular.js.git\"\n  },\n  \"keywords\": [\n    \"angular\",\n    \"framework\",\n    \"browser\",\n    \"mocks\",\n    \"testing\",\n    \"client-side\"\n  ],\n  \"author\": \"Angular Core Team <angular-core+npm@google.com>\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/angular/angular.js/issues\"\n  },\n  \"homepage\": \"http://angularjs.org\"\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-moment/.bower.json",
    "content": "{\n  \"name\": \"angular-moment\",\n  \"version\": \"0.10.0\",\n  \"description\": \"Moment.JS directives & filters for AngularJS (timeago alternative)\",\n  \"author\": \"Uri Shaked\",\n  \"license\": \"MIT\",\n  \"homepage\": \"http://github.com/urish/angular-moment\",\n  \"main\": \"./angular-moment.js\",\n  \"ignore\": [],\n  \"dependencies\": {\n    \"angular\": \">=1.2.0 <1.5.0\",\n    \"moment\": \">=2.8.0 <2.11.0\"\n  },\n  \"devDependencies\": {\n    \"angular-mocks\": \"1.3.x\",\n    \"moment-timezone\": \"0.3.1\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/urish/angular-moment.git\"\n  },\n  \"_release\": \"0.10.0\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"0.10.0\",\n    \"commit\": \"96d89aab944112e51177e06d4cd82a8b9306e656\"\n  },\n  \"_source\": \"git://github.com/urish/angular-moment.git\",\n  \"_target\": \"0.10.0\",\n  \"_originalSource\": \"angular-moment\",\n  \"_direct\": true\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-moment/.editorconfig",
    "content": "# EditorConfig helps developers define and maintain consistent\n# coding styles between different editors and IDEs\n# editorconfig.org\n\nroot = true\n\n[*]\n\n# Change these settings to your own preference\nindent_style = tab\nindent_size = 4\n\n# We recommend you to keep these unchanged\nend_of_line = lf\ncharset = utf-8\ntrim_trailing_whitespace = true\ninsert_final_newline = true\n\n[{package.json,bower.json}]\nindent_style=space\nindent_size=2\n\n[*.md]\ntrim_trailing_whitespace = false\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-moment/.gitignore",
    "content": "/.idea\n/bower_components\n/node_modules\n/coverage"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-moment/.jshintrc",
    "content": "{\n\t\"node\": true,\n\t\"browser\": true,\n\t\"esnext\": true,\n\t\"bitwise\": true,\n\t\"camelcase\": true,\n\t\"curly\": true,\n\t\"eqeqeq\": true,\n\t\"immed\": true,\n\t\"indent\": 2,\n\t\"latedef\": true,\n\t\"newcap\": true,\n\t\"noarg\": true,\n\t\"quotmark\": \"single\",\n\t\"regexp\": true,\n\t\"undef\": true,\n\t\"unused\": true,\n\t\"strict\": true,\n\t\"trailing\": true,\n\t\"smarttabs\": true,\n\t\"maxdepth\": 2,\n\t\"maxcomplexity\": 10,\n\t\"globals\": {\n\t\t\"angular\": false\n\t}\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-moment/.npmignore",
    "content": ".idea\nbower_components\nnode_modules\ncoverage\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-moment/.travis.yml",
    "content": "language: node_js\nnode_js:\n  - \"0.10\"\nbefore_script:\n  - npm run bower\nafter_success:\n  - cat ./coverage/*/lcov.info | ./node_modules/coveralls/bin/coveralls.js\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-moment/CHANGELOG.md",
    "content": "# Changelog\n\n## 0.10.0 - 2015-04-10\n- Breaking change: removed one-time binding for `am-time-ago` in favor of AngularJS 1.3's one time binding ([#122](https://github.com/urish/angular-moment/issues/122))\n- Remove support for AngularJS 1.0.x and 1.1.x.\n- Support moment.js v2.10.x\n- Support for displaying full dates in `am-time-ago` (see [#75](https://github.com/urish/angular-moment/issues/75)) \n- Support Angular Core's style CommonJS standard ([#123](https://github.com/urish/angular-moment/pull/123), contributed by [seanhealy](https://github.com/seanhealy))\n- Added an optional timezone parameter to amDateFormat ([#90](https://github.com/urish/angular-moment/pull/90), contributed by [robertbrooker](https://github.com/robertbrooker))\n\n## 0.9.2 - 2015-03-17\n- Critical fix: npm install angular-moment fails ([#121](https://github.com/urish/angular-moment/issues/121))\n\n## 0.9.1 - 2015-03-17\n- Add support for locale strings customization ([#102](https://github.com/urish/angular-moment/pull/102), contributed by [vosi](https://github.com/vosi))\n- Add `amDifference` filter ([#120](https://github.com/urish/angular-moment/pull/120), contributed by [ajhodges](https://github.com/ajhodges))\n- Support for changing the timezone via `amMoment.changeTimezone()` ([#92](https://github.com/urish/angular-moment/issues/92))\n- Support for AngularJS 1.4.x\n- Remove explicit module name for RequireJS ([#112](https://github.com/urish/angular-moment/pull/112), contributed by [WilliamCarter](https://github.com/WilliamCarter))\n\n## 0.9.0 - 2015-01-11\n- Support moment.js v2.9.0. See [here](https://gist.github.com/ichernev/0c9a9b49951111a27ce7) for changelog.\n- Removed support for older moment.js versions. Only 2.8.0 and newer versions are now supported.\n- Removed deprecated method: `amMoment.changeLanguage()`. Use `amMoment.changeLocale()` instead.\n- Removed deprecated event: `amMoment:languageChange`. Listen for `amMoment:localeChange` instead.\n- Filters are now stateful by default (fixes [#97](https://github.com/urish/angular-moment/issues/97)).\n- The project is now available on [NuGet](https://www.nuget.org/packages/angular-moment/) ([#99](https://github.com/urish/angular-moment/pull/99), contributed by [markvp](https://github.com/markvp)).\n\n## 0.8.3 - 2014-12-08\n- `amTimeAgo` filter ([#96](https://github.com/urish/angular-moment/pull/96), contributed by [maxklenk](https://github.com/maxklenk))\n- Show formatted time as element title ([#78](https://github.com/urish/angular-moment/pull/78), contributed by [ctesene](https://github.com/ctesene))\n- Support commonjs and browserify ([#95](https://github.com/urish/angular-moment/pull/95), contributed by [Pencroff](https://github.com/Pencroff))\n- SystemJS Loader support ([#85](https://github.com/urish/angular-moment/pull/85), contributed by [capaj](https://github.com/capaj))\n\n## 0.8.2 - 2014-09-07\n- `amMoment.changeLanguage()` was deprecated in favor of `amMoment.changeLocale()` (following [a change](http://momentjs.com/docs/#/i18n/changing-locale/) introduced in moment v2.8.1)\n- Bugfix: changing the locale emitted a deprecation warning (see [#76](https://github.com/urish/angular-moment/issues/76) for details).\n\n## 0.8.1 - 2014-09-01\n- Support moment.js v2.8.0. See [here](https://gist.github.com/ichernev/ac3899324a5fa6c8c9b4) for changelog.\n- Support moment-timezone v0.2.1. See [here](https://github.com/moment/moment-timezone/blob/develop/changelog.md#021-2014-08-02) for changelog.\n- Bugfix: `updateTime()` is called too often for future dates ([#73](https://github.com/urish/angular-moment/issues/73)) \n\n## 0.8.0 - 2014-07-26\n- Generate source map for the minified version ([#50](https://github.com/urish/angular-moment/issues/50))\n- Add support HTML `<time>` element - set the `datetime` attribute ([#41](https://github.com/urish/angular-moment/pull/41), contributed by [gsklee](https://github.com/gsklee))\n- Add default format (angularMomentConfig.format config property) ([#52](https://github.com/urish/angular-moment/pull/52), contributed by [otang](https://github.com/otang))\n- Add `serverTime` configuration option ([#53](https://github.com/urish/angular-moment/pull/53), contributed by [Facundo Pedrazzini](https://github.com/Facuu7))\n- Implement one-time binding for `am-time-ago` ([#54](https://github.com/urish/angular-moment/pull/54), contributed by [Ephi Gabay](https://github.com/ephigabay))\n- Support moment.js v2.7.0. See [here](https://gist.github.com/ichernev/b0a3d456d5a84c9901d7) for changelog.\n- Support moment-timezone v0.1.0. See [here](https://github.com/moment/moment-timezone/blob/develop/changelog.md#010-2014-06-23) for changelog.\n\n## 0.7.1 - 2014-05-16\n- bugfix: Preprocess set in configuration not used by filters ([#49](https://github.com/urish/angular-moment/issues/49))\n\n## 0.7.0 - 2014-04-19\n- Use `moment` as an injectable constant instead of relying on `$window.moment` ([#35](https://github.com/urish/angular-moment/pull/35), contributed by [just-boris](https://github.com/just-boris))\n- Require.js support ([#36](https://github.com/urish/angular-moment/issues/36))\n- Add am-preprocess attribute to support unix and utc timestamps ([#38](https://github.com/urish/angular-moment/pull/38), contributed by [jspaper](https://github.com/jspaper))\n- NGDoc documentation ([#40](https://github.com/urish/angular-moment/issues/40))\n- Enable support for AngularJS 1.3.x in bower.json\n- Support moment.js v2.6.0. See [here](https://gist.github.com/ichernev/10544682) for changelog.\n\n## 0.6.2 - 2014-02-05\n- Add `amMoment` service with a `changeLanguage()` method ([#32](https://github.com/urish/angular-moment/pull/32), contributed by [Ornthalas](https://github.com/Ornthalas))\n- bower.json: Move `moment-timezone` to devDependencies (fixes [#34](https://github.com/urish/angular-moment/issues/34))\n\n## 0.6.1 - 2014-01-31\n- Add optional timezone support to `amCalendar` and `amDateFormat` filters ([#27](https://github.com/urish/angular-moment/pull/27), contributed by [kayhadrin](https://github.com/kayhadrin))\n- Happy Year of the Horse!\n\n## 0.6.0 - 2013-12-24\n\n- Add optional `am-without-suffix` attribute to `am-time-ago` ([#22](https://github.com/urish/angular-moment/issues/22), contributed by [hramaker](https://github.com/hramaker))\n- Support moment.js v2.5.0. See [here](https://gist.github.com/ichernev/8104451) for changelog.\n- Merry Christmas!\n\n## 0.5.2 - 2013-11-17\n\n- Add `amCalendar` filter ([#24](https://github.com/urish/angular-moment/issues/24), contributed by [OndraM](https://github.com/OndraM))\n\n## 0.5.1 - 2013-11-09\n\n- Add `amDuration` filter ([#20](https://github.com/urish/angular-moment/issues/20), contributed by [gabrielstuff](https://github.com/gabrielstuff))\n\n## 0.5.0 - 2013-11-02\n\n- Use $window.setTimeout instead of $timeout, fixes protractor synchronization issue ([#19](https://github.com/urish/angular-moment/issues/19))\n\n## 0.4.2 - 2013-10-30\n\n- Add settings constant for configuring moment.js withoutSuffix-option ([#18](https://github.com/urish/angular-moment/pull/18))\n\n## 0.4.1 - 2013-10-27\n\n- Support moment.js v2.4.0. See [here](https://github.com/moment/moment/#240) for changelog.\n\n## 0.4.0 - 2013-10-08\n\n- Support moment.js v2.3.0. See [here](https://gist.github.com/ichernev/6864354) for possibly breaking changes.\n\n## 0.3.0 - 2013-10-07\n\n- Bugfix: `am-time-ago` support for empty string ([#15](https://github.com/urish/angular-moment/issues/15))\n- Behavior change: `am-time-ago` will only change the text once there is date\n\n## 0.2.2 - 2013-09-29\n\n- Add support for passing unix timestamp as a string to `amDateFormat` filter ([#14](https://github.com/urish/angular-moment/issues/14))\n\n## 0.2.1 - 2013-09-13\n\n- Fix an issue with tests failing on a different timezone\n- Support moment 2.2.x, AngularJS 1.2\n\n## 0.2.0 - 2013-08-22\n\n- Add optional `am-format` attribute to `am-time-ago` ([#11](https://github.com/urish/angular-moment/issues/11))\n- Add new `amDateFormat` filter ([#12](https://github.com/urish/angular-moment/issues/12))\n- Add changelog file\n\n## 0.1.1 - 2013-06-08\n\n- Fix to support iOS ([#2](https://github.com/urish/angular-moment/pull/2), contributed by [giuseppeaiello](https://github.com/giuseppeaiello))\n\n## 0.1.0 - 2013-05-27\n\n- Initial release\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-moment/CONTRIBUTING.md",
    "content": "# Contributing Guide\n\nContributing to `angular-moment` is fairly easy. This document shows you how to\nget the project, run all provided tests and generate a production ready build.\n\nIt also covers provided grunt tasks, that help you developing on `angular-moment`.\n\n## Dependencies\n\nTo make sure, that the following instructions work, please install the following dependencies\non you machine:\n\n- Node.js\n- npm\n- Git\n\n## Installation\n\nTo get the source of `angular-moment` clone the git repository via:\n\n`git clone https://github.com/urish/angular-moment`\n\nThis will clone the complete source to your local machine. Navigate to the project folder\nand install all needed dependencies via **npm**:\n\n`npm install`\n\nTo complete the installation, install the frontend (bower) dependencies by running the \nfollowing command:\n\n`npm run bower`\n\nWell done! angular-moment is now installed and ready to be built.\n\n## Building\n\n`angular-moment` comes with a few **grunt tasks** which help you to automate\nthe development process. The following grunt tasks are provided:\n\n#### grunt test\n\n`npm test` executes (as you might thought) the unit tests, which are located\nin `tests.js`. The task uses the **karma** test runner to executes the tests with\nthe **jasmine testing framework**. This task also checks the coding using **jshint**.\n\n#### grunt build\n\n`npm run build` updates the minified version of the code (angular-moment.min.js). It also\nchecks the code using **jshint**.\n\n## Contributing/Submitting changes\n\n- Checkout a new branch based on `master` and name it to what you intend to do:\n  - Example:\n    ````\n    $ git checkout -b BRANCH_NAME\n    ````\n  - Use one branch per fix/feature\n- Make your changes\n  - Make sure to provide a spec for unit tests (in `tests.js`)\n  - Run your tests with `npm test`\n  - When all tests pass, everything's fine\n- Commit your changes\n  - Please provide a git message which explains what you've done\n  - Commit to the forked repository\n- Make a pull request\n\nIf you follow these instructions, your PR will land pretty safety in the main repo!\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-moment/Gruntfile.js",
    "content": "/* License: MIT.\n * Copyright (C) 2013, 2014, 2015, Uri Shaked.\n */\n\n'use strict';\n\nmodule.exports = function (grunt) {\n\trequire('load-grunt-tasks')(grunt);\n\n\tgrunt.initConfig({\n\t\tkarma: {\n\t\t\tunit: {\n\t\t\t\tconfigFile: 'karma.conf.js',\n\t\t\t\tsingleRun: true\n\t\t\t}\n\t\t},\n\t\tjshint: {\n\t\t\toptions: {\n\t\t\t\tjshintrc: '.jshintrc'\n\t\t\t},\n\t\t\tall: [\n\t\t\t\t'Gruntfile.js',\n\t\t\t\t'angular-moment.js',\n\t\t\t\t'tests.js'\n\t\t\t]\n\t\t},\n\t\tuglify: {\n\t\t\tdist: {\n\t\t\t\toptions: {\n\t\t\t\t\tsourceMap: true\n\t\t\t\t},\n\t\t\t\tfiles: {\n\t\t\t\t\t'angular-moment.min.js': 'angular-moment.js'\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tngdocs: {\n\t\t\toptions: {\n\t\t\t\tstartPage: '/',\n\t\t\t\ttitle: false,\n\t\t\t\thtml5Mode: false\n\t\t\t},\n\t\t\tapi: {\n\t\t\t\tsrc: 'angular-moment.js',\n\t\t\t\ttitle: 'angular-moment API Documentation'\n\t\t\t}\n\t\t}\n\t});\n\n\tgrunt.registerTask('test', [\n\t\t'jshint',\n\t\t'karma'\n\t]);\n\n\tgrunt.registerTask('build', [\n\t\t'jshint',\n\t\t'uglify'\n\t]);\n\n\tgrunt.registerTask('default', ['build']);\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-moment/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2013-2015 Uri Shaked and contributors\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-moment/README.md",
    "content": "angular-moment\n==============\n\nAngularJS directive and filters for [Moment.JS](http://www.momentjs.com).\n\nCopyright (C) 2013, 2014, 2015, Uri Shaked <uri@urish.org>\n\n[![Build Status](https://travis-ci.org/urish/angular-moment.png?branch=master)](https://travis-ci.org/urish/angular-moment)\n[![Coverage Status](https://coveralls.io/repos/urish/angular-moment/badge.png)](https://coveralls.io/r/urish/angular-moment)\n\nInstallation\n------------\n\nYou can choose your preferred method of installation:\n* Through bower: `bower install angular-moment --save`\n* Through npm: `npm install angular-moment --save`\n* Through NuGet: `Install-Package angular-moment`\n* From a CDN: [jsDelivr](https://cdn.jsdelivr.net/angular.moment/0.10.0/angular-moment.min.js) or [CDNJS](https://cdnjs.cloudflare.com/ajax/libs/angular-moment/0.10.0/angular-moment.min.js)\n* Download from github: [angular-moment.min.js](https://raw.github.com/urish/angular-moment/master/angular-moment.min.js)\n\nUsage\n-----\nInclude both moment.js and angular-moment.js in your application.\n\n```html\n<script src=\"components/moment/moment.js\"></script>\n<script src=\"components/angular-moment/angular-moment.js\"></script>\n```\n\nAdd the module `angularMoment` as a dependency to your app module:\n\n```js\nvar myapp = angular.module('myapp', ['angularMoment']);\n```\n\nIf you need internationalization support, load specified moment.js locale file first:\n\n```html\n<script src=\"components/moment/locale/de.js\"></script>\n```\n\nThen call the `amMoment.changeLocale()` method (e.g. inside your app's run() callback):\n\n```js\nmyapp.run(function(amMoment) {\n\tamMoment.changeLocale('de');\n});\n```\n\n### Configuration\n\nParameter `preprocess`(e.g: `unix`, `utc`) would pre-execute before.\n\n```js\nangular.module('myapp').constant('angularMomentConfig', {\n\tpreprocess: 'unix', // optional\n\ttimezone: 'Europe/London' // optional\n});\n```\n\n### Timeago directive\nUse am-time-ago directive to format your relative timestamps. For example:\n\n```html\n<span am-time-ago=\"message.time\"></span>\n<span am-time-ago=\"message.time\" am-preprocess=\"unix\"></span>\n```\n\nangular-moment will dynamically update the span to indicate how much time\npassed since the message was created. So, if your controller contains the following\ncode:\n```js\n$scope.message = {\n   text: 'hello world!',\n   time: new Date()\n};\n```\n\nThe user will initially see \"a few seconds ago\", and about a minute\nafter the span will automatically update with the text \"a minute ago\",\netc.\n\n### amDateFormat filter\nFormat dates using moment.js format() method. Example:\n\n```html\n<span>{{message.time | amDateFormat:'dddd, MMMM Do YYYY, h:mm:ss a'}}</span>\n```\n\nThis snippet will format the given time as \"Monday, October 7th 2013, 12:36:29 am\".\n\nFor more information about Moment.JS formatting options, see the\n[docs for the format() function](http://momentjs.com/docs/#/displaying/format/).\n\n### amCalendar filter\n\nFormat dates using moment.js calendar() method. Example:\n\n```html\n<span>{{message.time | amCalendar}}</span>\n```\n\nThis snippet will format the given time as e.g. \"Today 2:30 AM\" or \"Last Monday 2:30 AM\" etc..\n\nFor more information about Moment.JS calendar time format, see the\n[docs for the calendar() function](http://momentjs.com/docs/#/displaying/calendar-time/).\n\n### amDifference filter\n\nGet the difference between two dates in milliseconds.\nParameters are date, units and usePrecision. Date defaults to current date. Example:\n\n```html\n<span>Scheduled {{message.createdAt | amDifference : null : 'days' }} days from now</span>\n```\n\nThis snippet will return the number of days between the current date and the date filtered.\n\nFor more information about Moment.JS difference function, see the\n[docs for the diff() function](http://momentjs.com/docs/#/displaying/difference/).\n\n### Time zone support\n\nThe `amDateFormat` and `amCalendar` filters can be configured to display dates aligned\nto a specific timezone. You can configure the timezone using the following syntax:\n\n```js\nangular.module('myapp').constant('angularMomentConfig', {\n    timezone: 'Name of Timezone' // e.g. 'Europe/London'\n});\n```\n\nRemember to include `moment-timezone.js` in your project, otherwise the custom timezone\nfunctionality will not be available. You will also need to include a timezone data file that\nyou can create using the [Timezone Data Builder](http://momentjs.com/timezone/data/)\nor simply download from [here](https://rawgithub.com/qw4n7y/7282780/raw/6ae3b334b295f93047e8f3ad300db6bc4387e235/moment-timezone-data.js).\n\nLicense\n----\n\nReleased under the terms of the [MIT License](LICENSE).\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-moment/angular-moment.nuspec",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<package xmlns=\"http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd\">\n    <metadata>\n        <id>angular-moment</id>\n        <version>0.10.0</version>\n        <title>Angular Moment</title>\n        <authors>urish</authors>\n        <projectUrl>https://github.com/urish/angular-moment</projectUrl>\n        <requireLicenseAcceptance>false</requireLicenseAcceptance>\n        <description>Moment.JS directives for AngularJS (timeago and more)</description>\n        <summary>Moment.JS directives for AngularJS (timeago and more).</summary>\n        <releaseNotes />\n        <copyright />\n        <dependencies>\n            <dependency id=\"Moment.js\" version=\"2.10.2\" />\n        </dependencies>\n        <tags>AngularJS MomentJS Moment</tags>\n    </metadata>\n    <files>\n        <file src=\"angular-moment.js\" target=\"content\\Scripts\\angular-moment.js\" />\n        <file src=\"angular-moment.min.js\" target=\"content\\Scripts\\angular-moment.min.js\" />\n        <file src=\"angular-moment.min.js.map\" target=\"content\\Scripts\\angular-moment.min.js.map\" />\n    </files>\n</package>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-moment/bower.json",
    "content": "{\n\t\"name\": \"angular-moment\",\n\t\"version\": \"0.10.0\",\n\t\"description\": \"Moment.JS directives & filters for AngularJS (timeago alternative)\",\n\t\"author\": \"Uri Shaked\",\n\t\"license\": \"MIT\",\n\t\"homepage\": \"http://github.com/urish/angular-moment\",\n\t\"main\": \"./angular-moment.js\",\n\t\"ignore\": [\n\t],\n\t\"dependencies\": {\n\t\t\"angular\": \">=1.2.0 <1.5.0\",\n\t\t\"moment\": \">=2.8.0 <2.11.0\"\n\t},\n\t\"devDependencies\": {\n\t\t\"angular-mocks\": \"1.3.x\",\n\t\t\"moment-timezone\": \"0.3.1\"\n\t},\n\t\"repository\": {\n\t\t\"type\": \"git\",\n\t\t\"url\": \"git://github.com/urish/angular-moment.git\"\n\t}\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-moment/karma.conf.js",
    "content": "/* License: MIT.\n * Copyright (C) 2013, 2014, 2015, Uri Shaked.\n */\n\n'use strict';\n\nmodule.exports = function (config) {\n\tconfig.set({\n\t\tbasePath: '',\n\t\tframeworks: ['jasmine'],\n\t\tlogLevel: config.LOG_INFO,\n\t\tbrowsers: ['PhantomJS'],\n\t\tautoWatch: true,\n\t\treporters: ['dots', 'coverage'],\n\t\tfiles: [\n\t\t\t'bower_components/angular/angular.js',\n\t\t\t'bower_components/moment/moment.js',\n\t\t\t'bower_components/moment/{locale,lang}/fr.js',\n\t\t\t'bower_components/moment-timezone/moment-timezone.js',\n\t\t\t'angular-moment.js',\n\t\t\t'bower_components/angular-mocks/angular-mocks.js',\n\n\t\t\t'tests.js'\n\t\t],\n\t\tpreprocessors: {\n\t\t\t'angular-moment.js': 'coverage'\n\t\t},\n\t\tcoverageReporter: {\n\t\t\ttype: 'lcov',\n\t\t\tdir: 'coverage/'\n\t\t}\n\t});\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-moment/package.json",
    "content": "{\n  \"name\": \"angular-moment\",\n  \"version\": \"0.10.0\",\n  \"main\": \"angular-moment.js\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"http://github.com/urish/angular-moment.git\"\n  },\n  \"dependencies\": {\n    \"moment\": \">=2.8.0 <2.11.0\"\n  },\n  \"devDependencies\": {\n    \"bower\": \"^1.3.12\",\n    \"coveralls\": \"~2.11.0\",\n    \"grunt\": \"~0.4.1\",\n    \"grunt-cli\": \"^0.1.13\",\n    \"grunt-contrib-jshint\": \"~0.11.0\",\n    \"grunt-contrib-uglify\": \"0.8.1\",\n    \"grunt-karma\": \"~0.10.1\",\n    \"grunt-ngdocs\": \"^0.2.7\",\n    \"karma\": \"~0.12.0\",\n    \"karma-coverage\": \"~0.2.0\",\n    \"karma-jasmine\": \"~0.3.5\",\n    \"karma-phantomjs-launcher\": \"~0.1.1\",\n    \"load-grunt-tasks\": \"3.1.0\"\n  },\n  \"engines\": {\n    \"node\": \">=0.10.0\"\n  },\n  \"scripts\": {\n    \"bower\": \"node_modules/.bin/bower install\",\n    \"test\": \"node_modules/.bin/grunt test\",\n    \"build\": \"node_modules/.bin/grunt build\"\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-moment/tests.js",
    "content": "/* License: MIT.\n * Copyright (C) 2013, 2014, 2015, Uri Shaked.\n */\n\n/* global describe, inject, module, beforeEach, afterEach, it, expect, spyOn, jasmine */\n\n'use strict';\n\ndescribe('module angularMoment', function () {\n\tvar $rootScope, $compile, $window, $filter, moment, amTimeAgoConfig, originalTimeAgoConfig, angularMomentConfig,\n\t\toriginalAngularMomentConfig, amMoment;\n\n\tbeforeEach(module('angularMoment'));\n\n\tbeforeEach(inject(function ($injector) {\n\t\t$rootScope = $injector.get('$rootScope');\n\t\t$compile = $injector.get('$compile');\n\t\t$window = $injector.get('$window');\n\t\t$filter = $injector.get('$filter');\n\t\tmoment = $injector.get('moment');\n\t\tamMoment = $injector.get('amMoment');\n\t\tamTimeAgoConfig = $injector.get('amTimeAgoConfig');\n\t\tangularMomentConfig = $injector.get('angularMomentConfig');\n\t\toriginalTimeAgoConfig = angular.copy(amTimeAgoConfig);\n\t\toriginalAngularMomentConfig = angular.copy(angularMomentConfig);\n\t\t(moment.locale || moment.lang)('en');\n\t\tmoment.tz.add('UTC|UTC|0|0|');\n\t\tmoment.tz.add('Pacific/Tahiti|LMT TAHT|9W.g a0|01|-2joe1.I');\n\t}));\n\n\tafterEach(function () {\n\t\tangular.copy(originalTimeAgoConfig, amTimeAgoConfig);\n\t\tangular.copy(originalAngularMomentConfig, angularMomentConfig);\n\t\tjasmine.clock().uninstall();\n\t});\n\n\n\tdescribe('am-time-ago directive', function () {\n\t\tit('should change the text of the element to \"a few seconds ago\" when given unix timestamp', function () {\n\t\t\t$rootScope.testDate = new Date().getTime() / 1000;\n\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\" am-preprocess=\"unix\"></span>');\n\t\t\telement = $compile(element)($rootScope);\n\t\t\t$rootScope.$digest();\n\t\t\texpect(element.text()).toBe('a few seconds ago');\n\t\t});\n\n\t\tit('should change the text of the element to \"a few seconds ago\" when given current time', function () {\n\t\t\t$rootScope.testDate = new Date();\n\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\"></span>');\n\t\t\telement = $compile(element)($rootScope);\n\t\t\t$rootScope.$digest();\n\t\t\texpect(element.text()).toBe('a few seconds ago');\n\t\t});\n\n\t\tit('should change the text of the div to \"3 minutes ago\" when given a date 3 minutes ago', function () {\n\t\t\t$rootScope.testDate = new Date(new Date().getTime() - 3 * 60 * 1000);\n\t\t\tvar element = angular.element('<div am-time-ago=\"testDate\"></div>');\n\t\t\telement = $compile(element)($rootScope);\n\t\t\t$rootScope.$digest();\n\t\t\texpect(element.text()).toBe('3 minutes ago');\n\t\t});\n\n\t\tit('should change the text of the div to \"2 hours ago\" when given a date 2 hours ago', function () {\n\t\t\t$rootScope.testDate = new Date(new Date().getTime() - 2 * 60 * 60 * 1000);\n\t\t\tvar element = angular.element('<div am-time-ago=\"testDate\"></div>');\n\t\t\telement = $compile(element)($rootScope);\n\t\t\t$rootScope.$digest();\n\t\t\texpect(element.text()).toBe('2 hours ago');\n\t\t});\n\n\t\tit('should change the text of the div to \"one year ago\" when given a date one year ago', function () {\n\t\t\tvar today = new Date();\n\t\t\t$rootScope.testDate = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate());\n\t\t\tvar element = angular.element('<div am-time-ago=\"testDate\"></div>');\n\t\t\telement = $compile(element)($rootScope);\n\t\t\t$rootScope.$digest();\n\t\t\texpect(element.text()).toBe('a year ago');\n\t\t});\n\n\t\tit('should parse correctly numeric dates as milliseconds since the epoch', function () {\n\t\t\t$rootScope.testDate = new Date().getTime();\n\t\t\tvar element = angular.element('<div am-time-ago=\"testDate\"></div>');\n\t\t\telement = $compile(element)($rootScope);\n\t\t\t$rootScope.$digest();\n\t\t\texpect(element.text()).toBe('a few seconds ago');\n\t\t});\n\n\t\tit('should update the value if date changes on scope', function () {\n\t\t\tvar today = new Date();\n\t\t\t$rootScope.testDate = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate()).getTime();\n\t\t\tvar element = angular.element('<div am-time-ago=\"testDate\"></div>');\n\t\t\telement = $compile(element)($rootScope);\n\t\t\t$rootScope.$digest();\n\t\t\texpect(element.text()).toBe('a year ago');\n\t\t\t$rootScope.testDate = new Date();\n\t\t\t$rootScope.$digest();\n\t\t\texpect(element.text()).toBe('a few seconds ago');\n\t\t});\n\n\t\tit('should update the span text as time passes', function (done) {\n\t\t\t$rootScope.testDate = new Date(new Date().getTime() - 44000);\n\t\t\tvar element = angular.element('<div am-time-ago=\"testDate\"></div>');\n\t\t\telement = $compile(element)($rootScope);\n\t\t\t$rootScope.$digest();\n\t\t\texpect(element.text()).toBe('a few seconds ago');\n\n\t\t\tvar waitsInterval = setInterval(function () {\n\t\t\t\tif (new Date().getTime() - $rootScope.testDate.getTime() < 45000) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tclearInterval(waitsInterval);\n\t\t\t\t$rootScope.$digest();\n\t\t\t\texpect(element.text()).toBe('a minute ago');\n\t\t\t\tdone();\n\t\t\t}, 50);\n\t\t});\n\n\t\tit('should schedule the update timer to one hour ahead for date in the far future (#73)', function () {\n\t\t\t$rootScope.testDate = new Date(new Date().getTime() + 86400000);\n\t\t\tjasmine.clock().install();\n\t\t\tspyOn($window, 'setTimeout');\n\t\t\tvar element = angular.element('<div am-time-ago=\"testDate\"></div>');\n\t\t\telement = $compile(element)($rootScope);\n\t\t\t$rootScope.$digest();\n\t\t\texpect($window.setTimeout).toHaveBeenCalledWith(jasmine.any(Function), 3600000);\n\t\t});\n\n\t\tdescribe('bindonce', function () {\n\t\t\tit('should change the text of the div to \"3 minutes ago\" when given a date 3 minutes ago with one time binding', function () {\n\t\t\t\t$rootScope.testDate = new Date(new Date().getTime() - 3 * 60 * 1000);\n\t\t\t\tvar element = angular.element('<div am-time-ago=\"::testDate\"></div>');\n\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t$rootScope.$digest();\n\t\t\t\texpect(element.text()).toBe('3 minutes ago');\n\t\t\t});\n\n\t\t\tit('should parse correctly numeric dates as milliseconds since the epoch with one time binding', function () {\n\t\t\t\t$rootScope.testDate = new Date().getTime();\n\t\t\t\tvar element = angular.element('<div am-time-ago=\"::testDate\"></div>');\n\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t$rootScope.$digest();\n\t\t\t\texpect(element.text()).toBe('a few seconds ago');\n\t\t\t});\n\n\t\t\tit('should not update the value if date changes on scope when using one time binding', function () {\n\t\t\t\tvar today = new Date();\n\t\t\t\t$rootScope.testDate = new Date(today.getFullYear() - 1, today.getMonth(), today.getDate()).getTime();\n\t\t\t\tvar element = angular.element('<div am-time-ago=\"::testDate\"></div>');\n\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t$rootScope.$digest();\n\t\t\t\texpect(element.text()).toBe('a year ago');\n\t\t\t\t$rootScope.testDate = new Date();\n\t\t\t\t$rootScope.$digest();\n\t\t\t\texpect(element.text()).toBe('a year ago');\n\t\t\t});\n\t\t});\n\n\t\tit('should handle undefined data', function () {\n\t\t\t$rootScope.testDate = null;\n\t\t\tvar element = angular.element('<div am-time-ago=\"testDate\"></div>');\n\t\t\telement = $compile(element)($rootScope);\n\t\t\tvar digest = function () {\n\t\t\t\t$rootScope.$digest();\n\t\t\t};\n\t\t\texpect(digest).not.toThrow();\n\t\t});\n\n\t\tit('should remove the element text and cancel the timer when an empty string is given (#15)', function () {\n\t\t\t$rootScope.testDate = new Date().getTime();\n\t\t\tvar element = angular.element('<div am-time-ago=\"testDate\"></div>');\n\t\t\telement = $compile(element)($rootScope);\n\t\t\t$rootScope.$digest();\n\t\t\texpect(element.text()).toBe('a few seconds ago');\n\t\t\t$rootScope.testDate = '';\n\t\t\tspyOn($window, 'clearTimeout').and.callThrough();\n\t\t\t$rootScope.$digest();\n\t\t\texpect($window.clearTimeout).toHaveBeenCalled();\n\t\t\texpect(element.text()).toBe('');\n\t\t});\n\n\t\tit('should not change the contents of the element until a date is given', function () {\n\t\t\t$rootScope.testDate = null;\n\t\t\tvar element = angular.element('<div am-time-ago=\"testDate\">Initial text</div>');\n\t\t\telement = $compile(element)($rootScope);\n\t\t\t$rootScope.$digest();\n\t\t\texpect(element.text()).toBe('Initial text');\n\t\t\t$rootScope.testDate = new Date().getTime();\n\t\t\t$rootScope.$digest();\n\t\t\texpect(element.text()).toBe('a few seconds ago');\n\t\t});\n\n\t\tit('should cancel the timer when the scope is destroyed', function () {\n\t\t\tvar scope = $rootScope.$new();\n\t\t\t$rootScope.testDate = new Date();\n\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\"></span>');\n\t\t\telement = $compile(element)(scope);\n\t\t\t$rootScope.$digest();\n\t\t\tspyOn($window, 'clearTimeout').and.callThrough();\n\t\t\tscope.$destroy();\n\t\t\texpect($window.clearTimeout).toHaveBeenCalled();\n\t\t});\n\n\t\tit('should generate a time string without suffix when configured to do so', function () {\n\t\t\tamTimeAgoConfig.withoutSuffix = true;\n\t\t\t$rootScope.testDate = new Date();\n\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\"></span>');\n\t\t\telement = $compile(element)($rootScope);\n\t\t\t$rootScope.$digest();\n\t\t\texpect(element.text()).toBe('a few seconds');\n\t\t});\n\n\t\tit('should generate update the text following a locale change via amMoment.changeLocale() method', function () {\n\t\t\t$rootScope.testDate = new Date();\n\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\"></span>');\n\t\t\telement = $compile(element)($rootScope);\n\t\t\t$rootScope.$digest();\n\t\t\texpect(element.text()).toBe('a few seconds ago');\n\t\t\tamMoment.changeLocale('fr');\n\t\t\texpect(element.text()).toBe('il y a quelques secondes');\n\t\t});\n\n\t\tit('should update the `datetime` attr if applied to a TIME element', function () {\n\t\t\t$rootScope.testDate = Date.UTC(2012, 8, 20, 15, 20, 12);\n\t\t\tvar element = angular.element('<time am-time-ago=\"testDate\"></span>');\n\t\t\telement = $compile(element)($rootScope);\n\t\t\t$rootScope.$digest();\n\t\t\texpect(element.attr('datetime')).toBe('2012-09-20T15:20:12.000Z');\n\t\t});\n\n\t\tdescribe('setting the element title', function () {\n\t\t\tit('should not set the title attribute of the element to the date by default', function () {\n\t\t\t\t$rootScope.testDate = new Date().getTime() / 1000;\n\t\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\"></span>');\n\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t$rootScope.$digest();\n\t\t\t\texpect(element.attr('title')).toBeUndefined();\n\t\t\t});\n\n\t\t\tit('should not change the title attribute of the element if the element already has a title', function () {\n\t\t\t\tamTimeAgoConfig.titleFormat = 'MMMM Do YYYY, h:mm:ss a';\n\t\t\t\t$rootScope.testDate = new Date().getTime() / 1000;\n\t\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\" title=\"test\"></span>');\n\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t$rootScope.$digest();\n\t\t\t\texpect(element.attr('title')).toBe('test');\n\t\t\t});\n\n\t\t\tit('should set the title attribute of the element to the formatted date as per the config', function () {\n\t\t\t\tamTimeAgoConfig.titleFormat = 'MMMM Do YYYY, h:mm:ss a';\n\t\t\t\t$rootScope.testDate = new Date().getTime() / 1000;\n\t\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\"></span>');\n\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t$rootScope.$digest();\n\t\t\t\tvar testDateWithCustomFormatting = moment($rootScope.testDate).format(amTimeAgoConfig.titleFormat);\n\t\t\t\texpect(element.attr('title')).toBe(testDateWithCustomFormatting);\n\t\t\t});\n\n\t\t\tdescribe('full date support', function () {\n\t\t\t\tit('should display relative time if the date is recent', function () {\n\t\t\t\t\tamTimeAgoConfig.fullDateThreshold = 7;\n\t\t\t\t\t$rootScope.testDate = new Date(new Date().getTime() - 2 * 24 * 60 * 60 * 1000);\n\t\t\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\"></span>');\n\t\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t\t$rootScope.$digest();\n\t\t\t\t\texpect(element.text()).toBe('2 days ago');\n\t\t\t\t});\n\n\t\t\t\tit('should display full time if the date is past the threshold', function () {\n\t\t\t\t\tamTimeAgoConfig.fullDateThreshold = 7;\n\t\t\t\t\t$rootScope.testDate = new Date(2012, 5, 5);\n\t\t\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\"></span>');\n\t\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t\t$rootScope.$digest();\n\t\t\t\t\texpect(element.text()).toMatch(/^2012-06-05T00:00:00\\+\\d\\d:\\d\\d$/);\n\t\t\t\t});\n\n\t\t\t\tit('should display full time using the given format', function () {\n\t\t\t\t\tamTimeAgoConfig.fullDateThreshold = 7;\n\t\t\t\t\tamTimeAgoConfig.fullDateFormat = 'YYYY,DD,MM';\n\t\t\t\t\t$rootScope.testDate = new Date(2010, 1, 8);\n\t\t\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\"></span>');\n\t\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t\t$rootScope.$digest();\n\t\t\t\t\texpect(element.text()).toBe('2010,08,02');\n\t\t\t\t});\n\n\t\t\t\tit('should support changing the full date threshold through attribute', function () {\n\t\t\t\t\t$rootScope.threshold = 7;\n\t\t\t\t\t$rootScope.testDate = new Date(new Date().getTime() - 12 * 24 * 60 * 60 * 1000);\n\t\t\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\" am-full-date-threshold=\"{{threshold}}\"></span>');\n\t\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t\t$rootScope.$digest();\n\t\t\t\t\texpect(element.text()).toBe(moment($rootScope.testDate).format());\n\n\t\t\t\t\t$rootScope.threshold = 20;\n\t\t\t\t\t$rootScope.$digest();\n\t\t\t\t\texpect(element.text()).toBe('12 days ago');\n\t\t\t\t});\n\n\t\t\t\tit('should support setting the full date format through attribute', function () {\n\t\t\t\t\tamTimeAgoConfig.fullDateThreshold = 7;\n\t\t\t\t\t$rootScope.testDate =  new Date(2013, 11, 15);\n\t\t\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\" am-full-date-format=\"YYYY-MM-DD\"></span>');\n\t\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t\t$rootScope.$digest();\n\t\t\t\t\texpect(element.text()).toBe('2013-12-15');\n\t\t\t\t});\n\t\t\t});\n\t\t});\n\n\t\tdescribe('am-without-suffix attribute', function () {\n\t\t\tit('should generate a time string without suffix when true', function () {\n\t\t\t\t$rootScope.testDate = new Date();\n\t\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\" am-without-suffix=\"true\"></span>');\n\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t$rootScope.$digest();\n\t\t\t\texpect(element.text()).toBe('a few seconds');\n\t\t\t});\n\n\t\t\tit('should generate a time string with suffix when false', function () {\n\t\t\t\tamTimeAgoConfig.withoutSuffix = true;\n\t\t\t\t$rootScope.testDate = new Date();\n\t\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\" am-without-suffix=\"false\"></span>');\n\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t$rootScope.$digest();\n\t\t\t\texpect(element.text()).toBe('a few seconds ago');\n\t\t\t});\n\n\t\t\tit('should support expressions', function () {\n\t\t\t\t$rootScope.testDate = new Date();\n\t\t\t\t$rootScope.withSuffix = false;\n\t\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\" am-without-suffix=\"!withSuffix\"></span>');\n\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t$rootScope.$digest();\n\t\t\t\texpect(element.text()).toBe('a few seconds');\n\t\t\t\t$rootScope.withSuffix = true;\n\t\t\t\t$rootScope.$digest();\n\t\t\t\texpect(element.text()).toBe('a few seconds ago');\n\t\t\t});\n\n\t\t\tit('should ignore non-boolean values', function () {\n\t\t\t\t$rootScope.testDate = new Date();\n\t\t\t\t$rootScope.withoutSuffix = 'string';\n\t\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\" am-without-suffix=\"withoutSuffix\"></span>');\n\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t$rootScope.$digest();\n\t\t\t\texpect(element.text()).toBe('a few seconds ago');\n\t\t\t});\n\t\t});\n\n\t\tdescribe('am-format attribute', function () {\n\t\t\tit('should support custom date format', function () {\n\t\t\t\tvar today = new Date();\n\t\t\t\t$rootScope.testDate = today.getFullYear() + '#' + today.getDate() + '#' + today.getMonth();\n\t\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\" am-format=\"YYYY#DD#MM\"></span>');\n\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t$rootScope.$digest();\n\t\t\t\texpect(element.text()).toBe('a month ago');\n\t\t\t});\n\n\t\t\tit('should support angular expressions in date format', function () {\n\t\t\t\tvar today = new Date();\n\t\t\t\t$rootScope.testDate = today.getMonth() + '@' + today.getFullYear() + '@' + today.getDate();\n\t\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\" am-format=\"{{dateFormat}}\"></span>');\n\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t$rootScope.$digest();\n\t\t\t\t$rootScope.dateFormat = 'MM@YYYY@DD';\n\t\t\t\t$rootScope.$digest();\n\t\t\t\texpect(element.text()).toBe('a month ago');\n\t\t\t});\n\t\t});\n\n\t\tdescribe('format config property', function () {\n\t\t\tit('should be used when no `am-format` attribute is found', function () {\n\t\t\t\tangularMomentConfig.format = 'MM@YYYY@DD';\n\t\t\t\tvar today = new Date();\n\t\t\t\t$rootScope.testDate = today.getMonth() + '@' + today.getFullYear() + '@' + today.getDate();\n\t\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\"></span>');\n\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t$rootScope.$digest();\n\t\t\t\texpect(element.text()).toBe('a month ago');\n\t\t\t});\n\n\t\t\tit('should be overridable by `am-format` attribute', function () {\n\t\t\t\tangularMomentConfig.format = 'YYYY@MM@@DD';\n\t\t\t\tvar today = new Date();\n\t\t\t\t$rootScope.testDate = today.getMonth() + '@' + today.getFullYear() + '@' + today.getDate();\n\t\t\t\tvar element = angular.element('<span am-format=\"MM@YYYY@DD\" am-time-ago=\"testDate\"></span>');\n\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t$rootScope.$digest();\n\t\t\t\texpect(element.text()).toBe('a month ago');\n\t\t\t});\n\t\t});\n\n\t\tdescribe('serverTime configuration', function () {\n\t\t\tit('should calculate time ago in respect to the configured server time', function () {\n\t\t\t\tamTimeAgoConfig.serverTime = Date.UTC(2014, 5, 12, 5, 22, 11);\n\t\t\t\t$rootScope.testDate = Date.UTC(2014, 5, 12, 9, 22, 11);\n\t\t\t\tvar element = angular.element('<span am-time-ago=\"testDate\"></span>');\n\t\t\t\telement = $compile(element)($rootScope);\n\t\t\t\t$rootScope.$digest();\n\t\t\t\texpect(element.text()).toBe('in 4 hours');\n\t\t\t});\n\t\t});\n\t});\n\n\tdescribe('amCalendar filter', function () {\n\t\tvar amCalendar;\n\n\t\tbeforeEach(function () {\n\t\t\tamCalendar = $filter('amCalendar');\n\t\t});\n\n\t\tit('should convert today date to calendar form', function () {\n\t\t\tvar today = new Date();\n\t\t\tvar testDate = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 13, 33, 33);\n\t\t\texpect(amCalendar(testDate)).toBe('Today at 1:33 PM');\n\t\t});\n\n\t\tit('should convert date in long past to calendar form', function () {\n\t\t\texpect(amCalendar(new Date(2012, 2, 25, 13, 14, 15))).toBe('03/25/2012');\n\t\t});\n\n\t\tit('should gracefully handle undefined values', function () {\n\t\t\texpect(amCalendar()).toBe('');\n\t\t});\n\n\t\tit('should accept a numeric unix timestamp (milliseconds since the epoch) as input', function () {\n\t\t\texpect(amCalendar(new Date(2012, 0, 22, 4, 46, 54).getTime())).toBe('01/22/2012');\n\t\t});\n\n\t\tit('should respect the configured timezone', function () {\n\t\t\tangularMomentConfig.timezone = 'Pacific/Tahiti';\n\t\t\texpect(amCalendar(Date.UTC(2012, 0, 22, 4, 46, 54))).toBe('01/21/2012');\n\t\t});\n\n\t\tit('should apply the \"utc\" preprocessor when the string \"utc\" is given in the second argument', function () {\n\t\t\texpect(amCalendar(Date.UTC(2012, 0, 22, 0, 0, 0), 'utc')).toBe('01/22/2012');\n\t\t\texpect(amCalendar(Date.UTC(2012, 0, 22, 23, 59, 59), 'utc')).toBe('01/22/2012');\n\t\t});\n\n\t\tit('should apply the \"unix\" preprocessor if angularMomentConfig.preprocess is set to \"unix\" and no preprocessor is given', function () {\n\t\t\tvar unixDate = new Date(1970, 0, 2, 10, 0, 0).getTime() / 1000;\n\t\t\tangularMomentConfig.preprocess = 'unix';\n\t\t\texpect(amCalendar(unixDate)).toBe('01/02/1970');\n\t\t});\n\n\t\tit('should ignore the default preprocessor if we explicity give it null in the second argument', function () {\n\t\t\tvar unixDate = new Date(1970, 0, 1, 10, 0, 0).getTime();\n\t\t\tangularMomentConfig.preprocess = 'unix';\n\t\t\texpect(amCalendar(unixDate, null)).toBe('01/01/1970');\n\t\t});\n\n\t\tit('should gracefully handle the case where timezone is given but moment-timezone is not loaded', function () {\n\t\t\tangularMomentConfig.timezone = 'Pacific/Tahiti';\n\t\t\tvar originalMomentTz = moment.fn.tz;\n\t\t\ttry {\n\t\t\t\tdelete moment.fn.tz;\n\t\t\t\texpect(amCalendar(new Date(2012, 0, 22, 4, 46, 54).getTime())).toBe('01/22/2012');\n\t\t\t} finally {\n\t\t\t\tmoment.fn.tz = originalMomentTz;\n\t\t\t\tmoment.fn.tz = originalMomentTz;\n\t\t\t}\n\t\t});\n\n\t\tit('should return an empty string for invalid input', function () {\n\t\t\texpect(amCalendar('blah blah')).toBe('');\n\t\t});\n\t});\n\n\tdescribe('amDifference filter', function () {\n\t\tvar amDifference;\n\n\t\tbeforeEach(function () {\n\t\t\tamDifference = $filter('amDifference');\n\t\t});\n\n\t\tit('should take the difference of two dates in milliseconds', function () {\n\t\t\tvar today = new Date(2012, 0, 22, 0, 0, 0);\n\t\t\tvar testDate = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 13, 33, 33);\n\t\t\texpect(amDifference(testDate, today)).toBe(48813000);\n\t\t});\n\n\t\tit('should support passing \"years\", \"months\", \"days\", etc as a units parameter', function () {\n\t\t\tvar test = new Date(2012, 0, 22, 4, 46, 54);\n\t\t\tvar testDate1 = new Date(2013, 0, 22, 4, 46, 54);\n\t\t\texpect(amDifference(testDate1, test, 'years')).toBe(1);\n\t\t\tvar testDate2 = new Date(2012, 1, 22, 4, 46, 54);\n\t\t\texpect(amDifference(testDate2, test, 'months')).toBe(1);\n\t\t\tvar testDate3 = new Date(2012, 0, 23, 4, 46, 54);\n\t\t\texpect(amDifference(testDate3, test, 'days')).toBe(1);\n\t\t});\n\n\t\tit('should allow rounding to be disabled via parameter', function () {\n\t\t\tvar test = new Date(2012, 0, 22, 4, 46, 54);\n\t\t\tvar testDate1 = new Date(test.getFullYear() + 1, test.getMonth() + 6, test.getDate());\n\t\t\texpect(amDifference(testDate1, test, 'years')).toBe(1);\n\t\t\texpect(amDifference(testDate1, test, 'years', true)).toBeCloseTo(1.5);\n\t\t});\n\n\t\tit('dates from the future should return negative values', function () {\n\t\t\tvar today = new Date(2012, 0, 22, 4, 46, 54);\n\t\t\tvar testDate = new Date(2013, 0, 22, 4, 46, 54);\n\t\t\texpect(String(amDifference(today, testDate))).toContain('-');\n\t\t});\n\n\t\tit('should gracefully handle undefined values', function () {\n\t\t\texpect(amDifference()).toBe('');\n\t\t});\n\n\t\tit('should accept a numeric unix timestamp (milliseconds since the epoch) as input', function () {\n\t\t\texpect(amDifference(new Date(2012, 0, 22, 4, 46, 55).getTime(), new Date(2012, 0, 22, 4, 46, 54).getTime())).toBe(1000);\n\t\t});\n\n\t\tit('should apply the \"utc\" preprocessor when the string \"utc\" is given as a preprocessor argument', function () {\n\t\t\texpect(amDifference([2012, 0, 22, 0, 0, 1], Date.UTC(2012, 0, 22, 0, 0, 0), null, null, 'utc')).toBe(1000);\n\t\t\texpect(amDifference(Date.UTC(2012, 0, 22, 0, 0, 1), [2012, 0, 22, 0, 0, 0], null, null, null, 'utc')).toBe(1000);\n\t\t});\n\n\t\tit('should apply the \"unix\" preprocessor if angularMomentConfig.preprocess is set to \"unix\" and no preprocessor is given', function () {\n\t\t\tangularMomentConfig.preprocess = 'unix';\n\t\t\texpect(amDifference(100001, 100000)).toBe(1000);\n\t\t});\n\n\t\tit('should return an empty string for invalid input', function () {\n\t\t\texpect(amDifference('blah blah')).toBe('');\n\t\t});\n\t});\n\n\tdescribe('amDateFormat filter', function () {\n\t\tvar amDateFormat;\n\n\t\tbeforeEach(function () {\n\t\t\tamDateFormat = $filter('amDateFormat');\n\t\t});\n\n\t\tit('should support displaying format', function () {\n\t\t\tvar today = new Date();\n\t\t\tvar expectedResult = today.getDate() + '.' + (today.getMonth() + 1) + '.' + today.getFullYear();\n\t\t\texpect(amDateFormat(today, 'D.M.YYYY')).toBe(expectedResult);\n\t\t});\n\n\t\tit('should gracefully handle undefined values', function () {\n\t\t\texpect(amDateFormat(undefined, 'D.M.YYYY')).toBe('');\n\t\t});\n\n\t\tit('should accept a numeric unix timestamp (milliseconds since the epoch) as input', function () {\n\t\t\tvar timestamp = new Date(2012, 0, 22, 12, 46, 54).getTime();\n\t\t\texpect(amDateFormat(timestamp, '(HH,mm,ss);MM.DD.YYYY')).toBe('(12,46,54);01.22.2012');\n\t\t});\n\n\t\tit('should gracefully handle string unix timestamp as input', function () {\n\t\t\tvar strTimestamp = String(new Date(2012, 0, 22, 12, 46, 54).getTime());\n\t\t\texpect(amDateFormat(strTimestamp, '(HH,mm,ss);MM.DD.YYYY')).toBe('(12,46,54);01.22.2012');\n\t\t});\n\n\t\tit('should respect the configured timezone', function () {\n\t\t\tangularMomentConfig.timezone = 'Pacific/Tahiti';\n\t\t\tvar timestamp = Date.UTC(2012, 0, 22, 12, 46, 54);\n\t\t\texpect(amDateFormat(timestamp, '(HH,mm,ss);MM.DD.YYYY')).toBe('(02,46,54);01.22.2012');\n\t\t});\n\n\t\tit('should respect the timezone parameter', function () {\n\t\t\tvar timestamp = Date.UTC(2012, 0, 22, 12, 46, 54);\n\t\t\texpect(amDateFormat(timestamp, '(HH,mm,ss);MM.DD.YYYY', 'utc', 'Pacific/Tahiti')).toBe('(02,46,54);01.22.2012');\n\t\t});\n\n\t\tit('should return an empty string for invalid input', function () {\n\t\t\texpect(amDateFormat('blah blah', '(HH,mm,ss);MM.DD.YYYY')).toBe('');\n\t\t});\n\t});\n\n\tdescribe('amDurationFormat filter', function () {\n\t\tvar amDurationFormat;\n\n\t\tbeforeEach(function () {\n\t\t\tamDurationFormat = $filter('amDurationFormat');\n\t\t});\n\n\t\tit('should support return the given duration as text', function () {\n\t\t\texpect(amDurationFormat(1000, 'milliseconds')).toBe('a few seconds');\n\t\t});\n\n\t\tit('should support return a day given 24 hours', function () {\n\t\t\texpect(amDurationFormat(24, 'hours')).toBe('a day');\n\t\t});\n\n\t\tit('should add prefix the result with the word \"in\" if the third parameter (suffix) is true', function () {\n\t\t\texpect(amDurationFormat(1, 'minutes', true)).toBe('in a minute');\n\t\t});\n\n\t\tit('should add suffix the result with the word \"ago\" if the duration is negative and the third parameter is true', function () {\n\t\t\texpect(amDurationFormat(-1, 'minutes', true)).toBe('a minute ago');\n\t\t});\n\n\t\tit('should gracefully handle undefined values for duration', function () {\n\t\t\texpect(amDurationFormat(undefined, 'minutes')).toBe('');\n\t\t});\n\t});\n\n\n\tdescribe('amTimeAgo filter', function () {\n\t\tvar amTimeAgo;\n\n\t\tbeforeEach(function () {\n\t\t\tamTimeAgo = $filter('amTimeAgo');\n\t\t});\n\n\t\tit('should support return the time ago as text', function () {\n\t\t\tvar date = new Date();\n\t\t\texpect(amTimeAgo(date)).toBe('a few seconds ago');\n\t\t});\n\n\t\tit('should remove suffix from the result if the third parameter (suffix) is true', function () {\n\t\t\tvar date = new Date();\n\t\t\texpect(amTimeAgo(date, null, true)).toBe('a few seconds');\n\t\t});\n\n\t\tit('should gracefully handle undefined values', function () {\n\t\t\texpect(amTimeAgo()).toBe('');\n\t\t});\n\n\t\tit('should gracefully handle invalid input', function () {\n\t\t\texpect(amTimeAgo('noDate')).toBe('');\n\t\t});\n\n\t});\n\n\tdescribe('amMoment service', function () {\n\t\tdescribe('#changeLocale', function () {\n\t\t\tit('should convert today\\'s date to custom calendar format', function () {\n\t\t\t\tvar today = new Date();\n\t\t\t\tamMoment.changeLocale('en', {calendar: {sameDay: '[This Day]'}});\n\t\t\t\tvar amCalendar = $filter('amCalendar');\n\t\t\t\tvar testDate = new Date(today.getFullYear(), today.getMonth(), today.getDate(), 13, 33, 33);\n\t\t\t\texpect(amCalendar(testDate)).toBe('This Day');\n\t\t\t});\n\n\t\t\tit('should return the current locale', function () {\n\t\t\t\texpect(amMoment.changeLocale()).toBe('en');\n\t\t\t});\n\n\t\t\tit('should broadcast an angularMoment:localeChanged event on the root scope if a locale is specified', function () {\n\t\t\t\tvar eventBroadcasted = false;\n\t\t\t\t$rootScope.$on('amMoment:localeChanged', function () {\n\t\t\t\t\teventBroadcasted = true;\n\t\t\t\t});\n\t\t\t\tamMoment.changeLocale('fr');\n\t\t\t\texpect(eventBroadcasted).toBe(true);\n\t\t\t});\n\n\t\t\tit('should not broadcast an angularMoment:localeChanged event on the root scope if no locale is specified', function () {\n\t\t\t\tvar eventBroadcasted = false;\n\t\t\t\t$rootScope.$on('amMoment:localeChanged', function () {\n\t\t\t\t\teventBroadcasted = true;\n\t\t\t\t});\n\t\t\t\tamMoment.changeLocale();\n\t\t\t\texpect(eventBroadcasted).toBe(false);\n\t\t\t});\n\t\t});\n\n\t\tdescribe('#changeTimezone', function () {\n\t\t\tit('Should update the current timezone', function () {\n\t\t\t\tamMoment.changeTimezone('UTC');\n\t\t\t\texpect(amMoment.applyTimezone(moment()).utcOffset()).toBe(0);\n\n\t\t\t\tamMoment.changeTimezone('Pacific/Tahiti');\n\t\t\t\texpect(amMoment.applyTimezone(moment()).utcOffset()).toBe(-600);\n\t\t\t});\n\n\t\t\tit('should broadcast an angularMoment:timezoneChanged event on the root scope with the new timezone value', function () {\n\t\t\t\tvar eventBroadcasted = false;\n\t\t\t\t$rootScope.$on('amMoment:timezoneChanged', function () {\n\t\t\t\t\teventBroadcasted = true;\n\t\t\t\t});\n\t\t\t\tamMoment.changeTimezone('UTC');\n\t\t\t\texpect(eventBroadcasted).toBe(true);\n\t\t\t});\n\t\t});\n\n\t\tdescribe('#preprocessDate', function () {\n\t\t\tit('should call a custom preprocessor that was registered on amMoment.preprocessors', function () {\n\t\t\t\tvar testDate = new Date(2013, 0, 22, 12, 46, 54);\n\t\t\t\tvar meeting = {\n\t\t\t\t\tname: 'Budget plan',\n\t\t\t\t\tdate: testDate\n\t\t\t\t};\n\n\t\t\t\tamMoment.preprocessors.foobar = function (value) {\n\t\t\t\t\treturn moment(value.date);\n\t\t\t\t};\n\n\t\t\t\texpect(amMoment.preprocessDate(meeting, 'foobar').valueOf()).toEqual(testDate.getTime());\n\t\t\t});\n\n\t\t\tit('should issue a warning if an unsupported preprocessor is used and fall-back to default processing', inject(function ($log) {\n\t\t\t\tvar testDate = new Date(2014, 0, 22, 12, 46, 54);\n\t\t\t\tspyOn($log, 'warn');\n\t\t\t\texpect(amMoment.preprocessDate(testDate.getTime(), 'blabla').valueOf()).toEqual(testDate.getTime());\n\t\t\t\texpect($log.warn).toHaveBeenCalledWith('angular-moment: Ignoring unsupported value for preprocess: blabla');\n\t\t\t}));\n\t\t});\n\t});\n\n\tdescribe('amTimeAgoConfig constant', function () {\n\t\tit('should generate time with suffix by default', function () {\n\t\t\texpect(amTimeAgoConfig.withoutSuffix).toBe(false);\n\t\t});\n\t});\n\n\tdescribe('angularMomentConfig constant', function () {\n\t\tit('should have an empty timezone value by default', function () {\n\t\t\texpect(angularMomentConfig.timezone).toBe('');\n\t\t});\n\t\tit('should have an empty preprocess value by default', function () {\n\t\t\texpect(angularMomentConfig.preprocess).toBe(null);\n\t\t});\n\t});\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-resource/.bower.json",
    "content": "{\n  \"name\": \"angular-resource\",\n  \"version\": \"1.3.15\",\n  \"main\": \"./angular-resource.js\",\n  \"ignore\": [],\n  \"dependencies\": {\n    \"angular\": \"1.3.15\"\n  },\n  \"homepage\": \"https://github.com/angular/bower-angular-resource\",\n  \"_release\": \"1.3.15\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"v1.3.15\",\n    \"commit\": \"4cc3a759e2077f27aafb273a4a4929241aae1fd6\"\n  },\n  \"_source\": \"git://github.com/angular/bower-angular-resource.git\",\n  \"_target\": \"1.3.15\",\n  \"_originalSource\": \"angular-resource\",\n  \"_direct\": true\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-resource/README.md",
    "content": "# packaged angular-resource\n\nThis repo is for distribution on `npm` and `bower`. The source for this module is in the\n[main AngularJS repo](https://github.com/angular/angular.js/tree/master/src/ngResource).\nPlease file issues and pull requests against that repo.\n\n## Install\n\nYou can install this package either with `npm` or with `bower`.\n\n### npm\n\n```shell\nnpm install angular-resource\n```\n\nThen add `ngResource` as a dependency for your app:\n\n```javascript\nangular.module('myApp', [require('angular-resource')]);\n```\n\n### bower\n\n```shell\nbower install angular-resource\n```\n\nAdd a `<script>` to your `index.html`:\n\n```html\n<script src=\"/bower_components/angular-resource/angular-resource.js\"></script>\n```\n\nThen add `ngResource` as a dependency for your app:\n\n```javascript\nangular.module('myApp', ['ngResource']);\n```\n\n## Documentation\n\nDocumentation is available on the\n[AngularJS docs site](http://docs.angularjs.org/api/ngResource).\n\n## License\n\nThe MIT License\n\nCopyright (c) 2010-2015 Google, Inc. http://angularjs.org\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-resource/bower.json",
    "content": "{\n  \"name\": \"angular-resource\",\n  \"version\": \"1.3.15\",\n  \"main\": \"./angular-resource.js\",\n  \"ignore\": [],\n  \"dependencies\": {\n    \"angular\": \"1.3.15\"\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-resource/index.js",
    "content": "require('./angular-resource');\nmodule.exports = 'ngResource';\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-resource/package.json",
    "content": "{\n  \"name\": \"angular-resource\",\n  \"version\": \"1.3.15\",\n  \"description\": \"AngularJS module for interacting with RESTful server-side data sources\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/angular/angular.js.git\"\n  },\n  \"keywords\": [\n    \"angular\",\n    \"framework\",\n    \"browser\",\n    \"rest\",\n    \"client-side\"\n  ],\n  \"author\": \"Angular Core Team <angular-core+npm@google.com>\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/angular/angular.js/issues\"\n  },\n  \"homepage\": \"http://angularjs.org\"\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-route/.bower.json",
    "content": "{\n  \"name\": \"angular-route\",\n  \"version\": \"1.2.16\",\n  \"main\": \"./angular-route.js\",\n  \"dependencies\": {\n    \"angular\": \"1.2.16\"\n  },\n  \"homepage\": \"https://github.com/angular/bower-angular-route\",\n  \"_release\": \"1.2.16\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"v1.2.16\",\n    \"commit\": \"ed0e2b796077d953f518cb81cc7af981cf695a45\"\n  },\n  \"_source\": \"git://github.com/angular/bower-angular-route.git\",\n  \"_target\": \"1.2.16\",\n  \"_originalSource\": \"angular-route\"\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-route/README.md",
    "content": "# bower-angular-route\n\nThis repo is for distribution on `bower`. The source for this module is in the\n[main AngularJS repo](https://github.com/angular/angular.js/tree/master/src/ngRoute).\nPlease file issues and pull requests against that repo.\n\n## Install\n\nInstall with `bower`:\n\n```shell\nbower install angular-route\n```\n\nAdd a `<script>` to your `index.html`:\n\n```html\n<script src=\"/bower_components/angular-route/angular-route.js\"></script>\n```\n\nAnd add `ngRoute` as a dependency for your app:\n\n```javascript\nangular.module('myApp', ['ngRoute']);\n```\n\n## Documentation\n\nDocumentation is available on the\n[AngularJS docs site](http://docs.angularjs.org/api/ngRoute).\n\n## License\n\nThe MIT License\n\nCopyright (c) 2010-2012 Google, Inc. http://angularjs.org\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-route/angular-route.js",
    "content": "(function(window, angular, undefined) {'use strict';\n\n /* global -ngRouteModule */\nvar ngRouteModule = angular.module('ngRoute', ['ng']).\n                        provider('$route', $RouteProvider);\n\nfunction $RouteProvider(){\n  function inherit(parent, extra) {\n    return angular.extend(new (angular.extend(function() {}, {prototype:parent}))(), extra);\n  }\n\n  var routes = {};\n\n    this.when = function(path, route) {\n    routes[path] = angular.extend(\n      {reloadOnSearch: true},\n      route,\n      path && pathRegExp(path, route)\n    );\n    if (path) {\n      var redirectPath = (path[path.length-1] == '/')\n            ? path.substr(0, path.length-1)\n            : path +'/';\n\n      routes[redirectPath] = angular.extend(\n        {redirectTo: path},\n        pathRegExp(redirectPath, route)\n      );\n    }\n\n    return this;\n  };\n\n     function pathRegExp(path, opts) {\n    var insensitive = opts.caseInsensitiveMatch,\n        ret = {\n          originalPath: path,\n          regexp: path\n        },\n        keys = ret.keys = [];\n\n    path = path\n      .replace(/([().])/g, '\\\\$1')\n      .replace(/(\\/)?:(\\w+)([\\?\\*])?/g, function(_, slash, key, option){\n        var optional = option === '?' ? option : null;\n        var star = option === '*' ? option : null;\n        keys.push({ name: key, optional: !!optional });\n        slash = slash || '';\n        return ''\n          + (optional ? '' : slash)\n          + '(?:'\n          + (optional ? slash : '')\n          + (star && '(.+?)' || '([^/]+)')\n          + (optional || '')\n          + ')'\n          + (optional || '');\n      })\n      .replace(/([\\/$\\*])/g, '\\\\$1');\n\n    ret.regexp = new RegExp('^' + path + '$', insensitive ? 'i' : '');\n    return ret;\n  }\n\n    this.otherwise = function(params) {\n    this.when(null, params);\n    return this;\n  };\n\n\n  this.$get = ['$rootScope',\n               '$location',\n               '$routeParams',\n               '$q',\n               '$injector',\n               '$http',\n               '$templateCache',\n               '$sce',\n      function($rootScope, $location, $routeParams, $q, $injector, $http, $templateCache, $sce) {\n\n    \n    \n    \n    \n    \n    var forceReload = false,\n        $route = {\n          routes: routes,\n\n                    reload: function() {\n            forceReload = true;\n            $rootScope.$evalAsync(updateRoute);\n          }\n        };\n\n    $rootScope.$on('$locationChangeSuccess', updateRoute);\n\n    return $route;\n\n        function switchRouteMatcher(on, route) {\n      var keys = route.keys,\n          params = {};\n\n      if (!route.regexp) return null;\n\n      var m = route.regexp.exec(on);\n      if (!m) return null;\n\n      for (var i = 1, len = m.length; i < len; ++i) {\n        var key = keys[i - 1];\n\n        var val = 'string' == typeof m[i]\n              ? decodeURIComponent(m[i])\n              : m[i];\n\n        if (key && val) {\n          params[key.name] = val;\n        }\n      }\n      return params;\n    }\n\n    function updateRoute() {\n      var next = parseRoute(),\n          last = $route.current;\n\n      if (next && last && next.$$route === last.$$route\n          && angular.equals(next.pathParams, last.pathParams)\n          && !next.reloadOnSearch && !forceReload) {\n        last.params = next.params;\n        angular.copy(last.params, $routeParams);\n        $rootScope.$broadcast('$routeUpdate', last);\n      } else if (next || last) {\n        forceReload = false;\n        $rootScope.$broadcast('$routeChangeStart', next, last);\n        $route.current = next;\n        if (next) {\n          if (next.redirectTo) {\n            if (angular.isString(next.redirectTo)) {\n              $location.path(interpolate(next.redirectTo, next.params)).search(next.params)\n                       .replace();\n            } else {\n              $location.url(next.redirectTo(next.pathParams, $location.path(), $location.search()))\n                       .replace();\n            }\n          }\n        }\n\n        $q.when(next).\n          then(function() {\n            if (next) {\n              var locals = angular.extend({}, next.resolve),\n                  template, templateUrl;\n\n              angular.forEach(locals, function(value, key) {\n                locals[key] = angular.isString(value) ?\n                    $injector.get(value) : $injector.invoke(value);\n              });\n\n              if (angular.isDefined(template = next.template)) {\n                if (angular.isFunction(template)) {\n                  template = template(next.params);\n                }\n              } else if (angular.isDefined(templateUrl = next.templateUrl)) {\n                if (angular.isFunction(templateUrl)) {\n                  templateUrl = templateUrl(next.params);\n                }\n                templateUrl = $sce.getTrustedResourceUrl(templateUrl);\n                if (angular.isDefined(templateUrl)) {\n                  next.loadedTemplateUrl = templateUrl;\n                  template = $http.get(templateUrl, {cache: $templateCache}).\n                      then(function(response) { return response.data; });\n                }\n              }\n              if (angular.isDefined(template)) {\n                locals['$template'] = template;\n              }\n              return $q.all(locals);\n            }\n          }).\n          then(function(locals) {\n            if (next == $route.current) {\n              if (next) {\n                next.locals = locals;\n                angular.copy(next.params, $routeParams);\n              }\n              $rootScope.$broadcast('$routeChangeSuccess', next, last);\n            }\n          }, function(error) {\n            if (next == $route.current) {\n              $rootScope.$broadcast('$routeChangeError', next, last, error);\n            }\n          });\n      }\n    }\n\n\n        function parseRoute() {\n      var params, match;\n      angular.forEach(routes, function(route, path) {\n        if (!match && (params = switchRouteMatcher($location.path(), route))) {\n          match = inherit(route, {\n            params: angular.extend({}, $location.search(), params),\n            pathParams: params});\n          match.$$route = route;\n        }\n      });\n      return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}});\n    }\n\n        function interpolate(string, params) {\n      var result = [];\n      angular.forEach((string||'').split(':'), function(segment, i) {\n        if (i === 0) {\n          result.push(segment);\n        } else {\n          var segmentMatch = segment.match(/(\\w+)(.*)/);\n          var key = segmentMatch[1];\n          result.push(params[key]);\n          result.push(segmentMatch[2] || '');\n          delete params[key];\n        }\n      });\n      return result.join('');\n    }\n  }];\n}\n\nngRouteModule.provider('$routeParams', $RouteParamsProvider);\n\n\nfunction $RouteParamsProvider() {\n  this.$get = function() { return {}; };\n}\n\nngRouteModule.directive('ngView', ngViewFactory);\nngRouteModule.directive('ngView', ngViewFillContentFactory);\n\n\n\n\nngViewFactory.$inject = ['$route', '$anchorScroll', '$animate'];\nfunction ngViewFactory(   $route,   $anchorScroll,   $animate) {\n  return {\n    restrict: 'ECA',\n    terminal: true,\n    priority: 400,\n    transclude: 'element',\n    link: function(scope, $element, attr, ctrl, $transclude) {\n        var currentScope,\n            currentElement,\n            previousElement,\n            autoScrollExp = attr.autoscroll,\n            onloadExp = attr.onload || '';\n\n        scope.$on('$routeChangeSuccess', update);\n        update();\n\n        function cleanupLastView() {\n          if(previousElement) {\n            previousElement.remove();\n            previousElement = null;\n          }\n          if(currentScope) {\n            currentScope.$destroy();\n            currentScope = null;\n          }\n          if(currentElement) {\n            $animate.leave(currentElement, function() {\n              previousElement = null;\n            });\n            previousElement = currentElement;\n            currentElement = null;\n          }\n        }\n\n        function update() {\n          var locals = $route.current && $route.current.locals,\n              template = locals && locals.$template;\n\n          if (angular.isDefined(template)) {\n            var newScope = scope.$new();\n            var current = $route.current;\n            var clone = $transclude(newScope, function(clone) {\n              $animate.enter(clone, null, currentElement || $element, function onNgViewEnter () {\n                if (angular.isDefined(autoScrollExp)\n                  && (!autoScrollExp || scope.$eval(autoScrollExp))) {\n                  $anchorScroll();\n                }\n              });\n              cleanupLastView();\n            });\n\n            currentElement = clone;\n            currentScope = current.scope = newScope;\n            currentScope.$emit('$viewContentLoaded');\n            currentScope.$eval(onloadExp);\n          } else {\n            cleanupLastView();\n          }\n        }\n    }\n  };\n}\nngViewFillContentFactory.$inject = ['$compile', '$controller', '$route'];\nfunction ngViewFillContentFactory($compile, $controller, $route) {\n  return {\n    restrict: 'ECA',\n    priority: -400,\n    link: function(scope, $element) {\n      var current = $route.current,\n          locals = current.locals;\n\n      $element.html(locals.$template);\n\n      var link = $compile($element.contents());\n\n      if (current.controller) {\n        locals.$scope = scope;\n        var controller = $controller(current.controller, locals);\n        if (current.controllerAs) {\n          scope[current.controllerAs] = controller;\n        }\n        $element.data('$ngControllerController', controller);\n        $element.children().data('$ngControllerController', controller);\n      }\n\n      link(scope);\n    }\n  };\n}\n\n\n})(window, window.angular);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-route/bower.json",
    "content": "{\n  \"name\": \"angular-route\",\n  \"version\": \"1.2.16\",\n  \"main\": \"./angular-route.js\",\n  \"dependencies\": {\n    \"angular\": \"1.2.16\"\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-sanitize/.bower.json",
    "content": "{\n  \"name\": \"angular-sanitize\",\n  \"version\": \"1.3.15\",\n  \"main\": \"./angular-sanitize.js\",\n  \"ignore\": [],\n  \"dependencies\": {\n    \"angular\": \"1.3.15\"\n  },\n  \"homepage\": \"https://github.com/angular/bower-angular-sanitize\",\n  \"_release\": \"1.3.15\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"v1.3.15\",\n    \"commit\": \"9a728e87c8da5cf193435dad2fe82e2d188767b0\"\n  },\n  \"_source\": \"git://github.com/angular/bower-angular-sanitize.git\",\n  \"_target\": \">=1.2.15 <=1.4.0\",\n  \"_originalSource\": \"angular-sanitize\"\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-sanitize/README.md",
    "content": "# packaged angular-sanitize\n\nThis repo is for distribution on `npm` and `bower`. The source for this module is in the\n[main AngularJS repo](https://github.com/angular/angular.js/tree/master/src/ngSanitize).\nPlease file issues and pull requests against that repo.\n\n## Install\n\nYou can install this package either with `npm` or with `bower`.\n\n### npm\n\n```shell\nnpm install angular-sanitize\n```\n\nThen add `ngSanitize` as a dependency for your app:\n\n```javascript\nangular.module('myApp', [require('angular-sanitize')]);\n```\n\n### bower\n\n```shell\nbower install angular-sanitize\n```\n\nAdd a `<script>` to your `index.html`:\n\n```html\n<script src=\"/bower_components/angular-sanitize/angular-sanitize.js\"></script>\n```\n\nThen add `ngSanitize` as a dependency for your app:\n\n```javascript\nangular.module('myApp', ['ngSanitize']);\n```\n\n## Documentation\n\nDocumentation is available on the\n[AngularJS docs site](http://docs.angularjs.org/api/ngSanitize).\n\n## License\n\nThe MIT License\n\nCopyright (c) 2010-2015 Google, Inc. http://angularjs.org\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-sanitize/bower.json",
    "content": "{\n  \"name\": \"angular-sanitize\",\n  \"version\": \"1.3.15\",\n  \"main\": \"./angular-sanitize.js\",\n  \"ignore\": [],\n  \"dependencies\": {\n    \"angular\": \"1.3.15\"\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-sanitize/index.js",
    "content": "require('./angular-sanitize');\nmodule.exports = 'ngSanitize';\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-sanitize/package.json",
    "content": "{\n  \"name\": \"angular-sanitize\",\n  \"version\": \"1.3.15\",\n  \"description\": \"AngularJS module for sanitizing HTML\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/angular/angular.js.git\"\n  },\n  \"keywords\": [\n    \"angular\",\n    \"framework\",\n    \"browser\",\n    \"html\",\n    \"client-side\"\n  ],\n  \"author\": \"Angular Core Team <angular-core+npm@google.com>\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/angular/angular.js/issues\"\n  },\n  \"homepage\": \"http://angularjs.org\"\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-touch/.bower.json",
    "content": "{\n  \"name\": \"angular-touch\",\n  \"version\": \"1.3.15\",\n  \"main\": \"./angular-touch.js\",\n  \"ignore\": [],\n  \"dependencies\": {\n    \"angular\": \"1.3.15\"\n  },\n  \"homepage\": \"https://github.com/angular/bower-angular-touch\",\n  \"_release\": \"1.3.15\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"v1.3.15\",\n    \"commit\": \"952bc774b600d97318f253ce47491052b9c4f145\"\n  },\n  \"_source\": \"git://github.com/angular/bower-angular-touch.git\",\n  \"_target\": \"~1.3.15\",\n  \"_originalSource\": \"angular-touch\",\n  \"_direct\": true\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-touch/README.md",
    "content": "# packaged angular-touch\n\nThis repo is for distribution on `npm` and `bower`. The source for this module is in the\n[main AngularJS repo](https://github.com/angular/angular.js/tree/master/src/ngTouch).\nPlease file issues and pull requests against that repo.\n\n## Install\n\nYou can install this package either with `npm` or with `bower`.\n\n### npm\n\n```shell\nnpm install angular-touch\n```\n\nThen add `ngTouch` as a dependency for your app:\n\n```javascript\nangular.module('myApp', [require('angular-touch')]);\n```\n\n### bower\n\n```shell\nbower install angular-touch\n```\n\nAdd a `<script>` to your `index.html`:\n\n```html\n<script src=\"/bower_components/angular-touch/angular-touch.js\"></script>\n```\n\nThen add `ngTouch` as a dependency for your app:\n\n```javascript\nangular.module('myApp', ['ngTouch']);\n```\n\n## Documentation\n\nDocumentation is available on the\n[AngularJS docs site](http://docs.angularjs.org/api/ngTouch).\n\n## License\n\nThe MIT License\n\nCopyright (c) 2010-2015 Google, Inc. http://angularjs.org\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-touch/bower.json",
    "content": "{\n  \"name\": \"angular-touch\",\n  \"version\": \"1.3.15\",\n  \"main\": \"./angular-touch.js\",\n  \"ignore\": [],\n  \"dependencies\": {\n    \"angular\": \"1.3.15\"\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-touch/index.js",
    "content": "require('./angular-touch');\nmodule.exports = 'ngTouch';\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-touch/package.json",
    "content": "{\n  \"name\": \"angular-touch\",\n  \"version\": \"1.3.15\",\n  \"description\": \"AngularJS module for touch events and helpers for touch-enabled devices\",\n  \"main\": \"index.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/angular/angular.js.git\"\n  },\n  \"keywords\": [\n    \"angular\",\n    \"framework\",\n    \"browser\",\n    \"touch\",\n    \"client-side\"\n  ],\n  \"author\": \"Angular Core Team <angular-core+npm@google.com>\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/angular/angular.js/issues\"\n  },\n  \"homepage\": \"http://angularjs.org\"\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-translate/.bower.json",
    "content": "{\n  \"name\": \"angular-translate\",\n  \"description\": \"A translation module for AngularJS\",\n  \"version\": \"2.6.1\",\n  \"main\": \"./angular-translate.js\",\n  \"dependencies\": {\n    \"angular\": \">=1.2.26 <=1.4\"\n  },\n  \"ignore\": [],\n  \"author\": \"Pascal Precht\",\n  \"licenses\": [\n    {\n      \"type\": \"MIT\",\n      \"url\": \"http://www.opensource.org/licenses/MIT\"\n    }\n  ],\n  \"homepage\": \"https://github.com/PascalPrecht/bower-angular-translate\",\n  \"_release\": \"2.6.1\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"2.6.1\",\n    \"commit\": \"6dd0ce6459b271498c05b7e9a9f0e78f9c008c74\"\n  },\n  \"_source\": \"git://github.com/PascalPrecht/bower-angular-translate.git\",\n  \"_target\": \"~2.6.1\",\n  \"_originalSource\": \"angular-translate\"\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-translate/README.md",
    "content": "# bower-angular-translate\n\nangular-translate bower package\n\n### Installation\n\n````\n$ bower install angular-translate\n````\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-translate/bower.json",
    "content": "{\n  \"name\": \"angular-translate\",\n  \"description\": \"A translation module for AngularJS\",\n  \"version\": \"2.6.1\",\n  \"main\": \"./angular-translate.js\",\n  \"dependencies\": {\n    \"angular\": \">=1.2.26 <=1.4\"\n  },\n  \"ignore\": [],\n  \"author\": \"Pascal Precht\",\n  \"licenses\": [\n    {\n      \"type\": \"MIT\",\n      \"url\": \"http://www.opensource.org/licenses/MIT\"\n    }\n  ]\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-translate-storage-cookie/.bower.json",
    "content": "{\n  \"name\": \"angular-translate-storage-cookie\",\n  \"description\": \"A plugin for Angular Translate\",\n  \"version\": \"2.6.1\",\n  \"main\": \"./angular-translate-storage-cookie.js\",\n  \"dependencies\": {\n    \"angular-translate\": \"~2.6.1\",\n    \"angular-cookies\": \">=1.2.26 <=1.4\"\n  },\n  \"ignore\": [],\n  \"author\": \"Pascal Precht\",\n  \"licenses\": [\n    {\n      \"type\": \"MIT\",\n      \"url\": \"http://www.opensource.org/licenses/MIT\"\n    }\n  ],\n  \"homepage\": \"https://github.com/PascalPrecht/bower-angular-translate-storage-cookie\",\n  \"_release\": \"2.6.1\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"2.6.1\",\n    \"commit\": \"244f29febbf1f9df7c10e5bbf3770463df21913b\"\n  },\n  \"_source\": \"git://github.com/PascalPrecht/bower-angular-translate-storage-cookie.git\",\n  \"_target\": \"~2.6.1\",\n  \"_originalSource\": \"angular-translate-storage-cookie\",\n  \"_direct\": true\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-translate-storage-cookie/README.md",
    "content": "# bower-angular-translate-storage-cookie\n\nangular-translate-cookie-storage bower package\n\n### Installation\n\n````\n$ bower install angular-translate-storage-cookie\n````\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-translate-storage-cookie/bower.json",
    "content": "{\n  \"name\": \"angular-translate-storage-cookie\",\n  \"description\": \"A plugin for Angular Translate\",\n  \"version\": \"2.6.1\",\n  \"main\": \"./angular-translate-storage-cookie.js\",\n  \"dependencies\": {\n    \"angular-translate\": \"~2.6.1\",\n    \"angular-cookies\": \">=1.2.26 <=1.4\"\n  },\n  \"ignore\": [],\n  \"author\": \"Pascal Precht\",\n  \"licenses\": [\n    {\n      \"type\": \"MIT\",\n      \"url\": \"http://www.opensource.org/licenses/MIT\"\n    }\n  ]\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-ui-router/.bower.json",
    "content": "{\n  \"name\": \"angular-ui-router\",\n  \"version\": \"0.2.14\",\n  \"main\": \"./release/angular-ui-router.js\",\n  \"dependencies\": {\n    \"angular\": \">= 1.0.8\"\n  },\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"component.json\",\n    \"package.json\",\n    \"lib\",\n    \"config\",\n    \"sample\",\n    \"test\",\n    \"tests\",\n    \"ngdoc_assets\",\n    \"Gruntfile.js\",\n    \"files.js\"\n  ],\n  \"homepage\": \"https://github.com/angular-ui/ui-router\",\n  \"_release\": \"0.2.14\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"0.2.14\",\n    \"commit\": \"da63b27b7bbd13d2633b68fa74606f977e6d4147\"\n  },\n  \"_source\": \"git://github.com/angular-ui/ui-router.git\",\n  \"_target\": \"~0.2.14\",\n  \"_originalSource\": \"angular-ui-router\",\n  \"_direct\": true\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-ui-router/CHANGELOG.md",
    "content": "<a name=\"0.2.14\"></a>\n### 0.2.14 (2015-04-23)\n\n\n#### Bug Fixes\n\n* **$StateRefDirective:** resolve missing support for svg anchor elements #1667 ([0149a7bb](https://github.com/angular-ui/ui-router/commit/0149a7bb38b7af99388a1ad7cc9909a7b7c4439d))\n* **$urlMatcherFactory:**\n  * regex params should respect case-sensitivity ([1e10519f](https://github.com/angular-ui/ui-router/commit/1e10519f3be6bbf0cefdcce623cd2ade06e649e5), closes [#1671](https://github.com/angular-ui/ui-router/issues/1671))\n  * unquote all dashes from array params ([06664d33](https://github.com/angular-ui/ui-router/commit/06664d330f882390655dcfa83e10276110d0d0fa))\n  * add Type.$normalize function ([b0c6aa23](https://github.com/angular-ui/ui-router/commit/b0c6aa2350fdd3ce8483144774adc12f5a72b7e9))\n  * make optional params regex grouping optional ([06f73794](https://github.com/angular-ui/ui-router/commit/06f737945e83e668d09cfc3bcffd04a500ff1963), closes [#1576](https://github.com/angular-ui/ui-router/issues/1576))\n* **$state:** allow about.*.** glob patterns ([e39b27a2](https://github.com/angular-ui/ui-router/commit/e39b27a2cb7d88525c446a041f9fbf1553202010))\n* **uiSref:**\n  * use Object's toString instead of Window's toString ([2aa7f4d1](https://github.com/angular-ui/ui-router/commit/2aa7f4d139dbd5b9fcc4afdcf2ab6642c87f5671))\n  * add absolute to allowed transition options ([ae1b3c4e](https://github.com/angular-ui/ui-router/commit/ae1b3c4eedc37983400d830895afb50457c63af4))\n* **uiSrefActive:** Apply active classes on lazy loaded states ([f0ddbe7b](https://github.com/angular-ui/ui-router/commit/f0ddbe7b4a91daf279c3b7d0cee732bb1f3be5b4))\n* **uiView:** add `$element` to locals for view controller ([db68914c](https://github.com/angular-ui/ui-router/commit/db68914cd6c821e7dec8155bd33142a3a97f5453))\n\n\n#### Features\n\n* **$state:**\n  * support URLs with #fragments ([3da0a170](https://github.com/angular-ui/ui-router/commit/3da0a17069e27598c0f9d9164e104dd5ce05cdc6))\n  * inject resolve params into controllerProvider ([b380c223](https://github.com/angular-ui/ui-router/commit/b380c223fe12e2fde7582c0d6b1ed7b15a23579b), closes [#1131](https://github.com/angular-ui/ui-router/issues/1131))\n  * added 'state' to state reload method (feat no.1612)  - modiefied options.reload  ([b8f04575](https://github.com/angular-ui/ui-router/commit/b8f04575a8557035c1858c4d5c8dbde3e1855aaa))\n  * broadcast $stateChangeCancel event when event.preventDefault() is called in $sta ([ecefb758](https://github.com/angular-ui/ui-router/commit/ecefb758cb445e41620b62a272aafa3638613d7a))\n* **$uiViewScroll:** change function to return promise ([c2a9a311](https://github.com/angular-ui/ui-router/commit/c2a9a311388bb212e5a2e820536d1d739f829ccd), closes [#1702](https://github.com/angular-ui/ui-router/issues/1702))\n* **uiSrefActive:** Added support for multiple nested uiSref directives ([b1844948](https://github.com/angular-ui/ui-router/commit/b18449481d152b50705abfce2493a444eb059fa5))\n\n\n<a name=\"0.2.13\"></a>\n### 0.2.13 (2014-11-20)\n\nThis release primarily fixes issues reported against 0.2.12\n\n#### Bug Fixes\n\n* **$state:** fix $state.includes/.is to apply param types before comparisions fix(uiSref): ma ([19715d15](https://github.com/angular-ui/ui-router/commit/19715d15e3cbfff724519e9febedd05b49c75baa), closes [#1513](https://github.com/angular-ui/ui-router/issues/1513))\n  * Avoid re-synchronizing from url after .transitionTo ([b267ecd3](https://github.com/angular-ui/ui-router/commit/b267ecd348e5c415233573ef95ebdbd051875f52), closes [#1573](https://github.com/angular-ui/ui-router/issues/1573))\n* **$urlMatcherFactory:**\n  * Built-in date type uses local time zone ([d726bedc](https://github.com/angular-ui/ui-router/commit/d726bedcbb5f70a5660addf43fd52ec730790293))\n  * make date type fn check .is before running ([aa94ce3b](https://github.com/angular-ui/ui-router/commit/aa94ce3b86632ad05301530a2213099da73a3dc0), closes [#1564](https://github.com/angular-ui/ui-router/issues/1564))\n  * early binding of array handler bypasses type resolution ([ada4bc27](https://github.com/angular-ui/ui-router/commit/ada4bc27df5eff3ba3ab0de94a09bd91b0f7a28c))\n  * add 'any' Type for non-encoding non-url params ([3bfd75ab](https://github.com/angular-ui/ui-router/commit/3bfd75ab445ee2f1dd55275465059ed116b10b27), closes [#1562](https://github.com/angular-ui/ui-router/issues/1562))\n  * fix encoding slashes in params ([0c983a08](https://github.com/angular-ui/ui-router/commit/0c983a08e2947f999683571477debd73038e95cf), closes [#1119](https://github.com/angular-ui/ui-router/issues/1119))\n  * fix mixed path/query params ordering problem ([a479fbd0](https://github.com/angular-ui/ui-router/commit/a479fbd0b8eb393a94320973e5b9a62d83912ee2), closes [#1543](https://github.com/angular-ui/ui-router/issues/1543))\n* **ArrayType:**\n  * specify empty array mapping corner case ([74aa6091](https://github.com/angular-ui/ui-router/commit/74aa60917e996b0b4e27bbb4eb88c3c03832021d), closes [#1511](https://github.com/angular-ui/ui-router/issues/1511))\n  * fix .equals for array types ([5e6783b7](https://github.com/angular-ui/ui-router/commit/5e6783b77af9a90ddff154f990b43dbb17eeda6e), closes [#1538](https://github.com/angular-ui/ui-router/issues/1538))\n* **Param:** fix default value shorthand declaration ([831d812a](https://github.com/angular-ui/ui-router/commit/831d812a524524c71f0ee1c9afaf0487a5a66230), closes [#1554](https://github.com/angular-ui/ui-router/issues/1554))\n* **common:** fixed the _.filter clone to not create sparse arrays ([750f5cf5](https://github.com/angular-ui/ui-router/commit/750f5cf5fd91f9ada96f39e50d39aceb2caf22b6), closes [#1563](https://github.com/angular-ui/ui-router/issues/1563))\n* **ie8:** fix calls to indexOf and filter ([dcb31b84](https://github.com/angular-ui/ui-router/commit/dcb31b843391b3e61dee4de13f368c109541813e), closes [#1556](https://github.com/angular-ui/ui-router/issues/1556))\n\n\n#### Features\n\n* add json parameter Type ([027f1fcf](https://github.com/angular-ui/ui-router/commit/027f1fcf9c0916cea651e88981345da6f9ff214a))\n\n\n<a name=\"0.2.12\"></a>\n### 0.2.12 (2014-11-13)\n\n#### Bug Fixes\n\n* **$resolve:** use resolve fn result, not parent resolved value of same name ([67f5e00c](https://github.com/angular-ui/ui-router/commit/67f5e00cc9aa006ce3fe6cde9dff261c28eab70a), closes [#1317], [#1353])\n* **$state:**\n  * populate default params in .transitionTo. ([3f60fbe6](https://github.com/angular-ui/ui-router/commit/3f60fbe6d65ebeca8d97952c05aa1d269f1b7ba1), closes [#1396])\n  * reload() now reinvokes controllers ([73443420](https://github.com/angular-ui/ui-router/commit/7344342018847902594dc1fc62d30a5c30f01763), closes [#582])\n  * do not emit $viewContentLoading if notify: false ([74255feb](https://github.com/angular-ui/ui-router/commit/74255febdf48ae082a02ca1e735165f2c369a463), closes [#1387](https://github.com/angular-ui/ui-router/issues/1387))\n  * register states at config-time ([4533fe36](https://github.com/angular-ui/ui-router/commit/4533fe36e0ab2f0143edd854a4145deaa013915a))\n  * handle parent.name when parent is obj ([4533fe36](https://github.com/angular-ui/ui-router/commit/4533fe36e0ab2f0143edd854a4145deaa013915a))\n* **$urlMatcherFactory:**\n  * register types at config ([4533fe36](https://github.com/angular-ui/ui-router/commit/4533fe36e0ab2f0143edd854a4145deaa013915a), closes [#1476])\n  * made path params default value \"\" for backwards compat ([8f998e71](https://github.com/angular-ui/ui-router/commit/8f998e71e43a0b31293331c981f5db0f0097b8ba))\n  * Pre-replace certain param values for better mapping ([6374a3e2](https://github.com/angular-ui/ui-router/commit/6374a3e29ab932014a7c77d2e1ab884cc841a2e3))\n  * fixed ParamSet.$$keys() ordering ([9136fecb](https://github.com/angular-ui/ui-router/commit/9136fecbc2bfd4fda748a9914f0225a46c933860))\n  * empty string policy now respected in Param.value() ([db12c85c](https://github.com/angular-ui/ui-router/commit/db12c85c16f2d105415f9bbbdeb11863f64728e0))\n  * \"string\" type now encodes/decodes slashes ([3045e415](https://github.com/angular-ui/ui-router/commit/3045e41577a8b8b8afc6039f42adddf5f3c061ec), closes [#1119])\n  * allow arrays in both path and query params ([fdd2f2c1](https://github.com/angular-ui/ui-router/commit/fdd2f2c191c4a67c874fdb9ec9a34f8dde9ad180), closes [#1073], [#1045], [#1486], [#1394])\n  * typed params in search ([8d4cab69](https://github.com/angular-ui/ui-router/commit/8d4cab69dd67058e1a716892cc37b7d80a57037f), closes [#1488](https://github.com/angular-ui/ui-router/issues/1488))\n  * no longer generate unroutable urls ([cb9fd9d8](https://github.com/angular-ui/ui-router/commit/cb9fd9d8943cb26c7223f6990db29c82ae8740f8), closes [#1487](https://github.com/angular-ui/ui-router/issues/1487))\n  * handle optional parameter followed by required parameter in url format. ([efc72106](https://github.com/angular-ui/ui-router/commit/efc72106ddcc4774b48ea176a505ef9e95193b41))\n  * default to parameter string coersion. ([13a468a7](https://github.com/angular-ui/ui-router/commit/13a468a7d54c2fb0751b94c0c1841d580b71e6dc), closes [#1414](https://github.com/angular-ui/ui-router/issues/1414))\n  * concat respects strictMode/caseInsensitive ([dd72e103](https://github.com/angular-ui/ui-router/commit/dd72e103edb342d9cf802816fe127e1bbd68fd5f), closes [#1395])\n* **ui-sref:**\n  * Allow sref state options to take a scope object ([b5f7b596](https://github.com/angular-ui/ui-router/commit/b5f7b59692ce4933e2d63eb5df3f50a4ba68ccc0))\n  * replace raw href modification with attrs. ([08c96782](https://github.com/angular-ui/ui-router/commit/08c96782faf881b0c7ab00afc233ee6729548fa0))\n  * nagivate to state when url is \"\" fix($state.href): generate href for state with  ([656b5aab](https://github.com/angular-ui/ui-router/commit/656b5aab906e5749db9b5a080c6a83b95f50fd91), closes [#1363](https://github.com/angular-ui/ui-router/issues/1363))\n  * Check that state is defined in isMatch() ([92aebc75](https://github.com/angular-ui/ui-router/commit/92aebc7520f88babdc6e266536086e07263514c3), closes [#1314](https://github.com/angular-ui/ui-router/issues/1314), [#1332](https://github.com/angular-ui/ui-router/issues/1332))\n* **uiView:**\n  * allow inteprolated ui-view names ([81f6a19a](https://github.com/angular-ui/ui-router/commit/81f6a19a432dac9198fd33243855bfd3b4fea8c0), closes [#1324](https://github.com/angular-ui/ui-router/issues/1324))\n  * Made anim work with angular 1.3 ([c3bb7ad9](https://github.com/angular-ui/ui-router/commit/c3bb7ad903da1e1f3c91019cfd255be8489ff4ef), closes [#1367](https://github.com/angular-ui/ui-router/issues/1367), [#1345](https://github.com/angular-ui/ui-router/issues/1345))\n* **urlRouter:** html5Mode accepts an object from angular v1.3.0-rc.3 ([7fea1e9d](https://github.com/angular-ui/ui-router/commit/7fea1e9d0d8c6e09cc6c895ecb93d4221e9adf48))\n* **stateFilters:** mark state filters as stateful. ([a00b353e](https://github.com/angular-ui/ui-router/commit/a00b353e3036f64a81245c4e7898646ba218f833), closes [#1479])\n* **ui-router:** re-add IE8 compatibility for map/filter/keys ([8ce69d9f](https://github.com/angular-ui/ui-router/commit/8ce69d9f7c886888ab53eca7e53536f36b428aae), closes [#1518], [#1383])\n* **package:** point 'main' to a valid filename ([ac903350](https://github.com/angular-ui/ui-router/commit/ac9033501debb63364539d91fbf3a0cba4579f8e))\n* **travis:** make CI build faster ([0531de05](https://github.com/angular-ui/ui-router/commit/0531de052e414a8d839fbb4e7635e923e94865b3))\n\n\n#### Features\n\n##### Default and Typed params\n\nThis release includes a lot of bug fixes around default/optional and typed parameters.  As such, 0.2.12 is the first release where we recommend those features be used.\n\n* **$state:**\n  * add state params validation ([b1379e6a](https://github.com/angular-ui/ui-router/commit/b1379e6a4d38f7ed7436e05873932d7c279af578), closes [#1433](https://github.com/angular-ui/ui-router/issues/1433))\n  * is/includes/get work on relative stateOrName ([232e94b3](https://github.com/angular-ui/ui-router/commit/232e94b3c2ca2c764bb9510046e4b61690c87852))\n  * .reload() returns state transition promise ([639e0565](https://github.com/angular-ui/ui-router/commit/639e0565dece9d5544cc93b3eee6e11c99bd7373))\n* **$templateFactory:** request templateURL as text/html ([ccd60769](https://github.com/angular-ui/ui-router/commit/ccd6076904a4b801d77b47f6e2de4c06ce9962f8), closes [#1287])\n* **$urlMatcherFactory:** Made a Params and ParamSet class ([0cc1e6cc](https://github.com/angular-ui/ui-router/commit/0cc1e6cc461a4640618e2bb594566551c54834e2))\n\n\n\n<a name=\"0.2.11\"></a>\n### 0.2.11 (2014-08-26)\n\n\n#### Bug Fixes\n\n* **$resolve:** Resolves only inherit from immediate parent fixes #702 ([df34e20c](https://github.com/angular-ui/ui-router/commit/df34e20c576299e7a3c8bd4ebc68d42341c0ace9))\n* **$state:**\n  * change $state.href default options.inherit to true ([deea695f](https://github.com/angular-ui/ui-router/commit/deea695f5cacc55de351ab985144fd233c02a769))\n  * sanity-check state lookups ([456fd5ae](https://github.com/angular-ui/ui-router/commit/456fd5aec9ea507518927bfabd62b4afad4cf714), closes [#980](https://github.com/angular-ui/ui-router/issues/980))\n  * didn't comply to inherit parameter ([09836781](https://github.com/angular-ui/ui-router/commit/09836781f126c1c485b06551eb9cfd4fa0f45c35))\n  * allow view content loading broadcast ([7b78edee](https://github.com/angular-ui/ui-router/commit/7b78edeeb52a74abf4d3f00f79534033d5a08d1a))\n* **$urlMatcherFactory:**\n  * detect injected functions ([91f75ae6](https://github.com/angular-ui/ui-router/commit/91f75ae66c4d129f6f69e53bd547594e9661f5d5))\n  * syntax ([1ebed370](https://github.com/angular-ui/ui-router/commit/1ebed37069bae8614d41541d56521f5c45f703f3))\n* **UrlMatcher:**\n  * query param function defaults ([f9c20530](https://github.com/angular-ui/ui-router/commit/f9c205304f10d8a4ebe7efe9025e642016479a51))\n  * don't decode default values ([63607bdb](https://github.com/angular-ui/ui-router/commit/63607bdbbcb432d3fb37856a1cb3da0cd496804e))\n* **travis:** update Node version to fix build ([d6b95ef2](https://github.com/angular-ui/ui-router/commit/d6b95ef23d9dacb4eba08897f5190a0bcddb3a48))\n* **uiSref:**\n  * Generate an href for states with a blank url. closes #1293 ([691745b1](https://github.com/angular-ui/ui-router/commit/691745b12fa05d3700dd28f0c8d25f8a105074ad))\n  * should inherit params by default ([b973dad1](https://github.com/angular-ui/ui-router/commit/b973dad155ad09a7975e1476bd096f7b2c758eeb))\n  * cancel transition if preventDefault() has been called ([2e6d9167](https://github.com/angular-ui/ui-router/commit/2e6d9167d3afbfbca6427e53e012f94fb5fb8022))\n* **uiView:** Fixed infinite loop when is called .go() from a controller. ([e13988b8](https://github.com/angular-ui/ui-router/commit/e13988b8cd6231d75c78876ee9d012cc87f4a8d9), closes [#1194](https://github.com/angular-ui/ui-router/issues/1194))\n* **docs:**\n  * Fixed link to milestones ([6c0ae500](https://github.com/angular-ui/ui-router/commit/6c0ae500cc238ea9fc95adcc15415c55fc9e1f33))\n  * fix bug in decorator example ([4bd00af5](https://github.com/angular-ui/ui-router/commit/4bd00af50b8b88a49d1545a76290731cb8e0feb1))\n  * Removed an incorrect semi-colon ([af97cef8](https://github.com/angular-ui/ui-router/commit/af97cef8b967f2e32177e539ef41450dca131a7d))\n  * Explain return value of rule as function ([5e887890](https://github.com/angular-ui/ui-router/commit/5e8878900a6ffe59a81aed531a3925e34a297377))\n\n\n#### Features\n\n* **$state:**\n  * allow parameters to pass unharmed ([8939d057](https://github.com/angular-ui/ui-router/commit/8939d0572ab1316e458ef016317ecff53131a822))\n    * **BREAKING CHANGE**: state parameters are no longer automatically coerced to strings, and unspecified parameter values are now set to undefined rather than null.\n  * allow prevent syncUrl on failure ([753060b9](https://github.com/angular-ui/ui-router/commit/753060b910d5d2da600a6fa0757976e401c33172))\n* **typescript:** Add typescript definitions for component builds ([521ceb3f](https://github.com/angular-ui/ui-router/commit/521ceb3fd7850646422f411921e21ce5e7d82e0f))\n* **uiSref:** extend syntax for ui-sref ([71cad3d6](https://github.com/angular-ui/ui-router/commit/71cad3d636508b5a9fe004775ad1f1adc0c80c3e))\n* **uiSrefActive:** \n  * Also activate for child states. ([bf163ad6](https://github.com/angular-ui/ui-router/commit/bf163ad6ce176ce28792696c8302d7cdf5c05a01), closes [#818](https://github.com/angular-ui/ui-router/issues/818))\n    * **BREAKING CHANGE** Since ui-sref-active now activates even when child states are active you may need to swap out your ui-sref-active with ui-sref-active-eq, thought typically we think devs want the auto inheritance.\n\n  * uiSrefActiveEq: new directive with old ui-sref-active behavior\n* **$urlRouter:**\n  * defer URL change interception ([c72d8ce1](https://github.com/angular-ui/ui-router/commit/c72d8ce11916d0ac22c81b409c9e61d7048554d7))\n  * force URLs to have valid params ([d48505cd](https://github.com/angular-ui/ui-router/commit/d48505cd328d83e39d5706e085ba319715f999a6))\n  * abstract $location handling ([08b4636b](https://github.com/angular-ui/ui-router/commit/08b4636b294611f08db35f00641eb5211686fb50))\n* **$urlMatcherFactory:**\n  * fail on bad parameters ([d8f124c1](https://github.com/angular-ui/ui-router/commit/d8f124c10d00c7e5dde88c602d966db261aea221))\n  * date type support ([b7f074ff](https://github.com/angular-ui/ui-router/commit/b7f074ff65ca150a3cdbda4d5ad6cb17107300eb))\n  * implement type support ([450b1f0e](https://github.com/angular-ui/ui-router/commit/450b1f0e8e03c738174ff967f688b9a6373290f4))\n* **UrlMatcher:**\n  * handle query string arrays ([9cf764ef](https://github.com/angular-ui/ui-router/commit/9cf764efab45fa9309368688d535ddf6e96d6449), closes [#373](https://github.com/angular-ui/ui-router/issues/373))\n  * injectable functions as defaults ([00966ecd](https://github.com/angular-ui/ui-router/commit/00966ecd91fb745846039160cab707bfca8b3bec))\n  * default values & type decoding for query params ([a472b301](https://github.com/angular-ui/ui-router/commit/a472b301389fbe84d1c1fa9f24852b492a569d11))\n  * allow shorthand definitions ([5b724304](https://github.com/angular-ui/ui-router/commit/5b7243049793505e44b6608ea09878c37c95b1f5))\n  * validates whole interface ([32b27db1](https://github.com/angular-ui/ui-router/commit/32b27db173722e9194ef1d5c0ea7d93f25a98d11))\n  * implement non-strict matching ([a3e21366](https://github.com/angular-ui/ui-router/commit/a3e21366bee0475c9795a1ec76f70eec41c5b4e3))\n  * add per-param config support ([07b3029f](https://github.com/angular-ui/ui-router/commit/07b3029f4d409cf955780113df92e36401b47580))\n    * **BREAKING CHANGE**: the `params` option in state configurations must now be an object keyed by parameter name.\n\n### 0.2.10 (2014-03-12)\n\n\n#### Bug Fixes\n\n* **$state:** use $browser.baseHref() when generating urls with .href() ([cbcc8488](https://github.com/angular-ui/ui-router/commit/cbcc84887d6b6d35258adabb97c714cd9c1e272d))\n* **bower.json:** JS files should not be ignored ([ccdab193](https://github.com/angular-ui/ui-router/commit/ccdab193315f304eb3be5f5b97c47a926c79263e))\n* **dev:** karma:background task is missing, can't run grunt:dev. ([d9f7b898](https://github.com/angular-ui/ui-router/commit/d9f7b898e8e3abb8c846b0faa16a382913d7b22b))\n* **sample:** Contacts menu button not staying active when navigating to detail states. Need t ([2fcb8443](https://github.com/angular-ui/ui-router/commit/2fcb84437cb43ade12682a92b764f13cac77dfe7))\n* **uiSref:** support mock-clicks/events with no data ([717d3ff7](https://github.com/angular-ui/ui-router/commit/717d3ff7d0ba72d239892dee562b401cdf90e418))\n* **uiView:**\n  * Do NOT autoscroll when autoscroll attr is missing ([affe5bd7](https://github.com/angular-ui/ui-router/commit/affe5bd785cdc3f02b7a9f64a52e3900386ec3a0), closes [#807](https://github.com/angular-ui/ui-router/issues/807))\n  * Refactoring uiView directive to copy ngView logic ([548fab6a](https://github.com/angular-ui/ui-router/commit/548fab6ab9debc9904c5865c8bc68b4fc3271dd0), closes [#857](https://github.com/angular-ui/ui-router/issues/857), [#552](https://github.com/angular-ui/ui-router/issues/552))\n\n\n#### Features\n\n* **$state:** includes() allows glob patterns for state matching. ([2d5f6b37](https://github.com/angular-ui/ui-router/commit/2d5f6b37191a3135f4a6d9e8f344c54edcdc065b))\n* **UrlMatcher:** Add support for case insensitive url matching ([642d5247](https://github.com/angular-ui/ui-router/commit/642d524799f604811e680331002feec7199a1fb5))\n* **uiSref:** add support for transition options ([2ed7a728](https://github.com/angular-ui/ui-router/commit/2ed7a728cee6854b38501fbc1df6139d3de5b28a))\n* **uiView:** add controllerAs config with function ([1ee7334a](https://github.com/angular-ui/ui-router/commit/1ee7334a73efeccc9b95340e315cdfd59944762d))\n\n\n### 0.2.9 (2014-01-17)\n\n\nThis release is identical to 0.2.8. 0.2.8 was re-tagged in git to fix a problem with bower.\n\n\n### 0.2.8 (2014-01-16)\n\n\n#### Bug Fixes\n\n* **$state:** allow null to be passed as 'params' param ([094dc30e](https://github.com/angular-ui/ui-router/commit/094dc30e883e1bd14e50a475553bafeaade3b178))\n* **$state.go:** param inheritance shouldn't inherit from siblings ([aea872e0](https://github.com/angular-ui/ui-router/commit/aea872e0b983cb433436ce5875df10c838fccedb))\n* **bower.json:** fixes bower.json ([eed3cc4d](https://github.com/angular-ui/ui-router/commit/eed3cc4d4dfef1d3ef84b9fd063127538ebf59d3))\n* **uiSrefActive:** annotate controller injection ([85921422](https://github.com/angular-ui/ui-router/commit/85921422ff7fb0effed358136426d616cce3d583), closes [#671](https://github.com/angular-ui/ui-router/issues/671))\n* **uiView:**\n  * autoscroll tests pass on 1.2.4 & 1.1.5 ([86eacac0](https://github.com/angular-ui/ui-router/commit/86eacac09ca5e9000bd3b9c7ba6e2cc95d883a3a))\n  * don't animate initial load ([83b6634d](https://github.com/angular-ui/ui-router/commit/83b6634d27942ca74766b2b1244a7fc52c5643d9))\n  * test pass against 1.0.8 and 1.2.4 ([a402415a](https://github.com/angular-ui/ui-router/commit/a402415a2a28b360c43b9fe8f4f54c540f6c33de))\n  * it should autoscroll when expr is missing. ([8bb9e27a](https://github.com/angular-ui/ui-router/commit/8bb9e27a2986725f45daf44c4c9f846385095aff))\n\n\n#### Features\n\n* **uiSref:** add target attribute behaviour ([c12bf9a5](https://github.com/angular-ui/ui-router/commit/c12bf9a520d30d70294e3d82de7661900f8e394e))\n* **uiView:**\n  * merge autoscroll expression test. ([b89e0f87](https://github.com/angular-ui/ui-router/commit/b89e0f871d5cc35c10925ede986c10684d5c9252))\n  * cache and test autoscroll expression ([ee262282](https://github.com/angular-ui/ui-router/commit/ee2622828c2ce83807f006a459ac4e11406d9258))\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-ui-router/CONTRIBUTING.md",
    "content": "\n# Report an Issue\n\nHelp us make UI-Router better! If you think you might have found a bug, or some other weirdness, start by making sure\nit hasn't already been reported. You can [search through existing issues](https://github.com/angular-ui/ui-router/search?q=wat%3F&type=Issues)\nto see if someone's reported one similar to yours.\n\nIf not, then [create a plunkr](http://bit.ly/UIR-Plunk) that demonstrates the problem (try to use as little code\nas possible: the more minimalist, the faster we can debug it).\n\nNext, [create a new issue](https://github.com/angular-ui/ui-router/issues/new) that briefly explains the problem,\nand provides a bit of background as to the circumstances that triggered it. Don't forget to include the link to\nthat plunkr you created!\n\n**Note**: If you're unsure how a feature is used, or are encountering some unexpected behavior that you aren't sure\nis a bug, it's best to talk it out on\n[StackOverflow](http://stackoverflow.com/questions/ask?tags=angularjs,angular-ui-router) before reporting it. This\nkeeps development streamlined, and helps us focus on building great software.\n\n\nIssues only! |\n-------------|\nPlease keep in mind that the issue tracker is for *issues*. Please do *not* post an issue if you need help or support. Instead, see one of the above-mentioned forums or [IRC](irc://irc.freenode.net/#angularjs). |\n\n####Purple Labels\nA purple label means that **you** need to take some further action.  \n - ![Not Actionable - Need Info](http://angular-ui.github.io/ui-router/images/notactionable.png): Your issue is not specific enough, or there is no clear action that we can take. Please clarify and refine your issue.\n - ![Plunkr Please](http://angular-ui.github.io/ui-router/images/plunkrplease.png): Please [create a plunkr](http://bit.ly/UIR-Plunk)\n - ![StackOverflow](http://angular-ui.github.io/ui-router/images/stackoverflow.png): We suspect your issue is really a help request, or could be answered by the community.  Please ask your question on [StackOverflow](http://stackoverflow.com/questions/ask?tags=angularjs,angular-ui-router).  If you determine that is an actual issue, please explain why.\n \nIf your issue gets labeled with purple label, no further action will be taken until you respond to the label appropriately.\n\n# Contribute\n\n**(1)** See the **[Developing](#developing)** section below, to get the development version of UI-Router up and running on your local machine.\n\n**(2)** Check out the [roadmap](https://github.com/angular-ui/ui-router/milestones) to see where the project is headed, and if your feature idea fits with where we're headed.\n\n**(3)** If you're not sure, [open an RFC](https://github.com/angular-ui/ui-router/issues/new?title=RFC:%20My%20idea) to get some feedback on your idea.\n\n**(4)** Finally, commit some code and open a pull request. Code & commits should abide by the following rules:\n\n- *Always* have test coverage for new features (or regression tests for bug fixes), and *never* break existing tests\n- Commits should represent one logical change each; if a feature goes through multiple iterations, squash your commits down to one\n- Make sure to follow the [Angular commit message format](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#commit-message-format) so your change will appear in the changelog of the next release.\n- Changes should always respect the coding style of the project\n\n\n\n# Developing\n\nUI-Router uses <code>grunt >= 0.4.x</code>. Make sure to upgrade your environment and read the\n[Migration Guide](http://gruntjs.com/upgrading-from-0.3-to-0.4).\n\nDependencies for building from source and running tests:\n\n* [grunt-cli](https://github.com/gruntjs/grunt-cli) - run: `$ npm install -g grunt-cli`\n* Then, install the development dependencies by running `$ npm install` from the project directory\n\nThere are a number of targets in the gruntfile that are used to generating different builds:\n\n* `grunt`: Perform a normal build, runs jshint and karma tests\n* `grunt build`: Perform a normal build\n* `grunt dist`: Perform a clean build and generate documentation\n* `grunt dev`: Run dev server (sample app) and watch for changes, builds and runs karma tests on changes.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-ui-router/LICENSE",
    "content": "The MIT License\n\nCopyright (c) 2013-2015 The AngularUI Team, Karsten Sperling\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-ui-router/README.md",
    "content": "# AngularUI Router &nbsp;[![Build Status](https://travis-ci.org/angular-ui/ui-router.svg?branch=master)](https://travis-ci.org/angular-ui/ui-router)\n\n#### The de-facto solution to flexible routing with nested views\n---\n**[Download 0.2.14](http://angular-ui.github.io/ui-router/release/angular-ui-router.js)** (or **[Minified](http://angular-ui.github.io/ui-router/release/angular-ui-router.min.js)**) **|**\n**[Guide](https://github.com/angular-ui/ui-router/wiki) |**\n**[API](http://angular-ui.github.io/ui-router/site) |**\n**[Sample](http://angular-ui.github.com/ui-router/sample/) ([Src](https://github.com/angular-ui/ui-router/tree/gh-pages/sample)) |**\n**[FAQ](https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions) |**\n**[Resources](#resources) |**\n**[Report an Issue](https://github.com/angular-ui/ui-router/blob/master/CONTRIBUTING.md#report-an-issue) |**\n**[Contribute](https://github.com/angular-ui/ui-router/blob/master/CONTRIBUTING.md#contribute) |**\n**[Help!](http://stackoverflow.com/questions/ask?tags=angularjs,angular-ui-router) |**\n**[Discuss](https://groups.google.com/forum/#!categories/angular-ui/router)**\n\n---\n\nAngularUI Router is a routing framework for [AngularJS](http://angularjs.org), which allows you to organize the\nparts of your interface into a [*state machine*](https://en.wikipedia.org/wiki/Finite-state_machine). Unlike the\n[`$route` service](http://docs.angularjs.org/api/ngRoute.$route) in the Angular ngRoute module, which is organized around URL\nroutes, UI-Router is organized around [*states*](https://github.com/angular-ui/ui-router/wiki),\nwhich may optionally have routes, as well as other behavior, attached.\n\nStates are bound to *named*, *nested* and *parallel views*, allowing you to powerfully manage your application's interface.\n\nCheck out the sample app: http://angular-ui.github.io/ui-router/sample/\n\n-\n**Note:** *UI-Router is under active development. As such, while this library is well-tested, the API may change. Consider using it in production applications only if you're comfortable following a changelog and updating your usage accordingly.*\n\n\n## Get Started\n\n**(1)** Get UI-Router in one of the following ways:\n - clone & [build](CONTRIBUTING.md#developing) this repository\n - [download the release](http://angular-ui.github.io/ui-router/release/angular-ui-router.js) (or [minified](http://angular-ui.github.io/ui-router/release/angular-ui-router.min.js))\n - [link to cdn](http://cdnjs.com/libraries/angular-ui-router)\n - via **[jspm](http://jspm.io/)**: by running `$ jspm install angular-ui-router` from your console\n - or via **[npm](https://www.npmjs.org/)**: by running `$ npm install angular-ui-router` from your console\n - or via **[Bower](http://bower.io/)**: by running `$ bower install angular-ui-router` from your console\n - or via **[Component](https://github.com/component/component)**: by running `$ component install angular-ui/ui-router` from your console\n\n**(2)** Include `angular-ui-router.js` (or `angular-ui-router.min.js`) in your `index.html`, after including Angular itself (For Component users: ignore this step)\n\n**(3)** Add `'ui.router'` to your main module's list of dependencies (For Component users: replace `'ui.router'` with `require('angular-ui-router')`)\n\nWhen you're done, your setup should look similar to the following:\n\n>\n```html\n<!doctype html>\n<html ng-app=\"myApp\">\n<head>\n    <script src=\"//ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js\"></script>\n    <script src=\"js/angular-ui-router.min.js\"></script>\n    <script>\n        var myApp = angular.module('myApp', ['ui.router']);\n        // For Component users, it should look like this:\n        // var myApp = angular.module('myApp', [require('angular-ui-router')]);\n    </script>\n    ...\n</head>\n<body>\n    ...\n</body>\n</html>\n```\n\n### [Nested States & Views](http://plnkr.co/edit/u18KQc?p=preview)\n\nThe majority of UI-Router's power is in its ability to nest states & views.\n\n**(1)** First, follow the [setup](#get-started) instructions detailed above.\n\n**(2)** Then, add a [`ui-view` directive](https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-view) to the `<body />` of your app.\n\n>\n```html\n<!-- index.html -->\n<body>\n    <div ui-view></div>\n    <!-- We'll also add some navigation: -->\n    <a ui-sref=\"state1\">State 1</a>\n    <a ui-sref=\"state2\">State 2</a>\n</body>\n```\n\n**(3)** You'll notice we also added some links with [`ui-sref` directives](https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref). In addition to managing state transitions, this directive auto-generates the `href` attribute of the `<a />` element it's attached to, if the corresponding state has a URL. Next we'll add some templates. These will plug into the `ui-view` within `index.html`. Notice that they have their own `ui-view` as well! That is the key to nesting states and views.\n\n>\n```html\n<!-- partials/state1.html -->\n<h1>State 1</h1>\n<hr/>\n<a ui-sref=\"state1.list\">Show List</a>\n<div ui-view></div>\n```\n```html\n<!-- partials/state2.html -->\n<h1>State 2</h1>\n<hr/>\n<a ui-sref=\"state2.list\">Show List</a>\n<div ui-view></div>\n```\n\n**(4)** Next, we'll add some child templates. *These* will get plugged into the `ui-view` of their parent state templates.\n\n>\n```html\n<!-- partials/state1.list.html -->\n<h3>List of State 1 Items</h3>\n<ul>\n  <li ng-repeat=\"item in items\">{{ item }}</li>\n</ul>\n```\n\n>\n```html\n<!-- partials/state2.list.html -->\n<h3>List of State 2 Things</h3>\n<ul>\n  <li ng-repeat=\"thing in things\">{{ thing }}</li>\n</ul>\n```\n\n**(5)** Finally, we'll wire it all up with `$stateProvider`. Set up your states in the module config, as in the following:\n\n\n>\n```javascript\nmyApp.config(function($stateProvider, $urlRouterProvider) {\n  //\n  // For any unmatched url, redirect to /state1\n  $urlRouterProvider.otherwise(\"/state1\");\n  //\n  // Now set up the states\n  $stateProvider\n    .state('state1', {\n      url: \"/state1\",\n      templateUrl: \"partials/state1.html\"\n    })\n    .state('state1.list', {\n      url: \"/list\",\n      templateUrl: \"partials/state1.list.html\",\n      controller: function($scope) {\n        $scope.items = [\"A\", \"List\", \"Of\", \"Items\"];\n      }\n    })\n    .state('state2', {\n      url: \"/state2\",\n      templateUrl: \"partials/state2.html\"\n    })\n    .state('state2.list', {\n      url: \"/list\",\n      templateUrl: \"partials/state2.list.html\",\n      controller: function($scope) {\n        $scope.things = [\"A\", \"Set\", \"Of\", \"Things\"];\n      }\n    });\n});\n```\n\n**(6)** See this quick start example in action.\n>**[Go to Quick Start Plunker for Nested States & Views](http://plnkr.co/edit/u18KQc?p=preview)**\n\n**(7)** This only scratches the surface\n>**[Dive Deeper!](https://github.com/angular-ui/ui-router/wiki)**\n\n\n### [Multiple & Named Views](http://plnkr.co/edit/SDOcGS?p=preview)\n\nAnother great feature is the ability to have multiple `ui-view`s view per template.\n\n**Pro Tip:** *While multiple parallel views are a powerful feature, you'll often be able to manage your\ninterfaces more effectively by nesting your views, and pairing those views with nested states.*\n\n**(1)** Follow the [setup](#get-started) instructions detailed above.\n\n**(2)** Add one or more `ui-view` to your app, give them names.\n>\n```html\n<!-- index.html -->\n<body>\n    <div ui-view=\"viewA\"></div>\n    <div ui-view=\"viewB\"></div>\n    <!-- Also a way to navigate -->\n    <a ui-sref=\"route1\">Route 1</a>\n    <a ui-sref=\"route2\">Route 2</a>\n</body>\n```\n\n**(3)** Set up your states in the module config:\n>\n```javascript\nmyApp.config(function($stateProvider) {\n  $stateProvider\n    .state('index', {\n      url: \"\",\n      views: {\n        \"viewA\": { template: \"index.viewA\" },\n        \"viewB\": { template: \"index.viewB\" }\n      }\n    })\n    .state('route1', {\n      url: \"/route1\",\n      views: {\n        \"viewA\": { template: \"route1.viewA\" },\n        \"viewB\": { template: \"route1.viewB\" }\n      }\n    })\n    .state('route2', {\n      url: \"/route2\",\n      views: {\n        \"viewA\": { template: \"route2.viewA\" },\n        \"viewB\": { template: \"route2.viewB\" }\n      }\n    })\n});\n```\n\n**(4)** See this quick start example in action.\n>**[Go to Quick Start Plunker for Multiple & Named Views](http://plnkr.co/edit/SDOcGS?p=preview)**\n\n\n## Resources\n\n* [In-Depth Guide](https://github.com/angular-ui/ui-router/wiki)\n* [API Reference](http://angular-ui.github.io/ui-router/site)\n* [Sample App](http://angular-ui.github.com/ui-router/sample/) ([Source](https://github.com/angular-ui/ui-router/tree/gh-pages/sample))\n* [FAQ](https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions)\n* [Slides comparing ngRoute to ui-router](http://slid.es/timkindberg/ui-router#/)\n* [UI-Router Extras / Addons](http://christopherthielen.github.io/ui-router-extras/#/home) (@christopherthielen)\n \n### Videos\n\n* [Introduction Video](https://egghead.io/lessons/angularjs-introduction-ui-router) (egghead.io)\n* [Tim Kindberg on Angular UI-Router](https://www.youtube.com/watch?v=lBqiZSemrqg)\n* [Activating States](https://egghead.io/lessons/angularjs-ui-router-activating-states) (egghead.io)\n* [Learn Angular.js using UI-Router](http://youtu.be/QETUuZ27N0w) (LearnCode.academy)\n\n\n\n## Reporting issues and Contributing\n\nPlease read our [Contributor guidelines](CONTRIBUTING.md) before reporting an issue or creating a pull request.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-ui-router/api/angular-ui-router.d.ts",
    "content": "// Type definitions for Angular JS 1.1.5+ (ui.router module)\n// Project: https://github.com/angular-ui/ui-router\n// Definitions by: Michel Salib <https://github.com/michelsalib>\n// Definitions: https://github.com/borisyankov/DefinitelyTyped\n\ndeclare module ng.ui {\n\n    interface IState {\n        name?: string;\n        template?: string;\n        templateUrl?: any; // string || () => string\n        templateProvider?: any; // () => string || IPromise<string>\n        controller?: any;\n        controllerAs?: string;    \n        controllerProvider?: any;\n        resolve?: {};\n        url?: string;\n        params?: any;\n        views?: {};\n        abstract?: boolean;\n        onEnter?: (...args: any[]) => void;\n        onExit?: (...args: any[]) => void;\n        data?: any;\n        reloadOnSearch?: boolean;\n    }\n\n    interface ITypedState<T> extends IState {\n        data?: T;\n    }\n\n    interface IStateProvider extends IServiceProvider {\n        state(name: string, config: IState): IStateProvider;\n        state(config: IState): IStateProvider;\n        decorator(name?: string, decorator?: (state: IState, parent: Function) => any): any;\n    }\n\n    interface IUrlMatcher {\n        concat(pattern: string): IUrlMatcher;\n        exec(path: string, searchParams: {}): {};\n        parameters(): string[];\n        format(values: {}): string;\n    }\n\n    interface IUrlMatcherFactory {\n        compile(pattern: string): IUrlMatcher;\n        isMatcher(o: any): boolean;\n    }\n\n    interface IUrlRouterProvider extends IServiceProvider {\n        when(whenPath: RegExp, handler: Function): IUrlRouterProvider;\n        when(whenPath: RegExp, handler: any[]): IUrlRouterProvider;\n        when(whenPath: RegExp, toPath: string): IUrlRouterProvider;\n        when(whenPath: IUrlMatcher, hanlder: Function): IUrlRouterProvider;\n        when(whenPath: IUrlMatcher, handler: any[]): IUrlRouterProvider;\n        when(whenPath: IUrlMatcher, toPath: string): IUrlRouterProvider;\n        when(whenPath: string, handler: Function): IUrlRouterProvider;\n        when(whenPath: string, handler: any[]): IUrlRouterProvider;\n        when(whenPath: string, toPath: string): IUrlRouterProvider;\n        otherwise(handler: Function): IUrlRouterProvider;\n        otherwise(handler: any[]): IUrlRouterProvider;\n        otherwise(path: string): IUrlRouterProvider;\n        rule(handler: Function): IUrlRouterProvider;\n        rule(handler: any[]): IUrlRouterProvider;\n    }\n\n    interface IStateOptions {\n        location?: any;\n        inherit?: boolean;\n        relative?: IState;\n        notify?: boolean;\n        reload?: boolean;\n    }\n\n    interface IHrefOptions {\n        lossy?: boolean;\n        inherit?: boolean;\n        relative?: IState;\n        absolute?: boolean;\n    }\n\n    interface IStateService {\n        go(to: string, params?: {}, options?: IStateOptions): IPromise<any>;\n        transitionTo(state: string, params?: {}, updateLocation?: boolean): void;\n        transitionTo(state: string, params?: {}, options?: IStateOptions): void;\n        includes(state: string, params?: {}): boolean;\n        is(state:string, params?: {}): boolean;\n        is(state: IState, params?: {}): boolean;\n        href(state: IState, params?: {}, options?: IHrefOptions): string;\n        href(state: string, params?: {}, options?: IHrefOptions): string;\n        get(state: string): IState;\n        get(): IState[];\n        current: IState;\n        params: any;\n        reload(): void;\n    }\n\n    interface IStateParamsService {\n        [key: string]: any;\n    }\n\n    interface IStateParams {\n        [key: string]: any;\n    }\n\n    interface IUrlRouterService {\n        /*\n         * Triggers an update; the same update that happens when the address bar\n         * url changes, aka $locationChangeSuccess.\n         *\n         * This method is useful when you need to use preventDefault() on the\n         * $locationChangeSuccess event, perform some custom logic (route protection,\n         * auth, config, redirection, etc) and then finally proceed with the transition\n         * by calling $urlRouter.sync().\n         *\n         */\n        sync(): void;\n    }\n\n    interface IUiViewScrollProvider {\n        /*\n         * Reverts back to using the core $anchorScroll service for scrolling \n         * based on the url anchor.\n         */\n        useAnchorScroll(): void;\n    }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-ui-router/bower.json",
    "content": "{\n  \"name\": \"angular-ui-router\",\n  \"version\": \"0.2.14\",\n  \"main\": \"./release/angular-ui-router.js\",\n  \"dependencies\": {\n    \"angular\": \">= 1.0.8\"\n  },\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"component.json\",\n    \"package.json\",\n    \"lib\",\n    \"config\",\n    \"sample\",\n    \"test\",\n    \"tests\",\n    \"ngdoc_assets\",\n    \"Gruntfile.js\",\n    \"files.js\"\n  ]\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-ui-router/release/angular-ui-router.js",
    "content": "\n/* commonjs package manager support (eg componentjs) */\nif (typeof module !== \"undefined\" && typeof exports !== \"undefined\" && module.exports === exports){\n  module.exports = 'ui.router';\n}\n\n(function (window, angular, undefined) {\n/*jshint globalstrict:true*/\n/*global angular:false*/\n'use strict';\n\nvar isDefined = angular.isDefined,\n    isFunction = angular.isFunction,\n    isString = angular.isString,\n    isObject = angular.isObject,\n    isArray = angular.isArray,\n    forEach = angular.forEach,\n    extend = angular.extend,\n    copy = angular.copy;\n\nfunction inherit(parent, extra) {\n  return extend(new (extend(function() {}, { prototype: parent }))(), extra);\n}\n\nfunction merge(dst) {\n  forEach(arguments, function(obj) {\n    if (obj !== dst) {\n      forEach(obj, function(value, key) {\n        if (!dst.hasOwnProperty(key)) dst[key] = value;\n      });\n    }\n  });\n  return dst;\n}\n\nfunction ancestors(first, second) {\n  var path = [];\n\n  for (var n in first.path) {\n    if (first.path[n] !== second.path[n]) break;\n    path.push(first.path[n]);\n  }\n  return path;\n}\n\nfunction objectKeys(object) {\n  if (Object.keys) {\n    return Object.keys(object);\n  }\n  var result = [];\n\n  forEach(object, function(val, key) {\n    result.push(key);\n  });\n  return result;\n}\n\nfunction indexOf(array, value) {\n  if (Array.prototype.indexOf) {\n    return array.indexOf(value, Number(arguments[2]) || 0);\n  }\n  var len = array.length >>> 0, from = Number(arguments[2]) || 0;\n  from = (from < 0) ? Math.ceil(from) : Math.floor(from);\n\n  if (from < 0) from += len;\n\n  for (; from < len; from++) {\n    if (from in array && array[from] === value) return from;\n  }\n  return -1;\n}\n\nfunction inheritParams(currentParams, newParams, $current, $to) {\n  var parents = ancestors($current, $to), parentParams, inherited = {}, inheritList = [];\n\n  for (var i in parents) {\n    if (!parents[i].params) continue;\n    parentParams = objectKeys(parents[i].params);\n    if (!parentParams.length) continue;\n\n    for (var j in parentParams) {\n      if (indexOf(inheritList, parentParams[j]) >= 0) continue;\n      inheritList.push(parentParams[j]);\n      inherited[parentParams[j]] = currentParams[parentParams[j]];\n    }\n  }\n  return extend({}, inherited, newParams);\n}\n\nfunction equalForKeys(a, b, keys) {\n  if (!keys) {\n    keys = [];\n    for (var n in a) keys.push(n); // Used instead of Object.keys() for IE8 compatibility\n  }\n\n  for (var i=0; i<keys.length; i++) {\n    var k = keys[i];\n    if (a[k] != b[k]) return false; // Not '===', values aren't necessarily normalized\n  }\n  return true;\n}\n\nfunction filterByKeys(keys, values) {\n  var filtered = {};\n\n  forEach(keys, function (name) {\n    filtered[name] = values[name];\n  });\n  return filtered;\n}\nfunction indexBy(array, propName) {\n  var result = {};\n  forEach(array, function(item) {\n    result[item[propName]] = item;\n  });\n  return result;\n}\nfunction pick(obj) {\n  var copy = {};\n  var keys = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));\n  forEach(keys, function(key) {\n    if (key in obj) copy[key] = obj[key];\n  });\n  return copy;\n}\nfunction omit(obj) {\n  var copy = {};\n  var keys = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));\n  for (var key in obj) {\n    if (indexOf(keys, key) == -1) copy[key] = obj[key];\n  }\n  return copy;\n}\n\nfunction pluck(collection, key) {\n  var result = isArray(collection) ? [] : {};\n\n  forEach(collection, function(val, i) {\n    result[i] = isFunction(key) ? key(val) : val[key];\n  });\n  return result;\n}\n\nfunction filter(collection, callback) {\n  var array = isArray(collection);\n  var result = array ? [] : {};\n  forEach(collection, function(val, i) {\n    if (callback(val, i)) {\n      result[array ? result.length : i] = val;\n    }\n  });\n  return result;\n}\n\nfunction map(collection, callback) {\n  var result = isArray(collection) ? [] : {};\n\n  forEach(collection, function(val, i) {\n    result[i] = callback(val, i);\n  });\n  return result;\n}\n\nangular.module('ui.router.util', ['ng']);\n\nangular.module('ui.router.router', ['ui.router.util']);\n\nangular.module('ui.router.state', ['ui.router.router', 'ui.router.util']);\n\nangular.module('ui.router', ['ui.router.state']);\n\nangular.module('ui.router.compat', ['ui.router']);\n\n$Resolve.$inject = ['$q', '$injector'];\nfunction $Resolve(  $q,    $injector) {\n  \n  var VISIT_IN_PROGRESS = 1,\n      VISIT_DONE = 2,\n      NOTHING = {},\n      NO_DEPENDENCIES = [],\n      NO_LOCALS = NOTHING,\n      NO_PARENT = extend($q.when(NOTHING), { $$promises: NOTHING, $$values: NOTHING });\n  \n\n    this.study = function (invocables) {\n    if (!isObject(invocables)) throw new Error(\"'invocables' must be an object\");\n    var invocableKeys = objectKeys(invocables || {});\n    var plan = [], cycle = [], visited = {};\n    function visit(value, key) {\n      if (visited[key] === VISIT_DONE) return;\n      \n      cycle.push(key);\n      if (visited[key] === VISIT_IN_PROGRESS) {\n        cycle.splice(0, indexOf(cycle, key));\n        throw new Error(\"Cyclic dependency: \" + cycle.join(\" -> \"));\n      }\n      visited[key] = VISIT_IN_PROGRESS;\n      \n      if (isString(value)) {\n        plan.push(key, [ function() { return $injector.get(value); }], NO_DEPENDENCIES);\n      } else {\n        var params = $injector.annotate(value);\n        forEach(params, function (param) {\n          if (param !== key && invocables.hasOwnProperty(param)) visit(invocables[param], param);\n        });\n        plan.push(key, value, params);\n      }\n      \n      cycle.pop();\n      visited[key] = VISIT_DONE;\n    }\n    forEach(invocables, visit);\n    invocables = cycle = visited = null; // plan is all that's required\n    \n    function isResolve(value) {\n      return isObject(value) && value.then && value.$$promises;\n    }\n    \n    return function (locals, parent, self) {\n      if (isResolve(locals) && self === undefined) {\n        self = parent; parent = locals; locals = null;\n      }\n      if (!locals) locals = NO_LOCALS;\n      else if (!isObject(locals)) {\n        throw new Error(\"'locals' must be an object\");\n      }       \n      if (!parent) parent = NO_PARENT;\n      else if (!isResolve(parent)) {\n        throw new Error(\"'parent' must be a promise returned by $resolve.resolve()\");\n      }\n      var resolution = $q.defer(),\n          result = resolution.promise,\n          promises = result.$$promises = {},\n          values = extend({}, locals),\n          wait = 1 + plan.length/3,\n          merged = false;\n          \n      function done() {\n        if (!--wait) {\n          if (!merged) merge(values, parent.$$values); \n          result.$$values = values;\n          result.$$promises = result.$$promises || true; // keep for isResolve()\n          delete result.$$inheritedValues;\n          resolution.resolve(values);\n        }\n      }\n      \n      function fail(reason) {\n        result.$$failure = reason;\n        resolution.reject(reason);\n      }\n      if (isDefined(parent.$$failure)) {\n        fail(parent.$$failure);\n        return result;\n      }\n      \n      if (parent.$$inheritedValues) {\n        merge(values, omit(parent.$$inheritedValues, invocableKeys));\n      }\n      extend(promises, parent.$$promises);\n      if (parent.$$values) {\n        merged = merge(values, omit(parent.$$values, invocableKeys));\n        result.$$inheritedValues = omit(parent.$$values, invocableKeys);\n        done();\n      } else {\n        if (parent.$$inheritedValues) {\n          result.$$inheritedValues = omit(parent.$$inheritedValues, invocableKeys);\n        }        \n        parent.then(done, fail);\n      }\n      for (var i=0, ii=plan.length; i<ii; i+=3) {\n        if (locals.hasOwnProperty(plan[i])) done();\n        else invoke(plan[i], plan[i+1], plan[i+2]);\n      }\n      \n      function invoke(key, invocable, params) {\n        var invocation = $q.defer(), waitParams = 0;\n        function onfailure(reason) {\n          invocation.reject(reason);\n          fail(reason);\n        }\n        forEach(params, function (dep) {\n          if (promises.hasOwnProperty(dep) && !locals.hasOwnProperty(dep)) {\n            waitParams++;\n            promises[dep].then(function (result) {\n              values[dep] = result;\n              if (!(--waitParams)) proceed();\n            }, onfailure);\n          }\n        });\n        if (!waitParams) proceed();\n        function proceed() {\n          if (isDefined(result.$$failure)) return;\n          try {\n            invocation.resolve($injector.invoke(invocable, self, values));\n            invocation.promise.then(function (result) {\n              values[key] = result;\n              done();\n            }, onfailure);\n          } catch (e) {\n            onfailure(e);\n          }\n        }\n        promises[key] = invocation.promise;\n      }\n      \n      return result;\n    };\n  };\n  \n    this.resolve = function (invocables, locals, parent, self) {\n    return this.study(invocables)(locals, parent, self);\n  };\n}\n\nangular.module('ui.router.util').service('$resolve', $Resolve);\n\n\n$TemplateFactory.$inject = ['$http', '$templateCache', '$injector'];\nfunction $TemplateFactory(  $http,   $templateCache,   $injector) {\n\n    this.fromConfig = function (config, params, locals) {\n    return (\n      isDefined(config.template) ? this.fromString(config.template, params) :\n      isDefined(config.templateUrl) ? this.fromUrl(config.templateUrl, params) :\n      isDefined(config.templateProvider) ? this.fromProvider(config.templateProvider, params, locals) :\n      null\n    );\n  };\n\n    this.fromString = function (template, params) {\n    return isFunction(template) ? template(params) : template;\n  };\n\n    this.fromUrl = function (url, params) {\n    if (isFunction(url)) url = url(params);\n    if (url == null) return null;\n    else return $http\n        .get(url, { cache: $templateCache, headers: { Accept: 'text/html' }})\n        .then(function(response) { return response.data; });\n  };\n\n    this.fromProvider = function (provider, params, locals) {\n    return $injector.invoke(provider, null, locals || { params: params });\n  };\n}\n\nangular.module('ui.router.util').service('$templateFactory', $TemplateFactory);\n\nvar $$UMFP; // reference to $UrlMatcherFactoryProvider\n\nfunction UrlMatcher(pattern, config, parentMatcher) {\n  config = extend({ params: {} }, isObject(config) ? config : {});\n  var placeholder       = /([:*])([\\w\\[\\]]+)|\\{([\\w\\[\\]]+)(?:\\:((?:[^{}\\\\]+|\\\\.|\\{(?:[^{}\\\\]+|\\\\.)*\\})+))?\\}/g,\n      searchPlaceholder = /([:]?)([\\w\\[\\]-]+)|\\{([\\w\\[\\]-]+)(?:\\:((?:[^{}\\\\]+|\\\\.|\\{(?:[^{}\\\\]+|\\\\.)*\\})+))?\\}/g,\n      compiled = '^', last = 0, m,\n      segments = this.segments = [],\n      parentParams = parentMatcher ? parentMatcher.params : {},\n      params = this.params = parentMatcher ? parentMatcher.params.$$new() : new $$UMFP.ParamSet(),\n      paramNames = [];\n\n  function addParameter(id, type, config, location) {\n    paramNames.push(id);\n    if (parentParams[id]) return parentParams[id];\n    if (!/^\\w+(-+\\w+)*(?:\\[\\])?$/.test(id)) throw new Error(\"Invalid parameter name '\" + id + \"' in pattern '\" + pattern + \"'\");\n    if (params[id]) throw new Error(\"Duplicate parameter name '\" + id + \"' in pattern '\" + pattern + \"'\");\n    params[id] = new $$UMFP.Param(id, type, config, location);\n    return params[id];\n  }\n\n  function quoteRegExp(string, pattern, squash, optional) {\n    var surroundPattern = ['',''], result = string.replace(/[\\\\\\[\\]\\^$*+?.()|{}]/g, \"\\\\$&\");\n    if (!pattern) return result;\n    switch(squash) {\n      case false: surroundPattern = ['(', ')' + (optional ? \"?\" : \"\")]; break;\n      case true:  surroundPattern = ['?(', ')?']; break;\n      default:    surroundPattern = ['(' + squash + \"|\", ')?']; break;\n    }\n    return result + surroundPattern[0] + pattern + surroundPattern[1];\n  }\n\n  this.source = pattern;\n  function matchDetails(m, isSearch) {\n    var id, regexp, segment, type, cfg, arrayMode;\n    id          = m[2] || m[3]; // IE[78] returns '' for unmatched groups instead of null\n    cfg         = config.params[id];\n    segment     = pattern.substring(last, m.index);\n    regexp      = isSearch ? m[4] : m[4] || (m[1] == '*' ? '.*' : null);\n    type        = $$UMFP.type(regexp || \"string\") || inherit($$UMFP.type(\"string\"), { pattern: new RegExp(regexp, config.caseInsensitive ? 'i' : undefined) });\n    return {\n      id: id, regexp: regexp, segment: segment, type: type, cfg: cfg\n    };\n  }\n\n  var p, param, segment;\n  while ((m = placeholder.exec(pattern))) {\n    p = matchDetails(m, false);\n    if (p.segment.indexOf('?') >= 0) break; // we're into the search part\n\n    param = addParameter(p.id, p.type, p.cfg, \"path\");\n    compiled += quoteRegExp(p.segment, param.type.pattern.source, param.squash, param.isOptional);\n    segments.push(p.segment);\n    last = placeholder.lastIndex;\n  }\n  segment = pattern.substring(last);\n  var i = segment.indexOf('?');\n\n  if (i >= 0) {\n    var search = this.sourceSearch = segment.substring(i);\n    segment = segment.substring(0, i);\n    this.sourcePath = pattern.substring(0, last + i);\n\n    if (search.length > 0) {\n      last = 0;\n      while ((m = searchPlaceholder.exec(search))) {\n        p = matchDetails(m, true);\n        param = addParameter(p.id, p.type, p.cfg, \"search\");\n        last = placeholder.lastIndex;\n      }\n    }\n  } else {\n    this.sourcePath = pattern;\n    this.sourceSearch = '';\n  }\n\n  compiled += quoteRegExp(segment) + (config.strict === false ? '\\/?' : '') + '$';\n  segments.push(segment);\n\n  this.regexp = new RegExp(compiled, config.caseInsensitive ? 'i' : undefined);\n  this.prefix = segments[0];\n  this.$$paramNames = paramNames;\n}\n\nUrlMatcher.prototype.concat = function (pattern, config) {\n  var defaultConfig = {\n    caseInsensitive: $$UMFP.caseInsensitive(),\n    strict: $$UMFP.strictMode(),\n    squash: $$UMFP.defaultSquashPolicy()\n  };\n  return new UrlMatcher(this.sourcePath + pattern + this.sourceSearch, extend(defaultConfig, config), this);\n};\n\nUrlMatcher.prototype.toString = function () {\n  return this.source;\n};\n\nUrlMatcher.prototype.exec = function (path, searchParams) {\n  var m = this.regexp.exec(path);\n  if (!m) return null;\n  searchParams = searchParams || {};\n\n  var paramNames = this.parameters(), nTotal = paramNames.length,\n    nPath = this.segments.length - 1,\n    values = {}, i, j, cfg, paramName;\n\n  if (nPath !== m.length - 1) throw new Error(\"Unbalanced capture group in route '\" + this.source + \"'\");\n\n  function decodePathArray(string) {\n    function reverseString(str) { return str.split(\"\").reverse().join(\"\"); }\n    function unquoteDashes(str) { return str.replace(/\\\\-/g, \"-\"); }\n\n    var split = reverseString(string).split(/-(?!\\\\)/);\n    var allReversed = map(split, reverseString);\n    return map(allReversed, unquoteDashes).reverse();\n  }\n\n  for (i = 0; i < nPath; i++) {\n    paramName = paramNames[i];\n    var param = this.params[paramName];\n    var paramVal = m[i+1];\n    for (j = 0; j < param.replace; j++) {\n      if (param.replace[j].from === paramVal) paramVal = param.replace[j].to;\n    }\n    if (paramVal && param.array === true) paramVal = decodePathArray(paramVal);\n    values[paramName] = param.value(paramVal);\n  }\n  for (UrlMatcher.prototype.parameters = function (param) {\n  if (!isDefined(param)) return this.$$paramNames;\n  return this.params[param] || null;\n};\n\nUrlMatcher.prototype.validates = function (params) {\n  return this.params.$$validates(params);\n};\n\nUrlMatcher.prototype.format = function (values) {\n  values = values || {};\n  var segments = this.segments, params = this.parameters(), paramset = this.params;\n  if (!this.validates(values)) return null;\n\n  var i, search = false, nPath = segments.length - 1, nTotal = params.length, result = segments[0];\n\n  function encodeDashes(str) { // Replace dashes with encoded \"\\-\"\n    return encodeURIComponent(str).replace(/-/g, function(c) { return '%5C%' + c.charCodeAt(0).toString(16).toUpperCase(); });\n  }\n\n  for (i = 0; i < nTotal; i++) {\n    var isPathParam = i < nPath;\n    var name = params[i], param = paramset[name], value = param.value(values[name]);\n    var isDefaultValue = param.isOptional && param.type.equals(param.value(), value);\n    var squash = isDefaultValue ? param.squash : false;\n    var encoded = param.type.encode(value);\n\n    if (isPathParam) {\n      var nextSegment = segments[i + 1];\n      if (squash === false) {\n        if (encoded != null) {\n          if (isArray(encoded)) {\n            result += map(encoded, encodeDashes).join(\"-\");\n          } else {\n            result += encodeURIComponent(encoded);\n          }\n        }\n        result += nextSegment;\n      } else if (squash === true) {\n        var capture = result.match(/\\/$/) ? /\\/?(.*)/ : /(.*)/;\n        result += nextSegment.match(capture)[1];\n      } else if (isString(squash)) {\n        result += squash + nextSegment;\n      }\n    } else {\n      if (encoded == null || (isDefaultValue && squash !== false)) continue;\n      if (!isArray(encoded)) encoded = [ encoded ];\n      encoded = map(encoded, encodeURIComponent).join('&' + name + '=');\n      result += (search ? '&' : '?') + (name + '=' + encoded);\n      search = true;\n    }\n  }\n\n  return result;\n};\n\nfunction Type(config) {\n  extend(this, config);\n}\n\nType.prototype.is = function(val, key) {\n  return true;\n};\n\nType.prototype.encode = function(val, key) {\n  return val;\n};\n\nType.prototype.decode = function(val, key) {\n  return val;\n};\n\nType.prototype.equals = function(a, b) {\n  return a == b;\n};\n\nType.prototype.$subPattern = function() {\n  var sub = this.pattern.toString();\n  return sub.substr(1, sub.length - 2);\n};\n\nType.prototype.pattern = /.*/;\n\nType.prototype.toString = function() { return \"{Type:\" + this.name + \"}\"; };\n\nType.prototype.$normalize = function(val) {\n  return this.is(val) ? val : this.decode(val);\n};\n\n/*\n * Wraps an existing custom Type as an array of Type, depending on 'mode'.\n * e.g.:\n * - urlmatcher pattern \"/path?{queryParam[]:int}\"\n * - url: \"/path?queryParam=1&queryParam=2\n * - $stateParams.queryParam will be [1, 2]\n * if `mode` is \"auto\", then\n * - url: \"/path?queryParam=1 will create $stateParams.queryParam: 1\n * - url: \"/path?queryParam=1&queryParam=2 will create $stateParams.queryParam: [1, 2]\n */\nType.prototype.$asArray = function(mode, isSearch) {\n  if (!mode) return this;\n  if (mode === \"auto\" && !isSearch) throw new Error(\"'auto' array mode is for query parameters only\");\n\n  function ArrayType(type, mode) {\n    function bindTo(type, callbackName) {\n      return function() {\n        return type[callbackName].apply(type, arguments);\n      };\n    }\n    function arrayWrap(val) { return isArray(val) ? val : (isDefined(val) ? [ val ] : []); }\n    function arrayUnwrap(val) {\n      switch(val.length) {\n        case 0: return undefined;\n        case 1: return mode === \"auto\" ? val[0] : val;\n        default: return val;\n      }\n    }\n    function falsey(val) { return !val; }\n    function arrayHandler(callback, allTruthyMode) {\n      return function handleArray(val) {\n        val = arrayWrap(val);\n        var result = map(val, callback);\n        if (allTruthyMode === true)\n          return filter(result, falsey).length === 0;\n        return arrayUnwrap(result);\n      };\n    }\n    function arrayEqualsHandler(callback) {\n      return function handleArray(val1, val2) {\n        var left = arrayWrap(val1), right = arrayWrap(val2);\n        if (left.length !== right.length) return false;\n        for (var i = 0; i < left.length; i++) {\n          if (!callback(left[i], right[i])) return false;\n        }\n        return true;\n      };\n    }\n\n    this.encode = arrayHandler(bindTo(type, 'encode'));\n    this.decode = arrayHandler(bindTo(type, 'decode'));\n    this.is     = arrayHandler(bindTo(type, 'is'), true);\n    this.equals = arrayEqualsHandler(bindTo(type, 'equals'));\n    this.pattern = type.pattern;\n    this.$normalize = arrayHandler(bindTo(type, '$normalize'));\n    this.name = type.name;\n    this.$arrayMode = mode;\n  }\n\n  return new ArrayType(this, mode);\n};\n\n\n\nfunction $UrlMatcherFactory() {\n  $$UMFP = this;\n\n  var isCaseInsensitive = false, isStrictMode = true, defaultSquashPolicy = false;\n\n  function valToString(val) { return val != null ? val.toString().replace(/\\//g, \"%2F\") : val; }\n  function valFromString(val) { return val != null ? val.toString().replace(/%2F/g, \"/\") : val; }\n  function regexpMatches(val) { /*jshint validthis:true */ return this.pattern.test(val); }\n\n  var $types = {}, enqueue = true, typeQueue = [], injector, defaultTypes = {\n    string: {\n      encode: valToString,\n      decode: valFromString,\n      is: function(val) { return typeof val === \"string\"; },\n      pattern: /[^/]*/\n    },\n    int: {\n      encode: valToString,\n      decode: function(val) { return parseInt(val, 10); },\n      is: function(val) { return isDefined(val) && this.decode(val.toString()) === val; },\n      pattern: /\\d+/\n    },\n    bool: {\n      encode: function(val) { return val ? 1 : 0; },\n      decode: function(val) { return parseInt(val, 10) !== 0; },\n      is: function(val) { return val === true || val === false; },\n      pattern: /0|1/\n    },\n    date: {\n      encode: function (val) {\n        if (!this.is(val))\n          return undefined;\n        return [ val.getFullYear(),\n          ('0' + (val.getMonth() + 1)).slice(-2),\n          ('0' + val.getDate()).slice(-2)\n        ].join(\"-\");\n      },\n      decode: function (val) {\n        if (this.is(val)) return val;\n        var match = this.capture.exec(val);\n        return match ? new Date(match[1], match[2] - 1, match[3]) : undefined;\n      },\n      is: function(val) { return val instanceof Date && !isNaN(val.valueOf()); },\n      equals: function (a, b) { return this.is(a) && this.is(b) && a.toISOString() === b.toISOString(); },\n      pattern: /[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1])/,\n      capture: /([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/\n    },\n    json: {\n      encode: angular.toJson,\n      decode: angular.fromJson,\n      is: angular.isObject,\n      equals: angular.equals,\n      pattern: /[^/]*/\n    },\n    any: { // does not encode/decode\n      encode: angular.identity,\n      decode: angular.identity,\n      is: angular.identity,\n      equals: angular.equals,\n      pattern: /.*/\n    }\n  };\n\n  function getDefaultConfig() {\n    return {\n      strict: isStrictMode,\n      caseInsensitive: isCaseInsensitive\n    };\n  }\n\n  function isInjectable(value) {\n    return (isFunction(value) || (isArray(value) && isFunction(value[value.length - 1])));\n  }\n\n    $UrlMatcherFactory.$$getDefaultValue = function(config) {\n    if (!isInjectable(config.value)) return config.value;\n    if (!injector) throw new Error(\"Injectable functions cannot be called at configuration time\");\n    return injector.invoke(config.value);\n  };\n\n    this.caseInsensitive = function(value) {\n    if (isDefined(value))\n      isCaseInsensitive = value;\n    return isCaseInsensitive;\n  };\n\n    this.strictMode = function(value) {\n    if (isDefined(value))\n      isStrictMode = value;\n    return isStrictMode;\n  };\n\n    this.defaultSquashPolicy = function(value) {\n    if (!isDefined(value)) return defaultSquashPolicy;\n    if (value !== true && value !== false && !isString(value))\n      throw new Error(\"Invalid squash policy: \" + value + \". Valid policies: false, true, arbitrary-string\");\n    defaultSquashPolicy = value;\n    return value;\n  };\n\n    this.compile = function (pattern, config) {\n    return new UrlMatcher(pattern, extend(getDefaultConfig(), config));\n  };\n\n    this.isMatcher = function (o) {\n    if (!isObject(o)) return false;\n    var result = true;\n\n    forEach(UrlMatcher.prototype, function(val, name) {\n      if (isFunction(val)) {\n        result = result && (isDefined(o[name]) && isFunction(o[name]));\n      }\n    });\n    return result;\n  };\n\n    this.type = function (name, definition, definitionFn) {\n    if (!isDefined(definition)) return $types[name];\n    if ($types.hasOwnProperty(name)) throw new Error(\"A type named '\" + name + \"' has already been defined.\");\n\n    $types[name] = new Type(extend({ name: name }, definition));\n    if (definitionFn) {\n      typeQueue.push({ name: name, def: definitionFn });\n      if (!enqueue) flushTypeQueue();\n    }\n    return this;\n  };\n  function flushTypeQueue() {\n    while(typeQueue.length) {\n      var type = typeQueue.shift();\n      if (type.pattern) throw new Error(\"You cannot override a type's .pattern at runtime.\");\n      angular.extend($types[type.name], injector.invoke(type.def));\n    }\n  }\n  forEach(defaultTypes, function(type, name) { $types[name] = new Type(extend({name: name}, type)); });\n  $types = inherit($types, {});\n\n  /* No need to document $get, since it returns this */\n  this.$get = ['$injector', function ($injector) {\n    injector = $injector;\n    enqueue = false;\n    flushTypeQueue();\n\n    forEach(defaultTypes, function(type, name) {\n      if (!$types[name]) $types[name] = new Type(type);\n    });\n    return this;\n  }];\n\n  this.Param = function Param(id, type, config, location) {\n    var self = this;\n    config = unwrapShorthand(config);\n    type = getType(config, type, location);\n    var arrayMode = getArrayMode();\n    type = arrayMode ? type.$asArray(arrayMode, location === \"search\") : type;\n    if (type.name === \"string\" && !arrayMode && location === \"path\" && config.value === undefined)\n      config.value = \"\"; // for 0.2.x; in 0.3.0+ do not automatically default to \"\"\n    var isOptional = config.value !== undefined;\n    var squash = getSquashPolicy(config, isOptional);\n    var replace = getReplace(config, arrayMode, isOptional, squash);\n\n    function unwrapShorthand(config) {\n      var keys = isObject(config) ? objectKeys(config) : [];\n      var isShorthand = indexOf(keys, \"value\") === -1 && indexOf(keys, \"type\") === -1 &&\n                        indexOf(keys, \"squash\") === -1 && indexOf(keys, \"array\") === -1;\n      if (isShorthand) config = { value: config };\n      config.$$fn = isInjectable(config.value) ? config.value : function () { return config.value; };\n      return config;\n    }\n\n    function getType(config, urlType, location) {\n      if (config.type && urlType) throw new Error(\"Param '\"+id+\"' has two type configurations.\");\n      if (urlType) return urlType;\n      if (!config.type) return (location === \"config\" ? $types.any : $types.string);\n      return config.type instanceof Type ? config.type : new Type(config.type);\n    }\n    function getArrayMode() {\n      var arrayDefaults = { array: (location === \"search\" ? \"auto\" : false) };\n      var arrayParamNomenclature = id.match(/\\[\\]$/) ? { array: true } : {};\n      return extend(arrayDefaults, arrayParamNomenclature, config).array;\n    }\n\n        function getSquashPolicy(config, isOptional) {\n      var squash = config.squash;\n      if (!isOptional || squash === false) return false;\n      if (!isDefined(squash) || squash == null) return defaultSquashPolicy;\n      if (squash === true || isString(squash)) return squash;\n      throw new Error(\"Invalid squash policy: '\" + squash + \"'. Valid policies: false, true, or arbitrary string\");\n    }\n\n    function getReplace(config, arrayMode, isOptional, squash) {\n      var replace, configuredKeys, defaultPolicy = [\n        { from: \"\",   to: (isOptional || arrayMode ? undefined : \"\") },\n        { from: null, to: (isOptional || arrayMode ? undefined : \"\") }\n      ];\n      replace = isArray(config.replace) ? config.replace : [];\n      if (isString(squash))\n        replace.push({ from: squash, to: undefined });\n      configuredKeys = map(replace, function(item) { return item.from; } );\n      return filter(defaultPolicy, function(item) { return indexOf(configuredKeys, item.from) === -1; }).concat(replace);\n    }\n\n        function $$getDefaultValue() {\n      if (!injector) throw new Error(\"Injectable functions cannot be called at configuration time\");\n      var defaultValue = injector.invoke(config.$$fn);\n      if (defaultValue !== null && defaultValue !== undefined && !self.type.is(defaultValue))\n        throw new Error(\"Default value (\" + defaultValue + \") for parameter '\" + self.id + \"' is not an instance of Type (\" + self.type.name + \")\");\n      return defaultValue;\n    }\n\n        function $value(value) {\n      function hasReplaceVal(val) { return function(obj) { return obj.from === val; }; }\n      function $replace(value) {\n        var replacement = map(filter(self.replace, hasReplaceVal(value)), function(obj) { return obj.to; });\n        return replacement.length ? replacement[0] : value;\n      }\n      value = $replace(value);\n      return !isDefined(value) ? $$getDefaultValue() : self.type.$normalize(value);\n    }\n\n    function toString() { return \"{Param:\" + id + \" \" + type + \" squash: '\" + squash + \"' optional: \" + isOptional + \"}\"; }\n\n    extend(this, {\n      id: id,\n      type: type,\n      location: location,\n      array: arrayMode,\n      squash: squash,\n      replace: replace,\n      isOptional: isOptional,\n      value: $value,\n      dynamic: undefined,\n      config: config,\n      toString: toString\n    });\n  };\n\n  function ParamSet(params) {\n    extend(this, params || {});\n  }\n\n  ParamSet.prototype = {\n    $$new: function() {\n      return inherit(this, extend(new ParamSet(), { $$parent: this}));\n    },\n    $$keys: function () {\n      var keys = [], chain = [], parent = this,\n        ignore = objectKeys(ParamSet.prototype);\n      while (parent) { chain.push(parent); parent = parent.$$parent; }\n      chain.reverse();\n      forEach(chain, function(paramset) {\n        forEach(objectKeys(paramset), function(key) {\n            if (indexOf(keys, key) === -1 && indexOf(ignore, key) === -1) keys.push(key);\n        });\n      });\n      return keys;\n    },\n    $$values: function(paramValues) {\n      var values = {}, self = this;\n      forEach(self.$$keys(), function(key) {\n        values[key] = self[key].value(paramValues && paramValues[key]);\n      });\n      return values;\n    },\n    $$equals: function(paramValues1, paramValues2) {\n      var equal = true, self = this;\n      forEach(self.$$keys(), function(key) {\n        var left = paramValues1 && paramValues1[key], right = paramValues2 && paramValues2[key];\n        if (!self[key].type.equals(left, right)) equal = false;\n      });\n      return equal;\n    },\n    $$validates: function $$validate(paramValues) {\n      var keys = this.$$keys(), i, param, rawVal, normalized, encoded;\n      for (i = 0; i < keys.length; i++) {\n        param = this[keys[i]];\n        rawVal = paramValues[keys[i]];\n        if ((rawVal === undefined || rawVal === null) && param.isOptional)\n          break; // There was no parameter value, but the param is optional\n        normalized = param.type.$normalize(rawVal);\n        if (!param.type.is(normalized))\n          return false; // The value was not of the correct Type, and could not be decoded to the correct Type\n        encoded = param.type.encode(normalized);\n        if (angular.isString(encoded) && !param.type.pattern.exec(encoded))\n          return false; // The value was of the correct type, but when encoded, did not match the Type's regexp\n      }\n      return true;\n    },\n    $$parent: undefined\n  };\n\n  this.ParamSet = ParamSet;\n}\nangular.module('ui.router.util').provider('$urlMatcherFactory', $UrlMatcherFactory);\nangular.module('ui.router.util').run(['$urlMatcherFactory', function($urlMatcherFactory) { }]);\n\n$UrlRouterProvider.$inject = ['$locationProvider', '$urlMatcherFactoryProvider'];\nfunction $UrlRouterProvider(   $locationProvider,   $urlMatcherFactory) {\n  var rules = [], otherwise = null, interceptDeferred = false, listener;\n  function regExpPrefix(re) {\n    var prefix = /^\\^((?:\\\\[^a-zA-Z0-9]|[^\\\\\\[\\]\\^$*+?.()|{}]+)*)/.exec(re.source);\n    return (prefix != null) ? prefix[1].replace(/\\\\(.)/g, \"$1\") : '';\n  }\n  function interpolate(pattern, match) {\n    return pattern.replace(/\\$(\\$|\\d{1,2})/, function (m, what) {\n      return match[what === '$' ? 0 : Number(what)];\n    });\n  }\n\n    this.rule = function (rule) {\n    if (!isFunction(rule)) throw new Error(\"'rule' must be a function\");\n    rules.push(rule);\n    return this;\n  };\n\n    this.otherwise = function (rule) {\n    if (isString(rule)) {\n      var redirect = rule;\n      rule = function () { return redirect; };\n    }\n    else if (!isFunction(rule)) throw new Error(\"'rule' must be a function\");\n    otherwise = rule;\n    return this;\n  };\n\n\n  function handleIfMatch($injector, handler, match) {\n    if (!match) return false;\n    var result = $injector.invoke(handler, handler, { $match: match });\n    return isDefined(result) ? result : true;\n  }\n\n    this.when = function (what, handler) {\n    var redirect, handlerIsString = isString(handler);\n    if (isString(what)) what = $urlMatcherFactory.compile(what);\n\n    if (!handlerIsString && !isFunction(handler) && !isArray(handler))\n      throw new Error(\"invalid 'handler' in when()\");\n\n    var strategies = {\n      matcher: function (what, handler) {\n        if (handlerIsString) {\n          redirect = $urlMatcherFactory.compile(handler);\n          handler = ['$match', function ($match) { return redirect.format($match); }];\n        }\n        return extend(function ($injector, $location) {\n          return handleIfMatch($injector, handler, what.exec($location.path(), $location.search()));\n        }, {\n          prefix: isString(what.prefix) ? what.prefix : ''\n        });\n      },\n      regex: function (what, handler) {\n        if (what.global || what.sticky) throw new Error(\"when() RegExp must not be global or sticky\");\n\n        if (handlerIsString) {\n          redirect = handler;\n          handler = ['$match', function ($match) { return interpolate(redirect, $match); }];\n        }\n        return extend(function ($injector, $location) {\n          return handleIfMatch($injector, handler, what.exec($location.path()));\n        }, {\n          prefix: regExpPrefix(what)\n        });\n      }\n    };\n\n    var check = { matcher: $urlMatcherFactory.isMatcher(what), regex: what instanceof RegExp };\n\n    for (var n in check) {\n      if (check[n]) return this.rule(strategies[n](what, handler));\n    }\n\n    throw new Error(\"invalid 'what' in when()\");\n  };\n\n    this.deferIntercept = function (defer) {\n    if (defer === undefined) defer = true;\n    interceptDeferred = defer;\n  };\n\n    this.$get = $get;\n  $get.$inject = ['$location', '$rootScope', '$injector', '$browser'];\n  function $get(   $location,   $rootScope,   $injector,   $browser) {\n\n    var baseHref = $browser.baseHref(), location = $location.url(), lastPushedUrl;\n\n    function appendBasePath(url, isHtml5, absolute) {\n      if (baseHref === '/') return url;\n      if (isHtml5) return baseHref.slice(0, -1) + url;\n      if (absolute) return baseHref.slice(1) + url;\n      return url;\n    }\n    function update(evt) {\n      if (evt && evt.defaultPrevented) return;\n      var ignoreUpdate = lastPushedUrl && $location.url() === lastPushedUrl;\n      lastPushedUrl = undefined;\n      if (ignoreUpdate) return true;\n\n      function check(rule) {\n        var handled = rule($injector, $location);\n\n        if (!handled) return false;\n        if (isString(handled)) $location.replace().url(handled);\n        return true;\n      }\n      var n = rules.length, i;\n\n      for (i = 0; i < n; i++) {\n        if (check(rules[i])) return;\n      }\n      if (otherwise) check(otherwise);\n    }\n\n    function listen() {\n      listener = listener || $rootScope.$on('$locationChangeSuccess', update);\n      return listener;\n    }\n\n    if (!interceptDeferred) listen();\n\n    return {\n            sync: function() {\n        update();\n      },\n\n      listen: function() {\n        return listen();\n      },\n\n      update: function(read) {\n        if (read) {\n          location = $location.url();\n          return;\n        }\n        if ($location.url() === location) return;\n\n        $location.url(location);\n        $location.replace();\n      },\n\n      push: function(urlMatcher, params, options) {\n         var url = urlMatcher.format(params || {});\n        if (url !== null && params && params['#']) {\n            url += '#' + params['#'];\n        }\n\n        $location.url(url);\n        lastPushedUrl = options && options.$$avoidResync ? $location.url() : undefined;\n        if (options && options.replace) $location.replace();\n      },\n\n            href: function(urlMatcher, params, options) {\n        if (!urlMatcher.validates(params)) return null;\n\n        var isHtml5 = $locationProvider.html5Mode();\n        if (angular.isObject(isHtml5)) {\n          isHtml5 = isHtml5.enabled;\n        }\n        \n        var url = urlMatcher.format(params);\n        options = options || {};\n\n        if (!isHtml5 && url !== null) {\n          url = \"#\" + $locationProvider.hashPrefix() + url;\n        }\n        if (url !== null && params && params['#']) {\n          url += '#' + params['#'];\n        }\n\n        url = appendBasePath(url, isHtml5, options.absolute);\n\n        if (!options.absolute || !url) {\n          return url;\n        }\n\n        var slash = (!isHtml5 && url ? '/' : ''), port = $location.port();\n        port = (port === 80 || port === 443 ? '' : ':' + port);\n\n        return [$location.protocol(), '://', $location.host(), port, slash, url].join('');\n      }\n    };\n  }\n}\n\nangular.module('ui.router.router').provider('$urlRouter', $UrlRouterProvider);\n\n$StateProvider.$inject = ['$urlRouterProvider', '$urlMatcherFactoryProvider'];\nfunction $StateProvider(   $urlRouterProvider,   $urlMatcherFactory) {\n\n  var root, states = {}, $state, queue = {}, abstractKey = 'abstract';\n  var stateBuilder = {\n    parent: function(state) {\n      if (isDefined(state.parent) && state.parent) return findState(state.parent);\n      var compositeName = /^(.+)\\.[^.]+$/.exec(state.name);\n      return compositeName ? findState(compositeName[1]) : root;\n    },\n    data: function(state) {\n      if (state.parent && state.parent.data) {\n        state.data = state.self.data = extend({}, state.parent.data, state.data);\n      }\n      return state.data;\n    },\n    url: function(state) {\n      var url = state.url, config = { params: state.params || {} };\n\n      if (isString(url)) {\n        if (url.charAt(0) == '^') return $urlMatcherFactory.compile(url.substring(1), config);\n        return (state.parent.navigable || root).url.concat(url, config);\n      }\n\n      if (!url || $urlMatcherFactory.isMatcher(url)) return url;\n      throw new Error(\"Invalid url '\" + url + \"' in state '\" + state + \"'\");\n    },\n    navigable: function(state) {\n      return state.url ? state : (state.parent ? state.parent.navigable : null);\n    },\n    ownParams: function(state) {\n      var params = state.url && state.url.params || new $$UMFP.ParamSet();\n      forEach(state.params || {}, function(config, id) {\n        if (!params[id]) params[id] = new $$UMFP.Param(id, null, config, \"config\");\n      });\n      return params;\n    },\n    params: function(state) {\n      return state.parent && state.parent.params ? extend(state.parent.params.$$new(), state.ownParams) : new $$UMFP.ParamSet();\n    },\n    views: function(state) {\n      var views = {};\n\n      forEach(isDefined(state.views) ? state.views : { '': state }, function (view, name) {\n        if (name.indexOf('@') < 0) name += '@' + state.parent.name;\n        views[name] = view;\n      });\n      return views;\n    },\n    path: function(state) {\n      return state.parent ? state.parent.path.concat(state) : []; // exclude root from path\n    },\n    includes: function(state) {\n      var includes = state.parent ? extend({}, state.parent.includes) : {};\n      includes[state.name] = true;\n      return includes;\n    },\n\n    $delegates: {}\n  };\n\n  function isRelative(stateName) {\n    return stateName.indexOf(\".\") === 0 || stateName.indexOf(\"^\") === 0;\n  }\n\n  function findState(stateOrName, base) {\n    if (!stateOrName) return undefined;\n\n    var isStr = isString(stateOrName),\n        name  = isStr ? stateOrName : stateOrName.name,\n        path  = isRelative(name);\n\n    if (path) {\n      if (!base) throw new Error(\"No reference point given for path '\"  + name + \"'\");\n      base = findState(base);\n      \n      var rel = name.split(\".\"), i = 0, pathLength = rel.length, current = base;\n\n      for (; i < pathLength; i++) {\n        if (rel[i] === \"\" && i === 0) {\n          current = base;\n          continue;\n        }\n        if (rel[i] === \"^\") {\n          if (!current.parent) throw new Error(\"Path '\" + name + \"' not valid for state '\" + base.name + \"'\");\n          current = current.parent;\n          continue;\n        }\n        break;\n      }\n      rel = rel.slice(i).join(\".\");\n      name = current.name + (current.name && rel ? \".\" : \"\") + rel;\n    }\n    var state = states[name];\n\n    if (state && (isStr || (!isStr && (state === stateOrName || state.self === stateOrName)))) {\n      return state;\n    }\n    return undefined;\n  }\n\n  function queueState(parentName, state) {\n    if (!queue[parentName]) {\n      queue[parentName] = [];\n    }\n    queue[parentName].push(state);\n  }\n\n  function flushQueuedChildren(parentName) {\n    var queued = queue[parentName] || [];\n    while(queued.length) {\n      registerState(queued.shift());\n    }\n  }\n\n  function registerState(state) {\n    state = inherit(state, {\n      self: state,\n      resolve: state.resolve || {},\n      toString: function() { return this.name; }\n    });\n\n    var name = state.name;\n    if (!isString(name) || name.indexOf('@') >= 0) throw new Error(\"State must have a valid name\");\n    if (states.hasOwnProperty(name)) throw new Error(\"State '\" + name + \"'' is already defined\");\n    var parentName = (name.indexOf('.') !== -1) ? name.substring(0, name.lastIndexOf('.'))\n        : (isString(state.parent)) ? state.parent\n        : (isObject(state.parent) && isString(state.parent.name)) ? state.parent.name\n        : '';\n    if (parentName && !states[parentName]) {\n      return queueState(parentName, state.self);\n    }\n\n    for (var key in stateBuilder) {\n      if (isFunction(stateBuilder[key])) state[key] = stateBuilder[key](state, stateBuilder.$delegates[key]);\n    }\n    states[name] = state;\n    if (!state[abstractKey] && state.url) {\n      $urlRouterProvider.when(state.url, ['$match', '$stateParams', function ($match, $stateParams) {\n        if ($state.$current.navigable != state || !equalForKeys($match, $stateParams)) {\n          $state.transitionTo(state, $match, { inherit: true, location: false });\n        }\n      }]);\n    }\n    flushQueuedChildren(name);\n\n    return state;\n  }\n  function isGlob (text) {\n    return text.indexOf('*') > -1;\n  }\n  function doesStateMatchGlob (glob) {\n    var globSegments = glob.split('.'),\n        segments = $state.$current.name.split('.');\n    for (var i = 0, l = globSegments.length; i < l; i++) {\n      if (globSegments[i] === '*') {\n        segments[i] = '*';\n      }\n    }\n    if (globSegments[0] === '**') {\n       segments = segments.slice(indexOf(segments, globSegments[1]));\n       segments.unshift('**');\n    }\n    if (globSegments[globSegments.length - 1] === '**') {\n       segments.splice(indexOf(segments, globSegments[globSegments.length - 2]) + 1, Number.MAX_VALUE);\n       segments.push('**');\n    }\n\n    if (globSegments.length != segments.length) {\n      return false;\n    }\n\n    return segments.join('') === globSegments.join('');\n  }\n  root = registerState({\n    name: '',\n    url: '^',\n    views: null,\n    'abstract': true\n  });\n  root.navigable = null;\n\n\n    this.decorator = decorator;\n  function decorator(name, func) {\n    /*jshint validthis: true */\n    if (isString(name) && !isDefined(func)) {\n      return stateBuilder[name];\n    }\n    if (!isFunction(func) || !isString(name)) {\n      return this;\n    }\n    if (stateBuilder[name] && !stateBuilder.$delegates[name]) {\n      stateBuilder.$delegates[name] = stateBuilder[name];\n    }\n    stateBuilder[name] = func;\n    return this;\n  }\n\n    this.state = state;\n  function state(name, definition) {\n    /*jshint validthis: true */\n    if (isObject(name)) definition = name;\n    else definition.name = name;\n    registerState(definition);\n    return this;\n  }\n\n    this.$get = $get;\n  $get.$inject = ['$rootScope', '$q', '$view', '$injector', '$resolve', '$stateParams', '$urlRouter', '$location', '$urlMatcherFactory'];\n  function $get(   $rootScope,   $q,   $view,   $injector,   $resolve,   $stateParams,   $urlRouter,   $location,   $urlMatcherFactory) {\n\n    var TransitionSuperseded = $q.reject(new Error('transition superseded'));\n    var TransitionPrevented = $q.reject(new Error('transition prevented'));\n    var TransitionAborted = $q.reject(new Error('transition aborted'));\n    var TransitionFailed = $q.reject(new Error('transition failed'));\n    function handleRedirect(redirect, state, params, options) {\n            var evt = $rootScope.$broadcast('$stateNotFound', redirect, state, params);\n\n      if (evt.defaultPrevented) {\n        $urlRouter.update();\n        return TransitionAborted;\n      }\n\n      if (!evt.retry) {\n        return null;\n      }\n      if (options.$retry) {\n        $urlRouter.update();\n        return TransitionFailed;\n      }\n      var retryTransition = $state.transition = $q.when(evt.retry);\n\n      retryTransition.then(function() {\n        if (retryTransition !== $state.transition) return TransitionSuperseded;\n        redirect.options.$retry = true;\n        return $state.transitionTo(redirect.to, redirect.toParams, redirect.options);\n      }, function() {\n        return TransitionAborted;\n      });\n      $urlRouter.update();\n\n      return retryTransition;\n    }\n\n    root.locals = { resolve: null, globals: { $stateParams: {} } };\n\n    $state = {\n      params: {},\n      current: root.self,\n      $current: root,\n      transition: null\n    };\n\n        $state.reload = function reload(state) {\n      return $state.transitionTo($state.current, $stateParams, { reload: state || true, inherit: false, notify: true});\n    };\n\n        $state.go = function go(to, params, options) {\n      return $state.transitionTo(to, params, extend({ inherit: true, relative: $state.$current }, options));\n    };\n\n        $state.transitionTo = function transitionTo(to, toParams, options) {\n      toParams = toParams || {};\n      options = extend({\n        location: true, inherit: false, relative: null, notify: true, reload: false, $retry: false\n      }, options || {});\n\n      var from = $state.$current, fromParams = $state.params, fromPath = from.path;\n      var evt, toState = findState(to, options.relative);\n      var hash = toParams['#'];\n\n      if (!isDefined(toState)) {\n        var redirect = { to: to, toParams: toParams, options: options };\n        var redirectResult = handleRedirect(redirect, from.self, fromParams, options);\n\n        if (redirectResult) {\n          return redirectResult;\n        }\n        to = redirect.to;\n        toParams = redirect.toParams;\n        options = redirect.options;\n        toState = findState(to, options.relative);\n\n        if (!isDefined(toState)) {\n          if (!options.relative) throw new Error(\"No such state '\" + to + \"'\");\n          throw new Error(\"Could not resolve '\" + to + \"' from state '\" + options.relative + \"'\");\n        }\n      }\n      if (toState[abstractKey]) throw new Error(\"Cannot transition to abstract state '\" + to + \"'\");\n      if (options.inherit) toParams = inheritParams($stateParams, toParams || {}, $state.$current, toState);\n      if (!toState.params.$$validates(toParams)) return TransitionFailed;\n\n      toParams = toState.params.$$values(toParams);\n      to = toState;\n\n      var toPath = to.path;\n      var keep = 0, state = toPath[keep], locals = root.locals, toLocals = [];\n      var skipTriggerReloadCheck = false;\n\n      if (!options.reload) {\n        while (state && state === fromPath[keep] && state.ownParams.$$equals(toParams, fromParams)) {\n          locals = toLocals[keep] = state.locals;\n          keep++;\n          state = toPath[keep];\n        }\n      } else if (isString(options.reload) || isObject(options.reload)) {\n        if (isObject(options.reload) && !options.reload.name) {\n          throw new Error('Invalid reload state object');\n        }\n        \n        var reloadState = options.reload === true ? fromPath[0] : findState(options.reload);\n        if (options.reload && !reloadState) {\n          throw new Error(\"No such reload state '\" + (isString(options.reload) ? options.reload : options.reload.name) + \"'\");\n        }\n\n        skipTriggerReloadCheck = true;\n \n        while (state && state === fromPath[keep] && state !== reloadState) {\n          locals = toLocals[keep] = state.locals;\n          keep++;\n          state = toPath[keep];\n        }\n      }\n      if (!skipTriggerReloadCheck && shouldTriggerReload(to, from, locals, options)) {\n        if (to.self.reloadOnSearch !== false) $urlRouter.update();\n        $state.transition = null;\n        return $q.when($state.current);\n      }\n      toParams = filterByKeys(to.params.$$keys(), toParams || {});\n      if (options.notify) {\n                if ($rootScope.$broadcast('$stateChangeStart', to.self, toParams, from.self, fromParams).defaultPrevented) {\n          $rootScope.$broadcast('$stateChangeCancel', to.self, toParams, from.self, fromParams);\n          $urlRouter.update();\n          return TransitionPrevented;\n        }\n      }\n      var resolved = $q.when(locals);\n\n      for (var l = keep; l < toPath.length; l++, state = toPath[l]) {\n        locals = toLocals[l] = inherit(locals);\n        resolved = resolveState(state, toParams, state === to, resolved, locals, options);\n      }\n      var transition = $state.transition = resolved.then(function () {\n        var l, entering, exiting;\n\n        if ($state.transition !== transition) return TransitionSuperseded;\n        for (l = fromPath.length - 1; l >= keep; l--) {\n          exiting = fromPath[l];\n          if (exiting.self.onExit) {\n            $injector.invoke(exiting.self.onExit, exiting.self, exiting.locals.globals);\n          }\n          exiting.locals = null;\n        }\n        for (l = keep; l < toPath.length; l++) {\n          entering = toPath[l];\n          entering.locals = toLocals[l];\n          if (entering.self.onEnter) {\n            $injector.invoke(entering.self.onEnter, entering.self, entering.locals.globals);\n          }\n        }\n        if (hash) toParams['#'] = hash;\n        if ($state.transition !== transition) return TransitionSuperseded;\n        $state.$current = to;\n        $state.current = to.self;\n        $state.params = toParams;\n        copy($state.params, $stateParams);\n        $state.transition = null;\n\n        if (options.location && to.navigable) {\n          $urlRouter.push(to.navigable.url, to.navigable.locals.globals.$stateParams, {\n            $$avoidResync: true, replace: options.location === 'replace'\n          });\n        }\n\n        if (options.notify) {\n                  $rootScope.$broadcast('$stateChangeSuccess', to.self, toParams, from.self, fromParams);\n        }\n        $urlRouter.update(true);\n\n        return $state.current;\n      }, function (error) {\n        if ($state.transition !== transition) return TransitionSuperseded;\n\n        $state.transition = null;\n                evt = $rootScope.$broadcast('$stateChangeError', to.self, toParams, from.self, fromParams, error);\n\n        if (!evt.defaultPrevented) {\n            $urlRouter.update();\n        }\n\n        return $q.reject(error);\n      });\n\n      return transition;\n    };\n\n        $state.is = function is(stateOrName, params, options) {\n      options = extend({ relative: $state.$current }, options || {});\n      var state = findState(stateOrName, options.relative);\n\n      if (!isDefined(state)) { return undefined; }\n      if ($state.$current !== state) { return false; }\n      return params ? equalForKeys(state.params.$$values(params), $stateParams) : true;\n    };\n\n        $state.includes = function includes(stateOrName, params, options) {\n      options = extend({ relative: $state.$current }, options || {});\n      if (isString(stateOrName) && isGlob(stateOrName)) {\n        if (!doesStateMatchGlob(stateOrName)) {\n          return false;\n        }\n        stateOrName = $state.$current.name;\n      }\n\n      var state = findState(stateOrName, options.relative);\n      if (!isDefined(state)) { return undefined; }\n      if (!isDefined($state.$current.includes[state.name])) { return false; }\n      return params ? equalForKeys(state.params.$$values(params), $stateParams, objectKeys(params)) : true;\n    };\n\n\n        $state.href = function href(stateOrName, params, options) {\n      options = extend({\n        lossy:    true,\n        inherit:  true,\n        absolute: false,\n        relative: $state.$current\n      }, options || {});\n\n      var state = findState(stateOrName, options.relative);\n\n      if (!isDefined(state)) return null;\n      if (options.inherit) params = inheritParams($stateParams, params || {}, $state.$current, state);\n      \n      var nav = (state && options.lossy) ? state.navigable : state;\n\n      if (!nav || nav.url === undefined || nav.url === null) {\n        return null;\n      }\n      return $urlRouter.href(nav.url, filterByKeys(state.params.$$keys().concat('#'), params || {}), {\n        absolute: options.absolute\n      });\n    };\n\n        $state.get = function (stateOrName, context) {\n      if (arguments.length === 0) return map(objectKeys(states), function(name) { return states[name].self; });\n      var state = findState(stateOrName, context || $state.$current);\n      return (state && state.self) ? state.self : null;\n    };\n\n    function resolveState(state, params, paramsAreFiltered, inherited, dst, options) {\n      var $stateParams = (paramsAreFiltered) ? params : filterByKeys(state.params.$$keys(), params);\n      var locals = { $stateParams: $stateParams };\n      dst.resolve = $resolve.resolve(state.resolve, locals, dst.resolve, state);\n      var promises = [dst.resolve.then(function (globals) {\n        dst.globals = globals;\n      })];\n      if (inherited) promises.push(inherited);\n      forEach(state.views, function (view, name) {\n        var injectables = (view.resolve && view.resolve !== state.resolve ? view.resolve : {});\n        injectables.$template = [ function () {\n          return $view.load(name, { view: view, locals: locals, params: $stateParams, notify: options.notify }) || '';\n        }];\n\n        promises.push($resolve.resolve(injectables, locals, dst.resolve, state).then(function (result) {\n          if (isFunction(view.controllerProvider) || isArray(view.controllerProvider)) {\n            var injectLocals = angular.extend({}, injectables, locals, result);\n            result.$$controller = $injector.invoke(view.controllerProvider, null, injectLocals);\n          } else {\n            result.$$controller = view.controller;\n          }\n          result.$$state = state;\n          result.$$controllerAs = view.controllerAs;\n          dst[name] = result;\n        }));\n      });\n      return $q.all(promises).then(function (values) {\n        return dst;\n      });\n    }\n\n    return $state;\n  }\n\n  function shouldTriggerReload(to, from, locals, options) {\n    if (to === from && ((locals === from.locals && !options.reload) || (to.self.reloadOnSearch === false))) {\n      return true;\n    }\n  }\n}\n\nangular.module('ui.router.state')\n  .value('$stateParams', {})\n  .provider('$state', $StateProvider);\n\n\n$ViewProvider.$inject = [];\nfunction $ViewProvider() {\n\n  this.$get = $get;\n    $get.$inject = ['$rootScope', '$templateFactory'];\n  function $get(   $rootScope,   $templateFactory) {\n    return {\n            load: function load(name, options) {\n        var result, defaults = {\n          template: null, controller: null, view: null, locals: null, notify: true, async: true, params: {}\n        };\n        options = extend(defaults, options);\n\n        if (options.view) {\n          result = $templateFactory.fromConfig(options.view, options.params, options.locals);\n        }\n        if (result && options.notify) {\n                  $rootScope.$broadcast('$viewContentLoading', options);\n        }\n        return result;\n      }\n    };\n  }\n}\n\nangular.module('ui.router.state').provider('$view', $ViewProvider);\n\nfunction $ViewScrollProvider() {\n\n  var useAnchorScroll = false;\n\n    this.useAnchorScroll = function () {\n    useAnchorScroll = true;\n  };\n\n    this.$get = ['$anchorScroll', '$timeout', function ($anchorScroll, $timeout) {\n    if (useAnchorScroll) {\n      return $anchorScroll;\n    }\n\n    return function ($element) {\n      return $timeout(function () {\n        $element[0].scrollIntoView();\n      }, 0, false);\n    };\n  }];\n}\n\nangular.module('ui.router.state').provider('$uiViewScroll', $ViewScrollProvider);\n\n$ViewDirective.$inject = ['$state', '$injector', '$uiViewScroll', '$interpolate'];\nfunction $ViewDirective(   $state,   $injector,   $uiViewScroll,   $interpolate) {\n\n  function getService() {\n    return ($injector.has) ? function(service) {\n      return $injector.has(service) ? $injector.get(service) : null;\n    } : function(service) {\n      try {\n        return $injector.get(service);\n      } catch (e) {\n        return null;\n      }\n    };\n  }\n\n  var service = getService(),\n      $animator = service('$animator'),\n      $animate = service('$animate');\n  function getRenderer(attrs, scope) {\n    var statics = function() {\n      return {\n        enter: function (element, target, cb) { target.after(element); cb(); },\n        leave: function (element, cb) { element.remove(); cb(); }\n      };\n    };\n\n    if ($animate) {\n      return {\n        enter: function(element, target, cb) {\n          var promise = $animate.enter(element, null, target, cb);\n          if (promise && promise.then) promise.then(cb);\n        },\n        leave: function(element, cb) {\n          var promise = $animate.leave(element, cb);\n          if (promise && promise.then) promise.then(cb);\n        }\n      };\n    }\n\n    if ($animator) {\n      var animate = $animator && $animator(scope, attrs);\n\n      return {\n        enter: function(element, target, cb) {animate.enter(element, null, target); cb(); },\n        leave: function(element, cb) { animate.leave(element); cb(); }\n      };\n    }\n\n    return statics();\n  }\n\n  var directive = {\n    restrict: 'ECA',\n    terminal: true,\n    priority: 400,\n    transclude: 'element',\n    compile: function (tElement, tAttrs, $transclude) {\n      return function (scope, $element, attrs) {\n        var previousEl, currentEl, currentScope, latestLocals,\n            onloadExp     = attrs.onload || '',\n            autoScrollExp = attrs.autoscroll,\n            renderer      = getRenderer(attrs, scope);\n\n        scope.$on('$stateChangeSuccess', function() {\n          updateView(false);\n        });\n        scope.$on('$viewContentLoading', function() {\n          updateView(false);\n        });\n\n        updateView(true);\n\n        function cleanupLastView() {\n          if (previousEl) {\n            previousEl.remove();\n            previousEl = null;\n          }\n\n          if (currentScope) {\n            currentScope.$destroy();\n            currentScope = null;\n          }\n\n          if (currentEl) {\n            renderer.leave(currentEl, function() {\n              previousEl = null;\n            });\n\n            previousEl = currentEl;\n            currentEl = null;\n          }\n        }\n\n        function updateView(firstTime) {\n          var newScope,\n              name            = getUiViewName(scope, attrs, $element, $interpolate),\n              previousLocals  = name && $state.$current && $state.$current.locals[name];\n\n          if (!firstTime && previousLocals === latestLocals) return; // nothing to do\n          newScope = scope.$new();\n          latestLocals = $state.$current.locals[name];\n\n          var clone = $transclude(newScope, function(clone) {\n            renderer.enter(clone, $element, function onUiViewEnter() {\n              if(currentScope) {\n                currentScope.$emit('$viewContentAnimationEnded');\n              }\n\n              if (angular.isDefined(autoScrollExp) && !autoScrollExp || scope.$eval(autoScrollExp)) {\n                $uiViewScroll(clone);\n              }\n            });\n            cleanupLastView();\n          });\n\n          currentEl = clone;\n          currentScope = newScope;\n                    currentScope.$emit('$viewContentLoaded');\n          currentScope.$eval(onloadExp);\n        }\n      };\n    }\n  };\n\n  return directive;\n}\n\n$ViewDirectiveFill.$inject = ['$compile', '$controller', '$state', '$interpolate'];\nfunction $ViewDirectiveFill (  $compile,   $controller,   $state,   $interpolate) {\n  return {\n    restrict: 'ECA',\n    priority: -400,\n    compile: function (tElement) {\n      var initial = tElement.html();\n      return function (scope, $element, attrs) {\n        var current = $state.$current,\n            name = getUiViewName(scope, attrs, $element, $interpolate),\n            locals  = current && current.locals[name];\n\n        if (! locals) {\n          return;\n        }\n\n        $element.data('$uiView', { name: name, state: locals.$$state });\n        $element.html(locals.$template ? locals.$template : initial);\n\n        var link = $compile($element.contents());\n\n        if (locals.$$controller) {\n          locals.$scope = scope;\n          locals.$element = $element;\n          var controller = $controller(locals.$$controller, locals);\n          if (locals.$$controllerAs) {\n            scope[locals.$$controllerAs] = controller;\n          }\n          $element.data('$ngControllerController', controller);\n          $element.children().data('$ngControllerController', controller);\n        }\n\n        link(scope);\n      };\n    }\n  };\n}\n\nfunction getUiViewName(scope, attrs, element, $interpolate) {\n  var name = $interpolate(attrs.uiView || attrs.name || '')(scope);\n  var inherited = element.inheritedData('$uiView');\n  return name.indexOf('@') >= 0 ?  name :  (name + '@' + (inherited ? inherited.state.name : ''));\n}\n\nangular.module('ui.router.state').directive('uiView', $ViewDirective);\nangular.module('ui.router.state').directive('uiView', $ViewDirectiveFill);\n\nfunction parseStateRef(ref, current) {\n  var preparsed = ref.match(/^\\s*({[^}]*})\\s*$/), parsed;\n  if (preparsed) ref = current + '(' + preparsed[1] + ')';\n  parsed = ref.replace(/\\n/g, \" \").match(/^([^(]+?)\\s*(\\((.*)\\))?$/);\n  if (!parsed || parsed.length !== 4) throw new Error(\"Invalid state ref '\" + ref + \"'\");\n  return { state: parsed[1], paramExpr: parsed[3] || null };\n}\n\nfunction stateContext(el) {\n  var stateData = el.parent().inheritedData('$uiView');\n\n  if (stateData && stateData.state && stateData.state.name) {\n    return stateData.state;\n  }\n}\n\n$StateRefDirective.$inject = ['$state', '$timeout'];\nfunction $StateRefDirective($state, $timeout) {\n  var allowedOptions = ['location', 'inherit', 'reload', 'absolute'];\n\n  return {\n    restrict: 'A',\n    require: ['?^uiSrefActive', '?^uiSrefActiveEq'],\n    link: function(scope, element, attrs, uiSrefActive) {\n      var ref = parseStateRef(attrs.uiSref, $state.current.name);\n      var params = null, url = null, base = stateContext(element) || $state.$current;\n      var hrefKind = Object.prototype.toString.call(element.prop('href')) === '[object SVGAnimatedString]' ?\n                 'xlink:href' : 'href';\n      var newHref = null, isAnchor = element.prop(\"tagName\").toUpperCase() === \"A\";\n      var isForm = element[0].nodeName === \"FORM\";\n      var attr = isForm ? \"action\" : hrefKind, nav = true;\n\n      var options = { relative: base, inherit: true };\n      var optionsOverride = scope.$eval(attrs.uiSrefOpts) || {};\n\n      angular.forEach(allowedOptions, function(option) {\n        if (option in optionsOverride) {\n          options[option] = optionsOverride[option];\n        }\n      });\n\n      var update = function(newVal) {\n        if (newVal) params = angular.copy(newVal);\n        if (!nav) return;\n\n        newHref = $state.href(ref.state, params, options);\n\n        var activeDirective = uiSrefActive[1] || uiSrefActive[0];\n        if (activeDirective) {\n          activeDirective.$$addStateInfo(ref.state, params);\n        }\n        if (newHref === null) {\n          nav = false;\n          return false;\n        }\n        attrs.$set(attr, newHref);\n      };\n\n      if (ref.paramExpr) {\n        scope.$watch(ref.paramExpr, function(newVal, oldVal) {\n          if (newVal !== params) update(newVal);\n        }, true);\n        params = angular.copy(scope.$eval(ref.paramExpr));\n      }\n      update();\n\n      if (isForm) return;\n\n      element.bind(\"click\", function(e) {\n        var button = e.which || e.button;\n        if ( !(button > 1 || e.ctrlKey || e.metaKey || e.shiftKey || element.attr('target')) ) {\n          var transition = $timeout(function() {\n            $state.go(ref.state, params, options);\n          });\n          e.preventDefault();\n          var ignorePreventDefaultCount = isAnchor && !newHref ? 1: 0;\n          e.preventDefault = function() {\n            if (ignorePreventDefaultCount-- <= 0)\n              $timeout.cancel(transition);\n          };\n        }\n      });\n    }\n  };\n}\n\n\n$StateRefActiveDirective.$inject = ['$state', '$stateParams', '$interpolate'];\nfunction $StateRefActiveDirective($state, $stateParams, $interpolate) {\n  return  {\n    restrict: \"A\",\n    controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {\n      var states = [], activeClass;\n      activeClass = $interpolate($attrs.uiSrefActiveEq || $attrs.uiSrefActive || '', false)($scope);\n      this.$$addStateInfo = function (newState, newParams) {\n        var state = $state.get(newState, stateContext($element));\n\n        states.push({\n          state: state || { name: newState },\n          params: newParams\n        });\n\n        update();\n      };\n\n      $scope.$on('$stateChangeSuccess', update);\n      function update() {\n        if (anyMatch()) {\n          $element.addClass(activeClass);\n        } else {\n          $element.removeClass(activeClass);\n        }\n      }\n\n      function anyMatch() {\n        for (var i = 0; i < states.length; i++) {\n          if (isMatch(states[i].state, states[i].params)) {\n            return true;\n          }\n        }\n        return false;\n      }\n\n      function isMatch(state, params) {\n        if (typeof $attrs.uiSrefActiveEq !== 'undefined') {\n          return $state.is(state.name, params);\n        } else {\n          return $state.includes(state.name, params);\n        }\n      }\n    }]\n  };\n}\n\nangular.module('ui.router.state')\n  .directive('uiSref', $StateRefDirective)\n  .directive('uiSrefActive', $StateRefActiveDirective)\n  .directive('uiSrefActiveEq', $StateRefActiveDirective);\n\n$IsStateFilter.$inject = ['$state'];\nfunction $IsStateFilter($state) {\n  var isFilter = function (state) {\n    return $state.is(state);\n  };\n  isFilter.$stateful = true;\n  return isFilter;\n}\n\n$IncludedByStateFilter.$inject = ['$state'];\nfunction $IncludedByStateFilter($state) {\n  var includesFilter = function (state) {\n    return $state.includes(state);\n  };\n  includesFilter.$stateful = true;\n  return  includesFilter;\n}\n\nangular.module('ui.router.state')\n  .filter('isState', $IsStateFilter)\n  .filter('includedByState', $IncludedByStateFilter);\n})(window, window.angular);"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-ui-router/src/common.js",
    "content": "/*jshint globalstrict:true*/\n/*global angular:false*/\n'use strict';\n\nvar isDefined = angular.isDefined,\n    isFunction = angular.isFunction,\n    isString = angular.isString,\n    isObject = angular.isObject,\n    isArray = angular.isArray,\n    forEach = angular.forEach,\n    extend = angular.extend,\n    copy = angular.copy;\n\nfunction inherit(parent, extra) {\n  return extend(new (extend(function() {}, { prototype: parent }))(), extra);\n}\n\nfunction merge(dst) {\n  forEach(arguments, function(obj) {\n    if (obj !== dst) {\n      forEach(obj, function(value, key) {\n        if (!dst.hasOwnProperty(key)) dst[key] = value;\n      });\n    }\n  });\n  return dst;\n}\n\nfunction ancestors(first, second) {\n  var path = [];\n\n  for (var n in first.path) {\n    if (first.path[n] !== second.path[n]) break;\n    path.push(first.path[n]);\n  }\n  return path;\n}\n\nfunction objectKeys(object) {\n  if (Object.keys) {\n    return Object.keys(object);\n  }\n  var result = [];\n\n  forEach(object, function(val, key) {\n    result.push(key);\n  });\n  return result;\n}\n\nfunction indexOf(array, value) {\n  if (Array.prototype.indexOf) {\n    return array.indexOf(value, Number(arguments[2]) || 0);\n  }\n  var len = array.length >>> 0, from = Number(arguments[2]) || 0;\n  from = (from < 0) ? Math.ceil(from) : Math.floor(from);\n\n  if (from < 0) from += len;\n\n  for (; from < len; from++) {\n    if (from in array && array[from] === value) return from;\n  }\n  return -1;\n}\n\nfunction inheritParams(currentParams, newParams, $current, $to) {\n  var parents = ancestors($current, $to), parentParams, inherited = {}, inheritList = [];\n\n  for (var i in parents) {\n    if (!parents[i].params) continue;\n    parentParams = objectKeys(parents[i].params);\n    if (!parentParams.length) continue;\n\n    for (var j in parentParams) {\n      if (indexOf(inheritList, parentParams[j]) >= 0) continue;\n      inheritList.push(parentParams[j]);\n      inherited[parentParams[j]] = currentParams[parentParams[j]];\n    }\n  }\n  return extend({}, inherited, newParams);\n}\n\nfunction equalForKeys(a, b, keys) {\n  if (!keys) {\n    keys = [];\n    for (var n in a) keys.push(n); // Used instead of Object.keys() for IE8 compatibility\n  }\n\n  for (var i=0; i<keys.length; i++) {\n    var k = keys[i];\n    if (a[k] != b[k]) return false; // Not '===', values aren't necessarily normalized\n  }\n  return true;\n}\n\nfunction filterByKeys(keys, values) {\n  var filtered = {};\n\n  forEach(keys, function (name) {\n    filtered[name] = values[name];\n  });\n  return filtered;\n}\nfunction indexBy(array, propName) {\n  var result = {};\n  forEach(array, function(item) {\n    result[item[propName]] = item;\n  });\n  return result;\n}\nfunction pick(obj) {\n  var copy = {};\n  var keys = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));\n  forEach(keys, function(key) {\n    if (key in obj) copy[key] = obj[key];\n  });\n  return copy;\n}\nfunction omit(obj) {\n  var copy = {};\n  var keys = Array.prototype.concat.apply(Array.prototype, Array.prototype.slice.call(arguments, 1));\n  for (var key in obj) {\n    if (indexOf(keys, key) == -1) copy[key] = obj[key];\n  }\n  return copy;\n}\n\nfunction pluck(collection, key) {\n  var result = isArray(collection) ? [] : {};\n\n  forEach(collection, function(val, i) {\n    result[i] = isFunction(key) ? key(val) : val[key];\n  });\n  return result;\n}\n\nfunction filter(collection, callback) {\n  var array = isArray(collection);\n  var result = array ? [] : {};\n  forEach(collection, function(val, i) {\n    if (callback(val, i)) {\n      result[array ? result.length : i] = val;\n    }\n  });\n  return result;\n}\n\nfunction map(collection, callback) {\n  var result = isArray(collection) ? [] : {};\n\n  forEach(collection, function(val, i) {\n    result[i] = callback(val, i);\n  });\n  return result;\n}\n\nangular.module('ui.router.util', ['ng']);\n\nangular.module('ui.router.router', ['ui.router.util']);\n\nangular.module('ui.router.state', ['ui.router.router', 'ui.router.util']);\n\nangular.module('ui.router', ['ui.router.state']);\n\nangular.module('ui.router.compat', ['ui.router']);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-ui-router/src/resolve.js",
    "content": "$Resolve.$inject = ['$q', '$injector'];\nfunction $Resolve(  $q,    $injector) {\n  \n  var VISIT_IN_PROGRESS = 1,\n      VISIT_DONE = 2,\n      NOTHING = {},\n      NO_DEPENDENCIES = [],\n      NO_LOCALS = NOTHING,\n      NO_PARENT = extend($q.when(NOTHING), { $$promises: NOTHING, $$values: NOTHING });\n  \n\n    this.study = function (invocables) {\n    if (!isObject(invocables)) throw new Error(\"'invocables' must be an object\");\n    var invocableKeys = objectKeys(invocables || {});\n    var plan = [], cycle = [], visited = {};\n    function visit(value, key) {\n      if (visited[key] === VISIT_DONE) return;\n      \n      cycle.push(key);\n      if (visited[key] === VISIT_IN_PROGRESS) {\n        cycle.splice(0, indexOf(cycle, key));\n        throw new Error(\"Cyclic dependency: \" + cycle.join(\" -> \"));\n      }\n      visited[key] = VISIT_IN_PROGRESS;\n      \n      if (isString(value)) {\n        plan.push(key, [ function() { return $injector.get(value); }], NO_DEPENDENCIES);\n      } else {\n        var params = $injector.annotate(value);\n        forEach(params, function (param) {\n          if (param !== key && invocables.hasOwnProperty(param)) visit(invocables[param], param);\n        });\n        plan.push(key, value, params);\n      }\n      \n      cycle.pop();\n      visited[key] = VISIT_DONE;\n    }\n    forEach(invocables, visit);\n    invocables = cycle = visited = null; // plan is all that's required\n    \n    function isResolve(value) {\n      return isObject(value) && value.then && value.$$promises;\n    }\n    \n    return function (locals, parent, self) {\n      if (isResolve(locals) && self === undefined) {\n        self = parent; parent = locals; locals = null;\n      }\n      if (!locals) locals = NO_LOCALS;\n      else if (!isObject(locals)) {\n        throw new Error(\"'locals' must be an object\");\n      }       \n      if (!parent) parent = NO_PARENT;\n      else if (!isResolve(parent)) {\n        throw new Error(\"'parent' must be a promise returned by $resolve.resolve()\");\n      }\n      var resolution = $q.defer(),\n          result = resolution.promise,\n          promises = result.$$promises = {},\n          values = extend({}, locals),\n          wait = 1 + plan.length/3,\n          merged = false;\n          \n      function done() {\n        if (!--wait) {\n          if (!merged) merge(values, parent.$$values); \n          result.$$values = values;\n          result.$$promises = result.$$promises || true; // keep for isResolve()\n          delete result.$$inheritedValues;\n          resolution.resolve(values);\n        }\n      }\n      \n      function fail(reason) {\n        result.$$failure = reason;\n        resolution.reject(reason);\n      }\n      if (isDefined(parent.$$failure)) {\n        fail(parent.$$failure);\n        return result;\n      }\n      \n      if (parent.$$inheritedValues) {\n        merge(values, omit(parent.$$inheritedValues, invocableKeys));\n      }\n      extend(promises, parent.$$promises);\n      if (parent.$$values) {\n        merged = merge(values, omit(parent.$$values, invocableKeys));\n        result.$$inheritedValues = omit(parent.$$values, invocableKeys);\n        done();\n      } else {\n        if (parent.$$inheritedValues) {\n          result.$$inheritedValues = omit(parent.$$inheritedValues, invocableKeys);\n        }        \n        parent.then(done, fail);\n      }\n      for (var i=0, ii=plan.length; i<ii; i+=3) {\n        if (locals.hasOwnProperty(plan[i])) done();\n        else invoke(plan[i], plan[i+1], plan[i+2]);\n      }\n      \n      function invoke(key, invocable, params) {\n        var invocation = $q.defer(), waitParams = 0;\n        function onfailure(reason) {\n          invocation.reject(reason);\n          fail(reason);\n        }\n        forEach(params, function (dep) {\n          if (promises.hasOwnProperty(dep) && !locals.hasOwnProperty(dep)) {\n            waitParams++;\n            promises[dep].then(function (result) {\n              values[dep] = result;\n              if (!(--waitParams)) proceed();\n            }, onfailure);\n          }\n        });\n        if (!waitParams) proceed();\n        function proceed() {\n          if (isDefined(result.$$failure)) return;\n          try {\n            invocation.resolve($injector.invoke(invocable, self, values));\n            invocation.promise.then(function (result) {\n              values[key] = result;\n              done();\n            }, onfailure);\n          } catch (e) {\n            onfailure(e);\n          }\n        }\n        promises[key] = invocation.promise;\n      }\n      \n      return result;\n    };\n  };\n  \n    this.resolve = function (invocables, locals, parent, self) {\n    return this.study(invocables)(locals, parent, self);\n  };\n}\n\nangular.module('ui.router.util').service('$resolve', $Resolve);\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-ui-router/src/state.js",
    "content": "$StateProvider.$inject = ['$urlRouterProvider', '$urlMatcherFactoryProvider'];\nfunction $StateProvider(   $urlRouterProvider,   $urlMatcherFactory) {\n\n  var root, states = {}, $state, queue = {}, abstractKey = 'abstract';\n  var stateBuilder = {\n    parent: function(state) {\n      if (isDefined(state.parent) && state.parent) return findState(state.parent);\n      var compositeName = /^(.+)\\.[^.]+$/.exec(state.name);\n      return compositeName ? findState(compositeName[1]) : root;\n    },\n    data: function(state) {\n      if (state.parent && state.parent.data) {\n        state.data = state.self.data = extend({}, state.parent.data, state.data);\n      }\n      return state.data;\n    },\n    url: function(state) {\n      var url = state.url, config = { params: state.params || {} };\n\n      if (isString(url)) {\n        if (url.charAt(0) == '^') return $urlMatcherFactory.compile(url.substring(1), config);\n        return (state.parent.navigable || root).url.concat(url, config);\n      }\n\n      if (!url || $urlMatcherFactory.isMatcher(url)) return url;\n      throw new Error(\"Invalid url '\" + url + \"' in state '\" + state + \"'\");\n    },\n    navigable: function(state) {\n      return state.url ? state : (state.parent ? state.parent.navigable : null);\n    },\n    ownParams: function(state) {\n      var params = state.url && state.url.params || new $$UMFP.ParamSet();\n      forEach(state.params || {}, function(config, id) {\n        if (!params[id]) params[id] = new $$UMFP.Param(id, null, config, \"config\");\n      });\n      return params;\n    },\n    params: function(state) {\n      return state.parent && state.parent.params ? extend(state.parent.params.$$new(), state.ownParams) : new $$UMFP.ParamSet();\n    },\n    views: function(state) {\n      var views = {};\n\n      forEach(isDefined(state.views) ? state.views : { '': state }, function (view, name) {\n        if (name.indexOf('@') < 0) name += '@' + state.parent.name;\n        views[name] = view;\n      });\n      return views;\n    },\n    path: function(state) {\n      return state.parent ? state.parent.path.concat(state) : []; // exclude root from path\n    },\n    includes: function(state) {\n      var includes = state.parent ? extend({}, state.parent.includes) : {};\n      includes[state.name] = true;\n      return includes;\n    },\n\n    $delegates: {}\n  };\n\n  function isRelative(stateName) {\n    return stateName.indexOf(\".\") === 0 || stateName.indexOf(\"^\") === 0;\n  }\n\n  function findState(stateOrName, base) {\n    if (!stateOrName) return undefined;\n\n    var isStr = isString(stateOrName),\n        name  = isStr ? stateOrName : stateOrName.name,\n        path  = isRelative(name);\n\n    if (path) {\n      if (!base) throw new Error(\"No reference point given for path '\"  + name + \"'\");\n      base = findState(base);\n      \n      var rel = name.split(\".\"), i = 0, pathLength = rel.length, current = base;\n\n      for (; i < pathLength; i++) {\n        if (rel[i] === \"\" && i === 0) {\n          current = base;\n          continue;\n        }\n        if (rel[i] === \"^\") {\n          if (!current.parent) throw new Error(\"Path '\" + name + \"' not valid for state '\" + base.name + \"'\");\n          current = current.parent;\n          continue;\n        }\n        break;\n      }\n      rel = rel.slice(i).join(\".\");\n      name = current.name + (current.name && rel ? \".\" : \"\") + rel;\n    }\n    var state = states[name];\n\n    if (state && (isStr || (!isStr && (state === stateOrName || state.self === stateOrName)))) {\n      return state;\n    }\n    return undefined;\n  }\n\n  function queueState(parentName, state) {\n    if (!queue[parentName]) {\n      queue[parentName] = [];\n    }\n    queue[parentName].push(state);\n  }\n\n  function flushQueuedChildren(parentName) {\n    var queued = queue[parentName] || [];\n    while(queued.length) {\n      registerState(queued.shift());\n    }\n  }\n\n  function registerState(state) {\n    state = inherit(state, {\n      self: state,\n      resolve: state.resolve || {},\n      toString: function() { return this.name; }\n    });\n\n    var name = state.name;\n    if (!isString(name) || name.indexOf('@') >= 0) throw new Error(\"State must have a valid name\");\n    if (states.hasOwnProperty(name)) throw new Error(\"State '\" + name + \"'' is already defined\");\n    var parentName = (name.indexOf('.') !== -1) ? name.substring(0, name.lastIndexOf('.'))\n        : (isString(state.parent)) ? state.parent\n        : (isObject(state.parent) && isString(state.parent.name)) ? state.parent.name\n        : '';\n    if (parentName && !states[parentName]) {\n      return queueState(parentName, state.self);\n    }\n\n    for (var key in stateBuilder) {\n      if (isFunction(stateBuilder[key])) state[key] = stateBuilder[key](state, stateBuilder.$delegates[key]);\n    }\n    states[name] = state;\n    if (!state[abstractKey] && state.url) {\n      $urlRouterProvider.when(state.url, ['$match', '$stateParams', function ($match, $stateParams) {\n        if ($state.$current.navigable != state || !equalForKeys($match, $stateParams)) {\n          $state.transitionTo(state, $match, { inherit: true, location: false });\n        }\n      }]);\n    }\n    flushQueuedChildren(name);\n\n    return state;\n  }\n  function isGlob (text) {\n    return text.indexOf('*') > -1;\n  }\n  function doesStateMatchGlob (glob) {\n    var globSegments = glob.split('.'),\n        segments = $state.$current.name.split('.');\n    for (var i = 0, l = globSegments.length; i < l; i++) {\n      if (globSegments[i] === '*') {\n        segments[i] = '*';\n      }\n    }\n    if (globSegments[0] === '**') {\n       segments = segments.slice(indexOf(segments, globSegments[1]));\n       segments.unshift('**');\n    }\n    if (globSegments[globSegments.length - 1] === '**') {\n       segments.splice(indexOf(segments, globSegments[globSegments.length - 2]) + 1, Number.MAX_VALUE);\n       segments.push('**');\n    }\n\n    if (globSegments.length != segments.length) {\n      return false;\n    }\n\n    return segments.join('') === globSegments.join('');\n  }\n  root = registerState({\n    name: '',\n    url: '^',\n    views: null,\n    'abstract': true\n  });\n  root.navigable = null;\n\n\n    this.decorator = decorator;\n  function decorator(name, func) {\n    /*jshint validthis: true */\n    if (isString(name) && !isDefined(func)) {\n      return stateBuilder[name];\n    }\n    if (!isFunction(func) || !isString(name)) {\n      return this;\n    }\n    if (stateBuilder[name] && !stateBuilder.$delegates[name]) {\n      stateBuilder.$delegates[name] = stateBuilder[name];\n    }\n    stateBuilder[name] = func;\n    return this;\n  }\n\n    this.state = state;\n  function state(name, definition) {\n    /*jshint validthis: true */\n    if (isObject(name)) definition = name;\n    else definition.name = name;\n    registerState(definition);\n    return this;\n  }\n\n    this.$get = $get;\n  $get.$inject = ['$rootScope', '$q', '$view', '$injector', '$resolve', '$stateParams', '$urlRouter', '$location', '$urlMatcherFactory'];\n  function $get(   $rootScope,   $q,   $view,   $injector,   $resolve,   $stateParams,   $urlRouter,   $location,   $urlMatcherFactory) {\n\n    var TransitionSuperseded = $q.reject(new Error('transition superseded'));\n    var TransitionPrevented = $q.reject(new Error('transition prevented'));\n    var TransitionAborted = $q.reject(new Error('transition aborted'));\n    var TransitionFailed = $q.reject(new Error('transition failed'));\n    function handleRedirect(redirect, state, params, options) {\n            var evt = $rootScope.$broadcast('$stateNotFound', redirect, state, params);\n\n      if (evt.defaultPrevented) {\n        $urlRouter.update();\n        return TransitionAborted;\n      }\n\n      if (!evt.retry) {\n        return null;\n      }\n      if (options.$retry) {\n        $urlRouter.update();\n        return TransitionFailed;\n      }\n      var retryTransition = $state.transition = $q.when(evt.retry);\n\n      retryTransition.then(function() {\n        if (retryTransition !== $state.transition) return TransitionSuperseded;\n        redirect.options.$retry = true;\n        return $state.transitionTo(redirect.to, redirect.toParams, redirect.options);\n      }, function() {\n        return TransitionAborted;\n      });\n      $urlRouter.update();\n\n      return retryTransition;\n    }\n\n    root.locals = { resolve: null, globals: { $stateParams: {} } };\n\n    $state = {\n      params: {},\n      current: root.self,\n      $current: root,\n      transition: null\n    };\n\n        $state.reload = function reload(state) {\n      return $state.transitionTo($state.current, $stateParams, { reload: state || true, inherit: false, notify: true});\n    };\n\n        $state.go = function go(to, params, options) {\n      return $state.transitionTo(to, params, extend({ inherit: true, relative: $state.$current }, options));\n    };\n\n        $state.transitionTo = function transitionTo(to, toParams, options) {\n      toParams = toParams || {};\n      options = extend({\n        location: true, inherit: false, relative: null, notify: true, reload: false, $retry: false\n      }, options || {});\n\n      var from = $state.$current, fromParams = $state.params, fromPath = from.path;\n      var evt, toState = findState(to, options.relative);\n      var hash = toParams['#'];\n\n      if (!isDefined(toState)) {\n        var redirect = { to: to, toParams: toParams, options: options };\n        var redirectResult = handleRedirect(redirect, from.self, fromParams, options);\n\n        if (redirectResult) {\n          return redirectResult;\n        }\n        to = redirect.to;\n        toParams = redirect.toParams;\n        options = redirect.options;\n        toState = findState(to, options.relative);\n\n        if (!isDefined(toState)) {\n          if (!options.relative) throw new Error(\"No such state '\" + to + \"'\");\n          throw new Error(\"Could not resolve '\" + to + \"' from state '\" + options.relative + \"'\");\n        }\n      }\n      if (toState[abstractKey]) throw new Error(\"Cannot transition to abstract state '\" + to + \"'\");\n      if (options.inherit) toParams = inheritParams($stateParams, toParams || {}, $state.$current, toState);\n      if (!toState.params.$$validates(toParams)) return TransitionFailed;\n\n      toParams = toState.params.$$values(toParams);\n      to = toState;\n\n      var toPath = to.path;\n      var keep = 0, state = toPath[keep], locals = root.locals, toLocals = [];\n      var skipTriggerReloadCheck = false;\n\n      if (!options.reload) {\n        while (state && state === fromPath[keep] && state.ownParams.$$equals(toParams, fromParams)) {\n          locals = toLocals[keep] = state.locals;\n          keep++;\n          state = toPath[keep];\n        }\n      } else if (isString(options.reload) || isObject(options.reload)) {\n        if (isObject(options.reload) && !options.reload.name) {\n          throw new Error('Invalid reload state object');\n        }\n        \n        var reloadState = options.reload === true ? fromPath[0] : findState(options.reload);\n        if (options.reload && !reloadState) {\n          throw new Error(\"No such reload state '\" + (isString(options.reload) ? options.reload : options.reload.name) + \"'\");\n        }\n\n        skipTriggerReloadCheck = true;\n \n        while (state && state === fromPath[keep] && state !== reloadState) {\n          locals = toLocals[keep] = state.locals;\n          keep++;\n          state = toPath[keep];\n        }\n      }\n      if (!skipTriggerReloadCheck && shouldTriggerReload(to, from, locals, options)) {\n        if (to.self.reloadOnSearch !== false) $urlRouter.update();\n        $state.transition = null;\n        return $q.when($state.current);\n      }\n      toParams = filterByKeys(to.params.$$keys(), toParams || {});\n      if (options.notify) {\n                if ($rootScope.$broadcast('$stateChangeStart', to.self, toParams, from.self, fromParams).defaultPrevented) {\n          $rootScope.$broadcast('$stateChangeCancel', to.self, toParams, from.self, fromParams);\n          $urlRouter.update();\n          return TransitionPrevented;\n        }\n      }\n      var resolved = $q.when(locals);\n\n      for (var l = keep; l < toPath.length; l++, state = toPath[l]) {\n        locals = toLocals[l] = inherit(locals);\n        resolved = resolveState(state, toParams, state === to, resolved, locals, options);\n      }\n      var transition = $state.transition = resolved.then(function () {\n        var l, entering, exiting;\n\n        if ($state.transition !== transition) return TransitionSuperseded;\n        for (l = fromPath.length - 1; l >= keep; l--) {\n          exiting = fromPath[l];\n          if (exiting.self.onExit) {\n            $injector.invoke(exiting.self.onExit, exiting.self, exiting.locals.globals);\n          }\n          exiting.locals = null;\n        }\n        for (l = keep; l < toPath.length; l++) {\n          entering = toPath[l];\n          entering.locals = toLocals[l];\n          if (entering.self.onEnter) {\n            $injector.invoke(entering.self.onEnter, entering.self, entering.locals.globals);\n          }\n        }\n        if (hash) toParams['#'] = hash;\n        if ($state.transition !== transition) return TransitionSuperseded;\n        $state.$current = to;\n        $state.current = to.self;\n        $state.params = toParams;\n        copy($state.params, $stateParams);\n        $state.transition = null;\n\n        if (options.location && to.navigable) {\n          $urlRouter.push(to.navigable.url, to.navigable.locals.globals.$stateParams, {\n            $$avoidResync: true, replace: options.location === 'replace'\n          });\n        }\n\n        if (options.notify) {\n                  $rootScope.$broadcast('$stateChangeSuccess', to.self, toParams, from.self, fromParams);\n        }\n        $urlRouter.update(true);\n\n        return $state.current;\n      }, function (error) {\n        if ($state.transition !== transition) return TransitionSuperseded;\n\n        $state.transition = null;\n                evt = $rootScope.$broadcast('$stateChangeError', to.self, toParams, from.self, fromParams, error);\n\n        if (!evt.defaultPrevented) {\n            $urlRouter.update();\n        }\n\n        return $q.reject(error);\n      });\n\n      return transition;\n    };\n\n        $state.is = function is(stateOrName, params, options) {\n      options = extend({ relative: $state.$current }, options || {});\n      var state = findState(stateOrName, options.relative);\n\n      if (!isDefined(state)) { return undefined; }\n      if ($state.$current !== state) { return false; }\n      return params ? equalForKeys(state.params.$$values(params), $stateParams) : true;\n    };\n\n        $state.includes = function includes(stateOrName, params, options) {\n      options = extend({ relative: $state.$current }, options || {});\n      if (isString(stateOrName) && isGlob(stateOrName)) {\n        if (!doesStateMatchGlob(stateOrName)) {\n          return false;\n        }\n        stateOrName = $state.$current.name;\n      }\n\n      var state = findState(stateOrName, options.relative);\n      if (!isDefined(state)) { return undefined; }\n      if (!isDefined($state.$current.includes[state.name])) { return false; }\n      return params ? equalForKeys(state.params.$$values(params), $stateParams, objectKeys(params)) : true;\n    };\n\n\n        $state.href = function href(stateOrName, params, options) {\n      options = extend({\n        lossy:    true,\n        inherit:  true,\n        absolute: false,\n        relative: $state.$current\n      }, options || {});\n\n      var state = findState(stateOrName, options.relative);\n\n      if (!isDefined(state)) return null;\n      if (options.inherit) params = inheritParams($stateParams, params || {}, $state.$current, state);\n      \n      var nav = (state && options.lossy) ? state.navigable : state;\n\n      if (!nav || nav.url === undefined || nav.url === null) {\n        return null;\n      }\n      return $urlRouter.href(nav.url, filterByKeys(state.params.$$keys().concat('#'), params || {}), {\n        absolute: options.absolute\n      });\n    };\n\n        $state.get = function (stateOrName, context) {\n      if (arguments.length === 0) return map(objectKeys(states), function(name) { return states[name].self; });\n      var state = findState(stateOrName, context || $state.$current);\n      return (state && state.self) ? state.self : null;\n    };\n\n    function resolveState(state, params, paramsAreFiltered, inherited, dst, options) {\n      var $stateParams = (paramsAreFiltered) ? params : filterByKeys(state.params.$$keys(), params);\n      var locals = { $stateParams: $stateParams };\n      dst.resolve = $resolve.resolve(state.resolve, locals, dst.resolve, state);\n      var promises = [dst.resolve.then(function (globals) {\n        dst.globals = globals;\n      })];\n      if (inherited) promises.push(inherited);\n      forEach(state.views, function (view, name) {\n        var injectables = (view.resolve && view.resolve !== state.resolve ? view.resolve : {});\n        injectables.$template = [ function () {\n          return $view.load(name, { view: view, locals: locals, params: $stateParams, notify: options.notify }) || '';\n        }];\n\n        promises.push($resolve.resolve(injectables, locals, dst.resolve, state).then(function (result) {\n          if (isFunction(view.controllerProvider) || isArray(view.controllerProvider)) {\n            var injectLocals = angular.extend({}, injectables, locals, result);\n            result.$$controller = $injector.invoke(view.controllerProvider, null, injectLocals);\n          } else {\n            result.$$controller = view.controller;\n          }\n          result.$$state = state;\n          result.$$controllerAs = view.controllerAs;\n          dst[name] = result;\n        }));\n      });\n      return $q.all(promises).then(function (values) {\n        return dst;\n      });\n    }\n\n    return $state;\n  }\n\n  function shouldTriggerReload(to, from, locals, options) {\n    if (to === from && ((locals === from.locals && !options.reload) || (to.self.reloadOnSearch === false))) {\n      return true;\n    }\n  }\n}\n\nangular.module('ui.router.state')\n  .value('$stateParams', {})\n  .provider('$state', $StateProvider);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-ui-router/src/stateDirectives.js",
    "content": "function parseStateRef(ref, current) {\n  var preparsed = ref.match(/^\\s*({[^}]*})\\s*$/), parsed;\n  if (preparsed) ref = current + '(' + preparsed[1] + ')';\n  parsed = ref.replace(/\\n/g, \" \").match(/^([^(]+?)\\s*(\\((.*)\\))?$/);\n  if (!parsed || parsed.length !== 4) throw new Error(\"Invalid state ref '\" + ref + \"'\");\n  return { state: parsed[1], paramExpr: parsed[3] || null };\n}\n\nfunction stateContext(el) {\n  var stateData = el.parent().inheritedData('$uiView');\n\n  if (stateData && stateData.state && stateData.state.name) {\n    return stateData.state;\n  }\n}\n\n$StateRefDirective.$inject = ['$state', '$timeout'];\nfunction $StateRefDirective($state, $timeout) {\n  var allowedOptions = ['location', 'inherit', 'reload', 'absolute'];\n\n  return {\n    restrict: 'A',\n    require: ['?^uiSrefActive', '?^uiSrefActiveEq'],\n    link: function(scope, element, attrs, uiSrefActive) {\n      var ref = parseStateRef(attrs.uiSref, $state.current.name);\n      var params = null, url = null, base = stateContext(element) || $state.$current;\n      var hrefKind = Object.prototype.toString.call(element.prop('href')) === '[object SVGAnimatedString]' ?\n                 'xlink:href' : 'href';\n      var newHref = null, isAnchor = element.prop(\"tagName\").toUpperCase() === \"A\";\n      var isForm = element[0].nodeName === \"FORM\";\n      var attr = isForm ? \"action\" : hrefKind, nav = true;\n\n      var options = { relative: base, inherit: true };\n      var optionsOverride = scope.$eval(attrs.uiSrefOpts) || {};\n\n      angular.forEach(allowedOptions, function(option) {\n        if (option in optionsOverride) {\n          options[option] = optionsOverride[option];\n        }\n      });\n\n      var update = function(newVal) {\n        if (newVal) params = angular.copy(newVal);\n        if (!nav) return;\n\n        newHref = $state.href(ref.state, params, options);\n\n        var activeDirective = uiSrefActive[1] || uiSrefActive[0];\n        if (activeDirective) {\n          activeDirective.$$addStateInfo(ref.state, params);\n        }\n        if (newHref === null) {\n          nav = false;\n          return false;\n        }\n        attrs.$set(attr, newHref);\n      };\n\n      if (ref.paramExpr) {\n        scope.$watch(ref.paramExpr, function(newVal, oldVal) {\n          if (newVal !== params) update(newVal);\n        }, true);\n        params = angular.copy(scope.$eval(ref.paramExpr));\n      }\n      update();\n\n      if (isForm) return;\n\n      element.bind(\"click\", function(e) {\n        var button = e.which || e.button;\n        if ( !(button > 1 || e.ctrlKey || e.metaKey || e.shiftKey || element.attr('target')) ) {\n          var transition = $timeout(function() {\n            $state.go(ref.state, params, options);\n          });\n          e.preventDefault();\n          var ignorePreventDefaultCount = isAnchor && !newHref ? 1: 0;\n          e.preventDefault = function() {\n            if (ignorePreventDefaultCount-- <= 0)\n              $timeout.cancel(transition);\n          };\n        }\n      });\n    }\n  };\n}\n\n\n$StateRefActiveDirective.$inject = ['$state', '$stateParams', '$interpolate'];\nfunction $StateRefActiveDirective($state, $stateParams, $interpolate) {\n  return  {\n    restrict: \"A\",\n    controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {\n      var states = [], activeClass;\n      activeClass = $interpolate($attrs.uiSrefActiveEq || $attrs.uiSrefActive || '', false)($scope);\n      this.$$addStateInfo = function (newState, newParams) {\n        var state = $state.get(newState, stateContext($element));\n\n        states.push({\n          state: state || { name: newState },\n          params: newParams\n        });\n\n        update();\n      };\n\n      $scope.$on('$stateChangeSuccess', update);\n      function update() {\n        if (anyMatch()) {\n          $element.addClass(activeClass);\n        } else {\n          $element.removeClass(activeClass);\n        }\n      }\n\n      function anyMatch() {\n        for (var i = 0; i < states.length; i++) {\n          if (isMatch(states[i].state, states[i].params)) {\n            return true;\n          }\n        }\n        return false;\n      }\n\n      function isMatch(state, params) {\n        if (typeof $attrs.uiSrefActiveEq !== 'undefined') {\n          return $state.is(state.name, params);\n        } else {\n          return $state.includes(state.name, params);\n        }\n      }\n    }]\n  };\n}\n\nangular.module('ui.router.state')\n  .directive('uiSref', $StateRefDirective)\n  .directive('uiSrefActive', $StateRefActiveDirective)\n  .directive('uiSrefActiveEq', $StateRefActiveDirective);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-ui-router/src/stateFilters.js",
    "content": "$IsStateFilter.$inject = ['$state'];\nfunction $IsStateFilter($state) {\n  var isFilter = function (state) {\n    return $state.is(state);\n  };\n  isFilter.$stateful = true;\n  return isFilter;\n}\n\n$IncludedByStateFilter.$inject = ['$state'];\nfunction $IncludedByStateFilter($state) {\n  var includesFilter = function (state) {\n    return $state.includes(state);\n  };\n  includesFilter.$stateful = true;\n  return  includesFilter;\n}\n\nangular.module('ui.router.state')\n  .filter('isState', $IsStateFilter)\n  .filter('includedByState', $IncludedByStateFilter);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-ui-router/src/templateFactory.js",
    "content": "$TemplateFactory.$inject = ['$http', '$templateCache', '$injector'];\nfunction $TemplateFactory(  $http,   $templateCache,   $injector) {\n\n    this.fromConfig = function (config, params, locals) {\n    return (\n      isDefined(config.template) ? this.fromString(config.template, params) :\n      isDefined(config.templateUrl) ? this.fromUrl(config.templateUrl, params) :\n      isDefined(config.templateProvider) ? this.fromProvider(config.templateProvider, params, locals) :\n      null\n    );\n  };\n\n    this.fromString = function (template, params) {\n    return isFunction(template) ? template(params) : template;\n  };\n\n    this.fromUrl = function (url, params) {\n    if (isFunction(url)) url = url(params);\n    if (url == null) return null;\n    else return $http\n        .get(url, { cache: $templateCache, headers: { Accept: 'text/html' }})\n        .then(function(response) { return response.data; });\n  };\n\n    this.fromProvider = function (provider, params, locals) {\n    return $injector.invoke(provider, null, locals || { params: params });\n  };\n}\n\nangular.module('ui.router.util').service('$templateFactory', $TemplateFactory);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-ui-router/src/urlMatcherFactory.js",
    "content": "var $$UMFP; // reference to $UrlMatcherFactoryProvider\n\nfunction UrlMatcher(pattern, config, parentMatcher) {\n  config = extend({ params: {} }, isObject(config) ? config : {});\n  var placeholder       = /([:*])([\\w\\[\\]]+)|\\{([\\w\\[\\]]+)(?:\\:((?:[^{}\\\\]+|\\\\.|\\{(?:[^{}\\\\]+|\\\\.)*\\})+))?\\}/g,\n      searchPlaceholder = /([:]?)([\\w\\[\\]-]+)|\\{([\\w\\[\\]-]+)(?:\\:((?:[^{}\\\\]+|\\\\.|\\{(?:[^{}\\\\]+|\\\\.)*\\})+))?\\}/g,\n      compiled = '^', last = 0, m,\n      segments = this.segments = [],\n      parentParams = parentMatcher ? parentMatcher.params : {},\n      params = this.params = parentMatcher ? parentMatcher.params.$$new() : new $$UMFP.ParamSet(),\n      paramNames = [];\n\n  function addParameter(id, type, config, location) {\n    paramNames.push(id);\n    if (parentParams[id]) return parentParams[id];\n    if (!/^\\w+(-+\\w+)*(?:\\[\\])?$/.test(id)) throw new Error(\"Invalid parameter name '\" + id + \"' in pattern '\" + pattern + \"'\");\n    if (params[id]) throw new Error(\"Duplicate parameter name '\" + id + \"' in pattern '\" + pattern + \"'\");\n    params[id] = new $$UMFP.Param(id, type, config, location);\n    return params[id];\n  }\n\n  function quoteRegExp(string, pattern, squash, optional) {\n    var surroundPattern = ['',''], result = string.replace(/[\\\\\\[\\]\\^$*+?.()|{}]/g, \"\\\\$&\");\n    if (!pattern) return result;\n    switch(squash) {\n      case false: surroundPattern = ['(', ')' + (optional ? \"?\" : \"\")]; break;\n      case true:  surroundPattern = ['?(', ')?']; break;\n      default:    surroundPattern = ['(' + squash + \"|\", ')?']; break;\n    }\n    return result + surroundPattern[0] + pattern + surroundPattern[1];\n  }\n\n  this.source = pattern;\n  function matchDetails(m, isSearch) {\n    var id, regexp, segment, type, cfg, arrayMode;\n    id          = m[2] || m[3]; // IE[78] returns '' for unmatched groups instead of null\n    cfg         = config.params[id];\n    segment     = pattern.substring(last, m.index);\n    regexp      = isSearch ? m[4] : m[4] || (m[1] == '*' ? '.*' : null);\n    type        = $$UMFP.type(regexp || \"string\") || inherit($$UMFP.type(\"string\"), { pattern: new RegExp(regexp, config.caseInsensitive ? 'i' : undefined) });\n    return {\n      id: id, regexp: regexp, segment: segment, type: type, cfg: cfg\n    };\n  }\n\n  var p, param, segment;\n  while ((m = placeholder.exec(pattern))) {\n    p = matchDetails(m, false);\n    if (p.segment.indexOf('?') >= 0) break; // we're into the search part\n\n    param = addParameter(p.id, p.type, p.cfg, \"path\");\n    compiled += quoteRegExp(p.segment, param.type.pattern.source, param.squash, param.isOptional);\n    segments.push(p.segment);\n    last = placeholder.lastIndex;\n  }\n  segment = pattern.substring(last);\n  var i = segment.indexOf('?');\n\n  if (i >= 0) {\n    var search = this.sourceSearch = segment.substring(i);\n    segment = segment.substring(0, i);\n    this.sourcePath = pattern.substring(0, last + i);\n\n    if (search.length > 0) {\n      last = 0;\n      while ((m = searchPlaceholder.exec(search))) {\n        p = matchDetails(m, true);\n        param = addParameter(p.id, p.type, p.cfg, \"search\");\n        last = placeholder.lastIndex;\n      }\n    }\n  } else {\n    this.sourcePath = pattern;\n    this.sourceSearch = '';\n  }\n\n  compiled += quoteRegExp(segment) + (config.strict === false ? '\\/?' : '') + '$';\n  segments.push(segment);\n\n  this.regexp = new RegExp(compiled, config.caseInsensitive ? 'i' : undefined);\n  this.prefix = segments[0];\n  this.$$paramNames = paramNames;\n}\n\nUrlMatcher.prototype.concat = function (pattern, config) {\n  var defaultConfig = {\n    caseInsensitive: $$UMFP.caseInsensitive(),\n    strict: $$UMFP.strictMode(),\n    squash: $$UMFP.defaultSquashPolicy()\n  };\n  return new UrlMatcher(this.sourcePath + pattern + this.sourceSearch, extend(defaultConfig, config), this);\n};\n\nUrlMatcher.prototype.toString = function () {\n  return this.source;\n};\n\nUrlMatcher.prototype.exec = function (path, searchParams) {\n  var m = this.regexp.exec(path);\n  if (!m) return null;\n  searchParams = searchParams || {};\n\n  var paramNames = this.parameters(), nTotal = paramNames.length,\n    nPath = this.segments.length - 1,\n    values = {}, i, j, cfg, paramName;\n\n  if (nPath !== m.length - 1) throw new Error(\"Unbalanced capture group in route '\" + this.source + \"'\");\n\n  function decodePathArray(string) {\n    function reverseString(str) { return str.split(\"\").reverse().join(\"\"); }\n    function unquoteDashes(str) { return str.replace(/\\\\-/g, \"-\"); }\n\n    var split = reverseString(string).split(/-(?!\\\\)/);\n    var allReversed = map(split, reverseString);\n    return map(allReversed, unquoteDashes).reverse();\n  }\n\n  for (i = 0; i < nPath; i++) {\n    paramName = paramNames[i];\n    var param = this.params[paramName];\n    var paramVal = m[i+1];\n    for (j = 0; j < param.replace; j++) {\n      if (param.replace[j].from === paramVal) paramVal = param.replace[j].to;\n    }\n    if (paramVal && param.array === true) paramVal = decodePathArray(paramVal);\n    values[paramName] = param.value(paramVal);\n  }\n  for (UrlMatcher.prototype.parameters = function (param) {\n  if (!isDefined(param)) return this.$$paramNames;\n  return this.params[param] || null;\n};\n\nUrlMatcher.prototype.validates = function (params) {\n  return this.params.$$validates(params);\n};\n\nUrlMatcher.prototype.format = function (values) {\n  values = values || {};\n  var segments = this.segments, params = this.parameters(), paramset = this.params;\n  if (!this.validates(values)) return null;\n\n  var i, search = false, nPath = segments.length - 1, nTotal = params.length, result = segments[0];\n\n  function encodeDashes(str) { // Replace dashes with encoded \"\\-\"\n    return encodeURIComponent(str).replace(/-/g, function(c) { return '%5C%' + c.charCodeAt(0).toString(16).toUpperCase(); });\n  }\n\n  for (i = 0; i < nTotal; i++) {\n    var isPathParam = i < nPath;\n    var name = params[i], param = paramset[name], value = param.value(values[name]);\n    var isDefaultValue = param.isOptional && param.type.equals(param.value(), value);\n    var squash = isDefaultValue ? param.squash : false;\n    var encoded = param.type.encode(value);\n\n    if (isPathParam) {\n      var nextSegment = segments[i + 1];\n      if (squash === false) {\n        if (encoded != null) {\n          if (isArray(encoded)) {\n            result += map(encoded, encodeDashes).join(\"-\");\n          } else {\n            result += encodeURIComponent(encoded);\n          }\n        }\n        result += nextSegment;\n      } else if (squash === true) {\n        var capture = result.match(/\\/$/) ? /\\/?(.*)/ : /(.*)/;\n        result += nextSegment.match(capture)[1];\n      } else if (isString(squash)) {\n        result += squash + nextSegment;\n      }\n    } else {\n      if (encoded == null || (isDefaultValue && squash !== false)) continue;\n      if (!isArray(encoded)) encoded = [ encoded ];\n      encoded = map(encoded, encodeURIComponent).join('&' + name + '=');\n      result += (search ? '&' : '?') + (name + '=' + encoded);\n      search = true;\n    }\n  }\n\n  return result;\n};\n\nfunction Type(config) {\n  extend(this, config);\n}\n\nType.prototype.is = function(val, key) {\n  return true;\n};\n\nType.prototype.encode = function(val, key) {\n  return val;\n};\n\nType.prototype.decode = function(val, key) {\n  return val;\n};\n\nType.prototype.equals = function(a, b) {\n  return a == b;\n};\n\nType.prototype.$subPattern = function() {\n  var sub = this.pattern.toString();\n  return sub.substr(1, sub.length - 2);\n};\n\nType.prototype.pattern = /.*/;\n\nType.prototype.toString = function() { return \"{Type:\" + this.name + \"}\"; };\n\nType.prototype.$normalize = function(val) {\n  return this.is(val) ? val : this.decode(val);\n};\n\n/*\n * Wraps an existing custom Type as an array of Type, depending on 'mode'.\n * e.g.:\n * - urlmatcher pattern \"/path?{queryParam[]:int}\"\n * - url: \"/path?queryParam=1&queryParam=2\n * - $stateParams.queryParam will be [1, 2]\n * if `mode` is \"auto\", then\n * - url: \"/path?queryParam=1 will create $stateParams.queryParam: 1\n * - url: \"/path?queryParam=1&queryParam=2 will create $stateParams.queryParam: [1, 2]\n */\nType.prototype.$asArray = function(mode, isSearch) {\n  if (!mode) return this;\n  if (mode === \"auto\" && !isSearch) throw new Error(\"'auto' array mode is for query parameters only\");\n\n  function ArrayType(type, mode) {\n    function bindTo(type, callbackName) {\n      return function() {\n        return type[callbackName].apply(type, arguments);\n      };\n    }\n    function arrayWrap(val) { return isArray(val) ? val : (isDefined(val) ? [ val ] : []); }\n    function arrayUnwrap(val) {\n      switch(val.length) {\n        case 0: return undefined;\n        case 1: return mode === \"auto\" ? val[0] : val;\n        default: return val;\n      }\n    }\n    function falsey(val) { return !val; }\n    function arrayHandler(callback, allTruthyMode) {\n      return function handleArray(val) {\n        val = arrayWrap(val);\n        var result = map(val, callback);\n        if (allTruthyMode === true)\n          return filter(result, falsey).length === 0;\n        return arrayUnwrap(result);\n      };\n    }\n    function arrayEqualsHandler(callback) {\n      return function handleArray(val1, val2) {\n        var left = arrayWrap(val1), right = arrayWrap(val2);\n        if (left.length !== right.length) return false;\n        for (var i = 0; i < left.length; i++) {\n          if (!callback(left[i], right[i])) return false;\n        }\n        return true;\n      };\n    }\n\n    this.encode = arrayHandler(bindTo(type, 'encode'));\n    this.decode = arrayHandler(bindTo(type, 'decode'));\n    this.is     = arrayHandler(bindTo(type, 'is'), true);\n    this.equals = arrayEqualsHandler(bindTo(type, 'equals'));\n    this.pattern = type.pattern;\n    this.$normalize = arrayHandler(bindTo(type, '$normalize'));\n    this.name = type.name;\n    this.$arrayMode = mode;\n  }\n\n  return new ArrayType(this, mode);\n};\n\n\n\nfunction $UrlMatcherFactory() {\n  $$UMFP = this;\n\n  var isCaseInsensitive = false, isStrictMode = true, defaultSquashPolicy = false;\n\n  function valToString(val) { return val != null ? val.toString().replace(/\\//g, \"%2F\") : val; }\n  function valFromString(val) { return val != null ? val.toString().replace(/%2F/g, \"/\") : val; }\n  function regexpMatches(val) { /*jshint validthis:true */ return this.pattern.test(val); }\n\n  var $types = {}, enqueue = true, typeQueue = [], injector, defaultTypes = {\n    string: {\n      encode: valToString,\n      decode: valFromString,\n      is: function(val) { return typeof val === \"string\"; },\n      pattern: /[^/]*/\n    },\n    int: {\n      encode: valToString,\n      decode: function(val) { return parseInt(val, 10); },\n      is: function(val) { return isDefined(val) && this.decode(val.toString()) === val; },\n      pattern: /\\d+/\n    },\n    bool: {\n      encode: function(val) { return val ? 1 : 0; },\n      decode: function(val) { return parseInt(val, 10) !== 0; },\n      is: function(val) { return val === true || val === false; },\n      pattern: /0|1/\n    },\n    date: {\n      encode: function (val) {\n        if (!this.is(val))\n          return undefined;\n        return [ val.getFullYear(),\n          ('0' + (val.getMonth() + 1)).slice(-2),\n          ('0' + val.getDate()).slice(-2)\n        ].join(\"-\");\n      },\n      decode: function (val) {\n        if (this.is(val)) return val;\n        var match = this.capture.exec(val);\n        return match ? new Date(match[1], match[2] - 1, match[3]) : undefined;\n      },\n      is: function(val) { return val instanceof Date && !isNaN(val.valueOf()); },\n      equals: function (a, b) { return this.is(a) && this.is(b) && a.toISOString() === b.toISOString(); },\n      pattern: /[0-9]{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[1-2][0-9]|3[0-1])/,\n      capture: /([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])/\n    },\n    json: {\n      encode: angular.toJson,\n      decode: angular.fromJson,\n      is: angular.isObject,\n      equals: angular.equals,\n      pattern: /[^/]*/\n    },\n    any: { // does not encode/decode\n      encode: angular.identity,\n      decode: angular.identity,\n      is: angular.identity,\n      equals: angular.equals,\n      pattern: /.*/\n    }\n  };\n\n  function getDefaultConfig() {\n    return {\n      strict: isStrictMode,\n      caseInsensitive: isCaseInsensitive\n    };\n  }\n\n  function isInjectable(value) {\n    return (isFunction(value) || (isArray(value) && isFunction(value[value.length - 1])));\n  }\n\n    $UrlMatcherFactory.$$getDefaultValue = function(config) {\n    if (!isInjectable(config.value)) return config.value;\n    if (!injector) throw new Error(\"Injectable functions cannot be called at configuration time\");\n    return injector.invoke(config.value);\n  };\n\n    this.caseInsensitive = function(value) {\n    if (isDefined(value))\n      isCaseInsensitive = value;\n    return isCaseInsensitive;\n  };\n\n    this.strictMode = function(value) {\n    if (isDefined(value))\n      isStrictMode = value;\n    return isStrictMode;\n  };\n\n    this.defaultSquashPolicy = function(value) {\n    if (!isDefined(value)) return defaultSquashPolicy;\n    if (value !== true && value !== false && !isString(value))\n      throw new Error(\"Invalid squash policy: \" + value + \". Valid policies: false, true, arbitrary-string\");\n    defaultSquashPolicy = value;\n    return value;\n  };\n\n    this.compile = function (pattern, config) {\n    return new UrlMatcher(pattern, extend(getDefaultConfig(), config));\n  };\n\n    this.isMatcher = function (o) {\n    if (!isObject(o)) return false;\n    var result = true;\n\n    forEach(UrlMatcher.prototype, function(val, name) {\n      if (isFunction(val)) {\n        result = result && (isDefined(o[name]) && isFunction(o[name]));\n      }\n    });\n    return result;\n  };\n\n    this.type = function (name, definition, definitionFn) {\n    if (!isDefined(definition)) return $types[name];\n    if ($types.hasOwnProperty(name)) throw new Error(\"A type named '\" + name + \"' has already been defined.\");\n\n    $types[name] = new Type(extend({ name: name }, definition));\n    if (definitionFn) {\n      typeQueue.push({ name: name, def: definitionFn });\n      if (!enqueue) flushTypeQueue();\n    }\n    return this;\n  };\n  function flushTypeQueue() {\n    while(typeQueue.length) {\n      var type = typeQueue.shift();\n      if (type.pattern) throw new Error(\"You cannot override a type's .pattern at runtime.\");\n      angular.extend($types[type.name], injector.invoke(type.def));\n    }\n  }\n  forEach(defaultTypes, function(type, name) { $types[name] = new Type(extend({name: name}, type)); });\n  $types = inherit($types, {});\n\n  /* No need to document $get, since it returns this */\n  this.$get = ['$injector', function ($injector) {\n    injector = $injector;\n    enqueue = false;\n    flushTypeQueue();\n\n    forEach(defaultTypes, function(type, name) {\n      if (!$types[name]) $types[name] = new Type(type);\n    });\n    return this;\n  }];\n\n  this.Param = function Param(id, type, config, location) {\n    var self = this;\n    config = unwrapShorthand(config);\n    type = getType(config, type, location);\n    var arrayMode = getArrayMode();\n    type = arrayMode ? type.$asArray(arrayMode, location === \"search\") : type;\n    if (type.name === \"string\" && !arrayMode && location === \"path\" && config.value === undefined)\n      config.value = \"\"; // for 0.2.x; in 0.3.0+ do not automatically default to \"\"\n    var isOptional = config.value !== undefined;\n    var squash = getSquashPolicy(config, isOptional);\n    var replace = getReplace(config, arrayMode, isOptional, squash);\n\n    function unwrapShorthand(config) {\n      var keys = isObject(config) ? objectKeys(config) : [];\n      var isShorthand = indexOf(keys, \"value\") === -1 && indexOf(keys, \"type\") === -1 &&\n                        indexOf(keys, \"squash\") === -1 && indexOf(keys, \"array\") === -1;\n      if (isShorthand) config = { value: config };\n      config.$$fn = isInjectable(config.value) ? config.value : function () { return config.value; };\n      return config;\n    }\n\n    function getType(config, urlType, location) {\n      if (config.type && urlType) throw new Error(\"Param '\"+id+\"' has two type configurations.\");\n      if (urlType) return urlType;\n      if (!config.type) return (location === \"config\" ? $types.any : $types.string);\n      return config.type instanceof Type ? config.type : new Type(config.type);\n    }\n    function getArrayMode() {\n      var arrayDefaults = { array: (location === \"search\" ? \"auto\" : false) };\n      var arrayParamNomenclature = id.match(/\\[\\]$/) ? { array: true } : {};\n      return extend(arrayDefaults, arrayParamNomenclature, config).array;\n    }\n\n        function getSquashPolicy(config, isOptional) {\n      var squash = config.squash;\n      if (!isOptional || squash === false) return false;\n      if (!isDefined(squash) || squash == null) return defaultSquashPolicy;\n      if (squash === true || isString(squash)) return squash;\n      throw new Error(\"Invalid squash policy: '\" + squash + \"'. Valid policies: false, true, or arbitrary string\");\n    }\n\n    function getReplace(config, arrayMode, isOptional, squash) {\n      var replace, configuredKeys, defaultPolicy = [\n        { from: \"\",   to: (isOptional || arrayMode ? undefined : \"\") },\n        { from: null, to: (isOptional || arrayMode ? undefined : \"\") }\n      ];\n      replace = isArray(config.replace) ? config.replace : [];\n      if (isString(squash))\n        replace.push({ from: squash, to: undefined });\n      configuredKeys = map(replace, function(item) { return item.from; } );\n      return filter(defaultPolicy, function(item) { return indexOf(configuredKeys, item.from) === -1; }).concat(replace);\n    }\n\n        function $$getDefaultValue() {\n      if (!injector) throw new Error(\"Injectable functions cannot be called at configuration time\");\n      var defaultValue = injector.invoke(config.$$fn);\n      if (defaultValue !== null && defaultValue !== undefined && !self.type.is(defaultValue))\n        throw new Error(\"Default value (\" + defaultValue + \") for parameter '\" + self.id + \"' is not an instance of Type (\" + self.type.name + \")\");\n      return defaultValue;\n    }\n\n        function $value(value) {\n      function hasReplaceVal(val) { return function(obj) { return obj.from === val; }; }\n      function $replace(value) {\n        var replacement = map(filter(self.replace, hasReplaceVal(value)), function(obj) { return obj.to; });\n        return replacement.length ? replacement[0] : value;\n      }\n      value = $replace(value);\n      return !isDefined(value) ? $$getDefaultValue() : self.type.$normalize(value);\n    }\n\n    function toString() { return \"{Param:\" + id + \" \" + type + \" squash: '\" + squash + \"' optional: \" + isOptional + \"}\"; }\n\n    extend(this, {\n      id: id,\n      type: type,\n      location: location,\n      array: arrayMode,\n      squash: squash,\n      replace: replace,\n      isOptional: isOptional,\n      value: $value,\n      dynamic: undefined,\n      config: config,\n      toString: toString\n    });\n  };\n\n  function ParamSet(params) {\n    extend(this, params || {});\n  }\n\n  ParamSet.prototype = {\n    $$new: function() {\n      return inherit(this, extend(new ParamSet(), { $$parent: this}));\n    },\n    $$keys: function () {\n      var keys = [], chain = [], parent = this,\n        ignore = objectKeys(ParamSet.prototype);\n      while (parent) { chain.push(parent); parent = parent.$$parent; }\n      chain.reverse();\n      forEach(chain, function(paramset) {\n        forEach(objectKeys(paramset), function(key) {\n            if (indexOf(keys, key) === -1 && indexOf(ignore, key) === -1) keys.push(key);\n        });\n      });\n      return keys;\n    },\n    $$values: function(paramValues) {\n      var values = {}, self = this;\n      forEach(self.$$keys(), function(key) {\n        values[key] = self[key].value(paramValues && paramValues[key]);\n      });\n      return values;\n    },\n    $$equals: function(paramValues1, paramValues2) {\n      var equal = true, self = this;\n      forEach(self.$$keys(), function(key) {\n        var left = paramValues1 && paramValues1[key], right = paramValues2 && paramValues2[key];\n        if (!self[key].type.equals(left, right)) equal = false;\n      });\n      return equal;\n    },\n    $$validates: function $$validate(paramValues) {\n      var keys = this.$$keys(), i, param, rawVal, normalized, encoded;\n      for (i = 0; i < keys.length; i++) {\n        param = this[keys[i]];\n        rawVal = paramValues[keys[i]];\n        if ((rawVal === undefined || rawVal === null) && param.isOptional)\n          break; // There was no parameter value, but the param is optional\n        normalized = param.type.$normalize(rawVal);\n        if (!param.type.is(normalized))\n          return false; // The value was not of the correct Type, and could not be decoded to the correct Type\n        encoded = param.type.encode(normalized);\n        if (angular.isString(encoded) && !param.type.pattern.exec(encoded))\n          return false; // The value was of the correct type, but when encoded, did not match the Type's regexp\n      }\n      return true;\n    },\n    $$parent: undefined\n  };\n\n  this.ParamSet = ParamSet;\n}\nangular.module('ui.router.util').provider('$urlMatcherFactory', $UrlMatcherFactory);\nangular.module('ui.router.util').run(['$urlMatcherFactory', function($urlMatcherFactory) { }]);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-ui-router/src/urlRouter.js",
    "content": "$UrlRouterProvider.$inject = ['$locationProvider', '$urlMatcherFactoryProvider'];\nfunction $UrlRouterProvider(   $locationProvider,   $urlMatcherFactory) {\n  var rules = [], otherwise = null, interceptDeferred = false, listener;\n  function regExpPrefix(re) {\n    var prefix = /^\\^((?:\\\\[^a-zA-Z0-9]|[^\\\\\\[\\]\\^$*+?.()|{}]+)*)/.exec(re.source);\n    return (prefix != null) ? prefix[1].replace(/\\\\(.)/g, \"$1\") : '';\n  }\n  function interpolate(pattern, match) {\n    return pattern.replace(/\\$(\\$|\\d{1,2})/, function (m, what) {\n      return match[what === '$' ? 0 : Number(what)];\n    });\n  }\n\n    this.rule = function (rule) {\n    if (!isFunction(rule)) throw new Error(\"'rule' must be a function\");\n    rules.push(rule);\n    return this;\n  };\n\n    this.otherwise = function (rule) {\n    if (isString(rule)) {\n      var redirect = rule;\n      rule = function () { return redirect; };\n    }\n    else if (!isFunction(rule)) throw new Error(\"'rule' must be a function\");\n    otherwise = rule;\n    return this;\n  };\n\n\n  function handleIfMatch($injector, handler, match) {\n    if (!match) return false;\n    var result = $injector.invoke(handler, handler, { $match: match });\n    return isDefined(result) ? result : true;\n  }\n\n    this.when = function (what, handler) {\n    var redirect, handlerIsString = isString(handler);\n    if (isString(what)) what = $urlMatcherFactory.compile(what);\n\n    if (!handlerIsString && !isFunction(handler) && !isArray(handler))\n      throw new Error(\"invalid 'handler' in when()\");\n\n    var strategies = {\n      matcher: function (what, handler) {\n        if (handlerIsString) {\n          redirect = $urlMatcherFactory.compile(handler);\n          handler = ['$match', function ($match) { return redirect.format($match); }];\n        }\n        return extend(function ($injector, $location) {\n          return handleIfMatch($injector, handler, what.exec($location.path(), $location.search()));\n        }, {\n          prefix: isString(what.prefix) ? what.prefix : ''\n        });\n      },\n      regex: function (what, handler) {\n        if (what.global || what.sticky) throw new Error(\"when() RegExp must not be global or sticky\");\n\n        if (handlerIsString) {\n          redirect = handler;\n          handler = ['$match', function ($match) { return interpolate(redirect, $match); }];\n        }\n        return extend(function ($injector, $location) {\n          return handleIfMatch($injector, handler, what.exec($location.path()));\n        }, {\n          prefix: regExpPrefix(what)\n        });\n      }\n    };\n\n    var check = { matcher: $urlMatcherFactory.isMatcher(what), regex: what instanceof RegExp };\n\n    for (var n in check) {\n      if (check[n]) return this.rule(strategies[n](what, handler));\n    }\n\n    throw new Error(\"invalid 'what' in when()\");\n  };\n\n    this.deferIntercept = function (defer) {\n    if (defer === undefined) defer = true;\n    interceptDeferred = defer;\n  };\n\n    this.$get = $get;\n  $get.$inject = ['$location', '$rootScope', '$injector', '$browser'];\n  function $get(   $location,   $rootScope,   $injector,   $browser) {\n\n    var baseHref = $browser.baseHref(), location = $location.url(), lastPushedUrl;\n\n    function appendBasePath(url, isHtml5, absolute) {\n      if (baseHref === '/') return url;\n      if (isHtml5) return baseHref.slice(0, -1) + url;\n      if (absolute) return baseHref.slice(1) + url;\n      return url;\n    }\n    function update(evt) {\n      if (evt && evt.defaultPrevented) return;\n      var ignoreUpdate = lastPushedUrl && $location.url() === lastPushedUrl;\n      lastPushedUrl = undefined;\n      if (ignoreUpdate) return true;\n\n      function check(rule) {\n        var handled = rule($injector, $location);\n\n        if (!handled) return false;\n        if (isString(handled)) $location.replace().url(handled);\n        return true;\n      }\n      var n = rules.length, i;\n\n      for (i = 0; i < n; i++) {\n        if (check(rules[i])) return;\n      }\n      if (otherwise) check(otherwise);\n    }\n\n    function listen() {\n      listener = listener || $rootScope.$on('$locationChangeSuccess', update);\n      return listener;\n    }\n\n    if (!interceptDeferred) listen();\n\n    return {\n            sync: function() {\n        update();\n      },\n\n      listen: function() {\n        return listen();\n      },\n\n      update: function(read) {\n        if (read) {\n          location = $location.url();\n          return;\n        }\n        if ($location.url() === location) return;\n\n        $location.url(location);\n        $location.replace();\n      },\n\n      push: function(urlMatcher, params, options) {\n         var url = urlMatcher.format(params || {});\n        if (url !== null && params && params['#']) {\n            url += '#' + params['#'];\n        }\n\n        $location.url(url);\n        lastPushedUrl = options && options.$$avoidResync ? $location.url() : undefined;\n        if (options && options.replace) $location.replace();\n      },\n\n            href: function(urlMatcher, params, options) {\n        if (!urlMatcher.validates(params)) return null;\n\n        var isHtml5 = $locationProvider.html5Mode();\n        if (angular.isObject(isHtml5)) {\n          isHtml5 = isHtml5.enabled;\n        }\n        \n        var url = urlMatcher.format(params);\n        options = options || {};\n\n        if (!isHtml5 && url !== null) {\n          url = \"#\" + $locationProvider.hashPrefix() + url;\n        }\n        if (url !== null && params && params['#']) {\n          url += '#' + params['#'];\n        }\n\n        url = appendBasePath(url, isHtml5, options.absolute);\n\n        if (!options.absolute || !url) {\n          return url;\n        }\n\n        var slash = (!isHtml5 && url ? '/' : ''), port = $location.port();\n        port = (port === 80 || port === 443 ? '' : ':' + port);\n\n        return [$location.protocol(), '://', $location.host(), port, slash, url].join('');\n      }\n    };\n  }\n}\n\nangular.module('ui.router.router').provider('$urlRouter', $UrlRouterProvider);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-ui-router/src/view.js",
    "content": "\n$ViewProvider.$inject = [];\nfunction $ViewProvider() {\n\n  this.$get = $get;\n    $get.$inject = ['$rootScope', '$templateFactory'];\n  function $get(   $rootScope,   $templateFactory) {\n    return {\n            load: function load(name, options) {\n        var result, defaults = {\n          template: null, controller: null, view: null, locals: null, notify: true, async: true, params: {}\n        };\n        options = extend(defaults, options);\n\n        if (options.view) {\n          result = $templateFactory.fromConfig(options.view, options.params, options.locals);\n        }\n        if (result && options.notify) {\n                  $rootScope.$broadcast('$viewContentLoading', options);\n        }\n        return result;\n      }\n    };\n  }\n}\n\nangular.module('ui.router.state').provider('$view', $ViewProvider);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-ui-router/src/viewDirective.js",
    "content": "$ViewDirective.$inject = ['$state', '$injector', '$uiViewScroll', '$interpolate'];\nfunction $ViewDirective(   $state,   $injector,   $uiViewScroll,   $interpolate) {\n\n  function getService() {\n    return ($injector.has) ? function(service) {\n      return $injector.has(service) ? $injector.get(service) : null;\n    } : function(service) {\n      try {\n        return $injector.get(service);\n      } catch (e) {\n        return null;\n      }\n    };\n  }\n\n  var service = getService(),\n      $animator = service('$animator'),\n      $animate = service('$animate');\n  function getRenderer(attrs, scope) {\n    var statics = function() {\n      return {\n        enter: function (element, target, cb) { target.after(element); cb(); },\n        leave: function (element, cb) { element.remove(); cb(); }\n      };\n    };\n\n    if ($animate) {\n      return {\n        enter: function(element, target, cb) {\n          var promise = $animate.enter(element, null, target, cb);\n          if (promise && promise.then) promise.then(cb);\n        },\n        leave: function(element, cb) {\n          var promise = $animate.leave(element, cb);\n          if (promise && promise.then) promise.then(cb);\n        }\n      };\n    }\n\n    if ($animator) {\n      var animate = $animator && $animator(scope, attrs);\n\n      return {\n        enter: function(element, target, cb) {animate.enter(element, null, target); cb(); },\n        leave: function(element, cb) { animate.leave(element); cb(); }\n      };\n    }\n\n    return statics();\n  }\n\n  var directive = {\n    restrict: 'ECA',\n    terminal: true,\n    priority: 400,\n    transclude: 'element',\n    compile: function (tElement, tAttrs, $transclude) {\n      return function (scope, $element, attrs) {\n        var previousEl, currentEl, currentScope, latestLocals,\n            onloadExp     = attrs.onload || '',\n            autoScrollExp = attrs.autoscroll,\n            renderer      = getRenderer(attrs, scope);\n\n        scope.$on('$stateChangeSuccess', function() {\n          updateView(false);\n        });\n        scope.$on('$viewContentLoading', function() {\n          updateView(false);\n        });\n\n        updateView(true);\n\n        function cleanupLastView() {\n          if (previousEl) {\n            previousEl.remove();\n            previousEl = null;\n          }\n\n          if (currentScope) {\n            currentScope.$destroy();\n            currentScope = null;\n          }\n\n          if (currentEl) {\n            renderer.leave(currentEl, function() {\n              previousEl = null;\n            });\n\n            previousEl = currentEl;\n            currentEl = null;\n          }\n        }\n\n        function updateView(firstTime) {\n          var newScope,\n              name            = getUiViewName(scope, attrs, $element, $interpolate),\n              previousLocals  = name && $state.$current && $state.$current.locals[name];\n\n          if (!firstTime && previousLocals === latestLocals) return; // nothing to do\n          newScope = scope.$new();\n          latestLocals = $state.$current.locals[name];\n\n          var clone = $transclude(newScope, function(clone) {\n            renderer.enter(clone, $element, function onUiViewEnter() {\n              if(currentScope) {\n                currentScope.$emit('$viewContentAnimationEnded');\n              }\n\n              if (angular.isDefined(autoScrollExp) && !autoScrollExp || scope.$eval(autoScrollExp)) {\n                $uiViewScroll(clone);\n              }\n            });\n            cleanupLastView();\n          });\n\n          currentEl = clone;\n          currentScope = newScope;\n                    currentScope.$emit('$viewContentLoaded');\n          currentScope.$eval(onloadExp);\n        }\n      };\n    }\n  };\n\n  return directive;\n}\n\n$ViewDirectiveFill.$inject = ['$compile', '$controller', '$state', '$interpolate'];\nfunction $ViewDirectiveFill (  $compile,   $controller,   $state,   $interpolate) {\n  return {\n    restrict: 'ECA',\n    priority: -400,\n    compile: function (tElement) {\n      var initial = tElement.html();\n      return function (scope, $element, attrs) {\n        var current = $state.$current,\n            name = getUiViewName(scope, attrs, $element, $interpolate),\n            locals  = current && current.locals[name];\n\n        if (! locals) {\n          return;\n        }\n\n        $element.data('$uiView', { name: name, state: locals.$$state });\n        $element.html(locals.$template ? locals.$template : initial);\n\n        var link = $compile($element.contents());\n\n        if (locals.$$controller) {\n          locals.$scope = scope;\n          locals.$element = $element;\n          var controller = $controller(locals.$$controller, locals);\n          if (locals.$$controllerAs) {\n            scope[locals.$$controllerAs] = controller;\n          }\n          $element.data('$ngControllerController', controller);\n          $element.children().data('$ngControllerController', controller);\n        }\n\n        link(scope);\n      };\n    }\n  };\n}\n\nfunction getUiViewName(scope, attrs, element, $interpolate) {\n  var name = $interpolate(attrs.uiView || attrs.name || '')(scope);\n  var inherited = element.inheritedData('$uiView');\n  return name.indexOf('@') >= 0 ?  name :  (name + '@' + (inherited ? inherited.state.name : ''));\n}\n\nangular.module('ui.router.state').directive('uiView', $ViewDirective);\nangular.module('ui.router.state').directive('uiView', $ViewDirectiveFill);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/angular-ui-router/src/viewScroll.js",
    "content": "function $ViewScrollProvider() {\n\n  var useAnchorScroll = false;\n\n    this.useAnchorScroll = function () {\n    useAnchorScroll = true;\n  };\n\n    this.$get = ['$anchorScroll', '$timeout', function ($anchorScroll, $timeout) {\n    if (useAnchorScroll) {\n      return $anchorScroll;\n    }\n\n    return function ($element) {\n      return $timeout(function () {\n        $element[0].scrollIntoView();\n      }, 0, false);\n    };\n  }];\n}\n\nangular.module('ui.router.state').provider('$uiViewScroll', $ViewScrollProvider);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/.bower.json",
    "content": "{\n  \"name\": \"bootstrap\",\n  \"version\": \"3.0.3\",\n  \"main\": [\n    \"./dist/js/bootstrap.js\",\n    \"./dist/css/bootstrap.css\",\n    \"./dist/fonts/glyphicons-halflings-regular.eot\",\n    \"./dist/fonts/glyphicons-halflings-regular.svg\",\n    \"./dist/fonts/glyphicons-halflings-regular.ttf\",\n    \"./dist/fonts/glyphicons-halflings-regular.woff\"\n  ],\n  \"ignore\": [\n    \"**/.*\",\n    \"_*\",\n    \"docs-assets\",\n    \"examples\",\n    \"/fonts\",\n    \"js/tests\",\n    \"CNAME\",\n    \"CONTRIBUTING.md\",\n    \"Gruntfile.js\",\n    \"browserstack.json\",\n    \"composer.json\",\n    \"package.json\",\n    \"*.html\"\n  ],\n  \"dependencies\": {\n    \"jquery\": \">= 1.9.0\"\n  },\n  \"homepage\": \"https://github.com/twbs/bootstrap\",\n  \"_release\": \"3.0.3\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"v3.0.3\",\n    \"commit\": \"6d03173a1aad98e75f7d33e65b411c519176c59a\"\n  },\n  \"_source\": \"git://github.com/twbs/bootstrap.git\",\n  \"_target\": \"3.0.3\",\n  \"_originalSource\": \"bootstrap\"\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/DOCS-LICENSE",
    "content": "Creative Commons Legal Code\n\nAttribution 3.0 Unported\n\n    CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE\n    LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN\n    ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS\n    INFORMATION ON AN \"AS-IS\" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES\n    REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR\n    DAMAGES RESULTING FROM ITS USE.\n\nLicense\n\nTHE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE\nCOMMONS PUBLIC LICENSE (\"CCPL\" OR \"LICENSE\"). THE WORK IS PROTECTED BY\nCOPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS\nAUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED.\n\nBY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE\nTO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY\nBE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS\nCONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND\nCONDITIONS.\n\n1. Definitions\n\n a. \"Adaptation\" means a work based upon the Work, or upon the Work and\n    other pre-existing works, such as a translation, adaptation,\n    derivative work, arrangement of music or other alterations of a\n    literary or artistic work, or phonogram or performance and includes\n    cinematographic adaptations or any other form in which the Work may be\n    recast, transformed, or adapted including in any form recognizably\n    derived from the original, except that a work that constitutes a\n    Collection will not be considered an Adaptation for the purpose of\n    this License. For the avoidance of doubt, where the Work is a musical\n    work, performance or phonogram, the synchronization of the Work in\n    timed-relation with a moving image (\"synching\") will be considered an\n    Adaptation for the purpose of this License.\n b. \"Collection\" means a collection of literary or artistic works, such as\n    encyclopedias and anthologies, or performances, phonograms or\n    broadcasts, or other works or subject matter other than works listed\n    in Section 1(f) below, which, by reason of the selection and\n    arrangement of their contents, constitute intellectual creations, in\n    which the Work is included in its entirety in unmodified form along\n    with one or more other contributions, each constituting separate and\n    independent works in themselves, which together are assembled into a\n    collective whole. A work that constitutes a Collection will not be\n    considered an Adaptation (as defined above) for the purposes of this\n    License.\n c. \"Distribute\" means to make available to the public the original and\n    copies of the Work or Adaptation, as appropriate, through sale or\n    other transfer of ownership.\n d. \"Licensor\" means the individual, individuals, entity or entities that\n    offer(s) the Work under the terms of this License.\n e. \"Original Author\" means, in the case of a literary or artistic work,\n    the individual, individuals, entity or entities who created the Work\n    or if no individual or entity can be identified, the publisher; and in\n    addition (i) in the case of a performance the actors, singers,\n    musicians, dancers, and other persons who act, sing, deliver, declaim,\n    play in, interpret or otherwise perform literary or artistic works or\n    expressions of folklore; (ii) in the case of a phonogram the producer\n    being the person or legal entity who first fixes the sounds of a\n    performance or other sounds; and, (iii) in the case of broadcasts, the\n    organization that transmits the broadcast.\n f. \"Work\" means the literary and/or artistic work offered under the terms\n    of this License including without limitation any production in the\n    literary, scientific and artistic domain, whatever may be the mode or\n    form of its expression including digital form, such as a book,\n    pamphlet and other writing; a lecture, address, sermon or other work\n    of the same nature; a dramatic or dramatico-musical work; a\n    choreographic work or entertainment in dumb show; a musical\n    composition with or without words; a cinematographic work to which are\n    assimilated works expressed by a process analogous to cinematography;\n    a work of drawing, painting, architecture, sculpture, engraving or\n    lithography; a photographic work to which are assimilated works\n    expressed by a process analogous to photography; a work of applied\n    art; an illustration, map, plan, sketch or three-dimensional work\n    relative to geography, topography, architecture or science; a\n    performance; a broadcast; a phonogram; a compilation of data to the\n    extent it is protected as a copyrightable work; or a work performed by\n    a variety or circus performer to the extent it is not otherwise\n    considered a literary or artistic work.\n g. \"You\" means an individual or entity exercising rights under this\n    License who has not previously violated the terms of this License with\n    respect to the Work, or who has received express permission from the\n    Licensor to exercise rights under this License despite a previous\n    violation.\n h. \"Publicly Perform\" means to perform public recitations of the Work and\n    to communicate to the public those public recitations, by any means or\n    process, including by wire or wireless means or public digital\n    performances; to make available to the public Works in such a way that\n    members of the public may access these Works from a place and at a\n    place individually chosen by them; to perform the Work to the public\n    by any means or process and the communication to the public of the\n    performances of the Work, including by public digital performance; to\n    broadcast and rebroadcast the Work by any means including signs,\n    sounds or images.\n i. \"Reproduce\" means to make copies of the Work by any means including\n    without limitation by sound or visual recordings and the right of\n    fixation and reproducing fixations of the Work, including storage of a\n    protected performance or phonogram in digital form or other electronic\n    medium.\n\n2. Fair Dealing Rights. Nothing in this License is intended to reduce,\nlimit, or restrict any uses free from copyright or rights arising from\nlimitations or exceptions that are provided for in connection with the\ncopyright protection under copyright law or other applicable laws.\n\n3. License Grant. Subject to the terms and conditions of this License,\nLicensor hereby grants You a worldwide, royalty-free, non-exclusive,\nperpetual (for the duration of the applicable copyright) license to\nexercise the rights in the Work as stated below:\n\n a. to Reproduce the Work, to incorporate the Work into one or more\n    Collections, and to Reproduce the Work as incorporated in the\n    Collections;\n b. to create and Reproduce Adaptations provided that any such Adaptation,\n    including any translation in any medium, takes reasonable steps to\n    clearly label, demarcate or otherwise identify that changes were made\n    to the original Work. For example, a translation could be marked \"The\n    original work was translated from English to Spanish,\" or a\n    modification could indicate \"The original work has been modified.\";\n c. to Distribute and Publicly Perform the Work including as incorporated\n    in Collections; and,\n d. to Distribute and Publicly Perform Adaptations.\n e. For the avoidance of doubt:\n\n     i. Non-waivable Compulsory License Schemes. In those jurisdictions in\n        which the right to collect royalties through any statutory or\n        compulsory licensing scheme cannot be waived, the Licensor\n        reserves the exclusive right to collect such royalties for any\n        exercise by You of the rights granted under this License;\n    ii. Waivable Compulsory License Schemes. In those jurisdictions in\n        which the right to collect royalties through any statutory or\n        compulsory licensing scheme can be waived, the Licensor waives the\n        exclusive right to collect such royalties for any exercise by You\n        of the rights granted under this License; and,\n   iii. Voluntary License Schemes. The Licensor waives the right to\n        collect royalties, whether individually or, in the event that the\n        Licensor is a member of a collecting society that administers\n        voluntary licensing schemes, via that society, from any exercise\n        by You of the rights granted under this License.\n\nThe above rights may be exercised in all media and formats whether now\nknown or hereafter devised. The above rights include the right to make\nsuch modifications as are technically necessary to exercise the rights in\nother media and formats. Subject to Section 8(f), all rights not expressly\ngranted by Licensor are hereby reserved.\n\n4. Restrictions. The license granted in Section 3 above is expressly made\nsubject to and limited by the following restrictions:\n\n a. You may Distribute or Publicly Perform the Work only under the terms\n    of this License. You must include a copy of, or the Uniform Resource\n    Identifier (URI) for, this License with every copy of the Work You\n    Distribute or Publicly Perform. You may not offer or impose any terms\n    on the Work that restrict the terms of this License or the ability of\n    the recipient of the Work to exercise the rights granted to that\n    recipient under the terms of the License. You may not sublicense the\n    Work. You must keep intact all notices that refer to this License and\n    to the disclaimer of warranties with every copy of the Work You\n    Distribute or Publicly Perform. When You Distribute or Publicly\n    Perform the Work, You may not impose any effective technological\n    measures on the Work that restrict the ability of a recipient of the\n    Work from You to exercise the rights granted to that recipient under\n    the terms of the License. This Section 4(a) applies to the Work as\n    incorporated in a Collection, but this does not require the Collection\n    apart from the Work itself to be made subject to the terms of this\n    License. If You create a Collection, upon notice from any Licensor You\n    must, to the extent practicable, remove from the Collection any credit\n    as required by Section 4(b), as requested. If You create an\n    Adaptation, upon notice from any Licensor You must, to the extent\n    practicable, remove from the Adaptation any credit as required by\n    Section 4(b), as requested.\n b. If You Distribute, or Publicly Perform the Work or any Adaptations or\n    Collections, You must, unless a request has been made pursuant to\n    Section 4(a), keep intact all copyright notices for the Work and\n    provide, reasonable to the medium or means You are utilizing: (i) the\n    name of the Original Author (or pseudonym, if applicable) if supplied,\n    and/or if the Original Author and/or Licensor designate another party\n    or parties (e.g., a sponsor institute, publishing entity, journal) for\n    attribution (\"Attribution Parties\") in Licensor's copyright notice,\n    terms of service or by other reasonable means, the name of such party\n    or parties; (ii) the title of the Work if supplied; (iii) to the\n    extent reasonably practicable, the URI, if any, that Licensor\n    specifies to be associated with the Work, unless such URI does not\n    refer to the copyright notice or licensing information for the Work;\n    and (iv) , consistent with Section 3(b), in the case of an Adaptation,\n    a credit identifying the use of the Work in the Adaptation (e.g.,\n    \"French translation of the Work by Original Author,\" or \"Screenplay\n    based on original Work by Original Author\"). The credit required by\n    this Section 4 (b) may be implemented in any reasonable manner;\n    provided, however, that in the case of a Adaptation or Collection, at\n    a minimum such credit will appear, if a credit for all contributing\n    authors of the Adaptation or Collection appears, then as part of these\n    credits and in a manner at least as prominent as the credits for the\n    other contributing authors. For the avoidance of doubt, You may only\n    use the credit required by this Section for the purpose of attribution\n    in the manner set out above and, by exercising Your rights under this\n    License, You may not implicitly or explicitly assert or imply any\n    connection with, sponsorship or endorsement by the Original Author,\n    Licensor and/or Attribution Parties, as appropriate, of You or Your\n    use of the Work, without the separate, express prior written\n    permission of the Original Author, Licensor and/or Attribution\n    Parties.\n c. Except as otherwise agreed in writing by the Licensor or as may be\n    otherwise permitted by applicable law, if You Reproduce, Distribute or\n    Publicly Perform the Work either by itself or as part of any\n    Adaptations or Collections, You must not distort, mutilate, modify or\n    take other derogatory action in relation to the Work which would be\n    prejudicial to the Original Author's honor or reputation. Licensor\n    agrees that in those jurisdictions (e.g. Japan), in which any exercise\n    of the right granted in Section 3(b) of this License (the right to\n    make Adaptations) would be deemed to be a distortion, mutilation,\n    modification or other derogatory action prejudicial to the Original\n    Author's honor and reputation, the Licensor will waive or not assert,\n    as appropriate, this Section, to the fullest extent permitted by the\n    applicable national law, to enable You to reasonably exercise Your\n    right under Section 3(b) of this License (right to make Adaptations)\n    but not otherwise.\n\n5. Representations, Warranties and Disclaimer\n\nUNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR\nOFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY\nKIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE,\nINCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY,\nFITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF\nLATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS,\nWHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION\nOF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU.\n\n6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE\nLAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR\nANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES\nARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS\nBEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.\n\n7. Termination\n\n a. This License and the rights granted hereunder will terminate\n    automatically upon any breach by You of the terms of this License.\n    Individuals or entities who have received Adaptations or Collections\n    from You under this License, however, will not have their licenses\n    terminated provided such individuals or entities remain in full\n    compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will\n    survive any termination of this License.\n b. Subject to the above terms and conditions, the license granted here is\n    perpetual (for the duration of the applicable copyright in the Work).\n    Notwithstanding the above, Licensor reserves the right to release the\n    Work under different license terms or to stop distributing the Work at\n    any time; provided, however that any such election will not serve to\n    withdraw this License (or any other license that has been, or is\n    required to be, granted under the terms of this License), and this\n    License will continue in full force and effect unless terminated as\n    stated above.\n\n8. Miscellaneous\n\n a. Each time You Distribute or Publicly Perform the Work or a Collection,\n    the Licensor offers to the recipient a license to the Work on the same\n    terms and conditions as the license granted to You under this License.\n b. Each time You Distribute or Publicly Perform an Adaptation, Licensor\n    offers to the recipient a license to the original Work on the same\n    terms and conditions as the license granted to You under this License.\n c. If any provision of this License is invalid or unenforceable under\n    applicable law, it shall not affect the validity or enforceability of\n    the remainder of the terms of this License, and without further action\n    by the parties to this agreement, such provision shall be reformed to\n    the minimum extent necessary to make such provision valid and\n    enforceable.\n d. No term or provision of this License shall be deemed waived and no\n    breach consented to unless such waiver or consent shall be in writing\n    and signed by the party to be charged with such waiver or consent.\n e. This License constitutes the entire agreement between the parties with\n    respect to the Work licensed here. There are no understandings,\n    agreements or representations with respect to the Work not specified\n    here. Licensor shall not be bound by any additional provisions that\n    may appear in any communication from You. This License may not be\n    modified without the mutual written agreement of the Licensor and You.\n f. The rights granted under, and the subject matter referenced, in this\n    License were drafted utilizing the terminology of the Berne Convention\n    for the Protection of Literary and Artistic Works (as amended on\n    September 28, 1979), the Rome Convention of 1961, the WIPO Copyright\n    Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996\n    and the Universal Copyright Convention (as revised on July 24, 1971).\n    These rights and subject matter take effect in the relevant\n    jurisdiction in which the License terms are sought to be enforced\n    according to the corresponding provisions of the implementation of\n    those treaty provisions in the applicable national law. If the\n    standard suite of rights granted under applicable copyright law\n    includes additional rights not granted under this License, such\n    additional rights are deemed to be included in the License; this\n    License is not intended to restrict the license of any rights under\n    applicable law.\n\n\nCreative Commons Notice\n\n    Creative Commons is not a party to this License, and makes no warranty\n    whatsoever in connection with the Work. Creative Commons will not be\n    liable to You or any party on any legal theory for any damages\n    whatsoever, including without limitation any general, special,\n    incidental or consequential damages arising in connection to this\n    license. Notwithstanding the foregoing two (2) sentences, if Creative\n    Commons has expressly identified itself as the Licensor hereunder, it\n    shall have all rights and obligations of Licensor.\n\n    Except for the limited purpose of indicating to the public that the\n    Work is licensed under the CCPL, Creative Commons does not authorize\n    the use by either party of the trademark \"Creative Commons\" or any\n    related trademark or logo of Creative Commons without the prior\n    written consent of Creative Commons. Any permitted use will be in\n    compliance with Creative Commons' then-current trademark usage\n    guidelines, as may be published on its website or otherwise made\n    available upon request from time to time. For the avoidance of doubt,\n    this trademark restriction does not form part of this License.\n\n    Creative Commons may be contacted at http://creativecommons.org/.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/LICENSE-MIT",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2013 Twitter, Inc\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/README.md",
    "content": "# [Bootstrap](http://getbootstrap.com) [![Build Status](https://secure.travis-ci.org/twbs/bootstrap.png)](http://travis-ci.org/twbs/bootstrap) [![devDependency Status](https://david-dm.org/twbs/bootstrap/dev-status.png)](https://david-dm.org/twbs/bootstrap#info=devDependencies)\n[![Selenium Test Status](https://saucelabs.com/browser-matrix/bootstrap.svg)](https://saucelabs.com/u/bootstrap)\n\nBootstrap is a sleek, intuitive, and powerful front-end framework for faster and easier web development, created and maintained by [Mark Otto](http://twitter.com/mdo) and [Jacob Thornton](http://twitter.com/fat).\n\nTo get started, check out <http://getbootstrap.com>!\n\n\n\n## Quick start\n\nThree quick start options are available:\n\n* [Download the latest release](https://github.com/twbs/bootstrap/archive/v3.0.3.zip).\n* Clone the repo: `git clone https://github.com/twbs/bootstrap.git`.\n* Install with [Bower](http://bower.io): `bower install bootstrap`.\n\nRead the [Getting Started page](http://getbootstrap.com/getting-started/) for information on the framework contents, templates and examples, and more.\n\n### What's included\n\nWithin the download you'll find the following directories and files, logically grouping common assets and providing both compiled and minified variations. You'll see something like this:\n\n```\nbootstrap/\n├── css/\n│   ├── bootstrap.css\n│   ├── bootstrap.min.css\n│   ├── bootstrap-theme.css\n│   └── bootstrap-theme.min.css\n├── js/\n│   ├── bootstrap.js\n│   └── bootstrap.min.js\n└── fonts/\n    ├── glyphicons-halflings-regular.eot\n    ├── glyphicons-halflings-regular.svg\n    ├── glyphicons-halflings-regular.ttf\n    └── glyphicons-halflings-regular.woff\n```\n\nWe provide compiled CSS and JS (`bootstrap.*`), as well as compiled and minified CSS and JS (`bootstrap.min.*`). Fonts from Glyphicons are included, as is the optional Bootstrap theme.\n\n\n\n## Bugs and feature requests\n\nHave a bug or a feature request? [Please open a new issue](https://github.com/twbs/bootstrap/issues). Before opening any issue, please search for existing issues and read the [Issue Guidelines](https://github.com/necolas/issue-guidelines), written by [Nicolas Gallagher](https://github.com/necolas/).\n\nYou may use [this JS Bin](http://jsbin.com/aKiCIDO/1/edit) as a template for your bug reports.\n\n\n\n## Documentation\n\nBootstrap's documentation, included in this repo in the root directory, is built with [Jekyll](http://jekyllrb.com) and publicly hosted on GitHub Pages at <http://getbootstrap.com>. The docs may also be run locally.\n\n### Running documentation locally\n\n1. If necessary, [install Jekyll](http://jekyllrb.com/docs/installation) (requires v1.x).\n2. From the root `/bootstrap` directory, run `jekyll serve` in the command line.\n  - **Windows users:** run `chcp 65001` first to change the command prompt's character encoding ([code page](http://en.wikipedia.org/wiki/Windows_code_page)) to UTF-8 so Jekyll runs without errors.\n3. Open <http://localhost:9001> in your browser, and voilà.\n\nLearn more about using Jekyll by reading its [documentation](http://jekyllrb.com/docs/home/).\n\n### Documentation for previous releases\n\nDocumentation for v2.3.2 has been made available for the time being at <http://getbootstrap.com/2.3.2/> while folks transition to Bootstrap 3.\n\n[Previous releases](https://github.com/twbs/bootstrap/releases) and their documentation are also available for download.\n\n\n\n## Compiling CSS and JavaScript\n\nBootstrap uses [Grunt](http://gruntjs.com/) with convenient methods for working with the framework. It's how we compile our code, run tests, and more. To use it, install the required dependencies as directed and then run some Grunt commands.\n\n### Install Grunt\n\nFrom the command line:\n\n1. Install `grunt-cli` globally with `npm install -g grunt-cli`.\n2. Navigate to the root `/bootstrap` directory, then run `npm install`. npm will look at [package.json](package.json) and automatically install the necessary local dependencies listed there.\n\nWhen completed, you'll be able to run the various Grunt commands provided from the command line.\n\n**Unfamiliar with `npm`? Don't have node installed?** That's a-okay. npm stands for [node packaged modules](http://npmjs.org/) and is a way to manage development dependencies through node.js. [Download and install node.js](http://nodejs.org/download/) before proceeding.\n\n### Available Grunt commands\n\n#### Build - `grunt`\nRun `grunt` to run tests locally and compile the CSS and JavaScript into `/dist`. **Uses [recess](http://twitter.github.io/recess/) and [UglifyJS](http://lisperator.net/uglifyjs/).**\n\n#### Only compile CSS and JavaScript - `grunt dist`\n`grunt dist` creates the `/dist` directory with compiled files. **Uses [recess](http://twitter.github.io/recess/) and [UglifyJS](http://lisperator.net/uglifyjs/).**\n\n#### Tests - `grunt test`\nRuns [JSHint](http://jshint.com) and [QUnit](http://qunitjs.com/) tests headlessly in [PhantomJS](http://phantomjs.org/) (used for CI).\n\n#### Watch - `grunt watch`\nThis is a convenience method for watching just Less files and automatically building them whenever you save.\n\n### Troubleshooting dependencies\n\nShould you encounter problems with installing dependencies or running Grunt commands, uninstall all previous dependency versions (global and local). Then, rerun `npm install`.\n\n\n\n## Contributing\n\nPlease read through our [contributing guidelines](https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md). Included are directions for opening issues, coding standards, and notes on development.\n\nMore over, if your pull request contains JavaScript patches or features, you must include relevant unit tests. All HTML and CSS should conform to the [Code Guide](http://github.com/mdo/code-guide), maintained by [Mark Otto](http://github.com/mdo).\n\nEditor preferences are available in the [editor config](.editorconfig) for easy use in common text editors. Read more and download plugins at <http://editorconfig.org>.\n\nWith v3.1, we're moving from the Apache 2 to the MIT license for the Bootstrap code (not the docs). Please see the [contributing guidelines](https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md) for more information.\n\n\n## Community\n\nKeep track of development and community news.\n\n* Follow [@twbootstrap on Twitter](http://twitter.com/twbootstrap).\n* Read and subscribe to [The Official Bootstrap Blog](http://blog.getbootstrap.com).\n* Have a question that's not a feature request or bug report? [Ask on the mailing list.](http://groups.google.com/group/twitter-bootstrap)\n* Chat with fellow Bootstrappers in IRC. On the `irc.freenode.net` server, in the `##twitter-bootstrap` channel.\n\n\n\n\n## Versioning\n\nFor transparency and insight into our release cycle, and for striving to maintain backward compatibility, Bootstrap will be maintained under the Semantic Versioning guidelines as much as possible.\n\nReleases will be numbered with the following format:\n\n`<major>.<minor>.<patch>`\n\nAnd constructed with the following guidelines:\n\n* Breaking backward compatibility bumps the major (and resets the minor and patch)\n* New additions without breaking backward compatibility bumps the minor (and resets the patch)\n* Bug fixes and misc changes bumps the patch\n\nFor more information on SemVer, please visit <http://semver.org/>.\n\n\n\n## Authors\n\n**Mark Otto**\n\n+ <http://twitter.com/mdo>\n+ <http://github.com/mdo>\n\n**Jacob Thornton**\n\n+ <http://twitter.com/fat>\n+ <http://github.com/fat>\n\n\n\n## Copyright and license\n\nCopyright 2013 Twitter, Inc under [the Apache 2.0 license](LICENSE).\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/bower.json",
    "content": "{\n  \"name\": \"bootstrap\",\n  \"version\": \"3.0.3\",\n  \"main\": [\n    \"./dist/js/bootstrap.js\", \n    \"./dist/css/bootstrap.css\", \n    \"./dist/fonts/glyphicons-halflings-regular.eot\",\n    \"./dist/fonts/glyphicons-halflings-regular.svg\",\n    \"./dist/fonts/glyphicons-halflings-regular.ttf\",\n    \"./dist/fonts/glyphicons-halflings-regular.woff\"\n  ],\n  \"ignore\": [\n    \"**/.*\",\n    \"_*\",\n    \"docs-assets\",\n    \"examples\",\n    \"/fonts\",\n    \"js/tests\",\n    \"CNAME\",\n    \"CONTRIBUTING.md\",\n    \"Gruntfile.js\",\n    \"browserstack.json\",\n    \"composer.json\",\n    \"package.json\",\n    \"*.html\"\n  ],\n  \"dependencies\": {\n    \"jquery\": \">= 1.9.0\"\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/dist/css/bootstrap-theme.css",
    "content": "/*!\n * Bootstrap v3.0.3 (http://getbootstrap.com)\n * Copyright 2013 Twitter, Inc.\n * Licensed under http://www.apache.org/licenses/LICENSE-2.0\n */\n\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n\n.btn-default:active,\n.btn-primary:active,\n.btn-success:active,\n.btn-info:active,\n.btn-warning:active,\n.btn-danger:active,\n.btn-default.active,\n.btn-primary.active,\n.btn-success.active,\n.btn-info.active,\n.btn-warning.active,\n.btn-danger.active {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n\n.btn:active,\n.btn.active {\n  background-image: none;\n}\n\n.btn-default {\n  text-shadow: 0 1px 0 #fff;\n  background-image: -webkit-linear-gradient(top, #ffffff 0%, #e0e0e0 100%);\n  background-image: linear-gradient(to bottom, #ffffff 0%, #e0e0e0 100%);\n  background-repeat: repeat-x;\n  border-color: #dbdbdb;\n  border-color: #ccc;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n\n.btn-default:hover,\n.btn-default:focus {\n  background-color: #e0e0e0;\n  background-position: 0 -15px;\n}\n\n.btn-default:active,\n.btn-default.active {\n  background-color: #e0e0e0;\n  border-color: #dbdbdb;\n}\n\n.btn-primary {\n  background-image: -webkit-linear-gradient(top, #428bca 0%, #2d6ca2 100%);\n  background-image: linear-gradient(to bottom, #428bca 0%, #2d6ca2 100%);\n  background-repeat: repeat-x;\n  border-color: #2b669a;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff2d6ca2', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n\n.btn-primary:hover,\n.btn-primary:focus {\n  background-color: #2d6ca2;\n  background-position: 0 -15px;\n}\n\n.btn-primary:active,\n.btn-primary.active {\n  background-color: #2d6ca2;\n  border-color: #2b669a;\n}\n\n.btn-success {\n  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);\n  background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);\n  background-repeat: repeat-x;\n  border-color: #3e8f3e;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n\n.btn-success:hover,\n.btn-success:focus {\n  background-color: #419641;\n  background-position: 0 -15px;\n}\n\n.btn-success:active,\n.btn-success.active {\n  background-color: #419641;\n  border-color: #3e8f3e;\n}\n\n.btn-warning {\n  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);\n  background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);\n  background-repeat: repeat-x;\n  border-color: #e38d13;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n\n.btn-warning:hover,\n.btn-warning:focus {\n  background-color: #eb9316;\n  background-position: 0 -15px;\n}\n\n.btn-warning:active,\n.btn-warning.active {\n  background-color: #eb9316;\n  border-color: #e38d13;\n}\n\n.btn-danger {\n  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);\n  background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);\n  background-repeat: repeat-x;\n  border-color: #b92c28;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n\n.btn-danger:hover,\n.btn-danger:focus {\n  background-color: #c12e2a;\n  background-position: 0 -15px;\n}\n\n.btn-danger:active,\n.btn-danger.active {\n  background-color: #c12e2a;\n  border-color: #b92c28;\n}\n\n.btn-info {\n  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);\n  background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);\n  background-repeat: repeat-x;\n  border-color: #28a4c9;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n\n.btn-info:hover,\n.btn-info:focus {\n  background-color: #2aabd2;\n  background-position: 0 -15px;\n}\n\n.btn-info:active,\n.btn-info.active {\n  background-color: #2aabd2;\n  border-color: #28a4c9;\n}\n\n.thumbnail,\n.img-thumbnail {\n  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n          box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  background-color: #e8e8e8;\n  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n}\n\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  background-color: #357ebd;\n  background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%);\n  background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);\n}\n\n.navbar-default {\n  background-image: -webkit-linear-gradient(top, #ffffff 0%, #f8f8f8 100%);\n  background-image: linear-gradient(to bottom, #ffffff 0%, #f8f8f8 100%);\n  background-repeat: repeat-x;\n  border-radius: 4px;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 1px 5px rgba(0, 0, 0, 0.075);\n}\n\n.navbar-default .navbar-nav > .active > a {\n  background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f3f3f3 100%);\n  background-image: linear-gradient(to bottom, #ebebeb 0%, #f3f3f3 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff3f3f3', GradientType=0);\n  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.075);\n}\n\n.navbar-brand,\n.navbar-nav > li > a {\n  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.25);\n}\n\n.navbar-inverse {\n  background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222222 100%);\n  background-image: linear-gradient(to bottom, #3c3c3c 0%, #222222 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n\n.navbar-inverse .navbar-nav > .active > a {\n  background-image: -webkit-linear-gradient(top, #222222 0%, #282828 100%);\n  background-image: linear-gradient(to bottom, #222222 0%, #282828 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff282828', GradientType=0);\n  -webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n          box-shadow: inset 0 3px 9px rgba(0, 0, 0, 0.25);\n}\n\n.navbar-inverse .navbar-brand,\n.navbar-inverse .navbar-nav > li > a {\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  border-radius: 0;\n}\n\n.alert {\n  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.2);\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.25), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n\n.alert-success {\n  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);\n  background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);\n  background-repeat: repeat-x;\n  border-color: #b2dba1;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);\n}\n\n.alert-info {\n  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);\n  background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);\n  background-repeat: repeat-x;\n  border-color: #9acfea;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);\n}\n\n.alert-warning {\n  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);\n  background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);\n  background-repeat: repeat-x;\n  border-color: #f5e79e;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);\n}\n\n.alert-danger {\n  background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);\n  background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);\n  background-repeat: repeat-x;\n  border-color: #dca7a7;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);\n}\n\n.progress {\n  background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);\n  background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);\n}\n\n.progress-bar {\n  background-image: -webkit-linear-gradient(top, #428bca 0%, #3071a9 100%);\n  background-image: linear-gradient(to bottom, #428bca 0%, #3071a9 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3071a9', GradientType=0);\n}\n\n.progress-bar-success {\n  background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);\n  background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);\n}\n\n.progress-bar-info {\n  background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);\n  background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);\n}\n\n.progress-bar-warning {\n  background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);\n  background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);\n}\n\n.progress-bar-danger {\n  background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);\n  background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);\n}\n\n.list-group {\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n          box-shadow: 0 1px 2px rgba(0, 0, 0, 0.075);\n}\n\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  text-shadow: 0 -1px 0 #3071a9;\n  background-image: -webkit-linear-gradient(top, #428bca 0%, #3278b3 100%);\n  background-image: linear-gradient(to bottom, #428bca 0%, #3278b3 100%);\n  background-repeat: repeat-x;\n  border-color: #3278b3;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff3278b3', GradientType=0);\n}\n\n.panel {\n  -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n          box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n\n.panel-default > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);\n  background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);\n}\n\n.panel-primary > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #428bca 0%, #357ebd 100%);\n  background-image: linear-gradient(to bottom, #428bca 0%, #357ebd 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);\n}\n\n.panel-success > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);\n  background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);\n}\n\n.panel-info > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);\n  background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);\n}\n\n.panel-warning > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);\n  background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);\n}\n\n.panel-danger > .panel-heading {\n  background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);\n  background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);\n}\n\n.well {\n  background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);\n  background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);\n  background-repeat: repeat-x;\n  border-color: #dcdcdc;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);\n  -webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n          box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.05), 0 1px 0 rgba(255, 255, 255, 0.1);\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/dist/css/bootstrap.css",
    "content": "/*!\n * Bootstrap v3.0.3 (http://getbootstrap.com)\n * Copyright 2013 Twitter, Inc.\n * Licensed under http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/*! normalize.css v2.1.3 | MIT License | git.io/normalize */\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nnav,\nsection,\nsummary {\n  display: block;\n}\n\naudio,\ncanvas,\nvideo {\n  display: inline-block;\n}\n\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n\n[hidden],\ntemplate {\n  display: none;\n}\n\nhtml {\n  font-family: sans-serif;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\n\nbody {\n  margin: 0;\n}\n\na {\n  background: transparent;\n}\n\na:focus {\n  outline: thin dotted;\n}\n\na:active,\na:hover {\n  outline: 0;\n}\n\nh1 {\n  margin: 0.67em 0;\n  font-size: 2em;\n}\n\nabbr[title] {\n  border-bottom: 1px dotted;\n}\n\nb,\nstrong {\n  font-weight: bold;\n}\n\ndfn {\n  font-style: italic;\n}\n\nhr {\n  height: 0;\n  -moz-box-sizing: content-box;\n       box-sizing: content-box;\n}\n\nmark {\n  color: #000;\n  background: #ff0;\n}\n\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, serif;\n  font-size: 1em;\n}\n\npre {\n  white-space: pre-wrap;\n}\n\nq {\n  quotes: \"\\201C\" \"\\201D\" \"\\2018\" \"\\2019\";\n}\n\nsmall {\n  font-size: 80%;\n}\n\nsub,\nsup {\n  position: relative;\n  font-size: 75%;\n  line-height: 0;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\nimg {\n  border: 0;\n}\n\nsvg:not(:root) {\n  overflow: hidden;\n}\n\nfigure {\n  margin: 0;\n}\n\nfieldset {\n  padding: 0.35em 0.625em 0.75em;\n  margin: 0 2px;\n  border: 1px solid #c0c0c0;\n}\n\nlegend {\n  padding: 0;\n  border: 0;\n}\n\nbutton,\ninput,\nselect,\ntextarea {\n  margin: 0;\n  font-family: inherit;\n  font-size: 100%;\n}\n\nbutton,\ninput {\n  line-height: normal;\n}\n\nbutton,\nselect {\n  text-transform: none;\n}\n\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  cursor: pointer;\n  -webkit-appearance: button;\n}\n\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  padding: 0;\n  box-sizing: border-box;\n}\n\ninput[type=\"search\"] {\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n  -webkit-appearance: textfield;\n}\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  padding: 0;\n  border: 0;\n}\n\ntextarea {\n  overflow: auto;\n  vertical-align: top;\n}\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\n@media print {\n  * {\n    color: #000 !important;\n    text-shadow: none !important;\n    background: transparent !important;\n    box-shadow: none !important;\n  }\n  a,\n  a:visited {\n    text-decoration: underline;\n  }\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n  a[href^=\"javascript:\"]:after,\n  a[href^=\"#\"]:after {\n    content: \"\";\n  }\n  pre,\n  blockquote {\n    border: 1px solid #999;\n    page-break-inside: avoid;\n  }\n  thead {\n    display: table-header-group;\n  }\n  tr,\n  img {\n    page-break-inside: avoid;\n  }\n  img {\n    max-width: 100% !important;\n  }\n  @page  {\n    margin: 2cm .5cm;\n  }\n  p,\n  h2,\n  h3 {\n    orphans: 3;\n    widows: 3;\n  }\n  h2,\n  h3 {\n    page-break-after: avoid;\n  }\n  select {\n    background: #fff !important;\n  }\n  .navbar {\n    display: none;\n  }\n  .table td,\n  .table th {\n    background-color: #fff !important;\n  }\n  .btn > .caret,\n  .dropup > .btn > .caret {\n    border-top-color: #000 !important;\n  }\n  .label {\n    border: 1px solid #000;\n  }\n  .table {\n    border-collapse: collapse !important;\n  }\n  .table-bordered th,\n  .table-bordered td {\n    border: 1px solid #ddd !important;\n  }\n}\n\n*,\n*:before,\n*:after {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n\nhtml {\n  font-size: 62.5%;\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\nbody {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  line-height: 1.428571429;\n  color: #333333;\n  background-color: #ffffff;\n}\n\ninput,\nbutton,\nselect,\ntextarea {\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\n\na {\n  color: #428bca;\n  text-decoration: none;\n}\n\na:hover,\na:focus {\n  color: #2a6496;\n  text-decoration: underline;\n}\n\na:focus {\n  outline: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n\nimg {\n  vertical-align: middle;\n}\n\n.img-responsive {\n  display: block;\n  height: auto;\n  max-width: 100%;\n}\n\n.img-rounded {\n  border-radius: 6px;\n}\n\n.img-thumbnail {\n  display: inline-block;\n  height: auto;\n  max-width: 100%;\n  padding: 4px;\n  line-height: 1.428571429;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-radius: 4px;\n  -webkit-transition: all 0.2s ease-in-out;\n          transition: all 0.2s ease-in-out;\n}\n\n.img-circle {\n  border-radius: 50%;\n}\n\nhr {\n  margin-top: 20px;\n  margin-bottom: 20px;\n  border: 0;\n  border-top: 1px solid #eeeeee;\n}\n\n.sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  padding: 0;\n  margin: -1px;\n  overflow: hidden;\n  clip: rect(0, 0, 0, 0);\n  border: 0;\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-weight: 500;\n  line-height: 1.1;\n  color: inherit;\n}\n\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n  font-weight: normal;\n  line-height: 1;\n  color: #999999;\n}\n\nh1,\nh2,\nh3 {\n  margin-top: 20px;\n  margin-bottom: 10px;\n}\n\nh1 small,\nh2 small,\nh3 small,\nh1 .small,\nh2 .small,\nh3 .small {\n  font-size: 65%;\n}\n\nh4,\nh5,\nh6 {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n\nh4 small,\nh5 small,\nh6 small,\nh4 .small,\nh5 .small,\nh6 .small {\n  font-size: 75%;\n}\n\nh1,\n.h1 {\n  font-size: 36px;\n}\n\nh2,\n.h2 {\n  font-size: 30px;\n}\n\nh3,\n.h3 {\n  font-size: 24px;\n}\n\nh4,\n.h4 {\n  font-size: 18px;\n}\n\nh5,\n.h5 {\n  font-size: 14px;\n}\n\nh6,\n.h6 {\n  font-size: 12px;\n}\n\np {\n  margin: 0 0 10px;\n}\n\n.lead {\n  margin-bottom: 20px;\n  font-size: 16px;\n  font-weight: 200;\n  line-height: 1.4;\n}\n\n@media (min-width: 768px) {\n  .lead {\n    font-size: 21px;\n  }\n}\n\nsmall,\n.small {\n  font-size: 85%;\n}\n\ncite {\n  font-style: normal;\n}\n\n.text-muted {\n  color: #999999;\n}\n\n.text-primary {\n  color: #428bca;\n}\n\n.text-primary:hover {\n  color: #3071a9;\n}\n\n.text-warning {\n  color: #8a6d3b;\n}\n\n.text-warning:hover {\n  color: #66512c;\n}\n\n.text-danger {\n  color: #a94442;\n}\n\n.text-danger:hover {\n  color: #843534;\n}\n\n.text-success {\n  color: #3c763d;\n}\n\n.text-success:hover {\n  color: #2b542c;\n}\n\n.text-info {\n  color: #31708f;\n}\n\n.text-info:hover {\n  color: #245269;\n}\n\n.text-left {\n  text-align: left;\n}\n\n.text-right {\n  text-align: right;\n}\n\n.text-center {\n  text-align: center;\n}\n\n.page-header {\n  padding-bottom: 9px;\n  margin: 40px 0 20px;\n  border-bottom: 1px solid #eeeeee;\n}\n\nul,\nol {\n  margin-top: 0;\n  margin-bottom: 10px;\n}\n\nul ul,\nol ul,\nul ol,\nol ol {\n  margin-bottom: 0;\n}\n\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n\n.list-inline {\n  padding-left: 0;\n  list-style: none;\n}\n\n.list-inline > li {\n  display: inline-block;\n  padding-right: 5px;\n  padding-left: 5px;\n}\n\n.list-inline > li:first-child {\n  padding-left: 0;\n}\n\ndl {\n  margin-top: 0;\n  margin-bottom: 20px;\n}\n\ndt,\ndd {\n  line-height: 1.428571429;\n}\n\ndt {\n  font-weight: bold;\n}\n\ndd {\n  margin-left: 0;\n}\n\n@media (min-width: 768px) {\n  .dl-horizontal dt {\n    float: left;\n    width: 160px;\n    overflow: hidden;\n    clear: left;\n    text-align: right;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  }\n  .dl-horizontal dd {\n    margin-left: 180px;\n  }\n  .dl-horizontal dd:before,\n  .dl-horizontal dd:after {\n    display: table;\n    content: \" \";\n  }\n  .dl-horizontal dd:after {\n    clear: both;\n  }\n  .dl-horizontal dd:before,\n  .dl-horizontal dd:after {\n    display: table;\n    content: \" \";\n  }\n  .dl-horizontal dd:after {\n    clear: both;\n  }\n}\n\nabbr[title],\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted #999999;\n}\n\n.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\n\nblockquote {\n  padding: 10px 20px;\n  margin: 0 0 20px;\n  border-left: 5px solid #eeeeee;\n}\n\nblockquote p {\n  font-size: 17.5px;\n  font-weight: 300;\n  line-height: 1.25;\n}\n\nblockquote p:last-child {\n  margin-bottom: 0;\n}\n\nblockquote small,\nblockquote .small {\n  display: block;\n  line-height: 1.428571429;\n  color: #999999;\n}\n\nblockquote small:before,\nblockquote .small:before {\n  content: '\\2014 \\00A0';\n}\n\nblockquote.pull-right {\n  padding-right: 15px;\n  padding-left: 0;\n  border-right: 5px solid #eeeeee;\n  border-left: 0;\n}\n\nblockquote.pull-right p,\nblockquote.pull-right small,\nblockquote.pull-right .small {\n  text-align: right;\n}\n\nblockquote.pull-right small:before,\nblockquote.pull-right .small:before {\n  content: '';\n}\n\nblockquote.pull-right small:after,\nblockquote.pull-right .small:after {\n  content: '\\00A0 \\2014';\n}\n\nblockquote:before,\nblockquote:after {\n  content: \"\";\n}\n\naddress {\n  margin-bottom: 20px;\n  font-style: normal;\n  line-height: 1.428571429;\n}\n\ncode,\nkbd,\npre,\nsamp {\n  font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\n\ncode {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #c7254e;\n  white-space: nowrap;\n  background-color: #f9f2f4;\n  border-radius: 4px;\n}\n\npre {\n  display: block;\n  padding: 9.5px;\n  margin: 0 0 10px;\n  font-size: 13px;\n  line-height: 1.428571429;\n  color: #333333;\n  word-break: break-all;\n  word-wrap: break-word;\n  background-color: #f5f5f5;\n  border: 1px solid #cccccc;\n  border-radius: 4px;\n}\n\npre code {\n  padding: 0;\n  font-size: inherit;\n  color: inherit;\n  white-space: pre-wrap;\n  background-color: transparent;\n  border-radius: 0;\n}\n\n.pre-scrollable {\n  max-height: 340px;\n  overflow-y: scroll;\n}\n\n.container {\n  padding-right: 15px;\n  padding-left: 15px;\n  margin-right: auto;\n  margin-left: auto;\n}\n\n.container:before,\n.container:after {\n  display: table;\n  content: \" \";\n}\n\n.container:after {\n  clear: both;\n}\n\n.container:before,\n.container:after {\n  display: table;\n  content: \" \";\n}\n\n.container:after {\n  clear: both;\n}\n\n@media (min-width: 768px) {\n  .container {\n    width: 750px;\n  }\n}\n\n@media (min-width: 992px) {\n  .container {\n    width: 970px;\n  }\n}\n\n@media (min-width: 1200px) {\n  .container {\n    width: 1170px;\n  }\n}\n\n.row {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n\n.row:before,\n.row:after {\n  display: table;\n  content: \" \";\n}\n\n.row:after {\n  clear: both;\n}\n\n.row:before,\n.row:after {\n  display: table;\n  content: \" \";\n}\n\n.row:after {\n  clear: both;\n}\n\n.col-xs-1,\n.col-sm-1,\n.col-md-1,\n.col-lg-1,\n.col-xs-2,\n.col-sm-2,\n.col-md-2,\n.col-lg-2,\n.col-xs-3,\n.col-sm-3,\n.col-md-3,\n.col-lg-3,\n.col-xs-4,\n.col-sm-4,\n.col-md-4,\n.col-lg-4,\n.col-xs-5,\n.col-sm-5,\n.col-md-5,\n.col-lg-5,\n.col-xs-6,\n.col-sm-6,\n.col-md-6,\n.col-lg-6,\n.col-xs-7,\n.col-sm-7,\n.col-md-7,\n.col-lg-7,\n.col-xs-8,\n.col-sm-8,\n.col-md-8,\n.col-lg-8,\n.col-xs-9,\n.col-sm-9,\n.col-md-9,\n.col-lg-9,\n.col-xs-10,\n.col-sm-10,\n.col-md-10,\n.col-lg-10,\n.col-xs-11,\n.col-sm-11,\n.col-md-11,\n.col-lg-11,\n.col-xs-12,\n.col-sm-12,\n.col-md-12,\n.col-lg-12 {\n  position: relative;\n  min-height: 1px;\n  padding-right: 15px;\n  padding-left: 15px;\n}\n\n.col-xs-1,\n.col-xs-2,\n.col-xs-3,\n.col-xs-4,\n.col-xs-5,\n.col-xs-6,\n.col-xs-7,\n.col-xs-8,\n.col-xs-9,\n.col-xs-10,\n.col-xs-11,\n.col-xs-12 {\n  float: left;\n}\n\n.col-xs-12 {\n  width: 100%;\n}\n\n.col-xs-11 {\n  width: 91.66666666666666%;\n}\n\n.col-xs-10 {\n  width: 83.33333333333334%;\n}\n\n.col-xs-9 {\n  width: 75%;\n}\n\n.col-xs-8 {\n  width: 66.66666666666666%;\n}\n\n.col-xs-7 {\n  width: 58.333333333333336%;\n}\n\n.col-xs-6 {\n  width: 50%;\n}\n\n.col-xs-5 {\n  width: 41.66666666666667%;\n}\n\n.col-xs-4 {\n  width: 33.33333333333333%;\n}\n\n.col-xs-3 {\n  width: 25%;\n}\n\n.col-xs-2 {\n  width: 16.666666666666664%;\n}\n\n.col-xs-1 {\n  width: 8.333333333333332%;\n}\n\n.col-xs-pull-12 {\n  right: 100%;\n}\n\n.col-xs-pull-11 {\n  right: 91.66666666666666%;\n}\n\n.col-xs-pull-10 {\n  right: 83.33333333333334%;\n}\n\n.col-xs-pull-9 {\n  right: 75%;\n}\n\n.col-xs-pull-8 {\n  right: 66.66666666666666%;\n}\n\n.col-xs-pull-7 {\n  right: 58.333333333333336%;\n}\n\n.col-xs-pull-6 {\n  right: 50%;\n}\n\n.col-xs-pull-5 {\n  right: 41.66666666666667%;\n}\n\n.col-xs-pull-4 {\n  right: 33.33333333333333%;\n}\n\n.col-xs-pull-3 {\n  right: 25%;\n}\n\n.col-xs-pull-2 {\n  right: 16.666666666666664%;\n}\n\n.col-xs-pull-1 {\n  right: 8.333333333333332%;\n}\n\n.col-xs-pull-0 {\n  right: 0;\n}\n\n.col-xs-push-12 {\n  left: 100%;\n}\n\n.col-xs-push-11 {\n  left: 91.66666666666666%;\n}\n\n.col-xs-push-10 {\n  left: 83.33333333333334%;\n}\n\n.col-xs-push-9 {\n  left: 75%;\n}\n\n.col-xs-push-8 {\n  left: 66.66666666666666%;\n}\n\n.col-xs-push-7 {\n  left: 58.333333333333336%;\n}\n\n.col-xs-push-6 {\n  left: 50%;\n}\n\n.col-xs-push-5 {\n  left: 41.66666666666667%;\n}\n\n.col-xs-push-4 {\n  left: 33.33333333333333%;\n}\n\n.col-xs-push-3 {\n  left: 25%;\n}\n\n.col-xs-push-2 {\n  left: 16.666666666666664%;\n}\n\n.col-xs-push-1 {\n  left: 8.333333333333332%;\n}\n\n.col-xs-push-0 {\n  left: 0;\n}\n\n.col-xs-offset-12 {\n  margin-left: 100%;\n}\n\n.col-xs-offset-11 {\n  margin-left: 91.66666666666666%;\n}\n\n.col-xs-offset-10 {\n  margin-left: 83.33333333333334%;\n}\n\n.col-xs-offset-9 {\n  margin-left: 75%;\n}\n\n.col-xs-offset-8 {\n  margin-left: 66.66666666666666%;\n}\n\n.col-xs-offset-7 {\n  margin-left: 58.333333333333336%;\n}\n\n.col-xs-offset-6 {\n  margin-left: 50%;\n}\n\n.col-xs-offset-5 {\n  margin-left: 41.66666666666667%;\n}\n\n.col-xs-offset-4 {\n  margin-left: 33.33333333333333%;\n}\n\n.col-xs-offset-3 {\n  margin-left: 25%;\n}\n\n.col-xs-offset-2 {\n  margin-left: 16.666666666666664%;\n}\n\n.col-xs-offset-1 {\n  margin-left: 8.333333333333332%;\n}\n\n.col-xs-offset-0 {\n  margin-left: 0;\n}\n\n@media (min-width: 768px) {\n  .col-sm-1,\n  .col-sm-2,\n  .col-sm-3,\n  .col-sm-4,\n  .col-sm-5,\n  .col-sm-6,\n  .col-sm-7,\n  .col-sm-8,\n  .col-sm-9,\n  .col-sm-10,\n  .col-sm-11,\n  .col-sm-12 {\n    float: left;\n  }\n  .col-sm-12 {\n    width: 100%;\n  }\n  .col-sm-11 {\n    width: 91.66666666666666%;\n  }\n  .col-sm-10 {\n    width: 83.33333333333334%;\n  }\n  .col-sm-9 {\n    width: 75%;\n  }\n  .col-sm-8 {\n    width: 66.66666666666666%;\n  }\n  .col-sm-7 {\n    width: 58.333333333333336%;\n  }\n  .col-sm-6 {\n    width: 50%;\n  }\n  .col-sm-5 {\n    width: 41.66666666666667%;\n  }\n  .col-sm-4 {\n    width: 33.33333333333333%;\n  }\n  .col-sm-3 {\n    width: 25%;\n  }\n  .col-sm-2 {\n    width: 16.666666666666664%;\n  }\n  .col-sm-1 {\n    width: 8.333333333333332%;\n  }\n  .col-sm-pull-12 {\n    right: 100%;\n  }\n  .col-sm-pull-11 {\n    right: 91.66666666666666%;\n  }\n  .col-sm-pull-10 {\n    right: 83.33333333333334%;\n  }\n  .col-sm-pull-9 {\n    right: 75%;\n  }\n  .col-sm-pull-8 {\n    right: 66.66666666666666%;\n  }\n  .col-sm-pull-7 {\n    right: 58.333333333333336%;\n  }\n  .col-sm-pull-6 {\n    right: 50%;\n  }\n  .col-sm-pull-5 {\n    right: 41.66666666666667%;\n  }\n  .col-sm-pull-4 {\n    right: 33.33333333333333%;\n  }\n  .col-sm-pull-3 {\n    right: 25%;\n  }\n  .col-sm-pull-2 {\n    right: 16.666666666666664%;\n  }\n  .col-sm-pull-1 {\n    right: 8.333333333333332%;\n  }\n  .col-sm-pull-0 {\n    right: 0;\n  }\n  .col-sm-push-12 {\n    left: 100%;\n  }\n  .col-sm-push-11 {\n    left: 91.66666666666666%;\n  }\n  .col-sm-push-10 {\n    left: 83.33333333333334%;\n  }\n  .col-sm-push-9 {\n    left: 75%;\n  }\n  .col-sm-push-8 {\n    left: 66.66666666666666%;\n  }\n  .col-sm-push-7 {\n    left: 58.333333333333336%;\n  }\n  .col-sm-push-6 {\n    left: 50%;\n  }\n  .col-sm-push-5 {\n    left: 41.66666666666667%;\n  }\n  .col-sm-push-4 {\n    left: 33.33333333333333%;\n  }\n  .col-sm-push-3 {\n    left: 25%;\n  }\n  .col-sm-push-2 {\n    left: 16.666666666666664%;\n  }\n  .col-sm-push-1 {\n    left: 8.333333333333332%;\n  }\n  .col-sm-push-0 {\n    left: 0;\n  }\n  .col-sm-offset-12 {\n    margin-left: 100%;\n  }\n  .col-sm-offset-11 {\n    margin-left: 91.66666666666666%;\n  }\n  .col-sm-offset-10 {\n    margin-left: 83.33333333333334%;\n  }\n  .col-sm-offset-9 {\n    margin-left: 75%;\n  }\n  .col-sm-offset-8 {\n    margin-left: 66.66666666666666%;\n  }\n  .col-sm-offset-7 {\n    margin-left: 58.333333333333336%;\n  }\n  .col-sm-offset-6 {\n    margin-left: 50%;\n  }\n  .col-sm-offset-5 {\n    margin-left: 41.66666666666667%;\n  }\n  .col-sm-offset-4 {\n    margin-left: 33.33333333333333%;\n  }\n  .col-sm-offset-3 {\n    margin-left: 25%;\n  }\n  .col-sm-offset-2 {\n    margin-left: 16.666666666666664%;\n  }\n  .col-sm-offset-1 {\n    margin-left: 8.333333333333332%;\n  }\n  .col-sm-offset-0 {\n    margin-left: 0;\n  }\n}\n\n@media (min-width: 992px) {\n  .col-md-1,\n  .col-md-2,\n  .col-md-3,\n  .col-md-4,\n  .col-md-5,\n  .col-md-6,\n  .col-md-7,\n  .col-md-8,\n  .col-md-9,\n  .col-md-10,\n  .col-md-11,\n  .col-md-12 {\n    float: left;\n  }\n  .col-md-12 {\n    width: 100%;\n  }\n  .col-md-11 {\n    width: 91.66666666666666%;\n  }\n  .col-md-10 {\n    width: 83.33333333333334%;\n  }\n  .col-md-9 {\n    width: 75%;\n  }\n  .col-md-8 {\n    width: 66.66666666666666%;\n  }\n  .col-md-7 {\n    width: 58.333333333333336%;\n  }\n  .col-md-6 {\n    width: 50%;\n  }\n  .col-md-5 {\n    width: 41.66666666666667%;\n  }\n  .col-md-4 {\n    width: 33.33333333333333%;\n  }\n  .col-md-3 {\n    width: 25%;\n  }\n  .col-md-2 {\n    width: 16.666666666666664%;\n  }\n  .col-md-1 {\n    width: 8.333333333333332%;\n  }\n  .col-md-pull-12 {\n    right: 100%;\n  }\n  .col-md-pull-11 {\n    right: 91.66666666666666%;\n  }\n  .col-md-pull-10 {\n    right: 83.33333333333334%;\n  }\n  .col-md-pull-9 {\n    right: 75%;\n  }\n  .col-md-pull-8 {\n    right: 66.66666666666666%;\n  }\n  .col-md-pull-7 {\n    right: 58.333333333333336%;\n  }\n  .col-md-pull-6 {\n    right: 50%;\n  }\n  .col-md-pull-5 {\n    right: 41.66666666666667%;\n  }\n  .col-md-pull-4 {\n    right: 33.33333333333333%;\n  }\n  .col-md-pull-3 {\n    right: 25%;\n  }\n  .col-md-pull-2 {\n    right: 16.666666666666664%;\n  }\n  .col-md-pull-1 {\n    right: 8.333333333333332%;\n  }\n  .col-md-pull-0 {\n    right: 0;\n  }\n  .col-md-push-12 {\n    left: 100%;\n  }\n  .col-md-push-11 {\n    left: 91.66666666666666%;\n  }\n  .col-md-push-10 {\n    left: 83.33333333333334%;\n  }\n  .col-md-push-9 {\n    left: 75%;\n  }\n  .col-md-push-8 {\n    left: 66.66666666666666%;\n  }\n  .col-md-push-7 {\n    left: 58.333333333333336%;\n  }\n  .col-md-push-6 {\n    left: 50%;\n  }\n  .col-md-push-5 {\n    left: 41.66666666666667%;\n  }\n  .col-md-push-4 {\n    left: 33.33333333333333%;\n  }\n  .col-md-push-3 {\n    left: 25%;\n  }\n  .col-md-push-2 {\n    left: 16.666666666666664%;\n  }\n  .col-md-push-1 {\n    left: 8.333333333333332%;\n  }\n  .col-md-push-0 {\n    left: 0;\n  }\n  .col-md-offset-12 {\n    margin-left: 100%;\n  }\n  .col-md-offset-11 {\n    margin-left: 91.66666666666666%;\n  }\n  .col-md-offset-10 {\n    margin-left: 83.33333333333334%;\n  }\n  .col-md-offset-9 {\n    margin-left: 75%;\n  }\n  .col-md-offset-8 {\n    margin-left: 66.66666666666666%;\n  }\n  .col-md-offset-7 {\n    margin-left: 58.333333333333336%;\n  }\n  .col-md-offset-6 {\n    margin-left: 50%;\n  }\n  .col-md-offset-5 {\n    margin-left: 41.66666666666667%;\n  }\n  .col-md-offset-4 {\n    margin-left: 33.33333333333333%;\n  }\n  .col-md-offset-3 {\n    margin-left: 25%;\n  }\n  .col-md-offset-2 {\n    margin-left: 16.666666666666664%;\n  }\n  .col-md-offset-1 {\n    margin-left: 8.333333333333332%;\n  }\n  .col-md-offset-0 {\n    margin-left: 0;\n  }\n}\n\n@media (min-width: 1200px) {\n  .col-lg-1,\n  .col-lg-2,\n  .col-lg-3,\n  .col-lg-4,\n  .col-lg-5,\n  .col-lg-6,\n  .col-lg-7,\n  .col-lg-8,\n  .col-lg-9,\n  .col-lg-10,\n  .col-lg-11,\n  .col-lg-12 {\n    float: left;\n  }\n  .col-lg-12 {\n    width: 100%;\n  }\n  .col-lg-11 {\n    width: 91.66666666666666%;\n  }\n  .col-lg-10 {\n    width: 83.33333333333334%;\n  }\n  .col-lg-9 {\n    width: 75%;\n  }\n  .col-lg-8 {\n    width: 66.66666666666666%;\n  }\n  .col-lg-7 {\n    width: 58.333333333333336%;\n  }\n  .col-lg-6 {\n    width: 50%;\n  }\n  .col-lg-5 {\n    width: 41.66666666666667%;\n  }\n  .col-lg-4 {\n    width: 33.33333333333333%;\n  }\n  .col-lg-3 {\n    width: 25%;\n  }\n  .col-lg-2 {\n    width: 16.666666666666664%;\n  }\n  .col-lg-1 {\n    width: 8.333333333333332%;\n  }\n  .col-lg-pull-12 {\n    right: 100%;\n  }\n  .col-lg-pull-11 {\n    right: 91.66666666666666%;\n  }\n  .col-lg-pull-10 {\n    right: 83.33333333333334%;\n  }\n  .col-lg-pull-9 {\n    right: 75%;\n  }\n  .col-lg-pull-8 {\n    right: 66.66666666666666%;\n  }\n  .col-lg-pull-7 {\n    right: 58.333333333333336%;\n  }\n  .col-lg-pull-6 {\n    right: 50%;\n  }\n  .col-lg-pull-5 {\n    right: 41.66666666666667%;\n  }\n  .col-lg-pull-4 {\n    right: 33.33333333333333%;\n  }\n  .col-lg-pull-3 {\n    right: 25%;\n  }\n  .col-lg-pull-2 {\n    right: 16.666666666666664%;\n  }\n  .col-lg-pull-1 {\n    right: 8.333333333333332%;\n  }\n  .col-lg-pull-0 {\n    right: 0;\n  }\n  .col-lg-push-12 {\n    left: 100%;\n  }\n  .col-lg-push-11 {\n    left: 91.66666666666666%;\n  }\n  .col-lg-push-10 {\n    left: 83.33333333333334%;\n  }\n  .col-lg-push-9 {\n    left: 75%;\n  }\n  .col-lg-push-8 {\n    left: 66.66666666666666%;\n  }\n  .col-lg-push-7 {\n    left: 58.333333333333336%;\n  }\n  .col-lg-push-6 {\n    left: 50%;\n  }\n  .col-lg-push-5 {\n    left: 41.66666666666667%;\n  }\n  .col-lg-push-4 {\n    left: 33.33333333333333%;\n  }\n  .col-lg-push-3 {\n    left: 25%;\n  }\n  .col-lg-push-2 {\n    left: 16.666666666666664%;\n  }\n  .col-lg-push-1 {\n    left: 8.333333333333332%;\n  }\n  .col-lg-push-0 {\n    left: 0;\n  }\n  .col-lg-offset-12 {\n    margin-left: 100%;\n  }\n  .col-lg-offset-11 {\n    margin-left: 91.66666666666666%;\n  }\n  .col-lg-offset-10 {\n    margin-left: 83.33333333333334%;\n  }\n  .col-lg-offset-9 {\n    margin-left: 75%;\n  }\n  .col-lg-offset-8 {\n    margin-left: 66.66666666666666%;\n  }\n  .col-lg-offset-7 {\n    margin-left: 58.333333333333336%;\n  }\n  .col-lg-offset-6 {\n    margin-left: 50%;\n  }\n  .col-lg-offset-5 {\n    margin-left: 41.66666666666667%;\n  }\n  .col-lg-offset-4 {\n    margin-left: 33.33333333333333%;\n  }\n  .col-lg-offset-3 {\n    margin-left: 25%;\n  }\n  .col-lg-offset-2 {\n    margin-left: 16.666666666666664%;\n  }\n  .col-lg-offset-1 {\n    margin-left: 8.333333333333332%;\n  }\n  .col-lg-offset-0 {\n    margin-left: 0;\n  }\n}\n\ntable {\n  max-width: 100%;\n  background-color: transparent;\n}\n\nth {\n  text-align: left;\n}\n\n.table {\n  width: 100%;\n  margin-bottom: 20px;\n}\n\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n  padding: 8px;\n  line-height: 1.428571429;\n  vertical-align: top;\n  border-top: 1px solid #dddddd;\n}\n\n.table > thead > tr > th {\n  vertical-align: bottom;\n  border-bottom: 2px solid #dddddd;\n}\n\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n  border-top: 0;\n}\n\n.table > tbody + tbody {\n  border-top: 2px solid #dddddd;\n}\n\n.table .table {\n  background-color: #ffffff;\n}\n\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n  padding: 5px;\n}\n\n.table-bordered {\n  border: 1px solid #dddddd;\n}\n\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n  border: 1px solid #dddddd;\n}\n\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n  border-bottom-width: 2px;\n}\n\n.table-striped > tbody > tr:nth-child(odd) > td,\n.table-striped > tbody > tr:nth-child(odd) > th {\n  background-color: #f9f9f9;\n}\n\n.table-hover > tbody > tr:hover > td,\n.table-hover > tbody > tr:hover > th {\n  background-color: #f5f5f5;\n}\n\ntable col[class*=\"col-\"] {\n  position: static;\n  display: table-column;\n  float: none;\n}\n\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n  display: table-cell;\n  float: none;\n}\n\n.table > thead > tr > .active,\n.table > tbody > tr > .active,\n.table > tfoot > tr > .active,\n.table > thead > .active > td,\n.table > tbody > .active > td,\n.table > tfoot > .active > td,\n.table > thead > .active > th,\n.table > tbody > .active > th,\n.table > tfoot > .active > th {\n  background-color: #f5f5f5;\n}\n\n.table-hover > tbody > tr > .active:hover,\n.table-hover > tbody > .active:hover > td,\n.table-hover > tbody > .active:hover > th {\n  background-color: #e8e8e8;\n}\n\n.table > thead > tr > .success,\n.table > tbody > tr > .success,\n.table > tfoot > tr > .success,\n.table > thead > .success > td,\n.table > tbody > .success > td,\n.table > tfoot > .success > td,\n.table > thead > .success > th,\n.table > tbody > .success > th,\n.table > tfoot > .success > th {\n  background-color: #dff0d8;\n}\n\n.table-hover > tbody > tr > .success:hover,\n.table-hover > tbody > .success:hover > td,\n.table-hover > tbody > .success:hover > th {\n  background-color: #d0e9c6;\n}\n\n.table > thead > tr > .danger,\n.table > tbody > tr > .danger,\n.table > tfoot > tr > .danger,\n.table > thead > .danger > td,\n.table > tbody > .danger > td,\n.table > tfoot > .danger > td,\n.table > thead > .danger > th,\n.table > tbody > .danger > th,\n.table > tfoot > .danger > th {\n  background-color: #f2dede;\n}\n\n.table-hover > tbody > tr > .danger:hover,\n.table-hover > tbody > .danger:hover > td,\n.table-hover > tbody > .danger:hover > th {\n  background-color: #ebcccc;\n}\n\n.table > thead > tr > .warning,\n.table > tbody > tr > .warning,\n.table > tfoot > tr > .warning,\n.table > thead > .warning > td,\n.table > tbody > .warning > td,\n.table > tfoot > .warning > td,\n.table > thead > .warning > th,\n.table > tbody > .warning > th,\n.table > tfoot > .warning > th {\n  background-color: #fcf8e3;\n}\n\n.table-hover > tbody > tr > .warning:hover,\n.table-hover > tbody > .warning:hover > td,\n.table-hover > tbody > .warning:hover > th {\n  background-color: #faf2cc;\n}\n\n@media (max-width: 767px) {\n  .table-responsive {\n    width: 100%;\n    margin-bottom: 15px;\n    overflow-x: scroll;\n    overflow-y: hidden;\n    border: 1px solid #dddddd;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    -webkit-overflow-scrolling: touch;\n  }\n  .table-responsive > .table {\n    margin-bottom: 0;\n  }\n  .table-responsive > .table > thead > tr > th,\n  .table-responsive > .table > tbody > tr > th,\n  .table-responsive > .table > tfoot > tr > th,\n  .table-responsive > .table > thead > tr > td,\n  .table-responsive > .table > tbody > tr > td,\n  .table-responsive > .table > tfoot > tr > td {\n    white-space: nowrap;\n  }\n  .table-responsive > .table-bordered {\n    border: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:first-child,\n  .table-responsive > .table-bordered > tbody > tr > th:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n  .table-responsive > .table-bordered > thead > tr > td:first-child,\n  .table-responsive > .table-bordered > tbody > tr > td:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n    border-left: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:last-child,\n  .table-responsive > .table-bordered > tbody > tr > th:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n  .table-responsive > .table-bordered > thead > tr > td:last-child,\n  .table-responsive > .table-bordered > tbody > tr > td:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n    border-right: 0;\n  }\n  .table-responsive > .table-bordered > tbody > tr:last-child > th,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n  .table-responsive > .table-bordered > tbody > tr:last-child > td,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n    border-bottom: 0;\n  }\n}\n\nfieldset {\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\n\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 20px;\n  font-size: 21px;\n  line-height: inherit;\n  color: #333333;\n  border: 0;\n  border-bottom: 1px solid #e5e5e5;\n}\n\nlabel {\n  display: inline-block;\n  margin-bottom: 5px;\n  font-weight: bold;\n}\n\ninput[type=\"search\"] {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9;\n  /* IE8-9 */\n\n  line-height: normal;\n}\n\ninput[type=\"file\"] {\n  display: block;\n}\n\nselect[multiple],\nselect[size] {\n  height: auto;\n}\n\nselect optgroup {\n  font-family: inherit;\n  font-size: inherit;\n  font-style: inherit;\n}\n\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  outline: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n\ninput[type=\"number\"]::-webkit-outer-spin-button,\ninput[type=\"number\"]::-webkit-inner-spin-button {\n  height: auto;\n}\n\noutput {\n  display: block;\n  padding-top: 7px;\n  font-size: 14px;\n  line-height: 1.428571429;\n  color: #555555;\n  vertical-align: middle;\n}\n\n.form-control {\n  display: block;\n  width: 100%;\n  height: 34px;\n  padding: 6px 12px;\n  font-size: 14px;\n  line-height: 1.428571429;\n  color: #555555;\n  vertical-align: middle;\n  background-color: #ffffff;\n  background-image: none;\n  border: 1px solid #cccccc;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  -webkit-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;\n          transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;\n}\n\n.form-control:focus {\n  border-color: #66afe9;\n  outline: 0;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n\n.form-control:-moz-placeholder {\n  color: #999999;\n}\n\n.form-control::-moz-placeholder {\n  color: #999999;\n  opacity: 1;\n}\n\n.form-control:-ms-input-placeholder {\n  color: #999999;\n}\n\n.form-control::-webkit-input-placeholder {\n  color: #999999;\n}\n\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n  cursor: not-allowed;\n  background-color: #eeeeee;\n}\n\ntextarea.form-control {\n  height: auto;\n}\n\n.form-group {\n  margin-bottom: 15px;\n}\n\n.radio,\n.checkbox {\n  display: block;\n  min-height: 20px;\n  padding-left: 20px;\n  margin-top: 10px;\n  margin-bottom: 10px;\n  vertical-align: middle;\n}\n\n.radio label,\n.checkbox label {\n  display: inline;\n  margin-bottom: 0;\n  font-weight: normal;\n  cursor: pointer;\n}\n\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  float: left;\n  margin-left: -20px;\n}\n\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px;\n}\n\n.radio-inline,\n.checkbox-inline {\n  display: inline-block;\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n  vertical-align: middle;\n  cursor: pointer;\n}\n\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px;\n}\n\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\n.radio[disabled],\n.radio-inline[disabled],\n.checkbox[disabled],\n.checkbox-inline[disabled],\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"],\nfieldset[disabled] .radio,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox,\nfieldset[disabled] .checkbox-inline {\n  cursor: not-allowed;\n}\n\n.input-sm {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n\nselect.input-sm {\n  height: 30px;\n  line-height: 30px;\n}\n\ntextarea.input-sm {\n  height: auto;\n}\n\n.input-lg {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.33;\n  border-radius: 6px;\n}\n\nselect.input-lg {\n  height: 46px;\n  line-height: 46px;\n}\n\ntextarea.input-lg {\n  height: auto;\n}\n\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline {\n  color: #8a6d3b;\n}\n\n.has-warning .form-control {\n  border-color: #8a6d3b;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n\n.has-warning .form-control:focus {\n  border-color: #66512c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #c0a16b;\n}\n\n.has-warning .input-group-addon {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #8a6d3b;\n}\n\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline {\n  color: #a94442;\n}\n\n.has-error .form-control {\n  border-color: #a94442;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n\n.has-error .form-control:focus {\n  border-color: #843534;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #ce8483;\n}\n\n.has-error .input-group-addon {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #a94442;\n}\n\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline {\n  color: #3c763d;\n}\n\n.has-success .form-control {\n  border-color: #3c763d;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n\n.has-success .form-control:focus {\n  border-color: #2b542c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #67b168;\n}\n\n.has-success .input-group-addon {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #3c763d;\n}\n\n.form-control-static {\n  margin-bottom: 0;\n}\n\n.help-block {\n  display: block;\n  margin-top: 5px;\n  margin-bottom: 10px;\n  color: #737373;\n}\n\n@media (min-width: 768px) {\n  .form-inline .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .form-control {\n    display: inline-block;\n  }\n  .form-inline select.form-control {\n    width: auto;\n  }\n  .form-inline .radio,\n  .form-inline .checkbox {\n    display: inline-block;\n    padding-left: 0;\n    margin-top: 0;\n    margin-bottom: 0;\n  }\n  .form-inline .radio input[type=\"radio\"],\n  .form-inline .checkbox input[type=\"checkbox\"] {\n    float: none;\n    margin-left: 0;\n  }\n}\n\n.form-horizontal .control-label,\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n  padding-top: 7px;\n  margin-top: 0;\n  margin-bottom: 0;\n}\n\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n  min-height: 27px;\n}\n\n.form-horizontal .form-group {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after {\n  display: table;\n  content: \" \";\n}\n\n.form-horizontal .form-group:after {\n  clear: both;\n}\n\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after {\n  display: table;\n  content: \" \";\n}\n\n.form-horizontal .form-group:after {\n  clear: both;\n}\n\n.form-horizontal .form-control-static {\n  padding-top: 7px;\n}\n\n@media (min-width: 768px) {\n  .form-horizontal .control-label {\n    text-align: right;\n  }\n}\n\n.btn {\n  display: inline-block;\n  padding: 6px 12px;\n  margin-bottom: 0;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1.428571429;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  cursor: pointer;\n  background-image: none;\n  border: 1px solid transparent;\n  border-radius: 4px;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n       -o-user-select: none;\n          user-select: none;\n}\n\n.btn:focus {\n  outline: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n\n.btn:hover,\n.btn:focus {\n  color: #333333;\n  text-decoration: none;\n}\n\n.btn:active,\n.btn.active {\n  background-image: none;\n  outline: 0;\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n  pointer-events: none;\n  cursor: not-allowed;\n  opacity: 0.65;\n  filter: alpha(opacity=65);\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n\n.btn-default {\n  color: #333333;\n  background-color: #ffffff;\n  border-color: #cccccc;\n}\n\n.btn-default:hover,\n.btn-default:focus,\n.btn-default:active,\n.btn-default.active,\n.open .dropdown-toggle.btn-default {\n  color: #333333;\n  background-color: #ebebeb;\n  border-color: #adadad;\n}\n\n.btn-default:active,\n.btn-default.active,\n.open .dropdown-toggle.btn-default {\n  background-image: none;\n}\n\n.btn-default.disabled,\n.btn-default[disabled],\nfieldset[disabled] .btn-default,\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled:active,\n.btn-default[disabled]:active,\nfieldset[disabled] .btn-default:active,\n.btn-default.disabled.active,\n.btn-default[disabled].active,\nfieldset[disabled] .btn-default.active {\n  background-color: #ffffff;\n  border-color: #cccccc;\n}\n\n.btn-default .badge {\n  color: #ffffff;\n  background-color: #fff;\n}\n\n.btn-primary {\n  color: #ffffff;\n  background-color: #428bca;\n  border-color: #357ebd;\n}\n\n.btn-primary:hover,\n.btn-primary:focus,\n.btn-primary:active,\n.btn-primary.active,\n.open .dropdown-toggle.btn-primary {\n  color: #ffffff;\n  background-color: #3276b1;\n  border-color: #285e8e;\n}\n\n.btn-primary:active,\n.btn-primary.active,\n.open .dropdown-toggle.btn-primary {\n  background-image: none;\n}\n\n.btn-primary.disabled,\n.btn-primary[disabled],\nfieldset[disabled] .btn-primary,\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n  background-color: #428bca;\n  border-color: #357ebd;\n}\n\n.btn-primary .badge {\n  color: #428bca;\n  background-color: #fff;\n}\n\n.btn-warning {\n  color: #ffffff;\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n\n.btn-warning:hover,\n.btn-warning:focus,\n.btn-warning:active,\n.btn-warning.active,\n.open .dropdown-toggle.btn-warning {\n  color: #ffffff;\n  background-color: #ed9c28;\n  border-color: #d58512;\n}\n\n.btn-warning:active,\n.btn-warning.active,\n.open .dropdown-toggle.btn-warning {\n  background-image: none;\n}\n\n.btn-warning.disabled,\n.btn-warning[disabled],\nfieldset[disabled] .btn-warning,\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n\n.btn-warning .badge {\n  color: #f0ad4e;\n  background-color: #fff;\n}\n\n.btn-danger {\n  color: #ffffff;\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n\n.btn-danger:hover,\n.btn-danger:focus,\n.btn-danger:active,\n.btn-danger.active,\n.open .dropdown-toggle.btn-danger {\n  color: #ffffff;\n  background-color: #d2322d;\n  border-color: #ac2925;\n}\n\n.btn-danger:active,\n.btn-danger.active,\n.open .dropdown-toggle.btn-danger {\n  background-image: none;\n}\n\n.btn-danger.disabled,\n.btn-danger[disabled],\nfieldset[disabled] .btn-danger,\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n\n.btn-danger .badge {\n  color: #d9534f;\n  background-color: #fff;\n}\n\n.btn-success {\n  color: #ffffff;\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n\n.btn-success:hover,\n.btn-success:focus,\n.btn-success:active,\n.btn-success.active,\n.open .dropdown-toggle.btn-success {\n  color: #ffffff;\n  background-color: #47a447;\n  border-color: #398439;\n}\n\n.btn-success:active,\n.btn-success.active,\n.open .dropdown-toggle.btn-success {\n  background-image: none;\n}\n\n.btn-success.disabled,\n.btn-success[disabled],\nfieldset[disabled] .btn-success,\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n\n.btn-success .badge {\n  color: #5cb85c;\n  background-color: #fff;\n}\n\n.btn-info {\n  color: #ffffff;\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n\n.btn-info:hover,\n.btn-info:focus,\n.btn-info:active,\n.btn-info.active,\n.open .dropdown-toggle.btn-info {\n  color: #ffffff;\n  background-color: #39b3d7;\n  border-color: #269abc;\n}\n\n.btn-info:active,\n.btn-info.active,\n.open .dropdown-toggle.btn-info {\n  background-image: none;\n}\n\n.btn-info.disabled,\n.btn-info[disabled],\nfieldset[disabled] .btn-info,\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n\n.btn-info .badge {\n  color: #5bc0de;\n  background-color: #fff;\n}\n\n.btn-link {\n  font-weight: normal;\n  color: #428bca;\n  cursor: pointer;\n  border-radius: 0;\n}\n\n.btn-link,\n.btn-link:active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n  background-color: transparent;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n  border-color: transparent;\n}\n\n.btn-link:hover,\n.btn-link:focus {\n  color: #2a6496;\n  text-decoration: underline;\n  background-color: transparent;\n}\n\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n  color: #999999;\n  text-decoration: none;\n}\n\n.btn-lg {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.33;\n  border-radius: 6px;\n}\n\n.btn-sm {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n\n.btn-xs {\n  padding: 1px 5px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n\n.btn-block {\n  display: block;\n  width: 100%;\n  padding-right: 0;\n  padding-left: 0;\n}\n\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\n\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n  width: 100%;\n}\n\n.fade {\n  opacity: 0;\n  -webkit-transition: opacity 0.15s linear;\n          transition: opacity 0.15s linear;\n}\n\n.fade.in {\n  opacity: 1;\n}\n\n.collapse {\n  display: none;\n}\n\n.collapse.in {\n  display: block;\n}\n\n.collapsing {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  -webkit-transition: height 0.35s ease;\n          transition: height 0.35s ease;\n}\n\n@font-face {\n  font-family: 'Glyphicons Halflings';\n  src: url('../fonts/glyphicons-halflings-regular.eot');\n  src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons-halflingsregular') format('svg');\n}\n\n.glyphicon {\n  position: relative;\n  top: 1px;\n  display: inline-block;\n  font-family: 'Glyphicons Halflings';\n  -webkit-font-smoothing: antialiased;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n  -moz-osx-font-smoothing: grayscale;\n}\n\n.glyphicon:empty {\n  width: 1em;\n}\n\n.glyphicon-asterisk:before {\n  content: \"\\2a\";\n}\n\n.glyphicon-plus:before {\n  content: \"\\2b\";\n}\n\n.glyphicon-euro:before {\n  content: \"\\20ac\";\n}\n\n.glyphicon-minus:before {\n  content: \"\\2212\";\n}\n\n.glyphicon-cloud:before {\n  content: \"\\2601\";\n}\n\n.glyphicon-envelope:before {\n  content: \"\\2709\";\n}\n\n.glyphicon-pencil:before {\n  content: \"\\270f\";\n}\n\n.glyphicon-glass:before {\n  content: \"\\e001\";\n}\n\n.glyphicon-music:before {\n  content: \"\\e002\";\n}\n\n.glyphicon-search:before {\n  content: \"\\e003\";\n}\n\n.glyphicon-heart:before {\n  content: \"\\e005\";\n}\n\n.glyphicon-star:before {\n  content: \"\\e006\";\n}\n\n.glyphicon-star-empty:before {\n  content: \"\\e007\";\n}\n\n.glyphicon-user:before {\n  content: \"\\e008\";\n}\n\n.glyphicon-film:before {\n  content: \"\\e009\";\n}\n\n.glyphicon-th-large:before {\n  content: \"\\e010\";\n}\n\n.glyphicon-th:before {\n  content: \"\\e011\";\n}\n\n.glyphicon-th-list:before {\n  content: \"\\e012\";\n}\n\n.glyphicon-ok:before {\n  content: \"\\e013\";\n}\n\n.glyphicon-remove:before {\n  content: \"\\e014\";\n}\n\n.glyphicon-zoom-in:before {\n  content: \"\\e015\";\n}\n\n.glyphicon-zoom-out:before {\n  content: \"\\e016\";\n}\n\n.glyphicon-off:before {\n  content: \"\\e017\";\n}\n\n.glyphicon-signal:before {\n  content: \"\\e018\";\n}\n\n.glyphicon-cog:before {\n  content: \"\\e019\";\n}\n\n.glyphicon-trash:before {\n  content: \"\\e020\";\n}\n\n.glyphicon-home:before {\n  content: \"\\e021\";\n}\n\n.glyphicon-file:before {\n  content: \"\\e022\";\n}\n\n.glyphicon-time:before {\n  content: \"\\e023\";\n}\n\n.glyphicon-road:before {\n  content: \"\\e024\";\n}\n\n.glyphicon-download-alt:before {\n  content: \"\\e025\";\n}\n\n.glyphicon-download:before {\n  content: \"\\e026\";\n}\n\n.glyphicon-upload:before {\n  content: \"\\e027\";\n}\n\n.glyphicon-inbox:before {\n  content: \"\\e028\";\n}\n\n.glyphicon-play-circle:before {\n  content: \"\\e029\";\n}\n\n.glyphicon-repeat:before {\n  content: \"\\e030\";\n}\n\n.glyphicon-refresh:before {\n  content: \"\\e031\";\n}\n\n.glyphicon-list-alt:before {\n  content: \"\\e032\";\n}\n\n.glyphicon-lock:before {\n  content: \"\\e033\";\n}\n\n.glyphicon-flag:before {\n  content: \"\\e034\";\n}\n\n.glyphicon-headphones:before {\n  content: \"\\e035\";\n}\n\n.glyphicon-volume-off:before {\n  content: \"\\e036\";\n}\n\n.glyphicon-volume-down:before {\n  content: \"\\e037\";\n}\n\n.glyphicon-volume-up:before {\n  content: \"\\e038\";\n}\n\n.glyphicon-qrcode:before {\n  content: \"\\e039\";\n}\n\n.glyphicon-barcode:before {\n  content: \"\\e040\";\n}\n\n.glyphicon-tag:before {\n  content: \"\\e041\";\n}\n\n.glyphicon-tags:before {\n  content: \"\\e042\";\n}\n\n.glyphicon-book:before {\n  content: \"\\e043\";\n}\n\n.glyphicon-bookmark:before {\n  content: \"\\e044\";\n}\n\n.glyphicon-print:before {\n  content: \"\\e045\";\n}\n\n.glyphicon-camera:before {\n  content: \"\\e046\";\n}\n\n.glyphicon-font:before {\n  content: \"\\e047\";\n}\n\n.glyphicon-bold:before {\n  content: \"\\e048\";\n}\n\n.glyphicon-italic:before {\n  content: \"\\e049\";\n}\n\n.glyphicon-text-height:before {\n  content: \"\\e050\";\n}\n\n.glyphicon-text-width:before {\n  content: \"\\e051\";\n}\n\n.glyphicon-align-left:before {\n  content: \"\\e052\";\n}\n\n.glyphicon-align-center:before {\n  content: \"\\e053\";\n}\n\n.glyphicon-align-right:before {\n  content: \"\\e054\";\n}\n\n.glyphicon-align-justify:before {\n  content: \"\\e055\";\n}\n\n.glyphicon-list:before {\n  content: \"\\e056\";\n}\n\n.glyphicon-indent-left:before {\n  content: \"\\e057\";\n}\n\n.glyphicon-indent-right:before {\n  content: \"\\e058\";\n}\n\n.glyphicon-facetime-video:before {\n  content: \"\\e059\";\n}\n\n.glyphicon-picture:before {\n  content: \"\\e060\";\n}\n\n.glyphicon-map-marker:before {\n  content: \"\\e062\";\n}\n\n.glyphicon-adjust:before {\n  content: \"\\e063\";\n}\n\n.glyphicon-tint:before {\n  content: \"\\e064\";\n}\n\n.glyphicon-edit:before {\n  content: \"\\e065\";\n}\n\n.glyphicon-share:before {\n  content: \"\\e066\";\n}\n\n.glyphicon-check:before {\n  content: \"\\e067\";\n}\n\n.glyphicon-move:before {\n  content: \"\\e068\";\n}\n\n.glyphicon-step-backward:before {\n  content: \"\\e069\";\n}\n\n.glyphicon-fast-backward:before {\n  content: \"\\e070\";\n}\n\n.glyphicon-backward:before {\n  content: \"\\e071\";\n}\n\n.glyphicon-play:before {\n  content: \"\\e072\";\n}\n\n.glyphicon-pause:before {\n  content: \"\\e073\";\n}\n\n.glyphicon-stop:before {\n  content: \"\\e074\";\n}\n\n.glyphicon-forward:before {\n  content: \"\\e075\";\n}\n\n.glyphicon-fast-forward:before {\n  content: \"\\e076\";\n}\n\n.glyphicon-step-forward:before {\n  content: \"\\e077\";\n}\n\n.glyphicon-eject:before {\n  content: \"\\e078\";\n}\n\n.glyphicon-chevron-left:before {\n  content: \"\\e079\";\n}\n\n.glyphicon-chevron-right:before {\n  content: \"\\e080\";\n}\n\n.glyphicon-plus-sign:before {\n  content: \"\\e081\";\n}\n\n.glyphicon-minus-sign:before {\n  content: \"\\e082\";\n}\n\n.glyphicon-remove-sign:before {\n  content: \"\\e083\";\n}\n\n.glyphicon-ok-sign:before {\n  content: \"\\e084\";\n}\n\n.glyphicon-question-sign:before {\n  content: \"\\e085\";\n}\n\n.glyphicon-info-sign:before {\n  content: \"\\e086\";\n}\n\n.glyphicon-screenshot:before {\n  content: \"\\e087\";\n}\n\n.glyphicon-remove-circle:before {\n  content: \"\\e088\";\n}\n\n.glyphicon-ok-circle:before {\n  content: \"\\e089\";\n}\n\n.glyphicon-ban-circle:before {\n  content: \"\\e090\";\n}\n\n.glyphicon-arrow-left:before {\n  content: \"\\e091\";\n}\n\n.glyphicon-arrow-right:before {\n  content: \"\\e092\";\n}\n\n.glyphicon-arrow-up:before {\n  content: \"\\e093\";\n}\n\n.glyphicon-arrow-down:before {\n  content: \"\\e094\";\n}\n\n.glyphicon-share-alt:before {\n  content: \"\\e095\";\n}\n\n.glyphicon-resize-full:before {\n  content: \"\\e096\";\n}\n\n.glyphicon-resize-small:before {\n  content: \"\\e097\";\n}\n\n.glyphicon-exclamation-sign:before {\n  content: \"\\e101\";\n}\n\n.glyphicon-gift:before {\n  content: \"\\e102\";\n}\n\n.glyphicon-leaf:before {\n  content: \"\\e103\";\n}\n\n.glyphicon-fire:before {\n  content: \"\\e104\";\n}\n\n.glyphicon-eye-open:before {\n  content: \"\\e105\";\n}\n\n.glyphicon-eye-close:before {\n  content: \"\\e106\";\n}\n\n.glyphicon-warning-sign:before {\n  content: \"\\e107\";\n}\n\n.glyphicon-plane:before {\n  content: \"\\e108\";\n}\n\n.glyphicon-calendar:before {\n  content: \"\\e109\";\n}\n\n.glyphicon-random:before {\n  content: \"\\e110\";\n}\n\n.glyphicon-comment:before {\n  content: \"\\e111\";\n}\n\n.glyphicon-magnet:before {\n  content: \"\\e112\";\n}\n\n.glyphicon-chevron-up:before {\n  content: \"\\e113\";\n}\n\n.glyphicon-chevron-down:before {\n  content: \"\\e114\";\n}\n\n.glyphicon-retweet:before {\n  content: \"\\e115\";\n}\n\n.glyphicon-shopping-cart:before {\n  content: \"\\e116\";\n}\n\n.glyphicon-folder-close:before {\n  content: \"\\e117\";\n}\n\n.glyphicon-folder-open:before {\n  content: \"\\e118\";\n}\n\n.glyphicon-resize-vertical:before {\n  content: \"\\e119\";\n}\n\n.glyphicon-resize-horizontal:before {\n  content: \"\\e120\";\n}\n\n.glyphicon-hdd:before {\n  content: \"\\e121\";\n}\n\n.glyphicon-bullhorn:before {\n  content: \"\\e122\";\n}\n\n.glyphicon-bell:before {\n  content: \"\\e123\";\n}\n\n.glyphicon-certificate:before {\n  content: \"\\e124\";\n}\n\n.glyphicon-thumbs-up:before {\n  content: \"\\e125\";\n}\n\n.glyphicon-thumbs-down:before {\n  content: \"\\e126\";\n}\n\n.glyphicon-hand-right:before {\n  content: \"\\e127\";\n}\n\n.glyphicon-hand-left:before {\n  content: \"\\e128\";\n}\n\n.glyphicon-hand-up:before {\n  content: \"\\e129\";\n}\n\n.glyphicon-hand-down:before {\n  content: \"\\e130\";\n}\n\n.glyphicon-circle-arrow-right:before {\n  content: \"\\e131\";\n}\n\n.glyphicon-circle-arrow-left:before {\n  content: \"\\e132\";\n}\n\n.glyphicon-circle-arrow-up:before {\n  content: \"\\e133\";\n}\n\n.glyphicon-circle-arrow-down:before {\n  content: \"\\e134\";\n}\n\n.glyphicon-globe:before {\n  content: \"\\e135\";\n}\n\n.glyphicon-wrench:before {\n  content: \"\\e136\";\n}\n\n.glyphicon-tasks:before {\n  content: \"\\e137\";\n}\n\n.glyphicon-filter:before {\n  content: \"\\e138\";\n}\n\n.glyphicon-briefcase:before {\n  content: \"\\e139\";\n}\n\n.glyphicon-fullscreen:before {\n  content: \"\\e140\";\n}\n\n.glyphicon-dashboard:before {\n  content: \"\\e141\";\n}\n\n.glyphicon-paperclip:before {\n  content: \"\\e142\";\n}\n\n.glyphicon-heart-empty:before {\n  content: \"\\e143\";\n}\n\n.glyphicon-link:before {\n  content: \"\\e144\";\n}\n\n.glyphicon-phone:before {\n  content: \"\\e145\";\n}\n\n.glyphicon-pushpin:before {\n  content: \"\\e146\";\n}\n\n.glyphicon-usd:before {\n  content: \"\\e148\";\n}\n\n.glyphicon-gbp:before {\n  content: \"\\e149\";\n}\n\n.glyphicon-sort:before {\n  content: \"\\e150\";\n}\n\n.glyphicon-sort-by-alphabet:before {\n  content: \"\\e151\";\n}\n\n.glyphicon-sort-by-alphabet-alt:before {\n  content: \"\\e152\";\n}\n\n.glyphicon-sort-by-order:before {\n  content: \"\\e153\";\n}\n\n.glyphicon-sort-by-order-alt:before {\n  content: \"\\e154\";\n}\n\n.glyphicon-sort-by-attributes:before {\n  content: \"\\e155\";\n}\n\n.glyphicon-sort-by-attributes-alt:before {\n  content: \"\\e156\";\n}\n\n.glyphicon-unchecked:before {\n  content: \"\\e157\";\n}\n\n.glyphicon-expand:before {\n  content: \"\\e158\";\n}\n\n.glyphicon-collapse-down:before {\n  content: \"\\e159\";\n}\n\n.glyphicon-collapse-up:before {\n  content: \"\\e160\";\n}\n\n.glyphicon-log-in:before {\n  content: \"\\e161\";\n}\n\n.glyphicon-flash:before {\n  content: \"\\e162\";\n}\n\n.glyphicon-log-out:before {\n  content: \"\\e163\";\n}\n\n.glyphicon-new-window:before {\n  content: \"\\e164\";\n}\n\n.glyphicon-record:before {\n  content: \"\\e165\";\n}\n\n.glyphicon-save:before {\n  content: \"\\e166\";\n}\n\n.glyphicon-open:before {\n  content: \"\\e167\";\n}\n\n.glyphicon-saved:before {\n  content: \"\\e168\";\n}\n\n.glyphicon-import:before {\n  content: \"\\e169\";\n}\n\n.glyphicon-export:before {\n  content: \"\\e170\";\n}\n\n.glyphicon-send:before {\n  content: \"\\e171\";\n}\n\n.glyphicon-floppy-disk:before {\n  content: \"\\e172\";\n}\n\n.glyphicon-floppy-saved:before {\n  content: \"\\e173\";\n}\n\n.glyphicon-floppy-remove:before {\n  content: \"\\e174\";\n}\n\n.glyphicon-floppy-save:before {\n  content: \"\\e175\";\n}\n\n.glyphicon-floppy-open:before {\n  content: \"\\e176\";\n}\n\n.glyphicon-credit-card:before {\n  content: \"\\e177\";\n}\n\n.glyphicon-transfer:before {\n  content: \"\\e178\";\n}\n\n.glyphicon-cutlery:before {\n  content: \"\\e179\";\n}\n\n.glyphicon-header:before {\n  content: \"\\e180\";\n}\n\n.glyphicon-compressed:before {\n  content: \"\\e181\";\n}\n\n.glyphicon-earphone:before {\n  content: \"\\e182\";\n}\n\n.glyphicon-phone-alt:before {\n  content: \"\\e183\";\n}\n\n.glyphicon-tower:before {\n  content: \"\\e184\";\n}\n\n.glyphicon-stats:before {\n  content: \"\\e185\";\n}\n\n.glyphicon-sd-video:before {\n  content: \"\\e186\";\n}\n\n.glyphicon-hd-video:before {\n  content: \"\\e187\";\n}\n\n.glyphicon-subtitles:before {\n  content: \"\\e188\";\n}\n\n.glyphicon-sound-stereo:before {\n  content: \"\\e189\";\n}\n\n.glyphicon-sound-dolby:before {\n  content: \"\\e190\";\n}\n\n.glyphicon-sound-5-1:before {\n  content: \"\\e191\";\n}\n\n.glyphicon-sound-6-1:before {\n  content: \"\\e192\";\n}\n\n.glyphicon-sound-7-1:before {\n  content: \"\\e193\";\n}\n\n.glyphicon-copyright-mark:before {\n  content: \"\\e194\";\n}\n\n.glyphicon-registration-mark:before {\n  content: \"\\e195\";\n}\n\n.glyphicon-cloud-download:before {\n  content: \"\\e197\";\n}\n\n.glyphicon-cloud-upload:before {\n  content: \"\\e198\";\n}\n\n.glyphicon-tree-conifer:before {\n  content: \"\\e199\";\n}\n\n.glyphicon-tree-deciduous:before {\n  content: \"\\e200\";\n}\n\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  margin-left: 2px;\n  vertical-align: middle;\n  border-top: 4px solid;\n  border-right: 4px solid transparent;\n  border-left: 4px solid transparent;\n}\n\n.dropdown {\n  position: relative;\n}\n\n.dropdown-toggle:focus {\n  outline: 0;\n}\n\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 1000;\n  display: none;\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0;\n  font-size: 14px;\n  list-style: none;\n  background-color: #ffffff;\n  border: 1px solid #cccccc;\n  border: 1px solid rgba(0, 0, 0, 0.15);\n  border-radius: 4px;\n  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n          box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n  background-clip: padding-box;\n}\n\n.dropdown-menu.pull-right {\n  right: 0;\n  left: auto;\n}\n\n.dropdown-menu .divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n\n.dropdown-menu > li > a {\n  display: block;\n  padding: 3px 20px;\n  clear: both;\n  font-weight: normal;\n  line-height: 1.428571429;\n  color: #333333;\n  white-space: nowrap;\n}\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  color: #262626;\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\n\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  color: #ffffff;\n  text-decoration: none;\n  background-color: #428bca;\n  outline: 0;\n}\n\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  color: #999999;\n}\n\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  text-decoration: none;\n  cursor: not-allowed;\n  background-color: transparent;\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n\n.open > .dropdown-menu {\n  display: block;\n}\n\n.open > a {\n  outline: 0;\n}\n\n.dropdown-header {\n  display: block;\n  padding: 3px 20px;\n  font-size: 12px;\n  line-height: 1.428571429;\n  color: #999999;\n}\n\n.dropdown-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 990;\n}\n\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n  border-top: 0;\n  border-bottom: 4px solid;\n  content: \"\";\n}\n\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n  top: auto;\n  bottom: 100%;\n  margin-bottom: 1px;\n}\n\n@media (min-width: 768px) {\n  .navbar-right .dropdown-menu {\n    right: 0;\n    left: auto;\n  }\n}\n\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle;\n}\n\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n  position: relative;\n  float: left;\n}\n\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n  z-index: 2;\n}\n\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus {\n  outline: none;\n}\n\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n  margin-left: -1px;\n}\n\n.btn-toolbar:before,\n.btn-toolbar:after {\n  display: table;\n  content: \" \";\n}\n\n.btn-toolbar:after {\n  clear: both;\n}\n\n.btn-toolbar:before,\n.btn-toolbar:after {\n  display: table;\n  content: \" \";\n}\n\n.btn-toolbar:after {\n  clear: both;\n}\n\n.btn-toolbar .btn-group {\n  float: left;\n}\n\n.btn-toolbar > .btn + .btn,\n.btn-toolbar > .btn-group + .btn,\n.btn-toolbar > .btn + .btn-group,\n.btn-toolbar > .btn-group + .btn-group {\n  margin-left: 5px;\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n  border-radius: 0;\n}\n\n.btn-group > .btn:first-child {\n  margin-left: 0;\n}\n\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n\n.btn-group > .btn-group {\n  float: left;\n}\n\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n\n.btn-group > .btn-group:first-child > .btn:last-child,\n.btn-group > .btn-group:first-child > .dropdown-toggle {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n\n.btn-group > .btn-group:last-child > .btn:first-child {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n\n.btn-group-xs > .btn {\n  padding: 1px 5px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n\n.btn-group-sm > .btn {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n\n.btn-group-lg > .btn {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.33;\n  border-radius: 6px;\n}\n\n.btn-group > .btn + .dropdown-toggle {\n  padding-right: 8px;\n  padding-left: 8px;\n}\n\n.btn-group > .btn-lg + .dropdown-toggle {\n  padding-right: 12px;\n  padding-left: 12px;\n}\n\n.btn-group.open .dropdown-toggle {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n\n.btn-group.open .dropdown-toggle.btn-link {\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n\n.btn .caret {\n  margin-left: 0;\n}\n\n.btn-lg .caret {\n  border-width: 5px 5px 0;\n  border-bottom-width: 0;\n}\n\n.dropup .btn-lg .caret {\n  border-width: 0 5px 5px;\n}\n\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n  display: block;\n  float: none;\n  width: 100%;\n  max-width: 100%;\n}\n\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after {\n  display: table;\n  content: \" \";\n}\n\n.btn-group-vertical > .btn-group:after {\n  clear: both;\n}\n\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after {\n  display: table;\n  content: \" \";\n}\n\n.btn-group-vertical > .btn-group:after {\n  clear: both;\n}\n\n.btn-group-vertical > .btn-group > .btn {\n  float: none;\n}\n\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n  margin-top: -1px;\n  margin-left: 0;\n}\n\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n  border-top-right-radius: 0;\n  border-bottom-left-radius: 4px;\n  border-top-left-radius: 0;\n}\n\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n\n.btn-group-vertical > .btn-group:first-child > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child > .dropdown-toggle {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n\n.btn-group-vertical > .btn-group:last-child > .btn:first-child {\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n\n.btn-group-justified {\n  display: table;\n  width: 100%;\n  border-collapse: separate;\n  table-layout: fixed;\n}\n\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n  display: table-cell;\n  float: none;\n  width: 1%;\n}\n\n.btn-group-justified > .btn-group .btn {\n  width: 100%;\n}\n\n[data-toggle=\"buttons\"] > .btn > input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn > input[type=\"checkbox\"] {\n  display: none;\n}\n\n.input-group {\n  position: relative;\n  display: table;\n  border-collapse: separate;\n}\n\n.input-group[class*=\"col-\"] {\n  float: none;\n  padding-right: 0;\n  padding-left: 0;\n}\n\n.input-group .form-control {\n  width: 100%;\n  margin-bottom: 0;\n}\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.33;\n  border-radius: 6px;\n}\n\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  line-height: 46px;\n}\n\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn {\n  height: auto;\n}\n\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  line-height: 30px;\n}\n\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn {\n  height: auto;\n}\n\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n  display: table-cell;\n}\n\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n\n.input-group-addon,\n.input-group-btn {\n  width: 1%;\n  white-space: nowrap;\n  vertical-align: middle;\n}\n\n.input-group-addon {\n  padding: 6px 12px;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1;\n  color: #555555;\n  text-align: center;\n  background-color: #eeeeee;\n  border: 1px solid #cccccc;\n  border-radius: 4px;\n}\n\n.input-group-addon.input-sm {\n  padding: 5px 10px;\n  font-size: 12px;\n  border-radius: 3px;\n}\n\n.input-group-addon.input-lg {\n  padding: 10px 16px;\n  font-size: 18px;\n  border-radius: 6px;\n}\n\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n  margin-top: 0;\n}\n\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle) {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n\n.input-group-addon:first-child {\n  border-right: 0;\n}\n\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child) {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n}\n\n.input-group-addon:last-child {\n  border-left: 0;\n}\n\n.input-group-btn {\n  position: relative;\n  white-space: nowrap;\n}\n\n.input-group-btn:first-child > .btn {\n  margin-right: -1px;\n}\n\n.input-group-btn:last-child > .btn {\n  margin-left: -1px;\n}\n\n.input-group-btn > .btn {\n  position: relative;\n}\n\n.input-group-btn > .btn + .btn {\n  margin-left: -4px;\n}\n\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:active {\n  z-index: 2;\n}\n\n.nav {\n  padding-left: 0;\n  margin-bottom: 0;\n  list-style: none;\n}\n\n.nav:before,\n.nav:after {\n  display: table;\n  content: \" \";\n}\n\n.nav:after {\n  clear: both;\n}\n\n.nav:before,\n.nav:after {\n  display: table;\n  content: \" \";\n}\n\n.nav:after {\n  clear: both;\n}\n\n.nav > li {\n  position: relative;\n  display: block;\n}\n\n.nav > li > a {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n}\n\n.nav > li > a:hover,\n.nav > li > a:focus {\n  text-decoration: none;\n  background-color: #eeeeee;\n}\n\n.nav > li.disabled > a {\n  color: #999999;\n}\n\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n  color: #999999;\n  text-decoration: none;\n  cursor: not-allowed;\n  background-color: transparent;\n}\n\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n  background-color: #eeeeee;\n  border-color: #428bca;\n}\n\n.nav .nav-divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n\n.nav > li > a > img {\n  max-width: none;\n}\n\n.nav-tabs {\n  border-bottom: 1px solid #dddddd;\n}\n\n.nav-tabs > li {\n  float: left;\n  margin-bottom: -1px;\n}\n\n.nav-tabs > li > a {\n  margin-right: 2px;\n  line-height: 1.428571429;\n  border: 1px solid transparent;\n  border-radius: 4px 4px 0 0;\n}\n\n.nav-tabs > li > a:hover {\n  border-color: #eeeeee #eeeeee #dddddd;\n}\n\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n  color: #555555;\n  cursor: default;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-bottom-color: transparent;\n}\n\n.nav-tabs.nav-justified {\n  width: 100%;\n  border-bottom: 0;\n}\n\n.nav-tabs.nav-justified > li {\n  float: none;\n}\n\n.nav-tabs.nav-justified > li > a {\n  margin-bottom: 5px;\n  text-align: center;\n}\n\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-tabs.nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n\n.nav-tabs.nav-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n  border: 1px solid #dddddd;\n}\n\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li > a {\n    border-bottom: 1px solid #dddddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs.nav-justified > .active > a,\n  .nav-tabs.nav-justified > .active > a:hover,\n  .nav-tabs.nav-justified > .active > a:focus {\n    border-bottom-color: #ffffff;\n  }\n}\n\n.nav-pills > li {\n  float: left;\n}\n\n.nav-pills > li > a {\n  border-radius: 4px;\n}\n\n.nav-pills > li + li {\n  margin-left: 2px;\n}\n\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n  color: #ffffff;\n  background-color: #428bca;\n}\n\n.nav-stacked > li {\n  float: none;\n}\n\n.nav-stacked > li + li {\n  margin-top: 2px;\n  margin-left: 0;\n}\n\n.nav-justified {\n  width: 100%;\n}\n\n.nav-justified > li {\n  float: none;\n}\n\n.nav-justified > li > a {\n  margin-bottom: 5px;\n  text-align: center;\n}\n\n.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n\n@media (min-width: 768px) {\n  .nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n\n.nav-tabs-justified {\n  border-bottom: 0;\n}\n\n.nav-tabs-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n  border: 1px solid #dddddd;\n}\n\n@media (min-width: 768px) {\n  .nav-tabs-justified > li > a {\n    border-bottom: 1px solid #dddddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs-justified > .active > a,\n  .nav-tabs-justified > .active > a:hover,\n  .nav-tabs-justified > .active > a:focus {\n    border-bottom-color: #ffffff;\n  }\n}\n\n.tab-content > .tab-pane {\n  display: none;\n}\n\n.tab-content > .active {\n  display: block;\n}\n\n.nav-tabs .dropdown-menu {\n  margin-top: -1px;\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n\n.navbar {\n  position: relative;\n  min-height: 50px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n}\n\n.navbar:before,\n.navbar:after {\n  display: table;\n  content: \" \";\n}\n\n.navbar:after {\n  clear: both;\n}\n\n.navbar:before,\n.navbar:after {\n  display: table;\n  content: \" \";\n}\n\n.navbar:after {\n  clear: both;\n}\n\n@media (min-width: 768px) {\n  .navbar {\n    border-radius: 4px;\n  }\n}\n\n.navbar-header:before,\n.navbar-header:after {\n  display: table;\n  content: \" \";\n}\n\n.navbar-header:after {\n  clear: both;\n}\n\n.navbar-header:before,\n.navbar-header:after {\n  display: table;\n  content: \" \";\n}\n\n.navbar-header:after {\n  clear: both;\n}\n\n@media (min-width: 768px) {\n  .navbar-header {\n    float: left;\n  }\n}\n\n.navbar-collapse {\n  max-height: 340px;\n  padding-right: 15px;\n  padding-left: 15px;\n  overflow-x: visible;\n  border-top: 1px solid transparent;\n  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1);\n  -webkit-overflow-scrolling: touch;\n}\n\n.navbar-collapse:before,\n.navbar-collapse:after {\n  display: table;\n  content: \" \";\n}\n\n.navbar-collapse:after {\n  clear: both;\n}\n\n.navbar-collapse:before,\n.navbar-collapse:after {\n  display: table;\n  content: \" \";\n}\n\n.navbar-collapse:after {\n  clear: both;\n}\n\n.navbar-collapse.in {\n  overflow-y: auto;\n}\n\n@media (min-width: 768px) {\n  .navbar-collapse {\n    width: auto;\n    border-top: 0;\n    box-shadow: none;\n  }\n  .navbar-collapse.collapse {\n    display: block !important;\n    height: auto !important;\n    padding-bottom: 0;\n    overflow: visible !important;\n  }\n  .navbar-collapse.in {\n    overflow-y: visible;\n  }\n  .navbar-fixed-top .navbar-collapse,\n  .navbar-static-top .navbar-collapse,\n  .navbar-fixed-bottom .navbar-collapse {\n    padding-right: 0;\n    padding-left: 0;\n  }\n}\n\n.container > .navbar-header,\n.container > .navbar-collapse {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n\n@media (min-width: 768px) {\n  .container > .navbar-header,\n  .container > .navbar-collapse {\n    margin-right: 0;\n    margin-left: 0;\n  }\n}\n\n.navbar-static-top {\n  z-index: 1000;\n  border-width: 0 0 1px;\n}\n\n@media (min-width: 768px) {\n  .navbar-static-top {\n    border-radius: 0;\n  }\n}\n\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: 1030;\n}\n\n@media (min-width: 768px) {\n  .navbar-fixed-top,\n  .navbar-fixed-bottom {\n    border-radius: 0;\n  }\n}\n\n.navbar-fixed-top {\n  top: 0;\n  border-width: 0 0 1px;\n}\n\n.navbar-fixed-bottom {\n  bottom: 0;\n  margin-bottom: 0;\n  border-width: 1px 0 0;\n}\n\n.navbar-brand {\n  float: left;\n  padding: 15px 15px;\n  font-size: 18px;\n  line-height: 20px;\n}\n\n.navbar-brand:hover,\n.navbar-brand:focus {\n  text-decoration: none;\n}\n\n@media (min-width: 768px) {\n  .navbar > .container .navbar-brand {\n    margin-left: -15px;\n  }\n}\n\n.navbar-toggle {\n  position: relative;\n  float: right;\n  padding: 9px 10px;\n  margin-top: 8px;\n  margin-right: 15px;\n  margin-bottom: 8px;\n  background-color: transparent;\n  background-image: none;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n\n.navbar-toggle .icon-bar {\n  display: block;\n  width: 22px;\n  height: 2px;\n  border-radius: 1px;\n}\n\n.navbar-toggle .icon-bar + .icon-bar {\n  margin-top: 4px;\n}\n\n@media (min-width: 768px) {\n  .navbar-toggle {\n    display: none;\n  }\n}\n\n.navbar-nav {\n  margin: 7.5px -15px;\n}\n\n.navbar-nav > li > a {\n  padding-top: 10px;\n  padding-bottom: 10px;\n  line-height: 20px;\n}\n\n@media (max-width: 767px) {\n  .navbar-nav .open .dropdown-menu {\n    position: static;\n    float: none;\n    width: auto;\n    margin-top: 0;\n    background-color: transparent;\n    border: 0;\n    box-shadow: none;\n  }\n  .navbar-nav .open .dropdown-menu > li > a,\n  .navbar-nav .open .dropdown-menu .dropdown-header {\n    padding: 5px 15px 5px 25px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a {\n    line-height: 20px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-nav .open .dropdown-menu > li > a:focus {\n    background-image: none;\n  }\n}\n\n@media (min-width: 768px) {\n  .navbar-nav {\n    float: left;\n    margin: 0;\n  }\n  .navbar-nav > li {\n    float: left;\n  }\n  .navbar-nav > li > a {\n    padding-top: 15px;\n    padding-bottom: 15px;\n  }\n  .navbar-nav.navbar-right:last-child {\n    margin-right: -15px;\n  }\n}\n\n@media (min-width: 768px) {\n  .navbar-left {\n    float: left !important;\n  }\n  .navbar-right {\n    float: right !important;\n  }\n}\n\n.navbar-form {\n  padding: 10px 15px;\n  margin-top: 8px;\n  margin-right: -15px;\n  margin-bottom: 8px;\n  margin-left: -15px;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid transparent;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n\n@media (min-width: 768px) {\n  .navbar-form .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .form-control {\n    display: inline-block;\n  }\n  .navbar-form select.form-control {\n    width: auto;\n  }\n  .navbar-form .radio,\n  .navbar-form .checkbox {\n    display: inline-block;\n    padding-left: 0;\n    margin-top: 0;\n    margin-bottom: 0;\n  }\n  .navbar-form .radio input[type=\"radio\"],\n  .navbar-form .checkbox input[type=\"checkbox\"] {\n    float: none;\n    margin-left: 0;\n  }\n}\n\n@media (max-width: 767px) {\n  .navbar-form .form-group {\n    margin-bottom: 5px;\n  }\n}\n\n@media (min-width: 768px) {\n  .navbar-form {\n    width: auto;\n    padding-top: 0;\n    padding-bottom: 0;\n    margin-right: 0;\n    margin-left: 0;\n    border: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n  .navbar-form.navbar-right:last-child {\n    margin-right: -15px;\n  }\n}\n\n.navbar-nav > li > .dropdown-menu {\n  margin-top: 0;\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n\n.navbar-nav.pull-right > li > .dropdown-menu,\n.navbar-nav > li > .dropdown-menu.pull-right {\n  right: 0;\n  left: auto;\n}\n\n.navbar-btn {\n  margin-top: 8px;\n  margin-bottom: 8px;\n}\n\n.navbar-btn.btn-sm {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n\n.navbar-btn.btn-xs {\n  margin-top: 14px;\n  margin-bottom: 14px;\n}\n\n.navbar-text {\n  margin-top: 15px;\n  margin-bottom: 15px;\n}\n\n@media (min-width: 768px) {\n  .navbar-text {\n    float: left;\n    margin-right: 15px;\n    margin-left: 15px;\n  }\n  .navbar-text.navbar-right:last-child {\n    margin-right: 0;\n  }\n}\n\n.navbar-default {\n  background-color: #f8f8f8;\n  border-color: #e7e7e7;\n}\n\n.navbar-default .navbar-brand {\n  color: #777777;\n}\n\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n  color: #5e5e5e;\n  background-color: transparent;\n}\n\n.navbar-default .navbar-text {\n  color: #777777;\n}\n\n.navbar-default .navbar-nav > li > a {\n  color: #777777;\n}\n\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n  color: #333333;\n  background-color: transparent;\n}\n\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n  color: #555555;\n  background-color: #e7e7e7;\n}\n\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n  color: #cccccc;\n  background-color: transparent;\n}\n\n.navbar-default .navbar-toggle {\n  border-color: #dddddd;\n}\n\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n  background-color: #dddddd;\n}\n\n.navbar-default .navbar-toggle .icon-bar {\n  background-color: #cccccc;\n}\n\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n  border-color: #e7e7e7;\n}\n\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n  color: #555555;\n  background-color: #e7e7e7;\n}\n\n@media (max-width: 767px) {\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n    color: #777777;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #333333;\n    background-color: transparent;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #555555;\n    background-color: #e7e7e7;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #cccccc;\n    background-color: transparent;\n  }\n}\n\n.navbar-default .navbar-link {\n  color: #777777;\n}\n\n.navbar-default .navbar-link:hover {\n  color: #333333;\n}\n\n.navbar-inverse {\n  background-color: #222222;\n  border-color: #080808;\n}\n\n.navbar-inverse .navbar-brand {\n  color: #999999;\n}\n\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n  color: #ffffff;\n  background-color: transparent;\n}\n\n.navbar-inverse .navbar-text {\n  color: #999999;\n}\n\n.navbar-inverse .navbar-nav > li > a {\n  color: #999999;\n}\n\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n  color: #ffffff;\n  background-color: transparent;\n}\n\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n  color: #ffffff;\n  background-color: #080808;\n}\n\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n  color: #444444;\n  background-color: transparent;\n}\n\n.navbar-inverse .navbar-toggle {\n  border-color: #333333;\n}\n\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n  background-color: #333333;\n}\n\n.navbar-inverse .navbar-toggle .icon-bar {\n  background-color: #ffffff;\n}\n\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n  border-color: #101010;\n}\n\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n  color: #ffffff;\n  background-color: #080808;\n}\n\n@media (max-width: 767px) {\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n    border-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n    color: #999999;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #ffffff;\n    background-color: transparent;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #ffffff;\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #444444;\n    background-color: transparent;\n  }\n}\n\n.navbar-inverse .navbar-link {\n  color: #999999;\n}\n\n.navbar-inverse .navbar-link:hover {\n  color: #ffffff;\n}\n\n.breadcrumb {\n  padding: 8px 15px;\n  margin-bottom: 20px;\n  list-style: none;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n}\n\n.breadcrumb > li {\n  display: inline-block;\n}\n\n.breadcrumb > li + li:before {\n  padding: 0 5px;\n  color: #cccccc;\n  content: \"/\\00a0\";\n}\n\n.breadcrumb > .active {\n  color: #999999;\n}\n\n.pagination {\n  display: inline-block;\n  padding-left: 0;\n  margin: 20px 0;\n  border-radius: 4px;\n}\n\n.pagination > li {\n  display: inline;\n}\n\n.pagination > li > a,\n.pagination > li > span {\n  position: relative;\n  float: left;\n  padding: 6px 12px;\n  margin-left: -1px;\n  line-height: 1.428571429;\n  text-decoration: none;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n}\n\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n  margin-left: 0;\n  border-bottom-left-radius: 4px;\n  border-top-left-radius: 4px;\n}\n\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n  background-color: #eeeeee;\n}\n\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n  z-index: 2;\n  color: #ffffff;\n  cursor: default;\n  background-color: #428bca;\n  border-color: #428bca;\n}\n\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n  color: #999999;\n  cursor: not-allowed;\n  background-color: #ffffff;\n  border-color: #dddddd;\n}\n\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n  padding: 10px 16px;\n  font-size: 18px;\n}\n\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n  border-bottom-left-radius: 6px;\n  border-top-left-radius: 6px;\n}\n\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n  border-top-right-radius: 6px;\n  border-bottom-right-radius: 6px;\n}\n\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n  padding: 5px 10px;\n  font-size: 12px;\n}\n\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n  border-bottom-left-radius: 3px;\n  border-top-left-radius: 3px;\n}\n\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n  border-top-right-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n\n.pager {\n  padding-left: 0;\n  margin: 20px 0;\n  text-align: center;\n  list-style: none;\n}\n\n.pager:before,\n.pager:after {\n  display: table;\n  content: \" \";\n}\n\n.pager:after {\n  clear: both;\n}\n\n.pager:before,\n.pager:after {\n  display: table;\n  content: \" \";\n}\n\n.pager:after {\n  clear: both;\n}\n\n.pager li {\n  display: inline;\n}\n\n.pager li > a,\n.pager li > span {\n  display: inline-block;\n  padding: 5px 14px;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-radius: 15px;\n}\n\n.pager li > a:hover,\n.pager li > a:focus {\n  text-decoration: none;\n  background-color: #eeeeee;\n}\n\n.pager .next > a,\n.pager .next > span {\n  float: right;\n}\n\n.pager .previous > a,\n.pager .previous > span {\n  float: left;\n}\n\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n  color: #999999;\n  cursor: not-allowed;\n  background-color: #ffffff;\n}\n\n.label {\n  display: inline;\n  padding: .2em .6em .3em;\n  font-size: 75%;\n  font-weight: bold;\n  line-height: 1;\n  color: #ffffff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: .25em;\n}\n\n.label[href]:hover,\n.label[href]:focus {\n  color: #ffffff;\n  text-decoration: none;\n  cursor: pointer;\n}\n\n.label:empty {\n  display: none;\n}\n\n.btn .label {\n  position: relative;\n  top: -1px;\n}\n\n.label-default {\n  background-color: #999999;\n}\n\n.label-default[href]:hover,\n.label-default[href]:focus {\n  background-color: #808080;\n}\n\n.label-primary {\n  background-color: #428bca;\n}\n\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n  background-color: #3071a9;\n}\n\n.label-success {\n  background-color: #5cb85c;\n}\n\n.label-success[href]:hover,\n.label-success[href]:focus {\n  background-color: #449d44;\n}\n\n.label-info {\n  background-color: #5bc0de;\n}\n\n.label-info[href]:hover,\n.label-info[href]:focus {\n  background-color: #31b0d5;\n}\n\n.label-warning {\n  background-color: #f0ad4e;\n}\n\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n  background-color: #ec971f;\n}\n\n.label-danger {\n  background-color: #d9534f;\n}\n\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n  background-color: #c9302c;\n}\n\n.badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: 12px;\n  font-weight: bold;\n  line-height: 1;\n  color: #ffffff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  background-color: #999999;\n  border-radius: 10px;\n}\n\n.badge:empty {\n  display: none;\n}\n\n.btn .badge {\n  position: relative;\n  top: -1px;\n}\n\na.badge:hover,\na.badge:focus {\n  color: #ffffff;\n  text-decoration: none;\n  cursor: pointer;\n}\n\na.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n  color: #428bca;\n  background-color: #ffffff;\n}\n\n.nav-pills > li > a > .badge {\n  margin-left: 3px;\n}\n\n.jumbotron {\n  padding: 30px;\n  margin-bottom: 30px;\n  font-size: 21px;\n  font-weight: 200;\n  line-height: 2.1428571435;\n  color: inherit;\n  background-color: #eeeeee;\n}\n\n.jumbotron h1,\n.jumbotron .h1 {\n  line-height: 1;\n  color: inherit;\n}\n\n.jumbotron p {\n  line-height: 1.4;\n}\n\n.container .jumbotron {\n  border-radius: 6px;\n}\n\n.jumbotron .container {\n  max-width: 100%;\n}\n\n@media screen and (min-width: 768px) {\n  .jumbotron {\n    padding-top: 48px;\n    padding-bottom: 48px;\n  }\n  .container .jumbotron {\n    padding-right: 60px;\n    padding-left: 60px;\n  }\n  .jumbotron h1,\n  .jumbotron .h1 {\n    font-size: 63px;\n  }\n}\n\n.thumbnail {\n  display: block;\n  padding: 4px;\n  margin-bottom: 20px;\n  line-height: 1.428571429;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-radius: 4px;\n  -webkit-transition: all 0.2s ease-in-out;\n          transition: all 0.2s ease-in-out;\n}\n\n.thumbnail > img,\n.thumbnail a > img {\n  display: block;\n  height: auto;\n  max-width: 100%;\n  margin-right: auto;\n  margin-left: auto;\n}\n\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n  border-color: #428bca;\n}\n\n.thumbnail .caption {\n  padding: 9px;\n  color: #333333;\n}\n\n.alert {\n  padding: 15px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n\n.alert h4 {\n  margin-top: 0;\n  color: inherit;\n}\n\n.alert .alert-link {\n  font-weight: bold;\n}\n\n.alert > p,\n.alert > ul {\n  margin-bottom: 0;\n}\n\n.alert > p + p {\n  margin-top: 5px;\n}\n\n.alert-dismissable {\n  padding-right: 35px;\n}\n\n.alert-dismissable .close {\n  position: relative;\n  top: -2px;\n  right: -21px;\n  color: inherit;\n}\n\n.alert-success {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n\n.alert-success hr {\n  border-top-color: #c9e2b3;\n}\n\n.alert-success .alert-link {\n  color: #2b542c;\n}\n\n.alert-info {\n  color: #31708f;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n\n.alert-info hr {\n  border-top-color: #a6e1ec;\n}\n\n.alert-info .alert-link {\n  color: #245269;\n}\n\n.alert-warning {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n\n.alert-warning hr {\n  border-top-color: #f7e1b5;\n}\n\n.alert-warning .alert-link {\n  color: #66512c;\n}\n\n.alert-danger {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #ebccd1;\n}\n\n.alert-danger hr {\n  border-top-color: #e4b9c0;\n}\n\n.alert-danger .alert-link {\n  color: #843534;\n}\n\n@-webkit-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n\n@keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n\n.progress {\n  height: 20px;\n  margin-bottom: 20px;\n  overflow: hidden;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n          box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n\n.progress-bar {\n  float: left;\n  width: 0;\n  height: 100%;\n  font-size: 12px;\n  line-height: 20px;\n  color: #ffffff;\n  text-align: center;\n  background-color: #428bca;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n  -webkit-transition: width 0.6s ease;\n          transition: width 0.6s ease;\n}\n\n.progress-striped .progress-bar {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-size: 40px 40px;\n}\n\n.progress.active .progress-bar {\n  -webkit-animation: progress-bar-stripes 2s linear infinite;\n          animation: progress-bar-stripes 2s linear infinite;\n}\n\n.progress-bar-success {\n  background-color: #5cb85c;\n}\n\n.progress-striped .progress-bar-success {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n\n.progress-bar-info {\n  background-color: #5bc0de;\n}\n\n.progress-striped .progress-bar-info {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n\n.progress-bar-warning {\n  background-color: #f0ad4e;\n}\n\n.progress-striped .progress-bar-warning {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n\n.progress-bar-danger {\n  background-color: #d9534f;\n}\n\n.progress-striped .progress-bar-danger {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n\n.media,\n.media-body {\n  overflow: hidden;\n  zoom: 1;\n}\n\n.media,\n.media .media {\n  margin-top: 15px;\n}\n\n.media:first-child {\n  margin-top: 0;\n}\n\n.media-object {\n  display: block;\n}\n\n.media-heading {\n  margin: 0 0 5px;\n}\n\n.media > .pull-left {\n  margin-right: 10px;\n}\n\n.media > .pull-right {\n  margin-left: 10px;\n}\n\n.media-list {\n  padding-left: 0;\n  list-style: none;\n}\n\n.list-group {\n  padding-left: 0;\n  margin-bottom: 20px;\n}\n\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n  margin-bottom: -1px;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n}\n\n.list-group-item:first-child {\n  border-top-right-radius: 4px;\n  border-top-left-radius: 4px;\n}\n\n.list-group-item:last-child {\n  margin-bottom: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n\n.list-group-item > .badge {\n  float: right;\n}\n\n.list-group-item > .badge + .badge {\n  margin-right: 5px;\n}\n\na.list-group-item {\n  color: #555555;\n}\n\na.list-group-item .list-group-item-heading {\n  color: #333333;\n}\n\na.list-group-item:hover,\na.list-group-item:focus {\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\n\na.list-group-item.active,\na.list-group-item.active:hover,\na.list-group-item.active:focus {\n  z-index: 2;\n  color: #ffffff;\n  background-color: #428bca;\n  border-color: #428bca;\n}\n\na.list-group-item.active .list-group-item-heading,\na.list-group-item.active:hover .list-group-item-heading,\na.list-group-item.active:focus .list-group-item-heading {\n  color: inherit;\n}\n\na.list-group-item.active .list-group-item-text,\na.list-group-item.active:hover .list-group-item-text,\na.list-group-item.active:focus .list-group-item-text {\n  color: #e1edf7;\n}\n\n.list-group-item-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n\n.list-group-item-text {\n  margin-bottom: 0;\n  line-height: 1.3;\n}\n\n.panel {\n  margin-bottom: 20px;\n  background-color: #ffffff;\n  border: 1px solid transparent;\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n          box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n\n.panel-body {\n  padding: 15px;\n}\n\n.panel-body:before,\n.panel-body:after {\n  display: table;\n  content: \" \";\n}\n\n.panel-body:after {\n  clear: both;\n}\n\n.panel-body:before,\n.panel-body:after {\n  display: table;\n  content: \" \";\n}\n\n.panel-body:after {\n  clear: both;\n}\n\n.panel > .list-group {\n  margin-bottom: 0;\n}\n\n.panel > .list-group .list-group-item {\n  border-width: 1px 0;\n}\n\n.panel > .list-group .list-group-item:first-child {\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n\n.panel > .list-group .list-group-item:last-child {\n  border-bottom: 0;\n}\n\n.panel-heading + .list-group .list-group-item:first-child {\n  border-top-width: 0;\n}\n\n.panel > .table,\n.panel > .table-responsive > .table {\n  margin-bottom: 0;\n}\n\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive {\n  border-top: 1px solid #dddddd;\n}\n\n.panel > .table > tbody:first-child th,\n.panel > .table > tbody:first-child td {\n  border-top: 0;\n}\n\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n  border: 0;\n}\n\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n  border-left: 0;\n}\n\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n  border-right: 0;\n}\n\n.panel > .table-bordered > thead > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:last-child > th,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-bordered > thead > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n  border-bottom: 0;\n}\n\n.panel > .table-responsive {\n  margin-bottom: 0;\n  border: 0;\n}\n\n.panel-heading {\n  padding: 10px 15px;\n  border-bottom: 1px solid transparent;\n  border-top-right-radius: 3px;\n  border-top-left-radius: 3px;\n}\n\n.panel-heading > .dropdown .dropdown-toggle {\n  color: inherit;\n}\n\n.panel-title {\n  margin-top: 0;\n  margin-bottom: 0;\n  font-size: 16px;\n  color: inherit;\n}\n\n.panel-title > a {\n  color: inherit;\n}\n\n.panel-footer {\n  padding: 10px 15px;\n  background-color: #f5f5f5;\n  border-top: 1px solid #dddddd;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n\n.panel-group .panel {\n  margin-bottom: 0;\n  overflow: hidden;\n  border-radius: 4px;\n}\n\n.panel-group .panel + .panel {\n  margin-top: 5px;\n}\n\n.panel-group .panel-heading {\n  border-bottom: 0;\n}\n\n.panel-group .panel-heading + .panel-collapse .panel-body {\n  border-top: 1px solid #dddddd;\n}\n\n.panel-group .panel-footer {\n  border-top: 0;\n}\n\n.panel-group .panel-footer + .panel-collapse .panel-body {\n  border-bottom: 1px solid #dddddd;\n}\n\n.panel-default {\n  border-color: #dddddd;\n}\n\n.panel-default > .panel-heading {\n  color: #333333;\n  background-color: #f5f5f5;\n  border-color: #dddddd;\n}\n\n.panel-default > .panel-heading + .panel-collapse .panel-body {\n  border-top-color: #dddddd;\n}\n\n.panel-default > .panel-footer + .panel-collapse .panel-body {\n  border-bottom-color: #dddddd;\n}\n\n.panel-primary {\n  border-color: #428bca;\n}\n\n.panel-primary > .panel-heading {\n  color: #ffffff;\n  background-color: #428bca;\n  border-color: #428bca;\n}\n\n.panel-primary > .panel-heading + .panel-collapse .panel-body {\n  border-top-color: #428bca;\n}\n\n.panel-primary > .panel-footer + .panel-collapse .panel-body {\n  border-bottom-color: #428bca;\n}\n\n.panel-success {\n  border-color: #d6e9c6;\n}\n\n.panel-success > .panel-heading {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n\n.panel-success > .panel-heading + .panel-collapse .panel-body {\n  border-top-color: #d6e9c6;\n}\n\n.panel-success > .panel-footer + .panel-collapse .panel-body {\n  border-bottom-color: #d6e9c6;\n}\n\n.panel-warning {\n  border-color: #faebcc;\n}\n\n.panel-warning > .panel-heading {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n\n.panel-warning > .panel-heading + .panel-collapse .panel-body {\n  border-top-color: #faebcc;\n}\n\n.panel-warning > .panel-footer + .panel-collapse .panel-body {\n  border-bottom-color: #faebcc;\n}\n\n.panel-danger {\n  border-color: #ebccd1;\n}\n\n.panel-danger > .panel-heading {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #ebccd1;\n}\n\n.panel-danger > .panel-heading + .panel-collapse .panel-body {\n  border-top-color: #ebccd1;\n}\n\n.panel-danger > .panel-footer + .panel-collapse .panel-body {\n  border-bottom-color: #ebccd1;\n}\n\n.panel-info {\n  border-color: #bce8f1;\n}\n\n.panel-info > .panel-heading {\n  color: #31708f;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n\n.panel-info > .panel-heading + .panel-collapse .panel-body {\n  border-top-color: #bce8f1;\n}\n\n.panel-info > .panel-footer + .panel-collapse .panel-body {\n  border-bottom-color: #bce8f1;\n}\n\n.well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n\n.well blockquote {\n  border-color: #ddd;\n  border-color: rgba(0, 0, 0, 0.15);\n}\n\n.well-lg {\n  padding: 24px;\n  border-radius: 6px;\n}\n\n.well-sm {\n  padding: 9px;\n  border-radius: 3px;\n}\n\n.close {\n  float: right;\n  font-size: 21px;\n  font-weight: bold;\n  line-height: 1;\n  color: #000000;\n  text-shadow: 0 1px 0 #ffffff;\n  opacity: 0.2;\n  filter: alpha(opacity=20);\n}\n\n.close:hover,\n.close:focus {\n  color: #000000;\n  text-decoration: none;\n  cursor: pointer;\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\n\nbutton.close {\n  padding: 0;\n  cursor: pointer;\n  background: transparent;\n  border: 0;\n  -webkit-appearance: none;\n}\n\n.modal-open {\n  overflow: hidden;\n}\n\n.modal {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1040;\n  display: none;\n  overflow: auto;\n  overflow-y: scroll;\n}\n\n.modal.fade .modal-dialog {\n  -webkit-transform: translate(0, -25%);\n      -ms-transform: translate(0, -25%);\n          transform: translate(0, -25%);\n  -webkit-transition: -webkit-transform 0.3s ease-out;\n     -moz-transition: -moz-transform 0.3s ease-out;\n       -o-transition: -o-transform 0.3s ease-out;\n          transition: transform 0.3s ease-out;\n}\n\n.modal.in .modal-dialog {\n  -webkit-transform: translate(0, 0);\n      -ms-transform: translate(0, 0);\n          transform: translate(0, 0);\n}\n\n.modal-dialog {\n  position: relative;\n  z-index: 1050;\n  width: auto;\n  margin: 10px;\n}\n\n.modal-content {\n  position: relative;\n  background-color: #ffffff;\n  border: 1px solid #999999;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 6px;\n  outline: none;\n  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n          box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n  background-clip: padding-box;\n}\n\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1030;\n  background-color: #000000;\n}\n\n.modal-backdrop.fade {\n  opacity: 0;\n  filter: alpha(opacity=0);\n}\n\n.modal-backdrop.in {\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\n\n.modal-header {\n  min-height: 16.428571429px;\n  padding: 15px;\n  border-bottom: 1px solid #e5e5e5;\n}\n\n.modal-header .close {\n  margin-top: -2px;\n}\n\n.modal-title {\n  margin: 0;\n  line-height: 1.428571429;\n}\n\n.modal-body {\n  position: relative;\n  padding: 20px;\n}\n\n.modal-footer {\n  padding: 19px 20px 20px;\n  margin-top: 15px;\n  text-align: right;\n  border-top: 1px solid #e5e5e5;\n}\n\n.modal-footer:before,\n.modal-footer:after {\n  display: table;\n  content: \" \";\n}\n\n.modal-footer:after {\n  clear: both;\n}\n\n.modal-footer:before,\n.modal-footer:after {\n  display: table;\n  content: \" \";\n}\n\n.modal-footer:after {\n  clear: both;\n}\n\n.modal-footer .btn + .btn {\n  margin-bottom: 0;\n  margin-left: 5px;\n}\n\n.modal-footer .btn-group .btn + .btn {\n  margin-left: -1px;\n}\n\n.modal-footer .btn-block + .btn-block {\n  margin-left: 0;\n}\n\n@media screen and (min-width: 768px) {\n  .modal-dialog {\n    width: 600px;\n    margin: 30px auto;\n  }\n  .modal-content {\n    -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n  }\n}\n\n.tooltip {\n  position: absolute;\n  z-index: 1030;\n  display: block;\n  font-size: 12px;\n  line-height: 1.4;\n  opacity: 0;\n  filter: alpha(opacity=0);\n  visibility: visible;\n}\n\n.tooltip.in {\n  opacity: 0.9;\n  filter: alpha(opacity=90);\n}\n\n.tooltip.top {\n  padding: 5px 0;\n  margin-top: -3px;\n}\n\n.tooltip.right {\n  padding: 0 5px;\n  margin-left: 3px;\n}\n\n.tooltip.bottom {\n  padding: 5px 0;\n  margin-top: 3px;\n}\n\n.tooltip.left {\n  padding: 0 5px;\n  margin-left: -3px;\n}\n\n.tooltip-inner {\n  max-width: 200px;\n  padding: 3px 8px;\n  color: #ffffff;\n  text-align: center;\n  text-decoration: none;\n  background-color: #000000;\n  border-radius: 4px;\n}\n\n.tooltip-arrow {\n  position: absolute;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n\n.tooltip.top .tooltip-arrow {\n  bottom: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-top-color: #000000;\n  border-width: 5px 5px 0;\n}\n\n.tooltip.top-left .tooltip-arrow {\n  bottom: 0;\n  left: 5px;\n  border-top-color: #000000;\n  border-width: 5px 5px 0;\n}\n\n.tooltip.top-right .tooltip-arrow {\n  right: 5px;\n  bottom: 0;\n  border-top-color: #000000;\n  border-width: 5px 5px 0;\n}\n\n.tooltip.right .tooltip-arrow {\n  top: 50%;\n  left: 0;\n  margin-top: -5px;\n  border-right-color: #000000;\n  border-width: 5px 5px 5px 0;\n}\n\n.tooltip.left .tooltip-arrow {\n  top: 50%;\n  right: 0;\n  margin-top: -5px;\n  border-left-color: #000000;\n  border-width: 5px 0 5px 5px;\n}\n\n.tooltip.bottom .tooltip-arrow {\n  top: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-bottom-color: #000000;\n  border-width: 0 5px 5px;\n}\n\n.tooltip.bottom-left .tooltip-arrow {\n  top: 0;\n  left: 5px;\n  border-bottom-color: #000000;\n  border-width: 0 5px 5px;\n}\n\n.tooltip.bottom-right .tooltip-arrow {\n  top: 0;\n  right: 5px;\n  border-bottom-color: #000000;\n  border-width: 0 5px 5px;\n}\n\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 1010;\n  display: none;\n  max-width: 276px;\n  padding: 1px;\n  text-align: left;\n  white-space: normal;\n  background-color: #ffffff;\n  border: 1px solid #cccccc;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 6px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n          box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  background-clip: padding-box;\n}\n\n.popover.top {\n  margin-top: -10px;\n}\n\n.popover.right {\n  margin-left: 10px;\n}\n\n.popover.bottom {\n  margin-top: 10px;\n}\n\n.popover.left {\n  margin-left: -10px;\n}\n\n.popover-title {\n  padding: 8px 14px;\n  margin: 0;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 18px;\n  background-color: #f7f7f7;\n  border-bottom: 1px solid #ebebeb;\n  border-radius: 5px 5px 0 0;\n}\n\n.popover-content {\n  padding: 9px 14px;\n}\n\n.popover .arrow,\n.popover .arrow:after {\n  position: absolute;\n  display: block;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n\n.popover .arrow {\n  border-width: 11px;\n}\n\n.popover .arrow:after {\n  border-width: 10px;\n  content: \"\";\n}\n\n.popover.top .arrow {\n  bottom: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-top-color: #999999;\n  border-top-color: rgba(0, 0, 0, 0.25);\n  border-bottom-width: 0;\n}\n\n.popover.top .arrow:after {\n  bottom: 1px;\n  margin-left: -10px;\n  border-top-color: #ffffff;\n  border-bottom-width: 0;\n  content: \" \";\n}\n\n.popover.right .arrow {\n  top: 50%;\n  left: -11px;\n  margin-top: -11px;\n  border-right-color: #999999;\n  border-right-color: rgba(0, 0, 0, 0.25);\n  border-left-width: 0;\n}\n\n.popover.right .arrow:after {\n  bottom: -10px;\n  left: 1px;\n  border-right-color: #ffffff;\n  border-left-width: 0;\n  content: \" \";\n}\n\n.popover.bottom .arrow {\n  top: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-bottom-color: #999999;\n  border-bottom-color: rgba(0, 0, 0, 0.25);\n  border-top-width: 0;\n}\n\n.popover.bottom .arrow:after {\n  top: 1px;\n  margin-left: -10px;\n  border-bottom-color: #ffffff;\n  border-top-width: 0;\n  content: \" \";\n}\n\n.popover.left .arrow {\n  top: 50%;\n  right: -11px;\n  margin-top: -11px;\n  border-left-color: #999999;\n  border-left-color: rgba(0, 0, 0, 0.25);\n  border-right-width: 0;\n}\n\n.popover.left .arrow:after {\n  right: 1px;\n  bottom: -10px;\n  border-left-color: #ffffff;\n  border-right-width: 0;\n  content: \" \";\n}\n\n.carousel {\n  position: relative;\n}\n\n.carousel-inner {\n  position: relative;\n  width: 100%;\n  overflow: hidden;\n}\n\n.carousel-inner > .item {\n  position: relative;\n  display: none;\n  -webkit-transition: 0.6s ease-in-out left;\n          transition: 0.6s ease-in-out left;\n}\n\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  display: block;\n  height: auto;\n  max-width: 100%;\n  line-height: 1;\n}\n\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  display: block;\n}\n\n.carousel-inner > .active {\n  left: 0;\n}\n\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  position: absolute;\n  top: 0;\n  width: 100%;\n}\n\n.carousel-inner > .next {\n  left: 100%;\n}\n\n.carousel-inner > .prev {\n  left: -100%;\n}\n\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n  left: 0;\n}\n\n.carousel-inner > .active.left {\n  left: -100%;\n}\n\n.carousel-inner > .active.right {\n  left: 100%;\n}\n\n.carousel-control {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  width: 15%;\n  font-size: 20px;\n  color: #ffffff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\n\n.carousel-control.left {\n  background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.5) 0), color-stop(rgba(0, 0, 0, 0.0001) 100%));\n  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5) 0, rgba(0, 0, 0, 0.0001) 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n\n.carousel-control.right {\n  right: 0;\n  left: auto;\n  background-image: -webkit-linear-gradient(left, color-stop(rgba(0, 0, 0, 0.0001) 0), color-stop(rgba(0, 0, 0, 0.5) 100%));\n  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001) 0, rgba(0, 0, 0, 0.5) 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n\n.carousel-control:hover,\n.carousel-control:focus {\n  color: #ffffff;\n  text-decoration: none;\n  outline: none;\n  opacity: 0.9;\n  filter: alpha(opacity=90);\n}\n\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n  position: absolute;\n  top: 50%;\n  z-index: 5;\n  display: inline-block;\n}\n\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n  left: 50%;\n}\n\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n  right: 50%;\n}\n\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n  width: 20px;\n  height: 20px;\n  margin-top: -10px;\n  margin-left: -10px;\n  font-family: serif;\n}\n\n.carousel-control .icon-prev:before {\n  content: '\\2039';\n}\n\n.carousel-control .icon-next:before {\n  content: '\\203a';\n}\n\n.carousel-indicators {\n  position: absolute;\n  bottom: 10px;\n  left: 50%;\n  z-index: 15;\n  width: 60%;\n  padding-left: 0;\n  margin-left: -30%;\n  text-align: center;\n  list-style: none;\n}\n\n.carousel-indicators li {\n  display: inline-block;\n  width: 10px;\n  height: 10px;\n  margin: 1px;\n  text-indent: -999px;\n  cursor: pointer;\n  background-color: #000 \\9;\n  background-color: rgba(0, 0, 0, 0);\n  border: 1px solid #ffffff;\n  border-radius: 10px;\n}\n\n.carousel-indicators .active {\n  width: 12px;\n  height: 12px;\n  margin: 0;\n  background-color: #ffffff;\n}\n\n.carousel-caption {\n  position: absolute;\n  right: 15%;\n  bottom: 20px;\n  left: 15%;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: #ffffff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n\n.carousel-caption .btn {\n  text-shadow: none;\n}\n\n@media screen and (min-width: 768px) {\n  .carousel-control .glyphicons-chevron-left,\n  .carousel-control .glyphicons-chevron-right,\n  .carousel-control .icon-prev,\n  .carousel-control .icon-next {\n    width: 30px;\n    height: 30px;\n    margin-top: -15px;\n    margin-left: -15px;\n    font-size: 30px;\n  }\n  .carousel-caption {\n    right: 20%;\n    left: 20%;\n    padding-bottom: 30px;\n  }\n  .carousel-indicators {\n    bottom: 20px;\n  }\n}\n\n.clearfix:before,\n.clearfix:after {\n  display: table;\n  content: \" \";\n}\n\n.clearfix:after {\n  clear: both;\n}\n\n.center-block {\n  display: block;\n  margin-right: auto;\n  margin-left: auto;\n}\n\n.pull-right {\n  float: right !important;\n}\n\n.pull-left {\n  float: left !important;\n}\n\n.hide {\n  display: none !important;\n}\n\n.show {\n  display: block !important;\n}\n\n.invisible {\n  visibility: hidden;\n}\n\n.text-hide {\n  font: 0/0 a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n\n.hidden {\n  display: none !important;\n  visibility: hidden !important;\n}\n\n.affix {\n  position: fixed;\n}\n\n@-ms-viewport {\n  width: device-width;\n}\n\n.visible-xs,\ntr.visible-xs,\nth.visible-xs,\ntd.visible-xs {\n  display: none !important;\n}\n\n@media (max-width: 767px) {\n  .visible-xs {\n    display: block !important;\n  }\n  table.visible-xs {\n    display: table;\n  }\n  tr.visible-xs {\n    display: table-row !important;\n  }\n  th.visible-xs,\n  td.visible-xs {\n    display: table-cell !important;\n  }\n}\n\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-xs.visible-sm {\n    display: block !important;\n  }\n  table.visible-xs.visible-sm {\n    display: table;\n  }\n  tr.visible-xs.visible-sm {\n    display: table-row !important;\n  }\n  th.visible-xs.visible-sm,\n  td.visible-xs.visible-sm {\n    display: table-cell !important;\n  }\n}\n\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-xs.visible-md {\n    display: block !important;\n  }\n  table.visible-xs.visible-md {\n    display: table;\n  }\n  tr.visible-xs.visible-md {\n    display: table-row !important;\n  }\n  th.visible-xs.visible-md,\n  td.visible-xs.visible-md {\n    display: table-cell !important;\n  }\n}\n\n@media (min-width: 1200px) {\n  .visible-xs.visible-lg {\n    display: block !important;\n  }\n  table.visible-xs.visible-lg {\n    display: table;\n  }\n  tr.visible-xs.visible-lg {\n    display: table-row !important;\n  }\n  th.visible-xs.visible-lg,\n  td.visible-xs.visible-lg {\n    display: table-cell !important;\n  }\n}\n\n.visible-sm,\ntr.visible-sm,\nth.visible-sm,\ntd.visible-sm {\n  display: none !important;\n}\n\n@media (max-width: 767px) {\n  .visible-sm.visible-xs {\n    display: block !important;\n  }\n  table.visible-sm.visible-xs {\n    display: table;\n  }\n  tr.visible-sm.visible-xs {\n    display: table-row !important;\n  }\n  th.visible-sm.visible-xs,\n  td.visible-sm.visible-xs {\n    display: table-cell !important;\n  }\n}\n\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm {\n    display: block !important;\n  }\n  table.visible-sm {\n    display: table;\n  }\n  tr.visible-sm {\n    display: table-row !important;\n  }\n  th.visible-sm,\n  td.visible-sm {\n    display: table-cell !important;\n  }\n}\n\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-sm.visible-md {\n    display: block !important;\n  }\n  table.visible-sm.visible-md {\n    display: table;\n  }\n  tr.visible-sm.visible-md {\n    display: table-row !important;\n  }\n  th.visible-sm.visible-md,\n  td.visible-sm.visible-md {\n    display: table-cell !important;\n  }\n}\n\n@media (min-width: 1200px) {\n  .visible-sm.visible-lg {\n    display: block !important;\n  }\n  table.visible-sm.visible-lg {\n    display: table;\n  }\n  tr.visible-sm.visible-lg {\n    display: table-row !important;\n  }\n  th.visible-sm.visible-lg,\n  td.visible-sm.visible-lg {\n    display: table-cell !important;\n  }\n}\n\n.visible-md,\ntr.visible-md,\nth.visible-md,\ntd.visible-md {\n  display: none !important;\n}\n\n@media (max-width: 767px) {\n  .visible-md.visible-xs {\n    display: block !important;\n  }\n  table.visible-md.visible-xs {\n    display: table;\n  }\n  tr.visible-md.visible-xs {\n    display: table-row !important;\n  }\n  th.visible-md.visible-xs,\n  td.visible-md.visible-xs {\n    display: table-cell !important;\n  }\n}\n\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-md.visible-sm {\n    display: block !important;\n  }\n  table.visible-md.visible-sm {\n    display: table;\n  }\n  tr.visible-md.visible-sm {\n    display: table-row !important;\n  }\n  th.visible-md.visible-sm,\n  td.visible-md.visible-sm {\n    display: table-cell !important;\n  }\n}\n\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md {\n    display: block !important;\n  }\n  table.visible-md {\n    display: table;\n  }\n  tr.visible-md {\n    display: table-row !important;\n  }\n  th.visible-md,\n  td.visible-md {\n    display: table-cell !important;\n  }\n}\n\n@media (min-width: 1200px) {\n  .visible-md.visible-lg {\n    display: block !important;\n  }\n  table.visible-md.visible-lg {\n    display: table;\n  }\n  tr.visible-md.visible-lg {\n    display: table-row !important;\n  }\n  th.visible-md.visible-lg,\n  td.visible-md.visible-lg {\n    display: table-cell !important;\n  }\n}\n\n.visible-lg,\ntr.visible-lg,\nth.visible-lg,\ntd.visible-lg {\n  display: none !important;\n}\n\n@media (max-width: 767px) {\n  .visible-lg.visible-xs {\n    display: block !important;\n  }\n  table.visible-lg.visible-xs {\n    display: table;\n  }\n  tr.visible-lg.visible-xs {\n    display: table-row !important;\n  }\n  th.visible-lg.visible-xs,\n  td.visible-lg.visible-xs {\n    display: table-cell !important;\n  }\n}\n\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-lg.visible-sm {\n    display: block !important;\n  }\n  table.visible-lg.visible-sm {\n    display: table;\n  }\n  tr.visible-lg.visible-sm {\n    display: table-row !important;\n  }\n  th.visible-lg.visible-sm,\n  td.visible-lg.visible-sm {\n    display: table-cell !important;\n  }\n}\n\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-lg.visible-md {\n    display: block !important;\n  }\n  table.visible-lg.visible-md {\n    display: table;\n  }\n  tr.visible-lg.visible-md {\n    display: table-row !important;\n  }\n  th.visible-lg.visible-md,\n  td.visible-lg.visible-md {\n    display: table-cell !important;\n  }\n}\n\n@media (min-width: 1200px) {\n  .visible-lg {\n    display: block !important;\n  }\n  table.visible-lg {\n    display: table;\n  }\n  tr.visible-lg {\n    display: table-row !important;\n  }\n  th.visible-lg,\n  td.visible-lg {\n    display: table-cell !important;\n  }\n}\n\n.hidden-xs {\n  display: block !important;\n}\n\ntable.hidden-xs {\n  display: table;\n}\n\ntr.hidden-xs {\n  display: table-row !important;\n}\n\nth.hidden-xs,\ntd.hidden-xs {\n  display: table-cell !important;\n}\n\n@media (max-width: 767px) {\n  .hidden-xs,\n  tr.hidden-xs,\n  th.hidden-xs,\n  td.hidden-xs {\n    display: none !important;\n  }\n}\n\n@media (min-width: 768px) and (max-width: 991px) {\n  .hidden-xs.hidden-sm,\n  tr.hidden-xs.hidden-sm,\n  th.hidden-xs.hidden-sm,\n  td.hidden-xs.hidden-sm {\n    display: none !important;\n  }\n}\n\n@media (min-width: 992px) and (max-width: 1199px) {\n  .hidden-xs.hidden-md,\n  tr.hidden-xs.hidden-md,\n  th.hidden-xs.hidden-md,\n  td.hidden-xs.hidden-md {\n    display: none !important;\n  }\n}\n\n@media (min-width: 1200px) {\n  .hidden-xs.hidden-lg,\n  tr.hidden-xs.hidden-lg,\n  th.hidden-xs.hidden-lg,\n  td.hidden-xs.hidden-lg {\n    display: none !important;\n  }\n}\n\n.hidden-sm {\n  display: block !important;\n}\n\ntable.hidden-sm {\n  display: table;\n}\n\ntr.hidden-sm {\n  display: table-row !important;\n}\n\nth.hidden-sm,\ntd.hidden-sm {\n  display: table-cell !important;\n}\n\n@media (max-width: 767px) {\n  .hidden-sm.hidden-xs,\n  tr.hidden-sm.hidden-xs,\n  th.hidden-sm.hidden-xs,\n  td.hidden-sm.hidden-xs {\n    display: none !important;\n  }\n}\n\n@media (min-width: 768px) and (max-width: 991px) {\n  .hidden-sm,\n  tr.hidden-sm,\n  th.hidden-sm,\n  td.hidden-sm {\n    display: none !important;\n  }\n}\n\n@media (min-width: 992px) and (max-width: 1199px) {\n  .hidden-sm.hidden-md,\n  tr.hidden-sm.hidden-md,\n  th.hidden-sm.hidden-md,\n  td.hidden-sm.hidden-md {\n    display: none !important;\n  }\n}\n\n@media (min-width: 1200px) {\n  .hidden-sm.hidden-lg,\n  tr.hidden-sm.hidden-lg,\n  th.hidden-sm.hidden-lg,\n  td.hidden-sm.hidden-lg {\n    display: none !important;\n  }\n}\n\n.hidden-md {\n  display: block !important;\n}\n\ntable.hidden-md {\n  display: table;\n}\n\ntr.hidden-md {\n  display: table-row !important;\n}\n\nth.hidden-md,\ntd.hidden-md {\n  display: table-cell !important;\n}\n\n@media (max-width: 767px) {\n  .hidden-md.hidden-xs,\n  tr.hidden-md.hidden-xs,\n  th.hidden-md.hidden-xs,\n  td.hidden-md.hidden-xs {\n    display: none !important;\n  }\n}\n\n@media (min-width: 768px) and (max-width: 991px) {\n  .hidden-md.hidden-sm,\n  tr.hidden-md.hidden-sm,\n  th.hidden-md.hidden-sm,\n  td.hidden-md.hidden-sm {\n    display: none !important;\n  }\n}\n\n@media (min-width: 992px) and (max-width: 1199px) {\n  .hidden-md,\n  tr.hidden-md,\n  th.hidden-md,\n  td.hidden-md {\n    display: none !important;\n  }\n}\n\n@media (min-width: 1200px) {\n  .hidden-md.hidden-lg,\n  tr.hidden-md.hidden-lg,\n  th.hidden-md.hidden-lg,\n  td.hidden-md.hidden-lg {\n    display: none !important;\n  }\n}\n\n.hidden-lg {\n  display: block !important;\n}\n\ntable.hidden-lg {\n  display: table;\n}\n\ntr.hidden-lg {\n  display: table-row !important;\n}\n\nth.hidden-lg,\ntd.hidden-lg {\n  display: table-cell !important;\n}\n\n@media (max-width: 767px) {\n  .hidden-lg.hidden-xs,\n  tr.hidden-lg.hidden-xs,\n  th.hidden-lg.hidden-xs,\n  td.hidden-lg.hidden-xs {\n    display: none !important;\n  }\n}\n\n@media (min-width: 768px) and (max-width: 991px) {\n  .hidden-lg.hidden-sm,\n  tr.hidden-lg.hidden-sm,\n  th.hidden-lg.hidden-sm,\n  td.hidden-lg.hidden-sm {\n    display: none !important;\n  }\n}\n\n@media (min-width: 992px) and (max-width: 1199px) {\n  .hidden-lg.hidden-md,\n  tr.hidden-lg.hidden-md,\n  th.hidden-lg.hidden-md,\n  td.hidden-lg.hidden-md {\n    display: none !important;\n  }\n}\n\n@media (min-width: 1200px) {\n  .hidden-lg,\n  tr.hidden-lg,\n  th.hidden-lg,\n  td.hidden-lg {\n    display: none !important;\n  }\n}\n\n.visible-print,\ntr.visible-print,\nth.visible-print,\ntd.visible-print {\n  display: none !important;\n}\n\n@media print {\n  .visible-print {\n    display: block !important;\n  }\n  table.visible-print {\n    display: table;\n  }\n  tr.visible-print {\n    display: table-row !important;\n  }\n  th.visible-print,\n  td.visible-print {\n    display: table-cell !important;\n  }\n  .hidden-print,\n  tr.hidden-print,\n  th.hidden-print,\n  td.hidden-print {\n    display: none !important;\n  }\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/dist/js/bootstrap.js",
    "content": "/*!\n * Bootstrap v3.0.3 (http://getbootstrap.com)\n * Copyright 2013 Twitter, Inc.\n * Licensed under http://www.apache.org/licenses/LICENSE-2.0\n */\n\nif (typeof jQuery === \"undefined\") { throw new Error(\"Bootstrap requires jQuery\") }\n\n/* ========================================================================\n * Bootstrap: transition.js v3.0.3\n * http://getbootstrap.com/javascript/#transitions\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  function transitionEnd() {\n    var el = document.createElement('bootstrap')\n\n    var transEndEventNames = {\n      'WebkitTransition' : 'webkitTransitionEnd'\n    , 'MozTransition'    : 'transitionend'\n    , 'OTransition'      : 'oTransitionEnd otransitionend'\n    , 'transition'       : 'transitionend'\n    }\n\n    for (var name in transEndEventNames) {\n      if (el.style[name] !== undefined) {\n        return { end: transEndEventNames[name] }\n      }\n    }\n  }\n  $.fn.emulateTransitionEnd = function (duration) {\n    var called = false, $el = this\n    $(this).one($.support.transition.end, function () { called = true })\n    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }\n    setTimeout(callback, duration)\n    return this\n  }\n\n  $(function () {\n    $.support.transition = transitionEnd()\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: alert.js v3.0.3\n * http://getbootstrap.com/javascript/#alerts\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var dismiss = '[data-dismiss=\"alert\"]'\n  var Alert   = function (el) {\n    $(el).on('click', dismiss, this.close)\n  }\n\n  Alert.prototype.close = function (e) {\n    var $this    = $(this)\n    var selector = $this.attr('data-target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    var $parent = $(selector)\n\n    if (e) e.preventDefault()\n\n    if (!$parent.length) {\n      $parent = $this.hasClass('alert') ? $this : $this.parent()\n    }\n\n    $parent.trigger(e = $.Event('close.bs.alert'))\n\n    if (e.isDefaultPrevented()) return\n\n    $parent.removeClass('in')\n\n    function removeElement() {\n      $parent.trigger('closed.bs.alert').remove()\n    }\n\n    $.support.transition && $parent.hasClass('fade') ?\n      $parent\n        .one($.support.transition.end, removeElement)\n        .emulateTransitionEnd(150) :\n      removeElement()\n  }\n\n  var old = $.fn.alert\n\n  $.fn.alert = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.alert')\n\n      if (!data) $this.data('bs.alert', (data = new Alert(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  $.fn.alert.Constructor = Alert\n\n  $.fn.alert.noConflict = function () {\n    $.fn.alert = old\n    return this\n  }\n\n  $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: button.js v3.0.3\n * http://getbootstrap.com/javascript/#buttons\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var Button = function (element, options) {\n    this.$element = $(element)\n    this.options  = $.extend({}, Button.DEFAULTS, options)\n  }\n\n  Button.DEFAULTS = {\n    loadingText: 'loading...'\n  }\n\n  Button.prototype.setState = function (state) {\n    var d    = 'disabled'\n    var $el  = this.$element\n    var val  = $el.is('input') ? 'val' : 'html'\n    var data = $el.data()\n\n    state = state + 'Text'\n\n    if (!data.resetText) $el.data('resetText', $el[val]())\n\n    $el[val](data[state] || this.options[state])\n    setTimeout(function () {\n      state == 'loadingText' ?\n        $el.addClass(d).attr(d, d) :\n        $el.removeClass(d).removeAttr(d);\n    }, 0)\n  }\n\n  Button.prototype.toggle = function () {\n    var $parent = this.$element.closest('[data-toggle=\"buttons\"]')\n    var changed = true\n\n    if ($parent.length) {\n      var $input = this.$element.find('input')\n      if ($input.prop('type') === 'radio') {\n        if ($input.prop('checked') && this.$element.hasClass('active'))\n          changed = false\n        else\n          $parent.find('.active').removeClass('active')\n      }\n      if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')\n    }\n\n    if (changed) this.$element.toggleClass('active')\n  }\n\n  var old = $.fn.button\n\n  $.fn.button = function (option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.button')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.button', (data = new Button(this, options)))\n\n      if (option == 'toggle') data.toggle()\n      else if (option) data.setState(option)\n    })\n  }\n\n  $.fn.button.Constructor = Button\n\n  $.fn.button.noConflict = function () {\n    $.fn.button = old\n    return this\n  }\n\n  $(document).on('click.bs.button.data-api', '[data-toggle^=button]', function (e) {\n    var $btn = $(e.target)\n    if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')\n    $btn.button('toggle')\n    e.preventDefault()\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: carousel.js v3.0.3\n * http://getbootstrap.com/javascript/#carousel\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var Carousel = function (element, options) {\n    this.$element    = $(element)\n    this.$indicators = this.$element.find('.carousel-indicators')\n    this.options     = options\n    this.paused      =\n    this.sliding     =\n    this.interval    =\n    this.$active     =\n    this.$items      = null\n\n    this.options.pause == 'hover' && this.$element\n      .on('mouseenter', $.proxy(this.pause, this))\n      .on('mouseleave', $.proxy(this.cycle, this))\n  }\n\n  Carousel.DEFAULTS = {\n    interval: 5000\n  , pause: 'hover'\n  , wrap: true\n  }\n\n  Carousel.prototype.cycle =  function (e) {\n    e || (this.paused = false)\n\n    this.interval && clearInterval(this.interval)\n\n    this.options.interval\n      && !this.paused\n      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))\n\n    return this\n  }\n\n  Carousel.prototype.getActiveIndex = function () {\n    this.$active = this.$element.find('.item.active')\n    this.$items  = this.$active.parent().children()\n\n    return this.$items.index(this.$active)\n  }\n\n  Carousel.prototype.to = function (pos) {\n    var that        = this\n    var activeIndex = this.getActiveIndex()\n\n    if (pos > (this.$items.length - 1) || pos < 0) return\n\n    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) })\n    if (activeIndex == pos) return this.pause().cycle()\n\n    return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))\n  }\n\n  Carousel.prototype.pause = function (e) {\n    e || (this.paused = true)\n\n    if (this.$element.find('.next, .prev').length && $.support.transition.end) {\n      this.$element.trigger($.support.transition.end)\n      this.cycle(true)\n    }\n\n    this.interval = clearInterval(this.interval)\n\n    return this\n  }\n\n  Carousel.prototype.next = function () {\n    if (this.sliding) return\n    return this.slide('next')\n  }\n\n  Carousel.prototype.prev = function () {\n    if (this.sliding) return\n    return this.slide('prev')\n  }\n\n  Carousel.prototype.slide = function (type, next) {\n    var $active   = this.$element.find('.item.active')\n    var $next     = next || $active[type]()\n    var isCycling = this.interval\n    var direction = type == 'next' ? 'left' : 'right'\n    var fallback  = type == 'next' ? 'first' : 'last'\n    var that      = this\n\n    if (!$next.length) {\n      if (!this.options.wrap) return\n      $next = this.$element.find('.item')[fallback]()\n    }\n\n    this.sliding = true\n\n    isCycling && this.pause()\n\n    var e = $.Event('slide.bs.carousel', { relatedTarget: $next[0], direction: direction })\n\n    if ($next.hasClass('active')) return\n\n    if (this.$indicators.length) {\n      this.$indicators.find('.active').removeClass('active')\n      this.$element.one('slid.bs.carousel', function () {\n        var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])\n        $nextIndicator && $nextIndicator.addClass('active')\n      })\n    }\n\n    if ($.support.transition && this.$element.hasClass('slide')) {\n      this.$element.trigger(e)\n      if (e.isDefaultPrevented()) return\n      $next.addClass(type)\n      $next[0].offsetWidth // force reflow\n      $active.addClass(direction)\n      $next.addClass(direction)\n      $active\n        .one($.support.transition.end, function () {\n          $next.removeClass([type, direction].join(' ')).addClass('active')\n          $active.removeClass(['active', direction].join(' '))\n          that.sliding = false\n          setTimeout(function () { that.$element.trigger('slid.bs.carousel') }, 0)\n        })\n        .emulateTransitionEnd(600)\n    } else {\n      this.$element.trigger(e)\n      if (e.isDefaultPrevented()) return\n      $active.removeClass('active')\n      $next.addClass('active')\n      this.sliding = false\n      this.$element.trigger('slid.bs.carousel')\n    }\n\n    isCycling && this.cycle()\n\n    return this\n  }\n\n  var old = $.fn.carousel\n\n  $.fn.carousel = function (option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.carousel')\n      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)\n      var action  = typeof option == 'string' ? option : options.slide\n\n      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))\n      if (typeof option == 'number') data.to(option)\n      else if (action) data[action]()\n      else if (options.interval) data.pause().cycle()\n    })\n  }\n\n  $.fn.carousel.Constructor = Carousel\n\n  $.fn.carousel.noConflict = function () {\n    $.fn.carousel = old\n    return this\n  }\n\n  $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {\n    var $this   = $(this), href\n    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) //strip for ie7\n    var options = $.extend({}, $target.data(), $this.data())\n    var slideIndex = $this.attr('data-slide-to')\n    if (slideIndex) options.interval = false\n\n    $target.carousel(options)\n\n    if (slideIndex = $this.attr('data-slide-to')) {\n      $target.data('bs.carousel').to(slideIndex)\n    }\n\n    e.preventDefault()\n  })\n\n  $(window).on('load', function () {\n    $('[data-ride=\"carousel\"]').each(function () {\n      var $carousel = $(this)\n      $carousel.carousel($carousel.data())\n    })\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: collapse.js v3.0.3\n * http://getbootstrap.com/javascript/#collapse\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var Collapse = function (element, options) {\n    this.$element      = $(element)\n    this.options       = $.extend({}, Collapse.DEFAULTS, options)\n    this.transitioning = null\n\n    if (this.options.parent) this.$parent = $(this.options.parent)\n    if (this.options.toggle) this.toggle()\n  }\n\n  Collapse.DEFAULTS = {\n    toggle: true\n  }\n\n  Collapse.prototype.dimension = function () {\n    var hasWidth = this.$element.hasClass('width')\n    return hasWidth ? 'width' : 'height'\n  }\n\n  Collapse.prototype.show = function () {\n    if (this.transitioning || this.$element.hasClass('in')) return\n\n    var startEvent = $.Event('show.bs.collapse')\n    this.$element.trigger(startEvent)\n    if (startEvent.isDefaultPrevented()) return\n\n    var actives = this.$parent && this.$parent.find('> .panel > .in')\n\n    if (actives && actives.length) {\n      var hasData = actives.data('bs.collapse')\n      if (hasData && hasData.transitioning) return\n      actives.collapse('hide')\n      hasData || actives.data('bs.collapse', null)\n    }\n\n    var dimension = this.dimension()\n\n    this.$element\n      .removeClass('collapse')\n      .addClass('collapsing')\n      [dimension](0)\n\n    this.transitioning = 1\n\n    var complete = function () {\n      this.$element\n        .removeClass('collapsing')\n        .addClass('in')\n        [dimension]('auto')\n      this.transitioning = 0\n      this.$element.trigger('shown.bs.collapse')\n    }\n\n    if (!$.support.transition) return complete.call(this)\n\n    var scrollSize = $.camelCase(['scroll', dimension].join('-'))\n\n    this.$element\n      .one($.support.transition.end, $.proxy(complete, this))\n      .emulateTransitionEnd(350)\n      [dimension](this.$element[0][scrollSize])\n  }\n\n  Collapse.prototype.hide = function () {\n    if (this.transitioning || !this.$element.hasClass('in')) return\n\n    var startEvent = $.Event('hide.bs.collapse')\n    this.$element.trigger(startEvent)\n    if (startEvent.isDefaultPrevented()) return\n\n    var dimension = this.dimension()\n\n    this.$element\n      [dimension](this.$element[dimension]())\n      [0].offsetHeight\n\n    this.$element\n      .addClass('collapsing')\n      .removeClass('collapse')\n      .removeClass('in')\n\n    this.transitioning = 1\n\n    var complete = function () {\n      this.transitioning = 0\n      this.$element\n        .trigger('hidden.bs.collapse')\n        .removeClass('collapsing')\n        .addClass('collapse')\n    }\n\n    if (!$.support.transition) return complete.call(this)\n\n    this.$element\n      [dimension](0)\n      .one($.support.transition.end, $.proxy(complete, this))\n      .emulateTransitionEnd(350)\n  }\n\n  Collapse.prototype.toggle = function () {\n    this[this.$element.hasClass('in') ? 'hide' : 'show']()\n  }\n\n  var old = $.fn.collapse\n\n  $.fn.collapse = function (option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.collapse')\n      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.collapse.Constructor = Collapse\n\n  $.fn.collapse.noConflict = function () {\n    $.fn.collapse = old\n    return this\n  }\n\n  $(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) {\n    var $this   = $(this), href\n    var target  = $this.attr('data-target')\n        || e.preventDefault()\n        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '') //strip for ie7\n    var $target = $(target)\n    var data    = $target.data('bs.collapse')\n    var option  = data ? 'toggle' : $this.data()\n    var parent  = $this.attr('data-parent')\n    var $parent = parent && $(parent)\n\n    if (!data || !data.transitioning) {\n      if ($parent) $parent.find('[data-toggle=collapse][data-parent=\"' + parent + '\"]').not($this).addClass('collapsed')\n      $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')\n    }\n\n    $target.collapse(option)\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: dropdown.js v3.0.3\n * http://getbootstrap.com/javascript/#dropdowns\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var backdrop = '.dropdown-backdrop'\n  var toggle   = '[data-toggle=dropdown]'\n  var Dropdown = function (element) {\n    $(element).on('click.bs.dropdown', this.toggle)\n  }\n\n  Dropdown.prototype.toggle = function (e) {\n    var $this = $(this)\n\n    if ($this.is('.disabled, :disabled')) return\n\n    var $parent  = getParent($this)\n    var isActive = $parent.hasClass('open')\n\n    clearMenus()\n\n    if (!isActive) {\n      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {\n        $('<div class=\"dropdown-backdrop\"/>').insertAfter($(this)).on('click', clearMenus)\n      }\n\n      $parent.trigger(e = $.Event('show.bs.dropdown'))\n\n      if (e.isDefaultPrevented()) return\n\n      $parent\n        .toggleClass('open')\n        .trigger('shown.bs.dropdown')\n\n      $this.focus()\n    }\n\n    return false\n  }\n\n  Dropdown.prototype.keydown = function (e) {\n    if (!/(38|40|27)/.test(e.keyCode)) return\n\n    var $this = $(this)\n\n    e.preventDefault()\n    e.stopPropagation()\n\n    if ($this.is('.disabled, :disabled')) return\n\n    var $parent  = getParent($this)\n    var isActive = $parent.hasClass('open')\n\n    if (!isActive || (isActive && e.keyCode == 27)) {\n      if (e.which == 27) $parent.find(toggle).focus()\n      return $this.click()\n    }\n\n    var $items = $('[role=menu] li:not(.divider):visible a', $parent)\n\n    if (!$items.length) return\n\n    var index = $items.index($items.filter(':focus'))\n\n    if (e.keyCode == 38 && index > 0)                 index--                        // up\n    if (e.keyCode == 40 && index < $items.length - 1) index++                        // down\n    if (!~index)                                      index=0\n\n    $items.eq(index).focus()\n  }\n\n  function clearMenus() {\n    $(backdrop).remove()\n    $(toggle).each(function (e) {\n      var $parent = getParent($(this))\n      if (!$parent.hasClass('open')) return\n      $parent.trigger(e = $.Event('hide.bs.dropdown'))\n      if (e.isDefaultPrevented()) return\n      $parent.removeClass('open').trigger('hidden.bs.dropdown')\n    })\n  }\n\n  function getParent($this) {\n    var selector = $this.attr('data-target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\\s]*$)/, '') //strip for ie7\n    }\n\n    var $parent = selector && $(selector)\n\n    return $parent && $parent.length ? $parent : $this.parent()\n  }\n\n  var old = $.fn.dropdown\n\n  $.fn.dropdown = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.dropdown')\n\n      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  $.fn.dropdown.Constructor = Dropdown\n\n  $.fn.dropdown.noConflict = function () {\n    $.fn.dropdown = old\n    return this\n  }\n\n  $(document)\n    .on('click.bs.dropdown.data-api', clearMenus)\n    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })\n    .on('click.bs.dropdown.data-api'  , toggle, Dropdown.prototype.toggle)\n    .on('keydown.bs.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: modal.js v3.0.3\n * http://getbootstrap.com/javascript/#modals\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var Modal = function (element, options) {\n    this.options   = options\n    this.$element  = $(element)\n    this.$backdrop =\n    this.isShown   = null\n\n    if (this.options.remote) this.$element.load(this.options.remote)\n  }\n\n  Modal.DEFAULTS = {\n      backdrop: true\n    , keyboard: true\n    , show: true\n  }\n\n  Modal.prototype.toggle = function (_relatedTarget) {\n    return this[!this.isShown ? 'show' : 'hide'](_relatedTarget)\n  }\n\n  Modal.prototype.show = function (_relatedTarget) {\n    var that = this\n    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })\n\n    this.$element.trigger(e)\n\n    if (this.isShown || e.isDefaultPrevented()) return\n\n    this.isShown = true\n\n    this.escape()\n\n    this.$element.on('click.dismiss.modal', '[data-dismiss=\"modal\"]', $.proxy(this.hide, this))\n\n    this.backdrop(function () {\n      var transition = $.support.transition && that.$element.hasClass('fade')\n\n      if (!that.$element.parent().length) {\n        that.$element.appendTo(document.body) // don't move modals dom position\n      }\n\n      that.$element.show()\n\n      if (transition) {\n        that.$element[0].offsetWidth // force reflow\n      }\n\n      that.$element\n        .addClass('in')\n        .attr('aria-hidden', false)\n\n      that.enforceFocus()\n\n      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })\n\n      transition ?\n        that.$element.find('.modal-dialog') // wait for modal to slide in\n          .one($.support.transition.end, function () {\n            that.$element.focus().trigger(e)\n          })\n          .emulateTransitionEnd(300) :\n        that.$element.focus().trigger(e)\n    })\n  }\n\n  Modal.prototype.hide = function (e) {\n    if (e) e.preventDefault()\n\n    e = $.Event('hide.bs.modal')\n\n    this.$element.trigger(e)\n\n    if (!this.isShown || e.isDefaultPrevented()) return\n\n    this.isShown = false\n\n    this.escape()\n\n    $(document).off('focusin.bs.modal')\n\n    this.$element\n      .removeClass('in')\n      .attr('aria-hidden', true)\n      .off('click.dismiss.modal')\n\n    $.support.transition && this.$element.hasClass('fade') ?\n      this.$element\n        .one($.support.transition.end, $.proxy(this.hideModal, this))\n        .emulateTransitionEnd(300) :\n      this.hideModal()\n  }\n\n  Modal.prototype.enforceFocus = function () {\n    $(document)\n      .off('focusin.bs.modal') // guard against infinite focus loop\n      .on('focusin.bs.modal', $.proxy(function (e) {\n        if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {\n          this.$element.focus()\n        }\n      }, this))\n  }\n\n  Modal.prototype.escape = function () {\n    if (this.isShown && this.options.keyboard) {\n      this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) {\n        e.which == 27 && this.hide()\n      }, this))\n    } else if (!this.isShown) {\n      this.$element.off('keyup.dismiss.bs.modal')\n    }\n  }\n\n  Modal.prototype.hideModal = function () {\n    var that = this\n    this.$element.hide()\n    this.backdrop(function () {\n      that.removeBackdrop()\n      that.$element.trigger('hidden.bs.modal')\n    })\n  }\n\n  Modal.prototype.removeBackdrop = function () {\n    this.$backdrop && this.$backdrop.remove()\n    this.$backdrop = null\n  }\n\n  Modal.prototype.backdrop = function (callback) {\n    var that    = this\n    var animate = this.$element.hasClass('fade') ? 'fade' : ''\n\n    if (this.isShown && this.options.backdrop) {\n      var doAnimate = $.support.transition && animate\n\n      this.$backdrop = $('<div class=\"modal-backdrop ' + animate + '\" />')\n        .appendTo(document.body)\n\n      this.$element.on('click.dismiss.modal', $.proxy(function (e) {\n        if (e.target !== e.currentTarget) return\n        this.options.backdrop == 'static'\n          ? this.$element[0].focus.call(this.$element[0])\n          : this.hide.call(this)\n      }, this))\n\n      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow\n\n      this.$backdrop.addClass('in')\n\n      if (!callback) return\n\n      doAnimate ?\n        this.$backdrop\n          .one($.support.transition.end, callback)\n          .emulateTransitionEnd(150) :\n        callback()\n\n    } else if (!this.isShown && this.$backdrop) {\n      this.$backdrop.removeClass('in')\n\n      $.support.transition && this.$element.hasClass('fade')?\n        this.$backdrop\n          .one($.support.transition.end, callback)\n          .emulateTransitionEnd(150) :\n        callback()\n\n    } else if (callback) {\n      callback()\n    }\n  }\n\n  var old = $.fn.modal\n\n  $.fn.modal = function (option, _relatedTarget) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.modal')\n      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))\n      if (typeof option == 'string') data[option](_relatedTarget)\n      else if (options.show) data.show(_relatedTarget)\n    })\n  }\n\n  $.fn.modal.Constructor = Modal\n\n  $.fn.modal.noConflict = function () {\n    $.fn.modal = old\n    return this\n  }\n\n  $(document).on('click.bs.modal.data-api', '[data-toggle=\"modal\"]', function (e) {\n    var $this   = $(this)\n    var href    = $this.attr('href')\n    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\\s]+$)/, ''))) //strip for ie7\n    var option  = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())\n\n    e.preventDefault()\n\n    $target\n      .modal(option, this)\n      .one('hide', function () {\n        $this.is(':visible') && $this.focus()\n      })\n  })\n\n  $(document)\n    .on('show.bs.modal',  '.modal', function () { $(document.body).addClass('modal-open') })\n    .on('hidden.bs.modal', '.modal', function () { $(document.body).removeClass('modal-open') })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tooltip.js v3.0.3\n * http://getbootstrap.com/javascript/#tooltip\n * Inspired by the original jQuery.tipsy by Jason Frame\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var Tooltip = function (element, options) {\n    this.type       =\n    this.options    =\n    this.enabled    =\n    this.timeout    =\n    this.hoverState =\n    this.$element   = null\n\n    this.init('tooltip', element, options)\n  }\n\n  Tooltip.DEFAULTS = {\n    animation: true\n  , placement: 'top'\n  , selector: false\n  , template: '<div class=\"tooltip\"><div class=\"tooltip-arrow\"></div><div class=\"tooltip-inner\"></div></div>'\n  , trigger: 'hover focus'\n  , title: ''\n  , delay: 0\n  , html: false\n  , container: false\n  }\n\n  Tooltip.prototype.init = function (type, element, options) {\n    this.enabled  = true\n    this.type     = type\n    this.$element = $(element)\n    this.options  = this.getOptions(options)\n\n    var triggers = this.options.trigger.split(' ')\n\n    for (var i = triggers.length; i--;) {\n      var trigger = triggers[i]\n\n      if (trigger == 'click') {\n        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))\n      } else if (trigger != 'manual') {\n        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focus'\n        var eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'\n\n        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))\n        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))\n      }\n    }\n\n    this.options.selector ?\n      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :\n      this.fixTitle()\n  }\n\n  Tooltip.prototype.getDefaults = function () {\n    return Tooltip.DEFAULTS\n  }\n\n  Tooltip.prototype.getOptions = function (options) {\n    options = $.extend({}, this.getDefaults(), this.$element.data(), options)\n\n    if (options.delay && typeof options.delay == 'number') {\n      options.delay = {\n        show: options.delay\n      , hide: options.delay\n      }\n    }\n\n    return options\n  }\n\n  Tooltip.prototype.getDelegateOptions = function () {\n    var options  = {}\n    var defaults = this.getDefaults()\n\n    this._options && $.each(this._options, function (key, value) {\n      if (defaults[key] != value) options[key] = value\n    })\n\n    return options\n  }\n\n  Tooltip.prototype.enter = function (obj) {\n    var self = obj instanceof this.constructor ?\n      obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)\n\n    clearTimeout(self.timeout)\n\n    self.hoverState = 'in'\n\n    if (!self.options.delay || !self.options.delay.show) return self.show()\n\n    self.timeout = setTimeout(function () {\n      if (self.hoverState == 'in') self.show()\n    }, self.options.delay.show)\n  }\n\n  Tooltip.prototype.leave = function (obj) {\n    var self = obj instanceof this.constructor ?\n      obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)\n\n    clearTimeout(self.timeout)\n\n    self.hoverState = 'out'\n\n    if (!self.options.delay || !self.options.delay.hide) return self.hide()\n\n    self.timeout = setTimeout(function () {\n      if (self.hoverState == 'out') self.hide()\n    }, self.options.delay.hide)\n  }\n\n  Tooltip.prototype.show = function () {\n    var e = $.Event('show.bs.'+ this.type)\n\n    if (this.hasContent() && this.enabled) {\n      this.$element.trigger(e)\n\n      if (e.isDefaultPrevented()) return\n\n      var $tip = this.tip()\n\n      this.setContent()\n\n      if (this.options.animation) $tip.addClass('fade')\n\n      var placement = typeof this.options.placement == 'function' ?\n        this.options.placement.call(this, $tip[0], this.$element[0]) :\n        this.options.placement\n\n      var autoToken = /\\s?auto?\\s?/i\n      var autoPlace = autoToken.test(placement)\n      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'\n\n      $tip\n        .detach()\n        .css({ top: 0, left: 0, display: 'block' })\n        .addClass(placement)\n\n      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)\n\n      var pos          = this.getPosition()\n      var actualWidth  = $tip[0].offsetWidth\n      var actualHeight = $tip[0].offsetHeight\n\n      if (autoPlace) {\n        var $parent = this.$element.parent()\n\n        var orgPlacement = placement\n        var docScroll    = document.documentElement.scrollTop || document.body.scrollTop\n        var parentWidth  = this.options.container == 'body' ? window.innerWidth  : $parent.outerWidth()\n        var parentHeight = this.options.container == 'body' ? window.innerHeight : $parent.outerHeight()\n        var parentLeft   = this.options.container == 'body' ? 0 : $parent.offset().left\n\n        placement = placement == 'bottom' && pos.top   + pos.height  + actualHeight - docScroll > parentHeight  ? 'top'    :\n                    placement == 'top'    && pos.top   - docScroll   - actualHeight < 0                         ? 'bottom' :\n                    placement == 'right'  && pos.right + actualWidth > parentWidth                              ? 'left'   :\n                    placement == 'left'   && pos.left  - actualWidth < parentLeft                               ? 'right'  :\n                    placement\n\n        $tip\n          .removeClass(orgPlacement)\n          .addClass(placement)\n      }\n\n      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)\n\n      this.applyPlacement(calculatedOffset, placement)\n      this.$element.trigger('shown.bs.' + this.type)\n    }\n  }\n\n  Tooltip.prototype.applyPlacement = function(offset, placement) {\n    var replace\n    var $tip   = this.tip()\n    var width  = $tip[0].offsetWidth\n    var height = $tip[0].offsetHeight\n    var marginTop = parseInt($tip.css('margin-top'), 10)\n    var marginLeft = parseInt($tip.css('margin-left'), 10)\n    if (isNaN(marginTop))  marginTop  = 0\n    if (isNaN(marginLeft)) marginLeft = 0\n\n    offset.top  = offset.top  + marginTop\n    offset.left = offset.left + marginLeft\n\n    $tip\n      .offset(offset)\n      .addClass('in')\n    var actualWidth  = $tip[0].offsetWidth\n    var actualHeight = $tip[0].offsetHeight\n\n    if (placement == 'top' && actualHeight != height) {\n      replace = true\n      offset.top = offset.top + height - actualHeight\n    }\n\n    if (/bottom|top/.test(placement)) {\n      var delta = 0\n\n      if (offset.left < 0) {\n        delta       = offset.left * -2\n        offset.left = 0\n\n        $tip.offset(offset)\n\n        actualWidth  = $tip[0].offsetWidth\n        actualHeight = $tip[0].offsetHeight\n      }\n\n      this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')\n    } else {\n      this.replaceArrow(actualHeight - height, actualHeight, 'top')\n    }\n\n    if (replace) $tip.offset(offset)\n  }\n\n  Tooltip.prototype.replaceArrow = function(delta, dimension, position) {\n    this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + \"%\") : '')\n  }\n\n  Tooltip.prototype.setContent = function () {\n    var $tip  = this.tip()\n    var title = this.getTitle()\n\n    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)\n    $tip.removeClass('fade in top bottom left right')\n  }\n\n  Tooltip.prototype.hide = function () {\n    var that = this\n    var $tip = this.tip()\n    var e    = $.Event('hide.bs.' + this.type)\n\n    function complete() {\n      if (that.hoverState != 'in') $tip.detach()\n    }\n\n    this.$element.trigger(e)\n\n    if (e.isDefaultPrevented()) return\n\n    $tip.removeClass('in')\n\n    $.support.transition && this.$tip.hasClass('fade') ?\n      $tip\n        .one($.support.transition.end, complete)\n        .emulateTransitionEnd(150) :\n      complete()\n\n    this.$element.trigger('hidden.bs.' + this.type)\n\n    return this\n  }\n\n  Tooltip.prototype.fixTitle = function () {\n    var $e = this.$element\n    if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {\n      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')\n    }\n  }\n\n  Tooltip.prototype.hasContent = function () {\n    return this.getTitle()\n  }\n\n  Tooltip.prototype.getPosition = function () {\n    var el = this.$element[0]\n    return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {\n      width: el.offsetWidth\n    , height: el.offsetHeight\n    }, this.$element.offset())\n  }\n\n  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {\n    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2  } :\n           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2  } :\n           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :\n        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width   }\n  }\n\n  Tooltip.prototype.getTitle = function () {\n    var title\n    var $e = this.$element\n    var o  = this.options\n\n    title = $e.attr('data-original-title')\n      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)\n\n    return title\n  }\n\n  Tooltip.prototype.tip = function () {\n    return this.$tip = this.$tip || $(this.options.template)\n  }\n\n  Tooltip.prototype.arrow = function () {\n    return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')\n  }\n\n  Tooltip.prototype.validate = function () {\n    if (!this.$element[0].parentNode) {\n      this.hide()\n      this.$element = null\n      this.options  = null\n    }\n  }\n\n  Tooltip.prototype.enable = function () {\n    this.enabled = true\n  }\n\n  Tooltip.prototype.disable = function () {\n    this.enabled = false\n  }\n\n  Tooltip.prototype.toggleEnabled = function () {\n    this.enabled = !this.enabled\n  }\n\n  Tooltip.prototype.toggle = function (e) {\n    var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this\n    self.tip().hasClass('in') ? self.leave(self) : self.enter(self)\n  }\n\n  Tooltip.prototype.destroy = function () {\n    this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)\n  }\n\n  var old = $.fn.tooltip\n\n  $.fn.tooltip = function (option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.tooltip')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.tooltip.Constructor = Tooltip\n\n  $.fn.tooltip.noConflict = function () {\n    $.fn.tooltip = old\n    return this\n  }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: popover.js v3.0.3\n * http://getbootstrap.com/javascript/#popovers\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var Popover = function (element, options) {\n    this.init('popover', element, options)\n  }\n\n  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')\n\n  Popover.DEFAULTS = $.extend({} , $.fn.tooltip.Constructor.DEFAULTS, {\n    placement: 'right'\n  , trigger: 'click'\n  , content: ''\n  , template: '<div class=\"popover\"><div class=\"arrow\"></div><h3 class=\"popover-title\"></h3><div class=\"popover-content\"></div></div>'\n  })\n\n  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)\n\n  Popover.prototype.constructor = Popover\n\n  Popover.prototype.getDefaults = function () {\n    return Popover.DEFAULTS\n  }\n\n  Popover.prototype.setContent = function () {\n    var $tip    = this.tip()\n    var title   = this.getTitle()\n    var content = this.getContent()\n\n    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)\n    $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)\n\n    $tip.removeClass('fade top bottom left right in')\n    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()\n  }\n\n  Popover.prototype.hasContent = function () {\n    return this.getTitle() || this.getContent()\n  }\n\n  Popover.prototype.getContent = function () {\n    var $e = this.$element\n    var o  = this.options\n\n    return $e.attr('data-content')\n      || (typeof o.content == 'function' ?\n            o.content.call($e[0]) :\n            o.content)\n  }\n\n  Popover.prototype.arrow = function () {\n    return this.$arrow = this.$arrow || this.tip().find('.arrow')\n  }\n\n  Popover.prototype.tip = function () {\n    if (!this.$tip) this.$tip = $(this.options.template)\n    return this.$tip\n  }\n\n  var old = $.fn.popover\n\n  $.fn.popover = function (option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.popover')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.popover.Constructor = Popover\n\n  $.fn.popover.noConflict = function () {\n    $.fn.popover = old\n    return this\n  }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: scrollspy.js v3.0.3\n * http://getbootstrap.com/javascript/#scrollspy\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  function ScrollSpy(element, options) {\n    var href\n    var process  = $.proxy(this.process, this)\n\n    this.$element       = $(element).is('body') ? $(window) : $(element)\n    this.$body          = $('body')\n    this.$scrollElement = this.$element.on('scroll.bs.scroll-spy.data-api', process)\n    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)\n    this.selector       = (this.options.target\n      || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) //strip for ie7\n      || '') + ' .nav li > a'\n    this.offsets        = $([])\n    this.targets        = $([])\n    this.activeTarget   = null\n\n    this.refresh()\n    this.process()\n  }\n\n  ScrollSpy.DEFAULTS = {\n    offset: 10\n  }\n\n  ScrollSpy.prototype.refresh = function () {\n    var offsetMethod = this.$element[0] == window ? 'offset' : 'position'\n\n    this.offsets = $([])\n    this.targets = $([])\n\n    var self     = this\n    var $targets = this.$body\n      .find(this.selector)\n      .map(function () {\n        var $el   = $(this)\n        var href  = $el.data('target') || $el.attr('href')\n        var $href = /^#\\w/.test(href) && $(href)\n\n        return ($href\n          && $href.length\n          && [[ $href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null\n      })\n      .sort(function (a, b) { return a[0] - b[0] })\n      .each(function () {\n        self.offsets.push(this[0])\n        self.targets.push(this[1])\n      })\n  }\n\n  ScrollSpy.prototype.process = function () {\n    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset\n    var scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight\n    var maxScroll    = scrollHeight - this.$scrollElement.height()\n    var offsets      = this.offsets\n    var targets      = this.targets\n    var activeTarget = this.activeTarget\n    var i\n\n    if (scrollTop >= maxScroll) {\n      return activeTarget != (i = targets.last()[0]) && this.activate(i)\n    }\n\n    for (i = offsets.length; i--;) {\n      activeTarget != targets[i]\n        && scrollTop >= offsets[i]\n        && (!offsets[i + 1] || scrollTop <= offsets[i + 1])\n        && this.activate( targets[i] )\n    }\n  }\n\n  ScrollSpy.prototype.activate = function (target) {\n    this.activeTarget = target\n\n    $(this.selector)\n      .parents('.active')\n      .removeClass('active')\n\n    var selector = this.selector\n      + '[data-target=\"' + target + '\"],'\n      + this.selector + '[href=\"' + target + '\"]'\n\n    var active = $(selector)\n      .parents('li')\n      .addClass('active')\n\n    if (active.parent('.dropdown-menu').length)  {\n      active = active\n        .closest('li.dropdown')\n        .addClass('active')\n    }\n\n    active.trigger('activate.bs.scrollspy')\n  }\n\n  var old = $.fn.scrollspy\n\n  $.fn.scrollspy = function (option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.scrollspy')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.scrollspy.Constructor = ScrollSpy\n\n  $.fn.scrollspy.noConflict = function () {\n    $.fn.scrollspy = old\n    return this\n  }\n\n  $(window).on('load', function () {\n    $('[data-spy=\"scroll\"]').each(function () {\n      var $spy = $(this)\n      $spy.scrollspy($spy.data())\n    })\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tab.js v3.0.3\n * http://getbootstrap.com/javascript/#tabs\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var Tab = function (element) {\n    this.element = $(element)\n  }\n\n  Tab.prototype.show = function () {\n    var $this    = this.element\n    var $ul      = $this.closest('ul:not(.dropdown-menu)')\n    var selector = $this.data('target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') //strip for ie7\n    }\n\n    if ($this.parent('li').hasClass('active')) return\n\n    var previous = $ul.find('.active:last a')[0]\n    var e        = $.Event('show.bs.tab', {\n      relatedTarget: previous\n    })\n\n    $this.trigger(e)\n\n    if (e.isDefaultPrevented()) return\n\n    var $target = $(selector)\n\n    this.activate($this.parent('li'), $ul)\n    this.activate($target, $target.parent(), function () {\n      $this.trigger({\n        type: 'shown.bs.tab'\n      , relatedTarget: previous\n      })\n    })\n  }\n\n  Tab.prototype.activate = function (element, container, callback) {\n    var $active    = container.find('> .active')\n    var transition = callback\n      && $.support.transition\n      && $active.hasClass('fade')\n\n    function next() {\n      $active\n        .removeClass('active')\n        .find('> .dropdown-menu > .active')\n        .removeClass('active')\n\n      element.addClass('active')\n\n      if (transition) {\n        element[0].offsetWidth // reflow for transition\n        element.addClass('in')\n      } else {\n        element.removeClass('fade')\n      }\n\n      if (element.parent('.dropdown-menu')) {\n        element.closest('li.dropdown').addClass('active')\n      }\n\n      callback && callback()\n    }\n\n    transition ?\n      $active\n        .one($.support.transition.end, next)\n        .emulateTransitionEnd(150) :\n      next()\n\n    $active.removeClass('in')\n  }\n\n  var old = $.fn.tab\n\n  $.fn.tab = function ( option ) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.tab')\n\n      if (!data) $this.data('bs.tab', (data = new Tab(this)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.tab.Constructor = Tab\n\n  $.fn.tab.noConflict = function () {\n    $.fn.tab = old\n    return this\n  }\n\n  $(document).on('click.bs.tab.data-api', '[data-toggle=\"tab\"], [data-toggle=\"pill\"]', function (e) {\n    e.preventDefault()\n    $(this).tab('show')\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: affix.js v3.0.3\n * http://getbootstrap.com/javascript/#affix\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var Affix = function (element, options) {\n    this.options = $.extend({}, Affix.DEFAULTS, options)\n    this.$window = $(window)\n      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))\n      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))\n\n    this.$element = $(element)\n    this.affixed  =\n    this.unpin    = null\n\n    this.checkPosition()\n  }\n\n  Affix.RESET = 'affix affix-top affix-bottom'\n\n  Affix.DEFAULTS = {\n    offset: 0\n  }\n\n  Affix.prototype.checkPositionWithEventLoop = function () {\n    setTimeout($.proxy(this.checkPosition, this), 1)\n  }\n\n  Affix.prototype.checkPosition = function () {\n    if (!this.$element.is(':visible')) return\n\n    var scrollHeight = $(document).height()\n    var scrollTop    = this.$window.scrollTop()\n    var position     = this.$element.offset()\n    var offset       = this.options.offset\n    var offsetTop    = offset.top\n    var offsetBottom = offset.bottom\n\n    if (typeof offset != 'object')         offsetBottom = offsetTop = offset\n    if (typeof offsetTop == 'function')    offsetTop    = offset.top()\n    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()\n\n    var affix = this.unpin   != null && (scrollTop + this.unpin <= position.top) ? false :\n                offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :\n                offsetTop    != null && (scrollTop <= offsetTop) ? 'top' : false\n\n    if (this.affixed === affix) return\n    if (this.unpin) this.$element.css('top', '')\n\n    this.affixed = affix\n    this.unpin   = affix == 'bottom' ? position.top - scrollTop : null\n\n    this.$element.removeClass(Affix.RESET).addClass('affix' + (affix ? '-' + affix : ''))\n\n    if (affix == 'bottom') {\n      this.$element.offset({ top: document.body.offsetHeight - offsetBottom - this.$element.height() })\n    }\n  }\n\n  var old = $.fn.affix\n\n  $.fn.affix = function (option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.affix')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.affix.Constructor = Affix\n\n  $.fn.affix.noConflict = function () {\n    $.fn.affix = old\n    return this\n  }\n\n  $(window).on('load', function () {\n    $('[data-spy=\"affix\"]').each(function () {\n      var $spy = $(this)\n      var data = $spy.data()\n\n      data.offset = data.offset || {}\n\n      if (data.offsetBottom) data.offset.bottom = data.offsetBottom\n      if (data.offsetTop)    data.offset.top    = data.offsetTop\n\n      $spy.affix(data)\n    })\n  })\n\n}(jQuery);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/js/affix.js",
    "content": "/* ========================================================================\n * Bootstrap: affix.js v3.0.3\n * http://getbootstrap.com/javascript/#affix\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var Affix = function (element, options) {\n    this.options = $.extend({}, Affix.DEFAULTS, options)\n    this.$window = $(window)\n      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))\n      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))\n\n    this.$element = $(element)\n    this.affixed  =\n    this.unpin    = null\n\n    this.checkPosition()\n  }\n\n  Affix.RESET = 'affix affix-top affix-bottom'\n\n  Affix.DEFAULTS = {\n    offset: 0\n  }\n\n  Affix.prototype.checkPositionWithEventLoop = function () {\n    setTimeout($.proxy(this.checkPosition, this), 1)\n  }\n\n  Affix.prototype.checkPosition = function () {\n    if (!this.$element.is(':visible')) return\n\n    var scrollHeight = $(document).height()\n    var scrollTop    = this.$window.scrollTop()\n    var position     = this.$element.offset()\n    var offset       = this.options.offset\n    var offsetTop    = offset.top\n    var offsetBottom = offset.bottom\n\n    if (typeof offset != 'object')         offsetBottom = offsetTop = offset\n    if (typeof offsetTop == 'function')    offsetTop    = offset.top()\n    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()\n\n    var affix = this.unpin   != null && (scrollTop + this.unpin <= position.top) ? false :\n                offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ? 'bottom' :\n                offsetTop    != null && (scrollTop <= offsetTop) ? 'top' : false\n\n    if (this.affixed === affix) return\n    if (this.unpin) this.$element.css('top', '')\n\n    this.affixed = affix\n    this.unpin   = affix == 'bottom' ? position.top - scrollTop : null\n\n    this.$element.removeClass(Affix.RESET).addClass('affix' + (affix ? '-' + affix : ''))\n\n    if (affix == 'bottom') {\n      this.$element.offset({ top: document.body.offsetHeight - offsetBottom - this.$element.height() })\n    }\n  }\n\n  var old = $.fn.affix\n\n  $.fn.affix = function (option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.affix')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.affix.Constructor = Affix\n\n  $.fn.affix.noConflict = function () {\n    $.fn.affix = old\n    return this\n  }\n\n  $(window).on('load', function () {\n    $('[data-spy=\"affix\"]').each(function () {\n      var $spy = $(this)\n      var data = $spy.data()\n\n      data.offset = data.offset || {}\n\n      if (data.offsetBottom) data.offset.bottom = data.offsetBottom\n      if (data.offsetTop)    data.offset.top    = data.offsetTop\n\n      $spy.affix(data)\n    })\n  })\n\n}(jQuery);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/js/alert.js",
    "content": "/* ========================================================================\n * Bootstrap: alert.js v3.0.3\n * http://getbootstrap.com/javascript/#alerts\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var dismiss = '[data-dismiss=\"alert\"]'\n  var Alert   = function (el) {\n    $(el).on('click', dismiss, this.close)\n  }\n\n  Alert.prototype.close = function (e) {\n    var $this    = $(this)\n    var selector = $this.attr('data-target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    var $parent = $(selector)\n\n    if (e) e.preventDefault()\n\n    if (!$parent.length) {\n      $parent = $this.hasClass('alert') ? $this : $this.parent()\n    }\n\n    $parent.trigger(e = $.Event('close.bs.alert'))\n\n    if (e.isDefaultPrevented()) return\n\n    $parent.removeClass('in')\n\n    function removeElement() {\n      $parent.trigger('closed.bs.alert').remove()\n    }\n\n    $.support.transition && $parent.hasClass('fade') ?\n      $parent\n        .one($.support.transition.end, removeElement)\n        .emulateTransitionEnd(150) :\n      removeElement()\n  }\n\n  var old = $.fn.alert\n\n  $.fn.alert = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.alert')\n\n      if (!data) $this.data('bs.alert', (data = new Alert(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  $.fn.alert.Constructor = Alert\n\n  $.fn.alert.noConflict = function () {\n    $.fn.alert = old\n    return this\n  }\n\n  $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)\n\n}(jQuery);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/js/button.js",
    "content": "/* ========================================================================\n * Bootstrap: button.js v3.0.3\n * http://getbootstrap.com/javascript/#buttons\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var Button = function (element, options) {\n    this.$element = $(element)\n    this.options  = $.extend({}, Button.DEFAULTS, options)\n  }\n\n  Button.DEFAULTS = {\n    loadingText: 'loading...'\n  }\n\n  Button.prototype.setState = function (state) {\n    var d    = 'disabled'\n    var $el  = this.$element\n    var val  = $el.is('input') ? 'val' : 'html'\n    var data = $el.data()\n\n    state = state + 'Text'\n\n    if (!data.resetText) $el.data('resetText', $el[val]())\n\n    $el[val](data[state] || this.options[state])\n    setTimeout(function () {\n      state == 'loadingText' ?\n        $el.addClass(d).attr(d, d) :\n        $el.removeClass(d).removeAttr(d);\n    }, 0)\n  }\n\n  Button.prototype.toggle = function () {\n    var $parent = this.$element.closest('[data-toggle=\"buttons\"]')\n    var changed = true\n\n    if ($parent.length) {\n      var $input = this.$element.find('input')\n      if ($input.prop('type') === 'radio') {\n        if ($input.prop('checked') && this.$element.hasClass('active'))\n          changed = false\n        else\n          $parent.find('.active').removeClass('active')\n      }\n      if (changed) $input.prop('checked', !this.$element.hasClass('active')).trigger('change')\n    }\n\n    if (changed) this.$element.toggleClass('active')\n  }\n\n  var old = $.fn.button\n\n  $.fn.button = function (option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.button')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.button', (data = new Button(this, options)))\n\n      if (option == 'toggle') data.toggle()\n      else if (option) data.setState(option)\n    })\n  }\n\n  $.fn.button.Constructor = Button\n\n  $.fn.button.noConflict = function () {\n    $.fn.button = old\n    return this\n  }\n\n  $(document).on('click.bs.button.data-api', '[data-toggle^=button]', function (e) {\n    var $btn = $(e.target)\n    if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')\n    $btn.button('toggle')\n    e.preventDefault()\n  })\n\n}(jQuery);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/js/carousel.js",
    "content": "/* ========================================================================\n * Bootstrap: carousel.js v3.0.3\n * http://getbootstrap.com/javascript/#carousel\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var Carousel = function (element, options) {\n    this.$element    = $(element)\n    this.$indicators = this.$element.find('.carousel-indicators')\n    this.options     = options\n    this.paused      =\n    this.sliding     =\n    this.interval    =\n    this.$active     =\n    this.$items      = null\n\n    this.options.pause == 'hover' && this.$element\n      .on('mouseenter', $.proxy(this.pause, this))\n      .on('mouseleave', $.proxy(this.cycle, this))\n  }\n\n  Carousel.DEFAULTS = {\n    interval: 5000\n  , pause: 'hover'\n  , wrap: true\n  }\n\n  Carousel.prototype.cycle =  function (e) {\n    e || (this.paused = false)\n\n    this.interval && clearInterval(this.interval)\n\n    this.options.interval\n      && !this.paused\n      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))\n\n    return this\n  }\n\n  Carousel.prototype.getActiveIndex = function () {\n    this.$active = this.$element.find('.item.active')\n    this.$items  = this.$active.parent().children()\n\n    return this.$items.index(this.$active)\n  }\n\n  Carousel.prototype.to = function (pos) {\n    var that        = this\n    var activeIndex = this.getActiveIndex()\n\n    if (pos > (this.$items.length - 1) || pos < 0) return\n\n    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) })\n    if (activeIndex == pos) return this.pause().cycle()\n\n    return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))\n  }\n\n  Carousel.prototype.pause = function (e) {\n    e || (this.paused = true)\n\n    if (this.$element.find('.next, .prev').length && $.support.transition.end) {\n      this.$element.trigger($.support.transition.end)\n      this.cycle(true)\n    }\n\n    this.interval = clearInterval(this.interval)\n\n    return this\n  }\n\n  Carousel.prototype.next = function () {\n    if (this.sliding) return\n    return this.slide('next')\n  }\n\n  Carousel.prototype.prev = function () {\n    if (this.sliding) return\n    return this.slide('prev')\n  }\n\n  Carousel.prototype.slide = function (type, next) {\n    var $active   = this.$element.find('.item.active')\n    var $next     = next || $active[type]()\n    var isCycling = this.interval\n    var direction = type == 'next' ? 'left' : 'right'\n    var fallback  = type == 'next' ? 'first' : 'last'\n    var that      = this\n\n    if (!$next.length) {\n      if (!this.options.wrap) return\n      $next = this.$element.find('.item')[fallback]()\n    }\n\n    this.sliding = true\n\n    isCycling && this.pause()\n\n    var e = $.Event('slide.bs.carousel', { relatedTarget: $next[0], direction: direction })\n\n    if ($next.hasClass('active')) return\n\n    if (this.$indicators.length) {\n      this.$indicators.find('.active').removeClass('active')\n      this.$element.one('slid.bs.carousel', function () {\n        var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])\n        $nextIndicator && $nextIndicator.addClass('active')\n      })\n    }\n\n    if ($.support.transition && this.$element.hasClass('slide')) {\n      this.$element.trigger(e)\n      if (e.isDefaultPrevented()) return\n      $next.addClass(type)\n      $next[0].offsetWidth // force reflow\n      $active.addClass(direction)\n      $next.addClass(direction)\n      $active\n        .one($.support.transition.end, function () {\n          $next.removeClass([type, direction].join(' ')).addClass('active')\n          $active.removeClass(['active', direction].join(' '))\n          that.sliding = false\n          setTimeout(function () { that.$element.trigger('slid.bs.carousel') }, 0)\n        })\n        .emulateTransitionEnd(600)\n    } else {\n      this.$element.trigger(e)\n      if (e.isDefaultPrevented()) return\n      $active.removeClass('active')\n      $next.addClass('active')\n      this.sliding = false\n      this.$element.trigger('slid.bs.carousel')\n    }\n\n    isCycling && this.cycle()\n\n    return this\n  }\n\n  var old = $.fn.carousel\n\n  $.fn.carousel = function (option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.carousel')\n      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)\n      var action  = typeof option == 'string' ? option : options.slide\n\n      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))\n      if (typeof option == 'number') data.to(option)\n      else if (action) data[action]()\n      else if (options.interval) data.pause().cycle()\n    })\n  }\n\n  $.fn.carousel.Constructor = Carousel\n\n  $.fn.carousel.noConflict = function () {\n    $.fn.carousel = old\n    return this\n  }\n\n  $(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {\n    var $this   = $(this), href\n    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) //strip for ie7\n    var options = $.extend({}, $target.data(), $this.data())\n    var slideIndex = $this.attr('data-slide-to')\n    if (slideIndex) options.interval = false\n\n    $target.carousel(options)\n\n    if (slideIndex = $this.attr('data-slide-to')) {\n      $target.data('bs.carousel').to(slideIndex)\n    }\n\n    e.preventDefault()\n  })\n\n  $(window).on('load', function () {\n    $('[data-ride=\"carousel\"]').each(function () {\n      var $carousel = $(this)\n      $carousel.carousel($carousel.data())\n    })\n  })\n\n}(jQuery);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/js/collapse.js",
    "content": "/* ========================================================================\n * Bootstrap: collapse.js v3.0.3\n * http://getbootstrap.com/javascript/#collapse\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var Collapse = function (element, options) {\n    this.$element      = $(element)\n    this.options       = $.extend({}, Collapse.DEFAULTS, options)\n    this.transitioning = null\n\n    if (this.options.parent) this.$parent = $(this.options.parent)\n    if (this.options.toggle) this.toggle()\n  }\n\n  Collapse.DEFAULTS = {\n    toggle: true\n  }\n\n  Collapse.prototype.dimension = function () {\n    var hasWidth = this.$element.hasClass('width')\n    return hasWidth ? 'width' : 'height'\n  }\n\n  Collapse.prototype.show = function () {\n    if (this.transitioning || this.$element.hasClass('in')) return\n\n    var startEvent = $.Event('show.bs.collapse')\n    this.$element.trigger(startEvent)\n    if (startEvent.isDefaultPrevented()) return\n\n    var actives = this.$parent && this.$parent.find('> .panel > .in')\n\n    if (actives && actives.length) {\n      var hasData = actives.data('bs.collapse')\n      if (hasData && hasData.transitioning) return\n      actives.collapse('hide')\n      hasData || actives.data('bs.collapse', null)\n    }\n\n    var dimension = this.dimension()\n\n    this.$element\n      .removeClass('collapse')\n      .addClass('collapsing')\n      [dimension](0)\n\n    this.transitioning = 1\n\n    var complete = function () {\n      this.$element\n        .removeClass('collapsing')\n        .addClass('in')\n        [dimension]('auto')\n      this.transitioning = 0\n      this.$element.trigger('shown.bs.collapse')\n    }\n\n    if (!$.support.transition) return complete.call(this)\n\n    var scrollSize = $.camelCase(['scroll', dimension].join('-'))\n\n    this.$element\n      .one($.support.transition.end, $.proxy(complete, this))\n      .emulateTransitionEnd(350)\n      [dimension](this.$element[0][scrollSize])\n  }\n\n  Collapse.prototype.hide = function () {\n    if (this.transitioning || !this.$element.hasClass('in')) return\n\n    var startEvent = $.Event('hide.bs.collapse')\n    this.$element.trigger(startEvent)\n    if (startEvent.isDefaultPrevented()) return\n\n    var dimension = this.dimension()\n\n    this.$element\n      [dimension](this.$element[dimension]())\n      [0].offsetHeight\n\n    this.$element\n      .addClass('collapsing')\n      .removeClass('collapse')\n      .removeClass('in')\n\n    this.transitioning = 1\n\n    var complete = function () {\n      this.transitioning = 0\n      this.$element\n        .trigger('hidden.bs.collapse')\n        .removeClass('collapsing')\n        .addClass('collapse')\n    }\n\n    if (!$.support.transition) return complete.call(this)\n\n    this.$element\n      [dimension](0)\n      .one($.support.transition.end, $.proxy(complete, this))\n      .emulateTransitionEnd(350)\n  }\n\n  Collapse.prototype.toggle = function () {\n    this[this.$element.hasClass('in') ? 'hide' : 'show']()\n  }\n\n  var old = $.fn.collapse\n\n  $.fn.collapse = function (option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.collapse')\n      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.collapse.Constructor = Collapse\n\n  $.fn.collapse.noConflict = function () {\n    $.fn.collapse = old\n    return this\n  }\n\n  $(document).on('click.bs.collapse.data-api', '[data-toggle=collapse]', function (e) {\n    var $this   = $(this), href\n    var target  = $this.attr('data-target')\n        || e.preventDefault()\n        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '') //strip for ie7\n    var $target = $(target)\n    var data    = $target.data('bs.collapse')\n    var option  = data ? 'toggle' : $this.data()\n    var parent  = $this.attr('data-parent')\n    var $parent = parent && $(parent)\n\n    if (!data || !data.transitioning) {\n      if ($parent) $parent.find('[data-toggle=collapse][data-parent=\"' + parent + '\"]').not($this).addClass('collapsed')\n      $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')\n    }\n\n    $target.collapse(option)\n  })\n\n}(jQuery);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/js/dropdown.js",
    "content": "/* ========================================================================\n * Bootstrap: dropdown.js v3.0.3\n * http://getbootstrap.com/javascript/#dropdowns\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var backdrop = '.dropdown-backdrop'\n  var toggle   = '[data-toggle=dropdown]'\n  var Dropdown = function (element) {\n    $(element).on('click.bs.dropdown', this.toggle)\n  }\n\n  Dropdown.prototype.toggle = function (e) {\n    var $this = $(this)\n\n    if ($this.is('.disabled, :disabled')) return\n\n    var $parent  = getParent($this)\n    var isActive = $parent.hasClass('open')\n\n    clearMenus()\n\n    if (!isActive) {\n      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {\n        $('<div class=\"dropdown-backdrop\"/>').insertAfter($(this)).on('click', clearMenus)\n      }\n\n      $parent.trigger(e = $.Event('show.bs.dropdown'))\n\n      if (e.isDefaultPrevented()) return\n\n      $parent\n        .toggleClass('open')\n        .trigger('shown.bs.dropdown')\n\n      $this.focus()\n    }\n\n    return false\n  }\n\n  Dropdown.prototype.keydown = function (e) {\n    if (!/(38|40|27)/.test(e.keyCode)) return\n\n    var $this = $(this)\n\n    e.preventDefault()\n    e.stopPropagation()\n\n    if ($this.is('.disabled, :disabled')) return\n\n    var $parent  = getParent($this)\n    var isActive = $parent.hasClass('open')\n\n    if (!isActive || (isActive && e.keyCode == 27)) {\n      if (e.which == 27) $parent.find(toggle).focus()\n      return $this.click()\n    }\n\n    var $items = $('[role=menu] li:not(.divider):visible a', $parent)\n\n    if (!$items.length) return\n\n    var index = $items.index($items.filter(':focus'))\n\n    if (e.keyCode == 38 && index > 0)                 index--                        // up\n    if (e.keyCode == 40 && index < $items.length - 1) index++                        // down\n    if (!~index)                                      index=0\n\n    $items.eq(index).focus()\n  }\n\n  function clearMenus() {\n    $(backdrop).remove()\n    $(toggle).each(function (e) {\n      var $parent = getParent($(this))\n      if (!$parent.hasClass('open')) return\n      $parent.trigger(e = $.Event('hide.bs.dropdown'))\n      if (e.isDefaultPrevented()) return\n      $parent.removeClass('open').trigger('hidden.bs.dropdown')\n    })\n  }\n\n  function getParent($this) {\n    var selector = $this.attr('data-target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\\s]*$)/, '') //strip for ie7\n    }\n\n    var $parent = selector && $(selector)\n\n    return $parent && $parent.length ? $parent : $this.parent()\n  }\n\n  var old = $.fn.dropdown\n\n  $.fn.dropdown = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.dropdown')\n\n      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  $.fn.dropdown.Constructor = Dropdown\n\n  $.fn.dropdown.noConflict = function () {\n    $.fn.dropdown = old\n    return this\n  }\n\n  $(document)\n    .on('click.bs.dropdown.data-api', clearMenus)\n    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })\n    .on('click.bs.dropdown.data-api'  , toggle, Dropdown.prototype.toggle)\n    .on('keydown.bs.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)\n\n}(jQuery);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/js/modal.js",
    "content": "/* ========================================================================\n * Bootstrap: modal.js v3.0.3\n * http://getbootstrap.com/javascript/#modals\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var Modal = function (element, options) {\n    this.options   = options\n    this.$element  = $(element)\n    this.$backdrop =\n    this.isShown   = null\n\n    if (this.options.remote) this.$element.load(this.options.remote)\n  }\n\n  Modal.DEFAULTS = {\n      backdrop: true\n    , keyboard: true\n    , show: true\n  }\n\n  Modal.prototype.toggle = function (_relatedTarget) {\n    return this[!this.isShown ? 'show' : 'hide'](_relatedTarget)\n  }\n\n  Modal.prototype.show = function (_relatedTarget) {\n    var that = this\n    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })\n\n    this.$element.trigger(e)\n\n    if (this.isShown || e.isDefaultPrevented()) return\n\n    this.isShown = true\n\n    this.escape()\n\n    this.$element.on('click.dismiss.modal', '[data-dismiss=\"modal\"]', $.proxy(this.hide, this))\n\n    this.backdrop(function () {\n      var transition = $.support.transition && that.$element.hasClass('fade')\n\n      if (!that.$element.parent().length) {\n        that.$element.appendTo(document.body) // don't move modals dom position\n      }\n\n      that.$element.show()\n\n      if (transition) {\n        that.$element[0].offsetWidth // force reflow\n      }\n\n      that.$element\n        .addClass('in')\n        .attr('aria-hidden', false)\n\n      that.enforceFocus()\n\n      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })\n\n      transition ?\n        that.$element.find('.modal-dialog') // wait for modal to slide in\n          .one($.support.transition.end, function () {\n            that.$element.focus().trigger(e)\n          })\n          .emulateTransitionEnd(300) :\n        that.$element.focus().trigger(e)\n    })\n  }\n\n  Modal.prototype.hide = function (e) {\n    if (e) e.preventDefault()\n\n    e = $.Event('hide.bs.modal')\n\n    this.$element.trigger(e)\n\n    if (!this.isShown || e.isDefaultPrevented()) return\n\n    this.isShown = false\n\n    this.escape()\n\n    $(document).off('focusin.bs.modal')\n\n    this.$element\n      .removeClass('in')\n      .attr('aria-hidden', true)\n      .off('click.dismiss.modal')\n\n    $.support.transition && this.$element.hasClass('fade') ?\n      this.$element\n        .one($.support.transition.end, $.proxy(this.hideModal, this))\n        .emulateTransitionEnd(300) :\n      this.hideModal()\n  }\n\n  Modal.prototype.enforceFocus = function () {\n    $(document)\n      .off('focusin.bs.modal') // guard against infinite focus loop\n      .on('focusin.bs.modal', $.proxy(function (e) {\n        if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {\n          this.$element.focus()\n        }\n      }, this))\n  }\n\n  Modal.prototype.escape = function () {\n    if (this.isShown && this.options.keyboard) {\n      this.$element.on('keyup.dismiss.bs.modal', $.proxy(function (e) {\n        e.which == 27 && this.hide()\n      }, this))\n    } else if (!this.isShown) {\n      this.$element.off('keyup.dismiss.bs.modal')\n    }\n  }\n\n  Modal.prototype.hideModal = function () {\n    var that = this\n    this.$element.hide()\n    this.backdrop(function () {\n      that.removeBackdrop()\n      that.$element.trigger('hidden.bs.modal')\n    })\n  }\n\n  Modal.prototype.removeBackdrop = function () {\n    this.$backdrop && this.$backdrop.remove()\n    this.$backdrop = null\n  }\n\n  Modal.prototype.backdrop = function (callback) {\n    var that    = this\n    var animate = this.$element.hasClass('fade') ? 'fade' : ''\n\n    if (this.isShown && this.options.backdrop) {\n      var doAnimate = $.support.transition && animate\n\n      this.$backdrop = $('<div class=\"modal-backdrop ' + animate + '\" />')\n        .appendTo(document.body)\n\n      this.$element.on('click.dismiss.modal', $.proxy(function (e) {\n        if (e.target !== e.currentTarget) return\n        this.options.backdrop == 'static'\n          ? this.$element[0].focus.call(this.$element[0])\n          : this.hide.call(this)\n      }, this))\n\n      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow\n\n      this.$backdrop.addClass('in')\n\n      if (!callback) return\n\n      doAnimate ?\n        this.$backdrop\n          .one($.support.transition.end, callback)\n          .emulateTransitionEnd(150) :\n        callback()\n\n    } else if (!this.isShown && this.$backdrop) {\n      this.$backdrop.removeClass('in')\n\n      $.support.transition && this.$element.hasClass('fade')?\n        this.$backdrop\n          .one($.support.transition.end, callback)\n          .emulateTransitionEnd(150) :\n        callback()\n\n    } else if (callback) {\n      callback()\n    }\n  }\n\n  var old = $.fn.modal\n\n  $.fn.modal = function (option, _relatedTarget) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.modal')\n      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))\n      if (typeof option == 'string') data[option](_relatedTarget)\n      else if (options.show) data.show(_relatedTarget)\n    })\n  }\n\n  $.fn.modal.Constructor = Modal\n\n  $.fn.modal.noConflict = function () {\n    $.fn.modal = old\n    return this\n  }\n\n  $(document).on('click.bs.modal.data-api', '[data-toggle=\"modal\"]', function (e) {\n    var $this   = $(this)\n    var href    = $this.attr('href')\n    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\\s]+$)/, ''))) //strip for ie7\n    var option  = $target.data('modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())\n\n    e.preventDefault()\n\n    $target\n      .modal(option, this)\n      .one('hide', function () {\n        $this.is(':visible') && $this.focus()\n      })\n  })\n\n  $(document)\n    .on('show.bs.modal',  '.modal', function () { $(document.body).addClass('modal-open') })\n    .on('hidden.bs.modal', '.modal', function () { $(document.body).removeClass('modal-open') })\n\n}(jQuery);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/js/popover.js",
    "content": "/* ========================================================================\n * Bootstrap: popover.js v3.0.3\n * http://getbootstrap.com/javascript/#popovers\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var Popover = function (element, options) {\n    this.init('popover', element, options)\n  }\n\n  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')\n\n  Popover.DEFAULTS = $.extend({} , $.fn.tooltip.Constructor.DEFAULTS, {\n    placement: 'right'\n  , trigger: 'click'\n  , content: ''\n  , template: '<div class=\"popover\"><div class=\"arrow\"></div><h3 class=\"popover-title\"></h3><div class=\"popover-content\"></div></div>'\n  })\n\n  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)\n\n  Popover.prototype.constructor = Popover\n\n  Popover.prototype.getDefaults = function () {\n    return Popover.DEFAULTS\n  }\n\n  Popover.prototype.setContent = function () {\n    var $tip    = this.tip()\n    var title   = this.getTitle()\n    var content = this.getContent()\n\n    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)\n    $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)\n\n    $tip.removeClass('fade top bottom left right in')\n    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()\n  }\n\n  Popover.prototype.hasContent = function () {\n    return this.getTitle() || this.getContent()\n  }\n\n  Popover.prototype.getContent = function () {\n    var $e = this.$element\n    var o  = this.options\n\n    return $e.attr('data-content')\n      || (typeof o.content == 'function' ?\n            o.content.call($e[0]) :\n            o.content)\n  }\n\n  Popover.prototype.arrow = function () {\n    return this.$arrow = this.$arrow || this.tip().find('.arrow')\n  }\n\n  Popover.prototype.tip = function () {\n    if (!this.$tip) this.$tip = $(this.options.template)\n    return this.$tip\n  }\n\n  var old = $.fn.popover\n\n  $.fn.popover = function (option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.popover')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.popover.Constructor = Popover\n\n  $.fn.popover.noConflict = function () {\n    $.fn.popover = old\n    return this\n  }\n\n}(jQuery);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/js/scrollspy.js",
    "content": "/* ========================================================================\n * Bootstrap: scrollspy.js v3.0.3\n * http://getbootstrap.com/javascript/#scrollspy\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  function ScrollSpy(element, options) {\n    var href\n    var process  = $.proxy(this.process, this)\n\n    this.$element       = $(element).is('body') ? $(window) : $(element)\n    this.$body          = $('body')\n    this.$scrollElement = this.$element.on('scroll.bs.scroll-spy.data-api', process)\n    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)\n    this.selector       = (this.options.target\n      || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) //strip for ie7\n      || '') + ' .nav li > a'\n    this.offsets        = $([])\n    this.targets        = $([])\n    this.activeTarget   = null\n\n    this.refresh()\n    this.process()\n  }\n\n  ScrollSpy.DEFAULTS = {\n    offset: 10\n  }\n\n  ScrollSpy.prototype.refresh = function () {\n    var offsetMethod = this.$element[0] == window ? 'offset' : 'position'\n\n    this.offsets = $([])\n    this.targets = $([])\n\n    var self     = this\n    var $targets = this.$body\n      .find(this.selector)\n      .map(function () {\n        var $el   = $(this)\n        var href  = $el.data('target') || $el.attr('href')\n        var $href = /^#\\w/.test(href) && $(href)\n\n        return ($href\n          && $href.length\n          && [[ $href[offsetMethod]().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]]) || null\n      })\n      .sort(function (a, b) { return a[0] - b[0] })\n      .each(function () {\n        self.offsets.push(this[0])\n        self.targets.push(this[1])\n      })\n  }\n\n  ScrollSpy.prototype.process = function () {\n    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset\n    var scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight\n    var maxScroll    = scrollHeight - this.$scrollElement.height()\n    var offsets      = this.offsets\n    var targets      = this.targets\n    var activeTarget = this.activeTarget\n    var i\n\n    if (scrollTop >= maxScroll) {\n      return activeTarget != (i = targets.last()[0]) && this.activate(i)\n    }\n\n    for (i = offsets.length; i--;) {\n      activeTarget != targets[i]\n        && scrollTop >= offsets[i]\n        && (!offsets[i + 1] || scrollTop <= offsets[i + 1])\n        && this.activate( targets[i] )\n    }\n  }\n\n  ScrollSpy.prototype.activate = function (target) {\n    this.activeTarget = target\n\n    $(this.selector)\n      .parents('.active')\n      .removeClass('active')\n\n    var selector = this.selector\n      + '[data-target=\"' + target + '\"],'\n      + this.selector + '[href=\"' + target + '\"]'\n\n    var active = $(selector)\n      .parents('li')\n      .addClass('active')\n\n    if (active.parent('.dropdown-menu').length)  {\n      active = active\n        .closest('li.dropdown')\n        .addClass('active')\n    }\n\n    active.trigger('activate.bs.scrollspy')\n  }\n\n  var old = $.fn.scrollspy\n\n  $.fn.scrollspy = function (option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.scrollspy')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.scrollspy.Constructor = ScrollSpy\n\n  $.fn.scrollspy.noConflict = function () {\n    $.fn.scrollspy = old\n    return this\n  }\n\n  $(window).on('load', function () {\n    $('[data-spy=\"scroll\"]').each(function () {\n      var $spy = $(this)\n      $spy.scrollspy($spy.data())\n    })\n  })\n\n}(jQuery);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/js/tab.js",
    "content": "/* ========================================================================\n * Bootstrap: tab.js v3.0.3\n * http://getbootstrap.com/javascript/#tabs\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var Tab = function (element) {\n    this.element = $(element)\n  }\n\n  Tab.prototype.show = function () {\n    var $this    = this.element\n    var $ul      = $this.closest('ul:not(.dropdown-menu)')\n    var selector = $this.data('target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') //strip for ie7\n    }\n\n    if ($this.parent('li').hasClass('active')) return\n\n    var previous = $ul.find('.active:last a')[0]\n    var e        = $.Event('show.bs.tab', {\n      relatedTarget: previous\n    })\n\n    $this.trigger(e)\n\n    if (e.isDefaultPrevented()) return\n\n    var $target = $(selector)\n\n    this.activate($this.parent('li'), $ul)\n    this.activate($target, $target.parent(), function () {\n      $this.trigger({\n        type: 'shown.bs.tab'\n      , relatedTarget: previous\n      })\n    })\n  }\n\n  Tab.prototype.activate = function (element, container, callback) {\n    var $active    = container.find('> .active')\n    var transition = callback\n      && $.support.transition\n      && $active.hasClass('fade')\n\n    function next() {\n      $active\n        .removeClass('active')\n        .find('> .dropdown-menu > .active')\n        .removeClass('active')\n\n      element.addClass('active')\n\n      if (transition) {\n        element[0].offsetWidth // reflow for transition\n        element.addClass('in')\n      } else {\n        element.removeClass('fade')\n      }\n\n      if (element.parent('.dropdown-menu')) {\n        element.closest('li.dropdown').addClass('active')\n      }\n\n      callback && callback()\n    }\n\n    transition ?\n      $active\n        .one($.support.transition.end, next)\n        .emulateTransitionEnd(150) :\n      next()\n\n    $active.removeClass('in')\n  }\n\n  var old = $.fn.tab\n\n  $.fn.tab = function ( option ) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.tab')\n\n      if (!data) $this.data('bs.tab', (data = new Tab(this)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.tab.Constructor = Tab\n\n  $.fn.tab.noConflict = function () {\n    $.fn.tab = old\n    return this\n  }\n\n  $(document).on('click.bs.tab.data-api', '[data-toggle=\"tab\"], [data-toggle=\"pill\"]', function (e) {\n    e.preventDefault()\n    $(this).tab('show')\n  })\n\n}(jQuery);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/js/tooltip.js",
    "content": "/* ========================================================================\n * Bootstrap: tooltip.js v3.0.3\n * http://getbootstrap.com/javascript/#tooltip\n * Inspired by the original jQuery.tipsy by Jason Frame\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  var Tooltip = function (element, options) {\n    this.type       =\n    this.options    =\n    this.enabled    =\n    this.timeout    =\n    this.hoverState =\n    this.$element   = null\n\n    this.init('tooltip', element, options)\n  }\n\n  Tooltip.DEFAULTS = {\n    animation: true\n  , placement: 'top'\n  , selector: false\n  , template: '<div class=\"tooltip\"><div class=\"tooltip-arrow\"></div><div class=\"tooltip-inner\"></div></div>'\n  , trigger: 'hover focus'\n  , title: ''\n  , delay: 0\n  , html: false\n  , container: false\n  }\n\n  Tooltip.prototype.init = function (type, element, options) {\n    this.enabled  = true\n    this.type     = type\n    this.$element = $(element)\n    this.options  = this.getOptions(options)\n\n    var triggers = this.options.trigger.split(' ')\n\n    for (var i = triggers.length; i--;) {\n      var trigger = triggers[i]\n\n      if (trigger == 'click') {\n        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))\n      } else if (trigger != 'manual') {\n        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focus'\n        var eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'\n\n        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))\n        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))\n      }\n    }\n\n    this.options.selector ?\n      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :\n      this.fixTitle()\n  }\n\n  Tooltip.prototype.getDefaults = function () {\n    return Tooltip.DEFAULTS\n  }\n\n  Tooltip.prototype.getOptions = function (options) {\n    options = $.extend({}, this.getDefaults(), this.$element.data(), options)\n\n    if (options.delay && typeof options.delay == 'number') {\n      options.delay = {\n        show: options.delay\n      , hide: options.delay\n      }\n    }\n\n    return options\n  }\n\n  Tooltip.prototype.getDelegateOptions = function () {\n    var options  = {}\n    var defaults = this.getDefaults()\n\n    this._options && $.each(this._options, function (key, value) {\n      if (defaults[key] != value) options[key] = value\n    })\n\n    return options\n  }\n\n  Tooltip.prototype.enter = function (obj) {\n    var self = obj instanceof this.constructor ?\n      obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)\n\n    clearTimeout(self.timeout)\n\n    self.hoverState = 'in'\n\n    if (!self.options.delay || !self.options.delay.show) return self.show()\n\n    self.timeout = setTimeout(function () {\n      if (self.hoverState == 'in') self.show()\n    }, self.options.delay.show)\n  }\n\n  Tooltip.prototype.leave = function (obj) {\n    var self = obj instanceof this.constructor ?\n      obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)\n\n    clearTimeout(self.timeout)\n\n    self.hoverState = 'out'\n\n    if (!self.options.delay || !self.options.delay.hide) return self.hide()\n\n    self.timeout = setTimeout(function () {\n      if (self.hoverState == 'out') self.hide()\n    }, self.options.delay.hide)\n  }\n\n  Tooltip.prototype.show = function () {\n    var e = $.Event('show.bs.'+ this.type)\n\n    if (this.hasContent() && this.enabled) {\n      this.$element.trigger(e)\n\n      if (e.isDefaultPrevented()) return\n\n      var $tip = this.tip()\n\n      this.setContent()\n\n      if (this.options.animation) $tip.addClass('fade')\n\n      var placement = typeof this.options.placement == 'function' ?\n        this.options.placement.call(this, $tip[0], this.$element[0]) :\n        this.options.placement\n\n      var autoToken = /\\s?auto?\\s?/i\n      var autoPlace = autoToken.test(placement)\n      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'\n\n      $tip\n        .detach()\n        .css({ top: 0, left: 0, display: 'block' })\n        .addClass(placement)\n\n      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)\n\n      var pos          = this.getPosition()\n      var actualWidth  = $tip[0].offsetWidth\n      var actualHeight = $tip[0].offsetHeight\n\n      if (autoPlace) {\n        var $parent = this.$element.parent()\n\n        var orgPlacement = placement\n        var docScroll    = document.documentElement.scrollTop || document.body.scrollTop\n        var parentWidth  = this.options.container == 'body' ? window.innerWidth  : $parent.outerWidth()\n        var parentHeight = this.options.container == 'body' ? window.innerHeight : $parent.outerHeight()\n        var parentLeft   = this.options.container == 'body' ? 0 : $parent.offset().left\n\n        placement = placement == 'bottom' && pos.top   + pos.height  + actualHeight - docScroll > parentHeight  ? 'top'    :\n                    placement == 'top'    && pos.top   - docScroll   - actualHeight < 0                         ? 'bottom' :\n                    placement == 'right'  && pos.right + actualWidth > parentWidth                              ? 'left'   :\n                    placement == 'left'   && pos.left  - actualWidth < parentLeft                               ? 'right'  :\n                    placement\n\n        $tip\n          .removeClass(orgPlacement)\n          .addClass(placement)\n      }\n\n      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)\n\n      this.applyPlacement(calculatedOffset, placement)\n      this.$element.trigger('shown.bs.' + this.type)\n    }\n  }\n\n  Tooltip.prototype.applyPlacement = function(offset, placement) {\n    var replace\n    var $tip   = this.tip()\n    var width  = $tip[0].offsetWidth\n    var height = $tip[0].offsetHeight\n    var marginTop = parseInt($tip.css('margin-top'), 10)\n    var marginLeft = parseInt($tip.css('margin-left'), 10)\n    if (isNaN(marginTop))  marginTop  = 0\n    if (isNaN(marginLeft)) marginLeft = 0\n\n    offset.top  = offset.top  + marginTop\n    offset.left = offset.left + marginLeft\n\n    $tip\n      .offset(offset)\n      .addClass('in')\n    var actualWidth  = $tip[0].offsetWidth\n    var actualHeight = $tip[0].offsetHeight\n\n    if (placement == 'top' && actualHeight != height) {\n      replace = true\n      offset.top = offset.top + height - actualHeight\n    }\n\n    if (/bottom|top/.test(placement)) {\n      var delta = 0\n\n      if (offset.left < 0) {\n        delta       = offset.left * -2\n        offset.left = 0\n\n        $tip.offset(offset)\n\n        actualWidth  = $tip[0].offsetWidth\n        actualHeight = $tip[0].offsetHeight\n      }\n\n      this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')\n    } else {\n      this.replaceArrow(actualHeight - height, actualHeight, 'top')\n    }\n\n    if (replace) $tip.offset(offset)\n  }\n\n  Tooltip.prototype.replaceArrow = function(delta, dimension, position) {\n    this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + \"%\") : '')\n  }\n\n  Tooltip.prototype.setContent = function () {\n    var $tip  = this.tip()\n    var title = this.getTitle()\n\n    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)\n    $tip.removeClass('fade in top bottom left right')\n  }\n\n  Tooltip.prototype.hide = function () {\n    var that = this\n    var $tip = this.tip()\n    var e    = $.Event('hide.bs.' + this.type)\n\n    function complete() {\n      if (that.hoverState != 'in') $tip.detach()\n    }\n\n    this.$element.trigger(e)\n\n    if (e.isDefaultPrevented()) return\n\n    $tip.removeClass('in')\n\n    $.support.transition && this.$tip.hasClass('fade') ?\n      $tip\n        .one($.support.transition.end, complete)\n        .emulateTransitionEnd(150) :\n      complete()\n\n    this.$element.trigger('hidden.bs.' + this.type)\n\n    return this\n  }\n\n  Tooltip.prototype.fixTitle = function () {\n    var $e = this.$element\n    if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {\n      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')\n    }\n  }\n\n  Tooltip.prototype.hasContent = function () {\n    return this.getTitle()\n  }\n\n  Tooltip.prototype.getPosition = function () {\n    var el = this.$element[0]\n    return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {\n      width: el.offsetWidth\n    , height: el.offsetHeight\n    }, this.$element.offset())\n  }\n\n  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {\n    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2  } :\n           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2  } :\n           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :\n        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width   }\n  }\n\n  Tooltip.prototype.getTitle = function () {\n    var title\n    var $e = this.$element\n    var o  = this.options\n\n    title = $e.attr('data-original-title')\n      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)\n\n    return title\n  }\n\n  Tooltip.prototype.tip = function () {\n    return this.$tip = this.$tip || $(this.options.template)\n  }\n\n  Tooltip.prototype.arrow = function () {\n    return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')\n  }\n\n  Tooltip.prototype.validate = function () {\n    if (!this.$element[0].parentNode) {\n      this.hide()\n      this.$element = null\n      this.options  = null\n    }\n  }\n\n  Tooltip.prototype.enable = function () {\n    this.enabled = true\n  }\n\n  Tooltip.prototype.disable = function () {\n    this.enabled = false\n  }\n\n  Tooltip.prototype.toggleEnabled = function () {\n    this.enabled = !this.enabled\n  }\n\n  Tooltip.prototype.toggle = function (e) {\n    var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this\n    self.tip().hasClass('in') ? self.leave(self) : self.enter(self)\n  }\n\n  Tooltip.prototype.destroy = function () {\n    this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)\n  }\n\n  var old = $.fn.tooltip\n\n  $.fn.tooltip = function (option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.tooltip')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.tooltip.Constructor = Tooltip\n\n  $.fn.tooltip.noConflict = function () {\n    $.fn.tooltip = old\n    return this\n  }\n\n}(jQuery);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/js/transition.js",
    "content": "/* ========================================================================\n * Bootstrap: transition.js v3.0.3\n * http://getbootstrap.com/javascript/#transitions\n * ========================================================================\n * Copyright 2013 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================================== */\n\n\n+function ($) { \"use strict\";\n\n  function transitionEnd() {\n    var el = document.createElement('bootstrap')\n\n    var transEndEventNames = {\n      'WebkitTransition' : 'webkitTransitionEnd'\n    , 'MozTransition'    : 'transitionend'\n    , 'OTransition'      : 'oTransitionEnd otransitionend'\n    , 'transition'       : 'transitionend'\n    }\n\n    for (var name in transEndEventNames) {\n      if (el.style[name] !== undefined) {\n        return { end: transEndEventNames[name] }\n      }\n    }\n  }\n  $.fn.emulateTransitionEnd = function (duration) {\n    var called = false, $el = this\n    $(this).one($.support.transition.end, function () { called = true })\n    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }\n    setTimeout(callback, duration)\n    return this\n  }\n\n  $(function () {\n    $.support.transition = transitionEnd()\n  })\n\n}(jQuery);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/alerts.less",
    "content": "//\n// Alerts\n// --------------------------------------------------\n\n\n// Base styles\n// -------------------------\n\n.alert {\n  padding: @alert-padding;\n  margin-bottom: @line-height-computed;\n  border: 1px solid transparent;\n  border-radius: @alert-border-radius;\n\n  // Headings for larger alerts\n  h4 {\n    margin-top: 0;\n    // Specified for the h4 to prevent conflicts of changing @headings-color\n    color: inherit;\n  }\n  // Provide class for links that match alerts\n  .alert-link {\n    font-weight: @alert-link-font-weight;\n  }\n\n  // Improve alignment and spacing of inner content\n  > p,\n  > ul {\n    margin-bottom: 0;\n  }\n  > p + p {\n    margin-top: 5px;\n  }\n}\n\n// Dismissable alerts\n//\n// Expand the right padding and account for the close button's positioning.\n\n.alert-dismissable {\n padding-right: (@alert-padding + 20);\n\n  // Adjust close link position\n  .close {\n    position: relative;\n    top: -2px;\n    right: -21px;\n    color: inherit;\n  }\n}\n\n// Alternate styles\n//\n// Generate contextual modifier classes for colorizing the alert.\n\n.alert-success {\n  .alert-variant(@alert-success-bg; @alert-success-border; @alert-success-text);\n}\n.alert-info {\n  .alert-variant(@alert-info-bg; @alert-info-border; @alert-info-text);\n}\n.alert-warning {\n  .alert-variant(@alert-warning-bg; @alert-warning-border; @alert-warning-text);\n}\n.alert-danger {\n  .alert-variant(@alert-danger-bg; @alert-danger-border; @alert-danger-text);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/badges.less",
    "content": "//\n// Badges\n// --------------------------------------------------\n\n\n// Base classes\n.badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: @font-size-small;\n  font-weight: @badge-font-weight;\n  color: @badge-color;\n  line-height: @badge-line-height;\n  vertical-align: baseline;\n  white-space: nowrap;\n  text-align: center;\n  background-color: @badge-bg;\n  border-radius: @badge-border-radius;\n\n  // Empty badges collapse automatically (not available in IE8)\n  &:empty {\n    display: none;\n  }\n\n  // Quick fix for badges in buttons\n  .btn & {\n    position: relative;\n    top: -1px;\n  }\n}\n\n// Hover state, but only for links\na.badge {\n  &:hover,\n  &:focus {\n    color: @badge-link-hover-color;\n    text-decoration: none;\n    cursor: pointer;\n  }\n}\n\n// Account for counters in navs\na.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n  color: @badge-active-color;\n  background-color: @badge-active-bg;\n}\n.nav-pills > li > a > .badge {\n  margin-left: 3px;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/bootstrap.less",
    "content": "// Core variables and mixins\n@import \"variables.less\";\n@import \"mixins.less\";\n\n// Reset\n@import \"normalize.less\";\n@import \"print.less\";\n\n// Core CSS\n@import \"scaffolding.less\";\n@import \"type.less\";\n@import \"code.less\";\n@import \"grid.less\";\n@import \"tables.less\";\n@import \"forms.less\";\n@import \"buttons.less\";\n\n// Components\n@import \"component-animations.less\";\n@import \"glyphicons.less\";\n@import \"dropdowns.less\";\n@import \"button-groups.less\";\n@import \"input-groups.less\";\n@import \"navs.less\";\n@import \"navbar.less\";\n@import \"breadcrumbs.less\";\n@import \"pagination.less\";\n@import \"pager.less\";\n@import \"labels.less\";\n@import \"badges.less\";\n@import \"jumbotron.less\";\n@import \"thumbnails.less\";\n@import \"alerts.less\";\n@import \"progress-bars.less\";\n@import \"media.less\";\n@import \"list-group.less\";\n@import \"panels.less\";\n@import \"wells.less\";\n@import \"close.less\";\n\n// Components w/ JavaScript\n@import \"modals.less\";\n@import \"tooltip.less\";\n@import \"popovers.less\";\n@import \"carousel.less\";\n\n// Utility classes\n@import \"utilities.less\";\n@import \"responsive-utilities.less\";\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/breadcrumbs.less",
    "content": "//\n// Breadcrumbs\n// --------------------------------------------------\n\n\n.breadcrumb {\n  padding: 8px 15px;\n  margin-bottom: @line-height-computed;\n  list-style: none;\n  background-color: @breadcrumb-bg;\n  border-radius: @border-radius-base;\n  > li {\n    display: inline-block;\n    + li:before {\n      content: \"@{breadcrumb-separator}\\00a0\"; // Unicode space added since inline-block means non-collapsing white-space\n      padding: 0 5px;\n      color: @breadcrumb-color;\n    }\n  }\n  > .active {\n    color: @breadcrumb-active-color;\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/button-groups.less",
    "content": "//\n// Button groups\n// --------------------------------------------------\n\n// Make the div behave like a button\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle; // match .btn alignment given font-size hack above\n  > .btn {\n    position: relative;\n    float: left;\n    // Bring the \"active\" button to the front\n    &:hover,\n    &:focus,\n    &:active,\n    &.active {\n      z-index: 2;\n    }\n    &:focus {\n      // Remove focus outline when dropdown JS adds it after closing the menu\n      outline: none;\n    }\n  }\n}\n\n// Prevent double borders when buttons are next to each other\n.btn-group {\n  .btn + .btn,\n  .btn + .btn-group,\n  .btn-group + .btn,\n  .btn-group + .btn-group {\n    margin-left: -1px;\n  }\n}\n\n// Optional: Group multiple button groups together for a toolbar\n.btn-toolbar {\n  .clearfix();\n\n  .btn-group {\n    float: left;\n  }\n  // Space out series of button groups\n  > .btn,\n  > .btn-group {\n    + .btn,\n    + .btn-group {\n      margin-left: 5px;\n    }\n  }\n}\n\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n  border-radius: 0;\n}\n\n// Set corners individual because sometimes a single button can be in a .btn-group and we need :first-child and :last-child to both match\n.btn-group > .btn:first-child {\n  margin-left: 0;\n  &:not(:last-child):not(.dropdown-toggle) {\n    .border-right-radius(0);\n  }\n}\n// Need .dropdown-toggle since :last-child doesn't apply given a .dropdown-menu immediately after it\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n  .border-left-radius(0);\n}\n\n// Custom edits for including btn-groups within btn-groups (useful for including dropdown buttons within a btn-group)\n.btn-group > .btn-group {\n  float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group > .btn-group:first-child {\n  > .btn:last-child,\n  > .dropdown-toggle {\n    .border-right-radius(0);\n  }\n}\n.btn-group > .btn-group:last-child > .btn:first-child {\n  .border-left-radius(0);\n}\n\n// On active and open, don't show outline\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n\n\n// Sizing\n//\n// Remix the default button sizing classes into new ones for easier manipulation.\n\n.btn-group-xs > .btn { .btn-xs(); }\n.btn-group-sm > .btn { .btn-sm(); }\n.btn-group-lg > .btn { .btn-lg(); }\n\n\n// Split button dropdowns\n// ----------------------\n\n// Give the line between buttons some depth\n.btn-group > .btn + .dropdown-toggle {\n  padding-left: 8px;\n  padding-right: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n  padding-left: 12px;\n  padding-right: 12px;\n}\n\n// The clickable button for toggling the menu\n// Remove the gradient and set the same inset shadow as the :active state\n.btn-group.open .dropdown-toggle {\n  .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n\n  // Show no shadow for `.btn-link` since it has no other button styles.\n  &.btn-link {\n    .box-shadow(none);\n  }\n}\n\n\n// Reposition the caret\n.btn .caret {\n  margin-left: 0;\n}\n// Carets in other button sizes\n.btn-lg .caret {\n  border-width: @caret-width-large @caret-width-large 0;\n  border-bottom-width: 0;\n}\n// Upside down carets for .dropup\n.dropup .btn-lg .caret {\n  border-width: 0 @caret-width-large @caret-width-large;\n}\n\n\n// Vertical button groups\n// ----------------------\n\n.btn-group-vertical {\n  > .btn,\n  > .btn-group,\n  > .btn-group > .btn {\n    display: block;\n    float: none;\n    width: 100%;\n    max-width: 100%;\n  }\n\n  // Clear floats so dropdown menus can be properly placed\n  > .btn-group {\n    .clearfix();\n    > .btn {\n      float: none;\n    }\n  }\n\n  > .btn + .btn,\n  > .btn + .btn-group,\n  > .btn-group + .btn,\n  > .btn-group + .btn-group {\n    margin-top: -1px;\n    margin-left: 0;\n  }\n}\n\n.btn-group-vertical > .btn {\n  &:not(:first-child):not(:last-child) {\n    border-radius: 0;\n  }\n  &:first-child:not(:last-child) {\n    border-top-right-radius: @border-radius-base;\n    .border-bottom-radius(0);\n  }\n  &:last-child:not(:first-child) {\n    border-bottom-left-radius: @border-radius-base;\n    .border-top-radius(0);\n  }\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child {\n  > .btn:last-child,\n  > .dropdown-toggle {\n    .border-bottom-radius(0);\n  }\n}\n.btn-group-vertical > .btn-group:last-child > .btn:first-child {\n  .border-top-radius(0);\n}\n\n\n\n// Justified button groups\n// ----------------------\n\n.btn-group-justified {\n  display: table;\n  width: 100%;\n  table-layout: fixed;\n  border-collapse: separate;\n  > .btn,\n  > .btn-group {\n    float: none;\n    display: table-cell;\n    width: 1%;\n  }\n  > .btn-group .btn {\n    width: 100%;\n  }\n}\n\n\n// Checkbox and radio options\n[data-toggle=\"buttons\"] > .btn > input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn > input[type=\"checkbox\"] {\n  display: none;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/buttons.less",
    "content": "//\n// Buttons\n// --------------------------------------------------\n\n\n// Base styles\n// --------------------------------------------------\n\n.btn {\n  display: inline-block;\n  margin-bottom: 0; // For input.btn\n  font-weight: @btn-font-weight;\n  text-align: center;\n  vertical-align: middle;\n  cursor: pointer;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid transparent;\n  white-space: nowrap;\n  .button-size(@padding-base-vertical; @padding-base-horizontal; @font-size-base; @line-height-base; @border-radius-base);\n  .user-select(none);\n\n  &:focus {\n    .tab-focus();\n  }\n\n  &:hover,\n  &:focus {\n    color: @btn-default-color;\n    text-decoration: none;\n  }\n\n  &:active,\n  &.active {\n    outline: 0;\n    background-image: none;\n    .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n  }\n\n  &.disabled,\n  &[disabled],\n  fieldset[disabled] & {\n    cursor: not-allowed;\n    pointer-events: none; // Future-proof disabling of clicks\n    .opacity(.65);\n    .box-shadow(none);\n  }\n}\n\n\n// Alternate buttons\n// --------------------------------------------------\n\n.btn-default {\n  .button-variant(@btn-default-color; @btn-default-bg; @btn-default-border);\n}\n.btn-primary {\n  .button-variant(@btn-primary-color; @btn-primary-bg; @btn-primary-border);\n}\n// Warning appears as orange\n.btn-warning {\n  .button-variant(@btn-warning-color; @btn-warning-bg; @btn-warning-border);\n}\n// Danger and error appear as red\n.btn-danger {\n  .button-variant(@btn-danger-color; @btn-danger-bg; @btn-danger-border);\n}\n// Success appears as green\n.btn-success {\n  .button-variant(@btn-success-color; @btn-success-bg; @btn-success-border);\n}\n// Info appears as blue-green\n.btn-info {\n  .button-variant(@btn-info-color; @btn-info-bg; @btn-info-border);\n}\n\n\n// Link buttons\n// -------------------------\n\n// Make a button look and behave like a link\n.btn-link {\n  color: @link-color;\n  font-weight: normal;\n  cursor: pointer;\n  border-radius: 0;\n\n  &,\n  &:active,\n  &[disabled],\n  fieldset[disabled] & {\n    background-color: transparent;\n    .box-shadow(none);\n  }\n  &,\n  &:hover,\n  &:focus,\n  &:active {\n    border-color: transparent;\n  }\n  &:hover,\n  &:focus {\n    color: @link-hover-color;\n    text-decoration: underline;\n    background-color: transparent;\n  }\n  &[disabled],\n  fieldset[disabled] & {\n    &:hover,\n    &:focus {\n      color: @btn-link-disabled-color;\n      text-decoration: none;\n    }\n  }\n}\n\n\n// Button Sizes\n// --------------------------------------------------\n\n.btn-lg {\n  // line-height: ensure even-numbered height of button next to large input\n  .button-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n.btn-sm {\n  // line-height: ensure proper height of button next to small input\n  .button-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n.btn-xs {\n  .button-size(@padding-xs-vertical; @padding-xs-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n\n\n// Block button\n// --------------------------------------------------\n\n.btn-block {\n  display: block;\n  width: 100%;\n  padding-left: 0;\n  padding-right: 0;\n}\n\n// Vertically space out multiple block buttons\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\n\n// Specificity overrides\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"] {\n  &.btn-block {\n    width: 100%;\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/carousel.less",
    "content": "//\n// Carousel\n// --------------------------------------------------\n\n\n// Wrapper for the slide container and indicators\n.carousel {\n  position: relative;\n}\n\n.carousel-inner {\n  position: relative;\n  overflow: hidden;\n  width: 100%;\n\n  > .item {\n    display: none;\n    position: relative;\n    .transition(.6s ease-in-out left);\n\n    // Account for jankitude on images\n    > img,\n    > a > img {\n      .img-responsive();\n      line-height: 1;\n    }\n  }\n\n  > .active,\n  > .next,\n  > .prev { display: block; }\n\n  > .active {\n    left: 0;\n  }\n\n  > .next,\n  > .prev {\n    position: absolute;\n    top: 0;\n    width: 100%;\n  }\n\n  > .next {\n    left: 100%;\n  }\n  > .prev {\n    left: -100%;\n  }\n  > .next.left,\n  > .prev.right {\n    left: 0;\n  }\n\n  > .active.left {\n    left: -100%;\n  }\n  > .active.right {\n    left: 100%;\n  }\n\n}\n\n// Left/right controls for nav\n// ---------------------------\n\n.carousel-control {\n  position: absolute;\n  top: 0;\n  left: 0;\n  bottom: 0;\n  width: @carousel-control-width;\n  .opacity(@carousel-control-opacity);\n  font-size: @carousel-control-font-size;\n  color: @carousel-control-color;\n  text-align: center;\n  text-shadow: @carousel-text-shadow;\n  // We can't have this transition here because WebKit cancels the carousel\n  // animation if you trip this while in the middle of another animation.\n\n  // Set gradients for backgrounds\n  &.left {\n    #gradient > .horizontal(@start-color: rgba(0,0,0,.5); @end-color: rgba(0,0,0,.0001));\n  }\n  &.right {\n    left: auto;\n    right: 0;\n    #gradient > .horizontal(@start-color: rgba(0,0,0,.0001); @end-color: rgba(0,0,0,.5));\n  }\n\n  // Hover/focus state\n  &:hover,\n  &:focus {\n    outline: none;\n    color: @carousel-control-color;\n    text-decoration: none;\n    .opacity(.9);\n  }\n\n  // Toggles\n  .icon-prev,\n  .icon-next,\n  .glyphicon-chevron-left,\n  .glyphicon-chevron-right {\n    position: absolute;\n    top: 50%;\n    z-index: 5;\n    display: inline-block;\n  }\n  .icon-prev,\n  .glyphicon-chevron-left {\n    left: 50%;\n  }\n  .icon-next,\n  .glyphicon-chevron-right {\n    right: 50%;\n  }\n  .icon-prev,\n  .icon-next {\n    width:  20px;\n    height: 20px;\n    margin-top: -10px;\n    margin-left: -10px;\n    font-family: serif;\n  }\n\n  .icon-prev {\n    &:before {\n      content: '\\2039';// SINGLE LEFT-POINTING ANGLE QUOTATION MARK (U+2039)\n    }\n  }\n  .icon-next {\n    &:before {\n      content: '\\203a';// SINGLE RIGHT-POINTING ANGLE QUOTATION MARK (U+203A)\n    }\n  }\n}\n\n// Optional indicator pips\n//\n// Add an unordered list with the following class and add a list item for each\n// slide your carousel holds.\n\n.carousel-indicators {\n  position: absolute;\n  bottom: 10px;\n  left: 50%;\n  z-index: 15;\n  width: 60%;\n  margin-left: -30%;\n  padding-left: 0;\n  list-style: none;\n  text-align: center;\n\n  li {\n    display: inline-block;\n    width:  10px;\n    height: 10px;\n    margin: 1px;\n    text-indent: -999px;\n    border: 1px solid @carousel-indicator-border-color;\n    border-radius: 10px;\n    cursor: pointer;\n\n    // IE8-9 hack for event handling\n    //\n    // Internet Explorer 8-9 does not support clicks on elements without a set\n    // `background-color`. We cannot use `filter` since that's not viewed as a\n    // background color by the browser. Thus, a hack is needed.\n    //\n    // For IE8, we set solid black as it doesn't support `rgba()`. For IE9, we\n    // set alpha transparency for the best results possible.\n    background-color: #000 \\9; // IE8\n    background-color: rgba(0,0,0,0); // IE9\n  }\n  .active {\n    margin: 0;\n    width:  12px;\n    height: 12px;\n    background-color: @carousel-indicator-active-bg;\n  }\n}\n\n// Optional captions\n// -----------------------------\n// Hidden by default for smaller viewports\n.carousel-caption {\n  position: absolute;\n  left: 15%;\n  right: 15%;\n  bottom: 20px;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: @carousel-caption-color;\n  text-align: center;\n  text-shadow: @carousel-text-shadow;\n  & .btn {\n    text-shadow: none; // No shadow for button elements in carousel-caption\n  }\n}\n\n\n// Scale up controls for tablets and up\n@media screen and (min-width: @screen-sm-min) {\n\n  // Scale up the controls a smidge\n  .carousel-control {\n    .glyphicons-chevron-left,\n    .glyphicons-chevron-right,\n    .icon-prev,\n    .icon-next {\n      width: 30px;\n      height: 30px;\n      margin-top: -15px;\n      margin-left: -15px;\n      font-size: 30px;\n    }\n  }\n\n  // Show and left align the captions\n  .carousel-caption {\n    left: 20%;\n    right: 20%;\n    padding-bottom: 30px;\n  }\n\n  // Move up the indicators\n  .carousel-indicators {\n    bottom: 20px;\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/close.less",
    "content": "//\n// Close icons\n// --------------------------------------------------\n\n\n.close {\n  float: right;\n  font-size: (@font-size-base * 1.5);\n  font-weight: @close-font-weight;\n  line-height: 1;\n  color: @close-color;\n  text-shadow: @close-text-shadow;\n  .opacity(.2);\n\n  &:hover,\n  &:focus {\n    color: @close-color;\n    text-decoration: none;\n    cursor: pointer;\n    .opacity(.5);\n  }\n\n  // Additional properties for button version\n  // iOS requires the button element instead of an anchor tag.\n  // If you want the anchor version, it requires `href=\"#\"`.\n  button& {\n    padding: 0;\n    cursor: pointer;\n    background: transparent;\n    border: 0;\n    -webkit-appearance: none;\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/code.less",
    "content": "//\n// Code (inline and block)\n// --------------------------------------------------\n\n\n// Inline and block code styles\ncode,\nkbd,\npre,\nsamp {\n  font-family: @font-family-monospace;\n}\n\n// Inline code\ncode {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: @code-color;\n  background-color: @code-bg;\n  white-space: nowrap;\n  border-radius: @border-radius-base;\n}\n\n// Blocks of code\npre {\n  display: block;\n  padding: ((@line-height-computed - 1) / 2);\n  margin: 0 0 (@line-height-computed / 2);\n  font-size: (@font-size-base - 1); // 14px to 13px\n  line-height: @line-height-base;\n  word-break: break-all;\n  word-wrap: break-word;\n  color: @pre-color;\n  background-color: @pre-bg;\n  border: 1px solid @pre-border-color;\n  border-radius: @border-radius-base;\n\n  // Account for some code outputs that place code tags in pre tags\n  code {\n    padding: 0;\n    font-size: inherit;\n    color: inherit;\n    white-space: pre-wrap;\n    background-color: transparent;\n    border-radius: 0;\n  }\n}\n\n// Enable scrollable blocks of code\n.pre-scrollable {\n  max-height: @pre-scrollable-max-height;\n  overflow-y: scroll;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/component-animations.less",
    "content": "//\n// Component animations\n// --------------------------------------------------\n\n// Heads up!\n//\n// We don't use the `.opacity()` mixin here since it causes a bug with text\n// fields in IE7-8. Source: https://github.com/twitter/bootstrap/pull/3552.\n\n.fade {\n  opacity: 0;\n  .transition(opacity .15s linear);\n  &.in {\n    opacity: 1;\n  }\n}\n\n.collapse {\n  display: none;\n  &.in {\n    display: block;\n  }\n}\n.collapsing {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  .transition(height .35s ease);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/dropdowns.less",
    "content": "//\n// Dropdown menus\n// --------------------------------------------------\n\n\n// Dropdown arrow/caret\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  margin-left: 2px;\n  vertical-align: middle;\n  border-top:   @caret-width-base solid;\n  border-right: @caret-width-base solid transparent;\n  border-left:  @caret-width-base solid transparent;\n}\n\n// The dropdown wrapper (div)\n.dropdown {\n  position: relative;\n}\n\n// Prevent the focus on the dropdown toggle when closing dropdowns\n.dropdown-toggle:focus {\n  outline: 0;\n}\n\n// The dropdown menu (ul)\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: @zindex-dropdown;\n  display: none; // none by default, but block on \"open\" of the menu\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0; // override default ul\n  list-style: none;\n  font-size: @font-size-base;\n  background-color: @dropdown-bg;\n  border: 1px solid @dropdown-fallback-border; // IE8 fallback\n  border: 1px solid @dropdown-border;\n  border-radius: @border-radius-base;\n  .box-shadow(0 6px 12px rgba(0,0,0,.175));\n  background-clip: padding-box;\n\n  // Aligns the dropdown menu to right\n  &.pull-right {\n    right: 0;\n    left: auto;\n  }\n\n  // Dividers (basically an hr) within the dropdown\n  .divider {\n    .nav-divider(@dropdown-divider-bg);\n  }\n\n  // Links within the dropdown menu\n  > li > a {\n    display: block;\n    padding: 3px 20px;\n    clear: both;\n    font-weight: normal;\n    line-height: @line-height-base;\n    color: @dropdown-link-color;\n    white-space: nowrap; // prevent links from randomly breaking onto new lines\n  }\n}\n\n// Hover/Focus state\n.dropdown-menu > li > a {\n  &:hover,\n  &:focus {\n    text-decoration: none;\n    color: @dropdown-link-hover-color;\n    background-color: @dropdown-link-hover-bg;\n  }\n}\n\n// Active state\n.dropdown-menu > .active > a {\n  &,\n  &:hover,\n  &:focus {\n    color: @dropdown-link-active-color;\n    text-decoration: none;\n    outline: 0;\n    background-color: @dropdown-link-active-bg;\n  }\n}\n\n// Disabled state\n//\n// Gray out text and ensure the hover/focus state remains gray\n\n.dropdown-menu > .disabled > a {\n  &,\n  &:hover,\n  &:focus {\n    color: @dropdown-link-disabled-color;\n  }\n}\n// Nuke hover/focus effects\n.dropdown-menu > .disabled > a {\n  &:hover,\n  &:focus {\n    text-decoration: none;\n    background-color: transparent;\n    background-image: none; // Remove CSS gradient\n    .reset-filter();\n    cursor: not-allowed;\n  }\n}\n\n// Open state for the dropdown\n.open {\n  // Show the menu\n  > .dropdown-menu {\n    display: block;\n  }\n\n  // Remove the outline when :focus is triggered\n  > a {\n    outline: 0;\n  }\n}\n\n// Dropdown section headers\n.dropdown-header {\n  display: block;\n  padding: 3px 20px;\n  font-size: @font-size-small;\n  line-height: @line-height-base;\n  color: @dropdown-header-color;\n}\n\n// Backdrop to catch body clicks on mobile, etc.\n.dropdown-backdrop {\n  position: fixed;\n  left: 0;\n  right: 0;\n  bottom: 0;\n  top: 0;\n  z-index: @zindex-dropdown - 10;\n}\n\n// Right aligned dropdowns\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n\n// Allow for dropdowns to go bottom up (aka, dropup-menu)\n//\n// Just add .dropup after the standard .dropdown class and you're set, bro.\n// TODO: abstract this so that the navbar fixed styles are not placed here?\n\n.dropup,\n.navbar-fixed-bottom .dropdown {\n  // Reverse the caret\n  .caret {\n    border-top: 0;\n    border-bottom: @caret-width-base solid;\n    content: \"\";\n  }\n  // Different positioning for bottom up menu\n  .dropdown-menu {\n    top: auto;\n    bottom: 100%;\n    margin-bottom: 1px;\n  }\n}\n\n\n// Component alignment\n//\n// Reiterate per navbar.less and the modified component alignment there.\n\n@media (min-width: @grid-float-breakpoint) {\n  .navbar-right {\n    .dropdown-menu {\n      .pull-right > .dropdown-menu();\n    }\n  }\n}\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/forms.less",
    "content": "//\n// Forms\n// --------------------------------------------------\n\n\n// Normalize non-controls\n//\n// Restyle and baseline non-control form elements.\n\nfieldset {\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\n\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: @line-height-computed;\n  font-size: (@font-size-base * 1.5);\n  line-height: inherit;\n  color: @legend-color;\n  border: 0;\n  border-bottom: 1px solid @legend-border-color;\n}\n\nlabel {\n  display: inline-block;\n  margin-bottom: 5px;\n  font-weight: bold;\n}\n\n\n// Normalize form controls\n\n// Override content-box in Normalize (* isn't specific enough)\ninput[type=\"search\"] {\n  .box-sizing(border-box);\n}\n\n// Position radios and checkboxes better\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9; /* IE8-9 */\n  line-height: normal;\n}\n\n// Set the height of select and file controls to match text inputs\ninput[type=\"file\"] {\n  display: block;\n}\n\n// Make multiple select elements height not fixed\nselect[multiple],\nselect[size] {\n  height: auto;\n}\n\n// Fix optgroup Firefox bug per https://github.com/twbs/bootstrap/issues/7611\nselect optgroup {\n  font-size: inherit;\n  font-style: inherit;\n  font-family: inherit;\n}\n\n// Focus for select, file, radio, and checkbox\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  .tab-focus();\n}\n\n// Fix for Chrome number input\n// Setting certain font-sizes causes the `I` bar to appear on hover of the bottom increment button.\n// See https://github.com/twbs/bootstrap/issues/8350 for more.\ninput[type=\"number\"] {\n  &::-webkit-outer-spin-button,\n  &::-webkit-inner-spin-button {\n    height: auto;\n  }\n}\n\n// Adjust output element\noutput {\n  display: block;\n  padding-top: (@padding-base-vertical + 1);\n  font-size: @font-size-base;\n  line-height: @line-height-base;\n  color: @input-color;\n  vertical-align: middle;\n}\n\n\n// Common form controls\n//\n// Shared size and type resets for form controls. Apply `.form-control` to any\n// of the following form controls:\n//\n// select\n// textarea\n// input[type=\"text\"]\n// input[type=\"password\"]\n// input[type=\"datetime\"]\n// input[type=\"datetime-local\"]\n// input[type=\"date\"]\n// input[type=\"month\"]\n// input[type=\"time\"]\n// input[type=\"week\"]\n// input[type=\"number\"]\n// input[type=\"email\"]\n// input[type=\"url\"]\n// input[type=\"search\"]\n// input[type=\"tel\"]\n// input[type=\"color\"]\n\n.form-control {\n  display: block;\n  width: 100%;\n  height: @input-height-base; // Make inputs at least the height of their button counterpart (base line-height + padding + border)\n  padding: @padding-base-vertical @padding-base-horizontal;\n  font-size: @font-size-base;\n  line-height: @line-height-base;\n  color: @input-color;\n  vertical-align: middle;\n  background-color: @input-bg;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid @input-border;\n  border-radius: @input-border-radius;\n  .box-shadow(inset 0 1px 1px rgba(0,0,0,.075));\n  .transition(~\"border-color ease-in-out .15s, box-shadow ease-in-out .15s\");\n\n  // Customize the `:focus` state to imitate native WebKit styles.\n  .form-control-focus();\n\n  // Placeholder\n  //\n  // Placeholder text gets special styles because when browsers invalidate entire\n  // lines if it doesn't understand a selector/\n  .placeholder();\n\n  // Disabled and read-only inputs\n  // Note: HTML5 says that controls under a fieldset > legend:first-child won't\n  // be disabled if the fieldset is disabled. Due to implementation difficulty,\n  // we don't honor that edge case; we style them as disabled anyway.\n  &[disabled],\n  &[readonly],\n  fieldset[disabled] & {\n    cursor: not-allowed;\n    background-color: @input-bg-disabled;\n  }\n\n  // Reset height for `textarea`s\n  textarea& {\n    height: auto;\n  }\n}\n\n\n// Form groups\n//\n// Designed to help with the organization and spacing of vertical forms. For\n// horizontal forms, use the predefined grid classes.\n\n.form-group {\n  margin-bottom: 15px;\n}\n\n\n// Checkboxes and radios\n//\n// Indent the labels to position radios/checkboxes as hanging controls.\n\n.radio,\n.checkbox {\n  display: block;\n  min-height: @line-height-computed; // clear the floating input if there is no label text\n  margin-top: 10px;\n  margin-bottom: 10px;\n  padding-left: 20px;\n  vertical-align: middle;\n  label {\n    display: inline;\n    margin-bottom: 0;\n    font-weight: normal;\n    cursor: pointer;\n  }\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  float: left;\n  margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px; // Move up sibling radios or checkboxes for tighter spacing\n}\n\n// Radios and checkboxes on same line\n.radio-inline,\n.checkbox-inline {\n  display: inline-block;\n  padding-left: 20px;\n  margin-bottom: 0;\n  vertical-align: middle;\n  font-weight: normal;\n  cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px; // space out consecutive inline controls\n}\n\n// Apply same disabled cursor tweak as for inputs\n//\n// Note: Neither radios nor checkboxes can be readonly.\ninput[type=\"radio\"],\ninput[type=\"checkbox\"],\n.radio,\n.radio-inline,\n.checkbox,\n.checkbox-inline {\n  &[disabled],\n  fieldset[disabled] & {\n    cursor: not-allowed;\n  }\n}\n\n// Form control sizing\n.input-sm {\n  .input-size(@input-height-small; @padding-small-vertical; @padding-small-horizontal; @font-size-small; @line-height-small; @border-radius-small);\n}\n\n.input-lg {\n  .input-size(@input-height-large; @padding-large-vertical; @padding-large-horizontal; @font-size-large; @line-height-large; @border-radius-large);\n}\n\n\n// Form control feedback states\n//\n// Apply contextual and semantic states to individual form controls.\n\n// Warning\n.has-warning {\n  .form-control-validation(@state-warning-text; @state-warning-text; @state-warning-bg);\n}\n// Error\n.has-error {\n  .form-control-validation(@state-danger-text; @state-danger-text; @state-danger-bg);\n}\n// Success\n.has-success {\n  .form-control-validation(@state-success-text; @state-success-text; @state-success-bg);\n}\n\n\n// Static form control text\n//\n// Apply class to a `p` element to make any string of text align with labels in\n// a horizontal form layout.\n\n.form-control-static {\n  margin-bottom: 0; // Remove default margin from `p`\n}\n\n\n// Help text\n//\n// Apply to any element you wish to create light text for placement immediately\n// below a form control. Use for general help, formatting, or instructional text.\n\n.help-block {\n  display: block; // account for any element using help-block\n  margin-top: 5px;\n  margin-bottom: 10px;\n  color: lighten(@text-color, 25%); // lighten the text some for contrast\n}\n\n\n\n// Inline forms\n//\n// Make forms appear inline(-block) by adding the `.form-inline` class. Inline\n// forms begin stacked on extra small (mobile) devices and then go inline when\n// viewports reach <768px.\n//\n// Requires wrapping inputs and labels with `.form-group` for proper display of\n// default HTML form controls and our custom form controls (e.g., input groups).\n//\n// Heads up! This is mixin-ed into `.navbar-form` in navbars.less.\n\n.form-inline {\n\n  // Kick in the inline\n  @media (min-width: @screen-sm) {\n    // Inline-block all the things for \"inline\"\n    .form-group  {\n      display: inline-block;\n      margin-bottom: 0;\n      vertical-align: middle;\n    }\n\n    // In navbar-form, allow folks to *not* use `.form-group`\n    .form-control {\n      display: inline-block;\n    }\n\n    // Override `width: 100%;` when not within a `.form-group`\n    select.form-control {\n      width: auto;\n    }\n\n    // Remove default margin on radios/checkboxes that were used for stacking, and\n    // then undo the floating of radios and checkboxes to match (which also avoids\n    // a bug in WebKit: https://github.com/twbs/bootstrap/issues/1969).\n    .radio,\n    .checkbox {\n      display: inline-block;\n      margin-top: 0;\n      margin-bottom: 0;\n      padding-left: 0;\n    }\n    .radio input[type=\"radio\"],\n    .checkbox input[type=\"checkbox\"] {\n      float: none;\n      margin-left: 0;\n    }\n  }\n}\n\n\n// Horizontal forms\n//\n// Horizontal forms are built on grid classes and allow you to create forms with\n// labels on the left and inputs on the right.\n\n.form-horizontal {\n\n  // Consistent vertical alignment of labels, radios, and checkboxes\n  .control-label,\n  .radio,\n  .checkbox,\n  .radio-inline,\n  .checkbox-inline {\n    margin-top: 0;\n    margin-bottom: 0;\n    padding-top: (@padding-base-vertical + 1); // Default padding plus a border\n  }\n  // Account for padding we're adding to ensure the alignment and of help text\n  // and other content below items\n  .radio,\n  .checkbox {\n    min-height: @line-height-computed + (@padding-base-vertical + 1);\n  }\n\n  // Make form groups behave like rows\n  .form-group {\n    .make-row();\n  }\n\n  .form-control-static {\n    padding-top: (@padding-base-vertical + 1);\n  }\n\n  // Only right align form labels here when the columns stop stacking\n  @media (min-width: @screen-sm-min) {\n    .control-label {\n      text-align: right;\n    }\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/glyphicons.less",
    "content": "//\n// Glyphicons for Bootstrap\n//\n// Since icons are fonts, they can be placed anywhere text is placed and are\n// thus automatically sized to match the surrounding child. To use, create an\n// inline element with the appropriate classes, like so:\n//\n// <a href=\"#\"><span class=\"glyphicon glyphicon-star\"></span> Star</a>\n\n// Import the fonts\n@font-face {\n  font-family: 'Glyphicons Halflings';\n  src: ~\"url('@{icon-font-path}@{icon-font-name}.eot')\";\n  src: ~\"url('@{icon-font-path}@{icon-font-name}.eot?#iefix') format('embedded-opentype')\",\n       ~\"url('@{icon-font-path}@{icon-font-name}.woff') format('woff')\",\n       ~\"url('@{icon-font-path}@{icon-font-name}.ttf') format('truetype')\",\n       ~\"url('@{icon-font-path}@{icon-font-name}.svg#glyphicons-halflingsregular') format('svg')\";\n}\n\n// Catchall baseclass\n.glyphicon {\n  position: relative;\n  top: 1px;\n  display: inline-block;\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n\n  &:empty {\n    width: 1em;\n  }\n}\n\n// Individual icons\n.glyphicon-asterisk               { &:before { content: \"\\2a\"; } }\n.glyphicon-plus                   { &:before { content: \"\\2b\"; } }\n.glyphicon-euro                   { &:before { content: \"\\20ac\"; } }\n.glyphicon-minus                  { &:before { content: \"\\2212\"; } }\n.glyphicon-cloud                  { &:before { content: \"\\2601\"; } }\n.glyphicon-envelope               { &:before { content: \"\\2709\"; } }\n.glyphicon-pencil                 { &:before { content: \"\\270f\"; } }\n.glyphicon-glass                  { &:before { content: \"\\e001\"; } }\n.glyphicon-music                  { &:before { content: \"\\e002\"; } }\n.glyphicon-search                 { &:before { content: \"\\e003\"; } }\n.glyphicon-heart                  { &:before { content: \"\\e005\"; } }\n.glyphicon-star                   { &:before { content: \"\\e006\"; } }\n.glyphicon-star-empty             { &:before { content: \"\\e007\"; } }\n.glyphicon-user                   { &:before { content: \"\\e008\"; } }\n.glyphicon-film                   { &:before { content: \"\\e009\"; } }\n.glyphicon-th-large               { &:before { content: \"\\e010\"; } }\n.glyphicon-th                     { &:before { content: \"\\e011\"; } }\n.glyphicon-th-list                { &:before { content: \"\\e012\"; } }\n.glyphicon-ok                     { &:before { content: \"\\e013\"; } }\n.glyphicon-remove                 { &:before { content: \"\\e014\"; } }\n.glyphicon-zoom-in                { &:before { content: \"\\e015\"; } }\n.glyphicon-zoom-out               { &:before { content: \"\\e016\"; } }\n.glyphicon-off                    { &:before { content: \"\\e017\"; } }\n.glyphicon-signal                 { &:before { content: \"\\e018\"; } }\n.glyphicon-cog                    { &:before { content: \"\\e019\"; } }\n.glyphicon-trash                  { &:before { content: \"\\e020\"; } }\n.glyphicon-home                   { &:before { content: \"\\e021\"; } }\n.glyphicon-file                   { &:before { content: \"\\e022\"; } }\n.glyphicon-time                   { &:before { content: \"\\e023\"; } }\n.glyphicon-road                   { &:before { content: \"\\e024\"; } }\n.glyphicon-download-alt           { &:before { content: \"\\e025\"; } }\n.glyphicon-download               { &:before { content: \"\\e026\"; } }\n.glyphicon-upload                 { &:before { content: \"\\e027\"; } }\n.glyphicon-inbox                  { &:before { content: \"\\e028\"; } }\n.glyphicon-play-circle            { &:before { content: \"\\e029\"; } }\n.glyphicon-repeat                 { &:before { content: \"\\e030\"; } }\n.glyphicon-refresh                { &:before { content: \"\\e031\"; } }\n.glyphicon-list-alt               { &:before { content: \"\\e032\"; } }\n.glyphicon-lock                   { &:before { content: \"\\e033\"; } }\n.glyphicon-flag                   { &:before { content: \"\\e034\"; } }\n.glyphicon-headphones             { &:before { content: \"\\e035\"; } }\n.glyphicon-volume-off             { &:before { content: \"\\e036\"; } }\n.glyphicon-volume-down            { &:before { content: \"\\e037\"; } }\n.glyphicon-volume-up              { &:before { content: \"\\e038\"; } }\n.glyphicon-qrcode                 { &:before { content: \"\\e039\"; } }\n.glyphicon-barcode                { &:before { content: \"\\e040\"; } }\n.glyphicon-tag                    { &:before { content: \"\\e041\"; } }\n.glyphicon-tags                   { &:before { content: \"\\e042\"; } }\n.glyphicon-book                   { &:before { content: \"\\e043\"; } }\n.glyphicon-bookmark               { &:before { content: \"\\e044\"; } }\n.glyphicon-print                  { &:before { content: \"\\e045\"; } }\n.glyphicon-camera                 { &:before { content: \"\\e046\"; } }\n.glyphicon-font                   { &:before { content: \"\\e047\"; } }\n.glyphicon-bold                   { &:before { content: \"\\e048\"; } }\n.glyphicon-italic                 { &:before { content: \"\\e049\"; } }\n.glyphicon-text-height            { &:before { content: \"\\e050\"; } }\n.glyphicon-text-width             { &:before { content: \"\\e051\"; } }\n.glyphicon-align-left             { &:before { content: \"\\e052\"; } }\n.glyphicon-align-center           { &:before { content: \"\\e053\"; } }\n.glyphicon-align-right            { &:before { content: \"\\e054\"; } }\n.glyphicon-align-justify          { &:before { content: \"\\e055\"; } }\n.glyphicon-list                   { &:before { content: \"\\e056\"; } }\n.glyphicon-indent-left            { &:before { content: \"\\e057\"; } }\n.glyphicon-indent-right           { &:before { content: \"\\e058\"; } }\n.glyphicon-facetime-video         { &:before { content: \"\\e059\"; } }\n.glyphicon-picture                { &:before { content: \"\\e060\"; } }\n.glyphicon-map-marker             { &:before { content: \"\\e062\"; } }\n.glyphicon-adjust                 { &:before { content: \"\\e063\"; } }\n.glyphicon-tint                   { &:before { content: \"\\e064\"; } }\n.glyphicon-edit                   { &:before { content: \"\\e065\"; } }\n.glyphicon-share                  { &:before { content: \"\\e066\"; } }\n.glyphicon-check                  { &:before { content: \"\\e067\"; } }\n.glyphicon-move                   { &:before { content: \"\\e068\"; } }\n.glyphicon-step-backward          { &:before { content: \"\\e069\"; } }\n.glyphicon-fast-backward          { &:before { content: \"\\e070\"; } }\n.glyphicon-backward               { &:before { content: \"\\e071\"; } }\n.glyphicon-play                   { &:before { content: \"\\e072\"; } }\n.glyphicon-pause                  { &:before { content: \"\\e073\"; } }\n.glyphicon-stop                   { &:before { content: \"\\e074\"; } }\n.glyphicon-forward                { &:before { content: \"\\e075\"; } }\n.glyphicon-fast-forward           { &:before { content: \"\\e076\"; } }\n.glyphicon-step-forward           { &:before { content: \"\\e077\"; } }\n.glyphicon-eject                  { &:before { content: \"\\e078\"; } }\n.glyphicon-chevron-left           { &:before { content: \"\\e079\"; } }\n.glyphicon-chevron-right          { &:before { content: \"\\e080\"; } }\n.glyphicon-plus-sign              { &:before { content: \"\\e081\"; } }\n.glyphicon-minus-sign             { &:before { content: \"\\e082\"; } }\n.glyphicon-remove-sign            { &:before { content: \"\\e083\"; } }\n.glyphicon-ok-sign                { &:before { content: \"\\e084\"; } }\n.glyphicon-question-sign          { &:before { content: \"\\e085\"; } }\n.glyphicon-info-sign              { &:before { content: \"\\e086\"; } }\n.glyphicon-screenshot             { &:before { content: \"\\e087\"; } }\n.glyphicon-remove-circle          { &:before { content: \"\\e088\"; } }\n.glyphicon-ok-circle              { &:before { content: \"\\e089\"; } }\n.glyphicon-ban-circle             { &:before { content: \"\\e090\"; } }\n.glyphicon-arrow-left             { &:before { content: \"\\e091\"; } }\n.glyphicon-arrow-right            { &:before { content: \"\\e092\"; } }\n.glyphicon-arrow-up               { &:before { content: \"\\e093\"; } }\n.glyphicon-arrow-down             { &:before { content: \"\\e094\"; } }\n.glyphicon-share-alt              { &:before { content: \"\\e095\"; } }\n.glyphicon-resize-full            { &:before { content: \"\\e096\"; } }\n.glyphicon-resize-small           { &:before { content: \"\\e097\"; } }\n.glyphicon-exclamation-sign       { &:before { content: \"\\e101\"; } }\n.glyphicon-gift                   { &:before { content: \"\\e102\"; } }\n.glyphicon-leaf                   { &:before { content: \"\\e103\"; } }\n.glyphicon-fire                   { &:before { content: \"\\e104\"; } }\n.glyphicon-eye-open               { &:before { content: \"\\e105\"; } }\n.glyphicon-eye-close              { &:before { content: \"\\e106\"; } }\n.glyphicon-warning-sign           { &:before { content: \"\\e107\"; } }\n.glyphicon-plane                  { &:before { content: \"\\e108\"; } }\n.glyphicon-calendar               { &:before { content: \"\\e109\"; } }\n.glyphicon-random                 { &:before { content: \"\\e110\"; } }\n.glyphicon-comment                { &:before { content: \"\\e111\"; } }\n.glyphicon-magnet                 { &:before { content: \"\\e112\"; } }\n.glyphicon-chevron-up             { &:before { content: \"\\e113\"; } }\n.glyphicon-chevron-down           { &:before { content: \"\\e114\"; } }\n.glyphicon-retweet                { &:before { content: \"\\e115\"; } }\n.glyphicon-shopping-cart          { &:before { content: \"\\e116\"; } }\n.glyphicon-folder-close           { &:before { content: \"\\e117\"; } }\n.glyphicon-folder-open            { &:before { content: \"\\e118\"; } }\n.glyphicon-resize-vertical        { &:before { content: \"\\e119\"; } }\n.glyphicon-resize-horizontal      { &:before { content: \"\\e120\"; } }\n.glyphicon-hdd                    { &:before { content: \"\\e121\"; } }\n.glyphicon-bullhorn               { &:before { content: \"\\e122\"; } }\n.glyphicon-bell                   { &:before { content: \"\\e123\"; } }\n.glyphicon-certificate            { &:before { content: \"\\e124\"; } }\n.glyphicon-thumbs-up              { &:before { content: \"\\e125\"; } }\n.glyphicon-thumbs-down            { &:before { content: \"\\e126\"; } }\n.glyphicon-hand-right             { &:before { content: \"\\e127\"; } }\n.glyphicon-hand-left              { &:before { content: \"\\e128\"; } }\n.glyphicon-hand-up                { &:before { content: \"\\e129\"; } }\n.glyphicon-hand-down              { &:before { content: \"\\e130\"; } }\n.glyphicon-circle-arrow-right     { &:before { content: \"\\e131\"; } }\n.glyphicon-circle-arrow-left      { &:before { content: \"\\e132\"; } }\n.glyphicon-circle-arrow-up        { &:before { content: \"\\e133\"; } }\n.glyphicon-circle-arrow-down      { &:before { content: \"\\e134\"; } }\n.glyphicon-globe                  { &:before { content: \"\\e135\"; } }\n.glyphicon-wrench                 { &:before { content: \"\\e136\"; } }\n.glyphicon-tasks                  { &:before { content: \"\\e137\"; } }\n.glyphicon-filter                 { &:before { content: \"\\e138\"; } }\n.glyphicon-briefcase              { &:before { content: \"\\e139\"; } }\n.glyphicon-fullscreen             { &:before { content: \"\\e140\"; } }\n.glyphicon-dashboard              { &:before { content: \"\\e141\"; } }\n.glyphicon-paperclip              { &:before { content: \"\\e142\"; } }\n.glyphicon-heart-empty            { &:before { content: \"\\e143\"; } }\n.glyphicon-link                   { &:before { content: \"\\e144\"; } }\n.glyphicon-phone                  { &:before { content: \"\\e145\"; } }\n.glyphicon-pushpin                { &:before { content: \"\\e146\"; } }\n.glyphicon-usd                    { &:before { content: \"\\e148\"; } }\n.glyphicon-gbp                    { &:before { content: \"\\e149\"; } }\n.glyphicon-sort                   { &:before { content: \"\\e150\"; } }\n.glyphicon-sort-by-alphabet       { &:before { content: \"\\e151\"; } }\n.glyphicon-sort-by-alphabet-alt   { &:before { content: \"\\e152\"; } }\n.glyphicon-sort-by-order          { &:before { content: \"\\e153\"; } }\n.glyphicon-sort-by-order-alt      { &:before { content: \"\\e154\"; } }\n.glyphicon-sort-by-attributes     { &:before { content: \"\\e155\"; } }\n.glyphicon-sort-by-attributes-alt { &:before { content: \"\\e156\"; } }\n.glyphicon-unchecked              { &:before { content: \"\\e157\"; } }\n.glyphicon-expand                 { &:before { content: \"\\e158\"; } }\n.glyphicon-collapse-down          { &:before { content: \"\\e159\"; } }\n.glyphicon-collapse-up            { &:before { content: \"\\e160\"; } }\n.glyphicon-log-in                 { &:before { content: \"\\e161\"; } }\n.glyphicon-flash                  { &:before { content: \"\\e162\"; } }\n.glyphicon-log-out                { &:before { content: \"\\e163\"; } }\n.glyphicon-new-window             { &:before { content: \"\\e164\"; } }\n.glyphicon-record                 { &:before { content: \"\\e165\"; } }\n.glyphicon-save                   { &:before { content: \"\\e166\"; } }\n.glyphicon-open                   { &:before { content: \"\\e167\"; } }\n.glyphicon-saved                  { &:before { content: \"\\e168\"; } }\n.glyphicon-import                 { &:before { content: \"\\e169\"; } }\n.glyphicon-export                 { &:before { content: \"\\e170\"; } }\n.glyphicon-send                   { &:before { content: \"\\e171\"; } }\n.glyphicon-floppy-disk            { &:before { content: \"\\e172\"; } }\n.glyphicon-floppy-saved           { &:before { content: \"\\e173\"; } }\n.glyphicon-floppy-remove          { &:before { content: \"\\e174\"; } }\n.glyphicon-floppy-save            { &:before { content: \"\\e175\"; } }\n.glyphicon-floppy-open            { &:before { content: \"\\e176\"; } }\n.glyphicon-credit-card            { &:before { content: \"\\e177\"; } }\n.glyphicon-transfer               { &:before { content: \"\\e178\"; } }\n.glyphicon-cutlery                { &:before { content: \"\\e179\"; } }\n.glyphicon-header                 { &:before { content: \"\\e180\"; } }\n.glyphicon-compressed             { &:before { content: \"\\e181\"; } }\n.glyphicon-earphone               { &:before { content: \"\\e182\"; } }\n.glyphicon-phone-alt              { &:before { content: \"\\e183\"; } }\n.glyphicon-tower                  { &:before { content: \"\\e184\"; } }\n.glyphicon-stats                  { &:before { content: \"\\e185\"; } }\n.glyphicon-sd-video               { &:before { content: \"\\e186\"; } }\n.glyphicon-hd-video               { &:before { content: \"\\e187\"; } }\n.glyphicon-subtitles              { &:before { content: \"\\e188\"; } }\n.glyphicon-sound-stereo           { &:before { content: \"\\e189\"; } }\n.glyphicon-sound-dolby            { &:before { content: \"\\e190\"; } }\n.glyphicon-sound-5-1              { &:before { content: \"\\e191\"; } }\n.glyphicon-sound-6-1              { &:before { content: \"\\e192\"; } }\n.glyphicon-sound-7-1              { &:before { content: \"\\e193\"; } }\n.glyphicon-copyright-mark         { &:before { content: \"\\e194\"; } }\n.glyphicon-registration-mark      { &:before { content: \"\\e195\"; } }\n.glyphicon-cloud-download         { &:before { content: \"\\e197\"; } }\n.glyphicon-cloud-upload           { &:before { content: \"\\e198\"; } }\n.glyphicon-tree-conifer           { &:before { content: \"\\e199\"; } }\n.glyphicon-tree-deciduous         { &:before { content: \"\\e200\"; } }\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/grid.less",
    "content": "//\n// Grid system\n// --------------------------------------------------\n\n// Set the container width, and override it for fixed navbars in media queries\n.container {\n  .container-fixed();\n\n  @media (min-width: @screen-sm) {\n    width: @container-sm;\n  }\n  @media (min-width: @screen-md) {\n    width: @container-md;\n  }\n  @media (min-width: @screen-lg-min) {\n    width: @container-lg;\n  }\n}\n\n// mobile first defaults\n.row {\n  .make-row();\n}\n\n// Common styles for small and large grid columns\n.make-grid-columns();\n\n\n// Extra small grid\n//\n// Columns, offsets, pushes, and pulls for extra small devices like\n// smartphones.\n\n.make-grid-columns-float(xs);\n.make-grid(@grid-columns, xs, width);\n.make-grid(@grid-columns, xs, pull);\n.make-grid(@grid-columns, xs, push);\n.make-grid(@grid-columns, xs, offset);\n\n\n// Small grid\n//\n// Columns, offsets, pushes, and pulls for the small device range, from phones\n// to tablets.\n\n@media (min-width: @screen-sm-min) {\n  .make-grid-columns-float(sm);\n  .make-grid(@grid-columns, sm, width);\n  .make-grid(@grid-columns, sm, pull);\n  .make-grid(@grid-columns, sm, push);\n  .make-grid(@grid-columns, sm, offset);\n}\n\n\n// Medium grid\n//\n// Columns, offsets, pushes, and pulls for the desktop device range.\n\n@media (min-width: @screen-md-min) {\n  .make-grid-columns-float(md);\n  .make-grid(@grid-columns, md, width);\n  .make-grid(@grid-columns, md, pull);\n  .make-grid(@grid-columns, md, push);\n  .make-grid(@grid-columns, md, offset);\n}\n\n\n// Large grid\n//\n// Columns, offsets, pushes, and pulls for the large desktop device range.\n\n@media (min-width: @screen-lg-min) {\n  .make-grid-columns-float(lg);\n  .make-grid(@grid-columns, lg, width);\n  .make-grid(@grid-columns, lg, pull);\n  .make-grid(@grid-columns, lg, push);\n  .make-grid(@grid-columns, lg, offset);\n}\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/input-groups.less",
    "content": "//\n// Input groups\n// --------------------------------------------------\n\n// Base styles\n// -------------------------\n.input-group {\n  position: relative; // For dropdowns\n  display: table;\n  border-collapse: separate; // prevent input groups from inheriting border styles from table cells when placed within a table\n\n  // Undo padding and float of grid classes\n  &[class*=\"col-\"] {\n    float: none;\n    padding-left: 0;\n    padding-right: 0;\n  }\n\n  .form-control {\n    width: 100%;\n    margin-bottom: 0;\n  }\n}\n\n// Sizing options\n//\n// Remix the default form control sizing classes into new ones for easier\n// manipulation.\n\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn { .input-lg(); }\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn { .input-sm(); }\n\n\n// Display as table-cell\n// -------------------------\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n  display: table-cell;\n\n  &:not(:first-child):not(:last-child) {\n    border-radius: 0;\n  }\n}\n// Addon and addon wrapper for buttons\n.input-group-addon,\n.input-group-btn {\n  width: 1%;\n  white-space: nowrap;\n  vertical-align: middle; // Match the inputs\n}\n\n// Text input groups\n// -------------------------\n.input-group-addon {\n  padding: @padding-base-vertical @padding-base-horizontal;\n  font-size: @font-size-base;\n  font-weight: normal;\n  line-height: 1;\n  color: @input-color;\n  text-align: center;\n  background-color: @input-group-addon-bg;\n  border: 1px solid @input-group-addon-border-color;\n  border-radius: @border-radius-base;\n\n  // Sizing\n  &.input-sm {\n    padding: @padding-small-vertical @padding-small-horizontal;\n    font-size: @font-size-small;\n    border-radius: @border-radius-small;\n  }\n  &.input-lg {\n    padding: @padding-large-vertical @padding-large-horizontal;\n    font-size: @font-size-large;\n    border-radius: @border-radius-large;\n  }\n\n  // Nuke default margins from checkboxes and radios to vertically center within.\n  input[type=\"radio\"],\n  input[type=\"checkbox\"] {\n    margin-top: 0;\n  }\n}\n\n// Reset rounded corners\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle) {\n  .border-right-radius(0);\n}\n.input-group-addon:first-child {\n  border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child) {\n  .border-left-radius(0);\n}\n.input-group-addon:last-child {\n  border-left: 0;\n}\n\n// Button input groups\n// -------------------------\n.input-group-btn {\n  position: relative;\n  white-space: nowrap;\n\n  // Negative margin to only have a 1px border between the two\n  &:first-child > .btn {\n    margin-right: -1px;\n  }\n  &:last-child > .btn {\n    margin-left: -1px;\n  }\n}\n.input-group-btn > .btn {\n  position: relative;\n  // Jankily prevent input button groups from wrapping\n  + .btn {\n    margin-left: -4px;\n  }\n  // Bring the \"active\" button to the front\n  &:hover,\n  &:active {\n    z-index: 2;\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/jumbotron.less",
    "content": "//\n// Jumbotron\n// --------------------------------------------------\n\n\n.jumbotron {\n  padding: @jumbotron-padding;\n  margin-bottom: @jumbotron-padding;\n  font-size: @jumbotron-font-size;\n  font-weight: 200;\n  line-height: (@line-height-base * 1.5);\n  color: @jumbotron-color;\n  background-color: @jumbotron-bg;\n\n  h1,\n  .h1 {\n    line-height: 1;\n    color: @jumbotron-heading-color;\n  }\n  p {\n    line-height: 1.4;\n  }\n\n  .container & {\n    border-radius: @border-radius-large; // Only round corners at higher resolutions if contained in a container\n  }\n\n  .container {\n    max-width: 100%;\n  }\n\n  @media screen and (min-width: @screen-sm-min) {\n    padding-top:    (@jumbotron-padding * 1.6);\n    padding-bottom: (@jumbotron-padding * 1.6);\n\n    .container & {\n      padding-left:  (@jumbotron-padding * 2);\n      padding-right: (@jumbotron-padding * 2);\n    }\n\n    h1,\n    .h1 {\n      font-size: (@font-size-base * 4.5);\n    }\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/labels.less",
    "content": "//\n// Labels\n// --------------------------------------------------\n\n.label {\n  display: inline;\n  padding: .2em .6em .3em;\n  font-size: 75%;\n  font-weight: bold;\n  line-height: 1;\n  color: @label-color;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: .25em;\n\n  // Add hover effects, but only for links\n  &[href] {\n    &:hover,\n    &:focus {\n      color: @label-link-hover-color;\n      text-decoration: none;\n      cursor: pointer;\n    }\n  }\n\n  // Empty labels collapse automatically (not available in IE8)\n  &:empty {\n    display: none;\n  }\n\n  // Quick fix for labels in buttons\n  .btn & {\n    position: relative;\n    top: -1px;\n  }\n}\n\n// Colors\n// Contextual variations (linked labels get darker on :hover)\n\n.label-default {\n  .label-variant(@label-default-bg);\n}\n\n.label-primary {\n  .label-variant(@label-primary-bg);\n}\n\n.label-success {\n  .label-variant(@label-success-bg);\n}\n\n.label-info {\n  .label-variant(@label-info-bg);\n}\n\n.label-warning {\n  .label-variant(@label-warning-bg);\n}\n\n.label-danger {\n  .label-variant(@label-danger-bg);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/list-group.less",
    "content": "//\n// List groups\n// --------------------------------------------------\n\n// Base class\n//\n// Easily usable on <ul>, <ol>, or <div>.\n.list-group {\n  // No need to set list-style: none; since .list-group-item is block level\n  margin-bottom: 20px;\n  padding-left: 0; // reset padding because ul and ol\n}\n\n// Individual list items\n// -------------------------\n\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n  // Place the border on the list items and negative margin up for better styling\n  margin-bottom: -1px;\n  background-color: @list-group-bg;\n  border: 1px solid @list-group-border;\n\n  // Round the first and last items\n  &:first-child {\n    .border-top-radius(@list-group-border-radius);\n  }\n  &:last-child {\n    margin-bottom: 0;\n    .border-bottom-radius(@list-group-border-radius);\n  }\n\n  // Align badges within list items\n  > .badge {\n    float: right;\n  }\n  > .badge + .badge {\n    margin-right: 5px;\n  }\n}\n\n// Linked list items\na.list-group-item {\n  color: @list-group-link-color;\n\n  .list-group-item-heading {\n    color: @list-group-link-heading-color;\n  }\n\n  // Hover state\n  &:hover,\n  &:focus {\n    text-decoration: none;\n    background-color: @list-group-hover-bg;\n  }\n\n  // Active class on item itself, not parent\n  &.active,\n  &.active:hover,\n  &.active:focus {\n    z-index: 2; // Place active items above their siblings for proper border styling\n    color: @list-group-active-color;\n    background-color: @list-group-active-bg;\n    border-color: @list-group-active-border;\n\n    // Force color to inherit for custom content\n    .list-group-item-heading {\n      color: inherit;\n    }\n    .list-group-item-text {\n      color: lighten(@list-group-active-bg, 40%);\n    }\n  }\n}\n\n// Custom content options\n// -------------------------\n\n.list-group-item-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.list-group-item-text {\n  margin-bottom: 0;\n  line-height: 1.3;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/media.less",
    "content": "// Media objects\n// Source: http://stubbornella.org/content/?p=497\n// --------------------------------------------------\n\n\n// Common styles\n// -------------------------\n\n// Clear the floats\n.media,\n.media-body {\n  overflow: hidden;\n  zoom: 1;\n}\n\n// Proper spacing between instances of .media\n.media,\n.media .media {\n  margin-top: 15px;\n}\n.media:first-child {\n  margin-top: 0;\n}\n\n// For images and videos, set to block\n.media-object {\n  display: block;\n}\n\n// Reset margins on headings for tighter default spacing\n.media-heading {\n  margin: 0 0 5px;\n}\n\n\n// Media image alignment\n// -------------------------\n\n.media {\n  > .pull-left {\n    margin-right: 10px;\n  }\n  > .pull-right {\n    margin-left: 10px;\n  }\n}\n\n\n// Media list variation\n// -------------------------\n\n// Undo default ul/ol styles\n.media-list {\n  padding-left: 0;\n  list-style: none;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/mixins.less",
    "content": "//\n// Mixins\n// --------------------------------------------------\n\n\n// Utilities\n// -------------------------\n\n// Clearfix\n// Source: http://nicolasgallagher.com/micro-clearfix-hack/\n//\n// For modern browsers\n// 1. The space content is one way to avoid an Opera bug when the\n//    contenteditable attribute is included anywhere else in the document.\n//    Otherwise it causes space to appear at the top and bottom of elements\n//    that are clearfixed.\n// 2. The use of `table` rather than `block` is only necessary if using\n//    `:before` to contain the top-margins of child elements.\n.clearfix() {\n  &:before,\n  &:after {\n    content: \" \"; // 1\n    display: table; // 2\n  }\n  &:after {\n    clear: both;\n  }\n}\n\n// WebKit-style focus\n.tab-focus() {\n  // Default\n  outline: thin dotted;\n  // WebKit\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n\n// Center-align a block level element\n.center-block() {\n  display: block;\n  margin-left: auto;\n  margin-right: auto;\n}\n\n// Sizing shortcuts\n.size(@width; @height) {\n  width: @width;\n  height: @height;\n}\n.square(@size) {\n  .size(@size; @size);\n}\n\n// Placeholder text\n.placeholder(@color: @input-color-placeholder) {\n  &:-moz-placeholder            { color: @color; } // Firefox 4-18\n  &::-moz-placeholder           { color: @color;   // Firefox 19+\n                                  opacity: 1; } // See https://github.com/twbs/bootstrap/pull/11526\n  &:-ms-input-placeholder       { color: @color; } // Internet Explorer 10+\n  &::-webkit-input-placeholder  { color: @color; } // Safari and Chrome\n}\n\n// Text overflow\n// Requires inline-block or block for proper styling\n.text-overflow() {\n  overflow: hidden;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n// CSS image replacement\n//\n// Heads up! v3 launched with with only `.hide-text()`, but per our pattern for\n// mixins being reused as classes with the same name, this doesn't hold up. As\n// of v3.0.1 we have added `.text-hide()` and deprecated `.hide-text()`. Note\n// that we cannot chain the mixins together in Less, so they are repeated.\n//\n// Source: https://github.com/h5bp/html5-boilerplate/commit/aa0396eae757\n\n// Deprecated as of v3.0.1 (will be removed in v4)\n.hide-text() {\n  font: ~\"0/0\" a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n// New mixin to use as of v3.0.1\n.text-hide() {\n  .hide-text();\n}\n\n\n\n// CSS3 PROPERTIES\n// --------------------------------------------------\n\n// Single side border-radius\n.border-top-radius(@radius) {\n  border-top-right-radius: @radius;\n   border-top-left-radius: @radius;\n}\n.border-right-radius(@radius) {\n  border-bottom-right-radius: @radius;\n     border-top-right-radius: @radius;\n}\n.border-bottom-radius(@radius) {\n  border-bottom-right-radius: @radius;\n   border-bottom-left-radius: @radius;\n}\n.border-left-radius(@radius) {\n  border-bottom-left-radius: @radius;\n     border-top-left-radius: @radius;\n}\n\n// Drop shadows\n.box-shadow(@shadow) {\n  -webkit-box-shadow: @shadow; // iOS <4.3 & Android <4.1\n          box-shadow: @shadow;\n}\n\n// Transitions\n.transition(@transition) {\n  -webkit-transition: @transition;\n          transition: @transition;\n}\n.transition-property(@transition-property) {\n  -webkit-transition-property: @transition-property;\n          transition-property: @transition-property;\n}\n.transition-delay(@transition-delay) {\n  -webkit-transition-delay: @transition-delay;\n          transition-delay: @transition-delay;\n}\n.transition-duration(@transition-duration) {\n  -webkit-transition-duration: @transition-duration;\n          transition-duration: @transition-duration;\n}\n.transition-transform(@transition) {\n  -webkit-transition: -webkit-transform @transition;\n     -moz-transition: -moz-transform @transition;\n       -o-transition: -o-transform @transition;\n          transition: transform @transition;\n}\n\n// Transformations\n.rotate(@degrees) {\n  -webkit-transform: rotate(@degrees);\n      -ms-transform: rotate(@degrees); // IE9+\n          transform: rotate(@degrees);\n}\n.scale(@ratio) {\n  -webkit-transform: scale(@ratio);\n      -ms-transform: scale(@ratio); // IE9+\n          transform: scale(@ratio);\n}\n.translate(@x; @y) {\n  -webkit-transform: translate(@x, @y);\n      -ms-transform: translate(@x, @y); // IE9+\n          transform: translate(@x, @y);\n}\n.skew(@x; @y) {\n  -webkit-transform: skew(@x, @y);\n      -ms-transform: skewX(@x) skewY(@y); // See https://github.com/twbs/bootstrap/issues/4885; IE9+\n          transform: skew(@x, @y);\n}\n.translate3d(@x; @y; @z) {\n  -webkit-transform: translate3d(@x, @y, @z);\n          transform: translate3d(@x, @y, @z);\n}\n\n.rotateX(@degrees) {\n  -webkit-transform: rotateX(@degrees);\n      -ms-transform: rotateX(@degrees); // IE9+\n          transform: rotateX(@degrees);\n}\n.rotateY(@degrees) {\n  -webkit-transform: rotateY(@degrees);\n      -ms-transform: rotateY(@degrees); // IE9+\n          transform: rotateY(@degrees);\n}\n.perspective(@perspective) {\n  -webkit-perspective: @perspective;\n     -moz-perspective: @perspective;\n          perspective: @perspective;\n}\n.perspective-origin(@perspective) {\n  -webkit-perspective-origin: @perspective;\n     -moz-perspective-origin: @perspective;\n          perspective-origin: @perspective;\n}\n.transform-origin(@origin) {\n  -webkit-transform-origin: @origin;\n     -moz-transform-origin: @origin;\n          transform-origin: @origin;\n}\n\n// Animations\n.animation(@animation) {\n  -webkit-animation: @animation;\n          animation: @animation;\n}\n\n// Backface visibility\n// Prevent browsers from flickering when using CSS 3D transforms.\n// Default value is `visible`, but can be changed to `hidden`\n.backface-visibility(@visibility){\n  -webkit-backface-visibility: @visibility;\n     -moz-backface-visibility: @visibility;\n          backface-visibility: @visibility;\n}\n\n// Box sizing\n.box-sizing(@boxmodel) {\n  -webkit-box-sizing: @boxmodel;\n     -moz-box-sizing: @boxmodel;\n          box-sizing: @boxmodel;\n}\n\n// User select\n// For selecting text on the page\n.user-select(@select) {\n  -webkit-user-select: @select;\n     -moz-user-select: @select;\n      -ms-user-select: @select; // IE10+\n       -o-user-select: @select;\n          user-select: @select;\n}\n\n// Resize anything\n.resizable(@direction) {\n  resize: @direction; // Options: horizontal, vertical, both\n  overflow: auto; // Safari fix\n}\n\n// CSS3 Content Columns\n.content-columns(@column-count; @column-gap: @grid-gutter-width) {\n  -webkit-column-count: @column-count;\n     -moz-column-count: @column-count;\n          column-count: @column-count;\n  -webkit-column-gap: @column-gap;\n     -moz-column-gap: @column-gap;\n          column-gap: @column-gap;\n}\n\n// Optional hyphenation\n.hyphens(@mode: auto) {\n  word-wrap: break-word;\n  -webkit-hyphens: @mode;\n     -moz-hyphens: @mode;\n      -ms-hyphens: @mode; // IE10+\n       -o-hyphens: @mode;\n          hyphens: @mode;\n}\n\n// Opacity\n.opacity(@opacity) {\n  opacity: @opacity;\n  // IE8 filter\n  @opacity-ie: (@opacity * 100);\n  filter: ~\"alpha(opacity=@{opacity-ie})\";\n}\n\n\n\n// GRADIENTS\n// --------------------------------------------------\n\n#gradient {\n\n  // Horizontal gradient, from left to right\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .horizontal(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(left, color-stop(@start-color @start-percent), color-stop(@end-color @end-percent)); // Safari 5.1-6, Chrome 10+\n    background-image:  linear-gradient(to right, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  // Vertical gradient, from top to bottom\n  //\n  // Creates two color stops, start and end, by specifying a color and position for each color stop.\n  // Color stops are not available in IE9 and below.\n  .vertical(@start-color: #555; @end-color: #333; @start-percent: 0%; @end-percent: 100%) {\n    background-image: -webkit-linear-gradient(top, @start-color @start-percent, @end-color @end-percent);  // Safari 5.1-6, Chrome 10+\n    background-image: linear-gradient(to bottom, @start-color @start-percent, @end-color @end-percent); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n    background-repeat: repeat-x;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down\n  }\n\n  .directional(@start-color: #555; @end-color: #333; @deg: 45deg) {\n    background-repeat: repeat-x;\n    background-image: -webkit-linear-gradient(@deg, @start-color, @end-color); // Safari 5.1-6, Chrome 10+\n    background-image: linear-gradient(@deg, @start-color, @end-color); // Standard, IE10, Firefox 16+, Opera 12.10+, Safari 7+, Chrome 26+\n  }\n  .horizontal-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(left, @start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(to right, @start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=1)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .vertical-three-colors(@start-color: #00b3ee; @mid-color: #7a43b6; @color-stop: 50%; @end-color: #c3325f) {\n    background-image: -webkit-linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-image: linear-gradient(@start-color, @mid-color @color-stop, @end-color);\n    background-repeat: no-repeat;\n    filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(startColorstr='%d', endColorstr='%d', GradientType=0)\",argb(@start-color),argb(@end-color))); // IE9 and down, gets no color-stop at all for proper fallback\n  }\n  .radial(@inner-color: #555; @outer-color: #333) {\n    background-image: -webkit-radial-gradient(circle, @inner-color, @outer-color);\n    background-image: radial-gradient(circle, @inner-color, @outer-color);\n    background-repeat: no-repeat;\n  }\n  .striped(@color: rgba(255,255,255,.15); @angle: 45deg) {\n    background-image: -webkit-linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n    background-image: linear-gradient(@angle, @color 25%, transparent 25%, transparent 50%, @color 50%, @color 75%, transparent 75%, transparent);\n  }\n}\n\n// Reset filters for IE\n//\n// When you need to remove a gradient background, do not forget to use this to reset\n// the IE filter for IE9 and below.\n.reset-filter() {\n  filter: e(%(\"progid:DXImageTransform.Microsoft.gradient(enabled = false)\"));\n}\n\n\n\n// Retina images\n//\n// Short retina mixin for setting background-image and -size\n\n.img-retina(@file-1x; @file-2x; @width-1x; @height-1x) {\n  background-image: url(\"@{file-1x}\");\n\n  @media\n  only screen and (-webkit-min-device-pixel-ratio: 2),\n  only screen and (   min--moz-device-pixel-ratio: 2),\n  only screen and (     -o-min-device-pixel-ratio: 2/1),\n  only screen and (        min-device-pixel-ratio: 2),\n  only screen and (                min-resolution: 192dpi),\n  only screen and (                min-resolution: 2dppx) {\n    background-image: url(\"@{file-2x}\");\n    background-size: @width-1x @height-1x;\n  }\n}\n\n\n// Responsive image\n//\n// Keep images from scaling beyond the width of their parents.\n\n.img-responsive(@display: block;) {\n  display: @display;\n  max-width: 100%; // Part 1: Set a maximum relative to the parent\n  height: auto; // Part 2: Scale the height according to the width, otherwise you get stretching\n}\n\n\n// COMPONENT MIXINS\n// --------------------------------------------------\n\n// Horizontal dividers\n// -------------------------\n// Dividers (basically an hr) within dropdowns and nav lists\n.nav-divider(@color: #e5e5e5) {\n  height: 1px;\n  margin: ((@line-height-computed / 2) - 1) 0;\n  overflow: hidden;\n  background-color: @color;\n}\n\n// Panels\n// -------------------------\n.panel-variant(@border; @heading-text-color; @heading-bg-color; @heading-border) {\n  border-color: @border;\n\n  & > .panel-heading {\n    color: @heading-text-color;\n    background-color: @heading-bg-color;\n    border-color: @heading-border;\n\n    + .panel-collapse .panel-body {\n      border-top-color: @border;\n    }\n  }\n  & > .panel-footer {\n    + .panel-collapse .panel-body {\n      border-bottom-color: @border;\n    }\n  }\n}\n\n// Alerts\n// -------------------------\n.alert-variant(@background; @border; @text-color) {\n  background-color: @background;\n  border-color: @border;\n  color: @text-color;\n\n  hr {\n    border-top-color: darken(@border, 5%);\n  }\n  .alert-link {\n    color: darken(@text-color, 10%);\n  }\n}\n\n// Tables\n// -------------------------\n.table-row-variant(@state; @background) {\n  // Exact selectors below required to override `.table-striped` and prevent\n  // inheritance to nested tables.\n  .table {\n    > thead,\n    > tbody,\n    > tfoot {\n      > tr > .@{state},\n      > .@{state} > td,\n      > .@{state} > th {\n        background-color: @background;\n      }\n    }\n  }\n\n  // Hover states for `.table-hover`\n  // Note: this is not available for cells or rows within `thead` or `tfoot`.\n  .table-hover > tbody {\n    > tr > .@{state}:hover,\n    > .@{state}:hover > td,\n    > .@{state}:hover > th {\n      background-color: darken(@background, 5%);\n    }\n  }\n}\n\n// Button variants\n// -------------------------\n// Easily pump out default styles, as well as :hover, :focus, :active,\n// and disabled options for all buttons\n.button-variant(@color; @background; @border) {\n  color: @color;\n  background-color: @background;\n  border-color: @border;\n\n  &:hover,\n  &:focus,\n  &:active,\n  &.active,\n  .open .dropdown-toggle& {\n    color: @color;\n    background-color: darken(@background, 8%);\n        border-color: darken(@border, 12%);\n  }\n  &:active,\n  &.active,\n  .open .dropdown-toggle& {\n    background-image: none;\n  }\n  &.disabled,\n  &[disabled],\n  fieldset[disabled] & {\n    &,\n    &:hover,\n    &:focus,\n    &:active,\n    &.active {\n      background-color: @background;\n          border-color: @border;\n    }\n  }\n\n  .badge {\n    color: @background;\n    background-color: #fff;\n  }\n}\n\n// Button sizes\n// -------------------------\n.button-size(@padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n  padding: @padding-vertical @padding-horizontal;\n  font-size: @font-size;\n  line-height: @line-height;\n  border-radius: @border-radius;\n}\n\n// Pagination\n// -------------------------\n.pagination-size(@padding-vertical; @padding-horizontal; @font-size; @border-radius) {\n  > li {\n    > a,\n    > span {\n      padding: @padding-vertical @padding-horizontal;\n      font-size: @font-size;\n    }\n    &:first-child {\n      > a,\n      > span {\n        .border-left-radius(@border-radius);\n      }\n    }\n    &:last-child {\n      > a,\n      > span {\n        .border-right-radius(@border-radius);\n      }\n    }\n  }\n}\n\n// Labels\n// -------------------------\n.label-variant(@color) {\n  background-color: @color;\n  &[href] {\n    &:hover,\n    &:focus {\n      background-color: darken(@color, 10%);\n    }\n  }\n}\n\n// Navbar vertical align\n// -------------------------\n// Vertically center elements in the navbar.\n// Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.\n.navbar-vertical-align(@element-height) {\n  margin-top: ((@navbar-height - @element-height) / 2);\n  margin-bottom: ((@navbar-height - @element-height) / 2);\n}\n\n// Progress bars\n// -------------------------\n.progress-bar-variant(@color) {\n  background-color: @color;\n  .progress-striped & {\n    #gradient > .striped();\n  }\n}\n\n// Responsive utilities\n// -------------------------\n// More easily include all the states for responsive-utilities.less.\n.responsive-visibility() {\n  display: block !important;\n  table&  { display: table; }\n  tr&     { display: table-row !important; }\n  th&,\n  td&     { display: table-cell !important; }\n}\n\n.responsive-invisibility() {\n    &,\n  tr&,\n  th&,\n  td& { display: none !important; }\n}\n\n\n// Grid System\n// -----------\n\n// Centered container element\n.container-fixed() {\n  margin-right: auto;\n  margin-left: auto;\n  padding-left:  (@grid-gutter-width / 2);\n  padding-right: (@grid-gutter-width / 2);\n  .clearfix();\n}\n\n// Creates a wrapper for a series of columns\n.make-row(@gutter: @grid-gutter-width) {\n  margin-left:  (@gutter / -2);\n  margin-right: (@gutter / -2);\n  .clearfix();\n}\n\n// Generate the extra small columns\n.make-xs-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  float: left;\n  width: percentage((@columns / @grid-columns));\n  // Prevent columns from collapsing when empty\n  min-height: 1px;\n  // Inner gutter via padding\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n}\n\n// Generate the small columns\n.make-sm-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  // Prevent columns from collapsing when empty\n  min-height: 1px;\n  // Inner gutter via padding\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n\n  // Calculate width based on number of columns available\n  @media (min-width: @screen-sm-min) {\n    float: left;\n    width: percentage((@columns / @grid-columns));\n  }\n}\n\n// Generate the small column offsets\n.make-sm-column-offset(@columns) {\n  @media (min-width: @screen-sm-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-sm-column-push(@columns) {\n  @media (min-width: @screen-sm-min) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-sm-column-pull(@columns) {\n  @media (min-width: @screen-sm-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n\n// Generate the medium columns\n.make-md-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  // Prevent columns from collapsing when empty\n  min-height: 1px;\n  // Inner gutter via padding\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n\n  // Calculate width based on number of columns available\n  @media (min-width: @screen-md-min) {\n    float: left;\n    width: percentage((@columns / @grid-columns));\n  }\n}\n\n// Generate the medium column offsets\n.make-md-column-offset(@columns) {\n  @media (min-width: @screen-md-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-md-column-push(@columns) {\n  @media (min-width: @screen-md) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-md-column-pull(@columns) {\n  @media (min-width: @screen-md-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n\n// Generate the large columns\n.make-lg-column(@columns; @gutter: @grid-gutter-width) {\n  position: relative;\n  // Prevent columns from collapsing when empty\n  min-height: 1px;\n  // Inner gutter via padding\n  padding-left:  (@gutter / 2);\n  padding-right: (@gutter / 2);\n\n  // Calculate width based on number of columns available\n  @media (min-width: @screen-lg-min) {\n    float: left;\n    width: percentage((@columns / @grid-columns));\n  }\n}\n\n// Generate the large column offsets\n.make-lg-column-offset(@columns) {\n  @media (min-width: @screen-lg-min) {\n    margin-left: percentage((@columns / @grid-columns));\n  }\n}\n.make-lg-column-push(@columns) {\n  @media (min-width: @screen-lg-min) {\n    left: percentage((@columns / @grid-columns));\n  }\n}\n.make-lg-column-pull(@columns) {\n  @media (min-width: @screen-lg-min) {\n    right: percentage((@columns / @grid-columns));\n  }\n}\n\n\n// Framework grid generation\n//\n// Used only by Bootstrap to generate the correct number of grid classes given\n// any value of `@grid-columns`.\n\n.make-grid-columns() {\n  // Common styles for all sizes of grid columns, widths 1-12\n  .col(@index) when (@index = 1) { // initial\n    @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n    .col(@index + 1, @item);\n  }\n  .col(@index, @list) when (@index =< @grid-columns) { // general; \"=<\" isn't a typo\n    @item: ~\".col-xs-@{index}, .col-sm-@{index}, .col-md-@{index}, .col-lg-@{index}\";\n    .col(@index + 1, ~\"@{list}, @{item}\");\n  }\n  .col(@index, @list) when (@index > @grid-columns) { // terminal\n    @{list} {\n      position: relative;\n      // Prevent columns from collapsing when empty\n      min-height: 1px;\n      // Inner gutter via padding\n      padding-left:  (@grid-gutter-width / 2);\n      padding-right: (@grid-gutter-width / 2);\n    }\n  }\n  .col(1); // kickstart it\n}\n\n.make-grid-columns-float(@class) {\n  .col(@index) when (@index = 1) { // initial\n    @item: ~\".col-@{class}-@{index}\";\n    .col(@index + 1, @item);\n  }\n  .col(@index, @list) when (@index =< @grid-columns) { // general\n    @item: ~\".col-@{class}-@{index}\";\n    .col(@index + 1, ~\"@{list}, @{item}\");\n  }\n  .col(@index, @list) when (@index > @grid-columns) { // terminal\n    @{list} {\n      float: left;\n    }\n  }\n  .col(1); // kickstart it\n}\n\n.calc-grid(@index, @class, @type) when (@type = width) and (@index > 0) {\n  .col-@{class}-@{index} {\n    width: percentage((@index / @grid-columns));\n  }\n}\n.calc-grid(@index, @class, @type) when (@type = push) {\n  .col-@{class}-push-@{index} {\n    left: percentage((@index / @grid-columns));\n  }\n}\n.calc-grid(@index, @class, @type) when (@type = pull) {\n  .col-@{class}-pull-@{index} {\n    right: percentage((@index / @grid-columns));\n  }\n}\n.calc-grid(@index, @class, @type) when (@type = offset) {\n  .col-@{class}-offset-@{index} {\n    margin-left: percentage((@index / @grid-columns));\n  }\n}\n\n// Basic looping in LESS\n.make-grid(@index, @class, @type) when (@index >= 0) {\n  .calc-grid(@index, @class, @type);\n  // next iteration\n  .make-grid(@index - 1, @class, @type);\n}\n\n\n// Form validation states\n//\n// Used in forms.less to generate the form validation CSS for warnings, errors,\n// and successes.\n\n.form-control-validation(@text-color: #555; @border-color: #ccc; @background-color: #f5f5f5) {\n  // Color the label and help text\n  .help-block,\n  .control-label,\n  .radio,\n  .checkbox,\n  .radio-inline,\n  .checkbox-inline  {\n    color: @text-color;\n  }\n  // Set the border and box shadow on specific inputs to match\n  .form-control {\n    border-color: @border-color;\n    .box-shadow(inset 0 1px 1px rgba(0,0,0,.075)); // Redeclare so transitions work\n    &:focus {\n      border-color: darken(@border-color, 10%);\n      @shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 6px lighten(@border-color, 20%);\n      .box-shadow(@shadow);\n    }\n  }\n  // Set validation states also for addons\n  .input-group-addon {\n    color: @text-color;\n    border-color: @border-color;\n    background-color: @background-color;\n  }\n}\n\n// Form control focus state\n//\n// Generate a customized focus state and for any input with the specified color,\n// which defaults to the `@input-focus-border` variable.\n//\n// We highly encourage you to not customize the default value, but instead use\n// this to tweak colors on an as-needed basis. This aesthetic change is based on\n// WebKit's default styles, but applicable to a wider range of browsers. Its\n// usability and accessibility should be taken into account with any change.\n//\n// Example usage: change the default blue border and shadow to white for better\n// contrast against a dark gray background.\n\n.form-control-focus(@color: @input-border-focus) {\n  @color-rgba: rgba(red(@color), green(@color), blue(@color), .6);\n  &:focus {\n    border-color: @color;\n    outline: 0;\n    .box-shadow(~\"inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px @{color-rgba}\");\n  }\n}\n\n// Form control sizing\n//\n// Relative text size, padding, and border-radii changes for form controls. For\n// horizontal sizing, wrap controls in the predefined grid classes. `<select>`\n// element gets special love because it's special, and that's a fact!\n\n.input-size(@input-height; @padding-vertical; @padding-horizontal; @font-size; @line-height; @border-radius) {\n  height: @input-height;\n  padding: @padding-vertical @padding-horizontal;\n  font-size: @font-size;\n  line-height: @line-height;\n  border-radius: @border-radius;\n\n  select& {\n    height: @input-height;\n    line-height: @input-height;\n  }\n\n  textarea& {\n    height: auto;\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/modals.less",
    "content": "//\n// Modals\n// --------------------------------------------------\n\n// .modal-open      - body class for killing the scroll\n// .modal           - container to scroll within\n// .modal-dialog    - positioning shell for the actual modal\n// .modal-content   - actual modal w/ bg and corners and shit\n\n// Kill the scroll on the body\n.modal-open {\n  overflow: hidden;\n}\n\n// Container that the modal scrolls within\n.modal {\n  display: none;\n  overflow: auto;\n  overflow-y: scroll;\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: @zindex-modal-background;\n\n  // When fading in the modal, animate it to slide down\n  &.fade .modal-dialog {\n    .translate(0, -25%);\n    .transition-transform(~\"0.3s ease-out\");\n  }\n  &.in .modal-dialog { .translate(0, 0)}\n}\n\n// Shell div to position the modal with bottom padding\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: 10px;\n  z-index: (@zindex-modal-background + 10);\n}\n\n// Actual modal\n.modal-content {\n  position: relative;\n  background-color: @modal-content-bg;\n  border: 1px solid @modal-content-fallback-border-color; //old browsers fallback (ie8 etc)\n  border: 1px solid @modal-content-border-color;\n  border-radius: @border-radius-large;\n  .box-shadow(0 3px 9px rgba(0,0,0,.5));\n  background-clip: padding-box;\n  // Remove focus outline from opened modal\n  outline: none;\n}\n\n// Modal background\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: (@zindex-modal-background - 10);\n  background-color: @modal-backdrop-bg;\n  // Fade for backdrop\n  &.fade { .opacity(0); }\n  &.in { .opacity(.5); }\n}\n\n// Modal header\n// Top section of the modal w/ title and dismiss\n.modal-header {\n  padding: @modal-title-padding;\n  border-bottom: 1px solid @modal-header-border-color;\n  min-height: (@modal-title-padding + @modal-title-line-height);\n}\n// Close icon\n.modal-header .close {\n  margin-top: -2px;\n}\n\n// Title text within header\n.modal-title {\n  margin: 0;\n  line-height: @modal-title-line-height;\n}\n\n// Modal body\n// Where all modal content resides (sibling of .modal-header and .modal-footer)\n.modal-body {\n  position: relative;\n  padding: @modal-inner-padding;\n}\n\n// Footer (for actions)\n.modal-footer {\n  margin-top: 15px;\n  padding: (@modal-inner-padding - 1) @modal-inner-padding @modal-inner-padding;\n  text-align: right; // right align buttons\n  border-top: 1px solid @modal-footer-border-color;\n  .clearfix(); // clear it in case folks use .pull-* classes on buttons\n\n  // Properly space out buttons\n  .btn + .btn {\n    margin-left: 5px;\n    margin-bottom: 0; // account for input[type=\"submit\"] which gets the bottom margin like all other inputs\n  }\n  // but override that for button groups\n  .btn-group .btn + .btn {\n    margin-left: -1px;\n  }\n  // and override it for block buttons as well\n  .btn-block + .btn-block {\n    margin-left: 0;\n  }\n}\n\n// Scale up the modal\n@media screen and (min-width: @screen-sm-min) {\n\n  .modal-dialog {\n    width: 600px;\n    margin: 30px auto;\n  }\n  .modal-content {\n    .box-shadow(0 5px 15px rgba(0,0,0,.5));\n  }\n\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/navbar.less",
    "content": "//\n// Navbars\n// --------------------------------------------------\n\n\n// Wrapper and base class\n//\n// Provide a static navbar from which we expand to create full-width, fixed, and\n// other navbar variations.\n\n.navbar {\n  position: relative;\n  min-height: @navbar-height; // Ensure a navbar always shows (e.g., without a .navbar-brand in collapsed mode)\n  margin-bottom: @navbar-margin-bottom;\n  border: 1px solid transparent;\n\n  // Prevent floats from breaking the navbar\n  .clearfix();\n\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: @navbar-border-radius;\n  }\n}\n\n\n// Navbar heading\n//\n// Groups `.navbar-brand` and `.navbar-toggle` into a single component for easy\n// styling of responsive aspects.\n\n.navbar-header {\n  .clearfix();\n\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n  }\n}\n\n\n// Navbar collapse (body)\n//\n// Group your navbar content into this for easy collapsing and expanding across\n// various device sizes. By default, this content is collapsed when <768px, but\n// will expand past that for a horizontal display.\n//\n// To start (on mobile devices) the navbar links, forms, and buttons are stacked\n// vertically and include a `max-height` to overflow in case you have too much\n// content for the user's viewport.\n\n.navbar-collapse {\n  max-height: 340px;\n  overflow-x: visible;\n  padding-right: @navbar-padding-horizontal;\n  padding-left:  @navbar-padding-horizontal;\n  border-top: 1px solid transparent;\n  box-shadow: inset 0 1px 0 rgba(255,255,255,.1);\n  .clearfix();\n  -webkit-overflow-scrolling: touch;\n\n  &.in {\n    overflow-y: auto;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    width: auto;\n    border-top: 0;\n    box-shadow: none;\n\n    &.collapse {\n      display: block !important;\n      height: auto !important;\n      padding-bottom: 0; // Override default setting\n      overflow: visible !important;\n    }\n\n    &.in {\n      overflow-y: visible;\n    }\n\n    // Undo the collapse side padding for navbars with containers to ensure\n    // alignment of right-aligned contents.\n    .navbar-fixed-top &,\n    .navbar-static-top &,\n    .navbar-fixed-bottom & {\n      padding-left: 0;\n      padding-right: 0;\n    }\n  }\n}\n\n\n// Both navbar header and collapse\n//\n// When a container is present, change the behavior of the header and collapse.\n\n.container > .navbar-header,\n.container > .navbar-collapse {\n  margin-right: -@navbar-padding-horizontal;\n  margin-left:  -@navbar-padding-horizontal;\n\n  @media (min-width: @grid-float-breakpoint) {\n    margin-right: 0;\n    margin-left:  0;\n  }\n}\n\n\n//\n// Navbar alignment options\n//\n// Display the navbar across the entirety of the page or fixed it to the top or\n// bottom of the page.\n\n// Static top (unfixed, but 100% wide) navbar\n.navbar-static-top {\n  z-index: @zindex-navbar;\n  border-width: 0 0 1px;\n\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: 0;\n  }\n}\n\n// Fix the top/bottom navbars when screen real estate supports it\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: @zindex-navbar-fixed;\n\n  // Undo the rounded corners\n  @media (min-width: @grid-float-breakpoint) {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top {\n  top: 0;\n  border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n  bottom: 0;\n  margin-bottom: 0; // override .navbar defaults\n  border-width: 1px 0 0;\n}\n\n\n// Brand/project name\n\n.navbar-brand {\n  float: left;\n  padding: @navbar-padding-vertical @navbar-padding-horizontal;\n  font-size: @font-size-large;\n  line-height: @line-height-computed;\n\n  &:hover,\n  &:focus {\n    text-decoration: none;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    .navbar > .container & {\n      margin-left: -@navbar-padding-horizontal;\n    }\n  }\n}\n\n\n// Navbar toggle\n//\n// Custom button for toggling the `.navbar-collapse`, powered by the collapse\n// JavaScript plugin.\n\n.navbar-toggle {\n  position: relative;\n  float: right;\n  margin-right: @navbar-padding-horizontal;\n  padding: 9px 10px;\n  .navbar-vertical-align(34px);\n  background-color: transparent;\n  background-image: none; // Reset unusual Firefox-on-Android default style; see https://github.com/necolas/normalize.css/issues/214\n  border: 1px solid transparent;\n  border-radius: @border-radius-base;\n\n  // Bars\n  .icon-bar {\n    display: block;\n    width: 22px;\n    height: 2px;\n    border-radius: 1px;\n  }\n  .icon-bar + .icon-bar {\n    margin-top: 4px;\n  }\n\n  @media (min-width: @grid-float-breakpoint) {\n    display: none;\n  }\n}\n\n\n// Navbar nav links\n//\n// Builds on top of the `.nav` components with it's own modifier class to make\n// the nav the full height of the horizontal nav (above 768px).\n\n.navbar-nav {\n  margin: (@navbar-padding-vertical / 2) -@navbar-padding-horizontal;\n\n  > li > a {\n    padding-top:    10px;\n    padding-bottom: 10px;\n    line-height: @line-height-computed;\n  }\n\n  @media (max-width: @grid-float-breakpoint-max) {\n    // Dropdowns get custom display when collapsed\n    .open .dropdown-menu {\n      position: static;\n      float: none;\n      width: auto;\n      margin-top: 0;\n      background-color: transparent;\n      border: 0;\n      box-shadow: none;\n      > li > a,\n      .dropdown-header {\n        padding: 5px 15px 5px 25px;\n      }\n      > li > a {\n        line-height: @line-height-computed;\n        &:hover,\n        &:focus {\n          background-image: none;\n        }\n      }\n    }\n  }\n\n  // Uncollapse the nav\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n    margin: 0;\n\n    > li {\n      float: left;\n      > a {\n        padding-top:    @navbar-padding-vertical;\n        padding-bottom: @navbar-padding-vertical;\n      }\n    }\n\n    &.navbar-right:last-child {\n      margin-right: -@navbar-padding-horizontal;\n    }\n  }\n}\n\n\n// Component alignment\n//\n// Repurpose the pull utilities as their own navbar utilities to avoid specificity\n// issues with parents and chaining. Only do this when the navbar is uncollapsed\n// though so that navbar contents properly stack and align in mobile.\n\n@media (min-width: @grid-float-breakpoint) {\n  .navbar-left  { .pull-left(); }\n  .navbar-right { .pull-right(); }\n}\n\n\n// Navbar form\n//\n// Extension of the `.form-inline` with some extra flavor for optimum display in\n// our navbars.\n\n.navbar-form {\n  margin-left: -@navbar-padding-horizontal;\n  margin-right: -@navbar-padding-horizontal;\n  padding: 10px @navbar-padding-horizontal;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid transparent;\n  @shadow: inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);\n  .box-shadow(@shadow);\n\n  // Mixin behavior for optimum display\n  .form-inline();\n\n  .form-group {\n    @media (max-width: @grid-float-breakpoint-max) {\n      margin-bottom: 5px;\n    }\n  }\n\n  // Vertically center in expanded, horizontal navbar\n  .navbar-vertical-align(@input-height-base);\n\n  // Undo 100% width for pull classes\n  @media (min-width: @grid-float-breakpoint) {\n    width: auto;\n    border: 0;\n    margin-left: 0;\n    margin-right: 0;\n    padding-top: 0;\n    padding-bottom: 0;\n    .box-shadow(none);\n\n    // Outdent the form if last child to line up with content down the page\n    &.navbar-right:last-child {\n      margin-right: -@navbar-padding-horizontal;\n    }\n  }\n}\n\n\n// Dropdown menus\n\n// Menu position and menu carets\n.navbar-nav > li > .dropdown-menu {\n  margin-top: 0;\n  .border-top-radius(0);\n}\n// Menu position and menu caret support for dropups via extra dropup class\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n  .border-bottom-radius(0);\n}\n\n// Right aligned menus need alt position\n.navbar-nav.pull-right > li > .dropdown-menu,\n.navbar-nav > li > .dropdown-menu.pull-right {\n  left: auto;\n  right: 0;\n}\n\n\n// Buttons in navbars\n//\n// Vertically center a button within a navbar (when *not* in a form).\n\n.navbar-btn {\n  .navbar-vertical-align(@input-height-base);\n\n  &.btn-sm {\n    .navbar-vertical-align(@input-height-small);\n  }\n  &.btn-xs {\n    .navbar-vertical-align(22);\n  }\n}\n\n\n// Text in navbars\n//\n// Add a class to make any element properly align itself vertically within the navbars.\n\n.navbar-text {\n  .navbar-vertical-align(@line-height-computed);\n\n  @media (min-width: @grid-float-breakpoint) {\n    float: left;\n    margin-left: @navbar-padding-horizontal;\n    margin-right: @navbar-padding-horizontal;\n\n    // Outdent the form if last child to line up with content down the page\n    &.navbar-right:last-child {\n      margin-right: 0;\n    }\n  }\n}\n\n// Alternate navbars\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n  background-color: @navbar-default-bg;\n  border-color: @navbar-default-border;\n\n  .navbar-brand {\n    color: @navbar-default-brand-color;\n    &:hover,\n    &:focus {\n      color: @navbar-default-brand-hover-color;\n      background-color: @navbar-default-brand-hover-bg;\n    }\n  }\n\n  .navbar-text {\n    color: @navbar-default-color;\n  }\n\n  .navbar-nav {\n    > li > a {\n      color: @navbar-default-link-color;\n\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-hover-color;\n        background-color: @navbar-default-link-hover-bg;\n      }\n    }\n    > .active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-active-color;\n        background-color: @navbar-default-link-active-bg;\n      }\n    }\n    > .disabled > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-default-link-disabled-color;\n        background-color: @navbar-default-link-disabled-bg;\n      }\n    }\n  }\n\n  .navbar-toggle {\n    border-color: @navbar-default-toggle-border-color;\n    &:hover,\n    &:focus {\n      background-color: @navbar-default-toggle-hover-bg;\n    }\n    .icon-bar {\n      background-color: @navbar-default-toggle-icon-bar-bg;\n    }\n  }\n\n  .navbar-collapse,\n  .navbar-form {\n    border-color: @navbar-default-border;\n  }\n\n  // Dropdown menu items\n  .navbar-nav {\n    // Remove background color from open dropdown\n    > .open > a {\n      &,\n      &:hover,\n      &:focus {\n        background-color: @navbar-default-link-active-bg;\n        color: @navbar-default-link-active-color;\n      }\n    }\n\n    @media (max-width: @grid-float-breakpoint-max) {\n      // Dropdowns get custom display when collapsed\n      .open .dropdown-menu {\n        > li > a {\n          color: @navbar-default-link-color;\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-hover-color;\n            background-color: @navbar-default-link-hover-bg;\n          }\n        }\n        > .active > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-active-color;\n            background-color: @navbar-default-link-active-bg;\n          }\n        }\n        > .disabled > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-default-link-disabled-color;\n            background-color: @navbar-default-link-disabled-bg;\n          }\n        }\n      }\n    }\n  }\n\n\n  // Links in navbars\n  //\n  // Add a class to ensure links outside the navbar nav are colored correctly.\n\n  .navbar-link {\n    color: @navbar-default-link-color;\n    &:hover {\n      color: @navbar-default-link-hover-color;\n    }\n  }\n\n}\n\n// Inverse navbar\n\n.navbar-inverse {\n  background-color: @navbar-inverse-bg;\n  border-color: @navbar-inverse-border;\n\n  .navbar-brand {\n    color: @navbar-inverse-brand-color;\n    &:hover,\n    &:focus {\n      color: @navbar-inverse-brand-hover-color;\n      background-color: @navbar-inverse-brand-hover-bg;\n    }\n  }\n\n  .navbar-text {\n    color: @navbar-inverse-color;\n  }\n\n  .navbar-nav {\n    > li > a {\n      color: @navbar-inverse-link-color;\n\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-hover-color;\n        background-color: @navbar-inverse-link-hover-bg;\n      }\n    }\n    > .active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-active-color;\n        background-color: @navbar-inverse-link-active-bg;\n      }\n    }\n    > .disabled > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @navbar-inverse-link-disabled-color;\n        background-color: @navbar-inverse-link-disabled-bg;\n      }\n    }\n  }\n\n  // Darken the responsive nav toggle\n  .navbar-toggle {\n    border-color: @navbar-inverse-toggle-border-color;\n    &:hover,\n    &:focus {\n      background-color: @navbar-inverse-toggle-hover-bg;\n    }\n    .icon-bar {\n      background-color: @navbar-inverse-toggle-icon-bar-bg;\n    }\n  }\n\n  .navbar-collapse,\n  .navbar-form {\n    border-color: darken(@navbar-inverse-bg, 7%);\n  }\n\n  // Dropdowns\n  .navbar-nav {\n    > .open > a {\n      &,\n      &:hover,\n      &:focus {\n        background-color: @navbar-inverse-link-active-bg;\n        color: @navbar-inverse-link-active-color;\n      }\n    }\n\n    @media (max-width: @grid-float-breakpoint-max) {\n      // Dropdowns get custom display\n      .open .dropdown-menu {\n        > .dropdown-header {\n          border-color: @navbar-inverse-border;\n        }\n        .divider {\n          background-color: @navbar-inverse-border;\n        }\n        > li > a {\n          color: @navbar-inverse-link-color;\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-hover-color;\n            background-color: @navbar-inverse-link-hover-bg;\n          }\n        }\n        > .active > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-active-color;\n            background-color: @navbar-inverse-link-active-bg;\n          }\n        }\n        > .disabled > a {\n          &,\n          &:hover,\n          &:focus {\n            color: @navbar-inverse-link-disabled-color;\n            background-color: @navbar-inverse-link-disabled-bg;\n          }\n        }\n      }\n    }\n  }\n\n  .navbar-link {\n    color: @navbar-inverse-link-color;\n    &:hover {\n      color: @navbar-inverse-link-hover-color;\n    }\n  }\n\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/navs.less",
    "content": "//\n// Navs\n// --------------------------------------------------\n\n\n// Base class\n// --------------------------------------------------\n\n.nav {\n  margin-bottom: 0;\n  padding-left: 0; // Override default ul/ol\n  list-style: none;\n  .clearfix();\n\n  > li {\n    position: relative;\n    display: block;\n\n    > a {\n      position: relative;\n      display: block;\n      padding: @nav-link-padding;\n      &:hover,\n      &:focus {\n        text-decoration: none;\n        background-color: @nav-link-hover-bg;\n      }\n    }\n\n    // Disabled state sets text to gray and nukes hover/tab effects\n    &.disabled > a {\n      color: @nav-disabled-link-color;\n\n      &:hover,\n      &:focus {\n        color: @nav-disabled-link-hover-color;\n        text-decoration: none;\n        background-color: transparent;\n        cursor: not-allowed;\n      }\n    }\n  }\n\n  // Open dropdowns\n  .open > a {\n    &,\n    &:hover,\n    &:focus {\n      background-color: @nav-link-hover-bg;\n      border-color: @link-color;\n    }\n  }\n\n  // Nav dividers (deprecated with v3.0.1)\n  //\n  // This should have been removed in v3 with the dropping of `.nav-list`, but\n  // we missed it. We don't currently support this anywhere, but in the interest\n  // of maintaining backward compatibility in case you use it, it's deprecated.\n  .nav-divider {\n    .nav-divider();\n  }\n\n  // Prevent IE8 from misplacing imgs\n  //\n  // See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n  > li > a > img {\n    max-width: none;\n  }\n}\n\n\n// Tabs\n// -------------------------\n\n// Give the tabs something to sit on\n.nav-tabs {\n  border-bottom: 1px solid @nav-tabs-border-color;\n  > li {\n    float: left;\n    // Make the list-items overlay the bottom border\n    margin-bottom: -1px;\n\n    // Actual tabs (as links)\n    > a {\n      margin-right: 2px;\n      line-height: @line-height-base;\n      border: 1px solid transparent;\n      border-radius: @border-radius-base @border-radius-base 0 0;\n      &:hover {\n        border-color: @nav-tabs-link-hover-border-color @nav-tabs-link-hover-border-color @nav-tabs-border-color;\n      }\n    }\n\n    // Active state, and it's :hover to override normal :hover\n    &.active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @nav-tabs-active-link-hover-color;\n        background-color: @nav-tabs-active-link-hover-bg;\n        border: 1px solid @nav-tabs-active-link-hover-border-color;\n        border-bottom-color: transparent;\n        cursor: default;\n      }\n    }\n  }\n  // pulling this in mainly for less shorthand\n  &.nav-justified {\n    .nav-justified();\n    .nav-tabs-justified();\n  }\n}\n\n\n// Pills\n// -------------------------\n.nav-pills {\n  > li {\n    float: left;\n\n    // Links rendered as pills\n    > a {\n      border-radius: @nav-pills-border-radius;\n    }\n    + li {\n      margin-left: 2px;\n    }\n\n    // Active state\n    &.active > a {\n      &,\n      &:hover,\n      &:focus {\n        color: @nav-pills-active-link-hover-color;\n        background-color: @nav-pills-active-link-hover-bg;\n      }\n    }\n  }\n}\n\n\n// Stacked pills\n.nav-stacked {\n  > li {\n    float: none;\n    + li {\n      margin-top: 2px;\n      margin-left: 0; // no need for this gap between nav items\n    }\n  }\n}\n\n\n// Nav variations\n// --------------------------------------------------\n\n// Justified nav links\n// -------------------------\n\n.nav-justified {\n  width: 100%;\n\n  > li {\n    float: none;\n     > a {\n      text-align: center;\n      margin-bottom: 5px;\n    }\n  }\n\n  > .dropdown .dropdown-menu {\n    top: auto;\n    left: auto;\n  }\n\n  @media (min-width: @screen-sm-min) {\n    > li {\n      display: table-cell;\n      width: 1%;\n      > a {\n        margin-bottom: 0;\n      }\n    }\n  }\n}\n\n// Move borders to anchors instead of bottom of list\n//\n// Mixin for adding on top the shared `.nav-justified` styles for our tabs\n.nav-tabs-justified {\n  border-bottom: 0;\n\n  > li > a {\n    // Override margin from .nav-tabs\n    margin-right: 0;\n    border-radius: @border-radius-base;\n  }\n\n  > .active > a,\n  > .active > a:hover,\n  > .active > a:focus {\n    border: 1px solid @nav-tabs-justified-link-border-color;\n  }\n\n  @media (min-width: @screen-sm-min) {\n    > li > a {\n      border-bottom: 1px solid @nav-tabs-justified-link-border-color;\n      border-radius: @border-radius-base @border-radius-base 0 0;\n    }\n    > .active > a,\n    > .active > a:hover,\n    > .active > a:focus {\n      border-bottom-color: @nav-tabs-justified-active-link-border-color;\n    }\n  }\n}\n\n\n// Tabbable tabs\n// -------------------------\n\n// Hide tabbable panes to start, show them when `.active`\n.tab-content {\n  > .tab-pane {\n    display: none;\n  }\n  > .active {\n    display: block;\n  }\n}\n\n\n// Dropdowns\n// -------------------------\n\n// Specific dropdowns\n.nav-tabs .dropdown-menu {\n  // make dropdown border overlap tab border\n  margin-top: -1px;\n  // Remove the top rounded corners here since there is a hard edge above the menu\n  .border-top-radius(0);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/normalize.less",
    "content": "/*! normalize.css v2.1.3 | MIT License | git.io/normalize */\n\n// ==========================================================================\n// HTML5 display definitions\n// ==========================================================================\n\n//\n// Correct `block` display not defined in IE 8/9.\n//\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nnav,\nsection,\nsummary {\n  display: block;\n}\n\n//\n// Correct `inline-block` display not defined in IE 8/9.\n//\n\naudio,\ncanvas,\nvideo {\n  display: inline-block;\n}\n\n//\n// Prevent modern browsers from displaying `audio` without controls.\n// Remove excess height in iOS 5 devices.\n//\n\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n\n//\n// Address `[hidden]` styling not present in IE 8/9.\n// Hide the `template` element in IE, Safari, and Firefox < 22.\n//\n\n[hidden],\ntemplate {\n  display: none;\n}\n\n// ==========================================================================\n// Base\n// ==========================================================================\n\n//\n// 1. Set default font family to sans-serif.\n// 2. Prevent iOS text size adjust after orientation change, without disabling\n//    user zoom.\n//\n\nhtml {\n  font-family: sans-serif; // 1\n  -ms-text-size-adjust: 100%; // 2\n  -webkit-text-size-adjust: 100%; // 2\n}\n\n//\n// Remove default margin.\n//\n\nbody {\n  margin: 0;\n}\n\n// ==========================================================================\n// Links\n// ==========================================================================\n\n//\n// Remove the gray background color from active links in IE 10.\n//\n\na {\n  background: transparent;\n}\n\n//\n// Address `outline` inconsistency between Chrome and other browsers.\n//\n\na:focus {\n  outline: thin dotted;\n}\n\n//\n// Improve readability when focused and also mouse hovered in all browsers.\n//\n\na:active,\na:hover {\n  outline: 0;\n}\n\n// ==========================================================================\n// Typography\n// ==========================================================================\n\n//\n// Address variable `h1` font-size and margin within `section` and `article`\n// contexts in Firefox 4+, Safari 5, and Chrome.\n//\n\nh1 {\n  font-size: 2em;\n  margin: 0.67em 0;\n}\n\n//\n// Address styling not present in IE 8/9, Safari 5, and Chrome.\n//\n\nabbr[title] {\n  border-bottom: 1px dotted;\n}\n\n//\n// Address style set to `bolder` in Firefox 4+, Safari 5, and Chrome.\n//\n\nb,\nstrong {\n  font-weight: bold;\n}\n\n//\n// Address styling not present in Safari 5 and Chrome.\n//\n\ndfn {\n  font-style: italic;\n}\n\n//\n// Address differences between Firefox and other browsers.\n//\n\nhr {\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n  height: 0;\n}\n\n//\n// Address styling not present in IE 8/9.\n//\n\nmark {\n  background: #ff0;\n  color: #000;\n}\n\n//\n// Correct font family set oddly in Safari 5 and Chrome.\n//\n\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, serif;\n  font-size: 1em;\n}\n\n//\n// Improve readability of pre-formatted text in all browsers.\n//\n\npre {\n  white-space: pre-wrap;\n}\n\n//\n// Set consistent quote types.\n//\n\nq {\n  quotes: \"\\201C\" \"\\201D\" \"\\2018\" \"\\2019\";\n}\n\n//\n// Address inconsistent and variable font size in all browsers.\n//\n\nsmall {\n  font-size: 80%;\n}\n\n//\n// Prevent `sub` and `sup` affecting `line-height` in all browsers.\n//\n\nsub,\nsup {\n  font-size: 75%;\n  line-height: 0;\n  position: relative;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\n// ==========================================================================\n// Embedded content\n// ==========================================================================\n\n//\n// Remove border when inside `a` element in IE 8/9.\n//\n\nimg {\n  border: 0;\n}\n\n//\n// Correct overflow displayed oddly in IE 9.\n//\n\nsvg:not(:root) {\n  overflow: hidden;\n}\n\n// ==========================================================================\n// Figures\n// ==========================================================================\n\n//\n// Address margin not present in IE 8/9 and Safari 5.\n//\n\nfigure {\n  margin: 0;\n}\n\n// ==========================================================================\n// Forms\n// ==========================================================================\n\n//\n// Define consistent border, margin, and padding.\n//\n\nfieldset {\n  border: 1px solid #c0c0c0;\n  margin: 0 2px;\n  padding: 0.35em 0.625em 0.75em;\n}\n\n//\n// 1. Correct `color` not being inherited in IE 8/9.\n// 2. Remove padding so people aren't caught out if they zero out fieldsets.\n//\n\nlegend {\n  border: 0; // 1\n  padding: 0; // 2\n}\n\n//\n// 1. Correct font family not being inherited in all browsers.\n// 2. Correct font size not being inherited in all browsers.\n// 3. Address margins set differently in Firefox 4+, Safari 5, and Chrome.\n//\n\nbutton,\ninput,\nselect,\ntextarea {\n  font-family: inherit; // 1\n  font-size: 100%; // 2\n  margin: 0; // 3\n}\n\n//\n// Address Firefox 4+ setting `line-height` on `input` using `!important` in\n// the UA stylesheet.\n//\n\nbutton,\ninput {\n  line-height: normal;\n}\n\n//\n// Address inconsistent `text-transform` inheritance for `button` and `select`.\n// All other form control elements do not inherit `text-transform` values.\n// Correct `button` style inheritance in Chrome, Safari 5+, and IE 8+.\n// Correct `select` style inheritance in Firefox 4+ and Opera.\n//\n\nbutton,\nselect {\n  text-transform: none;\n}\n\n//\n// 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`\n//    and `video` controls.\n// 2. Correct inability to style clickable `input` types in iOS.\n// 3. Improve usability and consistency of cursor style between image-type\n//    `input` and others.\n//\n\nbutton,\nhtml input[type=\"button\"], // 1\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button; // 2\n  cursor: pointer; // 3\n}\n\n//\n// Re-set default cursor for disabled elements.\n//\n\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\n\n//\n// 1. Address box sizing set to `content-box` in IE 8/9/10.\n// 2. Remove excess padding in IE 8/9/10.\n//\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  box-sizing: border-box; // 1\n  padding: 0; // 2\n}\n\n//\n// 1. Address `appearance` set to `searchfield` in Safari 5 and Chrome.\n// 2. Address `box-sizing` set to `border-box` in Safari 5 and Chrome\n//    (include `-moz` to future-proof).\n//\n\ninput[type=\"search\"] {\n  -webkit-appearance: textfield; // 1\n  -moz-box-sizing: content-box;\n  -webkit-box-sizing: content-box; // 2\n  box-sizing: content-box;\n}\n\n//\n// Remove inner padding and search cancel button in Safari 5 and Chrome\n// on OS X.\n//\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\n//\n// Remove inner padding and border in Firefox 4+.\n//\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  border: 0;\n  padding: 0;\n}\n\n//\n// 1. Remove default vertical scrollbar in IE 8/9.\n// 2. Improve readability and alignment in all browsers.\n//\n\ntextarea {\n  overflow: auto; // 1\n  vertical-align: top; // 2\n}\n\n// ==========================================================================\n// Tables\n// ==========================================================================\n\n//\n// Remove most spacing between table cells.\n//\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/pager.less",
    "content": "//\n// Pager pagination\n// --------------------------------------------------\n\n\n.pager {\n  padding-left: 0;\n  margin: @line-height-computed 0;\n  list-style: none;\n  text-align: center;\n  .clearfix();\n  li {\n    display: inline;\n    > a,\n    > span {\n      display: inline-block;\n      padding: 5px 14px;\n      background-color: @pagination-bg;\n      border: 1px solid @pagination-border;\n      border-radius: @pager-border-radius;\n    }\n\n    > a:hover,\n    > a:focus {\n      text-decoration: none;\n      background-color: @pagination-hover-bg;\n    }\n  }\n\n  .next {\n    > a,\n    > span {\n      float: right;\n    }\n  }\n\n  .previous {\n    > a,\n    > span {\n      float: left;\n    }\n  }\n\n  .disabled {\n    > a,\n    > a:hover,\n    > a:focus,\n    > span {\n      color: @pager-disabled-color;\n      background-color: @pagination-bg;\n      cursor: not-allowed;\n    }\n  }\n\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/pagination.less",
    "content": "//\n// Pagination (multiple pages)\n// --------------------------------------------------\n.pagination {\n  display: inline-block;\n  padding-left: 0;\n  margin: @line-height-computed 0;\n  border-radius: @border-radius-base;\n\n  > li {\n    display: inline; // Remove list-style and block-level defaults\n    > a,\n    > span {\n      position: relative;\n      float: left; // Collapse white-space\n      padding: @padding-base-vertical @padding-base-horizontal;\n      line-height: @line-height-base;\n      text-decoration: none;\n      background-color: @pagination-bg;\n      border: 1px solid @pagination-border;\n      margin-left: -1px;\n    }\n    &:first-child {\n      > a,\n      > span {\n        margin-left: 0;\n        .border-left-radius(@border-radius-base);\n      }\n    }\n    &:last-child {\n      > a,\n      > span {\n        .border-right-radius(@border-radius-base);\n      }\n    }\n  }\n\n  > li > a,\n  > li > span {\n    &:hover,\n    &:focus {\n      background-color: @pagination-hover-bg;\n    }\n  }\n\n  > .active > a,\n  > .active > span {\n    &,\n    &:hover,\n    &:focus {\n      z-index: 2;\n      color: @pagination-active-color;\n      background-color: @pagination-active-bg;\n      border-color: @pagination-active-bg;\n      cursor: default;\n    }\n  }\n\n  > .disabled {\n    > span,\n    > span:hover,\n    > span:focus,\n    > a,\n    > a:hover,\n    > a:focus {\n      color: @pagination-disabled-color;\n      background-color: @pagination-bg;\n      border-color: @pagination-border;\n      cursor: not-allowed;\n    }\n  }\n}\n\n// Sizing\n// --------------------------------------------------\n\n// Large\n.pagination-lg {\n  .pagination-size(@padding-large-vertical; @padding-large-horizontal; @font-size-large; @border-radius-large);\n}\n\n// Small\n.pagination-sm {\n  .pagination-size(@padding-small-vertical; @padding-small-horizontal; @font-size-small; @border-radius-small);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/panels.less",
    "content": "//\n// Panels\n// --------------------------------------------------\n\n\n// Base class\n.panel {\n  margin-bottom: @line-height-computed;\n  background-color: @panel-bg;\n  border: 1px solid transparent;\n  border-radius: @panel-border-radius;\n  .box-shadow(0 1px 1px rgba(0,0,0,.05));\n}\n\n// Panel contents\n.panel-body {\n  padding: 15px;\n  .clearfix();\n}\n\n\n// List groups in panels\n//\n// By default, space out list group content from panel headings to account for\n// any kind of custom content between the two.\n\n.panel {\n  > .list-group {\n    margin-bottom: 0;\n\n    .list-group-item {\n      border-width: 1px 0;\n\n      // Remove border radius for top one\n      &:first-child {\n        .border-top-radius(0);\n      }\n      // But keep it for the last one\n      &:last-child {\n        border-bottom: 0;\n      }\n    }\n  }\n}\n// Collapse space between when there's no additional content.\n.panel-heading + .list-group {\n  .list-group-item:first-child {\n    border-top-width: 0;\n  }\n}\n\n\n// Tables in panels\n//\n// Place a non-bordered `.table` within a panel (not within a `.panel-body`) and\n// watch it go full width.\n\n.panel {\n  > .table,\n  > .table-responsive > .table {\n    margin-bottom: 0;\n  }\n  > .panel-body + .table,\n  > .panel-body + .table-responsive {\n    border-top: 1px solid @table-border-color;\n  }\n  > .table > tbody:first-child th,\n  > .table > tbody:first-child td {\n    border-top: 0;\n  }\n  > .table-bordered,\n  > .table-responsive > .table-bordered {\n    border: 0;\n    > thead,\n    > tbody,\n    > tfoot {\n      > tr {\n        > th:first-child,\n        > td:first-child {\n          border-left: 0;\n        }\n        > th:last-child,\n        > td:last-child {\n          border-right: 0;\n        }\n\n        &:last-child > th,\n        &:last-child > td {\n          border-bottom: 0;\n        }\n      }\n    }\n  }\n  > .table-responsive {\n    border: 0;\n    margin-bottom: 0;\n  }\n}\n\n\n// Optional heading\n.panel-heading {\n  padding: 10px 15px;\n  border-bottom: 1px solid transparent;\n  .border-top-radius(@panel-border-radius - 1);\n\n  > .dropdown .dropdown-toggle {\n    color: inherit;\n  }\n}\n\n// Within heading, strip any `h*` tag of it's default margins for spacing.\n.panel-title {\n  margin-top: 0;\n  margin-bottom: 0;\n  font-size: ceil((@font-size-base * 1.125));\n  color: inherit;\n\n  > a {\n    color: inherit;\n  }\n}\n\n// Optional footer (stays gray in every modifier class)\n.panel-footer {\n  padding: 10px 15px;\n  background-color: @panel-footer-bg;\n  border-top: 1px solid @panel-inner-border;\n  .border-bottom-radius(@panel-border-radius - 1);\n}\n\n\n// Collapsable panels (aka, accordion)\n//\n// Wrap a series of panels in `.panel-group` to turn them into an accordion with\n// the help of our collapse JavaScript plugin.\n\n.panel-group {\n  // Tighten up margin so it's only between panels\n  .panel {\n    margin-bottom: 0;\n    border-radius: @panel-border-radius;\n    overflow: hidden; // crop contents when collapsed\n    + .panel {\n      margin-top: 5px;\n    }\n  }\n\n  .panel-heading {\n    border-bottom: 0;\n    + .panel-collapse .panel-body {\n      border-top: 1px solid @panel-inner-border;\n    }\n  }\n  .panel-footer {\n    border-top: 0;\n    + .panel-collapse .panel-body {\n      border-bottom: 1px solid @panel-inner-border;\n    }\n  }\n}\n\n\n// Contextual variations\n.panel-default {\n  .panel-variant(@panel-default-border; @panel-default-text; @panel-default-heading-bg; @panel-default-border);\n}\n.panel-primary {\n  .panel-variant(@panel-primary-border; @panel-primary-text; @panel-primary-heading-bg; @panel-primary-border);\n}\n.panel-success {\n  .panel-variant(@panel-success-border; @panel-success-text; @panel-success-heading-bg; @panel-success-border);\n}\n.panel-warning {\n  .panel-variant(@panel-warning-border; @panel-warning-text; @panel-warning-heading-bg; @panel-warning-border);\n}\n.panel-danger {\n  .panel-variant(@panel-danger-border; @panel-danger-text; @panel-danger-heading-bg; @panel-danger-border);\n}\n.panel-info {\n  .panel-variant(@panel-info-border; @panel-info-text; @panel-info-heading-bg; @panel-info-border);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/popovers.less",
    "content": "//\n// Popovers\n// --------------------------------------------------\n\n\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: @zindex-popover;\n  display: none;\n  max-width: @popover-max-width;\n  padding: 1px;\n  text-align: left; // Reset given new insertion method\n  background-color: @popover-bg;\n  background-clip: padding-box;\n  border: 1px solid @popover-fallback-border-color;\n  border: 1px solid @popover-border-color;\n  border-radius: @border-radius-large;\n  .box-shadow(0 5px 10px rgba(0,0,0,.2));\n\n  // Overrides for proper insertion\n  white-space: normal;\n\n  // Offset the popover to account for the popover arrow\n  &.top     { margin-top: -10px; }\n  &.right   { margin-left: 10px; }\n  &.bottom  { margin-top: 10px; }\n  &.left    { margin-left: -10px; }\n}\n\n.popover-title {\n  margin: 0; // reset heading margin\n  padding: 8px 14px;\n  font-size: @font-size-base;\n  font-weight: normal;\n  line-height: 18px;\n  background-color: @popover-title-bg;\n  border-bottom: 1px solid darken(@popover-title-bg, 5%);\n  border-radius: 5px 5px 0 0;\n}\n\n.popover-content {\n  padding: 9px 14px;\n}\n\n// Arrows\n//\n// .arrow is outer, .arrow:after is inner\n\n.popover .arrow {\n  &,\n  &:after {\n    position: absolute;\n    display: block;\n    width: 0;\n    height: 0;\n    border-color: transparent;\n    border-style: solid;\n  }\n}\n.popover .arrow {\n  border-width: @popover-arrow-outer-width;\n}\n.popover .arrow:after {\n  border-width: @popover-arrow-width;\n  content: \"\";\n}\n\n.popover {\n  &.top .arrow {\n    left: 50%;\n    margin-left: -@popover-arrow-outer-width;\n    border-bottom-width: 0;\n    border-top-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-top-color: @popover-arrow-outer-color;\n    bottom: -@popover-arrow-outer-width;\n    &:after {\n      content: \" \";\n      bottom: 1px;\n      margin-left: -@popover-arrow-width;\n      border-bottom-width: 0;\n      border-top-color: @popover-arrow-color;\n    }\n  }\n  &.right .arrow {\n    top: 50%;\n    left: -@popover-arrow-outer-width;\n    margin-top: -@popover-arrow-outer-width;\n    border-left-width: 0;\n    border-right-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-right-color: @popover-arrow-outer-color;\n    &:after {\n      content: \" \";\n      left: 1px;\n      bottom: -@popover-arrow-width;\n      border-left-width: 0;\n      border-right-color: @popover-arrow-color;\n    }\n  }\n  &.bottom .arrow {\n    left: 50%;\n    margin-left: -@popover-arrow-outer-width;\n    border-top-width: 0;\n    border-bottom-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-bottom-color: @popover-arrow-outer-color;\n    top: -@popover-arrow-outer-width;\n    &:after {\n      content: \" \";\n      top: 1px;\n      margin-left: -@popover-arrow-width;\n      border-top-width: 0;\n      border-bottom-color: @popover-arrow-color;\n    }\n  }\n\n  &.left .arrow {\n    top: 50%;\n    right: -@popover-arrow-outer-width;\n    margin-top: -@popover-arrow-outer-width;\n    border-right-width: 0;\n    border-left-color: @popover-arrow-outer-fallback-color; // IE8 fallback\n    border-left-color: @popover-arrow-outer-color;\n    &:after {\n      content: \" \";\n      right: 1px;\n      border-right-width: 0;\n      border-left-color: @popover-arrow-color;\n      bottom: -@popover-arrow-width;\n    }\n  }\n\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/print.less",
    "content": "//\n// Basic print styles\n// --------------------------------------------------\n// Source: https://github.com/h5bp/html5-boilerplate/blob/master/css/main.css\n\n@media print {\n\n  * {\n    text-shadow: none !important;\n    color: #000 !important; // Black prints faster: h5bp.com/s\n    background: transparent !important;\n    box-shadow: none !important;\n  }\n\n  a,\n  a:visited {\n    text-decoration: underline;\n  }\n\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n\n  // Don't show links for images, or javascript/internal links\n  a[href^=\"javascript:\"]:after,\n  a[href^=\"#\"]:after {\n    content: \"\";\n  }\n\n  pre,\n  blockquote {\n    border: 1px solid #999;\n    page-break-inside: avoid;\n  }\n\n  thead {\n    display: table-header-group; // h5bp.com/t\n  }\n\n  tr,\n  img {\n    page-break-inside: avoid;\n  }\n\n  img {\n    max-width: 100% !important;\n  }\n\n  @page {\n    margin: 2cm .5cm;\n  }\n\n  p,\n  h2,\n  h3 {\n    orphans: 3;\n    widows: 3;\n  }\n\n  h2,\n  h3 {\n    page-break-after: avoid;\n  }\n\n  // Chrome (OSX) fix for https://github.com/twbs/bootstrap/issues/11245\n  // Once fixed, we can just straight up remove this.\n  select {\n    background: #fff !important;\n  }\n\n  // Bootstrap components\n  .navbar {\n    display: none;\n  }\n  .table {\n    td,\n    th {\n      background-color: #fff !important;\n    }\n  }\n  .btn,\n  .dropup > .btn {\n    > .caret {\n      border-top-color: #000 !important;\n    }\n  }\n  .label {\n    border: 1px solid #000;\n  }\n\n  .table {\n    border-collapse: collapse !important;\n  }\n  .table-bordered {\n    th,\n    td {\n      border: 1px solid #ddd !important;\n    }\n  }\n\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/progress-bars.less",
    "content": "//\n// Progress bars\n// --------------------------------------------------\n\n\n// Bar animations\n// -------------------------\n\n// WebKit\n@-webkit-keyframes progress-bar-stripes {\n  from  { background-position: 40px 0; }\n  to    { background-position: 0 0; }\n}\n\n// Spec and IE10+\n@keyframes progress-bar-stripes {\n  from  { background-position: 40px 0; }\n  to    { background-position: 0 0; }\n}\n\n\n\n// Bar itself\n// -------------------------\n\n// Outer container\n.progress {\n  overflow: hidden;\n  height: @line-height-computed;\n  margin-bottom: @line-height-computed;\n  background-color: @progress-bg;\n  border-radius: @border-radius-base;\n  .box-shadow(inset 0 1px 2px rgba(0,0,0,.1));\n}\n\n// Bar of progress\n.progress-bar {\n  float: left;\n  width: 0%;\n  height: 100%;\n  font-size: @font-size-small;\n  line-height: @line-height-computed;\n  color: @progress-bar-color;\n  text-align: center;\n  background-color: @progress-bar-bg;\n  .box-shadow(inset 0 -1px 0 rgba(0,0,0,.15));\n  .transition(width .6s ease);\n}\n\n// Striped bars\n.progress-striped .progress-bar {\n  #gradient > .striped();\n  background-size: 40px 40px;\n}\n\n// Call animation for the active one\n.progress.active .progress-bar {\n  .animation(progress-bar-stripes 2s linear infinite);\n}\n\n\n\n// Variations\n// -------------------------\n\n.progress-bar-success {\n  .progress-bar-variant(@progress-bar-success-bg);\n}\n\n.progress-bar-info {\n  .progress-bar-variant(@progress-bar-info-bg);\n}\n\n.progress-bar-warning {\n  .progress-bar-variant(@progress-bar-warning-bg);\n}\n\n.progress-bar-danger {\n  .progress-bar-variant(@progress-bar-danger-bg);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/responsive-utilities.less",
    "content": "//\n// Responsive: Utility classes\n// --------------------------------------------------\n\n\n// IE10 in Windows (Phone) 8\n//\n// Support for responsive views via media queries is kind of borked in IE10, for\n// Surface/desktop in split view and for Windows Phone 8. This particular fix\n// must be accompanied by a snippet of JavaScript to sniff the user agent and\n// apply some conditional CSS to *only* the Surface/desktop Windows 8. Look at\n// our Getting Started page for more information on this bug.\n//\n// For more information, see the following:\n//\n// Issue: https://github.com/twbs/bootstrap/issues/10497\n// Docs: http://getbootstrap.com/getting-started/#browsers\n// Source: http://timkadlec.com/2012/10/ie10-snap-mode-and-responsive-design/\n\n@-ms-viewport {\n  width: device-width;\n}\n\n\n// Visibility utilities\n\n.visible-xs {\n  .responsive-invisibility();\n  @media (max-width: @screen-xs-max) {\n    .responsive-visibility();\n  }\n  &.visible-sm {\n    @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n      .responsive-visibility();\n    }\n  }\n  &.visible-md {\n    @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n      .responsive-visibility();\n    }\n  }\n  &.visible-lg {\n    @media (min-width: @screen-lg-min) {\n      .responsive-visibility();\n    }\n  }\n}\n.visible-sm {\n  .responsive-invisibility();\n  &.visible-xs {\n    @media (max-width: @screen-xs-max) {\n      .responsive-visibility();\n    }\n  }\n  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n    .responsive-visibility();\n  }\n  &.visible-md {\n    @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n      .responsive-visibility();\n    }\n  }\n  &.visible-lg {\n    @media (min-width: @screen-lg-min) {\n      .responsive-visibility();\n    }\n  }\n}\n.visible-md {\n  .responsive-invisibility();\n  &.visible-xs {\n    @media (max-width: @screen-xs-max) {\n      .responsive-visibility();\n    }\n  }\n  &.visible-sm {\n    @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n      .responsive-visibility();\n    }\n  }\n  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n    .responsive-visibility();\n  }\n  &.visible-lg {\n    @media (min-width: @screen-lg-min) {\n      .responsive-visibility();\n    }\n  }\n}\n.visible-lg {\n  .responsive-invisibility();\n  &.visible-xs {\n    @media (max-width: @screen-xs-max) {\n      .responsive-visibility();\n    }\n  }\n  &.visible-sm {\n    @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n      .responsive-visibility();\n    }\n  }\n  &.visible-md {\n    @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n      .responsive-visibility();\n    }\n  }\n  @media (min-width: @screen-lg-min) {\n    .responsive-visibility();\n  }\n}\n\n.hidden-xs {\n  .responsive-visibility();\n  @media (max-width: @screen-xs-max) {\n    .responsive-invisibility();\n  }\n  &.hidden-sm {\n    @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n      .responsive-invisibility();\n    }\n  }\n  &.hidden-md {\n    @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n      .responsive-invisibility();\n    }\n  }\n  &.hidden-lg {\n    @media (min-width: @screen-lg-min) {\n      .responsive-invisibility();\n    }\n  }\n}\n.hidden-sm {\n  .responsive-visibility();\n  &.hidden-xs {\n    @media (max-width: @screen-xs-max) {\n      .responsive-invisibility();\n    }\n  }\n  @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n    .responsive-invisibility();\n  }\n  &.hidden-md {\n    @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n      .responsive-invisibility();\n    }\n  }\n  &.hidden-lg {\n    @media (min-width: @screen-lg-min) {\n      .responsive-invisibility();\n    }\n  }\n}\n.hidden-md {\n  .responsive-visibility();\n  &.hidden-xs {\n    @media (max-width: @screen-xs-max) {\n      .responsive-invisibility();\n    }\n  }\n  &.hidden-sm {\n    @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n      .responsive-invisibility();\n    }\n  }\n  @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n    .responsive-invisibility();\n  }\n  &.hidden-lg {\n    @media (min-width: @screen-lg-min) {\n      .responsive-invisibility();\n    }\n  }\n}\n.hidden-lg {\n  .responsive-visibility();\n  &.hidden-xs {\n    @media (max-width: @screen-xs-max) {\n      .responsive-invisibility();\n    }\n  }\n  &.hidden-sm {\n    @media (min-width: @screen-sm-min) and (max-width: @screen-sm-max) {\n      .responsive-invisibility();\n    }\n  }\n  &.hidden-md {\n    @media (min-width: @screen-md-min) and (max-width: @screen-md-max) {\n      .responsive-invisibility();\n    }\n  }\n  @media (min-width: @screen-lg-min) {\n    .responsive-invisibility();\n  }\n}\n\n// Print utilities\n.visible-print {\n  .responsive-invisibility();\n}\n\n@media print {\n  .visible-print {\n    .responsive-visibility();\n  }\n  .hidden-print {\n    .responsive-invisibility();\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/scaffolding.less",
    "content": "//\n// Scaffolding\n// --------------------------------------------------\n\n\n// Reset the box-sizing\n\n*,\n*:before,\n*:after {\n  .box-sizing(border-box);\n}\n\n\n// Body reset\n\nhtml {\n  font-size: 62.5%;\n  -webkit-tap-highlight-color: rgba(0,0,0,0);\n}\n\nbody {\n  font-family: @font-family-base;\n  font-size: @font-size-base;\n  line-height: @line-height-base;\n  color: @text-color;\n  background-color: @body-bg;\n}\n\n// Reset fonts for relevant elements\ninput,\nbutton,\nselect,\ntextarea {\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\n\n\n// Links\n\na {\n  color: @link-color;\n  text-decoration: none;\n\n  &:hover,\n  &:focus {\n    color: @link-hover-color;\n    text-decoration: underline;\n  }\n\n  &:focus {\n    .tab-focus();\n  }\n}\n\n\n// Images\n\nimg {\n  vertical-align: middle;\n}\n\n// Responsive images (ensure images don't scale beyond their parents)\n.img-responsive {\n  .img-responsive();\n}\n\n// Rounded corners\n.img-rounded {\n  border-radius: @border-radius-large;\n}\n\n// Image thumbnails\n//\n// Heads up! This is mixin-ed into thumbnails.less for `.thumbnail`.\n.img-thumbnail {\n  padding: @thumbnail-padding;\n  line-height: @line-height-base;\n  background-color: @thumbnail-bg;\n  border: 1px solid @thumbnail-border;\n  border-radius: @thumbnail-border-radius;\n  .transition(all .2s ease-in-out);\n\n  // Keep them at most 100% wide\n  .img-responsive(inline-block);\n}\n\n// Perfect circle\n.img-circle {\n  border-radius: 50%; // set radius in percents\n}\n\n\n// Horizontal rules\n\nhr {\n  margin-top:    @line-height-computed;\n  margin-bottom: @line-height-computed;\n  border: 0;\n  border-top: 1px solid @hr-border;\n}\n\n\n// Only display content to screen readers\n//\n// See: http://a11yproject.com/posts/how-to-hide-content/\n\n.sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  margin: -1px;\n  padding: 0;\n  overflow: hidden;\n  clip: rect(0,0,0,0);\n  border: 0;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/tables.less",
    "content": "//\n// Tables\n// --------------------------------------------------\n\n\ntable {\n  max-width: 100%;\n  background-color: @table-bg;\n}\nth {\n  text-align: left;\n}\n\n\n// Baseline styles\n\n.table {\n  width: 100%;\n  margin-bottom: @line-height-computed;\n  // Cells\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        padding: @table-cell-padding;\n        line-height: @line-height-base;\n        vertical-align: top;\n        border-top: 1px solid @table-border-color;\n      }\n    }\n  }\n  // Bottom align for column headings\n  > thead > tr > th {\n    vertical-align: bottom;\n    border-bottom: 2px solid @table-border-color;\n  }\n  // Remove top border from thead by default\n  > caption + thead,\n  > colgroup + thead,\n  > thead:first-child {\n    > tr:first-child {\n      > th,\n      > td {\n        border-top: 0;\n      }\n    }\n  }\n  // Account for multiple tbody instances\n  > tbody + tbody {\n    border-top: 2px solid @table-border-color;\n  }\n\n  // Nesting\n  .table {\n    background-color: @body-bg;\n  }\n}\n\n\n// Condensed table w/ half padding\n\n.table-condensed {\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        padding: @table-condensed-cell-padding;\n      }\n    }\n  }\n}\n\n\n// Bordered version\n//\n// Add borders all around the table and between all the columns.\n\n.table-bordered {\n  border: 1px solid @table-border-color;\n  > thead,\n  > tbody,\n  > tfoot {\n    > tr {\n      > th,\n      > td {\n        border: 1px solid @table-border-color;\n      }\n    }\n  }\n  > thead > tr {\n    > th,\n    > td {\n      border-bottom-width: 2px;\n    }\n  }\n}\n\n\n// Zebra-striping\n//\n// Default zebra-stripe styles (alternating gray and transparent backgrounds)\n\n.table-striped {\n  > tbody > tr:nth-child(odd) {\n    > td,\n    > th {\n      background-color: @table-bg-accent;\n    }\n  }\n}\n\n\n// Hover effect\n//\n// Placed here since it has to come after the potential zebra striping\n\n.table-hover {\n  > tbody > tr:hover {\n    > td,\n    > th {\n      background-color: @table-bg-hover;\n    }\n  }\n}\n\n\n// Table cell sizing\n//\n// Reset default table behavior\n\ntable col[class*=\"col-\"] {\n  position: static; // Prevent border hiding in Firefox and IE9/10 (see https://github.com/twbs/bootstrap/issues/11623)\n  float: none;\n  display: table-column;\n}\ntable {\n  td,\n  th {\n    &[class*=\"col-\"] {\n      float: none;\n      display: table-cell;\n    }\n  }\n}\n\n\n// Table backgrounds\n//\n// Exact selectors below required to override `.table-striped` and prevent\n// inheritance to nested tables.\n\n// Generate the contextual variants\n.table-row-variant(active; @table-bg-active);\n.table-row-variant(success; @state-success-bg);\n.table-row-variant(danger; @state-danger-bg);\n.table-row-variant(warning; @state-warning-bg);\n\n\n// Responsive tables\n//\n// Wrap your tables in `.table-responsive` and we'll make them mobile friendly\n// by enabling horizontal scrolling. Only applies <768px. Everything above that\n// will display normally.\n\n@media (max-width: @screen-xs-max) {\n  .table-responsive {\n    width: 100%;\n    margin-bottom: (@line-height-computed * 0.75);\n    overflow-y: hidden;\n    overflow-x: scroll;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    border: 1px solid @table-border-color;\n    -webkit-overflow-scrolling: touch;\n\n    // Tighten up spacing\n    > .table {\n      margin-bottom: 0;\n\n      // Ensure the content doesn't wrap\n      > thead,\n      > tbody,\n      > tfoot {\n        > tr {\n          > th,\n          > td {\n            white-space: nowrap;\n          }\n        }\n      }\n    }\n\n    // Special overrides for the bordered tables\n    > .table-bordered {\n      border: 0;\n\n      // Nuke the appropriate borders so that the parent can handle them\n      > thead,\n      > tbody,\n      > tfoot {\n        > tr {\n          > th:first-child,\n          > td:first-child {\n            border-left: 0;\n          }\n          > th:last-child,\n          > td:last-child {\n            border-right: 0;\n          }\n        }\n      }\n\n      // Only nuke the last row's bottom-border in `tbody` and `tfoot` since\n      // chances are there will be only one `tr` in a `thead` and that would\n      // remove the border altogether.\n      > tbody,\n      > tfoot {\n        > tr:last-child {\n          > th,\n          > td {\n            border-bottom: 0;\n          }\n        }\n      }\n\n    }\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/theme.less",
    "content": "\n//\n// Load core variables and mixins\n// --------------------------------------------------\n\n@import \"variables.less\";\n@import \"mixins.less\";\n\n\n\n//\n// Buttons\n// --------------------------------------------------\n\n// Common styles\n.btn-default,\n.btn-primary,\n.btn-success,\n.btn-info,\n.btn-warning,\n.btn-danger {\n  text-shadow: 0 -1px 0 rgba(0,0,0,.2);\n  @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 1px rgba(0,0,0,.075);\n  .box-shadow(@shadow);\n\n  // Reset the shadow\n  &:active,\n  &.active {\n    .box-shadow(inset 0 3px 5px rgba(0,0,0,.125));\n  }\n}\n\n// Mixin for generating new styles\n.btn-styles(@btn-color: #555) {\n  #gradient > .vertical(@start-color: @btn-color; @end-color: darken(@btn-color, 12%));\n  .reset-filter(); // Disable gradients for IE9 because filter bleeds through rounded corners\n  background-repeat: repeat-x;\n  border-color: darken(@btn-color, 14%);\n\n  &:hover,\n  &:focus  {\n    background-color: darken(@btn-color, 12%);\n    background-position: 0 -15px;\n  }\n\n  &:active,\n  &.active {\n    background-color: darken(@btn-color, 12%);\n    border-color: darken(@btn-color, 14%);\n  }\n}\n\n// Common styles\n.btn {\n  // Remove the gradient for the pressed/active state\n  &:active,\n  &.active {\n    background-image: none;\n  }\n}\n\n// Apply the mixin to the buttons\n.btn-default { .btn-styles(@btn-default-bg); text-shadow: 0 1px 0 #fff; border-color: #ccc; }\n.btn-primary { .btn-styles(@btn-primary-bg); }\n.btn-success { .btn-styles(@btn-success-bg); }\n.btn-warning { .btn-styles(@btn-warning-bg); }\n.btn-danger  { .btn-styles(@btn-danger-bg); }\n.btn-info    { .btn-styles(@btn-info-bg); }\n\n\n\n//\n// Images\n// --------------------------------------------------\n\n.thumbnail,\n.img-thumbnail {\n  .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n\n\n\n//\n// Dropdowns\n// --------------------------------------------------\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  #gradient > .vertical(@start-color: @dropdown-link-hover-bg; @end-color: darken(@dropdown-link-hover-bg, 5%));\n  background-color: darken(@dropdown-link-hover-bg, 5%);\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  #gradient > .vertical(@start-color: @dropdown-link-active-bg; @end-color: darken(@dropdown-link-active-bg, 5%));\n  background-color: darken(@dropdown-link-active-bg, 5%);\n}\n\n\n\n//\n// Navbar\n// --------------------------------------------------\n\n// Default navbar\n.navbar-default {\n  #gradient > .vertical(@start-color: lighten(@navbar-default-bg, 10%); @end-color: @navbar-default-bg);\n  .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n  border-radius: @navbar-border-radius;\n  @shadow: inset 0 1px 0 rgba(255,255,255,.15), 0 1px 5px rgba(0,0,0,.075);\n  .box-shadow(@shadow);\n\n  .navbar-nav > .active > a {\n    #gradient > .vertical(@start-color: darken(@navbar-default-bg, 5%); @end-color: darken(@navbar-default-bg, 2%));\n    .box-shadow(inset 0 3px 9px rgba(0,0,0,.075));\n  }\n}\n.navbar-brand,\n.navbar-nav > li > a {\n  text-shadow: 0 1px 0 rgba(255,255,255,.25);\n}\n\n// Inverted navbar\n.navbar-inverse {\n  #gradient > .vertical(@start-color: lighten(@navbar-inverse-bg, 10%); @end-color: @navbar-inverse-bg);\n  .reset-filter(); // Remove gradient in IE<10 to fix bug where dropdowns don't get triggered\n\n  .navbar-nav > .active > a {\n    #gradient > .vertical(@start-color: @navbar-inverse-bg; @end-color: lighten(@navbar-inverse-bg, 2.5%));\n    .box-shadow(inset 0 3px 9px rgba(0,0,0,.25));\n  }\n\n  .navbar-brand,\n  .navbar-nav > li > a {\n    text-shadow: 0 -1px 0 rgba(0,0,0,.25);\n  }\n}\n\n// Undo rounded corners in static and fixed navbars\n.navbar-static-top,\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  border-radius: 0;\n}\n\n\n\n//\n// Alerts\n// --------------------------------------------------\n\n// Common styles\n.alert {\n  text-shadow: 0 1px 0 rgba(255,255,255,.2);\n  @shadow: inset 0 1px 0 rgba(255,255,255,.25), 0 1px 2px rgba(0,0,0,.05);\n  .box-shadow(@shadow);\n}\n\n// Mixin for generating new styles\n.alert-styles(@color) {\n  #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 7.5%));\n  border-color: darken(@color, 15%);\n}\n\n// Apply the mixin to the alerts\n.alert-success    { .alert-styles(@alert-success-bg); }\n.alert-info       { .alert-styles(@alert-info-bg); }\n.alert-warning    { .alert-styles(@alert-warning-bg); }\n.alert-danger     { .alert-styles(@alert-danger-bg); }\n\n\n\n//\n// Progress bars\n// --------------------------------------------------\n\n// Give the progress background some depth\n.progress {\n  #gradient > .vertical(@start-color: darken(@progress-bg, 4%); @end-color: @progress-bg)\n}\n\n// Mixin for generating new styles\n.progress-bar-styles(@color) {\n  #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 10%));\n}\n\n// Apply the mixin to the progress bars\n.progress-bar            { .progress-bar-styles(@progress-bar-bg); }\n.progress-bar-success    { .progress-bar-styles(@progress-bar-success-bg); }\n.progress-bar-info       { .progress-bar-styles(@progress-bar-info-bg); }\n.progress-bar-warning    { .progress-bar-styles(@progress-bar-warning-bg); }\n.progress-bar-danger     { .progress-bar-styles(@progress-bar-danger-bg); }\n\n\n\n//\n// List groups\n// --------------------------------------------------\n\n.list-group {\n  border-radius: @border-radius-base;\n  .box-shadow(0 1px 2px rgba(0,0,0,.075));\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  text-shadow: 0 -1px 0 darken(@list-group-active-bg, 10%);\n  #gradient > .vertical(@start-color: @list-group-active-bg; @end-color: darken(@list-group-active-bg, 7.5%));\n  border-color: darken(@list-group-active-border, 7.5%);\n}\n\n\n\n//\n// Panels\n// --------------------------------------------------\n\n// Common styles\n.panel {\n  .box-shadow(0 1px 2px rgba(0,0,0,.05));\n}\n\n// Mixin for generating new styles\n.panel-heading-styles(@color) {\n  #gradient > .vertical(@start-color: @color; @end-color: darken(@color, 5%));\n}\n\n// Apply the mixin to the panel headings only\n.panel-default > .panel-heading   { .panel-heading-styles(@panel-default-heading-bg); }\n.panel-primary > .panel-heading   { .panel-heading-styles(@panel-primary-heading-bg); }\n.panel-success > .panel-heading   { .panel-heading-styles(@panel-success-heading-bg); }\n.panel-info > .panel-heading      { .panel-heading-styles(@panel-info-heading-bg); }\n.panel-warning > .panel-heading   { .panel-heading-styles(@panel-warning-heading-bg); }\n.panel-danger > .panel-heading    { .panel-heading-styles(@panel-danger-heading-bg); }\n\n\n\n//\n// Wells\n// --------------------------------------------------\n\n.well {\n  #gradient > .vertical(@start-color: darken(@well-bg, 5%); @end-color: @well-bg);\n  border-color: darken(@well-bg, 10%);\n  @shadow: inset 0 1px 3px rgba(0,0,0,.05), 0 1px 0 rgba(255,255,255,.1);\n  .box-shadow(@shadow);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/thumbnails.less",
    "content": "//\n// Thumbnails\n// --------------------------------------------------\n\n\n// Mixin and adjust the regular image class\n.thumbnail {\n  display: block;\n  padding: @thumbnail-padding;\n  margin-bottom: @line-height-computed;\n  line-height: @line-height-base;\n  background-color: @thumbnail-bg;\n  border: 1px solid @thumbnail-border;\n  border-radius: @thumbnail-border-radius;\n  .transition(all .2s ease-in-out);\n\n  > img,\n  a > img {\n    .img-responsive();\n    margin-left: auto;\n    margin-right: auto;\n  }\n\n  // Add a hover state for linked versions only\n  a&:hover,\n  a&:focus,\n  a&.active {\n    border-color: @link-color;\n  }\n\n  // Image captions\n  .caption {\n    padding: @thumbnail-caption-padding;\n    color: @thumbnail-caption-color;\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/tooltip.less",
    "content": "//\n// Tooltips\n// --------------------------------------------------\n\n\n// Base class\n.tooltip {\n  position: absolute;\n  z-index: @zindex-tooltip;\n  display: block;\n  visibility: visible;\n  font-size: @font-size-small;\n  line-height: 1.4;\n  .opacity(0);\n\n  &.in     { .opacity(.9); }\n  &.top    { margin-top:  -3px; padding: @tooltip-arrow-width 0; }\n  &.right  { margin-left:  3px; padding: 0 @tooltip-arrow-width; }\n  &.bottom { margin-top:   3px; padding: @tooltip-arrow-width 0; }\n  &.left   { margin-left: -3px; padding: 0 @tooltip-arrow-width; }\n}\n\n// Wrapper for the tooltip content\n.tooltip-inner {\n  max-width: @tooltip-max-width;\n  padding: 3px 8px;\n  color: @tooltip-color;\n  text-align: center;\n  text-decoration: none;\n  background-color: @tooltip-bg;\n  border-radius: @border-radius-base;\n}\n\n// Arrows\n.tooltip-arrow {\n  position: absolute;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.tooltip {\n  &.top .tooltip-arrow {\n    bottom: 0;\n    left: 50%;\n    margin-left: -@tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-top-color: @tooltip-arrow-color;\n  }\n  &.top-left .tooltip-arrow {\n    bottom: 0;\n    left: @tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-top-color: @tooltip-arrow-color;\n  }\n  &.top-right .tooltip-arrow {\n    bottom: 0;\n    right: @tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-top-color: @tooltip-arrow-color;\n  }\n  &.right .tooltip-arrow {\n    top: 50%;\n    left: 0;\n    margin-top: -@tooltip-arrow-width;\n    border-width: @tooltip-arrow-width @tooltip-arrow-width @tooltip-arrow-width 0;\n    border-right-color: @tooltip-arrow-color;\n  }\n  &.left .tooltip-arrow {\n    top: 50%;\n    right: 0;\n    margin-top: -@tooltip-arrow-width;\n    border-width: @tooltip-arrow-width 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-left-color: @tooltip-arrow-color;\n  }\n  &.bottom .tooltip-arrow {\n    top: 0;\n    left: 50%;\n    margin-left: -@tooltip-arrow-width;\n    border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-bottom-color: @tooltip-arrow-color;\n  }\n  &.bottom-left .tooltip-arrow {\n    top: 0;\n    left: @tooltip-arrow-width;\n    border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-bottom-color: @tooltip-arrow-color;\n  }\n  &.bottom-right .tooltip-arrow {\n    top: 0;\n    right: @tooltip-arrow-width;\n    border-width: 0 @tooltip-arrow-width @tooltip-arrow-width;\n    border-bottom-color: @tooltip-arrow-color;\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/type.less",
    "content": "//\n// Typography\n// --------------------------------------------------\n\n\n// Headings\n// -------------------------\n\nh1, h2, h3, h4, h5, h6,\n.h1, .h2, .h3, .h4, .h5, .h6 {\n  font-family: @headings-font-family;\n  font-weight: @headings-font-weight;\n  line-height: @headings-line-height;\n  color: @headings-color;\n\n  small,\n  .small {\n    font-weight: normal;\n    line-height: 1;\n    color: @headings-small-color;\n  }\n}\n\nh1,\nh2,\nh3 {\n  margin-top: @line-height-computed;\n  margin-bottom: (@line-height-computed / 2);\n\n  small,\n  .small {\n    font-size: 65%;\n  }\n}\nh4,\nh5,\nh6 {\n  margin-top: (@line-height-computed / 2);\n  margin-bottom: (@line-height-computed / 2);\n\n  small,\n  .small {\n    font-size: 75%;\n  }\n}\n\nh1, .h1 { font-size: @font-size-h1; }\nh2, .h2 { font-size: @font-size-h2; }\nh3, .h3 { font-size: @font-size-h3; }\nh4, .h4 { font-size: @font-size-h4; }\nh5, .h5 { font-size: @font-size-h5; }\nh6, .h6 { font-size: @font-size-h6; }\n\n\n// Body text\n// -------------------------\n\np {\n  margin: 0 0 (@line-height-computed / 2);\n}\n\n.lead {\n  margin-bottom: @line-height-computed;\n  font-size: floor(@font-size-base * 1.15);\n  font-weight: 200;\n  line-height: 1.4;\n\n  @media (min-width: @screen-sm-min) {\n    font-size: (@font-size-base * 1.5);\n  }\n}\n\n\n// Emphasis & misc\n// -------------------------\n\n// Ex: 14px base font * 85% = about 12px\nsmall,\n.small  { font-size: 85%; }\n\n// Undo browser default styling\ncite    { font-style: normal; }\n\n// Contextual emphasis\n.text-muted {\n  color: @text-muted;\n}\n.text-primary {\n  color: @brand-primary;\n  &:hover {\n    color: darken(@brand-primary, 10%);\n  }\n}\n.text-warning {\n  color: @state-warning-text;\n  &:hover {\n    color: darken(@state-warning-text, 10%);\n  }\n}\n.text-danger {\n  color: @state-danger-text;\n  &:hover {\n    color: darken(@state-danger-text, 10%);\n  }\n}\n.text-success {\n  color: @state-success-text;\n  &:hover {\n    color: darken(@state-success-text, 10%);\n  }\n}\n.text-info {\n  color: @state-info-text;\n  &:hover {\n    color: darken(@state-info-text, 10%);\n  }\n}\n\n// Alignment\n.text-left           { text-align: left; }\n.text-right          { text-align: right; }\n.text-center         { text-align: center; }\n\n\n// Page header\n// -------------------------\n\n.page-header {\n  padding-bottom: ((@line-height-computed / 2) - 1);\n  margin: (@line-height-computed * 2) 0 @line-height-computed;\n  border-bottom: 1px solid @page-header-border-color;\n}\n\n\n// Lists\n// --------------------------------------------------\n\n// Unordered and Ordered lists\nul,\nol {\n  margin-top: 0;\n  margin-bottom: (@line-height-computed / 2);\n  ul,\n  ol {\n    margin-bottom: 0;\n  }\n}\n\n// List options\n\n// Unstyled keeps list items block level, just removes default browser padding and list-style\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n\n// Inline turns list items into inline-block\n.list-inline {\n  .list-unstyled();\n\n  > li {\n    display: inline-block;\n    padding-left: 5px;\n    padding-right: 5px;\n\n    &:first-child {\n      padding-left: 0;\n    }\n  }\n}\n\n// Description Lists\ndl {\n  margin-top: 0; // Remove browser default\n  margin-bottom: @line-height-computed;\n}\ndt,\ndd {\n  line-height: @line-height-base;\n}\ndt {\n  font-weight: bold;\n}\ndd {\n  margin-left: 0; // Undo browser default\n}\n\n// Horizontal description lists\n//\n// Defaults to being stacked without any of the below styles applied, until the\n// grid breakpoint is reached (default of ~768px).\n\n@media (min-width: @grid-float-breakpoint) {\n  .dl-horizontal {\n    dt {\n      float: left;\n      width: (@component-offset-horizontal - 20);\n      clear: left;\n      text-align: right;\n      .text-overflow();\n    }\n    dd {\n      margin-left: @component-offset-horizontal;\n      .clearfix(); // Clear the floated `dt` if an empty `dd` is present\n    }\n  }\n}\n\n// MISC\n// ----\n\n// Abbreviations and acronyms\nabbr[title],\n// Add data-* attribute to help out our tooltip plugin, per https://github.com/twbs/bootstrap/issues/5257\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted @abbr-border-color;\n}\n.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\n\n// Blockquotes\nblockquote {\n  padding: (@line-height-computed / 2) @line-height-computed;\n  margin: 0 0 @line-height-computed;\n  border-left: 5px solid @blockquote-border-color;\n  p {\n    font-size: (@font-size-base * 1.25);\n    font-weight: 300;\n    line-height: 1.25;\n  }\n  p:last-child {\n    margin-bottom: 0;\n  }\n  small,\n  .small {\n    display: block;\n    line-height: @line-height-base;\n    color: @blockquote-small-color;\n    &:before {\n      content: '\\2014 \\00A0'; // EM DASH, NBSP\n    }\n  }\n\n  // Float right with text-align: right\n  &.pull-right {\n    padding-right: 15px;\n    padding-left: 0;\n    border-right: 5px solid @blockquote-border-color;\n    border-left: 0;\n    p,\n    small,\n    .small {\n      text-align: right;\n    }\n    small,\n    .small {\n      &:before {\n        content: '';\n      }\n      &:after {\n        content: '\\00A0 \\2014'; // NBSP, EM DASH\n      }\n    }\n  }\n}\n\n// Quotes\nblockquote:before,\nblockquote:after {\n  content: \"\";\n}\n\n// Addresses\naddress {\n  margin-bottom: @line-height-computed;\n  font-style: normal;\n  line-height: @line-height-base;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/utilities.less",
    "content": "//\n// Utility classes\n// --------------------------------------------------\n\n\n// Floats\n// -------------------------\n\n.clearfix {\n  .clearfix();\n}\n.center-block {\n  .center-block();\n}\n.pull-right {\n  float: right !important;\n}\n.pull-left {\n  float: left !important;\n}\n\n\n// Toggling content\n// -------------------------\n\n// Note: Deprecated .hide in favor of .hidden or .sr-only (as appropriate) in v3.0.1\n.hide {\n  display: none !important;\n}\n.show {\n  display: block !important;\n}\n.invisible {\n  visibility: hidden;\n}\n.text-hide {\n  .text-hide();\n}\n\n\n// Hide from screenreaders and browsers\n//\n// Credit: HTML5 Boilerplate\n\n.hidden {\n  display: none !important;\n  visibility: hidden !important;\n}\n\n\n// For Affix plugin\n// -------------------------\n\n.affix {\n  position: fixed;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/variables.less",
    "content": "//\n// Variables\n// --------------------------------------------------\n\n\n// Global values\n// --------------------------------------------------\n\n// Grays\n// -------------------------\n\n@gray-darker:            lighten(#000, 13.5%); // #222\n@gray-dark:              lighten(#000, 20%);   // #333\n@gray:                   lighten(#000, 33.5%); // #555\n@gray-light:             lighten(#000, 60%);   // #999\n@gray-lighter:           lighten(#000, 93.5%); // #eee\n\n// Brand colors\n// -------------------------\n\n@brand-primary:         #428bca;\n@brand-success:         #5cb85c;\n@brand-warning:         #f0ad4e;\n@brand-danger:          #d9534f;\n@brand-info:            #5bc0de;\n\n// Scaffolding\n// -------------------------\n\n@body-bg:               #fff;\n@text-color:            @gray-dark;\n\n// Links\n// -------------------------\n\n@link-color:            @brand-primary;\n@link-hover-color:      darken(@link-color, 15%);\n\n// Typography\n// -------------------------\n\n@font-family-sans-serif:  \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n@font-family-serif:       Georgia, \"Times New Roman\", Times, serif;\n@font-family-monospace:   Menlo, Monaco, Consolas, \"Courier New\", monospace;\n@font-family-base:        @font-family-sans-serif;\n\n@font-size-base:          14px;\n@font-size-large:         ceil(@font-size-base * 1.25); // ~18px\n@font-size-small:         ceil(@font-size-base * 0.85); // ~12px\n\n@font-size-h1:            floor(@font-size-base * 2.6); // ~36px\n@font-size-h2:            floor(@font-size-base * 2.15); // ~30px\n@font-size-h3:            ceil(@font-size-base * 1.7); // ~24px\n@font-size-h4:            ceil(@font-size-base * 1.25); // ~18px\n@font-size-h5:            @font-size-base;\n@font-size-h6:            ceil(@font-size-base * 0.85); // ~12px\n\n@line-height-base:        1.428571429; // 20/14\n@line-height-computed:    floor(@font-size-base * @line-height-base); // ~20px\n\n@headings-font-family:    @font-family-base;\n@headings-font-weight:    500;\n@headings-line-height:    1.1;\n@headings-color:          inherit;\n\n\n// Iconography\n// -------------------------\n\n@icon-font-path:          \"../fonts/\";\n@icon-font-name:          \"glyphicons-halflings-regular\";\n\n\n// Components\n// -------------------------\n// Based on 14px font-size and 1.428 line-height (~20px to start)\n\n@padding-base-vertical:          6px;\n@padding-base-horizontal:        12px;\n\n@padding-large-vertical:         10px;\n@padding-large-horizontal:       16px;\n\n@padding-small-vertical:         5px;\n@padding-small-horizontal:       10px;\n\n@padding-xs-vertical:            1px;\n@padding-xs-horizontal:          5px;\n\n@line-height-large:              1.33;\n@line-height-small:              1.5;\n\n@border-radius-base:             4px;\n@border-radius-large:            6px;\n@border-radius-small:            3px;\n\n@component-active-color:         #fff;\n@component-active-bg:            @brand-primary;\n\n@caret-width-base:               4px;\n@caret-width-large:              5px;\n\n// Tables\n// -------------------------\n\n@table-cell-padding:                 8px;\n@table-condensed-cell-padding:       5px;\n\n@table-bg:                           transparent; // overall background-color\n@table-bg-accent:                    #f9f9f9; // for striping\n@table-bg-hover:                     #f5f5f5;\n@table-bg-active:                    @table-bg-hover;\n\n@table-border-color:                 #ddd; // table and cell border\n\n\n// Buttons\n// -------------------------\n\n@btn-font-weight:                normal;\n\n@btn-default-color:              #333;\n@btn-default-bg:                 #fff;\n@btn-default-border:             #ccc;\n\n@btn-primary-color:              #fff;\n@btn-primary-bg:                 @brand-primary;\n@btn-primary-border:             darken(@btn-primary-bg, 5%);\n\n@btn-success-color:              #fff;\n@btn-success-bg:                 @brand-success;\n@btn-success-border:             darken(@btn-success-bg, 5%);\n\n@btn-warning-color:              #fff;\n@btn-warning-bg:                 @brand-warning;\n@btn-warning-border:             darken(@btn-warning-bg, 5%);\n\n@btn-danger-color:               #fff;\n@btn-danger-bg:                  @brand-danger;\n@btn-danger-border:              darken(@btn-danger-bg, 5%);\n\n@btn-info-color:                 #fff;\n@btn-info-bg:                    @brand-info;\n@btn-info-border:                darken(@btn-info-bg, 5%);\n\n@btn-link-disabled-color:        @gray-light;\n\n\n// Forms\n// -------------------------\n\n@input-bg:                       #fff;\n@input-bg-disabled:              @gray-lighter;\n\n@input-color:                    @gray;\n@input-border:                   #ccc;\n@input-border-radius:            @border-radius-base;\n@input-border-focus:             #66afe9;\n\n@input-color-placeholder:        @gray-light;\n\n@input-height-base:              (@line-height-computed + (@padding-base-vertical * 2) + 2);\n@input-height-large:             (ceil(@font-size-large * @line-height-large) + (@padding-large-vertical * 2) + 2);\n@input-height-small:             (floor(@font-size-small * @line-height-small) + (@padding-small-vertical * 2) + 2);\n\n@legend-color:                   @gray-dark;\n@legend-border-color:            #e5e5e5;\n\n@input-group-addon-bg:           @gray-lighter;\n@input-group-addon-border-color: @input-border;\n\n\n// Dropdowns\n// -------------------------\n\n@dropdown-bg:                    #fff;\n@dropdown-border:                rgba(0,0,0,.15);\n@dropdown-fallback-border:       #ccc;\n@dropdown-divider-bg:            #e5e5e5;\n\n@dropdown-link-color:            @gray-dark;\n@dropdown-link-hover-color:      darken(@gray-dark, 5%);\n@dropdown-link-hover-bg:         #f5f5f5;\n\n@dropdown-link-active-color:     @component-active-color;\n@dropdown-link-active-bg:        @component-active-bg;\n\n@dropdown-link-disabled-color:   @gray-light;\n\n@dropdown-header-color:          @gray-light;\n\n\n// COMPONENT VARIABLES\n// --------------------------------------------------\n\n\n// Z-index master list\n// -------------------------\n// Used for a bird's eye view of components dependent on the z-axis\n// Try to avoid customizing these :)\n\n@zindex-navbar:            1000;\n@zindex-dropdown:          1000;\n@zindex-popover:           1010;\n@zindex-tooltip:           1030;\n@zindex-navbar-fixed:      1030;\n@zindex-modal-background:  1040;\n@zindex-modal:             1050;\n\n// Media queries breakpoints\n// --------------------------------------------------\n\n// Extra small screen / phone\n// Note: Deprecated @screen-xs and @screen-phone as of v3.0.1\n@screen-xs:                  480px;\n@screen-xs-min:              @screen-xs;\n@screen-phone:               @screen-xs-min;\n\n// Small screen / tablet\n// Note: Deprecated @screen-sm and @screen-tablet as of v3.0.1\n@screen-sm:                  768px;\n@screen-sm-min:              @screen-sm;\n@screen-tablet:              @screen-sm-min;\n\n// Medium screen / desktop\n// Note: Deprecated @screen-md and @screen-desktop as of v3.0.1\n@screen-md:                  992px;\n@screen-md-min:              @screen-md;\n@screen-desktop:             @screen-md-min;\n\n// Large screen / wide desktop\n// Note: Deprecated @screen-lg and @screen-lg-desktop as of v3.0.1\n@screen-lg:                  1200px;\n@screen-lg-min:              @screen-lg;\n@screen-lg-desktop:          @screen-lg-min;\n\n// So media queries don't overlap when required, provide a maximum\n@screen-xs-max:              (@screen-sm-min - 1);\n@screen-sm-max:              (@screen-md-min - 1);\n@screen-md-max:              (@screen-lg-min - 1);\n\n\n// Grid system\n// --------------------------------------------------\n\n// Number of columns in the grid system\n@grid-columns:              12;\n// Padding, to be divided by two and applied to the left and right of all columns\n@grid-gutter-width:         30px;\n\n// Navbar collapse\n\n// Point at which the navbar becomes uncollapsed\n@grid-float-breakpoint:     @screen-sm-min;\n// Point at which the navbar begins collapsing\n@grid-float-breakpoint-max: (@grid-float-breakpoint - 1);\n\n\n// Navbar\n// -------------------------\n\n// Basics of a navbar\n@navbar-height:                    50px;\n@navbar-margin-bottom:             @line-height-computed;\n@navbar-border-radius:             @border-radius-base;\n@navbar-padding-horizontal:        floor(@grid-gutter-width / 2);\n@navbar-padding-vertical:          ((@navbar-height - @line-height-computed) / 2);\n\n@navbar-default-color:             #777;\n@navbar-default-bg:                #f8f8f8;\n@navbar-default-border:            darken(@navbar-default-bg, 6.5%);\n\n// Navbar links\n@navbar-default-link-color:                #777;\n@navbar-default-link-hover-color:          #333;\n@navbar-default-link-hover-bg:             transparent;\n@navbar-default-link-active-color:         #555;\n@navbar-default-link-active-bg:            darken(@navbar-default-bg, 6.5%);\n@navbar-default-link-disabled-color:       #ccc;\n@navbar-default-link-disabled-bg:          transparent;\n\n// Navbar brand label\n@navbar-default-brand-color:               @navbar-default-link-color;\n@navbar-default-brand-hover-color:         darken(@navbar-default-brand-color, 10%);\n@navbar-default-brand-hover-bg:            transparent;\n\n// Navbar toggle\n@navbar-default-toggle-hover-bg:           #ddd;\n@navbar-default-toggle-icon-bar-bg:        #ccc;\n@navbar-default-toggle-border-color:       #ddd;\n\n\n// Inverted navbar\n//\n// Reset inverted navbar basics\n@navbar-inverse-color:                      @gray-light;\n@navbar-inverse-bg:                         #222;\n@navbar-inverse-border:                     darken(@navbar-inverse-bg, 10%);\n\n// Inverted navbar links\n@navbar-inverse-link-color:                 @gray-light;\n@navbar-inverse-link-hover-color:           #fff;\n@navbar-inverse-link-hover-bg:              transparent;\n@navbar-inverse-link-active-color:          @navbar-inverse-link-hover-color;\n@navbar-inverse-link-active-bg:             darken(@navbar-inverse-bg, 10%);\n@navbar-inverse-link-disabled-color:        #444;\n@navbar-inverse-link-disabled-bg:           transparent;\n\n// Inverted navbar brand label\n@navbar-inverse-brand-color:                @navbar-inverse-link-color;\n@navbar-inverse-brand-hover-color:          #fff;\n@navbar-inverse-brand-hover-bg:             transparent;\n\n// Inverted navbar toggle\n@navbar-inverse-toggle-hover-bg:            #333;\n@navbar-inverse-toggle-icon-bar-bg:         #fff;\n@navbar-inverse-toggle-border-color:        #333;\n\n\n// Navs\n// -------------------------\n\n@nav-link-padding:                          10px 15px;\n@nav-link-hover-bg:                         @gray-lighter;\n\n@nav-disabled-link-color:                   @gray-light;\n@nav-disabled-link-hover-color:             @gray-light;\n\n@nav-open-link-hover-color:                 #fff;\n\n// Tabs\n@nav-tabs-border-color:                     #ddd;\n\n@nav-tabs-link-hover-border-color:          @gray-lighter;\n\n@nav-tabs-active-link-hover-bg:             @body-bg;\n@nav-tabs-active-link-hover-color:          @gray;\n@nav-tabs-active-link-hover-border-color:   #ddd;\n\n@nav-tabs-justified-link-border-color:            #ddd;\n@nav-tabs-justified-active-link-border-color:     @body-bg;\n\n// Pills\n@nav-pills-border-radius:                   @border-radius-base;\n@nav-pills-active-link-hover-bg:            @component-active-bg;\n@nav-pills-active-link-hover-color:         @component-active-color;\n\n\n// Pagination\n// -------------------------\n\n@pagination-bg:                        #fff;\n@pagination-border:                    #ddd;\n\n@pagination-hover-bg:                  @gray-lighter;\n\n@pagination-active-bg:                 @brand-primary;\n@pagination-active-color:              #fff;\n\n@pagination-disabled-color:            @gray-light;\n\n\n// Pager\n// -------------------------\n\n@pager-border-radius:                  15px;\n@pager-disabled-color:                 @gray-light;\n\n\n// Jumbotron\n// -------------------------\n\n@jumbotron-padding:              30px;\n@jumbotron-color:                inherit;\n@jumbotron-bg:                   @gray-lighter;\n@jumbotron-heading-color:        inherit;\n@jumbotron-font-size:            ceil(@font-size-base * 1.5);\n\n\n// Form states and alerts\n// -------------------------\n\n@state-success-text:             #3c763d;\n@state-success-bg:               #dff0d8;\n@state-success-border:           darken(spin(@state-success-bg, -10), 5%);\n\n@state-info-text:                #31708f;\n@state-info-bg:                  #d9edf7;\n@state-info-border:              darken(spin(@state-info-bg, -10), 7%);\n\n@state-warning-text:             #8a6d3b;\n@state-warning-bg:               #fcf8e3;\n@state-warning-border:           darken(spin(@state-warning-bg, -10), 5%);\n\n@state-danger-text:              #a94442;\n@state-danger-bg:                #f2dede;\n@state-danger-border:            darken(spin(@state-danger-bg, -10), 5%);\n\n\n// Tooltips\n// -------------------------\n@tooltip-max-width:           200px;\n@tooltip-color:               #fff;\n@tooltip-bg:                  #000;\n\n@tooltip-arrow-width:         5px;\n@tooltip-arrow-color:         @tooltip-bg;\n\n\n// Popovers\n// -------------------------\n@popover-bg:                          #fff;\n@popover-max-width:                   276px;\n@popover-border-color:                rgba(0,0,0,.2);\n@popover-fallback-border-color:       #ccc;\n\n@popover-title-bg:                    darken(@popover-bg, 3%);\n\n@popover-arrow-width:                 10px;\n@popover-arrow-color:                 #fff;\n\n@popover-arrow-outer-width:           (@popover-arrow-width + 1);\n@popover-arrow-outer-color:           rgba(0,0,0,.25);\n@popover-arrow-outer-fallback-color:  #999;\n\n\n// Labels\n// -------------------------\n\n@label-default-bg:            @gray-light;\n@label-primary-bg:            @brand-primary;\n@label-success-bg:            @brand-success;\n@label-info-bg:               @brand-info;\n@label-warning-bg:            @brand-warning;\n@label-danger-bg:             @brand-danger;\n\n@label-color:                 #fff;\n@label-link-hover-color:      #fff;\n\n\n// Modals\n// -------------------------\n@modal-inner-padding:         20px;\n\n@modal-title-padding:         15px;\n@modal-title-line-height:     @line-height-base;\n\n@modal-content-bg:                             #fff;\n@modal-content-border-color:                   rgba(0,0,0,.2);\n@modal-content-fallback-border-color:          #999;\n\n@modal-backdrop-bg:           #000;\n@modal-header-border-color:   #e5e5e5;\n@modal-footer-border-color:   @modal-header-border-color;\n\n\n// Alerts\n// -------------------------\n@alert-padding:               15px;\n@alert-border-radius:         @border-radius-base;\n@alert-link-font-weight:      bold;\n\n@alert-success-bg:            @state-success-bg;\n@alert-success-text:          @state-success-text;\n@alert-success-border:        @state-success-border;\n\n@alert-info-bg:               @state-info-bg;\n@alert-info-text:             @state-info-text;\n@alert-info-border:           @state-info-border;\n\n@alert-warning-bg:            @state-warning-bg;\n@alert-warning-text:          @state-warning-text;\n@alert-warning-border:        @state-warning-border;\n\n@alert-danger-bg:             @state-danger-bg;\n@alert-danger-text:           @state-danger-text;\n@alert-danger-border:         @state-danger-border;\n\n\n// Progress bars\n// -------------------------\n@progress-bg:                 #f5f5f5;\n@progress-bar-color:          #fff;\n\n@progress-bar-bg:             @brand-primary;\n@progress-bar-success-bg:     @brand-success;\n@progress-bar-warning-bg:     @brand-warning;\n@progress-bar-danger-bg:      @brand-danger;\n@progress-bar-info-bg:        @brand-info;\n\n\n// List group\n// -------------------------\n@list-group-bg:               #fff;\n@list-group-border:           #ddd;\n@list-group-border-radius:    @border-radius-base;\n\n@list-group-hover-bg:         #f5f5f5;\n@list-group-active-color:     @component-active-color;\n@list-group-active-bg:        @component-active-bg;\n@list-group-active-border:    @list-group-active-bg;\n\n@list-group-link-color:          #555;\n@list-group-link-heading-color:  #333;\n\n\n// Panels\n// -------------------------\n@panel-bg:                    #fff;\n@panel-inner-border:          #ddd;\n@panel-border-radius:         @border-radius-base;\n@panel-footer-bg:             #f5f5f5;\n\n@panel-default-text:          @gray-dark;\n@panel-default-border:        #ddd;\n@panel-default-heading-bg:    #f5f5f5;\n\n@panel-primary-text:          #fff;\n@panel-primary-border:        @brand-primary;\n@panel-primary-heading-bg:    @brand-primary;\n\n@panel-success-text:          @state-success-text;\n@panel-success-border:        @state-success-border;\n@panel-success-heading-bg:    @state-success-bg;\n\n@panel-warning-text:          @state-warning-text;\n@panel-warning-border:        @state-warning-border;\n@panel-warning-heading-bg:    @state-warning-bg;\n\n@panel-danger-text:           @state-danger-text;\n@panel-danger-border:         @state-danger-border;\n@panel-danger-heading-bg:     @state-danger-bg;\n\n@panel-info-text:             @state-info-text;\n@panel-info-border:           @state-info-border;\n@panel-info-heading-bg:       @state-info-bg;\n\n\n// Thumbnails\n// -------------------------\n@thumbnail-padding:           4px;\n@thumbnail-bg:                @body-bg;\n@thumbnail-border:            #ddd;\n@thumbnail-border-radius:     @border-radius-base;\n\n@thumbnail-caption-color:     @text-color;\n@thumbnail-caption-padding:   9px;\n\n\n// Wells\n// -------------------------\n@well-bg:                     #f5f5f5;\n\n\n// Badges\n// -------------------------\n@badge-color:                 #fff;\n@badge-link-hover-color:      #fff;\n@badge-bg:                    @gray-light;\n\n@badge-active-color:          @link-color;\n@badge-active-bg:             #fff;\n\n@badge-font-weight:           bold;\n@badge-line-height:           1;\n@badge-border-radius:         10px;\n\n\n// Breadcrumbs\n// -------------------------\n@breadcrumb-bg:               #f5f5f5;\n@breadcrumb-color:            #ccc;\n@breadcrumb-active-color:     @gray-light;\n@breadcrumb-separator:        \"/\";\n\n\n// Carousel\n// ------------------------\n\n@carousel-text-shadow:                        0 1px 2px rgba(0,0,0,.6);\n\n@carousel-control-color:                      #fff;\n@carousel-control-width:                      15%;\n@carousel-control-opacity:                    .5;\n@carousel-control-font-size:                  20px;\n\n@carousel-indicator-active-bg:                #fff;\n@carousel-indicator-border-color:             #fff;\n\n@carousel-caption-color:                      #fff;\n\n\n// Close\n// ------------------------\n@close-font-weight:           bold;\n@close-color:                 #000;\n@close-text-shadow:           0 1px 0 #fff;\n\n\n// Code\n// ------------------------\n@code-color:                  #c7254e;\n@code-bg:                     #f9f2f4;\n\n@pre-bg:                      #f5f5f5;\n@pre-color:                   @gray-dark;\n@pre-border-color:            #ccc;\n@pre-scrollable-max-height:   340px;\n\n// Type\n// ------------------------\n@text-muted:                  @gray-light;\n@abbr-border-color:           @gray-light;\n@headings-small-color:        @gray-light;\n@blockquote-small-color:      @gray-light;\n@blockquote-border-color:     @gray-lighter;\n@page-header-border-color:    @gray-lighter;\n\n// Miscellaneous\n// -------------------------\n\n// Hr border color\n@hr-border:                   @gray-lighter;\n\n// Horizontal forms & lists\n@component-offset-horizontal: 180px;\n\n\n// Container sizes\n// --------------------------------------------------\n\n// Small screen / tablet\n@container-tablet:             ((720px + @grid-gutter-width));\n@container-sm:                 @container-tablet;\n\n// Medium screen / desktop\n@container-desktop:            ((940px + @grid-gutter-width));\n@container-md:                 @container-desktop;\n\n// Large screen / wide desktop\n@container-large-desktop:      ((1140px + @grid-gutter-width));\n@container-lg:                 @container-large-desktop;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/bootstrap/less/wells.less",
    "content": "//\n// Wells\n// --------------------------------------------------\n\n\n// Base class\n.well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: @well-bg;\n  border: 1px solid darken(@well-bg, 7%);\n  border-radius: @border-radius-base;\n  .box-shadow(inset 0 1px 1px rgba(0,0,0,.05));\n  blockquote {\n    border-color: #ddd;\n    border-color: rgba(0,0,0,.15);\n  }\n}\n\n// Sizes\n.well-lg {\n  padding: 24px;\n  border-radius: @border-radius-large;\n}\n.well-sm {\n  padding: 9px;\n  border-radius: @border-radius-small;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/.bower.json",
    "content": "{\n  \"name\": \"jquery\",\n  \"version\": \"1.11.1\",\n  \"main\": \"dist/jquery.js\",\n  \"license\": \"MIT\",\n  \"ignore\": [\n    \"**/.*\",\n    \"build\",\n    \"speed\",\n    \"test\",\n    \"*.md\",\n    \"AUTHORS.txt\",\n    \"Gruntfile.js\",\n    \"package.json\"\n  ],\n  \"devDependencies\": {\n    \"sizzle\": \"1.10.19\",\n    \"requirejs\": \"2.1.10\",\n    \"qunit\": \"1.14.0\",\n    \"sinon\": \"1.8.1\"\n  },\n  \"keywords\": [\n    \"jquery\",\n    \"javascript\",\n    \"library\"\n  ],\n  \"homepage\": \"https://github.com/jquery/jquery\",\n  \"_release\": \"1.11.1\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"1.11.1\",\n    \"commit\": \"0d5ec2d8ac94a419ee47a39319c43ff9a7326b50\"\n  },\n  \"_source\": \"git://github.com/jquery/jquery.git\",\n  \"_target\": \"1.11.1\",\n  \"_originalSource\": \"jquery\"\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/MIT-LICENSE.txt",
    "content": "Copyright 2014 jQuery Foundation and other contributors\nhttp://jquery.com/\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/bower.json",
    "content": "{\n  \"name\": \"jquery\",\n  \"version\": \"1.11.1\",\n  \"main\": \"dist/jquery.js\",\n  \"license\": \"MIT\",\n  \"ignore\": [\n    \"**/.*\",\n    \"build\",\n    \"speed\",\n    \"test\",\n    \"*.md\",\n    \"AUTHORS.txt\",\n    \"Gruntfile.js\",\n    \"package.json\"\n  ],\n  \"devDependencies\": {\n    \"sizzle\": \"1.10.19\",\n    \"requirejs\": \"2.1.10\",\n    \"qunit\": \"1.14.0\",\n    \"sinon\": \"1.8.1\"\n  },\n  \"keywords\": [\n    \"jquery\",\n    \"javascript\",\n    \"library\"\n  ]\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/dist/jquery.js",
    "content": "/*!\n * jQuery JavaScript Library v1.11.1\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2014-05-01T17:42Z\n */\n\n(function( global, factory ) {\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n}(typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\nvar deletedIds = [];\n\nvar slice = deletedIds.slice;\n\nvar concat = deletedIds.concat;\n\nvar push = deletedIds.push;\n\nvar indexOf = deletedIds.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar support = {};\n\n\n\nvar\n\tversion = \"1.11.1\",\n\tjQuery = function( selector, context ) {\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([\\da-z])/gi,\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\n\njQuery.fn = jQuery.prototype = {\n\tjquery: version,\n\n\tconstructor: jQuery,\n\tselector: \"\",\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\tget: function( num ) {\n\t\treturn num != null ?\n\t\t\t( num < 0 ? this[ num + this.length ] : this[ num ] ) :\n\t\t\tslice.call( this );\n\t},\n\tpushStack: function( elems ) {\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\t\tret.prevObject = this;\n\t\tret.context = this.context;\n\t\treturn ret;\n\t},\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\tpush: push,\n\tsort: deletedIds.sort,\n\tsplice: deletedIds.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar src, copyIsArray, copy, name, options, clone,\n\t\ttarget = arguments[0] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\tif ( (options = arguments[ i ]) != null ) {\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn target;\n};\n\njQuery.extend({\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray || function( obj ) {\n\t\treturn jQuery.type(obj) === \"array\";\n\t},\n\n\tisWindow: function( obj ) {\n\t\t/* jshint eqeqeq: false */\n\t\treturn obj != null && obj == obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\t\treturn !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\tvar key;\n\t\tif ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\tif ( obj.constructor &&\n\t\t\t\t!hasOwn.call(obj, \"constructor\") &&\n\t\t\t\t!hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\treturn false;\n\t\t}\n\t\tif ( support.ownLast ) {\n\t\t\tfor ( key in obj ) {\n\t\t\t\treturn hasOwn.call( obj, key );\n\t\t\t}\n\t\t}\n\t\tfor ( key in obj ) {}\n\n\t\treturn key === undefined || hasOwn.call( obj, key );\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn obj + \"\";\n\t\t}\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ toString.call(obj) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\tglobalEval: function( data ) {\n\t\tif ( data && jQuery.trim( data ) ) {\n\t\t\t( window.execScript || function( data ) {\n\t\t\t\twindow[ \"eval\" ].call( window, data );\n\t\t\t} )( data );\n\t\t}\n\t},\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\teach: function( obj, callback, args ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = obj.length,\n\t\t\tisArray = isArraylike( obj );\n\n\t\tif ( args ) {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArraylike( Object(arr) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\tvar len;\n\n\t\tif ( arr ) {\n\t\t\tif ( indexOf ) {\n\t\t\t\treturn indexOf.call( arr, elem, i );\n\t\t\t}\n\n\t\t\tlen = arr.length;\n\t\t\ti = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tif ( i in arr && arr[ i ] === elem ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn -1;\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\twhile ( j < len ) {\n\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t}\n\t\tif ( len !== len ) {\n\t\t\twhile ( second[j] !== undefined ) {\n\t\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t\t}\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\tmap: function( elems, callback, arg ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tisArray = isArraylike( elems ),\n\t\t\tret = [];\n\t\tif ( isArray ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn concat.apply( [], ret );\n\t},\n\tguid: 1,\n\tproxy: function( fn, context ) {\n\t\tvar args, proxy, tmp;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\t\targs = slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t\t};\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\tnow: function() {\n\t\treturn +( new Date() );\n\t},\n\tsupport: support\n});\njQuery.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\nfunction isArraylike( obj ) {\n\tvar length = obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( type === \"function\" || jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\tif ( obj.nodeType === 1 && length ) {\n\t\treturn true;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v1.10.19\n * http://sizzlejs.com/\n *\n * Copyright 2013 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2014-04-18\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\texpando = \"sizzle\" + -(new Date()),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\tstrundefined = typeof undefined,\n\tMAX_NEGATIVE = 1 << 31,\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\tindexOf = arr.indexOf || function( elem ) {\n\t\tvar i = 0,\n\t\t\tlen = this.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( this[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\tcharacterEncoding = \"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",\n\tidentifier = characterEncoding.replace( \"w\", \"w#\" ),\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")(?:\" + whitespace +\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + characterEncoding + \")(?:\\\\((\" +\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\trescape = /'|\\\\/g,\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t};\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar match, elem, m, nodeType,\n\t\ti, groups, old, nid, newContext, newSelector;\n\n\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\n\tcontext = context || document;\n\tresults = results || [];\n\n\tif ( !selector || typeof selector !== \"string\" ) {\n\t\treturn results;\n\t}\n\n\tif ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {\n\t\treturn [];\n\t}\n\n\tif ( documentIsHTML && !seed ) {\n\t\tif ( (match = rquickExpr.exec( selector )) ) {\n\t\t\tif ( (m = match[1]) ) {\n\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\telem = context.getElementById( m );\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n\t\t\t\t\t\tcontains( context, elem ) && elem.id === m ) {\n\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if ( match[2] ) {\n\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\treturn results;\n\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {\n\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\treturn results;\n\t\t\t}\n\t\t}\n\t\tif ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\t\t\tnid = old = expando;\n\t\t\tnewContext = context;\n\t\t\tnewSelector = nodeType === 9 && selector;\n\t\t\tif ( nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n\t\t\t\tgroups = tokenize( selector );\n\n\t\t\t\tif ( (old = context.getAttribute(\"id\")) ) {\n\t\t\t\t\tnid = old.replace( rescape, \"\\\\$&\" );\n\t\t\t\t} else {\n\t\t\t\t\tcontext.setAttribute( \"id\", nid );\n\t\t\t\t}\n\t\t\t\tnid = \"[id='\" + nid + \"'] \";\n\n\t\t\t\ti = groups.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tgroups[i] = nid + toSelector( groups[i] );\n\t\t\t\t}\n\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;\n\t\t\t\tnewSelector = groups.join(\",\");\n\t\t\t}\n\n\t\t\tif ( newSelector ) {\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch(qsaError) {\n\t\t\t\t} finally {\n\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\tcontext.removeAttribute(\"id\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\nfunction assert( fn ) {\n\tvar div = document.createElement(\"div\");\n\n\ttry {\n\t\treturn !!fn( div );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\tif ( div.parentNode ) {\n\t\t\tdiv.parentNode.removeChild( div );\n\t\t}\n\t\tdiv = null;\n\t}\n}\n\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = attrs.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\t( ~b.sourceIndex || MAX_NEGATIVE ) -\n\t\t\t( ~a.sourceIndex || MAX_NEGATIVE );\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== strundefined && context;\n}\nsupport = Sizzle.support = {};\n\nisXML = Sizzle.isXML = function( elem ) {\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc,\n\t\tparent = doc.defaultView;\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\tdocument = doc;\n\tdocElem = doc.documentElement;\n\tdocumentIsHTML = !isXML( doc );\n\tif ( parent && parent !== parent.top ) {\n\t\tif ( parent.addEventListener ) {\n\t\t\tparent.addEventListener( \"unload\", function() {\n\t\t\t\tsetDocument();\n\t\t\t}, false );\n\t\t} else if ( parent.attachEvent ) {\n\t\t\tparent.attachEvent( \"onunload\", function() {\n\t\t\t\tsetDocument();\n\t\t\t});\n\t\t}\n\t}\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\tsupport.attributes = assert(function( div ) {\n\t\tdiv.className = \"i\";\n\t\treturn !div.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\tsupport.getElementsByTagName = assert(function( div ) {\n\t\tdiv.appendChild( doc.createComment(\"\") );\n\t\treturn !div.getElementsByTagName(\"*\").length;\n\t});\n\tsupport.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {\n\t\tdiv.innerHTML = \"<div class='a'></div><div class='a i'></div>\";\n\t\tdiv.firstChild.className = \"i\";\n\t\treturn div.getElementsByClassName(\"i\").length === 2;\n\t});\n\tsupport.getById = assert(function( div ) {\n\t\tdocElem.appendChild( div ).id = expando;\n\t\treturn !doc.getElementsByName || !doc.getElementsByName( expando ).length;\n\t});\n\tif ( support.getById ) {\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== strundefined && documentIsHTML ) {\n\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\treturn m && m.parentNode ? [ m ] : [];\n\t\t\t}\n\t\t};\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t} else {\n\t\tdelete Expr.find[\"ID\"];\n\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\t}\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== strundefined ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\t\t\t}\n\t\t} :\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\trbuggyMatches = [];\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {\n\t\tassert(function( div ) {\n\t\t\tdiv.innerHTML = \"<select msallowclip=''><option selected=''></option></select>\";\n\t\t\tif ( div.querySelectorAll(\"[msallowclip^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\t\t\tif ( !div.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\t\t\tif ( !div.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( div ) {\n\t\t\tvar input = doc.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tdiv.appendChild( input ).setAttribute( \"name\", \"D\" );\n\t\t\tif ( div.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\t\t\tif ( !div.querySelectorAll(\":enabled\").length ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\t\t\tdiv.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( div ) {\n\t\t\tsupport.disconnectedMatch = matches.call( div, \"div\" );\n\t\t\tmatches.call( div, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\t\t\t1;\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\t\t\tif ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === doc ? -1 :\n\t\t\t\tb === doc ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn doc;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch(e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\tsortInput = null;\n\n\treturn results;\n};\n\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, outerCache, node, diff, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType;\n\n\t\t\t\t\tif ( parent ) {\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\t\t\t\t\t\tif ( forward && useCache ) {\n\t\t\t\t\t\t\touterCache = parent[ expando ] || (parent[ expando ] = {});\n\t\t\t\t\t\t\tcache = outerCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[0] === dirruns && cache[1];\n\t\t\t\t\t\t\tdiff = cache[0] === dirruns && cache[2];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\touterCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {\n\t\t\t\t\t\t\tdiff = cache[1];\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\tif ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {\n\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf.call( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\t\t\"enabled\": function( elem ) {\n\t\t\treturn elem.disabled === false;\n\t\t},\n\n\t\t\"disabled\": function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\t\"checked\": function( elem ) {\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\t\t\"empty\": function( elem ) {\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tcheckNonElements = base && dir === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\t\t\t\t\t\tif ( (oldCache = outerCache[ dir ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\touterCache[ dir ] = newCache;\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\t\t\t\t\t[] :\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf.call( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\treturn ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context !== document && context;\n\t\t\t}\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tmatchedCount += i;\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\t\t\t\tpush.apply( results, setMatched );\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\tif ( match.length === 1 ) {\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tsupport.getById && context.nodeType === 9 && documentIsHTML &&\n\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\trsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\nsupport.detectDuplicates = !!hasDuplicate;\nsetDocument();\nsupport.sortDetached = assert(function( div1 ) {\n\treturn div1.compareDocumentPosition( document.createElement(\"div\") ) & 1;\n});\nif ( !assert(function( div ) {\n\tdiv.innerHTML = \"<a href='#'></a>\";\n\treturn div.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\nif ( !support.attributes || !assert(function( div ) {\n\tdiv.innerHTML = \"<input/>\";\n\tdiv.firstChild.setAttribute( \"value\", \"\" );\n\treturn div.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\nif ( !assert(function( div ) {\n\treturn div.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\nvar rsingleTag = (/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/);\n\n\n\nvar risSimple = /^.[^:#\\[\\.,]*$/;\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\t/* jshint -W018 */\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t});\n\n\t}\n\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t});\n\n\t}\n\n\tif ( typeof qualifier === \"string\" ) {\n\t\tif ( risSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter( qualifier, elements, not );\n\t\t}\n\n\t\tqualifier = jQuery.filter( qualifier, elements );\n\t}\n\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;\n\t});\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\treturn elems.length === 1 && elem.nodeType === 1 ?\n\t\tjQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n\t\tjQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t}));\n};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar i,\n\t\t\tret = [],\n\t\t\tself = this,\n\t\t\tlen = self.length;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter(function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}) );\n\t\t}\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\t\tret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );\n\t\tret.selector = this.selector ? this.selector + \" \" + selector : selector;\n\t\treturn ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], false) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], true) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n});\nvar rootjQuery,\n\tdocument = window.document,\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,\n\n\tinit = jQuery.fn.init = function( selector, context ) {\n\t\tvar match, elem;\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\t\t\tif ( match && (match[1] || !context) ) {\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[1],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\t\t\t\t\tif ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\tif ( elem.id !== match[2] ) {\n\t\t\t\t\t\t\treturn rootjQuery.find( selector );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || rootjQuery ).find( selector );\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn typeof rootjQuery.ready !== \"undefined\" ?\n\t\t\t\trootjQuery.ready( selector ) :\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\tif ( selector.selector !== undefined ) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\ninit.prototype = jQuery.fn;\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.extend({\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\tcur = elem[ dir ];\n\n\t\twhile ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n\t\t\tif ( cur.nodeType === 1 ) {\n\t\t\t\tmatched.push( cur );\n\t\t\t}\n\t\t\tcur = cur[dir];\n\t\t}\n\t\treturn matched;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar r = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tr.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn r;\n\t}\n});\n\njQuery.fn.extend({\n\thas: function( target ) {\n\t\tvar i,\n\t\t\ttargets = jQuery( target, this ),\n\t\t\tlen = targets.length;\n\n\t\treturn this.filter(function() {\n\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\tpos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tfor ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {\n\t\t\t\tif ( cur.nodeType < 11 && (pos ?\n\t\t\t\t\tpos.index(cur) > -1 :\n\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\tjQuery.find.matchesSelector(cur, selectors)) ) {\n\n\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );\n\t},\n\tindex: function( elem ) {\n\t\tif ( !elem ) {\n\t\t\treturn ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn jQuery.inArray( this[0], jQuery( elem ) );\n\t\t}\n\t\treturn jQuery.inArray(\n\t\t\telem.jquery ? elem[0] : elem, this );\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.unique(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter(selector)\n\t\t);\n\t}\n});\n\nfunction sibling( cur, dir ) {\n\tdo {\n\t\tcur = cur[ dir ];\n\t} while ( cur && cur.nodeType !== 1 );\n\n\treturn cur;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn jQuery.nodeName( elem, \"iframe\" ) ?\n\t\t\telem.contentDocument || elem.contentWindow.document :\n\t\t\tjQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar ret = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tret = jQuery.filter( selector, ret );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tret = jQuery.unique( ret );\n\t\t\t}\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tret = ret.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\nvar rnotwhite = (/\\S+/g);\nvar optionsCache = {};\nfunction createOptions( options ) {\n\tvar object = optionsCache[ options ] = {};\n\tjQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t});\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\toptions = typeof options === \"string\" ?\n\t\t( optionsCache[ options ] || createOptions( options ) ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\t\tmemory,\n\t\tfired,\n\t\tfiringLength,\n\t\tfiringIndex,\n\t\tfiringStart,\n\t\tlist = [],\n\t\tstack = !options.once && [],\n\t\tfire = function( data ) {\n\t\t\tmemory = options.memory && data;\n\t\t\tfired = true;\n\t\t\tfiringIndex = firingStart || 0;\n\t\t\tfiringStart = 0;\n\t\t\tfiringLength = list.length;\n\t\t\tfiring = true;\n\t\t\tfor ( ; list && firingIndex < firingLength; firingIndex++ ) {\n\t\t\t\tif ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n\t\t\t\t\tmemory = false; // To prevent further calls using add\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfiring = false;\n\t\t\tif ( list ) {\n\t\t\t\tif ( stack ) {\n\t\t\t\t\tif ( stack.length ) {\n\t\t\t\t\t\tfire( stack.shift() );\n\t\t\t\t\t}\n\t\t\t\t} else if ( memory ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t} else {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tself = {\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tvar start = list.length;\n\t\t\t\t\t(function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tvar type = jQuery.type( arg );\n\t\t\t\t\t\t\tif ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && type !== \"string\" ) {\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t})( arguments );\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tfiringLength = list.length;\n\t\t\t\t\t} else if ( memory ) {\n\t\t\t\t\t\tfiringStart = start;\n\t\t\t\t\t\tfire( memory );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tremove: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\t\tvar index;\n\t\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\t\tlist.splice( index, 1 );\n\t\t\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\t\t\tif ( index <= firingLength ) {\n\t\t\t\t\t\t\t\t\tfiringLength--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );\n\t\t\t},\n\t\t\tempty: function() {\n\t\t\t\tlist = [];\n\t\t\t\tfiringLength = 0;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisable: function() {\n\t\t\t\tlist = stack = memory = undefined;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\t\t\tlock: function() {\n\t\t\t\tstack = undefined;\n\t\t\t\tif ( !memory ) {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !stack;\n\t\t\t},\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( list && ( !fired || stack ) ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tstack.push( args );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfire( args );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\njQuery.extend({\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tthen: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\t\t\t\t\treturn jQuery.Deferred(function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\t\t\t\t\tvar fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];\n\t\t\t\t\t\t\tdeferred[ tuple[1] ](function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject )\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t}).promise();\n\t\t\t\t},\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\t\tpromise.pipe = promise.then;\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 3 ];\n\t\t\tpromise[ tuple[1] ] = list.add;\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(function() {\n\t\t\t\t\tstate = stateString;\n\t\t\t\t}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n\t\t\t}\n\t\t\tdeferred[ tuple[0] ] = function() {\n\t\t\t\tdeferred[ tuple[0] + \"With\" ]( this === deferred ? promise : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tdeferred[ tuple[0] + \"With\" ] = list.fireWith;\n\t\t});\n\t\tpromise.promise( deferred );\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\t\treturn deferred;\n\t},\n\twhen: function( subordinate /* , ..., subordinateN */ ) {\n\t\tvar i = 0,\n\t\t\tresolveValues = slice.call( arguments ),\n\t\t\tlength = resolveValues.length,\n\t\t\tremaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\t\t\tdeferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\t\t\tupdateFunc = function( i, contexts, values ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tcontexts[ i ] = this;\n\t\t\t\t\tvalues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( values === progressValues ) {\n\t\t\t\t\t\tdeferred.notifyWith( contexts, values );\n\n\t\t\t\t\t} else if ( !(--remaining) ) {\n\t\t\t\t\t\tdeferred.resolveWith( contexts, values );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\t\t\tprogressValues, progressContexts, resolveContexts;\n\t\tif ( length > 1 ) {\n\t\t\tprogressValues = new Array( length );\n\t\t\tprogressContexts = new Array( length );\n\t\t\tresolveContexts = new Array( length );\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n\t\t\t\t\tresolveValues[ i ].promise()\n\t\t\t\t\t\t.done( updateFunc( i, resolveContexts, resolveValues ) )\n\t\t\t\t\t\t.fail( deferred.reject )\n\t\t\t\t\t\t.progress( updateFunc( i, progressContexts, progressValues ) );\n\t\t\t\t} else {\n\t\t\t\t\t--remaining;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif ( !remaining ) {\n\t\t\tdeferred.resolveWith( resolveContexts, resolveValues );\n\t\t}\n\n\t\treturn deferred.promise();\n\t}\n});\nvar readyList;\n\njQuery.fn.ready = function( fn ) {\n\tjQuery.ready.promise().done( fn );\n\n\treturn this;\n};\n\njQuery.extend({\n\tisReady: false,\n\treadyWait: 1,\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\tready: function( wait ) {\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( !document.body ) {\n\t\t\treturn setTimeout( jQuery.ready );\n\t\t}\n\t\tjQuery.isReady = true;\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t\tif ( jQuery.fn.triggerHandler ) {\n\t\t\tjQuery( document ).triggerHandler( \"ready\" );\n\t\t\tjQuery( document ).off( \"ready\" );\n\t\t}\n\t}\n});\n\nfunction detach() {\n\tif ( document.addEventListener ) {\n\t\tdocument.removeEventListener( \"DOMContentLoaded\", completed, false );\n\t\twindow.removeEventListener( \"load\", completed, false );\n\n\t} else {\n\t\tdocument.detachEvent( \"onreadystatechange\", completed );\n\t\twindow.detachEvent( \"onload\", completed );\n\t}\n}\n\nfunction completed() {\n\tif ( document.addEventListener || event.type === \"load\" || document.readyState === \"complete\" ) {\n\t\tdetach();\n\t\tjQuery.ready();\n\t}\n}\n\njQuery.ready.promise = function( obj ) {\n\tif ( !readyList ) {\n\n\t\treadyList = jQuery.Deferred();\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\tsetTimeout( jQuery.ready );\n\t\t} else if ( document.addEventListener ) {\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", completed, false );\n\t\t\twindow.addEventListener( \"load\", completed, false );\n\t\t} else {\n\t\t\tdocument.attachEvent( \"onreadystatechange\", completed );\n\t\t\twindow.attachEvent( \"onload\", completed );\n\t\t\tvar top = false;\n\n\t\t\ttry {\n\t\t\t\ttop = window.frameElement == null && document.documentElement;\n\t\t\t} catch(e) {}\n\n\t\t\tif ( top && top.doScroll ) {\n\t\t\t\t(function doScrollCheck() {\n\t\t\t\t\tif ( !jQuery.isReady ) {\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\ttop.doScroll(\"left\");\n\t\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t\treturn setTimeout( doScrollCheck, 50 );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdetach();\n\t\t\t\t\t\tjQuery.ready();\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t}\n\t\t}\n\t}\n\treturn readyList.promise( obj );\n};\n\n\nvar strundefined = typeof undefined;\nvar i;\nfor ( i in jQuery( support ) ) {\n\tbreak;\n}\nsupport.ownLast = i !== \"0\";\nsupport.inlineBlockNeedsLayout = false;\njQuery(function() {\n\tvar val, div, body, container;\n\n\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\tif ( !body || !body.style ) {\n\t\treturn;\n\t}\n\tdiv = document.createElement( \"div\" );\n\tcontainer = document.createElement( \"div\" );\n\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\tbody.appendChild( container ).appendChild( div );\n\n\tif ( typeof div.style.zoom !== strundefined ) {\n\t\tdiv.style.cssText = \"display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1\";\n\n\t\tsupport.inlineBlockNeedsLayout = val = div.offsetWidth === 3;\n\t\tif ( val ) {\n\t\t\tbody.style.zoom = 1;\n\t\t}\n\t}\n\n\tbody.removeChild( container );\n});\n\n\n\n\n(function() {\n\tvar div = document.createElement( \"div\" );\n\tif (support.deleteExpando == null) {\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n\tdiv = null;\n})();\n\n\njQuery.acceptData = function( elem ) {\n\tvar noData = jQuery.noData[ (elem.nodeName + \" \").toLowerCase() ],\n\t\tnodeType = +elem.nodeType || 1;\n\treturn nodeType !== 1 && nodeType !== 9 ?\n\t\tfalse :\n\t\t!noData || noData !== true && elem.getAttribute(\"classid\") === noData;\n};\n\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /([A-Z])/g;\n\nfunction dataAttr( elem, key, data ) {\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\n\t\tvar name = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\t\tdata === \"false\" ? false :\n\t\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\t\t\tjQuery.data( elem, key, data );\n\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\n\treturn data;\n}\nfunction isEmptyDataObject( obj ) {\n\tvar name;\n\tfor ( name in obj ) {\n\t\tif ( name === \"data\" && jQuery.isEmptyObject( obj[name] ) ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( name !== \"toJSON\" ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nfunction internalData( elem, name, data, pvt /* Internal Use Only */ ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar ret, thisCache,\n\t\tinternalKey = jQuery.expando,\n\t\tisNode = elem.nodeType,\n\t\tcache = isNode ? jQuery.cache : elem,\n\t\tid = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;\n\tif ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === \"string\" ) {\n\t\treturn;\n\t}\n\n\tif ( !id ) {\n\t\tif ( isNode ) {\n\t\t\tid = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;\n\t\t} else {\n\t\t\tid = internalKey;\n\t\t}\n\t}\n\n\tif ( !cache[ id ] ) {\n\t\tcache[ id ] = isNode ? {} : { toJSON: jQuery.noop };\n\t}\n\tif ( typeof name === \"object\" || typeof name === \"function\" ) {\n\t\tif ( pvt ) {\n\t\t\tcache[ id ] = jQuery.extend( cache[ id ], name );\n\t\t} else {\n\t\t\tcache[ id ].data = jQuery.extend( cache[ id ].data, name );\n\t\t}\n\t}\n\n\tthisCache = cache[ id ];\n\tif ( !pvt ) {\n\t\tif ( !thisCache.data ) {\n\t\t\tthisCache.data = {};\n\t\t}\n\n\t\tthisCache = thisCache.data;\n\t}\n\n\tif ( data !== undefined ) {\n\t\tthisCache[ jQuery.camelCase( name ) ] = data;\n\t}\n\tif ( typeof name === \"string\" ) {\n\t\tret = thisCache[ name ];\n\t\tif ( ret == null ) {\n\t\t\tret = thisCache[ jQuery.camelCase( name ) ];\n\t\t}\n\t} else {\n\t\tret = thisCache;\n\t}\n\n\treturn ret;\n}\n\nfunction internalRemoveData( elem, name, pvt ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar thisCache, i,\n\t\tisNode = elem.nodeType,\n\t\tcache = isNode ? jQuery.cache : elem,\n\t\tid = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\tif ( !cache[ id ] ) {\n\t\treturn;\n\t}\n\n\tif ( name ) {\n\n\t\tthisCache = pvt ? cache[ id ] : cache[ id ].data;\n\n\t\tif ( thisCache ) {\n\t\t\tif ( !jQuery.isArray( name ) ) {\n\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\tname = [ name ];\n\t\t\t\t} else {\n\t\t\t\t\tname = jQuery.camelCase( name );\n\t\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\t\tname = [ name ];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tname = name.split(\" \");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tname = name.concat( jQuery.map( name, jQuery.camelCase ) );\n\t\t\t}\n\n\t\t\ti = name.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete thisCache[ name[i] ];\n\t\t\t}\n\t\t\tif ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\tif ( !pvt ) {\n\t\tdelete cache[ id ].data;\n\t\tif ( !isEmptyDataObject( cache[ id ] ) ) {\n\t\t\treturn;\n\t\t}\n\t}\n\tif ( isNode ) {\n\t\tjQuery.cleanData( [ elem ], true );\n\t/* jshint eqeqeq: false */\n\t} else if ( support.deleteExpando || cache != cache.window ) {\n\t\t/* jshint eqeqeq: true */\n\t\tdelete cache[ id ];\n\t} else {\n\t\tcache[ id ] = null;\n\t}\n}\n\njQuery.extend({\n\tcache: {},\n\tnoData: {\n\t\t\"applet \": true,\n\t\t\"embed \": true,\n\t\t\"object \": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n\t},\n\n\thasData: function( elem ) {\n\t\telem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n\t\treturn !!elem && !isEmptyDataObject( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name );\n\t},\n\t_data: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data, true );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name, true );\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[0],\n\t\t\tattrs = elem && elem.attributes;\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = jQuery.data( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !jQuery._data( elem, \"parsedAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice(5) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tjQuery._data( elem, \"parsedAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery.data( this, key );\n\t\t\t});\n\t\t}\n\n\t\treturn arguments.length > 1 ?\n\t\t\tthis.each(function() {\n\t\t\t\tjQuery.data( this, key, value );\n\t\t\t}) :\n\t\t\telem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeData( this, key );\n\t\t});\n\t}\n});\n\n\njQuery.extend({\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = jQuery._data( elem, type );\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray(data) ) {\n\t\t\t\t\tqueue = jQuery._data( elem, type, jQuery.makeArray(data) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn jQuery._data( elem, key ) || jQuery._data( elem, key, {\n\t\t\tempty: jQuery.Callbacks(\"once memory\").add(function() {\n\t\t\t\tjQuery._removeData( elem, type + \"queue\" );\n\t\t\t\tjQuery._removeData( elem, key );\n\t\t\t})\n\t\t});\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = jQuery._data( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n});\nvar pnum = (/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/).source;\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar isHidden = function( elem, el ) {\n\t\telem = el || elem;\n\t\treturn jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n\t};\nvar access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlength = elems.length,\n\t\tbulk = key == null;\n\tif ( jQuery.type( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\tjQuery.access( elems, fn, i, key[i], true, emptyGet, raw );\n\t\t}\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tfn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn chainable ?\n\t\telems :\n\t\tbulk ?\n\t\t\tfn.call( elems ) :\n\t\t\tlength ? fn( elems[0], key ) : emptyGet;\n};\nvar rcheckableType = (/^(?:checkbox|radio)$/i);\n\n\n\n(function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tdiv = document.createElement( \"div\" ),\n\t\tfragment = document.createDocumentFragment();\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\tsupport.leadingWhitespace = div.firstChild.nodeType === 3;\n\tsupport.tbody = !div.getElementsByTagName( \"tbody\" ).length;\n\tsupport.htmlSerialize = !!div.getElementsByTagName( \"link\" ).length;\n\tsupport.html5Clone =\n\t\tdocument.createElement( \"nav\" ).cloneNode( true ).outerHTML !== \"<:nav></:nav>\";\n\tinput.type = \"checkbox\";\n\tinput.checked = true;\n\tfragment.appendChild( input );\n\tsupport.appendChecked = input.checked;\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\tfragment.appendChild( div );\n\tdiv.innerHTML = \"<input type='radio' checked='checked' name='t'/>\";\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\tsupport.noCloneEvent = true;\n\tif ( div.attachEvent ) {\n\t\tdiv.attachEvent( \"onclick\", function() {\n\t\t\tsupport.noCloneEvent = false;\n\t\t});\n\n\t\tdiv.cloneNode( true ).click();\n\t}\n\tif (support.deleteExpando == null) {\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n})();\n\n\n(function() {\n\tvar i, eventName,\n\t\tdiv = document.createElement( \"div\" );\n\tfor ( i in { submit: true, change: true, focusin: true }) {\n\t\teventName = \"on\" + i;\n\n\t\tif ( !(support[ i + \"Bubbles\" ] = eventName in window) ) {\n\t\t\tdiv.setAttribute( eventName, \"t\" );\n\t\t\tsupport[ i + \"Bubbles\" ] = div.attributes[ eventName ].expando === false;\n\t\t}\n\t}\n\tdiv = null;\n})();\n\n\nvar rformElems = /^(?:input|select|textarea)$/i,\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,\n\trfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)$/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\t\tvar tmp, events, t, handleObjIn,\n\t\t\tspecial, eventHandle, handleObj,\n\t\t\thandlers, type, namespaces, origType,\n\t\t\telemData = jQuery._data( elem );\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\t\tif ( !(events = elemData.events) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !(eventHandle = elemData.handle) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\t\t\t\treturn typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?\n\t\t\t\t\tjQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n\t\t\t\t\tundefined;\n\t\t\t};\n\t\t\teventHandle.elem = elem;\n\t\t}\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\thandleObj = jQuery.extend({\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join(\".\")\n\t\t\t}, handleObjIn );\n\t\t\tif ( !(handlers = events[ type ]) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\n\t\t\t\t\t} else if ( elem.attachEvent ) {\n\t\t\t\t\t\telem.attachEvent( \"on\" + type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\t\telem = null;\n\t},\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\t\tvar j, handleObj, tmp,\n\t\t\torigCount, t, events,\n\t\t\tspecial, handlers, type,\n\t\t\tnamespaces, origType,\n\t\t\telemData = jQuery.hasData( elem ) && jQuery._data( elem );\n\n\t\tif ( !elemData || !(events = elemData.events) ) {\n\t\t\treturn;\n\t\t}\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[2] && new RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" );\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdelete elemData.handle;\n\t\t\tjQuery._removeData( elem, \"events\" );\n\t\t}\n\t},\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\t\tvar handle, ontype, cur,\n\t\t\tbubbleType, special, tmp, i,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split(\".\") : [];\n\n\t\tcur = tmp = elem = elem || document;\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf(\".\") >= 0 ) {\n\t\t\tnamespaces = type.split(\".\");\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf(\":\") < 0 && \"on\" + type;\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join(\".\");\n\t\tevent.namespace_re = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\t\t\tif ( tmp === (elem.ownerDocument || document) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\t\ti = 0;\n\t\twhile ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\t\t\thandle = ( jQuery._data( cur, \"events\" ) || {} )[ event.type ] && jQuery._data( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && jQuery.acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&\n\t\t\t\tjQuery.acceptData( elem ) ) {\n\t\t\t\tif ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\ttry {\n\t\t\t\t\t\telem[ type ]();\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t}\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\tdispatch: function( event ) {\n\t\tevent = jQuery.event.fix( event );\n\n\t\tvar i, ret, handleObj, matched, j,\n\t\t\thandlerQueue = [],\n\t\t\targs = slice.call( arguments ),\n\t\t\thandlers = ( jQuery._data( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\t\targs[0] = event;\n\t\tevent.delegateTarget = this;\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\t\ti = 0;\n\t\twhile ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {\n\t\t\t\tif ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n\t\t\t\t\t\t\t.apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( (event.result = ret) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar sel, handleObj, matches, i,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\t\tif ( delegateCount && cur.nodeType && (!event.button || event.type !== \"click\") ) {\n\n\t\t\t/* jshint eqeqeq: false */\n\t\t\tfor ( ; cur != this; cur = cur.parentNode || this ) {\n\t\t\t\t/* jshint eqeqeq: true */\n\t\t\t\tif ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== \"click\") ) {\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matches[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatches[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) >= 0 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matches[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push({ elem: cur, handlers: matches });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\t\tvar i, prop, copy,\n\t\t\ttype = event.type,\n\t\t\toriginalEvent = event,\n\t\t\tfixHook = this.fixHooks[ type ];\n\n\t\tif ( !fixHook ) {\n\t\t\tthis.fixHooks[ type ] = fixHook =\n\t\t\t\trmouseEvent.test( type ) ? this.mouseHooks :\n\t\t\t\trkeyEvent.test( type ) ? this.keyHooks :\n\t\t\t\t{};\n\t\t}\n\t\tcopy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n\t\tevent = new jQuery.Event( originalEvent );\n\n\t\ti = copy.length;\n\t\twhile ( i-- ) {\n\t\t\tprop = copy[ i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\t\tif ( !event.target ) {\n\t\t\tevent.target = originalEvent.srcElement || document;\n\t\t}\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\t\tevent.metaKey = !!event.metaKey;\n\n\t\treturn fixHook.filter ? fixHook.filter( event, originalEvent ) : event;\n\t},\n\tprops: \"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n\tfixHooks: {},\n\n\tkeyHooks: {\n\t\tprops: \"char charCode key keyCode\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\t\t\tif ( event.which == null ) {\n\t\t\t\tevent.which = original.charCode != null ? original.charCode : original.keyCode;\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tmouseHooks: {\n\t\tprops: \"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\t\t\tvar body, eventDoc, doc,\n\t\t\t\tbutton = original.button,\n\t\t\t\tfromElement = original.fromElement;\n\t\t\tif ( event.pageX == null && original.clientX != null ) {\n\t\t\t\teventDoc = event.target.ownerDocument || document;\n\t\t\t\tdoc = eventDoc.documentElement;\n\t\t\t\tbody = eventDoc.body;\n\n\t\t\t\tevent.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n\t\t\t\tevent.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );\n\t\t\t}\n\t\t\tif ( !event.relatedTarget && fromElement ) {\n\t\t\t\tevent.relatedTarget = fromElement === event.target ? original.toElement : fromElement;\n\t\t\t}\n\t\t\tif ( !event.which && button !== undefined ) {\n\t\t\t\tevent.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tspecial: {\n\t\tload: {\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.focus();\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( jQuery.nodeName( this, \"input\" ) && this.type === \"checkbox\" && this.click ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\t_default: function( event ) {\n\t\t\t\treturn jQuery.nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tsimulate: function( type, elem, event, bubble ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true,\n\t\t\t\toriginalEvent: {}\n\t\t\t}\n\t\t);\n\t\tif ( bubble ) {\n\t\t\tjQuery.event.trigger( e, null, elem );\n\t\t} else {\n\t\t\tjQuery.event.dispatch.call( elem, e );\n\t\t}\n\t\tif ( e.isDefaultPrevented() ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n};\n\njQuery.removeEvent = document.removeEventListener ?\n\tfunction( elem, type, handle ) {\n\t\tif ( elem.removeEventListener ) {\n\t\t\telem.removeEventListener( type, handle, false );\n\t\t}\n\t} :\n\tfunction( elem, type, handle ) {\n\t\tvar name = \"on\" + type;\n\n\t\tif ( elem.detachEvent ) {\n\t\t\tif ( typeof elem[ name ] === strundefined ) {\n\t\t\t\telem[ name ] = null;\n\t\t\t}\n\n\t\t\telem.detachEvent( name, handle );\n\t\t}\n\t};\n\njQuery.Event = function( src, props ) {\n\tif ( !(this instanceof jQuery.Event) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\t} else {\n\t\tthis.type = src;\n\t}\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\tthis[ jQuery.expando ] = true;\n};\njQuery.Event.prototype = {\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( e.preventDefault ) {\n\t\t\te.preventDefault();\n\t\t} else {\n\t\t\te.returnValue = false;\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( e.stopPropagation ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t\te.cancelBubble = true;\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && e.stopImmediatePropagation ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\njQuery.each({\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\t\t\tif ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n});\nif ( !support.submitBubbles ) {\n\n\tjQuery.event.special.submit = {\n\t\tsetup: function() {\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tjQuery.event.add( this, \"click._submit keypress._submit\", function( e ) {\n\t\t\t\tvar elem = e.target,\n\t\t\t\t\tform = jQuery.nodeName( elem, \"input\" ) || jQuery.nodeName( elem, \"button\" ) ? elem.form : undefined;\n\t\t\t\tif ( form && !jQuery._data( form, \"submitBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( form, \"submit._submit\", function( event ) {\n\t\t\t\t\t\tevent._submit_bubble = true;\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( form, \"submitBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\tpostDispatch: function( event ) {\n\t\t\tif ( event._submit_bubble ) {\n\t\t\t\tdelete event._submit_bubble;\n\t\t\t\tif ( this.parentNode && !event.isTrigger ) {\n\t\t\t\t\tjQuery.event.simulate( \"submit\", this.parentNode, event, true );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tjQuery.event.remove( this, \"._submit\" );\n\t\t}\n\t};\n}\nif ( !support.changeBubbles ) {\n\n\tjQuery.event.special.change = {\n\n\t\tsetup: function() {\n\n\t\t\tif ( rformElems.test( this.nodeName ) ) {\n\t\t\t\tif ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n\t\t\t\t\tjQuery.event.add( this, \"propertychange._change\", function( event ) {\n\t\t\t\t\t\tif ( event.originalEvent.propertyName === \"checked\" ) {\n\t\t\t\t\t\t\tthis._just_changed = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery.event.add( this, \"click._change\", function( event ) {\n\t\t\t\t\t\tif ( this._just_changed && !event.isTrigger ) {\n\t\t\t\t\t\t\tthis._just_changed = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tjQuery.event.simulate( \"change\", this, event, true );\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tjQuery.event.add( this, \"beforeactivate._change\", function( e ) {\n\t\t\t\tvar elem = e.target;\n\n\t\t\t\tif ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, \"changeBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( elem, \"change._change\", function( event ) {\n\t\t\t\t\t\tif ( this.parentNode && !event.isSimulated && !event.isTrigger ) {\n\t\t\t\t\t\t\tjQuery.event.simulate( \"change\", this.parentNode, event, true );\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( elem, \"changeBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\thandle: function( event ) {\n\t\t\tvar elem = event.target;\n\t\t\tif ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== \"radio\" && elem.type !== \"checkbox\") ) {\n\t\t\t\treturn event.handleObj.handler.apply( this, arguments );\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\tjQuery.event.remove( this, \"._change\" );\n\n\t\t\treturn !rformElems.test( this.nodeName );\n\t\t}\n\t};\n}\nif ( !support.focusinBubbles ) {\n\tjQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\t\tvar handler = function( event ) {\n\t\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n\t\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tjQuery._data( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tjQuery._removeData( doc, fix );\n\t\t\t\t} else {\n\t\t\t\t\tjQuery._data( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\njQuery.fn.extend({\n\n\ton: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n\t\tvar type, origFn;\n\t\tif ( typeof types === \"object\" ) {\n\t\t\tif ( typeof selector !== \"string\" ) {\n\t\t\t\tdata = data || selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.on( type, selector, data, types[ type ], one );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( data == null && fn == null ) {\n\t\t\tfn = selector;\n\t\t\tdata = selector = undefined;\n\t\t} else if ( fn == null ) {\n\t\t\tif ( typeof selector === \"string\" ) {\n\t\t\t\tfn = data;\n\t\t\t\tdata = undefined;\n\t\t\t} else {\n\t\t\t\tfn = data;\n\t\t\t\tdata = selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t} else if ( !fn ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( one === 1 ) {\n\t\t\torigFn = fn;\n\t\t\tfn = function( event ) {\n\t\t\t\tjQuery().off( event );\n\t\t\t\treturn origFn.apply( this, arguments );\n\t\t\t};\n\t\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.add( this, types, fn, data, selector );\n\t\t});\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn this.on( types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t});\n\t},\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t});\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[0];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n});\n\n\nfunction createSafeFragment( document ) {\n\tvar list = nodeNames.split( \"|\" ),\n\t\tsafeFrag = document.createDocumentFragment();\n\n\tif ( safeFrag.createElement ) {\n\t\twhile ( list.length ) {\n\t\t\tsafeFrag.createElement(\n\t\t\t\tlist.pop()\n\t\t\t);\n\t\t}\n\t}\n\treturn safeFrag;\n}\n\nvar nodeNames = \"abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|\" +\n\t\t\"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video\",\n\trinlinejQuery = / jQuery\\d+=\"(?:null|\\d+)\"/g,\n\trnoshimcache = new RegExp(\"<(?:\" + nodeNames + \")[\\\\s/>]\", \"i\"),\n\trleadingWhitespace = /^\\s+/,\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n\trtagName = /<([\\w:]+)/,\n\trtbody = /<tbody/i,\n\trhtml = /<|&#?\\w+;/,\n\trnoInnerhtml = /<(?:script|style|link)/i,\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptType = /^$|\\/(?:java|ecma)script/i,\n\trscriptTypeMasked = /^true\\/(.*)/,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,\n\twrapMap = {\n\t\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\t\tlegend: [ 1, \"<fieldset>\", \"</fieldset>\" ],\n\t\tarea: [ 1, \"<map>\", \"</map>\" ],\n\t\tparam: [ 1, \"<object>\", \"</object>\" ],\n\t\tthead: [ 1, \"<table>\", \"</table>\" ],\n\t\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\t\tcol: [ 2, \"<table><tbody></tbody><colgroup>\", \"</colgroup></table>\" ],\n\t\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\t\t_default: support.htmlSerialize ? [ 0, \"\", \"\" ] : [ 1, \"X<div>\", \"</div>\"  ]\n\t},\n\tsafeFragment = createSafeFragment( document ),\n\tfragmentDiv = safeFragment.appendChild( document.createElement(\"div\") );\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\nfunction getAll( context, tag ) {\n\tvar elems, elem,\n\t\ti = 0,\n\t\tfound = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || \"*\" ) :\n\t\t\ttypeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || \"*\" ) :\n\t\t\tundefined;\n\n\tif ( !found ) {\n\t\tfor ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( !tag || jQuery.nodeName( elem, tag ) ) {\n\t\t\t\tfound.push( elem );\n\t\t\t} else {\n\t\t\t\tjQuery.merge( found, getAll( elem, tag ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn tag === undefined || tag && jQuery.nodeName( context, tag ) ?\n\t\tjQuery.merge( [ context ], found ) :\n\t\tfound;\n}\nfunction fixDefaultChecked( elem ) {\n\tif ( rcheckableType.test( elem.type ) ) {\n\t\telem.defaultChecked = elem.checked;\n\t}\n}\nfunction manipulationTarget( elem, content ) {\n\treturn jQuery.nodeName( elem, \"table\" ) &&\n\t\tjQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ?\n\n\t\telem.getElementsByTagName(\"tbody\")[0] ||\n\t\t\telem.appendChild( elem.ownerDocument.createElement(\"tbody\") ) :\n\t\telem;\n}\nfunction disableScript( elem ) {\n\telem.type = (jQuery.find.attr( elem, \"type\" ) !== null) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tvar match = rscriptTypeMasked.exec( elem.type );\n\tif ( match ) {\n\t\telem.type = match[1];\n\t} else {\n\t\telem.removeAttribute(\"type\");\n\t}\n\treturn elem;\n}\nfunction setGlobalEval( elems, refElements ) {\n\tvar elem,\n\t\ti = 0;\n\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\tjQuery._data( elem, \"globalEval\", !refElements || jQuery._data( refElements[i], \"globalEval\" ) );\n\t}\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n\tif ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n\t\treturn;\n\t}\n\n\tvar type, i, l,\n\t\toldData = jQuery._data( src ),\n\t\tcurData = jQuery._data( dest, oldData ),\n\t\tevents = oldData.events;\n\n\tif ( events ) {\n\t\tdelete curData.handle;\n\t\tcurData.events = {};\n\n\t\tfor ( type in events ) {\n\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t}\n\t\t}\n\t}\n\tif ( curData.data ) {\n\t\tcurData.data = jQuery.extend( {}, curData.data );\n\t}\n}\n\nfunction fixCloneNodeIssues( src, dest ) {\n\tvar nodeName, e, data;\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\tnodeName = dest.nodeName.toLowerCase();\n\tif ( !support.noCloneEvent && dest[ jQuery.expando ] ) {\n\t\tdata = jQuery._data( dest );\n\n\t\tfor ( e in data.events ) {\n\t\t\tjQuery.removeEvent( dest, e, data.handle );\n\t\t}\n\t\tdest.removeAttribute( jQuery.expando );\n\t}\n\tif ( nodeName === \"script\" && dest.text !== src.text ) {\n\t\tdisableScript( dest ).text = src.text;\n\t\trestoreScript( dest );\n\t} else if ( nodeName === \"object\" ) {\n\t\tif ( dest.parentNode ) {\n\t\t\tdest.outerHTML = src.outerHTML;\n\t\t}\n\t\tif ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {\n\t\t\tdest.innerHTML = src.innerHTML;\n\t\t}\n\n\t} else if ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\n\t\tdest.defaultChecked = dest.checked = src.checked;\n\t\tif ( dest.value !== src.value ) {\n\t\t\tdest.value = src.value;\n\t\t}\n\t} else if ( nodeName === \"option\" ) {\n\t\tdest.defaultSelected = dest.selected = src.defaultSelected;\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\njQuery.extend({\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar destElements, node, clone, i, srcElements,\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\tif ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( \"<\" + elem.nodeName + \">\" ) ) {\n\t\t\tclone = elem.cloneNode( true );\n\t\t} else {\n\t\t\tfragmentDiv.innerHTML = elem.outerHTML;\n\t\t\tfragmentDiv.removeChild( clone = fragmentDiv.firstChild );\n\t\t}\n\n\t\tif ( (!support.noCloneEvent || !support.noCloneChecked) &&\n\t\t\t\t(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\t\t\tfor ( i = 0; (node = srcElements[i]) != null; ++i ) {\n\t\t\t\tif ( destElements[i] ) {\n\t\t\t\t\tfixCloneNodeIssues( node, destElements[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0; (node = srcElements[i]) != null; i++ ) {\n\t\t\t\t\tcloneCopyEvent( node, destElements[i] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\tdestElements = srcElements = node = null;\n\t\treturn clone;\n\t},\n\n\tbuildFragment: function( elems, context, scripts, selection ) {\n\t\tvar j, elem, contains,\n\t\t\ttmp, tag, tbody, wrap,\n\t\t\tl = elems.length,\n\t\t\tsafe = createSafeFragment( context ),\n\n\t\t\tnodes = [],\n\t\t\ti = 0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\telem = elems[ i ];\n\n\t\t\tif ( elem || elem === 0 ) {\n\t\t\t\tif ( jQuery.type( elem ) === \"object\" ) {\n\t\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\t\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\t\t\t\t} else {\n\t\t\t\t\ttmp = tmp || safe.appendChild( context.createElement(\"div\") );\n\t\t\t\t\ttag = (rtagName.exec( elem ) || [ \"\", \"\" ])[ 1 ].toLowerCase();\n\t\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\n\t\t\t\t\ttmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, \"<$1></$2>\" ) + wrap[2];\n\t\t\t\t\tj = wrap[0];\n\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t\t}\n\t\t\t\t\tif ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n\t\t\t\t\t\tnodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );\n\t\t\t\t\t}\n\t\t\t\t\tif ( !support.tbody ) {\n\t\t\t\t\t\telem = tag === \"table\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\ttmp.firstChild :\n\t\t\t\t\t\t\twrap[1] === \"<table>\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\t\ttmp :\n\t\t\t\t\t\t\t\t0;\n\n\t\t\t\t\t\tj = elem && elem.childNodes.length;\n\t\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\t\tif ( jQuery.nodeName( (tbody = elem.childNodes[j]), \"tbody\" ) && !tbody.childNodes.length ) {\n\t\t\t\t\t\t\t\telem.removeChild( tbody );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\t\t\t\t\ttmp.textContent = \"\";\n\t\t\t\t\twhile ( tmp.firstChild ) {\n\t\t\t\t\t\ttmp.removeChild( tmp.firstChild );\n\t\t\t\t\t}\n\t\t\t\t\ttmp = safe.lastChild;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif ( tmp ) {\n\t\t\tsafe.removeChild( tmp );\n\t\t}\n\t\tif ( !support.appendChecked ) {\n\t\t\tjQuery.grep( getAll( nodes, \"input\" ), fixDefaultChecked );\n\t\t}\n\n\t\ti = 0;\n\t\twhile ( (elem = nodes[ i++ ]) ) {\n\t\t\tif ( selection && jQuery.inArray( elem, selection ) !== -1 ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\t\t\ttmp = getAll( safe.appendChild( elem ), \"script\" );\n\t\t\tif ( contains ) {\n\t\t\t\tsetGlobalEval( tmp );\n\t\t\t}\n\t\t\tif ( scripts ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (elem = tmp[ j++ ]) ) {\n\t\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\t\tscripts.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttmp = null;\n\n\t\treturn safe;\n\t},\n\n\tcleanData: function( elems, /* internal */ acceptData ) {\n\t\tvar elem, type, id, data,\n\t\t\ti = 0,\n\t\t\tinternalKey = jQuery.expando,\n\t\t\tcache = jQuery.cache,\n\t\t\tdeleteExpando = support.deleteExpando,\n\t\t\tspecial = jQuery.event.special;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( acceptData || jQuery.acceptData( elem ) ) {\n\n\t\t\t\tid = elem[ internalKey ];\n\t\t\t\tdata = id && cache[ id ];\n\n\t\t\t\tif ( data ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( cache[ id ] ) {\n\n\t\t\t\t\t\tdelete cache[ id ];\n\t\t\t\t\t\tif ( deleteExpando ) {\n\t\t\t\t\t\t\tdelete elem[ internalKey ];\n\n\t\t\t\t\t\t} else if ( typeof elem.removeAttribute !== strundefined ) {\n\t\t\t\t\t\t\telem.removeAttribute( internalKey );\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\telem[ internalKey ] = null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdeletedIds.push( id );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\njQuery.fn.extend({\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t});\n\t},\n\n\tprepend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t});\n\t},\n\n\tbefore: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t});\n\t},\n\n\tafter: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t});\n\t},\n\n\tremove: function( selector, keepData /* Internal Use Only */ ) {\n\t\tvar elem,\n\t\t\telems = selector ? jQuery.filter( selector, this ) : this,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\n\t\t\tif ( !keepData && elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem ) );\n\t\t\t}\n\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\tif ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\t\tsetGlobalEval( getAll( elem, \"script\" ) );\n\t\t\t\t}\n\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = this[i]) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t}\n\t\t\twhile ( elem.firstChild ) {\n\t\t\t\telem.removeChild( elem.firstChild );\n\t\t\t}\n\t\t\tif ( elem.options && jQuery.nodeName( elem, \"select\" ) ) {\n\t\t\t\telem.options.length = 0;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map(function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t});\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined ) {\n\t\t\t\treturn elem.nodeType === 1 ?\n\t\t\t\t\telem.innerHTML.replace( rinlinejQuery, \"\" ) :\n\t\t\t\t\tundefined;\n\t\t\t}\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t( support.htmlSerialize || !rnoshimcache.test( value )  ) &&\n\t\t\t\t( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&\n\t\t\t\t!wrapMap[ (rtagName.exec( value ) || [ \"\", \"\" ])[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = value.replace( rxhtmlTag, \"<$1></$2>\" );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor (; i < l; i++ ) {\n\t\t\t\t\t\telem = this[i] || {};\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar arg = arguments[ 0 ];\n\t\tthis.domManip( arguments, function( elem ) {\n\t\t\targ = this.parentNode;\n\n\t\t\tjQuery.cleanData( getAll( this ) );\n\n\t\t\tif ( arg ) {\n\t\t\t\targ.replaceChild( elem, this );\n\t\t\t}\n\t\t});\n\t\treturn arg && (arg.length || arg.nodeType) ? this : this.remove();\n\t},\n\n\tdetach: function( selector ) {\n\t\treturn this.remove( selector, true );\n\t},\n\n\tdomManip: function( args, callback ) {\n\t\targs = concat.apply( [], args );\n\n\t\tvar first, node, hasScripts,\n\t\t\tscripts, doc, fragment,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tset = this,\n\t\t\tiNoClone = l - 1,\n\t\t\tvalue = args[0],\n\t\t\tisFunction = jQuery.isFunction( value );\n\t\tif ( isFunction ||\n\t\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\t\treturn this.each(function( index ) {\n\t\t\t\tvar self = set.eq( index );\n\t\t\t\tif ( isFunction ) {\n\t\t\t\t\targs[0] = value.call( this, index, self.html() );\n\t\t\t\t}\n\t\t\t\tself.domManip( args, callback );\n\t\t\t});\n\t\t}\n\n\t\tif ( l ) {\n\t\t\tfragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );\n\t\t\tfirst = fragment.firstChild;\n\n\t\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\t\tfragment = first;\n\t\t\t}\n\n\t\t\tif ( first ) {\n\t\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\t\thasScripts = scripts.length;\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\tnode = fragment;\n\n\t\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\t\t\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcallback.call( this[i], node, i );\n\t\t\t\t}\n\n\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\t\t\t\t\tjQuery.map( scripts, restoreScript );\n\t\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t\t!jQuery._data( node, \"globalEval\" ) && jQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\t\tif ( node.src ) {\n\t\t\t\t\t\t\t\tif ( jQuery._evalUrl ) {\n\t\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.globalEval( ( node.text || node.textContent || node.innerHTML || \"\" ).replace( rcleanScript, \"\" ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfragment = first = null;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n});\n\njQuery.each({\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\ti = 0,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone(true);\n\t\t\tjQuery( insert[i] )[ original ]( elems );\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\n\n\nvar iframe,\n\telemdisplay = {};\nfunction actualDisplay( name, doc ) {\n\tvar style,\n\t\telem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),\n\t\tdisplay = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?\n\t\t\tstyle.display : jQuery.css( elem[ 0 ], \"display\" );\n\telem.detach();\n\n\treturn display;\n}\n\nfunction defaultDisplay( nodeName ) {\n\tvar doc = document,\n\t\tdisplay = elemdisplay[ nodeName ];\n\n\tif ( !display ) {\n\t\tdisplay = actualDisplay( nodeName, doc );\n\t\tif ( display === \"none\" || !display ) {\n\t\t\tiframe = (iframe || jQuery( \"<iframe frameborder='0' width='0' height='0'/>\" )).appendTo( doc.documentElement );\n\t\t\tdoc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;\n\t\t\tdoc.write();\n\t\t\tdoc.close();\n\n\t\t\tdisplay = actualDisplay( nodeName, doc );\n\t\t\tiframe.detach();\n\t\t}\n\t\telemdisplay[ nodeName ] = display;\n\t}\n\n\treturn display;\n}\n\n\n(function() {\n\tvar shrinkWrapBlocksVal;\n\n\tsupport.shrinkWrapBlocks = function() {\n\t\tif ( shrinkWrapBlocksVal != null ) {\n\t\t\treturn shrinkWrapBlocksVal;\n\t\t}\n\t\tshrinkWrapBlocksVal = false;\n\t\tvar div, body, container;\n\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\t\tif ( !body || !body.style ) {\n\t\t\treturn;\n\t\t}\n\t\tdiv = document.createElement( \"div\" );\n\t\tcontainer = document.createElement( \"div\" );\n\t\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\t\tbody.appendChild( container ).appendChild( div );\n\t\tif ( typeof div.style.zoom !== strundefined ) {\n\t\t\tdiv.style.cssText =\n\t\t\t\t\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;\" +\n\t\t\t\t\"box-sizing:content-box;display:block;margin:0;border:0;\" +\n\t\t\t\t\"padding:1px;width:1px;zoom:1\";\n\t\t\tdiv.appendChild( document.createElement( \"div\" ) ).style.width = \"5px\";\n\t\t\tshrinkWrapBlocksVal = div.offsetWidth !== 3;\n\t\t}\n\n\t\tbody.removeChild( container );\n\n\t\treturn shrinkWrapBlocksVal;\n\t};\n\n})();\nvar rmargin = (/^margin/);\n\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\n\n\nvar getStyles, curCSS,\n\trposition = /^(top|right|bottom|left)$/;\n\nif ( window.getComputedStyle ) {\n\tgetStyles = function( elem ) {\n\t\treturn elem.ownerDocument.defaultView.getComputedStyle( elem, null );\n\t};\n\n\tcurCSS = function( elem, name, computed ) {\n\t\tvar width, minWidth, maxWidth, ret,\n\t\t\tstyle = elem.style;\n\n\t\tcomputed = computed || getStyles( elem );\n\t\tret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;\n\n\t\tif ( computed ) {\n\n\t\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\tret = jQuery.style( elem, name );\n\t\t\t}\n\t\t\tif ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\t\t\t\twidth = style.width;\n\t\t\t\tminWidth = style.minWidth;\n\t\t\t\tmaxWidth = style.maxWidth;\n\t\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\t\tret = computed.width;\n\t\t\t\tstyle.width = width;\n\t\t\t\tstyle.minWidth = minWidth;\n\t\t\t\tstyle.maxWidth = maxWidth;\n\t\t\t}\n\t\t}\n\t\treturn ret === undefined ?\n\t\t\tret :\n\t\t\tret + \"\";\n\t};\n} else if ( document.documentElement.currentStyle ) {\n\tgetStyles = function( elem ) {\n\t\treturn elem.currentStyle;\n\t};\n\n\tcurCSS = function( elem, name, computed ) {\n\t\tvar left, rs, rsLeft, ret,\n\t\t\tstyle = elem.style;\n\n\t\tcomputed = computed || getStyles( elem );\n\t\tret = computed ? computed[ name ] : undefined;\n\t\tif ( ret == null && style && style[ name ] ) {\n\t\t\tret = style[ name ];\n\t\t}\n\t\tif ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {\n\t\t\tleft = style.left;\n\t\t\trs = elem.runtimeStyle;\n\t\t\trsLeft = rs && rs.left;\n\t\t\tif ( rsLeft ) {\n\t\t\t\trs.left = elem.currentStyle.left;\n\t\t\t}\n\t\t\tstyle.left = name === \"fontSize\" ? \"1em\" : ret;\n\t\t\tret = style.pixelLeft + \"px\";\n\t\t\tstyle.left = left;\n\t\t\tif ( rsLeft ) {\n\t\t\t\trs.left = rsLeft;\n\t\t\t}\n\t\t}\n\t\treturn ret === undefined ?\n\t\t\tret :\n\t\t\tret + \"\" || \"auto\";\n\t};\n}\n\n\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\treturn {\n\t\tget: function() {\n\t\t\tvar condition = conditionFn();\n\n\t\t\tif ( condition == null ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( condition ) {\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\treturn (this.get = hookFn).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\n(function() {\n\tvar div, style, a, pixelPositionVal, boxSizingReliableVal,\n\t\treliableHiddenOffsetsVal, reliableMarginRightVal;\n\tdiv = document.createElement( \"div\" );\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\ta = div.getElementsByTagName( \"a\" )[ 0 ];\n\tstyle = a && a.style;\n\tif ( !style ) {\n\t\treturn;\n\t}\n\n\tstyle.cssText = \"float:left;opacity:.5\";\n\tsupport.opacity = style.opacity === \"0.5\";\n\tsupport.cssFloat = !!style.cssFloat;\n\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\tsupport.boxSizing = style.boxSizing === \"\" || style.MozBoxSizing === \"\" ||\n\t\tstyle.WebkitBoxSizing === \"\";\n\n\tjQuery.extend(support, {\n\t\treliableHiddenOffsets: function() {\n\t\t\tif ( reliableHiddenOffsetsVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn reliableHiddenOffsetsVal;\n\t\t},\n\n\t\tboxSizingReliable: function() {\n\t\t\tif ( boxSizingReliableVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\n\t\tpixelPosition: function() {\n\t\t\tif ( pixelPositionVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\treliableMarginRight: function() {\n\t\t\tif ( reliableMarginRightVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn reliableMarginRightVal;\n\t\t}\n\t});\n\n\tfunction computeStyleTests() {\n\t\tvar div, body, container, contents;\n\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\t\tif ( !body || !body.style ) {\n\t\t\treturn;\n\t\t}\n\t\tdiv = document.createElement( \"div\" );\n\t\tcontainer = document.createElement( \"div\" );\n\t\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\t\tbody.appendChild( container ).appendChild( div );\n\n\t\tdiv.style.cssText =\n\t\t\t\"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;\" +\n\t\t\t\"box-sizing:border-box;display:block;margin-top:1%;top:1%;\" +\n\t\t\t\"border:1px;padding:1px;width:4px;position:absolute\";\n\t\tpixelPositionVal = boxSizingReliableVal = false;\n\t\treliableMarginRightVal = true;\n\t\tif ( window.getComputedStyle ) {\n\t\t\tpixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== \"1%\";\n\t\t\tboxSizingReliableVal =\n\t\t\t\t( window.getComputedStyle( div, null ) || { width: \"4px\" } ).width === \"4px\";\n\t\t\tcontents = div.appendChild( document.createElement( \"div\" ) );\n\t\t\tcontents.style.cssText = div.style.cssText =\n\t\t\t\t\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;\" +\n\t\t\t\t\"box-sizing:content-box;display:block;margin:0;border:0;padding:0\";\n\t\t\tcontents.style.marginRight = contents.style.width = \"0\";\n\t\t\tdiv.style.width = \"1px\";\n\n\t\t\treliableMarginRightVal =\n\t\t\t\t!parseFloat( ( window.getComputedStyle( contents, null ) || {} ).marginRight );\n\t\t}\n\t\tdiv.innerHTML = \"<table><tr><td></td><td>t</td></tr></table>\";\n\t\tcontents = div.getElementsByTagName( \"td\" );\n\t\tcontents[ 0 ].style.cssText = \"margin:0;border:0;padding:0;display:none\";\n\t\treliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;\n\t\tif ( reliableHiddenOffsetsVal ) {\n\t\t\tcontents[ 0 ].style.display = \"\";\n\t\t\tcontents[ 1 ].style.display = \"none\";\n\t\t\treliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;\n\t\t}\n\n\t\tbody.removeChild( container );\n\t}\n\n})();\njQuery.swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar\n\t\tralpha = /alpha\\([^)]*\\)/i,\n\tropacity = /opacity\\s*=\\s*([^)]*)/,\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trnumsplit = new RegExp( \"^(\" + pnum + \")(.*)$\", \"i\" ),\n\trrelNum = new RegExp( \"^([+-])=(\" + pnum + \")\", \"i\" ),\n\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t},\n\n\tcssPrefixes = [ \"Webkit\", \"O\", \"Moz\", \"ms\" ];\nfunction vendorPropName( style, name ) {\n\tif ( name in style ) {\n\t\treturn name;\n\t}\n\tvar capName = name.charAt(0).toUpperCase() + name.slice(1),\n\t\torigName = name,\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in style ) {\n\t\t\treturn name;\n\t\t}\n\t}\n\n\treturn origName;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem, hidden,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\" );\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\t\t\tif ( !values[ index ] && display === \"none\" ) {\n\t\t\t\telem.style.display = \"\";\n\t\t\t}\n\t\t\tif ( elem.style.display === \"\" && isHidden( elem ) ) {\n\t\t\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\", defaultDisplay(elem.nodeName) );\n\t\t\t}\n\t\t} else {\n\t\t\thidden = isHidden( elem );\n\n\t\t\tif ( display && display !== \"none\" || !hidden ) {\n\t\t\t\tjQuery._data( elem, \"olddisplay\", hidden ? display : jQuery.css( elem, \"display\" ) );\n\t\t\t}\n\t\t}\n\t}\n\tfor ( index = 0; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( !show || elem.style.display === \"none\" || elem.style.display === \"\" ) {\n\t\t\telem.style.display = show ? values[ index ] || \"\" : \"none\";\n\t\t}\n\t}\n\n\treturn elements;\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\tvar matches = rnumsplit.exec( value );\n\treturn matches ?\n\t\tMath.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {\n\tvar i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n\t\t4 :\n\t\tname === \"width\" ? 1 : 0,\n\n\t\tval = 0;\n\n\tfor ( ; i < 4; i += 2 ) {\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += jQuery.css( elem, extra + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\tif ( isBorderBox ) {\n\t\t\tif ( extra === \"content\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\t\t\tif ( extra !== \"margin\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t} else {\n\t\t\tval += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\tvar valueIsBorderBox = true,\n\t\tval = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n\t\tstyles = getStyles( elem ),\n\t\tisBorderBox = support.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\tif ( val <= 0 || val == null ) {\n\t\tval = curCSS( elem, name, styles );\n\t\tif ( val < 0 || val == null ) {\n\t\t\tval = elem.style[ name ];\n\t\t}\n\t\tif ( rnumnonpx.test(val) ) {\n\t\t\treturn val;\n\t\t}\n\t\tvalueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] );\n\t\tval = parseFloat( val ) || 0;\n\t}\n\treturn ( val +\n\t\taugmentWidthOrHeight(\n\t\t\telem,\n\t\t\tname,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend({\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\tcssNumber: {\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\tcssProps: {\n\t\t\"float\": support.cssFloat ? \"cssFloat\" : \"styleFloat\"\n\t},\n\tstyle: function( elem, name, value, extra ) {\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\t\tvar ret, type, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style;\n\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\t\t\tif ( type === \"string\" && (ret = rrelNum.exec( value )) ) {\n\t\t\t\tvalue = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n\t\t\t\tvalue += \"px\";\n\t\t\t}\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf(\"background\") === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\t\t\tif ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {\n\t\t\t\ttry {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t} else {\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar num, val, hooks,\n\t\t\torigName = jQuery.camelCase( name );\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || jQuery.isNumeric( num ) ? num || 0 : val;\n\t\t}\n\t\treturn val;\n\t}\n});\n\njQuery.each([ \"height\", \"width\" ], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) && elem.offsetWidth === 0 ?\n\t\t\t\t\tjQuery.swap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t\t}) :\n\t\t\t\t\tgetWidthOrHeight( elem, name, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar styles = extra && getStyles( elem );\n\t\t\treturn setPositiveNumber( elem, value, extra ?\n\t\t\t\taugmentWidthOrHeight(\n\t\t\t\t\telem,\n\t\t\t\t\tname,\n\t\t\t\t\textra,\n\t\t\t\t\tsupport.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\t\tstyles\n\t\t\t\t) : 0\n\t\t\t);\n\t\t}\n\t};\n});\n\nif ( !support.opacity ) {\n\tjQuery.cssHooks.opacity = {\n\t\tget: function( elem, computed ) {\n\t\t\treturn ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || \"\" ) ?\n\t\t\t\t( 0.01 * parseFloat( RegExp.$1 ) ) + \"\" :\n\t\t\t\tcomputed ? \"1\" : \"\";\n\t\t},\n\n\t\tset: function( elem, value ) {\n\t\t\tvar style = elem.style,\n\t\t\t\tcurrentStyle = elem.currentStyle,\n\t\t\t\topacity = jQuery.isNumeric( value ) ? \"alpha(opacity=\" + value * 100 + \")\" : \"\",\n\t\t\t\tfilter = currentStyle && currentStyle.filter || style.filter || \"\";\n\t\t\tstyle.zoom = 1;\n\t\t\tif ( ( value >= 1 || value === \"\" ) &&\n\t\t\t\t\tjQuery.trim( filter.replace( ralpha, \"\" ) ) === \"\" &&\n\t\t\t\t\tstyle.removeAttribute ) {\n\t\t\t\tstyle.removeAttribute( \"filter\" );\n\t\t\t\tif ( value === \"\" || currentStyle && !currentStyle.filter ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tstyle.filter = ralpha.test( filter ) ?\n\t\t\t\tfilter.replace( ralpha, opacity ) :\n\t\t\t\tfilter + \" \" + opacity;\n\t\t}\n\t};\n}\n\njQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn jQuery.swap( elem, { \"display\": \"inline-block\" },\n\t\t\t\tcurCSS, [ elem, \"marginRight\" ] );\n\t\t}\n\t}\n);\njQuery.each({\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\t\t\t\tparts = typeof value === \"string\" ? value.split(\" \") : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( !rmargin.test( prefix ) ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n});\n\njQuery.fn.extend({\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( jQuery.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t},\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( isHidden( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t});\n\t}\n});\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || \"swing\";\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\tif ( tween.elem[ tween.prop ] != null &&\n\t\t\t\t(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t}\n};\n\njQuery.fx = Tween.prototype.init;\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, timerId,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trfxnum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" ),\n\trrun = /queueHooks$/,\n\tanimationPrefilters = [ defaultPrefilter ],\n\ttweeners = {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value ),\n\t\t\t\ttarget = tween.cur(),\n\t\t\t\tparts = rfxnum.exec( value ),\n\t\t\t\tunit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\t\t\t\tstart = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +target ) &&\n\t\t\t\t\trfxnum.exec( jQuery.css( tween.elem, prop ) ),\n\t\t\t\tscale = 1,\n\t\t\t\tmaxIterations = 20;\n\n\t\t\tif ( start && start[ 3 ] !== unit ) {\n\t\t\t\tunit = unit || start[ 3 ];\n\t\t\t\tparts = parts || [];\n\t\t\t\tstart = +target || 1;\n\n\t\t\t\tdo {\n\t\t\t\t\tscale = scale || \".5\";\n\t\t\t\t\tstart = start / scale;\n\t\t\t\t\tjQuery.style( tween.elem, prop, start + unit );\n\t\t\t\t} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );\n\t\t\t}\n\t\t\tif ( parts ) {\n\t\t\t\tstart = tween.start = +start || +target || 0;\n\t\t\t\ttween.unit = unit;\n\t\t\t\ttween.end = parts[ 1 ] ?\n\t\t\t\t\tstart + ( parts[ 1 ] + 1 ) * parts[ 2 ] :\n\t\t\t\t\t+parts[ 2 ];\n\t\t\t}\n\n\t\t\treturn tween;\n\t\t} ]\n\t};\nfunction createFxNow() {\n\tsetTimeout(function() {\n\t\tfxNow = undefined;\n\t});\n\treturn ( fxNow = jQuery.now() );\n}\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\tattrs = { height: type },\n\t\ti = 0;\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4 ; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( tweeners[ prop ] || [] ).concat( tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( (tween = collection[ index ].call( animation, prop, value )) ) {\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\t/* jshint validthis: true */\n\tvar prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHidden( elem ),\n\t\tdataShow = jQuery._data( elem, \"fxshow\" );\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always(function() {\n\t\t\tanim.always(function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\tif ( elem.nodeType === 1 && ( \"height\" in props || \"width\" in props ) ) {\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tcheckDisplay = display === \"none\" ?\n\t\t\tjQuery._data( elem, \"olddisplay\" ) || defaultDisplay( elem.nodeName ) : display;\n\n\t\tif ( checkDisplay === \"inline\" && jQuery.css( elem, \"float\" ) === \"none\" ) {\n\t\t\tif ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === \"inline\" ) {\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t} else {\n\t\t\t\tstyle.zoom = 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tif ( !support.shrinkWrapBlocks() ) {\n\t\t\tanim.always(function() {\n\t\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t\t});\n\t\t}\n\t}\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.exec( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t} else {\n\t\t\tdisplay = undefined;\n\t\t}\n\t}\n\n\tif ( !jQuery.isEmptyObject( orig ) ) {\n\t\tif ( dataShow ) {\n\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\thidden = dataShow.hidden;\n\t\t\t}\n\t\t} else {\n\t\t\tdataShow = jQuery._data( elem, \"fxshow\", {} );\n\t\t}\n\t\tif ( toggle ) {\n\t\t\tdataShow.hidden = !hidden;\n\t\t}\n\t\tif ( hidden ) {\n\t\t\tjQuery( elem ).show();\n\t\t} else {\n\t\t\tanim.done(function() {\n\t\t\t\tjQuery( elem ).hide();\n\t\t\t});\n\t\t}\n\t\tanim.done(function() {\n\t\t\tvar prop;\n\t\t\tjQuery._removeData( elem, \"fxshow\" );\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t}\n\t\t});\n\t\tfor ( prop in orig ) {\n\t\t\ttween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\n\t\t\tif ( !( prop in dataShow ) ) {\n\t\t\t\tdataShow[ prop ] = tween.start;\n\t\t\t\tif ( hidden ) {\n\t\t\t\t\ttween.end = tween.start;\n\t\t\t\t\ttween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if ( (display === \"none\" ? defaultDisplay( elem.nodeName ) : display) === \"inline\" ) {\n\t\tstyle.display = display;\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\tfor ( index in props ) {\n\t\tname = jQuery.camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( jQuery.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = animationPrefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\t\t\tdelete tick.elem;\n\t\t}),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ]);\n\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t} else {\n\t\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tanimation = deferred.promise({\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, { specialEasing: {} }, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length ; index++ ) {\n\t\tresult = animationPrefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( jQuery.isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t})\n\t);\n\treturn animation.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\ttweener: function( props, callback ) {\n\t\tif ( jQuery.isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.split(\" \");\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length ; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\ttweeners[ prop ] = tweeners[ prop ] || [];\n\t\t\ttweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tanimationPrefilters.unshift( callback );\n\t\t} else {\n\t\t\tanimationPrefilters.push( callback );\n\t\t}\n\t}\n});\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tjQuery.isFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n\t};\n\n\topt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n\t\topt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend({\n\tfadeTo: function( speed, to, easing, callback ) {\n\t\treturn this.filter( isHidden ).css( \"opacity\", 0 ).show()\n\t\t\t.end().animate({ opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\t\t\t\tif ( empty || jQuery._data( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = jQuery._data( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t});\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tvar index,\n\t\t\t\tdata = jQuery._data( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\t\t\tdata.finish = true;\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\t\t\tdelete data.finish;\n\t\t});\n\t}\n});\n\njQuery.each([ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n});\njQuery.each({\n\tslideDown: genFx(\"show\"),\n\tslideUp: genFx(\"hide\"),\n\tslideToggle: genFx(\"toggle\"),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n});\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ttimers = jQuery.timers,\n\t\ti = 0;\n\n\tfxNow = jQuery.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tif ( timer() ) {\n\t\tjQuery.fx.start();\n\t} else {\n\t\tjQuery.timers.pop();\n\t}\n};\n\njQuery.fx.interval = 13;\n\njQuery.fx.start = function() {\n\tif ( !timerId ) {\n\t\ttimerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );\n\t}\n};\n\njQuery.fx.stop = function() {\n\tclearInterval( timerId );\n\ttimerId = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\t_default: 400\n};\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\tclearTimeout( timeout );\n\t\t};\n\t});\n};\n\n\n(function() {\n\tvar input, div, select, a, opt;\n\tdiv = document.createElement( \"div\" );\n\tdiv.setAttribute( \"className\", \"t\" );\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\ta = div.getElementsByTagName(\"a\")[ 0 ];\n\tselect = document.createElement(\"select\");\n\topt = select.appendChild( document.createElement(\"option\") );\n\tinput = div.getElementsByTagName(\"input\")[ 0 ];\n\n\ta.style.cssText = \"top:1px\";\n\tsupport.getSetAttribute = div.className !== \"t\";\n\tsupport.style = /top/.test( a.getAttribute(\"style\") );\n\tsupport.hrefNormalized = a.getAttribute(\"href\") === \"/a\";\n\tsupport.checkOn = !!input.value;\n\tsupport.optSelected = opt.selected;\n\tsupport.enctype = !!document.createElement(\"form\").enctype;\n\tselect.disabled = true;\n\tsupport.optDisabled = !opt.disabled;\n\tinput = document.createElement( \"input\" );\n\tinput.setAttribute( \"value\", \"\" );\n\tsupport.input = input.getAttribute( \"value\" ) === \"\";\n\tinput.value = \"t\";\n\tinput.setAttribute( \"type\", \"radio\" );\n\tsupport.radioValue = input.value === \"t\";\n})();\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend({\n\tval: function( value ) {\n\t\tvar hooks, ret, isFunction,\n\t\t\telem = this[0];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ?\n\t\t\t\t\tret.replace(rreturn, \"\") :\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tisFunction = jQuery.isFunction( value );\n\n\t\treturn this.each(function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\t\t\tif ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\t\t\t\t\tjQuery.trim( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\" || index < 0,\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length,\n\t\t\t\t\ti = index < 0 ?\n\t\t\t\t\t\tmax :\n\t\t\t\t\t\tone ? index : 0;\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\t\t\t\t\t\t\t( support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null ) &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\tif ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\toption.selected = optionSet = true;\n\n\t\t\t\t\t\t} catch ( _ ) {\n\t\t\t\t\t\t\toption.scrollHeight;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\toption.selected = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\n\t\t\t\treturn options;\n\t\t\t}\n\t\t}\n\t}\n});\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n\t\t};\n\t}\n});\n\n\n\n\nvar nodeHook, boolHook,\n\tattrHandle = jQuery.expr.attrHandle,\n\truseDefault = /^(?:checked|selected)$/i,\n\tgetSetAttribute = support.getSetAttribute,\n\tgetSetInput = support.input;\n\njQuery.fn.extend({\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tattr: function( elem, name, value ) {\n\t\tvar hooks, ret,\n\t\t\tnType = elem.nodeType;\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( typeof elem.getAttribute === strundefined ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\tname = name.toLowerCase();\n\t\t\thooks = jQuery.attrHooks[ name ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\n\t\t\t} else if ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t} else if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ) {\n\t\t\treturn ret;\n\n\t\t} else {\n\t\t\tret = jQuery.find.attr( elem, name );\n\t\t\treturn ret == null ?\n\t\t\t\tundefined :\n\t\t\t\tret;\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name, propName,\n\t\t\ti = 0,\n\t\t\tattrNames = value && value.match( rnotwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( (name = attrNames[i++]) ) {\n\t\t\t\tpropName = jQuery.propFix[ name ] || name;\n\t\t\t\tif ( jQuery.expr.match.bool.test( name ) ) {\n\t\t\t\t\tif ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\telem[ jQuery.camelCase( \"default-\" + name ) ] =\n\t\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tjQuery.attr( elem, name, \"\" );\n\t\t\t\t}\n\n\t\t\t\telem.removeAttribute( getSetAttribute ? name : propName );\n\t\t\t}\n\t\t}\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" && jQuery.nodeName(elem, \"input\") ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n\t\t\telem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );\n\t\t} else {\n\t\t\telem[ jQuery.camelCase( \"default-\" + name ) ] = elem[ name ] = true;\n\t\t}\n\n\t\treturn name;\n\t}\n};\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?\n\t\tfunction( elem, name, isXML ) {\n\t\t\tvar ret, handle;\n\t\t\tif ( !isXML ) {\n\t\t\t\thandle = attrHandle[ name ];\n\t\t\t\tattrHandle[ name ] = ret;\n\t\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\t\tname.toLowerCase() :\n\t\t\t\t\tnull;\n\t\t\t\tattrHandle[ name ] = handle;\n\t\t\t}\n\t\t\treturn ret;\n\t\t} :\n\t\tfunction( elem, name, isXML ) {\n\t\t\tif ( !isXML ) {\n\t\t\t\treturn elem[ jQuery.camelCase( \"default-\" + name ) ] ?\n\t\t\t\t\tname.toLowerCase() :\n\t\t\t\t\tnull;\n\t\t\t}\n\t\t};\n});\nif ( !getSetInput || !getSetAttribute ) {\n\tjQuery.attrHooks.value = {\n\t\tset: function( elem, value, name ) {\n\t\t\tif ( jQuery.nodeName( elem, \"input\" ) ) {\n\t\t\t\telem.defaultValue = value;\n\t\t\t} else {\n\t\t\t\treturn nodeHook && nodeHook.set( elem, value, name );\n\t\t\t}\n\t\t}\n\t};\n}\nif ( !getSetAttribute ) {\n\tnodeHook = {\n\t\tset: function( elem, value, name ) {\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( !ret ) {\n\t\t\t\telem.setAttributeNode(\n\t\t\t\t\t(ret = elem.ownerDocument.createAttribute( name ))\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tret.value = value += \"\";\n\t\t\tif ( name === \"value\" || value === elem.getAttribute( name ) ) {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t};\n\tattrHandle.id = attrHandle.name = attrHandle.coords =\n\t\tfunction( elem, name, isXML ) {\n\t\t\tvar ret;\n\t\t\tif ( !isXML ) {\n\t\t\t\treturn (ret = elem.getAttributeNode( name )) && ret.value !== \"\" ?\n\t\t\t\t\tret.value :\n\t\t\t\t\tnull;\n\t\t\t}\n\t\t};\n\tjQuery.valHooks.button = {\n\t\tget: function( elem, name ) {\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( ret && ret.specified ) {\n\t\t\t\treturn ret.value;\n\t\t\t}\n\t\t},\n\t\tset: nodeHook.set\n\t};\n\tjQuery.attrHooks.contenteditable = {\n\t\tset: function( elem, value, name ) {\n\t\t\tnodeHook.set( elem, value === \"\" ? false : value, name );\n\t\t}\n\t};\n\tjQuery.each([ \"width\", \"height\" ], function( i, name ) {\n\t\tjQuery.attrHooks[ name ] = {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( value === \"\" ) {\n\t\t\t\t\telem.setAttribute( name, \"auto\" );\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\nif ( !support.style ) {\n\tjQuery.attrHooks.style = {\n\t\tget: function( elem ) {\n\t\t\treturn elem.style.cssText || undefined;\n\t\t},\n\t\tset: function( elem, value ) {\n\t\t\treturn ( elem.style.cssText = value + \"\" );\n\t\t}\n\t};\n}\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button|object)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend({\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\tname = jQuery.propFix[ name ] || name;\n\t\treturn this.each(function() {\n\t\t\ttry {\n\t\t\t\tthis[ name ] = undefined;\n\t\t\t\tdelete this[ name ];\n\t\t\t} catch( e ) {}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t},\n\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks, notxml,\n\t\t\tnType = elem.nodeType;\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\tif ( notxml ) {\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\treturn hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?\n\t\t\t\tret :\n\t\t\t\t( elem[ name ] = value );\n\n\t\t} else {\n\t\t\treturn hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ?\n\t\t\t\tret :\n\t\t\t\telem[ name ];\n\t\t}\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\treturn tabindex ?\n\t\t\t\t\tparseInt( tabindex, 10 ) :\n\t\t\t\t\trfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?\n\t\t\t\t\t\t0 :\n\t\t\t\t\t\t-1;\n\t\t\t}\n\t\t}\n\t}\n});\nif ( !support.hrefNormalized ) {\n\tjQuery.each([ \"href\", \"src\" ], function( i, name ) {\n\t\tjQuery.propHooks[ name ] = {\n\t\t\tget: function( elem ) {\n\t\t\t\treturn elem.getAttribute( name, 4 );\n\t\t\t}\n\t\t};\n\t});\n}\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t};\n}\n\njQuery.each([\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n});\nif ( !support.enctype ) {\n\tjQuery.propFix.enctype = \"encoding\";\n}\n\n\n\n\nvar rclass = /[\\t\\r\\n\\f]/g;\n\njQuery.fn.extend({\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\n\t\tif ( proceed ) {\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\" \"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfinalValue = jQuery.trim( cur );\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = arguments.length === 0 || typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\t\tif ( proceed ) {\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) >= 0 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfinalValue = value ? jQuery.trim( cur ) : \"\";\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value;\n\n\t\tif ( typeof stateVal === \"boolean\" && type === \"string\" ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( type === \"string\" ) {\n\t\t\t\tvar className,\n\t\t\t\t\ti = 0,\n\t\t\t\t\tself = jQuery( this ),\n\t\t\t\t\tclassNames = value.match( rnotwhite ) || [];\n\n\t\t\t\twhile ( (className = classNames[ i++ ]) ) {\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if ( type === strundefined || type === \"boolean\" ) {\n\t\t\t\tif ( this.className ) {\n\t\t\t\t\tjQuery._data( this, \"__className__\", this.className );\n\t\t\t\t}\n\t\t\t\tthis.className = this.className || value === false ? \"\" : jQuery._data( this, \"__className__\" ) || \"\";\n\t\t\t}\n\t\t});\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className = \" \" + selector + \" \",\n\t\t\ti = 0,\n\t\t\tl = this.length;\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tif ( this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) >= 0 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n});\n\n\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup error contextmenu\").split(\" \"), function( i, name ) {\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n});\n\njQuery.fn.extend({\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t},\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\t\treturn arguments.length === 1 ? this.off( selector, \"**\" ) : this.off( types, selector || \"**\", fn );\n\t}\n});\n\n\nvar nonce = jQuery.now();\n\nvar rquery = (/\\?/);\n\n\n\nvar rvalidtokens = /(,)|(\\[|{)|(}|])|\"(?:[^\"\\\\\\r\\n]|\\\\[\"\\\\\\/bfnrt]|\\\\u[\\da-fA-F]{4})*\"\\s*:?|true|false|null|-?(?!0\\d)\\d+(?:\\.\\d+|)(?:[eE][+-]?\\d+|)/g;\n\njQuery.parseJSON = function( data ) {\n\tif ( window.JSON && window.JSON.parse ) {\n\t\treturn window.JSON.parse( data + \"\" );\n\t}\n\n\tvar requireNonComma,\n\t\tdepth = null,\n\t\tstr = jQuery.trim( data + \"\" );\n\treturn str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {\n\t\tif ( requireNonComma && comma ) {\n\t\t\tdepth = 0;\n\t\t}\n\t\tif ( depth === 0 ) {\n\t\t\treturn token;\n\t\t}\n\t\trequireNonComma = open || comma;\n\t\tdepth += !close - !open;\n\t\treturn \"\";\n\t}) ) ?\n\t\t( Function( \"return \" + str ) )() :\n\t\tjQuery.error( \"Invalid JSON: \" + data );\n};\njQuery.parseXML = function( data ) {\n\tvar xml, tmp;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\ttry {\n\t\tif ( window.DOMParser ) { // Standard\n\t\t\ttmp = new DOMParser();\n\t\t\txml = tmp.parseFromString( data, \"text/xml\" );\n\t\t} else { // IE\n\t\t\txml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n\t\t\txml.async = \"false\";\n\t\t\txml.loadXML( data );\n\t\t}\n\t} catch( e ) {\n\t\txml = undefined;\n\t}\n\tif ( !xml || !xml.documentElement || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\tajaxLocParts,\n\tajaxLocation,\n\n\trhash = /#.*$/,\n\trts = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/mg, // IE leaves an \\r character at EOL\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\trurl = /^([\\w.+-]+:)(?:\\/\\/(?:[^\\/?#]*@|)([^\\/?#:]*)(?::(\\d+)|)|)/,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\tallTypes = \"*/\".concat(\"*\");\ntry {\n\tajaxLocation = location.href;\n} catch( e ) {\n\tajaxLocation = document.createElement( \"a\" );\n\tajaxLocation.href = \"\";\n\tajaxLocation = ajaxLocation.href;\n}\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\nfunction addToPrefiltersOrTransports( structure ) {\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\t\t\twhile ( (dataType = dataTypes[i++]) ) {\n\t\t\t\tif ( dataType.charAt( 0 ) === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).unshift( func );\n\t\t\t\t} else {\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t});\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\nfunction ajaxExtend( target, src ) {\n\tvar deep, key,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\tvar firstDataType, ct, finalDataType, type,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader(\"Content-Type\");\n\t\t}\n\t}\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\t\tdataTypes = s.dataTypes.slice();\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ( conv !== true ) {\n\t\t\t\t\tif ( conv && s[ \"throws\" ] ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn { state: \"parsererror\", error: conv ? e : \"No conversion from \" + prev + \" to \" + current };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend({\n\tactive: 0,\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: ajaxLocation,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /xml/,\n\t\t\thtml: /html/,\n\t\t\tjson: /json/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\t\tconverters: {\n\t\t\t\"* text\": String,\n\t\t\t\"text html\": true,\n\t\t\t\"text json\": jQuery.parseJSON,\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\tajax: function( url, options ) {\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\t\toptions = options || {};\n\n\t\tvar // Cross-domain detection vars\n\t\t\tparts,\n\t\t\ti,\n\t\t\tcacheURL,\n\t\t\tresponseHeadersString,\n\t\t\ttimeoutTimer,\n\t\t\tfireGlobals,\n\n\t\t\ttransport,\n\t\t\tresponseHeaders,\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\t\t\tcallbackContext = s.context || s,\n\t\t\tglobalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\tjQuery.event,\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks(\"once memory\"),\n\t\t\tstatusCode = s.statusCode || {},\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\t\t\tstate = 0,\n\t\t\tstrAbort = \"canceled\",\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( state === 2 ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( (match = rheaders.exec( responseHeadersString )) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match;\n\t\t\t\t},\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn state === 2 ? responseHeadersString : null;\n\t\t\t\t},\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tvar lname = name.toLowerCase();\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\tname = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\t\tdeferred.promise( jqXHR ).complete = completeDeferred.add;\n\t\tjqXHR.success = jqXHR.done;\n\t\tjqXHR.error = jqXHR.fail;\n\t\ts.url = ( ( url || s.url || ajaxLocation ) + \"\" ).replace( rhash, \"\" ).replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\t\ts.type = options.method || options.type || s.method || s.type;\n\t\ts.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().match( rnotwhite ) || [ \"\" ];\n\t\tif ( s.crossDomain == null ) {\n\t\t\tparts = rurl.exec( s.url.toLowerCase() );\n\t\t\ts.crossDomain = !!( parts &&\n\t\t\t\t( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||\n\t\t\t\t\t( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) !==\n\t\t\t\t\t\t( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) )\n\t\t\t);\n\t\t}\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\t\tif ( state === 2 ) {\n\t\t\treturn jqXHR;\n\t\t}\n\t\tfireGlobals = s.global;\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger(\"ajaxStart\");\n\t\t}\n\t\ts.type = s.type.toUpperCase();\n\t\ts.hasContent = !rnoContent.test( s.type );\n\t\tcacheURL = s.url;\n\t\tif ( !s.hasContent ) {\n\t\t\tif ( s.data ) {\n\t\t\t\tcacheURL = ( s.url += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data );\n\t\t\t\tdelete s.data;\n\t\t\t}\n\t\t\tif ( s.cache === false ) {\n\t\t\t\ts.url = rts.test( cacheURL ) ?\n\t\t\t\t\tcacheURL.replace( rts, \"$1_=\" + nonce++ ) :\n\t\t\t\t\tcacheURL + ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + nonce++;\n\t\t\t}\n\t\t}\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\t\tif ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n\t\t\treturn jqXHR.abort();\n\t\t}\n\t\tstrAbort = \"abort\";\n\t\tfor ( i in { success: 1, error: 1, complete: 1 } ) {\n\t\t\tjqXHR[ i ]( s[ i ] );\n\t\t}\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = setTimeout(function() {\n\t\t\t\t\tjqXHR.abort(\"timeout\");\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tstate = 1;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tdone( -1, e );\n\t\t\t\t} else {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\t\t\tif ( state === 2 ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tstate = 2;\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\tclearTimeout( timeoutTimer );\n\t\t\t}\n\t\t\ttransport = undefined;\n\t\t\tresponseHeadersString = headers || \"\";\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\t\t\tif ( isSuccess ) {\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"Last-Modified\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"etag\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger(\"ajaxStop\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\treturn jQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t});\n\t};\n});\njQuery.each( [ \"ajaxStart\", \"ajaxStop\", \"ajaxComplete\", \"ajaxError\", \"ajaxSuccess\", \"ajaxSend\" ], function( i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n});\n\n\njQuery._evalUrl = function( url ) {\n\treturn jQuery.ajax({\n\t\turl: url,\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tasync: false,\n\t\tglobal: false,\n\t\t\"throws\": true\n\t});\n};\n\n\njQuery.fn.extend({\n\twrapAll: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapAll( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[0] ) {\n\t\t\tvar wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);\n\n\t\t\tif ( this[0].parentNode ) {\n\t\t\t\twrap.insertBefore( this[0] );\n\t\t\t}\n\n\t\t\twrap.map(function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstChild && elem.firstChild.nodeType === 1 ) {\n\t\t\t\t\telem = elem.firstChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t}).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapInner( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t});\n\t},\n\n\twrap: function( html ) {\n\t\tvar isFunction = jQuery.isFunction( html );\n\n\t\treturn this.each(function(i) {\n\t\t\tjQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );\n\t\t});\n\t},\n\n\tunwrap: function() {\n\t\treturn this.parent().each(function() {\n\t\t\tif ( !jQuery.nodeName( this, \"body\" ) ) {\n\t\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t\t}\n\t\t}).end();\n\t}\n});\n\n\njQuery.expr.filters.hidden = function( elem ) {\n\treturn elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||\n\t\t(!support.reliableHiddenOffsets() &&\n\t\t\t((elem.style && elem.style.display) || jQuery.css( elem, \"display\" )) === \"none\");\n};\n\njQuery.expr.filters.visible = function( elem ) {\n\treturn !jQuery.expr.filters.hidden( elem );\n};\n\n\n\n\nvar r20 = /%20/g,\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( jQuery.isArray( obj ) ) {\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\t\t\t\tbuildParams( prefix + \"[\" + ( typeof v === \"object\" ? i : \"\" ) + \"]\", v, traditional, add );\n\t\t\t}\n\t\t});\n\n\t} else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\t\tadd( prefix, obj );\n\t}\n}\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, value ) {\n\t\t\tvalue = jQuery.isFunction( value ) ? value() : ( value == null ? \"\" : value );\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n\t\t};\n\tif ( traditional === undefined ) {\n\t\ttraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n\t}\n\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t});\n\n\t} else {\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\treturn s.join( \"&\" ).replace( r20, \"+\" );\n};\n\njQuery.fn.extend({\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map(function() {\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t})\n\t\t.filter(function() {\n\t\t\tvar type = this.type;\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t})\n\t\t.map(function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val ) {\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t}) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t}).get();\n\t}\n});\njQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?\n\tfunction() {\n\t\treturn !this.isLocal &&\n\t\t\t/^(get|post|head|put|delete|options)$/i.test( this.type ) &&\n\n\t\t\tcreateStandardXHR() || createActiveXHR();\n\t} :\n\tcreateStandardXHR;\n\nvar xhrId = 0,\n\txhrCallbacks = {},\n\txhrSupported = jQuery.ajaxSettings.xhr();\nif ( window.ActiveXObject ) {\n\tjQuery( window ).on( \"unload\", function() {\n\t\tfor ( var key in xhrCallbacks ) {\n\t\t\txhrCallbacks[ key ]( undefined, true );\n\t\t}\n\t});\n}\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nxhrSupported = support.ajax = !!xhrSupported;\nif ( xhrSupported ) {\n\n\tjQuery.ajaxTransport(function( options ) {\n\t\tif ( !options.crossDomain || support.cors ) {\n\n\t\t\tvar callback;\n\n\t\t\treturn {\n\t\t\t\tsend: function( headers, complete ) {\n\t\t\t\t\tvar i,\n\t\t\t\t\t\txhr = options.xhr(),\n\t\t\t\t\t\tid = ++xhrId;\n\t\t\t\t\txhr.open( options.type, options.url, options.async, options.username, options.password );\n\t\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t\t}\n\t\t\t\t\tif ( !options.crossDomain && !headers[\"X-Requested-With\"] ) {\n\t\t\t\t\t\theaders[\"X-Requested-With\"] = \"XMLHttpRequest\";\n\t\t\t\t\t}\n\t\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\t\tif ( headers[ i ] !== undefined ) {\n\t\t\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] + \"\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\txhr.send( ( options.hasContent && options.data ) || null );\n\t\t\t\t\tcallback = function( _, isAbort ) {\n\t\t\t\t\t\tvar status, statusText, responses;\n\t\t\t\t\t\tif ( callback && ( isAbort || xhr.readyState === 4 ) ) {\n\t\t\t\t\t\t\tdelete xhrCallbacks[ id ];\n\t\t\t\t\t\t\tcallback = undefined;\n\t\t\t\t\t\t\txhr.onreadystatechange = jQuery.noop;\n\t\t\t\t\t\t\tif ( isAbort ) {\n\t\t\t\t\t\t\t\tif ( xhr.readyState !== 4 ) {\n\t\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tresponses = {};\n\t\t\t\t\t\t\t\tstatus = xhr.status;\n\t\t\t\t\t\t\t\tif ( typeof xhr.responseText === \"string\" ) {\n\t\t\t\t\t\t\t\t\tresponses.text = xhr.responseText;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tstatusText = xhr.statusText;\n\t\t\t\t\t\t\t\t} catch( e ) {\n\t\t\t\t\t\t\t\t\tstatusText = \"\";\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( !status && options.isLocal && !options.crossDomain ) {\n\t\t\t\t\t\t\t\t\tstatus = responses.text ? 200 : 404;\n\t\t\t\t\t\t\t\t} else if ( status === 1223 ) {\n\t\t\t\t\t\t\t\t\tstatus = 204;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( responses ) {\n\t\t\t\t\t\t\tcomplete( status, statusText, responses, xhr.getAllResponseHeaders() );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\tif ( !options.async ) {\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t} else if ( xhr.readyState === 4 ) {\n\t\t\t\t\t\tsetTimeout( callback );\n\t\t\t\t\t} else {\n\t\t\t\t\t\txhr.onreadystatechange = xhrCallbacks[ id ] = callback;\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tabort: function() {\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tcallback( undefined, true );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t});\n}\nfunction createStandardXHR() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch( e ) {}\n}\n\nfunction createActiveXHR() {\n\ttry {\n\t\treturn new window.ActiveXObject( \"Microsoft.XMLHTTP\" );\n\t} catch( e ) {}\n}\njQuery.ajaxSetup({\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /(?:java|ecma)script/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n});\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t\ts.global = false;\n\t}\n});\njQuery.ajaxTransport( \"script\", function(s) {\n\tif ( s.crossDomain ) {\n\n\t\tvar script,\n\t\t\thead = document.head || jQuery(\"head\")[0] || document.documentElement;\n\n\t\treturn {\n\n\t\t\tsend: function( _, callback ) {\n\n\t\t\t\tscript = document.createElement(\"script\");\n\n\t\t\t\tscript.async = true;\n\n\t\t\t\tif ( s.scriptCharset ) {\n\t\t\t\t\tscript.charset = s.scriptCharset;\n\t\t\t\t}\n\n\t\t\t\tscript.src = s.url;\n\t\t\t\tscript.onload = script.onreadystatechange = function( _, isAbort ) {\n\n\t\t\t\t\tif ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {\n\t\t\t\t\t\tscript.onload = script.onreadystatechange = null;\n\t\t\t\t\t\tif ( script.parentNode ) {\n\t\t\t\t\t\t\tscript.parentNode.removeChild( script );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tscript = null;\n\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\tcallback( 200, \"success\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\thead.insertBefore( script, head.firstChild );\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( script ) {\n\t\t\t\t\tscript.onload( undefined, true );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n});\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\njQuery.ajaxSetup({\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n});\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" && !( s.contentType || \"\" ).indexOf(\"application/x-www-form-urlencoded\") && rjsonp.test( s.data ) && \"data\"\n\t\t);\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\t\tcallbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\t\ts.converters[\"script json\"] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\t\ts.dataTypes[ 0 ] = \"json\";\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\t\tjqXHR.always(function() {\n\t\t\twindow[ callbackName ] = overwritten;\n\t\t\tif ( s[ callbackName ] ) {\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\t\t\tif ( responseContainer && jQuery.isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t});\n\t\treturn \"script\";\n\t}\n});\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\tcontext = context || document;\n\n\tvar parsed = rsingleTag.exec( data ),\n\t\tscripts = !keepScripts && [];\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[1] ) ];\n\t}\n\n\tparsed = jQuery.buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\nvar _load = jQuery.fn.load;\n\njQuery.fn.load = function( url, params, callback ) {\n\tif ( typeof url !== \"string\" && _load ) {\n\t\treturn _load.apply( this, arguments );\n\t}\n\n\tvar selector, response, type,\n\t\tself = this,\n\t\toff = url.indexOf(\" \");\n\n\tif ( off >= 0 ) {\n\t\tselector = jQuery.trim( url.slice( off, url.length ) );\n\t\turl = url.slice( 0, off );\n\t}\n\tif ( jQuery.isFunction( params ) ) {\n\t\tcallback = params;\n\t\tparams = undefined;\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: type,\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t}).done(function( responseText ) {\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\t\t\t\tjQuery(\"<div>\").append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\t\t\t\tresponseText );\n\n\t\t}).complete( callback && function( jqXHR, status ) {\n\t\t\tself.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t});\n\t}\n\n\treturn this;\n};\n\n\n\n\njQuery.expr.filters.animated = function( elem ) {\n\treturn jQuery.grep(jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t}).length;\n};\n\n\n\n\n\nvar docElem = window.document.documentElement;\n\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ?\n\t\telem :\n\t\telem.nodeType === 9 ?\n\t\t\telem.defaultView || elem.parentWindow :\n\t\t\tfalse;\n}\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\tjQuery.inArray(\"auto\", [ curCSSTop, curCSSLeft ] ) > -1;\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\t\t\toptions = options.call( elem, i, curOffset );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend({\n\toffset: function( options ) {\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each(function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t});\n\t\t}\n\n\t\tvar docElem, win,\n\t\t\tbox = { top: 0, left: 0 },\n\t\t\telem = this[ 0 ],\n\t\t\tdoc = elem && elem.ownerDocument;\n\n\t\tif ( !doc ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdocElem = doc.documentElement;\n\t\tif ( !jQuery.contains( docElem, elem ) ) {\n\t\t\treturn box;\n\t\t}\n\t\tif ( typeof elem.getBoundingClientRect !== strundefined ) {\n\t\t\tbox = elem.getBoundingClientRect();\n\t\t}\n\t\twin = getWindow( doc );\n\t\treturn {\n\t\t\ttop: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),\n\t\t\tleft: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )\n\t\t};\n\t},\n\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset,\n\t\t\tparentOffset = { top: 0, left: 0 },\n\t\t\telem = this[ 0 ];\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\t\t\toffset = elem.getBoundingClientRect();\n\t\t} else {\n\t\t\toffsetParent = this.offsetParent();\n\t\t\toffset = this.offset();\n\t\t\tif ( !jQuery.nodeName( offsetParent[ 0 ], \"html\" ) ) {\n\t\t\t\tparentOffset = offsetParent.offset();\n\t\t\t}\n\t\t\tparentOffset.top  += jQuery.css( offsetParent[ 0 ], \"borderTopWidth\", true );\n\t\t\tparentOffset.left += jQuery.css( offsetParent[ 0 ], \"borderLeftWidth\", true );\n\t\t}\n\t\treturn {\n\t\t\ttop:  offset.top  - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true)\n\t\t};\n\t},\n\n\toffsetParent: function() {\n\t\treturn this.map(function() {\n\t\t\tvar offsetParent = this.offsetParent || docElem;\n\n\t\t\twhile ( offsetParent && ( !jQuery.nodeName( offsetParent, \"html\" ) && jQuery.css( offsetParent, \"position\" ) === \"static\" ) ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\t\t\treturn offsetParent || docElem;\n\t\t});\n\t}\n});\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = /Y/.test( prop );\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\t\t\tvar win = getWindow( elem );\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? (prop in win) ? win[ prop ] :\n\t\t\t\t\twin.document.documentElement[ method ] :\n\t\t\t\t\telem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : jQuery( win ).scrollLeft(),\n\t\t\t\t\ttop ? val : jQuery( win ).scrollTop()\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length, null );\n\t};\n});\njQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n});\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name }, function( defaultExtra, funcName ) {\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( jQuery.isWindow( elem ) ) {\n\t\t\t\t\treturn elem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable, null );\n\t\t};\n\t});\n});\njQuery.fn.size = function() {\n\treturn this.length;\n};\n\njQuery.fn.andSelf = jQuery.fn.addBack;\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t});\n}\n\n\n\n\nvar\n\t_jQuery = window.jQuery,\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\nif ( typeof noGlobal === strundefined ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n\n\n\nreturn jQuery;\n\n}));\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/ajax/jsonp.js",
    "content": "define([\n\t\"../core\",\n\t\"./var/nonce\",\n\t\"./var/rquery\",\n\t\"../ajax\"\n], function( jQuery, nonce, rquery ) {\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\njQuery.ajaxSetup({\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n});\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" && !( s.contentType || \"\" ).indexOf(\"application/x-www-form-urlencoded\") && rjsonp.test( s.data ) && \"data\"\n\t\t);\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\t\tcallbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\t\ts.converters[\"script json\"] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\t\ts.dataTypes[ 0 ] = \"json\";\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\t\tjqXHR.always(function() {\n\t\t\twindow[ callbackName ] = overwritten;\n\t\t\tif ( s[ callbackName ] ) {\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\t\t\tif ( responseContainer && jQuery.isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t});\n\t\treturn \"script\";\n\t}\n});\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/ajax/load.js",
    "content": "define([\n\t\"../core\",\n\t\"../core/parseHTML\",\n\t\"../ajax\",\n\t\"../traversing\",\n\t\"../manipulation\",\n\t\"../selector\",\n\t\"../event/alias\"\n], function( jQuery ) {\nvar _load = jQuery.fn.load;\n\njQuery.fn.load = function( url, params, callback ) {\n\tif ( typeof url !== \"string\" && _load ) {\n\t\treturn _load.apply( this, arguments );\n\t}\n\n\tvar selector, response, type,\n\t\tself = this,\n\t\toff = url.indexOf(\" \");\n\n\tif ( off >= 0 ) {\n\t\tselector = jQuery.trim( url.slice( off, url.length ) );\n\t\turl = url.slice( 0, off );\n\t}\n\tif ( jQuery.isFunction( params ) ) {\n\t\tcallback = params;\n\t\tparams = undefined;\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: type,\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t}).done(function( responseText ) {\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\t\t\t\tjQuery(\"<div>\").append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\t\t\t\tresponseText );\n\n\t\t}).complete( callback && function( jqXHR, status ) {\n\t\t\tself.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t});\n\t}\n\n\treturn this;\n};\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/ajax/parseJSON.js",
    "content": "define([\n\t\"../core\"\n], function( jQuery ) {\n\nvar rvalidtokens = /(,)|(\\[|{)|(}|])|\"(?:[^\"\\\\\\r\\n]|\\\\[\"\\\\\\/bfnrt]|\\\\u[\\da-fA-F]{4})*\"\\s*:?|true|false|null|-?(?!0\\d)\\d+(?:\\.\\d+|)(?:[eE][+-]?\\d+|)/g;\n\njQuery.parseJSON = function( data ) {\n\tif ( window.JSON && window.JSON.parse ) {\n\t\treturn window.JSON.parse( data + \"\" );\n\t}\n\n\tvar requireNonComma,\n\t\tdepth = null,\n\t\tstr = jQuery.trim( data + \"\" );\n\treturn str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) {\n\t\tif ( requireNonComma && comma ) {\n\t\t\tdepth = 0;\n\t\t}\n\t\tif ( depth === 0 ) {\n\t\t\treturn token;\n\t\t}\n\t\trequireNonComma = open || comma;\n\t\tdepth += !close - !open;\n\t\treturn \"\";\n\t}) ) ?\n\t\t( Function( \"return \" + str ) )() :\n\t\tjQuery.error( \"Invalid JSON: \" + data );\n};\n\nreturn jQuery.parseJSON;\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/ajax/parseXML.js",
    "content": "define([\n\t\"../core\"\n], function( jQuery ) {\njQuery.parseXML = function( data ) {\n\tvar xml, tmp;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\ttry {\n\t\tif ( window.DOMParser ) { // Standard\n\t\t\ttmp = new DOMParser();\n\t\t\txml = tmp.parseFromString( data, \"text/xml\" );\n\t\t} else { // IE\n\t\t\txml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n\t\t\txml.async = \"false\";\n\t\t\txml.loadXML( data );\n\t\t}\n\t} catch( e ) {\n\t\txml = undefined;\n\t}\n\tif ( !xml || !xml.documentElement || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\nreturn jQuery.parseXML;\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/ajax/script.js",
    "content": "define([\n\t\"../core\",\n\t\"../ajax\"\n], function( jQuery ) {\njQuery.ajaxSetup({\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /(?:java|ecma)script/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n});\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t\ts.global = false;\n\t}\n});\njQuery.ajaxTransport( \"script\", function(s) {\n\tif ( s.crossDomain ) {\n\n\t\tvar script,\n\t\t\thead = document.head || jQuery(\"head\")[0] || document.documentElement;\n\n\t\treturn {\n\n\t\t\tsend: function( _, callback ) {\n\n\t\t\t\tscript = document.createElement(\"script\");\n\n\t\t\t\tscript.async = true;\n\n\t\t\t\tif ( s.scriptCharset ) {\n\t\t\t\t\tscript.charset = s.scriptCharset;\n\t\t\t\t}\n\n\t\t\t\tscript.src = s.url;\n\t\t\t\tscript.onload = script.onreadystatechange = function( _, isAbort ) {\n\n\t\t\t\t\tif ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {\n\t\t\t\t\t\tscript.onload = script.onreadystatechange = null;\n\t\t\t\t\t\tif ( script.parentNode ) {\n\t\t\t\t\t\t\tscript.parentNode.removeChild( script );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tscript = null;\n\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\tcallback( 200, \"success\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\thead.insertBefore( script, head.firstChild );\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( script ) {\n\t\t\t\t\tscript.onload( undefined, true );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n});\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/ajax/var/nonce.js",
    "content": "define([\n\t\"../../core\"\n], function( jQuery ) {\n\treturn jQuery.now();\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/ajax/var/rquery.js",
    "content": "define(function() {\n\treturn (/\\?/);\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/ajax/xhr.js",
    "content": "define([\n\t\"../core\",\n\t\"../var/support\",\n\t\"../ajax\"\n], function( jQuery, support ) {\njQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ?\n\tfunction() {\n\t\treturn !this.isLocal &&\n\t\t\t/^(get|post|head|put|delete|options)$/i.test( this.type ) &&\n\n\t\t\tcreateStandardXHR() || createActiveXHR();\n\t} :\n\tcreateStandardXHR;\n\nvar xhrId = 0,\n\txhrCallbacks = {},\n\txhrSupported = jQuery.ajaxSettings.xhr();\nif ( window.ActiveXObject ) {\n\tjQuery( window ).on( \"unload\", function() {\n\t\tfor ( var key in xhrCallbacks ) {\n\t\t\txhrCallbacks[ key ]( undefined, true );\n\t\t}\n\t});\n}\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nxhrSupported = support.ajax = !!xhrSupported;\nif ( xhrSupported ) {\n\n\tjQuery.ajaxTransport(function( options ) {\n\t\tif ( !options.crossDomain || support.cors ) {\n\n\t\t\tvar callback;\n\n\t\t\treturn {\n\t\t\t\tsend: function( headers, complete ) {\n\t\t\t\t\tvar i,\n\t\t\t\t\t\txhr = options.xhr(),\n\t\t\t\t\t\tid = ++xhrId;\n\t\t\t\t\txhr.open( options.type, options.url, options.async, options.username, options.password );\n\t\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t\t}\n\t\t\t\t\tif ( !options.crossDomain && !headers[\"X-Requested-With\"] ) {\n\t\t\t\t\t\theaders[\"X-Requested-With\"] = \"XMLHttpRequest\";\n\t\t\t\t\t}\n\t\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\t\tif ( headers[ i ] !== undefined ) {\n\t\t\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] + \"\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\txhr.send( ( options.hasContent && options.data ) || null );\n\t\t\t\t\tcallback = function( _, isAbort ) {\n\t\t\t\t\t\tvar status, statusText, responses;\n\t\t\t\t\t\tif ( callback && ( isAbort || xhr.readyState === 4 ) ) {\n\t\t\t\t\t\t\tdelete xhrCallbacks[ id ];\n\t\t\t\t\t\t\tcallback = undefined;\n\t\t\t\t\t\t\txhr.onreadystatechange = jQuery.noop;\n\t\t\t\t\t\t\tif ( isAbort ) {\n\t\t\t\t\t\t\t\tif ( xhr.readyState !== 4 ) {\n\t\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tresponses = {};\n\t\t\t\t\t\t\t\tstatus = xhr.status;\n\t\t\t\t\t\t\t\tif ( typeof xhr.responseText === \"string\" ) {\n\t\t\t\t\t\t\t\t\tresponses.text = xhr.responseText;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\tstatusText = xhr.statusText;\n\t\t\t\t\t\t\t\t} catch( e ) {\n\t\t\t\t\t\t\t\t\tstatusText = \"\";\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( !status && options.isLocal && !options.crossDomain ) {\n\t\t\t\t\t\t\t\t\tstatus = responses.text ? 200 : 404;\n\t\t\t\t\t\t\t\t} else if ( status === 1223 ) {\n\t\t\t\t\t\t\t\t\tstatus = 204;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( responses ) {\n\t\t\t\t\t\t\tcomplete( status, statusText, responses, xhr.getAllResponseHeaders() );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\tif ( !options.async ) {\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t} else if ( xhr.readyState === 4 ) {\n\t\t\t\t\t\tsetTimeout( callback );\n\t\t\t\t\t} else {\n\t\t\t\t\t\txhr.onreadystatechange = xhrCallbacks[ id ] = callback;\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tabort: function() {\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tcallback( undefined, true );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t});\n}\nfunction createStandardXHR() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch( e ) {}\n}\n\nfunction createActiveXHR() {\n\ttry {\n\t\treturn new window.ActiveXObject( \"Microsoft.XMLHTTP\" );\n\t} catch( e ) {}\n}\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/ajax.js",
    "content": "define([\n\t\"./core\",\n\t\"./var/rnotwhite\",\n\t\"./ajax/var/nonce\",\n\t\"./ajax/var/rquery\",\n\t\"./core/init\",\n\t\"./ajax/parseJSON\",\n\t\"./ajax/parseXML\",\n\t\"./deferred\"\n], function( jQuery, rnotwhite, nonce, rquery ) {\n\nvar\n\tajaxLocParts,\n\tajaxLocation,\n\n\trhash = /#.*$/,\n\trts = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/mg, // IE leaves an \\r character at EOL\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\trurl = /^([\\w.+-]+:)(?:\\/\\/(?:[^\\/?#]*@|)([^\\/?#:]*)(?::(\\d+)|)|)/,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\tallTypes = \"*/\".concat(\"*\");\ntry {\n\tajaxLocation = location.href;\n} catch( e ) {\n\tajaxLocation = document.createElement( \"a\" );\n\tajaxLocation.href = \"\";\n\tajaxLocation = ajaxLocation.href;\n}\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\nfunction addToPrefiltersOrTransports( structure ) {\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\t\t\twhile ( (dataType = dataTypes[i++]) ) {\n\t\t\t\tif ( dataType.charAt( 0 ) === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).unshift( func );\n\t\t\t\t} else {\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t});\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\nfunction ajaxExtend( target, src ) {\n\tvar deep, key,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\tvar firstDataType, ct, finalDataType, type,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader(\"Content-Type\");\n\t\t}\n\t}\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\t\tdataTypes = s.dataTypes.slice();\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ( conv !== true ) {\n\t\t\t\t\tif ( conv && s[ \"throws\" ] ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn { state: \"parsererror\", error: conv ? e : \"No conversion from \" + prev + \" to \" + current };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend({\n\tactive: 0,\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: ajaxLocation,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /xml/,\n\t\t\thtml: /html/,\n\t\t\tjson: /json/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\t\tconverters: {\n\t\t\t\"* text\": String,\n\t\t\t\"text html\": true,\n\t\t\t\"text json\": jQuery.parseJSON,\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\tajax: function( url, options ) {\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\t\toptions = options || {};\n\n\t\tvar // Cross-domain detection vars\n\t\t\tparts,\n\t\t\ti,\n\t\t\tcacheURL,\n\t\t\tresponseHeadersString,\n\t\t\ttimeoutTimer,\n\t\t\tfireGlobals,\n\n\t\t\ttransport,\n\t\t\tresponseHeaders,\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\t\t\tcallbackContext = s.context || s,\n\t\t\tglobalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\tjQuery.event,\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks(\"once memory\"),\n\t\t\tstatusCode = s.statusCode || {},\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\t\t\tstate = 0,\n\t\t\tstrAbort = \"canceled\",\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( state === 2 ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( (match = rheaders.exec( responseHeadersString )) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match;\n\t\t\t\t},\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn state === 2 ? responseHeadersString : null;\n\t\t\t\t},\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tvar lname = name.toLowerCase();\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\tname = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\t\tdeferred.promise( jqXHR ).complete = completeDeferred.add;\n\t\tjqXHR.success = jqXHR.done;\n\t\tjqXHR.error = jqXHR.fail;\n\t\ts.url = ( ( url || s.url || ajaxLocation ) + \"\" ).replace( rhash, \"\" ).replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\t\ts.type = options.method || options.type || s.method || s.type;\n\t\ts.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().match( rnotwhite ) || [ \"\" ];\n\t\tif ( s.crossDomain == null ) {\n\t\t\tparts = rurl.exec( s.url.toLowerCase() );\n\t\t\ts.crossDomain = !!( parts &&\n\t\t\t\t( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||\n\t\t\t\t\t( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) !==\n\t\t\t\t\t\t( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) )\n\t\t\t);\n\t\t}\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\t\tif ( state === 2 ) {\n\t\t\treturn jqXHR;\n\t\t}\n\t\tfireGlobals = s.global;\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger(\"ajaxStart\");\n\t\t}\n\t\ts.type = s.type.toUpperCase();\n\t\ts.hasContent = !rnoContent.test( s.type );\n\t\tcacheURL = s.url;\n\t\tif ( !s.hasContent ) {\n\t\t\tif ( s.data ) {\n\t\t\t\tcacheURL = ( s.url += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data );\n\t\t\t\tdelete s.data;\n\t\t\t}\n\t\t\tif ( s.cache === false ) {\n\t\t\t\ts.url = rts.test( cacheURL ) ?\n\t\t\t\t\tcacheURL.replace( rts, \"$1_=\" + nonce++ ) :\n\t\t\t\t\tcacheURL + ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + nonce++;\n\t\t\t}\n\t\t}\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\t\tif ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n\t\t\treturn jqXHR.abort();\n\t\t}\n\t\tstrAbort = \"abort\";\n\t\tfor ( i in { success: 1, error: 1, complete: 1 } ) {\n\t\t\tjqXHR[ i ]( s[ i ] );\n\t\t}\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = setTimeout(function() {\n\t\t\t\t\tjqXHR.abort(\"timeout\");\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tstate = 1;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tdone( -1, e );\n\t\t\t\t} else {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\t\t\tif ( state === 2 ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tstate = 2;\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\tclearTimeout( timeoutTimer );\n\t\t\t}\n\t\t\ttransport = undefined;\n\t\t\tresponseHeadersString = headers || \"\";\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\t\t\tif ( isSuccess ) {\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"Last-Modified\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"etag\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger(\"ajaxStop\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\treturn jQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t});\n\t};\n});\njQuery.each( [ \"ajaxStart\", \"ajaxStop\", \"ajaxComplete\", \"ajaxError\", \"ajaxSuccess\", \"ajaxSend\" ], function( i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n});\n\nreturn jQuery;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/attributes/attr.js",
    "content": "define([\n\t\"../core\",\n\t\"../var/rnotwhite\",\n\t\"../var/strundefined\",\n\t\"../core/access\",\n\t\"./support\",\n\t\"./val\",\n\t\"../selector\"\n], function( jQuery, rnotwhite, strundefined, access, support ) {\n\nvar nodeHook, boolHook,\n\tattrHandle = jQuery.expr.attrHandle,\n\truseDefault = /^(?:checked|selected)$/i,\n\tgetSetAttribute = support.getSetAttribute,\n\tgetSetInput = support.input;\n\njQuery.fn.extend({\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tattr: function( elem, name, value ) {\n\t\tvar hooks, ret,\n\t\t\tnType = elem.nodeType;\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( typeof elem.getAttribute === strundefined ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\tname = name.toLowerCase();\n\t\t\thooks = jQuery.attrHooks[ name ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\n\t\t\t} else if ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t} else if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ) {\n\t\t\treturn ret;\n\n\t\t} else {\n\t\t\tret = jQuery.find.attr( elem, name );\n\t\t\treturn ret == null ?\n\t\t\t\tundefined :\n\t\t\t\tret;\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name, propName,\n\t\t\ti = 0,\n\t\t\tattrNames = value && value.match( rnotwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( (name = attrNames[i++]) ) {\n\t\t\t\tpropName = jQuery.propFix[ name ] || name;\n\t\t\t\tif ( jQuery.expr.match.bool.test( name ) ) {\n\t\t\t\t\tif ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\telem[ jQuery.camelCase( \"default-\" + name ) ] =\n\t\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tjQuery.attr( elem, name, \"\" );\n\t\t\t\t}\n\n\t\t\t\telem.removeAttribute( getSetAttribute ? name : propName );\n\t\t\t}\n\t\t}\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" && jQuery.nodeName(elem, \"input\") ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n\t\t\telem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );\n\t\t} else {\n\t\t\telem[ jQuery.camelCase( \"default-\" + name ) ] = elem[ name ] = true;\n\t\t}\n\n\t\treturn name;\n\t}\n};\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?\n\t\tfunction( elem, name, isXML ) {\n\t\t\tvar ret, handle;\n\t\t\tif ( !isXML ) {\n\t\t\t\thandle = attrHandle[ name ];\n\t\t\t\tattrHandle[ name ] = ret;\n\t\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\t\tname.toLowerCase() :\n\t\t\t\t\tnull;\n\t\t\t\tattrHandle[ name ] = handle;\n\t\t\t}\n\t\t\treturn ret;\n\t\t} :\n\t\tfunction( elem, name, isXML ) {\n\t\t\tif ( !isXML ) {\n\t\t\t\treturn elem[ jQuery.camelCase( \"default-\" + name ) ] ?\n\t\t\t\t\tname.toLowerCase() :\n\t\t\t\t\tnull;\n\t\t\t}\n\t\t};\n});\nif ( !getSetInput || !getSetAttribute ) {\n\tjQuery.attrHooks.value = {\n\t\tset: function( elem, value, name ) {\n\t\t\tif ( jQuery.nodeName( elem, \"input\" ) ) {\n\t\t\t\telem.defaultValue = value;\n\t\t\t} else {\n\t\t\t\treturn nodeHook && nodeHook.set( elem, value, name );\n\t\t\t}\n\t\t}\n\t};\n}\nif ( !getSetAttribute ) {\n\tnodeHook = {\n\t\tset: function( elem, value, name ) {\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( !ret ) {\n\t\t\t\telem.setAttributeNode(\n\t\t\t\t\t(ret = elem.ownerDocument.createAttribute( name ))\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tret.value = value += \"\";\n\t\t\tif ( name === \"value\" || value === elem.getAttribute( name ) ) {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t};\n\tattrHandle.id = attrHandle.name = attrHandle.coords =\n\t\tfunction( elem, name, isXML ) {\n\t\t\tvar ret;\n\t\t\tif ( !isXML ) {\n\t\t\t\treturn (ret = elem.getAttributeNode( name )) && ret.value !== \"\" ?\n\t\t\t\t\tret.value :\n\t\t\t\t\tnull;\n\t\t\t}\n\t\t};\n\tjQuery.valHooks.button = {\n\t\tget: function( elem, name ) {\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( ret && ret.specified ) {\n\t\t\t\treturn ret.value;\n\t\t\t}\n\t\t},\n\t\tset: nodeHook.set\n\t};\n\tjQuery.attrHooks.contenteditable = {\n\t\tset: function( elem, value, name ) {\n\t\t\tnodeHook.set( elem, value === \"\" ? false : value, name );\n\t\t}\n\t};\n\tjQuery.each([ \"width\", \"height\" ], function( i, name ) {\n\t\tjQuery.attrHooks[ name ] = {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( value === \"\" ) {\n\t\t\t\t\telem.setAttribute( name, \"auto\" );\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\nif ( !support.style ) {\n\tjQuery.attrHooks.style = {\n\t\tget: function( elem ) {\n\t\t\treturn elem.style.cssText || undefined;\n\t\t},\n\t\tset: function( elem, value ) {\n\t\t\treturn ( elem.style.cssText = value + \"\" );\n\t\t}\n\t};\n}\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/attributes/classes.js",
    "content": "define([\n\t\"../core\",\n\t\"../var/rnotwhite\",\n\t\"../var/strundefined\",\n\t\"../core/init\"\n], function( jQuery, rnotwhite, strundefined ) {\n\nvar rclass = /[\\t\\r\\n\\f]/g;\n\njQuery.fn.extend({\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\n\t\tif ( proceed ) {\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\" \"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfinalValue = jQuery.trim( cur );\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j, finalValue,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = arguments.length === 0 || typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\t\tif ( proceed ) {\n\t\t\tclasses = ( value || \"\" ).match( rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) >= 0 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfinalValue = value ? jQuery.trim( cur ) : \"\";\n\t\t\t\t\tif ( elem.className !== finalValue ) {\n\t\t\t\t\t\telem.className = finalValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value;\n\n\t\tif ( typeof stateVal === \"boolean\" && type === \"string\" ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( type === \"string\" ) {\n\t\t\t\tvar className,\n\t\t\t\t\ti = 0,\n\t\t\t\t\tself = jQuery( this ),\n\t\t\t\t\tclassNames = value.match( rnotwhite ) || [];\n\n\t\t\t\twhile ( (className = classNames[ i++ ]) ) {\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if ( type === strundefined || type === \"boolean\" ) {\n\t\t\t\tif ( this.className ) {\n\t\t\t\t\tjQuery._data( this, \"__className__\", this.className );\n\t\t\t\t}\n\t\t\t\tthis.className = this.className || value === false ? \"\" : jQuery._data( this, \"__className__\" ) || \"\";\n\t\t\t}\n\t\t});\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className = \" \" + selector + \" \",\n\t\t\ti = 0,\n\t\t\tl = this.length;\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tif ( this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) >= 0 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n});\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/attributes/prop.js",
    "content": "define([\n\t\"../core\",\n\t\"../core/access\",\n\t\"./support\"\n], function( jQuery, access, support ) {\n\nvar rfocusable = /^(?:input|select|textarea|button|object)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend({\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\tname = jQuery.propFix[ name ] || name;\n\t\treturn this.each(function() {\n\t\t\ttry {\n\t\t\t\tthis[ name ] = undefined;\n\t\t\t\tdelete this[ name ];\n\t\t\t} catch( e ) {}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t},\n\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks, notxml,\n\t\t\tnType = elem.nodeType;\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\tif ( notxml ) {\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\treturn hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?\n\t\t\t\tret :\n\t\t\t\t( elem[ name ] = value );\n\n\t\t} else {\n\t\t\treturn hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ?\n\t\t\t\tret :\n\t\t\t\telem[ name ];\n\t\t}\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\treturn tabindex ?\n\t\t\t\t\tparseInt( tabindex, 10 ) :\n\t\t\t\t\trfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?\n\t\t\t\t\t\t0 :\n\t\t\t\t\t\t-1;\n\t\t\t}\n\t\t}\n\t}\n});\nif ( !support.hrefNormalized ) {\n\tjQuery.each([ \"href\", \"src\" ], function( i, name ) {\n\t\tjQuery.propHooks[ name ] = {\n\t\t\tget: function( elem ) {\n\t\t\t\treturn elem.getAttribute( name, 4 );\n\t\t\t}\n\t\t};\n\t});\n}\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t};\n}\n\njQuery.each([\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n});\nif ( !support.enctype ) {\n\tjQuery.propFix.enctype = \"encoding\";\n}\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/attributes/support.js",
    "content": "define([\n\t\"../var/support\"\n], function( support ) {\n\n(function() {\n\tvar input, div, select, a, opt;\n\tdiv = document.createElement( \"div\" );\n\tdiv.setAttribute( \"className\", \"t\" );\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\ta = div.getElementsByTagName(\"a\")[ 0 ];\n\tselect = document.createElement(\"select\");\n\topt = select.appendChild( document.createElement(\"option\") );\n\tinput = div.getElementsByTagName(\"input\")[ 0 ];\n\n\ta.style.cssText = \"top:1px\";\n\tsupport.getSetAttribute = div.className !== \"t\";\n\tsupport.style = /top/.test( a.getAttribute(\"style\") );\n\tsupport.hrefNormalized = a.getAttribute(\"href\") === \"/a\";\n\tsupport.checkOn = !!input.value;\n\tsupport.optSelected = opt.selected;\n\tsupport.enctype = !!document.createElement(\"form\").enctype;\n\tselect.disabled = true;\n\tsupport.optDisabled = !opt.disabled;\n\tinput = document.createElement( \"input\" );\n\tinput.setAttribute( \"value\", \"\" );\n\tsupport.input = input.getAttribute( \"value\" ) === \"\";\n\tinput.value = \"t\";\n\tinput.setAttribute( \"type\", \"radio\" );\n\tsupport.radioValue = input.value === \"t\";\n})();\n\nreturn support;\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/attributes/val.js",
    "content": "define([\n\t\"../core\",\n\t\"./support\",\n\t\"../core/init\"\n], function( jQuery, support ) {\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend({\n\tval: function( value ) {\n\t\tvar hooks, ret, isFunction,\n\t\t\telem = this[0];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ?\n\t\t\t\t\tret.replace(rreturn, \"\") :\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tisFunction = jQuery.isFunction( value );\n\n\t\treturn this.each(function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\t\t\tif ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\t\t\t\t\tjQuery.trim( jQuery.text( elem ) );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\" || index < 0,\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length,\n\t\t\t\t\ti = index < 0 ?\n\t\t\t\t\t\tmax :\n\t\t\t\t\t\tone ? index : 0;\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\t\t\t\t\t\t\t( support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null ) &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\tif ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\toption.selected = optionSet = true;\n\n\t\t\t\t\t\t} catch ( _ ) {\n\t\t\t\t\t\t\toption.scrollHeight;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\toption.selected = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\n\t\t\t\treturn options;\n\t\t\t}\n\t\t}\n\t}\n});\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n\t\t};\n\t}\n});\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/attributes.js",
    "content": "define([\n\t\"./core\",\n\t\"./attributes/val\",\n\t\"./attributes/attr\",\n\t\"./attributes/prop\",\n\t\"./attributes/classes\"\n], function( jQuery ) {\nreturn jQuery;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/callbacks.js",
    "content": "define([\n\t\"./core\",\n\t\"./var/rnotwhite\"\n], function( jQuery, rnotwhite ) {\nvar optionsCache = {};\nfunction createOptions( options ) {\n\tvar object = optionsCache[ options ] = {};\n\tjQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t});\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\toptions = typeof options === \"string\" ?\n\t\t( optionsCache[ options ] || createOptions( options ) ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\t\tmemory,\n\t\tfired,\n\t\tfiringLength,\n\t\tfiringIndex,\n\t\tfiringStart,\n\t\tlist = [],\n\t\tstack = !options.once && [],\n\t\tfire = function( data ) {\n\t\t\tmemory = options.memory && data;\n\t\t\tfired = true;\n\t\t\tfiringIndex = firingStart || 0;\n\t\t\tfiringStart = 0;\n\t\t\tfiringLength = list.length;\n\t\t\tfiring = true;\n\t\t\tfor ( ; list && firingIndex < firingLength; firingIndex++ ) {\n\t\t\t\tif ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n\t\t\t\t\tmemory = false; // To prevent further calls using add\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfiring = false;\n\t\t\tif ( list ) {\n\t\t\t\tif ( stack ) {\n\t\t\t\t\tif ( stack.length ) {\n\t\t\t\t\t\tfire( stack.shift() );\n\t\t\t\t\t}\n\t\t\t\t} else if ( memory ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t} else {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tself = {\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tvar start = list.length;\n\t\t\t\t\t(function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tvar type = jQuery.type( arg );\n\t\t\t\t\t\t\tif ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && type !== \"string\" ) {\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t})( arguments );\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tfiringLength = list.length;\n\t\t\t\t\t} else if ( memory ) {\n\t\t\t\t\t\tfiringStart = start;\n\t\t\t\t\t\tfire( memory );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tremove: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\t\tvar index;\n\t\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\t\tlist.splice( index, 1 );\n\t\t\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\t\t\tif ( index <= firingLength ) {\n\t\t\t\t\t\t\t\t\tfiringLength--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );\n\t\t\t},\n\t\t\tempty: function() {\n\t\t\t\tlist = [];\n\t\t\t\tfiringLength = 0;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisable: function() {\n\t\t\t\tlist = stack = memory = undefined;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\t\t\tlock: function() {\n\t\t\t\tstack = undefined;\n\t\t\t\tif ( !memory ) {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !stack;\n\t\t\t},\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( list && ( !fired || stack ) ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tstack.push( args );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfire( args );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\nreturn jQuery;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/core/access.js",
    "content": "define([\n\t\"../core\"\n], function( jQuery ) {\nvar access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlength = elems.length,\n\t\tbulk = key == null;\n\tif ( jQuery.type( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\tjQuery.access( elems, fn, i, key[i], true, emptyGet, raw );\n\t\t}\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tfn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn chainable ?\n\t\telems :\n\t\tbulk ?\n\t\t\tfn.call( elems ) :\n\t\t\tlength ? fn( elems[0], key ) : emptyGet;\n};\n\nreturn access;\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/core/init.js",
    "content": "define([\n\t\"../core\",\n\t\"./var/rsingleTag\",\n\t\"../traversing/findFilter\"\n], function( jQuery, rsingleTag ) {\nvar rootjQuery,\n\tdocument = window.document,\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,\n\n\tinit = jQuery.fn.init = function( selector, context ) {\n\t\tvar match, elem;\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\t\t\tif ( match && (match[1] || !context) ) {\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[1],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\t\t\t\t\tif ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\tif ( elem.id !== match[2] ) {\n\t\t\t\t\t\t\treturn rootjQuery.find( selector );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || rootjQuery ).find( selector );\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn typeof rootjQuery.ready !== \"undefined\" ?\n\t\t\t\trootjQuery.ready( selector ) :\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\tif ( selector.selector !== undefined ) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\ninit.prototype = jQuery.fn;\nrootjQuery = jQuery( document );\n\nreturn init;\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/core/parseHTML.js",
    "content": "define([\n\t\"../core\",\n\t\"./var/rsingleTag\",\n\t\"../manipulation\" // buildFragment\n], function( jQuery, rsingleTag ) {\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\tcontext = context || document;\n\n\tvar parsed = rsingleTag.exec( data ),\n\t\tscripts = !keepScripts && [];\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[1] ) ];\n\t}\n\n\tparsed = jQuery.buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\nreturn jQuery.parseHTML;\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/core/ready.js",
    "content": "define([\n\t\"../core\",\n\t\"../core/init\",\n\t\"../deferred\"\n], function( jQuery ) {\nvar readyList;\n\njQuery.fn.ready = function( fn ) {\n\tjQuery.ready.promise().done( fn );\n\n\treturn this;\n};\n\njQuery.extend({\n\tisReady: false,\n\treadyWait: 1,\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\tready: function( wait ) {\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( !document.body ) {\n\t\t\treturn setTimeout( jQuery.ready );\n\t\t}\n\t\tjQuery.isReady = true;\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\t\tif ( jQuery.fn.triggerHandler ) {\n\t\t\tjQuery( document ).triggerHandler( \"ready\" );\n\t\t\tjQuery( document ).off( \"ready\" );\n\t\t}\n\t}\n});\n\nfunction detach() {\n\tif ( document.addEventListener ) {\n\t\tdocument.removeEventListener( \"DOMContentLoaded\", completed, false );\n\t\twindow.removeEventListener( \"load\", completed, false );\n\n\t} else {\n\t\tdocument.detachEvent( \"onreadystatechange\", completed );\n\t\twindow.detachEvent( \"onload\", completed );\n\t}\n}\n\nfunction completed() {\n\tif ( document.addEventListener || event.type === \"load\" || document.readyState === \"complete\" ) {\n\t\tdetach();\n\t\tjQuery.ready();\n\t}\n}\n\njQuery.ready.promise = function( obj ) {\n\tif ( !readyList ) {\n\n\t\treadyList = jQuery.Deferred();\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\tsetTimeout( jQuery.ready );\n\t\t} else if ( document.addEventListener ) {\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", completed, false );\n\t\t\twindow.addEventListener( \"load\", completed, false );\n\t\t} else {\n\t\t\tdocument.attachEvent( \"onreadystatechange\", completed );\n\t\t\twindow.attachEvent( \"onload\", completed );\n\t\t\tvar top = false;\n\n\t\t\ttry {\n\t\t\t\ttop = window.frameElement == null && document.documentElement;\n\t\t\t} catch(e) {}\n\n\t\t\tif ( top && top.doScroll ) {\n\t\t\t\t(function doScrollCheck() {\n\t\t\t\t\tif ( !jQuery.isReady ) {\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\ttop.doScroll(\"left\");\n\t\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t\treturn setTimeout( doScrollCheck, 50 );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdetach();\n\t\t\t\t\t\tjQuery.ready();\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t}\n\t\t}\n\t}\n\treturn readyList.promise( obj );\n};\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/core/var/rsingleTag.js",
    "content": "define(function() {\n\treturn (/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/);\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/core.js",
    "content": "define([\n\t\"./var/deletedIds\",\n\t\"./var/slice\",\n\t\"./var/concat\",\n\t\"./var/push\",\n\t\"./var/indexOf\",\n\t\"./var/class2type\",\n\t\"./var/toString\",\n\t\"./var/hasOwn\",\n\t\"./var/support\"\n], function( deletedIds, slice, concat, push, indexOf, class2type, toString, hasOwn, support ) {\n\nvar\n\tversion = \"@VERSION\",\n\tjQuery = function( selector, context ) {\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([\\da-z])/gi,\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\n\njQuery.fn = jQuery.prototype = {\n\tjquery: version,\n\n\tconstructor: jQuery,\n\tselector: \"\",\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\tget: function( num ) {\n\t\treturn num != null ?\n\t\t\t( num < 0 ? this[ num + this.length ] : this[ num ] ) :\n\t\t\tslice.call( this );\n\t},\n\tpushStack: function( elems ) {\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\t\tret.prevObject = this;\n\t\tret.context = this.context;\n\t\treturn ret;\n\t},\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\tpush: push,\n\tsort: deletedIds.sort,\n\tsplice: deletedIds.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar src, copyIsArray, copy, name, options, clone,\n\t\ttarget = arguments[0] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\tif ( (options = arguments[ i ]) != null ) {\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn target;\n};\n\njQuery.extend({\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray || function( obj ) {\n\t\treturn jQuery.type(obj) === \"array\";\n\t},\n\n\tisWindow: function( obj ) {\n\t\t/* jshint eqeqeq: false */\n\t\treturn obj != null && obj == obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\t\treturn !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\tvar key;\n\t\tif ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\tif ( obj.constructor &&\n\t\t\t\t!hasOwn.call(obj, \"constructor\") &&\n\t\t\t\t!hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\treturn false;\n\t\t}\n\t\tif ( support.ownLast ) {\n\t\t\tfor ( key in obj ) {\n\t\t\t\treturn hasOwn.call( obj, key );\n\t\t\t}\n\t\t}\n\t\tfor ( key in obj ) {}\n\n\t\treturn key === undefined || hasOwn.call( obj, key );\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn obj + \"\";\n\t\t}\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ toString.call(obj) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\tglobalEval: function( data ) {\n\t\tif ( data && jQuery.trim( data ) ) {\n\t\t\t( window.execScript || function( data ) {\n\t\t\t\twindow[ \"eval\" ].call( window, data );\n\t\t\t} )( data );\n\t\t}\n\t},\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\teach: function( obj, callback, args ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = obj.length,\n\t\t\tisArray = isArraylike( obj );\n\n\t\tif ( args ) {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArraylike( Object(arr) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\tvar len;\n\n\t\tif ( arr ) {\n\t\t\tif ( indexOf ) {\n\t\t\t\treturn indexOf.call( arr, elem, i );\n\t\t\t}\n\n\t\t\tlen = arr.length;\n\t\t\ti = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tif ( i in arr && arr[ i ] === elem ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn -1;\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\twhile ( j < len ) {\n\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t}\n\t\tif ( len !== len ) {\n\t\t\twhile ( second[j] !== undefined ) {\n\t\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t\t}\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\tmap: function( elems, callback, arg ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tisArray = isArraylike( elems ),\n\t\t\tret = [];\n\t\tif ( isArray ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn concat.apply( [], ret );\n\t},\n\tguid: 1,\n\tproxy: function( fn, context ) {\n\t\tvar args, proxy, tmp;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\t\targs = slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t\t};\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\tnow: function() {\n\t\treturn +( new Date() );\n\t},\n\tsupport: support\n});\njQuery.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\nfunction isArraylike( obj ) {\n\tvar length = obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( type === \"function\" || jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\tif ( obj.nodeType === 1 && length ) {\n\t\treturn true;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\n\nreturn jQuery;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/css/addGetHookIf.js",
    "content": "define(function() {\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\treturn {\n\t\tget: function() {\n\t\t\tvar condition = conditionFn();\n\n\t\t\tif ( condition == null ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( condition ) {\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\treturn (this.get = hookFn).apply( this, arguments );\n\t\t}\n\t};\n}\n\nreturn addGetHookIf;\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/css/curCSS.js",
    "content": "define([\n\t\"exports\",\n\t\"../core\",\n\t\"./var/rnumnonpx\",\n\t\"./var/rmargin\",\n\t\"../selector\" // contains\n], function( exports, jQuery, rnumnonpx, rmargin ) {\n\nvar getStyles, curCSS,\n\trposition = /^(top|right|bottom|left)$/;\n\nif ( window.getComputedStyle ) {\n\tgetStyles = function( elem ) {\n\t\treturn elem.ownerDocument.defaultView.getComputedStyle( elem, null );\n\t};\n\n\tcurCSS = function( elem, name, computed ) {\n\t\tvar width, minWidth, maxWidth, ret,\n\t\t\tstyle = elem.style;\n\n\t\tcomputed = computed || getStyles( elem );\n\t\tret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;\n\n\t\tif ( computed ) {\n\n\t\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\tret = jQuery.style( elem, name );\n\t\t\t}\n\t\t\tif ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\t\t\t\twidth = style.width;\n\t\t\t\tminWidth = style.minWidth;\n\t\t\t\tmaxWidth = style.maxWidth;\n\t\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\t\tret = computed.width;\n\t\t\t\tstyle.width = width;\n\t\t\t\tstyle.minWidth = minWidth;\n\t\t\t\tstyle.maxWidth = maxWidth;\n\t\t\t}\n\t\t}\n\t\treturn ret === undefined ?\n\t\t\tret :\n\t\t\tret + \"\";\n\t};\n} else if ( document.documentElement.currentStyle ) {\n\tgetStyles = function( elem ) {\n\t\treturn elem.currentStyle;\n\t};\n\n\tcurCSS = function( elem, name, computed ) {\n\t\tvar left, rs, rsLeft, ret,\n\t\t\tstyle = elem.style;\n\n\t\tcomputed = computed || getStyles( elem );\n\t\tret = computed ? computed[ name ] : undefined;\n\t\tif ( ret == null && style && style[ name ] ) {\n\t\t\tret = style[ name ];\n\t\t}\n\t\tif ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {\n\t\t\tleft = style.left;\n\t\t\trs = elem.runtimeStyle;\n\t\t\trsLeft = rs && rs.left;\n\t\t\tif ( rsLeft ) {\n\t\t\t\trs.left = elem.currentStyle.left;\n\t\t\t}\n\t\t\tstyle.left = name === \"fontSize\" ? \"1em\" : ret;\n\t\t\tret = style.pixelLeft + \"px\";\n\t\t\tstyle.left = left;\n\t\t\tif ( rsLeft ) {\n\t\t\t\trs.left = rsLeft;\n\t\t\t}\n\t\t}\n\t\treturn ret === undefined ?\n\t\t\tret :\n\t\t\tret + \"\" || \"auto\";\n\t};\n}\n\nexports.getStyles = getStyles;\nexports.curCSS = curCSS;\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/css/defaultDisplay.js",
    "content": "define([\n\t\"../core\",\n\t\"../manipulation\" // appendTo\n], function( jQuery ) {\n\nvar iframe,\n\telemdisplay = {};\nfunction actualDisplay( name, doc ) {\n\tvar style,\n\t\telem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),\n\t\tdisplay = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?\n\t\t\tstyle.display : jQuery.css( elem[ 0 ], \"display\" );\n\telem.detach();\n\n\treturn display;\n}\n\nfunction defaultDisplay( nodeName ) {\n\tvar doc = document,\n\t\tdisplay = elemdisplay[ nodeName ];\n\n\tif ( !display ) {\n\t\tdisplay = actualDisplay( nodeName, doc );\n\t\tif ( display === \"none\" || !display ) {\n\t\t\tiframe = (iframe || jQuery( \"<iframe frameborder='0' width='0' height='0'/>\" )).appendTo( doc.documentElement );\n\t\t\tdoc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document;\n\t\t\tdoc.write();\n\t\t\tdoc.close();\n\n\t\t\tdisplay = actualDisplay( nodeName, doc );\n\t\t\tiframe.detach();\n\t\t}\n\t\telemdisplay[ nodeName ] = display;\n\t}\n\n\treturn display;\n}\n\nreturn defaultDisplay;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/css/hiddenVisibleSelectors.js",
    "content": "define([\n\t\"../core\",\n\t\"./support\",\n\t\"../selector\",\n\t\"../css\"\n], function( jQuery, support ) {\n\njQuery.expr.filters.hidden = function( elem ) {\n\treturn elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||\n\t\t(!support.reliableHiddenOffsets() &&\n\t\t\t((elem.style && elem.style.display) || jQuery.css( elem, \"display\" )) === \"none\");\n};\n\njQuery.expr.filters.visible = function( elem ) {\n\treturn !jQuery.expr.filters.hidden( elem );\n};\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/css/support.js",
    "content": "define([\n\t\"../core\",\n\t\"../var/support\"\n], function( jQuery, support ) {\n\n(function() {\n\tvar div, style, a, pixelPositionVal, boxSizingReliableVal,\n\t\treliableHiddenOffsetsVal, reliableMarginRightVal;\n\tdiv = document.createElement( \"div\" );\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\ta = div.getElementsByTagName( \"a\" )[ 0 ];\n\tstyle = a && a.style;\n\tif ( !style ) {\n\t\treturn;\n\t}\n\n\tstyle.cssText = \"float:left;opacity:.5\";\n\tsupport.opacity = style.opacity === \"0.5\";\n\tsupport.cssFloat = !!style.cssFloat;\n\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\tsupport.boxSizing = style.boxSizing === \"\" || style.MozBoxSizing === \"\" ||\n\t\tstyle.WebkitBoxSizing === \"\";\n\n\tjQuery.extend(support, {\n\t\treliableHiddenOffsets: function() {\n\t\t\tif ( reliableHiddenOffsetsVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn reliableHiddenOffsetsVal;\n\t\t},\n\n\t\tboxSizingReliable: function() {\n\t\t\tif ( boxSizingReliableVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\n\t\tpixelPosition: function() {\n\t\t\tif ( pixelPositionVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\treliableMarginRight: function() {\n\t\t\tif ( reliableMarginRightVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn reliableMarginRightVal;\n\t\t}\n\t});\n\n\tfunction computeStyleTests() {\n\t\tvar div, body, container, contents;\n\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\t\tif ( !body || !body.style ) {\n\t\t\treturn;\n\t\t}\n\t\tdiv = document.createElement( \"div\" );\n\t\tcontainer = document.createElement( \"div\" );\n\t\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\t\tbody.appendChild( container ).appendChild( div );\n\n\t\tdiv.style.cssText =\n\t\t\t\"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;\" +\n\t\t\t\"box-sizing:border-box;display:block;margin-top:1%;top:1%;\" +\n\t\t\t\"border:1px;padding:1px;width:4px;position:absolute\";\n\t\tpixelPositionVal = boxSizingReliableVal = false;\n\t\treliableMarginRightVal = true;\n\t\tif ( window.getComputedStyle ) {\n\t\t\tpixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== \"1%\";\n\t\t\tboxSizingReliableVal =\n\t\t\t\t( window.getComputedStyle( div, null ) || { width: \"4px\" } ).width === \"4px\";\n\t\t\tcontents = div.appendChild( document.createElement( \"div\" ) );\n\t\t\tcontents.style.cssText = div.style.cssText =\n\t\t\t\t\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;\" +\n\t\t\t\t\"box-sizing:content-box;display:block;margin:0;border:0;padding:0\";\n\t\t\tcontents.style.marginRight = contents.style.width = \"0\";\n\t\t\tdiv.style.width = \"1px\";\n\n\t\t\treliableMarginRightVal =\n\t\t\t\t!parseFloat( ( window.getComputedStyle( contents, null ) || {} ).marginRight );\n\t\t}\n\t\tdiv.innerHTML = \"<table><tr><td></td><td>t</td></tr></table>\";\n\t\tcontents = div.getElementsByTagName( \"td\" );\n\t\tcontents[ 0 ].style.cssText = \"margin:0;border:0;padding:0;display:none\";\n\t\treliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;\n\t\tif ( reliableHiddenOffsetsVal ) {\n\t\t\tcontents[ 0 ].style.display = \"\";\n\t\t\tcontents[ 1 ].style.display = \"none\";\n\t\t\treliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0;\n\t\t}\n\n\t\tbody.removeChild( container );\n\t}\n\n})();\n\nreturn support;\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/css/swap.js",
    "content": "define([\n\t\"../core\"\n], function( jQuery ) {\njQuery.swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\nreturn jQuery.swap;\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/css/var/cssExpand.js",
    "content": "define(function() {\n\treturn [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/css/var/isHidden.js",
    "content": "define([\n\t\"../../core\",\n\t\"../../selector\"\n], function( jQuery ) {\n\n\treturn function( elem, el ) {\n\t\telem = el || elem;\n\t\treturn jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n\t};\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/css/var/rmargin.js",
    "content": "define(function() {\n\treturn (/^margin/);\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/css/var/rnumnonpx.js",
    "content": "define([\n\t\"../../var/pnum\"\n], function( pnum ) {\n\treturn new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/css.js",
    "content": "define([\n\t\"./core\",\n\t\"./var/pnum\",\n\t\"./core/access\",\n\t\"./css/var/rmargin\",\n\t\"./css/var/rnumnonpx\",\n\t\"./css/var/cssExpand\",\n\t\"./css/var/isHidden\",\n\t\"./css/curCSS\",\n\t\"./css/defaultDisplay\",\n\t\"./css/addGetHookIf\",\n\t\"./css/support\",\n\n\t\"./core/init\",\n\t\"./css/swap\",\n\t\"./core/ready\",\n\t\"./selector\" // contains\n], function( jQuery, pnum, access, rmargin, rnumnonpx, cssExpand, isHidden,\n\tcurCSS, defaultDisplay, addGetHookIf, support ) {\n\nvar\n\tgetStyles = curCSS.getStyles,\n\tralpha = /alpha\\([^)]*\\)/i,\n\tropacity = /opacity\\s*=\\s*([^)]*)/,\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trnumsplit = new RegExp( \"^(\" + pnum + \")(.*)$\", \"i\" ),\n\trrelNum = new RegExp( \"^([+-])=(\" + pnum + \")\", \"i\" ),\n\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t},\n\n\tcssPrefixes = [ \"Webkit\", \"O\", \"Moz\", \"ms\" ];\ncurCSS = curCSS.curCSS;\nfunction vendorPropName( style, name ) {\n\tif ( name in style ) {\n\t\treturn name;\n\t}\n\tvar capName = name.charAt(0).toUpperCase() + name.slice(1),\n\t\torigName = name,\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in style ) {\n\t\t\treturn name;\n\t\t}\n\t}\n\n\treturn origName;\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem, hidden,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\" );\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\t\t\tif ( !values[ index ] && display === \"none\" ) {\n\t\t\t\telem.style.display = \"\";\n\t\t\t}\n\t\t\tif ( elem.style.display === \"\" && isHidden( elem ) ) {\n\t\t\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\", defaultDisplay(elem.nodeName) );\n\t\t\t}\n\t\t} else {\n\t\t\thidden = isHidden( elem );\n\n\t\t\tif ( display && display !== \"none\" || !hidden ) {\n\t\t\t\tjQuery._data( elem, \"olddisplay\", hidden ? display : jQuery.css( elem, \"display\" ) );\n\t\t\t}\n\t\t}\n\t}\n\tfor ( index = 0; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( !show || elem.style.display === \"none\" || elem.style.display === \"\" ) {\n\t\t\telem.style.display = show ? values[ index ] || \"\" : \"none\";\n\t\t}\n\t}\n\n\treturn elements;\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\tvar matches = rnumsplit.exec( value );\n\treturn matches ?\n\t\tMath.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {\n\tvar i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n\t\t4 :\n\t\tname === \"width\" ? 1 : 0,\n\n\t\tval = 0;\n\n\tfor ( ; i < 4; i += 2 ) {\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += jQuery.css( elem, extra + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\tif ( isBorderBox ) {\n\t\t\tif ( extra === \"content\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\t\t\tif ( extra !== \"margin\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t} else {\n\t\t\tval += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\tvar valueIsBorderBox = true,\n\t\tval = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n\t\tstyles = getStyles( elem ),\n\t\tisBorderBox = support.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\tif ( val <= 0 || val == null ) {\n\t\tval = curCSS( elem, name, styles );\n\t\tif ( val < 0 || val == null ) {\n\t\t\tval = elem.style[ name ];\n\t\t}\n\t\tif ( rnumnonpx.test(val) ) {\n\t\t\treturn val;\n\t\t}\n\t\tvalueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] );\n\t\tval = parseFloat( val ) || 0;\n\t}\n\treturn ( val +\n\t\taugmentWidthOrHeight(\n\t\t\telem,\n\t\t\tname,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles\n\t\t)\n\t) + \"px\";\n}\n\njQuery.extend({\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\tcssNumber: {\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\tcssProps: {\n\t\t\"float\": support.cssFloat ? \"cssFloat\" : \"styleFloat\"\n\t},\n\tstyle: function( elem, name, value, extra ) {\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\t\tvar ret, type, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style;\n\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\t\t\tif ( type === \"string\" && (ret = rrelNum.exec( value )) ) {\n\t\t\t\tvalue = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n\t\t\t\tvalue += \"px\";\n\t\t\t}\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf(\"background\") === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\t\t\tif ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {\n\t\t\t\ttry {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t} else {\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar num, val, hooks,\n\t\t\torigName = jQuery.camelCase( name );\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || jQuery.isNumeric( num ) ? num || 0 : val;\n\t\t}\n\t\treturn val;\n\t}\n});\n\njQuery.each([ \"height\", \"width\" ], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) && elem.offsetWidth === 0 ?\n\t\t\t\t\tjQuery.swap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t\t}) :\n\t\t\t\t\tgetWidthOrHeight( elem, name, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar styles = extra && getStyles( elem );\n\t\t\treturn setPositiveNumber( elem, value, extra ?\n\t\t\t\taugmentWidthOrHeight(\n\t\t\t\t\telem,\n\t\t\t\t\tname,\n\t\t\t\t\textra,\n\t\t\t\t\tsupport.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\t\tstyles\n\t\t\t\t) : 0\n\t\t\t);\n\t\t}\n\t};\n});\n\nif ( !support.opacity ) {\n\tjQuery.cssHooks.opacity = {\n\t\tget: function( elem, computed ) {\n\t\t\treturn ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || \"\" ) ?\n\t\t\t\t( 0.01 * parseFloat( RegExp.$1 ) ) + \"\" :\n\t\t\t\tcomputed ? \"1\" : \"\";\n\t\t},\n\n\t\tset: function( elem, value ) {\n\t\t\tvar style = elem.style,\n\t\t\t\tcurrentStyle = elem.currentStyle,\n\t\t\t\topacity = jQuery.isNumeric( value ) ? \"alpha(opacity=\" + value * 100 + \")\" : \"\",\n\t\t\t\tfilter = currentStyle && currentStyle.filter || style.filter || \"\";\n\t\t\tstyle.zoom = 1;\n\t\t\tif ( ( value >= 1 || value === \"\" ) &&\n\t\t\t\t\tjQuery.trim( filter.replace( ralpha, \"\" ) ) === \"\" &&\n\t\t\t\t\tstyle.removeAttribute ) {\n\t\t\t\tstyle.removeAttribute( \"filter\" );\n\t\t\t\tif ( value === \"\" || currentStyle && !currentStyle.filter ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t\tstyle.filter = ralpha.test( filter ) ?\n\t\t\t\tfilter.replace( ralpha, opacity ) :\n\t\t\t\tfilter + \" \" + opacity;\n\t\t}\n\t};\n}\n\njQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn jQuery.swap( elem, { \"display\": \"inline-block\" },\n\t\t\t\tcurCSS, [ elem, \"marginRight\" ] );\n\t\t}\n\t}\n);\njQuery.each({\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\t\t\t\tparts = typeof value === \"string\" ? value.split(\" \") : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( !rmargin.test( prefix ) ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n});\n\njQuery.fn.extend({\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( jQuery.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t},\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( isHidden( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t});\n\t}\n});\n\nreturn jQuery;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/data.js",
    "content": "define([\n\t\"./core\",\n\t\"./var/deletedIds\",\n\t\"./data/support\",\n\t\"./data/accepts\"\n], function( jQuery, deletedIds, support ) {\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /([A-Z])/g;\n\nfunction dataAttr( elem, key, data ) {\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\n\t\tvar name = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\t\tdata === \"false\" ? false :\n\t\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\t\t\tjQuery.data( elem, key, data );\n\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\n\treturn data;\n}\nfunction isEmptyDataObject( obj ) {\n\tvar name;\n\tfor ( name in obj ) {\n\t\tif ( name === \"data\" && jQuery.isEmptyObject( obj[name] ) ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( name !== \"toJSON\" ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nfunction internalData( elem, name, data, pvt /* Internal Use Only */ ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar ret, thisCache,\n\t\tinternalKey = jQuery.expando,\n\t\tisNode = elem.nodeType,\n\t\tcache = isNode ? jQuery.cache : elem,\n\t\tid = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;\n\tif ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === \"string\" ) {\n\t\treturn;\n\t}\n\n\tif ( !id ) {\n\t\tif ( isNode ) {\n\t\t\tid = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;\n\t\t} else {\n\t\t\tid = internalKey;\n\t\t}\n\t}\n\n\tif ( !cache[ id ] ) {\n\t\tcache[ id ] = isNode ? {} : { toJSON: jQuery.noop };\n\t}\n\tif ( typeof name === \"object\" || typeof name === \"function\" ) {\n\t\tif ( pvt ) {\n\t\t\tcache[ id ] = jQuery.extend( cache[ id ], name );\n\t\t} else {\n\t\t\tcache[ id ].data = jQuery.extend( cache[ id ].data, name );\n\t\t}\n\t}\n\n\tthisCache = cache[ id ];\n\tif ( !pvt ) {\n\t\tif ( !thisCache.data ) {\n\t\t\tthisCache.data = {};\n\t\t}\n\n\t\tthisCache = thisCache.data;\n\t}\n\n\tif ( data !== undefined ) {\n\t\tthisCache[ jQuery.camelCase( name ) ] = data;\n\t}\n\tif ( typeof name === \"string\" ) {\n\t\tret = thisCache[ name ];\n\t\tif ( ret == null ) {\n\t\t\tret = thisCache[ jQuery.camelCase( name ) ];\n\t\t}\n\t} else {\n\t\tret = thisCache;\n\t}\n\n\treturn ret;\n}\n\nfunction internalRemoveData( elem, name, pvt ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar thisCache, i,\n\t\tisNode = elem.nodeType,\n\t\tcache = isNode ? jQuery.cache : elem,\n\t\tid = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\tif ( !cache[ id ] ) {\n\t\treturn;\n\t}\n\n\tif ( name ) {\n\n\t\tthisCache = pvt ? cache[ id ] : cache[ id ].data;\n\n\t\tif ( thisCache ) {\n\t\t\tif ( !jQuery.isArray( name ) ) {\n\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\tname = [ name ];\n\t\t\t\t} else {\n\t\t\t\t\tname = jQuery.camelCase( name );\n\t\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\t\tname = [ name ];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tname = name.split(\" \");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tname = name.concat( jQuery.map( name, jQuery.camelCase ) );\n\t\t\t}\n\n\t\t\ti = name.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete thisCache[ name[i] ];\n\t\t\t}\n\t\t\tif ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\tif ( !pvt ) {\n\t\tdelete cache[ id ].data;\n\t\tif ( !isEmptyDataObject( cache[ id ] ) ) {\n\t\t\treturn;\n\t\t}\n\t}\n\tif ( isNode ) {\n\t\tjQuery.cleanData( [ elem ], true );\n\t/* jshint eqeqeq: false */\n\t} else if ( support.deleteExpando || cache != cache.window ) {\n\t\t/* jshint eqeqeq: true */\n\t\tdelete cache[ id ];\n\t} else {\n\t\tcache[ id ] = null;\n\t}\n}\n\njQuery.extend({\n\tcache: {},\n\tnoData: {\n\t\t\"applet \": true,\n\t\t\"embed \": true,\n\t\t\"object \": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n\t},\n\n\thasData: function( elem ) {\n\t\telem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n\t\treturn !!elem && !isEmptyDataObject( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name );\n\t},\n\t_data: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data, true );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name, true );\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[0],\n\t\t\tattrs = elem && elem.attributes;\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = jQuery.data( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !jQuery._data( elem, \"parsedAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice(5) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tjQuery._data( elem, \"parsedAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery.data( this, key );\n\t\t\t});\n\t\t}\n\n\t\treturn arguments.length > 1 ?\n\t\t\tthis.each(function() {\n\t\t\t\tjQuery.data( this, key, value );\n\t\t\t}) :\n\t\t\telem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeData( this, key );\n\t\t});\n\t}\n});\n\nreturn jQuery;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/deferred.js",
    "content": "define([\n\t\"./core\",\n\t\"./var/slice\",\n\t\"./callbacks\"\n], function( jQuery, slice ) {\n\njQuery.extend({\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tthen: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\t\t\t\t\treturn jQuery.Deferred(function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\t\t\t\t\tvar fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];\n\t\t\t\t\t\t\tdeferred[ tuple[1] ](function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject )\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t}).promise();\n\t\t\t\t},\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\t\tpromise.pipe = promise.then;\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 3 ];\n\t\t\tpromise[ tuple[1] ] = list.add;\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(function() {\n\t\t\t\t\tstate = stateString;\n\t\t\t\t}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n\t\t\t}\n\t\t\tdeferred[ tuple[0] ] = function() {\n\t\t\t\tdeferred[ tuple[0] + \"With\" ]( this === deferred ? promise : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tdeferred[ tuple[0] + \"With\" ] = list.fireWith;\n\t\t});\n\t\tpromise.promise( deferred );\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\t\treturn deferred;\n\t},\n\twhen: function( subordinate /* , ..., subordinateN */ ) {\n\t\tvar i = 0,\n\t\t\tresolveValues = slice.call( arguments ),\n\t\t\tlength = resolveValues.length,\n\t\t\tremaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\t\t\tdeferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\t\t\tupdateFunc = function( i, contexts, values ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tcontexts[ i ] = this;\n\t\t\t\t\tvalues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( values === progressValues ) {\n\t\t\t\t\t\tdeferred.notifyWith( contexts, values );\n\n\t\t\t\t\t} else if ( !(--remaining) ) {\n\t\t\t\t\t\tdeferred.resolveWith( contexts, values );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\t\t\tprogressValues, progressContexts, resolveContexts;\n\t\tif ( length > 1 ) {\n\t\t\tprogressValues = new Array( length );\n\t\t\tprogressContexts = new Array( length );\n\t\t\tresolveContexts = new Array( length );\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n\t\t\t\t\tresolveValues[ i ].promise()\n\t\t\t\t\t\t.done( updateFunc( i, resolveContexts, resolveValues ) )\n\t\t\t\t\t\t.fail( deferred.reject )\n\t\t\t\t\t\t.progress( updateFunc( i, progressContexts, progressValues ) );\n\t\t\t\t} else {\n\t\t\t\t\t--remaining;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif ( !remaining ) {\n\t\t\tdeferred.resolveWith( resolveContexts, resolveValues );\n\t\t}\n\n\t\treturn deferred.promise();\n\t}\n});\n\nreturn jQuery;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/deprecated.js",
    "content": "define([\n\t\"./core\",\n\t\"./traversing\"\n], function( jQuery ) {\njQuery.fn.size = function() {\n\treturn this.length;\n};\n\njQuery.fn.andSelf = jQuery.fn.addBack;\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/dimensions.js",
    "content": "define([\n\t\"./core\",\n\t\"./core/access\",\n\t\"./css\"\n], function( jQuery, access ) {\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name }, function( defaultExtra, funcName ) {\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( jQuery.isWindow( elem ) ) {\n\t\t\t\t\treturn elem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable, null );\n\t\t};\n\t});\n});\n\nreturn jQuery;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/effects/Tween.js",
    "content": "define([\n\t\"../core\",\n\t\"../css\"\n], function( jQuery ) {\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || \"swing\";\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\tif ( tween.elem[ tween.prop ] != null &&\n\t\t\t\t(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t}\n};\n\njQuery.fx = Tween.prototype.init;\njQuery.fx.step = {};\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/effects/animatedSelector.js",
    "content": "define([\n\t\"../core\",\n\t\"../selector\",\n\t\"../effects\"\n], function( jQuery ) {\n\njQuery.expr.filters.animated = function( elem ) {\n\treturn jQuery.grep(jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t}).length;\n};\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/effects/support.js",
    "content": "define([\n\t\"../var/strundefined\",\n\t\"../var/support\"\n], function( strundefined, support ) {\n\n(function() {\n\tvar shrinkWrapBlocksVal;\n\n\tsupport.shrinkWrapBlocks = function() {\n\t\tif ( shrinkWrapBlocksVal != null ) {\n\t\t\treturn shrinkWrapBlocksVal;\n\t\t}\n\t\tshrinkWrapBlocksVal = false;\n\t\tvar div, body, container;\n\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\t\tif ( !body || !body.style ) {\n\t\t\treturn;\n\t\t}\n\t\tdiv = document.createElement( \"div\" );\n\t\tcontainer = document.createElement( \"div\" );\n\t\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\t\tbody.appendChild( container ).appendChild( div );\n\t\tif ( typeof div.style.zoom !== strundefined ) {\n\t\t\tdiv.style.cssText =\n\t\t\t\t\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;\" +\n\t\t\t\t\"box-sizing:content-box;display:block;margin:0;border:0;\" +\n\t\t\t\t\"padding:1px;width:1px;zoom:1\";\n\t\t\tdiv.appendChild( document.createElement( \"div\" ) ).style.width = \"5px\";\n\t\t\tshrinkWrapBlocksVal = div.offsetWidth !== 3;\n\t\t}\n\n\t\tbody.removeChild( container );\n\n\t\treturn shrinkWrapBlocksVal;\n\t};\n\n})();\n\nreturn support;\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/effects.js",
    "content": "define([\n\t\"./core\",\n\t\"./var/pnum\",\n\t\"./css/var/cssExpand\",\n\t\"./css/var/isHidden\",\n\t\"./css/defaultDisplay\",\n\t\"./effects/support\",\n\n\t\"./core/init\",\n\t\"./effects/Tween\",\n\t\"./queue\",\n\t\"./css\",\n\t\"./deferred\",\n\t\"./traversing\"\n], function( jQuery, pnum, cssExpand, isHidden, defaultDisplay, support ) {\n\nvar\n\tfxNow, timerId,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trfxnum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" ),\n\trrun = /queueHooks$/,\n\tanimationPrefilters = [ defaultPrefilter ],\n\ttweeners = {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value ),\n\t\t\t\ttarget = tween.cur(),\n\t\t\t\tparts = rfxnum.exec( value ),\n\t\t\t\tunit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\t\t\t\tstart = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +target ) &&\n\t\t\t\t\trfxnum.exec( jQuery.css( tween.elem, prop ) ),\n\t\t\t\tscale = 1,\n\t\t\t\tmaxIterations = 20;\n\n\t\t\tif ( start && start[ 3 ] !== unit ) {\n\t\t\t\tunit = unit || start[ 3 ];\n\t\t\t\tparts = parts || [];\n\t\t\t\tstart = +target || 1;\n\n\t\t\t\tdo {\n\t\t\t\t\tscale = scale || \".5\";\n\t\t\t\t\tstart = start / scale;\n\t\t\t\t\tjQuery.style( tween.elem, prop, start + unit );\n\t\t\t\t} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );\n\t\t\t}\n\t\t\tif ( parts ) {\n\t\t\t\tstart = tween.start = +start || +target || 0;\n\t\t\t\ttween.unit = unit;\n\t\t\t\ttween.end = parts[ 1 ] ?\n\t\t\t\t\tstart + ( parts[ 1 ] + 1 ) * parts[ 2 ] :\n\t\t\t\t\t+parts[ 2 ];\n\t\t\t}\n\n\t\t\treturn tween;\n\t\t} ]\n\t};\nfunction createFxNow() {\n\tsetTimeout(function() {\n\t\tfxNow = undefined;\n\t});\n\treturn ( fxNow = jQuery.now() );\n}\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\tattrs = { height: type },\n\t\ti = 0;\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4 ; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( tweeners[ prop ] || [] ).concat( tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( (tween = collection[ index ].call( animation, prop, value )) ) {\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\t/* jshint validthis: true */\n\tvar prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHidden( elem ),\n\t\tdataShow = jQuery._data( elem, \"fxshow\" );\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always(function() {\n\t\t\tanim.always(function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\tif ( elem.nodeType === 1 && ( \"height\" in props || \"width\" in props ) ) {\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\t\tcheckDisplay = display === \"none\" ?\n\t\t\tjQuery._data( elem, \"olddisplay\" ) || defaultDisplay( elem.nodeName ) : display;\n\n\t\tif ( checkDisplay === \"inline\" && jQuery.css( elem, \"float\" ) === \"none\" ) {\n\t\t\tif ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === \"inline\" ) {\n\t\t\t\tstyle.display = \"inline-block\";\n\t\t\t} else {\n\t\t\t\tstyle.zoom = 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tif ( !support.shrinkWrapBlocks() ) {\n\t\t\tanim.always(function() {\n\t\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t\t});\n\t\t}\n\t}\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.exec( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t} else {\n\t\t\tdisplay = undefined;\n\t\t}\n\t}\n\n\tif ( !jQuery.isEmptyObject( orig ) ) {\n\t\tif ( dataShow ) {\n\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\thidden = dataShow.hidden;\n\t\t\t}\n\t\t} else {\n\t\t\tdataShow = jQuery._data( elem, \"fxshow\", {} );\n\t\t}\n\t\tif ( toggle ) {\n\t\t\tdataShow.hidden = !hidden;\n\t\t}\n\t\tif ( hidden ) {\n\t\t\tjQuery( elem ).show();\n\t\t} else {\n\t\t\tanim.done(function() {\n\t\t\t\tjQuery( elem ).hide();\n\t\t\t});\n\t\t}\n\t\tanim.done(function() {\n\t\t\tvar prop;\n\t\t\tjQuery._removeData( elem, \"fxshow\" );\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t}\n\t\t});\n\t\tfor ( prop in orig ) {\n\t\t\ttween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\n\t\t\tif ( !( prop in dataShow ) ) {\n\t\t\t\tdataShow[ prop ] = tween.start;\n\t\t\t\tif ( hidden ) {\n\t\t\t\t\ttween.end = tween.start;\n\t\t\t\t\ttween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} else if ( (display === \"none\" ? defaultDisplay( elem.nodeName ) : display) === \"inline\" ) {\n\t\tstyle.display = display;\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\tfor ( index in props ) {\n\t\tname = jQuery.camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( jQuery.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = animationPrefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\t\t\tdelete tick.elem;\n\t\t}),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ]);\n\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t} else {\n\t\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tanimation = deferred.promise({\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, { specialEasing: {} }, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length ; index++ ) {\n\t\tresult = animationPrefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( jQuery.isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t})\n\t);\n\treturn animation.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\ttweener: function( props, callback ) {\n\t\tif ( jQuery.isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.split(\" \");\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length ; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\ttweeners[ prop ] = tweeners[ prop ] || [];\n\t\t\ttweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tanimationPrefilters.unshift( callback );\n\t\t} else {\n\t\t\tanimationPrefilters.push( callback );\n\t\t}\n\t}\n});\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tjQuery.isFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n\t};\n\n\topt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n\t\topt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend({\n\tfadeTo: function( speed, to, easing, callback ) {\n\t\treturn this.filter( isHidden ).css( \"opacity\", 0 ).show()\n\t\t\t.end().animate({ opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\t\t\t\tif ( empty || jQuery._data( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = jQuery._data( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t});\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tvar index,\n\t\t\t\tdata = jQuery._data( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\t\t\tdata.finish = true;\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\t\t\tdelete data.finish;\n\t\t});\n\t}\n});\n\njQuery.each([ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n});\njQuery.each({\n\tslideDown: genFx(\"show\"),\n\tslideUp: genFx(\"hide\"),\n\tslideToggle: genFx(\"toggle\"),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n});\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ttimers = jQuery.timers,\n\t\ti = 0;\n\n\tfxNow = jQuery.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tif ( timer() ) {\n\t\tjQuery.fx.start();\n\t} else {\n\t\tjQuery.timers.pop();\n\t}\n};\n\njQuery.fx.interval = 13;\n\njQuery.fx.start = function() {\n\tif ( !timerId ) {\n\t\ttimerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );\n\t}\n};\n\njQuery.fx.stop = function() {\n\tclearInterval( timerId );\n\ttimerId = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\t_default: 400\n};\n\nreturn jQuery;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/event/alias.js",
    "content": "define([\n\t\"../core\",\n\t\"../event\"\n], function( jQuery ) {\n\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup error contextmenu\").split(\" \"), function( i, name ) {\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n});\n\njQuery.fn.extend({\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t},\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\t\treturn arguments.length === 1 ? this.off( selector, \"**\" ) : this.off( types, selector || \"**\", fn );\n\t}\n});\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/event/support.js",
    "content": "define([\n\t\"../var/support\"\n], function( support ) {\n\n(function() {\n\tvar i, eventName,\n\t\tdiv = document.createElement( \"div\" );\n\tfor ( i in { submit: true, change: true, focusin: true }) {\n\t\teventName = \"on\" + i;\n\n\t\tif ( !(support[ i + \"Bubbles\" ] = eventName in window) ) {\n\t\t\tdiv.setAttribute( eventName, \"t\" );\n\t\t\tsupport[ i + \"Bubbles\" ] = div.attributes[ eventName ].expando === false;\n\t\t}\n\t}\n\tdiv = null;\n})();\n\nreturn support;\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/event.js",
    "content": "define([\n\t\"./core\",\n\t\"./var/strundefined\",\n\t\"./var/rnotwhite\",\n\t\"./var/hasOwn\",\n\t\"./var/slice\",\n\t\"./event/support\",\n\n\t\"./core/init\",\n\t\"./data/accepts\",\n\t\"./selector\"\n], function( jQuery, strundefined, rnotwhite, hasOwn, slice, support ) {\n\nvar rformElems = /^(?:input|select|textarea)$/i,\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,\n\trfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)$/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\t\tvar tmp, events, t, handleObjIn,\n\t\t\tspecial, eventHandle, handleObj,\n\t\t\thandlers, type, namespaces, origType,\n\t\t\telemData = jQuery._data( elem );\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\t\tif ( !(events = elemData.events) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !(eventHandle = elemData.handle) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\t\t\t\treturn typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?\n\t\t\t\t\tjQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n\t\t\t\t\tundefined;\n\t\t\t};\n\t\t\teventHandle.elem = elem;\n\t\t}\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\thandleObj = jQuery.extend({\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join(\".\")\n\t\t\t}, handleObjIn );\n\t\t\tif ( !(handlers = events[ type ]) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\n\t\t\t\t\t} else if ( elem.attachEvent ) {\n\t\t\t\t\t\telem.attachEvent( \"on\" + type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\t\telem = null;\n\t},\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\t\tvar j, handleObj, tmp,\n\t\t\torigCount, t, events,\n\t\t\tspecial, handlers, type,\n\t\t\tnamespaces, origType,\n\t\t\telemData = jQuery.hasData( elem ) && jQuery._data( elem );\n\n\t\tif ( !elemData || !(events = elemData.events) ) {\n\t\t\treturn;\n\t\t}\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[2] && new RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" );\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdelete elemData.handle;\n\t\t\tjQuery._removeData( elem, \"events\" );\n\t\t}\n\t},\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\t\tvar handle, ontype, cur,\n\t\t\tbubbleType, special, tmp, i,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split(\".\") : [];\n\n\t\tcur = tmp = elem = elem || document;\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf(\".\") >= 0 ) {\n\t\t\tnamespaces = type.split(\".\");\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf(\":\") < 0 && \"on\" + type;\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join(\".\");\n\t\tevent.namespace_re = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\t\t\tif ( tmp === (elem.ownerDocument || document) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\t\ti = 0;\n\t\twhile ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\t\t\thandle = ( jQuery._data( cur, \"events\" ) || {} )[ event.type ] && jQuery._data( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && jQuery.acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&\n\t\t\t\tjQuery.acceptData( elem ) ) {\n\t\t\t\tif ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\ttry {\n\t\t\t\t\t\telem[ type ]();\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t}\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\tdispatch: function( event ) {\n\t\tevent = jQuery.event.fix( event );\n\n\t\tvar i, ret, handleObj, matched, j,\n\t\t\thandlerQueue = [],\n\t\t\targs = slice.call( arguments ),\n\t\t\thandlers = ( jQuery._data( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\t\targs[0] = event;\n\t\tevent.delegateTarget = this;\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\t\ti = 0;\n\t\twhile ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {\n\t\t\t\tif ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n\t\t\t\t\t\t\t.apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( (event.result = ret) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar sel, handleObj, matches, i,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\t\tif ( delegateCount && cur.nodeType && (!event.button || event.type !== \"click\") ) {\n\n\t\t\t/* jshint eqeqeq: false */\n\t\t\tfor ( ; cur != this; cur = cur.parentNode || this ) {\n\t\t\t\t/* jshint eqeqeq: true */\n\t\t\t\tif ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== \"click\") ) {\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matches[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatches[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) >= 0 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matches[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push({ elem: cur, handlers: matches });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\t\tvar i, prop, copy,\n\t\t\ttype = event.type,\n\t\t\toriginalEvent = event,\n\t\t\tfixHook = this.fixHooks[ type ];\n\n\t\tif ( !fixHook ) {\n\t\t\tthis.fixHooks[ type ] = fixHook =\n\t\t\t\trmouseEvent.test( type ) ? this.mouseHooks :\n\t\t\t\trkeyEvent.test( type ) ? this.keyHooks :\n\t\t\t\t{};\n\t\t}\n\t\tcopy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n\t\tevent = new jQuery.Event( originalEvent );\n\n\t\ti = copy.length;\n\t\twhile ( i-- ) {\n\t\t\tprop = copy[ i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\t\tif ( !event.target ) {\n\t\t\tevent.target = originalEvent.srcElement || document;\n\t\t}\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\t\tevent.metaKey = !!event.metaKey;\n\n\t\treturn fixHook.filter ? fixHook.filter( event, originalEvent ) : event;\n\t},\n\tprops: \"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n\tfixHooks: {},\n\n\tkeyHooks: {\n\t\tprops: \"char charCode key keyCode\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\t\t\tif ( event.which == null ) {\n\t\t\t\tevent.which = original.charCode != null ? original.charCode : original.keyCode;\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tmouseHooks: {\n\t\tprops: \"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\t\t\tvar body, eventDoc, doc,\n\t\t\t\tbutton = original.button,\n\t\t\t\tfromElement = original.fromElement;\n\t\t\tif ( event.pageX == null && original.clientX != null ) {\n\t\t\t\teventDoc = event.target.ownerDocument || document;\n\t\t\t\tdoc = eventDoc.documentElement;\n\t\t\t\tbody = eventDoc.body;\n\n\t\t\t\tevent.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n\t\t\t\tevent.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );\n\t\t\t}\n\t\t\tif ( !event.relatedTarget && fromElement ) {\n\t\t\t\tevent.relatedTarget = fromElement === event.target ? original.toElement : fromElement;\n\t\t\t}\n\t\t\tif ( !event.which && button !== undefined ) {\n\t\t\t\tevent.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tspecial: {\n\t\tload: {\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.focus();\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( jQuery.nodeName( this, \"input\" ) && this.type === \"checkbox\" && this.click ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\t_default: function( event ) {\n\t\t\t\treturn jQuery.nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tsimulate: function( type, elem, event, bubble ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true,\n\t\t\t\toriginalEvent: {}\n\t\t\t}\n\t\t);\n\t\tif ( bubble ) {\n\t\t\tjQuery.event.trigger( e, null, elem );\n\t\t} else {\n\t\t\tjQuery.event.dispatch.call( elem, e );\n\t\t}\n\t\tif ( e.isDefaultPrevented() ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n};\n\njQuery.removeEvent = document.removeEventListener ?\n\tfunction( elem, type, handle ) {\n\t\tif ( elem.removeEventListener ) {\n\t\t\telem.removeEventListener( type, handle, false );\n\t\t}\n\t} :\n\tfunction( elem, type, handle ) {\n\t\tvar name = \"on\" + type;\n\n\t\tif ( elem.detachEvent ) {\n\t\t\tif ( typeof elem[ name ] === strundefined ) {\n\t\t\t\telem[ name ] = null;\n\t\t\t}\n\n\t\t\telem.detachEvent( name, handle );\n\t\t}\n\t};\n\njQuery.Event = function( src, props ) {\n\tif ( !(this instanceof jQuery.Event) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\t} else {\n\t\tthis.type = src;\n\t}\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\tthis[ jQuery.expando ] = true;\n};\njQuery.Event.prototype = {\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( e.preventDefault ) {\n\t\t\te.preventDefault();\n\t\t} else {\n\t\t\te.returnValue = false;\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( e.stopPropagation ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t\te.cancelBubble = true;\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && e.stopImmediatePropagation ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\njQuery.each({\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\t\t\tif ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n});\nif ( !support.submitBubbles ) {\n\n\tjQuery.event.special.submit = {\n\t\tsetup: function() {\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tjQuery.event.add( this, \"click._submit keypress._submit\", function( e ) {\n\t\t\t\tvar elem = e.target,\n\t\t\t\t\tform = jQuery.nodeName( elem, \"input\" ) || jQuery.nodeName( elem, \"button\" ) ? elem.form : undefined;\n\t\t\t\tif ( form && !jQuery._data( form, \"submitBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( form, \"submit._submit\", function( event ) {\n\t\t\t\t\t\tevent._submit_bubble = true;\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( form, \"submitBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\tpostDispatch: function( event ) {\n\t\t\tif ( event._submit_bubble ) {\n\t\t\t\tdelete event._submit_bubble;\n\t\t\t\tif ( this.parentNode && !event.isTrigger ) {\n\t\t\t\t\tjQuery.event.simulate( \"submit\", this.parentNode, event, true );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tjQuery.event.remove( this, \"._submit\" );\n\t\t}\n\t};\n}\nif ( !support.changeBubbles ) {\n\n\tjQuery.event.special.change = {\n\n\t\tsetup: function() {\n\n\t\t\tif ( rformElems.test( this.nodeName ) ) {\n\t\t\t\tif ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n\t\t\t\t\tjQuery.event.add( this, \"propertychange._change\", function( event ) {\n\t\t\t\t\t\tif ( event.originalEvent.propertyName === \"checked\" ) {\n\t\t\t\t\t\t\tthis._just_changed = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery.event.add( this, \"click._change\", function( event ) {\n\t\t\t\t\t\tif ( this._just_changed && !event.isTrigger ) {\n\t\t\t\t\t\t\tthis._just_changed = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tjQuery.event.simulate( \"change\", this, event, true );\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tjQuery.event.add( this, \"beforeactivate._change\", function( e ) {\n\t\t\t\tvar elem = e.target;\n\n\t\t\t\tif ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, \"changeBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( elem, \"change._change\", function( event ) {\n\t\t\t\t\t\tif ( this.parentNode && !event.isSimulated && !event.isTrigger ) {\n\t\t\t\t\t\t\tjQuery.event.simulate( \"change\", this.parentNode, event, true );\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( elem, \"changeBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\thandle: function( event ) {\n\t\t\tvar elem = event.target;\n\t\t\tif ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== \"radio\" && elem.type !== \"checkbox\") ) {\n\t\t\t\treturn event.handleObj.handler.apply( this, arguments );\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\tjQuery.event.remove( this, \"._change\" );\n\n\t\t\treturn !rformElems.test( this.nodeName );\n\t\t}\n\t};\n}\nif ( !support.focusinBubbles ) {\n\tjQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\t\tvar handler = function( event ) {\n\t\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n\t\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tjQuery._data( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tjQuery._removeData( doc, fix );\n\t\t\t\t} else {\n\t\t\t\t\tjQuery._data( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\njQuery.fn.extend({\n\n\ton: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n\t\tvar type, origFn;\n\t\tif ( typeof types === \"object\" ) {\n\t\t\tif ( typeof selector !== \"string\" ) {\n\t\t\t\tdata = data || selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.on( type, selector, data, types[ type ], one );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( data == null && fn == null ) {\n\t\t\tfn = selector;\n\t\t\tdata = selector = undefined;\n\t\t} else if ( fn == null ) {\n\t\t\tif ( typeof selector === \"string\" ) {\n\t\t\t\tfn = data;\n\t\t\t\tdata = undefined;\n\t\t\t} else {\n\t\t\t\tfn = data;\n\t\t\t\tdata = selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t} else if ( !fn ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( one === 1 ) {\n\t\t\torigFn = fn;\n\t\t\tfn = function( event ) {\n\t\t\t\tjQuery().off( event );\n\t\t\t\treturn origFn.apply( this, arguments );\n\t\t\t};\n\t\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.add( this, types, fn, data, selector );\n\t\t});\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn this.on( types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t});\n\t},\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t});\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[0];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n});\n\nreturn jQuery;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/exports/amd.js",
    "content": "define([\n\t\"../core\"\n], function( jQuery ) {\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t});\n}\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/exports/global.js",
    "content": "define([\n\t\"../core\",\n\t\"../var/strundefined\"\n], function( jQuery, strundefined ) {\n\nvar\n\t_jQuery = window.jQuery,\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\nif ( typeof noGlobal === strundefined ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/intro.js",
    "content": "/*!\n * jQuery JavaScript Library v@VERSION\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: @DATE\n */\n\n(function( global, factory ) {\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n}(typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/jquery.js",
    "content": "define([\n\t\"./core\",\n\t\"./selector\",\n\t\"./traversing\",\n\t\"./callbacks\",\n\t\"./deferred\",\n\t\"./core/ready\",\n\t\"./support\",\n\t\"./data\",\n\t\"./queue\",\n\t\"./queue/delay\",\n\t\"./attributes\",\n\t\"./event\",\n\t\"./event/alias\",\n\t\"./manipulation\",\n\t\"./manipulation/_evalUrl\",\n\t\"./wrap\",\n\t\"./css\",\n\t\"./css/hiddenVisibleSelectors\",\n\t\"./serialize\",\n\t\"./ajax\",\n\t\"./ajax/xhr\",\n\t\"./ajax/script\",\n\t\"./ajax/jsonp\",\n\t\"./ajax/load\",\n\t\"./effects\",\n\t\"./effects/animatedSelector\",\n\t\"./offset\",\n\t\"./dimensions\",\n\t\"./deprecated\",\n\t\"./exports/amd\",\n\t\"./exports/global\"\n], function( jQuery ) {\n\nreturn jQuery;\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/manipulation/_evalUrl.js",
    "content": "define([\n\t\"../ajax\"\n], function( jQuery ) {\n\njQuery._evalUrl = function( url ) {\n\treturn jQuery.ajax({\n\t\turl: url,\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tasync: false,\n\t\tglobal: false,\n\t\t\"throws\": true\n\t});\n};\n\nreturn jQuery._evalUrl;\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/manipulation/support.js",
    "content": "define([\n\t\"../var/support\"\n], function( support ) {\n\n(function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tdiv = document.createElement( \"div\" ),\n\t\tfragment = document.createDocumentFragment();\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\tsupport.leadingWhitespace = div.firstChild.nodeType === 3;\n\tsupport.tbody = !div.getElementsByTagName( \"tbody\" ).length;\n\tsupport.htmlSerialize = !!div.getElementsByTagName( \"link\" ).length;\n\tsupport.html5Clone =\n\t\tdocument.createElement( \"nav\" ).cloneNode( true ).outerHTML !== \"<:nav></:nav>\";\n\tinput.type = \"checkbox\";\n\tinput.checked = true;\n\tfragment.appendChild( input );\n\tsupport.appendChecked = input.checked;\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\tfragment.appendChild( div );\n\tdiv.innerHTML = \"<input type='radio' checked='checked' name='t'/>\";\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\tsupport.noCloneEvent = true;\n\tif ( div.attachEvent ) {\n\t\tdiv.attachEvent( \"onclick\", function() {\n\t\t\tsupport.noCloneEvent = false;\n\t\t});\n\n\t\tdiv.cloneNode( true ).click();\n\t}\n\tif (support.deleteExpando == null) {\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n})();\n\nreturn support;\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/manipulation/var/rcheckableType.js",
    "content": "define(function() {\n\treturn (/^(?:checkbox|radio)$/i);\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/manipulation.js",
    "content": "define([\n\t\"./core\",\n\t\"./var/strundefined\",\n\t\"./var/concat\",\n\t\"./var/push\",\n\t\"./var/deletedIds\",\n\t\"./core/access\",\n\t\"./manipulation/var/rcheckableType\",\n\t\"./manipulation/support\",\n\n\t\"./core/init\",\n\t\"./data/accepts\",\n\t\"./traversing\",\n\t\"./selector\",\n\t\"./event\"\n], function( jQuery, strundefined, concat, push, deletedIds, access, rcheckableType, support ) {\n\nfunction createSafeFragment( document ) {\n\tvar list = nodeNames.split( \"|\" ),\n\t\tsafeFrag = document.createDocumentFragment();\n\n\tif ( safeFrag.createElement ) {\n\t\twhile ( list.length ) {\n\t\t\tsafeFrag.createElement(\n\t\t\t\tlist.pop()\n\t\t\t);\n\t\t}\n\t}\n\treturn safeFrag;\n}\n\nvar nodeNames = \"abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|\" +\n\t\t\"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video\",\n\trinlinejQuery = / jQuery\\d+=\"(?:null|\\d+)\"/g,\n\trnoshimcache = new RegExp(\"<(?:\" + nodeNames + \")[\\\\s/>]\", \"i\"),\n\trleadingWhitespace = /^\\s+/,\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n\trtagName = /<([\\w:]+)/,\n\trtbody = /<tbody/i,\n\trhtml = /<|&#?\\w+;/,\n\trnoInnerhtml = /<(?:script|style|link)/i,\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptType = /^$|\\/(?:java|ecma)script/i,\n\trscriptTypeMasked = /^true\\/(.*)/,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,\n\twrapMap = {\n\t\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\t\tlegend: [ 1, \"<fieldset>\", \"</fieldset>\" ],\n\t\tarea: [ 1, \"<map>\", \"</map>\" ],\n\t\tparam: [ 1, \"<object>\", \"</object>\" ],\n\t\tthead: [ 1, \"<table>\", \"</table>\" ],\n\t\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\t\tcol: [ 2, \"<table><tbody></tbody><colgroup>\", \"</colgroup></table>\" ],\n\t\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\t\t_default: support.htmlSerialize ? [ 0, \"\", \"\" ] : [ 1, \"X<div>\", \"</div>\"  ]\n\t},\n\tsafeFragment = createSafeFragment( document ),\n\tfragmentDiv = safeFragment.appendChild( document.createElement(\"div\") );\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\nfunction getAll( context, tag ) {\n\tvar elems, elem,\n\t\ti = 0,\n\t\tfound = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || \"*\" ) :\n\t\t\ttypeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || \"*\" ) :\n\t\t\tundefined;\n\n\tif ( !found ) {\n\t\tfor ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( !tag || jQuery.nodeName( elem, tag ) ) {\n\t\t\t\tfound.push( elem );\n\t\t\t} else {\n\t\t\t\tjQuery.merge( found, getAll( elem, tag ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn tag === undefined || tag && jQuery.nodeName( context, tag ) ?\n\t\tjQuery.merge( [ context ], found ) :\n\t\tfound;\n}\nfunction fixDefaultChecked( elem ) {\n\tif ( rcheckableType.test( elem.type ) ) {\n\t\telem.defaultChecked = elem.checked;\n\t}\n}\nfunction manipulationTarget( elem, content ) {\n\treturn jQuery.nodeName( elem, \"table\" ) &&\n\t\tjQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ?\n\n\t\telem.getElementsByTagName(\"tbody\")[0] ||\n\t\t\telem.appendChild( elem.ownerDocument.createElement(\"tbody\") ) :\n\t\telem;\n}\nfunction disableScript( elem ) {\n\telem.type = (jQuery.find.attr( elem, \"type\" ) !== null) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tvar match = rscriptTypeMasked.exec( elem.type );\n\tif ( match ) {\n\t\telem.type = match[1];\n\t} else {\n\t\telem.removeAttribute(\"type\");\n\t}\n\treturn elem;\n}\nfunction setGlobalEval( elems, refElements ) {\n\tvar elem,\n\t\ti = 0;\n\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\tjQuery._data( elem, \"globalEval\", !refElements || jQuery._data( refElements[i], \"globalEval\" ) );\n\t}\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n\tif ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n\t\treturn;\n\t}\n\n\tvar type, i, l,\n\t\toldData = jQuery._data( src ),\n\t\tcurData = jQuery._data( dest, oldData ),\n\t\tevents = oldData.events;\n\n\tif ( events ) {\n\t\tdelete curData.handle;\n\t\tcurData.events = {};\n\n\t\tfor ( type in events ) {\n\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t}\n\t\t}\n\t}\n\tif ( curData.data ) {\n\t\tcurData.data = jQuery.extend( {}, curData.data );\n\t}\n}\n\nfunction fixCloneNodeIssues( src, dest ) {\n\tvar nodeName, e, data;\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\tnodeName = dest.nodeName.toLowerCase();\n\tif ( !support.noCloneEvent && dest[ jQuery.expando ] ) {\n\t\tdata = jQuery._data( dest );\n\n\t\tfor ( e in data.events ) {\n\t\t\tjQuery.removeEvent( dest, e, data.handle );\n\t\t}\n\t\tdest.removeAttribute( jQuery.expando );\n\t}\n\tif ( nodeName === \"script\" && dest.text !== src.text ) {\n\t\tdisableScript( dest ).text = src.text;\n\t\trestoreScript( dest );\n\t} else if ( nodeName === \"object\" ) {\n\t\tif ( dest.parentNode ) {\n\t\t\tdest.outerHTML = src.outerHTML;\n\t\t}\n\t\tif ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {\n\t\t\tdest.innerHTML = src.innerHTML;\n\t\t}\n\n\t} else if ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\n\t\tdest.defaultChecked = dest.checked = src.checked;\n\t\tif ( dest.value !== src.value ) {\n\t\t\tdest.value = src.value;\n\t\t}\n\t} else if ( nodeName === \"option\" ) {\n\t\tdest.defaultSelected = dest.selected = src.defaultSelected;\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\njQuery.extend({\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar destElements, node, clone, i, srcElements,\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\tif ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( \"<\" + elem.nodeName + \">\" ) ) {\n\t\t\tclone = elem.cloneNode( true );\n\t\t} else {\n\t\t\tfragmentDiv.innerHTML = elem.outerHTML;\n\t\t\tfragmentDiv.removeChild( clone = fragmentDiv.firstChild );\n\t\t}\n\n\t\tif ( (!support.noCloneEvent || !support.noCloneChecked) &&\n\t\t\t\t(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\t\t\tfor ( i = 0; (node = srcElements[i]) != null; ++i ) {\n\t\t\t\tif ( destElements[i] ) {\n\t\t\t\t\tfixCloneNodeIssues( node, destElements[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0; (node = srcElements[i]) != null; i++ ) {\n\t\t\t\t\tcloneCopyEvent( node, destElements[i] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\tdestElements = srcElements = node = null;\n\t\treturn clone;\n\t},\n\n\tbuildFragment: function( elems, context, scripts, selection ) {\n\t\tvar j, elem, contains,\n\t\t\ttmp, tag, tbody, wrap,\n\t\t\tl = elems.length,\n\t\t\tsafe = createSafeFragment( context ),\n\n\t\t\tnodes = [],\n\t\t\ti = 0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\telem = elems[ i ];\n\n\t\t\tif ( elem || elem === 0 ) {\n\t\t\t\tif ( jQuery.type( elem ) === \"object\" ) {\n\t\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\t\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\t\t\t\t} else {\n\t\t\t\t\ttmp = tmp || safe.appendChild( context.createElement(\"div\") );\n\t\t\t\t\ttag = (rtagName.exec( elem ) || [ \"\", \"\" ])[ 1 ].toLowerCase();\n\t\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\n\t\t\t\t\ttmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, \"<$1></$2>\" ) + wrap[2];\n\t\t\t\t\tj = wrap[0];\n\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t\t}\n\t\t\t\t\tif ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n\t\t\t\t\t\tnodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );\n\t\t\t\t\t}\n\t\t\t\t\tif ( !support.tbody ) {\n\t\t\t\t\t\telem = tag === \"table\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\ttmp.firstChild :\n\t\t\t\t\t\t\twrap[1] === \"<table>\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\t\ttmp :\n\t\t\t\t\t\t\t\t0;\n\n\t\t\t\t\t\tj = elem && elem.childNodes.length;\n\t\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\t\tif ( jQuery.nodeName( (tbody = elem.childNodes[j]), \"tbody\" ) && !tbody.childNodes.length ) {\n\t\t\t\t\t\t\t\telem.removeChild( tbody );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\t\t\t\t\ttmp.textContent = \"\";\n\t\t\t\t\twhile ( tmp.firstChild ) {\n\t\t\t\t\t\ttmp.removeChild( tmp.firstChild );\n\t\t\t\t\t}\n\t\t\t\t\ttmp = safe.lastChild;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif ( tmp ) {\n\t\t\tsafe.removeChild( tmp );\n\t\t}\n\t\tif ( !support.appendChecked ) {\n\t\t\tjQuery.grep( getAll( nodes, \"input\" ), fixDefaultChecked );\n\t\t}\n\n\t\ti = 0;\n\t\twhile ( (elem = nodes[ i++ ]) ) {\n\t\t\tif ( selection && jQuery.inArray( elem, selection ) !== -1 ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\t\t\ttmp = getAll( safe.appendChild( elem ), \"script\" );\n\t\t\tif ( contains ) {\n\t\t\t\tsetGlobalEval( tmp );\n\t\t\t}\n\t\t\tif ( scripts ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (elem = tmp[ j++ ]) ) {\n\t\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\t\tscripts.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttmp = null;\n\n\t\treturn safe;\n\t},\n\n\tcleanData: function( elems, /* internal */ acceptData ) {\n\t\tvar elem, type, id, data,\n\t\t\ti = 0,\n\t\t\tinternalKey = jQuery.expando,\n\t\t\tcache = jQuery.cache,\n\t\t\tdeleteExpando = support.deleteExpando,\n\t\t\tspecial = jQuery.event.special;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( acceptData || jQuery.acceptData( elem ) ) {\n\n\t\t\t\tid = elem[ internalKey ];\n\t\t\t\tdata = id && cache[ id ];\n\n\t\t\t\tif ( data ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( cache[ id ] ) {\n\n\t\t\t\t\t\tdelete cache[ id ];\n\t\t\t\t\t\tif ( deleteExpando ) {\n\t\t\t\t\t\t\tdelete elem[ internalKey ];\n\n\t\t\t\t\t\t} else if ( typeof elem.removeAttribute !== strundefined ) {\n\t\t\t\t\t\t\telem.removeAttribute( internalKey );\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\telem[ internalKey ] = null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdeletedIds.push( id );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\njQuery.fn.extend({\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t});\n\t},\n\n\tprepend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t});\n\t},\n\n\tbefore: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t});\n\t},\n\n\tafter: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t});\n\t},\n\n\tremove: function( selector, keepData /* Internal Use Only */ ) {\n\t\tvar elem,\n\t\t\telems = selector ? jQuery.filter( selector, this ) : this,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\n\t\t\tif ( !keepData && elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem ) );\n\t\t\t}\n\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\tif ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\t\tsetGlobalEval( getAll( elem, \"script\" ) );\n\t\t\t\t}\n\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = this[i]) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t}\n\t\t\twhile ( elem.firstChild ) {\n\t\t\t\telem.removeChild( elem.firstChild );\n\t\t\t}\n\t\t\tif ( elem.options && jQuery.nodeName( elem, \"select\" ) ) {\n\t\t\t\telem.options.length = 0;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map(function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t});\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined ) {\n\t\t\t\treturn elem.nodeType === 1 ?\n\t\t\t\t\telem.innerHTML.replace( rinlinejQuery, \"\" ) :\n\t\t\t\t\tundefined;\n\t\t\t}\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t( support.htmlSerialize || !rnoshimcache.test( value )  ) &&\n\t\t\t\t( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&\n\t\t\t\t!wrapMap[ (rtagName.exec( value ) || [ \"\", \"\" ])[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = value.replace( rxhtmlTag, \"<$1></$2>\" );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor (; i < l; i++ ) {\n\t\t\t\t\t\telem = this[i] || {};\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar arg = arguments[ 0 ];\n\t\tthis.domManip( arguments, function( elem ) {\n\t\t\targ = this.parentNode;\n\n\t\t\tjQuery.cleanData( getAll( this ) );\n\n\t\t\tif ( arg ) {\n\t\t\t\targ.replaceChild( elem, this );\n\t\t\t}\n\t\t});\n\t\treturn arg && (arg.length || arg.nodeType) ? this : this.remove();\n\t},\n\n\tdetach: function( selector ) {\n\t\treturn this.remove( selector, true );\n\t},\n\n\tdomManip: function( args, callback ) {\n\t\targs = concat.apply( [], args );\n\n\t\tvar first, node, hasScripts,\n\t\t\tscripts, doc, fragment,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tset = this,\n\t\t\tiNoClone = l - 1,\n\t\t\tvalue = args[0],\n\t\t\tisFunction = jQuery.isFunction( value );\n\t\tif ( isFunction ||\n\t\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\t\treturn this.each(function( index ) {\n\t\t\t\tvar self = set.eq( index );\n\t\t\t\tif ( isFunction ) {\n\t\t\t\t\targs[0] = value.call( this, index, self.html() );\n\t\t\t\t}\n\t\t\t\tself.domManip( args, callback );\n\t\t\t});\n\t\t}\n\n\t\tif ( l ) {\n\t\t\tfragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );\n\t\t\tfirst = fragment.firstChild;\n\n\t\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\t\tfragment = first;\n\t\t\t}\n\n\t\t\tif ( first ) {\n\t\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\t\thasScripts = scripts.length;\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\tnode = fragment;\n\n\t\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\t\t\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcallback.call( this[i], node, i );\n\t\t\t\t}\n\n\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\t\t\t\t\tjQuery.map( scripts, restoreScript );\n\t\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t\t!jQuery._data( node, \"globalEval\" ) && jQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\t\tif ( node.src ) {\n\t\t\t\t\t\t\t\tif ( jQuery._evalUrl ) {\n\t\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.globalEval( ( node.text || node.textContent || node.innerHTML || \"\" ).replace( rcleanScript, \"\" ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfragment = first = null;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n});\n\njQuery.each({\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\ti = 0,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone(true);\n\t\t\tjQuery( insert[i] )[ original ]( elems );\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\n\nreturn jQuery;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/offset.js",
    "content": "define([\n\t\"./core\",\n\t\"./var/strundefined\",\n\t\"./core/access\",\n\t\"./css/var/rnumnonpx\",\n\t\"./css/curCSS\",\n\t\"./css/addGetHookIf\",\n\t\"./css/support\",\n\n\t\"./core/init\",\n\t\"./css\",\n\t\"./selector\" // contains\n], function( jQuery, strundefined, access, rnumnonpx, curCSS, addGetHookIf, support ) {\ncurCSS = curCSS.curCSS;\n\nvar docElem = window.document.documentElement;\n\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ?\n\t\telem :\n\t\telem.nodeType === 9 ?\n\t\t\telem.defaultView || elem.parentWindow :\n\t\t\tfalse;\n}\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\tjQuery.inArray(\"auto\", [ curCSSTop, curCSSLeft ] ) > -1;\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\t\t\toptions = options.call( elem, i, curOffset );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend({\n\toffset: function( options ) {\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each(function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t});\n\t\t}\n\n\t\tvar docElem, win,\n\t\t\tbox = { top: 0, left: 0 },\n\t\t\telem = this[ 0 ],\n\t\t\tdoc = elem && elem.ownerDocument;\n\n\t\tif ( !doc ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdocElem = doc.documentElement;\n\t\tif ( !jQuery.contains( docElem, elem ) ) {\n\t\t\treturn box;\n\t\t}\n\t\tif ( typeof elem.getBoundingClientRect !== strundefined ) {\n\t\t\tbox = elem.getBoundingClientRect();\n\t\t}\n\t\twin = getWindow( doc );\n\t\treturn {\n\t\t\ttop: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),\n\t\t\tleft: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )\n\t\t};\n\t},\n\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset,\n\t\t\tparentOffset = { top: 0, left: 0 },\n\t\t\telem = this[ 0 ];\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\t\t\toffset = elem.getBoundingClientRect();\n\t\t} else {\n\t\t\toffsetParent = this.offsetParent();\n\t\t\toffset = this.offset();\n\t\t\tif ( !jQuery.nodeName( offsetParent[ 0 ], \"html\" ) ) {\n\t\t\t\tparentOffset = offsetParent.offset();\n\t\t\t}\n\t\t\tparentOffset.top  += jQuery.css( offsetParent[ 0 ], \"borderTopWidth\", true );\n\t\t\tparentOffset.left += jQuery.css( offsetParent[ 0 ], \"borderLeftWidth\", true );\n\t\t}\n\t\treturn {\n\t\t\ttop:  offset.top  - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true)\n\t\t};\n\t},\n\n\toffsetParent: function() {\n\t\treturn this.map(function() {\n\t\t\tvar offsetParent = this.offsetParent || docElem;\n\n\t\t\twhile ( offsetParent && ( !jQuery.nodeName( offsetParent, \"html\" ) && jQuery.css( offsetParent, \"position\" ) === \"static\" ) ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\t\t\treturn offsetParent || docElem;\n\t\t});\n\t}\n});\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = /Y/.test( prop );\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\t\t\tvar win = getWindow( elem );\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? (prop in win) ? win[ prop ] :\n\t\t\t\t\twin.document.documentElement[ method ] :\n\t\t\t\t\telem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : jQuery( win ).scrollLeft(),\n\t\t\t\t\ttop ? val : jQuery( win ).scrollTop()\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length, null );\n\t};\n});\njQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n});\n\nreturn jQuery;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/outro.js",
    "content": "}));\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/queue/delay.js",
    "content": "define([\n\t\"../core\",\n\t\"../queue\",\n\t\"../effects\" // Delay is optional because of this dependency\n], function( jQuery ) {\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\tclearTimeout( timeout );\n\t\t};\n\t});\n};\n\nreturn jQuery.fn.delay;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/queue.js",
    "content": "define([\n\t\"./core\",\n\t\"./deferred\",\n\t\"./callbacks\"\n], function( jQuery ) {\n\njQuery.extend({\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = jQuery._data( elem, type );\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray(data) ) {\n\t\t\t\t\tqueue = jQuery._data( elem, type, jQuery.makeArray(data) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn jQuery._data( elem, key ) || jQuery._data( elem, key, {\n\t\t\tempty: jQuery.Callbacks(\"once memory\").add(function() {\n\t\t\t\tjQuery._removeData( elem, type + \"queue\" );\n\t\t\t\tjQuery._removeData( elem, key );\n\t\t\t})\n\t\t});\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = jQuery._data( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n});\n\nreturn jQuery;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/selector-sizzle.js",
    "content": "define([\n\t\"./core\",\n\t\"sizzle\"\n], function( jQuery, Sizzle ) {\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/selector.js",
    "content": "define([ \"./selector-sizzle\" ]);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/serialize.js",
    "content": "define([\n\t\"./core\",\n\t\"./manipulation/var/rcheckableType\",\n\t\"./core/init\",\n\t\"./traversing\", // filter\n\t\"./attributes/prop\"\n], function( jQuery, rcheckableType ) {\n\nvar r20 = /%20/g,\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( jQuery.isArray( obj ) ) {\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\t\t\t\tbuildParams( prefix + \"[\" + ( typeof v === \"object\" ? i : \"\" ) + \"]\", v, traditional, add );\n\t\t\t}\n\t\t});\n\n\t} else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\t\tadd( prefix, obj );\n\t}\n}\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, value ) {\n\t\t\tvalue = jQuery.isFunction( value ) ? value() : ( value == null ? \"\" : value );\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n\t\t};\n\tif ( traditional === undefined ) {\n\t\ttraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n\t}\n\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t});\n\n\t} else {\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\treturn s.join( \"&\" ).replace( r20, \"+\" );\n};\n\njQuery.fn.extend({\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map(function() {\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t})\n\t\t.filter(function() {\n\t\t\tvar type = this.type;\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t})\n\t\t.map(function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val ) {\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t}) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t}).get();\n\t}\n});\n\nreturn jQuery;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/sizzle/dist/sizzle.js",
    "content": "/*!\n * Sizzle CSS Selector Engine v1.10.19\n * http://sizzlejs.com/\n *\n * Copyright 2013 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2014-04-18\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\texpando = \"sizzle\" + -(new Date()),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\tstrundefined = typeof undefined,\n\tMAX_NEGATIVE = 1 << 31,\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\tindexOf = arr.indexOf || function( elem ) {\n\t\tvar i = 0,\n\t\t\tlen = this.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( this[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\tcharacterEncoding = \"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",\n\tidentifier = characterEncoding.replace( \"w\", \"w#\" ),\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")(?:\" + whitespace +\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + characterEncoding + \")(?:\\\\((\" +\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\trescape = /'|\\\\/g,\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t};\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar match, elem, m, nodeType,\n\t\ti, groups, old, nid, newContext, newSelector;\n\n\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\n\tcontext = context || document;\n\tresults = results || [];\n\n\tif ( !selector || typeof selector !== \"string\" ) {\n\t\treturn results;\n\t}\n\n\tif ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {\n\t\treturn [];\n\t}\n\n\tif ( documentIsHTML && !seed ) {\n\t\tif ( (match = rquickExpr.exec( selector )) ) {\n\t\t\tif ( (m = match[1]) ) {\n\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\telem = context.getElementById( m );\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n\t\t\t\t\t\tcontains( context, elem ) && elem.id === m ) {\n\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else if ( match[2] ) {\n\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\treturn results;\n\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {\n\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\treturn results;\n\t\t\t}\n\t\t}\n\t\tif ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\t\t\tnid = old = expando;\n\t\t\tnewContext = context;\n\t\t\tnewSelector = nodeType === 9 && selector;\n\t\t\tif ( nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n\t\t\t\tgroups = tokenize( selector );\n\n\t\t\t\tif ( (old = context.getAttribute(\"id\")) ) {\n\t\t\t\t\tnid = old.replace( rescape, \"\\\\$&\" );\n\t\t\t\t} else {\n\t\t\t\t\tcontext.setAttribute( \"id\", nid );\n\t\t\t\t}\n\t\t\t\tnid = \"[id='\" + nid + \"'] \";\n\n\t\t\t\ti = groups.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tgroups[i] = nid + toSelector( groups[i] );\n\t\t\t\t}\n\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;\n\t\t\t\tnewSelector = groups.join(\",\");\n\t\t\t}\n\n\t\t\tif ( newSelector ) {\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch(qsaError) {\n\t\t\t\t} finally {\n\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\tcontext.removeAttribute(\"id\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\nfunction assert( fn ) {\n\tvar div = document.createElement(\"div\");\n\n\ttry {\n\t\treturn !!fn( div );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\tif ( div.parentNode ) {\n\t\t\tdiv.parentNode.removeChild( div );\n\t\t}\n\t\tdiv = null;\n\t}\n}\n\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = attrs.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\t( ~b.sourceIndex || MAX_NEGATIVE ) -\n\t\t\t( ~a.sourceIndex || MAX_NEGATIVE );\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== strundefined && context;\n}\nsupport = Sizzle.support = {};\n\nisXML = Sizzle.isXML = function( elem ) {\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc,\n\t\tparent = doc.defaultView;\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\tdocument = doc;\n\tdocElem = doc.documentElement;\n\tdocumentIsHTML = !isXML( doc );\n\tif ( parent && parent !== parent.top ) {\n\t\tif ( parent.addEventListener ) {\n\t\t\tparent.addEventListener( \"unload\", function() {\n\t\t\t\tsetDocument();\n\t\t\t}, false );\n\t\t} else if ( parent.attachEvent ) {\n\t\t\tparent.attachEvent( \"onunload\", function() {\n\t\t\t\tsetDocument();\n\t\t\t});\n\t\t}\n\t}\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\tsupport.attributes = assert(function( div ) {\n\t\tdiv.className = \"i\";\n\t\treturn !div.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\tsupport.getElementsByTagName = assert(function( div ) {\n\t\tdiv.appendChild( doc.createComment(\"\") );\n\t\treturn !div.getElementsByTagName(\"*\").length;\n\t});\n\tsupport.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) {\n\t\tdiv.innerHTML = \"<div class='a'></div><div class='a i'></div>\";\n\t\tdiv.firstChild.className = \"i\";\n\t\treturn div.getElementsByClassName(\"i\").length === 2;\n\t});\n\tsupport.getById = assert(function( div ) {\n\t\tdocElem.appendChild( div ).id = expando;\n\t\treturn !doc.getElementsByName || !doc.getElementsByName( expando ).length;\n\t});\n\tif ( support.getById ) {\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== strundefined && documentIsHTML ) {\n\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\treturn m && m.parentNode ? [ m ] : [];\n\t\t\t}\n\t\t};\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t} else {\n\t\tdelete Expr.find[\"ID\"];\n\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\t}\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== strundefined ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\t\t\t}\n\t\t} :\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\trbuggyMatches = [];\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {\n\t\tassert(function( div ) {\n\t\t\tdiv.innerHTML = \"<select msallowclip=''><option selected=''></option></select>\";\n\t\t\tif ( div.querySelectorAll(\"[msallowclip^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\t\t\tif ( !div.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\t\t\tif ( !div.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( div ) {\n\t\t\tvar input = doc.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tdiv.appendChild( input ).setAttribute( \"name\", \"D\" );\n\t\t\tif ( div.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\t\t\tif ( !div.querySelectorAll(\":enabled\").length ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\t\t\tdiv.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( div ) {\n\t\t\tsupport.disconnectedMatch = matches.call( div, \"div\" );\n\t\t\tmatches.call( div, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\t\t\t1;\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\t\t\tif ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === doc ? -1 :\n\t\t\t\tb === doc ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn doc;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch(e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\tsortInput = null;\n\n\treturn results;\n};\n\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, outerCache, node, diff, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType;\n\n\t\t\t\t\tif ( parent ) {\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\t\t\t\t\t\tif ( forward && useCache ) {\n\t\t\t\t\t\t\touterCache = parent[ expando ] || (parent[ expando ] = {});\n\t\t\t\t\t\t\tcache = outerCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[0] === dirruns && cache[1];\n\t\t\t\t\t\t\tdiff = cache[0] === dirruns && cache[2];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\touterCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {\n\t\t\t\t\t\t\tdiff = cache[1];\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\tif ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {\n\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf.call( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\t\t\"enabled\": function( elem ) {\n\t\t\treturn elem.disabled === false;\n\t\t},\n\n\t\t\"disabled\": function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\t\"checked\": function( elem ) {\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\t\t\"empty\": function( elem ) {\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tcheckNonElements = base && dir === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\t\t\t\t\t\tif ( (oldCache = outerCache[ dir ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\touterCache[ dir ] = newCache;\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\t\t\t\t\t[] :\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf.call( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\treturn ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context !== document && context;\n\t\t\t}\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tmatchedCount += i;\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\t\t\t\tpush.apply( results, setMatched );\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\tif ( match.length === 1 ) {\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tsupport.getById && context.nodeType === 9 && documentIsHTML &&\n\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\trsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\nsupport.detectDuplicates = !!hasDuplicate;\nsetDocument();\nsupport.sortDetached = assert(function( div1 ) {\n\treturn div1.compareDocumentPosition( document.createElement(\"div\") ) & 1;\n});\nif ( !assert(function( div ) {\n\tdiv.innerHTML = \"<a href='#'></a>\";\n\treturn div.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\nif ( !support.attributes || !assert(function( div ) {\n\tdiv.innerHTML = \"<input/>\";\n\tdiv.firstChild.setAttribute( \"value\", \"\" );\n\treturn div.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\nif ( !assert(function( div ) {\n\treturn div.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine(function() { return Sizzle; });\n} else if ( typeof module !== \"undefined\" && module.exports ) {\n\tmodule.exports = Sizzle;\n} else {\n\twindow.Sizzle = Sizzle;\n}\n\n})( window );\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/support.js",
    "content": "define([\n\t\"./core\",\n\t\"./var/strundefined\",\n\t\"./var/support\",\n\t\"./core/init\", // Needed for hasOwn support test\n\t\"./core/ready\"\n], function( jQuery, strundefined, support ) {\nvar i;\nfor ( i in jQuery( support ) ) {\n\tbreak;\n}\nsupport.ownLast = i !== \"0\";\nsupport.inlineBlockNeedsLayout = false;\njQuery(function() {\n\tvar val, div, body, container;\n\n\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\tif ( !body || !body.style ) {\n\t\treturn;\n\t}\n\tdiv = document.createElement( \"div\" );\n\tcontainer = document.createElement( \"div\" );\n\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\tbody.appendChild( container ).appendChild( div );\n\n\tif ( typeof div.style.zoom !== strundefined ) {\n\t\tdiv.style.cssText = \"display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1\";\n\n\t\tsupport.inlineBlockNeedsLayout = val = div.offsetWidth === 3;\n\t\tif ( val ) {\n\t\t\tbody.style.zoom = 1;\n\t\t}\n\t}\n\n\tbody.removeChild( container );\n});\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/traversing/findFilter.js",
    "content": "define([\n\t\"../core\",\n\t\"../var/indexOf\",\n\t\"./var/rneedsContext\",\n\t\"../selector\"\n], function( jQuery, indexOf, rneedsContext ) {\n\nvar risSimple = /^.[^:#\\[\\.,]*$/;\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\t/* jshint -W018 */\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t});\n\n\t}\n\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t});\n\n\t}\n\n\tif ( typeof qualifier === \"string\" ) {\n\t\tif ( risSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter( qualifier, elements, not );\n\t\t}\n\n\t\tqualifier = jQuery.filter( qualifier, elements );\n\t}\n\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;\n\t});\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\treturn elems.length === 1 && elem.nodeType === 1 ?\n\t\tjQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n\t\tjQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t}));\n};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar i,\n\t\t\tret = [],\n\t\t\tself = this,\n\t\t\tlen = self.length;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter(function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}) );\n\t\t}\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\t\tret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );\n\t\tret.selector = this.selector ? this.selector + \" \" + selector : selector;\n\t\treturn ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], false) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], true) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n});\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/traversing/var/rneedsContext.js",
    "content": "define([\n\t\"../../core\",\n\t\"../../selector\"\n], function( jQuery ) {\n\treturn jQuery.expr.match.needsContext;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/traversing.js",
    "content": "define([\n\t\"./core\",\n\t\"./traversing/var/rneedsContext\",\n\t\"./core/init\",\n\t\"./traversing/findFilter\",\n\t\"./selector\"\n], function( jQuery, rneedsContext ) {\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.extend({\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\tcur = elem[ dir ];\n\n\t\twhile ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n\t\t\tif ( cur.nodeType === 1 ) {\n\t\t\t\tmatched.push( cur );\n\t\t\t}\n\t\t\tcur = cur[dir];\n\t\t}\n\t\treturn matched;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar r = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tr.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn r;\n\t}\n});\n\njQuery.fn.extend({\n\thas: function( target ) {\n\t\tvar i,\n\t\t\ttargets = jQuery( target, this ),\n\t\t\tlen = targets.length;\n\n\t\treturn this.filter(function() {\n\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\tpos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tfor ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {\n\t\t\t\tif ( cur.nodeType < 11 && (pos ?\n\t\t\t\t\tpos.index(cur) > -1 :\n\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\tjQuery.find.matchesSelector(cur, selectors)) ) {\n\n\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );\n\t},\n\tindex: function( elem ) {\n\t\tif ( !elem ) {\n\t\t\treturn ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn jQuery.inArray( this[0], jQuery( elem ) );\n\t\t}\n\t\treturn jQuery.inArray(\n\t\t\telem.jquery ? elem[0] : elem, this );\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.unique(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter(selector)\n\t\t);\n\t}\n});\n\nfunction sibling( cur, dir ) {\n\tdo {\n\t\tcur = cur[ dir ];\n\t} while ( cur && cur.nodeType !== 1 );\n\n\treturn cur;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn jQuery.nodeName( elem, \"iframe\" ) ?\n\t\t\telem.contentDocument || elem.contentWindow.document :\n\t\t\tjQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar ret = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tret = jQuery.filter( selector, ret );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tret = jQuery.unique( ret );\n\t\t\t}\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tret = ret.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\n\nreturn jQuery;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/var/class2type.js",
    "content": "define(function() {\n\treturn {};\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/var/concat.js",
    "content": "define([\n\t\"./deletedIds\"\n], function( deletedIds ) {\n\treturn deletedIds.concat;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/var/deletedIds.js",
    "content": "define(function() {\n\treturn [];\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/var/hasOwn.js",
    "content": "define([\n\t\"./class2type\"\n], function( class2type ) {\n\treturn class2type.hasOwnProperty;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/var/indexOf.js",
    "content": "define([\n\t\"./deletedIds\"\n], function( deletedIds ) {\n\treturn deletedIds.indexOf;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/var/pnum.js",
    "content": "define(function() {\n\treturn (/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/).source;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/var/push.js",
    "content": "define([\n\t\"./deletedIds\"\n], function( deletedIds ) {\n\treturn deletedIds.push;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/var/rnotwhite.js",
    "content": "define(function() {\n\treturn (/\\S+/g);\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/var/slice.js",
    "content": "define([\n\t\"./deletedIds\"\n], function( deletedIds ) {\n\treturn deletedIds.slice;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/var/strundefined.js",
    "content": "define(function() {\n\treturn typeof undefined;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/var/support.js",
    "content": "define(function() {\n\treturn {};\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/var/toString.js",
    "content": "define([\n\t\"./class2type\"\n], function( class2type ) {\n\treturn class2type.toString;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/jquery/src/wrap.js",
    "content": "define([\n\t\"./core\",\n\t\"./core/init\",\n\t\"./traversing\" // parent, contents\n], function( jQuery ) {\n\njQuery.fn.extend({\n\twrapAll: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapAll( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[0] ) {\n\t\t\tvar wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);\n\n\t\t\tif ( this[0].parentNode ) {\n\t\t\t\twrap.insertBefore( this[0] );\n\t\t\t}\n\n\t\t\twrap.map(function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstChild && elem.firstChild.nodeType === 1 ) {\n\t\t\t\t\telem = elem.firstChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t}).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapInner( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t});\n\t},\n\n\twrap: function( html ) {\n\t\tvar isFunction = jQuery.isFunction( html );\n\n\t\treturn this.each(function(i) {\n\t\t\tjQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );\n\t\t});\n\t},\n\n\tunwrap: function() {\n\t\treturn this.parent().each(function() {\n\t\t\tif ( !jQuery.nodeName( this, \"body\" ) ) {\n\t\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t\t}\n\t\t}).end();\n\t}\n});\n\nreturn jQuery;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ment.io/.bower.json",
    "content": "{\n  \"name\": \"ment.io\",\n  \"main\": \"dist/mentio.js\",\n  \"version\": \"0.9.23\",\n  \"homepage\": \"https://github.com/jeff-collins/ment.io\",\n  \"authors\": [\n    \"jeff-collins <i.am.jeff.collins@gmail.com>\",\n    \"adamayres <magicaj@gmail.com>\"\n  ],\n  \"description\": \"Mentions for Angular\",\n  \"keywords\": [\n    \"angular\",\n    \"mentions\",\n    \"ment.io\"\n  ],\n  \"license\": \"MIT\",\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"test\",\n    \"tests\"\n  ],\n  \"devDependencies\": {\n    \"angular\": \"~1.2.18\",\n    \"angular-mocks\": \"~1.2.18\",\n    \"angular-ui-tinymce\": \"latest\"\n  },\n  \"_release\": \"0.9.23\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"0.9.23\",\n    \"commit\": \"4cefa13c2e3c9a93deb7730524680d230bbfce29\"\n  },\n  \"_source\": \"git://github.com/jeff-collins/ment.io.git\",\n  \"_target\": \"~0.9.23\",\n  \"_originalSource\": \"ment.io\",\n  \"_direct\": true\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ment.io/LICENSE-MIT",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Jeff Collins\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE."
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ment.io/README.md",
    "content": "ment.io\n======\n\n[![Build Status](https://travis-ci.org/jeff-collins/ment.io.svg?branch=master)](https://travis-ci.org/jeff-collins/ment.io)\n[![Coverage Status](https://img.shields.io/coveralls/jeff-collins/ment.io.svg)](https://coveralls.io/r/jeff-collins/ment.io)\n\n@mentions and macros widget based on AngularJS, but with no dependencies on jQuery.  \n\nTo get started, add the following to your Controller to set up a scope variable called ```people```:\n\n```js\n$scope.people = [\n    { label: 'Joe'},\n    { label: 'Mike'},\n    { label: 'Diane'}\n]\n```\n\nThen add this to your html:\n\n```html\n<input type=\"text\" mentio \n mentio-typed-text=\"typedTerm\" \n mentio-items=\"people | filter:label:typedTerm\" \n ng-model=\"myval\"/>\n```\n\nNow you can type @ into your text field, and see a menu of choices.\n\nThere are many other options, including the ability to have multiple trigger characters, templates, binding your menu to an API, converting the selected item to markup, and more.  \n\nSee the <a href=\"http://jeff-collins.github.io/ment.io\">Ment.io Page</a> for a demo and more detailed documentation.\n\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ment.io/bower.json",
    "content": "{\n  \"name\": \"ment.io\",\n  \"main\": \"dist/mentio.js\",\n  \"version\": \"0.9.23\",\n  \"homepage\": \"https://github.com/jeff-collins/ment.io\",\n  \"authors\": [\n    \"jeff-collins <i.am.jeff.collins@gmail.com>\",\n    \"adamayres <magicaj@gmail.com>\"\n  ],\n  \"description\": \"Mentions for Angular\",\n  \"keywords\": [\n    \"angular\",\n    \"mentions\",\n    \"ment.io\"\n  ],\n  \"license\": \"MIT\",\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"test\",\n    \"tests\"\n  ],\n  \"devDependencies\": {\n    \"angular\": \"~1.2.18\",\n    \"angular-mocks\": \"~1.2.18\",\n    \"angular-ui-tinymce\": \"latest\"\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ment.io/dist/mentio.js",
    "content": "'use strict';\n\nangular.module('mentio', [])\n    .directive('mentio', ['mentioUtil', '$document', '$compile', '$log', '$timeout',\n        function (mentioUtil, $document, $compile, $log, $timeout) {\n        return {\n            restrict: 'A',\n            scope: {\n                macros: '=mentioMacros',\n                search: '&mentioSearch',\n                select: '&mentioSelect',\n                items: '=mentioItems',\n                typedTerm: '=mentioTypedTerm',\n                altId: '=mentioId',\n                iframeElement: '=mentioIframeElement',\n                requireLeadingSpace: '=mentioRequireLeadingSpace',\n                selectNotFound: '=mentioSelectNotFound',\n                trimTerm: '=mentioTrimTerm',\n                ngModel: '='\n            },\n            controller: [\"$scope\", \"$timeout\", \"$attrs\", function($scope, $timeout, $attrs) {\n\n                $scope.query = function (triggerChar, triggerText) {\n                    var remoteScope = $scope.triggerCharMap[triggerChar];\n\n                    if ($scope.trimTerm === undefined || $scope.trimTerm) {\n                        triggerText = triggerText.trim();\n                    }\n\n                    remoteScope.showMenu();\n\n                    remoteScope.search({\n                        term: triggerText\n                    });\n\n                    remoteScope.typedTerm = triggerText;\n                };\n\n                $scope.defaultSearch = function(locals) {\n                    var results = [];\n                    angular.forEach($scope.items, function(item) {\n                        if (item.label.toUpperCase().indexOf(locals.term.toUpperCase()) >= 0) {\n                            results.push(item);\n                        }\n                    });\n                    $scope.localItems = results;\n                };\n\n                $scope.bridgeSearch = function(termString) {\n                    var searchFn = $attrs.mentioSearch ? $scope.search : $scope.defaultSearch;\n                    searchFn({\n                        term: termString\n                    });\n                };\n\n                $scope.defaultSelect = function(locals) {\n                    return $scope.defaultTriggerChar + locals.item.label;\n                };\n\n                $scope.bridgeSelect = function(itemVar) {\n                    var selectFn = $attrs.mentioSelect ? $scope.select : $scope.defaultSelect;\n                    return selectFn({\n                        item: itemVar\n                    });\n                };\n\n                $scope.setTriggerText = function(text) {\n                    if ($scope.syncTriggerText) {\n                        $scope.typedTerm = ($scope.trimTerm === undefined || $scope.trimTerm) ? text.trim() : text;\n                    }\n                };\n\n                $scope.context = function() {\n                    if ($scope.iframeElement) {\n                        return {iframe: $scope.iframeElement};\n                    }\n                };\n\n                $scope.replaceText = function (text, hasTrailingSpace) {\n                    $scope.hideAll();\n\n                    mentioUtil.replaceTriggerText($scope.context(), $scope.targetElement, $scope.targetElementPath,\n                        $scope.targetElementSelectedOffset, $scope.triggerCharSet, text, $scope.requireLeadingSpace,\n                        hasTrailingSpace);\n\n                    if (!hasTrailingSpace) {\n                        $scope.setTriggerText('');\n                        angular.element($scope.targetElement).triggerHandler('change');\n                        if ($scope.isContentEditable()) {\n                            $scope.contentEditableMenuPasted = true;\n                            var timer = $timeout(function() {\n                                $scope.contentEditableMenuPasted = false;\n                            }, 200);\n                            $scope.$on('$destroy', function() {\n                                $timeout.cancel(timer);\n                            });\n                        }\n                    }\n                };\n\n                $scope.hideAll = function () {\n                    for (var key in $scope.triggerCharMap) {\n                        if ($scope.triggerCharMap.hasOwnProperty(key)) {\n                            $scope.triggerCharMap[key].hideMenu();\n                        }\n                    }\n                };\n\n                $scope.getActiveMenuScope = function () {\n                    for (var key in $scope.triggerCharMap) {\n                        if ($scope.triggerCharMap.hasOwnProperty(key)) {\n                            if ($scope.triggerCharMap[key].visible) {\n                                return $scope.triggerCharMap[key];\n                            }\n                        }\n                    }\n                    return null;\n                };\n\n                $scope.selectActive = function () {\n                    for (var key in $scope.triggerCharMap) {\n                        if ($scope.triggerCharMap.hasOwnProperty(key)) {\n                            if ($scope.triggerCharMap[key].visible) {\n                                $scope.triggerCharMap[key].selectActive();\n                            }\n                        }\n                    }\n                };\n\n                $scope.isActive = function () {\n                    for (var key in $scope.triggerCharMap) {\n                        if ($scope.triggerCharMap.hasOwnProperty(key)) {\n                            if ($scope.triggerCharMap[key].visible) {\n                                return true;\n                            }\n                        }\n                    }\n                    return false;\n                };\n\n                $scope.isContentEditable = function() {\n                    return ($scope.targetElement.nodeName !== 'INPUT' && $scope.targetElement.nodeName !== 'TEXTAREA');\n                };\n\n                $scope.replaceMacro = function(macro, hasTrailingSpace) {\n                    if (!hasTrailingSpace) {\n                        $scope.replacingMacro = true;\n                        $scope.timer = $timeout(function() {\n                            mentioUtil.replaceMacroText($scope.context(), $scope.targetElement,\n                                $scope.targetElementPath, $scope.targetElementSelectedOffset,\n                                $scope.macros, $scope.macros[macro]);\n                            angular.element($scope.targetElement).triggerHandler('change');\n                            $scope.replacingMacro = false;\n                        }, 300);\n                        $scope.$on('$destroy', function() {\n                            $timeout.cancel($scope.timer);\n                        });\n                    } else {\n                        mentioUtil.replaceMacroText($scope.context(), $scope.targetElement, $scope.targetElementPath,\n                            $scope.targetElementSelectedOffset, $scope.macros, $scope.macros[macro]);\n                    }\n                };\n\n                $scope.addMenu = function(menuScope) {\n                    if (menuScope.parentScope && $scope.triggerCharMap.hasOwnProperty(menuScope.triggerChar)) {\n                        return;\n                    }\n                    $scope.triggerCharMap[menuScope.triggerChar] = menuScope;\n                    if ($scope.triggerCharSet === undefined) {\n                        $scope.triggerCharSet = [];\n                    }\n                    $scope.triggerCharSet.push(menuScope.triggerChar);\n                    menuScope.setParent($scope);\n                };\n\n                $scope.$on(\n                    'menuCreated', function (event, data) {\n                        if (\n                            $attrs.id !== undefined ||\n                            $attrs.mentioId !== undefined\n                        )\n                        {\n                            if (\n                                $attrs.id === data.targetElement ||\n                                (\n                                    $attrs.mentioId !== undefined &&\n                                    $scope.altId === data.targetElement\n                                )\n                            )\n                            {\n                                $scope.addMenu(data.scope);\n                            }\n                        }\n                    }\n                );\n\n                $document.on(\n                    'click', function () {\n                        if ($scope.isActive()) {\n                            $scope.$apply(function () {\n                                $scope.hideAll();\n                            });\n                        }\n                    }\n                );\n\n                $document.on(\n                    'keydown keypress paste', function (event) {\n                        var activeMenuScope = $scope.getActiveMenuScope();\n                        if (activeMenuScope) {\n                            if (event.which === 9 || event.which === 13) {\n                                event.preventDefault();\n                                activeMenuScope.selectActive();\n                            }\n\n                            if (event.which === 27) {\n                                event.preventDefault();\n                                activeMenuScope.$apply(function () {\n                                    activeMenuScope.hideMenu();\n                                });\n                            }\n\n                            if (event.which === 40) {\n                                event.preventDefault();\n                                activeMenuScope.$apply(function () {\n                                    activeMenuScope.activateNextItem();\n                                });\n                                activeMenuScope.adjustScroll(1);\n                            }\n\n                            if (event.which === 38) {\n                                event.preventDefault();\n                                activeMenuScope.$apply(function () {\n                                    activeMenuScope.activatePreviousItem();\n                                });\n                                activeMenuScope.adjustScroll(-1);\n                            }\n\n                            if (event.which === 37 || event.which === 39) {\n                                event.preventDefault();\n                             }\n                        }\n                    }\n                );\n            }],\n            link: function (scope, element, attrs) {\n                scope.triggerCharMap = {};\n\n                scope.targetElement = element;\n                attrs.$set('autocomplete','off');\n\n                if (attrs.mentioItems) {\n                    scope.localItems = [];\n                    scope.parentScope = scope;\n                    var itemsRef = attrs.mentioSearch ? ' mentio-items=\"items\"' : ' mentio-items=\"localItems\"';\n\n                    scope.defaultTriggerChar = attrs.mentioTriggerChar ? scope.$eval(attrs.mentioTriggerChar) : '@';\n\n                    var html = '<mentio-menu' +\n                        ' mentio-search=\"bridgeSearch(term)\"' +\n                        ' mentio-select=\"bridgeSelect(item)\"' +\n                        itemsRef;\n\n                    if (attrs.mentioTemplateUrl) {\n                        html = html + ' mentio-template-url=\"' + attrs.mentioTemplateUrl + '\"';\n                    }\n                    html = html + ' mentio-trigger-char=\"\\'' + scope.defaultTriggerChar + '\\'\"' +\n                        ' mentio-parent-scope=\"parentScope\"' +\n                        '/>';\n                    var linkFn = $compile(html);\n                    var el = linkFn(scope);\n\n                    element.parent().append(el);\n\n                    scope.$on('$destroy', function() {\n                      el.remove();\n                    });\n                }\n\n                if (attrs.mentioTypedTerm) {\n                    scope.syncTriggerText = true;\n                }\n\n                function keyHandler(event) {\n                    function stopEvent(event) {\n                        event.preventDefault();\n                        event.stopPropagation();\n                        event.stopImmediatePropagation();\n                    }\n                    var activeMenuScope = scope.getActiveMenuScope();\n                    if (activeMenuScope) {\n                        if (event.which === 9 || event.which === 13) {\n                            stopEvent(event);\n                            activeMenuScope.selectActive();\n                            return false;\n                        }\n\n                        if (event.which === 27) {\n                            stopEvent(event);\n                            activeMenuScope.$apply(function () {\n                                activeMenuScope.hideMenu();\n                            });\n                            return false;\n                        }\n\n                        if (event.which === 40) {\n                            stopEvent(event);\n                            activeMenuScope.$apply(function () {\n                                activeMenuScope.activateNextItem();\n                            });\n                            activeMenuScope.adjustScroll(1);\n                            return false;\n                        }\n\n                        if (event.which === 38) {\n                            stopEvent(event);\n                            activeMenuScope.$apply(function () {\n                                activeMenuScope.activatePreviousItem();\n                            });\n                            activeMenuScope.adjustScroll(-1);\n                            return false;\n                        }\n\n                        if (event.which === 37 || event.which === 39) {\n                            stopEvent(event);\n                            return false;\n                        }\n                    }\n                }\n\n                scope.$watch(\n                    'iframeElement', function(newValue) {\n                        if (newValue) {\n                            var iframeDocument = newValue.contentWindow.document;\n                            iframeDocument.addEventListener('click',\n                                function () {\n                                    if (scope.isActive()) {\n                                        scope.$apply(function () {\n                                            scope.hideAll();\n                                        });\n                                    }\n                                }\n                            );\n\n\n                            iframeDocument.addEventListener('keydown', keyHandler, true /*capture*/);\n\n                            scope.$on ( '$destroy', function() {\n                                iframeDocument.removeEventListener ( 'keydown', keyHandler );\n                            });\n                        }\n                    }\n                );\n\n                scope.$watch(\n                    'ngModel',\n                    function (newValue) {\n                        /*jshint maxcomplexity:14 */\n                        /*jshint maxstatements:39 */\n                        if ((!newValue || newValue === '') && !scope.isActive()) {\n                            return;\n                        }\n                        if (scope.triggerCharSet === undefined) {\n                            $log.error('Error, no mentio-items attribute was provided, ' +\n                                'and no separate mentio-menus were specified.  Nothing to do.');\n                            return;\n                        }\n\n                        if (scope.contentEditableMenuPasted) {\n                            scope.contentEditableMenuPasted = false;\n                            return;\n                        }\n\n                        if (scope.replacingMacro) {\n                            $timeout.cancel(scope.timer);\n                            scope.replacingMacro = false;\n                        }\n\n                        var isActive = scope.isActive();\n                        var isContentEditable = scope.isContentEditable();\n\n                        var mentionInfo = mentioUtil.getTriggerInfo(scope.context(), scope.triggerCharSet,\n                            scope.requireLeadingSpace, isActive);\n\n                        if (mentionInfo !== undefined &&\n                                (\n                                    !isActive ||\n                                    (isActive &&\n                                        (\n                                            /* content editable selection changes to local nodes which\n                                            modifies the start position of the selection over time,\n                                            just consider triggerchar changes which\n                                            will have the odd effect that deleting a trigger char pops\n                                            the menu for a previous\n                                            trigger char sequence if one exists in a content editable */\n                                            (isContentEditable && mentionInfo.mentionTriggerChar ===\n                                                scope.currentMentionTriggerChar) ||\n                                            (!isContentEditable && mentionInfo.mentionPosition ===\n                                                scope.currentMentionPosition)\n                                        )\n                                    )\n                                )\n                            )\n                        {\n                                                        if (mentionInfo.mentionSelectedElement) {\n                                scope.targetElement = mentionInfo.mentionSelectedElement;\n                                scope.targetElementPath = mentionInfo.mentionSelectedPath;\n                                scope.targetElementSelectedOffset = mentionInfo.mentionSelectedOffset;\n                            }\n\n                            /* publish to external ngModel */\n                            scope.setTriggerText(mentionInfo.mentionText);\n                            /* remember current position */\n                            scope.currentMentionPosition = mentionInfo.mentionPosition;\n                            scope.currentMentionTriggerChar = mentionInfo.mentionTriggerChar;\n                            /* perform query */\n                            scope.query(mentionInfo.mentionTriggerChar, mentionInfo.mentionText);\n                        } else {\n                            var currentTypedTerm = scope.typedTerm;\n                            scope.setTriggerText('');\n                            scope.hideAll();\n\n                            var macroMatchInfo = mentioUtil.getMacroMatch(scope.context(), scope.macros);\n\n                            if (macroMatchInfo !== undefined) {\n                                scope.targetElement = macroMatchInfo.macroSelectedElement;\n                                scope.targetElementPath = macroMatchInfo.macroSelectedPath;\n                                scope.targetElementSelectedOffset = macroMatchInfo.macroSelectedOffset;\n                                scope.replaceMacro(macroMatchInfo.macroText, macroMatchInfo.macroHasTrailingSpace);\n                            } else if (scope.selectNotFound && currentTypedTerm && currentTypedTerm !== '') {\n                                var lastScope = scope.triggerCharMap[scope.currentMentionTriggerChar];\n                                if (lastScope) {\n                                    var text = lastScope.select({\n                                        item: {label: currentTypedTerm}\n                                    });\n                                    if (typeof text.then === 'function') {\n                                        /* text is a promise, at least our best guess */\n                                        text.then(scope.replaceText);\n                                    } else {\n                                        scope.replaceText(text, true);\n                                    }\n                                }\n                            }\n                        }\n                    }\n                );\n            }\n        };\n    }])\n\n    .directive('mentioMenu', ['mentioUtil', '$rootScope', '$log', '$window', '$document',\n        function (mentioUtil, $rootScope, $log, $window, $document) {\n        return {\n            restrict: 'E',\n            scope: {\n                search: '&mentioSearch',\n                select: '&mentioSelect',\n                items: '=mentioItems',\n                triggerChar: '=mentioTriggerChar',\n                forElem: '=mentioFor',\n                parentScope: '=mentioParentScope'\n            },\n            templateUrl: function(tElement, tAttrs) {\n                return tAttrs.mentioTemplateUrl !== undefined ? tAttrs.mentioTemplateUrl : 'mentio-menu.tpl.html';\n            },\n            controller: [\"$scope\", function ($scope) {\n                $scope.visible = false;\n                this.activate = $scope.activate = function (item) {\n                    $scope.activeItem = item;\n                };\n                this.isActive = $scope.isActive = function (item) {\n                    return $scope.activeItem === item;\n                };\n                this.selectItem = $scope.selectItem = function (item) {\n                    var text = $scope.select({\n                        item: item\n                    });\n                    if (typeof text.then === 'function') {\n                        /* text is a promise, at least our best guess */\n                        text.then($scope.parentMentio.replaceText);\n                    } else {\n                        $scope.parentMentio.replaceText(text);\n                    }\n                };\n\n                $scope.activateNextItem = function () {\n                    var index = $scope.items.indexOf($scope.activeItem);\n                    this.activate($scope.items[(index + 1) % $scope.items.length]);\n                };\n\n                $scope.activatePreviousItem = function () {\n                    var index = $scope.items.indexOf($scope.activeItem);\n                    this.activate($scope.items[index === 0 ? $scope.items.length - 1 : index - 1]);\n                };\n\n                $scope.isFirstItemActive = function () {\n                    var index = $scope.items.indexOf($scope.activeItem);\n\n                    return index === 0;\n                };\n\n                $scope.isLastItemActive = function () {\n                    var index = $scope.items.indexOf($scope.activeItem);\n\n                    return index === ($scope.items.length - 1);\n                };\n\n                $scope.selectActive = function () {\n                    $scope.selectItem($scope.activeItem);\n                };\n\n                $scope.isVisible = function () {\n                    return $scope.visible;\n                };\n\n                $scope.showMenu = function () {\n                    if (!$scope.visible) {\n                        $scope.requestVisiblePendingSearch = true;\n                    }\n                };\n\n                $scope.setParent = function (scope) {\n                    $scope.parentMentio = scope;\n                    $scope.targetElement = scope.targetElement;\n                };\n            }],\n\n            link: function (scope, element) {\n                element[0].parentNode.removeChild(element[0]);\n                $document[0].body.appendChild(element[0]);\n                scope.menuElement = element; // for testing\n\n                if (scope.parentScope) {\n                    scope.parentScope.addMenu(scope);\n                } else {\n                    if (!scope.forElem) {\n                        $log.error('mentio-menu requires a target element in tbe mentio-for attribute');\n                        return;\n                    }\n                    if (!scope.triggerChar) {\n                        $log.error('mentio-menu requires a trigger char');\n                        return;\n                    }\n                    $rootScope.$broadcast('menuCreated',\n                        {\n                            targetElement : scope.forElem,\n                            scope : scope\n                        });\n                }\n\n                angular.element($window).bind(\n                    'resize', function () {\n                        if (scope.isVisible()) {\n                            var triggerCharSet = [];\n                            triggerCharSet.push(scope.triggerChar);\n                            mentioUtil.popUnderMention(scope.parentMentio.context(),\n                                triggerCharSet, element, scope.requireLeadingSpace);\n                        }\n                    }\n                );\n\n                scope.$watch('items', function (items) {\n                    if (items && items.length > 0) {\n                        scope.activate(items[0]);\n                        if (!scope.visible && scope.requestVisiblePendingSearch) {\n                            scope.visible = true;\n                            scope.requestVisiblePendingSearch = false;\n                        }\n                    } else {\n                        scope.hideMenu();\n                    }\n                });\n\n                scope.$watch('isVisible()', function (visible) {\n                    if (visible) {\n                        var triggerCharSet = [];\n                        triggerCharSet.push(scope.triggerChar);\n                        mentioUtil.popUnderMention(scope.parentMentio.context(),\n                            triggerCharSet, element, scope.requireLeadingSpace);\n                    }\n                });\n\n                scope.parentMentio.$on('$destroy', function () {\n                    element.remove();\n                });\n\n                scope.hideMenu = function () {\n                    scope.visible = false;\n                    element.css('display', 'none');\n                };\n\n                scope.adjustScroll = function (direction) {\n                    var menuEl = element[0];\n                    var menuItemsList = menuEl.querySelector('ul');\n                    var menuItem = menuEl.querySelector('[mentio-menu-item].active');\n\n                    if (scope.isFirstItemActive()) {\n                        return menuItemsList.scrollTop = 0;\n                    } else if(scope.isLastItemActive()) {\n                        return menuItemsList.scrollTop = menuItemsList.scrollHeight;\n                    }\n\n                    if (direction === 1) {\n                        menuItemsList.scrollTop += menuItem.offsetHeight;\n                    } else {\n                        menuItemsList.scrollTop -= menuItem.offsetHeight;\n                    }\n                };\n\n            }\n        };\n    }])\n\n    .directive('mentioMenuItem', function () {\n        return {\n            restrict: 'A',\n            scope: {\n                item: '=mentioMenuItem'\n            },\n            require: '^mentioMenu',\n            link: function (scope, element, attrs, controller) {\n\n                scope.$watch(function () {\n                    return controller.isActive(scope.item);\n                }, function (active) {\n                    if (active) {\n                        element.addClass('active');\n                    } else {\n                        element.removeClass('active');\n                    }\n                });\n\n                element.bind('mouseenter', function () {\n                    scope.$apply(function () {\n                        controller.activate(scope.item);\n                    });\n                });\n\n                element.bind('click', function () {\n                    controller.selectItem(scope.item);\n                    return false;\n                });\n            }\n        };\n    })\n    .filter('unsafe', [\"$sce\", function($sce) {\n        return function (val) {\n            return $sce.trustAsHtml(val);\n        };\n    }])\n    .filter('mentioHighlight', function() {\n        function escapeRegexp (queryToEscape) {\n            return queryToEscape.replace(/([.?*+^$[\\]\\\\(){}|-])/g, '\\\\$1');\n        }\n\n        return function (matchItem, query, hightlightClass) {\n            if (query) {\n                var replaceText = hightlightClass ?\n                                 '<span class=\"' + hightlightClass + '\">$&</span>' :\n                                 '<strong>$&</strong>';\n                return ('' + matchItem).replace(new RegExp(escapeRegexp(query), 'gi'), replaceText);\n            } else {\n                return matchItem;\n            }\n        };\n    });\n\n'use strict';\n\nangular.module('mentio')\n    .factory('mentioUtil', [\"$window\", \"$location\", \"$anchorScroll\", \"$timeout\", function ($window, $location, $anchorScroll, $timeout) {\n        function popUnderMention (ctx, triggerCharSet, selectionEl, requireLeadingSpace) {\n            var coordinates;\n            var mentionInfo = getTriggerInfo(ctx, triggerCharSet, requireLeadingSpace, false);\n\n            if (mentionInfo !== undefined) {\n\n                if (selectedElementIsTextAreaOrInput(ctx)) {\n                    coordinates = getTextAreaOrInputUnderlinePosition(ctx, getDocument(ctx).activeElement,\n                        mentionInfo.mentionPosition);\n                } else {\n                    coordinates = getContentEditableCaretPosition(ctx, mentionInfo.mentionPosition);\n                }\n                selectionEl.css({\n                    top: coordinates.top + 'px',\n                    left: coordinates.left + 'px',\n                    position: 'absolute',\n                    zIndex: 200000,\n                    display: 'block'\n                });\n\n                $timeout(function(){\n                    scrollIntoView(ctx, selectionEl);\n                },0);\n            } else {\n                selectionEl.css({\n                    display: 'none'\n                });\n            }\n        }\n\n        function scrollIntoView(ctx, elem)\n        {\n            var reasonableBuffer = 20;\n            var maxScrollDisplacement = 100;\n            var clientRect;\n            var e = elem[0];\n            while (clientRect === undefined || clientRect.height === 0) {\n                clientRect = e.getBoundingClientRect();\n                if (clientRect.height === 0) {\n                    e = e.childNodes[0];\n                    if (e === undefined || !e.getBoundingClientRect) {\n                        return;\n                    }\n                }\n            }\n            var elemTop = clientRect.top;\n            var elemBottom = elemTop + clientRect.height;\n            if(elemTop < 0) {\n                $window.scrollTo(0, $window.pageYOffset + clientRect.top - reasonableBuffer);\n            } else if (elemBottom > $window.innerHeight) {\n                var maxY = $window.pageYOffset + clientRect.top - reasonableBuffer;\n                if (maxY - $window.pageYOffset > maxScrollDisplacement) {\n                    maxY = $window.pageYOffset + maxScrollDisplacement;\n                }\n                var targetY = $window.pageYOffset - ($window.innerHeight - elemBottom);\n                if (targetY > maxY) {\n                    targetY = maxY;\n                }\n                $window.scrollTo(0, targetY);\n            }\n        }\n\n        function selectedElementIsTextAreaOrInput (ctx) {\n            var element = getDocument(ctx).activeElement;\n            if (element !== null) {\n                var nodeName = element.nodeName;\n                var type = element.getAttribute('type');\n                return (nodeName === 'INPUT' && type === 'text') || nodeName === 'TEXTAREA';\n            }\n            return false;\n        }\n\n        function selectElement (ctx, targetElement, path, offset) {\n            var range;\n            var elem = targetElement;\n            if (path) {\n                for (var i = 0; i < path.length; i++) {\n                    elem = elem.childNodes[path[i]];\n                    if (elem === undefined) {\n                        return;\n                    }\n                    while (elem.length < offset) {\n                        offset -= elem.length;\n                        elem = elem.nextSibling;\n                    }\n                    if (elem.childNodes.length === 0 && !elem.length) {\n                        elem = elem.previousSibling;\n                    }\n                }\n            }\n            var sel = getWindowSelection(ctx);\n\n            range = getDocument(ctx).createRange();\n            range.setStart(elem, offset);\n            range.setEnd(elem, offset);\n            range.collapse(true);\n            try{sel.removeAllRanges();}catch(error){}\n            sel.addRange(range);\n            targetElement.focus();\n        }\n\n        function pasteHtml (ctx, html, startPos, endPos) {\n            var range, sel;\n            sel = getWindowSelection(ctx);\n            range = getDocument(ctx).createRange();\n            range.setStart(sel.anchorNode, startPos);\n            range.setEnd(sel.anchorNode, endPos);\n            range.deleteContents();\n\n            var el = getDocument(ctx).createElement('div');\n            el.innerHTML = html;\n            var frag = getDocument(ctx).createDocumentFragment(),\n                node, lastNode;\n            while ((node = el.firstChild)) {\n                lastNode = frag.appendChild(node);\n            }\n            range.insertNode(frag);\n            if (lastNode) {\n                range = range.cloneRange();\n                range.setStartAfter(lastNode);\n                range.collapse(true);\n                sel.removeAllRanges();\n                sel.addRange(range);\n            }\n        }\n\n        function resetSelection (ctx, targetElement, path, offset) {\n            var nodeName = targetElement.nodeName;\n            if (nodeName === 'INPUT' || nodeName === 'TEXTAREA') {\n                if (targetElement !== getDocument(ctx).activeElement) {\n                    targetElement.focus();\n                }\n            } else {\n                selectElement(ctx, targetElement, path, offset);\n            }\n        }\n        function replaceMacroText (ctx, targetElement, path, offset, macros, text) {\n            resetSelection(ctx, targetElement, path, offset);\n\n            var macroMatchInfo = getMacroMatch(ctx, macros);\n\n            if (macroMatchInfo.macroHasTrailingSpace) {\n                macroMatchInfo.macroText = macroMatchInfo.macroText + '\\xA0';\n                text = text + '\\xA0';\n            }\n\n            if (macroMatchInfo !== undefined) {\n                var element = getDocument(ctx).activeElement;\n                if (selectedElementIsTextAreaOrInput(ctx)) {\n                    var startPos = macroMatchInfo.macroPosition;\n                    var endPos = macroMatchInfo.macroPosition + macroMatchInfo.macroText.length;\n                    element.value = element.value.substring(0, startPos) + text +\n                        element.value.substring(endPos, element.value.length);\n                    element.selectionStart = startPos + text.length;\n                    element.selectionEnd = startPos + text.length;\n                } else {\n                    pasteHtml(ctx, text, macroMatchInfo.macroPosition,\n                            macroMatchInfo.macroPosition + macroMatchInfo.macroText.length);\n                }\n            }\n        }\n        function replaceTriggerText (ctx, targetElement, path, offset, triggerCharSet, \n                text, requireLeadingSpace, hasTrailingSpace) {\n            resetSelection(ctx, targetElement, path, offset);\n\n            var mentionInfo = getTriggerInfo(ctx, triggerCharSet, requireLeadingSpace, true, hasTrailingSpace);\n\n            if (mentionInfo !== undefined) {\n                if (selectedElementIsTextAreaOrInput()) {\n                    var myField = getDocument(ctx).activeElement;\n                    text = text + ' ';\n                    var startPos = mentionInfo.mentionPosition;\n                    var endPos = mentionInfo.mentionPosition + mentionInfo.mentionText.length + 1;\n                    myField.value = myField.value.substring(0, startPos) + text +\n                        myField.value.substring(endPos, myField.value.length);\n                    myField.selectionStart = startPos + text.length;\n                    myField.selectionEnd = startPos + text.length;\n                } else {\n                    text = text + '\\xA0';\n                    pasteHtml(ctx, text, mentionInfo.mentionPosition,\n                            mentionInfo.mentionPosition + mentionInfo.mentionText.length + 1);\n                }\n            }\n        }\n\n        function getNodePositionInParent (ctx, elem) {\n            if (elem.parentNode === null) {\n                return 0;\n            }\n            for (var i = 0; i < elem.parentNode.childNodes.length; i++) {\n                var node = elem.parentNode.childNodes[i];\n                if (node === elem) {\n                    return i;\n                }\n            }\n        }\n        function getMacroMatch (ctx, macros) {\n            var selected, path = [], offset;\n\n            if (selectedElementIsTextAreaOrInput(ctx)) {\n                selected = getDocument(ctx).activeElement;\n            } else {\n                var selectionInfo = getContentEditableSelectedPath(ctx);\n                if (selectionInfo) {\n                    selected = selectionInfo.selected;\n                    path = selectionInfo.path;\n                    offset = selectionInfo.offset;\n                }\n            }\n            var effectiveRange = getTextPrecedingCurrentSelection(ctx);\n            if (effectiveRange !== undefined && effectiveRange !== null) {\n\n                var matchInfo;\n\n                var hasTrailingSpace = false;\n\n                if (effectiveRange.length > 0 &&\n                    (effectiveRange.charAt(effectiveRange.length - 1) === '\\xA0' ||\n                        effectiveRange.charAt(effectiveRange.length - 1) === ' ')) {\n                    hasTrailingSpace = true;\n                    effectiveRange = effectiveRange.substring(0, effectiveRange.length-1);\n                }\n\n                angular.forEach(macros, function (macro, c) {\n                    var idx = effectiveRange.toUpperCase().lastIndexOf(c.toUpperCase());\n\n                    if (idx >= 0 && c.length + idx === effectiveRange.length) {\n                        var prevCharPos = idx - 1;\n                        if (idx === 0 || effectiveRange.charAt(prevCharPos) === '\\xA0' ||\n                            effectiveRange.charAt(prevCharPos) === ' ' ) {\n\n                            matchInfo = {\n                                macroPosition: idx,\n                                macroText: c,\n                                macroSelectedElement: selected,\n                                macroSelectedPath: path,\n                                macroSelectedOffset: offset,\n                                macroHasTrailingSpace: hasTrailingSpace\n                            };\n                        }\n                    }\n                });\n                if (matchInfo) {\n                    return matchInfo;\n                }\n            }\n        }\n\n        function getContentEditableSelectedPath(ctx) {\n            var sel = getWindowSelection(ctx);\n            var selected = sel.anchorNode;\n            var path = [];\n            var offset;\n            if (selected != null) {\n                var i;\n                var ce = selected.contentEditable;\n                while (selected !== null && ce !== 'true') {\n                    i = getNodePositionInParent(ctx, selected);\n                    path.push(i);\n                    selected = selected.parentNode;\n                    if (selected !== null) {\n                        ce = selected.contentEditable;\n                    }\n                }\n                path.reverse();\n                offset = sel.getRangeAt(0).startOffset;\n                return {\n                    selected: selected,\n                    path: path,\n                    offset: offset\n                };\n            }\n        }\n        function getTriggerInfo (ctx, triggerCharSet, requireLeadingSpace, menuAlreadyActive, hasTrailingSpace) {\n            /*jshint maxcomplexity:11 */\n            var selected, path, offset;\n            if (selectedElementIsTextAreaOrInput(ctx)) {\n                selected = getDocument(ctx).activeElement;\n            } else {\n                var selectionInfo = getContentEditableSelectedPath(ctx);\n                if (selectionInfo) {\n                    selected = selectionInfo.selected;\n                    path = selectionInfo.path;\n                    offset = selectionInfo.offset;\n                }\n            }\n            var effectiveRange = getTextPrecedingCurrentSelection(ctx);\n\n            if (effectiveRange !== undefined && effectiveRange !== null) {\n                var mostRecentTriggerCharPos = -1;\n                var triggerChar;\n                triggerCharSet.forEach(function(c) {\n                    var idx = effectiveRange.lastIndexOf(c);\n                    if (idx > mostRecentTriggerCharPos) {\n                        mostRecentTriggerCharPos = idx;\n                        triggerChar = c;\n                    }\n                });\n                if (mostRecentTriggerCharPos >= 0 &&\n                        (\n                            mostRecentTriggerCharPos === 0 ||\n                            !requireLeadingSpace ||\n                            /[\\xA0\\s]/g.test\n                            (\n                                effectiveRange.substring(\n                                    mostRecentTriggerCharPos - 1,\n                                    mostRecentTriggerCharPos)\n                            )\n                        )\n                    )\n                {\n                    var currentTriggerSnippet = effectiveRange.substring(mostRecentTriggerCharPos + 1,\n                        effectiveRange.length);\n\n                    triggerChar = effectiveRange.substring(mostRecentTriggerCharPos, mostRecentTriggerCharPos+1);\n                    var firstSnippetChar = currentTriggerSnippet.substring(0,1);\n                    var leadingSpace = currentTriggerSnippet.length > 0 &&\n                        (\n                            firstSnippetChar === ' ' ||\n                            firstSnippetChar === '\\xA0'\n                        );\n                    if (hasTrailingSpace) {\n                        currentTriggerSnippet = currentTriggerSnippet.trim();\n                    }\n                    if (!leadingSpace && (menuAlreadyActive || !(/[\\xA0\\s]/g.test(currentTriggerSnippet)))) {\n                        return {\n                            mentionPosition: mostRecentTriggerCharPos,\n                            mentionText: currentTriggerSnippet,\n                            mentionSelectedElement: selected,\n                            mentionSelectedPath: path,\n                            mentionSelectedOffset: offset,\n                            mentionTriggerChar: triggerChar\n                        };\n                    }\n                }\n            }\n        }\n\n        function getWindowSelection(ctx) {\n            if (!ctx) {\n                return window.getSelection();\n            } else {\n                return ctx.iframe.contentWindow.getSelection();\n            }\n        }\n\n        function getDocument(ctx) {\n            if (!ctx) {\n                return document;\n            } else {\n                return ctx.iframe.contentWindow.document;\n            }\n        }\n\n        function getTextPrecedingCurrentSelection (ctx) {\n            var text;\n            if (selectedElementIsTextAreaOrInput(ctx)) {\n                var textComponent = getDocument(ctx).activeElement;\n                var startPos = textComponent.selectionStart;\n                text = textComponent.value.substring(0, startPos);\n\n            } else {\n                var selectedElem = getWindowSelection(ctx).anchorNode;\n                if (selectedElem != null) {\n                    var workingNodeContent = selectedElem.textContent;\n                    var selectStartOffset = getWindowSelection(ctx).getRangeAt(0).startOffset;\n                    if (selectStartOffset >= 0) {\n                        text = workingNodeContent.substring(0, selectStartOffset);\n                    }\n                }\n            }\n            return text;\n        }\n\n        function getContentEditableCaretPosition (ctx, selectedNodePosition) {\n            var markerTextChar = '\\ufeff';\n            var markerEl, markerId = 'sel_' + new Date().getTime() + '_' + Math.random().toString().substr(2);\n\n            var range;\n            var sel = getWindowSelection(ctx);\n            var prevRange = sel.getRangeAt(0);\n            range = getDocument(ctx).createRange();\n\n            range.setStart(sel.anchorNode, selectedNodePosition);\n            range.setEnd(sel.anchorNode, selectedNodePosition);\n\n            range.collapse(false);\n            markerEl = getDocument(ctx).createElement('span');\n            markerEl.id = markerId;\n            markerEl.appendChild(getDocument(ctx).createTextNode(markerTextChar));\n            range.insertNode(markerEl);\n            sel.removeAllRanges();\n            sel.addRange(prevRange);\n\n            var coordinates = {\n                left: 0,\n                top: markerEl.offsetHeight\n            };\n\n            localToGlobalCoordinates(ctx, markerEl, coordinates);\n\n            markerEl.parentNode.removeChild(markerEl);\n            return coordinates;\n        }\n\n        function localToGlobalCoordinates(ctx, element, coordinates) {\n            var obj = element;\n            var iframe = ctx ? ctx.iframe : null;\n            while(obj) {\n                coordinates.left += obj.offsetLeft;\n                coordinates.top += obj.offsetTop;\n                if (obj !== getDocument().body) {\n                    coordinates.top -= obj.scrollTop;\n                    coordinates.left -= obj.scrollLeft;\n                }\n                obj = obj.offsetParent;\n                if (!obj && iframe) {\n                    obj = iframe;\n                    iframe = null;\n                }\n            }            \n        }\n\n        function getTextAreaOrInputUnderlinePosition (ctx, element, position) {\n            var properties = [\n                'direction',\n                'boxSizing',\n                'width',\n                'height',\n                'overflowX',\n                'overflowY',\n                'borderTopWidth',\n                'borderRightWidth',\n                'borderBottomWidth',\n                'borderLeftWidth',\n                'paddingTop',\n                'paddingRight',\n                'paddingBottom',\n                'paddingLeft',\n                'fontStyle',\n                'fontVariant',\n                'fontWeight',\n                'fontStretch',\n                'fontSize',\n                'fontSizeAdjust',\n                'lineHeight',\n                'fontFamily',\n                'textAlign',\n                'textTransform',\n                'textIndent',\n                'textDecoration',\n                'letterSpacing',\n                'wordSpacing'\n            ];\n\n            var isFirefox = (window.mozInnerScreenX !== null);\n\n            var div = getDocument(ctx).createElement('div');\n            div.id = 'input-textarea-caret-position-mirror-div';\n            getDocument(ctx).body.appendChild(div);\n\n            var style = div.style;\n            var computed = window.getComputedStyle ? getComputedStyle(element) : element.currentStyle;\n\n            style.whiteSpace = 'pre-wrap';\n            if (element.nodeName !== 'INPUT') {\n                style.wordWrap = 'break-word';\n            }\n            style.position = 'absolute';\n            style.visibility = 'hidden';\n            properties.forEach(function (prop) {\n                style[prop] = computed[prop];\n            });\n\n            if (isFirefox) {\n                style.width = (parseInt(computed.width) - 2) + 'px';\n                if (element.scrollHeight > parseInt(computed.height))\n                    style.overflowY = 'scroll';\n            } else {\n                style.overflow = 'hidden';\n            }\n\n            div.textContent = element.value.substring(0, position);\n\n            if (element.nodeName === 'INPUT') {\n                div.textContent = div.textContent.replace(/\\s/g, '\\u00a0');\n            }\n\n            var span = getDocument(ctx).createElement('span');\n            span.textContent = element.value.substring(position) || '.';\n            div.appendChild(span);\n\n            var coordinates = {\n                top: span.offsetTop + parseInt(computed.borderTopWidth) + parseInt(computed.fontSize),\n                left: span.offsetLeft + parseInt(computed.borderLeftWidth)\n            };\n\n            localToGlobalCoordinates(ctx, element, coordinates);\n\n            getDocument(ctx).body.removeChild(div);\n\n            return coordinates;\n        }\n\n        return {\n            popUnderMention: popUnderMention,\n            replaceMacroText: replaceMacroText,\n            replaceTriggerText: replaceTriggerText,\n            getMacroMatch: getMacroMatch,\n            getTriggerInfo: getTriggerInfo,\n            selectElement: selectElement,\n            getTextAreaOrInputUnderlinePosition: getTextAreaOrInputUnderlinePosition,\n            getTextPrecedingCurrentSelection: getTextPrecedingCurrentSelection,\n            getContentEditableSelectedPath: getContentEditableSelectedPath,\n            getNodePositionInParent: getNodePositionInParent,\n            getContentEditableCaretPosition: getContentEditableCaretPosition,\n            pasteHtml: pasteHtml,\n            resetSelection: resetSelection,\n            scrollIntoView: scrollIntoView\n        };\n    }]);\n\nangular.module(\"mentio\").run([\"$templateCache\", function($templateCache) {$templateCache.put(\"mentio-menu.tpl.html\",\"<style>\\n.scrollable-menu {\\n    height: auto;\\n    max-height: 300px;\\n    overflow: auto;\\n}\\n\\n.menu-highlighted {\\n    font-weight: bold;\\n}\\n</style>\\n<ul class=\\\"dropdown-menu scrollable-menu\\\" style=\\\"display:block\\\">\\n    <li mentio-menu-item=\\\"item\\\" ng-repeat=\\\"item in items track by $index\\\">\\n        <a class=\\\"text-primary\\\" ng-bind-html=\\\"item.label | mentioHighlight:typedTerm:\\'menu-highlighted\\' | unsafe\\\"></a>\\n    </li>\\n</ul>\");}]);"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ment.io/dist/templates.js",
    "content": "angular.module(\"mentio\").run([\"$templateCache\", function($templateCache) {$templateCache.put(\"mentio-menu.tpl.html\",\"<ul class=\\\"dropdown-menu\\\" style=\\\"display:block\\\">\\n    <li mentio-menu-item=\\\"item\\\" ng-repeat=\\\"item in items track by $index\\\">\\n        <a class=\\\"text-primary\\\" ng-bind-html=\\\"item.label | mentioHighlight:triggerText:\\'menu-highlighted\\' | unsafe\\\"></a>\\n    </li>\\n</ul>\");}]);"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ment.io/gulpfile.js",
    "content": "'use strict';\n\nvar gulp = require('gulp');\nvar gutil = require('gulp-util');\nvar fs = require('fs');\nvar concat = require('gulp-concat');\nvar uglify = require('gulp-uglify');\nvar templateCache = require('gulp-angular-templatecache');\nvar gjshint = require('gulp-jshint');\nvar ngAnnotate = require('gulp-ng-annotate');\nvar stylish = require('jshint-stylish');\n\nvar port = gutil.env.port || 3000;\nvar covport = gutil.env.covport || 3001;\nvar lrport = gutil.env.lrport || 35729;\nvar openBrowser = gutil.env.browser;\nvar bump = require('gulp-bump');\n\n/*\n * Default task is to start the site\n */\ngulp.task('default', ['site']);\n\ngulp.task('site', ['copy', 'dist'], function () {\n    var express = require('express');\n    var app = express();\n\n    app.use(require('connect-livereload')({\n        port: lrport\n    }));\n\n    app.use(express.static('./'));\n\n    app.listen(port, function () {\n        var lrServer = require('gulp-livereload')();\n\n        gulp.watch(['srcgulp.task('test', ['copy', 'dist'], function () {\n    testTask({\n        isWatch: gutil.env.hasOwnProperty('watch')\n    });\n});\n\ngulp.task('coveralls', function () {\n    var coveralls = require('gulp-coveralls');\n\n    gulp.src('./coverage/**/lcov.info')\n      .pipe(coveralls());\n});\n\ngulp.task('coverage', function () {\n    var express = require('express');\n    var app = express();\n    var coverageFile;\n    var karmaHtmlFile;\n\n    function getTestFile (path) {\n        if (fs.existsSync(path)) {\n            var files = fs.readdirSync(path);\n\n            if (files) {\n                for (var i = 0; i < files.length; i++) {\n                    if (fs.lstatSync(path + '/' + files[i]).isDirectory()) {\n                        return files[i];\n                    } else {\n                        return files[i];\n                    }\n                }\n            }\n        }\n    }\n\n    testTask({\n        isWatch: gutil.env.hasOwnProperty('watch'),\n        reporters: ['progress', 'coverage', 'threshold']\n    });\n\n    setTimeout(function () {\n        coverageFile = getTestFile('coverage');\n        karmaHtmlFile = getTestFile('karma_html');\n\n        app.use(express.static('./'));\n\n        app.listen(covport, function openPage () {\n            if (coverageFile) {\n                require('open')('http://localhost:' + covport + '/coverage/' + coverageFile);\n            }\n        });\n    }, 3000);\n});"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ment.io/karma.conf.js",
    "content": "'use strict';\n\nmodule.exports = function(config) {\n    config.set({\n        frameworks: ['jasmine'],\n        files: [\n            'bower_components/**/*.js',\n            'src/main/webapp/**/*.js'\n        ],\n        exclude: [],\n\n        preprocessors: {\n            './src/**/*.js': 'coverage'\n        },\n        reporters: ['junit','progress','coverage','threshold'],\n\n        junitReporter: {\n            outputFile: 'test-reports/junit.xml',\n            suite: 'ment.io'\n        },\n\n        thresholdReporter: {\n            statements: 0,\n            branches: 0,\n            functions: 0,\n            lines: 0\n        },\n\n        coverageReporter: {\n              type: 'lcov',\n              dir:'coverage/'\n        },\n        port: 8085,\n        colors: true,\n        logLevel: config.LOG_INFO,\n        autoWatch: false,\n        browsers: ['PhantomJS'],\n        captureTimeout: 20000,\n        singleRun: false,\n        reportSlowerThan: 500\n\n    });\n};\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ment.io/ment.io/index.html",
    "content": "<!DOCTYPE html>\n<html ng-app=\"mentio-demo\">\n<head>\n    <meta charset=\"utf-8\" />\n    <title>{{title}}</title>\n    <link data-require=\"bootstrap-css@3.1.1\" data-semver=\"3.1.1\" rel=\"stylesheet\" href=\"//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css\" />\n    <link rel=\"stylesheet\" href=\"styles.css\" />\n    <script src=\"//ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular.js\"></script>\n    <script src=\"//ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular-route.min.js\"></script>\n    <script src=\"//tinymce.cachefly.net/4.1/tinymce.min.js\"></script>\n    <script src=\"/dist/mentio.js\"></script>\n    <script src=\"scripts.js\"></script>\n    <script src=\"tinymce.js\"></script>\n    </head>\n<body ng-controller=\"mentio-demo-ctrl\">\n<div>\n    <nav class=\"navbar navbar-default\" role=\"navigation\">\n        <div class=\"container\">\n            <div class=\"navbar-header\">\n                <a class=\"navbar-brand\" ng-href=\"#\">ment.io</a>\n                <ul class=\"nav navbar-nav\">\n                    <li ng-class=\"{active: tab === 'examples' }\"><a ng-href=\"#/examples\">Demo</a></li>\n                    <li ng-class=\"{active: tab === 'documentation' }\"><a ng-href=\"#/documentation\">Documentation</a></li>\n                </ul>\n            </div>\n        </div>\n    </nav>\n    <div ng-view></div>\n\n    <script type=\"text/ng-template\" id=\"examples.html\">\n        <form action=\"#\">\n        <div class=\"container\">\n            <div class=\"row\">\n                <header class=\"text-center\">\n                    <h1 class=\"heading\">Ment.io</h1>\n                    <h6 class=\"text-muted\">(Angular @mentions with macros)</h6>\n                </header>\n            </div>\n            <div class=\"row\">\n                <div class=\"col-md-12\">\n\n                    <div class=\"form-group\">\n                        <h3>Content Editable:</h3>\n                        <div contenteditable mentio\n                            mentio-typed-term=\"typedTerm\"\n                            mentio-macros=\"macros\"\n                            mentio-require-leading-space=\"true\"\n                            mentio-select-not-found=\"true\"\n                            class=\"editor form-control\"\n                            mentio-id=\"'htmlContent'\"\n                            id=\"htmlContent\"\n                            ng-model=\"htmlContent\"\n                            >\n                        </div>\n                        <span class=\"caption small\">Mentioned: {{typedTerm}}</span>\n                    </div>\n\n                    <mentio-menu\n                                mentio-for=\"'htmlContent'\"\n                                mentio-trigger-char=\"'@'\"\n                                mentio-items=\"people\"\n                                mentio-template-url=\"/people-mentions.tpl\"\n                                mentio-search=\"searchPeople(term)\"\n                                mentio-select=\"getPeopleText(item)\"\n                                ></mentio-menu>\n\n                    <div class=\"form-group\">\n                        <h3>Text Area:</h3>\n                        <textarea mentio\n\n                                mentio-macros=\"macros\"\n                                mentio-trigger-char=\"'@'\"\n                                mentio-items=\"people\"\n                                mentio-template-url=\"/people-mentions.tpl\"\n                                mentio-search=\"searchPeople(term)\"\n                                mentio-select=\"getPeopleTextRaw(item)\"\n                                mentio-typed-term=\"typedTerm2\"\n\n                                class=\"editor form-control\"\n                                mentio-id=\"'theTextArea'\"\n                                ng-model=\"theTextArea\"\n                                ng-trim=\"false\"\n                                rows=\"6\">\n                        </textarea>\n                        <span class=\"caption small\">Mentioned: {{typedTerm2}}</span>\n                   </div>\n\n                    <mentio-menu\n\n                                mentio-for=\"'theTextArea'\"\n                                mentio-trigger-char=\"'#'\"\n                                mentio-items=\"products\"\n                                mentio-template-url=\"/product-mentions.tpl\"\n                                mentio-search=\"searchProducts(term)\"\n                                mentio-select=\"getProductTextRaw(item)\"></mentio-menu>\n\n                    <div class=\"form-group\">\n                        <h3>Text Input:</h3>\n                        <!--Note the use of an angular expression for the ID.  This can be done within ng-repeat using $index-->\n                        <input mentio\n\n                                ng-model=\"theText\"\n                                mentio-id=\"'theText' + myIndexValue\"\n                                type=\"text\"\n                                class=\"form-control\"\n                                ng-trim=\"false\"\n                                size=\"100\"/>\n                    </div>\n\n                    <mentio-menu\n                                mentio-for=\"'theText' + myIndexValue\"\n                                mentio-trigger-char=\"'#'\"\n                                mentio-items=\"products\"\n                                mentio-template-url=\"/product-mentions.tpl\"\n                                mentio-search=\"searchProducts(term)\"\n                                mentio-select=\"getProductTextRaw(item)\"></mentio-menu>\n                    <mentio-menu\n                                mentio-for=\"'theText' + myIndexValue\"\n                                mentio-trigger-char=\"'@'\"\n                                mentio-items=\"people\"\n                                mentio-template-url=\"/people-mentions.tpl\"\n                                mentio-search=\"searchPeople(term)\"\n                                mentio-select=\"getPeopleTextRaw(item)\"></mentio-menu>\n\n\n                    <div class=\"form-group\">\n                        <h3>Minimal:</h3>\n                        <!--Note no need for external mentio-menu elements because there is only one trigger character needed-->\n                        <input type=\"text\" mentio mentio-typed-text=\"typedTerm\" mentio-items=\"simplePeople | filter:label:typedTerm\" class=\"form-control\" ng-model=\"theTextArea2\"\n                                  size=\"100\"/>\n                        </textarea>\n                    </div>\n\n                    <div class=\"form-group\">\n                        <h3>TinyMCE (iframe-based):</h3>\n                        <textarea ui-tinymce=\"tinyMceOptions\" mentio mentio-typed-text=\"typedTerm\" \n                            mentio-items=\"simplePeople | filter:label:typedTerm\" ng-model='foo'\n                            mentio-iframe-element=\"iframeElement\"></textarea>\n                    </div>\n\n                    <div class=\"form-group\">\n                         <input type=\"submit\">\n                    </div>\n                </div>\n            </div>\n        </div>\n        </form>\n    </script>\n\n    <script type=\"text/ng-template\" id=\"/product-mentions.tpl\">\n        <ul class=\"list-group product-search demo-scrollable-menu\">\n            <li mentio-menu-item=\"product\" ng-repeat=\"product in items\" class=\"list-group-item clearfix\">\n                <div class=\"row\">\n                    <div class=\"col-xs-2 text-center\">\n                        <img ng-src=\"{{product.imageUrl}}\" class=\"product-photo\">\n                    </div>\n                    <div class=\"col-xs-10\">\n                        <h4 class=\"list-group-item-heading\">{{product.title | words:5}}</h4>\n                        <p class=\"list-group-item-text\">{{product.description | words:7}}</p>\n                    </div>\n                </div>\n            </li>\n        </ul>\n    </script>\n\n    <script type=\"text/ng-template\" id=\"/people-mentions.tpl\">\n        <ul class=\"list-group user-search\">\n            <li mentio-menu-item=\"person\" ng-repeat=\"person in items\" class=\"list-group-item\">\n                <img ng-src=\"{{person.imageUrl}}\" class=\"user-photo\">\n                <span class=\"text-primary\" ng-bind-html=\"person.name | mentioHighlight:typedTerm:'menu-highlighted' | unsafe\"></span>\n                <em class=\"text-muted\" ng-bind=\"person.bio | words:5\"></em>\n            </li>\n        </ul>\n    </script>\n\n    <script type=\"text/ng-template\" id=\"documentation.html\">\n        <div class=\"container\">\n            <div class=\"row\">\n                <header class=\"text-center\">\n                    <h1 class=\"heading\">Ment.io</h1>\n                    <h6 class=\"text-muted\">(Angular @mentions with macros)</h6>\n                </header>\n                <h3 class=\"section-heading\">Overview</h3>\n                The <code>mentio</code> directive is applied to any element that accepts selectable text input and exposes \n                an <code>ngModel</code>.\n                The <code>mentio</code> directive watches the <code>ngModel</code> of the element for changes.  If the user enters\n                a sequence of non-wihtespace characters starting with a <em>trigger character</em>, a typeahead menu appears.\n                <p></p>\n                To get started, use\n                <p></p>\n                <pre>bower install ment.io --save</pre>\n                or\n                <p></p>\n                <pre>npm install ment.io --save</pre>\n                <p>Then add 'mentio' to your app’s module dependency list.</p>\n\n                <h3 class=\"section-heading\">Directives</h3>\n                <header class=\"documentation-element\">\n                    <code>\n                    mentio\n                    </code>\n                </header>\n\n                For the mentio directive, specification of options can either be done inline, within\n                the same element for one triggering character, or using a series of configurations if there are a multiple applicable\n                triggering characters.</p>\n\n                <p>\n                When detecting user input that should show a typeahead menu, the following rules apply:\n                <ul>\n                    <li>A specified <em>trigger character</em> is present in the text preceding the current caret location (e.g. @)</li>\n                    <li>A space precedes the trigger character</li>\n                    <li>The text following the trigger character contains no spaces up to the current caret location</li>\n                </ul>\n                When a match is found, the current text after the trigger character is assigned to the scope property specified in the\n                <code>mentio-typed-term</code> attribute if present.\n                It is only possible for one trigger character to cause a menu to show at a time.  Also, only one menu will display on a given page\n                at a time.\n                </p>\n\n                <p>Definition of menu behavior for each desired trigger character can be specified\n                with separate <code>mentio-menu</code> directives.\n                However the <code>mentio</code> directive does not require separate <code>mentio-menu</code> directives.\n                If only one trigger character\n                is needed, the <code>mentio-trigger-char</code>, <code>mentio-items</code>, <code>mentio-template-url</code>, <code>mentio-search</code>,\n                and <code>mentio-select</code> attributes from the <code>mentio-menu</code> directive can be specified directly along side\n                the <code>mentio</code> directive.\n                </p>\n\n                <p>To support macro expansion, a translation table to use for macros can be assigned through the <code>macros</code>\n                attribute which will expand typed sequences of characters into predefined strings of HTML or text.\n                </p>\n\n                <h4 class=\"section-heading\">Attributes</h4>\n\n                <header class=\"text-primary documentation-attr\">ng-model</header>\n                <strong>Required.</strong> An <code>ngModel</code> is required on the element for mentio to be able to operate.\n\n                <header class=\"text-primary documentation-attr\">mentio-id</header>\n                <strong>Optional.</strong> An angular expression representing the ID of the <code>mentio</code> element.  This value\n                is matched by the <code>mentio-for</code> attribute on any separate <code>mentio-menu</code> elements.  \n                If no <code>mentio-id</code> is specified, the <code>id</code>\n                html attribute will be used to match <code>mentio-for</code>.  The <code>mentio-id</code> is unnecessary if there\n                is only one trigger character and all attributes are specified on the <code>mentio</code> directive.\n\n                <header class=\"text-primary documentation-attr\">mentio-typed-term</header>\n                <strong>Optional.</strong> If specified, binds a scope property that will be assigned\n                the current value of the typed term when the <code>mentio</code> menu is active.\n\n                <header class=\"text-primary documentation-attr\">mentio-macros</header>\n                <strong>Optional.</strong> Specifies a JSON map of macro translations.  The key should be a simple sequence of characters, not including spaces.  The key\n                will be matched case-insensitive.  When a match is detected, the value in the macro table will be expanded in place of the\n                macro the user typed.\n                <p></p>\n                An example from the sample demo in <code>scripts.js</code>:\n                <p></p>\n                <pre>\n                    $scope.macros = {\n                        'brb': 'Be right back',\n                        'omw': 'On my way',\n                        '(smile)' : '&lt;img src=\"http://a248.e.akamai.net/assets.github.com/images/icons/emoji/smile.png\"' +\n                                ' height=\"20\" width=\"20\"&gt;'\n                    };</pre>\n\n                <header class=\"text-primary documentation-attr\">mentio-require-leading-space</header>\n                <strong>Optional.</strong> When <code>true</code>, specifies that the menu will only be displayed if the trigger character is \n                preceded by a space.  This option can benefit the user by \n                disambiguating typeahead text from other text that might normally\n                contain the configured trigger character, but for some languages like Chinese, spaces cannot be required.\n                <p></p>\n \n                <header class=\"text-primary documentation-attr\">mentio-iframe-element</header>\n                <strong>Optional.</strong> Specifies an iframe DOM element within which the ment.io menu will be shown.\n                This is useful for situations where the actual control is a <code>textarea</code>, but the editor is \n                presented in an iframe, like TinyMCE.\n                <p></p>\n\n                <header class=\"text-primary documentation-attr\">mentio-select-not-found</header>\n                <strong>Optional.</strong> Will run the <code>mentio-select</code> function passing a the <code>typedText</code> scope variable in the label property of a JSON object when the typedText will become empty (after a space was typed, for instance).  This is useful for creating new items dynamically even if they do not exist in your backend service yet (e.g. tags).\n                <p></p>\n\n                 <h4 class=\"section-heading\">Provided Scope Properties</h4>\n\n                <header class=\"text-primary documentation-attr\">typedTerm</header>\n                The <code>typedTerm</code> scope property is bound to the text currently after the trigger char.  \n                This can be referenced from within the\n                <code>mentio-menu</code> template to highlight text when presenting menu items.\n\n                <p></p>\n \n                <strong>Special note for contenteditable:</strong> To see the ment.io directive operate in a contenteditable, \n                you must have set up the contenteditable to update the <code>ngModel</code> as per the AngularJS examples here:\n                <a href=\"https://docs.angularjs.org/api/ng/type/ngModel.NgModelController\">\n                https://docs.angularjs.org/api/ng/type/ngModel.NgModelController</a>.  The approach of creating a custom\n                <code>contenteditable</code> directive is demonstrated in the ment.io demo code.\n\n                <header class=\"text-primary documentation-attr\">mentio-trigger-char, mentio-items, mentio-template-url, mentio-search,\n                mentio-select </header>\n                <strong>Optional.</strong> If only one trigger char is needed, these attribtues can be used on the <code>mentio</code>\n                directive.  See the description of these attributes in <code>mentio-menu</code> below for details. \n\n                <header class=\"documentation-element\">\n                    <code>\n                    mentio-menu\n                    </code>\n                </header>\n                <p>The <code>mentio-menu</code> element defines a menu for each a trigger\n                character that the <code>mentio</code> directive\n                should respond to.  The <code>mentio-menu</code> identifies which <code>mentio</code> directive it is targeting\n                by referring to the element <code>id</code> of the element containing the <code>mentio</code> directive.\n                </p>\n                <p>Each menu must specify the trigger character, a data collection,\n                the template to use to render the menu, a search\n                function, and a select function.  Based on the specified attributes,\n                the specified menu will display whenever text in the target\n                text element is changed.  </p>\n                <h4 class=\"section-heading\">Attributes</h4>\n\n                If only one trigger character\n                is needed, the <code>mentio-trigger-char</code>, <code>mentio-items</code>, <code>mentio-template-url</code>, <code>mentio-search</code>,\n                and <code>mentio-select</code> attributes can be placed on the same element with the <code>mentio</code> directive.\n\n\n                <header class=\"text-primary documentation-attr\">mentio-for</header>\n                <strong>Required.</strong> The string literal <code>id</code> of the element containing a\n                <code>mentio</code> directive that this <code>mentio-menu</code> should attach to.\n\n                <header class=\"text-primary documentation-attr\">mentio-items</header>\n                <strong>Required.</strong> The data list to bind the menu to.  This must be a reference to a value in current scope.\n                Since a <code>mentio-menu</code> has\n                isolate scope, the list referenced by the <code>items</code> attribute will\n                be passed down through the child scope contexts to the template used in the <code>mention-rule</code>, which then allows it to\n                be refrenced in an angular expression that drives an <code>ng-repeat</code>.  Note the reference to <code>items</code> in\n                the example below.\n                <p></p>\n                <pre>\n                &lt;mentio-menu mentio-for=\"'theText'\" mentio-trigger-char=\"@\" mentio-items=\"people\" mentio-template-url=\"<b>/people-mentions.tpl</b>\"\n                             mentio-search=\"searchPeople(term)\" mentio-select=\"getPeopleTextRaw(item)\"&gt&lt;/mentio-menu&gt\n\n                &lt;script type=\"text/ng-template\" id=\"<b>/people-mentions.tpl</b>\"&gt;\n                    &lt;ul class=\"list-group user-search\"&gt;\n                        &lt;i mentio-menu-item=\"person\" ng-repeat=\"person in <b>items</b>\" class=\"list-group-item\"&gt;\n                            &lt;mg ng-src=\" { {person.imageUrl} }\" class=\"user-photo\"&gt;\n                            &lt;span class=\"text-primary\"\n                                ng-bind-html=\"person.name | mentioHighlight:typedTerm:'menu-highlighted' | unsafe\">&lt;/span&gt;\n                            &lt;em class=\"text-muted\" ng-bind=\"person.bio | words:5\">&lt;/em&gt;\n                        &lt;/li&gt;\n                    &lt;/ul&gt;\n                &lt;/script&gt;</pre>\n\n                <strong>Node</strong> The mentio directive watches the collection \n                referenced by <code>mentio-items</code>.  If the values in this list are cached and never change, the menu \n                will not appear.  Make sure in your <code>mentio-search</code> function to modify the items list in some way.\n\n                <header class=\"text-primary documentation-attr\">mentio-trigger-char</header>\n                <strong>Optional.</strong> The character that should trigger the menu behavior.  In the example, '@' and '#'s are used. \n                The default value is '@'.\n\n                <header class=\"text-primary documentation-attr\">mentio-template-url</header>\n                <strong>Optional.</strong>\n                Specifies the template url to use to render the select menu.  The template should iterate the <code>items</code> list to\n                present a menu of choices.  The <code>items</code> scope property from the <code>mentio-menu</code> is available to iterate\n                within an <code>ng-repeat</code>. The <code>typedTerm</code> scope property\n                from the <code>mentio-menu</code> can be accessed in order\n                to highlight text in the menu.  The default template presents a simple menu, and assumes that each object has a property\n                called <code>label</code>.\n\n                <header class=\"text-primary documentation-attr\">mentio-search</header>\n                <strong>Optional.</strong>\n                Specifies a function call to invoke when the trigger char \n                has been entered into the target text element.  The currently active\n                typed term after the trigger char is bound as the <code>term</code> argument in the expression.\n                <p></p>\n                The implementation of the search function should populate the data collection referenced by the <code>mentio-items</code>\n                attribute with data.  No return is expected from\n                the search fucntion.\n                <p></p>\n                If no search function is specified, the list of objects in <code>mentio-items</code> will \n                be scanned and the <code>label</code> property will be matched against the typed term.  Alternatively, the expression\n                for <code>mentio-items</code> can just be specified using a filter, as in this example:\n                <p></p>\n\n                <pre>\n                    &lt;input type=\"text\" mentio mentio-typed-text=\"typedTerm\" \n                        mentio-items=<strong>\"simplePeople | filter:label:typedTerm\"</strong> class=\"form-control\" \n                        ng-model=\"theTextArea2\" size=\"100\"/&gt;               \n                </pre>\n\n                <header class=\"text-primary documentation-attr\">mentio-select</header>\n                <strong>Optional.</strong>\n                Specifies a function call to invoke when the user has picked an item in the menu.  The item in <code>mentio-items</code>\n                corresponding to the selected item in the menu is bound to the <code>item</code> parameter of the select function.  The\n                select function may return a string or a <code>Promise</code> that returns a string value to use to replace the \n                current trigger char and mention text.\n                <p></p>\n                If no select function is specified, the trigger char is prepended to the <code>label</code> property of the current item.\n\n                <h4 class=\"section-heading\">Provided Scope Properties</h4>\n\n                <header class=\"text-primary documentation-attr\">items</header>\n                The name <code>items</code> is made available within the scope of the <code>mentio-menu</code> template. It is a mapping\n                from the <code>mentio-items</code> attribute specified on the <code>mentio-menu</code> or <code>mentio</code> directives.\n\n                <header class=\"documentation-element\">\n                    <code>\n                    mentio-menu-item\n                    </code>\n                </header>\n                A <code>mentio-menu-item</code> must be contained within a <code>mentio-menu</code> template.\n                When applied to an element in this context, the <code>mentio-menu-item</code> directive will add or remove the\n                class <code>active</code> to highlight an item in the menu when it is considered selected by the <code>mentio-menu</code>,\n                including during mouse-enter events.  If the user\n                clicks an element with the <code>mentio-menu-item</code> directive, the item corresponding to the currently\n                active <code>mentio-menu-item</code> will be selected by invoking the <code>select</code> function provided in the\n                <code>mentio-search</code> attribute of the <code>mentio-menu</code>.\n\n                <h3 class=\"section-heading\">Filters</h3>\n                <header class=\"documentation-element\">\n                    <code>\n                    mentioHighlight\n                    </code>\n                </header>\n                A filter that can be used to replace text with a span having an arbitrary class.  The class must be passed as an extended\n                second argument to the filter.  In the following example, text that matches the mentioned text after the trigger char will\n                be replaced with a <code>span</code> element with the class <code>menu-highlighted</code>:\n\n                <p></p>\n                <pre>person.name | mentioHighlight:typedTerm:'menu-highlighted'</pre>\n                The filter is useful within the <code>mentio-menu</code> template when iterating the items in the select menu for the user\n                to pick.\n               <p></p>\n           </div>\n        </div>\n    </script>\n\n\n    <a href=\"https://github.com/jeff-collins/ment.io\"><img style=\"position: absolute; top: 0; right: 0; border: 0;\" src=\"https://camo.githubusercontent.com/365986a132ccd6a44c23a9169022c0b5c890c387/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f7265645f6161303030302e706e67\" alt=\"Fork me on GitHub\" data-canonical-src=\"https://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png\"></a>\n\n    </div>\n</body>\n\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ment.io/ment.io/peopledata.json",
    "content": "[\n   {\n      \"name\":\"Iqbal\",\n      \"bio\":\"I think therefore I am\",\n      \"imageUrl\":\"https://avatars0.githubusercontent.com/u/3493285?s=460\"\n   },\n   {\n      \"name\":\"Frank\",\n      \"bio\":\"Long walks in the park\",\n      \"imageUrl\":\"https://avatars0.githubusercontent.com/u/207585?s=460\"\n   },\n   {\n      \"name\":\"Suzie\",\n      \"bio\":\"Icecream eater\",\n      \"imageUrl\":\"http://educationalsoftware.wikispaces.com/file/view/manga_suzie.jpg/38030142/178x177/manga_suzie.jpg\"\n   },\n   {\n      \"name\":\"Godzilla\",\n      \"bio\":\"Roar!\",\n      \"imageUrl\":\"http://www.badassoftheweek.com/godzilla.jpg\"\n   }\n]"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ment.io/ment.io/productdata.json",
    "content": "[\n    {\n        \"sku\": \"XBR55X900A\",\n        \"title\":\"55 in. Class (54.6in. diag) XBR 4K Ultra HD TV | XBR55X900A\",\n        \"imageUrl\":\"http://ecx.images-amazon.com/images/I/71cqu%2BgwJyL._SL1500_.jpg\",\n        \"description\":\"Model Features: 4K Ultra HD, 4K X-Reality PRO Picture Engine, 65W front-facing speaker system, TRILUMINOS display, Dynamic Edge LED backlight, Motionflow XR 960, wireless smartphone mirroring technology, plus 4 pairs of 3D glasses, HDMI 2.0 support for next 4K video formats (Free upgrade)\"\n    },\n    {\n        \"sku\": \"L32B1120\",\n        \"title\":\"Haier 32-Inch 720p 60Hz LCD TV - Black (L32B1120)\",\n        \"imageUrl\":\"http://ecx.images-amazon.com/images/I/41CQD4PazFL.jpg\",\n        \"description\":\"Haier L32B1120 32-Inch 720p LCD TV The Haier L32B1120 32\\\" LCD HDTV is a 720p high definition sleek TV with everything you need. It has 2 HDMI inputs for various high definition devices and a contrast ratio of 3,000 to 1 for razor sharp clarity.\"\n    },\n    {\n        \"sku\": \"BATLOGOLIT\",\n        \"title\":\"Batman Logo Night Light\",\n        \"imageUrl\":\"http://ecx.images-amazon.com/images/I/31zttVXWsLL.jpg\",\n        \"description\":\"Night light features the Batman bat-signal. Will bring a soothing glow to any child's room. Automatic light sensor turns light on and off. Bulb included. Dimensions: 4.5\\\"H x 3.5\\\"W x 1.5\\\"D\"\n    },\n    {\n        \"sku\": \"DAMPRIDQ9L\",\n        \"title\":\"DampRid FG91 Easy-Fill System Any Room Moisture Absorber\",\n        \"imageUrl\":\"http://ecx.images-amazon.com/images/I/51lTO--dQ9L.jpg\",\n        \"description\":\"DampRid FG91 Easy-Fill System Any Room Moisture Absorber\"\n    },\n    {\n        \"sku\": \"ICUPDCCOMIC\",\n        \"title\":\"ICUP DC Comics Batman Ice Cube Tray\",\n        \"imageUrl\":\"http://ecx.images-amazon.com/images/I/41jUeLPk23L.jpg\",\n        \"description\":\"Black Twelve Cavity Ice Tray That Creates Batman's Famous Bat Symbol. Become A Kitchen Superhero With Ice Cubes Sent From The Dark Knight.\"\n    },\n    {\n        \"sku\": \"GBCLIPBK01\",\n        \"title\":\"Geoffrey Beene Men's Money Clip, Silver/Black, No Size\",\n        \"imageUrl\":\"http://ecx.images-amazon.com/images/I/31SWC8OlcBL.jpg\",\n        \"description\":\"Geoffrey Beene Men's Money Clip, Silver/Black, No Size\"\n    },\n    {\n        \"sku\": \"DIS_FRZ_FF\",\n        \"title\":\"Disney Store - Girls - Frozen Cold Feet - Flip Flop\",\n        \"imageUrl\":\"http://ecx.images-amazon.com/images/I/51y5O7WsV1L.jpg\",\n        \"description\":\"Amazon.com: Disney Store - Girls - Frozen Cold Feet - Flip Flop: Shoes\"\n    },\n    {\n        \"sku\": \"ANASTR3000\",\n        \"title\":\"Anker® Astro Mini 3000mAh Ultra-Compact Portable Charger Lipstick-Sized External Battery Power Bank Pack for iPhone 5S, 5C, 5, 4S, Galaxy S5, S4, S3, Note 3, Nexus 4, HTC One, One 2 (M8), Nokia Lumia 520, 1020, most other Smartphones (Apple Adapters- 30 pin and Lightning, NOT Included) - Silver\",\n        \"imageUrl\":\"http://ecx.images-amazon.com/images/I/31cwVJtaHUL.jpg\",\n        \"description\":\"Anker® Astro Mini 3000mAh Ultra-Compact Portable Charger Lipstick-Sized External Battery Power Bank Pack for iPhone 5S, 5C, 5, 4S, Galaxy S5, S4, S3, Note 3, Nexus 4, HTC One, One 2 (M8), Nokia Lumia 520, 1020, most other Smartphones (Apple Adapters- 30 pin and Lightning, NOT Included) - Silver\"\n    },\n    {\n        \"sku\": \"JIVEBLTZ55\",\n        \"title\":\"Amazon.com: CableJive iBoltz XS, short charge cable for iPhone 5 / 5S / 5C, iPad Air, iPod nano and all Apple Lightning devices. Charge and Sync cable. Extra Short (12cm) Lightning to USB Sync and Charge Cable.: MP3 Players & Accessories\",\n        \"imageUrl\":\"http://ecx.images-amazon.com/images/I/31j-7yVAxdL.jpg\",\n        \"description\":\"More is less in this case. Only 5 inches (just 12cm) of cable means that this cable can be everywhere you want it to be without hassle or cable tangle. Made for iPhone certification means that this cable is constructed under strict guidelines and will be durable, ready for your active lifestyle.\"\n    }\n]"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ment.io/ment.io/scripts.js",
    "content": "'use strict';\n\nangular.module('mentio-demo', ['mentio', 'ngRoute', 'ui.tinymce'])\n\n    .config(function($routeProvider) {\n        $routeProvider\n            .when('/', {\n                templateUrl: 'examples.html',\n                tab: 'examples',\n                title: 'Ment.io examples'\n            })\n            .when('/documentation', {\n                templateUrl: 'documentation.html',\n                tab: 'documentation',\n                title: 'Ment.io Documentation'\n            })\n            .when('/examples', {\n                templateUrl: 'examples.html',\n                tab: 'examples',\n                title: 'Ment.io examples'\n            });\n    })\n\n    .run(function ($rootScope) {\n        $rootScope.$on('$routeChangeSuccess', function (event, current) {\n            if (current.$$route) {\n                $rootScope.title = current.$$route.title;\n                $rootScope.tab = current.$$route.tab;\n            }\n        });\n    })\n\n    .controller('mentio-demo-ctrl', function ($scope, $rootScope, $http, $q, $sce, $timeout, mentioUtil) {\n\n        $scope.tinyMceOptions = {\n            init_instance_callback: function(editor) {\n                $scope.iframeElement = editor.iframeElement;\n            }\n        };\n\n        $scope.macros = {\n            'brb': 'Be right back',\n            'omw': 'On my way',\n            '(smile)' : '<img src=\"http://a248.e.akamai.net/assets.github.com/images/icons/emoji/smile.png\"' +\n                ' height=\"20\" width=\"20\">'\n        };\n        $scope.myIndexValue = \"5\";\n\n        $scope.searchProducts = function(term) {\n            var prodList = [];\n\n            return $http.get('productdata.json').then(function (response) {\n                angular.forEach(response.data, function(item) {\n                    if (item.title.toUpperCase().indexOf(term.toUpperCase()) >= 0) {\n                        prodList.push(item);\n                    }\n                });\n\n                $scope.products = prodList;\n                return $q.when(prodList);\n            });\n        };\n\n        $scope.searchPeople = function(term) {\n            var peopleList = [];\n            return $http.get('peopledata.json').then(function (response) {\n                angular.forEach(response.data, function(item) {\n                    if (item.name.toUpperCase().indexOf(term.toUpperCase()) >= 0) {\n                        peopleList.push(item);\n                    }\n                });\n                $scope.people = peopleList;\n                return $q.when(peopleList);\n            });\n        };\n\n        $scope.searchSimplePeople = function(term) {\n            return $http.get('simplepeopledata.json').then(function (response) {\n                $scope.simplePeople = [];\n                angular.forEach(response.data, function(item) {\n                    if (item.label.toUpperCase().indexOf(term.toUpperCase()) >= 0) {\n                        $scope.simplePeople.push(item);\n                    }\n                });\n            });\n        };\n\n        $scope.getProductText = function(item) {\n            return '[~<strong>' + item.sku + '</strong>]';\n        };\n\n        $scope.getProductTextRaw = function(item) {\n            var deferred = $q.defer();\n            /* the select() function can also return a Promise which ment.io will handle\n            propertly during replacement */\n            $timeout(function() {\n                deferred.resolve('#' + item.sku);\n            }, 500);\n            return deferred.promise;\n        };\n\n        $scope.getPeopleText = function(item) {\n            return '[~<i>' + (item.name || item.label) + '</i>]';\n        };\n\n        $scope.getPeopleTextRaw = function(item) {\n            return '@' + item.name;\n        };\n\n        $scope.resetDemo = function() {\n            $timeout(function() {\n                var html = \"Try me @ or add a macro like brb, omw, (smile)\";\n                var htmlContent = document.querySelector('#htmlContent');\n                if (htmlContent) {\n                    var ngHtmlContent = angular.element(htmlContent);\n                    ngHtmlContent.html(html);\n                    ngHtmlContent.scope().htmlContent = html;\n                    mentioUtil.selectElement(null, htmlContent, [0], 8);\n                    ngHtmlContent.scope().$apply();\n                }\n            }, 0);\n        };\n\n        $rootScope.$on('$routeChangeSuccess', function (event, current) {\n            $scope.resetDemo();\n        });\n \n        $scope.theTextArea = 'Type an # and some text';\n        $scope.theTextArea2 = 'Type an @';\n        $scope.searchSimplePeople('');\n        $scope.resetDemo();\n    })\n\n    .directive('contenteditable', ['$sce', function($sce) {\n        return {\n            restrict: 'A', // only activate on element attribute\n            require: '?ngModel', // get a hold of NgModelController\n            link: function(scope, element, attrs, ngModel) {\n                function read() {\n                    var html = element.html();\n                    if (attrs.stripBr && html === '<br>') {\n                        html = '';\n                    }\n                    ngModel.$setViewValue(html);\n                }\n\n                if(!ngModel) return; // do nothing if no ng-model\n                ngModel.$render = function() {\n                    if (ngModel.$viewValue !== element.html()) {\n                        element.html($sce.getTrustedHtml(ngModel.$viewValue || ''));\n                    }\n                };\n                element.on('blur keyup change', function() {\n                    scope.$apply(read);\n                });\n                read(); // initialize\n            }\n        };\n    }])\n    .filter('words', function () {\n        return function (input, words) {\n            if (isNaN(words)) {\n                return input;\n            }\n            if (words <= 0) {\n                return '';\n            }\n            if (input) {\n                var inputWords = input.split(/\\s+/);\n                if (inputWords.length > words) {\n                    input = inputWords.slice(0, words).join(' ') + '\\u2026';\n                }\n            }\n            return input;\n        };\n    });\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ment.io/ment.io/simplepeopledata.json",
    "content": "[\n    {\n        \"label\":\"Iqbal\"\n    },\n    {\n        \"label\":\"Frank\"\n    },\n    {\n        \"label\":\"Suzie\"\n    },\n    {\n        \"label\":\"Godzilla\"\n    }\n]"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ment.io/ment.io/styles.css",
    "content": ".editor {\n\theight: auto;\n    min-height: 140px;\n}\n\n.menu-highlighted {\n    font-weight: bold;\n}\n\n.product-search, .user-search {\n    box-shadow: 0 5px 15px rgba(0,0,0,.5);\n    border-radius: 6px;\n    -webkit-box-shadow: 0 3px 9px rgba(0,0,0,.5);\n    box-shadow: 0 3px 9px rgba(0,0,0,.5);\n    background-clip: padding-box;\n    outline: 0;\n}\n\n.product-search {\n    max-width: 500px;\n}\n\n.product-search .list-group-item.active {\n    background-color: #f5f5f5;\n}\n\n.product-search:hover, .user-search:hover {\n    cursor: pointer;\n}\n\n.product-search .product-photo-container {\n    float: left;\n    width: 100px;\n}\n\n.product-search .product-photo {\n    max-width: 80px;\n    max-height: 50px;\n    border-radius: 3px;\n    margin: auto;\n}\n\n.product-search .list-group-item-heading, .product-search .list-group-item-text {\n    margin-left: 10px;\n}\n\n.user-search .list-group-item.active {\n    color: #fff;\n    background-color: #428bca;\n    border-color: #428bca;\n}\n\n.user-search .list-group-item.active .text-muted {\n    color: #ccc;\n}\n\n.user-search .list-group-item.active .text-primary {\n    color: #fff;\n}\n\n.user-search .list-group-item {\n    padding: 5px;\n}\n\n.user-search .user-photo {\n    max-width: 30px;\n    max-height: 30px;\n    border-radius: 15px;\n}\n\n.documentation-attr {\n    margin-top: 20px;\n    margin-bottom: 10px;\n    font-weight: bold;\n}\n\n.documentation-element {\n    margin-top: 30px;\n    margin-bottom: 10px;\n    font-size: 20px;\n    font-weight: bold;\n}\n\n.section-heading {\n    margin-top: 30px;\n}\n\n.demo-scrollable-menu {\n    height: auto;\n    max-height: 300px;\n    overflow-y: auto;\n}\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ment.io/package.json",
    "content": "{\n  \"name\": \"ment.io\",\n  \"version\": \"0.9.23\",\n  \"description\": \"Mentions for Angular\",\n  \"main\": \"dist/mentio.js\",\n  \"scripts\": {\n    \"test\": \"echo \\\"Error: no test specified\\\" && exit 1\",\n    \"coveralls\": \"gulp coveralls\"\n  },\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"https://github.com/jeff-collins/ment.io.git\"\n  },\n  \"keywords\": [\n    \"angular\",\n    \"mentions\",\n    \"ment.io\"\n  ],\n  \"author\": \"\",\n  \"license\": \"MIT\",\n  \"bugs\": {\n    \"url\": \"https://github.com/jeff-collins/ment.io/issues\"\n  },\n  \"homepage\": \"https://github.com/jeff-collins/ment.io\",\n  \"devDependencies\": {\n    \"connect-livereload\": \"^0.4.0\",\n    \"express\": \"^4.1.2\",\n    \"gulp\": \"^3.6.2\",\n    \"gulp-angular-templatecache\": \"^1.2.1\",\n    \"gulp-bump\": \"^0.1.11\",\n    \"gulp-concat\": \"^2.2.0\",\n    \"gulp-coveralls\": \"^0.1.2\",\n    \"gulp-jshint\": \"^1.6.3\",\n    \"gulp-karma\": \"0.0.4\",\n    \"gulp-livereload\": \"^1.5.0\",\n    \"gulp-ng-annotate\": \"^0.3.0\",\n    \"gulp-uglify\": \"^0.3.1\",\n    \"gulp-util\": \"^2.2.14\",\n    \"gulp-wrap\": \"^0.3.0\",\n    \"jasmine-reporters\": \"~0.4.1\",\n    \"jshint-stylish\": \"^0.2.0\",\n    \"karma\": \"^0.12.16\",\n    \"karma-chrome-launcher\": \"^0.1.2\",\n    \"karma-coverage\": \"~0.1.4\",\n    \"karma-firefox-launcher\": \"^0.1.3\",\n    \"karma-jasmine\": \"~0.1.5\",\n    \"karma-junit-reporter\": \"~0.2.2\",\n    \"karma-phantomjs-launcher\": \"~0.1.4\",\n    \"karma-script-launcher\": \"^0.1.0\",\n    \"karma-threshold-reporter\": \"~0.1.7\",\n    \"open\": \"0.0.5\"\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ment.io/src/mentio-menu.tpl.html",
    "content": "<style>\n.scrollable-menu {\n    height: auto;\n    max-height: 300px;\n    overflow: auto;\n}\n\n.menu-highlighted {\n    font-weight: bold;\n}\n</style>\n<ul class=\"dropdown-menu scrollable-menu\" style=\"display:block\">\n    <li mentio-menu-item=\"item\" ng-repeat=\"item in items track by $index\">\n        <a class=\"text-primary\" ng-bind-html=\"item.label | mentioHighlight:typedTerm:'menu-highlighted' | unsafe\"></a>\n    </li>\n</ul>"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ment.io/src/mentio.directive.js",
    "content": "'use strict';\n\nangular.module('mentio', [])\n    .directive('mentio', ['mentioUtil', '$document', '$compile', '$log', '$timeout',\n        function (mentioUtil, $document, $compile, $log, $timeout) {\n        return {\n            restrict: 'A',\n            scope: {\n                macros: '=mentioMacros',\n                search: '&mentioSearch',\n                select: '&mentioSelect',\n                items: '=mentioItems',\n                typedTerm: '=mentioTypedTerm',\n                altId: '=mentioId',\n                iframeElement: '=mentioIframeElement',\n                requireLeadingSpace: '=mentioRequireLeadingSpace',\n                selectNotFound: '=mentioSelectNotFound',\n                trimTerm: '=mentioTrimTerm',\n                ngModel: '='\n            },\n            controller: function($scope, $timeout, $attrs) {\n\n                $scope.query = function (triggerChar, triggerText) {\n                    var remoteScope = $scope.triggerCharMap[triggerChar];\n\n                    if ($scope.trimTerm === undefined || $scope.trimTerm) {\n                        triggerText = triggerText.trim();\n                    }\n\n                    remoteScope.showMenu();\n\n                    remoteScope.search({\n                        term: triggerText\n                    });\n\n                    remoteScope.typedTerm = triggerText;\n                };\n\n                $scope.defaultSearch = function(locals) {\n                    var results = [];\n                    angular.forEach($scope.items, function(item) {\n                        if (item.label.toUpperCase().indexOf(locals.term.toUpperCase()) >= 0) {\n                            results.push(item);\n                        }\n                    });\n                    $scope.localItems = results;\n                };\n\n                $scope.bridgeSearch = function(termString) {\n                    var searchFn = $attrs.mentioSearch ? $scope.search : $scope.defaultSearch;\n                    searchFn({\n                        term: termString\n                    });\n                };\n\n                $scope.defaultSelect = function(locals) {\n                    return $scope.defaultTriggerChar + locals.item.label;\n                };\n\n                $scope.bridgeSelect = function(itemVar) {\n                    var selectFn = $attrs.mentioSelect ? $scope.select : $scope.defaultSelect;\n                    return selectFn({\n                        item: itemVar\n                    });\n                };\n\n                $scope.setTriggerText = function(text) {\n                    if ($scope.syncTriggerText) {\n                        $scope.typedTerm = ($scope.trimTerm === undefined || $scope.trimTerm) ? text.trim() : text;\n                    }\n                };\n\n                $scope.context = function() {\n                    if ($scope.iframeElement) {\n                        return {iframe: $scope.iframeElement};\n                    }\n                };\n\n                $scope.replaceText = function (text, hasTrailingSpace) {\n                    $scope.hideAll();\n\n                    mentioUtil.replaceTriggerText($scope.context(), $scope.targetElement, $scope.targetElementPath,\n                        $scope.targetElementSelectedOffset, $scope.triggerCharSet, text, $scope.requireLeadingSpace,\n                        hasTrailingSpace);\n\n                    if (!hasTrailingSpace) {\n                        $scope.setTriggerText('');\n                        angular.element($scope.targetElement).triggerHandler('change');\n                        if ($scope.isContentEditable()) {\n                            $scope.contentEditableMenuPasted = true;\n                            var timer = $timeout(function() {\n                                $scope.contentEditableMenuPasted = false;\n                            }, 200);\n                            $scope.$on('$destroy', function() {\n                                $timeout.cancel(timer);\n                            });\n                        }\n                    }\n                };\n\n                $scope.hideAll = function () {\n                    for (var key in $scope.triggerCharMap) {\n                        if ($scope.triggerCharMap.hasOwnProperty(key)) {\n                            $scope.triggerCharMap[key].hideMenu();\n                        }\n                    }\n                };\n\n                $scope.getActiveMenuScope = function () {\n                    for (var key in $scope.triggerCharMap) {\n                        if ($scope.triggerCharMap.hasOwnProperty(key)) {\n                            if ($scope.triggerCharMap[key].visible) {\n                                return $scope.triggerCharMap[key];\n                            }\n                        }\n                    }\n                    return null;\n                };\n\n                $scope.selectActive = function () {\n                    for (var key in $scope.triggerCharMap) {\n                        if ($scope.triggerCharMap.hasOwnProperty(key)) {\n                            if ($scope.triggerCharMap[key].visible) {\n                                $scope.triggerCharMap[key].selectActive();\n                            }\n                        }\n                    }\n                };\n\n                $scope.isActive = function () {\n                    for (var key in $scope.triggerCharMap) {\n                        if ($scope.triggerCharMap.hasOwnProperty(key)) {\n                            if ($scope.triggerCharMap[key].visible) {\n                                return true;\n                            }\n                        }\n                    }\n                    return false;\n                };\n\n                $scope.isContentEditable = function() {\n                    return ($scope.targetElement.nodeName !== 'INPUT' && $scope.targetElement.nodeName !== 'TEXTAREA');\n                };\n\n                $scope.replaceMacro = function(macro, hasTrailingSpace) {\n                    if (!hasTrailingSpace) {\n                        $scope.replacingMacro = true;\n                        $scope.timer = $timeout(function() {\n                            mentioUtil.replaceMacroText($scope.context(), $scope.targetElement,\n                                $scope.targetElementPath, $scope.targetElementSelectedOffset,\n                                $scope.macros, $scope.macros[macro]);\n                            angular.element($scope.targetElement).triggerHandler('change');\n                            $scope.replacingMacro = false;\n                        }, 300);\n                        $scope.$on('$destroy', function() {\n                            $timeout.cancel($scope.timer);\n                        });\n                    } else {\n                        mentioUtil.replaceMacroText($scope.context(), $scope.targetElement, $scope.targetElementPath,\n                            $scope.targetElementSelectedOffset, $scope.macros, $scope.macros[macro]);\n                    }\n                };\n\n                $scope.addMenu = function(menuScope) {\n                    if (menuScope.parentScope && $scope.triggerCharMap.hasOwnProperty(menuScope.triggerChar)) {\n                        return;\n                    }\n                    $scope.triggerCharMap[menuScope.triggerChar] = menuScope;\n                    if ($scope.triggerCharSet === undefined) {\n                        $scope.triggerCharSet = [];\n                    }\n                    $scope.triggerCharSet.push(menuScope.triggerChar);\n                    menuScope.setParent($scope);\n                };\n\n                $scope.$on(\n                    'menuCreated', function (event, data) {\n                        if (\n                            $attrs.id !== undefined ||\n                            $attrs.mentioId !== undefined\n                        )\n                        {\n                            if (\n                                $attrs.id === data.targetElement ||\n                                (\n                                    $attrs.mentioId !== undefined &&\n                                    $scope.altId === data.targetElement\n                                )\n                            )\n                            {\n                                $scope.addMenu(data.scope);\n                            }\n                        }\n                    }\n                );\n\n                $document.on(\n                    'click', function () {\n                        if ($scope.isActive()) {\n                            $scope.$apply(function () {\n                                $scope.hideAll();\n                            });\n                        }\n                    }\n                );\n\n                $document.on(\n                    'keydown keypress paste', function (event) {\n                        var activeMenuScope = $scope.getActiveMenuScope();\n                        if (activeMenuScope) {\n                            if (event.which === 9 || event.which === 13) {\n                                event.preventDefault();\n                                activeMenuScope.selectActive();\n                            }\n\n                            if (event.which === 27) {\n                                event.preventDefault();\n                                activeMenuScope.$apply(function () {\n                                    activeMenuScope.hideMenu();\n                                });\n                            }\n\n                            if (event.which === 40) {\n                                event.preventDefault();\n                                activeMenuScope.$apply(function () {\n                                    activeMenuScope.activateNextItem();\n                                });\n                                activeMenuScope.adjustScroll(1);\n                            }\n\n                            if (event.which === 38) {\n                                event.preventDefault();\n                                activeMenuScope.$apply(function () {\n                                    activeMenuScope.activatePreviousItem();\n                                });\n                                activeMenuScope.adjustScroll(-1);\n                            }\n\n                            if (event.which === 37 || event.which === 39) {\n                                event.preventDefault();\n                             }\n                        }\n                    }\n                );\n            },\n            link: function (scope, element, attrs) {\n                scope.triggerCharMap = {};\n\n                scope.targetElement = element;\n                attrs.$set('autocomplete','off');\n\n                if (attrs.mentioItems) {\n                    scope.localItems = [];\n                    scope.parentScope = scope;\n                    var itemsRef = attrs.mentioSearch ? ' mentio-items=\"items\"' : ' mentio-items=\"localItems\"';\n\n                    scope.defaultTriggerChar = attrs.mentioTriggerChar ? scope.$eval(attrs.mentioTriggerChar) : '@';\n\n                    var html = '<mentio-menu' +\n                        ' mentio-search=\"bridgeSearch(term)\"' +\n                        ' mentio-select=\"bridgeSelect(item)\"' +\n                        itemsRef;\n\n                    if (attrs.mentioTemplateUrl) {\n                        html = html + ' mentio-template-url=\"' + attrs.mentioTemplateUrl + '\"';\n                    }\n                    html = html + ' mentio-trigger-char=\"\\'' + scope.defaultTriggerChar + '\\'\"' +\n                        ' mentio-parent-scope=\"parentScope\"' +\n                        '/>';\n                    var linkFn = $compile(html);\n                    var el = linkFn(scope);\n\n                    element.parent().append(el);\n\n                    scope.$on('$destroy', function() {\n                      el.remove();\n                    });\n                }\n\n                if (attrs.mentioTypedTerm) {\n                    scope.syncTriggerText = true;\n                }\n\n                function keyHandler(event) {\n                    function stopEvent(event) {\n                        event.preventDefault();\n                        event.stopPropagation();\n                        event.stopImmediatePropagation();\n                    }\n                    var activeMenuScope = scope.getActiveMenuScope();\n                    if (activeMenuScope) {\n                        if (event.which === 9 || event.which === 13) {\n                            stopEvent(event);\n                            activeMenuScope.selectActive();\n                            return false;\n                        }\n\n                        if (event.which === 27) {\n                            stopEvent(event);\n                            activeMenuScope.$apply(function () {\n                                activeMenuScope.hideMenu();\n                            });\n                            return false;\n                        }\n\n                        if (event.which === 40) {\n                            stopEvent(event);\n                            activeMenuScope.$apply(function () {\n                                activeMenuScope.activateNextItem();\n                            });\n                            activeMenuScope.adjustScroll(1);\n                            return false;\n                        }\n\n                        if (event.which === 38) {\n                            stopEvent(event);\n                            activeMenuScope.$apply(function () {\n                                activeMenuScope.activatePreviousItem();\n                            });\n                            activeMenuScope.adjustScroll(-1);\n                            return false;\n                        }\n\n                        if (event.which === 37 || event.which === 39) {\n                            stopEvent(event);\n                            return false;\n                        }\n                    }\n                }\n\n                scope.$watch(\n                    'iframeElement', function(newValue) {\n                        if (newValue) {\n                            var iframeDocument = newValue.contentWindow.document;\n                            iframeDocument.addEventListener('click',\n                                function () {\n                                    if (scope.isActive()) {\n                                        scope.$apply(function () {\n                                            scope.hideAll();\n                                        });\n                                    }\n                                }\n                            );\n\n\n                            iframeDocument.addEventListener('keydown', keyHandler, true /*capture*/);\n\n                            scope.$on ( '$destroy', function() {\n                                iframeDocument.removeEventListener ( 'keydown', keyHandler );\n                            });\n                        }\n                    }\n                );\n\n                scope.$watch(\n                    'ngModel',\n                    function (newValue) {\n                        /*jshint maxcomplexity:14 */\n                        /*jshint maxstatements:39 */\n                        if ((!newValue || newValue === '') && !scope.isActive()) {\n                            return;\n                        }\n                        if (scope.triggerCharSet === undefined) {\n                            $log.error('Error, no mentio-items attribute was provided, ' +\n                                'and no separate mentio-menus were specified.  Nothing to do.');\n                            return;\n                        }\n\n                        if (scope.contentEditableMenuPasted) {\n                            scope.contentEditableMenuPasted = false;\n                            return;\n                        }\n\n                        if (scope.replacingMacro) {\n                            $timeout.cancel(scope.timer);\n                            scope.replacingMacro = false;\n                        }\n\n                        var isActive = scope.isActive();\n                        var isContentEditable = scope.isContentEditable();\n\n                        var mentionInfo = mentioUtil.getTriggerInfo(scope.context(), scope.triggerCharSet,\n                            scope.requireLeadingSpace, isActive);\n\n                        if (mentionInfo !== undefined &&\n                                (\n                                    !isActive ||\n                                    (isActive &&\n                                        (\n                                            /* content editable selection changes to local nodes which\n                                            modifies the start position of the selection over time,\n                                            just consider triggerchar changes which\n                                            will have the odd effect that deleting a trigger char pops\n                                            the menu for a previous\n                                            trigger char sequence if one exists in a content editable */\n                                            (isContentEditable && mentionInfo.mentionTriggerChar ===\n                                                scope.currentMentionTriggerChar) ||\n                                            (!isContentEditable && mentionInfo.mentionPosition ===\n                                                scope.currentMentionPosition)\n                                        )\n                                    )\n                                )\n                            )\n                        {\n                                                        if (mentionInfo.mentionSelectedElement) {\n                                scope.targetElement = mentionInfo.mentionSelectedElement;\n                                scope.targetElementPath = mentionInfo.mentionSelectedPath;\n                                scope.targetElementSelectedOffset = mentionInfo.mentionSelectedOffset;\n                            }\n\n                            /* publish to external ngModel */\n                            scope.setTriggerText(mentionInfo.mentionText);\n                            /* remember current position */\n                            scope.currentMentionPosition = mentionInfo.mentionPosition;\n                            scope.currentMentionTriggerChar = mentionInfo.mentionTriggerChar;\n                            /* perform query */\n                            scope.query(mentionInfo.mentionTriggerChar, mentionInfo.mentionText);\n                        } else {\n                            var currentTypedTerm = scope.typedTerm;\n                            scope.setTriggerText('');\n                            scope.hideAll();\n\n                            var macroMatchInfo = mentioUtil.getMacroMatch(scope.context(), scope.macros);\n\n                            if (macroMatchInfo !== undefined) {\n                                scope.targetElement = macroMatchInfo.macroSelectedElement;\n                                scope.targetElementPath = macroMatchInfo.macroSelectedPath;\n                                scope.targetElementSelectedOffset = macroMatchInfo.macroSelectedOffset;\n                                scope.replaceMacro(macroMatchInfo.macroText, macroMatchInfo.macroHasTrailingSpace);\n                            } else if (scope.selectNotFound && currentTypedTerm && currentTypedTerm !== '') {\n                                var lastScope = scope.triggerCharMap[scope.currentMentionTriggerChar];\n                                if (lastScope) {\n                                    var text = lastScope.select({\n                                        item: {label: currentTypedTerm}\n                                    });\n                                    if (typeof text.then === 'function') {\n                                        /* text is a promise, at least our best guess */\n                                        text.then(scope.replaceText);\n                                    } else {\n                                        scope.replaceText(text, true);\n                                    }\n                                }\n                            }\n                        }\n                    }\n                );\n            }\n        };\n    }])\n\n    .directive('mentioMenu', ['mentioUtil', '$rootScope', '$log', '$window', '$document',\n        function (mentioUtil, $rootScope, $log, $window, $document) {\n        return {\n            restrict: 'E',\n            scope: {\n                search: '&mentioSearch',\n                select: '&mentioSelect',\n                items: '=mentioItems',\n                triggerChar: '=mentioTriggerChar',\n                forElem: '=mentioFor',\n                parentScope: '=mentioParentScope'\n            },\n            templateUrl: function(tElement, tAttrs) {\n                return tAttrs.mentioTemplateUrl !== undefined ? tAttrs.mentioTemplateUrl : 'mentio-menu.tpl.html';\n            },\n            controller: function ($scope) {\n                $scope.visible = false;\n                this.activate = $scope.activate = function (item) {\n                    $scope.activeItem = item;\n                };\n                this.isActive = $scope.isActive = function (item) {\n                    return $scope.activeItem === item;\n                };\n                this.selectItem = $scope.selectItem = function (item) {\n                    var text = $scope.select({\n                        item: item\n                    });\n                    if (typeof text.then === 'function') {\n                        /* text is a promise, at least our best guess */\n                        text.then($scope.parentMentio.replaceText);\n                    } else {\n                        $scope.parentMentio.replaceText(text);\n                    }\n                };\n\n                $scope.activateNextItem = function () {\n                    var index = $scope.items.indexOf($scope.activeItem);\n                    this.activate($scope.items[(index + 1) % $scope.items.length]);\n                };\n\n                $scope.activatePreviousItem = function () {\n                    var index = $scope.items.indexOf($scope.activeItem);\n                    this.activate($scope.items[index === 0 ? $scope.items.length - 1 : index - 1]);\n                };\n\n                $scope.isFirstItemActive = function () {\n                    var index = $scope.items.indexOf($scope.activeItem);\n\n                    return index === 0;\n                };\n\n                $scope.isLastItemActive = function () {\n                    var index = $scope.items.indexOf($scope.activeItem);\n\n                    return index === ($scope.items.length - 1);\n                };\n\n                $scope.selectActive = function () {\n                    $scope.selectItem($scope.activeItem);\n                };\n\n                $scope.isVisible = function () {\n                    return $scope.visible;\n                };\n\n                $scope.showMenu = function () {\n                    if (!$scope.visible) {\n                        $scope.requestVisiblePendingSearch = true;\n                    }\n                };\n\n                $scope.setParent = function (scope) {\n                    $scope.parentMentio = scope;\n                    $scope.targetElement = scope.targetElement;\n                };\n            },\n\n            link: function (scope, element) {\n                element[0].parentNode.removeChild(element[0]);\n                $document[0].body.appendChild(element[0]);\n                scope.menuElement = element; // for testing\n\n                if (scope.parentScope) {\n                    scope.parentScope.addMenu(scope);\n                } else {\n                    if (!scope.forElem) {\n                        $log.error('mentio-menu requires a target element in tbe mentio-for attribute');\n                        return;\n                    }\n                    if (!scope.triggerChar) {\n                        $log.error('mentio-menu requires a trigger char');\n                        return;\n                    }\n                    $rootScope.$broadcast('menuCreated',\n                        {\n                            targetElement : scope.forElem,\n                            scope : scope\n                        });\n                }\n\n                angular.element($window).bind(\n                    'resize', function () {\n                        if (scope.isVisible()) {\n                            var triggerCharSet = [];\n                            triggerCharSet.push(scope.triggerChar);\n                            mentioUtil.popUnderMention(scope.parentMentio.context(),\n                                triggerCharSet, element, scope.requireLeadingSpace);\n                        }\n                    }\n                );\n\n                scope.$watch('items', function (items) {\n                    if (items && items.length > 0) {\n                        scope.activate(items[0]);\n                        if (!scope.visible && scope.requestVisiblePendingSearch) {\n                            scope.visible = true;\n                            scope.requestVisiblePendingSearch = false;\n                        }\n                    } else {\n                        scope.hideMenu();\n                    }\n                });\n\n                scope.$watch('isVisible()', function (visible) {\n                    if (visible) {\n                        var triggerCharSet = [];\n                        triggerCharSet.push(scope.triggerChar);\n                        mentioUtil.popUnderMention(scope.parentMentio.context(),\n                            triggerCharSet, element, scope.requireLeadingSpace);\n                    }\n                });\n\n                scope.parentMentio.$on('$destroy', function () {\n                    element.remove();\n                });\n\n                scope.hideMenu = function () {\n                    scope.visible = false;\n                    element.css('display', 'none');\n                };\n\n                scope.adjustScroll = function (direction) {\n                    var menuEl = element[0];\n                    var menuItemsList = menuEl.querySelector('ul');\n                    var menuItem = menuEl.querySelector('[mentio-menu-item].active');\n\n                    if (scope.isFirstItemActive()) {\n                        return menuItemsList.scrollTop = 0;\n                    } else if(scope.isLastItemActive()) {\n                        return menuItemsList.scrollTop = menuItemsList.scrollHeight;\n                    }\n\n                    if (direction === 1) {\n                        menuItemsList.scrollTop += menuItem.offsetHeight;\n                    } else {\n                        menuItemsList.scrollTop -= menuItem.offsetHeight;\n                    }\n                };\n\n            }\n        };\n    }])\n\n    .directive('mentioMenuItem', function () {\n        return {\n            restrict: 'A',\n            scope: {\n                item: '=mentioMenuItem'\n            },\n            require: '^mentioMenu',\n            link: function (scope, element, attrs, controller) {\n\n                scope.$watch(function () {\n                    return controller.isActive(scope.item);\n                }, function (active) {\n                    if (active) {\n                        element.addClass('active');\n                    } else {\n                        element.removeClass('active');\n                    }\n                });\n\n                element.bind('mouseenter', function () {\n                    scope.$apply(function () {\n                        controller.activate(scope.item);\n                    });\n                });\n\n                element.bind('click', function () {\n                    controller.selectItem(scope.item);\n                    return false;\n                });\n            }\n        };\n    })\n    .filter('unsafe', function($sce) {\n        return function (val) {\n            return $sce.trustAsHtml(val);\n        };\n    })\n    .filter('mentioHighlight', function() {\n        function escapeRegexp (queryToEscape) {\n            return queryToEscape.replace(/([.?*+^$[\\]\\\\(){}|-])/g, '\\\\$1');\n        }\n\n        return function (matchItem, query, hightlightClass) {\n            if (query) {\n                var replaceText = hightlightClass ?\n                                 '<span class=\"' + hightlightClass + '\">$&</span>' :\n                                 '<strong>$&</strong>';\n                return ('' + matchItem).replace(new RegExp(escapeRegexp(query), 'gi'), replaceText);\n            } else {\n                return matchItem;\n            }\n        };\n    });\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ment.io/src/mentio.service.js",
    "content": "'use strict';\n\nangular.module('mentio')\n    .factory('mentioUtil', function ($window, $location, $anchorScroll, $timeout) {\n        function popUnderMention (ctx, triggerCharSet, selectionEl, requireLeadingSpace) {\n            var coordinates;\n            var mentionInfo = getTriggerInfo(ctx, triggerCharSet, requireLeadingSpace, false);\n\n            if (mentionInfo !== undefined) {\n\n                if (selectedElementIsTextAreaOrInput(ctx)) {\n                    coordinates = getTextAreaOrInputUnderlinePosition(ctx, getDocument(ctx).activeElement,\n                        mentionInfo.mentionPosition);\n                } else {\n                    coordinates = getContentEditableCaretPosition(ctx, mentionInfo.mentionPosition);\n                }\n                selectionEl.css({\n                    top: coordinates.top + 'px',\n                    left: coordinates.left + 'px',\n                    position: 'absolute',\n                    zIndex: 200000,\n                    display: 'block'\n                });\n\n                $timeout(function(){\n                    scrollIntoView(ctx, selectionEl);\n                },0);\n            } else {\n                selectionEl.css({\n                    display: 'none'\n                });\n            }\n        }\n\n        function scrollIntoView(ctx, elem)\n        {\n            var reasonableBuffer = 20;\n            var maxScrollDisplacement = 100;\n            var clientRect;\n            var e = elem[0];\n            while (clientRect === undefined || clientRect.height === 0) {\n                clientRect = e.getBoundingClientRect();\n                if (clientRect.height === 0) {\n                    e = e.childNodes[0];\n                    if (e === undefined || !e.getBoundingClientRect) {\n                        return;\n                    }\n                }\n            }\n            var elemTop = clientRect.top;\n            var elemBottom = elemTop + clientRect.height;\n            if(elemTop < 0) {\n                $window.scrollTo(0, $window.pageYOffset + clientRect.top - reasonableBuffer);\n            } else if (elemBottom > $window.innerHeight) {\n                var maxY = $window.pageYOffset + clientRect.top - reasonableBuffer;\n                if (maxY - $window.pageYOffset > maxScrollDisplacement) {\n                    maxY = $window.pageYOffset + maxScrollDisplacement;\n                }\n                var targetY = $window.pageYOffset - ($window.innerHeight - elemBottom);\n                if (targetY > maxY) {\n                    targetY = maxY;\n                }\n                $window.scrollTo(0, targetY);\n            }\n        }\n\n        function selectedElementIsTextAreaOrInput (ctx) {\n            var element = getDocument(ctx).activeElement;\n            if (element !== null) {\n                var nodeName = element.nodeName;\n                var type = element.getAttribute('type');\n                return (nodeName === 'INPUT' && type === 'text') || nodeName === 'TEXTAREA';\n            }\n            return false;\n        }\n\n        function selectElement (ctx, targetElement, path, offset) {\n            var range;\n            var elem = targetElement;\n            if (path) {\n                for (var i = 0; i < path.length; i++) {\n                    elem = elem.childNodes[path[i]];\n                    if (elem === undefined) {\n                        return;\n                    }\n                    while (elem.length < offset) {\n                        offset -= elem.length;\n                        elem = elem.nextSibling;\n                    }\n                    if (elem.childNodes.length === 0 && !elem.length) {\n                        elem = elem.previousSibling;\n                    }\n                }\n            }\n            var sel = getWindowSelection(ctx);\n\n            range = getDocument(ctx).createRange();\n            range.setStart(elem, offset);\n            range.setEnd(elem, offset);\n            range.collapse(true);\n            try{sel.removeAllRanges();}catch(error){}\n            sel.addRange(range);\n            targetElement.focus();\n        }\n\n        function pasteHtml (ctx, html, startPos, endPos) {\n            var range, sel;\n            sel = getWindowSelection(ctx);\n            range = getDocument(ctx).createRange();\n            range.setStart(sel.anchorNode, startPos);\n            range.setEnd(sel.anchorNode, endPos);\n            range.deleteContents();\n\n            var el = getDocument(ctx).createElement('div');\n            el.innerHTML = html;\n            var frag = getDocument(ctx).createDocumentFragment(),\n                node, lastNode;\n            while ((node = el.firstChild)) {\n                lastNode = frag.appendChild(node);\n            }\n            range.insertNode(frag);\n            if (lastNode) {\n                range = range.cloneRange();\n                range.setStartAfter(lastNode);\n                range.collapse(true);\n                sel.removeAllRanges();\n                sel.addRange(range);\n            }\n        }\n\n        function resetSelection (ctx, targetElement, path, offset) {\n            var nodeName = targetElement.nodeName;\n            if (nodeName === 'INPUT' || nodeName === 'TEXTAREA') {\n                if (targetElement !== getDocument(ctx).activeElement) {\n                    targetElement.focus();\n                }\n            } else {\n                selectElement(ctx, targetElement, path, offset);\n            }\n        }\n        function replaceMacroText (ctx, targetElement, path, offset, macros, text) {\n            resetSelection(ctx, targetElement, path, offset);\n\n            var macroMatchInfo = getMacroMatch(ctx, macros);\n\n            if (macroMatchInfo.macroHasTrailingSpace) {\n                macroMatchInfo.macroText = macroMatchInfo.macroText + '\\xA0';\n                text = text + '\\xA0';\n            }\n\n            if (macroMatchInfo !== undefined) {\n                var element = getDocument(ctx).activeElement;\n                if (selectedElementIsTextAreaOrInput(ctx)) {\n                    var startPos = macroMatchInfo.macroPosition;\n                    var endPos = macroMatchInfo.macroPosition + macroMatchInfo.macroText.length;\n                    element.value = element.value.substring(0, startPos) + text +\n                        element.value.substring(endPos, element.value.length);\n                    element.selectionStart = startPos + text.length;\n                    element.selectionEnd = startPos + text.length;\n                } else {\n                    pasteHtml(ctx, text, macroMatchInfo.macroPosition,\n                            macroMatchInfo.macroPosition + macroMatchInfo.macroText.length);\n                }\n            }\n        }\n        function replaceTriggerText (ctx, targetElement, path, offset, triggerCharSet, \n                text, requireLeadingSpace, hasTrailingSpace) {\n            resetSelection(ctx, targetElement, path, offset);\n\n            var mentionInfo = getTriggerInfo(ctx, triggerCharSet, requireLeadingSpace, true, hasTrailingSpace);\n\n            if (mentionInfo !== undefined) {\n                if (selectedElementIsTextAreaOrInput()) {\n                    var myField = getDocument(ctx).activeElement;\n                    text = text + ' ';\n                    var startPos = mentionInfo.mentionPosition;\n                    var endPos = mentionInfo.mentionPosition + mentionInfo.mentionText.length + 1;\n                    myField.value = myField.value.substring(0, startPos) + text +\n                        myField.value.substring(endPos, myField.value.length);\n                    myField.selectionStart = startPos + text.length;\n                    myField.selectionEnd = startPos + text.length;\n                } else {\n                    text = text + '\\xA0';\n                    pasteHtml(ctx, text, mentionInfo.mentionPosition,\n                            mentionInfo.mentionPosition + mentionInfo.mentionText.length + 1);\n                }\n            }\n        }\n\n        function getNodePositionInParent (ctx, elem) {\n            if (elem.parentNode === null) {\n                return 0;\n            }\n            for (var i = 0; i < elem.parentNode.childNodes.length; i++) {\n                var node = elem.parentNode.childNodes[i];\n                if (node === elem) {\n                    return i;\n                }\n            }\n        }\n        function getMacroMatch (ctx, macros) {\n            var selected, path = [], offset;\n\n            if (selectedElementIsTextAreaOrInput(ctx)) {\n                selected = getDocument(ctx).activeElement;\n            } else {\n                var selectionInfo = getContentEditableSelectedPath(ctx);\n                if (selectionInfo) {\n                    selected = selectionInfo.selected;\n                    path = selectionInfo.path;\n                    offset = selectionInfo.offset;\n                }\n            }\n            var effectiveRange = getTextPrecedingCurrentSelection(ctx);\n            if (effectiveRange !== undefined && effectiveRange !== null) {\n\n                var matchInfo;\n\n                var hasTrailingSpace = false;\n\n                if (effectiveRange.length > 0 &&\n                    (effectiveRange.charAt(effectiveRange.length - 1) === '\\xA0' ||\n                        effectiveRange.charAt(effectiveRange.length - 1) === ' ')) {\n                    hasTrailingSpace = true;\n                    effectiveRange = effectiveRange.substring(0, effectiveRange.length-1);\n                }\n\n                angular.forEach(macros, function (macro, c) {\n                    var idx = effectiveRange.toUpperCase().lastIndexOf(c.toUpperCase());\n\n                    if (idx >= 0 && c.length + idx === effectiveRange.length) {\n                        var prevCharPos = idx - 1;\n                        if (idx === 0 || effectiveRange.charAt(prevCharPos) === '\\xA0' ||\n                            effectiveRange.charAt(prevCharPos) === ' ' ) {\n\n                            matchInfo = {\n                                macroPosition: idx,\n                                macroText: c,\n                                macroSelectedElement: selected,\n                                macroSelectedPath: path,\n                                macroSelectedOffset: offset,\n                                macroHasTrailingSpace: hasTrailingSpace\n                            };\n                        }\n                    }\n                });\n                if (matchInfo) {\n                    return matchInfo;\n                }\n            }\n        }\n\n        function getContentEditableSelectedPath(ctx) {\n            var sel = getWindowSelection(ctx);\n            var selected = sel.anchorNode;\n            var path = [];\n            var offset;\n            if (selected != null) {\n                var i;\n                var ce = selected.contentEditable;\n                while (selected !== null && ce !== 'true') {\n                    i = getNodePositionInParent(ctx, selected);\n                    path.push(i);\n                    selected = selected.parentNode;\n                    if (selected !== null) {\n                        ce = selected.contentEditable;\n                    }\n                }\n                path.reverse();\n                offset = sel.getRangeAt(0).startOffset;\n                return {\n                    selected: selected,\n                    path: path,\n                    offset: offset\n                };\n            }\n        }\n        function getTriggerInfo (ctx, triggerCharSet, requireLeadingSpace, menuAlreadyActive, hasTrailingSpace) {\n            /*jshint maxcomplexity:11 */\n            var selected, path, offset;\n            if (selectedElementIsTextAreaOrInput(ctx)) {\n                selected = getDocument(ctx).activeElement;\n            } else {\n                var selectionInfo = getContentEditableSelectedPath(ctx);\n                if (selectionInfo) {\n                    selected = selectionInfo.selected;\n                    path = selectionInfo.path;\n                    offset = selectionInfo.offset;\n                }\n            }\n            var effectiveRange = getTextPrecedingCurrentSelection(ctx);\n\n            if (effectiveRange !== undefined && effectiveRange !== null) {\n                var mostRecentTriggerCharPos = -1;\n                var triggerChar;\n                triggerCharSet.forEach(function(c) {\n                    var idx = effectiveRange.lastIndexOf(c);\n                    if (idx > mostRecentTriggerCharPos) {\n                        mostRecentTriggerCharPos = idx;\n                        triggerChar = c;\n                    }\n                });\n                if (mostRecentTriggerCharPos >= 0 &&\n                        (\n                            mostRecentTriggerCharPos === 0 ||\n                            !requireLeadingSpace ||\n                            /[\\xA0\\s]/g.test\n                            (\n                                effectiveRange.substring(\n                                    mostRecentTriggerCharPos - 1,\n                                    mostRecentTriggerCharPos)\n                            )\n                        )\n                    )\n                {\n                    var currentTriggerSnippet = effectiveRange.substring(mostRecentTriggerCharPos + 1,\n                        effectiveRange.length);\n\n                    triggerChar = effectiveRange.substring(mostRecentTriggerCharPos, mostRecentTriggerCharPos+1);\n                    var firstSnippetChar = currentTriggerSnippet.substring(0,1);\n                    var leadingSpace = currentTriggerSnippet.length > 0 &&\n                        (\n                            firstSnippetChar === ' ' ||\n                            firstSnippetChar === '\\xA0'\n                        );\n                    if (hasTrailingSpace) {\n                        currentTriggerSnippet = currentTriggerSnippet.trim();\n                    }\n                    if (!leadingSpace && (menuAlreadyActive || !(/[\\xA0\\s]/g.test(currentTriggerSnippet)))) {\n                        return {\n                            mentionPosition: mostRecentTriggerCharPos,\n                            mentionText: currentTriggerSnippet,\n                            mentionSelectedElement: selected,\n                            mentionSelectedPath: path,\n                            mentionSelectedOffset: offset,\n                            mentionTriggerChar: triggerChar\n                        };\n                    }\n                }\n            }\n        }\n\n        function getWindowSelection(ctx) {\n            if (!ctx) {\n                return window.getSelection();\n            } else {\n                return ctx.iframe.contentWindow.getSelection();\n            }\n        }\n\n        function getDocument(ctx) {\n            if (!ctx) {\n                return document;\n            } else {\n                return ctx.iframe.contentWindow.document;\n            }\n        }\n\n        function getTextPrecedingCurrentSelection (ctx) {\n            var text;\n            if (selectedElementIsTextAreaOrInput(ctx)) {\n                var textComponent = getDocument(ctx).activeElement;\n                var startPos = textComponent.selectionStart;\n                text = textComponent.value.substring(0, startPos);\n\n            } else {\n                var selectedElem = getWindowSelection(ctx).anchorNode;\n                if (selectedElem != null) {\n                    var workingNodeContent = selectedElem.textContent;\n                    var selectStartOffset = getWindowSelection(ctx).getRangeAt(0).startOffset;\n                    if (selectStartOffset >= 0) {\n                        text = workingNodeContent.substring(0, selectStartOffset);\n                    }\n                }\n            }\n            return text;\n        }\n\n        function getContentEditableCaretPosition (ctx, selectedNodePosition) {\n            var markerTextChar = '\\ufeff';\n            var markerEl, markerId = 'sel_' + new Date().getTime() + '_' + Math.random().toString().substr(2);\n\n            var range;\n            var sel = getWindowSelection(ctx);\n            var prevRange = sel.getRangeAt(0);\n            range = getDocument(ctx).createRange();\n\n            range.setStart(sel.anchorNode, selectedNodePosition);\n            range.setEnd(sel.anchorNode, selectedNodePosition);\n\n            range.collapse(false);\n            markerEl = getDocument(ctx).createElement('span');\n            markerEl.id = markerId;\n            markerEl.appendChild(getDocument(ctx).createTextNode(markerTextChar));\n            range.insertNode(markerEl);\n            sel.removeAllRanges();\n            sel.addRange(prevRange);\n\n            var coordinates = {\n                left: 0,\n                top: markerEl.offsetHeight\n            };\n\n            localToGlobalCoordinates(ctx, markerEl, coordinates);\n\n            markerEl.parentNode.removeChild(markerEl);\n            return coordinates;\n        }\n\n        function localToGlobalCoordinates(ctx, element, coordinates) {\n            var obj = element;\n            var iframe = ctx ? ctx.iframe : null;\n            while(obj) {\n                coordinates.left += obj.offsetLeft;\n                coordinates.top += obj.offsetTop;\n                if (obj !== getDocument().body) {\n                    coordinates.top -= obj.scrollTop;\n                    coordinates.left -= obj.scrollLeft;\n                }\n                obj = obj.offsetParent;\n                if (!obj && iframe) {\n                    obj = iframe;\n                    iframe = null;\n                }\n            }            \n        }\n\n        function getTextAreaOrInputUnderlinePosition (ctx, element, position) {\n            var properties = [\n                'direction',\n                'boxSizing',\n                'width',\n                'height',\n                'overflowX',\n                'overflowY',\n                'borderTopWidth',\n                'borderRightWidth',\n                'borderBottomWidth',\n                'borderLeftWidth',\n                'paddingTop',\n                'paddingRight',\n                'paddingBottom',\n                'paddingLeft',\n                'fontStyle',\n                'fontVariant',\n                'fontWeight',\n                'fontStretch',\n                'fontSize',\n                'fontSizeAdjust',\n                'lineHeight',\n                'fontFamily',\n                'textAlign',\n                'textTransform',\n                'textIndent',\n                'textDecoration',\n                'letterSpacing',\n                'wordSpacing'\n            ];\n\n            var isFirefox = (window.mozInnerScreenX !== null);\n\n            var div = getDocument(ctx).createElement('div');\n            div.id = 'input-textarea-caret-position-mirror-div';\n            getDocument(ctx).body.appendChild(div);\n\n            var style = div.style;\n            var computed = window.getComputedStyle ? getComputedStyle(element) : element.currentStyle;\n\n            style.whiteSpace = 'pre-wrap';\n            if (element.nodeName !== 'INPUT') {\n                style.wordWrap = 'break-word';\n            }\n            style.position = 'absolute';\n            style.visibility = 'hidden';\n            properties.forEach(function (prop) {\n                style[prop] = computed[prop];\n            });\n\n            if (isFirefox) {\n                style.width = (parseInt(computed.width) - 2) + 'px';\n                if (element.scrollHeight > parseInt(computed.height))\n                    style.overflowY = 'scroll';\n            } else {\n                style.overflow = 'hidden';\n            }\n\n            div.textContent = element.value.substring(0, position);\n\n            if (element.nodeName === 'INPUT') {\n                div.textContent = div.textContent.replace(/\\s/g, '\\u00a0');\n            }\n\n            var span = getDocument(ctx).createElement('span');\n            span.textContent = element.value.substring(position) || '.';\n            div.appendChild(span);\n\n            var coordinates = {\n                top: span.offsetTop + parseInt(computed.borderTopWidth) + parseInt(computed.fontSize),\n                left: span.offsetLeft + parseInt(computed.borderLeftWidth)\n            };\n\n            localToGlobalCoordinates(ctx, element, coordinates);\n\n            getDocument(ctx).body.removeChild(div);\n\n            return coordinates;\n        }\n\n        return {\n            popUnderMention: popUnderMention,\n            replaceMacroText: replaceMacroText,\n            replaceTriggerText: replaceTriggerText,\n            getMacroMatch: getMacroMatch,\n            getTriggerInfo: getTriggerInfo,\n            selectElement: selectElement,\n            getTextAreaOrInputUnderlinePosition: getTextAreaOrInputUnderlinePosition,\n            getTextPrecedingCurrentSelection: getTextPrecedingCurrentSelection,\n            getContentEditableSelectedPath: getContentEditableSelectedPath,\n            getNodePositionInParent: getNodePositionInParent,\n            getContentEditableCaretPosition: getContentEditableCaretPosition,\n            pasteHtml: pasteHtml,\n            resetSelection: resetSelection,\n            scrollIntoView: scrollIntoView\n        };\n    });\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/.bower.json",
    "content": "{\n  \"name\": \"moment\",\n  \"version\": \"2.10.2\",\n  \"main\": \"moment.js\",\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"test\",\n    \"tests\",\n    \"tasks\",\n    \"component.json\",\n    \"composer.json\",\n    \"CONTRIBUTING.md\",\n    \"ender.js\",\n    \"Gruntfile.js\",\n    \"package.js\",\n    \"package.json\"\n  ],\n  \"homepage\": \"https://github.com/moment/moment\",\n  \"_release\": \"2.10.2\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"2.10.2\",\n    \"commit\": \"b54fa78b74d55a1680293b5260a42bd2751c333c\"\n  },\n  \"_source\": \"git://github.com/moment/moment.git\",\n  \"_target\": \">=2.8.0 <2.11.0\",\n  \"_originalSource\": \"moment\"\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/CHANGELOG.md",
    "content": "Changelog\n=========\n\n### 2.10.2\n\n* fixed moment-with-locales in browser env caused by esperanto change\n\n### 2.10.1\n\n* regression: Add moment.duration.fn back\n\n### 2.10.0\n\nPorted code to es6 modules.\n\n### 2.9.0 [See full changelog](https://gist.github.com/ichernev/0c9a9b49951111a27ce7)\n\nlanguages:\n* [2104](https://github.com/moment/moment/issues/2104) Frisian (fy) language file with unit test\n* [2097](https://github.com/moment/moment/issues/2097) add ar-tn locale\n\ndeprecations:\n* [2074](https://github.com/moment/moment/issues/2074) Implement `moment.fn.utcOffset`, deprecate `momen.fn.zone`\n\nfeatures:\n* [2088](https://github.com/moment/moment/issues/2088) add moment.fn.isBetween\n* [2054](https://github.com/moment/moment/issues/2054) Call updateOffset when creating moment (needed for default timezone in\n  moment-timezone)\n* [1893](https://github.com/moment/moment/issues/1893) Add moment.isDate method\n* [1825](https://github.com/moment/moment/issues/1825) Implement toJSON function on Duration\n* [1809](https://github.com/moment/moment/issues/1809) Allowing moment.set() to accept a hash of units\n* [2128](https://github.com/moment/moment/issues/2128) Add firstDayOfWeek, firstDayOfYear locale getters\n* [2131](https://github.com/moment/moment/issues/2131) Add quarter diff support\n\nSome bugfixes and language improvements -- [full changelog](https://gist.github.com/ichernev/0c9a9b49951111a27ce7)\n\n### 2.8.4 [See full changelog](https://gist.github.com/ichernev/a4fcb0a46d74e4b9b996)\n\nFeatures:\n\n* [#2000](https://github.com/moment/moment/issues/2000) Add LTS localised format that includes seconds\n* [#1960](https://github.com/moment/moment/issues/1960) added formatToken 'x' for unix offset in milliseconds #1938\n* [#1965](https://github.com/moment/moment/issues/1965) Support 24:00:00.000 to mean next day, at midnight.\n* [#2002](https://github.com/moment/moment/issues/2002) Accept 'date' key when creating moment with object\n* [#2009](https://github.com/moment/moment/issues/2009) Use native toISOString when we can\n\nSome bugfixes and language improvements -- [full changelog](https://gist.github.com/ichernev/a4fcb0a46d74e4b9b996)\n\n### 2.8.3\n\nBugfixes:\n\n* [#1801](https://github.com/moment/moment/issues/1801) proper pluralization for Arabic\n* [#1833](https://github.com/moment/moment/issues/1833) improve spm integration\n* [#1871](https://github.com/moment/moment/issues/1871) fix zone bug caused by Firefox 24\n* [#1882](https://github.com/moment/moment/issues/1882) Use hh:mm in Czech\n* [#1883](https://github.com/moment/moment/issues/1883) Fix 2.8.0 regression in duration as conversions\n* [#1890](https://github.com/moment/moment/issues/1890) Faster travis builds\n* [#1892](https://github.com/moment/moment/issues/1892) Faster isBefore/After/Same\n* [#1848](https://github.com/moment/moment/issues/1848) Fix flaky month diffs\n* [#1895](https://github.com/moment/moment/issues/1895) Fix 2.8.0 regression in moment.utc with format array\n* [#1896](https://github.com/moment/moment/issues/1896) Support setting invalid instance locale (noop)\n* [#1897](https://github.com/moment/moment/issues/1897) Support moment([str]) in addition to moment([int])\n\n### 2.8.2\n\nMinor bugfixes:\n\n* [#1874](https://github.com/moment/moment/issues/1874) use `Object.prototype.hasOwnProperty`\n  instead of `obj.hasOwnProperty` (ie8 bug)\n* [#1873](https://github.com/moment/moment/issues/1873) add `duration#toString()`\n* [#1859](https://github.com/moment/moment/issues/1859) better month/weekday names in norwegian\n* [#1812](https://github.com/moment/moment/issues/1812) meridiem parsing for greek\n* [#1804](https://github.com/moment/moment/issues/1804) spanish del -> de\n* [#1800](https://github.com/moment/moment/issues/1800) korean LT improvement\n\n### 2.8.1\n\n* bugfix [#1813](https://github.com/moment/moment/issues/1813): fix moment().lang([key]) incompatibility\n\n### 2.8.0 [See changelog](https://gist.github.com/ichernev/ac3899324a5fa6c8c9b4)\n\n* incompatible changes\n    * [#1761](https://github.com/moment/moment/issues/1761): moments created without a language are no longer following the global language, in case it changes. Only newly created moments take the global language by default. In case you're affected by this, wait, comment on [#1797](https://github.com/moment/moment/issues/1797) and wait for a proper reimplementation\n    * [#1642](https://github.com/moment/moment/issues/1642): 45 days is no longer \"a month\" according to humanize, cutoffs for month, and year have changed. Hopefully your code does not depend on a particular answer from humanize (which it shouldn't anyway)\n    * [#1784](https://github.com/moment/moment/issues/1784): if you use the human readable English datetime format in a weird way (like storing them in a database) that would break when the format changes you're at risk.\n\n* deprecations (old behavior will be dropped in 3.0)\n    * [#1761](https://github.com/moment/moment/issues/1761) `lang` is renamed to `locale`, `langData` -> `localeData`. Also there is now `defineLocale` that should be used when creating new locales\n    * [#1763](https://github.com/moment/moment/issues/1763) `add(unit, value)` and `subtract(unit, value)` are now deprecated. Use `add(value, unit)` and `subtract(value, unit)` instead.\n    * [#1759](https://github.com/moment/moment/issues/1759) rename `duration.toIsoString` to `duration.toISOString`. The js standard library and moment's `toISOString` follow that convention.\n\n* new locales\n    * [#1789](https://github.com/moment/moment/issues/1789) Tibetan (bo)\n    * [#1786](https://github.com/moment/moment/issues/1786) Africaans (af)\n    * [#1778](https://github.com/moment/moment/issues/1778) Burmese (my)\n    * [#1727](https://github.com/moment/moment/issues/1727) Belarusian (be)\n\n* bugfixes, locale bugfixes, performance improvements, features\n\n### 2.7.0 [See changelog](https://gist.github.com/ichernev/b0a3d456d5a84c9901d7)\n\n* new languages\n\n  * [#1678](https://github.com/moment/moment/issues/1678) Bengali (bn)\n  * [#1628](https://github.com/moment/moment/issues/1628) Azerbaijani (az)\n  * [#1633](https://github.com/moment/moment/issues/1633) Arabic, Saudi Arabia (ar-sa)\n  * [#1648](https://github.com/moment/moment/issues/1648) Austrian German (de-at)\n\n* features\n\n  * [#1663](https://github.com/moment/moment/issues/1663) configurable relative time thresholds\n  * [#1554](https://github.com/moment/moment/issues/1554) support anchor time in moment.calendar\n  * [#1693](https://github.com/moment/moment/issues/1693) support moment.ISO_8601 as parsing format\n  * [#1637](https://github.com/moment/moment/issues/1637) add moment.min and moment.max and deprecate min/max instance methods\n  * [#1704](https://github.com/moment/moment/issues/1704) support string value in add/subtract\n  * [#1647](https://github.com/moment/moment/issues/1647) add spm support (package manager)\n\n* bugfixes\n\n### 2.6.0 [See changelog](https://gist.github.com/ichernev/10544682)\n\n* languages\n  * [#1529](https://github.com/moment/moment/issues/1529) Serbian-Cyrillic (sr-cyr)\n  * [#1544](https://github.com/moment/moment/issues/1544), [#1546](https://github.com/moment/moment/issues/1546) Khmer Cambodia (km)\n\n* features\n    * [#1419](https://github.com/moment/moment/issues/1419), [#1468](https://github.com/moment/moment/issues/1468), [#1467](https://github.com/moment/moment/issues/1467), [#1546](https://github.com/moment/moment/issues/1546) better handling of timezone-d moments around DST\n    * [#1462](https://github.com/moment/moment/issues/1462) add weeksInYear and isoWeeksInYear\n    * [#1475](https://github.com/moment/moment/issues/1475) support ordinal parsing\n    * [#1499](https://github.com/moment/moment/issues/1499) composer support\n    * [#1577](https://github.com/moment/moment/issues/1577), [#1604](https://github.com/moment/moment/issues/1604) put Date parsing in moment.createFromInputFallback so it can be properly deprecated and controlled in the future\n    * [#1545](https://github.com/moment/moment/issues/1545) extract two-digit year parsing in moment.parseTwoDigitYear, so it can be overwritten\n    * [#1590](https://github.com/moment/moment/issues/1590) (see [#1574](https://github.com/moment/moment/issues/1574)) set AMD global before module definition to better support non AMD module dependencies used in AMD environment\n    * [#1589](https://github.com/moment/moment/issues/1589) remove global in Node.JS environment (was not working before, nobody complained, was scheduled for removal anyway)\n    * [#1586](https://github.com/moment/moment/issues/1586) support quarter setting and parsing\n\n* 18 bugs fixed\n\n### 2.5.1\n\n* languages\n  * [#1392](https://github.com/moment/moment/issues/1392) Armenian (hy-am)\n\n* bugfixes\n  * [#1429](https://github.com/moment/moment/issues/1429) fixes [#1423](https://github.com/moment/moment/issues/1423) weird chrome-32 bug with js object creation\n  * [#1421](https://github.com/moment/moment/issues/1421) remove html entities from Welsh\n  * [#1418](https://github.com/moment/moment/issues/1418) fixes [#1401](https://github.com/moment/moment/issues/1401) improved non-padded tokens in strict matching\n  * [#1417](https://github.com/moment/moment/issues/1417) fixes [#1404](https://github.com/moment/moment/issues/1404) handle buggy moment object created by property cloning\n  * [#1398](https://github.com/moment/moment/issues/1398) fixes [#1397](https://github.com/moment/moment/issues/1397) fix Arabic-like week number parsing\n  * [#1396](https://github.com/moment/moment/issues/1396) add leftZeroFill(4) to GGGG and gggg formats\n  * [#1373](https://github.com/moment/moment/issues/1373) use lowercase for months and days in Catalan\n\n* testing\n  * [#1374](https://github.com/moment/moment/issues/1374) run tests on multiple browser/os combos via SauceLabs and Travis\n\n### 2.5.0 [See changelog](https://gist.github.com/ichernev/8104451)\n\n* New languages\n  * Luxemburish (lb) [1247](https://github.com/moment/moment/issues/1247)\n  * Serbian (rs) [1319](https://github.com/moment/moment/issues/1319)\n  * Tamil (ta) [1324](https://github.com/moment/moment/issues/1324)\n  * Macedonian (mk) [1337](https://github.com/moment/moment/issues/1337)\n\n* Features\n  * [1311](https://github.com/moment/moment/issues/1311) Add quarter getter and format token `Q`\n  * [1303](https://github.com/moment/moment/issues/1303) strict parsing now respects number of digits per token (fix [1196](https://github.com/moment/moment/issues/1196))\n  * 0d30bb7 add jspm support\n  * [1347](https://github.com/moment/moment/issues/1347) improve zone parsing\n  * [1362](https://github.com/moment/moment/issues/1362) support merideam parsing in Korean\n\n* 22 bugfixes\n\n### 2.4.0\n\n* **Deprecate** globally exported moment, will be removed in next major\n* New languages\n  * Farose (fo) [#1206](https://github.com/moment/moment/issues/1206)\n  * Tagalog/Filipino (tl-ph) [#1197](https://github.com/moment/moment/issues/1197)\n  * Welsh (cy) [#1215](https://github.com/moment/moment/issues/1215)\n* Bugfixes\n  * properly handle Z at the end of iso RegExp [#1187](https://github.com/moment/moment/issues/1187)\n  * chinese meridian time improvements [#1076](https://github.com/moment/moment/issues/1076)\n  * fix language tests [#1177](https://github.com/moment/moment/issues/1177)\n  * remove some failing tests (that should have never existed :))\n    [#1185](https://github.com/moment/moment/issues/1185)\n    [#1183](https://github.com/moment/moment/issues/1183)\n  * handle russian noun cases in weird cases [#1195](https://github.com/moment/moment/issues/1195)\n\n### 2.3.1\n\nRemoved a trailing comma [1169] and fixed a bug with `months`, `weekdays` getters [#1171](https://github.com/moment/moment/issues/1171).\n\n### 2.3.0 [See changelog](https://gist.github.com/ichernev/6864354)\n\nChanged isValid, added strict parsing.\nWeek tokens parsing.\n\n### 2.2.1\n\nFixed bug in string prototype test.\nUpdated authors and contributors.\n\n### 2.2.0 [See changelog](https://gist.github.com/ichernev/00f837a9baf46a3565e4)\n\nAdded bower support.\n\nLanguage files now use UMD.\n\nCreating moment defaults to current date/month/year.\n\nAdded a bundle of moment and all language files.\n\n### 2.1.0 [See changelog](https://gist.github.com/timrwood/b8c2d90d528eddb53ab5)\n\nAdded better week support.\n\nAdded ability to set offset with `moment#zone`.\n\nAdded ability to set month or weekday from a string.\n\nAdded `moment#min` and `moment#max`\n\n### 2.0.0 [See changelog](https://gist.github.com/timrwood/e72f2eef320ed9e37c51)\n\nAdded short form localized tokens.\n\nAdded ability to define language a string should be parsed in.\n\nAdded support for reversed add/subtract arguments.\n\nAdded support for `endOf('week')` and `startOf('week')`.\n\nFixed the logic for `moment#diff(Moment, 'months')` and `moment#diff(Moment, 'years')`\n\n`moment#diff` now floors instead of rounds.\n\nNormalized `moment#toString`.\n\nAdded `isSame`, `isAfter`, and `isBefore` methods.\n\nAdded better week support.\n\nAdded `moment#toJSON`\n\nBugfix: Fixed parsing of first century dates\n\nBugfix: Parsing 10Sep2001 should work as expected\n\nBugfix: Fixed wierdness with `moment.utc()` parsing.\n\nChanged language ordinal method to return the number + ordinal instead of just the ordinal.\n\nChanged two digit year parsing cutoff to match strptime.\n\nRemoved `moment#sod` and `moment#eod` in favor of `moment#startOf` and `moment#endOf`.\n\nRemoved `moment.humanizeDuration()` in favor of `moment.duration().humanize()`.\n\nRemoved the lang data objects from the top level namespace.\n\nDuplicate `Date` passed to `moment()` instead of referencing it.\n\n### 1.7.2 [See discussion](https://github.com/timrwood/moment/issues/456)\n\nBugfixes\n\n### 1.7.1 [See discussion](https://github.com/timrwood/moment/issues/384)\n\nBugfixes\n\n### 1.7.0 [See discussion](https://github.com/timrwood/moment/issues/288)\n\nAdded `moment.fn.endOf()` and `moment.fn.startOf()`.\n\nAdded validation via `moment.fn.isValid()`.\n\nMade formatting method 3x faster. http://jsperf.com/momentjs-cached-format-functions\n\nAdd support for month/weekday callbacks in `moment.fn.format()`\n\nAdded instance specific languages.\n\nAdded two letter weekday abbreviations with the formatting token `dd`.\n\nVarious language updates.\n\nVarious bugfixes.\n\n### 1.6.0 [See discussion](https://github.com/timrwood/moment/pull/268)\n\nAdded Durations.\n\nRevamped parser to support parsing non-separated strings (YYYYMMDD vs YYYY-MM-DD).\n\nAdded support for millisecond parsing and formatting tokens (S SS SSS)\n\nAdded a getter for `moment.lang()`\n\nVarious bugfixes.\n\nThere are a few things deprecated in the 1.6.0 release.\n\n1. The format tokens `z` and `zz` (timezone abbreviations like EST CST MST etc) will no longer be supported. Due to inconsistent browser support, we are unable to consistently produce this value. See [this issue](https://github.com/timrwood/moment/issues/162) for more background.\n\n2. The method `moment.fn.native` is deprecated in favor of `moment.fn.toDate`. There continue to be issues with Google Closure Compiler throwing errors when using `native`, even in valid instances.\n\n3. The way to customize am/pm strings is being changed. This would only affect you if you created a custom language file. For more information, see [this issue](https://github.com/timrwood/moment/pull/222).\n\n### 1.5.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=10&page=1&state=closed)\n\nAdded UTC mode.\n\nAdded automatic ISO8601 parsing.\n\nVarious bugfixes.\n\n### 1.4.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=8&state=closed)\n\nAdded `moment.fn.toDate` as a replacement for `moment.fn.native`.\n\nAdded `moment.fn.sod` and `moment.fn.eod` to get the start and end of day.\n\nVarious bugfixes.\n\n### 1.3.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=7&state=closed)\n\nAdded support for parsing month names in the current language.\n\nAdded escape blocks for parsing tokens.\n\nAdded `moment.fn.calendar` to format strings like 'Today 2:30 PM', 'Tomorrow 1:25 AM', and 'Last Sunday 4:30 AM'.\n\nAdded `moment.fn.day` as a setter.\n\nVarious bugfixes\n\n### 1.2.0 [See milestone](https://github.com/timrwood/moment/issues?milestone=4&state=closed)\n\nAdded timezones to parser and formatter.\n\nAdded `moment.fn.isDST`.\n\nAdded `moment.fn.zone` to get the timezone offset in minutes.\n\n### 1.1.2 [See milestone](https://github.com/timrwood/moment/issues?milestone=6&state=closed)\n\nVarious bugfixes\n\n### 1.1.1 [See milestone](https://github.com/timrwood/moment/issues?milestone=5&state=closed)\n\nAdded time specific diffs (months, days, hours, etc)\n\n### 1.1.0\n\nAdded `moment.fn.format` localized masks. 'L LL LLL LLLL' [issue 29](https://github.com/timrwood/moment/pull/29)\n\nFixed [issue 31](https://github.com/timrwood/moment/pull/31).\n\n### 1.0.1\n\nAdded `moment.version` to get the current version.\n\nRemoved `window !== undefined` when checking if module exists to support browserify. [issue 25](https://github.com/timrwood/moment/pull/25)\n\n### 1.0.0\n\nAdded convenience methods for getting and setting date parts.\n\nAdded better support for `moment.add()`.\n\nAdded better lang support in NodeJS.\n\nRenamed library from underscore.date to Moment.js\n\n### 0.6.1\n\nAdded Portuguese, Italian, and French language support\n\n### 0.6.0\n\nAdded _date.lang() support.\nAdded support for passing multiple formats to try to parse a date. _date(\"07-10-1986\", [\"MM-DD-YYYY\", \"YYYY-MM-DD\"]);\nMade parse from string and single format 25% faster.\n\n### 0.5.2\n\nBugfix for [issue 8](https://github.com/timrwood/underscore.date/pull/8) and [issue 9](https://github.com/timrwood/underscore.date/pull/9).\n\n### 0.5.1\n\nBugfix for [issue 5](https://github.com/timrwood/underscore.date/pull/5).\n\n### 0.5.0\n\nDropped the redundant `_date.date()` in favor of `_date()`.\nRemoved `_date.now()`, as it is a duplicate of `_date()` with no parameters.\nRemoved `_date.isLeapYear(yearNumber)`. Use `_date([yearNumber]).isLeapYear()` instead.\nExposed customization options through the `_date.relativeTime`, `_date.weekdays`, `_date.weekdaysShort`, `_date.months`, `_date.monthsShort`, and `_date.ordinal` variables instead of the `_date.customize()` function.\n\n### 0.4.1\n\nAdded date input formats for input strings.\n\n### 0.4.0\n\nAdded underscore.date to npm. Removed dependencies on underscore.\n\n### 0.3.2\n\nAdded `'z'` and `'zz'` to `_.date().format()`. Cleaned up some redundant code to trim off some bytes.\n\n### 0.3.1\n\nCleaned up the namespace. Moved all date manipulation and display functions to the _.date() object.\n\n### 0.3.0\n\nSwitched to the Underscore methodology of not mucking with the native objects' prototypes.\nMade chaining possible.\n\n### 0.2.1\n\nChanged date names to be a more pseudo standardized 'dddd, MMMM Do YYYY, h:mm:ss a'.\nAdded `Date.prototype` functions `add`, `subtract`, `isdst`, and `isleapyear`.\n\n### 0.2.0\n\nChanged function names to be more concise.\nChanged date format from php date format to custom format.\n\n### 0.1.0\n\nInitial release\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/LICENSE",
    "content": "Copyright (c) 2011-2014 Tim Wood, Iskren Chernev, Moment.js contributors\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/Moment.js.nuspec",
    "content": "<?xml version=\"1.0\"?>\r\n<package xmlns=\"http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd\">\r\n    <metadata>\r\n        <id>Moment.js</id>\r\n        <version>2.10.2</version>\r\n        <authors>Tim Wood</authors>\r\n        <owners>Cory Deppen, Iskren Chernev</owners>\r\n        <description>A lightweight javascript date library for parsing, manipulating, and formatting dates.</description>\r\n        <releaseNotes>\r\n            - Add LTS localised format that includes seconds\r\n            - Added formatToken 'x' for unix offset in milliseconds #1938\r\n            - Support 24:00:00.000 to mean next day, at midnight.\r\n            - Accept 'date' key when creating moment with object\r\n            - Use native toISOString when we can\r\n            - Some bugfixes and language improvements\r\n        </releaseNotes>\r\n        <projectUrl>http://momentjs.com/</projectUrl>\r\n        <iconUrl>http://pbs.twimg.com/profile_images/482670411402858496/Xrtdc94q_normal.png</iconUrl>\r\n        <licenseUrl>https://raw.github.com/timrwood/moment/master/LICENSE</licenseUrl>\r\n        <tags>JavaScript date time browser node.js</tags>\r\n  </metadata>\r\n  <files>\r\n      <file src=\"moment.js\" target=\"Content\\Scripts\" />\r\n      <file src=\"min/moment.min.js\" target=\"Content\\Scripts\" />\r\n      <file src=\"min/moment-with-locales.js\" target=\"Content\\Scripts\" />\r\n      <file src=\"min/moment-with-locales.min.js\" target=\"Content\\Scripts\" />\r\n  </files>\r\n</package>\r\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/README.md",
    "content": "[![NPM version][npm-version-image]][npm-url] [![NPM downloads][npm-downloads-image]][npm-url] [![MIT License][license-image]][license-url] [![Build Status][travis-image]][travis-url]\n\nA lightweight JavaScript date library for parsing, validating, manipulating, and formatting dates.\n\n## [Documentation](http://momentjs.com/docs/)\n\n## Port to ES6 (version 2.10.0)\n\nMoment 2.10.0 does not bring any new features, but the code is now written in\nes6 modules and placed inside `src/`. Previously `moment.js`, `locale/*.js` and\n`test/moment/*.js`, `test/locale/*.js` contained the source of the project. Now\nthe source is in `src/`, temporary build (es5) files are placed under\n`build/umd/` (for running tests during development), and the `moment.js` and\n`locale/*.js` files are updated only on release.\n\nIf you want to use a particular revision of the code, make sure to run\n`grunt transpile update-index`, so `moment.js` and `locales/*.js` are synced\nwith `src/*`. We might place that in a commit hook in the future.\n\n## Upgrading to 2.0.0\n\nThere are a number of small backwards incompatible changes with version 2.0.0. [See the full descriptions here](https://gist.github.com/timrwood/e72f2eef320ed9e37c51#backwards-incompatible-changes)\n\n * Changed language ordinal method to return the number + ordinal instead of just the ordinal.\n\n * Changed two digit year parsing cutoff to match strptime.\n\n * Removed `moment#sod` and `moment#eod` in favor of `moment#startOf` and `moment#endOf`.\n\n * Removed `moment.humanizeDuration()` in favor of `moment.duration().humanize()`.\n\n * Removed the lang data objects from the top level namespace.\n\n * Duplicate `Date` passed to `moment()` instead of referencing it.\n\n## [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md)\n\n## [Contributing](https://github.com/moment/moment/blob/develop/CONTRIBUTING.md)\n\nWe're looking for co-maintainers! If you want to become a master of time please\nwrite to [ichernev](https://github.com/ichernev).\n\n## License\n\nMoment.js is freely distributable under the terms of the [MIT license](https://github.com/moment/moment/blob/develop/LICENSE).\n\n[license-image]: http://img.shields.io/badge/license-MIT-blue.svg?style=flat\n[license-url]: LICENSE\n\n[npm-url]: https://npmjs.org/package/moment\n[npm-version-image]: http://img.shields.io/npm/v/moment.svg?style=flat\n[npm-downloads-image]: http://img.shields.io/npm/dm/moment.svg?style=flat\n\n[travis-url]: http://travis-ci.org/moment/moment\n[travis-image]: http://img.shields.io/travis/moment/moment/develop.svg?style=flat\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/benchmarks/clone.js",
    "content": "var Benchmark = require('benchmark'),\n    moment = require(\"./../moment.js\"),\n    base = moment('2013-05-25');\n\nmodule.exports = {\n  name: 'clone',\n  onComplete: function(){console.log('done');},\n  fn: function(){base.clone();},\n  async: true\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/bower.json",
    "content": "{\n  \"name\": \"moment\",\n  \"version\": \"2.10.2\",\n  \"main\": \"moment.js\",\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"bower_components\",\n    \"test\",\n    \"tests\",\n    \"tasks\",\n    \"component.json\",\n    \"composer.json\",\n    \"CONTRIBUTING.md\",\n    \"ender.js\",\n    \"Gruntfile.js\",\n    \"package.js\",\n    \"package.json\"\n  ]\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/af.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var af = moment.defineLocale('af', {\n        months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),\n        weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'),\n        weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),\n        weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),\n        meridiemParse: /vm|nm/i,\n        isPM : function (input) {\n            return /^nm$/i.test(input);\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours < 12) {\n                return isLower ? 'vm' : 'VM';\n            } else {\n                return isLower ? 'nm' : 'NM';\n            }\n        },\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Vandag om] LT',\n            nextDay : '[Môre om] LT',\n            nextWeek : 'dddd [om] LT',\n            lastDay : '[Gister om] LT',\n            lastWeek : '[Laas] dddd [om] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'oor %s',\n            past : '%s gelede',\n            s : '\\'n paar sekondes',\n            m : '\\'n minuut',\n            mm : '%d minute',\n            h : '\\'n uur',\n            hh : '%d ure',\n            d : '\\'n dag',\n            dd : '%d dae',\n            M : '\\'n maand',\n            MM : '%d maande',\n            y : '\\'n jaar',\n            yy : '%d jaar'\n        },\n        ordinalParse: /\\d{1,2}(ste|de)/,\n        ordinal : function (number) {\n            return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter\n        },\n        week : {\n            dow : 1, // Maandag is die eerste dag van die week.\n            doy : 4  // Die week wat die 4de Januarie bevat is die eerste week van die jaar.\n        }\n    });\n\n    return af;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/ar-ma.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var ar_ma = moment.defineLocale('ar-ma', {\n        months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n        monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n        weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n        weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n        weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[اليوم على الساعة] LT',\n            nextDay: '[غدا على الساعة] LT',\n            nextWeek: 'dddd [على الساعة] LT',\n            lastDay: '[أمس على الساعة] LT',\n            lastWeek: 'dddd [على الساعة] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'في %s',\n            past : 'منذ %s',\n            s : 'ثوان',\n            m : 'دقيقة',\n            mm : '%d دقائق',\n            h : 'ساعة',\n            hh : '%d ساعات',\n            d : 'يوم',\n            dd : '%d أيام',\n            M : 'شهر',\n            MM : '%d أشهر',\n            y : 'سنة',\n            yy : '%d سنوات'\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return ar_ma;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/ar-sa.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var symbolMap = {\n        '1': '١',\n        '2': '٢',\n        '3': '٣',\n        '4': '٤',\n        '5': '٥',\n        '6': '٦',\n        '7': '٧',\n        '8': '٨',\n        '9': '٩',\n        '0': '٠'\n    }, numberMap = {\n        '١': '1',\n        '٢': '2',\n        '٣': '3',\n        '٤': '4',\n        '٥': '5',\n        '٦': '6',\n        '٧': '7',\n        '٨': '8',\n        '٩': '9',\n        '٠': '0'\n    };\n\n    var ar_sa = moment.defineLocale('ar-sa', {\n        months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n        monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n        weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n        weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n        weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        meridiemParse: /ص|م/,\n        isPM : function (input) {\n            return 'م' === input;\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return 'ص';\n            } else {\n                return 'م';\n            }\n        },\n        calendar : {\n            sameDay: '[اليوم على الساعة] LT',\n            nextDay: '[غدا على الساعة] LT',\n            nextWeek: 'dddd [على الساعة] LT',\n            lastDay: '[أمس على الساعة] LT',\n            lastWeek: 'dddd [على الساعة] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'في %s',\n            past : 'منذ %s',\n            s : 'ثوان',\n            m : 'دقيقة',\n            mm : '%d دقائق',\n            h : 'ساعة',\n            hh : '%d ساعات',\n            d : 'يوم',\n            dd : '%d أيام',\n            M : 'شهر',\n            MM : '%d أشهر',\n            y : 'سنة',\n            yy : '%d سنوات'\n        },\n        preparse: function (string) {\n            return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n                return numberMap[match];\n            }).replace(/،/g, ',');\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return symbolMap[match];\n            }).replace(/,/g, '،');\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return ar_sa;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/ar-tn.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var ar_tn = moment.defineLocale('ar-tn', {\n        months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n        monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n        weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n        weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n        weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n        longDateFormat: {\n            LT: 'HH:mm',\n            LTS: 'LT:ss',\n            L: 'DD/MM/YYYY',\n            LL: 'D MMMM YYYY',\n            LLL: 'D MMMM YYYY LT',\n            LLLL: 'dddd D MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[اليوم على الساعة] LT',\n            nextDay: '[غدا على الساعة] LT',\n            nextWeek: 'dddd [على الساعة] LT',\n            lastDay: '[أمس على الساعة] LT',\n            lastWeek: 'dddd [على الساعة] LT',\n            sameElse: 'L'\n        },\n        relativeTime: {\n            future: 'في %s',\n            past: 'منذ %s',\n            s: 'ثوان',\n            m: 'دقيقة',\n            mm: '%d دقائق',\n            h: 'ساعة',\n            hh: '%d ساعات',\n            d: 'يوم',\n            dd: '%d أيام',\n            M: 'شهر',\n            MM: '%d أشهر',\n            y: 'سنة',\n            yy: '%d سنوات'\n        },\n        week: {\n            dow: 1, // Monday is the first day of the week.\n            doy: 4 // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return ar_tn;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/ar.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var symbolMap = {\n        '1': '١',\n        '2': '٢',\n        '3': '٣',\n        '4': '٤',\n        '5': '٥',\n        '6': '٦',\n        '7': '٧',\n        '8': '٨',\n        '9': '٩',\n        '0': '٠'\n    }, numberMap = {\n        '١': '1',\n        '٢': '2',\n        '٣': '3',\n        '٤': '4',\n        '٥': '5',\n        '٦': '6',\n        '٧': '7',\n        '٨': '8',\n        '٩': '9',\n        '٠': '0'\n    }, pluralForm = function (n) {\n        return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n    }, plurals = {\n        s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n        m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n        h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n        d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n        M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n        y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n    }, pluralize = function (u) {\n        return function (number, withoutSuffix, string, isFuture) {\n            var f = pluralForm(number),\n                str = plurals[u][pluralForm(number)];\n            if (f === 2) {\n                str = str[withoutSuffix ? 0 : 1];\n            }\n            return str.replace(/%d/i, number);\n        };\n    }, months = [\n        'كانون الثاني يناير',\n        'شباط فبراير',\n        'آذار مارس',\n        'نيسان أبريل',\n        'أيار مايو',\n        'حزيران يونيو',\n        'تموز يوليو',\n        'آب أغسطس',\n        'أيلول سبتمبر',\n        'تشرين الأول أكتوبر',\n        'تشرين الثاني نوفمبر',\n        'كانون الأول ديسمبر'\n    ];\n\n    var ar = moment.defineLocale('ar', {\n        months : months,\n        monthsShort : months,\n        weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n        weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n        weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        meridiemParse: /ص|م/,\n        isPM : function (input) {\n            return 'م' === input;\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return 'ص';\n            } else {\n                return 'م';\n            }\n        },\n        calendar : {\n            sameDay: '[اليوم عند الساعة] LT',\n            nextDay: '[غدًا عند الساعة] LT',\n            nextWeek: 'dddd [عند الساعة] LT',\n            lastDay: '[أمس عند الساعة] LT',\n            lastWeek: 'dddd [عند الساعة] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'بعد %s',\n            past : 'منذ %s',\n            s : pluralize('s'),\n            m : pluralize('m'),\n            mm : pluralize('m'),\n            h : pluralize('h'),\n            hh : pluralize('h'),\n            d : pluralize('d'),\n            dd : pluralize('d'),\n            M : pluralize('M'),\n            MM : pluralize('M'),\n            y : pluralize('y'),\n            yy : pluralize('y')\n        },\n        preparse: function (string) {\n            return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n                return numberMap[match];\n            }).replace(/،/g, ',');\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return symbolMap[match];\n            }).replace(/,/g, '،');\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return ar;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/az.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var suffixes = {\n        1: '-inci',\n        5: '-inci',\n        8: '-inci',\n        70: '-inci',\n        80: '-inci',\n        2: '-nci',\n        7: '-nci',\n        20: '-nci',\n        50: '-nci',\n        3: '-üncü',\n        4: '-üncü',\n        100: '-üncü',\n        6: '-ncı',\n        9: '-uncu',\n        10: '-uncu',\n        30: '-uncu',\n        60: '-ıncı',\n        90: '-ıncı'\n    };\n\n    var az = moment.defineLocale('az', {\n        months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'),\n        monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),\n        weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'),\n        weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),\n        weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[bugün saat] LT',\n            nextDay : '[sabah saat] LT',\n            nextWeek : '[gələn həftə] dddd [saat] LT',\n            lastDay : '[dünən] LT',\n            lastWeek : '[keçən həftə] dddd [saat] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s sonra',\n            past : '%s əvvəl',\n            s : 'birneçə saniyyə',\n            m : 'bir dəqiqə',\n            mm : '%d dəqiqə',\n            h : 'bir saat',\n            hh : '%d saat',\n            d : 'bir gün',\n            dd : '%d gün',\n            M : 'bir ay',\n            MM : '%d ay',\n            y : 'bir il',\n            yy : '%d il'\n        },\n        meridiemParse: /gecə|səhər|gündüz|axşam/,\n        isPM : function (input) {\n            return /^(gündüz|axşam)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'gecə';\n            } else if (hour < 12) {\n                return 'səhər';\n            } else if (hour < 17) {\n                return 'gündüz';\n            } else {\n                return 'axşam';\n            }\n        },\n        ordinalParse: /\\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,\n        ordinal : function (number) {\n            if (number === 0) {  // special case for zero\n                return number + '-ıncı';\n            }\n            var a = number % 10,\n                b = number % 100 - a,\n                c = number >= 100 ? 100 : null;\n            return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return az;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/be.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function plural(word, num) {\n        var forms = word.split('_');\n        return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n    }\n    function relativeTimeWithPlural(number, withoutSuffix, key) {\n        var format = {\n            'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',\n            'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',\n            'dd': 'дзень_дні_дзён',\n            'MM': 'месяц_месяцы_месяцаў',\n            'yy': 'год_гады_гадоў'\n        };\n        if (key === 'm') {\n            return withoutSuffix ? 'хвіліна' : 'хвіліну';\n        }\n        else if (key === 'h') {\n            return withoutSuffix ? 'гадзіна' : 'гадзіну';\n        }\n        else {\n            return number + ' ' + plural(format[key], +number);\n        }\n    }\n    function monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'),\n            'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_')\n        },\n        nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function weekdaysCaseReplace(m, format) {\n        var weekdays = {\n            'nominative': 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'),\n            'accusative': 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_')\n        },\n        nounCase = (/\\[ ?[Вв] ?(?:мінулую|наступную)? ?\\] ?dddd/).test(format) ?\n            'accusative' :\n            'nominative';\n        return weekdays[nounCase][m.day()];\n    }\n\n    var be = moment.defineLocale('be', {\n        months : monthsCaseReplace,\n        monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'),\n        weekdays : weekdaysCaseReplace,\n        weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n        weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY г.',\n            LLL : 'D MMMM YYYY г., LT',\n            LLLL : 'dddd, D MMMM YYYY г., LT'\n        },\n        calendar : {\n            sameDay: '[Сёння ў] LT',\n            nextDay: '[Заўтра ў] LT',\n            lastDay: '[Учора ў] LT',\n            nextWeek: function () {\n                return '[У] dddd [ў] LT';\n            },\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return '[У мінулую] dddd [ў] LT';\n                case 1:\n                case 2:\n                case 4:\n                    return '[У мінулы] dddd [ў] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'праз %s',\n            past : '%s таму',\n            s : 'некалькі секунд',\n            m : relativeTimeWithPlural,\n            mm : relativeTimeWithPlural,\n            h : relativeTimeWithPlural,\n            hh : relativeTimeWithPlural,\n            d : 'дзень',\n            dd : relativeTimeWithPlural,\n            M : 'месяц',\n            MM : relativeTimeWithPlural,\n            y : 'год',\n            yy : relativeTimeWithPlural\n        },\n        meridiemParse: /ночы|раніцы|дня|вечара/,\n        isPM : function (input) {\n            return /^(дня|вечара)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'ночы';\n            } else if (hour < 12) {\n                return 'раніцы';\n            } else if (hour < 17) {\n                return 'дня';\n            } else {\n                return 'вечара';\n            }\n        },\n        ordinalParse: /\\d{1,2}-(і|ы|га)/,\n        ordinal: function (number, period) {\n            switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';\n            case 'D':\n                return number + '-га';\n            default:\n                return number;\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return be;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/bg.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var bg = moment.defineLocale('bg', {\n        months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),\n        monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),\n        weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'),\n        weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'),\n        weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'D.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Днес в] LT',\n            nextDay : '[Утре в] LT',\n            nextWeek : 'dddd [в] LT',\n            lastDay : '[Вчера в] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[В изминалата] dddd [в] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[В изминалия] dddd [в] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'след %s',\n            past : 'преди %s',\n            s : 'няколко секунди',\n            m : 'минута',\n            mm : '%d минути',\n            h : 'час',\n            hh : '%d часа',\n            d : 'ден',\n            dd : '%d дни',\n            M : 'месец',\n            MM : '%d месеца',\n            y : 'година',\n            yy : '%d години'\n        },\n        ordinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n        ordinal : function (number) {\n            var lastDigit = number % 10,\n                last2Digits = number % 100;\n            if (number === 0) {\n                return number + '-ев';\n            } else if (last2Digits === 0) {\n                return number + '-ен';\n            } else if (last2Digits > 10 && last2Digits < 20) {\n                return number + '-ти';\n            } else if (lastDigit === 1) {\n                return number + '-ви';\n            } else if (lastDigit === 2) {\n                return number + '-ри';\n            } else if (lastDigit === 7 || lastDigit === 8) {\n                return number + '-ми';\n            } else {\n                return number + '-ти';\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return bg;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/bn.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var symbolMap = {\n        '1': '১',\n        '2': '২',\n        '3': '৩',\n        '4': '৪',\n        '5': '৫',\n        '6': '৬',\n        '7': '৭',\n        '8': '৮',\n        '9': '৯',\n        '0': '০'\n    },\n    numberMap = {\n        '১': '1',\n        '২': '2',\n        '৩': '3',\n        '৪': '4',\n        '৫': '5',\n        '৬': '6',\n        '৭': '7',\n        '৮': '8',\n        '৯': '9',\n        '০': '0'\n    };\n\n    var bn = moment.defineLocale('bn', {\n        months : 'জানুয়ারী_ফেবুয়ারী_মার্চ_এপ্রিল_মে_জুন_জুলাই_অগাস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'),\n        monthsShort : 'জানু_ফেব_মার্চ_এপর_মে_জুন_জুল_অগ_সেপ্ট_অক্টো_নভ_ডিসেম্'.split('_'),\n        weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পত্তিবার_শুক্রুবার_শনিবার'.split('_'),\n        weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পত্তি_শুক্রু_শনি'.split('_'),\n        weekdaysMin : 'রব_সম_মঙ্গ_বু_ব্রিহ_শু_শনি'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm সময়',\n            LTS : 'A h:mm:ss সময়',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        calendar : {\n            sameDay : '[আজ] LT',\n            nextDay : '[আগামীকাল] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[গতকাল] LT',\n            lastWeek : '[গত] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s পরে',\n            past : '%s আগে',\n            s : 'কএক সেকেন্ড',\n            m : 'এক মিনিট',\n            mm : '%d মিনিট',\n            h : 'এক ঘন্টা',\n            hh : '%d ঘন্টা',\n            d : 'এক দিন',\n            dd : '%d দিন',\n            M : 'এক মাস',\n            MM : '%d মাস',\n            y : 'এক বছর',\n            yy : '%d বছর'\n        },\n        preparse: function (string) {\n            return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {\n                return numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return symbolMap[match];\n            });\n        },\n        meridiemParse: /রাত|শকাল|দুপুর|বিকেল|রাত/,\n        isPM: function (input) {\n            return /^(দুপুর|বিকেল|রাত)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'রাত';\n            } else if (hour < 10) {\n                return 'শকাল';\n            } else if (hour < 17) {\n                return 'দুপুর';\n            } else if (hour < 20) {\n                return 'বিকেল';\n            } else {\n                return 'রাত';\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return bn;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/bo.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var symbolMap = {\n        '1': '༡',\n        '2': '༢',\n        '3': '༣',\n        '4': '༤',\n        '5': '༥',\n        '6': '༦',\n        '7': '༧',\n        '8': '༨',\n        '9': '༩',\n        '0': '༠'\n    },\n    numberMap = {\n        '༡': '1',\n        '༢': '2',\n        '༣': '3',\n        '༤': '4',\n        '༥': '5',\n        '༦': '6',\n        '༧': '7',\n        '༨': '8',\n        '༩': '9',\n        '༠': '0'\n    };\n\n    var bo = moment.defineLocale('bo', {\n        months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n        monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n        weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'),\n        weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n        weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        calendar : {\n            sameDay : '[དི་རིང] LT',\n            nextDay : '[སང་ཉིན] LT',\n            nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',\n            lastDay : '[ཁ་སང] LT',\n            lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s ལ་',\n            past : '%s སྔན་ལ',\n            s : 'ལམ་སང',\n            m : 'སྐར་མ་གཅིག',\n            mm : '%d སྐར་མ',\n            h : 'ཆུ་ཚོད་གཅིག',\n            hh : '%d ཆུ་ཚོད',\n            d : 'ཉིན་གཅིག',\n            dd : '%d ཉིན་',\n            M : 'ཟླ་བ་གཅིག',\n            MM : '%d ཟླ་བ',\n            y : 'ལོ་གཅིག',\n            yy : '%d ལོ'\n        },\n        preparse: function (string) {\n            return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {\n                return numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return symbolMap[match];\n            });\n        },\n        meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,\n        isPM: function (input) {\n            return /^(ཉིན་གུང|དགོང་དག|མཚན་མོ)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'མཚན་མོ';\n            } else if (hour < 10) {\n                return 'ཞོགས་ཀས';\n            } else if (hour < 17) {\n                return 'ཉིན་གུང';\n            } else if (hour < 20) {\n                return 'དགོང་དག';\n            } else {\n                return 'མཚན་མོ';\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return bo;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/br.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function relativeTimeWithMutation(number, withoutSuffix, key) {\n        var format = {\n            'mm': 'munutenn',\n            'MM': 'miz',\n            'dd': 'devezh'\n        };\n        return number + ' ' + mutation(format[key], number);\n    }\n    function specialMutationForYears(number) {\n        switch (lastNumber(number)) {\n        case 1:\n        case 3:\n        case 4:\n        case 5:\n        case 9:\n            return number + ' bloaz';\n        default:\n            return number + ' vloaz';\n        }\n    }\n    function lastNumber(number) {\n        if (number > 9) {\n            return lastNumber(number % 10);\n        }\n        return number;\n    }\n    function mutation(text, number) {\n        if (number === 2) {\n            return softMutation(text);\n        }\n        return text;\n    }\n    function softMutation(text) {\n        var mutationTable = {\n            'm': 'v',\n            'b': 'v',\n            'd': 'z'\n        };\n        if (mutationTable[text.charAt(0)] === undefined) {\n            return text;\n        }\n        return mutationTable[text.charAt(0)] + text.substring(1);\n    }\n\n    var br = moment.defineLocale('br', {\n        months : 'Genver_C\\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'),\n        monthsShort : 'Gen_C\\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),\n        weekdays : 'Sul_Lun_Meurzh_Merc\\'her_Yaou_Gwener_Sadorn'.split('_'),\n        weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),\n        weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'h[e]mm A',\n            LTS : 'h[e]mm:ss A',\n            L : 'DD/MM/YYYY',\n            LL : 'D [a viz] MMMM YYYY',\n            LLL : 'D [a viz] MMMM YYYY LT',\n            LLLL : 'dddd, D [a viz] MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Hiziv da] LT',\n            nextDay : '[Warc\\'hoazh da] LT',\n            nextWeek : 'dddd [da] LT',\n            lastDay : '[Dec\\'h da] LT',\n            lastWeek : 'dddd [paset da] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'a-benn %s',\n            past : '%s \\'zo',\n            s : 'un nebeud segondennoù',\n            m : 'ur vunutenn',\n            mm : relativeTimeWithMutation,\n            h : 'un eur',\n            hh : '%d eur',\n            d : 'un devezh',\n            dd : relativeTimeWithMutation,\n            M : 'ur miz',\n            MM : relativeTimeWithMutation,\n            y : 'ur bloaz',\n            yy : specialMutationForYears\n        },\n        ordinalParse: /\\d{1,2}(añ|vet)/,\n        ordinal : function (number) {\n            var output = (number === 1) ? 'añ' : 'vet';\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return br;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/bs.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function translate(number, withoutSuffix, key) {\n        var result = number + ' ';\n        switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n        }\n    }\n\n    var bs = moment.defineLocale('bs', {\n        months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'),\n        monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n        weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n        weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n        weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD. MM. YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd, D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay  : '[danas u] LT',\n            nextDay  : '[sutra u] LT',\n            nextWeek : function () {\n                switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n                }\n            },\n            lastDay  : '[jučer u] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past   : 'prije %s',\n            s      : 'par sekundi',\n            m      : translate,\n            mm     : translate,\n            h      : translate,\n            hh     : translate,\n            d      : 'dan',\n            dd     : translate,\n            M      : 'mjesec',\n            MM     : translate,\n            y      : 'godinu',\n            yy     : translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return bs;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/ca.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var ca = moment.defineLocale('ca', {\n        months : 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),\n        monthsShort : 'gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.'.split('_'),\n        weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'),\n        weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),\n        weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : function () {\n                return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            nextDay : function () {\n                return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            nextWeek : function () {\n                return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            lastDay : function () {\n                return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            lastWeek : function () {\n                return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'en %s',\n            past : 'fa %s',\n            s : 'uns segons',\n            m : 'un minut',\n            mm : '%d minuts',\n            h : 'una hora',\n            hh : '%d hores',\n            d : 'un dia',\n            dd : '%d dies',\n            M : 'un mes',\n            MM : '%d mesos',\n            y : 'un any',\n            yy : '%d anys'\n        },\n        ordinalParse: /\\d{1,2}(r|n|t|è|a)/,\n        ordinal : function (number, period) {\n            var output = (number === 1) ? 'r' :\n                (number === 2) ? 'n' :\n                (number === 3) ? 'r' :\n                (number === 4) ? 't' : 'è';\n            if (period === 'w' || period === 'W') {\n                output = 'a';\n            }\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return ca;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/cs.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_'),\n        monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');\n    function plural(n) {\n        return (n > 1) && (n < 5) && (~~(n / 10) !== 1);\n    }\n    function translate(number, withoutSuffix, key, isFuture) {\n        var result = number + ' ';\n        switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'minuty' : 'minut');\n            } else {\n                return result + 'minutami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'hodiny' : 'hodin');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'den' : 'dnem';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'dny' : 'dní');\n            } else {\n                return result + 'dny';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'měsíce' : 'měsíců');\n            } else {\n                return result + 'měsíci';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokem';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'roky' : 'let');\n            } else {\n                return result + 'lety';\n            }\n            break;\n        }\n    }\n\n    var cs = moment.defineLocale('cs', {\n        months : months,\n        monthsShort : monthsShort,\n        monthsParse : (function (months, monthsShort) {\n            var i, _monthsParse = [];\n            for (i = 0; i < 12; i++) {\n                _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');\n            }\n            return _monthsParse;\n        }(months, monthsShort)),\n        weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),\n        weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'),\n        weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),\n        longDateFormat : {\n            LT: 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[dnes v] LT',\n            nextDay: '[zítra v] LT',\n            nextWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[v neděli v] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [v] LT';\n                case 3:\n                    return '[ve středu v] LT';\n                case 4:\n                    return '[ve čtvrtek v] LT';\n                case 5:\n                    return '[v pátek v] LT';\n                case 6:\n                    return '[v sobotu v] LT';\n                }\n            },\n            lastDay: '[včera v] LT',\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[minulou neděli v] LT';\n                case 1:\n                case 2:\n                    return '[minulé] dddd [v] LT';\n                case 3:\n                    return '[minulou středu v] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [v] LT';\n                case 6:\n                    return '[minulou sobotu v] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past : 'před %s',\n            s : translate,\n            m : translate,\n            mm : translate,\n            h : translate,\n            hh : translate,\n            d : translate,\n            dd : translate,\n            M : translate,\n            MM : translate,\n            y : translate,\n            yy : translate\n        },\n        ordinalParse : /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return cs;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/cv.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var cv = moment.defineLocale('cv', {\n        months : 'кăрлач_нарăс_пуш_ака_май_çĕртме_утă_çурла_авăн_юпа_чӳк_раштав'.split('_'),\n        monthsShort : 'кăр_нар_пуш_ака_май_çĕр_утă_çур_ав_юпа_чӳк_раш'.split('_'),\n        weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кĕçнерникун_эрнекун_шăматкун'.split('_'),\n        weekdaysShort : 'выр_тун_ытл_юн_кĕç_эрн_шăм'.split('_'),\n        weekdaysMin : 'вр_тн_ыт_юн_кç_эр_шм'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD-MM-YYYY',\n            LL : 'YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ]',\n            LLL : 'YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT',\n            LLLL : 'dddd, YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT'\n        },\n        calendar : {\n            sameDay: '[Паян] LT [сехетре]',\n            nextDay: '[Ыран] LT [сехетре]',\n            lastDay: '[Ĕнер] LT [сехетре]',\n            nextWeek: '[Çитес] dddd LT [сехетре]',\n            lastWeek: '[Иртнĕ] dddd LT [сехетре]',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : function (output) {\n                var affix = /сехет$/i.exec(output) ? 'рен' : /çул$/i.exec(output) ? 'тан' : 'ран';\n                return output + affix;\n            },\n            past : '%s каялла',\n            s : 'пĕр-ик çеккунт',\n            m : 'пĕр минут',\n            mm : '%d минут',\n            h : 'пĕр сехет',\n            hh : '%d сехет',\n            d : 'пĕр кун',\n            dd : '%d кун',\n            M : 'пĕр уйăх',\n            MM : '%d уйăх',\n            y : 'пĕр çул',\n            yy : '%d çул'\n        },\n        ordinalParse: /\\d{1,2}-мĕш/,\n        ordinal : '%d-мĕш',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return cv;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/cy.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var cy = moment.defineLocale('cy', {\n        months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),\n        monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'),\n        weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'),\n        weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),\n        weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),\n        longDateFormat: {\n            LT: 'HH:mm',\n            LTS : 'LT:ss',\n            L: 'DD/MM/YYYY',\n            LL: 'D MMMM YYYY',\n            LLL: 'D MMMM YYYY LT',\n            LLLL: 'dddd, D MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[Heddiw am] LT',\n            nextDay: '[Yfory am] LT',\n            nextWeek: 'dddd [am] LT',\n            lastDay: '[Ddoe am] LT',\n            lastWeek: 'dddd [diwethaf am] LT',\n            sameElse: 'L'\n        },\n        relativeTime: {\n            future: 'mewn %s',\n            past: '%s yn ôl',\n            s: 'ychydig eiliadau',\n            m: 'munud',\n            mm: '%d munud',\n            h: 'awr',\n            hh: '%d awr',\n            d: 'diwrnod',\n            dd: '%d diwrnod',\n            M: 'mis',\n            MM: '%d mis',\n            y: 'blwyddyn',\n            yy: '%d flynedd'\n        },\n        ordinalParse: /\\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,\n        ordinal: function (number) {\n            var b = number,\n                output = '',\n                lookup = [\n                    '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed\n                    'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed\n                ];\n            if (b > 20) {\n                if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {\n                    output = 'fed'; // not 30ain, 70ain or 90ain\n                } else {\n                    output = 'ain';\n                }\n            } else if (b > 0) {\n                output = lookup[b];\n            }\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return cy;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/da.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var da = moment.defineLocale('da', {\n        months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n        weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n        weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'),\n        weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd [d.] D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[I dag kl.] LT',\n            nextDay : '[I morgen kl.] LT',\n            nextWeek : 'dddd [kl.] LT',\n            lastDay : '[I går kl.] LT',\n            lastWeek : '[sidste] dddd [kl] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'om %s',\n            past : '%s siden',\n            s : 'få sekunder',\n            m : 'et minut',\n            mm : '%d minutter',\n            h : 'en time',\n            hh : '%d timer',\n            d : 'en dag',\n            dd : '%d dage',\n            M : 'en måned',\n            MM : '%d måneder',\n            y : 'et år',\n            yy : '%d år'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return da;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/de-at.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function processRelativeTime(number, withoutSuffix, key, isFuture) {\n        var format = {\n            'm': ['eine Minute', 'einer Minute'],\n            'h': ['eine Stunde', 'einer Stunde'],\n            'd': ['ein Tag', 'einem Tag'],\n            'dd': [number + ' Tage', number + ' Tagen'],\n            'M': ['ein Monat', 'einem Monat'],\n            'MM': [number + ' Monate', number + ' Monaten'],\n            'y': ['ein Jahr', 'einem Jahr'],\n            'yy': [number + ' Jahre', number + ' Jahren']\n        };\n        return withoutSuffix ? format[key][0] : format[key][1];\n    }\n\n    var de_at = moment.defineLocale('de-at', {\n        months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n        monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n        weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n        weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n        weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT: 'HH:mm',\n            LTS: 'HH:mm:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd, D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Heute um] LT [Uhr]',\n            sameElse: 'L',\n            nextDay: '[Morgen um] LT [Uhr]',\n            nextWeek: 'dddd [um] LT [Uhr]',\n            lastDay: '[Gestern um] LT [Uhr]',\n            lastWeek: '[letzten] dddd [um] LT [Uhr]'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : 'vor %s',\n            s : 'ein paar Sekunden',\n            m : processRelativeTime,\n            mm : '%d Minuten',\n            h : processRelativeTime,\n            hh : '%d Stunden',\n            d : processRelativeTime,\n            dd : processRelativeTime,\n            M : processRelativeTime,\n            MM : processRelativeTime,\n            y : processRelativeTime,\n            yy : processRelativeTime\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return de_at;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/de.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function processRelativeTime(number, withoutSuffix, key, isFuture) {\n        var format = {\n            'm': ['eine Minute', 'einer Minute'],\n            'h': ['eine Stunde', 'einer Stunde'],\n            'd': ['ein Tag', 'einem Tag'],\n            'dd': [number + ' Tage', number + ' Tagen'],\n            'M': ['ein Monat', 'einem Monat'],\n            'MM': [number + ' Monate', number + ' Monaten'],\n            'y': ['ein Jahr', 'einem Jahr'],\n            'yy': [number + ' Jahre', number + ' Jahren']\n        };\n        return withoutSuffix ? format[key][0] : format[key][1];\n    }\n\n    var de = moment.defineLocale('de', {\n        months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n        monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n        weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n        weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n        weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT: 'HH:mm',\n            LTS: 'HH:mm:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd, D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Heute um] LT [Uhr]',\n            sameElse: 'L',\n            nextDay: '[Morgen um] LT [Uhr]',\n            nextWeek: 'dddd [um] LT [Uhr]',\n            lastDay: '[Gestern um] LT [Uhr]',\n            lastWeek: '[letzten] dddd [um] LT [Uhr]'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : 'vor %s',\n            s : 'ein paar Sekunden',\n            m : processRelativeTime,\n            mm : '%d Minuten',\n            h : processRelativeTime,\n            hh : '%d Stunden',\n            d : processRelativeTime,\n            dd : processRelativeTime,\n            M : processRelativeTime,\n            MM : processRelativeTime,\n            y : processRelativeTime,\n            yy : processRelativeTime\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return de;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/el.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var el = moment.defineLocale('el', {\n        monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),\n        monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'),\n        months : function (momentToFormat, format) {\n            if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM'\n                return this._monthsGenitiveEl[momentToFormat.month()];\n            } else {\n                return this._monthsNominativeEl[momentToFormat.month()];\n            }\n        },\n        monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),\n        weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'),\n        weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),\n        weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),\n        meridiem : function (hours, minutes, isLower) {\n            if (hours > 11) {\n                return isLower ? 'μμ' : 'ΜΜ';\n            } else {\n                return isLower ? 'πμ' : 'ΠΜ';\n            }\n        },\n        isPM : function (input) {\n            return ((input + '').toLowerCase()[0] === 'μ');\n        },\n        meridiemParse : /[ΠΜ]\\.?Μ?\\.?/i,\n        longDateFormat : {\n            LT : 'h:mm A',\n            LTS : 'h:mm:ss A',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendarEl : {\n            sameDay : '[Σήμερα {}] LT',\n            nextDay : '[Αύριο {}] LT',\n            nextWeek : 'dddd [{}] LT',\n            lastDay : '[Χθες {}] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                    case 6:\n                        return '[το προηγούμενο] dddd [{}] LT';\n                    default:\n                        return '[την προηγούμενη] dddd [{}] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        calendar : function (key, mom) {\n            var output = this._calendarEl[key],\n                hours = mom && mom.hours();\n            if (typeof output === 'function') {\n                output = output.apply(mom);\n            }\n            return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις'));\n        },\n        relativeTime : {\n            future : 'σε %s',\n            past : '%s πριν',\n            s : 'λίγα δευτερόλεπτα',\n            m : 'ένα λεπτό',\n            mm : '%d λεπτά',\n            h : 'μία ώρα',\n            hh : '%d ώρες',\n            d : 'μία μέρα',\n            dd : '%d μέρες',\n            M : 'ένας μήνας',\n            MM : '%d μήνες',\n            y : 'ένας χρόνος',\n            yy : '%d χρόνια'\n        },\n        ordinalParse: /\\d{1,2}η/,\n        ordinal: '%dη',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4st is the first week of the year.\n        }\n    });\n\n    return el;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/en-au.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var en_au = moment.defineLocale('en-au', {\n        months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n        weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n        weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n        weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'h:mm A',\n            LTS : 'h:mm:ss A',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Today at] LT',\n            nextDay : '[Tomorrow at] LT',\n            nextWeek : 'dddd [at] LT',\n            lastDay : '[Yesterday at] LT',\n            lastWeek : '[Last] dddd [at] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : '%s ago',\n            s : 'a few seconds',\n            m : 'a minute',\n            mm : '%d minutes',\n            h : 'an hour',\n            hh : '%d hours',\n            d : 'a day',\n            dd : '%d days',\n            M : 'a month',\n            MM : '%d months',\n            y : 'a year',\n            yy : '%d years'\n        },\n        ordinalParse: /\\d{1,2}(st|nd|rd|th)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (~~(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return en_au;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/en-ca.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var en_ca = moment.defineLocale('en-ca', {\n        months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n        weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n        weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n        weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'h:mm A',\n            LTS : 'h:mm:ss A',\n            L : 'YYYY-MM-DD',\n            LL : 'D MMMM, YYYY',\n            LLL : 'D MMMM, YYYY LT',\n            LLLL : 'dddd, D MMMM, YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Today at] LT',\n            nextDay : '[Tomorrow at] LT',\n            nextWeek : 'dddd [at] LT',\n            lastDay : '[Yesterday at] LT',\n            lastWeek : '[Last] dddd [at] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : '%s ago',\n            s : 'a few seconds',\n            m : 'a minute',\n            mm : '%d minutes',\n            h : 'an hour',\n            hh : '%d hours',\n            d : 'a day',\n            dd : '%d days',\n            M : 'a month',\n            MM : '%d months',\n            y : 'a year',\n            yy : '%d years'\n        },\n        ordinalParse: /\\d{1,2}(st|nd|rd|th)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (~~(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        }\n    });\n\n    return en_ca;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/en-gb.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var en_gb = moment.defineLocale('en-gb', {\n        months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n        weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n        weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n        weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Today at] LT',\n            nextDay : '[Tomorrow at] LT',\n            nextWeek : 'dddd [at] LT',\n            lastDay : '[Yesterday at] LT',\n            lastWeek : '[Last] dddd [at] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : '%s ago',\n            s : 'a few seconds',\n            m : 'a minute',\n            mm : '%d minutes',\n            h : 'an hour',\n            hh : '%d hours',\n            d : 'a day',\n            dd : '%d days',\n            M : 'a month',\n            MM : '%d months',\n            y : 'a year',\n            yy : '%d years'\n        },\n        ordinalParse: /\\d{1,2}(st|nd|rd|th)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (~~(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return en_gb;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/eo.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var eo = moment.defineLocale('eo', {\n        months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'),\n        weekdays : 'Dimanĉo_Lundo_Mardo_Merkredo_Ĵaŭdo_Vendredo_Sabato'.split('_'),\n        weekdaysShort : 'Dim_Lun_Mard_Merk_Ĵaŭ_Ven_Sab'.split('_'),\n        weekdaysMin : 'Di_Lu_Ma_Me_Ĵa_Ve_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'D[-an de] MMMM, YYYY',\n            LLL : 'D[-an de] MMMM, YYYY LT',\n            LLLL : 'dddd, [la] D[-an de] MMMM, YYYY LT'\n        },\n        meridiemParse: /[ap]\\.t\\.m/i,\n        isPM: function (input) {\n            return input.charAt(0).toLowerCase() === 'p';\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours > 11) {\n                return isLower ? 'p.t.m.' : 'P.T.M.';\n            } else {\n                return isLower ? 'a.t.m.' : 'A.T.M.';\n            }\n        },\n        calendar : {\n            sameDay : '[Hodiaŭ je] LT',\n            nextDay : '[Morgaŭ je] LT',\n            nextWeek : 'dddd [je] LT',\n            lastDay : '[Hieraŭ je] LT',\n            lastWeek : '[pasinta] dddd [je] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'je %s',\n            past : 'antaŭ %s',\n            s : 'sekundoj',\n            m : 'minuto',\n            mm : '%d minutoj',\n            h : 'horo',\n            hh : '%d horoj',\n            d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo\n            dd : '%d tagoj',\n            M : 'monato',\n            MM : '%d monatoj',\n            y : 'jaro',\n            yy : '%d jaroj'\n        },\n        ordinalParse: /\\d{1,2}a/,\n        ordinal : '%da',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return eo;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/es.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'),\n        monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\n    var es = moment.defineLocale('es', {\n        months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n        monthsShort : function (m, format) {\n            if (/-MMM-/.test(format)) {\n                return monthsShort[m.month()];\n            } else {\n                return monthsShortDot[m.month()];\n            }\n        },\n        weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n        weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n        weekdaysMin : 'Do_Lu_Ma_Mi_Ju_Vi_Sá'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D [de] MMMM [de] YYYY',\n            LLL : 'D [de] MMMM [de] YYYY LT',\n            LLLL : 'dddd, D [de] MMMM [de] YYYY LT'\n        },\n        calendar : {\n            sameDay : function () {\n                return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            nextDay : function () {\n                return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            nextWeek : function () {\n                return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            lastDay : function () {\n                return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            lastWeek : function () {\n                return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'en %s',\n            past : 'hace %s',\n            s : 'unos segundos',\n            m : 'un minuto',\n            mm : '%d minutos',\n            h : 'una hora',\n            hh : '%d horas',\n            d : 'un día',\n            dd : '%d días',\n            M : 'un mes',\n            MM : '%d meses',\n            y : 'un año',\n            yy : '%d años'\n        },\n        ordinalParse : /\\d{1,2}º/,\n        ordinal : '%dº',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return es;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/et.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function processRelativeTime(number, withoutSuffix, key, isFuture) {\n        var format = {\n            's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],\n            'm' : ['ühe minuti', 'üks minut'],\n            'mm': [number + ' minuti', number + ' minutit'],\n            'h' : ['ühe tunni', 'tund aega', 'üks tund'],\n            'hh': [number + ' tunni', number + ' tundi'],\n            'd' : ['ühe päeva', 'üks päev'],\n            'M' : ['kuu aja', 'kuu aega', 'üks kuu'],\n            'MM': [number + ' kuu', number + ' kuud'],\n            'y' : ['ühe aasta', 'aasta', 'üks aasta'],\n            'yy': [number + ' aasta', number + ' aastat']\n        };\n        if (withoutSuffix) {\n            return format[key][2] ? format[key][2] : format[key][1];\n        }\n        return isFuture ? format[key][0] : format[key][1];\n    }\n\n    var et = moment.defineLocale('et', {\n        months        : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'),\n        monthsShort   : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'),\n        weekdays      : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'),\n        weekdaysShort : 'P_E_T_K_N_R_L'.split('_'),\n        weekdaysMin   : 'P_E_T_K_N_R_L'.split('_'),\n        longDateFormat : {\n            LT   : 'H:mm',\n            LTS : 'LT:ss',\n            L    : 'DD.MM.YYYY',\n            LL   : 'D. MMMM YYYY',\n            LLL  : 'D. MMMM YYYY LT',\n            LLLL : 'dddd, D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay  : '[Täna,] LT',\n            nextDay  : '[Homme,] LT',\n            nextWeek : '[Järgmine] dddd LT',\n            lastDay  : '[Eile,] LT',\n            lastWeek : '[Eelmine] dddd LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s pärast',\n            past   : '%s tagasi',\n            s      : processRelativeTime,\n            m      : processRelativeTime,\n            mm     : processRelativeTime,\n            h      : processRelativeTime,\n            hh     : processRelativeTime,\n            d      : processRelativeTime,\n            dd     : '%d päeva',\n            M      : processRelativeTime,\n            MM     : processRelativeTime,\n            y      : processRelativeTime,\n            yy     : processRelativeTime\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return et;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/eu.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var eu = moment.defineLocale('eu', {\n        months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'),\n        monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'),\n        weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'),\n        weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'),\n        weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'YYYY[ko] MMMM[ren] D[a]',\n            LLL : 'YYYY[ko] MMMM[ren] D[a] LT',\n            LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] LT',\n            l : 'YYYY-M-D',\n            ll : 'YYYY[ko] MMM D[a]',\n            lll : 'YYYY[ko] MMM D[a] LT',\n            llll : 'ddd, YYYY[ko] MMM D[a] LT'\n        },\n        calendar : {\n            sameDay : '[gaur] LT[etan]',\n            nextDay : '[bihar] LT[etan]',\n            nextWeek : 'dddd LT[etan]',\n            lastDay : '[atzo] LT[etan]',\n            lastWeek : '[aurreko] dddd LT[etan]',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s barru',\n            past : 'duela %s',\n            s : 'segundo batzuk',\n            m : 'minutu bat',\n            mm : '%d minutu',\n            h : 'ordu bat',\n            hh : '%d ordu',\n            d : 'egun bat',\n            dd : '%d egun',\n            M : 'hilabete bat',\n            MM : '%d hilabete',\n            y : 'urte bat',\n            yy : '%d urte'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return eu;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/fa.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var symbolMap = {\n        '1': '۱',\n        '2': '۲',\n        '3': '۳',\n        '4': '۴',\n        '5': '۵',\n        '6': '۶',\n        '7': '۷',\n        '8': '۸',\n        '9': '۹',\n        '0': '۰'\n    }, numberMap = {\n        '۱': '1',\n        '۲': '2',\n        '۳': '3',\n        '۴': '4',\n        '۵': '5',\n        '۶': '6',\n        '۷': '7',\n        '۸': '8',\n        '۹': '9',\n        '۰': '0'\n    };\n\n    var fa = moment.defineLocale('fa', {\n        months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n        monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n        weekdays : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n        weekdaysShort : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n        weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        meridiemParse: /قبل از ظهر|بعد از ظهر/,\n        isPM: function (input) {\n            return /بعد از ظهر/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return 'قبل از ظهر';\n            } else {\n                return 'بعد از ظهر';\n            }\n        },\n        calendar : {\n            sameDay : '[امروز ساعت] LT',\n            nextDay : '[فردا ساعت] LT',\n            nextWeek : 'dddd [ساعت] LT',\n            lastDay : '[دیروز ساعت] LT',\n            lastWeek : 'dddd [پیش] [ساعت] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'در %s',\n            past : '%s پیش',\n            s : 'چندین ثانیه',\n            m : 'یک دقیقه',\n            mm : '%d دقیقه',\n            h : 'یک ساعت',\n            hh : '%d ساعت',\n            d : 'یک روز',\n            dd : '%d روز',\n            M : 'یک ماه',\n            MM : '%d ماه',\n            y : 'یک سال',\n            yy : '%d سال'\n        },\n        preparse: function (string) {\n            return string.replace(/[۰-۹]/g, function (match) {\n                return numberMap[match];\n            }).replace(/،/g, ',');\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return symbolMap[match];\n            }).replace(/,/g, '،');\n        },\n        ordinalParse: /\\d{1,2}م/,\n        ordinal : '%dم',\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12 // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return fa;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/fi.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '),\n        numbersFuture = [\n            'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',\n            numbersPast[7], numbersPast[8], numbersPast[9]\n        ];\n    function translate(number, withoutSuffix, key, isFuture) {\n        var result = '';\n        switch (key) {\n        case 's':\n            return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';\n        case 'm':\n            return isFuture ? 'minuutin' : 'minuutti';\n        case 'mm':\n            result = isFuture ? 'minuutin' : 'minuuttia';\n            break;\n        case 'h':\n            return isFuture ? 'tunnin' : 'tunti';\n        case 'hh':\n            result = isFuture ? 'tunnin' : 'tuntia';\n            break;\n        case 'd':\n            return isFuture ? 'päivän' : 'päivä';\n        case 'dd':\n            result = isFuture ? 'päivän' : 'päivää';\n            break;\n        case 'M':\n            return isFuture ? 'kuukauden' : 'kuukausi';\n        case 'MM':\n            result = isFuture ? 'kuukauden' : 'kuukautta';\n            break;\n        case 'y':\n            return isFuture ? 'vuoden' : 'vuosi';\n        case 'yy':\n            result = isFuture ? 'vuoden' : 'vuotta';\n            break;\n        }\n        result = verbalNumber(number, isFuture) + ' ' + result;\n        return result;\n    }\n    function verbalNumber(number, isFuture) {\n        return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;\n    }\n\n    var fi = moment.defineLocale('fi', {\n        months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'),\n        monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'),\n        weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'),\n        weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'),\n        weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'),\n        longDateFormat : {\n            LT : 'HH.mm',\n            LTS : 'HH.mm.ss',\n            L : 'DD.MM.YYYY',\n            LL : 'Do MMMM[ta] YYYY',\n            LLL : 'Do MMMM[ta] YYYY, [klo] LT',\n            LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] LT',\n            l : 'D.M.YYYY',\n            ll : 'Do MMM YYYY',\n            lll : 'Do MMM YYYY, [klo] LT',\n            llll : 'ddd, Do MMM YYYY, [klo] LT'\n        },\n        calendar : {\n            sameDay : '[tänään] [klo] LT',\n            nextDay : '[huomenna] [klo] LT',\n            nextWeek : 'dddd [klo] LT',\n            lastDay : '[eilen] [klo] LT',\n            lastWeek : '[viime] dddd[na] [klo] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s päästä',\n            past : '%s sitten',\n            s : translate,\n            m : translate,\n            mm : translate,\n            h : translate,\n            hh : translate,\n            d : translate,\n            dd : translate,\n            M : translate,\n            MM : translate,\n            y : translate,\n            yy : translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return fi;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/fo.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var fo = moment.defineLocale('fo', {\n        months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n        weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'),\n        weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'),\n        weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D. MMMM, YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Í dag kl.] LT',\n            nextDay : '[Í morgin kl.] LT',\n            nextWeek : 'dddd [kl.] LT',\n            lastDay : '[Í gjár kl.] LT',\n            lastWeek : '[síðstu] dddd [kl] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'um %s',\n            past : '%s síðani',\n            s : 'fá sekund',\n            m : 'ein minutt',\n            mm : '%d minuttir',\n            h : 'ein tími',\n            hh : '%d tímar',\n            d : 'ein dagur',\n            dd : '%d dagar',\n            M : 'ein mánaði',\n            MM : '%d mánaðir',\n            y : 'eitt ár',\n            yy : '%d ár'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return fo;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/fr-ca.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var fr_ca = moment.defineLocale('fr-ca', {\n        months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n        monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n        weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n        weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n        weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Aujourd\\'hui à] LT',\n            nextDay: '[Demain à] LT',\n            nextWeek: 'dddd [à] LT',\n            lastDay: '[Hier à] LT',\n            lastWeek: 'dddd [dernier à] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'dans %s',\n            past : 'il y a %s',\n            s : 'quelques secondes',\n            m : 'une minute',\n            mm : '%d minutes',\n            h : 'une heure',\n            hh : '%d heures',\n            d : 'un jour',\n            dd : '%d jours',\n            M : 'un mois',\n            MM : '%d mois',\n            y : 'un an',\n            yy : '%d ans'\n        },\n        ordinalParse: /\\d{1,2}(er|)/,\n        ordinal : function (number) {\n            return number + (number === 1 ? 'er' : '');\n        }\n    });\n\n    return fr_ca;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/fr.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var fr = moment.defineLocale('fr', {\n        months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n        monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n        weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n        weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n        weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Aujourd\\'hui à] LT',\n            nextDay: '[Demain à] LT',\n            nextWeek: 'dddd [à] LT',\n            lastDay: '[Hier à] LT',\n            lastWeek: 'dddd [dernier à] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'dans %s',\n            past : 'il y a %s',\n            s : 'quelques secondes',\n            m : 'une minute',\n            mm : '%d minutes',\n            h : 'une heure',\n            hh : '%d heures',\n            d : 'un jour',\n            dd : '%d jours',\n            M : 'un mois',\n            MM : '%d mois',\n            y : 'un an',\n            yy : '%d ans'\n        },\n        ordinalParse: /\\d{1,2}(er|)/,\n        ordinal : function (number) {\n            return number + (number === 1 ? 'er' : '');\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return fr;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/fy.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_'),\n        monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_');\n\n    var fy = moment.defineLocale('fy', {\n        months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'),\n        monthsShort : function (m, format) {\n            if (/-MMM-/.test(format)) {\n                return monthsShortWithoutDots[m.month()];\n            } else {\n                return monthsShortWithDots[m.month()];\n            }\n        },\n        weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'),\n        weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'),\n        weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD-MM-YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[hjoed om] LT',\n            nextDay: '[moarn om] LT',\n            nextWeek: 'dddd [om] LT',\n            lastDay: '[juster om] LT',\n            lastWeek: '[ôfrûne] dddd [om] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'oer %s',\n            past : '%s lyn',\n            s : 'in pear sekonden',\n            m : 'ien minút',\n            mm : '%d minuten',\n            h : 'ien oere',\n            hh : '%d oeren',\n            d : 'ien dei',\n            dd : '%d dagen',\n            M : 'ien moanne',\n            MM : '%d moannen',\n            y : 'ien jier',\n            yy : '%d jierren'\n        },\n        ordinalParse: /\\d{1,2}(ste|de)/,\n        ordinal : function (number) {\n            return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return fy;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/gl.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var gl = moment.defineLocale('gl', {\n        months : 'Xaneiro_Febreiro_Marzo_Abril_Maio_Xuño_Xullo_Agosto_Setembro_Outubro_Novembro_Decembro'.split('_'),\n        monthsShort : 'Xan._Feb._Mar._Abr._Mai._Xuñ._Xul._Ago._Set._Out._Nov._Dec.'.split('_'),\n        weekdays : 'Domingo_Luns_Martes_Mércores_Xoves_Venres_Sábado'.split('_'),\n        weekdaysShort : 'Dom._Lun._Mar._Mér._Xov._Ven._Sáb.'.split('_'),\n        weekdaysMin : 'Do_Lu_Ma_Mé_Xo_Ve_Sá'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : function () {\n                return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n            },\n            nextDay : function () {\n                return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n            },\n            nextWeek : function () {\n                return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n            },\n            lastDay : function () {\n                return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';\n            },\n            lastWeek : function () {\n                return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : function (str) {\n                if (str === 'uns segundos') {\n                    return 'nuns segundos';\n                }\n                return 'en ' + str;\n            },\n            past : 'hai %s',\n            s : 'uns segundos',\n            m : 'un minuto',\n            mm : '%d minutos',\n            h : 'unha hora',\n            hh : '%d horas',\n            d : 'un día',\n            dd : '%d días',\n            M : 'un mes',\n            MM : '%d meses',\n            y : 'un ano',\n            yy : '%d anos'\n        },\n        ordinalParse : /\\d{1,2}º/,\n        ordinal : '%dº',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return gl;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/he.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var he = moment.defineLocale('he', {\n        months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'),\n        monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'),\n        weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'),\n        weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'),\n        weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D [ב]MMMM YYYY',\n            LLL : 'D [ב]MMMM YYYY LT',\n            LLLL : 'dddd, D [ב]MMMM YYYY LT',\n            l : 'D/M/YYYY',\n            ll : 'D MMM YYYY',\n            lll : 'D MMM YYYY LT',\n            llll : 'ddd, D MMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[היום ב־]LT',\n            nextDay : '[מחר ב־]LT',\n            nextWeek : 'dddd [בשעה] LT',\n            lastDay : '[אתמול ב־]LT',\n            lastWeek : '[ביום] dddd [האחרון בשעה] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'בעוד %s',\n            past : 'לפני %s',\n            s : 'מספר שניות',\n            m : 'דקה',\n            mm : '%d דקות',\n            h : 'שעה',\n            hh : function (number) {\n                if (number === 2) {\n                    return 'שעתיים';\n                }\n                return number + ' שעות';\n            },\n            d : 'יום',\n            dd : function (number) {\n                if (number === 2) {\n                    return 'יומיים';\n                }\n                return number + ' ימים';\n            },\n            M : 'חודש',\n            MM : function (number) {\n                if (number === 2) {\n                    return 'חודשיים';\n                }\n                return number + ' חודשים';\n            },\n            y : 'שנה',\n            yy : function (number) {\n                if (number === 2) {\n                    return 'שנתיים';\n                } else if (number % 10 === 0 && number !== 10) {\n                    return number + ' שנה';\n                }\n                return number + ' שנים';\n            }\n        }\n    });\n\n    return he;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/hi.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var symbolMap = {\n        '1': '१',\n        '2': '२',\n        '3': '३',\n        '4': '४',\n        '5': '५',\n        '6': '६',\n        '7': '७',\n        '8': '८',\n        '9': '९',\n        '0': '०'\n    },\n    numberMap = {\n        '१': '1',\n        '२': '2',\n        '३': '3',\n        '४': '4',\n        '५': '5',\n        '६': '6',\n        '७': '7',\n        '८': '8',\n        '९': '9',\n        '०': '0'\n    };\n\n    var hi = moment.defineLocale('hi', {\n        months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'),\n        monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'),\n        weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n        weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'),\n        weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm बजे',\n            LTS : 'A h:mm:ss बजे',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        calendar : {\n            sameDay : '[आज] LT',\n            nextDay : '[कल] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[कल] LT',\n            lastWeek : '[पिछले] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s में',\n            past : '%s पहले',\n            s : 'कुछ ही क्षण',\n            m : 'एक मिनट',\n            mm : '%d मिनट',\n            h : 'एक घंटा',\n            hh : '%d घंटे',\n            d : 'एक दिन',\n            dd : '%d दिन',\n            M : 'एक महीने',\n            MM : '%d महीने',\n            y : 'एक वर्ष',\n            yy : '%d वर्ष'\n        },\n        preparse: function (string) {\n            return string.replace(/[१२३४५६७८९०]/g, function (match) {\n                return numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return symbolMap[match];\n            });\n        },\n        meridiemParse: /रात|सुबह|दोपहर|शाम/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'रात') {\n                return hour < 4 ? hour : hour + 12;\n            } else if (meridiem === 'सुबह') {\n                return hour;\n            } else if (meridiem === 'दोपहर') {\n                return hour >= 10 ? hour : hour + 12;\n            } else if (meridiem === 'शाम') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'रात';\n            } else if (hour < 10) {\n                return 'सुबह';\n            } else if (hour < 17) {\n                return 'दोपहर';\n            } else if (hour < 20) {\n                return 'शाम';\n            } else {\n                return 'रात';\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return hi;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/hr.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function translate(number, withoutSuffix, key) {\n        var result = number + ' ';\n        switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n        }\n    }\n\n    var hr = moment.defineLocale('hr', {\n        months : 'sječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_'),\n        monthsShort : 'sje._vel._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'),\n        weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n        weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n        weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD. MM. YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd, D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay  : '[danas u] LT',\n            nextDay  : '[sutra u] LT',\n            nextWeek : function () {\n                switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n                }\n            },\n            lastDay  : '[jučer u] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past   : 'prije %s',\n            s      : 'par sekundi',\n            m      : translate,\n            mm     : translate,\n            h      : translate,\n            hh     : translate,\n            d      : 'dan',\n            dd     : translate,\n            M      : 'mjesec',\n            MM     : translate,\n            y      : 'godinu',\n            yy     : translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return hr;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/hu.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');\n    function translate(number, withoutSuffix, key, isFuture) {\n        var num = number,\n            suffix;\n        switch (key) {\n        case 's':\n            return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';\n        case 'm':\n            return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'mm':\n            return num + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'h':\n            return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'hh':\n            return num + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'd':\n            return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'dd':\n            return num + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'M':\n            return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'MM':\n            return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'y':\n            return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');\n        case 'yy':\n            return num + (isFuture || withoutSuffix ? ' év' : ' éve');\n        }\n        return '';\n    }\n    function week(isFuture) {\n        return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';\n    }\n\n    var hu = moment.defineLocale('hu', {\n        months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'),\n        monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'),\n        weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),\n        weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),\n        weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'YYYY.MM.DD.',\n            LL : 'YYYY. MMMM D.',\n            LLL : 'YYYY. MMMM D., LT',\n            LLLL : 'YYYY. MMMM D., dddd LT'\n        },\n        meridiemParse: /de|du/i,\n        isPM: function (input) {\n            return input.charAt(1).toLowerCase() === 'u';\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours < 12) {\n                return isLower === true ? 'de' : 'DE';\n            } else {\n                return isLower === true ? 'du' : 'DU';\n            }\n        },\n        calendar : {\n            sameDay : '[ma] LT[-kor]',\n            nextDay : '[holnap] LT[-kor]',\n            nextWeek : function () {\n                return week.call(this, true);\n            },\n            lastDay : '[tegnap] LT[-kor]',\n            lastWeek : function () {\n                return week.call(this, false);\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s múlva',\n            past : '%s',\n            s : translate,\n            m : translate,\n            mm : translate,\n            h : translate,\n            hh : translate,\n            d : translate,\n            dd : translate,\n            M : translate,\n            MM : translate,\n            y : translate,\n            yy : translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return hu;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/hy-am.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),\n            'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_')\n        },\n        nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function monthsShortCaseReplace(m, format) {\n        var monthsShort = 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_');\n        return monthsShort[m.month()];\n    }\n    function weekdaysCaseReplace(m, format) {\n        var weekdays = 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_');\n        return weekdays[m.day()];\n    }\n\n    var hy_am = moment.defineLocale('hy-am', {\n        months : monthsCaseReplace,\n        monthsShort : monthsShortCaseReplace,\n        weekdays : weekdaysCaseReplace,\n        weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n        weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY թ.',\n            LLL : 'D MMMM YYYY թ., LT',\n            LLLL : 'dddd, D MMMM YYYY թ., LT'\n        },\n        calendar : {\n            sameDay: '[այսօր] LT',\n            nextDay: '[վաղը] LT',\n            lastDay: '[երեկ] LT',\n            nextWeek: function () {\n                return 'dddd [օրը ժամը] LT';\n            },\n            lastWeek: function () {\n                return '[անցած] dddd [օրը ժամը] LT';\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : '%s հետո',\n            past : '%s առաջ',\n            s : 'մի քանի վայրկյան',\n            m : 'րոպե',\n            mm : '%d րոպե',\n            h : 'ժամ',\n            hh : '%d ժամ',\n            d : 'օր',\n            dd : '%d օր',\n            M : 'ամիս',\n            MM : '%d ամիս',\n            y : 'տարի',\n            yy : '%d տարի'\n        },\n        meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,\n        isPM: function (input) {\n            return /^(ցերեկվա|երեկոյան)$/.test(input);\n        },\n        meridiem : function (hour) {\n            if (hour < 4) {\n                return 'գիշերվա';\n            } else if (hour < 12) {\n                return 'առավոտվա';\n            } else if (hour < 17) {\n                return 'ցերեկվա';\n            } else {\n                return 'երեկոյան';\n            }\n        },\n        ordinalParse: /\\d{1,2}|\\d{1,2}-(ին|րդ)/,\n        ordinal: function (number, period) {\n            switch (period) {\n            case 'DDD':\n            case 'w':\n            case 'W':\n            case 'DDDo':\n                if (number === 1) {\n                    return number + '-ին';\n                }\n                return number + '-րդ';\n            default:\n                return number;\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return hy_am;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/id.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var id = moment.defineLocale('id', {\n        months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'),\n        weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'),\n        weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'),\n        weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),\n        longDateFormat : {\n            LT : 'HH.mm',\n            LTS : 'LT.ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY [pukul] LT',\n            LLLL : 'dddd, D MMMM YYYY [pukul] LT'\n        },\n        meridiemParse: /pagi|siang|sore|malam/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'pagi') {\n                return hour;\n            } else if (meridiem === 'siang') {\n                return hour >= 11 ? hour : hour + 12;\n            } else if (meridiem === 'sore' || meridiem === 'malam') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours < 11) {\n                return 'pagi';\n            } else if (hours < 15) {\n                return 'siang';\n            } else if (hours < 19) {\n                return 'sore';\n            } else {\n                return 'malam';\n            }\n        },\n        calendar : {\n            sameDay : '[Hari ini pukul] LT',\n            nextDay : '[Besok pukul] LT',\n            nextWeek : 'dddd [pukul] LT',\n            lastDay : '[Kemarin pukul] LT',\n            lastWeek : 'dddd [lalu pukul] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'dalam %s',\n            past : '%s yang lalu',\n            s : 'beberapa detik',\n            m : 'semenit',\n            mm : '%d menit',\n            h : 'sejam',\n            hh : '%d jam',\n            d : 'sehari',\n            dd : '%d hari',\n            M : 'sebulan',\n            MM : '%d bulan',\n            y : 'setahun',\n            yy : '%d tahun'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return id;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/is.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function plural(n) {\n        if (n % 100 === 11) {\n            return true;\n        } else if (n % 10 === 1) {\n            return false;\n        }\n        return true;\n    }\n    function translate(number, withoutSuffix, key, isFuture) {\n        var result = number + ' ';\n        switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';\n        case 'm':\n            return withoutSuffix ? 'mínúta' : 'mínútu';\n        case 'mm':\n            if (plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');\n            } else if (withoutSuffix) {\n                return result + 'mínúta';\n            }\n            return result + 'mínútu';\n        case 'hh':\n            if (plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');\n            }\n            return result + 'klukkustund';\n        case 'd':\n            if (withoutSuffix) {\n                return 'dagur';\n            }\n            return isFuture ? 'dag' : 'degi';\n        case 'dd':\n            if (plural(number)) {\n                if (withoutSuffix) {\n                    return result + 'dagar';\n                }\n                return result + (isFuture ? 'daga' : 'dögum');\n            } else if (withoutSuffix) {\n                return result + 'dagur';\n            }\n            return result + (isFuture ? 'dag' : 'degi');\n        case 'M':\n            if (withoutSuffix) {\n                return 'mánuður';\n            }\n            return isFuture ? 'mánuð' : 'mánuði';\n        case 'MM':\n            if (plural(number)) {\n                if (withoutSuffix) {\n                    return result + 'mánuðir';\n                }\n                return result + (isFuture ? 'mánuði' : 'mánuðum');\n            } else if (withoutSuffix) {\n                return result + 'mánuður';\n            }\n            return result + (isFuture ? 'mánuð' : 'mánuði');\n        case 'y':\n            return withoutSuffix || isFuture ? 'ár' : 'ári';\n        case 'yy':\n            if (plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'ár' : 'árum');\n            }\n            return result + (withoutSuffix || isFuture ? 'ár' : 'ári');\n        }\n    }\n\n    var is = moment.defineLocale('is', {\n        months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'),\n        weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'),\n        weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'),\n        weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY [kl.] LT',\n            LLLL : 'dddd, D. MMMM YYYY [kl.] LT'\n        },\n        calendar : {\n            sameDay : '[í dag kl.] LT',\n            nextDay : '[á morgun kl.] LT',\n            nextWeek : 'dddd [kl.] LT',\n            lastDay : '[í gær kl.] LT',\n            lastWeek : '[síðasta] dddd [kl.] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'eftir %s',\n            past : 'fyrir %s síðan',\n            s : translate,\n            m : translate,\n            mm : translate,\n            h : 'klukkustund',\n            hh : translate,\n            d : translate,\n            dd : translate,\n            M : translate,\n            MM : translate,\n            y : translate,\n            yy : translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return is;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/it.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var it = moment.defineLocale('it', {\n        months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'),\n        monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),\n        weekdays : 'Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato'.split('_'),\n        weekdaysShort : 'Dom_Lun_Mar_Mer_Gio_Ven_Sab'.split('_'),\n        weekdaysMin : 'D_L_Ma_Me_G_V_S'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Oggi alle] LT',\n            nextDay: '[Domani alle] LT',\n            nextWeek: 'dddd [alle] LT',\n            lastDay: '[Ieri alle] LT',\n            lastWeek: function () {\n                switch (this.day()) {\n                    case 0:\n                        return '[la scorsa] dddd [alle] LT';\n                    default:\n                        return '[lo scorso] dddd [alle] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : function (s) {\n                return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s;\n            },\n            past : '%s fa',\n            s : 'alcuni secondi',\n            m : 'un minuto',\n            mm : '%d minuti',\n            h : 'un\\'ora',\n            hh : '%d ore',\n            d : 'un giorno',\n            dd : '%d giorni',\n            M : 'un mese',\n            MM : '%d mesi',\n            y : 'un anno',\n            yy : '%d anni'\n        },\n        ordinalParse : /\\d{1,2}º/,\n        ordinal: '%dº',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return it;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/ja.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var ja = moment.defineLocale('ja', {\n        months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n        monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n        weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),\n        weekdaysShort : '日_月_火_水_木_金_土'.split('_'),\n        weekdaysMin : '日_月_火_水_木_金_土'.split('_'),\n        longDateFormat : {\n            LT : 'Ah時m分',\n            LTS : 'LTs秒',\n            L : 'YYYY/MM/DD',\n            LL : 'YYYY年M月D日',\n            LLL : 'YYYY年M月D日LT',\n            LLLL : 'YYYY年M月D日LT dddd'\n        },\n        meridiemParse: /午前|午後/i,\n        isPM : function (input) {\n            return input === '午後';\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return '午前';\n            } else {\n                return '午後';\n            }\n        },\n        calendar : {\n            sameDay : '[今日] LT',\n            nextDay : '[明日] LT',\n            nextWeek : '[来週]dddd LT',\n            lastDay : '[昨日] LT',\n            lastWeek : '[前週]dddd LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s後',\n            past : '%s前',\n            s : '数秒',\n            m : '1分',\n            mm : '%d分',\n            h : '1時間',\n            hh : '%d時間',\n            d : '1日',\n            dd : '%d日',\n            M : '1ヶ月',\n            MM : '%dヶ月',\n            y : '1年',\n            yy : '%d年'\n        }\n    });\n\n    return ja;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/ka.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),\n            'accusative': 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')\n        },\n        nounCase = (/D[oD] *MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function weekdaysCaseReplace(m, format) {\n        var weekdays = {\n            'nominative': 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),\n            'accusative': 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_')\n        },\n        nounCase = (/(წინა|შემდეგ)/).test(format) ?\n            'accusative' :\n            'nominative';\n        return weekdays[nounCase][m.day()];\n    }\n\n    var ka = moment.defineLocale('ka', {\n        months : monthsCaseReplace,\n        monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'),\n        weekdays : weekdaysCaseReplace,\n        weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'),\n        weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'),\n        longDateFormat : {\n            LT : 'h:mm A',\n            LTS : 'h:mm:ss A',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[დღეს] LT[-ზე]',\n            nextDay : '[ხვალ] LT[-ზე]',\n            lastDay : '[გუშინ] LT[-ზე]',\n            nextWeek : '[შემდეგ] dddd LT[-ზე]',\n            lastWeek : '[წინა] dddd LT-ზე',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : function (s) {\n                return (/(წამი|წუთი|საათი|წელი)/).test(s) ?\n                    s.replace(/ი$/, 'ში') :\n                    s + 'ში';\n            },\n            past : function (s) {\n                if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {\n                    return s.replace(/(ი|ე)$/, 'ის წინ');\n                }\n                if ((/წელი/).test(s)) {\n                    return s.replace(/წელი$/, 'წლის წინ');\n                }\n            },\n            s : 'რამდენიმე წამი',\n            m : 'წუთი',\n            mm : '%d წუთი',\n            h : 'საათი',\n            hh : '%d საათი',\n            d : 'დღე',\n            dd : '%d დღე',\n            M : 'თვე',\n            MM : '%d თვე',\n            y : 'წელი',\n            yy : '%d წელი'\n        },\n        ordinalParse: /0|1-ლი|მე-\\d{1,2}|\\d{1,2}-ე/,\n        ordinal : function (number) {\n            if (number === 0) {\n                return number;\n            }\n            if (number === 1) {\n                return number + '-ლი';\n            }\n            if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {\n                return 'მე-' + number;\n            }\n            return number + '-ე';\n        },\n        week : {\n            dow : 1,\n            doy : 7\n        }\n    });\n\n    return ka;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/km.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var km = moment.defineLocale('km', {\n        months: 'មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n        monthsShort: 'មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n        weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n        weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n        weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n        longDateFormat: {\n            LT: 'HH:mm',\n            LTS : 'LT:ss',\n            L: 'DD/MM/YYYY',\n            LL: 'D MMMM YYYY',\n            LLL: 'D MMMM YYYY LT',\n            LLLL: 'dddd, D MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[ថ្ងៃនៈ ម៉ោង] LT',\n            nextDay: '[ស្អែក ម៉ោង] LT',\n            nextWeek: 'dddd [ម៉ោង] LT',\n            lastDay: '[ម្សិលមិញ ម៉ោង] LT',\n            lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',\n            sameElse: 'L'\n        },\n        relativeTime: {\n            future: '%sទៀត',\n            past: '%sមុន',\n            s: 'ប៉ុន្មានវិនាទី',\n            m: 'មួយនាទី',\n            mm: '%d នាទី',\n            h: 'មួយម៉ោង',\n            hh: '%d ម៉ោង',\n            d: 'មួយថ្ងៃ',\n            dd: '%d ថ្ងៃ',\n            M: 'មួយខែ',\n            MM: '%d ខែ',\n            y: 'មួយឆ្នាំ',\n            yy: '%d ឆ្នាំ'\n        },\n        week: {\n            dow: 1, // Monday is the first day of the week.\n            doy: 4 // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return km;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/ko.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var ko = moment.defineLocale('ko', {\n        months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n        monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n        weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),\n        weekdaysShort : '일_월_화_수_목_금_토'.split('_'),\n        weekdaysMin : '일_월_화_수_목_금_토'.split('_'),\n        longDateFormat : {\n            LT : 'A h시 m분',\n            LTS : 'A h시 m분 s초',\n            L : 'YYYY.MM.DD',\n            LL : 'YYYY년 MMMM D일',\n            LLL : 'YYYY년 MMMM D일 LT',\n            LLLL : 'YYYY년 MMMM D일 dddd LT'\n        },\n        calendar : {\n            sameDay : '오늘 LT',\n            nextDay : '내일 LT',\n            nextWeek : 'dddd LT',\n            lastDay : '어제 LT',\n            lastWeek : '지난주 dddd LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s 후',\n            past : '%s 전',\n            s : '몇초',\n            ss : '%d초',\n            m : '일분',\n            mm : '%d분',\n            h : '한시간',\n            hh : '%d시간',\n            d : '하루',\n            dd : '%d일',\n            M : '한달',\n            MM : '%d달',\n            y : '일년',\n            yy : '%d년'\n        },\n        ordinalParse : /\\d{1,2}일/,\n        ordinal : '%d일',\n        meridiemParse : /오전|오후/,\n        isPM : function (token) {\n            return token === '오후';\n        },\n        meridiem : function (hour, minute, isUpper) {\n            return hour < 12 ? '오전' : '오후';\n        }\n    });\n\n    return ko;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/lb.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function processRelativeTime(number, withoutSuffix, key, isFuture) {\n        var format = {\n            'm': ['eng Minutt', 'enger Minutt'],\n            'h': ['eng Stonn', 'enger Stonn'],\n            'd': ['een Dag', 'engem Dag'],\n            'M': ['ee Mount', 'engem Mount'],\n            'y': ['ee Joer', 'engem Joer']\n        };\n        return withoutSuffix ? format[key][0] : format[key][1];\n    }\n    function processFutureTime(string) {\n        var number = string.substr(0, string.indexOf(' '));\n        if (eifelerRegelAppliesToNumber(number)) {\n            return 'a ' + string;\n        }\n        return 'an ' + string;\n    }\n    function processPastTime(string) {\n        var number = string.substr(0, string.indexOf(' '));\n        if (eifelerRegelAppliesToNumber(number)) {\n            return 'viru ' + string;\n        }\n        return 'virun ' + string;\n    }\n        function eifelerRegelAppliesToNumber(number) {\n        number = parseInt(number, 10);\n        if (isNaN(number)) {\n            return false;\n        }\n        if (number < 0) {\n            return true;\n        } else if (number < 10) {\n            if (4 <= number && number <= 7) {\n                return true;\n            }\n            return false;\n        } else if (number < 100) {\n            var lastDigit = number % 10, firstDigit = number / 10;\n            if (lastDigit === 0) {\n                return eifelerRegelAppliesToNumber(firstDigit);\n            }\n            return eifelerRegelAppliesToNumber(lastDigit);\n        } else if (number < 10000) {\n            while (number >= 10) {\n                number = number / 10;\n            }\n            return eifelerRegelAppliesToNumber(number);\n        } else {\n            number = number / 1000;\n            return eifelerRegelAppliesToNumber(number);\n        }\n    }\n\n    var lb = moment.defineLocale('lb', {\n        months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n        monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n        weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'),\n        weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'),\n        weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'),\n        longDateFormat: {\n            LT: 'H:mm [Auer]',\n            LTS: 'H:mm:ss [Auer]',\n            L: 'DD.MM.YYYY',\n            LL: 'D. MMMM YYYY',\n            LLL: 'D. MMMM YYYY LT',\n            LLLL: 'dddd, D. MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[Haut um] LT',\n            sameElse: 'L',\n            nextDay: '[Muer um] LT',\n            nextWeek: 'dddd [um] LT',\n            lastDay: '[Gëschter um] LT',\n            lastWeek: function () {\n                switch (this.day()) {\n                    case 2:\n                    case 4:\n                        return '[Leschten] dddd [um] LT';\n                    default:\n                        return '[Leschte] dddd [um] LT';\n                }\n            }\n        },\n        relativeTime : {\n            future : processFutureTime,\n            past : processPastTime,\n            s : 'e puer Sekonnen',\n            m : processRelativeTime,\n            mm : '%d Minutten',\n            h : processRelativeTime,\n            hh : '%d Stonnen',\n            d : processRelativeTime,\n            dd : '%d Deeg',\n            M : processRelativeTime,\n            MM : '%d Méint',\n            y : processRelativeTime,\n            yy : '%d Joer'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal: '%d.',\n        week: {\n            dow: 1, // Monday is the first day of the week.\n            doy: 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return lb;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/lt.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var units = {\n        'm' : 'minutė_minutės_minutę',\n        'mm': 'minutės_minučių_minutes',\n        'h' : 'valanda_valandos_valandą',\n        'hh': 'valandos_valandų_valandas',\n        'd' : 'diena_dienos_dieną',\n        'dd': 'dienos_dienų_dienas',\n        'M' : 'mėnuo_mėnesio_mėnesį',\n        'MM': 'mėnesiai_mėnesių_mėnesius',\n        'y' : 'metai_metų_metus',\n        'yy': 'metai_metų_metus'\n    },\n    weekDays = 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_');\n    function translateSeconds(number, withoutSuffix, key, isFuture) {\n        if (withoutSuffix) {\n            return 'kelios sekundės';\n        } else {\n            return isFuture ? 'kelių sekundžių' : 'kelias sekundes';\n        }\n    }\n    function translateSingular(number, withoutSuffix, key, isFuture) {\n        return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);\n    }\n    function special(number) {\n        return number % 10 === 0 || (number > 10 && number < 20);\n    }\n    function forms(key) {\n        return units[key].split('_');\n    }\n    function translate(number, withoutSuffix, key, isFuture) {\n        var result = number + ' ';\n        if (number === 1) {\n            return result + translateSingular(number, withoutSuffix, key[0], isFuture);\n        } else if (withoutSuffix) {\n            return result + (special(number) ? forms(key)[1] : forms(key)[0]);\n        } else {\n            if (isFuture) {\n                return result + forms(key)[1];\n            } else {\n                return result + (special(number) ? forms(key)[1] : forms(key)[2]);\n            }\n        }\n    }\n    function relativeWeekDay(moment, format) {\n        var nominative = format.indexOf('dddd HH:mm') === -1,\n            weekDay = weekDays[moment.day()];\n        return nominative ? weekDay : weekDay.substring(0, weekDay.length - 2) + 'į';\n    }\n\n    var lt = moment.defineLocale('lt', {\n        months : 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),\n        monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),\n        weekdays : relativeWeekDay,\n        weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),\n        weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'YYYY [m.] MMMM D [d.]',\n            LLL : 'YYYY [m.] MMMM D [d.], LT [val.]',\n            LLLL : 'YYYY [m.] MMMM D [d.], dddd, LT [val.]',\n            l : 'YYYY-MM-DD',\n            ll : 'YYYY [m.] MMMM D [d.]',\n            lll : 'YYYY [m.] MMMM D [d.], LT [val.]',\n            llll : 'YYYY [m.] MMMM D [d.], ddd, LT [val.]'\n        },\n        calendar : {\n            sameDay : '[Šiandien] LT',\n            nextDay : '[Rytoj] LT',\n            nextWeek : 'dddd LT',\n            lastDay : '[Vakar] LT',\n            lastWeek : '[Praėjusį] dddd LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'po %s',\n            past : 'prieš %s',\n            s : translateSeconds,\n            m : translateSingular,\n            mm : translate,\n            h : translateSingular,\n            hh : translate,\n            d : translateSingular,\n            dd : translate,\n            M : translateSingular,\n            MM : translate,\n            y : translateSingular,\n            yy : translate\n        },\n        ordinalParse: /\\d{1,2}-oji/,\n        ordinal : function (number) {\n            return number + '-oji';\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return lt;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/lv.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var units = {\n        'mm': 'minūti_minūtes_minūte_minūtes',\n        'hh': 'stundu_stundas_stunda_stundas',\n        'dd': 'dienu_dienas_diena_dienas',\n        'MM': 'mēnesi_mēnešus_mēnesis_mēneši',\n        'yy': 'gadu_gadus_gads_gadi'\n    };\n    function format(word, number, withoutSuffix) {\n        var forms = word.split('_');\n        if (withoutSuffix) {\n            return number % 10 === 1 && number !== 11 ? forms[2] : forms[3];\n        } else {\n            return number % 10 === 1 && number !== 11 ? forms[0] : forms[1];\n        }\n    }\n    function relativeTimeWithPlural(number, withoutSuffix, key) {\n        return number + ' ' + format(units[key], number, withoutSuffix);\n    }\n\n    var lv = moment.defineLocale('lv', {\n        months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'),\n        weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'),\n        weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'),\n        weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'YYYY. [gada] D. MMMM',\n            LLL : 'YYYY. [gada] D. MMMM, LT',\n            LLLL : 'YYYY. [gada] D. MMMM, dddd, LT'\n        },\n        calendar : {\n            sameDay : '[Šodien pulksten] LT',\n            nextDay : '[Rīt pulksten] LT',\n            nextWeek : 'dddd [pulksten] LT',\n            lastDay : '[Vakar pulksten] LT',\n            lastWeek : '[Pagājušā] dddd [pulksten] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s vēlāk',\n            past : '%s agrāk',\n            s : 'dažas sekundes',\n            m : 'minūti',\n            mm : relativeTimeWithPlural,\n            h : 'stundu',\n            hh : relativeTimeWithPlural,\n            d : 'dienu',\n            dd : relativeTimeWithPlural,\n            M : 'mēnesi',\n            MM : relativeTimeWithPlural,\n            y : 'gadu',\n            yy : relativeTimeWithPlural\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return lv;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/mk.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var mk = moment.defineLocale('mk', {\n        months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'),\n        monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'),\n        weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'),\n        weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'),\n        weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'D.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Денес во] LT',\n            nextDay : '[Утре во] LT',\n            nextWeek : 'dddd [во] LT',\n            lastDay : '[Вчера во] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[Во изминатата] dddd [во] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[Во изминатиот] dddd [во] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'после %s',\n            past : 'пред %s',\n            s : 'неколку секунди',\n            m : 'минута',\n            mm : '%d минути',\n            h : 'час',\n            hh : '%d часа',\n            d : 'ден',\n            dd : '%d дена',\n            M : 'месец',\n            MM : '%d месеци',\n            y : 'година',\n            yy : '%d години'\n        },\n        ordinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n        ordinal : function (number) {\n            var lastDigit = number % 10,\n                last2Digits = number % 100;\n            if (number === 0) {\n                return number + '-ев';\n            } else if (last2Digits === 0) {\n                return number + '-ен';\n            } else if (last2Digits > 10 && last2Digits < 20) {\n                return number + '-ти';\n            } else if (lastDigit === 1) {\n                return number + '-ви';\n            } else if (lastDigit === 2) {\n                return number + '-ри';\n            } else if (lastDigit === 7 || lastDigit === 8) {\n                return number + '-ми';\n            } else {\n                return number + '-ти';\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return mk;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/ml.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var ml = moment.defineLocale('ml', {\n        months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'),\n        monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'),\n        weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'),\n        weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'),\n        weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm -നു',\n            LTS : 'A h:mm:ss -നു',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        calendar : {\n            sameDay : '[ഇന്ന്] LT',\n            nextDay : '[നാളെ] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[ഇന്നലെ] LT',\n            lastWeek : '[കഴിഞ്ഞ] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s കഴിഞ്ഞ്',\n            past : '%s മുൻപ്',\n            s : 'അൽപ നിമിഷങ്ങൾ',\n            m : 'ഒരു മിനിറ്റ്',\n            mm : '%d മിനിറ്റ്',\n            h : 'ഒരു മണിക്കൂർ',\n            hh : '%d മണിക്കൂർ',\n            d : 'ഒരു ദിവസം',\n            dd : '%d ദിവസം',\n            M : 'ഒരു മാസം',\n            MM : '%d മാസം',\n            y : 'ഒരു വർഷം',\n            yy : '%d വർഷം'\n        },\n        meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,\n        isPM : function (input) {\n            return /^(ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'രാത്രി';\n            } else if (hour < 12) {\n                return 'രാവിലെ';\n            } else if (hour < 17) {\n                return 'ഉച്ച കഴിഞ്ഞ്';\n            } else if (hour < 20) {\n                return 'വൈകുന്നേരം';\n            } else {\n                return 'രാത്രി';\n            }\n        }\n    });\n\n    return ml;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/mr.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var symbolMap = {\n        '1': '१',\n        '2': '२',\n        '3': '३',\n        '4': '४',\n        '5': '५',\n        '6': '६',\n        '7': '७',\n        '8': '८',\n        '9': '९',\n        '0': '०'\n    },\n    numberMap = {\n        '१': '1',\n        '२': '2',\n        '३': '3',\n        '४': '4',\n        '५': '5',\n        '६': '6',\n        '७': '7',\n        '८': '8',\n        '९': '9',\n        '०': '0'\n    };\n\n    var mr = moment.defineLocale('mr', {\n        months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'),\n        monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'),\n        weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n        weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),\n        weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm वाजता',\n            LTS : 'A h:mm:ss वाजता',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        calendar : {\n            sameDay : '[आज] LT',\n            nextDay : '[उद्या] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[काल] LT',\n            lastWeek: '[मागील] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s नंतर',\n            past : '%s पूर्वी',\n            s : 'सेकंद',\n            m: 'एक मिनिट',\n            mm: '%d मिनिटे',\n            h : 'एक तास',\n            hh : '%d तास',\n            d : 'एक दिवस',\n            dd : '%d दिवस',\n            M : 'एक महिना',\n            MM : '%d महिने',\n            y : 'एक वर्ष',\n            yy : '%d वर्षे'\n        },\n        preparse: function (string) {\n            return string.replace(/[१२३४५६७८९०]/g, function (match) {\n                return numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return symbolMap[match];\n            });\n        },\n        meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'रात्री') {\n                return hour < 4 ? hour : hour + 12;\n            } else if (meridiem === 'सकाळी') {\n                return hour;\n            } else if (meridiem === 'दुपारी') {\n                return hour >= 10 ? hour : hour + 12;\n            } else if (meridiem === 'सायंकाळी') {\n                return hour + 12;\n            }\n        },\n        meridiem: function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'रात्री';\n            } else if (hour < 10) {\n                return 'सकाळी';\n            } else if (hour < 17) {\n                return 'दुपारी';\n            } else if (hour < 20) {\n                return 'सायंकाळी';\n            } else {\n                return 'रात्री';\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return mr;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/ms-my.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var ms_my = moment.defineLocale('ms-my', {\n        months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n        monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n        weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n        weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n        weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n        longDateFormat : {\n            LT : 'HH.mm',\n            LTS : 'LT.ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY [pukul] LT',\n            LLLL : 'dddd, D MMMM YYYY [pukul] LT'\n        },\n        meridiemParse: /pagi|tengahari|petang|malam/,\n        meridiemHour: function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'pagi') {\n                return hour;\n            } else if (meridiem === 'tengahari') {\n                return hour >= 11 ? hour : hour + 12;\n            } else if (meridiem === 'petang' || meridiem === 'malam') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours < 11) {\n                return 'pagi';\n            } else if (hours < 15) {\n                return 'tengahari';\n            } else if (hours < 19) {\n                return 'petang';\n            } else {\n                return 'malam';\n            }\n        },\n        calendar : {\n            sameDay : '[Hari ini pukul] LT',\n            nextDay : '[Esok pukul] LT',\n            nextWeek : 'dddd [pukul] LT',\n            lastDay : '[Kelmarin pukul] LT',\n            lastWeek : 'dddd [lepas pukul] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'dalam %s',\n            past : '%s yang lepas',\n            s : 'beberapa saat',\n            m : 'seminit',\n            mm : '%d minit',\n            h : 'sejam',\n            hh : '%d jam',\n            d : 'sehari',\n            dd : '%d hari',\n            M : 'sebulan',\n            MM : '%d bulan',\n            y : 'setahun',\n            yy : '%d tahun'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return ms_my;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/my.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var symbolMap = {\n        '1': '၁',\n        '2': '၂',\n        '3': '၃',\n        '4': '၄',\n        '5': '၅',\n        '6': '၆',\n        '7': '၇',\n        '8': '၈',\n        '9': '၉',\n        '0': '၀'\n    }, numberMap = {\n        '၁': '1',\n        '၂': '2',\n        '၃': '3',\n        '၄': '4',\n        '၅': '5',\n        '၆': '6',\n        '၇': '7',\n        '၈': '8',\n        '၉': '9',\n        '၀': '0'\n    };\n\n    var my = moment.defineLocale('my', {\n        months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'),\n        monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'),\n        weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'),\n        weekdaysShort: 'နွေ_လာ_င်္ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n        weekdaysMin: 'နွေ_လာ_င်္ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n        longDateFormat: {\n            LT: 'HH:mm',\n            LTS: 'HH:mm:ss',\n            L: 'DD/MM/YYYY',\n            LL: 'D MMMM YYYY',\n            LLL: 'D MMMM YYYY LT',\n            LLLL: 'dddd D MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[ယနေ.] LT [မှာ]',\n            nextDay: '[မနက်ဖြန်] LT [မှာ]',\n            nextWeek: 'dddd LT [မှာ]',\n            lastDay: '[မနေ.က] LT [မှာ]',\n            lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]',\n            sameElse: 'L'\n        },\n        relativeTime: {\n            future: 'လာမည့် %s မှာ',\n            past: 'လွန်ခဲ့သော %s က',\n            s: 'စက္ကန်.အနည်းငယ်',\n            m: 'တစ်မိနစ်',\n            mm: '%d မိနစ်',\n            h: 'တစ်နာရီ',\n            hh: '%d နာရီ',\n            d: 'တစ်ရက်',\n            dd: '%d ရက်',\n            M: 'တစ်လ',\n            MM: '%d လ',\n            y: 'တစ်နှစ်',\n            yy: '%d နှစ်'\n        },\n        preparse: function (string) {\n            return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) {\n                return numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return symbolMap[match];\n            });\n        },\n        week: {\n            dow: 1, // Monday is the first day of the week.\n            doy: 4 // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return my;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/nb.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var nb = moment.defineLocale('nb', {\n        months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n        weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n        weekdaysShort : 'søn_man_tirs_ons_tors_fre_lør'.split('_'),\n        weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n        longDateFormat : {\n            LT : 'H.mm',\n            LTS : 'LT.ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY [kl.] LT',\n            LLLL : 'dddd D. MMMM YYYY [kl.] LT'\n        },\n        calendar : {\n            sameDay: '[i dag kl.] LT',\n            nextDay: '[i morgen kl.] LT',\n            nextWeek: 'dddd [kl.] LT',\n            lastDay: '[i går kl.] LT',\n            lastWeek: '[forrige] dddd [kl.] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'om %s',\n            past : 'for %s siden',\n            s : 'noen sekunder',\n            m : 'ett minutt',\n            mm : '%d minutter',\n            h : 'en time',\n            hh : '%d timer',\n            d : 'en dag',\n            dd : '%d dager',\n            M : 'en måned',\n            MM : '%d måneder',\n            y : 'ett år',\n            yy : '%d år'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return nb;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/ne.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var symbolMap = {\n        '1': '१',\n        '2': '२',\n        '3': '३',\n        '4': '४',\n        '5': '५',\n        '6': '६',\n        '7': '७',\n        '8': '८',\n        '9': '९',\n        '0': '०'\n    },\n    numberMap = {\n        '१': '1',\n        '२': '2',\n        '३': '3',\n        '४': '4',\n        '५': '5',\n        '६': '6',\n        '७': '7',\n        '८': '8',\n        '९': '9',\n        '०': '0'\n    };\n\n    var ne = moment.defineLocale('ne', {\n        months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'),\n        monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'),\n        weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'),\n        weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'),\n        weekdaysMin : 'आइ._सो._मङ्_बु._बि._शु._श.'.split('_'),\n        longDateFormat : {\n            LT : 'Aको h:mm बजे',\n            LTS : 'Aको h:mm:ss बजे',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        preparse: function (string) {\n            return string.replace(/[१२३४५६७८९०]/g, function (match) {\n                return numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return symbolMap[match];\n            });\n        },\n        meridiemParse: /राती|बिहान|दिउँसो|बेलुका|साँझ|राती/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'राती') {\n                return hour < 3 ? hour : hour + 12;\n            } else if (meridiem === 'बिहान') {\n                return hour;\n            } else if (meridiem === 'दिउँसो') {\n                return hour >= 10 ? hour : hour + 12;\n            } else if (meridiem === 'बेलुका' || meridiem === 'साँझ') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 3) {\n                return 'राती';\n            } else if (hour < 10) {\n                return 'बिहान';\n            } else if (hour < 15) {\n                return 'दिउँसो';\n            } else if (hour < 18) {\n                return 'बेलुका';\n            } else if (hour < 20) {\n                return 'साँझ';\n            } else {\n                return 'राती';\n            }\n        },\n        calendar : {\n            sameDay : '[आज] LT',\n            nextDay : '[भोली] LT',\n            nextWeek : '[आउँदो] dddd[,] LT',\n            lastDay : '[हिजो] LT',\n            lastWeek : '[गएको] dddd[,] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%sमा',\n            past : '%s अगाडी',\n            s : 'केही समय',\n            m : 'एक मिनेट',\n            mm : '%d मिनेट',\n            h : 'एक घण्टा',\n            hh : '%d घण्टा',\n            d : 'एक दिन',\n            dd : '%d दिन',\n            M : 'एक महिना',\n            MM : '%d महिना',\n            y : 'एक बर्ष',\n            yy : '%d बर्ष'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return ne;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/nl.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n        monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\n    var nl = moment.defineLocale('nl', {\n        months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n        monthsShort : function (m, format) {\n            if (/-MMM-/.test(format)) {\n                return monthsShortWithoutDots[m.month()];\n            } else {\n                return monthsShortWithDots[m.month()];\n            }\n        },\n        weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n        weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n        weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD-MM-YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[vandaag om] LT',\n            nextDay: '[morgen om] LT',\n            nextWeek: 'dddd [om] LT',\n            lastDay: '[gisteren om] LT',\n            lastWeek: '[afgelopen] dddd [om] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'over %s',\n            past : '%s geleden',\n            s : 'een paar seconden',\n            m : 'één minuut',\n            mm : '%d minuten',\n            h : 'één uur',\n            hh : '%d uur',\n            d : 'één dag',\n            dd : '%d dagen',\n            M : 'één maand',\n            MM : '%d maanden',\n            y : 'één jaar',\n            yy : '%d jaar'\n        },\n        ordinalParse: /\\d{1,2}(ste|de)/,\n        ordinal : function (number) {\n            return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return nl;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/nn.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var nn = moment.defineLocale('nn', {\n        months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n        weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'),\n        weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'),\n        weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[I dag klokka] LT',\n            nextDay: '[I morgon klokka] LT',\n            nextWeek: 'dddd [klokka] LT',\n            lastDay: '[I går klokka] LT',\n            lastWeek: '[Føregåande] dddd [klokka] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'om %s',\n            past : 'for %s sidan',\n            s : 'nokre sekund',\n            m : 'eit minutt',\n            mm : '%d minutt',\n            h : 'ein time',\n            hh : '%d timar',\n            d : 'ein dag',\n            dd : '%d dagar',\n            M : 'ein månad',\n            MM : '%d månader',\n            y : 'eit år',\n            yy : '%d år'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return nn;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/pl.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_'),\n        monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_');\n    function plural(n) {\n        return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);\n    }\n    function translate(number, withoutSuffix, key) {\n        var result = number + ' ';\n        switch (key) {\n        case 'm':\n            return withoutSuffix ? 'minuta' : 'minutę';\n        case 'mm':\n            return result + (plural(number) ? 'minuty' : 'minut');\n        case 'h':\n            return withoutSuffix  ? 'godzina'  : 'godzinę';\n        case 'hh':\n            return result + (plural(number) ? 'godziny' : 'godzin');\n        case 'MM':\n            return result + (plural(number) ? 'miesiące' : 'miesięcy');\n        case 'yy':\n            return result + (plural(number) ? 'lata' : 'lat');\n        }\n    }\n\n    var pl = moment.defineLocale('pl', {\n        months : function (momentToFormat, format) {\n            if (/D MMMM/.test(format)) {\n                return monthsSubjective[momentToFormat.month()];\n            } else {\n                return monthsNominative[momentToFormat.month()];\n            }\n        },\n        monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),\n        weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'),\n        weekdaysShort : 'nie_pon_wt_śr_czw_pt_sb'.split('_'),\n        weekdaysMin : 'N_Pn_Wt_Śr_Cz_Pt_So'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Dziś o] LT',\n            nextDay: '[Jutro o] LT',\n            nextWeek: '[W] dddd [o] LT',\n            lastDay: '[Wczoraj o] LT',\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[W zeszłą niedzielę o] LT';\n                case 3:\n                    return '[W zeszłą środę o] LT';\n                case 6:\n                    return '[W zeszłą sobotę o] LT';\n                default:\n                    return '[W zeszły] dddd [o] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past : '%s temu',\n            s : 'kilka sekund',\n            m : translate,\n            mm : translate,\n            h : translate,\n            hh : translate,\n            d : '1 dzień',\n            dd : '%d dni',\n            M : 'miesiąc',\n            MM : translate,\n            y : 'rok',\n            yy : translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return pl;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/pt-br.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var pt_br = moment.defineLocale('pt-br', {\n        months : 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split('_'),\n        monthsShort : 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'),\n        weekdays : 'domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado'.split('_'),\n        weekdaysShort : 'dom_seg_ter_qua_qui_sex_sáb'.split('_'),\n        weekdaysMin : 'dom_2ª_3ª_4ª_5ª_6ª_sáb'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D [de] MMMM [de] YYYY',\n            LLL : 'D [de] MMMM [de] YYYY [às] LT',\n            LLLL : 'dddd, D [de] MMMM [de] YYYY [às] LT'\n        },\n        calendar : {\n            sameDay: '[Hoje às] LT',\n            nextDay: '[Amanhã às] LT',\n            nextWeek: 'dddd [às] LT',\n            lastDay: '[Ontem às] LT',\n            lastWeek: function () {\n                return (this.day() === 0 || this.day() === 6) ?\n                    '[Último] dddd [às] LT' : // Saturday + Sunday\n                    '[Última] dddd [às] LT'; // Monday - Friday\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'em %s',\n            past : '%s atrás',\n            s : 'segundos',\n            m : 'um minuto',\n            mm : '%d minutos',\n            h : 'uma hora',\n            hh : '%d horas',\n            d : 'um dia',\n            dd : '%d dias',\n            M : 'um mês',\n            MM : '%d meses',\n            y : 'um ano',\n            yy : '%d anos'\n        },\n        ordinalParse: /\\d{1,2}º/,\n        ordinal : '%dº'\n    });\n\n    return pt_br;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/pt.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var pt = moment.defineLocale('pt', {\n        months : 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split('_'),\n        monthsShort : 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'),\n        weekdays : 'domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado'.split('_'),\n        weekdaysShort : 'dom_seg_ter_qua_qui_sex_sáb'.split('_'),\n        weekdaysMin : 'dom_2ª_3ª_4ª_5ª_6ª_sáb'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D [de] MMMM [de] YYYY',\n            LLL : 'D [de] MMMM [de] YYYY LT',\n            LLLL : 'dddd, D [de] MMMM [de] YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Hoje às] LT',\n            nextDay: '[Amanhã às] LT',\n            nextWeek: 'dddd [às] LT',\n            lastDay: '[Ontem às] LT',\n            lastWeek: function () {\n                return (this.day() === 0 || this.day() === 6) ?\n                    '[Último] dddd [às] LT' : // Saturday + Sunday\n                    '[Última] dddd [às] LT'; // Monday - Friday\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'em %s',\n            past : 'há %s',\n            s : 'segundos',\n            m : 'um minuto',\n            mm : '%d minutos',\n            h : 'uma hora',\n            hh : '%d horas',\n            d : 'um dia',\n            dd : '%d dias',\n            M : 'um mês',\n            MM : '%d meses',\n            y : 'um ano',\n            yy : '%d anos'\n        },\n        ordinalParse: /\\d{1,2}º/,\n        ordinal : '%dº',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return pt;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/ro.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function relativeTimeWithPlural(number, withoutSuffix, key) {\n        var format = {\n                'mm': 'minute',\n                'hh': 'ore',\n                'dd': 'zile',\n                'MM': 'luni',\n                'yy': 'ani'\n            },\n            separator = ' ';\n        if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {\n            separator = ' de ';\n        }\n        return number + separator + format[key];\n    }\n\n    var ro = moment.defineLocale('ro', {\n        months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'),\n        monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'),\n        weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'),\n        weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'),\n        weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY H:mm',\n            LLLL : 'dddd, D MMMM YYYY H:mm'\n        },\n        calendar : {\n            sameDay: '[azi la] LT',\n            nextDay: '[mâine la] LT',\n            nextWeek: 'dddd [la] LT',\n            lastDay: '[ieri la] LT',\n            lastWeek: '[fosta] dddd [la] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'peste %s',\n            past : '%s în urmă',\n            s : 'câteva secunde',\n            m : 'un minut',\n            mm : relativeTimeWithPlural,\n            h : 'o oră',\n            hh : relativeTimeWithPlural,\n            d : 'o zi',\n            dd : relativeTimeWithPlural,\n            M : 'o lună',\n            MM : relativeTimeWithPlural,\n            y : 'un an',\n            yy : relativeTimeWithPlural\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return ro;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/ru.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function plural(word, num) {\n        var forms = word.split('_');\n        return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n    }\n    function relativeTimeWithPlural(number, withoutSuffix, key) {\n        var format = {\n            'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',\n            'hh': 'час_часа_часов',\n            'dd': 'день_дня_дней',\n            'MM': 'месяц_месяца_месяцев',\n            'yy': 'год_года_лет'\n        };\n        if (key === 'm') {\n            return withoutSuffix ? 'минута' : 'минуту';\n        }\n        else {\n            return number + ' ' + plural(format[key], +number);\n        }\n    }\n    function monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n            'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')\n        },\n        nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function monthsShortCaseReplace(m, format) {\n        var monthsShort = {\n            'nominative': 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),\n            'accusative': 'янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек'.split('_')\n        },\n        nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return monthsShort[nounCase][m.month()];\n    }\n    function weekdaysCaseReplace(m, format) {\n        var weekdays = {\n            'nominative': 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),\n            'accusative': 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_')\n        },\n        nounCase = (/\\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\\] ?dddd/).test(format) ?\n            'accusative' :\n            'nominative';\n        return weekdays[nounCase][m.day()];\n    }\n\n    var ru = moment.defineLocale('ru', {\n        months : monthsCaseReplace,\n        monthsShort : monthsShortCaseReplace,\n        weekdays : weekdaysCaseReplace,\n        weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n        weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n        monthsParse : [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[й|я]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i],\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY г.',\n            LLL : 'D MMMM YYYY г., LT',\n            LLLL : 'dddd, D MMMM YYYY г., LT'\n        },\n        calendar : {\n            sameDay: '[Сегодня в] LT',\n            nextDay: '[Завтра в] LT',\n            lastDay: '[Вчера в] LT',\n            nextWeek: function () {\n                return this.day() === 2 ? '[Во] dddd [в] LT' : '[В] dddd [в] LT';\n            },\n            lastWeek: function (now) {\n                if (now.week() !== this.week()) {\n                    switch (this.day()) {\n                    case 0:\n                        return '[В прошлое] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В прошлый] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В прошлую] dddd [в] LT';\n                    }\n                } else {\n                    if (this.day() === 2) {\n                        return '[Во] dddd [в] LT';\n                    } else {\n                        return '[В] dddd [в] LT';\n                    }\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'через %s',\n            past : '%s назад',\n            s : 'несколько секунд',\n            m : relativeTimeWithPlural,\n            mm : relativeTimeWithPlural,\n            h : 'час',\n            hh : relativeTimeWithPlural,\n            d : 'день',\n            dd : relativeTimeWithPlural,\n            M : 'месяц',\n            MM : relativeTimeWithPlural,\n            y : 'год',\n            yy : relativeTimeWithPlural\n        },\n        meridiemParse: /ночи|утра|дня|вечера/i,\n        isPM : function (input) {\n            return /^(дня|вечера)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'ночи';\n            } else if (hour < 12) {\n                return 'утра';\n            } else if (hour < 17) {\n                return 'дня';\n            } else {\n                return 'вечера';\n            }\n        },\n        ordinalParse: /\\d{1,2}-(й|го|я)/,\n        ordinal: function (number, period) {\n            switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            case 'w':\n            case 'W':\n                return number + '-я';\n            default:\n                return number;\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return ru;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/sk.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_'),\n        monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_');\n    function plural(n) {\n        return (n > 1) && (n < 5);\n    }\n    function translate(number, withoutSuffix, key, isFuture) {\n        var result = number + ' ';\n        switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'minúty' : 'minút');\n            } else {\n                return result + 'minútami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'hodiny' : 'hodín');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'deň' : 'dňom';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'dni' : 'dní');\n            } else {\n                return result + 'dňami';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'mesiace' : 'mesiacov');\n            } else {\n                return result + 'mesiacmi';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokom';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (plural(number) ? 'roky' : 'rokov');\n            } else {\n                return result + 'rokmi';\n            }\n            break;\n        }\n    }\n\n    var sk = moment.defineLocale('sk', {\n        months : months,\n        monthsShort : monthsShort,\n        monthsParse : (function (months, monthsShort) {\n            var i, _monthsParse = [];\n            for (i = 0; i < 12; i++) {\n                _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');\n            }\n            return _monthsParse;\n        }(months, monthsShort)),\n        weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'),\n        weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'),\n        weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),\n        longDateFormat : {\n            LT: 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[dnes o] LT',\n            nextDay: '[zajtra o] LT',\n            nextWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[v nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [o] LT';\n                case 3:\n                    return '[v stredu o] LT';\n                case 4:\n                    return '[vo štvrtok o] LT';\n                case 5:\n                    return '[v piatok o] LT';\n                case 6:\n                    return '[v sobotu o] LT';\n                }\n            },\n            lastDay: '[včera o] LT',\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[minulú nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[minulý] dddd [o] LT';\n                case 3:\n                    return '[minulú stredu o] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [o] LT';\n                case 6:\n                    return '[minulú sobotu o] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past : 'pred %s',\n            s : translate,\n            m : translate,\n            mm : translate,\n            h : translate,\n            hh : translate,\n            d : translate,\n            dd : translate,\n            M : translate,\n            MM : translate,\n            y : translate,\n            yy : translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return sk;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/sl.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function translate(number, withoutSuffix, key) {\n        var result = number + ' ';\n        switch (key) {\n        case 'm':\n            return withoutSuffix ? 'ena minuta' : 'eno minuto';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2) {\n                result += 'minuti';\n            } else if (number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minut';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'ena ura' : 'eno uro';\n        case 'hh':\n            if (number === 1) {\n                result += 'ura';\n            } else if (number === 2) {\n                result += 'uri';\n            } else if (number === 3 || number === 4) {\n                result += 'ure';\n            } else {\n                result += 'ur';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dni';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mesec';\n            } else if (number === 2) {\n                result += 'meseca';\n            } else if (number === 3 || number === 4) {\n                result += 'mesece';\n            } else {\n                result += 'mesecev';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'leto';\n            } else if (number === 2) {\n                result += 'leti';\n            } else if (number === 3 || number === 4) {\n                result += 'leta';\n            } else {\n                result += 'let';\n            }\n            return result;\n        }\n    }\n\n    var sl = moment.defineLocale('sl', {\n        months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'),\n        monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'),\n        weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'),\n        weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'),\n        weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD. MM. YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd, D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay  : '[danes ob] LT',\n            nextDay  : '[jutri ob] LT',\n            nextWeek : function () {\n                switch (this.day()) {\n                case 0:\n                    return '[v] [nedeljo] [ob] LT';\n                case 3:\n                    return '[v] [sredo] [ob] LT';\n                case 6:\n                    return '[v] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[v] dddd [ob] LT';\n                }\n            },\n            lastDay  : '[včeraj ob] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[prejšnja] dddd [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prejšnji] dddd [ob] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'čez %s',\n            past   : '%s nazaj',\n            s      : 'nekaj sekund',\n            m      : translate,\n            mm     : translate,\n            h      : translate,\n            hh     : translate,\n            d      : 'en dan',\n            dd     : translate,\n            M      : 'en mesec',\n            MM     : translate,\n            y      : 'eno leto',\n            yy     : translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return sl;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/sq.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var sq = moment.defineLocale('sq', {\n        months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'),\n        monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'),\n        weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'),\n        weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'),\n        weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'),\n        meridiemParse: /PD|MD/,\n        isPM: function (input) {\n            return input.charAt(0) === 'M';\n        },\n        meridiem : function (hours, minutes, isLower) {\n            return hours < 12 ? 'PD' : 'MD';\n        },\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Sot në] LT',\n            nextDay : '[Nesër në] LT',\n            nextWeek : 'dddd [në] LT',\n            lastDay : '[Dje në] LT',\n            lastWeek : 'dddd [e kaluar në] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'në %s',\n            past : '%s më parë',\n            s : 'disa sekonda',\n            m : 'një minutë',\n            mm : '%d minuta',\n            h : 'një orë',\n            hh : '%d orë',\n            d : 'një ditë',\n            dd : '%d ditë',\n            M : 'një muaj',\n            MM : '%d muaj',\n            y : 'një vit',\n            yy : '%d vite'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return sq;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/sr-cyrl.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var translator = {\n        words: { //Different grammatical cases\n            m: ['један минут', 'једне минуте'],\n            mm: ['минут', 'минуте', 'минута'],\n            h: ['један сат', 'једног сата'],\n            hh: ['сат', 'сата', 'сати'],\n            dd: ['дан', 'дана', 'дана'],\n            MM: ['месец', 'месеца', 'месеци'],\n            yy: ['година', 'године', 'година']\n        },\n        correctGrammaticalCase: function (number, wordKey) {\n            return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n        },\n        translate: function (number, withoutSuffix, key) {\n            var wordKey = translator.words[key];\n            if (key.length === 1) {\n                return withoutSuffix ? wordKey[0] : wordKey[1];\n            } else {\n                return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n            }\n        }\n    };\n\n    var sr_cyrl = moment.defineLocale('sr-cyrl', {\n        months: ['јануар', 'фебруар', 'март', 'април', 'мај', 'јун', 'јул', 'август', 'септембар', 'октобар', 'новембар', 'децембар'],\n        monthsShort: ['јан.', 'феб.', 'мар.', 'апр.', 'мај', 'јун', 'јул', 'авг.', 'сеп.', 'окт.', 'нов.', 'дец.'],\n        weekdays: ['недеља', 'понедељак', 'уторак', 'среда', 'четвртак', 'петак', 'субота'],\n        weekdaysShort: ['нед.', 'пон.', 'уто.', 'сре.', 'чет.', 'пет.', 'суб.'],\n        weekdaysMin: ['не', 'по', 'ут', 'ср', 'че', 'пе', 'су'],\n        longDateFormat: {\n            LT: 'H:mm',\n            LTS : 'LT:ss',\n            L: 'DD. MM. YYYY',\n            LL: 'D. MMMM YYYY',\n            LLL: 'D. MMMM YYYY LT',\n            LLLL: 'dddd, D. MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[данас у] LT',\n            nextDay: '[сутра у] LT',\n            nextWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[у] [недељу] [у] LT';\n                case 3:\n                    return '[у] [среду] [у] LT';\n                case 6:\n                    return '[у] [суботу] [у] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[у] dddd [у] LT';\n                }\n            },\n            lastDay  : '[јуче у] LT',\n            lastWeek : function () {\n                var lastWeekDays = [\n                    '[прошле] [недеље] [у] LT',\n                    '[прошлог] [понедељка] [у] LT',\n                    '[прошлог] [уторка] [у] LT',\n                    '[прошле] [среде] [у] LT',\n                    '[прошлог] [четвртка] [у] LT',\n                    '[прошлог] [петка] [у] LT',\n                    '[прошле] [суботе] [у] LT'\n                ];\n                return lastWeekDays[this.day()];\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'за %s',\n            past   : 'пре %s',\n            s      : 'неколико секунди',\n            m      : translator.translate,\n            mm     : translator.translate,\n            h      : translator.translate,\n            hh     : translator.translate,\n            d      : 'дан',\n            dd     : translator.translate,\n            M      : 'месец',\n            MM     : translator.translate,\n            y      : 'годину',\n            yy     : translator.translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return sr_cyrl;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/sr.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var translator = {\n        words: { //Different grammatical cases\n            m: ['jedan minut', 'jedne minute'],\n            mm: ['minut', 'minute', 'minuta'],\n            h: ['jedan sat', 'jednog sata'],\n            hh: ['sat', 'sata', 'sati'],\n            dd: ['dan', 'dana', 'dana'],\n            MM: ['mesec', 'meseca', 'meseci'],\n            yy: ['godina', 'godine', 'godina']\n        },\n        correctGrammaticalCase: function (number, wordKey) {\n            return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n        },\n        translate: function (number, withoutSuffix, key) {\n            var wordKey = translator.words[key];\n            if (key.length === 1) {\n                return withoutSuffix ? wordKey[0] : wordKey[1];\n            } else {\n                return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n            }\n        }\n    };\n\n    var sr = moment.defineLocale('sr', {\n        months: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'],\n        monthsShort: ['jan.', 'feb.', 'mar.', 'apr.', 'maj', 'jun', 'jul', 'avg.', 'sep.', 'okt.', 'nov.', 'dec.'],\n        weekdays: ['nedelja', 'ponedeljak', 'utorak', 'sreda', 'četvrtak', 'petak', 'subota'],\n        weekdaysShort: ['ned.', 'pon.', 'uto.', 'sre.', 'čet.', 'pet.', 'sub.'],\n        weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],\n        longDateFormat: {\n            LT: 'H:mm',\n            LTS : 'LT:ss',\n            L: 'DD. MM. YYYY',\n            LL: 'D. MMMM YYYY',\n            LLL: 'D. MMMM YYYY LT',\n            LLLL: 'dddd, D. MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[danas u] LT',\n            nextDay: '[sutra u] LT',\n            nextWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[u] [nedelju] [u] LT';\n                case 3:\n                    return '[u] [sredu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n                }\n            },\n            lastDay  : '[juče u] LT',\n            lastWeek : function () {\n                var lastWeekDays = [\n                    '[prošle] [nedelje] [u] LT',\n                    '[prošlog] [ponedeljka] [u] LT',\n                    '[prošlog] [utorka] [u] LT',\n                    '[prošle] [srede] [u] LT',\n                    '[prošlog] [četvrtka] [u] LT',\n                    '[prošlog] [petka] [u] LT',\n                    '[prošle] [subote] [u] LT'\n                ];\n                return lastWeekDays[this.day()];\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past   : 'pre %s',\n            s      : 'nekoliko sekundi',\n            m      : translator.translate,\n            mm     : translator.translate,\n            h      : translator.translate,\n            hh     : translator.translate,\n            d      : 'dan',\n            dd     : translator.translate,\n            M      : 'mesec',\n            MM     : translator.translate,\n            y      : 'godinu',\n            yy     : translator.translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return sr;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/sv.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var sv = moment.defineLocale('sv', {\n        months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n        weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),\n        weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'),\n        weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Idag] LT',\n            nextDay: '[Imorgon] LT',\n            lastDay: '[Igår] LT',\n            nextWeek: 'dddd LT',\n            lastWeek: '[Förra] dddd[en] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'om %s',\n            past : 'för %s sedan',\n            s : 'några sekunder',\n            m : 'en minut',\n            mm : '%d minuter',\n            h : 'en timme',\n            hh : '%d timmar',\n            d : 'en dag',\n            dd : '%d dagar',\n            M : 'en månad',\n            MM : '%d månader',\n            y : 'ett år',\n            yy : '%d år'\n        },\n        ordinalParse: /\\d{1,2}(e|a)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (~~(number % 100 / 10) === 1) ? 'e' :\n                (b === 1) ? 'a' :\n                (b === 2) ? 'a' :\n                (b === 3) ? 'e' : 'e';\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return sv;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/ta.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var ta = moment.defineLocale('ta', {\n        months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n        monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n        weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'),\n        weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'),\n        weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        calendar : {\n            sameDay : '[இன்று] LT',\n            nextDay : '[நாளை] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[நேற்று] LT',\n            lastWeek : '[கடந்த வாரம்] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s இல்',\n            past : '%s முன்',\n            s : 'ஒரு சில விநாடிகள்',\n            m : 'ஒரு நிமிடம்',\n            mm : '%d நிமிடங்கள்',\n            h : 'ஒரு மணி நேரம்',\n            hh : '%d மணி நேரம்',\n            d : 'ஒரு நாள்',\n            dd : '%d நாட்கள்',\n            M : 'ஒரு மாதம்',\n            MM : '%d மாதங்கள்',\n            y : 'ஒரு வருடம்',\n            yy : '%d ஆண்டுகள்'\n        },\n        ordinalParse: /\\d{1,2}வது/,\n        ordinal : function (number) {\n            return number + 'வது';\n        },\n        meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 2) {\n                return ' யாமம்';\n            } else if (hour < 6) {\n                return ' வைகறை';  // வைகறை\n            } else if (hour < 10) {\n                return ' காலை'; // காலை\n            } else if (hour < 14) {\n                return ' நண்பகல்'; // நண்பகல்\n            } else if (hour < 18) {\n                return ' எற்பாடு'; // எற்பாடு\n            } else if (hour < 22) {\n                return ' மாலை'; // மாலை\n            } else {\n                return ' யாமம்';\n            }\n        },\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'யாமம்') {\n                return hour < 2 ? hour : hour + 12;\n            } else if (meridiem === 'வைகறை' || meridiem === 'காலை') {\n                return hour;\n            } else if (meridiem === 'நண்பகல்') {\n                return hour >= 10 ? hour : hour + 12;\n            } else {\n                return hour + 12;\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return ta;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/th.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var th = moment.defineLocale('th', {\n        months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'),\n        monthsShort : 'มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา'.split('_'),\n        weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'),\n        weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference\n        weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),\n        longDateFormat : {\n            LT : 'H นาฬิกา m นาที',\n            LTS : 'LT s วินาที',\n            L : 'YYYY/MM/DD',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY เวลา LT',\n            LLLL : 'วันddddที่ D MMMM YYYY เวลา LT'\n        },\n        meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,\n        isPM: function (input) {\n            return input === 'หลังเที่ยง';\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return 'ก่อนเที่ยง';\n            } else {\n                return 'หลังเที่ยง';\n            }\n        },\n        calendar : {\n            sameDay : '[วันนี้ เวลา] LT',\n            nextDay : '[พรุ่งนี้ เวลา] LT',\n            nextWeek : 'dddd[หน้า เวลา] LT',\n            lastDay : '[เมื่อวานนี้ เวลา] LT',\n            lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'อีก %s',\n            past : '%sที่แล้ว',\n            s : 'ไม่กี่วินาที',\n            m : '1 นาที',\n            mm : '%d นาที',\n            h : '1 ชั่วโมง',\n            hh : '%d ชั่วโมง',\n            d : '1 วัน',\n            dd : '%d วัน',\n            M : '1 เดือน',\n            MM : '%d เดือน',\n            y : '1 ปี',\n            yy : '%d ปี'\n        }\n    });\n\n    return th;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/tl-ph.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var tl_ph = moment.defineLocale('tl-ph', {\n        months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'),\n        monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),\n        weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'),\n        weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),\n        weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'MM/D/YYYY',\n            LL : 'MMMM D, YYYY',\n            LLL : 'MMMM D, YYYY LT',\n            LLLL : 'dddd, MMMM DD, YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Ngayon sa] LT',\n            nextDay: '[Bukas sa] LT',\n            nextWeek: 'dddd [sa] LT',\n            lastDay: '[Kahapon sa] LT',\n            lastWeek: 'dddd [huling linggo] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'sa loob ng %s',\n            past : '%s ang nakalipas',\n            s : 'ilang segundo',\n            m : 'isang minuto',\n            mm : '%d minuto',\n            h : 'isang oras',\n            hh : '%d oras',\n            d : 'isang araw',\n            dd : '%d araw',\n            M : 'isang buwan',\n            MM : '%d buwan',\n            y : 'isang taon',\n            yy : '%d taon'\n        },\n        ordinalParse: /\\d{1,2}/,\n        ordinal : function (number) {\n            return number;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return tl_ph;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/tr.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var suffixes = {\n        1: '\\'inci',\n        5: '\\'inci',\n        8: '\\'inci',\n        70: '\\'inci',\n        80: '\\'inci',\n        2: '\\'nci',\n        7: '\\'nci',\n        20: '\\'nci',\n        50: '\\'nci',\n        3: '\\'üncü',\n        4: '\\'üncü',\n        100: '\\'üncü',\n        6: '\\'ncı',\n        9: '\\'uncu',\n        10: '\\'uncu',\n        30: '\\'uncu',\n        60: '\\'ıncı',\n        90: '\\'ıncı'\n    };\n\n    var tr = moment.defineLocale('tr', {\n        months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),\n        monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),\n        weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),\n        weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),\n        weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[bugün saat] LT',\n            nextDay : '[yarın saat] LT',\n            nextWeek : '[haftaya] dddd [saat] LT',\n            lastDay : '[dün] LT',\n            lastWeek : '[geçen hafta] dddd [saat] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s sonra',\n            past : '%s önce',\n            s : 'birkaç saniye',\n            m : 'bir dakika',\n            mm : '%d dakika',\n            h : 'bir saat',\n            hh : '%d saat',\n            d : 'bir gün',\n            dd : '%d gün',\n            M : 'bir ay',\n            MM : '%d ay',\n            y : 'bir yıl',\n            yy : '%d yıl'\n        },\n        ordinalParse: /\\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,\n        ordinal : function (number) {\n            if (number === 0) {  // special case for zero\n                return number + '\\'ıncı';\n            }\n            var a = number % 10,\n                b = number % 100 - a,\n                c = number >= 100 ? 100 : null;\n            return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return tr;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/tzm-latn.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var tzm_latn = moment.defineLocale('tzm-latn', {\n        months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n        monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n        weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n        weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n        weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[asdkh g] LT',\n            nextDay: '[aska g] LT',\n            nextWeek: 'dddd [g] LT',\n            lastDay: '[assant g] LT',\n            lastWeek: 'dddd [g] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'dadkh s yan %s',\n            past : 'yan %s',\n            s : 'imik',\n            m : 'minuḍ',\n            mm : '%d minuḍ',\n            h : 'saɛa',\n            hh : '%d tassaɛin',\n            d : 'ass',\n            dd : '%d ossan',\n            M : 'ayowr',\n            MM : '%d iyyirn',\n            y : 'asgas',\n            yy : '%d isgasn'\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return tzm_latn;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/tzm.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var tzm = moment.defineLocale('tzm', {\n        months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n        monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n        weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n        weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n        weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS: 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',\n            nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',\n            nextWeek: 'dddd [ⴴ] LT',\n            lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',\n            lastWeek: 'dddd [ⴴ] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s',\n            past : 'ⵢⴰⵏ %s',\n            s : 'ⵉⵎⵉⴽ',\n            m : 'ⵎⵉⵏⵓⴺ',\n            mm : '%d ⵎⵉⵏⵓⴺ',\n            h : 'ⵙⴰⵄⴰ',\n            hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ',\n            d : 'ⴰⵙⵙ',\n            dd : '%d oⵙⵙⴰⵏ',\n            M : 'ⴰⵢoⵓⵔ',\n            MM : '%d ⵉⵢⵢⵉⵔⵏ',\n            y : 'ⴰⵙⴳⴰⵙ',\n            yy : '%d ⵉⵙⴳⴰⵙⵏ'\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return tzm;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/uk.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    function plural(word, num) {\n        var forms = word.split('_');\n        return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n    }\n    function relativeTimeWithPlural(number, withoutSuffix, key) {\n        var format = {\n            'mm': 'хвилина_хвилини_хвилин',\n            'hh': 'година_години_годин',\n            'dd': 'день_дні_днів',\n            'MM': 'місяць_місяці_місяців',\n            'yy': 'рік_роки_років'\n        };\n        if (key === 'm') {\n            return withoutSuffix ? 'хвилина' : 'хвилину';\n        }\n        else if (key === 'h') {\n            return withoutSuffix ? 'година' : 'годину';\n        }\n        else {\n            return number + ' ' + plural(format[key], +number);\n        }\n    }\n    function monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_'),\n            'accusative': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_')\n        },\n        nounCase = (/D[oD]? *MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function weekdaysCaseReplace(m, format) {\n        var weekdays = {\n            'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),\n            'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),\n            'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')\n        },\n        nounCase = (/(\\[[ВвУу]\\]) ?dddd/).test(format) ?\n            'accusative' :\n            ((/\\[?(?:минулої|наступної)? ?\\] ?dddd/).test(format) ?\n                'genitive' :\n                'nominative');\n        return weekdays[nounCase][m.day()];\n    }\n    function processHoursFunction(str) {\n        return function () {\n            return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';\n        };\n    }\n\n    var uk = moment.defineLocale('uk', {\n        months : monthsCaseReplace,\n        monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),\n        weekdays : weekdaysCaseReplace,\n        weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n        weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY р.',\n            LLL : 'D MMMM YYYY р., LT',\n            LLLL : 'dddd, D MMMM YYYY р., LT'\n        },\n        calendar : {\n            sameDay: processHoursFunction('[Сьогодні '),\n            nextDay: processHoursFunction('[Завтра '),\n            lastDay: processHoursFunction('[Вчора '),\n            nextWeek: processHoursFunction('[У] dddd ['),\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return processHoursFunction('[Минулої] dddd [').call(this);\n                case 1:\n                case 2:\n                case 4:\n                    return processHoursFunction('[Минулого] dddd [').call(this);\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'за %s',\n            past : '%s тому',\n            s : 'декілька секунд',\n            m : relativeTimeWithPlural,\n            mm : relativeTimeWithPlural,\n            h : 'годину',\n            hh : relativeTimeWithPlural,\n            d : 'день',\n            dd : relativeTimeWithPlural,\n            M : 'місяць',\n            MM : relativeTimeWithPlural,\n            y : 'рік',\n            yy : relativeTimeWithPlural\n        },\n        meridiemParse: /ночі|ранку|дня|вечора/,\n        isPM: function (input) {\n            return /^(дня|вечора)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'ночі';\n            } else if (hour < 12) {\n                return 'ранку';\n            } else if (hour < 17) {\n                return 'дня';\n            } else {\n                return 'вечора';\n            }\n        },\n        ordinalParse: /\\d{1,2}-(й|го)/,\n        ordinal: function (number, period) {\n            switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            default:\n                return number;\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    return uk;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/uz.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var uz = moment.defineLocale('uz', {\n        months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n        monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),\n        weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'),\n        weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'),\n        weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'D MMMM YYYY, dddd LT'\n        },\n        calendar : {\n            sameDay : '[Бугун соат] LT [да]',\n            nextDay : '[Эртага] LT [да]',\n            nextWeek : 'dddd [куни соат] LT [да]',\n            lastDay : '[Кеча соат] LT [да]',\n            lastWeek : '[Утган] dddd [куни соат] LT [да]',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'Якин %s ичида',\n            past : 'Бир неча %s олдин',\n            s : 'фурсат',\n            m : 'бир дакика',\n            mm : '%d дакика',\n            h : 'бир соат',\n            hh : '%d соат',\n            d : 'бир кун',\n            dd : '%d кун',\n            M : 'бир ой',\n            MM : '%d ой',\n            y : 'бир йил',\n            yy : '%d йил'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return uz;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/vi.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var vi = moment.defineLocale('vi', {\n        months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'),\n        monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'),\n        weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'),\n        weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n        weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM [năm] YYYY',\n            LLL : 'D MMMM [năm] YYYY LT',\n            LLLL : 'dddd, D MMMM [năm] YYYY LT',\n            l : 'DD/M/YYYY',\n            ll : 'D MMM YYYY',\n            lll : 'D MMM YYYY LT',\n            llll : 'ddd, D MMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Hôm nay lúc] LT',\n            nextDay: '[Ngày mai lúc] LT',\n            nextWeek: 'dddd [tuần tới lúc] LT',\n            lastDay: '[Hôm qua lúc] LT',\n            lastWeek: 'dddd [tuần rồi lúc] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : '%s tới',\n            past : '%s trước',\n            s : 'vài giây',\n            m : 'một phút',\n            mm : '%d phút',\n            h : 'một giờ',\n            hh : '%d giờ',\n            d : 'một ngày',\n            dd : '%d ngày',\n            M : 'một tháng',\n            MM : '%d tháng',\n            y : 'một năm',\n            yy : '%d năm'\n        },\n        ordinalParse: /\\d{1,2}/,\n        ordinal : function (number) {\n            return number;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return vi;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/zh-cn.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var zh_cn = moment.defineLocale('zh-cn', {\n        months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n        monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n        weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n        weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'),\n        weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n        longDateFormat : {\n            LT : 'Ah点mm',\n            LTS : 'Ah点m分s秒',\n            L : 'YYYY-MM-DD',\n            LL : 'YYYY年MMMD日',\n            LLL : 'YYYY年MMMD日LT',\n            LLLL : 'YYYY年MMMD日ddddLT',\n            l : 'YYYY-MM-DD',\n            ll : 'YYYY年MMMD日',\n            lll : 'YYYY年MMMD日LT',\n            llll : 'YYYY年MMMD日ddddLT'\n        },\n        meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n        meridiemHour: function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === '凌晨' || meridiem === '早上' ||\n                    meridiem === '上午') {\n                return hour;\n            } else if (meridiem === '下午' || meridiem === '晚上') {\n                return hour + 12;\n            } else {\n                return hour >= 11 ? hour : hour + 12;\n            }\n        },\n        meridiem : function (hour, minute, isLower) {\n            var hm = hour * 100 + minute;\n            if (hm < 600) {\n                return '凌晨';\n            } else if (hm < 900) {\n                return '早上';\n            } else if (hm < 1130) {\n                return '上午';\n            } else if (hm < 1230) {\n                return '中午';\n            } else if (hm < 1800) {\n                return '下午';\n            } else {\n                return '晚上';\n            }\n        },\n        calendar : {\n            sameDay : function () {\n                return this.minutes() === 0 ? '[今天]Ah[点整]' : '[今天]LT';\n            },\n            nextDay : function () {\n                return this.minutes() === 0 ? '[明天]Ah[点整]' : '[明天]LT';\n            },\n            lastDay : function () {\n                return this.minutes() === 0 ? '[昨天]Ah[点整]' : '[昨天]LT';\n            },\n            nextWeek : function () {\n                var startOfWeek, prefix;\n                startOfWeek = moment().startOf('week');\n                prefix = this.unix() - startOfWeek.unix() >= 7 * 24 * 3600 ? '[下]' : '[本]';\n                return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';\n            },\n            lastWeek : function () {\n                var startOfWeek, prefix;\n                startOfWeek = moment().startOf('week');\n                prefix = this.unix() < startOfWeek.unix()  ? '[上]' : '[本]';\n                return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';\n            },\n            sameElse : 'LL'\n        },\n        ordinalParse: /\\d{1,2}(日|月|周)/,\n        ordinal : function (number, period) {\n            switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            case 'M':\n                return number + '月';\n            case 'w':\n            case 'W':\n                return number + '周';\n            default:\n                return number;\n            }\n        },\n        relativeTime : {\n            future : '%s内',\n            past : '%s前',\n            s : '几秒',\n            m : '1分钟',\n            mm : '%d分钟',\n            h : '1小时',\n            hh : '%d小时',\n            d : '1天',\n            dd : '%d天',\n            M : '1个月',\n            MM : '%d个月',\n            y : '1年',\n            yy : '%d年'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    return zh_cn;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/locale/zh-tw.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n\n    var zh_tw = moment.defineLocale('zh-tw', {\n        months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n        monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n        weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n        weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n        weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n        longDateFormat : {\n            LT : 'Ah點mm',\n            LTS : 'Ah點m分s秒',\n            L : 'YYYY年MMMD日',\n            LL : 'YYYY年MMMD日',\n            LLL : 'YYYY年MMMD日LT',\n            LLLL : 'YYYY年MMMD日ddddLT',\n            l : 'YYYY年MMMD日',\n            ll : 'YYYY年MMMD日',\n            lll : 'YYYY年MMMD日LT',\n            llll : 'YYYY年MMMD日ddddLT'\n        },\n        meridiemParse: /早上|上午|中午|下午|晚上/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === '早上' || meridiem === '上午') {\n                return hour;\n            } else if (meridiem === '中午') {\n                return hour >= 11 ? hour : hour + 12;\n            } else if (meridiem === '下午' || meridiem === '晚上') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hour, minute, isLower) {\n            var hm = hour * 100 + minute;\n            if (hm < 900) {\n                return '早上';\n            } else if (hm < 1130) {\n                return '上午';\n            } else if (hm < 1230) {\n                return '中午';\n            } else if (hm < 1800) {\n                return '下午';\n            } else {\n                return '晚上';\n            }\n        },\n        calendar : {\n            sameDay : '[今天]LT',\n            nextDay : '[明天]LT',\n            nextWeek : '[下]ddddLT',\n            lastDay : '[昨天]LT',\n            lastWeek : '[上]ddddLT',\n            sameElse : 'L'\n        },\n        ordinalParse: /\\d{1,2}(日|月|週)/,\n        ordinal : function (number, period) {\n            switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n            }\n        },\n        relativeTime : {\n            future : '%s內',\n            past : '%s前',\n            s : '幾秒',\n            m : '一分鐘',\n            mm : '%d分鐘',\n            h : '一小時',\n            hh : '%d小時',\n            d : '一天',\n            dd : '%d天',\n            M : '一個月',\n            MM : '%d個月',\n            y : '一年',\n            yy : '%d年'\n        }\n    });\n\n    return zh_tw;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/meteor/README.md",
    "content": "Packaging [Moment](momentjs.org) for [Meteor.js](http://meteor.com).\n\n\n# Meteor\n\nIf you're new to Meteor, here's what the excitement is all about -\n[watch the first two minutes](https://www.youtube.com/watch?v=fsi0aJ9yr2o); you'll be hooked by 1:28.\n\nThat screencast is from 2012. In the meantime, Meteor has become a mature JavaScript-everywhere web\ndevelopment framework. Read more at [Why Meteor](http://www.meteorpedia.com/read/Why_Meteor).\n\n\n# Issues\n\nIf you encounter an issue while using this package, please CC @dandv when you file it in this repo.\n\n\n# DONE\n\n* Simple test. Should be enough.\n\n\n# TODO\n\n* Add other tests; however, that is overkill, and the responsibiity of Moment, not of the Meteor integration.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/meteor/export.js",
    "content": "moment = this.moment;\ndelete this.moment;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/meteor/test.js",
    "content": "'use strict';\n\nTinytest.add('Moment.is', function (test) {\n  test.ok(moment.isMoment(moment()), {message: 'simple moment object'});\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/min/locales.js",
    "content": "(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    var af = moment.defineLocale('af', {\n        months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),\n        weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'),\n        weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),\n        weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),\n        meridiemParse: /vm|nm/i,\n        isPM : function (input) {\n            return /^nm$/i.test(input);\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours < 12) {\n                return isLower ? 'vm' : 'VM';\n            } else {\n                return isLower ? 'nm' : 'NM';\n            }\n        },\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Vandag om] LT',\n            nextDay : '[Môre om] LT',\n            nextWeek : 'dddd [om] LT',\n            lastDay : '[Gister om] LT',\n            lastWeek : '[Laas] dddd [om] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'oor %s',\n            past : '%s gelede',\n            s : '\\'n paar sekondes',\n            m : '\\'n minuut',\n            mm : '%d minute',\n            h : '\\'n uur',\n            hh : '%d ure',\n            d : '\\'n dag',\n            dd : '%d dae',\n            M : '\\'n maand',\n            MM : '%d maande',\n            y : '\\'n jaar',\n            yy : '%d jaar'\n        },\n        ordinalParse: /\\d{1,2}(ste|de)/,\n        ordinal : function (number) {\n            return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter\n        },\n        week : {\n            dow : 1, // Maandag is die eerste dag van die week.\n            doy : 4  // Die week wat die 4de Januarie bevat is die eerste week van die jaar.\n        }\n    });\n\n    var ar_ma = moment.defineLocale('ar-ma', {\n        months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n        monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n        weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n        weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n        weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[اليوم على الساعة] LT',\n            nextDay: '[غدا على الساعة] LT',\n            nextWeek: 'dddd [على الساعة] LT',\n            lastDay: '[أمس على الساعة] LT',\n            lastWeek: 'dddd [على الساعة] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'في %s',\n            past : 'منذ %s',\n            s : 'ثوان',\n            m : 'دقيقة',\n            mm : '%d دقائق',\n            h : 'ساعة',\n            hh : '%d ساعات',\n            d : 'يوم',\n            dd : '%d أيام',\n            M : 'شهر',\n            MM : '%d أشهر',\n            y : 'سنة',\n            yy : '%d سنوات'\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var ar_sa__symbolMap = {\n        '1': '١',\n        '2': '٢',\n        '3': '٣',\n        '4': '٤',\n        '5': '٥',\n        '6': '٦',\n        '7': '٧',\n        '8': '٨',\n        '9': '٩',\n        '0': '٠'\n    }, ar_sa__numberMap = {\n        '١': '1',\n        '٢': '2',\n        '٣': '3',\n        '٤': '4',\n        '٥': '5',\n        '٦': '6',\n        '٧': '7',\n        '٨': '8',\n        '٩': '9',\n        '٠': '0'\n    };\n\n    var ar_sa = moment.defineLocale('ar-sa', {\n        months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n        monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n        weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n        weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n        weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        meridiemParse: /ص|م/,\n        isPM : function (input) {\n            return 'م' === input;\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return 'ص';\n            } else {\n                return 'م';\n            }\n        },\n        calendar : {\n            sameDay: '[اليوم على الساعة] LT',\n            nextDay: '[غدا على الساعة] LT',\n            nextWeek: 'dddd [على الساعة] LT',\n            lastDay: '[أمس على الساعة] LT',\n            lastWeek: 'dddd [على الساعة] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'في %s',\n            past : 'منذ %s',\n            s : 'ثوان',\n            m : 'دقيقة',\n            mm : '%d دقائق',\n            h : 'ساعة',\n            hh : '%d ساعات',\n            d : 'يوم',\n            dd : '%d أيام',\n            M : 'شهر',\n            MM : '%d أشهر',\n            y : 'سنة',\n            yy : '%d سنوات'\n        },\n        preparse: function (string) {\n            return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n                return ar_sa__numberMap[match];\n            }).replace(/،/g, ',');\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return ar_sa__symbolMap[match];\n            }).replace(/,/g, '،');\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var ar_tn = moment.defineLocale('ar-tn', {\n        months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n        monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n        weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n        weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n        weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n        longDateFormat: {\n            LT: 'HH:mm',\n            LTS: 'LT:ss',\n            L: 'DD/MM/YYYY',\n            LL: 'D MMMM YYYY',\n            LLL: 'D MMMM YYYY LT',\n            LLLL: 'dddd D MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[اليوم على الساعة] LT',\n            nextDay: '[غدا على الساعة] LT',\n            nextWeek: 'dddd [على الساعة] LT',\n            lastDay: '[أمس على الساعة] LT',\n            lastWeek: 'dddd [على الساعة] LT',\n            sameElse: 'L'\n        },\n        relativeTime: {\n            future: 'في %s',\n            past: 'منذ %s',\n            s: 'ثوان',\n            m: 'دقيقة',\n            mm: '%d دقائق',\n            h: 'ساعة',\n            hh: '%d ساعات',\n            d: 'يوم',\n            dd: '%d أيام',\n            M: 'شهر',\n            MM: '%d أشهر',\n            y: 'سنة',\n            yy: '%d سنوات'\n        },\n        week: {\n            dow: 1, // Monday is the first day of the week.\n            doy: 4 // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var ar__symbolMap = {\n        '1': '١',\n        '2': '٢',\n        '3': '٣',\n        '4': '٤',\n        '5': '٥',\n        '6': '٦',\n        '7': '٧',\n        '8': '٨',\n        '9': '٩',\n        '0': '٠'\n    }, ar__numberMap = {\n        '١': '1',\n        '٢': '2',\n        '٣': '3',\n        '٤': '4',\n        '٥': '5',\n        '٦': '6',\n        '٧': '7',\n        '٨': '8',\n        '٩': '9',\n        '٠': '0'\n    }, pluralForm = function (n) {\n        return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n    }, plurals = {\n        s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n        m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n        h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n        d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n        M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n        y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n    }, pluralize = function (u) {\n        return function (number, withoutSuffix, string, isFuture) {\n            var f = pluralForm(number),\n                str = plurals[u][pluralForm(number)];\n            if (f === 2) {\n                str = str[withoutSuffix ? 0 : 1];\n            }\n            return str.replace(/%d/i, number);\n        };\n    }, ar__months = [\n        'كانون الثاني يناير',\n        'شباط فبراير',\n        'آذار مارس',\n        'نيسان أبريل',\n        'أيار مايو',\n        'حزيران يونيو',\n        'تموز يوليو',\n        'آب أغسطس',\n        'أيلول سبتمبر',\n        'تشرين الأول أكتوبر',\n        'تشرين الثاني نوفمبر',\n        'كانون الأول ديسمبر'\n    ];\n\n    var ar = moment.defineLocale('ar', {\n        months : ar__months,\n        monthsShort : ar__months,\n        weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n        weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n        weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        meridiemParse: /ص|م/,\n        isPM : function (input) {\n            return 'م' === input;\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return 'ص';\n            } else {\n                return 'م';\n            }\n        },\n        calendar : {\n            sameDay: '[اليوم عند الساعة] LT',\n            nextDay: '[غدًا عند الساعة] LT',\n            nextWeek: 'dddd [عند الساعة] LT',\n            lastDay: '[أمس عند الساعة] LT',\n            lastWeek: 'dddd [عند الساعة] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'بعد %s',\n            past : 'منذ %s',\n            s : pluralize('s'),\n            m : pluralize('m'),\n            mm : pluralize('m'),\n            h : pluralize('h'),\n            hh : pluralize('h'),\n            d : pluralize('d'),\n            dd : pluralize('d'),\n            M : pluralize('M'),\n            MM : pluralize('M'),\n            y : pluralize('y'),\n            yy : pluralize('y')\n        },\n        preparse: function (string) {\n            return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n                return ar__numberMap[match];\n            }).replace(/،/g, ',');\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return ar__symbolMap[match];\n            }).replace(/,/g, '،');\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var az__suffixes = {\n        1: '-inci',\n        5: '-inci',\n        8: '-inci',\n        70: '-inci',\n        80: '-inci',\n        2: '-nci',\n        7: '-nci',\n        20: '-nci',\n        50: '-nci',\n        3: '-üncü',\n        4: '-üncü',\n        100: '-üncü',\n        6: '-ncı',\n        9: '-uncu',\n        10: '-uncu',\n        30: '-uncu',\n        60: '-ıncı',\n        90: '-ıncı'\n    };\n\n    var az = moment.defineLocale('az', {\n        months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'),\n        monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),\n        weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'),\n        weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),\n        weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[bugün saat] LT',\n            nextDay : '[sabah saat] LT',\n            nextWeek : '[gələn həftə] dddd [saat] LT',\n            lastDay : '[dünən] LT',\n            lastWeek : '[keçən həftə] dddd [saat] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s sonra',\n            past : '%s əvvəl',\n            s : 'birneçə saniyyə',\n            m : 'bir dəqiqə',\n            mm : '%d dəqiqə',\n            h : 'bir saat',\n            hh : '%d saat',\n            d : 'bir gün',\n            dd : '%d gün',\n            M : 'bir ay',\n            MM : '%d ay',\n            y : 'bir il',\n            yy : '%d il'\n        },\n        meridiemParse: /gecə|səhər|gündüz|axşam/,\n        isPM : function (input) {\n            return /^(gündüz|axşam)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'gecə';\n            } else if (hour < 12) {\n                return 'səhər';\n            } else if (hour < 17) {\n                return 'gündüz';\n            } else {\n                return 'axşam';\n            }\n        },\n        ordinalParse: /\\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,\n        ordinal : function (number) {\n            if (number === 0) {  // special case for zero\n                return number + '-ıncı';\n            }\n            var a = number % 10,\n                b = number % 100 - a,\n                c = number >= 100 ? 100 : null;\n            return number + (az__suffixes[a] || az__suffixes[b] || az__suffixes[c]);\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    function be__plural(word, num) {\n        var forms = word.split('_');\n        return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n    }\n    function be__relativeTimeWithPlural(number, withoutSuffix, key) {\n        var format = {\n            'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',\n            'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',\n            'dd': 'дзень_дні_дзён',\n            'MM': 'месяц_месяцы_месяцаў',\n            'yy': 'год_гады_гадоў'\n        };\n        if (key === 'm') {\n            return withoutSuffix ? 'хвіліна' : 'хвіліну';\n        }\n        else if (key === 'h') {\n            return withoutSuffix ? 'гадзіна' : 'гадзіну';\n        }\n        else {\n            return number + ' ' + be__plural(format[key], +number);\n        }\n    }\n    function be__monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'),\n            'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_')\n        },\n        nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function be__weekdaysCaseReplace(m, format) {\n        var weekdays = {\n            'nominative': 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'),\n            'accusative': 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_')\n        },\n        nounCase = (/\\[ ?[Вв] ?(?:мінулую|наступную)? ?\\] ?dddd/).test(format) ?\n            'accusative' :\n            'nominative';\n        return weekdays[nounCase][m.day()];\n    }\n\n    var be = moment.defineLocale('be', {\n        months : be__monthsCaseReplace,\n        monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'),\n        weekdays : be__weekdaysCaseReplace,\n        weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n        weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY г.',\n            LLL : 'D MMMM YYYY г., LT',\n            LLLL : 'dddd, D MMMM YYYY г., LT'\n        },\n        calendar : {\n            sameDay: '[Сёння ў] LT',\n            nextDay: '[Заўтра ў] LT',\n            lastDay: '[Учора ў] LT',\n            nextWeek: function () {\n                return '[У] dddd [ў] LT';\n            },\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return '[У мінулую] dddd [ў] LT';\n                case 1:\n                case 2:\n                case 4:\n                    return '[У мінулы] dddd [ў] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'праз %s',\n            past : '%s таму',\n            s : 'некалькі секунд',\n            m : be__relativeTimeWithPlural,\n            mm : be__relativeTimeWithPlural,\n            h : be__relativeTimeWithPlural,\n            hh : be__relativeTimeWithPlural,\n            d : 'дзень',\n            dd : be__relativeTimeWithPlural,\n            M : 'месяц',\n            MM : be__relativeTimeWithPlural,\n            y : 'год',\n            yy : be__relativeTimeWithPlural\n        },\n        meridiemParse: /ночы|раніцы|дня|вечара/,\n        isPM : function (input) {\n            return /^(дня|вечара)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'ночы';\n            } else if (hour < 12) {\n                return 'раніцы';\n            } else if (hour < 17) {\n                return 'дня';\n            } else {\n                return 'вечара';\n            }\n        },\n        ordinalParse: /\\d{1,2}-(і|ы|га)/,\n        ordinal: function (number, period) {\n            switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';\n            case 'D':\n                return number + '-га';\n            default:\n                return number;\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var bg = moment.defineLocale('bg', {\n        months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),\n        monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),\n        weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'),\n        weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'),\n        weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'D.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Днес в] LT',\n            nextDay : '[Утре в] LT',\n            nextWeek : 'dddd [в] LT',\n            lastDay : '[Вчера в] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[В изминалата] dddd [в] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[В изминалия] dddd [в] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'след %s',\n            past : 'преди %s',\n            s : 'няколко секунди',\n            m : 'минута',\n            mm : '%d минути',\n            h : 'час',\n            hh : '%d часа',\n            d : 'ден',\n            dd : '%d дни',\n            M : 'месец',\n            MM : '%d месеца',\n            y : 'година',\n            yy : '%d години'\n        },\n        ordinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n        ordinal : function (number) {\n            var lastDigit = number % 10,\n                last2Digits = number % 100;\n            if (number === 0) {\n                return number + '-ев';\n            } else if (last2Digits === 0) {\n                return number + '-ен';\n            } else if (last2Digits > 10 && last2Digits < 20) {\n                return number + '-ти';\n            } else if (lastDigit === 1) {\n                return number + '-ви';\n            } else if (lastDigit === 2) {\n                return number + '-ри';\n            } else if (lastDigit === 7 || lastDigit === 8) {\n                return number + '-ми';\n            } else {\n                return number + '-ти';\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var bn__symbolMap = {\n        '1': '১',\n        '2': '২',\n        '3': '৩',\n        '4': '৪',\n        '5': '৫',\n        '6': '৬',\n        '7': '৭',\n        '8': '৮',\n        '9': '৯',\n        '0': '০'\n    },\n    bn__numberMap = {\n        '১': '1',\n        '২': '2',\n        '৩': '3',\n        '৪': '4',\n        '৫': '5',\n        '৬': '6',\n        '৭': '7',\n        '৮': '8',\n        '৯': '9',\n        '০': '0'\n    };\n\n    var bn = moment.defineLocale('bn', {\n        months : 'জানুয়ারী_ফেবুয়ারী_মার্চ_এপ্রিল_মে_জুন_জুলাই_অগাস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'),\n        monthsShort : 'জানু_ফেব_মার্চ_এপর_মে_জুন_জুল_অগ_সেপ্ট_অক্টো_নভ_ডিসেম্'.split('_'),\n        weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পত্তিবার_শুক্রুবার_শনিবার'.split('_'),\n        weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পত্তি_শুক্রু_শনি'.split('_'),\n        weekdaysMin : 'রব_সম_মঙ্গ_বু_ব্রিহ_শু_শনি'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm সময়',\n            LTS : 'A h:mm:ss সময়',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        calendar : {\n            sameDay : '[আজ] LT',\n            nextDay : '[আগামীকাল] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[গতকাল] LT',\n            lastWeek : '[গত] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s পরে',\n            past : '%s আগে',\n            s : 'কএক সেকেন্ড',\n            m : 'এক মিনিট',\n            mm : '%d মিনিট',\n            h : 'এক ঘন্টা',\n            hh : '%d ঘন্টা',\n            d : 'এক দিন',\n            dd : '%d দিন',\n            M : 'এক মাস',\n            MM : '%d মাস',\n            y : 'এক বছর',\n            yy : '%d বছর'\n        },\n        preparse: function (string) {\n            return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {\n                return bn__numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return bn__symbolMap[match];\n            });\n        },\n        meridiemParse: /রাত|শকাল|দুপুর|বিকেল|রাত/,\n        isPM: function (input) {\n            return /^(দুপুর|বিকেল|রাত)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'রাত';\n            } else if (hour < 10) {\n                return 'শকাল';\n            } else if (hour < 17) {\n                return 'দুপুর';\n            } else if (hour < 20) {\n                return 'বিকেল';\n            } else {\n                return 'রাত';\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var bo__symbolMap = {\n        '1': '༡',\n        '2': '༢',\n        '3': '༣',\n        '4': '༤',\n        '5': '༥',\n        '6': '༦',\n        '7': '༧',\n        '8': '༨',\n        '9': '༩',\n        '0': '༠'\n    },\n    bo__numberMap = {\n        '༡': '1',\n        '༢': '2',\n        '༣': '3',\n        '༤': '4',\n        '༥': '5',\n        '༦': '6',\n        '༧': '7',\n        '༨': '8',\n        '༩': '9',\n        '༠': '0'\n    };\n\n    var bo = moment.defineLocale('bo', {\n        months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n        monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n        weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'),\n        weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n        weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        calendar : {\n            sameDay : '[དི་རིང] LT',\n            nextDay : '[སང་ཉིན] LT',\n            nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',\n            lastDay : '[ཁ་སང] LT',\n            lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s ལ་',\n            past : '%s སྔན་ལ',\n            s : 'ལམ་སང',\n            m : 'སྐར་མ་གཅིག',\n            mm : '%d སྐར་མ',\n            h : 'ཆུ་ཚོད་གཅིག',\n            hh : '%d ཆུ་ཚོད',\n            d : 'ཉིན་གཅིག',\n            dd : '%d ཉིན་',\n            M : 'ཟླ་བ་གཅིག',\n            MM : '%d ཟླ་བ',\n            y : 'ལོ་གཅིག',\n            yy : '%d ལོ'\n        },\n        preparse: function (string) {\n            return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {\n                return bo__numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return bo__symbolMap[match];\n            });\n        },\n        meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,\n        isPM: function (input) {\n            return /^(ཉིན་གུང|དགོང་དག|མཚན་མོ)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'མཚན་མོ';\n            } else if (hour < 10) {\n                return 'ཞོགས་ཀས';\n            } else if (hour < 17) {\n                return 'ཉིན་གུང';\n            } else if (hour < 20) {\n                return 'དགོང་དག';\n            } else {\n                return 'མཚན་མོ';\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    function relativeTimeWithMutation(number, withoutSuffix, key) {\n        var format = {\n            'mm': 'munutenn',\n            'MM': 'miz',\n            'dd': 'devezh'\n        };\n        return number + ' ' + mutation(format[key], number);\n    }\n    function specialMutationForYears(number) {\n        switch (lastNumber(number)) {\n        case 1:\n        case 3:\n        case 4:\n        case 5:\n        case 9:\n            return number + ' bloaz';\n        default:\n            return number + ' vloaz';\n        }\n    }\n    function lastNumber(number) {\n        if (number > 9) {\n            return lastNumber(number % 10);\n        }\n        return number;\n    }\n    function mutation(text, number) {\n        if (number === 2) {\n            return softMutation(text);\n        }\n        return text;\n    }\n    function softMutation(text) {\n        var mutationTable = {\n            'm': 'v',\n            'b': 'v',\n            'd': 'z'\n        };\n        if (mutationTable[text.charAt(0)] === undefined) {\n            return text;\n        }\n        return mutationTable[text.charAt(0)] + text.substring(1);\n    }\n\n    var br = moment.defineLocale('br', {\n        months : 'Genver_C\\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'),\n        monthsShort : 'Gen_C\\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),\n        weekdays : 'Sul_Lun_Meurzh_Merc\\'her_Yaou_Gwener_Sadorn'.split('_'),\n        weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),\n        weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'h[e]mm A',\n            LTS : 'h[e]mm:ss A',\n            L : 'DD/MM/YYYY',\n            LL : 'D [a viz] MMMM YYYY',\n            LLL : 'D [a viz] MMMM YYYY LT',\n            LLLL : 'dddd, D [a viz] MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Hiziv da] LT',\n            nextDay : '[Warc\\'hoazh da] LT',\n            nextWeek : 'dddd [da] LT',\n            lastDay : '[Dec\\'h da] LT',\n            lastWeek : 'dddd [paset da] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'a-benn %s',\n            past : '%s \\'zo',\n            s : 'un nebeud segondennoù',\n            m : 'ur vunutenn',\n            mm : relativeTimeWithMutation,\n            h : 'un eur',\n            hh : '%d eur',\n            d : 'un devezh',\n            dd : relativeTimeWithMutation,\n            M : 'ur miz',\n            MM : relativeTimeWithMutation,\n            y : 'ur bloaz',\n            yy : specialMutationForYears\n        },\n        ordinalParse: /\\d{1,2}(añ|vet)/,\n        ordinal : function (number) {\n            var output = (number === 1) ? 'añ' : 'vet';\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    function bs__translate(number, withoutSuffix, key) {\n        var result = number + ' ';\n        switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n        }\n    }\n\n    var bs = moment.defineLocale('bs', {\n        months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'),\n        monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n        weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n        weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n        weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD. MM. YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd, D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay  : '[danas u] LT',\n            nextDay  : '[sutra u] LT',\n            nextWeek : function () {\n                switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n                }\n            },\n            lastDay  : '[jučer u] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past   : 'prije %s',\n            s      : 'par sekundi',\n            m      : bs__translate,\n            mm     : bs__translate,\n            h      : bs__translate,\n            hh     : bs__translate,\n            d      : 'dan',\n            dd     : bs__translate,\n            M      : 'mjesec',\n            MM     : bs__translate,\n            y      : 'godinu',\n            yy     : bs__translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var ca = moment.defineLocale('ca', {\n        months : 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),\n        monthsShort : 'gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.'.split('_'),\n        weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'),\n        weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),\n        weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : function () {\n                return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            nextDay : function () {\n                return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            nextWeek : function () {\n                return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            lastDay : function () {\n                return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            lastWeek : function () {\n                return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'en %s',\n            past : 'fa %s',\n            s : 'uns segons',\n            m : 'un minut',\n            mm : '%d minuts',\n            h : 'una hora',\n            hh : '%d hores',\n            d : 'un dia',\n            dd : '%d dies',\n            M : 'un mes',\n            MM : '%d mesos',\n            y : 'un any',\n            yy : '%d anys'\n        },\n        ordinalParse: /\\d{1,2}(r|n|t|è|a)/,\n        ordinal : function (number, period) {\n            var output = (number === 1) ? 'r' :\n                (number === 2) ? 'n' :\n                (number === 3) ? 'r' :\n                (number === 4) ? 't' : 'è';\n            if (period === 'w' || period === 'W') {\n                output = 'a';\n            }\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var cs__months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_'),\n        cs__monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');\n    function cs__plural(n) {\n        return (n > 1) && (n < 5) && (~~(n / 10) !== 1);\n    }\n    function cs__translate(number, withoutSuffix, key, isFuture) {\n        var result = number + ' ';\n        switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (cs__plural(number) ? 'minuty' : 'minut');\n            } else {\n                return result + 'minutami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (cs__plural(number) ? 'hodiny' : 'hodin');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'den' : 'dnem';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (cs__plural(number) ? 'dny' : 'dní');\n            } else {\n                return result + 'dny';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (cs__plural(number) ? 'měsíce' : 'měsíců');\n            } else {\n                return result + 'měsíci';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokem';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (cs__plural(number) ? 'roky' : 'let');\n            } else {\n                return result + 'lety';\n            }\n            break;\n        }\n    }\n\n    var cs = moment.defineLocale('cs', {\n        months : cs__months,\n        monthsShort : cs__monthsShort,\n        monthsParse : (function (months, monthsShort) {\n            var i, _monthsParse = [];\n            for (i = 0; i < 12; i++) {\n                _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');\n            }\n            return _monthsParse;\n        }(cs__months, cs__monthsShort)),\n        weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),\n        weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'),\n        weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),\n        longDateFormat : {\n            LT: 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[dnes v] LT',\n            nextDay: '[zítra v] LT',\n            nextWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[v neděli v] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [v] LT';\n                case 3:\n                    return '[ve středu v] LT';\n                case 4:\n                    return '[ve čtvrtek v] LT';\n                case 5:\n                    return '[v pátek v] LT';\n                case 6:\n                    return '[v sobotu v] LT';\n                }\n            },\n            lastDay: '[včera v] LT',\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[minulou neděli v] LT';\n                case 1:\n                case 2:\n                    return '[minulé] dddd [v] LT';\n                case 3:\n                    return '[minulou středu v] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [v] LT';\n                case 6:\n                    return '[minulou sobotu v] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past : 'před %s',\n            s : cs__translate,\n            m : cs__translate,\n            mm : cs__translate,\n            h : cs__translate,\n            hh : cs__translate,\n            d : cs__translate,\n            dd : cs__translate,\n            M : cs__translate,\n            MM : cs__translate,\n            y : cs__translate,\n            yy : cs__translate\n        },\n        ordinalParse : /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var cv = moment.defineLocale('cv', {\n        months : 'кăрлач_нарăс_пуш_ака_май_çĕртме_утă_çурла_авăн_юпа_чӳк_раштав'.split('_'),\n        monthsShort : 'кăр_нар_пуш_ака_май_çĕр_утă_çур_ав_юпа_чӳк_раш'.split('_'),\n        weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кĕçнерникун_эрнекун_шăматкун'.split('_'),\n        weekdaysShort : 'выр_тун_ытл_юн_кĕç_эрн_шăм'.split('_'),\n        weekdaysMin : 'вр_тн_ыт_юн_кç_эр_шм'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD-MM-YYYY',\n            LL : 'YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ]',\n            LLL : 'YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT',\n            LLLL : 'dddd, YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT'\n        },\n        calendar : {\n            sameDay: '[Паян] LT [сехетре]',\n            nextDay: '[Ыран] LT [сехетре]',\n            lastDay: '[Ĕнер] LT [сехетре]',\n            nextWeek: '[Çитес] dddd LT [сехетре]',\n            lastWeek: '[Иртнĕ] dddd LT [сехетре]',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : function (output) {\n                var affix = /сехет$/i.exec(output) ? 'рен' : /çул$/i.exec(output) ? 'тан' : 'ран';\n                return output + affix;\n            },\n            past : '%s каялла',\n            s : 'пĕр-ик çеккунт',\n            m : 'пĕр минут',\n            mm : '%d минут',\n            h : 'пĕр сехет',\n            hh : '%d сехет',\n            d : 'пĕр кун',\n            dd : '%d кун',\n            M : 'пĕр уйăх',\n            MM : '%d уйăх',\n            y : 'пĕр çул',\n            yy : '%d çул'\n        },\n        ordinalParse: /\\d{1,2}-мĕш/,\n        ordinal : '%d-мĕш',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var cy = moment.defineLocale('cy', {\n        months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),\n        monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'),\n        weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'),\n        weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),\n        weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),\n        longDateFormat: {\n            LT: 'HH:mm',\n            LTS : 'LT:ss',\n            L: 'DD/MM/YYYY',\n            LL: 'D MMMM YYYY',\n            LLL: 'D MMMM YYYY LT',\n            LLLL: 'dddd, D MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[Heddiw am] LT',\n            nextDay: '[Yfory am] LT',\n            nextWeek: 'dddd [am] LT',\n            lastDay: '[Ddoe am] LT',\n            lastWeek: 'dddd [diwethaf am] LT',\n            sameElse: 'L'\n        },\n        relativeTime: {\n            future: 'mewn %s',\n            past: '%s yn ôl',\n            s: 'ychydig eiliadau',\n            m: 'munud',\n            mm: '%d munud',\n            h: 'awr',\n            hh: '%d awr',\n            d: 'diwrnod',\n            dd: '%d diwrnod',\n            M: 'mis',\n            MM: '%d mis',\n            y: 'blwyddyn',\n            yy: '%d flynedd'\n        },\n        ordinalParse: /\\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,\n        ordinal: function (number) {\n            var b = number,\n                output = '',\n                lookup = [\n                    '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed\n                    'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed\n                ];\n            if (b > 20) {\n                if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {\n                    output = 'fed'; // not 30ain, 70ain or 90ain\n                } else {\n                    output = 'ain';\n                }\n            } else if (b > 0) {\n                output = lookup[b];\n            }\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var da = moment.defineLocale('da', {\n        months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n        weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n        weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'),\n        weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd [d.] D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[I dag kl.] LT',\n            nextDay : '[I morgen kl.] LT',\n            nextWeek : 'dddd [kl.] LT',\n            lastDay : '[I går kl.] LT',\n            lastWeek : '[sidste] dddd [kl] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'om %s',\n            past : '%s siden',\n            s : 'få sekunder',\n            m : 'et minut',\n            mm : '%d minutter',\n            h : 'en time',\n            hh : '%d timer',\n            d : 'en dag',\n            dd : '%d dage',\n            M : 'en måned',\n            MM : '%d måneder',\n            y : 'et år',\n            yy : '%d år'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    function de_at__processRelativeTime(number, withoutSuffix, key, isFuture) {\n        var format = {\n            'm': ['eine Minute', 'einer Minute'],\n            'h': ['eine Stunde', 'einer Stunde'],\n            'd': ['ein Tag', 'einem Tag'],\n            'dd': [number + ' Tage', number + ' Tagen'],\n            'M': ['ein Monat', 'einem Monat'],\n            'MM': [number + ' Monate', number + ' Monaten'],\n            'y': ['ein Jahr', 'einem Jahr'],\n            'yy': [number + ' Jahre', number + ' Jahren']\n        };\n        return withoutSuffix ? format[key][0] : format[key][1];\n    }\n\n    var de_at = moment.defineLocale('de-at', {\n        months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n        monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n        weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n        weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n        weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT: 'HH:mm',\n            LTS: 'HH:mm:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd, D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Heute um] LT [Uhr]',\n            sameElse: 'L',\n            nextDay: '[Morgen um] LT [Uhr]',\n            nextWeek: 'dddd [um] LT [Uhr]',\n            lastDay: '[Gestern um] LT [Uhr]',\n            lastWeek: '[letzten] dddd [um] LT [Uhr]'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : 'vor %s',\n            s : 'ein paar Sekunden',\n            m : de_at__processRelativeTime,\n            mm : '%d Minuten',\n            h : de_at__processRelativeTime,\n            hh : '%d Stunden',\n            d : de_at__processRelativeTime,\n            dd : de_at__processRelativeTime,\n            M : de_at__processRelativeTime,\n            MM : de_at__processRelativeTime,\n            y : de_at__processRelativeTime,\n            yy : de_at__processRelativeTime\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    function de__processRelativeTime(number, withoutSuffix, key, isFuture) {\n        var format = {\n            'm': ['eine Minute', 'einer Minute'],\n            'h': ['eine Stunde', 'einer Stunde'],\n            'd': ['ein Tag', 'einem Tag'],\n            'dd': [number + ' Tage', number + ' Tagen'],\n            'M': ['ein Monat', 'einem Monat'],\n            'MM': [number + ' Monate', number + ' Monaten'],\n            'y': ['ein Jahr', 'einem Jahr'],\n            'yy': [number + ' Jahre', number + ' Jahren']\n        };\n        return withoutSuffix ? format[key][0] : format[key][1];\n    }\n\n    var de = moment.defineLocale('de', {\n        months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n        monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n        weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n        weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n        weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT: 'HH:mm',\n            LTS: 'HH:mm:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd, D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Heute um] LT [Uhr]',\n            sameElse: 'L',\n            nextDay: '[Morgen um] LT [Uhr]',\n            nextWeek: 'dddd [um] LT [Uhr]',\n            lastDay: '[Gestern um] LT [Uhr]',\n            lastWeek: '[letzten] dddd [um] LT [Uhr]'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : 'vor %s',\n            s : 'ein paar Sekunden',\n            m : de__processRelativeTime,\n            mm : '%d Minuten',\n            h : de__processRelativeTime,\n            hh : '%d Stunden',\n            d : de__processRelativeTime,\n            dd : de__processRelativeTime,\n            M : de__processRelativeTime,\n            MM : de__processRelativeTime,\n            y : de__processRelativeTime,\n            yy : de__processRelativeTime\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var el = moment.defineLocale('el', {\n        monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),\n        monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'),\n        months : function (momentToFormat, format) {\n            if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM'\n                return this._monthsGenitiveEl[momentToFormat.month()];\n            } else {\n                return this._monthsNominativeEl[momentToFormat.month()];\n            }\n        },\n        monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),\n        weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'),\n        weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),\n        weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),\n        meridiem : function (hours, minutes, isLower) {\n            if (hours > 11) {\n                return isLower ? 'μμ' : 'ΜΜ';\n            } else {\n                return isLower ? 'πμ' : 'ΠΜ';\n            }\n        },\n        isPM : function (input) {\n            return ((input + '').toLowerCase()[0] === 'μ');\n        },\n        meridiemParse : /[ΠΜ]\\.?Μ?\\.?/i,\n        longDateFormat : {\n            LT : 'h:mm A',\n            LTS : 'h:mm:ss A',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendarEl : {\n            sameDay : '[Σήμερα {}] LT',\n            nextDay : '[Αύριο {}] LT',\n            nextWeek : 'dddd [{}] LT',\n            lastDay : '[Χθες {}] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                    case 6:\n                        return '[το προηγούμενο] dddd [{}] LT';\n                    default:\n                        return '[την προηγούμενη] dddd [{}] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        calendar : function (key, mom) {\n            var output = this._calendarEl[key],\n                hours = mom && mom.hours();\n            if (typeof output === 'function') {\n                output = output.apply(mom);\n            }\n            return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις'));\n        },\n        relativeTime : {\n            future : 'σε %s',\n            past : '%s πριν',\n            s : 'λίγα δευτερόλεπτα',\n            m : 'ένα λεπτό',\n            mm : '%d λεπτά',\n            h : 'μία ώρα',\n            hh : '%d ώρες',\n            d : 'μία μέρα',\n            dd : '%d μέρες',\n            M : 'ένας μήνας',\n            MM : '%d μήνες',\n            y : 'ένας χρόνος',\n            yy : '%d χρόνια'\n        },\n        ordinalParse: /\\d{1,2}η/,\n        ordinal: '%dη',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4st is the first week of the year.\n        }\n    });\n\n    var en_au = moment.defineLocale('en-au', {\n        months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n        weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n        weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n        weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'h:mm A',\n            LTS : 'h:mm:ss A',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Today at] LT',\n            nextDay : '[Tomorrow at] LT',\n            nextWeek : 'dddd [at] LT',\n            lastDay : '[Yesterday at] LT',\n            lastWeek : '[Last] dddd [at] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : '%s ago',\n            s : 'a few seconds',\n            m : 'a minute',\n            mm : '%d minutes',\n            h : 'an hour',\n            hh : '%d hours',\n            d : 'a day',\n            dd : '%d days',\n            M : 'a month',\n            MM : '%d months',\n            y : 'a year',\n            yy : '%d years'\n        },\n        ordinalParse: /\\d{1,2}(st|nd|rd|th)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (~~(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var en_ca = moment.defineLocale('en-ca', {\n        months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n        weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n        weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n        weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'h:mm A',\n            LTS : 'h:mm:ss A',\n            L : 'YYYY-MM-DD',\n            LL : 'D MMMM, YYYY',\n            LLL : 'D MMMM, YYYY LT',\n            LLLL : 'dddd, D MMMM, YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Today at] LT',\n            nextDay : '[Tomorrow at] LT',\n            nextWeek : 'dddd [at] LT',\n            lastDay : '[Yesterday at] LT',\n            lastWeek : '[Last] dddd [at] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : '%s ago',\n            s : 'a few seconds',\n            m : 'a minute',\n            mm : '%d minutes',\n            h : 'an hour',\n            hh : '%d hours',\n            d : 'a day',\n            dd : '%d days',\n            M : 'a month',\n            MM : '%d months',\n            y : 'a year',\n            yy : '%d years'\n        },\n        ordinalParse: /\\d{1,2}(st|nd|rd|th)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (~~(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        }\n    });\n\n    var en_gb = moment.defineLocale('en-gb', {\n        months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n        weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n        weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n        weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Today at] LT',\n            nextDay : '[Tomorrow at] LT',\n            nextWeek : 'dddd [at] LT',\n            lastDay : '[Yesterday at] LT',\n            lastWeek : '[Last] dddd [at] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : '%s ago',\n            s : 'a few seconds',\n            m : 'a minute',\n            mm : '%d minutes',\n            h : 'an hour',\n            hh : '%d hours',\n            d : 'a day',\n            dd : '%d days',\n            M : 'a month',\n            MM : '%d months',\n            y : 'a year',\n            yy : '%d years'\n        },\n        ordinalParse: /\\d{1,2}(st|nd|rd|th)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (~~(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var eo = moment.defineLocale('eo', {\n        months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'),\n        weekdays : 'Dimanĉo_Lundo_Mardo_Merkredo_Ĵaŭdo_Vendredo_Sabato'.split('_'),\n        weekdaysShort : 'Dim_Lun_Mard_Merk_Ĵaŭ_Ven_Sab'.split('_'),\n        weekdaysMin : 'Di_Lu_Ma_Me_Ĵa_Ve_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'D[-an de] MMMM, YYYY',\n            LLL : 'D[-an de] MMMM, YYYY LT',\n            LLLL : 'dddd, [la] D[-an de] MMMM, YYYY LT'\n        },\n        meridiemParse: /[ap]\\.t\\.m/i,\n        isPM: function (input) {\n            return input.charAt(0).toLowerCase() === 'p';\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours > 11) {\n                return isLower ? 'p.t.m.' : 'P.T.M.';\n            } else {\n                return isLower ? 'a.t.m.' : 'A.T.M.';\n            }\n        },\n        calendar : {\n            sameDay : '[Hodiaŭ je] LT',\n            nextDay : '[Morgaŭ je] LT',\n            nextWeek : 'dddd [je] LT',\n            lastDay : '[Hieraŭ je] LT',\n            lastWeek : '[pasinta] dddd [je] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'je %s',\n            past : 'antaŭ %s',\n            s : 'sekundoj',\n            m : 'minuto',\n            mm : '%d minutoj',\n            h : 'horo',\n            hh : '%d horoj',\n            d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo\n            dd : '%d tagoj',\n            M : 'monato',\n            MM : '%d monatoj',\n            y : 'jaro',\n            yy : '%d jaroj'\n        },\n        ordinalParse: /\\d{1,2}a/,\n        ordinal : '%da',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'),\n        es__monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\n    var es = moment.defineLocale('es', {\n        months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n        monthsShort : function (m, format) {\n            if (/-MMM-/.test(format)) {\n                return es__monthsShort[m.month()];\n            } else {\n                return monthsShortDot[m.month()];\n            }\n        },\n        weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n        weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n        weekdaysMin : 'Do_Lu_Ma_Mi_Ju_Vi_Sá'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D [de] MMMM [de] YYYY',\n            LLL : 'D [de] MMMM [de] YYYY LT',\n            LLLL : 'dddd, D [de] MMMM [de] YYYY LT'\n        },\n        calendar : {\n            sameDay : function () {\n                return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            nextDay : function () {\n                return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            nextWeek : function () {\n                return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            lastDay : function () {\n                return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            lastWeek : function () {\n                return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'en %s',\n            past : 'hace %s',\n            s : 'unos segundos',\n            m : 'un minuto',\n            mm : '%d minutos',\n            h : 'una hora',\n            hh : '%d horas',\n            d : 'un día',\n            dd : '%d días',\n            M : 'un mes',\n            MM : '%d meses',\n            y : 'un año',\n            yy : '%d años'\n        },\n        ordinalParse : /\\d{1,2}º/,\n        ordinal : '%dº',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    function et__processRelativeTime(number, withoutSuffix, key, isFuture) {\n        var format = {\n            's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],\n            'm' : ['ühe minuti', 'üks minut'],\n            'mm': [number + ' minuti', number + ' minutit'],\n            'h' : ['ühe tunni', 'tund aega', 'üks tund'],\n            'hh': [number + ' tunni', number + ' tundi'],\n            'd' : ['ühe päeva', 'üks päev'],\n            'M' : ['kuu aja', 'kuu aega', 'üks kuu'],\n            'MM': [number + ' kuu', number + ' kuud'],\n            'y' : ['ühe aasta', 'aasta', 'üks aasta'],\n            'yy': [number + ' aasta', number + ' aastat']\n        };\n        if (withoutSuffix) {\n            return format[key][2] ? format[key][2] : format[key][1];\n        }\n        return isFuture ? format[key][0] : format[key][1];\n    }\n\n    var et = moment.defineLocale('et', {\n        months        : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'),\n        monthsShort   : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'),\n        weekdays      : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'),\n        weekdaysShort : 'P_E_T_K_N_R_L'.split('_'),\n        weekdaysMin   : 'P_E_T_K_N_R_L'.split('_'),\n        longDateFormat : {\n            LT   : 'H:mm',\n            LTS : 'LT:ss',\n            L    : 'DD.MM.YYYY',\n            LL   : 'D. MMMM YYYY',\n            LLL  : 'D. MMMM YYYY LT',\n            LLLL : 'dddd, D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay  : '[Täna,] LT',\n            nextDay  : '[Homme,] LT',\n            nextWeek : '[Järgmine] dddd LT',\n            lastDay  : '[Eile,] LT',\n            lastWeek : '[Eelmine] dddd LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s pärast',\n            past   : '%s tagasi',\n            s      : et__processRelativeTime,\n            m      : et__processRelativeTime,\n            mm     : et__processRelativeTime,\n            h      : et__processRelativeTime,\n            hh     : et__processRelativeTime,\n            d      : et__processRelativeTime,\n            dd     : '%d päeva',\n            M      : et__processRelativeTime,\n            MM     : et__processRelativeTime,\n            y      : et__processRelativeTime,\n            yy     : et__processRelativeTime\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var eu = moment.defineLocale('eu', {\n        months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'),\n        monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'),\n        weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'),\n        weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'),\n        weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'YYYY[ko] MMMM[ren] D[a]',\n            LLL : 'YYYY[ko] MMMM[ren] D[a] LT',\n            LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] LT',\n            l : 'YYYY-M-D',\n            ll : 'YYYY[ko] MMM D[a]',\n            lll : 'YYYY[ko] MMM D[a] LT',\n            llll : 'ddd, YYYY[ko] MMM D[a] LT'\n        },\n        calendar : {\n            sameDay : '[gaur] LT[etan]',\n            nextDay : '[bihar] LT[etan]',\n            nextWeek : 'dddd LT[etan]',\n            lastDay : '[atzo] LT[etan]',\n            lastWeek : '[aurreko] dddd LT[etan]',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s barru',\n            past : 'duela %s',\n            s : 'segundo batzuk',\n            m : 'minutu bat',\n            mm : '%d minutu',\n            h : 'ordu bat',\n            hh : '%d ordu',\n            d : 'egun bat',\n            dd : '%d egun',\n            M : 'hilabete bat',\n            MM : '%d hilabete',\n            y : 'urte bat',\n            yy : '%d urte'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var fa__symbolMap = {\n        '1': '۱',\n        '2': '۲',\n        '3': '۳',\n        '4': '۴',\n        '5': '۵',\n        '6': '۶',\n        '7': '۷',\n        '8': '۸',\n        '9': '۹',\n        '0': '۰'\n    }, fa__numberMap = {\n        '۱': '1',\n        '۲': '2',\n        '۳': '3',\n        '۴': '4',\n        '۵': '5',\n        '۶': '6',\n        '۷': '7',\n        '۸': '8',\n        '۹': '9',\n        '۰': '0'\n    };\n\n    var fa = moment.defineLocale('fa', {\n        months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n        monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n        weekdays : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n        weekdaysShort : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n        weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        meridiemParse: /قبل از ظهر|بعد از ظهر/,\n        isPM: function (input) {\n            return /بعد از ظهر/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return 'قبل از ظهر';\n            } else {\n                return 'بعد از ظهر';\n            }\n        },\n        calendar : {\n            sameDay : '[امروز ساعت] LT',\n            nextDay : '[فردا ساعت] LT',\n            nextWeek : 'dddd [ساعت] LT',\n            lastDay : '[دیروز ساعت] LT',\n            lastWeek : 'dddd [پیش] [ساعت] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'در %s',\n            past : '%s پیش',\n            s : 'چندین ثانیه',\n            m : 'یک دقیقه',\n            mm : '%d دقیقه',\n            h : 'یک ساعت',\n            hh : '%d ساعت',\n            d : 'یک روز',\n            dd : '%d روز',\n            M : 'یک ماه',\n            MM : '%d ماه',\n            y : 'یک سال',\n            yy : '%d سال'\n        },\n        preparse: function (string) {\n            return string.replace(/[۰-۹]/g, function (match) {\n                return fa__numberMap[match];\n            }).replace(/،/g, ',');\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return fa__symbolMap[match];\n            }).replace(/,/g, '،');\n        },\n        ordinalParse: /\\d{1,2}م/,\n        ordinal : '%dم',\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12 // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '),\n        numbersFuture = [\n            'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',\n            numbersPast[7], numbersPast[8], numbersPast[9]\n        ];\n    function fi__translate(number, withoutSuffix, key, isFuture) {\n        var result = '';\n        switch (key) {\n        case 's':\n            return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';\n        case 'm':\n            return isFuture ? 'minuutin' : 'minuutti';\n        case 'mm':\n            result = isFuture ? 'minuutin' : 'minuuttia';\n            break;\n        case 'h':\n            return isFuture ? 'tunnin' : 'tunti';\n        case 'hh':\n            result = isFuture ? 'tunnin' : 'tuntia';\n            break;\n        case 'd':\n            return isFuture ? 'päivän' : 'päivä';\n        case 'dd':\n            result = isFuture ? 'päivän' : 'päivää';\n            break;\n        case 'M':\n            return isFuture ? 'kuukauden' : 'kuukausi';\n        case 'MM':\n            result = isFuture ? 'kuukauden' : 'kuukautta';\n            break;\n        case 'y':\n            return isFuture ? 'vuoden' : 'vuosi';\n        case 'yy':\n            result = isFuture ? 'vuoden' : 'vuotta';\n            break;\n        }\n        result = verbalNumber(number, isFuture) + ' ' + result;\n        return result;\n    }\n    function verbalNumber(number, isFuture) {\n        return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;\n    }\n\n    var fi = moment.defineLocale('fi', {\n        months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'),\n        monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'),\n        weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'),\n        weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'),\n        weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'),\n        longDateFormat : {\n            LT : 'HH.mm',\n            LTS : 'HH.mm.ss',\n            L : 'DD.MM.YYYY',\n            LL : 'Do MMMM[ta] YYYY',\n            LLL : 'Do MMMM[ta] YYYY, [klo] LT',\n            LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] LT',\n            l : 'D.M.YYYY',\n            ll : 'Do MMM YYYY',\n            lll : 'Do MMM YYYY, [klo] LT',\n            llll : 'ddd, Do MMM YYYY, [klo] LT'\n        },\n        calendar : {\n            sameDay : '[tänään] [klo] LT',\n            nextDay : '[huomenna] [klo] LT',\n            nextWeek : 'dddd [klo] LT',\n            lastDay : '[eilen] [klo] LT',\n            lastWeek : '[viime] dddd[na] [klo] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s päästä',\n            past : '%s sitten',\n            s : fi__translate,\n            m : fi__translate,\n            mm : fi__translate,\n            h : fi__translate,\n            hh : fi__translate,\n            d : fi__translate,\n            dd : fi__translate,\n            M : fi__translate,\n            MM : fi__translate,\n            y : fi__translate,\n            yy : fi__translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var fo = moment.defineLocale('fo', {\n        months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n        weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'),\n        weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'),\n        weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D. MMMM, YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Í dag kl.] LT',\n            nextDay : '[Í morgin kl.] LT',\n            nextWeek : 'dddd [kl.] LT',\n            lastDay : '[Í gjár kl.] LT',\n            lastWeek : '[síðstu] dddd [kl] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'um %s',\n            past : '%s síðani',\n            s : 'fá sekund',\n            m : 'ein minutt',\n            mm : '%d minuttir',\n            h : 'ein tími',\n            hh : '%d tímar',\n            d : 'ein dagur',\n            dd : '%d dagar',\n            M : 'ein mánaði',\n            MM : '%d mánaðir',\n            y : 'eitt ár',\n            yy : '%d ár'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var fr_ca = moment.defineLocale('fr-ca', {\n        months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n        monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n        weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n        weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n        weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Aujourd\\'hui à] LT',\n            nextDay: '[Demain à] LT',\n            nextWeek: 'dddd [à] LT',\n            lastDay: '[Hier à] LT',\n            lastWeek: 'dddd [dernier à] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'dans %s',\n            past : 'il y a %s',\n            s : 'quelques secondes',\n            m : 'une minute',\n            mm : '%d minutes',\n            h : 'une heure',\n            hh : '%d heures',\n            d : 'un jour',\n            dd : '%d jours',\n            M : 'un mois',\n            MM : '%d mois',\n            y : 'un an',\n            yy : '%d ans'\n        },\n        ordinalParse: /\\d{1,2}(er|)/,\n        ordinal : function (number) {\n            return number + (number === 1 ? 'er' : '');\n        }\n    });\n\n    var fr = moment.defineLocale('fr', {\n        months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n        monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n        weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n        weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n        weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Aujourd\\'hui à] LT',\n            nextDay: '[Demain à] LT',\n            nextWeek: 'dddd [à] LT',\n            lastDay: '[Hier à] LT',\n            lastWeek: 'dddd [dernier à] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'dans %s',\n            past : 'il y a %s',\n            s : 'quelques secondes',\n            m : 'une minute',\n            mm : '%d minutes',\n            h : 'une heure',\n            hh : '%d heures',\n            d : 'un jour',\n            dd : '%d jours',\n            M : 'un mois',\n            MM : '%d mois',\n            y : 'un an',\n            yy : '%d ans'\n        },\n        ordinalParse: /\\d{1,2}(er|)/,\n        ordinal : function (number) {\n            return number + (number === 1 ? 'er' : '');\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var fy__monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_'),\n        fy__monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_');\n\n    var fy = moment.defineLocale('fy', {\n        months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'),\n        monthsShort : function (m, format) {\n            if (/-MMM-/.test(format)) {\n                return fy__monthsShortWithoutDots[m.month()];\n            } else {\n                return fy__monthsShortWithDots[m.month()];\n            }\n        },\n        weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'),\n        weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'),\n        weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD-MM-YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[hjoed om] LT',\n            nextDay: '[moarn om] LT',\n            nextWeek: 'dddd [om] LT',\n            lastDay: '[juster om] LT',\n            lastWeek: '[ôfrûne] dddd [om] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'oer %s',\n            past : '%s lyn',\n            s : 'in pear sekonden',\n            m : 'ien minút',\n            mm : '%d minuten',\n            h : 'ien oere',\n            hh : '%d oeren',\n            d : 'ien dei',\n            dd : '%d dagen',\n            M : 'ien moanne',\n            MM : '%d moannen',\n            y : 'ien jier',\n            yy : '%d jierren'\n        },\n        ordinalParse: /\\d{1,2}(ste|de)/,\n        ordinal : function (number) {\n            return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var gl = moment.defineLocale('gl', {\n        months : 'Xaneiro_Febreiro_Marzo_Abril_Maio_Xuño_Xullo_Agosto_Setembro_Outubro_Novembro_Decembro'.split('_'),\n        monthsShort : 'Xan._Feb._Mar._Abr._Mai._Xuñ._Xul._Ago._Set._Out._Nov._Dec.'.split('_'),\n        weekdays : 'Domingo_Luns_Martes_Mércores_Xoves_Venres_Sábado'.split('_'),\n        weekdaysShort : 'Dom._Lun._Mar._Mér._Xov._Ven._Sáb.'.split('_'),\n        weekdaysMin : 'Do_Lu_Ma_Mé_Xo_Ve_Sá'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : function () {\n                return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n            },\n            nextDay : function () {\n                return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n            },\n            nextWeek : function () {\n                return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n            },\n            lastDay : function () {\n                return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';\n            },\n            lastWeek : function () {\n                return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : function (str) {\n                if (str === 'uns segundos') {\n                    return 'nuns segundos';\n                }\n                return 'en ' + str;\n            },\n            past : 'hai %s',\n            s : 'uns segundos',\n            m : 'un minuto',\n            mm : '%d minutos',\n            h : 'unha hora',\n            hh : '%d horas',\n            d : 'un día',\n            dd : '%d días',\n            M : 'un mes',\n            MM : '%d meses',\n            y : 'un ano',\n            yy : '%d anos'\n        },\n        ordinalParse : /\\d{1,2}º/,\n        ordinal : '%dº',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var he = moment.defineLocale('he', {\n        months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'),\n        monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'),\n        weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'),\n        weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'),\n        weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D [ב]MMMM YYYY',\n            LLL : 'D [ב]MMMM YYYY LT',\n            LLLL : 'dddd, D [ב]MMMM YYYY LT',\n            l : 'D/M/YYYY',\n            ll : 'D MMM YYYY',\n            lll : 'D MMM YYYY LT',\n            llll : 'ddd, D MMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[היום ב־]LT',\n            nextDay : '[מחר ב־]LT',\n            nextWeek : 'dddd [בשעה] LT',\n            lastDay : '[אתמול ב־]LT',\n            lastWeek : '[ביום] dddd [האחרון בשעה] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'בעוד %s',\n            past : 'לפני %s',\n            s : 'מספר שניות',\n            m : 'דקה',\n            mm : '%d דקות',\n            h : 'שעה',\n            hh : function (number) {\n                if (number === 2) {\n                    return 'שעתיים';\n                }\n                return number + ' שעות';\n            },\n            d : 'יום',\n            dd : function (number) {\n                if (number === 2) {\n                    return 'יומיים';\n                }\n                return number + ' ימים';\n            },\n            M : 'חודש',\n            MM : function (number) {\n                if (number === 2) {\n                    return 'חודשיים';\n                }\n                return number + ' חודשים';\n            },\n            y : 'שנה',\n            yy : function (number) {\n                if (number === 2) {\n                    return 'שנתיים';\n                } else if (number % 10 === 0 && number !== 10) {\n                    return number + ' שנה';\n                }\n                return number + ' שנים';\n            }\n        }\n    });\n\n    var hi__symbolMap = {\n        '1': '१',\n        '2': '२',\n        '3': '३',\n        '4': '४',\n        '5': '५',\n        '6': '६',\n        '7': '७',\n        '8': '८',\n        '9': '९',\n        '0': '०'\n    },\n    hi__numberMap = {\n        '१': '1',\n        '२': '2',\n        '३': '3',\n        '४': '4',\n        '५': '5',\n        '६': '6',\n        '७': '7',\n        '८': '8',\n        '९': '9',\n        '०': '0'\n    };\n\n    var hi = moment.defineLocale('hi', {\n        months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'),\n        monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'),\n        weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n        weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'),\n        weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm बजे',\n            LTS : 'A h:mm:ss बजे',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        calendar : {\n            sameDay : '[आज] LT',\n            nextDay : '[कल] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[कल] LT',\n            lastWeek : '[पिछले] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s में',\n            past : '%s पहले',\n            s : 'कुछ ही क्षण',\n            m : 'एक मिनट',\n            mm : '%d मिनट',\n            h : 'एक घंटा',\n            hh : '%d घंटे',\n            d : 'एक दिन',\n            dd : '%d दिन',\n            M : 'एक महीने',\n            MM : '%d महीने',\n            y : 'एक वर्ष',\n            yy : '%d वर्ष'\n        },\n        preparse: function (string) {\n            return string.replace(/[१२३४५६७८९०]/g, function (match) {\n                return hi__numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return hi__symbolMap[match];\n            });\n        },\n        meridiemParse: /रात|सुबह|दोपहर|शाम/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'रात') {\n                return hour < 4 ? hour : hour + 12;\n            } else if (meridiem === 'सुबह') {\n                return hour;\n            } else if (meridiem === 'दोपहर') {\n                return hour >= 10 ? hour : hour + 12;\n            } else if (meridiem === 'शाम') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'रात';\n            } else if (hour < 10) {\n                return 'सुबह';\n            } else if (hour < 17) {\n                return 'दोपहर';\n            } else if (hour < 20) {\n                return 'शाम';\n            } else {\n                return 'रात';\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    function hr__translate(number, withoutSuffix, key) {\n        var result = number + ' ';\n        switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n        }\n    }\n\n    var hr = moment.defineLocale('hr', {\n        months : 'sječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_'),\n        monthsShort : 'sje._vel._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'),\n        weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n        weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n        weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD. MM. YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd, D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay  : '[danas u] LT',\n            nextDay  : '[sutra u] LT',\n            nextWeek : function () {\n                switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n                }\n            },\n            lastDay  : '[jučer u] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past   : 'prije %s',\n            s      : 'par sekundi',\n            m      : hr__translate,\n            mm     : hr__translate,\n            h      : hr__translate,\n            hh     : hr__translate,\n            d      : 'dan',\n            dd     : hr__translate,\n            M      : 'mjesec',\n            MM     : hr__translate,\n            y      : 'godinu',\n            yy     : hr__translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');\n    function hu__translate(number, withoutSuffix, key, isFuture) {\n        var num = number,\n            suffix;\n        switch (key) {\n        case 's':\n            return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';\n        case 'm':\n            return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'mm':\n            return num + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'h':\n            return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'hh':\n            return num + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'd':\n            return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'dd':\n            return num + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'M':\n            return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'MM':\n            return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'y':\n            return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');\n        case 'yy':\n            return num + (isFuture || withoutSuffix ? ' év' : ' éve');\n        }\n        return '';\n    }\n    function week(isFuture) {\n        return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';\n    }\n\n    var hu = moment.defineLocale('hu', {\n        months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'),\n        monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'),\n        weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),\n        weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),\n        weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'YYYY.MM.DD.',\n            LL : 'YYYY. MMMM D.',\n            LLL : 'YYYY. MMMM D., LT',\n            LLLL : 'YYYY. MMMM D., dddd LT'\n        },\n        meridiemParse: /de|du/i,\n        isPM: function (input) {\n            return input.charAt(1).toLowerCase() === 'u';\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours < 12) {\n                return isLower === true ? 'de' : 'DE';\n            } else {\n                return isLower === true ? 'du' : 'DU';\n            }\n        },\n        calendar : {\n            sameDay : '[ma] LT[-kor]',\n            nextDay : '[holnap] LT[-kor]',\n            nextWeek : function () {\n                return week.call(this, true);\n            },\n            lastDay : '[tegnap] LT[-kor]',\n            lastWeek : function () {\n                return week.call(this, false);\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s múlva',\n            past : '%s',\n            s : hu__translate,\n            m : hu__translate,\n            mm : hu__translate,\n            h : hu__translate,\n            hh : hu__translate,\n            d : hu__translate,\n            dd : hu__translate,\n            M : hu__translate,\n            MM : hu__translate,\n            y : hu__translate,\n            yy : hu__translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    function hy_am__monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),\n            'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_')\n        },\n        nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function hy_am__monthsShortCaseReplace(m, format) {\n        var monthsShort = 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_');\n        return monthsShort[m.month()];\n    }\n    function hy_am__weekdaysCaseReplace(m, format) {\n        var weekdays = 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_');\n        return weekdays[m.day()];\n    }\n\n    var hy_am = moment.defineLocale('hy-am', {\n        months : hy_am__monthsCaseReplace,\n        monthsShort : hy_am__monthsShortCaseReplace,\n        weekdays : hy_am__weekdaysCaseReplace,\n        weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n        weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY թ.',\n            LLL : 'D MMMM YYYY թ., LT',\n            LLLL : 'dddd, D MMMM YYYY թ., LT'\n        },\n        calendar : {\n            sameDay: '[այսօր] LT',\n            nextDay: '[վաղը] LT',\n            lastDay: '[երեկ] LT',\n            nextWeek: function () {\n                return 'dddd [օրը ժամը] LT';\n            },\n            lastWeek: function () {\n                return '[անցած] dddd [օրը ժամը] LT';\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : '%s հետո',\n            past : '%s առաջ',\n            s : 'մի քանի վայրկյան',\n            m : 'րոպե',\n            mm : '%d րոպե',\n            h : 'ժամ',\n            hh : '%d ժամ',\n            d : 'օր',\n            dd : '%d օր',\n            M : 'ամիս',\n            MM : '%d ամիս',\n            y : 'տարի',\n            yy : '%d տարի'\n        },\n        meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,\n        isPM: function (input) {\n            return /^(ցերեկվա|երեկոյան)$/.test(input);\n        },\n        meridiem : function (hour) {\n            if (hour < 4) {\n                return 'գիշերվա';\n            } else if (hour < 12) {\n                return 'առավոտվա';\n            } else if (hour < 17) {\n                return 'ցերեկվա';\n            } else {\n                return 'երեկոյան';\n            }\n        },\n        ordinalParse: /\\d{1,2}|\\d{1,2}-(ին|րդ)/,\n        ordinal: function (number, period) {\n            switch (period) {\n            case 'DDD':\n            case 'w':\n            case 'W':\n            case 'DDDo':\n                if (number === 1) {\n                    return number + '-ին';\n                }\n                return number + '-րդ';\n            default:\n                return number;\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var id = moment.defineLocale('id', {\n        months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'),\n        weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'),\n        weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'),\n        weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),\n        longDateFormat : {\n            LT : 'HH.mm',\n            LTS : 'LT.ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY [pukul] LT',\n            LLLL : 'dddd, D MMMM YYYY [pukul] LT'\n        },\n        meridiemParse: /pagi|siang|sore|malam/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'pagi') {\n                return hour;\n            } else if (meridiem === 'siang') {\n                return hour >= 11 ? hour : hour + 12;\n            } else if (meridiem === 'sore' || meridiem === 'malam') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours < 11) {\n                return 'pagi';\n            } else if (hours < 15) {\n                return 'siang';\n            } else if (hours < 19) {\n                return 'sore';\n            } else {\n                return 'malam';\n            }\n        },\n        calendar : {\n            sameDay : '[Hari ini pukul] LT',\n            nextDay : '[Besok pukul] LT',\n            nextWeek : 'dddd [pukul] LT',\n            lastDay : '[Kemarin pukul] LT',\n            lastWeek : 'dddd [lalu pukul] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'dalam %s',\n            past : '%s yang lalu',\n            s : 'beberapa detik',\n            m : 'semenit',\n            mm : '%d menit',\n            h : 'sejam',\n            hh : '%d jam',\n            d : 'sehari',\n            dd : '%d hari',\n            M : 'sebulan',\n            MM : '%d bulan',\n            y : 'setahun',\n            yy : '%d tahun'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    function is__plural(n) {\n        if (n % 100 === 11) {\n            return true;\n        } else if (n % 10 === 1) {\n            return false;\n        }\n        return true;\n    }\n    function is__translate(number, withoutSuffix, key, isFuture) {\n        var result = number + ' ';\n        switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';\n        case 'm':\n            return withoutSuffix ? 'mínúta' : 'mínútu';\n        case 'mm':\n            if (is__plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');\n            } else if (withoutSuffix) {\n                return result + 'mínúta';\n            }\n            return result + 'mínútu';\n        case 'hh':\n            if (is__plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');\n            }\n            return result + 'klukkustund';\n        case 'd':\n            if (withoutSuffix) {\n                return 'dagur';\n            }\n            return isFuture ? 'dag' : 'degi';\n        case 'dd':\n            if (is__plural(number)) {\n                if (withoutSuffix) {\n                    return result + 'dagar';\n                }\n                return result + (isFuture ? 'daga' : 'dögum');\n            } else if (withoutSuffix) {\n                return result + 'dagur';\n            }\n            return result + (isFuture ? 'dag' : 'degi');\n        case 'M':\n            if (withoutSuffix) {\n                return 'mánuður';\n            }\n            return isFuture ? 'mánuð' : 'mánuði';\n        case 'MM':\n            if (is__plural(number)) {\n                if (withoutSuffix) {\n                    return result + 'mánuðir';\n                }\n                return result + (isFuture ? 'mánuði' : 'mánuðum');\n            } else if (withoutSuffix) {\n                return result + 'mánuður';\n            }\n            return result + (isFuture ? 'mánuð' : 'mánuði');\n        case 'y':\n            return withoutSuffix || isFuture ? 'ár' : 'ári';\n        case 'yy':\n            if (is__plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'ár' : 'árum');\n            }\n            return result + (withoutSuffix || isFuture ? 'ár' : 'ári');\n        }\n    }\n\n    var is = moment.defineLocale('is', {\n        months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'),\n        weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'),\n        weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'),\n        weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY [kl.] LT',\n            LLLL : 'dddd, D. MMMM YYYY [kl.] LT'\n        },\n        calendar : {\n            sameDay : '[í dag kl.] LT',\n            nextDay : '[á morgun kl.] LT',\n            nextWeek : 'dddd [kl.] LT',\n            lastDay : '[í gær kl.] LT',\n            lastWeek : '[síðasta] dddd [kl.] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'eftir %s',\n            past : 'fyrir %s síðan',\n            s : is__translate,\n            m : is__translate,\n            mm : is__translate,\n            h : 'klukkustund',\n            hh : is__translate,\n            d : is__translate,\n            dd : is__translate,\n            M : is__translate,\n            MM : is__translate,\n            y : is__translate,\n            yy : is__translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var it = moment.defineLocale('it', {\n        months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'),\n        monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),\n        weekdays : 'Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato'.split('_'),\n        weekdaysShort : 'Dom_Lun_Mar_Mer_Gio_Ven_Sab'.split('_'),\n        weekdaysMin : 'D_L_Ma_Me_G_V_S'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Oggi alle] LT',\n            nextDay: '[Domani alle] LT',\n            nextWeek: 'dddd [alle] LT',\n            lastDay: '[Ieri alle] LT',\n            lastWeek: function () {\n                switch (this.day()) {\n                    case 0:\n                        return '[la scorsa] dddd [alle] LT';\n                    default:\n                        return '[lo scorso] dddd [alle] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : function (s) {\n                return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s;\n            },\n            past : '%s fa',\n            s : 'alcuni secondi',\n            m : 'un minuto',\n            mm : '%d minuti',\n            h : 'un\\'ora',\n            hh : '%d ore',\n            d : 'un giorno',\n            dd : '%d giorni',\n            M : 'un mese',\n            MM : '%d mesi',\n            y : 'un anno',\n            yy : '%d anni'\n        },\n        ordinalParse : /\\d{1,2}º/,\n        ordinal: '%dº',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var ja = moment.defineLocale('ja', {\n        months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n        monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n        weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),\n        weekdaysShort : '日_月_火_水_木_金_土'.split('_'),\n        weekdaysMin : '日_月_火_水_木_金_土'.split('_'),\n        longDateFormat : {\n            LT : 'Ah時m分',\n            LTS : 'LTs秒',\n            L : 'YYYY/MM/DD',\n            LL : 'YYYY年M月D日',\n            LLL : 'YYYY年M月D日LT',\n            LLLL : 'YYYY年M月D日LT dddd'\n        },\n        meridiemParse: /午前|午後/i,\n        isPM : function (input) {\n            return input === '午後';\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return '午前';\n            } else {\n                return '午後';\n            }\n        },\n        calendar : {\n            sameDay : '[今日] LT',\n            nextDay : '[明日] LT',\n            nextWeek : '[来週]dddd LT',\n            lastDay : '[昨日] LT',\n            lastWeek : '[前週]dddd LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s後',\n            past : '%s前',\n            s : '数秒',\n            m : '1分',\n            mm : '%d分',\n            h : '1時間',\n            hh : '%d時間',\n            d : '1日',\n            dd : '%d日',\n            M : '1ヶ月',\n            MM : '%dヶ月',\n            y : '1年',\n            yy : '%d年'\n        }\n    });\n\n    function ka__monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),\n            'accusative': 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')\n        },\n        nounCase = (/D[oD] *MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function ka__weekdaysCaseReplace(m, format) {\n        var weekdays = {\n            'nominative': 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),\n            'accusative': 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_')\n        },\n        nounCase = (/(წინა|შემდეგ)/).test(format) ?\n            'accusative' :\n            'nominative';\n        return weekdays[nounCase][m.day()];\n    }\n\n    var ka = moment.defineLocale('ka', {\n        months : ka__monthsCaseReplace,\n        monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'),\n        weekdays : ka__weekdaysCaseReplace,\n        weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'),\n        weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'),\n        longDateFormat : {\n            LT : 'h:mm A',\n            LTS : 'h:mm:ss A',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[დღეს] LT[-ზე]',\n            nextDay : '[ხვალ] LT[-ზე]',\n            lastDay : '[გუშინ] LT[-ზე]',\n            nextWeek : '[შემდეგ] dddd LT[-ზე]',\n            lastWeek : '[წინა] dddd LT-ზე',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : function (s) {\n                return (/(წამი|წუთი|საათი|წელი)/).test(s) ?\n                    s.replace(/ი$/, 'ში') :\n                    s + 'ში';\n            },\n            past : function (s) {\n                if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {\n                    return s.replace(/(ი|ე)$/, 'ის წინ');\n                }\n                if ((/წელი/).test(s)) {\n                    return s.replace(/წელი$/, 'წლის წინ');\n                }\n            },\n            s : 'რამდენიმე წამი',\n            m : 'წუთი',\n            mm : '%d წუთი',\n            h : 'საათი',\n            hh : '%d საათი',\n            d : 'დღე',\n            dd : '%d დღე',\n            M : 'თვე',\n            MM : '%d თვე',\n            y : 'წელი',\n            yy : '%d წელი'\n        },\n        ordinalParse: /0|1-ლი|მე-\\d{1,2}|\\d{1,2}-ე/,\n        ordinal : function (number) {\n            if (number === 0) {\n                return number;\n            }\n            if (number === 1) {\n                return number + '-ლი';\n            }\n            if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {\n                return 'მე-' + number;\n            }\n            return number + '-ე';\n        },\n        week : {\n            dow : 1,\n            doy : 7\n        }\n    });\n\n    var km = moment.defineLocale('km', {\n        months: 'មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n        monthsShort: 'មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n        weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n        weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n        weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n        longDateFormat: {\n            LT: 'HH:mm',\n            LTS : 'LT:ss',\n            L: 'DD/MM/YYYY',\n            LL: 'D MMMM YYYY',\n            LLL: 'D MMMM YYYY LT',\n            LLLL: 'dddd, D MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[ថ្ងៃនៈ ម៉ោង] LT',\n            nextDay: '[ស្អែក ម៉ោង] LT',\n            nextWeek: 'dddd [ម៉ោង] LT',\n            lastDay: '[ម្សិលមិញ ម៉ោង] LT',\n            lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',\n            sameElse: 'L'\n        },\n        relativeTime: {\n            future: '%sទៀត',\n            past: '%sមុន',\n            s: 'ប៉ុន្មានវិនាទី',\n            m: 'មួយនាទី',\n            mm: '%d នាទី',\n            h: 'មួយម៉ោង',\n            hh: '%d ម៉ោង',\n            d: 'មួយថ្ងៃ',\n            dd: '%d ថ្ងៃ',\n            M: 'មួយខែ',\n            MM: '%d ខែ',\n            y: 'មួយឆ្នាំ',\n            yy: '%d ឆ្នាំ'\n        },\n        week: {\n            dow: 1, // Monday is the first day of the week.\n            doy: 4 // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var ko = moment.defineLocale('ko', {\n        months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n        monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n        weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),\n        weekdaysShort : '일_월_화_수_목_금_토'.split('_'),\n        weekdaysMin : '일_월_화_수_목_금_토'.split('_'),\n        longDateFormat : {\n            LT : 'A h시 m분',\n            LTS : 'A h시 m분 s초',\n            L : 'YYYY.MM.DD',\n            LL : 'YYYY년 MMMM D일',\n            LLL : 'YYYY년 MMMM D일 LT',\n            LLLL : 'YYYY년 MMMM D일 dddd LT'\n        },\n        calendar : {\n            sameDay : '오늘 LT',\n            nextDay : '내일 LT',\n            nextWeek : 'dddd LT',\n            lastDay : '어제 LT',\n            lastWeek : '지난주 dddd LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s 후',\n            past : '%s 전',\n            s : '몇초',\n            ss : '%d초',\n            m : '일분',\n            mm : '%d분',\n            h : '한시간',\n            hh : '%d시간',\n            d : '하루',\n            dd : '%d일',\n            M : '한달',\n            MM : '%d달',\n            y : '일년',\n            yy : '%d년'\n        },\n        ordinalParse : /\\d{1,2}일/,\n        ordinal : '%d일',\n        meridiemParse : /오전|오후/,\n        isPM : function (token) {\n            return token === '오후';\n        },\n        meridiem : function (hour, minute, isUpper) {\n            return hour < 12 ? '오전' : '오후';\n        }\n    });\n\n    function lb__processRelativeTime(number, withoutSuffix, key, isFuture) {\n        var format = {\n            'm': ['eng Minutt', 'enger Minutt'],\n            'h': ['eng Stonn', 'enger Stonn'],\n            'd': ['een Dag', 'engem Dag'],\n            'M': ['ee Mount', 'engem Mount'],\n            'y': ['ee Joer', 'engem Joer']\n        };\n        return withoutSuffix ? format[key][0] : format[key][1];\n    }\n    function processFutureTime(string) {\n        var number = string.substr(0, string.indexOf(' '));\n        if (eifelerRegelAppliesToNumber(number)) {\n            return 'a ' + string;\n        }\n        return 'an ' + string;\n    }\n    function processPastTime(string) {\n        var number = string.substr(0, string.indexOf(' '));\n        if (eifelerRegelAppliesToNumber(number)) {\n            return 'viru ' + string;\n        }\n        return 'virun ' + string;\n    }\n        function eifelerRegelAppliesToNumber(number) {\n        number = parseInt(number, 10);\n        if (isNaN(number)) {\n            return false;\n        }\n        if (number < 0) {\n            return true;\n        } else if (number < 10) {\n            if (4 <= number && number <= 7) {\n                return true;\n            }\n            return false;\n        } else if (number < 100) {\n            var lastDigit = number % 10, firstDigit = number / 10;\n            if (lastDigit === 0) {\n                return eifelerRegelAppliesToNumber(firstDigit);\n            }\n            return eifelerRegelAppliesToNumber(lastDigit);\n        } else if (number < 10000) {\n            while (number >= 10) {\n                number = number / 10;\n            }\n            return eifelerRegelAppliesToNumber(number);\n        } else {\n            number = number / 1000;\n            return eifelerRegelAppliesToNumber(number);\n        }\n    }\n\n    var lb = moment.defineLocale('lb', {\n        months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n        monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n        weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'),\n        weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'),\n        weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'),\n        longDateFormat: {\n            LT: 'H:mm [Auer]',\n            LTS: 'H:mm:ss [Auer]',\n            L: 'DD.MM.YYYY',\n            LL: 'D. MMMM YYYY',\n            LLL: 'D. MMMM YYYY LT',\n            LLLL: 'dddd, D. MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[Haut um] LT',\n            sameElse: 'L',\n            nextDay: '[Muer um] LT',\n            nextWeek: 'dddd [um] LT',\n            lastDay: '[Gëschter um] LT',\n            lastWeek: function () {\n                switch (this.day()) {\n                    case 2:\n                    case 4:\n                        return '[Leschten] dddd [um] LT';\n                    default:\n                        return '[Leschte] dddd [um] LT';\n                }\n            }\n        },\n        relativeTime : {\n            future : processFutureTime,\n            past : processPastTime,\n            s : 'e puer Sekonnen',\n            m : lb__processRelativeTime,\n            mm : '%d Minutten',\n            h : lb__processRelativeTime,\n            hh : '%d Stonnen',\n            d : lb__processRelativeTime,\n            dd : '%d Deeg',\n            M : lb__processRelativeTime,\n            MM : '%d Méint',\n            y : lb__processRelativeTime,\n            yy : '%d Joer'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal: '%d.',\n        week: {\n            dow: 1, // Monday is the first day of the week.\n            doy: 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var lt__units = {\n        'm' : 'minutė_minutės_minutę',\n        'mm': 'minutės_minučių_minutes',\n        'h' : 'valanda_valandos_valandą',\n        'hh': 'valandos_valandų_valandas',\n        'd' : 'diena_dienos_dieną',\n        'dd': 'dienos_dienų_dienas',\n        'M' : 'mėnuo_mėnesio_mėnesį',\n        'MM': 'mėnesiai_mėnesių_mėnesius',\n        'y' : 'metai_metų_metus',\n        'yy': 'metai_metų_metus'\n    },\n    weekDays = 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_');\n    function translateSeconds(number, withoutSuffix, key, isFuture) {\n        if (withoutSuffix) {\n            return 'kelios sekundės';\n        } else {\n            return isFuture ? 'kelių sekundžių' : 'kelias sekundes';\n        }\n    }\n    function translateSingular(number, withoutSuffix, key, isFuture) {\n        return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);\n    }\n    function special(number) {\n        return number % 10 === 0 || (number > 10 && number < 20);\n    }\n    function forms(key) {\n        return lt__units[key].split('_');\n    }\n    function lt__translate(number, withoutSuffix, key, isFuture) {\n        var result = number + ' ';\n        if (number === 1) {\n            return result + translateSingular(number, withoutSuffix, key[0], isFuture);\n        } else if (withoutSuffix) {\n            return result + (special(number) ? forms(key)[1] : forms(key)[0]);\n        } else {\n            if (isFuture) {\n                return result + forms(key)[1];\n            } else {\n                return result + (special(number) ? forms(key)[1] : forms(key)[2]);\n            }\n        }\n    }\n    function relativeWeekDay(moment, format) {\n        var nominative = format.indexOf('dddd HH:mm') === -1,\n            weekDay = weekDays[moment.day()];\n        return nominative ? weekDay : weekDay.substring(0, weekDay.length - 2) + 'į';\n    }\n\n    var lt = moment.defineLocale('lt', {\n        months : 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),\n        monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),\n        weekdays : relativeWeekDay,\n        weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),\n        weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'YYYY [m.] MMMM D [d.]',\n            LLL : 'YYYY [m.] MMMM D [d.], LT [val.]',\n            LLLL : 'YYYY [m.] MMMM D [d.], dddd, LT [val.]',\n            l : 'YYYY-MM-DD',\n            ll : 'YYYY [m.] MMMM D [d.]',\n            lll : 'YYYY [m.] MMMM D [d.], LT [val.]',\n            llll : 'YYYY [m.] MMMM D [d.], ddd, LT [val.]'\n        },\n        calendar : {\n            sameDay : '[Šiandien] LT',\n            nextDay : '[Rytoj] LT',\n            nextWeek : 'dddd LT',\n            lastDay : '[Vakar] LT',\n            lastWeek : '[Praėjusį] dddd LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'po %s',\n            past : 'prieš %s',\n            s : translateSeconds,\n            m : translateSingular,\n            mm : lt__translate,\n            h : translateSingular,\n            hh : lt__translate,\n            d : translateSingular,\n            dd : lt__translate,\n            M : translateSingular,\n            MM : lt__translate,\n            y : translateSingular,\n            yy : lt__translate\n        },\n        ordinalParse: /\\d{1,2}-oji/,\n        ordinal : function (number) {\n            return number + '-oji';\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var lv__units = {\n        'mm': 'minūti_minūtes_minūte_minūtes',\n        'hh': 'stundu_stundas_stunda_stundas',\n        'dd': 'dienu_dienas_diena_dienas',\n        'MM': 'mēnesi_mēnešus_mēnesis_mēneši',\n        'yy': 'gadu_gadus_gads_gadi'\n    };\n    function format(word, number, withoutSuffix) {\n        var forms = word.split('_');\n        if (withoutSuffix) {\n            return number % 10 === 1 && number !== 11 ? forms[2] : forms[3];\n        } else {\n            return number % 10 === 1 && number !== 11 ? forms[0] : forms[1];\n        }\n    }\n    function lv__relativeTimeWithPlural(number, withoutSuffix, key) {\n        return number + ' ' + format(lv__units[key], number, withoutSuffix);\n    }\n\n    var lv = moment.defineLocale('lv', {\n        months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'),\n        weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'),\n        weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'),\n        weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'YYYY. [gada] D. MMMM',\n            LLL : 'YYYY. [gada] D. MMMM, LT',\n            LLLL : 'YYYY. [gada] D. MMMM, dddd, LT'\n        },\n        calendar : {\n            sameDay : '[Šodien pulksten] LT',\n            nextDay : '[Rīt pulksten] LT',\n            nextWeek : 'dddd [pulksten] LT',\n            lastDay : '[Vakar pulksten] LT',\n            lastWeek : '[Pagājušā] dddd [pulksten] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s vēlāk',\n            past : '%s agrāk',\n            s : 'dažas sekundes',\n            m : 'minūti',\n            mm : lv__relativeTimeWithPlural,\n            h : 'stundu',\n            hh : lv__relativeTimeWithPlural,\n            d : 'dienu',\n            dd : lv__relativeTimeWithPlural,\n            M : 'mēnesi',\n            MM : lv__relativeTimeWithPlural,\n            y : 'gadu',\n            yy : lv__relativeTimeWithPlural\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var mk = moment.defineLocale('mk', {\n        months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'),\n        monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'),\n        weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'),\n        weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'),\n        weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'D.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Денес во] LT',\n            nextDay : '[Утре во] LT',\n            nextWeek : 'dddd [во] LT',\n            lastDay : '[Вчера во] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[Во изминатата] dddd [во] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[Во изминатиот] dddd [во] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'после %s',\n            past : 'пред %s',\n            s : 'неколку секунди',\n            m : 'минута',\n            mm : '%d минути',\n            h : 'час',\n            hh : '%d часа',\n            d : 'ден',\n            dd : '%d дена',\n            M : 'месец',\n            MM : '%d месеци',\n            y : 'година',\n            yy : '%d години'\n        },\n        ordinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n        ordinal : function (number) {\n            var lastDigit = number % 10,\n                last2Digits = number % 100;\n            if (number === 0) {\n                return number + '-ев';\n            } else if (last2Digits === 0) {\n                return number + '-ен';\n            } else if (last2Digits > 10 && last2Digits < 20) {\n                return number + '-ти';\n            } else if (lastDigit === 1) {\n                return number + '-ви';\n            } else if (lastDigit === 2) {\n                return number + '-ри';\n            } else if (lastDigit === 7 || lastDigit === 8) {\n                return number + '-ми';\n            } else {\n                return number + '-ти';\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var ml = moment.defineLocale('ml', {\n        months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'),\n        monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'),\n        weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'),\n        weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'),\n        weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm -നു',\n            LTS : 'A h:mm:ss -നു',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        calendar : {\n            sameDay : '[ഇന്ന്] LT',\n            nextDay : '[നാളെ] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[ഇന്നലെ] LT',\n            lastWeek : '[കഴിഞ്ഞ] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s കഴിഞ്ഞ്',\n            past : '%s മുൻപ്',\n            s : 'അൽപ നിമിഷങ്ങൾ',\n            m : 'ഒരു മിനിറ്റ്',\n            mm : '%d മിനിറ്റ്',\n            h : 'ഒരു മണിക്കൂർ',\n            hh : '%d മണിക്കൂർ',\n            d : 'ഒരു ദിവസം',\n            dd : '%d ദിവസം',\n            M : 'ഒരു മാസം',\n            MM : '%d മാസം',\n            y : 'ഒരു വർഷം',\n            yy : '%d വർഷം'\n        },\n        meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,\n        isPM : function (input) {\n            return /^(ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'രാത്രി';\n            } else if (hour < 12) {\n                return 'രാവിലെ';\n            } else if (hour < 17) {\n                return 'ഉച്ച കഴിഞ്ഞ്';\n            } else if (hour < 20) {\n                return 'വൈകുന്നേരം';\n            } else {\n                return 'രാത്രി';\n            }\n        }\n    });\n\n    var mr__symbolMap = {\n        '1': '१',\n        '2': '२',\n        '3': '३',\n        '4': '४',\n        '5': '५',\n        '6': '६',\n        '7': '७',\n        '8': '८',\n        '9': '९',\n        '0': '०'\n    },\n    mr__numberMap = {\n        '१': '1',\n        '२': '2',\n        '३': '3',\n        '४': '4',\n        '५': '5',\n        '६': '6',\n        '७': '7',\n        '८': '8',\n        '९': '9',\n        '०': '0'\n    };\n\n    var mr = moment.defineLocale('mr', {\n        months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'),\n        monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'),\n        weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n        weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),\n        weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm वाजता',\n            LTS : 'A h:mm:ss वाजता',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        calendar : {\n            sameDay : '[आज] LT',\n            nextDay : '[उद्या] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[काल] LT',\n            lastWeek: '[मागील] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s नंतर',\n            past : '%s पूर्वी',\n            s : 'सेकंद',\n            m: 'एक मिनिट',\n            mm: '%d मिनिटे',\n            h : 'एक तास',\n            hh : '%d तास',\n            d : 'एक दिवस',\n            dd : '%d दिवस',\n            M : 'एक महिना',\n            MM : '%d महिने',\n            y : 'एक वर्ष',\n            yy : '%d वर्षे'\n        },\n        preparse: function (string) {\n            return string.replace(/[१२३४५६७८९०]/g, function (match) {\n                return mr__numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return mr__symbolMap[match];\n            });\n        },\n        meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'रात्री') {\n                return hour < 4 ? hour : hour + 12;\n            } else if (meridiem === 'सकाळी') {\n                return hour;\n            } else if (meridiem === 'दुपारी') {\n                return hour >= 10 ? hour : hour + 12;\n            } else if (meridiem === 'सायंकाळी') {\n                return hour + 12;\n            }\n        },\n        meridiem: function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'रात्री';\n            } else if (hour < 10) {\n                return 'सकाळी';\n            } else if (hour < 17) {\n                return 'दुपारी';\n            } else if (hour < 20) {\n                return 'सायंकाळी';\n            } else {\n                return 'रात्री';\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var ms_my = moment.defineLocale('ms-my', {\n        months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n        monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n        weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n        weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n        weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n        longDateFormat : {\n            LT : 'HH.mm',\n            LTS : 'LT.ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY [pukul] LT',\n            LLLL : 'dddd, D MMMM YYYY [pukul] LT'\n        },\n        meridiemParse: /pagi|tengahari|petang|malam/,\n        meridiemHour: function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'pagi') {\n                return hour;\n            } else if (meridiem === 'tengahari') {\n                return hour >= 11 ? hour : hour + 12;\n            } else if (meridiem === 'petang' || meridiem === 'malam') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours < 11) {\n                return 'pagi';\n            } else if (hours < 15) {\n                return 'tengahari';\n            } else if (hours < 19) {\n                return 'petang';\n            } else {\n                return 'malam';\n            }\n        },\n        calendar : {\n            sameDay : '[Hari ini pukul] LT',\n            nextDay : '[Esok pukul] LT',\n            nextWeek : 'dddd [pukul] LT',\n            lastDay : '[Kelmarin pukul] LT',\n            lastWeek : 'dddd [lepas pukul] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'dalam %s',\n            past : '%s yang lepas',\n            s : 'beberapa saat',\n            m : 'seminit',\n            mm : '%d minit',\n            h : 'sejam',\n            hh : '%d jam',\n            d : 'sehari',\n            dd : '%d hari',\n            M : 'sebulan',\n            MM : '%d bulan',\n            y : 'setahun',\n            yy : '%d tahun'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var my__symbolMap = {\n        '1': '၁',\n        '2': '၂',\n        '3': '၃',\n        '4': '၄',\n        '5': '၅',\n        '6': '၆',\n        '7': '၇',\n        '8': '၈',\n        '9': '၉',\n        '0': '၀'\n    }, my__numberMap = {\n        '၁': '1',\n        '၂': '2',\n        '၃': '3',\n        '၄': '4',\n        '၅': '5',\n        '၆': '6',\n        '၇': '7',\n        '၈': '8',\n        '၉': '9',\n        '၀': '0'\n    };\n\n    var my = moment.defineLocale('my', {\n        months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'),\n        monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'),\n        weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'),\n        weekdaysShort: 'နွေ_လာ_င်္ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n        weekdaysMin: 'နွေ_လာ_င်္ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n        longDateFormat: {\n            LT: 'HH:mm',\n            LTS: 'HH:mm:ss',\n            L: 'DD/MM/YYYY',\n            LL: 'D MMMM YYYY',\n            LLL: 'D MMMM YYYY LT',\n            LLLL: 'dddd D MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[ယနေ.] LT [မှာ]',\n            nextDay: '[မနက်ဖြန်] LT [မှာ]',\n            nextWeek: 'dddd LT [မှာ]',\n            lastDay: '[မနေ.က] LT [မှာ]',\n            lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]',\n            sameElse: 'L'\n        },\n        relativeTime: {\n            future: 'လာမည့် %s မှာ',\n            past: 'လွန်ခဲ့သော %s က',\n            s: 'စက္ကန်.အနည်းငယ်',\n            m: 'တစ်မိနစ်',\n            mm: '%d မိနစ်',\n            h: 'တစ်နာရီ',\n            hh: '%d နာရီ',\n            d: 'တစ်ရက်',\n            dd: '%d ရက်',\n            M: 'တစ်လ',\n            MM: '%d လ',\n            y: 'တစ်နှစ်',\n            yy: '%d နှစ်'\n        },\n        preparse: function (string) {\n            return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) {\n                return my__numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return my__symbolMap[match];\n            });\n        },\n        week: {\n            dow: 1, // Monday is the first day of the week.\n            doy: 4 // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var nb = moment.defineLocale('nb', {\n        months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n        weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n        weekdaysShort : 'søn_man_tirs_ons_tors_fre_lør'.split('_'),\n        weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n        longDateFormat : {\n            LT : 'H.mm',\n            LTS : 'LT.ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY [kl.] LT',\n            LLLL : 'dddd D. MMMM YYYY [kl.] LT'\n        },\n        calendar : {\n            sameDay: '[i dag kl.] LT',\n            nextDay: '[i morgen kl.] LT',\n            nextWeek: 'dddd [kl.] LT',\n            lastDay: '[i går kl.] LT',\n            lastWeek: '[forrige] dddd [kl.] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'om %s',\n            past : 'for %s siden',\n            s : 'noen sekunder',\n            m : 'ett minutt',\n            mm : '%d minutter',\n            h : 'en time',\n            hh : '%d timer',\n            d : 'en dag',\n            dd : '%d dager',\n            M : 'en måned',\n            MM : '%d måneder',\n            y : 'ett år',\n            yy : '%d år'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var ne__symbolMap = {\n        '1': '१',\n        '2': '२',\n        '3': '३',\n        '4': '४',\n        '5': '५',\n        '6': '६',\n        '7': '७',\n        '8': '८',\n        '9': '९',\n        '0': '०'\n    },\n    ne__numberMap = {\n        '१': '1',\n        '२': '2',\n        '३': '3',\n        '४': '4',\n        '५': '5',\n        '६': '6',\n        '७': '7',\n        '८': '8',\n        '९': '9',\n        '०': '0'\n    };\n\n    var ne = moment.defineLocale('ne', {\n        months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'),\n        monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'),\n        weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'),\n        weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'),\n        weekdaysMin : 'आइ._सो._मङ्_बु._बि._शु._श.'.split('_'),\n        longDateFormat : {\n            LT : 'Aको h:mm बजे',\n            LTS : 'Aको h:mm:ss बजे',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        preparse: function (string) {\n            return string.replace(/[१२३४५६७८९०]/g, function (match) {\n                return ne__numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return ne__symbolMap[match];\n            });\n        },\n        meridiemParse: /राती|बिहान|दिउँसो|बेलुका|साँझ|राती/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'राती') {\n                return hour < 3 ? hour : hour + 12;\n            } else if (meridiem === 'बिहान') {\n                return hour;\n            } else if (meridiem === 'दिउँसो') {\n                return hour >= 10 ? hour : hour + 12;\n            } else if (meridiem === 'बेलुका' || meridiem === 'साँझ') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 3) {\n                return 'राती';\n            } else if (hour < 10) {\n                return 'बिहान';\n            } else if (hour < 15) {\n                return 'दिउँसो';\n            } else if (hour < 18) {\n                return 'बेलुका';\n            } else if (hour < 20) {\n                return 'साँझ';\n            } else {\n                return 'राती';\n            }\n        },\n        calendar : {\n            sameDay : '[आज] LT',\n            nextDay : '[भोली] LT',\n            nextWeek : '[आउँदो] dddd[,] LT',\n            lastDay : '[हिजो] LT',\n            lastWeek : '[गएको] dddd[,] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%sमा',\n            past : '%s अगाडी',\n            s : 'केही समय',\n            m : 'एक मिनेट',\n            mm : '%d मिनेट',\n            h : 'एक घण्टा',\n            hh : '%d घण्टा',\n            d : 'एक दिन',\n            dd : '%d दिन',\n            M : 'एक महिना',\n            MM : '%d महिना',\n            y : 'एक बर्ष',\n            yy : '%d बर्ष'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var nl__monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n        nl__monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\n    var nl = moment.defineLocale('nl', {\n        months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n        monthsShort : function (m, format) {\n            if (/-MMM-/.test(format)) {\n                return nl__monthsShortWithoutDots[m.month()];\n            } else {\n                return nl__monthsShortWithDots[m.month()];\n            }\n        },\n        weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n        weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n        weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD-MM-YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[vandaag om] LT',\n            nextDay: '[morgen om] LT',\n            nextWeek: 'dddd [om] LT',\n            lastDay: '[gisteren om] LT',\n            lastWeek: '[afgelopen] dddd [om] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'over %s',\n            past : '%s geleden',\n            s : 'een paar seconden',\n            m : 'één minuut',\n            mm : '%d minuten',\n            h : 'één uur',\n            hh : '%d uur',\n            d : 'één dag',\n            dd : '%d dagen',\n            M : 'één maand',\n            MM : '%d maanden',\n            y : 'één jaar',\n            yy : '%d jaar'\n        },\n        ordinalParse: /\\d{1,2}(ste|de)/,\n        ordinal : function (number) {\n            return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var nn = moment.defineLocale('nn', {\n        months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n        weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'),\n        weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'),\n        weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[I dag klokka] LT',\n            nextDay: '[I morgon klokka] LT',\n            nextWeek: 'dddd [klokka] LT',\n            lastDay: '[I går klokka] LT',\n            lastWeek: '[Føregåande] dddd [klokka] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'om %s',\n            past : 'for %s sidan',\n            s : 'nokre sekund',\n            m : 'eit minutt',\n            mm : '%d minutt',\n            h : 'ein time',\n            hh : '%d timar',\n            d : 'ein dag',\n            dd : '%d dagar',\n            M : 'ein månad',\n            MM : '%d månader',\n            y : 'eit år',\n            yy : '%d år'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_'),\n        monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_');\n    function pl__plural(n) {\n        return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);\n    }\n    function pl__translate(number, withoutSuffix, key) {\n        var result = number + ' ';\n        switch (key) {\n        case 'm':\n            return withoutSuffix ? 'minuta' : 'minutę';\n        case 'mm':\n            return result + (pl__plural(number) ? 'minuty' : 'minut');\n        case 'h':\n            return withoutSuffix  ? 'godzina'  : 'godzinę';\n        case 'hh':\n            return result + (pl__plural(number) ? 'godziny' : 'godzin');\n        case 'MM':\n            return result + (pl__plural(number) ? 'miesiące' : 'miesięcy');\n        case 'yy':\n            return result + (pl__plural(number) ? 'lata' : 'lat');\n        }\n    }\n\n    var pl = moment.defineLocale('pl', {\n        months : function (momentToFormat, format) {\n            if (/D MMMM/.test(format)) {\n                return monthsSubjective[momentToFormat.month()];\n            } else {\n                return monthsNominative[momentToFormat.month()];\n            }\n        },\n        monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),\n        weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'),\n        weekdaysShort : 'nie_pon_wt_śr_czw_pt_sb'.split('_'),\n        weekdaysMin : 'N_Pn_Wt_Śr_Cz_Pt_So'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Dziś o] LT',\n            nextDay: '[Jutro o] LT',\n            nextWeek: '[W] dddd [o] LT',\n            lastDay: '[Wczoraj o] LT',\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[W zeszłą niedzielę o] LT';\n                case 3:\n                    return '[W zeszłą środę o] LT';\n                case 6:\n                    return '[W zeszłą sobotę o] LT';\n                default:\n                    return '[W zeszły] dddd [o] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past : '%s temu',\n            s : 'kilka sekund',\n            m : pl__translate,\n            mm : pl__translate,\n            h : pl__translate,\n            hh : pl__translate,\n            d : '1 dzień',\n            dd : '%d dni',\n            M : 'miesiąc',\n            MM : pl__translate,\n            y : 'rok',\n            yy : pl__translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var pt_br = moment.defineLocale('pt-br', {\n        months : 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split('_'),\n        monthsShort : 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'),\n        weekdays : 'domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado'.split('_'),\n        weekdaysShort : 'dom_seg_ter_qua_qui_sex_sáb'.split('_'),\n        weekdaysMin : 'dom_2ª_3ª_4ª_5ª_6ª_sáb'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D [de] MMMM [de] YYYY',\n            LLL : 'D [de] MMMM [de] YYYY [às] LT',\n            LLLL : 'dddd, D [de] MMMM [de] YYYY [às] LT'\n        },\n        calendar : {\n            sameDay: '[Hoje às] LT',\n            nextDay: '[Amanhã às] LT',\n            nextWeek: 'dddd [às] LT',\n            lastDay: '[Ontem às] LT',\n            lastWeek: function () {\n                return (this.day() === 0 || this.day() === 6) ?\n                    '[Último] dddd [às] LT' : // Saturday + Sunday\n                    '[Última] dddd [às] LT'; // Monday - Friday\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'em %s',\n            past : '%s atrás',\n            s : 'segundos',\n            m : 'um minuto',\n            mm : '%d minutos',\n            h : 'uma hora',\n            hh : '%d horas',\n            d : 'um dia',\n            dd : '%d dias',\n            M : 'um mês',\n            MM : '%d meses',\n            y : 'um ano',\n            yy : '%d anos'\n        },\n        ordinalParse: /\\d{1,2}º/,\n        ordinal : '%dº'\n    });\n\n    var pt = moment.defineLocale('pt', {\n        months : 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split('_'),\n        monthsShort : 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'),\n        weekdays : 'domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado'.split('_'),\n        weekdaysShort : 'dom_seg_ter_qua_qui_sex_sáb'.split('_'),\n        weekdaysMin : 'dom_2ª_3ª_4ª_5ª_6ª_sáb'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D [de] MMMM [de] YYYY',\n            LLL : 'D [de] MMMM [de] YYYY LT',\n            LLLL : 'dddd, D [de] MMMM [de] YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Hoje às] LT',\n            nextDay: '[Amanhã às] LT',\n            nextWeek: 'dddd [às] LT',\n            lastDay: '[Ontem às] LT',\n            lastWeek: function () {\n                return (this.day() === 0 || this.day() === 6) ?\n                    '[Último] dddd [às] LT' : // Saturday + Sunday\n                    '[Última] dddd [às] LT'; // Monday - Friday\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'em %s',\n            past : 'há %s',\n            s : 'segundos',\n            m : 'um minuto',\n            mm : '%d minutos',\n            h : 'uma hora',\n            hh : '%d horas',\n            d : 'um dia',\n            dd : '%d dias',\n            M : 'um mês',\n            MM : '%d meses',\n            y : 'um ano',\n            yy : '%d anos'\n        },\n        ordinalParse: /\\d{1,2}º/,\n        ordinal : '%dº',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    function ro__relativeTimeWithPlural(number, withoutSuffix, key) {\n        var format = {\n                'mm': 'minute',\n                'hh': 'ore',\n                'dd': 'zile',\n                'MM': 'luni',\n                'yy': 'ani'\n            },\n            separator = ' ';\n        if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {\n            separator = ' de ';\n        }\n        return number + separator + format[key];\n    }\n\n    var ro = moment.defineLocale('ro', {\n        months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'),\n        monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'),\n        weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'),\n        weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'),\n        weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY H:mm',\n            LLLL : 'dddd, D MMMM YYYY H:mm'\n        },\n        calendar : {\n            sameDay: '[azi la] LT',\n            nextDay: '[mâine la] LT',\n            nextWeek: 'dddd [la] LT',\n            lastDay: '[ieri la] LT',\n            lastWeek: '[fosta] dddd [la] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'peste %s',\n            past : '%s în urmă',\n            s : 'câteva secunde',\n            m : 'un minut',\n            mm : ro__relativeTimeWithPlural,\n            h : 'o oră',\n            hh : ro__relativeTimeWithPlural,\n            d : 'o zi',\n            dd : ro__relativeTimeWithPlural,\n            M : 'o lună',\n            MM : ro__relativeTimeWithPlural,\n            y : 'un an',\n            yy : ro__relativeTimeWithPlural\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    function ru__plural(word, num) {\n        var forms = word.split('_');\n        return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n    }\n    function ru__relativeTimeWithPlural(number, withoutSuffix, key) {\n        var format = {\n            'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',\n            'hh': 'час_часа_часов',\n            'dd': 'день_дня_дней',\n            'MM': 'месяц_месяца_месяцев',\n            'yy': 'год_года_лет'\n        };\n        if (key === 'm') {\n            return withoutSuffix ? 'минута' : 'минуту';\n        }\n        else {\n            return number + ' ' + ru__plural(format[key], +number);\n        }\n    }\n    function ru__monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n            'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')\n        },\n        nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function ru__monthsShortCaseReplace(m, format) {\n        var monthsShort = {\n            'nominative': 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),\n            'accusative': 'янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек'.split('_')\n        },\n        nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return monthsShort[nounCase][m.month()];\n    }\n    function ru__weekdaysCaseReplace(m, format) {\n        var weekdays = {\n            'nominative': 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),\n            'accusative': 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_')\n        },\n        nounCase = (/\\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\\] ?dddd/).test(format) ?\n            'accusative' :\n            'nominative';\n        return weekdays[nounCase][m.day()];\n    }\n\n    var ru = moment.defineLocale('ru', {\n        months : ru__monthsCaseReplace,\n        monthsShort : ru__monthsShortCaseReplace,\n        weekdays : ru__weekdaysCaseReplace,\n        weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n        weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n        monthsParse : [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[й|я]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i],\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY г.',\n            LLL : 'D MMMM YYYY г., LT',\n            LLLL : 'dddd, D MMMM YYYY г., LT'\n        },\n        calendar : {\n            sameDay: '[Сегодня в] LT',\n            nextDay: '[Завтра в] LT',\n            lastDay: '[Вчера в] LT',\n            nextWeek: function () {\n                return this.day() === 2 ? '[Во] dddd [в] LT' : '[В] dddd [в] LT';\n            },\n            lastWeek: function (now) {\n                if (now.week() !== this.week()) {\n                    switch (this.day()) {\n                    case 0:\n                        return '[В прошлое] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В прошлый] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В прошлую] dddd [в] LT';\n                    }\n                } else {\n                    if (this.day() === 2) {\n                        return '[Во] dddd [в] LT';\n                    } else {\n                        return '[В] dddd [в] LT';\n                    }\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'через %s',\n            past : '%s назад',\n            s : 'несколько секунд',\n            m : ru__relativeTimeWithPlural,\n            mm : ru__relativeTimeWithPlural,\n            h : 'час',\n            hh : ru__relativeTimeWithPlural,\n            d : 'день',\n            dd : ru__relativeTimeWithPlural,\n            M : 'месяц',\n            MM : ru__relativeTimeWithPlural,\n            y : 'год',\n            yy : ru__relativeTimeWithPlural\n        },\n        meridiemParse: /ночи|утра|дня|вечера/i,\n        isPM : function (input) {\n            return /^(дня|вечера)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'ночи';\n            } else if (hour < 12) {\n                return 'утра';\n            } else if (hour < 17) {\n                return 'дня';\n            } else {\n                return 'вечера';\n            }\n        },\n        ordinalParse: /\\d{1,2}-(й|го|я)/,\n        ordinal: function (number, period) {\n            switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            case 'w':\n            case 'W':\n                return number + '-я';\n            default:\n                return number;\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var sk__months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_'),\n        sk__monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_');\n    function sk__plural(n) {\n        return (n > 1) && (n < 5);\n    }\n    function sk__translate(number, withoutSuffix, key, isFuture) {\n        var result = number + ' ';\n        switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (sk__plural(number) ? 'minúty' : 'minút');\n            } else {\n                return result + 'minútami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (sk__plural(number) ? 'hodiny' : 'hodín');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'deň' : 'dňom';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (sk__plural(number) ? 'dni' : 'dní');\n            } else {\n                return result + 'dňami';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (sk__plural(number) ? 'mesiace' : 'mesiacov');\n            } else {\n                return result + 'mesiacmi';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokom';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (sk__plural(number) ? 'roky' : 'rokov');\n            } else {\n                return result + 'rokmi';\n            }\n            break;\n        }\n    }\n\n    var sk = moment.defineLocale('sk', {\n        months : sk__months,\n        monthsShort : sk__monthsShort,\n        monthsParse : (function (months, monthsShort) {\n            var i, _monthsParse = [];\n            for (i = 0; i < 12; i++) {\n                _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');\n            }\n            return _monthsParse;\n        }(sk__months, sk__monthsShort)),\n        weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'),\n        weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'),\n        weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),\n        longDateFormat : {\n            LT: 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[dnes o] LT',\n            nextDay: '[zajtra o] LT',\n            nextWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[v nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [o] LT';\n                case 3:\n                    return '[v stredu o] LT';\n                case 4:\n                    return '[vo štvrtok o] LT';\n                case 5:\n                    return '[v piatok o] LT';\n                case 6:\n                    return '[v sobotu o] LT';\n                }\n            },\n            lastDay: '[včera o] LT',\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[minulú nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[minulý] dddd [o] LT';\n                case 3:\n                    return '[minulú stredu o] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [o] LT';\n                case 6:\n                    return '[minulú sobotu o] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past : 'pred %s',\n            s : sk__translate,\n            m : sk__translate,\n            mm : sk__translate,\n            h : sk__translate,\n            hh : sk__translate,\n            d : sk__translate,\n            dd : sk__translate,\n            M : sk__translate,\n            MM : sk__translate,\n            y : sk__translate,\n            yy : sk__translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    function sl__translate(number, withoutSuffix, key) {\n        var result = number + ' ';\n        switch (key) {\n        case 'm':\n            return withoutSuffix ? 'ena minuta' : 'eno minuto';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2) {\n                result += 'minuti';\n            } else if (number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minut';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'ena ura' : 'eno uro';\n        case 'hh':\n            if (number === 1) {\n                result += 'ura';\n            } else if (number === 2) {\n                result += 'uri';\n            } else if (number === 3 || number === 4) {\n                result += 'ure';\n            } else {\n                result += 'ur';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dni';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mesec';\n            } else if (number === 2) {\n                result += 'meseca';\n            } else if (number === 3 || number === 4) {\n                result += 'mesece';\n            } else {\n                result += 'mesecev';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'leto';\n            } else if (number === 2) {\n                result += 'leti';\n            } else if (number === 3 || number === 4) {\n                result += 'leta';\n            } else {\n                result += 'let';\n            }\n            return result;\n        }\n    }\n\n    var sl = moment.defineLocale('sl', {\n        months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'),\n        monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'),\n        weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'),\n        weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'),\n        weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD. MM. YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd, D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay  : '[danes ob] LT',\n            nextDay  : '[jutri ob] LT',\n            nextWeek : function () {\n                switch (this.day()) {\n                case 0:\n                    return '[v] [nedeljo] [ob] LT';\n                case 3:\n                    return '[v] [sredo] [ob] LT';\n                case 6:\n                    return '[v] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[v] dddd [ob] LT';\n                }\n            },\n            lastDay  : '[včeraj ob] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[prejšnja] dddd [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prejšnji] dddd [ob] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'čez %s',\n            past   : '%s nazaj',\n            s      : 'nekaj sekund',\n            m      : sl__translate,\n            mm     : sl__translate,\n            h      : sl__translate,\n            hh     : sl__translate,\n            d      : 'en dan',\n            dd     : sl__translate,\n            M      : 'en mesec',\n            MM     : sl__translate,\n            y      : 'eno leto',\n            yy     : sl__translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var sq = moment.defineLocale('sq', {\n        months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'),\n        monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'),\n        weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'),\n        weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'),\n        weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'),\n        meridiemParse: /PD|MD/,\n        isPM: function (input) {\n            return input.charAt(0) === 'M';\n        },\n        meridiem : function (hours, minutes, isLower) {\n            return hours < 12 ? 'PD' : 'MD';\n        },\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Sot në] LT',\n            nextDay : '[Nesër në] LT',\n            nextWeek : 'dddd [në] LT',\n            lastDay : '[Dje në] LT',\n            lastWeek : 'dddd [e kaluar në] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'në %s',\n            past : '%s më parë',\n            s : 'disa sekonda',\n            m : 'një minutë',\n            mm : '%d minuta',\n            h : 'një orë',\n            hh : '%d orë',\n            d : 'një ditë',\n            dd : '%d ditë',\n            M : 'një muaj',\n            MM : '%d muaj',\n            y : 'një vit',\n            yy : '%d vite'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var sr_cyrl__translator = {\n        words: { //Different grammatical cases\n            m: ['један минут', 'једне минуте'],\n            mm: ['минут', 'минуте', 'минута'],\n            h: ['један сат', 'једног сата'],\n            hh: ['сат', 'сата', 'сати'],\n            dd: ['дан', 'дана', 'дана'],\n            MM: ['месец', 'месеца', 'месеци'],\n            yy: ['година', 'године', 'година']\n        },\n        correctGrammaticalCase: function (number, wordKey) {\n            return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n        },\n        translate: function (number, withoutSuffix, key) {\n            var wordKey = sr_cyrl__translator.words[key];\n            if (key.length === 1) {\n                return withoutSuffix ? wordKey[0] : wordKey[1];\n            } else {\n                return number + ' ' + sr_cyrl__translator.correctGrammaticalCase(number, wordKey);\n            }\n        }\n    };\n\n    var sr_cyrl = moment.defineLocale('sr-cyrl', {\n        months: ['јануар', 'фебруар', 'март', 'април', 'мај', 'јун', 'јул', 'август', 'септембар', 'октобар', 'новембар', 'децембар'],\n        monthsShort: ['јан.', 'феб.', 'мар.', 'апр.', 'мај', 'јун', 'јул', 'авг.', 'сеп.', 'окт.', 'нов.', 'дец.'],\n        weekdays: ['недеља', 'понедељак', 'уторак', 'среда', 'четвртак', 'петак', 'субота'],\n        weekdaysShort: ['нед.', 'пон.', 'уто.', 'сре.', 'чет.', 'пет.', 'суб.'],\n        weekdaysMin: ['не', 'по', 'ут', 'ср', 'че', 'пе', 'су'],\n        longDateFormat: {\n            LT: 'H:mm',\n            LTS : 'LT:ss',\n            L: 'DD. MM. YYYY',\n            LL: 'D. MMMM YYYY',\n            LLL: 'D. MMMM YYYY LT',\n            LLLL: 'dddd, D. MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[данас у] LT',\n            nextDay: '[сутра у] LT',\n            nextWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[у] [недељу] [у] LT';\n                case 3:\n                    return '[у] [среду] [у] LT';\n                case 6:\n                    return '[у] [суботу] [у] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[у] dddd [у] LT';\n                }\n            },\n            lastDay  : '[јуче у] LT',\n            lastWeek : function () {\n                var lastWeekDays = [\n                    '[прошле] [недеље] [у] LT',\n                    '[прошлог] [понедељка] [у] LT',\n                    '[прошлог] [уторка] [у] LT',\n                    '[прошле] [среде] [у] LT',\n                    '[прошлог] [четвртка] [у] LT',\n                    '[прошлог] [петка] [у] LT',\n                    '[прошле] [суботе] [у] LT'\n                ];\n                return lastWeekDays[this.day()];\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'за %s',\n            past   : 'пре %s',\n            s      : 'неколико секунди',\n            m      : sr_cyrl__translator.translate,\n            mm     : sr_cyrl__translator.translate,\n            h      : sr_cyrl__translator.translate,\n            hh     : sr_cyrl__translator.translate,\n            d      : 'дан',\n            dd     : sr_cyrl__translator.translate,\n            M      : 'месец',\n            MM     : sr_cyrl__translator.translate,\n            y      : 'годину',\n            yy     : sr_cyrl__translator.translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var sr__translator = {\n        words: { //Different grammatical cases\n            m: ['jedan minut', 'jedne minute'],\n            mm: ['minut', 'minute', 'minuta'],\n            h: ['jedan sat', 'jednog sata'],\n            hh: ['sat', 'sata', 'sati'],\n            dd: ['dan', 'dana', 'dana'],\n            MM: ['mesec', 'meseca', 'meseci'],\n            yy: ['godina', 'godine', 'godina']\n        },\n        correctGrammaticalCase: function (number, wordKey) {\n            return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n        },\n        translate: function (number, withoutSuffix, key) {\n            var wordKey = sr__translator.words[key];\n            if (key.length === 1) {\n                return withoutSuffix ? wordKey[0] : wordKey[1];\n            } else {\n                return number + ' ' + sr__translator.correctGrammaticalCase(number, wordKey);\n            }\n        }\n    };\n\n    var sr = moment.defineLocale('sr', {\n        months: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'],\n        monthsShort: ['jan.', 'feb.', 'mar.', 'apr.', 'maj', 'jun', 'jul', 'avg.', 'sep.', 'okt.', 'nov.', 'dec.'],\n        weekdays: ['nedelja', 'ponedeljak', 'utorak', 'sreda', 'četvrtak', 'petak', 'subota'],\n        weekdaysShort: ['ned.', 'pon.', 'uto.', 'sre.', 'čet.', 'pet.', 'sub.'],\n        weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],\n        longDateFormat: {\n            LT: 'H:mm',\n            LTS : 'LT:ss',\n            L: 'DD. MM. YYYY',\n            LL: 'D. MMMM YYYY',\n            LLL: 'D. MMMM YYYY LT',\n            LLLL: 'dddd, D. MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[danas u] LT',\n            nextDay: '[sutra u] LT',\n            nextWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[u] [nedelju] [u] LT';\n                case 3:\n                    return '[u] [sredu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n                }\n            },\n            lastDay  : '[juče u] LT',\n            lastWeek : function () {\n                var lastWeekDays = [\n                    '[prošle] [nedelje] [u] LT',\n                    '[prošlog] [ponedeljka] [u] LT',\n                    '[prošlog] [utorka] [u] LT',\n                    '[prošle] [srede] [u] LT',\n                    '[prošlog] [četvrtka] [u] LT',\n                    '[prošlog] [petka] [u] LT',\n                    '[prošle] [subote] [u] LT'\n                ];\n                return lastWeekDays[this.day()];\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past   : 'pre %s',\n            s      : 'nekoliko sekundi',\n            m      : sr__translator.translate,\n            mm     : sr__translator.translate,\n            h      : sr__translator.translate,\n            hh     : sr__translator.translate,\n            d      : 'dan',\n            dd     : sr__translator.translate,\n            M      : 'mesec',\n            MM     : sr__translator.translate,\n            y      : 'godinu',\n            yy     : sr__translator.translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var sv = moment.defineLocale('sv', {\n        months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n        weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),\n        weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'),\n        weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Idag] LT',\n            nextDay: '[Imorgon] LT',\n            lastDay: '[Igår] LT',\n            nextWeek: 'dddd LT',\n            lastWeek: '[Förra] dddd[en] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'om %s',\n            past : 'för %s sedan',\n            s : 'några sekunder',\n            m : 'en minut',\n            mm : '%d minuter',\n            h : 'en timme',\n            hh : '%d timmar',\n            d : 'en dag',\n            dd : '%d dagar',\n            M : 'en månad',\n            MM : '%d månader',\n            y : 'ett år',\n            yy : '%d år'\n        },\n        ordinalParse: /\\d{1,2}(e|a)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (~~(number % 100 / 10) === 1) ? 'e' :\n                (b === 1) ? 'a' :\n                (b === 2) ? 'a' :\n                (b === 3) ? 'e' : 'e';\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var ta = moment.defineLocale('ta', {\n        months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n        monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n        weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'),\n        weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'),\n        weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        calendar : {\n            sameDay : '[இன்று] LT',\n            nextDay : '[நாளை] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[நேற்று] LT',\n            lastWeek : '[கடந்த வாரம்] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s இல்',\n            past : '%s முன்',\n            s : 'ஒரு சில விநாடிகள்',\n            m : 'ஒரு நிமிடம்',\n            mm : '%d நிமிடங்கள்',\n            h : 'ஒரு மணி நேரம்',\n            hh : '%d மணி நேரம்',\n            d : 'ஒரு நாள்',\n            dd : '%d நாட்கள்',\n            M : 'ஒரு மாதம்',\n            MM : '%d மாதங்கள்',\n            y : 'ஒரு வருடம்',\n            yy : '%d ஆண்டுகள்'\n        },\n        ordinalParse: /\\d{1,2}வது/,\n        ordinal : function (number) {\n            return number + 'வது';\n        },\n        meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 2) {\n                return ' யாமம்';\n            } else if (hour < 6) {\n                return ' வைகறை';  // வைகறை\n            } else if (hour < 10) {\n                return ' காலை'; // காலை\n            } else if (hour < 14) {\n                return ' நண்பகல்'; // நண்பகல்\n            } else if (hour < 18) {\n                return ' எற்பாடு'; // எற்பாடு\n            } else if (hour < 22) {\n                return ' மாலை'; // மாலை\n            } else {\n                return ' யாமம்';\n            }\n        },\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'யாமம்') {\n                return hour < 2 ? hour : hour + 12;\n            } else if (meridiem === 'வைகறை' || meridiem === 'காலை') {\n                return hour;\n            } else if (meridiem === 'நண்பகல்') {\n                return hour >= 10 ? hour : hour + 12;\n            } else {\n                return hour + 12;\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var th = moment.defineLocale('th', {\n        months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'),\n        monthsShort : 'มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา'.split('_'),\n        weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'),\n        weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference\n        weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),\n        longDateFormat : {\n            LT : 'H นาฬิกา m นาที',\n            LTS : 'LT s วินาที',\n            L : 'YYYY/MM/DD',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY เวลา LT',\n            LLLL : 'วันddddที่ D MMMM YYYY เวลา LT'\n        },\n        meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,\n        isPM: function (input) {\n            return input === 'หลังเที่ยง';\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return 'ก่อนเที่ยง';\n            } else {\n                return 'หลังเที่ยง';\n            }\n        },\n        calendar : {\n            sameDay : '[วันนี้ เวลา] LT',\n            nextDay : '[พรุ่งนี้ เวลา] LT',\n            nextWeek : 'dddd[หน้า เวลา] LT',\n            lastDay : '[เมื่อวานนี้ เวลา] LT',\n            lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'อีก %s',\n            past : '%sที่แล้ว',\n            s : 'ไม่กี่วินาที',\n            m : '1 นาที',\n            mm : '%d นาที',\n            h : '1 ชั่วโมง',\n            hh : '%d ชั่วโมง',\n            d : '1 วัน',\n            dd : '%d วัน',\n            M : '1 เดือน',\n            MM : '%d เดือน',\n            y : '1 ปี',\n            yy : '%d ปี'\n        }\n    });\n\n    var tl_ph = moment.defineLocale('tl-ph', {\n        months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'),\n        monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),\n        weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'),\n        weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),\n        weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'MM/D/YYYY',\n            LL : 'MMMM D, YYYY',\n            LLL : 'MMMM D, YYYY LT',\n            LLLL : 'dddd, MMMM DD, YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Ngayon sa] LT',\n            nextDay: '[Bukas sa] LT',\n            nextWeek: 'dddd [sa] LT',\n            lastDay: '[Kahapon sa] LT',\n            lastWeek: 'dddd [huling linggo] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'sa loob ng %s',\n            past : '%s ang nakalipas',\n            s : 'ilang segundo',\n            m : 'isang minuto',\n            mm : '%d minuto',\n            h : 'isang oras',\n            hh : '%d oras',\n            d : 'isang araw',\n            dd : '%d araw',\n            M : 'isang buwan',\n            MM : '%d buwan',\n            y : 'isang taon',\n            yy : '%d taon'\n        },\n        ordinalParse: /\\d{1,2}/,\n        ordinal : function (number) {\n            return number;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var tr__suffixes = {\n        1: '\\'inci',\n        5: '\\'inci',\n        8: '\\'inci',\n        70: '\\'inci',\n        80: '\\'inci',\n        2: '\\'nci',\n        7: '\\'nci',\n        20: '\\'nci',\n        50: '\\'nci',\n        3: '\\'üncü',\n        4: '\\'üncü',\n        100: '\\'üncü',\n        6: '\\'ncı',\n        9: '\\'uncu',\n        10: '\\'uncu',\n        30: '\\'uncu',\n        60: '\\'ıncı',\n        90: '\\'ıncı'\n    };\n\n    var tr = moment.defineLocale('tr', {\n        months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),\n        monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),\n        weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),\n        weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),\n        weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[bugün saat] LT',\n            nextDay : '[yarın saat] LT',\n            nextWeek : '[haftaya] dddd [saat] LT',\n            lastDay : '[dün] LT',\n            lastWeek : '[geçen hafta] dddd [saat] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s sonra',\n            past : '%s önce',\n            s : 'birkaç saniye',\n            m : 'bir dakika',\n            mm : '%d dakika',\n            h : 'bir saat',\n            hh : '%d saat',\n            d : 'bir gün',\n            dd : '%d gün',\n            M : 'bir ay',\n            MM : '%d ay',\n            y : 'bir yıl',\n            yy : '%d yıl'\n        },\n        ordinalParse: /\\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,\n        ordinal : function (number) {\n            if (number === 0) {  // special case for zero\n                return number + '\\'ıncı';\n            }\n            var a = number % 10,\n                b = number % 100 - a,\n                c = number >= 100 ? 100 : null;\n            return number + (tr__suffixes[a] || tr__suffixes[b] || tr__suffixes[c]);\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var tzm_latn = moment.defineLocale('tzm-latn', {\n        months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n        monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n        weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n        weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n        weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[asdkh g] LT',\n            nextDay: '[aska g] LT',\n            nextWeek: 'dddd [g] LT',\n            lastDay: '[assant g] LT',\n            lastWeek: 'dddd [g] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'dadkh s yan %s',\n            past : 'yan %s',\n            s : 'imik',\n            m : 'minuḍ',\n            mm : '%d minuḍ',\n            h : 'saɛa',\n            hh : '%d tassaɛin',\n            d : 'ass',\n            dd : '%d ossan',\n            M : 'ayowr',\n            MM : '%d iyyirn',\n            y : 'asgas',\n            yy : '%d isgasn'\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var tzm = moment.defineLocale('tzm', {\n        months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n        monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n        weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n        weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n        weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS: 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',\n            nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',\n            nextWeek: 'dddd [ⴴ] LT',\n            lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',\n            lastWeek: 'dddd [ⴴ] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s',\n            past : 'ⵢⴰⵏ %s',\n            s : 'ⵉⵎⵉⴽ',\n            m : 'ⵎⵉⵏⵓⴺ',\n            mm : '%d ⵎⵉⵏⵓⴺ',\n            h : 'ⵙⴰⵄⴰ',\n            hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ',\n            d : 'ⴰⵙⵙ',\n            dd : '%d oⵙⵙⴰⵏ',\n            M : 'ⴰⵢoⵓⵔ',\n            MM : '%d ⵉⵢⵢⵉⵔⵏ',\n            y : 'ⴰⵙⴳⴰⵙ',\n            yy : '%d ⵉⵙⴳⴰⵙⵏ'\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    function uk__plural(word, num) {\n        var forms = word.split('_');\n        return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n    }\n    function uk__relativeTimeWithPlural(number, withoutSuffix, key) {\n        var format = {\n            'mm': 'хвилина_хвилини_хвилин',\n            'hh': 'година_години_годин',\n            'dd': 'день_дні_днів',\n            'MM': 'місяць_місяці_місяців',\n            'yy': 'рік_роки_років'\n        };\n        if (key === 'm') {\n            return withoutSuffix ? 'хвилина' : 'хвилину';\n        }\n        else if (key === 'h') {\n            return withoutSuffix ? 'година' : 'годину';\n        }\n        else {\n            return number + ' ' + uk__plural(format[key], +number);\n        }\n    }\n    function uk__monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_'),\n            'accusative': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_')\n        },\n        nounCase = (/D[oD]? *MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function uk__weekdaysCaseReplace(m, format) {\n        var weekdays = {\n            'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),\n            'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),\n            'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')\n        },\n        nounCase = (/(\\[[ВвУу]\\]) ?dddd/).test(format) ?\n            'accusative' :\n            ((/\\[?(?:минулої|наступної)? ?\\] ?dddd/).test(format) ?\n                'genitive' :\n                'nominative');\n        return weekdays[nounCase][m.day()];\n    }\n    function processHoursFunction(str) {\n        return function () {\n            return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';\n        };\n    }\n\n    var uk = moment.defineLocale('uk', {\n        months : uk__monthsCaseReplace,\n        monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),\n        weekdays : uk__weekdaysCaseReplace,\n        weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n        weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY р.',\n            LLL : 'D MMMM YYYY р., LT',\n            LLLL : 'dddd, D MMMM YYYY р., LT'\n        },\n        calendar : {\n            sameDay: processHoursFunction('[Сьогодні '),\n            nextDay: processHoursFunction('[Завтра '),\n            lastDay: processHoursFunction('[Вчора '),\n            nextWeek: processHoursFunction('[У] dddd ['),\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return processHoursFunction('[Минулої] dddd [').call(this);\n                case 1:\n                case 2:\n                case 4:\n                    return processHoursFunction('[Минулого] dddd [').call(this);\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'за %s',\n            past : '%s тому',\n            s : 'декілька секунд',\n            m : uk__relativeTimeWithPlural,\n            mm : uk__relativeTimeWithPlural,\n            h : 'годину',\n            hh : uk__relativeTimeWithPlural,\n            d : 'день',\n            dd : uk__relativeTimeWithPlural,\n            M : 'місяць',\n            MM : uk__relativeTimeWithPlural,\n            y : 'рік',\n            yy : uk__relativeTimeWithPlural\n        },\n        meridiemParse: /ночі|ранку|дня|вечора/,\n        isPM: function (input) {\n            return /^(дня|вечора)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'ночі';\n            } else if (hour < 12) {\n                return 'ранку';\n            } else if (hour < 17) {\n                return 'дня';\n            } else {\n                return 'вечора';\n            }\n        },\n        ordinalParse: /\\d{1,2}-(й|го)/,\n        ordinal: function (number, period) {\n            switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            default:\n                return number;\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var uz = moment.defineLocale('uz', {\n        months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n        monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),\n        weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'),\n        weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'),\n        weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'D MMMM YYYY, dddd LT'\n        },\n        calendar : {\n            sameDay : '[Бугун соат] LT [да]',\n            nextDay : '[Эртага] LT [да]',\n            nextWeek : 'dddd [куни соат] LT [да]',\n            lastDay : '[Кеча соат] LT [да]',\n            lastWeek : '[Утган] dddd [куни соат] LT [да]',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'Якин %s ичида',\n            past : 'Бир неча %s олдин',\n            s : 'фурсат',\n            m : 'бир дакика',\n            mm : '%d дакика',\n            h : 'бир соат',\n            hh : '%d соат',\n            d : 'бир кун',\n            dd : '%d кун',\n            M : 'бир ой',\n            MM : '%d ой',\n            y : 'бир йил',\n            yy : '%d йил'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var vi = moment.defineLocale('vi', {\n        months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'),\n        monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'),\n        weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'),\n        weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n        weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM [năm] YYYY',\n            LLL : 'D MMMM [năm] YYYY LT',\n            LLLL : 'dddd, D MMMM [năm] YYYY LT',\n            l : 'DD/M/YYYY',\n            ll : 'D MMM YYYY',\n            lll : 'D MMM YYYY LT',\n            llll : 'ddd, D MMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Hôm nay lúc] LT',\n            nextDay: '[Ngày mai lúc] LT',\n            nextWeek: 'dddd [tuần tới lúc] LT',\n            lastDay: '[Hôm qua lúc] LT',\n            lastWeek: 'dddd [tuần rồi lúc] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : '%s tới',\n            past : '%s trước',\n            s : 'vài giây',\n            m : 'một phút',\n            mm : '%d phút',\n            h : 'một giờ',\n            hh : '%d giờ',\n            d : 'một ngày',\n            dd : '%d ngày',\n            M : 'một tháng',\n            MM : '%d tháng',\n            y : 'một năm',\n            yy : '%d năm'\n        },\n        ordinalParse: /\\d{1,2}/,\n        ordinal : function (number) {\n            return number;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var zh_cn = moment.defineLocale('zh-cn', {\n        months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n        monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n        weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n        weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'),\n        weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n        longDateFormat : {\n            LT : 'Ah点mm',\n            LTS : 'Ah点m分s秒',\n            L : 'YYYY-MM-DD',\n            LL : 'YYYY年MMMD日',\n            LLL : 'YYYY年MMMD日LT',\n            LLLL : 'YYYY年MMMD日ddddLT',\n            l : 'YYYY-MM-DD',\n            ll : 'YYYY年MMMD日',\n            lll : 'YYYY年MMMD日LT',\n            llll : 'YYYY年MMMD日ddddLT'\n        },\n        meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n        meridiemHour: function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === '凌晨' || meridiem === '早上' ||\n                    meridiem === '上午') {\n                return hour;\n            } else if (meridiem === '下午' || meridiem === '晚上') {\n                return hour + 12;\n            } else {\n                return hour >= 11 ? hour : hour + 12;\n            }\n        },\n        meridiem : function (hour, minute, isLower) {\n            var hm = hour * 100 + minute;\n            if (hm < 600) {\n                return '凌晨';\n            } else if (hm < 900) {\n                return '早上';\n            } else if (hm < 1130) {\n                return '上午';\n            } else if (hm < 1230) {\n                return '中午';\n            } else if (hm < 1800) {\n                return '下午';\n            } else {\n                return '晚上';\n            }\n        },\n        calendar : {\n            sameDay : function () {\n                return this.minutes() === 0 ? '[今天]Ah[点整]' : '[今天]LT';\n            },\n            nextDay : function () {\n                return this.minutes() === 0 ? '[明天]Ah[点整]' : '[明天]LT';\n            },\n            lastDay : function () {\n                return this.minutes() === 0 ? '[昨天]Ah[点整]' : '[昨天]LT';\n            },\n            nextWeek : function () {\n                var startOfWeek, prefix;\n                startOfWeek = moment().startOf('week');\n                prefix = this.unix() - startOfWeek.unix() >= 7 * 24 * 3600 ? '[下]' : '[本]';\n                return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';\n            },\n            lastWeek : function () {\n                var startOfWeek, prefix;\n                startOfWeek = moment().startOf('week');\n                prefix = this.unix() < startOfWeek.unix()  ? '[上]' : '[本]';\n                return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';\n            },\n            sameElse : 'LL'\n        },\n        ordinalParse: /\\d{1,2}(日|月|周)/,\n        ordinal : function (number, period) {\n            switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            case 'M':\n                return number + '月';\n            case 'w':\n            case 'W':\n                return number + '周';\n            default:\n                return number;\n            }\n        },\n        relativeTime : {\n            future : '%s内',\n            past : '%s前',\n            s : '几秒',\n            m : '1分钟',\n            mm : '%d分钟',\n            h : '1小时',\n            hh : '%d小时',\n            d : '1天',\n            dd : '%d天',\n            M : '1个月',\n            MM : '%d个月',\n            y : '1年',\n            yy : '%d年'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var zh_tw = moment.defineLocale('zh-tw', {\n        months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n        monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n        weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n        weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n        weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n        longDateFormat : {\n            LT : 'Ah點mm',\n            LTS : 'Ah點m分s秒',\n            L : 'YYYY年MMMD日',\n            LL : 'YYYY年MMMD日',\n            LLL : 'YYYY年MMMD日LT',\n            LLLL : 'YYYY年MMMD日ddddLT',\n            l : 'YYYY年MMMD日',\n            ll : 'YYYY年MMMD日',\n            lll : 'YYYY年MMMD日LT',\n            llll : 'YYYY年MMMD日ddddLT'\n        },\n        meridiemParse: /早上|上午|中午|下午|晚上/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === '早上' || meridiem === '上午') {\n                return hour;\n            } else if (meridiem === '中午') {\n                return hour >= 11 ? hour : hour + 12;\n            } else if (meridiem === '下午' || meridiem === '晚上') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hour, minute, isLower) {\n            var hm = hour * 100 + minute;\n            if (hm < 900) {\n                return '早上';\n            } else if (hm < 1130) {\n                return '上午';\n            } else if (hm < 1230) {\n                return '中午';\n            } else if (hm < 1800) {\n                return '下午';\n            } else {\n                return '晚上';\n            }\n        },\n        calendar : {\n            sameDay : '[今天]LT',\n            nextDay : '[明天]LT',\n            nextWeek : '[下]ddddLT',\n            lastDay : '[昨天]LT',\n            lastWeek : '[上]ddddLT',\n            sameElse : 'L'\n        },\n        ordinalParse: /\\d{1,2}(日|月|週)/,\n        ordinal : function (number, period) {\n            switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n            }\n        },\n        relativeTime : {\n            future : '%s內',\n            past : '%s前',\n            s : '幾秒',\n            m : '一分鐘',\n            mm : '%d分鐘',\n            h : '一小時',\n            hh : '%d小時',\n            d : '一天',\n            dd : '%d天',\n            M : '一個月',\n            MM : '%d個月',\n            y : '一年',\n            yy : '%d年'\n        }\n    });\n\n\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/min/moment-with-locales.js",
    "content": "(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n    typeof define === 'function' && define.amd ? define(factory) :\n    global.moment = factory()\n}(this, function () { 'use strict';\n\n    var hookCallback;\n\n    function utils_hooks__hooks () {\n        return hookCallback.apply(null, arguments);\n    }\n    function setHookCallback (callback) {\n        hookCallback = callback;\n    }\n\n    function defaultParsingFlags() {\n        return {\n            empty           : false,\n            unusedTokens    : [],\n            unusedInput     : [],\n            overflow        : -2,\n            charsLeftOver   : 0,\n            nullInput       : false,\n            invalidMonth    : null,\n            invalidFormat   : false,\n            userInvalidated : false,\n            iso             : false\n        };\n    }\n\n    function isArray(input) {\n        return Object.prototype.toString.call(input) === '[object Array]';\n    }\n\n    function isDate(input) {\n        return Object.prototype.toString.call(input) === '[object Date]' || input instanceof Date;\n    }\n\n    function map(arr, fn) {\n        var res = [], i;\n        for (i = 0; i < arr.length; ++i) {\n            res.push(fn(arr[i], i));\n        }\n        return res;\n    }\n\n    function hasOwnProp(a, b) {\n        return Object.prototype.hasOwnProperty.call(a, b);\n    }\n\n    function extend(a, b) {\n        for (var i in b) {\n            if (hasOwnProp(b, i)) {\n                a[i] = b[i];\n            }\n        }\n\n        if (hasOwnProp(b, 'toString')) {\n            a.toString = b.toString;\n        }\n\n        if (hasOwnProp(b, 'valueOf')) {\n            a.valueOf = b.valueOf;\n        }\n\n        return a;\n    }\n\n    function create_utc__createUTC (input, format, locale, strict) {\n        return createLocalOrUTC(input, format, locale, strict, true).utc();\n    }\n\n    function valid__isValid(m) {\n        if (m._isValid == null) {\n            m._isValid = !isNaN(m._d.getTime()) &&\n                m._pf.overflow < 0 &&\n                !m._pf.empty &&\n                !m._pf.invalidMonth &&\n                !m._pf.nullInput &&\n                !m._pf.invalidFormat &&\n                !m._pf.userInvalidated;\n\n            if (m._strict) {\n                m._isValid = m._isValid &&\n                    m._pf.charsLeftOver === 0 &&\n                    m._pf.unusedTokens.length === 0 &&\n                    m._pf.bigHour === undefined;\n            }\n        }\n        return m._isValid;\n    }\n\n    function valid__createInvalid (flags) {\n        var m = create_utc__createUTC(NaN);\n        if (flags != null) {\n            extend(m._pf, flags);\n        }\n        else {\n            m._pf.userInvalidated = true;\n        }\n\n        return m;\n    }\n\n    var momentProperties = utils_hooks__hooks.momentProperties = [];\n\n    function copyConfig(to, from) {\n        var i, prop, val;\n\n        if (typeof from._isAMomentObject !== 'undefined') {\n            to._isAMomentObject = from._isAMomentObject;\n        }\n        if (typeof from._i !== 'undefined') {\n            to._i = from._i;\n        }\n        if (typeof from._f !== 'undefined') {\n            to._f = from._f;\n        }\n        if (typeof from._l !== 'undefined') {\n            to._l = from._l;\n        }\n        if (typeof from._strict !== 'undefined') {\n            to._strict = from._strict;\n        }\n        if (typeof from._tzm !== 'undefined') {\n            to._tzm = from._tzm;\n        }\n        if (typeof from._isUTC !== 'undefined') {\n            to._isUTC = from._isUTC;\n        }\n        if (typeof from._offset !== 'undefined') {\n            to._offset = from._offset;\n        }\n        if (typeof from._pf !== 'undefined') {\n            to._pf = from._pf;\n        }\n        if (typeof from._locale !== 'undefined') {\n            to._locale = from._locale;\n        }\n\n        if (momentProperties.length > 0) {\n            for (i in momentProperties) {\n                prop = momentProperties[i];\n                val = from[prop];\n                if (typeof val !== 'undefined') {\n                    to[prop] = val;\n                }\n            }\n        }\n\n        return to;\n    }\n\n    var updateInProgress = false;\n    function Moment(config) {\n        copyConfig(this, config);\n        this._d = new Date(+config._d);\n        if (updateInProgress === false) {\n            updateInProgress = true;\n            utils_hooks__hooks.updateOffset(this);\n            updateInProgress = false;\n        }\n    }\n\n    function isMoment (obj) {\n        return obj instanceof Moment || (obj != null && hasOwnProp(obj, '_isAMomentObject'));\n    }\n\n    function toInt(argumentForCoercion) {\n        var coercedNumber = +argumentForCoercion,\n            value = 0;\n\n        if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n            if (coercedNumber >= 0) {\n                value = Math.floor(coercedNumber);\n            } else {\n                value = Math.ceil(coercedNumber);\n            }\n        }\n\n        return value;\n    }\n\n    function compareArrays(array1, array2, dontConvert) {\n        var len = Math.min(array1.length, array2.length),\n            lengthDiff = Math.abs(array1.length - array2.length),\n            diffs = 0,\n            i;\n        for (i = 0; i < len; i++) {\n            if ((dontConvert && array1[i] !== array2[i]) ||\n                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n                diffs++;\n            }\n        }\n        return diffs + lengthDiff;\n    }\n\n    function Locale() {\n    }\n\n    var locales = {};\n    var globalLocale;\n\n    function normalizeLocale(key) {\n        return key ? key.toLowerCase().replace('_', '-') : key;\n    }\n    function chooseLocale(names) {\n        var i = 0, j, next, locale, split;\n\n        while (i < names.length) {\n            split = normalizeLocale(names[i]).split('-');\n            j = split.length;\n            next = normalizeLocale(names[i + 1]);\n            next = next ? next.split('-') : null;\n            while (j > 0) {\n                locale = loadLocale(split.slice(0, j).join('-'));\n                if (locale) {\n                    return locale;\n                }\n                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                    break;\n                }\n                j--;\n            }\n            i++;\n        }\n        return null;\n    }\n\n    function loadLocale(name) {\n        var oldLocale = null;\n        if (!locales[name] && typeof module !== 'undefined' &&\n                module && module.exports) {\n            try {\n                oldLocale = globalLocale._abbr;\n                require('./locale/' + name);\n                locale_locales__getSetGlobalLocale(oldLocale);\n            } catch (e) { }\n        }\n        return locales[name];\n    }\n    function locale_locales__getSetGlobalLocale (key, values) {\n        var data;\n        if (key) {\n            if (typeof values === 'undefined') {\n                data = locale_locales__getLocale(key);\n            }\n            else {\n                data = defineLocale(key, values);\n            }\n\n            if (data) {\n                globalLocale = data;\n            }\n        }\n\n        return globalLocale._abbr;\n    }\n\n    function defineLocale (name, values) {\n        if (values !== null) {\n            values.abbr = name;\n            if (!locales[name]) {\n                locales[name] = new Locale();\n            }\n            locales[name].set(values);\n            locale_locales__getSetGlobalLocale(name);\n\n            return locales[name];\n        } else {\n            delete locales[name];\n            return null;\n        }\n    }\n    function locale_locales__getLocale (key) {\n        var locale;\n\n        if (key && key._locale && key._locale._abbr) {\n            key = key._locale._abbr;\n        }\n\n        if (!key) {\n            return globalLocale;\n        }\n\n        if (!isArray(key)) {\n            locale = loadLocale(key);\n            if (locale) {\n                return locale;\n            }\n            key = [key];\n        }\n\n        return chooseLocale(key);\n    }\n\n    var aliases = {};\n\n    function addUnitAlias (unit, shorthand) {\n        var lowerCase = unit.toLowerCase();\n        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n    }\n\n    function normalizeUnits(units) {\n        return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n    }\n\n    function normalizeObjectUnits(inputObject) {\n        var normalizedInput = {},\n            normalizedProp,\n            prop;\n\n        for (prop in inputObject) {\n            if (hasOwnProp(inputObject, prop)) {\n                normalizedProp = normalizeUnits(prop);\n                if (normalizedProp) {\n                    normalizedInput[normalizedProp] = inputObject[prop];\n                }\n            }\n        }\n\n        return normalizedInput;\n    }\n\n    function makeGetSet (unit, keepTime) {\n        return function (value) {\n            if (value != null) {\n                get_set__set(this, unit, value);\n                utils_hooks__hooks.updateOffset(this, keepTime);\n                return this;\n            } else {\n                return get_set__get(this, unit);\n            }\n        };\n    }\n\n    function get_set__get (mom, unit) {\n        return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();\n    }\n\n    function get_set__set (mom, unit, value) {\n        return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n    }\n\n    function getSet (units, value) {\n        var unit;\n        if (typeof units === 'object') {\n            for (unit in units) {\n                this.set(unit, units[unit]);\n            }\n        } else {\n            units = normalizeUnits(units);\n            if (typeof this[units] === 'function') {\n                return this[units](value);\n            }\n        }\n        return this;\n    }\n\n    function zeroFill(number, targetLength, forceSign) {\n        var output = '' + Math.abs(number),\n            sign = number >= 0;\n\n        while (output.length < targetLength) {\n            output = '0' + output;\n        }\n        return (sign ? (forceSign ? '+' : '') : '-') + output;\n    }\n\n    var formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|x|X|zz?|ZZ?|.)/g;\n\n    var localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\n    var formatFunctions = {};\n\n    var formatTokenFunctions = {};\n    function addFormatToken (token, padded, ordinal, callback) {\n        var func = callback;\n        if (typeof callback === 'string') {\n            func = function () {\n                return this[callback]();\n            };\n        }\n        if (token) {\n            formatTokenFunctions[token] = func;\n        }\n        if (padded) {\n            formatTokenFunctions[padded[0]] = function () {\n                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n            };\n        }\n        if (ordinal) {\n            formatTokenFunctions[ordinal] = function () {\n                return this.localeData().ordinal(func.apply(this, arguments), token);\n            };\n        }\n    }\n\n    function removeFormattingTokens(input) {\n        if (input.match(/\\[[\\s\\S]/)) {\n            return input.replace(/^\\[|\\]$/g, '');\n        }\n        return input.replace(/\\\\/g, '');\n    }\n\n    function makeFormatFunction(format) {\n        var array = format.match(formattingTokens), i, length;\n\n        for (i = 0, length = array.length; i < length; i++) {\n            if (formatTokenFunctions[array[i]]) {\n                array[i] = formatTokenFunctions[array[i]];\n            } else {\n                array[i] = removeFormattingTokens(array[i]);\n            }\n        }\n\n        return function (mom) {\n            var output = '';\n            for (i = 0; i < length; i++) {\n                output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];\n            }\n            return output;\n        };\n    }\n    function formatMoment(m, format) {\n        if (!m.isValid()) {\n            return m.localeData().invalidDate();\n        }\n\n        format = expandFormat(format, m.localeData());\n\n        if (!formatFunctions[format]) {\n            formatFunctions[format] = makeFormatFunction(format);\n        }\n\n        return formatFunctions[format](m);\n    }\n\n    function expandFormat(format, locale) {\n        var i = 5;\n\n        function replaceLongDateFormatTokens(input) {\n            return locale.longDateFormat(input) || input;\n        }\n\n        localFormattingTokens.lastIndex = 0;\n        while (i >= 0 && localFormattingTokens.test(format)) {\n            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n            localFormattingTokens.lastIndex = 0;\n            i -= 1;\n        }\n\n        return format;\n    }\n\n    var match1         = /\\d/;            //       0 - 9\n    var match2         = /\\d\\d/;          //      00 - 99\n    var match3         = /\\d{3}/;         //     000 - 999\n    var match4         = /\\d{4}/;         //    0000 - 9999\n    var match6         = /[+-]?\\d{6}/;    // -999999 - 999999\n    var match1to2      = /\\d\\d?/;         //       0 - 99\n    var match1to3      = /\\d{1,3}/;       //       0 - 999\n    var match1to4      = /\\d{1,4}/;       //       0 - 9999\n    var match1to6      = /[+-]?\\d{1,6}/;  // -999999 - 999999\n\n    var matchUnsigned  = /\\d+/;           //       0 - inf\n    var matchSigned    = /[+-]?\\d+/;      //    -inf - inf\n\n    var matchOffset    = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\n\n    var matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n    var matchWord = /[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF\\/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i;\n\n    var regexes = {};\n\n    function addRegexToken (token, regex, strictRegex) {\n        regexes[token] = typeof regex === 'function' ? regex : function (isStrict) {\n            return (isStrict && strictRegex) ? strictRegex : regex;\n        };\n    }\n\n    function getParseRegexForToken (token, config) {\n        if (!hasOwnProp(regexes, token)) {\n            return new RegExp(unescapeFormat(token));\n        }\n\n        return regexes[token](config._strict, config._locale);\n    }\n    function unescapeFormat(s) {\n        return s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n            return p1 || p2 || p3 || p4;\n        }).replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n    }\n\n    var tokens = {};\n\n    function addParseToken (token, callback) {\n        var i, func = callback;\n        if (typeof token === 'string') {\n            token = [token];\n        }\n        if (typeof callback === 'number') {\n            func = function (input, array) {\n                array[callback] = toInt(input);\n            };\n        }\n        for (i = 0; i < token.length; i++) {\n            tokens[token[i]] = func;\n        }\n    }\n\n    function addWeekParseToken (token, callback) {\n        addParseToken(token, function (input, array, config, token) {\n            config._w = config._w || {};\n            callback(input, config._w, config, token);\n        });\n    }\n\n    function addTimeToArrayFromToken(token, input, config) {\n        if (input != null && hasOwnProp(tokens, token)) {\n            tokens[token](input, config._a, config, token);\n        }\n    }\n\n    var YEAR = 0;\n    var MONTH = 1;\n    var DATE = 2;\n    var HOUR = 3;\n    var MINUTE = 4;\n    var SECOND = 5;\n    var MILLISECOND = 6;\n\n    function daysInMonth(year, month) {\n        return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n    }\n\n    addFormatToken('M', ['MM', 2], 'Mo', function () {\n        return this.month() + 1;\n    });\n\n    addFormatToken('MMM', 0, 0, function (format) {\n        return this.localeData().monthsShort(this, format);\n    });\n\n    addFormatToken('MMMM', 0, 0, function (format) {\n        return this.localeData().months(this, format);\n    });\n\n    addUnitAlias('month', 'M');\n\n    addRegexToken('M',    match1to2);\n    addRegexToken('MM',   match1to2, match2);\n    addRegexToken('MMM',  matchWord);\n    addRegexToken('MMMM', matchWord);\n\n    addParseToken(['M', 'MM'], function (input, array) {\n        array[MONTH] = toInt(input) - 1;\n    });\n\n    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n        var month = config._locale.monthsParse(input, token, config._strict);\n        if (month != null) {\n            array[MONTH] = month;\n        } else {\n            config._pf.invalidMonth = input;\n        }\n    });\n\n    var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\n    function localeMonths (m) {\n        return this._months[m.month()];\n    }\n\n    var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\n    function localeMonthsShort (m) {\n        return this._monthsShort[m.month()];\n    }\n\n    function localeMonthsParse (monthName, format, strict) {\n        var i, mom, regex;\n\n        if (!this._monthsParse) {\n            this._monthsParse = [];\n            this._longMonthsParse = [];\n            this._shortMonthsParse = [];\n        }\n\n        for (i = 0; i < 12; i++) {\n            mom = create_utc__createUTC([2000, i]);\n            if (strict && !this._longMonthsParse[i]) {\n                this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n                this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n            }\n            if (!strict && !this._monthsParse[i]) {\n                regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n            }\n            if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n                return i;\n            } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n                return i;\n            } else if (!strict && this._monthsParse[i].test(monthName)) {\n                return i;\n            }\n        }\n    }\n\n    function setMonth (mom, value) {\n        var dayOfMonth;\n        if (typeof value === 'string') {\n            value = mom.localeData().monthsParse(value);\n            if (typeof value !== 'number') {\n                return mom;\n            }\n        }\n\n        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n        return mom;\n    }\n\n    function getSetMonth (value) {\n        if (value != null) {\n            setMonth(this, value);\n            utils_hooks__hooks.updateOffset(this, true);\n            return this;\n        } else {\n            return get_set__get(this, 'Month');\n        }\n    }\n\n    function getDaysInMonth () {\n        return daysInMonth(this.year(), this.month());\n    }\n\n    function checkOverflow (m) {\n        var overflow;\n        var a = m._a;\n\n        if (a && m._pf.overflow === -2) {\n            overflow =\n                a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :\n                a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n                a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n                a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :\n                a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :\n                a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n                -1;\n\n            if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n                overflow = DATE;\n            }\n\n            m._pf.overflow = overflow;\n        }\n\n        return m;\n    }\n\n    function warn(msg) {\n        if (utils_hooks__hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) {\n            console.warn('Deprecation warning: ' + msg);\n        }\n    }\n\n    function deprecate(msg, fn) {\n        var firstTime = true;\n        return extend(function () {\n            if (firstTime) {\n                warn(msg);\n                firstTime = false;\n            }\n            return fn.apply(this, arguments);\n        }, fn);\n    }\n\n    var deprecations = {};\n\n    function deprecateSimple(name, msg) {\n        if (!deprecations[name]) {\n            warn(msg);\n            deprecations[name] = true;\n        }\n    }\n\n    utils_hooks__hooks.suppressDeprecationWarnings = false;\n\n    var from_string__isoRegex = /^\\s*(?:[+-]\\d{6}|\\d{4})-(?:(\\d\\d-\\d\\d)|(W\\d\\d$)|(W\\d\\d-\\d)|(\\d\\d\\d))((T| )(\\d\\d(:\\d\\d(:\\d\\d(\\.\\d+)?)?)?)?([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\n    var isoDates = [\n        ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d{2}-\\d{2}/],\n        ['YYYY-MM-DD', /\\d{4}-\\d{2}-\\d{2}/],\n        ['GGGG-[W]WW-E', /\\d{4}-W\\d{2}-\\d/],\n        ['GGGG-[W]WW', /\\d{4}-W\\d{2}/],\n        ['YYYY-DDD', /\\d{4}-\\d{3}/]\n    ];\n    var isoTimes = [\n        ['HH:mm:ss.SSSS', /(T| )\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n        ['HH:mm:ss', /(T| )\\d\\d:\\d\\d:\\d\\d/],\n        ['HH:mm', /(T| )\\d\\d:\\d\\d/],\n        ['HH', /(T| )\\d\\d/]\n    ];\n\n    var aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n    function configFromISO(config) {\n        var i, l,\n            string = config._i,\n            match = from_string__isoRegex.exec(string);\n\n        if (match) {\n            config._pf.iso = true;\n            for (i = 0, l = isoDates.length; i < l; i++) {\n                if (isoDates[i][1].exec(string)) {\n                    config._f = isoDates[i][0] + (match[6] || ' ');\n                    break;\n                }\n            }\n            for (i = 0, l = isoTimes.length; i < l; i++) {\n                if (isoTimes[i][1].exec(string)) {\n                    config._f += isoTimes[i][0];\n                    break;\n                }\n            }\n            if (string.match(matchOffset)) {\n                config._f += 'Z';\n            }\n            configFromStringAndFormat(config);\n        } else {\n            config._isValid = false;\n        }\n    }\n    function configFromString(config) {\n        var matched = aspNetJsonRegex.exec(config._i);\n\n        if (matched !== null) {\n            config._d = new Date(+matched[1]);\n            return;\n        }\n\n        configFromISO(config);\n        if (config._isValid === false) {\n            delete config._isValid;\n            utils_hooks__hooks.createFromInputFallback(config);\n        }\n    }\n\n    utils_hooks__hooks.createFromInputFallback = deprecate(\n        'moment construction falls back to js Date. This is ' +\n        'discouraged and will be removed in upcoming major ' +\n        'release. Please refer to ' +\n        'https://github.com/moment/moment/issues/1407 for more info.',\n        function (config) {\n            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n        }\n    );\n\n    function createDate (y, m, d, h, M, s, ms) {\n        var date = new Date(y, m, d, h, M, s, ms);\n        if (y < 1970) {\n            date.setFullYear(y);\n        }\n        return date;\n    }\n\n    function createUTCDate (y) {\n        var date = new Date(Date.UTC.apply(null, arguments));\n        if (y < 1970) {\n            date.setUTCFullYear(y);\n        }\n        return date;\n    }\n\n    addFormatToken(0, ['YY', 2], 0, function () {\n        return this.year() % 100;\n    });\n\n    addFormatToken(0, ['YYYY',   4],       0, 'year');\n    addFormatToken(0, ['YYYYY',  5],       0, 'year');\n    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\n    addUnitAlias('year', 'y');\n\n    addRegexToken('Y',      matchSigned);\n    addRegexToken('YY',     match1to2, match2);\n    addRegexToken('YYYY',   match1to4, match4);\n    addRegexToken('YYYYY',  match1to6, match6);\n    addRegexToken('YYYYYY', match1to6, match6);\n\n    addParseToken(['YYYY', 'YYYYY', 'YYYYYY'], YEAR);\n    addParseToken('YY', function (input, array) {\n        array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input);\n    });\n\n    function daysInYear(year) {\n        return isLeapYear(year) ? 366 : 365;\n    }\n\n    function isLeapYear(year) {\n        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n    }\n\n    utils_hooks__hooks.parseTwoDigitYear = function (input) {\n        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n    };\n\n    var getSetYear = makeGetSet('FullYear', false);\n\n    function getIsLeapYear () {\n        return isLeapYear(this.year());\n    }\n\n    addFormatToken('w', ['ww', 2], 'wo', 'week');\n    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\n    addUnitAlias('week', 'w');\n    addUnitAlias('isoWeek', 'W');\n\n    addRegexToken('w',  match1to2);\n    addRegexToken('ww', match1to2, match2);\n    addRegexToken('W',  match1to2);\n    addRegexToken('WW', match1to2, match2);\n\n    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n        week[token.substr(0, 1)] = toInt(input);\n    });\n    function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {\n        var end = firstDayOfWeekOfYear - firstDayOfWeek,\n            daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),\n            adjustedMoment;\n\n\n        if (daysToDayOfWeek > end) {\n            daysToDayOfWeek -= 7;\n        }\n\n        if (daysToDayOfWeek < end - 7) {\n            daysToDayOfWeek += 7;\n        }\n\n        adjustedMoment = local__createLocal(mom).add(daysToDayOfWeek, 'd');\n        return {\n            week: Math.ceil(adjustedMoment.dayOfYear() / 7),\n            year: adjustedMoment.year()\n        };\n    }\n\n    function localeWeek (mom) {\n        return weekOfYear(mom, this._week.dow, this._week.doy).week;\n    }\n\n    var defaultLocaleWeek = {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    };\n\n    function localeFirstDayOfWeek () {\n        return this._week.dow;\n    }\n\n    function localeFirstDayOfYear () {\n        return this._week.doy;\n    }\n\n    function getSetWeek (input) {\n        var week = this.localeData().week(this);\n        return input == null ? week : this.add((input - week) * 7, 'd');\n    }\n\n    function getSetISOWeek (input) {\n        var week = weekOfYear(this, 1, 4).week;\n        return input == null ? week : this.add((input - week) * 7, 'd');\n    }\n\n    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\n    addUnitAlias('dayOfYear', 'DDD');\n\n    addRegexToken('DDD',  match1to3);\n    addRegexToken('DDDD', match3);\n    addParseToken(['DDD', 'DDDD'], function (input, array, config) {\n        config._dayOfYear = toInt(input);\n    });\n    function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {\n        var d = createUTCDate(year, 0, 1).getUTCDay();\n        var daysToAdd;\n        var dayOfYear;\n\n        d = d === 0 ? 7 : d;\n        weekday = weekday != null ? weekday : firstDayOfWeek;\n        daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0);\n        dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;\n\n        return {\n            year      : dayOfYear > 0 ? year      : year - 1,\n            dayOfYear : dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear\n        };\n    }\n\n    function getSetDayOfYear (input) {\n        var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n        return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n    }\n    function defaults(a, b, c) {\n        if (a != null) {\n            return a;\n        }\n        if (b != null) {\n            return b;\n        }\n        return c;\n    }\n\n    function currentDateArray(config) {\n        var now = new Date();\n        if (config._useUTC) {\n            return [now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()];\n        }\n        return [now.getFullYear(), now.getMonth(), now.getDate()];\n    }\n    function configFromArray (config) {\n        var i, date, input = [], currentDate, yearToUse;\n\n        if (config._d) {\n            return;\n        }\n\n        currentDate = currentDateArray(config);\n        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n            dayOfYearFromWeekInfo(config);\n        }\n        if (config._dayOfYear) {\n            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n            if (config._dayOfYear > daysInYear(yearToUse)) {\n                config._pf._overflowDayOfYear = true;\n            }\n\n            date = createUTCDate(yearToUse, 0, config._dayOfYear);\n            config._a[MONTH] = date.getUTCMonth();\n            config._a[DATE] = date.getUTCDate();\n        }\n        for (i = 0; i < 3 && config._a[i] == null; ++i) {\n            config._a[i] = input[i] = currentDate[i];\n        }\n        for (; i < 7; i++) {\n            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n        }\n        if (config._a[HOUR] === 24 &&\n                config._a[MINUTE] === 0 &&\n                config._a[SECOND] === 0 &&\n                config._a[MILLISECOND] === 0) {\n            config._nextDay = true;\n            config._a[HOUR] = 0;\n        }\n\n        config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n        if (config._tzm != null) {\n            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n        }\n\n        if (config._nextDay) {\n            config._a[HOUR] = 24;\n        }\n    }\n\n    function dayOfYearFromWeekInfo(config) {\n        var w, weekYear, week, weekday, dow, doy, temp;\n\n        w = config._w;\n        if (w.GG != null || w.W != null || w.E != null) {\n            dow = 1;\n            doy = 4;\n            weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(local__createLocal(), 1, 4).year);\n            week = defaults(w.W, 1);\n            weekday = defaults(w.E, 1);\n        } else {\n            dow = config._locale._week.dow;\n            doy = config._locale._week.doy;\n\n            weekYear = defaults(w.gg, config._a[YEAR], weekOfYear(local__createLocal(), dow, doy).year);\n            week = defaults(w.w, 1);\n\n            if (w.d != null) {\n                weekday = w.d;\n                if (weekday < dow) {\n                    ++week;\n                }\n            } else if (w.e != null) {\n                weekday = w.e + dow;\n            } else {\n                weekday = dow;\n            }\n        }\n        temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);\n\n        config._a[YEAR] = temp.year;\n        config._dayOfYear = temp.dayOfYear;\n    }\n\n    utils_hooks__hooks.ISO_8601 = function () {};\n    function configFromStringAndFormat(config) {\n        if (config._f === utils_hooks__hooks.ISO_8601) {\n            configFromISO(config);\n            return;\n        }\n\n        config._a = [];\n        config._pf.empty = true;\n        var string = '' + config._i,\n            i, parsedInput, tokens, token, skipped,\n            stringLength = string.length,\n            totalParsedInputLength = 0;\n\n        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n        for (i = 0; i < tokens.length; i++) {\n            token = tokens[i];\n            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n            if (parsedInput) {\n                skipped = string.substr(0, string.indexOf(parsedInput));\n                if (skipped.length > 0) {\n                    config._pf.unusedInput.push(skipped);\n                }\n                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n                totalParsedInputLength += parsedInput.length;\n            }\n            if (formatTokenFunctions[token]) {\n                if (parsedInput) {\n                    config._pf.empty = false;\n                }\n                else {\n                    config._pf.unusedTokens.push(token);\n                }\n                addTimeToArrayFromToken(token, parsedInput, config);\n            }\n            else if (config._strict && !parsedInput) {\n                config._pf.unusedTokens.push(token);\n            }\n        }\n        config._pf.charsLeftOver = stringLength - totalParsedInputLength;\n        if (string.length > 0) {\n            config._pf.unusedInput.push(string);\n        }\n        if (config._pf.bigHour === true && config._a[HOUR] <= 12) {\n            config._pf.bigHour = undefined;\n        }\n        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n        configFromArray(config);\n        checkOverflow(config);\n    }\n\n\n    function meridiemFixWrap (locale, hour, meridiem) {\n        var isPm;\n\n        if (meridiem == null) {\n            return hour;\n        }\n        if (locale.meridiemHour != null) {\n            return locale.meridiemHour(hour, meridiem);\n        } else if (locale.isPM != null) {\n            isPm = locale.isPM(meridiem);\n            if (isPm && hour < 12) {\n                hour += 12;\n            }\n            if (!isPm && hour === 12) {\n                hour = 0;\n            }\n            return hour;\n        } else {\n            return hour;\n        }\n    }\n\n    function configFromStringAndArray(config) {\n        var tempConfig,\n            bestMoment,\n\n            scoreToBeat,\n            i,\n            currentScore;\n\n        if (config._f.length === 0) {\n            config._pf.invalidFormat = true;\n            config._d = new Date(NaN);\n            return;\n        }\n\n        for (i = 0; i < config._f.length; i++) {\n            currentScore = 0;\n            tempConfig = copyConfig({}, config);\n            if (config._useUTC != null) {\n                tempConfig._useUTC = config._useUTC;\n            }\n            tempConfig._pf = defaultParsingFlags();\n            tempConfig._f = config._f[i];\n            configFromStringAndFormat(tempConfig);\n\n            if (!valid__isValid(tempConfig)) {\n                continue;\n            }\n            currentScore += tempConfig._pf.charsLeftOver;\n            currentScore += tempConfig._pf.unusedTokens.length * 10;\n\n            tempConfig._pf.score = currentScore;\n\n            if (scoreToBeat == null || currentScore < scoreToBeat) {\n                scoreToBeat = currentScore;\n                bestMoment = tempConfig;\n            }\n        }\n\n        extend(config, bestMoment || tempConfig);\n    }\n\n    function configFromObject(config) {\n        if (config._d) {\n            return;\n        }\n\n        var i = normalizeObjectUnits(config._i);\n        config._a = [i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond];\n\n        configFromArray(config);\n    }\n\n    function createFromConfig (config) {\n        var input = config._i,\n            format = config._f,\n            res;\n\n        config._locale = config._locale || locale_locales__getLocale(config._l);\n\n        if (input === null || (format === undefined && input === '')) {\n            return valid__createInvalid({nullInput: true});\n        }\n\n        if (typeof input === 'string') {\n            config._i = input = config._locale.preparse(input);\n        }\n\n        if (isMoment(input)) {\n            return new Moment(checkOverflow(input));\n        } else if (isArray(format)) {\n            configFromStringAndArray(config);\n        } else if (format) {\n            configFromStringAndFormat(config);\n        } else {\n            configFromInput(config);\n        }\n\n        res = new Moment(checkOverflow(config));\n        if (res._nextDay) {\n            res.add(1, 'd');\n            res._nextDay = undefined;\n        }\n\n        return res;\n    }\n\n    function configFromInput(config) {\n        var input = config._i;\n        if (input === undefined) {\n            config._d = new Date();\n        } else if (isDate(input)) {\n            config._d = new Date(+input);\n        } else if (typeof input === 'string') {\n            configFromString(config);\n        } else if (isArray(input)) {\n            config._a = map(input.slice(0), function (obj) {\n                return parseInt(obj, 10);\n            });\n            configFromArray(config);\n        } else if (typeof(input) === 'object') {\n            configFromObject(config);\n        } else if (typeof(input) === 'number') {\n            config._d = new Date(input);\n        } else {\n            utils_hooks__hooks.createFromInputFallback(config);\n        }\n    }\n\n    function createLocalOrUTC (input, format, locale, strict, isUTC) {\n        var c = {};\n\n        if (typeof(locale) === 'boolean') {\n            strict = locale;\n            locale = undefined;\n        }\n        c._isAMomentObject = true;\n        c._useUTC = c._isUTC = isUTC;\n        c._l = locale;\n        c._i = input;\n        c._f = format;\n        c._strict = strict;\n        c._pf = defaultParsingFlags();\n\n        return createFromConfig(c);\n    }\n\n    function local__createLocal (input, format, locale, strict) {\n        return createLocalOrUTC(input, format, locale, strict, false);\n    }\n\n    var prototypeMin = deprecate(\n         'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',\n         function () {\n             var other = local__createLocal.apply(null, arguments);\n             return other < this ? this : other;\n         }\n     );\n\n    var prototypeMax = deprecate(\n        'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',\n        function () {\n            var other = local__createLocal.apply(null, arguments);\n            return other > this ? this : other;\n        }\n    );\n    function pickBy(fn, moments) {\n        var res, i;\n        if (moments.length === 1 && isArray(moments[0])) {\n            moments = moments[0];\n        }\n        if (!moments.length) {\n            return local__createLocal();\n        }\n        res = moments[0];\n        for (i = 1; i < moments.length; ++i) {\n            if (moments[i][fn](res)) {\n                res = moments[i];\n            }\n        }\n        return res;\n    }\n    function min () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isBefore', args);\n    }\n\n    function max () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isAfter', args);\n    }\n\n    function Duration (duration) {\n        var normalizedInput = normalizeObjectUnits(duration),\n            years = normalizedInput.year || 0,\n            quarters = normalizedInput.quarter || 0,\n            months = normalizedInput.month || 0,\n            weeks = normalizedInput.week || 0,\n            days = normalizedInput.day || 0,\n            hours = normalizedInput.hour || 0,\n            minutes = normalizedInput.minute || 0,\n            seconds = normalizedInput.second || 0,\n            milliseconds = normalizedInput.millisecond || 0;\n        this._milliseconds = +milliseconds +\n            seconds * 1e3 + // 1000\n            minutes * 6e4 + // 1000 * 60\n            hours * 36e5; // 1000 * 60 * 60\n        this._days = +days +\n            weeks * 7;\n        this._months = +months +\n            quarters * 3 +\n            years * 12;\n\n        this._data = {};\n\n        this._locale = locale_locales__getLocale();\n\n        this._bubble();\n    }\n\n    function isDuration (obj) {\n        return obj instanceof Duration;\n    }\n\n    function offset (token, separator) {\n        addFormatToken(token, 0, 0, function () {\n            var offset = this.utcOffset();\n            var sign = '+';\n            if (offset < 0) {\n                offset = -offset;\n                sign = '-';\n            }\n            return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n        });\n    }\n\n    offset('Z', ':');\n    offset('ZZ', '');\n\n    addRegexToken('Z',  matchOffset);\n    addRegexToken('ZZ', matchOffset);\n    addParseToken(['Z', 'ZZ'], function (input, array, config) {\n        config._useUTC = true;\n        config._tzm = offsetFromString(input);\n    });\n    var chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\n    function offsetFromString(string) {\n        var matches = ((string || '').match(matchOffset) || []);\n        var chunk   = matches[matches.length - 1] || [];\n        var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n        var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n        return parts[0] === '+' ? minutes : -minutes;\n    }\n    function cloneWithOffset(input, model) {\n        var res, diff;\n        if (model._isUTC) {\n            res = model.clone();\n            diff = (isMoment(input) || isDate(input) ? +input : +local__createLocal(input)) - (+res);\n            res._d.setTime(+res._d + diff);\n            utils_hooks__hooks.updateOffset(res, false);\n            return res;\n        } else {\n            return local__createLocal(input).local();\n        }\n        return model._isUTC ? local__createLocal(input).zone(model._offset || 0) : local__createLocal(input).local();\n    }\n\n    function getDateOffset (m) {\n        return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n    }\n    utils_hooks__hooks.updateOffset = function () {};\n    function getSetOffset (input, keepLocalTime) {\n        var offset = this._offset || 0,\n            localAdjust;\n        if (input != null) {\n            if (typeof input === 'string') {\n                input = offsetFromString(input);\n            }\n            if (Math.abs(input) < 16) {\n                input = input * 60;\n            }\n            if (!this._isUTC && keepLocalTime) {\n                localAdjust = getDateOffset(this);\n            }\n            this._offset = input;\n            this._isUTC = true;\n            if (localAdjust != null) {\n                this.add(localAdjust, 'm');\n            }\n            if (offset !== input) {\n                if (!keepLocalTime || this._changeInProgress) {\n                    add_subtract__addSubtract(this, create__createDuration(input - offset, 'm'), 1, false);\n                } else if (!this._changeInProgress) {\n                    this._changeInProgress = true;\n                    utils_hooks__hooks.updateOffset(this, true);\n                    this._changeInProgress = null;\n                }\n            }\n            return this;\n        } else {\n            return this._isUTC ? offset : getDateOffset(this);\n        }\n    }\n\n    function getSetZone (input, keepLocalTime) {\n        if (input != null) {\n            if (typeof input !== 'string') {\n                input = -input;\n            }\n\n            this.utcOffset(input, keepLocalTime);\n\n            return this;\n        } else {\n            return -this.utcOffset();\n        }\n    }\n\n    function setOffsetToUTC (keepLocalTime) {\n        return this.utcOffset(0, keepLocalTime);\n    }\n\n    function setOffsetToLocal (keepLocalTime) {\n        if (this._isUTC) {\n            this.utcOffset(0, keepLocalTime);\n            this._isUTC = false;\n\n            if (keepLocalTime) {\n                this.subtract(getDateOffset(this), 'm');\n            }\n        }\n        return this;\n    }\n\n    function setOffsetToParsedOffset () {\n        if (this._tzm) {\n            this.utcOffset(this._tzm);\n        } else if (typeof this._i === 'string') {\n            this.utcOffset(offsetFromString(this._i));\n        }\n        return this;\n    }\n\n    function hasAlignedHourOffset (input) {\n        if (!input) {\n            input = 0;\n        }\n        else {\n            input = local__createLocal(input).utcOffset();\n        }\n\n        return (this.utcOffset() - input) % 60 === 0;\n    }\n\n    function isDaylightSavingTime () {\n        return (\n            this.utcOffset() > this.clone().month(0).utcOffset() ||\n            this.utcOffset() > this.clone().month(5).utcOffset()\n        );\n    }\n\n    function isDaylightSavingTimeShifted () {\n        if (this._a) {\n            var other = this._isUTC ? create_utc__createUTC(this._a) : local__createLocal(this._a);\n            return this.isValid() && compareArrays(this._a, other.toArray()) > 0;\n        }\n\n        return false;\n    }\n\n    function isLocal () {\n        return !this._isUTC;\n    }\n\n    function isUtcOffset () {\n        return this._isUTC;\n    }\n\n    function isUtc () {\n        return this._isUTC && this._offset === 0;\n    }\n\n    var aspNetRegex = /(\\-)?(?:(\\d*)\\.)?(\\d+)\\:(\\d+)(?:\\:(\\d+)\\.?(\\d{3})?)?/;\n    var create__isoRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/;\n\n    function create__createDuration (input, key) {\n        var duration = input,\n            match = null,\n            sign,\n            ret,\n            diffRes;\n\n        if (isDuration(input)) {\n            duration = {\n                ms : input._milliseconds,\n                d  : input._days,\n                M  : input._months\n            };\n        } else if (typeof input === 'number') {\n            duration = {};\n            if (key) {\n                duration[key] = input;\n            } else {\n                duration.milliseconds = input;\n            }\n        } else if (!!(match = aspNetRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            duration = {\n                y  : 0,\n                d  : toInt(match[DATE])        * sign,\n                h  : toInt(match[HOUR])        * sign,\n                m  : toInt(match[MINUTE])      * sign,\n                s  : toInt(match[SECOND])      * sign,\n                ms : toInt(match[MILLISECOND]) * sign\n            };\n        } else if (!!(match = create__isoRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            duration = {\n                y : parseIso(match[2], sign),\n                M : parseIso(match[3], sign),\n                d : parseIso(match[4], sign),\n                h : parseIso(match[5], sign),\n                m : parseIso(match[6], sign),\n                s : parseIso(match[7], sign),\n                w : parseIso(match[8], sign)\n            };\n        } else if (duration == null) {// checks for null or undefined\n            duration = {};\n        } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n            diffRes = momentsDifference(local__createLocal(duration.from), local__createLocal(duration.to));\n\n            duration = {};\n            duration.ms = diffRes.milliseconds;\n            duration.M = diffRes.months;\n        }\n\n        ret = new Duration(duration);\n\n        if (isDuration(input) && hasOwnProp(input, '_locale')) {\n            ret._locale = input._locale;\n        }\n\n        return ret;\n    }\n\n    create__createDuration.fn = Duration.prototype;\n\n    function parseIso (inp, sign) {\n        var res = inp && parseFloat(inp.replace(',', '.'));\n        return (isNaN(res) ? 0 : res) * sign;\n    }\n\n    function positiveMomentsDifference(base, other) {\n        var res = {milliseconds: 0, months: 0};\n\n        res.months = other.month() - base.month() +\n            (other.year() - base.year()) * 12;\n        if (base.clone().add(res.months, 'M').isAfter(other)) {\n            --res.months;\n        }\n\n        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n        return res;\n    }\n\n    function momentsDifference(base, other) {\n        var res;\n        other = cloneWithOffset(other, base);\n        if (base.isBefore(other)) {\n            res = positiveMomentsDifference(base, other);\n        } else {\n            res = positiveMomentsDifference(other, base);\n            res.milliseconds = -res.milliseconds;\n            res.months = -res.months;\n        }\n\n        return res;\n    }\n\n    function createAdder(direction, name) {\n        return function (val, period) {\n            var dur, tmp;\n            if (period !== null && !isNaN(+period)) {\n                deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period).');\n                tmp = val; val = period; period = tmp;\n            }\n\n            val = typeof val === 'string' ? +val : val;\n            dur = create__createDuration(val, period);\n            add_subtract__addSubtract(this, dur, direction);\n            return this;\n        };\n    }\n\n    function add_subtract__addSubtract (mom, duration, isAdding, updateOffset) {\n        var milliseconds = duration._milliseconds,\n            days = duration._days,\n            months = duration._months;\n        updateOffset = updateOffset == null ? true : updateOffset;\n\n        if (milliseconds) {\n            mom._d.setTime(+mom._d + milliseconds * isAdding);\n        }\n        if (days) {\n            get_set__set(mom, 'Date', get_set__get(mom, 'Date') + days * isAdding);\n        }\n        if (months) {\n            setMonth(mom, get_set__get(mom, 'Month') + months * isAdding);\n        }\n        if (updateOffset) {\n            utils_hooks__hooks.updateOffset(mom, days || months);\n        }\n    }\n\n    var add_subtract__add      = createAdder(1, 'add');\n    var add_subtract__subtract = createAdder(-1, 'subtract');\n\n    function moment_calendar__calendar (time) {\n        var now = time || local__createLocal(),\n            sod = cloneWithOffset(now, this).startOf('day'),\n            diff = this.diff(sod, 'days', true),\n            format = diff < -6 ? 'sameElse' :\n                diff < -1 ? 'lastWeek' :\n                diff < 0 ? 'lastDay' :\n                diff < 1 ? 'sameDay' :\n                diff < 2 ? 'nextDay' :\n                diff < 7 ? 'nextWeek' : 'sameElse';\n        return this.format(this.localeData().calendar(format, this, local__createLocal(now)));\n    }\n\n    function clone () {\n        return new Moment(this);\n    }\n\n    function isAfter (input, units) {\n        var inputMs;\n        units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');\n        if (units === 'millisecond') {\n            input = isMoment(input) ? input : local__createLocal(input);\n            return +this > +input;\n        } else {\n            inputMs = isMoment(input) ? +input : +local__createLocal(input);\n            return inputMs < +this.clone().startOf(units);\n        }\n    }\n\n    function isBefore (input, units) {\n        var inputMs;\n        units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');\n        if (units === 'millisecond') {\n            input = isMoment(input) ? input : local__createLocal(input);\n            return +this < +input;\n        } else {\n            inputMs = isMoment(input) ? +input : +local__createLocal(input);\n            return +this.clone().endOf(units) < inputMs;\n        }\n    }\n\n    function isBetween (from, to, units) {\n        return this.isAfter(from, units) && this.isBefore(to, units);\n    }\n\n    function isSame (input, units) {\n        var inputMs;\n        units = normalizeUnits(units || 'millisecond');\n        if (units === 'millisecond') {\n            input = isMoment(input) ? input : local__createLocal(input);\n            return +this === +input;\n        } else {\n            inputMs = +local__createLocal(input);\n            return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units));\n        }\n    }\n\n    function absFloor (number) {\n        if (number < 0) {\n            return Math.ceil(number);\n        } else {\n            return Math.floor(number);\n        }\n    }\n\n    function diff (input, units, asFloat) {\n        var that = cloneWithOffset(input, this),\n            zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4,\n            delta, output;\n\n        units = normalizeUnits(units);\n\n        if (units === 'year' || units === 'month' || units === 'quarter') {\n            output = monthDiff(this, that);\n            if (units === 'quarter') {\n                output = output / 3;\n            } else if (units === 'year') {\n                output = output / 12;\n            }\n        } else {\n            delta = this - that;\n            output = units === 'second' ? delta / 1e3 : // 1000\n                units === 'minute' ? delta / 6e4 : // 1000 * 60\n                units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60\n                units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst\n                units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst\n                delta;\n        }\n        return asFloat ? output : absFloor(output);\n    }\n\n    function monthDiff (a, b) {\n        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n            anchor = a.clone().add(wholeMonthDiff, 'months'),\n            anchor2, adjust;\n\n        if (b - anchor < 0) {\n            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n            adjust = (b - anchor) / (anchor - anchor2);\n        } else {\n            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n            adjust = (b - anchor) / (anchor2 - anchor);\n        }\n\n        return -(wholeMonthDiff + adjust);\n    }\n\n    utils_hooks__hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\n\n    function toString () {\n        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n    }\n\n    function moment_format__toISOString () {\n        var m = this.clone().utc();\n        if (0 < m.year() && m.year() <= 9999) {\n            if ('function' === typeof Date.prototype.toISOString) {\n                return this.toDate().toISOString();\n            } else {\n                return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n            }\n        } else {\n            return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n        }\n    }\n\n    function moment_format__format (inputString) {\n        var output = formatMoment(this, inputString || utils_hooks__hooks.defaultFormat);\n        return this.localeData().postformat(output);\n    }\n\n    function from (time, withoutSuffix) {\n        return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n    }\n\n    function fromNow (withoutSuffix) {\n        return this.from(local__createLocal(), withoutSuffix);\n    }\n\n    function locale (key) {\n        var newLocaleData;\n\n        if (key === undefined) {\n            return this._locale._abbr;\n        } else {\n            newLocaleData = locale_locales__getLocale(key);\n            if (newLocaleData != null) {\n                this._locale = newLocaleData;\n            }\n            return this;\n        }\n    }\n\n    var lang = deprecate(\n        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n        function (key) {\n            if (key === undefined) {\n                return this.localeData();\n            } else {\n                return this.locale(key);\n            }\n        }\n    );\n\n    function localeData () {\n        return this._locale;\n    }\n\n    function startOf (units) {\n        units = normalizeUnits(units);\n        switch (units) {\n        case 'year':\n            this.month(0);\n            /* falls through */\n        case 'quarter':\n        case 'month':\n            this.date(1);\n            /* falls through */\n        case 'week':\n        case 'isoWeek':\n        case 'day':\n            this.hours(0);\n            /* falls through */\n        case 'hour':\n            this.minutes(0);\n            /* falls through */\n        case 'minute':\n            this.seconds(0);\n            /* falls through */\n        case 'second':\n            this.milliseconds(0);\n        }\n        if (units === 'week') {\n            this.weekday(0);\n        }\n        if (units === 'isoWeek') {\n            this.isoWeekday(1);\n        }\n        if (units === 'quarter') {\n            this.month(Math.floor(this.month() / 3) * 3);\n        }\n\n        return this;\n    }\n\n    function endOf (units) {\n        units = normalizeUnits(units);\n        if (units === undefined || units === 'millisecond') {\n            return this;\n        }\n        return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');\n    }\n\n    function to_type__valueOf () {\n        return +this._d - ((this._offset || 0) * 60000);\n    }\n\n    function unix () {\n        return Math.floor(+this / 1000);\n    }\n\n    function toDate () {\n        return this._offset ? new Date(+this) : this._d;\n    }\n\n    function toArray () {\n        var m = this;\n        return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n    }\n\n    function moment_valid__isValid () {\n        return valid__isValid(this);\n    }\n\n    function parsingFlags () {\n        return extend({}, this._pf);\n    }\n\n    function invalidAt () {\n        return this._pf.overflow;\n    }\n\n    addFormatToken(0, ['gg', 2], 0, function () {\n        return this.weekYear() % 100;\n    });\n\n    addFormatToken(0, ['GG', 2], 0, function () {\n        return this.isoWeekYear() % 100;\n    });\n\n    function addWeekYearFormatToken (token, getter) {\n        addFormatToken(0, [token, token.length], 0, getter);\n    }\n\n    addWeekYearFormatToken('gggg',     'weekYear');\n    addWeekYearFormatToken('ggggg',    'weekYear');\n    addWeekYearFormatToken('GGGG',  'isoWeekYear');\n    addWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\n    addUnitAlias('weekYear', 'gg');\n    addUnitAlias('isoWeekYear', 'GG');\n\n    addRegexToken('G',      matchSigned);\n    addRegexToken('g',      matchSigned);\n    addRegexToken('GG',     match1to2, match2);\n    addRegexToken('gg',     match1to2, match2);\n    addRegexToken('GGGG',   match1to4, match4);\n    addRegexToken('gggg',   match1to4, match4);\n    addRegexToken('GGGGG',  match1to6, match6);\n    addRegexToken('ggggg',  match1to6, match6);\n\n    addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n        week[token.substr(0, 2)] = toInt(input);\n    });\n\n    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n        week[token] = utils_hooks__hooks.parseTwoDigitYear(input);\n    });\n\n    function weeksInYear(year, dow, doy) {\n        return weekOfYear(local__createLocal([year, 11, 31 + dow - doy]), dow, doy).week;\n    }\n\n    function getSetWeekYear (input) {\n        var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;\n        return input == null ? year : this.add((input - year), 'y');\n    }\n\n    function getSetISOWeekYear (input) {\n        var year = weekOfYear(this, 1, 4).year;\n        return input == null ? year : this.add((input - year), 'y');\n    }\n\n    function getISOWeeksInYear () {\n        return weeksInYear(this.year(), 1, 4);\n    }\n\n    function getWeeksInYear () {\n        var weekInfo = this.localeData()._week;\n        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n    }\n\n    addFormatToken('Q', 0, 0, 'quarter');\n\n    addUnitAlias('quarter', 'Q');\n\n    addRegexToken('Q', match1);\n    addParseToken('Q', function (input, array) {\n        array[MONTH] = (toInt(input) - 1) * 3;\n    });\n\n    function getSetQuarter (input) {\n        return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n    }\n\n    addFormatToken('D', ['DD', 2], 'Do', 'date');\n\n    addUnitAlias('date', 'D');\n\n    addRegexToken('D',  match1to2);\n    addRegexToken('DD', match1to2, match2);\n    addRegexToken('Do', function (isStrict, locale) {\n        return isStrict ? locale._ordinalParse : locale._ordinalParseLenient;\n    });\n\n    addParseToken(['D', 'DD'], DATE);\n    addParseToken('Do', function (input, array) {\n        array[DATE] = toInt(input.match(match1to2)[0], 10);\n    });\n\n    var getSetDayOfMonth = makeGetSet('Date', true);\n\n    addFormatToken('d', 0, 'do', 'day');\n\n    addFormatToken('dd', 0, 0, function (format) {\n        return this.localeData().weekdaysMin(this, format);\n    });\n\n    addFormatToken('ddd', 0, 0, function (format) {\n        return this.localeData().weekdaysShort(this, format);\n    });\n\n    addFormatToken('dddd', 0, 0, function (format) {\n        return this.localeData().weekdays(this, format);\n    });\n\n    addFormatToken('e', 0, 0, 'weekday');\n    addFormatToken('E', 0, 0, 'isoWeekday');\n\n    addUnitAlias('day', 'd');\n    addUnitAlias('weekday', 'e');\n    addUnitAlias('isoWeekday', 'E');\n\n    addRegexToken('d',    match1to2);\n    addRegexToken('e',    match1to2);\n    addRegexToken('E',    match1to2);\n    addRegexToken('dd',   matchWord);\n    addRegexToken('ddd',  matchWord);\n    addRegexToken('dddd', matchWord);\n\n    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config) {\n        var weekday = config._locale.weekdaysParse(input);\n        if (weekday != null) {\n            week.d = weekday;\n        } else {\n            config._pf.invalidWeekday = input;\n        }\n    });\n\n    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n        week[token] = toInt(input);\n    });\n\n    function parseWeekday(input, locale) {\n        if (typeof input === 'string') {\n            if (!isNaN(input)) {\n                input = parseInt(input, 10);\n            }\n            else {\n                input = locale.weekdaysParse(input);\n                if (typeof input !== 'number') {\n                    return null;\n                }\n            }\n        }\n        return input;\n    }\n\n    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\n    function localeWeekdays (m) {\n        return this._weekdays[m.day()];\n    }\n\n    var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\n    function localeWeekdaysShort (m) {\n        return this._weekdaysShort[m.day()];\n    }\n\n    var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\n    function localeWeekdaysMin (m) {\n        return this._weekdaysMin[m.day()];\n    }\n\n    function localeWeekdaysParse (weekdayName) {\n        var i, mom, regex;\n\n        if (!this._weekdaysParse) {\n            this._weekdaysParse = [];\n        }\n\n        for (i = 0; i < 7; i++) {\n            if (!this._weekdaysParse[i]) {\n                mom = local__createLocal([2000, 1]).day(i);\n                regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n            }\n            if (this._weekdaysParse[i].test(weekdayName)) {\n                return i;\n            }\n        }\n    }\n\n    function getSetDayOfWeek (input) {\n        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n        if (input != null) {\n            input = parseWeekday(input, this.localeData());\n            return this.add(input - day, 'd');\n        } else {\n            return day;\n        }\n    }\n\n    function getSetLocaleDayOfWeek (input) {\n        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n        return input == null ? weekday : this.add(input - weekday, 'd');\n    }\n\n    function getSetISODayOfWeek (input) {\n        return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);\n    }\n\n    addFormatToken('H', ['HH', 2], 0, 'hour');\n    addFormatToken('h', ['hh', 2], 0, function () {\n        return this.hours() % 12 || 12;\n    });\n\n    function meridiem (token, lowercase) {\n        addFormatToken(token, 0, 0, function () {\n            return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n        });\n    }\n\n    meridiem('a', true);\n    meridiem('A', false);\n\n    addUnitAlias('hour', 'h');\n\n    function matchMeridiem (isStrict, locale) {\n        return locale._meridiemParse;\n    }\n\n    addRegexToken('a',  matchMeridiem);\n    addRegexToken('A',  matchMeridiem);\n    addRegexToken('H',  match1to2);\n    addRegexToken('h',  match1to2);\n    addRegexToken('HH', match1to2, match2);\n    addRegexToken('hh', match1to2, match2);\n\n    addParseToken(['H', 'HH'], HOUR);\n    addParseToken(['a', 'A'], function (input, array, config) {\n        config._isPm = config._locale.isPM(input);\n        config._meridiem = input;\n    });\n    addParseToken(['h', 'hh'], function (input, array, config) {\n        array[HOUR] = toInt(input);\n        config._pf.bigHour = true;\n    });\n\n    function localeIsPM (input) {\n        return ((input + '').toLowerCase().charAt(0) === 'p');\n    }\n\n    var defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\n    function localeMeridiem (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'pm' : 'PM';\n        } else {\n            return isLower ? 'am' : 'AM';\n        }\n    }\n    var getSetHour = makeGetSet('Hours', true);\n\n    addFormatToken('m', ['mm', 2], 0, 'minute');\n\n    addUnitAlias('minute', 'm');\n\n    addRegexToken('m',  match1to2);\n    addRegexToken('mm', match1to2, match2);\n    addParseToken(['m', 'mm'], MINUTE);\n\n    var getSetMinute = makeGetSet('Minutes', false);\n\n    addFormatToken('s', ['ss', 2], 0, 'second');\n\n    addUnitAlias('second', 's');\n\n    addRegexToken('s',  match1to2);\n    addRegexToken('ss', match1to2, match2);\n    addParseToken(['s', 'ss'], SECOND);\n\n    var getSetSecond = makeGetSet('Seconds', false);\n\n    addFormatToken('S', 0, 0, function () {\n        return ~~(this.millisecond() / 100);\n    });\n\n    addFormatToken(0, ['SS', 2], 0, function () {\n        return ~~(this.millisecond() / 10);\n    });\n\n    function millisecond__milliseconds (token) {\n        addFormatToken(0, [token, 3], 0, 'millisecond');\n    }\n\n    millisecond__milliseconds('SSS');\n    millisecond__milliseconds('SSSS');\n\n    addUnitAlias('millisecond', 'ms');\n\n    addRegexToken('S',    match1to3, match1);\n    addRegexToken('SS',   match1to3, match2);\n    addRegexToken('SSS',  match1to3, match3);\n    addRegexToken('SSSS', matchUnsigned);\n    addParseToken(['S', 'SS', 'SSS', 'SSSS'], function (input, array) {\n        array[MILLISECOND] = toInt(('0.' + input) * 1000);\n    });\n\n    var getSetMillisecond = makeGetSet('Milliseconds', false);\n\n    addFormatToken('z',  0, 0, 'zoneAbbr');\n    addFormatToken('zz', 0, 0, 'zoneName');\n\n    function getZoneAbbr () {\n        return this._isUTC ? 'UTC' : '';\n    }\n\n    function getZoneName () {\n        return this._isUTC ? 'Coordinated Universal Time' : '';\n    }\n\n    var momentPrototype__proto = Moment.prototype;\n\n    momentPrototype__proto.add          = add_subtract__add;\n    momentPrototype__proto.calendar     = moment_calendar__calendar;\n    momentPrototype__proto.clone        = clone;\n    momentPrototype__proto.diff         = diff;\n    momentPrototype__proto.endOf        = endOf;\n    momentPrototype__proto.format       = moment_format__format;\n    momentPrototype__proto.from         = from;\n    momentPrototype__proto.fromNow      = fromNow;\n    momentPrototype__proto.get          = getSet;\n    momentPrototype__proto.invalidAt    = invalidAt;\n    momentPrototype__proto.isAfter      = isAfter;\n    momentPrototype__proto.isBefore     = isBefore;\n    momentPrototype__proto.isBetween    = isBetween;\n    momentPrototype__proto.isSame       = isSame;\n    momentPrototype__proto.isValid      = moment_valid__isValid;\n    momentPrototype__proto.lang         = lang;\n    momentPrototype__proto.locale       = locale;\n    momentPrototype__proto.localeData   = localeData;\n    momentPrototype__proto.max          = prototypeMax;\n    momentPrototype__proto.min          = prototypeMin;\n    momentPrototype__proto.parsingFlags = parsingFlags;\n    momentPrototype__proto.set          = getSet;\n    momentPrototype__proto.startOf      = startOf;\n    momentPrototype__proto.subtract     = add_subtract__subtract;\n    momentPrototype__proto.toArray      = toArray;\n    momentPrototype__proto.toDate       = toDate;\n    momentPrototype__proto.toISOString  = moment_format__toISOString;\n    momentPrototype__proto.toJSON       = moment_format__toISOString;\n    momentPrototype__proto.toString     = toString;\n    momentPrototype__proto.unix         = unix;\n    momentPrototype__proto.valueOf      = to_type__valueOf;\n    momentPrototype__proto.year       = getSetYear;\n    momentPrototype__proto.isLeapYear = getIsLeapYear;\n    momentPrototype__proto.weekYear    = getSetWeekYear;\n    momentPrototype__proto.isoWeekYear = getSetISOWeekYear;\n    momentPrototype__proto.quarter = momentPrototype__proto.quarters = getSetQuarter;\n    momentPrototype__proto.month       = getSetMonth;\n    momentPrototype__proto.daysInMonth = getDaysInMonth;\n    momentPrototype__proto.week           = momentPrototype__proto.weeks        = getSetWeek;\n    momentPrototype__proto.isoWeek        = momentPrototype__proto.isoWeeks     = getSetISOWeek;\n    momentPrototype__proto.weeksInYear    = getWeeksInYear;\n    momentPrototype__proto.isoWeeksInYear = getISOWeeksInYear;\n    momentPrototype__proto.date       = getSetDayOfMonth;\n    momentPrototype__proto.day        = momentPrototype__proto.days             = getSetDayOfWeek;\n    momentPrototype__proto.weekday    = getSetLocaleDayOfWeek;\n    momentPrototype__proto.isoWeekday = getSetISODayOfWeek;\n    momentPrototype__proto.dayOfYear  = getSetDayOfYear;\n    momentPrototype__proto.hour = momentPrototype__proto.hours = getSetHour;\n    momentPrototype__proto.minute = momentPrototype__proto.minutes = getSetMinute;\n    momentPrototype__proto.second = momentPrototype__proto.seconds = getSetSecond;\n    momentPrototype__proto.millisecond = momentPrototype__proto.milliseconds = getSetMillisecond;\n    momentPrototype__proto.utcOffset            = getSetOffset;\n    momentPrototype__proto.utc                  = setOffsetToUTC;\n    momentPrototype__proto.local                = setOffsetToLocal;\n    momentPrototype__proto.parseZone            = setOffsetToParsedOffset;\n    momentPrototype__proto.hasAlignedHourOffset = hasAlignedHourOffset;\n    momentPrototype__proto.isDST                = isDaylightSavingTime;\n    momentPrototype__proto.isDSTShifted         = isDaylightSavingTimeShifted;\n    momentPrototype__proto.isLocal              = isLocal;\n    momentPrototype__proto.isUtcOffset          = isUtcOffset;\n    momentPrototype__proto.isUtc                = isUtc;\n    momentPrototype__proto.isUTC                = isUtc;\n    momentPrototype__proto.zoneAbbr = getZoneAbbr;\n    momentPrototype__proto.zoneName = getZoneName;\n    momentPrototype__proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\n    momentPrototype__proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\n    momentPrototype__proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);\n    momentPrototype__proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779', getSetZone);\n\n    var momentPrototype = momentPrototype__proto;\n\n    function moment_moment__createUnix (input) {\n        return local__createLocal(input * 1000);\n    }\n\n    function moment_moment__createInZone () {\n        return local__createLocal.apply(null, arguments).parseZone();\n    }\n\n    var defaultCalendar = {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    };\n\n    function locale_calendar__calendar (key, mom, now) {\n        var output = this._calendar[key];\n        return typeof output === 'function' ? output.call(mom, now) : output;\n    }\n\n    var defaultLongDateFormat = {\n        LTS  : 'h:mm:ss A',\n        LT   : 'h:mm A',\n        L    : 'MM/DD/YYYY',\n        LL   : 'MMMM D, YYYY',\n        LLL  : 'MMMM D, YYYY LT',\n        LLLL : 'dddd, MMMM D, YYYY LT'\n    };\n\n    function longDateFormat (key) {\n        var output = this._longDateFormat[key];\n        if (!output && this._longDateFormat[key.toUpperCase()]) {\n            output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {\n                return val.slice(1);\n            });\n            this._longDateFormat[key] = output;\n        }\n        return output;\n    }\n\n    var defaultInvalidDate = 'Invalid date';\n\n    function invalidDate () {\n        return this._invalidDate;\n    }\n\n    var defaultOrdinal = '%d';\n    var defaultOrdinalParse = /\\d{1,2}/;\n\n    function ordinal (number) {\n        return this._ordinal.replace('%d', number);\n    }\n\n    function preParsePostFormat (string) {\n        return string;\n    }\n\n    var defaultRelativeTime = {\n        future : 'in %s',\n        past   : '%s ago',\n        s  : 'a few seconds',\n        m  : 'a minute',\n        mm : '%d minutes',\n        h  : 'an hour',\n        hh : '%d hours',\n        d  : 'a day',\n        dd : '%d days',\n        M  : 'a month',\n        MM : '%d months',\n        y  : 'a year',\n        yy : '%d years'\n    };\n\n    function relative__relativeTime (number, withoutSuffix, string, isFuture) {\n        var output = this._relativeTime[string];\n        return (typeof output === 'function') ?\n            output(number, withoutSuffix, string, isFuture) :\n            output.replace(/%d/i, number);\n    }\n\n    function pastFuture (diff, output) {\n        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n        return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);\n    }\n\n    function locale_set__set (config) {\n        var prop, i;\n        for (i in config) {\n            prop = config[i];\n            if (typeof prop === 'function') {\n                this[i] = prop;\n            } else {\n                this['_' + i] = prop;\n            }\n        }\n        this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + /\\d{1,2}/.source);\n    }\n\n    var prototype__proto = Locale.prototype;\n\n    prototype__proto._calendar       = defaultCalendar;\n    prototype__proto.calendar        = locale_calendar__calendar;\n    prototype__proto._longDateFormat = defaultLongDateFormat;\n    prototype__proto.longDateFormat  = longDateFormat;\n    prototype__proto._invalidDate    = defaultInvalidDate;\n    prototype__proto.invalidDate     = invalidDate;\n    prototype__proto._ordinal        = defaultOrdinal;\n    prototype__proto.ordinal         = ordinal;\n    prototype__proto._ordinalParse   = defaultOrdinalParse;\n    prototype__proto.preparse        = preParsePostFormat;\n    prototype__proto.postformat      = preParsePostFormat;\n    prototype__proto._relativeTime   = defaultRelativeTime;\n    prototype__proto.relativeTime    = relative__relativeTime;\n    prototype__proto.pastFuture      = pastFuture;\n    prototype__proto.set             = locale_set__set;\n    prototype__proto.months       =        localeMonths;\n    prototype__proto._months      = defaultLocaleMonths;\n    prototype__proto.monthsShort  =        localeMonthsShort;\n    prototype__proto._monthsShort = defaultLocaleMonthsShort;\n    prototype__proto.monthsParse  =        localeMonthsParse;\n    prototype__proto.week = localeWeek;\n    prototype__proto._week = defaultLocaleWeek;\n    prototype__proto.firstDayOfYear = localeFirstDayOfYear;\n    prototype__proto.firstDayOfWeek = localeFirstDayOfWeek;\n    prototype__proto.weekdays       =        localeWeekdays;\n    prototype__proto._weekdays      = defaultLocaleWeekdays;\n    prototype__proto.weekdaysMin    =        localeWeekdaysMin;\n    prototype__proto._weekdaysMin   = defaultLocaleWeekdaysMin;\n    prototype__proto.weekdaysShort  =        localeWeekdaysShort;\n    prototype__proto._weekdaysShort = defaultLocaleWeekdaysShort;\n    prototype__proto.weekdaysParse  =        localeWeekdaysParse;\n    prototype__proto.isPM = localeIsPM;\n    prototype__proto._meridiemParse = defaultLocaleMeridiemParse;\n    prototype__proto.meridiem = localeMeridiem;\n\n    function lists__get (format, index, field, setter) {\n        var locale = locale_locales__getLocale();\n        var utc = create_utc__createUTC().set(setter, index);\n        return locale[field](utc, format);\n    }\n\n    function list (format, index, field, count, setter) {\n        if (typeof format === 'number') {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n\n        if (index != null) {\n            return lists__get(format, index, field, setter);\n        }\n\n        var i;\n        var out = [];\n        for (i = 0; i < count; i++) {\n            out[i] = lists__get(format, i, field, setter);\n        }\n        return out;\n    }\n\n    function lists__listMonths (format, index) {\n        return list(format, index, 'months', 12, 'month');\n    }\n\n    function lists__listMonthsShort (format, index) {\n        return list(format, index, 'monthsShort', 12, 'month');\n    }\n\n    function lists__listWeekdays (format, index) {\n        return list(format, index, 'weekdays', 7, 'day');\n    }\n\n    function lists__listWeekdaysShort (format, index) {\n        return list(format, index, 'weekdaysShort', 7, 'day');\n    }\n\n    function lists__listWeekdaysMin (format, index) {\n        return list(format, index, 'weekdaysMin', 7, 'day');\n    }\n\n    locale_locales__getSetGlobalLocale('en', {\n        ordinalParse: /\\d{1,2}(th|st|nd|rd)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (toInt(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        }\n    });\n    utils_hooks__hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', locale_locales__getSetGlobalLocale);\n    utils_hooks__hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', locale_locales__getLocale);\n\n    var mathAbs = Math.abs;\n\n    function duration_abs__abs () {\n        var data           = this._data;\n\n        this._milliseconds = mathAbs(this._milliseconds);\n        this._days         = mathAbs(this._days);\n        this._months       = mathAbs(this._months);\n\n        data.milliseconds  = mathAbs(data.milliseconds);\n        data.seconds       = mathAbs(data.seconds);\n        data.minutes       = mathAbs(data.minutes);\n        data.hours         = mathAbs(data.hours);\n        data.months        = mathAbs(data.months);\n        data.years         = mathAbs(data.years);\n\n        return this;\n    }\n\n    function duration_add_subtract__addSubtract (duration, input, value, direction) {\n        var other = create__createDuration(input, value);\n\n        duration._milliseconds += direction * other._milliseconds;\n        duration._days         += direction * other._days;\n        duration._months       += direction * other._months;\n\n        return duration._bubble();\n    }\n    function duration_add_subtract__add (input, value) {\n        return duration_add_subtract__addSubtract(this, input, value, 1);\n    }\n    function duration_add_subtract__subtract (input, value) {\n        return duration_add_subtract__addSubtract(this, input, value, -1);\n    }\n\n    function bubble () {\n        var milliseconds = this._milliseconds;\n        var days         = this._days;\n        var months       = this._months;\n        var data         = this._data;\n        var seconds, minutes, hours, years = 0;\n        data.milliseconds = milliseconds % 1000;\n\n        seconds           = absFloor(milliseconds / 1000);\n        data.seconds      = seconds % 60;\n\n        minutes           = absFloor(seconds / 60);\n        data.minutes      = minutes % 60;\n\n        hours             = absFloor(minutes / 60);\n        data.hours        = hours % 24;\n\n        days += absFloor(hours / 24);\n        years = absFloor(daysToYears(days));\n        days -= absFloor(yearsToDays(years));\n        months += absFloor(days / 30);\n        days   %= 30;\n        years  += absFloor(months / 12);\n        months %= 12;\n\n        data.days   = days;\n        data.months = months;\n        data.years  = years;\n\n        return this;\n    }\n\n    function daysToYears (days) {\n        return days * 400 / 146097;\n    }\n\n    function yearsToDays (years) {\n        return years * 146097 / 400;\n    }\n\n    function as (units) {\n        var days;\n        var months;\n        var milliseconds = this._milliseconds;\n\n        units = normalizeUnits(units);\n\n        if (units === 'month' || units === 'year') {\n            days   = this._days   + milliseconds / 864e5;\n            months = this._months + daysToYears(days) * 12;\n            return units === 'month' ? months : months / 12;\n        } else {\n            days = this._days + Math.round(yearsToDays(this._months / 12));\n            switch (units) {\n                case 'week'   : return days / 7            + milliseconds / 6048e5;\n                case 'day'    : return days                + milliseconds / 864e5;\n                case 'hour'   : return days * 24           + milliseconds / 36e5;\n                case 'minute' : return days * 24 * 60      + milliseconds / 6e4;\n                case 'second' : return days * 24 * 60 * 60 + milliseconds / 1000;\n                case 'millisecond': return Math.floor(days * 24 * 60 * 60 * 1000) + milliseconds;\n                default: throw new Error('Unknown unit ' + units);\n            }\n        }\n    }\n    function duration_as__valueOf () {\n        return (\n            this._milliseconds +\n            this._days * 864e5 +\n            (this._months % 12) * 2592e6 +\n            toInt(this._months / 12) * 31536e6\n        );\n    }\n\n    function makeAs (alias) {\n        return function () {\n            return this.as(alias);\n        };\n    }\n\n    var asMilliseconds = makeAs('ms');\n    var asSeconds      = makeAs('s');\n    var asMinutes      = makeAs('m');\n    var asHours        = makeAs('h');\n    var asDays         = makeAs('d');\n    var asWeeks        = makeAs('w');\n    var asMonths       = makeAs('M');\n    var asYears        = makeAs('y');\n\n    function duration_get__get (units) {\n        units = normalizeUnits(units);\n        return this[units + 's']();\n    }\n\n    function makeGetter(name) {\n        return function () {\n            return this._data[name];\n        };\n    }\n\n    var duration_get__milliseconds = makeGetter('milliseconds');\n    var seconds      = makeGetter('seconds');\n    var minutes      = makeGetter('minutes');\n    var hours        = makeGetter('hours');\n    var days         = makeGetter('days');\n    var duration_get__months       = makeGetter('months');\n    var years        = makeGetter('years');\n\n    function weeks () {\n        return absFloor(this.days() / 7);\n    }\n\n    var round = Math.round;\n    var thresholds = {\n        s: 45,  // seconds to minute\n        m: 45,  // minutes to hour\n        h: 22,  // hours to day\n        d: 26,  // days to month\n        M: 11   // months to year\n    };\n    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n    }\n\n    function duration_humanize__relativeTime (posNegDuration, withoutSuffix, locale) {\n        var duration = create__createDuration(posNegDuration).abs();\n        var seconds  = round(duration.as('s'));\n        var minutes  = round(duration.as('m'));\n        var hours    = round(duration.as('h'));\n        var days     = round(duration.as('d'));\n        var months   = round(duration.as('M'));\n        var years    = round(duration.as('y'));\n\n        var a = seconds < thresholds.s && ['s', seconds]  ||\n                minutes === 1          && ['m']           ||\n                minutes < thresholds.m && ['mm', minutes] ||\n                hours   === 1          && ['h']           ||\n                hours   < thresholds.h && ['hh', hours]   ||\n                days    === 1          && ['d']           ||\n                days    < thresholds.d && ['dd', days]    ||\n                months  === 1          && ['M']           ||\n                months  < thresholds.M && ['MM', months]  ||\n                years   === 1          && ['y']           || ['yy', years];\n\n        a[2] = withoutSuffix;\n        a[3] = +posNegDuration > 0;\n        a[4] = locale;\n        return substituteTimeAgo.apply(null, a);\n    }\n    function duration_humanize__getSetRelativeTimeThreshold (threshold, limit) {\n        if (thresholds[threshold] === undefined) {\n            return false;\n        }\n        if (limit === undefined) {\n            return thresholds[threshold];\n        }\n        thresholds[threshold] = limit;\n        return true;\n    }\n\n    function humanize (withSuffix) {\n        var locale = this.localeData();\n        var output = duration_humanize__relativeTime(this, !withSuffix, locale);\n\n        if (withSuffix) {\n            output = locale.pastFuture(+this, output);\n        }\n\n        return locale.postformat(output);\n    }\n\n    var iso_string__abs = Math.abs;\n\n    function iso_string__toISOString() {\n        var Y = iso_string__abs(this.years());\n        var M = iso_string__abs(this.months());\n        var D = iso_string__abs(this.days());\n        var h = iso_string__abs(this.hours());\n        var m = iso_string__abs(this.minutes());\n        var s = iso_string__abs(this.seconds() + this.milliseconds() / 1000);\n        var total = this.asSeconds();\n\n        if (!total) {\n            return 'P0D';\n        }\n\n        return (total < 0 ? '-' : '') +\n            'P' +\n            (Y ? Y + 'Y' : '') +\n            (M ? M + 'M' : '') +\n            (D ? D + 'D' : '') +\n            ((h || m || s) ? 'T' : '') +\n            (h ? h + 'H' : '') +\n            (m ? m + 'M' : '') +\n            (s ? s + 'S' : '');\n    }\n\n    var duration_prototype__proto = Duration.prototype;\n\n    duration_prototype__proto.abs            = duration_abs__abs;\n    duration_prototype__proto.add            = duration_add_subtract__add;\n    duration_prototype__proto.subtract       = duration_add_subtract__subtract;\n    duration_prototype__proto.as             = as;\n    duration_prototype__proto.asMilliseconds = asMilliseconds;\n    duration_prototype__proto.asSeconds      = asSeconds;\n    duration_prototype__proto.asMinutes      = asMinutes;\n    duration_prototype__proto.asHours        = asHours;\n    duration_prototype__proto.asDays         = asDays;\n    duration_prototype__proto.asWeeks        = asWeeks;\n    duration_prototype__proto.asMonths       = asMonths;\n    duration_prototype__proto.asYears        = asYears;\n    duration_prototype__proto.valueOf        = duration_as__valueOf;\n    duration_prototype__proto._bubble        = bubble;\n    duration_prototype__proto.get            = duration_get__get;\n    duration_prototype__proto.milliseconds   = duration_get__milliseconds;\n    duration_prototype__proto.seconds        = seconds;\n    duration_prototype__proto.minutes        = minutes;\n    duration_prototype__proto.hours          = hours;\n    duration_prototype__proto.days           = days;\n    duration_prototype__proto.weeks          = weeks;\n    duration_prototype__proto.months         = duration_get__months;\n    duration_prototype__proto.years          = years;\n    duration_prototype__proto.humanize       = humanize;\n    duration_prototype__proto.toISOString    = iso_string__toISOString;\n    duration_prototype__proto.toString       = iso_string__toISOString;\n    duration_prototype__proto.toJSON         = iso_string__toISOString;\n    duration_prototype__proto.locale         = locale;\n    duration_prototype__proto.localeData     = localeData;\n    duration_prototype__proto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', iso_string__toISOString);\n    duration_prototype__proto.lang = lang;\n\n    addFormatToken('X', 0, 0, 'unix');\n    addFormatToken('x', 0, 0, 'valueOf');\n\n    addRegexToken('x', matchSigned);\n    addRegexToken('X', matchTimestamp);\n    addParseToken('X', function (input, array, config) {\n        config._d = new Date(parseFloat(input, 10) * 1000);\n    });\n    addParseToken('x', function (input, array, config) {\n        config._d = new Date(toInt(input));\n    });\n\n    ;\n\n    utils_hooks__hooks.version = '2.10.2';\n\n    setHookCallback(local__createLocal);\n\n    utils_hooks__hooks.fn                    = momentPrototype;\n    utils_hooks__hooks.min                   = min;\n    utils_hooks__hooks.max                   = max;\n    utils_hooks__hooks.utc                   = create_utc__createUTC;\n    utils_hooks__hooks.unix                  = moment_moment__createUnix;\n    utils_hooks__hooks.months                = lists__listMonths;\n    utils_hooks__hooks.isDate                = isDate;\n    utils_hooks__hooks.locale                = locale_locales__getSetGlobalLocale;\n    utils_hooks__hooks.invalid               = valid__createInvalid;\n    utils_hooks__hooks.duration              = create__createDuration;\n    utils_hooks__hooks.isMoment              = isMoment;\n    utils_hooks__hooks.weekdays              = lists__listWeekdays;\n    utils_hooks__hooks.parseZone             = moment_moment__createInZone;\n    utils_hooks__hooks.localeData            = locale_locales__getLocale;\n    utils_hooks__hooks.isDuration            = isDuration;\n    utils_hooks__hooks.monthsShort           = lists__listMonthsShort;\n    utils_hooks__hooks.weekdaysMin           = lists__listWeekdaysMin;\n    utils_hooks__hooks.defineLocale          = defineLocale;\n    utils_hooks__hooks.weekdaysShort         = lists__listWeekdaysShort;\n    utils_hooks__hooks.normalizeUnits        = normalizeUnits;\n    utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold;\n\n    var _moment__default = utils_hooks__hooks;\n\n    var af = _moment__default.defineLocale('af', {\n        months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),\n        weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'),\n        weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),\n        weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),\n        meridiemParse: /vm|nm/i,\n        isPM : function (input) {\n            return /^nm$/i.test(input);\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours < 12) {\n                return isLower ? 'vm' : 'VM';\n            } else {\n                return isLower ? 'nm' : 'NM';\n            }\n        },\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Vandag om] LT',\n            nextDay : '[Môre om] LT',\n            nextWeek : 'dddd [om] LT',\n            lastDay : '[Gister om] LT',\n            lastWeek : '[Laas] dddd [om] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'oor %s',\n            past : '%s gelede',\n            s : '\\'n paar sekondes',\n            m : '\\'n minuut',\n            mm : '%d minute',\n            h : '\\'n uur',\n            hh : '%d ure',\n            d : '\\'n dag',\n            dd : '%d dae',\n            M : '\\'n maand',\n            MM : '%d maande',\n            y : '\\'n jaar',\n            yy : '%d jaar'\n        },\n        ordinalParse: /\\d{1,2}(ste|de)/,\n        ordinal : function (number) {\n            return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter\n        },\n        week : {\n            dow : 1, // Maandag is die eerste dag van die week.\n            doy : 4  // Die week wat die 4de Januarie bevat is die eerste week van die jaar.\n        }\n    });\n\n    var ar_ma = _moment__default.defineLocale('ar-ma', {\n        months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n        monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n        weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n        weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n        weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[اليوم على الساعة] LT',\n            nextDay: '[غدا على الساعة] LT',\n            nextWeek: 'dddd [على الساعة] LT',\n            lastDay: '[أمس على الساعة] LT',\n            lastWeek: 'dddd [على الساعة] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'في %s',\n            past : 'منذ %s',\n            s : 'ثوان',\n            m : 'دقيقة',\n            mm : '%d دقائق',\n            h : 'ساعة',\n            hh : '%d ساعات',\n            d : 'يوم',\n            dd : '%d أيام',\n            M : 'شهر',\n            MM : '%d أشهر',\n            y : 'سنة',\n            yy : '%d سنوات'\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var ar_sa__symbolMap = {\n        '1': '١',\n        '2': '٢',\n        '3': '٣',\n        '4': '٤',\n        '5': '٥',\n        '6': '٦',\n        '7': '٧',\n        '8': '٨',\n        '9': '٩',\n        '0': '٠'\n    }, ar_sa__numberMap = {\n        '١': '1',\n        '٢': '2',\n        '٣': '3',\n        '٤': '4',\n        '٥': '5',\n        '٦': '6',\n        '٧': '7',\n        '٨': '8',\n        '٩': '9',\n        '٠': '0'\n    };\n\n    var ar_sa = _moment__default.defineLocale('ar-sa', {\n        months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n        monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n        weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n        weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n        weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        meridiemParse: /ص|م/,\n        isPM : function (input) {\n            return 'م' === input;\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return 'ص';\n            } else {\n                return 'م';\n            }\n        },\n        calendar : {\n            sameDay: '[اليوم على الساعة] LT',\n            nextDay: '[غدا على الساعة] LT',\n            nextWeek: 'dddd [على الساعة] LT',\n            lastDay: '[أمس على الساعة] LT',\n            lastWeek: 'dddd [على الساعة] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'في %s',\n            past : 'منذ %s',\n            s : 'ثوان',\n            m : 'دقيقة',\n            mm : '%d دقائق',\n            h : 'ساعة',\n            hh : '%d ساعات',\n            d : 'يوم',\n            dd : '%d أيام',\n            M : 'شهر',\n            MM : '%d أشهر',\n            y : 'سنة',\n            yy : '%d سنوات'\n        },\n        preparse: function (string) {\n            return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n                return ar_sa__numberMap[match];\n            }).replace(/،/g, ',');\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return ar_sa__symbolMap[match];\n            }).replace(/,/g, '،');\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var ar_tn = _moment__default.defineLocale('ar-tn', {\n        months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n        monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n        weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n        weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n        weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n        longDateFormat: {\n            LT: 'HH:mm',\n            LTS: 'LT:ss',\n            L: 'DD/MM/YYYY',\n            LL: 'D MMMM YYYY',\n            LLL: 'D MMMM YYYY LT',\n            LLLL: 'dddd D MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[اليوم على الساعة] LT',\n            nextDay: '[غدا على الساعة] LT',\n            nextWeek: 'dddd [على الساعة] LT',\n            lastDay: '[أمس على الساعة] LT',\n            lastWeek: 'dddd [على الساعة] LT',\n            sameElse: 'L'\n        },\n        relativeTime: {\n            future: 'في %s',\n            past: 'منذ %s',\n            s: 'ثوان',\n            m: 'دقيقة',\n            mm: '%d دقائق',\n            h: 'ساعة',\n            hh: '%d ساعات',\n            d: 'يوم',\n            dd: '%d أيام',\n            M: 'شهر',\n            MM: '%d أشهر',\n            y: 'سنة',\n            yy: '%d سنوات'\n        },\n        week: {\n            dow: 1, // Monday is the first day of the week.\n            doy: 4 // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var ar__symbolMap = {\n        '1': '١',\n        '2': '٢',\n        '3': '٣',\n        '4': '٤',\n        '5': '٥',\n        '6': '٦',\n        '7': '٧',\n        '8': '٨',\n        '9': '٩',\n        '0': '٠'\n    }, ar__numberMap = {\n        '١': '1',\n        '٢': '2',\n        '٣': '3',\n        '٤': '4',\n        '٥': '5',\n        '٦': '6',\n        '٧': '7',\n        '٨': '8',\n        '٩': '9',\n        '٠': '0'\n    }, pluralForm = function (n) {\n        return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n    }, plurals = {\n        s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n        m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n        h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n        d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n        M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n        y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n    }, pluralize = function (u) {\n        return function (number, withoutSuffix, string, isFuture) {\n            var f = pluralForm(number),\n                str = plurals[u][pluralForm(number)];\n            if (f === 2) {\n                str = str[withoutSuffix ? 0 : 1];\n            }\n            return str.replace(/%d/i, number);\n        };\n    }, ar__months = [\n        'كانون الثاني يناير',\n        'شباط فبراير',\n        'آذار مارس',\n        'نيسان أبريل',\n        'أيار مايو',\n        'حزيران يونيو',\n        'تموز يوليو',\n        'آب أغسطس',\n        'أيلول سبتمبر',\n        'تشرين الأول أكتوبر',\n        'تشرين الثاني نوفمبر',\n        'كانون الأول ديسمبر'\n    ];\n\n    var ar = _moment__default.defineLocale('ar', {\n        months : ar__months,\n        monthsShort : ar__months,\n        weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n        weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n        weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        meridiemParse: /ص|م/,\n        isPM : function (input) {\n            return 'م' === input;\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return 'ص';\n            } else {\n                return 'م';\n            }\n        },\n        calendar : {\n            sameDay: '[اليوم عند الساعة] LT',\n            nextDay: '[غدًا عند الساعة] LT',\n            nextWeek: 'dddd [عند الساعة] LT',\n            lastDay: '[أمس عند الساعة] LT',\n            lastWeek: 'dddd [عند الساعة] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'بعد %s',\n            past : 'منذ %s',\n            s : pluralize('s'),\n            m : pluralize('m'),\n            mm : pluralize('m'),\n            h : pluralize('h'),\n            hh : pluralize('h'),\n            d : pluralize('d'),\n            dd : pluralize('d'),\n            M : pluralize('M'),\n            MM : pluralize('M'),\n            y : pluralize('y'),\n            yy : pluralize('y')\n        },\n        preparse: function (string) {\n            return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n                return ar__numberMap[match];\n            }).replace(/،/g, ',');\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return ar__symbolMap[match];\n            }).replace(/,/g, '،');\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var az__suffixes = {\n        1: '-inci',\n        5: '-inci',\n        8: '-inci',\n        70: '-inci',\n        80: '-inci',\n        2: '-nci',\n        7: '-nci',\n        20: '-nci',\n        50: '-nci',\n        3: '-üncü',\n        4: '-üncü',\n        100: '-üncü',\n        6: '-ncı',\n        9: '-uncu',\n        10: '-uncu',\n        30: '-uncu',\n        60: '-ıncı',\n        90: '-ıncı'\n    };\n\n    var az = _moment__default.defineLocale('az', {\n        months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'),\n        monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),\n        weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'),\n        weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),\n        weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[bugün saat] LT',\n            nextDay : '[sabah saat] LT',\n            nextWeek : '[gələn həftə] dddd [saat] LT',\n            lastDay : '[dünən] LT',\n            lastWeek : '[keçən həftə] dddd [saat] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s sonra',\n            past : '%s əvvəl',\n            s : 'birneçə saniyyə',\n            m : 'bir dəqiqə',\n            mm : '%d dəqiqə',\n            h : 'bir saat',\n            hh : '%d saat',\n            d : 'bir gün',\n            dd : '%d gün',\n            M : 'bir ay',\n            MM : '%d ay',\n            y : 'bir il',\n            yy : '%d il'\n        },\n        meridiemParse: /gecə|səhər|gündüz|axşam/,\n        isPM : function (input) {\n            return /^(gündüz|axşam)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'gecə';\n            } else if (hour < 12) {\n                return 'səhər';\n            } else if (hour < 17) {\n                return 'gündüz';\n            } else {\n                return 'axşam';\n            }\n        },\n        ordinalParse: /\\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,\n        ordinal : function (number) {\n            if (number === 0) {  // special case for zero\n                return number + '-ıncı';\n            }\n            var a = number % 10,\n                b = number % 100 - a,\n                c = number >= 100 ? 100 : null;\n            return number + (az__suffixes[a] || az__suffixes[b] || az__suffixes[c]);\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    function be__plural(word, num) {\n        var forms = word.split('_');\n        return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n    }\n    function be__relativeTimeWithPlural(number, withoutSuffix, key) {\n        var format = {\n            'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',\n            'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',\n            'dd': 'дзень_дні_дзён',\n            'MM': 'месяц_месяцы_месяцаў',\n            'yy': 'год_гады_гадоў'\n        };\n        if (key === 'm') {\n            return withoutSuffix ? 'хвіліна' : 'хвіліну';\n        }\n        else if (key === 'h') {\n            return withoutSuffix ? 'гадзіна' : 'гадзіну';\n        }\n        else {\n            return number + ' ' + be__plural(format[key], +number);\n        }\n    }\n    function be__monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'),\n            'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_')\n        },\n        nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function be__weekdaysCaseReplace(m, format) {\n        var weekdays = {\n            'nominative': 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'),\n            'accusative': 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_')\n        },\n        nounCase = (/\\[ ?[Вв] ?(?:мінулую|наступную)? ?\\] ?dddd/).test(format) ?\n            'accusative' :\n            'nominative';\n        return weekdays[nounCase][m.day()];\n    }\n\n    var be = _moment__default.defineLocale('be', {\n        months : be__monthsCaseReplace,\n        monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'),\n        weekdays : be__weekdaysCaseReplace,\n        weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n        weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY г.',\n            LLL : 'D MMMM YYYY г., LT',\n            LLLL : 'dddd, D MMMM YYYY г., LT'\n        },\n        calendar : {\n            sameDay: '[Сёння ў] LT',\n            nextDay: '[Заўтра ў] LT',\n            lastDay: '[Учора ў] LT',\n            nextWeek: function () {\n                return '[У] dddd [ў] LT';\n            },\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return '[У мінулую] dddd [ў] LT';\n                case 1:\n                case 2:\n                case 4:\n                    return '[У мінулы] dddd [ў] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'праз %s',\n            past : '%s таму',\n            s : 'некалькі секунд',\n            m : be__relativeTimeWithPlural,\n            mm : be__relativeTimeWithPlural,\n            h : be__relativeTimeWithPlural,\n            hh : be__relativeTimeWithPlural,\n            d : 'дзень',\n            dd : be__relativeTimeWithPlural,\n            M : 'месяц',\n            MM : be__relativeTimeWithPlural,\n            y : 'год',\n            yy : be__relativeTimeWithPlural\n        },\n        meridiemParse: /ночы|раніцы|дня|вечара/,\n        isPM : function (input) {\n            return /^(дня|вечара)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'ночы';\n            } else if (hour < 12) {\n                return 'раніцы';\n            } else if (hour < 17) {\n                return 'дня';\n            } else {\n                return 'вечара';\n            }\n        },\n        ordinalParse: /\\d{1,2}-(і|ы|га)/,\n        ordinal: function (number, period) {\n            switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';\n            case 'D':\n                return number + '-га';\n            default:\n                return number;\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var bg = _moment__default.defineLocale('bg', {\n        months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),\n        monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),\n        weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'),\n        weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'),\n        weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'D.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Днес в] LT',\n            nextDay : '[Утре в] LT',\n            nextWeek : 'dddd [в] LT',\n            lastDay : '[Вчера в] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[В изминалата] dddd [в] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[В изминалия] dddd [в] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'след %s',\n            past : 'преди %s',\n            s : 'няколко секунди',\n            m : 'минута',\n            mm : '%d минути',\n            h : 'час',\n            hh : '%d часа',\n            d : 'ден',\n            dd : '%d дни',\n            M : 'месец',\n            MM : '%d месеца',\n            y : 'година',\n            yy : '%d години'\n        },\n        ordinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n        ordinal : function (number) {\n            var lastDigit = number % 10,\n                last2Digits = number % 100;\n            if (number === 0) {\n                return number + '-ев';\n            } else if (last2Digits === 0) {\n                return number + '-ен';\n            } else if (last2Digits > 10 && last2Digits < 20) {\n                return number + '-ти';\n            } else if (lastDigit === 1) {\n                return number + '-ви';\n            } else if (lastDigit === 2) {\n                return number + '-ри';\n            } else if (lastDigit === 7 || lastDigit === 8) {\n                return number + '-ми';\n            } else {\n                return number + '-ти';\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var bn__symbolMap = {\n        '1': '১',\n        '2': '২',\n        '3': '৩',\n        '4': '৪',\n        '5': '৫',\n        '6': '৬',\n        '7': '৭',\n        '8': '৮',\n        '9': '৯',\n        '0': '০'\n    },\n    bn__numberMap = {\n        '১': '1',\n        '২': '2',\n        '৩': '3',\n        '৪': '4',\n        '৫': '5',\n        '৬': '6',\n        '৭': '7',\n        '৮': '8',\n        '৯': '9',\n        '০': '0'\n    };\n\n    var bn = _moment__default.defineLocale('bn', {\n        months : 'জানুয়ারী_ফেবুয়ারী_মার্চ_এপ্রিল_মে_জুন_জুলাই_অগাস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'),\n        monthsShort : 'জানু_ফেব_মার্চ_এপর_মে_জুন_জুল_অগ_সেপ্ট_অক্টো_নভ_ডিসেম্'.split('_'),\n        weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পত্তিবার_শুক্রুবার_শনিবার'.split('_'),\n        weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পত্তি_শুক্রু_শনি'.split('_'),\n        weekdaysMin : 'রব_সম_মঙ্গ_বু_ব্রিহ_শু_শনি'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm সময়',\n            LTS : 'A h:mm:ss সময়',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        calendar : {\n            sameDay : '[আজ] LT',\n            nextDay : '[আগামীকাল] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[গতকাল] LT',\n            lastWeek : '[গত] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s পরে',\n            past : '%s আগে',\n            s : 'কএক সেকেন্ড',\n            m : 'এক মিনিট',\n            mm : '%d মিনিট',\n            h : 'এক ঘন্টা',\n            hh : '%d ঘন্টা',\n            d : 'এক দিন',\n            dd : '%d দিন',\n            M : 'এক মাস',\n            MM : '%d মাস',\n            y : 'এক বছর',\n            yy : '%d বছর'\n        },\n        preparse: function (string) {\n            return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {\n                return bn__numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return bn__symbolMap[match];\n            });\n        },\n        meridiemParse: /রাত|শকাল|দুপুর|বিকেল|রাত/,\n        isPM: function (input) {\n            return /^(দুপুর|বিকেল|রাত)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'রাত';\n            } else if (hour < 10) {\n                return 'শকাল';\n            } else if (hour < 17) {\n                return 'দুপুর';\n            } else if (hour < 20) {\n                return 'বিকেল';\n            } else {\n                return 'রাত';\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var bo__symbolMap = {\n        '1': '༡',\n        '2': '༢',\n        '3': '༣',\n        '4': '༤',\n        '5': '༥',\n        '6': '༦',\n        '7': '༧',\n        '8': '༨',\n        '9': '༩',\n        '0': '༠'\n    },\n    bo__numberMap = {\n        '༡': '1',\n        '༢': '2',\n        '༣': '3',\n        '༤': '4',\n        '༥': '5',\n        '༦': '6',\n        '༧': '7',\n        '༨': '8',\n        '༩': '9',\n        '༠': '0'\n    };\n\n    var bo = _moment__default.defineLocale('bo', {\n        months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n        monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n        weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'),\n        weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n        weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        calendar : {\n            sameDay : '[དི་རིང] LT',\n            nextDay : '[སང་ཉིན] LT',\n            nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',\n            lastDay : '[ཁ་སང] LT',\n            lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s ལ་',\n            past : '%s སྔན་ལ',\n            s : 'ལམ་སང',\n            m : 'སྐར་མ་གཅིག',\n            mm : '%d སྐར་མ',\n            h : 'ཆུ་ཚོད་གཅིག',\n            hh : '%d ཆུ་ཚོད',\n            d : 'ཉིན་གཅིག',\n            dd : '%d ཉིན་',\n            M : 'ཟླ་བ་གཅིག',\n            MM : '%d ཟླ་བ',\n            y : 'ལོ་གཅིག',\n            yy : '%d ལོ'\n        },\n        preparse: function (string) {\n            return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {\n                return bo__numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return bo__symbolMap[match];\n            });\n        },\n        meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,\n        isPM: function (input) {\n            return /^(ཉིན་གུང|དགོང་དག|མཚན་མོ)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'མཚན་མོ';\n            } else if (hour < 10) {\n                return 'ཞོགས་ཀས';\n            } else if (hour < 17) {\n                return 'ཉིན་གུང';\n            } else if (hour < 20) {\n                return 'དགོང་དག';\n            } else {\n                return 'མཚན་མོ';\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    function relativeTimeWithMutation(number, withoutSuffix, key) {\n        var format = {\n            'mm': 'munutenn',\n            'MM': 'miz',\n            'dd': 'devezh'\n        };\n        return number + ' ' + mutation(format[key], number);\n    }\n    function specialMutationForYears(number) {\n        switch (lastNumber(number)) {\n        case 1:\n        case 3:\n        case 4:\n        case 5:\n        case 9:\n            return number + ' bloaz';\n        default:\n            return number + ' vloaz';\n        }\n    }\n    function lastNumber(number) {\n        if (number > 9) {\n            return lastNumber(number % 10);\n        }\n        return number;\n    }\n    function mutation(text, number) {\n        if (number === 2) {\n            return softMutation(text);\n        }\n        return text;\n    }\n    function softMutation(text) {\n        var mutationTable = {\n            'm': 'v',\n            'b': 'v',\n            'd': 'z'\n        };\n        if (mutationTable[text.charAt(0)] === undefined) {\n            return text;\n        }\n        return mutationTable[text.charAt(0)] + text.substring(1);\n    }\n\n    var br = _moment__default.defineLocale('br', {\n        months : 'Genver_C\\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'),\n        monthsShort : 'Gen_C\\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),\n        weekdays : 'Sul_Lun_Meurzh_Merc\\'her_Yaou_Gwener_Sadorn'.split('_'),\n        weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),\n        weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'h[e]mm A',\n            LTS : 'h[e]mm:ss A',\n            L : 'DD/MM/YYYY',\n            LL : 'D [a viz] MMMM YYYY',\n            LLL : 'D [a viz] MMMM YYYY LT',\n            LLLL : 'dddd, D [a viz] MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Hiziv da] LT',\n            nextDay : '[Warc\\'hoazh da] LT',\n            nextWeek : 'dddd [da] LT',\n            lastDay : '[Dec\\'h da] LT',\n            lastWeek : 'dddd [paset da] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'a-benn %s',\n            past : '%s \\'zo',\n            s : 'un nebeud segondennoù',\n            m : 'ur vunutenn',\n            mm : relativeTimeWithMutation,\n            h : 'un eur',\n            hh : '%d eur',\n            d : 'un devezh',\n            dd : relativeTimeWithMutation,\n            M : 'ur miz',\n            MM : relativeTimeWithMutation,\n            y : 'ur bloaz',\n            yy : specialMutationForYears\n        },\n        ordinalParse: /\\d{1,2}(añ|vet)/,\n        ordinal : function (number) {\n            var output = (number === 1) ? 'añ' : 'vet';\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    function bs__translate(number, withoutSuffix, key) {\n        var result = number + ' ';\n        switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n        }\n    }\n\n    var bs = _moment__default.defineLocale('bs', {\n        months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'),\n        monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n        weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n        weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n        weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD. MM. YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd, D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay  : '[danas u] LT',\n            nextDay  : '[sutra u] LT',\n            nextWeek : function () {\n                switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n                }\n            },\n            lastDay  : '[jučer u] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past   : 'prije %s',\n            s      : 'par sekundi',\n            m      : bs__translate,\n            mm     : bs__translate,\n            h      : bs__translate,\n            hh     : bs__translate,\n            d      : 'dan',\n            dd     : bs__translate,\n            M      : 'mjesec',\n            MM     : bs__translate,\n            y      : 'godinu',\n            yy     : bs__translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var ca = _moment__default.defineLocale('ca', {\n        months : 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),\n        monthsShort : 'gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.'.split('_'),\n        weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'),\n        weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),\n        weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : function () {\n                return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            nextDay : function () {\n                return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            nextWeek : function () {\n                return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            lastDay : function () {\n                return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            lastWeek : function () {\n                return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'en %s',\n            past : 'fa %s',\n            s : 'uns segons',\n            m : 'un minut',\n            mm : '%d minuts',\n            h : 'una hora',\n            hh : '%d hores',\n            d : 'un dia',\n            dd : '%d dies',\n            M : 'un mes',\n            MM : '%d mesos',\n            y : 'un any',\n            yy : '%d anys'\n        },\n        ordinalParse: /\\d{1,2}(r|n|t|è|a)/,\n        ordinal : function (number, period) {\n            var output = (number === 1) ? 'r' :\n                (number === 2) ? 'n' :\n                (number === 3) ? 'r' :\n                (number === 4) ? 't' : 'è';\n            if (period === 'w' || period === 'W') {\n                output = 'a';\n            }\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var cs__months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_'),\n        cs__monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');\n    function cs__plural(n) {\n        return (n > 1) && (n < 5) && (~~(n / 10) !== 1);\n    }\n    function cs__translate(number, withoutSuffix, key, isFuture) {\n        var result = number + ' ';\n        switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (cs__plural(number) ? 'minuty' : 'minut');\n            } else {\n                return result + 'minutami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (cs__plural(number) ? 'hodiny' : 'hodin');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'den' : 'dnem';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (cs__plural(number) ? 'dny' : 'dní');\n            } else {\n                return result + 'dny';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (cs__plural(number) ? 'měsíce' : 'měsíců');\n            } else {\n                return result + 'měsíci';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokem';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (cs__plural(number) ? 'roky' : 'let');\n            } else {\n                return result + 'lety';\n            }\n            break;\n        }\n    }\n\n    var cs = _moment__default.defineLocale('cs', {\n        months : cs__months,\n        monthsShort : cs__monthsShort,\n        monthsParse : (function (months, monthsShort) {\n            var i, _monthsParse = [];\n            for (i = 0; i < 12; i++) {\n                _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');\n            }\n            return _monthsParse;\n        }(cs__months, cs__monthsShort)),\n        weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),\n        weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'),\n        weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),\n        longDateFormat : {\n            LT: 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[dnes v] LT',\n            nextDay: '[zítra v] LT',\n            nextWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[v neděli v] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [v] LT';\n                case 3:\n                    return '[ve středu v] LT';\n                case 4:\n                    return '[ve čtvrtek v] LT';\n                case 5:\n                    return '[v pátek v] LT';\n                case 6:\n                    return '[v sobotu v] LT';\n                }\n            },\n            lastDay: '[včera v] LT',\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[minulou neděli v] LT';\n                case 1:\n                case 2:\n                    return '[minulé] dddd [v] LT';\n                case 3:\n                    return '[minulou středu v] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [v] LT';\n                case 6:\n                    return '[minulou sobotu v] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past : 'před %s',\n            s : cs__translate,\n            m : cs__translate,\n            mm : cs__translate,\n            h : cs__translate,\n            hh : cs__translate,\n            d : cs__translate,\n            dd : cs__translate,\n            M : cs__translate,\n            MM : cs__translate,\n            y : cs__translate,\n            yy : cs__translate\n        },\n        ordinalParse : /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var cv = _moment__default.defineLocale('cv', {\n        months : 'кăрлач_нарăс_пуш_ака_май_çĕртме_утă_çурла_авăн_юпа_чӳк_раштав'.split('_'),\n        monthsShort : 'кăр_нар_пуш_ака_май_çĕр_утă_çур_ав_юпа_чӳк_раш'.split('_'),\n        weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кĕçнерникун_эрнекун_шăматкун'.split('_'),\n        weekdaysShort : 'выр_тун_ытл_юн_кĕç_эрн_шăм'.split('_'),\n        weekdaysMin : 'вр_тн_ыт_юн_кç_эр_шм'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD-MM-YYYY',\n            LL : 'YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ]',\n            LLL : 'YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT',\n            LLLL : 'dddd, YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT'\n        },\n        calendar : {\n            sameDay: '[Паян] LT [сехетре]',\n            nextDay: '[Ыран] LT [сехетре]',\n            lastDay: '[Ĕнер] LT [сехетре]',\n            nextWeek: '[Çитес] dddd LT [сехетре]',\n            lastWeek: '[Иртнĕ] dddd LT [сехетре]',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : function (output) {\n                var affix = /сехет$/i.exec(output) ? 'рен' : /çул$/i.exec(output) ? 'тан' : 'ран';\n                return output + affix;\n            },\n            past : '%s каялла',\n            s : 'пĕр-ик çеккунт',\n            m : 'пĕр минут',\n            mm : '%d минут',\n            h : 'пĕр сехет',\n            hh : '%d сехет',\n            d : 'пĕр кун',\n            dd : '%d кун',\n            M : 'пĕр уйăх',\n            MM : '%d уйăх',\n            y : 'пĕр çул',\n            yy : '%d çул'\n        },\n        ordinalParse: /\\d{1,2}-мĕш/,\n        ordinal : '%d-мĕш',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var cy = _moment__default.defineLocale('cy', {\n        months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),\n        monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'),\n        weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'),\n        weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),\n        weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),\n        longDateFormat: {\n            LT: 'HH:mm',\n            LTS : 'LT:ss',\n            L: 'DD/MM/YYYY',\n            LL: 'D MMMM YYYY',\n            LLL: 'D MMMM YYYY LT',\n            LLLL: 'dddd, D MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[Heddiw am] LT',\n            nextDay: '[Yfory am] LT',\n            nextWeek: 'dddd [am] LT',\n            lastDay: '[Ddoe am] LT',\n            lastWeek: 'dddd [diwethaf am] LT',\n            sameElse: 'L'\n        },\n        relativeTime: {\n            future: 'mewn %s',\n            past: '%s yn ôl',\n            s: 'ychydig eiliadau',\n            m: 'munud',\n            mm: '%d munud',\n            h: 'awr',\n            hh: '%d awr',\n            d: 'diwrnod',\n            dd: '%d diwrnod',\n            M: 'mis',\n            MM: '%d mis',\n            y: 'blwyddyn',\n            yy: '%d flynedd'\n        },\n        ordinalParse: /\\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,\n        ordinal: function (number) {\n            var b = number,\n                output = '',\n                lookup = [\n                    '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed\n                    'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed\n                ];\n            if (b > 20) {\n                if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {\n                    output = 'fed'; // not 30ain, 70ain or 90ain\n                } else {\n                    output = 'ain';\n                }\n            } else if (b > 0) {\n                output = lookup[b];\n            }\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var da = _moment__default.defineLocale('da', {\n        months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n        weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n        weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'),\n        weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd [d.] D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[I dag kl.] LT',\n            nextDay : '[I morgen kl.] LT',\n            nextWeek : 'dddd [kl.] LT',\n            lastDay : '[I går kl.] LT',\n            lastWeek : '[sidste] dddd [kl] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'om %s',\n            past : '%s siden',\n            s : 'få sekunder',\n            m : 'et minut',\n            mm : '%d minutter',\n            h : 'en time',\n            hh : '%d timer',\n            d : 'en dag',\n            dd : '%d dage',\n            M : 'en måned',\n            MM : '%d måneder',\n            y : 'et år',\n            yy : '%d år'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    function de_at__processRelativeTime(number, withoutSuffix, key, isFuture) {\n        var format = {\n            'm': ['eine Minute', 'einer Minute'],\n            'h': ['eine Stunde', 'einer Stunde'],\n            'd': ['ein Tag', 'einem Tag'],\n            'dd': [number + ' Tage', number + ' Tagen'],\n            'M': ['ein Monat', 'einem Monat'],\n            'MM': [number + ' Monate', number + ' Monaten'],\n            'y': ['ein Jahr', 'einem Jahr'],\n            'yy': [number + ' Jahre', number + ' Jahren']\n        };\n        return withoutSuffix ? format[key][0] : format[key][1];\n    }\n\n    var de_at = _moment__default.defineLocale('de-at', {\n        months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n        monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n        weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n        weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n        weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT: 'HH:mm',\n            LTS: 'HH:mm:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd, D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Heute um] LT [Uhr]',\n            sameElse: 'L',\n            nextDay: '[Morgen um] LT [Uhr]',\n            nextWeek: 'dddd [um] LT [Uhr]',\n            lastDay: '[Gestern um] LT [Uhr]',\n            lastWeek: '[letzten] dddd [um] LT [Uhr]'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : 'vor %s',\n            s : 'ein paar Sekunden',\n            m : de_at__processRelativeTime,\n            mm : '%d Minuten',\n            h : de_at__processRelativeTime,\n            hh : '%d Stunden',\n            d : de_at__processRelativeTime,\n            dd : de_at__processRelativeTime,\n            M : de_at__processRelativeTime,\n            MM : de_at__processRelativeTime,\n            y : de_at__processRelativeTime,\n            yy : de_at__processRelativeTime\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    function de__processRelativeTime(number, withoutSuffix, key, isFuture) {\n        var format = {\n            'm': ['eine Minute', 'einer Minute'],\n            'h': ['eine Stunde', 'einer Stunde'],\n            'd': ['ein Tag', 'einem Tag'],\n            'dd': [number + ' Tage', number + ' Tagen'],\n            'M': ['ein Monat', 'einem Monat'],\n            'MM': [number + ' Monate', number + ' Monaten'],\n            'y': ['ein Jahr', 'einem Jahr'],\n            'yy': [number + ' Jahre', number + ' Jahren']\n        };\n        return withoutSuffix ? format[key][0] : format[key][1];\n    }\n\n    var de = _moment__default.defineLocale('de', {\n        months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n        monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n        weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n        weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n        weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT: 'HH:mm',\n            LTS: 'HH:mm:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd, D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Heute um] LT [Uhr]',\n            sameElse: 'L',\n            nextDay: '[Morgen um] LT [Uhr]',\n            nextWeek: 'dddd [um] LT [Uhr]',\n            lastDay: '[Gestern um] LT [Uhr]',\n            lastWeek: '[letzten] dddd [um] LT [Uhr]'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : 'vor %s',\n            s : 'ein paar Sekunden',\n            m : de__processRelativeTime,\n            mm : '%d Minuten',\n            h : de__processRelativeTime,\n            hh : '%d Stunden',\n            d : de__processRelativeTime,\n            dd : de__processRelativeTime,\n            M : de__processRelativeTime,\n            MM : de__processRelativeTime,\n            y : de__processRelativeTime,\n            yy : de__processRelativeTime\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var el = _moment__default.defineLocale('el', {\n        monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),\n        monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'),\n        months : function (momentToFormat, format) {\n            if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM'\n                return this._monthsGenitiveEl[momentToFormat.month()];\n            } else {\n                return this._monthsNominativeEl[momentToFormat.month()];\n            }\n        },\n        monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),\n        weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'),\n        weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),\n        weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),\n        meridiem : function (hours, minutes, isLower) {\n            if (hours > 11) {\n                return isLower ? 'μμ' : 'ΜΜ';\n            } else {\n                return isLower ? 'πμ' : 'ΠΜ';\n            }\n        },\n        isPM : function (input) {\n            return ((input + '').toLowerCase()[0] === 'μ');\n        },\n        meridiemParse : /[ΠΜ]\\.?Μ?\\.?/i,\n        longDateFormat : {\n            LT : 'h:mm A',\n            LTS : 'h:mm:ss A',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendarEl : {\n            sameDay : '[Σήμερα {}] LT',\n            nextDay : '[Αύριο {}] LT',\n            nextWeek : 'dddd [{}] LT',\n            lastDay : '[Χθες {}] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                    case 6:\n                        return '[το προηγούμενο] dddd [{}] LT';\n                    default:\n                        return '[την προηγούμενη] dddd [{}] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        calendar : function (key, mom) {\n            var output = this._calendarEl[key],\n                hours = mom && mom.hours();\n            if (typeof output === 'function') {\n                output = output.apply(mom);\n            }\n            return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις'));\n        },\n        relativeTime : {\n            future : 'σε %s',\n            past : '%s πριν',\n            s : 'λίγα δευτερόλεπτα',\n            m : 'ένα λεπτό',\n            mm : '%d λεπτά',\n            h : 'μία ώρα',\n            hh : '%d ώρες',\n            d : 'μία μέρα',\n            dd : '%d μέρες',\n            M : 'ένας μήνας',\n            MM : '%d μήνες',\n            y : 'ένας χρόνος',\n            yy : '%d χρόνια'\n        },\n        ordinalParse: /\\d{1,2}η/,\n        ordinal: '%dη',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4st is the first week of the year.\n        }\n    });\n\n    var en_au = _moment__default.defineLocale('en-au', {\n        months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n        weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n        weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n        weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'h:mm A',\n            LTS : 'h:mm:ss A',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Today at] LT',\n            nextDay : '[Tomorrow at] LT',\n            nextWeek : 'dddd [at] LT',\n            lastDay : '[Yesterday at] LT',\n            lastWeek : '[Last] dddd [at] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : '%s ago',\n            s : 'a few seconds',\n            m : 'a minute',\n            mm : '%d minutes',\n            h : 'an hour',\n            hh : '%d hours',\n            d : 'a day',\n            dd : '%d days',\n            M : 'a month',\n            MM : '%d months',\n            y : 'a year',\n            yy : '%d years'\n        },\n        ordinalParse: /\\d{1,2}(st|nd|rd|th)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (~~(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var en_ca = _moment__default.defineLocale('en-ca', {\n        months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n        weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n        weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n        weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'h:mm A',\n            LTS : 'h:mm:ss A',\n            L : 'YYYY-MM-DD',\n            LL : 'D MMMM, YYYY',\n            LLL : 'D MMMM, YYYY LT',\n            LLLL : 'dddd, D MMMM, YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Today at] LT',\n            nextDay : '[Tomorrow at] LT',\n            nextWeek : 'dddd [at] LT',\n            lastDay : '[Yesterday at] LT',\n            lastWeek : '[Last] dddd [at] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : '%s ago',\n            s : 'a few seconds',\n            m : 'a minute',\n            mm : '%d minutes',\n            h : 'an hour',\n            hh : '%d hours',\n            d : 'a day',\n            dd : '%d days',\n            M : 'a month',\n            MM : '%d months',\n            y : 'a year',\n            yy : '%d years'\n        },\n        ordinalParse: /\\d{1,2}(st|nd|rd|th)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (~~(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        }\n    });\n\n    var en_gb = _moment__default.defineLocale('en-gb', {\n        months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n        weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n        weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n        weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'HH:mm:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Today at] LT',\n            nextDay : '[Tomorrow at] LT',\n            nextWeek : 'dddd [at] LT',\n            lastDay : '[Yesterday at] LT',\n            lastWeek : '[Last] dddd [at] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'in %s',\n            past : '%s ago',\n            s : 'a few seconds',\n            m : 'a minute',\n            mm : '%d minutes',\n            h : 'an hour',\n            hh : '%d hours',\n            d : 'a day',\n            dd : '%d days',\n            M : 'a month',\n            MM : '%d months',\n            y : 'a year',\n            yy : '%d years'\n        },\n        ordinalParse: /\\d{1,2}(st|nd|rd|th)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (~~(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var eo = _moment__default.defineLocale('eo', {\n        months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'),\n        weekdays : 'Dimanĉo_Lundo_Mardo_Merkredo_Ĵaŭdo_Vendredo_Sabato'.split('_'),\n        weekdaysShort : 'Dim_Lun_Mard_Merk_Ĵaŭ_Ven_Sab'.split('_'),\n        weekdaysMin : 'Di_Lu_Ma_Me_Ĵa_Ve_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'D[-an de] MMMM, YYYY',\n            LLL : 'D[-an de] MMMM, YYYY LT',\n            LLLL : 'dddd, [la] D[-an de] MMMM, YYYY LT'\n        },\n        meridiemParse: /[ap]\\.t\\.m/i,\n        isPM: function (input) {\n            return input.charAt(0).toLowerCase() === 'p';\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours > 11) {\n                return isLower ? 'p.t.m.' : 'P.T.M.';\n            } else {\n                return isLower ? 'a.t.m.' : 'A.T.M.';\n            }\n        },\n        calendar : {\n            sameDay : '[Hodiaŭ je] LT',\n            nextDay : '[Morgaŭ je] LT',\n            nextWeek : 'dddd [je] LT',\n            lastDay : '[Hieraŭ je] LT',\n            lastWeek : '[pasinta] dddd [je] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'je %s',\n            past : 'antaŭ %s',\n            s : 'sekundoj',\n            m : 'minuto',\n            mm : '%d minutoj',\n            h : 'horo',\n            hh : '%d horoj',\n            d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo\n            dd : '%d tagoj',\n            M : 'monato',\n            MM : '%d monatoj',\n            y : 'jaro',\n            yy : '%d jaroj'\n        },\n        ordinalParse: /\\d{1,2}a/,\n        ordinal : '%da',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'),\n        es__monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\n    var es = _moment__default.defineLocale('es', {\n        months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n        monthsShort : function (m, format) {\n            if (/-MMM-/.test(format)) {\n                return es__monthsShort[m.month()];\n            } else {\n                return monthsShortDot[m.month()];\n            }\n        },\n        weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n        weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n        weekdaysMin : 'Do_Lu_Ma_Mi_Ju_Vi_Sá'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D [de] MMMM [de] YYYY',\n            LLL : 'D [de] MMMM [de] YYYY LT',\n            LLLL : 'dddd, D [de] MMMM [de] YYYY LT'\n        },\n        calendar : {\n            sameDay : function () {\n                return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            nextDay : function () {\n                return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            nextWeek : function () {\n                return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            lastDay : function () {\n                return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            lastWeek : function () {\n                return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'en %s',\n            past : 'hace %s',\n            s : 'unos segundos',\n            m : 'un minuto',\n            mm : '%d minutos',\n            h : 'una hora',\n            hh : '%d horas',\n            d : 'un día',\n            dd : '%d días',\n            M : 'un mes',\n            MM : '%d meses',\n            y : 'un año',\n            yy : '%d años'\n        },\n        ordinalParse : /\\d{1,2}º/,\n        ordinal : '%dº',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    function et__processRelativeTime(number, withoutSuffix, key, isFuture) {\n        var format = {\n            's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],\n            'm' : ['ühe minuti', 'üks minut'],\n            'mm': [number + ' minuti', number + ' minutit'],\n            'h' : ['ühe tunni', 'tund aega', 'üks tund'],\n            'hh': [number + ' tunni', number + ' tundi'],\n            'd' : ['ühe päeva', 'üks päev'],\n            'M' : ['kuu aja', 'kuu aega', 'üks kuu'],\n            'MM': [number + ' kuu', number + ' kuud'],\n            'y' : ['ühe aasta', 'aasta', 'üks aasta'],\n            'yy': [number + ' aasta', number + ' aastat']\n        };\n        if (withoutSuffix) {\n            return format[key][2] ? format[key][2] : format[key][1];\n        }\n        return isFuture ? format[key][0] : format[key][1];\n    }\n\n    var et = _moment__default.defineLocale('et', {\n        months        : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'),\n        monthsShort   : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'),\n        weekdays      : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'),\n        weekdaysShort : 'P_E_T_K_N_R_L'.split('_'),\n        weekdaysMin   : 'P_E_T_K_N_R_L'.split('_'),\n        longDateFormat : {\n            LT   : 'H:mm',\n            LTS : 'LT:ss',\n            L    : 'DD.MM.YYYY',\n            LL   : 'D. MMMM YYYY',\n            LLL  : 'D. MMMM YYYY LT',\n            LLLL : 'dddd, D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay  : '[Täna,] LT',\n            nextDay  : '[Homme,] LT',\n            nextWeek : '[Järgmine] dddd LT',\n            lastDay  : '[Eile,] LT',\n            lastWeek : '[Eelmine] dddd LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s pärast',\n            past   : '%s tagasi',\n            s      : et__processRelativeTime,\n            m      : et__processRelativeTime,\n            mm     : et__processRelativeTime,\n            h      : et__processRelativeTime,\n            hh     : et__processRelativeTime,\n            d      : et__processRelativeTime,\n            dd     : '%d päeva',\n            M      : et__processRelativeTime,\n            MM     : et__processRelativeTime,\n            y      : et__processRelativeTime,\n            yy     : et__processRelativeTime\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var eu = _moment__default.defineLocale('eu', {\n        months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'),\n        monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'),\n        weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'),\n        weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'),\n        weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'YYYY[ko] MMMM[ren] D[a]',\n            LLL : 'YYYY[ko] MMMM[ren] D[a] LT',\n            LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] LT',\n            l : 'YYYY-M-D',\n            ll : 'YYYY[ko] MMM D[a]',\n            lll : 'YYYY[ko] MMM D[a] LT',\n            llll : 'ddd, YYYY[ko] MMM D[a] LT'\n        },\n        calendar : {\n            sameDay : '[gaur] LT[etan]',\n            nextDay : '[bihar] LT[etan]',\n            nextWeek : 'dddd LT[etan]',\n            lastDay : '[atzo] LT[etan]',\n            lastWeek : '[aurreko] dddd LT[etan]',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s barru',\n            past : 'duela %s',\n            s : 'segundo batzuk',\n            m : 'minutu bat',\n            mm : '%d minutu',\n            h : 'ordu bat',\n            hh : '%d ordu',\n            d : 'egun bat',\n            dd : '%d egun',\n            M : 'hilabete bat',\n            MM : '%d hilabete',\n            y : 'urte bat',\n            yy : '%d urte'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var fa__symbolMap = {\n        '1': '۱',\n        '2': '۲',\n        '3': '۳',\n        '4': '۴',\n        '5': '۵',\n        '6': '۶',\n        '7': '۷',\n        '8': '۸',\n        '9': '۹',\n        '0': '۰'\n    }, fa__numberMap = {\n        '۱': '1',\n        '۲': '2',\n        '۳': '3',\n        '۴': '4',\n        '۵': '5',\n        '۶': '6',\n        '۷': '7',\n        '۸': '8',\n        '۹': '9',\n        '۰': '0'\n    };\n\n    var fa = _moment__default.defineLocale('fa', {\n        months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n        monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n        weekdays : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n        weekdaysShort : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n        weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        meridiemParse: /قبل از ظهر|بعد از ظهر/,\n        isPM: function (input) {\n            return /بعد از ظهر/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return 'قبل از ظهر';\n            } else {\n                return 'بعد از ظهر';\n            }\n        },\n        calendar : {\n            sameDay : '[امروز ساعت] LT',\n            nextDay : '[فردا ساعت] LT',\n            nextWeek : 'dddd [ساعت] LT',\n            lastDay : '[دیروز ساعت] LT',\n            lastWeek : 'dddd [پیش] [ساعت] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'در %s',\n            past : '%s پیش',\n            s : 'چندین ثانیه',\n            m : 'یک دقیقه',\n            mm : '%d دقیقه',\n            h : 'یک ساعت',\n            hh : '%d ساعت',\n            d : 'یک روز',\n            dd : '%d روز',\n            M : 'یک ماه',\n            MM : '%d ماه',\n            y : 'یک سال',\n            yy : '%d سال'\n        },\n        preparse: function (string) {\n            return string.replace(/[۰-۹]/g, function (match) {\n                return fa__numberMap[match];\n            }).replace(/،/g, ',');\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return fa__symbolMap[match];\n            }).replace(/,/g, '،');\n        },\n        ordinalParse: /\\d{1,2}م/,\n        ordinal : '%dم',\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12 // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '),\n        numbersFuture = [\n            'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',\n            numbersPast[7], numbersPast[8], numbersPast[9]\n        ];\n    function fi__translate(number, withoutSuffix, key, isFuture) {\n        var result = '';\n        switch (key) {\n        case 's':\n            return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';\n        case 'm':\n            return isFuture ? 'minuutin' : 'minuutti';\n        case 'mm':\n            result = isFuture ? 'minuutin' : 'minuuttia';\n            break;\n        case 'h':\n            return isFuture ? 'tunnin' : 'tunti';\n        case 'hh':\n            result = isFuture ? 'tunnin' : 'tuntia';\n            break;\n        case 'd':\n            return isFuture ? 'päivän' : 'päivä';\n        case 'dd':\n            result = isFuture ? 'päivän' : 'päivää';\n            break;\n        case 'M':\n            return isFuture ? 'kuukauden' : 'kuukausi';\n        case 'MM':\n            result = isFuture ? 'kuukauden' : 'kuukautta';\n            break;\n        case 'y':\n            return isFuture ? 'vuoden' : 'vuosi';\n        case 'yy':\n            result = isFuture ? 'vuoden' : 'vuotta';\n            break;\n        }\n        result = verbalNumber(number, isFuture) + ' ' + result;\n        return result;\n    }\n    function verbalNumber(number, isFuture) {\n        return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;\n    }\n\n    var fi = _moment__default.defineLocale('fi', {\n        months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'),\n        monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'),\n        weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'),\n        weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'),\n        weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'),\n        longDateFormat : {\n            LT : 'HH.mm',\n            LTS : 'HH.mm.ss',\n            L : 'DD.MM.YYYY',\n            LL : 'Do MMMM[ta] YYYY',\n            LLL : 'Do MMMM[ta] YYYY, [klo] LT',\n            LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] LT',\n            l : 'D.M.YYYY',\n            ll : 'Do MMM YYYY',\n            lll : 'Do MMM YYYY, [klo] LT',\n            llll : 'ddd, Do MMM YYYY, [klo] LT'\n        },\n        calendar : {\n            sameDay : '[tänään] [klo] LT',\n            nextDay : '[huomenna] [klo] LT',\n            nextWeek : 'dddd [klo] LT',\n            lastDay : '[eilen] [klo] LT',\n            lastWeek : '[viime] dddd[na] [klo] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s päästä',\n            past : '%s sitten',\n            s : fi__translate,\n            m : fi__translate,\n            mm : fi__translate,\n            h : fi__translate,\n            hh : fi__translate,\n            d : fi__translate,\n            dd : fi__translate,\n            M : fi__translate,\n            MM : fi__translate,\n            y : fi__translate,\n            yy : fi__translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var fo = _moment__default.defineLocale('fo', {\n        months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n        weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'),\n        weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'),\n        weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D. MMMM, YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Í dag kl.] LT',\n            nextDay : '[Í morgin kl.] LT',\n            nextWeek : 'dddd [kl.] LT',\n            lastDay : '[Í gjár kl.] LT',\n            lastWeek : '[síðstu] dddd [kl] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'um %s',\n            past : '%s síðani',\n            s : 'fá sekund',\n            m : 'ein minutt',\n            mm : '%d minuttir',\n            h : 'ein tími',\n            hh : '%d tímar',\n            d : 'ein dagur',\n            dd : '%d dagar',\n            M : 'ein mánaði',\n            MM : '%d mánaðir',\n            y : 'eitt ár',\n            yy : '%d ár'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var fr_ca = _moment__default.defineLocale('fr-ca', {\n        months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n        monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n        weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n        weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n        weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Aujourd\\'hui à] LT',\n            nextDay: '[Demain à] LT',\n            nextWeek: 'dddd [à] LT',\n            lastDay: '[Hier à] LT',\n            lastWeek: 'dddd [dernier à] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'dans %s',\n            past : 'il y a %s',\n            s : 'quelques secondes',\n            m : 'une minute',\n            mm : '%d minutes',\n            h : 'une heure',\n            hh : '%d heures',\n            d : 'un jour',\n            dd : '%d jours',\n            M : 'un mois',\n            MM : '%d mois',\n            y : 'un an',\n            yy : '%d ans'\n        },\n        ordinalParse: /\\d{1,2}(er|)/,\n        ordinal : function (number) {\n            return number + (number === 1 ? 'er' : '');\n        }\n    });\n\n    var fr = _moment__default.defineLocale('fr', {\n        months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n        monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n        weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n        weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n        weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Aujourd\\'hui à] LT',\n            nextDay: '[Demain à] LT',\n            nextWeek: 'dddd [à] LT',\n            lastDay: '[Hier à] LT',\n            lastWeek: 'dddd [dernier à] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'dans %s',\n            past : 'il y a %s',\n            s : 'quelques secondes',\n            m : 'une minute',\n            mm : '%d minutes',\n            h : 'une heure',\n            hh : '%d heures',\n            d : 'un jour',\n            dd : '%d jours',\n            M : 'un mois',\n            MM : '%d mois',\n            y : 'un an',\n            yy : '%d ans'\n        },\n        ordinalParse: /\\d{1,2}(er|)/,\n        ordinal : function (number) {\n            return number + (number === 1 ? 'er' : '');\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var fy__monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_'),\n        fy__monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_');\n\n    var fy = _moment__default.defineLocale('fy', {\n        months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'),\n        monthsShort : function (m, format) {\n            if (/-MMM-/.test(format)) {\n                return fy__monthsShortWithoutDots[m.month()];\n            } else {\n                return fy__monthsShortWithDots[m.month()];\n            }\n        },\n        weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'),\n        weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'),\n        weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD-MM-YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[hjoed om] LT',\n            nextDay: '[moarn om] LT',\n            nextWeek: 'dddd [om] LT',\n            lastDay: '[juster om] LT',\n            lastWeek: '[ôfrûne] dddd [om] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'oer %s',\n            past : '%s lyn',\n            s : 'in pear sekonden',\n            m : 'ien minút',\n            mm : '%d minuten',\n            h : 'ien oere',\n            hh : '%d oeren',\n            d : 'ien dei',\n            dd : '%d dagen',\n            M : 'ien moanne',\n            MM : '%d moannen',\n            y : 'ien jier',\n            yy : '%d jierren'\n        },\n        ordinalParse: /\\d{1,2}(ste|de)/,\n        ordinal : function (number) {\n            return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var gl = _moment__default.defineLocale('gl', {\n        months : 'Xaneiro_Febreiro_Marzo_Abril_Maio_Xuño_Xullo_Agosto_Setembro_Outubro_Novembro_Decembro'.split('_'),\n        monthsShort : 'Xan._Feb._Mar._Abr._Mai._Xuñ._Xul._Ago._Set._Out._Nov._Dec.'.split('_'),\n        weekdays : 'Domingo_Luns_Martes_Mércores_Xoves_Venres_Sábado'.split('_'),\n        weekdaysShort : 'Dom._Lun._Mar._Mér._Xov._Ven._Sáb.'.split('_'),\n        weekdaysMin : 'Do_Lu_Ma_Mé_Xo_Ve_Sá'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : function () {\n                return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n            },\n            nextDay : function () {\n                return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n            },\n            nextWeek : function () {\n                return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n            },\n            lastDay : function () {\n                return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';\n            },\n            lastWeek : function () {\n                return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : function (str) {\n                if (str === 'uns segundos') {\n                    return 'nuns segundos';\n                }\n                return 'en ' + str;\n            },\n            past : 'hai %s',\n            s : 'uns segundos',\n            m : 'un minuto',\n            mm : '%d minutos',\n            h : 'unha hora',\n            hh : '%d horas',\n            d : 'un día',\n            dd : '%d días',\n            M : 'un mes',\n            MM : '%d meses',\n            y : 'un ano',\n            yy : '%d anos'\n        },\n        ordinalParse : /\\d{1,2}º/,\n        ordinal : '%dº',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var he = _moment__default.defineLocale('he', {\n        months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'),\n        monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'),\n        weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'),\n        weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'),\n        weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D [ב]MMMM YYYY',\n            LLL : 'D [ב]MMMM YYYY LT',\n            LLLL : 'dddd, D [ב]MMMM YYYY LT',\n            l : 'D/M/YYYY',\n            ll : 'D MMM YYYY',\n            lll : 'D MMM YYYY LT',\n            llll : 'ddd, D MMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[היום ב־]LT',\n            nextDay : '[מחר ב־]LT',\n            nextWeek : 'dddd [בשעה] LT',\n            lastDay : '[אתמול ב־]LT',\n            lastWeek : '[ביום] dddd [האחרון בשעה] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'בעוד %s',\n            past : 'לפני %s',\n            s : 'מספר שניות',\n            m : 'דקה',\n            mm : '%d דקות',\n            h : 'שעה',\n            hh : function (number) {\n                if (number === 2) {\n                    return 'שעתיים';\n                }\n                return number + ' שעות';\n            },\n            d : 'יום',\n            dd : function (number) {\n                if (number === 2) {\n                    return 'יומיים';\n                }\n                return number + ' ימים';\n            },\n            M : 'חודש',\n            MM : function (number) {\n                if (number === 2) {\n                    return 'חודשיים';\n                }\n                return number + ' חודשים';\n            },\n            y : 'שנה',\n            yy : function (number) {\n                if (number === 2) {\n                    return 'שנתיים';\n                } else if (number % 10 === 0 && number !== 10) {\n                    return number + ' שנה';\n                }\n                return number + ' שנים';\n            }\n        }\n    });\n\n    var hi__symbolMap = {\n        '1': '१',\n        '2': '२',\n        '3': '३',\n        '4': '४',\n        '5': '५',\n        '6': '६',\n        '7': '७',\n        '8': '८',\n        '9': '९',\n        '0': '०'\n    },\n    hi__numberMap = {\n        '१': '1',\n        '२': '2',\n        '३': '3',\n        '४': '4',\n        '५': '5',\n        '६': '6',\n        '७': '7',\n        '८': '8',\n        '९': '9',\n        '०': '0'\n    };\n\n    var hi = _moment__default.defineLocale('hi', {\n        months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'),\n        monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'),\n        weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n        weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'),\n        weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm बजे',\n            LTS : 'A h:mm:ss बजे',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        calendar : {\n            sameDay : '[आज] LT',\n            nextDay : '[कल] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[कल] LT',\n            lastWeek : '[पिछले] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s में',\n            past : '%s पहले',\n            s : 'कुछ ही क्षण',\n            m : 'एक मिनट',\n            mm : '%d मिनट',\n            h : 'एक घंटा',\n            hh : '%d घंटे',\n            d : 'एक दिन',\n            dd : '%d दिन',\n            M : 'एक महीने',\n            MM : '%d महीने',\n            y : 'एक वर्ष',\n            yy : '%d वर्ष'\n        },\n        preparse: function (string) {\n            return string.replace(/[१२३४५६७८९०]/g, function (match) {\n                return hi__numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return hi__symbolMap[match];\n            });\n        },\n        meridiemParse: /रात|सुबह|दोपहर|शाम/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'रात') {\n                return hour < 4 ? hour : hour + 12;\n            } else if (meridiem === 'सुबह') {\n                return hour;\n            } else if (meridiem === 'दोपहर') {\n                return hour >= 10 ? hour : hour + 12;\n            } else if (meridiem === 'शाम') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'रात';\n            } else if (hour < 10) {\n                return 'सुबह';\n            } else if (hour < 17) {\n                return 'दोपहर';\n            } else if (hour < 20) {\n                return 'शाम';\n            } else {\n                return 'रात';\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    function hr__translate(number, withoutSuffix, key) {\n        var result = number + ' ';\n        switch (key) {\n        case 'm':\n            return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minuta';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'jedan sat' : 'jednog sata';\n        case 'hh':\n            if (number === 1) {\n                result += 'sat';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'sata';\n            } else {\n                result += 'sati';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dana';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mjesec';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'mjeseca';\n            } else {\n                result += 'mjeseci';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'godina';\n            } else if (number === 2 || number === 3 || number === 4) {\n                result += 'godine';\n            } else {\n                result += 'godina';\n            }\n            return result;\n        }\n    }\n\n    var hr = _moment__default.defineLocale('hr', {\n        months : 'sječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_'),\n        monthsShort : 'sje._vel._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'),\n        weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n        weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n        weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD. MM. YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd, D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay  : '[danas u] LT',\n            nextDay  : '[sutra u] LT',\n            nextWeek : function () {\n                switch (this.day()) {\n                case 0:\n                    return '[u] [nedjelju] [u] LT';\n                case 3:\n                    return '[u] [srijedu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n                }\n            },\n            lastDay  : '[jučer u] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                    return '[prošlu] dddd [u] LT';\n                case 6:\n                    return '[prošle] [subote] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prošli] dddd [u] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past   : 'prije %s',\n            s      : 'par sekundi',\n            m      : hr__translate,\n            mm     : hr__translate,\n            h      : hr__translate,\n            hh     : hr__translate,\n            d      : 'dan',\n            dd     : hr__translate,\n            M      : 'mjesec',\n            MM     : hr__translate,\n            y      : 'godinu',\n            yy     : hr__translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');\n    function hu__translate(number, withoutSuffix, key, isFuture) {\n        var num = number,\n            suffix;\n        switch (key) {\n        case 's':\n            return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';\n        case 'm':\n            return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'mm':\n            return num + (isFuture || withoutSuffix ? ' perc' : ' perce');\n        case 'h':\n            return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'hh':\n            return num + (isFuture || withoutSuffix ? ' óra' : ' órája');\n        case 'd':\n            return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'dd':\n            return num + (isFuture || withoutSuffix ? ' nap' : ' napja');\n        case 'M':\n            return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'MM':\n            return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n        case 'y':\n            return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');\n        case 'yy':\n            return num + (isFuture || withoutSuffix ? ' év' : ' éve');\n        }\n        return '';\n    }\n    function week(isFuture) {\n        return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';\n    }\n\n    var hu = _moment__default.defineLocale('hu', {\n        months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'),\n        monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'),\n        weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),\n        weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),\n        weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'YYYY.MM.DD.',\n            LL : 'YYYY. MMMM D.',\n            LLL : 'YYYY. MMMM D., LT',\n            LLLL : 'YYYY. MMMM D., dddd LT'\n        },\n        meridiemParse: /de|du/i,\n        isPM: function (input) {\n            return input.charAt(1).toLowerCase() === 'u';\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours < 12) {\n                return isLower === true ? 'de' : 'DE';\n            } else {\n                return isLower === true ? 'du' : 'DU';\n            }\n        },\n        calendar : {\n            sameDay : '[ma] LT[-kor]',\n            nextDay : '[holnap] LT[-kor]',\n            nextWeek : function () {\n                return week.call(this, true);\n            },\n            lastDay : '[tegnap] LT[-kor]',\n            lastWeek : function () {\n                return week.call(this, false);\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s múlva',\n            past : '%s',\n            s : hu__translate,\n            m : hu__translate,\n            mm : hu__translate,\n            h : hu__translate,\n            hh : hu__translate,\n            d : hu__translate,\n            dd : hu__translate,\n            M : hu__translate,\n            MM : hu__translate,\n            y : hu__translate,\n            yy : hu__translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    function hy_am__monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),\n            'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_')\n        },\n        nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function hy_am__monthsShortCaseReplace(m, format) {\n        var monthsShort = 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_');\n        return monthsShort[m.month()];\n    }\n    function hy_am__weekdaysCaseReplace(m, format) {\n        var weekdays = 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_');\n        return weekdays[m.day()];\n    }\n\n    var hy_am = _moment__default.defineLocale('hy-am', {\n        months : hy_am__monthsCaseReplace,\n        monthsShort : hy_am__monthsShortCaseReplace,\n        weekdays : hy_am__weekdaysCaseReplace,\n        weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n        weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY թ.',\n            LLL : 'D MMMM YYYY թ., LT',\n            LLLL : 'dddd, D MMMM YYYY թ., LT'\n        },\n        calendar : {\n            sameDay: '[այսօր] LT',\n            nextDay: '[վաղը] LT',\n            lastDay: '[երեկ] LT',\n            nextWeek: function () {\n                return 'dddd [օրը ժամը] LT';\n            },\n            lastWeek: function () {\n                return '[անցած] dddd [օրը ժամը] LT';\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : '%s հետո',\n            past : '%s առաջ',\n            s : 'մի քանի վայրկյան',\n            m : 'րոպե',\n            mm : '%d րոպե',\n            h : 'ժամ',\n            hh : '%d ժամ',\n            d : 'օր',\n            dd : '%d օր',\n            M : 'ամիս',\n            MM : '%d ամիս',\n            y : 'տարի',\n            yy : '%d տարի'\n        },\n        meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,\n        isPM: function (input) {\n            return /^(ցերեկվա|երեկոյան)$/.test(input);\n        },\n        meridiem : function (hour) {\n            if (hour < 4) {\n                return 'գիշերվա';\n            } else if (hour < 12) {\n                return 'առավոտվա';\n            } else if (hour < 17) {\n                return 'ցերեկվա';\n            } else {\n                return 'երեկոյան';\n            }\n        },\n        ordinalParse: /\\d{1,2}|\\d{1,2}-(ին|րդ)/,\n        ordinal: function (number, period) {\n            switch (period) {\n            case 'DDD':\n            case 'w':\n            case 'W':\n            case 'DDDo':\n                if (number === 1) {\n                    return number + '-ին';\n                }\n                return number + '-րդ';\n            default:\n                return number;\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var id = _moment__default.defineLocale('id', {\n        months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'),\n        monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'),\n        weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'),\n        weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'),\n        weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),\n        longDateFormat : {\n            LT : 'HH.mm',\n            LTS : 'LT.ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY [pukul] LT',\n            LLLL : 'dddd, D MMMM YYYY [pukul] LT'\n        },\n        meridiemParse: /pagi|siang|sore|malam/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'pagi') {\n                return hour;\n            } else if (meridiem === 'siang') {\n                return hour >= 11 ? hour : hour + 12;\n            } else if (meridiem === 'sore' || meridiem === 'malam') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours < 11) {\n                return 'pagi';\n            } else if (hours < 15) {\n                return 'siang';\n            } else if (hours < 19) {\n                return 'sore';\n            } else {\n                return 'malam';\n            }\n        },\n        calendar : {\n            sameDay : '[Hari ini pukul] LT',\n            nextDay : '[Besok pukul] LT',\n            nextWeek : 'dddd [pukul] LT',\n            lastDay : '[Kemarin pukul] LT',\n            lastWeek : 'dddd [lalu pukul] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'dalam %s',\n            past : '%s yang lalu',\n            s : 'beberapa detik',\n            m : 'semenit',\n            mm : '%d menit',\n            h : 'sejam',\n            hh : '%d jam',\n            d : 'sehari',\n            dd : '%d hari',\n            M : 'sebulan',\n            MM : '%d bulan',\n            y : 'setahun',\n            yy : '%d tahun'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    function is__plural(n) {\n        if (n % 100 === 11) {\n            return true;\n        } else if (n % 10 === 1) {\n            return false;\n        }\n        return true;\n    }\n    function is__translate(number, withoutSuffix, key, isFuture) {\n        var result = number + ' ';\n        switch (key) {\n        case 's':\n            return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';\n        case 'm':\n            return withoutSuffix ? 'mínúta' : 'mínútu';\n        case 'mm':\n            if (is__plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');\n            } else if (withoutSuffix) {\n                return result + 'mínúta';\n            }\n            return result + 'mínútu';\n        case 'hh':\n            if (is__plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');\n            }\n            return result + 'klukkustund';\n        case 'd':\n            if (withoutSuffix) {\n                return 'dagur';\n            }\n            return isFuture ? 'dag' : 'degi';\n        case 'dd':\n            if (is__plural(number)) {\n                if (withoutSuffix) {\n                    return result + 'dagar';\n                }\n                return result + (isFuture ? 'daga' : 'dögum');\n            } else if (withoutSuffix) {\n                return result + 'dagur';\n            }\n            return result + (isFuture ? 'dag' : 'degi');\n        case 'M':\n            if (withoutSuffix) {\n                return 'mánuður';\n            }\n            return isFuture ? 'mánuð' : 'mánuði';\n        case 'MM':\n            if (is__plural(number)) {\n                if (withoutSuffix) {\n                    return result + 'mánuðir';\n                }\n                return result + (isFuture ? 'mánuði' : 'mánuðum');\n            } else if (withoutSuffix) {\n                return result + 'mánuður';\n            }\n            return result + (isFuture ? 'mánuð' : 'mánuði');\n        case 'y':\n            return withoutSuffix || isFuture ? 'ár' : 'ári';\n        case 'yy':\n            if (is__plural(number)) {\n                return result + (withoutSuffix || isFuture ? 'ár' : 'árum');\n            }\n            return result + (withoutSuffix || isFuture ? 'ár' : 'ári');\n        }\n    }\n\n    var is = _moment__default.defineLocale('is', {\n        months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'),\n        weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'),\n        weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'),\n        weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY [kl.] LT',\n            LLLL : 'dddd, D. MMMM YYYY [kl.] LT'\n        },\n        calendar : {\n            sameDay : '[í dag kl.] LT',\n            nextDay : '[á morgun kl.] LT',\n            nextWeek : 'dddd [kl.] LT',\n            lastDay : '[í gær kl.] LT',\n            lastWeek : '[síðasta] dddd [kl.] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'eftir %s',\n            past : 'fyrir %s síðan',\n            s : is__translate,\n            m : is__translate,\n            mm : is__translate,\n            h : 'klukkustund',\n            hh : is__translate,\n            d : is__translate,\n            dd : is__translate,\n            M : is__translate,\n            MM : is__translate,\n            y : is__translate,\n            yy : is__translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var it = _moment__default.defineLocale('it', {\n        months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'),\n        monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),\n        weekdays : 'Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato'.split('_'),\n        weekdaysShort : 'Dom_Lun_Mar_Mer_Gio_Ven_Sab'.split('_'),\n        weekdaysMin : 'D_L_Ma_Me_G_V_S'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Oggi alle] LT',\n            nextDay: '[Domani alle] LT',\n            nextWeek: 'dddd [alle] LT',\n            lastDay: '[Ieri alle] LT',\n            lastWeek: function () {\n                switch (this.day()) {\n                    case 0:\n                        return '[la scorsa] dddd [alle] LT';\n                    default:\n                        return '[lo scorso] dddd [alle] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : function (s) {\n                return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s;\n            },\n            past : '%s fa',\n            s : 'alcuni secondi',\n            m : 'un minuto',\n            mm : '%d minuti',\n            h : 'un\\'ora',\n            hh : '%d ore',\n            d : 'un giorno',\n            dd : '%d giorni',\n            M : 'un mese',\n            MM : '%d mesi',\n            y : 'un anno',\n            yy : '%d anni'\n        },\n        ordinalParse : /\\d{1,2}º/,\n        ordinal: '%dº',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var ja = _moment__default.defineLocale('ja', {\n        months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n        monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n        weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),\n        weekdaysShort : '日_月_火_水_木_金_土'.split('_'),\n        weekdaysMin : '日_月_火_水_木_金_土'.split('_'),\n        longDateFormat : {\n            LT : 'Ah時m分',\n            LTS : 'LTs秒',\n            L : 'YYYY/MM/DD',\n            LL : 'YYYY年M月D日',\n            LLL : 'YYYY年M月D日LT',\n            LLLL : 'YYYY年M月D日LT dddd'\n        },\n        meridiemParse: /午前|午後/i,\n        isPM : function (input) {\n            return input === '午後';\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return '午前';\n            } else {\n                return '午後';\n            }\n        },\n        calendar : {\n            sameDay : '[今日] LT',\n            nextDay : '[明日] LT',\n            nextWeek : '[来週]dddd LT',\n            lastDay : '[昨日] LT',\n            lastWeek : '[前週]dddd LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s後',\n            past : '%s前',\n            s : '数秒',\n            m : '1分',\n            mm : '%d分',\n            h : '1時間',\n            hh : '%d時間',\n            d : '1日',\n            dd : '%d日',\n            M : '1ヶ月',\n            MM : '%dヶ月',\n            y : '1年',\n            yy : '%d年'\n        }\n    });\n\n    function ka__monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),\n            'accusative': 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')\n        },\n        nounCase = (/D[oD] *MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function ka__weekdaysCaseReplace(m, format) {\n        var weekdays = {\n            'nominative': 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),\n            'accusative': 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_')\n        },\n        nounCase = (/(წინა|შემდეგ)/).test(format) ?\n            'accusative' :\n            'nominative';\n        return weekdays[nounCase][m.day()];\n    }\n\n    var ka = _moment__default.defineLocale('ka', {\n        months : ka__monthsCaseReplace,\n        monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'),\n        weekdays : ka__weekdaysCaseReplace,\n        weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'),\n        weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'),\n        longDateFormat : {\n            LT : 'h:mm A',\n            LTS : 'h:mm:ss A',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[დღეს] LT[-ზე]',\n            nextDay : '[ხვალ] LT[-ზე]',\n            lastDay : '[გუშინ] LT[-ზე]',\n            nextWeek : '[შემდეგ] dddd LT[-ზე]',\n            lastWeek : '[წინა] dddd LT-ზე',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : function (s) {\n                return (/(წამი|წუთი|საათი|წელი)/).test(s) ?\n                    s.replace(/ი$/, 'ში') :\n                    s + 'ში';\n            },\n            past : function (s) {\n                if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {\n                    return s.replace(/(ი|ე)$/, 'ის წინ');\n                }\n                if ((/წელი/).test(s)) {\n                    return s.replace(/წელი$/, 'წლის წინ');\n                }\n            },\n            s : 'რამდენიმე წამი',\n            m : 'წუთი',\n            mm : '%d წუთი',\n            h : 'საათი',\n            hh : '%d საათი',\n            d : 'დღე',\n            dd : '%d დღე',\n            M : 'თვე',\n            MM : '%d თვე',\n            y : 'წელი',\n            yy : '%d წელი'\n        },\n        ordinalParse: /0|1-ლი|მე-\\d{1,2}|\\d{1,2}-ე/,\n        ordinal : function (number) {\n            if (number === 0) {\n                return number;\n            }\n            if (number === 1) {\n                return number + '-ლი';\n            }\n            if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {\n                return 'მე-' + number;\n            }\n            return number + '-ე';\n        },\n        week : {\n            dow : 1,\n            doy : 7\n        }\n    });\n\n    var km = _moment__default.defineLocale('km', {\n        months: 'មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n        monthsShort: 'មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n        weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n        weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n        weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n        longDateFormat: {\n            LT: 'HH:mm',\n            LTS : 'LT:ss',\n            L: 'DD/MM/YYYY',\n            LL: 'D MMMM YYYY',\n            LLL: 'D MMMM YYYY LT',\n            LLLL: 'dddd, D MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[ថ្ងៃនៈ ម៉ោង] LT',\n            nextDay: '[ស្អែក ម៉ោង] LT',\n            nextWeek: 'dddd [ម៉ោង] LT',\n            lastDay: '[ម្សិលមិញ ម៉ោង] LT',\n            lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',\n            sameElse: 'L'\n        },\n        relativeTime: {\n            future: '%sទៀត',\n            past: '%sមុន',\n            s: 'ប៉ុន្មានវិនាទី',\n            m: 'មួយនាទី',\n            mm: '%d នាទី',\n            h: 'មួយម៉ោង',\n            hh: '%d ម៉ោង',\n            d: 'មួយថ្ងៃ',\n            dd: '%d ថ្ងៃ',\n            M: 'មួយខែ',\n            MM: '%d ខែ',\n            y: 'មួយឆ្នាំ',\n            yy: '%d ឆ្នាំ'\n        },\n        week: {\n            dow: 1, // Monday is the first day of the week.\n            doy: 4 // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var ko = _moment__default.defineLocale('ko', {\n        months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n        monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n        weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),\n        weekdaysShort : '일_월_화_수_목_금_토'.split('_'),\n        weekdaysMin : '일_월_화_수_목_금_토'.split('_'),\n        longDateFormat : {\n            LT : 'A h시 m분',\n            LTS : 'A h시 m분 s초',\n            L : 'YYYY.MM.DD',\n            LL : 'YYYY년 MMMM D일',\n            LLL : 'YYYY년 MMMM D일 LT',\n            LLLL : 'YYYY년 MMMM D일 dddd LT'\n        },\n        calendar : {\n            sameDay : '오늘 LT',\n            nextDay : '내일 LT',\n            nextWeek : 'dddd LT',\n            lastDay : '어제 LT',\n            lastWeek : '지난주 dddd LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s 후',\n            past : '%s 전',\n            s : '몇초',\n            ss : '%d초',\n            m : '일분',\n            mm : '%d분',\n            h : '한시간',\n            hh : '%d시간',\n            d : '하루',\n            dd : '%d일',\n            M : '한달',\n            MM : '%d달',\n            y : '일년',\n            yy : '%d년'\n        },\n        ordinalParse : /\\d{1,2}일/,\n        ordinal : '%d일',\n        meridiemParse : /오전|오후/,\n        isPM : function (token) {\n            return token === '오후';\n        },\n        meridiem : function (hour, minute, isUpper) {\n            return hour < 12 ? '오전' : '오후';\n        }\n    });\n\n    function lb__processRelativeTime(number, withoutSuffix, key, isFuture) {\n        var format = {\n            'm': ['eng Minutt', 'enger Minutt'],\n            'h': ['eng Stonn', 'enger Stonn'],\n            'd': ['een Dag', 'engem Dag'],\n            'M': ['ee Mount', 'engem Mount'],\n            'y': ['ee Joer', 'engem Joer']\n        };\n        return withoutSuffix ? format[key][0] : format[key][1];\n    }\n    function processFutureTime(string) {\n        var number = string.substr(0, string.indexOf(' '));\n        if (eifelerRegelAppliesToNumber(number)) {\n            return 'a ' + string;\n        }\n        return 'an ' + string;\n    }\n    function processPastTime(string) {\n        var number = string.substr(0, string.indexOf(' '));\n        if (eifelerRegelAppliesToNumber(number)) {\n            return 'viru ' + string;\n        }\n        return 'virun ' + string;\n    }\n        function eifelerRegelAppliesToNumber(number) {\n        number = parseInt(number, 10);\n        if (isNaN(number)) {\n            return false;\n        }\n        if (number < 0) {\n            return true;\n        } else if (number < 10) {\n            if (4 <= number && number <= 7) {\n                return true;\n            }\n            return false;\n        } else if (number < 100) {\n            var lastDigit = number % 10, firstDigit = number / 10;\n            if (lastDigit === 0) {\n                return eifelerRegelAppliesToNumber(firstDigit);\n            }\n            return eifelerRegelAppliesToNumber(lastDigit);\n        } else if (number < 10000) {\n            while (number >= 10) {\n                number = number / 10;\n            }\n            return eifelerRegelAppliesToNumber(number);\n        } else {\n            number = number / 1000;\n            return eifelerRegelAppliesToNumber(number);\n        }\n    }\n\n    var lb = _moment__default.defineLocale('lb', {\n        months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n        monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n        weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'),\n        weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'),\n        weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'),\n        longDateFormat: {\n            LT: 'H:mm [Auer]',\n            LTS: 'H:mm:ss [Auer]',\n            L: 'DD.MM.YYYY',\n            LL: 'D. MMMM YYYY',\n            LLL: 'D. MMMM YYYY LT',\n            LLLL: 'dddd, D. MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[Haut um] LT',\n            sameElse: 'L',\n            nextDay: '[Muer um] LT',\n            nextWeek: 'dddd [um] LT',\n            lastDay: '[Gëschter um] LT',\n            lastWeek: function () {\n                switch (this.day()) {\n                    case 2:\n                    case 4:\n                        return '[Leschten] dddd [um] LT';\n                    default:\n                        return '[Leschte] dddd [um] LT';\n                }\n            }\n        },\n        relativeTime : {\n            future : processFutureTime,\n            past : processPastTime,\n            s : 'e puer Sekonnen',\n            m : lb__processRelativeTime,\n            mm : '%d Minutten',\n            h : lb__processRelativeTime,\n            hh : '%d Stonnen',\n            d : lb__processRelativeTime,\n            dd : '%d Deeg',\n            M : lb__processRelativeTime,\n            MM : '%d Méint',\n            y : lb__processRelativeTime,\n            yy : '%d Joer'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal: '%d.',\n        week: {\n            dow: 1, // Monday is the first day of the week.\n            doy: 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var lt__units = {\n        'm' : 'minutė_minutės_minutę',\n        'mm': 'minutės_minučių_minutes',\n        'h' : 'valanda_valandos_valandą',\n        'hh': 'valandos_valandų_valandas',\n        'd' : 'diena_dienos_dieną',\n        'dd': 'dienos_dienų_dienas',\n        'M' : 'mėnuo_mėnesio_mėnesį',\n        'MM': 'mėnesiai_mėnesių_mėnesius',\n        'y' : 'metai_metų_metus',\n        'yy': 'metai_metų_metus'\n    },\n    weekDays = 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_');\n    function translateSeconds(number, withoutSuffix, key, isFuture) {\n        if (withoutSuffix) {\n            return 'kelios sekundės';\n        } else {\n            return isFuture ? 'kelių sekundžių' : 'kelias sekundes';\n        }\n    }\n    function translateSingular(number, withoutSuffix, key, isFuture) {\n        return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);\n    }\n    function special(number) {\n        return number % 10 === 0 || (number > 10 && number < 20);\n    }\n    function forms(key) {\n        return lt__units[key].split('_');\n    }\n    function lt__translate(number, withoutSuffix, key, isFuture) {\n        var result = number + ' ';\n        if (number === 1) {\n            return result + translateSingular(number, withoutSuffix, key[0], isFuture);\n        } else if (withoutSuffix) {\n            return result + (special(number) ? forms(key)[1] : forms(key)[0]);\n        } else {\n            if (isFuture) {\n                return result + forms(key)[1];\n            } else {\n                return result + (special(number) ? forms(key)[1] : forms(key)[2]);\n            }\n        }\n    }\n    function relativeWeekDay(moment, format) {\n        var nominative = format.indexOf('dddd HH:mm') === -1,\n            weekDay = weekDays[moment.day()];\n        return nominative ? weekDay : weekDay.substring(0, weekDay.length - 2) + 'į';\n    }\n\n    var lt = _moment__default.defineLocale('lt', {\n        months : 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),\n        monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),\n        weekdays : relativeWeekDay,\n        weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),\n        weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'YYYY [m.] MMMM D [d.]',\n            LLL : 'YYYY [m.] MMMM D [d.], LT [val.]',\n            LLLL : 'YYYY [m.] MMMM D [d.], dddd, LT [val.]',\n            l : 'YYYY-MM-DD',\n            ll : 'YYYY [m.] MMMM D [d.]',\n            lll : 'YYYY [m.] MMMM D [d.], LT [val.]',\n            llll : 'YYYY [m.] MMMM D [d.], ddd, LT [val.]'\n        },\n        calendar : {\n            sameDay : '[Šiandien] LT',\n            nextDay : '[Rytoj] LT',\n            nextWeek : 'dddd LT',\n            lastDay : '[Vakar] LT',\n            lastWeek : '[Praėjusį] dddd LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'po %s',\n            past : 'prieš %s',\n            s : translateSeconds,\n            m : translateSingular,\n            mm : lt__translate,\n            h : translateSingular,\n            hh : lt__translate,\n            d : translateSingular,\n            dd : lt__translate,\n            M : translateSingular,\n            MM : lt__translate,\n            y : translateSingular,\n            yy : lt__translate\n        },\n        ordinalParse: /\\d{1,2}-oji/,\n        ordinal : function (number) {\n            return number + '-oji';\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var lv__units = {\n        'mm': 'minūti_minūtes_minūte_minūtes',\n        'hh': 'stundu_stundas_stunda_stundas',\n        'dd': 'dienu_dienas_diena_dienas',\n        'MM': 'mēnesi_mēnešus_mēnesis_mēneši',\n        'yy': 'gadu_gadus_gads_gadi'\n    };\n    function lv__format(word, number, withoutSuffix) {\n        var forms = word.split('_');\n        if (withoutSuffix) {\n            return number % 10 === 1 && number !== 11 ? forms[2] : forms[3];\n        } else {\n            return number % 10 === 1 && number !== 11 ? forms[0] : forms[1];\n        }\n    }\n    function lv__relativeTimeWithPlural(number, withoutSuffix, key) {\n        return number + ' ' + lv__format(lv__units[key], number, withoutSuffix);\n    }\n\n    var lv = _moment__default.defineLocale('lv', {\n        months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'),\n        weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'),\n        weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'),\n        weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'YYYY. [gada] D. MMMM',\n            LLL : 'YYYY. [gada] D. MMMM, LT',\n            LLLL : 'YYYY. [gada] D. MMMM, dddd, LT'\n        },\n        calendar : {\n            sameDay : '[Šodien pulksten] LT',\n            nextDay : '[Rīt pulksten] LT',\n            nextWeek : 'dddd [pulksten] LT',\n            lastDay : '[Vakar pulksten] LT',\n            lastWeek : '[Pagājušā] dddd [pulksten] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s vēlāk',\n            past : '%s agrāk',\n            s : 'dažas sekundes',\n            m : 'minūti',\n            mm : lv__relativeTimeWithPlural,\n            h : 'stundu',\n            hh : lv__relativeTimeWithPlural,\n            d : 'dienu',\n            dd : lv__relativeTimeWithPlural,\n            M : 'mēnesi',\n            MM : lv__relativeTimeWithPlural,\n            y : 'gadu',\n            yy : lv__relativeTimeWithPlural\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var mk = _moment__default.defineLocale('mk', {\n        months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'),\n        monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'),\n        weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'),\n        weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'),\n        weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'D.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Денес во] LT',\n            nextDay : '[Утре во] LT',\n            nextWeek : 'dddd [во] LT',\n            lastDay : '[Вчера во] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[Во изминатата] dddd [во] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[Во изминатиот] dddd [во] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'после %s',\n            past : 'пред %s',\n            s : 'неколку секунди',\n            m : 'минута',\n            mm : '%d минути',\n            h : 'час',\n            hh : '%d часа',\n            d : 'ден',\n            dd : '%d дена',\n            M : 'месец',\n            MM : '%d месеци',\n            y : 'година',\n            yy : '%d години'\n        },\n        ordinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n        ordinal : function (number) {\n            var lastDigit = number % 10,\n                last2Digits = number % 100;\n            if (number === 0) {\n                return number + '-ев';\n            } else if (last2Digits === 0) {\n                return number + '-ен';\n            } else if (last2Digits > 10 && last2Digits < 20) {\n                return number + '-ти';\n            } else if (lastDigit === 1) {\n                return number + '-ви';\n            } else if (lastDigit === 2) {\n                return number + '-ри';\n            } else if (lastDigit === 7 || lastDigit === 8) {\n                return number + '-ми';\n            } else {\n                return number + '-ти';\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var ml = _moment__default.defineLocale('ml', {\n        months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'),\n        monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'),\n        weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'),\n        weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'),\n        weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm -നു',\n            LTS : 'A h:mm:ss -നു',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        calendar : {\n            sameDay : '[ഇന്ന്] LT',\n            nextDay : '[നാളെ] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[ഇന്നലെ] LT',\n            lastWeek : '[കഴിഞ്ഞ] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s കഴിഞ്ഞ്',\n            past : '%s മുൻപ്',\n            s : 'അൽപ നിമിഷങ്ങൾ',\n            m : 'ഒരു മിനിറ്റ്',\n            mm : '%d മിനിറ്റ്',\n            h : 'ഒരു മണിക്കൂർ',\n            hh : '%d മണിക്കൂർ',\n            d : 'ഒരു ദിവസം',\n            dd : '%d ദിവസം',\n            M : 'ഒരു മാസം',\n            MM : '%d മാസം',\n            y : 'ഒരു വർഷം',\n            yy : '%d വർഷം'\n        },\n        meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,\n        isPM : function (input) {\n            return /^(ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'രാത്രി';\n            } else if (hour < 12) {\n                return 'രാവിലെ';\n            } else if (hour < 17) {\n                return 'ഉച്ച കഴിഞ്ഞ്';\n            } else if (hour < 20) {\n                return 'വൈകുന്നേരം';\n            } else {\n                return 'രാത്രി';\n            }\n        }\n    });\n\n    var mr__symbolMap = {\n        '1': '१',\n        '2': '२',\n        '3': '३',\n        '4': '४',\n        '5': '५',\n        '6': '६',\n        '7': '७',\n        '8': '८',\n        '9': '९',\n        '0': '०'\n    },\n    mr__numberMap = {\n        '१': '1',\n        '२': '2',\n        '३': '3',\n        '४': '4',\n        '५': '5',\n        '६': '6',\n        '७': '7',\n        '८': '8',\n        '९': '9',\n        '०': '0'\n    };\n\n    var mr = _moment__default.defineLocale('mr', {\n        months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'),\n        monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'),\n        weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n        weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),\n        weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n        longDateFormat : {\n            LT : 'A h:mm वाजता',\n            LTS : 'A h:mm:ss वाजता',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        calendar : {\n            sameDay : '[आज] LT',\n            nextDay : '[उद्या] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[काल] LT',\n            lastWeek: '[मागील] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s नंतर',\n            past : '%s पूर्वी',\n            s : 'सेकंद',\n            m: 'एक मिनिट',\n            mm: '%d मिनिटे',\n            h : 'एक तास',\n            hh : '%d तास',\n            d : 'एक दिवस',\n            dd : '%d दिवस',\n            M : 'एक महिना',\n            MM : '%d महिने',\n            y : 'एक वर्ष',\n            yy : '%d वर्षे'\n        },\n        preparse: function (string) {\n            return string.replace(/[१२३४५६७८९०]/g, function (match) {\n                return mr__numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return mr__symbolMap[match];\n            });\n        },\n        meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'रात्री') {\n                return hour < 4 ? hour : hour + 12;\n            } else if (meridiem === 'सकाळी') {\n                return hour;\n            } else if (meridiem === 'दुपारी') {\n                return hour >= 10 ? hour : hour + 12;\n            } else if (meridiem === 'सायंकाळी') {\n                return hour + 12;\n            }\n        },\n        meridiem: function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'रात्री';\n            } else if (hour < 10) {\n                return 'सकाळी';\n            } else if (hour < 17) {\n                return 'दुपारी';\n            } else if (hour < 20) {\n                return 'सायंकाळी';\n            } else {\n                return 'रात्री';\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var ms_my = _moment__default.defineLocale('ms-my', {\n        months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n        monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n        weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n        weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n        weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n        longDateFormat : {\n            LT : 'HH.mm',\n            LTS : 'LT.ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY [pukul] LT',\n            LLLL : 'dddd, D MMMM YYYY [pukul] LT'\n        },\n        meridiemParse: /pagi|tengahari|petang|malam/,\n        meridiemHour: function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'pagi') {\n                return hour;\n            } else if (meridiem === 'tengahari') {\n                return hour >= 11 ? hour : hour + 12;\n            } else if (meridiem === 'petang' || meridiem === 'malam') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hours, minutes, isLower) {\n            if (hours < 11) {\n                return 'pagi';\n            } else if (hours < 15) {\n                return 'tengahari';\n            } else if (hours < 19) {\n                return 'petang';\n            } else {\n                return 'malam';\n            }\n        },\n        calendar : {\n            sameDay : '[Hari ini pukul] LT',\n            nextDay : '[Esok pukul] LT',\n            nextWeek : 'dddd [pukul] LT',\n            lastDay : '[Kelmarin pukul] LT',\n            lastWeek : 'dddd [lepas pukul] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'dalam %s',\n            past : '%s yang lepas',\n            s : 'beberapa saat',\n            m : 'seminit',\n            mm : '%d minit',\n            h : 'sejam',\n            hh : '%d jam',\n            d : 'sehari',\n            dd : '%d hari',\n            M : 'sebulan',\n            MM : '%d bulan',\n            y : 'setahun',\n            yy : '%d tahun'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var my__symbolMap = {\n        '1': '၁',\n        '2': '၂',\n        '3': '၃',\n        '4': '၄',\n        '5': '၅',\n        '6': '၆',\n        '7': '၇',\n        '8': '၈',\n        '9': '၉',\n        '0': '၀'\n    }, my__numberMap = {\n        '၁': '1',\n        '၂': '2',\n        '၃': '3',\n        '၄': '4',\n        '၅': '5',\n        '၆': '6',\n        '၇': '7',\n        '၈': '8',\n        '၉': '9',\n        '၀': '0'\n    };\n\n    var my = _moment__default.defineLocale('my', {\n        months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'),\n        monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'),\n        weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'),\n        weekdaysShort: 'နွေ_လာ_င်္ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n        weekdaysMin: 'နွေ_လာ_င်္ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n        longDateFormat: {\n            LT: 'HH:mm',\n            LTS: 'HH:mm:ss',\n            L: 'DD/MM/YYYY',\n            LL: 'D MMMM YYYY',\n            LLL: 'D MMMM YYYY LT',\n            LLLL: 'dddd D MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[ယနေ.] LT [မှာ]',\n            nextDay: '[မနက်ဖြန်] LT [မှာ]',\n            nextWeek: 'dddd LT [မှာ]',\n            lastDay: '[မနေ.က] LT [မှာ]',\n            lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]',\n            sameElse: 'L'\n        },\n        relativeTime: {\n            future: 'လာမည့် %s မှာ',\n            past: 'လွန်ခဲ့သော %s က',\n            s: 'စက္ကန်.အနည်းငယ်',\n            m: 'တစ်မိနစ်',\n            mm: '%d မိနစ်',\n            h: 'တစ်နာရီ',\n            hh: '%d နာရီ',\n            d: 'တစ်ရက်',\n            dd: '%d ရက်',\n            M: 'တစ်လ',\n            MM: '%d လ',\n            y: 'တစ်နှစ်',\n            yy: '%d နှစ်'\n        },\n        preparse: function (string) {\n            return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) {\n                return my__numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return my__symbolMap[match];\n            });\n        },\n        week: {\n            dow: 1, // Monday is the first day of the week.\n            doy: 4 // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var nb = _moment__default.defineLocale('nb', {\n        months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n        weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n        weekdaysShort : 'søn_man_tirs_ons_tors_fre_lør'.split('_'),\n        weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n        longDateFormat : {\n            LT : 'H.mm',\n            LTS : 'LT.ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY [kl.] LT',\n            LLLL : 'dddd D. MMMM YYYY [kl.] LT'\n        },\n        calendar : {\n            sameDay: '[i dag kl.] LT',\n            nextDay: '[i morgen kl.] LT',\n            nextWeek: 'dddd [kl.] LT',\n            lastDay: '[i går kl.] LT',\n            lastWeek: '[forrige] dddd [kl.] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'om %s',\n            past : 'for %s siden',\n            s : 'noen sekunder',\n            m : 'ett minutt',\n            mm : '%d minutter',\n            h : 'en time',\n            hh : '%d timer',\n            d : 'en dag',\n            dd : '%d dager',\n            M : 'en måned',\n            MM : '%d måneder',\n            y : 'ett år',\n            yy : '%d år'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var ne__symbolMap = {\n        '1': '१',\n        '2': '२',\n        '3': '३',\n        '4': '४',\n        '5': '५',\n        '6': '६',\n        '7': '७',\n        '8': '८',\n        '9': '९',\n        '0': '०'\n    },\n    ne__numberMap = {\n        '१': '1',\n        '२': '2',\n        '३': '3',\n        '४': '4',\n        '५': '5',\n        '६': '6',\n        '७': '7',\n        '८': '8',\n        '९': '9',\n        '०': '0'\n    };\n\n    var ne = _moment__default.defineLocale('ne', {\n        months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'),\n        monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'),\n        weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'),\n        weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'),\n        weekdaysMin : 'आइ._सो._मङ्_बु._बि._शु._श.'.split('_'),\n        longDateFormat : {\n            LT : 'Aको h:mm बजे',\n            LTS : 'Aको h:mm:ss बजे',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        preparse: function (string) {\n            return string.replace(/[१२३४५६७८९०]/g, function (match) {\n                return ne__numberMap[match];\n            });\n        },\n        postformat: function (string) {\n            return string.replace(/\\d/g, function (match) {\n                return ne__symbolMap[match];\n            });\n        },\n        meridiemParse: /राती|बिहान|दिउँसो|बेलुका|साँझ|राती/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'राती') {\n                return hour < 3 ? hour : hour + 12;\n            } else if (meridiem === 'बिहान') {\n                return hour;\n            } else if (meridiem === 'दिउँसो') {\n                return hour >= 10 ? hour : hour + 12;\n            } else if (meridiem === 'बेलुका' || meridiem === 'साँझ') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 3) {\n                return 'राती';\n            } else if (hour < 10) {\n                return 'बिहान';\n            } else if (hour < 15) {\n                return 'दिउँसो';\n            } else if (hour < 18) {\n                return 'बेलुका';\n            } else if (hour < 20) {\n                return 'साँझ';\n            } else {\n                return 'राती';\n            }\n        },\n        calendar : {\n            sameDay : '[आज] LT',\n            nextDay : '[भोली] LT',\n            nextWeek : '[आउँदो] dddd[,] LT',\n            lastDay : '[हिजो] LT',\n            lastWeek : '[गएको] dddd[,] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%sमा',\n            past : '%s अगाडी',\n            s : 'केही समय',\n            m : 'एक मिनेट',\n            mm : '%d मिनेट',\n            h : 'एक घण्टा',\n            hh : '%d घण्टा',\n            d : 'एक दिन',\n            dd : '%d दिन',\n            M : 'एक महिना',\n            MM : '%d महिना',\n            y : 'एक बर्ष',\n            yy : '%d बर्ष'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var nl__monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n        nl__monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\n    var nl = _moment__default.defineLocale('nl', {\n        months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n        monthsShort : function (m, format) {\n            if (/-MMM-/.test(format)) {\n                return nl__monthsShortWithoutDots[m.month()];\n            } else {\n                return nl__monthsShortWithDots[m.month()];\n            }\n        },\n        weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n        weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n        weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD-MM-YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[vandaag om] LT',\n            nextDay: '[morgen om] LT',\n            nextWeek: 'dddd [om] LT',\n            lastDay: '[gisteren om] LT',\n            lastWeek: '[afgelopen] dddd [om] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'over %s',\n            past : '%s geleden',\n            s : 'een paar seconden',\n            m : 'één minuut',\n            mm : '%d minuten',\n            h : 'één uur',\n            hh : '%d uur',\n            d : 'één dag',\n            dd : '%d dagen',\n            M : 'één maand',\n            MM : '%d maanden',\n            y : 'één jaar',\n            yy : '%d jaar'\n        },\n        ordinalParse: /\\d{1,2}(ste|de)/,\n        ordinal : function (number) {\n            return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var nn = _moment__default.defineLocale('nn', {\n        months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n        weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'),\n        weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'),\n        weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[I dag klokka] LT',\n            nextDay: '[I morgon klokka] LT',\n            nextWeek: 'dddd [klokka] LT',\n            lastDay: '[I går klokka] LT',\n            lastWeek: '[Føregåande] dddd [klokka] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'om %s',\n            past : 'for %s sidan',\n            s : 'nokre sekund',\n            m : 'eit minutt',\n            mm : '%d minutt',\n            h : 'ein time',\n            hh : '%d timar',\n            d : 'ein dag',\n            dd : '%d dagar',\n            M : 'ein månad',\n            MM : '%d månader',\n            y : 'eit år',\n            yy : '%d år'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_'),\n        monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_');\n    function pl__plural(n) {\n        return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);\n    }\n    function pl__translate(number, withoutSuffix, key) {\n        var result = number + ' ';\n        switch (key) {\n        case 'm':\n            return withoutSuffix ? 'minuta' : 'minutę';\n        case 'mm':\n            return result + (pl__plural(number) ? 'minuty' : 'minut');\n        case 'h':\n            return withoutSuffix  ? 'godzina'  : 'godzinę';\n        case 'hh':\n            return result + (pl__plural(number) ? 'godziny' : 'godzin');\n        case 'MM':\n            return result + (pl__plural(number) ? 'miesiące' : 'miesięcy');\n        case 'yy':\n            return result + (pl__plural(number) ? 'lata' : 'lat');\n        }\n    }\n\n    var pl = _moment__default.defineLocale('pl', {\n        months : function (momentToFormat, format) {\n            if (/D MMMM/.test(format)) {\n                return monthsSubjective[momentToFormat.month()];\n            } else {\n                return monthsNominative[momentToFormat.month()];\n            }\n        },\n        monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),\n        weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'),\n        weekdaysShort : 'nie_pon_wt_śr_czw_pt_sb'.split('_'),\n        weekdaysMin : 'N_Pn_Wt_Śr_Cz_Pt_So'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Dziś o] LT',\n            nextDay: '[Jutro o] LT',\n            nextWeek: '[W] dddd [o] LT',\n            lastDay: '[Wczoraj o] LT',\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[W zeszłą niedzielę o] LT';\n                case 3:\n                    return '[W zeszłą środę o] LT';\n                case 6:\n                    return '[W zeszłą sobotę o] LT';\n                default:\n                    return '[W zeszły] dddd [o] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past : '%s temu',\n            s : 'kilka sekund',\n            m : pl__translate,\n            mm : pl__translate,\n            h : pl__translate,\n            hh : pl__translate,\n            d : '1 dzień',\n            dd : '%d dni',\n            M : 'miesiąc',\n            MM : pl__translate,\n            y : 'rok',\n            yy : pl__translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var pt_br = _moment__default.defineLocale('pt-br', {\n        months : 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split('_'),\n        monthsShort : 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'),\n        weekdays : 'domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado'.split('_'),\n        weekdaysShort : 'dom_seg_ter_qua_qui_sex_sáb'.split('_'),\n        weekdaysMin : 'dom_2ª_3ª_4ª_5ª_6ª_sáb'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D [de] MMMM [de] YYYY',\n            LLL : 'D [de] MMMM [de] YYYY [às] LT',\n            LLLL : 'dddd, D [de] MMMM [de] YYYY [às] LT'\n        },\n        calendar : {\n            sameDay: '[Hoje às] LT',\n            nextDay: '[Amanhã às] LT',\n            nextWeek: 'dddd [às] LT',\n            lastDay: '[Ontem às] LT',\n            lastWeek: function () {\n                return (this.day() === 0 || this.day() === 6) ?\n                    '[Último] dddd [às] LT' : // Saturday + Sunday\n                    '[Última] dddd [às] LT'; // Monday - Friday\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'em %s',\n            past : '%s atrás',\n            s : 'segundos',\n            m : 'um minuto',\n            mm : '%d minutos',\n            h : 'uma hora',\n            hh : '%d horas',\n            d : 'um dia',\n            dd : '%d dias',\n            M : 'um mês',\n            MM : '%d meses',\n            y : 'um ano',\n            yy : '%d anos'\n        },\n        ordinalParse: /\\d{1,2}º/,\n        ordinal : '%dº'\n    });\n\n    var pt = _moment__default.defineLocale('pt', {\n        months : 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split('_'),\n        monthsShort : 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'),\n        weekdays : 'domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado'.split('_'),\n        weekdaysShort : 'dom_seg_ter_qua_qui_sex_sáb'.split('_'),\n        weekdaysMin : 'dom_2ª_3ª_4ª_5ª_6ª_sáb'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D [de] MMMM [de] YYYY',\n            LLL : 'D [de] MMMM [de] YYYY LT',\n            LLLL : 'dddd, D [de] MMMM [de] YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Hoje às] LT',\n            nextDay: '[Amanhã às] LT',\n            nextWeek: 'dddd [às] LT',\n            lastDay: '[Ontem às] LT',\n            lastWeek: function () {\n                return (this.day() === 0 || this.day() === 6) ?\n                    '[Último] dddd [às] LT' : // Saturday + Sunday\n                    '[Última] dddd [às] LT'; // Monday - Friday\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'em %s',\n            past : 'há %s',\n            s : 'segundos',\n            m : 'um minuto',\n            mm : '%d minutos',\n            h : 'uma hora',\n            hh : '%d horas',\n            d : 'um dia',\n            dd : '%d dias',\n            M : 'um mês',\n            MM : '%d meses',\n            y : 'um ano',\n            yy : '%d anos'\n        },\n        ordinalParse: /\\d{1,2}º/,\n        ordinal : '%dº',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    function ro__relativeTimeWithPlural(number, withoutSuffix, key) {\n        var format = {\n                'mm': 'minute',\n                'hh': 'ore',\n                'dd': 'zile',\n                'MM': 'luni',\n                'yy': 'ani'\n            },\n            separator = ' ';\n        if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {\n            separator = ' de ';\n        }\n        return number + separator + format[key];\n    }\n\n    var ro = _moment__default.defineLocale('ro', {\n        months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'),\n        monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'),\n        weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'),\n        weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'),\n        weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY H:mm',\n            LLLL : 'dddd, D MMMM YYYY H:mm'\n        },\n        calendar : {\n            sameDay: '[azi la] LT',\n            nextDay: '[mâine la] LT',\n            nextWeek: 'dddd [la] LT',\n            lastDay: '[ieri la] LT',\n            lastWeek: '[fosta] dddd [la] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'peste %s',\n            past : '%s în urmă',\n            s : 'câteva secunde',\n            m : 'un minut',\n            mm : ro__relativeTimeWithPlural,\n            h : 'o oră',\n            hh : ro__relativeTimeWithPlural,\n            d : 'o zi',\n            dd : ro__relativeTimeWithPlural,\n            M : 'o lună',\n            MM : ro__relativeTimeWithPlural,\n            y : 'un an',\n            yy : ro__relativeTimeWithPlural\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    function ru__plural(word, num) {\n        var forms = word.split('_');\n        return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n    }\n    function ru__relativeTimeWithPlural(number, withoutSuffix, key) {\n        var format = {\n            'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',\n            'hh': 'час_часа_часов',\n            'dd': 'день_дня_дней',\n            'MM': 'месяц_месяца_месяцев',\n            'yy': 'год_года_лет'\n        };\n        if (key === 'm') {\n            return withoutSuffix ? 'минута' : 'минуту';\n        }\n        else {\n            return number + ' ' + ru__plural(format[key], +number);\n        }\n    }\n    function ru__monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n            'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')\n        },\n        nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function ru__monthsShortCaseReplace(m, format) {\n        var monthsShort = {\n            'nominative': 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),\n            'accusative': 'янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек'.split('_')\n        },\n        nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return monthsShort[nounCase][m.month()];\n    }\n    function ru__weekdaysCaseReplace(m, format) {\n        var weekdays = {\n            'nominative': 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),\n            'accusative': 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_')\n        },\n        nounCase = (/\\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\\] ?dddd/).test(format) ?\n            'accusative' :\n            'nominative';\n        return weekdays[nounCase][m.day()];\n    }\n\n    var ru = _moment__default.defineLocale('ru', {\n        months : ru__monthsCaseReplace,\n        monthsShort : ru__monthsShortCaseReplace,\n        weekdays : ru__weekdaysCaseReplace,\n        weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n        weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n        monthsParse : [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[й|я]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i],\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY г.',\n            LLL : 'D MMMM YYYY г., LT',\n            LLLL : 'dddd, D MMMM YYYY г., LT'\n        },\n        calendar : {\n            sameDay: '[Сегодня в] LT',\n            nextDay: '[Завтра в] LT',\n            lastDay: '[Вчера в] LT',\n            nextWeek: function () {\n                return this.day() === 2 ? '[Во] dddd [в] LT' : '[В] dddd [в] LT';\n            },\n            lastWeek: function (now) {\n                if (now.week() !== this.week()) {\n                    switch (this.day()) {\n                    case 0:\n                        return '[В прошлое] dddd [в] LT';\n                    case 1:\n                    case 2:\n                    case 4:\n                        return '[В прошлый] dddd [в] LT';\n                    case 3:\n                    case 5:\n                    case 6:\n                        return '[В прошлую] dddd [в] LT';\n                    }\n                } else {\n                    if (this.day() === 2) {\n                        return '[Во] dddd [в] LT';\n                    } else {\n                        return '[В] dddd [в] LT';\n                    }\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'через %s',\n            past : '%s назад',\n            s : 'несколько секунд',\n            m : ru__relativeTimeWithPlural,\n            mm : ru__relativeTimeWithPlural,\n            h : 'час',\n            hh : ru__relativeTimeWithPlural,\n            d : 'день',\n            dd : ru__relativeTimeWithPlural,\n            M : 'месяц',\n            MM : ru__relativeTimeWithPlural,\n            y : 'год',\n            yy : ru__relativeTimeWithPlural\n        },\n        meridiemParse: /ночи|утра|дня|вечера/i,\n        isPM : function (input) {\n            return /^(дня|вечера)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'ночи';\n            } else if (hour < 12) {\n                return 'утра';\n            } else if (hour < 17) {\n                return 'дня';\n            } else {\n                return 'вечера';\n            }\n        },\n        ordinalParse: /\\d{1,2}-(й|го|я)/,\n        ordinal: function (number, period) {\n            switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            case 'w':\n            case 'W':\n                return number + '-я';\n            default:\n                return number;\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var sk__months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_'),\n        sk__monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_');\n    function sk__plural(n) {\n        return (n > 1) && (n < 5);\n    }\n    function sk__translate(number, withoutSuffix, key, isFuture) {\n        var result = number + ' ';\n        switch (key) {\n        case 's':  // a few seconds / in a few seconds / a few seconds ago\n            return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';\n        case 'm':  // a minute / in a minute / a minute ago\n            return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');\n        case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n            if (withoutSuffix || isFuture) {\n                return result + (sk__plural(number) ? 'minúty' : 'minút');\n            } else {\n                return result + 'minútami';\n            }\n            break;\n        case 'h':  // an hour / in an hour / an hour ago\n            return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n        case 'hh': // 9 hours / in 9 hours / 9 hours ago\n            if (withoutSuffix || isFuture) {\n                return result + (sk__plural(number) ? 'hodiny' : 'hodín');\n            } else {\n                return result + 'hodinami';\n            }\n            break;\n        case 'd':  // a day / in a day / a day ago\n            return (withoutSuffix || isFuture) ? 'deň' : 'dňom';\n        case 'dd': // 9 days / in 9 days / 9 days ago\n            if (withoutSuffix || isFuture) {\n                return result + (sk__plural(number) ? 'dni' : 'dní');\n            } else {\n                return result + 'dňami';\n            }\n            break;\n        case 'M':  // a month / in a month / a month ago\n            return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';\n        case 'MM': // 9 months / in 9 months / 9 months ago\n            if (withoutSuffix || isFuture) {\n                return result + (sk__plural(number) ? 'mesiace' : 'mesiacov');\n            } else {\n                return result + 'mesiacmi';\n            }\n            break;\n        case 'y':  // a year / in a year / a year ago\n            return (withoutSuffix || isFuture) ? 'rok' : 'rokom';\n        case 'yy': // 9 years / in 9 years / 9 years ago\n            if (withoutSuffix || isFuture) {\n                return result + (sk__plural(number) ? 'roky' : 'rokov');\n            } else {\n                return result + 'rokmi';\n            }\n            break;\n        }\n    }\n\n    var sk = _moment__default.defineLocale('sk', {\n        months : sk__months,\n        monthsShort : sk__monthsShort,\n        monthsParse : (function (months, monthsShort) {\n            var i, _monthsParse = [];\n            for (i = 0; i < 12; i++) {\n                _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');\n            }\n            return _monthsParse;\n        }(sk__months, sk__monthsShort)),\n        weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'),\n        weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'),\n        weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),\n        longDateFormat : {\n            LT: 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[dnes o] LT',\n            nextDay: '[zajtra o] LT',\n            nextWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[v nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[v] dddd [o] LT';\n                case 3:\n                    return '[v stredu o] LT';\n                case 4:\n                    return '[vo štvrtok o] LT';\n                case 5:\n                    return '[v piatok o] LT';\n                case 6:\n                    return '[v sobotu o] LT';\n                }\n            },\n            lastDay: '[včera o] LT',\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[minulú nedeľu o] LT';\n                case 1:\n                case 2:\n                    return '[minulý] dddd [o] LT';\n                case 3:\n                    return '[minulú stredu o] LT';\n                case 4:\n                case 5:\n                    return '[minulý] dddd [o] LT';\n                case 6:\n                    return '[minulú sobotu o] LT';\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past : 'pred %s',\n            s : sk__translate,\n            m : sk__translate,\n            mm : sk__translate,\n            h : sk__translate,\n            hh : sk__translate,\n            d : sk__translate,\n            dd : sk__translate,\n            M : sk__translate,\n            MM : sk__translate,\n            y : sk__translate,\n            yy : sk__translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    function sl__translate(number, withoutSuffix, key) {\n        var result = number + ' ';\n        switch (key) {\n        case 'm':\n            return withoutSuffix ? 'ena minuta' : 'eno minuto';\n        case 'mm':\n            if (number === 1) {\n                result += 'minuta';\n            } else if (number === 2) {\n                result += 'minuti';\n            } else if (number === 3 || number === 4) {\n                result += 'minute';\n            } else {\n                result += 'minut';\n            }\n            return result;\n        case 'h':\n            return withoutSuffix ? 'ena ura' : 'eno uro';\n        case 'hh':\n            if (number === 1) {\n                result += 'ura';\n            } else if (number === 2) {\n                result += 'uri';\n            } else if (number === 3 || number === 4) {\n                result += 'ure';\n            } else {\n                result += 'ur';\n            }\n            return result;\n        case 'dd':\n            if (number === 1) {\n                result += 'dan';\n            } else {\n                result += 'dni';\n            }\n            return result;\n        case 'MM':\n            if (number === 1) {\n                result += 'mesec';\n            } else if (number === 2) {\n                result += 'meseca';\n            } else if (number === 3 || number === 4) {\n                result += 'mesece';\n            } else {\n                result += 'mesecev';\n            }\n            return result;\n        case 'yy':\n            if (number === 1) {\n                result += 'leto';\n            } else if (number === 2) {\n                result += 'leti';\n            } else if (number === 3 || number === 4) {\n                result += 'leta';\n            } else {\n                result += 'let';\n            }\n            return result;\n        }\n    }\n\n    var sl = _moment__default.defineLocale('sl', {\n        months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'),\n        monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'),\n        weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'),\n        weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'),\n        weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),\n        longDateFormat : {\n            LT : 'H:mm',\n            LTS : 'LT:ss',\n            L : 'DD. MM. YYYY',\n            LL : 'D. MMMM YYYY',\n            LLL : 'D. MMMM YYYY LT',\n            LLLL : 'dddd, D. MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay  : '[danes ob] LT',\n            nextDay  : '[jutri ob] LT',\n            nextWeek : function () {\n                switch (this.day()) {\n                case 0:\n                    return '[v] [nedeljo] [ob] LT';\n                case 3:\n                    return '[v] [sredo] [ob] LT';\n                case 6:\n                    return '[v] [soboto] [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[v] dddd [ob] LT';\n                }\n            },\n            lastDay  : '[včeraj ob] LT',\n            lastWeek : function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                case 6:\n                    return '[prejšnja] dddd [ob] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[prejšnji] dddd [ob] LT';\n                }\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'čez %s',\n            past   : '%s nazaj',\n            s      : 'nekaj sekund',\n            m      : sl__translate,\n            mm     : sl__translate,\n            h      : sl__translate,\n            hh     : sl__translate,\n            d      : 'en dan',\n            dd     : sl__translate,\n            M      : 'en mesec',\n            MM     : sl__translate,\n            y      : 'eno leto',\n            yy     : sl__translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var sq = _moment__default.defineLocale('sq', {\n        months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'),\n        monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'),\n        weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'),\n        weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'),\n        weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'),\n        meridiemParse: /PD|MD/,\n        isPM: function (input) {\n            return input.charAt(0) === 'M';\n        },\n        meridiem : function (hours, minutes, isLower) {\n            return hours < 12 ? 'PD' : 'MD';\n        },\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[Sot në] LT',\n            nextDay : '[Nesër në] LT',\n            nextWeek : 'dddd [në] LT',\n            lastDay : '[Dje në] LT',\n            lastWeek : 'dddd [e kaluar në] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'në %s',\n            past : '%s më parë',\n            s : 'disa sekonda',\n            m : 'një minutë',\n            mm : '%d minuta',\n            h : 'një orë',\n            hh : '%d orë',\n            d : 'një ditë',\n            dd : '%d ditë',\n            M : 'një muaj',\n            MM : '%d muaj',\n            y : 'një vit',\n            yy : '%d vite'\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var sr_cyrl__translator = {\n        words: { //Different grammatical cases\n            m: ['један минут', 'једне минуте'],\n            mm: ['минут', 'минуте', 'минута'],\n            h: ['један сат', 'једног сата'],\n            hh: ['сат', 'сата', 'сати'],\n            dd: ['дан', 'дана', 'дана'],\n            MM: ['месец', 'месеца', 'месеци'],\n            yy: ['година', 'године', 'година']\n        },\n        correctGrammaticalCase: function (number, wordKey) {\n            return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n        },\n        translate: function (number, withoutSuffix, key) {\n            var wordKey = sr_cyrl__translator.words[key];\n            if (key.length === 1) {\n                return withoutSuffix ? wordKey[0] : wordKey[1];\n            } else {\n                return number + ' ' + sr_cyrl__translator.correctGrammaticalCase(number, wordKey);\n            }\n        }\n    };\n\n    var sr_cyrl = _moment__default.defineLocale('sr-cyrl', {\n        months: ['јануар', 'фебруар', 'март', 'април', 'мај', 'јун', 'јул', 'август', 'септембар', 'октобар', 'новембар', 'децембар'],\n        monthsShort: ['јан.', 'феб.', 'мар.', 'апр.', 'мај', 'јун', 'јул', 'авг.', 'сеп.', 'окт.', 'нов.', 'дец.'],\n        weekdays: ['недеља', 'понедељак', 'уторак', 'среда', 'четвртак', 'петак', 'субота'],\n        weekdaysShort: ['нед.', 'пон.', 'уто.', 'сре.', 'чет.', 'пет.', 'суб.'],\n        weekdaysMin: ['не', 'по', 'ут', 'ср', 'че', 'пе', 'су'],\n        longDateFormat: {\n            LT: 'H:mm',\n            LTS : 'LT:ss',\n            L: 'DD. MM. YYYY',\n            LL: 'D. MMMM YYYY',\n            LLL: 'D. MMMM YYYY LT',\n            LLLL: 'dddd, D. MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[данас у] LT',\n            nextDay: '[сутра у] LT',\n            nextWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[у] [недељу] [у] LT';\n                case 3:\n                    return '[у] [среду] [у] LT';\n                case 6:\n                    return '[у] [суботу] [у] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[у] dddd [у] LT';\n                }\n            },\n            lastDay  : '[јуче у] LT',\n            lastWeek : function () {\n                var lastWeekDays = [\n                    '[прошле] [недеље] [у] LT',\n                    '[прошлог] [понедељка] [у] LT',\n                    '[прошлог] [уторка] [у] LT',\n                    '[прошле] [среде] [у] LT',\n                    '[прошлог] [четвртка] [у] LT',\n                    '[прошлог] [петка] [у] LT',\n                    '[прошле] [суботе] [у] LT'\n                ];\n                return lastWeekDays[this.day()];\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'за %s',\n            past   : 'пре %s',\n            s      : 'неколико секунди',\n            m      : sr_cyrl__translator.translate,\n            mm     : sr_cyrl__translator.translate,\n            h      : sr_cyrl__translator.translate,\n            hh     : sr_cyrl__translator.translate,\n            d      : 'дан',\n            dd     : sr_cyrl__translator.translate,\n            M      : 'месец',\n            MM     : sr_cyrl__translator.translate,\n            y      : 'годину',\n            yy     : sr_cyrl__translator.translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var sr__translator = {\n        words: { //Different grammatical cases\n            m: ['jedan minut', 'jedne minute'],\n            mm: ['minut', 'minute', 'minuta'],\n            h: ['jedan sat', 'jednog sata'],\n            hh: ['sat', 'sata', 'sati'],\n            dd: ['dan', 'dana', 'dana'],\n            MM: ['mesec', 'meseca', 'meseci'],\n            yy: ['godina', 'godine', 'godina']\n        },\n        correctGrammaticalCase: function (number, wordKey) {\n            return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n        },\n        translate: function (number, withoutSuffix, key) {\n            var wordKey = sr__translator.words[key];\n            if (key.length === 1) {\n                return withoutSuffix ? wordKey[0] : wordKey[1];\n            } else {\n                return number + ' ' + sr__translator.correctGrammaticalCase(number, wordKey);\n            }\n        }\n    };\n\n    var sr = _moment__default.defineLocale('sr', {\n        months: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'],\n        monthsShort: ['jan.', 'feb.', 'mar.', 'apr.', 'maj', 'jun', 'jul', 'avg.', 'sep.', 'okt.', 'nov.', 'dec.'],\n        weekdays: ['nedelja', 'ponedeljak', 'utorak', 'sreda', 'četvrtak', 'petak', 'subota'],\n        weekdaysShort: ['ned.', 'pon.', 'uto.', 'sre.', 'čet.', 'pet.', 'sub.'],\n        weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],\n        longDateFormat: {\n            LT: 'H:mm',\n            LTS : 'LT:ss',\n            L: 'DD. MM. YYYY',\n            LL: 'D. MMMM YYYY',\n            LLL: 'D. MMMM YYYY LT',\n            LLLL: 'dddd, D. MMMM YYYY LT'\n        },\n        calendar: {\n            sameDay: '[danas u] LT',\n            nextDay: '[sutra u] LT',\n            nextWeek: function () {\n                switch (this.day()) {\n                case 0:\n                    return '[u] [nedelju] [u] LT';\n                case 3:\n                    return '[u] [sredu] [u] LT';\n                case 6:\n                    return '[u] [subotu] [u] LT';\n                case 1:\n                case 2:\n                case 4:\n                case 5:\n                    return '[u] dddd [u] LT';\n                }\n            },\n            lastDay  : '[juče u] LT',\n            lastWeek : function () {\n                var lastWeekDays = [\n                    '[prošle] [nedelje] [u] LT',\n                    '[prošlog] [ponedeljka] [u] LT',\n                    '[prošlog] [utorka] [u] LT',\n                    '[prošle] [srede] [u] LT',\n                    '[prošlog] [četvrtka] [u] LT',\n                    '[prošlog] [petka] [u] LT',\n                    '[prošle] [subote] [u] LT'\n                ];\n                return lastWeekDays[this.day()];\n            },\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'za %s',\n            past   : 'pre %s',\n            s      : 'nekoliko sekundi',\n            m      : sr__translator.translate,\n            mm     : sr__translator.translate,\n            h      : sr__translator.translate,\n            hh     : sr__translator.translate,\n            d      : 'dan',\n            dd     : sr__translator.translate,\n            M      : 'mesec',\n            MM     : sr__translator.translate,\n            y      : 'godinu',\n            yy     : sr__translator.translate\n        },\n        ordinalParse: /\\d{1,2}\\./,\n        ordinal : '%d.',\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var sv = _moment__default.defineLocale('sv', {\n        months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'),\n        monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n        weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),\n        weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'),\n        weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'YYYY-MM-DD',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Idag] LT',\n            nextDay: '[Imorgon] LT',\n            lastDay: '[Igår] LT',\n            nextWeek: 'dddd LT',\n            lastWeek: '[Förra] dddd[en] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'om %s',\n            past : 'för %s sedan',\n            s : 'några sekunder',\n            m : 'en minut',\n            mm : '%d minuter',\n            h : 'en timme',\n            hh : '%d timmar',\n            d : 'en dag',\n            dd : '%d dagar',\n            M : 'en månad',\n            MM : '%d månader',\n            y : 'ett år',\n            yy : '%d år'\n        },\n        ordinalParse: /\\d{1,2}(e|a)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (~~(number % 100 / 10) === 1) ? 'e' :\n                (b === 1) ? 'a' :\n                (b === 2) ? 'a' :\n                (b === 3) ? 'e' : 'e';\n            return number + output;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var ta = _moment__default.defineLocale('ta', {\n        months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n        monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n        weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'),\n        weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'),\n        weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY, LT',\n            LLLL : 'dddd, D MMMM YYYY, LT'\n        },\n        calendar : {\n            sameDay : '[இன்று] LT',\n            nextDay : '[நாளை] LT',\n            nextWeek : 'dddd, LT',\n            lastDay : '[நேற்று] LT',\n            lastWeek : '[கடந்த வாரம்] dddd, LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s இல்',\n            past : '%s முன்',\n            s : 'ஒரு சில விநாடிகள்',\n            m : 'ஒரு நிமிடம்',\n            mm : '%d நிமிடங்கள்',\n            h : 'ஒரு மணி நேரம்',\n            hh : '%d மணி நேரம்',\n            d : 'ஒரு நாள்',\n            dd : '%d நாட்கள்',\n            M : 'ஒரு மாதம்',\n            MM : '%d மாதங்கள்',\n            y : 'ஒரு வருடம்',\n            yy : '%d ஆண்டுகள்'\n        },\n        ordinalParse: /\\d{1,2}வது/,\n        ordinal : function (number) {\n            return number + 'வது';\n        },\n        meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 2) {\n                return ' யாமம்';\n            } else if (hour < 6) {\n                return ' வைகறை';  // வைகறை\n            } else if (hour < 10) {\n                return ' காலை'; // காலை\n            } else if (hour < 14) {\n                return ' நண்பகல்'; // நண்பகல்\n            } else if (hour < 18) {\n                return ' எற்பாடு'; // எற்பாடு\n            } else if (hour < 22) {\n                return ' மாலை'; // மாலை\n            } else {\n                return ' யாமம்';\n            }\n        },\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === 'யாமம்') {\n                return hour < 2 ? hour : hour + 12;\n            } else if (meridiem === 'வைகறை' || meridiem === 'காலை') {\n                return hour;\n            } else if (meridiem === 'நண்பகல்') {\n                return hour >= 10 ? hour : hour + 12;\n            } else {\n                return hour + 12;\n            }\n        },\n        week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var th = _moment__default.defineLocale('th', {\n        months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'),\n        monthsShort : 'มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา'.split('_'),\n        weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'),\n        weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference\n        weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),\n        longDateFormat : {\n            LT : 'H นาฬิกา m นาที',\n            LTS : 'LT s วินาที',\n            L : 'YYYY/MM/DD',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY เวลา LT',\n            LLLL : 'วันddddที่ D MMMM YYYY เวลา LT'\n        },\n        meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,\n        isPM: function (input) {\n            return input === 'หลังเที่ยง';\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 12) {\n                return 'ก่อนเที่ยง';\n            } else {\n                return 'หลังเที่ยง';\n            }\n        },\n        calendar : {\n            sameDay : '[วันนี้ เวลา] LT',\n            nextDay : '[พรุ่งนี้ เวลา] LT',\n            nextWeek : 'dddd[หน้า เวลา] LT',\n            lastDay : '[เมื่อวานนี้ เวลา] LT',\n            lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'อีก %s',\n            past : '%sที่แล้ว',\n            s : 'ไม่กี่วินาที',\n            m : '1 นาที',\n            mm : '%d นาที',\n            h : '1 ชั่วโมง',\n            hh : '%d ชั่วโมง',\n            d : '1 วัน',\n            dd : '%d วัน',\n            M : '1 เดือน',\n            MM : '%d เดือน',\n            y : '1 ปี',\n            yy : '%d ปี'\n        }\n    });\n\n    var tl_ph = _moment__default.defineLocale('tl-ph', {\n        months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'),\n        monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),\n        weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'),\n        weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),\n        weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'MM/D/YYYY',\n            LL : 'MMMM D, YYYY',\n            LLL : 'MMMM D, YYYY LT',\n            LLLL : 'dddd, MMMM DD, YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Ngayon sa] LT',\n            nextDay: '[Bukas sa] LT',\n            nextWeek: 'dddd [sa] LT',\n            lastDay: '[Kahapon sa] LT',\n            lastWeek: 'dddd [huling linggo] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'sa loob ng %s',\n            past : '%s ang nakalipas',\n            s : 'ilang segundo',\n            m : 'isang minuto',\n            mm : '%d minuto',\n            h : 'isang oras',\n            hh : '%d oras',\n            d : 'isang araw',\n            dd : '%d araw',\n            M : 'isang buwan',\n            MM : '%d buwan',\n            y : 'isang taon',\n            yy : '%d taon'\n        },\n        ordinalParse: /\\d{1,2}/,\n        ordinal : function (number) {\n            return number;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var tr__suffixes = {\n        1: '\\'inci',\n        5: '\\'inci',\n        8: '\\'inci',\n        70: '\\'inci',\n        80: '\\'inci',\n        2: '\\'nci',\n        7: '\\'nci',\n        20: '\\'nci',\n        50: '\\'nci',\n        3: '\\'üncü',\n        4: '\\'üncü',\n        100: '\\'üncü',\n        6: '\\'ncı',\n        9: '\\'uncu',\n        10: '\\'uncu',\n        30: '\\'uncu',\n        60: '\\'ıncı',\n        90: '\\'ıncı'\n    };\n\n    var tr = _moment__default.defineLocale('tr', {\n        months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),\n        monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),\n        weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),\n        weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),\n        weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd, D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay : '[bugün saat] LT',\n            nextDay : '[yarın saat] LT',\n            nextWeek : '[haftaya] dddd [saat] LT',\n            lastDay : '[dün] LT',\n            lastWeek : '[geçen hafta] dddd [saat] LT',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : '%s sonra',\n            past : '%s önce',\n            s : 'birkaç saniye',\n            m : 'bir dakika',\n            mm : '%d dakika',\n            h : 'bir saat',\n            hh : '%d saat',\n            d : 'bir gün',\n            dd : '%d gün',\n            M : 'bir ay',\n            MM : '%d ay',\n            y : 'bir yıl',\n            yy : '%d yıl'\n        },\n        ordinalParse: /\\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,\n        ordinal : function (number) {\n            if (number === 0) {  // special case for zero\n                return number + '\\'ıncı';\n            }\n            var a = number % 10,\n                b = number % 100 - a,\n                c = number >= 100 ? 100 : null;\n            return number + (tr__suffixes[a] || tr__suffixes[b] || tr__suffixes[c]);\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var tzm_latn = _moment__default.defineLocale('tzm-latn', {\n        months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n        monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n        weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n        weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n        weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[asdkh g] LT',\n            nextDay: '[aska g] LT',\n            nextWeek: 'dddd [g] LT',\n            lastDay: '[assant g] LT',\n            lastWeek: 'dddd [g] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'dadkh s yan %s',\n            past : 'yan %s',\n            s : 'imik',\n            m : 'minuḍ',\n            mm : '%d minuḍ',\n            h : 'saɛa',\n            hh : '%d tassaɛin',\n            d : 'ass',\n            dd : '%d ossan',\n            M : 'ayowr',\n            MM : '%d iyyirn',\n            y : 'asgas',\n            yy : '%d isgasn'\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var tzm = _moment__default.defineLocale('tzm', {\n        months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n        monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n        weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n        weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n        weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS: 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'dddd D MMMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',\n            nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',\n            nextWeek: 'dddd [ⴴ] LT',\n            lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',\n            lastWeek: 'dddd [ⴴ] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s',\n            past : 'ⵢⴰⵏ %s',\n            s : 'ⵉⵎⵉⴽ',\n            m : 'ⵎⵉⵏⵓⴺ',\n            mm : '%d ⵎⵉⵏⵓⴺ',\n            h : 'ⵙⴰⵄⴰ',\n            hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ',\n            d : 'ⴰⵙⵙ',\n            dd : '%d oⵙⵙⴰⵏ',\n            M : 'ⴰⵢoⵓⵔ',\n            MM : '%d ⵉⵢⵢⵉⵔⵏ',\n            y : 'ⴰⵙⴳⴰⵙ',\n            yy : '%d ⵉⵙⴳⴰⵙⵏ'\n        },\n        week : {\n            dow : 6, // Saturday is the first day of the week.\n            doy : 12  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    function uk__plural(word, num) {\n        var forms = word.split('_');\n        return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n    }\n    function uk__relativeTimeWithPlural(number, withoutSuffix, key) {\n        var format = {\n            'mm': 'хвилина_хвилини_хвилин',\n            'hh': 'година_години_годин',\n            'dd': 'день_дні_днів',\n            'MM': 'місяць_місяці_місяців',\n            'yy': 'рік_роки_років'\n        };\n        if (key === 'm') {\n            return withoutSuffix ? 'хвилина' : 'хвилину';\n        }\n        else if (key === 'h') {\n            return withoutSuffix ? 'година' : 'годину';\n        }\n        else {\n            return number + ' ' + uk__plural(format[key], +number);\n        }\n    }\n    function uk__monthsCaseReplace(m, format) {\n        var months = {\n            'nominative': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_'),\n            'accusative': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_')\n        },\n        nounCase = (/D[oD]? *MMMM?/).test(format) ?\n            'accusative' :\n            'nominative';\n        return months[nounCase][m.month()];\n    }\n    function uk__weekdaysCaseReplace(m, format) {\n        var weekdays = {\n            'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),\n            'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),\n            'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')\n        },\n        nounCase = (/(\\[[ВвУу]\\]) ?dddd/).test(format) ?\n            'accusative' :\n            ((/\\[?(?:минулої|наступної)? ?\\] ?dddd/).test(format) ?\n                'genitive' :\n                'nominative');\n        return weekdays[nounCase][m.day()];\n    }\n    function processHoursFunction(str) {\n        return function () {\n            return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';\n        };\n    }\n\n    var uk = _moment__default.defineLocale('uk', {\n        months : uk__monthsCaseReplace,\n        monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),\n        weekdays : uk__weekdaysCaseReplace,\n        weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n        weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD.MM.YYYY',\n            LL : 'D MMMM YYYY р.',\n            LLL : 'D MMMM YYYY р., LT',\n            LLLL : 'dddd, D MMMM YYYY р., LT'\n        },\n        calendar : {\n            sameDay: processHoursFunction('[Сьогодні '),\n            nextDay: processHoursFunction('[Завтра '),\n            lastDay: processHoursFunction('[Вчора '),\n            nextWeek: processHoursFunction('[У] dddd ['),\n            lastWeek: function () {\n                switch (this.day()) {\n                case 0:\n                case 3:\n                case 5:\n                case 6:\n                    return processHoursFunction('[Минулої] dddd [').call(this);\n                case 1:\n                case 2:\n                case 4:\n                    return processHoursFunction('[Минулого] dddd [').call(this);\n                }\n            },\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : 'за %s',\n            past : '%s тому',\n            s : 'декілька секунд',\n            m : uk__relativeTimeWithPlural,\n            mm : uk__relativeTimeWithPlural,\n            h : 'годину',\n            hh : uk__relativeTimeWithPlural,\n            d : 'день',\n            dd : uk__relativeTimeWithPlural,\n            M : 'місяць',\n            MM : uk__relativeTimeWithPlural,\n            y : 'рік',\n            yy : uk__relativeTimeWithPlural\n        },\n        meridiemParse: /ночі|ранку|дня|вечора/,\n        isPM: function (input) {\n            return /^(дня|вечора)$/.test(input);\n        },\n        meridiem : function (hour, minute, isLower) {\n            if (hour < 4) {\n                return 'ночі';\n            } else if (hour < 12) {\n                return 'ранку';\n            } else if (hour < 17) {\n                return 'дня';\n            } else {\n                return 'вечора';\n            }\n        },\n        ordinalParse: /\\d{1,2}-(й|го)/,\n        ordinal: function (number, period) {\n            switch (period) {\n            case 'M':\n            case 'd':\n            case 'DDD':\n            case 'w':\n            case 'W':\n                return number + '-й';\n            case 'D':\n                return number + '-го';\n            default:\n                return number;\n            }\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 1st is the first week of the year.\n        }\n    });\n\n    var uz = _moment__default.defineLocale('uz', {\n        months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n        monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),\n        weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'),\n        weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'),\n        weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM YYYY',\n            LLL : 'D MMMM YYYY LT',\n            LLLL : 'D MMMM YYYY, dddd LT'\n        },\n        calendar : {\n            sameDay : '[Бугун соат] LT [да]',\n            nextDay : '[Эртага] LT [да]',\n            nextWeek : 'dddd [куни соат] LT [да]',\n            lastDay : '[Кеча соат] LT [да]',\n            lastWeek : '[Утган] dddd [куни соат] LT [да]',\n            sameElse : 'L'\n        },\n        relativeTime : {\n            future : 'Якин %s ичида',\n            past : 'Бир неча %s олдин',\n            s : 'фурсат',\n            m : 'бир дакика',\n            mm : '%d дакика',\n            h : 'бир соат',\n            hh : '%d соат',\n            d : 'бир кун',\n            dd : '%d кун',\n            M : 'бир ой',\n            MM : '%d ой',\n            y : 'бир йил',\n            yy : '%d йил'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 7  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var vi = _moment__default.defineLocale('vi', {\n        months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'),\n        monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'),\n        weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'),\n        weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n        weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n        longDateFormat : {\n            LT : 'HH:mm',\n            LTS : 'LT:ss',\n            L : 'DD/MM/YYYY',\n            LL : 'D MMMM [năm] YYYY',\n            LLL : 'D MMMM [năm] YYYY LT',\n            LLLL : 'dddd, D MMMM [năm] YYYY LT',\n            l : 'DD/M/YYYY',\n            ll : 'D MMM YYYY',\n            lll : 'D MMM YYYY LT',\n            llll : 'ddd, D MMM YYYY LT'\n        },\n        calendar : {\n            sameDay: '[Hôm nay lúc] LT',\n            nextDay: '[Ngày mai lúc] LT',\n            nextWeek: 'dddd [tuần tới lúc] LT',\n            lastDay: '[Hôm qua lúc] LT',\n            lastWeek: 'dddd [tuần rồi lúc] LT',\n            sameElse: 'L'\n        },\n        relativeTime : {\n            future : '%s tới',\n            past : '%s trước',\n            s : 'vài giây',\n            m : 'một phút',\n            mm : '%d phút',\n            h : 'một giờ',\n            hh : '%d giờ',\n            d : 'một ngày',\n            dd : '%d ngày',\n            M : 'một tháng',\n            MM : '%d tháng',\n            y : 'một năm',\n            yy : '%d năm'\n        },\n        ordinalParse: /\\d{1,2}/,\n        ordinal : function (number) {\n            return number;\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var zh_cn = _moment__default.defineLocale('zh-cn', {\n        months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n        monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n        weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n        weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'),\n        weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n        longDateFormat : {\n            LT : 'Ah点mm',\n            LTS : 'Ah点m分s秒',\n            L : 'YYYY-MM-DD',\n            LL : 'YYYY年MMMD日',\n            LLL : 'YYYY年MMMD日LT',\n            LLLL : 'YYYY年MMMD日ddddLT',\n            l : 'YYYY-MM-DD',\n            ll : 'YYYY年MMMD日',\n            lll : 'YYYY年MMMD日LT',\n            llll : 'YYYY年MMMD日ddddLT'\n        },\n        meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n        meridiemHour: function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === '凌晨' || meridiem === '早上' ||\n                    meridiem === '上午') {\n                return hour;\n            } else if (meridiem === '下午' || meridiem === '晚上') {\n                return hour + 12;\n            } else {\n                return hour >= 11 ? hour : hour + 12;\n            }\n        },\n        meridiem : function (hour, minute, isLower) {\n            var hm = hour * 100 + minute;\n            if (hm < 600) {\n                return '凌晨';\n            } else if (hm < 900) {\n                return '早上';\n            } else if (hm < 1130) {\n                return '上午';\n            } else if (hm < 1230) {\n                return '中午';\n            } else if (hm < 1800) {\n                return '下午';\n            } else {\n                return '晚上';\n            }\n        },\n        calendar : {\n            sameDay : function () {\n                return this.minutes() === 0 ? '[今天]Ah[点整]' : '[今天]LT';\n            },\n            nextDay : function () {\n                return this.minutes() === 0 ? '[明天]Ah[点整]' : '[明天]LT';\n            },\n            lastDay : function () {\n                return this.minutes() === 0 ? '[昨天]Ah[点整]' : '[昨天]LT';\n            },\n            nextWeek : function () {\n                var startOfWeek, prefix;\n                startOfWeek = _moment__default().startOf('week');\n                prefix = this.unix() - startOfWeek.unix() >= 7 * 24 * 3600 ? '[下]' : '[本]';\n                return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';\n            },\n            lastWeek : function () {\n                var startOfWeek, prefix;\n                startOfWeek = _moment__default().startOf('week');\n                prefix = this.unix() < startOfWeek.unix()  ? '[上]' : '[本]';\n                return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';\n            },\n            sameElse : 'LL'\n        },\n        ordinalParse: /\\d{1,2}(日|月|周)/,\n        ordinal : function (number, period) {\n            switch (period) {\n            case 'd':\n            case 'D':\n            case 'DDD':\n                return number + '日';\n            case 'M':\n                return number + '月';\n            case 'w':\n            case 'W':\n                return number + '周';\n            default:\n                return number;\n            }\n        },\n        relativeTime : {\n            future : '%s内',\n            past : '%s前',\n            s : '几秒',\n            m : '1分钟',\n            mm : '%d分钟',\n            h : '1小时',\n            hh : '%d小时',\n            d : '1天',\n            dd : '%d天',\n            M : '1个月',\n            MM : '%d个月',\n            y : '1年',\n            yy : '%d年'\n        },\n        week : {\n            dow : 1, // Monday is the first day of the week.\n            doy : 4  // The week that contains Jan 4th is the first week of the year.\n        }\n    });\n\n    var zh_tw = _moment__default.defineLocale('zh-tw', {\n        months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n        monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n        weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n        weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n        weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n        longDateFormat : {\n            LT : 'Ah點mm',\n            LTS : 'Ah點m分s秒',\n            L : 'YYYY年MMMD日',\n            LL : 'YYYY年MMMD日',\n            LLL : 'YYYY年MMMD日LT',\n            LLLL : 'YYYY年MMMD日ddddLT',\n            l : 'YYYY年MMMD日',\n            ll : 'YYYY年MMMD日',\n            lll : 'YYYY年MMMD日LT',\n            llll : 'YYYY年MMMD日ddddLT'\n        },\n        meridiemParse: /早上|上午|中午|下午|晚上/,\n        meridiemHour : function (hour, meridiem) {\n            if (hour === 12) {\n                hour = 0;\n            }\n            if (meridiem === '早上' || meridiem === '上午') {\n                return hour;\n            } else if (meridiem === '中午') {\n                return hour >= 11 ? hour : hour + 12;\n            } else if (meridiem === '下午' || meridiem === '晚上') {\n                return hour + 12;\n            }\n        },\n        meridiem : function (hour, minute, isLower) {\n            var hm = hour * 100 + minute;\n            if (hm < 900) {\n                return '早上';\n            } else if (hm < 1130) {\n                return '上午';\n            } else if (hm < 1230) {\n                return '中午';\n            } else if (hm < 1800) {\n                return '下午';\n            } else {\n                return '晚上';\n            }\n        },\n        calendar : {\n            sameDay : '[今天]LT',\n            nextDay : '[明天]LT',\n            nextWeek : '[下]ddddLT',\n            lastDay : '[昨天]LT',\n            lastWeek : '[上]ddddLT',\n            sameElse : 'L'\n        },\n        ordinalParse: /\\d{1,2}(日|月|週)/,\n        ordinal : function (number, period) {\n            switch (period) {\n            case 'd' :\n            case 'D' :\n            case 'DDD' :\n                return number + '日';\n            case 'M' :\n                return number + '月';\n            case 'w' :\n            case 'W' :\n                return number + '週';\n            default :\n                return number;\n            }\n        },\n        relativeTime : {\n            future : '%s內',\n            past : '%s前',\n            s : '幾秒',\n            m : '一分鐘',\n            mm : '%d分鐘',\n            h : '一小時',\n            hh : '%d小時',\n            d : '一天',\n            dd : '%d天',\n            M : '一個月',\n            MM : '%d個月',\n            y : '一年',\n            yy : '%d年'\n        }\n    });\n\n    var moment_with_locales = _moment__default;\n\n    return moment_with_locales;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/min/tests.js",
    "content": "\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('af');\n\n    test('parse', function (assert) {\n        var tests = 'Januarie Jan_Februarie Feb_Maart Mar_April Apr_Mei Mei_Junie Jun_Julie Jul_Augustus Aug_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sondag, Februarie 14de 2010, 3:25:50 nm'],\n                ['ddd, hA',                            'Son, 3NM'],\n                ['M Mo MM MMMM MMM',                   '2 2de 02 Februarie Feb'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14de 14'],\n                ['d do dddd ddd dd',                   '0 0de Sondag Son So'],\n                ['DDD DDDo DDDD',                      '45 45ste 045'],\n                ['w wo ww',                            '6 6de 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'nm NM'],\n                ['[the] DDDo [day of the year]',       'the 45ste day of the year'],\n                ['LT',                                 '15:25'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 Februarie 2010'],\n                ['LLL',                                '14 Februarie 2010 15:25'],\n                ['LLLL',                               'Sondag, 14 Februarie 2010 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 Feb 2010'],\n                ['lll',                                '14 Feb 2010 15:25'],\n                ['llll',                               'Son, 14 Feb 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'Januarie Jan_Februarie Feb_Maart Mar_April Apr_Mei Mei_Junie Jun_Julie Jul_Augustus Aug_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'Sondag Son So_Maandag Maa Ma_Dinsdag Din Di_Woensdag Woe Wo_Donderdag Don Do_Vrydag Vry Vr_Saterdag Sat Sa'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '\\'n paar sekondes', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '\\'n minuut',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '\\'n minuut',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minute',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '\\'n uur',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '\\'n uur',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ure',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ure',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ure',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '\\'n dag',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '\\'n dag',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dae',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '\\'n dag',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dae',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dae',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '\\'n maand',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '\\'n maand',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '\\'n maand',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 maande',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 maande',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 maande',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '\\'n maand',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 maande',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '\\'n jaar',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jaar',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '\\'n jaar',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jaar',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'oor \\'n paar sekondes',  'prefix');\n        assert.equal(moment(0).from(30000), '\\'n paar sekondes gelede', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), '\\'n paar sekondes gelede',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'oor \\'n paar sekondes', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'oor 5 dae', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                   'Vandag om 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Vandag om 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Vandag om 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Môre om 02:00',    'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Vandag om 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Gister om 02:00',   'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[Laas] dddd [om] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[Laas] dddd [om] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[Laas] dddd [om] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ste', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1ste', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1ste', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),    '2 02 2de', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),    '2 02 2de', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('ar-ma');\n\n    test('parse', function (assert) {\n        var tests = 'يناير:يناير_فبراير:فبراير_مارس:مارس_أبريل:أبريل_ماي:ماي_يونيو:يونيو_يوليوز:يوليوز_غشت:غشت_شتنبر:شتنبر_أكتوبر:أكتوبر_نونبر:نونبر_دجنبر:دجنبر'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(':');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد, فبراير 14 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'احد, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2 02 فبراير فبراير'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14 14'],\n                ['d do dddd ddd dd',                   '0 0 الأحد احد ح'],\n                ['DDD DDDo DDDD',                      '45 45 045'],\n                ['w wo ww',                            '8 8 08'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n                ['LT',                                 '15:25'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 فبراير 2010'],\n                ['LLL',                                '14 فبراير 2010 15:25'],\n                ['LLLL',                               'الأحد 14 فبراير 2010 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 فبراير 2010'],\n                ['lll',                                '14 فبراير 2010 15:25'],\n                ['llll',                               'احد 14 فبراير 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'يناير يناير_فبراير فبراير_مارس مارس_أبريل أبريل_ماي ماي_يونيو يونيو_يوليوز يوليوز_غشت غشت_شتنبر شتنبر_أكتوبر أكتوبر_نونبر نونبر_دجنبر دجنبر'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'الأحد احد ح_الإتنين اتنين ن_الثلاثاء ثلاثاء ث_الأربعاء اربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ثوان', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 دقائق',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 دقائق',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ساعات',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ساعات',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ساعات',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 أيام',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 أيام',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 أيام',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 أشهر',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 أشهر',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 أشهر',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 أشهر',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'سنة',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 سنوات',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'سنة',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 سنوات',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'في ثوان',  'prefix');\n        assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'منذ ثوان',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'في ثوان', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'في 5 أيام', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'اليوم على الساعة 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم على الساعة 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم على الساعة 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'غدا على الساعة 02:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم على الساعة 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس على الساعة 02:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 31]).week(), 1, 'Dec 31 2011 should be week 1');\n        assert.equal(moment([2012,  0,  6]).week(), 1, 'Jan  6 2012 should be week 1');\n        assert.equal(moment([2012,  0,  7]).week(), 2, 'Jan  7 2012 should be week 2');\n        assert.equal(moment([2012,  0, 13]).week(), 2, 'Jan 13 2012 should be week 2');\n        assert.equal(moment([2012,  0, 14]).week(), 3, 'Jan 14 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 30]).week(), 1, 'Dec 30 2006 should be week 1');\n        assert.equal(moment([2007,  0,  5]).week(), 1, 'Jan  5 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 2, 'Jan  6 2007 should be week 2');\n        assert.equal(moment([2007,  0, 12]).week(), 2, 'Jan 12 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 3, 'Jan 13 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 1, 'Dec 29 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  4]).week(), 1, 'Jan  4 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 2, 'Jan  5 2008 should be week 2');\n        assert.equal(moment([2008,  0, 11]).week(), 2, 'Jan 11 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 3, 'Jan 12 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 28]).week(), 1, 'Dec 28 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  3]).week(), 1, 'Jan  3 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 2, 'Jan  4 2003 should be week 2');\n        assert.equal(moment([2003,  0, 10]).week(), 2, 'Jan 10 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 3, 'Jan 11 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 27]).week(), 1, 'Dec 27 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  2]).week(), 1, 'Jan  2 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 2, 'Jan  3 2009 should be week 2');\n        assert.equal(moment([2009,  0,  9]).week(), 2, 'Jan  9 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 3, 'Jan 10 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 26]).week(), 1, 'Dec 26 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 2, 'Jan  2 2010 should be week 2');\n        assert.equal(moment([2010,  0,  8]).week(), 2, 'Jan  8 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 3, 'Jan  9 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2011, 0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011, 0,  7]).week(), 1, 'Jan  7 2011 should be week 1');\n        assert.equal(moment([2011, 0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011, 0, 14]).week(), 2, 'Jan 14 2011 should be week 2');\n        assert.equal(moment([2011, 0, 15]).week(), 3, 'Jan 15 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n        assert.equal(moment([2012,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2012 should be week 1');\n        assert.equal(moment([2012,  0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 should be week 2');\n        assert.equal(moment([2012,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2012 should be week 2');\n        assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('ar-sa');\n\n    test('parse', function (assert) {\n        var tests = 'يناير:يناير_فبراير:فبراير_مارس:مارس_أبريل:أبريل_مايو:مايو_يونيو:يونيو_يوليو:يوليو_أغسطس:أغسطس_سبتمبر:سبتمبر_أكتوبر:أكتوبر_نوفمبر:نوفمبر_ديسمبر:ديسمبر'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' instead is month ' + moment(input, mmm).month());\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(':');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد، فبراير ١٤ ٢٠١٠، ٣:٢٥:٥٠ م'],\n                ['ddd, hA',                            'أحد، ٣م'],\n                ['M Mo MM MMMM MMM',                   '٢ ٢ ٠٢ فبراير فبراير'],\n                ['YYYY YY',                            '٢٠١٠ ١٠'],\n                ['D Do DD',                            '١٤ ١٤ ١٤'],\n                ['d do dddd ddd dd',                   '٠ ٠ الأحد أحد ح'],\n                ['DDD DDDo DDDD',                      '٤٥ ٤٥ ٠٤٥'],\n                ['w wo ww',                            '٨ ٨ ٠٨'],\n                ['h hh',                               '٣ ٠٣'],\n                ['H HH',                               '١٥ ١٥'],\n                ['m mm',                               '٢٥ ٢٥'],\n                ['s ss',                               '٥٠ ٥٠'],\n                ['a A',                                'م م'],\n                ['[the] DDDo [day of the year]',       'the ٤٥ day of the year'],\n                ['LT',                                 '١٥:٢٥'],\n                ['LTS',                                '١٥:٢٥:٥٠'],\n                ['L',                                  '١٤/٠٢/٢٠١٠'],\n                ['LL',                                 '١٤ فبراير ٢٠١٠'],\n                ['LLL',                                '١٤ فبراير ٢٠١٠ ١٥:٢٥'],\n                ['LLLL',                               'الأحد ١٤ فبراير ٢٠١٠ ١٥:٢٥'],\n                ['l',                                  '١٤/٢/٢٠١٠'],\n                ['ll',                                 '١٤ فبراير ٢٠١٠'],\n                ['lll',                                '١٤ فبراير ٢٠١٠ ١٥:٢٥'],\n                ['llll',                               'أحد ١٤ فبراير ٢٠١٠ ١٥:٢٥']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '١', '1');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '٢', '2');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '٣', '3');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '٤', '4');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '٥', '5');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '٦', '6');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '٧', '7');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '٨', '8');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '٩', '9');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '١٠', '10');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '١١', '11');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '١٢', '12');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '١٣', '13');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '١٤', '14');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '١٥', '15');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '١٦', '16');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '١٧', '17');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '١٨', '18');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '١٩', '19');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '٢٠', '20');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '٢١', '21');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '٢٢', '22');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '٢٣', '23');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '٢٤', '24');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '٢٥', '25');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '٢٦', '26');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '٢٧', '27');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '٢٨', '28');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '٢٩', '29');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '٣٠', '30');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '٣١', '31');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'يناير يناير_فبراير فبراير_مارس مارس_أبريل أبريل_مايو مايو_يونيو يونيو_يوليو يوليو_أغسطس أغسطس_سبتمبر سبتمبر_أكتوبر أكتوبر_نوفمبر نوفمبر_ديسمبر ديسمبر'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ثوان', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '٢ دقائق',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '٤٤ دقائق',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '٢ ساعات',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '٥ ساعات',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '٢١ ساعات',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '٢ أيام',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '٥ أيام',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '٢٥ أيام',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '٢ أشهر',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '٢ أشهر',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '٣ أشهر',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '٥ أشهر',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'سنة',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '٢ سنوات',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'سنة',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '٥ سنوات',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'في ثوان',  'prefix');\n        assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'منذ ثوان',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'في ثوان', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'في ٥ أيام', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'اليوم على الساعة ٠٢:٠٠',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم على الساعة ٠٢:٢٥',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم على الساعة ٠٣:٠٠',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'غدا على الساعة ٠٢:٠٠',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم على الساعة ٠١:٠٠',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس على الساعة ٠٢:٠٠', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [على الساعة] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 31]).week(), 1, 'Dec 31 2011 should be week 1');\n        assert.equal(moment([2012,  0,  6]).week(), 1, 'Jan  6 2012 should be week 1');\n        assert.equal(moment([2012,  0,  7]).week(), 2, 'Jan  7 2012 should be week 2');\n        assert.equal(moment([2012,  0, 13]).week(), 2, 'Jan 13 2012 should be week 2');\n        assert.equal(moment([2012,  0, 14]).week(), 3, 'Jan 14 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 30]).week(), 1, 'Dec 30 2006 should be week 1');\n        assert.equal(moment([2007,  0,  5]).week(), 1, 'Jan  5 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 2, 'Jan  6 2007 should be week 2');\n        assert.equal(moment([2007,  0, 12]).week(), 2, 'Jan 12 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 3, 'Jan 13 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 1, 'Dec 29 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  4]).week(), 1, 'Jan  4 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 2, 'Jan  5 2008 should be week 2');\n        assert.equal(moment([2008,  0, 11]).week(), 2, 'Jan 11 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 3, 'Jan 12 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 28]).week(), 1, 'Dec 28 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  3]).week(), 1, 'Jan  3 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 2, 'Jan  4 2003 should be week 2');\n        assert.equal(moment([2003,  0, 10]).week(), 2, 'Jan 10 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 3, 'Jan 11 2003 should be week 3');\n\n        assert.equal(moment('2003 1 6', 'gggg w d').format('YYYY-MM-DD'), '٢٠٠٢-١٢-٢٨', 'Week 1 of 2003 should be Dec 28 2002');\n        assert.equal(moment('2003 1 0', 'gggg w e').format('YYYY-MM-DD'), '٢٠٠٢-١٢-٢٨', 'Week 1 of 2003 should be Dec 28 2002');\n        assert.equal(moment('2003 1 6', 'gggg w d').format('gggg w d'), '٢٠٠٣ ١ ٦', 'Saturday of week 1 of 2003 parsed should be formatted as 2003 1 6');\n        assert.equal(moment('2003 1 0', 'gggg w e').format('gggg w e'), '٢٠٠٣ ١ ٠', '1st day of week 1 of 2003 parsed should be formatted as 2003 1 0');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 27]).week(), 1, 'Dec 27 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  2]).week(), 1, 'Jan  2 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 2, 'Jan  3 2009 should be week 2');\n        assert.equal(moment([2009,  0,  9]).week(), 2, 'Jan  9 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 3, 'Jan 10 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 26]).week(), 1, 'Dec 26 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 2, 'Jan  2 2010 should be week 2');\n        assert.equal(moment([2010,  0,  8]).week(), 2, 'Jan  8 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 3, 'Jan  9 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2011, 0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011, 0,  7]).week(), 1, 'Jan  7 2011 should be week 1');\n        assert.equal(moment([2011, 0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011, 0, 14]).week(), 2, 'Jan 14 2011 should be week 2');\n        assert.equal(moment([2011, 0, 15]).week(), 3, 'Jan 15 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 31]).format('w ww wo'), '١ ٠١ ١', 'Dec 31 2011 should be week 1');\n        assert.equal(moment([2012,  0,  6]).format('w ww wo'), '١ ٠١ ١', 'Jan  6 2012 should be week 1');\n        assert.equal(moment([2012,  0,  7]).format('w ww wo'), '٢ ٠٢ ٢', 'Jan  7 2012 should be week 2');\n        assert.equal(moment([2012,  0, 13]).format('w ww wo'), '٢ ٠٢ ٢', 'Jan 13 2012 should be week 2');\n        assert.equal(moment([2012,  0, 14]).format('w ww wo'), '٣ ٠٣ ٣', 'Jan 14 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('ar-tn');\n\n    test('parse', function (assert) {\n        var tests = 'جانفي:جانفي_فيفري:فيفري_مارس:مارس_أفريل:أفريل_ماي:ماي_جوان:جوان_جويلية:جويلية_أوت:أوت_سبتمبر:سبتمبر_أكتوبر:أكتوبر_نوفمبر:نوفمبر_ديسمبر:ديسمبر'.split('_'),\n            i;\n\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(':');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a', 'الأحد, فيفري 14 2010, 3:25:50 pm'],\n                ['ddd, hA', 'أحد, 3PM'],\n                ['M Mo MM MMMM MMM', '2 2 02 فيفري فيفري'],\n                ['YYYY YY', '2010 10'],\n                ['D Do DD', '14 14 14'],\n                ['d do dddd ddd dd', '0 0 الأحد أحد ح'],\n                ['DDD DDDo DDDD', '45 45 045'],\n                ['w wo ww', '6 6 06'],\n                ['h hh', '3 03'],\n                ['H HH', '15 15'],\n                ['m mm', '25 25'],\n                ['s ss', '50 50'],\n                ['a A', 'pm PM'],\n                ['[the] DDDo [day of the year]', 'the 45 day of the year'],\n                ['LT', '15:25'],\n                ['LTS', '15:25:50'],\n                ['L', '14/02/2010'],\n                ['LL', '14 فيفري 2010'],\n                ['LLL', '14 فيفري 2010 15:25'],\n                ['LLLL', 'الأحد 14 فيفري 2010 15:25'],\n                ['l', '14/2/2010'],\n                ['ll', '14 فيفري 2010'],\n                ['lll', '14 فيفري 2010 15:25'],\n                ['llll', 'أحد 14 فيفري 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'جانفي جانفي_فيفري فيفري_مارس مارس_أفريل أفريل_ماي ماي_جوان جوان_جويلية جويلية_أوت أوت_سبتمبر سبتمبر_أكتوبر أكتوبر_نوفمبر نوفمبر_ديسمبر ديسمبر'.split('_'),\n            i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'),\n            i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            s: 44\n        }), true), 'ثوان', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            s: 45\n        }), true), 'دقيقة', '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            s: 89\n        }), true), 'دقيقة', '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            s: 90\n        }), true), '2 دقائق', '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            m: 44\n        }), true), '44 دقائق', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            m: 45\n        }), true), 'ساعة', '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            m: 89\n        }), true), 'ساعة', '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            m: 90\n        }), true), '2 ساعات', '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            h: 5\n        }), true), '5 ساعات', '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            h: 21\n        }), true), '21 ساعات', '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            h: 22\n        }), true), 'يوم', '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            h: 35\n        }), true), 'يوم', '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            h: 36\n        }), true), '2 أيام', '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 1\n        }), true), 'يوم', '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 5\n        }), true), '5 أيام', '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 25\n        }), true), '25 أيام', '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 26\n        }), true), 'شهر', '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 30\n        }), true), 'شهر', '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 43\n        }), true), 'شهر', '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 46\n        }), true), '2 أشهر', '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 74\n        }), true), '2 أشهر', '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 76\n        }), true), '3 أشهر', '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            M: 1\n        }), true), 'شهر', '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            M: 5\n        }), true), '5 أشهر', '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 345\n        }), true), 'سنة', '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 548\n        }), true), '2 سنوات', '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            y: 1\n        }), true), 'سنة', '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            y: 5\n        }), true), '5 سنوات', '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'في ثوان', 'prefix');\n        assert.equal(moment(0).from(30000), 'منذ ثوان', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'منذ ثوان', 'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({\n            s: 30\n        }).fromNow(), 'في ثوان', 'in a few seconds');\n        assert.equal(moment().add({\n            d: 5\n        }).fromNow(), 'في 5 أيام', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(), 'اليوم على الساعة 02:00', 'today at the same time');\n        assert.equal(moment(a).add({\n            m: 25\n        }).calendar(), 'اليوم على الساعة 02:25', 'Now plus 25 min');\n        assert.equal(moment(a).add({\n            h: 1\n        }).calendar(), 'اليوم على الساعة 03:00', 'Now plus 1 hour');\n        assert.equal(moment(a).add({\n            d: 1\n        }).calendar(), 'غدا على الساعة 02:00', 'tomorrow at the same time');\n        assert.equal(moment(a).subtract({\n            h: 1\n        }).calendar(), 'اليوم على الساعة 01:00', 'Now minus 1 hour');\n        assert.equal(moment(a).subtract({\n            d: 1\n        }).calendar(), 'أمس على الساعة 02:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({\n                d: i\n            });\n            assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({\n                d: i\n            });\n            assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(), m.format('dddd [على الساعة] LT'), 'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({\n                w: 1\n            }),\n            weeksFromNow = moment().add({\n                w: 1\n            });\n\n        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n        assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n        weeksAgo = moment().subtract({\n            w: 2\n        });\n        weeksFromNow = moment().add({\n            w: 2\n        });\n\n        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('ar');\n\n    var months = [\n        'كانون الثاني يناير',\n        'شباط فبراير',\n        'آذار مارس',\n        'نيسان أبريل',\n        'أيار مايو',\n        'حزيران يونيو',\n        'تموز يوليو',\n        'آب أغسطس',\n        'أيلول سبتمبر',\n        'تشرين الأول أكتوبر',\n        'تشرين الثاني نوفمبر',\n        'كانون الأول ديسمبر'\n    ];\n\n    test('parse', function (assert) {\n        var tests = months, i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' instead is month ' + moment(input, mmm).month());\n        }\n        for (i = 0; i < 12; i++) {\n            equalTest(tests[i], 'MMM', i);\n            equalTest(tests[i], 'MMM', i);\n            equalTest(tests[i], 'MMMM', i);\n            equalTest(tests[i], 'MMMM', i);\n            equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'الأحد، شباط فبراير ١٤ ٢٠١٠، ٣:٢٥:٥٠ م'],\n                ['ddd, hA',                            'أحد، ٣م'],\n                ['M Mo MM MMMM MMM',                   '٢ ٢ ٠٢ شباط فبراير شباط فبراير'],\n                ['YYYY YY',                            '٢٠١٠ ١٠'],\n                ['D Do DD',                            '١٤ ١٤ ١٤'],\n                ['d do dddd ddd dd',                   '٠ ٠ الأحد أحد ح'],\n                ['DDD DDDo DDDD',                      '٤٥ ٤٥ ٠٤٥'],\n                ['w wo ww',                            '٨ ٨ ٠٨'],\n                ['h hh',                               '٣ ٠٣'],\n                ['H HH',                               '١٥ ١٥'],\n                ['m mm',                               '٢٥ ٢٥'],\n                ['s ss',                               '٥٠ ٥٠'],\n                ['a A',                                'م م'],\n                ['[the] DDDo [day of the year]',       'the ٤٥ day of the year'],\n                ['LT',                                 '١٥:٢٥'],\n                ['LTS',                                '١٥:٢٥:٥٠'],\n                ['L',                                  '١٤/٠٢/٢٠١٠'],\n                ['LL',                                 '١٤ شباط فبراير ٢٠١٠'],\n                ['LLL',                                '١٤ شباط فبراير ٢٠١٠ ١٥:٢٥'],\n                ['LLLL',                               'الأحد ١٤ شباط فبراير ٢٠١٠ ١٥:٢٥'],\n                ['l',                                  '١٤/٢/٢٠١٠'],\n                ['ll',                                 '١٤ شباط فبراير ٢٠١٠'],\n                ['lll',                                '١٤ شباط فبراير ٢٠١٠ ١٥:٢٥'],\n                ['llll',                               'أحد ١٤ شباط فبراير ٢٠١٠ ١٥:٢٥']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '١', '1');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '٢', '2');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '٣', '3');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '٤', '4');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '٥', '5');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '٦', '6');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '٧', '7');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '٨', '8');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '٩', '9');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '١٠', '10');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '١١', '11');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '١٢', '12');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '١٣', '13');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '١٤', '14');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '١٥', '15');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '١٦', '16');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '١٧', '17');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '١٨', '18');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '١٩', '19');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '٢٠', '20');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '٢١', '21');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '٢٢', '22');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '٢٣', '23');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '٢٤', '24');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '٢٥', '25');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '٢٦', '26');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '٢٧', '27');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '٢٨', '28');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '٢٩', '29');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '٣٠', '30');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '٣١', '31');\n    });\n\n    test('format month', function (assert) {\n        var expected = months, i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM'), expected[i], expected[i]);\n            assert.equal(moment([2011, i, 1]).format('MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'الأحد أحد ح_الإثنين إثنين ن_الثلاثاء ثلاثاء ث_الأربعاء أربعاء ر_الخميس خميس خ_الجمعة جمعة ج_السبت سبت س'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '٤٤ ثانية', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'دقيقة واحدة',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'دقيقة واحدة',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'دقيقتان',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '٤٤ دقيقة',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ساعة واحدة',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ساعة واحدة',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'ساعتان',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '٥ ساعات',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '٢١ ساعة',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'يوم واحد',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'يوم واحد',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'يومان',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'يوم واحد',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '٥ أيام',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '٢٥ يومًا',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'شهر واحد',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'شهر واحد',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'شهر واحد',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'شهران',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'شهران',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '٣ أشهر',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'شهر واحد',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '٥ أشهر',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'عام واحد',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'عامان',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'عام واحد',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '٥ أعوام',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'بعد ٣٠ ثانية',  'prefix');\n        assert.equal(moment(0).from(30000), 'منذ ٣٠ ثانية', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'منذ ثانية واحدة',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'بعد ٣٠ ثانية', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'بعد ٥ أيام', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'اليوم عند الساعة ٠٢:٠٠',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'اليوم عند الساعة ٠٢:٢٥',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'اليوم عند الساعة ٠٣:٠٠',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'غدًا عند الساعة ٠٢:٠٠',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'اليوم عند الساعة ٠١:٠٠',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'أمس عند الساعة ٠٢:٠٠', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [عند الساعة] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 31]).week(), 1, 'Dec 31 2011 should be week 1');\n        assert.equal(moment([2012,  0,  6]).week(), 1, 'Jan  6 2012 should be week 1');\n        assert.equal(moment([2012,  0,  7]).week(), 2, 'Jan  7 2012 should be week 2');\n        assert.equal(moment([2012,  0, 13]).week(), 2, 'Jan 13 2012 should be week 2');\n        assert.equal(moment([2012,  0, 14]).week(), 3, 'Jan 14 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 30]).week(), 1, 'Dec 30 2006 should be week 1');\n        assert.equal(moment([2007,  0,  5]).week(), 1, 'Jan  5 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 2, 'Jan  6 2007 should be week 2');\n        assert.equal(moment([2007,  0, 12]).week(), 2, 'Jan 12 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 3, 'Jan 13 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 1, 'Dec 29 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  4]).week(), 1, 'Jan  4 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 2, 'Jan  5 2008 should be week 2');\n        assert.equal(moment([2008,  0, 11]).week(), 2, 'Jan 11 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 3, 'Jan 12 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 28]).week(), 1, 'Dec 28 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  3]).week(), 1, 'Jan  3 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 2, 'Jan  4 2003 should be week 2');\n        assert.equal(moment([2003,  0, 10]).week(), 2, 'Jan 10 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 3, 'Jan 11 2003 should be week 3');\n\n        assert.equal(moment('2003 1 6', 'gggg w d').format('YYYY-MM-DD'), '٢٠٠٢-١٢-٢٨', 'Week 1 of 2003 should be Dec 28 2002');\n        assert.equal(moment('2003 1 0', 'gggg w e').format('YYYY-MM-DD'), '٢٠٠٢-١٢-٢٨', 'Week 1 of 2003 should be Dec 28 2002');\n        assert.equal(moment('2003 1 6', 'gggg w d').format('gggg w d'), '٢٠٠٣ ١ ٦', 'Saturday of week 1 of 2003 parsed should be formatted as 2003 1 6');\n        assert.equal(moment('2003 1 0', 'gggg w e').format('gggg w e'), '٢٠٠٣ ١ ٠', '1st day of week 1 of 2003 parsed should be formatted as 2003 1 0');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 27]).week(), 1, 'Dec 27 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  2]).week(), 1, 'Jan  2 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 2, 'Jan  3 2009 should be week 2');\n        assert.equal(moment([2009,  0,  9]).week(), 2, 'Jan  9 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 3, 'Jan 10 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 26]).week(), 1, 'Dec 26 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 2, 'Jan  2 2010 should be week 2');\n        assert.equal(moment([2010,  0,  8]).week(), 2, 'Jan  8 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 3, 'Jan  9 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2011, 0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011, 0,  7]).week(), 1, 'Jan  7 2011 should be week 1');\n        assert.equal(moment([2011, 0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011, 0, 14]).week(), 2, 'Jan 14 2011 should be week 2');\n        assert.equal(moment([2011, 0, 15]).week(), 3, 'Jan 15 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 31]).format('w ww wo'), '١ ٠١ ١', 'Dec 31 2011 should be week 1');\n        assert.equal(moment([2012,  0,  6]).format('w ww wo'), '١ ٠١ ١', 'Jan  6 2012 should be week 1');\n        assert.equal(moment([2012,  0,  7]).format('w ww wo'), '٢ ٠٢ ٢', 'Jan  7 2012 should be week 2');\n        assert.equal(moment([2012,  0, 13]).format('w ww wo'), '٢ ٠٢ ٢', 'Jan 13 2012 should be week 2');\n        assert.equal(moment([2012,  0, 14]).format('w ww wo'), '٣ ٠٣ ٣', 'Jan 14 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('az');\n\n    test('parse', function (assert) {\n        var tests = 'yanvar yan_fevral fev_mart mar_Aprel apr_may may_iyun iyn_iyul iyl_Avqust avq_sentyabr sen_oktyabr okt_noyabr noy_dekabr dek'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, D MMMM YYYY, HH:mm:ss',        'Bazar, 14 fevral 2010, 15:25:50'],\n                ['ddd, A h',                           'Baz, gündüz 3'],\n                ['M Mo MM MMMM MMM',                   '2 2-nci 02 fevral fev'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14-üncü 14'],\n                ['d do dddd ddd dd',                   '0 0-ıncı Bazar Baz Bz'],\n                ['DDD DDDo DDDD',                      '45 45-inci 045'],\n                ['w wo ww',                            '7 7-nci 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'gündüz gündüz'],\n                ['[ilin] DDDo [günü]',                 'ilin 45-inci günü'],\n                ['LT',                                 '15:25'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14.02.2010'],\n                ['LL',                                 '14 fevral 2010'],\n                ['LLL',                                '14 fevral 2010 15:25'],\n                ['LLLL',                               'Bazar, 14 fevral 2010 15:25'],\n                ['l',                                  '14.2.2010'],\n                ['ll',                                 '14 fev 2010'],\n                ['lll',                                '14 fev 2010 15:25'],\n                ['llll',                               'Baz, 14 fev 2010 15:25']\n            ],\n            DDDo = [\n                [359, '360-ıncı'],\n                [199, '200-üncü'],\n                [149, '150-nci']\n            ],\n            dt = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            DDDoDt,\n            i;\n\n        for (i = 0; i < a.length; i++) {\n            assert.equal(dt.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n        for (i = 0; i < DDDo.length; i++) {\n            DDDoDt = moment([2010]);\n            assert.equal(DDDoDt.add(DDDo[i][0], 'days').format('DDDo'), DDDo[i][1], DDDo[i][0] + ' ---> ' + DDDo[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-inci', '1st');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-nci', '2nd');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-üncü', '3rd');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-üncü', '4th');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-inci', '5th');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ncı', '6th');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-nci', '7th');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-inci', '8th');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-uncu', '9th');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-uncu', '10th');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-inci', '11th');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-nci', '12th');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-üncü', '13th');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-üncü', '14th');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-inci', '15th');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ncı', '16th');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-nci', '17th');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-inci', '18th');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-uncu', '19th');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-nci', '20th');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-inci', '21th');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-nci', '22th');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-üncü', '23th');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-üncü', '24th');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-inci', '25th');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ncı', '26th');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-nci', '27th');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-inci', '28th');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-uncu', '29th');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-uncu', '30th');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-inci', '31st');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'yanvar yan_fevral fev_mart mar_aprel apr_may may_iyun iyn_iyul iyl_avqust avq_sentyabr sen_oktyabr okt_noyabr noy_dekabr dek'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'Bazar Baz Bz_Bazar ertəsi BzE BE_Çərşənbə axşamı ÇAx ÇA_Çərşənbə Çər Çə_Cümə axşamı CAx CA_Cümə Cüm Cü_Şənbə Şən Şə'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'birneçə saniyyə', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'bir dəqiqə',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'bir dəqiqə',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 dəqiqə',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 dəqiqə',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'bir saat',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'bir saat',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 saat',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 saat',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 saat',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'bir gün',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'bir gün',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 gün',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'bir gün',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 gün',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 gün',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'bir ay',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'bir ay',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ay',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ay',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ay',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'bir ay',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ay',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'bir il',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 il',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'bir il',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 il',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'birneçə saniyyə sonra',  'prefix');\n        assert.equal(moment(0).from(30000), 'birneçə saniyyə əvvəl', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'birneçə saniyyə əvvəl',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'birneçə saniyyə sonra', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), '5 gün sonra', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'bugün saat 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'bugün saat 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'bugün saat 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'sabah saat 02:00',     'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'bugün saat 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'dünən 02:00',          'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('[gələn həftə] dddd [saat] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[gələn həftə] dddd [saat] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[gələn həftə] dddd [saat] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[keçən həftə] dddd [saat] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[keçən həftə] dddd [saat] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[keçən həftə] dddd [saat] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-inci', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-inci', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-nci', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-nci', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-üncü', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('be');\n\n    test('parse', function (assert) {\n        var tests = 'студзень студ_люты лют_сакавік сак_красавік крас_травень трав_чэрвень чэрв_ліпень ліп_жнівень жнів_верасень вер_кастрычнік каст_лістапад ліст_снежань снеж'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, HH:mm:ss',       'нядзеля, 14-га лютага 2010, 15:25:50'],\n                ['ddd, h A',                           'нд, 3 дня'],\n                ['M Mo MM MMMM MMM',                   '2 2-і 02 люты лют'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14-га 14'],\n                ['d do dddd ddd dd',                   '0 0-ы нядзеля нд нд'],\n                ['DDD DDDo DDDD',                      '45 45-ы 045'],\n                ['w wo ww',                            '7 7-ы 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'дня дня'],\n                ['DDDo [дзень года]',                   '45-ы дзень года'],\n                ['LT',                                 '15:25'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14.02.2010'],\n                ['LL',                                 '14 лютага 2010 г.'],\n                ['LLL',                                '14 лютага 2010 г., 15:25'],\n                ['LLLL',                               'нядзеля, 14 лютага 2010 г., 15:25'],\n                ['l',                                  '14.2.2010'],\n                ['ll',                                 '14 лют 2010 г.'],\n                ['lll',                                '14 лют 2010 г., 15:25'],\n                ['llll',                               'нд, 14 лют 2010 г., 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format meridiem', function (assert) {\n        assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'ночы', 'night');\n        assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'ночы', 'night');\n        assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'раніцы', 'morning');\n        assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'раніцы', 'morning');\n        assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'дня', 'afternoon');\n        assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'дня', 'afternoon');\n        assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'вечара', 'evening');\n        assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'вечара', 'evening');\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ы', '1-ы');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-і', '2-і');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-і', '3-і');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ы', '4-ы');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ы', '5-ы');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ы', '6-ы');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ы', '7-ы');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ы', '8-ы');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-ы', '9-ы');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-ы', '10-ы');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ы', '11-ы');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ы', '12-ы');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ы', '13-ы');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ы', '14-ы');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ы', '15-ы');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ы', '16-ы');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ы', '17-ы');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ы', '18-ы');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-ы', '19-ы');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-ы', '20-ы');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ы', '21-ы');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-і', '22-і');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-і', '23-і');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ы', '24-ы');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ы', '25-ы');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ы', '26-ы');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ы', '27-ы');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ы', '28-ы');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ы', '29-ы');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ы', '30-ы');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ы', '31-ы');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'студзень студ_люты лют_сакавік сак_красавік крас_травень трав_чэрвень чэрв_ліпень ліп_жнівень жнів_верасень вер_кастрычнік каст_лістапад ліст_снежань снеж'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format month case', function (assert) {\n        var months = {\n            'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'),\n            'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_')\n        }, i;\n        for (i = 0; i < 12; i++) {\n            assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n            assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n        }\n    });\n\n    test('format month case with escaped symbols', function (assert) {\n        var months = {\n            'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'),\n            'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_')\n        }, i;\n        for (i = 0; i < 12; i++) {\n            assert.equal(moment([2013, i, 1]).format('D[] MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n            assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMMM[</b>]'), '<i>1</i> <b>' + months.accusative[i] + '</b>', '1 <b>' + months.accusative[i] + '</b>');\n            assert.equal(moment([2013, i, 1]).format('D[-ы дзень] MMMM'), '1-ы дзень ' + months.accusative[i], '1-ы дзень ' + months.accusative[i]);\n            assert.equal(moment([2013, i, 1]).format('D, MMMM'), '1, ' + months.nominative[i], '1, ' + months.nominative[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'нядзеля нд нд_панядзелак пн пн_аўторак ат ат_серада ср ср_чацвер чц чц_пятніца пт пт_субота сб сб'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'некалькі секунд',    '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'хвіліна',   '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'хвіліна',   '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 хвіліны',  '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 31}), true),  '31 хвіліна',  '31 minutes = 31 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 хвіліны', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'гадзіна',    '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'гадзіна',    '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 гадзіны',    '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 гадзін',    '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 гадзіна',   '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'дзень',      '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'дзень',      '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дні',     '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'дзень',      '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дзён',     '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 дзён',     '11 days = 11 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 дзень',     '21 days = 21 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дзён',    '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месяц',    '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месяц',    '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месяц',    '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месяцы',   '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месяцы',   '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месяцы',   '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месяц',    '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месяцаў',   '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'год',     '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 гады',    '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'год',     '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 гадоў',    '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'праз некалькі секунд', 'prefix');\n        assert.equal(moment(0).from(30000), 'некалькі секунд таму', 'suffix');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'праз некалькі секунд', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'праз 5 дзён', 'in 5 days');\n        assert.equal(moment().add({m: 31}).fromNow(), 'праз 31 хвіліну', 'in 31 minutes = in 31 minutes');\n        assert.equal(moment().subtract({m: 31}).fromNow(), '31 хвіліну таму', '31 minutes ago = 31 minutes ago');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Сёння ў 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Сёння ў 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Сёння ў 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Заўтра ў 02:00',      'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Сёння ў 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Учора ў 02:00',       'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        function makeFormat(d) {\n            return '[У] dddd [ў] LT';\n        }\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        function makeFormat(d) {\n            switch (d.day()) {\n            case 0:\n            case 3:\n            case 5:\n            case 6:\n                return '[У мінулую] dddd [ў] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[У мінулы] dddd [ў] LT';\n            }\n        }\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ы', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ы', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-і', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-і', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-і', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('bg');\n\n    test('parse', function (assert) {\n        var tests = 'януари янр_февруари фев_март мар_април апр_май май_юни юни_юли юли_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, H:mm:ss',        'неделя, февруари 14-ти 2010, 15:25:50'],\n                ['ddd, hA',                            'нед, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2-ри 02 февруари фев'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14-ти 14'],\n                ['d do dddd ddd dd',                   '0 0-ев неделя нед нд'],\n                ['DDD DDDo DDDD',                      '45 45-ти 045'],\n                ['w wo ww',                            '7 7-ми 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45-ти day of the year'],\n                ['LT',                                 '15:25'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14.02.2010'],\n                ['LL',                                 '14 февруари 2010'],\n                ['LLL',                                '14 февруари 2010 15:25'],\n                ['LLLL',                               'неделя, 14 февруари 2010 15:25'],\n                ['l',                                  '14.2.2010'],\n                ['ll',                                 '14 фев 2010'],\n                ['lll',                                '14 фев 2010 15:25'],\n                ['llll',                               'нед, 14 фев 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ви', '1-ви');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-ри', '2-ри');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-ти', '3-ти');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ти', '4-ти');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ти', '5-ти');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ти', '6-ти');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ми', '7-ми');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ми', '8-ми');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-ти', '9-ти');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-ти', '10-ти');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ти', '11-ти');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ти', '12-ти');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ти', '13-ти');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ти', '14-ти');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ти', '15-ти');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ти', '16-ти');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ти', '17-ти');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ти', '18-ти');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-ти', '19-ти');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-ти', '20-ти');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ви', '21-ви');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ри', '22-ри');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ти', '23-ти');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ти', '24-ти');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ти', '25-ти');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ти', '26-ти');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ми', '27-ми');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ми', '28-ми');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ти', '29-ти');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ти', '30-ти');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ви', '31-ви');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'януари янр_февруари фев_март мар_април апр_май май_юни юни_юли юли_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'неделя нед нд_понеделник пон пн_вторник вто вт_сряда сря ср_четвъртък чет чт_петък пет пт_събота съб сб'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'няколко секунди', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'минута',          '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'минута',          '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минути',        '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минути',       '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'час',             '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'час',             '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 часа',          '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 часа',          '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 часа',         '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ден',             '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ден',             '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дни',           '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ден',             '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дни',           '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дни',          '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месец',           '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месец',           '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месец',           '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месеца',        '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месеца',        '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месеца',        '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месец',           '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месеца',        '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'година',          '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 години',        '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'година',          '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 години',        '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'след няколко секунди',  'prefix');\n        assert.equal(moment(0).from(30000), 'преди няколко секунди', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'преди няколко секунди',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'след няколко секунди', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'след 5 дни', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Днес в 2:00',  'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Днес в 2:25',  'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Днес в 3:00',  'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Утре в 2:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Днес в 1:00',  'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчера в 2:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [в] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [в] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [в] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        function makeFormat(d) {\n            switch (d.day()) {\n            case 0:\n            case 3:\n            case 6:\n                return '[В изминалата] dddd [в] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[В изминалия] dddd [в] LT';\n            }\n        }\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ви', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ви', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-ри', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-ри', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-ти', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('bn');\n\n    test('parse', function (assert) {\n        var tests = 'জানুয়ারী জানু_ফেবুয়ারী ফেব_মার্চ মার্চ_এপ্রিল এপর_মে মে_জুন জুন_জুলাই জুল_অগাস্ট অগ_সেপ্টেম্বর সেপ্ট_অক্টোবর অক্টো_নভেম্বর নভ_ডিসেম্বর ডিসেম্'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, a h:mm:ss সময়',  'রবিবার, ১৪ ফেবুয়ারী ২০১০, দুপুর ৩:২৫:৫০ সময়'],\n                ['ddd, a h সময়',                       'রবি, দুপুর ৩ সময়'],\n                ['M Mo MM MMMM MMM',                   '২ ২ ০২ ফেবুয়ারী ফেব'],\n                ['YYYY YY',                            '২০১০ ১০'],\n                ['D Do DD',                            '১৪ ১৪ ১৪'],\n                ['d do dddd ddd dd',                   '০ ০ রবিবার রবি রব'],\n                ['DDD DDDo DDDD',                      '৪৫ ৪৫ ০৪৫'],\n                ['w wo ww',                            '৮ ৮ ০৮'],\n                ['h hh',                               '৩ ০৩'],\n                ['H HH',                               '১৫ ১৫'],\n                ['m mm',                               '২৫ ২৫'],\n                ['s ss',                               '৫০ ৫০'],\n                ['a A',                                'দুপুর দুপুর'],\n                ['LT',                                 'দুপুর ৩:২৫ সময়'],\n                ['LTS',                                'দুপুর ৩:২৫:৫০ সময়'],\n                ['L',                                  '১৪/০২/২০১০'],\n                ['LL',                                 '১৪ ফেবুয়ারী ২০১০'],\n                ['LLL',                                '১৪ ফেবুয়ারী ২০১০, দুপুর ৩:২৫ সময়'],\n                ['LLLL',                               'রবিবার, ১৪ ফেবুয়ারী ২০১০, দুপুর ৩:২৫ সময়'],\n                ['l',                                  '১৪/২/২০১০'],\n                ['ll',                                 '১৪ ফেব ২০১০'],\n                ['lll',                                '১৪ ফেব ২০১০, দুপুর ৩:২৫ সময়'],\n                ['llll',                               'রবি, ১৪ ফেব ২০১০, দুপুর ৩:২৫ সময়']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '১', '১');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '২', '২');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '৩', '৩');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '৪', '৪');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '৫', '৫');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '৬', '৬');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '৭', '৭');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '৮', '৮');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '৯', '৯');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '১০', '১০');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '১১', '১১');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '১২', '১২');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '১৩', '১৩');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '১৪', '১৪');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '১৫', '১৫');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '১৬', '১৬');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '১৭', '১৭');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '১৮', '১৮');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '১৯', '১৯');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '২০', '২০');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '২১', '২১');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '২২', '২২');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '২৩', '২৩');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '২৪', '২৪');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '২৫', '২৫');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '২৬', '২৬');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '২৭', '২৭');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '২৮', '२৮');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '২৯', '২৯');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '৩০', '৩০');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '৩১', '৩১');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'জানুয়ারী জানু_ফেবুয়ারী ফেব_মার্চ মার্চ_এপ্রিল এপর_মে মে_জুন জুন_জুলাই জুল_অগাস্ট অগ_সেপ্টেম্বর সেপ্ট_অক্টোবর অক্টো_নভেম্বর নভ_ডিসেম্বর ডিসেম্'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'রবিবার রবি রব_সোমবার সোম সম_মঙ্গলবার মঙ্গল মঙ্গ_বুধবার বুধ বু_বৃহস্পত্তিবার বৃহস্পত্তি ব্রিহ_শুক্রুবার শুক্রু শু_শনিবার শনি শনি'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'কএক সেকেন্ড', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'এক মিনিট',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'এক মিনিট',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '২ মিনিট',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '৪৪ মিনিট',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'এক ঘন্টা',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'এক ঘন্টা',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '২ ঘন্টা',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '৫ ঘন্টা',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '২১ ঘন্টা',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'এক দিন',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'এক দিন',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '২ দিন',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'এক দিন',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '৫ দিন',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '২৫ দিন',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'এক মাস',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'এক মাস',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '২ মাস',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '২ মাস',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '৩ মাস',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'এক মাস',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '৫ মাস',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'এক বছর',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '২ বছর',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'এক বছর',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '৫ বছর',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'কএক সেকেন্ড পরে',  'prefix');\n        assert.equal(moment(0).from(30000), 'কএক সেকেন্ড আগে', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'কএক সেকেন্ড আগে',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'কএক সেকেন্ড পরে', 'কএক সেকেন্ড পরে');\n        assert.equal(moment().add({d: 5}).fromNow(), '৫ দিন পরে', '৫ দিন পরে');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'আজ রাত ২:০০ সময়',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'আজ রাত ২:২৫ সময়',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 3}).calendar(),       'আজ শকাল ৫:০০ সময়',     'Now plus 3 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'আগামীকাল রাত ২:০০ সময়',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'আজ রাত ১:০০ সময়',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'গতকাল রাত ২:০০ সময়', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[গত] dddd[,] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[গত] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[গত] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('meridiem', function (assert) {\n        assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'রাত', 'before dawn');\n        assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'শকাল', 'morning');\n        assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'দুপুর', 'during day');\n        assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'বিকেল', 'evening');\n        assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'বিকেল', 'late evening');\n        assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'রাত', 'night');\n\n        assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'রাত', 'before dawn');\n        assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'শকাল', 'morning');\n        assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'দুপুর', ' during day');\n        assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'বিকেল', 'evening');\n        assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'বিকেল', 'late evening');\n        assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'রাত', 'night');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n        assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n        assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n        assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n        assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '১ ০১ ১', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).format('w ww wo'), '১ ০১ ১', 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'), '২ ০২ ২', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).format('w ww wo'), '২ ০২ ২', 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'), '৩ ০৩ ৩', 'Jan 15 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('bo');\n\n    test('parse', function (assert) {\n        var tests = 'ཟླ་བ་དང་པོ ཟླ་བ་དང་པོ._ཟླ་བ་གཉིས་པ ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, a h:mm:ss ལ་',  'གཟའ་ཉི་མ་, ༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥:༥༠ ལ་'],\n                ['ddd, a h ལ་',                       'ཉི་མ་, ཉིན་གུང ༣ ལ་'],\n                ['M Mo MM MMMM MMM',                   '༢ ༢ ༠༢ ཟླ་བ་གཉིས་པ ཟླ་བ་གཉིས་པ'],\n                ['YYYY YY',                            '༢༠༡༠ ༡༠'],\n                ['D Do DD',                            '༡༤ ༡༤ ༡༤'],\n                ['d do dddd ddd dd',                   '༠ ༠ གཟའ་ཉི་མ་ ཉི་མ་ ཉི་མ་'],\n                ['DDD DDDo DDDD',                      '༤༥ ༤༥ ༠༤༥'],\n                ['w wo ww',                            '༨ ༨ ༠༨'],\n                ['h hh',                               '༣ ༠༣'],\n                ['H HH',                               '༡༥ ༡༥'],\n                ['m mm',                               '༢༥ ༢༥'],\n                ['s ss',                               '༥༠ ༥༠'],\n                ['a A',                                'ཉིན་གུང ཉིན་གུང'],\n                ['LT',                                 'ཉིན་གུང ༣:༢༥'],\n                ['LTS',                                'ཉིན་གུང ༣:༢༥:༥༠'],\n                ['L',                                  '༡༤/༠༢/༢༠༡༠'],\n                ['LL',                                 '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠'],\n                ['LLL',                                '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥'],\n                ['LLLL',                               'གཟའ་ཉི་མ་, ༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥'],\n                ['l',                                  '༡༤/༢/༢༠༡༠'],\n                ['ll',                                 '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠'],\n                ['lll',                                '༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥'],\n                ['llll',                               'ཉི་མ་, ༡༤ ཟླ་བ་གཉིས་པ ༢༠༡༠, ཉིན་གུང ༣:༢༥']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '༡', '༡');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '༢', '༢');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '༣', '༣');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '༤', '༤');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '༥', '༥');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '༦', '༦');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '༧', '༧');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '༨', '༨');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '༩', '༩');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '༡༠', '༡༠');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '༡༡', '༡༡');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '༡༢', '༡༢');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '༡༣', '༡༣');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '༡༤', '༡༤');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '༡༥', '༡༥');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '༡༦', '༡༦');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '༡༧', '༡༧');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '༡༨', '༡༨');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '༡༩', '༡༩');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '༢༠', '༢༠');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '༢༡', '༢༡');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '༢༢', '༢༢');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '༢༣', '༢༣');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '༢༤', '༢༤');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '༢༥', '༢༥');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '༢༦', '༢༦');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '༢༧', '༢༧');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '༢༨', '༢༨');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '༢༩', '༢༩');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '༣༠', '༣༠');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '༣༡', '༣༡');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'ཟླ་བ་དང་པོ ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ ཟླ་བ་བཅུ་གཉིས་པ'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'གཟའ་ཉི་མ་ ཉི་མ་ ཉི་མ་_གཟའ་ཟླ་བ་ ཟླ་བ་ ཟླ་བ་_གཟའ་མིག་དམར་ མིག་དམར་ མིག་དམར་_གཟའ་ལྷག་པ་ ལྷག་པ་ ལྷག་པ་_གཟའ་ཕུར་བུ ཕུར་བུ ཕུར་བུ_གཟའ་པ་སངས་ པ་སངས་ པ་སངས་_གཟའ་སྤེན་པ་ སྤེན་པ་ སྤེན་པ་'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ལམ་སང', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'སྐར་མ་གཅིག',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'སྐར་མ་གཅིག',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '༢ སྐར་མ',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '༤༤ སྐར་མ',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ཆུ་ཚོད་གཅིག',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ཆུ་ཚོད་གཅིག',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '༢ ཆུ་ཚོད',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '༥ ཆུ་ཚོད',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '༢༡ ཆུ་ཚོད',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ཉིན་གཅིག',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ཉིན་གཅིག',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '༢ ཉིན་',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ཉིན་གཅིག',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '༥ ཉིན་',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '༢༥ ཉིན་',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ཟླ་བ་གཅིག',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ཟླ་བ་གཅིག',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ཟླ་བ་གཅིག',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '༢ ཟླ་བ',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '༢ ཟླ་བ',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '༣ ཟླ་བ',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ཟླ་བ་གཅིག',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '༥ ཟླ་བ',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ལོ་གཅིག',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '༢ ལོ',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ལོ་གཅིག',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '༥ ལོ',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'ལམ་སང ལ་',  'prefix');\n        assert.equal(moment(0).from(30000), 'ལམ་སང སྔན་ལ', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'ལམ་སང སྔན་ལ',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'ལམ་སང ལ་', 'ལམ་སང ལ་');\n        assert.equal(moment().add({d: 5}).fromNow(), '༥ ཉིན་ ལ་', '༥ ཉིན་ ལ་');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'དི་རིང མཚན་མོ ༢:༠༠',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'དི་རིང མཚན་མོ ༢:༢༥',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 3}).calendar(),       'དི་རིང ཞོགས་ཀས ༥:༠༠',     'Now plus 3 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'སང་ཉིན མཚན་མོ ༢:༠༠',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'དི་རིང མཚན་མོ ༡:༠༠',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'ཁ་སང མཚན་མོ ༢:༠༠', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་རྗེས་མ][,] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་རྗེས་མ][,] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་རྗེས་མ][,] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་མཐའ་མ] dddd[,] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་མཐའ་མ] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[བདུན་ཕྲག་མཐའ་མ] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('meridiem', function (assert) {\n        assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'མཚན་མོ', 'before dawn');\n        assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'ཞོགས་ཀས', 'morning');\n        assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'ཉིན་གུང', 'during day');\n        assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'དགོང་དག', 'evening');\n        assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'དགོང་དག', 'late evening');\n        assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'མཚན་མོ', 'night');\n\n        assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'མཚན་མོ', 'before dawn');\n        assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'ཞོགས་ཀས', 'morning');\n        assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'ཉིན་གུང', ' during day');\n        assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'དགོང་དག', 'evening');\n        assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'དགོང་དག', 'late evening');\n        assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'མཚན་མོ', 'night');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n        assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n        assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n        assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n        assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '༡ ༠༡ ༡', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).format('w ww wo'), '༡ ༠༡ ༡', 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'), '༢ ༠༢ ༢', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).format('w ww wo'), '༢ ༠༢ ༢', 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'), '༣ ༠༣ ༣', 'Jan 15 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('br');\n\n    test('parse', function (assert) {\n        var tests = 'Genver Gen_C\\'hwevrer C\\'hwe_Meurzh Meu_Ebrel Ebr_Mae Mae_Mezheven Eve_Gouere Gou_Eost Eos_Gwengolo Gwe_Here Her_Du Du_Kerzu Ker'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        moment.locale('br');\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sul, C\\'hwevrer 14vet 2010, 3:25:50 pm'],\n                ['ddd, h A',                            'Sul, 3 PM'],\n                ['M Mo MM MMMM MMM',                   '2 2vet 02 C\\'hwevrer C\\'hwe'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14vet 14'],\n                ['d do dddd ddd dd',                   '0 0vet Sul Sul Su'],\n                ['DDD DDDo DDDD',                      '45 45vet 045'],\n                ['w wo ww',                            '6 6vet 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['DDDo [devezh] [ar] [vloaz]',       '45vet devezh ar vloaz'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 a viz C\\'hwevrer 2010'],\n                ['LLL',                                '14 a viz C\\'hwevrer 2010 3e25 PM'],\n                ['LLLL',                               'Sul, 14 a viz C\\'hwevrer 2010 3e25 PM']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        moment.locale('br');\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1añ', '1añ');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2vet', '2vet');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3vet', '3vet');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4vet', '4vet');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5vet', '5vet');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6vet', '6vet');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7vet', '7vet');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8vet', '8vet');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9vet', '9vet');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10vet', '10vet');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11vet', '11vet');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12vet', '12vet');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13vet', '13vet');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14vet', '14vet');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15vet', '15vet');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16vet', '16vet');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17vet', '17vet');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18vet', '18vet');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19vet', '19vet');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20vet', '20vet');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21vet', '21vet');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22vet', '22vet');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23vet', '23vet');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24vet', '24vet');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25vet', '25vet');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26vet', '26vet');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27vet', '27vet');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28vet', '28vet');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29vet', '29vet');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30vet', '30vet');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31vet', '31vet');\n    });\n\n    test('format month', function (assert) {\n        moment.locale('br');\n        var expected = 'Genver Gen_C\\'hwevrer C\\'hwe_Meurzh Meu_Ebrel Ebr_Mae Mae_Mezheven Eve_Gouere Gou_Eost Eos_Gwengolo Gwe_Here Her_Du Du_Kerzu Ker'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        moment.locale('br');\n        var expected = 'Sul Sul Su_Lun Lun Lu_Meurzh Meu Me_Merc\\'her Mer Mer_Yaou Yao Ya_Gwener Gwe Gw_Sadorn Sad Sa'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        moment.locale('br');\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'un nebeud segondennoù', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ur vunutenn',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ur vunutenn',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 vunutenn',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 munutenn',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'un eur',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'un eur',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 eur',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 eur',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 eur',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un devezh',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un devezh',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 zevezh',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un devezh',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 devezh',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 devezh',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ur miz',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ur miz',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ur miz',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 viz',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 viz',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 miz',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ur miz',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 miz',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ur bloaz',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 vloaz',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ur bloaz',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 bloaz',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        moment.locale('br');\n        assert.equal(moment(30000).from(0), 'a-benn un nebeud segondennoù',  'prefix');\n        assert.equal(moment(0).from(30000), 'un nebeud segondennoù \\'zo', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        moment.locale('br');\n        assert.equal(moment().fromNow(), 'un nebeud segondennoù \\'zo',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        moment.locale('br');\n        assert.equal(moment().add({s: 30}).fromNow(), 'a-benn un nebeud segondennoù', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'a-benn 5 devezh', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        moment.locale('br');\n\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Hiziv da 2e00 AM',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Hiziv da 2e25 AM',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Hiziv da 3e00 AM',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Warc\\'hoazh da 2e00 AM',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hiziv da 1e00 AM',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Dec\\'h da 2e00 AM', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        moment.locale('br');\n\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [da] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [da] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [da] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        moment.locale('br');\n\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [paset da] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [paset da] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [paset da] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        moment.locale('br');\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('special mutations for years', function (assert) {\n        moment.locale('br');\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'ur bloaz', 'mutation 1 year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 2}), true), '2 vloaz', 'mutation 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 3}), true), '3 bloaz', 'mutation 3 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 4}), true), '4 bloaz', 'mutation 4 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 bloaz', 'mutation 5 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 9}), true), '9 bloaz', 'mutation 9 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 10}), true), '10 vloaz', 'mutation 10 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 21}), true), '21 bloaz', 'mutation 21 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 22}), true), '22 vloaz', 'mutation 22 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 133}), true), '133 bloaz', 'mutation 133 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 148}), true), '148 vloaz', 'mutation 148 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 261}), true), '261 bloaz', 'mutation 261 years');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('bs');\n\n    test('parse', function (assert) {\n        var tests = 'januar jan._februar feb._mart mar._april apr._maj maj._juni jun._juli jul._august aug._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedjelja, 14. februar 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'ned., 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14. 14'],\n                ['d do dddd ddd dd',                   '0 0. nedjelja ned. ne'],\n                ['DDD DDDo DDDD',                      '45 45. 045'],\n                ['w wo ww',                            '7 7. 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14. 02. 2010'],\n                ['LL',                                 '14. februar 2010'],\n                ['LLL',                                '14. februar 2010 15:25'],\n                ['LLLL',                               'nedjelja, 14. februar 2010 15:25'],\n                ['l',                                  '14. 2. 2010'],\n                ['ll',                                 '14. feb. 2010'],\n                ['lll',                                '14. feb. 2010 15:25'],\n                ['llll',                               'ned., 14. feb. 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'januar jan._februar feb._mart mar._april apr._maj maj._juni jun._juli jul._august aug._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'nedjelja ned. ne_ponedjeljak pon. po_utorak uto. ut_srijeda sri. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'par sekundi', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'jedna minuta',   '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'jedna minuta',   '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',     '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'jedan sat',      '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'jedan sat',      '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 sata',        '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 sati',         '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 sati',        '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dan',       '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dan',       '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dana',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dan',       '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dana',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dana',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mjesec',     '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mjesec',     '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mjesec',     '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mjeseca',     '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mjeseca',     '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mjeseca',     '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mjesec',     '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mjeseci',    '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'godinu',     '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 godine',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'godinu',     '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 godina',        '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'za par sekundi',  'prefix');\n        assert.equal(moment(0).from(30000), 'prije par sekundi', 'prefix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'prije par sekundi',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'za par sekundi', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dana', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'danas u 2:00',  'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'danas u 2:25',  'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'danas u 3:00',  'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'sutra u 2:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'danas u 1:00',  'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'jučer u 2:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n\n        function makeFormat(d) {\n            switch (d.day()) {\n            case 0:\n                return '[u] [nedjelju] [u] LT';\n            case 3:\n                return '[u] [srijedu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n            }\n        }\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        function makeFormat(d) {\n            switch (d.day()) {\n            case 0:\n            case 3:\n                return '[prošlu] dddd [u] LT';\n            case 6:\n                return '[prošle] [subote] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[prošli] dddd [u] LT';\n            }\n        }\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('ca');\n\n    test('parse', function (assert) {\n        var tests = 'gener gen._febrer febr._març mar._abril abr._maig mai._juny jun._juliol jul._agost ag._setembre set._octubre oct._novembre nov._desembre des.'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, h:mm:ss a',      'diumenge, 14è febrer 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'dg., 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2n 02 febrer febr.'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14è 14'],\n                ['d do dddd ddd dd',                   '0 0è diumenge dg. Dg'],\n                ['DDD DDDo DDDD',                      '45 45è 045'],\n                ['w wo ww',                            '6 6a 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45è day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 febrer 2010'],\n                ['LLL',                                '14 febrer 2010 15:25'],\n                ['LLLL',                               'diumenge 14 febrer 2010 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 febr. 2010'],\n                ['lll',                                '14 febr. 2010 15:25'],\n                ['llll',                               'dg. 14 febr. 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1r', '1r');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2n', '2n');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3r', '3r');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4t', '4t');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5è', '5è');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6è', '6è');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7è', '7è');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8è', '8è');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9è', '9è');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10è', '10è');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11è', '11è');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12è', '12è');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13è', '13è');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14è', '14è');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15è', '15è');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16è', '16è');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17è', '17è');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18è', '18è');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19è', '19è');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20è', '20è');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21è', '21è');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22è', '22è');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23è', '23è');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24è', '24è');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25è', '25è');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26è', '26è');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27è', '27è');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28è', '28è');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29è', '29è');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30è', '30è');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31è', '31è');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'gener gen._febrer febr._març mar._abril abr._maig mai._juny jun._juliol jul._agost ag._setembre set._octubre oct._novembre nov._desembre des.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'diumenge dg. Dg_dilluns dl. Dl_dimarts dt. Dt_dimecres dc. Dc_dijous dj. Dj_divendres dv. Dv_dissabte ds. Ds'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'uns segons', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minut',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minut',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuts',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuts',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'una hora',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'una hora',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hores',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hores',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hores',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un dia',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un dia',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dies',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un dia',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dies',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dies',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mes',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mes',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mes',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mesos',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mesos',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesos',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mes',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesos',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un any',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anys',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un any',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anys',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'en uns segons',  'prefix');\n        assert.equal(moment(0).from(30000), 'fa uns segons', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'fa uns segons',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'en uns segons', 'en uns segons');\n        assert.equal(moment().add({d: 5}).fromNow(), 'en 5 dies', 'en 5 dies');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                         'avui a les 2:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),          'avui a les 2:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),           'avui a les 3:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),           'demà a les 2:00',  'tomorrow at the same time');\n        assert.equal(moment(a).add({d: 1, h : -1}).calendar(),   'demà a la 1:00',   'tomorrow minus 1 hour');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),      'avui a la 1:00',      'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),      'ahir a les 2:00',    'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[el] dddd [passat a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[el] dddd [passat a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[el] dddd [passat a ' + ((m.hours() !== 1) ? 'les' : 'la') + '] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52a', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1a', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1a', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2a', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2a', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('cs');\n\n    test('parse', function (assert) {\n        var tests = 'leden led_únor úno_březen bře_duben dub_květen kvě_červen čvn_červenec čvc_srpen srp_září zář_říjen říj_listopad lis_prosinec pro'.split('_'), i;\n        function equalTest(input, mmm, monthIndex) {\n            assert.equal(moment(input, mmm).month(), monthIndex, input + ' should be month ' + (monthIndex + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss',  'neděle, únor 14. 2010, 3:25:50'],\n                ['ddd, h',                       'ne, 3'],\n                ['M Mo MM MMMM MMM',             '2 2. 02 únor úno'],\n                ['YYYY YY',                      '2010 10'],\n                ['D Do DD',                      '14 14. 14'],\n                ['d do dddd ddd dd',             '0 0. neděle ne ne'],\n                ['DDD DDDo DDDD',                '45 45. 045'],\n                ['w wo ww',                      '6 6. 06'],\n                ['h hh',                         '3 03'],\n                ['H HH',                         '15 15'],\n                ['m mm',                         '25 25'],\n                ['s ss',                         '50 50'],\n                ['a A',                          'pm PM'],\n                ['DDDo [den v roce]',            '45. den v roce'],\n                ['LTS',                          '15:25:50'],\n                ['L',                            '14.02.2010'],\n                ['LL',                           '14. únor 2010'],\n                ['LLL',                          '14. únor 2010 15:25'],\n                ['LLLL',                         'neděle 14. únor 2010 15:25'],\n                ['l',                            '14.2.2010'],\n                ['ll',                           '14. úno 2010'],\n                ['lll',                          '14. úno 2010 15:25'],\n                ['llll',                         'ne 14. úno 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'leden led_únor úno_březen bře_duben dub_květen kvě_červen čvn_červenec čvc_srpen srp_září zář_říjen říj_listopad lis_prosinec pro'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'neděle ne ne_pondělí po po_úterý út út_středa st st_čtvrtek čt čt_pátek pá pá_sobota so so'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'pár sekund',  '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuta',        '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuta',        '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuty',      '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minut',     '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'hodina',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'hodina',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hodiny',     '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hodin',      '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hodin',     '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'den',       '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'den',       '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dny',         '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'den',       '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dní',         '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dní',        '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'měsíc',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'měsíc',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'měsíc',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 měsíce',    '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 měsíce',    '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 měsíce',    '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'měsíc',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 měsíců',    '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'rok',           '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 roky',        '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'rok',           '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 let',         '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'za pár sekund',  'prefix');\n        assert.equal(moment(0).from(30000), 'před pár sekundami', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'před pár sekundami',  'now from now should display as in the past');\n    });\n\n    test('fromNow (future)', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'za pár sekund', 'in a few seconds');\n        assert.equal(moment().add({m: 1}).fromNow(), 'za minutu', 'in a minute');\n        assert.equal(moment().add({m: 3}).fromNow(), 'za 3 minuty', 'in 3 minutes');\n        assert.equal(moment().add({m: 10}).fromNow(), 'za 10 minut', 'in 10 minutes');\n        assert.equal(moment().add({h: 1}).fromNow(), 'za hodinu', 'in an hour');\n        assert.equal(moment().add({h: 3}).fromNow(), 'za 3 hodiny', 'in 3 hours');\n        assert.equal(moment().add({h: 10}).fromNow(), 'za 10 hodin', 'in 10 hours');\n        assert.equal(moment().add({d: 1}).fromNow(), 'za den', 'in a day');\n        assert.equal(moment().add({d: 3}).fromNow(), 'za 3 dny', 'in 3 days');\n        assert.equal(moment().add({d: 10}).fromNow(), 'za 10 dní', 'in 10 days');\n        assert.equal(moment().add({M: 1}).fromNow(), 'za měsíc', 'in a month');\n        assert.equal(moment().add({M: 3}).fromNow(), 'za 3 měsíce', 'in 3 months');\n        assert.equal(moment().add({M: 10}).fromNow(), 'za 10 měsíců', 'in 10 months');\n        assert.equal(moment().add({y: 1}).fromNow(), 'za rok', 'in a year');\n        assert.equal(moment().add({y: 3}).fromNow(), 'za 3 roky', 'in 3 years');\n        assert.equal(moment().add({y: 10}).fromNow(), 'za 10 let', 'in 10 years');\n    });\n\n    test('fromNow (past)', function (assert) {\n        assert.equal(moment().subtract({s: 30}).fromNow(), 'před pár sekundami', 'a few seconds ago');\n        assert.equal(moment().subtract({m: 1}).fromNow(), 'před minutou', 'a minute ago');\n        assert.equal(moment().subtract({m: 3}).fromNow(), 'před 3 minutami', '3 minutes ago');\n        assert.equal(moment().subtract({m: 10}).fromNow(), 'před 10 minutami', '10 minutes ago');\n        assert.equal(moment().subtract({h: 1}).fromNow(), 'před hodinou', 'an hour ago');\n        assert.equal(moment().subtract({h: 3}).fromNow(), 'před 3 hodinami', '3 hours ago');\n        assert.equal(moment().subtract({h: 10}).fromNow(), 'před 10 hodinami', '10 hours ago');\n        assert.equal(moment().subtract({d: 1}).fromNow(), 'před dnem', 'a day ago');\n        assert.equal(moment().subtract({d: 3}).fromNow(), 'před 3 dny', '3 days ago');\n        assert.equal(moment().subtract({d: 10}).fromNow(), 'před 10 dny', '10 days ago');\n        assert.equal(moment().subtract({M: 1}).fromNow(), 'před měsícem', 'a month ago');\n        assert.equal(moment().subtract({M: 3}).fromNow(), 'před 3 měsíci', '3 months ago');\n        assert.equal(moment().subtract({M: 10}).fromNow(), 'před 10 měsíci', '10 months ago');\n        assert.equal(moment().subtract({y: 1}).fromNow(), 'před rokem', 'a year ago');\n        assert.equal(moment().subtract({y: 3}).fromNow(), 'před 3 lety', '3 years ago');\n        assert.equal(moment().subtract({y: 10}).fromNow(), 'před 10 lety', '10 years ago');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'dnes v 2:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'dnes v 2:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'dnes v 3:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'zítra v 2:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'dnes v 1:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'včera v 2:00',     'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m, nextDay;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            nextDay = '';\n            switch (m.day()) {\n            case 0:\n                nextDay = 'v neděli';\n                break;\n            case 1:\n                nextDay = 'v pondělí';\n                break;\n            case 2:\n                nextDay = 'v úterý';\n                break;\n            case 3:\n                nextDay = 've středu';\n                break;\n            case 4:\n                nextDay = 've čtvrtek';\n                break;\n            case 5:\n                nextDay = 'v pátek';\n                break;\n            case 6:\n                nextDay = 'v sobotu';\n                break;\n            }\n            assert.equal(m.calendar(),       m.format('[' + nextDay + '] [v] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[' + nextDay + '] [v] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[' + nextDay + '] [v] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m, lastDay;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            lastDay = '';\n            switch (m.day()) {\n            case 0:\n                lastDay = 'minulou neděli';\n                break;\n            case 1:\n                lastDay = 'minulé pondělí';\n                break;\n            case 2:\n                lastDay = 'minulé úterý';\n                break;\n            case 3:\n                lastDay = 'minulou středu';\n                break;\n            case 4:\n                lastDay = 'minulý čtvrtek';\n                break;\n            case 5:\n                lastDay = 'minulý pátek';\n                break;\n            case 6:\n                lastDay = 'minulou sobotu';\n                break;\n            }\n            assert.equal(m.calendar(),       m.format('[' + lastDay + '] [v] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[' + lastDay + '] [v] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[' + lastDay + '] [v] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('humanize duration', function (assert) {\n        assert.equal(moment.duration(1, 'minutes').humanize(), 'minuta', 'a minute (future)');\n        assert.equal(moment.duration(1, 'minutes').humanize(true), 'za minutu', 'in a minute');\n        assert.equal(moment.duration(-1, 'minutes').humanize(), 'minuta', 'a minute (past)');\n        assert.equal(moment.duration(-1, 'minutes').humanize(true), 'před minutou', 'a minute ago');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('cv');\n\n    test('parse', function (assert) {\n        var tests = 'кăрлач кăр_нарăс нар_пуш пуш_ака ака_май май_çĕртме çĕр_утă утă_çурла çур_авăн ав_юпа юпа_чӳк чӳк_раштав раш'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'вырсарникун, нарăс 14-мĕш 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'выр, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2-мĕш 02 нарăс нар'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14-мĕш 14'],\n                ['d do dddd ddd dd',                   '0 0-мĕш вырсарникун выр вр'],\n                ['DDD DDDo DDDD',                      '45 45-мĕш 045'],\n                ['w wo ww',                            '7 7-мĕш 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['Çулăн DDDo кунĕ',                    'Çулăн 45-мĕш кунĕ'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14-02-2010'],\n                ['LL',                                 '2010 çулхи нарăс уйăхĕн 14-мĕшĕ'],\n                ['LLL',                                '2010 çулхи нарăс уйăхĕн 14-мĕшĕ, 15:25'],\n                ['LLLL',                               'вырсарникун, 2010 çулхи нарăс уйăхĕн 14-мĕшĕ, 15:25'],\n                ['l',                                  '14-2-2010'],\n                ['ll',                                 '2010 çулхи нар уйăхĕн 14-мĕшĕ'],\n                ['lll',                                '2010 çулхи нар уйăхĕн 14-мĕшĕ, 15:25'],\n                ['llll',                               'выр, 2010 çулхи нар уйăхĕн 14-мĕшĕ, 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-мĕш', '1-мĕш');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-мĕш', '2-мĕш');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-мĕш', '3-мĕш');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-мĕш', '4-мĕш');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-мĕш', '5-мĕш');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-мĕш', '6-мĕш');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-мĕш', '7-мĕш');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-мĕш', '8-мĕш');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-мĕш', '9-мĕш');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-мĕш', '10-мĕш');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-мĕш', '11-мĕш');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-мĕш', '12-мĕш');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-мĕш', '13-мĕш');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-мĕш', '14-мĕш');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-мĕш', '15-мĕш');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-мĕш', '16-мĕш');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-мĕш', '17-мĕш');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-мĕш', '18-мĕш');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-мĕш', '19-мĕш');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-мĕш', '20-мĕш');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-мĕш', '21-мĕш');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-мĕш', '22-мĕш');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-мĕш', '23-мĕш');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-мĕш', '24-мĕш');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-мĕш', '25-мĕш');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-мĕш', '26-мĕш');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-мĕш', '27-мĕш');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-мĕш', '28-мĕш');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-мĕш', '29-мĕш');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-мĕш', '30-мĕш');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-мĕш', '31-мĕш');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'кăрлач кăр_нарăс нар_пуш пуш_ака ака_май май_çĕртме çĕр_утă утă_çурла çур_авăн ав_юпа юпа_чӳк чӳк_раштав раш'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'вырсарникун выр вр_тунтикун тун тн_ытларикун ытл ыт_юнкун юн юн_кĕçнерникун кĕç кç_эрнекун эрн эр_шăматкун шăм шм'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'пĕр-ик çеккунт', '44 sekunder = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'пĕр минут',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'пĕр минут',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минут',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минут',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'пĕр сехет',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'пĕр сехет',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 сехет',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 сехет',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 сехет',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'пĕр кун',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'пĕр кун',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 кун',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'пĕр кун',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 кун',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 кун',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'пĕр уйăх',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'пĕр уйăх',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'пĕр уйăх',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 уйăх',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 уйăх',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 уйăх',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'пĕр уйăх',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 уйăх',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'пĕр çул',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 çул',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'пĕр çул',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 çул',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'пĕр-ик çеккунтран',  'prefix');\n        assert.equal(moment(0).from(30000), 'пĕр-ик çеккунт каялла', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'пĕр-ик çеккунт каялла',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'пĕр-ик çеккунтран', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), '5 кунран', 'in 5 days');\n        assert.equal(moment().add({h: 2}).fromNow(), '2 сехетрен', 'in 2 hours, the right suffix!');\n        assert.equal(moment().add({y: 3}).fromNow(), '3 çултан', 'in 3 years, the right suffix!');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n        assert.equal(moment(a).calendar(),                     'Паян 02:00 сехетре',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Паян 02:25 сехетре',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Паян 03:00 сехетре',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Ыран 02:00 сехетре',     'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Паян 01:00 сехетре',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ĕнер 02:00 сехетре',     'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('[Çитес] dddd LT [сехетре]'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[Çитес] dddd LT [сехетре]'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[Çитес] dddd LT [сехетре]'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[Иртнĕ] dddd LT [сехетре]'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[Иртнĕ] dddd LT [сехетре]'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[Иртнĕ] dddd LT [сехетре]'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-мĕш', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-мĕш', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-мĕш', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-мĕш', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-мĕш', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('cy');\n\n    test('parse', function (assert) {\n        var tests = 'Ionawr Ion_Chwefror Chwe_Mawrth Maw_Ebrill Ebr_Mai Mai_Mehefin Meh_Gorffennaf Gor_Awst Aws_Medi Med_Hydref Hyd_Tachwedd Tach_Rhagfyr Rhag'.split('_'),\n            i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'Dydd Sul, Chwefror 14eg 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'Sul, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2il 02 Chwefror Chwe'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14eg 14'],\n                ['d do dddd ddd dd',                   '0 0 Dydd Sul Sul Su'],\n                ['DDD DDDo DDDD',                      '45 45ain 045'],\n                ['w wo ww',                            '6 6ed 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45ain day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 Chwefror 2010'],\n                ['LLL',                                '14 Chwefror 2010 15:25'],\n                ['LLLL',                               'Dydd Sul, 14 Chwefror 2010 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 Chwe 2010'],\n                ['lll',                                '14 Chwe 2010 15:25'],\n                ['llll',                               'Sul, 14 Chwe 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1af', '1af');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2il', '2il');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3ydd', '3ydd');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4ydd', '4ydd');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5ed', '5ed');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6ed', '6ed');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7ed', '7ed');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8fed', '8fed');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9fed', '9fed');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10fed', '10fed');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11eg', '11eg');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12fed', '12fed');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13eg', '13eg');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14eg', '14eg');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15fed', '15fed');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16eg', '16eg');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17eg', '17eg');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18fed', '18fed');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19eg', '19eg');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20fed', '20fed');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ain', '21ain');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ain', '22ain');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ain', '23ain');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ain', '24ain');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ain', '25ain');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ain', '26ain');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ain', '27ain');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ain', '28ain');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ain', '29ain');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ain', '30ain');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ain', '31ain');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'Ionawr Ion_Chwefror Chwe_Mawrth Maw_Ebrill Ebr_Mai Mai_Mehefin Meh_Gorffennaf Gor_Awst Aws_Medi Med_Hydref Hyd_Tachwedd Tach_Rhagfyr Rhag'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'Dydd Sul Sul Su_Dydd Llun Llun Ll_Dydd Mawrth Maw Ma_Dydd Mercher Mer Me_Dydd Iau Iau Ia_Dydd Gwener Gwe Gw_Dydd Sadwrn Sad Sa'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ychydig eiliadau', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'munud',   '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'munud',   '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 munud',  '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 munud', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'awr',    '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'awr',    '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 awr',    '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 awr',    '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 awr',   '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'diwrnod',      '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'diwrnod',      '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 diwrnod',     '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'diwrnod',      '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 diwrnod',     '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 diwrnod',    '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mis',    '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mis',    '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mis',    '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mis',   '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mis',   '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mis',   '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mis',    '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mis',   '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'blwyddyn',     '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 flynedd',    '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'blwyddyn',     '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 flynedd',    '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'mewn ychydig eiliadau', 'prefix');\n        assert.equal(moment(0).from(30000), 'ychydig eiliadau yn ôl', 'suffix');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'mewn ychydig eiliadau', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'mewn 5 diwrnod', 'in 5 days');\n    });\n\n    test('same day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Heddiw am 02:00',    'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Heddiw am 02:25',    'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Heddiw am 03:00',    'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Yfory am 02:00',         'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Heddiw am 01:00',    'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ddoe am 02:00',           'yesterday at the same time');\n    });\n\n    test('same next week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [am] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [am] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [am] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('same last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [diwethaf am] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [diwethaf am] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [diwethaf am] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('same all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ain', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1af', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1af', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2il', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2il', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('da');\n\n    test('parse', function (assert) {\n        var tests = 'januar jan_februar feb_marts mar_april apr_maj maj_juni jun_juli jul_august aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd [den] Do MMMM YYYY, h:mm:ss a', 'søndag den 14. februar 2010, 3:25:50 pm'],\n                ['ddd hA',                             'søn 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14. 14'],\n                ['d do dddd ddd dd',                   '0 0. søndag søn sø'],\n                ['DDD DDDo DDDD',                      '45 45. 045'],\n                ['w wo ww',                            '6 6. 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[den] DDDo [dag på året]',           'den 45. dag på året'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14. februar 2010'],\n                ['LLL',                                '14. februar 2010 15:25'],\n                ['LLLL',                               'søndag d. 14. februar 2010 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14. feb 2010'],\n                ['lll',                                '14. feb 2010 15:25'],\n                ['llll',                               'søn d. 14. feb 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'januar jan_februar feb_marts mar_april apr_maj maj_juni jun_juli jul_august aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'søndag søn sø_mandag man ma_tirsdag tir ti_onsdag ons on_torsdag tor to_fredag fre fr_lørdag lør lø'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'få sekunder', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'et minut',    '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'et minut',    '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutter',  '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutter', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'en time',     '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'en time',     '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timer',     '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timer',     '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timer',    '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dag',      '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dag',      '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dage',      '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dag',      '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dage',      '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dage',     '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en måned',    '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en måned',    '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en måned',    '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 måneder',   '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 måneder',   '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 måneder',   '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en måned',    '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 måneder',   '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'et år',       '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',        '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'et år',       '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',        '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'om få sekunder',  'prefix');\n        assert.equal(moment(0).from(30000), 'få sekunder siden', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'få sekunder siden',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'om få sekunder', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dage', 'in 5 days');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('de-at');\n\n    test('parse', function (assert) {\n        var tests = 'Jänner Jän._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, h:mm:ss a', 'Sonntag, 14. Februar 2010, 3:25:50 pm'],\n                ['ddd, hA', 'So., 3PM'],\n                ['M Mo MM MMMM MMM', '2 2. 02 Februar Febr.'],\n                ['YYYY YY', '2010 10'],\n                ['D Do DD', '14 14. 14'],\n                ['d do dddd ddd dd', '0 0. Sonntag So. So'],\n                ['DDD DDDo DDDD', '45 45. 045'],\n                ['w wo ww', '6 6. 06'],\n                ['h hh', '3 03'],\n                ['H HH', '15 15'],\n                ['m mm', '25 25'],\n                ['s ss', '50 50'],\n                ['a A', 'pm PM'],\n                ['[the] DDDo [day of the year]', 'the 45. day of the year'],\n                ['LTS', '15:25:50'],\n                ['L', '14.02.2010'],\n                ['LL', '14. Februar 2010'],\n                ['LLL', '14. Februar 2010 15:25'],\n                ['LLLL', 'Sonntag, 14. Februar 2010 15:25'],\n                ['l', '14.2.2010'],\n                ['ll', '14. Febr. 2010'],\n                ['lll', '14. Febr. 2010 15:25'],\n                ['llll', 'So., 14. Febr. 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'Jänner Jän._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'Sonntag So. So_Montag Mo. Mo_Dienstag Di. Di_Mittwoch Mi. Mi_Donnerstag Do. Do_Freitag Fr. Fr_Samstag Sa. Sa'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'ein paar Sekunden', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'eine Minute', '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'eine Minute', '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 Minuten', '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 Minuten', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'eine Stunde', '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'eine Stunde', '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 Stunden', '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 Stunden', '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 Stunden', '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'ein Tag', '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'ein Tag', '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 Tage', '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'ein Tag', '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 Tage', '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 Tage', '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'ein Monat', '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'ein Monat', '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 Monate', '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 Monate', '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 Monate', '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'ein Monat', '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 Monate', '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ein Jahr', '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 Jahre', '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'ein Jahr', '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 Jahre', '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'in ein paar Sekunden', 'prefix');\n        assert.equal(moment(0).from(30000), 'vor ein paar Sekunden', 'suffix');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'in ein paar Sekunden', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'in 5 Tagen', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(), 'Heute um 02:00 Uhr', 'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(), 'Heute um 02:25 Uhr', 'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(), 'Heute um 03:00 Uhr', 'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(), 'Morgen um 02:00 Uhr', 'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(), 'Heute um 01:00 Uhr', 'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(), 'Gestern um 02:00 Uhr', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(), m.format('dddd [um] LT [Uhr]'), 'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(), m.format('dddd [um] LT [Uhr]'), 'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(), m.format('dddd [um] LT [Uhr]'), 'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(), m.format('[letzten] dddd [um] LT [Uhr]'), 'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(), m.format('[letzten] dddd [um] LT [Uhr]'), 'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(), m.format('[letzten] dddd [um] LT [Uhr]'), 'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n        assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(), 1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(), 1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(), 2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(), 1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(), 2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008, 0, 1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008, 0, 6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008, 0, 7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008, 0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008, 0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003, 0, 1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003, 0, 5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003, 0, 6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003, 0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003, 0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009, 0, 1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009, 0, 4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009, 0, 5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009, 0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009, 0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010, 0, 1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010, 0, 3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010, 0, 4]).week(), 1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010, 0, 10]).week(), 1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010, 0, 11]).week(), 2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011, 0, 1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011, 0, 2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011, 0, 3]).week(), 1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011, 0, 9]).week(), 1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011, 0, 10]).week(), 2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0, 1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).format('w ww wo'), '1 01 1.', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).format('w ww wo'), '1 01 1.', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).format('w ww wo'), '2 02 2.', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2.', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('de');\n\n    test('parse', function (assert) {\n        var tests = 'Januar Jan._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, h:mm:ss a',      'Sonntag, 14. Februar 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'So., 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2. 02 Februar Febr.'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14. 14'],\n                ['d do dddd ddd dd',                   '0 0. Sonntag So. So'],\n                ['DDD DDDo DDDD',                      '45 45. 045'],\n                ['w wo ww',                            '6 6. 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14.02.2010'],\n                ['LL',                                 '14. Februar 2010'],\n                ['LLL',                                '14. Februar 2010 15:25'],\n                ['LLLL',                               'Sonntag, 14. Februar 2010 15:25'],\n                ['l',                                  '14.2.2010'],\n                ['ll',                                 '14. Febr. 2010'],\n                ['lll',                                '14. Febr. 2010 15:25'],\n                ['llll',                               'So., 14. Febr. 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'Januar Jan._Februar Febr._März Mrz._April Apr._Mai Mai_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'Sonntag So. So_Montag Mo. Mo_Dienstag Di. Di_Mittwoch Mi. Mi_Donnerstag Do. Do_Freitag Fr. Fr_Samstag Sa. Sa'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ein paar Sekunden',  '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'eine Minute',       '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'eine Minute',       '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 Minuten',          '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 Minuten',         '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'eine Stunde',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'eine Stunde',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 Stunden',          '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 Stunden',          '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 Stunden',         '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ein Tag',          '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ein Tag',          '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 Tage',            '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ein Tag',          '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 Tage',            '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 Tage',           '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ein Monat',        '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ein Monat',        '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ein Monat',        '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 Monate',          '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 Monate',          '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 Monate',          '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ein Monat',        '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 Monate',          '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ein Jahr',         '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 Jahre',           '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ein Jahr',         '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 Jahre',           '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'in ein paar Sekunden', 'prefix');\n        assert.equal(moment(0).from(30000), 'vor ein paar Sekunden', 'suffix');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'in ein paar Sekunden', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'in 5 Tagen', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Heute um 02:00 Uhr',   'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Heute um 02:25 Uhr',   'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Heute um 03:00 Uhr',   'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Morgen um 02:00 Uhr',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Heute um 01:00 Uhr',   'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Gestern um 02:00 Uhr', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [um] LT [Uhr]'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[letzten] dddd [um] LT [Uhr]'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('el');\n\n    test('parse', function (assert) {\n        var i,\n            tests = 'Ιανουάριος Ιαν_Φεβρουάριος Φεβ_Μάρτιος Μαρ_Απρίλιος Απρ_Μάιος Μαϊ_Ιούνιος Ιουν_Ιούλιος Ιουλ_Αύγουστος Αυγ_Σεπτέμβριος Σεπ_Οκτώβριος Οκτ_Νοέμβριος Νοε_Δεκέμβριος Δεκ'.split('_');\n\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('parse meridiem', function (assert) {\n        var i,\n            b = moment(),\n            meridiemTests = [\n                ['10 πμ',   10, true],\n                ['10 μμ',   22, true],\n                ['10 π.μ.', 10, true],\n                ['10 μ.μ.', 22, true],\n                ['10 π',    10, true],\n                ['10 μ',    22, true],\n                ['10 ΠΜ',   10, true],\n                ['10 ΜΜ',   22, true],\n                ['10 Π.Μ.', 10, true],\n                ['10 Μ.Μ.', 22, true],\n                ['10 Π',    10, true],\n                ['10 Μ',    22, true],\n                ['10 am',   10, false],\n                ['10 pm',   10, false]\n            ];\n        assert.ok(b.isSame(moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'el', true), 'seconds'), b.format('h:mm:ss a') + ' should be equal to ' + moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'el', true).format('h:mm:ss a'));\n        assert.ok(moment(b.format('h:mm:ss a'), 'h:mm:ss a', 'el', true).isValid(), b.format('h:mm:ss a') + ' should be parsed as valid');\n\n        for (i = 0; i < meridiemTests.length; i++) {\n            assert.equal(moment(meridiemTests[i][0], 'h a', 'el', true).hours(), meridiemTests[i][1], moment(meridiemTests[i][0], 'h a', 'el', true).hours() + ' should be ' + meridiemTests[i][1]);\n            assert.ok(moment(meridiemTests[i][0], 'h a', 'el', true).isValid() === meridiemTests[i][2], meridiemTests[i][0] + ' ----> ' + meridiemTests[i][2]);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'Κυριακή, Φεβρουάριος 14η 2010, 3:25:50 μμ'],\n                ['dddd, D MMMM YYYY, h:mm:ss a',       'Κυριακή, 14 Φεβρουαρίου 2010, 3:25:50 μμ'],\n                ['ddd, hA',                            'Κυρ, 3ΜΜ'],\n                ['dddd, MMMM YYYY',                    'Κυριακή, Φεβρουάριος 2010'],\n                ['M Mo MM MMMM MMM',                   '2 2η 02 Φεβρουάριος Φεβ'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14η 14'],\n                ['d do dddd ddd dd',                   '0 0η Κυριακή Κυρ Κυ'],\n                ['DDD DDDo DDDD',                      '45 45η 045'],\n                ['w wo ww',                            '6 6η 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'μμ ΜΜ'],\n                ['[the] DDDo [day of the year]',       'the 45η day of the year'],\n                ['LTS',                                '3:25:50 ΜΜ'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 Φεβρουαρίου 2010'],\n                ['LLL',                                '14 Φεβρουαρίου 2010 3:25 ΜΜ'],\n                ['LLLL',                               'Κυριακή, 14 Φεβρουαρίου 2010 3:25 ΜΜ'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 Φεβ 2010'],\n                ['lll',                                '14 Φεβ 2010 3:25 ΜΜ'],\n                ['llll',                               'Κυρ, 14 Φεβ 2010 3:25 ΜΜ']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1η', '1η');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2η', '2η');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3η', '3η');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4η', '4η');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5η', '5η');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6η', '6η');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7η', '7η');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8η', '8η');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9η', '9η');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10η', '10η');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11η', '11η');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12η', '12η');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13η', '13η');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14η', '14η');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15η', '15η');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16η', '16η');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17η', '17η');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18η', '18η');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19η', '19η');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20η', '20η');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21η', '21η');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22η', '22η');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23η', '23η');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24η', '24η');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25η', '25η');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26η', '26η');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27η', '27η');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28η', '28η');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29η', '29η');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30η', '30η');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31η', '31η');\n    });\n\n    test('format month', function (assert) {\n        var i,\n            expected = 'Ιανουάριος Ιαν_Φεβρουάριος Φεβ_Μάρτιος Μαρ_Απρίλιος Απρ_Μάιος Μαϊ_Ιούνιος Ιουν_Ιούλιος Ιουλ_Αύγουστος Αυγ_Σεπτέμβριος Σεπ_Οκτώβριος Οκτ_Νοέμβριος Νοε_Δεκέμβριος Δεκ'.split('_');\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var i,\n            expected = 'Κυριακή Κυρ Κυ_Δευτέρα Δευ Δε_Τρίτη Τρι Τρ_Τετάρτη Τετ Τε_Πέμπτη Πεμ Πε_Παρασκευή Παρ Πα_Σάββατο Σαβ Σα'.split('_');\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'λίγα δευτερόλεπτα',   '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ένα λεπτό',           '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ένα λεπτό',           '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 λεπτά',             '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 λεπτά',            '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'μία ώρα',             '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'μία ώρα',             '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ώρες',              '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ώρες',              '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ώρες',             '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'μία μέρα',            '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'μία μέρα',            '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 μέρες',             '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'μία μέρα',            '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 μέρες',             '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 μέρες',            '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ένας μήνας',          '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ένας μήνας',          '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ένας μήνας',          '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 μήνες',             '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 μήνες',             '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 μήνες',             '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ένας μήνας',          '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 μήνες',             '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ένας χρόνος',         '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 χρόνια',            '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ένας χρόνος',         '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 χρόνια',            '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'σε λίγα δευτερόλεπτα',  'prefix');\n        assert.equal(moment(0).from(30000), 'λίγα δευτερόλεπτα πριν', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'λίγα δευτερόλεπτα πριν',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'σε λίγα δευτερόλεπτα', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'σε 5 μέρες', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Σήμερα στις 2:00 ΠΜ',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Σήμερα στις 2:25 ΠΜ',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Σήμερα στις 3:00 ΠΜ',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Αύριο στις 2:00 ΠΜ',      'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Σήμερα στη 1:00 ΠΜ',        'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Χθες στις 2:00 ΠΜ',       'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [' + (m.hours() % 12 === 1 ? 'στη' : 'στις') + '] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [στις] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [στις] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m, dayString;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            dayString = m.day() === 6 ? '[το προηγούμενο Σάββατο]' : '[την προηγούμενη] dddd';\n            assert.equal(m.calendar(),       m.format(dayString + ' [' + (m.hours() % 12 === 1 ? 'στη' : 'στις') + '] LT'),  'Today - ' + i + ' days current time');\n            m.hours(1).minutes(30).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(dayString + ' [στη] LT'),  'Today - ' + i + ' days one o clock');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(dayString + ' [στις] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format(dayString + ' [στις] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0,  1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).week(), 1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 31]).week(), 52, 'Dec 31 2006 should be week 52');\n        assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n        assert.equal(moment([2007,  0,  7]).week(), 1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n        assert.equal(moment([2007,  0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 30]).week(), 52, 'Dec 30 2007 should be week 52');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 29]).week(), 52, 'Dec 29 2002 should be week 52');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 28]).week(), 52, 'Dec 28 2008 should be week 52');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 27]).week(), 52, 'Dec 27 2009 should be week 52');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  2]).week(), 53, 'Jan  2 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  9]).week(), 1, 'Jan  9 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(), 1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(), 2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 26]).week(), 51, 'Dec 26 2010 should be week 51');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  8]).week(), 1, 'Jan  8 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(), 1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(), 2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday format', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52η', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  7]).format('w ww wo'),   '1 01 1η', 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1η', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 14]).format('w ww wo'),   '2 02 2η', 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2η', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('en-au');\n\n    test('parse', function (assert) {\n        var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'Sun, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14th 14'],\n                ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n                ['DDD DDDo DDDD',                      '45 45th 045'],\n                ['w wo ww',                            '6 6th 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n                ['LTS',                                '3:25:50 PM'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 February 2010'],\n                ['LLL',                                '14 February 2010 3:25 PM'],\n                ['LLLL',                               'Sunday, 14 February 2010 3:25 PM'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 Feb 2010'],\n                ['lll',                                '14 Feb 2010 3:25 PM'],\n                ['llll',                               'Sun, 14 Feb 2010 3:25 PM']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n        assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Today at 2:00 AM',      'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 2:25 AM',      'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 3:00 AM',      'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 2:00 AM',   'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 1:00 AM',      'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 2:00 AM',  'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testStr;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testStr = moment(ordinalStr, 'YYYY MM Do').format('YYYY MM D');\n            assert.equal(testStr, '2014 01 ' + i, 'lenient ordinal parsing ' + i);\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testStr;\n        for (i = 1; i <= 31; ++i) {\n            testStr = moment('2014 01 ' + i, 'YYYY MM Do').format('YYYY MM D');\n            assert.equal(testStr, '2014 01 ' + i,\n                    'lenient ordinal parsing of number ' + i);\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MMM Do');\n            testMoment = moment(ordinalStr, 'YYYY MMM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('en-ca');\n\n    test('parse', function (assert) {\n        var i,\n            tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'Sun, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14th 14'],\n                ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n                ['DDD DDDo DDDD',                      '45 45th 045'],\n                ['w wo ww',                            '8 8th 08'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n                ['L',                                  '2010-02-14'],\n                ['LTS',                                '3:25:50 PM'],\n                ['LL',                                 '14 February, 2010'],\n                ['LLL',                                '14 February, 2010 3:25 PM'],\n                ['LLLL',                               'Sunday, 14 February, 2010 3:25 PM'],\n                ['l',                                  '2010-2-14'],\n                ['ll',                                 '14 Feb, 2010'],\n                ['lll',                                '14 Feb, 2010 3:25 PM'],\n                ['llll',                               'Sun, 14 Feb, 2010 3:25 PM']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n    });\n\n    test('format month', function (assert) {\n        var i,\n            expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var i,\n            expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_');\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n        assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Today at 2:00 AM',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 2:25 AM',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 3:00 AM',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 2:00 AM',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 1:00 AM',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 2:00 AM', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n        assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n        assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n        assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n        assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday format', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1st', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1st', 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2nd', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2nd', 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3rd', 'Jan 15 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('en-gb');\n\n    test('parse', function (assert) {\n        var tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'Sun, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14th 14'],\n                ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n                ['DDD DDDo DDDD',                      '45 45th 045'],\n                ['w wo ww',                            '6 6th 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 February 2010'],\n                ['LLL',                                '14 February 2010 15:25'],\n                ['LLLL',                               'Sunday, 14 February 2010 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 Feb 2010'],\n                ['lll',                                '14 Feb 2010 15:25'],\n                ['llll',                               'Sun, 14 Feb 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n        assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Today at 02:00',      'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 02:25',      'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 03:00',      'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 02:00',   'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 01:00',      'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 02:00',  'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52nd', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1st', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1st', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2nd', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2nd', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('en');\n\n    test('parse', function (assert) {\n        var i,\n            tests = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'Sunday, February 14th 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'Sun, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2nd 02 February Feb'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14th 14'],\n                ['d do dddd ddd dd',                   '0 0th Sunday Sun Su'],\n                ['DDD DDDo DDDD',                      '45 45th 045'],\n                ['w wo ww',                            '8 8th 08'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45th day of the year'],\n                ['LTS',                                '3:25:50 PM'],\n                ['L',                                  '02/14/2010'],\n                ['LL',                                 'February 14, 2010'],\n                ['LLL',                                'February 14, 2010 3:25 PM'],\n                ['LLLL',                               'Sunday, February 14, 2010 3:25 PM'],\n                ['l',                                  '2/14/2010'],\n                ['ll',                                 'Feb 14, 2010'],\n                ['lll',                                'Feb 14, 2010 3:25 PM'],\n                ['llll',                               'Sun, Feb 14, 2010 3:25 PM']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1st', '1st');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2nd', '2nd');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3rd', '3rd');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4th', '4th');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5th', '5th');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6th', '6th');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7th', '7th');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8th', '8th');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9th', '9th');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10th', '10th');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11th', '11th');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12th', '12th');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13th', '13th');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14th', '14th');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15th', '15th');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16th', '16th');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17th', '17th');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18th', '18th');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19th', '19th');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20th', '20th');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21st', '21st');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22nd', '22nd');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23rd', '23rd');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24th', '24th');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25th', '25th');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26th', '26th');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27th', '27th');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28th', '28th');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29th', '29th');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30th', '30th');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31st', '31st');\n    });\n\n    test('format month', function (assert) {\n        var i,\n            expected = 'January Jan_February Feb_March Mar_April Apr_May May_June Jun_July Jul_August Aug_September Sep_October Oct_November Nov_December Dec'.split('_');\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var i,\n            expected = 'Sunday Sun Su_Monday Mon Mo_Tuesday Tue Tu_Wednesday Wed We_Thursday Thu Th_Friday Fri Fr_Saturday Sat Sa'.split('_');\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'a few seconds', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'a minute',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'a minute',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'an hour',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'an hour',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hours',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hours',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hours',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'a day',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'a day',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 days',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'a day',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 days',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 days',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'a month',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'a month',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'a month',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 months',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 months',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 months',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'a month',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 months',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'a year',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 years',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'a year',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 years',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'in a few seconds',  'prefix');\n        assert.equal(moment(0).from(30000), 'a few seconds ago', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'a few seconds ago',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'in a few seconds', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'in 5 days', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Today at 2:00 AM',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Today at 2:25 AM',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Today at 3:00 AM',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at 2:00 AM',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at 1:00 AM',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at 2:00 AM', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [at] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[Last] dddd [at] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n        assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n        assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n        assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n        assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday format', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1st', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1st', 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2nd', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2nd', 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3rd', 'Jan 15 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('eo');\n\n    test('parse', function (assert) {\n        var tests = 'januaro jan_februaro feb_marto mar_aprilo apr_majo maj_junio jun_julio jul_aŭgusto aŭg_septembro sep_oktobro okt_novembro nov_decembro dec'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'Dimanĉo, februaro 14a 2010, 3:25:50 p.t.m.'],\n                ['ddd, hA',                            'Dim, 3P.T.M.'],\n                ['M Mo MM MMMM MMM',                   '2 2a 02 februaro feb'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14a 14'],\n                ['d do dddd ddd dd',                   '0 0a Dimanĉo Dim Di'],\n                ['DDD DDDo DDDD',                      '45 45a 045'],\n                ['w wo ww',                            '7 7a 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'p.t.m. P.T.M.'],\n                ['[la] DDDo [tago] [de] [la] [jaro]',  'la 45a tago de la jaro'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '2010-02-14'],\n                ['LL',                                 '14-an de februaro, 2010'],\n                ['LLL',                                '14-an de februaro, 2010 15:25'],\n                ['LLLL',                               'Dimanĉo, la 14-an de februaro, 2010 15:25'],\n                ['l',                                  '2010-2-14'],\n                ['ll',                                 '14-an de feb, 2010'],\n                ['lll',                                '14-an de feb, 2010 15:25'],\n                ['llll',                               'Dim, la 14-an de feb, 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1a', '1a');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2a', '2a');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3a', '3a');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4a', '4a');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5a', '5a');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6a', '6a');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7a', '7a');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8a', '8a');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9a', '9a');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10a', '10a');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11a', '11a');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12a', '12a');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13a', '13a');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14a', '14a');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15a', '15a');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16a', '16a');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17a', '17a');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18a', '18a');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19a', '19a');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20a', '20a');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21a', '21a');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22a', '22a');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23a', '23a');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24a', '24a');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25a', '25a');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26a', '26a');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27a', '27a');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28a', '28a');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29a', '29a');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30a', '30a');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31a', '31a');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'januaro jan_februaro feb_marto mar_aprilo apr_majo maj_junio jun_julio jul_aŭgusto aŭg_septembro sep_oktobro okt_novembro nov_decembro dec'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'Dimanĉo Dim Di_Lundo Lun Lu_Mardo Mard Ma_Merkredo Merk Me_Ĵaŭdo Ĵaŭ Ĵa_Vendredo Ven Ve_Sabato Sab Sa'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'sekundoj', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuto',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuto',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutoj',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutoj',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'horo',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'horo',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horoj',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horoj',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horoj',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'tago',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'tago',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 tagoj',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'tago',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 tagoj',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 tagoj',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'monato',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'monato',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'monato',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 monatoj',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 monatoj',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 monatoj',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'monato',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 monatoj',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'jaro',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jaroj',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'jaro',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jaroj',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'je sekundoj',  'je prefix');\n        assert.equal(moment(0).from(30000), 'antaŭ sekundoj', 'antaŭ prefix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'antaŭ sekundoj',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'je sekundoj', 'je sekundoj');\n        assert.equal(moment().add({d: 5}).fromNow(), 'je 5 tagoj', 'je 5 tagoj');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Hodiaŭ je 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Hodiaŭ je 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Hodiaŭ je 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Morgaŭ je 02:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hodiaŭ je 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Hieraŭ je 02:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [je] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [je] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [je] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[pasinta] dddd [je] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[pasinta] dddd [je] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[pasinta] dddd [je] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1a', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1a', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2a', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2a', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3a', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('es');\n\n    test('parse', function (assert) {\n        var tests = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'domingo, febrero 14º 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'dom., 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2º 02 febrero feb.'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14º 14'],\n                ['d do dddd ddd dd',                   '0 0º domingo dom. Do'],\n                ['DDD DDDo DDDD',                      '45 45º 045'],\n                ['w wo ww',                            '6 6º 06'],\n                ['YYYY-MMM-DD',                        '2010-feb-14'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 de febrero de 2010'],\n                ['LLL',                                '14 de febrero de 2010 15:25'],\n                ['LLLL',                               'domingo, 14 de febrero de 2010 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 de feb. de 2010'],\n                ['lll',                                '14 de feb. de 2010 15:25'],\n                ['llll',                               'dom., 14 de feb. de 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'enero ene._febrero feb._marzo mar._abril abr._mayo may._junio jun._julio jul._agosto ago._septiembre sep._octubre oct._noviembre nov._diciembre dic.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'domingo dom. Do_lunes lun. Lu_martes mar. Ma_miércoles mié. Mi_jueves jue. Ju_viernes vie. Vi_sábado sáb. Sá'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'unos segundos', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minuto',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minuto',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'una hora',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'una hora',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un día',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un día',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 días',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un día',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 días',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 días',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mes',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mes',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mes',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mes',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un año',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 años',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un año',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 años',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'en unos segundos',  'prefix');\n        assert.equal(moment(0).from(30000), 'hace unos segundos', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'hace unos segundos',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'en unos segundos', 'en unos segundos');\n        assert.equal(moment().add({d: 5}).fromNow(), 'en 5 días', 'en 5 días');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                         'hoy a las 2:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),          'hoy a las 2:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),           'hoy a las 3:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),           'mañana a las 2:00',  'tomorrow at the same time');\n        assert.equal(moment(a).add({d: 1, h : -1}).calendar(),   'mañana a la 1:00',   'tomorrow minus 1 hour');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),      'hoy a la 1:00',      'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),      'ayer a las 2:00',    'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[el] dddd [pasado a la' + ((m.hours() !== 1) ? 's' : '') + '] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1º', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1º', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2º', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2º', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('et');\n\n    test('parse', function (assert) {\n        var tests = 'jaanuar jaan_veebruar veebr_märts märts_aprill apr_mai mai_juuni juuni_juuli juuli_august aug_september sept_oktoober okt_november nov_detsember dets'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' peaks olema kuu ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, H:mm:ss',      'pühapäev, 14. veebruar 2010, 15:25:50'],\n                ['ddd, h',                           'P, 3'],\n                ['M Mo MM MMMM MMM',                 '2 2. 02 veebruar veebr'],\n                ['YYYY YY',                          '2010 10'],\n                ['D Do DD',                          '14 14. 14'],\n                ['d do dddd ddd dd',                 '0 0. pühapäev P P'],\n                ['DDD DDDo DDDD',                    '45 45. 045'],\n                ['w wo ww',                          '6 6. 06'],\n                ['h hh',                             '3 03'],\n                ['H HH',                             '15 15'],\n                ['m mm',                             '25 25'],\n                ['s ss',                             '50 50'],\n                ['a A',                              'pm PM'],\n                ['[aasta] DDDo [päev]',              'aasta 45. päev'],\n                ['LTS',                              '15:25:50'],\n                ['L',                                '14.02.2010'],\n                ['LL',                               '14. veebruar 2010'],\n                ['LLL',                              '14. veebruar 2010 15:25'],\n                ['LLLL',                             'pühapäev, 14. veebruar 2010 15:25'],\n                ['l',                                '14.2.2010'],\n                ['ll',                               '14. veebr 2010'],\n                ['lll',                              '14. veebr 2010 15:25'],\n                ['llll',                             'P, 14. veebr 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'jaanuar jaan_veebruar veebr_märts märts_aprill apr_mai mai_juuni juuni_juuli juuli_august aug_september sept_oktoober okt_november nov_detsember dets'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'pühapäev P P_esmaspäev E E_teisipäev T T_kolmapäev K K_neljapäev N N_reede R R_laupäev L L'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'paar sekundit',  '44 seconds = paar sekundit');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'üks minut',      '45 seconds = üks minut');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'üks minut',      '89 seconds = üks minut');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutit',      '90 seconds = 2 minutit');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutit',     '44 minutes = 44 minutit');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'üks tund',       '45 minutes = tund aega');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'üks tund',       '89 minutes = üks tund');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 tundi',        '90 minutes = 2 tundi');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 tundi',        '5 hours = 5 tundi');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tundi',       '21 hours = 21 tundi');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'üks päev',       '22 hours = üks päev');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'üks päev',       '35 hours = üks päev');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 päeva',        '36 hours = 2 päeva');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'üks päev',       '1 day = üks päev');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 päeva',        '5 days = 5 päeva');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 päeva',       '25 days = 25 päeva');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'üks kuu',        '26 days = üks kuu');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'üks kuu',        '30 days = üks kuu');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'üks kuu',        '43 days = üks kuu');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 kuud',         '46 days = 2 kuud');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 kuud',         '75 days = 2 kuud');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 kuud',         '76 days = 3 kuud');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'üks kuu',        '1 month = üks kuu');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 kuud',         '5 months = 5 kuud');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'üks aasta',      '345 days = üks aasta');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 aastat',       '548 days = 2 aastat');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'üks aasta',      '1 year = üks aasta');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 aastat',       '5 years = 5 aastat');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'mõne sekundi pärast',  'prefix');\n        assert.equal(moment(0).from(30000), 'mõni sekund tagasi', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'mõni sekund tagasi',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'mõne sekundi pärast', 'in a few seconds');\n        assert.equal(moment().subtract({s: 30}).fromNow(), 'mõni sekund tagasi', 'a few seconds ago');\n\n        assert.equal(moment().add({m: 1}).fromNow(), 'ühe minuti pärast', 'in a minute');\n        assert.equal(moment().subtract({m: 1}).fromNow(), 'üks minut tagasi', 'a minute ago');\n\n        assert.equal(moment().add({m: 5}).fromNow(), '5 minuti pärast', 'in 5 minutes');\n        assert.equal(moment().subtract({m: 5}).fromNow(), '5 minutit tagasi', '5 minutes ago');\n\n        assert.equal(moment().add({d: 1}).fromNow(), 'ühe päeva pärast', 'in one day');\n        assert.equal(moment().subtract({d: 1}).fromNow(), 'üks päev tagasi', 'one day ago');\n\n        assert.equal(moment().add({d: 5}).fromNow(), '5 päeva pärast', 'in 5 days');\n        assert.equal(moment().subtract({d: 5}).fromNow(), '5 päeva tagasi', '5 days ago');\n\n        assert.equal(moment().add({M: 1}).fromNow(), 'kuu aja pärast', 'in a month');\n        assert.equal(moment().subtract({M: 1}).fromNow(), 'kuu aega tagasi', 'a month ago');\n\n        assert.equal(moment().add({M: 5}).fromNow(), '5 kuu pärast', 'in 5 months');\n        assert.equal(moment().subtract({M: 5}).fromNow(), '5 kuud tagasi', '5 months ago');\n\n        assert.equal(moment().add({y: 1}).fromNow(), 'ühe aasta pärast', 'in a year');\n        assert.equal(moment().subtract({y: 1}).fromNow(), 'aasta tagasi', 'a year ago');\n\n        assert.equal(moment().add({y: 5}).fromNow(), '5 aasta pärast', 'in 5 years');\n        assert.equal(moment().subtract({y: 5}).fromNow(), '5 aastat tagasi', '5 years ago');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Täna, 2:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Täna, 2:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Täna, 3:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Homme, 2:00',    'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Täna, 1:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Eile, 2:00',     'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('[Järgmine] dddd LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[Järgmine] dddd LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[Järgmine] dddd LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[Eelmine] dddd LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[Eelmine] dddd LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[Eelmine] dddd LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 nädal tagasi');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '1 nädala pärast');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 nädalat tagasi');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '2 nädala pärast');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('eu');\n\n    test('parse', function (assert) {\n        var tests = 'urtarrila urt._otsaila ots._martxoa mar._apirila api._maiatza mai._ekaina eka._uztaila uzt._abuztua abu._iraila ira._urria urr._azaroa aza._abendua abe.'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'igandea, otsaila 14. 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'ig., 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2. 02 otsaila ots.'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14. 14'],\n                ['d do dddd ddd dd',                   '0 0. igandea ig. ig'],\n                ['DDD DDDo DDDD',                      '45 45. 045'],\n                ['w wo ww',                            '7 7. 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '2010-02-14'],\n                ['LL',                                 '2010ko otsailaren 14a'],\n                ['LLL',                                '2010ko otsailaren 14a 15:25'],\n                ['LLLL',                               'igandea, 2010ko otsailaren 14a 15:25'],\n                ['l',                                  '2010-2-14'],\n                ['ll',                                 '2010ko ots. 14a'],\n                ['lll',                                '2010ko ots. 14a 15:25'],\n                ['llll',                               'ig., 2010ko ots. 14a 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'urtarrila urt._otsaila ots._martxoa mar._apirila api._maiatza mai._ekaina eka._uztaila uzt._abuztua abu._iraila ira._urria urr._azaroa aza._abendua abe.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'igandea ig. ig_astelehena al. al_asteartea ar. ar_asteazkena az. az_osteguna og. og_ostirala ol. ol_larunbata lr. lr'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'segundo batzuk', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minutu bat',     '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minutu bat',     '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutu',       '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutu',      '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ordu bat',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ordu bat',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ordu',         '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ordu',         '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ordu',        '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'egun bat',       '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'egun bat',       '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 egun',         '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'egun bat',       '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 egun',         '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 egun',        '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'hilabete bat',   '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'hilabete bat',   '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'hilabete bat',   '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 hilabete',     '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 hilabete',     '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 hilabete',     '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'hilabete bat',   '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 hilabete',     '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'urte bat',       '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 urte',         '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'urte bat',       '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 urte',         '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'segundo batzuk barru',  'prefix');\n        assert.equal(moment(0).from(30000), 'duela segundo batzuk', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'duela segundo batzuk',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'segundo batzuk barru', 'in seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), '5 egun barru', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'gaur 02:00etan',  'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'gaur 02:25etan',  'now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'gaur 03:00etan',  'now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'bihar 02:00etan', 'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'gaur 01:00etan',  'now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'atzo 02:00etan',  'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd LT[etan]'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd LT[etan]'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd LT[etan]'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[aurreko] dddd LT[etan]'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[aurreko] dddd LT[etan]'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[aurreko] dddd LT[etan]'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('fa');\n\n    test('parse', function (assert) {\n        var tests = 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1) + ' instead is month ' + moment(input, mmm).month());\n        }\n        for (i = 0; i < 12; i++) {\n            equalTest(tests[i], 'MMM', i);\n            equalTest(tests[i], 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'یک\\u200cشنبه، فوریه ۱۴م ۲۰۱۰، ۳:۲۵:۵۰ بعد از ظهر'],\n                ['ddd, hA',                            'یک\\u200cشنبه، ۳بعد از ظهر'],\n                ['M Mo MM MMMM MMM',                   '۲ ۲م ۰۲ فوریه فوریه'],\n                ['YYYY YY',                            '۲۰۱۰ ۱۰'],\n                ['D Do DD',                            '۱۴ ۱۴م ۱۴'],\n                ['d do dddd ddd dd',                   '۰ ۰م یک\\u200cشنبه یک\\u200cشنبه ی'],\n                ['DDD DDDo DDDD',                      '۴۵ ۴۵م ۰۴۵'],\n                ['w wo ww',                            '۸ ۸م ۰۸'],\n                ['h hh',                               '۳ ۰۳'],\n                ['H HH',                               '۱۵ ۱۵'],\n                ['m mm',                               '۲۵ ۲۵'],\n                ['s ss',                               '۵۰ ۵۰'],\n                ['a A',                                'بعد از ظهر بعد از ظهر'],\n                ['DDDo [روز سال]',             '۴۵م روز سال'],\n                ['LTS',                                '۱۵:۲۵:۵۰'],\n                ['L',                                  '۱۴/۰۲/۲۰۱۰'],\n                ['LL',                                 '۱۴ فوریه ۲۰۱۰'],\n                ['LLL',                                '۱۴ فوریه ۲۰۱۰ ۱۵:۲۵'],\n                ['LLLL',                               'یک\\u200cشنبه، ۱۴ فوریه ۲۰۱۰ ۱۵:۲۵'],\n                ['l',                                  '۱۴/۲/۲۰۱۰'],\n                ['ll',                                 '۱۴ فوریه ۲۰۱۰'],\n                ['lll',                                '۱۴ فوریه ۲۰۱۰ ۱۵:۲۵'],\n                ['llll',                               'یک\\u200cشنبه، ۱۴ فوریه ۲۰۱۰ ۱۵:۲۵']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '۱م', '1');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '۲م', '2');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '۳م', '3');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '۴م', '4');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '۵م', '5');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '۶م', '6');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '۷م', '7');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '۸م', '8');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '۹م', '9');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '۱۰م', '10');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '۱۱م', '11');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '۱۲م', '12');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '۱۳م', '13');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '۱۴م', '14');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '۱۵م', '15');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '۱۶م', '16');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '۱۷م', '17');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '۱۸م', '18');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '۱۹م', '19');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '۲۰م', '20');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '۲۱م', '21');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '۲۲م', '22');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '۲۳م', '23');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '۲۴م', '24');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '۲۵م', '25');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '۲۶م', '26');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '۲۷م', '27');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '۲۸م', '28');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '۲۹م', '29');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '۳۰م', '30');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '۳۱م', '31');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'ژانویه ژانویه_فوریه فوریه_مارس مارس_آوریل آوریل_مه مه_ژوئن ژوئن_ژوئیه ژوئیه_اوت اوت_سپتامبر سپتامبر_اکتبر اکتبر_نوامبر نوامبر_دسامبر دسامبر'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'یک\\u200cشنبه یک\\u200cشنبه ی_دوشنبه دوشنبه د_سه\\u200cشنبه سه\\u200cشنبه س_چهارشنبه چهارشنبه چ_پنج\\u200cشنبه پنج\\u200cشنبه پ_جمعه جمعه ج_شنبه شنبه ش'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'چندین ثانیه', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'یک دقیقه',       '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'یک دقیقه',       '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '۲ دقیقه',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '۴۴ دقیقه',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'یک ساعت',     '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'یک ساعت',     '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '۲ ساعت',      '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '۵ ساعت',      '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '۲۱ ساعت',     '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'یک روز',      '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'یک روز',      '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '۲ روز',       '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'یک روز',      '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '۵ روز',       '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '۲۵ روز',      '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'یک ماه',      '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'یک ماه',      '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'یک ماه',      '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '۲ ماه',       '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '۲ ماه',       '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '۳ ماه',       '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'یک ماه',      '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '۵ ماه',       '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'یک سال',      '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '۲ سال',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'یک سال',      '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '۵ سال',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'در چندین ثانیه', 'prefix');\n        assert.equal(moment(0).from(30000), 'چندین ثانیه پیش', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'چندین ثانیه پیش',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'در چندین ثانیه', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'در ۵ روز', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'امروز ساعت ۰۲:۰۰', 'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'امروز ساعت ۰۲:۲۵', 'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'امروز ساعت ۰۳:۰۰', 'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'فردا ساعت ۰۲:۰۰', 'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'امروز ساعت ۰۱:۰۰', 'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'دیروز ساعت ۰۲:۰۰', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [ساعت] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [ساعت] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [ساعت] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [پیش ساعت] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [پیش ساعت] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [پیش ساعت] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 31]).week(), 1, 'Dec 31 2011 should be week 1');\n        assert.equal(moment([2012,  0,  6]).week(), 1, 'Jan  6 2012 should be week 1');\n        assert.equal(moment([2012,  0,  7]).week(), 2, 'Jan  7 2012 should be week 2');\n        assert.equal(moment([2012,  0, 13]).week(), 2, 'Jan 13 2012 should be week 2');\n        assert.equal(moment([2012,  0, 14]).week(), 3, 'Jan 14 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 30]).week(), 1, 'Dec 30 2006 should be week 1');\n        assert.equal(moment([2007,  0,  5]).week(), 1, 'Jan  5 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 2, 'Jan  6 2007 should be week 2');\n        assert.equal(moment([2007,  0, 12]).week(), 2, 'Jan 12 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 3, 'Jan 13 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 1, 'Dec 29 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  4]).week(), 1, 'Jan  4 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 2, 'Jan  5 2008 should be week 2');\n        assert.equal(moment([2008,  0, 11]).week(), 2, 'Jan 11 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 3, 'Jan 12 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 28]).week(), 1, 'Dec 28 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  3]).week(), 1, 'Jan  3 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 2, 'Jan  4 2003 should be week 2');\n        assert.equal(moment([2003,  0, 10]).week(), 2, 'Jan 10 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 3, 'Jan 11 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 27]).week(), 1, 'Dec 27 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  2]).week(), 1, 'Jan  2 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 2, 'Jan  3 2009 should be week 2');\n        assert.equal(moment([2009,  0,  9]).week(), 2, 'Jan  9 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 3, 'Jan 10 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 26]).week(), 1, 'Dec 26 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 2, 'Jan  2 2010 should be week 2');\n        assert.equal(moment([2010,  0,  8]).week(), 2, 'Jan  8 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 3, 'Jan  9 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2011, 0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011, 0,  7]).week(), 1, 'Jan  7 2011 should be week 1');\n        assert.equal(moment([2011, 0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011, 0, 14]).week(), 2, 'Jan 14 2011 should be week 2');\n        assert.equal(moment([2011, 0, 15]).week(), 3, 'Jan 15 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 31]).format('w ww wo'), '۱ ۰۱ ۱م', 'Dec 31 2011 should be week 1');\n        assert.equal(moment([2012,  0,  6]).format('w ww wo'), '۱ ۰۱ ۱م', 'Jan  6 2012 should be week 1');\n        assert.equal(moment([2012,  0,  7]).format('w ww wo'), '۲ ۰۲ ۲م', 'Jan  7 2012 should be week 2');\n        assert.equal(moment([2012,  0, 13]).format('w ww wo'), '۲ ۰۲ ۲م', 'Jan 13 2012 should be week 2');\n        assert.equal(moment([2012,  0, 14]).format('w ww wo'), '۳ ۰۳ ۳م', 'Jan 14 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('fi');\n\n    test('parse', function (assert) {\n        var tests = 'tammikuu tammi_helmikuu helmi_maaliskuu maalis_huhtikuu huhti_toukokuu touko_kesäkuu kesä_heinäkuu heinä_elokuu elo_syyskuu syys_lokakuu loka_marraskuu marras_joulukuu joulu'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'sunnuntai, helmikuu 14. 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'su, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2. 02 helmikuu helmi'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14. 14'],\n                ['d do dddd ddd dd',                   '0 0. sunnuntai su su'],\n                ['DDD DDDo DDDD',                      '45 45. 045'],\n                ['w wo ww',                            '6 6. 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[vuoden] DDDo [päivä]',              'vuoden 45. päivä'],\n                ['LTS',                                '15.25.50'],\n                ['L',                                  '14.02.2010'],\n                ['LL',                                 '14. helmikuuta 2010'],\n                ['LLL',                                '14. helmikuuta 2010, klo 15.25'],\n                ['LLLL',                               'sunnuntai, 14. helmikuuta 2010, klo 15.25'],\n                ['l',                                  '14.2.2010'],\n                ['ll',                                 '14. helmi 2010'],\n                ['lll',                                '14. helmi 2010, klo 15.25'],\n                ['llll',                               'su, 14. helmi 2010, klo 15.25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1st');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2nd');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3rd');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4th');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5th');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6th');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7th');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8th');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9th');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10th');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11th');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12th');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13th');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14th');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15th');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16th');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17th');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18th');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19th');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20th');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21st');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22nd');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23rd');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24th');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25th');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26th');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27th');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28th');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29th');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30th');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31st');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'tammikuu tammi_helmikuu helmi_maaliskuu maalis_huhtikuu huhti_toukokuu touko_kesäkuu kesä_heinäkuu heinä_elokuu elo_syyskuu syys_lokakuu loka_marraskuu marras_joulukuu joulu'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'sunnuntai su su_maanantai ma ma_tiistai ti ti_keskiviikko ke ke_torstai to to_perjantai pe pe_lauantai la la'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'muutama sekunti', '44 seconds = few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuutti',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuutti',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  'kaksi minuuttia',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuuttia',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'tunti',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'tunti',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'kaksi tuntia',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   'viisi tuntia',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tuntia',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'päivä',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'päivä',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'kaksi päivää',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'päivä',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   'viisi päivää',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 päivää',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'kuukausi',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'kuukausi',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'kuukausi',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'kaksi kuukautta',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'kaksi kuukautta',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  'kolme kuukautta',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'kuukausi',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   'viisi kuukautta',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'vuosi',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'kaksi vuotta',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'vuosi',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   'viisi vuotta',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'muutaman sekunnin päästä',  'prefix');\n        assert.equal(moment(0).from(30000), 'muutama sekunti sitten', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'muutama sekunti sitten',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'muutaman sekunnin päästä', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'viiden päivän päästä', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'tänään klo 02.00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'tänään klo 02.25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'tänään klo 03.00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'huomenna klo 02.00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'tänään klo 01.00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'eilen klo 02.00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [klo] LT'),  'today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [klo] LT'),  'today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [klo] LT'),  'today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[viime] dddd[na] [klo] LT'),  'today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[viime] dddd[na] [klo] LT'),  'today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[viime] dddd[na] [klo] LT'),  'today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'yksi viikko sitten');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'yhden viikon päästä');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'kaksi viikkoa sitten');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'kaden viikon päästä');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('fo');\n\n    test('parse', function (assert) {\n        var tests = 'januar jan_februar feb_mars mar_apríl apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd [tann] Do MMMM YYYY, h:mm:ss a', 'sunnudagur tann 14. februar 2010, 3:25:50 pm'],\n                ['ddd hA',                             'sun 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14. 14'],\n                ['d do dddd ddd dd',                   '0 0. sunnudagur sun su'],\n                ['DDD DDDo DDDD',                      '45 45. 045'],\n                ['w wo ww',                            '6 6. 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[tann] DDDo [dagin á árinum]',       'tann 45. dagin á árinum'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 februar 2010'],\n                ['LLL',                                '14 februar 2010 15:25'],\n                ['LLLL',                               'sunnudagur 14. februar, 2010 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 feb 2010'],\n                ['lll',                                '14 feb 2010 15:25'],\n                ['llll',                               'sun 14. feb, 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'januar jan_februar feb_mars mar_apríl apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'sunnudagur sun su_mánadagur mán má_týsdagur týs tý_mikudagur mik mi_hósdagur hós hó_fríggjadagur frí fr_leygardagur ley le'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'fá sekund', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ein minutt',    '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ein minutt',    '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuttir',  '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuttir', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ein tími',     '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ein tími',     '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 tímar',     '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 tímar',     '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tímar',    '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ein dagur',      '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ein dagur',      '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',      '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ein dagur',      '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',      '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',     '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ein mánaði',    '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ein mánaði',    '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ein mánaði',    '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mánaðir',   '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mánaðir',   '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mánaðir',   '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ein mánaði',    '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mánaðir',   '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'eitt ár',       '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ár',        '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'eitt ár',       '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ár',        '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'um fá sekund',  'prefix');\n        assert.equal(moment(0).from(30000), 'fá sekund síðani', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'fá sekund síðani',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'um fá sekund', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'um 5 dagar', 'in 5 days');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('fr-ca');\n\n    test('parse', function (assert) {\n        var i,\n            tests = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'dimanche, février 14 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'dim., 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2 02 février févr.'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14 14'],\n                ['d do dddd ddd dd',                   '0 0 dimanche dim. Di'],\n                ['DDD DDDo DDDD',                      '45 45 045'],\n                ['w wo ww',                            '8 8 08'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '2010-02-14'],\n                ['LL',                                 '14 février 2010'],\n                ['LLL',                                '14 février 2010 15:25'],\n                ['LLLL',                               'dimanche 14 février 2010 15:25'],\n                ['l',                                  '2010-2-14'],\n                ['ll',                                 '14 févr. 2010'],\n                ['lll',                                '14 févr. 2010 15:25'],\n                ['llll',                               'dim. 14 févr. 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1er', '1er');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n    });\n\n    test('format month', function (assert) {\n        var i,\n            expected = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_');\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var i,\n            expected = 'dimanche dim. Di_lundi lun. Lu_mardi mar. Ma_mercredi mer. Me_jeudi jeu. Je_vendredi ven. Ve_samedi sam. Sa'.split('_');\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'quelques secondes', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'une minute',   '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'une minute',   '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',  '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'une heure',    '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'une heure',    '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 heures',    '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 heures',    '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 heures',   '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un jour',      '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un jour',      '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 jours',     '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un jour',      '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 jours',     '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 jours',    '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mois',    '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mois',    '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mois',    '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mois',   '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mois',   '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mois',   '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mois',    '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mois',   '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un an',     '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ans',    '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un an',     '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ans',    '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'dans quelques secondes', 'prefix');\n        assert.equal(moment(0).from(30000), 'il y a quelques secondes', 'suffix');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'dans quelques secondes', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'dans 5 jours', 'in 5 days');\n    });\n\n    test('same day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Aujourd\\'hui à 02:00',    'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Aujourd\\'hui à 02:25',    'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Aujourd\\'hui à 03:00',    'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Demain à 02:00',         'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Aujourd\\'hui à 01:00',    'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Hier à 02:00',           'yesterday at the same time');\n    });\n\n    test('same next week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [à] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [à] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [à] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('same last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [dernier à] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [dernier à] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [dernier à] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('same all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n        assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n        assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n        assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n        assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday format', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1er', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1er', 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('fr');\n\n    test('parse', function (assert) {\n        var tests = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_'),\n            i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'dimanche, février 14 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'dim., 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2 02 février févr.'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14 14'],\n                ['d do dddd ddd dd',                   '0 0 dimanche dim. Di'],\n                ['DDD DDDo DDDD',                      '45 45 045'],\n                ['w wo ww',                            '6 6 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 février 2010'],\n                ['LLL',                                '14 février 2010 15:25'],\n                ['LLLL',                               'dimanche 14 février 2010 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 févr. 2010'],\n                ['lll',                                '14 févr. 2010 15:25'],\n                ['llll',                               'dim. 14 févr. 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1er', '1er');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'janvier janv._février févr._mars mars_avril avr._mai mai_juin juin_juillet juil._août août_septembre sept._octobre oct._novembre nov._décembre déc.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'dimanche dim. Di_lundi lun. Lu_mardi mar. Ma_mercredi mer. Me_jeudi jeu. Je_vendredi ven. Ve_samedi sam. Sa'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'quelques secondes', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'une minute',   '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'une minute',   '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutes',  '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutes', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'une heure',    '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'une heure',    '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 heures',    '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 heures',    '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 heures',   '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un jour',      '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un jour',      '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 jours',     '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un jour',      '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 jours',     '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 jours',    '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mois',    '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mois',    '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mois',    '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mois',   '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mois',   '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mois',   '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mois',    '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mois',   '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un an',     '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ans',    '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un an',     '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ans',    '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'dans quelques secondes', 'prefix');\n        assert.equal(moment(0).from(30000), 'il y a quelques secondes', 'suffix');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'dans quelques secondes', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'dans 5 jours', 'in 5 days');\n    });\n\n    test('same day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Aujourd\\'hui à 02:00',    'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Aujourd\\'hui à 02:25',    'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Aujourd\\'hui à 03:00',    'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Demain à 02:00',         'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Aujourd\\'hui à 01:00',    'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Hier à 02:00',           'yesterday at the same time');\n    });\n\n    test('same next week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [à] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [à] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [à] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('same last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [dernier à] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [dernier à] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [dernier à] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('same all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1er', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1er', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('fy');\n\n    test('parse', function (assert) {\n        var tests = 'jannewaris jan._febrewaris feb._maart mrt._april apr._maaie mai._juny jun._july jul._augustus aug._septimber sep._oktober okt._novimber nov._desimber des.'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, HH:mm:ss',       'snein, febrewaris 14de 2010, 15:25:50'],\n                ['ddd, HH',                            'si., 15'],\n                ['M Mo MM MMMM MMM',                   '2 2de 02 febrewaris feb.'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14de 14'],\n                ['d do dddd ddd dd',                   '0 0de snein si. Si'],\n                ['DDD DDDo DDDD',                      '45 45ste 045'],\n                ['w wo ww',                            '6 6de 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45ste day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14-02-2010'],\n                ['LL',                                 '14 febrewaris 2010'],\n                ['LLL',                                '14 febrewaris 2010 15:25'],\n                ['LLLL',                               'snein 14 febrewaris 2010 15:25'],\n                ['l',                                  '14-2-2010'],\n                ['ll',                                 '14 feb. 2010'],\n                ['lll',                                '14 feb. 2010 15:25'],\n                ['llll',                               'si. 14 feb. 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'jannewaris jan._febrewaris feb._maart mrt._april apr._maaie mai_juny jun._july jul._augustus aug._septimber sep._oktober okt._novimber nov._desimber des.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'snein si. Si_moandei mo. Mo_tiisdei ti. Ti_woansdei wo. Wo_tongersdei to. To_freed fr. Fr_sneon so. So'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'in pear sekonden', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ien minút',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ien minút',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuten',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuten',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ien oere',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ien oere',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 oeren',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 oeren',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 oeren',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ien dei',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ien dei',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagen',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ien dei',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagen',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagen',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ien moanne',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ien moanne',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ien moanne',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 moannen',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 moannen',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 moannen',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ien moanne',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 moannen',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ien jier',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jierren',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ien jier',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jierren',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'oer in pear sekonden',  'prefix');\n        assert.equal(moment(0).from(30000), 'in pear sekonden lyn', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'in pear sekonden lyn',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'oer in pear sekonden', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'oer 5 dagen', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'hjoed om 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'hjoed om 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'hjoed om 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'moarn om 02:00',    'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'hjoed om 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'juster om 02:00',   'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[ôfrûne] dddd [om] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[ôfrûne] dddd [om] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[ôfrûne] dddd [om] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('month abbreviation', function (assert) {\n        assert.equal(moment([2012, 5, 23]).format('D-MMM-YYYY'), '23-jun-2012', 'format month abbreviation surrounded by dashes should not include a dot');\n        assert.equal(moment([2012, 5, 23]).format('D MMM YYYY'), '23 jun. 2012', 'format month abbreviation not surrounded by dashes should include a dot');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ste', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1ste', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1ste', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),    '2 02 2de', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),    '2 02 2de', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('gl');\n\n    test('parse', function (assert) {\n        var tests = 'Xaneiro Xan._Febreiro Feb._Marzo Mar._Abril Abr._Maio Mai._Xuño Xuñ._Xullo Xul._Agosto Ago._Setembro Set._Outubro Out._Novembro Nov._Decembro Dec.'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'Domingo, Febreiro 14º 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'Dom., 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2º 02 Febreiro Feb.'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14º 14'],\n                ['d do dddd ddd dd',                   '0 0º Domingo Dom. Do'],\n                ['DDD DDDo DDDD',                      '45 45º 045'],\n                ['w wo ww',                            '7 7º 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 Febreiro 2010'],\n                ['LLL',                                '14 Febreiro 2010 15:25'],\n                ['LLLL',                               'Domingo 14 Febreiro 2010 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 Feb. 2010'],\n                ['lll',                                '14 Feb. 2010 15:25'],\n                ['llll',                               'Dom. 14 Feb. 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'Xaneiro Xan._Febreiro Feb._Marzo Mar._Abril Abr._Maio Mai._Xuño Xuñ._Xullo Xul._Agosto Ago._Setembro Set._Outubro Out._Novembro Nov._Decembro Dec.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'Domingo Dom. Do_Luns Lun. Lu_Martes Mar. Ma_Mércores Mér. Mé_Xoves Xov. Xo_Venres Ven. Ve_Sábado Sáb. Sá'.split('_'),\n        i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'uns segundos', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minuto',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minuto',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'unha hora',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'unha hora',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un día',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un día',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 días',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un día',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 días',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 días',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mes',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mes',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mes',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mes',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un ano',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anos',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un ano',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anos',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'nuns segundos',  'prefix');\n        assert.equal(moment(0).from(30000), 'hai uns segundos', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'hai uns segundos',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'nuns segundos', 'en unos segundos');\n        assert.equal(moment().add({d: 5}).fromNow(), 'en 5 días', 'en 5 días');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                         'hoxe ás 2:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),          'hoxe ás 2:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),           'hoxe ás 3:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),           'mañá ás 2:00',  'tomorrow at the same time');\n        assert.equal(moment(a).add({d: 1, h : -1}).calendar(),   'mañá á 1:00',   'tomorrow minus 1 hour');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),      'hoxe á 1:00',      'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),      'onte á 2:00',    'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[o] dddd [pasado ' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[o] dddd [pasado ' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[o] dddd [pasado ' + ((m.hours() !== 1) ? 'ás' : 'a') + '] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('regression tests', function (assert) {\n        var lastWeek = moment().subtract({d: 4}).hours(1);\n        assert.equal(lastWeek.calendar(), lastWeek.format('[o] dddd [pasado a] LT'), '1 o\\'clock bug');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1º', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1º', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2º', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2º', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3º', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('he');\n\n    test('parse', function (assert) {\n        var tests = 'ינואר ינו׳_פברואר פבר׳_מרץ מרץ_אפריל אפר׳_מאי מאי_יוני יוני_יולי יולי_אוגוסט אוג׳_ספטמבר ספט׳_אוקטובר אוק׳_נובמבר נוב׳_דצמבר דצמ׳'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'ראשון, פברואר 14 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'א׳, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2 02 פברואר פבר׳'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14 14'],\n                ['d do dddd ddd dd',                   '0 0 ראשון א׳ א'],\n                ['DDD DDDo DDDD',                      '45 45 045'],\n                ['w wo ww',                            '8 8 08'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 בפברואר 2010'],\n                ['LLL',                                '14 בפברואר 2010 15:25'],\n                ['LLLL',                               'ראשון, 14 בפברואר 2010 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 פבר׳ 2010'],\n                ['lll',                                '14 פבר׳ 2010 15:25'],\n                ['llll',                               'א׳, 14 פבר׳ 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format month', function (assert) {\n        var expected = 'ינואר ינו׳_פברואר פבר׳_מרץ מרץ_אפריל אפר׳_מאי מאי_יוני יוני_יולי יולי_אוגוסט אוג׳_ספטמבר ספט׳_אוקטובר אוק׳_נובמבר נוב׳_דצמבר דצמ׳'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'ראשון א׳ א|שני ב׳ ב|שלישי ג׳ ג|רביעי ד׳ ד|חמישי ה׳ ה|שישי ו׳ ו|שבת ש׳ ש'.split('|'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'מספר שניות', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'דקה',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'דקה',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 דקות',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 דקות',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'שעה',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'שעה',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  'שעתיים',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 שעות',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 שעות',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'יום',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'יום',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  'יומיים',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'יום',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ימים',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ימים',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'חודש',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'חודש',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'חודש',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  'חודשיים',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  'חודשיים',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 חודשים',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'חודש',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 חודשים',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'שנה',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), 'שנתיים',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 3699}), true), '10 שנים',        '345 days = 10 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 7340}), true), '20 שנה',       '548 days = 20 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'שנה',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 שנים',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'בעוד מספר שניות',  'prefix');\n        assert.equal(moment(0).from(30000), 'לפני מספר שניות', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'לפני מספר שניות',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'בעוד מספר שניות', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'בעוד 5 ימים', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'היום ב־02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'היום ב־02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'היום ב־03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'מחר ב־02:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'היום ב־01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'אתמול ב־02:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [בשעה] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [בשעה] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [בשעה] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[ביום] dddd [האחרון בשעה] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[ביום] dddd [האחרון בשעה] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[ביום] dddd [האחרון בשעה] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n        assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n        assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n        assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n        assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday format', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('hi');\n\n    test('parse', function (assert) {\n        var tests = 'जनवरी जन._फ़रवरी फ़र._मार्च मार्च_अप्रैल अप्रै._मई मई_जून जून_जुलाई जुल._अगस्त अग._सितम्बर सित._अक्टूबर अक्टू._नवम्बर नव._दिसम्बर दिस.'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, a h:mm:ss बजे',  'रविवार, १४ फ़रवरी २०१०, दोपहर ३:२५:५० बजे'],\n                ['ddd, a h बजे',                       'रवि, दोपहर ३ बजे'],\n                ['M Mo MM MMMM MMM',                   '२ २ ०२ फ़रवरी फ़र.'],\n                ['YYYY YY',                            '२०१० १०'],\n                ['D Do DD',                            '१४ १४ १४'],\n                ['d do dddd ddd dd',                   '० ० रविवार रवि र'],\n                ['DDD DDDo DDDD',                      '४५ ४५ ०४५'],\n                ['w wo ww',                            '८ ८ ०८'],\n                ['h hh',                               '३ ०३'],\n                ['H HH',                               '१५ १५'],\n                ['m mm',                               '२५ २५'],\n                ['s ss',                               '५० ५०'],\n                ['a A',                                'दोपहर दोपहर'],\n                ['LTS',                                'दोपहर ३:२५:५० बजे'],\n                ['L',                                  '१४/०२/२०१०'],\n                ['LL',                                 '१४ फ़रवरी २०१०'],\n                ['LLL',                                '१४ फ़रवरी २०१०, दोपहर ३:२५ बजे'],\n                ['LLLL',                               'रविवार, १४ फ़रवरी २०१०, दोपहर ३:२५ बजे'],\n                ['l',                                  '१४/२/२०१०'],\n                ['ll',                                 '१४ फ़र. २०१०'],\n                ['lll',                                '१४ फ़र. २०१०, दोपहर ३:२५ बजे'],\n                ['llll',                               'रवि, १४ फ़र. २०१०, दोपहर ३:२५ बजे']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '१', '१');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '२', '२');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '३', '३');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '४', '४');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '५', '५');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '६', '६');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '७', '७');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '८', '८');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '९', '९');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '१०', '१०');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '११', '११');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '१२', '१२');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '१३', '१३');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '१४', '१४');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '१५', '१५');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '१६', '१६');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '१७', '१७');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '१८', '१८');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '१९', '१९');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '२०', '२०');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '२१', '२१');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '२२', '२२');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '२३', '२३');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '२४', '२४');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '२५', '२५');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '२६', '२६');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '२७', '२७');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '२८', '२८');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '२९', '२९');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '३०', '३०');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '३१', '३१');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'जनवरी जन._फ़रवरी फ़र._मार्च मार्च_अप्रैल अप्रै._मई मई_जून जून_जुलाई जुल._अगस्त अग._सितम्बर सित._अक्टूबर अक्टू._नवम्बर नव._दिसम्बर दिस.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'रविवार रवि र_सोमवार सोम सो_मंगलवार मंगल मं_बुधवार बुध बु_गुरूवार गुरू गु_शुक्रवार शुक्र शु_शनिवार शनि श'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'कुछ ही क्षण', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'एक मिनट',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'एक मिनट',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '२ मिनट',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '४४ मिनट',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'एक घंटा',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'एक घंटा',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '२ घंटे',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '५ घंटे',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '२१ घंटे',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'एक दिन',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'एक दिन',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '२ दिन',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'एक दिन',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '५ दिन',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '२५ दिन',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'एक महीने',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'एक महीने',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'एक महीने',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '२ महीने',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '२ महीने',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '३ महीने',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'एक महीने',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '५ महीने',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'एक वर्ष',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '२ वर्ष',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'एक वर्ष',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '५ वर्ष',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'कुछ ही क्षण में',  'prefix');\n        assert.equal(moment(0).from(30000), 'कुछ ही क्षण पहले', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'कुछ ही क्षण पहले',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'कुछ ही क्षण में', 'कुछ ही क्षण में');\n        assert.equal(moment().add({d: 5}).fromNow(), '५ दिन में', '५ दिन में');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'आज रात २:०० बजे',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'आज रात २:२५ बजे',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 3}).calendar(),       'आज सुबह ५:०० बजे',     'Now plus 3 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'कल रात २:०० बजे',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'आज रात १:०० बजे',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'कल रात २:०० बजे', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[पिछले] dddd[,] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[पिछले] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[पिछले] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('meridiem invariant', function (assert) {\n        assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'रात', 'before dawn');\n        assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'सुबह', 'morning');\n        assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'दोपहर', 'during day');\n        assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'शाम', 'evening');\n        assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'शाम', 'late evening');\n        assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'रात', 'night');\n\n        assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'रात', 'before dawn');\n        assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'सुबह', 'morning');\n        assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'दोपहर', ' during day');\n        assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'शाम', 'evening');\n        assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'शाम', 'late evening');\n        assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'रात', 'night');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n        assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n        assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n        assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n        assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '१ ०१ १', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).format('w ww wo'), '१ ०१ १', 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'), '२ ०२ २', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).format('w ww wo'), '२ ०२ २', 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'), '३ ०३ ३', 'Jan 15 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('meridiem', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('hr');\n\n    test('parse', function (assert) {\n        var tests = 'sječanj sje._veljača vel._ožujak ožu._travanj tra._svibanj svi._lipanj lip._srpanj srp._kolovoz kol._rujan ruj._listopad lis._studeni stu._prosinac pro.'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedjelja, 14. veljača 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'ned., 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2. 02 veljača vel.'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14. 14'],\n                ['d do dddd ddd dd',                   '0 0. nedjelja ned. ne'],\n                ['DDD DDDo DDDD',                      '45 45. 045'],\n                ['w wo ww',                            '7 7. 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14. 02. 2010'],\n                ['LL',                                 '14. veljača 2010'],\n                ['LLL',                                '14. veljača 2010 15:25'],\n                ['LLLL',                               'nedjelja, 14. veljača 2010 15:25'],\n                ['l',                                  '14. 2. 2010'],\n                ['ll',                                 '14. vel. 2010'],\n                ['lll',                                '14. vel. 2010 15:25'],\n                ['llll',                               'ned., 14. vel. 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'sječanj sje._veljača vel._ožujak ožu._travanj tra._svibanj svi._lipanj lip._srpanj srp._kolovoz kol._rujan ruj._listopad lis._studeni stu._prosinac pro.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'nedjelja ned. ne_ponedjeljak pon. po_utorak uto. ut_srijeda sri. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'par sekundi', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'jedna minuta',   '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'jedna minuta',   '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',     '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'jedan sat',      '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'jedan sat',      '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 sata',        '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 sati',         '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 sati',        '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dan',       '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dan',       '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dana',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dan',       '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dana',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dana',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mjesec',     '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mjesec',     '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mjesec',     '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mjeseca',     '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mjeseca',     '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mjeseca',     '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mjesec',     '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mjeseci',    '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'godinu',     '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 godine',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'godinu',     '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 godina',        '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'za par sekundi',  'prefix');\n        assert.equal(moment(0).from(30000), 'prije par sekundi', 'prefix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'prije par sekundi',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'za par sekundi', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dana', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'danas u 2:00',  'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'danas u 2:25',  'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'danas u 3:00',  'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'sutra u 2:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'danas u 1:00',  'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'jučer u 2:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n\n        function makeFormat(d) {\n            switch (d.day()) {\n            case 0:\n                return '[u] [nedjelju] [u] LT';\n            case 3:\n                return '[u] [srijedu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n            }\n        }\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        function makeFormat(d) {\n            switch (d.day()) {\n            case 0:\n            case 3:\n                return '[prošlu] dddd [u] LT';\n            case 6:\n                return '[prošle] [subote] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[prošli] dddd [u] LT';\n            }\n        }\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('hu');\n\n    test('parse', function (assert) {\n        var tests = 'január jan_február feb_március márc_április ápr_május máj_június jún_július júl_augusztus aug_szeptember szept_október okt_november nov_december dec'.split('_'),\n            i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, HH:mm:ss',      'vasárnap, február 14. 2010, 15:25:50'],\n                ['ddd, HH',                            'vas, 15'],\n                ['M Mo MM MMMM MMM',                   '2 2. 02 február feb'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14. 14'],\n                ['d do dddd ddd dd',                   '0 0. vasárnap vas v'],\n                ['DDD DDDo DDDD',                      '45 45. 045'],\n                ['w wo ww',                            '7 7. 07'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['[az év] DDDo [napja]',               'az év 45. napja'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '2010.02.14.'],\n                ['LL',                                 '2010. február 14.'],\n                ['LLL',                                '2010. február 14., 15:25'],\n                ['LLLL',                               '2010. február 14., vasárnap 15:25'],\n                ['l',                                  '2010.2.14.'],\n                ['ll',                                 '2010. feb 14.'],\n                ['lll',                                '2010. feb 14., 15:25'],\n                ['llll',                               '2010. feb 14., vas 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('meridiem', function (assert) {\n        assert.equal(moment([2011, 2, 23,  0,  0]).format('a'), 'de', 'am');\n        assert.equal(moment([2011, 2, 23, 11, 59]).format('a'), 'de', 'am');\n        assert.equal(moment([2011, 2, 23, 12,  0]).format('a'), 'du', 'pm');\n        assert.equal(moment([2011, 2, 23, 23, 59]).format('a'), 'du', 'pm');\n\n        assert.equal(moment([2011, 2, 23,  0,  0]).format('A'), 'DE', 'AM');\n        assert.equal(moment([2011, 2, 23, 11, 59]).format('A'), 'DE', 'AM');\n        assert.equal(moment([2011, 2, 23, 12,  0]).format('A'), 'DU', 'PM');\n        assert.equal(moment([2011, 2, 23, 23, 59]).format('A'), 'DU', 'PM');\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'január jan_február feb_március márc_április ápr_május máj_június jún_július júl_augusztus aug_szeptember szept_október okt_november nov_december dec'.split('_'),\n            i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'vasárnap vas_hétfő hét_kedd kedd_szerda sze_csütörtök csüt_péntek pén_szombat szo'.split('_'),\n            i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'néhány másodperc', '44 másodperc = néhány másodperc');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'egy perc',         '45 másodperc = egy perc');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'egy perc',         '89 másodperc = egy perc');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 perc',           '90 másodperc = 2 perc');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 perc',          '44 perc = 44 perc');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'egy óra',          '45 perc = egy óra');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'egy óra',          '89 perc = egy óra');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 óra',            '90 perc = 2 óra');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 óra',            '5 óra = 5 óra');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 óra',           '21 óra = 21 óra');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'egy nap',          '22 óra = egy nap');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'egy nap',          '35 óra = egy nap');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 nap',            '36 óra = 2 nap');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'egy nap',          '1 nap = egy nap');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 nap',            '5 nap = 5 nap');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 nap',           '25 nap = 25 nap');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'egy hónap',        '26 nap = egy hónap');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'egy hónap',        '30 nap = egy hónap');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'egy hónap',        '45 nap = egy hónap');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 hónap',          '46 nap = 2 hónap');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 hónap',          '75 nap = 2 hónap');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 hónap',          '76 nap = 3 hónap');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'egy hónap',        '1 hónap = egy hónap');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 hónap',          '5 hónap = 5 hónap');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'egy év',           '345 nap = egy év');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 év',             '548 nap = 2 év');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'egy év',           '1 év = egy év');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 év',             '5 év = 5 év');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'néhány másodperc múlva',  'prefix');\n        assert.equal(moment(0).from(30000), 'néhány másodperce', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'néhány másodperce',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'néhány másodperc múlva', 'néhány másodperc múlva');\n        assert.equal(moment().add({d: 5}).fromNow(), '5 nap múlva', '5 nap múlva');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'ma 2:00-kor',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'ma 2:25-kor',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'ma 3:00-kor',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'holnap 2:00-kor', 'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'ma 1:00-kor',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'tegnap 2:00-kor', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m, days = 'vasárnap_hétfőn_kedden_szerdán_csütörtökön_pénteken_szombaton'.split('_');\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('[' + days[m.day()] + '] LT[-kor]'),  'today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[' + days[m.day()] + '] LT[-kor]'),  'today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[' + days[m.day()] + '] LT[-kor]'),  'today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m, days = 'vasárnap_hétfőn_kedden_szerdán_csütörtökön_pénteken_szombaton'.split('_');\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[múlt ' + days[m.day()] + '] LT[-kor]'),  'today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[múlt ' + days[m.day()] + '] LT[-kor]'),  'today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[múlt ' + days[m.day()] + '] LT[-kor]'),  'today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  'egy héte');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'egy hét múlva');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 hete');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '2 hét múlva');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('hy-am');\n\n    test('parse', function (assert) {\n        var tests = 'հունվար հնվ_փետրվար փտր_մարտ մրտ_ապրիլ ապր_մայիս մյս_հունիս հնս_հուլիս հլս_օգոստոս օգս_սեպտեմբեր սպտ_հոկտեմբեր հկտ_նոյեմբեր նմբ_դեկտեմբեր դկտ'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('parse exceptional case', function (assert) {\n        assert.equal(moment('11 մայիսի 1989', ['DD MMMM YYYY']).format('DD-MM-YYYY'), '11-05-1989');\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, HH:mm:ss',       'կիրակի, 14 փետրվարի 2010, 15:25:50'],\n                ['ddd, h A',                           'կրկ, 3 ցերեկվա'],\n                ['M Mo MM MMMM MMM',                   '2 2 02 փետրվար փտր'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14 14'],\n                ['d do dddd ddd dd',                   '0 0 կիրակի կրկ կրկ'],\n                ['DDD DDDo DDDD',                      '45 45-րդ 045'],\n                ['w wo ww',                            '7 7-րդ 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'ցերեկվա ցերեկվա'],\n                ['[տարվա] DDDo [օրը]',                 'տարվա 45-րդ օրը'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14.02.2010'],\n                ['LL',                                 '14 փետրվարի 2010 թ.'],\n                ['LLL',                                '14 փետրվարի 2010 թ., 15:25'],\n                ['LLLL',                               'կիրակի, 14 փետրվարի 2010 թ., 15:25'],\n                ['l',                                  '14.2.2010'],\n                ['ll',                                 '14 փտր 2010 թ.'],\n                ['lll',                                '14 փտր 2010 թ., 15:25'],\n                ['llll',                               'կրկ, 14 փտր 2010 թ., 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format meridiem', function (assert) {\n        assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'գիշերվա', 'night');\n        assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'գիշերվա', 'night');\n        assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'առավոտվա', 'morning');\n        assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'առավոտվա', 'morning');\n        assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'ցերեկվա', 'afternoon');\n        assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'ցերեկվա', 'afternoon');\n        assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'երեկոյան', 'evening');\n        assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'երեկոյան', 'evening');\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ին', '1-ին');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-րդ', '2-րդ');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-րդ', '3-րդ');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-րդ', '4-րդ');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-րդ', '5-րդ');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-րդ', '6-րդ');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-րդ', '7-րդ');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-րդ', '8-րդ');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-րդ', '9-րդ');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-րդ', '10-րդ');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-րդ', '11-րդ');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-րդ', '12-րդ');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-րդ', '13-րդ');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-րդ', '14-րդ');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-րդ', '15-րդ');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-րդ', '16-րդ');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-րդ', '17-րդ');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-րդ', '18-րդ');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-րդ', '19-րդ');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-րդ', '20-րդ');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-րդ', '21-րդ');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-րդ', '22-րդ');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-րդ', '23-րդ');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-րդ', '24-րդ');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-րդ', '25-րդ');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-րդ', '26-րդ');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-րդ', '27-րդ');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-րդ', '28-րդ');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-րդ', '29-րդ');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-րդ', '30-րդ');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-րդ', '31-րդ');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'հունվար հնվ_փետրվար փտր_մարտ մրտ_ապրիլ ապր_մայիս մյս_հունիս հնս_հուլիս հլս_օգոստոս օգս_սեպտեմբեր սպտ_հոկտեմբեր հկտ_նոյեմբեր նմբ_դեկտեմբեր դկտ'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format month case', function (assert) {\n        var months = {\n            'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),\n            'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_')\n        }, i;\n        for (i = 0; i < 12; i++) {\n            assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n            assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n        }\n    });\n\n    test('format month short case', function (assert) {\n        var monthsShort = {\n            'nominative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),\n            'accusative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_')\n        }, i;\n        for (i = 0; i < 12; i++) {\n            assert.equal(moment([2011, i, 1]).format('D MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n            assert.equal(moment([2011, i, 1]).format('MMM'), monthsShort.nominative[i], '1 ' + monthsShort.nominative[i]);\n        }\n    });\n\n    test('format month case with escaped symbols', function (assert) {\n        var months = {\n            'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),\n            'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_')\n        }, i;\n        for (i = 0; i < 12; i++) {\n            assert.equal(moment([2013, i, 1]).format('D[] MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n            assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMMM[</b>]'), '<i>1</i> <b>' + months.accusative[i] + '</b>', '1 <b>' + months.accusative[i] + '</b>');\n            assert.equal(moment([2013, i, 1]).format('D[-ին օրը] MMMM'), '1-ին օրը ' + months.accusative[i], '1-ին օրը ' + months.accusative[i]);\n            assert.equal(moment([2013, i, 1]).format('D, MMMM'), '1, ' + months.nominative[i], '1, ' + months.nominative[i]);\n        }\n    });\n\n    test('format month short case with escaped symbols', function (assert) {\n        var monthsShort = {\n            'nominative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_'),\n            'accusative': 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_')\n        }, i;\n        for (i = 0; i < 12; i++) {\n            assert.equal(moment([2013, i, 1]).format('D[] MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n            assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMM[</b>]'), '<i>1</i> <b>' + monthsShort.accusative[i] + '</b>', '1 <b>' + monthsShort.accusative[i] + '</b>');\n            assert.equal(moment([2013, i, 1]).format('D[-ին օրը] MMM'), '1-ին օրը ' + monthsShort.accusative[i], '1-ին օրը ' + monthsShort.accusative[i]);\n            assert.equal(moment([2013, i, 1]).format('D, MMM'), '1, ' + monthsShort.nominative[i], '1, ' + monthsShort.nominative[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'կիրակի կրկ կրկ_երկուշաբթի երկ երկ_երեքշաբթի երք երք_չորեքշաբթի չրք չրք_հինգշաբթի հնգ հնգ_ուրբաթ ուրբ ուրբ_շաբաթ շբթ շբթ'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'մի քանի վայրկյան',    '44 seconds = seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'րոպե',   '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'րոպե',   '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 րոպե',  '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 րոպե', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ժամ',    '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ժամ',    '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ժամ',    '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ժամ',    '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ժամ',   '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'օր',      '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'օր',      '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 օր',     '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'օր',      '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 օր',     '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 օր',     '11 days = 11 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 օր',     '21 days = 21 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 օր',    '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ամիս',    '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ամիս',    '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ամիս',    '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ամիս',   '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ամիս',   '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ամիս',   '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ամիս',    '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ամիս',   '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'տարի',     '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 տարի',    '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'տարի',     '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 տարի',    '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'մի քանի վայրկյան հետո', 'prefix');\n        assert.equal(moment(0).from(30000), 'մի քանի վայրկյան առաջ', 'suffix');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'մի քանի վայրկյան հետո', 'in seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), '5 օր հետո', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'այսօր 02:00',   'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'այսօր 02:25',   'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'այսօր 03:00',   'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'վաղը 02:00',   'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'այսօր 01:00',   'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'երեկ 02:00',   'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        function makeFormat(d) {\n            return 'dddd [օրը ժամը] LT';\n        }\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        function makeFormat(d) {\n            return '[անցած] dddd [օրը ժամը] LT';\n        }\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ին', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ին', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-րդ', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-րդ', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-րդ', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('id');\n\n    test('parse', function (assert) {\n        var tests = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'Minggu, Februari 14 2010, 3:25:50 sore'],\n                ['ddd, hA',                            'Min, 3sore'],\n                ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14 14'],\n                ['d do dddd ddd dd',                   '0 0 Minggu Min Mg'],\n                ['DDD DDDo DDDD',                      '45 45 045'],\n                ['w wo ww',                            '7 7 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'sore sore'],\n                ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n                ['LTS',                                '15.25.50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 Februari 2010'],\n                ['LLL',                                '14 Februari 2010 pukul 15.25'],\n                ['LLLL',                               'Minggu, 14 Februari 2010 pukul 15.25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 Feb 2010'],\n                ['lll',                                '14 Feb 2010 pukul 15.25'],\n                ['llll',                               'Min, 14 Feb 2010 pukul 15.25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format month', function (assert) {\n        var expected = 'Januari Jan_Februari Feb_Maret Mar_April Apr_Mei Mei_Juni Jun_Juli Jul_Agustus Ags_September Sep_Oktober Okt_November Nov_Desember Des'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'Minggu Min Mg_Senin Sen Sn_Selasa Sel Sl_Rabu Rab Rb_Kamis Kam Km_Jumat Jum Jm_Sabtu Sab Sb'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'beberapa detik', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'semenit',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'semenit',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 menit',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 menit',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'sejam',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'sejam',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 jam',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 jam',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 jam',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'sehari',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'sehari',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 hari',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'sehari',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 hari',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 hari',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'sebulan',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'sebulan',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'sebulan',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 bulan',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 bulan',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 bulan',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'sebulan',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 bulan',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'setahun',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 tahun',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'setahun',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 tahun',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'dalam beberapa detik',  'prefix');\n        assert.equal(moment(0).from(30000), 'beberapa detik yang lalu', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'beberapa detik yang lalu',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'dalam beberapa detik', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'dalam 5 hari', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Hari ini pukul 02.00', 'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Hari ini pukul 02.25', 'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Hari ini pukul 03.00', 'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Besok pukul 02.00',    'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hari ini pukul 01.00', 'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kemarin pukul 02.00',  'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [lalu pukul] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [lalu pukul] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [lalu pukul] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('is');\n\n    test('parse', function (assert) {\n        var tests = 'janúar jan_febrúar feb_mars mar_apríl apr_maí maí_júní jún_júlí júl_ágúst ágú_september sep_október okt_nóvember nóv_desember des'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, h:mm:ss a',      'sunnudagur, 14. febrúar 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'sun, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2. 02 febrúar feb'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14. 14'],\n                ['d do dddd ddd dd',                   '0 0. sunnudagur sun Su'],\n                ['DDD DDDo DDDD',                      '45 45. 045'],\n                ['w wo ww',                            '6 6. 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14. febrúar 2010'],\n                ['LLL',                                '14. febrúar 2010 kl. 15:25'],\n                ['LLLL',                               'sunnudagur, 14. febrúar 2010 kl. 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14. feb 2010'],\n                ['lll',                                '14. feb 2010 kl. 15:25'],\n                ['llll',                               'sun, 14. feb 2010 kl. 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'janúar jan_febrúar feb_mars mar_apríl apr_maí maí_júní jún_júlí júl_ágúst ágú_september sep_október okt_nóvember nóv_desember des'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'sunnudagur sun Su_mánudagur mán Má_þriðjudagur þri Þr_miðvikudagur mið Mi_fimmtudagur fim Fi_föstudagur fös Fö_laugardagur lau La'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nokkrar sekúndur', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'mínúta',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'mínúta',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 mínútur',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 mínútur',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 21}), true),  '21 mínúta',    '21 minutes = 21 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'klukkustund',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'klukkustund',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 klukkustundir',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 klukkustundir',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 klukkustund',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dagur',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dagur',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dagur',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 dagar',       '11 days = 11 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 dagur',       '21 days = 21 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mánuður',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mánuður',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mánuður',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mánuðir',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mánuðir',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mánuðir',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mánuður',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mánuðir',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ár',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ár',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ár',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ár',       '5 years = 5 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 21}), true),  '21 ár',       '21 years = 21 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'eftir nokkrar sekúndur',  'prefix');\n        assert.equal(moment(0).from(30000), 'fyrir nokkrum sekúndum síðan', 'suffix');\n        assert.equal(moment().subtract({m: 1}).fromNow(), 'fyrir mínútu síðan', 'a minute ago');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'fyrir nokkrum sekúndum síðan',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'eftir nokkrar sekúndur', 'in a few seconds');\n        assert.equal(moment().add({m: 1}).fromNow(), 'eftir mínútu', 'in a minute');\n        assert.equal(moment().add({d: 5}).fromNow(), 'eftir 5 daga', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'í dag kl. 2:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'í dag kl. 2:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'í dag kl. 3:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'á morgun kl. 2:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'í dag kl. 1:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'í gær kl. 2:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[síðasta] dddd [kl.] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[síðasta] dddd [kl.] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[síðasta] dddd [kl.] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1.', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1.', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2.', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2.', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('it');\n\n    test('parse', function (assert) {\n        var tests = 'gennaio gen_febbraio feb_marzo mar_aprile apr_maggio mag_giugno giu_luglio lug_agosto ago_settembre set_ottobre ott_novembre nov_dicembre dic'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'Domenica, febbraio 14º 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'Dom, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2º 02 febbraio feb'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14º 14'],\n                ['d do dddd ddd dd',                   '0 0º Domenica Dom D'],\n                ['DDD DDDo DDDD',                      '45 45º 045'],\n                ['w wo ww',                            '6 6º 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 febbraio 2010'],\n                ['LLL',                                '14 febbraio 2010 15:25'],\n                ['LLLL',                               'Domenica, 14 febbraio 2010 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 feb 2010'],\n                ['lll',                                '14 feb 2010 15:25'],\n                ['llll',                               'Dom, 14 feb 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'gennaio gen_febbraio feb_marzo mar_aprile apr_maggio mag_giugno giu_luglio lug_agosto ago_settembre set_ottobre ott_novembre nov_dicembre dic'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'Domenica Dom D_Lunedì Lun L_Martedì Mar Ma_Mercoledì Mer Me_Giovedì Gio G_Venerdì Ven V_Sabato Sab S'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'alcuni secondi', '44 seconds = seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minuto',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minuto',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuti',       '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuti',      '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'un\\'ora',        '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'un\\'ora',        '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ore',          '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ore',          '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ore',         '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'un giorno',      '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'un giorno',      '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 giorni',       '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'un giorno',      '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 giorni',       '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 giorni',      '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'un mese',        '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'un mese',        '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'un mese',        '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mesi',         '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mesi',         '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesi',         '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'un mese',        '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesi',         '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un anno',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anni',         '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un anno',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anni',         '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'in alcuni secondi', 'prefix');\n        assert.equal(moment(0).from(30000), 'alcuni secondi fa', 'suffix');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'in alcuni secondi', 'in seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'tra 5 giorni', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                   'Oggi alle 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Oggi alle 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Oggi alle 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Domani alle 02:00',   'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Oggi alle 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ieri alle 02:00',     'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [alle] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [alle] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [alle] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m, weekday, datestring;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            weekday = parseInt(m.format('d'), 10);\n            datestring = (weekday === 0) ? '[la scorsa] dddd [alle] LT' : '[lo scorso] dddd [alle] LT';\n            assert.equal(m.calendar(), m.format(datestring), 'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(), m.format(datestring), 'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(), m.format(datestring), 'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1º', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1º', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2º', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2º', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('ja');\n\n    test('parse', function (assert) {\n        var tests = '1月 1月_2月 2月_3月 3月_4月 4月_5月 5月_6月 6月_7月 7月_8月 8月_9月 9月_10月 10月_11月 11月_12月 12月'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, a h:mm:ss',      '日曜日, 2月 14 2010, 午後 3:25:50'],\n                ['ddd, Ah',                            '日, 午後3'],\n                ['M Mo MM MMMM MMM',                   '2 2 02 2月 2月'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14 14'],\n                ['d do dddd ddd dd',                   '0 0 日曜日 日 日'],\n                ['DDD DDDo DDDD',                      '45 45 045'],\n                ['w wo ww',                            '8 8 08'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                '午後 午後'],\n                ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n                ['LTS',                                '午後3時25分50秒'],\n                ['L',                                  '2010/02/14'],\n                ['LL',                                 '2010年2月14日'],\n                ['LLL',                                '2010年2月14日午後3時25分'],\n                ['LLLL',                               '2010年2月14日午後3時25分 日曜日'],\n                ['l',                                  '2010/2/14'],\n                ['ll',                                 '2010年2月14日'],\n                ['lll',                                '2010年2月14日午後3時25分'],\n                ['llll',                               '2010年2月14日午後3時25分 日']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format month', function (assert) {\n        var expected = '1月 1月_2月 2月_3月 3月_4月 4月_5月 5月_6月 6月_7月 7月_8月 8月_9月 9月_10月 10月_11月 11月_12月 12月'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = '日曜日 日 日_月曜日 月 月_火曜日 火 火_水曜日 水 水_木曜日 木 木_金曜日 金 金_土曜日 土 土'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '数秒',   '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1分', '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1分', '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2分',  '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44分', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1時間', '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1時間', '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2時間',  '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5時間',  '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21時間', '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1日',   '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1日',   '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2日',   '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1日',   '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5日',   '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25日',  '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1ヶ月', '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1ヶ月', '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1ヶ月', '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2ヶ月',  '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2ヶ月',  '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3ヶ月',  '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1ヶ月', '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5ヶ月',  '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1年',   '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2年',   '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1年',   '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5年',   '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), '数秒後',  'prefix');\n        assert.equal(moment(0).from(30000), '数秒前', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), '数秒前',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), '数秒後', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), '5日後', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     '今日 午前2時0分',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      '今日 午前2時25分',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       '今日 午前3時0分',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       '明日 午前2時0分',     'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  '今日 午前1時0分',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  '昨日 午前2時0分',     'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('[来週]dddd LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[来週]dddd LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[来週]dddd LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[前週]dddd LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[前週]dddd LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[前週]dddd LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n        assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n        assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n        assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n        assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday format', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('ka');\n\n    test('parse', function (assert) {\n        var i,\n            tests = 'იანვარი იან_თებერვალი თებ_მარტი მარ_აპრილი აპრ_მაისი მაი_ივნისი ივნ_ივლისი ივლ_აგვისტო აგვ_სექტემბერი სექ_ოქტომბერი ოქტ_ნოემბერი ნოე_დეკემბერი დეკ'.split('_');\n\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' უნდა იყოს თვე ' + (i + 1));\n        }\n\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a', 'კვირა, თებერვალი მე-14 2010, 3:25:50 pm'],\n                ['ddd, hA',                       'კვი, 3PM'],\n                ['M Mo MM MMMM MMM',              '2 მე-2 02 თებერვალი თებ'],\n                ['YYYY YY',                       '2010 10'],\n                ['D Do DD',                       '14 მე-14 14'],\n                ['d do dddd ddd dd',              '0 0 კვირა კვი კვ'],\n                ['DDD DDDo DDDD',                 '45 45-ე 045'],\n                ['w wo ww',                       '7 მე-7 07'],\n                ['h hh',                          '3 03'],\n                ['H HH',                          '15 15'],\n                ['m mm',                          '25 25'],\n                ['s ss',                          '50 50'],\n                ['a A',                           'pm PM'],\n                ['წლის DDDo დღე',                 'წლის 45-ე დღე'],\n                ['LTS',                           '3:25:50 PM'],\n                ['L',                             '14/02/2010'],\n                ['LL',                            '14 თებერვალი 2010'],\n                ['LLL',                           '14 თებერვალი 2010 3:25 PM'],\n                ['LLLL',                          'კვირა, 14 თებერვალი 2010 3:25 PM'],\n                ['l',                             '14/2/2010'],\n                ['ll',                            '14 თებ 2010'],\n                ['lll',                           '14 თებ 2010 3:25 PM'],\n                ['llll',                          'კვი, 14 თებ 2010 3:25 PM']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'),  '1-ლი',  '1-ლი');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'),  'მე-2',  'მე-2');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'),  'მე-3',  'მე-3');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'),  'მე-4',  'მე-4');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'),  'მე-5',  'მე-5');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'),  'მე-6',  'მე-6');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'),  'მე-7',  'მე-7');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'),  'მე-8',  'მე-8');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'),  'მე-9',  'მე-9');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), 'მე-10', 'მე-10');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), 'მე-11', 'მე-11');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), 'მე-12', 'მე-12');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), 'მე-13', 'მე-13');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), 'მე-14', 'მე-14');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), 'მე-15', 'მე-15');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), 'მე-16', 'მე-16');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), 'მე-17', 'მე-17');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), 'მე-18', 'მე-18');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), 'მე-19', 'მე-19');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), 'მე-20', 'მე-20');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ე', '21-ე');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ე', '22-ე');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ე', '23-ე');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ე', '24-ე');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ე', '25-ე');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ე', '26-ე');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ე', '27-ე');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ე', '28-ე');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ე', '29-ე');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ე', '30-ე');\n\n        assert.equal(moment('2011 40', 'YYYY DDD').format('DDDo'),  'მე-40',  'მე-40');\n        assert.equal(moment('2011 50', 'YYYY DDD').format('DDDo'),  '50-ე',   '50-ე');\n        assert.equal(moment('2011 60', 'YYYY DDD').format('DDDo'),  'მე-60',  'მე-60');\n        assert.equal(moment('2011 100', 'YYYY DDD').format('DDDo'), 'მე-100', 'მე-100');\n        assert.equal(moment('2011 101', 'YYYY DDD').format('DDDo'), '101-ე',  '101-ე');\n    });\n\n    test('format month', function (assert) {\n        var i,\n            expected = 'იანვარი იან_თებერვალი თებ_მარტი მარ_აპრილი აპრ_მაისი მაი_ივნისი ივნ_ივლისი ივლ_აგვისტო აგვ_სექტემბერი სექ_ოქტომბერი ოქტ_ნოემბერი ნოე_დეკემბერი დეკ'.split('_');\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var i,\n            expected = 'კვირა კვი კვ_ორშაბათი ორშ ორ_სამშაბათი სამ სა_ოთხშაბათი ოთხ ოთ_ხუთშაბათი ხუთ ხუ_პარასკევი პარ პა_შაბათი შაბ შა'.split('_');\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}),  true), 'რამდენიმე წამი', '44 წამი  = რამდენიმე წამი');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}),  true), 'წუთი',           '45 წამი  = წუთი');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}),  true), 'წუთი',           '89 წამი  = წუთი');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}),  true), '2 წუთი',         '90 წამი  = 2 წუთი');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}),  true), '44 წუთი',        '44 წამი  = 44 წუთი');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}),  true), 'საათი',          '45 წამი  = საათი');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}),  true), 'საათი',          '89 წამი  = საათი');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}),  true), '2 საათი',        '90 წამი  = 2 საათი');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}),   true), '5 საათი',        '5 საათი  = 5 საათი');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}),  true), '21 საათი',       '21 საათი = 21 საათი');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}),  true), 'დღე',            '22 საათი = დღე');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}),  true), 'დღე',            '35 საათი = დღე');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}),  true), '2 დღე',          '36 საათი = 2 დღე');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}),   true), 'დღე',            '1 დღე    = დღე');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}),   true), '5 დღე',          '5 დღე    = 5 დღე');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}),  true), '25 დღე',         '25 დღე   = 25 დღე');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}),  true), 'თვე',            '26 დღე   = თვე');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}),  true), 'თვე',            '30 დღე   = თვე');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}),  true), 'თვე',            '45 დღე   = თვე');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}),  true), '2 თვე',          '46 დღე   = 2 თვე');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}),  true), '2 თვე',          '75 დღე   = 2 თვე');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}),  true), '3 თვე',          '76 დღე   = 3 თვე');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}),   true), 'თვე',            '1 თვე    = თვე');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}),   true), '5 თვე',          '5 თვე    = 5 თვე');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'წელი',           '345 დღე  = წელი');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 წელი',         '548 დღე  = 2 წელი');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}),   true), 'წელი',           '1 წელი   = წელი');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}),   true), '5 წელი',         '5 წელი   = 5 წელი');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'რამდენიმე წამში',     'ში სუფიქსი');\n        assert.equal(moment(0).from(30000), 'რამდენიმე წამის წინ', 'წინ სუფიქსი');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'რამდენიმე წამის წინ', 'უნდა აჩვენოს როგორც წარსული');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'რამდენიმე წამში', 'რამდენიმე წამში');\n        assert.equal(moment().add({d: 5}).fromNow(), '5 დღეში', '5 დღეში');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'დღეს 2:00 AM-ზე',  'დღეს ამავე დროს');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'დღეს 2:25 AM-ზე',  'ახლანდელ დროს დამატებული 25 წუთი');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'დღეს 3:00 AM-ზე',  'ახლანდელ დროს დამატებული 1 საათი');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'ხვალ 2:00 AM-ზე',  'ხვალ ამავე დროს');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'დღეს 1:00 AM-ზე',  'ახლანდელ დროს გამოკლებული 1 საათი');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'გუშინ 2:00 AM-ზე', 'გუშინ ამავე დროს');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('[შემდეგ] dddd LT[-ზე]'),  'დღეს + ' + i + ' დღე ახლანდელ დროს');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[შემდეგ] dddd LT[-ზე]'),  'დღეს + ' + i + ' დღე დღის დასაწყისში');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[შემდეგ] dddd LT[-ზე]'),  'დღეს + ' + i + ' დღე დღის დასასრულს');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[წინა] dddd LT[-ზე]'),  'დღეს - ' + i + ' დღე ახლანდელ დროს');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[წინა] dddd LT[-ზე]'),  'დღეს - ' + i + ' დღე დღის დასაწყისში');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[წინა] dddd LT[-ზე]'),  'დღეს - ' + i + ' დღე დღის დასასრულს');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 კვირის წინ');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '1 კვირაში');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 კვირის წინ');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  '2 კვირაში');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'დეკ 26 2011 უნდა იყოს კვირა 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'იან  1 2012 უნდა იყოს კვირა 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'იან  2 2012 უნდა იყოს კვირა 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'იან  8 2012 უნდა იყოს კვირა 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'იან  9 2012 უნდა იყოს კვირა 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'იან  1 2007 უნდა იყოს კვირა 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'იან  7 2007 უნდა იყოს კვირა 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'იან  8 2007 უნდა იყოს კვირა 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'იან 14 2007 უნდა იყოს კვირა 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'იან 15 2007 უნდა იყოს კვირა 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'დეკ 31 2007 უნდა იყოს კვირა 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'იან  1 2008 უნდა იყოს კვირა 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'იან  6 2008 უნდა იყოს კვირა 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'იან  7 2008 უნდა იყოს კვირა 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'იან 13 2008 უნდა იყოს კვირა 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'იან 14 2008 უნდა იყოს კვირა 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'დეკ 30 2002 უნდა იყოს კვირა 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'იან  1 2003 უნდა იყოს კვირა 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'იან  5 2003 უნდა იყოს კვირა 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'იან  6 2003 უნდა იყოს კვირა 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'იან 12 2003 უნდა იყოს კვირა 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'იან 13 2003 უნდა იყოს კვირა 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'დეკ 29 2008 უნდა იყოს კვირა 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'იან  1 2009 უნდა იყოს კვირა 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'იან  4 2009 უნდა იყოს კვირა 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'იან  5 2009 უნდა იყოს კვირა 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'იან 11 2009 უნდა იყოს კვირა 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'იან 12 2009 უნდა იყოს კვირა 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'დეკ 28 2009 უნდა იყოს კვირა 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'იან  1 2010 უნდა იყოს კვირა 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'იან  3 2010 უნდა იყოს კვირა 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'იან  4 2010 უნდა იყოს კვირა 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'იან 10 2010 უნდა იყოს კვირა 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'იან 11 2010 უნდა იყოს კვირა 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'დეკ 27 2010 უნდა იყოს კვირა 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'იან  1 2011 უნდა იყოს კვირა 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'იან  2 2011 უნდა იყოს კვირა 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'იან  3 2011 უნდა იყოს კვირა 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'იან  9 2011 უნდა იყოს კვირა 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'იან 10 2011 უნდა იყოს კვირა 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ლი', 'დეკ 26 2011 უნდა იყოს კვირა 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ლი', 'იან  1 2012 უნდა იყოს კვირა 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 მე-2', 'იან  2 2012 უნდა იყოს კვირა 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 მე-2', 'იან  8 2012 უნდა იყოს კვირა 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 მე-3', 'იან  9 2012 უნდა იყოს კვირა 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('km');\n\n    test('parse', function (assert) {\n        var tests = 'មករា មករា_កុម្ភៈ កុម្ភៈ_មិនា មិនា_មេសា មេសា_ឧសភា ឧសភា_មិថុនា មិថុនា_កក្កដា កក្កដា_សីហា សីហា_កញ្ញា កញ្ញា_តុលា តុលា_វិច្ឆិកា វិច្ឆិកា_ធ្នូ ធ្នូ'.split('_'),\n            i;\n\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a', 'អាទិត្យ, កុម្ភៈ 14 2010, 3:25:50 pm'],\n                ['ddd, hA', 'អាទិត្យ, 3PM'],\n                ['M Mo MM MMMM MMM', '2 2 02 កុម្ភៈ កុម្ភៈ'],\n                ['YYYY YY', '2010 10'],\n                ['D Do DD', '14 14 14'],\n                ['d do dddd ddd dd', '0 0 អាទិត្យ អាទិត្យ អាទិត្យ'],\n                ['DDD DDDo DDDD', '45 45 045'],\n                ['w wo ww', '6 6 06'],\n                ['h hh', '3 03'],\n                ['H HH', '15 15'],\n                ['m mm', '25 25'],\n                ['s ss', '50 50'],\n                ['a A', 'pm PM'],\n                ['[the] DDDo [day of the year]', 'the 45 day of the year'],\n                ['LTS', '15:25:50'],\n                ['L', '14/02/2010'],\n                ['LL', '14 កុម្ភៈ 2010'],\n                ['LLL', '14 កុម្ភៈ 2010 15:25'],\n                ['LLLL', 'អាទិត្យ, 14 កុម្ភៈ 2010 15:25'],\n                ['l', '14/2/2010'],\n                ['ll', '14 កុម្ភៈ 2010'],\n                ['lll', '14 កុម្ភៈ 2010 15:25'],\n                ['llll', 'អាទិត្យ, 14 កុម្ភៈ 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1st');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2nd');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3rd');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4th');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5th');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6th');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7th');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8th');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9th');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10th');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11th');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12th');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13th');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14th');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15th');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16th');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17th');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18th');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19th');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20th');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21st');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22nd');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23rd');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24th');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25th');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26th');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27th');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28th');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29th');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30th');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31st');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'មករា មករា_កុម្ភៈ កុម្ភៈ_មិនា មិនា_មេសា មេសា_ឧសភា ឧសភា_មិថុនា មិថុនា_កក្កដា កក្កដា_សីហា សីហា_កញ្ញា កញ្ញា_តុលា តុលា_វិច្ឆិកា វិច្ឆិកា_ធ្នូ ធ្នូ'.split('_'),\n            i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'អាទិត្យ អាទិត្យ អាទិត្យ_ច័ន្ទ ច័ន្ទ ច័ន្ទ_អង្គារ អង្គារ អង្គារ_ពុធ ពុធ ពុធ_ព្រហស្បតិ៍ ព្រហស្បតិ៍ ព្រហស្បតិ៍_សុក្រ សុក្រ សុក្រ_សៅរ៍ សៅរ៍ សៅរ៍'.split('_'),\n            i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'ប៉ុន្មានវិនាទី', '44 seconds = ប៉ុន្មានវិនាទី');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'មួយនាទី', '45 seconds = មួយនាទី');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'មួយនាទី', '89 seconds = មួយនាទី');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 នាទី', '90 seconds = 2 នាទី');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 នាទី', '44 minutes = 44 នាទី');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'មួយម៉ោង', '45 minutes = មួយម៉ោង');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'មួយម៉ោង', '89 minutes = មួយម៉ោង');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 ម៉ោង', '90 minutes = 2 ម៉ោង');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 ម៉ោង', '5 hours = 5 ម៉ោង');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 ម៉ោង', '21 hours = 21 ម៉ោង');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'មួយថ្ងៃ', '22 hours = មួយថ្ងៃ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'មួយថ្ងៃ', '35 hours = មួយថ្ងៃ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 ថ្ងៃ', '36 hours = 2 ថ្ងៃ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'មួយថ្ងៃ', '1 day = មួយថ្ងៃ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 ថ្ងៃ', '5 days = 5 ថ្ងៃ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 ថ្ងៃ', '25 days = 25 ថ្ងៃ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'មួយខែ', '26 days = មួយខែ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'មួយខែ', '30 days = មួយខែ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'មួយខែ', '43 days = មួយខែ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 ខែ', '46 days = 2 ខែ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 ខែ', '75 days = 2 ខែ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 ខែ', '76 days = 3 ខែ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'មួយខែ', '1 month = មួយខែ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 ខែ', '5 months = 5 ខែ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'មួយឆ្នាំ', '345 days = មួយឆ្នាំ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ឆ្នាំ', '548 days = 2 ឆ្នាំ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'មួយឆ្នាំ', '1 year = មួយឆ្នាំ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 ឆ្នាំ', '5 years = 5 ឆ្នាំ');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'ប៉ុន្មានវិនាទីទៀត', 'prefix');\n        assert.equal(moment(0).from(30000), 'ប៉ុន្មានវិនាទីមុន', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'ប៉ុន្មានវិនាទីមុន', 'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({\n            s: 30\n        }).fromNow(), 'ប៉ុន្មានវិនាទីទៀត', 'in a few seconds');\n        assert.equal(moment().add({\n            d: 5\n        }).fromNow(), '5 ថ្ងៃទៀត', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(), 'ថ្ងៃនៈ ម៉ោង 02:00', 'today at the same time');\n        assert.equal(moment(a).add({\n            m: 25\n        }).calendar(), 'ថ្ងៃនៈ ម៉ោង 02:25', 'Now plus 25 min');\n        assert.equal(moment(a).add({\n            h: 1\n        }).calendar(), 'ថ្ងៃនៈ ម៉ោង 03:00', 'Now plus 1 hour');\n        assert.equal(moment(a).add({\n            d: 1\n        }).calendar(), 'ស្អែក ម៉ោង 02:00', 'tomorrow at the same time');\n        assert.equal(moment(a).subtract({\n            h: 1\n        }).calendar(), 'ថ្ងៃនៈ ម៉ោង 01:00', 'Now minus 1 hour');\n        assert.equal(moment(a).subtract({\n            d: 1\n        }).calendar(), 'ម្សិលមិញ ម៉ោង 02:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({\n                d: i\n            });\n            assert.equal(m.calendar(), m.format('dddd [ម៉ោង] LT'), 'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(), m.format('dddd [ម៉ោង] LT'), 'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(), m.format('dddd [ម៉ោង] LT'), 'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({\n                d: i\n            });\n            assert.equal(m.calendar(), m.format('dddd [សប្តាហ៍មុន] [ម៉ោង] LT'), 'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(), m.format('dddd [សប្តាហ៍មុន] [ម៉ោង] LT'), 'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(), m.format('dddd [សប្តាហ៍មុន] [ម៉ោង] LT'), 'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({\n                w: 1\n            }),\n            weeksFromNow = moment().add({\n                w: 1\n            });\n\n        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '1 week ago');\n        assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 1 week');\n\n        weeksAgo = moment().subtract({\n            w: 2\n        });\n        weeksFromNow = moment().add({\n            w: 2\n        });\n\n        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), 'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(), 1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(), 1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(), 2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(), 1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(), 2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008, 0, 1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008, 0, 6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008, 0, 7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008, 0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008, 0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003, 0, 1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003, 0, 5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003, 0, 6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003, 0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003, 0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009, 0, 1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009, 0, 4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009, 0, 5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009, 0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009, 0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010, 0, 1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010, 0, 3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010, 0, 4]).week(), 1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010, 0, 10]).week(), 1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010, 0, 11]).week(), 2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011, 0, 1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011, 0, 2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011, 0, 3]).week(), 1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011, 0, 9]).week(), 1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011, 0, 10]).week(), 2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0, 1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).format('w ww wo'), '1 01 1', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).format('w ww wo'), '1 01 1', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).format('w ww wo'), '2 02 2', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'), '2 02 2', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('ko');\n\n    test('parse', function (assert) {\n        var tests = '1월 1월_2월 2월_3월 3월_4월 4월_5월 5월_6월 6월_7월 7월_8월 8월_9월 9월_10월 10월_11월 11월_12월 12월'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('parse meridiem', function (assert) {\n        var elements = [{\n            expression : '1981년 9월 8일 오후 2시 30분',\n            inputFormat : 'YYYY[년] M[월] D[일] A h[시] m[분]',\n            outputFormat : 'A',\n            expected : '오후'\n        }, {\n            expression : '1981년 9월 8일 오전 2시 30분',\n            inputFormat : 'YYYY[년] M[월] D[일] A h[시] m[분]',\n            outputFormat : 'A h시',\n            expected : '오전 2시'\n        }, {\n            expression : '14시 30분',\n            inputFormat : 'H[시] m[분]',\n            outputFormat : 'A',\n            expected : '오후'\n        }, {\n            expression : '오후 4시',\n            inputFormat : 'A h[시]',\n            outputFormat : 'H',\n            expected : '16'\n        }], i, l, it, actual;\n\n\n        for (i = 0, l = elements.length; i < l; ++i) {\n            it = elements[i];\n            actual = moment(it.expression, it.inputFormat).format(it.outputFormat);\n\n            assert.equal(\n                actual,\n                it.expected,\n                '\\'' + it.outputFormat + '\\' of \\'' + it.expression + '\\' must be \\'' + it.expected + '\\' but was \\'' + actual + '\\'.'\n            );\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['YYYY년 MMMM Do dddd a h:mm:ss',      '2010년 2월 14일 일요일 오후 3:25:50'],\n                ['ddd A h',                            '일 오후 3'],\n                ['M Mo MM MMMM MMM',                   '2 2일 02 2월 2월'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14일 14'],\n                ['d do dddd ddd dd',                   '0 0일 일요일 일 일'],\n                ['DDD DDDo DDDD',                      '45 45일 045'],\n                ['w wo ww',                            '8 8일 08'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                '오후 오후'],\n                ['일년 중 DDDo째 되는 날',                 '일년 중 45일째 되는 날'],\n                ['LTS',                                '오후 3시 25분 50초'],\n                ['L',                                  '2010.02.14'],\n                ['LL',                                 '2010년 2월 14일'],\n                ['LLL',                                '2010년 2월 14일 오후 3시 25분'],\n                ['LLLL',                               '2010년 2월 14일 일요일 오후 3시 25분'],\n                ['l',                                  '2010.2.14'],\n                ['ll',                                 '2010년 2월 14일'],\n                ['lll',                                '2010년 2월 14일 오후 3시 25분'],\n                ['llll',                               '2010년 2월 14일 일 오후 3시 25분']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1일', '1일');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2일', '2일');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3일', '3일');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4일', '4일');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5일', '5일');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6일', '6일');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7일', '7일');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8일', '8일');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9일', '9일');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10일', '10일');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11일', '11일');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12일', '12일');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13일', '13일');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14일', '14일');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15일', '15일');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16일', '16일');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17일', '17일');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18일', '18일');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19일', '19일');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20일', '20일');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21일', '21일');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22일', '22일');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23일', '23일');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24일', '24일');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25일', '25일');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26일', '26일');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27일', '27일');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28일', '28일');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29일', '29일');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30일', '30일');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31일', '31일');\n    });\n\n    test('format month', function (assert) {\n        var expected = '1월 1월_2월 2월_3월 3월_4월 4월_5월 5월_6월 6월_7월 7월_8월 8월_9월 9월_10월 10월_11월 11월_12월 12월'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = '일요일 일 일_월요일 월 월_화요일 화 화_수요일 수 수_목요일 목 목_금요일 금 금_토요일 토 토'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '몇초', '44초 = 몇초');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '일분',      '45초 = 일분');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '일분',      '89초 = 일분');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2분',     '90초 = 2분');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44분',    '44분 = 44분');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '한시간',       '45분 = 한시간');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '한시간',       '89분 = 한시간');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2시간',       '90분 = 2시간');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5시간',       '5시간 = 5시간');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21시간',      '21시간 = 21시간');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '하루',         '22시간 = 하루');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '하루',         '35시간 = 하루');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2일',        '36시간 = 2일');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '하루',         '하루 = 하루');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5일',        '5일 = 5일');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25일',       '25일 = 25일');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '한달',       '26일 = 한달');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '한달',       '30일 = 한달');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '한달',       '45일 = 한달');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2달',      '46일 = 2달');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2달',      '75일 = 2달');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3달',      '76일 = 3달');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '한달',       '1달 = 한달');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5달',      '5달 = 5달');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '일년',        '345일 = 일년');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2년',       '548일 = 2년');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '일년',        '일년 = 일년');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5년',       '5년 = 5년');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), '몇초 후',  'prefix');\n        assert.equal(moment(0).from(30000), '몇초 전', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), '몇초 전',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), '몇초 후', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), '5일 후', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     '오늘 오전 2시 0분',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      '오늘 오전 2시 25분',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       '오늘 오전 3시 0분',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       '내일 오전 2시 0분',     'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  '오늘 오전 1시 0분',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  '어제 오전 2시 0분',     'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('지난주 dddd LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('지난주 dddd LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('지난주 dddd LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n        assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n        assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n        assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n        assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday format', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1일', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1일', 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2일', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2일', 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3일', 'Jan 15 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('lb');\n\n    test('parse', function (assert) {\n        var tests = 'Januar Jan._Februar Febr._Mäerz Mrz._Abrëll Abr._Mee Mee_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, HH:mm:ss', 'Sonndeg, 14. Februar 2010, 15:25:50'],\n                ['ddd, HH:mm', 'So., 15:25'],\n                ['M Mo MM MMMM MMM', '2 2. 02 Februar Febr.'],\n                ['YYYY YY', '2010 10'],\n                ['D Do DD', '14 14. 14'],\n                ['d do dddd ddd dd', '0 0. Sonndeg So. So'],\n                ['DDD DDDo DDDD', '45 45. 045'],\n                ['w wo ww', '6 6. 06'],\n                ['h hh', '3 03'],\n                ['H HH', '15 15'],\n                ['m mm', '25 25'],\n                ['s ss', '50 50'],\n                ['a A', 'pm PM'],\n                ['[the] DDDo [day of the year]', 'the 45. day of the year'],\n                ['LTS', '15:25:50 Auer'],\n                ['L', '14.02.2010'],\n                ['LL', '14. Februar 2010'],\n                ['LLL', '14. Februar 2010 15:25 Auer'],\n                ['LLLL', 'Sonndeg, 14. Februar 2010 15:25 Auer'],\n                ['l', '14.2.2010'],\n                ['ll', '14. Febr. 2010'],\n                ['lll', '14. Febr. 2010 15:25 Auer'],\n                ['llll', 'So., 14. Febr. 2010 15:25 Auer']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format month', function (assert) {\n        var expected = 'Januar Jan._Februar Febr._Mäerz Mrz._Abrëll Abr._Mee Mee_Juni Jun._Juli Jul._August Aug._September Sept._Oktober Okt._November Nov._Dezember Dez.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'Sonndeg So. So_Méindeg Mé. Mé_Dënschdeg Dë. Dë_Mëttwoch Më. Më_Donneschdeg Do. Do_Freideg Fr. Fr_Samschdeg Sa. Sa'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true), 'e puer Sekonnen', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true), 'eng Minutt', '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true), 'eng Minutt', '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '2 Minutten', '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '44 Minutten', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true), 'eng Stonn', '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true), 'eng Stonn', '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true), '2 Stonnen', '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true), '5 Stonnen', '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true), '21 Stonnen', '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true), 'een Dag', '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true), 'een Dag', '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true), '2 Deeg', '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true), 'een Dag', '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true), '5 Deeg', '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true), '25 Deeg', '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'ee Mount', '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'ee Mount', '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'ee Mount', '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '2 Méint', '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '2 Méint', '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '3 Méint', '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'ee Mount', '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '5 Méint', '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ee Joer', '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 Joer', '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true), 'ee Joer', '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '5 Joer', '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'an e puer Sekonnen', 'prefix');\n        assert.equal(moment(0).from(30000), 'virun e puer Sekonnen', 'suffix');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'an e puer Sekonnen', 'in a few seconds');\n        assert.equal(moment().add({d: 1}).fromNow(), 'an engem Dag', 'in one day');\n        assert.equal(moment().add({d: 2}).fromNow(), 'an 2 Deeg', 'in 2 days');\n        assert.equal(moment().add({d: 3}).fromNow(), 'an 3 Deeg', 'in 3 days');\n        assert.equal(moment().add({d: 4}).fromNow(), 'a 4 Deeg', 'in 4 days');\n        assert.equal(moment().add({d: 5}).fromNow(), 'a 5 Deeg', 'in 5 days');\n        assert.equal(moment().add({d: 6}).fromNow(), 'a 6 Deeg', 'in 6 days');\n        assert.equal(moment().add({d: 7}).fromNow(), 'a 7 Deeg', 'in 7 days');\n        assert.equal(moment().add({d: 8}).fromNow(), 'an 8 Deeg', 'in 8 days');\n        assert.equal(moment().add({d: 9}).fromNow(), 'an 9 Deeg', 'in 9 days');\n        assert.equal(moment().add({d: 10}).fromNow(), 'an 10 Deeg', 'in 10 days');\n        assert.equal(moment().add({y: 100}).fromNow(), 'an 100 Joer', 'in 100 years');\n        assert.equal(moment().add({y: 400}).fromNow(), 'a 400 Joer', 'in 400 years');\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m, weekday, datestring;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            weekday = parseInt(m.format('d'), 10);\n            datestring = (weekday === 2 || weekday === 4 ? '[Leschten] dddd [um] LT' : '[Leschte] dddd [um] LT');\n\n            assert.equal(m.calendar(), m.format(datestring), 'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(), m.format(datestring), 'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(), m.format(datestring), 'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('lt');\n\n    test('parse', function (assert) {\n        var tests = 'sausio sau_vasario vas_kovo kov_balandžio bal_gegužės geg_birželio bir_liepos lie_rugpjūčio rgp_rugsėjo rgs_spalio spa_lapkričio lap_gruodžio grd'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, h:mm:ss a',      'sekmadienis, 14-oji vasario 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'Sek, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2-oji 02 vasario vas'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14-oji 14'],\n                ['d do dddd ddd dd',                   '0 0-oji sekmadienis Sek S'],\n                ['DDD DDDo DDDD',                      '45 45-oji 045'],\n                ['w wo ww',                            '6 6-oji 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['DDDo [metų diena]',                  '45-oji metų diena'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '2010-02-14'],\n                ['LL',                                 '2010 m. vasario 14 d.'],\n                ['LLL',                                '2010 m. vasario 14 d., 15:25 val.'],\n                ['LLLL',                               '2010 m. vasario 14 d., sekmadienis, 15:25 val.'],\n                ['l',                                  '2010-02-14'],\n                ['ll',                                 '2010 m. vasario 14 d.'],\n                ['lll',                                '2010 m. vasario 14 d., 15:25 val.'],\n                ['llll',                               '2010 m. vasario 14 d., Sek, 15:25 val.']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-oji', '1-oji');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-oji', '2-oji');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-oji', '3-oji');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-oji', '4-oji');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-oji', '5-oji');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-oji', '6-oji');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-oji', '7-oji');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-oji', '8-oji');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-oji', '9-oji');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-oji', '10-oji');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-oji', '11-oji');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-oji', '12-oji');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-oji', '13-oji');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-oji', '14-oji');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-oji', '15-oji');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-oji', '16-oji');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-oji', '17-oji');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-oji', '18-oji');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-oji', '19-oji');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-oji', '20-oji');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-oji', '21-oji');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-oji', '22-oji');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-oji', '23-oji');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-oji', '24-oji');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-oji', '25-oji');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-oji', '26-oji');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-oji', '27-oji');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-oji', '28-oji');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-oji', '29-oji');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-oji', '30-oji');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-oji', '31-oji');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'sausio sau_vasario vas_kovo kov_balandžio bal_gegužės geg_birželio bir_liepos lie_rugpjūčio rgp_rugsėjo rgs_spalio spa_lapkričio lap_gruodžio grd'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'sekmadienis Sek S_pirmadienis Pir P_antradienis Ant A_trečiadienis Tre T_ketvirtadienis Ket K_penktadienis Pen Pn_šeštadienis Šeš Š'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week on US calendar', function (assert) {\n        moment.locale('lt', {week: {dow: 0, doy: 6}});\n        var expected = 'sekmadienis Sek S_pirmadienis Pir P_antradienis Ant A_trečiadienis Tre T_ketvirtadienis Ket K_penktadienis Pen Pn_šeštadienis Šeš Š'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n        moment.locale('lt', {week: {dow: 1, doy: 4}});\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'kelios sekundės', '44 seconds = seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minutė',          '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minutė',          '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutės',       '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 10}), true),  '10 minučių',       '10 minutes = 10 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 11}), true),  '11 minučių',       '11 minutes = 11 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 19}), true),  '19 minučių',       '19 minutes = 19 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 20}), true),  '20 minučių',       '20 minutes = 20 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutės',      '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'valanda',         '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'valanda',         '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 valandos',      '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 valandos',      '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 10}), true),  '10 valandų',      '10 hours = 10 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 valandos',     '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'diena',           '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'diena',           '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dienos',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'diena',           '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dienos',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 10}), true),  '10 dienų',        '10 days = 10 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dienos',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mėnuo',           '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mėnuo',           '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mėnuo',           '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mėnesiai',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mėnesiai',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mėnesiai',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mėnuo',           '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mėnesiai',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 10}), true),  '10 mėnesių',      '10 months = 10 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'metai',           '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 metai',         '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'metai',           '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 metai',         '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'po kelių sekundžių',  'prefix');\n        assert.equal(moment(0).from(30000), 'prieš kelias sekundes', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'prieš kelias sekundes',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'po kelių sekundžių', 'in seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'po 5 dienų', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Šiandien 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Šiandien 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Šiandien 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Rytoj 02:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Šiandien 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Vakar 02:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[Praėjusį] dddd LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[Praėjusį] dddd LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[Praėjusį] dddd LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52-oji', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1-oji', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1-oji', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2-oji', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2-oji', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('lv');\n\n    test('parse', function (assert) {\n        var tests = 'janvāris jan_februāris feb_marts mar_aprīlis apr_maijs mai_jūnijs jūn_jūlijs jūl_augusts aug_septembris sep_oktobris okt_novembris nov_decembris dec'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, h:mm:ss a',      'svētdiena, 14. februāris 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'Sv, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2. 02 februāris feb'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14. 14'],\n                ['d do dddd ddd dd',                   '0 0. svētdiena Sv Sv'],\n                ['DDD DDDo DDDD',                      '45 45. 045'],\n                ['w wo ww',                            '6 6. 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14.02.2010'],\n                ['LL',                                 '2010. gada 14. februāris'],\n                ['LLL',                                '2010. gada 14. februāris, 15:25'],\n                ['LLLL',                               '2010. gada 14. februāris, svētdiena, 15:25'],\n                ['l',                                  '14.2.2010'],\n                ['ll',                                 '2010. gada 14. feb'],\n                ['lll',                                '2010. gada 14. feb, 15:25'],\n                ['llll',                               '2010. gada 14. feb, Sv, 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'janvāris jan_februāris feb_marts mar_aprīlis apr_maijs mai_jūnijs jūn_jūlijs jūl_augusts aug_septembris sep_oktobris okt_novembris nov_decembris dec'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'svētdiena Sv Sv_pirmdiena P P_otrdiena O O_trešdiena T T_ceturtdiena C C_piektdiena Pk Pk_sestdiena S S'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'dažas sekundes',    '44 seconds = seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minūti',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minūti',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minūtes',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minūtes',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'stundu',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'stundu',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 stundas',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 stundas',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 stunda',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dienu',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dienu',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dienas',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dienu',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dienas',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dienas',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mēnesi',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mēnesi',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mēnesi',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mēneši',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mēneši',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mēneši',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mēnesi',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mēneši',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'gadu',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 gadi',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'gadu',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 gadi',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'dažas sekundes vēlāk',  'prefix');\n        assert.equal(moment(0).from(30000), 'dažas sekundes agrāk', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'dažas sekundes agrāk',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'dažas sekundes vēlāk', 'in seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), '5 dienas vēlāk', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Šodien pulksten 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Šodien pulksten 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Šodien pulksten 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Rīt pulksten 02:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Šodien pulksten 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Vakar pulksten 02:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [pulksten] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [pulksten] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [pulksten] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[Pagājušā] dddd [pulksten] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[Pagājušā] dddd [pulksten] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[Pagājušā] dddd [pulksten] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1.', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1.', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2.', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2.', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('mk');\n\n    test('parse', function (assert) {\n        var tests = 'јануари јан_февруари фев_март мар_април апр_мај мај_јуни јун_јули јул_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, H:mm:ss',        'недела, февруари 14-ти 2010, 15:25:50'],\n                ['ddd, hA',                            'нед, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2-ри 02 февруари фев'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14-ти 14'],\n                ['d do dddd ddd dd',                   '0 0-ев недела нед нe'],\n                ['DDD DDDo DDDD',                      '45 45-ти 045'],\n                ['w wo ww',                            '7 7-ми 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45-ти day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14.02.2010'],\n                ['LL',                                 '14 февруари 2010'],\n                ['LLL',                                '14 февруари 2010 15:25'],\n                ['LLLL',                               'недела, 14 февруари 2010 15:25'],\n                ['l',                                  '14.2.2010'],\n                ['ll',                                 '14 фев 2010'],\n                ['lll',                                '14 фев 2010 15:25'],\n                ['llll',                               'нед, 14 фев 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-ви', '1-ви');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-ри', '2-ри');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-ти', '3-ти');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-ти', '4-ти');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-ти', '5-ти');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-ти', '6-ти');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-ми', '7-ми');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-ми', '8-ми');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-ти', '9-ти');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-ти', '10-ти');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-ти', '11-ти');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-ти', '12-ти');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-ти', '13-ти');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-ти', '14-ти');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-ти', '15-ти');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-ти', '16-ти');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-ти', '17-ти');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-ти', '18-ти');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-ти', '19-ти');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-ти', '20-ти');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-ви', '21-ви');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-ри', '22-ри');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-ти', '23-ти');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-ти', '24-ти');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-ти', '25-ти');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-ти', '26-ти');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-ми', '27-ми');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-ми', '28-ми');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-ти', '29-ти');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-ти', '30-ти');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-ви', '31-ви');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'јануари јан_февруари фев_март мар_април апр_мај мај_јуни јун_јули јул_август авг_септември сеп_октомври окт_ноември ное_декември дек'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'недела нед нe_понеделник пон пo_вторник вто вт_среда сре ср_четврток чет че_петок пет пе_сабота саб сa'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'неколку секунди', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'минута',          '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'минута',          '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минути',        '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минути',       '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'час',             '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'час',             '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 часа',          '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 часа',          '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 часа',         '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ден',             '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ден',             '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дена',          '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ден',             '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дена',          '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дена',         '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месец',           '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месец',           '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месец',           '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месеци',        '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месеци',        '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месеци',        '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месец',           '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месеци',        '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'година',          '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 години',        '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'година',          '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 години',        '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'после неколку секунди',  'prefix');\n        assert.equal(moment(0).from(30000), 'пред неколку секунди', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'пред неколку секунди',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'после неколку секунди', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'после 5 дена', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Денес во 2:00',  'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Денес во 2:25',  'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Денес во 3:00',  'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Утре во 2:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Денес во 1:00',  'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчера во 2:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [во] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [во] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [во] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        function makeFormat(d) {\n            switch (d.day()) {\n            case 0:\n            case 3:\n            case 6:\n                return '[Во изминатата] dddd [во] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[Во изминатиот] dddd [во] LT';\n            }\n        }\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-ви', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-ви', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-ри', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-ри', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-ти', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('ml');\n\n    test('parse', function (assert) {\n        var tests = 'ജനുവരി ജനു._ഫെബ്രുവരി ഫെബ്രു._മാർച്ച് മാർ._ഏപ്രിൽ ഏപ്രി._മേയ് മേയ്_ജൂൺ ജൂൺ_ജൂലൈ ജൂലൈ._ഓഗസ്റ്റ് ഓഗ._സെപ്റ്റംബർ സെപ്റ്റ._ഒക്ടോബർ ഒക്ടോ._നവംബർ നവം._ഡിസംബർ ഡിസം.'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, a h:mm:ss -നു',  'ഞായറാഴ്ച, 14 ഫെബ്രുവരി 2010, ഉച്ച കഴിഞ്ഞ് 3:25:50 -നു'],\n                ['ddd, a h -നു',                       'ഞായർ, ഉച്ച കഴിഞ്ഞ് 3 -നു'],\n                ['M Mo MM MMMM MMM',                   '2 2 02 ഫെബ്രുവരി ഫെബ്രു.'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14 14'],\n                ['d do dddd ddd dd',                   '0 0 ഞായറാഴ്ച ഞായർ ഞാ'],\n                ['DDD DDDo DDDD',                      '45 45 045'],\n                ['w wo ww',                            '8 8 08'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'ഉച്ച കഴിഞ്ഞ് ഉച്ച കഴിഞ്ഞ്'],\n                ['LTS',                                'ഉച്ച കഴിഞ്ഞ് 3:25:50 -നു'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 ഫെബ്രുവരി 2010'],\n                ['LLL',                                '14 ഫെബ്രുവരി 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു'],\n                ['LLLL',                               'ഞായറാഴ്ച, 14 ഫെബ്രുവരി 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 ഫെബ്രു. 2010'],\n                ['lll',                                '14 ഫെബ്രു. 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു'],\n                ['llll',                               'ഞായർ, 14 ഫെബ്രു. 2010, ഉച്ച കഴിഞ്ഞ് 3:25 -നു']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'ജനുവരി ജനു._ഫെബ്രുവരി ഫെബ്രു._മാർച്ച് മാർ._ഏപ്രിൽ ഏപ്രി._മേയ് മേയ്_ജൂൺ ജൂൺ_ജൂലൈ ജൂലൈ._ഓഗസ്റ്റ് ഓഗ._സെപ്റ്റംബർ സെപ്റ്റ._ഒക്ടോബർ ഒക്ടോ._നവംബർ നവം._ഡിസംബർ ഡിസം.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'ഞായറാഴ്ച ഞായർ ഞാ_തിങ്കളാഴ്ച തിങ്കൾ തി_ചൊവ്വാഴ്ച ചൊവ്വ ചൊ_ബുധനാഴ്ച ബുധൻ ബു_വ്യാഴാഴ്ച വ്യാഴം വ്യാ_വെള്ളിയാഴ്ച വെള്ളി വെ_ശനിയാഴ്ച ശനി ശ'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'അൽപ നിമിഷങ്ങൾ', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ഒരു മിനിറ്റ്',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ഒരു മിനിറ്റ്',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 മിനിറ്റ്',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 മിനിറ്റ്',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ഒരു മണിക്കൂർ',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ഒരു മണിക്കൂർ',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 മണിക്കൂർ',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 മണിക്കൂർ',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 മണിക്കൂർ',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ഒരു ദിവസം',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ഒരു ദിവസം',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ദിവസം',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ഒരു ദിവസം',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ദിവസം',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ദിവസം',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ഒരു മാസം',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ഒരു മാസം',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ഒരു മാസം',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 മാസം',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 മാസം',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 മാസം',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ഒരു മാസം',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 മാസം',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ഒരു വർഷം',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 വർഷം',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ഒരു വർഷം',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 വർഷം',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'അൽപ നിമിഷങ്ങൾ കഴിഞ്ഞ്',  'prefix');\n        assert.equal(moment(0).from(30000), 'അൽപ നിമിഷങ്ങൾ മുൻപ്', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'അൽപ നിമിഷങ്ങൾ മുൻപ്',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'അൽപ നിമിഷങ്ങൾ കഴിഞ്ഞ്', 'അൽപ നിമിഷങ്ങൾ കഴിഞ്ഞ്');\n        assert.equal(moment().add({d: 5}).fromNow(), '5 ദിവസം കഴിഞ്ഞ്', '5 ദിവസം കഴിഞ്ഞ്');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'ഇന്ന് രാത്രി 2:00 -നു',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'ഇന്ന് രാത്രി 2:25 -നു',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 3}).calendar(),       'ഇന്ന് രാവിലെ 5:00 -നു',     'Now plus 3 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'നാളെ രാത്രി 2:00 -നു',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'ഇന്ന് രാത്രി 1:00 -നു',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'ഇന്നലെ രാത്രി 2:00 -നു', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[കഴിഞ്ഞ] dddd[,] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[കഴിഞ്ഞ] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[കഴിഞ്ഞ] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('meridiem', function (assert) {\n        assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'രാത്രി', 'before dawn');\n        assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'രാവിലെ', 'morning');\n        assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'ഉച്ച കഴിഞ്ഞ്', 'during day');\n        assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'വൈകുന്നേരം', 'evening');\n        assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'വൈകുന്നേരം', 'late evening');\n        assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'രാത്രി', 'night');\n\n        assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'രാത്രി', 'before dawn');\n        assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'രാവിലെ', 'morning');\n        assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'ഉച്ച കഴിഞ്ഞ്', ' during day');\n        assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'വൈകുന്നേരം', 'evening');\n        assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'വൈകുന്നേരം', 'late evening');\n        assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'രാത്രി', 'night');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n        assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n        assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n        assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n        assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('mr');\n\n    test('parse', function (assert) {\n        var tests = 'जानेवारी जाने._फेब्रुवारी फेब्रु._मार्च मार्च._एप्रिल एप्रि._मे मे._जून जून._जुलै जुलै._ऑगस्ट ऑग._सप्टेंबर सप्टें._ऑक्टोबर ऑक्टो._नोव्हेंबर नोव्हें._डिसेंबर डिसें.'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, a h:mm:ss वाजता', 'रविवार, १४ फेब्रुवारी २०१०, दुपारी ३:२५:५० वाजता'],\n                ['ddd, a h वाजता',                       'रवि, दुपारी ३ वाजता'],\n                ['M Mo MM MMMM MMM',                   '२ २ ०२ फेब्रुवारी फेब्रु.'],\n                ['YYYY YY',                            '२०१० १०'],\n                ['D Do DD',                            '१४ १४ १४'],\n                ['d do dddd ddd dd',                   '० ० रविवार रवि र'],\n                ['DDD DDDo DDDD',                      '४५ ४५ ०४५'],\n                ['w wo ww',                            '८ ८ ०८'],\n                ['h hh',                               '३ ०३'],\n                ['H HH',                               '१५ १५'],\n                ['m mm',                               '२५ २५'],\n                ['s ss',                               '५० ५०'],\n                ['a A',                                'दुपारी दुपारी'],\n                ['LTS',                                'दुपारी ३:२५:५० वाजता'],\n                ['L',                                  '१४/०२/२०१०'],\n                ['LL',                                 '१४ फेब्रुवारी २०१०'],\n                ['LLL',                                '१४ फेब्रुवारी २०१०, दुपारी ३:२५ वाजता'],\n                ['LLLL',                               'रविवार, १४ फेब्रुवारी २०१०, दुपारी ३:२५ वाजता'],\n                ['l',                                  '१४/२/२०१०'],\n                ['ll',                                 '१४ फेब्रु. २०१०'],\n                ['lll',                                '१४ फेब्रु. २०१०, दुपारी ३:२५ वाजता'],\n                ['llll',                               'रवि, १४ फेब्रु. २०१०, दुपारी ३:२५ वाजता']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '१', '१');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '२', '२');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '३', '३');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '४', '४');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '५', '५');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '६', '६');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '७', '७');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '८', '८');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '९', '९');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '१०', '१०');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '११', '११');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '१२', '१२');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '१३', '१३');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '१४', '१४');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '१५', '१५');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '१६', '१६');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '१७', '१७');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '१८', '१८');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '१९', '१९');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '२०', '२०');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '२१', '२१');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '२२', '२२');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '२३', '२३');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '२४', '२४');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '२५', '२५');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '२६', '२६');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '२७', '२७');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '२८', '२८');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '२९', '२९');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '३०', '३०');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '३१', '३१');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'जानेवारी जाने._फेब्रुवारी फेब्रु._मार्च मार्च._एप्रिल एप्रि._मे मे._जून जून._जुलै जुलै._ऑगस्ट ऑग._सप्टेंबर सप्टें._ऑक्टोबर ऑक्टो._नोव्हेंबर नोव्हें._डिसेंबर डिसें.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'रविवार रवि र_सोमवार सोम सो_मंगळवार मंगळ मं_बुधवार बुध बु_गुरूवार गुरू गु_शुक्रवार शुक्र शु_शनिवार शनि श'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'सेकंद', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'एक मिनिट',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'एक मिनिट',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '२ मिनिटे',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true), '४४ मिनिटे', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'एक तास',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'एक तास',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '२ तास',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '५ तास',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '२१ तास',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'एक दिवस',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'एक दिवस',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '२ दिवस',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'एक दिवस',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '५ दिवस',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '२५ दिवस',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true), 'एक महिना', '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true), 'एक महिना', '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true), 'एक महिना', '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true), '२ महिने', '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true), '२ महिने', '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true), '३ महिने', '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true), 'एक महिना', '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true), '५ महिने', '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'एक वर्ष',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '२ वर्षे',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'एक वर्ष',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true), '५ वर्षे', '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'सेकंद नंतर', 'prefix');\n        assert.equal(moment(0).from(30000), 'सेकंद पूर्वी', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'सेकंद पूर्वी',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'सेकंद नंतर', 'सेकंद नंतर');\n        assert.equal(moment().add({d: 5}).fromNow(), '५ दिवस नंतर', '५ दिवस नंतर');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'आज रात्री २:०० वाजता',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'आज रात्री २:२५ वाजता',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 3}).calendar(),       'आज सकाळी ५:०० वाजता',     'Now plus 3 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'उद्या रात्री २:०० वाजता',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'आज रात्री १:०० वाजता',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'काल रात्री २:०० वाजता', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd[,] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(), m.format('[मागील] dddd[,] LT'), 'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(), m.format('[मागील] dddd[,] LT'), 'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(), m.format('[मागील] dddd[,] LT'), 'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('meridiem', function (assert) {\n        assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'रात्री', 'before dawn');\n        assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'सकाळी', 'morning');\n        assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'दुपारी', 'during day');\n        assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'सायंकाळी', 'evening');\n        assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'सायंकाळी', 'late evening');\n        assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'रात्री', 'night');\n\n        assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'रात्री', 'before dawn');\n        assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'सकाळी', 'morning');\n        assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'दुपारी', ' during day');\n        assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'सायंकाळी', 'evening');\n        assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'सायंकाळी', 'late evening');\n        assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'रात्री', 'night');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n        assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n        assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n        assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n        assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '१ ०१ १', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).format('w ww wo'), '१ ०१ १', 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'), '२ ०२ २', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).format('w ww wo'), '२ ०२ २', 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'), '३ ०३ ३', 'Jan 15 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('ms-my');\n\n    test('parse', function (assert) {\n        var i,\n            tests = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');\n\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' sepatutnya bulan ' + (i + 1));\n        }\n\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'Ahad, Februari 14 2010, 3:25:50 petang'],\n                ['ddd, hA',                            'Ahd, 3petang'],\n                ['M Mo MM MMMM MMM',                   '2 2 02 Februari Feb'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14 14'],\n                ['d do dddd ddd dd',                   '0 0 Ahad Ahd Ah'],\n                ['DDD DDDo DDDD',                      '45 45 045'],\n                ['w wo ww',                            '7 7 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'petang petang'],\n                ['[hari] [ke] DDDo [tahun] ini', 'hari ke 45 tahun ini'],\n                ['LTS',                                '15.25.50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 Februari 2010'],\n                ['LLL',                                '14 Februari 2010 pukul 15.25'],\n                ['LLLL',                               'Ahad, 14 Februari 2010 pukul 15.25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 Feb 2010'],\n                ['lll',                                '14 Feb 2010 pukul 15.25'],\n                ['llll',                               'Ahd, 14 Feb 2010 pukul 15.25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n    });\n\n    test('format month', function (assert) {\n        var i,\n            expected = 'Januari Jan_Februari Feb_Mac Mac_April Apr_Mei Mei_Jun Jun_Julai Jul_Ogos Ogs_September Sep_Oktober Okt_November Nov_Disember Dis'.split('_');\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var i,\n            expected = 'Ahad Ahd Ah_Isnin Isn Is_Selasa Sel Sl_Rabu Rab Rb_Khamis Kha Km_Jumaat Jum Jm_Sabtu Sab Sb'.split('_');\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'beberapa saat', '44 saat = beberapa saat');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'seminit',      '45 saat = seminit');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'seminit',      '89 saat = seminit');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minit',     '90 saat = 2 minit');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minit',    '44 minit = 44 minit');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'sejam',       '45 minit = sejam');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'sejam',       '89 minit = sejam');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 jam',       '90 minit = 2 jam');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 jam',       '5 jam = 5 jam');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 jam',      '21 jam = 21 jam');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'sehari',         '22 jam = sehari');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'sehari',         '35 jam = sehari');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 hari',        '36 jam = 2 hari');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'sehari',         '1 hari = sehari');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 hari',        '5 hari = 5 hari');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 hari',       '25 hari = 25 hari');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'sebulan',       '26 hari = sebulan');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'sebulan',       '30 hari = sebulan');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'sebulan',       '45 hari = sebulan');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 bulan',      '46 hari = 2 bulan');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 bulan',      '75 hari = 2 bulan');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 bulan',      '76 hari = 3 bulan');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'sebulan',       '1 bulan = sebulan');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 bulan',      '5 bulan = 5 bulan');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'setahun',        '345 hari = setahun');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 tahun',       '548 hari = 2 tahun');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'setahun',        '1 tahun = setahun');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 tahun',       '5 tahun = 5 tahun');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'dalam beberapa saat',  'prefix');\n        assert.equal(moment(0).from(30000), 'beberapa saat yang lepas', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'beberapa saat yang lepas',  'waktu sekarang dari sekarang sepatutnya menunjukkan sebagai telah lepas');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'dalam beberapa saat', 'dalam beberapa saat');\n        assert.equal(moment().add({d: 5}).fromNow(), 'dalam 5 hari', 'dalam 5 hari');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Hari ini pukul 02.00',     'hari ini pada waktu yang sama');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Hari ini pukul 02.25',     'Sekarang tambah 25 minit');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Hari ini pukul 03.00',     'Sekarang tambah 1 jam');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Esok pukul 02.00',  'esok pada waktu yang sama');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hari ini pukul 01.00',     'Sekarang tolak 1 jam');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kelmarin pukul 02.00', 'kelmarin pada waktu yang sama');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari waktu sekarang');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari permulaan hari');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [pukul] LT'),  'Hari ini + ' + i + ' hari tamat hari');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari waktu sekarang');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari permulaan hari');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [lepas] [pukul] LT'),  'Hari ini - ' + i + ' hari tamat hari');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 minggu lepas');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'dalam 1 minggu');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 minggu lepas');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'dalam 2 minggu');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 sepatutnya minggu 1');\n        assert.equal(moment([2012, 0,  7]).week(), 2, 'Jan  7 2012 sepatutnya minggu 2');\n        assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 sepatutnya minggu 2');\n        assert.equal(moment([2012, 0, 14]).week(), 3, 'Jan 14 2012 sepatutnya minggu 3');\n        assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 sepatutnya minggu 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 31]).week(), 53, 'Dec 31 2006 sepatutnya minggu 53');\n        assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 sepatutnya minggu 1');\n        assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 sepatutnya minggu 1');\n        assert.equal(moment([2007,  0,  7]).week(), 1, 'Jan  7 2007 sepatutnya minggu 1');\n        assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 sepatutnya minggu 2');\n        assert.equal(moment([2007,  0, 14]).week(), 2, 'Jan 14 2007 sepatutnya minggu 2');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 30]).week(), 52, 'Dec 30 2007 sepatutnya minggu 52');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 sepatutnya minggu 1');\n        assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 sepatutnya minggu 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 sepatutnya minggu 1');\n        assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 sepatutnya minggu 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 sepatutnya minggu 2');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 29]).week(), 52, 'Dec 29 2002 sepatutnya minggu 52');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 sepatutnya minggu 1');\n        assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 sepatutnya minggu 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 sepatutnya minggu 1');\n        assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 sepatutnya minggu 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 sepatutnya minggu 2');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 28]).week(), 52, 'Dec 28 2008 sepatutnya minggu 52');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 sepatutnya minggu 1');\n        assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 sepatutnya minggu 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 sepatutnya minggu 1');\n        assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 sepatutnya minggu 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 sepatutnya minggu 2');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 27]).week(), 52, 'Dec 27 2009 sepatutnya minggu 52');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 sepatutnya minggu 1');\n        assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 sepatutnya minggu 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 sepatutnya minggu 1');\n        assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 sepatutnya minggu 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 sepatutnya minggu 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 26]).week(), 52, 'Dec 26 2010 sepatutnya minggu 52');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 sepatutnya minggu 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 sepatutnya minggu 1');\n        assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 sepatutnya minggu 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 sepatutnya minggu 2');\n    });\n\n    test('weeks year starting sunday format', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 sepatutnya minggu 1');\n        assert.equal(moment([2012, 0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 sepatutnya minggu 2');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 sepatutnya minggu 2');\n        assert.equal(moment([2012, 0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 sepatutnya minggu 3');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 sepatutnya minggu 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('my');\n\n    test('parse', function (assert) {\n        var tests = 'ဇန်နဝါရီ ဇန်_ဖေဖော်ဝါရီ ဖေ_မတ် မတ်_ဧပြီ ပြီ_မေ မေ_ဇွန် ဇွန်_ဇူလိုင် လိုင်_သြဂုတ် သြ_စက်တင်ဘာ စက်_အောက်တိုဘာ အောက်_နိုဝင်ဘာ နို_ဒီဇင်ဘာ ဒီ'.split('_'),\n            i;\n\n        function equalTest (input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a', 'တနင်္ဂနွေ, ဖေဖော်ဝါရီ ၁၄ ၂၀၁၀, ၃:၂၅:၅၀ pm'],\n                ['ddd, hA', 'နွေ, ၃PM'],\n                ['M Mo MM MMMM MMM', '၂ ၂ ၀၂ ဖေဖော်ဝါရီ ဖေ'],\n                ['YYYY YY', '၂၀၁၀ ၁၀'],\n                ['D Do DD', '၁၄ ၁၄ ၁၄'],\n                ['d do dddd ddd dd', '၀ ၀ တနင်္ဂနွေ နွေ နွေ'],\n                ['DDD DDDo DDDD', '၄၅ ၄၅ ၀၄၅'],\n                ['w wo ww', '၆ ၆ ၀၆'],\n                ['h hh', '၃ ၀၃'],\n                ['H HH', '၁၅ ၁၅'],\n                ['m mm', '၂၅ ၂၅'],\n                ['s ss', '၅၀ ၅၀'],\n                ['a A', 'pm PM'],\n                ['[နှစ်၏] DDDo [ရက်မြောက်]', 'နှစ်၏ ၄၅ ရက်မြောက်'],\n                ['LTS', '၁၅:၂၅:၅၀'],\n                ['L', '၁၄/၀၂/၂၀၁၀'],\n                ['LL', '၁၄ ဖေဖော်ဝါရီ ၂၀၁၀'],\n                ['LLL', '၁၄ ဖေဖော်ဝါရီ ၂၀၁၀ ၁၅:၂၅'],\n                ['LLLL', 'တနင်္ဂနွေ ၁၄ ဖေဖော်ဝါရီ ၂၀၁၀ ၁၅:၂၅'],\n                ['l', '၁၄/၂/၂၀၁၀'],\n                ['ll', '၁၄ ဖေ ၂၀၁၀'],\n                ['lll', '၁၄ ဖေ ၂၀၁၀ ၁၅:၂၅'],\n                ['llll', 'နွေ ၁၄ ဖေ ၂၀၁၀ ၁၅:၂၅']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '၁', '၁');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '၂', '၂');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '၃', '၃');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '၄', '၄');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '၅', '၅');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '၆', '၆');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '၇', '၇');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '၈', '၈');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '၉', '၉');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '၁၀', '၁၀');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '၁၁', '၁၁');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '၁၂', '၁၂');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '၁၃', '၁၃');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '၁၄', '၁၄');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '၁၅', '၁၅');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '၁၆', '၁၆');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '၁၇', '၁၇');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '၁၈', '၁၈');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '၁၉', '၁၉');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '၂၀', '၂၀');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '၂၁', '၂၁');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '၂၂', '၂၂');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '၂၃', '၂၃');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '၂၄', '၂၄');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '၂၅', '၂၅');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '၂၆', '၂၆');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '၂၇', '၂၇');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '၂၈', '၂၈');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '၂၉', '၂၉');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '၃၀', '၃၀');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '၃၁', '၃၁');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'ဇန်နဝါရီ ဇန်_ဖေဖော်ဝါရီ ဖေ_မတ် မတ်_ဧပြီ ပြီ_မေ မေ_ဇွန် ဇွန်_ဇူလိုင် လိုင်_သြဂုတ် သြ_စက်တင်ဘာ စက်_အောက်တိုဘာ အောက်_နိုဝင်ဘာ နို_ဒီဇင်ဘာ ဒီ'.split('_'),\n            i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'တနင်္ဂနွေ နွေ နွေ_တနင်္လာ လာ လာ_အင်္ဂါ င်္ဂါ င်္ဂါ_ဗုဒ္ဓဟူး ဟူး ဟူး_ကြာသပတေး ကြာ ကြာ_သောကြာ သော သော_စနေ နေ နေ'.split('_'),\n            i;\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            s: 44\n        }), true), 'စက္ကန်.အနည်းငယ်', '၄၄ စက္ကန်. = စက္ကန်.အနည်းငယ်');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            s: 45\n        }), true), 'တစ်မိနစ်', '၄၅ စက္ကန်. = တစ်မိနစ်');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            s: 89\n        }), true), 'တစ်မိနစ်', '၈၉ စက္ကန်. = တစ်မိနစ်');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            s: 90\n        }), true), '၂ မိနစ်', '၉၀ စက္ကန်. =  ၂ မိနစ်');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            m: 44\n        }), true), '၄၄ မိနစ်', '၄၄ မိနစ် = ၄၄ မိနစ်');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            m: 45\n        }), true), 'တစ်နာရီ', '၄၅ မိနစ် = ၁ နာရီ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            m: 89\n        }), true), 'တစ်နာရီ', '၈၉ မိနစ် = တစ်နာရီ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            m: 90\n        }), true), '၂ နာရီ', 'မိနစ် ၉၀= ၂ နာရီ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            h: 5\n        }), true), '၅ နာရီ', '၅ နာရီ= ၅ နာရီ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            h: 21\n        }), true), '၂၁ နာရီ', '၂၁ နာရီ =၂၁ နာရီ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            h: 22\n        }), true), 'တစ်ရက်', '၂၂ နာရီ =တစ်ရက်');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            h: 35\n        }), true), 'တစ်ရက်', '၃၅ နာရီ =တစ်ရက်');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            h: 36\n        }), true), '၂ ရက်', '၃၆ နာရီ = ၂ ရက်');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 1\n        }), true), 'တစ်ရက်', '၁ ရက်= တစ်ရက်');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 5\n        }), true), '၅ ရက်', '၅ ရက် = ၅ ရက်');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 25\n        }), true), '၂၅ ရက်', '၂၅ ရက်= ၂၅ ရက်');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 26\n        }), true), 'တစ်လ', '၂၆ ရက် = တစ်လ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 30\n        }), true), 'တစ်လ', 'ရက် ၃၀ = တစ်လ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 43\n        }), true), 'တစ်လ', '၄၃ ရက် = တစ်လ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 46\n        }), true), '၂ လ', '၄၆ ရက် = ၂ လ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 74\n        }), true), '၂ လ', '၇၅ ရက်= ၂ လ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 76\n        }), true), '၃ လ', '၇၆ ရက် = ၃ လ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            M: 1\n        }), true), 'တစ်လ', '၁ လ = တစ်လ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            M: 5\n        }), true), '၅ လ', '၅ လ = ၅ လ');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 345\n        }), true), 'တစ်နှစ်', '၃၄၅ ရက် = တစ်နှစ်');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            d: 548\n        }), true), '၂ နှစ်', '၅၄၈ ရက် = ၂ နှစ်');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            y: 1\n        }), true), 'တစ်နှစ်', '၁ နှစ် = တစ်နှစ်');\n        assert.equal(start.from(moment([2007, 1, 28]).add({\n            y: 5\n        }), true), '၅ နှစ်', '၅ နှစ် = ၅ နှစ်');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'လာမည့် စက္ကန်.အနည်းငယ် မှာ', 'prefix');\n        assert.equal(moment(0).from(30000), 'လွန်ခဲ့သော စက္ကန်.အနည်းငယ် က', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'လွန်ခဲ့သော စက္ကန်.အနည်းငယ် က', 'ယခုမှစပြီး အတိတ်တွင်ဖော်ပြသလိုဖော်ပြမည်');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({\n            s: 30\n        }).fromNow(), 'လာမည့် စက္ကန်.အနည်းငယ် မှာ', 'လာမည့် စက္ကန်.အနည်းငယ် မှာ');\n        assert.equal(moment().add({\n            d: 5\n        }).fromNow(), 'လာမည့် ၅ ရက် မှာ', 'လာမည့် ၅ ရက် မှာ');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(), 'ယနေ. ၀၂:၀၀ မှာ', 'ယနေ. ဒီအချိန်');\n        assert.equal(moment(a).add({\n            m: 25\n        }).calendar(), 'ယနေ. ၀၂:၂၅ မှာ', 'ယခုမှ ၂၅ မိနစ်ပေါင်းထည့်');\n        assert.equal(moment(a).add({\n            h: 1\n        }).calendar(), 'ယနေ. ၀၃:၀၀ မှာ', 'ယခုမှ ၁ နာရီပေါင်းထည့်');\n        assert.equal(moment(a).add({\n            d: 1\n        }).calendar(), 'မနက်ဖြန် ၀၂:၀၀ မှာ', 'မနက်ဖြန် ဒီအချိန်');\n        assert.equal(moment(a).subtract({\n            h: 1\n        }).calendar(), 'ယနေ. ၀၁:၀၀ မှာ', 'ယခုမှ ၁ နာရီနှုတ်');\n        assert.equal(moment(a).subtract({\n            d: 1\n        }).calendar(), 'မနေ.က ၀၂:၀၀ မှာ', 'မနေ.က ဒီအချိန်');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({\n                d: i\n            });\n            assert.equal(m.calendar(), m.format('dddd LT [မှာ]'), 'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(), m.format('dddd LT [မှာ]'), 'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(), m.format('dddd LT [မှာ]'), 'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({\n                d: i\n            });\n            assert.equal(m.calendar(), m.format('[ပြီးခဲ့သော] dddd LT [မှာ]'), 'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(), m.format('[ပြီးခဲ့သော] dddd LT [မှာ]'), 'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(), m.format('[ပြီးခဲ့သော] dddd LT [မှာ]'), 'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({\n                w: 1\n            }),\n            weeksFromNow = moment().add({\n                w: 1\n            });\n\n        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), 'လွန်ခဲ့သော ၁ ပတ်က');\n        assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), '၁ ပတ်အတွင်း');\n\n        weeksAgo = moment().subtract({\n            w: 2\n        });\n        weeksFromNow = moment().add({\n            w: 2\n        });\n\n        assert.equal(weeksAgo.calendar(), weeksAgo.format('L'), '၂ ပတ် အရင်က');\n        assert.equal(weeksFromNow.calendar(), weeksFromNow.format('L'), '၂ ပတ် အတွင်း');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(), 1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(), 1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(), 2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(), 1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(), 2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008, 0, 1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008, 0, 6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008, 0, 7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008, 0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008, 0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003, 0, 1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003, 0, 5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003, 0, 6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003, 0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003, 0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009, 0, 1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009, 0, 4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009, 0, 5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009, 0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009, 0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010, 0, 1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010, 0, 3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010, 0, 4]).week(), 1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010, 0, 10]).week(), 1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010, 0, 11]).week(), 2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011, 0, 1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011, 0, 2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011, 0, 3]).week(), 1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011, 0, 9]).week(), 1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011, 0, 10]).week(), 2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0, 1]).format('w ww wo'), '၅၂ ၅၂ ၅၂', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).format('w ww wo'), '၁ ၀၁ ၁', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).format('w ww wo'), '၁ ၀၁ ၁', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).format('w ww wo'), '၂ ၀၂ ၂', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'), '၂ ၀၂ ၂', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('nb');\n\n    test('parse', function (assert) {\n        var tests = 'januar jan_februar feb_mars mar_april apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'),\n            i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'søndag, februar 14. 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'søn, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14. 14'],\n                ['d do dddd ddd dd',                   '0 0. søndag søn sø'],\n                ['DDD DDDo DDDD',                      '45 45. 045'],\n                ['w wo ww',                            '6 6. 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[den] DDDo [dagen i året]',          'den 45. dagen i året'],\n                ['LTS',                                '15.25.50'],\n                ['L',                                  '14.02.2010'],\n                ['LL',                                 '14. februar 2010'],\n                ['LLL',                                '14. februar 2010 kl. 15.25'],\n                ['LLLL',                               'søndag 14. februar 2010 kl. 15.25'],\n                ['l',                                  '14.2.2010'],\n                ['ll',                                 '14. feb 2010'],\n                ['lll',                                '14. feb 2010 kl. 15.25'],\n                ['llll',                               'søn 14. feb 2010 kl. 15.25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'januar jan_februar feb_mars mar_april apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'søndag søn sø_mandag man ma_tirsdag tirs ti_onsdag ons on_torsdag tors to_fredag fre fr_lørdag lør lø'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'noen sekunder', '44 sekunder = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ett minutt',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ett minutt',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutter',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutter',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'en time',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'en time',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timer',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timer',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timer',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dag',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dag',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dager',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dag',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dager',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dager',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en måned',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en måned',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en måned',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 måneder',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 måneder',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 måneder',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en måned',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 måneder',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ett år',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ett år',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'om noen sekunder',  'prefix');\n        assert.equal(moment(0).from(30000), 'for noen sekunder siden', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'for noen sekunder siden',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'om noen sekunder', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dager', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'i dag kl. 2.00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'i dag kl. 2.25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'i dag kl. 3.00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'i morgen kl. 2.00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'i dag kl. 1.00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'i går kl. 2.00',     'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [kl.] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[forrige] dddd [kl.] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[forrige] dddd [kl.] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[forrige] dddd [kl.] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1.', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1.', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2.', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2.', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('ne');\n\n    test('parse', function (assert) {\n        var tests = 'जनवरी जन._फेब्रुवरी फेब्रु._मार्च मार्च_अप्रिल अप्रि._मई मई_जुन जुन_जुलाई जुलाई._अगष्ट अग._सेप्टेम्बर सेप्ट._अक्टोबर अक्टो._नोभेम्बर नोभे._डिसेम्बर डिसे.'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, aको h:mm:ss बजे',       'आइतबार, १४ फेब्रुवरी २०१०, बेलुकाको ३:२५:५० बजे'],\n                ['ddd, aको h बजे',                                                      'आइत., बेलुकाको ३ बजे'],\n                ['M Mo MM MMMM MMM',                   '२ २ ०२ फेब्रुवरी फेब्रु.'],\n                ['YYYY YY',                            '२०१० १०'],\n                ['D Do DD',                            '१४ १४ १४'],\n                ['d do dddd ddd dd',                   '० ० आइतबार आइत. आइ.'],\n                ['DDD DDDo DDDD',                      '४५ ४५ ०४५'],\n                ['w wo ww',                            '७ ७ ०७'],\n                ['h hh',                               '३ ०३'],\n                ['H HH',                               '१५ १५'],\n                ['m mm',                               '२५ २५'],\n                ['s ss',                               '५० ५०'],\n                ['a A',                                'बेलुका बेलुका'],\n                ['LTS',                                'बेलुकाको ३:२५:५० बजे'],\n                ['L',                                  '१४/०२/२०१०'],\n                ['LL',                                 '१४ फेब्रुवरी २०१०'],\n                ['LLL',                                '१४ फेब्रुवरी २०१०, बेलुकाको ३:२५ बजे'],\n                ['LLLL',                               'आइतबार, १४ फेब्रुवरी २०१०, बेलुकाको ३:२५ बजे'],\n                ['l',                                  '१४/२/२०१०'],\n                ['ll',                                 '१४ फेब्रु. २०१०'],\n                ['lll',                                '१४ फेब्रु. २०१०, बेलुकाको ३:२५ बजे'],\n                ['llll',                               'आइत., १४ फेब्रु. २०१०, बेलुकाको ३:२५ बजे']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '१', '१');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '२', '२');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '३', '३');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '४', '४');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '५', '५');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '६', '६');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '७', '७');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '८', '८');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '९', '९');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '१०', '१०');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '११', '११');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '१२', '१२');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '१३', '१३');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '१४', '१४');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '१५', '१५');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '१६', '१६');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '१७', '१७');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '१८', '१८');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '१९', '१९');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '२०', '२०');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '२१', '२१');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '२२', '२२');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '२३', '२३');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '२४', '२४');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '२५', '२५');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '२६', '२६');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '२७', '२७');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '२८', '२८');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '२९', '२९');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '३०', '३०');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '३१', '३१');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'जनवरी जन._फेब्रुवरी फेब्रु._मार्च मार्च_अप्रिल अप्रि._मई मई_जुन जुन_जुलाई जुलाई._अगष्ट अग._सेप्टेम्बर सेप्ट._अक्टोबर अक्टो._नोभेम्बर नोभे._डिसेम्बर डिसे.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'आइतबार आइत. आइ._सोमबार सोम. सो._मङ्गलबार मङ्गल. मङ्_बुधबार बुध. बु._बिहिबार बिहि. बि._शुक्रबार शुक्र. शु._शनिबार शनि. श.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'केही समय', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'एक मिनेट',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'एक मिनेट',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '२ मिनेट',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '४४ मिनेट',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'एक घण्टा',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'एक घण्टा',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '२ घण्टा',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '५ घण्टा',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '२१ घण्टा',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'एक दिन',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'एक दिन',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '२ दिन',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'एक दिन',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '५ दिन',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '२५ दिन',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'एक महिना',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'एक महिना',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'एक महिना',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '२ महिना',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '२ महिना',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '३ महिना',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'एक महिना',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '५ महिना',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'एक बर्ष',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '२ बर्ष',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'एक बर्ष',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '५ बर्ष',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'केही समयमा',  'prefix');\n        assert.equal(moment(0).from(30000), 'केही समय अगाडी', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'केही समय अगाडी',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'केही समयमा', 'केही समयमा');\n        assert.equal(moment().add({d: 5}).fromNow(), '५ दिनमा', '५ दिनमा');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'आज रातीको २:०० बजे',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'आज रातीको २:२५ बजे',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'आज बिहानको ३:०० बजे',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'भोली रातीको २:०० बजे',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'आज रातीको १:०० बजे',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'हिजो रातीको २:०० बजे', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('[आउँदो] dddd[,] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[आउँदो] dddd[,] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[आउँदो] dddd[,] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[गएको] dddd[,] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[गएको] dddd[,] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[गएको] dddd[,] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('meridiem', function (assert) {\n        assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), 'राती', 'before dawn');\n        assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), 'बिहान', 'morning');\n        assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), 'दिउँसो', 'during day');\n        assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), 'बेलुका', 'evening');\n        assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), 'साँझ', 'late evening');\n        assert.equal(moment([2011, 2, 23, 21, 20]).format('a'), 'राती', 'night');\n\n        assert.equal(moment([2011, 2, 23,  2, 30]).format('A'), 'राती', 'before dawn');\n        assert.equal(moment([2011, 2, 23,  9, 30]).format('A'), 'बिहान', 'morning');\n        assert.equal(moment([2011, 2, 23, 14, 30]).format('A'), 'दिउँसो', 'during day');\n        assert.equal(moment([2011, 2, 23, 17, 30]).format('A'), 'बेलुका', 'evening');\n        assert.equal(moment([2011, 2, 23, 19, 30]).format('A'), 'साँझ', 'late evening');\n        assert.equal(moment([2011, 2, 23, 21, 20]).format('A'), 'राती', 'night');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '१ ०१ १', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '१ ०१ १', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '२ ०२ २', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '२ ०२ २', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '३ ०३ ३', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('nl');\n\n    test('parse', function (assert) {\n        var tests = 'januari jan._februari feb._maart mrt._april apr._mei mei._juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, HH:mm:ss',       'zondag, februari 14de 2010, 15:25:50'],\n                ['ddd, HH',                            'zo., 15'],\n                ['M Mo MM MMMM MMM',                   '2 2de 02 februari feb.'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14de 14'],\n                ['d do dddd ddd dd',                   '0 0de zondag zo. Zo'],\n                ['DDD DDDo DDDD',                      '45 45ste 045'],\n                ['w wo ww',                            '6 6de 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45ste day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14-02-2010'],\n                ['LL',                                 '14 februari 2010'],\n                ['LLL',                                '14 februari 2010 15:25'],\n                ['LLLL',                               'zondag 14 februari 2010 15:25'],\n                ['l',                                  '14-2-2010'],\n                ['ll',                                 '14 feb. 2010'],\n                ['lll',                                '14 feb. 2010 15:25'],\n                ['llll',                               'zo. 14 feb. 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1ste', '1ste');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2de', '2de');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3de', '3de');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4de', '4de');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5de', '5de');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6de', '6de');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7de', '7de');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8ste', '8ste');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9de', '9de');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10de', '10de');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11de', '11de');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12de', '12de');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13de', '13de');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14de', '14de');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15de', '15de');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16de', '16de');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17de', '17de');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18de', '18de');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19de', '19de');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20ste', '20ste');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21ste', '21ste');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22ste', '22ste');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23ste', '23ste');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24ste', '24ste');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25ste', '25ste');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26ste', '26ste');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27ste', '27ste');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28ste', '28ste');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29ste', '29ste');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30ste', '30ste');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31ste', '31ste');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'januari jan._februari feb._maart mrt._april apr._mei mei_juni jun._juli jul._augustus aug._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'zondag zo. Zo_maandag ma. Ma_dinsdag di. Di_woensdag wo. Wo_donderdag do. Do_vrijdag vr. Vr_zaterdag za. Za'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'een paar seconden', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'één minuut',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'één minuut',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuten',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuten',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'één uur',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'één uur',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 uur',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 uur',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 uur',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'één dag',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'één dag',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagen',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'één dag',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagen',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagen',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'één maand',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'één maand',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'één maand',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 maanden',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 maanden',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 maanden',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'één maand',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 maanden',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'één jaar',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 jaar',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'één jaar',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 jaar',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'over een paar seconden',  'prefix');\n        assert.equal(moment(0).from(30000), 'een paar seconden geleden', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'een paar seconden geleden',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'over een paar seconden', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'over 5 dagen', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'vandaag om 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'vandaag om 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'vandaag om 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'morgen om 02:00',    'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'vandaag om 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'gisteren om 02:00',   'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [om] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[afgelopen] dddd [om] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('month abbreviation', function (assert) {\n        assert.equal(moment([2012, 5, 23]).format('D-MMM-YYYY'), '23-jun-2012', 'format month abbreviation surrounded by dashes should not include a dot');\n        assert.equal(moment([2012, 5, 23]).format('D MMM YYYY'), '23 jun. 2012', 'format month abbreviation not surrounded by dashes should include a dot');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52ste', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1ste', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1ste', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),    '2 02 2de', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),    '2 02 2de', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('nn');\n\n    test('parse', function (assert) {\n        var tests = 'januar jan_februar feb_mars mar_april apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'sundag, februar 14. 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'sun, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14. 14'],\n                ['d do dddd ddd dd',                   '0 0. sundag sun su'],\n                ['DDD DDDo DDDD',                      '45 45. 045'],\n                ['w wo ww',                            '6 6. 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14.02.2010'],\n                ['LL',                                 '14 februar 2010'],\n                ['LLL',                                '14 februar 2010 15:25'],\n                ['LLLL',                               'sundag 14 februar 2010 15:25'],\n                ['l',                                  '14.2.2010'],\n                ['ll',                                 '14 feb 2010'],\n                ['lll',                                '14 feb 2010 15:25'],\n                ['llll',                               'sun 14 feb 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'januar jan_februar feb_mars mar_april apr_mai mai_juni jun_juli jul_august aug_september sep_oktober okt_november nov_desember des'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'sundag sun su_måndag mån må_tysdag tys ty_onsdag ons on_torsdag tor to_fredag fre fr_laurdag lau lø'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nokre sekund', '44 sekunder = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'eit minutt',   '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'eit minutt',   '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutt',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutt',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ein time',     '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ein time',     '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timar',      '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timar',      '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timar',     '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ein dag',      '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ein dag',      '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',      '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ein dag',      '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',      '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',     '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ein månad',    '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ein månad',    '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ein månad',    '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 månader',    '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 månader',    '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 månader',    '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ein månad',    '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 månader',    '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'eit år',       '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',         '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'eit år',       '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',         '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'om nokre sekund',  'prefix');\n        assert.equal(moment(0).from(30000), 'for nokre sekund sidan', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'for nokre sekund sidan',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'om nokre sekund', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dagar', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'I dag klokka 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'I dag klokka 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'I dag klokka 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'I morgon klokka 02:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'I dag klokka 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'I går klokka 02:00',     'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [klokka] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [klokka] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [klokka] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[Føregåande] dddd [klokka] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[Føregåande] dddd [klokka] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[Føregåande] dddd [klokka] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('pl');\n\n    test('parse', function (assert) {\n        var tests = 'styczeń sty_luty lut_marzec mar_kwiecień kwi_maj maj_czerwiec cze_lipiec lip_sierpień sie_wrzesień wrz_październik paź_listopad lis_grudzień gru'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'niedziela, luty 14. 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'nie, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2. 02 luty lut'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14. 14'],\n                ['d do dddd ddd dd',                   '0 0. niedziela nie N'],\n                ['DDD DDDo DDDD',                      '45 45. 045'],\n                ['w wo ww',                            '6 6. 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14.02.2010'],\n                ['LL',                                 '14 lutego 2010'],\n                ['LLL',                                '14 lutego 2010 15:25'],\n                ['LLLL',                               'niedziela, 14 lutego 2010 15:25'],\n                ['l',                                  '14.2.2010'],\n                ['ll',                                 '14 lut 2010'],\n                ['lll',                                '14 lut 2010 15:25'],\n                ['llll',                               'nie, 14 lut 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'styczeń sty_luty lut_marzec mar_kwiecień kwi_maj maj_czerwiec cze_lipiec lip_sierpień sie_wrzesień wrz_październik paź_listopad lis_grudzień gru'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'niedziela nie N_poniedziałek pon Pn_wtorek wt Wt_środa śr Śr_czwartek czw Cz_piątek pt Pt_sobota sb So'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'kilka sekund',  '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuta',        '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuta',        '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuty',      '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuty',     '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'godzina',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'godzina',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 godziny',     '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 godzin',      '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 godzin',     '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 dzień',       '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 dzień',       '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dni',         '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 dzień',       '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dni',         '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dni',        '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'miesiąc',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'miesiąc',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'miesiąc',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 miesiące',    '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 miesiące',    '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 miesiące',    '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'miesiąc',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 miesięcy',    '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'rok',           '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 lata',        '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'rok',           '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 lat',         '5 years = 5 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 112}), true), '112 lat',       '112 years = 112 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 122}), true), '122 lata',      '122 years = 122 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 213}), true), '213 lat',       '213 years = 213 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 223}), true), '223 lata',      '223 years = 223 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'za kilka sekund',  'prefix');\n        assert.equal(moment(0).from(30000), 'kilka sekund temu', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'kilka sekund temu',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'za kilka sekund', 'in a few seconds');\n        assert.equal(moment().add({h: 1}).fromNow(), 'za godzinę', 'in an hour');\n        assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dni', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Dziś o 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Dziś o 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Dziś o 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Jutro o 02:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Dziś o 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Wczoraj o 02:00',     'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('[W] dddd [o] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[W] dddd [o] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[W] dddd [o] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        function makeFormat(d) {\n            switch (d.day()) {\n            case 0:\n                return '[W zeszłą niedzielę o] LT';\n            case 3:\n                return '[W zeszłą środę o] LT';\n            case 6:\n                return '[W zeszłą sobotę o] LT';\n            default:\n                return '[W zeszły] dddd [o] LT';\n            }\n        }\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(), m.format(makeFormat(m)), 'Today - ' + i + ' days current time');\n\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(), m.format(makeFormat(m)), 'Today - ' + i + ' days beginning of day');\n\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(), m.format(makeFormat(m)), 'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('pt-br');\n\n    test('parse', function (assert) {\n        var tests = 'janeiro jan_fevereiro fev_março mar_abril abr_maio mai_junho jun_julho jul_agosto ago_setembro set_outubro out_novembro nov_dezembro dez'.split('_'), i;\n\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'domingo, fevereiro 14º 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'dom, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2º 02 fevereiro fev'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14º 14'],\n                ['d do dddd ddd',                      '0 0º domingo dom'],\n                ['DDD DDDo DDDD',                      '45 45º 045'],\n                ['w wo ww',                            '8 8º 08'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 de fevereiro de 2010'],\n                ['LLL',                                '14 de fevereiro de 2010 às 15:25'],\n                ['LLLL',                               'domingo, 14 de fevereiro de 2010 às 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 de fev de 2010'],\n                ['lll',                                '14 de fev de 2010 às 15:25'],\n                ['llll',                               'dom, 14 de fev de 2010 às 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'janeiro jan_fevereiro fev_março mar_abril abr_maio mai_junho jun_julho jul_agosto ago_setembro set_outubro out_novembro nov_dezembro dez'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'domingo dom_segunda-feira seg_terça-feira ter_quarta-feira qua_quinta-feira qui_sexta-feira sex_sábado sáb'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'segundos',    '44 seconds = seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'um minuto',   '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'um minuto',   '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',  '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'uma hora',    '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'uma hora',    '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',    '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',    '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',   '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'um dia',      '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'um dia',      '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dias',     '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'um dia',      '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dias',     '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dias',    '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'um mês',    '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'um mês',    '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'um mês',    '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',   '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',   '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',   '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'um mês',    '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',   '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'um ano',     '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anos',    '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'um ano',     '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anos',    '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'em segundos', 'prefix');\n        assert.equal(moment(0).from(30000), 'segundos atrás', 'suffix');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'em segundos', 'in seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'em 5 dias', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Hoje às 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Hoje às 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Hoje às 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Amanhã às 02:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hoje às 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ontem às 02:00',     'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n        assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n        assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n        assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n        assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday format', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1º', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1º', 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2º', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2º', 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3º', 'Jan 15 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('pt');\n\n    test('parse', function (assert) {\n        var tests = 'Janeiro Jan_Fevereiro Fev_Março Mar_Abril Abr_Maio Mai_Junho Jun_Julho Jul_Agosto Ago_Setembro Set_Outubro Out_Novembro Nov_Dezembro Dez'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'domingo, fevereiro 14º 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'dom, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2º 02 fevereiro fev'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14º 14'],\n                ['d do dddd ddd dd',                   '0 0º domingo dom dom'],\n                ['DDD DDDo DDDD',                      '45 45º 045'],\n                ['w wo ww',                            '6 6º 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45º day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 de fevereiro de 2010'],\n                ['LLL',                                '14 de fevereiro de 2010 15:25'],\n                ['LLLL',                               'domingo, 14 de fevereiro de 2010 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 de fev de 2010'],\n                ['lll',                                '14 de fev de 2010 15:25'],\n                ['llll',                               'dom, 14 de fev de 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1º', '1º');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2º', '2º');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3º', '3º');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4º', '4º');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5º', '5º');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6º', '6º');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7º', '7º');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8º', '8º');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9º', '9º');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10º', '10º');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11º', '11º');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12º', '12º');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13º', '13º');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14º', '14º');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15º', '15º');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16º', '16º');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17º', '17º');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18º', '18º');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19º', '19º');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20º', '20º');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21º', '21º');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22º', '22º');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23º', '23º');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24º', '24º');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25º', '25º');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26º', '26º');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27º', '27º');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28º', '28º');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29º', '29º');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30º', '30º');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31º', '31º');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'janeiro jan_fevereiro fev_março mar_abril abr_maio mai_junho jun_julho jul_agosto ago_setembro set_outubro out_novembro nov_dezembro dez'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'domingo dom dom_segunda-feira seg 2ª_terça-feira ter 3ª_quarta-feira qua 4ª_quinta-feira qui 5ª_sexta-feira sex 6ª_sábado sáb sáb'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'segundos',    '44 seconds = seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'um minuto',   '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'um minuto',   '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minutos',  '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minutos', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'uma hora',    '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'uma hora',    '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 horas',    '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 horas',    '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 horas',   '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'um dia',      '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'um dia',      '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dias',     '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'um dia',      '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dias',     '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dias',    '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'um mês',    '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'um mês',    '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'um mês',    '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meses',   '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meses',   '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meses',   '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'um mês',    '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meses',   '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'um ano',     '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 anos',    '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'um ano',     '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 anos',    '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'em segundos', 'prefix');\n        assert.equal(moment(0).from(30000), 'há segundos', 'suffix');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'em segundos', 'in seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'em 5 dias', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Hoje às 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Hoje às 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Hoje às 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Amanhã às 02:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hoje às 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Ontem às 02:00',     'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [às] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format((m.day() === 0 || m.day() === 6) ? '[Último] dddd [às] LT' : '[Última] dddd [às] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52º', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),  '1 01 1º', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),  '1 01 1º', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),  '2 02 2º', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),  '2 02 2º', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('ro');\n\n    test('parse', function (assert) {\n        var tests = 'ianuarie ian._februarie febr._martie mart._aprilie apr._mai mai_iunie iun._iulie iul._august aug._septembrie sept._octombrie oct._noiembrie nov._decembrie dec.'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss A',  'duminică, februarie 14 2010, 3:25:50 PM'],\n                ['ddd, hA',                        'Dum, 3PM'],\n                ['M Mo MM MMMM MMM',               '2 2 02 februarie febr.'],\n                ['YYYY YY',                        '2010 10'],\n                ['D Do DD',                        '14 14 14'],\n                ['d do dddd ddd dd',               '0 0 duminică Dum Du'],\n                ['DDD DDDo DDDD',                  '45 45 045'],\n                ['w wo ww',                        '7 7 07'],\n                ['h hh',                           '3 03'],\n                ['H HH',                           '15 15'],\n                ['m mm',                           '25 25'],\n                ['s ss',                           '50 50'],\n                ['a A',                            'pm PM'],\n                ['[a] DDDo[a zi a anului]',        'a 45a zi a anului'],\n                ['LTS',                            '15:25:50'],\n                ['L',                              '14.02.2010'],\n                ['LL',                             '14 februarie 2010'],\n                ['LLL',                            '14 februarie 2010 15:25'],\n                ['LLLL',                           'duminică, 14 februarie 2010 15:25'],\n                ['l',                              '14.2.2010'],\n                ['ll',                             '14 febr. 2010'],\n                ['lll',                            '14 febr. 2010 15:25'],\n                ['llll',                           'Dum, 14 febr. 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'ianuarie ian._februarie febr._martie mart._aprilie apr._mai mai_iunie iun._iulie iul._august aug._septembrie sept._octombrie oct._noiembrie nov._decembrie dec.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'duminică Dum Du_luni Lun Lu_marți Mar Ma_miercuri Mie Mi_joi Joi Jo_vineri Vin Vi_sâmbătă Sâm Sâ'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'câteva secunde', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'un minut',       '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'un minut',       '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',       '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 de minute',   '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'o oră',          '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'o oră',          '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ore',          '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ore',          '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 de ore',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'o zi',           '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'o zi',           '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 zile',         '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'o zi',           '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 zile',         '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 de zile',     '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'o lună',         '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'o lună',         '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'o lună',         '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 luni',         '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 luni',         '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 luni',         '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'o lună',         '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 luni',         '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'un an',          '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ani',          '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'un an',          '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ani',          '5 years = 5 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 19}), true),   '19 ani',        '19 years = 19 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 20}), true),   '20 de ani',     '20 years = 20 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 100}), true),   '100 de ani',   '100 years = 100 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 101}), true),   '101 ani',      '101 years = 101 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 119}), true),   '119 ani',      '119 years = 119 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 120}), true),   '120 de ani',   '120 years = 120 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 219}), true),   '219 ani',      '219 years = 219 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 220}), true),   '220 de ani',   '220 years = 220 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'peste câteva secunde',   'prefix');\n        assert.equal(moment(0).from(30000), 'câteva secunde în urmă', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'câteva secunde în urmă',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'peste câteva secunde', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'peste 5 zile', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'azi la 2:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'azi la 2:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'azi la 3:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'mâine la 2:00',   'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'azi la 1:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'ieri la 2:00',    'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [la] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [la] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [la] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[fosta] dddd [la] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[fosta] dddd [la] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[fosta] dddd [la] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('ru');\n\n    test('parse', function (assert) {\n        var tests = 'январь янв_февраль фев_март март_апрель апр_май май_июнь июнь_июль июль_август авг_сентябрь сен_октябрь окт_ноябрь ноя_декабрь дек'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('parse exceptional case', function (assert) {\n        assert.equal(moment('11 мая 1989', ['DD MMMM YYYY']).format('DD-MM-YYYY'), '11-05-1989');\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, HH:mm:ss',       'воскресенье, 14-го февраля 2010, 15:25:50'],\n                ['ddd, h A',                           'вс, 3 дня'],\n                ['M Mo MM MMMM MMM',                   '2 2-й 02 февраль фев'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14-го 14'],\n                ['d do dddd ddd dd',                   '0 0-й воскресенье вс вс'],\n                ['DDD DDDo DDDD',                      '45 45-й 045'],\n                ['w wo ww',                            '7 7-я 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'дня дня'],\n                ['DDDo [день года]',                   '45-й день года'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14.02.2010'],\n                ['LL',                                 '14 февраля 2010 г.'],\n                ['LLL',                                '14 февраля 2010 г., 15:25'],\n                ['LLLL',                               'воскресенье, 14 февраля 2010 г., 15:25'],\n                ['l',                                  '14.2.2010'],\n                ['ll',                                 '14 фев 2010 г.'],\n                ['lll',                                '14 фев 2010 г., 15:25'],\n                ['llll',                               'вс, 14 фев 2010 г., 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format meridiem', function (assert) {\n        assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'ночи', 'night');\n        assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'ночи', 'night');\n        assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'утра', 'morning');\n        assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'утра', 'morning');\n        assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'дня', 'afternoon');\n        assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'дня', 'afternoon');\n        assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'вечера', 'evening');\n        assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'вечера', 'evening');\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-й', '1-й');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-й', '2-й');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-й', '3-й');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-й', '4-й');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-й', '5-й');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-й', '6-й');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-й', '7-й');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-й', '8-й');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-й', '9-й');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-й', '10-й');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-й', '11-й');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-й', '12-й');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-й', '13-й');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-й', '14-й');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-й', '15-й');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-й', '16-й');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-й', '17-й');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-й', '18-й');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-й', '19-й');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-й', '20-й');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-й', '21-й');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-й', '22-й');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-й', '23-й');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-й', '24-й');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-й', '25-й');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-й', '26-й');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-й', '27-й');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-й', '28-й');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-й', '29-й');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-й', '30-й');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-й', '31-й');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'январь янв_февраль фев_март март_апрель апр_май май_июнь июнь_июль июль_август авг_сентябрь сен_октябрь окт_ноябрь ноя_декабрь дек'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format month case', function (assert) {\n        var months = {\n            'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n            'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')\n        }, i;\n        for (i = 0; i < 12; i++) {\n            assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n            assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n        }\n    });\n\n    test('format month short case', function (assert) {\n        var monthsShort = {\n            'nominative': 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),\n            'accusative': 'янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек'.split('_')\n        }, i;\n        for (i = 0; i < 12; i++) {\n            assert.equal(moment([2011, i, 1]).format('D MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n            assert.equal(moment([2011, i, 1]).format('MMM'), monthsShort.nominative[i], '1 ' + monthsShort.nominative[i]);\n        }\n    });\n\n    test('format month case with escaped symbols', function (assert) {\n        var months = {\n            'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n            'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')\n        }, i;\n        for (i = 0; i < 12; i++) {\n            assert.equal(moment([2013, i, 1]).format('D[] MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n            assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMMM[</b>]'), '<i>1</i> <b>' + months.accusative[i] + '</b>', '1 <b>' + months.accusative[i] + '</b>');\n            assert.equal(moment([2013, i, 1]).format('D[-й день] MMMM'), '1-й день ' + months.accusative[i], '1-й день ' + months.accusative[i]);\n            assert.equal(moment([2013, i, 1]).format('D, MMMM'), '1, ' + months.nominative[i], '1, ' + months.nominative[i]);\n        }\n    });\n\n    test('format month short case with escaped symbols', function (assert) {\n        var monthsShort = {\n            'nominative': 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),\n            'accusative': 'янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек'.split('_')\n        }, i;\n        for (i = 0; i < 12; i++) {\n            assert.equal(moment([2013, i, 1]).format('D[] MMM'), '1 ' + monthsShort.accusative[i], '1 ' + monthsShort.accusative[i]);\n            assert.equal(moment([2013, i, 1]).format('[<i>]D[</i>] [<b>]MMM[</b>]'), '<i>1</i> <b>' + monthsShort.accusative[i] + '</b>', '1 <b>' + monthsShort.accusative[i] + '</b>');\n            assert.equal(moment([2013, i, 1]).format('D[-й день] MMM'), '1-й день ' + monthsShort.accusative[i], '1-й день ' + monthsShort.accusative[i]);\n            assert.equal(moment([2013, i, 1]).format('D, MMM'), '1, ' + monthsShort.nominative[i], '1, ' + monthsShort.nominative[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'воскресенье вс вс_понедельник пн пн_вторник вт вт_среда ср ср_четверг чт чт_пятница пт пт_суббота сб сб'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'несколько секунд',    '44 seconds = seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'минута',   '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'минута',   '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минуты',  '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 31}), true),  '31 минута',  '31 minutes = 31 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минуты', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'час',    '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'час',    '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 часа',    '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 часов',    '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 час',   '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'день',      '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'день',      '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дня',     '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'день',      '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дней',     '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 дней',     '11 days = 11 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 день',     '21 days = 21 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дней',    '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месяц',    '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месяц',    '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месяц',    '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месяца',   '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месяца',   '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месяца',   '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месяц',    '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месяцев',   '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'год',     '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 года',    '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'год',     '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 лет',    '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'через несколько секунд', 'prefix');\n        assert.equal(moment(0).from(30000), 'несколько секунд назад', 'suffix');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'через несколько секунд', 'in seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'через 5 дней', 'in 5 days');\n        assert.equal(moment().add({m: 31}).fromNow(), 'через 31 минуту', 'in 31 minutes = in 31 minutes');\n        assert.equal(moment().subtract({m: 31}).fromNow(), '31 минуту назад', '31 minutes ago = 31 minutes ago');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Сегодня в 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Сегодня в 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Сегодня в 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Завтра в 02:00',      'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Сегодня в 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчера в 02:00',       'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        function makeFormat(d) {\n            return d.day() === 2 ? '[Во] dddd [в] LT' : '[В] dddd [в] LT';\n        }\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m, now;\n\n        function makeFormatLast(d) {\n            switch (d.day()) {\n            case 0:\n                return '[В прошлое] dddd [в] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[В прошлый] dddd [в] LT';\n            case 3:\n            case 5:\n            case 6:\n                return '[В прошлую] dddd [в] LT';\n            }\n        }\n\n        function makeFormatThis(d) {\n            switch (d.day()) {\n            case 2:\n                return '[Во] dddd [в] LT';\n            case 0:\n            case 1:\n            case 3:\n            case 4:\n            case 5:\n            case 6:\n                return '[В] dddd [в] LT';\n            }\n        }\n\n        now = moment().startOf('week');\n        for (i = 2; i < 7; i++) {\n            m = moment(now).subtract({d: i});\n            assert.equal(m.calendar(now),       m.format(makeFormatLast(m)),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(now),       m.format(makeFormatLast(m)),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(now),       m.format(makeFormatLast(m)),  'Today - ' + i + ' days end of day');\n        }\n\n        now = moment().endOf('week');\n        for (i = 2; i < 7; i++) {\n            m = moment(now).subtract({d: i});\n            assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(now),       m.format(makeFormatThis(m)),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-я', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-я', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-я', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-я', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-я', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('sk');\n\n    test('parse', function (assert) {\n        var tests = 'január jan._február feb._marec mar._apríl apr._máj máj_jún jún._júl júl._august aug._september sep._október okt._november nov._december dec.'.split('_'), i;\n        function equalTest(input, mmm, monthIndex) {\n            assert.equal(moment(input, mmm).month(), monthIndex, input + ' should be month ' + (monthIndex + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss',  'nedeľa, február 14. 2010, 3:25:50'],\n                ['ddd, h',                       'ne, 3'],\n                ['M Mo MM MMMM MMM',             '2 2. 02 február feb'],\n                ['YYYY YY',                      '2010 10'],\n                ['D Do DD',                      '14 14. 14'],\n                ['d do dddd ddd dd',             '0 0. nedeľa ne ne'],\n                ['DDD DDDo DDDD',                '45 45. 045'],\n                ['w wo ww',                      '6 6. 06'],\n                ['h hh',                         '3 03'],\n                ['H HH',                         '15 15'],\n                ['m mm',                         '25 25'],\n                ['s ss',                         '50 50'],\n                ['a A',                          'pm PM'],\n                ['DDDo [deň v roku]',            '45. deň v roku'],\n                ['LTS',                          '15:25:50'],\n                ['L',                            '14.02.2010'],\n                ['LL',                           '14. február 2010'],\n                ['LLL',                          '14. február 2010 15:25'],\n                ['LLLL',                         'nedeľa 14. február 2010 15:25'],\n                ['l',                            '14.2.2010'],\n                ['ll',                           '14. feb 2010'],\n                ['lll',                          '14. feb 2010 15:25'],\n                ['llll',                         'ne 14. feb 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'január jan_február feb_marec mar_apríl apr_máj máj_jún jún_júl júl_august aug_september sep_október okt_november nov_december dec'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'nedeľa ne ne_pondelok po po_utorok ut ut_streda st st_štvrtok št št_piatok pi pi_sobota so so'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'pár sekúnd',  '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minúta',        '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minúta',        '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minúty',      '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minút',     '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'hodina',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'hodina',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 hodiny',     '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 hodín',      '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 hodín',     '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'deň',       '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'deň',       '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dni',         '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'deň',       '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dní',         '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dní',        '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mesiac',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mesiac',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mesiac',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 mesiace',    '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 mesiace',    '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesiace',    '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mesiac',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesiacov',    '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'rok',           '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 roky',        '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'rok',           '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 rokov',         '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'za pár sekúnd',  'prefix');\n        assert.equal(moment(0).from(30000), 'pred pár sekundami', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'pred pár sekundami',  'now from now should display as in the past');\n    });\n\n    test('fromNow (future)', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'za pár sekúnd', 'in a few seconds');\n        assert.equal(moment().add({m: 1}).fromNow(), 'za minútu', 'in a minute');\n        assert.equal(moment().add({m: 3}).fromNow(), 'za 3 minúty', 'in 3 minutes');\n        assert.equal(moment().add({m: 10}).fromNow(), 'za 10 minút', 'in 10 minutes');\n        assert.equal(moment().add({h: 1}).fromNow(), 'za hodinu', 'in an hour');\n        assert.equal(moment().add({h: 3}).fromNow(), 'za 3 hodiny', 'in 3 hours');\n        assert.equal(moment().add({h: 10}).fromNow(), 'za 10 hodín', 'in 10 hours');\n        assert.equal(moment().add({d: 1}).fromNow(), 'za deň', 'in a day');\n        assert.equal(moment().add({d: 3}).fromNow(), 'za 3 dni', 'in 3 days');\n        assert.equal(moment().add({d: 10}).fromNow(), 'za 10 dní', 'in 10 days');\n        assert.equal(moment().add({M: 1}).fromNow(), 'za mesiac', 'in a month');\n        assert.equal(moment().add({M: 3}).fromNow(), 'za 3 mesiace', 'in 3 months');\n        assert.equal(moment().add({M: 10}).fromNow(), 'za 10 mesiacov', 'in 10 months');\n        assert.equal(moment().add({y: 1}).fromNow(), 'za rok', 'in a year');\n        assert.equal(moment().add({y: 3}).fromNow(), 'za 3 roky', 'in 3 years');\n        assert.equal(moment().add({y: 10}).fromNow(), 'za 10 rokov', 'in 10 years');\n    });\n\n    test('fromNow (past)', function (assert) {\n        assert.equal(moment().subtract({s: 30}).fromNow(), 'pred pár sekundami', 'a few seconds ago');\n        assert.equal(moment().subtract({m: 1}).fromNow(), 'pred minútou', 'a minute ago');\n        assert.equal(moment().subtract({m: 3}).fromNow(), 'pred 3 minútami', '3 minutes ago');\n        assert.equal(moment().subtract({m: 10}).fromNow(), 'pred 10 minútami', '10 minutes ago');\n        assert.equal(moment().subtract({h: 1}).fromNow(), 'pred hodinou', 'an hour ago');\n        assert.equal(moment().subtract({h: 3}).fromNow(), 'pred 3 hodinami', '3 hours ago');\n        assert.equal(moment().subtract({h: 10}).fromNow(), 'pred 10 hodinami', '10 hours ago');\n        assert.equal(moment().subtract({d: 1}).fromNow(), 'pred dňom', 'a day ago');\n        assert.equal(moment().subtract({d: 3}).fromNow(), 'pred 3 dňami', '3 days ago');\n        assert.equal(moment().subtract({d: 10}).fromNow(), 'pred 10 dňami', '10 days ago');\n        assert.equal(moment().subtract({M: 1}).fromNow(), 'pred mesiacom', 'a month ago');\n        assert.equal(moment().subtract({M: 3}).fromNow(), 'pred 3 mesiacmi', '3 months ago');\n        assert.equal(moment().subtract({M: 10}).fromNow(), 'pred 10 mesiacmi', '10 months ago');\n        assert.equal(moment().subtract({y: 1}).fromNow(), 'pred rokom', 'a year ago');\n        assert.equal(moment().subtract({y: 3}).fromNow(), 'pred 3 rokmi', '3 years ago');\n        assert.equal(moment().subtract({y: 10}).fromNow(), 'pred 10 rokmi', '10 years ago');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'dnes o 2:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'dnes o 2:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'dnes o 3:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'zajtra o 2:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'dnes o 1:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'včera o 2:00',     'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m, nextDay;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            nextDay = '';\n            switch (m.day()) {\n            case 0:\n                nextDay = 'v nedeľu';\n                break;\n            case 1:\n                nextDay = 'v pondelok';\n                break;\n            case 2:\n                nextDay = 'v utorok';\n                break;\n            case 3:\n                nextDay = 'v stredu';\n                break;\n            case 4:\n                nextDay = 'vo štvrtok';\n                break;\n            case 5:\n                nextDay = 'v piatok';\n                break;\n            case 6:\n                nextDay = 'v sobotu';\n                break;\n            }\n            assert.equal(m.calendar(),       m.format('[' + nextDay + '] [o] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[' + nextDay + '] [o] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[' + nextDay + '] [o] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m, lastDay;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            lastDay = '';\n            switch (m.day()) {\n            case 0:\n                lastDay = 'minulú nedeľu';\n                break;\n            case 1:\n                lastDay = 'minulý pondelok';\n                break;\n            case 2:\n                lastDay = 'minulý utorok';\n                break;\n            case 3:\n                lastDay = 'minulú stredu';\n                break;\n            case 4:\n                lastDay = 'minulý štvrtok';\n                break;\n            case 5:\n                lastDay = 'minulý piatok';\n                break;\n            case 6:\n                lastDay = 'minulú sobotu';\n                break;\n            }\n            assert.equal(m.calendar(),       m.format('[' + lastDay + '] [o] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[' + lastDay + '] [o] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[' + lastDay + '] [o] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('humanize duration', function (assert) {\n        assert.equal(moment.duration(1, 'minutes').humanize(), 'minúta', 'a minute (future)');\n        assert.equal(moment.duration(1, 'minutes').humanize(true), 'za minútu', 'in a minute');\n        assert.equal(moment.duration(-1, 'minutes').humanize(), 'minúta', 'a minute (past)');\n        assert.equal(moment.duration(-1, 'minutes').humanize(true), 'pred minútou', 'a minute ago');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('sl');\n\n    test('parse', function (assert) {\n        var tests = 'januar jan._februar feb._marec mar._april apr._maj maj_junij jun._julij jul._avgust avg._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedelja, 14. februar 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'ned., 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14. 14'],\n                ['d do dddd ddd dd',                   '0 0. nedelja ned. ne'],\n                ['DDD DDDo DDDD',                      '45 45. 045'],\n                ['w wo ww',                            '7 7. 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14. 02. 2010'],\n                ['LL',                                 '14. februar 2010'],\n                ['LLL',                                '14. februar 2010 15:25'],\n                ['LLLL',                               'nedelja, 14. februar 2010 15:25'],\n                ['l',                                  '14. 2. 2010'],\n                ['ll',                                 '14. feb. 2010'],\n                ['lll',                                '14. feb. 2010 15:25'],\n                ['llll',                               'ned., 14. feb. 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'januar jan._februar feb._marec mar._april apr._maj maj._junij jun._julij jul._avgust avg._september sep._oktober okt._november nov._december dec.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'nedelja ned. ne_ponedeljek pon. po_torek tor. to_sreda sre. sr_četrtek čet. če_petek pet. pe_sobota sob. so'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nekaj sekund', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ena minuta',   '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ena minuta',   '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuti',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minut',     '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ena ura',      '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ena ura',      '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 uri',        '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ur',         '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ur',        '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dan',       '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dan',       '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dni',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dan',       '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dni',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dni',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en mesec',     '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en mesec',     '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en mesec',     '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meseca',     '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meseca',     '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 mesece',     '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en mesec',     '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 mesecev',    '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'eno leto',     '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 leti',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'eno leto',     '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 let',        '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'čez nekaj sekund',  'prefix');\n        assert.equal(moment(0).from(30000), 'nekaj sekund nazaj', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'nekaj sekund nazaj',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'čez nekaj sekund', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'čez 5 dni', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'danes ob 2:00',  'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'danes ob 2:25',  'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'danes ob 3:00',  'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'jutri ob 2:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'danes ob 1:00',  'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'včeraj ob 2:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n\n        function makeFormat(d) {\n            switch (d.day()) {\n            case 0:\n                return '[v] [nedeljo] [ob] LT';\n            case 3:\n                return '[v] [sredo] [ob] LT';\n            case 6:\n                return '[v] [soboto] [ob] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[v] dddd [ob] LT';\n            }\n        }\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        function makeFormat(d) {\n            switch (d.day()) {\n            case 0:\n            case 3:\n            case 6:\n                return '[prejšnja] dddd [ob] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[prejšnji] dddd [ob] LT';\n            }\n        }\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('sq');\n\n    test('parse', function (assert) {\n        var i,\n            tests = 'Janar Jan_Shkurt Shk_Mars Mar_Prill Pri_Maj Maj_Qershor Qer_Korrik Kor_Gusht Gus_Shtator Sht_Tetor Tet_Nëntor Nën_Dhjetor Dhj'.split('_');\n\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, HH:mm:ss',       'E Diel, Shkurt 14. 2010, 15:25:50'],\n                ['ddd, HH',                            'Die, 15'],\n                ['M Mo MM MMMM MMM',                   '2 2. 02 Shkurt Shk'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14. 14'],\n                ['d do dddd ddd dd',                   '0 0. E Diel Die D'],\n                ['DDD DDDo DDDD',                      '45 45. 045'],\n                ['w wo ww',                            '6 6. 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'MD MD'],\n                ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 Shkurt 2010'],\n                ['LLL',                                '14 Shkurt 2010 15:25'],\n                ['LLLL',                               'E Diel, 14 Shkurt 2010 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 Shk 2010'],\n                ['lll',                                '14 Shk 2010 15:25'],\n                ['llll',                               'Die, 14 Shk 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('meridiem', function (assert) {\n        assert.equal(moment([2011, 2, 23,  0, 0]).format('A'), 'PD', 'before dawn');\n        assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), 'MD', 'noon');\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var i,\n            expected = 'Janar Jan_Shkurt Shk_Mars Mar_Prill Pri_Maj Maj_Qershor Qer_Korrik Kor_Gusht Gus_Shtator Sht_Tetor Tet_Nëntor Nën_Dhjetor Dhj'.split('_');\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var i,\n            expected = 'E Diel Die D_E Hënë Hën H_E Martë Mar Ma_E Mërkurë Mër Më_E Enjte Enj E_E Premte Pre P_E Shtunë Sht Sh'.split('_');\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'disa sekonda', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'një minutë',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'një minutë',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuta',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'një orë',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'një orë',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 orë',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 orë',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 orë',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'një ditë',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'një ditë',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ditë',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'një ditë',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ditë',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ditë',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'një muaj',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'një muaj',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'një muaj',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 muaj',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 muaj',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 muaj',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'një muaj',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 muaj',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'një vit',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 vite',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'një vit',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 vite',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'në disa sekonda',  'prefix');\n        assert.equal(moment(0).from(30000), 'disa sekonda më parë', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'disa sekonda më parë',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'në disa sekonda', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'në 5 ditë', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Sot në 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Sot në 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Sot në 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Nesër në 02:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Sot në 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Dje në 02:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [në] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [në] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [në] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [e kaluar në] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [e kaluar në] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [e kaluar në] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52.', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1.', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1.', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2.', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2.', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('sr-cyrl');\n\n    test('parse', function (assert) {\n        var tests = 'јануар јан._фебруар феб._март мар._април апр._мај мај_јун јун_јул јул_август авг._септембар сеп._октобар окт._новембар нов._децембар дец.'.split('_'),\n            i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, h:mm:ss a',      'недеља, 14. фебруар 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'нед., 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2. 02 фебруар феб.'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14. 14'],\n                ['d do dddd ddd dd',                   '0 0. недеља нед. не'],\n                ['DDD DDDo DDDD',                      '45 45. 045'],\n                ['w wo ww',                            '7 7. 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14. 02. 2010'],\n                ['LL',                                 '14. фебруар 2010'],\n                ['LLL',                                '14. фебруар 2010 15:25'],\n                ['LLLL',                               'недеља, 14. фебруар 2010 15:25'],\n                ['l',                                  '14. 2. 2010'],\n                ['ll',                                 '14. феб. 2010'],\n                ['lll',                                '14. феб. 2010 15:25'],\n                ['llll',                               'нед., 14. феб. 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'јануар јан._фебруар феб._март мар._април апр._мај мај_јун јун_јул јул_август авг._септембар сеп._октобар окт._новембар нов._децембар дец.'.split('_'),\n            i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'недеља нед. не_понедељак пон. по_уторак уто. ут_среда сре. ср_четвртак чет. че_петак пет. пе_субота суб. су'.split('_'),\n            i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'неколико секунди', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'један минут',   '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'један минут',   '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 минуте',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 минута',     '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'један сат',      '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'један сат',      '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 сата',        '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 сати',         '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 сати',        '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'дан',       '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'дан',       '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дана',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'дан',       '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 дана',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 дана',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'месец',     '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'месец',     '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'месец',     '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 месеца',     '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 месеца',     '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 месеца',     '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'месец',     '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 месеци',    '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'годину',     '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 године',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'годину',     '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 година',        '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'за неколико секунди',  'prefix');\n        assert.equal(moment(0).from(30000), 'пре неколико секунди', 'prefix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'пре неколико секунди',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'за неколико секунди', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'за 5 дана', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'данас у 2:00',  'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'данас у 2:25',  'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'данас у 3:00',  'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'сутра у 2:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'данас у 1:00',  'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'јуче у 2:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n\n        function makeFormat(d) {\n            switch (d.day()) {\n            case 0:\n                return '[у] [недељу] [у] LT';\n            case 3:\n                return '[у] [среду] [у] LT';\n            case 6:\n                return '[у] [суботу] [у] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[у] dddd [у] LT';\n            }\n        }\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        function makeFormat(d) {\n            var lastWeekDay = [\n                    '[прошле] [недеље] [у] LT',\n                    '[прошлог] [понедељка] [у] LT',\n                    '[прошлог] [уторка] [у] LT',\n                    '[прошле] [среде] [у] LT',\n                    '[прошлог] [четвртка] [у] LT',\n                    '[прошлог] [петка] [у] LT',\n                    '[прошле] [суботе] [у] LT'\n                ];\n\n            return lastWeekDay[d.day()];\n        }\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('sr');\n\n    test('parse', function (assert) {\n        var tests = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'),\n            i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, h:mm:ss a',      'nedelja, 14. februar 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'ned., 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2. 02 februar feb.'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14. 14'],\n                ['d do dddd ddd dd',                   '0 0. nedelja ned. ne'],\n                ['DDD DDDo DDDD',                      '45 45. 045'],\n                ['w wo ww',                            '7 7. 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45. day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14. 02. 2010'],\n                ['LL',                                 '14. februar 2010'],\n                ['LLL',                                '14. februar 2010 15:25'],\n                ['LLLL',                               'nedelja, 14. februar 2010 15:25'],\n                ['l',                                  '14. 2. 2010'],\n                ['ll',                                 '14. feb. 2010'],\n                ['lll',                                '14. feb. 2010 15:25'],\n                ['llll',                               'ned., 14. feb. 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1.', '1.');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2.', '2.');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3.', '3.');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4.', '4.');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5.', '5.');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6.', '6.');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7.', '7.');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8.', '8.');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9.', '9.');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10.', '10.');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11.', '11.');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12.', '12.');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13.', '13.');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14.', '14.');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15.', '15.');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16.', '16.');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17.', '17.');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18.', '18.');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19.', '19.');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20.', '20.');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21.', '21.');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22.', '22.');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23.', '23.');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24.', '24.');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25.', '25.');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26.', '26.');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27.', '27.');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28.', '28.');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29.', '29.');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30.', '30.');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31.', '31.');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'januar jan._februar feb._mart mar._april apr._maj maj_jun jun_jul jul_avgust avg._septembar sep._oktobar okt._novembar nov._decembar dec.'.split('_'),\n            i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'nedelja ned. ne_ponedeljak pon. po_utorak uto. ut_sreda sre. sr_četvrtak čet. če_petak pet. pe_subota sub. su'.split('_'),\n            i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'nekoliko sekundi', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'jedan minut',   '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'jedan minut',   '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minute',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuta',     '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'jedan sat',      '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'jedan sat',      '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 sata',        '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 sati',         '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 sati',        '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'dan',       '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'dan',       '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dana',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'dan',       '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dana',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dana',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'mesec',     '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'mesec',     '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'mesec',     '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 meseca',     '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 meseca',     '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 meseca',     '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'mesec',     '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 meseci',    '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'godinu',     '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 godine',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'godinu',     '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 godina',        '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'za nekoliko sekundi',  'prefix');\n        assert.equal(moment(0).from(30000), 'pre nekoliko sekundi', 'prefix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'pre nekoliko sekundi',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'za nekoliko sekundi', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'za 5 dana', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'danas u 2:00',  'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'danas u 2:25',  'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'danas u 3:00',  'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'sutra u 2:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'danas u 1:00',  'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'juče u 2:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n\n        function makeFormat(d) {\n            switch (d.day()) {\n            case 0:\n                return '[u] [nedelju] [u] LT';\n            case 3:\n                return '[u] [sredu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n            }\n        }\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        function makeFormat(d) {\n            var lastWeekDay = [\n                    '[prošle] [nedelje] [u] LT',\n                    '[prošlog] [ponedeljka] [u] LT',\n                    '[prošlog] [utorka] [u] LT',\n                    '[prošle] [srede] [u] LT',\n                    '[prošlog] [četvrtka] [u] LT',\n                    '[prošlog] [petka] [u] LT',\n                    '[prošle] [subote] [u] LT'\n                ];\n\n            return lastWeekDay[d.day()];\n        }\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1.', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1.', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2.', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2.', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3.', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('sv');\n\n    test('parse', function (assert) {\n        var tests = 'januari jan_februari feb_mars mar_april apr_maj maj_juni jun_juli jul_augusti aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'söndag, februari 14e 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'sön, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2a 02 februari feb'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14e 14'],\n                ['d do dddd ddd dd',                   '0 0e söndag sön sö'],\n                ['DDD DDDo DDDD',                      '45 45e 045'],\n                ['w wo ww',                            '6 6e 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45e day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '2010-02-14'],\n                ['LL',                                 '14 februari 2010'],\n                ['LLL',                                '14 februari 2010 15:25'],\n                ['LLLL',                               'söndag 14 februari 2010 15:25'],\n                ['l',                                  '2010-2-14'],\n                ['ll',                                 '14 feb 2010'],\n                ['lll',                                '14 feb 2010 15:25'],\n                ['llll',                               'sön 14 feb 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1a', '1a');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2a', '2a');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3e', '3e');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4e', '4e');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5e', '5e');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6e', '6e');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7e', '7e');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8e', '8e');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9e', '9e');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10e', '10e');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11e', '11e');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12e', '12e');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13e', '13e');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14e', '14e');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15e', '15e');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16e', '16e');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17e', '17e');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18e', '18e');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19e', '19e');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20e', '20e');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21a', '21a');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22a', '22a');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23e', '23e');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24e', '24e');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25e', '25e');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26e', '26e');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27e', '27e');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28e', '28e');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29e', '29e');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30e', '30e');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31a', '31a');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'januari jan_februari feb_mars mar_april apr_maj maj_juni jun_juli jul_augusti aug_september sep_oktober okt_november nov_december dec'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'söndag sön sö_måndag mån må_tisdag tis ti_onsdag ons on_torsdag tor to_fredag fre fr_lördag lör lö'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'några sekunder', '44 sekunder = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'en minut',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'en minut',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuter',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuter',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'en timme',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'en timme',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 timmar',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 timmar',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 timmar',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'en dag',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'en dag',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 dagar',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'en dag',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 dagar',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 dagar',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'en månad',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'en månad',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'en månad',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 månader',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 månader',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 månader',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'en månad',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 månader',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ett år',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 år',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ett år',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 år',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'om några sekunder',  'prefix');\n        assert.equal(moment(0).from(30000), 'för några sekunder sedan', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'för några sekunder sedan',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'om några sekunder', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'om 5 dagar', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Idag 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Idag 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Idag 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Imorgon 02:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Idag 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Igår 02:00',     'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[Förra] dddd[en] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[Förra] dddd[en] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[Förra] dddd[en] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52a', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1a', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1a', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2a', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2a', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('ta');\n\n    test('parse', function (assert) {\n        var tests = 'ஜனவரி ஜனவரி_பிப்ரவரி பிப்ரவரி_மார்ச் மார்ச்_ஏப்ரல் ஏப்ரல்_மே மே_ஜூன் ஜூன்_ஜூலை ஜூலை_ஆகஸ்ட் ஆகஸ்ட்_செப்டெம்பர் செப்டெம்பர்_அக்டோபர் அக்டோபர்_நவம்பர் நவம்பர்_டிசம்பர் டிசம்பர்'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a', 'ஞாயிற்றுக்கிழமை, பிப்ரவரி 14வது 2010, 3:25:50  எற்பாடு'],\n                ['ddd, hA',                       'ஞாயிறு, 3 எற்பாடு'],\n                ['M Mo MM MMMM MMM',              '2 2வது 02 பிப்ரவரி பிப்ரவரி'],\n                ['YYYY YY',                       '2010 10'],\n                ['D Do DD',                       '14 14வது 14'],\n                ['d do dddd ddd dd',              '0 0வது ஞாயிற்றுக்கிழமை ஞாயிறு ஞா'],\n                ['DDD DDDo DDDD',                 '45 45வது 045'],\n                ['w wo ww',                       '8 8வது 08'],\n                ['h hh',                          '3 03'],\n                ['H HH',                          '15 15'],\n                ['m mm',                          '25 25'],\n                ['s ss',                          '50 50'],\n                ['a A',                           ' எற்பாடு  எற்பாடு'],\n                ['[ஆண்டின்] DDDo  [நாள்]', 'ஆண்டின் 45வது  நாள்'],\n                ['LTS',                           '15:25:50'],\n                ['L',                             '14/02/2010'],\n                ['LL',                            '14 பிப்ரவரி 2010'],\n                ['LLL',                           '14 பிப்ரவரி 2010, 15:25'],\n                ['LLLL',                          'ஞாயிற்றுக்கிழமை, 14 பிப்ரவரி 2010, 15:25'],\n                ['l',                             '14/2/2010'],\n                ['ll',                            '14 பிப்ரவரி 2010'],\n                ['lll',                           '14 பிப்ரவரி 2010, 15:25'],\n                ['llll',                          'ஞாயிறு, 14 பிப்ரவரி 2010, 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1வது', '1வது');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2வது', '2வது');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3வது', '3வது');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4வது', '4வது');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5வது', '5வது');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6வது', '6வது');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7வது', '7வது');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8வது', '8வது');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9வது', '9வது');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10வது', '10வது');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11வது', '11வது');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12வது', '12வது');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13வது', '13வது');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14வது', '14வது');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15வது', '15வது');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16வது', '16வது');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17வது', '17வது');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18வது', '18வது');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19வது', '19வது');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20வது', '20வது');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21வது', '21வது');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22வது', '22வது');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23வது', '23வது');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24வது', '24வது');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25வது', '25வது');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26வது', '26வது');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27வது', '27வது');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28வது', '28வது');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29வது', '29வது');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30வது', '30வது');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31வது', '31வது');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'ஜனவரி ஜனவரி_பிப்ரவரி பிப்ரவரி_மார்ச் மார்ச்_ஏப்ரல் ஏப்ரல்_மே மே_ஜூன் ஜூன்_ஜூலை ஜூலை_ஆகஸ்ட் ஆகஸ்ட்_செப்டெம்பர் செப்டெம்பர்_அக்டோபர் அக்டோபர்_நவம்பர் நவம்பர்_டிசம்பர் டிசம்பர்'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'ஞாயிற்றுக்கிழமை ஞாயிறு ஞா_திங்கட்கிழமை திங்கள் தி_செவ்வாய்கிழமை செவ்வாய் செ_புதன்கிழமை புதன் பு_வியாழக்கிழமை வியாழன் வி_வெள்ளிக்கிழமை வெள்ளி வெ_சனிக்கிழமை சனி ச'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ஒரு சில விநாடிகள்', '44 விநாடிகள் = ஒரு சில விநாடிகள்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ஒரு நிமிடம்',      '45 விநாடிகள் = ஒரு நிமிடம்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ஒரு நிமிடம்',      '89 விநாடிகள் = ஒரு நிமிடம்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 நிமிடங்கள்',     '90 விநாடிகள் = 2 நிமிடங்கள்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 நிமிடங்கள்',    '44 நிமிடங்கள் = 44 நிமிடங்கள்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ஒரு மணி நேரம்',       '45 நிமிடங்கள் = ஒரு மணி நேரம்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ஒரு மணி நேரம்',       '89 நிமிடங்கள் = ஒரு மணி நேரம்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 மணி நேரம்',       '90 நிமிடங்கள் = 2 மணி நேரம்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 மணி நேரம்',       '5 மணி நேரம் = 5 மணி நேரம்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 மணி நேரம்',      '21 மணி நேரம் = 21 மணி நேரம்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ஒரு நாள்',         '22 மணி நேரம் = ஒரு நாள்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ஒரு நாள்',         '35 மணி நேரம் = ஒரு நாள்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 நாட்கள்',        '36 மணி நேரம் = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ஒரு நாள்',         '1 நாள் = ஒரு நாள்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 நாட்கள்',        '5 நாட்கள் = 5 நாட்கள்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 நாட்கள்',       '25 நாட்கள் = 25 நாட்கள்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ஒரு மாதம்',       '26 நாட்கள் = ஒரு மாதம்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ஒரு மாதம்',       '30 நாட்கள் = ஒரு மாதம்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ஒரு மாதம்',       '45 நாட்கள் = ஒரு மாதம்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 மாதங்கள்',      '46 நாட்கள் = 2 மாதங்கள்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 மாதங்கள்',      '75 நாட்கள் = 2 மாதங்கள்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 மாதங்கள்',      '76 நாட்கள் = 3 மாதங்கள்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ஒரு மாதம்',       '1 மாதம் = ஒரு மாதம்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 மாதங்கள்',      '5 மாதங்கள் = 5 மாதங்கள்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ஒரு வருடம்',        '345 நாட்கள் = ஒரு வருடம்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ஆண்டுகள்',       '548 நாட்கள் = 2 ஆண்டுகள்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ஒரு வருடம்',        '1 வருடம் = ஒரு வருடம்');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ஆண்டுகள்',       '5 ஆண்டுகள் = 5 ஆண்டுகள்');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'ஒரு சில விநாடிகள் இல்',  'prefix');\n        assert.equal(moment(0).from(30000), 'ஒரு சில விநாடிகள் முன்', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'ஒரு சில விநாடிகள் முன்',  'இப்போது இருந்து கடந்த காலத்தில் காட்ட வேண்டும்');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'ஒரு சில விநாடிகள் இல்', 'ஒரு சில விநாடிகள் இல்');\n        assert.equal(moment().add({d: 5}).fromNow(), '5 நாட்கள் இல்', '5 நாட்கள் இல்');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),  'இன்று 02:00', 'இன்று  02:00');\n        assert.equal(moment(a).add({m: 25}).calendar(), 'இன்று 02:25', 'இன்று  02:25');\n        assert.equal(moment(a).add({h: 1}).calendar(), 'இன்று 03:00', 'இன்று  03:00');\n        assert.equal(moment(a).add({d: 1}).calendar(), 'நாளை 02:00', 'நாளை  02:00');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'இன்று 01:00',      'இன்று  01:00');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'நேற்று 02:00',  'நேற்று  02:00');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd, LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd, LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd, LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[கடந்த வாரம்] dddd, LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[கடந்த வாரம்] dddd, LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[கடந்த வாரம்] dddd, LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n        assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n        assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n        assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n        assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n    });\n\n    test('meridiem', function (assert) {\n        assert.equal(moment([2011, 2, 23,  0, 30]).format('a'), ' யாமம்', '(after) midnight');\n        assert.equal(moment([2011, 2, 23,  2, 30]).format('a'), ' வைகறை', 'before dawn');\n        assert.equal(moment([2011, 2, 23,  9, 30]).format('a'), ' காலை', 'morning');\n        assert.equal(moment([2011, 2, 23, 14, 30]).format('a'), ' எற்பாடு', 'during day');\n        assert.equal(moment([2011, 2, 23, 17, 30]).format('a'), ' எற்பாடு', 'evening');\n        assert.equal(moment([2011, 2, 23, 19, 30]).format('a'), ' மாலை', 'late evening');\n        assert.equal(moment([2011, 2, 23, 23, 30]).format('a'), ' யாமம்', '(before) midnight');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('th');\n\n    test('parse', function (assert) {\n        var tests = 'มกราคม มกรา_กุมภาพันธ์ กุมภา_มีนาคม มีนา_เมษายน เมษา_พฤษภาคม พฤษภา_มิถุนายน มิถุนา_กรกฎาคม กรกฎา_สิงหาคม สิงหา_กันยายน กันยา_ตุลาคม ตุลา_พฤศจิกายน พฤศจิกา_ธันวาคม ธันวา'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, h:mm:ss a',      'อาทิตย์, 14 กุมภาพันธ์ 2010, 3:25:50 หลังเที่ยง'],\n                ['ddd, h A',                           'อาทิตย์, 3 หลังเที่ยง'],\n                ['M Mo MM MMMM MMM',                   '2 2 02 กุมภาพันธ์ กุมภา'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14 14'],\n                ['d do dddd ddd dd',                   '0 0 อาทิตย์ อาทิตย์ อา.'],\n                ['DDD DDDo DDDD',                      '45 45 045'],\n                ['w wo ww',                            '8 8 08'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'หลังเที่ยง หลังเที่ยง'],\n                ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n                ['LTS',                                '15 นาฬิกา 25 นาที 50 วินาที'],\n                ['L',                                  '2010/02/14'],\n                ['LL',                                 '14 กุมภาพันธ์ 2010'],\n                ['LLL',                                '14 กุมภาพันธ์ 2010 เวลา 15 นาฬิกา 25 นาที'],\n                ['LLLL',                               'วันอาทิตย์ที่ 14 กุมภาพันธ์ 2010 เวลา 15 นาฬิกา 25 นาที'],\n                ['l',                                  '2010/2/14'],\n                ['ll',                                 '14 กุมภา 2010'],\n                ['lll',                                '14 กุมภา 2010 เวลา 15 นาฬิกา 25 นาที'],\n                ['llll',                               'วันอาทิตย์ที่ 14 กุมภา 2010 เวลา 15 นาฬิกา 25 นาที']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format month', function (assert) {\n        var expected = 'มกราคม มกรา_กุมภาพันธ์ กุมภา_มีนาคม มีนา_เมษายน เมษา_พฤษภาคม พฤษภา_มิถุนายน มิถุนา_กรกฎาคม กรกฎา_สิงหาคม สิงหา_กันยายน กันยา_ตุลาคม ตุลา_พฤศจิกายน พฤศจิกา_ธันวาคม ธันวา'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'อาทิตย์ อาทิตย์ อา._จันทร์ จันทร์ จ._อังคาร อังคาร อ._พุธ พุธ พ._พฤหัสบดี พฤหัส พฤ._ศุกร์ ศุกร์ ศ._เสาร์ เสาร์ ส.'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ไม่กี่วินาที',   '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1 นาที', '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1 นาที', '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 นาที',  '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 นาที', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1 ชั่วโมง', '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1 ชั่วโมง', '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ชั่วโมง',  '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ชั่วโมง',  '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ชั่วโมง', '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1 วัน',   '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1 วัน',   '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 วัน',   '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1 วัน',   '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 วัน',   '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 วัน',  '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1 เดือน', '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1 เดือน', '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1 เดือน', '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 เดือน',  '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 เดือน',  '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 เดือน',  '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1 เดือน', '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 เดือน',  '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1 ปี',   '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ปี',   '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1 ปี',   '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ปี',   '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'อีก ไม่กี่วินาที',  'prefix');\n        assert.equal(moment(0).from(30000), 'ไม่กี่วินาทีที่แล้ว', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'ไม่กี่วินาทีที่แล้ว',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'อีก ไม่กี่วินาที', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'อีก 5 วัน', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'วันนี้ เวลา 2 นาฬิกา 0 นาที',      'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'วันนี้ เวลา 2 นาฬิกา 25 นาที',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'วันนี้ เวลา 3 นาฬิกา 0 นาที',      'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'พรุ่งนี้ เวลา 2 นาฬิกา 0 นาที', 'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'วันนี้ เวลา 1 นาฬิกา 0 นาที',      'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'เมื่อวานนี้ เวลา 2 นาฬิกา 0 นาที', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd[หน้า เวลา] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd[หน้า เวลา] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd[หน้า เวลา] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[วัน]dddd[ที่แล้ว เวลา] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[วัน]dddd[ที่แล้ว เวลา] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[วัน]dddd[ที่แล้ว เวลา] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n        assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n        assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n        assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n        assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday format', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1', 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2', 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3', 'Jan 15 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('tl-ph');\n\n    test('parse', function (assert) {\n        var tests = 'Enero Ene_Pebrero Peb_Marso Mar_Abril Abr_Mayo May_Hunyo Hun_Hulyo Hul_Agosto Ago_Setyembre Set_Oktubre Okt_Nobyembre Nob_Disyembre Dis'.split('_'),\n            i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'Linggo, Pebrero 14 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'Lin, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2 02 Pebrero Peb'],\n                ['YYYY YY',                             '2010 10'],\n                ['D Do DD',                            '14 14 14'],\n                ['d do dddd ddd dd',                   '0 0 Linggo Lin Li'],\n                ['DDD DDDo DDDD',                      '45 45 045'],\n                ['w wo ww',                            '6 6 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '02/14/2010'],\n                ['LL',                                 'Pebrero 14, 2010'],\n                ['LLL',                                'Pebrero 14, 2010 15:25'],\n                ['LLLL',                               'Linggo, Pebrero 14, 2010 15:25'],\n                ['l',                                  '2/14/2010'],\n                ['ll',                                 'Peb 14, 2010'],\n                ['lll',                                'Peb 14, 2010 15:25'],\n                ['llll',                               'Lin, Peb 14, 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'Enero Ene_Pebrero Peb_Marso Mar_Abril Abr_Mayo May_Hunyo Hun_Hulyo Hul_Agosto Ago_Setyembre Set_Oktubre Okt_Nobyembre Nob_Disyembre Dis'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'Linggo Lin Li_Lunes Lun Lu_Martes Mar Ma_Miyerkules Miy Mi_Huwebes Huw Hu_Biyernes Biy Bi_Sabado Sab Sab'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ilang segundo', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'isang minuto',   '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'isang minuto',   '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuto',  '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuto', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'isang oras',    '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'isang oras',    '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 oras',    '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 oras',    '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 oras',   '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'isang araw',      '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'isang araw',      '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 araw',     '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'isang araw',      '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 araw',     '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 araw',    '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'isang buwan',    '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'isang buwan',    '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'isang buwan',    '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 buwan',   '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 buwan',   '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 buwan',   '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'isang buwan',    '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 buwan',   '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'isang taon',     '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 taon',    '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'isang taon',     '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 taon',    '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'sa loob ng ilang segundo', 'prefix');\n        assert.equal(moment(0).from(30000), 'ilang segundo ang nakalipas', 'suffix');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'sa loob ng ilang segundo', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'sa loob ng 5 araw', 'in 5 days');\n    });\n\n    test('same day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Ngayon sa 02:00',    'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Ngayon sa 02:25',    'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Ngayon sa 03:00',    'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Bukas sa 02:00',     'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Ngayon sa 01:00',    'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Kahapon sa 02:00',   'yesterday at the same time');\n    });\n\n    test('same next week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [sa] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [sa] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [sa] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('same last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [huling linggo] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [huling linggo] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [huling linggo] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('same all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'), '1 01 1', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'), '1 01 1', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('tr');\n\n    test('parse', function (assert) {\n        var tests = 'Ocak Oca_Şubat Şub_Mart Mar_Nisan Nis_Mayıs May_Haziran Haz_Temmuz Tem_Ağustos Ağu_Eylül Eyl_Ekim Eki_Kasım Kas_Aralık Ara'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'Pazar, Şubat 14\\'üncü 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'Paz, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2\\'nci 02 Şubat Şub'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14\\'üncü 14'],\n                ['d do dddd ddd dd',                   '0 0\\'ıncı Pazar Paz Pz'],\n                ['DDD DDDo DDDD',                      '45 45\\'inci 045'],\n                ['w wo ww',                            '7 7\\'nci 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[yılın] DDDo [günü]',                'yılın 45\\'inci günü'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14.02.2010'],\n                ['LL',                                 '14 Şubat 2010'],\n                ['LLL',                                '14 Şubat 2010 15:25'],\n                ['LLLL',                               'Pazar, 14 Şubat 2010 15:25'],\n                ['l',                                  '14.2.2010'],\n                ['ll',                                 '14 Şub 2010'],\n                ['lll',                                '14 Şub 2010 15:25'],\n                ['llll',                               'Paz, 14 Şub 2010 15:25']\n            ],\n            DDDo = [\n                [359, '360\\'ıncı'],\n                [199, '200\\'üncü'],\n                [149, '150\\'nci']\n            ],\n            dt = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            DDDoDt,\n            i;\n\n        for (i = 0; i < a.length; i++) {\n            assert.equal(dt.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n        for (i = 0; i < DDDo.length; i++) {\n            DDDoDt = moment([2010]);\n            assert.equal(DDDoDt.add(DDDo[i][0], 'days').format('DDDo'), DDDo[i][1], DDDo[i][0] + ' ---> ' + DDDo[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1\\'inci', '1st');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2\\'nci', '2nd');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3\\'üncü', '3rd');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4\\'üncü', '4th');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5\\'inci', '5th');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6\\'ncı', '6th');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7\\'nci', '7th');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8\\'inci', '8th');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9\\'uncu', '9th');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10\\'uncu', '10th');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11\\'inci', '11th');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12\\'nci', '12th');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13\\'üncü', '13th');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14\\'üncü', '14th');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15\\'inci', '15th');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16\\'ncı', '16th');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17\\'nci', '17th');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18\\'inci', '18th');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19\\'uncu', '19th');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20\\'nci', '20th');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21\\'inci', '21th');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22\\'nci', '22th');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23\\'üncü', '23th');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24\\'üncü', '24th');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25\\'inci', '25th');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26\\'ncı', '26th');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27\\'nci', '27th');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28\\'inci', '28th');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29\\'uncu', '29th');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30\\'uncu', '30th');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31\\'inci', '31st');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'Ocak Oca_Şubat Şub_Mart Mar_Nisan Nis_Mayıs May_Haziran Haz_Temmuz Tem_Ağustos Ağu_Eylül Eyl_Ekim Eki_Kasım Kas_Aralık Ara'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'Pazar Paz Pz_Pazartesi Pts Pt_Salı Sal Sa_Çarşamba Çar Ça_Perşembe Per Pe_Cuma Cum Cu_Cumartesi Cts Ct'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'birkaç saniye', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'bir dakika',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'bir dakika',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 dakika',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 dakika',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'bir saat',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'bir saat',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 saat',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 saat',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 saat',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'bir gün',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'bir gün',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 gün',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'bir gün',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 gün',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 gün',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'bir ay',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'bir ay',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'bir ay',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ay',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ay',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ay',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'bir ay',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ay',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'bir yıl',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 yıl',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'bir yıl',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 yıl',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'birkaç saniye sonra',  'prefix');\n        assert.equal(moment(0).from(30000), 'birkaç saniye önce', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'birkaç saniye önce',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'birkaç saniye sonra', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), '5 gün sonra', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'bugün saat 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'bugün saat 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'bugün saat 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'yarın saat 02:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'bugün saat 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'dün 02:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('[haftaya] dddd [saat] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[haftaya] dddd [saat] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[haftaya] dddd [saat] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[geçen hafta] dddd [saat] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[geçen hafta] dddd [saat] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[geçen hafta] dddd [saat] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1\\'inci', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1\\'inci', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2\\'nci', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2\\'nci', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3\\'üncü', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('tzm-latn');\n\n    test('parse', function (assert) {\n        var tests = 'innayr innayr_brˤayrˤ brˤayrˤ_marˤsˤ marˤsˤ_ibrir ibrir_mayyw mayyw_ywnyw ywnyw_ywlywz ywlywz_ɣwšt ɣwšt_šwtanbir šwtanbir_ktˤwbrˤ ktˤwbrˤ_nwwanbir nwwanbir_dwjnbir dwjnbir'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'asamas, brˤayrˤ 14 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'asamas, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2 02 brˤayrˤ brˤayrˤ'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14 14'],\n                ['d do dddd ddd dd',                   '0 0 asamas asamas asamas'],\n                ['DDD DDDo DDDD',                      '45 45 045'],\n                ['w wo ww',                            '8 8 08'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 brˤayrˤ 2010'],\n                ['LLL',                                '14 brˤayrˤ 2010 15:25'],\n                ['LLLL',                               'asamas 14 brˤayrˤ 2010 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 brˤayrˤ 2010'],\n                ['lll',                                '14 brˤayrˤ 2010 15:25'],\n                ['llll',                               'asamas 14 brˤayrˤ 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'innayr innayr_brˤayrˤ brˤayrˤ_marˤsˤ marˤsˤ_ibrir ibrir_mayyw mayyw_ywnyw ywnyw_ywlywz ywlywz_ɣwšt ɣwšt_šwtanbir šwtanbir_ktˤwbrˤ ktˤwbrˤ_nwwanbir nwwanbir_dwjnbir dwjnbir'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'asamas asamas asamas_aynas aynas aynas_asinas asinas asinas_akras akras akras_akwas akwas akwas_asimwas asimwas asimwas_asiḍyas asiḍyas asiḍyas'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'imik', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'minuḍ',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'minuḍ',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 minuḍ',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 minuḍ',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'saɛa',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'saɛa',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 tassaɛin',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 tassaɛin',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 tassaɛin',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ass',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ass',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ossan',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ass',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ossan',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ossan',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ayowr',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ayowr',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ayowr',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 iyyirn',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 iyyirn',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 iyyirn',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ayowr',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 iyyirn',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'asgas',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 isgasn',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'asgas',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 isgasn',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'dadkh s yan imik',  'prefix');\n        assert.equal(moment(0).from(30000), 'yan imik', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'yan imik',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'dadkh s yan imik', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'dadkh s yan 5 ossan', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'asdkh g 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'asdkh g 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'asdkh g 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'aska g 02:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'asdkh g 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'assant g 02:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [g] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 31]).week(), 1, 'Dec 31 2011 should be week 1');\n        assert.equal(moment([2012,  0,  6]).week(), 1, 'Jan  6 2012 should be week 1');\n        assert.equal(moment([2012,  0,  7]).week(), 2, 'Jan  7 2012 should be week 2');\n        assert.equal(moment([2012,  0, 13]).week(), 2, 'Jan 13 2012 should be week 2');\n        assert.equal(moment([2012,  0, 14]).week(), 3, 'Jan 14 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 30]).week(), 1, 'Dec 30 2006 should be week 1');\n        assert.equal(moment([2007,  0,  5]).week(), 1, 'Jan  5 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 2, 'Jan  6 2007 should be week 2');\n        assert.equal(moment([2007,  0, 12]).week(), 2, 'Jan 12 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 3, 'Jan 13 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 1, 'Dec 29 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  4]).week(), 1, 'Jan  4 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 2, 'Jan  5 2008 should be week 2');\n        assert.equal(moment([2008,  0, 11]).week(), 2, 'Jan 11 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 3, 'Jan 12 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 28]).week(), 1, 'Dec 28 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  3]).week(), 1, 'Jan  3 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 2, 'Jan  4 2003 should be week 2');\n        assert.equal(moment([2003,  0, 10]).week(), 2, 'Jan 10 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 3, 'Jan 11 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 27]).week(), 1, 'Dec 27 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  2]).week(), 1, 'Jan  2 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 2, 'Jan  3 2009 should be week 2');\n        assert.equal(moment([2009,  0,  9]).week(), 2, 'Jan  9 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 3, 'Jan 10 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 26]).week(), 1, 'Dec 26 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 2, 'Jan  2 2010 should be week 2');\n        assert.equal(moment([2010,  0,  8]).week(), 2, 'Jan  8 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 3, 'Jan  9 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2011, 0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011, 0,  7]).week(), 1, 'Jan  7 2011 should be week 1');\n        assert.equal(moment([2011, 0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011, 0, 14]).week(), 2, 'Jan 14 2011 should be week 2');\n        assert.equal(moment([2011, 0, 15]).week(), 3, 'Jan 15 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n        assert.equal(moment([2012,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2012 should be week 1');\n        assert.equal(moment([2012,  0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 should be week 2');\n        assert.equal(moment([2012,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2012 should be week 2');\n        assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('tzm');\n\n    test('parse', function (assert) {\n        var tests = 'ⵉⵏⵏⴰⵢⵔ ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'ⴰⵙⴰⵎⴰⵙ, ⴱⵕⴰⵢⵕ 14 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'ⴰⵙⴰⵎⴰⵙ, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2 02 ⴱⵕⴰⵢⵕ ⴱⵕⴰⵢⵕ'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14 14'],\n                ['d do dddd ddd dd',                   '0 0 ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ'],\n                ['DDD DDDo DDDD',                      '45 45 045'],\n                ['w wo ww',                            '8 8 08'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[the] DDDo [day of the year]',       'the 45 day of the year'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 ⴱⵕⴰⵢⵕ 2010'],\n                ['LLL',                                '14 ⴱⵕⴰⵢⵕ 2010 15:25'],\n                ['LLLL',                               'ⴰⵙⴰⵎⴰⵙ 14 ⴱⵕⴰⵢⵕ 2010 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 ⴱⵕⴰⵢⵕ 2010'],\n                ['lll',                                '14 ⴱⵕⴰⵢⵕ 2010 15:25'],\n                ['llll',                               'ⴰⵙⴰⵎⴰⵙ 14 ⴱⵕⴰⵢⵕ 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'ⵉⵏⵏⴰⵢⵔ ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ ⴷⵓⵊⵏⴱⵉⵔ'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ ⴰⵢⵏⴰⵙ ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ ⴰⵙⵉⵏⴰⵙ ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ ⴰⴽⵔⴰⵙ ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ ⴰⴽⵡⴰⵙ ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ ⴰⵙⵉⵎⵡⴰⵙ ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ ⴰⵙⵉⴹⵢⴰⵙ ⴰⵙⵉⴹⵢⴰⵙ'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'ⵉⵎⵉⴽ', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'ⵎⵉⵏⵓⴺ',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'ⵎⵉⵏⵓⴺ',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 ⵎⵉⵏⵓⴺ',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 ⵎⵉⵏⵓⴺ',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'ⵙⴰⵄⴰ',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'ⵙⴰⵄⴰ',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 ⵜⴰⵙⵙⴰⵄⵉⵏ',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 ⵜⴰⵙⵙⴰⵄⵉⵏ',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 ⵜⴰⵙⵙⴰⵄⵉⵏ',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'ⴰⵙⵙ',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'ⴰⵙⵙ',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 oⵙⵙⴰⵏ',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'ⴰⵙⵙ',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 oⵙⵙⴰⵏ',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 oⵙⵙⴰⵏ',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'ⴰⵢoⵓⵔ',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'ⴰⵢoⵓⵔ',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'ⴰⵢoⵓⵔ',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ⵉⵢⵢⵉⵔⵏ',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ⵉⵢⵢⵉⵔⵏ',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ⵉⵢⵢⵉⵔⵏ',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'ⴰⵢoⵓⵔ',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ⵉⵢⵢⵉⵔⵏ',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'ⴰⵙⴳⴰⵙ',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 ⵉⵙⴳⴰⵙⵏ',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'ⴰⵙⴳⴰⵙ',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 ⵉⵙⴳⴰⵙⵏ',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ ⵉⵎⵉⴽ',  'prefix');\n        assert.equal(moment(0).from(30000), 'ⵢⴰⵏ ⵉⵎⵉⴽ', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'ⵢⴰⵏ ⵉⵎⵉⴽ',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ ⵉⵎⵉⴽ', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ 5 oⵙⵙⴰⵏ', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'ⴰⵙⴷⵅ ⴴ 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'ⴰⵙⴷⵅ ⴴ 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'ⴰⵙⴷⵅ ⴴ 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'ⴰⵙⴽⴰ ⴴ 02:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'ⴰⵙⴷⵅ ⴴ 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'ⴰⵚⴰⵏⵜ ⴴ 02:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [ⴴ] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 31]).week(), 1, 'Dec 31 2011 should be week 1');\n        assert.equal(moment([2012,  0,  6]).week(), 1, 'Jan  6 2012 should be week 1');\n        assert.equal(moment([2012,  0,  7]).week(), 2, 'Jan  7 2012 should be week 2');\n        assert.equal(moment([2012,  0, 13]).week(), 2, 'Jan 13 2012 should be week 2');\n        assert.equal(moment([2012,  0, 14]).week(), 3, 'Jan 14 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 30]).week(), 1, 'Dec 30 2006 should be week 1');\n        assert.equal(moment([2007,  0,  5]).week(), 1, 'Jan  5 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 2, 'Jan  6 2007 should be week 2');\n        assert.equal(moment([2007,  0, 12]).week(), 2, 'Jan 12 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 3, 'Jan 13 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 1, 'Dec 29 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  4]).week(), 1, 'Jan  4 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 2, 'Jan  5 2008 should be week 2');\n        assert.equal(moment([2008,  0, 11]).week(), 2, 'Jan 11 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 3, 'Jan 12 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 28]).week(), 1, 'Dec 28 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  3]).week(), 1, 'Jan  3 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 2, 'Jan  4 2003 should be week 2');\n        assert.equal(moment([2003,  0, 10]).week(), 2, 'Jan 10 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 3, 'Jan 11 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 27]).week(), 1, 'Dec 27 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  2]).week(), 1, 'Jan  2 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 2, 'Jan  3 2009 should be week 2');\n        assert.equal(moment([2009,  0,  9]).week(), 2, 'Jan  9 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 3, 'Jan 10 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 26]).week(), 1, 'Dec 26 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 2, 'Jan  2 2010 should be week 2');\n        assert.equal(moment([2010,  0,  8]).week(), 2, 'Jan  8 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 3, 'Jan  9 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2011, 0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011, 0,  7]).week(), 1, 'Jan  7 2011 should be week 1');\n        assert.equal(moment([2011, 0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011, 0, 14]).week(), 2, 'Jan 14 2011 should be week 2');\n        assert.equal(moment([2011, 0, 15]).week(), 3, 'Jan 15 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 31]).format('w ww wo'), '1 01 1', 'Dec 31 2011 should be week 1');\n        assert.equal(moment([2012,  0,  6]).format('w ww wo'), '1 01 1', 'Jan  6 2012 should be week 1');\n        assert.equal(moment([2012,  0,  7]).format('w ww wo'), '2 02 2', 'Jan  7 2012 should be week 2');\n        assert.equal(moment([2012,  0, 13]).format('w ww wo'), '2 02 2', 'Jan 13 2012 should be week 2');\n        assert.equal(moment([2012,  0, 14]).format('w ww wo'), '3 03 3', 'Jan 14 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('uk');\n\n    test('parse', function (assert) {\n        var tests = 'січень січ_лютий лют_березень бер_квітень квіт_травень трав_червень черв_липень лип_серпень серп_вересень вер_жовтень жовт_листопад лист_грудень груд'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do MMMM YYYY, HH:mm:ss',       'неділя, 14-го лютого 2010, 15:25:50'],\n                ['ddd, h A',                           'нд, 3 дня'],\n                ['M Mo MM MMMM MMM',                   '2 2-й 02 лютий лют'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14-го 14'],\n                ['d do dddd ddd dd',                   '0 0-й неділя нд нд'],\n                ['DDD DDDo DDDD',                      '45 45-й 045'],\n                ['w wo ww',                            '7 7-й 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'дня дня'],\n                ['DDDo [день року]',                  '45-й день року'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14.02.2010'],\n                ['LL',                                 '14 лютого 2010 р.'],\n                ['LLL',                                '14 лютого 2010 р., 15:25'],\n                ['LLLL',                               'неділя, 14 лютого 2010 р., 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format meridiem', function (assert) {\n        assert.equal(moment([2012, 11, 28, 0, 0]).format('A'), 'ночі', 'night');\n        assert.equal(moment([2012, 11, 28, 3, 59]).format('A'), 'ночі', 'night');\n        assert.equal(moment([2012, 11, 28, 4, 0]).format('A'), 'ранку', 'morning');\n        assert.equal(moment([2012, 11, 28, 11, 59]).format('A'), 'ранку', 'morning');\n        assert.equal(moment([2012, 11, 28, 12, 0]).format('A'), 'дня', 'afternoon');\n        assert.equal(moment([2012, 11, 28, 16, 59]).format('A'), 'дня', 'afternoon');\n        assert.equal(moment([2012, 11, 28, 17, 0]).format('A'), 'вечора', 'evening');\n        assert.equal(moment([2012, 11, 28, 23, 59]).format('A'), 'вечора', 'evening');\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1-й', '1-й');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2-й', '2-й');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3-й', '3-й');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4-й', '4-й');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5-й', '5-й');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6-й', '6-й');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7-й', '7-й');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8-й', '8-й');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9-й', '9-й');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10-й', '10-й');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11-й', '11-й');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12-й', '12-й');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13-й', '13-й');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14-й', '14-й');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15-й', '15-й');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16-й', '16-й');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17-й', '17-й');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18-й', '18-й');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19-й', '19-й');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20-й', '20-й');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21-й', '21-й');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22-й', '22-й');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23-й', '23-й');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24-й', '24-й');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25-й', '25-й');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26-й', '26-й');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27-й', '27-й');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28-й', '28-й');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29-й', '29-й');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30-й', '30-й');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31-й', '31-й');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'січень січ_лютий лют_березень бер_квітень квіт_травень трав_червень черв_липень лип_серпень серп_вересень вер_жовтень жовт_листопад лист_грудень груд'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format month case', function (assert) {\n        var months = {\n            'nominative': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_'),\n            'accusative': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_')\n        }, i;\n        for (i = 0; i < 12; i++) {\n            assert.equal(moment([2011, i, 1]).format('D MMMM'), '1 ' + months.accusative[i], '1 ' + months.accusative[i]);\n            assert.equal(moment([2011, i, 1]).format('MMMM'), months.nominative[i], '1 ' + months.nominative[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'неділя нд нд_понеділок пн пн_вівторок вт вт_середа ср ср_четвер чт чт_п’ятниця пт пт_субота сб сб'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'декілька секунд',    '44 seconds = seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'хвилина',   '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'хвилина',   '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 хвилини',  '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 хвилини', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'годину',    '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'годину',    '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 години',    '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 годин',    '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 година',   '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'день',      '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'день',      '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 дні',     '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'день',      '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 днів',     '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 11}), true),  '11 днів',     '11 days = 11 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 21}), true),  '21 день',     '21 days = 21 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 днів',    '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'місяць',    '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'місяць',    '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'місяць',    '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 місяці',   '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 місяці',   '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 місяці',   '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'місяць',    '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 місяців',   '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'рік',     '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 роки',    '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'рік',     '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 років',    '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'за декілька секунд', 'prefix');\n        assert.equal(moment(0).from(30000), 'декілька секунд тому', 'suffix');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'за декілька секунд', 'in seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'за 5 днів', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Сьогодні о 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Сьогодні о 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Сьогодні о 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Завтра о 02:00',      'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Сьогодні о 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Вчора о 02:00',       'yesterday at the same time');\n        assert.equal(moment(a).add({h: 9}).calendar(),  'Сьогодні об 11:00',       'same day at 11 o\\'clock');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('[У] dddd [о' + (m.hours() === 11 ? 'б' : '') + '] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[У] dddd [о] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[У] dddd [о] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        function makeFormat(d) {\n            switch (d.day()) {\n            case 0:\n            case 3:\n            case 5:\n            case 6:\n                return '[Минулої] dddd [о' + (d.hours() === 11 ? 'б' : '') + '] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[Минулого] dddd [о' + (d.hours() === 11 ? 'б' : '') + '] LT';\n            }\n        }\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format(makeFormat(m)),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2011, 11, 26]).week(), 1, 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).week(), 2, 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).week(), 3, 'Jan  9 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 12]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 1');\n        assert.equal(moment([2010,  0,  4]).week(), 2, 'Jan  4 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 2, 'Jan 10 2010 should be week 2');\n        assert.equal(moment([2010,  0, 11]).week(), 3, 'Jan 11 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 1');\n        assert.equal(moment([2011,  0,  3]).week(), 2, 'Jan  3 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 2, 'Jan  9 2011 should be week 2');\n        assert.equal(moment([2011,  0, 10]).week(), 3, 'Jan 10 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2011, 11, 26]).format('w ww wo'), '1 01 1-й', 'Dec 26 2011 should be week 1');\n        assert.equal(moment([2012,  0,  1]).format('w ww wo'), '1 01 1-й', 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012,  0,  2]).format('w ww wo'), '2 02 2-й', 'Jan  2 2012 should be week 2');\n        assert.equal(moment([2012,  0,  8]).format('w ww wo'), '2 02 2-й', 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012,  0,  9]).format('w ww wo'), '3 03 3-й', 'Jan  9 2012 should be week 3');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('uz');\n\n    test('parse', function (assert) {\n        var tests = 'январь янв_февраль фев_март мар_апрель апр_май май_июнь июнь_июль июль_август авг_сентябрь сен_октябрь окт_ноябрь ноя_декабрь дек'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, Do-MMMM YYYY, h:mm:ss',        'Якшанба, 14-февраль 2010, 3:25:50'],\n                ['ddd, h:mm',                          'Якш, 3:25'],\n                ['M Mo MM MMMM MMM',                   '2 2 02 февраль фев'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14 14'],\n                ['d do dddd ddd dd',                   '0 0 Якшанба Якш Як'],\n                ['DDD DDDo DDDD',                      '45 45 045'],\n                ['w wo ww',                            '7 7 07'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[йилнинг] DDDo-[куни]',             'йилнинг 45-куни'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 февраль 2010'],\n                ['LLL',                                '14 февраль 2010 15:25'],\n                ['LLLL',                               '14 февраль 2010, Якшанба 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 фев 2010'],\n                ['lll',                                '14 фев 2010 15:25'],\n                ['llll',                               '14 фев 2010, Якш 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n    });\n\n    test('format month', function (assert) {\n        var expected = 'январь янв_февраль фев_март мар_апрель апр_май май_июнь июн_июль июл_август авг_сентябрь сен_октябрь окт_ноябрь ноя_декабрь дек'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = 'Якшанба Якш Як_Душанба Душ Ду_Сешанба Сеш Се_Чоршанба Чор Чо_Пайшанба Пай Па_Жума Жум Жу_Шанба Шан Ша'.split('_'), i;\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'фурсат', '44 секунд = фурсат');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'бир дакика',      '45 секунд = бир дакика');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'бир дакика',      '89 секунд = бир дакика');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 дакика',     '90 секунд = 2 дакика');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 дакика',    '44 дакика = 44 дакика');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'бир соат',       '45 минут = бир соат');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'бир соат',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 соат',       '90 минут = 2 соат');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 соат',       '5 соат = 5 соат');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 соат',      '21 соат = 21 соат');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'бир кун',         '22 соат = бир кун');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'бир кун',         '35 соат = бир кун');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 кун',        '36 соат = 2 кун');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'бир кун',         '1 кун = 1 кун');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 кун',        '5 кун = 5 кун');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 кун',       '25 кун = 25 кун');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'бир ой',       '26 кун = бир ой');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'бир ой',       '30 кун = бир ой');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'бир ой',       '45 кун = бир ой');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 ой',      '46 кун = 2 ой');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 ой',      '75 кун = 2 ой');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 ой',      '76 кун = 3 ой');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'бир ой',       'бир ой = бир ой');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 ой',      '5 ой = 5 ой');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'бир йил',        '345 кун = бир йил');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 йил',       '548 кун = 2 йил');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'бир йил',        '1 йил = бир йил');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 йил',       '5 йил = 5 йил');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'Якин фурсат ичида',  'prefix');\n        assert.equal(moment(0).from(30000), 'Бир неча фурсат олдин', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'Бир неча фурсат олдин',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'Якин фурсат ичида', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), 'Якин 5 кун ичида', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Бугун соат 02:00 да',      'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Бугун соат 02:25 да',      'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Бугун соат 03:00 да',      'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Эртага 02:00 да',   'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Бугун соат 01:00 да',      'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Кеча соат 02:00 да',  'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [куни соат] LT [да]'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [куни соат] LT [да]'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [куни соат] LT [да]'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[Утган] dddd [куни соат] LT [да]'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[Утган] dddd [куни соат] LT [да]'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[Утган] dddd [куни соат] LT [да]'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 1, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  2, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  2, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  3, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 1, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 1, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  2, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  2, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  3, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 1, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 1, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  2, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  2, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  3, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '2 02 2', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '2 02 2', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '3 03 3', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '3 03 3', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('vi');\n\n    test('parse', function (assert) {\n        var i,\n            tests = 'tháng 1,Th01_tháng 2,Th02_tháng 3,Th03_tháng 4,Th04_tháng 5,Th05_tháng 6,Th06_tháng 7,Th07_tháng 8,Th08_tháng 9,Th09_tháng 10,Th10_tháng 11,Th11_tháng 12,Th12'.split('_');\n\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + i);\n        }\n\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(',');\n            equalTest(tests[i][0], '[tháng] M', i);\n            equalTest(tests[i][1], '[Th]M', i);\n            equalTest(tests[i][0], '[tháng] MM', i);\n            equalTest(tests[i][1], '[Th]MM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), '[THÁNG] M', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), '[TH]M', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), '[THÁNG] MM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), '[TH]MM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, h:mm:ss a',      'chủ nhật, tháng 2 14 2010, 3:25:50 pm'],\n                ['ddd, hA',                            'CN, 3PM'],\n                ['M Mo MM MMMM MMM',                   '2 2 02 tháng 2 Th02'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14 14'],\n                ['d do dddd ddd dd',                   '0 0 chủ nhật CN CN'],\n                ['DDD DDDo DDDD',                      '45 45 045'],\n                ['w wo ww',                            '6 6 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                'pm PM'],\n                ['[ngày thứ] DDDo [của năm]',          'ngày thứ 45 của năm'],\n                ['LTS',                                '15:25:50'],\n                ['L',                                  '14/02/2010'],\n                ['LL',                                 '14 tháng 2 năm 2010'],\n                ['LLL',                                '14 tháng 2 năm 2010 15:25'],\n                ['LLLL',                               'chủ nhật, 14 tháng 2 năm 2010 15:25'],\n                ['l',                                  '14/2/2010'],\n                ['ll',                                 '14 Th02 2010'],\n                ['lll',                                '14 Th02 2010 15:25'],\n                ['llll',                               'CN, 14 Th02 2010 15:25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format ordinal', function (assert) {\n        assert.equal(moment([2011, 0, 1]).format('DDDo'), '1', '1');\n        assert.equal(moment([2011, 0, 2]).format('DDDo'), '2', '2');\n        assert.equal(moment([2011, 0, 3]).format('DDDo'), '3', '3');\n        assert.equal(moment([2011, 0, 4]).format('DDDo'), '4', '4');\n        assert.equal(moment([2011, 0, 5]).format('DDDo'), '5', '5');\n        assert.equal(moment([2011, 0, 6]).format('DDDo'), '6', '6');\n        assert.equal(moment([2011, 0, 7]).format('DDDo'), '7', '7');\n        assert.equal(moment([2011, 0, 8]).format('DDDo'), '8', '8');\n        assert.equal(moment([2011, 0, 9]).format('DDDo'), '9', '9');\n        assert.equal(moment([2011, 0, 10]).format('DDDo'), '10', '10');\n\n        assert.equal(moment([2011, 0, 11]).format('DDDo'), '11', '11');\n        assert.equal(moment([2011, 0, 12]).format('DDDo'), '12', '12');\n        assert.equal(moment([2011, 0, 13]).format('DDDo'), '13', '13');\n        assert.equal(moment([2011, 0, 14]).format('DDDo'), '14', '14');\n        assert.equal(moment([2011, 0, 15]).format('DDDo'), '15', '15');\n        assert.equal(moment([2011, 0, 16]).format('DDDo'), '16', '16');\n        assert.equal(moment([2011, 0, 17]).format('DDDo'), '17', '17');\n        assert.equal(moment([2011, 0, 18]).format('DDDo'), '18', '18');\n        assert.equal(moment([2011, 0, 19]).format('DDDo'), '19', '19');\n        assert.equal(moment([2011, 0, 20]).format('DDDo'), '20', '20');\n\n        assert.equal(moment([2011, 0, 21]).format('DDDo'), '21', '21');\n        assert.equal(moment([2011, 0, 22]).format('DDDo'), '22', '22');\n        assert.equal(moment([2011, 0, 23]).format('DDDo'), '23', '23');\n        assert.equal(moment([2011, 0, 24]).format('DDDo'), '24', '24');\n        assert.equal(moment([2011, 0, 25]).format('DDDo'), '25', '25');\n        assert.equal(moment([2011, 0, 26]).format('DDDo'), '26', '26');\n        assert.equal(moment([2011, 0, 27]).format('DDDo'), '27', '27');\n        assert.equal(moment([2011, 0, 28]).format('DDDo'), '28', '28');\n        assert.equal(moment([2011, 0, 29]).format('DDDo'), '29', '29');\n        assert.equal(moment([2011, 0, 30]).format('DDDo'), '30', '30');\n\n        assert.equal(moment([2011, 0, 31]).format('DDDo'), '31', '31');\n    });\n\n    test('format month', function (assert) {\n        var i,\n            expected = 'tháng 1,Th01_tháng 2,Th02_tháng 3,Th03_tháng 4,Th04_tháng 5,Th05_tháng 6,Th06_tháng 7,Th07_tháng 8,Th08_tháng 9,Th09_tháng 10,Th10_tháng 11,Th11_tháng 12,Th12'.split('_');\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM,MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var i,\n            expected = 'chủ nhật CN CN_thứ hai T2 T2_thứ ba T3 T3_thứ tư T4 T4_thứ năm T5 T5_thứ sáu T6 T6_thứ bảy T7 T7'.split('_');\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  'vài giây', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  'một phút',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  'một phút',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2 phút',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44 phút',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  'một giờ',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  'một giờ',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2 giờ',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5 giờ',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21 giờ',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  'một ngày',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  'một ngày',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2 ngày',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   'một ngày',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5 ngày',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25 ngày',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  'một tháng',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  'một tháng',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  'một tháng',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2 tháng',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2 tháng',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3 tháng',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   'một tháng',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5 tháng',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), 'một năm',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2 năm',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   'một năm',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5 năm',       '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), 'vài giây tới',  'prefix');\n        assert.equal(moment(0).from(30000), 'vài giây trước', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), 'vài giây trước',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), 'vài giây tới', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), '5 ngày tới', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     'Hôm nay lúc 02:00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Hôm nay lúc 02:25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Hôm nay lúc 03:00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Ngày mai lúc 02:00',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Hôm nay lúc 01:00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Hôm qua lúc 02:00', 'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [tuần tới lúc] LT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [tuần tới lúc] LT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [tuần tới lúc] LT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('dddd [tuần rồi lúc] LT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('dddd [tuần rồi lúc] LT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('dddd [tuần rồi lúc] LT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),  '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0, 2]).week(),  1, 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0, 8]).week(),  1, 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0, 9]).week(),  2, 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 2, 'Jan 15 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).week(),  1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007, 0, 7]).week(),  1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007, 0, 8]).week(),  2, 'Jan  8 2007 should be week 2');\n        assert.equal(moment([2007, 0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n        assert.equal(moment([2007, 0, 15]).week(), 3, 'Jan 15 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).week(), 1, 'Dec 31 2007 should be week 1');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0,  7]).week(), 2, 'Jan  7 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n        assert.equal(moment([2008,  0, 14]).week(), 3, 'Jan 14 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).week(), 1, 'Dec 30 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0,  6]).week(), 2, 'Jan  6 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n        assert.equal(moment([2003,  0, 13]).week(), 3, 'Jan 13 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).week(), 1, 'Dec 29 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0,  5]).week(), 2, 'Jan  5 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n        assert.equal(moment([2009,  0, 13]).week(), 3, 'Jan 12 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).week(), 53, 'Dec 28 2009 should be week 53');\n        assert.equal(moment([2010,  0,  1]).week(), 53, 'Jan  1 2010 should be week 53');\n        assert.equal(moment([2010,  0,  3]).week(), 53, 'Jan  3 2010 should be week 53');\n        assert.equal(moment([2010,  0,  4]).week(),  1, 'Jan  4 2010 should be week 1');\n        assert.equal(moment([2010,  0, 10]).week(),  1, 'Jan 10 2010 should be week 1');\n        assert.equal(moment([2010,  0, 11]).week(),  2, 'Jan 11 2010 should be week 2');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).week(), 52, 'Dec 27 2010 should be week 52');\n        assert.equal(moment([2011,  0,  1]).week(), 52, 'Jan  1 2011 should be week 52');\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  3]).week(),  1, 'Jan  3 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(),  1, 'Jan  9 2011 should be week 1');\n        assert.equal(moment([2011,  0, 10]).week(),  2, 'Jan 10 2011 should be week 2');\n    });\n\n    test('weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52', 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).format('w ww wo'),   '1 01 1', 'Jan  2 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'),   '1 01 1', 'Jan  8 2012 should be week 1');\n        assert.equal(moment([2012, 0,  9]).format('w ww wo'),   '2 02 2', 'Jan  9 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'),   '2 02 2', 'Jan 15 2012 should be week 2');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('zh-cn');\n\n    test('parse', function (assert) {\n        var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, a h:mm:ss',      '星期日, 二月 14日 2010, 下午 3:25:50'],\n                ['ddd, Ah',                            '周日, 下午3'],\n                ['M Mo MM MMMM MMM',                   '2 2月 02 二月 2月'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14日 14'],\n                ['d do dddd ddd dd',                   '0 0日 星期日 周日 日'],\n                ['DDD DDDo DDDD',                      '45 45日 045'],\n                ['w wo ww',                            '6 6周 06'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                '下午 下午'],\n                ['[这年的第] DDDo',                    '这年的第 45日'],\n                ['LTS',                                '下午3点25分50秒'],\n                ['L',                                  '2010-02-14'],\n                ['LL',                                 '2010年2月14日'],\n                ['LLL',                                '2010年2月14日下午3点25'],\n                ['LLLL',                               '2010年2月14日星期日下午3点25'],\n                ['l',                                  '2010-02-14'],\n                ['ll',                                 '2010年2月14日'],\n                ['lll',                                '2010年2月14日下午3点25'],\n                ['llll',                               '2010年2月14日星期日下午3点25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format month', function (assert) {\n        var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = '星期日 周日 日_星期一 周一 一_星期二 周二 二_星期三 周三 三_星期四 周四 四_星期五 周五 五_星期六 周六 六'.split('_'), i;\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '几秒',   '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '1分钟', '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '1分钟', '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2分钟',  '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44分钟', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '1小时', '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '1小时', '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2小时',  '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5小时',  '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21小时', '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '1天',   '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '1天',   '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2天',   '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '1天',   '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5天',   '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25天',  '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '1个月', '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '1个月', '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '1个月', '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2个月',  '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2个月',  '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3个月',  '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '1个月', '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5个月',  '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '1年',   '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2年',   '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '1年',   '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5年',   '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), '几秒内',  'prefix');\n        assert.equal(moment(0).from(30000), '几秒前', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), '几秒前',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), '几秒内', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), '5天内', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     '今天凌晨2点整',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      '今天凌晨2点25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       '今天凌晨3点整',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       '明天凌晨2点整',     'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  '今天凌晨1点整',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  '昨天凌晨2点整',     'yesterday at the same time');\n    });\n\n    test('calendar current week', function (assert) {\n        var i, m,\n            today = moment().startOf('day');\n\n        for (i = 0; i < 7; i++) {\n            m = moment().startOf('week').add({d: i});\n            if (Math.abs(m.diff(today, 'days')) <= 1) {\n                continue; // skip today, yesterday, tomorrow\n            }\n            assert.equal(m.calendar(),       m.format('[本]ddd凌晨12点整'),  'Monday + ' + i + ' days current time');\n        }\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m,\n            today = moment().startOf('day');\n\n        for (i = 7; i < 14; i++) {\n            m = moment().startOf('week').add({d: i});\n            if (Math.abs(m.diff(today, 'days')) >= 7) {\n                continue;\n            }\n            if (Math.abs(m.diff(today, 'days')) <= 1) {\n                continue; // skip today, yesterday, tomorrow\n            }\n            assert.equal(m.calendar(),  m.format('[下]ddd凌晨12点整'), 'Today + ' + i + ' days beginning of day');\n        }\n        assert.equal(42, 42, 'at least one assert');\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m,\n            today = moment().startOf('day');\n\n        for (i = 1; i < 8; i++) {\n            m = moment().startOf('week').subtract({d: i});\n            if ((Math.abs(m.diff(today, 'days')) >= 7) || (Math.abs(m.diff(today, 'days')) <= 1)) {\n                continue;\n            }\n            assert.equal(m.calendar(),  m.format('[上]ddd凌晨12点整'),  'Monday - ' + i + ' days next week');\n        }\n        assert.equal(42, 42, 'at least one assert');\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('LL'),      '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('LL'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('LL'),      '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('LL'),  'in 2 weeks');\n    });\n\n    test('meridiem', function (assert) {\n        assert.equal(moment([2011, 2, 23,  0, 0]).format('A'), '凌晨', 'before dawn');\n        assert.equal(moment([2011, 2, 23,  6, 0]).format('A'), '早上', 'morning');\n        assert.equal(moment([2011, 2, 23,  9, 0]).format('A'), '上午', 'before noon');\n        assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), '中午', 'noon');\n        assert.equal(moment([2011, 2, 23, 13, 0]).format('A'), '下午', 'afternoon');\n        assert.equal(moment([2011, 2, 23, 18, 0]).format('A'), '晚上', 'night');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0,  1]).week(), 52, 'Jan  1 2012 should be week 52');\n        assert.equal(moment([2012, 0,  2]).week(), 1, 'Jan  2 2012 should be week 52');\n        assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 31]).week(), 52, 'Dec 31 2006 should be week 52');\n        assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n        assert.equal(moment([2007,  0,  7]).week(), 1, 'Jan  7 2007 should be week 1');\n        assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n        assert.equal(moment([2007,  0, 14]).week(), 2, 'Jan 14 2007 should be week 2');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 1, 'Jan  6 2008 should be week 1');\n        assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 2, 'Jan 13 2008 should be week 2');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 29]).week(), 52, 'Dec 29 2002 should be week 52');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 1, 'Jan  5 2003 should be week 1');\n        assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 2, 'Jan 12 2003 should be week 2');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 1, 'Jan  4 2009 should be week 1');\n        assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 2, 'Jan 11 2009 should be week 2');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2010,  0,  2]).week(), 53, 'Jan  2 2010 should be week 53');\n        assert.equal(moment([2010,  0, 10]).week(), 1, 'Jan 10 2010 should be week 1');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2011,  0,  2]).week(), 52, 'Jan  2 2011 should be week 52');\n        assert.equal(moment([2011,  0,  8]).week(), 1, 'Jan  8 2011 should be week 1');\n        assert.equal(moment([2011,  0,  9]).week(), 1, 'Jan  9 2011 should be week 1');\n    });\n\n    test('weeks year starting sunday format', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '52 52 52周', 'Jan  1 2012 应该是第52周');\n        assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1周', 'Jan  7 2012 应该是第 1周');\n        assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2周', 'Jan 14 2012 应该是第 2周');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    localeModule('zh-tw');\n\n    test('parse', function (assert) {\n        var tests = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n        function equalTest(input, mmm, i) {\n            assert.equal(moment(input, mmm).month(), i, input + ' should be month ' + (i + 1));\n        }\n        for (i = 0; i < 12; i++) {\n            tests[i] = tests[i].split(' ');\n            equalTest(tests[i][0], 'MMM', i);\n            equalTest(tests[i][1], 'MMM', i);\n            equalTest(tests[i][0], 'MMMM', i);\n            equalTest(tests[i][1], 'MMMM', i);\n            equalTest(tests[i][0].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleLowerCase(), 'MMMM', i);\n            equalTest(tests[i][0].toLocaleUpperCase(), 'MMMM', i);\n            equalTest(tests[i][1].toLocaleUpperCase(), 'MMMM', i);\n        }\n    });\n\n    test('format', function (assert) {\n        var a = [\n                ['dddd, MMMM Do YYYY, a h:mm:ss',      '星期日, 二月 14日 2010, 下午 3:25:50'],\n                ['ddd, Ah',                            '週日, 下午3'],\n                ['M Mo MM MMMM MMM',                   '2 2月 02 二月 2月'],\n                ['YYYY YY',                            '2010 10'],\n                ['D Do DD',                            '14 14日 14'],\n                ['d do dddd ddd dd',                   '0 0日 星期日 週日 日'],\n                ['DDD DDDo DDDD',                      '45 45日 045'],\n                ['w wo ww',                            '8 8週 08'],\n                ['h hh',                               '3 03'],\n                ['H HH',                               '15 15'],\n                ['m mm',                               '25 25'],\n                ['s ss',                               '50 50'],\n                ['a A',                                '下午 下午'],\n                ['[這年的第] DDDo',                    '這年的第 45日'],\n                ['LTS',                                '下午3點25分50秒'],\n                ['L',                                  '2010年2月14日'],\n                ['LL',                                 '2010年2月14日'],\n                ['LLL',                                '2010年2月14日下午3點25'],\n                ['LLLL',                               '2010年2月14日星期日下午3點25'],\n                ['l',                                  '2010年2月14日'],\n                ['ll',                                 '2010年2月14日'],\n                ['lll',                                '2010年2月14日下午3點25'],\n                ['llll',                               '2010年2月14日星期日下午3點25']\n            ],\n            b = moment(new Date(2010, 1, 14, 15, 25, 50, 125)),\n            i;\n\n        for (i = 0; i < a.length; i++) {\n            assert.equal(b.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('format month', function (assert) {\n        var expected = '一月 1月_二月 2月_三月 3月_四月 4月_五月 5月_六月 6月_七月 7月_八月 8月_九月 9月_十月 10月_十一月 11月_十二月 12月'.split('_'), i;\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, i, 1]).format('MMMM MMM'), expected[i], expected[i]);\n        }\n    });\n\n    test('format week', function (assert) {\n        var expected = '星期日 週日 日_星期一 週一 一_星期二 週二 二_星期三 週三 三_星期四 週四 四_星期五 週五 五_星期六 週六 六'.split('_'), i;\n\n        for (i = 0; i < expected.length; i++) {\n            assert.equal(moment([2011, 0, 2 + i]).format('dddd ddd dd'), expected[i], expected[i]);\n        }\n    });\n\n    test('from', function (assert) {\n        var start = moment([2007, 1, 28]);\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44}), true),  '幾秒',   '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45}), true),  '一分鐘', '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89}), true),  '一分鐘', '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true),  '2分鐘',  '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44}), true),  '44分鐘', '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45}), true),  '一小時', '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89}), true),  '一小時', '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90}), true),  '2小時',  '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5}), true),   '5小時',  '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21}), true),  '21小時', '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22}), true),  '一天',   '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35}), true),  '一天',   '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36}), true),  '2天',   '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1}), true),   '一天',   '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5}), true),   '5天',   '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25}), true),  '25天',  '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26}), true),  '一個月', '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30}), true),  '一個月', '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43}), true),  '一個月', '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46}), true),  '2個月',  '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74}), true),  '2個月',  '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76}), true),  '3個月',  '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1}), true),   '一個月', '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5}), true),   '5個月',  '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345}), true), '一年',   '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548}), true), '2年',   '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1}), true),   '一年',   '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5}), true),   '5年',   '5 years = 5 years');\n    });\n\n    test('suffix', function (assert) {\n        assert.equal(moment(30000).from(0), '幾秒內',  'prefix');\n        assert.equal(moment(0).from(30000), '幾秒前', 'suffix');\n    });\n\n    test('now from now', function (assert) {\n        assert.equal(moment().fromNow(), '幾秒前',  'now from now should display as in the past');\n    });\n\n    test('fromNow', function (assert) {\n        assert.equal(moment().add({s: 30}).fromNow(), '幾秒內', 'in a few seconds');\n        assert.equal(moment().add({d: 5}).fromNow(), '5天內', 'in 5 days');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                     '今天早上2點00',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      '今天早上2點25',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       '今天早上3點00',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       '明天早上2點00',     'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  '今天早上1點00',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  '昨天早上2點00',     'yesterday at the same time');\n    });\n\n    test('calendar next week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().add({d: i});\n            assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[下]ddddLT'),  'Today + ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar last week', function (assert) {\n        var i, m;\n        for (i = 2; i < 7; i++) {\n            m = moment().subtract({d: i});\n            assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days current time');\n            m.hours(0).minutes(0).seconds(0).milliseconds(0);\n            assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days beginning of day');\n            m.hours(23).minutes(59).seconds(59).milliseconds(999);\n            assert.equal(m.calendar(),       m.format('[上]ddddLT'),  'Today - ' + i + ' days end of day');\n        }\n    });\n\n    test('calendar all else', function (assert) {\n        var weeksAgo = moment().subtract({w: 1}),\n            weeksFromNow = moment().add({w: 1});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '1 week ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 1 week');\n\n        weeksAgo = moment().subtract({w: 2});\n        weeksFromNow = moment().add({w: 2});\n\n        assert.equal(weeksAgo.calendar(),       weeksAgo.format('L'),      '2 weeks ago');\n        assert.equal(weeksFromNow.calendar(),   weeksFromNow.format('L'),  'in 2 weeks');\n    });\n\n    test('meridiem', function (assert) {\n        assert.equal(moment([2011, 2, 23,  0, 0]).format('a'), '早上', 'morning');\n        assert.equal(moment([2011, 2, 23,  9, 0]).format('a'), '上午', 'before noon');\n        assert.equal(moment([2011, 2, 23, 12, 0]).format('a'), '中午', 'noon');\n        assert.equal(moment([2011, 2, 23, 13, 0]).format('a'), '下午', 'after noon');\n        assert.equal(moment([2011, 2, 23, 18, 0]).format('a'), '晚上', 'night');\n\n        assert.equal(moment([2011, 2, 23,  0, 0]).format('A'), '早上', 'morning');\n        assert.equal(moment([2011, 2, 23,  9, 0]).format('A'), '上午', 'before noon');\n        assert.equal(moment([2011, 2, 23, 12, 0]).format('A'), '中午', 'noon');\n        assert.equal(moment([2011, 2, 23, 13, 0]).format('A'), '下午', 'afternoon');\n        assert.equal(moment([2011, 2, 23, 18, 0]).format('A'), '晚上', 'night');\n    });\n\n    test('weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0,  1]).week(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).week(), 1, 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).week(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).week(), 2, 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).week(), 3, 'Jan 15 2012 should be week 3');\n    });\n\n    test('weeks year starting monday', function (assert) {\n        assert.equal(moment([2006, 11, 31]).week(), 1, 'Dec 31 2006 should be week 1');\n        assert.equal(moment([2007,  0,  1]).week(), 1, 'Jan  1 2007 should be week 1');\n        assert.equal(moment([2007,  0,  6]).week(), 1, 'Jan  6 2007 should be week 1');\n        assert.equal(moment([2007,  0,  7]).week(), 2, 'Jan  7 2007 should be week 2');\n        assert.equal(moment([2007,  0, 13]).week(), 2, 'Jan 13 2007 should be week 2');\n        assert.equal(moment([2007,  0, 14]).week(), 3, 'Jan 14 2007 should be week 3');\n    });\n\n    test('weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 29]).week(), 52, 'Dec 29 2007 should be week 52');\n        assert.equal(moment([2008,  0,  1]).week(), 1, 'Jan  1 2008 should be week 1');\n        assert.equal(moment([2008,  0,  5]).week(), 1, 'Jan  5 2008 should be week 1');\n        assert.equal(moment([2008,  0,  6]).week(), 2, 'Jan  6 2008 should be week 2');\n        assert.equal(moment([2008,  0, 12]).week(), 2, 'Jan 12 2008 should be week 2');\n        assert.equal(moment([2008,  0, 13]).week(), 3, 'Jan 13 2008 should be week 3');\n    });\n\n    test('weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 29]).week(), 1, 'Dec 29 2002 should be week 1');\n        assert.equal(moment([2003,  0,  1]).week(), 1, 'Jan  1 2003 should be week 1');\n        assert.equal(moment([2003,  0,  4]).week(), 1, 'Jan  4 2003 should be week 1');\n        assert.equal(moment([2003,  0,  5]).week(), 2, 'Jan  5 2003 should be week 2');\n        assert.equal(moment([2003,  0, 11]).week(), 2, 'Jan 11 2003 should be week 2');\n        assert.equal(moment([2003,  0, 12]).week(), 3, 'Jan 12 2003 should be week 3');\n    });\n\n    test('weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 28]).week(), 1, 'Dec 28 2008 should be week 1');\n        assert.equal(moment([2009,  0,  1]).week(), 1, 'Jan  1 2009 should be week 1');\n        assert.equal(moment([2009,  0,  3]).week(), 1, 'Jan  3 2009 should be week 1');\n        assert.equal(moment([2009,  0,  4]).week(), 2, 'Jan  4 2009 should be week 2');\n        assert.equal(moment([2009,  0, 10]).week(), 2, 'Jan 10 2009 should be week 2');\n        assert.equal(moment([2009,  0, 11]).week(), 3, 'Jan 11 2009 should be week 3');\n    });\n\n    test('weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 27]).week(), 1, 'Dec 27 2009 should be week 1');\n        assert.equal(moment([2010,  0,  1]).week(), 1, 'Jan  1 2010 should be week 1');\n        assert.equal(moment([2010,  0,  2]).week(), 1, 'Jan  2 2010 should be week 1');\n        assert.equal(moment([2010,  0,  3]).week(), 2, 'Jan  3 2010 should be week 2');\n        assert.equal(moment([2010,  0,  9]).week(), 2, 'Jan  9 2010 should be week 2');\n        assert.equal(moment([2010,  0, 10]).week(), 3, 'Jan 10 2010 should be week 3');\n    });\n\n    test('weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 26]).week(), 1, 'Dec 26 2010 should be week 1');\n        assert.equal(moment([2011,  0,  1]).week(), 1, 'Jan  1 2011 should be week 1');\n        assert.equal(moment([2011,  0,  2]).week(), 2, 'Jan  2 2011 should be week 2');\n        assert.equal(moment([2011,  0,  8]).week(), 2, 'Jan  8 2011 should be week 2');\n        assert.equal(moment([2011,  0,  9]).week(), 3, 'Jan  9 2011 should be week 3');\n    });\n\n    test('weeks year starting sunday format', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('w ww wo'), '1 01 1週', 'Jan  1 2012 應該是第 1週');\n        assert.equal(moment([2012, 0,  7]).format('w ww wo'), '1 01 1週', 'Jan  7 2012 應該是第 1週');\n        assert.equal(moment([2012, 0,  8]).format('w ww wo'), '2 02 2週', 'Jan  8 2012 應該是第 2週');\n        assert.equal(moment([2012, 0, 14]).format('w ww wo'), '2 02 2週', 'Jan 14 2012 應該是第 2週');\n        assert.equal(moment([2012, 0, 15]).format('w ww wo'), '3 03 3週', 'Jan 15 2012 應該是第 3週');\n    });\n\n    test('lenient ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing ' + i + ' date check');\n        }\n    });\n\n    test('lenient ordinal parsing of number', function (assert) {\n        var i, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            testMoment = moment('2014 01 ' + i, 'YYYY MM Do');\n            assert.equal(testMoment.year(), 2014,\n                    'lenient ordinal parsing of number ' + i + ' year check');\n            assert.equal(testMoment.month(), 0,\n                    'lenient ordinal parsing of number ' + i + ' month check');\n            assert.equal(testMoment.date(), i,\n                    'lenient ordinal parsing of number ' + i + ' date check');\n        }\n    });\n\n    test('meridiem invariant', function (assert) {\n        var h, m, t1, t2;\n        for (h = 0; h < 24; ++h) {\n            for (m = 0; m < 60; m += 15) {\n                t1 = moment.utc([2000, 0, 1, h, m]);\n                t2 = moment(t1.format('A h:mm'), 'A h:mm');\n                assert.equal(t2.format('HH:mm'), t1.format('HH:mm'),\n                        'meridiem at ' + t1.format('HH:mm'));\n            }\n        }\n    });\n\n    test('strict ordinal parsing', function (assert) {\n        var i, ordinalStr, testMoment;\n        for (i = 1; i <= 31; ++i) {\n            ordinalStr = moment([2014, 0, i]).format('YYYY MM Do');\n            testMoment = moment(ordinalStr, 'YYYY MM Do', true);\n            assert.ok(testMoment.isValid(), 'strict ordinal parsing ' + i);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('add and subtract');\n\n    test('add short reverse args', function (assert) {\n        var a = moment(), b, c, d;\n        a.year(2011);\n        a.month(9);\n        a.date(12);\n        a.hours(6);\n        a.minutes(7);\n        a.seconds(8);\n        a.milliseconds(500);\n\n        assert.equal(a.add({ms: 50}).milliseconds(), 550, 'Add milliseconds');\n        assert.equal(a.add({s: 1}).seconds(), 9, 'Add seconds');\n        assert.equal(a.add({m: 1}).minutes(), 8, 'Add minutes');\n        assert.equal(a.add({h: 1}).hours(), 7, 'Add hours');\n        assert.equal(a.add({d: 1}).date(), 13, 'Add date');\n        assert.equal(a.add({w: 1}).date(), 20, 'Add week');\n        assert.equal(a.add({M: 1}).month(), 10, 'Add month');\n        assert.equal(a.add({y: 1}).year(), 2012, 'Add year');\n        assert.equal(a.add({Q: 1}).month(), 1, 'Add quarter');\n\n        b = moment([2010, 0, 31]).add({M: 1});\n        c = moment([2010, 1, 28]).subtract({M: 1});\n        d = moment([2010, 1, 28]).subtract({Q: 1});\n\n        assert.equal(b.month(), 1, 'add month, jan 31st to feb 28th');\n        assert.equal(b.date(), 28, 'add month, jan 31st to feb 28th');\n        assert.equal(c.month(), 0, 'subtract month, feb 28th to jan 28th');\n        assert.equal(c.date(), 28, 'subtract month, feb 28th to jan 28th');\n        assert.equal(d.month(), 10, 'subtract quarter, feb 28th 2010 to nov 28th 2009');\n        assert.equal(d.date(), 28, 'subtract quarter, feb 28th 2010 to nov 28th 2009');\n        assert.equal(d.year(), 2009, 'subtract quarter, feb 28th 2010 to nov 28th 2009');\n    });\n\n    test('add long reverse args', function (assert) {\n        var a = moment();\n        a.year(2011);\n        a.month(9);\n        a.date(12);\n        a.hours(6);\n        a.minutes(7);\n        a.seconds(8);\n        a.milliseconds(500);\n\n        assert.equal(a.add({milliseconds: 50}).milliseconds(), 550, 'Add milliseconds');\n        assert.equal(a.add({seconds: 1}).seconds(), 9, 'Add seconds');\n        assert.equal(a.add({minutes: 1}).minutes(), 8, 'Add minutes');\n        assert.equal(a.add({hours: 1}).hours(), 7, 'Add hours');\n        assert.equal(a.add({days: 1}).date(), 13, 'Add date');\n        assert.equal(a.add({weeks: 1}).date(), 20, 'Add week');\n        assert.equal(a.add({months: 1}).month(), 10, 'Add month');\n        assert.equal(a.add({years: 1}).year(), 2012, 'Add year');\n        assert.equal(a.add({quarters: 1}).month(), 1, 'Add quarter');\n    });\n\n    test('add long singular reverse args', function (assert) {\n        var a = moment();\n        a.year(2011);\n        a.month(9);\n        a.date(12);\n        a.hours(6);\n        a.minutes(7);\n        a.seconds(8);\n        a.milliseconds(500);\n\n        assert.equal(a.add({millisecond: 50}).milliseconds(), 550, 'Add milliseconds');\n        assert.equal(a.add({second: 1}).seconds(), 9, 'Add seconds');\n        assert.equal(a.add({minute: 1}).minutes(), 8, 'Add minutes');\n        assert.equal(a.add({hour: 1}).hours(), 7, 'Add hours');\n        assert.equal(a.add({day: 1}).date(), 13, 'Add date');\n        assert.equal(a.add({week: 1}).date(), 20, 'Add week');\n        assert.equal(a.add({month: 1}).month(), 10, 'Add month');\n        assert.equal(a.add({year: 1}).year(), 2012, 'Add year');\n        assert.equal(a.add({quarter: 1}).month(), 1, 'Add quarter');\n    });\n\n    test('add string long reverse args', function (assert) {\n        var a = moment(), b;\n        a.year(2011);\n        a.month(9);\n        a.date(12);\n        a.hours(6);\n        a.minutes(7);\n        a.seconds(8);\n        a.milliseconds(500);\n\n        b = a.clone();\n\n        assert.equal(a.add('millisecond', 50).milliseconds(), 550, 'Add milliseconds');\n        assert.equal(a.add('second', 1).seconds(), 9, 'Add seconds');\n        assert.equal(a.add('minute', 1).minutes(), 8, 'Add minutes');\n        assert.equal(a.add('hour', 1).hours(), 7, 'Add hours');\n        assert.equal(a.add('day', 1).date(), 13, 'Add date');\n        assert.equal(a.add('week', 1).date(), 20, 'Add week');\n        assert.equal(a.add('month', 1).month(), 10, 'Add month');\n        assert.equal(a.add('year', 1).year(), 2012, 'Add year');\n        assert.equal(b.add('day', '01').date(), 13, 'Add date');\n        assert.equal(a.add('quarter', 1).month(), 1, 'Add quarter');\n    });\n\n    test('add string long singular reverse args', function (assert) {\n        var a = moment(), b;\n        a.year(2011);\n        a.month(9);\n        a.date(12);\n        a.hours(6);\n        a.minutes(7);\n        a.seconds(8);\n        a.milliseconds(500);\n\n        b = a.clone();\n\n        assert.equal(a.add('milliseconds', 50).milliseconds(), 550, 'Add milliseconds');\n        assert.equal(a.add('seconds', 1).seconds(), 9, 'Add seconds');\n        assert.equal(a.add('minutes', 1).minutes(), 8, 'Add minutes');\n        assert.equal(a.add('hours', 1).hours(), 7, 'Add hours');\n        assert.equal(a.add('days', 1).date(), 13, 'Add date');\n        assert.equal(a.add('weeks', 1).date(), 20, 'Add week');\n        assert.equal(a.add('months', 1).month(), 10, 'Add month');\n        assert.equal(a.add('years', 1).year(), 2012, 'Add year');\n        assert.equal(b.add('days', '01').date(), 13, 'Add date');\n        assert.equal(a.add('quarters', 1).month(), 1, 'Add quarter');\n    });\n\n    test('add string short reverse args', function (assert) {\n        var a = moment();\n        a.year(2011);\n        a.month(9);\n        a.date(12);\n        a.hours(6);\n        a.minutes(7);\n        a.seconds(8);\n        a.milliseconds(500);\n\n        assert.equal(a.add('ms', 50).milliseconds(), 550, 'Add milliseconds');\n        assert.equal(a.add('s', 1).seconds(), 9, 'Add seconds');\n        assert.equal(a.add('m', 1).minutes(), 8, 'Add minutes');\n        assert.equal(a.add('h', 1).hours(), 7, 'Add hours');\n        assert.equal(a.add('d', 1).date(), 13, 'Add date');\n        assert.equal(a.add('w', 1).date(), 20, 'Add week');\n        assert.equal(a.add('M', 1).month(), 10, 'Add month');\n        assert.equal(a.add('y', 1).year(), 2012, 'Add year');\n        assert.equal(a.add('Q', 1).month(), 1, 'Add quarter');\n    });\n\n    test('add string long', function (assert) {\n        var a = moment();\n        a.year(2011);\n        a.month(9);\n        a.date(12);\n        a.hours(6);\n        a.minutes(7);\n        a.seconds(8);\n        a.milliseconds(500);\n\n        assert.equal(a.add(50, 'millisecond').milliseconds(), 550, 'Add milliseconds');\n        assert.equal(a.add(1, 'second').seconds(), 9, 'Add seconds');\n        assert.equal(a.add(1, 'minute').minutes(), 8, 'Add minutes');\n        assert.equal(a.add(1, 'hour').hours(), 7, 'Add hours');\n        assert.equal(a.add(1, 'day').date(), 13, 'Add date');\n        assert.equal(a.add(1, 'week').date(), 20, 'Add week');\n        assert.equal(a.add(1, 'month').month(), 10, 'Add month');\n        assert.equal(a.add(1, 'year').year(), 2012, 'Add year');\n        assert.equal(a.add(1, 'quarter').month(), 1, 'Add quarter');\n    });\n\n    test('add string long singular', function (assert) {\n        var a = moment();\n        a.year(2011);\n        a.month(9);\n        a.date(12);\n        a.hours(6);\n        a.minutes(7);\n        a.seconds(8);\n        a.milliseconds(500);\n\n        assert.equal(a.add(50, 'milliseconds').milliseconds(), 550, 'Add milliseconds');\n        assert.equal(a.add(1, 'seconds').seconds(), 9, 'Add seconds');\n        assert.equal(a.add(1, 'minutes').minutes(), 8, 'Add minutes');\n        assert.equal(a.add(1, 'hours').hours(), 7, 'Add hours');\n        assert.equal(a.add(1, 'days').date(), 13, 'Add date');\n        assert.equal(a.add(1, 'weeks').date(), 20, 'Add week');\n        assert.equal(a.add(1, 'months').month(), 10, 'Add month');\n        assert.equal(a.add(1, 'years').year(), 2012, 'Add year');\n        assert.equal(a.add(1, 'quarters').month(), 1, 'Add quarter');\n    });\n\n    test('add string short', function (assert) {\n        var a = moment();\n        a.year(2011);\n        a.month(9);\n        a.date(12);\n        a.hours(6);\n        a.minutes(7);\n        a.seconds(8);\n        a.milliseconds(500);\n\n        assert.equal(a.add(50, 'ms').milliseconds(), 550, 'Add milliseconds');\n        assert.equal(a.add(1, 's').seconds(), 9, 'Add seconds');\n        assert.equal(a.add(1, 'm').minutes(), 8, 'Add minutes');\n        assert.equal(a.add(1, 'h').hours(), 7, 'Add hours');\n        assert.equal(a.add(1, 'd').date(), 13, 'Add date');\n        assert.equal(a.add(1, 'w').date(), 20, 'Add week');\n        assert.equal(a.add(1, 'M').month(), 10, 'Add month');\n        assert.equal(a.add(1, 'y').year(), 2012, 'Add year');\n        assert.equal(a.add(1, 'Q').month(), 1, 'Add quarter');\n    });\n\n    test('add strings string short args', function (assert) {\n        var a = moment();\n        a.year(2011);\n        a.month(9);\n        a.date(12);\n        a.hours(6);\n        a.minutes(7);\n        a.seconds(8);\n        a.milliseconds(500);\n\n        assert.equal(a.add('ms', '50').milliseconds(), 550, 'Add milliseconds');\n        assert.equal(a.add('s', '1').seconds(), 9, 'Add seconds');\n        assert.equal(a.add('m', '1').minutes(), 8, 'Add minutes');\n        assert.equal(a.add('h', '1').hours(), 7, 'Add hours');\n        assert.equal(a.add('d', '1').date(), 13, 'Add date');\n        assert.equal(a.add('w', '1').date(), 20, 'Add week');\n        assert.equal(a.add('M', '1').month(), 10, 'Add month');\n        assert.equal(a.add('y', '1').year(), 2012, 'Add year');\n        assert.equal(a.add('Q', '1').month(), 1, 'Add quarter');\n    });\n\n    test('subtract strings string short args', function (assert) {\n        var a = moment();\n        a.year(2011);\n        a.month(9);\n        a.date(12);\n        a.hours(6);\n        a.minutes(7);\n        a.seconds(8);\n        a.milliseconds(500);\n\n        assert.equal(a.subtract('ms', '50').milliseconds(), 450, 'Subtract milliseconds');\n        assert.equal(a.subtract('s', '1').seconds(), 7, 'Subtract seconds');\n        assert.equal(a.subtract('m', '1').minutes(), 6, 'Subtract minutes');\n        assert.equal(a.subtract('h', '1').hours(), 5, 'Subtract hours');\n        assert.equal(a.subtract('d', '1').date(), 11, 'Subtract date');\n        assert.equal(a.subtract('w', '1').date(), 4, 'Subtract week');\n        assert.equal(a.subtract('M', '1').month(), 8, 'Subtract month');\n        assert.equal(a.subtract('y', '1').year(), 2010, 'Subtract year');\n        assert.equal(a.subtract('Q', '1').month(), 5, 'Subtract quarter');\n    });\n\n    test('add strings string short', function (assert) {\n        var a = moment();\n        a.year(2011);\n        a.month(9);\n        a.date(12);\n        a.hours(6);\n        a.minutes(7);\n        a.seconds(8);\n        a.milliseconds(500);\n\n        assert.equal(a.add('50', 'ms').milliseconds(), 550, 'Add milliseconds');\n        assert.equal(a.add('1', 's').seconds(), 9, 'Add seconds');\n        assert.equal(a.add('1', 'm').minutes(), 8, 'Add minutes');\n        assert.equal(a.add('1', 'h').hours(), 7, 'Add hours');\n        assert.equal(a.add('1', 'd').date(), 13, 'Add date');\n        assert.equal(a.add('1', 'w').date(), 20, 'Add week');\n        assert.equal(a.add('1', 'M').month(), 10, 'Add month');\n        assert.equal(a.add('1', 'y').year(), 2012, 'Add year');\n        assert.equal(a.add('1', 'Q').month(), 1, 'Add quarter');\n    });\n\n    test('subtract strings string short', function (assert) {\n        var a = moment();\n        a.year(2011);\n        a.month(9);\n        a.date(12);\n        a.hours(6);\n        a.minutes(7);\n        a.seconds(8);\n        a.milliseconds(500);\n\n        assert.equal(a.subtract('50', 'ms').milliseconds(), 450, 'Subtract milliseconds');\n        assert.equal(a.subtract('1', 's').seconds(), 7, 'Subtract seconds');\n        assert.equal(a.subtract('1', 'm').minutes(), 6, 'Subtract minutes');\n        assert.equal(a.subtract('1', 'h').hours(), 5, 'Subtract hours');\n        assert.equal(a.subtract('1', 'd').date(), 11, 'Subtract date');\n        assert.equal(a.subtract('1', 'w').date(), 4, 'Subtract week');\n        assert.equal(a.subtract('1', 'M').month(), 8, 'Subtract month');\n        assert.equal(a.subtract('1', 'y').year(), 2010, 'Subtract year');\n        assert.equal(a.subtract('1', 'Q').month(), 5, 'Subtract quarter');\n    });\n\n    test('add across DST', function (assert) {\n        if (new Date(2011, 2, 13, 5, 0, 0).getHours() !== 5) {\n            return;\n        }\n\n        var a = moment(new Date(2011, 2, 12, 5, 0, 0)),\n            b = moment(new Date(2011, 2, 12, 5, 0, 0)),\n            c = moment(new Date(2011, 2, 12, 5, 0, 0)),\n            d = moment(new Date(2011, 2, 12, 5, 0, 0)),\n            e = moment(new Date(2011, 2, 12, 5, 0, 0));\n        a.add(1, 'days');\n        b.add(24, 'hours');\n        c.add(1, 'months');\n        e.add(1, 'quarter');\n\n        assert.equal(a.hours(), 5, 'adding days over DST difference should result in the same hour');\n        if (b.isDST() && !d.isDST()) {\n            assert.equal(b.hours(), 6, 'adding hours over DST difference should result in a different hour');\n        } else if (!b.isDST() && d.isDST()) {\n            assert.equal(b.hours(), 4, 'adding hours over DST difference should result in a different hour');\n        } else {\n            assert.equal(b.hours(), 5, 'adding hours over DST difference should result in a same hour if the timezone does not have daylight savings time');\n        }\n        assert.equal(c.hours(), 5, 'adding months over DST difference should result in the same hour');\n        assert.equal(e.hours(), 5, 'adding quarters over DST difference should result in the same hour');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('create');\n\n    test('array', function (assert) {\n        assert.ok(moment([2010]).toDate() instanceof Date, '[2010]');\n        assert.ok(moment([2010, 1]).toDate() instanceof Date, '[2010, 1]');\n        assert.ok(moment([2010, 1, 12]).toDate() instanceof Date, '[2010, 1, 12]');\n        assert.ok(moment([2010, 1, 12, 1]).toDate() instanceof Date, '[2010, 1, 12, 1]');\n        assert.ok(moment([2010, 1, 12, 1, 1]).toDate() instanceof Date, '[2010, 1, 12, 1, 1]');\n        assert.ok(moment([2010, 1, 12, 1, 1, 1]).toDate() instanceof Date, '[2010, 1, 12, 1, 1, 1]');\n        assert.ok(moment([2010, 1, 12, 1, 1, 1, 1]).toDate() instanceof Date, '[2010, 1, 12, 1, 1, 1, 1]');\n        assert.equal(+moment(new Date(2010, 1, 14, 15, 25, 50, 125)), +moment([2010, 1, 14, 15, 25, 50, 125]), 'constructing with array === constructing with new Date()');\n    });\n\n    test('array copying', function (assert) {\n        var importantArray = [2009, 11];\n        moment(importantArray);\n        assert.deepEqual(importantArray, [2009, 11], 'initializer should not mutate the original array');\n    });\n\n    test('object', function (assert) {\n        var fmt = 'YYYY-MM-DD HH:mm:ss.SSS',\n            tests = [\n                [{year: 2010}, '2010-01-01 00:00:00.000'],\n                [{year: 2010, month: 1}, '2010-02-01 00:00:00.000'],\n                [{year: 2010, month: 1, day: 12}, '2010-02-12 00:00:00.000'],\n                [{year: 2010, month: 1, date: 12}, '2010-02-12 00:00:00.000'],\n                [{year: 2010, month: 1, day: 12, hours: 1}, '2010-02-12 01:00:00.000'],\n                [{year: 2010, month: 1, date: 12, hours: 1}, '2010-02-12 01:00:00.000'],\n                [{year: 2010, month: 1, day: 12, hours: 1, minutes: 1}, '2010-02-12 01:01:00.000'],\n                [{year: 2010, month: 1, date: 12, hours: 1, minutes: 1}, '2010-02-12 01:01:00.000'],\n                [{year: 2010, month: 1, day: 12, hours: 1, minutes: 1, seconds: 1}, '2010-02-12 01:01:01.000'],\n                [{year: 2010, month: 1, day: 12, hours: 1, minutes: 1, seconds: 1, milliseconds: 1}, '2010-02-12 01:01:01.001'],\n                [{years: 2010, months: 1, days: 14, hours: 15, minutes: 25, seconds: 50, milliseconds: 125}, '2010-02-14 15:25:50.125'],\n                [{year: 2010, month: 1, day: 14, hour: 15, minute: 25, second: 50, millisecond: 125}, '2010-02-14 15:25:50.125'],\n                [{y: 2010, M: 1, d: 14, h: 15, m: 25, s: 50, ms: 125}, '2010-02-14 15:25:50.125']\n            ], i;\n        for (i = 0; i < tests.length; ++i) {\n            assert.equal(moment(tests[i][0]).format(fmt), tests[i][1]);\n        }\n    });\n\n    test('multi format array copying', function (assert) {\n        var importantArray = ['MM/DD/YYYY', 'YYYY-MM-DD', 'MM-DD-YYYY'];\n        moment('1999-02-13', importantArray);\n        assert.deepEqual(importantArray, ['MM/DD/YYYY', 'YYYY-MM-DD', 'MM-DD-YYYY'], 'initializer should not mutate the original array');\n    });\n\n    test('number', function (assert) {\n        assert.ok(moment(1000).toDate() instanceof Date, '1000');\n        assert.equal(moment(1000).valueOf(), 1000, 'asserting valueOf');\n        assert.equal(moment.utc(1000).valueOf(), 1000, 'asserting valueOf');\n    });\n\n    test('unix', function (assert) {\n        assert.equal(moment.unix(1).valueOf(), 1000, '1 unix timestamp == 1000 Date.valueOf');\n        assert.equal(moment(1000).unix(), 1, '1000 Date.valueOf == 1 unix timestamp');\n        assert.equal(moment.unix(1000).valueOf(), 1000000, '1000 unix timestamp == 1000000 Date.valueOf');\n        assert.equal(moment(1500).unix(), 1, '1500 Date.valueOf == 1 unix timestamp');\n        assert.equal(moment(1900).unix(), 1, '1900 Date.valueOf == 1 unix timestamp');\n        assert.equal(moment(2100).unix(), 2, '2100 Date.valueOf == 2 unix timestamp');\n        assert.equal(moment(1333129333524).unix(), 1333129333, '1333129333524 Date.valueOf == 1333129333 unix timestamp');\n        assert.equal(moment(1333129333524000).unix(), 1333129333524, '1333129333524000 Date.valueOf == 1333129333524 unix timestamp');\n    });\n\n    test('date', function (assert) {\n        assert.ok(moment(new Date()).toDate() instanceof Date, 'new Date()');\n    });\n\n    test('date mutation', function (assert) {\n        var a = new Date();\n        assert.ok(moment(a).toDate() !== a, 'the date moment uses should not be the date passed in');\n    });\n\n    test('moment', function (assert) {\n        assert.ok(moment(moment()).toDate() instanceof Date, 'moment(moment())');\n        assert.ok(moment(moment(moment())).toDate() instanceof Date, 'moment(moment(moment()))');\n    });\n\n    test('cloning moment should only copy own properties', function (assert) {\n        assert.ok(!moment().clone().hasOwnProperty('month'), 'Should not clone prototype methods');\n    });\n\n    test('cloning moment works with weird clones', function (assert) {\n        var extend = function (a, b) {\n            var i;\n            for (i in b) {\n                a[i] = b[i];\n            }\n            return a;\n        },\n        now = moment(),\n        nowu = moment.utc();\n\n        assert.equal(+extend({}, now).clone(), +now, 'cloning extend-ed now is now');\n        assert.equal(+extend({}, nowu).clone(), +nowu, 'cloning extend-ed utc now is utc now');\n    });\n\n    test('cloning respects moment.momentProperties', function (assert) {\n        var m = moment();\n\n        assert.equal(m.clone()._special, undefined, 'cloning ignores extra properties');\n        m._special = 'bacon';\n        moment.momentProperties.push('_special');\n        assert.equal(m.clone()._special, 'bacon', 'cloning respects momentProperties');\n        moment.momentProperties.pop();\n    });\n\n    test('undefined', function (assert) {\n        assert.ok(moment().toDate() instanceof Date, 'undefined');\n    });\n\n    test('iso format 24hrs', function (assert) {\n        assert.equal(moment('2014-01-01T24:00:00.000').format('YYYY-MM-DD[T]HH:mm:ss.SSS'),\n                '2014-01-02T00:00:00.000', 'iso format with 24:00 localtime');\n        assert.equal(moment.utc('2014-01-01T24:00:00.000').format('YYYY-MM-DD[T]HH:mm:ss.SSS'),\n                '2014-01-02T00:00:00.000', 'iso format with 24:00 utc');\n    });\n\n    test('string without format - json', function (assert) {\n        assert.equal(moment('Date(1325132654000)').valueOf(), 1325132654000, 'Date(1325132654000)');\n        assert.equal(moment('Date(-1325132654000)').valueOf(), -1325132654000, 'Date(-1325132654000)');\n        assert.equal(moment('/Date(1325132654000)/').valueOf(), 1325132654000, '/Date(1325132654000)/');\n        assert.equal(moment('/Date(1325132654000+0700)/').valueOf(), 1325132654000, '/Date(1325132654000+0700)/');\n        assert.equal(moment('/Date(1325132654000-0700)/').valueOf(), 1325132654000, '/Date(1325132654000-0700)/');\n    });\n\n    test('string with format dropped am/pm bug', function (assert) {\n        moment.locale('en');\n\n        assert.equal(moment('05/1/2012 12:25:00', 'MM/DD/YYYY h:m:s a').format('MM/DD/YYYY'), '05/01/2012', 'should not break if am/pm is left off from the parsing tokens');\n        assert.equal(moment('05/1/2012 12:25:00 am', 'MM/DD/YYYY h:m:s a').format('MM/DD/YYYY'), '05/01/2012', 'should not break if am/pm is left off from the parsing tokens');\n        assert.equal(moment('05/1/2012 12:25:00 pm', 'MM/DD/YYYY h:m:s a').format('MM/DD/YYYY'), '05/01/2012', 'should not break if am/pm is left off from the parsing tokens');\n\n        assert.ok(moment('05/1/2012 12:25:00', 'MM/DD/YYYY h:m:s a').isValid());\n        assert.ok(moment('05/1/2012 12:25:00 am', 'MM/DD/YYYY h:m:s a').isValid());\n        assert.ok(moment('05/1/2012 12:25:00 pm', 'MM/DD/YYYY h:m:s a').isValid());\n    });\n\n    test('empty string with formats', function (assert) {\n        assert.equal(moment('', 'MM').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n        assert.equal(moment(' ', 'MM').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n        assert.equal(moment(' ', 'DD').format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n        assert.equal(moment(' ', ['MM', 'DD']).format('YYYY-MM-DD HH:mm:ss'), 'Invalid date');\n\n        assert.ok(!moment('', 'MM').isValid());\n        assert.ok(!moment(' ', 'MM').isValid());\n        assert.ok(!moment(' ', 'DD').isValid());\n        assert.ok(!moment(' ', ['MM', 'DD']).isValid());\n    });\n\n    test('defaulting to current date', function (assert) {\n        var now = moment();\n        assert.equal(moment('12:13:14', 'hh:mm:ss').format('YYYY-MM-DD hh:mm:ss'),\n                     now.clone().hour(12).minute(13).second(14).format('YYYY-MM-DD hh:mm:ss'),\n                     'given only time default to current date');\n        assert.equal(moment('05', 'DD').format('YYYY-MM-DD'),\n                     now.clone().date(5).format('YYYY-MM-DD'),\n                     'given day of month default to current month, year');\n        assert.equal(moment('05', 'MM').format('YYYY-MM-DD'),\n                     now.clone().month(4).date(1).format('YYYY-MM-DD'),\n                     'given month default to current year');\n        assert.equal(moment('1996', 'YYYY').format('YYYY-MM-DD'),\n                     now.clone().year(1996).month(0).date(1).format('YYYY-MM-DD'),\n                     'given year do not default');\n    });\n\n    test('matching am/pm', function (assert) {\n        assert.equal(moment('2012-09-03T03:00PM',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for PM');\n        assert.equal(moment('2012-09-03T03:00P.M.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for P.M.');\n        assert.equal(moment('2012-09-03T03:00P',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for P');\n        assert.equal(moment('2012-09-03T03:00pm',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for pm');\n        assert.equal(moment('2012-09-03T03:00p.m.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for p.m.');\n        assert.equal(moment('2012-09-03T03:00p',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00PM', 'am/pm should parse correctly for p');\n\n        assert.equal(moment('2012-09-03T03:00AM',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for AM');\n        assert.equal(moment('2012-09-03T03:00A.M.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for A.M.');\n        assert.equal(moment('2012-09-03T03:00A',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for A');\n        assert.equal(moment('2012-09-03T03:00am',   'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for am');\n        assert.equal(moment('2012-09-03T03:00a.m.', 'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for a.m.');\n        assert.equal(moment('2012-09-03T03:00a',    'YYYY-MM-DDThh:mmA').format('YYYY-MM-DDThh:mmA'), '2012-09-03T03:00AM', 'am/pm should parse correctly for a');\n\n        assert.equal(moment('5:00p.m.March 4 2012', 'h:mmAMMMM D YYYY').format('YYYY-MM-DDThh:mmA'), '2012-03-04T05:00PM', 'am/pm should parse correctly before month names');\n    });\n\n    test('string with format', function (assert) {\n        moment.locale('en');\n        var a = [\n            ['YYYY-Q',              '2014-4'],\n            ['MM-DD-YYYY',          '12-02-1999'],\n            ['DD-MM-YYYY',          '12-02-1999'],\n            ['DD/MM/YYYY',          '12/02/1999'],\n            ['DD_MM_YYYY',          '12_02_1999'],\n            ['DD:MM:YYYY',          '12:02:1999'],\n            ['D-M-YY',              '2-2-99'],\n            ['YY',                  '99'],\n            ['DDD-YYYY',            '300-1999'],\n            ['DD-MM-YYYY h:m:s',    '12-02-1999 2:45:10'],\n            ['DD-MM-YYYY h:m:s a',  '12-02-1999 2:45:10 am'],\n            ['DD-MM-YYYY h:m:s a',  '12-02-1999 2:45:10 pm'],\n            ['h:mm a',              '12:00 pm'],\n            ['h:mm a',              '12:30 pm'],\n            ['h:mm a',              '12:00 am'],\n            ['h:mm a',              '12:30 am'],\n            ['HH:mm',               '12:00'],\n            ['YYYY-MM-DDTHH:mm:ss', '2011-11-11T11:11:11'],\n            ['MM-DD-YYYY [M]',      '12-02-1999 M'],\n            ['ddd MMM DD HH:mm:ss YYYY', 'Tue Apr 07 22:52:51 2009'],\n            ['HH:mm:ss',            '12:00:00'],\n            ['HH:mm:ss',            '12:30:00'],\n            ['HH:mm:ss',            '00:00:00'],\n            ['HH:mm:ss S',          '00:30:00 1'],\n            ['HH:mm:ss SS',         '00:30:00 12'],\n            ['HH:mm:ss SSS',        '00:30:00 123'],\n            ['HH:mm:ss S',          '00:30:00 7'],\n            ['HH:mm:ss SS',         '00:30:00 78'],\n            ['HH:mm:ss SSS',        '00:30:00 789'],\n            ['X',                   '1234567890'],\n            ['x',                   '1234567890123'],\n            ['LT',                  '12:30 AM'],\n            ['LTS',                 '12:30:29 AM'],\n            ['L',                   '09/02/1999'],\n            ['l',                   '9/2/1999'],\n            ['LL',                  'September 2, 1999'],\n            ['ll',                  'Sep 2, 1999'],\n            ['LLL',                 'September 2, 1999 12:30 AM'],\n            ['lll',                 'Sep 2, 1999 12:30 AM'],\n            ['LLLL',                'Thursday, September 2, 1999 12:30 AM'],\n            ['llll',                'Thu, Sep 2, 1999 12:30 AM']\n        ],\n        m,\n        i;\n\n        for (i = 0; i < a.length; i++) {\n            m = moment(a[i][1], a[i][0]);\n            assert.ok(m.isValid());\n            assert.equal(m.format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('unix timestamp format', function (assert) {\n        var formats = ['X', 'X.S', 'X.SS', 'X.SSS'], i, format;\n\n        for (i = 0; i < formats.length; i++) {\n            format = formats[i];\n            assert.equal(moment('1234567890',     format).valueOf(), 1234567890 * 1000,       format + ' matches timestamp without milliseconds');\n            assert.equal(moment('1234567890.1',   format).valueOf(), 1234567890 * 1000 + 100, format + ' matches timestamp with deciseconds');\n            assert.equal(moment('1234567890.12',  format).valueOf(), 1234567890 * 1000 + 120, format + ' matches timestamp with centiseconds');\n            assert.equal(moment('1234567890.123', format).valueOf(), 1234567890 * 1000 + 123, format + ' matches timestamp with milliseconds');\n        }\n    });\n\n    test('unix offset milliseconds', function (assert) {\n        assert.equal(moment('1234567890123', 'x').valueOf(), 1234567890123, 'x matches unix offset in milliseconds');\n    });\n\n    test('milliseconds format', function (assert) {\n        assert.equal(moment('1', 'S').get('ms'), 100, 'deciseconds');\n        assert.equal(moment('12', 'SS').get('ms'), 120, 'centiseconds');\n        assert.equal(moment('123', 'SSS').get('ms'), 123, 'milliseconds');\n        assert.equal(moment('1234', 'SSSS').get('ms'), 123, 'milliseconds with SSSS');\n        assert.equal(moment('123456789101112', 'SSSS').get('ms'), 123, 'milliseconds with SSSS');\n    });\n\n    test('string with format no separators', function (assert) {\n        moment.locale('en');\n        var a = [\n            ['MMDDYYYY',          '12021999'],\n            ['DDMMYYYY',          '12021999'],\n            ['YYYYMMDD',          '19991202'],\n            ['DDMMMYYYY',         '10Sep2001']\n        ], i;\n\n        for (i = 0; i < a.length; i++) {\n            assert.equal(moment(a[i][1], a[i][0]).format(a[i][0]), a[i][1], a[i][0] + ' ---> ' + a[i][1]);\n        }\n    });\n\n    test('string with format (timezone)', function (assert) {\n        assert.equal(moment('5 -0700', 'H ZZ').toDate().getUTCHours(), 12, 'parse hours \\'5 -0700\\' ---> \\'H ZZ\\'');\n        assert.equal(moment('5 -07:00', 'H Z').toDate().getUTCHours(), 12, 'parse hours \\'5 -07:00\\' ---> \\'H Z\\'');\n        assert.equal(moment('5 -0730', 'H ZZ').toDate().getUTCMinutes(), 30, 'parse hours \\'5 -0730\\' ---> \\'H ZZ\\'');\n        assert.equal(moment('5 -07:30', 'H Z').toDate().getUTCMinutes(), 30, 'parse hours \\'5 -07:0\\' ---> \\'H Z\\'');\n        assert.equal(moment('5 +0100', 'H ZZ').toDate().getUTCHours(), 4, 'parse hours \\'5 +0100\\' ---> \\'H ZZ\\'');\n        assert.equal(moment('5 +01:00', 'H Z').toDate().getUTCHours(), 4, 'parse hours \\'5 +01:00\\' ---> \\'H Z\\'');\n        assert.equal(moment('5 +0130', 'H ZZ').toDate().getUTCMinutes(), 30, 'parse hours \\'5 +0130\\' ---> \\'H ZZ\\'');\n        assert.equal(moment('5 +01:30', 'H Z').toDate().getUTCMinutes(), 30, 'parse hours \\'5 +01:30\\' ---> \\'H Z\\'');\n    });\n\n    test('string with format (timezone offset)', function (assert) {\n        var a, b, c, d, e, f;\n        a = new Date(Date.UTC(2011, 0, 1, 1));\n        b = moment('2011 1 1 0 -01:00', 'YYYY MM DD HH Z');\n        assert.equal(a.getHours(), b.hours(), 'date created with utc == parsed string with timezone offset');\n        assert.equal(+a, +b, 'date created with utc == parsed string with timezone offset');\n        c = moment('2011 2 1 10 -05:00', 'YYYY MM DD HH Z');\n        d = moment('2011 2 1 8 -07:00', 'YYYY MM DD HH Z');\n        assert.equal(c.hours(), d.hours(), '10 am central time == 8 am pacific time');\n        e = moment.utc('Fri, 20 Jul 2012 17:15:00', 'ddd, DD MMM YYYY HH:mm:ss');\n        f = moment.utc('Fri, 20 Jul 2012 10:15:00 -0700', 'ddd, DD MMM YYYY HH:mm:ss ZZ');\n        assert.equal(e.hours(), f.hours(), 'parse timezone offset in utc');\n    });\n\n    test('string with timezone around start of year', function (assert) {\n        assert.equal(moment('2000-01-01T00:00:00.000+01:00').toISOString(), '1999-12-31T23:00:00.000Z', '+1:00 around 2000');\n        assert.equal(moment('2000-01-01T00:00:00.000-01:00').toISOString(), '2000-01-01T01:00:00.000Z', '-1:00 around 2000');\n        assert.equal(moment('1970-01-01T00:00:00.000+01:00').toISOString(), '1969-12-31T23:00:00.000Z', '+1:00 around 1970');\n        assert.equal(moment('1970-01-01T00:00:00.000-01:00').toISOString(), '1970-01-01T01:00:00.000Z', '-1:00 around 1970');\n        assert.equal(moment('1200-01-01T00:00:00.000+01:00').toISOString(), '1199-12-31T23:00:00.000Z', '+1:00 around 1200');\n        assert.equal(moment('1200-01-01T00:00:00.000-01:00').toISOString(), '1200-01-01T01:00:00.000Z', '-1:00 around 1200');\n    });\n\n    test('string with array of formats', function (assert) {\n        assert.equal(moment('11-02-1999', ['MM-DD-YYYY', 'DD-MM-YYYY']).format('MM DD YYYY'), '11 02 1999', 'switching month and day');\n        assert.equal(moment('02-11-1999', ['MM/DD/YYYY', 'YYYY MM DD', 'MM-DD-YYYY']).format('MM DD YYYY'), '02 11 1999', 'year last');\n        assert.equal(moment('1999-02-11', ['MM/DD/YYYY', 'YYYY MM DD', 'MM-DD-YYYY']).format('MM DD YYYY'), '02 11 1999', 'year first');\n\n        assert.equal(moment('02-11-1999', ['MM/DD/YYYY', 'YYYY MM DD']).format('MM DD YYYY'), '02 11 1999', 'year last');\n        assert.equal(moment('1999-02-11', ['MM/DD/YYYY', 'YYYY MM DD']).format('MM DD YYYY'), '02 11 1999', 'year first');\n        assert.equal(moment('02-11-1999', ['YYYY MM DD', 'MM/DD/YYYY']).format('MM DD YYYY'), '02 11 1999', 'year last');\n        assert.equal(moment('1999-02-11', ['YYYY MM DD', 'MM/DD/YYYY']).format('MM DD YYYY'), '02 11 1999', 'year first');\n\n        assert.equal(moment('13-11-1999', ['MM/DD/YYYY', 'DD/MM/YYYY']).format('MM DD YYYY'), '11 13 1999', 'second must be month');\n        assert.equal(moment('11-13-1999', ['MM/DD/YYYY', 'DD/MM/YYYY']).format('MM DD YYYY'), '11 13 1999', 'first must be month');\n        assert.equal(moment('01-02-2000', ['MM/DD/YYYY', 'DD/MM/YYYY']).format('MM DD YYYY'), '01 02 2000', 'either can be a month, month first format');\n        assert.equal(moment('02-01-2000', ['DD/MM/YYYY', 'MM/DD/YYYY']).format('MM DD YYYY'), '01 02 2000', 'either can be a month, day first format');\n\n        assert.equal(moment('11-02-10', ['MM/DD/YY', 'YY MM DD', 'DD-MM-YY']).format('MM DD YYYY'), '02 11 2010', 'all unparsed substrings have influence on format penalty');\n        assert.equal(moment('11-02-10', ['MM-DD-YY HH:mm', 'YY MM DD']).format('MM DD YYYY'), '02 10 2011', 'prefer formats without extra tokens');\n        assert.equal(moment('11-02-10 junk', ['MM-DD-YY', 'YY.MM.DD junk']).format('MM DD YYYY'), '02 10 2011', 'prefer formats that dont result in extra characters');\n        assert.equal(moment('11-22-10', ['YY-MM-DD', 'YY-DD-MM']).format('MM DD YYYY'), '10 22 2011', 'prefer valid results');\n\n        assert.equal(moment('gibberish', ['YY-MM-DD', 'YY-DD-MM']).format('MM DD YYYY'), 'Invalid date', 'doest throw for invalid strings');\n        assert.equal(moment('gibberish', []).format('MM DD YYYY'), 'Invalid date', 'doest throw for an empty array');\n        assert.equal(moment(\n            'System Administrator and Database Assistant (7/1/2011), System Administrator and Database Assistant (7/1/2011), Database Coordinator (7/1/2011), Vice President (7/1/2011), System Administrator and Database Assistant (5/31/2012), Database Coordinator (7/1/2012), System Administrator and Database Assistant (7/1/2013)',\n            ['MM/DD/YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD', 'YYYY-MM-DDTHH:mm:ssZ'])\n            .format('YYYY-MM-DD'), '2011-07-01', 'Works for long strings');\n\n        assert.equal(moment('11-02-10', ['MM.DD.YY', 'DD-MM-YY']).format('MM DD YYYY'), '02 11 2010', 'escape RegExp special characters on comparing');\n\n        assert.equal(moment('13-10-98', ['DD MM YY', 'DD MM YYYY'])._f, 'DD MM YY', 'use two digit year');\n        assert.equal(moment('13-10-1998', ['DD MM YY', 'DD MM YYYY'])._f, 'DD MM YYYY', 'use four digit year');\n\n        assert.equal(moment('01', ['MM', 'DD'])._f, 'MM', 'Should use first valid format');\n    });\n\n    test('string with array of formats + ISO', function (assert) {\n        assert.equal(moment('1994', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).year(), 1994, 'iso: assert parse YYYY');\n        assert.equal(moment('17:15', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).hour(), 17, 'iso: assert parse HH:mm (1)');\n        assert.equal(moment('17:15', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).minutes(), 15, 'iso: assert parse HH:mm (2)');\n        assert.equal(moment('06', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).month(), 6 - 1, 'iso: assert parse MM');\n        assert.equal(moment('2012-06-01', [moment.ISO_8601, 'MM', 'HH:mm', 'YYYY']).parsingFlags().iso, true, 'iso: assert parse iso');\n        assert.equal(moment('2014-05-05', [moment.ISO_8601, 'YYYY-MM-DD']).parsingFlags().iso, true, 'iso: edge case array precedence iso');\n        assert.equal(moment('2014-05-05', ['YYYY-MM-DD', moment.ISO_8601]).parsingFlags().iso, false, 'iso: edge case array precedence not iso');\n    });\n\n    test('string with format - years', function (assert) {\n        assert.equal(moment('67', 'YY').format('YYYY'), '2067', '67 > 2067');\n        assert.equal(moment('68', 'YY').format('YYYY'), '2068', '68 > 2068');\n        assert.equal(moment('69', 'YY').format('YYYY'), '1969', '69 > 1969');\n        assert.equal(moment('70', 'YY').format('YYYY'), '1970', '70 > 1970');\n    });\n\n    test('implicit cloning', function (assert) {\n        var momentA = moment([2011, 10, 10]),\n        momentB = moment(momentA);\n        momentA.month(5);\n        assert.equal(momentB.month(), 10, 'Calling moment() on a moment will create a clone');\n        assert.equal(momentA.month(), 5, 'Calling moment() on a moment will create a clone');\n    });\n\n    test('explicit cloning', function (assert) {\n        var momentA = moment([2011, 10, 10]),\n        momentB = momentA.clone();\n        momentA.month(5);\n        assert.equal(momentB.month(), 10, 'Calling moment() on a moment will create a clone');\n        assert.equal(momentA.month(), 5, 'Calling moment() on a moment will create a clone');\n    });\n\n    test('cloning carrying over utc mode', function (assert) {\n        assert.equal(moment().local().clone()._isUTC, false, 'An explicit cloned local moment should have _isUTC == false');\n        assert.equal(moment().utc().clone()._isUTC, true, 'An cloned utc moment should have _isUTC == true');\n        assert.equal(moment().clone()._isUTC, false, 'An explicit cloned local moment should have _isUTC == false');\n        assert.equal(moment.utc().clone()._isUTC, true, 'An explicit cloned utc moment should have _isUTC == true');\n        assert.equal(moment(moment().local())._isUTC, false, 'An implicit cloned local moment should have _isUTC == false');\n        assert.equal(moment(moment().utc())._isUTC, true, 'An implicit cloned utc moment should have _isUTC == true');\n        assert.equal(moment(moment())._isUTC, false, 'An implicit cloned local moment should have _isUTC == false');\n        assert.equal(moment(moment.utc())._isUTC, true, 'An implicit cloned utc moment should have _isUTC == true');\n    });\n\n    test('parsing iso', function (assert) {\n        var offset = moment([2011, 9, 8]).utcOffset(),\n        pad = function (input) {\n            if (input < 10) {\n                return '0' + input;\n            }\n            return '' + input;\n        },\n        hourOffset = (offset > 0 ? Math.floor(offset / 60) : Math.ceil(offset / 60)),\n        minOffset = offset - (hourOffset * 60),\n        tz = (offset >= 0) ?\n            '+' + pad(hourOffset) + ':' + pad(minOffset) :\n            '-' + pad(-hourOffset) + ':' + pad(-minOffset),\n        tz2 = tz.replace(':', ''),\n        tz3 = tz2.slice(0, 3),\n        formats = [\n            ['2011-10-08',                    '2011-10-08T00:00:00.000' + tz],\n            ['2011-10-08T18',                 '2011-10-08T18:00:00.000' + tz],\n            ['2011-10-08T18:04',              '2011-10-08T18:04:00.000' + tz],\n            ['2011-10-08T18:04:20',           '2011-10-08T18:04:20.000' + tz],\n            ['2011-10-08T18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n            ['2011-10-08T18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n            ['2011-10-08T18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n            ['2011-10-08T18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n            ['2011-10-08T18:04' + tz3,        '2011-10-08T18:04:00.000' + tz],\n            ['2011-10-08T18:04:20' + tz3,     '2011-10-08T18:04:20.000' + tz],\n            ['2011-10-08T18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n            ['2011-10-08T18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n            ['2011-10-08T18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n            ['2011-10-08 18',                 '2011-10-08T18:00:00.000' + tz],\n            ['2011-10-08 18:04',              '2011-10-08T18:04:00.000' + tz],\n            ['2011-10-08 18:04:20',           '2011-10-08T18:04:20.000' + tz],\n            ['2011-10-08 18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n            ['2011-10-08 18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n            ['2011-10-08 18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n            ['2011-10-08 18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n            ['2011-10-08 18:04' + tz3,        '2011-10-08T18:04:00.000' + tz],\n            ['2011-10-08 18:04:20' + tz3,     '2011-10-08T18:04:20.000' + tz],\n            ['2011-10-08 18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n            ['2011-10-08 18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n            ['2011-10-08 18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n            ['2011-W40',                      '2011-10-03T00:00:00.000' + tz],\n            ['2011-W40-6',                    '2011-10-08T00:00:00.000' + tz],\n            ['2011-W40-6T18',                 '2011-10-08T18:00:00.000' + tz],\n            ['2011-W40-6T18:04',              '2011-10-08T18:04:00.000' + tz],\n            ['2011-W40-6T18:04:20',           '2011-10-08T18:04:20.000' + tz],\n            ['2011-W40-6T18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n            ['2011-W40-6T18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n            ['2011-W40-6T18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n            ['2011-W40-6T18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n            ['2011-W40-6T18:04' + tz3,        '2011-10-08T18:04:00.000' + tz],\n            ['2011-W40-6T18:04:20' + tz3,     '2011-10-08T18:04:20.000' + tz],\n            ['2011-W40-6T18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n            ['2011-W40-6T18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n            ['2011-W40-6T18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n            ['2011-W40-6 18',                 '2011-10-08T18:00:00.000' + tz],\n            ['2011-W40-6 18:04',              '2011-10-08T18:04:00.000' + tz],\n            ['2011-W40-6 18:04:20',           '2011-10-08T18:04:20.000' + tz],\n            ['2011-W40-6 18:04' + tz,         '2011-10-08T18:04:00.000' + tz],\n            ['2011-W40-6 18:04:20' + tz,      '2011-10-08T18:04:20.000' + tz],\n            ['2011-W40-6 18:04' + tz2,        '2011-10-08T18:04:00.000' + tz],\n            ['2011-W40-6 18:04:20' + tz2,     '2011-10-08T18:04:20.000' + tz],\n            ['2011-W40-6 18:04' + tz3,        '2011-10-08T18:04:00.000' + tz],\n            ['2011-W40-6 18:04:20' + tz3,     '2011-10-08T18:04:20.000' + tz],\n            ['2011-W40-6 18:04:20.1' + tz2,   '2011-10-08T18:04:20.100' + tz],\n            ['2011-W40-6 18:04:20.11' + tz2,  '2011-10-08T18:04:20.110' + tz],\n            ['2011-W40-6 18:04:20.111' + tz2, '2011-10-08T18:04:20.111' + tz],\n            ['2011-281',                      '2011-10-08T00:00:00.000' + tz],\n            ['2011-281T18',                   '2011-10-08T18:00:00.000' + tz],\n            ['2011-281T18:04',                '2011-10-08T18:04:00.000' + tz],\n            ['2011-281T18:04:20',             '2011-10-08T18:04:20.000' + tz],\n            ['2011-281T18:04' + tz,           '2011-10-08T18:04:00.000' + tz],\n            ['2011-281T18:04:20' + tz,        '2011-10-08T18:04:20.000' + tz],\n            ['2011-281T18:04' + tz2,          '2011-10-08T18:04:00.000' + tz],\n            ['2011-281T18:04:20' + tz2,       '2011-10-08T18:04:20.000' + tz],\n            ['2011-281T18:04' + tz3,          '2011-10-08T18:04:00.000' + tz],\n            ['2011-281T18:04:20' + tz3,       '2011-10-08T18:04:20.000' + tz],\n            ['2011-281T18:04:20.1' + tz2,     '2011-10-08T18:04:20.100' + tz],\n            ['2011-281T18:04:20.11' + tz2,    '2011-10-08T18:04:20.110' + tz],\n            ['2011-281T18:04:20.111' + tz2,   '2011-10-08T18:04:20.111' + tz],\n            ['2011-281 18',                   '2011-10-08T18:00:00.000' + tz],\n            ['2011-281 18:04',                '2011-10-08T18:04:00.000' + tz],\n            ['2011-281 18:04:20',             '2011-10-08T18:04:20.000' + tz],\n            ['2011-281 18:04' + tz,           '2011-10-08T18:04:00.000' + tz],\n            ['2011-281 18:04:20' + tz,        '2011-10-08T18:04:20.000' + tz],\n            ['2011-281 18:04' + tz2,          '2011-10-08T18:04:00.000' + tz],\n            ['2011-281 18:04:20' + tz2,       '2011-10-08T18:04:20.000' + tz],\n            ['2011-281 18:04' + tz3,          '2011-10-08T18:04:00.000' + tz],\n            ['2011-281 18:04:20' + tz3,       '2011-10-08T18:04:20.000' + tz],\n            ['2011-281 18:04:20.1' + tz2,     '2011-10-08T18:04:20.100' + tz],\n            ['2011-281 18:04:20.11' + tz2,    '2011-10-08T18:04:20.110' + tz],\n            ['2011-281 18:04:20.111' + tz2,   '2011-10-08T18:04:20.111' + tz]\n        ], i;\n        for (i = 0; i < formats.length; i++) {\n            assert.equal(moment(formats[i][0]).format('YYYY-MM-DDTHH:mm:ss.SSSZ'), formats[i][1], 'moment should be able to parse ISO ' + formats[i][0]);\n        }\n    });\n\n    test('parsing iso week year/week/weekday', function (assert) {\n        assert.equal(moment.utc('2007-W01').format(), '2007-01-01T00:00:00+00:00', '2008 week 1 (1st Jan Mon)');\n        assert.equal(moment.utc('2008-W01').format(), '2007-12-31T00:00:00+00:00', '2008 week 1 (1st Jan Tue)');\n        assert.equal(moment.utc('2003-W01').format(), '2002-12-30T00:00:00+00:00', '2008 week 1 (1st Jan Wed)');\n        assert.equal(moment.utc('2009-W01').format(), '2008-12-29T00:00:00+00:00', '2009 week 1 (1st Jan Thu)');\n        assert.equal(moment.utc('2010-W01').format(), '2010-01-04T00:00:00+00:00', '2010 week 1 (1st Jan Fri)');\n        assert.equal(moment.utc('2011-W01').format(), '2011-01-03T00:00:00+00:00', '2011 week 1 (1st Jan Sat)');\n        assert.equal(moment.utc('2012-W01').format(), '2012-01-02T00:00:00+00:00', '2012 week 1 (1st Jan Sun)');\n    });\n\n    test('parsing week year/week/weekday (dow 1, doy 4)', function (assert) {\n        moment.locale('dow:1,doy:4', {week: {dow: 1, doy: 4}});\n\n        assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2007-01-01T00:00:00+00:00', '2007 week 1 (1st Jan Mon)');\n        assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-31T00:00:00+00:00', '2008 week 1 (1st Jan Tue)');\n        assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-30T00:00:00+00:00', '2003 week 1 (1st Jan Wed)');\n        assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-29T00:00:00+00:00', '2009 week 1 (1st Jan Thu)');\n        assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2010-01-04T00:00:00+00:00', '2010 week 1 (1st Jan Fri)');\n        assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2011-01-03T00:00:00+00:00', '2011 week 1 (1st Jan Sat)');\n        assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2012-01-02T00:00:00+00:00', '2012 week 1 (1st Jan Sun)');\n\n        moment.defineLocale('dow:1,doy:4', null);\n    });\n\n    test('parsing week year/week/weekday (dow 1, doy 7)', function (assert) {\n        moment.locale('dow:1,doy:7', {week: {dow: 1, doy: 7}});\n\n        assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2007-01-01T00:00:00+00:00', '2007 week 1 (1st Jan Mon)');\n        assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-31T00:00:00+00:00', '2008 week 1 (1st Jan Tue)');\n        assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-30T00:00:00+00:00', '2003 week 1 (1st Jan Wed)');\n        assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-29T00:00:00+00:00', '2009 week 1 (1st Jan Thu)');\n        assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2009-12-28T00:00:00+00:00', '2010 week 1 (1st Jan Fri)');\n        assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2010-12-27T00:00:00+00:00', '2011 week 1 (1st Jan Sat)');\n        assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2011-12-26T00:00:00+00:00', '2012 week 1 (1st Jan Sun)');\n        moment.defineLocale('dow:1,doy:7', null);\n    });\n\n    test('parsing week year/week/weekday (dow 0, doy 6)', function (assert) {\n        moment.locale('dow:0,doy:6', {week: {dow: 0, doy: 6}});\n\n        assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2006-12-31T00:00:00+00:00', '2007 week 1 (1st Jan Mon)');\n        assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-30T00:00:00+00:00', '2008 week 1 (1st Jan Tue)');\n        assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-29T00:00:00+00:00', '2003 week 1 (1st Jan Wed)');\n        assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-28T00:00:00+00:00', '2009 week 1 (1st Jan Thu)');\n        assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2009-12-27T00:00:00+00:00', '2010 week 1 (1st Jan Fri)');\n        assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2010-12-26T00:00:00+00:00', '2011 week 1 (1st Jan Sat)');\n        assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2012-01-01T00:00:00+00:00', '2012 week 1 (1st Jan Sun)');\n        moment.defineLocale('dow:0,doy:6', null);\n    });\n\n    test('parsing week year/week/weekday (dow 6, doy 12)', function (assert) {\n        moment.locale('dow:6,doy:12', {week: {dow: 6, doy: 12}});\n\n        assert.equal(moment.utc('2007-01', 'gggg-ww').format(), '2006-12-30T00:00:00+00:00', '2007 week 1 (1st Jan Mon)');\n        assert.equal(moment.utc('2008-01', 'gggg-ww').format(), '2007-12-29T00:00:00+00:00', '2008 week 1 (1st Jan Tue)');\n        assert.equal(moment.utc('2003-01', 'gggg-ww').format(), '2002-12-28T00:00:00+00:00', '2003 week 1 (1st Jan Wed)');\n        assert.equal(moment.utc('2009-01', 'gggg-ww').format(), '2008-12-27T00:00:00+00:00', '2009 week 1 (1st Jan Thu)');\n        assert.equal(moment.utc('2010-01', 'gggg-ww').format(), '2009-12-26T00:00:00+00:00', '2010 week 1 (1st Jan Fri)');\n        assert.equal(moment.utc('2011-01', 'gggg-ww').format(), '2011-01-01T00:00:00+00:00', '2011 week 1 (1st Jan Sat)');\n        assert.equal(moment.utc('2012-01', 'gggg-ww').format(), '2011-12-31T00:00:00+00:00', '2012 week 1 (1st Jan Sun)');\n    });\n\n    test('parsing ISO with Z', function (assert) {\n        var i, mom, formats = [\n            ['2011-10-08T18:04',             '2011-10-08T18:04:00.000'],\n            ['2011-10-08T18:04:20',          '2011-10-08T18:04:20.000'],\n            ['2011-10-08T18:04:20.1',        '2011-10-08T18:04:20.100'],\n            ['2011-10-08T18:04:20.11',       '2011-10-08T18:04:20.110'],\n            ['2011-10-08T18:04:20.111',      '2011-10-08T18:04:20.111'],\n            ['2011-W40-6T18',                '2011-10-08T18:00:00.000'],\n            ['2011-W40-6T18:04',             '2011-10-08T18:04:00.000'],\n            ['2011-W40-6T18:04:20',          '2011-10-08T18:04:20.000'],\n            ['2011-W40-6T18:04:20.1',        '2011-10-08T18:04:20.100'],\n            ['2011-W40-6T18:04:20.11',       '2011-10-08T18:04:20.110'],\n            ['2011-W40-6T18:04:20.111',      '2011-10-08T18:04:20.111'],\n            ['2011-281T18',                  '2011-10-08T18:00:00.000'],\n            ['2011-281T18:04',               '2011-10-08T18:04:00.000'],\n            ['2011-281T18:04:20',            '2011-10-08T18:04:20.000'],\n            ['2011-281T18:04:20',            '2011-10-08T18:04:20.000'],\n            ['2011-281T18:04:20.1',          '2011-10-08T18:04:20.100'],\n            ['2011-281T18:04:20.11',         '2011-10-08T18:04:20.110'],\n            ['2011-281T18:04:20.111',        '2011-10-08T18:04:20.111']\n        ];\n\n        for (i = 0; i < formats.length; i++) {\n            mom = moment(formats[i][0] + 'Z').utc();\n            assert.equal(mom.format('YYYY-MM-DDTHH:mm:ss.SSS'), formats[i][1], 'moment should be able to parse ISO in UTC ' + formats[i][0] + 'Z');\n\n            mom = moment(formats[i][0] + ' Z').utc();\n            assert.equal(mom.format('YYYY-MM-DDTHH:mm:ss.SSS'), formats[i][1], 'moment should be able to parse ISO in UTC ' + formats[i][0] + ' Z');\n        }\n    });\n\n    test('parsing iso with T', function (assert) {\n        assert.equal(moment('2011-10-08T18')._f, 'YYYY-MM-DDTHH', 'should include \\'T\\' in the format');\n        assert.equal(moment('2011-10-08T18:20')._f, 'YYYY-MM-DDTHH:mm', 'should include \\'T\\' in the format');\n        assert.equal(moment('2011-10-08T18:20:13')._f, 'YYYY-MM-DDTHH:mm:ss', 'should include \\'T\\' in the format');\n        assert.equal(moment('2011-10-08T18:20:13.321')._f, 'YYYY-MM-DDTHH:mm:ss.SSSS', 'should include \\'T\\' in the format');\n\n        assert.equal(moment('2011-10-08 18')._f, 'YYYY-MM-DD HH', 'should not include \\'T\\' in the format');\n        assert.equal(moment('2011-10-08 18:20')._f, 'YYYY-MM-DD HH:mm', 'should not include \\'T\\' in the format');\n        assert.equal(moment('2011-10-08 18:20:13')._f, 'YYYY-MM-DD HH:mm:ss', 'should not include \\'T\\' in the format');\n        assert.equal(moment('2011-10-08 18:20:13.321')._f, 'YYYY-MM-DD HH:mm:ss.SSSS', 'should not include \\'T\\' in the format');\n    });\n\n    test('parsing iso Z timezone', function (assert) {\n        var i,\n        formats = [\n            ['2011-10-08T18:04Z',             '2011-10-08T18:04:00.000+00:00'],\n            ['2011-10-08T18:04:20Z',          '2011-10-08T18:04:20.000+00:00'],\n            ['2011-10-08T18:04:20.111Z',      '2011-10-08T18:04:20.111+00:00']\n        ];\n        for (i = 0; i < formats.length; i++) {\n            assert.equal(moment.utc(formats[i][0]).format('YYYY-MM-DDTHH:mm:ss.SSSZ'), formats[i][1], 'moment should be able to parse ISO ' + formats[i][0]);\n        }\n    });\n\n    test('parsing iso Z timezone into local', function (assert) {\n        var m = moment('2011-10-08T18:04:20.111Z');\n\n        assert.equal(m.utc().format('YYYY-MM-DDTHH:mm:ss.SSS'), '2011-10-08T18:04:20.111', 'moment should be able to parse ISO 2011-10-08T18:04:20.111Z');\n    });\n\n    test('parsing iso with more subsecond precision digits', function (assert) {\n        assert.equal(moment.utc('2013-07-31T22:00:00.0000000Z').format(), '2013-07-31T22:00:00+00:00', 'more than 3 subsecond digits');\n    });\n\n    test('null or empty', function (assert) {\n        assert.equal(moment('').isValid(), false, 'moment(\\'\\') is not valid');\n        assert.equal(moment(null).isValid(), false, 'moment(null) is not valid');\n        assert.equal(moment(null, 'YYYY-MM-DD').isValid(), false, 'moment(\\'\\', \\'format\\') is not valid');\n        assert.equal(moment('', 'YYYY-MM-DD').isValid(), false, 'moment(\\'\\', \\'format\\') is not valid');\n        assert.equal(moment.utc('').isValid(), false, 'moment.utc(\\'\\') is not valid');\n        assert.equal(moment.utc(null).isValid(), false, 'moment.utc(null) is not valid');\n        assert.equal(moment.utc(null, 'YYYY-MM-DD').isValid(), false, 'moment.utc(null) is not valid');\n        assert.equal(moment.utc('', 'YYYY-MM-DD').isValid(), false, 'moment.utc(\\'\\', \\'YYYY-MM-DD\\') is not valid');\n    });\n\n    test('first century', function (assert) {\n        assert.equal(moment([0, 0, 1]).format('YYYY-MM-DD'), '0000-01-01', 'Year AD 0');\n        assert.equal(moment([99, 0, 1]).format('YYYY-MM-DD'), '0099-01-01', 'Year AD 99');\n        assert.equal(moment([999, 0, 1]).format('YYYY-MM-DD'), '0999-01-01', 'Year AD 999');\n        assert.equal(moment('0 1 1', 'YYYY MM DD').format('YYYY-MM-DD'), '0000-01-01', 'Year AD 0');\n        assert.equal(moment('99 1 1', 'YYYY MM DD').format('YYYY-MM-DD'), '0099-01-01', 'Year AD 99');\n        assert.equal(moment('999 1 1', 'YYYY MM DD').format('YYYY-MM-DD'), '0999-01-01', 'Year AD 999');\n        assert.equal(moment('0 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'), '00000-01-01', 'Year AD 0');\n        assert.equal(moment('99 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'), '00099-01-01', 'Year AD 99');\n        assert.equal(moment('999 1 1', 'YYYYY MM DD').format('YYYYY-MM-DD'), '00999-01-01', 'Year AD 999');\n    });\n\n    test('six digit years', function (assert) {\n        assert.equal(moment([-270000, 0, 1]).format('YYYYY-MM-DD'), '-270000-01-01', 'format BC 270,001');\n        assert.equal(moment([270000, 0, 1]).format('YYYYY-MM-DD'), '270000-01-01', 'format AD 270,000');\n        assert.equal(moment('-270000-01-01', 'YYYYY-MM-DD').toDate().getFullYear(), -270000, 'parse BC 270,001');\n        assert.equal(moment('270000-01-01',  'YYYYY-MM-DD').toDate().getFullYear(), 270000, 'parse AD 270,000');\n        assert.equal(moment('+270000-01-01', 'YYYYY-MM-DD').toDate().getFullYear(), 270000, 'parse AD +270,000');\n        assert.equal(moment.utc('-270000-01-01', 'YYYYY-MM-DD').toDate().getUTCFullYear(), -270000, 'parse utc BC 270,001');\n        assert.equal(moment.utc('270000-01-01',  'YYYYY-MM-DD').toDate().getUTCFullYear(), 270000, 'parse utc AD 270,000');\n        assert.equal(moment.utc('+270000-01-01', 'YYYYY-MM-DD').toDate().getUTCFullYear(), 270000, 'parse utc AD +270,000');\n    });\n\n    test('negative four digit years', function (assert) {\n        assert.equal(moment('-1000-01-01', 'YYYYY-MM-DD').toDate().getFullYear(), -1000, 'parse BC 1,001');\n        assert.equal(moment.utc('-1000-01-01', 'YYYYY-MM-DD').toDate().getUTCFullYear(), -1000, 'parse utc BC 1,001');\n    });\n\n    test('strict parsing', function (assert) {\n        assert.equal(moment('2014-', 'YYYY-Q', true).isValid(), false, 'fail missing quarter');\n\n        assert.equal(moment('2012-05', 'YYYY-MM', true).format('YYYY-MM'), '2012-05', 'parse correct string');\n        assert.equal(moment(' 2012-05', 'YYYY-MM', true).isValid(), false, 'fail on extra whitespace');\n        assert.equal(moment('foo 2012-05', '[foo] YYYY-MM', true).format('YYYY-MM'), '2012-05', 'handle fixed text');\n        assert.equal(moment('2012 05', 'YYYY-MM', true).isValid(), false, 'fail on different separator');\n        assert.equal(moment('2012 05', 'YYYY MM DD', true).isValid(), false, 'fail on too many tokens');\n\n        assert.equal(moment('05 30 2010', ['DD MM YYYY', 'MM DD YYYY'], true).format('MM DD YYYY'), '05 30 2010', 'array with bad date');\n        assert.equal(moment('05 30 2010', ['', 'MM DD YYYY'], true).format('MM DD YYYY'), '05 30 2010', 'array with invalid format');\n        assert.equal(moment('05 30 2010', [' DD MM YYYY', 'MM DD YYYY'], true).format('MM DD YYYY'), '05 30 2010', 'array with non-matching format');\n\n        assert.equal(moment('2010.*...', 'YYYY.*', true).isValid(), false, 'invalid format with regex chars');\n        assert.equal(moment('2010.*', 'YYYY.*', true).year(), 2010, 'valid format with regex chars');\n        assert.equal(moment('.*2010.*', '.*YYYY.*', true).year(), 2010, 'valid format with regex chars on both sides');\n        assert.equal(moment('-5-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid negative year');\n        assert.equal(moment('2-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid one-digit year');\n        assert.equal(moment('20-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid two-digit year');\n        assert.equal(moment('201-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid three-digit year');\n        assert.equal(moment('2010-05-25', 'YYYY-MM-DD', true).isValid(), true, 'valid four-digit year');\n        assert.equal(moment('22010-05-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid five-digit year');\n\n        assert.equal(moment('12-05-25', 'YY-MM-DD', true).isValid(), true, 'valid two-digit year');\n        assert.equal(moment('2012-05-25', 'YY-MM-DD', true).isValid(), false, 'invalid four-digit year');\n\n        assert.equal(moment('-5-05-25', 'Y-MM-DD', true).isValid(), true, 'valid negative year');\n        assert.equal(moment('2-05-25', 'Y-MM-DD', true).isValid(), true, 'valid one-digit year');\n        assert.equal(moment('20-05-25', 'Y-MM-DD', true).isValid(), true, 'valid two-digit year');\n        assert.equal(moment('201-05-25', 'Y-MM-DD', true).isValid(), true, 'valid three-digit year');\n\n        assert.equal(moment('2012-5-25', 'YYYY-M-DD', true).isValid(), true, 'valid one-digit month');\n        assert.equal(moment('2012-5-25', 'YYYY-MM-DD', true).isValid(), false, 'invalid one-digit month');\n        assert.equal(moment('2012-05-25', 'YYYY-M-DD', true).isValid(), true, 'valid one-digit month');\n        assert.equal(moment('2012-05-25', 'YYYY-MM-DD', true).isValid(), true, 'valid one-digit month');\n\n        assert.equal(moment('2012-05-2', 'YYYY-MM-D', true).isValid(), true, 'valid one-digit day');\n        assert.equal(moment('2012-05-2', 'YYYY-MM-DD', true).isValid(), false, 'invalid one-digit day');\n        assert.equal(moment('2012-05-02', 'YYYY-MM-D', true).isValid(), true, 'valid two-digit day');\n        assert.equal(moment('2012-05-02', 'YYYY-MM-DD', true).isValid(), true, 'valid two-digit day');\n\n        assert.equal(moment('+002012-05-25', 'YYYYY-MM-DD', true).isValid(), true, 'valid six-digit year');\n        assert.equal(moment('+2012-05-25', 'YYYYY-MM-DD', true).isValid(), false, 'invalid four-digit year');\n        assert.equal(moment('1', 'S', true).isValid(), true, 'valid one-digit milisecond');\n        assert.equal(moment('12', 'S', true).isValid(), false, 'invalid two-digit milisecond');\n        assert.equal(moment('123', 'S', true).isValid(), false, 'invalid three-digit milisecond');\n\n        assert.equal(moment('1', 'SS', true).isValid(), false, 'invalid one-digit milisecond');\n        assert.equal(moment('12', 'SS', true).isValid(), true, 'valid two-digit milisecond');\n        assert.equal(moment('123', 'SS', true).isValid(), false, 'invalid three-digit milisecond');\n\n        assert.equal(moment('1', 'SSS', true).isValid(), false, 'invalid one-digit milisecond');\n        assert.equal(moment('12', 'SSS', true).isValid(), false, 'invalid two-digit milisecond');\n        assert.equal(moment('123', 'SSS', true).isValid(), true, 'valid three-digit milisecond');\n        assert.ok(moment('1 January 2000', 'D MMMM YYYY', true).isValid(), 'capital long-month + MMMM');\n        assert.ok(!moment('1 January 2000', 'D MMM YYYY', true).isValid(), 'capital long-month + MMM');\n        assert.ok(!moment('1 Jan 2000', 'D MMMM YYYY', true).isValid(), 'capital short-month + MMMM');\n        assert.ok(moment('1 Jan 2000', 'D MMM YYYY', true).isValid(), 'capital short-month + MMM');\n        assert.ok(moment('1 january 2000', 'D MMMM YYYY', true).isValid(), 'lower long-month + MMMM');\n        assert.ok(!moment('1 january 2000', 'D MMM YYYY', true).isValid(), 'lower long-month + MMM');\n        assert.ok(!moment('1 jan 2000', 'D MMMM YYYY', true).isValid(), 'lower short-month + MMMM');\n        assert.ok(moment('1 jan 2000', 'D MMM YYYY', true).isValid(), 'lower short-month + MMM');\n    });\n\n    test('parsing into a locale', function (assert) {\n        moment.defineLocale('parselocale', {\n            months : 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_'),\n            monthsShort : 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_')\n        });\n\n        moment.locale('en');\n\n        assert.equal(moment('2012 seven', 'YYYY MMM', 'parselocale').month(), 6, 'should be able to parse in a specific locale');\n\n        moment.locale('parselocale');\n\n        assert.equal(moment('2012 july', 'YYYY MMM', 'en').month(), 6, 'should be able to parse in a specific locale');\n\n        moment.defineLocale('parselocale', null);\n    });\n\n    function getVerifier(test) {\n        return function (input, format, expected, description, asymetrical) {\n            var m = moment(input, format);\n            test.equal(m.format('YYYY MM DD'), expected, 'compare: ' + description);\n            if (!asymetrical) {\n                test.equal(m.format(format), input, 'round trip: ' + description);\n            }\n        };\n    }\n\n    test('parsing week and weekday information', function (assert) {\n        var ver = getVerifier(assert);\n        ver('12', 'gg', '2012 01 01', 'week-year two digits');\n        ver('2012', 'gggg', '2012 01 01', 'week-year four digits');\n\n        ver('99', 'gg', '1998 12 27', 'week-year two digits previous year');\n        ver('1999', 'gggg', '1998 12 27', 'week-year four digits previous year');\n\n        ver('99', 'GG', '1999 01 04', 'iso week-year two digits');\n        ver('1999', 'GGGG', '1999 01 04', 'iso week-year four digits');\n\n        ver('13', 'GG', '2012 12 31', 'iso week-year two digits previous year');\n        ver('2013', 'GGGG', '2012 12 31', 'iso week-year four digits previous year');\n        ver('1999 37', 'gggg w', '1999 09 05', 'week');\n        ver('1999 37', 'gggg ww', '1999 09 05', 'week double');\n        ver('1999 37', 'GGGG W', '1999 09 13', 'iso week');\n        ver('1999 37', 'GGGG WW', '1999 09 13', 'iso week double');\n\n        ver('1999 37 4', 'GGGG WW E', '1999 09 16', 'iso day');\n        ver('1999 37 04', 'GGGG WW E', '1999 09 16', 'iso day wide', true);\n\n        ver('1999 37 4', 'gggg ww e', '1999 09 09', 'day');\n        ver('1999 37 04', 'gggg ww e', '1999 09 09', 'day wide', true);\n        ver('1999 37 4', 'gggg ww d', '1999 09 09', 'd');\n        ver('1999 37 Th', 'gggg ww dd', '1999 09 09', 'dd');\n        ver('1999 37 Thu', 'gggg ww ddd', '1999 09 09', 'ddd');\n        ver('1999 37 Thursday', 'gggg ww dddd', '1999 09 09', 'dddd');\n        assert.equal(moment('22', 'ww').week(), 22, 'week sets the week by itself');\n        assert.equal(moment('22', 'ww').weekYear(), moment().weekYear(), 'week keeps this year');\n        assert.equal(moment('2012 22', 'YYYY ww').weekYear(), 2012, 'week keeps parsed year');\n\n        assert.equal(moment('22', 'WW').isoWeek(), 22, 'iso week sets the week by itself');\n        assert.equal(moment('2012 22', 'YYYY WW').weekYear(), 2012, 'iso week keeps parsed year');\n        assert.equal(moment('22', 'WW').isoWeekYear(), moment().isoWeekYear(), 'iso week keeps this year');\n        ver('6 2013 2', 'e gggg w', '2013 01 12', 'order doesn\\'t matter');\n        ver('6 2013 2', 'E GGGG W', '2013 01 12', 'iso order doesn\\'t matter');\n        assert.equal(moment('1999-W37-4 3:30', 'GGGG-[W]WW-E HH:mm').format('YYYY MM DD HH:mm'), '1999 09 16 03:30', 'parsing weeks and hours');\n        if (new Date('1300-01-01').getUTCFullYear() === 1300) {\n            ver('0098-06', 'GGGG-WW', '0098 02 03', 'small years work', true);\n        }\n    });\n\n    test('parsing localized weekdays', function (assert) {\n        var ver = getVerifier(assert);\n        try {\n            moment.locale('dow:1,doy:4', {\n                weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n                weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n                weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n                week: {dow: 1, doy: 4}\n            });\n            ver('1999 37 4', 'GGGG WW E', '1999 09 16', 'iso ignores locale');\n            ver('1999 37 7', 'GGGG WW E', '1999 09 19', 'iso ignores locale');\n\n            ver('1999 37 0', 'gggg ww e', '1999 09 13', 'localized e uses local doy and dow: 0 = monday');\n            ver('1999 37 4', 'gggg ww e', '1999 09 17', 'localized e uses local doy and dow: 4 = friday');\n\n            ver('1999 37 1', 'gggg ww d', '1999 09 13', 'localized d uses 0-indexed days: 1 = monday');\n            ver('1999 37 Lu', 'gggg ww dd', '1999 09 13', 'localized d uses 0-indexed days: Mo');\n            ver('1999 37 lun.', 'gggg ww ddd', '1999 09 13', 'localized d uses 0-indexed days: Mon');\n            ver('1999 37 lundi', 'gggg ww dddd', '1999 09 13', 'localized d uses 0-indexed days: Monday');\n            ver('1999 37 4', 'gggg ww d', '1999 09 16', 'localized d uses 0-indexed days: 4');\n            ver('1999 37 0', 'gggg ww d', '1999 09 19', 'localized d uses 0-indexed days: 0 = sund');\n            ver('1999 37 Di', 'gggg ww dd', '1999 09 19', 'localized d uses 0-indexed days: 0 = sund');\n        }\n        finally {\n            moment.locale('en');\n        }\n    });\n\n    test('parsing with customized two-digit year', function (assert) {\n        var original = moment.parseTwoDigitYear;\n        try {\n            assert.equal(moment('68', 'YY').year(), 2068);\n            assert.equal(moment('69', 'YY').year(), 1969);\n            moment.parseTwoDigitYear = function (input) {\n                return +input + (+input > 30 ? 1900 : 2000);\n            };\n            assert.equal(moment('68', 'YY').year(), 1968);\n            assert.equal(moment('67', 'YY').year(), 1967);\n            assert.equal(moment('31', 'YY').year(), 1931);\n            assert.equal(moment('30', 'YY').year(), 2030);\n        }\n        finally {\n            moment.parseTwoDigitYear = original;\n        }\n    });\n\n    test('array with strings', function (assert) {\n        assert.equal(moment(['2014', '7', '31']).isValid(), true, 'string array + isValid');\n    });\n\n    test('utc with array of formats', function (assert) {\n        assert.equal(moment.utc('2014-01-01', ['YYYY-MM-DD', 'YYYY-MM']).format(), '2014-01-01T00:00:00+00:00', 'moment.utc works with array of formats');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function each(array, callback) {\n        var i;\n        for (i = 0; i < array.length; i++) {\n            callback(array[i], i, array);\n        }\n    }\n\n    var helpers_each = each;\n\n    module('days in month');\n\n    test('days in month', function (assert) {\n        helpers_each([31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], function (days, i) {\n            var firstDay = moment([2012, i]),\n                lastDay  = moment([2012, i, days]);\n            assert.equal(firstDay.daysInMonth(), days, firstDay.format('L') + ' should have ' + days + ' days.');\n            assert.equal(lastDay.daysInMonth(), days, lastDay.format('L') + ' should have ' + days + ' days.');\n        });\n    });\n\n    test('days in month leap years', function (assert) {\n        assert.equal(moment([2010, 1]).daysInMonth(), 28, 'Feb 2010 should have 28 days');\n        assert.equal(moment([2100, 1]).daysInMonth(), 28, 'Feb 2100 should have 28 days');\n        assert.equal(moment([2008, 1]).daysInMonth(), 29, 'Feb 2008 should have 29 days');\n        assert.equal(moment([2000, 1]).daysInMonth(), 29, 'Feb 2000 should have 29 days');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function equal(assert, a, b, message) {\n        assert.ok(Math.abs(a - b) < 0.00000001, '(' + a + ' === ' + b + ') ' + message);\n    }\n\n    function dstForYear(year) {\n        var start = moment([year]),\n            end = moment([year + 1]),\n            current = start.clone(),\n            last;\n\n        while (current < end) {\n            last = current.clone();\n            current.add(24, 'hour');\n            if (last.utcOffset() !== current.utcOffset()) {\n                end = current.clone();\n                current = last.clone();\n                break;\n            }\n        }\n\n        while (current < end) {\n            last = current.clone();\n            current.add(1, 'hour');\n            if (last.utcOffset() !== current.utcOffset()) {\n                return {\n                    moment : last,\n                    diff : -(current.utcOffset() - last.utcOffset()) / 60\n                };\n            }\n        }\n    }\n\n    module('diff');\n\n    test('diff', function (assert) {\n        assert.equal(moment(1000).diff(0), 1000, '1 second - 0 = 1000');\n        assert.equal(moment(1000).diff(500), 500, '1 second - 0.5 seconds = 500');\n        assert.equal(moment(0).diff(1000), -1000, '0 - 1 second = -1000');\n        assert.equal(moment(new Date(1000)).diff(1000), 0, '1 second - 1 second = 0');\n        var oneHourDate = new Date(),\n        nowDate = new Date(+oneHourDate);\n        oneHourDate.setHours(oneHourDate.getHours() + 1);\n        assert.equal(moment(oneHourDate).diff(nowDate), 60 * 60 * 1000, '1 hour from now = 3600000');\n    });\n\n    test('diff key after', function (assert) {\n        assert.equal(moment([2010]).diff([2011], 'years'), -1, 'year diff');\n        assert.equal(moment([2010]).diff([2010, 2], 'months'), -2, 'month diff');\n        assert.equal(moment([2010]).diff([2010, 0, 7], 'weeks'), 0, 'week diff');\n        assert.equal(moment([2010]).diff([2010, 0, 8], 'weeks'), -1, 'week diff');\n        assert.equal(moment([2010]).diff([2010, 0, 21], 'weeks'), -2, 'week diff');\n        assert.equal(moment([2010]).diff([2010, 0, 22], 'weeks'), -3, 'week diff');\n        assert.equal(moment([2010]).diff([2010, 0, 4], 'days'), -3, 'day diff');\n        assert.equal(moment([2010]).diff([2010, 0, 1, 4], 'hours'), -4, 'hour diff');\n        assert.equal(moment([2010]).diff([2010, 0, 1, 0, 5], 'minutes'), -5, 'minute diff');\n        assert.equal(moment([2010]).diff([2010, 0, 1, 0, 0, 6], 'seconds'), -6, 'second diff');\n    });\n\n    test('diff key before', function (assert) {\n        assert.equal(moment([2011]).diff([2010], 'years'), 1, 'year diff');\n        assert.equal(moment([2010, 2]).diff([2010], 'months'), 2, 'month diff');\n        assert.equal(moment([2010, 0, 4]).diff([2010], 'days'), 3, 'day diff');\n        assert.equal(moment([2010, 0, 7]).diff([2010], 'weeks'), 0, 'week diff');\n        assert.equal(moment([2010, 0, 8]).diff([2010], 'weeks'), 1, 'week diff');\n        assert.equal(moment([2010, 0, 21]).diff([2010], 'weeks'), 2, 'week diff');\n        assert.equal(moment([2010, 0, 22]).diff([2010], 'weeks'), 3, 'week diff');\n        assert.equal(moment([2010, 0, 1, 4]).diff([2010], 'hours'), 4, 'hour diff');\n        assert.equal(moment([2010, 0, 1, 0, 5]).diff([2010], 'minutes'), 5, 'minute diff');\n        assert.equal(moment([2010, 0, 1, 0, 0, 6]).diff([2010], 'seconds'), 6, 'second diff');\n    });\n\n    test('diff key before singular', function (assert) {\n        assert.equal(moment([2011]).diff([2010], 'year'), 1, 'year diff singular');\n        assert.equal(moment([2010, 2]).diff([2010], 'month'), 2, 'month diff singular');\n        assert.equal(moment([2010, 0, 4]).diff([2010], 'day'), 3, 'day diff singular');\n        assert.equal(moment([2010, 0, 7]).diff([2010], 'week'), 0, 'week diff singular');\n        assert.equal(moment([2010, 0, 8]).diff([2010], 'week'), 1, 'week diff singular');\n        assert.equal(moment([2010, 0, 21]).diff([2010], 'week'), 2, 'week diff singular');\n        assert.equal(moment([2010, 0, 22]).diff([2010], 'week'), 3, 'week diff singular');\n        assert.equal(moment([2010, 0, 1, 4]).diff([2010], 'hour'), 4, 'hour diff singular');\n        assert.equal(moment([2010, 0, 1, 0, 5]).diff([2010], 'minute'), 5, 'minute diff singular');\n        assert.equal(moment([2010, 0, 1, 0, 0, 6]).diff([2010], 'second'), 6, 'second diff singular');\n    });\n\n    test('diff key before abbreviated', function (assert) {\n        assert.equal(moment([2011]).diff([2010], 'y'), 1, 'year diff abbreviated');\n        assert.equal(moment([2010, 2]).diff([2010], 'M'), 2, 'month diff abbreviated');\n        assert.equal(moment([2010, 0, 4]).diff([2010], 'd'), 3, 'day diff abbreviated');\n        assert.equal(moment([2010, 0, 7]).diff([2010], 'w'), 0, 'week diff abbreviated');\n        assert.equal(moment([2010, 0, 8]).diff([2010], 'w'), 1, 'week diff abbreviated');\n        assert.equal(moment([2010, 0, 21]).diff([2010], 'w'), 2, 'week diff abbreviated');\n        assert.equal(moment([2010, 0, 22]).diff([2010], 'w'), 3, 'week diff abbreviated');\n        assert.equal(moment([2010, 0, 1, 4]).diff([2010], 'h'), 4, 'hour diff abbreviated');\n        assert.equal(moment([2010, 0, 1, 0, 5]).diff([2010], 'm'), 5, 'minute diff abbreviated');\n        assert.equal(moment([2010, 0, 1, 0, 0, 6]).diff([2010], 's'), 6, 'second diff abbreviated');\n    });\n\n    test('diff month', function (assert) {\n        assert.equal(moment([2011, 0, 31]).diff([2011, 2, 1], 'months'), -1, 'month diff');\n    });\n\n    test('diff across DST', function (assert) {\n        var dst = dstForYear(2012), a, b, daysInMonth;\n        if (!dst) {\n            assert.equal(42, 42, 'at least one assertion');\n            return;\n        }\n\n        a = dst.moment;\n        b = a.clone().utc().add(12, 'hours').local();\n        daysInMonth = (a.daysInMonth() + b.daysInMonth()) / 2;\n        assert.equal(b.diff(a, 'milliseconds', true), 12 * 60 * 60 * 1000,\n                'ms diff across DST');\n        assert.equal(b.diff(a, 'seconds', true), 12 * 60 * 60,\n                'second diff across DST');\n        assert.equal(b.diff(a, 'minutes', true), 12 * 60,\n                'minute diff across DST');\n        assert.equal(b.diff(a, 'hours', true), 12,\n                'hour diff across DST');\n        assert.equal(b.diff(a, 'days', true), (12 - dst.diff) / 24,\n                'day diff across DST');\n        equal(assert, b.diff(a, 'weeks', true),  (12 - dst.diff) / 24 / 7,\n                'week diff across DST');\n        assert.ok(0.95 / (2 * 31) < b.diff(a, 'months', true),\n                'month diff across DST, lower bound');\n        assert.ok(b.diff(a, 'month', true) < 1.05 / (2 * 28),\n                'month diff across DST, upper bound');\n        assert.ok(0.95 / (2 * 31 * 12) < b.diff(a, 'years', true),\n                'year diff across DST, lower bound');\n        assert.ok(b.diff(a, 'year', true) < 1.05 / (2 * 28 * 12),\n                'year diff across DST, upper bound');\n\n        a = dst.moment;\n        b = a.clone().utc().add(12 + dst.diff, 'hours').local();\n        daysInMonth = (a.daysInMonth() + b.daysInMonth()) / 2;\n\n        assert.equal(b.diff(a, 'milliseconds', true),\n                (12 + dst.diff) * 60 * 60 * 1000,\n                'ms diff across DST');\n        assert.equal(b.diff(a, 'seconds', true),  (12 + dst.diff) * 60 * 60,\n                'second diff across DST');\n        assert.equal(b.diff(a, 'minutes', true),  (12 + dst.diff) * 60,\n                'minute diff across DST');\n        assert.equal(b.diff(a, 'hours', true),  (12 + dst.diff),\n                'hour diff across DST');\n        assert.equal(b.diff(a, 'days', true),  12 / 24, 'day diff across DST');\n        equal(assert, b.diff(a, 'weeks', true),  12 / 24 / 7,\n                'week diff across DST');\n        assert.ok(0.95 / (2 * 31) < b.diff(a, 'months', true),\n                'month diff across DST, lower bound');\n        assert.ok(b.diff(a, 'month', true) < 1.05 / (2 * 28),\n                'month diff across DST, upper bound');\n        assert.ok(0.95 / (2 * 31 * 12) < b.diff(a, 'years', true),\n                'year diff across DST, lower bound');\n        assert.ok(b.diff(a, 'year', true) < 1.05 / (2 * 28 * 12),\n                'year diff across DST, upper bound');\n    });\n\n    test('diff overflow', function (assert) {\n        assert.equal(moment([2011]).diff([2010], 'months'), 12, 'month diff');\n        assert.equal(moment([2010, 0, 2]).diff([2010], 'hours'), 24, 'hour diff');\n        assert.equal(moment([2010, 0, 1, 2]).diff([2010], 'minutes'), 120, 'minute diff');\n        assert.equal(moment([2010, 0, 1, 0, 4]).diff([2010], 'seconds'), 240, 'second diff');\n    });\n\n    test('diff between utc and local', function (assert) {\n        if (moment([2012]).utcOffset() === moment([2011]).utcOffset()) {\n            assert.equal(moment([2012]).utc().diff([2011], 'years'), 1, 'year diff');\n        }\n        assert.equal(moment([2010, 2, 2]).utc().diff([2010, 0, 2], 'months'), 2, 'month diff');\n        assert.equal(moment([2010, 0, 4]).utc().diff([2010], 'days'), 3, 'day diff');\n        assert.equal(moment([2010, 0, 22]).utc().diff([2010], 'weeks'), 3, 'week diff');\n        assert.equal(moment([2010, 0, 1, 4]).utc().diff([2010], 'hours'), 4, 'hour diff');\n        assert.equal(moment([2010, 0, 1, 0, 5]).utc().diff([2010], 'minutes'), 5, 'minute diff');\n        assert.equal(moment([2010, 0, 1, 0, 0, 6]).utc().diff([2010], 'seconds'), 6, 'second diff');\n    });\n\n    test('diff floored', function (assert) {\n        assert.equal(moment([2010, 0, 1, 23]).diff([2010], 'day'), 0, '23 hours = 0 days');\n        assert.equal(moment([2010, 0, 1, 23, 59]).diff([2010], 'day'), 0, '23:59 hours = 0 days');\n        assert.equal(moment([2010, 0, 1, 24]).diff([2010], 'day'), 1, '24 hours = 1 day');\n        assert.equal(moment([2010, 0, 2]).diff([2011, 0, 1], 'year'), 0, 'year rounded down');\n        assert.equal(moment([2011, 0, 1]).diff([2010, 0, 2], 'year'), 0, 'year rounded down');\n        assert.equal(moment([2010, 0, 2]).diff([2011, 0, 2], 'year'), -1, 'year rounded down');\n        assert.equal(moment([2011, 0, 2]).diff([2010, 0, 2], 'year'), 1, 'year rounded down');\n    });\n\n    test('year diffs include dates', function (assert) {\n        assert.ok(moment([2012, 1, 19]).diff(moment([2002, 1, 20]), 'years', true) < 10, 'year diff should include date of month');\n    });\n\n    test('month diffs', function (assert) {\n        assert.equal(moment([2012, 0, 1]).diff([2012, 1, 1], 'months', true), -1, 'Jan 1 to Feb 1 should be 1 month');\n        equal(assert, moment([2012, 0, 1]).diff([2012, 0, 1, 12], 'months', true), -0.5 / 31, 'Jan 1 to Jan 1 noon should be 0.5 / 31 months');\n        assert.equal(moment([2012, 0, 15]).diff([2012, 1, 15], 'months', true), -1, 'Jan 15 to Feb 15 should be 1 month');\n        assert.equal(moment([2012, 0, 28]).diff([2012, 1, 28], 'months', true), -1, 'Jan 28 to Feb 28 should be 1 month');\n        assert.ok(moment([2012, 0, 31]).diff([2012, 1, 29], 'months', true), -1, 'Jan 31 to Feb 29 should be 1 month');\n        assert.ok(-1 > moment([2012, 0, 31]).diff([2012, 2, 1], 'months', true), 'Jan 31 to Mar 1 should be more than 1 month');\n        assert.ok(-30 / 28 < moment([2012, 0, 31]).diff([2012, 2, 1], 'months', true), 'Jan 31 to Mar 1 should be less than 1 month and 1 day');\n        equal(assert, moment([2012, 0, 1]).diff([2012, 0, 31], 'months', true), -(30 / 31), 'Jan 1 to Jan 31 should be 30 / 31 months');\n        assert.ok(0 < moment('2014-02-01').diff(moment('2014-01-31'), 'months', true), 'jan-31 to feb-1 diff is positive');\n    });\n\n    test('exact month diffs', function (assert) {\n\n        var m1, m2;\n        for (m1 = 0; m1 < 12; ++m1) {\n            for (m2 = m1; m2 < 12; ++m2) {\n                assert.equal(moment([2013, m2, 15]).diff(moment([2013, m1, 15]), 'months', true), m2 - m1,\n                             'month diff from 2013-' + m1 + '-15 to 2013-' + m2 + '-15');\n            }\n        }\n    });\n\n    test('year diffs', function (assert) {\n        equal(assert, moment([2012, 0, 1]).diff([2013, 0, 1], 'years', true), -1, 'Jan 1 2012 to Jan 1 2013 should be 1 year');\n        equal(assert, moment([2012, 1, 28]).diff([2013, 1, 28], 'years', true), -1, 'Feb 28 2012 to Feb 28 2013 should be 1 year');\n        equal(assert, moment([2012, 2, 1]).diff([2013, 2, 1], 'years', true), -1, 'Mar 1 2012 to Mar 1 2013 should be 1 year');\n        equal(assert, moment([2012, 11, 1]).diff([2013, 11, 1], 'years', true), -1, 'Dec 1 2012 to Dec 1 2013 should be 1 year');\n        equal(assert, moment([2012, 11, 31]).diff([2013, 11, 31], 'years', true), -1, 'Dec 31 2012 to Dec 31 2013 should be 1 year');\n        equal(assert, moment([2012, 0, 1]).diff([2013, 6, 1], 'years', true), -1.5, 'Jan 1 2012 to Jul 1 2013 should be 1.5 years');\n        equal(assert, moment([2012, 0, 31]).diff([2013, 6, 31], 'years', true), -1.5, 'Jan 31 2012 to Jul 31 2013 should be 1.5 years');\n        equal(assert, moment([2012, 0, 1]).diff([2013, 0, 1, 12], 'years', true), -1 - (0.5 / 31) / 12, 'Jan 1 2012 to Jan 1 2013 noon should be 1+(0.5 / 31) / 12 years');\n        equal(assert, moment([2012, 0, 1]).diff([2013, 6, 1, 12], 'years', true), -1.5 - (0.5 / 31) / 12, 'Jan 1 2012 to Jul 1 2013 noon should be 1.5+(0.5 / 31) / 12 years');\n        equal(assert, moment([2012, 1, 29]).diff([2013, 1, 28], 'years', true), -1, 'Feb 29 2012 to Feb 28 2013 should be 1-(1 / 28.5) / 12 years');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('duration');\n\n    test('object instantiation', function (assert) {\n        var d = moment.duration({\n            years: 2,\n            months: 3,\n            weeks: 2,\n            days: 1,\n            hours: 8,\n            minutes: 9,\n            seconds: 20,\n            milliseconds: 12\n        });\n\n        assert.equal(d.years(),        2,  'years');\n        assert.equal(d.months(),       3,  'months');\n        assert.equal(d.weeks(),        2,  'weeks');\n        assert.equal(d.days(),         15, 'days'); // two weeks + 1 day\n        assert.equal(d.hours(),        8,  'hours');\n        assert.equal(d.minutes(),      9,  'minutes');\n        assert.equal(d.seconds(),      20, 'seconds');\n        assert.equal(d.milliseconds(), 12, 'milliseconds');\n    });\n\n    test('object instantiation with strings', function (assert) {\n        var d = moment.duration({\n            years: '2',\n            months: '3',\n            weeks: '2',\n            days: '1',\n            hours: '8',\n            minutes: '9',\n            seconds: '20',\n            milliseconds: '12'\n        });\n\n        assert.equal(d.years(),        2,  'years');\n        assert.equal(d.months(),       3,  'months');\n        assert.equal(d.weeks(),        2,  'weeks');\n        assert.equal(d.days(),         15, 'days'); // two weeks + 1 day\n        assert.equal(d.hours(),        8,  'hours');\n        assert.equal(d.minutes(),      9,  'minutes');\n        assert.equal(d.seconds(),      20, 'seconds');\n        assert.equal(d.milliseconds(), 12, 'milliseconds');\n    });\n\n    test('milliseconds instantiation', function (assert) {\n        assert.equal(moment.duration(72).milliseconds(), 72, 'milliseconds');\n    });\n\n    test('undefined instantiation', function (assert) {\n        assert.equal(moment.duration(undefined).milliseconds(), 0, 'milliseconds');\n    });\n\n    test('null instantiation', function (assert) {\n        assert.equal(moment.duration(null).milliseconds(), 0, 'milliseconds');\n    });\n\n    test('instantiation by type', function (assert) {\n        assert.equal(moment.duration(1, 'years').years(),                 1, 'years');\n        assert.equal(moment.duration(1, 'y').years(),                     1, 'y');\n        assert.equal(moment.duration(2, 'months').months(),               2, 'months');\n        assert.equal(moment.duration(2, 'M').months(),                    2, 'M');\n        assert.equal(moment.duration(3, 'weeks').weeks(),                 3, 'weeks');\n        assert.equal(moment.duration(3, 'w').weeks(),                     3, 'weeks');\n        assert.equal(moment.duration(4, 'days').days(),                   4, 'days');\n        assert.equal(moment.duration(4, 'd').days(),                      4, 'd');\n        assert.equal(moment.duration(5, 'hours').hours(),                 5, 'hours');\n        assert.equal(moment.duration(5, 'h').hours(),                     5, 'h');\n        assert.equal(moment.duration(6, 'minutes').minutes(),             6, 'minutes');\n        assert.equal(moment.duration(6, 'm').minutes(),                   6, 'm');\n        assert.equal(moment.duration(7, 'seconds').seconds(),             7, 'seconds');\n        assert.equal(moment.duration(7, 's').seconds(),                   7, 's');\n        assert.equal(moment.duration(8, 'milliseconds').milliseconds(),   8, 'milliseconds');\n        assert.equal(moment.duration(8, 'ms').milliseconds(),             8, 'ms');\n    });\n\n    test('shortcuts', function (assert) {\n        assert.equal(moment.duration({y: 1}).years(),         1, 'years = y');\n        assert.equal(moment.duration({M: 2}).months(),        2, 'months = M');\n        assert.equal(moment.duration({w: 3}).weeks(),         3, 'weeks = w');\n        assert.equal(moment.duration({d: 4}).days(),          4, 'days = d');\n        assert.equal(moment.duration({h: 5}).hours(),         5, 'hours = h');\n        assert.equal(moment.duration({m: 6}).minutes(),       6, 'minutes = m');\n        assert.equal(moment.duration({s: 7}).seconds(),       7, 'seconds = s');\n        assert.equal(moment.duration({ms: 8}).milliseconds(), 8, 'milliseconds = ms');\n    });\n\n    test('generic getter', function (assert) {\n        assert.equal(moment.duration(1, 'years').get('years'),                1, 'years');\n        assert.equal(moment.duration(1, 'years').get('year'),                 1, 'years = year');\n        assert.equal(moment.duration(1, 'years').get('y'),                    1, 'years = y');\n        assert.equal(moment.duration(2, 'months').get('months'),              2, 'months');\n        assert.equal(moment.duration(2, 'months').get('month'),               2, 'months = month');\n        assert.equal(moment.duration(2, 'months').get('M'),                   2, 'months = M');\n        assert.equal(moment.duration(3, 'weeks').get('weeks'),                3, 'weeks');\n        assert.equal(moment.duration(3, 'weeks').get('week'),                 3, 'weeks = week');\n        assert.equal(moment.duration(3, 'weeks').get('w'),                    3, 'weeks = w');\n        assert.equal(moment.duration(4, 'days').get('days'),                  4, 'days');\n        assert.equal(moment.duration(4, 'days').get('day'),                   4, 'days = day');\n        assert.equal(moment.duration(4, 'days').get('d'),                     4, 'days = d');\n        assert.equal(moment.duration(5, 'hours').get('hours'),                5, 'hours');\n        assert.equal(moment.duration(5, 'hours').get('hour'),                 5, 'hours = hour');\n        assert.equal(moment.duration(5, 'hours').get('h'),                    5, 'hours = h');\n        assert.equal(moment.duration(6, 'minutes').get('minutes'),            6, 'minutes');\n        assert.equal(moment.duration(6, 'minutes').get('minute'),             6, 'minutes = minute');\n        assert.equal(moment.duration(6, 'minutes').get('m'),                  6, 'minutes = m');\n        assert.equal(moment.duration(7, 'seconds').get('seconds'),            7, 'seconds');\n        assert.equal(moment.duration(7, 'seconds').get('second'),             7, 'seconds = second');\n        assert.equal(moment.duration(7, 'seconds').get('s'),                  7, 'seconds = s');\n        assert.equal(moment.duration(8, 'milliseconds').get('milliseconds'),  8, 'milliseconds');\n        assert.equal(moment.duration(8, 'milliseconds').get('millisecond'),   8, 'milliseconds = millisecond');\n        assert.equal(moment.duration(8, 'milliseconds').get('ms'),            8, 'milliseconds = ms');\n    });\n\n    test('instantiation from another duration', function (assert) {\n        var simple = moment.duration(1234),\n            lengthy = moment.duration(60 * 60 * 24 * 360 * 1e3),\n            complicated = moment.duration({\n                years: 2,\n                months: 3,\n                weeks: 4,\n                days: 1,\n                hours: 8,\n                minutes: 9,\n                seconds: 20,\n                milliseconds: 12\n            }),\n            modified = moment.duration(1, 'day').add(moment.duration(1, 'day'));\n\n        assert.deepEqual(moment.duration(simple), simple, 'simple clones are equal');\n        assert.deepEqual(moment.duration(lengthy), lengthy, 'lengthy clones are equal');\n        assert.deepEqual(moment.duration(complicated), complicated, 'complicated clones are equal');\n        assert.deepEqual(moment.duration(modified), modified, 'cloning modified duration works');\n    });\n\n    test('instantiation from 24-hour time zero', function (assert) {\n        assert.equal(moment.duration('00:00').years(), 0, '0 years');\n        assert.equal(moment.duration('00:00').days(), 0, '0 days');\n        assert.equal(moment.duration('00:00').hours(), 0, '0 hours');\n        assert.equal(moment.duration('00:00').minutes(), 0, '0 minutes');\n        assert.equal(moment.duration('00:00').seconds(), 0, '0 seconds');\n        assert.equal(moment.duration('00:00').milliseconds(), 0, '0 milliseconds');\n    });\n\n    test('instantiation from 24-hour time <24 hours', function (assert) {\n        assert.equal(moment.duration('06:45').years(), 0, '0 years');\n        assert.equal(moment.duration('06:45').days(), 0, '0 days');\n        assert.equal(moment.duration('06:45').hours(), 6, '6 hours');\n        assert.equal(moment.duration('06:45').minutes(), 45, '45 minutes');\n        assert.equal(moment.duration('06:45').seconds(), 0, '0 seconds');\n        assert.equal(moment.duration('06:45').milliseconds(), 0, '0 milliseconds');\n    });\n\n    test('instantiation from 24-hour time >24 hours', function (assert) {\n        assert.equal(moment.duration('26:45').years(), 0, '0 years');\n        assert.equal(moment.duration('26:45').days(), 1, '0 days');\n        assert.equal(moment.duration('26:45').hours(), 2, '2 hours');\n        assert.equal(moment.duration('26:45').minutes(), 45, '45 minutes');\n        assert.equal(moment.duration('26:45').seconds(), 0, '0 seconds');\n        assert.equal(moment.duration('26:45').milliseconds(), 0, '0 milliseconds');\n    });\n\n    test('instatiation from serialized C# TimeSpan zero', function (assert) {\n        assert.equal(moment.duration('00:00:00').years(), 0, '0 years');\n        assert.equal(moment.duration('00:00:00').days(), 0, '0 days');\n        assert.equal(moment.duration('00:00:00').hours(), 0, '0 hours');\n        assert.equal(moment.duration('00:00:00').minutes(), 0, '0 minutes');\n        assert.equal(moment.duration('00:00:00').seconds(), 0, '0 seconds');\n        assert.equal(moment.duration('00:00:00').milliseconds(), 0, '0 milliseconds');\n    });\n\n    test('instatiation from serialized C# TimeSpan with days', function (assert) {\n        assert.equal(moment.duration('1.02:03:04.9999999').years(), 0, '0 years');\n        assert.equal(moment.duration('1.02:03:04.9999999').days(), 1, '1 day');\n        assert.equal(moment.duration('1.02:03:04.9999999').hours(), 2, '2 hours');\n        assert.equal(moment.duration('1.02:03:04.9999999').minutes(), 3, '3 minutes');\n        assert.equal(moment.duration('1.02:03:04.9999999').seconds(), 4, '4 seconds');\n        assert.equal(moment.duration('1.02:03:04.9999999').milliseconds(), 999, '999 milliseconds');\n    });\n\n    test('instatiation from serialized C# TimeSpan without days', function (assert) {\n        assert.equal(moment.duration('01:02:03.9999999').years(), 0, '0 years');\n        assert.equal(moment.duration('01:02:03.9999999').days(), 0, '0 days');\n        assert.equal(moment.duration('01:02:03.9999999').hours(), 1, '1 hour');\n        assert.equal(moment.duration('01:02:03.9999999').minutes(), 2, '2 minutes');\n        assert.equal(moment.duration('01:02:03.9999999').seconds(), 3, '3 seconds');\n        assert.equal(moment.duration('01:02:03.9999999').milliseconds(), 999, '999 milliseconds');\n\n        assert.equal(moment.duration('23:59:59.9999999').days(), 0, '0 days');\n        assert.equal(moment.duration('23:59:59.9999999').hours(), 23, '23 hours');\n\n        assert.equal(moment.duration('500:59:59.9999999').days(), 20, '500 hours overflows to 20 days');\n        assert.equal(moment.duration('500:59:59.9999999').hours(), 20, '500 hours overflows to 20 hours');\n    });\n\n    test('instatiation from serialized C# TimeSpan without days or milliseconds', function (assert) {\n        assert.equal(moment.duration('01:02:03').years(), 0, '0 years');\n        assert.equal(moment.duration('01:02:03').days(), 0, '0 days');\n        assert.equal(moment.duration('01:02:03').hours(), 1, '1 hour');\n        assert.equal(moment.duration('01:02:03').minutes(), 2, '2 minutes');\n        assert.equal(moment.duration('01:02:03').seconds(), 3, '3 seconds');\n        assert.equal(moment.duration('01:02:03').milliseconds(), 0, '0 milliseconds');\n    });\n\n    test('instatiation from serialized C# TimeSpan without milliseconds', function (assert) {\n        assert.equal(moment.duration('1.02:03:04').years(), 0, '0 years');\n        assert.equal(moment.duration('1.02:03:04').days(), 1, '1 day');\n        assert.equal(moment.duration('1.02:03:04').hours(), 2, '2 hours');\n        assert.equal(moment.duration('1.02:03:04').minutes(), 3, '3 minutes');\n        assert.equal(moment.duration('1.02:03:04').seconds(), 4, '4 seconds');\n        assert.equal(moment.duration('1.02:03:04').milliseconds(), 0, '0 milliseconds');\n    });\n\n    test('instatiation from serialized C# TimeSpan maxValue', function (assert) {\n        var d = moment.duration('10675199.02:48:05.4775807');\n\n        assert.equal(d.years(), 29227, '29227 years');\n        assert.equal(d.months(), 8, '8 months');\n        assert.equal(d.days(), 17, '17 day');  // this should be 13\n\n        assert.equal(d.hours(), 2, '2 hours');\n        assert.equal(d.minutes(), 48, '48 minutes');\n        assert.equal(d.seconds(), 5, '5 seconds');\n        assert.equal(d.milliseconds(), 477, '477 milliseconds');\n    });\n\n    test('instatiation from serialized C# TimeSpan minValue', function (assert) {\n        var d = moment.duration('-10675199.02:48:05.4775808');\n\n        assert.equal(d.years(), -29227, '29653 years');\n        assert.equal(d.months(), -8, '8 day');\n        assert.equal(d.days(), -17, '17 day'); // this should be 13\n\n        assert.equal(d.hours(), -2, '2 hours');\n        assert.equal(d.minutes(), -48, '48 minutes');\n        assert.equal(d.seconds(), -5, '5 seconds');\n        assert.equal(d.milliseconds(), -477, '477 milliseconds');\n    });\n\n    test('instantiation from ISO 8601 duration', function (assert) {\n        assert.equal(moment.duration('P1Y2M3DT4H5M6S').asSeconds(), moment.duration({y: 1, M: 2, d: 3, h: 4, m: 5, s: 6}).asSeconds(), 'all fields');\n        assert.equal(moment.duration('P1M').asSeconds(), moment.duration({M: 1}).asSeconds(), 'single month field');\n        assert.equal(moment.duration('PT1M').asSeconds(), moment.duration({m: 1}).asSeconds(), 'single minute field');\n        assert.equal(moment.duration('P1MT2H').asSeconds(), moment.duration({M: 1, h: 2}).asSeconds(), 'random fields missing');\n        assert.equal(moment.duration('-P60D').asSeconds(), moment.duration({d: -60}).asSeconds(), 'negative days');\n        assert.equal(moment.duration('PT0.5S').asSeconds(), moment.duration({s: 0.5}).asSeconds(), 'fractional seconds');\n        assert.equal(moment.duration('PT0,5S').asSeconds(), moment.duration({s: 0.5}).asSeconds(), 'fractional seconds (comma)');\n    });\n\n    test('serialization to ISO 8601 duration strings', function (assert) {\n        assert.equal(moment.duration({y: 1, M: 2, d: 3, h: 4, m: 5, s: 6}).toISOString(), 'P1Y2M3DT4H5M6S', 'all fields');\n        assert.equal(moment.duration({M: -1}).toISOString(), '-P1M', 'one month ago');\n        assert.equal(moment.duration({m: -1}).toISOString(), '-PT1M', 'one minute ago');\n        assert.equal(moment.duration({s: -0.5}).toISOString(), '-PT0.5S', 'one half second ago');\n        assert.equal(moment.duration({y: -0.5, M: 1}).toISOString(), '-P5M', 'a month after half a year ago');\n        assert.equal(moment.duration({}).toISOString(), 'P0D', 'zero duration');\n    });\n\n    test('toString acts as toISOString', function (assert) {\n        assert.equal(moment.duration({y: 1, M: 2, d: 3, h: 4, m: 5, s: 6}).toString(), 'P1Y2M3DT4H5M6S', 'all fields');\n        assert.equal(moment.duration({M: -1}).toString(), '-P1M', 'one month ago');\n        assert.equal(moment.duration({m: -1}).toString(), '-PT1M', 'one minute ago');\n        assert.equal(moment.duration({s: -0.5}).toString(), '-PT0.5S', 'one half second ago');\n        assert.equal(moment.duration({y: -0.5, M: 1}).toString(), '-P5M', 'a month after half a year ago');\n        assert.equal(moment.duration({}).toString(), 'P0D', 'zero duration');\n    });\n\n    test('toIsoString deprecation', function (assert) {\n        assert.equal(moment.duration({}).toIsoString(), moment.duration({}).toISOString(), 'toIsoString delegates to toISOString');\n    });\n\n    test('`isodate` (python) test cases', function (assert) {\n        assert.equal(moment.duration('P18Y9M4DT11H9M8S').asSeconds(), moment.duration({y: 18, M: 9, d: 4, h: 11, m: 9, s: 8}).asSeconds(), 'python isodate 1');\n        assert.equal(moment.duration('P2W').asSeconds(), moment.duration({w: 2}).asSeconds(), 'python isodate 2');\n        assert.equal(moment.duration('P3Y6M4DT12H30M5S').asSeconds(), moment.duration({y: 3, M: 6, d: 4, h: 12, m: 30, s: 5}).asSeconds(), 'python isodate 3');\n        assert.equal(moment.duration('P23DT23H').asSeconds(), moment.duration({d: 23, h: 23}).asSeconds(), 'python isodate 4');\n        assert.equal(moment.duration('P4Y').asSeconds(), moment.duration({y: 4}).asSeconds(), 'python isodate 5');\n        assert.equal(moment.duration('P1M').asSeconds(), moment.duration({M: 1}).asSeconds(), 'python isodate 6');\n        assert.equal(moment.duration('PT1M').asSeconds(), moment.duration({m: 1}).asSeconds(), 'python isodate 7');\n        assert.equal(moment.duration('P0.5Y').asSeconds(), moment.duration({y: 0.5}).asSeconds(), 'python isodate 8');\n        assert.equal(moment.duration('PT36H').asSeconds(), moment.duration({h: 36}).asSeconds(), 'python isodate 9');\n        assert.equal(moment.duration('P1DT12H').asSeconds(), moment.duration({d: 1, h: 12}).asSeconds(), 'python isodate 10');\n        assert.equal(moment.duration('-P2W').asSeconds(), moment.duration({w: -2}).asSeconds(), 'python isodate 11');\n        assert.equal(moment.duration('-P2.2W').asSeconds(), moment.duration({w: -2.2}).asSeconds(), 'python isodate 12');\n        assert.equal(moment.duration('P1DT2H3M4S').asSeconds(), moment.duration({d: 1, h: 2, m: 3, s: 4}).asSeconds(), 'python isodate 13');\n        assert.equal(moment.duration('P1DT2H3M').asSeconds(), moment.duration({d: 1, h: 2, m: 3}).asSeconds(), 'python isodate 14');\n        assert.equal(moment.duration('P1DT2H').asSeconds(), moment.duration({d: 1, h: 2}).asSeconds(), 'python isodate 15');\n        assert.equal(moment.duration('PT2H').asSeconds(), moment.duration({h: 2}).asSeconds(), 'python isodate 16');\n        assert.equal(moment.duration('PT2.3H').asSeconds(), moment.duration({h: 2.3}).asSeconds(), 'python isodate 17');\n        assert.equal(moment.duration('PT2H3M4S').asSeconds(), moment.duration({h: 2, m: 3, s: 4}).asSeconds(), 'python isodate 18');\n        assert.equal(moment.duration('PT3M4S').asSeconds(), moment.duration({m: 3, s: 4}).asSeconds(), 'python isodate 19');\n        assert.equal(moment.duration('PT22S').asSeconds(), moment.duration({s: 22}).asSeconds(), 'python isodate 20');\n        assert.equal(moment.duration('PT22.22S').asSeconds(), moment.duration({s: 22.22}).asSeconds(), 'python isodate 21');\n        assert.equal(moment.duration('-P2Y').asSeconds(), moment.duration({y: -2}).asSeconds(), 'python isodate 22');\n        assert.equal(moment.duration('-P3Y6M4DT12H30M5S').asSeconds(), moment.duration({y: -3, M: -6, d: -4, h: -12, m: -30, s: -5}).asSeconds(), 'python isodate 23');\n        assert.equal(moment.duration('-P1DT2H3M4S').asSeconds(), moment.duration({d: -1, h: -2, m: -3, s: -4}).asSeconds(), 'python isodate 24');\n    });\n\n    test('ISO 8601 misuse cases', function (assert) {\n        assert.equal(moment.duration('P').asSeconds(), 0, 'lonely P');\n        assert.equal(moment.duration('PT').asSeconds(), 0, 'just P and T');\n        assert.equal(moment.duration('P1H').asSeconds(), 0, 'missing T');\n        assert.equal(moment.duration('P1D1Y').asSeconds(), 0, 'out of order');\n        assert.equal(moment.duration('PT.5S').asSeconds(), 0.5, 'accept no leading zero for decimal');\n        assert.equal(moment.duration('PT1,S').asSeconds(), 1, 'accept trailing decimal separator');\n        assert.equal(moment.duration('PT1M0,,5S').asSeconds(), 60, 'extra decimal separators are ignored as 0');\n        assert.equal(moment.duration('P-1DS').asSeconds(), 0, 'wrong position of negative');\n    });\n\n    test('humanize', function (assert) {\n        moment.locale('en');\n        assert.equal(moment.duration({seconds: 44}).humanize(),  'a few seconds', '44 seconds = a few seconds');\n        assert.equal(moment.duration({seconds: 45}).humanize(),  'a minute',      '45 seconds = a minute');\n        assert.equal(moment.duration({seconds: 89}).humanize(),  'a minute',      '89 seconds = a minute');\n        assert.equal(moment.duration({seconds: 90}).humanize(),  '2 minutes',     '90 seconds = 2 minutes');\n        assert.equal(moment.duration({minutes: 44}).humanize(),  '44 minutes',    '44 minutes = 44 minutes');\n        assert.equal(moment.duration({minutes: 45}).humanize(),  'an hour',       '45 minutes = an hour');\n        assert.equal(moment.duration({minutes: 89}).humanize(),  'an hour',       '89 minutes = an hour');\n        assert.equal(moment.duration({minutes: 90}).humanize(),  '2 hours',       '90 minutes = 2 hours');\n        assert.equal(moment.duration({hours: 5}).humanize(),     '5 hours',       '5 hours = 5 hours');\n        assert.equal(moment.duration({hours: 21}).humanize(),    '21 hours',      '21 hours = 21 hours');\n        assert.equal(moment.duration({hours: 22}).humanize(),    'a day',         '22 hours = a day');\n        assert.equal(moment.duration({hours: 35}).humanize(),    'a day',         '35 hours = a day');\n        assert.equal(moment.duration({hours: 36}).humanize(),    '2 days',        '36 hours = 2 days');\n        assert.equal(moment.duration({days: 1}).humanize(),      'a day',         '1 day = a day');\n        assert.equal(moment.duration({days: 5}).humanize(),      '5 days',        '5 days = 5 days');\n        assert.equal(moment.duration({weeks: 1}).humanize(),     '7 days',        '1 week = 7 days');\n        assert.equal(moment.duration({days: 25}).humanize(),     '25 days',       '25 days = 25 days');\n        assert.equal(moment.duration({days: 26}).humanize(),     'a month',       '26 days = a month');\n        assert.equal(moment.duration({days: 30}).humanize(),     'a month',       '30 days = a month');\n        assert.equal(moment.duration({days: 45}).humanize(),     'a month',       '45 days = a month');\n        assert.equal(moment.duration({days: 46}).humanize(),     '2 months',      '46 days = 2 months');\n        assert.equal(moment.duration({days: 74}).humanize(),     '2 months',      '74 days = 2 months');\n        assert.equal(moment.duration({days: 77}).humanize(),     '3 months',      '77 days = 3 months');\n        assert.equal(moment.duration({months: 1}).humanize(),    'a month',       '1 month = a month');\n        assert.equal(moment.duration({months: 5}).humanize(),    '5 months',      '5 months = 5 months');\n        assert.equal(moment.duration({days: 344}).humanize(),    'a year',        '344 days = a year');\n        assert.equal(moment.duration({days: 345}).humanize(),    'a year',        '345 days = a year');\n        assert.equal(moment.duration({days: 547}).humanize(),    'a year',        '547 days = a year');\n        assert.equal(moment.duration({days: 548}).humanize(),    '2 years',       '548 days = 2 years');\n        assert.equal(moment.duration({years: 1}).humanize(),     'a year',        '1 year = a year');\n        assert.equal(moment.duration({years: 5}).humanize(),     '5 years',       '5 years = 5 years');\n        assert.equal(moment.duration(7200000).humanize(),        '2 hours',       '7200000 = 2 minutes');\n    });\n\n    test('humanize duration with suffix', function (assert) {\n        moment.locale('en');\n        assert.equal(moment.duration({seconds:  44}).humanize(true),  'in a few seconds', '44 seconds = a few seconds');\n        assert.equal(moment.duration({seconds: -44}).humanize(true),  'a few seconds ago', '44 seconds = a few seconds');\n    });\n\n    test('bubble value up', function (assert) {\n        assert.equal(moment.duration({milliseconds: 61001}).milliseconds(), 1, '61001 milliseconds has 1 millisecond left over');\n        assert.equal(moment.duration({milliseconds: 61001}).seconds(),      1, '61001 milliseconds has 1 second left over');\n        assert.equal(moment.duration({milliseconds: 61001}).minutes(),      1, '61001 milliseconds has 1 minute left over');\n\n        assert.equal(moment.duration({minutes: 350}).minutes(), 50, '350 minutes has 50 minutes left over');\n        assert.equal(moment.duration({minutes: 350}).hours(),   5,  '350 minutes has 5 hours left over');\n    });\n\n    test('clipping', function (assert) {\n        assert.equal(moment.duration({months: 11}).months(), 11, '11 months is 11 months');\n        assert.equal(moment.duration({months: 11}).years(),  0,  '11 months makes no year');\n        assert.equal(moment.duration({months: 12}).months(), 0,  '12 months is 0 months left over');\n        assert.equal(moment.duration({months: 12}).years(),  1,  '12 months makes 1 year');\n        assert.equal(moment.duration({months: 13}).months(), 1,  '13 months is 1 month left over');\n        assert.equal(moment.duration({months: 13}).years(),  1,  '13 months makes 1 year');\n\n        assert.equal(moment.duration({days: 29}).days(),   29, '29 days is 29 days');\n        assert.equal(moment.duration({days: 29}).months(), 0,  '29 days makes no month');\n        assert.equal(moment.duration({days: 30}).days(),   0,  '30 days is 0 days left over');\n        assert.equal(moment.duration({days: 30}).months(), 1,  '30 days is a month');\n        assert.equal(moment.duration({days: 31}).days(),   1,  '31 days is 1 day left over');\n        assert.equal(moment.duration({days: 31}).months(), 1,  '31 days is a month');\n\n        assert.equal(moment.duration({hours: 23}).hours(), 23, '23 hours is 23 hours');\n        assert.equal(moment.duration({hours: 23}).days(),  0,  '23 hours makes no day');\n        assert.equal(moment.duration({hours: 24}).hours(), 0,  '24 hours is 0 hours left over');\n        assert.equal(moment.duration({hours: 24}).days(),  1,  '24 hours makes 1 day');\n        assert.equal(moment.duration({hours: 25}).hours(), 1,  '25 hours is 1 hour left over');\n        assert.equal(moment.duration({hours: 25}).days(),  1,  '25 hours makes 1 day');\n    });\n\n    test('effective equivalency', function (assert) {\n        assert.deepEqual(moment.duration({seconds: 1})._data,  moment.duration({milliseconds: 1000})._data, '1 second is the same as 1000 milliseconds');\n        assert.deepEqual(moment.duration({seconds: 60})._data, moment.duration({minutes: 1})._data,         '1 minute is the same as 60 seconds');\n        assert.deepEqual(moment.duration({minutes: 60})._data, moment.duration({hours: 1})._data,           '1 hour is the same as 60 minutes');\n        assert.deepEqual(moment.duration({hours: 24})._data,   moment.duration({days: 1})._data,            '1 day is the same as 24 hours');\n        assert.deepEqual(moment.duration({days: 7})._data,     moment.duration({weeks: 1})._data,           '1 week is the same as 7 days');\n        assert.deepEqual(moment.duration({days: 30})._data,    moment.duration({months: 1})._data,          '1 month is the same as 30 days');\n        assert.deepEqual(moment.duration({months: 12})._data,  moment.duration({years: 1})._data,           '1 years is the same as 12 months');\n    });\n\n    test('asGetters', function (assert) {\n        assert.equal(moment.duration(1, 'year').asYears(),            1,           '1 year as years');\n        assert.equal(moment.duration(1, 'year').asMonths(),           12,          '1 year as months');\n        assert.equal(moment.duration(400, 'year').asMonths(),         4800,        '400 years as months');\n        assert.equal(moment.duration(1, 'year').asWeeks().toFixed(3), 52.143,      '1 year as weeks');\n        assert.equal(moment.duration(1, 'year').asDays(),             365,         '1 year as days');\n        assert.equal(moment.duration(2, 'year').asDays(),             730,         '2 years as days');\n        assert.equal(moment.duration(3, 'year').asDays(),             1096,        '3 years as days');\n        assert.equal(moment.duration(4, 'year').asDays(),             1461,        '4 years as days');\n        assert.equal(moment.duration(400, 'year').asDays(),           146097,      '400 years as days');\n        assert.equal(moment.duration(1, 'year').asHours(),            8760,        '1 year as hours');\n        assert.equal(moment.duration(1, 'year').asMinutes(),          525600,      '1 year as minutes');\n        assert.equal(moment.duration(1, 'year').asSeconds(),          31536000,    '1 year as seconds');\n        assert.equal(moment.duration(1, 'year').asMilliseconds(),     31536000000, '1 year as milliseconds');\n        assert.equal(moment.duration(1, 'month').asYears().toFixed(4), 0.0833,     '1 month as years');\n        assert.equal(moment.duration(1, 'month').asMonths(),           1,          '1 month as months');\n        assert.equal(moment.duration(1, 'month').asWeeks().toFixed(3), 4.286,      '1 month as weeks');\n        assert.equal(moment.duration(1, 'month').asDays(),             30,         '1 month as days');\n        assert.equal(moment.duration(2, 'month').asDays(),             61,         '2 months as days');\n        assert.equal(moment.duration(3, 'month').asDays(),             91,         '3 months as days');\n        assert.equal(moment.duration(4, 'month').asDays(),             122,        '4 months as days');\n        assert.equal(moment.duration(5, 'month').asDays(),             152,        '5 months as days');\n        assert.equal(moment.duration(6, 'month').asDays(),             183,        '6 months as days');\n        assert.equal(moment.duration(7, 'month').asDays(),             213,        '7 months as days');\n        assert.equal(moment.duration(8, 'month').asDays(),             243,        '8 months as days');\n        assert.equal(moment.duration(9, 'month').asDays(),             274,        '9 months as days');\n        assert.equal(moment.duration(10, 'month').asDays(),            304,        '10 months as days');\n        assert.equal(moment.duration(11, 'month').asDays(),            335,        '11 months as days');\n        assert.equal(moment.duration(12, 'month').asDays(),            365,        '12 months as days');\n        assert.equal(moment.duration(24, 'month').asDays(),            730,        '24 months as days');\n        assert.equal(moment.duration(36, 'month').asDays(),            1096,       '36 months as days');\n        assert.equal(moment.duration(48, 'month').asDays(),            1461,       '48 months as days');\n        assert.equal(moment.duration(4800, 'month').asDays(),          146097,     '4800 months as days');\n        assert.equal(moment.duration(1, 'month').asHours(),            720,        '1 month as hours');\n        assert.equal(moment.duration(1, 'month').asMinutes(),          43200,      '1 month as minutes');\n        assert.equal(moment.duration(1, 'month').asSeconds(),          2592000,    '1 month as seconds');\n        assert.equal(moment.duration(1, 'month').asMilliseconds(),     2592000000, '1 month as milliseconds');\n        assert.equal(moment.duration(1, 'week').asYears().toFixed(4),  0.0192,    '1 week as years');\n        assert.equal(moment.duration(1, 'week').asMonths().toFixed(3), 0.230,     '1 week as months');\n        assert.equal(moment.duration(1, 'week').asWeeks(),             1,         '1 week as weeks');\n        assert.equal(moment.duration(1, 'week').asDays(),              7,         '1 week as days');\n        assert.equal(moment.duration(1, 'week').asHours(),             168,       '1 week as hours');\n        assert.equal(moment.duration(1, 'week').asMinutes(),           10080,     '1 week as minutes');\n        assert.equal(moment.duration(1, 'week').asSeconds(),           604800,    '1 week as seconds');\n        assert.equal(moment.duration(1, 'week').asMilliseconds(),      604800000, '1 week as milliseconds');\n        assert.equal(moment.duration(1, 'day').asYears().toFixed(4),  0.0027,   '1 day as years');\n        assert.equal(moment.duration(1, 'day').asMonths().toFixed(3), 0.033,    '1 day as months');\n        assert.equal(moment.duration(1, 'day').asWeeks().toFixed(3),  0.143,    '1 day as weeks');\n        assert.equal(moment.duration(1, 'day').asDays(),              1,        '1 day as days');\n        assert.equal(moment.duration(1, 'day').asHours(),             24,       '1 day as hours');\n        assert.equal(moment.duration(1, 'day').asMinutes(),           1440,     '1 day as minutes');\n        assert.equal(moment.duration(1, 'day').asSeconds(),           86400,    '1 day as seconds');\n        assert.equal(moment.duration(1, 'day').asMilliseconds(),      86400000, '1 day as milliseconds');\n        assert.equal(moment.duration(1, 'hour').asYears().toFixed(6),  0.000114, '1 hour as years');\n        assert.equal(moment.duration(1, 'hour').asMonths().toFixed(5), 0.00137,  '1 hour as months');\n        assert.equal(moment.duration(1, 'hour').asWeeks().toFixed(5),  0.00595,  '1 hour as weeks');\n        assert.equal(moment.duration(1, 'hour').asDays().toFixed(4),   0.0417,   '1 hour as days');\n        assert.equal(moment.duration(1, 'hour').asHours(),             1,        '1 hour as hours');\n        assert.equal(moment.duration(1, 'hour').asMinutes(),           60,       '1 hour as minutes');\n        assert.equal(moment.duration(1, 'hour').asSeconds(),           3600,     '1 hour as seconds');\n        assert.equal(moment.duration(1, 'hour').asMilliseconds(),      3600000,  '1 hour as milliseconds');\n        assert.equal(moment.duration(1, 'minute').asYears().toFixed(8),  0.00000190, '1 minute as years');\n        assert.equal(moment.duration(1, 'minute').asMonths().toFixed(7), 0.0000228,  '1 minute as months');\n        assert.equal(moment.duration(1, 'minute').asWeeks().toFixed(7),  0.0000992,  '1 minute as weeks');\n        assert.equal(moment.duration(1, 'minute').asDays().toFixed(6),   0.000694,   '1 minute as days');\n        assert.equal(moment.duration(1, 'minute').asHours().toFixed(4),  0.0167,     '1 minute as hours');\n        assert.equal(moment.duration(1, 'minute').asMinutes(),           1,          '1 minute as minutes');\n        assert.equal(moment.duration(1, 'minute').asSeconds(),           60,         '1 minute as seconds');\n        assert.equal(moment.duration(1, 'minute').asMilliseconds(),      60000,      '1 minute as milliseconds');\n        assert.equal(moment.duration(1, 'second').asYears().toFixed(10),  0.0000000317, '1 second as years');\n        assert.equal(moment.duration(1, 'second').asMonths().toFixed(9),  0.000000380,  '1 second as months');\n        assert.equal(moment.duration(1, 'second').asWeeks().toFixed(8),   0.00000165,   '1 second as weeks');\n        assert.equal(moment.duration(1, 'second').asDays().toFixed(7),    0.0000116,    '1 second as days');\n        assert.equal(moment.duration(1, 'second').asHours().toFixed(6),   0.000278,     '1 second as hours');\n        assert.equal(moment.duration(1, 'second').asMinutes().toFixed(4), 0.0167,       '1 second as minutes');\n        assert.equal(moment.duration(1, 'second').asSeconds(),            1,            '1 second as seconds');\n        assert.equal(moment.duration(1, 'second').asMilliseconds(),       1000,         '1 second as milliseconds');\n        assert.equal(moment.duration(1, 'millisecond').asYears().toFixed(13),  0.0000000000317, '1 millisecond as years');\n        assert.equal(moment.duration(1, 'millisecond').asMonths().toFixed(12), 0.000000000380,  '1 millisecond as months');\n        assert.equal(moment.duration(1, 'millisecond').asWeeks().toFixed(11),  0.00000000165,   '1 millisecond as weeks');\n        assert.equal(moment.duration(1, 'millisecond').asDays().toFixed(10),   0.0000000116,    '1 millisecond as days');\n        assert.equal(moment.duration(1, 'millisecond').asHours().toFixed(9),   0.000000278,     '1 millisecond as hours');\n        assert.equal(moment.duration(1, 'millisecond').asMinutes().toFixed(7), 0.0000167,       '1 millisecond as minutes');\n        assert.equal(moment.duration(1, 'millisecond').asSeconds(),            0.001,           '1 millisecond as seconds');\n        assert.equal(moment.duration(1, 'millisecond').asMilliseconds(),       1,               '1 millisecond as milliseconds');\n    });\n\n    test('as getters for small units', function (assert) {\n        var dS = moment.duration(1, 'milliseconds'),\n            ds = moment.duration(3, 'seconds'),\n            dm = moment.duration(13, 'minutes');\n        assert.equal(dS.as('milliseconds'), 1, 'as(\"milliseconds\")');\n        assert.equal(dS.asMilliseconds(),   1, 'asMilliseconds()');\n        assert.equal(ds.as('seconds'),      3, 'as(\"seconds\")');\n        assert.equal(ds.asSeconds(),        3, 'asSeconds()');\n        assert.equal(dm.as('minutes'),      13, 'as(\"minutes\")');\n        assert.equal(dm.asMinutes(),        13, 'asMinutes()');\n    });\n\n    test('isDuration', function (assert) {\n        assert.ok(moment.isDuration(moment.duration(12345678)), 'correctly says true');\n        assert.ok(!moment.isDuration(moment()), 'moment object is not a duration');\n        assert.ok(!moment.isDuration({milliseconds: 1}), 'plain object is not a duration');\n    });\n\n    test('add', function (assert) {\n        var d = moment.duration({months: 4, weeks: 3, days: 2});\n        assert.equal(d.add(1, 'month')._months, 5, 'Add months');\n        assert.equal(d.add(5, 'days')._days, 28, 'Add days');\n        assert.equal(d.add(10000)._milliseconds, 10000, 'Add milliseconds');\n        assert.equal(d.add({h: 23, m: 59})._milliseconds, 23 * 60 * 60 * 1000 + 59 * 60 * 1000 + 10000, 'Add hour:minute');\n    });\n\n    test('add and bubble', function (assert) {\n        assert.equal(moment.duration(1, 'second').add(1000, 'milliseconds').seconds(), 2, 'Adding milliseconds should bubble up to seconds');\n        assert.equal(moment.duration(1, 'minute').add(60, 'second').minutes(), 2, 'Adding seconds should bubble up to minutes');\n        assert.equal(moment.duration(1, 'hour').add(60, 'minutes').hours(), 2, 'Adding minutes should bubble up to hours');\n        assert.equal(moment.duration(1, 'day').add(24, 'hours').days(), 2, 'Adding hours should bubble up to days');\n    });\n\n    test('subtract and bubble', function (assert) {\n        assert.equal(moment.duration(2, 'second').subtract(1000, 'milliseconds').seconds(), 1, 'Subtracting milliseconds should bubble up to seconds');\n        assert.equal(moment.duration(2, 'minute').subtract(60, 'second').minutes(), 1, 'Subtracting seconds should bubble up to minutes');\n        assert.equal(moment.duration(2, 'hour').subtract(60, 'minutes').hours(), 1, 'Subtracting minutes should bubble up to hours');\n        assert.equal(moment.duration(2, 'day').subtract(24, 'hours').days(), 1, 'Subtracting hours should bubble up to days');\n    });\n\n    test('subtract', function (assert) {\n        var d = moment.duration({months: 2, weeks: 2, days: 0, hours: 5});\n        assert.equal(d.subtract(1, 'months')._months, 1, 'Subtract months');\n        assert.equal(d.subtract(14, 'days')._days, 0, 'Subtract days');\n        assert.equal(d.subtract(10000)._milliseconds, 5 * 60 * 60 * 1000 - 10000, 'Subtract milliseconds');\n        assert.equal(d.subtract({h: 1, m: 59})._milliseconds, 3 * 60 * 60 * 1000 + 1 * 60 * 1000 - 10000, 'Subtract hour:minute');\n    });\n\n    test('JSON.stringify duration', function (assert) {\n        var d = moment.duration(1024, 'h');\n\n        assert.equal(JSON.stringify(d), '\"' + d.toISOString() + '\"', 'JSON.stringify on duration should return ISO string');\n    });\n\n    test('duration plugins', function (assert) {\n        var durationObject = moment.duration();\n        moment.duration.fn.foo = function (arg) {\n            assert.equal(this, durationObject);\n            assert.equal(arg, 5);\n        };\n        durationObject.foo(5);\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('duration from moments');\n\n    test('pure year diff', function (assert) {\n        var m1 = moment('2012-01-01T00:00:00.000Z'),\n            m2 = moment('2013-01-01T00:00:00.000Z');\n\n        assert.equal(moment.duration({from: m1, to: m2}).as('years'), 1, 'year moment difference');\n        assert.equal(moment.duration({from: m2, to: m1}).as('years'), -1, 'negative year moment difference');\n    });\n\n    test('month and day diff', function (assert) {\n        var m1 = moment('2012-01-15T00:00:00.000Z'),\n            m2 = moment('2012-02-17T00:00:00.000Z'),\n            d = moment.duration({from: m1, to: m2});\n\n        assert.equal(d.get('days'), 2);\n        assert.equal(d.get('months'), 1);\n    });\n\n    test('day diff, separate months', function (assert) {\n        var m1 = moment('2012-01-15T00:00:00.000Z'),\n            m2 = moment('2012-02-13T00:00:00.000Z'),\n            d = moment.duration({from: m1, to: m2});\n\n        assert.equal(d.as('days'), 29);\n    });\n\n    test('hour diff', function (assert) {\n        var m1 = moment('2012-01-15T17:00:00.000Z'),\n            m2 = moment('2012-01-16T03:00:00.000Z'),\n            d = moment.duration({from: m1, to: m2});\n\n        assert.equal(d.as('hours'), 10);\n    });\n\n    test('minute diff', function (assert) {\n        var m1 = moment('2012-01-15T17:45:00.000Z'),\n            m2 = moment('2012-01-16T03:15:00.000Z'),\n            d = moment.duration({from: m1, to: m2});\n\n        assert.equal(d.as('hours'), 9.5);\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('format');\n\n    test('format YY', function (assert) {\n        var b = moment(new Date(2009, 1, 14, 15, 25, 50, 125));\n        assert.equal(b.format('YY'), '09', 'YY ---> 09');\n    });\n\n    test('format escape brackets', function (assert) {\n        moment.locale('en');\n\n        var b = moment(new Date(2009, 1, 14, 15, 25, 50, 125));\n        assert.equal(b.format('[day]'), 'day', 'Single bracket');\n        assert.equal(b.format('[day] YY [YY]'), 'day 09 YY', 'Double bracket');\n        assert.equal(b.format('[YY'), '[09', 'Un-ended bracket');\n        assert.equal(b.format('[[YY]]'), '[YY]', 'Double nested brackets');\n        assert.equal(b.format('[[]'), '[', 'Escape open bracket');\n        assert.equal(b.format('[Last]'), 'Last', 'localized tokens');\n        assert.equal(b.format('[L] L'), 'L 02/14/2009', 'localized tokens with escaped localized tokens');\n        assert.equal(b.format('[L LL LLL LLLL aLa]'), 'L LL LLL LLLL aLa', 'localized tokens with escaped localized tokens');\n        assert.equal(b.format('[LLL] LLL'), 'LLL February 14, 2009 3:25 PM', 'localized tokens with escaped localized tokens (recursion)');\n        assert.equal(b.format('YYYY[\\n]DD[\\n]'), '2009\\n14\\n', 'Newlines');\n    });\n\n    test('handle negative years', function (assert) {\n        moment.locale('en');\n        assert.equal(moment.utc().year(-1).format('YY'), '-01', 'YY with negative year');\n        assert.equal(moment.utc().year(-1).format('YYYY'), '-0001', 'YYYY with negative year');\n        assert.equal(moment.utc().year(-12).format('YY'), '-12', 'YY with negative year');\n        assert.equal(moment.utc().year(-12).format('YYYY'), '-0012', 'YYYY with negative year');\n        assert.equal(moment.utc().year(-123).format('YY'), '-23', 'YY with negative year');\n        assert.equal(moment.utc().year(-123).format('YYYY'), '-0123', 'YYYY with negative year');\n        assert.equal(moment.utc().year(-1234).format('YY'), '-34', 'YY with negative year');\n        assert.equal(moment.utc().year(-1234).format('YYYY'), '-1234', 'YYYY with negative year');\n        assert.equal(moment.utc().year(-12345).format('YY'), '-45', 'YY with negative year');\n        assert.equal(moment.utc().year(-12345).format('YYYY'), '-12345', 'YYYY with negative year');\n    });\n\n    test('format milliseconds', function (assert) {\n        var b = moment(new Date(2009, 1, 14, 15, 25, 50, 123));\n        assert.equal(b.format('S'), '1', 'Deciseconds');\n        assert.equal(b.format('SS'), '12', 'Centiseconds');\n        assert.equal(b.format('SSS'), '123', 'Milliseconds');\n        b.milliseconds(789);\n        assert.equal(b.format('S'), '7', 'Deciseconds');\n        assert.equal(b.format('SS'), '78', 'Centiseconds');\n        assert.equal(b.format('SSS'), '789', 'Milliseconds');\n    });\n\n    test('format timezone', function (assert) {\n        var b = moment(new Date(2010, 1, 14, 15, 25, 50, 125));\n        assert.ok(b.format('Z').match(/^[\\+\\-]\\d\\d:\\d\\d$/), b.format('Z') + ' should be something like \\'+07:30\\'');\n        assert.ok(b.format('ZZ').match(/^[\\+\\-]\\d{4}$/), b.format('ZZ') + ' should be something like \\'+0700\\'');\n    });\n\n    test('format multiple with utc offset', function (assert) {\n        var b = moment('2012-10-08 -1200', ['YYYY-MM-DD HH:mm ZZ', 'YYYY-MM-DD ZZ', 'YYYY-MM-DD']);\n        assert.equal(b.format('YYYY-MM'), '2012-10', 'Parsing multiple formats should not crash with different sized formats');\n    });\n\n    test('isDST', function (assert) {\n        var janOffset = new Date(2011, 0, 1).getTimezoneOffset(),\n            julOffset = new Date(2011, 6, 1).getTimezoneOffset(),\n            janIsDst = janOffset < julOffset,\n            julIsDst = julOffset < janOffset,\n            jan1 = moment([2011]),\n            jul1 = moment([2011, 6]);\n\n        if (janIsDst && julIsDst) {\n            assert.ok(0, 'January and July cannot both be in DST');\n            assert.ok(0, 'January and July cannot both be in DST');\n        } else if (janIsDst) {\n            assert.ok(jan1.isDST(), 'January 1 is DST');\n            assert.ok(!jul1.isDST(), 'July 1 is not DST');\n        } else if (julIsDst) {\n            assert.ok(!jan1.isDST(), 'January 1 is not DST');\n            assert.ok(jul1.isDST(), 'July 1 is DST');\n        } else {\n            assert.ok(!jan1.isDST(), 'January 1 is not DST');\n            assert.ok(!jul1.isDST(), 'July 1 is not DST');\n        }\n    });\n\n    test('unix timestamp', function (assert) {\n        var m = moment('1234567890.123', 'X');\n        assert.equal(m.format('X'), '1234567890', 'unix timestamp without milliseconds');\n        assert.equal(m.format('X.S'), '1234567890.1', 'unix timestamp with deciseconds');\n        assert.equal(m.format('X.SS'), '1234567890.12', 'unix timestamp with centiseconds');\n        assert.equal(m.format('X.SSS'), '1234567890.123', 'unix timestamp with milliseconds');\n\n        m = moment(1234567890.123, 'X');\n        assert.equal(m.format('X'), '1234567890', 'unix timestamp as integer');\n    });\n\n    test('unix offset milliseconds', function (assert) {\n        var m = moment('1234567890123', 'x');\n        assert.equal(m.format('x'), '1234567890123', 'unix offset in milliseconds');\n\n        m = moment(1234567890123, 'x');\n        assert.equal(m.format('x'), '1234567890123', 'unix offset in milliseconds as integer');\n    });\n\n    test('utcOffset sanity checks', function (assert) {\n        assert.equal(moment().utcOffset() % 15, 0,\n                'utc offset should be a multiple of 15 (was ' + moment().utcOffset() + ')');\n\n        assert.equal(moment().utcOffset(), -(new Date()).getTimezoneOffset(),\n            'utcOffset should return the opposite of getTimezoneOffset');\n    });\n\n    test('default format', function (assert) {\n        var isoRegex = /\\d{4}.\\d\\d.\\d\\dT\\d\\d.\\d\\d.\\d\\d[\\+\\-]\\d\\d:\\d\\d/;\n        assert.ok(isoRegex.exec(moment().format()), 'default format (' + moment().format() + ') should match ISO');\n    });\n\n    test('toJSON', function (assert) {\n        var supportsJson = typeof JSON !== 'undefined' && JSON.stringify && JSON.stringify.call,\n            date = moment('2012-10-09T21:30:40.678+0100');\n\n        assert.equal(date.toJSON(), '2012-10-09T20:30:40.678Z', 'should output ISO8601 on moment.fn.toJSON');\n\n        if (supportsJson) {\n            assert.equal(JSON.stringify({\n                date : date\n            }), '{\"date\":\"2012-10-09T20:30:40.678Z\"}', 'should output ISO8601 on JSON.stringify');\n        }\n    });\n\n    test('toISOString', function (assert) {\n        var date = moment.utc('2012-10-09T20:30:40.678');\n\n        assert.equal(date.toISOString(), '2012-10-09T20:30:40.678Z', 'should output ISO8601 on moment.fn.toISOString');\n        date = moment.utc('+020123-10-09T20:30:40.678');\n        assert.equal(date.toISOString(), '+020123-10-09T20:30:40.678Z', 'ISO8601 format on big positive year');\n        date = moment.utc('-000001-10-09T20:30:40.678');\n        assert.equal(date.toISOString(), '-000001-10-09T20:30:40.678Z', 'ISO8601 format on negative year');\n        date = moment.utc('-020123-10-09T20:30:40.678');\n        assert.equal(date.toISOString(), '-020123-10-09T20:30:40.678Z', 'ISO8601 format on big negative year');\n    });\n\n    test('long years', function (assert) {\n        assert.equal(moment.utc().year(2).format('YYYYYY'), '+000002', 'small year with YYYYYY');\n        assert.equal(moment.utc().year(2012).format('YYYYYY'), '+002012', 'regular year with YYYYYY');\n        assert.equal(moment.utc().year(20123).format('YYYYYY'), '+020123', 'big year with YYYYYY');\n\n        assert.equal(moment.utc().year(-1).format('YYYYYY'), '-000001', 'small negative year with YYYYYY');\n        assert.equal(moment.utc().year(-2012).format('YYYYYY'), '-002012', 'negative year with YYYYYY');\n        assert.equal(moment.utc().year(-20123).format('YYYYYY'), '-020123', 'big negative year with YYYYYY');\n    });\n\n    test('iso week formats', function (assert) {\n        var cases = {\n            '2005-01-02': '2004-53',\n            '2005-12-31': '2005-52',\n            '2007-01-01': '2007-01',\n            '2007-12-30': '2007-52',\n            '2007-12-31': '2008-01',\n            '2008-01-01': '2008-01',\n            '2008-12-28': '2008-52',\n            '2008-12-29': '2009-01',\n            '2008-12-30': '2009-01',\n            '2008-12-31': '2009-01',\n            '2009-01-01': '2009-01',\n            '2009-12-31': '2009-53',\n            '2010-01-01': '2009-53',\n            '2010-01-02': '2009-53',\n            '2010-01-03': '2009-53',\n            '404-12-31': '0404-53',\n            '405-12-31': '0405-52'\n        }, i, isoWeek, formatted2, formatted1;\n\n        for (i in cases) {\n            isoWeek = cases[i].split('-').pop();\n            formatted2 = moment(i, 'YYYY-MM-DD').format('WW');\n            assert.equal(isoWeek, formatted2, i + ': WW should be ' + isoWeek + ', but ' + formatted2);\n            isoWeek = isoWeek.replace(/^0+/, '');\n            formatted1 = moment(i, 'YYYY-MM-DD').format('W');\n            assert.equal(isoWeek, formatted1, i + ': W should be ' + isoWeek + ', but ' + formatted1);\n        }\n    });\n\n    test('iso week year formats', function (assert) {\n        var cases = {\n            '2005-01-02': '2004-53',\n            '2005-12-31': '2005-52',\n            '2007-01-01': '2007-01',\n            '2007-12-30': '2007-52',\n            '2007-12-31': '2008-01',\n            '2008-01-01': '2008-01',\n            '2008-12-28': '2008-52',\n            '2008-12-29': '2009-01',\n            '2008-12-30': '2009-01',\n            '2008-12-31': '2009-01',\n            '2009-01-01': '2009-01',\n            '2009-12-31': '2009-53',\n            '2010-01-01': '2009-53',\n            '2010-01-02': '2009-53',\n            '2010-01-03': '2009-53',\n            '404-12-31': '0404-53',\n            '405-12-31': '0405-52'\n        }, i, isoWeekYear, formatted5, formatted4, formatted2;\n\n        for (i in cases) {\n            isoWeekYear = cases[i].split('-')[0];\n            formatted5 = moment(i, 'YYYY-MM-DD').format('GGGGG');\n            assert.equal('0' + isoWeekYear, formatted5, i + ': GGGGG should be ' + isoWeekYear + ', but ' + formatted5);\n            formatted4 = moment(i, 'YYYY-MM-DD').format('GGGG');\n            assert.equal(isoWeekYear, formatted4, i + ': GGGG should be ' + isoWeekYear + ', but ' + formatted4);\n            formatted2 = moment(i, 'YYYY-MM-DD').format('GG');\n            assert.equal(isoWeekYear.slice(2, 4), formatted2, i + ': GG should be ' + isoWeekYear + ', but ' + formatted2);\n        }\n    });\n\n    test('week year formats', function (assert) {\n        var cases = {\n            '2005-01-02': '2004-53',\n            '2005-12-31': '2005-52',\n            '2007-01-01': '2007-01',\n            '2007-12-30': '2007-52',\n            '2007-12-31': '2008-01',\n            '2008-01-01': '2008-01',\n            '2008-12-28': '2008-52',\n            '2008-12-29': '2009-01',\n            '2008-12-30': '2009-01',\n            '2008-12-31': '2009-01',\n            '2009-01-01': '2009-01',\n            '2009-12-31': '2009-53',\n            '2010-01-01': '2009-53',\n            '2010-01-02': '2009-53',\n            '2010-01-03': '2009-53',\n            '404-12-31': '0404-53',\n            '405-12-31': '0405-52'\n        }, i, isoWeekYear, formatted5, formatted4, formatted2;\n\n        moment.locale('dow:1,doy:4', {week: {dow: 1, doy: 4}});\n\n        for (i in cases) {\n            isoWeekYear = cases[i].split('-')[0];\n            formatted5 = moment(i, 'YYYY-MM-DD').format('ggggg');\n            assert.equal('0' + isoWeekYear, formatted5, i + ': ggggg should be ' + isoWeekYear + ', but ' + formatted5);\n            formatted4 = moment(i, 'YYYY-MM-DD').format('gggg');\n            assert.equal(isoWeekYear, formatted4, i + ': gggg should be ' + isoWeekYear + ', but ' + formatted4);\n            formatted2 = moment(i, 'YYYY-MM-DD').format('gg');\n            assert.equal(isoWeekYear.slice(2, 4), formatted2, i + ': gg should be ' + isoWeekYear + ', but ' + formatted2);\n        }\n    });\n\n    test('iso weekday formats', function (assert) {\n        assert.equal(moment([1985, 1,  4]).format('E'), '1', 'Feb  4 1985 is Monday    -- 1st day');\n        assert.equal(moment([2029, 8, 18]).format('E'), '2', 'Sep 18 2029 is Tuesday   -- 2nd day');\n        assert.equal(moment([2013, 3, 24]).format('E'), '3', 'Apr 24 2013 is Wednesday -- 3rd day');\n        assert.equal(moment([2015, 2,  5]).format('E'), '4', 'Mar  5 2015 is Thursday  -- 4th day');\n        assert.equal(moment([1970, 0,  2]).format('E'), '5', 'Jan  2 1970 is Friday    -- 5th day');\n        assert.equal(moment([2001, 4, 12]).format('E'), '6', 'May 12 2001 is Saturday  -- 6th day');\n        assert.equal(moment([2000, 0,  2]).format('E'), '7', 'Jan  2 2000 is Sunday    -- 7th day');\n    });\n\n    test('weekday formats', function (assert) {\n        moment.locale('dow: 3,doy: 5', {week: {dow: 3, doy: 5}});\n        assert.equal(moment([1985, 1,  6]).format('e'), '0', 'Feb  6 1985 is Wednesday -- 0th day');\n        assert.equal(moment([2029, 8, 20]).format('e'), '1', 'Sep 20 2029 is Thursday  -- 1st day');\n        assert.equal(moment([2013, 3, 26]).format('e'), '2', 'Apr 26 2013 is Friday    -- 2nd day');\n        assert.equal(moment([2015, 2,  7]).format('e'), '3', 'Mar  7 2015 is Saturday  -- 3nd day');\n        assert.equal(moment([1970, 0,  4]).format('e'), '4', 'Jan  4 1970 is Sunday    -- 4th day');\n        assert.equal(moment([2001, 4, 14]).format('e'), '5', 'May 14 2001 is Monday    -- 5th day');\n        assert.equal(moment([2000, 0,  4]).format('e'), '6', 'Jan  4 2000 is Tuesday   -- 6th day');\n    });\n\n    test('toString is just human readable format', function (assert) {\n        var b = moment(new Date(2009, 1, 5, 15, 25, 50, 125));\n        assert.equal(b.toString(), b.format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ'));\n    });\n\n    test('toJSON skips postformat', function (assert) {\n        moment.locale('postformat', {\n            postformat: function (s) {\n                s.replace(/./g, 'X');\n            }\n        });\n        assert.equal(moment.utc([2000, 0, 1]).toJSON(), '2000-01-01T00:00:00.000Z', 'toJSON doesn\\'t postformat');\n        moment.locale('postformat', null);\n    });\n\n    test('calendar day timezone', function (assert) {\n        moment.locale('en');\n        var zones = [60, -60, 90, -90, 360, -360, 720, -720],\n            b = moment().utc().startOf('day').subtract({m : 1}),\n            c = moment().local().startOf('day').subtract({m : 1}),\n            d = moment().local().startOf('day').subtract({d : 2}),\n            i, z, a;\n\n        for (i = 0; i < zones.length; ++i) {\n            z = zones[i];\n            a = moment().utcOffset(z).startOf('day').subtract({m: 1});\n            assert.equal(moment(a).utcOffset(z).calendar(), 'Yesterday at 11:59 PM',\n                         'Yesterday at 11:59 PM, not Today, or the wrong time, tz = ' + z);\n        }\n\n        assert.equal(moment(b).utc().calendar(), 'Yesterday at 11:59 PM', 'Yesterday at 11:59 PM, not Today, or the wrong time');\n        assert.equal(moment(c).local().calendar(), 'Yesterday at 11:59 PM', 'Yesterday at 11:59 PM, not Today, or the wrong time');\n        assert.equal(moment(c).local().calendar(d), 'Tomorrow at 11:59 PM', 'Tomorrow at 11:59 PM, not Yesterday, or the wrong time');\n    });\n\n    test('invalid', function (assert) {\n        assert.equal(moment.invalid().format(), 'Invalid date');\n        assert.equal(moment.invalid().format('YYYY-MM-DD'), 'Invalid date');\n    });\n\n    test('quarter formats', function (assert) {\n        assert.equal(moment([1985, 1,  4]).format('Q'), '1', 'Feb  4 1985 is Q1');\n        assert.equal(moment([2029, 8, 18]).format('Q'), '3', 'Sep 18 2029 is Q3');\n        assert.equal(moment([2013, 3, 24]).format('Q'), '2', 'Apr 24 2013 is Q2');\n        assert.equal(moment([2015, 2,  5]).format('Q'), '1', 'Mar  5 2015 is Q1');\n        assert.equal(moment([1970, 0,  2]).format('Q'), '1', 'Jan  2 1970 is Q1');\n        assert.equal(moment([2001, 11, 12]).format('Q'), '4', 'Dec 12 2001 is Q4');\n        assert.equal(moment([2000, 0,  2]).format('[Q]Q-YYYY'), 'Q1-2000', 'Jan  2 2000 is Q1');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('getters and setters');\n\n    test('getters', function (assert) {\n        var a = moment([2011, 9, 12, 6, 7, 8, 9]);\n        assert.equal(a.year(), 2011, 'year');\n        assert.equal(a.month(), 9, 'month');\n        assert.equal(a.date(), 12, 'date');\n        assert.equal(a.day(), 3, 'day');\n        assert.equal(a.hours(), 6, 'hour');\n        assert.equal(a.minutes(), 7, 'minute');\n        assert.equal(a.seconds(), 8, 'second');\n        assert.equal(a.milliseconds(), 9, 'milliseconds');\n    });\n\n    test('getters programmatic', function (assert) {\n        var a = moment([2011, 9, 12, 6, 7, 8, 9]);\n        assert.equal(a.get('year'), 2011, 'year');\n        assert.equal(a.get('month'), 9, 'month');\n        assert.equal(a.get('date'), 12, 'date');\n        assert.equal(a.get('day'), 3, 'day');\n        assert.equal(a.get('hour'), 6, 'hour');\n        assert.equal(a.get('minute'), 7, 'minute');\n        assert.equal(a.get('second'), 8, 'second');\n        assert.equal(a.get('milliseconds'), 9, 'milliseconds');\n        assert.equal(a.get('weekday'), a.weekday(), 'weekday');\n        assert.equal(a.get('isoWeekday'), a.isoWeekday(), 'isoWeekday');\n        assert.equal(a.get('week'), a.week(), 'week');\n        assert.equal(a.get('isoWeek'), a.isoWeek(), 'isoWeek');\n        assert.equal(a.get('dayOfYear'), a.dayOfYear(), 'dayOfYear');\n    });\n\n    test('setters plural', function (assert) {\n        var a = moment();\n        a.years(2011);\n        a.months(9);\n        a.dates(12);\n        a.hours(6);\n        a.minutes(7);\n        a.seconds(8);\n        a.milliseconds(9);\n        assert.equal(a.years(), 2011, 'years');\n        assert.equal(a.months(), 9, 'months');\n        assert.equal(a.dates(), 12, 'dates');\n        assert.equal(a.days(), 3, 'days');\n        assert.equal(a.hours(), 6, 'hours');\n        assert.equal(a.minutes(), 7, 'minutes');\n        assert.equal(a.seconds(), 8, 'seconds');\n        assert.equal(a.milliseconds(), 9, 'milliseconds');\n    });\n\n    test('setters singular', function (assert) {\n        var a = moment();\n        a.year(2011);\n        a.month(9);\n        a.date(12);\n        a.hour(6);\n        a.minute(7);\n        a.second(8);\n        a.millisecond(9);\n        assert.equal(a.year(), 2011, 'year');\n        assert.equal(a.month(), 9, 'month');\n        assert.equal(a.date(), 12, 'date');\n        assert.equal(a.day(), 3, 'day');\n        assert.equal(a.hour(), 6, 'hour');\n        assert.equal(a.minute(), 7, 'minute');\n        assert.equal(a.second(), 8, 'second');\n        assert.equal(a.millisecond(), 9, 'milliseconds');\n    });\n\n    test('setters', function (assert) {\n        var a = moment();\n        a.year(2011);\n        a.month(9);\n        a.date(12);\n        a.hours(6);\n        a.minutes(7);\n        a.seconds(8);\n        a.milliseconds(9);\n        assert.equal(a.year(), 2011, 'year');\n        assert.equal(a.month(), 9, 'month');\n        assert.equal(a.date(), 12, 'date');\n        assert.equal(a.day(), 3, 'day');\n        assert.equal(a.hours(), 6, 'hour');\n        assert.equal(a.minutes(), 7, 'minute');\n        assert.equal(a.seconds(), 8, 'second');\n        assert.equal(a.milliseconds(), 9, 'milliseconds');\n        a = moment('20130531', 'YYYYMMDD');\n        a.month(3);\n        assert.equal(a.month(), 3, 'month edge case');\n    });\n\n    test('setter programmatic', function (assert) {\n        var a = moment();\n        a.set('year', 2011);\n        a.set('month', 9);\n        a.set('date', 12);\n        a.set('hours', 6);\n        a.set('minutes', 7);\n        a.set('seconds', 8);\n        a.set('milliseconds', 9);\n        assert.equal(a.year(), 2011, 'year');\n        assert.equal(a.month(), 9, 'month');\n        assert.equal(a.date(), 12, 'date');\n        assert.equal(a.day(), 3, 'day');\n        assert.equal(a.hours(), 6, 'hour');\n        assert.equal(a.minutes(), 7, 'minute');\n        assert.equal(a.seconds(), 8, 'second');\n        assert.equal(a.milliseconds(), 9, 'milliseconds');\n        a = moment('20130531', 'YYYYMMDD');\n        a.month(3);\n        assert.equal(a.month(), 3, 'month edge case');\n    });\n\n    test('setters strings', function (assert) {\n        var a = moment([2012]).locale('en');\n        assert.equal(a.clone().day(0).day('Wednesday').day(), 3, 'day full name');\n        assert.equal(a.clone().day(0).day('Wed').day(), 3, 'day short name');\n        assert.equal(a.clone().day(0).day('We').day(), 3, 'day minimal name');\n        assert.equal(a.clone().day(0).day('invalid').day(), 0, 'invalid day name');\n        assert.equal(a.clone().month(0).month('April').month(), 3, 'month full name');\n        assert.equal(a.clone().month(0).month('Apr').month(), 3, 'month short name');\n        assert.equal(a.clone().month(0).month('invalid').month(), 0, 'invalid month name');\n    });\n\n    test('setters - falsey values', function (assert) {\n        var a = moment();\n        a.minutes(1);\n        a.minutes(0);\n        assert.equal(a.minutes(), 0, 'falsey value');\n    });\n\n    test('chaining setters', function (assert) {\n        var a = moment();\n        a.year(2011)\n         .month(9)\n         .date(12)\n         .hours(6)\n         .minutes(7)\n         .seconds(8);\n        assert.equal(a.year(), 2011, 'year');\n        assert.equal(a.month(), 9, 'month');\n        assert.equal(a.date(), 12, 'date');\n        assert.equal(a.day(), 3, 'day');\n        assert.equal(a.hours(), 6, 'hour');\n        assert.equal(a.minutes(), 7, 'minute');\n        assert.equal(a.seconds(), 8, 'second');\n    });\n\n    test('setter with multiple unit values', function (assert) {\n        var a = moment();\n        a.set({\n            year: 2011,\n            month: 9,\n            date: 12,\n            hours: 6,\n            minutes: 7,\n            seconds: 8,\n            milliseconds: 9\n        });\n        assert.equal(a.year(), 2011, 'year');\n        assert.equal(a.month(), 9, 'month');\n        assert.equal(a.date(), 12, 'date');\n        assert.equal(a.day(), 3, 'day');\n        assert.equal(a.hours(), 6, 'hour');\n        assert.equal(a.minutes(), 7, 'minute');\n        assert.equal(a.seconds(), 8, 'second');\n        assert.equal(a.milliseconds(), 9, 'milliseconds');\n    });\n\n    test('day setter', function (assert) {\n        var a = moment([2011, 0, 15]);\n        assert.equal(moment(a).day(0).date(), 9, 'set from saturday to sunday');\n        assert.equal(moment(a).day(6).date(), 15, 'set from saturday to saturday');\n        assert.equal(moment(a).day(3).date(), 12, 'set from saturday to wednesday');\n\n        a = moment([2011, 0, 9]);\n        assert.equal(moment(a).day(0).date(), 9, 'set from sunday to sunday');\n        assert.equal(moment(a).day(6).date(), 15, 'set from sunday to saturday');\n        assert.equal(moment(a).day(3).date(), 12, 'set from sunday to wednesday');\n\n        a = moment([2011, 0, 12]);\n        assert.equal(moment(a).day(0).date(), 9, 'set from wednesday to sunday');\n        assert.equal(moment(a).day(6).date(), 15, 'set from wednesday to saturday');\n        assert.equal(moment(a).day(3).date(), 12, 'set from wednesday to wednesday');\n\n        assert.equal(moment(a).day(-7).date(), 2, 'set from wednesday to last sunday');\n        assert.equal(moment(a).day(-1).date(), 8, 'set from wednesday to last saturday');\n        assert.equal(moment(a).day(-4).date(), 5, 'set from wednesday to last wednesday');\n\n        assert.equal(moment(a).day(7).date(), 16, 'set from wednesday to next sunday');\n        assert.equal(moment(a).day(13).date(), 22, 'set from wednesday to next saturday');\n        assert.equal(moment(a).day(10).date(), 19, 'set from wednesday to next wednesday');\n\n        assert.equal(moment(a).day(14).date(), 23, 'set from wednesday to second next sunday');\n        assert.equal(moment(a).day(20).date(), 29, 'set from wednesday to second next saturday');\n        assert.equal(moment(a).day(17).date(), 26, 'set from wednesday to second next wednesday');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('invalid');\n\n    test('invalid', function (assert) {\n        var m = moment.invalid();\n        assert.equal(m.isValid(), false);\n        assert.equal(m.parsingFlags().userInvalidated, true);\n        assert.ok(isNaN(m.valueOf()));\n    });\n\n    test('invalid with existing flag', function (assert) {\n        var m = moment.invalid({invalidMonth : 'whatchamacallit'});\n        assert.equal(m.isValid(), false);\n        assert.equal(m.parsingFlags().userInvalidated, false);\n        assert.equal(m.parsingFlags().invalidMonth, 'whatchamacallit');\n        assert.ok(isNaN(m.valueOf()));\n    });\n\n    test('invalid with custom flag', function (assert) {\n        var m = moment.invalid({tooBusyWith : 'reiculating splines'});\n        assert.equal(m.isValid(), false);\n        assert.equal(m.parsingFlags().userInvalidated, false);\n        assert.equal(m.parsingFlags().tooBusyWith, 'reiculating splines');\n        assert.ok(isNaN(m.valueOf()));\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('is after');\n\n    test('is after without units', function (assert) {\n        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n        assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), false, 'year is later');\n        assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), true, 'year is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), false, 'month is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), true, 'month is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), false, 'day is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), true, 'day is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), false, 'hour is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), true, 'hour is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), false, 'minute is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), true, 'minute is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), false, 'second is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), true, 'second is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'millisecond match');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), false, 'millisecond is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), true, 'millisecond is earlier');\n        assert.equal(m.isAfter(m), false, 'moments are not after themselves');\n        assert.equal(+m, +mCopy, 'isAfter second should not change moment');\n    });\n\n    test('is after year', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year match');\n        assert.equal(m.isAfter(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n        assert.equal(m.isAfter(moment(new Date(2013, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is later');\n        assert.equal(m.isAfter(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), false, 'exact start of year');\n        assert.equal(m.isAfter(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), false, 'exact end of year');\n        assert.equal(m.isAfter(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), false, 'start of next year');\n        assert.equal(m.isAfter(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), true, 'end of previous year');\n        assert.equal(m.isAfter(moment(new Date(1980, 11, 31, 23, 59, 59, 999)), 'year'), true, 'end of year far before');\n        assert.equal(m.isAfter(m, 'year'), false, 'same moments are not after the same year');\n        assert.equal(+m, +mCopy, 'isAfter year should not change moment');\n    });\n\n    test('is after month', function (assert) {\n        var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n        assert.equal(m.isAfter(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), false, 'month match');\n        assert.equal(m.isAfter(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n        assert.equal(m.isAfter(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year is later');\n        assert.equal(m.isAfter(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'), true, 'year is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), false, 'month is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), true, 'month is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), false, 'exact start of month');\n        assert.equal(m.isAfter(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), false, 'exact end of month');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), false, 'start of next month');\n        assert.equal(m.isAfter(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), true, 'end of previous month');\n        assert.equal(m.isAfter(moment(new Date(2010, 12, 31, 23, 59, 59, 999)), 'month'), true, 'later month but earlier year');\n        assert.equal(m.isAfter(m, 'month'), false, 'same moments are not after the same month');\n        assert.equal(+m, +mCopy, 'isAfter month should not change moment');\n    });\n\n    test('is after day', function (assert) {\n        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 7, 8, 9, 10)), 'day'), false, 'day match');\n        assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n        assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 7, 8, 9, 10)), 'day'), false, 'year is later');\n        assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 7, 8, 9, 10)), 'day'), true, 'year is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 7, 8, 9, 10)), 'day'), false, 'month is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), true, 'month is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 7, 8, 9, 10)), 'day'), false, 'day is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 7, 8, 9, 10)), 'day'), true, 'day is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 0, 0, 0, 0)), 'day'), false, 'exact start of day');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 23, 59, 59, 999)), 'day'), false, 'exact end of day');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 0, 0, 0, 0)), 'day'), false, 'start of next day');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 23, 59, 59, 999)), 'day'), true, 'end of previous day');\n        assert.equal(m.isAfter(moment(new Date(2010, 3, 10, 0, 0, 0, 0)), 'day'), true, 'later day but earlier year');\n        assert.equal(m.isAfter(m, 'day'), false, 'same moments are not after the same day');\n        assert.equal(+m, +mCopy, 'isAfter day should not change moment');\n    });\n\n    test('is after hour', function (assert) {\n        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour match');\n        assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n        assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'year is later');\n        assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 8, 9, 10)), 'hour'), true, 'year is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 8, 9, 10)), 'hour'), false, 'month is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'month is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 8, 9, 10)), 'hour'), false, 'day is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 3, 8, 9, 10)), 'hour'), true, 'day is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 8, 9, 10)), 'hour'), false, 'hour is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 0, 0, 0)), 'hour'), false, 'exact start of hour');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 59, 59, 999)), 'hour'), false, 'exact end of hour');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 0, 0, 0)), 'hour'), false, 'start of next hour');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 2, 59, 59, 999)), 'hour'), true, 'end of previous hour');\n        assert.equal(m.isAfter(m, 'hour'), false, 'same moments are not after the same hour');\n        assert.equal(+m, +mCopy, 'isAfter hour should not change moment');\n    });\n\n    test('is after minute', function (assert) {\n        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'minute match');\n        assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n        assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'year is later');\n        assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 9, 10)), 'minute'), true, 'year is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 9, 10)), 'minute'), false, 'month is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), true, 'month is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 9, 10)), 'minute'), false, 'day is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 3, 4, 9, 10)), 'minute'), true, 'day is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 9, 10)), 'minute'), false, 'hour is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 2, 4, 9, 10)), 'minute'), true, 'hour is earler');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 9, 10)), 'minute'), false, 'minute is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 9, 10)), 'minute'), true, 'minute is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 0, 0)), 'minute'), false, 'exact start of minute');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 59, 999)), 'minute'), false, 'exact end of minute');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 0, 0)), 'minute'), false, 'start of next minute');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 59, 999)), 'minute'), true, 'end of previous minute');\n        assert.equal(m.isAfter(m, 'minute'), false, 'same moments are not after the same minute');\n        assert.equal(+m, +mCopy, 'isAfter minute should not change moment');\n    });\n\n    test('is after second', function (assert) {\n        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'second'), false, 'second match');\n        assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n        assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'second'), false, 'year is later');\n        assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'second'), true, 'year is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'second'), false, 'month is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), true, 'month is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'second'), false, 'day is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'second'), true, 'day is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'second'), false, 'hour is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'second'), true, 'hour is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'second'), false, 'minute is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'second'), true, 'minute is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'second'), false, 'second is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'second'), true, 'second is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 0)), 'second'), false, 'exact start of second');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 999)), 'second'), false, 'exact end of second');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 0)), 'second'), false, 'start of next second');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 999)), 'second'), true, 'end of previous second');\n        assert.equal(m.isAfter(m, 'second'), false, 'same moments are not after the same second');\n        assert.equal(+m, +mCopy, 'isAfter second should not change moment');\n    });\n\n    test('is after millisecond', function (assert) {\n        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'millisecond match');\n        assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'plural should work');\n        assert.equal(m.isAfter(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is later');\n        assert.equal(m.isAfter(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'year is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), true, 'month is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), false, 'day is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), true, 'day is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), false, 'hour is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), true, 'hour is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), false, 'minute is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), true, 'minute is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), false, 'second is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), true, 'second is earlier');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), false, 'millisecond is later');\n        assert.equal(m.isAfter(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), true, 'millisecond is earlier');\n        assert.equal(m.isAfter(m, 'millisecond'), false, 'same moments are not after the same millisecond');\n        assert.equal(+m, +mCopy, 'isAfter millisecond should not change moment');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('is before');\n\n    test('is after without units', function (assert) {\n        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n        assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), true, 'year is later');\n        assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), false, 'year is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), true, 'month is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), false, 'month is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), true, 'day is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), false, 'day is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), true, 'hour is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), false, 'hour is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), true, 'minute is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), false, 'minute is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), true, 'second is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), false, 'second is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'millisecond match');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), true, 'millisecond is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), false, 'millisecond is earlier');\n        assert.equal(m.isBefore(m), false, 'moments are not before themselves');\n        assert.equal(+m, +mCopy, 'isBefore second should not change moment');\n    });\n\n    test('is before year', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year match');\n        assert.equal(m.isBefore(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n        assert.equal(m.isBefore(moment(new Date(2013, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is later');\n        assert.equal(m.isBefore(moment(new Date(2010, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), false, 'exact start of year');\n        assert.equal(m.isBefore(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), false, 'exact end of year');\n        assert.equal(m.isBefore(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), true, 'start of next year');\n        assert.equal(m.isBefore(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), false, 'end of previous year');\n        assert.equal(m.isBefore(moment(new Date(1980, 11, 31, 23, 59, 59, 999)), 'year'), false, 'end of year far before');\n        assert.equal(m.isBefore(m, 'year'), false, 'same moments are not before the same year');\n        assert.equal(+m, +mCopy, 'isBefore year should not change moment');\n    });\n\n    test('is before month', function (assert) {\n        var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n        assert.equal(m.isBefore(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), false, 'month match');\n        assert.equal(m.isBefore(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n        assert.equal(m.isBefore(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), true, 'year is later');\n        assert.equal(m.isBefore(moment(new Date(2010, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), true, 'month is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), false, 'month is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), false, 'exact start of month');\n        assert.equal(m.isBefore(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), false, 'exact end of month');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), true, 'start of next month');\n        assert.equal(m.isBefore(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), false, 'end of previous month');\n        assert.equal(m.isBefore(moment(new Date(2010, 12, 31, 23, 59, 59, 999)), 'month'), false, 'later month but earlier year');\n        assert.equal(m.isBefore(m, 'month'), false, 'same moments are not before the same month');\n        assert.equal(+m, +mCopy, 'isBefore month should not change moment');\n    });\n\n    test('is before day', function (assert) {\n        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 7, 8, 9, 10)), 'day'), false, 'day match');\n        assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n        assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 7, 8, 9, 10)), 'day'), true, 'year is later');\n        assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 7, 8, 9, 10)), 'day'), false, 'year is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 7, 8, 9, 10)), 'day'), true, 'month is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), false, 'month is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 7, 8, 9, 10)), 'day'), true, 'day is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 7, 8, 9, 10)), 'day'), false, 'day is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 0, 0, 0, 0)), 'day'), false, 'exact start of day');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 23, 59, 59, 999)), 'day'), false, 'exact end of day');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 0, 0, 0, 0)), 'day'), true, 'start of next day');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 23, 59, 59, 999)), 'day'), false, 'end of previous day');\n        assert.equal(m.isBefore(moment(new Date(2010, 3, 10, 0, 0, 0, 0)), 'day'), false, 'later day but earlier year');\n        assert.equal(m.isBefore(m, 'day'), false, 'same moments are not before the same day');\n        assert.equal(+m, +mCopy, 'isBefore day should not change moment');\n    });\n\n    test('is before hour', function (assert) {\n        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour match');\n        assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n        assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 8, 9, 10)), 'hour'), true, 'year is later');\n        assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'year is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 8, 9, 10)), 'hour'), true, 'month is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), false, 'month is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 8, 9, 10)), 'hour'), true, 'day is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 3, 8, 9, 10)), 'hour'), false, 'day is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 8, 9, 10)), 'hour'), true, 'hour is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 8, 9, 10)), 'hour'), false, 'hour is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 0, 0, 0)), 'hour'), false, 'exact start of hour');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 59, 59, 999)), 'hour'), false, 'exact end of hour');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 0, 0, 0)), 'hour'), true, 'start of next hour');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 2, 59, 59, 999)), 'hour'), false, 'end of previous hour');\n        assert.equal(m.isBefore(m, 'hour'), false, 'same moments are not before the same hour');\n        assert.equal(+m, +mCopy, 'isBefore hour should not change moment');\n    });\n\n    test('is before minute', function (assert) {\n        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'minute match');\n        assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n        assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 9, 10)), 'minute'), true, 'year is later');\n        assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 9, 10)), 'minute'), false, 'year is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 9, 10)), 'minute'), true, 'month is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), false, 'month is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 9, 10)), 'minute'), true, 'day is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 3, 4, 9, 10)), 'minute'), false, 'day is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 9, 10)), 'minute'), true, 'hour is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 2, 4, 9, 10)), 'minute'), false, 'hour is earler');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 9, 10)), 'minute'), true, 'minute is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 9, 10)), 'minute'), false, 'minute is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 0, 0)), 'minute'), false, 'exact start of minute');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 59, 999)), 'minute'), false, 'exact end of minute');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 0, 0)), 'minute'), true, 'start of next minute');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 59, 999)), 'minute'), false, 'end of previous minute');\n        assert.equal(m.isBefore(m, 'minute'), false, 'same moments are not before the same minute');\n        assert.equal(+m, +mCopy, 'isBefore minute should not change moment');\n    });\n\n    test('is before second', function (assert) {\n        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'second'), false, 'second match');\n        assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n        assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'second'), true, 'year is later');\n        assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'second'), false, 'year is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'second'), true, 'month is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), false, 'month is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'second'), true, 'day is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'second'), false, 'day is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'second'), true, 'hour is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'second'), false, 'hour is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'second'), true, 'minute is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'second'), false, 'minute is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'second'), true, 'second is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'second'), false, 'second is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 0)), 'second'), false, 'exact start of second');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 999)), 'second'), false, 'exact end of second');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 0)), 'second'), true, 'start of next second');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 999)), 'second'), false, 'end of previous second');\n        assert.equal(m.isBefore(m, 'second'), false, 'same moments are not before the same second');\n        assert.equal(+m, +mCopy, 'isBefore second should not change moment');\n    });\n\n    test('is before millisecond', function (assert) {\n        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'millisecond match');\n        assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'milliseconds'), false, 'plural should work');\n        assert.equal(m.isBefore(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'year is later');\n        assert.equal(m.isBefore(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), true, 'month is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), true, 'day is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), false, 'day is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), true, 'hour is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), false, 'hour is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), true, 'minute is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), false, 'minute is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), true, 'second is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), false, 'second is earlier');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), true, 'millisecond is later');\n        assert.equal(m.isBefore(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), false, 'millisecond is earlier');\n        assert.equal(m.isBefore(m, 'millisecond'), false, 'same moments are not before the same millisecond');\n        assert.equal(+m, +mCopy, 'isBefore millisecond should not change moment');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('is between');\n\n    test('is between without units', function (assert) {\n        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n        assert.equal(m.isBetween(\n                    moment(new Date(2009, 3, 2, 3, 4, 5, 10)),\n                    moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'year is later');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                    moment(new Date(2013, 3, 2, 3, 4, 5, 10))), false, 'year is earlier');\n        assert.equal(m.isBetween(\n                    moment(new Date(2010, 3, 2, 3, 4, 5, 10)),\n                    moment(new Date(2012, 3, 2, 3, 4, 5, 10))), true, 'year is between');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 3, 4, 5, 10)),\n                    moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'month is later');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                    moment(new Date(2011, 5, 2, 3, 4, 5, 10))), false, 'month is earlier');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 2, 2, 3, 4, 5, 10)),\n                    moment(new Date(2011, 4, 2, 3, 4, 5, 10))), true, 'month is between');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 3, 1, 3, 4, 5, 10)),\n                    moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'day is later');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                    moment(new Date(2011, 3, 4, 3, 4, 5, 10))), false, 'day is earlier');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 3, 1, 3, 4, 5, 10)),\n                    moment(new Date(2011, 3, 3, 3, 4, 5, 10))), true, 'day is between');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 3, 2, 1, 4, 5, 10)),\n                    moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'hour is later');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                    moment(new Date(2011, 3, 2, 5, 4, 5, 10))), false, 'hour is earlier');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 3, 2, 2, 4, 5, 10)),\n                    moment(new Date(2011, 3, 2, 4, 4, 5, 10))), true, 'hour is between');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                    moment(new Date(2011, 3, 2, 3, 6, 5, 10))), false, 'minute is later');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 3, 2, 3, 2, 5, 10)),\n                    moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'minute is earlier');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 3, 2, 3, 3, 5, 10)),\n                    moment(new Date(2011, 3, 2, 3, 5, 5, 10))), true, 'minute is between');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                    moment(new Date(2011, 3, 2, 3, 4, 7, 10))), false, 'second is later');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 3, 2, 3, 4, 3, 10)),\n                    moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'second is earlier');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 3, 2, 3, 4, 4, 10)),\n                    moment(new Date(2011, 3, 2, 3, 4, 6, 10))), true, 'second is between');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 3, 2, 3, 4, 5, 10)),\n                    moment(new Date(2011, 3, 2, 3, 4, 5, 12))), false, 'millisecond is later');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 3, 2, 3, 4, 5, 8)),\n                    moment(new Date(2011, 3, 2, 3, 4, 5, 10))), false, 'millisecond is earlier');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 3, 2, 3, 4, 5, 9)),\n                    moment(new Date(2011, 3, 2, 3, 4, 5, 11))), true, 'millisecond is between');\n        assert.equal(m.isBetween(m, m), false, 'moments are not between themselves');\n        assert.equal(+m, +mCopy, 'isBetween second should not change moment');\n    });\n\n    test('is between year', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 5, 6, 7, 8, 9, 10)),\n                    moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year match');\n        assert.equal(m.isBetween(\n                    moment(new Date(2010, 5, 6, 7, 8, 9, 10)),\n                    moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n        assert.equal(m.isBetween(\n                    moment(new Date(2010, 5, 6, 7, 8, 9, 10)),\n                    moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year is between');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 5, 6, 7, 8, 9, 10)),\n                    moment(new Date(2013, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is earlier');\n        assert.equal(m.isBetween(\n                    moment(new Date(2010, 5, 6, 7, 8, 9, 10)),\n                    moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year is later');\n        assert.equal(m.isBetween(m, 'year'), false, 'same moments are not between the same year');\n        assert.equal(+m, +mCopy, 'isBetween year should not change moment');\n    });\n\n    test('is between month', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 6, 7, 8, 9, 10)),\n                    moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), false, 'month match');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 0, 6, 7, 8, 9, 10)),\n                    moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 0, 31, 23, 59, 59, 999)),\n                    moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), true, 'month is between');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 6, 7, 8, 9, 10)),\n                    moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), false, 'month is earlier');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 11, 6, 7, 8, 9, 10)),\n                    moment(new Date(2011, 1, 6, 7, 8, 9, 10)), 'month'), false, 'month is later');\n        assert.equal(m.isBetween(m, 'month'), false, 'same moments are not between the same month');\n        assert.equal(+m, +mCopy, 'isBetween month should not change moment');\n    });\n\n    test('is between day', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                    moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), false, 'day match');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 1, 7, 8, 9, 10)),\n                    moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 1, 7, 8, 9, 10)),\n                    moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'), true, 'day is between');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                    moment(new Date(2011, 1, 4, 7, 8, 9, 10)), 'day'), false, 'day is earlier');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 1, 7, 8, 9, 10)),\n                    moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), false, 'day is later');\n        assert.equal(m.isBetween(m, 'day'), false, 'same moments are not between the same day');\n        assert.equal(+m, +mCopy, 'isBetween day should not change moment');\n    });\n\n    test('is between hour', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 3, 5, 9, 10)),\n                    moment(new Date(2011, 1, 2, 3, 9, 9, 10)), 'hour'), false, 'hour match');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 1, 59, 59, 999)),\n                    moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hours'), true, 'plural should work');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 2, 59, 59, 999)),\n                    moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'), true, 'hour is between');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                    moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'hour'), false, 'hour is earlier');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 7, 8, 9, 10)),\n                    moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'hour'), false, 'hour is later');\n        assert.equal(m.isBetween(m, 'hour'), false, 'same moments are not between the same hour');\n        assert.equal(+m, +mCopy, 'isBetween hour should not change moment');\n    });\n\n    test('is between minute', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 3, 4, 9, 10)),\n                    moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'), false, 'minute match');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 3, 3, 9, 10)),\n                    moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minutes'), true, 'plural should work');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 3, 3, 59, 999)),\n                    moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'), true, 'minute is between');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 3, 5, 0, 0)),\n                    moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'minute'), false, 'minute is earlier');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 3, 2, 9, 10)),\n                    moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'), false, 'minute is later');\n        assert.equal(m.isBetween(m, 'minute'), false, 'same moments are not between the same minute');\n        assert.equal(+m, +mCopy, 'isBetween minute should not change moment');\n    });\n\n    test('is between second', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 3, 4, 5, 10)),\n                    moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'), false, 'second match');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 3, 4, 4, 10)),\n                    moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'seconds'), true, 'plural should work');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 3, 4, 4, 999)),\n                    moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'), true, 'second is between');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 3, 4, 6, 0)),\n                    moment(new Date(2011, 1, 2, 3, 4, 7, 10)), 'second'), false, 'second is earlier');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 3, 4, 3, 10)),\n                    moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'), false, 'second is later');\n        assert.equal(m.isBetween(m, 'second'), false, 'same moments are not between the same second');\n        assert.equal(+m, +mCopy, 'isBetween second should not change moment');\n    });\n\n    test('is between millisecond', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 3, 4, 5, 6)),\n                    moment(new Date(2011, 1, 2, 3, 4, 5, 6)), 'millisecond'), false, 'millisecond match');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 3, 4, 5, 5)),\n                    moment(new Date(2011, 1, 2, 3, 4, 5, 7)), 'milliseconds'), true, 'plural should work');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 3, 4, 5, 5)),\n                    moment(new Date(2011, 1, 2, 3, 4, 5, 7)), 'millisecond'), true, 'millisecond is between');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 3, 4, 5, 7)),\n                    moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'millisecond'), false, 'millisecond is earlier');\n        assert.equal(m.isBetween(\n                    moment(new Date(2011, 1, 2, 3, 4, 5, 4)),\n                    moment(new Date(2011, 1, 2, 3, 4, 5, 6)), 'millisecond'), false, 'millisecond is later');\n        assert.equal(m.isBetween(m, 'millisecond'), false, 'same moments are not between the same millisecond');\n        assert.equal(+m, +mCopy, 'isBetween millisecond should not change moment');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('is date');\n\n    test('isDate recognizes Date objects', function (assert) {\n        assert.ok(moment.isDate(new Date()), 'no args (now)');\n        assert.ok(moment.isDate(new Date([2014, 2, 15])), 'array args');\n        assert.ok(moment.isDate(new Date('2014-03-15')), 'string args');\n        assert.ok(moment.isDate(new Date('does NOT look like a date')), 'invalid date');\n    });\n\n    test('isDate rejects non-Date objects', function (assert) {\n        assert.ok(!moment.isDate(), 'nothing');\n        assert.ok(!moment.isDate(undefined), 'undefined');\n        assert.ok(!moment.isDate(null), 'string args');\n        assert.ok(!moment.isDate(42), 'number');\n        assert.ok(!moment.isDate('2014-03-15'), 'string');\n        assert.ok(!moment.isDate([2014, 2, 15]), 'array');\n        assert.ok(!moment.isDate({year: 2014, month: 2, day: 15}), 'object');\n        assert.ok(!moment.isDate({toString: function () {\n            return '[object Date]';\n        }}), 'lying object');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('is moment');\n\n    test('is moment object', function (assert) {\n        var MyObj = function () {},\n            extend = function (a, b) {\n                var i;\n                for (i in b) {\n                    a[i] = b[i];\n                }\n                return a;\n            };\n        MyObj.prototype.toDate = function () {\n            return new Date();\n        };\n\n        assert.ok(moment.isMoment(moment()), 'simple moment object');\n        assert.ok(moment.isMoment(moment(null)), 'invalid moment object');\n        assert.ok(moment.isMoment(extend({}, moment())), 'externally cloned moments are moments');\n        assert.ok(moment.isMoment(extend({}, moment.utc())), 'externally cloned utc moments are moments');\n\n        assert.ok(!moment.isMoment(new MyObj()), 'myObj is not moment object');\n        assert.ok(!moment.isMoment(moment), 'moment function is not moment object');\n        assert.ok(!moment.isMoment(new Date()), 'date object is not moment object');\n        assert.ok(!moment.isMoment(Object), 'Object is not moment object');\n        assert.ok(!moment.isMoment('foo'), 'string is not moment object');\n        assert.ok(!moment.isMoment(1), 'number is not moment object');\n        assert.ok(!moment.isMoment(NaN), 'NaN is not moment object');\n        assert.ok(!moment.isMoment(null), 'null is not moment object');\n        assert.ok(!moment.isMoment(undefined), 'undefined is not moment object');\n    });\n\n    test('is moment with hacked hasOwnProperty', function (assert) {\n        var obj = {};\n        obj['hasOwnMoney'.replace('Money', 'Property')] = function () {\n            return true;\n        };\n\n        assert.ok(!moment.isMoment(obj), 'isMoment works even if passed object has a wrong hasOwnProperty implementation (ie8)');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('is same');\n\n    test('is same without units', function (assert) {\n        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n        assert.equal(m.isSame(moment(new Date(2012, 3, 2, 3, 5, 5, 10))), false, 'year is later');\n        assert.equal(m.isSame(moment(new Date(2010, 3, 2, 3, 3, 5, 10))), false, 'year is earlier');\n        assert.equal(m.isSame(moment(new Date(2011, 4, 2, 3, 4, 5, 10))), false, 'month is later');\n        assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 5, 10))), false, 'month is earlier');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 3, 3, 4, 5, 10))), false, 'day is later');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 1, 3, 4, 5, 10))), false, 'day is earlier');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 2, 4, 4, 5, 10))), false, 'hour is later');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 2, 2, 4, 5, 10))), false, 'hour is earlier');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 5, 5, 10))), false, 'minute is later');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 3, 5, 10))), false, 'minute is earlier');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 6, 10))), false, 'second is later');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 4, 11))), false, 'second is earlier');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 10))), true, 'millisecond match');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 11))), false, 'millisecond is later');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 9))), false, 'millisecond is earlier');\n        assert.equal(m.isSame(m), true, 'moments are the same as themselves');\n        assert.equal(+m, +mCopy, 'isSame second should not change moment');\n    });\n\n    test('is same year', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isSame(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'year'), true, 'year match');\n        assert.equal(m.isSame(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'years'), true, 'plural should work');\n        assert.equal(m.isSame(moment(new Date(2012, 5, 6, 7, 8, 9, 10)), 'year'), false, 'year mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 0, 1, 0, 0, 0, 0)), 'year'), true, 'exact start of year');\n        assert.equal(m.isSame(moment(new Date(2011, 11, 31, 23, 59, 59, 999)), 'year'), true, 'exact end of year');\n        assert.equal(m.isSame(moment(new Date(2012, 0, 1, 0, 0, 0, 0)), 'year'), false, 'start of next year');\n        assert.equal(m.isSame(moment(new Date(2010, 11, 31, 23, 59, 59, 999)), 'year'), false, 'end of previous year');\n        assert.equal(m.isSame(m, 'year'), true, 'same moments are in the same year');\n        assert.equal(+m, +mCopy, 'isSame year should not change moment');\n    });\n\n    test('is same month', function (assert) {\n        var m = moment(new Date(2011, 2, 3, 4, 5, 6, 7)), mCopy = moment(m);\n        assert.equal(m.isSame(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'month'), true, 'month match');\n        assert.equal(m.isSame(moment(new Date(2011, 2, 6, 7, 8, 9, 10)), 'months'), true, 'plural should work');\n        assert.equal(m.isSame(moment(new Date(2012, 2, 6, 7, 8, 9, 10)), 'month'), false, 'year mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 5, 6, 7, 8, 9, 10)), 'month'), false, 'month mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 2, 1, 0, 0, 0, 0)), 'month'), true, 'exact start of month');\n        assert.equal(m.isSame(moment(new Date(2011, 2, 31, 23, 59, 59, 999)), 'month'), true, 'exact end of month');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 1, 0, 0, 0, 0)), 'month'), false, 'start of next month');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 27, 23, 59, 59, 999)), 'month'), false, 'end of previous month');\n        assert.equal(m.isSame(m, 'month'), true, 'same moments are in the same month');\n        assert.equal(+m, +mCopy, 'isSame month should not change moment');\n    });\n\n    test('is same day', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'day'), true, 'day match');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 7, 8, 9, 10)), 'days'), true, 'plural should work');\n        assert.equal(m.isSame(moment(new Date(2012, 1, 2, 7, 8, 9, 10)), 'day'), false, 'year mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 2, 2, 7, 8, 9, 10)), 'day'), false, 'month mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 3, 7, 8, 9, 10)), 'day'), false, 'day mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 0, 0, 0, 0)), 'day'), true, 'exact start of day');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 23, 59, 59, 999)), 'day'), true, 'exact end of day');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 3, 0, 0, 0, 0)), 'day'), false, 'start of next day');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 1, 23, 59, 59, 999)), 'day'), false, 'end of previous day');\n        assert.equal(m.isSame(m, 'day'), true, 'same moments are in the same day');\n        assert.equal(+m, +mCopy, 'isSame day should not change moment');\n    });\n\n    test('is same hour', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hour'), true, 'hour match');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 8, 9, 10)), 'hours'), true, 'plural should work');\n        assert.equal(m.isSame(moment(new Date(2012, 1, 2, 3, 8, 9, 10)), 'hour'), false, 'year mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 8, 9, 10)), 'hour'), false, 'month mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 3, 3, 8, 9, 10)), 'hour'), false, 'day mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 8, 9, 10)), 'hour'), false, 'hour mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 0, 0, 0)), 'hour'), true, 'exact start of hour');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 59, 59, 999)), 'hour'), true, 'exact end of hour');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 0, 0, 0)), 'hour'), false, 'start of next hour');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 2, 59, 59, 999)), 'hour'), false, 'end of previous hour');\n        assert.equal(m.isSame(m, 'hour'), true, 'same moments are in the same hour');\n        assert.equal(+m, +mCopy, 'isSame hour should not change moment');\n    });\n\n    test('is same minute', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minute'), true, 'minute match');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 9, 10)), 'minutes'), true, 'plural should work');\n        assert.equal(m.isSame(moment(new Date(2012, 1, 2, 3, 4, 9, 10)), 'minute'), false, 'year mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 9, 10)), 'minute'), false, 'month mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 3, 3, 4, 9, 10)), 'minute'), false, 'day mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 4, 9, 10)), 'minute'), false, 'hour mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 5, 9, 10)), 'minute'), false, 'minute mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 0, 0)), 'minute'), true, 'exact start of minute');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 59, 999)), 'minute'), true, 'exact end of minute');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 5, 0, 0)), 'minute'), false, 'start of next minute');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 3, 59, 999)), 'minute'), false, 'end of previous minute');\n        assert.equal(m.isSame(m, 'minute'), true, 'same moments are in the same minute');\n        assert.equal(+m, +mCopy, 'isSame minute should not change moment');\n    });\n\n    test('is same second', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)), mCopy = moment(m);\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'second'), true, 'second match');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 10)), 'seconds'), true, 'plural should work');\n        assert.equal(m.isSame(moment(new Date(2012, 1, 2, 3, 4, 5, 10)), 'second'), false, 'year mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'second'), false, 'month mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 3, 3, 4, 5, 10)), 'second'), false, 'day mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 4, 4, 5, 10)), 'second'), false, 'hour mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 5, 5, 10)), 'second'), false, 'minute mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 6, 10)), 'second'), false, 'second mismatch');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 0)), 'second'), true, 'exact start of second');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 5, 999)), 'second'), true, 'exact end of second');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 6, 0)), 'second'), false, 'start of next second');\n        assert.equal(m.isSame(moment(new Date(2011, 1, 2, 3, 4, 4, 999)), 'second'), false, 'end of previous second');\n        assert.equal(m.isSame(m, 'second'), true, 'same moments are in the same second');\n        assert.equal(+m, +mCopy, 'isSame second should not change moment');\n    });\n\n    test('is same millisecond', function (assert) {\n        var m = moment(new Date(2011, 3, 2, 3, 4, 5, 10)), mCopy = moment(m);\n        assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'millisecond'), true, 'millisecond match');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 5, 10)), 'milliseconds'), true, 'plural should work');\n        assert.equal(m.isSame(moment(new Date(2012, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is later');\n        assert.equal(m.isSame(moment(new Date(2010, 3, 2, 3, 4, 5, 10)), 'millisecond'), false, 'year is earlier');\n        assert.equal(m.isSame(moment(new Date(2011, 4, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is later');\n        assert.equal(m.isSame(moment(new Date(2011, 2, 2, 3, 4, 5, 10)), 'millisecond'), false, 'month is earlier');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 3, 3, 4, 5, 10)), 'millisecond'), false, 'day is later');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 1, 1, 4, 5, 10)), 'millisecond'), false, 'day is earlier');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 2, 4, 4, 5, 10)), 'millisecond'), false, 'hour is later');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 1, 4, 1, 5, 10)), 'millisecond'), false, 'hour is earlier');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 5, 5, 10)), 'millisecond'), false, 'minute is later');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 3, 5, 10)), 'millisecond'), false, 'minute is earlier');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 6, 10)), 'millisecond'), false, 'second is later');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 4, 5)), 'millisecond'), false, 'second is earlier');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 6, 11)), 'millisecond'), false, 'millisecond is later');\n        assert.equal(m.isSame(moment(new Date(2011, 3, 2, 3, 4, 4, 9)), 'millisecond'), false, 'millisecond is earlier');\n        assert.equal(m.isSame(m, 'millisecond'), true, 'same moments are in the same millisecond');\n        assert.equal(+m, +mCopy, 'isSame millisecond should not change moment');\n    });\n\n    test('is same with utc offset moments', function (assert) {\n        assert.ok(moment.parseZone('2013-02-01T-05:00').isSame(moment('2013-02-01'), 'year'), 'zoned vs local moment');\n        assert.ok(moment('2013-02-01').isSame(moment('2013-02-01').utcOffset('-05:00'), 'year'), 'local vs zoned moment');\n        assert.ok(moment.parseZone('2013-02-01T-05:00').isSame(moment.parseZone('2013-02-01T-06:30'), 'year'),\n                'zoned vs (differently) zoned moment');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('is valid');\n\n    test('array bad month', function (assert) {\n        assert.equal(moment([2010, -1]).isValid(), false, 'month -1 invalid');\n        assert.equal(moment([2100, 12]).isValid(), false, 'month 12 invalid');\n    });\n\n    test('array good month', function (assert) {\n        for (var i = 0; i < 12; i++) {\n            assert.equal(moment([2010, i]).isValid(), true, 'month ' + i);\n            assert.equal(moment.utc([2010, i]).isValid(), true, 'month ' + i);\n        }\n    });\n\n    test('array bad date', function (assert) {\n        var tests = [\n            moment([2010, 0, 0]),\n            moment([2100, 0, 32]),\n            moment.utc([2010, 0, 0]),\n            moment.utc([2100, 0, 32])\n        ],\n        i, m;\n\n        for (i in tests) {\n            m = tests[i];\n            assert.equal(m.isValid(), false);\n        }\n    });\n\n    test('h/hh with hour > 12', function (assert) {\n        assert.ok(moment('06/20/2014 11:51 PM', 'MM/DD/YYYY hh:mm A', true).isValid(), '11 for hh');\n        assert.ok(moment('06/20/2014 11:51 AM', 'MM/DD/YYYY hh:mm A', true).isValid(), '11 for hh');\n        assert.ok(moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A').isValid(), 'non-strict validity 23 for hh');\n        assert.ok(moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A').parsingFlags().bigHour, 'non-strict bigHour 23 for hh');\n        assert.ok(!moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A', true).isValid(), 'validity 23 for hh');\n        assert.ok(moment('06/20/2014 23:51 PM', 'MM/DD/YYYY hh:mm A', true).parsingFlags().bigHour, 'bigHour 23 for hh');\n    });\n\n    test('array bad date leap year', function (assert) {\n        assert.equal(moment([2010, 1, 29]).isValid(), false, '2010 feb 29');\n        assert.equal(moment([2100, 1, 29]).isValid(), false, '2100 feb 29');\n        assert.equal(moment([2008, 1, 30]).isValid(), false, '2008 feb 30');\n        assert.equal(moment([2000, 1, 30]).isValid(), false, '2000 feb 30');\n\n        assert.equal(moment.utc([2010, 1, 29]).isValid(), false, 'utc 2010 feb 29');\n        assert.equal(moment.utc([2100, 1, 29]).isValid(), false, 'utc 2100 feb 29');\n        assert.equal(moment.utc([2008, 1, 30]).isValid(), false, 'utc 2008 feb 30');\n        assert.equal(moment.utc([2000, 1, 30]).isValid(), false, 'utc 2000 feb 30');\n    });\n\n    test('string + formats bad date', function (assert) {\n        assert.equal(moment('2020-00-00', []).isValid(), false, 'invalid on empty array');\n        assert.equal(moment('2020-00-00', ['YYYY-MM-DD', 'DD-MM-YYYY']).isValid(), false, 'invalid on all in array');\n        assert.equal(moment('2020-00-00', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(), false, 'invalid on all in array');\n        assert.equal(moment('2020-01-01', ['YYYY-MM-DD', 'DD-MM-YYYY']).isValid(), true, 'valid on first');\n        assert.equal(moment('2020-01-01', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(), true, 'valid on last');\n        assert.equal(moment('2020-01-01', ['YYYY-MM-DD', 'YYYY-DD-MM']).isValid(), true, 'valid on both');\n        assert.equal(moment('2020-13-01', ['YYYY-MM-DD', 'YYYY-DD-MM']).isValid(), true, 'valid on last');\n\n        assert.equal(moment('12-13-2012', ['DD-MM-YYYY', 'YYYY-MM-DD']).isValid(), false, 'month rollover');\n        assert.equal(moment('12-13-2012', ['DD-MM-YYYY', 'DD-MM-YYYY']).isValid(), false, 'month rollover');\n        assert.equal(moment('38-12-2012', ['DD-MM-YYYY']).isValid(), false, 'day rollover');\n    });\n\n    test('string nonsensical with format', function (assert) {\n        assert.equal(moment('fail', 'MM-DD-YYYY').isValid(), false, 'string \\'fail\\' with format \\'MM-DD-YYYY\\'');\n        assert.equal(moment('xx-xx-2001', 'DD-MM-YYY').isValid(), true, 'string \\'xx-xx-2001\\' with format \\'MM-DD-YYYY\\'');\n    });\n\n    test('string with bad month name', function (assert) {\n        assert.equal(moment('01-Nam-2012', 'DD-MMM-YYYY').isValid(), false, '\\'Nam\\' is an invalid month');\n        assert.equal(moment('01-Aug-2012', 'DD-MMM-YYYY').isValid(), true, '\\'Aug\\' is a valid month');\n    });\n\n    test('string with spaceless format', function (assert) {\n        assert.equal(moment('10Sep2001', 'DDMMMYYYY').isValid(), true, 'Parsing 10Sep2001 should result in a valid date');\n    });\n\n    test('invalid string iso 8601', function (assert) {\n        var tests = [\n            '2010-00-00',\n            '2010-01-00',\n            '2010-01-40',\n            '2010-01-01T24:01',  // 24:00:00 is actually valid\n            '2010-01-01T23:60',\n            '2010-01-01T23:59:60'\n        ], i;\n\n        for (i = 0; i < tests.length; i++) {\n            assert.equal(moment(tests[i]).isValid(), false, tests[i] + ' should be invalid');\n            assert.equal(moment.utc(tests[i]).isValid(), false, tests[i] + ' should be invalid');\n        }\n    });\n\n    test('invalid string iso 8601 + timezone', function (assert) {\n        var tests = [\n            '2010-00-00T+00:00',\n            '2010-01-00T+00:00',\n            '2010-01-40T+00:00',\n            '2010-01-40T24:01+00:00',\n            '2010-01-40T23:60+00:00',\n            '2010-01-40T23:59:60+00:00',\n            '2010-01-40T23:59:59.9999+00:00'\n        ], i;\n\n        for (i = 0; i < tests.length; i++) {\n            assert.equal(moment(tests[i]).isValid(), false, tests[i] + ' should be invalid');\n            assert.equal(moment.utc(tests[i]).isValid(), false, tests[i] + ' should be invalid');\n        }\n    });\n\n    test('valid string iso 8601 + timezone', function (assert) {\n        var tests = [\n            '2010-01-01',\n            '2010-01-30',\n            '2010-01-30T23+00:00',\n            '2010-01-30T23:59+00:00',\n            '2010-01-30T23:59:59+00:00',\n            '2010-01-30T23:59:59.999+00:00',\n            '2010-01-30T23:59:59.999-07:00',\n            '2010-01-30T00:00:00.000+07:00',\n            '2010-01-30T00:00:00.000+07'\n        ], i;\n\n        for (i = 0; i < tests.length; i++) {\n            assert.equal(moment(tests[i]).isValid(), true, tests[i] + ' should be valid');\n            assert.equal(moment.utc(tests[i]).isValid(), true, tests[i] + ' should be valid');\n        }\n    });\n\n    test('invalidAt', function (assert) {\n        assert.equal(moment([2000, 12]).invalidAt(), 1, 'month 12 is invalid: 0-11');\n        assert.equal(moment([2000, 1, 30]).invalidAt(), 2, '30 is not a valid february day');\n        assert.equal(moment([2000, 1, 29, 25]).invalidAt(), 3, '25 is invalid hour');\n        assert.equal(moment([2000, 1, 29, 24,  1]).invalidAt(), 3, '24:01 is invalid hour');\n        assert.equal(moment([2000, 1, 29, 23, 60]).invalidAt(), 4, '60 is invalid minute');\n        assert.equal(moment([2000, 1, 29, 23, 59, 60]).invalidAt(), 5, '60 is invalid second');\n        assert.equal(moment([2000, 1, 29, 23, 59, 59, 1000]).invalidAt(), 6, '1000 is invalid millisecond');\n        assert.equal(moment([2000, 1, 29, 23, 59, 59, 999]).invalidAt(), -1, '-1 if everything is fine');\n    });\n\n    test('valid Unix timestamp', function (assert) {\n        assert.equal(moment(1371065286, 'X').isValid(), true, 'number integer');\n        assert.equal(moment(1379066897.0, 'X').isValid(), true, 'number whole 1dp');\n        assert.equal(moment(1379066897.7, 'X').isValid(), true, 'number 1dp');\n        assert.equal(moment(1379066897.00, 'X').isValid(), true, 'number whole 2dp');\n        assert.equal(moment(1379066897.07, 'X').isValid(), true, 'number 2dp');\n        assert.equal(moment(1379066897.17, 'X').isValid(), true, 'number 2dp');\n        assert.equal(moment(1379066897.000, 'X').isValid(), true, 'number whole 3dp');\n        assert.equal(moment(1379066897.007, 'X').isValid(), true, 'number 3dp');\n        assert.equal(moment(1379066897.017, 'X').isValid(), true, 'number 3dp');\n        assert.equal(moment(1379066897.157, 'X').isValid(), true, 'number 3dp');\n        assert.equal(moment('1371065286', 'X').isValid(), true, 'string integer');\n        assert.equal(moment('1379066897.', 'X').isValid(), true, 'string trailing .');\n        assert.equal(moment('1379066897.0', 'X').isValid(), true, 'string whole 1dp');\n        assert.equal(moment('1379066897.7', 'X').isValid(), true, 'string 1dp');\n        assert.equal(moment('1379066897.00', 'X').isValid(), true, 'string whole 2dp');\n        assert.equal(moment('1379066897.07', 'X').isValid(), true, 'string 2dp');\n        assert.equal(moment('1379066897.17', 'X').isValid(), true, 'string 2dp');\n        assert.equal(moment('1379066897.000', 'X').isValid(), true, 'string whole 3dp');\n        assert.equal(moment('1379066897.007', 'X').isValid(), true, 'string 3dp');\n        assert.equal(moment('1379066897.017', 'X').isValid(), true, 'string 3dp');\n        assert.equal(moment('1379066897.157', 'X').isValid(), true, 'string 3dp');\n    });\n\n    test('invalid Unix timestamp', function (assert) {\n        assert.equal(moment(undefined, 'X').isValid(), false, 'undefined');\n        assert.equal(moment('undefined', 'X').isValid(), false, 'string undefined');\n        try {\n            assert.equal(moment(null, 'X').isValid(), false, 'null');\n        } catch (e) {\n            assert.ok(true, 'null');\n        }\n\n        assert.equal(moment('null', 'X').isValid(), false, 'string null');\n        assert.equal(moment([], 'X').isValid(), false, 'array');\n        assert.equal(moment('{}', 'X').isValid(), false, 'object');\n        try {\n            assert.equal(moment('', 'X').isValid(), false, 'string empty');\n        } catch (e) {\n            assert.ok(true, 'string empty');\n        }\n\n        assert.equal(moment(' ', 'X').isValid(), false, 'string space');\n    });\n\n    test('valid Unix offset milliseconds', function (assert) {\n        assert.equal(moment(1234567890123, 'x').isValid(), true, 'number integer');\n        assert.equal(moment('1234567890123', 'x').isValid(), true, 'string integer');\n    });\n\n    test('invalid Unix offset milliseconds', function (assert) {\n        assert.equal(moment(undefined, 'x').isValid(), false, 'undefined');\n        assert.equal(moment('undefined', 'x').isValid(), false, 'string undefined');\n        try {\n            assert.equal(moment(null, 'x').isValid(), false, 'null');\n        } catch (e) {\n            assert.ok(true, 'null');\n        }\n\n        assert.equal(moment('null', 'x').isValid(), false, 'string null');\n        assert.equal(moment([], 'x').isValid(), false, 'array');\n        assert.equal(moment('{}', 'x').isValid(), false, 'object');\n        try {\n            assert.equal(moment('', 'x').isValid(), false, 'string empty');\n        } catch (e) {\n            assert.ok(true, 'string empty');\n        }\n\n        assert.equal(moment(' ', 'x').isValid(), false, 'string space');\n    });\n\n    test('empty', function (assert) {\n        assert.equal(moment(null).isValid(), false, 'null');\n        assert.equal(moment('').isValid(), false, 'empty string');\n        assert.equal(moment(null, 'YYYY').isValid(), false, 'format + null');\n        assert.equal(moment('', 'YYYY').isValid(), false, 'format + empty string');\n        assert.equal(moment(' ', 'YYYY').isValid(), false, 'format + empty when trimmed');\n    });\n\n    test('days of the year', function (assert) {\n        assert.equal(moment('2010 300', 'YYYY DDDD').isValid(), true, 'day 300 of year valid');\n        assert.equal(moment('2010 365', 'YYYY DDDD').isValid(), true, 'day 365 of year valid');\n        assert.equal(moment('2010 366', 'YYYY DDDD').isValid(), false, 'day 366 of year invalid');\n        assert.equal(moment('2012 365', 'YYYY DDDD').isValid(), true, 'day 365 of leap year valid');\n        assert.equal(moment('2012 366', 'YYYY DDDD').isValid(), true, 'day 366 of leap year valid');\n        assert.equal(moment('2012 367', 'YYYY DDDD').isValid(), false, 'day 367 of leap year invalid');\n    });\n\n    test('24:00:00.000 is valid', function (assert) {\n        assert.equal(moment('2014-01-01 24', 'YYYY-MM-DD HH').isValid(), true, '24 is valid');\n        assert.equal(moment('2014-01-01 24:00', 'YYYY-MM-DD HH:mm').isValid(), true, '24:00 is valid');\n        assert.equal(moment('2014-01-01 24:01', 'YYYY-MM-DD HH:mm').isValid(), false, '24:01 is not valid');\n    });\n\n    test('oddball permissiveness', function (assert) {\n        assert.ok(moment('2010-10-3199', ['MM/DD/YYYY', 'MM-DD-YYYY', 'YYYY-MM-DD']).isValid());\n        assert.ok(moment('3:25', ['h:mma', 'hh:mma', 'H:mm', 'HH:mm']).isValid());\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('leap year');\n\n    test('leap year', function (assert) {\n        assert.equal(moment([2010, 0, 1]).isLeapYear(), false, '2010');\n        assert.equal(moment([2100, 0, 1]).isLeapYear(), false, '2100');\n        assert.equal(moment([2008, 0, 1]).isLeapYear(), true, '2008');\n        assert.equal(moment([2000, 0, 1]).isLeapYear(), true, '2000');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('listers');\n\n    test('default', function (assert) {\n        assert.deepEqual(moment.months(), ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December']);\n        assert.deepEqual(moment.monthsShort(), ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']);\n        assert.deepEqual(moment.weekdays(), ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']);\n        assert.deepEqual(moment.weekdaysShort(), ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']);\n        assert.deepEqual(moment.weekdaysMin(), ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa']);\n    });\n\n    test('index', function (assert) {\n        assert.equal(moment.months(0), 'January');\n        assert.equal(moment.months(2), 'March');\n        assert.equal(moment.monthsShort(0), 'Jan');\n        assert.equal(moment.monthsShort(2), 'Mar');\n        assert.equal(moment.weekdays(0), 'Sunday');\n        assert.equal(moment.weekdays(2), 'Tuesday');\n        assert.equal(moment.weekdaysShort(0), 'Sun');\n        assert.equal(moment.weekdaysShort(2), 'Tue');\n        assert.equal(moment.weekdaysMin(0), 'Su');\n        assert.equal(moment.weekdaysMin(2), 'Tu');\n    });\n\n    test('localized', function (assert) {\n        var months = 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_'),\n            monthsShort = 'on_tw_th_fo_fi_si_se_ei_ni_te_el_tw'.split('_'),\n            weekdays = 'one_two_three_four_five_six_seven'.split('_'),\n            weekdaysShort = 'on_tw_th_fo_fi_si_se'.split('_'),\n            weekdaysMin = '1_2_3_4_5_6_7'.split('_');\n\n        moment.locale('numerologists', {\n            months : months,\n            monthsShort : monthsShort,\n            weekdays : weekdays,\n            weekdaysShort: weekdaysShort,\n            weekdaysMin: weekdaysMin\n        });\n\n        assert.deepEqual(moment.months(), months);\n        assert.deepEqual(moment.monthsShort(), monthsShort);\n        assert.deepEqual(moment.weekdays(), weekdays);\n        assert.deepEqual(moment.weekdaysShort(), weekdaysShort);\n        assert.deepEqual(moment.weekdaysMin(), weekdaysMin);\n\n        assert.equal(moment.months(0), 'one');\n        assert.equal(moment.monthsShort(0), 'on');\n        assert.equal(moment.weekdays(0), 'one');\n        assert.equal(moment.weekdaysShort(0), 'on');\n        assert.equal(moment.weekdaysMin(0), '1');\n\n        assert.equal(moment.months(2), 'three');\n        assert.equal(moment.monthsShort(2), 'th');\n        assert.equal(moment.weekdays(2), 'three');\n        assert.equal(moment.weekdaysShort(2), 'th');\n        assert.equal(moment.weekdaysMin(2), '3');\n    });\n\n    test('with functions', function (assert) {\n        var monthsShort = 'one_two_three_four_five_six_seven_eight_nine_ten_eleven_twelve'.split('_'),\n            monthsShortWeird = 'onesy_twosy_threesy_foursy_fivesy_sixsy_sevensy_eightsy_ninesy_tensy_elevensy_twelvesy'.split('_');\n\n        moment.locale('difficult', {\n\n            monthsShort: function (m, format) {\n                var arr = format.match(/-MMM-/) ? monthsShortWeird : monthsShort;\n                return arr[m.month()];\n            }\n        });\n\n        assert.deepEqual(moment.monthsShort(), monthsShort);\n        assert.deepEqual(moment.monthsShort('MMM'), monthsShort);\n        assert.deepEqual(moment.monthsShort('-MMM-'), monthsShortWeird);\n\n        assert.deepEqual(moment.monthsShort('MMM', 2), 'three');\n        assert.deepEqual(moment.monthsShort('-MMM-', 2), 'threesy');\n        assert.deepEqual(moment.monthsShort(2), 'three');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function each(array, callback) {\n        var i;\n        for (i = 0; i < array.length; i++) {\n            callback(array[i], i, array);\n        }\n    }\n\n    var helpers_each = each;\n\n    module('locale', {\n        setup : function () {\n            helpers_each([{\n                name: 'en-gb',\n                data: {}\n            }, {\n                name: 'en-ca',\n                data: {}\n            }, {\n                name: 'es',\n                data: {\n                    relativeTime: {past: 'hace %s', s: 'unos segundos', d: 'un día'},\n                    months: 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_')\n                }\n            }, {\n                name: 'fr',\n                data: {}\n            }, {\n                name: 'fr-ca',\n                data: {}\n            }, {\n                name: 'it',\n                data: {}\n            }, {\n                name: 'zh-cn',\n                data: {\n                    months: '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_')\n                }\n            }], function (locale) {\n                if (moment.locale(locale.name) !== locale.name) {\n                    moment.defineLocale(locale.name, locale.data);\n                }\n            });\n            moment.locale('en');\n        }\n    });\n\n    test('library getters and setters', function (assert) {\n        var r = moment.locale('en');\n\n        assert.equal(r, 'en', 'locale should return en by default');\n        assert.equal(moment.locale(), 'en', 'locale should return en by default');\n\n        moment.locale('fr');\n        assert.equal(moment.locale(), 'fr', 'locale should return the changed locale');\n\n        moment.locale('en-gb');\n        assert.equal(moment.locale(), 'en-gb', 'locale should return the changed locale');\n\n        moment.locale('en');\n        assert.equal(moment.locale(), 'en', 'locale should reset');\n\n        moment.locale('does-not-exist');\n        assert.equal(moment.locale(), 'en', 'locale should reset');\n\n        moment.locale('EN');\n        assert.equal(moment.locale(), 'en', 'Normalize locale key case');\n\n        moment.locale('EN_gb');\n        assert.equal(moment.locale(), 'en-gb', 'Normalize locale key underscore');\n    });\n\n    test('library setter array of locales', function (assert) {\n        assert.equal(moment.locale(['non-existent', 'fr', 'also-non-existent']), 'fr', 'passing an array uses the first valid locale');\n        assert.equal(moment.locale(['es', 'fr', 'also-non-existent']), 'es', 'passing an array uses the first valid locale');\n    });\n\n    test('library setter locale substrings', function (assert) {\n        assert.equal(moment.locale('fr-crap'), 'fr', 'use substrings');\n        assert.equal(moment.locale('fr-does-not-exist'), 'fr', 'uses deep substrings');\n        assert.equal(moment.locale('fr-CA-does-not-exist'), 'fr-ca', 'uses deepest substring');\n    });\n\n    test('library getter locale array and substrings', function (assert) {\n        assert.equal(moment.locale(['en-CH', 'fr']), 'en', 'prefer root locale to shallower ones');\n        assert.equal(moment.locale(['en-gb-leeds', 'en-CA']), 'en-gb', 'prefer root locale to shallower ones');\n        assert.equal(moment.locale(['en-fake', 'en-CA']), 'en-ca', 'prefer alternatives with shared roots');\n        assert.equal(moment.locale(['en-fake', 'en-fake2', 'en-ca']), 'en-ca', 'prefer alternatives with shared roots');\n        assert.equal(moment.locale(['fake-CA', 'fake-MX', 'fr']), 'fr', 'always find something if possible');\n        assert.equal(moment.locale(['fake-CA', 'fake-MX', 'fr']), 'fr', 'always find something if possible');\n        assert.equal(moment.locale(['fake-CA', 'fake-MX', 'fr-fake-fake-fake']), 'fr', 'always find something if possible');\n        assert.equal(moment.locale(['en', 'en-CA']), 'en', 'prefer earlier if it works');\n    });\n\n    test('library ensure inheritance', function (assert) {\n        moment.locale('made-up', {\n            months : 'February_March_April_May_June_July_August_September_October_November_December_January'.split('_')\n        });\n\n        assert.equal(moment([2012, 5, 6]).format('MMMM'), 'July', 'Override some of the configs');\n        assert.equal(moment([2012, 5, 6]).format('MMM'), 'Jun', 'But not all of them');\n    });\n\n    test('library ensure inheritance LT L LL LLL LLLL', function (assert) {\n        var locale = 'test-inherit-lt';\n\n        moment.defineLocale(locale, {\n            longDateFormat : {\n                LT : '-[LT]-',\n                L : '-[L]-',\n                LL : '-[LL]-',\n                LLL : '-[LLL]-',\n                LLLL : '-[LLLL]-'\n            },\n            calendar : {\n                sameDay : '[sameDay] LT',\n                nextDay : '[nextDay] L',\n                nextWeek : '[nextWeek] LL',\n                lastDay : '[lastDay] LLL',\n                lastWeek : '[lastWeek] LLLL',\n                sameElse : 'L'\n            }\n        });\n\n        moment.locale('es');\n\n        assert.equal(moment().locale(locale).calendar(), 'sameDay -LT-', 'Should use instance locale in LT formatting');\n        assert.equal(moment().add(1, 'days').locale(locale).calendar(), 'nextDay -L-', 'Should use instance locale in L formatting');\n        assert.equal(moment().add(-1, 'days').locale(locale).calendar(), 'lastDay -LLL-', 'Should use instance locale in LL formatting');\n        assert.equal(moment().add(4, 'days').locale(locale).calendar(), 'nextWeek -LL-', 'Should use instance locale in LLL formatting');\n        assert.equal(moment().add(-4, 'days').locale(locale).calendar(), 'lastWeek -LLLL-', 'Should use instance locale in LLLL formatting');\n    });\n\n    test('library localeData', function (assert) {\n        moment.locale('en');\n\n        var jan = moment([2000, 0]);\n\n        assert.equal(moment.localeData().months(jan), 'January', 'no arguments returns global');\n        assert.equal(moment.localeData('zh-cn').months(jan), '一月', 'a string returns the locale based on key');\n        assert.equal(moment.localeData(moment().locale('es')).months(jan), 'enero', 'if you pass in a moment it uses the moment\\'s locale');\n    });\n\n    test('library deprecations', function (assert) {\n        moment.lang('dude', {months: ['Movember']});\n        assert.equal(moment.locale(), 'dude', 'setting the lang sets the locale');\n        assert.equal(moment.lang(), moment.locale());\n        assert.equal(moment.langData(), moment.localeData(), 'langData is localeData');\n    });\n\n    test('defineLocale', function (assert) {\n        moment.locale('en');\n        moment.defineLocale('dude', {months: ['Movember']});\n        assert.equal(moment().locale(), 'dude', 'defineLocale also sets it');\n        assert.equal(moment().locale('dude').locale(), 'dude', 'defineLocale defines a locale');\n    });\n\n    test('library convenience', function (assert) {\n        moment.locale('something', {week: {dow: 3}});\n        moment.locale('something');\n        assert.equal(moment.locale(), 'something', 'locale can be used to create the locale too');\n    });\n\n    test('firstDayOfWeek firstDayOfYear locale getters', function (assert) {\n        moment.locale('something', {week: {dow: 3, doy: 4}});\n        moment.locale('something');\n        assert.equal(moment.localeData().firstDayOfWeek(), 3, 'firstDayOfWeek');\n        assert.equal(moment.localeData().firstDayOfYear(), 4, 'firstDayOfYear');\n    });\n\n    test('instance locale method', function (assert) {\n        moment.locale('en');\n\n        assert.equal(moment([2012, 5, 6]).format('MMMM'), 'June', 'Normally default to global');\n        assert.equal(moment([2012, 5, 6]).locale('es').format('MMMM'), 'junio', 'Use the instance specific locale');\n        assert.equal(moment([2012, 5, 6]).format('MMMM'), 'June', 'Using an instance specific locale does not affect other moments');\n    });\n\n    test('instance locale method with array', function (assert) {\n        var m = moment().locale(['non-existent', 'fr', 'also-non-existent']);\n        assert.equal(m.locale(), 'fr', 'passing an array uses the first valid locale');\n        m = moment().locale(['es', 'fr', 'also-non-existent']);\n        assert.equal(m.locale(), 'es', 'passing an array uses the first valid locale');\n    });\n\n    test('instance getter locale substrings', function (assert) {\n        var m = moment();\n\n        m.locale('fr-crap');\n        assert.equal(m.locale(), 'fr', 'use substrings');\n\n        m.locale('fr-does-not-exist');\n        assert.equal(m.locale(), 'fr', 'uses deep substrings');\n    });\n\n    test('instance locale persists with manipulation', function (assert) {\n        moment.locale('en');\n\n        assert.equal(moment([2012, 5, 6]).locale('es').add({days: 1}).format('MMMM'), 'junio', 'With addition');\n        assert.equal(moment([2012, 5, 6]).locale('es').day(0).format('MMMM'), 'junio', 'With day getter');\n        assert.equal(moment([2012, 5, 6]).locale('es').endOf('day').format('MMMM'), 'junio', 'With endOf');\n    });\n\n    test('instance locale persists with cloning', function (assert) {\n        moment.locale('en');\n\n        var a = moment([2012, 5, 6]).locale('es'),\n            b = a.clone(),\n            c = moment(a);\n\n        assert.equal(b.format('MMMM'), 'junio', 'using moment.fn.clone()');\n        assert.equal(b.format('MMMM'), 'junio', 'using moment()');\n    });\n\n    test('duration locale method', function (assert) {\n        moment.locale('en');\n\n        assert.equal(moment.duration({seconds:  44}).humanize(), 'a few seconds', 'Normally default to global');\n        assert.equal(moment.duration({seconds:  44}).locale('es').humanize(), 'unos segundos', 'Use the instance specific locale');\n        assert.equal(moment.duration({seconds:  44}).humanize(), 'a few seconds', 'Using an instance specific locale does not affect other durations');\n    });\n\n    test('duration locale persists with cloning', function (assert) {\n        moment.locale('en');\n\n        var a = moment.duration({seconds:  44}).locale('es'),\n            b = moment.duration(a);\n\n        assert.equal(b.humanize(), 'unos segundos', 'using moment.duration()');\n    });\n\n    test('changing the global locale doesn\\'t affect existing duration instances', function (assert) {\n        var mom = moment.duration();\n        moment.locale('fr');\n        assert.equal('en', mom.locale());\n    });\n\n    test('duration deprecations', function (assert) {\n        assert.equal(moment.duration().lang(), moment.duration().localeData(), 'duration.lang is the same as duration.localeData');\n    });\n\n    test('from relative time future', function (assert) {\n        var start = moment([2007, 1, 28]);\n\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 44})),  'in a few seconds', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 45})),  'in a minute',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 89})),  'in a minute',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({s: 90})),  'in 2 minutes',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 44})),  'in 44 minutes',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 45})),  'in an hour',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 89})),  'in an hour',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({m: 90})),  'in 2 hours',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 5})),   'in 5 hours',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 21})),  'in 21 hours',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 22})),  'in a day',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 35})),  'in a day',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({h: 36})),  'in 2 days',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 1})),   'in a day',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 5})),   'in 5 days',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 25})),  'in 25 days',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 26})),  'in a month',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 30})),  'in a month',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 45})),  'in a month',       '45 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 47})),  'in 2 months',      '47 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 74})),  'in 2 months',      '74 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 78})),  'in 3 months',      '78 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({M: 1})),   'in a month',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({M: 5})),   'in 5 months',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 315})), 'in 10 months',     '315 days = 10 months');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 344})), 'in a year',        '344 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 345})), 'in a year',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({d: 548})), 'in 2 years',       '548 days = in 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({y: 1})),   'in a year',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).subtract({y: 5})),   'in 5 years',       '5 years = 5 years');\n    });\n\n    test('from relative time past', function (assert) {\n        var start = moment([2007, 1, 28]);\n\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 44})),  'a few seconds ago', '44 seconds = a few seconds');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 45})),  'a minute ago',      '45 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 89})),  'a minute ago',      '89 seconds = a minute');\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90})),  '2 minutes ago',     '90 seconds = 2 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 44})),  '44 minutes ago',    '44 minutes = 44 minutes');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 45})),  'an hour ago',       '45 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 89})),  'an hour ago',       '89 minutes = an hour');\n        assert.equal(start.from(moment([2007, 1, 28]).add({m: 90})),  '2 hours ago',       '90 minutes = 2 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 5})),   '5 hours ago',       '5 hours = 5 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 21})),  '21 hours ago',      '21 hours = 21 hours');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 22})),  'a day ago',         '22 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 35})),  'a day ago',         '35 hours = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({h: 36})),  '2 days ago',        '36 hours = 2 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 1})),   'a day ago',         '1 day = a day');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 5})),   '5 days ago',        '5 days = 5 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 25})),  '25 days ago',       '25 days = 25 days');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 26})),  'a month ago',       '26 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 30})),  'a month ago',       '30 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 43})),  'a month ago',       '43 days = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 46})),  '2 months ago',      '46 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 74})),  '2 months ago',      '75 days = 2 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 76})),  '3 months ago',      '76 days = 3 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 1})),   'a month ago',       '1 month = a month');\n        assert.equal(start.from(moment([2007, 1, 28]).add({M: 5})),   '5 months ago',      '5 months = 5 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 315})), '10 months ago',     '315 days = 10 months');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 344})), 'a year ago',        '344 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 345})), 'a year ago',        '345 days = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({d: 548})), '2 years ago',       '548 days = 2 years');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 1})),   'a year ago',        '1 year = a year');\n        assert.equal(start.from(moment([2007, 1, 28]).add({y: 5})),   '5 years ago',       '5 years = 5 years');\n    });\n\n    test('instance locale used with from', function (assert) {\n        moment.locale('en');\n\n        var a = moment([2012, 5, 6]).locale('es'),\n            b = moment([2012, 5, 7]);\n\n        assert.equal(a.from(b), 'hace un día', 'preserve locale of first moment');\n        assert.equal(b.from(a), 'in a day', 'do not preserve locale of second moment');\n    });\n\n    test('instance localeData', function (assert) {\n        moment.defineLocale('dude', {week: {dow: 3}});\n        assert.equal(moment().locale('dude').localeData()._week.dow, 3);\n    });\n\n    test('month name callback function', function (assert) {\n        function fakeReplace(m, format) {\n            if (/test/.test(format)) {\n                return 'test';\n            }\n            if (m.date() === 1) {\n                return 'date';\n            }\n            return 'default';\n        }\n\n        moment.locale('made-up-2', {\n            months : fakeReplace,\n            monthsShort : fakeReplace,\n            weekdays : fakeReplace,\n            weekdaysShort : fakeReplace,\n            weekdaysMin : fakeReplace\n        });\n\n        assert.equal(moment().format('[test] dd ddd dddd MMM MMMM'), 'test test test test test test', 'format month name function should be able to access the format string');\n        assert.equal(moment([2011, 0, 1]).format('dd ddd dddd MMM MMMM'), 'date date date date date', 'format month name function should be able to access the moment object');\n        assert.equal(moment([2011, 0, 2]).format('dd ddd dddd MMM MMMM'), 'default default default default default', 'format month name function should be able to access the moment object');\n    });\n\n    test('changing parts of a locale config', function (assert) {\n        moment.locale('partial-lang', {\n            months : 'a b c d e f g h i j k l'.split(' ')\n        });\n\n        assert.equal(moment([2011, 0, 1]).format('MMMM'), 'a', 'should be able to set locale values when creating the localeuage');\n\n        moment.locale('partial-lang', {\n            monthsShort : 'A B C D E F G H I J K L'.split(' ')\n        });\n\n        assert.equal(moment([2011, 0, 1]).format('MMMM MMM'), 'a A', 'should be able to set locale values after creating the localeuage');\n    });\n\n    test('start/endOf week feature for first-day-is-monday locales', function (assert) {\n        moment.locale('monday-lang', {\n            week : {\n                dow : 1 // Monday is the first day of the week\n            }\n        });\n\n        moment.locale('monday-lang');\n        assert.equal(moment([2013, 0, 1]).startOf('week').day(), 1, 'for locale monday-lang first day of the week should be monday');\n        assert.equal(moment([2013, 0, 1]).endOf('week').day(), 0, 'for locale monday-lang last day of the week should be sunday');\n    });\n\n    test('meridiem parsing', function (assert) {\n        moment.locale('meridiem-parsing', {\n            meridiemParse : /[bd]/i,\n            isPM : function (input) {\n                return input === 'b';\n            }\n        });\n\n        moment.locale('meridiem-parsing');\n        assert.equal(moment('2012-01-01 3b', 'YYYY-MM-DD ha').hour(), 15, 'Custom parsing of meridiem should work');\n        assert.equal(moment('2012-01-01 3d', 'YYYY-MM-DD ha').hour(), 3, 'Custom parsing of meridiem should work');\n    });\n\n    test('invalid date formatting', function (assert) {\n        moment.locale('has-invalid', {\n            invalidDate: 'KHAAAAAAAAAAAN!'\n        });\n\n        assert.equal(moment.invalid().format(), 'KHAAAAAAAAAAAN!');\n        assert.equal(moment.invalid().format('YYYY-MM-DD'), 'KHAAAAAAAAAAAN!');\n    });\n\n    test('return locale name', function (assert) {\n        var registered = moment.locale('return-this', {});\n\n        assert.equal(registered, 'return-this', 'returns the locale configured');\n    });\n\n    test('changing the global locale doesn\\'t affect existing instances', function (assert) {\n        var mom = moment();\n        moment.locale('fr');\n        assert.equal('en', mom.locale());\n    });\n\n    test('setting a language on instance returns the original moment for chaining', function (assert) {\n        var mom = moment();\n\n        assert.equal(mom.lang('fr'), mom, 'setting the language (lang) returns the original moment for chaining');\n        assert.equal(mom.locale('it'), mom, 'setting the language (locale) returns the original moment for chaining');\n    });\n\n    test('lang(key) changes the language of the instance', function (assert) {\n        var m = moment().month(0);\n        m.lang('fr');\n        assert.equal(m.locale(), 'fr', 'm.lang(key) changes instance locale');\n    });\n\n    test('moment#locale(false) resets to global locale', function (assert) {\n        var m = moment();\n\n        moment.locale('fr');\n        m.locale('it');\n\n        assert.equal(moment.locale(), 'fr', 'global locale is it');\n        assert.equal(m.locale(), 'it', 'instance locale is it');\n        m.locale(false);\n        assert.equal(m.locale(), 'fr', 'instance locale reset to global locale');\n    });\n\n    test('moment().locale with missing key doesn\\'t change locale', function (assert) {\n        assert.equal(moment().locale('boo').localeData(), moment.localeData(),\n                'preserve global locale in case of bad locale id');\n    });\n\n    test('moment().lang with missing key doesn\\'t change locale', function (assert) {\n        assert.equal(moment().lang('boo').localeData(), moment.localeData(),\n                'preserve global locale in case of bad locale id');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('min max');\n\n    test('min', function (assert) {\n        var now = moment(),\n            future = now.clone().add(1, 'month'),\n            past = now.clone().subtract(1, 'month');\n\n        assert.equal(moment.min(now, future, past), past, 'min(now, future, past)');\n        assert.equal(moment.min(future, now, past), past, 'min(future, now, past)');\n        assert.equal(moment.min(future, past, now), past, 'min(future, past, now)');\n        assert.equal(moment.min(past, future, now), past, 'min(past, future, now)');\n        assert.equal(moment.min(now, past), past, 'min(now, past)');\n        assert.equal(moment.min(past, now), past, 'min(past, now)');\n        assert.equal(moment.min(now), now, 'min(now, past)');\n\n        assert.equal(moment.min([now, future, past]), past, 'min([now, future, past])');\n        assert.equal(moment.min([now, past]), past, 'min(now, past)');\n        assert.equal(moment.min([now]), now, 'min(now)');\n    });\n\n    test('max', function (assert) {\n        var now = moment(),\n            future = now.clone().add(1, 'month'),\n            past = now.clone().subtract(1, 'month');\n\n        assert.equal(moment.max(now, future, past), future, 'max(now, future, past)');\n        assert.equal(moment.max(future, now, past), future, 'max(future, now, past)');\n        assert.equal(moment.max(future, past, now), future, 'max(future, past, now)');\n        assert.equal(moment.max(past, future, now), future, 'max(past, future, now)');\n        assert.equal(moment.max(now, past), now, 'max(now, past)');\n        assert.equal(moment.max(past, now), now, 'max(past, now)');\n        assert.equal(moment.max(now), now, 'max(now, past)');\n\n        assert.equal(moment.max([now, future, past]), future, 'max([now, future, past])');\n        assert.equal(moment.max([now, past]), now, 'max(now, past)');\n        assert.equal(moment.max([now]), now, 'max(now)');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('mutable');\n\n    test('manipulation methods', function (assert) {\n        var m = moment();\n\n        assert.equal(m, m.year(2011), 'year() should be mutable');\n        assert.equal(m, m.month(1), 'month() should be mutable');\n        assert.equal(m, m.hours(7), 'hours() should be mutable');\n        assert.equal(m, m.minutes(33), 'minutes() should be mutable');\n        assert.equal(m, m.seconds(44), 'seconds() should be mutable');\n        assert.equal(m, m.milliseconds(55), 'milliseconds() should be mutable');\n        assert.equal(m, m.day(2), 'day() should be mutable');\n        assert.equal(m, m.startOf('week'), 'startOf() should be mutable');\n        assert.equal(m, m.add(1, 'days'), 'add() should be mutable');\n        assert.equal(m, m.subtract(2, 'years'), 'subtract() should be mutable');\n        assert.equal(m, m.local(), 'local() should be mutable');\n        assert.equal(m, m.utc(), 'utc() should be mutable');\n    });\n\n    test('non mutable methods', function (assert) {\n        var m = moment();\n        assert.notEqual(m, m.clone(), 'clone() should not be mutable');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('normalize units');\n\n    test('normalize units', function (assert) {\n        var fullKeys = ['year', 'quarter', 'month', 'isoWeek', 'week', 'day', 'hour', 'minute', 'second', 'millisecond', 'date', 'dayOfYear', 'weekday', 'isoWeekday', 'weekYear', 'isoWeekYear'],\n            aliases = ['y', 'Q', 'M', 'W', 'w', 'd', 'h', 'm', 's', 'ms', 'D', 'DDD', 'e', 'E', 'gg', 'GG'],\n            length = fullKeys.length,\n            fullKey,\n            fullKeyCaps,\n            fullKeyPlural,\n            fullKeyCapsPlural,\n            fullKeyLower,\n            alias,\n            index;\n\n        for (index = 0; index < length; index += 1) {\n            fullKey = fullKeys[index];\n            fullKeyCaps = fullKey.toUpperCase();\n            fullKeyLower = fullKey.toLowerCase();\n            fullKeyPlural = fullKey + 's';\n            fullKeyCapsPlural = fullKeyCaps + 's';\n            alias = aliases[index];\n            assert.equal(moment.normalizeUnits(fullKey), fullKey, 'Testing full key ' + fullKey);\n            assert.equal(moment.normalizeUnits(fullKeyCaps), fullKey, 'Testing full key capitalised ' + fullKey);\n            assert.equal(moment.normalizeUnits(fullKeyPlural), fullKey, 'Testing full key plural ' + fullKey);\n            assert.equal(moment.normalizeUnits(fullKeyCapsPlural), fullKey, 'Testing full key capitalised and plural ' + fullKey);\n            assert.equal(moment.normalizeUnits(alias), fullKey, 'Testing alias ' + fullKey);\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('parsing flags');\n\n    function flags () {\n        return moment.apply(null, arguments).parsingFlags();\n    }\n\n    test('overflow with array', function (assert) {\n        assert.equal(flags([2010, 0]).overflow, -1, 'month 0 valid');\n        assert.equal(flags([2010, 1]).overflow, -1, 'month 1 valid');\n        assert.equal(flags([2010, -1]).overflow, 1, 'month -1 invalid');\n        assert.equal(flags([2100, 12]).overflow, 1, 'month 12 invalid');\n        assert.equal(flags([2010, 1, 16]).overflow, -1, 'date valid');\n        assert.equal(flags([2010, 1, -1]).overflow, 2, 'date -1 invalid');\n        assert.equal(flags([2010, 1, 0]).overflow, 2, 'date 0 invalid');\n        assert.equal(flags([2010, 1, 32]).overflow, 2, 'date 32 invalid');\n        assert.equal(flags([2012, 1, 29]).overflow, -1, 'date leap year valid');\n        assert.equal(flags([2010, 1, 29]).overflow, 2, 'date leap year invalid');\n        assert.equal(flags([2010, 1, 1, 8]).overflow, -1, 'hour valid');\n        assert.equal(flags([2010, 1, 1, 0]).overflow, -1, 'hour 0 valid');\n        assert.equal(flags([2010, 1, 1, -1]).overflow, 3, 'hour -1 invalid');\n        assert.equal(flags([2010, 1, 1, 25]).overflow, 3, 'hour 25 invalid');\n        assert.equal(flags([2010, 1, 1, 24, 1]).overflow, 3, 'hour 24:01 invalid');\n        assert.equal(flags([2010, 1, 1, 8, 15]).overflow, -1, 'minute valid');\n        assert.equal(flags([2010, 1, 1, 8, 0]).overflow, -1, 'minute 0 valid');\n        assert.equal(flags([2010, 1, 1, 8, -1]).overflow, 4, 'minute -1 invalid');\n        assert.equal(flags([2010, 1, 1, 8, 60]).overflow, 4, 'minute 60 invalid');\n        assert.equal(flags([2010, 1, 1, 8, 15, 12]).overflow, -1, 'second valid');\n        assert.equal(flags([2010, 1, 1, 8, 15, 0]).overflow, -1, 'second 0 valid');\n        assert.equal(flags([2010, 1, 1, 8, 15, -1]).overflow, 5, 'second -1 invalid');\n        assert.equal(flags([2010, 1, 1, 8, 15, 60]).overflow, 5, 'second 60 invalid');\n        assert.equal(flags([2010, 1, 1, 8, 15, 12, 345]).overflow, -1, 'millisecond valid');\n        assert.equal(flags([2010, 1, 1, 8, 15, 12, 0]).overflow, -1, 'millisecond 0 valid');\n        assert.equal(flags([2010, 1, 1, 8, 15, 12, -1]).overflow, 6, 'millisecond -1 invalid');\n        assert.equal(flags([2010, 1, 1, 8, 15, 12, 1000]).overflow, 6, 'millisecond 1000 invalid');\n        assert.equal(flags([2010, 1, 1, 24, 0, 0, 0]).overflow, -1, '24:00:00.000 is fine');\n        assert.equal(flags([2010, 1, 1, 24, 1, 0, 0]).overflow, 3, '24:01:00.000 is wrong hour');\n        assert.equal(flags([2010, 1, 1, 24, 0, 1, 0]).overflow, 3, '24:00:01.000 is wrong hour');\n        assert.equal(flags([2010, 1, 1, 24, 0, 0, 1]).overflow, 3, '24:00:00.001 is wrong hour');\n    });\n\n    test('overflow without format', function (assert) {\n        assert.equal(flags('2001-01', 'YYYY-MM').overflow, -1, 'month 1 valid');\n        assert.equal(flags('2001-12', 'YYYY-MM').overflow, -1, 'month 12 valid');\n        assert.equal(flags('2001-13', 'YYYY-MM').overflow, 1, 'month 13 invalid');\n        assert.equal(flags('2010-01-16', 'YYYY-MM-DD').overflow, -1, 'date 16 valid');\n        assert.equal(flags('2010-01-0',  'YYYY-MM-DD').overflow, 2, 'date 0 invalid');\n        assert.equal(flags('2010-01-32', 'YYYY-MM-DD').overflow, 2, 'date 32 invalid');\n        assert.equal(flags('2012-02-29', 'YYYY-MM-DD').overflow, -1, 'date leap year valid');\n        assert.equal(flags('2010-02-29', 'YYYY-MM-DD').overflow, 2, 'date leap year invalid');\n        assert.equal(flags('2010 300', 'YYYY DDDD').overflow, -1, 'day 300 of year valid');\n        assert.equal(flags('2010 365', 'YYYY DDDD').overflow, -1, 'day 365 of year valid');\n        assert.equal(flags('2010 366', 'YYYY DDDD').overflow, 2, 'day 366 of year invalid');\n        assert.equal(flags('2012 366', 'YYYY DDDD').overflow, -1, 'day 366 of leap year valid');\n        assert.equal(flags('2012 367', 'YYYY DDDD').overflow, 2, 'day 367 of leap year invalid');\n        assert.equal(flags('08', 'HH').overflow, -1, 'hour valid');\n        assert.equal(flags('00', 'HH').overflow, -1, 'hour 0 valid');\n        assert.equal(flags('25', 'HH').overflow, 3, 'hour 25 invalid');\n        assert.equal(flags('24:01', 'HH:mm').overflow, 3, 'hour 24:01 invalid');\n        assert.equal(flags('08:15', 'HH:mm').overflow, -1, 'minute valid');\n        assert.equal(flags('08:00', 'HH:mm').overflow, -1, 'minute 0 valid');\n        assert.equal(flags('08:60', 'HH:mm').overflow, 4, 'minute 60 invalid');\n        assert.equal(flags('08:15:12', 'HH:mm:ss').overflow, -1, 'second valid');\n        assert.equal(flags('08:15:00', 'HH:mm:ss').overflow, -1, 'second 0 valid');\n        assert.equal(flags('08:15:60', 'HH:mm:ss').overflow, 5, 'second 60 invalid');\n        assert.equal(flags('08:15:12:345', 'HH:mm:ss:SSSS').overflow, -1, 'millisecond valid');\n        assert.equal(flags('08:15:12:000', 'HH:mm:ss:SSSS').overflow, -1, 'millisecond 0 valid');\n        assert.equal(flags('08:15:12:1000', 'HH:mm:ss:SSSS').overflow, -1, 'millisecond 1000 actually valid');\n    });\n\n    test('extra tokens', function (assert) {\n        assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD').unusedTokens, [], 'nothing extra');\n        assert.deepEqual(flags('1982-05', 'YYYY-MM-DD').unusedTokens, ['DD'], 'extra formatting token');\n        assert.deepEqual(flags('1982', 'YYYY-MM-DD').unusedTokens, ['MM', 'DD'], 'multiple extra formatting tokens');\n        assert.deepEqual(flags('1982-05', 'YYYY-MM-').unusedTokens, [], 'extra non-formatting token');\n        assert.deepEqual(flags('1982-05-', 'YYYY-MM-DD').unusedTokens, ['DD'], 'non-extra non-formatting token');\n        assert.deepEqual(flags('1982 05 1982', 'YYYY-MM-DD').unusedTokens, [], 'different non-formatting token');\n    });\n\n    test('extra tokens strict', function (assert) {\n        assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD', true).unusedTokens, [], 'nothing extra');\n        assert.deepEqual(flags('1982-05', 'YYYY-MM-DD', true).unusedTokens, ['-', 'DD'], 'extra formatting token');\n        assert.deepEqual(flags('1982', 'YYYY-MM-DD', true).unusedTokens, ['-', 'MM', '-', 'DD'], 'multiple extra formatting tokens');\n        assert.deepEqual(flags('1982-05', 'YYYY-MM-', true).unusedTokens, ['-'], 'extra non-formatting token');\n        assert.deepEqual(flags('1982-05-', 'YYYY-MM-DD', true).unusedTokens, ['DD'], 'non-extra non-formatting token');\n        assert.deepEqual(flags('1982 05 1982', 'YYYY-MM-DD', true).unusedTokens, ['-', '-'], 'different non-formatting token');\n    });\n\n    test('unused input', function (assert) {\n        assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD').unusedInput, [], 'normal input');\n        assert.deepEqual(flags('1982-05-25 this is more stuff', 'YYYY-MM-DD').unusedInput, [' this is more stuff'], 'trailing nonsense');\n        assert.deepEqual(flags('1982-05-25 09:30', 'YYYY-MM-DD').unusedInput, [' 09:30'], ['trailing legit-looking input']);\n        assert.deepEqual(flags('1982-05-25 some junk', 'YYYY-MM-DD [some junk]').unusedInput, [], 'junk that actually gets matched');\n        assert.deepEqual(flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD').unusedInput, ['stuff at beginning '], 'leading junk');\n        assert.deepEqual(flags('junk 1982 more junk 05 yet more junk25', 'YYYY-MM-DD').unusedInput, ['junk ', ' more junk ', ' yet more junk'], 'interstitial junk');\n    });\n\n    test('unused input strict', function (assert) {\n        assert.deepEqual(flags('1982-05-25', 'YYYY-MM-DD', true).unusedInput, [], 'normal input');\n        assert.deepEqual(flags('1982-05-25 this is more stuff', 'YYYY-MM-DD', true).unusedInput, [' this is more stuff'], 'trailing nonsense');\n        assert.deepEqual(flags('1982-05-25 09:30', 'YYYY-MM-DD', true).unusedInput, [' 09:30'], ['trailing legit-looking input']);\n        assert.deepEqual(flags('1982-05-25 some junk', 'YYYY-MM-DD [some junk]', true).unusedInput, [], 'junk that actually gets matched');\n        assert.deepEqual(flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD', true).unusedInput, ['stuff at beginning '], 'leading junk');\n        assert.deepEqual(flags('junk 1982 more junk 05 yet more junk25', 'YYYY-MM-DD', true).unusedInput, ['junk ', ' more junk ', ' yet more junk'], 'interstitial junk');\n    });\n\n    test('chars left over', function (assert) {\n        assert.equal(flags('1982-05-25', 'YYYY-MM-DD').charsLeftOver, 0, 'normal input');\n        assert.equal(flags('1982-05-25 this is more stuff', 'YYYY-MM-DD').charsLeftOver, ' this is more stuff'.length, 'trailing nonsense');\n        assert.equal(flags('1982-05-25 09:30', 'YYYY-MM-DD').charsLeftOver, ' 09:30'.length, 'trailing legit-looking input');\n        assert.equal(flags('stuff at beginning 1982-05-25', 'YYYY-MM-DD').charsLeftOver, 'stuff at beginning '.length, 'leading junk');\n        assert.equal(flags('1982 junk 05 more junk25', 'YYYY-MM-DD').charsLeftOver, [' junk ', ' more junk'].join('').length, 'interstitial junk');\n        assert.equal(flags('stuff at beginning 1982 junk 05 more junk25', 'YYYY-MM-DD').charsLeftOver, ['stuff at beginning ', ' junk ', ' more junk'].join('').length, 'leading and interstitial junk');\n    });\n\n    test('empty', function (assert) {\n        assert.equal(flags('1982-05-25', 'YYYY-MM-DD').empty, false, 'normal input');\n        assert.equal(flags('nothing here', 'YYYY-MM-DD').empty, true, 'pure garbage');\n        assert.equal(flags('junk but has the number 2000 in it', 'YYYY-MM-DD').empty, false, 'only mostly garbage');\n        assert.equal(flags('', 'YYYY-MM-DD').empty, true, 'empty string');\n        assert.equal(flags('', 'YYYY-MM-DD').empty, true, 'blank string');\n    });\n\n    test('null', function (assert) {\n        assert.equal(flags('1982-05-25', 'YYYY-MM-DD').nullInput, false, 'normal input');\n        assert.equal(flags(null).nullInput, true, 'just null');\n        assert.equal(flags(null, 'YYYY-MM-DD').nullInput, true, 'null with format');\n    });\n\n    test('invalid month', function (assert) {\n        assert.equal(flags('1982 May', 'YYYY MMMM').invalidMonth, null, 'normal input');\n        assert.equal(flags('1982 Laser', 'YYYY MMMM').invalidMonth, 'Laser', 'bad month name');\n    });\n\n    test('empty format array', function (assert) {\n        assert.equal(flags('1982 May', ['YYYY MMM']).invalidFormat, false, 'empty format array');\n        assert.equal(flags('1982 May', []).invalidFormat, true, 'empty format array');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    var symbolMap = {\n            '1': '!',\n            '2': '@',\n            '3': '#',\n            '4': '$',\n            '5': '%',\n            '6': '^',\n            '7': '&',\n            '8': '*',\n            '9': '(',\n            '0': ')'\n        },\n        numberMap = {\n            '!': '1',\n            '@': '2',\n            '#': '3',\n            '$': '4',\n            '%': '5',\n            '^': '6',\n            '&': '7',\n            '*': '8',\n            '(': '9',\n            ')': '0'\n        };\n\n    module('preparse and postformat', {\n        setup: function () {\n            moment.locale('symbol', {\n                preparse: function (string) {\n                    return string.replace(/[!@#$%\\^&*()]/g, function (match) {\n                        return numberMap[match];\n                    });\n                },\n\n                postformat: function (string) {\n                    return string.replace(/\\d/g, function (match) {\n                        return symbolMap[match];\n                    });\n                }\n            });\n        }\n    });\n\n    test('transform', function (assert) {\n        assert.equal(moment.utc('@)!@-)*-@&', 'YYYY-MM-DD').unix(), 1346025600, 'preparse string + format');\n        assert.equal(moment.utc('@)!@-)*-@&').unix(), 1346025600, 'preparse ISO8601 string');\n        assert.equal(moment.unix(1346025600).utc().format('YYYY-MM-DD'), '@)!@-)*-@&', 'postformat');\n    });\n\n    test('transform from', function (assert) {\n        var start = moment([2007, 1, 28]);\n\n        assert.equal(start.from(moment([2007, 1, 28]).add({s: 90}), true), '@ minutes', 'postformat should work on moment.fn.from');\n        assert.equal(moment().add(6, 'd').fromNow(true), '^ days', 'postformat should work on moment.fn.fromNow');\n        assert.equal(moment.duration(10, 'h').humanize(), '!) hours', 'postformat should work on moment.duration.fn.humanize');\n    });\n\n    test('calendar day', function (assert) {\n        var a = moment().hours(2).minutes(0).seconds(0);\n\n        assert.equal(moment(a).calendar(),                   'Today at @:)) AM',     'today at the same time');\n        assert.equal(moment(a).add({m: 25}).calendar(),      'Today at @:@% AM',     'Now plus 25 min');\n        assert.equal(moment(a).add({h: 1}).calendar(),       'Today at #:)) AM',     'Now plus 1 hour');\n        assert.equal(moment(a).add({d: 1}).calendar(),       'Tomorrow at @:)) AM',  'tomorrow at the same time');\n        assert.equal(moment(a).subtract({h: 1}).calendar(),  'Today at !:)) AM',     'Now minus 1 hour');\n        assert.equal(moment(a).subtract({d: 1}).calendar(),  'Yesterday at @:)) AM', 'yesterday at the same time');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('quarter');\n\n    test('library quarter getter', function (assert) {\n        assert.equal(moment([1985,  1,  4]).quarter(), 1, 'Feb  4 1985 is Q1');\n        assert.equal(moment([2029,  8, 18]).quarter(), 3, 'Sep 18 2029 is Q3');\n        assert.equal(moment([2013,  3, 24]).quarter(), 2, 'Apr 24 2013 is Q2');\n        assert.equal(moment([2015,  2,  5]).quarter(), 1, 'Mar  5 2015 is Q1');\n        assert.equal(moment([1970,  0,  2]).quarter(), 1, 'Jan  2 1970 is Q1');\n        assert.equal(moment([2001, 11, 12]).quarter(), 4, 'Dec 12 2001 is Q4');\n        assert.equal(moment([2000,  0,  2]).quarter(), 1, 'Jan  2 2000 is Q1');\n    });\n\n    test('quarter setter singular', function (assert) {\n        var m = moment([2014, 4, 11]);\n        assert.equal(m.quarter(2).month(), 4, 'set same quarter');\n        assert.equal(m.quarter(3).month(), 7, 'set 3rd quarter');\n        assert.equal(m.quarter(1).month(), 1, 'set 1st quarter');\n        assert.equal(m.quarter(4).month(), 10, 'set 4th quarter');\n    });\n\n    test('quarter setter plural', function (assert) {\n        var m = moment([2014, 4, 11]);\n        assert.equal(m.quarters(2).month(), 4, 'set same quarter');\n        assert.equal(m.quarters(3).month(), 7, 'set 3rd quarter');\n        assert.equal(m.quarters(1).month(), 1, 'set 1st quarter');\n        assert.equal(m.quarters(4).month(), 10, 'set 4th quarter');\n    });\n\n    test('quarter setter programmatic', function (assert) {\n        var m = moment([2014, 4, 11]);\n        assert.equal(m.set('quarter', 2).month(), 4, 'set same quarter');\n        assert.equal(m.set('quarter', 3).month(), 7, 'set 3rd quarter');\n        assert.equal(m.set('quarter', 1).month(), 1, 'set 1st quarter');\n        assert.equal(m.set('quarter', 4).month(), 10, 'set 4th quarter');\n    });\n\n    test('quarter setter programmatic plural', function (assert) {\n        var m = moment([2014, 4, 11]);\n        assert.equal(m.set('quarters', 2).month(), 4, 'set same quarter');\n        assert.equal(m.set('quarters', 3).month(), 7, 'set 3rd quarter');\n        assert.equal(m.set('quarters', 1).month(), 1, 'set 1st quarter');\n        assert.equal(m.set('quarters', 4).month(), 10, 'set 4th quarter');\n    });\n\n    test('quarter setter programmatic abbr', function (assert) {\n        var m = moment([2014, 4, 11]);\n        assert.equal(m.set('Q', 2).month(), 4, 'set same quarter');\n        assert.equal(m.set('Q', 3).month(), 7, 'set 3rd quarter');\n        assert.equal(m.set('Q', 1).month(), 1, 'set 1st quarter');\n        assert.equal(m.set('Q', 4).month(), 10, 'set 4th quarter');\n    });\n\n    test('quarter setter only month changes', function (assert) {\n        var m = moment([2014, 4, 11, 1, 2, 3, 4]).quarter(4);\n        assert.equal(m.year(), 2014, 'keep year');\n        assert.equal(m.month(), 10, 'set month');\n        assert.equal(m.date(), 11, 'keep date');\n        assert.equal(m.hour(), 1, 'keep hour');\n        assert.equal(m.minute(), 2, 'keep minutes');\n        assert.equal(m.second(), 3, 'keep seconds');\n        assert.equal(m.millisecond(), 4, 'keep milliseconds');\n    });\n\n    test('quarter setter bubble to next year', function (assert) {\n        var m = moment([2014, 4, 11, 1, 2, 3, 4]).quarter(7);\n        assert.equal(m.year(), 2015, 'year bubbled');\n        assert.equal(m.month(), 7, 'set month');\n        assert.equal(m.date(), 11, 'keep date');\n        assert.equal(m.hour(), 1, 'keep hour');\n        assert.equal(m.minute(), 2, 'keep minutes');\n        assert.equal(m.second(), 3, 'keep seconds');\n        assert.equal(m.millisecond(), 4, 'keep milliseconds');\n    });\n\n    test('quarter diff', function (assert) {\n        assert.equal(moment('2014-01-01').diff(moment('2014-04-01'), 'quarter'),\n                -1, 'diff -1 quarter');\n        assert.equal(moment('2014-04-01').diff(moment('2014-01-01'), 'quarter'),\n                1, 'diff 1 quarter');\n        assert.equal(moment('2014-05-01').diff(moment('2014-01-01'), 'quarter'),\n                1, 'diff 1 quarter');\n        assert.ok(Math.abs((4 / 3) - moment('2014-05-01').diff(\n                        moment('2014-01-01'), 'quarter', true)) < 0.00001,\n                'diff 1 1/3 quarter');\n        assert.equal(moment('2015-01-01').diff(moment('2014-01-01'), 'quarter'),\n                4, 'diff 4 quarters');\n    });\n\n    test('quarter setter bubble to previous year', function (assert) {\n        var m = moment([2014, 4, 11, 1, 2, 3, 4]).quarter(-3);\n        assert.equal(m.year(), 2013, 'year bubbled');\n        assert.equal(m.month(), 1, 'set month');\n        assert.equal(m.date(), 11, 'keep date');\n        assert.equal(m.hour(), 1, 'keep hour');\n        assert.equal(m.minute(), 2, 'keep minutes');\n        assert.equal(m.second(), 3, 'keep seconds');\n        assert.equal(m.millisecond(), 4, 'keep milliseconds');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('relative time');\n\n    test('default thresholds', function (assert) {\n        var a = moment();\n        a.subtract(44, 'seconds');\n        assert.equal(a.fromNow(), 'a few seconds ago', 'Below default seconds to minutes threshold');\n        a.subtract(1, 'seconds');\n        assert.equal(a.fromNow(), 'a minute ago', 'Above default seconds to minutes threshold');\n        a = moment();\n        a.subtract(44, 'minutes');\n        assert.equal(a.fromNow(), '44 minutes ago', 'Below default minute to hour threshold');\n        a.subtract(1, 'minutes');\n        assert.equal(a.fromNow(), 'an hour ago', 'Above default minute to hour threshold');\n        a = moment();\n        a.subtract(21, 'hours');\n        assert.equal(a.fromNow(), '21 hours ago', 'Below default hours to day threshold');\n        a.subtract(1, 'hours');\n        assert.equal(a.fromNow(), 'a day ago', 'Above default hours to day threshold');\n        a = moment();\n        a.subtract(25, 'days');\n        assert.equal(a.fromNow(), '25 days ago', 'Below default days to month (singular) threshold');\n        a.subtract(1, 'days');\n        assert.equal(a.fromNow(), 'a month ago', 'Above default days to month (singular) threshold');\n        a = moment();\n        a.subtract(10, 'months');\n        assert.equal(a.fromNow(), '10 months ago', 'Below default days to years threshold');\n        a.subtract(1, 'month');\n        assert.equal(a.fromNow(), 'a year ago', 'Above default days to years threshold');\n    });\n\n    test('custom thresholds', function (assert) {\n        moment.relativeTimeThreshold('s', 55);\n\n        var a = moment();\n        a.subtract(54, 'seconds');\n        assert.equal(a.fromNow(), 'a few seconds ago', 'Below custom seconds to minutes threshold');\n        a.subtract(1, 'seconds');\n        assert.equal(a.fromNow(), 'a minute ago', 'Above custom seconds to minutes threshold');\n\n        moment.relativeTimeThreshold('s', 45);\n        moment.relativeTimeThreshold('m', 55);\n        a = moment();\n        a.subtract(54, 'minutes');\n        assert.equal(a.fromNow(), '54 minutes ago', 'Below custom minutes to hours threshold');\n        a.subtract(1, 'minutes');\n        assert.equal(a.fromNow(), 'an hour ago', 'Above custom minutes to hours threshold');\n        moment.relativeTimeThreshold('m', 45);\n        moment.relativeTimeThreshold('h', 24);\n        a = moment();\n        a.subtract(23, 'hours');\n        assert.equal(a.fromNow(), '23 hours ago', 'Below custom hours to days threshold');\n        a.subtract(1, 'hours');\n        assert.equal(a.fromNow(), 'a day ago', 'Above custom hours to days threshold');\n        moment.relativeTimeThreshold('h', 22);\n        moment.relativeTimeThreshold('d', 28);\n        a = moment();\n        a.subtract(27, 'days');\n        assert.equal(a.fromNow(), '27 days ago', 'Below custom days to month (singular) threshold');\n        a.subtract(1, 'days');\n        assert.equal(a.fromNow(), 'a month ago', 'Above custom days to month (singular) threshold');\n        moment.relativeTimeThreshold('d', 26);\n        moment.relativeTimeThreshold('M', 9);\n        a = moment();\n        a.subtract(8, 'months');\n        assert.equal(a.fromNow(), '8 months ago', 'Below custom days to years threshold');\n        a.subtract(1, 'months');\n        assert.equal(a.fromNow(), 'a year ago', 'Above custom days to years threshold');\n        moment.relativeTimeThreshold('M', 11);\n    });\n\n    test('retrive threshold settings', function (assert) {\n        moment.relativeTimeThreshold('m', 45);\n        var minuteThreshold = moment.relativeTimeThreshold('m');\n\n        assert.equal(minuteThreshold, 45, 'Can retrieve minute setting');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('start and end of units');\n\n    test('start of year', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('year'),\n            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('years'),\n            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('y');\n        assert.equal(+m, +ms, 'Plural or singular should work');\n        assert.equal(+m, +ma, 'Full or abbreviated should work');\n        assert.equal(m.year(), 2011, 'keep the year');\n        assert.equal(m.month(), 0, 'strip out the month');\n        assert.equal(m.date(), 1, 'strip out the day');\n        assert.equal(m.hours(), 0, 'strip out the hours');\n        assert.equal(m.minutes(), 0, 'strip out the minutes');\n        assert.equal(m.seconds(), 0, 'strip out the seconds');\n        assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n    });\n\n    test('end of year', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('year'),\n            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('years'),\n            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('y');\n        assert.equal(+m, +ms, 'Plural or singular should work');\n        assert.equal(+m, +ma, 'Full or abbreviated should work');\n        assert.equal(m.year(), 2011, 'keep the year');\n        assert.equal(m.month(), 11, 'set the month');\n        assert.equal(m.date(), 31, 'set the day');\n        assert.equal(m.hours(), 23, 'set the hours');\n        assert.equal(m.minutes(), 59, 'set the minutes');\n        assert.equal(m.seconds(), 59, 'set the seconds');\n        assert.equal(m.milliseconds(), 999, 'set the seconds');\n    });\n\n    test('start of quarter', function (assert) {\n        var m = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).startOf('quarter'),\n            ms = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).startOf('quarters'),\n            ma = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).startOf('Q');\n        assert.equal(+m, +ms, 'Plural or singular should work');\n        assert.equal(+m, +ma, 'Full or abbreviated should work');\n        assert.equal(m.year(), 2011, 'keep the year');\n        assert.equal(m.quarter(), 2, 'keep the quarter');\n        assert.equal(m.month(), 3, 'strip out the month');\n        assert.equal(m.date(), 1, 'strip out the day');\n        assert.equal(m.hours(), 0, 'strip out the hours');\n        assert.equal(m.minutes(), 0, 'strip out the minutes');\n        assert.equal(m.seconds(), 0, 'strip out the seconds');\n        assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n    });\n\n    test('end of quarter', function (assert) {\n        var m = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).endOf('quarter'),\n            ms = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).endOf('quarters'),\n            ma = moment(new Date(2011, 4, 2, 3, 4, 5, 6)).endOf('Q');\n        assert.equal(+m, +ms, 'Plural or singular should work');\n        assert.equal(+m, +ma, 'Full or abbreviated should work');\n        assert.equal(m.year(), 2011, 'keep the year');\n        assert.equal(m.quarter(), 2, 'keep the quarter');\n        assert.equal(m.month(), 5, 'set the month');\n        assert.equal(m.date(), 30, 'set the day');\n        assert.equal(m.hours(), 23, 'set the hours');\n        assert.equal(m.minutes(), 59, 'set the minutes');\n        assert.equal(m.seconds(), 59, 'set the seconds');\n        assert.equal(m.milliseconds(), 999, 'set the seconds');\n    });\n\n    test('start of month', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('month'),\n            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('months'),\n            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('M');\n        assert.equal(+m, +ms, 'Plural or singular should work');\n        assert.equal(+m, +ma, 'Full or abbreviated should work');\n        assert.equal(m.year(), 2011, 'keep the year');\n        assert.equal(m.month(), 1, 'keep the month');\n        assert.equal(m.date(), 1, 'strip out the day');\n        assert.equal(m.hours(), 0, 'strip out the hours');\n        assert.equal(m.minutes(), 0, 'strip out the minutes');\n        assert.equal(m.seconds(), 0, 'strip out the seconds');\n        assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n    });\n\n    test('end of month', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('month'),\n            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('months'),\n            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('M');\n        assert.equal(+m, +ms, 'Plural or singular should work');\n        assert.equal(+m, +ma, 'Full or abbreviated should work');\n        assert.equal(m.year(), 2011, 'keep the year');\n        assert.equal(m.month(), 1, 'keep the month');\n        assert.equal(m.date(), 28, 'set the day');\n        assert.equal(m.hours(), 23, 'set the hours');\n        assert.equal(m.minutes(), 59, 'set the minutes');\n        assert.equal(m.seconds(), 59, 'set the seconds');\n        assert.equal(m.milliseconds(), 999, 'set the seconds');\n    });\n\n    test('start of week', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('week'),\n            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('weeks'),\n            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('w');\n        assert.equal(+m, +ms, 'Plural or singular should work');\n        assert.equal(+m, +ma, 'Full or abbreviated should work');\n        assert.equal(m.year(), 2011, 'keep the year');\n        assert.equal(m.month(), 0, 'rolls back to January');\n        assert.equal(m.day(), 0, 'set day of week');\n        assert.equal(m.date(), 30, 'set correct date');\n        assert.equal(m.hours(), 0, 'strip out the hours');\n        assert.equal(m.minutes(), 0, 'strip out the minutes');\n        assert.equal(m.seconds(), 0, 'strip out the seconds');\n        assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n    });\n\n    test('end of week', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('week'),\n            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('weeks'),\n            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('weeks');\n        assert.equal(+m, +ms, 'Plural or singular should work');\n        assert.equal(+m, +ma, 'Full or abbreviated should work');\n        assert.equal(m.year(), 2011, 'keep the year');\n        assert.equal(m.month(), 1, 'keep the month');\n        assert.equal(m.day(), 6, 'set the day of the week');\n        assert.equal(m.date(), 5, 'set the day');\n        assert.equal(m.hours(), 23, 'set the hours');\n        assert.equal(m.minutes(), 59, 'set the minutes');\n        assert.equal(m.seconds(), 59, 'set the seconds');\n        assert.equal(m.milliseconds(), 999, 'set the seconds');\n    });\n\n    test('start of iso-week', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('isoWeek'),\n            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('isoWeeks'),\n            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('W');\n        assert.equal(+m, +ms, 'Plural or singular should work');\n        assert.equal(+m, +ma, 'Full or abbreviated should work');\n        assert.equal(m.year(), 2011, 'keep the year');\n        assert.equal(m.month(), 0, 'rollback to January');\n        assert.equal(m.isoWeekday(), 1, 'set day of iso-week');\n        assert.equal(m.date(), 31, 'set correct date');\n        assert.equal(m.hours(), 0, 'strip out the hours');\n        assert.equal(m.minutes(), 0, 'strip out the minutes');\n        assert.equal(m.seconds(), 0, 'strip out the seconds');\n        assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n    });\n\n    test('end of iso-week', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('isoWeek'),\n            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('isoWeeks'),\n            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('W');\n        assert.equal(+m, +ms, 'Plural or singular should work');\n        assert.equal(+m, +ma, 'Full or abbreviated should work');\n        assert.equal(m.year(), 2011, 'keep the year');\n        assert.equal(m.month(), 1, 'keep the month');\n        assert.equal(m.isoWeekday(), 7, 'set the day of the week');\n        assert.equal(m.date(), 6, 'set the day');\n        assert.equal(m.hours(), 23, 'set the hours');\n        assert.equal(m.minutes(), 59, 'set the minutes');\n        assert.equal(m.seconds(), 59, 'set the seconds');\n        assert.equal(m.milliseconds(), 999, 'set the seconds');\n    });\n\n    test('start of day', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('day'),\n            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('days'),\n            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('d');\n        assert.equal(+m, +ms, 'Plural or singular should work');\n        assert.equal(+m, +ma, 'Full or abbreviated should work');\n        assert.equal(m.year(), 2011, 'keep the year');\n        assert.equal(m.month(), 1, 'keep the month');\n        assert.equal(m.date(), 2, 'keep the day');\n        assert.equal(m.hours(), 0, 'strip out the hours');\n        assert.equal(m.minutes(), 0, 'strip out the minutes');\n        assert.equal(m.seconds(), 0, 'strip out the seconds');\n        assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n    });\n\n    test('end of day', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('day'),\n            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('days'),\n            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('d');\n        assert.equal(+m, +ms, 'Plural or singular should work');\n        assert.equal(+m, +ma, 'Full or abbreviated should work');\n        assert.equal(m.year(), 2011, 'keep the year');\n        assert.equal(m.month(), 1, 'keep the month');\n        assert.equal(m.date(), 2, 'keep the day');\n        assert.equal(m.hours(), 23, 'set the hours');\n        assert.equal(m.minutes(), 59, 'set the minutes');\n        assert.equal(m.seconds(), 59, 'set the seconds');\n        assert.equal(m.milliseconds(), 999, 'set the seconds');\n    });\n\n    test('start of hour', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('hour'),\n            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('hours'),\n            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('h');\n        assert.equal(+m, +ms, 'Plural or singular should work');\n        assert.equal(+m, +ma, 'Full or abbreviated should work');\n        assert.equal(m.year(), 2011, 'keep the year');\n        assert.equal(m.month(), 1, 'keep the month');\n        assert.equal(m.date(), 2, 'keep the day');\n        assert.equal(m.hours(), 3, 'keep the hours');\n        assert.equal(m.minutes(), 0, 'strip out the minutes');\n        assert.equal(m.seconds(), 0, 'strip out the seconds');\n        assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n    });\n\n    test('end of hour', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('hour'),\n            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('hours'),\n            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('h');\n        assert.equal(+m, +ms, 'Plural or singular should work');\n        assert.equal(+m, +ma, 'Full or abbreviated should work');\n        assert.equal(m.year(), 2011, 'keep the year');\n        assert.equal(m.month(), 1, 'keep the month');\n        assert.equal(m.date(), 2, 'keep the day');\n        assert.equal(m.hours(), 3, 'keep the hours');\n        assert.equal(m.minutes(), 59, 'set the minutes');\n        assert.equal(m.seconds(), 59, 'set the seconds');\n        assert.equal(m.milliseconds(), 999, 'set the seconds');\n    });\n\n    test('start of minute', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('minute'),\n            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('minutes'),\n            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('m');\n        assert.equal(+m, +ms, 'Plural or singular should work');\n        assert.equal(+m, +ma, 'Full or abbreviated should work');\n        assert.equal(m.year(), 2011, 'keep the year');\n        assert.equal(m.month(), 1, 'keep the month');\n        assert.equal(m.date(), 2, 'keep the day');\n        assert.equal(m.hours(), 3, 'keep the hours');\n        assert.equal(m.minutes(), 4, 'keep the minutes');\n        assert.equal(m.seconds(), 0, 'strip out the seconds');\n        assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n    });\n\n    test('end of minute', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('minute'),\n            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('minutes'),\n            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('m');\n        assert.equal(+m, +ms, 'Plural or singular should work');\n        assert.equal(+m, +ma, 'Full or abbreviated should work');\n        assert.equal(m.year(), 2011, 'keep the year');\n        assert.equal(m.month(), 1, 'keep the month');\n        assert.equal(m.date(), 2, 'keep the day');\n        assert.equal(m.hours(), 3, 'keep the hours');\n        assert.equal(m.minutes(), 4, 'keep the minutes');\n        assert.equal(m.seconds(), 59, 'set the seconds');\n        assert.equal(m.milliseconds(), 999, 'set the seconds');\n    });\n\n    test('start of second', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('second'),\n            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('seconds'),\n            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).startOf('s');\n        assert.equal(+m, +ms, 'Plural or singular should work');\n        assert.equal(+m, +ma, 'Full or abbreviated should work');\n        assert.equal(m.year(), 2011, 'keep the year');\n        assert.equal(m.month(), 1, 'keep the month');\n        assert.equal(m.date(), 2, 'keep the day');\n        assert.equal(m.hours(), 3, 'keep the hours');\n        assert.equal(m.minutes(), 4, 'keep the minutes');\n        assert.equal(m.seconds(), 5, 'keep the the seconds');\n        assert.equal(m.milliseconds(), 0, 'strip out the milliseconds');\n    });\n\n    test('end of second', function (assert) {\n        var m = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('second'),\n            ms = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('seconds'),\n            ma = moment(new Date(2011, 1, 2, 3, 4, 5, 6)).endOf('s');\n        assert.equal(+m, +ms, 'Plural or singular should work');\n        assert.equal(+m, +ma, 'Full or abbreviated should work');\n        assert.equal(m.year(), 2011, 'keep the year');\n        assert.equal(m.month(), 1, 'keep the month');\n        assert.equal(m.date(), 2, 'keep the day');\n        assert.equal(m.hours(), 3, 'keep the hours');\n        assert.equal(m.minutes(), 4, 'keep the minutes');\n        assert.equal(m.seconds(), 5, 'keep the seconds');\n        assert.equal(m.milliseconds(), 999, 'set the seconds');\n    });\n\n    test('startOf across DST +1', function (assert) {\n        var oldUpdateOffset = moment.updateOffset,\n            dstAt = moment('2014-03-09T02:00:00-08:00').parseZone(),\n            m;\n\n        moment.updateOffset = function (mom, keepTime) {\n            if (mom.isBefore(dstAt)) {\n                mom.utcOffset(-8, keepTime);\n            } else {\n                mom.utcOffset(-7, keepTime);\n            }\n        };\n\n        m = moment('2014-03-15T00:00:00-07:00').parseZone();\n        m.startOf('M');\n        assert.equal(m.format(), '2014-03-01T00:00:00-08:00', 'startOf(\\'month\\') across +1');\n\n        m = moment('2014-03-09T09:00:00-07:00').parseZone();\n        m.startOf('d');\n        assert.equal(m.format(), '2014-03-09T00:00:00-08:00', 'startOf(\\'day\\') across +1');\n\n        m = moment('2014-03-09T03:05:00-07:00').parseZone();\n        m.startOf('h');\n        assert.equal(m.format(), '2014-03-09T03:00:00-07:00', 'startOf(\\'hour\\') after +1');\n\n        m = moment('2014-03-09T01:35:00-08:00').parseZone();\n        m.startOf('h');\n        assert.equal(m.format(), '2014-03-09T01:00:00-08:00', 'startOf(\\'hour\\') before +1');\n\n        moment.updateOffset = oldUpdateOffset;\n    });\n\n    test('startOf across DST -1', function (assert) {\n        var oldUpdateOffset = moment.updateOffset,\n            dstAt = moment('2014-11-02T02:00:00-07:00').parseZone(),\n            m;\n\n        moment.updateOffset = function (mom, keepTime) {\n            if (mom.isBefore(dstAt)) {\n                mom.utcOffset(-7, keepTime);\n            } else {\n                mom.utcOffset(-8, keepTime);\n            }\n        };\n\n        m = moment('2014-11-15T00:00:00-08:00').parseZone();\n        m.startOf('M');\n        assert.equal(m.format(), '2014-11-01T00:00:00-07:00', 'startOf(\\'month\\') across -1');\n\n        m = moment('2014-11-02T09:00:00-08:00').parseZone();\n        m.startOf('d');\n        assert.equal(m.format(), '2014-11-02T00:00:00-07:00', 'startOf(\\'day\\') across -1');\n        m = moment('2014-11-02T01:30:00-08:00').parseZone();\n        m.startOf('h');\n        assert.equal(m.format(), '2014-11-02T01:00:00-08:00', 'startOf(\\'hour\\') after +1');\n        m = moment('2014-11-02T01:30:00-07:00').parseZone();\n        m.startOf('h');\n        assert.equal(m.format(), '2014-11-02T01:00:00-07:00', 'startOf(\\'hour\\') before +1');\n\n        moment.updateOffset = oldUpdateOffset;\n    });\n\n    test('endOf millisecond and no-arg', function (assert) {\n        var m = moment();\n        assert.equal(+m, +m.clone().endOf(), 'endOf without argument should change time');\n        assert.equal(+m, +m.clone().endOf('ms'), 'endOf with ms argument should change time');\n        assert.equal(+m, +m.clone().endOf('millisecond'), 'endOf with millisecond argument should change time');\n        assert.equal(+m, +m.clone().endOf('milliseconds'), 'endOf with milliseconds argument should change time');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('string prototype');\n\n    test('string prototype overrides call', function (assert) {\n        var prior = String.prototype.call, b;\n        String.prototype.call = function () {\n            return null;\n        };\n\n        b = moment(new Date(2011, 7, 28, 15, 25, 50, 125));\n        assert.equal(b.format('MMMM Do YYYY, h:mm a'), 'August 28th 2011, 3:25 pm');\n\n        String.prototype.call = prior;\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('utc');\n\n    test('utc and local', function (assert) {\n        var m = moment(Date.UTC(2011, 1, 2, 3, 4, 5, 6)), offset, expected;\n        m.utc();\n        assert.equal(m.date(), 2, 'the day should be correct for utc');\n        assert.equal(m.day(), 3, 'the date should be correct for utc');\n        assert.equal(m.hours(), 3, 'the hours should be correct for utc');\n        m.local();\n        if (m.zone() > 180) {\n            assert.equal(m.date(), 1, 'the date should be correct for local');\n            assert.equal(m.day(), 2, 'the day should be correct for local');\n        } else {\n            assert.equal(m.date(), 2, 'the date should be correct for local');\n            assert.equal(m.day(), 3, 'the day should be correct for local');\n        }\n        offset = Math.ceil(m.utcOffset() / 60);\n        expected = (24 + 3 + offset) % 24;\n        assert.equal(m.hours(), expected, 'the hours (' + m.hours() + ') should be correct for local');\n        assert.equal(moment().utc().utcOffset(), 0, 'timezone in utc should always be zero');\n    });\n\n    test('creating with utc and no arguments', function (assert) {\n        var startOfTest = new Date().valueOf(),\n            momentDefaultUtcTime = moment.utc().valueOf(),\n            afterMomentCreationTime = new Date().valueOf();\n\n        assert.ok(startOfTest <= momentDefaultUtcTime, 'moment UTC default time should be now, not in the past');\n        assert.ok(momentDefaultUtcTime <= afterMomentCreationTime, 'moment UTC default time should be now, not in the future');\n    });\n\n    test('creating with utc and a date parameter array', function (assert) {\n        var m = moment.utc([2011, 1, 2, 3, 4, 5, 6]);\n        assert.equal(m.date(), 2, 'the day should be correct for utc array');\n        assert.equal(m.hours(), 3, 'the hours should be correct for utc array');\n\n        m = moment.utc('2011-02-02 3:04:05', 'YYYY-MM-DD HH:mm:ss');\n        assert.equal(m.date(), 2, 'the day should be correct for utc parsing format');\n        assert.equal(m.hours(), 3, 'the hours should be correct for utc parsing format');\n\n        m = moment.utc('2011-02-02T03:04:05+00:00');\n        assert.equal(m.date(), 2, 'the day should be correct for utc parsing iso');\n        assert.equal(m.hours(), 3, 'the hours should be correct for utc parsing iso');\n    });\n\n    test('creating with utc without timezone', function (assert) {\n        var m = moment.utc('2012-01-02T08:20:00');\n        assert.equal(m.date(), 2, 'the day should be correct for utc parse without timezone');\n        assert.equal(m.hours(), 8, 'the hours should be correct for utc parse without timezone');\n\n        m = moment.utc('2012-01-02T08:20:00+09:00');\n        assert.equal(m.date(), 1, 'the day should be correct for utc parse with timezone');\n        assert.equal(m.hours(), 23, 'the hours should be correct for utc parse with timezone');\n    });\n\n    test('cloning with utc offset', function (assert) {\n        var m = moment.utc('2012-01-02T08:20:00');\n        assert.equal(moment.utc(m)._isUTC, true, 'the local offset should be converted to UTC');\n        assert.equal(moment.utc(m.clone().utc())._isUTC, true, 'the local offset should stay in UTC');\n\n        m.utcOffset(120);\n        assert.equal(moment.utc(m)._isUTC, true, 'the explicit utc offset should stay in UTC');\n        assert.equal(moment.utc(m).utcOffset(), 0, 'the explicit utc offset should have an offset of 0');\n    });\n\n    test('weekday with utc', function (assert) {\n        assert.equal(\n            moment('2013-09-15T00:00:00Z').utc().weekday(), // first minute of the day\n            moment('2013-09-15T23:59:00Z').utc().weekday(), // last minute of the day\n            'a UTC-moment\\'s .weekday() should not be affected by the local timezone'\n        );\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('utc offset');\n\n    test('setter / getter blackbox', function (assert) {\n        var m = moment([2010]);\n\n        assert.equal(m.clone().utcOffset(0).utcOffset(), 0, 'utcOffset 0');\n\n        assert.equal(m.clone().utcOffset(1).utcOffset(), 60, 'utcOffset 1 is 60');\n        assert.equal(m.clone().utcOffset(60).utcOffset(), 60, 'utcOffset 60');\n        assert.equal(m.clone().utcOffset('+01:00').utcOffset(), 60, 'utcOffset +01:00 is 60');\n        assert.equal(m.clone().utcOffset('+0100').utcOffset(), 60, 'utcOffset +0100 is 60');\n\n        assert.equal(m.clone().utcOffset(-1).utcOffset(), -60, 'utcOffset -1 is -60');\n        assert.equal(m.clone().utcOffset(-60).utcOffset(), -60, 'utcOffset -60');\n        assert.equal(m.clone().utcOffset('-01:00').utcOffset(), -60, 'utcOffset -01:00 is -60');\n        assert.equal(m.clone().utcOffset('-0100').utcOffset(), -60, 'utcOffset -0100 is -60');\n\n        assert.equal(m.clone().utcOffset(1.5).utcOffset(), 90, 'utcOffset 1.5 is 90');\n        assert.equal(m.clone().utcOffset(90).utcOffset(), 90, 'utcOffset 1.5 is 90');\n        assert.equal(m.clone().utcOffset('+01:30').utcOffset(), 90, 'utcOffset +01:30 is 90');\n        assert.equal(m.clone().utcOffset('+0130').utcOffset(), 90, 'utcOffset +0130 is 90');\n\n        assert.equal(m.clone().utcOffset(-1.5).utcOffset(), -90, 'utcOffset -1.5');\n        assert.equal(m.clone().utcOffset(-90).utcOffset(), -90, 'utcOffset -90');\n        assert.equal(m.clone().utcOffset('-01:30').utcOffset(), -90, 'utcOffset +01:30 is 90');\n        assert.equal(m.clone().utcOffset('-0130').utcOffset(), -90, 'utcOffset +0130 is 90');\n    });\n\n    test('utcOffset shorthand hours -> minutes', function (assert) {\n        var i;\n        for (i = -15; i <= 15; ++i) {\n            assert.equal(moment().utcOffset(i).utcOffset(), i * 60,\n                    '' + i + ' -> ' + i * 60);\n        }\n        assert.equal(moment().utcOffset(-16).utcOffset(), -16, '-16 -> -16');\n        assert.equal(moment().utcOffset(16).utcOffset(), 16, '16 -> 16');\n    });\n\n    test('isLocal, isUtc, isUtcOffset', function (assert) {\n        assert.ok(moment().isLocal(), 'moment() creates objects in local time');\n        assert.ok(!moment.utc().isLocal(), 'moment.utc creates objects NOT in local time');\n        assert.ok(moment.utc().local().isLocal(), 'moment.fn.local() converts to local time');\n        assert.ok(!moment().utcOffset(5).isLocal(), 'moment.fn.utcOffset(N) puts objects NOT in local time');\n        assert.ok(moment().utcOffset(5).local().isLocal(), 'moment.fn.local() converts to local time');\n\n        assert.ok(moment.utc().isUtc(), 'moment.utc() creates objects in utc time');\n        assert.ok(moment().utcOffset(0).isUtc(), 'utcOffset(0) is equivalent to utc mode');\n        assert.ok(!moment().utcOffset(1).isUtc(), 'utcOffset(1) is NOT equivalent to utc mode');\n\n        assert.ok(!moment().isUtcOffset(), 'moment() creates objects NOT in utc-offset mode');\n        assert.ok(moment.utc().isUtcOffset(), 'moment.utc() creates objects in utc-offset mode');\n        assert.ok(moment().utcOffset(3).isUtcOffset(), 'utcOffset(N != 0) creates objects in utc-offset mode');\n        assert.ok(moment().utcOffset(0).isUtcOffset(), 'utcOffset(0) creates objects in utc-offset mode');\n    });\n\n    test('isUTC', function (assert) {\n        assert.ok(moment.utc().isUTC(), 'moment.utc() creates objects in utc time');\n        assert.ok(moment().utcOffset(0).isUTC(), 'utcOffset(0) is equivalent to utc mode');\n        assert.ok(!moment().utcOffset(1).isUTC(), 'utcOffset(1) is NOT equivalent to utc mode');\n    });\n\n    test('change hours when changing the utc offset', function (assert) {\n        var m = moment.utc([2000, 0, 1, 6]);\n        assert.equal(m.hour(), 6, 'UTC 6AM should be 6AM at +0000');\n        m.utcOffset(0);\n        assert.equal(m.hour(), 6, 'UTC 6AM should be 6AM at +0000');\n\n        m.utcOffset(-60);\n        assert.equal(m.hour(), 5, 'UTC 6AM should be 5AM at -0100');\n\n        m.utcOffset(60);\n        assert.equal(m.hour(), 7, 'UTC 6AM should be 7AM at +0100');\n    });\n\n    test('change minutes when changing the utc offset', function (assert) {\n        var m = moment.utc([2000, 0, 1, 6, 31]);\n\n        m.utcOffset(0);\n        assert.equal(m.format('HH:mm'), '06:31', 'UTC 6:31AM should be 6:31AM at +0000');\n\n        m.utcOffset(-30);\n        assert.equal(m.format('HH:mm'), '06:01', 'UTC 6:31AM should be 6:01AM at -0030');\n\n        m.utcOffset(30);\n        assert.equal(m.format('HH:mm'), '07:01', 'UTC 6:31AM should be 7:01AM at +0030');\n\n        m.utcOffset(-1380);\n        assert.equal(m.format('HH:mm'), '07:31', 'UTC 6:31AM should be 7:31AM at +1380');\n    });\n\n    test('distance from the unix epoch', function (assert) {\n        var zoneA = moment(),\n            zoneB = moment(zoneA),\n            zoneC = moment(zoneA),\n            zoneD = moment(zoneA),\n            zoneE = moment(zoneA);\n\n        zoneB.utc();\n        assert.equal(+zoneA, +zoneB, 'moment should equal moment.utc');\n\n        zoneC.utcOffset(60);\n        assert.equal(+zoneA, +zoneC, 'moment should equal moment.utcOffset(60)');\n\n        zoneD.utcOffset(-480);\n        assert.equal(+zoneA, +zoneD,\n                'moment should equal moment.utcOffset(-480)');\n\n        zoneE.utcOffset(-1000);\n        assert.equal(+zoneA, +zoneE,\n                'moment should equal moment.utcOffset(-1000)');\n    });\n\n    test('update offset after changing any values', function (assert) {\n        var oldOffset = moment.updateOffset,\n            m = moment.utc([2000, 6, 1]);\n\n        moment.updateOffset = function (mom, keepTime) {\n            if (mom.__doChange) {\n                if (+mom > 962409600000) {\n                    mom.utcOffset(-120, keepTime);\n                } else {\n                    mom.utcOffset(-60, keepTime);\n                }\n            }\n        };\n\n        assert.equal(m.format('ZZ'), '+0000', 'should be at +0000');\n        assert.equal(m.format('HH:mm'), '00:00', 'should start 12AM at +0000 timezone');\n\n        m.__doChange = true;\n        m.add(1, 'h');\n\n        assert.equal(m.format('ZZ'), '-0200', 'should be at -0200');\n        assert.equal(m.format('HH:mm'), '23:00', '1AM at +0000 should be 11PM at -0200 timezone');\n\n        m.subtract(1, 'h');\n\n        assert.equal(m.format('ZZ'), '-0100', 'should be at -0100');\n        assert.equal(m.format('HH:mm'), '23:00', '12AM at +0000 should be 11PM at -0100 timezone');\n\n        moment.updateOffset = oldOffset;\n    });\n    test('getters and setters', function (assert) {\n        var a = moment([2011, 5, 20]);\n\n        assert.equal(a.clone().utcOffset(-120).year(2012).year(), 2012, 'should get and set year correctly');\n        assert.equal(a.clone().utcOffset(-120).month(1).month(), 1, 'should get and set month correctly');\n        assert.equal(a.clone().utcOffset(-120).date(2).date(), 2, 'should get and set date correctly');\n        assert.equal(a.clone().utcOffset(-120).day(1).day(), 1, 'should get and set day correctly');\n        assert.equal(a.clone().utcOffset(-120).hour(1).hour(), 1, 'should get and set hour correctly');\n        assert.equal(a.clone().utcOffset(-120).minute(1).minute(), 1, 'should get and set minute correctly');\n    });\n\n    test('getters', function (assert) {\n        var a = moment.utc([2012, 0, 1, 0, 0, 0]);\n\n        assert.equal(a.clone().utcOffset(-120).year(),  2011, 'should get year correctly');\n        assert.equal(a.clone().utcOffset(-120).month(),   11, 'should get month correctly');\n        assert.equal(a.clone().utcOffset(-120).date(),    31, 'should get date correctly');\n        assert.equal(a.clone().utcOffset(-120).hour(),    22, 'should get hour correctly');\n        assert.equal(a.clone().utcOffset(-120).minute(),   0, 'should get minute correctly');\n\n        assert.equal(a.clone().utcOffset(120).year(),  2012, 'should get year correctly');\n        assert.equal(a.clone().utcOffset(120).month(),    0, 'should get month correctly');\n        assert.equal(a.clone().utcOffset(120).date(),     1, 'should get date correctly');\n        assert.equal(a.clone().utcOffset(120).hour(),     2, 'should get hour correctly');\n        assert.equal(a.clone().utcOffset(120).minute(),   0, 'should get minute correctly');\n\n        assert.equal(a.clone().utcOffset(90).year(),  2012, 'should get year correctly');\n        assert.equal(a.clone().utcOffset(90).month(),    0, 'should get month correctly');\n        assert.equal(a.clone().utcOffset(90).date(),     1, 'should get date correctly');\n        assert.equal(a.clone().utcOffset(90).hour(),     1, 'should get hour correctly');\n        assert.equal(a.clone().utcOffset(90).minute(),  30, 'should get minute correctly');\n    });\n\n    test('from', function (assert) {\n        var zoneA = moment(),\n            zoneB = moment(zoneA).utcOffset(-720),\n            zoneC = moment(zoneA).utcOffset(-360),\n            zoneD = moment(zoneA).utcOffset(690),\n            other = moment(zoneA).add(35, 'm');\n\n        assert.equal(zoneA.from(other), zoneB.from(other), 'moment#from should be the same in all zones');\n        assert.equal(zoneA.from(other), zoneC.from(other), 'moment#from should be the same in all zones');\n        assert.equal(zoneA.from(other), zoneD.from(other), 'moment#from should be the same in all zones');\n    });\n\n    test('diff', function (assert) {\n        var zoneA = moment(),\n            zoneB = moment(zoneA).utcOffset(-720),\n            zoneC = moment(zoneA).utcOffset(-360),\n            zoneD = moment(zoneA).utcOffset(690),\n            other = moment(zoneA).add(35, 'm');\n\n        assert.equal(zoneA.diff(other), zoneB.diff(other), 'moment#diff should be the same in all zones');\n        assert.equal(zoneA.diff(other), zoneC.diff(other), 'moment#diff should be the same in all zones');\n        assert.equal(zoneA.diff(other), zoneD.diff(other), 'moment#diff should be the same in all zones');\n\n        assert.equal(zoneA.diff(other, 'minute', true), zoneB.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n        assert.equal(zoneA.diff(other, 'minute', true), zoneC.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n        assert.equal(zoneA.diff(other, 'minute', true), zoneD.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n\n        assert.equal(zoneA.diff(other, 'hour', true), zoneB.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n        assert.equal(zoneA.diff(other, 'hour', true), zoneC.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n        assert.equal(zoneA.diff(other, 'hour', true), zoneD.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n    });\n\n    test('unix offset and timestamp', function (assert) {\n        var zoneA = moment(),\n            zoneB = moment(zoneA).utcOffset(-720),\n            zoneC = moment(zoneA).utcOffset(-360),\n            zoneD = moment(zoneA).utcOffset(690);\n\n        assert.equal(zoneA.unix(), zoneB.unix(), 'moment#unix should be the same in all zones');\n        assert.equal(zoneA.unix(), zoneC.unix(), 'moment#unix should be the same in all zones');\n        assert.equal(zoneA.unix(), zoneD.unix(), 'moment#unix should be the same in all zones');\n\n        assert.equal(+zoneA, +zoneB, 'moment#valueOf should be the same in all zones');\n        assert.equal(+zoneA, +zoneC, 'moment#valueOf should be the same in all zones');\n        assert.equal(+zoneA, +zoneD, 'moment#valueOf should be the same in all zones');\n    });\n\n    test('cloning', function (assert) {\n        assert.equal(moment().utcOffset(-120).clone().utcOffset(), -120,\n                'explicit cloning should retain the offset');\n        assert.equal(moment().utcOffset(120).clone().utcOffset(), 120,\n                'explicit cloning should retain the offset');\n        assert.equal(moment(moment().utcOffset(-120)).utcOffset(), -120,\n                'implicit cloning should retain the offset');\n        assert.equal(moment(moment().utcOffset(120)).utcOffset(), 120,\n                'implicit cloning should retain the offset');\n    });\n\n    test('start of / end of', function (assert) {\n        var a = moment.utc([2010, 1, 2, 0, 0, 0]).utcOffset(-450);\n\n        assert.equal(a.clone().startOf('day').hour(), 0,\n                'start of day should work on moments with utc offset');\n        assert.equal(a.clone().startOf('day').minute(), 0,\n                'start of day should work on moments with utc offset');\n        assert.equal(a.clone().startOf('hour').minute(), 0,\n                'start of hour should work on moments with utc offset');\n\n        assert.equal(a.clone().endOf('day').hour(), 23,\n                'end of day should work on moments with utc offset');\n        assert.equal(a.clone().endOf('day').minute(), 59,\n                'end of day should work on moments with utc offset');\n        assert.equal(a.clone().endOf('hour').minute(), 59,\n                'end of hour should work on moments with utc offset');\n    });\n\n    test('reset offset with moment#utc', function (assert) {\n        var a = moment.utc([2012]).utcOffset(-480);\n\n        assert.equal(a.clone().hour(),      16, 'different utc offset should have different hour');\n        assert.equal(a.clone().utc().hour(), 0, 'calling moment#utc should reset the offset');\n    });\n\n    test('reset offset with moment#local', function (assert) {\n        var a = moment([2012]).utcOffset(-480);\n\n        assert.equal(a.clone().local().hour(), 0, 'calling moment#local should reset the offset');\n    });\n\n    test('toDate', function (assert) {\n        var zoneA = new Date(),\n            zoneB = moment(zoneA).utcOffset(-720).toDate(),\n            zoneC = moment(zoneA).utcOffset(-360).toDate(),\n            zoneD = moment(zoneA).utcOffset(690).toDate();\n\n        assert.equal(+zoneA, +zoneB, 'moment#toDate should output a date with the right unix timestamp');\n        assert.equal(+zoneA, +zoneC, 'moment#toDate should output a date with the right unix timestamp');\n        assert.equal(+zoneA, +zoneD, 'moment#toDate should output a date with the right unix timestamp');\n    });\n\n    test('same / before / after', function (assert) {\n        var zoneA = moment().utc(),\n            zoneB = moment(zoneA).utcOffset(-120),\n            zoneC = moment(zoneA).utcOffset(120);\n\n        assert.ok(zoneA.isSame(zoneB), 'two moments with different offsets should be the same');\n        assert.ok(zoneA.isSame(zoneC), 'two moments with different offsets should be the same');\n\n        assert.ok(zoneA.isSame(zoneB, 'hour'), 'two moments with different offsets should be the same hour');\n        assert.ok(zoneA.isSame(zoneC, 'hour'), 'two moments with different offsets should be the same hour');\n\n        zoneA.add(1, 'hour');\n\n        assert.ok(zoneA.isAfter(zoneB), 'isAfter should work with two moments with different offsets');\n        assert.ok(zoneA.isAfter(zoneC), 'isAfter should work with two moments with different offsets');\n\n        assert.ok(zoneA.isAfter(zoneB, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n        assert.ok(zoneA.isAfter(zoneC, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n\n        zoneA.subtract(2, 'hour');\n\n        assert.ok(zoneA.isBefore(zoneB), 'isBefore should work with two moments with different offsets');\n        assert.ok(zoneA.isBefore(zoneC), 'isBefore should work with two moments with different offsets');\n\n        assert.ok(zoneA.isBefore(zoneB, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n        assert.ok(zoneA.isBefore(zoneC, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n    });\n\n    test('add / subtract over dst', function (assert) {\n        var oldOffset = moment.updateOffset,\n            m = moment.utc([2000, 2, 31, 3]);\n\n        moment.updateOffset = function (mom, keepTime) {\n            if (mom.clone().utc().month() > 2) {\n                mom.utcOffset(60, keepTime);\n            } else {\n                mom.utcOffset(0, keepTime);\n            }\n        };\n\n        assert.equal(m.hour(), 3, 'should start at 00:00');\n\n        m.add(24, 'hour');\n\n        assert.equal(m.hour(), 4, 'adding 24 hours should disregard dst');\n\n        m.subtract(24, 'hour');\n\n        assert.equal(m.hour(), 3, 'subtracting 24 hours should disregard dst');\n\n        m.add(1, 'day');\n\n        assert.equal(m.hour(), 3, 'adding 1 day should have the same hour');\n\n        m.subtract(1, 'day');\n\n        assert.equal(m.hour(), 3, 'subtracting 1 day should have the same hour');\n\n        m.add(1, 'month');\n\n        assert.equal(m.hour(), 3, 'adding 1 month should have the same hour');\n\n        m.subtract(1, 'month');\n\n        assert.equal(m.hour(), 3, 'subtracting 1 month should have the same hour');\n\n        moment.updateOffset = oldOffset;\n    });\n\n    test('isDST', function (assert) {\n        var oldOffset = moment.updateOffset;\n\n        moment.updateOffset = function (mom, keepTime) {\n            if (mom.month() > 2 && mom.month() < 9) {\n                mom.utcOffset(60, keepTime);\n            } else {\n                mom.utcOffset(0, keepTime);\n            }\n        };\n\n        assert.ok(!moment().month(0).isDST(),  'Jan should not be summer dst');\n        assert.ok(moment().month(6).isDST(),   'Jul should be summer dst');\n        assert.ok(!moment().month(11).isDST(), 'Dec should not be summer dst');\n\n        moment.updateOffset = function (mom) {\n            if (mom.month() > 2 && mom.month() < 9) {\n                mom.utcOffset(0);\n            } else {\n                mom.utcOffset(60);\n            }\n        };\n\n        assert.ok(moment().month(0).isDST(),  'Jan should be winter dst');\n        assert.ok(!moment().month(6).isDST(), 'Jul should not be winter dst');\n        assert.ok(moment().month(11).isDST(), 'Dec should be winter dst');\n\n        moment.updateOffset = oldOffset;\n    });\n\n    test('zone names', function (assert) {\n        assert.equal(moment().zoneAbbr(),   '', 'Local zone abbr should be empty');\n        assert.equal(moment().format('z'),  '', 'Local zone formatted abbr should be empty');\n        assert.equal(moment().zoneName(),   '', 'Local zone name should be empty');\n        assert.equal(moment().format('zz'), '', 'Local zone formatted name should be empty');\n\n        assert.equal(moment.utc().zoneAbbr(),   'UTC', 'UTC zone abbr should be UTC');\n        assert.equal(moment.utc().format('z'),  'UTC', 'UTC zone formatted abbr should be UTC');\n        assert.equal(moment.utc().zoneName(),   'Coordinated Universal Time', 'UTC zone abbr should be Coordinated Universal Time');\n        assert.equal(moment.utc().format('zz'), 'Coordinated Universal Time', 'UTC zone formatted abbr should be Coordinated Universal Time');\n    });\n\n    test('hours alignment with UTC', function (assert) {\n        assert.equal(moment().utcOffset(-120).hasAlignedHourOffset(), true);\n        assert.equal(moment().utcOffset(180).hasAlignedHourOffset(), true);\n        assert.equal(moment().utcOffset(-90).hasAlignedHourOffset(), false);\n        assert.equal(moment().utcOffset(90).hasAlignedHourOffset(), false);\n    });\n\n    test('hours alignment with other zone', function (assert) {\n        var m = moment().utcOffset(-120);\n\n        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-180)), true);\n        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(180)), true);\n        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-90)), false);\n        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(90)), false);\n\n        m = moment().utcOffset(-90);\n\n        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-180)), false);\n        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(180)), false);\n        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-30)), true);\n        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(30)), true);\n\n        m = moment().utcOffset(60);\n\n        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-180)), true);\n        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(180)), true);\n        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-90)), false);\n        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(90)), false);\n\n        m = moment().utcOffset(-25);\n\n        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(35)), true);\n        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-85)), true);\n\n        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(-35)), false);\n        assert.equal(m.hasAlignedHourOffset(moment().utcOffset(85)), false);\n    });\n\n    test('parse zone', function (assert) {\n        var m = moment('2013-01-01T00:00:00-13:00').parseZone();\n        assert.equal(m.utcOffset(), -13 * 60);\n        assert.equal(m.hours(), 0);\n    });\n\n    test('parse zone static', function (assert) {\n        var m = moment.parseZone('2013-01-01T00:00:00-13:00');\n        assert.equal(m.utcOffset(), -13 * 60);\n        assert.equal(m.hours(), 0);\n    });\n\n    test('parse zone with more arguments', function (assert) {\n        var m;\n        m = moment.parseZone('2013 01 01 05 -13:00', 'YYYY MM DD HH ZZ');\n        assert.equal(m.format(), '2013-01-01T05:00:00-13:00', 'accept input and format');\n        m = moment.parseZone('2013-01-01-13:00', 'YYYY MM DD ZZ', true);\n        assert.equal(m.isValid(), false, 'accept input, format and strict flag');\n        m = moment.parseZone('2013-01-01-13:00', ['DD MM YYYY ZZ', 'YYYY MM DD ZZ']);\n        assert.equal(m.format(), '2013-01-01T00:00:00-13:00', 'accept input and array of formats');\n    });\n\n    test('parse zone with a timezone from the format string', function (assert) {\n        var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY ZZ #####').parseZone();\n\n        assert.equal(m.utcOffset(), -4 * 60);\n    });\n\n    test('parse zone without a timezone included in the format string', function (assert) {\n        var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY').parseZone();\n\n        assert.equal(m.utcOffset(), 11 * 60);\n    });\n\n    test('timezone format', function (assert) {\n        assert.equal(moment().utcOffset(60).format('ZZ'), '+0100', '-60 -> +0100');\n        assert.equal(moment().utcOffset(90).format('ZZ'), '+0130', '-90 -> +0130');\n        assert.equal(moment().utcOffset(120).format('ZZ'), '+0200', '-120 -> +0200');\n\n        assert.equal(moment().utcOffset(-60).format('ZZ'), '-0100', '+60 -> -0100');\n        assert.equal(moment().utcOffset(-90).format('ZZ'), '-0130', '+90 -> -0130');\n        assert.equal(moment().utcOffset(-120).format('ZZ'), '-0200', '+120 -> -0200');\n    });\n\n    test('local to utc, keepLocalTime = true', function (assert) {\n        var m = moment(),\n            fmt = 'YYYY-DD-MM HH:mm:ss';\n        assert.equal(m.clone().utc(true).format(fmt), m.format(fmt), 'local to utc failed to keep local time');\n    });\n\n    test('local to utc, keepLocalTime = false', function (assert) {\n        var m = moment();\n        assert.equal(m.clone().utc().valueOf(), m.valueOf(), 'local to utc failed to keep utc time (implicit)');\n        assert.equal(m.clone().utc(false).valueOf(), m.valueOf(), 'local to utc failed to keep utc time (explicit)');\n    });\n\n    test('local to zone, keepLocalTime = true', function (assert) {\n        var m = moment(),\n            fmt = 'YYYY-DD-MM HH:mm:ss',\n            z;\n        for (z = -12; z <= 14; ++z) {\n            assert.equal(m.clone().utcOffset(z * 60, true).format(fmt),\n                    m.format(fmt),\n                    'local to utcOffset(' + z + ':00) failed to keep local time');\n        }\n    });\n\n    test('local to zone, keepLocalTime = false', function (assert) {\n        var m = moment(),\n            z;\n        for (z = -12; z <= 14; ++z) {\n            assert.equal(m.clone().utcOffset(z * 60).valueOf(),\n                    m.valueOf(),\n                    'local to utcOffset(' + z + ':00) failed to keep utc time (implicit)');\n            assert.equal(m.clone().utcOffset(z * 60, false).valueOf(),\n                    m.valueOf(),\n                    'local to utcOffset(' + z + ':00) failed to keep utc time (explicit)');\n        }\n    });\n\n    test('utc to local, keepLocalTime = true', function (assert) {\n        var um = moment.utc(),\n            fmt = 'YYYY-DD-MM HH:mm:ss';\n\n        assert.equal(um.clone().local(true).format(fmt), um.format(fmt), 'utc to local failed to keep local time');\n    });\n\n    test('utc to local, keepLocalTime = false', function (assert) {\n        var um = moment.utc();\n        assert.equal(um.clone().local().valueOf(), um.valueOf(), 'utc to local failed to keep utc time (implicit)');\n        assert.equal(um.clone().local(false).valueOf(), um.valueOf(), 'utc to local failed to keep utc time (explicit)');\n    });\n\n    test('zone to local, keepLocalTime = true', function (assert) {\n        var m = moment(),\n            fmt = 'YYYY-DD-MM HH:mm:ss',\n            z;\n        for (z = -12; z <= 14; ++z) {\n            m.utcOffset(z * 60);\n\n            assert.equal(m.clone().local(true).format(fmt),\n                    m.format(fmt),\n                    'utcOffset(' + z + ':00) to local failed to keep local time');\n        }\n    });\n\n    test('zone to local, keepLocalTime = false', function (assert) {\n        var m = moment(),\n            z;\n        for (z = -12; z <= 14; ++z) {\n            m.utcOffset(z * 60);\n\n            assert.equal(m.clone().local(false).valueOf(), m.valueOf(),\n                    'utcOffset(' + z + ':00) to local failed to keep utc time (explicit)');\n            assert.equal(m.clone().local().valueOf(), m.valueOf(),\n                    'utcOffset(' + z + ':00) to local failed to keep utc time (implicit)');\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('week year');\n\n    test('iso week year', function (assert) {\n        assert.equal(moment([2005, 0, 1]).isoWeekYear(), 2004);\n        assert.equal(moment([2005, 0, 2]).isoWeekYear(), 2004);\n        assert.equal(moment([2005, 0, 3]).isoWeekYear(), 2005);\n        assert.equal(moment([2005, 11, 31]).isoWeekYear(), 2005);\n        assert.equal(moment([2006, 0, 1]).isoWeekYear(), 2005);\n        assert.equal(moment([2006, 0, 2]).isoWeekYear(), 2006);\n        assert.equal(moment([2007, 0, 1]).isoWeekYear(), 2007);\n        assert.equal(moment([2007, 11, 30]).isoWeekYear(), 2007);\n        assert.equal(moment([2007, 11, 31]).isoWeekYear(), 2008);\n        assert.equal(moment([2008, 0, 1]).isoWeekYear(), 2008);\n        assert.equal(moment([2008, 11, 28]).isoWeekYear(), 2008);\n        assert.equal(moment([2008, 11, 29]).isoWeekYear(), 2009);\n        assert.equal(moment([2008, 11, 30]).isoWeekYear(), 2009);\n        assert.equal(moment([2008, 11, 31]).isoWeekYear(), 2009);\n        assert.equal(moment([2009, 0, 1]).isoWeekYear(), 2009);\n        assert.equal(moment([2010, 0, 1]).isoWeekYear(), 2009);\n        assert.equal(moment([2010, 0, 2]).isoWeekYear(), 2009);\n        assert.equal(moment([2010, 0, 3]).isoWeekYear(), 2009);\n        assert.equal(moment([2010, 0, 4]).isoWeekYear(), 2010);\n    });\n\n    test('week year', function (assert) {\n        moment.locale('dow: 1,doy: 4', {week: {dow: 1, doy: 4}}); // like iso\n        assert.equal(moment([2005, 0, 1]).weekYear(), 2004);\n        assert.equal(moment([2005, 0, 2]).weekYear(), 2004);\n        assert.equal(moment([2005, 0, 3]).weekYear(), 2005);\n        assert.equal(moment([2005, 11, 31]).weekYear(), 2005);\n        assert.equal(moment([2006, 0, 1]).weekYear(), 2005);\n        assert.equal(moment([2006, 0, 2]).weekYear(), 2006);\n        assert.equal(moment([2007, 0, 1]).weekYear(), 2007);\n        assert.equal(moment([2007, 11, 30]).weekYear(), 2007);\n        assert.equal(moment([2007, 11, 31]).weekYear(), 2008);\n        assert.equal(moment([2008, 0, 1]).weekYear(), 2008);\n        assert.equal(moment([2008, 11, 28]).weekYear(), 2008);\n        assert.equal(moment([2008, 11, 29]).weekYear(), 2009);\n        assert.equal(moment([2008, 11, 30]).weekYear(), 2009);\n        assert.equal(moment([2008, 11, 31]).weekYear(), 2009);\n        assert.equal(moment([2009, 0, 1]).weekYear(), 2009);\n        assert.equal(moment([2010, 0, 1]).weekYear(), 2009);\n        assert.equal(moment([2010, 0, 2]).weekYear(), 2009);\n        assert.equal(moment([2010, 0, 3]).weekYear(), 2009);\n        assert.equal(moment([2010, 0, 4]).weekYear(), 2010);\n\n        moment.locale('dow: 1,doy: 7', {week: {dow: 1, doy: 7}});\n        assert.equal(moment([2004, 11, 26]).weekYear(), 2004);\n        assert.equal(moment([2004, 11, 27]).weekYear(), 2005);\n        assert.equal(moment([2005, 11, 25]).weekYear(), 2005);\n        assert.equal(moment([2005, 11, 26]).weekYear(), 2006);\n        assert.equal(moment([2006, 11, 31]).weekYear(), 2006);\n        assert.equal(moment([2007,  0,  1]).weekYear(), 2007);\n        assert.equal(moment([2007, 11, 30]).weekYear(), 2007);\n        assert.equal(moment([2007, 11, 31]).weekYear(), 2008);\n        assert.equal(moment([2008, 11, 28]).weekYear(), 2008);\n        assert.equal(moment([2008, 11, 29]).weekYear(), 2009);\n        assert.equal(moment([2009, 11, 27]).weekYear(), 2009);\n        assert.equal(moment([2009, 11, 28]).weekYear(), 2010);\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('week day');\n\n    test('iso weekday', function (assert) {\n        var i;\n\n        for (i = 0; i < 7; ++i) {\n            moment.locale('dow:' + i + ',doy: 6', {week: {dow: i, doy: 6}});\n            assert.equal(moment([1985, 1,  4]).isoWeekday(), 1, 'Feb  4 1985 is Monday    -- 1st day');\n            assert.equal(moment([2029, 8, 18]).isoWeekday(), 2, 'Sep 18 2029 is Tuesday   -- 2nd day');\n            assert.equal(moment([2013, 3, 24]).isoWeekday(), 3, 'Apr 24 2013 is Wednesday -- 3rd day');\n            assert.equal(moment([2015, 2,  5]).isoWeekday(), 4, 'Mar  5 2015 is Thursday  -- 4th day');\n            assert.equal(moment([1970, 0,  2]).isoWeekday(), 5, 'Jan  2 1970 is Friday    -- 5th day');\n            assert.equal(moment([2001, 4, 12]).isoWeekday(), 6, 'May 12 2001 is Saturday  -- 6th day');\n            assert.equal(moment([2000, 0,  2]).isoWeekday(), 7, 'Jan  2 2000 is Sunday    -- 7th day');\n        }\n    });\n\n    test('iso weekday setter', function (assert) {\n        var a = moment([2011, 0, 10]);\n        assert.equal(moment(a).isoWeekday(1).date(),  10, 'set from mon to mon');\n        assert.equal(moment(a).isoWeekday(4).date(),  13, 'set from mon to thu');\n        assert.equal(moment(a).isoWeekday(7).date(),  16, 'set from mon to sun');\n        assert.equal(moment(a).isoWeekday(-6).date(),  3, 'set from mon to last mon');\n        assert.equal(moment(a).isoWeekday(-3).date(),  6, 'set from mon to last thu');\n        assert.equal(moment(a).isoWeekday(0).date(),   9, 'set from mon to last sun');\n        assert.equal(moment(a).isoWeekday(8).date(),  17, 'set from mon to next mon');\n        assert.equal(moment(a).isoWeekday(11).date(), 20, 'set from mon to next thu');\n        assert.equal(moment(a).isoWeekday(14).date(), 23, 'set from mon to next sun');\n\n        a = moment([2011, 0, 13]);\n        assert.equal(moment(a).isoWeekday(1).date(), 10, 'set from thu to mon');\n        assert.equal(moment(a).isoWeekday(4).date(), 13, 'set from thu to thu');\n        assert.equal(moment(a).isoWeekday(7).date(), 16, 'set from thu to sun');\n        assert.equal(moment(a).isoWeekday(-6).date(),  3, 'set from thu to last mon');\n        assert.equal(moment(a).isoWeekday(-3).date(),  6, 'set from thu to last thu');\n        assert.equal(moment(a).isoWeekday(0).date(),   9, 'set from thu to last sun');\n        assert.equal(moment(a).isoWeekday(8).date(),  17, 'set from thu to next mon');\n        assert.equal(moment(a).isoWeekday(11).date(), 20, 'set from thu to next thu');\n        assert.equal(moment(a).isoWeekday(14).date(), 23, 'set from thu to next sun');\n\n        a = moment([2011, 0, 16]);\n        assert.equal(moment(a).isoWeekday(1).date(), 10, 'set from sun to mon');\n        assert.equal(moment(a).isoWeekday(4).date(), 13, 'set from sun to thu');\n        assert.equal(moment(a).isoWeekday(7).date(), 16, 'set from sun to sun');\n        assert.equal(moment(a).isoWeekday(-6).date(),  3, 'set from sun to last mon');\n        assert.equal(moment(a).isoWeekday(-3).date(),  6, 'set from sun to last thu');\n        assert.equal(moment(a).isoWeekday(0).date(),   9, 'set from sun to last sun');\n        assert.equal(moment(a).isoWeekday(8).date(),  17, 'set from sun to next mon');\n        assert.equal(moment(a).isoWeekday(11).date(), 20, 'set from sun to next thu');\n        assert.equal(moment(a).isoWeekday(14).date(), 23, 'set from sun to next sun');\n    });\n\n    test('weekday first day of week Sunday (dow 0)', function (assert) {\n        moment.locale('dow: 0,doy: 6', {week: {dow: 0, doy: 6}});\n        assert.equal(moment([1985, 1,  3]).weekday(), 0, 'Feb  3 1985 is Sunday    -- 0th day');\n        assert.equal(moment([2029, 8, 17]).weekday(), 1, 'Sep 17 2029 is Monday    -- 1st day');\n        assert.equal(moment([2013, 3, 23]).weekday(), 2, 'Apr 23 2013 is Tuesday   -- 2nd day');\n        assert.equal(moment([2015, 2,  4]).weekday(), 3, 'Mar  4 2015 is Wednesday -- 3nd day');\n        assert.equal(moment([1970, 0,  1]).weekday(), 4, 'Jan  1 1970 is Thursday  -- 4th day');\n        assert.equal(moment([2001, 4, 11]).weekday(), 5, 'May 11 2001 is Friday    -- 5th day');\n        assert.equal(moment([2000, 0,  1]).weekday(), 6, 'Jan  1 2000 is Saturday  -- 6th day');\n    });\n\n    test('weekday first day of week Monday (dow 1)', function (assert) {\n        moment.locale('dow: 1,doy: 6', {week: {dow: 1, doy: 6}});\n        assert.equal(moment([1985, 1,  4]).weekday(), 0, 'Feb  4 1985 is Monday    -- 0th day');\n        assert.equal(moment([2029, 8, 18]).weekday(), 1, 'Sep 18 2029 is Tuesday   -- 1st day');\n        assert.equal(moment([2013, 3, 24]).weekday(), 2, 'Apr 24 2013 is Wednesday -- 2nd day');\n        assert.equal(moment([2015, 2,  5]).weekday(), 3, 'Mar  5 2015 is Thursday  -- 3nd day');\n        assert.equal(moment([1970, 0,  2]).weekday(), 4, 'Jan  2 1970 is Friday    -- 4th day');\n        assert.equal(moment([2001, 4, 12]).weekday(), 5, 'May 12 2001 is Saturday  -- 5th day');\n        assert.equal(moment([2000, 0,  2]).weekday(), 6, 'Jan  2 2000 is Sunday    -- 6th day');\n    });\n\n    test('weekday first day of week Tuesday (dow 2)', function (assert) {\n        moment.locale('dow: 2,doy: 6', {week: {dow: 2, doy: 6}});\n        assert.equal(moment([1985, 1,  5]).weekday(), 0, 'Feb  5 1985 is Tuesday   -- 0th day');\n        assert.equal(moment([2029, 8, 19]).weekday(), 1, 'Sep 19 2029 is Wednesday -- 1st day');\n        assert.equal(moment([2013, 3, 25]).weekday(), 2, 'Apr 25 2013 is Thursday  -- 2nd day');\n        assert.equal(moment([2015, 2,  6]).weekday(), 3, 'Mar  6 2015 is Friday    -- 3nd day');\n        assert.equal(moment([1970, 0,  3]).weekday(), 4, 'Jan  3 1970 is Staturday -- 4th day');\n        assert.equal(moment([2001, 4, 13]).weekday(), 5, 'May 13 2001 is Sunday    -- 5th day');\n        assert.equal(moment([2000, 0,  3]).weekday(), 6, 'Jan  3 2000 is Monday    -- 6th day');\n    });\n\n    test('weekday first day of week Wednesday (dow 3)', function (assert) {\n        moment.locale('dow: 3,doy: 6', {week: {dow: 3, doy: 6}});\n        assert.equal(moment([1985, 1,  6]).weekday(), 0, 'Feb  6 1985 is Wednesday -- 0th day');\n        assert.equal(moment([2029, 8, 20]).weekday(), 1, 'Sep 20 2029 is Thursday  -- 1st day');\n        assert.equal(moment([2013, 3, 26]).weekday(), 2, 'Apr 26 2013 is Friday    -- 2nd day');\n        assert.equal(moment([2015, 2,  7]).weekday(), 3, 'Mar  7 2015 is Saturday  -- 3nd day');\n        assert.equal(moment([1970, 0,  4]).weekday(), 4, 'Jan  4 1970 is Sunday    -- 4th day');\n        assert.equal(moment([2001, 4, 14]).weekday(), 5, 'May 14 2001 is Monday    -- 5th day');\n        assert.equal(moment([2000, 0,  4]).weekday(), 6, 'Jan  4 2000 is Tuesday   -- 6th day');\n        moment.locale('dow:3,doy:6', null);\n    });\n\n    test('weekday first day of week Thursday (dow 4)', function (assert) {\n        moment.locale('dow: 4,doy: 6', {week: {dow: 4, doy: 6}});\n        assert.equal(moment([1985, 1,  7]).weekday(), 0, 'Feb  7 1985 is Thursday  -- 0th day');\n        assert.equal(moment([2029, 8, 21]).weekday(), 1, 'Sep 21 2029 is Friday    -- 1st day');\n        assert.equal(moment([2013, 3, 27]).weekday(), 2, 'Apr 27 2013 is Saturday  -- 2nd day');\n        assert.equal(moment([2015, 2,  8]).weekday(), 3, 'Mar  8 2015 is Sunday    -- 3nd day');\n        assert.equal(moment([1970, 0,  5]).weekday(), 4, 'Jan  5 1970 is Monday    -- 4th day');\n        assert.equal(moment([2001, 4, 15]).weekday(), 5, 'May 15 2001 is Tuesday   -- 5th day');\n        assert.equal(moment([2000, 0,  5]).weekday(), 6, 'Jan  5 2000 is Wednesday -- 6th day');\n    });\n\n    test('weekday first day of week Friday (dow 5)', function (assert) {\n        moment.locale('dow: 5,doy: 6', {week: {dow: 5, doy: 6}});\n        assert.equal(moment([1985, 1,  8]).weekday(), 0, 'Feb  8 1985 is Friday    -- 0th day');\n        assert.equal(moment([2029, 8, 22]).weekday(), 1, 'Sep 22 2029 is Staturday -- 1st day');\n        assert.equal(moment([2013, 3, 28]).weekday(), 2, 'Apr 28 2013 is Sunday    -- 2nd day');\n        assert.equal(moment([2015, 2,  9]).weekday(), 3, 'Mar  9 2015 is Monday    -- 3nd day');\n        assert.equal(moment([1970, 0,  6]).weekday(), 4, 'Jan  6 1970 is Tuesday   -- 4th day');\n        assert.equal(moment([2001, 4, 16]).weekday(), 5, 'May 16 2001 is Wednesday -- 5th day');\n        assert.equal(moment([2000, 0,  6]).weekday(), 6, 'Jan  6 2000 is Thursday  -- 6th day');\n    });\n\n    test('weekday first day of week Saturday (dow 6)', function (assert) {\n        moment.locale('dow: 6,doy: 6', {week: {dow: 6, doy: 6}});\n        assert.equal(moment([1985, 1,  9]).weekday(), 0, 'Feb  9 1985 is Staturday -- 0th day');\n        assert.equal(moment([2029, 8, 23]).weekday(), 1, 'Sep 23 2029 is Sunday    -- 1st day');\n        assert.equal(moment([2013, 3, 29]).weekday(), 2, 'Apr 29 2013 is Monday    -- 2nd day');\n        assert.equal(moment([2015, 2, 10]).weekday(), 3, 'Mar 10 2015 is Tuesday   -- 3nd day');\n        assert.equal(moment([1970, 0,  7]).weekday(), 4, 'Jan  7 1970 is Wednesday -- 4th day');\n        assert.equal(moment([2001, 4, 17]).weekday(), 5, 'May 17 2001 is Thursday  -- 5th day');\n        assert.equal(moment([2000, 0,  7]).weekday(), 6, 'Jan  7 2000 is Friday    -- 6th day');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('weeks');\n\n    test('day of year', function (assert) {\n        assert.equal(moment([2000,  0,  1]).dayOfYear(),   1, 'Jan  1 2000 should be day 1 of the year');\n        assert.equal(moment([2000,  1, 28]).dayOfYear(),  59, 'Feb 28 2000 should be day 59 of the year');\n        assert.equal(moment([2000,  1, 29]).dayOfYear(),  60, 'Feb 28 2000 should be day 60 of the year');\n        assert.equal(moment([2000, 11, 31]).dayOfYear(), 366, 'Dec 31 2000 should be day 366 of the year');\n        assert.equal(moment([2001,  0,  1]).dayOfYear(),   1, 'Jan  1 2001 should be day 1 of the year');\n        assert.equal(moment([2001,  1, 28]).dayOfYear(),  59, 'Feb 28 2001 should be day 59 of the year');\n        assert.equal(moment([2001,  2,  1]).dayOfYear(),  60, 'Mar  1 2001 should be day 60 of the year');\n        assert.equal(moment([2001, 11, 31]).dayOfYear(), 365, 'Dec 31 2001 should be day 365 of the year');\n    });\n\n    test('day of year setters', function (assert) {\n        assert.equal(moment([2000,  0,  1]).dayOfYear(200).dayOfYear(), 200, 'Setting Jan  1 2000 day of the year to 200 should work');\n        assert.equal(moment([2000,  1, 28]).dayOfYear(200).dayOfYear(), 200, 'Setting Feb 28 2000 day of the year to 200 should work');\n        assert.equal(moment([2000,  1, 29]).dayOfYear(200).dayOfYear(), 200, 'Setting Feb 28 2000 day of the year to 200 should work');\n        assert.equal(moment([2000, 11, 31]).dayOfYear(200).dayOfYear(), 200, 'Setting Dec 31 2000 day of the year to 200 should work');\n        assert.equal(moment().dayOfYear(1).dayOfYear(),   1, 'Setting day of the year to 1 should work');\n        assert.equal(moment().dayOfYear(59).dayOfYear(),  59, 'Setting day of the year to 59 should work');\n        assert.equal(moment().dayOfYear(60).dayOfYear(),  60, 'Setting day of the year to 60 should work');\n        assert.equal(moment().dayOfYear(365).dayOfYear(), 365, 'Setting day of the year to 365 should work');\n    });\n\n    test('iso weeks year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).isoWeek(), 52, 'Jan  1 2012 should be iso week 52');\n        assert.equal(moment([2012, 0, 2]).isoWeek(),  1, 'Jan  2 2012 should be iso week 1');\n        assert.equal(moment([2012, 0, 8]).isoWeek(),  1, 'Jan  8 2012 should be iso week 1');\n        assert.equal(moment([2012, 0, 9]).isoWeek(),  2, 'Jan  9 2012 should be iso week 2');\n        assert.equal(moment([2012, 0, 15]).isoWeek(), 2, 'Jan 15 2012 should be iso week 2');\n    });\n\n    test('iso weeks year starting monday', function (assert) {\n        assert.equal(moment([2007, 0, 1]).isoWeek(),  1, 'Jan  1 2007 should be iso week 1');\n        assert.equal(moment([2007, 0, 7]).isoWeek(),  1, 'Jan  7 2007 should be iso week 1');\n        assert.equal(moment([2007, 0, 8]).isoWeek(),  2, 'Jan  8 2007 should be iso week 2');\n        assert.equal(moment([2007, 0, 14]).isoWeek(), 2, 'Jan 14 2007 should be iso week 2');\n        assert.equal(moment([2007, 0, 15]).isoWeek(), 3, 'Jan 15 2007 should be iso week 3');\n    });\n\n    test('iso weeks year starting tuesday', function (assert) {\n        assert.equal(moment([2007, 11, 31]).isoWeek(), 1, 'Dec 31 2007 should be iso week 1');\n        assert.equal(moment([2008,  0,  1]).isoWeek(), 1, 'Jan  1 2008 should be iso week 1');\n        assert.equal(moment([2008,  0,  6]).isoWeek(), 1, 'Jan  6 2008 should be iso week 1');\n        assert.equal(moment([2008,  0,  7]).isoWeek(), 2, 'Jan  7 2008 should be iso week 2');\n        assert.equal(moment([2008,  0, 13]).isoWeek(), 2, 'Jan 13 2008 should be iso week 2');\n        assert.equal(moment([2008,  0, 14]).isoWeek(), 3, 'Jan 14 2008 should be iso week 3');\n    });\n\n    test('iso weeks year starting wednesday', function (assert) {\n        assert.equal(moment([2002, 11, 30]).isoWeek(), 1, 'Dec 30 2002 should be iso week 1');\n        assert.equal(moment([2003,  0,  1]).isoWeek(), 1, 'Jan  1 2003 should be iso week 1');\n        assert.equal(moment([2003,  0,  5]).isoWeek(), 1, 'Jan  5 2003 should be iso week 1');\n        assert.equal(moment([2003,  0,  6]).isoWeek(), 2, 'Jan  6 2003 should be iso week 2');\n        assert.equal(moment([2003,  0, 12]).isoWeek(), 2, 'Jan 12 2003 should be iso week 2');\n        assert.equal(moment([2003,  0, 13]).isoWeek(), 3, 'Jan 13 2003 should be iso week 3');\n    });\n\n    test('iso weeks year starting thursday', function (assert) {\n        assert.equal(moment([2008, 11, 29]).isoWeek(), 1, 'Dec 29 2008 should be iso week 1');\n        assert.equal(moment([2009,  0,  1]).isoWeek(), 1, 'Jan  1 2009 should be iso week 1');\n        assert.equal(moment([2009,  0,  4]).isoWeek(), 1, 'Jan  4 2009 should be iso week 1');\n        assert.equal(moment([2009,  0,  5]).isoWeek(), 2, 'Jan  5 2009 should be iso week 2');\n        assert.equal(moment([2009,  0, 11]).isoWeek(), 2, 'Jan 11 2009 should be iso week 2');\n        assert.equal(moment([2009,  0, 13]).isoWeek(), 3, 'Jan 12 2009 should be iso week 3');\n    });\n\n    test('iso weeks year starting friday', function (assert) {\n        assert.equal(moment([2009, 11, 28]).isoWeek(), 53, 'Dec 28 2009 should be iso week 53');\n        assert.equal(moment([2010,  0,  1]).isoWeek(), 53, 'Jan  1 2010 should be iso week 53');\n        assert.equal(moment([2010,  0,  3]).isoWeek(), 53, 'Jan  3 2010 should be iso week 53');\n        assert.equal(moment([2010,  0,  4]).isoWeek(),  1, 'Jan  4 2010 should be iso week 1');\n        assert.equal(moment([2010,  0, 10]).isoWeek(),  1, 'Jan 10 2010 should be iso week 1');\n        assert.equal(moment([2010,  0, 11]).isoWeek(),  2, 'Jan 11 2010 should be iso week 2');\n    });\n\n    test('iso weeks year starting saturday', function (assert) {\n        assert.equal(moment([2010, 11, 27]).isoWeek(), 52, 'Dec 27 2010 should be iso week 52');\n        assert.equal(moment([2011,  0,  1]).isoWeek(), 52, 'Jan  1 2011 should be iso week 52');\n        assert.equal(moment([2011,  0,  2]).isoWeek(), 52, 'Jan  2 2011 should be iso week 52');\n        assert.equal(moment([2011,  0,  3]).isoWeek(),  1, 'Jan  3 2011 should be iso week 1');\n        assert.equal(moment([2011,  0,  9]).isoWeek(),  1, 'Jan  9 2011 should be iso week 1');\n        assert.equal(moment([2011,  0, 10]).isoWeek(),  2, 'Jan 10 2011 should be iso week 2');\n    });\n\n    test('iso weeks year starting sunday formatted', function (assert) {\n        assert.equal(moment([2012, 0,  1]).format('W WW Wo'), '52 52 52nd', 'Jan  1 2012 should be iso week 52');\n        assert.equal(moment([2012, 0,  2]).format('W WW Wo'),   '1 01 1st', 'Jan  2 2012 should be iso week 1');\n        assert.equal(moment([2012, 0,  8]).format('W WW Wo'),   '1 01 1st', 'Jan  8 2012 should be iso week 1');\n        assert.equal(moment([2012, 0,  9]).format('W WW Wo'),   '2 02 2nd', 'Jan  9 2012 should be iso week 2');\n        assert.equal(moment([2012, 0, 15]).format('W WW Wo'),   '2 02 2nd', 'Jan 15 2012 should be iso week 2');\n    });\n\n    test('weeks plural year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0,  1]).weeks(), 1, 'Jan  1 2012 should be week 1');\n        assert.equal(moment([2012, 0,  7]).weeks(), 1, 'Jan  7 2012 should be week 1');\n        assert.equal(moment([2012, 0,  8]).weeks(), 2, 'Jan  8 2012 should be week 2');\n        assert.equal(moment([2012, 0, 14]).weeks(), 2, 'Jan 14 2012 should be week 2');\n        assert.equal(moment([2012, 0, 15]).weeks(), 3, 'Jan 15 2012 should be week 3');\n    });\n\n    test('iso weeks plural year starting sunday', function (assert) {\n        assert.equal(moment([2012, 0, 1]).isoWeeks(), 52, 'Jan  1 2012 should be iso week 52');\n        assert.equal(moment([2012, 0, 2]).isoWeeks(),  1, 'Jan  2 2012 should be iso week 1');\n        assert.equal(moment([2012, 0, 8]).isoWeeks(),  1, 'Jan  8 2012 should be iso week 1');\n        assert.equal(moment([2012, 0, 9]).isoWeeks(),  2, 'Jan  9 2012 should be iso week 2');\n        assert.equal(moment([2012, 0, 15]).isoWeeks(), 2, 'Jan 15 2012 should be iso week 2');\n    });\n\n    test('weeks setter', function (assert) {\n        assert.equal(moment([2012, 0,  1]).week(30).week(), 30, 'Setting Jan 1 2012 to week 30 should work');\n        assert.equal(moment([2012, 0,  7]).week(30).week(), 30, 'Setting Jan 7 2012 to week 30 should work');\n        assert.equal(moment([2012, 0,  8]).week(30).week(), 30, 'Setting Jan 8 2012 to week 30 should work');\n        assert.equal(moment([2012, 0, 14]).week(30).week(), 30, 'Setting Jan 14 2012 to week 30 should work');\n        assert.equal(moment([2012, 0, 15]).week(30).week(), 30, 'Setting Jan 15 2012 to week 30 should work');\n    });\n\n    test('iso weeks setter', function (assert) {\n        assert.equal(moment([2012, 0,  1]).isoWeeks(25).isoWeeks(), 25, 'Setting Jan  1 2012 to week 25 should work');\n        assert.equal(moment([2012, 0,  2]).isoWeeks(24).isoWeeks(), 24, 'Setting Jan  2 2012 to week 24 should work');\n        assert.equal(moment([2012, 0,  8]).isoWeeks(23).isoWeeks(), 23, 'Setting Jan  8 2012 to week 23 should work');\n        assert.equal(moment([2012, 0,  9]).isoWeeks(22).isoWeeks(), 22, 'Setting Jan  9 2012 to week 22 should work');\n        assert.equal(moment([2012, 0, 15]).isoWeeks(21).isoWeeks(), 21, 'Setting Jan 15 2012 to week 21 should work');\n    });\n\n    test('iso weeks setter day of year', function (assert) {\n        assert.equal(moment([2012, 0,  1]).isoWeek(1).dayOfYear(), 9, 'Setting Jan  1 2012 to week 1 should be day of year 8');\n        assert.equal(moment([2012, 0,  1]).isoWeek(1).year(),   2011, 'Setting Jan  1 2012 to week 1 should be year 2011');\n        assert.equal(moment([2012, 0,  2]).isoWeek(1).dayOfYear(), 2, 'Setting Jan  2 2012 to week 1 should be day of year 2');\n        assert.equal(moment([2012, 0,  8]).isoWeek(1).dayOfYear(), 8, 'Setting Jan  8 2012 to week 1 should be day of year 8');\n        assert.equal(moment([2012, 0,  9]).isoWeek(1).dayOfYear(), 2, 'Setting Jan  9 2012 to week 1 should be day of year 2');\n        assert.equal(moment([2012, 0, 15]).isoWeek(1).dayOfYear(), 8, 'Setting Jan 15 2012 to week 1 should be day of year 8');\n    });\n\n    test('years with iso week 53', function (assert) {\n        assert.equal(moment([2004, 11, 31]).isoWeek(), 53, 'Dec 31 2004 should be iso week 53');\n        assert.equal(moment([2009, 11, 31]).isoWeek(), 53, 'Dec 31 2009 should be iso week 53');\n        assert.equal(moment([2015, 11, 31]).isoWeek(), 53, 'Dec 31 2015 should be iso week 53');\n        assert.equal(moment([2020, 11, 31]).isoWeek(), 53, 'Dec 31 2020 should be iso week 53');\n        assert.equal(moment([2026, 11, 31]).isoWeek(), 53, 'Dec 31 2026 should be iso week 53');\n        assert.equal(moment([2032, 11, 31]).isoWeek(), 53, 'Dec 31 2032 should be iso week 53');\n        assert.equal(moment([2037, 11, 31]).isoWeek(), 53, 'Dec 31 2037 should be iso week 53');\n        assert.equal(moment([2043, 11, 31]).isoWeek(), 53, 'Dec 31 2043 should be iso week 53');\n        assert.equal(moment([2048, 11, 31]).isoWeek(), 53, 'Dec 31 2048 should be iso week 53');\n        assert.equal(moment([2054, 11, 31]).isoWeek(), 53, 'Dec 31 2054 should be iso week 53');\n        assert.equal(moment([2060, 11, 31]).isoWeek(), 53, 'Dec 31 2060 should be iso week 53');\n        assert.equal(moment([2065, 11, 31]).isoWeek(), 53, 'Dec 31 2065 should be iso week 53');\n        assert.equal(moment([2071, 11, 31]).isoWeek(), 53, 'Dec 31 2071 should be iso week 53');\n        assert.equal(moment([2076, 11, 31]).isoWeek(), 53, 'Dec 31 2076 should be iso week 53');\n        assert.equal(moment([2082, 11, 31]).isoWeek(), 53, 'Dec 31 2082 should be iso week 53');\n        assert.equal(moment([2088, 11, 31]).isoWeek(), 53, 'Dec 31 2088 should be iso week 53');\n        assert.equal(moment([2093, 11, 31]).isoWeek(), 53, 'Dec 31 2093 should be iso week 53');\n        assert.equal(moment([2099, 11, 31]).isoWeek(), 53, 'Dec 31 2099 should be iso week 53');\n        assert.equal(moment([2105, 11, 31]).isoWeek(), 53, 'Dec 31 2105 should be iso week 53');\n        assert.equal(moment([2111, 11, 31]).isoWeek(), 53, 'Dec 31 2111 should be iso week 53');\n        assert.equal(moment([2116, 11, 31]).isoWeek(), 53, 'Dec 31 2116 should be iso week 53');\n        assert.equal(moment([2122, 11, 31]).isoWeek(), 53, 'Dec 31 2122 should be iso week 53');\n        assert.equal(moment([2128, 11, 31]).isoWeek(), 53, 'Dec 31 2128 should be iso week 53');\n        assert.equal(moment([2133, 11, 31]).isoWeek(), 53, 'Dec 31 2133 should be iso week 53');\n        assert.equal(moment([2139, 11, 31]).isoWeek(), 53, 'Dec 31 2139 should be iso week 53');\n        assert.equal(moment([2144, 11, 31]).isoWeek(), 53, 'Dec 31 2144 should be iso week 53');\n        assert.equal(moment([2150, 11, 31]).isoWeek(), 53, 'Dec 31 2150 should be iso week 53');\n        assert.equal(moment([2156, 11, 31]).isoWeek(), 53, 'Dec 31 2156 should be iso week 53');\n        assert.equal(moment([2161, 11, 31]).isoWeek(), 53, 'Dec 31 2161 should be iso week 53');\n        assert.equal(moment([2167, 11, 31]).isoWeek(), 53, 'Dec 31 2167 should be iso week 53');\n        assert.equal(moment([2172, 11, 31]).isoWeek(), 53, 'Dec 31 2172 should be iso week 53');\n        assert.equal(moment([2178, 11, 31]).isoWeek(), 53, 'Dec 31 2178 should be iso week 53');\n        assert.equal(moment([2184, 11, 31]).isoWeek(), 53, 'Dec 31 2184 should be iso week 53');\n        assert.equal(moment([2189, 11, 31]).isoWeek(), 53, 'Dec 31 2189 should be iso week 53');\n        assert.equal(moment([2195, 11, 31]).isoWeek(), 53, 'Dec 31 2195 should be iso week 53');\n        assert.equal(moment([2201, 11, 31]).isoWeek(), 53, 'Dec 31 2201 should be iso week 53');\n        assert.equal(moment([2207, 11, 31]).isoWeek(), 53, 'Dec 31 2207 should be iso week 53');\n        assert.equal(moment([2212, 11, 31]).isoWeek(), 53, 'Dec 31 2212 should be iso week 53');\n        assert.equal(moment([2218, 11, 31]).isoWeek(), 53, 'Dec 31 2218 should be iso week 53');\n        assert.equal(moment([2224, 11, 31]).isoWeek(), 53, 'Dec 31 2224 should be iso week 53');\n        assert.equal(moment([2229, 11, 31]).isoWeek(), 53, 'Dec 31 2229 should be iso week 53');\n        assert.equal(moment([2235, 11, 31]).isoWeek(), 53, 'Dec 31 2235 should be iso week 53');\n        assert.equal(moment([2240, 11, 31]).isoWeek(), 53, 'Dec 31 2240 should be iso week 53');\n        assert.equal(moment([2246, 11, 31]).isoWeek(), 53, 'Dec 31 2246 should be iso week 53');\n        assert.equal(moment([2252, 11, 31]).isoWeek(), 53, 'Dec 31 2252 should be iso week 53');\n        assert.equal(moment([2257, 11, 31]).isoWeek(), 53, 'Dec 31 2257 should be iso week 53');\n        assert.equal(moment([2263, 11, 31]).isoWeek(), 53, 'Dec 31 2263 should be iso week 53');\n        assert.equal(moment([2268, 11, 31]).isoWeek(), 53, 'Dec 31 2268 should be iso week 53');\n        assert.equal(moment([2274, 11, 31]).isoWeek(), 53, 'Dec 31 2274 should be iso week 53');\n        assert.equal(moment([2280, 11, 31]).isoWeek(), 53, 'Dec 31 2280 should be iso week 53');\n        assert.equal(moment([2285, 11, 31]).isoWeek(), 53, 'Dec 31 2285 should be iso week 53');\n        assert.equal(moment([2291, 11, 31]).isoWeek(), 53, 'Dec 31 2291 should be iso week 53');\n        assert.equal(moment([2296, 11, 31]).isoWeek(), 53, 'Dec 31 2296 should be iso week 53');\n        assert.equal(moment([2303, 11, 31]).isoWeek(), 53, 'Dec 31 2303 should be iso week 53');\n        assert.equal(moment([2308, 11, 31]).isoWeek(), 53, 'Dec 31 2308 should be iso week 53');\n        assert.equal(moment([2314, 11, 31]).isoWeek(), 53, 'Dec 31 2314 should be iso week 53');\n        assert.equal(moment([2320, 11, 31]).isoWeek(), 53, 'Dec 31 2320 should be iso week 53');\n        assert.equal(moment([2325, 11, 31]).isoWeek(), 53, 'Dec 31 2325 should be iso week 53');\n        assert.equal(moment([2331, 11, 31]).isoWeek(), 53, 'Dec 31 2331 should be iso week 53');\n        assert.equal(moment([2336, 11, 31]).isoWeek(), 53, 'Dec 31 2336 should be iso week 53');\n        assert.equal(moment([2342, 11, 31]).isoWeek(), 53, 'Dec 31 2342 should be iso week 53');\n        assert.equal(moment([2348, 11, 31]).isoWeek(), 53, 'Dec 31 2348 should be iso week 53');\n        assert.equal(moment([2353, 11, 31]).isoWeek(), 53, 'Dec 31 2353 should be iso week 53');\n        assert.equal(moment([2359, 11, 31]).isoWeek(), 53, 'Dec 31 2359 should be iso week 53');\n        assert.equal(moment([2364, 11, 31]).isoWeek(), 53, 'Dec 31 2364 should be iso week 53');\n        assert.equal(moment([2370, 11, 31]).isoWeek(), 53, 'Dec 31 2370 should be iso week 53');\n        assert.equal(moment([2376, 11, 31]).isoWeek(), 53, 'Dec 31 2376 should be iso week 53');\n        assert.equal(moment([2381, 11, 31]).isoWeek(), 53, 'Dec 31 2381 should be iso week 53');\n        assert.equal(moment([2387, 11, 31]).isoWeek(), 53, 'Dec 31 2387 should be iso week 53');\n        assert.equal(moment([2392, 11, 31]).isoWeek(), 53, 'Dec 31 2392 should be iso week 53');\n        assert.equal(moment([2398, 11, 31]).isoWeek(), 53, 'Dec 31 2398 should be iso week 53');\n    });\n\n    test('count years with iso week 53', function (assert) {\n        var count = 0, i;\n        for (i = 0; i < 400; i++) {\n            count += (moment([2000 + i, 11, 31]).isoWeek() === 53) ? 1 : 0;\n        }\n        assert.equal(count, 71, 'Should have 71 years in 400-year cycle with iso week 53');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('weeks in year');\n\n    test('isoWeeksInYear', function (assert) {\n        assert.equal(moment([2004]).isoWeeksInYear(), 53, '2004 has 53 iso weeks');\n        assert.equal(moment([2005]).isoWeeksInYear(), 52, '2005 has 53 iso weeks');\n        assert.equal(moment([2006]).isoWeeksInYear(), 52, '2006 has 53 iso weeks');\n        assert.equal(moment([2007]).isoWeeksInYear(), 52, '2007 has 52 iso weeks');\n        assert.equal(moment([2008]).isoWeeksInYear(), 52, '2008 has 53 iso weeks');\n        assert.equal(moment([2009]).isoWeeksInYear(), 53, '2009 has 53 iso weeks');\n        assert.equal(moment([2010]).isoWeeksInYear(), 52, '2010 has 52 iso weeks');\n        assert.equal(moment([2011]).isoWeeksInYear(), 52, '2011 has 52 iso weeks');\n        assert.equal(moment([2012]).isoWeeksInYear(), 52, '2012 has 52 iso weeks');\n        assert.equal(moment([2013]).isoWeeksInYear(), 52, '2013 has 52 iso weeks');\n        assert.equal(moment([2014]).isoWeeksInYear(), 52, '2014 has 52 iso weeks');\n        assert.equal(moment([2015]).isoWeeksInYear(), 53, '2015 has 53 iso weeks');\n    });\n\n    test('weeksInYear doy/dow = 1/4', function (assert) {\n        moment.locale('1/4', {week: {dow: 1, doy: 4}});\n\n        assert.equal(moment([2004]).weeksInYear(), 53, '2004 has 53 weeks');\n        assert.equal(moment([2005]).weeksInYear(), 52, '2005 has 53 weeks');\n        assert.equal(moment([2006]).weeksInYear(), 52, '2006 has 53 weeks');\n        assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n        assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n        assert.equal(moment([2009]).weeksInYear(), 53, '2009 has 53 weeks');\n        assert.equal(moment([2010]).weeksInYear(), 52, '2010 has 52 weeks');\n        assert.equal(moment([2011]).weeksInYear(), 52, '2011 has 52 weeks');\n        assert.equal(moment([2012]).weeksInYear(), 52, '2012 has 52 weeks');\n        assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n        assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n        assert.equal(moment([2015]).weeksInYear(), 53, '2015 has 53 weeks');\n    });\n\n    test('weeksInYear doy/dow = 6/12', function (assert) {\n        moment.locale('6/12', {week: {dow: 6, doy: 12}});\n\n        assert.equal(moment([2004]).weeksInYear(), 53, '2004 has 53 weeks');\n        assert.equal(moment([2005]).weeksInYear(), 52, '2005 has 53 weeks');\n        assert.equal(moment([2006]).weeksInYear(), 52, '2006 has 53 weeks');\n        assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n        assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n        assert.equal(moment([2009]).weeksInYear(), 52, '2009 has 53 weeks');\n        assert.equal(moment([2010]).weeksInYear(), 53, '2010 has 52 weeks');\n        assert.equal(moment([2011]).weeksInYear(), 52, '2011 has 52 weeks');\n        assert.equal(moment([2012]).weeksInYear(), 52, '2012 has 52 weeks');\n        assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n        assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n        assert.equal(moment([2015]).weeksInYear(), 52, '2015 has 53 weeks');\n    });\n\n    test('weeksInYear doy/dow = 1/7', function (assert) {\n        moment.locale('1/7', {week: {dow: 1, doy: 7}});\n\n        assert.equal(moment([2004]).weeksInYear(), 52, '2004 has 53 weeks');\n        assert.equal(moment([2005]).weeksInYear(), 52, '2005 has 53 weeks');\n        assert.equal(moment([2006]).weeksInYear(), 53, '2006 has 53 weeks');\n        assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n        assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n        assert.equal(moment([2009]).weeksInYear(), 52, '2009 has 53 weeks');\n        assert.equal(moment([2010]).weeksInYear(), 52, '2010 has 52 weeks');\n        assert.equal(moment([2011]).weeksInYear(), 52, '2011 has 52 weeks');\n        assert.equal(moment([2012]).weeksInYear(), 53, '2012 has 52 weeks');\n        assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n        assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n        assert.equal(moment([2015]).weeksInYear(), 52, '2015 has 53 weeks');\n    });\n\n    test('weeksInYear doy/dow = 0/6', function (assert) {\n        moment.locale('0/6', {week: {dow: 0, doy: 6}});\n\n        assert.equal(moment([2004]).weeksInYear(), 52, '2004 has 53 weeks');\n        assert.equal(moment([2005]).weeksInYear(), 53, '2005 has 53 weeks');\n        assert.equal(moment([2006]).weeksInYear(), 52, '2006 has 53 weeks');\n        assert.equal(moment([2007]).weeksInYear(), 52, '2007 has 52 weeks');\n        assert.equal(moment([2008]).weeksInYear(), 52, '2008 has 53 weeks');\n        assert.equal(moment([2009]).weeksInYear(), 52, '2009 has 53 weeks');\n        assert.equal(moment([2010]).weeksInYear(), 52, '2010 has 52 weeks');\n        assert.equal(moment([2011]).weeksInYear(), 53, '2011 has 52 weeks');\n        assert.equal(moment([2012]).weeksInYear(), 52, '2012 has 52 weeks');\n        assert.equal(moment([2013]).weeksInYear(), 52, '2013 has 52 weeks');\n        assert.equal(moment([2014]).weeksInYear(), 52, '2014 has 52 weeks');\n        assert.equal(moment([2015]).weeksInYear(), 52, '2015 has 53 weeks');\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('zone switching');\n\n    test('local to utc, keepLocalTime = true', function (assert) {\n        var m = moment(),\n            fmt = 'YYYY-DD-MM HH:mm:ss';\n        assert.equal(m.clone().utc(true).format(fmt), m.format(fmt), 'local to utc failed to keep local time');\n    });\n\n    test('local to utc, keepLocalTime = false', function (assert) {\n        var m = moment();\n        assert.equal(m.clone().utc().valueOf(), m.valueOf(), 'local to utc failed to keep utc time (implicit)');\n        assert.equal(m.clone().utc(false).valueOf(), m.valueOf(), 'local to utc failed to keep utc time (explicit)');\n    });\n\n    test('local to zone, keepLocalTime = true', function (assert) {\n        var m = moment(),\n            fmt = 'YYYY-DD-MM HH:mm:ss',\n            z;\n        for (z = -12; z <= 14; ++z) {\n            assert.equal(m.clone().zone(z * 60, true).format(fmt), m.format(fmt),\n                    'local to zone(' + z + ':00) failed to keep local time');\n        }\n    });\n\n    test('local to zone, keepLocalTime = false', function (assert) {\n        var m = moment(),\n            z;\n        for (z = -12; z <= 14; ++z) {\n            assert.equal(m.clone().zone(z * 60).valueOf(), m.valueOf(),\n                    'local to zone(' + z + ':00) failed to keep utc time (implicit)');\n            assert.equal(m.clone().zone(z * 60, false).valueOf(), m.valueOf(),\n                    'local to zone(' + z + ':00) failed to keep utc time (explicit)');\n        }\n    });\n\n    test('utc to local, keepLocalTime = true', function (assert) {\n        var um = moment.utc(),\n            fmt = 'YYYY-DD-MM HH:mm:ss';\n\n        assert.equal(um.clone().local(true).format(fmt), um.format(fmt), 'utc to local failed to keep local time');\n    });\n\n    test('utc to local, keepLocalTime = false', function (assert) {\n        var um = moment.utc();\n        assert.equal(um.clone().local().valueOf(), um.valueOf(), 'utc to local failed to keep utc time (implicit)');\n        assert.equal(um.clone().local(false).valueOf(), um.valueOf(), 'utc to local failed to keep utc time (explicit)');\n    });\n\n    test('zone to local, keepLocalTime = true', function (assert) {\n        var m = moment(),\n            fmt = 'YYYY-DD-MM HH:mm:ss',\n            z;\n        for (z = -12; z <= 14; ++z) {\n            m.zone(z * 60);\n\n            assert.equal(m.clone().local(true).format(fmt), m.format(fmt),\n                    'zone(' + z + ':00) to local failed to keep local time');\n        }\n    });\n\n    test('zone to local, keepLocalTime = false', function (assert) {\n        var m = moment(),\n            z;\n        for (z = -12; z <= 14; ++z) {\n            m.zone(z * 60);\n\n            assert.equal(m.clone().local(false).valueOf(), m.valueOf(),\n                    'zone(' + z + ':00) to local failed to keep utc time (explicit)');\n            assert.equal(m.clone().local().valueOf(), m.valueOf(),\n                    'zone(' + z + ':00) to local failed to keep utc time (implicit)');\n        }\n    });\n\n}));\n\n(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n\n    /*global QUnit:false*/\n\n    var test = QUnit.test;\n\n    function module (name, lifecycle) {\n        QUnit.module(name, {\n            setup : function () {\n                moment.locale('en');\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    function localeModule (name, lifecycle) {\n        QUnit.module('locale:' + name, {\n            setup : function () {\n                moment.locale(name);\n                moment.createFromInputFallback = function () {\n                    throw new Error('input not handled by moment');\n                };\n                if (lifecycle && lifecycle.setup) {\n                    lifecycle.setup();\n                }\n            },\n            teardown : function () {\n                moment.locale('en');\n                if (lifecycle && lifecycle.teardown) {\n                    lifecycle.teardown();\n                }\n            }\n        });\n    }\n\n    module('zones');\n\n    test('set zone', function (assert) {\n        var zone = moment();\n\n        zone.zone(0);\n        assert.equal(zone.zone(), 0, 'should be able to set the zone to 0');\n\n        zone.zone(60);\n        assert.equal(zone.zone(), 60, 'should be able to set the zone to 60');\n\n        zone.zone(-60);\n        assert.equal(zone.zone(), -60, 'should be able to set the zone to -60');\n    });\n\n    test('set zone shorthand', function (assert) {\n        var zone = moment();\n\n        zone.zone(1);\n        assert.equal(zone.zone(), 60, 'setting the zone to 1 should imply hours and convert to 60');\n\n        zone.zone(-1);\n        assert.equal(zone.zone(), -60, 'setting the zone to -1 should imply hours and convert to -60');\n\n        zone.zone(15);\n        assert.equal(zone.zone(), 900, 'setting the zone to 15 should imply hours and convert to 900');\n\n        zone.zone(-15);\n        assert.equal(zone.zone(), -900, 'setting the zone to -15 should imply hours and convert to -900');\n\n        zone.zone(16);\n        assert.equal(zone.zone(), 16, 'setting the zone to 16 should imply minutes');\n\n        zone.zone(-16);\n        assert.equal(zone.zone(), -16, 'setting the zone to -16 should imply minutes');\n    });\n\n    test('set zone with string', function (assert) {\n        var zone = moment();\n\n        zone.zone('+00:00');\n        assert.equal(zone.zone(), 0, 'set the zone with a timezone string');\n\n        zone.zone('2013-03-07T07:00:00-08:00');\n        assert.equal(zone.zone(), 480, 'set the zone with a string that does not begin with the timezone');\n\n        zone.zone('2013-03-07T07:00:00+0100');\n        assert.equal(zone.zone(), -60, 'set the zone with a string that uses the +0000 syntax');\n\n        zone.zone('03-07-2013T07:00:00-08:00');\n        assert.equal(zone.zone(), 480, 'set the zone with a string with a non-ISO 8601 date');\n    });\n\n    test('change hours when changing the zone', function (assert) {\n        var zone = moment.utc([2000, 0, 1, 6]);\n\n        zone.zone(0);\n        assert.equal(zone.hour(), 6, 'UTC 6AM should be 6AM at +0000');\n\n        zone.zone(60);\n        assert.equal(zone.hour(), 5, 'UTC 6AM should be 5AM at -0100');\n\n        zone.zone(-60);\n        assert.equal(zone.hour(), 7, 'UTC 6AM should be 7AM at +0100');\n    });\n\n    test('change minutes when changing the zone', function (assert) {\n        var zone = moment.utc([2000, 0, 1, 6, 31]);\n\n        zone.zone(0);\n        assert.equal(zone.format('HH:mm'), '06:31', 'UTC 6:31AM should be 6:31AM at +0000');\n\n        zone.zone(30);\n        assert.equal(zone.format('HH:mm'), '06:01', 'UTC 6:31AM should be 6:01AM at -0030');\n\n        zone.zone(-30);\n        assert.equal(zone.format('HH:mm'), '07:01', 'UTC 6:31AM should be 7:01AM at +0030');\n\n        zone.zone(1380);\n        assert.equal(zone.format('HH:mm'), '07:31', 'UTC 6:31AM should be 7:31AM at +1380');\n    });\n\n    test('distance from the unix epoch', function (assert) {\n        var zoneA = moment(),\n            zoneB = moment(zoneA),\n            zoneC = moment(zoneA),\n            zoneD = moment(zoneA),\n            zoneE = moment(zoneA);\n\n        zoneB.utc();\n        assert.equal(+zoneA, +zoneB, 'moment should equal moment.utc');\n\n        zoneC.zone(-60);\n        assert.equal(+zoneA, +zoneC, 'moment should equal moment.zone(-60)');\n\n        zoneD.zone(480);\n        assert.equal(+zoneA, +zoneD, 'moment should equal moment.zone(480)');\n\n        zoneE.zone(1000);\n        assert.equal(+zoneA, +zoneE, 'moment should equal moment.zone(1000)');\n    });\n\n    test('update offset after changing any values', function (assert) {\n        var oldOffset = moment.updateOffset,\n            m = moment.utc([2000, 6, 1]);\n\n        moment.updateOffset = function (mom, keepTime) {\n            if (mom.__doChange) {\n                if (+mom > 962409600000) {\n                    mom.zone(120, keepTime);\n                } else {\n                    mom.zone(60, keepTime);\n                }\n            }\n        };\n\n        assert.equal(m.format('ZZ'), '+0000', 'should be at +0000');\n        assert.equal(m.format('HH:mm'), '00:00', 'should start 12AM at +0000 timezone');\n\n        m.__doChange = true;\n        m.add(1, 'h');\n\n        assert.equal(m.format('ZZ'), '-0200', 'should be at -0200');\n        assert.equal(m.format('HH:mm'), '23:00', '1AM at +0000 should be 11PM at -0200 timezone');\n\n        m.subtract(1, 'h');\n\n        assert.equal(m.format('ZZ'), '-0100', 'should be at -0100');\n        assert.equal(m.format('HH:mm'), '23:00', '12AM at +0000 should be 11PM at -0100 timezone');\n\n        moment.updateOffset = oldOffset;\n    });\n\n    test('getters and setters', function (assert) {\n        var a = moment([2011, 5, 20]);\n\n        assert.equal(a.clone().zone(120).year(2012).year(), 2012, 'should get and set year correctly');\n        assert.equal(a.clone().zone(120).month(1).month(), 1, 'should get and set month correctly');\n        assert.equal(a.clone().zone(120).date(2).date(), 2, 'should get and set date correctly');\n        assert.equal(a.clone().zone(120).day(1).day(), 1, 'should get and set day correctly');\n        assert.equal(a.clone().zone(120).hour(1).hour(), 1, 'should get and set hour correctly');\n        assert.equal(a.clone().zone(120).minute(1).minute(), 1, 'should get and set minute correctly');\n    });\n\n    test('getters', function (assert) {\n        var a = moment.utc([2012, 0, 1, 0, 0, 0]);\n\n        assert.equal(a.clone().zone(120).year(),  2011, 'should get year correctly');\n        assert.equal(a.clone().zone(120).month(),   11, 'should get month correctly');\n        assert.equal(a.clone().zone(120).date(),    31, 'should get date correctly');\n        assert.equal(a.clone().zone(120).hour(),    22, 'should get hour correctly');\n        assert.equal(a.clone().zone(120).minute(),   0, 'should get minute correctly');\n\n        assert.equal(a.clone().zone(-120).year(),  2012, 'should get year correctly');\n        assert.equal(a.clone().zone(-120).month(),    0, 'should get month correctly');\n        assert.equal(a.clone().zone(-120).date(),     1, 'should get date correctly');\n        assert.equal(a.clone().zone(-120).hour(),     2, 'should get hour correctly');\n        assert.equal(a.clone().zone(-120).minute(),   0, 'should get minute correctly');\n\n        assert.equal(a.clone().zone(-90).year(),  2012, 'should get year correctly');\n        assert.equal(a.clone().zone(-90).month(),    0, 'should get month correctly');\n        assert.equal(a.clone().zone(-90).date(),     1, 'should get date correctly');\n        assert.equal(a.clone().zone(-90).hour(),     1, 'should get hour correctly');\n        assert.equal(a.clone().zone(-90).minute(),  30, 'should get minute correctly');\n    });\n\n    test('from', function (assert) {\n        var zoneA = moment(),\n            zoneB = moment(zoneA).zone(720),\n            zoneC = moment(zoneA).zone(360),\n            zoneD = moment(zoneA).zone(-690),\n            other = moment(zoneA).add(35, 'm');\n\n        assert.equal(zoneA.from(other), zoneB.from(other), 'moment#from should be the same in all zones');\n        assert.equal(zoneA.from(other), zoneC.from(other), 'moment#from should be the same in all zones');\n        assert.equal(zoneA.from(other), zoneD.from(other), 'moment#from should be the same in all zones');\n    });\n\n    test('diff', function (assert) {\n        var zoneA = moment(),\n            zoneB = moment(zoneA).zone(720),\n            zoneC = moment(zoneA).zone(360),\n            zoneD = moment(zoneA).zone(-690),\n            other = moment(zoneA).add(35, 'm');\n\n        assert.equal(zoneA.diff(other), zoneB.diff(other), 'moment#diff should be the same in all zones');\n        assert.equal(zoneA.diff(other), zoneC.diff(other), 'moment#diff should be the same in all zones');\n        assert.equal(zoneA.diff(other), zoneD.diff(other), 'moment#diff should be the same in all zones');\n\n        assert.equal(zoneA.diff(other, 'minute', true), zoneB.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n        assert.equal(zoneA.diff(other, 'minute', true), zoneC.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n        assert.equal(zoneA.diff(other, 'minute', true), zoneD.diff(other, 'minute', true), 'moment#diff should be the same in all zones');\n\n        assert.equal(zoneA.diff(other, 'hour', true), zoneB.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n        assert.equal(zoneA.diff(other, 'hour', true), zoneC.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n        assert.equal(zoneA.diff(other, 'hour', true), zoneD.diff(other, 'hour', true), 'moment#diff should be the same in all zones');\n    });\n\n    test('unix offset and timestamp', function (assert) {\n        var zoneA = moment(),\n            zoneB = moment(zoneA).zone(720),\n            zoneC = moment(zoneA).zone(360),\n            zoneD = moment(zoneA).zone(-690);\n\n        assert.equal(zoneA.unix(), zoneB.unix(), 'moment#unix should be the same in all zones');\n        assert.equal(zoneA.unix(), zoneC.unix(), 'moment#unix should be the same in all zones');\n        assert.equal(zoneA.unix(), zoneD.unix(), 'moment#unix should be the same in all zones');\n\n        assert.equal(+zoneA, +zoneB, 'moment#valueOf should be the same in all zones');\n        assert.equal(+zoneA, +zoneC, 'moment#valueOf should be the same in all zones');\n        assert.equal(+zoneA, +zoneD, 'moment#valueOf should be the same in all zones');\n    });\n\n    test('cloning', function (assert) {\n        assert.equal(moment().zone(120).clone().zone(),   120, 'explicit cloning should retain the zone');\n        assert.equal(moment().zone(-120).clone().zone(), -120, 'explicit cloning should retain the zone');\n        assert.equal(moment(moment().zone(120)).zone(),   120, 'implicit cloning should retain the zone');\n        assert.equal(moment(moment().zone(-120)).zone(), -120, 'implicit cloning should retain the zone');\n    });\n\n    test('start of / end of', function (assert) {\n        var a = moment.utc([2010, 1, 2, 0, 0, 0]).zone(450);\n\n        assert.equal(a.clone().startOf('day').hour(), 0, 'start of day should work on moments with a zone');\n        assert.equal(a.clone().startOf('day').minute(), 0, 'start of day should work on moments with a zone');\n        assert.equal(a.clone().startOf('hour').minute(), 0, 'start of hour should work on moments with a zone');\n\n        assert.equal(a.clone().endOf('day').hour(), 23, 'end of day should work on moments with a zone');\n        assert.equal(a.clone().endOf('day').minute(), 59, 'end of day should work on moments with a zone');\n        assert.equal(a.clone().endOf('hour').minute(), 59, 'end of hour should work on moments with a zone');\n    });\n\n    test('reset zone with moment#utc', function (assert) {\n        var a = moment.utc([2012]).zone(480);\n\n        assert.equal(a.clone().hour(),      16, 'different zone should have different hour');\n        assert.equal(a.clone().utc().hour(), 0, 'calling moment#utc should reset the offset');\n    });\n\n    test('reset zone with moment#local', function (assert) {\n        var a = moment([2012]).zone(480);\n\n        assert.equal(a.clone().local().hour(), 0, 'calling moment#local should reset the offset');\n    });\n\n    test('toDate', function (assert) {\n        var zoneA = new Date(),\n            zoneB = moment(zoneA).zone(720).toDate(),\n            zoneC = moment(zoneA).zone(360).toDate(),\n            zoneD = moment(zoneA).zone(-690).toDate();\n\n        assert.equal(+zoneA, +zoneB, 'moment#toDate should output a date with the right unix timestamp');\n        assert.equal(+zoneA, +zoneC, 'moment#toDate should output a date with the right unix timestamp');\n        assert.equal(+zoneA, +zoneD, 'moment#toDate should output a date with the right unix timestamp');\n    });\n\n    test('same / before / after', function (assert) {\n        var zoneA = moment().utc(),\n            zoneB = moment(zoneA).zone(120),\n            zoneC = moment(zoneA).zone(-120);\n\n        assert.ok(zoneA.isSame(zoneB), 'two moments with different offsets should be the same');\n        assert.ok(zoneA.isSame(zoneC), 'two moments with different offsets should be the same');\n\n        assert.ok(zoneA.isSame(zoneB, 'hour'), 'two moments with different offsets should be the same hour');\n        assert.ok(zoneA.isSame(zoneC, 'hour'), 'two moments with different offsets should be the same hour');\n\n        zoneA.add(1, 'hour');\n\n        assert.ok(zoneA.isAfter(zoneB), 'isAfter should work with two moments with different offsets');\n        assert.ok(zoneA.isAfter(zoneC), 'isAfter should work with two moments with different offsets');\n\n        assert.ok(zoneA.isAfter(zoneB, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n        assert.ok(zoneA.isAfter(zoneC, 'hour'), 'isAfter:hour should work with two moments with different offsets');\n\n        zoneA.subtract(2, 'hour');\n\n        assert.ok(zoneA.isBefore(zoneB), 'isBefore should work with two moments with different offsets');\n        assert.ok(zoneA.isBefore(zoneC), 'isBefore should work with two moments with different offsets');\n\n        assert.ok(zoneA.isBefore(zoneB, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n        assert.ok(zoneA.isBefore(zoneC, 'hour'), 'isBefore:hour should work with two moments with different offsets');\n    });\n\n    test('add / subtract over dst', function (assert) {\n        var oldOffset = moment.updateOffset,\n            m = moment.utc([2000, 2, 31, 3]);\n\n        moment.updateOffset = function (mom, keepTime) {\n            if (mom.clone().utc().month() > 2) {\n                mom.zone(-60, keepTime);\n            } else {\n                mom.zone(0, keepTime);\n            }\n        };\n\n        assert.equal(m.hour(), 3, 'should start at 00:00');\n\n        m.add(24, 'hour');\n\n        assert.equal(m.hour(), 4, 'adding 24 hours should disregard dst');\n\n        m.subtract(24, 'hour');\n\n        assert.equal(m.hour(), 3, 'subtracting 24 hours should disregard dst');\n\n        m.add(1, 'day');\n\n        assert.equal(m.hour(), 3, 'adding 1 day should have the same hour');\n\n        m.subtract(1, 'day');\n\n        assert.equal(m.hour(), 3, 'subtracting 1 day should have the same hour');\n\n        m.add(1, 'month');\n\n        assert.equal(m.hour(), 3, 'adding 1 month should have the same hour');\n\n        m.subtract(1, 'month');\n\n        assert.equal(m.hour(), 3, 'subtracting 1 month should have the same hour');\n\n        moment.updateOffset = oldOffset;\n    });\n\n    test('isDST', function (assert) {\n        var oldOffset = moment.updateOffset;\n\n        moment.updateOffset = function (mom, keepTime) {\n            if (mom.month() > 2 && mom.month() < 9) {\n                mom.zone(-60, keepTime);\n            } else {\n                mom.zone(0, keepTime);\n            }\n        };\n\n        assert.ok(!moment().month(0).isDST(),  'Jan should not be summer dst');\n        assert.ok(moment().month(6).isDST(),   'Jul should be summer dst');\n        assert.ok(!moment().month(11).isDST(), 'Dec should not be summer dst');\n\n        moment.updateOffset = function (mom) {\n            if (mom.month() > 2 && mom.month() < 9) {\n                mom.zone(0);\n            } else {\n                mom.zone(-60);\n            }\n        };\n\n        assert.ok(moment().month(0).isDST(),  'Jan should be winter dst');\n        assert.ok(!moment().month(6).isDST(), 'Jul should not be winter dst');\n        assert.ok(moment().month(11).isDST(), 'Dec should be winter dst');\n\n        moment.updateOffset = oldOffset;\n    });\n\n    test('zone names', function (assert) {\n        assert.equal(moment().zoneAbbr(),   '', 'Local zone abbr should be empty');\n        assert.equal(moment().format('z'),  '', 'Local zone formatted abbr should be empty');\n        assert.equal(moment().zoneName(),   '', 'Local zone name should be empty');\n        assert.equal(moment().format('zz'), '', 'Local zone formatted name should be empty');\n\n        assert.equal(moment.utc().zoneAbbr(),   'UTC', 'UTC zone abbr should be UTC');\n        assert.equal(moment.utc().format('z'),  'UTC', 'UTC zone formatted abbr should be UTC');\n        assert.equal(moment.utc().zoneName(),   'Coordinated Universal Time', 'UTC zone abbr should be Coordinated Universal Time');\n        assert.equal(moment.utc().format('zz'), 'Coordinated Universal Time', 'UTC zone formatted abbr should be Coordinated Universal Time');\n    });\n\n    test('hours alignment with UTC', function (assert) {\n        assert.equal(moment().zone(120).hasAlignedHourOffset(), true);\n        assert.equal(moment().zone(-180).hasAlignedHourOffset(), true);\n        assert.equal(moment().zone(90).hasAlignedHourOffset(), false);\n        assert.equal(moment().zone(-90).hasAlignedHourOffset(), false);\n    });\n\n    test('hours alignment with other zone', function (assert) {\n        var m = moment().zone(120);\n\n        assert.equal(m.hasAlignedHourOffset(moment().zone(180)), true);\n        assert.equal(m.hasAlignedHourOffset(moment().zone(-180)), true);\n        assert.equal(m.hasAlignedHourOffset(moment().zone(90)), false);\n        assert.equal(m.hasAlignedHourOffset(moment().zone(-90)), false);\n\n        m = moment().zone(90);\n\n        assert.equal(m.hasAlignedHourOffset(moment().zone(180)), false);\n        assert.equal(m.hasAlignedHourOffset(moment().zone(-180)), false);\n        assert.equal(m.hasAlignedHourOffset(moment().zone(30)), true);\n        assert.equal(m.hasAlignedHourOffset(moment().zone(-30)), true);\n\n        m = moment().zone(-60);\n\n        assert.equal(m.hasAlignedHourOffset(moment().zone(180)), true);\n        assert.equal(m.hasAlignedHourOffset(moment().zone(-180)), true);\n        assert.equal(m.hasAlignedHourOffset(moment().zone(90)), false);\n        assert.equal(m.hasAlignedHourOffset(moment().zone(-90)), false);\n\n        m = moment().zone(25);\n\n        assert.equal(m.hasAlignedHourOffset(moment().zone(-35)), true);\n        assert.equal(m.hasAlignedHourOffset(moment().zone(85)), true);\n\n        assert.equal(m.hasAlignedHourOffset(moment().zone(35)), false);\n        assert.equal(m.hasAlignedHourOffset(moment().zone(-85)), false);\n    });\n\n    test('parse zone', function (assert) {\n        var m = moment('2013-01-01T00:00:00-13:00').parseZone();\n        assert.equal(m.zone(), 13 * 60);\n        assert.equal(m.hours(), 0);\n    });\n\n    test('parse zone static', function (assert) {\n        var m = moment.parseZone('2013-01-01T00:00:00-13:00');\n        assert.equal(m.zone(), 13 * 60);\n        assert.equal(m.hours(), 0);\n    });\n\n    test('parse zone with more arguments', function (assert) {\n        var m;\n        m = moment.parseZone('2013 01 01 05 -13:00', 'YYYY MM DD HH ZZ');\n        assert.equal(m.format(), '2013-01-01T05:00:00-13:00', 'accept input and format');\n        m = moment.parseZone('2013-01-01-13:00', 'YYYY MM DD ZZ', true);\n        assert.equal(m.isValid(), false, 'accept input, format and strict flag');\n        m = moment.parseZone('2013-01-01-13:00', ['DD MM YYYY ZZ', 'YYYY MM DD ZZ']);\n        assert.equal(m.format(), '2013-01-01T00:00:00-13:00', 'accept input and array of formats');\n    });\n\n    test('parse zone with a timezone from the format string', function (assert) {\n        var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY ZZ #####').parseZone();\n\n        assert.equal(m.zone(), 4 * 60);\n    });\n\n    test('parse zone without a timezone included in the format string', function (assert) {\n        var m = moment('11-12-2013 -0400 +1100', 'DD-MM-YYYY').parseZone();\n\n        assert.equal(m.zone(), -11 * 60);\n    });\n\n    test('timezone format', function (assert) {\n        assert.equal(moment().zone(-60).format('ZZ'), '+0100', '-60 -> +0100');\n        assert.equal(moment().zone(-90).format('ZZ'), '+0130', '-90 -> +0130');\n        assert.equal(moment().zone(-120).format('ZZ'), '+0200', '-120 -> +0200');\n\n        assert.equal(moment().zone(+60).format('ZZ'), '-0100', '+60 -> -0100');\n        assert.equal(moment().zone(+90).format('ZZ'), '-0130', '+90 -> -0130');\n        assert.equal(moment().zone(+120).format('ZZ'), '-0200', '+120 -> -0200');\n    });\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/moment.js",
    "content": "\n(function (global, factory) {\n    typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :\n    typeof define === 'function' && define.amd ? define(factory) :\n    global.moment = factory()\n}(this, function () { 'use strict';\n\n    var hookCallback;\n\n    function utils_hooks__hooks () {\n        return hookCallback.apply(null, arguments);\n    }\n    function setHookCallback (callback) {\n        hookCallback = callback;\n    }\n\n    function defaultParsingFlags() {\n        return {\n            empty           : false,\n            unusedTokens    : [],\n            unusedInput     : [],\n            overflow        : -2,\n            charsLeftOver   : 0,\n            nullInput       : false,\n            invalidMonth    : null,\n            invalidFormat   : false,\n            userInvalidated : false,\n            iso             : false\n        };\n    }\n\n    function isArray(input) {\n        return Object.prototype.toString.call(input) === '[object Array]';\n    }\n\n    function isDate(input) {\n        return Object.prototype.toString.call(input) === '[object Date]' || input instanceof Date;\n    }\n\n    function map(arr, fn) {\n        var res = [], i;\n        for (i = 0; i < arr.length; ++i) {\n            res.push(fn(arr[i], i));\n        }\n        return res;\n    }\n\n    function hasOwnProp(a, b) {\n        return Object.prototype.hasOwnProperty.call(a, b);\n    }\n\n    function extend(a, b) {\n        for (var i in b) {\n            if (hasOwnProp(b, i)) {\n                a[i] = b[i];\n            }\n        }\n\n        if (hasOwnProp(b, 'toString')) {\n            a.toString = b.toString;\n        }\n\n        if (hasOwnProp(b, 'valueOf')) {\n            a.valueOf = b.valueOf;\n        }\n\n        return a;\n    }\n\n    function create_utc__createUTC (input, format, locale, strict) {\n        return createLocalOrUTC(input, format, locale, strict, true).utc();\n    }\n\n    function valid__isValid(m) {\n        if (m._isValid == null) {\n            m._isValid = !isNaN(m._d.getTime()) &&\n                m._pf.overflow < 0 &&\n                !m._pf.empty &&\n                !m._pf.invalidMonth &&\n                !m._pf.nullInput &&\n                !m._pf.invalidFormat &&\n                !m._pf.userInvalidated;\n\n            if (m._strict) {\n                m._isValid = m._isValid &&\n                    m._pf.charsLeftOver === 0 &&\n                    m._pf.unusedTokens.length === 0 &&\n                    m._pf.bigHour === undefined;\n            }\n        }\n        return m._isValid;\n    }\n\n    function valid__createInvalid (flags) {\n        var m = create_utc__createUTC(NaN);\n        if (flags != null) {\n            extend(m._pf, flags);\n        }\n        else {\n            m._pf.userInvalidated = true;\n        }\n\n        return m;\n    }\n\n    var momentProperties = utils_hooks__hooks.momentProperties = [];\n\n    function copyConfig(to, from) {\n        var i, prop, val;\n\n        if (typeof from._isAMomentObject !== 'undefined') {\n            to._isAMomentObject = from._isAMomentObject;\n        }\n        if (typeof from._i !== 'undefined') {\n            to._i = from._i;\n        }\n        if (typeof from._f !== 'undefined') {\n            to._f = from._f;\n        }\n        if (typeof from._l !== 'undefined') {\n            to._l = from._l;\n        }\n        if (typeof from._strict !== 'undefined') {\n            to._strict = from._strict;\n        }\n        if (typeof from._tzm !== 'undefined') {\n            to._tzm = from._tzm;\n        }\n        if (typeof from._isUTC !== 'undefined') {\n            to._isUTC = from._isUTC;\n        }\n        if (typeof from._offset !== 'undefined') {\n            to._offset = from._offset;\n        }\n        if (typeof from._pf !== 'undefined') {\n            to._pf = from._pf;\n        }\n        if (typeof from._locale !== 'undefined') {\n            to._locale = from._locale;\n        }\n\n        if (momentProperties.length > 0) {\n            for (i in momentProperties) {\n                prop = momentProperties[i];\n                val = from[prop];\n                if (typeof val !== 'undefined') {\n                    to[prop] = val;\n                }\n            }\n        }\n\n        return to;\n    }\n\n    var updateInProgress = false;\n    function Moment(config) {\n        copyConfig(this, config);\n        this._d = new Date(+config._d);\n        if (updateInProgress === false) {\n            updateInProgress = true;\n            utils_hooks__hooks.updateOffset(this);\n            updateInProgress = false;\n        }\n    }\n\n    function isMoment (obj) {\n        return obj instanceof Moment || (obj != null && hasOwnProp(obj, '_isAMomentObject'));\n    }\n\n    function toInt(argumentForCoercion) {\n        var coercedNumber = +argumentForCoercion,\n            value = 0;\n\n        if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n            if (coercedNumber >= 0) {\n                value = Math.floor(coercedNumber);\n            } else {\n                value = Math.ceil(coercedNumber);\n            }\n        }\n\n        return value;\n    }\n\n    function compareArrays(array1, array2, dontConvert) {\n        var len = Math.min(array1.length, array2.length),\n            lengthDiff = Math.abs(array1.length - array2.length),\n            diffs = 0,\n            i;\n        for (i = 0; i < len; i++) {\n            if ((dontConvert && array1[i] !== array2[i]) ||\n                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n                diffs++;\n            }\n        }\n        return diffs + lengthDiff;\n    }\n\n    function Locale() {\n    }\n\n    var locales = {};\n    var globalLocale;\n\n    function normalizeLocale(key) {\n        return key ? key.toLowerCase().replace('_', '-') : key;\n    }\n    function chooseLocale(names) {\n        var i = 0, j, next, locale, split;\n\n        while (i < names.length) {\n            split = normalizeLocale(names[i]).split('-');\n            j = split.length;\n            next = normalizeLocale(names[i + 1]);\n            next = next ? next.split('-') : null;\n            while (j > 0) {\n                locale = loadLocale(split.slice(0, j).join('-'));\n                if (locale) {\n                    return locale;\n                }\n                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                    break;\n                }\n                j--;\n            }\n            i++;\n        }\n        return null;\n    }\n\n    function loadLocale(name) {\n        var oldLocale = null;\n        if (!locales[name] && typeof module !== 'undefined' &&\n                module && module.exports) {\n            try {\n                oldLocale = globalLocale._abbr;\n                require('./locale/' + name);\n                locale_locales__getSetGlobalLocale(oldLocale);\n            } catch (e) { }\n        }\n        return locales[name];\n    }\n    function locale_locales__getSetGlobalLocale (key, values) {\n        var data;\n        if (key) {\n            if (typeof values === 'undefined') {\n                data = locale_locales__getLocale(key);\n            }\n            else {\n                data = defineLocale(key, values);\n            }\n\n            if (data) {\n                globalLocale = data;\n            }\n        }\n\n        return globalLocale._abbr;\n    }\n\n    function defineLocale (name, values) {\n        if (values !== null) {\n            values.abbr = name;\n            if (!locales[name]) {\n                locales[name] = new Locale();\n            }\n            locales[name].set(values);\n            locale_locales__getSetGlobalLocale(name);\n\n            return locales[name];\n        } else {\n            delete locales[name];\n            return null;\n        }\n    }\n    function locale_locales__getLocale (key) {\n        var locale;\n\n        if (key && key._locale && key._locale._abbr) {\n            key = key._locale._abbr;\n        }\n\n        if (!key) {\n            return globalLocale;\n        }\n\n        if (!isArray(key)) {\n            locale = loadLocale(key);\n            if (locale) {\n                return locale;\n            }\n            key = [key];\n        }\n\n        return chooseLocale(key);\n    }\n\n    var aliases = {};\n\n    function addUnitAlias (unit, shorthand) {\n        var lowerCase = unit.toLowerCase();\n        aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n    }\n\n    function normalizeUnits(units) {\n        return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n    }\n\n    function normalizeObjectUnits(inputObject) {\n        var normalizedInput = {},\n            normalizedProp,\n            prop;\n\n        for (prop in inputObject) {\n            if (hasOwnProp(inputObject, prop)) {\n                normalizedProp = normalizeUnits(prop);\n                if (normalizedProp) {\n                    normalizedInput[normalizedProp] = inputObject[prop];\n                }\n            }\n        }\n\n        return normalizedInput;\n    }\n\n    function makeGetSet (unit, keepTime) {\n        return function (value) {\n            if (value != null) {\n                get_set__set(this, unit, value);\n                utils_hooks__hooks.updateOffset(this, keepTime);\n                return this;\n            } else {\n                return get_set__get(this, unit);\n            }\n        };\n    }\n\n    function get_set__get (mom, unit) {\n        return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();\n    }\n\n    function get_set__set (mom, unit, value) {\n        return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n    }\n\n    function getSet (units, value) {\n        var unit;\n        if (typeof units === 'object') {\n            for (unit in units) {\n                this.set(unit, units[unit]);\n            }\n        } else {\n            units = normalizeUnits(units);\n            if (typeof this[units] === 'function') {\n                return this[units](value);\n            }\n        }\n        return this;\n    }\n\n    function zeroFill(number, targetLength, forceSign) {\n        var output = '' + Math.abs(number),\n            sign = number >= 0;\n\n        while (output.length < targetLength) {\n            output = '0' + output;\n        }\n        return (sign ? (forceSign ? '+' : '') : '-') + output;\n    }\n\n    var formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|x|X|zz?|ZZ?|.)/g;\n\n    var localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\n    var formatFunctions = {};\n\n    var formatTokenFunctions = {};\n    function addFormatToken (token, padded, ordinal, callback) {\n        var func = callback;\n        if (typeof callback === 'string') {\n            func = function () {\n                return this[callback]();\n            };\n        }\n        if (token) {\n            formatTokenFunctions[token] = func;\n        }\n        if (padded) {\n            formatTokenFunctions[padded[0]] = function () {\n                return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n            };\n        }\n        if (ordinal) {\n            formatTokenFunctions[ordinal] = function () {\n                return this.localeData().ordinal(func.apply(this, arguments), token);\n            };\n        }\n    }\n\n    function removeFormattingTokens(input) {\n        if (input.match(/\\[[\\s\\S]/)) {\n            return input.replace(/^\\[|\\]$/g, '');\n        }\n        return input.replace(/\\\\/g, '');\n    }\n\n    function makeFormatFunction(format) {\n        var array = format.match(formattingTokens), i, length;\n\n        for (i = 0, length = array.length; i < length; i++) {\n            if (formatTokenFunctions[array[i]]) {\n                array[i] = formatTokenFunctions[array[i]];\n            } else {\n                array[i] = removeFormattingTokens(array[i]);\n            }\n        }\n\n        return function (mom) {\n            var output = '';\n            for (i = 0; i < length; i++) {\n                output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];\n            }\n            return output;\n        };\n    }\n    function formatMoment(m, format) {\n        if (!m.isValid()) {\n            return m.localeData().invalidDate();\n        }\n\n        format = expandFormat(format, m.localeData());\n\n        if (!formatFunctions[format]) {\n            formatFunctions[format] = makeFormatFunction(format);\n        }\n\n        return formatFunctions[format](m);\n    }\n\n    function expandFormat(format, locale) {\n        var i = 5;\n\n        function replaceLongDateFormatTokens(input) {\n            return locale.longDateFormat(input) || input;\n        }\n\n        localFormattingTokens.lastIndex = 0;\n        while (i >= 0 && localFormattingTokens.test(format)) {\n            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n            localFormattingTokens.lastIndex = 0;\n            i -= 1;\n        }\n\n        return format;\n    }\n\n    var match1         = /\\d/;            //       0 - 9\n    var match2         = /\\d\\d/;          //      00 - 99\n    var match3         = /\\d{3}/;         //     000 - 999\n    var match4         = /\\d{4}/;         //    0000 - 9999\n    var match6         = /[+-]?\\d{6}/;    // -999999 - 999999\n    var match1to2      = /\\d\\d?/;         //       0 - 99\n    var match1to3      = /\\d{1,3}/;       //       0 - 999\n    var match1to4      = /\\d{1,4}/;       //       0 - 9999\n    var match1to6      = /[+-]?\\d{1,6}/;  // -999999 - 999999\n\n    var matchUnsigned  = /\\d+/;           //       0 - inf\n    var matchSigned    = /[+-]?\\d+/;      //    -inf - inf\n\n    var matchOffset    = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\n\n    var matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\n    var matchWord = /[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF\\/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i;\n\n    var regexes = {};\n\n    function addRegexToken (token, regex, strictRegex) {\n        regexes[token] = typeof regex === 'function' ? regex : function (isStrict) {\n            return (isStrict && strictRegex) ? strictRegex : regex;\n        };\n    }\n\n    function getParseRegexForToken (token, config) {\n        if (!hasOwnProp(regexes, token)) {\n            return new RegExp(unescapeFormat(token));\n        }\n\n        return regexes[token](config._strict, config._locale);\n    }\n    function unescapeFormat(s) {\n        return s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n            return p1 || p2 || p3 || p4;\n        }).replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n    }\n\n    var tokens = {};\n\n    function addParseToken (token, callback) {\n        var i, func = callback;\n        if (typeof token === 'string') {\n            token = [token];\n        }\n        if (typeof callback === 'number') {\n            func = function (input, array) {\n                array[callback] = toInt(input);\n            };\n        }\n        for (i = 0; i < token.length; i++) {\n            tokens[token[i]] = func;\n        }\n    }\n\n    function addWeekParseToken (token, callback) {\n        addParseToken(token, function (input, array, config, token) {\n            config._w = config._w || {};\n            callback(input, config._w, config, token);\n        });\n    }\n\n    function addTimeToArrayFromToken(token, input, config) {\n        if (input != null && hasOwnProp(tokens, token)) {\n            tokens[token](input, config._a, config, token);\n        }\n    }\n\n    var YEAR = 0;\n    var MONTH = 1;\n    var DATE = 2;\n    var HOUR = 3;\n    var MINUTE = 4;\n    var SECOND = 5;\n    var MILLISECOND = 6;\n\n    function daysInMonth(year, month) {\n        return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n    }\n\n    addFormatToken('M', ['MM', 2], 'Mo', function () {\n        return this.month() + 1;\n    });\n\n    addFormatToken('MMM', 0, 0, function (format) {\n        return this.localeData().monthsShort(this, format);\n    });\n\n    addFormatToken('MMMM', 0, 0, function (format) {\n        return this.localeData().months(this, format);\n    });\n\n    addUnitAlias('month', 'M');\n\n    addRegexToken('M',    match1to2);\n    addRegexToken('MM',   match1to2, match2);\n    addRegexToken('MMM',  matchWord);\n    addRegexToken('MMMM', matchWord);\n\n    addParseToken(['M', 'MM'], function (input, array) {\n        array[MONTH] = toInt(input) - 1;\n    });\n\n    addParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n        var month = config._locale.monthsParse(input, token, config._strict);\n        if (month != null) {\n            array[MONTH] = month;\n        } else {\n            config._pf.invalidMonth = input;\n        }\n    });\n\n    var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\n    function localeMonths (m) {\n        return this._months[m.month()];\n    }\n\n    var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\n    function localeMonthsShort (m) {\n        return this._monthsShort[m.month()];\n    }\n\n    function localeMonthsParse (monthName, format, strict) {\n        var i, mom, regex;\n\n        if (!this._monthsParse) {\n            this._monthsParse = [];\n            this._longMonthsParse = [];\n            this._shortMonthsParse = [];\n        }\n\n        for (i = 0; i < 12; i++) {\n            mom = create_utc__createUTC([2000, i]);\n            if (strict && !this._longMonthsParse[i]) {\n                this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n                this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n            }\n            if (!strict && !this._monthsParse[i]) {\n                regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n                this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n            }\n            if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n                return i;\n            } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n                return i;\n            } else if (!strict && this._monthsParse[i].test(monthName)) {\n                return i;\n            }\n        }\n    }\n\n    function setMonth (mom, value) {\n        var dayOfMonth;\n        if (typeof value === 'string') {\n            value = mom.localeData().monthsParse(value);\n            if (typeof value !== 'number') {\n                return mom;\n            }\n        }\n\n        dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n        return mom;\n    }\n\n    function getSetMonth (value) {\n        if (value != null) {\n            setMonth(this, value);\n            utils_hooks__hooks.updateOffset(this, true);\n            return this;\n        } else {\n            return get_set__get(this, 'Month');\n        }\n    }\n\n    function getDaysInMonth () {\n        return daysInMonth(this.year(), this.month());\n    }\n\n    function checkOverflow (m) {\n        var overflow;\n        var a = m._a;\n\n        if (a && m._pf.overflow === -2) {\n            overflow =\n                a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :\n                a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n                a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n                a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :\n                a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :\n                a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n                -1;\n\n            if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n                overflow = DATE;\n            }\n\n            m._pf.overflow = overflow;\n        }\n\n        return m;\n    }\n\n    function warn(msg) {\n        if (utils_hooks__hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) {\n            console.warn('Deprecation warning: ' + msg);\n        }\n    }\n\n    function deprecate(msg, fn) {\n        var firstTime = true;\n        return extend(function () {\n            if (firstTime) {\n                warn(msg);\n                firstTime = false;\n            }\n            return fn.apply(this, arguments);\n        }, fn);\n    }\n\n    var deprecations = {};\n\n    function deprecateSimple(name, msg) {\n        if (!deprecations[name]) {\n            warn(msg);\n            deprecations[name] = true;\n        }\n    }\n\n    utils_hooks__hooks.suppressDeprecationWarnings = false;\n\n    var from_string__isoRegex = /^\\s*(?:[+-]\\d{6}|\\d{4})-(?:(\\d\\d-\\d\\d)|(W\\d\\d$)|(W\\d\\d-\\d)|(\\d\\d\\d))((T| )(\\d\\d(:\\d\\d(:\\d\\d(\\.\\d+)?)?)?)?([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\n    var isoDates = [\n        ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d{2}-\\d{2}/],\n        ['YYYY-MM-DD', /\\d{4}-\\d{2}-\\d{2}/],\n        ['GGGG-[W]WW-E', /\\d{4}-W\\d{2}-\\d/],\n        ['GGGG-[W]WW', /\\d{4}-W\\d{2}/],\n        ['YYYY-DDD', /\\d{4}-\\d{3}/]\n    ];\n    var isoTimes = [\n        ['HH:mm:ss.SSSS', /(T| )\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n        ['HH:mm:ss', /(T| )\\d\\d:\\d\\d:\\d\\d/],\n        ['HH:mm', /(T| )\\d\\d:\\d\\d/],\n        ['HH', /(T| )\\d\\d/]\n    ];\n\n    var aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\n    function configFromISO(config) {\n        var i, l,\n            string = config._i,\n            match = from_string__isoRegex.exec(string);\n\n        if (match) {\n            config._pf.iso = true;\n            for (i = 0, l = isoDates.length; i < l; i++) {\n                if (isoDates[i][1].exec(string)) {\n                    config._f = isoDates[i][0] + (match[6] || ' ');\n                    break;\n                }\n            }\n            for (i = 0, l = isoTimes.length; i < l; i++) {\n                if (isoTimes[i][1].exec(string)) {\n                    config._f += isoTimes[i][0];\n                    break;\n                }\n            }\n            if (string.match(matchOffset)) {\n                config._f += 'Z';\n            }\n            configFromStringAndFormat(config);\n        } else {\n            config._isValid = false;\n        }\n    }\n    function configFromString(config) {\n        var matched = aspNetJsonRegex.exec(config._i);\n\n        if (matched !== null) {\n            config._d = new Date(+matched[1]);\n            return;\n        }\n\n        configFromISO(config);\n        if (config._isValid === false) {\n            delete config._isValid;\n            utils_hooks__hooks.createFromInputFallback(config);\n        }\n    }\n\n    utils_hooks__hooks.createFromInputFallback = deprecate(\n        'moment construction falls back to js Date. This is ' +\n        'discouraged and will be removed in upcoming major ' +\n        'release. Please refer to ' +\n        'https://github.com/moment/moment/issues/1407 for more info.',\n        function (config) {\n            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n        }\n    );\n\n    function createDate (y, m, d, h, M, s, ms) {\n        var date = new Date(y, m, d, h, M, s, ms);\n        if (y < 1970) {\n            date.setFullYear(y);\n        }\n        return date;\n    }\n\n    function createUTCDate (y) {\n        var date = new Date(Date.UTC.apply(null, arguments));\n        if (y < 1970) {\n            date.setUTCFullYear(y);\n        }\n        return date;\n    }\n\n    addFormatToken(0, ['YY', 2], 0, function () {\n        return this.year() % 100;\n    });\n\n    addFormatToken(0, ['YYYY',   4],       0, 'year');\n    addFormatToken(0, ['YYYYY',  5],       0, 'year');\n    addFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\n    addUnitAlias('year', 'y');\n\n    addRegexToken('Y',      matchSigned);\n    addRegexToken('YY',     match1to2, match2);\n    addRegexToken('YYYY',   match1to4, match4);\n    addRegexToken('YYYYY',  match1to6, match6);\n    addRegexToken('YYYYYY', match1to6, match6);\n\n    addParseToken(['YYYY', 'YYYYY', 'YYYYYY'], YEAR);\n    addParseToken('YY', function (input, array) {\n        array[YEAR] = utils_hooks__hooks.parseTwoDigitYear(input);\n    });\n\n    function daysInYear(year) {\n        return isLeapYear(year) ? 366 : 365;\n    }\n\n    function isLeapYear(year) {\n        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n    }\n\n    utils_hooks__hooks.parseTwoDigitYear = function (input) {\n        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n    };\n\n    var getSetYear = makeGetSet('FullYear', false);\n\n    function getIsLeapYear () {\n        return isLeapYear(this.year());\n    }\n\n    addFormatToken('w', ['ww', 2], 'wo', 'week');\n    addFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\n    addUnitAlias('week', 'w');\n    addUnitAlias('isoWeek', 'W');\n\n    addRegexToken('w',  match1to2);\n    addRegexToken('ww', match1to2, match2);\n    addRegexToken('W',  match1to2);\n    addRegexToken('WW', match1to2, match2);\n\n    addWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n        week[token.substr(0, 1)] = toInt(input);\n    });\n    function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {\n        var end = firstDayOfWeekOfYear - firstDayOfWeek,\n            daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),\n            adjustedMoment;\n\n\n        if (daysToDayOfWeek > end) {\n            daysToDayOfWeek -= 7;\n        }\n\n        if (daysToDayOfWeek < end - 7) {\n            daysToDayOfWeek += 7;\n        }\n\n        adjustedMoment = local__createLocal(mom).add(daysToDayOfWeek, 'd');\n        return {\n            week: Math.ceil(adjustedMoment.dayOfYear() / 7),\n            year: adjustedMoment.year()\n        };\n    }\n\n    function localeWeek (mom) {\n        return weekOfYear(mom, this._week.dow, this._week.doy).week;\n    }\n\n    var defaultLocaleWeek = {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    };\n\n    function localeFirstDayOfWeek () {\n        return this._week.dow;\n    }\n\n    function localeFirstDayOfYear () {\n        return this._week.doy;\n    }\n\n    function getSetWeek (input) {\n        var week = this.localeData().week(this);\n        return input == null ? week : this.add((input - week) * 7, 'd');\n    }\n\n    function getSetISOWeek (input) {\n        var week = weekOfYear(this, 1, 4).week;\n        return input == null ? week : this.add((input - week) * 7, 'd');\n    }\n\n    addFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\n    addUnitAlias('dayOfYear', 'DDD');\n\n    addRegexToken('DDD',  match1to3);\n    addRegexToken('DDDD', match3);\n    addParseToken(['DDD', 'DDDD'], function (input, array, config) {\n        config._dayOfYear = toInt(input);\n    });\n    function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {\n        var d = createUTCDate(year, 0, 1).getUTCDay();\n        var daysToAdd;\n        var dayOfYear;\n\n        d = d === 0 ? 7 : d;\n        weekday = weekday != null ? weekday : firstDayOfWeek;\n        daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0);\n        dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;\n\n        return {\n            year      : dayOfYear > 0 ? year      : year - 1,\n            dayOfYear : dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear\n        };\n    }\n\n    function getSetDayOfYear (input) {\n        var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n        return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n    }\n    function defaults(a, b, c) {\n        if (a != null) {\n            return a;\n        }\n        if (b != null) {\n            return b;\n        }\n        return c;\n    }\n\n    function currentDateArray(config) {\n        var now = new Date();\n        if (config._useUTC) {\n            return [now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()];\n        }\n        return [now.getFullYear(), now.getMonth(), now.getDate()];\n    }\n    function configFromArray (config) {\n        var i, date, input = [], currentDate, yearToUse;\n\n        if (config._d) {\n            return;\n        }\n\n        currentDate = currentDateArray(config);\n        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n            dayOfYearFromWeekInfo(config);\n        }\n        if (config._dayOfYear) {\n            yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n            if (config._dayOfYear > daysInYear(yearToUse)) {\n                config._pf._overflowDayOfYear = true;\n            }\n\n            date = createUTCDate(yearToUse, 0, config._dayOfYear);\n            config._a[MONTH] = date.getUTCMonth();\n            config._a[DATE] = date.getUTCDate();\n        }\n        for (i = 0; i < 3 && config._a[i] == null; ++i) {\n            config._a[i] = input[i] = currentDate[i];\n        }\n        for (; i < 7; i++) {\n            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n        }\n        if (config._a[HOUR] === 24 &&\n                config._a[MINUTE] === 0 &&\n                config._a[SECOND] === 0 &&\n                config._a[MILLISECOND] === 0) {\n            config._nextDay = true;\n            config._a[HOUR] = 0;\n        }\n\n        config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n        if (config._tzm != null) {\n            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n        }\n\n        if (config._nextDay) {\n            config._a[HOUR] = 24;\n        }\n    }\n\n    function dayOfYearFromWeekInfo(config) {\n        var w, weekYear, week, weekday, dow, doy, temp;\n\n        w = config._w;\n        if (w.GG != null || w.W != null || w.E != null) {\n            dow = 1;\n            doy = 4;\n            weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(local__createLocal(), 1, 4).year);\n            week = defaults(w.W, 1);\n            weekday = defaults(w.E, 1);\n        } else {\n            dow = config._locale._week.dow;\n            doy = config._locale._week.doy;\n\n            weekYear = defaults(w.gg, config._a[YEAR], weekOfYear(local__createLocal(), dow, doy).year);\n            week = defaults(w.w, 1);\n\n            if (w.d != null) {\n                weekday = w.d;\n                if (weekday < dow) {\n                    ++week;\n                }\n            } else if (w.e != null) {\n                weekday = w.e + dow;\n            } else {\n                weekday = dow;\n            }\n        }\n        temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);\n\n        config._a[YEAR] = temp.year;\n        config._dayOfYear = temp.dayOfYear;\n    }\n\n    utils_hooks__hooks.ISO_8601 = function () {};\n    function configFromStringAndFormat(config) {\n        if (config._f === utils_hooks__hooks.ISO_8601) {\n            configFromISO(config);\n            return;\n        }\n\n        config._a = [];\n        config._pf.empty = true;\n        var string = '' + config._i,\n            i, parsedInput, tokens, token, skipped,\n            stringLength = string.length,\n            totalParsedInputLength = 0;\n\n        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n        for (i = 0; i < tokens.length; i++) {\n            token = tokens[i];\n            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n            if (parsedInput) {\n                skipped = string.substr(0, string.indexOf(parsedInput));\n                if (skipped.length > 0) {\n                    config._pf.unusedInput.push(skipped);\n                }\n                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n                totalParsedInputLength += parsedInput.length;\n            }\n            if (formatTokenFunctions[token]) {\n                if (parsedInput) {\n                    config._pf.empty = false;\n                }\n                else {\n                    config._pf.unusedTokens.push(token);\n                }\n                addTimeToArrayFromToken(token, parsedInput, config);\n            }\n            else if (config._strict && !parsedInput) {\n                config._pf.unusedTokens.push(token);\n            }\n        }\n        config._pf.charsLeftOver = stringLength - totalParsedInputLength;\n        if (string.length > 0) {\n            config._pf.unusedInput.push(string);\n        }\n        if (config._pf.bigHour === true && config._a[HOUR] <= 12) {\n            config._pf.bigHour = undefined;\n        }\n        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n        configFromArray(config);\n        checkOverflow(config);\n    }\n\n\n    function meridiemFixWrap (locale, hour, meridiem) {\n        var isPm;\n\n        if (meridiem == null) {\n            return hour;\n        }\n        if (locale.meridiemHour != null) {\n            return locale.meridiemHour(hour, meridiem);\n        } else if (locale.isPM != null) {\n            isPm = locale.isPM(meridiem);\n            if (isPm && hour < 12) {\n                hour += 12;\n            }\n            if (!isPm && hour === 12) {\n                hour = 0;\n            }\n            return hour;\n        } else {\n            return hour;\n        }\n    }\n\n    function configFromStringAndArray(config) {\n        var tempConfig,\n            bestMoment,\n\n            scoreToBeat,\n            i,\n            currentScore;\n\n        if (config._f.length === 0) {\n            config._pf.invalidFormat = true;\n            config._d = new Date(NaN);\n            return;\n        }\n\n        for (i = 0; i < config._f.length; i++) {\n            currentScore = 0;\n            tempConfig = copyConfig({}, config);\n            if (config._useUTC != null) {\n                tempConfig._useUTC = config._useUTC;\n            }\n            tempConfig._pf = defaultParsingFlags();\n            tempConfig._f = config._f[i];\n            configFromStringAndFormat(tempConfig);\n\n            if (!valid__isValid(tempConfig)) {\n                continue;\n            }\n            currentScore += tempConfig._pf.charsLeftOver;\n            currentScore += tempConfig._pf.unusedTokens.length * 10;\n\n            tempConfig._pf.score = currentScore;\n\n            if (scoreToBeat == null || currentScore < scoreToBeat) {\n                scoreToBeat = currentScore;\n                bestMoment = tempConfig;\n            }\n        }\n\n        extend(config, bestMoment || tempConfig);\n    }\n\n    function configFromObject(config) {\n        if (config._d) {\n            return;\n        }\n\n        var i = normalizeObjectUnits(config._i);\n        config._a = [i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond];\n\n        configFromArray(config);\n    }\n\n    function createFromConfig (config) {\n        var input = config._i,\n            format = config._f,\n            res;\n\n        config._locale = config._locale || locale_locales__getLocale(config._l);\n\n        if (input === null || (format === undefined && input === '')) {\n            return valid__createInvalid({nullInput: true});\n        }\n\n        if (typeof input === 'string') {\n            config._i = input = config._locale.preparse(input);\n        }\n\n        if (isMoment(input)) {\n            return new Moment(checkOverflow(input));\n        } else if (isArray(format)) {\n            configFromStringAndArray(config);\n        } else if (format) {\n            configFromStringAndFormat(config);\n        } else {\n            configFromInput(config);\n        }\n\n        res = new Moment(checkOverflow(config));\n        if (res._nextDay) {\n            res.add(1, 'd');\n            res._nextDay = undefined;\n        }\n\n        return res;\n    }\n\n    function configFromInput(config) {\n        var input = config._i;\n        if (input === undefined) {\n            config._d = new Date();\n        } else if (isDate(input)) {\n            config._d = new Date(+input);\n        } else if (typeof input === 'string') {\n            configFromString(config);\n        } else if (isArray(input)) {\n            config._a = map(input.slice(0), function (obj) {\n                return parseInt(obj, 10);\n            });\n            configFromArray(config);\n        } else if (typeof(input) === 'object') {\n            configFromObject(config);\n        } else if (typeof(input) === 'number') {\n            config._d = new Date(input);\n        } else {\n            utils_hooks__hooks.createFromInputFallback(config);\n        }\n    }\n\n    function createLocalOrUTC (input, format, locale, strict, isUTC) {\n        var c = {};\n\n        if (typeof(locale) === 'boolean') {\n            strict = locale;\n            locale = undefined;\n        }\n        c._isAMomentObject = true;\n        c._useUTC = c._isUTC = isUTC;\n        c._l = locale;\n        c._i = input;\n        c._f = format;\n        c._strict = strict;\n        c._pf = defaultParsingFlags();\n\n        return createFromConfig(c);\n    }\n\n    function local__createLocal (input, format, locale, strict) {\n        return createLocalOrUTC(input, format, locale, strict, false);\n    }\n\n    var prototypeMin = deprecate(\n         'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',\n         function () {\n             var other = local__createLocal.apply(null, arguments);\n             return other < this ? this : other;\n         }\n     );\n\n    var prototypeMax = deprecate(\n        'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',\n        function () {\n            var other = local__createLocal.apply(null, arguments);\n            return other > this ? this : other;\n        }\n    );\n    function pickBy(fn, moments) {\n        var res, i;\n        if (moments.length === 1 && isArray(moments[0])) {\n            moments = moments[0];\n        }\n        if (!moments.length) {\n            return local__createLocal();\n        }\n        res = moments[0];\n        for (i = 1; i < moments.length; ++i) {\n            if (moments[i][fn](res)) {\n                res = moments[i];\n            }\n        }\n        return res;\n    }\n    function min () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isBefore', args);\n    }\n\n    function max () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isAfter', args);\n    }\n\n    function Duration (duration) {\n        var normalizedInput = normalizeObjectUnits(duration),\n            years = normalizedInput.year || 0,\n            quarters = normalizedInput.quarter || 0,\n            months = normalizedInput.month || 0,\n            weeks = normalizedInput.week || 0,\n            days = normalizedInput.day || 0,\n            hours = normalizedInput.hour || 0,\n            minutes = normalizedInput.minute || 0,\n            seconds = normalizedInput.second || 0,\n            milliseconds = normalizedInput.millisecond || 0;\n        this._milliseconds = +milliseconds +\n            seconds * 1e3 + // 1000\n            minutes * 6e4 + // 1000 * 60\n            hours * 36e5; // 1000 * 60 * 60\n        this._days = +days +\n            weeks * 7;\n        this._months = +months +\n            quarters * 3 +\n            years * 12;\n\n        this._data = {};\n\n        this._locale = locale_locales__getLocale();\n\n        this._bubble();\n    }\n\n    function isDuration (obj) {\n        return obj instanceof Duration;\n    }\n\n    function offset (token, separator) {\n        addFormatToken(token, 0, 0, function () {\n            var offset = this.utcOffset();\n            var sign = '+';\n            if (offset < 0) {\n                offset = -offset;\n                sign = '-';\n            }\n            return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n        });\n    }\n\n    offset('Z', ':');\n    offset('ZZ', '');\n\n    addRegexToken('Z',  matchOffset);\n    addRegexToken('ZZ', matchOffset);\n    addParseToken(['Z', 'ZZ'], function (input, array, config) {\n        config._useUTC = true;\n        config._tzm = offsetFromString(input);\n    });\n    var chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\n    function offsetFromString(string) {\n        var matches = ((string || '').match(matchOffset) || []);\n        var chunk   = matches[matches.length - 1] || [];\n        var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n        var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n        return parts[0] === '+' ? minutes : -minutes;\n    }\n    function cloneWithOffset(input, model) {\n        var res, diff;\n        if (model._isUTC) {\n            res = model.clone();\n            diff = (isMoment(input) || isDate(input) ? +input : +local__createLocal(input)) - (+res);\n            res._d.setTime(+res._d + diff);\n            utils_hooks__hooks.updateOffset(res, false);\n            return res;\n        } else {\n            return local__createLocal(input).local();\n        }\n        return model._isUTC ? local__createLocal(input).zone(model._offset || 0) : local__createLocal(input).local();\n    }\n\n    function getDateOffset (m) {\n        return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n    }\n    utils_hooks__hooks.updateOffset = function () {};\n    function getSetOffset (input, keepLocalTime) {\n        var offset = this._offset || 0,\n            localAdjust;\n        if (input != null) {\n            if (typeof input === 'string') {\n                input = offsetFromString(input);\n            }\n            if (Math.abs(input) < 16) {\n                input = input * 60;\n            }\n            if (!this._isUTC && keepLocalTime) {\n                localAdjust = getDateOffset(this);\n            }\n            this._offset = input;\n            this._isUTC = true;\n            if (localAdjust != null) {\n                this.add(localAdjust, 'm');\n            }\n            if (offset !== input) {\n                if (!keepLocalTime || this._changeInProgress) {\n                    add_subtract__addSubtract(this, create__createDuration(input - offset, 'm'), 1, false);\n                } else if (!this._changeInProgress) {\n                    this._changeInProgress = true;\n                    utils_hooks__hooks.updateOffset(this, true);\n                    this._changeInProgress = null;\n                }\n            }\n            return this;\n        } else {\n            return this._isUTC ? offset : getDateOffset(this);\n        }\n    }\n\n    function getSetZone (input, keepLocalTime) {\n        if (input != null) {\n            if (typeof input !== 'string') {\n                input = -input;\n            }\n\n            this.utcOffset(input, keepLocalTime);\n\n            return this;\n        } else {\n            return -this.utcOffset();\n        }\n    }\n\n    function setOffsetToUTC (keepLocalTime) {\n        return this.utcOffset(0, keepLocalTime);\n    }\n\n    function setOffsetToLocal (keepLocalTime) {\n        if (this._isUTC) {\n            this.utcOffset(0, keepLocalTime);\n            this._isUTC = false;\n\n            if (keepLocalTime) {\n                this.subtract(getDateOffset(this), 'm');\n            }\n        }\n        return this;\n    }\n\n    function setOffsetToParsedOffset () {\n        if (this._tzm) {\n            this.utcOffset(this._tzm);\n        } else if (typeof this._i === 'string') {\n            this.utcOffset(offsetFromString(this._i));\n        }\n        return this;\n    }\n\n    function hasAlignedHourOffset (input) {\n        if (!input) {\n            input = 0;\n        }\n        else {\n            input = local__createLocal(input).utcOffset();\n        }\n\n        return (this.utcOffset() - input) % 60 === 0;\n    }\n\n    function isDaylightSavingTime () {\n        return (\n            this.utcOffset() > this.clone().month(0).utcOffset() ||\n            this.utcOffset() > this.clone().month(5).utcOffset()\n        );\n    }\n\n    function isDaylightSavingTimeShifted () {\n        if (this._a) {\n            var other = this._isUTC ? create_utc__createUTC(this._a) : local__createLocal(this._a);\n            return this.isValid() && compareArrays(this._a, other.toArray()) > 0;\n        }\n\n        return false;\n    }\n\n    function isLocal () {\n        return !this._isUTC;\n    }\n\n    function isUtcOffset () {\n        return this._isUTC;\n    }\n\n    function isUtc () {\n        return this._isUTC && this._offset === 0;\n    }\n\n    var aspNetRegex = /(\\-)?(?:(\\d*)\\.)?(\\d+)\\:(\\d+)(?:\\:(\\d+)\\.?(\\d{3})?)?/;\n    var create__isoRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/;\n\n    function create__createDuration (input, key) {\n        var duration = input,\n            match = null,\n            sign,\n            ret,\n            diffRes;\n\n        if (isDuration(input)) {\n            duration = {\n                ms : input._milliseconds,\n                d  : input._days,\n                M  : input._months\n            };\n        } else if (typeof input === 'number') {\n            duration = {};\n            if (key) {\n                duration[key] = input;\n            } else {\n                duration.milliseconds = input;\n            }\n        } else if (!!(match = aspNetRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            duration = {\n                y  : 0,\n                d  : toInt(match[DATE])        * sign,\n                h  : toInt(match[HOUR])        * sign,\n                m  : toInt(match[MINUTE])      * sign,\n                s  : toInt(match[SECOND])      * sign,\n                ms : toInt(match[MILLISECOND]) * sign\n            };\n        } else if (!!(match = create__isoRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            duration = {\n                y : parseIso(match[2], sign),\n                M : parseIso(match[3], sign),\n                d : parseIso(match[4], sign),\n                h : parseIso(match[5], sign),\n                m : parseIso(match[6], sign),\n                s : parseIso(match[7], sign),\n                w : parseIso(match[8], sign)\n            };\n        } else if (duration == null) {// checks for null or undefined\n            duration = {};\n        } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n            diffRes = momentsDifference(local__createLocal(duration.from), local__createLocal(duration.to));\n\n            duration = {};\n            duration.ms = diffRes.milliseconds;\n            duration.M = diffRes.months;\n        }\n\n        ret = new Duration(duration);\n\n        if (isDuration(input) && hasOwnProp(input, '_locale')) {\n            ret._locale = input._locale;\n        }\n\n        return ret;\n    }\n\n    create__createDuration.fn = Duration.prototype;\n\n    function parseIso (inp, sign) {\n        var res = inp && parseFloat(inp.replace(',', '.'));\n        return (isNaN(res) ? 0 : res) * sign;\n    }\n\n    function positiveMomentsDifference(base, other) {\n        var res = {milliseconds: 0, months: 0};\n\n        res.months = other.month() - base.month() +\n            (other.year() - base.year()) * 12;\n        if (base.clone().add(res.months, 'M').isAfter(other)) {\n            --res.months;\n        }\n\n        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n        return res;\n    }\n\n    function momentsDifference(base, other) {\n        var res;\n        other = cloneWithOffset(other, base);\n        if (base.isBefore(other)) {\n            res = positiveMomentsDifference(base, other);\n        } else {\n            res = positiveMomentsDifference(other, base);\n            res.milliseconds = -res.milliseconds;\n            res.months = -res.months;\n        }\n\n        return res;\n    }\n\n    function createAdder(direction, name) {\n        return function (val, period) {\n            var dur, tmp;\n            if (period !== null && !isNaN(+period)) {\n                deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period).');\n                tmp = val; val = period; period = tmp;\n            }\n\n            val = typeof val === 'string' ? +val : val;\n            dur = create__createDuration(val, period);\n            add_subtract__addSubtract(this, dur, direction);\n            return this;\n        };\n    }\n\n    function add_subtract__addSubtract (mom, duration, isAdding, updateOffset) {\n        var milliseconds = duration._milliseconds,\n            days = duration._days,\n            months = duration._months;\n        updateOffset = updateOffset == null ? true : updateOffset;\n\n        if (milliseconds) {\n            mom._d.setTime(+mom._d + milliseconds * isAdding);\n        }\n        if (days) {\n            get_set__set(mom, 'Date', get_set__get(mom, 'Date') + days * isAdding);\n        }\n        if (months) {\n            setMonth(mom, get_set__get(mom, 'Month') + months * isAdding);\n        }\n        if (updateOffset) {\n            utils_hooks__hooks.updateOffset(mom, days || months);\n        }\n    }\n\n    var add_subtract__add      = createAdder(1, 'add');\n    var add_subtract__subtract = createAdder(-1, 'subtract');\n\n    function moment_calendar__calendar (time) {\n        var now = time || local__createLocal(),\n            sod = cloneWithOffset(now, this).startOf('day'),\n            diff = this.diff(sod, 'days', true),\n            format = diff < -6 ? 'sameElse' :\n                diff < -1 ? 'lastWeek' :\n                diff < 0 ? 'lastDay' :\n                diff < 1 ? 'sameDay' :\n                diff < 2 ? 'nextDay' :\n                diff < 7 ? 'nextWeek' : 'sameElse';\n        return this.format(this.localeData().calendar(format, this, local__createLocal(now)));\n    }\n\n    function clone () {\n        return new Moment(this);\n    }\n\n    function isAfter (input, units) {\n        var inputMs;\n        units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');\n        if (units === 'millisecond') {\n            input = isMoment(input) ? input : local__createLocal(input);\n            return +this > +input;\n        } else {\n            inputMs = isMoment(input) ? +input : +local__createLocal(input);\n            return inputMs < +this.clone().startOf(units);\n        }\n    }\n\n    function isBefore (input, units) {\n        var inputMs;\n        units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');\n        if (units === 'millisecond') {\n            input = isMoment(input) ? input : local__createLocal(input);\n            return +this < +input;\n        } else {\n            inputMs = isMoment(input) ? +input : +local__createLocal(input);\n            return +this.clone().endOf(units) < inputMs;\n        }\n    }\n\n    function isBetween (from, to, units) {\n        return this.isAfter(from, units) && this.isBefore(to, units);\n    }\n\n    function isSame (input, units) {\n        var inputMs;\n        units = normalizeUnits(units || 'millisecond');\n        if (units === 'millisecond') {\n            input = isMoment(input) ? input : local__createLocal(input);\n            return +this === +input;\n        } else {\n            inputMs = +local__createLocal(input);\n            return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units));\n        }\n    }\n\n    function absFloor (number) {\n        if (number < 0) {\n            return Math.ceil(number);\n        } else {\n            return Math.floor(number);\n        }\n    }\n\n    function diff (input, units, asFloat) {\n        var that = cloneWithOffset(input, this),\n            zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4,\n            delta, output;\n\n        units = normalizeUnits(units);\n\n        if (units === 'year' || units === 'month' || units === 'quarter') {\n            output = monthDiff(this, that);\n            if (units === 'quarter') {\n                output = output / 3;\n            } else if (units === 'year') {\n                output = output / 12;\n            }\n        } else {\n            delta = this - that;\n            output = units === 'second' ? delta / 1e3 : // 1000\n                units === 'minute' ? delta / 6e4 : // 1000 * 60\n                units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60\n                units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst\n                units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst\n                delta;\n        }\n        return asFloat ? output : absFloor(output);\n    }\n\n    function monthDiff (a, b) {\n        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n            anchor = a.clone().add(wholeMonthDiff, 'months'),\n            anchor2, adjust;\n\n        if (b - anchor < 0) {\n            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n            adjust = (b - anchor) / (anchor - anchor2);\n        } else {\n            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n            adjust = (b - anchor) / (anchor2 - anchor);\n        }\n\n        return -(wholeMonthDiff + adjust);\n    }\n\n    utils_hooks__hooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\n\n    function toString () {\n        return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n    }\n\n    function moment_format__toISOString () {\n        var m = this.clone().utc();\n        if (0 < m.year() && m.year() <= 9999) {\n            if ('function' === typeof Date.prototype.toISOString) {\n                return this.toDate().toISOString();\n            } else {\n                return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n            }\n        } else {\n            return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n        }\n    }\n\n    function format (inputString) {\n        var output = formatMoment(this, inputString || utils_hooks__hooks.defaultFormat);\n        return this.localeData().postformat(output);\n    }\n\n    function from (time, withoutSuffix) {\n        return create__createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n    }\n\n    function fromNow (withoutSuffix) {\n        return this.from(local__createLocal(), withoutSuffix);\n    }\n\n    function locale (key) {\n        var newLocaleData;\n\n        if (key === undefined) {\n            return this._locale._abbr;\n        } else {\n            newLocaleData = locale_locales__getLocale(key);\n            if (newLocaleData != null) {\n                this._locale = newLocaleData;\n            }\n            return this;\n        }\n    }\n\n    var lang = deprecate(\n        'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n        function (key) {\n            if (key === undefined) {\n                return this.localeData();\n            } else {\n                return this.locale(key);\n            }\n        }\n    );\n\n    function localeData () {\n        return this._locale;\n    }\n\n    function startOf (units) {\n        units = normalizeUnits(units);\n        switch (units) {\n        case 'year':\n            this.month(0);\n            /* falls through */\n        case 'quarter':\n        case 'month':\n            this.date(1);\n            /* falls through */\n        case 'week':\n        case 'isoWeek':\n        case 'day':\n            this.hours(0);\n            /* falls through */\n        case 'hour':\n            this.minutes(0);\n            /* falls through */\n        case 'minute':\n            this.seconds(0);\n            /* falls through */\n        case 'second':\n            this.milliseconds(0);\n        }\n        if (units === 'week') {\n            this.weekday(0);\n        }\n        if (units === 'isoWeek') {\n            this.isoWeekday(1);\n        }\n        if (units === 'quarter') {\n            this.month(Math.floor(this.month() / 3) * 3);\n        }\n\n        return this;\n    }\n\n    function endOf (units) {\n        units = normalizeUnits(units);\n        if (units === undefined || units === 'millisecond') {\n            return this;\n        }\n        return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');\n    }\n\n    function to_type__valueOf () {\n        return +this._d - ((this._offset || 0) * 60000);\n    }\n\n    function unix () {\n        return Math.floor(+this / 1000);\n    }\n\n    function toDate () {\n        return this._offset ? new Date(+this) : this._d;\n    }\n\n    function toArray () {\n        var m = this;\n        return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n    }\n\n    function moment_valid__isValid () {\n        return valid__isValid(this);\n    }\n\n    function parsingFlags () {\n        return extend({}, this._pf);\n    }\n\n    function invalidAt () {\n        return this._pf.overflow;\n    }\n\n    addFormatToken(0, ['gg', 2], 0, function () {\n        return this.weekYear() % 100;\n    });\n\n    addFormatToken(0, ['GG', 2], 0, function () {\n        return this.isoWeekYear() % 100;\n    });\n\n    function addWeekYearFormatToken (token, getter) {\n        addFormatToken(0, [token, token.length], 0, getter);\n    }\n\n    addWeekYearFormatToken('gggg',     'weekYear');\n    addWeekYearFormatToken('ggggg',    'weekYear');\n    addWeekYearFormatToken('GGGG',  'isoWeekYear');\n    addWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\n    addUnitAlias('weekYear', 'gg');\n    addUnitAlias('isoWeekYear', 'GG');\n\n    addRegexToken('G',      matchSigned);\n    addRegexToken('g',      matchSigned);\n    addRegexToken('GG',     match1to2, match2);\n    addRegexToken('gg',     match1to2, match2);\n    addRegexToken('GGGG',   match1to4, match4);\n    addRegexToken('gggg',   match1to4, match4);\n    addRegexToken('GGGGG',  match1to6, match6);\n    addRegexToken('ggggg',  match1to6, match6);\n\n    addWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n        week[token.substr(0, 2)] = toInt(input);\n    });\n\n    addWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n        week[token] = utils_hooks__hooks.parseTwoDigitYear(input);\n    });\n\n    function weeksInYear(year, dow, doy) {\n        return weekOfYear(local__createLocal([year, 11, 31 + dow - doy]), dow, doy).week;\n    }\n\n    function getSetWeekYear (input) {\n        var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;\n        return input == null ? year : this.add((input - year), 'y');\n    }\n\n    function getSetISOWeekYear (input) {\n        var year = weekOfYear(this, 1, 4).year;\n        return input == null ? year : this.add((input - year), 'y');\n    }\n\n    function getISOWeeksInYear () {\n        return weeksInYear(this.year(), 1, 4);\n    }\n\n    function getWeeksInYear () {\n        var weekInfo = this.localeData()._week;\n        return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n    }\n\n    addFormatToken('Q', 0, 0, 'quarter');\n\n    addUnitAlias('quarter', 'Q');\n\n    addRegexToken('Q', match1);\n    addParseToken('Q', function (input, array) {\n        array[MONTH] = (toInt(input) - 1) * 3;\n    });\n\n    function getSetQuarter (input) {\n        return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n    }\n\n    addFormatToken('D', ['DD', 2], 'Do', 'date');\n\n    addUnitAlias('date', 'D');\n\n    addRegexToken('D',  match1to2);\n    addRegexToken('DD', match1to2, match2);\n    addRegexToken('Do', function (isStrict, locale) {\n        return isStrict ? locale._ordinalParse : locale._ordinalParseLenient;\n    });\n\n    addParseToken(['D', 'DD'], DATE);\n    addParseToken('Do', function (input, array) {\n        array[DATE] = toInt(input.match(match1to2)[0], 10);\n    });\n\n    var getSetDayOfMonth = makeGetSet('Date', true);\n\n    addFormatToken('d', 0, 'do', 'day');\n\n    addFormatToken('dd', 0, 0, function (format) {\n        return this.localeData().weekdaysMin(this, format);\n    });\n\n    addFormatToken('ddd', 0, 0, function (format) {\n        return this.localeData().weekdaysShort(this, format);\n    });\n\n    addFormatToken('dddd', 0, 0, function (format) {\n        return this.localeData().weekdays(this, format);\n    });\n\n    addFormatToken('e', 0, 0, 'weekday');\n    addFormatToken('E', 0, 0, 'isoWeekday');\n\n    addUnitAlias('day', 'd');\n    addUnitAlias('weekday', 'e');\n    addUnitAlias('isoWeekday', 'E');\n\n    addRegexToken('d',    match1to2);\n    addRegexToken('e',    match1to2);\n    addRegexToken('E',    match1to2);\n    addRegexToken('dd',   matchWord);\n    addRegexToken('ddd',  matchWord);\n    addRegexToken('dddd', matchWord);\n\n    addWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config) {\n        var weekday = config._locale.weekdaysParse(input);\n        if (weekday != null) {\n            week.d = weekday;\n        } else {\n            config._pf.invalidWeekday = input;\n        }\n    });\n\n    addWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n        week[token] = toInt(input);\n    });\n\n    function parseWeekday(input, locale) {\n        if (typeof input === 'string') {\n            if (!isNaN(input)) {\n                input = parseInt(input, 10);\n            }\n            else {\n                input = locale.weekdaysParse(input);\n                if (typeof input !== 'number') {\n                    return null;\n                }\n            }\n        }\n        return input;\n    }\n\n    var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\n    function localeWeekdays (m) {\n        return this._weekdays[m.day()];\n    }\n\n    var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\n    function localeWeekdaysShort (m) {\n        return this._weekdaysShort[m.day()];\n    }\n\n    var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\n    function localeWeekdaysMin (m) {\n        return this._weekdaysMin[m.day()];\n    }\n\n    function localeWeekdaysParse (weekdayName) {\n        var i, mom, regex;\n\n        if (!this._weekdaysParse) {\n            this._weekdaysParse = [];\n        }\n\n        for (i = 0; i < 7; i++) {\n            if (!this._weekdaysParse[i]) {\n                mom = local__createLocal([2000, 1]).day(i);\n                regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n                this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n            }\n            if (this._weekdaysParse[i].test(weekdayName)) {\n                return i;\n            }\n        }\n    }\n\n    function getSetDayOfWeek (input) {\n        var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n        if (input != null) {\n            input = parseWeekday(input, this.localeData());\n            return this.add(input - day, 'd');\n        } else {\n            return day;\n        }\n    }\n\n    function getSetLocaleDayOfWeek (input) {\n        var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n        return input == null ? weekday : this.add(input - weekday, 'd');\n    }\n\n    function getSetISODayOfWeek (input) {\n        return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);\n    }\n\n    addFormatToken('H', ['HH', 2], 0, 'hour');\n    addFormatToken('h', ['hh', 2], 0, function () {\n        return this.hours() % 12 || 12;\n    });\n\n    function meridiem (token, lowercase) {\n        addFormatToken(token, 0, 0, function () {\n            return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n        });\n    }\n\n    meridiem('a', true);\n    meridiem('A', false);\n\n    addUnitAlias('hour', 'h');\n\n    function matchMeridiem (isStrict, locale) {\n        return locale._meridiemParse;\n    }\n\n    addRegexToken('a',  matchMeridiem);\n    addRegexToken('A',  matchMeridiem);\n    addRegexToken('H',  match1to2);\n    addRegexToken('h',  match1to2);\n    addRegexToken('HH', match1to2, match2);\n    addRegexToken('hh', match1to2, match2);\n\n    addParseToken(['H', 'HH'], HOUR);\n    addParseToken(['a', 'A'], function (input, array, config) {\n        config._isPm = config._locale.isPM(input);\n        config._meridiem = input;\n    });\n    addParseToken(['h', 'hh'], function (input, array, config) {\n        array[HOUR] = toInt(input);\n        config._pf.bigHour = true;\n    });\n\n    function localeIsPM (input) {\n        return ((input + '').toLowerCase().charAt(0) === 'p');\n    }\n\n    var defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\n    function localeMeridiem (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'pm' : 'PM';\n        } else {\n            return isLower ? 'am' : 'AM';\n        }\n    }\n    var getSetHour = makeGetSet('Hours', true);\n\n    addFormatToken('m', ['mm', 2], 0, 'minute');\n\n    addUnitAlias('minute', 'm');\n\n    addRegexToken('m',  match1to2);\n    addRegexToken('mm', match1to2, match2);\n    addParseToken(['m', 'mm'], MINUTE);\n\n    var getSetMinute = makeGetSet('Minutes', false);\n\n    addFormatToken('s', ['ss', 2], 0, 'second');\n\n    addUnitAlias('second', 's');\n\n    addRegexToken('s',  match1to2);\n    addRegexToken('ss', match1to2, match2);\n    addParseToken(['s', 'ss'], SECOND);\n\n    var getSetSecond = makeGetSet('Seconds', false);\n\n    addFormatToken('S', 0, 0, function () {\n        return ~~(this.millisecond() / 100);\n    });\n\n    addFormatToken(0, ['SS', 2], 0, function () {\n        return ~~(this.millisecond() / 10);\n    });\n\n    function millisecond__milliseconds (token) {\n        addFormatToken(0, [token, 3], 0, 'millisecond');\n    }\n\n    millisecond__milliseconds('SSS');\n    millisecond__milliseconds('SSSS');\n\n    addUnitAlias('millisecond', 'ms');\n\n    addRegexToken('S',    match1to3, match1);\n    addRegexToken('SS',   match1to3, match2);\n    addRegexToken('SSS',  match1to3, match3);\n    addRegexToken('SSSS', matchUnsigned);\n    addParseToken(['S', 'SS', 'SSS', 'SSSS'], function (input, array) {\n        array[MILLISECOND] = toInt(('0.' + input) * 1000);\n    });\n\n    var getSetMillisecond = makeGetSet('Milliseconds', false);\n\n    addFormatToken('z',  0, 0, 'zoneAbbr');\n    addFormatToken('zz', 0, 0, 'zoneName');\n\n    function getZoneAbbr () {\n        return this._isUTC ? 'UTC' : '';\n    }\n\n    function getZoneName () {\n        return this._isUTC ? 'Coordinated Universal Time' : '';\n    }\n\n    var momentPrototype__proto = Moment.prototype;\n\n    momentPrototype__proto.add          = add_subtract__add;\n    momentPrototype__proto.calendar     = moment_calendar__calendar;\n    momentPrototype__proto.clone        = clone;\n    momentPrototype__proto.diff         = diff;\n    momentPrototype__proto.endOf        = endOf;\n    momentPrototype__proto.format       = format;\n    momentPrototype__proto.from         = from;\n    momentPrototype__proto.fromNow      = fromNow;\n    momentPrototype__proto.get          = getSet;\n    momentPrototype__proto.invalidAt    = invalidAt;\n    momentPrototype__proto.isAfter      = isAfter;\n    momentPrototype__proto.isBefore     = isBefore;\n    momentPrototype__proto.isBetween    = isBetween;\n    momentPrototype__proto.isSame       = isSame;\n    momentPrototype__proto.isValid      = moment_valid__isValid;\n    momentPrototype__proto.lang         = lang;\n    momentPrototype__proto.locale       = locale;\n    momentPrototype__proto.localeData   = localeData;\n    momentPrototype__proto.max          = prototypeMax;\n    momentPrototype__proto.min          = prototypeMin;\n    momentPrototype__proto.parsingFlags = parsingFlags;\n    momentPrototype__proto.set          = getSet;\n    momentPrototype__proto.startOf      = startOf;\n    momentPrototype__proto.subtract     = add_subtract__subtract;\n    momentPrototype__proto.toArray      = toArray;\n    momentPrototype__proto.toDate       = toDate;\n    momentPrototype__proto.toISOString  = moment_format__toISOString;\n    momentPrototype__proto.toJSON       = moment_format__toISOString;\n    momentPrototype__proto.toString     = toString;\n    momentPrototype__proto.unix         = unix;\n    momentPrototype__proto.valueOf      = to_type__valueOf;\n    momentPrototype__proto.year       = getSetYear;\n    momentPrototype__proto.isLeapYear = getIsLeapYear;\n    momentPrototype__proto.weekYear    = getSetWeekYear;\n    momentPrototype__proto.isoWeekYear = getSetISOWeekYear;\n    momentPrototype__proto.quarter = momentPrototype__proto.quarters = getSetQuarter;\n    momentPrototype__proto.month       = getSetMonth;\n    momentPrototype__proto.daysInMonth = getDaysInMonth;\n    momentPrototype__proto.week           = momentPrototype__proto.weeks        = getSetWeek;\n    momentPrototype__proto.isoWeek        = momentPrototype__proto.isoWeeks     = getSetISOWeek;\n    momentPrototype__proto.weeksInYear    = getWeeksInYear;\n    momentPrototype__proto.isoWeeksInYear = getISOWeeksInYear;\n    momentPrototype__proto.date       = getSetDayOfMonth;\n    momentPrototype__proto.day        = momentPrototype__proto.days             = getSetDayOfWeek;\n    momentPrototype__proto.weekday    = getSetLocaleDayOfWeek;\n    momentPrototype__proto.isoWeekday = getSetISODayOfWeek;\n    momentPrototype__proto.dayOfYear  = getSetDayOfYear;\n    momentPrototype__proto.hour = momentPrototype__proto.hours = getSetHour;\n    momentPrototype__proto.minute = momentPrototype__proto.minutes = getSetMinute;\n    momentPrototype__proto.second = momentPrototype__proto.seconds = getSetSecond;\n    momentPrototype__proto.millisecond = momentPrototype__proto.milliseconds = getSetMillisecond;\n    momentPrototype__proto.utcOffset            = getSetOffset;\n    momentPrototype__proto.utc                  = setOffsetToUTC;\n    momentPrototype__proto.local                = setOffsetToLocal;\n    momentPrototype__proto.parseZone            = setOffsetToParsedOffset;\n    momentPrototype__proto.hasAlignedHourOffset = hasAlignedHourOffset;\n    momentPrototype__proto.isDST                = isDaylightSavingTime;\n    momentPrototype__proto.isDSTShifted         = isDaylightSavingTimeShifted;\n    momentPrototype__proto.isLocal              = isLocal;\n    momentPrototype__proto.isUtcOffset          = isUtcOffset;\n    momentPrototype__proto.isUtc                = isUtc;\n    momentPrototype__proto.isUTC                = isUtc;\n    momentPrototype__proto.zoneAbbr = getZoneAbbr;\n    momentPrototype__proto.zoneName = getZoneName;\n    momentPrototype__proto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\n    momentPrototype__proto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\n    momentPrototype__proto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);\n    momentPrototype__proto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779', getSetZone);\n\n    var momentPrototype = momentPrototype__proto;\n\n    function moment__createUnix (input) {\n        return local__createLocal(input * 1000);\n    }\n\n    function moment__createInZone () {\n        return local__createLocal.apply(null, arguments).parseZone();\n    }\n\n    var defaultCalendar = {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    };\n\n    function locale_calendar__calendar (key, mom, now) {\n        var output = this._calendar[key];\n        return typeof output === 'function' ? output.call(mom, now) : output;\n    }\n\n    var defaultLongDateFormat = {\n        LTS  : 'h:mm:ss A',\n        LT   : 'h:mm A',\n        L    : 'MM/DD/YYYY',\n        LL   : 'MMMM D, YYYY',\n        LLL  : 'MMMM D, YYYY LT',\n        LLLL : 'dddd, MMMM D, YYYY LT'\n    };\n\n    function longDateFormat (key) {\n        var output = this._longDateFormat[key];\n        if (!output && this._longDateFormat[key.toUpperCase()]) {\n            output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {\n                return val.slice(1);\n            });\n            this._longDateFormat[key] = output;\n        }\n        return output;\n    }\n\n    var defaultInvalidDate = 'Invalid date';\n\n    function invalidDate () {\n        return this._invalidDate;\n    }\n\n    var defaultOrdinal = '%d';\n    var defaultOrdinalParse = /\\d{1,2}/;\n\n    function ordinal (number) {\n        return this._ordinal.replace('%d', number);\n    }\n\n    function preParsePostFormat (string) {\n        return string;\n    }\n\n    var defaultRelativeTime = {\n        future : 'in %s',\n        past   : '%s ago',\n        s  : 'a few seconds',\n        m  : 'a minute',\n        mm : '%d minutes',\n        h  : 'an hour',\n        hh : '%d hours',\n        d  : 'a day',\n        dd : '%d days',\n        M  : 'a month',\n        MM : '%d months',\n        y  : 'a year',\n        yy : '%d years'\n    };\n\n    function relative__relativeTime (number, withoutSuffix, string, isFuture) {\n        var output = this._relativeTime[string];\n        return (typeof output === 'function') ?\n            output(number, withoutSuffix, string, isFuture) :\n            output.replace(/%d/i, number);\n    }\n\n    function pastFuture (diff, output) {\n        var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n        return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);\n    }\n\n    function locale_set__set (config) {\n        var prop, i;\n        for (i in config) {\n            prop = config[i];\n            if (typeof prop === 'function') {\n                this[i] = prop;\n            } else {\n                this['_' + i] = prop;\n            }\n        }\n        this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + /\\d{1,2}/.source);\n    }\n\n    var prototype__proto = Locale.prototype;\n\n    prototype__proto._calendar       = defaultCalendar;\n    prototype__proto.calendar        = locale_calendar__calendar;\n    prototype__proto._longDateFormat = defaultLongDateFormat;\n    prototype__proto.longDateFormat  = longDateFormat;\n    prototype__proto._invalidDate    = defaultInvalidDate;\n    prototype__proto.invalidDate     = invalidDate;\n    prototype__proto._ordinal        = defaultOrdinal;\n    prototype__proto.ordinal         = ordinal;\n    prototype__proto._ordinalParse   = defaultOrdinalParse;\n    prototype__proto.preparse        = preParsePostFormat;\n    prototype__proto.postformat      = preParsePostFormat;\n    prototype__proto._relativeTime   = defaultRelativeTime;\n    prototype__proto.relativeTime    = relative__relativeTime;\n    prototype__proto.pastFuture      = pastFuture;\n    prototype__proto.set             = locale_set__set;\n    prototype__proto.months       =        localeMonths;\n    prototype__proto._months      = defaultLocaleMonths;\n    prototype__proto.monthsShort  =        localeMonthsShort;\n    prototype__proto._monthsShort = defaultLocaleMonthsShort;\n    prototype__proto.monthsParse  =        localeMonthsParse;\n    prototype__proto.week = localeWeek;\n    prototype__proto._week = defaultLocaleWeek;\n    prototype__proto.firstDayOfYear = localeFirstDayOfYear;\n    prototype__proto.firstDayOfWeek = localeFirstDayOfWeek;\n    prototype__proto.weekdays       =        localeWeekdays;\n    prototype__proto._weekdays      = defaultLocaleWeekdays;\n    prototype__proto.weekdaysMin    =        localeWeekdaysMin;\n    prototype__proto._weekdaysMin   = defaultLocaleWeekdaysMin;\n    prototype__proto.weekdaysShort  =        localeWeekdaysShort;\n    prototype__proto._weekdaysShort = defaultLocaleWeekdaysShort;\n    prototype__proto.weekdaysParse  =        localeWeekdaysParse;\n    prototype__proto.isPM = localeIsPM;\n    prototype__proto._meridiemParse = defaultLocaleMeridiemParse;\n    prototype__proto.meridiem = localeMeridiem;\n\n    function lists__get (format, index, field, setter) {\n        var locale = locale_locales__getLocale();\n        var utc = create_utc__createUTC().set(setter, index);\n        return locale[field](utc, format);\n    }\n\n    function list (format, index, field, count, setter) {\n        if (typeof format === 'number') {\n            index = format;\n            format = undefined;\n        }\n\n        format = format || '';\n\n        if (index != null) {\n            return lists__get(format, index, field, setter);\n        }\n\n        var i;\n        var out = [];\n        for (i = 0; i < count; i++) {\n            out[i] = lists__get(format, i, field, setter);\n        }\n        return out;\n    }\n\n    function lists__listMonths (format, index) {\n        return list(format, index, 'months', 12, 'month');\n    }\n\n    function lists__listMonthsShort (format, index) {\n        return list(format, index, 'monthsShort', 12, 'month');\n    }\n\n    function lists__listWeekdays (format, index) {\n        return list(format, index, 'weekdays', 7, 'day');\n    }\n\n    function lists__listWeekdaysShort (format, index) {\n        return list(format, index, 'weekdaysShort', 7, 'day');\n    }\n\n    function lists__listWeekdaysMin (format, index) {\n        return list(format, index, 'weekdaysMin', 7, 'day');\n    }\n\n    locale_locales__getSetGlobalLocale('en', {\n        ordinalParse: /\\d{1,2}(th|st|nd|rd)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (toInt(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        }\n    });\n    utils_hooks__hooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', locale_locales__getSetGlobalLocale);\n    utils_hooks__hooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', locale_locales__getLocale);\n\n    var mathAbs = Math.abs;\n\n    function duration_abs__abs () {\n        var data           = this._data;\n\n        this._milliseconds = mathAbs(this._milliseconds);\n        this._days         = mathAbs(this._days);\n        this._months       = mathAbs(this._months);\n\n        data.milliseconds  = mathAbs(data.milliseconds);\n        data.seconds       = mathAbs(data.seconds);\n        data.minutes       = mathAbs(data.minutes);\n        data.hours         = mathAbs(data.hours);\n        data.months        = mathAbs(data.months);\n        data.years         = mathAbs(data.years);\n\n        return this;\n    }\n\n    function duration_add_subtract__addSubtract (duration, input, value, direction) {\n        var other = create__createDuration(input, value);\n\n        duration._milliseconds += direction * other._milliseconds;\n        duration._days         += direction * other._days;\n        duration._months       += direction * other._months;\n\n        return duration._bubble();\n    }\n    function duration_add_subtract__add (input, value) {\n        return duration_add_subtract__addSubtract(this, input, value, 1);\n    }\n    function duration_add_subtract__subtract (input, value) {\n        return duration_add_subtract__addSubtract(this, input, value, -1);\n    }\n\n    function bubble () {\n        var milliseconds = this._milliseconds;\n        var days         = this._days;\n        var months       = this._months;\n        var data         = this._data;\n        var seconds, minutes, hours, years = 0;\n        data.milliseconds = milliseconds % 1000;\n\n        seconds           = absFloor(milliseconds / 1000);\n        data.seconds      = seconds % 60;\n\n        minutes           = absFloor(seconds / 60);\n        data.minutes      = minutes % 60;\n\n        hours             = absFloor(minutes / 60);\n        data.hours        = hours % 24;\n\n        days += absFloor(hours / 24);\n        years = absFloor(daysToYears(days));\n        days -= absFloor(yearsToDays(years));\n        months += absFloor(days / 30);\n        days   %= 30;\n        years  += absFloor(months / 12);\n        months %= 12;\n\n        data.days   = days;\n        data.months = months;\n        data.years  = years;\n\n        return this;\n    }\n\n    function daysToYears (days) {\n        return days * 400 / 146097;\n    }\n\n    function yearsToDays (years) {\n        return years * 146097 / 400;\n    }\n\n    function as (units) {\n        var days;\n        var months;\n        var milliseconds = this._milliseconds;\n\n        units = normalizeUnits(units);\n\n        if (units === 'month' || units === 'year') {\n            days   = this._days   + milliseconds / 864e5;\n            months = this._months + daysToYears(days) * 12;\n            return units === 'month' ? months : months / 12;\n        } else {\n            days = this._days + Math.round(yearsToDays(this._months / 12));\n            switch (units) {\n                case 'week'   : return days / 7            + milliseconds / 6048e5;\n                case 'day'    : return days                + milliseconds / 864e5;\n                case 'hour'   : return days * 24           + milliseconds / 36e5;\n                case 'minute' : return days * 24 * 60      + milliseconds / 6e4;\n                case 'second' : return days * 24 * 60 * 60 + milliseconds / 1000;\n                case 'millisecond': return Math.floor(days * 24 * 60 * 60 * 1000) + milliseconds;\n                default: throw new Error('Unknown unit ' + units);\n            }\n        }\n    }\n    function duration_as__valueOf () {\n        return (\n            this._milliseconds +\n            this._days * 864e5 +\n            (this._months % 12) * 2592e6 +\n            toInt(this._months / 12) * 31536e6\n        );\n    }\n\n    function makeAs (alias) {\n        return function () {\n            return this.as(alias);\n        };\n    }\n\n    var asMilliseconds = makeAs('ms');\n    var asSeconds      = makeAs('s');\n    var asMinutes      = makeAs('m');\n    var asHours        = makeAs('h');\n    var asDays         = makeAs('d');\n    var asWeeks        = makeAs('w');\n    var asMonths       = makeAs('M');\n    var asYears        = makeAs('y');\n\n    function duration_get__get (units) {\n        units = normalizeUnits(units);\n        return this[units + 's']();\n    }\n\n    function makeGetter(name) {\n        return function () {\n            return this._data[name];\n        };\n    }\n\n    var duration_get__milliseconds = makeGetter('milliseconds');\n    var seconds      = makeGetter('seconds');\n    var minutes      = makeGetter('minutes');\n    var hours        = makeGetter('hours');\n    var days         = makeGetter('days');\n    var months       = makeGetter('months');\n    var years        = makeGetter('years');\n\n    function weeks () {\n        return absFloor(this.days() / 7);\n    }\n\n    var round = Math.round;\n    var thresholds = {\n        s: 45,  // seconds to minute\n        m: 45,  // minutes to hour\n        h: 22,  // hours to day\n        d: 26,  // days to month\n        M: 11   // months to year\n    };\n    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n    }\n\n    function duration_humanize__relativeTime (posNegDuration, withoutSuffix, locale) {\n        var duration = create__createDuration(posNegDuration).abs();\n        var seconds  = round(duration.as('s'));\n        var minutes  = round(duration.as('m'));\n        var hours    = round(duration.as('h'));\n        var days     = round(duration.as('d'));\n        var months   = round(duration.as('M'));\n        var years    = round(duration.as('y'));\n\n        var a = seconds < thresholds.s && ['s', seconds]  ||\n                minutes === 1          && ['m']           ||\n                minutes < thresholds.m && ['mm', minutes] ||\n                hours   === 1          && ['h']           ||\n                hours   < thresholds.h && ['hh', hours]   ||\n                days    === 1          && ['d']           ||\n                days    < thresholds.d && ['dd', days]    ||\n                months  === 1          && ['M']           ||\n                months  < thresholds.M && ['MM', months]  ||\n                years   === 1          && ['y']           || ['yy', years];\n\n        a[2] = withoutSuffix;\n        a[3] = +posNegDuration > 0;\n        a[4] = locale;\n        return substituteTimeAgo.apply(null, a);\n    }\n    function duration_humanize__getSetRelativeTimeThreshold (threshold, limit) {\n        if (thresholds[threshold] === undefined) {\n            return false;\n        }\n        if (limit === undefined) {\n            return thresholds[threshold];\n        }\n        thresholds[threshold] = limit;\n        return true;\n    }\n\n    function humanize (withSuffix) {\n        var locale = this.localeData();\n        var output = duration_humanize__relativeTime(this, !withSuffix, locale);\n\n        if (withSuffix) {\n            output = locale.pastFuture(+this, output);\n        }\n\n        return locale.postformat(output);\n    }\n\n    var iso_string__abs = Math.abs;\n\n    function iso_string__toISOString() {\n        var Y = iso_string__abs(this.years());\n        var M = iso_string__abs(this.months());\n        var D = iso_string__abs(this.days());\n        var h = iso_string__abs(this.hours());\n        var m = iso_string__abs(this.minutes());\n        var s = iso_string__abs(this.seconds() + this.milliseconds() / 1000);\n        var total = this.asSeconds();\n\n        if (!total) {\n            return 'P0D';\n        }\n\n        return (total < 0 ? '-' : '') +\n            'P' +\n            (Y ? Y + 'Y' : '') +\n            (M ? M + 'M' : '') +\n            (D ? D + 'D' : '') +\n            ((h || m || s) ? 'T' : '') +\n            (h ? h + 'H' : '') +\n            (m ? m + 'M' : '') +\n            (s ? s + 'S' : '');\n    }\n\n    var duration_prototype__proto = Duration.prototype;\n\n    duration_prototype__proto.abs            = duration_abs__abs;\n    duration_prototype__proto.add            = duration_add_subtract__add;\n    duration_prototype__proto.subtract       = duration_add_subtract__subtract;\n    duration_prototype__proto.as             = as;\n    duration_prototype__proto.asMilliseconds = asMilliseconds;\n    duration_prototype__proto.asSeconds      = asSeconds;\n    duration_prototype__proto.asMinutes      = asMinutes;\n    duration_prototype__proto.asHours        = asHours;\n    duration_prototype__proto.asDays         = asDays;\n    duration_prototype__proto.asWeeks        = asWeeks;\n    duration_prototype__proto.asMonths       = asMonths;\n    duration_prototype__proto.asYears        = asYears;\n    duration_prototype__proto.valueOf        = duration_as__valueOf;\n    duration_prototype__proto._bubble        = bubble;\n    duration_prototype__proto.get            = duration_get__get;\n    duration_prototype__proto.milliseconds   = duration_get__milliseconds;\n    duration_prototype__proto.seconds        = seconds;\n    duration_prototype__proto.minutes        = minutes;\n    duration_prototype__proto.hours          = hours;\n    duration_prototype__proto.days           = days;\n    duration_prototype__proto.weeks          = weeks;\n    duration_prototype__proto.months         = months;\n    duration_prototype__proto.years          = years;\n    duration_prototype__proto.humanize       = humanize;\n    duration_prototype__proto.toISOString    = iso_string__toISOString;\n    duration_prototype__proto.toString       = iso_string__toISOString;\n    duration_prototype__proto.toJSON         = iso_string__toISOString;\n    duration_prototype__proto.locale         = locale;\n    duration_prototype__proto.localeData     = localeData;\n    duration_prototype__proto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', iso_string__toISOString);\n    duration_prototype__proto.lang = lang;\n\n    addFormatToken('X', 0, 0, 'unix');\n    addFormatToken('x', 0, 0, 'valueOf');\n\n    addRegexToken('x', matchSigned);\n    addRegexToken('X', matchTimestamp);\n    addParseToken('X', function (input, array, config) {\n        config._d = new Date(parseFloat(input, 10) * 1000);\n    });\n    addParseToken('x', function (input, array, config) {\n        config._d = new Date(toInt(input));\n    });\n\n\n    utils_hooks__hooks.version = '2.10.2';\n\n    setHookCallback(local__createLocal);\n\n    utils_hooks__hooks.fn                    = momentPrototype;\n    utils_hooks__hooks.min                   = min;\n    utils_hooks__hooks.max                   = max;\n    utils_hooks__hooks.utc                   = create_utc__createUTC;\n    utils_hooks__hooks.unix                  = moment__createUnix;\n    utils_hooks__hooks.months                = lists__listMonths;\n    utils_hooks__hooks.isDate                = isDate;\n    utils_hooks__hooks.locale                = locale_locales__getSetGlobalLocale;\n    utils_hooks__hooks.invalid               = valid__createInvalid;\n    utils_hooks__hooks.duration              = create__createDuration;\n    utils_hooks__hooks.isMoment              = isMoment;\n    utils_hooks__hooks.weekdays              = lists__listWeekdays;\n    utils_hooks__hooks.parseZone             = moment__createInZone;\n    utils_hooks__hooks.localeData            = locale_locales__getLocale;\n    utils_hooks__hooks.isDuration            = isDuration;\n    utils_hooks__hooks.monthsShort           = lists__listMonthsShort;\n    utils_hooks__hooks.weekdaysMin           = lists__listWeekdaysMin;\n    utils_hooks__hooks.defineLocale          = defineLocale;\n    utils_hooks__hooks.weekdaysShort         = lists__listWeekdaysShort;\n    utils_hooks__hooks.normalizeUnits        = normalizeUnits;\n    utils_hooks__hooks.relativeTimeThreshold = duration_humanize__getSetRelativeTimeThreshold;\n\n    var _moment = utils_hooks__hooks;\n\n    return _moment;\n\n}));"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/scripts/npm_prepublish.sh",
    "content": "#!/bin/bash\n\nset -e\n\nif [ \"$#\" != 1 ]; then\n    echo \"Please provide tag to checkout\" >&2\n    exit 1\nfi\ntag=\"$1\"\n\nwhile [ \"$PWD\" != '/' -a ! -f moment.js ]; do\n    cd ..\ndone\n\nif [ ! -f moment.js ]; then\n    echo \"Run me from the moment repo\" >&2\n    exit 1\nfi\n\nbasename=$(basename $PWD)\nsrc=moment-npm-git\ndest=moment-npm\n\ncd ..\n\nrm -rf $src $dest\n\ngit clone $basename $src\nmkdir $dest\n\n\ncp $src/moment.js $dest\ncp $src/package.json $dest\ncp $src/README.md $dest\ncp $src/LICENSE $dest\ncp -r $src/locale $dest\ncp -r $src/min $dest\ncp $src/ender.js $dest\ncp $src/package.js $dest\n\nrm -rf $src\n\necho \"Check out $dest\"\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/create/check-overflow.js",
    "content": "import { daysInMonth } from '../units/month';\nimport { YEAR, MONTH, DATE, HOUR, MINUTE, SECOND, MILLISECOND } from '../units/constants';\n\nexport default function checkOverflow (m) {\n    var overflow;\n    var a = m._a;\n\n    if (a && m._pf.overflow === -2) {\n        overflow =\n            a[MONTH]       < 0 || a[MONTH]       > 11  ? MONTH :\n            a[DATE]        < 1 || a[DATE]        > daysInMonth(a[YEAR], a[MONTH]) ? DATE :\n            a[HOUR]        < 0 || a[HOUR]        > 24 || (a[HOUR] === 24 && (a[MINUTE] !== 0 || a[SECOND] !== 0 || a[MILLISECOND] !== 0)) ? HOUR :\n            a[MINUTE]      < 0 || a[MINUTE]      > 59  ? MINUTE :\n            a[SECOND]      < 0 || a[SECOND]      > 59  ? SECOND :\n            a[MILLISECOND] < 0 || a[MILLISECOND] > 999 ? MILLISECOND :\n            -1;\n\n        if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n            overflow = DATE;\n        }\n\n        m._pf.overflow = overflow;\n    }\n\n    return m;\n}\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/create/date-from-array.js",
    "content": "export function createDate (y, m, d, h, M, s, ms) {\n    var date = new Date(y, m, d, h, M, s, ms);\n    if (y < 1970) {\n        date.setFullYear(y);\n    }\n    return date;\n}\n\nexport function createUTCDate (y) {\n    var date = new Date(Date.UTC.apply(null, arguments));\n    if (y < 1970) {\n        date.setUTCFullYear(y);\n    }\n    return date;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/create/default-parsing-flags.js",
    "content": "export default function defaultParsingFlags() {\n    return {\n        empty           : false,\n        unusedTokens    : [],\n        unusedInput     : [],\n        overflow        : -2,\n        charsLeftOver   : 0,\n        nullInput       : false,\n        invalidMonth    : null,\n        invalidFormat   : false,\n        userInvalidated : false,\n        iso             : false\n    };\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/create/from-anything.js",
    "content": "import defaultParsingFlags from './default-parsing-flags';\nimport isArray from '../utils/is-array';\nimport isDate from '../utils/is-date';\nimport map from '../utils/map';\nimport { createInvalid } from './valid';\nimport { Moment, isMoment } from '../moment/constructor';\nimport { getLocale } from '../locale/locales';\nimport { hooks } from '../utils/hooks';\nimport checkOverflow from './check-overflow';\n\nimport { configFromStringAndArray }  from './from-string-and-array';\nimport { configFromStringAndFormat } from './from-string-and-format';\nimport { configFromString }          from './from-string';\nimport { configFromArray }           from './from-array';\nimport { configFromObject }          from './from-object';\n\nfunction createFromConfig (config) {\n    var input = config._i,\n        format = config._f,\n        res;\n\n    config._locale = config._locale || getLocale(config._l);\n\n    if (input === null || (format === undefined && input === '')) {\n        return createInvalid({nullInput: true});\n    }\n\n    if (typeof input === 'string') {\n        config._i = input = config._locale.preparse(input);\n    }\n\n    if (isMoment(input)) {\n        return new Moment(checkOverflow(input));\n    } else if (isArray(format)) {\n        configFromStringAndArray(config);\n    } else if (format) {\n        configFromStringAndFormat(config);\n    } else {\n        configFromInput(config);\n    }\n\n    res = new Moment(checkOverflow(config));\n    if (res._nextDay) {\n        res.add(1, 'd');\n        res._nextDay = undefined;\n    }\n\n    return res;\n}\n\nfunction configFromInput(config) {\n    var input = config._i;\n    if (input === undefined) {\n        config._d = new Date();\n    } else if (isDate(input)) {\n        config._d = new Date(+input);\n    } else if (typeof input === 'string') {\n        configFromString(config);\n    } else if (isArray(input)) {\n        config._a = map(input.slice(0), function (obj) {\n            return parseInt(obj, 10);\n        });\n        configFromArray(config);\n    } else if (typeof(input) === 'object') {\n        configFromObject(config);\n    } else if (typeof(input) === 'number') {\n        config._d = new Date(input);\n    } else {\n        hooks.createFromInputFallback(config);\n    }\n}\n\nexport function createLocalOrUTC (input, format, locale, strict, isUTC) {\n    var c = {};\n\n    if (typeof(locale) === 'boolean') {\n        strict = locale;\n        locale = undefined;\n    }\n    c._isAMomentObject = true;\n    c._useUTC = c._isUTC = isUTC;\n    c._l = locale;\n    c._i = input;\n    c._f = format;\n    c._strict = strict;\n    c._pf = defaultParsingFlags();\n\n    return createFromConfig(c);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/create/from-array.js",
    "content": "import { createDate, createUTCDate } from './date-from-array';\nimport { daysInYear } from '../units/year';\nimport { weekOfYear } from '../units/week';\nimport { dayOfYearFromWeeks } from '../units/day-of-year';\nimport { YEAR, MONTH, DATE, HOUR, MINUTE, SECOND, MILLISECOND } from '../units/constants';\nimport { createLocal } from './local';\nimport defaults from '../utils/defaults';\n\nfunction currentDateArray(config) {\n    var now = new Date();\n    if (config._useUTC) {\n        return [now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()];\n    }\n    return [now.getFullYear(), now.getMonth(), now.getDate()];\n}\nexport function configFromArray (config) {\n    var i, date, input = [], currentDate, yearToUse;\n\n    if (config._d) {\n        return;\n    }\n\n    currentDate = currentDateArray(config);\n    if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n        dayOfYearFromWeekInfo(config);\n    }\n    if (config._dayOfYear) {\n        yearToUse = defaults(config._a[YEAR], currentDate[YEAR]);\n\n        if (config._dayOfYear > daysInYear(yearToUse)) {\n            config._pf._overflowDayOfYear = true;\n        }\n\n        date = createUTCDate(yearToUse, 0, config._dayOfYear);\n        config._a[MONTH] = date.getUTCMonth();\n        config._a[DATE] = date.getUTCDate();\n    }\n    for (i = 0; i < 3 && config._a[i] == null; ++i) {\n        config._a[i] = input[i] = currentDate[i];\n    }\n    for (; i < 7; i++) {\n        config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n    }\n    if (config._a[HOUR] === 24 &&\n            config._a[MINUTE] === 0 &&\n            config._a[SECOND] === 0 &&\n            config._a[MILLISECOND] === 0) {\n        config._nextDay = true;\n        config._a[HOUR] = 0;\n    }\n\n    config._d = (config._useUTC ? createUTCDate : createDate).apply(null, input);\n    if (config._tzm != null) {\n        config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n    }\n\n    if (config._nextDay) {\n        config._a[HOUR] = 24;\n    }\n}\n\nfunction dayOfYearFromWeekInfo(config) {\n    var w, weekYear, week, weekday, dow, doy, temp;\n\n    w = config._w;\n    if (w.GG != null || w.W != null || w.E != null) {\n        dow = 1;\n        doy = 4;\n        weekYear = defaults(w.GG, config._a[YEAR], weekOfYear(createLocal(), 1, 4).year);\n        week = defaults(w.W, 1);\n        weekday = defaults(w.E, 1);\n    } else {\n        dow = config._locale._week.dow;\n        doy = config._locale._week.doy;\n\n        weekYear = defaults(w.gg, config._a[YEAR], weekOfYear(createLocal(), dow, doy).year);\n        week = defaults(w.w, 1);\n\n        if (w.d != null) {\n            weekday = w.d;\n            if (weekday < dow) {\n                ++week;\n            }\n        } else if (w.e != null) {\n            weekday = w.e + dow;\n        } else {\n            weekday = dow;\n        }\n    }\n    temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);\n\n    config._a[YEAR] = temp.year;\n    config._dayOfYear = temp.dayOfYear;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/create/from-object.js",
    "content": "import { normalizeObjectUnits } from '../units/aliases';\nimport { configFromArray } from './from-array';\n\nexport function configFromObject(config) {\n    if (config._d) {\n        return;\n    }\n\n    var i = normalizeObjectUnits(config._i);\n    config._a = [i.year, i.month, i.day || i.date, i.hour, i.minute, i.second, i.millisecond];\n\n    configFromArray(config);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/create/from-string-and-array.js",
    "content": "import { copyConfig } from '../moment/constructor';\nimport { configFromStringAndFormat } from './from-string-and-format';\nimport defaultParsingFlags from './default-parsing-flags';\nimport { isValid } from './valid';\nimport extend from '../utils/extend';\nexport function configFromStringAndArray(config) {\n    var tempConfig,\n        bestMoment,\n\n        scoreToBeat,\n        i,\n        currentScore;\n\n    if (config._f.length === 0) {\n        config._pf.invalidFormat = true;\n        config._d = new Date(NaN);\n        return;\n    }\n\n    for (i = 0; i < config._f.length; i++) {\n        currentScore = 0;\n        tempConfig = copyConfig({}, config);\n        if (config._useUTC != null) {\n            tempConfig._useUTC = config._useUTC;\n        }\n        tempConfig._pf = defaultParsingFlags();\n        tempConfig._f = config._f[i];\n        configFromStringAndFormat(tempConfig);\n\n        if (!isValid(tempConfig)) {\n            continue;\n        }\n        currentScore += tempConfig._pf.charsLeftOver;\n        currentScore += tempConfig._pf.unusedTokens.length * 10;\n\n        tempConfig._pf.score = currentScore;\n\n        if (scoreToBeat == null || currentScore < scoreToBeat) {\n            scoreToBeat = currentScore;\n            bestMoment = tempConfig;\n        }\n    }\n\n    extend(config, bestMoment || tempConfig);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/create/from-string-and-format.js",
    "content": "import { configFromISO } from './from-string';\nimport { configFromArray } from './from-array';\nimport { getParseRegexForToken }   from '../parse/regex';\nimport { addTimeToArrayFromToken } from '../parse/token';\nimport { expandFormat, formatTokenFunctions, formattingTokens } from '../format/format';\nimport checkOverflow from './check-overflow';\nimport { HOUR } from '../units/constants';\nimport { hooks } from '../utils/hooks';\nhooks.ISO_8601 = function () {};\nexport function configFromStringAndFormat(config) {\n    if (config._f === hooks.ISO_8601) {\n        configFromISO(config);\n        return;\n    }\n\n    config._a = [];\n    config._pf.empty = true;\n    var string = '' + config._i,\n        i, parsedInput, tokens, token, skipped,\n        stringLength = string.length,\n        totalParsedInputLength = 0;\n\n    tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n    for (i = 0; i < tokens.length; i++) {\n        token = tokens[i];\n        parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n        if (parsedInput) {\n            skipped = string.substr(0, string.indexOf(parsedInput));\n            if (skipped.length > 0) {\n                config._pf.unusedInput.push(skipped);\n            }\n            string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n            totalParsedInputLength += parsedInput.length;\n        }\n        if (formatTokenFunctions[token]) {\n            if (parsedInput) {\n                config._pf.empty = false;\n            }\n            else {\n                config._pf.unusedTokens.push(token);\n            }\n            addTimeToArrayFromToken(token, parsedInput, config);\n        }\n        else if (config._strict && !parsedInput) {\n            config._pf.unusedTokens.push(token);\n        }\n    }\n    config._pf.charsLeftOver = stringLength - totalParsedInputLength;\n    if (string.length > 0) {\n        config._pf.unusedInput.push(string);\n    }\n    if (config._pf.bigHour === true && config._a[HOUR] <= 12) {\n        config._pf.bigHour = undefined;\n    }\n    config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR], config._meridiem);\n\n    configFromArray(config);\n    checkOverflow(config);\n}\n\n\nfunction meridiemFixWrap (locale, hour, meridiem) {\n    var isPm;\n\n    if (meridiem == null) {\n        return hour;\n    }\n    if (locale.meridiemHour != null) {\n        return locale.meridiemHour(hour, meridiem);\n    } else if (locale.isPM != null) {\n        isPm = locale.isPM(meridiem);\n        if (isPm && hour < 12) {\n            hour += 12;\n        }\n        if (!isPm && hour === 12) {\n            hour = 0;\n        }\n        return hour;\n    } else {\n        return hour;\n    }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/create/from-string.js",
    "content": "import { matchOffset } from '../parse/regex';\nimport { configFromStringAndFormat } from './from-string-and-format';\nimport { hooks } from '../utils/hooks';\nimport { deprecate } from '../utils/deprecate';\nvar isoRegex = /^\\s*(?:[+-]\\d{6}|\\d{4})-(?:(\\d\\d-\\d\\d)|(W\\d\\d$)|(W\\d\\d-\\d)|(\\d\\d\\d))((T| )(\\d\\d(:\\d\\d(:\\d\\d(\\.\\d+)?)?)?)?([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/;\n\nvar isoDates = [\n    ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d{2}-\\d{2}/],\n    ['YYYY-MM-DD', /\\d{4}-\\d{2}-\\d{2}/],\n    ['GGGG-[W]WW-E', /\\d{4}-W\\d{2}-\\d/],\n    ['GGGG-[W]WW', /\\d{4}-W\\d{2}/],\n    ['YYYY-DDD', /\\d{4}-\\d{3}/]\n];\nvar isoTimes = [\n    ['HH:mm:ss.SSSS', /(T| )\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n    ['HH:mm:ss', /(T| )\\d\\d:\\d\\d:\\d\\d/],\n    ['HH:mm', /(T| )\\d\\d:\\d\\d/],\n    ['HH', /(T| )\\d\\d/]\n];\n\nvar aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i;\nexport function configFromISO(config) {\n    var i, l,\n        string = config._i,\n        match = isoRegex.exec(string);\n\n    if (match) {\n        config._pf.iso = true;\n        for (i = 0, l = isoDates.length; i < l; i++) {\n            if (isoDates[i][1].exec(string)) {\n                config._f = isoDates[i][0] + (match[6] || ' ');\n                break;\n            }\n        }\n        for (i = 0, l = isoTimes.length; i < l; i++) {\n            if (isoTimes[i][1].exec(string)) {\n                config._f += isoTimes[i][0];\n                break;\n            }\n        }\n        if (string.match(matchOffset)) {\n            config._f += 'Z';\n        }\n        configFromStringAndFormat(config);\n    } else {\n        config._isValid = false;\n    }\n}\nexport function configFromString(config) {\n    var matched = aspNetJsonRegex.exec(config._i);\n\n    if (matched !== null) {\n        config._d = new Date(+matched[1]);\n        return;\n    }\n\n    configFromISO(config);\n    if (config._isValid === false) {\n        delete config._isValid;\n        hooks.createFromInputFallback(config);\n    }\n}\n\nhooks.createFromInputFallback = deprecate(\n    'moment construction falls back to js Date. This is ' +\n    'discouraged and will be removed in upcoming major ' +\n    'release. Please refer to ' +\n    'https://github.com/moment/moment/issues/1407 for more info.',\n    function (config) {\n        config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n    }\n);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/create/local.js",
    "content": "import { createLocalOrUTC } from './from-anything';\n\nexport function createLocal (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, false);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/create/utc.js",
    "content": "import { createLocalOrUTC } from './from-anything';\n\nexport function createUTC (input, format, locale, strict) {\n    return createLocalOrUTC(input, format, locale, strict, true).utc();\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/create/valid.js",
    "content": "import extend from '../utils/extend';\nimport { createUTC } from './utc';\n\nexport function isValid(m) {\n    if (m._isValid == null) {\n        m._isValid = !isNaN(m._d.getTime()) &&\n            m._pf.overflow < 0 &&\n            !m._pf.empty &&\n            !m._pf.invalidMonth &&\n            !m._pf.nullInput &&\n            !m._pf.invalidFormat &&\n            !m._pf.userInvalidated;\n\n        if (m._strict) {\n            m._isValid = m._isValid &&\n                m._pf.charsLeftOver === 0 &&\n                m._pf.unusedTokens.length === 0 &&\n                m._pf.bigHour === undefined;\n        }\n    }\n    return m._isValid;\n}\n\nexport function createInvalid (flags) {\n    var m = createUTC(NaN);\n    if (flags != null) {\n        extend(m._pf, flags);\n    }\n    else {\n        m._pf.userInvalidated = true;\n    }\n\n    return m;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/duration/abs.js",
    "content": "var mathAbs = Math.abs;\n\nexport function abs () {\n    var data           = this._data;\n\n    this._milliseconds = mathAbs(this._milliseconds);\n    this._days         = mathAbs(this._days);\n    this._months       = mathAbs(this._months);\n\n    data.milliseconds  = mathAbs(data.milliseconds);\n    data.seconds       = mathAbs(data.seconds);\n    data.minutes       = mathAbs(data.minutes);\n    data.hours         = mathAbs(data.hours);\n    data.months        = mathAbs(data.months);\n    data.years         = mathAbs(data.years);\n\n    return this;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/duration/add-subtract.js",
    "content": "import { createDuration } from './create';\n\nfunction addSubtract (duration, input, value, direction) {\n    var other = createDuration(input, value);\n\n    duration._milliseconds += direction * other._milliseconds;\n    duration._days         += direction * other._days;\n    duration._months       += direction * other._months;\n\n    return duration._bubble();\n}\nexport function add (input, value) {\n    return addSubtract(this, input, value, 1);\n}\nexport function subtract (input, value) {\n    return addSubtract(this, input, value, -1);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/duration/as.js",
    "content": "import { daysToYears, yearsToDays } from './bubble';\nimport { normalizeUnits } from '../units/aliases';\nimport toInt from '../utils/to-int';\n\nexport function as (units) {\n    var days;\n    var months;\n    var milliseconds = this._milliseconds;\n\n    units = normalizeUnits(units);\n\n    if (units === 'month' || units === 'year') {\n        days   = this._days   + milliseconds / 864e5;\n        months = this._months + daysToYears(days) * 12;\n        return units === 'month' ? months : months / 12;\n    } else {\n        days = this._days + Math.round(yearsToDays(this._months / 12));\n        switch (units) {\n            case 'week'   : return days / 7            + milliseconds / 6048e5;\n            case 'day'    : return days                + milliseconds / 864e5;\n            case 'hour'   : return days * 24           + milliseconds / 36e5;\n            case 'minute' : return days * 24 * 60      + milliseconds / 6e4;\n            case 'second' : return days * 24 * 60 * 60 + milliseconds / 1000;\n            case 'millisecond': return Math.floor(days * 24 * 60 * 60 * 1000) + milliseconds;\n            default: throw new Error('Unknown unit ' + units);\n        }\n    }\n}\nexport function valueOf () {\n    return (\n        this._milliseconds +\n        this._days * 864e5 +\n        (this._months % 12) * 2592e6 +\n        toInt(this._months / 12) * 31536e6\n    );\n}\n\nfunction makeAs (alias) {\n    return function () {\n        return this.as(alias);\n    };\n}\n\nexport var asMilliseconds = makeAs('ms');\nexport var asSeconds      = makeAs('s');\nexport var asMinutes      = makeAs('m');\nexport var asHours        = makeAs('h');\nexport var asDays         = makeAs('d');\nexport var asWeeks        = makeAs('w');\nexport var asMonths       = makeAs('M');\nexport var asYears        = makeAs('y');\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/duration/bubble.js",
    "content": "import absFloor from '../utils/abs-floor';\n\nexport function bubble () {\n    var milliseconds = this._milliseconds;\n    var days         = this._days;\n    var months       = this._months;\n    var data         = this._data;\n    var seconds, minutes, hours, years = 0;\n    data.milliseconds = milliseconds % 1000;\n\n    seconds           = absFloor(milliseconds / 1000);\n    data.seconds      = seconds % 60;\n\n    minutes           = absFloor(seconds / 60);\n    data.minutes      = minutes % 60;\n\n    hours             = absFloor(minutes / 60);\n    data.hours        = hours % 24;\n\n    days += absFloor(hours / 24);\n    years = absFloor(daysToYears(days));\n    days -= absFloor(yearsToDays(years));\n    months += absFloor(days / 30);\n    days   %= 30;\n    years  += absFloor(months / 12);\n    months %= 12;\n\n    data.days   = days;\n    data.months = months;\n    data.years  = years;\n\n    return this;\n}\n\nexport function daysToYears (days) {\n    return days * 400 / 146097;\n}\n\nexport function yearsToDays (years) {\n    return years * 146097 / 400;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/duration/constructor.js",
    "content": "import { normalizeObjectUnits } from '../units/aliases';\nimport { getLocale } from '../locale/locales';\n\nexport function Duration (duration) {\n    var normalizedInput = normalizeObjectUnits(duration),\n        years = normalizedInput.year || 0,\n        quarters = normalizedInput.quarter || 0,\n        months = normalizedInput.month || 0,\n        weeks = normalizedInput.week || 0,\n        days = normalizedInput.day || 0,\n        hours = normalizedInput.hour || 0,\n        minutes = normalizedInput.minute || 0,\n        seconds = normalizedInput.second || 0,\n        milliseconds = normalizedInput.millisecond || 0;\n    this._milliseconds = +milliseconds +\n        seconds * 1e3 + // 1000\n        minutes * 6e4 + // 1000 * 60\n        hours * 36e5; // 1000 * 60 * 60\n    this._days = +days +\n        weeks * 7;\n    this._months = +months +\n        quarters * 3 +\n        years * 12;\n\n    this._data = {};\n\n    this._locale = getLocale();\n\n    this._bubble();\n}\n\nexport function isDuration (obj) {\n    return obj instanceof Duration;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/duration/create.js",
    "content": "import { Duration, isDuration } from './constructor';\nimport toInt from '../utils/to-int';\nimport hasOwnProp from '../utils/has-own-prop';\nimport { DATE, HOUR, MINUTE, SECOND, MILLISECOND } from '../units/constants';\nimport { cloneWithOffset } from '../units/offset';\nimport { createLocal } from '../create/local';\nvar aspNetRegex = /(\\-)?(?:(\\d*)\\.)?(\\d+)\\:(\\d+)(?:\\:(\\d+)\\.?(\\d{3})?)?/;\nvar isoRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/;\n\nexport function createDuration (input, key) {\n    var duration = input,\n        match = null,\n        sign,\n        ret,\n        diffRes;\n\n    if (isDuration(input)) {\n        duration = {\n            ms : input._milliseconds,\n            d  : input._days,\n            M  : input._months\n        };\n    } else if (typeof input === 'number') {\n        duration = {};\n        if (key) {\n            duration[key] = input;\n        } else {\n            duration.milliseconds = input;\n        }\n    } else if (!!(match = aspNetRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y  : 0,\n            d  : toInt(match[DATE])        * sign,\n            h  : toInt(match[HOUR])        * sign,\n            m  : toInt(match[MINUTE])      * sign,\n            s  : toInt(match[SECOND])      * sign,\n            ms : toInt(match[MILLISECOND]) * sign\n        };\n    } else if (!!(match = isoRegex.exec(input))) {\n        sign = (match[1] === '-') ? -1 : 1;\n        duration = {\n            y : parseIso(match[2], sign),\n            M : parseIso(match[3], sign),\n            d : parseIso(match[4], sign),\n            h : parseIso(match[5], sign),\n            m : parseIso(match[6], sign),\n            s : parseIso(match[7], sign),\n            w : parseIso(match[8], sign)\n        };\n    } else if (duration == null) {// checks for null or undefined\n        duration = {};\n    } else if (typeof duration === 'object' && ('from' in duration || 'to' in duration)) {\n        diffRes = momentsDifference(createLocal(duration.from), createLocal(duration.to));\n\n        duration = {};\n        duration.ms = diffRes.milliseconds;\n        duration.M = diffRes.months;\n    }\n\n    ret = new Duration(duration);\n\n    if (isDuration(input) && hasOwnProp(input, '_locale')) {\n        ret._locale = input._locale;\n    }\n\n    return ret;\n}\n\ncreateDuration.fn = Duration.prototype;\n\nfunction parseIso (inp, sign) {\n    var res = inp && parseFloat(inp.replace(',', '.'));\n    return (isNaN(res) ? 0 : res) * sign;\n}\n\nfunction positiveMomentsDifference(base, other) {\n    var res = {milliseconds: 0, months: 0};\n\n    res.months = other.month() - base.month() +\n        (other.year() - base.year()) * 12;\n    if (base.clone().add(res.months, 'M').isAfter(other)) {\n        --res.months;\n    }\n\n    res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n    return res;\n}\n\nfunction momentsDifference(base, other) {\n    var res;\n    other = cloneWithOffset(other, base);\n    if (base.isBefore(other)) {\n        res = positiveMomentsDifference(base, other);\n    } else {\n        res = positiveMomentsDifference(other, base);\n        res.milliseconds = -res.milliseconds;\n        res.months = -res.months;\n    }\n\n    return res;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/duration/duration.js",
    "content": "import './prototype';\n\nimport { createDuration } from './create';\nimport { isDuration } from './constructor';\nimport { getSetRelativeTimeThreshold } from './humanize';\n\nexport {\n    createDuration,\n    isDuration,\n    getSetRelativeTimeThreshold\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/duration/get.js",
    "content": "import { normalizeUnits } from '../units/aliases';\nimport absFloor from '../utils/abs-floor';\n\nexport function get (units) {\n    units = normalizeUnits(units);\n    return this[units + 's']();\n}\n\nfunction makeGetter(name) {\n    return function () {\n        return this._data[name];\n    };\n}\n\nexport var milliseconds = makeGetter('milliseconds');\nexport var seconds      = makeGetter('seconds');\nexport var minutes      = makeGetter('minutes');\nexport var hours        = makeGetter('hours');\nexport var days         = makeGetter('days');\nexport var months       = makeGetter('months');\nexport var years        = makeGetter('years');\n\nexport function weeks () {\n    return absFloor(this.days() / 7);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/duration/humanize.js",
    "content": "import { createDuration } from './create';\n\nvar round = Math.round;\nvar thresholds = {\n    s: 45,  // seconds to minute\n    m: 45,  // minutes to hour\n    h: 22,  // hours to day\n    d: 26,  // days to month\n    M: 11   // months to year\n};\nfunction substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n    return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n}\n\nfunction relativeTime (posNegDuration, withoutSuffix, locale) {\n    var duration = createDuration(posNegDuration).abs();\n    var seconds  = round(duration.as('s'));\n    var minutes  = round(duration.as('m'));\n    var hours    = round(duration.as('h'));\n    var days     = round(duration.as('d'));\n    var months   = round(duration.as('M'));\n    var years    = round(duration.as('y'));\n\n    var a = seconds < thresholds.s && ['s', seconds]  ||\n            minutes === 1          && ['m']           ||\n            minutes < thresholds.m && ['mm', minutes] ||\n            hours   === 1          && ['h']           ||\n            hours   < thresholds.h && ['hh', hours]   ||\n            days    === 1          && ['d']           ||\n            days    < thresholds.d && ['dd', days]    ||\n            months  === 1          && ['M']           ||\n            months  < thresholds.M && ['MM', months]  ||\n            years   === 1          && ['y']           || ['yy', years];\n\n    a[2] = withoutSuffix;\n    a[3] = +posNegDuration > 0;\n    a[4] = locale;\n    return substituteTimeAgo.apply(null, a);\n}\nexport function getSetRelativeTimeThreshold (threshold, limit) {\n    if (thresholds[threshold] === undefined) {\n        return false;\n    }\n    if (limit === undefined) {\n        return thresholds[threshold];\n    }\n    thresholds[threshold] = limit;\n    return true;\n}\n\nexport function humanize (withSuffix) {\n    var locale = this.localeData();\n    var output = relativeTime(this, !withSuffix, locale);\n\n    if (withSuffix) {\n        output = locale.pastFuture(+this, output);\n    }\n\n    return locale.postformat(output);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/duration/iso-string.js",
    "content": "var abs = Math.abs;\n\nexport function toISOString() {\n    var Y = abs(this.years());\n    var M = abs(this.months());\n    var D = abs(this.days());\n    var h = abs(this.hours());\n    var m = abs(this.minutes());\n    var s = abs(this.seconds() + this.milliseconds() / 1000);\n    var total = this.asSeconds();\n\n    if (!total) {\n        return 'P0D';\n    }\n\n    return (total < 0 ? '-' : '') +\n        'P' +\n        (Y ? Y + 'Y' : '') +\n        (M ? M + 'M' : '') +\n        (D ? D + 'D' : '') +\n        ((h || m || s) ? 'T' : '') +\n        (h ? h + 'H' : '') +\n        (m ? m + 'M' : '') +\n        (s ? s + 'S' : '');\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/duration/prototype.js",
    "content": "import { Duration } from './constructor';\n\nvar proto = Duration.prototype;\n\nimport { abs } from './abs';\nimport { add, subtract } from './add-subtract';\nimport { as, asMilliseconds, asSeconds, asMinutes, asHours, asDays, asWeeks, asMonths, asYears, valueOf } from './as';\nimport { bubble } from './bubble';\nimport { get, milliseconds, seconds, minutes, hours, days, months, years, weeks } from './get';\nimport { humanize } from './humanize';\nimport { toISOString } from './iso-string';\nimport { lang, locale, localeData } from '../moment/locale';\n\nproto.abs            = abs;\nproto.add            = add;\nproto.subtract       = subtract;\nproto.as             = as;\nproto.asMilliseconds = asMilliseconds;\nproto.asSeconds      = asSeconds;\nproto.asMinutes      = asMinutes;\nproto.asHours        = asHours;\nproto.asDays         = asDays;\nproto.asWeeks        = asWeeks;\nproto.asMonths       = asMonths;\nproto.asYears        = asYears;\nproto.valueOf        = valueOf;\nproto._bubble        = bubble;\nproto.get            = get;\nproto.milliseconds   = milliseconds;\nproto.seconds        = seconds;\nproto.minutes        = minutes;\nproto.hours          = hours;\nproto.days           = days;\nproto.weeks          = weeks;\nproto.months         = months;\nproto.years          = years;\nproto.humanize       = humanize;\nproto.toISOString    = toISOString;\nproto.toString       = toISOString;\nproto.toJSON         = toISOString;\nproto.locale         = locale;\nproto.localeData     = localeData;\nimport { deprecate } from '../utils/deprecate';\n\nproto.toIsoString = deprecate('toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)', toISOString);\nproto.lang = lang;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/format/format.js",
    "content": "import zeroFill from '../utils/zero-fill';\n\nexport var formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|x|X|zz?|ZZ?|.)/g;\n\nvar localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g;\n\nvar formatFunctions = {};\n\nexport var formatTokenFunctions = {};\nexport function addFormatToken (token, padded, ordinal, callback) {\n    var func = callback;\n    if (typeof callback === 'string') {\n        func = function () {\n            return this[callback]();\n        };\n    }\n    if (token) {\n        formatTokenFunctions[token] = func;\n    }\n    if (padded) {\n        formatTokenFunctions[padded[0]] = function () {\n            return zeroFill(func.apply(this, arguments), padded[1], padded[2]);\n        };\n    }\n    if (ordinal) {\n        formatTokenFunctions[ordinal] = function () {\n            return this.localeData().ordinal(func.apply(this, arguments), token);\n        };\n    }\n}\n\nfunction removeFormattingTokens(input) {\n    if (input.match(/\\[[\\s\\S]/)) {\n        return input.replace(/^\\[|\\]$/g, '');\n    }\n    return input.replace(/\\\\/g, '');\n}\n\nfunction makeFormatFunction(format) {\n    var array = format.match(formattingTokens), i, length;\n\n    for (i = 0, length = array.length; i < length; i++) {\n        if (formatTokenFunctions[array[i]]) {\n            array[i] = formatTokenFunctions[array[i]];\n        } else {\n            array[i] = removeFormattingTokens(array[i]);\n        }\n    }\n\n    return function (mom) {\n        var output = '';\n        for (i = 0; i < length; i++) {\n            output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];\n        }\n        return output;\n    };\n}\nexport function formatMoment(m, format) {\n    if (!m.isValid()) {\n        return m.localeData().invalidDate();\n    }\n\n    format = expandFormat(format, m.localeData());\n\n    if (!formatFunctions[format]) {\n        formatFunctions[format] = makeFormatFunction(format);\n    }\n\n    return formatFunctions[format](m);\n}\n\nexport function expandFormat(format, locale) {\n    var i = 5;\n\n    function replaceLongDateFormatTokens(input) {\n        return locale.longDateFormat(input) || input;\n    }\n\n    localFormattingTokens.lastIndex = 0;\n    while (i >= 0 && localFormattingTokens.test(format)) {\n        format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n        localFormattingTokens.lastIndex = 0;\n        i -= 1;\n    }\n\n    return format;\n}\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/locale/calendar.js",
    "content": "export var defaultCalendar = {\n    sameDay : '[Today at] LT',\n    nextDay : '[Tomorrow at] LT',\n    nextWeek : 'dddd [at] LT',\n    lastDay : '[Yesterday at] LT',\n    lastWeek : '[Last] dddd [at] LT',\n    sameElse : 'L'\n};\n\nexport function calendar (key, mom, now) {\n    var output = this._calendar[key];\n    return typeof output === 'function' ? output.call(mom, now) : output;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/locale/constructor.js",
    "content": "export function Locale() {\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/locale/en.js",
    "content": "import './prototype';\nimport { getSetGlobalLocale } from './locales';\nimport toInt from '../utils/to-int';\n\ngetSetGlobalLocale('en', {\n    ordinalParse: /\\d{1,2}(th|st|nd|rd)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (toInt(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/locale/formats.js",
    "content": "export var defaultLongDateFormat = {\n    LTS  : 'h:mm:ss A',\n    LT   : 'h:mm A',\n    L    : 'MM/DD/YYYY',\n    LL   : 'MMMM D, YYYY',\n    LLL  : 'MMMM D, YYYY LT',\n    LLLL : 'dddd, MMMM D, YYYY LT'\n};\n\nexport function longDateFormat (key) {\n    var output = this._longDateFormat[key];\n    if (!output && this._longDateFormat[key.toUpperCase()]) {\n        output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {\n            return val.slice(1);\n        });\n        this._longDateFormat[key] = output;\n    }\n    return output;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/locale/invalid.js",
    "content": "export var defaultInvalidDate = 'Invalid date';\n\nexport function invalidDate () {\n    return this._invalidDate;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/locale/lists.js",
    "content": "import { getLocale } from './locales';\nimport { createUTC } from '../create/utc';\n\nfunction get (format, index, field, setter) {\n    var locale = getLocale();\n    var utc = createUTC().set(setter, index);\n    return locale[field](utc, format);\n}\n\nfunction list (format, index, field, count, setter) {\n    if (typeof format === 'number') {\n        index = format;\n        format = undefined;\n    }\n\n    format = format || '';\n\n    if (index != null) {\n        return get(format, index, field, setter);\n    }\n\n    var i;\n    var out = [];\n    for (i = 0; i < count; i++) {\n        out[i] = get(format, i, field, setter);\n    }\n    return out;\n}\n\nexport function listMonths (format, index) {\n    return list(format, index, 'months', 12, 'month');\n}\n\nexport function listMonthsShort (format, index) {\n    return list(format, index, 'monthsShort', 12, 'month');\n}\n\nexport function listWeekdays (format, index) {\n    return list(format, index, 'weekdays', 7, 'day');\n}\n\nexport function listWeekdaysShort (format, index) {\n    return list(format, index, 'weekdaysShort', 7, 'day');\n}\n\nexport function listWeekdaysMin (format, index) {\n    return list(format, index, 'weekdaysMin', 7, 'day');\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/locale/locale.js",
    "content": "import './prototype';\n\nimport {\n    getSetGlobalLocale,\n    defineLocale,\n    getLocale\n} from './locales';\n\nimport {\n    listMonths,\n    listMonthsShort,\n    listWeekdays,\n    listWeekdaysShort,\n    listWeekdaysMin\n} from './lists';\n\nexport {\n    getSetGlobalLocale,\n    defineLocale,\n    getLocale,\n    listMonths,\n    listMonthsShort,\n    listWeekdays,\n    listWeekdaysShort,\n    listWeekdaysMin\n};\n\nimport { deprecate } from '../utils/deprecate';\nimport { hooks } from '../utils/hooks';\n\nhooks.lang = deprecate('moment.lang is deprecated. Use moment.locale instead.', getSetGlobalLocale);\nhooks.langData = deprecate('moment.langData is deprecated. Use moment.localeData instead.', getLocale);\n\nimport './en';\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/locale/locales.js",
    "content": "import isArray from '../utils/is-array';\nimport compareArrays from '../utils/compare-arrays';\nimport { Locale } from './constructor';\nvar locales = {};\nvar globalLocale;\n\nfunction normalizeLocale(key) {\n    return key ? key.toLowerCase().replace('_', '-') : key;\n}\nfunction chooseLocale(names) {\n    var i = 0, j, next, locale, split;\n\n    while (i < names.length) {\n        split = normalizeLocale(names[i]).split('-');\n        j = split.length;\n        next = normalizeLocale(names[i + 1]);\n        next = next ? next.split('-') : null;\n        while (j > 0) {\n            locale = loadLocale(split.slice(0, j).join('-'));\n            if (locale) {\n                return locale;\n            }\n            if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                break;\n            }\n            j--;\n        }\n        i++;\n    }\n    return null;\n}\n\nfunction loadLocale(name) {\n    var oldLocale = null;\n    if (!locales[name] && typeof module !== 'undefined' &&\n            module && module.exports) {\n        try {\n            oldLocale = globalLocale._abbr;\n            require('./locale/' + name);\n            getSetGlobalLocale(oldLocale);\n        } catch (e) { }\n    }\n    return locales[name];\n}\nexport function getSetGlobalLocale (key, values) {\n    var data;\n    if (key) {\n        if (typeof values === 'undefined') {\n            data = getLocale(key);\n        }\n        else {\n            data = defineLocale(key, values);\n        }\n\n        if (data) {\n            globalLocale = data;\n        }\n    }\n\n    return globalLocale._abbr;\n}\n\nexport function defineLocale (name, values) {\n    if (values !== null) {\n        values.abbr = name;\n        if (!locales[name]) {\n            locales[name] = new Locale();\n        }\n        locales[name].set(values);\n        getSetGlobalLocale(name);\n\n        return locales[name];\n    } else {\n        delete locales[name];\n        return null;\n    }\n}\nexport function getLocale (key) {\n    var locale;\n\n    if (key && key._locale && key._locale._abbr) {\n        key = key._locale._abbr;\n    }\n\n    if (!key) {\n        return globalLocale;\n    }\n\n    if (!isArray(key)) {\n        locale = loadLocale(key);\n        if (locale) {\n            return locale;\n        }\n        key = [key];\n    }\n\n    return chooseLocale(key);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/locale/ordinal.js",
    "content": "export var defaultOrdinal = '%d';\nexport var defaultOrdinalParse = /\\d{1,2}/;\n\nexport function ordinal (number) {\n    return this._ordinal.replace('%d', number);\n}\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/locale/pre-post-format.js",
    "content": "export function preParsePostFormat (string) {\n    return string;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/locale/prototype.js",
    "content": "import { Locale } from './constructor';\n\nvar proto = Locale.prototype;\n\nimport { defaultCalendar, calendar } from './calendar';\nimport { defaultLongDateFormat, longDateFormat } from './formats';\nimport { defaultInvalidDate, invalidDate } from './invalid';\nimport { defaultOrdinal, ordinal, defaultOrdinalParse } from './ordinal';\nimport { preParsePostFormat } from './pre-post-format';\nimport { defaultRelativeTime, relativeTime, pastFuture } from './relative';\nimport { set } from './set';\n\nproto._calendar       = defaultCalendar;\nproto.calendar        = calendar;\nproto._longDateFormat = defaultLongDateFormat;\nproto.longDateFormat  = longDateFormat;\nproto._invalidDate    = defaultInvalidDate;\nproto.invalidDate     = invalidDate;\nproto._ordinal        = defaultOrdinal;\nproto.ordinal         = ordinal;\nproto._ordinalParse   = defaultOrdinalParse;\nproto.preparse        = preParsePostFormat;\nproto.postformat      = preParsePostFormat;\nproto._relativeTime   = defaultRelativeTime;\nproto.relativeTime    = relativeTime;\nproto.pastFuture      = pastFuture;\nproto.set             = set;\nimport {\n    localeMonthsParse,\n    defaultLocaleMonths,      localeMonths,\n    defaultLocaleMonthsShort, localeMonthsShort\n} from '../units/month';\n\nproto.months       =        localeMonths;\nproto._months      = defaultLocaleMonths;\nproto.monthsShort  =        localeMonthsShort;\nproto._monthsShort = defaultLocaleMonthsShort;\nproto.monthsParse  =        localeMonthsParse;\nimport { localeWeek, defaultLocaleWeek, localeFirstDayOfYear, localeFirstDayOfWeek } from '../units/week';\nproto.week = localeWeek;\nproto._week = defaultLocaleWeek;\nproto.firstDayOfYear = localeFirstDayOfYear;\nproto.firstDayOfWeek = localeFirstDayOfWeek;\nimport {\n    localeWeekdaysParse,\n    defaultLocaleWeekdays,      localeWeekdays,\n    defaultLocaleWeekdaysMin,   localeWeekdaysMin,\n    defaultLocaleWeekdaysShort, localeWeekdaysShort\n} from '../units/day-of-week';\n\nproto.weekdays       =        localeWeekdays;\nproto._weekdays      = defaultLocaleWeekdays;\nproto.weekdaysMin    =        localeWeekdaysMin;\nproto._weekdaysMin   = defaultLocaleWeekdaysMin;\nproto.weekdaysShort  =        localeWeekdaysShort;\nproto._weekdaysShort = defaultLocaleWeekdaysShort;\nproto.weekdaysParse  =        localeWeekdaysParse;\nimport { localeIsPM, defaultLocaleMeridiemParse, localeMeridiem } from '../units/hour';\n\nproto.isPM = localeIsPM;\nproto._meridiemParse = defaultLocaleMeridiemParse;\nproto.meridiem = localeMeridiem;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/locale/relative.js",
    "content": "export var defaultRelativeTime = {\n    future : 'in %s',\n    past   : '%s ago',\n    s  : 'a few seconds',\n    m  : 'a minute',\n    mm : '%d minutes',\n    h  : 'an hour',\n    hh : '%d hours',\n    d  : 'a day',\n    dd : '%d days',\n    M  : 'a month',\n    MM : '%d months',\n    y  : 'a year',\n    yy : '%d years'\n};\n\nexport function relativeTime (number, withoutSuffix, string, isFuture) {\n    var output = this._relativeTime[string];\n    return (typeof output === 'function') ?\n        output(number, withoutSuffix, string, isFuture) :\n        output.replace(/%d/i, number);\n}\n\nexport function pastFuture (diff, output) {\n    var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n    return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/locale/set.js",
    "content": "export function set (config) {\n    var prop, i;\n    for (i in config) {\n        prop = config[i];\n        if (typeof prop === 'function') {\n            this[i] = prop;\n        } else {\n            this['_' + i] = prop;\n        }\n    }\n    this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + /\\d{1,2}/.source);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/moment/add-subtract.js",
    "content": "import { get, set } from './get-set';\nimport { setMonth } from '../units/month';\nimport { createDuration } from '../duration/create';\nimport { deprecateSimple } from '../utils/deprecate';\nimport { hooks } from '../utils/hooks';\nfunction createAdder(direction, name) {\n    return function (val, period) {\n        var dur, tmp;\n        if (period !== null && !isNaN(+period)) {\n            deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period).');\n            tmp = val; val = period; period = tmp;\n        }\n\n        val = typeof val === 'string' ? +val : val;\n        dur = createDuration(val, period);\n        addSubtract(this, dur, direction);\n        return this;\n    };\n}\n\nexport function addSubtract (mom, duration, isAdding, updateOffset) {\n    var milliseconds = duration._milliseconds,\n        days = duration._days,\n        months = duration._months;\n    updateOffset = updateOffset == null ? true : updateOffset;\n\n    if (milliseconds) {\n        mom._d.setTime(+mom._d + milliseconds * isAdding);\n    }\n    if (days) {\n        set(mom, 'Date', get(mom, 'Date') + days * isAdding);\n    }\n    if (months) {\n        setMonth(mom, get(mom, 'Month') + months * isAdding);\n    }\n    if (updateOffset) {\n        hooks.updateOffset(mom, days || months);\n    }\n}\n\nexport var add      = createAdder(1, 'add');\nexport var subtract = createAdder(-1, 'subtract');\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/moment/calendar.js",
    "content": "import { createLocal } from '../create/local';\nimport { cloneWithOffset } from '../units/offset';\n\nexport function calendar (time) {\n    var now = time || createLocal(),\n        sod = cloneWithOffset(now, this).startOf('day'),\n        diff = this.diff(sod, 'days', true),\n        format = diff < -6 ? 'sameElse' :\n            diff < -1 ? 'lastWeek' :\n            diff < 0 ? 'lastDay' :\n            diff < 1 ? 'sameDay' :\n            diff < 2 ? 'nextDay' :\n            diff < 7 ? 'nextWeek' : 'sameElse';\n    return this.format(this.localeData().calendar(format, this, createLocal(now)));\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/moment/clone.js",
    "content": "import { Moment } from './constructor';\n\nexport function clone () {\n    return new Moment(this);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/moment/compare.js",
    "content": "import { isMoment } from './constructor';\nimport { normalizeUnits } from '../units/aliases';\nimport { createLocal } from '../create/local';\n\nexport function isAfter (input, units) {\n    var inputMs;\n    units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');\n    if (units === 'millisecond') {\n        input = isMoment(input) ? input : createLocal(input);\n        return +this > +input;\n    } else {\n        inputMs = isMoment(input) ? +input : +createLocal(input);\n        return inputMs < +this.clone().startOf(units);\n    }\n}\n\nexport function isBefore (input, units) {\n    var inputMs;\n    units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');\n    if (units === 'millisecond') {\n        input = isMoment(input) ? input : createLocal(input);\n        return +this < +input;\n    } else {\n        inputMs = isMoment(input) ? +input : +createLocal(input);\n        return +this.clone().endOf(units) < inputMs;\n    }\n}\n\nexport function isBetween (from, to, units) {\n    return this.isAfter(from, units) && this.isBefore(to, units);\n}\n\nexport function isSame (input, units) {\n    var inputMs;\n    units = normalizeUnits(units || 'millisecond');\n    if (units === 'millisecond') {\n        input = isMoment(input) ? input : createLocal(input);\n        return +this === +input;\n    } else {\n        inputMs = +createLocal(input);\n        return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units));\n    }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/moment/constructor.js",
    "content": "import { hooks } from '../utils/hooks';\nimport hasOwnProp from '../utils/has-own-prop';\nvar momentProperties = hooks.momentProperties = [];\n\nexport function copyConfig(to, from) {\n    var i, prop, val;\n\n    if (typeof from._isAMomentObject !== 'undefined') {\n        to._isAMomentObject = from._isAMomentObject;\n    }\n    if (typeof from._i !== 'undefined') {\n        to._i = from._i;\n    }\n    if (typeof from._f !== 'undefined') {\n        to._f = from._f;\n    }\n    if (typeof from._l !== 'undefined') {\n        to._l = from._l;\n    }\n    if (typeof from._strict !== 'undefined') {\n        to._strict = from._strict;\n    }\n    if (typeof from._tzm !== 'undefined') {\n        to._tzm = from._tzm;\n    }\n    if (typeof from._isUTC !== 'undefined') {\n        to._isUTC = from._isUTC;\n    }\n    if (typeof from._offset !== 'undefined') {\n        to._offset = from._offset;\n    }\n    if (typeof from._pf !== 'undefined') {\n        to._pf = from._pf;\n    }\n    if (typeof from._locale !== 'undefined') {\n        to._locale = from._locale;\n    }\n\n    if (momentProperties.length > 0) {\n        for (i in momentProperties) {\n            prop = momentProperties[i];\n            val = from[prop];\n            if (typeof val !== 'undefined') {\n                to[prop] = val;\n            }\n        }\n    }\n\n    return to;\n}\n\nvar updateInProgress = false;\nexport function Moment(config) {\n    copyConfig(this, config);\n    this._d = new Date(+config._d);\n    if (updateInProgress === false) {\n        updateInProgress = true;\n        hooks.updateOffset(this);\n        updateInProgress = false;\n    }\n}\n\nexport function isMoment (obj) {\n    return obj instanceof Moment || (obj != null && hasOwnProp(obj, '_isAMomentObject'));\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/moment/diff.js",
    "content": "import absFloor from '../utils/abs-floor';\nimport { cloneWithOffset } from '../units/offset';\nimport { normalizeUnits } from '../units/aliases';\n\nexport function diff (input, units, asFloat) {\n    var that = cloneWithOffset(input, this),\n        zoneDelta = (that.utcOffset() - this.utcOffset()) * 6e4,\n        delta, output;\n\n    units = normalizeUnits(units);\n\n    if (units === 'year' || units === 'month' || units === 'quarter') {\n        output = monthDiff(this, that);\n        if (units === 'quarter') {\n            output = output / 3;\n        } else if (units === 'year') {\n            output = output / 12;\n        }\n    } else {\n        delta = this - that;\n        output = units === 'second' ? delta / 1e3 : // 1000\n            units === 'minute' ? delta / 6e4 : // 1000 * 60\n            units === 'hour' ? delta / 36e5 : // 1000 * 60 * 60\n            units === 'day' ? (delta - zoneDelta) / 864e5 : // 1000 * 60 * 60 * 24, negate dst\n            units === 'week' ? (delta - zoneDelta) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst\n            delta;\n    }\n    return asFloat ? output : absFloor(output);\n}\n\nfunction monthDiff (a, b) {\n    var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n        anchor = a.clone().add(wholeMonthDiff, 'months'),\n        anchor2, adjust;\n\n    if (b - anchor < 0) {\n        anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n        adjust = (b - anchor) / (anchor - anchor2);\n    } else {\n        anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n        adjust = (b - anchor) / (anchor2 - anchor);\n    }\n\n    return -(wholeMonthDiff + adjust);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/moment/format.js",
    "content": "import { formatMoment } from '../format/format';\nimport { hooks } from '../utils/hooks';\n\nhooks.defaultFormat = 'YYYY-MM-DDTHH:mm:ssZ';\n\nexport function toString () {\n    return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n}\n\nexport function toISOString () {\n    var m = this.clone().utc();\n    if (0 < m.year() && m.year() <= 9999) {\n        if ('function' === typeof Date.prototype.toISOString) {\n            return this.toDate().toISOString();\n        } else {\n            return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n        }\n    } else {\n        return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n    }\n}\n\nexport function format (inputString) {\n    var output = formatMoment(this, inputString || hooks.defaultFormat);\n    return this.localeData().postformat(output);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/moment/from.js",
    "content": "import { createDuration } from '../duration/create';\nimport { createLocal } from '../create/local';\n\nexport function from (time, withoutSuffix) {\n    return createDuration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n}\n\nexport function fromNow (withoutSuffix) {\n    return this.from(createLocal(), withoutSuffix);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/moment/get-set.js",
    "content": "import { normalizeUnits } from '../units/aliases';\nimport { hooks } from '../utils/hooks';\n\nexport function makeGetSet (unit, keepTime) {\n    return function (value) {\n        if (value != null) {\n            set(this, unit, value);\n            hooks.updateOffset(this, keepTime);\n            return this;\n        } else {\n            return get(this, unit);\n        }\n    };\n}\n\nexport function get (mom, unit) {\n    return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();\n}\n\nexport function set (mom, unit, value) {\n    return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n}\n\nexport function getSet (units, value) {\n    var unit;\n    if (typeof units === 'object') {\n        for (unit in units) {\n            this.set(unit, units[unit]);\n        }\n    } else {\n        units = normalizeUnits(units);\n        if (typeof this[units] === 'function') {\n            return this[units](value);\n        }\n    }\n    return this;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/moment/locale.js",
    "content": "import { getLocale } from '../locale/locales';\nimport { deprecate } from '../utils/deprecate';\nexport function locale (key) {\n    var newLocaleData;\n\n    if (key === undefined) {\n        return this._locale._abbr;\n    } else {\n        newLocaleData = getLocale(key);\n        if (newLocaleData != null) {\n            this._locale = newLocaleData;\n        }\n        return this;\n    }\n}\n\nexport var lang = deprecate(\n    'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n    function (key) {\n        if (key === undefined) {\n            return this.localeData();\n        } else {\n            return this.locale(key);\n        }\n    }\n);\n\nexport function localeData () {\n    return this._locale;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/moment/min-max.js",
    "content": "import { deprecate } from '../utils/deprecate';\nimport isArray from '../utils/is-array';\nimport { createLocal } from '../create/local';\n\nexport var prototypeMin = deprecate(\n     'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',\n     function () {\n         var other = createLocal.apply(null, arguments);\n         return other < this ? this : other;\n     }\n );\n\nexport var prototypeMax = deprecate(\n    'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',\n    function () {\n        var other = createLocal.apply(null, arguments);\n        return other > this ? this : other;\n    }\n);\nfunction pickBy(fn, moments) {\n    var res, i;\n    if (moments.length === 1 && isArray(moments[0])) {\n        moments = moments[0];\n    }\n    if (!moments.length) {\n        return createLocal();\n    }\n    res = moments[0];\n    for (i = 1; i < moments.length; ++i) {\n        if (moments[i][fn](res)) {\n            res = moments[i];\n        }\n    }\n    return res;\n}\nexport function min () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isBefore', args);\n}\n\nexport function max () {\n    var args = [].slice.call(arguments, 0);\n\n    return pickBy('isAfter', args);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/moment/moment.js",
    "content": "import { createLocal } from '../create/local';\nimport { createUTC } from '../create/utc';\nimport { createInvalid } from '../create/valid';\nimport { isMoment } from './constructor';\nimport { min, max } from './min-max';\nimport momentPrototype from './prototype';\n\nfunction createUnix (input) {\n    return createLocal(input * 1000);\n}\n\nfunction createInZone () {\n    return createLocal.apply(null, arguments).parseZone();\n}\n\nexport {\n    min,\n    max,\n    isMoment,\n    createUTC,\n    createUnix,\n    createLocal,\n    createInZone,\n    createInvalid,\n    momentPrototype\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/moment/prototype.js",
    "content": "import { Moment } from './constructor';\n\nvar proto = Moment.prototype;\n\nimport { add, subtract } from './add-subtract';\nimport { calendar } from './calendar';\nimport { clone } from './clone';\nimport { isBefore, isBetween, isSame, isAfter } from './compare';\nimport { diff } from './diff';\nimport { format, toString, toISOString } from './format';\nimport { from, fromNow } from './from';\nimport { getSet } from './get-set';\nimport { locale, localeData, lang } from './locale';\nimport { prototypeMin, prototypeMax } from './min-max';\nimport { startOf, endOf } from './start-end-of';\nimport { valueOf, toDate, toArray, unix } from './to-type';\nimport { isValid, parsingFlags, invalidAt } from './valid';\n\nproto.add          = add;\nproto.calendar     = calendar;\nproto.clone        = clone;\nproto.diff         = diff;\nproto.endOf        = endOf;\nproto.format       = format;\nproto.from         = from;\nproto.fromNow      = fromNow;\nproto.get          = getSet;\nproto.invalidAt    = invalidAt;\nproto.isAfter      = isAfter;\nproto.isBefore     = isBefore;\nproto.isBetween    = isBetween;\nproto.isSame       = isSame;\nproto.isValid      = isValid;\nproto.lang         = lang;\nproto.locale       = locale;\nproto.localeData   = localeData;\nproto.max          = prototypeMax;\nproto.min          = prototypeMin;\nproto.parsingFlags = parsingFlags;\nproto.set          = getSet;\nproto.startOf      = startOf;\nproto.subtract     = subtract;\nproto.toArray      = toArray;\nproto.toDate       = toDate;\nproto.toISOString  = toISOString;\nproto.toJSON       = toISOString;\nproto.toString     = toString;\nproto.unix         = unix;\nproto.valueOf      = valueOf;\nimport { getSetYear, getIsLeapYear } from '../units/year';\nproto.year       = getSetYear;\nproto.isLeapYear = getIsLeapYear;\nimport { getSetWeekYear, getSetISOWeekYear, getWeeksInYear, getISOWeeksInYear } from '../units/week-year';\nproto.weekYear    = getSetWeekYear;\nproto.isoWeekYear = getSetISOWeekYear;\nimport { getSetQuarter } from '../units/quarter';\nproto.quarter = proto.quarters = getSetQuarter;\nimport { getSetMonth, getDaysInMonth } from '../units/month';\nproto.month       = getSetMonth;\nproto.daysInMonth = getDaysInMonth;\nimport { getSetWeek, getSetISOWeek } from '../units/week';\nproto.week           = proto.weeks        = getSetWeek;\nproto.isoWeek        = proto.isoWeeks     = getSetISOWeek;\nproto.weeksInYear    = getWeeksInYear;\nproto.isoWeeksInYear = getISOWeeksInYear;\nimport { getSetDayOfMonth } from '../units/day-of-month';\nimport { getSetDayOfWeek, getSetISODayOfWeek, getSetLocaleDayOfWeek } from '../units/day-of-week';\nimport { getSetDayOfYear } from '../units/day-of-year';\nproto.date       = getSetDayOfMonth;\nproto.day        = proto.days             = getSetDayOfWeek;\nproto.weekday    = getSetLocaleDayOfWeek;\nproto.isoWeekday = getSetISODayOfWeek;\nproto.dayOfYear  = getSetDayOfYear;\nimport { getSetHour } from '../units/hour';\nproto.hour = proto.hours = getSetHour;\nimport { getSetMinute } from '../units/minute';\nproto.minute = proto.minutes = getSetMinute;\nimport { getSetSecond } from '../units/second';\nproto.second = proto.seconds = getSetSecond;\nimport { getSetMillisecond } from '../units/millisecond';\nproto.millisecond = proto.milliseconds = getSetMillisecond;\nimport {\n    getSetOffset,\n    setOffsetToUTC,\n    setOffsetToLocal,\n    setOffsetToParsedOffset,\n    hasAlignedHourOffset,\n    isDaylightSavingTime,\n    isDaylightSavingTimeShifted,\n    getSetZone,\n    isLocal,\n    isUtcOffset,\n    isUtc\n} from '../units/offset';\nproto.utcOffset            = getSetOffset;\nproto.utc                  = setOffsetToUTC;\nproto.local                = setOffsetToLocal;\nproto.parseZone            = setOffsetToParsedOffset;\nproto.hasAlignedHourOffset = hasAlignedHourOffset;\nproto.isDST                = isDaylightSavingTime;\nproto.isDSTShifted         = isDaylightSavingTimeShifted;\nproto.isLocal              = isLocal;\nproto.isUtcOffset          = isUtcOffset;\nproto.isUtc                = isUtc;\nproto.isUTC                = isUtc;\nimport { getZoneAbbr, getZoneName } from '../units/timezone';\nproto.zoneAbbr = getZoneAbbr;\nproto.zoneName = getZoneName;\nimport { deprecate } from '../utils/deprecate';\nproto.dates  = deprecate('dates accessor is deprecated. Use date instead.', getSetDayOfMonth);\nproto.months = deprecate('months accessor is deprecated. Use month instead', getSetMonth);\nproto.years  = deprecate('years accessor is deprecated. Use year instead', getSetYear);\nproto.zone   = deprecate('moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779', getSetZone);\n\nexport default proto;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/moment/start-end-of.js",
    "content": "import { normalizeUnits } from '../units/aliases';\n\nexport function startOf (units) {\n    units = normalizeUnits(units);\n    switch (units) {\n    case 'year':\n        this.month(0);\n        /* falls through */\n    case 'quarter':\n    case 'month':\n        this.date(1);\n        /* falls through */\n    case 'week':\n    case 'isoWeek':\n    case 'day':\n        this.hours(0);\n        /* falls through */\n    case 'hour':\n        this.minutes(0);\n        /* falls through */\n    case 'minute':\n        this.seconds(0);\n        /* falls through */\n    case 'second':\n        this.milliseconds(0);\n    }\n    if (units === 'week') {\n        this.weekday(0);\n    }\n    if (units === 'isoWeek') {\n        this.isoWeekday(1);\n    }\n    if (units === 'quarter') {\n        this.month(Math.floor(this.month() / 3) * 3);\n    }\n\n    return this;\n}\n\nexport function endOf (units) {\n    units = normalizeUnits(units);\n    if (units === undefined || units === 'millisecond') {\n        return this;\n    }\n    return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/moment/to-type.js",
    "content": "export function valueOf () {\n    return +this._d - ((this._offset || 0) * 60000);\n}\n\nexport function unix () {\n    return Math.floor(+this / 1000);\n}\n\nexport function toDate () {\n    return this._offset ? new Date(+this) : this._d;\n}\n\nexport function toArray () {\n    var m = this;\n    return [m.year(), m.month(), m.date(), m.hour(), m.minute(), m.second(), m.millisecond()];\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/moment/valid.js",
    "content": "import { isValid as _isValid } from '../create/valid';\nimport extend from '../utils/extend';\n\nexport function isValid () {\n    return _isValid(this);\n}\n\nexport function parsingFlags () {\n    return extend({}, this._pf);\n}\n\nexport function invalidAt () {\n    return this._pf.overflow;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/parse/regex.js",
    "content": "export var match1         = /\\d/;            //       0 - 9\nexport var match2         = /\\d\\d/;          //      00 - 99\nexport var match3         = /\\d{3}/;         //     000 - 999\nexport var match4         = /\\d{4}/;         //    0000 - 9999\nexport var match6         = /[+-]?\\d{6}/;    // -999999 - 999999\nexport var match1to2      = /\\d\\d?/;         //       0 - 99\nexport var match1to3      = /\\d{1,3}/;       //       0 - 999\nexport var match1to4      = /\\d{1,4}/;       //       0 - 9999\nexport var match1to6      = /[+-]?\\d{1,6}/;  // -999999 - 999999\n\nexport var matchUnsigned  = /\\d+/;           //       0 - inf\nexport var matchSigned    = /[+-]?\\d+/;      //    -inf - inf\n\nexport var matchOffset    = /Z|[+-]\\d\\d:?\\d\\d/gi; // +00:00 -00:00 +0000 -0000 or Z\n\nexport var matchTimestamp = /[+-]?\\d+(\\.\\d{1,3})?/; // 123456789 123456789.123\nexport var matchWord = /[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF\\/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i;\n\nimport hasOwnProp from '../utils/has-own-prop';\n\nvar regexes = {};\n\nexport function addRegexToken (token, regex, strictRegex) {\n    regexes[token] = typeof regex === 'function' ? regex : function (isStrict) {\n        return (isStrict && strictRegex) ? strictRegex : regex;\n    };\n}\n\nexport function getParseRegexForToken (token, config) {\n    if (!hasOwnProp(regexes, token)) {\n        return new RegExp(unescapeFormat(token));\n    }\n\n    return regexes[token](config._strict, config._locale);\n}\nfunction unescapeFormat(s) {\n    return s.replace('\\\\', '').replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n        return p1 || p2 || p3 || p4;\n    }).replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/parse/token.js",
    "content": "import hasOwnProp from '../utils/has-own-prop';\nimport toInt from '../utils/to-int';\n\nvar tokens = {};\n\nexport function addParseToken (token, callback) {\n    var i, func = callback;\n    if (typeof token === 'string') {\n        token = [token];\n    }\n    if (typeof callback === 'number') {\n        func = function (input, array) {\n            array[callback] = toInt(input);\n        };\n    }\n    for (i = 0; i < token.length; i++) {\n        tokens[token[i]] = func;\n    }\n}\n\nexport function addWeekParseToken (token, callback) {\n    addParseToken(token, function (input, array, config, token) {\n        config._w = config._w || {};\n        callback(input, config._w, config, token);\n    });\n}\n\nexport function addTimeToArrayFromToken(token, input, config) {\n    if (input != null && hasOwnProp(tokens, token)) {\n        tokens[token](input, config._a, config, token);\n    }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/units/aliases.js",
    "content": "import hasOwnProp from '../utils/has-own-prop';\n\nvar aliases = {};\n\nexport function addUnitAlias (unit, shorthand) {\n    var lowerCase = unit.toLowerCase();\n    aliases[lowerCase] = aliases[lowerCase + 's'] = aliases[shorthand] = unit;\n}\n\nexport function normalizeUnits(units) {\n    return typeof units === 'string' ? aliases[units] || aliases[units.toLowerCase()] : undefined;\n}\n\nexport function normalizeObjectUnits(inputObject) {\n    var normalizedInput = {},\n        normalizedProp,\n        prop;\n\n    for (prop in inputObject) {\n        if (hasOwnProp(inputObject, prop)) {\n            normalizedProp = normalizeUnits(prop);\n            if (normalizedProp) {\n                normalizedInput[normalizedProp] = inputObject[prop];\n            }\n        }\n    }\n\n    return normalizedInput;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/units/constants.js",
    "content": "export var YEAR = 0;\nexport var MONTH = 1;\nexport var DATE = 2;\nexport var HOUR = 3;\nexport var MINUTE = 4;\nexport var SECOND = 5;\nexport var MILLISECOND = 6;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/units/day-of-month.js",
    "content": "import { makeGetSet } from '../moment/get-set';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addRegexToken, match1to2, match2 } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { DATE } from './constants';\nimport toInt from '../utils/to-int';\n\naddFormatToken('D', ['DD', 2], 'Do', 'date');\n\naddUnitAlias('date', 'D');\n\naddRegexToken('D',  match1to2);\naddRegexToken('DD', match1to2, match2);\naddRegexToken('Do', function (isStrict, locale) {\n    return isStrict ? locale._ordinalParse : locale._ordinalParseLenient;\n});\n\naddParseToken(['D', 'DD'], DATE);\naddParseToken('Do', function (input, array) {\n    array[DATE] = toInt(input.match(match1to2)[0], 10);\n});\n\nexport var getSetDayOfMonth = makeGetSet('Date', true);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/units/day-of-week.js",
    "content": "import { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addRegexToken, match1to2, matchWord } from '../parse/regex';\nimport { addWeekParseToken } from '../parse/token';\nimport toInt from '../utils/to-int';\nimport { createLocal } from '../create/local';\n\naddFormatToken('d', 0, 'do', 'day');\n\naddFormatToken('dd', 0, 0, function (format) {\n    return this.localeData().weekdaysMin(this, format);\n});\n\naddFormatToken('ddd', 0, 0, function (format) {\n    return this.localeData().weekdaysShort(this, format);\n});\n\naddFormatToken('dddd', 0, 0, function (format) {\n    return this.localeData().weekdays(this, format);\n});\n\naddFormatToken('e', 0, 0, 'weekday');\naddFormatToken('E', 0, 0, 'isoWeekday');\n\naddUnitAlias('day', 'd');\naddUnitAlias('weekday', 'e');\naddUnitAlias('isoWeekday', 'E');\n\naddRegexToken('d',    match1to2);\naddRegexToken('e',    match1to2);\naddRegexToken('E',    match1to2);\naddRegexToken('dd',   matchWord);\naddRegexToken('ddd',  matchWord);\naddRegexToken('dddd', matchWord);\n\naddWeekParseToken(['dd', 'ddd', 'dddd'], function (input, week, config) {\n    var weekday = config._locale.weekdaysParse(input);\n    if (weekday != null) {\n        week.d = weekday;\n    } else {\n        config._pf.invalidWeekday = input;\n    }\n});\n\naddWeekParseToken(['d', 'e', 'E'], function (input, week, config, token) {\n    week[token] = toInt(input);\n});\n\nfunction parseWeekday(input, locale) {\n    if (typeof input === 'string') {\n        if (!isNaN(input)) {\n            input = parseInt(input, 10);\n        }\n        else {\n            input = locale.weekdaysParse(input);\n            if (typeof input !== 'number') {\n                return null;\n            }\n        }\n    }\n    return input;\n}\n\nexport var defaultLocaleWeekdays = 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_');\nexport function localeWeekdays (m) {\n    return this._weekdays[m.day()];\n}\n\nexport var defaultLocaleWeekdaysShort = 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_');\nexport function localeWeekdaysShort (m) {\n    return this._weekdaysShort[m.day()];\n}\n\nexport var defaultLocaleWeekdaysMin = 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_');\nexport function localeWeekdaysMin (m) {\n    return this._weekdaysMin[m.day()];\n}\n\nexport function localeWeekdaysParse (weekdayName) {\n    var i, mom, regex;\n\n    if (!this._weekdaysParse) {\n        this._weekdaysParse = [];\n    }\n\n    for (i = 0; i < 7; i++) {\n        if (!this._weekdaysParse[i]) {\n            mom = createLocal([2000, 1]).day(i);\n            regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n            this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        if (this._weekdaysParse[i].test(weekdayName)) {\n            return i;\n        }\n    }\n}\n\nexport function getSetDayOfWeek (input) {\n    var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n    if (input != null) {\n        input = parseWeekday(input, this.localeData());\n        return this.add(input - day, 'd');\n    } else {\n        return day;\n    }\n}\n\nexport function getSetLocaleDayOfWeek (input) {\n    var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n    return input == null ? weekday : this.add(input - weekday, 'd');\n}\n\nexport function getSetISODayOfWeek (input) {\n    return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/units/day-of-year.js",
    "content": "import { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addRegexToken, match3, match1to3 } from '../parse/regex';\nimport { daysInYear } from './year';\nimport { createUTCDate } from '../create/date-from-array';\nimport { addParseToken } from '../parse/token';\nimport toInt from '../utils/to-int';\n\naddFormatToken('DDD', ['DDDD', 3], 'DDDo', 'dayOfYear');\n\naddUnitAlias('dayOfYear', 'DDD');\n\naddRegexToken('DDD',  match1to3);\naddRegexToken('DDDD', match3);\naddParseToken(['DDD', 'DDDD'], function (input, array, config) {\n    config._dayOfYear = toInt(input);\n});\nexport function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {\n    var d = createUTCDate(year, 0, 1).getUTCDay();\n    var daysToAdd;\n    var dayOfYear;\n\n    d = d === 0 ? 7 : d;\n    weekday = weekday != null ? weekday : firstDayOfWeek;\n    daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0);\n    dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;\n\n    return {\n        year      : dayOfYear > 0 ? year      : year - 1,\n        dayOfYear : dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear\n    };\n}\n\nexport function getSetDayOfYear (input) {\n    var dayOfYear = Math.round((this.clone().startOf('day') - this.clone().startOf('year')) / 864e5) + 1;\n    return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/units/hour.js",
    "content": "import { makeGetSet } from '../moment/get-set';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addRegexToken, match1to2, match2 } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { HOUR } from './constants';\nimport toInt from '../utils/to-int';\n\naddFormatToken('H', ['HH', 2], 0, 'hour');\naddFormatToken('h', ['hh', 2], 0, function () {\n    return this.hours() % 12 || 12;\n});\n\nfunction meridiem (token, lowercase) {\n    addFormatToken(token, 0, 0, function () {\n        return this.localeData().meridiem(this.hours(), this.minutes(), lowercase);\n    });\n}\n\nmeridiem('a', true);\nmeridiem('A', false);\n\naddUnitAlias('hour', 'h');\n\nfunction matchMeridiem (isStrict, locale) {\n    return locale._meridiemParse;\n}\n\naddRegexToken('a',  matchMeridiem);\naddRegexToken('A',  matchMeridiem);\naddRegexToken('H',  match1to2);\naddRegexToken('h',  match1to2);\naddRegexToken('HH', match1to2, match2);\naddRegexToken('hh', match1to2, match2);\n\naddParseToken(['H', 'HH'], HOUR);\naddParseToken(['a', 'A'], function (input, array, config) {\n    config._isPm = config._locale.isPM(input);\n    config._meridiem = input;\n});\naddParseToken(['h', 'hh'], function (input, array, config) {\n    array[HOUR] = toInt(input);\n    config._pf.bigHour = true;\n});\n\nexport function localeIsPM (input) {\n    return ((input + '').toLowerCase().charAt(0) === 'p');\n}\n\nexport var defaultLocaleMeridiemParse = /[ap]\\.?m?\\.?/i;\nexport function localeMeridiem (hours, minutes, isLower) {\n    if (hours > 11) {\n        return isLower ? 'pm' : 'PM';\n    } else {\n        return isLower ? 'am' : 'AM';\n    }\n}\nexport var getSetHour = makeGetSet('Hours', true);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/units/millisecond.js",
    "content": "import { makeGetSet } from '../moment/get-set';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addRegexToken, match1, match2, match3, match1to3, matchUnsigned } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { MILLISECOND } from './constants';\nimport toInt from '../utils/to-int';\n\naddFormatToken('S', 0, 0, function () {\n    return ~~(this.millisecond() / 100);\n});\n\naddFormatToken(0, ['SS', 2], 0, function () {\n    return ~~(this.millisecond() / 10);\n});\n\nfunction milliseconds (token) {\n    addFormatToken(0, [token, 3], 0, 'millisecond');\n}\n\nmilliseconds('SSS');\nmilliseconds('SSSS');\n\naddUnitAlias('millisecond', 'ms');\n\naddRegexToken('S',    match1to3, match1);\naddRegexToken('SS',   match1to3, match2);\naddRegexToken('SSS',  match1to3, match3);\naddRegexToken('SSSS', matchUnsigned);\naddParseToken(['S', 'SS', 'SSS', 'SSSS'], function (input, array) {\n    array[MILLISECOND] = toInt(('0.' + input) * 1000);\n});\n\nexport var getSetMillisecond = makeGetSet('Milliseconds', false);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/units/minute.js",
    "content": "import { makeGetSet } from '../moment/get-set';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addRegexToken, match1to2, match2 } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { MINUTE } from './constants';\n\naddFormatToken('m', ['mm', 2], 0, 'minute');\n\naddUnitAlias('minute', 'm');\n\naddRegexToken('m',  match1to2);\naddRegexToken('mm', match1to2, match2);\naddParseToken(['m', 'mm'], MINUTE);\n\nexport var getSetMinute = makeGetSet('Minutes', false);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/units/month.js",
    "content": "import { get } from '../moment/get-set';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addRegexToken, match1to2, match2, matchWord } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { hooks } from '../utils/hooks';\nimport { MONTH } from './constants';\nimport toInt from '../utils/to-int';\nimport { createUTC } from '../create/utc';\n\nexport function daysInMonth(year, month) {\n    return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n}\n\naddFormatToken('M', ['MM', 2], 'Mo', function () {\n    return this.month() + 1;\n});\n\naddFormatToken('MMM', 0, 0, function (format) {\n    return this.localeData().monthsShort(this, format);\n});\n\naddFormatToken('MMMM', 0, 0, function (format) {\n    return this.localeData().months(this, format);\n});\n\naddUnitAlias('month', 'M');\n\naddRegexToken('M',    match1to2);\naddRegexToken('MM',   match1to2, match2);\naddRegexToken('MMM',  matchWord);\naddRegexToken('MMMM', matchWord);\n\naddParseToken(['M', 'MM'], function (input, array) {\n    array[MONTH] = toInt(input) - 1;\n});\n\naddParseToken(['MMM', 'MMMM'], function (input, array, config, token) {\n    var month = config._locale.monthsParse(input, token, config._strict);\n    if (month != null) {\n        array[MONTH] = month;\n    } else {\n        config._pf.invalidMonth = input;\n    }\n});\n\nexport var defaultLocaleMonths = 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_');\nexport function localeMonths (m) {\n    return this._months[m.month()];\n}\n\nexport var defaultLocaleMonthsShort = 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_');\nexport function localeMonthsShort (m) {\n    return this._monthsShort[m.month()];\n}\n\nexport function localeMonthsParse (monthName, format, strict) {\n    var i, mom, regex;\n\n    if (!this._monthsParse) {\n        this._monthsParse = [];\n        this._longMonthsParse = [];\n        this._shortMonthsParse = [];\n    }\n\n    for (i = 0; i < 12; i++) {\n        mom = createUTC([2000, i]);\n        if (strict && !this._longMonthsParse[i]) {\n            this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n            this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n        }\n        if (!strict && !this._monthsParse[i]) {\n            regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n            this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n        }\n        if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n            return i;\n        } else if (!strict && this._monthsParse[i].test(monthName)) {\n            return i;\n        }\n    }\n}\n\nexport function setMonth (mom, value) {\n    var dayOfMonth;\n    if (typeof value === 'string') {\n        value = mom.localeData().monthsParse(value);\n        if (typeof value !== 'number') {\n            return mom;\n        }\n    }\n\n    dayOfMonth = Math.min(mom.date(), daysInMonth(mom.year(), value));\n    mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n    return mom;\n}\n\nexport function getSetMonth (value) {\n    if (value != null) {\n        setMonth(this, value);\n        hooks.updateOffset(this, true);\n        return this;\n    } else {\n        return get(this, 'Month');\n    }\n}\n\nexport function getDaysInMonth () {\n    return daysInMonth(this.year(), this.month());\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/units/offset.js",
    "content": "import zeroFill from '../utils/zero-fill';\nimport { createDuration } from '../duration/create';\nimport { addSubtract } from '../moment/add-subtract';\nimport { isMoment } from '../moment/constructor';\nimport { addFormatToken } from '../format/format';\nimport { addRegexToken, matchOffset } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { createLocal } from '../create/local';\nimport { createUTC } from '../create/utc';\nimport isDate from '../utils/is-date';\nimport toInt from '../utils/to-int';\nimport compareArrays from '../utils/compare-arrays';\nimport { hooks } from '../utils/hooks';\n\nfunction offset (token, separator) {\n    addFormatToken(token, 0, 0, function () {\n        var offset = this.utcOffset();\n        var sign = '+';\n        if (offset < 0) {\n            offset = -offset;\n            sign = '-';\n        }\n        return sign + zeroFill(~~(offset / 60), 2) + separator + zeroFill(~~(offset) % 60, 2);\n    });\n}\n\noffset('Z', ':');\noffset('ZZ', '');\n\naddRegexToken('Z',  matchOffset);\naddRegexToken('ZZ', matchOffset);\naddParseToken(['Z', 'ZZ'], function (input, array, config) {\n    config._useUTC = true;\n    config._tzm = offsetFromString(input);\n});\nvar chunkOffset = /([\\+\\-]|\\d\\d)/gi;\n\nfunction offsetFromString(string) {\n    var matches = ((string || '').match(matchOffset) || []);\n    var chunk   = matches[matches.length - 1] || [];\n    var parts   = (chunk + '').match(chunkOffset) || ['-', 0, 0];\n    var minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n    return parts[0] === '+' ? minutes : -minutes;\n}\nexport function cloneWithOffset(input, model) {\n    var res, diff;\n    if (model._isUTC) {\n        res = model.clone();\n        diff = (isMoment(input) || isDate(input) ? +input : +createLocal(input)) - (+res);\n        res._d.setTime(+res._d + diff);\n        hooks.updateOffset(res, false);\n        return res;\n    } else {\n        return createLocal(input).local();\n    }\n    return model._isUTC ? createLocal(input).zone(model._offset || 0) : createLocal(input).local();\n}\n\nfunction getDateOffset (m) {\n    return -Math.round(m._d.getTimezoneOffset() / 15) * 15;\n}\nhooks.updateOffset = function () {};\nexport function getSetOffset (input, keepLocalTime) {\n    var offset = this._offset || 0,\n        localAdjust;\n    if (input != null) {\n        if (typeof input === 'string') {\n            input = offsetFromString(input);\n        }\n        if (Math.abs(input) < 16) {\n            input = input * 60;\n        }\n        if (!this._isUTC && keepLocalTime) {\n            localAdjust = getDateOffset(this);\n        }\n        this._offset = input;\n        this._isUTC = true;\n        if (localAdjust != null) {\n            this.add(localAdjust, 'm');\n        }\n        if (offset !== input) {\n            if (!keepLocalTime || this._changeInProgress) {\n                addSubtract(this, createDuration(input - offset, 'm'), 1, false);\n            } else if (!this._changeInProgress) {\n                this._changeInProgress = true;\n                hooks.updateOffset(this, true);\n                this._changeInProgress = null;\n            }\n        }\n        return this;\n    } else {\n        return this._isUTC ? offset : getDateOffset(this);\n    }\n}\n\nexport function getSetZone (input, keepLocalTime) {\n    if (input != null) {\n        if (typeof input !== 'string') {\n            input = -input;\n        }\n\n        this.utcOffset(input, keepLocalTime);\n\n        return this;\n    } else {\n        return -this.utcOffset();\n    }\n}\n\nexport function setOffsetToUTC (keepLocalTime) {\n    return this.utcOffset(0, keepLocalTime);\n}\n\nexport function setOffsetToLocal (keepLocalTime) {\n    if (this._isUTC) {\n        this.utcOffset(0, keepLocalTime);\n        this._isUTC = false;\n\n        if (keepLocalTime) {\n            this.subtract(getDateOffset(this), 'm');\n        }\n    }\n    return this;\n}\n\nexport function setOffsetToParsedOffset () {\n    if (this._tzm) {\n        this.utcOffset(this._tzm);\n    } else if (typeof this._i === 'string') {\n        this.utcOffset(offsetFromString(this._i));\n    }\n    return this;\n}\n\nexport function hasAlignedHourOffset (input) {\n    if (!input) {\n        input = 0;\n    }\n    else {\n        input = createLocal(input).utcOffset();\n    }\n\n    return (this.utcOffset() - input) % 60 === 0;\n}\n\nexport function isDaylightSavingTime () {\n    return (\n        this.utcOffset() > this.clone().month(0).utcOffset() ||\n        this.utcOffset() > this.clone().month(5).utcOffset()\n    );\n}\n\nexport function isDaylightSavingTimeShifted () {\n    if (this._a) {\n        var other = this._isUTC ? createUTC(this._a) : createLocal(this._a);\n        return this.isValid() && compareArrays(this._a, other.toArray()) > 0;\n    }\n\n    return false;\n}\n\nexport function isLocal () {\n    return !this._isUTC;\n}\n\nexport function isUtcOffset () {\n    return this._isUTC;\n}\n\nexport function isUtc () {\n    return this._isUTC && this._offset === 0;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/units/quarter.js",
    "content": "import { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addRegexToken, match1 } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { MONTH } from './constants';\nimport toInt from '../utils/to-int';\n\naddFormatToken('Q', 0, 0, 'quarter');\n\naddUnitAlias('quarter', 'Q');\n\naddRegexToken('Q', match1);\naddParseToken('Q', function (input, array) {\n    array[MONTH] = (toInt(input) - 1) * 3;\n});\n\nexport function getSetQuarter (input) {\n    return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/units/second.js",
    "content": "import { makeGetSet } from '../moment/get-set';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addRegexToken, match1to2, match2 } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { SECOND } from './constants';\n\naddFormatToken('s', ['ss', 2], 0, 'second');\n\naddUnitAlias('second', 's');\n\naddRegexToken('s',  match1to2);\naddRegexToken('ss', match1to2, match2);\naddParseToken(['s', 'ss'], SECOND);\n\nexport var getSetSecond = makeGetSet('Seconds', false);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/units/timestamp.js",
    "content": "import { addFormatToken } from '../format/format';\nimport { addRegexToken, matchTimestamp, matchSigned } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport toInt from '../utils/to-int';\n\naddFormatToken('X', 0, 0, 'unix');\naddFormatToken('x', 0, 0, 'valueOf');\n\naddRegexToken('x', matchSigned);\naddRegexToken('X', matchTimestamp);\naddParseToken('X', function (input, array, config) {\n    config._d = new Date(parseFloat(input, 10) * 1000);\n});\naddParseToken('x', function (input, array, config) {\n    config._d = new Date(toInt(input));\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/units/timezone.js",
    "content": "import { addFormatToken } from '../format/format';\n\naddFormatToken('z',  0, 0, 'zoneAbbr');\naddFormatToken('zz', 0, 0, 'zoneName');\n\nexport function getZoneAbbr () {\n    return this._isUTC ? 'UTC' : '';\n}\n\nexport function getZoneName () {\n    return this._isUTC ? 'Coordinated Universal Time' : '';\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/units/units.js",
    "content": "import './day-of-month';\nimport './day-of-week';\nimport './day-of-year';\nimport './hour';\nimport './millisecond';\nimport './minute';\nimport './month';\nimport './offset';\nimport './quarter';\nimport './second';\nimport './timestamp';\nimport './timezone';\nimport './week-year';\nimport './week';\nimport './year';\n\nimport { normalizeUnits } from './aliases';\n\nexport { normalizeUnits };\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/units/week-year.js",
    "content": "import { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addRegexToken, match1to2, match1to4, match1to6, match2, match4, match6, matchSigned } from '../parse/regex';\nimport { addWeekParseToken } from '../parse/token';\nimport { weekOfYear } from './week';\nimport toInt from '../utils/to-int';\nimport { hooks } from '../utils/hooks';\nimport { createLocal } from '../create/local';\n\naddFormatToken(0, ['gg', 2], 0, function () {\n    return this.weekYear() % 100;\n});\n\naddFormatToken(0, ['GG', 2], 0, function () {\n    return this.isoWeekYear() % 100;\n});\n\nfunction addWeekYearFormatToken (token, getter) {\n    addFormatToken(0, [token, token.length], 0, getter);\n}\n\naddWeekYearFormatToken('gggg',     'weekYear');\naddWeekYearFormatToken('ggggg',    'weekYear');\naddWeekYearFormatToken('GGGG',  'isoWeekYear');\naddWeekYearFormatToken('GGGGG', 'isoWeekYear');\n\naddUnitAlias('weekYear', 'gg');\naddUnitAlias('isoWeekYear', 'GG');\n\naddRegexToken('G',      matchSigned);\naddRegexToken('g',      matchSigned);\naddRegexToken('GG',     match1to2, match2);\naddRegexToken('gg',     match1to2, match2);\naddRegexToken('GGGG',   match1to4, match4);\naddRegexToken('gggg',   match1to4, match4);\naddRegexToken('GGGGG',  match1to6, match6);\naddRegexToken('ggggg',  match1to6, match6);\n\naddWeekParseToken(['gggg', 'ggggg', 'GGGG', 'GGGGG'], function (input, week, config, token) {\n    week[token.substr(0, 2)] = toInt(input);\n});\n\naddWeekParseToken(['gg', 'GG'], function (input, week, config, token) {\n    week[token] = hooks.parseTwoDigitYear(input);\n});\n\nfunction weeksInYear(year, dow, doy) {\n    return weekOfYear(createLocal([year, 11, 31 + dow - doy]), dow, doy).week;\n}\n\nexport function getSetWeekYear (input) {\n    var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;\n    return input == null ? year : this.add((input - year), 'y');\n}\n\nexport function getSetISOWeekYear (input) {\n    var year = weekOfYear(this, 1, 4).year;\n    return input == null ? year : this.add((input - year), 'y');\n}\n\nexport function getISOWeeksInYear () {\n    return weeksInYear(this.year(), 1, 4);\n}\n\nexport function getWeeksInYear () {\n    var weekInfo = this.localeData()._week;\n    return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/units/week.js",
    "content": "import { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addRegexToken, match1to2, match2 } from '../parse/regex';\nimport { addWeekParseToken } from '../parse/token';\nimport toInt from '../utils/to-int';\nimport { createLocal } from '../create/local';\n\naddFormatToken('w', ['ww', 2], 'wo', 'week');\naddFormatToken('W', ['WW', 2], 'Wo', 'isoWeek');\n\naddUnitAlias('week', 'w');\naddUnitAlias('isoWeek', 'W');\n\naddRegexToken('w',  match1to2);\naddRegexToken('ww', match1to2, match2);\naddRegexToken('W',  match1to2);\naddRegexToken('WW', match1to2, match2);\n\naddWeekParseToken(['w', 'ww', 'W', 'WW'], function (input, week, config, token) {\n    week[token.substr(0, 1)] = toInt(input);\n});\nexport function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {\n    var end = firstDayOfWeekOfYear - firstDayOfWeek,\n        daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),\n        adjustedMoment;\n\n\n    if (daysToDayOfWeek > end) {\n        daysToDayOfWeek -= 7;\n    }\n\n    if (daysToDayOfWeek < end - 7) {\n        daysToDayOfWeek += 7;\n    }\n\n    adjustedMoment = createLocal(mom).add(daysToDayOfWeek, 'd');\n    return {\n        week: Math.ceil(adjustedMoment.dayOfYear() / 7),\n        year: adjustedMoment.year()\n    };\n}\n\nexport function localeWeek (mom) {\n    return weekOfYear(mom, this._week.dow, this._week.doy).week;\n}\n\nexport var defaultLocaleWeek = {\n    dow : 0, // Sunday is the first day of the week.\n    doy : 6  // The week that contains Jan 1st is the first week of the year.\n};\n\nexport function localeFirstDayOfWeek () {\n    return this._week.dow;\n}\n\nexport function localeFirstDayOfYear () {\n    return this._week.doy;\n}\n\nexport function getSetWeek (input) {\n    var week = this.localeData().week(this);\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n\nexport function getSetISOWeek (input) {\n    var week = weekOfYear(this, 1, 4).week;\n    return input == null ? week : this.add((input - week) * 7, 'd');\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/units/year.js",
    "content": "import { makeGetSet } from '../moment/get-set';\nimport { addFormatToken } from '../format/format';\nimport { addUnitAlias } from './aliases';\nimport { addRegexToken, match1to2, match1to4, match1to6, match2, match4, match6, matchSigned } from '../parse/regex';\nimport { addParseToken } from '../parse/token';\nimport { hooks } from '../utils/hooks';\nimport { YEAR } from './constants';\nimport toInt from '../utils/to-int';\n\naddFormatToken(0, ['YY', 2], 0, function () {\n    return this.year() % 100;\n});\n\naddFormatToken(0, ['YYYY',   4],       0, 'year');\naddFormatToken(0, ['YYYYY',  5],       0, 'year');\naddFormatToken(0, ['YYYYYY', 6, true], 0, 'year');\n\naddUnitAlias('year', 'y');\n\naddRegexToken('Y',      matchSigned);\naddRegexToken('YY',     match1to2, match2);\naddRegexToken('YYYY',   match1to4, match4);\naddRegexToken('YYYYY',  match1to6, match6);\naddRegexToken('YYYYYY', match1to6, match6);\n\naddParseToken(['YYYY', 'YYYYY', 'YYYYYY'], YEAR);\naddParseToken('YY', function (input, array) {\n    array[YEAR] = hooks.parseTwoDigitYear(input);\n});\n\nexport function daysInYear(year) {\n    return isLeapYear(year) ? 366 : 365;\n}\n\nfunction isLeapYear(year) {\n    return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n}\n\nhooks.parseTwoDigitYear = function (input) {\n    return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n};\n\nexport var getSetYear = makeGetSet('FullYear', false);\n\nexport function getIsLeapYear () {\n    return isLeapYear(this.year());\n}\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/utils/abs-floor.js",
    "content": "export default function absFloor (number) {\n    if (number < 0) {\n        return Math.ceil(number);\n    } else {\n        return Math.floor(number);\n    }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/utils/compare-arrays.js",
    "content": "import toInt from './to-int';\nexport default function compareArrays(array1, array2, dontConvert) {\n    var len = Math.min(array1.length, array2.length),\n        lengthDiff = Math.abs(array1.length - array2.length),\n        diffs = 0,\n        i;\n    for (i = 0; i < len; i++) {\n        if ((dontConvert && array1[i] !== array2[i]) ||\n            (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n            diffs++;\n        }\n    }\n    return diffs + lengthDiff;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/utils/defaults.js",
    "content": "export default function defaults(a, b, c) {\n    if (a != null) {\n        return a;\n    }\n    if (b != null) {\n        return b;\n    }\n    return c;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/utils/deprecate.js",
    "content": "import extend from './extend';\nimport { hooks } from './hooks';\n\nfunction warn(msg) {\n    if (hooks.suppressDeprecationWarnings === false && typeof console !== 'undefined' && console.warn) {\n        console.warn('Deprecation warning: ' + msg);\n    }\n}\n\nexport function deprecate(msg, fn) {\n    var firstTime = true;\n    return extend(function () {\n        if (firstTime) {\n            warn(msg);\n            firstTime = false;\n        }\n        return fn.apply(this, arguments);\n    }, fn);\n}\n\nvar deprecations = {};\n\nexport function deprecateSimple(name, msg) {\n    if (!deprecations[name]) {\n        warn(msg);\n        deprecations[name] = true;\n    }\n}\n\nhooks.suppressDeprecationWarnings = false;\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/utils/extend.js",
    "content": "import hasOwnProp from './has-own-prop';\n\nexport default function extend(a, b) {\n    for (var i in b) {\n        if (hasOwnProp(b, i)) {\n            a[i] = b[i];\n        }\n    }\n\n    if (hasOwnProp(b, 'toString')) {\n        a.toString = b.toString;\n    }\n\n    if (hasOwnProp(b, 'valueOf')) {\n        a.valueOf = b.valueOf;\n    }\n\n    return a;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/utils/has-own-prop.js",
    "content": "export default function hasOwnProp(a, b) {\n    return Object.prototype.hasOwnProperty.call(a, b);\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/utils/hooks.js",
    "content": "export { hooks, setHookCallback };\n\nvar hookCallback;\n\nfunction hooks () {\n    return hookCallback.apply(null, arguments);\n}\nfunction setHookCallback (callback) {\n    hookCallback = callback;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/utils/is-array.js",
    "content": "export default function isArray(input) {\n    return Object.prototype.toString.call(input) === '[object Array]';\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/utils/is-date.js",
    "content": "export default function isDate(input) {\n    return Object.prototype.toString.call(input) === '[object Date]' || input instanceof Date;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/utils/map.js",
    "content": "export default function map(arr, fn) {\n    var res = [], i;\n    for (i = 0; i < arr.length; ++i) {\n        res.push(fn(arr[i], i));\n    }\n    return res;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/utils/to-int.js",
    "content": "export default function toInt(argumentForCoercion) {\n    var coercedNumber = +argumentForCoercion,\n        value = 0;\n\n    if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n        if (coercedNumber >= 0) {\n            value = Math.floor(coercedNumber);\n        } else {\n            value = Math.ceil(coercedNumber);\n        }\n    }\n\n    return value;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/lib/utils/zero-fill.js",
    "content": "export default function zeroFill(number, targetLength, forceSign) {\n    var output = '' + Math.abs(number),\n        sign = number >= 0;\n\n    while (output.length < targetLength) {\n        output = '0' + output;\n    }\n    return (sign ? (forceSign ? '+' : '') : '-') + output;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/af.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('af', {\n    months : 'Januarie_Februarie_Maart_April_Mei_Junie_Julie_Augustus_September_Oktober_November_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Aug_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Sondag_Maandag_Dinsdag_Woensdag_Donderdag_Vrydag_Saterdag'.split('_'),\n    weekdaysShort : 'Son_Maa_Din_Woe_Don_Vry_Sat'.split('_'),\n    weekdaysMin : 'So_Ma_Di_Wo_Do_Vr_Sa'.split('_'),\n    meridiemParse: /vm|nm/i,\n    isPM : function (input) {\n        return /^nm$/i.test(input);\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower ? 'vm' : 'VM';\n        } else {\n            return isLower ? 'nm' : 'NM';\n        }\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd, D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay : '[Vandag om] LT',\n        nextDay : '[Môre om] LT',\n        nextWeek : 'dddd [om] LT',\n        lastDay : '[Gister om] LT',\n        lastWeek : '[Laas] dddd [om] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'oor %s',\n        past : '%s gelede',\n        s : '\\'n paar sekondes',\n        m : '\\'n minuut',\n        mm : '%d minute',\n        h : '\\'n uur',\n        hh : '%d ure',\n        d : '\\'n dag',\n        dd : '%d dae',\n        M : '\\'n maand',\n        MM : '%d maande',\n        y : '\\'n jaar',\n        yy : '%d jaar'\n    },\n    ordinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de'); // Thanks to Joris Röling : https://github.com/jjupiter\n    },\n    week : {\n        dow : 1, // Maandag is die eerste dag van die week.\n        doy : 4  // Die week wat die 4de Januarie bevat is die eerste week van die jaar.\n    }\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/ar-ma.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('ar-ma', {\n    months : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_ماي_يونيو_يوليوز_غشت_شتنبر_أكتوبر_نونبر_دجنبر'.split('_'),\n    weekdays : 'الأحد_الإتنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'احد_اتنين_ثلاثاء_اربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/ar-sa.js",
    "content": "\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '١',\n    '2': '٢',\n    '3': '٣',\n    '4': '٤',\n    '5': '٥',\n    '6': '٦',\n    '7': '٧',\n    '8': '٨',\n    '9': '٩',\n    '0': '٠'\n}, numberMap = {\n    '١': '1',\n    '٢': '2',\n    '٣': '3',\n    '٤': '4',\n    '٥': '5',\n    '٦': '6',\n    '٧': '7',\n    '٨': '8',\n    '٩': '9',\n    '٠': '0'\n};\n\nexport default moment.defineLocale('ar-sa', {\n    months : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort : 'يناير_فبراير_مارس_أبريل_مايو_يونيو_يوليو_أغسطس_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd D MMMM YYYY LT'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'في %s',\n        past : 'منذ %s',\n        s : 'ثوان',\n        m : 'دقيقة',\n        mm : '%d دقائق',\n        h : 'ساعة',\n        hh : '%d ساعات',\n        d : 'يوم',\n        dd : '%d أيام',\n        M : 'شهر',\n        MM : '%d أشهر',\n        y : 'سنة',\n        yy : '%d سنوات'\n    },\n    preparse: function (string) {\n        return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n            return numberMap[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/ar-tn.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('ar-tn', {\n    months: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    monthsShort: 'جانفي_فيفري_مارس_أفريل_ماي_جوان_جويلية_أوت_سبتمبر_أكتوبر_نوفمبر_ديسمبر'.split('_'),\n    weekdays: 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort: 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin: 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'LT:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY LT',\n        LLLL: 'dddd D MMMM YYYY LT'\n    },\n    calendar: {\n        sameDay: '[اليوم على الساعة] LT',\n        nextDay: '[غدا على الساعة] LT',\n        nextWeek: 'dddd [على الساعة] LT',\n        lastDay: '[أمس على الساعة] LT',\n        lastWeek: 'dddd [على الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'في %s',\n        past: 'منذ %s',\n        s: 'ثوان',\n        m: 'دقيقة',\n        mm: '%d دقائق',\n        h: 'ساعة',\n        hh: '%d ساعات',\n        d: 'يوم',\n        dd: '%d أيام',\n        M: 'شهر',\n        MM: '%d أشهر',\n        y: 'سنة',\n        yy: '%d سنوات'\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/ar.js",
    "content": "\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '١',\n    '2': '٢',\n    '3': '٣',\n    '4': '٤',\n    '5': '٥',\n    '6': '٦',\n    '7': '٧',\n    '8': '٨',\n    '9': '٩',\n    '0': '٠'\n}, numberMap = {\n    '١': '1',\n    '٢': '2',\n    '٣': '3',\n    '٤': '4',\n    '٥': '5',\n    '٦': '6',\n    '٧': '7',\n    '٨': '8',\n    '٩': '9',\n    '٠': '0'\n}, pluralForm = function (n) {\n    return n === 0 ? 0 : n === 1 ? 1 : n === 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5;\n}, plurals = {\n    s : ['أقل من ثانية', 'ثانية واحدة', ['ثانيتان', 'ثانيتين'], '%d ثوان', '%d ثانية', '%d ثانية'],\n    m : ['أقل من دقيقة', 'دقيقة واحدة', ['دقيقتان', 'دقيقتين'], '%d دقائق', '%d دقيقة', '%d دقيقة'],\n    h : ['أقل من ساعة', 'ساعة واحدة', ['ساعتان', 'ساعتين'], '%d ساعات', '%d ساعة', '%d ساعة'],\n    d : ['أقل من يوم', 'يوم واحد', ['يومان', 'يومين'], '%d أيام', '%d يومًا', '%d يوم'],\n    M : ['أقل من شهر', 'شهر واحد', ['شهران', 'شهرين'], '%d أشهر', '%d شهرا', '%d شهر'],\n    y : ['أقل من عام', 'عام واحد', ['عامان', 'عامين'], '%d أعوام', '%d عامًا', '%d عام']\n}, pluralize = function (u) {\n    return function (number, withoutSuffix, string, isFuture) {\n        var f = pluralForm(number),\n            str = plurals[u][pluralForm(number)];\n        if (f === 2) {\n            str = str[withoutSuffix ? 0 : 1];\n        }\n        return str.replace(/%d/i, number);\n    };\n}, months = [\n    'كانون الثاني يناير',\n    'شباط فبراير',\n    'آذار مارس',\n    'نيسان أبريل',\n    'أيار مايو',\n    'حزيران يونيو',\n    'تموز يوليو',\n    'آب أغسطس',\n    'أيلول سبتمبر',\n    'تشرين الأول أكتوبر',\n    'تشرين الثاني نوفمبر',\n    'كانون الأول ديسمبر'\n];\n\nexport default moment.defineLocale('ar', {\n    months : months,\n    monthsShort : months,\n    weekdays : 'الأحد_الإثنين_الثلاثاء_الأربعاء_الخميس_الجمعة_السبت'.split('_'),\n    weekdaysShort : 'أحد_إثنين_ثلاثاء_أربعاء_خميس_جمعة_سبت'.split('_'),\n    weekdaysMin : 'ح_ن_ث_ر_خ_ج_س'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd D MMMM YYYY LT'\n    },\n    meridiemParse: /ص|م/,\n    isPM : function (input) {\n        return 'م' === input;\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ص';\n        } else {\n            return 'م';\n        }\n    },\n    calendar : {\n        sameDay: '[اليوم عند الساعة] LT',\n        nextDay: '[غدًا عند الساعة] LT',\n        nextWeek: 'dddd [عند الساعة] LT',\n        lastDay: '[أمس عند الساعة] LT',\n        lastWeek: 'dddd [عند الساعة] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'بعد %s',\n        past : 'منذ %s',\n        s : pluralize('s'),\n        m : pluralize('m'),\n        mm : pluralize('m'),\n        h : pluralize('h'),\n        hh : pluralize('h'),\n        d : pluralize('d'),\n        dd : pluralize('d'),\n        M : pluralize('M'),\n        MM : pluralize('M'),\n        y : pluralize('y'),\n        yy : pluralize('y')\n    },\n    preparse: function (string) {\n        return string.replace(/[١٢٣٤٥٦٧٨٩٠]/g, function (match) {\n            return numberMap[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/az.js",
    "content": "\nimport moment from '../moment';\n\nvar suffixes = {\n    1: '-inci',\n    5: '-inci',\n    8: '-inci',\n    70: '-inci',\n    80: '-inci',\n    2: '-nci',\n    7: '-nci',\n    20: '-nci',\n    50: '-nci',\n    3: '-üncü',\n    4: '-üncü',\n    100: '-üncü',\n    6: '-ncı',\n    9: '-uncu',\n    10: '-uncu',\n    30: '-uncu',\n    60: '-ıncı',\n    90: '-ıncı'\n};\n\nexport default moment.defineLocale('az', {\n    months : 'yanvar_fevral_mart_aprel_may_iyun_iyul_avqust_sentyabr_oktyabr_noyabr_dekabr'.split('_'),\n    monthsShort : 'yan_fev_mar_apr_may_iyn_iyl_avq_sen_okt_noy_dek'.split('_'),\n    weekdays : 'Bazar_Bazar ertəsi_Çərşənbə axşamı_Çərşənbə_Cümə axşamı_Cümə_Şənbə'.split('_'),\n    weekdaysShort : 'Baz_BzE_ÇAx_Çər_CAx_Cüm_Şən'.split('_'),\n    weekdaysMin : 'Bz_BE_ÇA_Çə_CA_Cü_Şə'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd, D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay : '[bugün saat] LT',\n        nextDay : '[sabah saat] LT',\n        nextWeek : '[gələn həftə] dddd [saat] LT',\n        lastDay : '[dünən] LT',\n        lastWeek : '[keçən həftə] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s sonra',\n        past : '%s əvvəl',\n        s : 'birneçə saniyyə',\n        m : 'bir dəqiqə',\n        mm : '%d dəqiqə',\n        h : 'bir saat',\n        hh : '%d saat',\n        d : 'bir gün',\n        dd : '%d gün',\n        M : 'bir ay',\n        MM : '%d ay',\n        y : 'bir il',\n        yy : '%d il'\n    },\n    meridiemParse: /gecə|səhər|gündüz|axşam/,\n    isPM : function (input) {\n        return /^(gündüz|axşam)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'gecə';\n        } else if (hour < 12) {\n            return 'səhər';\n        } else if (hour < 17) {\n            return 'gündüz';\n        } else {\n            return 'axşam';\n        }\n    },\n    ordinalParse: /\\d{1,2}-(ıncı|inci|nci|üncü|ncı|uncu)/,\n    ordinal : function (number) {\n        if (number === 0) {  // special case for zero\n            return number + '-ıncı';\n        }\n        var a = number % 10,\n            b = number % 100 - a,\n            c = number >= 100 ? 100 : null;\n        return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/be.js",
    "content": "\nimport moment from '../moment';\n\nfunction plural(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'хвіліна_хвіліны_хвілін' : 'хвіліну_хвіліны_хвілін',\n        'hh': withoutSuffix ? 'гадзіна_гадзіны_гадзін' : 'гадзіну_гадзіны_гадзін',\n        'dd': 'дзень_дні_дзён',\n        'MM': 'месяц_месяцы_месяцаў',\n        'yy': 'год_гады_гадоў'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'хвіліна' : 'хвіліну';\n    }\n    else if (key === 'h') {\n        return withoutSuffix ? 'гадзіна' : 'гадзіну';\n    }\n    else {\n        return number + ' ' + plural(format[key], +number);\n    }\n}\nfunction monthsCaseReplace(m, format) {\n    var months = {\n        'nominative': 'студзень_люты_сакавік_красавік_травень_чэрвень_ліпень_жнівень_верасень_кастрычнік_лістапад_снежань'.split('_'),\n        'accusative': 'студзеня_лютага_сакавіка_красавіка_траўня_чэрвеня_ліпеня_жніўня_верасня_кастрычніка_лістапада_снежня'.split('_')\n    },\n    nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n        'accusative' :\n        'nominative';\n    return months[nounCase][m.month()];\n}\nfunction weekdaysCaseReplace(m, format) {\n    var weekdays = {\n        'nominative': 'нядзеля_панядзелак_аўторак_серада_чацвер_пятніца_субота'.split('_'),\n        'accusative': 'нядзелю_панядзелак_аўторак_сераду_чацвер_пятніцу_суботу'.split('_')\n    },\n    nounCase = (/\\[ ?[Вв] ?(?:мінулую|наступную)? ?\\] ?dddd/).test(format) ?\n        'accusative' :\n        'nominative';\n    return weekdays[nounCase][m.day()];\n}\n\nexport default moment.defineLocale('be', {\n    months : monthsCaseReplace,\n    monthsShort : 'студ_лют_сак_крас_трав_чэрв_ліп_жнів_вер_каст_ліст_снеж'.split('_'),\n    weekdays : weekdaysCaseReplace,\n    weekdaysShort : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n    weekdaysMin : 'нд_пн_ат_ср_чц_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY г.',\n        LLL : 'D MMMM YYYY г., LT',\n        LLLL : 'dddd, D MMMM YYYY г., LT'\n    },\n    calendar : {\n        sameDay: '[Сёння ў] LT',\n        nextDay: '[Заўтра ў] LT',\n        lastDay: '[Учора ў] LT',\n        nextWeek: function () {\n            return '[У] dddd [ў] LT';\n        },\n        lastWeek: function () {\n            switch (this.day()) {\n            case 0:\n            case 3:\n            case 5:\n            case 6:\n                return '[У мінулую] dddd [ў] LT';\n            case 1:\n            case 2:\n            case 4:\n                return '[У мінулы] dddd [ў] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'праз %s',\n        past : '%s таму',\n        s : 'некалькі секунд',\n        m : relativeTimeWithPlural,\n        mm : relativeTimeWithPlural,\n        h : relativeTimeWithPlural,\n        hh : relativeTimeWithPlural,\n        d : 'дзень',\n        dd : relativeTimeWithPlural,\n        M : 'месяц',\n        MM : relativeTimeWithPlural,\n        y : 'год',\n        yy : relativeTimeWithPlural\n    },\n    meridiemParse: /ночы|раніцы|дня|вечара/,\n    isPM : function (input) {\n        return /^(дня|вечара)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночы';\n        } else if (hour < 12) {\n            return 'раніцы';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечара';\n        }\n    },\n    ordinalParse: /\\d{1,2}-(і|ы|га)/,\n    ordinal: function (number, period) {\n        switch (period) {\n        case 'M':\n        case 'd':\n        case 'DDD':\n        case 'w':\n        case 'W':\n            return (number % 10 === 2 || number % 10 === 3) && (number % 100 !== 12 && number % 100 !== 13) ? number + '-і' : number + '-ы';\n        case 'D':\n            return number + '-га';\n        default:\n            return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/bg.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('bg', {\n    months : 'януари_февруари_март_април_май_юни_юли_август_септември_октомври_ноември_декември'.split('_'),\n    monthsShort : 'янр_фев_мар_апр_май_юни_юли_авг_сеп_окт_ное_дек'.split('_'),\n    weekdays : 'неделя_понеделник_вторник_сряда_четвъртък_петък_събота'.split('_'),\n    weekdaysShort : 'нед_пон_вто_сря_чет_пет_съб'.split('_'),\n    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'LT:ss',\n        L : 'D.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd, D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay : '[Днес в] LT',\n        nextDay : '[Утре в] LT',\n        nextWeek : 'dddd [в] LT',\n        lastDay : '[Вчера в] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n            case 0:\n            case 3:\n            case 6:\n                return '[В изминалата] dddd [в] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[В изминалия] dddd [в] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'след %s',\n        past : 'преди %s',\n        s : 'няколко секунди',\n        m : 'минута',\n        mm : '%d минути',\n        h : 'час',\n        hh : '%d часа',\n        d : 'ден',\n        dd : '%d дни',\n        M : 'месец',\n        MM : '%d месеца',\n        y : 'година',\n        yy : '%d години'\n    },\n    ordinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n    ordinal : function (number) {\n        var lastDigit = number % 10,\n            last2Digits = number % 100;\n        if (number === 0) {\n            return number + '-ев';\n        } else if (last2Digits === 0) {\n            return number + '-ен';\n        } else if (last2Digits > 10 && last2Digits < 20) {\n            return number + '-ти';\n        } else if (lastDigit === 1) {\n            return number + '-ви';\n        } else if (lastDigit === 2) {\n            return number + '-ри';\n        } else if (lastDigit === 7 || lastDigit === 8) {\n            return number + '-ми';\n        } else {\n            return number + '-ти';\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/bn.js",
    "content": "\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '১',\n    '2': '২',\n    '3': '৩',\n    '4': '৪',\n    '5': '৫',\n    '6': '৬',\n    '7': '৭',\n    '8': '৮',\n    '9': '৯',\n    '0': '০'\n},\nnumberMap = {\n    '১': '1',\n    '২': '2',\n    '৩': '3',\n    '৪': '4',\n    '৫': '5',\n    '৬': '6',\n    '৭': '7',\n    '৮': '8',\n    '৯': '9',\n    '০': '0'\n};\n\nexport default moment.defineLocale('bn', {\n    months : 'জানুয়ারী_ফেবুয়ারী_মার্চ_এপ্রিল_মে_জুন_জুলাই_অগাস্ট_সেপ্টেম্বর_অক্টোবর_নভেম্বর_ডিসেম্বর'.split('_'),\n    monthsShort : 'জানু_ফেব_মার্চ_এপর_মে_জুন_জুল_অগ_সেপ্ট_অক্টো_নভ_ডিসেম্'.split('_'),\n    weekdays : 'রবিবার_সোমবার_মঙ্গলবার_বুধবার_বৃহস্পত্তিবার_শুক্রুবার_শনিবার'.split('_'),\n    weekdaysShort : 'রবি_সোম_মঙ্গল_বুধ_বৃহস্পত্তি_শুক্রু_শনি'.split('_'),\n    weekdaysMin : 'রব_সম_মঙ্গ_বু_ব্রিহ_শু_শনি'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm সময়',\n        LTS : 'A h:mm:ss সময়',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, LT',\n        LLLL : 'dddd, D MMMM YYYY, LT'\n    },\n    calendar : {\n        sameDay : '[আজ] LT',\n        nextDay : '[আগামীকাল] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[গতকাল] LT',\n        lastWeek : '[গত] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s পরে',\n        past : '%s আগে',\n        s : 'কএক সেকেন্ড',\n        m : 'এক মিনিট',\n        mm : '%d মিনিট',\n        h : 'এক ঘন্টা',\n        hh : '%d ঘন্টা',\n        d : 'এক দিন',\n        dd : '%d দিন',\n        M : 'এক মাস',\n        MM : '%d মাস',\n        y : 'এক বছর',\n        yy : '%d বছর'\n    },\n    preparse: function (string) {\n        return string.replace(/[১২৩৪৫৬৭৮৯০]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /রাত|শকাল|দুপুর|বিকেল|রাত/,\n    isPM: function (input) {\n        return /^(দুপুর|বিকেল|রাত)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'রাত';\n        } else if (hour < 10) {\n            return 'শকাল';\n        } else if (hour < 17) {\n            return 'দুপুর';\n        } else if (hour < 20) {\n            return 'বিকেল';\n        } else {\n            return 'রাত';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/bo.js",
    "content": "\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '༡',\n    '2': '༢',\n    '3': '༣',\n    '4': '༤',\n    '5': '༥',\n    '6': '༦',\n    '7': '༧',\n    '8': '༨',\n    '9': '༩',\n    '0': '༠'\n},\nnumberMap = {\n    '༡': '1',\n    '༢': '2',\n    '༣': '3',\n    '༤': '4',\n    '༥': '5',\n    '༦': '6',\n    '༧': '7',\n    '༨': '8',\n    '༩': '9',\n    '༠': '0'\n};\n\nexport default moment.defineLocale('bo', {\n    months : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n    monthsShort : 'ཟླ་བ་དང་པོ_ཟླ་བ་གཉིས་པ_ཟླ་བ་གསུམ་པ_ཟླ་བ་བཞི་པ_ཟླ་བ་ལྔ་པ_ཟླ་བ་དྲུག་པ_ཟླ་བ་བདུན་པ_ཟླ་བ་བརྒྱད་པ_ཟླ་བ་དགུ་པ_ཟླ་བ་བཅུ་པ_ཟླ་བ་བཅུ་གཅིག་པ_ཟླ་བ་བཅུ་གཉིས་པ'.split('_'),\n    weekdays : 'གཟའ་ཉི་མ་_གཟའ་ཟླ་བ་_གཟའ་མིག་དམར་_གཟའ་ལྷག་པ་_གཟའ་ཕུར་བུ_གཟའ་པ་སངས་_གཟའ་སྤེན་པ་'.split('_'),\n    weekdaysShort : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n    weekdaysMin : 'ཉི་མ་_ཟླ་བ་_མིག་དམར་_ལྷག་པ་_ཕུར་བུ_པ་སངས་_སྤེན་པ་'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, LT',\n        LLLL : 'dddd, D MMMM YYYY, LT'\n    },\n    calendar : {\n        sameDay : '[དི་རིང] LT',\n        nextDay : '[སང་ཉིན] LT',\n        nextWeek : '[བདུན་ཕྲག་རྗེས་མ], LT',\n        lastDay : '[ཁ་སང] LT',\n        lastWeek : '[བདུན་ཕྲག་མཐའ་མ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s ལ་',\n        past : '%s སྔན་ལ',\n        s : 'ལམ་སང',\n        m : 'སྐར་མ་གཅིག',\n        mm : '%d སྐར་མ',\n        h : 'ཆུ་ཚོད་གཅིག',\n        hh : '%d ཆུ་ཚོད',\n        d : 'ཉིན་གཅིག',\n        dd : '%d ཉིན་',\n        M : 'ཟླ་བ་གཅིག',\n        MM : '%d ཟླ་བ',\n        y : 'ལོ་གཅིག',\n        yy : '%d ལོ'\n    },\n    preparse: function (string) {\n        return string.replace(/[༡༢༣༤༥༦༧༨༩༠]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /མཚན་མོ|ཞོགས་ཀས|ཉིན་གུང|དགོང་དག|མཚན་མོ/,\n    isPM: function (input) {\n        return /^(ཉིན་གུང|དགོང་དག|མཚན་མོ)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'མཚན་མོ';\n        } else if (hour < 10) {\n            return 'ཞོགས་ཀས';\n        } else if (hour < 17) {\n            return 'ཉིན་གུང';\n        } else if (hour < 20) {\n            return 'དགོང་དག';\n        } else {\n            return 'མཚན་མོ';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/br.js",
    "content": "\nimport moment from '../moment';\n\nfunction relativeTimeWithMutation(number, withoutSuffix, key) {\n    var format = {\n        'mm': 'munutenn',\n        'MM': 'miz',\n        'dd': 'devezh'\n    };\n    return number + ' ' + mutation(format[key], number);\n}\nfunction specialMutationForYears(number) {\n    switch (lastNumber(number)) {\n    case 1:\n    case 3:\n    case 4:\n    case 5:\n    case 9:\n        return number + ' bloaz';\n    default:\n        return number + ' vloaz';\n    }\n}\nfunction lastNumber(number) {\n    if (number > 9) {\n        return lastNumber(number % 10);\n    }\n    return number;\n}\nfunction mutation(text, number) {\n    if (number === 2) {\n        return softMutation(text);\n    }\n    return text;\n}\nfunction softMutation(text) {\n    var mutationTable = {\n        'm': 'v',\n        'b': 'v',\n        'd': 'z'\n    };\n    if (mutationTable[text.charAt(0)] === undefined) {\n        return text;\n    }\n    return mutationTable[text.charAt(0)] + text.substring(1);\n}\n\nexport default moment.defineLocale('br', {\n    months : 'Genver_C\\'hwevrer_Meurzh_Ebrel_Mae_Mezheven_Gouere_Eost_Gwengolo_Here_Du_Kerzu'.split('_'),\n    monthsShort : 'Gen_C\\'hwe_Meu_Ebr_Mae_Eve_Gou_Eos_Gwe_Her_Du_Ker'.split('_'),\n    weekdays : 'Sul_Lun_Meurzh_Merc\\'her_Yaou_Gwener_Sadorn'.split('_'),\n    weekdaysShort : 'Sul_Lun_Meu_Mer_Yao_Gwe_Sad'.split('_'),\n    weekdaysMin : 'Su_Lu_Me_Mer_Ya_Gw_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h[e]mm A',\n        LTS : 'h[e]mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D [a viz] MMMM YYYY',\n        LLL : 'D [a viz] MMMM YYYY LT',\n        LLLL : 'dddd, D [a viz] MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay : '[Hiziv da] LT',\n        nextDay : '[Warc\\'hoazh da] LT',\n        nextWeek : 'dddd [da] LT',\n        lastDay : '[Dec\\'h da] LT',\n        lastWeek : 'dddd [paset da] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'a-benn %s',\n        past : '%s \\'zo',\n        s : 'un nebeud segondennoù',\n        m : 'ur vunutenn',\n        mm : relativeTimeWithMutation,\n        h : 'un eur',\n        hh : '%d eur',\n        d : 'un devezh',\n        dd : relativeTimeWithMutation,\n        M : 'ur miz',\n        MM : relativeTimeWithMutation,\n        y : 'ur bloaz',\n        yy : specialMutationForYears\n    },\n    ordinalParse: /\\d{1,2}(añ|vet)/,\n    ordinal : function (number) {\n        var output = (number === 1) ? 'añ' : 'vet';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/bs.js",
    "content": "\nimport moment from '../moment';\n\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n    case 'm':\n        return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n    case 'mm':\n        if (number === 1) {\n            result += 'minuta';\n        } else if (number === 2 || number === 3 || number === 4) {\n            result += 'minute';\n        } else {\n            result += 'minuta';\n        }\n        return result;\n    case 'h':\n        return withoutSuffix ? 'jedan sat' : 'jednog sata';\n    case 'hh':\n        if (number === 1) {\n            result += 'sat';\n        } else if (number === 2 || number === 3 || number === 4) {\n            result += 'sata';\n        } else {\n            result += 'sati';\n        }\n        return result;\n    case 'dd':\n        if (number === 1) {\n            result += 'dan';\n        } else {\n            result += 'dana';\n        }\n        return result;\n    case 'MM':\n        if (number === 1) {\n            result += 'mjesec';\n        } else if (number === 2 || number === 3 || number === 4) {\n            result += 'mjeseca';\n        } else {\n            result += 'mjeseci';\n        }\n        return result;\n    case 'yy':\n        if (number === 1) {\n            result += 'godina';\n        } else if (number === 2 || number === 3 || number === 4) {\n            result += 'godine';\n        } else {\n            result += 'godina';\n        }\n        return result;\n    }\n}\n\nexport default moment.defineLocale('bs', {\n    months : 'januar_februar_mart_april_maj_juni_juli_august_septembar_oktobar_novembar_decembar'.split('_'),\n    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'LT:ss',\n        L : 'DD. MM. YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY LT',\n        LLLL : 'dddd, D. MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay  : '[danas u] LT',\n        nextDay  : '[sutra u] LT',\n        nextWeek : function () {\n            switch (this.day()) {\n            case 0:\n                return '[u] [nedjelju] [u] LT';\n            case 3:\n                return '[u] [srijedu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[jučer u] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n            case 0:\n            case 3:\n                return '[prošlu] dddd [u] LT';\n            case 6:\n                return '[prošle] [subote] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[prošli] dddd [u] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'par sekundi',\n        m      : translate,\n        mm     : translate,\n        h      : translate,\n        hh     : translate,\n        d      : 'dan',\n        dd     : translate,\n        M      : 'mjesec',\n        MM     : translate,\n        y      : 'godinu',\n        yy     : translate\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/ca.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('ca', {\n    months : 'gener_febrer_març_abril_maig_juny_juliol_agost_setembre_octubre_novembre_desembre'.split('_'),\n    monthsShort : 'gen._febr._mar._abr._mai._jun._jul._ag._set._oct._nov._des.'.split('_'),\n    weekdays : 'diumenge_dilluns_dimarts_dimecres_dijous_divendres_dissabte'.split('_'),\n    weekdaysShort : 'dg._dl._dt._dc._dj._dv._ds.'.split('_'),\n    weekdaysMin : 'Dg_Dl_Dt_Dc_Dj_Dv_Ds'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[avui a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        nextDay : function () {\n            return '[demà a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        lastDay : function () {\n            return '[ahir a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [passat a ' + ((this.hours() !== 1) ? 'les' : 'la') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'en %s',\n        past : 'fa %s',\n        s : 'uns segons',\n        m : 'un minut',\n        mm : '%d minuts',\n        h : 'una hora',\n        hh : '%d hores',\n        d : 'un dia',\n        dd : '%d dies',\n        M : 'un mes',\n        MM : '%d mesos',\n        y : 'un any',\n        yy : '%d anys'\n    },\n    ordinalParse: /\\d{1,2}(r|n|t|è|a)/,\n    ordinal : function (number, period) {\n        var output = (number === 1) ? 'r' :\n            (number === 2) ? 'n' :\n            (number === 3) ? 'r' :\n            (number === 4) ? 't' : 'è';\n        if (period === 'w' || period === 'W') {\n            output = 'a';\n        }\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/cs.js",
    "content": "\nimport moment from '../moment';\n\nvar months = 'leden_únor_březen_duben_květen_červen_červenec_srpen_září_říjen_listopad_prosinec'.split('_'),\n    monthsShort = 'led_úno_bře_dub_kvě_čvn_čvc_srp_zář_říj_lis_pro'.split('_');\nfunction plural(n) {\n    return (n > 1) && (n < 5) && (~~(n / 10) !== 1);\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n    case 's':  // a few seconds / in a few seconds / a few seconds ago\n        return (withoutSuffix || isFuture) ? 'pár sekund' : 'pár sekundami';\n    case 'm':  // a minute / in a minute / a minute ago\n        return withoutSuffix ? 'minuta' : (isFuture ? 'minutu' : 'minutou');\n    case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n        if (withoutSuffix || isFuture) {\n            return result + (plural(number) ? 'minuty' : 'minut');\n        } else {\n            return result + 'minutami';\n        }\n        break;\n    case 'h':  // an hour / in an hour / an hour ago\n        return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n    case 'hh': // 9 hours / in 9 hours / 9 hours ago\n        if (withoutSuffix || isFuture) {\n            return result + (plural(number) ? 'hodiny' : 'hodin');\n        } else {\n            return result + 'hodinami';\n        }\n        break;\n    case 'd':  // a day / in a day / a day ago\n        return (withoutSuffix || isFuture) ? 'den' : 'dnem';\n    case 'dd': // 9 days / in 9 days / 9 days ago\n        if (withoutSuffix || isFuture) {\n            return result + (plural(number) ? 'dny' : 'dní');\n        } else {\n            return result + 'dny';\n        }\n        break;\n    case 'M':  // a month / in a month / a month ago\n        return (withoutSuffix || isFuture) ? 'měsíc' : 'měsícem';\n    case 'MM': // 9 months / in 9 months / 9 months ago\n        if (withoutSuffix || isFuture) {\n            return result + (plural(number) ? 'měsíce' : 'měsíců');\n        } else {\n            return result + 'měsíci';\n        }\n        break;\n    case 'y':  // a year / in a year / a year ago\n        return (withoutSuffix || isFuture) ? 'rok' : 'rokem';\n    case 'yy': // 9 years / in 9 years / 9 years ago\n        if (withoutSuffix || isFuture) {\n            return result + (plural(number) ? 'roky' : 'let');\n        } else {\n            return result + 'lety';\n        }\n        break;\n    }\n}\n\nexport default moment.defineLocale('cs', {\n    months : months,\n    monthsShort : monthsShort,\n    monthsParse : (function (months, monthsShort) {\n        var i, _monthsParse = [];\n        for (i = 0; i < 12; i++) {\n            _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');\n        }\n        return _monthsParse;\n    }(months, monthsShort)),\n    weekdays : 'neděle_pondělí_úterý_středa_čtvrtek_pátek_sobota'.split('_'),\n    weekdaysShort : 'ne_po_út_st_čt_pá_so'.split('_'),\n    weekdaysMin : 'ne_po_út_st_čt_pá_so'.split('_'),\n    longDateFormat : {\n        LT: 'H:mm',\n        LTS : 'LT:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY LT',\n        LLLL : 'dddd D. MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay: '[dnes v] LT',\n        nextDay: '[zítra v] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n            case 0:\n                return '[v neděli v] LT';\n            case 1:\n            case 2:\n                return '[v] dddd [v] LT';\n            case 3:\n                return '[ve středu v] LT';\n            case 4:\n                return '[ve čtvrtek v] LT';\n            case 5:\n                return '[v pátek v] LT';\n            case 6:\n                return '[v sobotu v] LT';\n            }\n        },\n        lastDay: '[včera v] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n            case 0:\n                return '[minulou neděli v] LT';\n            case 1:\n            case 2:\n                return '[minulé] dddd [v] LT';\n            case 3:\n                return '[minulou středu v] LT';\n            case 4:\n            case 5:\n                return '[minulý] dddd [v] LT';\n            case 6:\n                return '[minulou sobotu v] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : 'před %s',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    ordinalParse : /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/cv.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('cv', {\n    months : 'кăрлач_нарăс_пуш_ака_май_çĕртме_утă_çурла_авăн_юпа_чӳк_раштав'.split('_'),\n    monthsShort : 'кăр_нар_пуш_ака_май_çĕр_утă_çур_ав_юпа_чӳк_раш'.split('_'),\n    weekdays : 'вырсарникун_тунтикун_ытларикун_юнкун_кĕçнерникун_эрнекун_шăматкун'.split('_'),\n    weekdaysShort : 'выр_тун_ытл_юн_кĕç_эрн_шăм'.split('_'),\n    weekdaysMin : 'вр_тн_ыт_юн_кç_эр_шм'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ]',\n        LLL : 'YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT',\n        LLLL : 'dddd, YYYY [çулхи] MMMM [уйăхĕн] D[-мĕшĕ], LT'\n    },\n    calendar : {\n        sameDay: '[Паян] LT [сехетре]',\n        nextDay: '[Ыран] LT [сехетре]',\n        lastDay: '[Ĕнер] LT [сехетре]',\n        nextWeek: '[Çитес] dddd LT [сехетре]',\n        lastWeek: '[Иртнĕ] dddd LT [сехетре]',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : function (output) {\n            var affix = /сехет$/i.exec(output) ? 'рен' : /çул$/i.exec(output) ? 'тан' : 'ран';\n            return output + affix;\n        },\n        past : '%s каялла',\n        s : 'пĕр-ик çеккунт',\n        m : 'пĕр минут',\n        mm : '%d минут',\n        h : 'пĕр сехет',\n        hh : '%d сехет',\n        d : 'пĕр кун',\n        dd : '%d кун',\n        M : 'пĕр уйăх',\n        MM : '%d уйăх',\n        y : 'пĕр çул',\n        yy : '%d çул'\n    },\n    ordinalParse: /\\d{1,2}-мĕш/,\n    ordinal : '%d-мĕш',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/cy.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('cy', {\n    months: 'Ionawr_Chwefror_Mawrth_Ebrill_Mai_Mehefin_Gorffennaf_Awst_Medi_Hydref_Tachwedd_Rhagfyr'.split('_'),\n    monthsShort: 'Ion_Chwe_Maw_Ebr_Mai_Meh_Gor_Aws_Med_Hyd_Tach_Rhag'.split('_'),\n    weekdays: 'Dydd Sul_Dydd Llun_Dydd Mawrth_Dydd Mercher_Dydd Iau_Dydd Gwener_Dydd Sadwrn'.split('_'),\n    weekdaysShort: 'Sul_Llun_Maw_Mer_Iau_Gwe_Sad'.split('_'),\n    weekdaysMin: 'Su_Ll_Ma_Me_Ia_Gw_Sa'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS : 'LT:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY LT',\n        LLLL: 'dddd, D MMMM YYYY LT'\n    },\n    calendar: {\n        sameDay: '[Heddiw am] LT',\n        nextDay: '[Yfory am] LT',\n        nextWeek: 'dddd [am] LT',\n        lastDay: '[Ddoe am] LT',\n        lastWeek: 'dddd [diwethaf am] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'mewn %s',\n        past: '%s yn ôl',\n        s: 'ychydig eiliadau',\n        m: 'munud',\n        mm: '%d munud',\n        h: 'awr',\n        hh: '%d awr',\n        d: 'diwrnod',\n        dd: '%d diwrnod',\n        M: 'mis',\n        MM: '%d mis',\n        y: 'blwyddyn',\n        yy: '%d flynedd'\n    },\n    ordinalParse: /\\d{1,2}(fed|ain|af|il|ydd|ed|eg)/,\n    ordinal: function (number) {\n        var b = number,\n            output = '',\n            lookup = [\n                '', 'af', 'il', 'ydd', 'ydd', 'ed', 'ed', 'ed', 'fed', 'fed', 'fed', // 1af to 10fed\n                'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'eg', 'fed', 'eg', 'fed' // 11eg to 20fed\n            ];\n        if (b > 20) {\n            if (b === 40 || b === 50 || b === 60 || b === 80 || b === 100) {\n                output = 'fed'; // not 30ain, 70ain or 90ain\n            } else {\n                output = 'ain';\n            }\n        } else if (b > 0) {\n            output = lookup[b];\n        }\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/da.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('da', {\n    months : 'januar_februar_marts_april_maj_juni_juli_august_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n    weekdaysShort : 'søn_man_tir_ons_tor_fre_lør'.split('_'),\n    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY LT',\n        LLLL : 'dddd [d.] D. MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay : '[I dag kl.] LT',\n        nextDay : '[I morgen kl.] LT',\n        nextWeek : 'dddd [kl.] LT',\n        lastDay : '[I går kl.] LT',\n        lastWeek : '[sidste] dddd [kl] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : '%s siden',\n        s : 'få sekunder',\n        m : 'et minut',\n        mm : '%d minutter',\n        h : 'en time',\n        hh : '%d timer',\n        d : 'en dag',\n        dd : '%d dage',\n        M : 'en måned',\n        MM : '%d måneder',\n        y : 'et år',\n        yy : '%d år'\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/de-at.js",
    "content": "\nimport moment from '../moment';\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nexport default moment.defineLocale('de-at', {\n    months : 'Jänner_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jän._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY LT',\n        LLLL : 'dddd, D. MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay: '[Heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[Morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[Gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime,\n        mm : '%d Minuten',\n        h : processRelativeTime,\n        hh : '%d Stunden',\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/de.js",
    "content": "\nimport moment from '../moment';\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eine Minute', 'einer Minute'],\n        'h': ['eine Stunde', 'einer Stunde'],\n        'd': ['ein Tag', 'einem Tag'],\n        'dd': [number + ' Tage', number + ' Tagen'],\n        'M': ['ein Monat', 'einem Monat'],\n        'MM': [number + ' Monate', number + ' Monaten'],\n        'y': ['ein Jahr', 'einem Jahr'],\n        'yy': [number + ' Jahre', number + ' Jahren']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\n\nexport default moment.defineLocale('de', {\n    months : 'Januar_Februar_März_April_Mai_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort : 'Jan._Febr._Mrz._Apr._Mai_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    weekdays : 'Sonntag_Montag_Dienstag_Mittwoch_Donnerstag_Freitag_Samstag'.split('_'),\n    weekdaysShort : 'So._Mo._Di._Mi._Do._Fr._Sa.'.split('_'),\n    weekdaysMin : 'So_Mo_Di_Mi_Do_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY LT',\n        LLLL : 'dddd, D. MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay: '[Heute um] LT [Uhr]',\n        sameElse: 'L',\n        nextDay: '[Morgen um] LT [Uhr]',\n        nextWeek: 'dddd [um] LT [Uhr]',\n        lastDay: '[Gestern um] LT [Uhr]',\n        lastWeek: '[letzten] dddd [um] LT [Uhr]'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : 'vor %s',\n        s : 'ein paar Sekunden',\n        m : processRelativeTime,\n        mm : '%d Minuten',\n        h : processRelativeTime,\n        hh : '%d Stunden',\n        d : processRelativeTime,\n        dd : processRelativeTime,\n        M : processRelativeTime,\n        MM : processRelativeTime,\n        y : processRelativeTime,\n        yy : processRelativeTime\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/el.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('el', {\n    monthsNominativeEl : 'Ιανουάριος_Φεβρουάριος_Μάρτιος_Απρίλιος_Μάιος_Ιούνιος_Ιούλιος_Αύγουστος_Σεπτέμβριος_Οκτώβριος_Νοέμβριος_Δεκέμβριος'.split('_'),\n    monthsGenitiveEl : 'Ιανουαρίου_Φεβρουαρίου_Μαρτίου_Απριλίου_Μαΐου_Ιουνίου_Ιουλίου_Αυγούστου_Σεπτεμβρίου_Οκτωβρίου_Νοεμβρίου_Δεκεμβρίου'.split('_'),\n    months : function (momentToFormat, format) {\n        if (/D/.test(format.substring(0, format.indexOf('MMMM')))) { // if there is a day number before 'MMMM'\n            return this._monthsGenitiveEl[momentToFormat.month()];\n        } else {\n            return this._monthsNominativeEl[momentToFormat.month()];\n        }\n    },\n    monthsShort : 'Ιαν_Φεβ_Μαρ_Απρ_Μαϊ_Ιουν_Ιουλ_Αυγ_Σεπ_Οκτ_Νοε_Δεκ'.split('_'),\n    weekdays : 'Κυριακή_Δευτέρα_Τρίτη_Τετάρτη_Πέμπτη_Παρασκευή_Σάββατο'.split('_'),\n    weekdaysShort : 'Κυρ_Δευ_Τρι_Τετ_Πεμ_Παρ_Σαβ'.split('_'),\n    weekdaysMin : 'Κυ_Δε_Τρ_Τε_Πε_Πα_Σα'.split('_'),\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'μμ' : 'ΜΜ';\n        } else {\n            return isLower ? 'πμ' : 'ΠΜ';\n        }\n    },\n    isPM : function (input) {\n        return ((input + '').toLowerCase()[0] === 'μ');\n    },\n    meridiemParse : /[ΠΜ]\\.?Μ?\\.?/i,\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd, D MMMM YYYY LT'\n    },\n    calendarEl : {\n        sameDay : '[Σήμερα {}] LT',\n        nextDay : '[Αύριο {}] LT',\n        nextWeek : 'dddd [{}] LT',\n        lastDay : '[Χθες {}] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n                case 6:\n                    return '[το προηγούμενο] dddd [{}] LT';\n                default:\n                    return '[την προηγούμενη] dddd [{}] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    calendar : function (key, mom) {\n        var output = this._calendarEl[key],\n            hours = mom && mom.hours();\n        if (typeof output === 'function') {\n            output = output.apply(mom);\n        }\n        return output.replace('{}', (hours % 12 === 1 ? 'στη' : 'στις'));\n    },\n    relativeTime : {\n        future : 'σε %s',\n        past : '%s πριν',\n        s : 'λίγα δευτερόλεπτα',\n        m : 'ένα λεπτό',\n        mm : '%d λεπτά',\n        h : 'μία ώρα',\n        hh : '%d ώρες',\n        d : 'μία μέρα',\n        dd : '%d μέρες',\n        M : 'ένας μήνας',\n        MM : '%d μήνες',\n        y : 'ένας χρόνος',\n        yy : '%d χρόνια'\n    },\n    ordinalParse: /\\d{1,2}η/,\n    ordinal: '%dη',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/en-au.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('en-au', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd, D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    ordinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/en-ca.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('en-ca', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'YYYY-MM-DD',\n        LL : 'D MMMM, YYYY',\n        LLL : 'D MMMM, YYYY LT',\n        LLLL : 'dddd, D MMMM, YYYY LT'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    ordinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/en-gb.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('en-gb', {\n    months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n    weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n    weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n    weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'HH:mm:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd, D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay : '[Today at] LT',\n        nextDay : '[Tomorrow at] LT',\n        nextWeek : 'dddd [at] LT',\n        lastDay : '[Yesterday at] LT',\n        lastWeek : '[Last] dddd [at] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'in %s',\n        past : '%s ago',\n        s : 'a few seconds',\n        m : 'a minute',\n        mm : '%d minutes',\n        h : 'an hour',\n        hh : '%d hours',\n        d : 'a day',\n        dd : '%d days',\n        M : 'a month',\n        MM : '%d months',\n        y : 'a year',\n        yy : '%d years'\n    },\n    ordinalParse: /\\d{1,2}(st|nd|rd|th)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'th' :\n            (b === 1) ? 'st' :\n            (b === 2) ? 'nd' :\n            (b === 3) ? 'rd' : 'th';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/eo.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('eo', {\n    months : 'januaro_februaro_marto_aprilo_majo_junio_julio_aŭgusto_septembro_oktobro_novembro_decembro'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aŭg_sep_okt_nov_dec'.split('_'),\n    weekdays : 'Dimanĉo_Lundo_Mardo_Merkredo_Ĵaŭdo_Vendredo_Sabato'.split('_'),\n    weekdaysShort : 'Dim_Lun_Mard_Merk_Ĵaŭ_Ven_Sab'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Ĵa_Ve_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D[-an de] MMMM, YYYY',\n        LLL : 'D[-an de] MMMM, YYYY LT',\n        LLLL : 'dddd, [la] D[-an de] MMMM, YYYY LT'\n    },\n    meridiemParse: /[ap]\\.t\\.m/i,\n    isPM: function (input) {\n        return input.charAt(0).toLowerCase() === 'p';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours > 11) {\n            return isLower ? 'p.t.m.' : 'P.T.M.';\n        } else {\n            return isLower ? 'a.t.m.' : 'A.T.M.';\n        }\n    },\n    calendar : {\n        sameDay : '[Hodiaŭ je] LT',\n        nextDay : '[Morgaŭ je] LT',\n        nextWeek : 'dddd [je] LT',\n        lastDay : '[Hieraŭ je] LT',\n        lastWeek : '[pasinta] dddd [je] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'je %s',\n        past : 'antaŭ %s',\n        s : 'sekundoj',\n        m : 'minuto',\n        mm : '%d minutoj',\n        h : 'horo',\n        hh : '%d horoj',\n        d : 'tago',//ne 'diurno', ĉar estas uzita por proksimumo\n        dd : '%d tagoj',\n        M : 'monato',\n        MM : '%d monatoj',\n        y : 'jaro',\n        yy : '%d jaroj'\n    },\n    ordinalParse: /\\d{1,2}a/,\n    ordinal : '%da',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/es.js",
    "content": "\nimport moment from '../moment';\n\nvar monthsShortDot = 'ene._feb._mar._abr._may._jun._jul._ago._sep._oct._nov._dic.'.split('_'),\n    monthsShort = 'ene_feb_mar_abr_may_jun_jul_ago_sep_oct_nov_dic'.split('_');\n\nexport default moment.defineLocale('es', {\n    months : 'enero_febrero_marzo_abril_mayo_junio_julio_agosto_septiembre_octubre_noviembre_diciembre'.split('_'),\n    monthsShort : function (m, format) {\n        if (/-MMM-/.test(format)) {\n            return monthsShort[m.month()];\n        } else {\n            return monthsShortDot[m.month()];\n        }\n    },\n    weekdays : 'domingo_lunes_martes_miércoles_jueves_viernes_sábado'.split('_'),\n    weekdaysShort : 'dom._lun._mar._mié._jue._vie._sáb.'.split('_'),\n    weekdaysMin : 'Do_Lu_Ma_Mi_Ju_Vi_Sá'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY LT',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY LT'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoy a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañana a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastDay : function () {\n            return '[ayer a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        lastWeek : function () {\n            return '[el] dddd [pasado a la' + ((this.hours() !== 1) ? 's' : '') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'en %s',\n        past : 'hace %s',\n        s : 'unos segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'una hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un año',\n        yy : '%d años'\n    },\n    ordinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/et.js",
    "content": "\nimport moment from '../moment';\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        's' : ['mõne sekundi', 'mõni sekund', 'paar sekundit'],\n        'm' : ['ühe minuti', 'üks minut'],\n        'mm': [number + ' minuti', number + ' minutit'],\n        'h' : ['ühe tunni', 'tund aega', 'üks tund'],\n        'hh': [number + ' tunni', number + ' tundi'],\n        'd' : ['ühe päeva', 'üks päev'],\n        'M' : ['kuu aja', 'kuu aega', 'üks kuu'],\n        'MM': [number + ' kuu', number + ' kuud'],\n        'y' : ['ühe aasta', 'aasta', 'üks aasta'],\n        'yy': [number + ' aasta', number + ' aastat']\n    };\n    if (withoutSuffix) {\n        return format[key][2] ? format[key][2] : format[key][1];\n    }\n    return isFuture ? format[key][0] : format[key][1];\n}\n\nexport default moment.defineLocale('et', {\n    months        : 'jaanuar_veebruar_märts_aprill_mai_juuni_juuli_august_september_oktoober_november_detsember'.split('_'),\n    monthsShort   : 'jaan_veebr_märts_apr_mai_juuni_juuli_aug_sept_okt_nov_dets'.split('_'),\n    weekdays      : 'pühapäev_esmaspäev_teisipäev_kolmapäev_neljapäev_reede_laupäev'.split('_'),\n    weekdaysShort : 'P_E_T_K_N_R_L'.split('_'),\n    weekdaysMin   : 'P_E_T_K_N_R_L'.split('_'),\n    longDateFormat : {\n        LT   : 'H:mm',\n        LTS : 'LT:ss',\n        L    : 'DD.MM.YYYY',\n        LL   : 'D. MMMM YYYY',\n        LLL  : 'D. MMMM YYYY LT',\n        LLLL : 'dddd, D. MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay  : '[Täna,] LT',\n        nextDay  : '[Homme,] LT',\n        nextWeek : '[Järgmine] dddd LT',\n        lastDay  : '[Eile,] LT',\n        lastWeek : '[Eelmine] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s pärast',\n        past   : '%s tagasi',\n        s      : processRelativeTime,\n        m      : processRelativeTime,\n        mm     : processRelativeTime,\n        h      : processRelativeTime,\n        hh     : processRelativeTime,\n        d      : processRelativeTime,\n        dd     : '%d päeva',\n        M      : processRelativeTime,\n        MM     : processRelativeTime,\n        y      : processRelativeTime,\n        yy     : processRelativeTime\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/eu.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('eu', {\n    months : 'urtarrila_otsaila_martxoa_apirila_maiatza_ekaina_uztaila_abuztua_iraila_urria_azaroa_abendua'.split('_'),\n    monthsShort : 'urt._ots._mar._api._mai._eka._uzt._abu._ira._urr._aza._abe.'.split('_'),\n    weekdays : 'igandea_astelehena_asteartea_asteazkena_osteguna_ostirala_larunbata'.split('_'),\n    weekdaysShort : 'ig._al._ar._az._og._ol._lr.'.split('_'),\n    weekdaysMin : 'ig_al_ar_az_og_ol_lr'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'YYYY[ko] MMMM[ren] D[a]',\n        LLL : 'YYYY[ko] MMMM[ren] D[a] LT',\n        LLLL : 'dddd, YYYY[ko] MMMM[ren] D[a] LT',\n        l : 'YYYY-M-D',\n        ll : 'YYYY[ko] MMM D[a]',\n        lll : 'YYYY[ko] MMM D[a] LT',\n        llll : 'ddd, YYYY[ko] MMM D[a] LT'\n    },\n    calendar : {\n        sameDay : '[gaur] LT[etan]',\n        nextDay : '[bihar] LT[etan]',\n        nextWeek : 'dddd LT[etan]',\n        lastDay : '[atzo] LT[etan]',\n        lastWeek : '[aurreko] dddd LT[etan]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s barru',\n        past : 'duela %s',\n        s : 'segundo batzuk',\n        m : 'minutu bat',\n        mm : '%d minutu',\n        h : 'ordu bat',\n        hh : '%d ordu',\n        d : 'egun bat',\n        dd : '%d egun',\n        M : 'hilabete bat',\n        MM : '%d hilabete',\n        y : 'urte bat',\n        yy : '%d urte'\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/fa.js",
    "content": "\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '۱',\n    '2': '۲',\n    '3': '۳',\n    '4': '۴',\n    '5': '۵',\n    '6': '۶',\n    '7': '۷',\n    '8': '۸',\n    '9': '۹',\n    '0': '۰'\n}, numberMap = {\n    '۱': '1',\n    '۲': '2',\n    '۳': '3',\n    '۴': '4',\n    '۵': '5',\n    '۶': '6',\n    '۷': '7',\n    '۸': '8',\n    '۹': '9',\n    '۰': '0'\n};\n\nexport default moment.defineLocale('fa', {\n    months : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n    monthsShort : 'ژانویه_فوریه_مارس_آوریل_مه_ژوئن_ژوئیه_اوت_سپتامبر_اکتبر_نوامبر_دسامبر'.split('_'),\n    weekdays : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n    weekdaysShort : 'یک\\u200cشنبه_دوشنبه_سه\\u200cشنبه_چهارشنبه_پنج\\u200cشنبه_جمعه_شنبه'.split('_'),\n    weekdaysMin : 'ی_د_س_چ_پ_ج_ش'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd, D MMMM YYYY LT'\n    },\n    meridiemParse: /قبل از ظهر|بعد از ظهر/,\n    isPM: function (input) {\n        return /بعد از ظهر/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'قبل از ظهر';\n        } else {\n            return 'بعد از ظهر';\n        }\n    },\n    calendar : {\n        sameDay : '[امروز ساعت] LT',\n        nextDay : '[فردا ساعت] LT',\n        nextWeek : 'dddd [ساعت] LT',\n        lastDay : '[دیروز ساعت] LT',\n        lastWeek : 'dddd [پیش] [ساعت] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'در %s',\n        past : '%s پیش',\n        s : 'چندین ثانیه',\n        m : 'یک دقیقه',\n        mm : '%d دقیقه',\n        h : 'یک ساعت',\n        hh : '%d ساعت',\n        d : 'یک روز',\n        dd : '%d روز',\n        M : 'یک ماه',\n        MM : '%d ماه',\n        y : 'یک سال',\n        yy : '%d سال'\n    },\n    preparse: function (string) {\n        return string.replace(/[۰-۹]/g, function (match) {\n            return numberMap[match];\n        }).replace(/،/g, ',');\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        }).replace(/,/g, '،');\n    },\n    ordinalParse: /\\d{1,2}م/,\n    ordinal : '%dم',\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12 // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/fi.js",
    "content": "\nimport moment from '../moment';\n\nvar numbersPast = 'nolla yksi kaksi kolme neljä viisi kuusi seitsemän kahdeksan yhdeksän'.split(' '),\n    numbersFuture = [\n        'nolla', 'yhden', 'kahden', 'kolmen', 'neljän', 'viiden', 'kuuden',\n        numbersPast[7], numbersPast[8], numbersPast[9]\n    ];\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = '';\n    switch (key) {\n    case 's':\n        return isFuture ? 'muutaman sekunnin' : 'muutama sekunti';\n    case 'm':\n        return isFuture ? 'minuutin' : 'minuutti';\n    case 'mm':\n        result = isFuture ? 'minuutin' : 'minuuttia';\n        break;\n    case 'h':\n        return isFuture ? 'tunnin' : 'tunti';\n    case 'hh':\n        result = isFuture ? 'tunnin' : 'tuntia';\n        break;\n    case 'd':\n        return isFuture ? 'päivän' : 'päivä';\n    case 'dd':\n        result = isFuture ? 'päivän' : 'päivää';\n        break;\n    case 'M':\n        return isFuture ? 'kuukauden' : 'kuukausi';\n    case 'MM':\n        result = isFuture ? 'kuukauden' : 'kuukautta';\n        break;\n    case 'y':\n        return isFuture ? 'vuoden' : 'vuosi';\n    case 'yy':\n        result = isFuture ? 'vuoden' : 'vuotta';\n        break;\n    }\n    result = verbalNumber(number, isFuture) + ' ' + result;\n    return result;\n}\nfunction verbalNumber(number, isFuture) {\n    return number < 10 ? (isFuture ? numbersFuture[number] : numbersPast[number]) : number;\n}\n\nexport default moment.defineLocale('fi', {\n    months : 'tammikuu_helmikuu_maaliskuu_huhtikuu_toukokuu_kesäkuu_heinäkuu_elokuu_syyskuu_lokakuu_marraskuu_joulukuu'.split('_'),\n    monthsShort : 'tammi_helmi_maalis_huhti_touko_kesä_heinä_elo_syys_loka_marras_joulu'.split('_'),\n    weekdays : 'sunnuntai_maanantai_tiistai_keskiviikko_torstai_perjantai_lauantai'.split('_'),\n    weekdaysShort : 'su_ma_ti_ke_to_pe_la'.split('_'),\n    weekdaysMin : 'su_ma_ti_ke_to_pe_la'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'HH.mm.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'Do MMMM[ta] YYYY',\n        LLL : 'Do MMMM[ta] YYYY, [klo] LT',\n        LLLL : 'dddd, Do MMMM[ta] YYYY, [klo] LT',\n        l : 'D.M.YYYY',\n        ll : 'Do MMM YYYY',\n        lll : 'Do MMM YYYY, [klo] LT',\n        llll : 'ddd, Do MMM YYYY, [klo] LT'\n    },\n    calendar : {\n        sameDay : '[tänään] [klo] LT',\n        nextDay : '[huomenna] [klo] LT',\n        nextWeek : 'dddd [klo] LT',\n        lastDay : '[eilen] [klo] LT',\n        lastWeek : '[viime] dddd[na] [klo] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s päästä',\n        past : '%s sitten',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/fo.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('fo', {\n    months : 'januar_februar_mars_apríl_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n    weekdays : 'sunnudagur_mánadagur_týsdagur_mikudagur_hósdagur_fríggjadagur_leygardagur'.split('_'),\n    weekdaysShort : 'sun_mán_týs_mik_hós_frí_ley'.split('_'),\n    weekdaysMin : 'su_má_tý_mi_hó_fr_le'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd D. MMMM, YYYY LT'\n    },\n    calendar : {\n        sameDay : '[Í dag kl.] LT',\n        nextDay : '[Í morgin kl.] LT',\n        nextWeek : 'dddd [kl.] LT',\n        lastDay : '[Í gjár kl.] LT',\n        lastWeek : '[síðstu] dddd [kl] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'um %s',\n        past : '%s síðani',\n        s : 'fá sekund',\n        m : 'ein minutt',\n        mm : '%d minuttir',\n        h : 'ein tími',\n        hh : '%d tímar',\n        d : 'ein dagur',\n        dd : '%d dagar',\n        M : 'ein mánaði',\n        MM : '%d mánaðir',\n        y : 'eitt ár',\n        yy : '%d ár'\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/fr-ca.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('fr-ca', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay: '[Aujourd\\'hui à] LT',\n        nextDay: '[Demain à] LT',\n        nextWeek: 'dddd [à] LT',\n        lastDay: '[Hier à] LT',\n        lastWeek: 'dddd [dernier à] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    ordinalParse: /\\d{1,2}(er|)/,\n    ordinal : function (number) {\n        return number + (number === 1 ? 'er' : '');\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/fr.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('fr', {\n    months : 'janvier_février_mars_avril_mai_juin_juillet_août_septembre_octobre_novembre_décembre'.split('_'),\n    monthsShort : 'janv._févr._mars_avr._mai_juin_juil._août_sept._oct._nov._déc.'.split('_'),\n    weekdays : 'dimanche_lundi_mardi_mercredi_jeudi_vendredi_samedi'.split('_'),\n    weekdaysShort : 'dim._lun._mar._mer._jeu._ven._sam.'.split('_'),\n    weekdaysMin : 'Di_Lu_Ma_Me_Je_Ve_Sa'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay: '[Aujourd\\'hui à] LT',\n        nextDay: '[Demain à] LT',\n        nextWeek: 'dddd [à] LT',\n        lastDay: '[Hier à] LT',\n        lastWeek: 'dddd [dernier à] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'dans %s',\n        past : 'il y a %s',\n        s : 'quelques secondes',\n        m : 'une minute',\n        mm : '%d minutes',\n        h : 'une heure',\n        hh : '%d heures',\n        d : 'un jour',\n        dd : '%d jours',\n        M : 'un mois',\n        MM : '%d mois',\n        y : 'un an',\n        yy : '%d ans'\n    },\n    ordinalParse: /\\d{1,2}(er|)/,\n    ordinal : function (number) {\n        return number + (number === 1 ? 'er' : '');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/fy.js",
    "content": "\nimport moment from '../moment';\n\nvar monthsShortWithDots = 'jan._feb._mrt._apr._mai_jun._jul._aug._sep._okt._nov._des.'.split('_'),\n    monthsShortWithoutDots = 'jan_feb_mrt_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_');\n\nexport default moment.defineLocale('fy', {\n    months : 'jannewaris_febrewaris_maart_april_maaie_juny_july_augustus_septimber_oktober_novimber_desimber'.split('_'),\n    monthsShort : function (m, format) {\n        if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots[m.month()];\n        } else {\n            return monthsShortWithDots[m.month()];\n        }\n    },\n    weekdays : 'snein_moandei_tiisdei_woansdei_tongersdei_freed_sneon'.split('_'),\n    weekdaysShort : 'si._mo._ti._wo._to._fr._so.'.split('_'),\n    weekdaysMin : 'Si_Mo_Ti_Wo_To_Fr_So'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay: '[hjoed om] LT',\n        nextDay: '[moarn om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[juster om] LT',\n        lastWeek: '[ôfrûne] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'oer %s',\n        past : '%s lyn',\n        s : 'in pear sekonden',\n        m : 'ien minút',\n        mm : '%d minuten',\n        h : 'ien oere',\n        hh : '%d oeren',\n        d : 'ien dei',\n        dd : '%d dagen',\n        M : 'ien moanne',\n        MM : '%d moannen',\n        y : 'ien jier',\n        yy : '%d jierren'\n    },\n    ordinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/gl.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('gl', {\n    months : 'Xaneiro_Febreiro_Marzo_Abril_Maio_Xuño_Xullo_Agosto_Setembro_Outubro_Novembro_Decembro'.split('_'),\n    monthsShort : 'Xan._Feb._Mar._Abr._Mai._Xuñ._Xul._Ago._Set._Out._Nov._Dec.'.split('_'),\n    weekdays : 'Domingo_Luns_Martes_Mércores_Xoves_Venres_Sábado'.split('_'),\n    weekdaysShort : 'Dom._Lun._Mar._Mér._Xov._Ven._Sáb.'.split('_'),\n    weekdaysMin : 'Do_Lu_Ma_Mé_Xo_Ve_Sá'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay : function () {\n            return '[hoxe ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n        },\n        nextDay : function () {\n            return '[mañá ' + ((this.hours() !== 1) ? 'ás' : 'á') + '] LT';\n        },\n        nextWeek : function () {\n            return 'dddd [' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n        },\n        lastDay : function () {\n            return '[onte ' + ((this.hours() !== 1) ? 'á' : 'a') + '] LT';\n        },\n        lastWeek : function () {\n            return '[o] dddd [pasado ' + ((this.hours() !== 1) ? 'ás' : 'a') + '] LT';\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : function (str) {\n            if (str === 'uns segundos') {\n                return 'nuns segundos';\n            }\n            return 'en ' + str;\n        },\n        past : 'hai %s',\n        s : 'uns segundos',\n        m : 'un minuto',\n        mm : '%d minutos',\n        h : 'unha hora',\n        hh : '%d horas',\n        d : 'un día',\n        dd : '%d días',\n        M : 'un mes',\n        MM : '%d meses',\n        y : 'un ano',\n        yy : '%d anos'\n    },\n    ordinalParse : /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/he.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('he', {\n    months : 'ינואר_פברואר_מרץ_אפריל_מאי_יוני_יולי_אוגוסט_ספטמבר_אוקטובר_נובמבר_דצמבר'.split('_'),\n    monthsShort : 'ינו׳_פבר׳_מרץ_אפר׳_מאי_יוני_יולי_אוג׳_ספט׳_אוק׳_נוב׳_דצמ׳'.split('_'),\n    weekdays : 'ראשון_שני_שלישי_רביעי_חמישי_שישי_שבת'.split('_'),\n    weekdaysShort : 'א׳_ב׳_ג׳_ד׳_ה׳_ו׳_ש׳'.split('_'),\n    weekdaysMin : 'א_ב_ג_ד_ה_ו_ש'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [ב]MMMM YYYY',\n        LLL : 'D [ב]MMMM YYYY LT',\n        LLLL : 'dddd, D [ב]MMMM YYYY LT',\n        l : 'D/M/YYYY',\n        ll : 'D MMM YYYY',\n        lll : 'D MMM YYYY LT',\n        llll : 'ddd, D MMM YYYY LT'\n    },\n    calendar : {\n        sameDay : '[היום ב־]LT',\n        nextDay : '[מחר ב־]LT',\n        nextWeek : 'dddd [בשעה] LT',\n        lastDay : '[אתמול ב־]LT',\n        lastWeek : '[ביום] dddd [האחרון בשעה] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'בעוד %s',\n        past : 'לפני %s',\n        s : 'מספר שניות',\n        m : 'דקה',\n        mm : '%d דקות',\n        h : 'שעה',\n        hh : function (number) {\n            if (number === 2) {\n                return 'שעתיים';\n            }\n            return number + ' שעות';\n        },\n        d : 'יום',\n        dd : function (number) {\n            if (number === 2) {\n                return 'יומיים';\n            }\n            return number + ' ימים';\n        },\n        M : 'חודש',\n        MM : function (number) {\n            if (number === 2) {\n                return 'חודשיים';\n            }\n            return number + ' חודשים';\n        },\n        y : 'שנה',\n        yy : function (number) {\n            if (number === 2) {\n                return 'שנתיים';\n            } else if (number % 10 === 0 && number !== 10) {\n                return number + ' שנה';\n            }\n            return number + ' שנים';\n        }\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/hi.js",
    "content": "\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n},\nnumberMap = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nexport default moment.defineLocale('hi', {\n    months : 'जनवरी_फ़रवरी_मार्च_अप्रैल_मई_जून_जुलाई_अगस्त_सितम्बर_अक्टूबर_नवम्बर_दिसम्बर'.split('_'),\n    monthsShort : 'जन._फ़र._मार्च_अप्रै._मई_जून_जुल._अग._सित._अक्टू._नव._दिस.'.split('_'),\n    weekdays : 'रविवार_सोमवार_मंगलवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n    weekdaysShort : 'रवि_सोम_मंगल_बुध_गुरू_शुक्र_शनि'.split('_'),\n    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm बजे',\n        LTS : 'A h:mm:ss बजे',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, LT',\n        LLLL : 'dddd, D MMMM YYYY, LT'\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[कल] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[कल] LT',\n        lastWeek : '[पिछले] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s में',\n        past : '%s पहले',\n        s : 'कुछ ही क्षण',\n        m : 'एक मिनट',\n        mm : '%d मिनट',\n        h : 'एक घंटा',\n        hh : '%d घंटे',\n        d : 'एक दिन',\n        dd : '%d दिन',\n        M : 'एक महीने',\n        MM : '%d महीने',\n        y : 'एक वर्ष',\n        yy : '%d वर्ष'\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /रात|सुबह|दोपहर|शाम/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'रात') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'सुबह') {\n            return hour;\n        } else if (meridiem === 'दोपहर') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'शाम') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'रात';\n        } else if (hour < 10) {\n            return 'सुबह';\n        } else if (hour < 17) {\n            return 'दोपहर';\n        } else if (hour < 20) {\n            return 'शाम';\n        } else {\n            return 'रात';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/hr.js",
    "content": "\nimport moment from '../moment';\n\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n    case 'm':\n        return withoutSuffix ? 'jedna minuta' : 'jedne minute';\n    case 'mm':\n        if (number === 1) {\n            result += 'minuta';\n        } else if (number === 2 || number === 3 || number === 4) {\n            result += 'minute';\n        } else {\n            result += 'minuta';\n        }\n        return result;\n    case 'h':\n        return withoutSuffix ? 'jedan sat' : 'jednog sata';\n    case 'hh':\n        if (number === 1) {\n            result += 'sat';\n        } else if (number === 2 || number === 3 || number === 4) {\n            result += 'sata';\n        } else {\n            result += 'sati';\n        }\n        return result;\n    case 'dd':\n        if (number === 1) {\n            result += 'dan';\n        } else {\n            result += 'dana';\n        }\n        return result;\n    case 'MM':\n        if (number === 1) {\n            result += 'mjesec';\n        } else if (number === 2 || number === 3 || number === 4) {\n            result += 'mjeseca';\n        } else {\n            result += 'mjeseci';\n        }\n        return result;\n    case 'yy':\n        if (number === 1) {\n            result += 'godina';\n        } else if (number === 2 || number === 3 || number === 4) {\n            result += 'godine';\n        } else {\n            result += 'godina';\n        }\n        return result;\n    }\n}\n\nexport default moment.defineLocale('hr', {\n    months : 'sječanj_veljača_ožujak_travanj_svibanj_lipanj_srpanj_kolovoz_rujan_listopad_studeni_prosinac'.split('_'),\n    monthsShort : 'sje._vel._ožu._tra._svi._lip._srp._kol._ruj._lis._stu._pro.'.split('_'),\n    weekdays : 'nedjelja_ponedjeljak_utorak_srijeda_četvrtak_petak_subota'.split('_'),\n    weekdaysShort : 'ned._pon._uto._sri._čet._pet._sub.'.split('_'),\n    weekdaysMin : 'ne_po_ut_sr_če_pe_su'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'LT:ss',\n        L : 'DD. MM. YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY LT',\n        LLLL : 'dddd, D. MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay  : '[danas u] LT',\n        nextDay  : '[sutra u] LT',\n        nextWeek : function () {\n            switch (this.day()) {\n            case 0:\n                return '[u] [nedjelju] [u] LT';\n            case 3:\n                return '[u] [srijedu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[jučer u] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n            case 0:\n            case 3:\n                return '[prošlu] dddd [u] LT';\n            case 6:\n                return '[prošle] [subote] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[prošli] dddd [u] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'prije %s',\n        s      : 'par sekundi',\n        m      : translate,\n        mm     : translate,\n        h      : translate,\n        hh     : translate,\n        d      : 'dan',\n        dd     : translate,\n        M      : 'mjesec',\n        MM     : translate,\n        y      : 'godinu',\n        yy     : translate\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/hu.js",
    "content": "\nimport moment from '../moment';\n\nvar weekEndings = 'vasárnap hétfőn kedden szerdán csütörtökön pénteken szombaton'.split(' ');\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var num = number,\n        suffix;\n    switch (key) {\n    case 's':\n        return (isFuture || withoutSuffix) ? 'néhány másodperc' : 'néhány másodperce';\n    case 'm':\n        return 'egy' + (isFuture || withoutSuffix ? ' perc' : ' perce');\n    case 'mm':\n        return num + (isFuture || withoutSuffix ? ' perc' : ' perce');\n    case 'h':\n        return 'egy' + (isFuture || withoutSuffix ? ' óra' : ' órája');\n    case 'hh':\n        return num + (isFuture || withoutSuffix ? ' óra' : ' órája');\n    case 'd':\n        return 'egy' + (isFuture || withoutSuffix ? ' nap' : ' napja');\n    case 'dd':\n        return num + (isFuture || withoutSuffix ? ' nap' : ' napja');\n    case 'M':\n        return 'egy' + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n    case 'MM':\n        return num + (isFuture || withoutSuffix ? ' hónap' : ' hónapja');\n    case 'y':\n        return 'egy' + (isFuture || withoutSuffix ? ' év' : ' éve');\n    case 'yy':\n        return num + (isFuture || withoutSuffix ? ' év' : ' éve');\n    }\n    return '';\n}\nfunction week(isFuture) {\n    return (isFuture ? '' : '[múlt] ') + '[' + weekEndings[this.day()] + '] LT[-kor]';\n}\n\nexport default moment.defineLocale('hu', {\n    months : 'január_február_március_április_május_június_július_augusztus_szeptember_október_november_december'.split('_'),\n    monthsShort : 'jan_feb_márc_ápr_máj_jún_júl_aug_szept_okt_nov_dec'.split('_'),\n    weekdays : 'vasárnap_hétfő_kedd_szerda_csütörtök_péntek_szombat'.split('_'),\n    weekdaysShort : 'vas_hét_kedd_sze_csüt_pén_szo'.split('_'),\n    weekdaysMin : 'v_h_k_sze_cs_p_szo'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'LT:ss',\n        L : 'YYYY.MM.DD.',\n        LL : 'YYYY. MMMM D.',\n        LLL : 'YYYY. MMMM D., LT',\n        LLLL : 'YYYY. MMMM D., dddd LT'\n    },\n    meridiemParse: /de|du/i,\n    isPM: function (input) {\n        return input.charAt(1).toLowerCase() === 'u';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 12) {\n            return isLower === true ? 'de' : 'DE';\n        } else {\n            return isLower === true ? 'du' : 'DU';\n        }\n    },\n    calendar : {\n        sameDay : '[ma] LT[-kor]',\n        nextDay : '[holnap] LT[-kor]',\n        nextWeek : function () {\n            return week.call(this, true);\n        },\n        lastDay : '[tegnap] LT[-kor]',\n        lastWeek : function () {\n            return week.call(this, false);\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s múlva',\n        past : '%s',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/hy-am.js",
    "content": "\nimport moment from '../moment';\n\nfunction monthsCaseReplace(m, format) {\n    var months = {\n        'nominative': 'հունվար_փետրվար_մարտ_ապրիլ_մայիս_հունիս_հուլիս_օգոստոս_սեպտեմբեր_հոկտեմբեր_նոյեմբեր_դեկտեմբեր'.split('_'),\n        'accusative': 'հունվարի_փետրվարի_մարտի_ապրիլի_մայիսի_հունիսի_հուլիսի_օգոստոսի_սեպտեմբերի_հոկտեմբերի_նոյեմբերի_դեկտեմբերի'.split('_')\n    },\n    nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n        'accusative' :\n        'nominative';\n    return months[nounCase][m.month()];\n}\nfunction monthsShortCaseReplace(m, format) {\n    var monthsShort = 'հնվ_փտր_մրտ_ապր_մյս_հնս_հլս_օգս_սպտ_հկտ_նմբ_դկտ'.split('_');\n    return monthsShort[m.month()];\n}\nfunction weekdaysCaseReplace(m, format) {\n    var weekdays = 'կիրակի_երկուշաբթի_երեքշաբթի_չորեքշաբթի_հինգշաբթի_ուրբաթ_շաբաթ'.split('_');\n    return weekdays[m.day()];\n}\n\nexport default moment.defineLocale('hy-am', {\n    months : monthsCaseReplace,\n    monthsShort : monthsShortCaseReplace,\n    weekdays : weekdaysCaseReplace,\n    weekdaysShort : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n    weekdaysMin : 'կրկ_երկ_երք_չրք_հնգ_ուրբ_շբթ'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY թ.',\n        LLL : 'D MMMM YYYY թ., LT',\n        LLLL : 'dddd, D MMMM YYYY թ., LT'\n    },\n    calendar : {\n        sameDay: '[այսօր] LT',\n        nextDay: '[վաղը] LT',\n        lastDay: '[երեկ] LT',\n        nextWeek: function () {\n            return 'dddd [օրը ժամը] LT';\n        },\n        lastWeek: function () {\n            return '[անցած] dddd [օրը ժամը] LT';\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s հետո',\n        past : '%s առաջ',\n        s : 'մի քանի վայրկյան',\n        m : 'րոպե',\n        mm : '%d րոպե',\n        h : 'ժամ',\n        hh : '%d ժամ',\n        d : 'օր',\n        dd : '%d օր',\n        M : 'ամիս',\n        MM : '%d ամիս',\n        y : 'տարի',\n        yy : '%d տարի'\n    },\n    meridiemParse: /գիշերվա|առավոտվա|ցերեկվա|երեկոյան/,\n    isPM: function (input) {\n        return /^(ցերեկվա|երեկոյան)$/.test(input);\n    },\n    meridiem : function (hour) {\n        if (hour < 4) {\n            return 'գիշերվա';\n        } else if (hour < 12) {\n            return 'առավոտվա';\n        } else if (hour < 17) {\n            return 'ցերեկվա';\n        } else {\n            return 'երեկոյան';\n        }\n    },\n    ordinalParse: /\\d{1,2}|\\d{1,2}-(ին|րդ)/,\n    ordinal: function (number, period) {\n        switch (period) {\n        case 'DDD':\n        case 'w':\n        case 'W':\n        case 'DDDo':\n            if (number === 1) {\n                return number + '-ին';\n            }\n            return number + '-րդ';\n        default:\n            return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/id.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('id', {\n    months : 'Januari_Februari_Maret_April_Mei_Juni_Juli_Agustus_September_Oktober_November_Desember'.split('_'),\n    monthsShort : 'Jan_Feb_Mar_Apr_Mei_Jun_Jul_Ags_Sep_Okt_Nov_Des'.split('_'),\n    weekdays : 'Minggu_Senin_Selasa_Rabu_Kamis_Jumat_Sabtu'.split('_'),\n    weekdaysShort : 'Min_Sen_Sel_Rab_Kam_Jum_Sab'.split('_'),\n    weekdaysMin : 'Mg_Sn_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'LT.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] LT',\n        LLLL : 'dddd, D MMMM YYYY [pukul] LT'\n    },\n    meridiemParse: /pagi|siang|sore|malam/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'siang') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'sore' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'siang';\n        } else if (hours < 19) {\n            return 'sore';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Besok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kemarin pukul] LT',\n        lastWeek : 'dddd [lalu pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lalu',\n        s : 'beberapa detik',\n        m : 'semenit',\n        mm : '%d menit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/is.js",
    "content": "\nimport moment from '../moment';\n\nfunction plural(n) {\n    if (n % 100 === 11) {\n        return true;\n    } else if (n % 10 === 1) {\n        return false;\n    }\n    return true;\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n    case 's':\n        return withoutSuffix || isFuture ? 'nokkrar sekúndur' : 'nokkrum sekúndum';\n    case 'm':\n        return withoutSuffix ? 'mínúta' : 'mínútu';\n    case 'mm':\n        if (plural(number)) {\n            return result + (withoutSuffix || isFuture ? 'mínútur' : 'mínútum');\n        } else if (withoutSuffix) {\n            return result + 'mínúta';\n        }\n        return result + 'mínútu';\n    case 'hh':\n        if (plural(number)) {\n            return result + (withoutSuffix || isFuture ? 'klukkustundir' : 'klukkustundum');\n        }\n        return result + 'klukkustund';\n    case 'd':\n        if (withoutSuffix) {\n            return 'dagur';\n        }\n        return isFuture ? 'dag' : 'degi';\n    case 'dd':\n        if (plural(number)) {\n            if (withoutSuffix) {\n                return result + 'dagar';\n            }\n            return result + (isFuture ? 'daga' : 'dögum');\n        } else if (withoutSuffix) {\n            return result + 'dagur';\n        }\n        return result + (isFuture ? 'dag' : 'degi');\n    case 'M':\n        if (withoutSuffix) {\n            return 'mánuður';\n        }\n        return isFuture ? 'mánuð' : 'mánuði';\n    case 'MM':\n        if (plural(number)) {\n            if (withoutSuffix) {\n                return result + 'mánuðir';\n            }\n            return result + (isFuture ? 'mánuði' : 'mánuðum');\n        } else if (withoutSuffix) {\n            return result + 'mánuður';\n        }\n        return result + (isFuture ? 'mánuð' : 'mánuði');\n    case 'y':\n        return withoutSuffix || isFuture ? 'ár' : 'ári';\n    case 'yy':\n        if (plural(number)) {\n            return result + (withoutSuffix || isFuture ? 'ár' : 'árum');\n        }\n        return result + (withoutSuffix || isFuture ? 'ár' : 'ári');\n    }\n}\n\nexport default moment.defineLocale('is', {\n    months : 'janúar_febrúar_mars_apríl_maí_júní_júlí_ágúst_september_október_nóvember_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maí_jún_júl_ágú_sep_okt_nóv_des'.split('_'),\n    weekdays : 'sunnudagur_mánudagur_þriðjudagur_miðvikudagur_fimmtudagur_föstudagur_laugardagur'.split('_'),\n    weekdaysShort : 'sun_mán_þri_mið_fim_fös_lau'.split('_'),\n    weekdaysMin : 'Su_Má_Þr_Mi_Fi_Fö_La'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] LT',\n        LLLL : 'dddd, D. MMMM YYYY [kl.] LT'\n    },\n    calendar : {\n        sameDay : '[í dag kl.] LT',\n        nextDay : '[á morgun kl.] LT',\n        nextWeek : 'dddd [kl.] LT',\n        lastDay : '[í gær kl.] LT',\n        lastWeek : '[síðasta] dddd [kl.] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'eftir %s',\n        past : 'fyrir %s síðan',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : 'klukkustund',\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/it.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('it', {\n    months : 'gennaio_febbraio_marzo_aprile_maggio_giugno_luglio_agosto_settembre_ottobre_novembre_dicembre'.split('_'),\n    monthsShort : 'gen_feb_mar_apr_mag_giu_lug_ago_set_ott_nov_dic'.split('_'),\n    weekdays : 'Domenica_Lunedì_Martedì_Mercoledì_Giovedì_Venerdì_Sabato'.split('_'),\n    weekdaysShort : 'Dom_Lun_Mar_Mer_Gio_Ven_Sab'.split('_'),\n    weekdaysMin : 'D_L_Ma_Me_G_V_S'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd, D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay: '[Oggi alle] LT',\n        nextDay: '[Domani alle] LT',\n        nextWeek: 'dddd [alle] LT',\n        lastDay: '[Ieri alle] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 0:\n                    return '[la scorsa] dddd [alle] LT';\n                default:\n                    return '[lo scorso] dddd [alle] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : function (s) {\n            return ((/^[0-9].+$/).test(s) ? 'tra' : 'in') + ' ' + s;\n        },\n        past : '%s fa',\n        s : 'alcuni secondi',\n        m : 'un minuto',\n        mm : '%d minuti',\n        h : 'un\\'ora',\n        hh : '%d ore',\n        d : 'un giorno',\n        dd : '%d giorni',\n        M : 'un mese',\n        MM : '%d mesi',\n        y : 'un anno',\n        yy : '%d anni'\n    },\n    ordinalParse : /\\d{1,2}º/,\n    ordinal: '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/ja.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('ja', {\n    months : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '日曜日_月曜日_火曜日_水曜日_木曜日_金曜日_土曜日'.split('_'),\n    weekdaysShort : '日_月_火_水_木_金_土'.split('_'),\n    weekdaysMin : '日_月_火_水_木_金_土'.split('_'),\n    longDateFormat : {\n        LT : 'Ah時m分',\n        LTS : 'LTs秒',\n        L : 'YYYY/MM/DD',\n        LL : 'YYYY年M月D日',\n        LLL : 'YYYY年M月D日LT',\n        LLLL : 'YYYY年M月D日LT dddd'\n    },\n    meridiemParse: /午前|午後/i,\n    isPM : function (input) {\n        return input === '午後';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return '午前';\n        } else {\n            return '午後';\n        }\n    },\n    calendar : {\n        sameDay : '[今日] LT',\n        nextDay : '[明日] LT',\n        nextWeek : '[来週]dddd LT',\n        lastDay : '[昨日] LT',\n        lastWeek : '[前週]dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s後',\n        past : '%s前',\n        s : '数秒',\n        m : '1分',\n        mm : '%d分',\n        h : '1時間',\n        hh : '%d時間',\n        d : '1日',\n        dd : '%d日',\n        M : '1ヶ月',\n        MM : '%dヶ月',\n        y : '1年',\n        yy : '%d年'\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/ka.js",
    "content": "\nimport moment from '../moment';\n\nfunction monthsCaseReplace(m, format) {\n    var months = {\n        'nominative': 'იანვარი_თებერვალი_მარტი_აპრილი_მაისი_ივნისი_ივლისი_აგვისტო_სექტემბერი_ოქტომბერი_ნოემბერი_დეკემბერი'.split('_'),\n        'accusative': 'იანვარს_თებერვალს_მარტს_აპრილის_მაისს_ივნისს_ივლისს_აგვისტს_სექტემბერს_ოქტომბერს_ნოემბერს_დეკემბერს'.split('_')\n    },\n    nounCase = (/D[oD] *MMMM?/).test(format) ?\n        'accusative' :\n        'nominative';\n    return months[nounCase][m.month()];\n}\nfunction weekdaysCaseReplace(m, format) {\n    var weekdays = {\n        'nominative': 'კვირა_ორშაბათი_სამშაბათი_ოთხშაბათი_ხუთშაბათი_პარასკევი_შაბათი'.split('_'),\n        'accusative': 'კვირას_ორშაბათს_სამშაბათს_ოთხშაბათს_ხუთშაბათს_პარასკევს_შაბათს'.split('_')\n    },\n    nounCase = (/(წინა|შემდეგ)/).test(format) ?\n        'accusative' :\n        'nominative';\n    return weekdays[nounCase][m.day()];\n}\n\nexport default moment.defineLocale('ka', {\n    months : monthsCaseReplace,\n    monthsShort : 'იან_თებ_მარ_აპრ_მაი_ივნ_ივლ_აგვ_სექ_ოქტ_ნოე_დეკ'.split('_'),\n    weekdays : weekdaysCaseReplace,\n    weekdaysShort : 'კვი_ორშ_სამ_ოთხ_ხუთ_პარ_შაბ'.split('_'),\n    weekdaysMin : 'კვ_ორ_სა_ოთ_ხუ_პა_შა'.split('_'),\n    longDateFormat : {\n        LT : 'h:mm A',\n        LTS : 'h:mm:ss A',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd, D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay : '[დღეს] LT[-ზე]',\n        nextDay : '[ხვალ] LT[-ზე]',\n        lastDay : '[გუშინ] LT[-ზე]',\n        nextWeek : '[შემდეგ] dddd LT[-ზე]',\n        lastWeek : '[წინა] dddd LT-ზე',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : function (s) {\n            return (/(წამი|წუთი|საათი|წელი)/).test(s) ?\n                s.replace(/ი$/, 'ში') :\n                s + 'ში';\n        },\n        past : function (s) {\n            if ((/(წამი|წუთი|საათი|დღე|თვე)/).test(s)) {\n                return s.replace(/(ი|ე)$/, 'ის წინ');\n            }\n            if ((/წელი/).test(s)) {\n                return s.replace(/წელი$/, 'წლის წინ');\n            }\n        },\n        s : 'რამდენიმე წამი',\n        m : 'წუთი',\n        mm : '%d წუთი',\n        h : 'საათი',\n        hh : '%d საათი',\n        d : 'დღე',\n        dd : '%d დღე',\n        M : 'თვე',\n        MM : '%d თვე',\n        y : 'წელი',\n        yy : '%d წელი'\n    },\n    ordinalParse: /0|1-ლი|მე-\\d{1,2}|\\d{1,2}-ე/,\n    ordinal : function (number) {\n        if (number === 0) {\n            return number;\n        }\n        if (number === 1) {\n            return number + '-ლი';\n        }\n        if ((number < 20) || (number <= 100 && (number % 20 === 0)) || (number % 100 === 0)) {\n            return 'მე-' + number;\n        }\n        return number + '-ე';\n    },\n    week : {\n        dow : 1,\n        doy : 7\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/km.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('km', {\n    months: 'មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n    monthsShort: 'មករា_កុម្ភៈ_មិនា_មេសា_ឧសភា_មិថុនា_កក្កដា_សីហា_កញ្ញា_តុលា_វិច្ឆិកា_ធ្នូ'.split('_'),\n    weekdays: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    weekdaysShort: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    weekdaysMin: 'អាទិត្យ_ច័ន្ទ_អង្គារ_ពុធ_ព្រហស្បតិ៍_សុក្រ_សៅរ៍'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS : 'LT:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY LT',\n        LLLL: 'dddd, D MMMM YYYY LT'\n    },\n    calendar: {\n        sameDay: '[ថ្ងៃនៈ ម៉ោង] LT',\n        nextDay: '[ស្អែក ម៉ោង] LT',\n        nextWeek: 'dddd [ម៉ោង] LT',\n        lastDay: '[ម្សិលមិញ ម៉ោង] LT',\n        lastWeek: 'dddd [សប្តាហ៍មុន] [ម៉ោង] LT',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: '%sទៀត',\n        past: '%sមុន',\n        s: 'ប៉ុន្មានវិនាទី',\n        m: 'មួយនាទី',\n        mm: '%d នាទី',\n        h: 'មួយម៉ោង',\n        hh: '%d ម៉ោង',\n        d: 'មួយថ្ងៃ',\n        dd: '%d ថ្ងៃ',\n        M: 'មួយខែ',\n        MM: '%d ខែ',\n        y: 'មួយឆ្នាំ',\n        yy: '%d ឆ្នាំ'\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/ko.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('ko', {\n    months : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n    monthsShort : '1월_2월_3월_4월_5월_6월_7월_8월_9월_10월_11월_12월'.split('_'),\n    weekdays : '일요일_월요일_화요일_수요일_목요일_금요일_토요일'.split('_'),\n    weekdaysShort : '일_월_화_수_목_금_토'.split('_'),\n    weekdaysMin : '일_월_화_수_목_금_토'.split('_'),\n    longDateFormat : {\n        LT : 'A h시 m분',\n        LTS : 'A h시 m분 s초',\n        L : 'YYYY.MM.DD',\n        LL : 'YYYY년 MMMM D일',\n        LLL : 'YYYY년 MMMM D일 LT',\n        LLLL : 'YYYY년 MMMM D일 dddd LT'\n    },\n    calendar : {\n        sameDay : '오늘 LT',\n        nextDay : '내일 LT',\n        nextWeek : 'dddd LT',\n        lastDay : '어제 LT',\n        lastWeek : '지난주 dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s 후',\n        past : '%s 전',\n        s : '몇초',\n        ss : '%d초',\n        m : '일분',\n        mm : '%d분',\n        h : '한시간',\n        hh : '%d시간',\n        d : '하루',\n        dd : '%d일',\n        M : '한달',\n        MM : '%d달',\n        y : '일년',\n        yy : '%d년'\n    },\n    ordinalParse : /\\d{1,2}일/,\n    ordinal : '%d일',\n    meridiemParse : /오전|오후/,\n    isPM : function (token) {\n        return token === '오후';\n    },\n    meridiem : function (hour, minute, isUpper) {\n        return hour < 12 ? '오전' : '오후';\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/lb.js",
    "content": "\nimport moment from '../moment';\n\nfunction processRelativeTime(number, withoutSuffix, key, isFuture) {\n    var format = {\n        'm': ['eng Minutt', 'enger Minutt'],\n        'h': ['eng Stonn', 'enger Stonn'],\n        'd': ['een Dag', 'engem Dag'],\n        'M': ['ee Mount', 'engem Mount'],\n        'y': ['ee Joer', 'engem Joer']\n    };\n    return withoutSuffix ? format[key][0] : format[key][1];\n}\nfunction processFutureTime(string) {\n    var number = string.substr(0, string.indexOf(' '));\n    if (eifelerRegelAppliesToNumber(number)) {\n        return 'a ' + string;\n    }\n    return 'an ' + string;\n}\nfunction processPastTime(string) {\n    var number = string.substr(0, string.indexOf(' '));\n    if (eifelerRegelAppliesToNumber(number)) {\n        return 'viru ' + string;\n    }\n    return 'virun ' + string;\n}\nfunction eifelerRegelAppliesToNumber(number) {\n    number = parseInt(number, 10);\n    if (isNaN(number)) {\n        return false;\n    }\n    if (number < 0) {\n        return true;\n    } else if (number < 10) {\n        if (4 <= number && number <= 7) {\n            return true;\n        }\n        return false;\n    } else if (number < 100) {\n        var lastDigit = number % 10, firstDigit = number / 10;\n        if (lastDigit === 0) {\n            return eifelerRegelAppliesToNumber(firstDigit);\n        }\n        return eifelerRegelAppliesToNumber(lastDigit);\n    } else if (number < 10000) {\n        while (number >= 10) {\n            number = number / 10;\n        }\n        return eifelerRegelAppliesToNumber(number);\n    } else {\n        number = number / 1000;\n        return eifelerRegelAppliesToNumber(number);\n    }\n}\n\nexport default moment.defineLocale('lb', {\n    months: 'Januar_Februar_Mäerz_Abrëll_Mee_Juni_Juli_August_September_Oktober_November_Dezember'.split('_'),\n    monthsShort: 'Jan._Febr._Mrz._Abr._Mee_Jun._Jul._Aug._Sept._Okt._Nov._Dez.'.split('_'),\n    weekdays: 'Sonndeg_Méindeg_Dënschdeg_Mëttwoch_Donneschdeg_Freideg_Samschdeg'.split('_'),\n    weekdaysShort: 'So._Mé._Dë._Më._Do._Fr._Sa.'.split('_'),\n    weekdaysMin: 'So_Mé_Dë_Më_Do_Fr_Sa'.split('_'),\n    longDateFormat: {\n        LT: 'H:mm [Auer]',\n        LTS: 'H:mm:ss [Auer]',\n        L: 'DD.MM.YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY LT',\n        LLLL: 'dddd, D. MMMM YYYY LT'\n    },\n    calendar: {\n        sameDay: '[Haut um] LT',\n        sameElse: 'L',\n        nextDay: '[Muer um] LT',\n        nextWeek: 'dddd [um] LT',\n        lastDay: '[Gëschter um] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n                case 2:\n                case 4:\n                    return '[Leschten] dddd [um] LT';\n                default:\n                    return '[Leschte] dddd [um] LT';\n            }\n        }\n    },\n    relativeTime : {\n        future : processFutureTime,\n        past : processPastTime,\n        s : 'e puer Sekonnen',\n        m : processRelativeTime,\n        mm : '%d Minutten',\n        h : processRelativeTime,\n        hh : '%d Stonnen',\n        d : processRelativeTime,\n        dd : '%d Deeg',\n        M : processRelativeTime,\n        MM : '%d Méint',\n        y : processRelativeTime,\n        yy : '%d Joer'\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal: '%d.',\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/lt.js",
    "content": "\nimport moment from '../moment';\n\nvar units = {\n    'm' : 'minutė_minutės_minutę',\n    'mm': 'minutės_minučių_minutes',\n    'h' : 'valanda_valandos_valandą',\n    'hh': 'valandos_valandų_valandas',\n    'd' : 'diena_dienos_dieną',\n    'dd': 'dienos_dienų_dienas',\n    'M' : 'mėnuo_mėnesio_mėnesį',\n    'MM': 'mėnesiai_mėnesių_mėnesius',\n    'y' : 'metai_metų_metus',\n    'yy': 'metai_metų_metus'\n},\nweekDays = 'sekmadienis_pirmadienis_antradienis_trečiadienis_ketvirtadienis_penktadienis_šeštadienis'.split('_');\nfunction translateSeconds(number, withoutSuffix, key, isFuture) {\n    if (withoutSuffix) {\n        return 'kelios sekundės';\n    } else {\n        return isFuture ? 'kelių sekundžių' : 'kelias sekundes';\n    }\n}\nfunction translateSingular(number, withoutSuffix, key, isFuture) {\n    return withoutSuffix ? forms(key)[0] : (isFuture ? forms(key)[1] : forms(key)[2]);\n}\nfunction special(number) {\n    return number % 10 === 0 || (number > 10 && number < 20);\n}\nfunction forms(key) {\n    return units[key].split('_');\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    if (number === 1) {\n        return result + translateSingular(number, withoutSuffix, key[0], isFuture);\n    } else if (withoutSuffix) {\n        return result + (special(number) ? forms(key)[1] : forms(key)[0]);\n    } else {\n        if (isFuture) {\n            return result + forms(key)[1];\n        } else {\n            return result + (special(number) ? forms(key)[1] : forms(key)[2]);\n        }\n    }\n}\nfunction relativeWeekDay(moment, format) {\n    var nominative = format.indexOf('dddd HH:mm') === -1,\n        weekDay = weekDays[moment.day()];\n    return nominative ? weekDay : weekDay.substring(0, weekDay.length - 2) + 'į';\n}\n\nexport default moment.defineLocale('lt', {\n    months : 'sausio_vasario_kovo_balandžio_gegužės_birželio_liepos_rugpjūčio_rugsėjo_spalio_lapkričio_gruodžio'.split('_'),\n    monthsShort : 'sau_vas_kov_bal_geg_bir_lie_rgp_rgs_spa_lap_grd'.split('_'),\n    weekdays : relativeWeekDay,\n    weekdaysShort : 'Sek_Pir_Ant_Tre_Ket_Pen_Šeš'.split('_'),\n    weekdaysMin : 'S_P_A_T_K_Pn_Š'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'YYYY [m.] MMMM D [d.]',\n        LLL : 'YYYY [m.] MMMM D [d.], LT [val.]',\n        LLLL : 'YYYY [m.] MMMM D [d.], dddd, LT [val.]',\n        l : 'YYYY-MM-DD',\n        ll : 'YYYY [m.] MMMM D [d.]',\n        lll : 'YYYY [m.] MMMM D [d.], LT [val.]',\n        llll : 'YYYY [m.] MMMM D [d.], ddd, LT [val.]'\n    },\n    calendar : {\n        sameDay : '[Šiandien] LT',\n        nextDay : '[Rytoj] LT',\n        nextWeek : 'dddd LT',\n        lastDay : '[Vakar] LT',\n        lastWeek : '[Praėjusį] dddd LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'po %s',\n        past : 'prieš %s',\n        s : translateSeconds,\n        m : translateSingular,\n        mm : translate,\n        h : translateSingular,\n        hh : translate,\n        d : translateSingular,\n        dd : translate,\n        M : translateSingular,\n        MM : translate,\n        y : translateSingular,\n        yy : translate\n    },\n    ordinalParse: /\\d{1,2}-oji/,\n    ordinal : function (number) {\n        return number + '-oji';\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/lv.js",
    "content": "\nimport moment from '../moment';\n\nvar units = {\n    'mm': 'minūti_minūtes_minūte_minūtes',\n    'hh': 'stundu_stundas_stunda_stundas',\n    'dd': 'dienu_dienas_diena_dienas',\n    'MM': 'mēnesi_mēnešus_mēnesis_mēneši',\n    'yy': 'gadu_gadus_gads_gadi'\n};\nfunction format(word, number, withoutSuffix) {\n    var forms = word.split('_');\n    if (withoutSuffix) {\n        return number % 10 === 1 && number !== 11 ? forms[2] : forms[3];\n    } else {\n        return number % 10 === 1 && number !== 11 ? forms[0] : forms[1];\n    }\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    return number + ' ' + format(units[key], number, withoutSuffix);\n}\n\nexport default moment.defineLocale('lv', {\n    months : 'janvāris_februāris_marts_aprīlis_maijs_jūnijs_jūlijs_augusts_septembris_oktobris_novembris_decembris'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jūn_jūl_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'svētdiena_pirmdiena_otrdiena_trešdiena_ceturtdiena_piektdiena_sestdiena'.split('_'),\n    weekdaysShort : 'Sv_P_O_T_C_Pk_S'.split('_'),\n    weekdaysMin : 'Sv_P_O_T_C_Pk_S'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'YYYY. [gada] D. MMMM',\n        LLL : 'YYYY. [gada] D. MMMM, LT',\n        LLLL : 'YYYY. [gada] D. MMMM, dddd, LT'\n    },\n    calendar : {\n        sameDay : '[Šodien pulksten] LT',\n        nextDay : '[Rīt pulksten] LT',\n        nextWeek : 'dddd [pulksten] LT',\n        lastDay : '[Vakar pulksten] LT',\n        lastWeek : '[Pagājušā] dddd [pulksten] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s vēlāk',\n        past : '%s agrāk',\n        s : 'dažas sekundes',\n        m : 'minūti',\n        mm : relativeTimeWithPlural,\n        h : 'stundu',\n        hh : relativeTimeWithPlural,\n        d : 'dienu',\n        dd : relativeTimeWithPlural,\n        M : 'mēnesi',\n        MM : relativeTimeWithPlural,\n        y : 'gadu',\n        yy : relativeTimeWithPlural\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/mk.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('mk', {\n    months : 'јануари_февруари_март_април_мај_јуни_јули_август_септември_октомври_ноември_декември'.split('_'),\n    monthsShort : 'јан_фев_мар_апр_мај_јун_јул_авг_сеп_окт_ное_дек'.split('_'),\n    weekdays : 'недела_понеделник_вторник_среда_четврток_петок_сабота'.split('_'),\n    weekdaysShort : 'нед_пон_вто_сре_чет_пет_саб'.split('_'),\n    weekdaysMin : 'нe_пo_вт_ср_че_пе_сa'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'LT:ss',\n        L : 'D.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd, D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay : '[Денес во] LT',\n        nextDay : '[Утре во] LT',\n        nextWeek : 'dddd [во] LT',\n        lastDay : '[Вчера во] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n            case 0:\n            case 3:\n            case 6:\n                return '[Во изминатата] dddd [во] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[Во изминатиот] dddd [во] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'после %s',\n        past : 'пред %s',\n        s : 'неколку секунди',\n        m : 'минута',\n        mm : '%d минути',\n        h : 'час',\n        hh : '%d часа',\n        d : 'ден',\n        dd : '%d дена',\n        M : 'месец',\n        MM : '%d месеци',\n        y : 'година',\n        yy : '%d години'\n    },\n    ordinalParse: /\\d{1,2}-(ев|ен|ти|ви|ри|ми)/,\n    ordinal : function (number) {\n        var lastDigit = number % 10,\n            last2Digits = number % 100;\n        if (number === 0) {\n            return number + '-ев';\n        } else if (last2Digits === 0) {\n            return number + '-ен';\n        } else if (last2Digits > 10 && last2Digits < 20) {\n            return number + '-ти';\n        } else if (lastDigit === 1) {\n            return number + '-ви';\n        } else if (lastDigit === 2) {\n            return number + '-ри';\n        } else if (lastDigit === 7 || lastDigit === 8) {\n            return number + '-ми';\n        } else {\n            return number + '-ти';\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/ml.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('ml', {\n    months : 'ജനുവരി_ഫെബ്രുവരി_മാർച്ച്_ഏപ്രിൽ_മേയ്_ജൂൺ_ജൂലൈ_ഓഗസ്റ്റ്_സെപ്റ്റംബർ_ഒക്ടോബർ_നവംബർ_ഡിസംബർ'.split('_'),\n    monthsShort : 'ജനു._ഫെബ്രു._മാർ._ഏപ്രി._മേയ്_ജൂൺ_ജൂലൈ._ഓഗ._സെപ്റ്റ._ഒക്ടോ._നവം._ഡിസം.'.split('_'),\n    weekdays : 'ഞായറാഴ്ച_തിങ്കളാഴ്ച_ചൊവ്വാഴ്ച_ബുധനാഴ്ച_വ്യാഴാഴ്ച_വെള്ളിയാഴ്ച_ശനിയാഴ്ച'.split('_'),\n    weekdaysShort : 'ഞായർ_തിങ്കൾ_ചൊവ്വ_ബുധൻ_വ്യാഴം_വെള്ളി_ശനി'.split('_'),\n    weekdaysMin : 'ഞാ_തി_ചൊ_ബു_വ്യാ_വെ_ശ'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm -നു',\n        LTS : 'A h:mm:ss -നു',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, LT',\n        LLLL : 'dddd, D MMMM YYYY, LT'\n    },\n    calendar : {\n        sameDay : '[ഇന്ന്] LT',\n        nextDay : '[നാളെ] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[ഇന്നലെ] LT',\n        lastWeek : '[കഴിഞ്ഞ] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s കഴിഞ്ഞ്',\n        past : '%s മുൻപ്',\n        s : 'അൽപ നിമിഷങ്ങൾ',\n        m : 'ഒരു മിനിറ്റ്',\n        mm : '%d മിനിറ്റ്',\n        h : 'ഒരു മണിക്കൂർ',\n        hh : '%d മണിക്കൂർ',\n        d : 'ഒരു ദിവസം',\n        dd : '%d ദിവസം',\n        M : 'ഒരു മാസം',\n        MM : '%d മാസം',\n        y : 'ഒരു വർഷം',\n        yy : '%d വർഷം'\n    },\n    meridiemParse: /രാത്രി|രാവിലെ|ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി/i,\n    isPM : function (input) {\n        return /^(ഉച്ച കഴിഞ്ഞ്|വൈകുന്നേരം|രാത്രി)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'രാത്രി';\n        } else if (hour < 12) {\n            return 'രാവിലെ';\n        } else if (hour < 17) {\n            return 'ഉച്ച കഴിഞ്ഞ്';\n        } else if (hour < 20) {\n            return 'വൈകുന്നേരം';\n        } else {\n            return 'രാത്രി';\n        }\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/mr.js",
    "content": "\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n},\nnumberMap = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nexport default moment.defineLocale('mr', {\n    months : 'जानेवारी_फेब्रुवारी_मार्च_एप्रिल_मे_जून_जुलै_ऑगस्ट_सप्टेंबर_ऑक्टोबर_नोव्हेंबर_डिसेंबर'.split('_'),\n    monthsShort: 'जाने._फेब्रु._मार्च._एप्रि._मे._जून._जुलै._ऑग._सप्टें._ऑक्टो._नोव्हें._डिसें.'.split('_'),\n    weekdays : 'रविवार_सोमवार_मंगळवार_बुधवार_गुरूवार_शुक्रवार_शनिवार'.split('_'),\n    weekdaysShort : 'रवि_सोम_मंगळ_बुध_गुरू_शुक्र_शनि'.split('_'),\n    weekdaysMin : 'र_सो_मं_बु_गु_शु_श'.split('_'),\n    longDateFormat : {\n        LT : 'A h:mm वाजता',\n        LTS : 'A h:mm:ss वाजता',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, LT',\n        LLLL : 'dddd, D MMMM YYYY, LT'\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[उद्या] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[काल] LT',\n        lastWeek: '[मागील] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s नंतर',\n        past : '%s पूर्वी',\n        s : 'सेकंद',\n        m: 'एक मिनिट',\n        mm: '%d मिनिटे',\n        h : 'एक तास',\n        hh : '%d तास',\n        d : 'एक दिवस',\n        dd : '%d दिवस',\n        M : 'एक महिना',\n        MM : '%d महिने',\n        y : 'एक वर्ष',\n        yy : '%d वर्षे'\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /रात्री|सकाळी|दुपारी|सायंकाळी/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'रात्री') {\n            return hour < 4 ? hour : hour + 12;\n        } else if (meridiem === 'सकाळी') {\n            return hour;\n        } else if (meridiem === 'दुपारी') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'सायंकाळी') {\n            return hour + 12;\n        }\n    },\n    meridiem: function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'रात्री';\n        } else if (hour < 10) {\n            return 'सकाळी';\n        } else if (hour < 17) {\n            return 'दुपारी';\n        } else if (hour < 20) {\n            return 'सायंकाळी';\n        } else {\n            return 'रात्री';\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/ms-my.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('ms-my', {\n    months : 'Januari_Februari_Mac_April_Mei_Jun_Julai_Ogos_September_Oktober_November_Disember'.split('_'),\n    monthsShort : 'Jan_Feb_Mac_Apr_Mei_Jun_Jul_Ogs_Sep_Okt_Nov_Dis'.split('_'),\n    weekdays : 'Ahad_Isnin_Selasa_Rabu_Khamis_Jumaat_Sabtu'.split('_'),\n    weekdaysShort : 'Ahd_Isn_Sel_Rab_Kha_Jum_Sab'.split('_'),\n    weekdaysMin : 'Ah_Is_Sl_Rb_Km_Jm_Sb'.split('_'),\n    longDateFormat : {\n        LT : 'HH.mm',\n        LTS : 'LT.ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY [pukul] LT',\n        LLLL : 'dddd, D MMMM YYYY [pukul] LT'\n    },\n    meridiemParse: /pagi|tengahari|petang|malam/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'pagi') {\n            return hour;\n        } else if (meridiem === 'tengahari') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === 'petang' || meridiem === 'malam') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hours, minutes, isLower) {\n        if (hours < 11) {\n            return 'pagi';\n        } else if (hours < 15) {\n            return 'tengahari';\n        } else if (hours < 19) {\n            return 'petang';\n        } else {\n            return 'malam';\n        }\n    },\n    calendar : {\n        sameDay : '[Hari ini pukul] LT',\n        nextDay : '[Esok pukul] LT',\n        nextWeek : 'dddd [pukul] LT',\n        lastDay : '[Kelmarin pukul] LT',\n        lastWeek : 'dddd [lepas pukul] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'dalam %s',\n        past : '%s yang lepas',\n        s : 'beberapa saat',\n        m : 'seminit',\n        mm : '%d minit',\n        h : 'sejam',\n        hh : '%d jam',\n        d : 'sehari',\n        dd : '%d hari',\n        M : 'sebulan',\n        MM : '%d bulan',\n        y : 'setahun',\n        yy : '%d tahun'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/my.js",
    "content": "\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '၁',\n    '2': '၂',\n    '3': '၃',\n    '4': '၄',\n    '5': '၅',\n    '6': '၆',\n    '7': '၇',\n    '8': '၈',\n    '9': '၉',\n    '0': '၀'\n}, numberMap = {\n    '၁': '1',\n    '၂': '2',\n    '၃': '3',\n    '၄': '4',\n    '၅': '5',\n    '၆': '6',\n    '၇': '7',\n    '၈': '8',\n    '၉': '9',\n    '၀': '0'\n};\n\nexport default moment.defineLocale('my', {\n    months: 'ဇန်နဝါရီ_ဖေဖော်ဝါရီ_မတ်_ဧပြီ_မေ_ဇွန်_ဇူလိုင်_သြဂုတ်_စက်တင်ဘာ_အောက်တိုဘာ_နိုဝင်ဘာ_ဒီဇင်ဘာ'.split('_'),\n    monthsShort: 'ဇန်_ဖေ_မတ်_ပြီ_မေ_ဇွန်_လိုင်_သြ_စက်_အောက်_နို_ဒီ'.split('_'),\n    weekdays: 'တနင်္ဂနွေ_တနင်္လာ_အင်္ဂါ_ဗုဒ္ဓဟူး_ကြာသပတေး_သောကြာ_စနေ'.split('_'),\n    weekdaysShort: 'နွေ_လာ_င်္ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n    weekdaysMin: 'နွေ_လာ_င်္ဂါ_ဟူး_ကြာ_သော_နေ'.split('_'),\n    longDateFormat: {\n        LT: 'HH:mm',\n        LTS: 'HH:mm:ss',\n        L: 'DD/MM/YYYY',\n        LL: 'D MMMM YYYY',\n        LLL: 'D MMMM YYYY LT',\n        LLLL: 'dddd D MMMM YYYY LT'\n    },\n    calendar: {\n        sameDay: '[ယနေ.] LT [မှာ]',\n        nextDay: '[မနက်ဖြန်] LT [မှာ]',\n        nextWeek: 'dddd LT [မှာ]',\n        lastDay: '[မနေ.က] LT [မှာ]',\n        lastWeek: '[ပြီးခဲ့သော] dddd LT [မှာ]',\n        sameElse: 'L'\n    },\n    relativeTime: {\n        future: 'လာမည့် %s မှာ',\n        past: 'လွန်ခဲ့သော %s က',\n        s: 'စက္ကန်.အနည်းငယ်',\n        m: 'တစ်မိနစ်',\n        mm: '%d မိနစ်',\n        h: 'တစ်နာရီ',\n        hh: '%d နာရီ',\n        d: 'တစ်ရက်',\n        dd: '%d ရက်',\n        M: 'တစ်လ',\n        MM: '%d လ',\n        y: 'တစ်နှစ်',\n        yy: '%d နှစ်'\n    },\n    preparse: function (string) {\n        return string.replace(/[၁၂၃၄၅၆၇၈၉၀]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    week: {\n        dow: 1, // Monday is the first day of the week.\n        doy: 4 // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/nb.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('nb', {\n    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n    weekdays : 'søndag_mandag_tirsdag_onsdag_torsdag_fredag_lørdag'.split('_'),\n    weekdaysShort : 'søn_man_tirs_ons_tors_fre_lør'.split('_'),\n    weekdaysMin : 'sø_ma_ti_on_to_fr_lø'.split('_'),\n    longDateFormat : {\n        LT : 'H.mm',\n        LTS : 'LT.ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY [kl.] LT',\n        LLLL : 'dddd D. MMMM YYYY [kl.] LT'\n    },\n    calendar : {\n        sameDay: '[i dag kl.] LT',\n        nextDay: '[i morgen kl.] LT',\n        nextWeek: 'dddd [kl.] LT',\n        lastDay: '[i går kl.] LT',\n        lastWeek: '[forrige] dddd [kl.] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : 'for %s siden',\n        s : 'noen sekunder',\n        m : 'ett minutt',\n        mm : '%d minutter',\n        h : 'en time',\n        hh : '%d timer',\n        d : 'en dag',\n        dd : '%d dager',\n        M : 'en måned',\n        MM : '%d måneder',\n        y : 'ett år',\n        yy : '%d år'\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/ne.js",
    "content": "\nimport moment from '../moment';\n\nvar symbolMap = {\n    '1': '१',\n    '2': '२',\n    '3': '३',\n    '4': '४',\n    '5': '५',\n    '6': '६',\n    '7': '७',\n    '8': '८',\n    '9': '९',\n    '0': '०'\n},\nnumberMap = {\n    '१': '1',\n    '२': '2',\n    '३': '3',\n    '४': '4',\n    '५': '5',\n    '६': '6',\n    '७': '7',\n    '८': '8',\n    '९': '9',\n    '०': '0'\n};\n\nexport default moment.defineLocale('ne', {\n    months : 'जनवरी_फेब्रुवरी_मार्च_अप्रिल_मई_जुन_जुलाई_अगष्ट_सेप्टेम्बर_अक्टोबर_नोभेम्बर_डिसेम्बर'.split('_'),\n    monthsShort : 'जन._फेब्रु._मार्च_अप्रि._मई_जुन_जुलाई._अग._सेप्ट._अक्टो._नोभे._डिसे.'.split('_'),\n    weekdays : 'आइतबार_सोमबार_मङ्गलबार_बुधबार_बिहिबार_शुक्रबार_शनिबार'.split('_'),\n    weekdaysShort : 'आइत._सोम._मङ्गल._बुध._बिहि._शुक्र._शनि.'.split('_'),\n    weekdaysMin : 'आइ._सो._मङ्_बु._बि._शु._श.'.split('_'),\n    longDateFormat : {\n        LT : 'Aको h:mm बजे',\n        LTS : 'Aको h:mm:ss बजे',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, LT',\n        LLLL : 'dddd, D MMMM YYYY, LT'\n    },\n    preparse: function (string) {\n        return string.replace(/[१२३४५६७८९०]/g, function (match) {\n            return numberMap[match];\n        });\n    },\n    postformat: function (string) {\n        return string.replace(/\\d/g, function (match) {\n            return symbolMap[match];\n        });\n    },\n    meridiemParse: /राती|बिहान|दिउँसो|बेलुका|साँझ|राती/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'राती') {\n            return hour < 3 ? hour : hour + 12;\n        } else if (meridiem === 'बिहान') {\n            return hour;\n        } else if (meridiem === 'दिउँसो') {\n            return hour >= 10 ? hour : hour + 12;\n        } else if (meridiem === 'बेलुका' || meridiem === 'साँझ') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 3) {\n            return 'राती';\n        } else if (hour < 10) {\n            return 'बिहान';\n        } else if (hour < 15) {\n            return 'दिउँसो';\n        } else if (hour < 18) {\n            return 'बेलुका';\n        } else if (hour < 20) {\n            return 'साँझ';\n        } else {\n            return 'राती';\n        }\n    },\n    calendar : {\n        sameDay : '[आज] LT',\n        nextDay : '[भोली] LT',\n        nextWeek : '[आउँदो] dddd[,] LT',\n        lastDay : '[हिजो] LT',\n        lastWeek : '[गएको] dddd[,] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%sमा',\n        past : '%s अगाडी',\n        s : 'केही समय',\n        m : 'एक मिनेट',\n        mm : '%d मिनेट',\n        h : 'एक घण्टा',\n        hh : '%d घण्टा',\n        d : 'एक दिन',\n        dd : '%d दिन',\n        M : 'एक महिना',\n        MM : '%d महिना',\n        y : 'एक बर्ष',\n        yy : '%d बर्ष'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/nl.js",
    "content": "\nimport moment from '../moment';\n\nvar monthsShortWithDots = 'jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.'.split('_'),\n    monthsShortWithoutDots = 'jan_feb_mrt_apr_mei_jun_jul_aug_sep_okt_nov_dec'.split('_');\n\nexport default moment.defineLocale('nl', {\n    months : 'januari_februari_maart_april_mei_juni_juli_augustus_september_oktober_november_december'.split('_'),\n    monthsShort : function (m, format) {\n        if (/-MMM-/.test(format)) {\n            return monthsShortWithoutDots[m.month()];\n        } else {\n            return monthsShortWithDots[m.month()];\n        }\n    },\n    weekdays : 'zondag_maandag_dinsdag_woensdag_donderdag_vrijdag_zaterdag'.split('_'),\n    weekdaysShort : 'zo._ma._di._wo._do._vr._za.'.split('_'),\n    weekdaysMin : 'Zo_Ma_Di_Wo_Do_Vr_Za'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD-MM-YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay: '[vandaag om] LT',\n        nextDay: '[morgen om] LT',\n        nextWeek: 'dddd [om] LT',\n        lastDay: '[gisteren om] LT',\n        lastWeek: '[afgelopen] dddd [om] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'over %s',\n        past : '%s geleden',\n        s : 'een paar seconden',\n        m : 'één minuut',\n        mm : '%d minuten',\n        h : 'één uur',\n        hh : '%d uur',\n        d : 'één dag',\n        dd : '%d dagen',\n        M : 'één maand',\n        MM : '%d maanden',\n        y : 'één jaar',\n        yy : '%d jaar'\n    },\n    ordinalParse: /\\d{1,2}(ste|de)/,\n    ordinal : function (number) {\n        return number + ((number === 1 || number === 8 || number >= 20) ? 'ste' : 'de');\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/nn.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('nn', {\n    months : 'januar_februar_mars_april_mai_juni_juli_august_september_oktober_november_desember'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_mai_jun_jul_aug_sep_okt_nov_des'.split('_'),\n    weekdays : 'sundag_måndag_tysdag_onsdag_torsdag_fredag_laurdag'.split('_'),\n    weekdaysShort : 'sun_mån_tys_ons_tor_fre_lau'.split('_'),\n    weekdaysMin : 'su_må_ty_on_to_fr_lø'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay: '[I dag klokka] LT',\n        nextDay: '[I morgon klokka] LT',\n        nextWeek: 'dddd [klokka] LT',\n        lastDay: '[I går klokka] LT',\n        lastWeek: '[Føregåande] dddd [klokka] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : 'for %s sidan',\n        s : 'nokre sekund',\n        m : 'eit minutt',\n        mm : '%d minutt',\n        h : 'ein time',\n        hh : '%d timar',\n        d : 'ein dag',\n        dd : '%d dagar',\n        M : 'ein månad',\n        MM : '%d månader',\n        y : 'eit år',\n        yy : '%d år'\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/pl.js",
    "content": "\nimport moment from '../moment';\n\nvar monthsNominative = 'styczeń_luty_marzec_kwiecień_maj_czerwiec_lipiec_sierpień_wrzesień_październik_listopad_grudzień'.split('_'),\n    monthsSubjective = 'stycznia_lutego_marca_kwietnia_maja_czerwca_lipca_sierpnia_września_października_listopada_grudnia'.split('_');\nfunction plural(n) {\n    return (n % 10 < 5) && (n % 10 > 1) && ((~~(n / 10) % 10) !== 1);\n}\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n    case 'm':\n        return withoutSuffix ? 'minuta' : 'minutę';\n    case 'mm':\n        return result + (plural(number) ? 'minuty' : 'minut');\n    case 'h':\n        return withoutSuffix  ? 'godzina'  : 'godzinę';\n    case 'hh':\n        return result + (plural(number) ? 'godziny' : 'godzin');\n    case 'MM':\n        return result + (plural(number) ? 'miesiące' : 'miesięcy');\n    case 'yy':\n        return result + (plural(number) ? 'lata' : 'lat');\n    }\n}\n\nexport default moment.defineLocale('pl', {\n    months : function (momentToFormat, format) {\n        if (/D MMMM/.test(format)) {\n            return monthsSubjective[momentToFormat.month()];\n        } else {\n            return monthsNominative[momentToFormat.month()];\n        }\n    },\n    monthsShort : 'sty_lut_mar_kwi_maj_cze_lip_sie_wrz_paź_lis_gru'.split('_'),\n    weekdays : 'niedziela_poniedziałek_wtorek_środa_czwartek_piątek_sobota'.split('_'),\n    weekdaysShort : 'nie_pon_wt_śr_czw_pt_sb'.split('_'),\n    weekdaysMin : 'N_Pn_Wt_Śr_Cz_Pt_So'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd, D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay: '[Dziś o] LT',\n        nextDay: '[Jutro o] LT',\n        nextWeek: '[W] dddd [o] LT',\n        lastDay: '[Wczoraj o] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n            case 0:\n                return '[W zeszłą niedzielę o] LT';\n            case 3:\n                return '[W zeszłą środę o] LT';\n            case 6:\n                return '[W zeszłą sobotę o] LT';\n            default:\n                return '[W zeszły] dddd [o] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : '%s temu',\n        s : 'kilka sekund',\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : '1 dzień',\n        dd : '%d dni',\n        M : 'miesiąc',\n        MM : translate,\n        y : 'rok',\n        yy : translate\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/pt-br.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('pt-br', {\n    months : 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split('_'),\n    monthsShort : 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'),\n    weekdays : 'domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado'.split('_'),\n    weekdaysShort : 'dom_seg_ter_qua_qui_sex_sáb'.split('_'),\n    weekdaysMin : 'dom_2ª_3ª_4ª_5ª_6ª_sáb'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY [às] LT',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY [às] LT'\n    },\n    calendar : {\n        sameDay: '[Hoje às] LT',\n        nextDay: '[Amanhã às] LT',\n        nextWeek: 'dddd [às] LT',\n        lastDay: '[Ontem às] LT',\n        lastWeek: function () {\n            return (this.day() === 0 || this.day() === 6) ?\n                '[Último] dddd [às] LT' : // Saturday + Sunday\n                '[Última] dddd [às] LT'; // Monday - Friday\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'em %s',\n        past : '%s atrás',\n        s : 'segundos',\n        m : 'um minuto',\n        mm : '%d minutos',\n        h : 'uma hora',\n        hh : '%d horas',\n        d : 'um dia',\n        dd : '%d dias',\n        M : 'um mês',\n        MM : '%d meses',\n        y : 'um ano',\n        yy : '%d anos'\n    },\n    ordinalParse: /\\d{1,2}º/,\n    ordinal : '%dº'\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/pt.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('pt', {\n    months : 'janeiro_fevereiro_março_abril_maio_junho_julho_agosto_setembro_outubro_novembro_dezembro'.split('_'),\n    monthsShort : 'jan_fev_mar_abr_mai_jun_jul_ago_set_out_nov_dez'.split('_'),\n    weekdays : 'domingo_segunda-feira_terça-feira_quarta-feira_quinta-feira_sexta-feira_sábado'.split('_'),\n    weekdaysShort : 'dom_seg_ter_qua_qui_sex_sáb'.split('_'),\n    weekdaysMin : 'dom_2ª_3ª_4ª_5ª_6ª_sáb'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D [de] MMMM [de] YYYY',\n        LLL : 'D [de] MMMM [de] YYYY LT',\n        LLLL : 'dddd, D [de] MMMM [de] YYYY LT'\n    },\n    calendar : {\n        sameDay: '[Hoje às] LT',\n        nextDay: '[Amanhã às] LT',\n        nextWeek: 'dddd [às] LT',\n        lastDay: '[Ontem às] LT',\n        lastWeek: function () {\n            return (this.day() === 0 || this.day() === 6) ?\n                '[Último] dddd [às] LT' : // Saturday + Sunday\n                '[Última] dddd [às] LT'; // Monday - Friday\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'em %s',\n        past : 'há %s',\n        s : 'segundos',\n        m : 'um minuto',\n        mm : '%d minutos',\n        h : 'uma hora',\n        hh : '%d horas',\n        d : 'um dia',\n        dd : '%d dias',\n        M : 'um mês',\n        MM : '%d meses',\n        y : 'um ano',\n        yy : '%d anos'\n    },\n    ordinalParse: /\\d{1,2}º/,\n    ordinal : '%dº',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/ro.js",
    "content": "\nimport moment from '../moment';\n\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n            'mm': 'minute',\n            'hh': 'ore',\n            'dd': 'zile',\n            'MM': 'luni',\n            'yy': 'ani'\n        },\n        separator = ' ';\n    if (number % 100 >= 20 || (number >= 100 && number % 100 === 0)) {\n        separator = ' de ';\n    }\n    return number + separator + format[key];\n}\n\nexport default moment.defineLocale('ro', {\n    months : 'ianuarie_februarie_martie_aprilie_mai_iunie_iulie_august_septembrie_octombrie_noiembrie_decembrie'.split('_'),\n    monthsShort : 'ian._febr._mart._apr._mai_iun._iul._aug._sept._oct._nov._dec.'.split('_'),\n    weekdays : 'duminică_luni_marți_miercuri_joi_vineri_sâmbătă'.split('_'),\n    weekdaysShort : 'Dum_Lun_Mar_Mie_Joi_Vin_Sâm'.split('_'),\n    weekdaysMin : 'Du_Lu_Ma_Mi_Jo_Vi_Sâ'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'LT:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY H:mm',\n        LLLL : 'dddd, D MMMM YYYY H:mm'\n    },\n    calendar : {\n        sameDay: '[azi la] LT',\n        nextDay: '[mâine la] LT',\n        nextWeek: 'dddd [la] LT',\n        lastDay: '[ieri la] LT',\n        lastWeek: '[fosta] dddd [la] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'peste %s',\n        past : '%s în urmă',\n        s : 'câteva secunde',\n        m : 'un minut',\n        mm : relativeTimeWithPlural,\n        h : 'o oră',\n        hh : relativeTimeWithPlural,\n        d : 'o zi',\n        dd : relativeTimeWithPlural,\n        M : 'o lună',\n        MM : relativeTimeWithPlural,\n        y : 'un an',\n        yy : relativeTimeWithPlural\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/ru.js",
    "content": "\nimport moment from '../moment';\n\nfunction plural(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n        'mm': withoutSuffix ? 'минута_минуты_минут' : 'минуту_минуты_минут',\n        'hh': 'час_часа_часов',\n        'dd': 'день_дня_дней',\n        'MM': 'месяц_месяца_месяцев',\n        'yy': 'год_года_лет'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'минута' : 'минуту';\n    }\n    else {\n        return number + ' ' + plural(format[key], +number);\n    }\n}\nfunction monthsCaseReplace(m, format) {\n    var months = {\n        'nominative': 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n        'accusative': 'января_февраля_марта_апреля_мая_июня_июля_августа_сентября_октября_ноября_декабря'.split('_')\n    },\n    nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n        'accusative' :\n        'nominative';\n    return months[nounCase][m.month()];\n}\nfunction monthsShortCaseReplace(m, format) {\n    var monthsShort = {\n        'nominative': 'янв_фев_март_апр_май_июнь_июль_авг_сен_окт_ноя_дек'.split('_'),\n        'accusative': 'янв_фев_мар_апр_мая_июня_июля_авг_сен_окт_ноя_дек'.split('_')\n    },\n    nounCase = (/D[oD]?(\\[[^\\[\\]]*\\]|\\s+)+MMMM?/).test(format) ?\n        'accusative' :\n        'nominative';\n    return monthsShort[nounCase][m.month()];\n}\nfunction weekdaysCaseReplace(m, format) {\n    var weekdays = {\n        'nominative': 'воскресенье_понедельник_вторник_среда_четверг_пятница_суббота'.split('_'),\n        'accusative': 'воскресенье_понедельник_вторник_среду_четверг_пятницу_субботу'.split('_')\n    },\n    nounCase = (/\\[ ?[Вв] ?(?:прошлую|следующую|эту)? ?\\] ?dddd/).test(format) ?\n        'accusative' :\n        'nominative';\n    return weekdays[nounCase][m.day()];\n}\n\nexport default moment.defineLocale('ru', {\n    months : monthsCaseReplace,\n    monthsShort : monthsShortCaseReplace,\n    weekdays : weekdaysCaseReplace,\n    weekdaysShort : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n    weekdaysMin : 'вс_пн_вт_ср_чт_пт_сб'.split('_'),\n    monthsParse : [/^янв/i, /^фев/i, /^мар/i, /^апр/i, /^ма[й|я]/i, /^июн/i, /^июл/i, /^авг/i, /^сен/i, /^окт/i, /^ноя/i, /^дек/i],\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY г.',\n        LLL : 'D MMMM YYYY г., LT',\n        LLLL : 'dddd, D MMMM YYYY г., LT'\n    },\n    calendar : {\n        sameDay: '[Сегодня в] LT',\n        nextDay: '[Завтра в] LT',\n        lastDay: '[Вчера в] LT',\n        nextWeek: function () {\n            return this.day() === 2 ? '[Во] dddd [в] LT' : '[В] dddd [в] LT';\n        },\n        lastWeek: function (now) {\n            if (now.week() !== this.week()) {\n                switch (this.day()) {\n                case 0:\n                    return '[В прошлое] dddd [в] LT';\n                case 1:\n                case 2:\n                case 4:\n                    return '[В прошлый] dddd [в] LT';\n                case 3:\n                case 5:\n                case 6:\n                    return '[В прошлую] dddd [в] LT';\n                }\n            } else {\n                if (this.day() === 2) {\n                    return '[Во] dddd [в] LT';\n                } else {\n                    return '[В] dddd [в] LT';\n                }\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'через %s',\n        past : '%s назад',\n        s : 'несколько секунд',\n        m : relativeTimeWithPlural,\n        mm : relativeTimeWithPlural,\n        h : 'час',\n        hh : relativeTimeWithPlural,\n        d : 'день',\n        dd : relativeTimeWithPlural,\n        M : 'месяц',\n        MM : relativeTimeWithPlural,\n        y : 'год',\n        yy : relativeTimeWithPlural\n    },\n    meridiemParse: /ночи|утра|дня|вечера/i,\n    isPM : function (input) {\n        return /^(дня|вечера)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночи';\n        } else if (hour < 12) {\n            return 'утра';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечера';\n        }\n    },\n    ordinalParse: /\\d{1,2}-(й|го|я)/,\n    ordinal: function (number, period) {\n        switch (period) {\n        case 'M':\n        case 'd':\n        case 'DDD':\n            return number + '-й';\n        case 'D':\n            return number + '-го';\n        case 'w':\n        case 'W':\n            return number + '-я';\n        default:\n            return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/sk.js",
    "content": "\nimport moment from '../moment';\n\nvar months = 'január_február_marec_apríl_máj_jún_júl_august_september_október_november_december'.split('_'),\n    monthsShort = 'jan_feb_mar_apr_máj_jún_júl_aug_sep_okt_nov_dec'.split('_');\nfunction plural(n) {\n    return (n > 1) && (n < 5);\n}\nfunction translate(number, withoutSuffix, key, isFuture) {\n    var result = number + ' ';\n    switch (key) {\n    case 's':  // a few seconds / in a few seconds / a few seconds ago\n        return (withoutSuffix || isFuture) ? 'pár sekúnd' : 'pár sekundami';\n    case 'm':  // a minute / in a minute / a minute ago\n        return withoutSuffix ? 'minúta' : (isFuture ? 'minútu' : 'minútou');\n    case 'mm': // 9 minutes / in 9 minutes / 9 minutes ago\n        if (withoutSuffix || isFuture) {\n            return result + (plural(number) ? 'minúty' : 'minút');\n        } else {\n            return result + 'minútami';\n        }\n        break;\n    case 'h':  // an hour / in an hour / an hour ago\n        return withoutSuffix ? 'hodina' : (isFuture ? 'hodinu' : 'hodinou');\n    case 'hh': // 9 hours / in 9 hours / 9 hours ago\n        if (withoutSuffix || isFuture) {\n            return result + (plural(number) ? 'hodiny' : 'hodín');\n        } else {\n            return result + 'hodinami';\n        }\n        break;\n    case 'd':  // a day / in a day / a day ago\n        return (withoutSuffix || isFuture) ? 'deň' : 'dňom';\n    case 'dd': // 9 days / in 9 days / 9 days ago\n        if (withoutSuffix || isFuture) {\n            return result + (plural(number) ? 'dni' : 'dní');\n        } else {\n            return result + 'dňami';\n        }\n        break;\n    case 'M':  // a month / in a month / a month ago\n        return (withoutSuffix || isFuture) ? 'mesiac' : 'mesiacom';\n    case 'MM': // 9 months / in 9 months / 9 months ago\n        if (withoutSuffix || isFuture) {\n            return result + (plural(number) ? 'mesiace' : 'mesiacov');\n        } else {\n            return result + 'mesiacmi';\n        }\n        break;\n    case 'y':  // a year / in a year / a year ago\n        return (withoutSuffix || isFuture) ? 'rok' : 'rokom';\n    case 'yy': // 9 years / in 9 years / 9 years ago\n        if (withoutSuffix || isFuture) {\n            return result + (plural(number) ? 'roky' : 'rokov');\n        } else {\n            return result + 'rokmi';\n        }\n        break;\n    }\n}\n\nexport default moment.defineLocale('sk', {\n    months : months,\n    monthsShort : monthsShort,\n    monthsParse : (function (months, monthsShort) {\n        var i, _monthsParse = [];\n        for (i = 0; i < 12; i++) {\n            _monthsParse[i] = new RegExp('^' + months[i] + '$|^' + monthsShort[i] + '$', 'i');\n        }\n        return _monthsParse;\n    }(months, monthsShort)),\n    weekdays : 'nedeľa_pondelok_utorok_streda_štvrtok_piatok_sobota'.split('_'),\n    weekdaysShort : 'ne_po_ut_st_št_pi_so'.split('_'),\n    weekdaysMin : 'ne_po_ut_st_št_pi_so'.split('_'),\n    longDateFormat : {\n        LT: 'H:mm',\n        LTS : 'LT:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY LT',\n        LLLL : 'dddd D. MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay: '[dnes o] LT',\n        nextDay: '[zajtra o] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n            case 0:\n                return '[v nedeľu o] LT';\n            case 1:\n            case 2:\n                return '[v] dddd [o] LT';\n            case 3:\n                return '[v stredu o] LT';\n            case 4:\n                return '[vo štvrtok o] LT';\n            case 5:\n                return '[v piatok o] LT';\n            case 6:\n                return '[v sobotu o] LT';\n            }\n        },\n        lastDay: '[včera o] LT',\n        lastWeek: function () {\n            switch (this.day()) {\n            case 0:\n                return '[minulú nedeľu o] LT';\n            case 1:\n            case 2:\n                return '[minulý] dddd [o] LT';\n            case 3:\n                return '[minulú stredu o] LT';\n            case 4:\n            case 5:\n                return '[minulý] dddd [o] LT';\n            case 6:\n                return '[minulú sobotu o] LT';\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past : 'pred %s',\n        s : translate,\n        m : translate,\n        mm : translate,\n        h : translate,\n        hh : translate,\n        d : translate,\n        dd : translate,\n        M : translate,\n        MM : translate,\n        y : translate,\n        yy : translate\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/sl.js",
    "content": "\nimport moment from '../moment';\n\nfunction translate(number, withoutSuffix, key) {\n    var result = number + ' ';\n    switch (key) {\n    case 'm':\n        return withoutSuffix ? 'ena minuta' : 'eno minuto';\n    case 'mm':\n        if (number === 1) {\n            result += 'minuta';\n        } else if (number === 2) {\n            result += 'minuti';\n        } else if (number === 3 || number === 4) {\n            result += 'minute';\n        } else {\n            result += 'minut';\n        }\n        return result;\n    case 'h':\n        return withoutSuffix ? 'ena ura' : 'eno uro';\n    case 'hh':\n        if (number === 1) {\n            result += 'ura';\n        } else if (number === 2) {\n            result += 'uri';\n        } else if (number === 3 || number === 4) {\n            result += 'ure';\n        } else {\n            result += 'ur';\n        }\n        return result;\n    case 'dd':\n        if (number === 1) {\n            result += 'dan';\n        } else {\n            result += 'dni';\n        }\n        return result;\n    case 'MM':\n        if (number === 1) {\n            result += 'mesec';\n        } else if (number === 2) {\n            result += 'meseca';\n        } else if (number === 3 || number === 4) {\n            result += 'mesece';\n        } else {\n            result += 'mesecev';\n        }\n        return result;\n    case 'yy':\n        if (number === 1) {\n            result += 'leto';\n        } else if (number === 2) {\n            result += 'leti';\n        } else if (number === 3 || number === 4) {\n            result += 'leta';\n        } else {\n            result += 'let';\n        }\n        return result;\n    }\n}\n\nexport default moment.defineLocale('sl', {\n    months : 'januar_februar_marec_april_maj_junij_julij_avgust_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan._feb._mar._apr._maj._jun._jul._avg._sep._okt._nov._dec.'.split('_'),\n    weekdays : 'nedelja_ponedeljek_torek_sreda_četrtek_petek_sobota'.split('_'),\n    weekdaysShort : 'ned._pon._tor._sre._čet._pet._sob.'.split('_'),\n    weekdaysMin : 'ne_po_to_sr_če_pe_so'.split('_'),\n    longDateFormat : {\n        LT : 'H:mm',\n        LTS : 'LT:ss',\n        L : 'DD. MM. YYYY',\n        LL : 'D. MMMM YYYY',\n        LLL : 'D. MMMM YYYY LT',\n        LLLL : 'dddd, D. MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay  : '[danes ob] LT',\n        nextDay  : '[jutri ob] LT',\n        nextWeek : function () {\n            switch (this.day()) {\n            case 0:\n                return '[v] [nedeljo] [ob] LT';\n            case 3:\n                return '[v] [sredo] [ob] LT';\n            case 6:\n                return '[v] [soboto] [ob] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[v] dddd [ob] LT';\n            }\n        },\n        lastDay  : '[včeraj ob] LT',\n        lastWeek : function () {\n            switch (this.day()) {\n            case 0:\n            case 3:\n            case 6:\n                return '[prejšnja] dddd [ob] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[prejšnji] dddd [ob] LT';\n            }\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'čez %s',\n        past   : '%s nazaj',\n        s      : 'nekaj sekund',\n        m      : translate,\n        mm     : translate,\n        h      : translate,\n        hh     : translate,\n        d      : 'en dan',\n        dd     : translate,\n        M      : 'en mesec',\n        MM     : translate,\n        y      : 'eno leto',\n        yy     : translate\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/sq.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('sq', {\n    months : 'Janar_Shkurt_Mars_Prill_Maj_Qershor_Korrik_Gusht_Shtator_Tetor_Nëntor_Dhjetor'.split('_'),\n    monthsShort : 'Jan_Shk_Mar_Pri_Maj_Qer_Kor_Gus_Sht_Tet_Nën_Dhj'.split('_'),\n    weekdays : 'E Diel_E Hënë_E Martë_E Mërkurë_E Enjte_E Premte_E Shtunë'.split('_'),\n    weekdaysShort : 'Die_Hën_Mar_Mër_Enj_Pre_Sht'.split('_'),\n    weekdaysMin : 'D_H_Ma_Më_E_P_Sh'.split('_'),\n    meridiemParse: /PD|MD/,\n    isPM: function (input) {\n        return input.charAt(0) === 'M';\n    },\n    meridiem : function (hours, minutes, isLower) {\n        return hours < 12 ? 'PD' : 'MD';\n    },\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd, D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay : '[Sot në] LT',\n        nextDay : '[Nesër në] LT',\n        nextWeek : 'dddd [në] LT',\n        lastDay : '[Dje në] LT',\n        lastWeek : 'dddd [e kaluar në] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'në %s',\n        past : '%s më parë',\n        s : 'disa sekonda',\n        m : 'një minutë',\n        mm : '%d minuta',\n        h : 'një orë',\n        hh : '%d orë',\n        d : 'një ditë',\n        dd : '%d ditë',\n        M : 'një muaj',\n        MM : '%d muaj',\n        y : 'një vit',\n        yy : '%d vite'\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/sr-cyrl.js",
    "content": "\nimport moment from '../moment';\n\nvar translator = {\n    words: { //Different grammatical cases\n        m: ['један минут', 'једне минуте'],\n        mm: ['минут', 'минуте', 'минута'],\n        h: ['један сат', 'једног сата'],\n        hh: ['сат', 'сата', 'сати'],\n        dd: ['дан', 'дана', 'дана'],\n        MM: ['месец', 'месеца', 'месеци'],\n        yy: ['година', 'године', 'година']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nexport default moment.defineLocale('sr-cyrl', {\n    months: ['јануар', 'фебруар', 'март', 'април', 'мај', 'јун', 'јул', 'август', 'септембар', 'октобар', 'новембар', 'децембар'],\n    monthsShort: ['јан.', 'феб.', 'мар.', 'апр.', 'мај', 'јун', 'јул', 'авг.', 'сеп.', 'окт.', 'нов.', 'дец.'],\n    weekdays: ['недеља', 'понедељак', 'уторак', 'среда', 'четвртак', 'петак', 'субота'],\n    weekdaysShort: ['нед.', 'пон.', 'уто.', 'сре.', 'чет.', 'пет.', 'суб.'],\n    weekdaysMin: ['не', 'по', 'ут', 'ср', 'че', 'пе', 'су'],\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'LT:ss',\n        L: 'DD. MM. YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY LT',\n        LLLL: 'dddd, D. MMMM YYYY LT'\n    },\n    calendar: {\n        sameDay: '[данас у] LT',\n        nextDay: '[сутра у] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n            case 0:\n                return '[у] [недељу] [у] LT';\n            case 3:\n                return '[у] [среду] [у] LT';\n            case 6:\n                return '[у] [суботу] [у] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[у] dddd [у] LT';\n            }\n        },\n        lastDay  : '[јуче у] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[прошле] [недеље] [у] LT',\n                '[прошлог] [понедељка] [у] LT',\n                '[прошлог] [уторка] [у] LT',\n                '[прошле] [среде] [у] LT',\n                '[прошлог] [четвртка] [у] LT',\n                '[прошлог] [петка] [у] LT',\n                '[прошле] [суботе] [у] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'за %s',\n        past   : 'пре %s',\n        s      : 'неколико секунди',\n        m      : translator.translate,\n        mm     : translator.translate,\n        h      : translator.translate,\n        hh     : translator.translate,\n        d      : 'дан',\n        dd     : translator.translate,\n        M      : 'месец',\n        MM     : translator.translate,\n        y      : 'годину',\n        yy     : translator.translate\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/sr.js",
    "content": "\nimport moment from '../moment';\n\nvar translator = {\n    words: { //Different grammatical cases\n        m: ['jedan minut', 'jedne minute'],\n        mm: ['minut', 'minute', 'minuta'],\n        h: ['jedan sat', 'jednog sata'],\n        hh: ['sat', 'sata', 'sati'],\n        dd: ['dan', 'dana', 'dana'],\n        MM: ['mesec', 'meseca', 'meseci'],\n        yy: ['godina', 'godine', 'godina']\n    },\n    correctGrammaticalCase: function (number, wordKey) {\n        return number === 1 ? wordKey[0] : (number >= 2 && number <= 4 ? wordKey[1] : wordKey[2]);\n    },\n    translate: function (number, withoutSuffix, key) {\n        var wordKey = translator.words[key];\n        if (key.length === 1) {\n            return withoutSuffix ? wordKey[0] : wordKey[1];\n        } else {\n            return number + ' ' + translator.correctGrammaticalCase(number, wordKey);\n        }\n    }\n};\n\nexport default moment.defineLocale('sr', {\n    months: ['januar', 'februar', 'mart', 'april', 'maj', 'jun', 'jul', 'avgust', 'septembar', 'oktobar', 'novembar', 'decembar'],\n    monthsShort: ['jan.', 'feb.', 'mar.', 'apr.', 'maj', 'jun', 'jul', 'avg.', 'sep.', 'okt.', 'nov.', 'dec.'],\n    weekdays: ['nedelja', 'ponedeljak', 'utorak', 'sreda', 'četvrtak', 'petak', 'subota'],\n    weekdaysShort: ['ned.', 'pon.', 'uto.', 'sre.', 'čet.', 'pet.', 'sub.'],\n    weekdaysMin: ['ne', 'po', 'ut', 'sr', 'če', 'pe', 'su'],\n    longDateFormat: {\n        LT: 'H:mm',\n        LTS : 'LT:ss',\n        L: 'DD. MM. YYYY',\n        LL: 'D. MMMM YYYY',\n        LLL: 'D. MMMM YYYY LT',\n        LLLL: 'dddd, D. MMMM YYYY LT'\n    },\n    calendar: {\n        sameDay: '[danas u] LT',\n        nextDay: '[sutra u] LT',\n        nextWeek: function () {\n            switch (this.day()) {\n            case 0:\n                return '[u] [nedelju] [u] LT';\n            case 3:\n                return '[u] [sredu] [u] LT';\n            case 6:\n                return '[u] [subotu] [u] LT';\n            case 1:\n            case 2:\n            case 4:\n            case 5:\n                return '[u] dddd [u] LT';\n            }\n        },\n        lastDay  : '[juče u] LT',\n        lastWeek : function () {\n            var lastWeekDays = [\n                '[prošle] [nedelje] [u] LT',\n                '[prošlog] [ponedeljka] [u] LT',\n                '[prošlog] [utorka] [u] LT',\n                '[prošle] [srede] [u] LT',\n                '[prošlog] [četvrtka] [u] LT',\n                '[prošlog] [petka] [u] LT',\n                '[prošle] [subote] [u] LT'\n            ];\n            return lastWeekDays[this.day()];\n        },\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'za %s',\n        past   : 'pre %s',\n        s      : 'nekoliko sekundi',\n        m      : translator.translate,\n        mm     : translator.translate,\n        h      : translator.translate,\n        hh     : translator.translate,\n        d      : 'dan',\n        dd     : translator.translate,\n        M      : 'mesec',\n        MM     : translator.translate,\n        y      : 'godinu',\n        yy     : translator.translate\n    },\n    ordinalParse: /\\d{1,2}\\./,\n    ordinal : '%d.',\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/sv.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('sv', {\n    months : 'januari_februari_mars_april_maj_juni_juli_augusti_september_oktober_november_december'.split('_'),\n    monthsShort : 'jan_feb_mar_apr_maj_jun_jul_aug_sep_okt_nov_dec'.split('_'),\n    weekdays : 'söndag_måndag_tisdag_onsdag_torsdag_fredag_lördag'.split('_'),\n    weekdaysShort : 'sön_mån_tis_ons_tor_fre_lör'.split('_'),\n    weekdaysMin : 'sö_må_ti_on_to_fr_lö'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'YYYY-MM-DD',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay: '[Idag] LT',\n        nextDay: '[Imorgon] LT',\n        lastDay: '[Igår] LT',\n        nextWeek: 'dddd LT',\n        lastWeek: '[Förra] dddd[en] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'om %s',\n        past : 'för %s sedan',\n        s : 'några sekunder',\n        m : 'en minut',\n        mm : '%d minuter',\n        h : 'en timme',\n        hh : '%d timmar',\n        d : 'en dag',\n        dd : '%d dagar',\n        M : 'en månad',\n        MM : '%d månader',\n        y : 'ett år',\n        yy : '%d år'\n    },\n    ordinalParse: /\\d{1,2}(e|a)/,\n    ordinal : function (number) {\n        var b = number % 10,\n            output = (~~(number % 100 / 10) === 1) ? 'e' :\n            (b === 1) ? 'a' :\n            (b === 2) ? 'a' :\n            (b === 3) ? 'e' : 'e';\n        return number + output;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/ta.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('ta', {\n    months : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n    monthsShort : 'ஜனவரி_பிப்ரவரி_மார்ச்_ஏப்ரல்_மே_ஜூன்_ஜூலை_ஆகஸ்ட்_செப்டெம்பர்_அக்டோபர்_நவம்பர்_டிசம்பர்'.split('_'),\n    weekdays : 'ஞாயிற்றுக்கிழமை_திங்கட்கிழமை_செவ்வாய்கிழமை_புதன்கிழமை_வியாழக்கிழமை_வெள்ளிக்கிழமை_சனிக்கிழமை'.split('_'),\n    weekdaysShort : 'ஞாயிறு_திங்கள்_செவ்வாய்_புதன்_வியாழன்_வெள்ளி_சனி'.split('_'),\n    weekdaysMin : 'ஞா_தி_செ_பு_வி_வெ_ச'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY, LT',\n        LLLL : 'dddd, D MMMM YYYY, LT'\n    },\n    calendar : {\n        sameDay : '[இன்று] LT',\n        nextDay : '[நாளை] LT',\n        nextWeek : 'dddd, LT',\n        lastDay : '[நேற்று] LT',\n        lastWeek : '[கடந்த வாரம்] dddd, LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s இல்',\n        past : '%s முன்',\n        s : 'ஒரு சில விநாடிகள்',\n        m : 'ஒரு நிமிடம்',\n        mm : '%d நிமிடங்கள்',\n        h : 'ஒரு மணி நேரம்',\n        hh : '%d மணி நேரம்',\n        d : 'ஒரு நாள்',\n        dd : '%d நாட்கள்',\n        M : 'ஒரு மாதம்',\n        MM : '%d மாதங்கள்',\n        y : 'ஒரு வருடம்',\n        yy : '%d ஆண்டுகள்'\n    },\n    ordinalParse: /\\d{1,2}வது/,\n    ordinal : function (number) {\n        return number + 'வது';\n    },\n    meridiemParse: /யாமம்|வைகறை|காலை|நண்பகல்|எற்பாடு|மாலை/,\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 2) {\n            return ' யாமம்';\n        } else if (hour < 6) {\n            return ' வைகறை';  // வைகறை\n        } else if (hour < 10) {\n            return ' காலை'; // காலை\n        } else if (hour < 14) {\n            return ' நண்பகல்'; // நண்பகல்\n        } else if (hour < 18) {\n            return ' எற்பாடு'; // எற்பாடு\n        } else if (hour < 22) {\n            return ' மாலை'; // மாலை\n        } else {\n            return ' யாமம்';\n        }\n    },\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === 'யாமம்') {\n            return hour < 2 ? hour : hour + 12;\n        } else if (meridiem === 'வைகறை' || meridiem === 'காலை') {\n            return hour;\n        } else if (meridiem === 'நண்பகல்') {\n            return hour >= 10 ? hour : hour + 12;\n        } else {\n            return hour + 12;\n        }\n    },\n    week : {\n        dow : 0, // Sunday is the first day of the week.\n        doy : 6  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/th.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('th', {\n    months : 'มกราคม_กุมภาพันธ์_มีนาคม_เมษายน_พฤษภาคม_มิถุนายน_กรกฎาคม_สิงหาคม_กันยายน_ตุลาคม_พฤศจิกายน_ธันวาคม'.split('_'),\n    monthsShort : 'มกรา_กุมภา_มีนา_เมษา_พฤษภา_มิถุนา_กรกฎา_สิงหา_กันยา_ตุลา_พฤศจิกา_ธันวา'.split('_'),\n    weekdays : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัสบดี_ศุกร์_เสาร์'.split('_'),\n    weekdaysShort : 'อาทิตย์_จันทร์_อังคาร_พุธ_พฤหัส_ศุกร์_เสาร์'.split('_'), // yes, three characters difference\n    weekdaysMin : 'อา._จ._อ._พ._พฤ._ศ._ส.'.split('_'),\n    longDateFormat : {\n        LT : 'H นาฬิกา m นาที',\n        LTS : 'LT s วินาที',\n        L : 'YYYY/MM/DD',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY เวลา LT',\n        LLLL : 'วันddddที่ D MMMM YYYY เวลา LT'\n    },\n    meridiemParse: /ก่อนเที่ยง|หลังเที่ยง/,\n    isPM: function (input) {\n        return input === 'หลังเที่ยง';\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 12) {\n            return 'ก่อนเที่ยง';\n        } else {\n            return 'หลังเที่ยง';\n        }\n    },\n    calendar : {\n        sameDay : '[วันนี้ เวลา] LT',\n        nextDay : '[พรุ่งนี้ เวลา] LT',\n        nextWeek : 'dddd[หน้า เวลา] LT',\n        lastDay : '[เมื่อวานนี้ เวลา] LT',\n        lastWeek : '[วัน]dddd[ที่แล้ว เวลา] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'อีก %s',\n        past : '%sที่แล้ว',\n        s : 'ไม่กี่วินาที',\n        m : '1 นาที',\n        mm : '%d นาที',\n        h : '1 ชั่วโมง',\n        hh : '%d ชั่วโมง',\n        d : '1 วัน',\n        dd : '%d วัน',\n        M : '1 เดือน',\n        MM : '%d เดือน',\n        y : '1 ปี',\n        yy : '%d ปี'\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/tl-ph.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('tl-ph', {\n    months : 'Enero_Pebrero_Marso_Abril_Mayo_Hunyo_Hulyo_Agosto_Setyembre_Oktubre_Nobyembre_Disyembre'.split('_'),\n    monthsShort : 'Ene_Peb_Mar_Abr_May_Hun_Hul_Ago_Set_Okt_Nob_Dis'.split('_'),\n    weekdays : 'Linggo_Lunes_Martes_Miyerkules_Huwebes_Biyernes_Sabado'.split('_'),\n    weekdaysShort : 'Lin_Lun_Mar_Miy_Huw_Biy_Sab'.split('_'),\n    weekdaysMin : 'Li_Lu_Ma_Mi_Hu_Bi_Sab'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'MM/D/YYYY',\n        LL : 'MMMM D, YYYY',\n        LLL : 'MMMM D, YYYY LT',\n        LLLL : 'dddd, MMMM DD, YYYY LT'\n    },\n    calendar : {\n        sameDay: '[Ngayon sa] LT',\n        nextDay: '[Bukas sa] LT',\n        nextWeek: 'dddd [sa] LT',\n        lastDay: '[Kahapon sa] LT',\n        lastWeek: 'dddd [huling linggo] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'sa loob ng %s',\n        past : '%s ang nakalipas',\n        s : 'ilang segundo',\n        m : 'isang minuto',\n        mm : '%d minuto',\n        h : 'isang oras',\n        hh : '%d oras',\n        d : 'isang araw',\n        dd : '%d araw',\n        M : 'isang buwan',\n        MM : '%d buwan',\n        y : 'isang taon',\n        yy : '%d taon'\n    },\n    ordinalParse: /\\d{1,2}/,\n    ordinal : function (number) {\n        return number;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/tr.js",
    "content": "\nimport moment from '../moment';\n\nvar suffixes = {\n    1: '\\'inci',\n    5: '\\'inci',\n    8: '\\'inci',\n    70: '\\'inci',\n    80: '\\'inci',\n    2: '\\'nci',\n    7: '\\'nci',\n    20: '\\'nci',\n    50: '\\'nci',\n    3: '\\'üncü',\n    4: '\\'üncü',\n    100: '\\'üncü',\n    6: '\\'ncı',\n    9: '\\'uncu',\n    10: '\\'uncu',\n    30: '\\'uncu',\n    60: '\\'ıncı',\n    90: '\\'ıncı'\n};\n\nexport default moment.defineLocale('tr', {\n    months : 'Ocak_Şubat_Mart_Nisan_Mayıs_Haziran_Temmuz_Ağustos_Eylül_Ekim_Kasım_Aralık'.split('_'),\n    monthsShort : 'Oca_Şub_Mar_Nis_May_Haz_Tem_Ağu_Eyl_Eki_Kas_Ara'.split('_'),\n    weekdays : 'Pazar_Pazartesi_Salı_Çarşamba_Perşembe_Cuma_Cumartesi'.split('_'),\n    weekdaysShort : 'Paz_Pts_Sal_Çar_Per_Cum_Cts'.split('_'),\n    weekdaysMin : 'Pz_Pt_Sa_Ça_Pe_Cu_Ct'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd, D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay : '[bugün saat] LT',\n        nextDay : '[yarın saat] LT',\n        nextWeek : '[haftaya] dddd [saat] LT',\n        lastDay : '[dün] LT',\n        lastWeek : '[geçen hafta] dddd [saat] LT',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : '%s sonra',\n        past : '%s önce',\n        s : 'birkaç saniye',\n        m : 'bir dakika',\n        mm : '%d dakika',\n        h : 'bir saat',\n        hh : '%d saat',\n        d : 'bir gün',\n        dd : '%d gün',\n        M : 'bir ay',\n        MM : '%d ay',\n        y : 'bir yıl',\n        yy : '%d yıl'\n    },\n    ordinalParse: /\\d{1,2}'(inci|nci|üncü|ncı|uncu|ıncı)/,\n    ordinal : function (number) {\n        if (number === 0) {  // special case for zero\n            return number + '\\'ıncı';\n        }\n        var a = number % 10,\n            b = number % 100 - a,\n            c = number >= 100 ? 100 : null;\n        return number + (suffixes[a] || suffixes[b] || suffixes[c]);\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/tzm-latn.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('tzm-latn', {\n    months : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n    monthsShort : 'innayr_brˤayrˤ_marˤsˤ_ibrir_mayyw_ywnyw_ywlywz_ɣwšt_šwtanbir_ktˤwbrˤ_nwwanbir_dwjnbir'.split('_'),\n    weekdays : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    weekdaysShort : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    weekdaysMin : 'asamas_aynas_asinas_akras_akwas_asimwas_asiḍyas'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay: '[asdkh g] LT',\n        nextDay: '[aska g] LT',\n        nextWeek: 'dddd [g] LT',\n        lastDay: '[assant g] LT',\n        lastWeek: 'dddd [g] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'dadkh s yan %s',\n        past : 'yan %s',\n        s : 'imik',\n        m : 'minuḍ',\n        mm : '%d minuḍ',\n        h : 'saɛa',\n        hh : '%d tassaɛin',\n        d : 'ass',\n        dd : '%d ossan',\n        M : 'ayowr',\n        MM : '%d iyyirn',\n        y : 'asgas',\n        yy : '%d isgasn'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/tzm.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('tzm', {\n    months : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n    monthsShort : 'ⵉⵏⵏⴰⵢⵔ_ⴱⵕⴰⵢⵕ_ⵎⴰⵕⵚ_ⵉⴱⵔⵉⵔ_ⵎⴰⵢⵢⵓ_ⵢⵓⵏⵢⵓ_ⵢⵓⵍⵢⵓⵣ_ⵖⵓⵛⵜ_ⵛⵓⵜⴰⵏⴱⵉⵔ_ⴽⵟⵓⴱⵕ_ⵏⵓⵡⴰⵏⴱⵉⵔ_ⴷⵓⵊⵏⴱⵉⵔ'.split('_'),\n    weekdays : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    weekdaysShort : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    weekdaysMin : 'ⴰⵙⴰⵎⴰⵙ_ⴰⵢⵏⴰⵙ_ⴰⵙⵉⵏⴰⵙ_ⴰⴽⵔⴰⵙ_ⴰⴽⵡⴰⵙ_ⴰⵙⵉⵎⵡⴰⵙ_ⴰⵙⵉⴹⵢⴰⵙ'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS: 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'dddd D MMMM YYYY LT'\n    },\n    calendar : {\n        sameDay: '[ⴰⵙⴷⵅ ⴴ] LT',\n        nextDay: '[ⴰⵙⴽⴰ ⴴ] LT',\n        nextWeek: 'dddd [ⴴ] LT',\n        lastDay: '[ⴰⵚⴰⵏⵜ ⴴ] LT',\n        lastWeek: 'dddd [ⴴ] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'ⴷⴰⴷⵅ ⵙ ⵢⴰⵏ %s',\n        past : 'ⵢⴰⵏ %s',\n        s : 'ⵉⵎⵉⴽ',\n        m : 'ⵎⵉⵏⵓⴺ',\n        mm : '%d ⵎⵉⵏⵓⴺ',\n        h : 'ⵙⴰⵄⴰ',\n        hh : '%d ⵜⴰⵙⵙⴰⵄⵉⵏ',\n        d : 'ⴰⵙⵙ',\n        dd : '%d oⵙⵙⴰⵏ',\n        M : 'ⴰⵢoⵓⵔ',\n        MM : '%d ⵉⵢⵢⵉⵔⵏ',\n        y : 'ⴰⵙⴳⴰⵙ',\n        yy : '%d ⵉⵙⴳⴰⵙⵏ'\n    },\n    week : {\n        dow : 6, // Saturday is the first day of the week.\n        doy : 12  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/uk.js",
    "content": "\nimport moment from '../moment';\n\nfunction plural(word, num) {\n    var forms = word.split('_');\n    return num % 10 === 1 && num % 100 !== 11 ? forms[0] : (num % 10 >= 2 && num % 10 <= 4 && (num % 100 < 10 || num % 100 >= 20) ? forms[1] : forms[2]);\n}\nfunction relativeTimeWithPlural(number, withoutSuffix, key) {\n    var format = {\n        'mm': 'хвилина_хвилини_хвилин',\n        'hh': 'година_години_годин',\n        'dd': 'день_дні_днів',\n        'MM': 'місяць_місяці_місяців',\n        'yy': 'рік_роки_років'\n    };\n    if (key === 'm') {\n        return withoutSuffix ? 'хвилина' : 'хвилину';\n    }\n    else if (key === 'h') {\n        return withoutSuffix ? 'година' : 'годину';\n    }\n    else {\n        return number + ' ' + plural(format[key], +number);\n    }\n}\nfunction monthsCaseReplace(m, format) {\n    var months = {\n        'nominative': 'січень_лютий_березень_квітень_травень_червень_липень_серпень_вересень_жовтень_листопад_грудень'.split('_'),\n        'accusative': 'січня_лютого_березня_квітня_травня_червня_липня_серпня_вересня_жовтня_листопада_грудня'.split('_')\n    },\n    nounCase = (/D[oD]? *MMMM?/).test(format) ?\n        'accusative' :\n        'nominative';\n    return months[nounCase][m.month()];\n}\nfunction weekdaysCaseReplace(m, format) {\n    var weekdays = {\n        'nominative': 'неділя_понеділок_вівторок_середа_четвер_п’ятниця_субота'.split('_'),\n        'accusative': 'неділю_понеділок_вівторок_середу_четвер_п’ятницю_суботу'.split('_'),\n        'genitive': 'неділі_понеділка_вівторка_середи_четверга_п’ятниці_суботи'.split('_')\n    },\n    nounCase = (/(\\[[ВвУу]\\]) ?dddd/).test(format) ?\n        'accusative' :\n        ((/\\[?(?:минулої|наступної)? ?\\] ?dddd/).test(format) ?\n            'genitive' :\n            'nominative');\n    return weekdays[nounCase][m.day()];\n}\nfunction processHoursFunction(str) {\n    return function () {\n        return str + 'о' + (this.hours() === 11 ? 'б' : '') + '] LT';\n    };\n}\n\nexport default moment.defineLocale('uk', {\n    months : monthsCaseReplace,\n    monthsShort : 'січ_лют_бер_квіт_трав_черв_лип_серп_вер_жовт_лист_груд'.split('_'),\n    weekdays : weekdaysCaseReplace,\n    weekdaysShort : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    weekdaysMin : 'нд_пн_вт_ср_чт_пт_сб'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD.MM.YYYY',\n        LL : 'D MMMM YYYY р.',\n        LLL : 'D MMMM YYYY р., LT',\n        LLLL : 'dddd, D MMMM YYYY р., LT'\n    },\n    calendar : {\n        sameDay: processHoursFunction('[Сьогодні '),\n        nextDay: processHoursFunction('[Завтра '),\n        lastDay: processHoursFunction('[Вчора '),\n        nextWeek: processHoursFunction('[У] dddd ['),\n        lastWeek: function () {\n            switch (this.day()) {\n            case 0:\n            case 3:\n            case 5:\n            case 6:\n                return processHoursFunction('[Минулої] dddd [').call(this);\n            case 1:\n            case 2:\n            case 4:\n                return processHoursFunction('[Минулого] dddd [').call(this);\n            }\n        },\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : 'за %s',\n        past : '%s тому',\n        s : 'декілька секунд',\n        m : relativeTimeWithPlural,\n        mm : relativeTimeWithPlural,\n        h : 'годину',\n        hh : relativeTimeWithPlural,\n        d : 'день',\n        dd : relativeTimeWithPlural,\n        M : 'місяць',\n        MM : relativeTimeWithPlural,\n        y : 'рік',\n        yy : relativeTimeWithPlural\n    },\n    meridiemParse: /ночі|ранку|дня|вечора/,\n    isPM: function (input) {\n        return /^(дня|вечора)$/.test(input);\n    },\n    meridiem : function (hour, minute, isLower) {\n        if (hour < 4) {\n            return 'ночі';\n        } else if (hour < 12) {\n            return 'ранку';\n        } else if (hour < 17) {\n            return 'дня';\n        } else {\n            return 'вечора';\n        }\n    },\n    ordinalParse: /\\d{1,2}-(й|го)/,\n    ordinal: function (number, period) {\n        switch (period) {\n        case 'M':\n        case 'd':\n        case 'DDD':\n        case 'w':\n        case 'W':\n            return number + '-й';\n        case 'D':\n            return number + '-го';\n        default:\n            return number;\n        }\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 1st is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/uz.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('uz', {\n    months : 'январь_февраль_март_апрель_май_июнь_июль_август_сентябрь_октябрь_ноябрь_декабрь'.split('_'),\n    monthsShort : 'янв_фев_мар_апр_май_июн_июл_авг_сен_окт_ноя_дек'.split('_'),\n    weekdays : 'Якшанба_Душанба_Сешанба_Чоршанба_Пайшанба_Жума_Шанба'.split('_'),\n    weekdaysShort : 'Якш_Душ_Сеш_Чор_Пай_Жум_Шан'.split('_'),\n    weekdaysMin : 'Як_Ду_Се_Чо_Па_Жу_Ша'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM YYYY',\n        LLL : 'D MMMM YYYY LT',\n        LLLL : 'D MMMM YYYY, dddd LT'\n    },\n    calendar : {\n        sameDay : '[Бугун соат] LT [да]',\n        nextDay : '[Эртага] LT [да]',\n        nextWeek : 'dddd [куни соат] LT [да]',\n        lastDay : '[Кеча соат] LT [да]',\n        lastWeek : '[Утган] dddd [куни соат] LT [да]',\n        sameElse : 'L'\n    },\n    relativeTime : {\n        future : 'Якин %s ичида',\n        past : 'Бир неча %s олдин',\n        s : 'фурсат',\n        m : 'бир дакика',\n        mm : '%d дакика',\n        h : 'бир соат',\n        hh : '%d соат',\n        d : 'бир кун',\n        dd : '%d кун',\n        M : 'бир ой',\n        MM : '%d ой',\n        y : 'бир йил',\n        yy : '%d йил'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 7  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/vi.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('vi', {\n    months : 'tháng 1_tháng 2_tháng 3_tháng 4_tháng 5_tháng 6_tháng 7_tháng 8_tháng 9_tháng 10_tháng 11_tháng 12'.split('_'),\n    monthsShort : 'Th01_Th02_Th03_Th04_Th05_Th06_Th07_Th08_Th09_Th10_Th11_Th12'.split('_'),\n    weekdays : 'chủ nhật_thứ hai_thứ ba_thứ tư_thứ năm_thứ sáu_thứ bảy'.split('_'),\n    weekdaysShort : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n    weekdaysMin : 'CN_T2_T3_T4_T5_T6_T7'.split('_'),\n    longDateFormat : {\n        LT : 'HH:mm',\n        LTS : 'LT:ss',\n        L : 'DD/MM/YYYY',\n        LL : 'D MMMM [năm] YYYY',\n        LLL : 'D MMMM [năm] YYYY LT',\n        LLLL : 'dddd, D MMMM [năm] YYYY LT',\n        l : 'DD/M/YYYY',\n        ll : 'D MMM YYYY',\n        lll : 'D MMM YYYY LT',\n        llll : 'ddd, D MMM YYYY LT'\n    },\n    calendar : {\n        sameDay: '[Hôm nay lúc] LT',\n        nextDay: '[Ngày mai lúc] LT',\n        nextWeek: 'dddd [tuần tới lúc] LT',\n        lastDay: '[Hôm qua lúc] LT',\n        lastWeek: 'dddd [tuần rồi lúc] LT',\n        sameElse: 'L'\n    },\n    relativeTime : {\n        future : '%s tới',\n        past : '%s trước',\n        s : 'vài giây',\n        m : 'một phút',\n        mm : '%d phút',\n        h : 'một giờ',\n        hh : '%d giờ',\n        d : 'một ngày',\n        dd : '%d ngày',\n        M : 'một tháng',\n        MM : '%d tháng',\n        y : 'một năm',\n        yy : '%d năm'\n    },\n    ordinalParse: /\\d{1,2}/,\n    ordinal : function (number) {\n        return number;\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/zh-cn.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('zh-cn', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '周日_周一_周二_周三_周四_周五_周六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'Ah点mm',\n        LTS : 'Ah点m分s秒',\n        L : 'YYYY-MM-DD',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日LT',\n        LLLL : 'YYYY年MMMD日ddddLT',\n        l : 'YYYY-MM-DD',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日LT',\n        llll : 'YYYY年MMMD日ddddLT'\n    },\n    meridiemParse: /凌晨|早上|上午|中午|下午|晚上/,\n    meridiemHour: function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '凌晨' || meridiem === '早上' ||\n                meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        } else {\n            return hour >= 11 ? hour : hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 600) {\n            return '凌晨';\n        } else if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : function () {\n            return this.minutes() === 0 ? '[今天]Ah[点整]' : '[今天]LT';\n        },\n        nextDay : function () {\n            return this.minutes() === 0 ? '[明天]Ah[点整]' : '[明天]LT';\n        },\n        lastDay : function () {\n            return this.minutes() === 0 ? '[昨天]Ah[点整]' : '[昨天]LT';\n        },\n        nextWeek : function () {\n            var startOfWeek, prefix;\n            startOfWeek = moment().startOf('week');\n            prefix = this.unix() - startOfWeek.unix() >= 7 * 24 * 3600 ? '[下]' : '[本]';\n            return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';\n        },\n        lastWeek : function () {\n            var startOfWeek, prefix;\n            startOfWeek = moment().startOf('week');\n            prefix = this.unix() < startOfWeek.unix()  ? '[上]' : '[本]';\n            return this.minutes() === 0 ? prefix + 'dddAh点整' : prefix + 'dddAh点mm';\n        },\n        sameElse : 'LL'\n    },\n    ordinalParse: /\\d{1,2}(日|月|周)/,\n    ordinal : function (number, period) {\n        switch (period) {\n        case 'd':\n        case 'D':\n        case 'DDD':\n            return number + '日';\n        case 'M':\n            return number + '月';\n        case 'w':\n        case 'W':\n            return number + '周';\n        default:\n            return number;\n        }\n    },\n    relativeTime : {\n        future : '%s内',\n        past : '%s前',\n        s : '几秒',\n        m : '1分钟',\n        mm : '%d分钟',\n        h : '1小时',\n        hh : '%d小时',\n        d : '1天',\n        dd : '%d天',\n        M : '1个月',\n        MM : '%d个月',\n        y : '1年',\n        yy : '%d年'\n    },\n    week : {\n        dow : 1, // Monday is the first day of the week.\n        doy : 4  // The week that contains Jan 4th is the first week of the year.\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/locale/zh-tw.js",
    "content": "\nimport moment from '../moment';\n\nexport default moment.defineLocale('zh-tw', {\n    months : '一月_二月_三月_四月_五月_六月_七月_八月_九月_十月_十一月_十二月'.split('_'),\n    monthsShort : '1月_2月_3月_4月_5月_6月_7月_8月_9月_10月_11月_12月'.split('_'),\n    weekdays : '星期日_星期一_星期二_星期三_星期四_星期五_星期六'.split('_'),\n    weekdaysShort : '週日_週一_週二_週三_週四_週五_週六'.split('_'),\n    weekdaysMin : '日_一_二_三_四_五_六'.split('_'),\n    longDateFormat : {\n        LT : 'Ah點mm',\n        LTS : 'Ah點m分s秒',\n        L : 'YYYY年MMMD日',\n        LL : 'YYYY年MMMD日',\n        LLL : 'YYYY年MMMD日LT',\n        LLLL : 'YYYY年MMMD日ddddLT',\n        l : 'YYYY年MMMD日',\n        ll : 'YYYY年MMMD日',\n        lll : 'YYYY年MMMD日LT',\n        llll : 'YYYY年MMMD日ddddLT'\n    },\n    meridiemParse: /早上|上午|中午|下午|晚上/,\n    meridiemHour : function (hour, meridiem) {\n        if (hour === 12) {\n            hour = 0;\n        }\n        if (meridiem === '早上' || meridiem === '上午') {\n            return hour;\n        } else if (meridiem === '中午') {\n            return hour >= 11 ? hour : hour + 12;\n        } else if (meridiem === '下午' || meridiem === '晚上') {\n            return hour + 12;\n        }\n    },\n    meridiem : function (hour, minute, isLower) {\n        var hm = hour * 100 + minute;\n        if (hm < 900) {\n            return '早上';\n        } else if (hm < 1130) {\n            return '上午';\n        } else if (hm < 1230) {\n            return '中午';\n        } else if (hm < 1800) {\n            return '下午';\n        } else {\n            return '晚上';\n        }\n    },\n    calendar : {\n        sameDay : '[今天]LT',\n        nextDay : '[明天]LT',\n        nextWeek : '[下]ddddLT',\n        lastDay : '[昨天]LT',\n        lastWeek : '[上]ddddLT',\n        sameElse : 'L'\n    },\n    ordinalParse: /\\d{1,2}(日|月|週)/,\n    ordinal : function (number, period) {\n        switch (period) {\n        case 'd' :\n        case 'D' :\n        case 'DDD' :\n            return number + '日';\n        case 'M' :\n            return number + '月';\n        case 'w' :\n        case 'W' :\n            return number + '週';\n        default :\n            return number;\n        }\n    },\n    relativeTime : {\n        future : '%s內',\n        past : '%s前',\n        s : '幾秒',\n        m : '一分鐘',\n        mm : '%d分鐘',\n        h : '一小時',\n        hh : '%d小時',\n        d : '一天',\n        dd : '%d天',\n        M : '一個月',\n        MM : '%d個月',\n        y : '一年',\n        yy : '%d年'\n    }\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/src/moment.js",
    "content": "\nimport { hooks as moment, setHookCallback } from './lib/utils/hooks';\n\nmoment.version = '2.10.2';\n\nimport {\n    min,\n    max,\n    isMoment,\n    momentPrototype as fn,\n    createUTC       as utc,\n    createUnix      as unix,\n    createLocal     as local,\n    createInvalid   as invalid,\n    createInZone    as parseZone\n} from './lib/moment/moment';\n\nimport {\n    defineLocale,\n    getSetGlobalLocale as locale,\n    getLocale          as localeData,\n    listMonths         as months,\n    listMonthsShort    as monthsShort,\n    listWeekdays       as weekdays,\n    listWeekdaysMin    as weekdaysMin,\n    listWeekdaysShort  as weekdaysShort\n} from './lib/locale/locale';\n\nimport {\n    isDuration,\n    createDuration as duration,\n    getSetRelativeTimeThreshold as relativeTimeThreshold\n} from './lib/duration/duration';\n\nimport { normalizeUnits } from './lib/units/units';\n\nimport isDate from './lib/utils/is-date';\n\nsetHookCallback(local);\n\nmoment.fn                    = fn;\nmoment.min                   = min;\nmoment.max                   = max;\nmoment.utc                   = utc;\nmoment.unix                  = unix;\nmoment.months                = months;\nmoment.isDate                = isDate;\nmoment.locale                = locale;\nmoment.invalid               = invalid;\nmoment.duration              = duration;\nmoment.isMoment              = isMoment;\nmoment.weekdays              = weekdays;\nmoment.parseZone             = parseZone;\nmoment.localeData            = localeData;\nmoment.isDuration            = isDuration;\nmoment.monthsShort           = monthsShort;\nmoment.weekdaysMin           = weekdaysMin;\nmoment.defineLocale          = defineLocale;\nmoment.weekdaysShort         = weekdaysShort;\nmoment.normalizeUnits        = normalizeUnits;\nmoment.relativeTimeThreshold = relativeTimeThreshold;\n\nexport default moment;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/templates/amd-named.js",
    "content": "/*global define:false*/\n\nimport moment from \"./moment\";\n\ndefine(\"moment\", [], function () {\n    return moment;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/templates/amd.js",
    "content": "/*global define:false*/\n\nimport moment from \"./moment\";\n\ndefine([], function () {\n    return moment;\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/templates/globals.js",
    "content": "/*global window:false*/\n\nimport moment from \"./moment\";\n\nwindow.moment = moment;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/templates/locale-header.js",
    "content": "(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../moment')) :\n   typeof define === 'function' && define.amd ? define(['moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/moment/templates/test-header.js",
    "content": "(function (global, factory) {\n   typeof exports === 'object' && typeof module !== 'undefined' ? factory(require('../../moment')) :\n   typeof define === 'function' && define.amd ? define(['../../moment'], factory) :\n   factory(global.moment)\n}(this, function (moment) { 'use strict';\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ng-file-upload/.bower.json",
    "content": "{\n  \"name\": \"angular-file-upload\",\n  \"main\": \"angular-file-upload.js\",\n  \"version\": \"3.3.3\",\n  \"homepage\": \"https://github.com/danialfarid/angular-file-upload\",\n  \"authors\": [\n    \"danialf <danial.farid@gmail.com>\"\n  ],\n  \"description\": \"Lightweight Angular JS directive to upload files. Support drag&drop, progress and abort\",\n  \"license\": \"MIT\",\n  \"_release\": \"3.3.3\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"3.3.3\",\n    \"commit\": \"daecb4c01cab44f42e0016ed085f9297cd3b2bd3\"\n  },\n  \"_source\": \"git://github.com/danialfarid/angular-file-upload-bower.git\",\n  \"_target\": \"~3.3.3\",\n  \"_originalSource\": \"ng-file-upload\",\n  \"_direct\": true\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ng-file-upload/FileAPI.js",
    "content": "/*! FileAPI 2.0.7 - BSD | git://github.com/mailru/FileAPI.git\n * FileAPI — a set of  javascript tools for working with files. Multiupload, drag'n'drop and chunked file upload. Images: crop, resize and auto orientation by EXIF.\n */\n\n/*\n * JavaScript Canvas to Blob 2.0.5\n * https://github.com/blueimp/JavaScript-Canvas-to-Blob\n *\n * Copyright 2012, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/MIT\n *\n * Based on stackoverflow user Stoive's code snippet:\n * http://stackoverflow.com/q/4998908\n */\n\n/*jslint nomen: true, regexp: true */\n/*global window, atob, Blob, ArrayBuffer, Uint8Array */\n\n(function (window) {\n    'use strict';\n    var CanvasPrototype = window.HTMLCanvasElement &&\n            window.HTMLCanvasElement.prototype,\n        hasBlobConstructor = window.Blob && (function () {\n            try {\n                return Boolean(new Blob());\n            } catch (e) {\n                return false;\n            }\n        }()),\n        hasArrayBufferViewSupport = hasBlobConstructor && window.Uint8Array &&\n            (function () {\n                try {\n                    return new Blob([new Uint8Array(100)]).size === 100;\n                } catch (e) {\n                    return false;\n                }\n            }()),\n        BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder ||\n            window.MozBlobBuilder || window.MSBlobBuilder,\n        dataURLtoBlob = (hasBlobConstructor || BlobBuilder) && window.atob &&\n            window.ArrayBuffer && window.Uint8Array && function (dataURI) {\n                var byteString,\n                    arrayBuffer,\n                    intArray,\n                    i,\n                    mimeString,\n                    bb;\n                if (dataURI.split(',')[0].indexOf('base64') >= 0) {\n                    byteString = atob(dataURI.split(',')[1]);\n                } else {\n                    byteString = decodeURIComponent(dataURI.split(',')[1]);\n                }\n                arrayBuffer = new ArrayBuffer(byteString.length);\n                intArray = new Uint8Array(arrayBuffer);\n                for (i = 0; i < byteString.length; i += 1) {\n                    intArray[i] = byteString.charCodeAt(i);\n                }\n                mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];\n                if (hasBlobConstructor) {\n                    return new Blob(\n                        [hasArrayBufferViewSupport ? intArray : arrayBuffer],\n                        {type: mimeString}\n                    );\n                }\n                bb = new BlobBuilder();\n                bb.append(arrayBuffer);\n                return bb.getBlob(mimeString);\n            };\n    if (window.HTMLCanvasElement && !CanvasPrototype.toBlob) {\n        if (CanvasPrototype.mozGetAsFile) {\n            CanvasPrototype.toBlob = function (callback, type, quality) {\n                if (quality && CanvasPrototype.toDataURL && dataURLtoBlob) {\n                    callback(dataURLtoBlob(this.toDataURL(type, quality)));\n                } else {\n                    callback(this.mozGetAsFile('blob', type));\n                }\n            };\n        } else if (CanvasPrototype.toDataURL && dataURLtoBlob) {\n            CanvasPrototype.toBlob = function (callback, type, quality) {\n                callback(dataURLtoBlob(this.toDataURL(type, quality)));\n            };\n        }\n    }\n    window.dataURLtoBlob = dataURLtoBlob;\n})(window);\n\n/*jslint evil: true */\n/*global window, URL, webkitURL, ActiveXObject */\n\n(function (window, undef){\n\t'use strict';\n\n\tvar\n\t\tgid = 1,\n\t\tnoop = function (){},\n\n\t\tdocument = window.document,\n\t\tdoctype = document.doctype || {},\n\t\tuserAgent = window.navigator.userAgent,\n\t\tapiURL = (window.createObjectURL && window) || (window.URL && URL.revokeObjectURL && URL) || (window.webkitURL && webkitURL),\n\n\t\tBlob = window.Blob,\n\t\tFile = window.File,\n\t\tFileReader = window.FileReader,\n\t\tFormData = window.FormData,\n\n\n\t\tXMLHttpRequest = window.XMLHttpRequest,\n\t\tjQuery = window.jQuery,\n\n\t\thtml5 =    !!(File && (FileReader && (window.Uint8Array || FormData || XMLHttpRequest.prototype.sendAsBinary)))\n\t\t\t\t&& !(/safari\\//i.test(userAgent) && !/chrome\\//i.test(userAgent) && /windows/i.test(userAgent)), // BugFix: https://github.com/mailru/FileAPI/issues/25\n\n\t\tcors = html5 && ('withCredentials' in (new XMLHttpRequest)),\n\n\t\tchunked = html5 && !!Blob && !!(Blob.prototype.webkitSlice || Blob.prototype.mozSlice || Blob.prototype.slice),\n\t\tdataURLtoBlob = window.dataURLtoBlob,\n\n\n\t\t_rimg = /img/i,\n\t\t_rcanvas = /canvas/i,\n\t\t_rimgcanvas = /img|canvas/i,\n\t\t_rinput = /input/i,\n\t\t_rdata = /^data:[^,]+,/,\n\n\t\t_toString = {}.toString,\n\n\n\t\tMath = window.Math,\n\n\t\t_SIZE_CONST = function (pow){\n\t\t\tpow = new window.Number(Math.pow(1024, pow));\n\t\t\tpow.from = function (sz){ return Math.round(sz * this); };\n\t\t\treturn\tpow;\n\t\t},\n\n\t\t_elEvents = {}, // element event listeners\n\t\t_infoReader = [], // list of file info processors\n\n\t\t_readerEvents = 'abort progress error load loadend',\n\t\t_xhrPropsExport = 'status statusText readyState response responseXML responseText responseBody'.split(' '),\n\n\t\tcurrentTarget = 'currentTarget', // for minimize\n\t\tpreventDefault = 'preventDefault', // and this too\n\n\t\t_isArray = function (ar) {\n\t\t\treturn\tar && ('length' in ar);\n\t\t},\n\n\t\t\t\t_each = function (obj, fn, ctx){\n\t\t\tif( obj ){\n\t\t\t\tif( _isArray(obj) ){\n\t\t\t\t\tfor( var i = 0, n = obj.length; i < n; i++ ){\n\t\t\t\t\t\tif( i in obj ){\n\t\t\t\t\t\t\tfn.call(ctx, obj[i], i, obj);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tfor( var key in obj ){\n\t\t\t\t\t\tif( obj.hasOwnProperty(key) ){\n\t\t\t\t\t\t\tfn.call(ctx, obj[key], key, obj);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t\t\t_extend = function (dst){\n\t\t\tvar args = arguments, i = 1, _ext = function (val, key){ dst[key] = val; };\n\t\t\tfor( ; i < args.length; i++ ){\n\t\t\t\t_each(args[i], _ext);\n\t\t\t}\n\t\t\treturn  dst;\n\t\t},\n\n\t\t\t\t_on = function (el, type, fn){\n\t\t\tif( el ){\n\t\t\t\tvar uid = api.uid(el);\n\n\t\t\t\tif( !_elEvents[uid] ){\n\t\t\t\t\t_elEvents[uid] = {};\n\t\t\t\t}\n\n\t\t\t\tvar isFileReader = (FileReader && el) && (el instanceof FileReader);\n\t\t\t\t_each(type.split(/\\s+/), function (type){\n\t\t\t\t\tif( jQuery && !isFileReader){\n\t\t\t\t\t\tjQuery.event.add(el, type, fn);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif( !_elEvents[uid][type] ){\n\t\t\t\t\t\t\t_elEvents[uid][type] = [];\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t_elEvents[uid][type].push(fn);\n\n\t\t\t\t\t\tif( el.addEventListener ){ el.addEventListener(type, fn, false); }\n\t\t\t\t\t\telse if( el.attachEvent ){ el.attachEvent('on'+type, fn); }\n\t\t\t\t\t\telse { el['on'+type] = fn; }\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\n\t\t\t\t_off = function (el, type, fn){\n\t\t\tif( el ){\n\t\t\t\tvar uid = api.uid(el), events = _elEvents[uid] || {};\n\n\t\t\t\tvar isFileReader = (FileReader && el) && (el instanceof FileReader);\n\t\t\t\t_each(type.split(/\\s+/), function (type){\n\t\t\t\t\tif( jQuery && !isFileReader){\n\t\t\t\t\t\tjQuery.event.remove(el, type, fn);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tvar fns = events[type] || [], i = fns.length;\n\n\t\t\t\t\t\twhile( i-- ){\n\t\t\t\t\t\t\tif( fns[i] === fn ){\n\t\t\t\t\t\t\t\tfns.splice(i, 1);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif( el.addEventListener ){ el.removeEventListener(type, fn, false); }\n\t\t\t\t\t\telse if( el.detachEvent ){ el.detachEvent('on'+type, fn); }\n\t\t\t\t\t\telse { el['on'+type] = null; }\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\n\t\t_one = function(el, type, fn){\n\t\t\t_on(el, type, function _(evt){\n\t\t\t\t_off(el, type, _);\n\t\t\t\tfn(evt);\n\t\t\t});\n\t\t},\n\n\n\t\t_fixEvent = function (evt){\n\t\t\tif( !evt.target ){ evt.target = window.event && window.event.srcElement || document; }\n\t\t\tif( evt.target.nodeType === 3 ){ evt.target = evt.target.parentNode; }\n\t\t\treturn  evt;\n\t\t},\n\n\n\t\t_supportInputAttr = function (attr){\n\t\t\tvar input = document.createElement('input');\n\t\t\tinput.setAttribute('type', \"file\");\n\t\t\treturn attr in input;\n\t\t},\n\n\n\t\t\t\tapi = {\n\t\t\tversion: '2.0.7',\n\n\t\t\tcors: false,\n\t\t\thtml5: true,\n\t\t\tmedia: false,\n\t\t\tformData: true,\n\t\t\tmultiPassResize: true,\n\n\t\t\tdebug: false,\n\t\t\tpingUrl: false,\n\t\t\tmultiFlash: false,\n\t\t\tflashAbortTimeout: 0,\n\t\t\twithCredentials: true,\n\n\t\t\tstaticPath: './dist/',\n\n\t\t\tflashUrl: 0, // @default: './FileAPI.flash.swf'\n\t\t\tflashImageUrl: 0, // @default: './FileAPI.flash.image.swf'\n\n\t\t\tpostNameConcat: function (name, idx){\n\t\t\t\treturn\tname + (idx != null ? '['+ idx +']' : '');\n\t\t\t},\n\n\t\t\text2mime: {\n\t\t\t\t  jpg:\t'image/jpeg'\n\t\t\t\t, tif:\t'image/tiff'\n\t\t\t\t, txt:\t'text/plain'\n\t\t\t},\n\t\t\taccept: {\n\t\t\t\t  'image/*': 'art bm bmp dwg dxf cbr cbz fif fpx gif ico iefs jfif jpe jpeg jpg jps jut mcf nap nif pbm pcx pgm pict pm png pnm qif qtif ras rast rf rp svf tga tif tiff xbm xbm xpm xwd'\n\t\t\t\t, 'audio/*': 'm4a flac aac rm mpa wav wma ogg mp3 mp2 m3u mod amf dmf dsm far gdm imf it m15 med okt s3m stm sfx ult uni xm sid ac3 dts cue aif aiff wpl ape mac mpc mpp shn wv nsf spc gym adplug adx dsp adp ymf ast afc hps xs'\n\t\t\t\t, 'video/*': 'm4v 3gp nsv ts ty strm rm rmvb m3u ifo mov qt divx xvid bivx vob nrg img iso pva wmv asf asx ogm m2v avi bin dat dvr-ms mpg mpeg mp4 mkv avc vp3 svq3 nuv viv dv fli flv wpl'\n\t\t\t},\n\n\t\t\tuploadRetry : 0,\n\t\t\tnetworkDownRetryTimeout : 5000, // milliseconds, don't flood when network is down\n\n\t\t\tchunkSize : 0,\n\t\t\tchunkUploadRetry : 0,\n\t\t\tchunkNetworkDownRetryTimeout : 2000, // milliseconds, don't flood when network is down\n\n\t\t\tKB: _SIZE_CONST(1),\n\t\t\tMB: _SIZE_CONST(2),\n\t\t\tGB: _SIZE_CONST(3),\n\t\t\tTB: _SIZE_CONST(4),\n\n\t\t\tEMPTY_PNG: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQIW2NkAAIAAAoAAggA9GkAAAAASUVORK5CYII=',\n\n\t\t\texpando: 'fileapi' + (new Date).getTime(),\n\n\t\t\tuid: function (obj){\n\t\t\t\treturn\tobj\n\t\t\t\t\t? (obj[api.expando] = obj[api.expando] || api.uid())\n\t\t\t\t\t: (++gid, api.expando + gid)\n\t\t\t\t;\n\t\t\t},\n\n\t\t\tlog: function (){\n\t\t\t\tif( api.debug && window.console && console.log ){\n\t\t\t\t\tif( console.log.apply ){\n\t\t\t\t\t\tconsole.log.apply(console, arguments);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tconsole.log([].join.call(arguments, ' '));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t\t\t\tnewImage: function (src, fn){\n\t\t\t\tvar img = document.createElement('img');\n\t\t\t\tif( fn ){\n\t\t\t\t\tapi.event.one(img, 'error load', function (evt){\n\t\t\t\t\t\tfn(evt.type == 'error', img);\n\t\t\t\t\t\timg = null;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\timg.src = src;\n\t\t\t\treturn\timg;\n\t\t\t},\n\n\t\t\t\t\t\tgetXHR: function (){\n\t\t\t\tvar xhr;\n\n\t\t\t\tif( XMLHttpRequest ){\n\t\t\t\t\txhr = new XMLHttpRequest;\n\t\t\t\t}\n\t\t\t\telse if( window.ActiveXObject ){\n\t\t\t\t\ttry {\n\t\t\t\t\t\txhr = new ActiveXObject('MSXML2.XMLHttp.3.0');\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\txhr = new ActiveXObject('Microsoft.XMLHTTP');\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn  xhr;\n\t\t\t},\n\n\t\t\tisArray: _isArray,\n\n\t\t\tsupport: {\n\t\t\t\tdnd:     cors && ('ondrop' in document.createElement('div')),\n\t\t\t\tcors:    cors,\n\t\t\t\thtml5:   html5,\n\t\t\t\tchunked: chunked,\n\t\t\t\tdataURI: true,\n\t\t\t\taccept:   _supportInputAttr('accept'),\n\t\t\t\tmultiple: _supportInputAttr('multiple')\n\t\t\t},\n\n\t\t\tevent: {\n\t\t\t\t  on: _on\n\t\t\t\t, off: _off\n\t\t\t\t, one: _one\n\t\t\t\t, fix: _fixEvent\n\t\t\t},\n\n\n\t\t\tthrottle: function(fn, delay) {\n\t\t\t\tvar id, args;\n\n\t\t\t\treturn function _throttle(){\n\t\t\t\t\targs = arguments;\n\n\t\t\t\t\tif( !id ){\n\t\t\t\t\t\tfn.apply(window, args);\n\t\t\t\t\t\tid = setTimeout(function (){\n\t\t\t\t\t\t\tid = 0;\n\t\t\t\t\t\t\tfn.apply(window, args);\n\t\t\t\t\t\t}, delay);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\n\t\t\tF: function (){},\n\n\n\t\t\tparseJSON: function (str){\n\t\t\t\tvar json;\n\t\t\t\tif( window.JSON && JSON.parse ){\n\t\t\t\t\tjson = JSON.parse(str);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tjson = (new Function('return ('+str.replace(/([\\r\\n])/g, '\\\\$1')+');'))();\n\t\t\t\t}\n\t\t\t\treturn json;\n\t\t\t},\n\n\n\t\t\ttrim: function (str){\n\t\t\t\tstr = String(str);\n\t\t\t\treturn\tstr.trim ? str.trim() : str.replace(/^\\s+|\\s+$/g, '');\n\t\t\t},\n\n\t\t\t\t\t\tdefer: function (){\n\t\t\t\tvar\n\t\t\t\t\t  list = []\n\t\t\t\t\t, result\n\t\t\t\t\t, error\n\t\t\t\t\t, defer = {\n\t\t\t\t\t\tresolve: function (err, res){\n\t\t\t\t\t\t\tdefer.resolve = noop;\n\t\t\t\t\t\t\terror\t= err || false;\n\t\t\t\t\t\t\tresult\t= res;\n\n\t\t\t\t\t\t\twhile( res = list.shift() ){\n\t\t\t\t\t\t\t\tres(error, result);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tthen: function (fn){\n\t\t\t\t\t\t\tif( error !== undef ){\n\t\t\t\t\t\t\t\tfn(error, result);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tlist.push(fn);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\treturn\tdefer;\n\t\t\t},\n\n\t\t\tqueue: function (fn){\n\t\t\t\tvar\n\t\t\t\t\t  _idx = 0\n\t\t\t\t\t, _length = 0\n\t\t\t\t\t, _fail = false\n\t\t\t\t\t, _end = false\n\t\t\t\t\t, queue = {\n\t\t\t\t\t\tinc: function (){\n\t\t\t\t\t\t\t_length++;\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tnext: function (){\n\t\t\t\t\t\t\t_idx++;\n\t\t\t\t\t\t\tsetTimeout(queue.check, 0);\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tcheck: function (){\n\t\t\t\t\t\t\t(_idx >= _length) && !_fail && queue.end();\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tisFail: function (){\n\t\t\t\t\t\t\treturn _fail;\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tfail: function (){\n\t\t\t\t\t\t\t!_fail && fn(_fail = true);\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\tend: function (){\n\t\t\t\t\t\t\tif( !_end ){\n\t\t\t\t\t\t\t\t_end = true;\n\t\t\t\t\t\t\t\tfn();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t;\n\t\t\t\treturn queue;\n\t\t\t},\n\n\n\t\t\t\t\t\teach: _each,\n\n\n\t\t\t\t\t\tafor: function (array, callback){\n\t\t\t\tvar i = 0, n = array.length;\n\n\t\t\t\tif( _isArray(array) && n-- ){\n\t\t\t\t\t(function _next(){\n\t\t\t\t\t\tcallback(n != i && _next, array[i], i++);\n\t\t\t\t\t})();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tcallback(false);\n\t\t\t\t}\n\t\t\t},\n\n\n\t\t\t\t\t\textend: _extend,\n\n\n\t\t\t\t\t\tisFile: function (file){\n\t\t\t\treturn _toString.call(file) === '[object File]';\n\t\t\t},\n\n\n\t\t\t\t\t\tisBlob: function (blob) {\n\t\t\t\treturn this.isFile(blob) || (_toString.call(blob) === '[object Blob]');\n\t\t\t},\n\n\n\t\t\t\t\t\tisCanvas: function (el){\n\t\t\t\treturn\tel && _rcanvas.test(el.nodeName);\n\t\t\t},\n\n\n\t\t\tgetFilesFilter: function (filter){\n\t\t\t\tfilter = typeof filter == 'string' ? filter : (filter.getAttribute && filter.getAttribute('accept') || '');\n\t\t\t\treturn\tfilter ? new RegExp('('+ filter.replace(/\\./g, '\\\\.').replace(/,/g, '|') +')$', 'i') : /./;\n\t\t\t},\n\n\n\n\t\t\t\t\t\treadAsDataURL: function (file, fn){\n\t\t\t\tif( api.isCanvas(file) ){\n\t\t\t\t\t_emit(file, fn, 'load', api.toDataURL(file));\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t_readAs(file, fn, 'DataURL');\n\t\t\t\t}\n\t\t\t},\n\n\n\t\t\t\t\t\treadAsBinaryString: function (file, fn){\n\t\t\t\tif( _hasSupportReadAs('BinaryString') ){\n\t\t\t\t\t_readAs(file, fn, 'BinaryString');\n\t\t\t\t} else {\n\t\t\t\t\t_readAs(file, function (evt){\n\t\t\t\t\t\tif( evt.type == 'load' ){\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tevt.result = api.toBinaryString(evt.result);\n\t\t\t\t\t\t\t} catch (e){\n\t\t\t\t\t\t\t\tevt.type = 'error';\n\t\t\t\t\t\t\t\tevt.message = e.toString();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfn(evt);\n\t\t\t\t\t}, 'DataURL');\n\t\t\t\t}\n\t\t\t},\n\n\n\t\t\t\t\t\treadAsArrayBuffer: function(file, fn){\n\t\t\t\t_readAs(file, fn, 'ArrayBuffer');\n\t\t\t},\n\n\n\t\t\t\t\t\treadAsText: function(file, encoding, fn){\n\t\t\t\tif( !fn ){\n\t\t\t\t\tfn\t= encoding;\n\t\t\t\t\tencoding = 'utf-8';\n\t\t\t\t}\n\n\t\t\t\t_readAs(file, fn, 'Text', encoding);\n\t\t\t},\n\n\n\t\t\t\t\t\ttoDataURL: function (el, type){\n\t\t\t\tif( typeof el == 'string' ){\n\t\t\t\t\treturn  el;\n\t\t\t\t}\n\t\t\t\telse if( el.toDataURL ){\n\t\t\t\t\treturn  el.toDataURL(type || 'image/png');\n\t\t\t\t}\n\t\t\t},\n\n\n\t\t\t\t\t\ttoBinaryString: function (val){\n\t\t\t\treturn  window.atob(api.toDataURL(val).replace(_rdata, ''));\n\t\t\t},\n\n\n\t\t\t\t\t\treadAsImage: function (file, fn, progress){\n\t\t\t\tif( api.isFile(file) ){\n\t\t\t\t\tif( apiURL ){\n\t\t\t\t\t\t\t\t\t\t\t\tvar data = apiURL.createObjectURL(file);\n\t\t\t\t\t\tif( data === undef ){\n\t\t\t\t\t\t\t_emit(file, fn, 'error');\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tapi.readAsImage(data, fn, progress);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tapi.readAsDataURL(file, function (evt){\n\t\t\t\t\t\t\tif( evt.type == 'load' ){\n\t\t\t\t\t\t\t\tapi.readAsImage(evt.result, fn, progress);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if( progress || evt.type == 'error' ){\n\t\t\t\t\t\t\t\t_emit(file, fn, evt, null, { loaded: evt.loaded, total: evt.total });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if( api.isCanvas(file) ){\n\t\t\t\t\t_emit(file, fn, 'load', file);\n\t\t\t\t}\n\t\t\t\telse if( _rimg.test(file.nodeName) ){\n\t\t\t\t\tif( file.complete ){\n\t\t\t\t\t\t_emit(file, fn, 'load', file);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tvar events = 'error abort load';\n\t\t\t\t\t\t_one(file, events, function _fn(evt){\n\t\t\t\t\t\t\tif( evt.type == 'load' && apiURL ){\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tapiURL.revokeObjectURL(file.src);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_off(file, events, _fn);\n\t\t\t\t\t\t\t_emit(file, fn, evt, file);\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if( file.iframe ){\n\t\t\t\t\t_emit(file, fn, { type: 'error' });\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tvar img = api.newImage(file.dataURL || file);\n\t\t\t\t\tapi.readAsImage(img, fn, progress);\n\t\t\t\t}\n\t\t\t},\n\n\n\t\t\t\t\t\tcheckFileObj: function (name){\n\t\t\t\tvar file = {}, accept = api.accept;\n\n\t\t\t\tif( typeof name == 'object' ){\n\t\t\t\t\tfile = name;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tfile.name = (name + '').split(/\\\\|\\//g).pop();\n\t\t\t\t}\n\n\t\t\t\tif( file.type == null ){\n\t\t\t\t\tfile.type = file.name.split('.').pop();\n\t\t\t\t}\n\n\t\t\t\t_each(accept, function (ext, type){\n\t\t\t\t\text = new RegExp(ext.replace(/\\s/g, '|'), 'i');\n\t\t\t\t\tif( ext.test(file.type) || api.ext2mime[file.type] ){\n\t\t\t\t\t\tfile.type = api.ext2mime[file.type] || (type.split('/')[0] +'/'+ file.type);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\treturn\tfile;\n\t\t\t},\n\n\n\t\t\t\t\t\tgetDropFiles: function (evt, callback){\n\t\t\t\tvar\n\t\t\t\t\t  files = []\n\t\t\t\t\t, dataTransfer = _getDataTransfer(evt)\n\t\t\t\t\t, entrySupport = _isArray(dataTransfer.items) && dataTransfer.items[0] && _getAsEntry(dataTransfer.items[0])\n\t\t\t\t\t, queue = api.queue(function (){ callback(files); })\n\t\t\t\t;\n\n\t\t\t\t_each((entrySupport ? dataTransfer.items : dataTransfer.files) || [], function (item){\n\t\t\t\t\tqueue.inc();\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif( entrySupport ){\n\t\t\t\t\t\t\t_readEntryAsFiles(item, function (err, entryFiles){\n\t\t\t\t\t\t\t\tif( err ){\n\t\t\t\t\t\t\t\t\tapi.log('[err] getDropFiles:', err);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tfiles.push.apply(files, entryFiles);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tqueue.next();\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t_isRegularFile(item, function (yes){\n\t\t\t\t\t\t\t\tyes && files.push(item);\n\t\t\t\t\t\t\t\tqueue.next();\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcatch( err ){\n\t\t\t\t\t\tqueue.next();\n\t\t\t\t\t\tapi.log('[err] getDropFiles: ', err);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tqueue.check();\n\t\t\t},\n\n\n\t\t\t\t\t\tgetFiles: function (input, filter, callback){\n\t\t\t\tvar files = [];\n\n\t\t\t\tif( callback ){\n\t\t\t\t\tapi.filterFiles(api.getFiles(input), filter, callback);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tif( input.jquery ){\n\t\t\t\t\tinput.each(function (){\n\t\t\t\t\t\tfiles = files.concat(api.getFiles(this));\n\t\t\t\t\t});\n\t\t\t\t\tinput\t= files;\n\t\t\t\t\tfiles\t= [];\n\t\t\t\t}\n\n\t\t\t\tif( typeof filter == 'string' ){\n\t\t\t\t\tfilter\t= api.getFilesFilter(filter);\n\t\t\t\t}\n\n\t\t\t\tif( input.originalEvent ){\n\t\t\t\t\tinput = _fixEvent(input.originalEvent);\n\t\t\t\t}\n\t\t\t\telse if( input.srcElement ){\n\t\t\t\t\tinput = _fixEvent(input);\n\t\t\t\t}\n\n\n\t\t\t\tif( input.dataTransfer ){\n\t\t\t\t\tinput = input.dataTransfer;\n\t\t\t\t}\n\t\t\t\telse if( input.target ){\n\t\t\t\t\tinput = input.target;\n\t\t\t\t}\n\n\t\t\t\tif( input.files ){\n\t\t\t\t\tfiles = input.files;\n\n\t\t\t\t\tif( !html5 ){\n\t\t\t\t\t\tfiles[0].blob\t= input;\n\t\t\t\t\t\tfiles[0].iframe\t= true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if( !html5 && isInputFile(input) ){\n\t\t\t\t\tif( api.trim(input.value) ){\n\t\t\t\t\t\tfiles = [api.checkFileObj(input.value)];\n\t\t\t\t\t\tfiles[0].blob   = input;\n\t\t\t\t\t\tfiles[0].iframe = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if( _isArray(input) ){\n\t\t\t\t\tfiles\t= input;\n\t\t\t\t}\n\n\t\t\t\treturn\tapi.filter(files, function (file){ return !filter || filter.test(file.name); });\n\t\t\t},\n\n\n\t\t\t\t\t\tgetTotalSize: function (files){\n\t\t\t\tvar size = 0, i = files && files.length;\n\t\t\t\twhile( i-- ){\n\t\t\t\t\tsize += files[i].size;\n\t\t\t\t}\n\t\t\t\treturn\tsize;\n\t\t\t},\n\n\n\t\t\t\t\t\tgetInfo: function (file, fn){\n\t\t\t\tvar info = {}, readers = _infoReader.concat();\n\n\t\t\t\tif( api.isFile(file) ){\n\t\t\t\t\t(function _next(){\n\t\t\t\t\t\tvar reader = readers.shift();\n\t\t\t\t\t\tif( reader ){\n\t\t\t\t\t\t\tif( reader.test(file.type) ){\n\t\t\t\t\t\t\t\treader(file, function (err, res){\n\t\t\t\t\t\t\t\t\tif( err ){\n\t\t\t\t\t\t\t\t\t\tfn(err);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\t\t_extend(info, res);\n\t\t\t\t\t\t\t\t\t\t_next();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t_next();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tfn(false, info);\n\t\t\t\t\t\t}\n\t\t\t\t\t})();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tfn('not_support_info', info);\n\t\t\t\t}\n\t\t\t},\n\n\n\t\t\t\t\t\taddInfoReader: function (mime, fn){\n\t\t\t\tfn.test = function (type){ return mime.test(type); };\n\t\t\t\t_infoReader.push(fn);\n\t\t\t},\n\n\n\t\t\t\t\t\tfilter: function (input, fn){\n\t\t\t\tvar result = [], i = 0, n = input.length, val;\n\n\t\t\t\tfor( ; i < n; i++ ){\n\t\t\t\t\tif( i in input ){\n\t\t\t\t\t\tval = input[i];\n\t\t\t\t\t\tif( fn.call(val, val, i, input) ){\n\t\t\t\t\t\t\tresult.push(val);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn\tresult;\n\t\t\t},\n\n\n\t\t\t\t\t\tfilterFiles: function (files, eachFn, resultFn){\n\t\t\t\tif( files.length ){\n\t\t\t\t\tvar queue = files.concat(), file, result = [], deleted = [];\n\n\t\t\t\t\t(function _next(){\n\t\t\t\t\t\tif( queue.length ){\n\t\t\t\t\t\t\tfile = queue.shift();\n\t\t\t\t\t\t\tapi.getInfo(file, function (err, info){\n\t\t\t\t\t\t\t\t(eachFn(file, err ? false : info) ? result : deleted).push(file);\n\t\t\t\t\t\t\t\t_next();\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tresultFn(result, deleted);\n\t\t\t\t\t\t}\n\t\t\t\t\t})();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tresultFn([], files);\n\t\t\t\t}\n\t\t\t},\n\n\n\t\t\tupload: function (options){\n\t\t\t\toptions = _extend({\n\t\t\t\t\t  jsonp: 'callback'\n\t\t\t\t\t, prepare: api.F\n\t\t\t\t\t, beforeupload: api.F\n\t\t\t\t\t, upload: api.F\n\t\t\t\t\t, fileupload: api.F\n\t\t\t\t\t, fileprogress: api.F\n\t\t\t\t\t, filecomplete: api.F\n\t\t\t\t\t, progress: api.F\n\t\t\t\t\t, complete: api.F\n\t\t\t\t\t, pause: api.F\n\t\t\t\t\t, imageOriginal: true\n\t\t\t\t\t, chunkSize: api.chunkSize\n\t\t\t\t\t, chunkUploadRetry: api.chunkUploadRetry\n\t\t\t\t\t, uploadRetry: api.uploadRetry\n\t\t\t\t}, options);\n\n\n\t\t\t\tif( options.imageAutoOrientation && !options.imageTransform ){\n\t\t\t\t\toptions.imageTransform = { rotate: 'auto' };\n\t\t\t\t}\n\n\n\t\t\t\tvar\n\t\t\t\t\t  proxyXHR = new api.XHR(options)\n\t\t\t\t\t, dataArray = this._getFilesDataArray(options.files)\n\t\t\t\t\t, _this = this\n\t\t\t\t\t, _total = 0\n\t\t\t\t\t, _loaded = 0\n\t\t\t\t\t, _nextFile\n\t\t\t\t\t, _complete = false\n\t\t\t\t;\n\t\t\t\t_each(dataArray, function (data){\n\t\t\t\t\t_total += data.size;\n\t\t\t\t});\n\t\t\t\tproxyXHR.files = [];\n\t\t\t\t_each(dataArray, function (data){\n\t\t\t\t\tproxyXHR.files.push(data.file);\n\t\t\t\t});\n\t\t\t\tproxyXHR.total\t= _total;\n\t\t\t\tproxyXHR.loaded\t= 0;\n\t\t\t\tproxyXHR.filesLeft = dataArray.length;\n\t\t\t\toptions.beforeupload(proxyXHR, options);\n\t\t\t\t_nextFile = function (){\n\t\t\t\t\tvar\n\t\t\t\t\t\t  data = dataArray.shift()\n\t\t\t\t\t\t, _file = data && data.file\n\t\t\t\t\t\t, _fileLoaded = false\n\t\t\t\t\t\t, _fileOptions = _simpleClone(options)\n\t\t\t\t\t;\n\n\t\t\t\t\tproxyXHR.filesLeft = dataArray.length;\n\n\t\t\t\t\tif( _file && _file.name === api.expando ){\n\t\t\t\t\t\t_file = null;\n\t\t\t\t\t\tapi.log('[warn] FileAPI.upload() — called without files');\n\t\t\t\t\t}\n\n\t\t\t\t\tif( ( proxyXHR.statusText != 'abort' || proxyXHR.current ) && data ){\n\t\t\t\t\t\t_complete = false;\n\t\t\t\t\t\tproxyXHR.currentFile = _file;\n\t\t\t\t\t\tif (_file && options.prepare(_file, _fileOptions) === false) {\n\t\t\t\t\t\t\t_nextFile.call(_this);\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t_fileOptions.file = _file;\n\n\t\t\t\t\t\t_this._getFormData(_fileOptions, data, function (form){\n\t\t\t\t\t\t\tif( !_loaded ){\n\t\t\t\t\t\t\t\toptions.upload(proxyXHR, options);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar xhr = new api.XHR(_extend({}, _fileOptions, {\n\n\t\t\t\t\t\t\t\tupload: _file ? function (){\n\t\t\t\t\t\t\t\t\toptions.fileupload(_file, xhr, _fileOptions);\n\t\t\t\t\t\t\t\t} : noop,\n\n\t\t\t\t\t\t\t\tprogress: _file ? function (evt){\n\t\t\t\t\t\t\t\t\tif( !_fileLoaded ){\n\t\t\t\t\t\t\t\t\t\t_fileLoaded = (evt.loaded === evt.total);\n\t\t\t\t\t\t\t\t\t\toptions.fileprogress({\n\t\t\t\t\t\t\t\t\t\t\t  type:   'progress'\n\t\t\t\t\t\t\t\t\t\t\t, total:  data.total = evt.total\n\t\t\t\t\t\t\t\t\t\t\t, loaded: data.loaded = evt.loaded\n\t\t\t\t\t\t\t\t\t\t}, _file, xhr, _fileOptions);\n\t\t\t\t\t\t\t\t\t\toptions.progress({\n\t\t\t\t\t\t\t\t\t\t\t  type:   'progress'\n\t\t\t\t\t\t\t\t\t\t\t, total:  _total\n\t\t\t\t\t\t\t\t\t\t\t, loaded: proxyXHR.loaded = (_loaded + data.size * (evt.loaded/evt.total))|0\n\t\t\t\t\t\t\t\t\t\t}, _file, xhr, _fileOptions);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} : noop,\n\n\t\t\t\t\t\t\t\tcomplete: function (err){\n\t\t\t\t\t\t\t\t\t_each(_xhrPropsExport, function (name){\n\t\t\t\t\t\t\t\t\t\tproxyXHR[name] = xhr[name];\n\t\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\t\tif( _file ){\n\t\t\t\t\t\t\t\t\t\tdata.total = (data.total || data.size);\n\t\t\t\t\t\t\t\t\t\tdata.loaded\t= data.total;\n\n\t\t\t\t\t\t\t\t\t\tif( !err ) {\n\t\t\t\t\t\t\t\t\t\t\tthis.progress(data);\n\t\t\t\t\t\t\t\t\t\t\t_fileLoaded = true;\n\t\t\t\t\t\t\t\t\t\t\t_loaded += data.size; // data.size != data.total, it's desirable fix this\n\t\t\t\t\t\t\t\t\t\t\tproxyXHR.loaded = _loaded;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\toptions.filecomplete(err, xhr, _file, _fileOptions);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tsetTimeout(function () {_nextFile.call(_this);}, 0);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t})); // xhr\n\t\t\t\t\t\t\tproxyXHR.abort = function (current){\n\t\t\t\t\t\t\t\tif (!current) { dataArray.length = 0; }\n\t\t\t\t\t\t\t\tthis.current = current;\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\txhr.send(form);\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tvar successful = proxyXHR.status == 200 || proxyXHR.status == 201 || proxyXHR.status == 204;\n\t\t\t\t\t\toptions.complete(successful ? false : (proxyXHR.statusText || 'error'), proxyXHR, options);\n\t\t\t\t\t\t_complete = true;\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tsetTimeout(_nextFile, 0);\n\t\t\t\tproxyXHR.append = function (files, first) {\n\t\t\t\t\tfiles = api._getFilesDataArray([].concat(files));\n\n\t\t\t\t\t_each(files, function (data) {\n\t\t\t\t\t\t_total += data.size;\n\t\t\t\t\t\tproxyXHR.files.push(data.file);\n\t\t\t\t\t\tif (first) {\n\t\t\t\t\t\t\tdataArray.unshift(data);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdataArray.push(data);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tproxyXHR.statusText = \"\";\n\n\t\t\t\t\tif( _complete ){\n\t\t\t\t\t\t_nextFile.call(_this);\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\tproxyXHR.remove = function (file) {\n\t\t\t\t    var i = dataArray.length, _file;\n\t\t\t\t    while( i-- ){\n\t\t\t\t\t\tif( dataArray[i].file == file ){\n\t\t\t\t\t\t\t_file = dataArray.splice(i, 1);\n\t\t\t\t\t\t\t_total -= _file.size;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn\t_file;\n\t\t\t\t};\n\n\t\t\t\treturn proxyXHR;\n\t\t\t},\n\n\n\t\t\t_getFilesDataArray: function (data){\n\t\t\t\tvar files = [], oFiles = {};\n\n\t\t\t\tif( isInputFile(data) ){\n\t\t\t\t\tvar tmp = api.getFiles(data);\n\t\t\t\t\toFiles[data.name || 'file'] = data.getAttribute('multiple') !== null ? tmp : tmp[0];\n\t\t\t\t}\n\t\t\t\telse if( _isArray(data) && isInputFile(data[0]) ){\n\t\t\t\t\t_each(data, function (input){\n\t\t\t\t\t\toFiles[input.name || 'file'] = api.getFiles(input);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\toFiles = data;\n\t\t\t\t}\n\n\t\t\t\t_each(oFiles, function add(file, name){\n\t\t\t\t\tif( _isArray(file) ){\n\t\t\t\t\t\t_each(file, function (file){\n\t\t\t\t\t\t\tadd(file, name);\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\telse if( file && (file.name || file.image) ){\n\t\t\t\t\t\tfiles.push({\n\t\t\t\t\t\t\t  name: name\n\t\t\t\t\t\t\t, file: file\n\t\t\t\t\t\t\t, size: file.size\n\t\t\t\t\t\t\t, total: file.size\n\t\t\t\t\t\t\t, loaded: 0\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tif( !files.length ){\n\t\t\t\t\tfiles.push({ file: { name: api.expando } });\n\t\t\t\t}\n\n\t\t\t\treturn\tfiles;\n\t\t\t},\n\n\n\t\t\t_getFormData: function (options, data, fn){\n\t\t\t\tvar\n\t\t\t\t\t  file = data.file\n\t\t\t\t\t, name = data.name\n\t\t\t\t\t, filename = file.name\n\t\t\t\t\t, filetype = file.type\n\t\t\t\t\t, trans = api.support.transform && options.imageTransform\n\t\t\t\t\t, Form = new api.Form\n\t\t\t\t\t, queue = api.queue(function (){ fn(Form); })\n\t\t\t\t\t, isOrignTrans = trans && _isOriginTransform(trans)\n\t\t\t\t\t, postNameConcat = api.postNameConcat\n\t\t\t\t;\n\t\t\t\t_each(options.data, function add(val, name){\n\t\t\t\t\tif( typeof val == 'object' ){\n\t\t\t\t\t\t_each(val, function (v, i){\n\t\t\t\t\t\t\tadd(v, postNameConcat(name, i));\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tForm.append(name, val);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t(function _addFile(file\t\t\tload: function (url, fn){\n\t\t\t\tvar xhr = api.getXHR();\n\t\t\t\tif( xhr ){\n\t\t\t\t\txhr.open('GET', url, true);\n\n\t\t\t\t\tif( xhr.overrideMimeType ){\n\t\t\t\t        xhr.overrideMimeType('text/plain; charset=x-user-defined');\n\t\t\t\t\t}\n\n\t\t\t\t\t_on(xhr, 'progress', function (\t\t\t\t\t\tif( evt.lengthComputable ){\n\t\t\t\t\t\t\tfn({ type: evt.type, loaded: evt.loaded, total: evt.total }, xhr);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\txhr.onreadystatechange = function(){\n\t\t\t\t\t\tif( xhr.readyState == 4 ){\n\t\t\t\t\t\t\txhr.onreadystatechange = null;\n\t\t\t\t\t\t\tif( xhr.status == 200 ){\n\t\t\t\t\t\t\t\turl = url.split('/');\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tvar file = {\n\t\t\t\t\t\t\t\t      name: url[url.length-1]\n\t\t\t\t\t\t\t\t\t, size: xhr.getResponseHeader('Content-Length')\n\t\t\t\t\t\t\t\t\t, type: xhr.getResponseHeader('Content-Type')\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\tfile.dataURL = 'data:'+file.type+';base64,' + api.encode64(xhr.responseBody || xhr.responseText);\n\t\t\t\t\t\t\t\tfn({ type: 'load', result: file }, xhr);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tfn({ type: 'error' }, xhr);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t    }\n\t\t\t\t\t};\n\t\t\t\t    xhr.send(null);\n\t\t\t\t} else {\n\t\t\t\t\tfn({ type: 'error' });\n\t\t\t\t}\n\n\t\t\t\treturn  xhr;\n\t\t\t},\n\n\t\t\tencode64: function (str){\n\t\t\t\tvar b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=', outStr = '', i = 0;\n\n\t\t\t\tif( typeof str !== 'string' ){\n\t\t\t\t\tstr\t= String(str);\n\t\t\t\t}\n\n\t\t\t\twhile( i < str.length ){\n\t\t\t\t\tvar\n\t\t\t\t\t\t  byte1 = str.charCodeAt(i++) & 0xff\n\t\t\t\t\t\t, byte2 = str.charCodeAt(i++) & 0xff\n\t\t\t\t\t\t, byte3 = str.charCodeAt(i++) & 0xff\n\t\t\t\t\t\t, enc1 = byte1 >> 2\n\t\t\t\t\t\t, enc2 = ((byte1 & 3) << 4) | (byte2 >> 4)\n\t\t\t\t\t\t, enc3, enc4\n\t\t\t\t\t;\n\n\t\t\t\t\tif( isNaN(byte2) ){\n\t\t\t\t\t\tenc3 = enc4 = 64;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tenc3 = ((byte2 & 15) << 2) | (byte3 >> 6);\n\t\t\t\t\t\tenc4 = isNaN(byte3) ? 64 : byte3 & 63;\n\t\t\t\t\t}\n\n\t\t\t\t\toutStr += b64.charAt(enc1) + b64.charAt(enc2) + b64.charAt(enc3) + b64.charAt(enc4);\n\t\t\t\t}\n\n\t\t\t\treturn  outStr;\n\t\t\t}\n\n\t\t} // api\n\t;\n\n\n\tfunction _emit(target, fn, name, res, ext){\n\t\tvar evt = {\n\t\t\t  type:\t\tname.type || name\n\t\t\t, target:\ttarget\n\t\t\t, result:\tres\n\t\t};\n\t\t_extend(evt, ext);\n\t\tfn(evt);\n\t}\n\n\n\tfunction _hasSupportReadAs(as){\n\t\treturn\tFileReader && !!FileReader.prototype['readAs'+as];\n\t}\n\n\n\tfunction _readAs(file, fn, as, encoding){\n\t\tif( api.isBlob(file) && _hasSupportReadAs(as) ){\n\t\t\tvar Reader = new FileReader;\n\t\t\t_on(Reader, _readerEvents, function _fn(evt){\n\t\t\t\tvar type = evt.type;\n\t\t\t\tif( type == 'progress' ){\n\t\t\t\t\t_emit(file, fn, evt, evt.target.result, { loaded: evt.loaded, total: evt.total });\n\t\t\t\t}\n\t\t\t\telse if( type == 'loadend' ){\n\t\t\t\t\t_off(Reader, _readerEvents, _fn);\n\t\t\t\t\tReader = null;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t_emit(file, fn, evt, evt.target.result);\n\t\t\t\t}\n\t\t\t});\n\n\n\t\t\ttry {\n\t\t\t\tif( encoding ){\n\t\t\t\t\tReader['readAs'+as](file, encoding);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tReader['readAs'+as](file);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (err){\n\t\t\t\t_emit(file, fn, 'error', undef, { error: err.toString() });\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\t_emit(file, fn, 'error', undef, { error: 'filreader_not_support_'+as });\n\t\t}\n\t}\n\n\n\tfunction _isRegularFile(file, callback){\n\t\tif( !file.type && (file.size % 4096) === 0 && (file.size <= 102400) ){\n\t\t\tif( FileReader ){\n\t\t\t\ttry {\n\t\t\t\t\tvar Reader = new FileReader();\n\n\t\t\t\t\t_one(Reader, _readerEvents, function (evt){\n\t\t\t\t\t\tvar isFile = evt.type != 'error';\n\t\t\t\t\t\tcallback(isFile);\n\t\t\t\t\t\tif( isFile ){\n\t\t\t\t\t\t\tReader.abort();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\t\t\t\t\tReader.readAsDataURL(file);\n\t\t\t\t} catch( err ){\n\t\t\t\t\tcallback(false);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tcallback(null);\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tcallback(true);\n\t\t}\n\t}\n\n\n\tfunction _getAsEntry(item){\n\t\tvar entry;\n\t\tif( item.getAsEntry ){ entry = item.getAsEntry(); }\n\t\telse if( item.webkitGetAsEntry ){ entry = item.webkitGetAsEntry(); }\n\t\treturn\tentry;\n\t}\n\n\n\tfunction _readEntryAsFiles(entry, callback){\n\t\tif( !entry ){\n\t\t\tcallback('invalid entry');\n\t\t}\n\t\telse if( entry.isFile ){\n\t\t\tentry.file(function(file){\n\t\t\t\tfile.fullPath = entry.fullPath;\n\t\t\t\tcallback(false, [file]);\n\t\t\t}, function (err){\n\t\t\t\tcallback('FileError.code: '+err.code);\n\t\t\t});\n\t\t}\n\t\telse if( entry.isDirectory ){\n\t\t\tvar reader = entry.createReader(), result = [];\n\n\t\t\treader.readEntries(function(entries){\n\t\t\t\tapi.afor(entries, function (next, entry){\n\t\t\t\t\t_readEntryAsFiles(entry, function (err, files){\n\t\t\t\t\t\tif( err ){\n\t\t\t\t\t\t\tapi.log(err);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tresult = result.concat(files);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif( next ){\n\t\t\t\t\t\t\tnext();\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tcallback(false, result);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t}, function (err){\n\t\t\t\tcallback('directory_reader: ' + err);\n\t\t\t});\n\t\t}\n\t\telse {\n\t\t\t_readEntryAsFiles(_getAsEntry(entry), callback);\n\t\t}\n\t}\n\n\n\tfunction _simpleClone(obj){\n\t\tvar copy = {};\n\t\t_each(obj, function (val, key){\n\t\t\tif( val && (typeof val === 'object') && (val.nodeType === void 0) ){\n\t\t\t\tval = _extend({}, val);\n\t\t\t}\n\t\t\tcopy[key] = val;\n\t\t});\n\t\treturn\tcopy;\n\t}\n\n\n\tfunction isInputFile(el){\n\t\treturn\t_rinput.test(el && el.tagName);\n\t}\n\n\n\tfunction _getDataTransfer(evt){\n\t\treturn\t(evt.originalEvent || evt || '').dataTransfer || {};\n\t}\n\n\n\tfunction _isOriginTransform(trans){\n\t\tvar key;\n\t\tfor( key in trans ){\n\t\t\tif( trans.hasOwnProperty(key) ){\n\t\t\t\tif( !(trans[key] instanceof Object || key === 'overlay' || key === 'filter') ){\n\t\t\t\t\treturn\ttrue;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn\tfalse;\n\t}\n\tapi.addInfoReader(/^image/, function (file\tapi.event.dnd = function (el, onHover, onDrop){\n\t\tvar _id, _type;\n\n\t\tif( !onDrop ){\n\t\t\tonDrop = onHover;\n\t\t\tonHover = api.F;\n\t\t}\n\n\t\tif( FileReader ){\n\t\t\t_on(el, 'dragenter dragleave dragover', onHover.ff = onHover.ff || function (evt){\n\t\t\t\tvar\n\t\t\t\t\t  types = _getDataTransfer(evt).types\n\t\t\t\t\t, i = types && types.length\n\t\t\t\t\t, debounceTrigger = false\n\t\t\t\t;\n\n\t\t\t\twhile( i-- ){\n\t\t\t\t\tif( ~types[i].indexOf('File') ){\n\t\t\t\t\t\tevt[preventDefault]();\n\n\t\t\t\t\t\tif( _type !== evt.type ){\n\t\t\t\t\t\t\t_type = evt.type; // Store current type of event\n\n\t\t\t\t\t\t\tif( _type != 'dragleave' ){\n\t\t\t\t\t\t\t\tonHover.call(evt[currentTarget], true, evt);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tdebounceTrigger = true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak; // exit from \"while\"\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif( debounceTrigger ){\n\t\t\t\t\tclearTimeout(_id);\n\t\t\t\t\t_id = setTimeout(function (){\n\t\t\t\t\t\tonHover.call(evt[currentTarget], _type != 'dragleave', evt);\n\t\t\t\t\t}, 50);\n\t\t\t\t}\n\t\t\t});\n\t\t\t_on(el, 'drop', onDrop.ff = onDrop.ff || function (evt){\n\t\t\t\tevt[preventDefault]();\n\n\t\t\t\t_type = 0;\n\t\t\t\tonHover.call(evt[currentTarget], false, evt);\n\n\t\t\t\tapi.getDropFiles(evt, function (files){\n\t\t\t\t\tonDrop.call(evt[currentTarget], files, evt);\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\t\telse {\n\t\t\tapi.log(\"Drag'n'Drop -- not supported\");\n\t\t}\n\t};\n\n\n\t\tapi.event.dnd.off = function (el, onHover, onDrop){\n\t\t_off(el, 'dragenter dragleave dragover', onHover.ff);\n\t\t_off(el, 'drop', onDrop.ff);\n\t};\n\tif( jQuery && !jQuery.fn.dnd ){\n\t\tjQuery.fn.dnd = function (onHover, onDrop){\n\t\t\treturn this.each(function (){\n\t\t\t\tapi.event.dnd(this, onHover, onDrop);\n\t\t\t});\n\t\t};\n\n\t\tjQuery.fn.offdnd = function (onHover, onDrop){\n\t\t\treturn this.each(function (){\n\t\t\t\tapi.event.dnd.off(this, onHover, onDrop);\n\t\t\t});\n\t\t};\n\t}\n\twindow.FileAPI  = _extend(api, window.FileAPI);\n\tapi.log('FileAPI: ' + api.version);\n\tapi.log('protocol: ' + window.location.protocol);\n\tapi.log('doctype: [' + doctype.name + '] ' + doctype.publicId + ' ' + doctype.systemId);\n\t_each(document.getElementsByTagName('meta'), function (meta){\n\t\tif( /x-ua-compatible/i.test(meta.getAttribute('http-equiv')) ){\n\t\t\tapi.log('meta.http-equiv: ' + meta.getAttribute('content'));\n\t\t}\n\t});\n\tif( !api.flashUrl ){ api.flashUrl = api.staticPath + 'FileAPI.flash.swf'; }\n\tif( !api.flashImageUrl ){ api.flashImageUrl = api.staticPath + 'FileAPI.flash.image.swf'; }\n\tif( !api.flashWebcamUrl ){ api.flashWebcamUrl = api.staticPath + 'FileAPI.flash.camera.swf'; }\n})(window, void 0);\n\n/*global window, FileAPI, document */\n\n(function (api, document, undef) {\n\t'use strict';\n\n\tvar\n\t\tmin = Math.min,\n\t\tround = Math.round,\n\t\tgetCanvas = function () { return document.createElement('canvas'); },\n\t\tsupport = false,\n\t\texifOrientation = {\n\t\t\t  8:\t270\n\t\t\t, 3:\t180\n\t\t\t, 6:\t90\n\t\t\t, 7:\t270\n\t\t\t, 4:\t180\n\t\t\t, 5:\t90\n\t\t}\n\t;\n\n\ttry {\n\t\tsupport = getCanvas().toDataURL('image/png').indexOf('data:image/png') > -1;\n\t}\n\tcatch (e){}\n\n\n\tfunction Image(file){\n\t\tif( file instanceof Image ){\n\t\t\tvar img = new Image(file.file);\n\t\t\tapi.extend(img.matrix, file.matrix);\n\t\t\treturn\timg;\n\t\t}\n\t\telse if( !(this instanceof Image) ){\n\t\t\treturn\tnew Image(file);\n\t\t}\n\n\t\tthis.file   = file;\n\t\tthis.size   = file.size || 100;\n\n\t\tthis.matrix\t= {\n\t\t\tsx: 0,\n\t\t\tsy: 0,\n\t\t\tsw: 0,\n\t\t\tsh: 0,\n\t\t\tdx: 0,\n\t\t\tdy: 0,\n\t\t\tdw: 0,\n\t\t\tdh: 0,\n\t\t\tresize: 0, // min, max OR preview\n\t\t\tdeg: 0,\n\t\t\tquality: 1, // jpeg quality\n\t\t\tfilter: 0\n\t\t};\n\t}\n\n\n\tImage.prototype = {\n\t\timage: true,\n\t\tconstructor: Image,\n\n\t\tset: function (attrs){\n\t\t\tapi.extend(this.matrix, attrs);\n\t\t\treturn\tthis;\n\t\t},\n\n\t\tcrop: function (x, y, w, h){\n\t\t\tif( w === undef ){\n\t\t\t\tw\t= x;\n\t\t\t\th\t= y;\n\t\t\t\tx = y = 0;\n\t\t\t}\n\t\t\treturn\tthis.set({ sx: x, sy: y, sw: w, sh: h || w });\n\t\t},\n\n\t\tresize: function (w, h, strategy){\n\t\t\tif( /min|max/.test(h) ){\n\t\t\t\tstrategy = h;\n\t\t\t\th = w;\n\t\t\t}\n\n\t\t\treturn\tthis.set({ dw: w, dh: h || w, resize: strategy });\n\t\t},\n\n\t\tpreview: function (w, h){\n\t\t\treturn\tthis.resize(w, h || w, 'preview');\n\t\t},\n\n\t\trotate: function (deg){\n\t\t\treturn\tthis.set({ deg: deg });\n\t\t},\n\n\t\tfilter: function (filter){\n\t\t\treturn\tthis.set({ filter: filter });\n\t\t},\n\n\t\toverlay: function (images){\n\t\t\treturn\tthis.set({ overlay: images });\n\t\t},\n\n\t\tclone: function (){\n\t\t\treturn\tnew Image(this);\n\t\t},\n\n\t\t_load: function (image, fn){\n\t\t\tvar self = this;\n\n\t\t\tif( /img|video/i.test(image.nodeName) ){\n\t\t\t\tfn.call(self, null, image);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tapi.readAsImage(image, function (evt){\n\t\t\t\t\tfn.call(self, evt.type != 'load', evt.result);\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\n\t\t_apply: function (image, fn){\n\t\t\tvar\n\t\t\t\t  canvas = getCanvas()\n\t\t\t\t, m = this.getMatrix(image)\n\t\t\t\t, ctx = canvas.getContext('2d')\n\t\t\t\t, width = image.videoWidth || image.width\n\t\t\t\t, height = image.videoHeight || image.height\n\t\t\t\t, deg = m.deg\n\t\t\t\t, dw = m.dw\n\t\t\t\t, dh = m.dh\n\t\t\t\t, w = width\n\t\t\t\t, h = height\n\t\t\t\t, filter = m.filter\n\t\t\t\t, copy // canvas copy\n\t\t\t\t, buffer = image\n\t\t\t\t, overlay = m.overlay\n\t\t\t\t, queue = api.queue(function (){ image.src = api.EMPTY_PNG; fn(false, canvas); })\n\t\t\t\t, renderImageToCanvas = api.renderImageToCanvas\n\t\t\t;\n\t\t\tdeg = deg - Math.floor(deg/360)*360;\n\t\t\timage._type = this.file.type;\n\n\t\t\twhile(m.multipass && min(w/dw, h/dh) > 2 ){\n\t\t\t\tw = (w/2 + 0.5)|0;\n\t\t\t\th = (h/2 + 0.5)|0;\n\n\t\t\t\tcopy = getCanvas();\n\t\t\t\tcopy.width  = w;\n\t\t\t\tcopy.height = h;\n\n\t\t\t\tif( buffer !== image ){\n\t\t\t\t\trenderImageToCanvas(copy, buffer, 0, 0, buffer.width, buffer.height, 0, 0, w, h);\n\t\t\t\t\tbuffer = copy;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tbuffer = copy;\n\t\t\t\t\trenderImageToCanvas(buffer, image, m.sx, m.sy, m.sw, m.sh, 0, 0, w, h);\n\t\t\t\t\tm.sx = m.sy = m.sw = m.sh = 0;\n\t\t\t\t}\n\t\t\t}\n\n\n\t\t\tcanvas.width  = (deg % 180) ? dh : dw;\n\t\t\tcanvas.height = (deg % 180) ? dw : dh;\n\n\t\t\tcanvas.type = m.type;\n\t\t\tcanvas.quality = m.quality;\n\n\t\t\tctx.rotate(deg * Math.PI / 180);\n\t\t\trenderImageToCanvas(ctx.canvas, buffer\n\t\t\t\t, m.sx, m.sy\n\t\t\t\t, m.sw || buffer.width\n\t\t\t\t, m.sh || buffer.height\n\t\t\t\t, (deg == 180 || deg == 270 ? -dw : 0)\n\t\t\t\t, (deg == 90 || deg == 180 ? -dh : 0)\n\t\t\t\t, dw, dh\n\t\t\t);\n\t\t\tdw = canvas.width;\n\t\t\tdh = canvas.height;\n\t\t\toverlay && api.each([].concat(overlay), function (over){\n\t\t\t\tqueue.inc();\n\t\t\t\tvar img = new window.Image, fn = function (){\n\t\t\t\t\tvar\n\t\t\t\t\t\t  x = over.x|0\n\t\t\t\t\t\t, y = over.y|0\n\t\t\t\t\t\t, w = over.w || img.width\n\t\t\t\t\t\t, h = over.h || img.height\n\t\t\t\t\t\t, rel = over.rel\n\t\t\t\t\t;\n\t\t\t\t\tx = (rel == 1 || rel == 4 || rel == 7) ? (dw - w + x)/2 : (rel == 2 || rel == 5 || rel == 8 ? dw - (w + x) : x);\n\t\t\t\t\ty = (rel == 3 || rel == 4 || rel == 5) ? (dh - h + y)/2 : (rel >= 6 ? dh - (h + y) : y);\n\n\t\t\t\t\tapi.event.off(img, 'error load abort', fn);\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tctx.globalAlpha = over.opacity || 1;\n\t\t\t\t\t\tctx.drawImage(img, x, y, w, h);\n\t\t\t\t\t}\n\t\t\t\t\tcatch (er){}\n\n\t\t\t\t\tqueue.next();\n\t\t\t\t};\n\n\t\t\t\tapi.event.on(img, 'error load abort', fn);\n\t\t\t\timg.src = over.src;\n\n\t\t\t\tif( img.complete ){\n\t\t\t\t\tfn();\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif( filter ){\n\t\t\t\tqueue.inc();\n\t\t\t\tImage.applyFilter(canvas, filter, queue.next);\n\t\t\t}\n\n\t\t\tqueue.check();\n\t\t},\n\n\t\tgetMatrix: function (image){\n\t\t\tvar\n\t\t\t\t  m  = api.extend({}, this.matrix)\n\t\t\t\t, sw = m.sw = m.sw || image.videoWidth || image.naturalWidth ||  image.width\n\t\t\t\t, sh = m.sh = m.sh || image.videoHeight || image.naturalHeight || image.height\n\t\t\t\t, dw = m.dw = m.dw || sw\n\t\t\t\t, dh = m.dh = m.dh || sh\n\t\t\t\t, sf = sw/sh, df = dw/dh\n\t\t\t\t, strategy = m.resize\n\t\t\t;\n\n\t\t\tif( strategy == 'preview' ){\n\t\t\t\tif( dw != sw || dh != sh ){\n\t\t\t\t\tvar w, h;\n\n\t\t\t\t\tif( df >= sf ){\n\t\t\t\t\t\tw\t= sw;\n\t\t\t\t\t\th\t= w / df;\n\t\t\t\t\t} else {\n\t\t\t\t\t\th\t= sh;\n\t\t\t\t\t\tw\t= h * df;\n\t\t\t\t\t}\n\n\t\t\t\t\tif( w != sw || h != sh ){\n\t\t\t\t\t\tm.sx\t= ~~((sw - w)/2);\n\t\t\t\t\t\tm.sy\t= ~~((sh - h)/2);\n\t\t\t\t\t\tsw\t\t= w;\n\t\t\t\t\t\tsh\t\t= h;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if( strategy ){\n\t\t\t\tif( !(sw > dw || sh > dh) ){\n\t\t\t\t\tdw = sw;\n\t\t\t\t\tdh = sh;\n\t\t\t\t}\n\t\t\t\telse if( strategy == 'min' ){\n\t\t\t\t\tdw = round(sf < df ? min(sw, dw) : dh*sf);\n\t\t\t\t\tdh = round(sf < df ? dw/sf : min(sh, dh));\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tdw = round(sf >= df ? min(sw, dw) : dh*sf);\n\t\t\t\t\tdh = round(sf >= df ? dw/sf : min(sh, dh));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tm.sw = sw;\n\t\t\tm.sh = sh;\n\t\t\tm.dw = dw;\n\t\t\tm.dh = dh;\n\t\t\tm.multipass = api.multiPassResize;\n\t\t\treturn\tm;\n\t\t},\n\n\t\t_trans: function (fn){\n\t\t\tthis._load(this.file, function (err, image){\n\t\t\t\tif( err ){\n\t\t\t\t\tfn(err);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis._apply(image, fn);\n\t\t\t\t\t} catch (err){\n\t\t\t\t\t\tapi.log('[err] FileAPI.Image.fn._apply:', err);\n\t\t\t\t\t\tfn(err);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\n\t\tget: function (fn){\n\t\t\tif( api.support.transform ){\n\t\t\t\tvar _this = this, matrix = _this.matrix;\n\n\t\t\t\tif( matrix.deg == 'auto' ){\n\t\t\t\t\tapi.getInfo(_this.file, function (err, info){\n\t\t\t\t\t\tmatrix.deg = exifOrientation[info && info.exif && info.exif.Orientation] || 0;\n\t\t\t\t\t\t_this._trans(fn);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t_this._trans(fn);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tfn('not_support_transform');\n\t\t\t}\n\n\t\t\treturn this;\n\t\t},\n\n\n\t\ttoData: function (fn){\n\t\t\treturn this.get(fn);\n\t\t}\n\n\t};\n\n\n\tImage.exifOrientation = exifOrientation;\n\n\n\tImage.transform = function (file, transform, autoOrientation, fn){\n\t\tfunction _transform(err, img){\n\t\t\tvar\n\t\t\t\t  images = {}\n\t\t\t\t, queue = api.queue(function (err){\n\t\t\t\t\tfn(err, images);\n\t\t\t\t})\n\t\t\t;\n\n\t\t\tif( !err ){\n\t\t\t\tapi.each(transform, function (params, name){\n\t\t\t\t\tif( !queue.isFail() ){\n\t\t\t\t\t\tvar ImgTrans = new Image(img.nodeType ? img : file), isFn = typeof params == 'function';\n\n\t\t\t\t\t\tif( isFn ){\n\t\t\t\t\t\t\tparams(img, ImgTrans);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if( params.width ){\n\t\t\t\t\t\t\tImgTrans[params.preview ? 'preview' : 'resize'](params.width, params.height, params.strategy);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tif( params.maxWidth && (img.width > params.maxWidth || img.height > params.maxHeight) ){\n\t\t\t\t\t\t\t\tImgTrans.resize(params.maxWidth, params.maxHeight, 'max');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif( params.crop ){\n\t\t\t\t\t\t\tvar crop = params.crop;\n\t\t\t\t\t\t\tImgTrans.crop(crop.x|0, crop.y|0, crop.w || crop.width, crop.h || crop.height);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif( params.rotate === undef && autoOrientation ){\n\t\t\t\t\t\t\tparams.rotate = 'auto';\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tImgTrans.set({ type: ImgTrans.matrix.type || params.type || file.type || 'image/png' });\n\n\t\t\t\t\t\tif( !isFn ){\n\t\t\t\t\t\t\tImgTrans.set({\n\t\t\t\t\t\t\t\t  deg: params.rotate\n\t\t\t\t\t\t\t\t, overlay: params.overlay\n\t\t\t\t\t\t\t\t, filter: params.filter\n\t\t\t\t\t\t\t\t, quality: params.quality || 1\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tqueue.inc();\n\t\t\t\t\t\tImgTrans.toData(function (err, image){\n\t\t\t\t\t\t\tif( err ){\n\t\t\t\t\t\t\t\tqueue.fail();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\timages[name] = image;\n\t\t\t\t\t\t\t\tqueue.next();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\telse {\n\t\t\t\tqueue.fail();\n\t\t\t}\n\t\t}\n\t\tif( file.width ){\n\t\t\t_transform(false, file);\n\t\t} else {\n\t\t\tapi.getInfo(file, _transform);\n\t\t}\n\t};\n\tapi.each(['TOP', 'CENTER', 'BOTTOM'], function (x, i){\n\t\tapi.each(['LEFT', 'CENTER', 'RIGHT'], function (y, j){\n\t\t\tImage[x+'_'+y] = i*3 + j;\n\t\t\tImage[y+'_'+x] = i*3 + j;\n\t\t});\n\t});\n\n\n\t\tImage.toCanvas = function(el){\n\t\tvar canvas\t\t= document.createElement('canvas');\n\t\tcanvas.width\t= el.videoWidth || el.width;\n\t\tcanvas.height\t= el.videoHeight || el.height;\n\t\tcanvas.getContext('2d').drawImage(el, 0, 0);\n\t\treturn\tcanvas;\n\t};\n\n\n\t\tImage.fromDataURL = function (dataURL, size, callback){\n\t\tvar img = api.newImage(dataURL);\n\t\tapi.extend(img, size);\n\t\tcallback(img);\n\t};\n\n\n\t\tImage.applyFilter = function (canvas, filter, doneFn){\n\t\tif( typeof filter == 'function' ){\n\t\t\tfilter(canvas, doneFn);\n\t\t}\n\t\telse if( window.Caman ){\n\t\t\twindow.Caman(canvas.tagName == 'IMG' ? Image.toCanvas(canvas) : canvas, function (){\n\t\t\t\tif( typeof filter == 'string' ){\n\t\t\t\t\tthis[filter]();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tapi.each(filter, function (val, method){\n\t\t\t\t\t\tthis[method](val);\n\t\t\t\t\t}, this);\n\t\t\t\t}\n\t\t\t\tthis.render(doneFn);\n\t\t\t});\n\t\t}\n\t};\n\n\n\t\tapi.renderImageToCanvas = function (canvas, img, sx, sy, sw, sh, dx, dy, dw, dh){\n\t\ttry {\n\t\t\treturn canvas.getContext('2d').drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh);\n\t\t} catch (ex) {\n\t\t\tapi.log('renderImageToCanvas failed');\n\t\t\tthrow ex;\n\t\t}\n\t};\n\tapi.support.canvas = api.support.transform = support;\n\tapi.Image = Image;\n})(FileAPI, document);\n\n/*\n * JavaScript Load Image iOS scaling fixes 1.0.3\n * https://github.com/blueimp/JavaScript-Load-Image\n *\n * Copyright 2013, Sebastian Tschan\n * https://blueimp.net\n *\n * iOS image scaling fixes based on\n * https://github.com/stomita/ios-imagefile-megapixel\n *\n * Licensed under the MIT license:\n * http://www.opensource.org/licenses/MIT\n */\n\n/*jslint nomen: true, bitwise: true */\n/*global FileAPI, window, document */\n\n(function (factory) {\n\t'use strict';\n\tfactory(FileAPI);\n}(function (loadImage) {\n    'use strict';\n    if (!window.navigator || !window.navigator.platform ||\n             !(/iP(hone|od|ad)/).test(window.navigator.platform)) {\n        return;\n    }\n\n    var originalRenderMethod = loadImage.renderImageToCanvas;\n    loadImage.detectSubsampling = function (img) {\n        var canvas,\n            context;\n        if (img.width * img.height > 1024 * 1024) { // only consider mexapixel images\n            canvas = document.createElement('canvas');\n            canvas.width = canvas.height = 1;\n            context = canvas.getContext('2d');\n            context.drawImage(img, -img.width + 1, 0);\n            return context.getImageData(0, 0, 1, 1).data[3] === 0;\n        }\n        return false;\n    };\n    loadImage.detectVerticalSquash = function (img, subsampled) {\n        var naturalHeight = img.naturalHeight || img.height,\n            canvas = document.createElement('canvas'),\n            context = canvas.getContext('2d'),\n            data,\n            sy,\n            ey,\n            py,\n            alpha;\n        if (subsampled) {\n            naturalHeight /= 2;\n        }\n        canvas.width = 1;\n        canvas.height = naturalHeight;\n        context.drawImage(img, 0, 0);\n        data = context.getImageData(0, 0, 1, naturalHeight).data;\n        sy = 0;\n        ey = naturalHeight;\n        py = naturalHeight;\n        while (py > sy) {\n            alpha = data[(py - 1) * 4 + 3];\n            if (alpha === 0) {\n                ey = py;\n            } else {\n                sy = py;\n            }\n            py = (ey + sy) >> 1;\n        }\n        return (py / naturalHeight) || 1;\n    };\n    loadImage.renderImageToCanvas = function (\n        canvas,\n        img,\n        sourceX,\n        sourceY,\n        sourceWidth,\n        sourceHeight,\n        destX,\n        destY,\n        destWidth,\n        destHeight\n    ) {\n        if (img._type === 'image/jpeg') {\n            var context = canvas.getContext('2d'),\n                tmpCanvas = document.createElement('canvas'),\n                tileSize = 1024,\n                tmpContext = tmpCanvas.getContext('2d'),\n                subsampled,\n                vertSquashRatio,\n                tileX,\n                tileY;\n            tmpCanvas.width = tileSize;\n            tmpCanvas.height = tileSize;\n            context.save();\n            subsampled = loadImage.detectSubsampling(img);\n            if (subsampled) {\n                sourceX /= 2;\n                sourceY /= 2;\n                sourceWidth /= 2;\n                sourceHeight /= 2;\n            }\n            vertSquashRatio = loadImage.detectVerticalSquash(img, subsampled);\n            if (subsampled || vertSquashRatio !== 1) {\n                sourceY *= vertSquashRatio;\n                destWidth = Math.ceil(tileSize * destWidth / sourceWidth);\n                destHeight = Math.ceil(\n                    tileSize * destHeight / sourceHeight / vertSquashRatio\n                );\n                destY = 0;\n                tileY = 0;\n                while (tileY < sourceHeight) {\n                    destX = 0;\n                    tileX = 0;\n                    while (tileX < sourceWidth) {\n                        tmpContext.clearRect(0, 0, tileSize, tileSize);\n                        tmpContext.drawImage(\n                            img,\n                            sourceX,\n                            sourceY,\n                            sourceWidth,\n                            sourceHeight,\n                            -tileX,\n                            -tileY,\n                            sourceWidth,\n                            sourceHeight\n                        );\n                        context.drawImage(\n                            tmpCanvas,\n                            0,\n                            0,\n                            tileSize,\n                            tileSize,\n                            destX,\n                            destY,\n                            destWidth,\n                            destHeight\n                        );\n                        tileX += tileSize;\n                        destX += destWidth;\n                    }\n                    tileY += tileSize;\n                    destY += destHeight;\n                }\n                context.restore();\n                return canvas;\n            }\n        }\n        return originalRenderMethod(\n            canvas,\n            img,\n            sourceX,\n            sourceY,\n            sourceWidth,\n            sourceHeight,\n            destX,\n            destY,\n            destWidth,\n            destHeight\n        );\n    };\n\n}));\n\n/*global window, FileAPI */\n\n(function (api, window){\n\t\"use strict\";\n\n\tvar\n\t\t  document = window.document\n\t\t, FormData = window.FormData\n\t\t, Form = function (){ this.items = []; }\n\t\t, encodeURIComponent = window.encodeURIComponent\n\t;\n\n\n\tForm.prototype = {\n\n\t\tappend: function (name, blob, file, type){\n\t\t\tthis.items.push({\n\t\t\t\t  name: name\n\t\t\t\t, blob: blob && blob.blob || (blob == void 0 ? '' : blob)\n\t\t\t\t, file: blob && (file || blob.name)\n\t\t\t\t, type:\tblob && (type || blob.type)\n\t\t\t});\n\t\t},\n\n\t\teach: function (fn){\n\t\t\tvar i = 0, n = this.items.length;\n\t\t\tfor( ; i < n; i++ ){\n\t\t\t\tfn.call(this, this.items[i]);\n\t\t\t}\n\t\t},\n\n\t\ttoData: function (fn, options){\n\t\t    options._chunked = api.support.chunked && options.chunkSize > 0 && api.filter(this.items, function (item){ return item.file; }).length == 1;\n\n\t\t\tif( !api.support.html5 ){\n\t\t\t\tapi.log('FileAPI.Form.toHtmlData');\n\t\t\t\tthis.toHtmlData(fn);\n\t\t\t}\n\t\t\telse if( !api.formData || this.multipart || !FormData ){\n\t\t\t\tapi.log('FileAPI.Form.toMultipartData');\n\t\t\t\tthis.toMultipartData(fn);\n\t\t\t}\n\t\t\telse if( options._chunked ){\n\t\t\t\tapi.log('FileAPI.Form.toPlainData');\n\t\t\t\tthis.toPlainData(fn);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tapi.log('FileAPI.Form.toFormData');\n\t\t\t\tthis.toFormData(fn);\n\t\t\t}\n\t\t},\n\n\t\t_to: function (data, complete, next, arg){\n\t\t\tvar queue = api.queue(function (){\n\t\t\t\tcomplete(data);\n\t\t\t});\n\n\t\t\tthis.each(function (file){\n\t\t\t\tnext(file, data, queue, arg);\n\t\t\t});\n\n\t\t\tqueue.check();\n\t\t},\n\n\n\t\ttoHtmlData: function (fn){\n\t\t\tthis._to(document.createDocumentFragment(), fn, function (file, data\n(function (window, api){\n\t\"use strict\";\n\n\tvar\n\t\t  noop = function (){}\n\t\t, document = window.document\n\n\t\t, XHR = function (options){\n\t\t\tthis.uid = api.uid();\n\t\t\tthis.xhr = {\n\t\t\t\t  abort: noop\n\t\t\t\t, getResponseHeader: noop\n\t\t\t\t, getAllResponseHeaders: noop\n\t\t\t};\n\t\t\tthis.options = options;\n\t\t},\n\n\t\t_xhrResponsePostfix = { '': 1, XML: 1, Text: 1, Body: 1 }\n\t;\n\n\n\tXHR.prototype = {\n\t\tstatus: 0,\n\t\tstatusText: '',\n\t\tconstructor: XHR,\n\n\t\tgetResponseHeader: function (name){\n\t\t\treturn this.xhr.getResponseHeader(name);\n\t\t},\n\n\t\tgetAllResponseHeaders: function (){\n\t\t\treturn this.xhr.getAllResponseHeaders() || {};\n\t\t},\n\n\t\tend: function (status, statusText){\n\t\t\tvar _this = this, options = _this.options;\n\n\t\t\t_this.end\t\t=\n\t\t\t_this.abort\t\t= noop;\n\t\t\t_this.status\t= status;\n\n\t\t\tif( statusText ){\n\t\t\t\t_this.statusText = statusText;\n\t\t\t}\n\n\t\t\tapi.log('xhr.end:', status, statusText);\n\t\t\toptions.complete(status == 200 || status == 201 ? false : _this.statusText || 'unknown', _this);\n\n\t\t\tif( _this.xhr && _this.xhr.node ){\n\t\t\t\tsetTimeout(function (){\n\t\t\t\t\tvar node = _this.xhr.node;\n\t\t\t\t\ttry { node.parentNode.removeChild(node); } catch (e){}\n\t\t\t\t\ttry { delete window[_this.uid]; } catch (e){}\n\t\t\t\t\twindow[_this.uid] = _this.xhr.node = null;\n\t\t\t\t}, 9);\n\t\t\t}\n\t\t},\n\n\t\tabort: function (){\n\t\t\tthis.end(0, 'abort');\n\n\t\t\tif( this.xhr ){\n\t\t\t\tthis.xhr.aborted = true;\n\t\t\t\tthis.xhr.abort();\n\t\t\t}\n\t\t},\n\n\t\tsend: function (FormData){\n\t\t\tvar _this = this, options = this.options;\n\n\t\t\tFormData.toData(function (data){\n\t\t\t\toptions.upload(options, _this);\n\t\t\t\t_this._send.call(_this, options, data);\n\t\t\t}, options);\n\t\t},\n\n\t\t_send: function (options, data){\n\t\t\tvar _this = this, xhr, uid = _this.uid, onloadFuncName = _this.uid + \"Load\", url = options.url;\n\n\t\t\tapi.log('XHR._send:', data);\n\n\t\t\tif( !options.cache ){\n\t\t\t\turl += (~url.indexOf('?') ? '&' : '?') + api.uid();\n\t\t\t}\n\n\t\t\tif( data.nodeName ){\n\t\t\t\tvar jsonp = options.jsonp;\n\t\t\t\turl = url.replace(/([a-z]+)=(\\?)/i, '$1='+uid);\n\t\t\t\toptions.upload(options, _this);\n\n\t\t\t\tvar\n\t\t\t\t\tonPostMessage = function (evt){\n\t\t\t\t\t\tif( ~url.indexOf(evt.origin) ){\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tvar result = api.parseJSON(evt.data);\n\t\t\t\t\t\t\t\tif( result.id == uid ){\n\t\t\t\t\t\t\t\t\tcomplete(result.status, result.statusText, result.response);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} catch( err ){\n\t\t\t\t\t\t\t\tcomplete(0, err.message);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\tcomplete = window[uid] = function (status, statusText, response){\n\t\t\t\t\t\t_this.readyState\t= 4;\n\t\t\t\t\t\t_this.responseText\t= response;\n\t\t\t\t\t\t_this.end(status, statusText);\n\n\t\t\t\t\t\tapi.event.off(window, 'message', onPostMessage);\n\t\t\t\t\t\twindow[uid] = xhr = transport = window[onloadFuncName] = null;\n\t\t\t\t\t}\n\t\t\t\t;\n\n\t\t\t\t_this.xhr.abort = function (){\n\t\t\t\t\ttry {\n\t\t\t\t\t\tif( transport.stop ){ transport.stop(); }\n\t\t\t\t\t\telse if( transport.contentWindow.stop ){ transport.contentWindow.stop(); }\n\t\t\t\t\t\telse { transport.contentWindow.document.execCommand('Stop'); }\n\t\t\t\t\t}\n\t\t\t\t\tcatch (er) {}\n\t\t\t\t\tcomplete(0, \"abort\");\n\t\t\t\t};\n\n\t\t\t\tapi.event.on(window, 'message', onPostMessage);\n\n\t\t\t\twindow[onloadFuncName] = function (){\n\t\t\t\t\ttry {\n\t\t\t\t\t\tvar\n\t\t\t\t\t\t\t  win = transport.contentWindow\n\t\t\t\t\t\t\t, doc = win.document\n\t\t\t\t\t\t\t, result = win.result || api.parseJSON(doc.body.innerHTML)\n\t\t\t\t\t\t;\n\t\t\t\t\t\tcomplete(result.status, result.statusText, result.response);\n\t\t\t\t\t} catch (e){\n\t\t\t\t\t\tapi.log('[transport.onload]', e);\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\txhr = document.createElement('div');\n\t\t\t\txhr.innerHTML = '<form target=\"'+ uid +'\" action=\"'+ url +'\" method=\"POST\" enctype=\"multipart/form-data\" style=\"position: absolute; top: -1000px; overflow: hidden; width: 1px; height: 1px;\">'\n\t\t\t\t\t\t\t+ '<iframe name=\"'+ uid +'\" src=\"javascript:false;\" onload=\"' + onloadFuncName + '()\"></iframe>'\n\t\t\t\t\t\t\t+ (jsonp && (options.url.indexOf('=?') < 0) ? '<input value=\"'+ uid +'\" name=\"'+jsonp+'\" type=\"hidden\"/>' : '')\n\t\t\t\t\t\t\t+ '</form>'\n\t\t\t\t;\n\t\t\t\tvar\n\t\t\t\t\t  form = xhr.getElementsByTagName('form')[0]\n\t\t\t\t\t, transport = xhr.getElementsByTagName('iframe')[0]\n\t\t\t\t;\n\n\t\t\t\tform.appendChild(data);\n\n\t\t\t\tapi.log(form.parentNode.innerHTML);\n\t\t\t\tdocument.body.appendChild(xhr);\n\t\t\t\t_this.xhr.node = xhr;\n\t\t\t\t_this.readyState = 2; // loaded\n\t\t\t\tform.submit();\n\t\t\t\tform = null;\n\t\t\t}\n\t\t\telse {\n\t\t\t\turl = url.replace(/([a-z]+)=(\\?)&?/i, '');\n\t\t\t\tif (this.xhr && this.xhr.aborted) {\n\t\t\t\t\tapi.log(\"Error: already aborted\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\txhr = _this.xhr = api.getXHR();\n\n\t\t\t\tif (data.params) {\n\t\t\t\t\turl += (url.indexOf('?') < 0 ? \"?\" : \"&\") + data.params.join(\"&\");\n\t\t\t\t}\n\n\t\t\t\txhr.open('POST', url, true);\n\n\t\t\t\tif( api.withCredentials ){\n\t\t\t\t\txhr.withCredentials = \"true\";\n\t\t\t\t}\n\n\t\t\t\tif( !options.headers || !options.headers['X-Requested-With'] ){\n\t\t\t\t\txhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');\n\t\t\t\t}\n\n\t\t\t\tapi.each(options.headers, function (val, key){\n\t\t\t\t\txhr.setRequestHeader(key, val);\n\t\t\t\t});\n\n\n\t\t\t\tif ( options._chunked ) {\n\t\t\t\t\tif( xhr.upload ){\n\t\t\t\t\t\txhr.upload.addEventListener('progress', api.throttle(function (\t\t\t\t\t\tif( xhr.sendAsBinary ){\n\t\t\t\t\t\t\txhr.sendAsBinary(rawData);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tvar bytes = Array.prototype.map.call(rawData, function(c){ return c.charCodeAt(0) & 0xff; });\n\t\t\t\t\t\t\txhr.send(new Uint8Array(bytes).buffer);\n\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\txhr.send(data);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\tapi.XHR = XHR;\n})(window, FileAPI);\n\n\n/*global window, FileAPI, jQuery */\n(function (window, api){\n\t\"use strict\";\n\n\tvar\n\t\tURL = window.URL || window.webkitURL,\n\n\t\tdocument = window.document,\n\t\tnavigator = window.navigator,\n\n\t\tgetMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia,\n\n\t\thtml5 = !!getMedia\n\t;\n\tapi.support.media = html5;\n\n\n\tvar Camera = function (video){\n\t\tthis.video = video;\n\t};\n\n\n\tCamera.prototype = {\n\t\tisActive: function (){\n\t\t\treturn\t!!this._active;\n\t\t},\n\n\n\t\t\t\tstart: function (callback){\n\t\t\tvar\n\t\t\t\t  _this = this\n\t\t\t\t, video = _this.video\n\t\t\t\t, _successId\n\t\t\t\t, _failId\n\t\t\t\t, _complete = function (err){\n\t\t\t\t\t_this._active = !err;\n\t\t\t\t\tclearTimeout(_failId);\n\t\t\t\t\tclearTimeout(_successId);\n\t\t\t\t\tcallback && callback(err, _this);\n\t\t\t\t}\n\t\t\t;\n\n\t\t\tgetMedia.call(navigator, { video: true }, function (stream\t\tstop: function (){\n\t\t\ttry {\n\t\t\t\tthis._active = false;\n\t\t\t\tthis.video.pause();\n\t\t\t\tthis.stream.stop();\n\t\t\t} catch( err ){ }\n\t\t},\n\n\n\t\t\t\tshot: function (){\n\t\t\treturn\tnew Shot(this.video);\n\t\t}\n\t};\n\n\n\t\tCamera.get = function (el){\n\t\treturn\tnew Camera(el.firstChild);\n\t};\n\n\n\t\tCamera.publish = function (el, options, callback){\n\t\tif( typeof options == 'function' ){\n\t\t\tcallback = options;\n\t\t\toptions = {};\n\t\t}\n\t\toptions = api.extend({}, {\n\t\t\t  width:\t'100%'\n\t\t\t, height:\t'100%'\n\t\t\t, start:\ttrue\n\t\t}, options);\n\n\n\t\tif( el.jquery ){\n\t\t\tel = el[0];\n\t\t}\n\n\n\t\tvar doneFn = function (err){\n\t\t\tif( err ){\n\t\t\t\tcallback(err);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tvar cam = Camera.get(el);\n\t\t\t\tif( options.start ){\n\t\t\t\t\tcam.start(callback);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tcallback(null, cam);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\n\t\tel.style.width\t= _px(options.width);\n\t\tel.style.height\t= _px(options.height);\n\n\n\t\tif( api.html5 && html5 ){\n\t\t\tvar video = document.createElement('video');\n\t\t\tvideo.style.width\t= _px(options.width);\n\t\t\tvideo.style.height\t= _px(options.height);\n\t\t\tif( window.jQuery ){\n\t\t\t\tjQuery(el).empty();\n\t\t\t} else {\n\t\t\t\tel.innerHTML = '';\n\t\t\t}\n\t\t\tel.appendChild(video);\n\t\t\tdoneFn();\n\t\t}\n\t\telse {\n\t\t\tCamera.fallback(el, options, doneFn);\n\t\t}\n\t};\n\n\n\tCamera.fallback = function (el, options, callback){\n\t\tcallback('not_support_camera');\n\t};\n\n\n\t\tvar Shot = function (video){\n\t\tvar canvas\t= video.nodeName ? api.Image.toCanvas(video) : video;\n\t\tvar shot\t= api.Image(canvas);\n\t\tshot.type\t= 'image/png';\n\t\tshot.width\t= canvas.width;\n\t\tshot.height\t= canvas.height;\n\t\tshot.size\t= canvas.width * canvas.height * 4;\n\t\treturn\tshot;\n\t};\n\n\n\t\tfunction _px(val){\n\t\treturn\tval >= 0 ? val + 'px' : val;\n\t}\n\n\n\t\tfunction _detectVideoSignal(video){\n\t\tvar canvas = document.createElement('canvas'), ctx, res = false;\n\t\ttry {\n\t\t\tctx = canvas.getContext('2d');\n\t\t\tctx.drawImage(video, 0, 0, 1, 1);\n\t\t\tres = ctx.getImageData(0, 0, 1, 1).data[4] != 255;\n\t\t}\n\t\tcatch( e ){}\n\t\treturn\tres;\n\t}\n\tCamera.Shot\t= Shot;\n\tapi.Camera\t= Camera;\n})(window, FileAPI);\n\n\n/*global window, ActiveXObject, FileAPI */\n(function (window, jQuery, api) {\n\t\"use strict\";\n\n\tvar\n\t\t  document = window.document\n\t\t, location = window.location\n\t\t, navigator = window.navigator\n\t\t, _each = api.each\n\t;\n\n\n\tapi.support.flash = (function (){\n\t\tvar mime = navigator.mimeTypes, has = false;\n\n\t\tif( navigator.plugins && typeof navigator.plugins['Shockwave Flash'] == 'object' ){\n\t\t\thas\t= navigator.plugins['Shockwave Flash'].description && !(mime && mime['application/x-shockwave-flash'] && !mime['application/x-shockwave-flash'].enabledPlugin);\n\t\t}\n\t\telse {\n\t\t\ttry {\n\t\t\t\thas\t= !!(window.ActiveXObject && new ActiveXObject('ShockwaveFlash.ShockwaveFlash'));\n\t\t\t}\n\t\t\tcatch(er){\n\t\t\t\tapi.log('Flash -- does not supported.');\n\t\t\t}\n\t\t}\n\n\t\tif( has && /^file:/i.test(location) ){\n\t\t\tapi.log('[warn] Flash does not work on `file:` protocol.');\n\t\t}\n\n\t\treturn\thas;\n\t})();\n\n\n\t   api.support.flash\n\t&& (0\n\t\t|| !api.html5 || !api.support.html5\n\t\t|| (api.cors && !api.support.cors)\n\t\t|| (api.media && !api.support.media)\n\t)\n\t&& (function (){\n\t\tvar\n\t\t\t  _attr  = api.uid()\n\t\t\t, _retry = 0\n\t\t\t, _files = {}\n\t\t\t, _rhttp = /^https?:/i\n\n\t\t\t, flash = {\n\t\t\t\t_fn: {},\n\n\n\t\t\t\t\t\t\t\tinit: function (){\n\t\t\t\t\tvar child = document.body && document.body.firstChild;\n\n\t\t\t\t\tif( child ){\n\t\t\t\t\t\tdo {\n\t\t\t\t\t\t\tif( child.nodeType == 1 ){\n\t\t\t\t\t\t\t\tapi.log('FlashAPI.state: awaiting');\n\n\t\t\t\t\t\t\t\tvar dummy = document.createElement('div');\n\n\t\t\t\t\t\t\t\tdummy.id = '_' + _attr;\n\n\t\t\t\t\t\t\t\t_css(dummy, {\n\t\t\t\t\t\t\t\t\t  top: 1\n\t\t\t\t\t\t\t\t\t, right: 1\n\t\t\t\t\t\t\t\t\t, width: 5\n\t\t\t\t\t\t\t\t\t, height: 5\n\t\t\t\t\t\t\t\t\t, position: 'absolute'\n\t\t\t\t\t\t\t\t\t, zIndex: 1e6+'' // set max zIndex\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\tchild.parentNode.insertBefore(dummy, child);\n\t\t\t\t\t\t\t\tflash.publish(dummy, _attr);\n\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\twhile( child = child.nextSibling );\n\t\t\t\t\t}\n\n\t\t\t\t\tif( _retry < 10 ){\n\t\t\t\t\t\tsetTimeout(flash.init, ++_retry*50);\n\t\t\t\t\t}\n\t\t\t\t},\n\n\n\t\t\t\t\t\t\t\tpublish: function (el, id, opts){\n\t\t\t\t\topts = opts || {};\n\t\t\t\t\tel.innerHTML = _makeFlashHTML({\n\t\t\t\t\t\t  id: id\n\t\t\t\t\t\t, src: _getUrl(api.flashUrl, 'r=' + api.version)\n\t\t\t\t\t\t, wmode: opts.camera ? '' : 'transparent'\n\t\t\t\t\t\t, flashvars: 'callback=' + (opts.onEvent || 'FileAPI.Flash.onEvent')\n\t\t\t\t\t\t\t+ '&flashId='+ id\n\t\t\t\t\t\t\t+ '&storeKey='+ navigator.userAgent.match(/\\d/ig).join('') +'_'+ api.version\n\t\t\t\t\t\t\t+ (flash.isReady || (api.pingUrl ? '&ping='+api.pingUrl : ''))\n\t\t\t\t\t\t\t+ '&timeout='+api.flashAbortTimeout\n\t\t\t\t\t\t\t+ (opts.camera ? '&useCamera=' + _getUrl(api.flashWebcamUrl) : '')\n\t\t\t\t\t\t\t+ '&debug='+(api.debug?\"1\":\"\")\n\t\t\t\t\t}, opts);\n\t\t\t\t},\n\n\n\t\t\t\tready: function (){\n\t\t\t\t\tapi.log('FlashAPI.state: ready');\n\n\t\t\t\t\tflash.ready = api.F;\n\t\t\t\t\tflash.isReady = true;\n\t\t\t\t\tflash.patch();\n\t\t\t\t\tflash.patchCamera && flash.patchCamera();\n\t\t\t\t\tapi.event.on(document, 'mouseover', flash.mouseover);\n\t\t\t\t\tapi.event.on(document, 'click', function (evt){\n\t\t\t\t\t\tif( flash.mouseover(evt) ){\n\t\t\t\t\t\t\tevt.preventDefault\n\t\t\t\t\t\t\t\t? evt.preventDefault()\n\t\t\t\t\t\t\t\t: (evt.returnValue = true)\n\t\t\t\t\t\t\t;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t},\n\n\n\t\t\t\tgetEl: function (){\n\t\t\t\t\treturn\tdocument.getElementById('_'+_attr);\n\t\t\t\t},\n\n\n\t\t\t\tgetWrapper: function (node){\n\t\t\t\t\tdo {\n\t\t\t\t\t\tif( /js-fileapi-wrapper/.test(node.className) ){\n\t\t\t\t\t\t\treturn\tnode;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\twhile( (node = node.parentNode) && (node !== document.body) );\n\t\t\t\t},\n\t\t\t\t\n\t\t\t\tdisableMouseover: false,\n\n\t\t\t\tmouseover: function (evt){\n\t\t\t\t\tif (!flash.disableMouseover) {\n\t\t\t\t\t\tvar target = api.event.fix(evt).target;\n\t\n\t\t\t\t\t\tif( /input/i.test(target.nodeName) && target.type == 'file' && !target.disabled ){\n\t\t\t\t\t\t\tvar\n\t\t\t\t\t\t\t\t  state = target.getAttribute(_attr)\n\t\t\t\t\t\t\t\t, wrapper = flash.getWrapper(target)\n\t\t\t\t\t\t\t;\n\t\n\t\t\t\t\t\t\tif( api.multiFlash ){\n\t\t\t\t\t\t\t\tif( state == 'i' || state == 'r' ){\n\t\t\t\t\t\t\t\t\treturn\tfalse;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse if( state != 'p' ){\n\t\t\t\t\t\t\t\t\ttarget.setAttribute(_attr, 'i');\n\t\n\t\t\t\t\t\t\t\t\tvar dummy = document.createElement('div');\n\t\n\t\t\t\t\t\t\t\t\tif( !wrapper ){\n\t\t\t\t\t\t\t\t\t\tapi.log('[err] FlashAPI.mouseover: js-fileapi-wrapper not found');\n\t\t\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t\t\t\t_css(dummy, {\n\t\t\t\t\t\t\t\t\t\t  top:    0\n\t\t\t\t\t\t\t\t\t\t, left:   0\n\t\t\t\t\t\t\t\t\t\t, width:  target.offsetWidth\n\t\t\t\t\t\t\t\t\t\t, height: target.offsetHeight\n\t\t\t\t\t\t\t\t\t\t, zIndex: 1e6+'' // set max zIndex\n\t\t\t\t\t\t\t\t\t\t, position: 'absolute'\n\t\t\t\t\t\t\t\t\t});\n\t\n\t\t\t\t\t\t\t\t\twrapper.appendChild(dummy);\n\t\t\t\t\t\t\t\t\tflash.publish(dummy, api.uid());\n\t\t\t\t\t\t\t\t\ttarget.setAttribute(_attr, 'p');\n\t\t\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t\t\treturn\ttrue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if( wrapper ){\n\t\t\t\t\t\t\t\tvar box = _getDimensions(wrapper);\n\t\t\t\t\t\t\t\t_css(flash.getEl(), box);\n\t\t\t\t\t\t\t\tflash.curInp = target;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if( !/object|embed/i.test(target.nodeName) ){\n\t\t\t\t\t\t\t_css(flash.getEl(), { top: 1, left: 1, width: 5, height: 5 });\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tonEvent: function (evt){\n\t\t\t\t\tvar type = evt.type;\n\t\t\t\t\t\n\t\t\t\t\tif( type == 'ready' ){\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tflash.getInput(evt.flashId).setAttribute(_attr, 'r');\n\t\t\t\t\t\t} catch (e){\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tflash.ready();\n\t\t\t\t\t\tsetTimeout(function (){ flash.mouseenter(evt); }, 50);\n\t\t\t\t\t\treturn\ttrue;\n\t\t\t\t\t}\n\t\t\t\t\telse if( type === 'ping' ){\n\t\t\t\t\t\tapi.log('(flash -> js).ping:', [evt.status, evt.savedStatus], evt.error);\n\t\t\t\t\t}\n\t\t\t\t\telse if( type === 'log' ){\n\t\t\t\t\t\tapi.log('(flash -> js).log:', evt.target);\n\t\t\t\t\t}\n\t\t\t\t\telse if( type in flash ){\n\t\t\t\t\t\tsetTimeout(function (){\n\t\t\t\t\t\t\tapi.log('FlashAPI.event.'+evt.type+':', evt);\n\t\t\t\t\t\t\tflash[type](evt);\n\t\t\t\t\t\t}, 1);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tmouseDown: function(evt) {\n\t\t\t\t\tflash.disableMouseover = true;\n\t\t\t\t},\n\t\t\t\tcancel: function(evt) {\n\t\t\t\t\tflash.disableMouseover = false;\n\t\t\t\t},\n\t\t\t\tmouseenter: function (evt){\n\t\t\t\t\tvar node = flash.getInput(evt.flashId);\n\n\t\t\t\t\tif( node ){\n\t\t\t\t\t\tflash.cmd(evt, 'multiple', node.getAttribute('multiple') != null);\n\t\t\t\t\t\tvar accept = [], exts = {};\n\n\t\t\t\t\t\t_each((node.getAttribute('accept') || '').split(/,\\s*/), function (mime){\n\t\t\t\t\t\t\tapi.accept[mime] && _each(api.accept[mime].split(' '), function (ext){\n\t\t\t\t\t\t\t\texts[ext] = 1;\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\t_each(exts, function (i, ext){\n\t\t\t\t\t\t\taccept.push( ext );\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tflash.cmd(evt, 'accept', accept.length ? accept.join(',')+','+accept.join(',').toUpperCase() : '*');\n\t\t\t\t\t}\n\t\t\t\t},\n\n\n\t\t\t\tget: function (id){\n\t\t\t\t\treturn\tdocument[id] || window[id] || document.embeds[id];\n\t\t\t\t},\n\n\n\t\t\t\tgetInput: function (id){\n\t\t\t\t\tif( api.multiFlash ){\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tvar node = flash.getWrapper(flash.get(id));\n\t\t\t\t\t\t\tif( node ){\n\t\t\t\t\t\t\t\treturn node.getElementsByTagName('input')[0];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch (e){\n\t\t\t\t\t\t\tapi.log('[err] Can not find \"input\" by flashId:', id, e);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn\tflash.curInp;\n\t\t\t\t\t}\n\t\t\t\t},\n\n\n\t\t\t\tselect: function (evt){\n\t\t\t\t\ttry {\n\t\t\t\t\t\tvar\n\t\t\t\t\t\t\t  inp = flash.getInput(evt.flashId)\n\t\t\t\t\t\t\t, uid = api.uid(inp)\n\t\t\t\t\t\t\t, files = evt.target.files\n\t\t\t\t\t\t\t, event\n\t\t\t\t\t\t;\n\t\t\t\t\t\t_each(files, function (file){\n\t\t\t\t\t\t\tapi.checkFileObj(file);\n\t\t\t\t\t\t});\n\t\n\t\t\t\t\t\t_files[uid] = files;\n\t\n\t\t\t\t\t\tif( document.createEvent ){\n\t\t\t\t\t\t\tevent = document.createEvent('Event');\n\t\t\t\t\t\t\tevent.files = files;\n\t\t\t\t\t\t\tevent.initEvent('change', true, true);\n\t\t\t\t\t\t\tinp.dispatchEvent(event);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if( jQuery ){\n\t\t\t\t\t\t\tjQuery(inp).trigger({ type: 'change', files: files });\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tevent = document.createEventObject();\n\t\t\t\t\t\t\tevent.files = files;\n\t\t\t\t\t\t\tinp.fireEvent('onchange', event);\n\t\t\t\t\t\t}\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tflash.disableMouseover = false;\n\t\t\t\t\t}\n\t\t\t\t},\n\n\n\t\t\t\tcmd: function (id, name, data, last){\n\t\t\t\t\ttry {\n\t\t\t\t\t\tapi.log('(js -> flash).'+name+':', data);\n\t\t\t\t\t\treturn flash.get(id.flashId || id).cmd(name, data);\n\t\t\t\t\t} catch (e){\n\t\t\t\t\t\tapi.log('(js -> flash).onError:', e);\n\t\t\t\t\t\tif( !last ){\n\t\t\t\t\t\t\tsetTimeout(function (){ flash.cmd(id, name, data, true); }, 50);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t},\n\n\n\t\t\t\tpatch: function (){\n\t\t\t\t\tapi.flashEngine = true;\n\t\t\t\t\t_inherit(api, {\n\t\t\t\t\t\tgetFiles: function (input, filter, callback){\n\t\t\t\t\t\t\tif( callback ){\n\t\t\t\t\t\t\t\tapi.filterFiles(api.getFiles(input), filter, callback);\n\t\t\t\t\t\t\t\treturn null;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar files = api.isArray(input) ? input : _files[api.uid(input.target || input.srcElement || input)];\n\n\n\t\t\t\t\t\t\tif( !files ){\n\t\t\t\t\t\t\t\treturn\tthis.parent.apply(this, arguments);\n\t\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\t\tif( filter ){\n\t\t\t\t\t\t\t\tfilter\t= api.getFilesFilter(filter);\n\t\t\t\t\t\t\t\tfiles\t= api.filter(files, function (file){ return filter.test(file.name); });\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn\tfiles;\n\t\t\t\t\t\t},\n\n\n\t\t\t\t\t\tgetInfo: function (file, fn){\n\t\t\t\t\t\t\tif( _isHtmlFile(file) ){\n\t\t\t\t\t\t\t\tthis.parent.apply(this, arguments);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if( file.isShot ){\n\t\t\t\t\t\t\t\tfn(null, file.info = {\n\t\t\t\t\t\t\t\t\twidth: file.width,\n\t\t\t\t\t\t\t\t\theight: file.height\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tif( !file.__info ){\n\t\t\t\t\t\t\t\t\tvar defer = file.__info = api.defer();\n\t\t\t\t\t\t\t\t\tdefer.resolve(null, file.info = null);\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tfile.__info.then(fn);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tapi.support.transform = true;\n\t\t\t\t\tapi.Image && _inherit(api.Image.prototype, {\n\t\t\t\t\t\tget: function (fn, scaleMode){\n\t\t\t\t\t\t\tthis.set({ scaleMode: scaleMode || 'noScale' }); // noScale, exactFit\n\t\t\t\t\t\t\treturn this.parent(fn);\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\t_load: function (file, fn){\n\t\t\t\t\t\t\tapi.log('FlashAPI.Image._load:', file);\n\n\t\t\t\t\t\t\tif( _isHtmlFile(file) ){\n\t\t\t\t\t\t\t\tthis.parent.apply(this, arguments);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tvar _this = this;\n\t\t\t\t\t\t\t\tapi.getInfo(file, function (err){\n\t\t\t\t\t\t\t\t\tfn.call(_this, err, file);\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\t_apply: function (file, fn){\n\t\t\t\t\t\t\tapi.log('FlashAPI.Image._apply:', file);\n\n\t\t\t\t\t\t\tif( _isHtmlFile(file) ){\n\t\t\t\t\t\t\t\tthis.parent.apply(this, arguments);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tvar m = this.getMatrix(file.info), doneFn = fn;\n\n\t\t\t\t\t\t\t\tflash.cmd(file, 'imageTransform', {\n\t\t\t\t\t\t\t\t\t  id: file.id\n\t\t\t\t\t\t\t\t\t, matrix: m\n\t\t\t\t\t\t\t\t\t, callback: _wrap(function _(err, base64){\n\t\t\t\t\t\t\t\t\t\tapi.log('FlashAPI.Image._apply.callback:', err);\n\t\t\t\t\t\t\t\t\t\t_unwrap(_);\n\n\t\t\t\t\t\t\t\t\t\tif( err ){\n\t\t\t\t\t\t\t\t\t\t\tdoneFn(err);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse if( !api.support.html5 && (!api.support.dataURI || base64.length > 3e4) ){\n\t\t\t\t\t\t\t\t\t\t\t_makeFlashImage({\n\t\t\t\t\t\t\t\t\t\t\t\t  width:\t(m.deg % 180) ? m.dh : m.dw\n\t\t\t\t\t\t\t\t\t\t\t\t, height:\t(m.deg % 180) ? m.dw : m.dh\n\t\t\t\t\t\t\t\t\t\t\t\t, scale:\tm.scaleMode\n\t\t\t\t\t\t\t\t\t\t\t}, base64, doneFn);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\t\t\tif( m.filter ){\n\t\t\t\t\t\t\t\t\t\t\t\tdoneFn = function (err, img){\n\t\t\t\t\t\t\t\t\t\t\t\t\tif( err ){\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tfn(err);\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tapi.Image.applyFilter(img, m.filter, function (){\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tfn(err, this.canvas);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\tapi.newImage('data:'+ file.type +';base64,'+ base64, doneFn);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\n\t\t\t\t\t\ttoData: function (fn){\n\t\t\t\t\t\t\tvar\n\t\t\t\t\t\t\t\t  file = this.file\n\t\t\t\t\t\t\t\t, info = file.info\n\t\t\t\t\t\t\t\t, matrix = this.getMatrix(info)\n\t\t\t\t\t\t\t;\n\t\t\t\t\t\t\tapi.log('FlashAPI.Image.toData');\n\n\t\t\t\t\t\t\tif( _isHtmlFile(file) ){\n\t\t\t\t\t\t\t\tthis.parent.apply(this, arguments);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tif( matrix.deg == 'auto' ){\n\t\t\t\t\t\t\t\t\tmatrix.deg = api.Image.exifOrientation[info && info.exif && info.exif.Orientation] || 0;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tfn.call(this, !file.info, {\n\t\t\t\t\t\t\t\t\t  id:\t\tfile.id\n\t\t\t\t\t\t\t\t\t, flashId:\tfile.flashId\n\t\t\t\t\t\t\t\t\t, name:\t\tfile.name\n\t\t\t\t\t\t\t\t\t, type:\t\tfile.type\n\t\t\t\t\t\t\t\t\t, matrix:\tmatrix\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\n\n\t\t\t\t\tapi.Image && _inherit(api.Image, {\n\t\t\t\t\t\tfromDataURL: function (dataURL, size, callback){\n\t\t\t\t\t\t\tif( !api.support.dataURI || dataURL.length > 3e4 ){\n\t\t\t\t\t\t\t\t_makeFlashImage(\n\t\t\t\t\t\t\t\t\t  api.extend({ scale: 'exactFit' }, size)\n\t\t\t\t\t\t\t\t\t, dataURL.replace(/^data:[^,]+,/, '')\n\t\t\t\t\t\t\t\t\t, function (err, el){ callback(el); }\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tthis.parent(dataURL, size, callback);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\t_inherit(api.Form.prototype, {\n\t\t\t\t\t\ttoData: function (fn){\n\t\t\t\t\t\t\tvar items = this.items, i = items.length;\n\n\t\t\t\t\t\t\tfor( ; i--; ){\n\t\t\t\t\t\t\t\tif( items[i].file && _isHtmlFile(items[i].blob) ){\n\t\t\t\t\t\t\t\t\treturn this.parent.apply(this, arguments);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tapi.log('FlashAPI.Form.toData');\n\t\t\t\t\t\t\tfn(items);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\t_inherit(api.XHR.prototype, {\n\t\t\t\t\t\t_send: function (options, formData){\n\t\t\t\t\t\t\tif(\n\t\t\t\t\t\t\t\t   formData.nodeName\n\t\t\t\t\t\t\t\t|| formData.append && api.support.html5\n\t\t\t\t\t\t\t\t|| api.isArray(formData) && (typeof formData[0] === 'string')\n\t\t\t\t\t\t\t){\n\t\t\t\t\t\t\t\treturn\tthis.parent.apply(this, arguments);\n\t\t\t\t\t\t\t}\n\n\n\t\t\t\t\t\t\tvar\n\t\t\t\t\t\t\t\t  data = {}\n\t\t\t\t\t\t\t\t, files = {}\n\t\t\t\t\t\t\t\t, _this = this\n\t\t\t\t\t\t\t\t, flashId\n\t\t\t\t\t\t\t\t, fileId\n\t\t\t\t\t\t\t;\n\n\t\t\t\t\t\t\t_each(formData, function (item){\n\t\t\t\t\t\t\t\tif( item.file ){\n\t\t\t\t\t\t\t\t\tfiles[item.name] = item = _getFileDescr(item.blob);\n\t\t\t\t\t\t\t\t\tfileId  = item.id;\n\t\t\t\t\t\t\t\t\tflashId = item.flashId;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\tdata[item.name] = item.blob;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif( !fileId ){\n\t\t\t\t\t\t\t\tflashId = _attr;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif( !flashId ){\n\t\t\t\t\t\t\t\tapi.log('[err] FlashAPI._send: flashId -- undefined');\n\t\t\t\t\t\t\t\treturn this.parent.apply(this, arguments);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tapi.log('FlashAPI.XHR._send: '+ flashId +' -> '+ fileId);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t_this.xhr = {\n\t\t\t\t\t\t\t\theaders: {},\n\t\t\t\t\t\t\t\tabort: function (){ flash.cmd(flashId, 'abort', { id: fileId }); },\n\t\t\t\t\t\t\t\tgetResponseHeader: function (name){ return this.headers[name]; },\n\t\t\t\t\t\t\t\tgetAllResponseHeaders: function (){ return this.headers; }\n\t\t\t\t\t\t\t};\n\n\t\t\t\t\t\t\tvar queue = api.queue(function (){\n\t\t\t\t\t\t\t\tflash.cmd(flashId, 'upload', {\n\t\t\t\t\t\t\t\t\t  url: _getUrl(options.url.replace(/([a-z]+)=(\\?)&?/i, ''))\n\t\t\t\t\t\t\t\t\t, data: data\n\t\t\t\t\t\t\t\t\t, files: fileId ? files : null\n\t\t\t\t\t\t\t\t\t, headers: options.headers || {}\n\t\t\t\t\t\t\t\t\t, callback: _wrap(function upload(evt){\n\t\t\t\t\t\t\t\t\t\tvar type = evt.type, result = evt.result;\n\n\t\t\t\t\t\t\t\t\t\tapi.log('FlashAPI.upload.'+type);\n\n\t\t\t\t\t\t\t\t\t\tif( type == 'progress' ){\n\t\t\t\t\t\t\t\t\t\t\tevt.loaded = Math.min(evt.loaded, evt.total); // @todo fixme\n\t\t\t\t\t\t\t\t\t\t\tevt.lengthComputable = true;\n\t\t\t\t\t\t\t\t\t\t\toptions.progress(evt);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse if( type == 'complete' ){\n\t\t\t\t\t\t\t\t\t\t\t_unwrap(upload);\n\n\t\t\t\t\t\t\t\t\t\t\tif( typeof result == 'string' ){\n\t\t\t\t\t\t\t\t\t\t\t\t_this.responseText\t= result.replace(/%22/g, \"\\\"\").replace(/%5c/g, \"\\\\\").replace(/%26/g, \"&\").replace(/%25/g, \"%\");\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t_this.end(evt.status || 200);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse if( type == 'abort' || type == 'error' ){\n\t\t\t\t\t\t\t\t\t\t\t_this.end(evt.status || 0, evt.message);\n\t\t\t\t\t\t\t\t\t\t\t_unwrap(upload);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t_each(files, function (file){\n\t\t\t\t\t\t\t\tqueue.inc();\n\t\t\t\t\t\t\t\tapi.getInfo(file, queue.next);\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tqueue.check();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t;\n\n\n\t\tfunction _makeFlashHTML(opts){\n\t\t\treturn ('<object id=\"#id#\" classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" width=\"'+(opts.width || '100%')+'\" height=\"'+(opts.height || '100%')+'\">'\n\t\t\t\t+ '<param name=\"movie\" value=\"#src#\" />'\n\t\t\t\t+ '<param name=\"flashvars\" value=\"#flashvars#\" />'\n\t\t\t\t+ '<param name=\"swliveconnect\" value=\"true\" />'\n\t\t\t\t+ '<param name=\"allowscriptaccess\" value=\"always\" />'\n\t\t\t\t+ '<param name=\"allownetworking\" value=\"all\" />'\n\t\t\t\t+ '<param name=\"menu\" value=\"false\" />'\n\t\t\t\t+ '<param name=\"wmode\" value=\"#wmode#\" />'\n\t\t\t\t+ '<embed flashvars=\"#flashvars#\" swliveconnect=\"true\" allownetworking=\"all\" allowscriptaccess=\"always\" name=\"#id#\" src=\"#src#\" width=\"'+(opts.width || '100%')+'\" height=\"'+(opts.height || '100%')+'\" menu=\"false\" wmode=\"transparent\" type=\"application/x-shockwave-flash\"></embed>'\n\t\t\t\t+ '</object>').replace(/#(\\w+)#/ig, function (a, name){ return opts[name]; })\n\t\t\t;\n\t\t}\n\n\n\t\tfunction _css(el, css){\n\t\t\tif( el && el.style ){\n\t\t\t\tvar key, val;\n\t\t\t\tfor( key in css ){\n\t\t\t\t\tval = css[key];\n\t\t\t\t\tif( typeof val == 'number' ){\n\t\t\t\t\t\tval += 'px';\n\t\t\t\t\t}\n\t\t\t\t\ttry { el.style[key] = val; } catch (e) {}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t}\n\t\t}\n\n\n\t\tfunction _inherit(obj, methods){\n\t\t\t_each(methods, function (fn, name){\n\t\t\t\tvar prev = obj[name];\n\t\t\t\tobj[name] = function (){\n\t\t\t\t\tthis.parent = prev;\n\t\t\t\t\treturn fn.apply(this, arguments);\n\t\t\t\t};\n\t\t\t});\n\t\t}\n\n\t\tfunction _isHtmlFile(file){\n\t\t\treturn\tfile && !file.flashId;\n\t\t}\n\n\t\tfunction _wrap(fn){\n\t\t\tvar id = fn.wid = api.uid();\n\t\t\tflash._fn[id] = fn;\n\t\t\treturn\t'FileAPI.Flash._fn.'+id;\n\t\t}\n\n\n\t\tfunction _unwrap(fn){\n\t\t\ttry {\n\t\t\t\tflash._fn[fn.wid] = null;\n\t\t\t\tdelete\tflash._fn[fn.wid];\n\t\t\t}\n\t\t\tcatch(e){}\n\t\t}\n\n\n\t\tfunction _getUrl(url, params){\n\t\t\tif( !_rhttp.test(url) ){\n\t\t\t\tif( /^\\.\\//.test(url) || '/' != url.charAt(0) ){\n\t\t\t\t\tvar path = location.pathname;\n\t\t\t\t\tpath = path.substr(0, path.lastIndexOf('/'));\n\t\t\t\t\turl = (path +'/'+ url).replace('/./', '/');\n\t\t\t\t}\n\n\t\t\t\tif( '//' != url.substr(0, 2) ){\n\t\t\t\t\turl = '//' + location.host + url;\n\t\t\t\t}\n\n\t\t\t\tif( !_rhttp.test(url) ){\n\t\t\t\t\turl = location.protocol + url;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif( params ){\n\t\t\t\turl += (/\\?/.test(url) ? '&' : '?') + params;\n\t\t\t}\n\n\t\t\treturn\turl;\n\t\t}\n\n\n\t\tfunction _makeFlashImage(opts, base64, fn){\n\t\t\tvar\n\t\t\t\t  key\n\t\t\t\t, flashId = api.uid()\n\t\t\t\t, el = document.createElement('div')\n\t\t\t\t, attempts = 10\n\t\t\t;\n\n\t\t\tfor( key in opts ){\n\t\t\t\tel.setAttribute(key, opts[key]);\n\t\t\t\tel[key] = opts[key];\n\t\t\t}\n\n\t\t\t_css(el, opts);\n\n\t\t\topts.width\t= '100%';\n\t\t\topts.height\t= '100%';\n\n\t\t\tel.innerHTML = _makeFlashHTML(api.extend({\n\t\t\t\t  id: flashId\n\t\t\t\t, src: _getUrl(api.flashImageUrl, 'r='+ api.uid())\n\t\t\t\t, wmode: 'opaque'\n\t\t\t\t, flashvars: 'scale='+ opts.scale +'&callback='+_wrap(function _(){\n\t\t\t\t\t_unwrap(_);\n\t\t\t\t\tif( --attempts > 0 ){\n\t\t\t\t\t\t_setImage();\n\t\t\t\t\t}\n\t\t\t\t\treturn true;\n\t\t\t\t})\n\t\t\t}, opts));\n\n\t\t\tfunction _setImage(){\n\t\t\t\ttry {\n\t\t\t\t\tvar img = flash.get(flashId);\n\t\t\t\t\timg.setImage(base64);\n\t\t\t\t} catch (e){\n\t\t\t\t\tapi.log('[err] FlashAPI.Preview.setImage -- can not set \"base64\":', e);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfn(false, el);\n\t\t\tel = null;\n\t\t}\n\n\n\t\tfunction _getFileDescr(file){\n\t\t\treturn\t{\n\t\t\t\t  id: file.id\n\t\t\t\t, name: file.name\n\t\t\t\t, matrix: file.matrix\n\t\t\t\t, flashId: file.flashId\n\t\t\t};\n\t\t}\n\n\n\t\tfunction _getDimensions(el){\n\t\t\tvar\n\t\t\t\t  box = el.getBoundingClientRect()\n\t\t\t\t, body = document.body\n\t\t\t\t, docEl = (el && el.ownerDocument).documentElement\n\t\t\t;\n\t\t\t\n\t\t\tfunction getOffset(obj) {\n\t\t\t    var left, top;\n\t\t\t    left = top = 0;\n\t\t\t    if (obj.offsetParent) {\n\t\t\t        do {\n\t\t\t            left += obj.offsetLeft;\n\t\t\t            top  += obj.offsetTop;\n\t\t\t        } while (obj = obj.offsetParent);\n\t\t\t    }\n\t\t\t    return {\n\t\t\t        left : left,\n\t\t\t        top : top\n\t\t\t    };\n\t\t\t};\n\t\t\t\n\t\t\treturn {\n\t\t\t\t  top:\t\tgetOffset(el).top\n\t\t\t\t, left:\t\tgetOffset(el).left\n\t\t\t\t, width:\tel.offsetWidth\n\t\t\t\t, height:\tel.offsetHeight\n\t\t\t};\n\t\t}\n\t\tapi.Flash = flash;\n\t\tapi.newImage('data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==', function (err, img){\n\t\t\tapi.support.dataURI = !(img.width != 1 || img.height != 1);\n\t\t\tflash.init();\n\t\t});\n\t})();\n})(window, window.jQuery, FileAPI);\n\n\n/*global window, FileAPI */\n(function (window, jQuery, api) {\n    \"use strict\";\n\n    var _each = api.each,\n        _cameraQueue = [];\n\n\n    if (api.support.flash && (api.media && !api.support.media)) {\n        (function () {\n\n            function _wrap(fn) {\n                var id = fn.wid = api.uid();\n                api.Flash._fn[id] = fn;\n                return 'FileAPI.Flash._fn.' + id;\n            }\n\n\n            function _unwrap(fn) {\n                try {\n                    api.Flash._fn[fn.wid] = null;\n                    delete api.Flash._fn[fn.wid];\n                } catch (e) {\n                }\n            }\n\n            var flash = api.Flash;\n            api.extend(api.Flash, {\n\n                patchCamera: function () {\n                    api.Camera.fallback = function (el, options, callback) {\n                        var camId = api.uid();\n                        api.log('FlashAPI.Camera.publish: ' + camId);\n                        flash.publish(el, camId, api.extend(options, {\n                            camera: true,\n                            onEvent: _wrap(function _(evt) {\n                                if (evt.type === 'camera') {\n                                    _unwrap(_);\n\n                                    if (evt.error) {\n                                        api.log('FlashAPI.Camera.publish.error: ' + evt.error);\n                                        callback(evt.error);\n                                    } else {\n                                        api.log('FlashAPI.Camera.publish.success: ' + camId);\n                                        callback(null);\n                                    }\n                                }\n                            })\n                        }));\n                    };\n                    _each(_cameraQueue, function (args) {\n                        api.Camera.fallback.apply(api.Camera, args);\n                    });\n                    _cameraQueue = [];\n                    api.extend(api.Camera.prototype, {\n                        _id: function () {\n                            return this.video.id;\n                        },\n\n                        start: function (callback) {\n                            var _this = this;\n                            flash.cmd(this._id(), 'camera.on', {\n                                callback: _wrap(function _(evt) {\n                                    _unwrap(_);\n\n                                    if (evt.error) {\n                                        api.log('FlashAPI.camera.on.error: ' + evt.error);\n                                        callback(evt.error, _this);\n                                    } else {\n                                        api.log('FlashAPI.camera.on.success: ' + _this._id());\n                                        _this._active = true;\n                                        callback(null, _this);\n                                    }\n                                })\n                            });\n                        },\n\n                        stop: function () {\n                            this._active = false;\n                            flash.cmd(this._id(), 'camera.off');\n                        },\n\n                        shot: function () {\n                            api.log('FlashAPI.Camera.shot:', this._id());\n\n                            var shot = api.Flash.cmd(this._id(), 'shot', {});\n                            shot.type = 'image/png';\n                            shot.flashId = this._id();\n                            shot.isShot = true;\n\n                            return new api.Camera.Shot(shot);\n                        }\n                    });\n                }\n            });\n\n            api.Camera.fallback = function () {\n                _cameraQueue.push(arguments);\n            };\n\n        }());\n    }\n}(window, window.jQuery, FileAPI));\nif( typeof define === \"function\" && define.amd ){ define(\"FileAPI\", [], function (){ return FileAPI; }); }"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ng-file-upload/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2013 danialfarid\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ng-file-upload/README.md",
    "content": "# angular-file-upload-bower\n\nbower distribution of [angular-file-upload](https://github.com/danialfarid/angular-file-upload).\nAll issues and pull request must be sumbitted to [angular-file-upload](https://github.com/danialfarid/angular-file-upload)\n\n## Install\n\nInstall with `bower`:\n\n```shell\nbower install ng-file-upload\n```\n\nAdd a `<script>` to your `index.html`:\n\n```html\n<script src=\"/bower_components/angular/angular.js\"></script>\n\n<!--only needed if you support non HTML5 FormData browsers.-->\n<script src=\"/bower_components/angular/angular-file-upload-shim.js\"></script>\n<script src=\"/bower_components/angular/angular-file-upload.js\"></script>\n```\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ng-file-upload/angular-file-upload-all.js",
    "content": "/**!\n * AngularJS file upload/drop directive and service with progress and abort\n * @author  Danial  <danial.farid@gmail.com>\n * @version 3.3.3\n */\n(function () {\n\nvar key, i;\nfunction patchXHR(fnName, newFn) {\n    window.XMLHttpRequest.prototype[fnName] = newFn(window.XMLHttpRequest.prototype[fnName]);\n}\n\nif (window.XMLHttpRequest && !window.XMLHttpRequest.__isFileAPIShim) {\n    patchXHR('setRequestHeader', function (orig) {\n        return function (header, value) {\n            if (header === '__setXHR_') {\n                var val = value(this);\n                if (val instanceof Function) {\n                    val(this);\n                }\n            } else {\n                orig.apply(this, arguments);\n            }\n        }\n    });\n}\n\nvar angularFileUpload = angular.module('angularFileUpload', []);\n\nangularFileUpload.version = '3.3.3';\nangularFileUpload.service('$upload', ['$http', '$q', '$timeout', function ($http, $q, $timeout) {\n    function sendHttp(config) {\n        config.method = config.method || 'POST';\n        config.headers = config.headers || {};\n        config.transformRequest = config.transformRequest || function (data, headersGetter) {\n            if (window.ArrayBuffer && data instanceof window.ArrayBuffer) {\n                return data;\n            }\n            return $http.defaults.transformRequest[0](data, headersGetter);\n        };\n        var deferred = $q.defer();\n        var promise = deferred.promise;\n\n        config.headers['__setXHR_'] = function () {\n            return function (xhr) {\n                if (!xhr) return;\n                config.__XHR = xhr;\n                config.xhrFn && config.xhrFn(xhr);\n                xhr.upload.addEventListener('progress', function (e) {\n                    e.config = config;\n                    deferred.notify ? deferred.notify(e) : promise.progress_fn && $timeout(function () {\n                        promise.progress_fn(e)\n                    });\n                }, false);\n                xhr.upload.addEventListener('load', function (e) {\n                    if (e.lengthComputable) {\n                        e.config = config;\n                        deferred.notify ? deferred.notify(e) : promise.progress_fn && $timeout(function () {\n                            promise.progress_fn(e)\n                        });\n                    }\n                }, false);\n            };\n        };\n\n        $http(config).then(function (r) {\n            deferred.resolve(r)\n        }, function (e) {\n            deferred.reject(e)\n        }, function (n) {\n            deferred.notify(n)\n        });\n\n        promise.success = function (fn) {\n            promise.then(function (response) {\n                fn(response.data, response.status, response.headers, config);\n            });\n            return promise;\n        };\n\n        promise.error = function (fn) {\n            promise.then(null, function (response) {\n                fn(response.data, response.status, response.headers, config);\n            });\n            return promise;\n        };\n\n        promise.progress = function (fn) {\n            promise.progress_fn = fn;\n            promise.then(null, null, function (update) {\n                fn(update);\n            });\n            return promise;\n        };\n        promise.abort = function () {\n            if (config.__XHR) {\n                $timeout(function () {\n                    config.__XHR.abort();\n                });\n            }\n            return promise;\n        };\n        promise.xhr = function (fn) {\n            config.xhrFn = (function (origXhrFn) {\n                return function () {\n                    origXhrFn && origXhrFn.apply(promise, arguments);\n                    fn.apply(promise, arguments);\n                }\n            })(config.xhrFn);\n            return promise;\n        };\n\n        return promise;\n    }\n\n    this.upload = function (config) {\n        config.headers = config.headers || {};\n        config.headers['Content-Type'] = undefined;\n        config.transformRequest = config.transformRequest ?\n            (angular.isArray(config.transformRequest) ?\n                config.transformRequest : [config.transformRequest]) : [];\n        config.transformRequest.push(function (data) {\n            var formData = new FormData();\n            var allFields = {};\n            for (key in config.fields) {\n                if (config.fields.hasOwnProperty(key)) {\n                    allFields[key] = config.fields[key];\n                }\n            }\n            if (data) allFields['data'] = data;\n\n            if (config.formDataAppender) {\n                for (key in allFields) {\n                    if (allFields.hasOwnProperty(key)) {\n                        config.formDataAppender(formData, key, allFields[key]);\n                    }\n                }\n            } else {\n                for (key in allFields) {\n                    if (allFields.hasOwnProperty(key)) {\n                        var val = allFields[key];\n                        if (val !== undefined) {\n                            if (angular.isDate(val)) {\n                                val = val.toISOString();\n                            }\n                            if (angular.isString(val)) {\n                                formData.append(key, val);\n                            } else {\n                                if (config.sendObjectsAsJsonBlob && angular.isObject(val)) {\n                                    formData.append(key, new Blob([val], {type: 'application/json'}));\n                                } else {\n                                    formData.append(key, JSON.stringify(val));\n                                }\n                            }\n\n                        }\n                    }\n                }\n            }\n\n            if (config.file != null) {\n                var fileFormName = config.fileFormDataName || 'file';\n\n                if (angular.isArray(config.file)) {\n                    var isFileFormNameString = angular.isString(fileFormName);\n                    for (i = 0; i < config.file.length; i++) {\n                        formData.append(isFileFormNameString ? fileFormName : fileFormName[i], config.file[i],\n                            (config.fileName && config.fileName[i]) || config.file[i].name);\n                    }\n                } else {\n                    formData.append(fileFormName, config.file, config.fileName || config.file.name);\n                }\n            }\n            return formData;\n        });\n\n        return sendHttp(config);\n    };\n\n    this.http = function (config) {\n        return sendHttp(config);\n    };\n}]);\n\nangularFileUpload.directive('ngFileSelect', ['$parse', '$timeout', '$compile',\n    function ($parse, $timeout, $compile) {\n        return {\n            restrict: 'AEC',\n            require: '?ngModel',\n            link: function (scope, elem, attr, ngModel) {\n                linkFileSelect(scope, elem, attr, ngModel, $parse, $timeout, $compile);\n            }\n        }\n    }]);\n\nfunction linkFileSelect(scope, elem, attr, ngModel, $parse, $timeout, $compile) {\n    function isInputTypeFile() {\n        return elem[0].tagName.toLowerCase() === 'input' && elem.attr('type') && elem.attr('type').toLowerCase() === 'file';\n    }\n\n    var isUpdating = false;\n    function changeFn(evt) {\n        if (!isUpdating) {\n            isUpdating = true;\n            try {\n                var fileList = evt.__files_ || (evt.target && evt.target.files);\n                var files = [], rejFiles = [];\n\n                var accept = $parse(attr.ngAccept);\n                for (i = 0; i < fileList.length; i++) {\n                    var file = fileList.item(i);\n                    if (isAccepted(scope, accept, file, evt)) {\n                        files.push(file);\n                    } else {\n                        rejFiles.push(file);\n                    }\n                }\n                updateModel($parse, $timeout, scope, ngModel, attr,\n                    attr.ngFileChange || (attr.ngFileDrop && attr.ngFileDrop.indexOf('(') > 0), files, rejFiles, evt);\n                if (files.length == 0) evt.target.value = files;\n            } finally {\n                isUpdating = false;\n            }\n        }\n    }\n\n    function bindAttrToFileInput(fileElem) {\n        if (attr.ngMultiple) fileElem.attr('multiple', $parse(attr.ngMultiple)(scope));\n        if (!$parse(attr.ngMultiple)(scope)) fileElem.attr('multiple', undefined);\n        if (attr['accept']) fileElem.attr('accept', attr['accept']);\n        if (attr.ngCapture) fileElem.attr('capture', $parse(attr.ngCapture)(scope));\n        if (attr.ngDisabled) fileElem.attr('disabled', $parse(attr.ngDisabled)(scope));\n        for (var i = 0; i < elem[0].attributes.length; i++) {\n            var attribute = elem[0].attributes[i];\n            if (attribute.name !== 'type' && attribute.name !== 'class' && attribute.name !== 'id' && attribute.name !== 'style') {\n            \tfileElem.attr(attribute.name, attribute.value);\n            }\n        }\n    }\n\n    function createFileInput(evt) {\n        if (elem.attr('disabled')) {\n            return;\n        }\n        var fileElem = angular.element('<input type=\"file\">');\n        bindAttrToFileInput(fileElem);\n\n        if (isInputTypeFile()) {\n            elem.replaceWith(fileElem);\n            elem = fileElem;\n        } else {\n            fileElem.css('display', 'none').attr('tabindex', '-1').attr('__ngf_gen__', true);\n            if (elem.__ngf_ref_elem__) {elem.__ngf_ref_elem__.remove();}\n            elem.__ngf_ref_elem__ = fileElem;\n            document.body.appendChild(fileElem[0]);\n        }\n\n        return fileElem;\n    }\n\n    function resetModel(evt) {\n        updateModel($parse, $timeout, scope, ngModel, attr,\n            attr.ngFileChange || attr.ngFileSelect, [], [], evt, true);\n    }\n\n    var clickTouchEvent = 'ontouchend' in document ? 'touchend' : 'click'\n    function clickHandler(evt) {\n        var fileElem = createFileInput(evt);\n        if (fileElem) {\n        \tfileElem.bind('change', changeFn);\n        \tresetModel(evt);\n\n        \tfunction clickAndAssign() {\n            \tfileElem[0].click();\n    \t        if (isInputTypeFile()) {\n    \t            elem.bind(clickTouchEvent, clickHandler);\n    \t            evt.preventDefault()\n    \t        }\n        \t}\n        \tif (navigator.userAgent.toLowerCase().match(/android/)) {\n                setTimeout(function() {\n                \tclickAndAssign();\n                }, 0);        \t\t\n        \t} else {\n        \t\tclickAndAssign();\n        \t}\n        }\n    }\n\n    if (window.FileAPI && window.FileAPI.ngfFixIE) {\n        window.FileAPI.ngfFixIE(elem, createFileInput, bindAttrToFileInput, changeFn, resetModel);\n    } else {\n        elem.bind(clickTouchEvent, clickHandler);\n    }\n}\n\nangularFileUpload.directive('ngFileDrop', ['$parse', '$timeout', '$location', function ($parse, $timeout, $location) {\n    return {\n        restrict: 'AEC',\n        require: '?ngModel',\n        link: function (scope, elem, attr, ngModel) {\n            linkDrop(scope, elem, attr, ngModel, $parse, $timeout, $location);\n        }\n    }\n}]);\n\nangularFileUpload.directive('ngNoFileDrop', function () {\n    return function (scope, elem) {\n        if (dropAvailable()) elem.css('display', 'none')\n    }\n});\nangularFileUpload.directive('ngFileDropAvailable', ['$parse', '$timeout', function ($parse, $timeout) {\n    return function (scope, elem, attr) {\n        if (dropAvailable()) {\n            var fn = $parse(attr['ngFileDropAvailable']);\n            $timeout(function () {\n                fn(scope);\n            });\n        }\n    }\n}]);\n\nfunction linkDrop(scope, elem, attr, ngModel, $parse, $timeout, $location) {\n    var available = dropAvailable();\n    if (attr.dropAvailable) {\n        $timeout(function () {\n        \tscope[attr.dropAvailable] ? scope[attr.dropAvailable].value = available : scope[attr.dropAvailable] = available;\n        });\n    }\n    if (!available) {\n        if ($parse(attr.hideOnDropNotAvailable)(scope) == true) {\n            elem.css('display', 'none');\n        }\n        return;\n    }\n    var leaveTimeout = null;\n    var stopPropagation = $parse(attr.stopPropagation);\n    var dragOverDelay = 1;\n    var accept = $parse(attr.ngAccept);\n    var disabled = $parse(attr.ngDisabled);\n    var actualDragOverClass;\n\n    elem[0].addEventListener('dragover', function (evt) {\n        if (disabled(scope)) return;\n        evt.preventDefault();\n        if (stopPropagation(scope)) evt.stopPropagation();\n        if (navigator.userAgent.indexOf(\"Chrome\") > -1) {\n            var b = evt.dataTransfer.effectAllowed;\n            evt.dataTransfer.dropEffect = ('move' === b || 'linkMove' === b) ? 'move' : 'copy';\n        }\n        $timeout.cancel(leaveTimeout);\n        if (!scope.actualDragOverClass) {\n            actualDragOverClass = calculateDragOverClass(scope, attr, evt);\n        }\n        elem.addClass(actualDragOverClass);\n    }, false);\n    elem[0].addEventListener('dragenter', function (evt) {\n        if (disabled(scope)) return;\n        evt.preventDefault();\n        if (stopPropagation(scope)) evt.stopPropagation();\n    }, false);\n    elem[0].addEventListener('dragleave', function () {\n        if (disabled(scope)) return;\n        leaveTimeout = $timeout(function () {\n            elem.removeClass(actualDragOverClass);\n            actualDragOverClass = null;\n        }, dragOverDelay || 1);\n    }, false);\n    elem[0].addEventListener('drop', function (evt) {\n        if (disabled(scope)) return;\n        evt.preventDefault();\n        if (stopPropagation(scope)) evt.stopPropagation();\n        elem.removeClass(actualDragOverClass);\n        actualDragOverClass = null;\n        extractFiles(evt, function (files, rejFiles) {\n            updateModel($parse, $timeout, scope, ngModel, attr,\n                attr.ngFileChange || (attr.ngFileDrop && attr.ngFileDrop.indexOf('(') > 0), files, rejFiles, evt)\n        }, $parse(attr.allowDir)(scope) != false, attr.multiple || $parse(attr.ngMultiple)(scope));\n    }, false);\n\n    function calculateDragOverClass(scope, attr, evt) {\n        var accepted = true;\n        var items = evt.dataTransfer.items;\n        if (items != null) {\n            for (i = 0; i < items.length && accepted; i++) {\n                accepted = accepted\n                    && (items[i].kind == 'file' || items[i].kind == '')\n                    && isAccepted(scope, accept, items[i], evt);\n            }\n        }\n        var clazz = $parse(attr.dragOverClass)(scope, {$event: evt});\n        if (clazz) {\n            if (clazz.delay) dragOverDelay = clazz.delay;\n            if (clazz.accept) clazz = accepted ? clazz.accept : clazz.reject;\n        }\n        return clazz || attr['dragOverClass'] || 'dragover';\n    }\n\n    function extractFiles(evt, callback, allowDir, multiple) {\n        var files = [], rejFiles = [], items = evt.dataTransfer.items, processing = 0;\n\n        function addFile(file) {\n            if (isAccepted(scope, accept, file, evt)) {\n                files.push(file);\n            } else {\n                rejFiles.push(file);\n            }\n        }\n\n        if (items && items.length > 0 && $location.protocol() != 'file') {\n            for (var i = 0; i < items.length; i++) {\n                if (items[i].webkitGetAsEntry && items[i].webkitGetAsEntry() && items[i].webkitGetAsEntry().isDirectory) {\n                    var entry = items[i].webkitGetAsEntry();\n                    if (entry.isDirectory && !allowDir) {\n                        continue;\n                    }\n                    if (entry != null) {\n                        traverseFileTree(files, entry);\n                    }\n                } else {\n                    var f = items[i].getAsFile();\n                    if (f != null) addFile(f);\n                }\n                if (!multiple && files.length > 0) break;\n            }\n        } else {\n            var fileList = evt.dataTransfer.files;\n            if (fileList != null) {\n                for (var i = 0; i < fileList.length; i++) {\n                    addFile(fileList.item(i));\n                    if (!multiple && files.length > 0) break;\n                }\n            }\n        }\n        var delays = 0;\n        (function waitForProcess(delay) {\n            $timeout(function () {\n                if (!processing) {\n                    if (!multiple && files.length > 1) {\n                        i = 0;\n                        while (files[i].type == 'directory') i++;\n                        files = [files[i]];\n                    }\n                    callback(files, rejFiles);\n                } else {\n                    if (delays++ * 10 < 20 * 1000) {\n                        waitForProcess(10);\n                    }\n                }\n            }, delay || 0)\n        })();\n\n        function traverseFileTree(files, entry, path) {\n            if (entry != null) {\n                if (entry.isDirectory) {\n                    var filePath = (path || '') + entry.name;\n                    addFile({name: entry.name, type: 'directory', path: filePath});\n                    var dirReader = entry.createReader();\n                    var entries = [];\n                    processing++;\n                    var readEntries = function () {\n                        dirReader.readEntries(function (results) {\n                            try {\n                                if (!results.length) {\n                                    for (i = 0; i < entries.length; i++) {\n                                        traverseFileTree(files, entries[i], (path ? path : '') + entry.name + '/');\n                                    }\n                                    processing--;\n                                } else {\n                                    entries = entries.concat(Array.prototype.slice.call(results || [], 0));\n                                    readEntries();\n                                }\n                            } catch (e) {\n                                processing--;\n                                console.error(e);\n                            }\n                        }, function () {\n                            processing--;\n                        });\n                    };\n                    readEntries();\n                } else {\n                    processing++;\n                    entry.file(function (file) {\n                        try {\n                            processing--;\n                            file.path = (path ? path : '') + file.name;\n                            addFile(file);\n                        } catch (e) {\n                            processing--;\n                            console.error(e);\n                        }\n                    }, function () {\n                        processing--;\n                    });\n                }\n            }\n        }\n    }\n}\n\nfunction dropAvailable() {\n    var div = document.createElement('div');\n    return ('draggable' in div) && ('ondrop' in div);\n}\n\nfunction updateModel($parse, $timeout, scope, ngModel, attr, fileChange, files, rejFiles, evt, noDelay) {\n    function update() {\n        if (ngModel) {\n            $parse(attr.ngModel).assign(scope, files);\n            $timeout(function () {\n                ngModel && ngModel.$setViewValue(files != null && files.length == 0 ? null : files);\n            });\n        }\n        if (attr.ngModelRejected) {\n            $parse(attr.ngModelRejected).assign(scope, rejFiles);\n        }\n        if (fileChange) {\n            $parse(fileChange)(scope, {\n                $files: files,\n                $rejectedFiles: rejFiles,\n                $event: evt\n            });\n\n        }\n    }\n    if (noDelay) {\n        update();\n    } else {\n        $timeout(function () {\n            update();\n        });\n    }\n}\n\nfunction isAccepted(scope, accept, file, evt) {\n    var val = accept(scope, {$file: file, $event: evt});\n    if (val == null) {\n        return true;\n    }\n    if (angular.isString(val)) {\n        var regexp = new RegExp(globStringToRegex(val), 'gi')\n        val = (file.type != null && file.type.match(regexp)) ||\n        (file.name != null && file.name.match(regexp));\n    }\n    return val;\n}\n\nfunction globStringToRegex(str) {\n    if (str.length > 2 && str[0] === '/' && str[str.length - 1] === '/') {\n        return str.substring(1, str.length - 1);\n    }\n    var split = str.split(','), result = '';\n    if (split.length > 1) {\n        for (i = 0; i < split.length; i++) {\n            result += '(' + globStringToRegex(split[i]) + ')';\n            if (i < split.length - 1) {\n                result += '|'\n            }\n        }\n    } else {\n        if (str.indexOf('.') == 0) {\n            str = '*' + str;\n        }\n        result = '^' + str.replace(new RegExp('[.\\\\\\\\+*?\\\\[\\\\^\\\\]$(){}=!<>|:\\\\' + '-]', 'g'), '\\\\$&') + '$';\n        result = result.replace(/\\\\\\*/g, '.*').replace(/\\\\\\?/g, '.');\n    }\n    return result;\n}\n\nvar ngFileUpload = angular.module('ngFileUpload', []);\n\nfor (key in angularFileUpload) {\n    if (angularFileUpload.hasOwnProperty(key)) {\n        ngFileUpload[key] = angularFileUpload[key];\n    }\n}\n\n})();\n\n/**!\n * AngularJS file upload/drop directive and service with progress and abort\n * FileAPI Flash shim for old browsers not supporting FormData \n * @author  Danial  <danial.farid@gmail.com>\n * @version 3.3.3\n */\n\n(function() {\n\nvar hasFlash = function() {\n\ttry {\n\t  var fo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');\n\t  if (fo) return true;\n\t} catch(e) {\n\t  if (navigator.mimeTypes['application/x-shockwave-flash'] != undefined) return true;\n\t}\n\treturn false;\n}\n\nfunction patchXHR(fnName, newFn) {\n\twindow.XMLHttpRequest.prototype[fnName] = newFn(window.XMLHttpRequest.prototype[fnName]);\n};\n\nif ((window.XMLHttpRequest && !window.FormData) || (window.FileAPI && FileAPI.forceLoad)) {\n\tvar initializeUploadListener = function(xhr) {\n\t\tif (!xhr.__listeners) {\n\t\t\tif (!xhr.upload) xhr.upload = {};\n\t\t\txhr.__listeners = [];\n\t\t\tvar origAddEventListener = xhr.upload.addEventListener;\n\t\t\txhr.upload.addEventListener = function(t, fn, b) {\n\t\t\t\txhr.__listeners[t] = fn;\n\t\t\t\torigAddEventListener && origAddEventListener.apply(this, arguments);\n\t\t\t};\n\t\t}\n\t}\n\t\n\tpatchXHR('open', function(orig) {\n\t\treturn function(m, url, b) {\n\t\t\tinitializeUploadListener(this);\n\t\t\tthis.__url = url;\n\t\t\ttry {\n\t\t\t\torig.apply(this, [m, url, b]);\n\t\t\t} catch (e) {\n\t\t\t\tif (e.message.indexOf('Access is denied') > -1) {\n\t\t\t\t\tthis.__origError = e;\n\t\t\t\t\torig.apply(this, [m, '_fix_for_ie_crossdomain__', b]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\n\tpatchXHR('getResponseHeader', function(orig) {\n\t\treturn function(h) {\n\t\t\treturn this.__fileApiXHR && this.__fileApiXHR.getResponseHeader ? this.__fileApiXHR.getResponseHeader(h) : (orig == null ? null : orig.apply(this, [h]));\n\t\t};\n\t});\n\n\tpatchXHR('getAllResponseHeaders', function(orig) {\n\t\treturn function() {\n\t\t\treturn this.__fileApiXHR && this.__fileApiXHR.getAllResponseHeaders ? this.__fileApiXHR.getAllResponseHeaders() : (orig == null ? null : orig.apply(this));\n\t\t}\n\t});\n\n\tpatchXHR('abort', function(orig) {\n\t\treturn function() {\n\t\t\treturn this.__fileApiXHR && this.__fileApiXHR.abort ? this.__fileApiXHR.abort() : (orig == null ? null : orig.apply(this));\n\t\t}\n\t});\n\n\tpatchXHR('setRequestHeader', function(orig) {\n\t\treturn function(header, value) {\n\t\t\tif (header === '__setXHR_') {\n\t\t\t\tinitializeUploadListener(this);\n\t\t\t\tvar val = value(this);\n\t\t\t\tif (val instanceof Function) {\n\t\t\t\t\tval(this);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.__requestHeaders = this.__requestHeaders || {};\n\t\t\t\tthis.__requestHeaders[header] = value;\n\t\t\t\torig.apply(this, arguments);\n\t\t\t}\n\t\t}\n\t});\n\t\n\tfunction redefineProp(xhr, prop, fn) {\n\t\ttry {\n\t\t\tObject.defineProperty(xhr, prop, {get: fn});\n\t\t} catch (e) {/*ignore*/}\n\t}\n\n\tpatchXHR('send', function(orig) {\n\t\treturn function() {\n\t\t\tvar xhr = this;\n\t\t\tif (arguments[0] && arguments[0].__isFileAPIShim) {\n\t\t\t\tvar formData = arguments[0];\n\t\t\t\tvar config = {\n\t\t\t\t\turl: xhr.__url,\n\t\t\t\t\tjsonp: false, //removes the callback form param\n\t\t\t\t\tcache: true, //removes the ?fileapiXXX in the url\n\t\t\t\t\tcomplete: function(err, fileApiXHR) {\n\t\t\t\t\t\txhr.__completed = true;\n\t\t\t\t\t\tif (!err && xhr.__listeners['load']) \n\t\t\t\t\t\t\txhr.__listeners['load']({type: 'load', loaded: xhr.__loaded, total: xhr.__total, target: xhr, lengthComputable: true});\n\t\t\t\t\t\tif (!err && xhr.__listeners['loadend']) \n\t\t\t\t\t\t\txhr.__listeners['loadend']({type: 'loadend', loaded: xhr.__loaded, total: xhr.__total, target: xhr, lengthComputable: true});\n\t\t\t\t\t\tif (err === 'abort' && xhr.__listeners['abort']) \n\t\t\t\t\t\t\txhr.__listeners['abort']({type: 'abort', loaded: xhr.__loaded, total: xhr.__total, target: xhr, lengthComputable: true});\n\t\t\t\t\t\tif (fileApiXHR.status !== undefined) redefineProp(xhr, 'status', function() {return (fileApiXHR.status == 0 && err && err !== 'abort') ? 500 : fileApiXHR.status});\n\t\t\t\t\t\tif (fileApiXHR.statusText !== undefined) redefineProp(xhr, 'statusText', function() {return fileApiXHR.statusText});\n\t\t\t\t\t\tredefineProp(xhr, 'readyState', function() {return 4});\n\t\t\t\t\t\tif (fileApiXHR.response !== undefined) redefineProp(xhr, 'response', function() {return fileApiXHR.response});\n\t\t\t\t\t\tvar resp = fileApiXHR.responseText || (err && fileApiXHR.status == 0 && err !== 'abort' ? err : undefined);\n\t\t\t\t\t\tredefineProp(xhr, 'responseText', function() {return resp});\n\t\t\t\t\t\tredefineProp(xhr, 'response', function() {return resp});\n\t\t\t\t\t\tif (err) redefineProp(xhr, 'err', function() {return err});\n\t\t\t\t\t\txhr.__fileApiXHR = fileApiXHR;\n\t\t\t\t\t\tif (xhr.onreadystatechange) xhr.onreadystatechange();\n\t\t\t\t\t\tif (xhr.onload) xhr.onload();\n\t\t\t\t\t},\n\t\t\t\t\tfileprogress: function(e) {\n\t\t\t\t\t\te.target = xhr;\n\t\t\t\t\t\txhr.__listeners['progress'] && xhr.__listeners['progress'](e);\n\t\t\t\t\t\txhr.__total = e.total;\n\t\t\t\t\t\txhr.__loaded = e.loaded;\n\t\t\t\t\t\tif (e.total === e.loaded) {\n\t\t\t\t\t\t\tvar _this = this\n\t\t\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\t\t\tif (!xhr.__completed) {\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders = function(){};\n\t\t\t\t\t\t\t\t\t_this.complete(null, {status: 204, statusText: 'No Content'});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}, FileAPI.noContentTimeout || 10000);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\theaders: xhr.__requestHeaders\n\t\t\t\t}\n\t\t\t\tconfig.data = {};\n\t\t\t\tconfig.files = {}\n\t\t\t\tfor (var i = 0; i < formData.data.length; i++) {\n\t\t\t\t\tvar item = formData.data[i];\n\t\t\t\t\tif (item.val != null && item.val.name != null && item.val.size != null && item.val.type != null) {\n\t\t\t\t\t\tconfig.files[item.key] = item.val;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconfig.data[item.key] = item.val;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\tif (!hasFlash()) {\n\t\t\t\t\t\tthrow 'Adode Flash Player need to be installed. To check ahead use \"FileAPI.hasFlash\"';\n\t\t\t\t\t}\n\t\t\t\t\txhr.__fileApiXHR = FileAPI.upload(config);\n\t\t\t\t}, 1);\n\t\t\t} else {\n\t\t\t\tif (this.__origError) {\n\t\t\t\t\tthrow this.__origError;\n\t\t\t\t}\n\t\t\t\torig.apply(xhr, arguments);\n\t\t\t}\n\t\t}\n\t});\n\twindow.XMLHttpRequest.__isFileAPIShim = true;\n\n\tfunction isInputTypeFile(elem) {\n\t\treturn elem[0].tagName.toLowerCase() === 'input' && elem.attr('type') && elem.attr('type').toLowerCase() === 'file';\n\t}\n\n\tFileAPI.ngfFixIE = function(elem, createFileElemFn, bindAttr, changeFn, resetModel) {\n\t\tif (!hasFlash()) {\n\t\t\tthrow 'Adode Flash Player need to be installed. To check ahead use \"FileAPI.hasFlash\"';\n\t\t}\n\t\tvar makeFlashInput = function(evt) {\n\t\t\tif (elem.attr('disabled')) {\n\t\t\t\telem.__ngf_elem__.removeClass('js-fileapi-wrapper');\n\t\t\t} else {\n\t\t\t\tvar fileElem = elem.__ngf_elem__;\n\t\t\t\tif (!fileElem) {\n\t\t\t\t\tfileElem = elem.__ngf_elem__ = createFileElemFn();\n\t\t\t\t\tfileElem.addClass('js-fileapi-wrapper');\n\t\t\t\t\tif (!isInputTypeFile(elem)) {\n\t\t\t\t\t}\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\tfileElem.bind('mouseenter', makeFlashInput);\n\t\t\t\t\t}, 10);\n\t\t\t\t\tfileElem.bind('change', function(evt) {\n\t\t\t\t    \tfileApiChangeFn.apply(this, [evt]);\n\t\t\t\t\t\tchangeFn.apply(this, [evt]);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tbindAttr(elem.__ngf_elem__);\n\t\t\t\t}\n\t\t\t\tif (!isInputTypeFile(elem)) {\n\t\t\t\t\tfileElem.css('position', 'absolute')\n\t\t\t\t\t\t\t.css('top', getOffset(elem[0]).top + 'px').css('left', getOffset(elem[0]).left + 'px')\n\t\t\t\t\t\t\t.css('width', elem[0].offsetWidth + 'px').css('height', elem[0].offsetHeight + 'px')\n\t\t\t\t\t\t\t.css('filter', 'alpha(opacity=0)').css('display', elem.css('display'))\n\t\t\t\t\t\t\t.css('overflow', 'hidden').css('z-index', '900000');\n\t\t\t\t}\n\t\t\t}\n\t\t\tfunction getOffset(obj) {\n\t\t\t    var left, top;\n\t\t\t    left = top = 0;\n\t\t\t    if (obj.offsetParent) {\n\t\t\t        do {\n\t\t\t            left += obj.offsetLeft;\n\t\t\t            top  += obj.offsetTop;\n\t\t\t        } while (obj = obj.offsetParent);\n\t\t\t    }\n\t\t\t    return {\n\t\t\t        left : left,\n\t\t\t        top : top\n\t\t\t    };\n\t\t\t};\n\t\t};\n\n\t\telem.bind('mouseenter', makeFlashInput);\n\n\t\tvar fileApiChangeFn = function(evt) {\n\t\t\tvar files = FileAPI.getFiles(evt);\n\t\t\tfor (var i = 0; i < files.length; i++) {\n\t\t\t\tif (files[i].size === undefined) files[i].size = 0;\n\t\t\t\tif (files[i].name === undefined) files[i].name = 'file';\n\t\t\t\tif (files[i].type === undefined) files[i].type = 'undefined';\n\t\t\t}\n\t\t\tif (!evt.target) {\n\t\t\t\tevt.target = {};\n\t\t\t}\n\t\t\tevt.target.files = files;\n\t\t\tif (evt.target.files != files) {\n\t\t\t\tevt.__files_ = files;\n\t\t\t}\n\t\t\t(evt.__files_ || evt.target.files).item = function(i) {\n\t\t\t\treturn (evt.__files_ || evt.target.files)[i] || null;\n\t\t\t};\n\t\t};\n\t};\n\n\twindow.FormData = FormData = function() {\n\t\treturn {\n\t\t\tappend: function(key, val, name) {\n\t\t\t\tif (val.__isFileAPIBlobShim) {\n\t\t\t\t\tval = val.data[0];\n\t\t\t\t}\n\t\t\t\tthis.data.push({\n\t\t\t\t\tkey: key,\n\t\t\t\t\tval: val,\n\t\t\t\t\tname: name\n\t\t\t\t});\n\t\t\t},\n\t\t\tdata: [],\n\t\t\t__isFileAPIShim: true\n\t\t};\n\t};\n\n\twindow.Blob = Blob = function(b) {\n\t\treturn {\n\t\t\tdata: b,\n\t\t\t__isFileAPIBlobShim: true\n\t\t};\n\t};\n\n\t(function () {\n\t\tif (!window.FileAPI) {\n\t\t\twindow.FileAPI = {};\n\t\t}\n\t\tif (FileAPI.forceLoad) {\n\t\t\tFileAPI.html5 = false;\n\t\t}\n\t\t\n\t\tif (!FileAPI.upload) {\n\t\t\tvar jsUrl, basePath, script = document.createElement('script'), allScripts = document.getElementsByTagName('script'), i, index, src;\n\t\t\tif (window.FileAPI.jsUrl) {\n\t\t\t\tjsUrl = window.FileAPI.jsUrl;\n\t\t\t} else if (window.FileAPI.jsPath) {\n\t\t\t\tbasePath = window.FileAPI.jsPath;\n\t\t\t} else {\n\t\t\t\tfor (i = 0; i < allScripts.length; i++) {\n\t\t\t\t\tsrc = allScripts[i].src;\n\t\t\t\t\tindex = src.search(/\\/angular\\-file\\-upload[\\-a-zA-z0-9\\.]*\\.js/)\n\t\t\t\t\tif (index > -1) {\n\t\t\t\t\t\tbasePath = src.substring(0, index + 1);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (FileAPI.staticPath == null) FileAPI.staticPath = basePath;\n\t\t\tscript.setAttribute('src', jsUrl || basePath + 'FileAPI.min.js');\n\t\t\tdocument.getElementsByTagName('head')[0].appendChild(script);\n\t\t\tFileAPI.hasFlash = hasFlash();\n\t\t}\n\t})();\n\tFileAPI.disableFileInput = function(elem, disable) {\n\t\tif (disable) {\n\t\t\telem.removeClass('js-fileapi-wrapper')\n\t\t} else {\n\t\t\telem.addClass('js-fileapi-wrapper');\n\t\t}\n\t}\n}\n\n\nif (!window.FileReader) {\n\twindow.FileReader = function() {\n\t\tvar _this = this, loadStarted = false;\n\t\tthis.listeners = {};\n\t\tthis.addEventListener = function(type, fn) {\n\t\t\t_this.listeners[type] = _this.listeners[type] || [];\n\t\t\t_this.listeners[type].push(fn);\n\t\t};\n\t\tthis.removeEventListener = function(type, fn) {\n\t\t\t_this.listeners[type] && _this.listeners[type].splice(_this.listeners[type].indexOf(fn), 1);\n\t\t};\n\t\tthis.dispatchEvent = function(evt) {\n\t\t\tvar list = _this.listeners[evt.type];\n\t\t\tif (list) {\n\t\t\t\tfor (var i = 0; i < list.length; i++) {\n\t\t\t\t\tlist[i].call(_this, evt);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tthis.onabort = this.onerror = this.onload = this.onloadstart = this.onloadend = this.onprogress = null;\n\n\t\tvar constructEvent = function(type, evt) {\n\t\t\tvar e = {type: type, target: _this, loaded: evt.loaded, total: evt.total, error: evt.error};\n\t\t\tif (evt.result != null) e.target.result = evt.result;\n\t\t\treturn e;\n\t\t};\n\t\tvar listener = function(evt) {\n\t\t\tif (!loadStarted) {\n\t\t\t\tloadStarted = true;\n\t\t\t\t_this.onloadstart && _this.onloadstart(constructEvent('loadstart', evt));\n\t\t\t}\n\t\t\tif (evt.type === 'load') {\n\t\t\t\t_this.onloadend && _this.onloadend(constructEvent('loadend', evt));\n\t\t\t\tvar e = constructEvent('load', evt);\n\t\t\t\t_this.onload && _this.onload(e);\n\t\t\t\t_this.dispatchEvent(e);\n\t\t\t} else if (evt.type === 'progress') {\n\t\t\t\tvar e = constructEvent('progress', evt);\n\t\t\t\t_this.onprogress && _this.onprogress(e);\n\t\t\t\t_this.dispatchEvent(e);\n\t\t\t} else {\n\t\t\t\tvar e = constructEvent('error', evt);\n\t\t\t\t_this.onerror && _this.onerror(e);\n\t\t\t\t_this.dispatchEvent(e);\n\t\t\t}\n\t\t};\n\t\tthis.readAsArrayBuffer = function(file) {\n\t\t\tFileAPI.readAsBinaryString(file, listener);\n\t\t}\n\t\tthis.readAsBinaryString = function(file) {\n\t\t\tFileAPI.readAsBinaryString(file, listener);\n\t\t}\n\t\tthis.readAsDataURL = function(file) {\n\t\t\tFileAPI.readAsDataURL(file, listener);\n\t\t}\n\t\tthis.readAsText = function(file) {\n\t\t\tFileAPI.readAsText(file, listener);\n\t\t}\n\t}\n}\n})();\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ng-file-upload/angular-file-upload-shim.js",
    "content": "/**!\n * AngularJS file upload/drop directive and service with progress and abort\n * FileAPI Flash shim for old browsers not supporting FormData \n * @author  Danial  <danial.farid@gmail.com>\n * @version 3.3.3\n */\n\n(function() {\n\nvar hasFlash = function() {\n\ttry {\n\t  var fo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');\n\t  if (fo) return true;\n\t} catch(e) {\n\t  if (navigator.mimeTypes['application/x-shockwave-flash'] != undefined) return true;\n\t}\n\treturn false;\n}\n\nfunction patchXHR(fnName, newFn) {\n\twindow.XMLHttpRequest.prototype[fnName] = newFn(window.XMLHttpRequest.prototype[fnName]);\n};\n\nif ((window.XMLHttpRequest && !window.FormData) || (window.FileAPI && FileAPI.forceLoad)) {\n\tvar initializeUploadListener = function(xhr) {\n\t\tif (!xhr.__listeners) {\n\t\t\tif (!xhr.upload) xhr.upload = {};\n\t\t\txhr.__listeners = [];\n\t\t\tvar origAddEventListener = xhr.upload.addEventListener;\n\t\t\txhr.upload.addEventListener = function(t, fn, b) {\n\t\t\t\txhr.__listeners[t] = fn;\n\t\t\t\torigAddEventListener && origAddEventListener.apply(this, arguments);\n\t\t\t};\n\t\t}\n\t}\n\t\n\tpatchXHR('open', function(orig) {\n\t\treturn function(m, url, b) {\n\t\t\tinitializeUploadListener(this);\n\t\t\tthis.__url = url;\n\t\t\ttry {\n\t\t\t\torig.apply(this, [m, url, b]);\n\t\t\t} catch (e) {\n\t\t\t\tif (e.message.indexOf('Access is denied') > -1) {\n\t\t\t\t\tthis.__origError = e;\n\t\t\t\t\torig.apply(this, [m, '_fix_for_ie_crossdomain__', b]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\n\tpatchXHR('getResponseHeader', function(orig) {\n\t\treturn function(h) {\n\t\t\treturn this.__fileApiXHR && this.__fileApiXHR.getResponseHeader ? this.__fileApiXHR.getResponseHeader(h) : (orig == null ? null : orig.apply(this, [h]));\n\t\t};\n\t});\n\n\tpatchXHR('getAllResponseHeaders', function(orig) {\n\t\treturn function() {\n\t\t\treturn this.__fileApiXHR && this.__fileApiXHR.getAllResponseHeaders ? this.__fileApiXHR.getAllResponseHeaders() : (orig == null ? null : orig.apply(this));\n\t\t}\n\t});\n\n\tpatchXHR('abort', function(orig) {\n\t\treturn function() {\n\t\t\treturn this.__fileApiXHR && this.__fileApiXHR.abort ? this.__fileApiXHR.abort() : (orig == null ? null : orig.apply(this));\n\t\t}\n\t});\n\n\tpatchXHR('setRequestHeader', function(orig) {\n\t\treturn function(header, value) {\n\t\t\tif (header === '__setXHR_') {\n\t\t\t\tinitializeUploadListener(this);\n\t\t\t\tvar val = value(this);\n\t\t\t\tif (val instanceof Function) {\n\t\t\t\t\tval(this);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthis.__requestHeaders = this.__requestHeaders || {};\n\t\t\t\tthis.__requestHeaders[header] = value;\n\t\t\t\torig.apply(this, arguments);\n\t\t\t}\n\t\t}\n\t});\n\t\n\tfunction redefineProp(xhr, prop, fn) {\n\t\ttry {\n\t\t\tObject.defineProperty(xhr, prop, {get: fn});\n\t\t} catch (e) {/*ignore*/}\n\t}\n\n\tpatchXHR('send', function(orig) {\n\t\treturn function() {\n\t\t\tvar xhr = this;\n\t\t\tif (arguments[0] && arguments[0].__isFileAPIShim) {\n\t\t\t\tvar formData = arguments[0];\n\t\t\t\tvar config = {\n\t\t\t\t\turl: xhr.__url,\n\t\t\t\t\tjsonp: false, //removes the callback form param\n\t\t\t\t\tcache: true, //removes the ?fileapiXXX in the url\n\t\t\t\t\tcomplete: function(err, fileApiXHR) {\n\t\t\t\t\t\txhr.__completed = true;\n\t\t\t\t\t\tif (!err && xhr.__listeners['load']) \n\t\t\t\t\t\t\txhr.__listeners['load']({type: 'load', loaded: xhr.__loaded, total: xhr.__total, target: xhr, lengthComputable: true});\n\t\t\t\t\t\tif (!err && xhr.__listeners['loadend']) \n\t\t\t\t\t\t\txhr.__listeners['loadend']({type: 'loadend', loaded: xhr.__loaded, total: xhr.__total, target: xhr, lengthComputable: true});\n\t\t\t\t\t\tif (err === 'abort' && xhr.__listeners['abort']) \n\t\t\t\t\t\t\txhr.__listeners['abort']({type: 'abort', loaded: xhr.__loaded, total: xhr.__total, target: xhr, lengthComputable: true});\n\t\t\t\t\t\tif (fileApiXHR.status !== undefined) redefineProp(xhr, 'status', function() {return (fileApiXHR.status == 0 && err && err !== 'abort') ? 500 : fileApiXHR.status});\n\t\t\t\t\t\tif (fileApiXHR.statusText !== undefined) redefineProp(xhr, 'statusText', function() {return fileApiXHR.statusText});\n\t\t\t\t\t\tredefineProp(xhr, 'readyState', function() {return 4});\n\t\t\t\t\t\tif (fileApiXHR.response !== undefined) redefineProp(xhr, 'response', function() {return fileApiXHR.response});\n\t\t\t\t\t\tvar resp = fileApiXHR.responseText || (err && fileApiXHR.status == 0 && err !== 'abort' ? err : undefined);\n\t\t\t\t\t\tredefineProp(xhr, 'responseText', function() {return resp});\n\t\t\t\t\t\tredefineProp(xhr, 'response', function() {return resp});\n\t\t\t\t\t\tif (err) redefineProp(xhr, 'err', function() {return err});\n\t\t\t\t\t\txhr.__fileApiXHR = fileApiXHR;\n\t\t\t\t\t\tif (xhr.onreadystatechange) xhr.onreadystatechange();\n\t\t\t\t\t\tif (xhr.onload) xhr.onload();\n\t\t\t\t\t},\n\t\t\t\t\tfileprogress: function(e) {\n\t\t\t\t\t\te.target = xhr;\n\t\t\t\t\t\txhr.__listeners['progress'] && xhr.__listeners['progress'](e);\n\t\t\t\t\t\txhr.__total = e.total;\n\t\t\t\t\t\txhr.__loaded = e.loaded;\n\t\t\t\t\t\tif (e.total === e.loaded) {\n\t\t\t\t\t\t\tvar _this = this\n\t\t\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\t\t\tif (!xhr.__completed) {\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders = function(){};\n\t\t\t\t\t\t\t\t\t_this.complete(null, {status: 204, statusText: 'No Content'});\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}, FileAPI.noContentTimeout || 10000);\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\theaders: xhr.__requestHeaders\n\t\t\t\t}\n\t\t\t\tconfig.data = {};\n\t\t\t\tconfig.files = {}\n\t\t\t\tfor (var i = 0; i < formData.data.length; i++) {\n\t\t\t\t\tvar item = formData.data[i];\n\t\t\t\t\tif (item.val != null && item.val.name != null && item.val.size != null && item.val.type != null) {\n\t\t\t\t\t\tconfig.files[item.key] = item.val;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tconfig.data[item.key] = item.val;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tsetTimeout(function() {\n\t\t\t\t\tif (!hasFlash()) {\n\t\t\t\t\t\tthrow 'Adode Flash Player need to be installed. To check ahead use \"FileAPI.hasFlash\"';\n\t\t\t\t\t}\n\t\t\t\t\txhr.__fileApiXHR = FileAPI.upload(config);\n\t\t\t\t}, 1);\n\t\t\t} else {\n\t\t\t\tif (this.__origError) {\n\t\t\t\t\tthrow this.__origError;\n\t\t\t\t}\n\t\t\t\torig.apply(xhr, arguments);\n\t\t\t}\n\t\t}\n\t});\n\twindow.XMLHttpRequest.__isFileAPIShim = true;\n\n\tfunction isInputTypeFile(elem) {\n\t\treturn elem[0].tagName.toLowerCase() === 'input' && elem.attr('type') && elem.attr('type').toLowerCase() === 'file';\n\t}\n\n\tFileAPI.ngfFixIE = function(elem, createFileElemFn, bindAttr, changeFn, resetModel) {\n\t\tif (!hasFlash()) {\n\t\t\tthrow 'Adode Flash Player need to be installed. To check ahead use \"FileAPI.hasFlash\"';\n\t\t}\n\t\tvar makeFlashInput = function(evt) {\n\t\t\tif (elem.attr('disabled')) {\n\t\t\t\telem.__ngf_elem__.removeClass('js-fileapi-wrapper');\n\t\t\t} else {\n\t\t\t\tvar fileElem = elem.__ngf_elem__;\n\t\t\t\tif (!fileElem) {\n\t\t\t\t\tfileElem = elem.__ngf_elem__ = createFileElemFn();\n\t\t\t\t\tfileElem.addClass('js-fileapi-wrapper');\n\t\t\t\t\tif (!isInputTypeFile(elem)) {\n\t\t\t\t\t}\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\tfileElem.bind('mouseenter', makeFlashInput);\n\t\t\t\t\t}, 10);\n\t\t\t\t\tfileElem.bind('change', function(evt) {\n\t\t\t\t    \tfileApiChangeFn.apply(this, [evt]);\n\t\t\t\t\t\tchangeFn.apply(this, [evt]);\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tbindAttr(elem.__ngf_elem__);\n\t\t\t\t}\n\t\t\t\tif (!isInputTypeFile(elem)) {\n\t\t\t\t\tfileElem.css('position', 'absolute')\n\t\t\t\t\t\t\t.css('top', getOffset(elem[0]).top + 'px').css('left', getOffset(elem[0]).left + 'px')\n\t\t\t\t\t\t\t.css('width', elem[0].offsetWidth + 'px').css('height', elem[0].offsetHeight + 'px')\n\t\t\t\t\t\t\t.css('filter', 'alpha(opacity=0)').css('display', elem.css('display'))\n\t\t\t\t\t\t\t.css('overflow', 'hidden').css('z-index', '900000');\n\t\t\t\t}\n\t\t\t}\n\t\t\tfunction getOffset(obj) {\n\t\t\t    var left, top;\n\t\t\t    left = top = 0;\n\t\t\t    if (obj.offsetParent) {\n\t\t\t        do {\n\t\t\t            left += obj.offsetLeft;\n\t\t\t            top  += obj.offsetTop;\n\t\t\t        } while (obj = obj.offsetParent);\n\t\t\t    }\n\t\t\t    return {\n\t\t\t        left : left,\n\t\t\t        top : top\n\t\t\t    };\n\t\t\t};\n\t\t};\n\n\t\telem.bind('mouseenter', makeFlashInput);\n\n\t\tvar fileApiChangeFn = function(evt) {\n\t\t\tvar files = FileAPI.getFiles(evt);\n\t\t\tfor (var i = 0; i < files.length; i++) {\n\t\t\t\tif (files[i].size === undefined) files[i].size = 0;\n\t\t\t\tif (files[i].name === undefined) files[i].name = 'file';\n\t\t\t\tif (files[i].type === undefined) files[i].type = 'undefined';\n\t\t\t}\n\t\t\tif (!evt.target) {\n\t\t\t\tevt.target = {};\n\t\t\t}\n\t\t\tevt.target.files = files;\n\t\t\tif (evt.target.files != files) {\n\t\t\t\tevt.__files_ = files;\n\t\t\t}\n\t\t\t(evt.__files_ || evt.target.files).item = function(i) {\n\t\t\t\treturn (evt.__files_ || evt.target.files)[i] || null;\n\t\t\t};\n\t\t};\n\t};\n\n\twindow.FormData = FormData = function() {\n\t\treturn {\n\t\t\tappend: function(key, val, name) {\n\t\t\t\tif (val.__isFileAPIBlobShim) {\n\t\t\t\t\tval = val.data[0];\n\t\t\t\t}\n\t\t\t\tthis.data.push({\n\t\t\t\t\tkey: key,\n\t\t\t\t\tval: val,\n\t\t\t\t\tname: name\n\t\t\t\t});\n\t\t\t},\n\t\t\tdata: [],\n\t\t\t__isFileAPIShim: true\n\t\t};\n\t};\n\n\twindow.Blob = Blob = function(b) {\n\t\treturn {\n\t\t\tdata: b,\n\t\t\t__isFileAPIBlobShim: true\n\t\t};\n\t};\n\n\t(function () {\n\t\tif (!window.FileAPI) {\n\t\t\twindow.FileAPI = {};\n\t\t}\n\t\tif (FileAPI.forceLoad) {\n\t\t\tFileAPI.html5 = false;\n\t\t}\n\t\t\n\t\tif (!FileAPI.upload) {\n\t\t\tvar jsUrl, basePath, script = document.createElement('script'), allScripts = document.getElementsByTagName('script'), i, index, src;\n\t\t\tif (window.FileAPI.jsUrl) {\n\t\t\t\tjsUrl = window.FileAPI.jsUrl;\n\t\t\t} else if (window.FileAPI.jsPath) {\n\t\t\t\tbasePath = window.FileAPI.jsPath;\n\t\t\t} else {\n\t\t\t\tfor (i = 0; i < allScripts.length; i++) {\n\t\t\t\t\tsrc = allScripts[i].src;\n\t\t\t\t\tindex = src.search(/\\/angular\\-file\\-upload[\\-a-zA-z0-9\\.]*\\.js/)\n\t\t\t\t\tif (index > -1) {\n\t\t\t\t\t\tbasePath = src.substring(0, index + 1);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (FileAPI.staticPath == null) FileAPI.staticPath = basePath;\n\t\t\tscript.setAttribute('src', jsUrl || basePath + 'FileAPI.min.js');\n\t\t\tdocument.getElementsByTagName('head')[0].appendChild(script);\n\t\t\tFileAPI.hasFlash = hasFlash();\n\t\t}\n\t})();\n\tFileAPI.disableFileInput = function(elem, disable) {\n\t\tif (disable) {\n\t\t\telem.removeClass('js-fileapi-wrapper')\n\t\t} else {\n\t\t\telem.addClass('js-fileapi-wrapper');\n\t\t}\n\t}\n}\n\n\nif (!window.FileReader) {\n\twindow.FileReader = function() {\n\t\tvar _this = this, loadStarted = false;\n\t\tthis.listeners = {};\n\t\tthis.addEventListener = function(type, fn) {\n\t\t\t_this.listeners[type] = _this.listeners[type] || [];\n\t\t\t_this.listeners[type].push(fn);\n\t\t};\n\t\tthis.removeEventListener = function(type, fn) {\n\t\t\t_this.listeners[type] && _this.listeners[type].splice(_this.listeners[type].indexOf(fn), 1);\n\t\t};\n\t\tthis.dispatchEvent = function(evt) {\n\t\t\tvar list = _this.listeners[evt.type];\n\t\t\tif (list) {\n\t\t\t\tfor (var i = 0; i < list.length; i++) {\n\t\t\t\t\tlist[i].call(_this, evt);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tthis.onabort = this.onerror = this.onload = this.onloadstart = this.onloadend = this.onprogress = null;\n\n\t\tvar constructEvent = function(type, evt) {\n\t\t\tvar e = {type: type, target: _this, loaded: evt.loaded, total: evt.total, error: evt.error};\n\t\t\tif (evt.result != null) e.target.result = evt.result;\n\t\t\treturn e;\n\t\t};\n\t\tvar listener = function(evt) {\n\t\t\tif (!loadStarted) {\n\t\t\t\tloadStarted = true;\n\t\t\t\t_this.onloadstart && _this.onloadstart(constructEvent('loadstart', evt));\n\t\t\t}\n\t\t\tif (evt.type === 'load') {\n\t\t\t\t_this.onloadend && _this.onloadend(constructEvent('loadend', evt));\n\t\t\t\tvar e = constructEvent('load', evt);\n\t\t\t\t_this.onload && _this.onload(e);\n\t\t\t\t_this.dispatchEvent(e);\n\t\t\t} else if (evt.type === 'progress') {\n\t\t\t\tvar e = constructEvent('progress', evt);\n\t\t\t\t_this.onprogress && _this.onprogress(e);\n\t\t\t\t_this.dispatchEvent(e);\n\t\t\t} else {\n\t\t\t\tvar e = constructEvent('error', evt);\n\t\t\t\t_this.onerror && _this.onerror(e);\n\t\t\t\t_this.dispatchEvent(e);\n\t\t\t}\n\t\t};\n\t\tthis.readAsArrayBuffer = function(file) {\n\t\t\tFileAPI.readAsBinaryString(file, listener);\n\t\t}\n\t\tthis.readAsBinaryString = function(file) {\n\t\t\tFileAPI.readAsBinaryString(file, listener);\n\t\t}\n\t\tthis.readAsDataURL = function(file) {\n\t\t\tFileAPI.readAsDataURL(file, listener);\n\t\t}\n\t\tthis.readAsText = function(file) {\n\t\t\tFileAPI.readAsText(file, listener);\n\t\t}\n\t}\n}\n})();\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ng-file-upload/angular-file-upload.js",
    "content": "/**!\n * AngularJS file upload/drop directive and service with progress and abort\n * @author  Danial  <danial.farid@gmail.com>\n * @version 3.3.3\n */\n(function () {\n\nvar key, i;\nfunction patchXHR(fnName, newFn) {\n    window.XMLHttpRequest.prototype[fnName] = newFn(window.XMLHttpRequest.prototype[fnName]);\n}\n\nif (window.XMLHttpRequest && !window.XMLHttpRequest.__isFileAPIShim) {\n    patchXHR('setRequestHeader', function (orig) {\n        return function (header, value) {\n            if (header === '__setXHR_') {\n                var val = value(this);\n                if (val instanceof Function) {\n                    val(this);\n                }\n            } else {\n                orig.apply(this, arguments);\n            }\n        }\n    });\n}\n\nvar angularFileUpload = angular.module('angularFileUpload', []);\n\nangularFileUpload.version = '3.3.3';\nangularFileUpload.service('$upload', ['$http', '$q', '$timeout', function ($http, $q, $timeout) {\n    function sendHttp(config) {\n        config.method = config.method || 'POST';\n        config.headers = config.headers || {};\n        config.transformRequest = config.transformRequest || function (data, headersGetter) {\n            if (window.ArrayBuffer && data instanceof window.ArrayBuffer) {\n                return data;\n            }\n            return $http.defaults.transformRequest[0](data, headersGetter);\n        };\n        var deferred = $q.defer();\n        var promise = deferred.promise;\n\n        config.headers['__setXHR_'] = function () {\n            return function (xhr) {\n                if (!xhr) return;\n                config.__XHR = xhr;\n                config.xhrFn && config.xhrFn(xhr);\n                xhr.upload.addEventListener('progress', function (e) {\n                    e.config = config;\n                    deferred.notify ? deferred.notify(e) : promise.progress_fn && $timeout(function () {\n                        promise.progress_fn(e)\n                    });\n                }, false);\n                xhr.upload.addEventListener('load', function (e) {\n                    if (e.lengthComputable) {\n                        e.config = config;\n                        deferred.notify ? deferred.notify(e) : promise.progress_fn && $timeout(function () {\n                            promise.progress_fn(e)\n                        });\n                    }\n                }, false);\n            };\n        };\n\n        $http(config).then(function (r) {\n            deferred.resolve(r)\n        }, function (e) {\n            deferred.reject(e)\n        }, function (n) {\n            deferred.notify(n)\n        });\n\n        promise.success = function (fn) {\n            promise.then(function (response) {\n                fn(response.data, response.status, response.headers, config);\n            });\n            return promise;\n        };\n\n        promise.error = function (fn) {\n            promise.then(null, function (response) {\n                fn(response.data, response.status, response.headers, config);\n            });\n            return promise;\n        };\n\n        promise.progress = function (fn) {\n            promise.progress_fn = fn;\n            promise.then(null, null, function (update) {\n                fn(update);\n            });\n            return promise;\n        };\n        promise.abort = function () {\n            if (config.__XHR) {\n                $timeout(function () {\n                    config.__XHR.abort();\n                });\n            }\n            return promise;\n        };\n        promise.xhr = function (fn) {\n            config.xhrFn = (function (origXhrFn) {\n                return function () {\n                    origXhrFn && origXhrFn.apply(promise, arguments);\n                    fn.apply(promise, arguments);\n                }\n            })(config.xhrFn);\n            return promise;\n        };\n\n        return promise;\n    }\n\n    this.upload = function (config) {\n        config.headers = config.headers || {};\n        config.headers['Content-Type'] = undefined;\n        config.transformRequest = config.transformRequest ?\n            (angular.isArray(config.transformRequest) ?\n                config.transformRequest : [config.transformRequest]) : [];\n        config.transformRequest.push(function (data) {\n            var formData = new FormData();\n            var allFields = {};\n            for (key in config.fields) {\n                if (config.fields.hasOwnProperty(key)) {\n                    allFields[key] = config.fields[key];\n                }\n            }\n            if (data) allFields['data'] = data;\n\n            if (config.formDataAppender) {\n                for (key in allFields) {\n                    if (allFields.hasOwnProperty(key)) {\n                        config.formDataAppender(formData, key, allFields[key]);\n                    }\n                }\n            } else {\n                for (key in allFields) {\n                    if (allFields.hasOwnProperty(key)) {\n                        var val = allFields[key];\n                        if (val !== undefined) {\n                            if (angular.isDate(val)) {\n                                val = val.toISOString();\n                            }\n                            if (angular.isString(val)) {\n                                formData.append(key, val);\n                            } else {\n                                if (config.sendObjectsAsJsonBlob && angular.isObject(val)) {\n                                    formData.append(key, new Blob([val], {type: 'application/json'}));\n                                } else {\n                                    formData.append(key, JSON.stringify(val));\n                                }\n                            }\n\n                        }\n                    }\n                }\n            }\n\n            if (config.file != null) {\n                var fileFormName = config.fileFormDataName || 'file';\n\n                if (angular.isArray(config.file)) {\n                    var isFileFormNameString = angular.isString(fileFormName);\n                    for (i = 0; i < config.file.length; i++) {\n                        formData.append(isFileFormNameString ? fileFormName : fileFormName[i], config.file[i],\n                            (config.fileName && config.fileName[i]) || config.file[i].name);\n                    }\n                } else {\n                    formData.append(fileFormName, config.file, config.fileName || config.file.name);\n                }\n            }\n            return formData;\n        });\n\n        return sendHttp(config);\n    };\n\n    this.http = function (config) {\n        return sendHttp(config);\n    };\n}]);\n\nangularFileUpload.directive('ngFileSelect', ['$parse', '$timeout', '$compile',\n    function ($parse, $timeout, $compile) {\n        return {\n            restrict: 'AEC',\n            require: '?ngModel',\n            link: function (scope, elem, attr, ngModel) {\n                linkFileSelect(scope, elem, attr, ngModel, $parse, $timeout, $compile);\n            }\n        }\n    }]);\n\nfunction linkFileSelect(scope, elem, attr, ngModel, $parse, $timeout, $compile) {\n    function isInputTypeFile() {\n        return elem[0].tagName.toLowerCase() === 'input' && elem.attr('type') && elem.attr('type').toLowerCase() === 'file';\n    }\n\n    var isUpdating = false;\n    function changeFn(evt) {\n        if (!isUpdating) {\n            isUpdating = true;\n            try {\n                var fileList = evt.__files_ || (evt.target && evt.target.files);\n                var files = [], rejFiles = [];\n\n                var accept = $parse(attr.ngAccept);\n                for (i = 0; i < fileList.length; i++) {\n                    var file = fileList.item(i);\n                    if (isAccepted(scope, accept, file, evt)) {\n                        files.push(file);\n                    } else {\n                        rejFiles.push(file);\n                    }\n                }\n                updateModel($parse, $timeout, scope, ngModel, attr,\n                    attr.ngFileChange || (attr.ngFileDrop && attr.ngFileDrop.indexOf('(') > 0), files, rejFiles, evt);\n                if (files.length == 0) evt.target.value = files;\n            } finally {\n                isUpdating = false;\n            }\n        }\n    }\n\n    function bindAttrToFileInput(fileElem) {\n        if (attr.ngMultiple) fileElem.attr('multiple', $parse(attr.ngMultiple)(scope));\n        if (!$parse(attr.ngMultiple)(scope)) fileElem.attr('multiple', undefined);\n        if (attr['accept']) fileElem.attr('accept', attr['accept']);\n        if (attr.ngCapture) fileElem.attr('capture', $parse(attr.ngCapture)(scope));\n        if (attr.ngDisabled) fileElem.attr('disabled', $parse(attr.ngDisabled)(scope));\n        for (var i = 0; i < elem[0].attributes.length; i++) {\n            var attribute = elem[0].attributes[i];\n            if (attribute.name !== 'type' && attribute.name !== 'class' && attribute.name !== 'id' && attribute.name !== 'style') {\n            \tfileElem.attr(attribute.name, attribute.value);\n            }\n        }\n    }\n\n    function createFileInput(evt) {\n        if (elem.attr('disabled')) {\n            return;\n        }\n        var fileElem = angular.element('<input type=\"file\">');\n        bindAttrToFileInput(fileElem);\n\n        if (isInputTypeFile()) {\n            elem.replaceWith(fileElem);\n            elem = fileElem;\n        } else {\n            fileElem.css('display', 'none').attr('tabindex', '-1').attr('__ngf_gen__', true);\n            if (elem.__ngf_ref_elem__) {elem.__ngf_ref_elem__.remove();}\n            elem.__ngf_ref_elem__ = fileElem;\n            document.body.appendChild(fileElem[0]);\n        }\n\n        return fileElem;\n    }\n\n    function resetModel(evt) {\n        updateModel($parse, $timeout, scope, ngModel, attr,\n            attr.ngFileChange || attr.ngFileSelect, [], [], evt, true);\n    }\n\n    var clickTouchEvent = 'ontouchend' in document ? 'touchend' : 'click'\n    function clickHandler(evt) {\n        var fileElem = createFileInput(evt);\n        if (fileElem) {\n        \tfileElem.bind('change', changeFn);\n        \tresetModel(evt);\n\n        \tfunction clickAndAssign() {\n            \tfileElem[0].click();\n    \t        if (isInputTypeFile()) {\n    \t            elem.bind(clickTouchEvent, clickHandler);\n    \t            evt.preventDefault()\n    \t        }\n        \t}\n        \tif (navigator.userAgent.toLowerCase().match(/android/)) {\n                setTimeout(function() {\n                \tclickAndAssign();\n                }, 0);        \t\t\n        \t} else {\n        \t\tclickAndAssign();\n        \t}\n        }\n    }\n\n    if (window.FileAPI && window.FileAPI.ngfFixIE) {\n        window.FileAPI.ngfFixIE(elem, createFileInput, bindAttrToFileInput, changeFn, resetModel);\n    } else {\n        elem.bind(clickTouchEvent, clickHandler);\n    }\n}\n\nangularFileUpload.directive('ngFileDrop', ['$parse', '$timeout', '$location', function ($parse, $timeout, $location) {\n    return {\n        restrict: 'AEC',\n        require: '?ngModel',\n        link: function (scope, elem, attr, ngModel) {\n            linkDrop(scope, elem, attr, ngModel, $parse, $timeout, $location);\n        }\n    }\n}]);\n\nangularFileUpload.directive('ngNoFileDrop', function () {\n    return function (scope, elem) {\n        if (dropAvailable()) elem.css('display', 'none')\n    }\n});\nangularFileUpload.directive('ngFileDropAvailable', ['$parse', '$timeout', function ($parse, $timeout) {\n    return function (scope, elem, attr) {\n        if (dropAvailable()) {\n            var fn = $parse(attr['ngFileDropAvailable']);\n            $timeout(function () {\n                fn(scope);\n            });\n        }\n    }\n}]);\n\nfunction linkDrop(scope, elem, attr, ngModel, $parse, $timeout, $location) {\n    var available = dropAvailable();\n    if (attr.dropAvailable) {\n        $timeout(function () {\n        \tscope[attr.dropAvailable] ? scope[attr.dropAvailable].value = available : scope[attr.dropAvailable] = available;\n        });\n    }\n    if (!available) {\n        if ($parse(attr.hideOnDropNotAvailable)(scope) == true) {\n            elem.css('display', 'none');\n        }\n        return;\n    }\n    var leaveTimeout = null;\n    var stopPropagation = $parse(attr.stopPropagation);\n    var dragOverDelay = 1;\n    var accept = $parse(attr.ngAccept);\n    var disabled = $parse(attr.ngDisabled);\n    var actualDragOverClass;\n\n    elem[0].addEventListener('dragover', function (evt) {\n        if (disabled(scope)) return;\n        evt.preventDefault();\n        if (stopPropagation(scope)) evt.stopPropagation();\n        if (navigator.userAgent.indexOf(\"Chrome\") > -1) {\n            var b = evt.dataTransfer.effectAllowed;\n            evt.dataTransfer.dropEffect = ('move' === b || 'linkMove' === b) ? 'move' : 'copy';\n        }\n        $timeout.cancel(leaveTimeout);\n        if (!scope.actualDragOverClass) {\n            actualDragOverClass = calculateDragOverClass(scope, attr, evt);\n        }\n        elem.addClass(actualDragOverClass);\n    }, false);\n    elem[0].addEventListener('dragenter', function (evt) {\n        if (disabled(scope)) return;\n        evt.preventDefault();\n        if (stopPropagation(scope)) evt.stopPropagation();\n    }, false);\n    elem[0].addEventListener('dragleave', function () {\n        if (disabled(scope)) return;\n        leaveTimeout = $timeout(function () {\n            elem.removeClass(actualDragOverClass);\n            actualDragOverClass = null;\n        }, dragOverDelay || 1);\n    }, false);\n    elem[0].addEventListener('drop', function (evt) {\n        if (disabled(scope)) return;\n        evt.preventDefault();\n        if (stopPropagation(scope)) evt.stopPropagation();\n        elem.removeClass(actualDragOverClass);\n        actualDragOverClass = null;\n        extractFiles(evt, function (files, rejFiles) {\n            updateModel($parse, $timeout, scope, ngModel, attr,\n                attr.ngFileChange || (attr.ngFileDrop && attr.ngFileDrop.indexOf('(') > 0), files, rejFiles, evt)\n        }, $parse(attr.allowDir)(scope) != false, attr.multiple || $parse(attr.ngMultiple)(scope));\n    }, false);\n\n    function calculateDragOverClass(scope, attr, evt) {\n        var accepted = true;\n        var items = evt.dataTransfer.items;\n        if (items != null) {\n            for (i = 0; i < items.length && accepted; i++) {\n                accepted = accepted\n                    && (items[i].kind == 'file' || items[i].kind == '')\n                    && isAccepted(scope, accept, items[i], evt);\n            }\n        }\n        var clazz = $parse(attr.dragOverClass)(scope, {$event: evt});\n        if (clazz) {\n            if (clazz.delay) dragOverDelay = clazz.delay;\n            if (clazz.accept) clazz = accepted ? clazz.accept : clazz.reject;\n        }\n        return clazz || attr['dragOverClass'] || 'dragover';\n    }\n\n    function extractFiles(evt, callback, allowDir, multiple) {\n        var files = [], rejFiles = [], items = evt.dataTransfer.items, processing = 0;\n\n        function addFile(file) {\n            if (isAccepted(scope, accept, file, evt)) {\n                files.push(file);\n            } else {\n                rejFiles.push(file);\n            }\n        }\n\n        if (items && items.length > 0 && $location.protocol() != 'file') {\n            for (var i = 0; i < items.length; i++) {\n                if (items[i].webkitGetAsEntry && items[i].webkitGetAsEntry() && items[i].webkitGetAsEntry().isDirectory) {\n                    var entry = items[i].webkitGetAsEntry();\n                    if (entry.isDirectory && !allowDir) {\n                        continue;\n                    }\n                    if (entry != null) {\n                        traverseFileTree(files, entry);\n                    }\n                } else {\n                    var f = items[i].getAsFile();\n                    if (f != null) addFile(f);\n                }\n                if (!multiple && files.length > 0) break;\n            }\n        } else {\n            var fileList = evt.dataTransfer.files;\n            if (fileList != null) {\n                for (var i = 0; i < fileList.length; i++) {\n                    addFile(fileList.item(i));\n                    if (!multiple && files.length > 0) break;\n                }\n            }\n        }\n        var delays = 0;\n        (function waitForProcess(delay) {\n            $timeout(function () {\n                if (!processing) {\n                    if (!multiple && files.length > 1) {\n                        i = 0;\n                        while (files[i].type == 'directory') i++;\n                        files = [files[i]];\n                    }\n                    callback(files, rejFiles);\n                } else {\n                    if (delays++ * 10 < 20 * 1000) {\n                        waitForProcess(10);\n                    }\n                }\n            }, delay || 0)\n        })();\n\n        function traverseFileTree(files, entry, path) {\n            if (entry != null) {\n                if (entry.isDirectory) {\n                    var filePath = (path || '') + entry.name;\n                    addFile({name: entry.name, type: 'directory', path: filePath});\n                    var dirReader = entry.createReader();\n                    var entries = [];\n                    processing++;\n                    var readEntries = function () {\n                        dirReader.readEntries(function (results) {\n                            try {\n                                if (!results.length) {\n                                    for (i = 0; i < entries.length; i++) {\n                                        traverseFileTree(files, entries[i], (path ? path : '') + entry.name + '/');\n                                    }\n                                    processing--;\n                                } else {\n                                    entries = entries.concat(Array.prototype.slice.call(results || [], 0));\n                                    readEntries();\n                                }\n                            } catch (e) {\n                                processing--;\n                                console.error(e);\n                            }\n                        }, function () {\n                            processing--;\n                        });\n                    };\n                    readEntries();\n                } else {\n                    processing++;\n                    entry.file(function (file) {\n                        try {\n                            processing--;\n                            file.path = (path ? path : '') + file.name;\n                            addFile(file);\n                        } catch (e) {\n                            processing--;\n                            console.error(e);\n                        }\n                    }, function () {\n                        processing--;\n                    });\n                }\n            }\n        }\n    }\n}\n\nfunction dropAvailable() {\n    var div = document.createElement('div');\n    return ('draggable' in div) && ('ondrop' in div);\n}\n\nfunction updateModel($parse, $timeout, scope, ngModel, attr, fileChange, files, rejFiles, evt, noDelay) {\n    function update() {\n        if (ngModel) {\n            $parse(attr.ngModel).assign(scope, files);\n            $timeout(function () {\n                ngModel && ngModel.$setViewValue(files != null && files.length == 0 ? null : files);\n            });\n        }\n        if (attr.ngModelRejected) {\n            $parse(attr.ngModelRejected).assign(scope, rejFiles);\n        }\n        if (fileChange) {\n            $parse(fileChange)(scope, {\n                $files: files,\n                $rejectedFiles: rejFiles,\n                $event: evt\n            });\n\n        }\n    }\n    if (noDelay) {\n        update();\n    } else {\n        $timeout(function () {\n            update();\n        });\n    }\n}\n\nfunction isAccepted(scope, accept, file, evt) {\n    var val = accept(scope, {$file: file, $event: evt});\n    if (val == null) {\n        return true;\n    }\n    if (angular.isString(val)) {\n        var regexp = new RegExp(globStringToRegex(val), 'gi')\n        val = (file.type != null && file.type.match(regexp)) ||\n        (file.name != null && file.name.match(regexp));\n    }\n    return val;\n}\n\nfunction globStringToRegex(str) {\n    if (str.length > 2 && str[0] === '/' && str[str.length - 1] === '/') {\n        return str.substring(1, str.length - 1);\n    }\n    var split = str.split(','), result = '';\n    if (split.length > 1) {\n        for (i = 0; i < split.length; i++) {\n            result += '(' + globStringToRegex(split[i]) + ')';\n            if (i < split.length - 1) {\n                result += '|'\n            }\n        }\n    } else {\n        if (str.indexOf('.') == 0) {\n            str = '*' + str;\n        }\n        result = '^' + str.replace(new RegExp('[.\\\\\\\\+*?\\\\[\\\\^\\\\]$(){}=!<>|:\\\\' + '-]', 'g'), '\\\\$&') + '$';\n        result = result.replace(/\\\\\\*/g, '.*').replace(/\\\\\\?/g, '.');\n    }\n    return result;\n}\n\nvar ngFileUpload = angular.module('ngFileUpload', []);\n\nfor (key in angularFileUpload) {\n    if (angularFileUpload.hasOwnProperty(key)) {\n        ngFileUpload[key] = angularFileUpload[key];\n    }\n}\n\n})();\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ng-file-upload/bower.json",
    "content": "{\n  \"name\": \"angular-file-upload\",\n  \"main\": \"angular-file-upload.js\",\n  \"version\": \"3.3.3\",\n  \"homepage\": \"https://github.com/danialfarid/angular-file-upload\",\n  \"authors\": [\n    \"danialf <danial.farid@gmail.com>\"\n  ],\n  \"description\": \"Lightweight Angular JS directive to upload files. Support drag&drop, progress and abort\",\n  \"license\": \"MIT\"\n }\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ng-file-upload/ng-file-upload-all.js",
    "content": ""
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ngInfiniteScroll/.bower.json",
    "content": "{\n  \"name\": \"ngInfiniteScroll\",\n  \"version\": \"1.2.0\",\n  \"main\": \"build/ng-infinite-scroll.js\",\n  \"ignore\": [\n    \"**/.*\",\n    \"_*\",\n    \"node_modules\",\n    \"compile\",\n    \"test\",\n    \"Gruntfile.coffee\",\n    \".*\"\n  ],\n  \"dependencies\": {\n    \"angular\": \">=1.2.0\"\n  },\n  \"homepage\": \"https://github.com/sroze/ngInfiniteScroll\",\n  \"_release\": \"1.2.0\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"1.2.0\",\n    \"commit\": \"78770d784efcc5e77ea9976c359057714486389a\"\n  },\n  \"_source\": \"git://github.com/sroze/ngInfiniteScroll.git\",\n  \"_target\": \"~1.2.0\",\n  \"_originalSource\": \"ngInfiniteScroll\",\n  \"_direct\": true\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ngInfiniteScroll/LICENSE",
    "content": "Copyright (c) 2012 Brandon Tilley\n\nPermission is hereby granted, free of charge, to any person\nobtaining a copy of this software and associated documentation\nfiles (the \"Software\"), to deal in the Software without\nrestriction, including without limitation the rights to use,\ncopy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the\nSoftware is furnished to do so, subject to the following\nconditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\nOF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\nHOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\nWHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\nFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\nOTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ngInfiniteScroll/README.md",
    "content": "![logo](http://sroze.github.com/ngInfiniteScroll/images/logo-resized.png)\n\n[![Build Status](https://travis-ci.org/sroze/ngInfiniteScroll.png?branch=master)](https://travis-ci.org/sroze/ngInfiniteScroll)\n\nngInfiniteScroll is a directive for [AngularJS](http://angularjs.org/) to evaluate an expression when the bottom of the directive's element approaches the bottom of the browser window, which can be used to implement infinite scrolling.\n\nDemos\n-----\n\nCheck out the running demos [at the ngInfiniteScroll web site](http://sroze.github.com/ngInfiniteScroll/demos.html).\n\nVersion Numbers\n---------------\n\nngInfinite Scroll follows [semantic versioning](http://semver.org/) and uses the following versioning scheme:\n\n * Versions starting with 0 (e.g. 0.1.0, 0.2.0, etc.) are for initial development, and the API is not stable\n * Versions with an even minor version (1.0.0, 1.4.0, 2.2.0, etc.) are stable releases\n * Versions with an odd minor version (1.1.0, 1.3.0, 2.1.0, etc.) are development releases\n\nThe [download page](http://sroze.github.com/ngInfiniteScroll/#download) allows you to pick among various versions and specify which releases are stable (not including pre-release builds).\n\nGetting Started\n---------------\n\n * Download ngInfiniteScroll from [the download page on the ngInfiniteScroll web site](http://sroze.github.com/ngInfiniteScroll/#download) or install it with:\n   * [Bower](http://bower.io/) via `bower install ngInfiniteScroll`\n   * [Nuget](https://www.nuget.org) via `PM> Install-Package ng-infinite-scroll`\n * Include the script tag on your page after the AngularJS and jQuery script tags (ngInfiniteScroll requires jQuery to run)\n\n        <script type='text/javascript' src='path/to/jquery.min.js'></script>\n        <script type='text/javascript' src='path/to/angular.min.js'></script>\n        <script type='text/javascript' src='path/to/ng-infinite-scroll.min.js'></script>\n\n * Ensure that your application module specifies `infinite-scroll` as a dependency:\n\n        angular.module('myApplication', ['infinite-scroll']);\n\n * Use the directive by specifying an `infinite-scroll` attribute on an element.\n\n        <div infinite-scroll=\"myPagingFunction()\" infinite-scroll-distance=\"3\"></div>\n\nNote that neither the module nor the directive use the `ng` prefix, as that prefix is reserved for the core Angular module.\n\nDetailed Documentation\n----------------------\n\nngInfiniteScroll accepts several attributes to customize the behavior of the directive; detailed instructions can be found [on the ngInfiniteScroll web site](http://sroze.github.com/ngInfiniteScroll/documentation.html).\n\nPorts\n-----\n\nIf you use [AngularDart](https://github.com/angular/angular.dart), Juha Komulainen has [a port of the project](http://pub.dartlang.org/packages/ng_infinite_scroll) you can use.\n\nLicense\n-------\n\nngInfiniteScroll is licensed under the MIT license. See the LICENSE file for more details.\n\nTesting\n-------\n\nngInfiniteScroll uses Protractor for testing. Note that you will need to have Chrome browser, and the `grunt-cli` npm package installed globally if you wish to use grunt (`npm install -g grunt-cli`). Then, install the dependencies with `npm install`.\n\n* `grunt test:protractor-local` - run tests\n\nThank you very much @pomerantsev for your work on these Protractor tests.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ngInfiniteScroll/bower.json",
    "content": "{\n    \"name\": \"ngInfiniteScroll\",\n    \"version\": \"1.2.0\",\n    \"main\": \"build/ng-infinite-scroll.js\",\n    \"ignore\": [\n        \"**/.*\",\n        \"_*\",\n        \"node_modules\",\n        \"compile\",\n        \"test\",\n        \"Gruntfile.coffee\",\n        \".*\"\n    ],\n    \"dependencies\": {\n        \"angular\": \">=1.2.0\"\n    }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ngInfiniteScroll/build/ng-infinite-scroll.js",
    "content": "/* ng-infinite-scroll - v1.2.0 - 2014-12-02 */\nvar mod;\n\nmod = angular.module('infinite-scroll', []);\n\nmod.value('THROTTLE_MILLISECONDS', null);\n\nmod.directive('infiniteScroll', [\n  '$rootScope', '$window', '$interval', 'THROTTLE_MILLISECONDS', function($rootScope, $window, $interval, THROTTLE_MILLISECONDS) {\n    return {\n      scope: {\n        infiniteScroll: '&',\n        infiniteScrollContainer: '=',\n        infiniteScrollDistance: '=',\n        infiniteScrollDisabled: '=',\n        infiniteScrollUseDocumentBottom: '='\n      },\n      link: function(scope, elem, attrs) {\n        var changeContainer, checkWhenEnabled, container, handleInfiniteScrollContainer, handleInfiniteScrollDisabled, handleInfiniteScrollDistance, handleInfiniteScrollUseDocumentBottom, handler, height, immediateCheck, offsetTop, pageYOffset, scrollDistance, scrollEnabled, throttle, useDocumentBottom, windowElement;\n        windowElement = angular.element($window);\n        scrollDistance = null;\n        scrollEnabled = null;\n        checkWhenEnabled = null;\n        container = null;\n        immediateCheck = true;\n        useDocumentBottom = false;\n        height = function(elem) {\n          elem = elem[0] || elem;\n          if (isNaN(elem.offsetHeight)) {\n            return elem.document.documentElement.clientHeight;\n          } else {\n            return elem.offsetHeight;\n          }\n        };\n        offsetTop = function(elem) {\n          if (!elem[0].getBoundingClientRect || elem.css('none')) {\n            return;\n          }\n          return elem[0].getBoundingClientRect().top + pageYOffset(elem);\n        };\n        pageYOffset = function(elem) {\n          elem = elem[0] || elem;\n          if (isNaN(window.pageYOffset)) {\n            return elem.document.documentElement.scrollTop;\n          } else {\n            return elem.ownerDocument.defaultView.pageYOffset;\n          }\n        };\n        handler = function() {\n          var containerBottom, containerTopOffset, elementBottom, remaining, shouldScroll;\n          if (container === windowElement) {\n            containerBottom = height(container) + pageYOffset(container[0].document.documentElement);\n            elementBottom = offsetTop(elem) + height(elem);\n          } else {\n            containerBottom = height(container);\n            containerTopOffset = 0;\n            if (offsetTop(container) !== void 0) {\n              containerTopOffset = offsetTop(container);\n            }\n            elementBottom = offsetTop(elem) - containerTopOffset + height(elem);\n          }\n          if (useDocumentBottom) {\n            elementBottom = height((elem[0].ownerDocument || elem[0].document).documentElement);\n          }\n          remaining = elementBottom - containerBottom;\n          shouldScroll = remaining <= height(container) * scrollDistance + 1;\n          if (shouldScroll) {\n            checkWhenEnabled = true;\n            if (scrollEnabled) {\n              if (scope.$$phase || $rootScope.$$phase) {\n                return scope.infiniteScroll();\n              } else {\n                return scope.$apply(scope.infiniteScroll);\n              }\n            }\n          } else {\n            return checkWhenEnabled = false;\n          }\n        };\n        throttle = function(func, wait) {\n          var later, previous, timeout;\n          timeout = null;\n          previous = 0;\n          later = function() {\n            var context;\n            previous = new Date().getTime();\n            $interval.cancel(timeout);\n            timeout = null;\n            func.call();\n            return context = null;\n          };\n          return function() {\n            var now, remaining;\n            now = new Date().getTime();\n            remaining = wait - (now - previous);\n            if (remaining <= 0) {\n              clearTimeout(timeout);\n              $interval.cancel(timeout);\n              timeout = null;\n              previous = now;\n              return func.call();\n            } else {\n              if (!timeout) {\n                return timeout = $interval(later, remaining, 1);\n              }\n            }\n          };\n        };\n        if (THROTTLE_MILLISECONDS != null) {\n          handler = throttle(handler, THROTTLE_MILLISECONDS);\n        }\n        scope.$on('$destroy', function() {\n          return container.unbind('scroll', handler);\n        });\n        handleInfiniteScrollDistance = function(v) {\n          return scrollDistance = parseFloat(v) || 0;\n        };\n        scope.$watch('infiniteScrollDistance', handleInfiniteScrollDistance);\n        handleInfiniteScrollDistance(scope.infiniteScrollDistance);\n        handleInfiniteScrollDisabled = function(v) {\n          scrollEnabled = !v;\n          if (scrollEnabled && checkWhenEnabled) {\n            checkWhenEnabled = false;\n            return handler();\n          }\n        };\n        scope.$watch('infiniteScrollDisabled', handleInfiniteScrollDisabled);\n        handleInfiniteScrollDisabled(scope.infiniteScrollDisabled);\n        handleInfiniteScrollUseDocumentBottom = function(v) {\n          return useDocumentBottom = v;\n        };\n        scope.$watch('infiniteScrollUseDocumentBottom', handleInfiniteScrollUseDocumentBottom);\n        handleInfiniteScrollUseDocumentBottom(scope.infiniteScrollUseDocumentBottom);\n        changeContainer = function(newContainer) {\n          if (container != null) {\n            container.unbind('scroll', handler);\n          }\n          container = newContainer;\n          if (newContainer != null) {\n            return container.bind('scroll', handler);\n          }\n        };\n        changeContainer(windowElement);\n        handleInfiniteScrollContainer = function(newContainer) {\n          if ((newContainer == null) || newContainer.length === 0) {\n            return;\n          }\n          if (newContainer instanceof HTMLElement) {\n            newContainer = angular.element(newContainer);\n          } else if (typeof newContainer.append === 'function') {\n            newContainer = angular.element(newContainer[newContainer.length - 1]);\n          } else if (typeof newContainer === 'string') {\n            newContainer = angular.element(document.querySelector(newContainer));\n          }\n          if (newContainer != null) {\n            return changeContainer(newContainer);\n          } else {\n            throw new Exception(\"invalid infinite-scroll-container attribute.\");\n          }\n        };\n        scope.$watch('infiniteScrollContainer', handleInfiniteScrollContainer);\n        handleInfiniteScrollContainer(scope.infiniteScrollContainer || []);\n        if (attrs.infiniteScrollParent != null) {\n          changeContainer(angular.element(elem.parent()));\n        }\n        if (attrs.infiniteScrollImmediateCheck != null) {\n          immediateCheck = scope.$eval(attrs.infiniteScrollImmediateCheck);\n        }\n        return $interval((function() {\n          if (immediateCheck) {\n            return handler();\n          }\n        }), 0, 1);\n      }\n    };\n  }\n]);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ngInfiniteScroll/package.json",
    "content": "{\n  \"name\": \"ng-infinite-scroll\",\n  \"version\": \"1.2.0\",\n  \"description\": \"Infinite scrolling for AngularJS\",\n  \"repository\": {\n    \"type\": \"git\",\n    \"url\": \"git://github.com/sroze/ngInfiniteScroll.git\"\n  },\n  \"browser\": \"build/ng-infinite-scroll.js\",\n  \"scripts\": {\n    \"test\": \"grunt test:protractor-local\"\n  },\n  \"author\": {\n    \"name\": \"Brandon Tilley\",\n    \"email\": \"brandon@brandontilley.com\",\n    \"url\": \"http://brandontilley.com\"\n  },\n  \"contributors\": [\n    {\n      \"name\": \"Samuel ROZE\",\n      \"email\": \"samuel.roze@gmail.com\",\n      \"url\": \"http://sroze.io\"\n    }\n  ],\n  \"license\": \"MIT\",\n  \"readmeFilename\": \"README.md\",\n  \"devDependencies\": {\n    \"coffee-script\": \"~1.8.0\",\n    \"grunt\": \"~0.4.5\",\n    \"grunt-coffeelint\": \"~0.0.13\",\n    \"grunt-contrib-clean\": \"~0.6.0\",\n    \"grunt-contrib-coffee\": \"~0.12.0\",\n    \"grunt-contrib-concat\": \"~0.5.0\",\n    \"grunt-contrib-connect\": \"0.8.0\",\n    \"grunt-contrib-uglify\": \"~0.6.0\",\n    \"grunt-protractor-runner\": \"1.1.4\",\n    \"mkdirp\": \"0.5.0\",\n    \"protractor\": \"1.4.0\",\n    \"sauce-connect-launcher\": \"0.9.0\"\n  }\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ngInfiniteScroll/src/infinite-scroll.coffee",
    "content": "mod = angular.module('infinite-scroll', [])\n\nmod.value('THROTTLE_MILLISECONDS', null)\n\nmod.directive 'infiniteScroll', ['$rootScope', '$window', '$interval', 'THROTTLE_MILLISECONDS', \\\n                                  ($rootScope, $window, $interval, THROTTLE_MILLISECONDS) ->\n  scope:\n    infiniteScroll: '&'\n    infiniteScrollContainer: '='\n    infiniteScrollDistance: '='\n    infiniteScrollDisabled: '='\n    infiniteScrollUseDocumentBottom: '='\n\n  link: (scope, elem, attrs) ->\n    windowElement = angular.element($window)\n\n    scrollDistance = null\n    scrollEnabled = null\n    checkWhenEnabled = null\n    container = null\n    immediateCheck = true\n    useDocumentBottom = false\n\n    height = (elem) ->\n      elem = elem[0] or elem\n\n      if isNaN(elem.offsetHeight) then elem.document.documentElement.clientHeight else elem.offsetHeight\n\n    offsetTop = (elem) ->\n      if not elem[0].getBoundingClientRect or elem.css('none')\n        return\n\n      elem[0].getBoundingClientRect().top + pageYOffset(elem)\n\n    pageYOffset = (elem) ->\n      elem = elem[0] or elem\n\n      if isNaN(window.pageYOffset) then elem.document.documentElement.scrollTop else elem.ownerDocument.defaultView.pageYOffset\n\n    # infinite-scroll specifies a function to call when the window,\n    # or some other container specified by infinite-scroll-container,\n    # is scrolled within a certain range from the bottom of the\n    # document. It is recommended to use infinite-scroll-disabled\n    # with a boolean that is set to true when the function is\n    # called in order to throttle the function call.\n    handler = ->\n      if container == windowElement\n        containerBottom = height(container) + pageYOffset(container[0].document.documentElement)\n        elementBottom = offsetTop(elem) + height(elem)\n      else\n        containerBottom = height(container)\n        containerTopOffset = 0\n        if offsetTop(container) != undefined\n          containerTopOffset = offsetTop(container)\n        elementBottom = offsetTop(elem) - containerTopOffset + height(elem)\n\n      if(useDocumentBottom)\n        elementBottom = height((elem[0].ownerDocument || elem[0].document).documentElement)\n\n      remaining = elementBottom - containerBottom\n      shouldScroll = remaining <= height(container) * scrollDistance + 1\n\n      if shouldScroll\n        checkWhenEnabled = true\n\n        if scrollEnabled\n          if scope.$$phase || $rootScope.$$phase\n            scope.infiniteScroll()\n          else\n            scope.$apply(scope.infiniteScroll)\n      else\n        checkWhenEnabled = false\n\n    # The optional THROTTLE_MILLISECONDS configuration value specifies\n    # a minimum time that should elapse between each call to the\n    # handler. N.b. the first call the handler will be run\n    # immediately, and the final call will always result in the\n    # handler being called after the `wait` period elapses.\n    # A slimmed down version of underscore's implementation.\n    throttle = (func, wait) ->\n      timeout = null\n      previous = 0\n      later = ->\n        previous = new Date().getTime()\n        $interval.cancel(timeout)\n        timeout = null\n        func.call()\n        context = null\n\n      return ->\n        now = new Date().getTime()\n        remaining = wait - (now - previous)\n        if remaining <= 0\n          clearTimeout timeout\n          $interval.cancel(timeout)\n          timeout = null\n          previous = now\n          func.call()\n        else timeout = $interval(later, remaining, 1) unless timeout\n\n    if THROTTLE_MILLISECONDS?\n      handler = throttle(handler, THROTTLE_MILLISECONDS)\n\n    scope.$on '$destroy', ->\n      container.unbind 'scroll', handler\n\n    # infinite-scroll-distance specifies how close to the bottom of the page\n    # the window is allowed to be before we trigger a new scroll. The value\n    # provided is multiplied by the container height; for example, to load\n    # more when the bottom of the page is less than 3 container heights away,\n    # specify a value of 3. Defaults to 0.\n    handleInfiniteScrollDistance = (v) ->\n      scrollDistance = parseFloat(v) or 0\n\n    scope.$watch 'infiniteScrollDistance', handleInfiniteScrollDistance\n    # If I don't explicitly call the handler here, tests fail. Don't know why yet.\n    handleInfiniteScrollDistance scope.infiniteScrollDistance\n\n    # infinite-scroll-disabled specifies a boolean that will keep the\n    # infnite scroll function from being called; this is useful for\n    # debouncing or throttling the function call. If an infinite\n    # scroll is triggered but this value evaluates to true, then\n    # once it switches back to false the infinite scroll function\n    # will be triggered again.\n    handleInfiniteScrollDisabled = (v) ->\n      scrollEnabled = !v\n      if scrollEnabled && checkWhenEnabled\n        checkWhenEnabled = false\n        handler()\n\n    scope.$watch 'infiniteScrollDisabled', handleInfiniteScrollDisabled\n    # If I don't explicitly call the handler here, tests fail. Don't know why yet.\n    handleInfiniteScrollDisabled scope.infiniteScrollDisabled\n\n    # use the bottom of the document instead of the element's bottom.\n    # This useful when the element does not have a height due to its\n    # children being absolute positioned.\n    handleInfiniteScrollUseDocumentBottom = (v) ->\n      useDocumentBottom = v\n\n    scope.$watch 'infiniteScrollUseDocumentBottom', handleInfiniteScrollUseDocumentBottom\n    handleInfiniteScrollUseDocumentBottom scope.infiniteScrollUseDocumentBottom\n\n    # infinite-scroll-container sets the container which we want to be\n    # infinte scrolled, instead of the whole window. Must be an\n    # Angular or jQuery element, or, if jQuery is loaded,\n    # a jQuery selector as a string.\n    changeContainer = (newContainer) ->\n      if container?\n        container.unbind 'scroll', handler\n\n      container = newContainer\n      if newContainer?\n        container.bind 'scroll', handler\n\n    changeContainer windowElement\n\n    handleInfiniteScrollContainer = (newContainer) ->\n      # TODO: For some reason newContainer is sometimes null instead\n      # of the empty array, which Angular is supposed to pass when the\n      # element is not defined\n      # (https://github.com/sroze/ngInfiniteScroll/pull/7#commitcomment-5748431).\n      # So I leave both checks.\n      if (not newContainer?) or newContainer.length == 0\n        return\n\n      if newContainer instanceof HTMLElement\n        newContainer = angular.element newContainer\n      else if typeof newContainer.append == 'function'\n        newContainer = angular.element newContainer[newContainer.length - 1]\n      else if typeof newContainer == 'string'\n        newContainer = angular.element document.querySelector newContainer\n\n      if newContainer?\n        changeContainer newContainer\n      else\n        throw new Exception(\"invalid infinite-scroll-container attribute.\")\n\n    scope.$watch 'infiniteScrollContainer', handleInfiniteScrollContainer\n    handleInfiniteScrollContainer(scope.infiniteScrollContainer or [])\n\n    # infinite-scroll-parent establishes this element's parent as the\n    # container infinitely scrolled instead of the whole window.\n    if attrs.infiniteScrollParent?\n      changeContainer angular.element elem.parent()\n\n    # infinte-scoll-immediate-check sets whether or not run the\n    # expression passed on infinite-scroll for the first time when the\n    # directive first loads, before any actual scroll.\n    if attrs.infiniteScrollImmediateCheck?\n      immediateCheck = scope.$eval(attrs.infiniteScrollImmediateCheck)\n\n    $interval (->\n      if immediateCheck\n        handler()\n    ), 0, 1\n]\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ngtoast/.bower.json",
    "content": "{\n  \"name\": \"ngToast\",\n  \"version\": \"1.5.0\",\n  \"main\": [\n    \"dist/ngToast.js\",\n    \"dist/ngToast.css\"\n  ],\n  \"authors\": [\n    \"Tamer Aydin (http://tamerayd.in)\",\n    \"Levi Thomason (http://www.levithomason.com)\"\n  ],\n  \"dependencies\": {\n    \"angular\": \">=1.2.15 <=1.4.0\",\n    \"angular-animate\": \">=1.2.17 <=1.4.0\",\n    \"angular-sanitize\": \">=1.2.15 <=1.4.0\"\n  },\n  \"devDependencies\": {\n    \"bootstrap\": \"~3.3.2\",\n    \"Faker\": \"~2.1.2\"\n  },\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"test\",\n    \"src\",\n    \".editorconfig\",\n    \".gitignore\",\n    \".gitattributes\",\n    \".jshintrc\",\n    \".travis.yml\",\n    \"Gruntfile.js\",\n    \"package.json\",\n    \"index.html\"\n  ],\n  \"homepage\": \"https://github.com/tameraydin/ngToast\",\n  \"_release\": \"1.5.0\",\n  \"_resolution\": {\n    \"type\": \"version\",\n    \"tag\": \"1.5.0\",\n    \"commit\": \"39d12eced161c23ccb3b3d3111d7454d83571882\"\n  },\n  \"_source\": \"git://github.com/tameraydin/ngToast.git\",\n  \"_target\": \"1.5.0\",\n  \"_originalSource\": \"ngtoast\",\n  \"_direct\": true\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ngtoast/README.md",
    "content": "ngToast [![Code Climate](http://img.shields.io/codeclimate/github/tameraydin/ngToast.svg?style=flat-square)](https://codeclimate.com/github/tameraydin/ngToast/dist/ngToast.js) [![Build Status](http://img.shields.io/travis/tameraydin/ngToast/master.svg?style=flat-square)](https://travis-ci.org/tameraydin/ngToast)\n=======\n\nngToast is a simple Angular provider for toast notifications.\n\n**[Demo](http://tameraydin.github.io/ngToast)**\n\n## Usage\n\n1. Install via [Bower](http://bower.io/):\n  ```console\n  bower install ngtoast --production\n  ```\n  or manually [download](https://github.com/tameraydin/ngToast/archive/master.zip).\n\n2. Include ngToast source files and dependencies ([ngSanitize](http://docs.angularjs.org/api/ngSanitize), [Bootstrap CSS](http://getbootstrap.com/)):\n  ```html\n  <link rel=\"stylesheet\" href=\"bower/bootstrap/dist/css/bootstrap.min.css\">\n  <link rel=\"stylesheet\" href=\"bower/ngtoast/dist/ngToast.min.css\">\n  \n  <script src=\"bower/angular-sanitize/angular-sanitize.min.js\"></script>\n  <script src=\"bower/ngtoast/dist/ngToast.min.js\"></script>\n  ```\n *Note: only the [Alerts](http://getbootstrap.com/components/#alerts) component is used as style base, so you don't have to include complete CSS*\n\n3. Include ngToast as a dependency in your application module:\n  ```javascript\n  var app = angular.module('myApp', ['ngToast']);\n  ```\n\n4. Place `toast` element into your HTML:\n  ```html\n  <body>\n    <toast></toast>\n    ...\n  </body>\n  ```\n\n5. Inject ngToast provider in your controller:\n  ```javascript\n  app.controller('myCtrl', function(ngToast) {\n    ngToast.create('a toast message...');\n  });\n  ```\n\n## Animations\nngToast comes with optional animations. In order to enable animations in ngToast, you need to include [ngAnimate](http://docs.angularjs.org/api/ngAnimate) module into your app:\n\n```html\n<script src=\"bower/angular-animate/angular-animate.min.js\"></script>\n```\n\n**Built-in**\n  1. Include the ngToast animation stylesheet:\n  \n  ```html\n  <link rel=\"stylesheet\" href=\"bower/ngtoast/dist/ngToast-animations.min.css\">\n  ```\n\n  2. Set the `animation` option.\n  ```javascript\n  app.config(['ngToastProvider', function(ngToastProvider) {\n    ngToastProvider.configure({\n      animation: 'slide',\n      horizontalPosition: 'right',\n      verticalPosition: 'top',\n      maxNumber: 0,\n    });\n  }]);\n  ```\n  Built-in ngToast animations include `fade` & `slide`.\n  \n**Custom**\n  1. Using the `additionalClasses` option and [ngAnimate](http://docs.angularjs.org/api/ngAnimate) you can easily add your own animations or wire up 3rd party css animations.\n  ```javascript\n  app.config(['ngToastProvider', function(ngToastProvider) {\n    ngToastProvider.configure({\n      additionalClasses: 'my-animation',\n      horizontalPosition: 'right',\n      verticalPosition: 'top',\n      maxNumber: 0,\n    });\n  }]);\n  ```\n\n  2. Then in your css (example using animate.css):\n  ```css\n  .my-animation.ng-enter {\n    animation: flipInY 1s;\n  }\n  \n  .my-animation.ng-leave {\n    animation: flipOutY 1s;\n  }\n  ```\n\n## Settings & API\n\nPlease find at the [project website](http://tameraydin.github.io/ngToast/#api).\n\n## Development\n\n* Clone the repo or [download](https://github.com/tameraydin/ngToast/archive/master.zip)\n* Install dependencies: ``npm install && bower install``\n* Run ``grunt watch``, play on **/src**\n* Build: ``grunt``\n\n## License\n\nMIT [http://tameraydin.mit-license.org/](http://tameraydin.mit-license.org/)\n\n## Maintainers\n\n- [Tamer Aydin](http://tamerayd.in)\n- [Levi Thomason](http://www.levithomason.com)\n\n## TODO\n- Add more unit & e2e tests\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ngtoast/bower.json",
    "content": "{\n  \"name\": \"ngToast\",\n  \"version\": \"1.5.0\",\n  \"main\": [\n    \"dist/ngToast.js\",\n    \"dist/ngToast.css\"\n  ],\n  \"authors\": [\n    \"Tamer Aydin (http://tamerayd.in)\",\n    \"Levi Thomason (http://www.levithomason.com)\"\n  ],\n  \"dependencies\": {\n    \"angular\": \">=1.2.15 <=1.4.0\",\n    \"angular-animate\": \">=1.2.17 <=1.4.0\",\n    \"angular-sanitize\": \">=1.2.15 <=1.4.0\"\n  },\n  \"devDependencies\": {\n    \"bootstrap\": \"~3.3.2\",\n    \"Faker\": \"~2.1.2\"\n  },\n  \"ignore\": [\n    \"**/.*\",\n    \"node_modules\",\n    \"test\",\n    \"src\",\n    \".editorconfig\",\n    \".gitignore\",\n    \".gitattributes\",\n    \".jshintrc\",\n    \".travis.yml\",\n    \"Gruntfile.js\",\n    \"package.json\",\n    \"index.html\"\n  ]\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ngtoast/dist/ngToast-animations.css",
    "content": "/*!\n * ngToast v1.5.0 (http://tameraydin.github.io/ngToast)\n * Copyright 2015 Tamer Aydin (http://tamerayd.in)\n * Licensed under MIT (http://tameraydin.mit-license.org/)\n */\n\n.ng-toast--animate-fade .ng-enter,\n.ng-toast--animate-fade .ng-leave,\n.ng-toast--animate-fade .ng-move {\n  transition-property: opacity;\n  transition-duration: 0.3s;\n  transition-timing-function: ease;\n}\n.ng-toast--animate-fade .ng-enter {\n  opacity: 0;\n}\n.ng-toast--animate-fade .ng-enter.ng-enter-active {\n  opacity: 1;\n}\n.ng-toast--animate-fade .ng-leave {\n  opacity: 1;\n}\n.ng-toast--animate-fade .ng-leave.ng-leave-active {\n  opacity: 0;\n}\n.ng-toast--animate-fade .ng-move {\n  opacity: 0.5;\n}\n.ng-toast--animate-fade .ng-move.ng-move-active {\n  opacity: 1;\n}\n\n.ng-toast--animate-slide .ng-enter,\n.ng-toast--animate-slide .ng-leave,\n.ng-toast--animate-slide .ng-move {\n  position: relative;\n  transition-duration: 0.3s;\n  transition-timing-function: ease;\n}\n.ng-toast--animate-slide.ng-toast--center.ng-toast--top .ng-toast__message {\n  position: relative;\n  transition-property: top, margin-top, opacity;\n}\n.ng-toast--animate-slide.ng-toast--center.ng-toast--top .ng-toast__message.ng-enter {\n  opacity: 0;\n  top: -100px;\n}\n.ng-toast--animate-slide.ng-toast--center.ng-toast--top .ng-toast__message.ng-enter.ng-enter-active {\n  opacity: 1;\n  top: 0;\n}\n.ng-toast--animate-slide.ng-toast--center.ng-toast--top .ng-toast__message.ng-leave {\n  opacity: 1;\n  top: 0;\n}\n.ng-toast--animate-slide.ng-toast--center.ng-toast--top .ng-toast__message.ng-leave.ng-leave-active {\n  opacity: 0;\n  margin-top: -72px;\n}\n.ng-toast--animate-slide.ng-toast--center.ng-toast--bottom .ng-toast__message {\n  position: relative;\n  transition-property: bottom, margin-bottom, opacity;\n}\n.ng-toast--animate-slide.ng-toast--center.ng-toast--bottom .ng-toast__message.ng-enter {\n  opacity: 0;\n  bottom: -100px;\n}\n.ng-toast--animate-slide.ng-toast--center.ng-toast--bottom .ng-toast__message.ng-enter.ng-enter-active {\n  opacity: 1;\n  bottom: 0;\n}\n.ng-toast--animate-slide.ng-toast--center.ng-toast--bottom .ng-toast__message.ng-leave {\n  opacity: 1;\n  bottom: 0;\n}\n.ng-toast--animate-slide.ng-toast--center.ng-toast--bottom .ng-toast__message.ng-leave.ng-leave-active {\n  opacity: 0;\n  margin-bottom: -72px;\n}\n.ng-toast--animate-slide.ng-toast--right {\n  transition-property: right, margin-right, opacity;\n}\n.ng-toast--animate-slide.ng-toast--right .ng-enter {\n  opacity: 0;\n  right: -200%;\n  margin-right: 20px;\n}\n.ng-toast--animate-slide.ng-toast--right .ng-enter.ng-enter-active {\n  opacity: 1;\n  right: 0;\n  margin-right: 0;\n}\n.ng-toast--animate-slide.ng-toast--right .ng-leave {\n  opacity: 1;\n  right: 0;\n  margin-right: 0;\n}\n.ng-toast--animate-slide.ng-toast--right .ng-leave.ng-leave-active {\n  opacity: 0;\n  right: -200%;\n  margin-right: 20px;\n}\n.ng-toast--animate-slide.ng-toast--left {\n  transition-property: left, margin-left, opacity;\n}\n.ng-toast--animate-slide.ng-toast--left .ng-enter {\n  opacity: 0;\n  left: -200%;\n  margin-left: 20px;\n}\n.ng-toast--animate-slide.ng-toast--left .ng-enter.ng-enter-active {\n  opacity: 1;\n  left: 0;\n  margin-left: 0;\n}\n.ng-toast--animate-slide.ng-toast--left .ng-leave {\n  opacity: 1;\n  left: 0;\n  margin-left: 0;\n}\n.ng-toast--animate-slide.ng-toast--left .ng-leave.ng-leave-active {\n  opacity: 0;\n  left: -200%;\n  margin-left: 20px;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ngtoast/dist/ngToast.css",
    "content": "/*!\n * ngToast v1.5.0 (http://tameraydin.github.io/ngToast)\n * Copyright 2015 Tamer Aydin (http://tamerayd.in)\n * Licensed under MIT (http://tameraydin.mit-license.org/)\n */\n\n.ng-toast {\n  position: fixed;\n  z-index: 1080;\n  width: 100%;\n  height: 0;\n  margin-top: 20px;\n  text-align: center;\n}\n.ng-toast.ng-toast--top {\n  top: 0;\n  bottom: auto;\n}\n.ng-toast.ng-toast--top .ng-toast__list {\n  top: 0;\n  bottom: auto;\n}\n.ng-toast.ng-toast--top.ng-toast--center .ng-toast__list {\n  position: static;\n}\n.ng-toast.ng-toast--bottom {\n  top: auto;\n  bottom: 0;\n}\n.ng-toast.ng-toast--bottom .ng-toast__list {\n  top: auto;\n  bottom: 0;\n}\n.ng-toast.ng-toast--bottom.ng-toast--center .ng-toast__list {\n  pointer-events: none;\n}\n.ng-toast.ng-toast--bottom.ng-toast--center .ng-toast__message .alert {\n  pointer-events: auto;\n}\n.ng-toast.ng-toast--right .ng-toast__list {\n  left: auto;\n  right: 0;\n  margin-right: 20px;\n}\n.ng-toast.ng-toast--right .ng-toast__message {\n  text-align: right;\n}\n.ng-toast.ng-toast--left .ng-toast__list {\n  right: auto;\n  left: 0;\n  margin-left: 20px;\n}\n.ng-toast.ng-toast--left .ng-toast__message {\n  text-align: left;\n}\n.ng-toast .ng-toast__list {\n  display: inline-block;\n  position: absolute;\n  right: 0;\n  left: 0;\n  margin: 0 auto;\n  padding: 0;\n  list-style: none;\n}\n.ng-toast .ng-toast__message {\n  display: block;\n  width: 100%;\n  text-align: center;\n}\n.ng-toast .ng-toast__message .alert {\n  display: inline-block;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/ngtoast/dist/ngToast.js",
    "content": "/*!\n * ngToast v1.5.0 (http://tameraydin.github.io/ngToast)\n * Copyright 2015 Tamer Aydin (http://tamerayd.in)\n * Licensed under MIT (http://tameraydin.mit-license.org/)\n */\n(function(window, angular, undefined) {\n  'use strict';\n\n  angular.module('ngToast.provider', [])\n    .provider('ngToast', [\n      function() {\n        var messages = [],\n            messageStack = [];\n\n        var defaults = {\n          animation: false,\n          className: 'success',\n          additionalClasses: null,\n          dismissOnTimeout: true,\n          timeout: 4000,\n          dismissButton: false,\n          dismissButtonHtml: '&times;',\n          dismissOnClick: true,\n          compileContent: false,\n          horizontalPosition: 'right', // right, center, left\n          verticalPosition: 'top', // top, bottom,\n          maxNumber: 0\n        };\n\n        function Message(msg) {\n          var id = Math.floor(Math.random()*1000);\n          while (messages.indexOf(id) > -1) {\n            id = Math.floor(Math.random()*1000);\n          }\n\n          this.id = id;\n          this.animation = defaults.animation;\n          this.className = defaults.className;\n          this.additionalClasses = defaults.additionalClasses;\n          this.dismissOnTimeout = defaults.dismissOnTimeout;\n          this.timeout = defaults.timeout;\n          this.dismissButton = defaults.dismissButton;\n          this.dismissButtonHtml = defaults.dismissButtonHtml;\n          this.dismissOnClick = defaults.dismissOnClick;\n          this.compileContent = defaults.compileContent;\n\n          angular.extend(this, msg);\n        }\n\n        this.configure = function(config) {\n          angular.extend(defaults, config);\n        };\n\n        this.$get = [function() {\n          return {\n            settings: defaults,\n            messages: messages,\n            dismiss: function(id) {\n              if (id) {\n                for (var i = messages.length - 1; i >= 0; i--) {\n                  if (messages[i].id === id) {\n                    messages.splice(i, 1);\n                    messageStack.splice(messageStack.indexOf(id), 1);\n                    return;\n                  }\n                }\n\n              } else {\n                while(messages.length > 0) {\n                  messages.pop();\n                }\n                messageStack = [];\n              }\n            },\n            create: function(msg) {\n              if (defaults.maxNumber > 0 &&\n                  messageStack.length >= defaults.maxNumber) {\n                this.dismiss(messageStack[0]);\n              }\n\n              msg = (typeof msg === 'string') ? {content: msg} : msg;\n\n              var newMsg = new Message(msg);\n              if (defaults.verticalPosition === 'bottom') {\n                messages.unshift(newMsg);\n              } else {\n                messages.push(newMsg);\n              }\n              messageStack.push(newMsg.id);\n              return newMsg.id;\n            }\n          };\n        }];\n      }\n    ]);\n\n})(window, window.angular);\n\n(function(window, angular) {\n  'use strict';\n\n  angular.module('ngToast.directives', ['ngToast.provider'])\n    .directive('toast', ['ngToast', '$templateCache', '$log',\n      function(ngToast, $templateCache, $log) {\n        return {\n          replace: true,\n          restrict: 'EA',\n          template:\n            '<div class=\"ng-toast ng-toast--{{hPos}} ng-toast--{{vPos}} {{animation ? \\'ng-toast--animate-\\' + animation : \\'\\'}}\">' +\n              '<ul class=\"ng-toast__list\">' +\n                '<toast-message ng-repeat=\"message in messages\" ' +\n                  'message=\"message\">' +\n                  '<span ng-bind-html=\"message.content\"></span>' +\n                '</toast-message>' +\n              '</ul>' +\n            '</div>',\n          compile: function(tElem, tAttrs) {\n            if (tAttrs.template) {\n              var template = $templateCache.get(tAttrs.template);\n              if (template) {\n                tElem.replaceWith(template);\n              } else {\n                $log.warn('ngToast: Provided template could not be loaded. ' +\n                  'Please be sure that it is populated before the <toast> element is represented.');\n              }\n            }\n\n            return function(scope) {\n              scope.hPos = ngToast.settings.horizontalPosition;\n              scope.vPos = ngToast.settings.verticalPosition;\n              scope.animation = ngToast.settings.animation;\n              scope.messages = ngToast.messages;\n            };\n          }\n        };\n      }\n    ])\n    .directive('toastMessage', ['$timeout', '$compile', 'ngToast',\n      function($timeout, $compile, ngToast) {\n        return {\n          replace: true,\n          transclude: true,\n          restrict: 'EA',\n          scope: {\n            message: '='\n          },\n          controller: ['$scope', 'ngToast', function($scope, ngToast) {\n            $scope.dismiss = function() {\n              ngToast.dismiss($scope.message.id);\n            };\n          }],\n          template:\n            '<li class=\"ng-toast__message {{message.additionalClasses}}\">' +\n              '<div class=\"alert alert-{{message.className}}\" ' +\n                'ng-class=\"{\\'alert-dismissible\\': message.dismissButton}\">' +\n                '<button type=\"button\" class=\"close\" ' +\n                  'ng-if=\"message.dismissButton\" ' +\n                  'ng-bind-html=\"message.dismissButtonHtml\" ' +\n                  'ng-click=\"!message.dismissOnClick && dismiss()\">' +\n                '</button>' +\n                '<span ng-if=\"!message.compileContent\" ng-transclude></span>' +\n              '</div>' +\n            '</li>',\n          link: function(scope, element, attrs, ctrl, transclude) {\n            if (scope.message.compileContent) {\n              var transcludedEl;\n\n              transclude(scope, function(clone) {\n                transcludedEl = clone;\n                element.children().append(transcludedEl);\n              });\n\n              $timeout(function() {\n                $compile(transcludedEl.contents())\n                  (scope.$parent, function(compiledClone) {\n                    transcludedEl.replaceWith(compiledClone);\n                  });\n              }, 0);\n            }\n\n            if (scope.message.dismissOnTimeout) {\n              $timeout(function() {\n                ngToast.dismiss(scope.message.id);\n              }, scope.message.timeout);\n            }\n\n            if (scope.message.dismissOnClick) {\n              element.bind('click', function() {\n                ngToast.dismiss(scope.message.id);\n                scope.$apply();\n              });\n            }\n          }\n        };\n      }\n    ]);\n\n})(window, window.angular);\n\n(function(window, angular) {\n  'use strict';\n\n  angular\n    .module('ngToast', [\n      'ngSanitize',\n      'ngToast.directives',\n      'ngToast.provider'\n    ]);\n\n})(window, window.angular);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/.bower.json",
    "content": "{\n  \"name\": \"openlayers\",\n  \"homepage\": \"https://github.com/openlayers/openlayers\",\n  \"_release\": \"fed67aafc2\",\n  \"_resolution\": {\n    \"type\": \"branch\",\n    \"branch\": \"master\",\n    \"commit\": \"fed67aafc253b9876e6766eb30beac336a804d6f\"\n  },\n  \"_source\": \"git://github.com/openlayers/openlayers.git\",\n  \"_target\": \"*\",\n  \"_originalSource\": \"openlayers\"\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/.gitignore",
    "content": "/build/OpenLayers.js\n/tools/closure-compiler.jar\n/tools/*.pyc\n/apidoc_config/Data/\n/doc/apidocs/\n/examples/example-list.js\n/examples/example-list.xml\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/apidoc_config/Languages.txt",
    "content": "Format: 1.52\n\n# This is the Natural Docs languages file for this project.  If you change\n# anything here, it will apply to THIS PROJECT ONLY.  If you'd like to change\n# something for all your projects, edit the Languages.txt in Natural Docs'\n# Config directory instead.\n\n\n# You can prevent certain file extensions from being scanned like this:\n# Ignore Extensions: [extension] [extension] ...\n\n\n#-------------------------------------------------------------------------------\n# SYNTAX:\n#\n# Unlike other Natural Docs configuration files, in this file all comments\n# MUST be alone on a line.  Some languages deal with the # character, so you\n# cannot put comments on the same line as content.\n#\n# Also, all lists are separated with spaces, not commas, again because some\n# languages may need to use them.\n#\n# Language: [name]\n# Alter Language: [name]\n#    Defines a new language or alters an existing one.  Its name can use any\n#    characters.  If any of the properties below have an add/replace form, you\n#    must use that when using Alter Language.\n#\n#    The language Shebang Script is special.  It's entry is only used for\n#    extensions, and files with those extensions have their shebang (#!) lines\n#    read to determine the real language of the file.  Extensionless files are\n#    always treated this way.\n#\n#    The language Text File is also special.  It's treated as one big comment\n#    so you can put Natural Docs content in them without special symbols.  Also,\n#    if you don't specify a package separator, ignored prefixes, or enum value\n#    behavior, it will copy those settings from the language that is used most\n#    in the source tree.\n#\n# Extensions: [extension] [extension] ...\n# [Add/Replace] Extensions: [extension] [extension] ...\n#    Defines the file extensions of the language's source files.  You can\n#    redefine extensions found in the main languages file.  You can use * to\n#    mean any undefined extension.\n#\n# Shebang Strings: [string] [string] ...\n# [Add/Replace] Shebang Strings: [string] [string] ...\n#    Defines a list of strings that can appear in the shebang (#!) line to\n#    designate that it's part of the language.  You can redefine strings found\n#    in the main languages file.\n#\n# Ignore Prefixes in Index: [prefix] [prefix] ...\n# [Add/Replace] Ignored Prefixes in Index: [prefix] [prefix] ...\n#\n# Ignore [Topic Type] Prefixes in Index: [prefix] [prefix] ...\n# [Add/Replace] Ignored [Topic Type] Prefixes in Index: [prefix] [prefix] ...\n#    Specifies prefixes that should be ignored when sorting symbols in an\n#    index.  Can be specified in general or for a specific topic type.\n#\n#------------------------------------------------------------------------------\n# For basic language support only:\n#\n# Line Comments: [symbol] [symbol] ...\n#    Defines a space-separated list of symbols that are used for line comments,\n#    if any.\n#\n# Block Comments: [opening sym] [closing sym] [opening sym] [closing sym] ...\n#    Defines a space-separated list of symbol pairs that are used for block\n#    comments, if any.\n#\n# Package Separator: [symbol]\n#    Defines the default package separator symbol.  The default is a dot.\n#\n# [Topic Type] Prototype Enders: [symbol] [symbol] ...\n#    When defined, Natural Docs will attempt to get a prototype from the code\n#    immediately following the topic type.  It stops when it reaches one of\n#    these symbols.  Use \\n for line breaks.\n#\n# Line Extender: [symbol]\n#    Defines the symbol that allows a prototype to span multiple lines if\n#    normally a line break would end it.\n#\n# Enum Values: [global|under type|under parent]\n#    Defines how enum values are referenced.  The default is global.\n#    global       - Values are always global, referenced as 'value'.\n#    under type   - Values are under the enum type, referenced as\n#               'package.enum.value'.\n#    under parent - Values are under the enum's parent, referenced as\n#               'package.value'.\n#\n# Perl Package: [perl package]\n#    Specifies the Perl package used to fine-tune the language behavior in ways\n#    too complex to do in this file.\n#\n#------------------------------------------------------------------------------\n# For full language support only:\n#\n# Full Language Support: [perl package]\n#    Specifies the Perl package that has the parsing routines necessary for full\n#    language support.\n#\n#-------------------------------------------------------------------------------\n\n# The following languages are defined in the main file, if you'd like to alter\n# them:\n#\n#    Text File, Shebang Script, C/C++, C#, Java, JavaScript, Perl, Python,\n#    PHP, SQL, Visual Basic, Pascal, Assembly, Ada, Tcl, Ruby, Makefile,\n#    ActionScript, ColdFusion, R, Fortran\n\n# If you add a language that you think would be useful to other developers\n# and should be included in Natural Docs by default, please e-mail it to\n# languages [at] naturaldocs [dot] org.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/apidoc_config/Menu.txt",
    "content": "Format: 1.52\n\n\nTitle: OpenLayers\nSubTitle: JavaScript Mapping Library\n\n# You can add a footer to your documentation like this:\n# Footer: [text]\n# If you want to add a copyright notice, this would be the place to do it.\n\n# You can add a timestamp to your documentation like one of these:\n# Timestamp: Generated on month day, year\n# Timestamp: Updated mm/dd/yyyy\n# Timestamp: Last updated mon day\n#\n#   m     - One or two digit month.  January is \"1\"\n#   mm    - Always two digit month.  January is \"01\"\n#   mon   - Short month word.  January is \"Jan\"\n#   month - Long month word.  January is \"January\"\n#   d     - One or two digit day.  1 is \"1\"\n#   dd    - Always two digit day.  1 is \"01\"\n#   day   - Day with letter extension.  1 is \"1st\"\n#   yy    - Two digit year.  2006 is \"06\"\n#   yyyy  - Four digit year.  2006 is \"2006\"\n#   year  - Four digit year.  2006 is \"2006\"\n\n\n# --------------------------------------------------------------------------\n# \n# Cut and paste the lines below to change the order in which your files\n# appear on the menu.  Don't worry about adding or removing files, Natural\n# Docs will take care of that.\n# \n# You can further organize the menu by grouping the entries.  Add a\n# \"Group: [name] {\" line to start a group, and add a \"}\" to end it.\n# \n# You can add text and web links to the menu by adding \"Text: [text]\" and\n# \"Link: [name] ([URL])\" lines, respectively.\n# \n# The formatting and comments are auto-generated, so don't worry about\n# neatness when editing the file.  Natural Docs will clean it up the next\n# time it is run.  When working with groups, just deal with the braces and\n# forget about the indentation and comments.\n# \n# --------------------------------------------------------------------------\n\n\nGroup: OpenLayers  {\n\n   File: OpenLayers  (no auto-title, OpenLayers.js)\n\n   Group: BaseTypes  {\n\n      File: Base Types  (no auto-title, OpenLayers/BaseTypes.js)\n      File: Bounds  (no auto-title, OpenLayers/BaseTypes/Bounds.js)\n      File: Class  (no auto-title, OpenLayers/BaseTypes/Class.js)\n      File: Date  (no auto-title, OpenLayers/BaseTypes/Date.js)\n      File: Element  (no auto-title, OpenLayers/BaseTypes/Element.js)\n      File: LonLat  (no auto-title, OpenLayers/BaseTypes/LonLat.js)\n      File: Pixel  (no auto-title, OpenLayers/BaseTypes/Pixel.js)\n      File: Size  (no auto-title, OpenLayers/BaseTypes/Size.js)\n      }  # Group: BaseTypes\n\n   Group: Control  {\n\n      File: Control  (no auto-title, OpenLayers/Control.js)\n\n      Group: Control  {\n\n         File: ArgParser  (no auto-title, OpenLayers/Control/ArgParser.js)\n         File: Attribution  (no auto-title, OpenLayers/Control/Attribution.js)\n         File: Button  (no auto-title, OpenLayers/Control/Button.js)\n         File: CacheRead  (OpenLayers/Control/CacheRead.js)\n         File: CacheWrite  (OpenLayers/Control/CacheWrite.js)\n         File: DragFeature  (no auto-title, OpenLayers/Control/DragFeature.js)\n         File: DragPan  (no auto-title, OpenLayers/Control/DragPan.js)\n         File: DrawFeature  (no auto-title, OpenLayers/Control/DrawFeature.js)\n         File: EditingToolbar  (no auto-title, OpenLayers/Control/EditingToolbar.js)\n         File: Geolocate  (no auto-title, OpenLayers/Control/Geolocate.js)\n         File: GetFeature  (no auto-title, OpenLayers/Control/GetFeature.js)\n         File: Graticule  (no auto-title, OpenLayers/Control/Graticule.js)\n         File: KeyboardDefaults  (no auto-title, OpenLayers/Control/KeyboardDefaults.js)\n         File: LayerSwitcher  (no auto-title, OpenLayers/Control/LayerSwitcher.js)\n         File: Measure  (no auto-title, OpenLayers/Control/Measure.js)\n         File: ModifyFeature  (no auto-title, OpenLayers/Control/ModifyFeature.js)\n         File: ModifyFeature.BySegment  (OpenLayers/Control/ModifyFeature/BySegment.js)\n         File: MousePosition  (no auto-title, OpenLayers/Control/MousePosition.js)\n         File: Navigation  (no auto-title, OpenLayers/Control/Navigation.js)\n         File: NavigationHistory  (no auto-title, OpenLayers/Control/NavigationHistory.js)\n         File: NavToolbar  (no auto-title, OpenLayers/Control/NavToolbar.js)\n         File: OverviewMap  (no auto-title, OpenLayers/Control/OverviewMap.js)\n         File: Pan  (no auto-title, OpenLayers/Control/Pan.js)\n         File: Panel  (no auto-title, OpenLayers/Control/Panel.js)\n         File: PanPanel  (no auto-title, OpenLayers/Control/PanPanel.js)\n         File: PanZoom  (no auto-title, OpenLayers/Control/PanZoom.js)\n         File: PanZoomBar  (no auto-title, OpenLayers/Control/PanZoomBar.js)\n         File: Permalink  (no auto-title, OpenLayers/Control/Permalink.js)\n         File: PinchZoom  (no auto-title, OpenLayers/Control/PinchZoom.js)\n         File: Scale  (no auto-title, OpenLayers/Control/Scale.js)\n         File: ScaleLine  (no auto-title, OpenLayers/Control/ScaleLine.js)\n         File: SelectFeature  (no auto-title, OpenLayers/Control/SelectFeature.js)\n         File: SLDSelect  (no auto-title, OpenLayers/Control/SLDSelect.js)\n         File: Snapping  (no auto-title, OpenLayers/Control/Snapping.js)\n         File: Split  (no auto-title, OpenLayers/Control/Split.js)\n         File: TextButtonPanel  (OpenLayers/Control/TextButtonPanel.js)\n         File: TouchNavigation  (no auto-title, OpenLayers/Control/TouchNavigation.js)\n         File: TransformFeature  (no auto-title, OpenLayers/Control/TransformFeature.js)\n         File: UTFGrid  (OpenLayers/Control/UTFGrid.js)\n         File: WMSGetFeatureInfo  (no auto-title, OpenLayers/Control/WMSGetFeatureInfo.js)\n         File: WMTSGetFeatureInfo  (no auto-title, OpenLayers/Control/WMTSGetFeatureInfo.js)\n         File: Zoom  (OpenLayers/Control/Zoom.js)\n         File: ZoomBox  (no auto-title, OpenLayers/Control/ZoomBox.js)\n         File: ZoomIn  (no auto-title, OpenLayers/Control/ZoomIn.js)\n         File: ZoomOut  (no auto-title, OpenLayers/Control/ZoomOut.js)\n         File: ZoomPanel  (no auto-title, OpenLayers/Control/ZoomPanel.js)\n         File: ZoomToMaxExtent  (no auto-title, OpenLayers/Control/ZoomToMaxExtent.js)\n         }  # Group: Control\n\n      }  # Group: Control\n\n   Group: Feature  {\n\n      File: Feature  (no auto-title, OpenLayers/Feature.js)\n      File: Vector  (no auto-title, OpenLayers/Feature/Vector.js)\n      }  # Group: Feature\n\n   Group: Filter  {\n\n      File: Filter  (no auto-title, OpenLayers/Filter.js)\n      File: Comparison  (no auto-title, OpenLayers/Filter/Comparison.js)\n      File: FeatureId  (no auto-title, OpenLayers/Filter/FeatureId.js)\n      File: Function  (no auto-title, OpenLayers/Filter/Function.js)\n      File: Logical  (no auto-title, OpenLayers/Filter/Logical.js)\n      File: Spatial  (no auto-title, OpenLayers/Filter/Spatial.js)\n      }  # Group: Filter\n\n   Group: Format  {\n\n      File: Format  (no auto-title, OpenLayers/Format.js)\n\n      Group: Filter  {\n\n         File: Filter  (no auto-title, OpenLayers/Format/Filter.js)\n         File: v1  (no auto-title, OpenLayers/Format/Filter/v1.js)\n         File: v1_0_0  (no auto-title, OpenLayers/Format/Filter/v1_0_0.js)\n         File: v1_1_0  (no auto-title, OpenLayers/Format/Filter/v1_1_0.js)\n         File: v2  (OpenLayers/Format/Filter/v2.js)\n         File: v2_0_0  (OpenLayers/Format/Filter/v2_0_0.js)\n         }  # Group: Filter\n\n      Group: GML  {\n\n         File: GML  (no auto-title, OpenLayers/Format/GML.js)\n         File: Base  (no auto-title, OpenLayers/Format/GML/Base.js)\n         File: v2  (no auto-title, OpenLayers/Format/GML/v2.js)\n         File: v3  (no auto-title, OpenLayers/Format/GML/v3.js)\n         }  # Group: GML\n\n      Group: SLD  {\n\n         File: SLD  (no auto-title, OpenLayers/Format/SLD.js)\n         File: SLD/v1_0_0_GeoServer  (OpenLayers/Format/SLD/v1_0_0_GeoServer.js)\n         File: v1  (no auto-title, OpenLayers/Format/SLD/v1.js)\n         File: v1_0_0  (no auto-title, OpenLayers/Format/SLD/v1_0_0.js)\n         }  # Group: SLD\n\n      Group: OWSCommon  {\n\n         File: OWSCommon  (no auto-title, OpenLayers/Format/OWSCommon.js)\n         File: v1  (no auto-title, OpenLayers/Format/OWSCommon/v1.js)\n         File: v1_0_0  (no auto-title, OpenLayers/Format/OWSCommon/v1_0_0.js)\n         File: v1_1_0  (no auto-title, OpenLayers/Format/OWSCommon/v1_1_0.js)\n         }  # Group: OWSCommon\n\n      Group: WFSCapabilities  {\n\n         File: WFSCapabilities  (no auto-title, OpenLayers/Format/WFSCapabilities.js)\n         File: v1  (no auto-title, OpenLayers/Format/WFSCapabilities/v1.js)\n         File: v1_0_0  (no auto-title, OpenLayers/Format/WFSCapabilities/v1_0_0.js)\n         File: v1_1_0  (no auto-title, OpenLayers/Format/WFSCapabilities/v1_1_0.js)\n         File: v2_0_0  (OpenLayers/Format/WFSCapabilities/v2_0_0.js)\n         }  # Group: WFSCapabilities\n\n      Group: WFST  {\n\n         File: WFST  (no auto-title, OpenLayers/Format/WFST.js)\n         File: v1  (no auto-title, OpenLayers/Format/WFST/v1.js)\n         File: v1_0_0  (no auto-title, OpenLayers/Format/WFST/v1_0_0.js)\n         File: v1_1_0  (no auto-title, OpenLayers/Format/WFST/v1_1_0.js)\n         File: v2_0_0  (OpenLayers/Format/WFST/v2_0_0.js)\n         }  # Group: WFST\n\n      Group: WMC  {\n\n         File: WMC  (no auto-title, OpenLayers/Format/WMC.js)\n         File: v1  (no auto-title, OpenLayers/Format/WMC/v1.js)\n         File: v1_0_0  (no auto-title, OpenLayers/Format/WMC/v1_0_0.js)\n         File: v1_1_0  (no auto-title, OpenLayers/Format/WMC/v1_1_0.js)\n         }  # Group: WMC\n\n      Group: WMSCapabilities  {\n\n         File: WMSCapabilities  (no auto-title, OpenLayers/Format/WMSCapabilities.js)\n         File: v1  (no auto-title, OpenLayers/Format/WMSCapabilities/v1.js)\n         File: v1_1  (no auto-title, OpenLayers/Format/WMSCapabilities/v1_1.js)\n         File: v1_1_0  (no auto-title, OpenLayers/Format/WMSCapabilities/v1_1_0.js)\n         File: v1_1_1  (no auto-title, OpenLayers/Format/WMSCapabilities/v1_1_1.js)\n         File: v1_3  (no auto-title, OpenLayers/Format/WMSCapabilities/v1_3.js)\n         File: v1_3_0  (no auto-title, OpenLayers/Format/WMSCapabilities/v1_3_0.js)\n         File: WMSCapabilities/v1_1_1_WMSC  (no auto-title, OpenLayers/Format/WMSCapabilities/v1_1_1_WMSC.js)\n         }  # Group: WMSCapabilities\n\n      Group: WMSDescribeLayer  {\n\n         File: WMSDescribeLayer  (no auto-title, OpenLayers/Format/WMSDescribeLayer.js)\n         File: v1_1  (no auto-title, OpenLayers/Format/WMSDescribeLayer/v1_1.js)\n         }  # Group: WMSDescribeLayer\n\n      Group: Format  {\n\n         File: ArcXML  (no auto-title, OpenLayers/Format/ArcXML.js)\n         File: ArcXML.Features  (no auto-title, OpenLayers/Format/ArcXML/Features.js)\n         File: Atom  (no auto-title, OpenLayers/Format/Atom.js)\n         File: Context  (no auto-title, OpenLayers/Format/Context.js)\n         File: CQL  (no auto-title, OpenLayers/Format/CQL.js)\n         File: CSWGetDomain  (no auto-title, OpenLayers/Format/CSWGetDomain.js)\n         File: CSWGetDomain.v2_0_2  (no auto-title, OpenLayers/Format/CSWGetDomain/v2_0_2.js)\n         File: CSWGetRecords  (no auto-title, OpenLayers/Format/CSWGetRecords.js)\n         File: CSWGetRecords.v2_0_2  (no auto-title, OpenLayers/Format/CSWGetRecords/v2_0_2.js)\n         File: EncodedPolyline  (OpenLayers/Format/EncodedPolyline.js)\n         File: GeoJSON  (no auto-title, OpenLayers/Format/GeoJSON.js)\n         File: GeoRSS  (no auto-title, OpenLayers/Format/GeoRSS.js)\n         File: GPX  (no auto-title, OpenLayers/Format/GPX.js)\n         File: JSON  (no auto-title, OpenLayers/Format/JSON.js)\n         File: KML  (no auto-title, OpenLayers/Format/KML.js)\n         File: OGCExceptionReport  (no auto-title, OpenLayers/Format/OGCExceptionReport.js)\n         File: OSM  (no auto-title, OpenLayers/Format/OSM.js)\n         File: OWSContext  (no auto-title, OpenLayers/Format/OWSContext.js)\n         File: OWSContext.v0_3_1  (no auto-title, OpenLayers/Format/OWSContext/v0_3_1.js)\n         File: QueryStringFilter  (no auto-title, OpenLayers/Format/QueryStringFilter.js)\n         File: SOSCapabilities  (no auto-title, OpenLayers/Format/SOSCapabilities.js)\n         File: SOSCapabilities.v1_0_0  (no auto-title, OpenLayers/Format/SOSCapabilities/v1_0_0.js)\n         File: SOSGetFeatureOfInterest  (no auto-title, OpenLayers/Format/SOSGetFeatureOfInterest.js)\n         File: SOSGetObservation  (no auto-title, OpenLayers/Format/SOSGetObservation.js)\n         File: Text  (no auto-title, OpenLayers/Format/Text.js)\n         File: TMSCapabilities  (OpenLayers/Format/TMSCapabilities.js)\n         File: WCSCapabilities  (OpenLayers/Format/WCSCapabilities.js)\n\n         Group: WCSCapabilities  {\n\n            File: WCSCapabilities.v1  (OpenLayers/Format/WCSCapabilities/v1.js)\n            File: WCSCapabilities/v1_0_0  (OpenLayers/Format/WCSCapabilities/v1_0_0.js)\n            File: WCSCapabilities/v1_1_0  (OpenLayers/Format/WCSCapabilities/v1_1_0.js)\n            }  # Group: WCSCapabilities\n\n         File: WCSDescribeCoverage  (OpenLayers/Format/WCSDescribeCoverage.js)\n\n         Group: WCSDescribeCoverage  {\n\n            File: WCSDescribeCoverage.v1  (OpenLayers/Format/WCSDescribeCoverage/v1.js)\n            File: WCSDescribeCoverage/v1_0_0  (OpenLayers/Format/WCSDescribeCoverage/v1_0_0.js)\n            File: WCSDescribeCoverage/v1_1_0  (OpenLayers/Format/WCSDescribeCoverage/v1_1_0.js)\n            }  # Group: WCSDescribeCoverage\n\n         File: WCSGetCoverage version 1.1.0  (no auto-title, OpenLayers/Format/WCSGetCoverage.js)\n         File: WFS  (no auto-title, OpenLayers/Format/WFS.js)\n         File: WFSDescribeFeatureType  (no auto-title, OpenLayers/Format/WFSDescribeFeatureType.js)\n         File: WKT  (no auto-title, OpenLayers/Format/WKT.js)\n         File: WMSGetFeatureInfo  (no auto-title, OpenLayers/Format/WMSGetFeatureInfo.js)\n         File: WMTSCapabilities  (no auto-title, OpenLayers/Format/WMTSCapabilities.js)\n         File: WMTSCapabilities.v1_0_0  (no auto-title, OpenLayers/Format/WMTSCapabilities/v1_0_0.js)\n         File: WPSCapabilities  (no auto-title, OpenLayers/Format/WPSCapabilities.js)\n         File: WPSCapabilities.v1_0_0  (no auto-title, OpenLayers/Format/WPSCapabilities/v1_0_0.js)\n         File: WPSDescribeProcess  (no auto-title, OpenLayers/Format/WPSDescribeProcess.js)\n         File: WPSExecute version 1.0.0  (no auto-title, OpenLayers/Format/WPSExecute.js)\n         File: XLS  (no auto-title, OpenLayers/Format/XLS.js)\n         File: XLS.v1  (no auto-title, OpenLayers/Format/XLS/v1.js)\n         File: XLS.v1_1_0  (no auto-title, OpenLayers/Format/XLS/v1_1_0.js)\n         File: XML  (no auto-title, OpenLayers/Format/XML.js)\n         File: XML.VersionedOGC  (OpenLayers/Format/XML/VersionedOGC.js)\n         }  # Group: Format\n\n      }  # Group: Format\n\n   Group: Geometry  {\n\n      File: Geometry  (no auto-title, OpenLayers/Geometry.js)\n      File: Collection  (no auto-title, OpenLayers/Geometry/Collection.js)\n      File: Curve  (no auto-title, OpenLayers/Geometry/Curve.js)\n      File: LinearRing  (no auto-title, OpenLayers/Geometry/LinearRing.js)\n      File: LineString  (no auto-title, OpenLayers/Geometry/LineString.js)\n      File: MultiLineString  (no auto-title, OpenLayers/Geometry/MultiLineString.js)\n      File: MultiPoint  (no auto-title, OpenLayers/Geometry/MultiPoint.js)\n      File: MultiPolygon  (no auto-title, OpenLayers/Geometry/MultiPolygon.js)\n      File: Point  (no auto-title, OpenLayers/Geometry/Point.js)\n      File: Polygon  (no auto-title, OpenLayers/Geometry/Polygon.js)\n      }  # Group: Geometry\n\n   Group: Handler  {\n\n      File: Handler  (no auto-title, OpenLayers/Handler.js)\n      File: Box  (no auto-title, OpenLayers/Handler/Box.js)\n      File: Click  (no auto-title, OpenLayers/Handler/Click.js)\n      File: Drag  (no auto-title, OpenLayers/Handler/Drag.js)\n      File: Feature  (no auto-title, OpenLayers/Handler/Feature.js)\n      File: Hover  (no auto-title, OpenLayers/Handler/Hover.js)\n      File: Keyboard  (no auto-title, OpenLayers/Handler/Keyboard.js)\n      File: MouseWheel  (no auto-title, OpenLayers/Handler/MouseWheel.js)\n      File: Path  (no auto-title, OpenLayers/Handler/Path.js)\n      File: Pinch  (no auto-title, OpenLayers/Handler/Pinch.js)\n      File: Point  (no auto-title, OpenLayers/Handler/Point.js)\n      File: Polygon  (no auto-title, OpenLayers/Handler/Polygon.js)\n      File: RegularPolygon  (no auto-title, OpenLayers/Handler/RegularPolygon.js)\n      }  # Group: Handler\n\n   Group: Lang  {\n\n      File: Lang  (no auto-title, OpenLayers/Lang.js)\n\n      Group: Lang  {\n\n         File: ar  (no auto-title, OpenLayers/Lang/ar.js)\n         File: be-tarask  (no auto-title, OpenLayers/Lang/be-tarask.js)\n         File: bg  (no auto-title, OpenLayers/Lang/bg.js)\n         File: br  (no auto-title, OpenLayers/Lang/br.js)\n         File: ca  (no auto-title, OpenLayers/Lang/ca.js)\n         File: cs-CZ  (no auto-title, OpenLayers/Lang/cs-CZ.js)\n         File: da-DK  (no auto-title, OpenLayers/Lang/da-DK.js)\n         File: de  (no auto-title, OpenLayers/Lang/de.js)\n         File: en  (no auto-title, OpenLayers/Lang/en.js)\n         File: en-CA  (no auto-title, OpenLayers/Lang/en-CA.js)\n         File: es  (no auto-title, OpenLayers/Lang/es.js)\n         File: el  (no auto-title, OpenLayers/Lang/el.js)\n         File: fi  (no auto-title, OpenLayers/Lang/fi.js)\n         File: fr  (no auto-title, OpenLayers/Lang/fr.js)\n         File: fur  (no auto-title, OpenLayers/Lang/fur.js)\n         File: gl  (no auto-title, OpenLayers/Lang/gl.js)\n         File: gsw  (no auto-title, OpenLayers/Lang/gsw.js)\n         File: hr  (no auto-title, OpenLayers/Lang/hr.js)\n         File: hsb  (no auto-title, OpenLayers/Lang/hsb.js)\n         File: hu  (no auto-title, OpenLayers/Lang/hu.js)\n         File: ia  (no auto-title, OpenLayers/Lang/ia.js)\n         File: id  (no auto-title, OpenLayers/Lang/id.js)\n         File: io  (no auto-title, OpenLayers/Lang/io.js)\n         File: is  (no auto-title, OpenLayers/Lang/is.js)\n         File: it  (no auto-title, OpenLayers/Lang/it.js)\n         File: ja  (no auto-title, OpenLayers/Lang/ja.js)\n         File: km  (no auto-title, OpenLayers/Lang/km.js)\n         File: ksh  (no auto-title, OpenLayers/Lang/ksh.js)\n         File: lt  (no auto-title, OpenLayers/Lang/lt.js)\n         File: nds  (no auto-title, OpenLayers/Lang/nds.js)\n         File: nb  (no auto-title, OpenLayers/Lang/nb.js)\n         File: nl  (no auto-title, OpenLayers/Lang/nl.js)\n         File: nn  (no auto-title, OpenLayers/Lang/nn.js)\n         File: oc  (no auto-title, OpenLayers/Lang/oc.js)\n         File: pt  (no auto-title, OpenLayers/Lang/pt.js)\n         File: pl  (no auto-title, OpenLayers/Lang/pl.js)\n         File: pt-BR  (no auto-title, OpenLayers/Lang/pt-BR.js)\n         File: ru  (no auto-title, OpenLayers/Lang/ru.js)\n         File: sk  (no auto-title, OpenLayers/Lang/sk.js)\n         File: sv-SE  (no auto-title, OpenLayers/Lang/sv-SE.js)\n         File: te  (no auto-title, OpenLayers/Lang/te.js)\n         File: vi  (no auto-title, OpenLayers/Lang/vi.js)\n         File: zh-CN  (no auto-title, OpenLayers/Lang/zh-CN.js)\n         File: zh-TW  (no auto-title, OpenLayers/Lang/zh-TW.js)\n         File: Lang[\"ro\"]  (OpenLayers/Lang/ro.js)\n         }  # Group: Lang\n\n      }  # Group: Lang\n\n   Group: Layer  {\n\n      File: Layer  (no auto-title, OpenLayers/Layer.js)\n\n      Group: Layer  {\n\n         File: ArcGISCache.js  (no auto-title, OpenLayers/Layer/ArcGISCache.js)\n         File: ArcGIS93Rest  (no auto-title, OpenLayers/Layer/ArcGIS93Rest.js)\n         File: ArcIMS  (no auto-title, OpenLayers/Layer/ArcIMS.js)\n         File: Bing  (no auto-title, OpenLayers/Layer/Bing.js)\n         File: Boxes  (no auto-title, OpenLayers/Layer/Boxes.js)\n         File: EventPane  (no auto-title, OpenLayers/Layer/EventPane.js)\n         File: FixedZoomLevels  (no auto-title, OpenLayers/Layer/FixedZoomLevels.js)\n         File: GeoRSS  (no auto-title, OpenLayers/Layer/GeoRSS.js)\n         File: Google  (no auto-title, OpenLayers/Layer/Google.js)\n         File: Google.v3  (no auto-title, OpenLayers/Layer/Google/v3.js)\n         File: Grid  (no auto-title, OpenLayers/Layer/Grid.js)\n         File: HTTPRequest  (no auto-title, OpenLayers/Layer/HTTPRequest.js)\n         File: Image  (no auto-title, OpenLayers/Layer/Image.js)\n         File: KaMap  (no auto-title, OpenLayers/Layer/KaMap.js)\n         File: KaMapCache  (no auto-title, OpenLayers/Layer/KaMapCache.js)\n         File: MapGuide  (no auto-title, OpenLayers/Layer/MapGuide.js)\n         File: MapServer  (no auto-title, OpenLayers/Layer/MapServer.js)\n         File: Markers  (no auto-title, OpenLayers/Layer/Markers.js)\n         File: OSM  (no auto-title, OpenLayers/Layer/OSM.js)\n         File: PointGrid  (no auto-title, OpenLayers/Layer/PointGrid.js)\n         File: PointTrack  (no auto-title, OpenLayers/Layer/PointTrack.js)\n         File: SphericalMercator  (no auto-title, OpenLayers/Layer/SphericalMercator.js)\n         File: Text  (no auto-title, OpenLayers/Layer/Text.js)\n         File: TileCache  (no auto-title, OpenLayers/Layer/TileCache.js)\n         File: TMS  (no auto-title, OpenLayers/Layer/TMS.js)\n         File: Vector  (no auto-title, OpenLayers/Layer/Vector.js)\n         File: Vector.RootContainer  (no auto-title, OpenLayers/Layer/Vector/RootContainer.js)\n         File: WMS  (no auto-title, OpenLayers/Layer/WMS.js)\n         File: WMTS  (no auto-title, OpenLayers/Layer/WMTS.js)\n         File: WorldWind  (no auto-title, OpenLayers/Layer/WorldWind.js)\n         File: XYZ  (no auto-title, OpenLayers/Layer/XYZ.js)\n         File: Zoomify  (no auto-title, OpenLayers/Layer/Zoomify.js)\n         File: UTFGrid  (OpenLayers/Layer/UTFGrid.js)\n         }  # Group: Layer\n\n      }  # Group: Layer\n\n   Group: Marker  {\n\n      File: Marker  (no auto-title, OpenLayers/Marker.js)\n      File: Box  (no auto-title, OpenLayers/Marker/Box.js)\n      }  # Group: Marker\n\n   Group: Popup  {\n\n      File: Popup  (no auto-title, OpenLayers/Popup.js)\n      File: Anchored  (no auto-title, OpenLayers/Popup/Anchored.js)\n      File: Framed  (no auto-title, OpenLayers/Popup/Framed.js)\n      File: FramedCloud  (no auto-title, OpenLayers/Popup/FramedCloud.js)\n      }  # Group: Popup\n\n   Group: Protocol  {\n\n      File: Protocol  (no auto-title, OpenLayers/Protocol.js)\n\n      Group: Protocol  {\n\n         File: CSW  (OpenLayers/Protocol/CSW.js)\n         File: CSW.v2_0_2  (OpenLayers/Protocol/CSW/v2_0_2.js)\n         File: HTTP  (no auto-title, OpenLayers/Protocol/HTTP.js)\n         File: Script  (no auto-title, OpenLayers/Protocol/Script.js)\n         File: SOS.DEFAULTS  (no auto-title, OpenLayers/Protocol/SOS.js)\n         File: SOS.v1_0_0  (no auto-title, OpenLayers/Protocol/SOS/v1_0_0.js)\n         }  # Group: Protocol\n\n      Group: WFS  {\n\n         File: WFS  (no auto-title, OpenLayers/Protocol/WFS.js)\n         File: v1  (no auto-title, OpenLayers/Protocol/WFS/v1.js)\n         File: v1_0_0  (no auto-title, OpenLayers/Protocol/WFS/v1_0_0.js)\n         File: v1_1_0  (no auto-title, OpenLayers/Protocol/WFS/v1_1_0.js)\n         File: v2_0_0  (OpenLayers/Protocol/WFS/v2_0_0.js)\n         }  # Group: WFS\n\n      }  # Group: Protocol\n\n   Group: Renderer  {\n\n      File: Renderer  (no auto-title, OpenLayers/Renderer.js)\n      File: Canvas  (no auto-title, OpenLayers/Renderer/Canvas.js)\n      File: ElementsIndexer  (no auto-title, OpenLayers/Renderer/Elements.js)\n      File: SVG  (no auto-title, OpenLayers/Renderer/SVG.js)\n      File: VML  (no auto-title, OpenLayers/Renderer/VML.js)\n      }  # Group: Renderer\n\n   Group: Request  {\n\n      File: Request  (no auto-title, OpenLayers/Request.js)\n      File: XMLHttpRequest  (no auto-title, OpenLayers/Request/XMLHttpRequest.js)\n      }  # Group: Request\n\n   Group: Strategy  {\n\n      File: Strategy  (no auto-title, OpenLayers/Strategy.js)\n      File: BBOX  (no auto-title, OpenLayers/Strategy/BBOX.js)\n      File: Cluster  (no auto-title, OpenLayers/Strategy/Cluster.js)\n      File: Filter  (no auto-title, OpenLayers/Strategy/Filter.js)\n      File: Fixed  (no auto-title, OpenLayers/Strategy/Fixed.js)\n      File: Paging  (no auto-title, OpenLayers/Strategy/Paging.js)\n      File: Refresh  (no auto-title, OpenLayers/Strategy/Refresh.js)\n      File: Save  (no auto-title, OpenLayers/Strategy/Save.js)\n      }  # Group: Strategy\n\n   Group: Symbolizer  {\n\n      File: Symbolizer  (no auto-title, OpenLayers/Symbolizer.js)\n      File: Line  (no auto-title, OpenLayers/Symbolizer/Line.js)\n      File: Point  (no auto-title, OpenLayers/Symbolizer/Point.js)\n      File: Polygon  (no auto-title, OpenLayers/Symbolizer/Polygon.js)\n      File: Raster  (no auto-title, OpenLayers/Symbolizer/Raster.js)\n      File: Text  (no auto-title, OpenLayers/Symbolizer/Text.js)\n      }  # Group: Symbolizer\n\n   Group: Tile  {\n\n      File: Tile  (no auto-title, OpenLayers/Tile.js)\n      File: Image  (no auto-title, OpenLayers/Tile/Image.js)\n      File: Image.IFrame  (no auto-title, OpenLayers/Tile/Image/IFrame.js)\n      File: UTFGrid  (OpenLayers/Tile/UTFGrid.js)\n      }  # Group: Tile\n\n   File: Deprecated  (no auto-title, deprecated.js)\n\n   Group: OpenLayers  {\n\n      File: Console  (no auto-title, OpenLayers/Console.js)\n      File: Events  (no auto-title, OpenLayers/Events.js)\n      File: Icon  (no auto-title, OpenLayers/Icon.js)\n      File: Map  (no auto-title, OpenLayers/Map.js)\n      File: OpenLayers.Animation  (OpenLayers/Animation.js)\n      File: OpenLayers.Events.buttonclick  (OpenLayers/Events/buttonclick.js)\n      File: OpenLayers.Events.featureclick  (OpenLayers/Events/featureclick.js)\n      File: OpenLayers.Kinetic  (OpenLayers/Kinetic.js)\n      File: OpenLayers.TileManager  (OpenLayers/TileManager.js)\n      File: OpenLayers.Util.vendorPrefix  (OpenLayers/Util/vendorPrefix.js)\n      File: OpenLayers.WPSClient  (OpenLayers/WPSClient.js)\n      File: OpenLayers.WPSProcess  (OpenLayers/WPSProcess.js)\n      File: Projection  (no auto-title, OpenLayers/Projection.js)\n      File: Rule  (no auto-title, OpenLayers/Rule.js)\n      File: SingleFile.js  (no auto-title, OpenLayers/SingleFile.js)\n      File: Spherical  (OpenLayers/Spherical.js)\n      File: Style  (no auto-title, OpenLayers/Style.js)\n      File: Style2  (no auto-title, OpenLayers/Style2.js)\n      File: StyleMap  (no auto-title, OpenLayers/StyleMap.js)\n      File: Tween  (no auto-title, OpenLayers/Tween.js)\n      File: Util  (no auto-title, OpenLayers/Util.js)\n      }  # Group: OpenLayers\n\n   }  # Group: OpenLayers\n\nGroup: Index  {\n\n   Index: Everything\n   Class Index: Classes\n   Constant Index: Constants\n   Function Index: Functions\n   Property Index: Properties\n   File Index: Files\n   Constructor Index: Constructor\n   }  # Group: Index\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/apidoc_config/OL.css",
    "content": "p {\n    text-indent: 0; margin-bottom: 1em;\n}\n\n.MGroup {\n    font-variant: normal;\n    margin: 0.4em 0 0em 10px\n}\n\n.MTitle {\n    font-variant: normal;\n}\n\n.CGroup .CTitle {\n    font-variant: normal;\n}\n\n.SGroup .SEntry {\n    font-variant: normal;\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/apidoc_config/Topics.txt",
    "content": "Format: 1.52\n\n# This is the Natural Docs topics file for this project.  If you change anything\n# here, it will apply to THIS PROJECT ONLY.  If you'd like to change something\n# for all your projects, edit the Topics.txt in Natural Docs' Config directory\n# instead.\n\n\nIgnore Keywords: \n   function, functions\n   func, funcs\n   procedure, procedures\n   proc, procs\n   routine, routines\n   subroutine, subroutines\n   sub, subs\n   method, methods\n   callback, callbacks\n   property, properties\n   prop, props\n\n\n#-------------------------------------------------------------------------------\n# SYNTAX:\n#\n# Topic Type: [name]\n# Alter Topic Type: [name]\n#    Creates a new topic type or alters one from the main file.  Each type gets\n#    its own index and behavior settings.  Its name can have letters, numbers,\n#    spaces, and these charaters: - / . '\n#\n# Plural: [name]\n#    Sets the plural name of the topic type, if different.\n#\n# Keywords:\n#    [keyword]\n#    [keyword], [plural keyword]\n#    ...\n#    Defines or adds to the list of keywords for the topic type.  They may only\n#    contain letters, numbers, and spaces and are not case sensitive.  Plural\n#    keywords are used for list topics.  You can redefine keywords found in the\n#    main topics file.\n#\n# Index: [yes|no]\n#    Whether the topics get their own index.  Defaults to yes.  Everything is\n#    included in the general index regardless of this setting.\n#\n# Scope: [normal|start|end|always global]\n#    How the topics affects scope.  Defaults to normal.\n#    normal        - Topics stay within the current scope.\n#    start         - Topics start a new scope for all the topics beneath it,\n#                    like class topics.\n#    end           - Topics reset the scope back to global for all the topics\n#                    beneath it.\n#    always global - Topics are defined as global, but do not change the scope\n#                    for any other topics.\n#\n# Class Hierarchy: [yes|no]\n#    Whether the topics are part of the class hierarchy.  Defaults to no.\n#\n# Page Title If First: [yes|no]\n#    Whether the topic's title becomes the page title if it's the first one in\n#    a file.  Defaults to no.\n#\n# Break Lists: [yes|no]\n#    Whether list topics should be broken into individual topics in the output.\n#    Defaults to no.\n#\n# Can Group With: [type], [type], ...\n#    Defines a list of topic types that this one can possibly be grouped with.\n#    Defaults to none.\n#-------------------------------------------------------------------------------\n\n# The following topics are defined in the main file, if you'd like to alter\n# their behavior or add keywords:\n#\n#    Generic, Class, Interface, Section, File, Group, Function, Variable,\n#    Property, Type, Constant, Enumeration, Event, Delegate, Macro,\n#    Database, Database Table, Database View, Database Index, Database\n#    Cursor, Database Trigger, Cookie, Build Target\n\n# If you add something that you think would be useful to other developers\n# and should be included in Natural Docs by default, please e-mail it to\n# topics [at] naturaldocs [dot] org.\n\n\nTopic Type: Constructor\n\n   Class Hierarchy: Yes\n   Keywords:\n      constructor\n      initialize\n\n\nAlter Topic Type: Function\n\n   Add Keywords:\n      apimethod\n      apifunction\n\n\nAlter Topic Type: Property\n\n   Add Keywords:\n      apiproperty\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/authors.txt",
    "content": "OpenLayers contributors:\n\nAntoine Abt\nMike Adair\nJeff Adams\nSeb Benthall\nBruno Binet\nStéphane Brunner\nHoward Butler\nBertil Chaupis                                                               \nJohn Cole\nTim Coulter\nRobert Coup\nJeff Dege\nRoald de Wit\nSchuyler Erle\nChristian López Espínola\nJohn Frank\nSean Gilles\nPierre Giraud\nIvan Grcic\nAndreas Hocevar\nMarc Jansen\nIan Johnson\nFrédéric Junod\nEric Lemoine\nPhilip Lindsay\nMartijn van Oosterhout\nDavid Overstrom\nCorey Puffault\nPeter William Robins\nGregers Rygg\nTim Schaub\nChristopher Schmidt\nCameron Shorter                                                              \nPedro Simonetti\nPaul Spencer                                                                 \nPaul Smith                                                                 \nGlen Stampoultzis\nJames Stembridge\nErik Uzureau\nBart van den Eijnden\nIvan Willig\nThomas Wood\nBill Woodall\nSteve Woodbridge\nDavid Zwarg\n\nSome portions of OpenLayers are used under the Apache 2.0 license, available\nin doc/licenses/APACHE-2.0.txt.\n\nSome portions of OpenLayers are used under the MIT license, availabie in \ndoc/licenses/MIT-LICENSE.txt.\n\nSome portions of OpenLayers are Copyright 2001 Robert Penner, and are used \nunder the BSD license, available in doc/licenses/BSD-LICENSE.txt\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/build/README.txt",
    "content": "The OpenLayers build tool supports several different\nforms of compressing your javascript code, and a method\nof describing build profiles to create customized \nOpenLayers builds with only the components you need.\n\nWhen building a file, you can choose to build with several\ndifferent compression options to the Python-based build.py\nscript. The following is an example script:\n\npython build.py -c closure full OpenLayers-closure.js\n\nThis script selects the 'closure' compression mechanism,\nuses a config file called 'full.cfg', and writes the output\nto OpenLayers-closure.js.\n\nThe options available for compression are:\n\n * closure\n   This requires you to have a closure-compiler.jar in your\n   tools directory. You can do this by fetching the compiler\n   from:\n\n     http://closure-compiler.googlecode.com/files/compiler-latest.zip\n\n   Then unzipping that file, and placing compiler.jar into tools\n   and renaming it closure-compiler.jar.\n\n * closure_ws\n   This uses the closure compiler webservice. This will only work\n   for files source Javascript files which are under 1MB. (Note that\n   the default OpenLayers full build is not under 1MB.)\n\n * uglify-js\n   This uses the uglify-js compiler.  You will need the uglifyjs tool\n   in your PATH; this can be installed using npm (the node.js package\n   manager).\n\n * jsmin\n   jsmin is the default compiler, and uses the Python-based\n   jsmin script to compress the Javascript. \n\n * minimize\n   This is a simple whitespace removing Python script, designed\n   to fill in when other tools are unavailable.\n\n * none\n   None will leave the Javascript uncompressed.\n\n\nFor more information on the build script and custom build profiles,\nsee http://docs.openlayers.org/library/deploying.html\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/build/build.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nsys.path.append(\"../tools\")\nimport mergejs\nimport optparse\n\ndef build(config_file = None, output_file = None, options = None):\n    have_compressor = []\n    try:\n        import jsmin\n        have_compressor.append(\"jsmin\")\n    except ImportError:\n        print \"No jsmin\"\n    try:\n        # tools/closure_library_jscompiler.py from: \n        #       http://code.google.com/p/closure-library/source/browse/trunk/closure/bin/build/jscompiler.py\n        import closure_library_jscompiler as closureCompiler\n        have_compressor.append(\"closure\")\n    except Exception, E:\n        print \"No closure (%s)\" % E\n    try:\n        import closure_ws\n        have_compressor.append(\"closure_ws\")\n    except ImportError:\n        print \"No closure_ws\"\n    \n    try:\n        import minimize\n        have_compressor.append(\"minimize\")\n    except ImportError:\n        print \"No minimize\"\n\n    try:\n        import uglify_js\n        uglify_js.check_available()\n        have_compressor.append(\"uglify-js\")\n    except Exception, E:\n        print \"No uglify-js (%s)\" % E\n\n    use_compressor = None\n    if options.compressor and options.compressor in have_compressor:\n        use_compressor = options.compressor\n\n    sourceDirectory = \"../lib\"\n    configFilename = \"full.cfg\"\n    outputFilename = \"OpenLayers.js\"\n\n    if config_file:\n        configFilename = config_file\n        extension = configFilename[-4:]\n\n        if extension  != \".cfg\":\n            configFilename = config_file + \".cfg\"\n\n    if output_file:\n        outputFilename = output_file\n\n    print \"Merging libraries.\"\n    try:\n        if use_compressor == \"closure\" or use_compressor == 'uglify-js':\n            sourceFiles = mergejs.getNames(sourceDirectory, configFilename)\n        else:\n            merged = mergejs.run(sourceDirectory, None, configFilename)\n    except mergejs.MissingImport, E:\n        print \"\\nAbnormal termination.\"\n        sys.exit(\"ERROR: %s\" % E)\n\n    if options.amdname:\n        options.amdname = \"'\" + options.amdname + \"',\"\n    else:\n        options.amdname = \"\"\n        \n    if options.amd == 'pre':\n        print \"\\nAdding AMD function.\"\n        merged = \"define(%sfunction(){%sreturn OpenLayers;});\" % (options.amdname, merged)\n    \n    print \"Compressing using %s\" % use_compressor\n    if use_compressor == \"jsmin\":\n        minimized = jsmin.jsmin(merged)\n    elif use_compressor == \"minimize\":\n        minimized = minimize.minimize(merged)\n    elif use_compressor == \"closure_ws\":\n        if len(merged) > 1000000: # The maximum file size for this web service is 1000 KB.\n            print \"\\nPre-compressing using jsmin\"\n            merged = jsmin.jsmin(merged)\n        print \"\\nIs being compressed using Closure Compiler Service.\"\n        try:\n            minimized = closure_ws.minimize(merged)\n        except Exception, E:\n            print \"\\nAbnormal termination.\"\n            sys.exit(\"ERROR: Closure Compilation using Web service failed!\\n%s\" % E)\n        if len(minimized) <= 2:\n            print \"\\nAbnormal termination due to compilation errors.\"\n            sys.exit(\"ERROR: Closure Compilation using Web service failed!\")\n        else:\n            print \"Closure Compilation using Web service has completed successfully.\"\n    elif use_compressor == \"closure\":\n        jscompilerJar = \"../tools/closure-compiler.jar\"\n        if not os.path.isfile(jscompilerJar):\n            print \"\\nNo closure-compiler.jar; read README.txt!\"\n            sys.exit(\"ERROR: Closure Compiler \\\"%s\\\" does not exist! Read README.txt\" % jscompilerJar)\n        minimized = closureCompiler.Compile(\n            jscompilerJar, \n            sourceFiles, [\n                \"--externs\", \"closure-compiler/Externs.js\",\n                \"--jscomp_warning\", \"checkVars\",   # To enable \"undefinedVars\"\n                \"--jscomp_error\",   \"checkRegExp\", # Also necessary to enable \"undefinedVars\"\n                \"--jscomp_error\",   \"undefinedVars\"\n            ]\n        )\n        if minimized is None:\n            print \"\\nAbnormal termination due to compilation errors.\" \n            sys.exit(\"ERROR: Closure Compilation failed! See compilation errors.\") \n        print \"Closure Compilation has completed successfully.\"\n    elif use_compressor == \"uglify-js\":\n        minimized = uglify_js.compile(sourceFiles)\n        if minimized is None:\n            print \"\\nAbnormal termination due to compilation errors.\"\n            sys.exit(\"ERROR: Uglify JS compilation failed! See compilation errors.\")\n\n        print \"Uglify JS compilation has completed successfully.\"\n\n    else: # fallback\n        minimized = merged \n\n    if options.amd == 'post':\n        print \"\\nAdding AMD function.\"\n        minimized = \"define(%sfunction(){%sreturn OpenLayers;});\" % (options.amdname, minimized)\n    \n    if options.status:\n        print \"\\nAdding status file.\"\n        minimized = \"// status: \" + file(options.status).read() + minimized\n    \n    print \"\\nAdding license file.\"\n    minimized = file(\"license.txt\").read() + minimized\n\n    print \"Writing to %s.\" % outputFilename\n    file(outputFilename, \"w\").write(minimized)\n\n    print \"Done.\"\n\nif __name__ == '__main__':\n  opt = optparse.OptionParser(usage=\"%s [options] [config_file] [output_file]\\n  Default config_file is 'full.cfg', Default output_file is 'OpenLayers.js'\")\n  opt.add_option(\"-c\", \"--compressor\", dest=\"compressor\", help=\"compression method: one of 'jsmin' (default), 'minimize', 'closure_ws', 'closure', 'uglify-js', or 'none'\", default=\"jsmin\")\n  opt.add_option(\"-s\", \"--status\", dest=\"status\", help=\"name of a file whose contents will be added as a comment at the front of the output file. For example, when building from a git repo, you can save the output of 'git describe --tags' in this file. Default is no file.\", default=False)\n  opt.add_option(\"--amd\", dest=\"amd\", help=\"output should be AMD module; wrap merged files in define function; can be either 'pre' (before compilation) or 'post' (after compilation). Wrapping the OpenLayers var in a function means the filesize can be reduced by the closure compiler using 'pre', but be aware that a few functions depend on the OpenLayers variable being present. Either option can be used with jsmin or minimize compression. Default false, not AMD.\", default=False)\n  opt.add_option(\"--amdname\", dest=\"amdname\", help=\"only useful with amd option. Name of AMD module. Default no name, anonymous module.\", default=False)\n  (options, args) = opt.parse_args()\n  if not len(args):\n    build(options=options)\n  elif len(args) == 1:\n    build(args[0], options=options)\n  elif len(args) == 2:\n    build(args[0], args[1], options=options)\n  else:\n    print \"Wrong number of arguments\"\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/build/buildUncompressed.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nsys.path.append(\"../tools\")\n\nimport jsmin, mergejs\n\nsourceDirectory = \"../lib\"\nconfigFilename = \"full.cfg\"\noutputFilename = \"OpenLayers.js\"\n\nif len(sys.argv) > 1:\n    configFilename = sys.argv[1] + \".cfg\"\nif len(sys.argv) > 2:\n    outputFilename = sys.argv[2]\n\nprint \"Merging libraries.\"\nmerged = mergejs.run(sourceDirectory, None, configFilename)\nprint \"Adding license file.\"\nmerged = file(\"license.txt\").read() + merged\n\nprint \"Writing to %s.\" % outputFilename\nfile(outputFilename, \"w\").write(merged)\n\nprint \"Done.\"\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/build/closure-compiler/Externs.js",
    "content": "\n    var frames;\r\n    var console;\r\n    var Proj4js = {Proj: function(){}};\r\n    var JSON = {};\r\n    var GMap2;\r\n    var G_NORMAL_MAP;\r\n    var GEvent;\r\n    var GLatLngBounds = function(){};\r\n    var GSize = function(x, y){};\r\n    var GPoint = function(x, y){};\r\n    var GLatLng = function(lat, lon){};\r\n    var MultimapViewer = function(div){};\r\n    var MMLatLon = function(lat, lon){};\r\n    var MMPoint = function(x, y){};\r\n    var VEMap = function(name){};\r\n    var VEPixel = function(x, y){};\r\n    var VELatLong = function(lat, lon){};\r\n    var Msn = {VE:{}};\r\n    var YMap = function(div, type, size){};\r\n    var YGeoPoint = function(lat, lon){};\r\n    var YCoordPoint = function(x, y){};\r\n    var YSize = function(w, h){};\r\n\r\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/build/full.cfg",
    "content": "# This is the full build with all files: this includes the vector-related files\n# like Renderers and Formats.\n\n[first]\n\n[last]\n\n[include]\n\n[exclude]\nFirebug\nOpenLayers.js\nOpenLayers/Lang\ndeprecated.js\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/build/license.txt",
    "content": "/*\n\n  OpenLayers.js -- OpenLayers Map Viewer Library\n\n  Copyright (c) 2006-2013 by OpenLayers Contributors\n  Published under the 2-clause BSD license.\n  See http://openlayers.org/dev/license.txt for the full text of the license, and http://openlayers.org/dev/authors.txt for full list of contributors.\n\n  Includes compressed code under the following licenses:\n\n  (For uncompressed versions of the code used, please see the\n  OpenLayers Github repository: <https://github.com/openlayers/openlayers>)\n\n*/\n\n/**\n * Contains XMLHttpRequest.js <http://code.google.com/p/xmlhttprequest/>\n * Copyright 2007 Sergey Ilinsky (http://www.ilinsky.com)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n * http://www.apache.org/licenses/LICENSE-2.0\n */\n\n/**\n * OpenLayers.Util.pagePosition is based on Yahoo's getXY method, which is\n * Copyright (c) 2006, Yahoo! Inc.\n * All rights reserved.\n * \n * Redistribution and use of this software in source and binary forms, with or\n * without modification, are permitted provided that the following conditions\n * are met:\n * \n * * Redistributions of source code must retain the above copyright notice,\n *   this list of conditions and the following disclaimer.\n * \n * * Redistributions in binary form must reproduce the above copyright notice,\n *   this list of conditions and the following disclaimer in the documentation\n *   and/or other materials provided with the distribution.\n * \n * * Neither the name of Yahoo! Inc. nor the names of its contributors may be\n *   used to endorse or promote products derived from this software without\n *   specific prior written permission of Yahoo! Inc.\n * \n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\n * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE \n * POSSIBILITY OF SUCH DAMAGE.\n */\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/build/light.cfg",
    "content": "[first]\n\n[last]\n\n[include]\nOpenLayers/Map.js\nOpenLayers/Kinetic.js\nOpenLayers/Projection.js\nOpenLayers/Layer/Vector.js\nOpenLayers/Layer/OSM.js\nOpenLayers/Layer/Bing.js\nOpenLayers/Layer/WMS.js\nOpenLayers/Layer/Google/v3.js\nOpenLayers/Popup/FramedCloud.js\nOpenLayers/Control/Navigation.js\nOpenLayers/Control/Zoom.js\nOpenLayers/Control/Attribution.js\nOpenLayers/Control/SelectFeature.js\nOpenLayers/Control/Panel.js\nOpenLayers/Control/LayerSwitcher.js\nOpenLayers/Renderer/SVG.js\nOpenLayers/Renderer/VML.js\nOpenLayers/Format/GeoJSON.js\nOpenLayers/Protocol/HTTP.js\nOpenLayers/Strategy/Fixed.js\nOpenLayers/Strategy/BBOX.js\nOpenLayers/StyleMap.js\nOpenLayers/Rule.js\nOpenLayers/Filter/Comparison.js\nOpenLayers/Filter/Logical.js\n\n[exclude]\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/build/lite.cfg",
    "content": "# This file includes a small subset of OpenLayers code, designed to be\n# integrated into another application. It includes only the Layer types\n# necessary to create tiled or untiled WMS, and does not include any Controls.\n# This is the result of what was at the time called \"Webmap.js\" at the FOSS4G\n# Web Mapping BOF.\n\n[first]\n\n[last]\n\n[include]\nOpenLayers/Map.js\nOpenLayers/Layer/WMS.js\n\n[exclude]\n\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/build/mobile.cfg",
    "content": "[first]\n\n[last]\n\n[include]\nOpenLayers/Map.js\nOpenLayers/Kinetic.js\nOpenLayers/Projection.js\nOpenLayers/Layer/OSM.js\nOpenLayers/Layer/Bing.js\nOpenLayers/Layer/WMS.js\nOpenLayers/Control/TouchNavigation.js\nOpenLayers/Control/Geolocate.js\nOpenLayers/Control/Zoom.js\nOpenLayers/Control/Attribution.js\nOpenLayers/Control/SelectFeature.js\nOpenLayers/Control/DrawFeature.js\nOpenLayers/Control/ModifyFeature.js\nOpenLayers/Control/Panel.js\nOpenLayers/Handler/Point.js\nOpenLayers/Handler/Path.js\nOpenLayers/Handler/Polygon.js\nOpenLayers/Layer/Vector.js\nOpenLayers/Renderer/SVG.js\nOpenLayers/Renderer/Canvas.js\nOpenLayers/Format/GeoJSON.js\nOpenLayers/Format/KML.js\nOpenLayers/Protocol/HTTP.js\nOpenLayers/Protocol/WFS.js\nOpenLayers/Protocol/WFS/v1_0_0.js\nOpenLayers/Strategy/Fixed.js\nOpenLayers/TileManager.js\n\n[exclude]\n\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/build/tests.cfg",
    "content": "# This build config is supposed to be used for the units tests with \"mode=build\"\n\n[first]\n\n[last]\n\n[include]\n\n[exclude]\nFirebug\nOpenLayers.js\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/doc_config/Languages.txt",
    "content": "Format: 1.52\n\n# This is the Natural Docs languages file for this project.  If you change\n# anything here, it will apply to THIS PROJECT ONLY.  If you'd like to change\n# something for all your projects, edit the Languages.txt in Natural Docs'\n# Config directory instead.\n\n\n# You can prevent certain file extensions from being scanned like this:\n# Ignore Extensions: [extension] [extension] ...\n\n\n#-------------------------------------------------------------------------------\n# SYNTAX:\n#\n# Unlike other Natural Docs configuration files, in this file all comments\n# MUST be alone on a line.  Some languages deal with the # character, so you\n# cannot put comments on the same line as content.\n#\n# Also, all lists are separated with spaces, not commas, again because some\n# languages may need to use them.\n#\n# Language: [name]\n# Alter Language: [name]\n#    Defines a new language or alters an existing one.  Its name can use any\n#    characters.  If any of the properties below have an add/replace form, you\n#    must use that when using Alter Language.\n#\n#    The language Shebang Script is special.  It's entry is only used for\n#    extensions, and files with those extensions have their shebang (#!) lines\n#    read to determine the real language of the file.  Extensionless files are\n#    always treated this way.\n#\n#    The language Text File is also special.  It's treated as one big comment\n#    so you can put Natural Docs content in them without special symbols.  Also,\n#    if you don't specify a package separator, ignored prefixes, or enum value\n#    behavior, it will copy those settings from the language that is used most\n#    in the source tree.\n#\n# Extensions: [extension] [extension] ...\n# [Add/Replace] Extensions: [extension] [extension] ...\n#    Defines the file extensions of the language's source files.  You can\n#    redefine extensions found in the main languages file.  You can use * to\n#    mean any undefined extension.\n#\n# Shebang Strings: [string] [string] ...\n# [Add/Replace] Shebang Strings: [string] [string] ...\n#    Defines a list of strings that can appear in the shebang (#!) line to\n#    designate that it's part of the language.  You can redefine strings found\n#    in the main languages file.\n#\n# Ignore Prefixes in Index: [prefix] [prefix] ...\n# [Add/Replace] Ignored Prefixes in Index: [prefix] [prefix] ...\n#\n# Ignore [Topic Type] Prefixes in Index: [prefix] [prefix] ...\n# [Add/Replace] Ignored [Topic Type] Prefixes in Index: [prefix] [prefix] ...\n#    Specifies prefixes that should be ignored when sorting symbols in an\n#    index.  Can be specified in general or for a specific topic type.\n#\n#------------------------------------------------------------------------------\n# For basic language support only:\n#\n# Line Comments: [symbol] [symbol] ...\n#    Defines a space-separated list of symbols that are used for line comments,\n#    if any.\n#\n# Block Comments: [opening sym] [closing sym] [opening sym] [closing sym] ...\n#    Defines a space-separated list of symbol pairs that are used for block\n#    comments, if any.\n#\n# Package Separator: [symbol]\n#    Defines the default package separator symbol.  The default is a dot.\n#\n# [Topic Type] Prototype Enders: [symbol] [symbol] ...\n#    When defined, Natural Docs will attempt to get a prototype from the code\n#    immediately following the topic type.  It stops when it reaches one of\n#    these symbols.  Use \\n for line breaks.\n#\n# Line Extender: [symbol]\n#    Defines the symbol that allows a prototype to span multiple lines if\n#    normally a line break would end it.\n#\n# Enum Values: [global|under type|under parent]\n#    Defines how enum values are referenced.  The default is global.\n#    global       - Values are always global, referenced as 'value'.\n#    under type   - Values are under the enum type, referenced as\n#               'package.enum.value'.\n#    under parent - Values are under the enum's parent, referenced as\n#               'package.value'.\n#\n# Perl Package: [perl package]\n#    Specifies the Perl package used to fine-tune the language behavior in ways\n#    too complex to do in this file.\n#\n#------------------------------------------------------------------------------\n# For full language support only:\n#\n# Full Language Support: [perl package]\n#    Specifies the Perl package that has the parsing routines necessary for full\n#    language support.\n#\n#-------------------------------------------------------------------------------\n\n# The following languages are defined in the main file, if you'd like to alter\n# them:\n#\n#    Text File, Shebang Script, C/C++, C#, Java, JavaScript, Perl, Python,\n#    PHP, SQL, Visual Basic, Pascal, Assembly, Ada, Tcl, Ruby, Makefile,\n#    ActionScript, ColdFusion, R, Fortran\n\n# If you add a language that you think would be useful to other developers\n# and should be included in Natural Docs by default, please e-mail it to\n# languages [at] naturaldocs [dot] org.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/doc_config/Menu.txt",
    "content": "Format: 1.52\n\n\nTitle: OpenLayers\nSubTitle: JavaScript Mapping Library\n\n# You can add a footer to your documentation like this:\n# Footer: [text]\n# If you want to add a copyright notice, this would be the place to do it.\n\n# You can add a timestamp to your documentation like one of these:\n# Timestamp: Generated on month day, year\n# Timestamp: Updated mm/dd/yyyy\n# Timestamp: Last updated mon day\n#\n#   m     - One or two digit month.  January is \"1\"\n#   mm    - Always two digit month.  January is \"01\"\n#   mon   - Short month word.  January is \"Jan\"\n#   month - Long month word.  January is \"January\"\n#   d     - One or two digit day.  1 is \"1\"\n#   dd    - Always two digit day.  1 is \"01\"\n#   day   - Day with letter extension.  1 is \"1st\"\n#   yy    - Two digit year.  2006 is \"06\"\n#   yyyy  - Four digit year.  2006 is \"2006\"\n#   year  - Four digit year.  2006 is \"2006\"\n\n\n# --------------------------------------------------------------------------\n# \n# Cut and paste the lines below to change the order in which your files\n# appear on the menu.  Don't worry about adding or removing files, Natural\n# Docs will take care of that.\n# \n# You can further organize the menu by grouping the entries.  Add a\n# \"Group: [name] {\" line to start a group, and add a \"}\" to end it.\n# \n# You can add text and web links to the menu by adding \"Text: [text]\" and\n# \"Link: [name] ([URL])\" lines, respectively.\n# \n# The formatting and comments are auto-generated, so don't worry about\n# neatness when editing the file.  Natural Docs will clean it up the next\n# time it is run.  When working with groups, just deal with the braces and\n# forget about the indentation and comments.\n# \n# --------------------------------------------------------------------------\n\n\nGroup: OpenLayers  {\n\n   File: OpenLayers  (no auto-title, OpenLayers.js)\n\n   Group: BaseTypes  {\n\n      File: Base Types  (no auto-title, OpenLayers/BaseTypes.js)\n      File: Bounds  (no auto-title, OpenLayers/BaseTypes/Bounds.js)\n      File: Class  (no auto-title, OpenLayers/BaseTypes/Class.js)\n      File: Date  (no auto-title, OpenLayers/BaseTypes/Date.js)\n      File: Element  (no auto-title, OpenLayers/BaseTypes/Element.js)\n      File: LonLat  (no auto-title, OpenLayers/BaseTypes/LonLat.js)\n      File: Pixel  (no auto-title, OpenLayers/BaseTypes/Pixel.js)\n      File: Size  (no auto-title, OpenLayers/BaseTypes/Size.js)\n      }  # Group: BaseTypes\n\n   Group: Control  {\n\n      File: Control  (no auto-title, OpenLayers/Control.js)\n\n      Group: Control  {\n\n         File: ArgParser  (no auto-title, OpenLayers/Control/ArgParser.js)\n         File: Attribution  (no auto-title, OpenLayers/Control/Attribution.js)\n         File: Button  (no auto-title, OpenLayers/Control/Button.js)\n         File: CacheRead  (OpenLayers/Control/CacheRead.js)\n         File: CacheWrite  (OpenLayers/Control/CacheWrite.js)\n         File: DragFeature  (no auto-title, OpenLayers/Control/DragFeature.js)\n         File: DragPan  (no auto-title, OpenLayers/Control/DragPan.js)\n         File: DrawFeature  (no auto-title, OpenLayers/Control/DrawFeature.js)\n         File: EditingToolbar  (no auto-title, OpenLayers/Control/EditingToolbar.js)\n         File: Geolocate  (no auto-title, OpenLayers/Control/Geolocate.js)\n         File: GetFeature  (no auto-title, OpenLayers/Control/GetFeature.js)\n         File: Graticule  (no auto-title, OpenLayers/Control/Graticule.js)\n         File: KeyboardDefaults  (no auto-title, OpenLayers/Control/KeyboardDefaults.js)\n         File: LayerSwitcher  (no auto-title, OpenLayers/Control/LayerSwitcher.js)\n         File: Measure  (no auto-title, OpenLayers/Control/Measure.js)\n         File: ModifyFeature  (no auto-title, OpenLayers/Control/ModifyFeature.js)\n         File: ModifyFeature.BySegment  (OpenLayers/Control/ModifyFeature/BySegment.js)\n         File: MousePosition  (no auto-title, OpenLayers/Control/MousePosition.js)\n         File: Navigation  (no auto-title, OpenLayers/Control/Navigation.js)\n         File: NavigationHistory  (no auto-title, OpenLayers/Control/NavigationHistory.js)\n         File: NavToolbar  (no auto-title, OpenLayers/Control/NavToolbar.js)\n         File: OverviewMap  (no auto-title, OpenLayers/Control/OverviewMap.js)\n         File: Pan  (no auto-title, OpenLayers/Control/Pan.js)\n         File: Panel  (no auto-title, OpenLayers/Control/Panel.js)\n         File: PanPanel  (no auto-title, OpenLayers/Control/PanPanel.js)\n         File: PanZoom  (no auto-title, OpenLayers/Control/PanZoom.js)\n         File: PanZoomBar  (no auto-title, OpenLayers/Control/PanZoomBar.js)\n         File: Permalink  (no auto-title, OpenLayers/Control/Permalink.js)\n         File: PinchZoom  (no auto-title, OpenLayers/Control/PinchZoom.js)\n         File: Scale  (no auto-title, OpenLayers/Control/Scale.js)\n         File: ScaleLine  (no auto-title, OpenLayers/Control/ScaleLine.js)\n         File: SelectFeature  (no auto-title, OpenLayers/Control/SelectFeature.js)\n         File: SLDSelect  (no auto-title, OpenLayers/Control/SLDSelect.js)\n         File: Snapping  (no auto-title, OpenLayers/Control/Snapping.js)\n         File: Split  (no auto-title, OpenLayers/Control/Split.js)\n         File: TextButtonPanel  (OpenLayers/Control/TextButtonPanel.js)\n         File: TouchNavigation  (no auto-title, OpenLayers/Control/TouchNavigation.js)\n         File: TransformFeature  (no auto-title, OpenLayers/Control/TransformFeature.js)\n         File: UTFGrid  (OpenLayers/Control/UTFGrid.js)\n         File: WMSGetFeatureInfo  (no auto-title, OpenLayers/Control/WMSGetFeatureInfo.js)\n         File: WMTSGetFeatureInfo  (no auto-title, OpenLayers/Control/WMTSGetFeatureInfo.js)\n         File: Zoom  (OpenLayers/Control/Zoom.js)\n         File: ZoomBox  (no auto-title, OpenLayers/Control/ZoomBox.js)\n         File: ZoomIn  (no auto-title, OpenLayers/Control/ZoomIn.js)\n         File: ZoomOut  (no auto-title, OpenLayers/Control/ZoomOut.js)\n         File: ZoomPanel  (no auto-title, OpenLayers/Control/ZoomPanel.js)\n         File: ZoomToMaxExtent  (no auto-title, OpenLayers/Control/ZoomToMaxExtent.js)\n         }  # Group: Control\n\n      }  # Group: Control\n\n   Group: Feature  {\n\n      File: Feature  (no auto-title, OpenLayers/Feature.js)\n      File: Vector  (no auto-title, OpenLayers/Feature/Vector.js)\n      }  # Group: Feature\n\n   Group: Filter  {\n\n      File: Filter  (no auto-title, OpenLayers/Filter.js)\n      File: Comparison  (no auto-title, OpenLayers/Filter/Comparison.js)\n      File: FeatureId  (no auto-title, OpenLayers/Filter/FeatureId.js)\n      File: Function  (no auto-title, OpenLayers/Filter/Function.js)\n      File: Logical  (no auto-title, OpenLayers/Filter/Logical.js)\n      File: Spatial  (no auto-title, OpenLayers/Filter/Spatial.js)\n      }  # Group: Filter\n\n   Group: Format  {\n\n      File: Format  (no auto-title, OpenLayers/Format.js)\n\n      Group: Filter  {\n\n         File: Filter  (no auto-title, OpenLayers/Format/Filter.js)\n         File: v1  (no auto-title, OpenLayers/Format/Filter/v1.js)\n         File: v1_0_0  (no auto-title, OpenLayers/Format/Filter/v1_0_0.js)\n         File: v1_1_0  (no auto-title, OpenLayers/Format/Filter/v1_1_0.js)\n         File: v2  (OpenLayers/Format/Filter/v2.js)\n         File: v2_0_0  (OpenLayers/Format/Filter/v2_0_0.js)\n         }  # Group: Filter\n\n      Group: GML  {\n\n         File: GML  (no auto-title, OpenLayers/Format/GML.js)\n         File: Base  (no auto-title, OpenLayers/Format/GML/Base.js)\n         File: v2  (no auto-title, OpenLayers/Format/GML/v2.js)\n         File: v3  (no auto-title, OpenLayers/Format/GML/v3.js)\n         }  # Group: GML\n\n      Group: SLD  {\n\n         File: SLD  (no auto-title, OpenLayers/Format/SLD.js)\n         File: SLD/v1_0_0_GeoServer  (OpenLayers/Format/SLD/v1_0_0_GeoServer.js)\n         File: v1  (no auto-title, OpenLayers/Format/SLD/v1.js)\n         File: v1_0_0  (no auto-title, OpenLayers/Format/SLD/v1_0_0.js)\n         }  # Group: SLD\n\n      Group: OWSCommon  {\n\n         File: OWSCommon  (no auto-title, OpenLayers/Format/OWSCommon.js)\n         File: v1  (no auto-title, OpenLayers/Format/OWSCommon/v1.js)\n         File: v1_0_0  (no auto-title, OpenLayers/Format/OWSCommon/v1_0_0.js)\n         File: v1_1_0  (no auto-title, OpenLayers/Format/OWSCommon/v1_1_0.js)\n         }  # Group: OWSCommon\n\n      Group: WFSCapabilities  {\n\n         File: WFSCapabilities  (no auto-title, OpenLayers/Format/WFSCapabilities.js)\n         File: v1  (no auto-title, OpenLayers/Format/WFSCapabilities/v1.js)\n         File: v1_0_0  (no auto-title, OpenLayers/Format/WFSCapabilities/v1_0_0.js)\n         File: v1_1_0  (no auto-title, OpenLayers/Format/WFSCapabilities/v1_1_0.js)\n         File: v2_0_0  (OpenLayers/Format/WFSCapabilities/v2_0_0.js)\n         }  # Group: WFSCapabilities\n\n      Group: WFST  {\n\n         File: WFST  (no auto-title, OpenLayers/Format/WFST.js)\n         File: v1  (no auto-title, OpenLayers/Format/WFST/v1.js)\n         File: v1_0_0  (no auto-title, OpenLayers/Format/WFST/v1_0_0.js)\n         File: v1_1_0  (no auto-title, OpenLayers/Format/WFST/v1_1_0.js)\n         File: v2_0_0  (OpenLayers/Format/WFST/v2_0_0.js)\n         }  # Group: WFST\n\n      Group: WMC  {\n\n         File: WMC  (no auto-title, OpenLayers/Format/WMC.js)\n         File: v1  (no auto-title, OpenLayers/Format/WMC/v1.js)\n         File: v1_0_0  (no auto-title, OpenLayers/Format/WMC/v1_0_0.js)\n         File: v1_1_0  (no auto-title, OpenLayers/Format/WMC/v1_1_0.js)\n         }  # Group: WMC\n\n      Group: WMSCapabilities  {\n\n         File: WMSCapabilities  (no auto-title, OpenLayers/Format/WMSCapabilities.js)\n         File: v1  (no auto-title, OpenLayers/Format/WMSCapabilities/v1.js)\n         File: v1_1  (no auto-title, OpenLayers/Format/WMSCapabilities/v1_1.js)\n         File: v1_1_0  (no auto-title, OpenLayers/Format/WMSCapabilities/v1_1_0.js)\n         File: v1_1_1  (no auto-title, OpenLayers/Format/WMSCapabilities/v1_1_1.js)\n         File: v1_3  (no auto-title, OpenLayers/Format/WMSCapabilities/v1_3.js)\n         File: v1_3_0  (no auto-title, OpenLayers/Format/WMSCapabilities/v1_3_0.js)\n         File: WMSCapabilities/v1_1_1_WMSC  (no auto-title, OpenLayers/Format/WMSCapabilities/v1_1_1_WMSC.js)\n         }  # Group: WMSCapabilities\n\n      Group: WMSDescribeLayer  {\n\n         File: WMSDescribeLayer  (no auto-title, OpenLayers/Format/WMSDescribeLayer.js)\n         File: v1_1  (no auto-title, OpenLayers/Format/WMSDescribeLayer/v1_1.js)\n         }  # Group: WMSDescribeLayer\n\n      Group: Format  {\n\n         File: ArcXML  (no auto-title, OpenLayers/Format/ArcXML.js)\n         File: ArcXML.Features  (no auto-title, OpenLayers/Format/ArcXML/Features.js)\n         File: Atom  (no auto-title, OpenLayers/Format/Atom.js)\n         File: Context  (no auto-title, OpenLayers/Format/Context.js)\n         File: CQL  (no auto-title, OpenLayers/Format/CQL.js)\n         File: CSWGetDomain  (no auto-title, OpenLayers/Format/CSWGetDomain.js)\n         File: CSWGetDomain.v2_0_2  (no auto-title, OpenLayers/Format/CSWGetDomain/v2_0_2.js)\n         File: CSWGetRecords  (no auto-title, OpenLayers/Format/CSWGetRecords.js)\n         File: CSWGetRecords.v2_0_2  (no auto-title, OpenLayers/Format/CSWGetRecords/v2_0_2.js)\n         File: EncodedPolyline  (OpenLayers/Format/EncodedPolyline.js)\n         File: GeoJSON  (no auto-title, OpenLayers/Format/GeoJSON.js)\n         File: GeoRSS  (no auto-title, OpenLayers/Format/GeoRSS.js)\n         File: GPX  (no auto-title, OpenLayers/Format/GPX.js)\n         File: JSON  (no auto-title, OpenLayers/Format/JSON.js)\n         File: KML  (no auto-title, OpenLayers/Format/KML.js)\n         File: OGCExceptionReport  (no auto-title, OpenLayers/Format/OGCExceptionReport.js)\n         File: OSM  (no auto-title, OpenLayers/Format/OSM.js)\n         File: OWSContext  (no auto-title, OpenLayers/Format/OWSContext.js)\n         File: OWSContext.v0_3_1  (no auto-title, OpenLayers/Format/OWSContext/v0_3_1.js)\n         File: QueryStringFilter  (no auto-title, OpenLayers/Format/QueryStringFilter.js)\n         File: SOSCapabilities  (no auto-title, OpenLayers/Format/SOSCapabilities.js)\n         File: SOSCapabilities.v1_0_0  (no auto-title, OpenLayers/Format/SOSCapabilities/v1_0_0.js)\n         File: SOSGetFeatureOfInterest  (no auto-title, OpenLayers/Format/SOSGetFeatureOfInterest.js)\n         File: SOSGetObservation  (no auto-title, OpenLayers/Format/SOSGetObservation.js)\n         File: Text  (no auto-title, OpenLayers/Format/Text.js)\n         File: TMSCapabilities  (OpenLayers/Format/TMSCapabilities.js)\n         File: WCSCapabilities  (OpenLayers/Format/WCSCapabilities.js)\n\n         Group: WCSCapabilities  {\n\n            File: WCSCapabilities.v1  (OpenLayers/Format/WCSCapabilities/v1.js)\n            File: WCSCapabilities/v1_0_0  (OpenLayers/Format/WCSCapabilities/v1_0_0.js)\n            File: WCSCapabilities/v1_1_0  (OpenLayers/Format/WCSCapabilities/v1_1_0.js)\n            }  # Group: WCSCapabilities\n\n         File: WCSDescribeCoverage  (OpenLayers/Format/WCSDescribeCoverage.js)\n\n         Group: WCSDescribeCoverage  {\n\n            File: WCSDescribeCoverage.v1  (OpenLayers/Format/WCSDescribeCoverage/v1.js)\n            File: WCSDescribeCoverage/v1_0_0  (OpenLayers/Format/WCSDescribeCoverage/v1_0_0.js)\n            File: WCSDescribeCoverage/v1_1_0  (OpenLayers/Format/WCSDescribeCoverage/v1_1_0.js)\n            }  # Group: WCSDescribeCoverage\n\n         File: WCSGetCoverage version 1.1.0  (no auto-title, OpenLayers/Format/WCSGetCoverage.js)\n         File: WFS  (no auto-title, OpenLayers/Format/WFS.js)\n         File: WFSDescribeFeatureType  (no auto-title, OpenLayers/Format/WFSDescribeFeatureType.js)\n         File: WKT  (no auto-title, OpenLayers/Format/WKT.js)\n         File: WMSGetFeatureInfo  (no auto-title, OpenLayers/Format/WMSGetFeatureInfo.js)\n         File: WMTSCapabilities  (no auto-title, OpenLayers/Format/WMTSCapabilities.js)\n         File: WMTSCapabilities.v1_0_0  (no auto-title, OpenLayers/Format/WMTSCapabilities/v1_0_0.js)\n         File: WPSCapabilities  (no auto-title, OpenLayers/Format/WPSCapabilities.js)\n         File: WPSCapabilities.v1_0_0  (no auto-title, OpenLayers/Format/WPSCapabilities/v1_0_0.js)\n         File: WPSDescribeProcess  (no auto-title, OpenLayers/Format/WPSDescribeProcess.js)\n         File: WPSExecute version 1.0.0  (no auto-title, OpenLayers/Format/WPSExecute.js)\n         File: XLS  (no auto-title, OpenLayers/Format/XLS.js)\n         File: XLS.v1  (no auto-title, OpenLayers/Format/XLS/v1.js)\n         File: XLS.v1_1_0  (no auto-title, OpenLayers/Format/XLS/v1_1_0.js)\n         File: XML  (no auto-title, OpenLayers/Format/XML.js)\n         File: XML.VersionedOGC  (OpenLayers/Format/XML/VersionedOGC.js)\n         }  # Group: Format\n\n      }  # Group: Format\n\n   Group: Geometry  {\n\n      File: Geometry  (no auto-title, OpenLayers/Geometry.js)\n      File: Collection  (no auto-title, OpenLayers/Geometry/Collection.js)\n      File: Curve  (no auto-title, OpenLayers/Geometry/Curve.js)\n      File: LinearRing  (no auto-title, OpenLayers/Geometry/LinearRing.js)\n      File: LineString  (no auto-title, OpenLayers/Geometry/LineString.js)\n      File: MultiLineString  (no auto-title, OpenLayers/Geometry/MultiLineString.js)\n      File: MultiPoint  (no auto-title, OpenLayers/Geometry/MultiPoint.js)\n      File: MultiPolygon  (no auto-title, OpenLayers/Geometry/MultiPolygon.js)\n      File: Point  (no auto-title, OpenLayers/Geometry/Point.js)\n      File: Polygon  (no auto-title, OpenLayers/Geometry/Polygon.js)\n      }  # Group: Geometry\n\n   Group: Handler  {\n\n      File: Handler  (no auto-title, OpenLayers/Handler.js)\n      File: Box  (no auto-title, OpenLayers/Handler/Box.js)\n      File: Click  (no auto-title, OpenLayers/Handler/Click.js)\n      File: Drag  (no auto-title, OpenLayers/Handler/Drag.js)\n      File: Feature  (no auto-title, OpenLayers/Handler/Feature.js)\n      File: Hover  (no auto-title, OpenLayers/Handler/Hover.js)\n      File: Keyboard  (no auto-title, OpenLayers/Handler/Keyboard.js)\n      File: MouseWheel  (no auto-title, OpenLayers/Handler/MouseWheel.js)\n      File: Path  (no auto-title, OpenLayers/Handler/Path.js)\n      File: Pinch  (no auto-title, OpenLayers/Handler/Pinch.js)\n      File: Point  (no auto-title, OpenLayers/Handler/Point.js)\n      File: Polygon  (no auto-title, OpenLayers/Handler/Polygon.js)\n      File: RegularPolygon  (no auto-title, OpenLayers/Handler/RegularPolygon.js)\n      }  # Group: Handler\n\n   Group: Lang  {\n\n      File: Lang  (no auto-title, OpenLayers/Lang.js)\n\n      Group: Lang  {\n\n         File: ar  (no auto-title, OpenLayers/Lang/ar.js)\n         File: be-tarask  (no auto-title, OpenLayers/Lang/be-tarask.js)\n         File: bg  (no auto-title, OpenLayers/Lang/bg.js)\n         File: br  (no auto-title, OpenLayers/Lang/br.js)\n         File: ca  (no auto-title, OpenLayers/Lang/ca.js)\n         File: cs-CZ  (no auto-title, OpenLayers/Lang/cs-CZ.js)\n         File: da-DK  (no auto-title, OpenLayers/Lang/da-DK.js)\n         File: de  (no auto-title, OpenLayers/Lang/de.js)\n         File: en  (no auto-title, OpenLayers/Lang/en.js)\n         File: en-CA  (no auto-title, OpenLayers/Lang/en-CA.js)\n         File: es  (no auto-title, OpenLayers/Lang/es.js)\n         File: el  (no auto-title, OpenLayers/Lang/el.js)\n         File: fi  (no auto-title, OpenLayers/Lang/fi.js)\n         File: fr  (no auto-title, OpenLayers/Lang/fr.js)\n         File: fur  (no auto-title, OpenLayers/Lang/fur.js)\n         File: gl  (no auto-title, OpenLayers/Lang/gl.js)\n         File: gsw  (no auto-title, OpenLayers/Lang/gsw.js)\n         File: hr  (no auto-title, OpenLayers/Lang/hr.js)\n         File: hsb  (no auto-title, OpenLayers/Lang/hsb.js)\n         File: hu  (no auto-title, OpenLayers/Lang/hu.js)\n         File: ia  (no auto-title, OpenLayers/Lang/ia.js)\n         File: id  (no auto-title, OpenLayers/Lang/id.js)\n         File: io  (no auto-title, OpenLayers/Lang/io.js)\n         File: is  (no auto-title, OpenLayers/Lang/is.js)\n         File: it  (no auto-title, OpenLayers/Lang/it.js)\n         File: ja  (no auto-title, OpenLayers/Lang/ja.js)\n         File: km  (no auto-title, OpenLayers/Lang/km.js)\n         File: ksh  (no auto-title, OpenLayers/Lang/ksh.js)\n         File: lt  (no auto-title, OpenLayers/Lang/lt.js)\n         File: nds  (no auto-title, OpenLayers/Lang/nds.js)\n         File: nb  (no auto-title, OpenLayers/Lang/nb.js)\n         File: nl  (no auto-title, OpenLayers/Lang/nl.js)\n         File: nn  (no auto-title, OpenLayers/Lang/nn.js)\n         File: oc  (no auto-title, OpenLayers/Lang/oc.js)\n         File: pl  (no auto-title, OpenLayers/Lang/pl.js)\n         File: pt  (no auto-title, OpenLayers/Lang/pt.js)\n         File: pt-BR  (no auto-title, OpenLayers/Lang/pt-BR.js)\n         File: ru  (no auto-title, OpenLayers/Lang/ru.js)\n         File: sk  (no auto-title, OpenLayers/Lang/sk.js)\n         File: sv-SE  (no auto-title, OpenLayers/Lang/sv-SE.js)\n         File: te  (no auto-title, OpenLayers/Lang/te.js)\n         File: vi  (no auto-title, OpenLayers/Lang/vi.js)\n         File: zh-CN  (no auto-title, OpenLayers/Lang/zh-CN.js)\n         File: zh-TW  (no auto-title, OpenLayers/Lang/zh-TW.js)\n         File: Lang[\"ro\"]  (OpenLayers/Lang/ro.js)\n         }  # Group: Lang\n\n      }  # Group: Lang\n\n   Group: Layer  {\n\n      File: Layer  (no auto-title, OpenLayers/Layer.js)\n\n      Group: Layer  {\n\n         File: ArcGISCache.js  (no auto-title, OpenLayers/Layer/ArcGISCache.js)\n         File: ArcGIS93Rest  (no auto-title, OpenLayers/Layer/ArcGIS93Rest.js)\n         File: ArcIMS  (no auto-title, OpenLayers/Layer/ArcIMS.js)\n         File: Bing  (no auto-title, OpenLayers/Layer/Bing.js)\n         File: Boxes  (no auto-title, OpenLayers/Layer/Boxes.js)\n         File: EventPane  (no auto-title, OpenLayers/Layer/EventPane.js)\n         File: FixedZoomLevels  (no auto-title, OpenLayers/Layer/FixedZoomLevels.js)\n         File: GeoRSS  (no auto-title, OpenLayers/Layer/GeoRSS.js)\n         File: Google  (no auto-title, OpenLayers/Layer/Google.js)\n         File: Google.v3  (no auto-title, OpenLayers/Layer/Google/v3.js)\n         File: Grid  (no auto-title, OpenLayers/Layer/Grid.js)\n         File: HTTPRequest  (no auto-title, OpenLayers/Layer/HTTPRequest.js)\n         File: Image  (no auto-title, OpenLayers/Layer/Image.js)\n         File: KaMap  (no auto-title, OpenLayers/Layer/KaMap.js)\n         File: KaMapCache  (no auto-title, OpenLayers/Layer/KaMapCache.js)\n         File: MapGuide  (no auto-title, OpenLayers/Layer/MapGuide.js)\n         File: MapServer  (no auto-title, OpenLayers/Layer/MapServer.js)\n         File: Markers  (no auto-title, OpenLayers/Layer/Markers.js)\n         File: PointGrid  (no auto-title, OpenLayers/Layer/PointGrid.js)\n         File: PointTrack  (no auto-title, OpenLayers/Layer/PointTrack.js)\n         File: SphericalMercator  (no auto-title, OpenLayers/Layer/SphericalMercator.js)\n         File: Text  (no auto-title, OpenLayers/Layer/Text.js)\n         File: TileCache  (no auto-title, OpenLayers/Layer/TileCache.js)\n         File: TMS  (no auto-title, OpenLayers/Layer/TMS.js)\n         File: Vector  (no auto-title, OpenLayers/Layer/Vector.js)\n         File: Vector.RootContainer  (no auto-title, OpenLayers/Layer/Vector/RootContainer.js)\n         File: WMS  (no auto-title, OpenLayers/Layer/WMS.js)\n         File: WMTS  (no auto-title, OpenLayers/Layer/WMTS.js)\n         File: WorldWind  (no auto-title, OpenLayers/Layer/WorldWind.js)\n         File: XYZ  (no auto-title, OpenLayers/Layer/XYZ.js)\n         File: Zoomify  (no auto-title, OpenLayers/Layer/Zoomify.js)\n         File: OSM  (OpenLayers/Layer/OSM.js)\n         File: UTFGrid  (OpenLayers/Layer/UTFGrid.js)\n         }  # Group: Layer\n\n      }  # Group: Layer\n\n   Group: Marker  {\n\n      File: Marker  (no auto-title, OpenLayers/Marker.js)\n      File: Box  (no auto-title, OpenLayers/Marker/Box.js)\n      }  # Group: Marker\n\n   Group: Popup  {\n\n      File: Popup  (no auto-title, OpenLayers/Popup.js)\n      File: Anchored  (no auto-title, OpenLayers/Popup/Anchored.js)\n      File: Framed  (no auto-title, OpenLayers/Popup/Framed.js)\n      File: FramedCloud  (no auto-title, OpenLayers/Popup/FramedCloud.js)\n      }  # Group: Popup\n\n   Group: Protocol  {\n\n      File: Protocol  (no auto-title, OpenLayers/Protocol.js)\n\n      Group: Protocol  {\n\n         File: CSW  (OpenLayers/Protocol/CSW.js)\n         File: CSW.v2_0_2  (OpenLayers/Protocol/CSW/v2_0_2.js)\n         File: HTTP  (no auto-title, OpenLayers/Protocol/HTTP.js)\n         File: Script  (no auto-title, OpenLayers/Protocol/Script.js)\n         File: SOS.DEFAULTS  (no auto-title, OpenLayers/Protocol/SOS.js)\n         File: SOS.v1_0_0  (no auto-title, OpenLayers/Protocol/SOS/v1_0_0.js)\n         }  # Group: Protocol\n\n      Group: WFS  {\n\n         File: WFS  (no auto-title, OpenLayers/Protocol/WFS.js)\n         File: v1  (no auto-title, OpenLayers/Protocol/WFS/v1.js)\n         File: v1_0_0  (no auto-title, OpenLayers/Protocol/WFS/v1_0_0.js)\n         File: v1_1_0  (no auto-title, OpenLayers/Protocol/WFS/v1_1_0.js)\n         File: v2_0_0  (OpenLayers/Protocol/WFS/v2_0_0.js)\n         }  # Group: WFS\n\n      }  # Group: Protocol\n\n   Group: Renderer  {\n\n      File: Renderer  (no auto-title, OpenLayers/Renderer.js)\n      File: Canvas  (no auto-title, OpenLayers/Renderer/Canvas.js)\n      File: ElementsIndexer  (no auto-title, OpenLayers/Renderer/Elements.js)\n      File: SVG  (no auto-title, OpenLayers/Renderer/SVG.js)\n      File: VML  (no auto-title, OpenLayers/Renderer/VML.js)\n      }  # Group: Renderer\n\n   Group: Request  {\n\n      File: Request  (no auto-title, OpenLayers/Request.js)\n      File: XMLHttpRequest  (no auto-title, OpenLayers/Request/XMLHttpRequest.js)\n      }  # Group: Request\n\n   Group: Strategy  {\n\n      File: Strategy  (no auto-title, OpenLayers/Strategy.js)\n      File: BBOX  (no auto-title, OpenLayers/Strategy/BBOX.js)\n      File: Cluster  (no auto-title, OpenLayers/Strategy/Cluster.js)\n      File: Filter  (no auto-title, OpenLayers/Strategy/Filter.js)\n      File: Fixed  (no auto-title, OpenLayers/Strategy/Fixed.js)\n      File: Paging  (no auto-title, OpenLayers/Strategy/Paging.js)\n      File: Refresh  (no auto-title, OpenLayers/Strategy/Refresh.js)\n      File: Save  (no auto-title, OpenLayers/Strategy/Save.js)\n      }  # Group: Strategy\n\n   Group: Symbolizer  {\n\n      File: Symbolizer  (no auto-title, OpenLayers/Symbolizer.js)\n      File: Line  (no auto-title, OpenLayers/Symbolizer/Line.js)\n      File: Point  (no auto-title, OpenLayers/Symbolizer/Point.js)\n      File: Polygon  (no auto-title, OpenLayers/Symbolizer/Polygon.js)\n      File: Raster  (no auto-title, OpenLayers/Symbolizer/Raster.js)\n      File: Text  (no auto-title, OpenLayers/Symbolizer/Text.js)\n      }  # Group: Symbolizer\n\n   Group: Tile  {\n\n      File: Tile  (no auto-title, OpenLayers/Tile.js)\n      File: Image  (no auto-title, OpenLayers/Tile/Image.js)\n      File: Image.IFrame  (no auto-title, OpenLayers/Tile/Image/IFrame.js)\n      File: UTFGrid  (OpenLayers/Tile/UTFGrid.js)\n      }  # Group: Tile\n\n   File: Deprecated  (no auto-title, deprecated.js)\n\n   Group: OpenLayers  {\n\n      File: Console  (no auto-title, OpenLayers/Console.js)\n      File: Events  (no auto-title, OpenLayers/Events.js)\n      File: Icon  (no auto-title, OpenLayers/Icon.js)\n      File: Kinetic  (no auto-title, OpenLayers/Kinetic.js)\n      File: Map  (no auto-title, OpenLayers/Map.js)\n      File: Projection  (no auto-title, OpenLayers/Projection.js)\n      File: Rule  (no auto-title, OpenLayers/Rule.js)\n      File: SingleFile.js  (no auto-title, OpenLayers/SingleFile.js)\n      File: Style  (no auto-title, OpenLayers/Style.js)\n      File: Style2  (no auto-title, OpenLayers/Style2.js)\n      File: StyleMap  (no auto-title, OpenLayers/StyleMap.js)\n      File: Tween  (no auto-title, OpenLayers/Tween.js)\n      File: Util  (no auto-title, OpenLayers/Util.js)\n      File: Spherical  (no auto-title, OpenLayers/Spherical.js)\n      File: Animation  (OpenLayers/Animation.js)\n      File: Events.buttonclick  (OpenLayers/Events/buttonclick.js)\n      File: Events.featureclick  (OpenLayers/Events/featureclick.js)\n      File: TileManager  (OpenLayers/TileManager.js)\n      File: Util.vendorPrefix  (OpenLayers/Util/vendorPrefix.js)\n      File: WPSClient  (OpenLayers/WPSClient.js)\n      File: WPSProcess  (OpenLayers/WPSProcess.js)\n      }  # Group: OpenLayers\n\n   }  # Group: OpenLayers\n\nGroup: Index  {\n\n   Index: Everything\n   Class Index: Classes\n   Constant Index: Constants\n   Function Index: Functions\n   Property Index: Properties\n   File Index: Files\n   Constructor Index: Constructor\n   }  # Group: Index\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/doc_config/OL.css",
    "content": "p {\n    text-indent: 0; margin-bottom: 1em;\n}\n\n.MGroup {\n    font-variant: normal;\n    margin: 0.4em 0 0em 10px\n}\n\n.MTitle {\n    font-variant: normal;\n}\n\n.CGroup .CTitle {\n    font-variant: normal;\n}\n\n.SGroup .SEntry {\n    font-variant: normal;\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/doc_config/Topics.txt",
    "content": "Format: 1.52\n\n# This is the Natural Docs topics file for this project.  If you change anything\n# here, it will apply to THIS PROJECT ONLY.  If you'd like to change something\n# for all your projects, edit the Topics.txt in Natural Docs' Config directory\n# instead.\n\n\n# If you'd like to prevent keywords from being recognized by Natural Docs, you\n# can do it like this:\n# Ignore Keywords: [keyword], [keyword], ...\n#\n# Or you can use the list syntax like how they are defined:\n# Ignore Keywords:\n#    [keyword]\n#    [keyword], [plural keyword]\n#    ...\n\n\n#-------------------------------------------------------------------------------\n# SYNTAX:\n#\n# Topic Type: [name]\n# Alter Topic Type: [name]\n#    Creates a new topic type or alters one from the main file.  Each type gets\n#    its own index and behavior settings.  Its name can have letters, numbers,\n#    spaces, and these charaters: - / . '\n#\n# Plural: [name]\n#    Sets the plural name of the topic type, if different.\n#\n# Keywords:\n#    [keyword]\n#    [keyword], [plural keyword]\n#    ...\n#    Defines or adds to the list of keywords for the topic type.  They may only\n#    contain letters, numbers, and spaces and are not case sensitive.  Plural\n#    keywords are used for list topics.  You can redefine keywords found in the\n#    main topics file.\n#\n# Index: [yes|no]\n#    Whether the topics get their own index.  Defaults to yes.  Everything is\n#    included in the general index regardless of this setting.\n#\n# Scope: [normal|start|end|always global]\n#    How the topics affects scope.  Defaults to normal.\n#    normal        - Topics stay within the current scope.\n#    start         - Topics start a new scope for all the topics beneath it,\n#                    like class topics.\n#    end           - Topics reset the scope back to global for all the topics\n#                    beneath it.\n#    always global - Topics are defined as global, but do not change the scope\n#                    for any other topics.\n#\n# Class Hierarchy: [yes|no]\n#    Whether the topics are part of the class hierarchy.  Defaults to no.\n#\n# Page Title If First: [yes|no]\n#    Whether the topic's title becomes the page title if it's the first one in\n#    a file.  Defaults to no.\n#\n# Break Lists: [yes|no]\n#    Whether list topics should be broken into individual topics in the output.\n#    Defaults to no.\n#\n# Can Group With: [type], [type], ...\n#    Defines a list of topic types that this one can possibly be grouped with.\n#    Defaults to none.\n#-------------------------------------------------------------------------------\n\n# The following topics are defined in the main file, if you'd like to alter\n# their behavior or add keywords:\n#\n#    Generic, Class, Interface, Section, File, Group, Function, Variable,\n#    Property, Type, Constant, Enumeration, Event, Delegate, Macro,\n#    Database, Database Table, Database View, Database Index, Database\n#    Cursor, Database Trigger, Cookie, Build Target\n\n# If you add something that you think would be useful to other developers\n# and should be included in Natural Docs by default, please e-mail it to\n# topics [at] naturaldocs [dot] org.\n\n\nTopic Type: Constructor\n\n   Class Hierarchy: Yes\n   Keywords:\n      constructor\n      initialize\n\n\nAlter Topic Type: Function\n\n   Add Keywords:\n      apimethod\n      apifunction\n\n\nAlter Topic Type: Property\n\n   Add Keywords:\n      apiproperty\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/Firebug/firebug.css",
    "content": "\nhtml, body {\n    margin: 0;\n    background: #FFFFFF;\n    font-family: Lucida Grande, Tahoma, sans-serif;\n    font-size: 11px;\n    overflow: hidden;\n}\n\na {\n    text-decoration: none;\n}\n\na:hover {\n    text-decoration: underline;\n}\n\n.toolbar {\n    height: 14px;\n    border-top: 1px solid ThreeDHighlight;\n    border-bottom: 1px solid ThreeDShadow;\n    padding: 2px 6px;\n    background: ThreeDFace;\n}\n\n.toolbarRight {\n    position: absolute;\n    top: 4px;\n    right: 6px;\n}\n\n#log {\n    overflow: auto;\n    position: absolute;\n    left: 0;\n    width: 100%;\n}\n\n#commandLine {\n    position: absolute;\n    bottom: 0;\n    left: 0;\n    width: 100%;\n    height: 18px;\n    border: none;\n    border-top: 1px solid ThreeDShadow;\n}\n\n/************************************************************************************************/\n\n.logRow {\n    position: relative;\n    border-bottom: 1px solid #D7D7D7;\n    padding: 2px 4px 1px 6px;\n    background-color: #FFFFFF;\n}\n\n.logRow-command {\n    font-family: Monaco, monospace;\n    color: blue;\n}\n\n.objectBox-null {\n    padding: 0 2px;\n    border: 1px solid #666666;\n    background-color: #888888;\n    color: #FFFFFF;\n}\n\n.objectBox-string {\n    font-family: Monaco, monospace;\n    color: red;\n    white-space: pre;\n}\n\n.objectBox-number {\n    color: #000088;\n}\n\n.objectBox-function {\n    font-family: Monaco, monospace;\n    color: DarkGreen;\n}\n\n.objectBox-object {\n    color: DarkGreen;\n    font-weight: bold;\n}\n\n/************************************************************************************************/\n\n.logRow-info,\n.logRow-error,\n.logRow-warning {\n    background: #FFFFFF no-repeat 2px 2px;\n    padding-left: 20px;\n    padding-bottom: 3px;\n}\n\n.logRow-info {\n    background-image: url(infoIcon.png);\n}\n\n.logRow-warning {\n    background-color: cyan;\n    background-image: url(warningIcon.png);\n}\n\n.logRow-error {\n    background-color: LightYellow;\n    background-image: url(errorIcon.png);\n}\n\n.errorMessage {\n    vertical-align: top;\n    color: #FF0000;\n}\n\n.objectBox-sourceLink {\n    position: absolute;\n    right: 4px;\n    top: 2px;\n    padding-left: 8px;\n    font-family: Lucida Grande, sans-serif;\n    font-weight: bold;\n    color: #0000FF;\n}\n\n/************************************************************************************************/\n\n.logRow-group {\n    background: #EEEEEE;\n    border-bottom: none;\n}\n\n.logGroup {\n    background: #EEEEEE;\n}\n\n.logGroupBox {\n    margin-left: 24px;\n    border-top: 1px solid #D7D7D7;\n    border-left: 1px solid #D7D7D7;\n}\n\n/************************************************************************************************/\n\n.selectorTag,\n.selectorId,\n.selectorClass {\n    font-family: Monaco, monospace;\n    font-weight: normal;\n}\n\n.selectorTag {\n    color: #0000FF;\n}\n\n.selectorId {\n    color: DarkBlue;\n}\n\n.selectorClass {\n    color: red;\n}\n\n/************************************************************************************************/\n\n.objectBox-element {\n    font-family: Monaco, monospace;\n    color: #000088;\n}\n\n.nodeChildren {\n    margin-left: 16px;\n}\n\n.nodeTag {\n    color: blue;\n}\n\n.nodeValue {\n    color: #FF0000;\n    font-weight: normal;\n}\n\n.nodeText,\n.nodeComment {\n    margin: 0 2px;\n    vertical-align: top;\n}\n\n.nodeText {\n    color: #333333;\n}\n\n.nodeComment {\n    color: DarkGreen;\n}\n\n/************************************************************************************************/\n\n.propertyNameCell {\n    vertical-align: top;\n}\n\n.propertyName {\n    font-weight: bold;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/Firebug/firebug.html",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n         \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n\n<head>\n    <title>Firebug</title>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"firebug.css\">\n</head>\n\n<body>\n    <div id=\"toolbar\" class=\"toolbar\">\n        <a href=\"#\" onclick=\"parent.console.clear()\">Clear</a>\n        <span class=\"toolbarRight\">\n            <a href=\"#\" onclick=\"parent.console.close()\">Close</a>\n        </span>\n    </div>\n    <div id=\"log\"></div>\n    <input type=\"text\" id=\"commandLine\">\n    \n    <script>parent.onFirebugReady(document);</script>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/Firebug/firebug.js",
    "content": "\nif (!window.console || !console.firebug) { (function()\n{\n    window.console = \n    {\n        log: function()\n        {\n            logFormatted(arguments, \"\");\n        },\n        \n        debug: function()\n        {\n            logFormatted(arguments, \"debug\");\n        },\n        \n        info: function()\n        {\n            logFormatted(arguments, \"info\");\n        },\n        \n        warn: function()\n        {\n            logFormatted(arguments, \"warning\");\n        },\n        \n        error: function()\n        {\n            logFormatted(arguments, \"error\");\n        },\n        \n        assert: function(truth, message)\n        {\n            if (!truth)\n            {\n                var args = [];\n                for (var i = 1; i < arguments.length; ++i)\n                    args.push(arguments[i]);\n                \n                logFormatted(args.length ? args : [\"Assertion Failure\"], \"error\");\n                throw message ? message : \"Assertion Failure\";\n            }\n        },\n        \n        dir: function(object)\n        {\n            var html = [];\n                        \n            var pairs = [];\n            for (var name in object)\n            {\n                try\n                {\n                    pairs.push([name, object[name]]);\n                }\n                catch (exc)\n                {\n                }\n            }\n            \n            pairs.sort(function(a, b) { return a[0] < b[0] ? -1 : 1; });\n            \n            html.push('<table>');\n            for (var i = 0; i < pairs.length; ++i)\n            {\n                var name = pairs[i][0], value = pairs[i][1];\n                \n                html.push('<tr>', \n                '<td class=\"propertyNameCell\"><span class=\"propertyName\">',\n                    escapeHTML(name), '</span></td>', '<td><span class=\"propertyValue\">');\n                appendObject(value, html);\n                html.push('</span></td></tr>');\n            }\n            html.push('</table>');\n            \n            logRow(html, \"dir\");\n        },\n        \n        dirxml: function(node)\n        {\n            var html = [];\n            \n            appendNode(node, html);\n            logRow(html, \"dirxml\");\n        },\n        \n        group: function()\n        {\n            logRow(arguments, \"group\", pushGroup);\n        },\n        \n        groupEnd: function()\n        {\n            logRow(arguments, \"\", popGroup);\n        },\n        \n        time: function(name)\n        {\n            timeMap[name] = (new Date()).getTime();\n        },\n        \n        timeEnd: function(name)\n        {\n            if (name in timeMap)\n            {\n                var delta = (new Date()).getTime() - timeMap[name];\n                logFormatted([name+ \":\", delta+\"ms\"]);\n                delete timeMap[name];\n            }\n        },\n        \n        count: function()\n        {\n            this.warn([\"count() not supported.\"]);\n        },\n        \n        trace: function()\n        {\n            this.warn([\"trace() not supported.\"]);\n        },\n        \n        profile: function()\n        {\n            this.warn([\"profile() not supported.\"]);\n        },\n        \n        profileEnd: function()\n        {\n        },\n        \n        clear: function()\n        {\n            consoleBody.innerHTML = \"\";\n        },\n\n        open: function()\n        {\n            toggleConsole(true);\n        },\n        \n        close: function()\n        {\n            if (frameVisible)\n                toggleConsole();\n        }\n    };\n       \n    var consoleFrame = null;\n    var consoleBody = null;\n    var commandLine = null;\n    \n    var frameVisible = false;\n    var messageQueue = [];\n    var groupStack = [];\n    var timeMap = {};\n    \n    var clPrefix = \">>> \";\n    \n    var isFirefox = navigator.userAgent.indexOf(\"Firefox\") != -1;\n    var isIE = navigator.userAgent.indexOf(\"MSIE\") != -1;\n    var isOpera = navigator.userAgent.indexOf(\"Opera\") != -1;\n    var isSafari = navigator.userAgent.indexOf(\"AppleWebKit\") != -1;\n\n    function toggleConsole(forceOpen)\n    {\n        frameVisible = forceOpen || !frameVisible;\n        if (consoleFrame)\n            consoleFrame.style.visibility = frameVisible ? \"visible\" : \"hidden\";\n        else\n            waitForBody();\n    }\n\n    function focusCommandLine()\n    {\n        toggleConsole(true);\n        if (commandLine)\n            commandLine.focus();\n    }\n\n    function waitForBody()\n    {\n        if (document.body)\n            createFrame();\n        else\n            setTimeout(waitForBody, 200);\n    }    \n\n    function createFrame()\n    {\n        if (consoleFrame)\n            return;\n        \n        window.onFirebugReady = function(doc)\n        {\n            window.onFirebugReady = null;\n\n            var toolbar = doc.getElementById(\"toolbar\");\n            toolbar.onmousedown = onSplitterMouseDown;\n\n            commandLine = doc.getElementById(\"commandLine\");\n            addEvent(commandLine, \"keydown\", onCommandLineKeyDown);\n\n            addEvent(doc, isIE || isSafari ? \"keydown\" : \"keypress\", onKeyDown);\n            \n            consoleBody = doc.getElementById(\"log\");\n            layout();\n            flush();\n        };\n\n        var baseURL = getFirebugURL();\n\n        consoleFrame = document.createElement(\"iframe\");\n        consoleFrame.setAttribute(\"src\", baseURL+\"/firebug.html\");\n        consoleFrame.setAttribute(\"frameBorder\", \"0\");\n        consoleFrame.style.visibility = (frameVisible ? \"visible\" : \"hidden\");    \n        consoleFrame.style.zIndex = \"2147483583\";\n        consoleFrame.style.position = document.all ? \"absolute\" : \"fixed\";\n        consoleFrame.style.width = \"100%\";\n        consoleFrame.style.left = \"0\";\n        consoleFrame.style.bottom = \"0\";\n        consoleFrame.style.height = \"200px\";\n        document.body.appendChild(consoleFrame);\n    }\n    \n    function getFirebugURL()\n    {\n        var scripts = document.getElementsByTagName(\"script\");\n        for (var i = 0; i < scripts.length; ++i)\n        {\n            if (scripts[i].src.indexOf(\"firebug.js\") != -1)\n            {\n                var lastSlash = scripts[i].src.lastIndexOf(\"/\");\n                return scripts[i].src.substr(0, lastSlash);\n            }\n        }\n    }\n    \n    function evalCommandLine()\n    {\n        var text = commandLine.value;\n        commandLine.value = \"\";\n\n        logRow([clPrefix, text], \"command\");\n        \n        var value;\n        try\n        {\n            value = eval(text);\n        }\n        catch (exc)\n        {\n        }\n\n        console.log(value);\n    }\n    \n    function layout()\n    {\n        var toolbar = consoleBody.ownerDocument.getElementById(\"toolbar\");\n        var height = consoleFrame.offsetHeight - (toolbar.offsetHeight + commandLine.offsetHeight);\n        height = Math.max(height, 0);\n        consoleBody.style.top = toolbar.offsetHeight + \"px\";\n        consoleBody.style.height = height + \"px\";\n        \n        commandLine.style.top = (consoleFrame.offsetHeight - commandLine.offsetHeight) + \"px\";\n    }\n    \n    function logRow(message, className, handler)\n    {\n        if (consoleBody)\n            writeMessage(message, className, handler);\n        else\n        {\n            messageQueue.push([message, className, handler]);\n            waitForBody();\n        }\n    }\n    \n    function flush()\n    {\n        var queue = messageQueue;\n        messageQueue = [];\n        \n        for (var i = 0; i < queue.length; ++i)\n            writeMessage(queue[i][0], queue[i][1], queue[i][2]);\n    }\n\n    function writeMessage(message, className, handler)\n    {\n        var isScrolledToBottom =\n            consoleBody.scrollTop + consoleBody.offsetHeight >= consoleBody.scrollHeight;\n\n        if (!handler)\n            handler = writeRow;\n        \n        handler(message, className);\n        \n        if (isScrolledToBottom)\n            consoleBody.scrollTop = consoleBody.scrollHeight - consoleBody.offsetHeight;\n    }\n    \n    function appendRow(row)\n    {\n        var container = groupStack.length ? groupStack[groupStack.length-1] : consoleBody;\n        container.appendChild(row);\n    }\n\n    function writeRow(message, className)\n    {\n        var row = consoleBody.ownerDocument.createElement(\"div\");\n        row.className = \"logRow\" + (className ? \" logRow-\"+className : \"\");\n        row.innerHTML = message.join(\"\");\n        appendRow(row);\n    }\n\n    function pushGroup(message, className)\n    {\n        logFormatted(message, className);\n\n        var groupRow = consoleBody.ownerDocument.createElement(\"div\");\n        groupRow.className = \"logGroup\";\n        var groupRowBox = consoleBody.ownerDocument.createElement(\"div\");\n        groupRowBox.className = \"logGroupBox\";\n        groupRow.appendChild(groupRowBox);\n        appendRow(groupRowBox);\n        groupStack.push(groupRowBox);\n    }\n\n    function popGroup()\n    {\n        groupStack.pop();\n    }\n\n    function logFormatted(objects, className)\n    {\n        var html = [];\n\n        var format = objects[0];\n        var objIndex = 0;\n\n        if (typeof(format) != \"string\")\n        {\n            format = \"\";\n            objIndex = -1;\n        }\n\n        var parts = parseFormat(format);\n        for (var i = 0; i < parts.length; ++i)\n        {\n            var part = parts[i];\n            if (part && typeof(part) == \"object\")\n            {\n                var object = objects[++objIndex];\n                part.appender(object, html);\n            }\n            else\n                appendText(part, html);\n        }\n\n        for (var i = objIndex+1; i < objects.length; ++i)\n        {\n            appendText(\" \", html);\n            \n            var object = objects[i];\n            if (typeof(object) == \"string\")\n                appendText(object, html);\n            else\n                appendObject(object, html);\n        }\n        \n        logRow(html, className);\n    }\n\n    function parseFormat(format)\n    {\n        var parts = [];\n\n        var reg = /((^%|[^\\\\]%)(\\d+)?(\\.)([a-zA-Z]))|((^%|[^\\\\]%)([a-zA-Z]))/;    \n        var appenderMap = {s: appendText, d: appendInteger, i: appendInteger, f: appendFloat};\n\n        for (var m = reg.exec(format); m; m = reg.exec(format))\n        {\n            var type = m[8] ? m[8] : m[5];\n            var appender = type in appenderMap ? appenderMap[type] : appendObject;\n            var precision = m[3] ? parseInt(m[3]) : (m[4] == \".\" ? -1 : 0);\n\n            parts.push(format.substr(0, m[0][0] == \"%\" ? m.index : m.index+1));\n            parts.push({appender: appender, precision: precision});\n\n            format = format.substr(m.index+m[0].length);\n        }\n\n        parts.push(format);\n\n        return parts;\n    }\n\n    function escapeHTML(value)\n    {\n        function replaceChars(ch)\n        {\n            switch (ch)\n            {\n                case \"<\":\n                    return \"&lt;\";\n                case \">\":\n                    return \"&gt;\";\n                case \"&\":\n                    return \"&amp;\";\n                case \"'\":\n                    return \"&#39;\";\n                case '\"':\n                    return \"&quot;\";\n            }\n            return \"?\";\n        };\n        return String(value).replace(/[<>&\"']/g, replaceChars);\n    }\n\n    function objectToString(object)\n    {\n        try\n        {\n            return object+\"\";\n        }\n        catch (exc)\n        {\n            return null;\n        }\n    }\n\n    function appendText(object, html)\n    {\n        html.push(escapeHTML(objectToString(object)));\n    }\n\n    function appendNull(object, html)\n    {\n        html.push('<span class=\"objectBox-null\">', escapeHTML(objectToString(object)), '</span>');\n    }\n\n    function appendString(object, html)\n    {\n        html.push('<span class=\"objectBox-string\">&quot;', escapeHTML(objectToString(object)),\n            '&quot;</span>');\n    }\n\n    function appendInteger(object, html)\n    {\n        html.push('<span class=\"objectBox-number\">', escapeHTML(objectToString(object)), '</span>');\n    }\n\n    function appendFloat(object, html)\n    {\n        html.push('<span class=\"objectBox-number\">', escapeHTML(objectToString(object)), '</span>');\n    }\n\n    function appendFunction(object, html)\n    {\n        var reName = /function ?(.*?)\\(/;\n        var m = reName.exec(objectToString(object));\n        var name = m ? m[1] : \"function\";\n        html.push('<span class=\"objectBox-function\">', escapeHTML(name), '()</span>');\n    }\n    \n    function appendObject(object, html)\n    {\n        try\n        {\n            if (object == undefined)\n                appendNull(\"undefined\", html);\n            else if (object == null)\n                appendNull(\"null\", html);\n            else if (typeof object == \"string\")\n                appendString(object, html);\n            else if (typeof object == \"number\")\n                appendInteger(object, html);\n            else if (typeof object == \"function\")\n                appendFunction(object, html);\n            else if (object.nodeType == 1)\n                appendSelector(object, html);\n            else if (typeof object == \"object\")\n                appendObjectFormatted(object, html);\n            else\n                appendText(object, html);\n        }\n        catch (exc)\n        {\n        }\n    }\n        \n    function appendObjectFormatted(object, html)\n    {\n        var text = objectToString(object);\n        var reObject = /\\[object (.*?)\\]/;\n\n        var m = reObject.exec(text);\n        html.push('<span class=\"objectBox-object\">', m ? m[1] : text, '</span>')\n    }\n    \n    function appendSelector(object, html)\n    {\n        html.push('<span class=\"objectBox-selector\">');\n\n        html.push('<span class=\"selectorTag\">', escapeHTML(object.nodeName.toLowerCase()), '</span>');\n        if (object.id)\n            html.push('<span class=\"selectorId\">#', escapeHTML(object.id), '</span>');\n        if (object.className)\n            html.push('<span class=\"selectorClass\">.', escapeHTML(object.className), '</span>');\n\n        html.push('</span>');\n    }\n\n    function appendNode(node, html)\n    {\n        if (node.nodeType == 1)\n        {\n            html.push(\n                '<div class=\"objectBox-element\">',\n                    '&lt;<span class=\"nodeTag\">', node.nodeName.toLowerCase(), '</span>');\n\n            for (var i = 0; i < node.attributes.length; ++i)\n            {\n                var attr = node.attributes[i];\n                if (!attr.specified)\n                    continue;\n                \n                html.push('&nbsp;<span class=\"nodeName\">', attr.nodeName.toLowerCase(),\n                    '</span>=&quot;<span class=\"nodeValue\">', escapeHTML(attr.nodeValue),\n                    '</span>&quot;')\n            }\n\n            if (node.firstChild)\n            {\n                html.push('&gt;</div><div class=\"nodeChildren\">');\n\n                for (var child = node.firstChild; child; child = child.nextSibling)\n                    appendNode(child, html);\n                    \n                html.push('</div><div class=\"objectBox-element\">&lt;/<span class=\"nodeTag\">', \n                    node.nodeName.toLowerCase(), '&gt;</span></div>');\n            }\n            else\n                html.push('/&gt;</div>');\n        }\n        else if (node.nodeType == 3)\n        {\n            html.push('<div class=\"nodeText\">', escapeHTML(node.nodeValue),\n                '</div>');\n        }\n    }\n    \n    function addEvent(object, name, handler)\n    {\n        if (document.all)\n            object.attachEvent(\"on\"+name, handler);\n        else\n            object.addEventListener(name, handler, false);\n    }\n    \n    function removeEvent(object, name, handler)\n    {\n        if (document.all)\n            object.detachEvent(\"on\"+name, handler);\n        else\n            object.removeEventListener(name, handler, false);\n    }\n    \n    function cancelEvent(event)\n    {\n        if (document.all)\n            event.cancelBubble = true;\n        else\n            event.stopPropagation();        \n    }\n\n    function onError(msg, href, lineNo)\n    {\n        var html = [];\n        \n        var lastSlash = href.lastIndexOf(\"/\");\n        var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1);\n        \n        html.push(\n            '<span class=\"errorMessage\">', msg, '</span>', \n            '<div class=\"objectBox-sourceLink\">', fileName, ' (line ', lineNo, ')</div>'\n        );\n        \n        logRow(html, \"error\");\n    };\n\n    function onKeyDown(event)\n    {\n        if (event.keyCode == 123)\n            toggleConsole();\n        else if ((event.keyCode == 108 || event.keyCode == 76) && event.shiftKey\n                 && (event.metaKey || event.ctrlKey))\n            focusCommandLine();\n        else\n            return;\n        \n        cancelEvent(event);\n    }\n\n    function onSplitterMouseDown(event)\n    {\n        if (isSafari || isOpera)\n            return;\n        \n        addEvent(document, \"mousemove\", onSplitterMouseMove);\n        addEvent(document, \"mouseup\", onSplitterMouseUp);\n\n        for (var i = 0; i < frames.length; ++i)\n        {\n            addEvent(frames[i].document, \"mousemove\", onSplitterMouseMove);\n            addEvent(frames[i].document, \"mouseup\", onSplitterMouseUp);\n        }\n    }\n    \n    function onSplitterMouseMove(event)\n    {\n        var win = document.all\n            ? event.srcElement.ownerDocument.parentWindow\n            : event.target.ownerDocument.defaultView;\n\n        var clientY = event.clientY;\n        if (win != win.parent)\n            clientY += win.frameElement ? win.frameElement.offsetTop : 0;\n        \n        var height = consoleFrame.offsetTop + consoleFrame.clientHeight;\n        var toolbar = consoleBody.ownerDocument.getElementById(\"toolbar\");\n        var y = Math.max(height - clientY,\n                         toolbar.offsetHeight + commandLine.offsetHeight);\n        \n        consoleFrame.style.height = y + \"px\";\n        layout();\n    }\n    \n    function onSplitterMouseUp(event)\n    {\n        removeEvent(document, \"mousemove\", onSplitterMouseMove);\n        removeEvent(document, \"mouseup\", onSplitterMouseUp);\n\n        for (var i = 0; i < frames.length; ++i)\n        {\n            removeEvent(frames[i].document, \"mousemove\", onSplitterMouseMove);\n            removeEvent(frames[i].document, \"mouseup\", onSplitterMouseUp);\n        }\n    }\n    \n    function onCommandLineKeyDown(event)\n    {\n        if (event.keyCode == 13)\n            evalCommandLine();\n        else if (event.keyCode == 27)\n            commandLine.value = \"\";\n    }\n    \n    window.onerror = onError;\n    addEvent(document, isIE || isSafari ? \"keydown\" : \"keypress\", onKeyDown);\n    \n    if (document.documentElement.getAttribute(\"debug\") == \"true\")\n        toggleConsole(true);\n})();\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/Firebug/firebugx.js",
    "content": "(function() {\n    if (!window.console || !console.firebug) {\n        var names = [\"log\", \"debug\", \"info\", \"warn\", \"error\", \"assert\", \"dir\", \"dirxml\",\n        \"group\", \"groupEnd\", \"time\", \"timeEnd\", \"count\", \"trace\", \"profile\", \"profileEnd\"];\n\n        window.console = {};\n        for (var i = 0; i < names.length; ++i)\n            window.console[names[i]] = function() {}\n    }\n})();\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/Firebug/license.txt",
    "content": "Software License Agreement (BSD License)\n\nCopyright (c) 2007, Parakey Inc.\nAll rights reserved.\n\nRedistribution and use of this software in source and binary forms, with or without modification,\nare permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above\n  copyright notice, this list of conditions and the\n  following disclaimer.\n\n* Redistributions in binary form must reproduce the above\n  copyright notice, this list of conditions and the\n  following disclaimer in the documentation and/or other\n  materials provided with the distribution.\n\n* Neither the name of Parakey Inc. nor the names of its\n  contributors may be used to endorse or promote products\n  derived from this software without specific prior\n  written permission of Parakey Inc.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR\nIMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND\nFITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\nCONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER\nIN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT\nOF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/Firebug/readme.txt",
    "content": "This directory contains the source for Firebug Lite\n(http://www.getfirebug.com/lite.html).  This code is distributed with a\nBSD License, Copyright (c) 2007, Parakey Inc.  See the included license.txt\nfor the full text of the license.\n\nThis is a patched version of the trunk from\nhttp://fbug.googlecode.com/svn/trunk.\n\nRevision 36 was patched to resolve the issue described here\nhttp://code.google.com/p/fbug/issues/detail?id=85\n\nWhen this issue is resolved, Firebug Lite can be used directly - no further\nmodifications are needed for OpenLayers."
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Animation.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Animation = (function(window) {\n    \n        var requestAnimationFrame = OpenLayers.Util.vendorPrefix.js(window, \"requestAnimationFrame\");\n    var isNative = !!(requestAnimationFrame);\n    \n        var requestFrame = (function() {\n        var request = window[requestAnimationFrame] ||\n            function(callback, element) {\n                window.setTimeout(callback, 16);\n            };\n        return function(callback, element) {\n            request.apply(window, [callback, element]);\n        };\n    })();\n    var counter = 0;\n    var loops = {};\n    \n        function start(callback, duration, element) {\n        duration = duration > 0 ? duration : Number.POSITIVE_INFINITY;\n        var id = ++counter;\n        var start = +new Date;\n        loops[id] = function() {\n            if (loops[id] && +new Date - start <= duration) {\n                callback();\n                if (loops[id]) {\n                    requestFrame(loops[id], element);\n                }\n            } else {\n                delete loops[id];\n            }\n        };\n        requestFrame(loops[id], element);\n        return id;\n    }\n    \n        function stop(id) {\n        delete loops[id];\n    }\n    \n    return {\n        isNative: isNative,\n        requestFrame: requestFrame,\n        start: start,\n        stop: stop\n    };\n    \n})(window);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/BaseTypes/Bounds.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Bounds = OpenLayers.Class({\n\n        left: null,\n\n        bottom: null,\n\n        right: null,\n\n        top: null,\n    \n        centerLonLat: null,\n\n        initialize: function(left, bottom, right, top) {\n        if (OpenLayers.Util.isArray(left)) {\n            top = left[3];\n            right = left[2];\n            bottom = left[1];\n            left = left[0];\n        }\n        if (left != null) {\n            this.left = OpenLayers.Util.toFloat(left);\n        }\n        if (bottom != null) {\n            this.bottom = OpenLayers.Util.toFloat(bottom);\n        }\n        if (right != null) {\n            this.right = OpenLayers.Util.toFloat(right);\n        }\n        if (top != null) {\n            this.top = OpenLayers.Util.toFloat(top);\n        }\n    },\n\n        clone:function() {\n        return new OpenLayers.Bounds(this.left, this.bottom, \n                                     this.right, this.top);\n    },\n\n        equals:function(bounds) {\n        var equals = false;\n        if (bounds != null) {\n            equals = ((this.left == bounds.left) && \n                      (this.right == bounds.right) &&\n                      (this.top == bounds.top) && \n                      (this.bottom == bounds.bottom));\n        }\n        return equals;\n    },\n\n        toString:function() {\n        return [this.left, this.bottom, this.right, this.top].join(\",\");\n    },\n\n        toArray: function(reverseAxisOrder) {\n        if (reverseAxisOrder === true) {\n            return [this.bottom, this.left, this.top, this.right];\n        } else {\n            return [this.left, this.bottom, this.right, this.top];\n        }\n    },    \n\n        toBBOX:function(decimal, reverseAxisOrder) {\n        if (decimal== null) {\n            decimal = 6; \n        }\n        var mult = Math.pow(10, decimal);\n        var xmin = Math.round(this.left * mult) / mult;\n        var ymin = Math.round(this.bottom * mult) / mult;\n        var xmax = Math.round(this.right * mult) / mult;\n        var ymax = Math.round(this.top * mult) / mult;\n        if (reverseAxisOrder === true) {\n            return ymin + \",\" + xmin + \",\" + ymax + \",\" + xmax;\n        } else {\n            return xmin + \",\" + ymin + \",\" + xmax + \",\" + ymax;\n        }\n    },\n \n        toGeometry: function() {\n        return new OpenLayers.Geometry.Polygon([\n            new OpenLayers.Geometry.LinearRing([\n                new OpenLayers.Geometry.Point(this.left, this.bottom),\n                new OpenLayers.Geometry.Point(this.right, this.bottom),\n                new OpenLayers.Geometry.Point(this.right, this.top),\n                new OpenLayers.Geometry.Point(this.left, this.top)\n            ])\n        ]);\n    },\n    \n        getWidth:function() {\n        return (this.right - this.left);\n    },\n\n        getHeight:function() {\n        return (this.top - this.bottom);\n    },\n\n        getSize:function() {\n        return new OpenLayers.Size(this.getWidth(), this.getHeight());\n    },\n\n        getCenterPixel:function() {\n        return new OpenLayers.Pixel( (this.left + this.right) / 2,\n                                     (this.bottom + this.top) / 2);\n    },\n\n        getCenterLonLat:function() {\n        if(!this.centerLonLat) {\n            this.centerLonLat = new OpenLayers.LonLat(\n                (this.left + this.right) / 2, (this.bottom + this.top) / 2\n            );\n        }\n        return this.centerLonLat;\n    },\n\n        scale: function(ratio, origin){\n        if(origin == null){\n            origin = this.getCenterLonLat();\n        }\n        \n        var origx,origy;\n        if(origin.CLASS_NAME == \"OpenLayers.LonLat\"){\n            origx = origin.lon;\n            origy = origin.lat;\n        } else {\n            origx = origin.x;\n            origy = origin.y;\n        }\n\n        var left = (this.left - origx) * ratio + origx;\n        var bottom = (this.bottom - origy) * ratio + origy;\n        var right = (this.right - origx) * ratio + origx;\n        var top = (this.top - origy) * ratio + origy;\n        \n        return new OpenLayers.Bounds(left, bottom, right, top);\n    },\n\n        add:function(x, y) {\n        if ( (x == null) || (y == null) ) {\n            throw new TypeError('Bounds.add cannot receive null values');\n        }\n        return new OpenLayers.Bounds(this.left + x, this.bottom + y,\n                                     this.right + x, this.top + y);\n    },\n    \n        extend:function(object) {\n        if (object) {\n            switch(object.CLASS_NAME) {\n                case \"OpenLayers.LonLat\":\n                    this.extendXY(object.lon, object.lat);\n                    break;\n                case \"OpenLayers.Geometry.Point\":\n                    this.extendXY(object.x, object.y);\n                    break;\n\n                case \"OpenLayers.Bounds\":\n                    this.centerLonLat = null;\n\n                    if ( (this.left == null) || (object.left < this.left)) {\n                        this.left = object.left;\n                    }\n                    if ( (this.bottom == null) || (object.bottom < this.bottom) ) {\n                        this.bottom = object.bottom;\n                    }\n                    if ( (this.right == null) || (object.right > this.right) ) {\n                        this.right = object.right;\n                    }\n                    if ( (this.top == null) || (object.top > this.top) ) {\n                        this.top = object.top;\n                    }\n                    break;\n            }\n        }\n    },\n\n        extendXY:function(x, y) {\n        this.centerLonLat = null;\n\n        if ((this.left == null) || (x < this.left)) {\n            this.left = x;\n        }\n        if ((this.bottom == null) || (y < this.bottom)) {\n            this.bottom = y;\n        }\n        if ((this.right == null) || (x > this.right)) {\n            this.right = x;\n        }\n        if ((this.top == null) || (y > this.top)) {\n            this.top = y;\n        }\n    },\n\n        containsLonLat: function(ll, options) {\n        if (typeof options === \"boolean\") {\n            options =  {inclusive: options};\n        }\n        options = options || {};\n        var contains = this.contains(ll.lon, ll.lat, options.inclusive),\n            worldBounds = options.worldBounds;\n        if (worldBounds && !contains) {\n            var worldWidth = worldBounds.getWidth();\n            var worldCenterX = (worldBounds.left + worldBounds.right) / 2;\n            var worldsAway = Math.round((ll.lon - worldCenterX) / worldWidth);\n            contains = this.containsLonLat({\n                lon: ll.lon - worldsAway * worldWidth,\n                lat: ll.lat\n            }, {inclusive: options.inclusive});\n        }\n        return contains;\n    },\n\n        containsPixel:function(px, inclusive) {\n        return this.contains(px.x, px.y, inclusive);\n    },\n    \n        contains:function(x, y, inclusive) {\n        if (inclusive == null) {\n            inclusive = true;\n        }\n\n        if (x == null || y == null) {\n            return false;\n        }\n\n        x = OpenLayers.Util.toFloat(x);\n        y = OpenLayers.Util.toFloat(y);\n\n        var contains = false;\n        if (inclusive) {\n            contains = ((x >= this.left) && (x <= this.right) && \n                        (y >= this.bottom) && (y <= this.top));\n        } else {\n            contains = ((x > this.left) && (x < this.right) && \n                        (y > this.bottom) && (y < this.top));\n        }              \n        return contains;\n    },\n\n        intersectsBounds:function(bounds, options) {\n        if (typeof options === \"boolean\") {\n            options =  {inclusive: options};\n        }\n        options = options || {};\n        if (options.worldBounds) {\n            var self = this.wrapDateLine(options.worldBounds);\n            bounds = bounds.wrapDateLine(options.worldBounds);\n        } else {\n            self = this;\n        }\n        if (options.inclusive == null) {\n            options.inclusive = true;\n        }\n        var intersects = false;\n        var mightTouch = (\n            self.left == bounds.right ||\n            self.right == bounds.left ||\n            self.top == bounds.bottom ||\n            self.bottom == bounds.top\n        );\n        if (options.inclusive || !mightTouch) {\n            var inBottom = (\n                ((bounds.bottom >= self.bottom) && (bounds.bottom <= self.top)) ||\n                ((self.bottom >= bounds.bottom) && (self.bottom <= bounds.top))\n            );\n            var inTop = (\n                ((bounds.top >= self.bottom) && (bounds.top <= self.top)) ||\n                ((self.top > bounds.bottom) && (self.top < bounds.top))\n            );\n            var inLeft = (\n                ((bounds.left >= self.left) && (bounds.left <= self.right)) ||\n                ((self.left >= bounds.left) && (self.left <= bounds.right))\n            );\n            var inRight = (\n                ((bounds.right >= self.left) && (bounds.right <= self.right)) ||\n                ((self.right >= bounds.left) && (self.right <= bounds.right))\n            );\n            intersects = ((inBottom || inTop) && (inLeft || inRight));\n        }\n        if (options.worldBounds && !intersects) {\n            var world = options.worldBounds;\n            var width = world.getWidth();\n            var selfCrosses = !world.containsBounds(self);\n            var boundsCrosses = !world.containsBounds(bounds);\n            if (selfCrosses && !boundsCrosses) {\n                bounds = bounds.add(-width, 0);\n                intersects = self.intersectsBounds(bounds, {inclusive: options.inclusive});\n            } else if (boundsCrosses && !selfCrosses) {\n                self = self.add(-width, 0);\n                intersects = bounds.intersectsBounds(self, {inclusive: options.inclusive});                \n            }\n        }\n        return intersects;\n    },\n    \n        containsBounds:function(bounds, partial, inclusive) {\n        if (partial == null) {\n            partial = false;\n        }\n        if (inclusive == null) {\n            inclusive = true;\n        }\n        var bottomLeft  = this.contains(bounds.left, bounds.bottom, inclusive);\n        var bottomRight = this.contains(bounds.right, bounds.bottom, inclusive);\n        var topLeft  = this.contains(bounds.left, bounds.top, inclusive);\n        var topRight = this.contains(bounds.right, bounds.top, inclusive);\n        \n        return (partial) ? (bottomLeft || bottomRight || topLeft || topRight)\n                         : (bottomLeft && bottomRight && topLeft && topRight);\n    },\n\n        determineQuadrant: function(lonlat) {\n    \n        var quadrant = \"\";\n        var center = this.getCenterLonLat();\n        \n        quadrant += (lonlat.lat < center.lat) ? \"b\" : \"t\";\n        quadrant += (lonlat.lon < center.lon) ? \"l\" : \"r\";\n    \n        return quadrant; \n    },\n    \n        transform: function(source, dest) {\n        this.centerLonLat = null;\n        var ll = OpenLayers.Projection.transform(\n            {'x': this.left, 'y': this.bottom}, source, dest);\n        var lr = OpenLayers.Projection.transform(\n            {'x': this.right, 'y': this.bottom}, source, dest);\n        var ul = OpenLayers.Projection.transform(\n            {'x': this.left, 'y': this.top}, source, dest);\n        var ur = OpenLayers.Projection.transform(\n            {'x': this.right, 'y': this.top}, source, dest);\n        this.left   = Math.min(ll.x, ul.x);\n        this.bottom = Math.min(ll.y, lr.y);\n        this.right  = Math.max(lr.x, ur.x);\n        this.top    = Math.max(ul.y, ur.y);\n        return this;\n    },\n\n        wrapDateLine: function(maxExtent, options) {    \n        options = options || {};\n        \n        var leftTolerance = options.leftTolerance || 0;\n        var rightTolerance = options.rightTolerance || 0;\n\n        var newBounds = this.clone();\n    \n        if (maxExtent) {\n            var width = maxExtent.getWidth();\n            while (newBounds.left < maxExtent.left && \n                   newBounds.right - rightTolerance <= maxExtent.left ) { \n                newBounds = newBounds.add(width, 0);\n            }\n            while (newBounds.left + leftTolerance >= maxExtent.right && \n                   newBounds.right > maxExtent.right ) { \n                newBounds = newBounds.add(-width, 0);\n            }\n            var newLeft = newBounds.left + leftTolerance;\n            if (newLeft < maxExtent.right && newLeft > maxExtent.left && \n                   newBounds.right - rightTolerance > maxExtent.right) {\n                newBounds = newBounds.add(-width, 0);\n            }\n        }\n                \n        return newBounds;\n    },\n\n    CLASS_NAME: \"OpenLayers.Bounds\"\n});\n\nOpenLayers.Bounds.fromString = function(str, reverseAxisOrder) {\n    var bounds = str.split(\",\");\n    return OpenLayers.Bounds.fromArray(bounds, reverseAxisOrder);\n};\n\nOpenLayers.Bounds.fromArray = function(bbox, reverseAxisOrder) {\n    return reverseAxisOrder === true ?\n           new OpenLayers.Bounds(bbox[1], bbox[0], bbox[3], bbox[2]) :\n           new OpenLayers.Bounds(bbox[0], bbox[1], bbox[2], bbox[3]);\n};\n\nOpenLayers.Bounds.fromSize = function(size) {\n    return new OpenLayers.Bounds(0,\n                                 size.h,\n                                 size.w,\n                                 0);\n};\n\nOpenLayers.Bounds.oppositeQuadrant = function(quadrant) {\n    var opp = \"\";\n    \n    opp += (quadrant.charAt(0) == 't') ? 'b' : 't';\n    opp += (quadrant.charAt(1) == 'l') ? 'r' : 'l';\n    \n    return opp;\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/BaseTypes/Class.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Class = function() {\n    var len = arguments.length;\n    var P = arguments[0];\n    var F = arguments[len-1];\n\n    var C = typeof F.initialize == \"function\" ?\n        F.initialize :\n        function(){ P.prototype.initialize.apply(this, arguments); };\n\n    if (len > 1) {\n        var newArgs = [C, P].concat(\n                Array.prototype.slice.call(arguments).slice(1, len-1), F);\n        OpenLayers.inherit.apply(null, newArgs);\n    } else {\n        C.prototype = F;\n    }\n    return C;\n};\n\nOpenLayers.inherit = function(C, P) {\n   var F = function() {};\n   F.prototype = P.prototype;\n   C.prototype = new F;\n   var i, l, o;\n   for(i=2, l=arguments.length; i<l; i++) {\n       o = arguments[i];\n       if(typeof o === \"function\") {\n           o = o.prototype;\n       }\n       OpenLayers.Util.extend(C.prototype, o);\n   }\n};\n\nOpenLayers.Util = OpenLayers.Util || {};\nOpenLayers.Util.extend = function(destination, source) {\n    destination = destination || {};\n    if (source) {\n        for (var property in source) {\n            var value = source[property];\n            if (value !== undefined) {\n                destination[property] = value;\n            }\n        }\n\n        \n        /*\n         * FF/Windows < 2.0.0.13 reports \"Illegal operation on WrappedNative\n         * prototype object\" when calling hawOwnProperty if the source object\n         * is an instance of window.Event.\n         */\n\n        var sourceIsEvt = typeof window.Event == \"function\"\n                          && source instanceof window.Event;\n\n        if (!sourceIsEvt\n           && source.hasOwnProperty && source.hasOwnProperty(\"toString\")) {\n            destination.toString = source.toString;\n        }\n    }\n    return destination;\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/BaseTypes/Date.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Date = {\n\n        dateRegEx: /^(?:(\\d{4})(?:-(\\d{2})(?:-(\\d{2}))?)?)?(?:(?:T(\\d{1,2}):(\\d{2}):(\\d{2}(?:\\.\\d+)?)(Z|(?:[+-]\\d{1,2}(?::(\\d{2}))?)))|Z)?$/,\n\n        toISOString: (function() {\n        if (\"toISOString\" in Date.prototype) {\n            return function(date) {\n                return date.toISOString();\n            };\n        } else {\n            return function(date) {\n                var str;\n                if (isNaN(date.getTime())) {\n                    str = \"Invalid Date\";\n                } else {\n                    str =\n                        date.getUTCFullYear() + \"-\" +\n                        OpenLayers.Number.zeroPad(date.getUTCMonth() + 1, 2) + \"-\" +\n                        OpenLayers.Number.zeroPad(date.getUTCDate(), 2) + \"T\" +\n                        OpenLayers.Number.zeroPad(date.getUTCHours(), 2) + \":\" +\n                        OpenLayers.Number.zeroPad(date.getUTCMinutes(), 2) + \":\" +\n                        OpenLayers.Number.zeroPad(date.getUTCSeconds(), 2) + \".\" +\n                        OpenLayers.Number.zeroPad(date.getUTCMilliseconds(), 3) + \"Z\";\n                }\n                return str;\n            };\n        }\n\n    })(),\n\n        parse: function(str) {\n        var date;\n        var match = str.match(this.dateRegEx);\n        if (match && (match[1] || match[7])) { // must have at least year or time\n            var year = parseInt(match[1], 10) || 0;\n            var month = (parseInt(match[2], 10) - 1) || 0;\n            var day = parseInt(match[3], 10) || 1;\n            date = new Date(Date.UTC(year, month, day));\n            var type = match[7];\n            if (type) {\n                var hours = parseInt(match[4], 10);\n                var minutes = parseInt(match[5], 10);\n                var secFrac = parseFloat(match[6]);\n                var seconds = secFrac | 0;\n                var milliseconds = Math.round(1000 * (secFrac - seconds));\n                date.setUTCHours(hours, minutes, seconds, milliseconds);\n                if (type !== \"Z\") {\n                    var hoursOffset = parseInt(type, 10);\n                    var minutesOffset = parseInt(match[8], 10) || 0;\n                    var offset = -1000 * (60 * (hoursOffset * 60) + minutesOffset * 60);\n                    date = new Date(date.getTime() + offset);\n                }\n            }\n        } else {\n            date = new Date(\"invalid\");\n        }\n        return date;\n    }\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/BaseTypes/Element.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Element = {\n\n        visible: function(element) {\n        return OpenLayers.Util.getElement(element).style.display != 'none';\n    },\n\n        toggle: function() {\n        for (var i=0, len=arguments.length; i<len; i++) {\n            var element = OpenLayers.Util.getElement(arguments[i]);\n            var display = OpenLayers.Element.visible(element) ? 'none' \n                                                              : '';\n            element.style.display = display;\n        }\n    },\n\n        remove: function(element) {\n        element = OpenLayers.Util.getElement(element);\n        element.parentNode.removeChild(element);\n    },\n\n        getHeight: function(element) {\n        element = OpenLayers.Util.getElement(element);\n        return element.offsetHeight;\n    },\n\n        hasClass: function(element, name) {\n        var names = element.className;\n        return (!!names && new RegExp(\"(^|\\\\s)\" + name + \"(\\\\s|$)\").test(names));\n    },\n    \n        addClass: function(element, name) {\n        if(!OpenLayers.Element.hasClass(element, name)) {\n            element.className += (element.className ? \" \" : \"\") + name;\n        }\n        return element;\n    },\n\n        removeClass: function(element, name) {\n        var names = element.className;\n        if(names) {\n            element.className = OpenLayers.String.trim(\n                names.replace(\n                    new RegExp(\"(^|\\\\s+)\" + name + \"(\\\\s+|$)\"), \" \"\n                )\n            );\n        }\n        return element;\n    },\n\n        toggleClass: function(element, name) {\n        if(OpenLayers.Element.hasClass(element, name)) {\n            OpenLayers.Element.removeClass(element, name);\n        } else {\n            OpenLayers.Element.addClass(element, name);\n        }\n        return element;\n    },\n\n        getStyle: function(element, style) {\n        element = OpenLayers.Util.getElement(element);\n\n        var value = null;\n        if (element && element.style) {\n            value = element.style[OpenLayers.String.camelize(style)];\n            if (!value) {\n                if (document.defaultView && \n                    document.defaultView.getComputedStyle) {\n                    \n                    var css = document.defaultView.getComputedStyle(element, null);\n                    value = css ? css.getPropertyValue(style) : null;\n                } else if (element.currentStyle) {\n                    value = element.currentStyle[OpenLayers.String.camelize(style)];\n                }\n            }\n        \n            var positions = ['left', 'top', 'right', 'bottom'];\n            if (window.opera &&\n                (OpenLayers.Util.indexOf(positions,style) != -1) &&\n                (OpenLayers.Element.getStyle(element, 'position') == 'static')) { \n                value = 'auto';\n            }\n        }\n    \n        return value == 'auto' ? null : value;\n    }\n\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/BaseTypes/LonLat.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.LonLat = OpenLayers.Class({\n\n        lon: 0.0,\n    \n        lat: 0.0,\n\n        initialize: function(lon, lat) {\n        if (OpenLayers.Util.isArray(lon)) {\n            lat = lon[1];\n            lon = lon[0];\n        }\n        this.lon = OpenLayers.Util.toFloat(lon);\n        this.lat = OpenLayers.Util.toFloat(lat);\n    },\n    \n        toString:function() {\n        return (\"lon=\" + this.lon + \",lat=\" + this.lat);\n    },\n\n        toShortString:function() {\n        return (this.lon + \", \" + this.lat);\n    },\n\n        clone:function() {\n        return new OpenLayers.LonLat(this.lon, this.lat);\n    },\n\n        add:function(lon, lat) {\n        if ( (lon == null) || (lat == null) ) {\n            throw new TypeError('LonLat.add cannot receive null values');\n        }\n        return new OpenLayers.LonLat(this.lon + OpenLayers.Util.toFloat(lon), \n                                     this.lat + OpenLayers.Util.toFloat(lat));\n    },\n\n        equals:function(ll) {\n        var equals = false;\n        if (ll != null) {\n            equals = ((this.lon == ll.lon && this.lat == ll.lat) ||\n                      (isNaN(this.lon) && isNaN(this.lat) && isNaN(ll.lon) && isNaN(ll.lat)));\n        }\n        return equals;\n    },\n\n        transform: function(source, dest) {\n        var point = OpenLayers.Projection.transform(\n            {'x': this.lon, 'y': this.lat}, source, dest);\n        this.lon = point.x;\n        this.lat = point.y;\n        return this;\n    },\n    \n        wrapDateLine: function(maxExtent) {    \n\n        var newLonLat = this.clone();\n    \n        if (maxExtent) {\n            while (newLonLat.lon < maxExtent.left) {\n                newLonLat.lon +=  maxExtent.getWidth();\n            }    \n            while (newLonLat.lon > maxExtent.right) {\n                newLonLat.lon -= maxExtent.getWidth();\n            }    \n        }\n                \n        return newLonLat;\n    },\n\n    CLASS_NAME: \"OpenLayers.LonLat\"\n});\n\nOpenLayers.LonLat.fromString = function(str) {\n    var pair = str.split(\",\");\n    return new OpenLayers.LonLat(pair[0], pair[1]);\n};\n\nOpenLayers.LonLat.fromArray = function(arr) {\n    var gotArr = OpenLayers.Util.isArray(arr),\n        lon = gotArr && arr[0],\n        lat = gotArr && arr[1];\n    return new OpenLayers.LonLat(lon, lat);\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/BaseTypes/Pixel.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Pixel = OpenLayers.Class({\n    \n        x: 0.0,\n\n        y: 0.0,\n    \n        initialize: function(x, y) {\n        this.x = parseFloat(x);\n        this.y = parseFloat(y);\n    },\n    \n        toString:function() {\n        return (\"x=\" + this.x + \",y=\" + this.y);\n    },\n\n        clone:function() {\n        return new OpenLayers.Pixel(this.x, this.y); \n    },\n    \n        equals:function(px) {\n        var equals = false;\n        if (px != null) {\n            equals = ((this.x == px.x && this.y == px.y) ||\n                      (isNaN(this.x) && isNaN(this.y) && isNaN(px.x) && isNaN(px.y)));\n        }\n        return equals;\n    },\n\n        distanceTo:function(px) {\n        return Math.sqrt(\n            Math.pow(this.x - px.x, 2) +\n            Math.pow(this.y - px.y, 2)\n        );\n    },\n\n        add:function(x, y) {\n        if ( (x == null) || (y == null) ) {\n            throw new TypeError('Pixel.add cannot receive null values');\n        }\n        return new OpenLayers.Pixel(this.x + x, this.y + y);\n    },\n\n        offset:function(px) {\n        var newPx = this.clone();\n        if (px) {\n            newPx = this.add(px.x, px.y);\n        }\n        return newPx;\n    },\n\n    CLASS_NAME: \"OpenLayers.Pixel\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/BaseTypes/Size.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Size = OpenLayers.Class({\n\n        w: 0.0,\n    \n        h: 0.0,\n\n\n        initialize: function(w, h) {\n        this.w = parseFloat(w);\n        this.h = parseFloat(h);\n    },\n\n        toString:function() {\n        return (\"w=\" + this.w + \",h=\" + this.h);\n    },\n\n        clone:function() {\n        return new OpenLayers.Size(this.w, this.h);\n    },\n\n        equals:function(sz) {\n        var equals = false;\n        if (sz != null) {\n            equals = ((this.w == sz.w && this.h == sz.h) ||\n                      (isNaN(this.w) && isNaN(this.h) && isNaN(sz.w) && isNaN(sz.h)));\n        }\n        return equals;\n    },\n\n    CLASS_NAME: \"OpenLayers.Size\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/BaseTypes.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.String = {\n\n        startsWith: function(str, sub) {\n        return (str.indexOf(sub) == 0);\n    },\n\n        contains: function(str, sub) {\n        return (str.indexOf(sub) != -1);\n    },\n    \n        trim: function(str) {\n        return str.replace(/^\\s\\s*/, '').replace(/\\s\\s*$/, '');\n    },\n    \n        camelize: function(str) {\n        var oStringList = str.split('-');\n        var camelizedString = oStringList[0];\n        for (var i=1, len=oStringList.length; i<len; i++) {\n            var s = oStringList[i];\n            camelizedString += s.charAt(0).toUpperCase() + s.substring(1);\n        }\n        return camelizedString;\n    },\n    \n        format: function(template, context, args) {\n        if(!context) {\n            context = window;\n        }\n        var replacer = function(str, match) {\n            var replacement;\n            var subs = match.split(/\\.+/);\n            for (var i=0; i< subs.length; i++) {\n                if (i == 0) {\n                    replacement = context;\n                }\n                if (replacement === undefined) {\n                    break;\n                }\n                replacement = replacement[subs[i]];\n            }\n\n            if(typeof replacement == \"function\") {\n                replacement = args ?\n                    replacement.apply(null, args) :\n                    replacement();\n            }\n            if (typeof replacement == 'undefined') {\n                return 'undefined';\n            } else {\n                return replacement; \n            }\n        };\n\n        return template.replace(OpenLayers.String.tokenRegEx, replacer);\n    },\n\n        tokenRegEx:  /\\$\\{([\\w.]+?)\\}/g,\n    \n        numberRegEx: /^([+-]?)(?=\\d|\\.\\d)\\d*(\\.\\d*)?([Ee]([+-]?\\d+))?$/,\n    \n        isNumeric: function(value) {\n        return OpenLayers.String.numberRegEx.test(value);\n    },\n    \n        numericIf: function(value, trimWhitespace) {\n        var originalValue = value;\n        if (trimWhitespace === true && value != null && value.replace) {\n            value = value.replace(/^\\s*|\\s*$/g, \"\");\n        }\n        return OpenLayers.String.isNumeric(value) ? parseFloat(value) : originalValue;\n    }\n\n};\n\nOpenLayers.Number = {\n\n        decimalSeparator: \".\",\n    \n        thousandsSeparator: \",\",\n    \n        limitSigDigs: function(num, sig) {\n        var fig = 0;\n        if (sig > 0) {\n            fig = parseFloat(num.toPrecision(sig));\n        }\n        return fig;\n    },\n    \n        format: function(num, dec, tsep, dsep) {\n        dec = (typeof dec != \"undefined\") ? dec : 0; \n        tsep = (typeof tsep != \"undefined\") ? tsep :\n            OpenLayers.Number.thousandsSeparator; \n        dsep = (typeof dsep != \"undefined\") ? dsep :\n            OpenLayers.Number.decimalSeparator;\n\n        if (dec != null) {\n            num = parseFloat(num.toFixed(dec));\n        }\n\n        var parts = num.toString().split(\".\");\n        if (parts.length == 1 && dec == null) {\n            dec = 0;\n        }\n        \n        var integer = parts[0];\n        if (tsep) {\n            var thousands = /(-?[0-9]+)([0-9]{3})/; \n            while(thousands.test(integer)) { \n                integer = integer.replace(thousands, \"$1\" + tsep + \"$2\"); \n            }\n        }\n        \n        var str;\n        if (dec == 0) {\n            str = integer;\n        } else {\n            var rem = parts.length > 1 ? parts[1] : \"0\";\n            if (dec != null) {\n                rem = rem + new Array(dec - rem.length + 1).join(\"0\");\n            }\n            str = integer + dsep + rem;\n        }\n        return str;\n    },\n\n        zeroPad: function(num, len, radix) {\n        var str = num.toString(radix || 10);\n        while (str.length < len) {\n            str = \"0\" + str;\n        }\n        return str;\n    }    \n};\n\nOpenLayers.Function = {\n        bind: function(func, object) {\n        var args = Array.prototype.slice.call(arguments, 2);\n        return function() {\n            var newArgs = args.concat(\n                Array.prototype.slice.call(arguments, 0)\n            );\n            return func.apply(object, newArgs);\n        };\n    },\n    \n        bindAsEventListener: function(func, object) {\n        return function(event) {\n            return func.call(object, event || window.event);\n        };\n    },\n    \n        False : function() {\n        return false;\n    },\n\n        True : function() {\n        return true;\n    },\n    \n        Void: function() {}\n\n};\n\nOpenLayers.Array = {\n\n        filter: function(array, callback, caller) {\n        var selected = [];\n        if (Array.prototype.filter) {\n            selected = array.filter(callback, caller);\n        } else {\n            var len = array.length;\n            if (typeof callback != \"function\") {\n                throw new TypeError();\n            }\n            for(var i=0; i<len; i++) {\n                if (i in array) {\n                    var val = array[i];\n                    if (callback.call(caller, val, i, array)) {\n                        selected.push(val);\n                    }\n                }\n            }        \n        }\n        return selected;\n    }\n    \n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Console.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Console = {\n        \n        log: function() {},\n\n        debug: function() {},\n\n        info: function() {},\n\n        warn: function() {},\n\n        error: function() {},\n    \n        userError: function(error) {\n        alert(error);\n    },\n\n        assert: function() {},\n\n        dir: function() {},\n\n        dirxml: function() {},\n\n        trace: function() {},\n\n        group: function() {},\n\n        groupEnd: function() {},\n    \n        time: function() {},\n\n        timeEnd: function() {},\n\n        profile: function() {},\n\n        profileEnd: function() {},\n\n        count: function() {},\n\n    CLASS_NAME: \"OpenLayers.Console\"\n};\n\n(function() {\n        var scripts = document.getElementsByTagName(\"script\");\n    for(var i=0, len=scripts.length; i<len; ++i) {\n        if(scripts[i].src.indexOf(\"firebug.js\") != -1) {\n            if(console) {\n                OpenLayers.Util.extend(OpenLayers.Console, console);\n                break;\n            }\n        }\n    }\n})();\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/ArgParser.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Control.ArgParser = OpenLayers.Class(OpenLayers.Control, {\n\n        center: null,\n    \n        zoom: null,\n\n        layers: null,\n    \n        displayProjection: null, \n\n    \n        setMap: function(map) {\n        OpenLayers.Control.prototype.setMap.apply(this, arguments);\n        for(var i=0, len=this.map.controls.length; i<len; i++) {\n            var control = this.map.controls[i];\n            if ( (control != this) &&\n                 (control.CLASS_NAME == \"OpenLayers.Control.ArgParser\") ) {\n                if (control.displayProjection != this.displayProjection) {\n                    this.displayProjection = control.displayProjection;\n                }    \n                \n                break;\n            }\n        }\n        if (i == this.map.controls.length) {\n\n            var args = this.getParameters();\n            if (args.layers) {\n                this.layers = args.layers;\n                this.map.events.register('addlayer', this, \n                                         this.configureLayers);\n                this.configureLayers();\n            }\n            if (args.lat && args.lon) {\n                this.center = new OpenLayers.LonLat(parseFloat(args.lon),\n                                                    parseFloat(args.lat));\n                if (args.zoom) {\n                    this.zoom = parseFloat(args.zoom);\n                }\n                this.map.events.register('changebaselayer', this, \n                                         this.setCenter);\n                this.setCenter();\n            }\n        }\n    },\n   \n        setCenter: function() {\n        \n        if (this.map.baseLayer) {\n            this.map.events.unregister('changebaselayer', this, \n                                       this.setCenter);\n            \n            if (this.displayProjection) {\n                this.center.transform(this.displayProjection, \n                                      this.map.getProjectionObject()); \n            }      \n\n            this.map.setCenter(this.center, this.zoom);\n        }\n    },\n\n        configureLayers: function() {\n\n        if (this.layers.length == this.map.layers.length) { \n            this.map.events.unregister('addlayer', this, this.configureLayers);\n\n            for(var i=0, len=this.layers.length; i<len; i++) {\n                \n                var layer = this.map.layers[i];\n                var c = this.layers.charAt(i);\n                \n                if (c == \"B\") {\n                    this.map.setBaseLayer(layer);\n                } else if ( (c == \"T\") || (c == \"F\") ) {\n                    layer.setVisibility(c == \"T\");\n                }\n            }\n        }\n    },     \n\n    CLASS_NAME: \"OpenLayers.Control.ArgParser\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/Attribution.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.Attribution = \n  OpenLayers.Class(OpenLayers.Control, {\n    \n        separator: \", \",\n\n        template: \"${layers}\",\n\n        layerTemplate: '<a href=\"${href}\" target=\"_blank\">${title}</a>',\n\n    \n        destroy: function() {\n        this.map.events.un({\n            \"removelayer\": this.updateAttribution,\n            \"addlayer\": this.updateAttribution,\n            \"changelayer\": this.updateAttribution,\n            \"changebaselayer\": this.updateAttribution,\n            scope: this\n        });\n        \n        OpenLayers.Control.prototype.destroy.apply(this, arguments);\n    },    \n    \n        updateAttribution: function() {\n        var attributions = [], attribution;\n        if (this.map && this.map.layers) {\n            for(var i=0, len=this.map.layers.length; i<len; i++) {\n                var layer = this.map.layers[i];\n                if (layer.attribution && layer.getVisibility()) {\n                    attribution = (typeof layer.attribution == \"object\") ?\n                        OpenLayers.String.format(\n                            this.layerTemplate, layer.attribution) :\n                        layer.attribution;\n                    if (OpenLayers.Util.indexOf(\n                                    attributions, attribution) === -1) {\n                        attributions.push( attribution );\n                    }\n                }\n            } \n            this.div.innerHTML = OpenLayers.String.format(this.template, {\n                layers: attributions.join(this.separator)\n            });\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.Attribution\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/Button.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.Button = OpenLayers.Class(OpenLayers.Control, {\n        type: OpenLayers.Control.TYPE_BUTTON,\n    \n        trigger: function() {},\n\n    CLASS_NAME: \"OpenLayers.Control.Button\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/CacheRead.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.CacheRead = OpenLayers.Class(OpenLayers.Control, {\n    \n        fetchEvent: \"tileloadstart\",\n    \n        layers: null,\n    \n        autoActivate: true,\n\n        \n        setMap: function(map) {\n        OpenLayers.Control.prototype.setMap.apply(this, arguments);\n        var i, layers = this.layers || map.layers;\n        for (i=layers.length-1; i>=0; --i) {\n            this.addLayer({layer: layers[i]});\n        }\n        if (!this.layers) {\n            map.events.on({\n                addlayer: this.addLayer,\n                removeLayer: this.removeLayer,\n                scope: this\n            });\n        }\n    },\n    \n        addLayer: function(evt) {\n        evt.layer.events.register(this.fetchEvent, this, this.fetch);        \n    },\n    \n        removeLayer: function(evt) {\n        evt.layer.events.unregister(this.fetchEvent, this, this.fetch);\n    },\n    \n        fetch: function(evt) {\n        if (this.active && window.localStorage &&\n                evt.tile instanceof OpenLayers.Tile.Image) {\n            var tile = evt.tile,\n                url = tile.url;\n            if (!tile.layer.crossOriginKeyword && OpenLayers.ProxyHost &&\n                    url.indexOf(OpenLayers.ProxyHost) === 0) {\n                url = OpenLayers.Control.CacheWrite.urlMap[url];        \n            }\n            var dataURI = window.localStorage.getItem(\"olCache_\" + url);\n            if (dataURI) {\n                tile.url = dataURI;\n                if (evt.type === \"tileerror\") {\n                    tile.setImgSrc(dataURI);\n                }\n            }\n        }\n    },\n    \n        destroy: function() {\n        if (this.layers || this.map) {\n            var i, layers = this.layers || this.map.layers;\n            for (i=layers.length-1; i>=0; --i) {\n                this.removeLayer({layer: layers[i]});\n            }\n        }\n        if (this.map) {\n            this.map.events.un({\n                addlayer: this.addLayer,\n                removeLayer: this.removeLayer,\n                scope: this\n            });\n        }\n        OpenLayers.Control.prototype.destroy.apply(this, arguments);\n    },\n    \n    CLASS_NAME: \"OpenLayers.Control.CacheRead\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/CacheWrite.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.CacheWrite = OpenLayers.Class(OpenLayers.Control, {\n    \n        \n    \n        layers: null,\n    \n        imageFormat: \"image/png\",\n    \n        quotaRegEx: (/quota/i),\n    \n    \n        setMap: function(map) {\n        OpenLayers.Control.prototype.setMap.apply(this, arguments);\n        var i, layers = this.layers || map.layers;\n        for (i=layers.length-1; i>=0; --i) {\n            this.addLayer({layer: layers[i]});\n        }\n        if (!this.layers) {\n            map.events.on({\n                addlayer: this.addLayer,\n                removeLayer: this.removeLayer,\n                scope: this\n            });\n        }\n    },\n    \n        addLayer: function(evt) {\n        evt.layer.events.on({\n            tileloadstart: this.makeSameOrigin,\n            tileloaded: this.onTileLoaded,\n            scope: this\n        });        \n    },\n    \n        removeLayer: function(evt) {\n        evt.layer.events.un({\n            tileloadstart: this.makeSameOrigin,\n            tileloaded: this.onTileLoaded,\n            scope: this\n        });\n    },\n\n        makeSameOrigin: function(evt) {\n        if (this.active) {\n            var tile = evt.tile;\n            if (tile instanceof OpenLayers.Tile.Image &&\n                    !tile.crossOriginKeyword &&\n                    tile.url.substr(0, 5) !== \"data:\") {\n                var sameOriginUrl = OpenLayers.Request.makeSameOrigin(\n                    tile.url, OpenLayers.ProxyHost\n                );\n                OpenLayers.Control.CacheWrite.urlMap[sameOriginUrl] = tile.url;\n                tile.url = sameOriginUrl;\n            }\n        }\n    },\n    \n        onTileLoaded: function(evt) {\n        if (this.active && !evt.aborted &&\n                evt.tile instanceof OpenLayers.Tile.Image &&\n                evt.tile.url.substr(0, 5) !== 'data:') {\n            this.cache({tile: evt.tile});\n            delete OpenLayers.Control.CacheWrite.urlMap[evt.tile.url];\n        }\n    },\n    \n        cache: function(obj) {\n        if (window.localStorage) {\n            var tile = obj.tile;\n            try {\n                var canvasContext = tile.getCanvasContext();\n                if (canvasContext) {\n                    var urlMap = OpenLayers.Control.CacheWrite.urlMap;\n                    var url = urlMap[tile.url] || tile.url;\n                    window.localStorage.setItem(\n                        \"olCache_\" + url,\n                        canvasContext.canvas.toDataURL(this.imageFormat)\n                    );\n                }\n            } catch(e) {\n                var reason = e.name || e.message;\n                if (reason && this.quotaRegEx.test(reason)) {\n                    this.events.triggerEvent(\"cachefull\", {tile: tile});\n                } else {\n                    OpenLayers.Console.error(e.toString());\n                }\n            }\n        }\n    },\n    \n        destroy: function() {\n        if (this.layers || this.map) {\n            var i, layers = this.layers || this.map.layers;\n            for (i=layers.length-1; i>=0; --i) {\n                this.removeLayer({layer: layers[i]});\n            }\n        }\n        if (this.map) {\n            this.map.events.un({\n                addlayer: this.addLayer,\n                removeLayer: this.removeLayer,\n                scope: this\n            });\n        }\n        OpenLayers.Control.prototype.destroy.apply(this, arguments);\n    },\n    \n    CLASS_NAME: \"OpenLayers.Control.CacheWrite\"\n});\n\nOpenLayers.Control.CacheWrite.clearCache = function() {\n    if (!window.localStorage) { return; }\n    var i, key;\n    for (i=window.localStorage.length-1; i>=0; --i) {\n        key = window.localStorage.key(i);\n        if (key.substr(0, 8) === \"olCache_\") {\n            window.localStorage.removeItem(key);\n        }\n    }\n};\n\nOpenLayers.Control.CacheWrite.urlMap = {};\n\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/DragFeature.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Control.DragFeature = OpenLayers.Class(OpenLayers.Control, {\n\n        geometryTypes: null,\n    \n        onStart: function(feature, pixel) {},\n\n        onDrag: function(feature, pixel) {},\n\n        onComplete: function(feature, pixel) {},\n\n        onEnter: function(feature) {},\n\n        onLeave: function(feature) {},\n\n        documentDrag: false,\n    \n        layer: null,\n    \n        feature: null,\n\n        dragCallbacks: {},\n\n        featureCallbacks: {},\n    \n        lastPixel: null,\n\n        initialize: function(layer, options) {\n        OpenLayers.Control.prototype.initialize.apply(this, [options]);\n        this.layer = layer;\n        this.handlers = {\n            drag: new OpenLayers.Handler.Drag(\n                this, OpenLayers.Util.extend({\n                    down: this.downFeature,\n                    move: this.moveFeature,\n                    up: this.upFeature,\n                    out: this.cancel,\n                    done: this.doneDragging\n                }, this.dragCallbacks), {\n                    documentDrag: this.documentDrag\n                }\n            ),\n            feature: new OpenLayers.Handler.Feature(\n                this, this.layer, OpenLayers.Util.extend({\n                    click: this.clickFeature,\n                    clickout: this.clickoutFeature,\n                    over: this.overFeature,\n                    out: this.outFeature\n                }, this.featureCallbacks),\n                {geometryTypes: this.geometryTypes}\n            )\n        };\n    },\n\n        clickFeature: function(feature) {\n        if (this.handlers.feature.touch && !this.over && this.overFeature(feature)) {\n            this.handlers.drag.dragstart(this.handlers.feature.evt);\n            this.handlers.drag.stopDown = false;\n        }\n    },\n\n        clickoutFeature: function(feature) {\n        if (this.handlers.feature.touch && this.over) {\n            this.outFeature(feature);\n            this.handlers.drag.stopDown = true;\n        }\n    },\n\n        destroy: function() {\n        this.layer = null;\n        OpenLayers.Control.prototype.destroy.apply(this, []);\n    },\n\n        activate: function() {\n        return (this.handlers.feature.activate() &&\n                OpenLayers.Control.prototype.activate.apply(this, arguments));\n    },\n\n        deactivate: function() {\n        this.handlers.drag.deactivate();\n        this.handlers.feature.deactivate();\n        this.feature = null;\n        this.dragging = false;\n        this.lastPixel = null;\n        OpenLayers.Element.removeClass(\n            this.map.viewPortDiv, this.displayClass + \"Over\"\n        );\n        return OpenLayers.Control.prototype.deactivate.apply(this, arguments);\n    },\n\n        overFeature: function(feature) {\n        var activated = false;\n        if(!this.handlers.drag.dragging) {\n            this.feature = feature;\n            this.handlers.drag.activate();\n            activated = true;\n            this.over = true;\n            OpenLayers.Element.addClass(this.map.viewPortDiv, this.displayClass + \"Over\");\n            this.onEnter(feature);\n        } else {\n            if(this.feature.id == feature.id) {\n                this.over = true;\n            } else {\n                this.over = false;\n            }\n        }\n        return activated;\n    },\n\n        downFeature: function(pixel) {\n        this.lastPixel = pixel;\n        this.onStart(this.feature, pixel);\n    },\n\n        moveFeature: function(pixel) {\n        var res = this.map.getResolution();\n        this.feature.geometry.move(res * (pixel.x - this.lastPixel.x),\n                                   res * (this.lastPixel.y - pixel.y));\n        this.layer.drawFeature(this.feature);\n        this.lastPixel = pixel;\n        this.onDrag(this.feature, pixel);\n    },\n\n        upFeature: function(pixel) {\n        if(!this.over) {\n            this.handlers.drag.deactivate();\n        }\n    },\n\n        doneDragging: function(pixel) {\n        this.onComplete(this.feature, pixel);\n    },\n\n        outFeature: function(feature) {\n        if(!this.handlers.drag.dragging) {\n            this.over = false;\n            this.handlers.drag.deactivate();\n            OpenLayers.Element.removeClass(\n                this.map.viewPortDiv, this.displayClass + \"Over\"\n            );\n            this.onLeave(feature);\n            this.feature = null;\n        } else {\n            if(this.feature.id == feature.id) {\n                this.over = false;\n            }\n        }\n    },\n        \n        cancel: function() {\n        this.handlers.drag.deactivate();\n        this.over = false;\n    },\n\n        setMap: function(map) {\n        this.handlers.drag.setMap(map);\n        this.handlers.feature.setMap(map);\n        OpenLayers.Control.prototype.setMap.apply(this, arguments);\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.DragFeature\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/DragPan.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.DragPan = OpenLayers.Class(OpenLayers.Control, {\n\n        type: OpenLayers.Control.TYPE_TOOL,\n    \n        panned: false,\n    \n        interval: 0,\n    \n        documentDrag: false,\n\n        kinetic: null,\n\n        enableKinetic: true,\n\n        kineticInterval: 10,\n\n\n        panMapStart: function() {\n        if(this.kinetic) {\n            this.kinetic.begin();\n        }\n    },\n\n        panMap: function(xy) {\n        if(this.kinetic) {\n            this.kinetic.update(xy);\n        }\n        this.panned = true;\n        this.map.pan(\n            this.handler.last.x - xy.x,\n            this.handler.last.y - xy.y,\n            {dragging: true, animate: false}\n        );\n    },\n    \n        panMapDone: function(xy) {\n        if(this.panned) {\n            var res = null;\n            if (this.kinetic) {\n                res = this.kinetic.end(xy);\n            }\n            this.map.pan(\n                this.handler.last.x - xy.x,\n                this.handler.last.y - xy.y,\n                {dragging: !!res, animate: false}\n            );\n            if (res) {\n                var self = this;\n                this.kinetic.move(res, function(x, y, end) {\n                    self.map.pan(x, y, {dragging: !end, animate: false});\n                });\n            }\n            this.panned = false;\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.DragPan\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/DrawFeature.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Control.DrawFeature = OpenLayers.Class(OpenLayers.Control, {\n    \n        layer: null,\n\n        callbacks: null,\n    \n        \n        multi: false,\n\n        featureAdded: function() {},\n\n        \n        initialize: function(layer, handler, options) {\n        OpenLayers.Control.prototype.initialize.apply(this, [options]);\n        this.callbacks = OpenLayers.Util.extend(\n            {\n                done: this.drawFeature,\n                modify: function(vertex, feature) {\n                    this.layer.events.triggerEvent(\n                        \"sketchmodified\", {vertex: vertex, feature: feature}\n                    );\n                },\n                create: function(vertex, feature) {\n                    this.layer.events.triggerEvent(\n                        \"sketchstarted\", {vertex: vertex, feature: feature}\n                    );\n                }\n            },\n            this.callbacks\n        );\n        this.layer = layer;\n        this.handlerOptions = this.handlerOptions || {};\n        this.handlerOptions.layerOptions = OpenLayers.Util.applyDefaults(\n            this.handlerOptions.layerOptions, {\n                renderers: layer.renderers, rendererOptions: layer.rendererOptions\n            }\n        );\n        if (!(\"multi\" in this.handlerOptions)) {\n            this.handlerOptions.multi = this.multi;\n        }\n        var sketchStyle = this.layer.styleMap && this.layer.styleMap.styles.temporary;\n        if(sketchStyle) {\n            this.handlerOptions.layerOptions = OpenLayers.Util.applyDefaults(\n                this.handlerOptions.layerOptions,\n                {styleMap: new OpenLayers.StyleMap({\"default\": sketchStyle})}\n            );\n        }\n        this.handler = new handler(this, this.callbacks, this.handlerOptions);\n    },\n\n        drawFeature: function(geometry) {\n        var feature = new OpenLayers.Feature.Vector(geometry);\n        var proceed = this.layer.events.triggerEvent(\n            \"sketchcomplete\", {feature: feature}\n        );\n        if(proceed !== false) {\n            feature.state = OpenLayers.State.INSERT;\n            this.layer.addFeatures([feature]);\n            this.featureAdded(feature);\n            this.events.triggerEvent(\"featureadded\",{feature : feature});\n        }\n    },\n    \n        insertXY: function(x, y) {\n        if (this.handler && this.handler.line) {\n            this.handler.insertXY(x, y);\n        }\n    },\n\n        insertDeltaXY: function(dx, dy) {\n        if (this.handler && this.handler.line) {\n            this.handler.insertDeltaXY(dx, dy);\n        }\n    },\n\n        insertDirectionLength: function(direction, length) {\n        if (this.handler && this.handler.line) {\n            this.handler.insertDirectionLength(direction, length);\n        }\n    },\n\n        insertDeflectionLength: function(deflection, length) {\n        if (this.handler && this.handler.line) {\n            this.handler.insertDeflectionLength(deflection, length);\n        }\n    },\n    \n        undo: function() {\n        return this.handler.undo && this.handler.undo();\n    },\n    \n        redo: function() {\n        return this.handler.redo && this.handler.redo();\n    },\n    \n        finishSketch: function() {\n        this.handler.finishGeometry();\n    },\n\n        cancel: function() {\n        this.handler.cancel();\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.DrawFeature\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/EditingToolbar.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.EditingToolbar = OpenLayers.Class(\n  OpenLayers.Control.Panel, {\n\n        citeCompliant: false,\n\n        initialize: function(layer, options) {\n        OpenLayers.Control.Panel.prototype.initialize.apply(this, [options]);\n        \n        this.addControls(\n          [ new OpenLayers.Control.Navigation() ]\n        );  \n        var controls = [\n            new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Point, {\n                displayClass: 'olControlDrawFeaturePoint',\n                handlerOptions: {citeCompliant: this.citeCompliant}\n            }),\n            new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Path, {\n                displayClass: 'olControlDrawFeaturePath',\n                handlerOptions: {citeCompliant: this.citeCompliant}\n            }),\n            new OpenLayers.Control.DrawFeature(layer, OpenLayers.Handler.Polygon, {\n                displayClass: 'olControlDrawFeaturePolygon',\n                handlerOptions: {citeCompliant: this.citeCompliant}\n            })\n        ];\n        this.addControls(controls);\n    },\n\n        draw: function() {\n        var div = OpenLayers.Control.Panel.prototype.draw.apply(this, arguments);\n        if (this.defaultControl === null) {\n            this.defaultControl = this.controls[0];\n        }\n        return div;\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.EditingToolbar\"\n});    \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/Geolocate.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.Geolocate = OpenLayers.Class(OpenLayers.Control, {\n\n    \n        geolocation: null,\n\n        available: ('geolocation' in navigator),\n\n        bind: true,\n\n        watch: false,\n\n        geolocationOptions: null,\n\n    \n        destroy: function() {\n        this.deactivate();\n        OpenLayers.Control.prototype.destroy.apply(this, arguments);\n    },\n\n        activate: function () {\n        if (this.available && !this.geolocation) {\n            this.geolocation = navigator.geolocation;\n        }\n        if (!this.geolocation) {\n            this.events.triggerEvent(\"locationuncapable\");\n            return false;\n        }\n        if (OpenLayers.Control.prototype.activate.apply(this, arguments)) {\n            if (this.watch) {\n                this.watchId = this.geolocation.watchPosition(\n                    OpenLayers.Function.bind(this.geolocate, this),\n                    OpenLayers.Function.bind(this.failure, this),\n                    this.geolocationOptions\n                );\n            } else {\n                this.getCurrentLocation();\n            }\n            return true;\n        }\n        return false;\n    },\n\n        deactivate: function () {\n        if (this.active && this.watchId !== null) {\n            this.geolocation.clearWatch(this.watchId);\n        }\n        return OpenLayers.Control.prototype.deactivate.apply(\n            this, arguments\n        );\n    },\n\n        geolocate: function (position) {\n        var center = new OpenLayers.LonLat(\n            position.coords.longitude,\n            position.coords.latitude\n        ).transform(\n            new OpenLayers.Projection(\"EPSG:4326\"),\n            this.map.getProjectionObject()\n        );\n        if (this.bind) {\n            this.map.setCenter(center);\n        }\n        this.events.triggerEvent(\"locationupdated\", {\n            position: position,\n            point: new OpenLayers.Geometry.Point(\n                center.lon, center.lat\n            )\n        });\n    },\n\n        getCurrentLocation: function() {\n        if (!this.active || this.watch) {\n            return false;\n        }\n        this.geolocation.getCurrentPosition(\n            OpenLayers.Function.bind(this.geolocate, this),\n            OpenLayers.Function.bind(this.failure, this),\n            this.geolocationOptions\n        );\n        return true;\n    },\n\n        failure: function (error) {\n        this.events.triggerEvent(\"locationfailed\", {error: error});\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.Geolocate\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/GetFeature.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.GetFeature = OpenLayers.Class(OpenLayers.Control, {\n    \n        protocol: null,\n    \n        multipleKey: null,\n    \n        toggleKey: null,\n    \n        modifiers: null,\n    \n        multiple: false, \n\n        click: true,\n\n        single: true,\n    \n        clickout: true,\n    \n        toggle: false,\n\n        clickTolerance: 5,\n    \n        hover: false,\n\n        box: false,\n    \n        maxFeatures: 10,\n    \n        features: null,\n    \n        hoverFeature: null,\n    \n        \n        handlers: null,\n\n        hoverResponse: null,\n    \n        filterType: OpenLayers.Filter.Spatial.BBOX,\n\n    \n        initialize: function(options) {\n        options.handlerOptions = options.handlerOptions || {};\n\n        OpenLayers.Control.prototype.initialize.apply(this, [options]);\n        \n        this.features = {};\n\n        this.handlers = {};\n        \n        if(this.click) {\n            this.handlers.click = new OpenLayers.Handler.Click(this,\n                {click: this.selectClick}, this.handlerOptions.click || {});\n        }\n\n        if(this.box) {\n            this.handlers.box = new OpenLayers.Handler.Box(\n                this, {done: this.selectBox},\n                OpenLayers.Util.extend(this.handlerOptions.box, {\n                    boxDivClassName: \"olHandlerBoxSelectFeature\"\n                })\n            ); \n        }\n        \n        if(this.hover) {\n            this.handlers.hover = new OpenLayers.Handler.Hover(\n                this, {'move': this.cancelHover, 'pause': this.selectHover},\n                OpenLayers.Util.applyDefaults(this.handlerOptions.hover, {\n                    'delay': 250,\n                    'pixelTolerance': 2\n                })\n            );\n        }\n    },\n    \n        activate: function () {\n        if (!this.active) {\n            for(var i in this.handlers) {\n                this.handlers[i].activate();\n            }\n        }\n        return OpenLayers.Control.prototype.activate.apply(\n            this, arguments\n        );\n    },\n\n        deactivate: function () {\n        if (this.active) {\n            for(var i in this.handlers) {\n                this.handlers[i].deactivate();\n            }\n        }\n        return OpenLayers.Control.prototype.deactivate.apply(\n            this, arguments\n        );\n    },\n    \n        selectClick: function(evt) {\n        var bounds = this.pixelToBounds(evt.xy);\n        \n        this.setModifiers(evt);\n        this.request(bounds, {single: this.single});\n    },\n\n        selectBox: function(position) {\n        var bounds;\n        if (position instanceof OpenLayers.Bounds) {\n            var minXY = this.map.getLonLatFromPixel({\n                x: position.left,\n                y: position.bottom\n            });\n            var maxXY = this.map.getLonLatFromPixel({\n                x: position.right,\n                y: position.top\n            });\n            bounds = new OpenLayers.Bounds(\n                minXY.lon, minXY.lat, maxXY.lon, maxXY.lat\n            );\n            \n        } else {\n            if(this.click) {\n                return;\n            }\n            bounds = this.pixelToBounds(position);\n        }\n        this.setModifiers(this.handlers.box.dragHandler.evt);\n        this.request(bounds);\n    },\n    \n        selectHover: function(evt) {\n        var bounds = this.pixelToBounds(evt.xy);\n        this.request(bounds, {single: true, hover: true});\n    },\n\n        cancelHover: function() {\n        if (this.hoverResponse) {\n            this.protocol.abort(this.hoverResponse);\n            this.hoverResponse = null;\n\n            OpenLayers.Element.removeClass(this.map.viewPortDiv, \"olCursorWait\");\n        }\n    },\n\n        request: function(bounds, options) {\n        options = options || {};\n        var filter = new OpenLayers.Filter.Spatial({\n            type: this.filterType, \n            value: bounds\n        });\n        OpenLayers.Element.addClass(this.map.viewPortDiv, \"olCursorWait\");\n\n        var response = this.protocol.read({\n            maxFeatures: options.single == true ? this.maxFeatures : undefined,\n            filter: filter,\n            callback: function(result) {\n                if(result.success()) {\n                    if(result.features.length) {\n                        if(options.single == true) {\n                            this.selectBestFeature(result.features,\n                                bounds.getCenterLonLat(), options);\n                        } else {\n                            this.select(result.features);\n                        }\n                    } else if(options.hover) {\n                        this.hoverSelect();\n                    } else {\n                        this.events.triggerEvent(\"clickout\");\n                        if(this.clickout) {\n                            this.unselectAll();\n                        }\n                    }\n                }\n                OpenLayers.Element.removeClass(this.map.viewPortDiv, \"olCursorWait\");\n            },\n            scope: this\n        });\n        if(options.hover == true) {\n            this.hoverResponse = response;\n        }\n    },\n\n        selectBestFeature: function(features, clickPosition, options) {\n        options = options || {};\n        if(features.length) {\n            var point = new OpenLayers.Geometry.Point(clickPosition.lon,\n                clickPosition.lat);\n            var feature, resultFeature, dist;\n            var minDist = Number.MAX_VALUE;\n            for(var i=0; i<features.length; ++i) {\n                feature = features[i];\n                if(feature.geometry) {\n                    dist = point.distanceTo(feature.geometry, {edge: false});\n                    if(dist < minDist) {\n                        minDist = dist;\n                        resultFeature = feature;\n                        if(minDist == 0) {\n                            break;\n                        }\n                    }\n                }\n            }\n            \n            if(options.hover == true) {\n                this.hoverSelect(resultFeature);\n            } else {\n                this.select(resultFeature || features);\n            } \n        }\n    },\n    \n        setModifiers: function(evt) {\n        this.modifiers = {\n            multiple: this.multiple || (this.multipleKey && evt[this.multipleKey]),\n            toggle: this.toggle || (this.toggleKey && evt[this.toggleKey])\n        };        \n    },\n\n        select: function(features) {\n        if(!this.modifiers.multiple && !this.modifiers.toggle) {\n            this.unselectAll();\n        }\n        if(!(OpenLayers.Util.isArray(features))) {\n            features = [features];\n        }\n        \n        var cont = this.events.triggerEvent(\"beforefeaturesselected\", {\n            features: features\n        });\n        if(cont !== false) {\n            var selectedFeatures = [];\n            var feature;\n            for(var i=0, len=features.length; i<len; ++i) {\n                feature = features[i];\n                if(this.features[feature.fid || feature.id]) {\n                    if(this.modifiers.toggle) {\n                        this.unselect(this.features[feature.fid || feature.id]);\n                    }\n                } else {\n                    cont = this.events.triggerEvent(\"beforefeatureselected\", {\n                        feature: feature\n                    });\n                    if(cont !== false) {\n                        this.features[feature.fid || feature.id] = feature;\n                        selectedFeatures.push(feature);\n                \n                        this.events.triggerEvent(\"featureselected\",\n                            {feature: feature});\n                    }\n                }\n            }\n            this.events.triggerEvent(\"featuresselected\", {\n                features: selectedFeatures\n            });\n        }\n    },\n    \n        hoverSelect: function(feature) {\n        var fid = feature ? feature.fid || feature.id : null;\n        var hfid = this.hoverFeature ?\n            this.hoverFeature.fid || this.hoverFeature.id : null;\n            \n        if(hfid && hfid != fid) {\n            this.events.triggerEvent(\"outfeature\",\n                {feature: this.hoverFeature});\n            this.hoverFeature = null;\n        }\n        if(fid && fid != hfid) {\n            this.events.triggerEvent(\"hoverfeature\", {feature: feature});\n            this.hoverFeature = feature;\n        }\n    },\n\n        unselect: function(feature) {\n        delete this.features[feature.fid || feature.id];\n        this.events.triggerEvent(\"featureunselected\", {feature: feature});\n    },\n    \n        unselectAll: function() {\n        for(var fid in this.features) {\n            this.unselect(this.features[fid]);\n        }\n    },\n    \n        setMap: function(map) {\n        for(var i in this.handlers) {\n            this.handlers[i].setMap(map);\n        }\n        OpenLayers.Control.prototype.setMap.apply(this, arguments);\n    },\n    \n        pixelToBounds: function(pixel) {\n        var llPx = pixel.add(-this.clickTolerance/2, this.clickTolerance/2);\n        var urPx = pixel.add(this.clickTolerance/2, -this.clickTolerance/2);\n        var ll = this.map.getLonLatFromPixel(llPx);\n        var ur = this.map.getLonLatFromPixel(urPx);\n        return new OpenLayers.Bounds(ll.lon, ll.lat, ur.lon, ur.lat);\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.GetFeature\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/Graticule.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.Graticule = OpenLayers.Class(OpenLayers.Control, {\n\n        autoActivate: true,\n\n        intervals: [90, 45, 30, 20, 10, 5, 2, 1,\n        0.5, 0.2, 0.1, 0.05, 0.01,\n        0.005, 0.002, 0.001\n    ],\n\n        intervalHeights: null,\n\n        intervalHeightFactor: 1,\n\n        displayInLayerSwitcher: true,\n\n        visible: true,\n\n        numPoints: 50,\n\n        targetSize: 200,\n\n        layerName: null,\n\n        labelled: true,\n\n        labelFormat: 'dm',\n\n        labelLonYOffset: 2,\n\n        labelLatXOffset: -2,\n\n        lineSymbolizer: {\n        strokeColor: \"#333\",\n        strokeWidth: 1,\n        strokeOpacity: 0.5\n    },\n\n        labelSymbolizer: null,\n\n        gratLayer: null,\n\n        epsg4326Projection: null,\n\n        projection: null,\n\n        projectionCenterLonLat: null,\n\n        maxLat: Infinity,\n\n        maxLon: Infinity,\n\n        minLat: -Infinity,\n\n        minLon: -Infinity,\n\n        meridians: null,\n\n        parallels: null,\n\n        initialize: function(options) {\n        options = options || {};\n        options.layerName = options.layerName || OpenLayers.i18n(\"Graticule\");\n        OpenLayers.Control.prototype.initialize.apply(this, [options]);\n\n        this.labelSymbolizer = {\n            stroke: false,\n            fill: false,\n            label: \"${label}\",\n            labelAlign: \"${labelAlign}\",\n            labelXOffset: \"${xOffset}\",\n            labelYOffset: \"${yOffset}\"\n        };\n\n        this.epsg4326Projection = new OpenLayers.Projection('EPSG:4326');\n        this.parallels = [];\n        this.meridians = [];\n    },\n\n        destroy: function() {\n        this.deactivate();\n        OpenLayers.Control.prototype.destroy.apply(this, arguments);\n        if (this.gratLayer) {\n            this.gratLayer.destroy();\n            this.gratLayer = null;\n        }\n    },\n\n        draw: function() {\n        OpenLayers.Control.prototype.draw.apply(this, arguments);\n        if (!this.gratLayer) {\n            var gratStyle = new OpenLayers.Style({}, {\n                rules: [new OpenLayers.Rule({\n                    'symbolizer': {\n                        \"Point\": this.labelSymbolizer,\n                        \"Line\": this.lineSymbolizer\n                    }\n                })]\n            });\n            this.gratLayer = new OpenLayers.Layer.Vector(this.layerName, {\n                styleMap: new OpenLayers.StyleMap({\n                    'default': gratStyle\n                }),\n                visibility: this.visible,\n                displayInLayerSwitcher: this.displayInLayerSwitcher,\n                renderers: ['Canvas', 'VML', 'SVG']\n            });\n        }\n        return this.div;\n    },\n\n        activate: function() {\n        if (OpenLayers.Control.prototype.activate.apply(this, arguments)) {\n            this.map.addLayer(this.gratLayer);\n            this.map.events.register('moveend', this, this.update);\n            this.update();\n            return true;\n        } else {\n            return false;\n        }\n    },\n\n        deactivate: function() {\n        if (OpenLayers.Control.prototype.deactivate.apply(this, arguments)) {\n            this.map.events.unregister('moveend', this, this.update);\n            this.map.removeLayer(this.gratLayer);\n            return true;\n        } else {\n            return false;\n        }\n    },\n\n        update: function() {\n        var map = this.map;\n        var extent = this.map.getExtent();\n        if (!extent) {\n            return;\n        }\n        var center = map.getCenter();\n        var projection = map.getProjectionObject();\n        var resolution = map.getResolution();\n        var squaredTolerance = resolution * resolution / 4;\n\n        var updateProjectionInfo = !this.projection || !this.projection.equals(projection);\n\n        if (updateProjectionInfo) {\n            this.updateProjectionInfo(projection);\n        }\n\n        this.createGraticule(extent, center, resolution, squaredTolerance);\n        this.gratLayer.destroyFeatures();\n        this.gratLayer.addFeatures(this.meridians);\n        this.gratLayer.addFeatures(this.parallels);\n        if (this.labelled) {\n            var left = new OpenLayers.Geometry.LineString([\n                new OpenLayers.Geometry.Point(extent.left, extent.bottom),\n                new OpenLayers.Geometry.Point(extent.left, extent.top)\n            ]);\n            var top = new OpenLayers.Geometry.LineString([\n                new OpenLayers.Geometry.Point(extent.left, extent.top),\n                new OpenLayers.Geometry.Point(extent.right, extent.top)\n            ]);\n            var labels = [];\n            var i, ii, line, labelPoint, split, labelAlign;\n            for (i = 0, ii = this.meridians.length; i < ii; ++i) {\n                line = this.meridians[i];\n                labelPoint = line.attributes.labelPoint;\n                labelAlign = 'cb';\n                if (!labelPoint) {\n                    split = line.geometry.split(left);\n                    if (split) {\n                        labelPoint = split[0].components[1];\n                        labelAlign = 'lt';\n                    }\n                }\n                if (labelPoint) {\n                    labels.push(new OpenLayers.Feature.Vector(labelPoint, {\n                        value: line.attributes.lon,\n                        label: OpenLayers.Util.getFormattedLonLat(\n                            line.attributes.lon, 'lon', this.labelFormat),\n                        labelAlign: labelAlign,\n                        xOffset: 0,\n                        yOffset: this.labelLonYOffset\n                    }));\n                }\n            }\n            for (i = 0, ii = this.parallels.length; i < ii; ++i) {\n                line = this.parallels[i];\n                labelPoint = line.attributes.labelPoint;\n                labelAlign = 'rb';\n                if (!labelPoint) {\n                    split = line.geometry.split(top);\n                    if (split) {\n                        labelPoint = split[0].components[1];\n                        labelAlign = 'ct';\n                    }\n                }\n                if (labelPoint) {\n                    labels.push(new OpenLayers.Feature.Vector(labelPoint, {\n                        value: line.attributes.lat,\n                        label: OpenLayers.Util.getFormattedLonLat(\n                            line.attributes.lat, 'lat', this.labelFormat),\n                        labelAlign: labelAlign,\n                        xOffset: this.labelLatXOffset,\n                        yOffset: 2\n                    }));\n                }\n            }\n            this.gratLayer.addFeatures(labels);\n        }\n    },\n\n        createGraticule: function(extent, center, resolution, squaredTolerance) {\n        var centerLonLat = center.clone().transform(\n            this.projection, this.epsg4326Projection);\n        if (isNaN(centerLonLat.lon) || isNaN(centerLonLat.lat)) {\n            centerLonLat = center.add(0.000000001, 0.000000001).transform(\n                this.projection, this.epsg4326Projection);\n        }\n        var extentGeom = extent.toGeometry();\n        var extent4326 = extent.clone()\n            .transform(this.projection, this.epsg4326Projection);\n        var minLon, minLat, maxLon, maxLat;\n        var pixelSize = this.map.getGeodesicPixelSize();\n        if (pixelSize.w < 0.5 && pixelSize.h < 0.5 &&\n                extent4326.right > extent4326.left &&\n                extent4326.top > extent4326.bottom &&\n                Math.abs(extent4326.bottom) / extent4326.bottom ==\n                Math.abs(extent4326.top) / extent4326.top &&\n                Math.abs(extent4326.left) / extent4326.left ==\n                Math.abs(extent4326.right) / extent4326.right) {\n            minLon = Math.max(extent4326.left, this.minLon);\n            minLat = Math.max(extent4326.bottom, this.minLat);\n            maxLon = Math.min(extent4326.right, this.maxLon);\n            maxLat = Math.min(extent4326.top, this.maxLat);\n        } else {\n            minLon = this.minLon;\n            minLat = this.minLat;\n            maxLon = this.maxLon;\n            maxLat = this.maxLat;\n        }\n\n        var size = this.map.getSize();\n        var idx, prevIdx, lon, lat, visibleIntervals, interval, intervalIndex;\n        var centerLon, centerLat;\n        visibleIntervals = Math.ceil(size.w / this.targetSize);\n        intervalIndex = 0;\n        do {\n            interval = this.intervals[intervalIndex++];\n            centerLon = Math.floor(centerLonLat.lon / interval) * interval;\n\n            lon = Math.max(centerLon, this.minLon);\n            lon = Math.min(lon, this.maxLon);\n\n            idx = this.addMeridian(\n                lon, minLat, maxLat, squaredTolerance, extentGeom, 0);\n\n            while (lon != this.minLon) {\n                lon = Math.max(lon - interval, this.minLon);\n                prevIdx = idx;\n                idx = this.addMeridian(\n                    lon, minLat, maxLat, squaredTolerance, extentGeom, idx);\n                if (prevIdx == idx) {\n                    break;\n                }\n            }\n\n            lon = Math.max(centerLon, this.minLon);\n            lon = Math.min(lon, this.maxLon);\n\n            while (lon != this.maxLon) {\n                lon = Math.min(lon + interval, this.maxLon);\n                prevIdx = idx;\n                idx = this.addMeridian(\n                    lon, minLat, maxLat, squaredTolerance, extentGeom, idx);\n                if (prevIdx == idx) {\n                    break;\n                }\n            }\n        } while (intervalIndex < this.intervals.length &&\n            idx <= visibleIntervals);\n\n        this.meridians.length = idx;\n        visibleIntervals = Math.ceil(size.h / this.targetSize);\n        intervalIndex = 0;\n        do {\n            interval = this.intervalHeights ?\n                this.intervalHeights[intervalIndex++] :\n                this.intervals[intervalIndex++] * this.intervalHeightFactor;\n            centerLat = Math.floor(centerLonLat.lat / interval) * interval;\n\n            lat = Math.max(centerLat, this.minLat);\n            lat = Math.min(lat, this.maxLat);\n\n            idx = this.addParallel(\n                lat, minLon, maxLon, squaredTolerance, extentGeom, 0);\n\n            while (lat != this.minLat) {\n                lat = Math.max(lat - interval, this.minLat);\n                prevIdx = idx;\n                idx = this.addParallel(\n                    lat, minLon, maxLon, squaredTolerance, extentGeom, idx);\n                if (prevIdx == idx) {\n                    break;\n                }\n            }\n\n            lat = Math.max(centerLat, this.minLat);\n            lat = Math.min(lat, this.maxLat);\n\n            while (lat != this.maxLat) {\n                lat = Math.min(lat + interval, this.maxLat);\n                prevIdx = idx;\n                idx = this.addParallel(\n                    lat, minLon, maxLon, squaredTolerance, extentGeom, idx);\n                if (prevIdx == idx) {\n                    break;\n                }\n            }\n\n        } while (intervalIndex < this.intervals.length &&\n            idx <= visibleIntervals);\n\n        this.parallels.length = idx;\n    },\n\n        updateProjectionInfo: function(projection) {\n        var defaults = OpenLayers.Projection.defaults[projection.getCode()];\n        var extent = defaults && defaults.maxExtent ?\n            OpenLayers.Bounds.fromArray(defaults.maxExtent) :\n            this.map.getMaxExtent();\n        var worldExtent = defaults && defaults.worldExtent ?\n            defaults.worldExtent : [-180, -90, 180, 90];\n\n        this.maxLat = worldExtent[3];\n        this.maxLon = worldExtent[2];\n        this.minLat = worldExtent[1];\n        this.minLon = worldExtent[0];\n        this.projectionCenterLonLat = extent.clone().transform(\n            projection, this.epsg4326Projection).getCenterLonLat();\n\n        this.projection = projection;\n    },\n\n        addMeridian: function(\n            lon, minLat, maxLat, squaredTolerance, extentGeom, index) {\n        var lineString = OpenLayers.Geometry.LineString.geodesicMeridian(\n            lon, minLat, maxLat, this.projection, squaredTolerance);\n        var split = lineString.split(new OpenLayers.Geometry.LineString(\n            extentGeom.components[0].components.slice(0, 2)));\n        if (split || extentGeom.intersects(lineString)) {\n            this.meridians[index++] =\n                new OpenLayers.Feature.Vector(lineString, {\n                    lon: lon,\n                    labelPoint: split ? split[0].components[1] : undefined\n                });\n        }\n        return index;\n    },\n\n        addParallel: function(\n            lat, minLon, maxLon, squaredTolerance, extentGeom, index) {\n        var lineString = OpenLayers.Geometry.LineString.geodesicParallel(\n            lat, minLon, maxLon, this.projection, squaredTolerance);\n        var split = lineString.split(new OpenLayers.Geometry.LineString(\n            extentGeom.components[0].components.slice(1, 3)));\n        if (split || extentGeom.intersects(lineString)) {\n            this.parallels[index++] =\n                new OpenLayers.Feature.Vector(lineString, {\n                    lat: lat,\n                    labelPoint: split ? split[0].components[1] : undefined\n                });\n        }\n        return index;\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.Graticule\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/KeyboardDefaults.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.KeyboardDefaults = OpenLayers.Class(OpenLayers.Control, {\n\n        autoActivate: true,\n\n        slideFactor: 75,\n\n        observeElement: null,\n\n            \n        draw: function() {\n        var observeElement = this.observeElement || document;\n        this.handler = new OpenLayers.Handler.Keyboard( this,\n                {\"keydown\": this.defaultKeyPress},\n                {observeElement: observeElement}\n        );\n    },\n    \n        defaultKeyPress: function (evt) {\n        var size, handled = true;\n\n        var target = OpenLayers.Event.element(evt);\n        if (target  &&\n            (target.tagName == 'INPUT' ||\n             target.tagName == 'TEXTAREA' ||\n             target.tagName == 'SELECT')) {\n            return;\n        }\n\n        switch (evt.keyCode) {\n            case OpenLayers.Event.KEY_LEFT:\n                this.map.pan(-this.slideFactor, 0);\n                break;\n            case OpenLayers.Event.KEY_RIGHT: \n                this.map.pan(this.slideFactor, 0);\n                break;\n            case OpenLayers.Event.KEY_UP:\n                this.map.pan(0, -this.slideFactor);\n                break;\n            case OpenLayers.Event.KEY_DOWN:\n                this.map.pan(0, this.slideFactor);\n                break;\n            \n            case 33: // Page Up. Same in all browsers.\n                size = this.map.getSize();\n                this.map.pan(0, -0.75*size.h);\n                break;\n            case 34: // Page Down. Same in all browsers.\n                size = this.map.getSize();\n                this.map.pan(0, 0.75*size.h);\n                break; \n            case 35: // End. Same in all browsers.\n                size = this.map.getSize();\n                this.map.pan(0.75*size.w, 0);\n                break; \n            case 36: // Home. Same in all browsers.\n                size = this.map.getSize();\n                this.map.pan(-0.75*size.w, 0);\n                break; \n\n            case 43:  // +/= (ASCII), keypad + (ASCII, Opera)\n            case 61:  // +/= (Mozilla, Opera, some ASCII)\n            case 187: // +/= (IE)\n            case 107: // keypad + (IE, Mozilla)\n                this.map.zoomIn();\n                break; \n            case 45:  // -/_ (ASCII, Opera), keypad - (ASCII, Opera)\n            case 109: // -/_ (Mozilla), keypad - (Mozilla, IE)\n            case 189: // -/_ (IE)\n            case 95:  // -/_ (some ASCII)\n                this.map.zoomOut();\n                break; \n            default:\n                handled = false;\n        }\n        if (handled) {\n            OpenLayers.Event.stop(evt);\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.KeyboardDefaults\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/LayerSwitcher.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.LayerSwitcher = OpenLayers.Class(OpenLayers.Control, {\n\n        layerStates: null,\n\n        layersDiv: null,\n\n        baseLayersDiv: null,\n\n        baseLayers: null,\n\n\n        dataLbl: null,\n\n        dataLayersDiv: null,\n\n        dataLayers: null,\n\n\n        minimizeDiv: null,\n\n        maximizeDiv: null,\n\n        ascending: true,\n\n        initialize: function(options) {\n        OpenLayers.Control.prototype.initialize.apply(this, arguments);\n        this.layerStates = [];\n    },\n\n        destroy: function() {\n        this.clearLayersArray(\"base\");\n        this.clearLayersArray(\"data\");\n\n        this.map.events.un({\n            buttonclick: this.onButtonClick,\n            addlayer: this.redraw,\n            changelayer: this.redraw,\n            removelayer: this.redraw,\n            changebaselayer: this.redraw,\n            scope: this\n        });\n        this.events.unregister(\"buttonclick\", this, this.onButtonClick);\n\n        OpenLayers.Control.prototype.destroy.apply(this, arguments);\n    },\n\n        setMap: function(map) {\n        OpenLayers.Control.prototype.setMap.apply(this, arguments);\n\n        this.map.events.on({\n            addlayer: this.redraw,\n            changelayer: this.redraw,\n            removelayer: this.redraw,\n            changebaselayer: this.redraw,\n            scope: this\n        });\n        if (this.outsideViewport) {\n            this.events.attachToElement(this.div);\n            this.events.register(\"buttonclick\", this, this.onButtonClick);\n        } else {\n            this.map.events.register(\"buttonclick\", this, this.onButtonClick);\n        }\n    },\n\n        draw: function() {\n        OpenLayers.Control.prototype.draw.apply(this);\n        this.loadContents();\n        if(!this.outsideViewport) {\n            this.minimizeControl();\n        }\n        this.redraw();\n\n        return this.div;\n    },\n\n        onButtonClick: function(evt) {\n        var button = evt.buttonElement;\n        if (button === this.minimizeDiv) {\n            this.minimizeControl();\n        } else if (button === this.maximizeDiv) {\n            this.maximizeControl();\n        } else if (button._layerSwitcher === this.id) {\n            if (button[\"for\"]) {\n                button = document.getElementById(button[\"for\"]);\n            }\n            if (!button.disabled) {\n                if (button.type == \"radio\") {\n                    button.checked = true;\n                    this.map.setBaseLayer(this.map.getLayer(button._layer));\n                } else {\n                    button.checked = !button.checked;\n                    this.updateMap();\n                }\n            }\n        }\n    },\n\n        clearLayersArray: function(layersType) {\n        this[layersType + \"LayersDiv\"].innerHTML = \"\";\n        this[layersType + \"Layers\"] = [];\n    },\n\n\n        checkRedraw: function() {\n        if ( !this.layerStates.length ||\n             (this.map.layers.length != this.layerStates.length) ) {\n            return true;\n        }\n\n        for (var i = 0, len = this.layerStates.length; i < len; i++) {\n            var layerState = this.layerStates[i];\n            var layer = this.map.layers[i];\n            if ( (layerState.name != layer.name) ||\n                 (layerState.inRange != layer.inRange) ||\n                 (layerState.id != layer.id) ||\n                 (layerState.visibility != layer.visibility) ) {\n                return true;\n            }\n        }\n\n        return false;\n    },\n\n        redraw: function() {\n        if (!this.checkRedraw()) {\n            return this.div;\n        }\n        this.clearLayersArray(\"base\");\n        this.clearLayersArray(\"data\");\n\n        var containsOverlays = false;\n        var containsBaseLayers = false;\n        var len = this.map.layers.length;\n        this.layerStates = new Array(len);\n        for (var i=0; i <len; i++) {\n            var layer = this.map.layers[i];\n            this.layerStates[i] = {\n                'name': layer.name,\n                'visibility': layer.visibility,\n                'inRange': layer.inRange,\n                'id': layer.id\n            };\n        }\n\n        var layers = this.map.layers.slice();\n        if (!this.ascending) { layers.reverse(); }\n        for(var i=0, len=layers.length; i<len; i++) {\n            var layer = layers[i];\n            var baseLayer = layer.isBaseLayer;\n\n            if (layer.displayInLayerSwitcher) {\n\n                if (baseLayer) {\n                    containsBaseLayers = true;\n                } else {\n                    containsOverlays = true;\n                }\n                var checked = (baseLayer) ? (layer == this.map.baseLayer)\n                                          : layer.getVisibility();\n                var inputElem = document.createElement(\"input\"),\n                    inputId = OpenLayers.Util.createUniqueID(\n                        this.id + \"_input_\"\n                    );\n\n                inputElem.id = inputId;\n                inputElem.name = (baseLayer) ? this.id + \"_baseLayers\" : layer.name;\n                inputElem.type = (baseLayer) ? \"radio\" : \"checkbox\";\n                inputElem.value = layer.name;\n                inputElem.checked = checked;\n                inputElem.defaultChecked = checked;\n                inputElem.className = \"olButton\";\n                inputElem._layer = layer.id;\n                inputElem._layerSwitcher = this.id;\n\n                if (!baseLayer && !layer.inRange) {\n                    inputElem.disabled = true;\n                }\n                var labelSpan = document.createElement(\"label\");\n                labelSpan[\"for\"] = inputElem.id;\n                OpenLayers.Element.addClass(labelSpan, \"labelSpan olButton\");\n                labelSpan._layer = layer.id;\n                labelSpan._layerSwitcher = this.id;\n                if (!baseLayer && !layer.inRange) {\n                    labelSpan.style.color = \"gray\";\n                }\n                labelSpan.innerHTML = layer.name;\n                labelSpan.style.verticalAlign = (baseLayer) ? \"bottom\"\n                                                            : \"baseline\";\n                var br = document.createElement(\"br\");\n\n\n                var groupArray = (baseLayer) ? this.baseLayers\n                                             : this.dataLayers;\n                groupArray.push({\n                    'layer': layer,\n                    'inputElem': inputElem,\n                    'labelSpan': labelSpan\n                });\n\n\n                var groupDiv = (baseLayer) ? this.baseLayersDiv\n                                           : this.dataLayersDiv;\n                groupDiv.appendChild(inputElem);\n                groupDiv.appendChild(labelSpan);\n                groupDiv.appendChild(br);\n            }\n        }\n        this.dataLbl.style.display = (containsOverlays) ? \"\" : \"none\";\n        this.baseLbl.style.display = (containsBaseLayers) ? \"\" : \"none\";\n\n        return this.div;\n    },\n\n        updateMap: function() {\n        for(var i=0, len=this.baseLayers.length; i<len; i++) {\n            var layerEntry = this.baseLayers[i];\n            if (layerEntry.inputElem.checked) {\n                this.map.setBaseLayer(layerEntry.layer, false);\n            }\n        }\n        for(var i=0, len=this.dataLayers.length; i<len; i++) {\n            var layerEntry = this.dataLayers[i];\n            layerEntry.layer.setVisibility(layerEntry.inputElem.checked);\n        }\n\n    },\n\n        maximizeControl: function(e) {\n        this.div.style.width = \"\";\n        this.div.style.height = \"\";\n\n        this.showControls(false);\n\n        if (e != null) {\n            OpenLayers.Event.stop(e);\n        }\n    },\n\n        minimizeControl: function(e) {\n        this.div.style.width = \"0px\";\n        this.div.style.height = \"0px\";\n\n        this.showControls(true);\n\n        if (e != null) {\n            OpenLayers.Event.stop(e);\n        }\n    },\n\n        showControls: function(minimize) {\n\n        this.maximizeDiv.style.display = minimize ? \"\" : \"none\";\n        this.minimizeDiv.style.display = minimize ? \"none\" : \"\";\n\n        this.layersDiv.style.display = minimize ? \"none\" : \"\";\n    },\n\n        loadContents: function() {\n        this.layersDiv = document.createElement(\"div\");\n        this.layersDiv.id = this.id + \"_layersDiv\";\n        OpenLayers.Element.addClass(this.layersDiv, \"layersDiv\");\n\n        this.baseLbl = document.createElement(\"div\");\n        this.baseLbl.innerHTML = OpenLayers.i18n(\"Base Layer\");\n        OpenLayers.Element.addClass(this.baseLbl, \"baseLbl\");\n\n        this.baseLayersDiv = document.createElement(\"div\");\n        OpenLayers.Element.addClass(this.baseLayersDiv, \"baseLayersDiv\");\n\n        this.dataLbl = document.createElement(\"div\");\n        this.dataLbl.innerHTML = OpenLayers.i18n(\"Overlays\");\n        OpenLayers.Element.addClass(this.dataLbl, \"dataLbl\");\n\n        this.dataLayersDiv = document.createElement(\"div\");\n        OpenLayers.Element.addClass(this.dataLayersDiv, \"dataLayersDiv\");\n\n        if (this.ascending) {\n            this.layersDiv.appendChild(this.baseLbl);\n            this.layersDiv.appendChild(this.baseLayersDiv);\n            this.layersDiv.appendChild(this.dataLbl);\n            this.layersDiv.appendChild(this.dataLayersDiv);\n        } else {\n            this.layersDiv.appendChild(this.dataLbl);\n            this.layersDiv.appendChild(this.dataLayersDiv);\n            this.layersDiv.appendChild(this.baseLbl);\n            this.layersDiv.appendChild(this.baseLayersDiv);\n        }\n\n        this.div.appendChild(this.layersDiv);\n        var img = OpenLayers.Util.getImageLocation('layer-switcher-maximize.png');\n        this.maximizeDiv = OpenLayers.Util.createAlphaImageDiv(\n                                    \"OpenLayers_Control_MaximizeDiv\",\n                                    null,\n                                    null,\n                                    img,\n                                    \"absolute\");\n        OpenLayers.Element.addClass(this.maximizeDiv, \"maximizeDiv olButton\");\n        this.maximizeDiv.style.display = \"none\";\n\n        this.div.appendChild(this.maximizeDiv);\n        var img = OpenLayers.Util.getImageLocation('layer-switcher-minimize.png');\n        this.minimizeDiv = OpenLayers.Util.createAlphaImageDiv(\n                                    \"OpenLayers_Control_MinimizeDiv\",\n                                    null,\n                                    null,\n                                    img,\n                                    \"absolute\");\n        OpenLayers.Element.addClass(this.minimizeDiv, \"minimizeDiv olButton\");\n        this.minimizeDiv.style.display = \"none\";\n\n        this.div.appendChild(this.minimizeDiv);\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.LayerSwitcher\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/Measure.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.Measure = OpenLayers.Class(OpenLayers.Control, {\n\n    \n    \n        callbacks: null,\n\n        displaySystem: 'metric',\n\n        geodesic: false,\n\n        displaySystemUnits: {\n        geographic: ['dd'],\n        english: ['mi', 'ft', 'in'],\n        metric: ['km', 'm']\n    },\n\n        partialDelay: 300,\n\n        delayedTrigger: null,\n\n        persist: false,\n\n        immediate : false,\n\n        initialize: function(handler, options) {\n        OpenLayers.Control.prototype.initialize.apply(this, [options]);\n        var callbacks = {done: this.measureComplete,\n            point: this.measurePartial};\n        if (this.immediate){\n            callbacks.modify = this.measureImmediate;\n        }\n        this.callbacks = OpenLayers.Util.extend(callbacks, this.callbacks);\n        this.handlerOptions = OpenLayers.Util.extend(\n            {persist: this.persist}, this.handlerOptions\n        );\n        this.handler = new handler(this, this.callbacks, this.handlerOptions);\n    },\n\n        deactivate: function() {\n        this.cancelDelay();\n        return OpenLayers.Control.prototype.deactivate.apply(this, arguments);\n    },\n\n        cancel: function() {\n        this.cancelDelay();\n        this.handler.cancel();\n    },\n\n        setImmediate: function(immediate) {\n        this.immediate = immediate;\n        if (this.immediate){\n            this.callbacks.modify = this.measureImmediate;\n        } else {\n            delete this.callbacks.modify;\n        }\n    },\n\n        updateHandler: function(handler, options) {\n        var active = this.active;\n        if(active) {\n            this.deactivate();\n        }\n        this.handler = new handler(this, this.callbacks, options);\n        if(active) {\n            this.activate();\n        }\n    },\n\n        measureComplete: function(geometry) {\n        this.cancelDelay();\n        this.measure(geometry, \"measure\");\n    },\n\n        measurePartial: function(point, geometry) {\n        this.cancelDelay();\n        geometry = geometry.clone();\n        if (this.handler.freehandMode(this.handler.evt)) {\n            this.measure(geometry, \"measurepartial\");\n        } else {\n            this.delayedTrigger = window.setTimeout(\n                OpenLayers.Function.bind(function() {\n                    this.delayedTrigger = null;\n                    this.measure(geometry, \"measurepartial\");\n                }, this),\n                this.partialDelay\n            );\n        }\n    },\n\n        measureImmediate : function(point, feature, drawing) {\n        if (drawing && !this.handler.freehandMode(this.handler.evt)) {\n            this.cancelDelay();\n            this.measure(feature.geometry, \"measurepartial\");\n        }\n    },\n\n        cancelDelay: function() {\n        if (this.delayedTrigger !== null) {\n            window.clearTimeout(this.delayedTrigger);\n            this.delayedTrigger = null;\n        }\n    },\n\n        measure: function(geometry, eventType) {\n        var stat, order;\n        if(geometry.CLASS_NAME.indexOf('LineString') > -1) {\n            stat = this.getBestLength(geometry);\n            order = 1;\n        } else {\n            stat = this.getBestArea(geometry);\n            order = 2;\n        }\n        this.events.triggerEvent(eventType, {\n            measure: stat[0],\n            units: stat[1],\n            order: order,\n            geometry: geometry\n        });\n    },\n\n        getBestArea: function(geometry) {\n        var units = this.displaySystemUnits[this.displaySystem];\n        var unit, area;\n        for(var i=0, len=units.length; i<len; ++i) {\n            unit = units[i];\n            area = this.getArea(geometry, unit);\n            if(area > 1) {\n                break;\n            }\n        }\n        return [area, unit];\n    },\n\n        getArea: function(geometry, units) {\n        var area, geomUnits;\n        if(this.geodesic) {\n            area = geometry.getGeodesicArea(this.map.getProjectionObject());\n            geomUnits = \"m\";\n        } else {\n            area = geometry.getArea();\n            geomUnits = this.map.getUnits();\n        }\n        var inPerDisplayUnit = OpenLayers.INCHES_PER_UNIT[units];\n        if(inPerDisplayUnit) {\n            var inPerMapUnit = OpenLayers.INCHES_PER_UNIT[geomUnits];\n            area *= Math.pow((inPerMapUnit / inPerDisplayUnit), 2);\n        }\n        return area;\n    },\n\n        getBestLength: function(geometry) {\n        var units = this.displaySystemUnits[this.displaySystem];\n        var unit, length;\n        for(var i=0, len=units.length; i<len; ++i) {\n            unit = units[i];\n            length = this.getLength(geometry, unit);\n            if(length > 1) {\n                break;\n            }\n        }\n        return [length, unit];\n    },\n\n        getLength: function(geometry, units) {\n        var length, geomUnits;\n        if(this.geodesic) {\n            length = geometry.getGeodesicLength(this.map.getProjectionObject());\n            geomUnits = \"m\";\n        } else {\n            length = geometry.getLength();\n            geomUnits = this.map.getUnits();\n        }\n        var inPerDisplayUnit = OpenLayers.INCHES_PER_UNIT[units];\n        if(inPerDisplayUnit) {\n            var inPerMapUnit = OpenLayers.INCHES_PER_UNIT[geomUnits];\n            length *= (inPerMapUnit / inPerDisplayUnit);\n        }\n        return length;\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.Measure\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/ModifyFeature/BySegment.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Control.ModifyFeature.BySegment = {\n\n        hoverTolerance: 25,\n\n        collectVertices: OpenLayers.Function.Void,\n\n        setMap: function(map) {\n        OpenLayers.Control.ModifyFeature.prototype.setMap.apply(this, arguments);\n        if (!this.handlers.hover) {\n            this.handlers.hover = new OpenLayers.Handler.Hover(this, { \n                move: this.onHoverMove\n            });\n        }\n        this.handlers.hover.setMap(map);\n        this.layer.events.on({\n            beforefeaturemodified: this.createSpatialIndex,\n            afterfeaturemodified: this.deactivateHover,\n            scope: this\n       });\n    },\n\n        deactivateHover: function() {\n        this.handlers.hover.deactivate();\n    },\n\n        destroy: function() {\n        if (this.layer) {\n            this.layer.events.un({\n                beforefeaturemodified: this.createSpatialIndex,\n                afterfeaturemodified: this.deactivateHover,\n                scope: this\n            });\n        }\n        OpenLayers.Control.ModifyFeature.prototype.destroy.apply(this, []);\n    },\n\n        dragStart: function(feature) {\n        OpenLayers.Control.ModifyFeature.prototype.dragStart.apply(this, arguments);\n        this.vertexGeom = feature.geometry.clone();\n        if (this.handlers.drag.stopDown) {\n            this.handlers.hover.deactivate();\n        }\n    },\n\n        dragComplete: function(vertex) {\n        this.updateSpatialIndex(vertex);\n        OpenLayers.Control.ModifyFeature.prototype.dragComplete.apply(this, arguments);\n        this.handlers.hover.activate();\n    },\n\n        onHoverMove: function(evt) {\n        if(this.vertices.length > 0) {\n            this.layer.removeFeatures(this.vertices, {silent: true});\n            this.vertices = [];\n        }\n        if(this.virtualVertices.length > 0) {\n            this.layer.removeFeatures(this.virtualVertices, {silent: true});\n            this.virtualVertices = [];\n        }\n        var pixel = evt.xy;\n        var llPx = pixel.add(-this.hoverTolerance/2, this.hoverTolerance/2);\n        var urPx = pixel.add(this.hoverTolerance/2, -this.hoverTolerance/2);\n        var ll = this.map.getLonLatFromPixel(llPx);\n        var ur = this.map.getLonLatFromPixel(urPx);\n        var hits = this.tree.search([ll.lon, ll.lat, ur.lon, ur.lat]);\n        if (hits.length > 0) {\n            var center = this.map.getLonLatFromPixel(pixel);\n            var centerPt = new OpenLayers.Geometry.Point(center.lon, center.lat);\n            var d = Number.MAX_VALUE;\n            var closestHit;\n            for (var i=0, ii = hits.length; i<ii; ++i) {\n                var hit = hits[i];\n                var distance = OpenLayers.Geometry.distanceSquaredToSegment(centerPt, {\n                    x1: hit.point1.x,\n                    x2: hit.point2.x,\n                    y1: hit.point1.y,\n                    y2: hit.point2.y\n                }).distance;\n                if (distance < d) {\n                    closestHit = hit;\n                }\n                d = distance;\n            }\n            var createVertex = function(geom) {\n                var vertex = new OpenLayers.Feature.Vector(geom);\n                vertex._sketch = true;\n                vertex.renderIntent = this.vertexRenderIntent;\n                this.vertices.push(vertex);\n            };\n            createVertex.call(this, closestHit.point1);\n            createVertex.call(this, closestHit.point2);\n            var point = this.createVirtualVertex(closestHit.point1, closestHit.point2);\n            point._previous = closestHit.point1;\n            point._next = closestHit.point2;\n            point._index = -1;\n            point.geometry.parent = closestHit.point1.parent;\n            this.virtualVertices.push(point);\n        }\n        this.layer.addFeatures(this.vertices, {silent: true});\n        this.layer.addFeatures(this.virtualVertices, {silent: true});\n    },\n\n        createSpatialIndex: function(evt) {\n        var feature = evt.feature;\n        var data = [];\n        function collectComponentVertices(geometry) {\n            var i, vertex, component, nextComponent, len;\n            if (geometry.CLASS_NAME !== \"OpenLayers.Geometry.Point\") {\n                var numVert = geometry.components.length;\n                if (geometry.CLASS_NAME == \"OpenLayers.Geometry.LinearRing\"\n                || geometry.CLASS_NAME == \"OpenLayers.Geometry.LineString\") {\n                    numVert -= 1;\n                }\n                nextComponent = geometry.components[0];\n                for (i=1; i<=numVert; ++i) {\n                    component = nextComponent;\n                    nextComponent = geometry.components[i];\n                    if (component.CLASS_NAME == \"OpenLayers.Geometry.Point\") {\n                        var bbox = this.createBBOX(component, nextComponent);\n                        bbox.point1 = component;\n                        bbox.point2 = nextComponent;\n                        data.push(bbox);\n                    } else {\n                        collectComponentVertices.call(this, component);\n                    }\n                }\n            }\n        }\n        collectComponentVertices.call(this, feature.geometry);\n        this.tree = window.rbush();\n        this.tree.load(data);\n        this.handlers.hover.activate();\n    },\n\n        createBBOX: function(point1, point2) {\n        return [\n            point1.x < point2.x ? point1.x : point2.x,\n            point1.y < point2.y ? point1.y : point2.y,\n            point1.x < point2.x ? point2.x : point1.x,\n            point1.y < point2.y ? point2.y : point1.y\n        ];\n    },\n\n        updateSpatialIndex: function(vertex) {\n        var hits = this.tree.search([\n            this.vertexGeom.x, \n            this.vertexGeom.y, \n            this.vertexGeom.x, \n            this.vertexGeom.y\n        ]);\n        var bbox, i, ii;\n        if (vertex._previous) {\n            bbox = this.createBBOX(vertex._previous, vertex.geometry);\n            bbox.point1 = vertex._previous;\n            bbox.point2 = vertex.geometry;\n            this.tree.insert(bbox);\n            bbox = this.createBBOX(vertex.geometry, vertex._next);\n            bbox.point1 = vertex.geometry;\n            bbox.point2 = vertex._next;\n            this.tree.insert(bbox);\n            this.tree.remove(hits[0]);\n            delete vertex._next;\n            delete vertex._previous;\n        } else { // normal vertex\n            for (i=0, ii=hits.length; i<ii; ++i) {\n                var hit = hits[i];\n                if (this.vertexGeom.equals(hit.point1)) {\n                    bbox = this.createBBOX(vertex.geometry, hit.point2);\n                    bbox.point1 = vertex.geometry;\n                    bbox.point2 = hit.point2;\n                } else {\n                    bbox = this.createBBOX(vertex.geometry, hit.point1);\n                    bbox.point1 = hit.point1;\n                    bbox.point2 = vertex.geometry;\n                }\n                this.tree.insert(bbox);\n                this.tree.remove(hit);\n            }\n        }\n        this.vertexGeom.destroy();\n        this.vertexGeom = null;\n    }\n\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/ModifyFeature.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.ModifyFeature = OpenLayers.Class(OpenLayers.Control, {\n\n        bySegment: false,\n\n        documentDrag: false,\n\n        geometryTypes: null,\n\n        clickout: true,\n\n        toggle: true,\n\n        standalone: false,\n\n        layer: null,\n\n        feature: null,\n\n        vertex: null,\n\n        vertices: null,\n\n        virtualVertices: null,\n\n        handlers: null,\n\n        deleteCodes: null,\n\n        virtualStyle: null,\n\n        vertexRenderIntent: null,\n\n        mode: null,\n\n        createVertices: true,\n\n        modified: false,\n\n        radiusHandle: null,\n\n        dragHandle: null,\n\n        onModificationStart: function() {},\n\n        onModification: function() {},\n\n        onModificationEnd: function() {},\n\n        initialize: function(layer, options) {\n        options = options || {};\n        this.layer = layer;\n        this.vertices = [];\n        this.virtualVertices = [];\n        this.virtualStyle = OpenLayers.Util.extend({},\n            this.layer.style ||\n            this.layer.styleMap.createSymbolizer(null, options.vertexRenderIntent)\n        );\n        this.virtualStyle.fillOpacity = 0.3;\n        this.virtualStyle.strokeOpacity = 0.3;\n        this.deleteCodes = [46, 68];\n        this.mode = OpenLayers.Control.ModifyFeature.RESHAPE;\n        OpenLayers.Control.prototype.initialize.apply(this, [options]);\n        if(!(OpenLayers.Util.isArray(this.deleteCodes))) {\n            this.deleteCodes = [this.deleteCodes];\n        }\n        var dragCallbacks = {\n            down: function(pixel) {\n                this.vertex = null;\n                var feature = this.layer.getFeatureFromEvent(\n                        this.handlers.drag.evt);\n                if (feature) {\n                    this.dragStart(feature);\n                } else if (this.clickout) {\n                    this._unselect = this.feature;\n                }\n            },\n            move: function(pixel) {\n                delete this._unselect;\n                if (this.vertex) {\n                    this.dragVertex(this.vertex, pixel);\n                }\n            },\n            up: function() {\n                this.handlers.drag.stopDown = false;\n                if (this._unselect) {\n                    this.unselectFeature(this._unselect);\n                    delete this._unselect;\n                }\n            },\n            done: function(pixel) {\n                if (this.vertex) {\n                    this.dragComplete(this.vertex);\n                }\n            }\n        };\n        var _self = this;\n        var dragOptions = {\n            documentDrag: this.documentDrag,\n            setEvent: function(evt) {\n                var feature = _self.feature;\n                _self._lastVertex = feature ?\n                                  feature.layer.getFeatureFromEvent(evt) : null;\n                OpenLayers.Handler.Drag.prototype.setEvent.apply(\n                                                               this, arguments);\n            },\n            stopDown: false\n        };\n        var keyboardOptions = {\n            keydown: this.handleKeypress\n        };\n        this.handlers = {\n            keyboard: new OpenLayers.Handler.Keyboard(this, keyboardOptions),\n            drag: new OpenLayers.Handler.Drag(this, dragCallbacks, dragOptions)\n        };\n\n        if (this.bySegment) {\n            if (!window.rbush) {\n                throw new Error(\"The rbush library is required\");\n            }\n            if (!OpenLayers.Control.ModifyFeature.BySegment) {\n                throw new Error(\"OpenLayers.Control.ModifyFeature.BySegment is missing from the build\");\n            } else {\n                OpenLayers.Util.extend(this, OpenLayers.Control.ModifyFeature.BySegment);\n            }\n        }\n    },\n\n        createVirtualVertex: function(point1, point2) {\n        var x = (point1.x + point2.x) / 2;\n        var y = (point1.y + point2.y) / 2;\n        var point = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(x, y),\n            null, this.virtualStyle\n        );\n        point._sketch = true;\n        return point;\n    },\n\n        destroy: function() {\n        if (this.map) {\n            this.map.events.un({\n                \"removelayer\": this.handleMapEvents,\n                \"changelayer\": this.handleMapEvents,\n                scope: this\n            });\n        }\n        this.layer = null;\n        OpenLayers.Control.prototype.destroy.apply(this, []);\n    },\n\n        activate: function() {\n        if (OpenLayers.Control.prototype.activate.apply(this, arguments)) {\n            this.moveLayerToTop();\n            this.map.events.on({\n                \"removelayer\": this.handleMapEvents,\n                \"changelayer\": this.handleMapEvents,\n                scope: this\n            });\n            this._lastVertex = null;\n            return this.handlers.keyboard.activate() &&\n                    this.handlers.drag.activate();\n        }\n        return false;\n    },\n\n        deactivate: function() {\n        var deactivated = false;\n        if(OpenLayers.Control.prototype.deactivate.apply(this, arguments)) {\n            this.moveLayerBack();\n            this.map.events.un({\n                \"removelayer\": this.handleMapEvents,\n                \"changelayer\": this.handleMapEvents,\n                scope: this\n            });\n            this.layer.removeFeatures(this.vertices, {silent: true});\n            this.layer.removeFeatures(this.virtualVertices, {silent: true});\n            this.vertices = [];\n            this.handlers.drag.deactivate();\n            this.handlers.keyboard.deactivate();\n            var feature = this.feature;\n            if (feature && feature.geometry && feature.layer) {\n                this.unselectFeature(feature);\n            }\n            deactivated = true;\n        }\n        return deactivated;\n    },\n\n        beforeSelectFeature: function(feature) {\n        return this.layer.events.triggerEvent(\n            \"beforefeaturemodified\", {feature: feature}\n        );\n    },\n\n        selectFeature: function(feature) {\n        var indexOf = OpenLayers.Util.indexOf;\n\n        if (this.feature === feature ||\n           (this.geometryTypes && indexOf(this.geometryTypes,\n           feature.geometry.CLASS_NAME) == -1)) {\n            return;\n        }\n        if (this.beforeSelectFeature(feature) !== false) {\n            if (this.feature) {\n                this.unselectFeature(this.feature);\n            }\n            this.feature = feature;\n\n            if(indexOf(this.layer.selectedFeatures, feature) == -1){\n                this.layer.selectedFeatures.push(feature);\n            }\n\n            this.layer.drawFeature(feature, 'select');\n            this.modified = false;\n            this.resetVertices();\n            this.onModificationStart(this.feature);\n        }\n        var modified = feature.modified;\n        if (feature.geometry && !(modified && modified.geometry)) {\n            this._originalGeometry = feature.geometry.clone();\n        }\n    },\n\n        unselectFeature: function(feature) {\n        this.layer.removeFeatures(this.vertices, {silent: true});\n        this.vertices = [];\n        this.layer.destroyFeatures(this.virtualVertices, {silent: true});\n        this.virtualVertices = [];\n        if(this.dragHandle) {\n            this.layer.destroyFeatures([this.dragHandle], {silent: true});\n            delete this.dragHandle;\n        }\n        if(this.radiusHandle) {\n            this.layer.destroyFeatures([this.radiusHandle], {silent: true});\n            delete this.radiusHandle;\n        }\n        this.layer.drawFeature(this.feature, 'default');\n        this.feature = null;\n        OpenLayers.Util.removeItem(this.layer.selectedFeatures, feature);\n        this.onModificationEnd(feature);\n        this.layer.events.triggerEvent(\"afterfeaturemodified\", {\n            feature: feature,\n            modified: this.modified\n        });\n        this.modified = false;\n    },\n\n\n        dragStart: function(feature) {\n        var isPoint = feature.geometry.CLASS_NAME ==\n                'OpenLayers.Geometry.Point';\n        if (!this.standalone &&\n                ((!feature._sketch && isPoint) || !feature._sketch)) {\n            if (this.toggle && this.feature === feature) {\n                this._unselect = feature;\n            }\n            this.selectFeature(feature);\n        }\n        if (this.feature &&\n                (feature._sketch || isPoint && feature === this.feature)) {\n            this.vertex = feature;\n            this.handlers.drag.stopDown = true;\n        }\n    },\n\n        dragVertex: function(vertex, pixel) {\n        var pos = this.map.getLonLatFromViewPortPx(pixel);\n        var geom = vertex.geometry;\n        geom.move(pos.lon - geom.x, pos.lat - geom.y);\n        this.modified = true;\n                if(this.feature.geometry.CLASS_NAME == \"OpenLayers.Geometry.Point\") {\n            this.layer.events.triggerEvent(\"vertexmodified\", {\n                vertex: vertex.geometry,\n                feature: this.feature,\n                pixel: pixel\n            });\n        } else {\n            if(vertex._index) {\n                if (vertex._index == -1) {\n                    vertex._index = OpenLayers.Util.indexOf(vertex.geometry.parent.components, vertex._next);\n                }\n                vertex.geometry.parent.addComponent(vertex.geometry,\n                                                    vertex._index);\n                delete vertex._index;\n                OpenLayers.Util.removeItem(this.virtualVertices, vertex);\n                this.vertices.push(vertex);\n            } else if(vertex == this.dragHandle) {\n                this.layer.removeFeatures(this.vertices, {silent: true});\n                this.vertices = [];\n                if(this.radiusHandle) {\n                    this.layer.destroyFeatures([this.radiusHandle], {silent: true});\n                    this.radiusHandle = null;\n                }\n            } else if(vertex !== this.radiusHandle) {\n                this.layer.events.triggerEvent(\"vertexmodified\", {\n                    vertex: vertex.geometry,\n                    feature: this.feature,\n                    pixel: pixel\n                });\n            }\n            if(this.virtualVertices.length > 0) {\n                this.layer.destroyFeatures(this.virtualVertices, {silent: true});\n                this.virtualVertices = [];\n            }\n            this.layer.drawFeature(this.feature, this.standalone ? undefined :\n                                            'select');\n        }\n        this.layer.drawFeature(vertex);\n    },\n\n        dragComplete: function(vertex) {\n        this.resetVertices();\n        this.setFeatureState();\n        this.onModification(this.feature);\n        this.layer.events.triggerEvent(\"featuremodified\",\n                                       {feature: this.feature});\n    },\n\n        setFeatureState: function() {\n        if(this.feature.state != OpenLayers.State.INSERT &&\n           this.feature.state != OpenLayers.State.DELETE) {\n            this.feature.state = OpenLayers.State.UPDATE;\n            if (this.modified && this._originalGeometry) {\n                var feature = this.feature;\n                feature.modified = OpenLayers.Util.extend(feature.modified, {\n                    geometry: this._originalGeometry\n                });\n                delete this._originalGeometry;\n            }\n        }\n    },\n\n        resetVertices: function() {\n        if(this.vertices.length > 0) {\n            this.layer.removeFeatures(this.vertices, {silent: true});\n            this.vertices = [];\n        }\n        if(this.virtualVertices.length > 0) {\n            this.layer.removeFeatures(this.virtualVertices, {silent: true});\n            this.virtualVertices = [];\n        }\n        if(this.dragHandle) {\n            this.layer.destroyFeatures([this.dragHandle], {silent: true});\n            this.dragHandle = null;\n        }\n        if(this.radiusHandle) {\n            this.layer.destroyFeatures([this.radiusHandle], {silent: true});\n            this.radiusHandle = null;\n        }\n        if(this.feature &&\n           this.feature.geometry.CLASS_NAME != \"OpenLayers.Geometry.Point\") {\n            if((this.mode & OpenLayers.Control.ModifyFeature.DRAG)) {\n                this.collectDragHandle();\n            }\n            if((this.mode & (OpenLayers.Control.ModifyFeature.ROTATE |\n                             OpenLayers.Control.ModifyFeature.RESIZE))) {\n                this.collectRadiusHandle();\n            }\n            if(this.mode & OpenLayers.Control.ModifyFeature.RESHAPE){\n                if (!(this.mode & OpenLayers.Control.ModifyFeature.RESIZE)){\n                    this.collectVertices();\n                }\n            }\n        }\n    },\n\n        handleKeypress: function(evt) {\n        var code = evt.keyCode;\n        if(this.feature &&\n           OpenLayers.Util.indexOf(this.deleteCodes, code) != -1) {\n            var vertex = this._lastVertex;\n            if (vertex &&\n                    OpenLayers.Util.indexOf(this.vertices, vertex) != -1 &&\n                    !this.handlers.drag.dragging && vertex.geometry.parent) {\n                vertex.geometry.parent.removeComponent(vertex.geometry);\n                this.layer.events.triggerEvent(\"vertexremoved\", {\n                    vertex: vertex.geometry,\n                    feature: this.feature,\n                    pixel: evt.xy\n                });\n                this.layer.drawFeature(this.feature, this.standalone ?\n                                       undefined : 'select');\n                this.modified = true;\n                this.resetVertices();\n                this.setFeatureState();\n                this.onModification(this.feature);\n                this.layer.events.triggerEvent(\"featuremodified\",\n                                               {feature: this.feature});\n            }\n        }\n    },\n\n        collectVertices: function() {\n        this.vertices = [];\n        this.virtualVertices = [];\n        var control = this;\n        function collectComponentVertices(geometry) {\n            var i, vertex, component, len;\n            if(geometry.CLASS_NAME == \"OpenLayers.Geometry.Point\") {\n                vertex = new OpenLayers.Feature.Vector(geometry);\n                vertex._sketch = true;\n                vertex.renderIntent = control.vertexRenderIntent;\n                control.vertices.push(vertex);\n            } else {\n                var numVert = geometry.components.length;\n                if(geometry.CLASS_NAME == \"OpenLayers.Geometry.LinearRing\") {\n                    numVert -= 1;\n                }\n                for(i=0; i<numVert; ++i) {\n                    component = geometry.components[i];\n                    if(component.CLASS_NAME == \"OpenLayers.Geometry.Point\") {\n                        vertex = new OpenLayers.Feature.Vector(component);\n                        vertex._sketch = true;\n                        vertex.renderIntent = control.vertexRenderIntent;\n                        control.vertices.push(vertex);\n                    } else {\n                        collectComponentVertices(component);\n                    }\n                }\n                if (control.createVertices && geometry.CLASS_NAME != \"OpenLayers.Geometry.MultiPoint\") {\n                    for(i=0, len=geometry.components.length; i<len-1; ++i) {\n                        var prevVertex = geometry.components[i];\n                        var nextVertex = geometry.components[i + 1];\n                        if(prevVertex.CLASS_NAME == \"OpenLayers.Geometry.Point\" &&\n                           nextVertex.CLASS_NAME == \"OpenLayers.Geometry.Point\") {\n                            var point = control.createVirtualVertex.call(control, prevVertex, nextVertex);\n                            point.geometry.parent = geometry;\n                            point._index = i + 1;\n                            control.virtualVertices.push(point);\n                        }\n                    }\n                }\n            }\n        }\n        collectComponentVertices.call(this, this.feature.geometry);\n        this.layer.addFeatures(this.virtualVertices, {silent: true});\n        this.layer.addFeatures(this.vertices, {silent: true});\n    },\n\n        collectDragHandle: function() {\n        var geometry = this.feature.geometry;\n        var center = geometry.getBounds().getCenterLonLat();\n        var originGeometry = new OpenLayers.Geometry.Point(\n            center.lon, center.lat\n        );\n        var origin = new OpenLayers.Feature.Vector(originGeometry);\n        originGeometry.move = function(x, y) {\n            OpenLayers.Geometry.Point.prototype.move.call(this, x, y);\n            geometry.move(x, y);\n        };\n        origin._sketch = true;\n        this.dragHandle = origin;\n        this.dragHandle.renderIntent = this.vertexRenderIntent;\n        this.layer.addFeatures([this.dragHandle], {silent: true});\n    },\n\n        collectRadiusHandle: function() {\n        var geometry = this.feature.geometry;\n        var bounds = geometry.getBounds();\n        var center = bounds.getCenterLonLat();\n        var originGeometry = new OpenLayers.Geometry.Point(\n            center.lon, center.lat\n        );\n        var radiusGeometry = new OpenLayers.Geometry.Point(\n            bounds.right, bounds.bottom\n        );\n        var radius = new OpenLayers.Feature.Vector(radiusGeometry);\n        var resize = (this.mode & OpenLayers.Control.ModifyFeature.RESIZE);\n        var reshape = (this.mode & OpenLayers.Control.ModifyFeature.RESHAPE);\n        var rotate = (this.mode & OpenLayers.Control.ModifyFeature.ROTATE);\n\n        radiusGeometry.move = function(x, y) {\n            OpenLayers.Geometry.Point.prototype.move.call(this, x, y);\n            var dx1 = this.x - originGeometry.x;\n            var dy1 = this.y - originGeometry.y;\n            var dx0 = dx1 - x;\n            var dy0 = dy1 - y;\n            if(rotate) {\n                var a0 = Math.atan2(dy0, dx0);\n                var a1 = Math.atan2(dy1, dx1);\n                var angle = a1 - a0;\n                angle *= 180 / Math.PI;\n                geometry.rotate(angle, originGeometry);\n            }\n            if(resize) {\n                var scale, ratio;\n                if (reshape) {\n                    scale = dy1 / dy0;\n                    ratio = (dx1 / dx0) / scale;\n                } else {\n                    var l0 = Math.sqrt((dx0 * dx0) + (dy0 * dy0));\n                    var l1 = Math.sqrt((dx1 * dx1) + (dy1 * dy1));\n                    scale = l1 / l0;\n                }\n                geometry.resize(scale, originGeometry, ratio);\n            }\n        };\n        radius._sketch = true;\n        this.radiusHandle = radius;\n        this.radiusHandle.renderIntent = this.vertexRenderIntent;\n        this.layer.addFeatures([this.radiusHandle], {silent: true});\n    },\n\n        setMap: function(map) {\n        this.handlers.drag.setMap(map);\n        OpenLayers.Control.prototype.setMap.apply(this, arguments);\n    },\n\n        handleMapEvents: function(evt) {\n        if (evt.type == \"removelayer\" || evt.property == \"order\") {\n            this.moveLayerToTop();\n        }\n    },\n\n        moveLayerToTop: function() {\n        var index = Math.max(this.map.Z_INDEX_BASE['Feature'] - 1,\n            this.layer.getZIndex()) + 1;\n        this.layer.setZIndex(index);\n\n    },\n\n        moveLayerBack: function() {\n        var index = this.layer.getZIndex() - 1;\n        if (index >= this.map.Z_INDEX_BASE['Feature']) {\n            this.layer.setZIndex(index);\n        } else {\n            this.map.setLayerZIndex(this.layer,\n                this.map.getLayerIndex(this.layer));\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.ModifyFeature\"\n});\n\nOpenLayers.Control.ModifyFeature.RESHAPE = 1;\nOpenLayers.Control.ModifyFeature.RESIZE = 2;\nOpenLayers.Control.ModifyFeature.ROTATE = 4;\nOpenLayers.Control.ModifyFeature.DRAG = 8;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/MousePosition.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Control.MousePosition = OpenLayers.Class(OpenLayers.Control, {\n\n        autoActivate: true,\n\n        element: null,\n\n        prefix: '',\n\n        separator: ', ',\n\n        suffix: '',\n\n        numDigits: 5,\n\n        granularity: 10,\n\n        emptyString: null,\n\n        lastXy: null,\n\n        displayProjection: null,\n\n    \n         destroy: function() {\n         this.deactivate();\n         OpenLayers.Control.prototype.destroy.apply(this, arguments);\n     },\n\n        activate: function() {\n        if (OpenLayers.Control.prototype.activate.apply(this, arguments)) {\n            this.map.events.register('mousemove', this, this.redraw);\n            this.map.events.register('mouseout', this, this.reset);\n            this.redraw();\n            return true;\n        } else {\n            return false;\n        }\n    },\n\n        deactivate: function() {\n        if (OpenLayers.Control.prototype.deactivate.apply(this, arguments)) {\n            this.map.events.unregister('mousemove', this, this.redraw);\n            this.map.events.unregister('mouseout', this, this.reset);\n            this.element.innerHTML = \"\";\n            return true;\n        } else {\n            return false;\n        }\n    },\n\n        draw: function() {\n        OpenLayers.Control.prototype.draw.apply(this, arguments);\n\n        if (!this.element) {\n            this.div.left = \"\";\n            this.div.top = \"\";\n            this.element = this.div;\n        }\n\n        return this.div;\n    },\n\n        redraw: function(evt) {\n\n        var lonLat;\n\n        if (evt == null) {\n            this.reset();\n            return;\n        } else {\n            if (this.lastXy == null ||\n                Math.abs(evt.xy.x - this.lastXy.x) > this.granularity ||\n                Math.abs(evt.xy.y - this.lastXy.y) > this.granularity)\n            {\n                this.lastXy = evt.xy;\n                return;\n            }\n\n            lonLat = this.map.getLonLatFromPixel(evt.xy);\n            if (!lonLat) {\n                return;\n            }\n            if (this.displayProjection) {\n                lonLat.transform(this.map.getProjectionObject(),\n                                 this.displayProjection );\n            }\n            this.lastXy = evt.xy;\n\n        }\n\n        var newHtml = this.formatOutput(lonLat);\n\n        if (newHtml != this.element.innerHTML) {\n            this.element.innerHTML = newHtml;\n        }\n    },\n\n        reset: function(evt) {\n        if (this.emptyString != null) {\n            this.element.innerHTML = this.emptyString;\n        }\n    },\n\n        formatOutput: function(lonLat) {\n        var digits = parseInt(this.numDigits);\n        var newHtml =\n            this.prefix +\n            lonLat.lon.toFixed(digits) +\n            this.separator +\n            lonLat.lat.toFixed(digits) +\n            this.suffix;\n        return newHtml;\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.MousePosition\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/NavToolbar.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.NavToolbar = OpenLayers.Class(OpenLayers.Control.Panel, {\n\n        initialize: function(options) {\n        OpenLayers.Control.Panel.prototype.initialize.apply(this, [options]);\n        this.addControls([\n          new OpenLayers.Control.Navigation(),\n          new OpenLayers.Control.ZoomBox()\n        ]);\n    },\n\n        draw: function() {\n        var div = OpenLayers.Control.Panel.prototype.draw.apply(this, arguments);\n        if (this.defaultControl === null) {\n            this.defaultControl = this.controls[0];\n        }\n        return div;\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.NavToolbar\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/Navigation.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.Navigation = OpenLayers.Class(OpenLayers.Control, {\n\n        dragPan: null,\n\n        dragPanOptions: null,\n\n        pinchZoom: null,\n\n        pinchZoomOptions: null,\n\n        documentDrag: false,\n\n        zoomBox: null,\n\n        zoomBoxEnabled: true, \n\n        zoomWheelEnabled: true,\n    \n        mouseWheelOptions: null,\n\n        handleRightClicks: false,\n\n        zoomBoxKeyMask: OpenLayers.Handler.MOD_SHIFT,\n    \n        autoActivate: true,\n\n        initialize: function(options) {\n        this.handlers = {};\n        OpenLayers.Control.prototype.initialize.apply(this, arguments);\n    },\n\n        destroy: function() {\n        this.deactivate();\n\n        if (this.dragPan) {\n            this.dragPan.destroy();\n        }\n        this.dragPan = null;\n\n        if (this.zoomBox) {\n            this.zoomBox.destroy();\n        }\n        this.zoomBox = null;\n\n        if (this.pinchZoom) {\n            this.pinchZoom.destroy();\n        }\n        this.pinchZoom = null;\n\n        OpenLayers.Control.prototype.destroy.apply(this,arguments);\n    },\n    \n        activate: function() {\n        this.dragPan.activate();\n        if (this.zoomWheelEnabled) {\n            this.handlers.wheel.activate();\n        }    \n        this.handlers.click.activate();\n        if (this.zoomBoxEnabled) {\n            this.zoomBox.activate();\n        }\n        if (this.pinchZoom) {\n            this.pinchZoom.activate();\n        }\n        return OpenLayers.Control.prototype.activate.apply(this,arguments);\n    },\n\n        deactivate: function() {\n        if (this.pinchZoom) {\n            this.pinchZoom.deactivate();\n        }\n        this.zoomBox.deactivate();\n        this.dragPan.deactivate();\n        this.handlers.click.deactivate();\n        this.handlers.wheel.deactivate();\n        return OpenLayers.Control.prototype.deactivate.apply(this,arguments);\n    },\n    \n        draw: function() {\n        if (this.handleRightClicks) {\n            this.map.viewPortDiv.oncontextmenu = OpenLayers.Function.False;\n        }\n\n        var clickCallbacks = { \n            'click': this.defaultClick,\n            'dblclick': this.defaultDblClick, \n            'dblrightclick': this.defaultDblRightClick \n        };\n        var clickOptions = {\n            'double': true, \n            'stopDouble': true\n        };\n        this.handlers.click = new OpenLayers.Handler.Click(\n            this, clickCallbacks, clickOptions\n        );\n        this.dragPan = new OpenLayers.Control.DragPan(\n            OpenLayers.Util.extend({\n                map: this.map,\n                documentDrag: this.documentDrag\n            }, this.dragPanOptions)\n        );\n        this.zoomBox = new OpenLayers.Control.ZoomBox(\n                    {map: this.map, keyMask: this.zoomBoxKeyMask});\n        this.dragPan.draw();\n        this.zoomBox.draw();\n        var wheelOptions = this.map.fractionalZoom ? {} : {\n            cumulative: false,\n            interval: 50,\n            maxDelta: 6\n        };\n        this.handlers.wheel = new OpenLayers.Handler.MouseWheel(\n            this, {up : this.wheelUp, down: this.wheelDown},\n            OpenLayers.Util.extend(wheelOptions, this.mouseWheelOptions)\n        );\n        if (OpenLayers.Control.PinchZoom) {\n            this.pinchZoom = new OpenLayers.Control.PinchZoom(\n                OpenLayers.Util.extend(\n                    {map: this.map}, this.pinchZoomOptions));\n        }\n    },\n\n        defaultClick: function (evt) {\n        if (evt.lastTouches && evt.lastTouches.length == 2) {\n            this.map.zoomOut();\n        }\n    },\n\n        defaultDblClick: function (evt) {\n        this.map.zoomTo(this.map.zoom + 1, evt.xy);\n    },\n\n        defaultDblRightClick: function (evt) {\n        this.map.zoomTo(this.map.zoom - 1, evt.xy);\n    },\n    \n        wheelChange: function(evt, deltaZ) {\n        if (!this.map.fractionalZoom) {\n            deltaZ =  Math.round(deltaZ);\n        }\n        var currentZoom = this.map.getZoom(),\n            newZoom = currentZoom + deltaZ;\n        newZoom = Math.max(newZoom, 0);\n        newZoom = Math.min(newZoom, this.map.getNumZoomLevels());\n        if (newZoom === currentZoom) {\n            return;\n        }\n        this.map.zoomTo(newZoom, evt.xy);\n    },\n\n        wheelUp: function(evt, delta) {\n        this.wheelChange(evt, delta || 1);\n    },\n\n        wheelDown: function(evt, delta) {\n        this.wheelChange(evt, delta || -1);\n    },\n    \n        disableZoomBox : function() {\n        this.zoomBoxEnabled = false;\n        this.zoomBox.deactivate();       \n    },\n    \n        enableZoomBox : function() {\n        this.zoomBoxEnabled = true;\n        if (this.active) {\n            this.zoomBox.activate();\n        }    \n    },\n    \n        \n    disableZoomWheel : function() {\n        this.zoomWheelEnabled = false;\n        this.handlers.wheel.deactivate();       \n    },\n    \n        \n    enableZoomWheel : function() {\n        this.zoomWheelEnabled = true;\n        if (this.active) {\n            this.handlers.wheel.activate();\n        }    \n    },\n\n    CLASS_NAME: \"OpenLayers.Control.Navigation\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/NavigationHistory.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.NavigationHistory = OpenLayers.Class(OpenLayers.Control, {\n\n        type: OpenLayers.Control.TYPE_TOGGLE,\n\n        previous: null,\n    \n        previousOptions: null,\n    \n        next: null,\n\n        nextOptions: null,\n\n        limit: 50,\n\n        autoActivate: true,\n\n        clearOnDeactivate: false,\n\n        registry: null,\n\n        nextStack: null,\n\n        previousStack: null,\n    \n        listeners: null,\n    \n        restoring: false,\n    \n        initialize: function(options) {\n        OpenLayers.Control.prototype.initialize.apply(this, [options]);\n        \n        this.registry = OpenLayers.Util.extend({\n            \"moveend\": this.getState\n        }, this.registry);\n        \n        var previousOptions = {\n            trigger: OpenLayers.Function.bind(this.previousTrigger, this),\n            displayClass: this.displayClass + \" \" + this.displayClass + \"Previous\"\n        };\n        OpenLayers.Util.extend(previousOptions, this.previousOptions);\n        this.previous = new OpenLayers.Control.Button(previousOptions);\n        \n        var nextOptions = {\n            trigger: OpenLayers.Function.bind(this.nextTrigger, this),\n            displayClass: this.displayClass + \" \" + this.displayClass + \"Next\"\n        };\n        OpenLayers.Util.extend(nextOptions, this.nextOptions);\n        this.next = new OpenLayers.Control.Button(nextOptions);\n\n        this.clear();\n    },\n    \n        onPreviousChange: function(state, length) {\n        if(state && !this.previous.active) {\n            this.previous.activate();\n        } else if(!state && this.previous.active) {\n            this.previous.deactivate();\n        }\n    },\n    \n        onNextChange: function(state, length) {\n        if(state && !this.next.active) {\n            this.next.activate();\n        } else if(!state && this.next.active) {\n            this.next.deactivate();\n        }\n    },\n    \n        destroy: function() {\n        OpenLayers.Control.prototype.destroy.apply(this);\n        this.previous.destroy();\n        this.next.destroy();\n        this.deactivate();\n        for(var prop in this) {\n            this[prop] = null;\n        }\n    },\n    \n        setMap: function(map) {\n        this.map = map;\n        this.next.setMap(map);\n        this.previous.setMap(map);\n    },\n\n        draw: function() {\n        OpenLayers.Control.prototype.draw.apply(this, arguments);\n        this.next.draw();\n        this.previous.draw();\n    },\n    \n        previousTrigger: function() {\n        var current = this.previousStack.shift();\n        var state = this.previousStack.shift();\n        if(state != undefined) {\n            this.nextStack.unshift(current);\n            this.previousStack.unshift(state);\n            this.restoring = true;\n            this.restore(state);\n            this.restoring = false;\n            this.onNextChange(this.nextStack[0], this.nextStack.length);\n            this.onPreviousChange(\n                this.previousStack[1], this.previousStack.length - 1\n            );\n        } else {\n            this.previousStack.unshift(current);\n        }\n        return state;\n    },\n    \n        nextTrigger: function() {\n        var state = this.nextStack.shift();\n        if(state != undefined) {\n            this.previousStack.unshift(state);\n            this.restoring = true;\n            this.restore(state);\n            this.restoring = false;\n            this.onNextChange(this.nextStack[0], this.nextStack.length);\n            this.onPreviousChange(\n                this.previousStack[1], this.previousStack.length - 1\n            );\n        }\n        return state;\n    },\n    \n        clear: function() {\n        this.previousStack = [];\n        this.previous.deactivate();\n        this.nextStack = [];\n        this.next.deactivate();\n    },\n\n        getState: function() {\n        return {\n            center: this.map.getCenter(),\n            resolution: this.map.getResolution(),\n            projection: this.map.getProjectionObject(),\n            units: this.map.getProjectionObject().getUnits() || \n                this.map.units || this.map.baseLayer.units\n        };\n    },\n\n        restore: function(state) {\n        var center, zoom;\n        if (this.map.getProjectionObject() == state.projection) { \n            zoom = this.map.getZoomForResolution(state.resolution);\n            center = state.center;\n        } else {\n            center = state.center.clone();\n            center.transform(state.projection, this.map.getProjectionObject());\n            var sourceUnits = state.units;\n            var targetUnits = this.map.getProjectionObject().getUnits() || \n                this.map.units || this.map.baseLayer.units;\n            var resolutionFactor = sourceUnits && targetUnits ? \n                OpenLayers.INCHES_PER_UNIT[sourceUnits] / OpenLayers.INCHES_PER_UNIT[targetUnits] : 1;\n            zoom = this.map.getZoomForResolution(resolutionFactor*state.resolution); \n        }\n        this.map.setCenter(center, zoom);\n    },\n    \n        setListeners: function() {\n        this.listeners = {};\n        for(var type in this.registry) {\n            this.listeners[type] = OpenLayers.Function.bind(function() {\n                if(!this.restoring) {\n                    var state = this.registry[type].apply(this, arguments);\n                    this.previousStack.unshift(state);\n                    if(this.previousStack.length > 1) {\n                        this.onPreviousChange(\n                            this.previousStack[1], this.previousStack.length - 1\n                        );\n                    }\n                    if(this.previousStack.length > (this.limit + 1)) {\n                        this.previousStack.pop();\n                    }\n                    if(this.nextStack.length > 0) {\n                        this.nextStack = [];\n                        this.onNextChange(null, 0);\n                    }\n                }\n                return true;\n            }, this);\n        }\n    },\n\n        activate: function() {\n        var activated = false;\n        if(this.map) {\n            if(OpenLayers.Control.prototype.activate.apply(this)) {\n                if(this.listeners == null) {\n                    this.setListeners();\n                }\n                for(var type in this.listeners) {\n                    this.map.events.register(type, this, this.listeners[type]);\n                }\n                activated = true;\n                if(this.previousStack.length == 0) {\n                    this.initStack();\n                }\n            }\n        }\n        return activated;\n    },\n    \n        initStack: function() {\n        if(this.map.getCenter()) {\n            this.listeners.moveend();\n        }\n    },\n    \n        deactivate: function() {\n        var deactivated = false;\n        if(this.map) {\n            if(OpenLayers.Control.prototype.deactivate.apply(this)) {\n                for(var type in this.listeners) {\n                    this.map.events.unregister(\n                        type, this, this.listeners[type]\n                    );\n                }\n                if(this.clearOnDeactivate) {\n                    this.clear();\n                }\n                deactivated = true;\n            }\n        }\n        return deactivated;\n    },\n    \n    CLASS_NAME: \"OpenLayers.Control.NavigationHistory\"\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/OverviewMap.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.OverviewMap = OpenLayers.Class(OpenLayers.Control, {\n\n        element: null,\n    \n        ovmap: null,\n\n        size: {w: 180, h: 90},\n\n        layers: null,\n    \n        minRectSize: 15,\n    \n        minRectDisplayClass: \"RectReplacement\",\n\n        minRatio: 8,\n\n        maxRatio: 32,\n    \n        mapOptions: null,\n\n        autoPan: false,\n    \n        handlers: null,\n\n        resolutionFactor: 1,\n\n        maximized: false,\n\n        initialize: function(options) {\n        this.layers = [];\n        this.handlers = {};\n        OpenLayers.Control.prototype.initialize.apply(this, [options]);\n    },\n    \n        destroy: function() {\n        if (!this.mapDiv) { // we've already been destroyed\n            return;\n        }\n        if (this.handlers.click) {\n            this.handlers.click.destroy();\n        }\n        if (this.handlers.drag) {\n            this.handlers.drag.destroy();\n        }\n\n        this.ovmap && this.ovmap.viewPortDiv.removeChild(this.extentRectangle);\n        this.extentRectangle = null;\n\n        if (this.rectEvents) {\n            this.rectEvents.destroy();\n            this.rectEvents = null;\n        }\n\n        if (this.ovmap) {\n            this.ovmap.destroy();\n            this.ovmap = null;\n        }\n        \n        this.element.removeChild(this.mapDiv);\n        this.mapDiv = null;\n\n        this.div.removeChild(this.element);\n        this.element = null;\n\n        if (this.maximizeDiv) {\n            this.div.removeChild(this.maximizeDiv);\n            this.maximizeDiv = null;\n        }\n        \n        if (this.minimizeDiv) {\n            this.div.removeChild(this.minimizeDiv);\n            this.minimizeDiv = null;\n        }\n\n        this.map.events.un({\n            buttonclick: this.onButtonClick,\n            moveend: this.update,\n            changebaselayer: this.baseLayerDraw,\n            scope: this\n        });\n\n        OpenLayers.Control.prototype.destroy.apply(this, arguments);    \n    },\n\n        baseLayerDraw: function() {\n        this.draw();\n        this.map.events.unregister(\"changebaselayer\", this, this.baseLayerDraw);\n    },\n\n        rectDrag: function(px) {\n        var deltaX = this.handlers.drag.last.x - px.x;\n        var deltaY = this.handlers.drag.last.y - px.y;\n        if(deltaX != 0 || deltaY != 0) {\n            var rectTop = this.rectPxBounds.top;\n            var rectLeft = this.rectPxBounds.left;\n            var rectHeight = Math.abs(this.rectPxBounds.getHeight());\n            var rectWidth = this.rectPxBounds.getWidth();\n            var newTop = Math.max(0, (rectTop - deltaY));\n            newTop = Math.min(newTop,\n                              this.ovmap.size.h - this.hComp - rectHeight);\n            var newLeft = Math.max(0, (rectLeft - deltaX));\n            newLeft = Math.min(newLeft,\n                               this.ovmap.size.w - this.wComp - rectWidth);\n            this.setRectPxBounds(new OpenLayers.Bounds(newLeft,\n                                                       newTop + rectHeight,\n                                                       newLeft + rectWidth,\n                                                       newTop));\n        }\n    },\n    \n        mapDivClick: function(evt) {\n        var pxCenter = this.rectPxBounds.getCenterPixel();\n        var deltaX = evt.xy.x - pxCenter.x;\n        var deltaY = evt.xy.y - pxCenter.y;\n        var top = this.rectPxBounds.top;\n        var left = this.rectPxBounds.left;\n        var height = Math.abs(this.rectPxBounds.getHeight());\n        var width = this.rectPxBounds.getWidth();\n        var newTop = Math.max(0, (top + deltaY));\n        newTop = Math.min(newTop, this.ovmap.size.h - height);\n        var newLeft = Math.max(0, (left + deltaX));\n        newLeft = Math.min(newLeft, this.ovmap.size.w - width);\n        this.setRectPxBounds(new OpenLayers.Bounds(newLeft,\n                                                   newTop + height,\n                                                   newLeft + width,\n                                                   newTop));\n        this.updateMapToRect();\n    },\n    \n        onButtonClick: function(evt) {\n        if (evt.buttonElement === this.minimizeDiv) {\n            this.minimizeControl();\n        } else if (evt.buttonElement === this.maximizeDiv) {\n            this.maximizeControl();\n        }\n    },\n\n        maximizeControl: function(e) {\n        this.element.style.display = '';\n        this.showToggle(false);\n        if (e != null) {\n            OpenLayers.Event.stop(e);                                            \n        }\n    },\n\n        minimizeControl: function(e) {\n        this.element.style.display = 'none';\n        this.showToggle(true);\n        if (e != null) {\n            OpenLayers.Event.stop(e);                                            \n        }\n    },\n\n        showToggle: function(minimize) {\n        if (this.maximizeDiv) {\n            this.maximizeDiv.style.display = minimize ? '' : 'none';\n        }\n        if (this.minimizeDiv) {\n            this.minimizeDiv.style.display = minimize ? 'none' : '';\n        }\n    },\n\n        update: function() {\n        if(this.ovmap == null) {\n            this.createMap();\n        }\n        \n        if(this.autoPan || !this.isSuitableOverview()) {\n            this.updateOverview();\n        }\n        this.updateRectToMap();\n    },\n    \n        isSuitableOverview: function() {\n        var mapExtent = this.map.getExtent();\n        var maxExtent = this.map.getMaxExtent();\n        var testExtent = new OpenLayers.Bounds(\n                                Math.max(mapExtent.left, maxExtent.left),\n                                Math.max(mapExtent.bottom, maxExtent.bottom),\n                                Math.min(mapExtent.right, maxExtent.right),\n                                Math.min(mapExtent.top, maxExtent.top));        \n\n        if (this.ovmap.getProjection() != this.map.getProjection()) {\n            testExtent = testExtent.transform(\n                this.map.getProjectionObject(),\n                this.ovmap.getProjectionObject() );\n        }\n\n        var resRatio = this.ovmap.getResolution() / this.map.getResolution();\n        return ((resRatio > this.minRatio) &&\n                (resRatio <= this.maxRatio) &&\n                (this.ovmap.getExtent().containsBounds(testExtent)));\n    },\n    \n        updateOverview: function() {\n        var mapRes = this.map.getResolution();\n        var targetRes = this.ovmap.getResolution();\n        var resRatio = targetRes / mapRes;\n        if(resRatio > this.maxRatio) {\n            targetRes = this.minRatio * mapRes;            \n        } else if(resRatio <= this.minRatio) {\n            targetRes = this.maxRatio * mapRes;\n        }\n        var center;\n        if (this.ovmap.getProjection() != this.map.getProjection()) {\n            center = this.map.center.clone();\n            center.transform(this.map.getProjectionObject(),\n                this.ovmap.getProjectionObject() );\n        } else {\n            center = this.map.center;\n        }\n        this.ovmap.setCenter(center, this.ovmap.getZoomForResolution(\n            targetRes * this.resolutionFactor));\n        this.updateRectToMap();\n    },\n    \n        createMap: function() {\n        var options = OpenLayers.Util.extend(\n                        {controls: [], maxResolution: 'auto', \n                         fallThrough: false}, this.mapOptions);\n        this.ovmap = new OpenLayers.Map(this.mapDiv, options);\n        this.ovmap.viewPortDiv.appendChild(this.extentRectangle);\n        OpenLayers.Event.stopObserving(window, 'unload', this.ovmap.unloadDestroy);\n        \n        this.ovmap.addLayers(this.layers);\n        this.ovmap.zoomToMaxExtent();\n        this.wComp = parseInt(OpenLayers.Element.getStyle(this.extentRectangle,\n                                               'border-left-width')) +\n                     parseInt(OpenLayers.Element.getStyle(this.extentRectangle,\n                                               'border-right-width'));\n        this.wComp = (this.wComp) ? this.wComp : 2;\n        this.hComp = parseInt(OpenLayers.Element.getStyle(this.extentRectangle,\n                                               'border-top-width')) +\n                     parseInt(OpenLayers.Element.getStyle(this.extentRectangle,\n                                               'border-bottom-width'));\n        this.hComp = (this.hComp) ? this.hComp : 2;\n\n        this.handlers.drag = new OpenLayers.Handler.Drag(\n            this, {move: this.rectDrag, done: this.updateMapToRect},\n            {map: this.ovmap}\n        );\n        this.handlers.click = new OpenLayers.Handler.Click(\n            this, {\n                \"click\": this.mapDivClick\n            },{\n                \"single\": true, \"double\": false,\n                \"stopSingle\": true, \"stopDouble\": true,\n                \"pixelTolerance\": 1,\n                map: this.ovmap\n            }\n        );\n        this.handlers.click.activate();\n        \n        this.rectEvents = new OpenLayers.Events(this, this.extentRectangle,\n                                                null, true);\n        this.rectEvents.register(\"mouseover\", this, function(e) {\n            if(!this.handlers.drag.active && !this.map.dragging) {\n                this.handlers.drag.activate();\n            }\n        });\n        this.rectEvents.register(\"mouseout\", this, function(e) {\n            if(!this.handlers.drag.dragging) {\n                this.handlers.drag.deactivate();\n            }\n        });\n\n        if (this.ovmap.getProjection() != this.map.getProjection()) {\n            var sourceUnits = this.map.getProjectionObject().getUnits() ||\n                this.map.units || this.map.baseLayer.units;\n            var targetUnits = this.ovmap.getProjectionObject().getUnits() ||\n                this.ovmap.units || this.ovmap.baseLayer.units;\n            this.resolutionFactor = sourceUnits && targetUnits ?\n                OpenLayers.INCHES_PER_UNIT[sourceUnits] /\n                OpenLayers.INCHES_PER_UNIT[targetUnits] : 1;\n        }\n    },\n        \n        updateRectToMap: function() {\n        var bounds;\n        if (this.ovmap.getProjection() != this.map.getProjection()) {\n            bounds = this.map.getExtent().transform(\n                this.map.getProjectionObject(), \n                this.ovmap.getProjectionObject() );\n        } else {\n            bounds = this.map.getExtent();\n        }\n        var pxBounds = this.getRectBoundsFromMapBounds(bounds);\n        if (pxBounds) {\n            this.setRectPxBounds(pxBounds);\n        }\n    },\n    \n        updateMapToRect: function() {\n        var lonLatBounds = this.getMapBoundsFromRectBounds(this.rectPxBounds);\n        if (this.ovmap.getProjection() != this.map.getProjection()) {\n            lonLatBounds = lonLatBounds.transform(\n                this.ovmap.getProjectionObject(),\n                this.map.getProjectionObject() );\n        }\n        this.map.panTo(lonLatBounds.getCenterLonLat());\n    },\n\n        setRectPxBounds: function(pxBounds) {\n        var top = Math.max(pxBounds.top, 0);\n        var left = Math.max(pxBounds.left, 0);\n        var bottom = Math.min(pxBounds.top + Math.abs(pxBounds.getHeight()),\n                              this.ovmap.size.h - this.hComp);\n        var right = Math.min(pxBounds.left + pxBounds.getWidth(),\n                             this.ovmap.size.w - this.wComp);\n        var width = Math.max(right - left, 0);\n        var height = Math.max(bottom - top, 0);\n        if(width < this.minRectSize || height < this.minRectSize) {\n            this.extentRectangle.className = this.displayClass +\n                                             this.minRectDisplayClass;\n            var rLeft = left + (width / 2) - (this.minRectSize / 2);\n            var rTop = top + (height / 2) - (this.minRectSize / 2);\n            this.extentRectangle.style.top = Math.round(rTop) + 'px';\n            this.extentRectangle.style.left = Math.round(rLeft) + 'px';\n            this.extentRectangle.style.height = this.minRectSize + 'px';\n            this.extentRectangle.style.width = this.minRectSize + 'px';\n        } else {\n            this.extentRectangle.className = this.displayClass +\n                                             'ExtentRectangle';\n            this.extentRectangle.style.top = Math.round(top) + 'px';\n            this.extentRectangle.style.left = Math.round(left) + 'px';\n            this.extentRectangle.style.height = Math.round(height) + 'px';\n            this.extentRectangle.style.width = Math.round(width) + 'px';\n        }\n        this.rectPxBounds = new OpenLayers.Bounds(\n            Math.round(left), Math.round(bottom),\n            Math.round(right), Math.round(top)\n        );\n    },\n\n        getRectBoundsFromMapBounds: function(lonLatBounds) {\n        var leftBottomPx = this.getOverviewPxFromLonLat({\n            lon: lonLatBounds.left,\n            lat: lonLatBounds.bottom\n        });\n        var rightTopPx = this.getOverviewPxFromLonLat({\n            lon: lonLatBounds.right,\n            lat: lonLatBounds.top\n        });\n        var bounds = null;\n        if (leftBottomPx && rightTopPx) {\n            bounds = new OpenLayers.Bounds(leftBottomPx.x, leftBottomPx.y,\n                                           rightTopPx.x, rightTopPx.y);\n        }\n        return bounds;\n    },\n\n        getMapBoundsFromRectBounds: function(pxBounds) {\n        var leftBottomLonLat = this.getLonLatFromOverviewPx({\n            x: pxBounds.left,\n            y: pxBounds.bottom\n        });\n        var rightTopLonLat = this.getLonLatFromOverviewPx({\n            x: pxBounds.right,\n            y: pxBounds.top\n        });\n        return new OpenLayers.Bounds(leftBottomLonLat.lon, leftBottomLonLat.lat,\n                                     rightTopLonLat.lon, rightTopLonLat.lat);\n    },\n\n        getLonLatFromOverviewPx: function(overviewMapPx) {\n        var size = this.ovmap.size;\n        var res  = this.ovmap.getResolution();\n        var center = this.ovmap.getExtent().getCenterLonLat();\n    \n        var deltaX = overviewMapPx.x - (size.w / 2);\n        var deltaY = overviewMapPx.y - (size.h / 2);\n\n        return {\n            lon: center.lon + deltaX * res,\n            lat: center.lat - deltaY * res\n        };\n    },\n\n        getOverviewPxFromLonLat: function(lonlat) {\n        var res = this.ovmap.getResolution();\n        var extent = this.ovmap.getExtent();\n        if (extent) {\n            return {\n                x: Math.round(1/res * (lonlat.lon - extent.left)),\n                y: Math.round(1/res * (extent.top - lonlat.lat))\n            };\n        } \n    },\n\n    CLASS_NAME: 'OpenLayers.Control.OverviewMap'\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/Pan.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.Pan = OpenLayers.Class(OpenLayers.Control.Button, {\n\n        slideFactor: 50,\n\n        slideRatio: null,\n\n        direction: null,\n\n        initialize: function(direction, options) {\n    \n        this.direction = direction;\n        this.CLASS_NAME += this.direction;\n        \n        OpenLayers.Control.prototype.initialize.apply(this, [options]);\n    },\n    \n        trigger: function(){\n        if (this.map) {\n            var getSlideFactor = OpenLayers.Function.bind(function (dim) {\n                return this.slideRatio ?\n                    this.map.getSize()[dim] * this.slideRatio :\n                    this.slideFactor;\n            }, this);\n    \n            switch (this.direction) {\n                case OpenLayers.Control.Pan.NORTH: \n                    this.map.pan(0, -getSlideFactor(\"h\"));\n                    break;\n                case OpenLayers.Control.Pan.SOUTH: \n                    this.map.pan(0, getSlideFactor(\"h\"));\n                    break;\n                case OpenLayers.Control.Pan.WEST: \n                    this.map.pan(-getSlideFactor(\"w\"), 0);\n                    break;\n                case OpenLayers.Control.Pan.EAST: \n                    this.map.pan(getSlideFactor(\"w\"), 0);\n                    break;\n            }   \n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.Pan\"\n});\n\nOpenLayers.Control.Pan.NORTH = \"North\";\nOpenLayers.Control.Pan.SOUTH = \"South\";\nOpenLayers.Control.Pan.EAST = \"East\";\nOpenLayers.Control.Pan.WEST = \"West\";\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/PanPanel.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.PanPanel = OpenLayers.Class(OpenLayers.Control.Panel, {\n\n        slideFactor: 50,\n\n        slideRatio: null,\n\n        initialize: function(options) {\n        OpenLayers.Control.Panel.prototype.initialize.apply(this, [options]);\n        var options = {\n            slideFactor: this.slideFactor,\n            slideRatio: this.slideRatio\n        };\n        this.addControls([\n            new OpenLayers.Control.Pan(OpenLayers.Control.Pan.NORTH, options),\n            new OpenLayers.Control.Pan(OpenLayers.Control.Pan.SOUTH, options),\n            new OpenLayers.Control.Pan(OpenLayers.Control.Pan.EAST, options),\n            new OpenLayers.Control.Pan(OpenLayers.Control.Pan.WEST, options)\n        ]);\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.PanPanel\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/PanZoom.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Control.PanZoom = OpenLayers.Class(OpenLayers.Control, {\n\n        slideFactor: 50,\n\n        slideRatio: null,\n\n        buttons: null,\n\n        position: null,\n\n        initialize: function(options) {\n        this.position = new OpenLayers.Pixel(OpenLayers.Control.PanZoom.X,\n                                             OpenLayers.Control.PanZoom.Y);\n        OpenLayers.Control.prototype.initialize.apply(this, arguments);\n    },\n\n        destroy: function() {\n        if (this.map && !this.outsideViewport) {\n            this.map.events.unregister(\"buttonclick\", this, this.onButtonClick);\n        }\n        this.removeButtons();\n        this.buttons = null;\n        this.position = null;\n        OpenLayers.Control.prototype.destroy.apply(this, arguments);\n    },\n\n        setMap: function(map) {\n        OpenLayers.Control.prototype.setMap.apply(this, arguments);\n        var target;\n        if (this.outsideViewport) {\n            this.events.attachToElement(this.div);\n            target = this;\n        } else {\n            target = this.map;\n        }\n        target.events.register('buttonclick', this, this.onButtonClick);\n    },\n\n        draw: function(px) {\n        OpenLayers.Control.prototype.draw.apply(this, arguments);\n        px = this.position;\n        this.buttons = [];\n\n        var sz = {w: 18, h: 18};\n        var centered = new OpenLayers.Pixel(px.x+sz.w/2, px.y);\n\n        this._addButton(\"panup\", \"north-mini.png\", centered, sz);\n        px.y = centered.y+sz.h;\n        this._addButton(\"panleft\", \"west-mini.png\", px, sz);\n        this._addButton(\"panright\", \"east-mini.png\", px.add(sz.w, 0), sz);\n        this._addButton(\"pandown\", \"south-mini.png\", \n                        centered.add(0, sz.h*2), sz);\n        this._addButton(\"zoomin\", \"zoom-plus-mini.png\", \n                        centered.add(0, sz.h*3+5), sz);\n        this._addButton(\"zoomworld\", \"zoom-world-mini.png\", \n                        centered.add(0, sz.h*4+5), sz);\n        this._addButton(\"zoomout\", \"zoom-minus-mini.png\", \n                        centered.add(0, sz.h*5+5), sz);\n        return this.div;\n    },\n    \n        _addButton:function(id, img, xy, sz) {\n        var imgLocation = OpenLayers.Util.getImageLocation(img);\n        var btn = OpenLayers.Util.createAlphaImageDiv(\n                                    this.id + \"_\" + id, \n                                    xy, sz, imgLocation, \"absolute\");\n        btn.style.cursor = \"pointer\";\n        this.div.appendChild(btn);\n        btn.action = id;\n        btn.className = \"olButton\";\n        this.buttons.push(btn);\n        return btn;\n    },\n    \n        _removeButton: function(btn) {\n        this.div.removeChild(btn);\n        OpenLayers.Util.removeItem(this.buttons, btn);\n    },\n    \n        removeButtons: function() {\n        for(var i=this.buttons.length-1; i>=0; --i) {\n            this._removeButton(this.buttons[i]);\n        }\n    },\n    \n        onButtonClick: function(evt) {\n        var btn = evt.buttonElement;\n        switch (btn.action) {\n            case \"panup\": \n                this.map.pan(0, -this.getSlideFactor(\"h\"));\n                break;\n            case \"pandown\": \n                this.map.pan(0, this.getSlideFactor(\"h\"));\n                break;\n            case \"panleft\": \n                this.map.pan(-this.getSlideFactor(\"w\"), 0);\n                break;\n            case \"panright\": \n                this.map.pan(this.getSlideFactor(\"w\"), 0);\n                break;\n            case \"zoomin\": \n                this.map.zoomIn(); \n                break;\n            case \"zoomout\": \n                this.map.zoomOut(); \n                break;\n            case \"zoomworld\": \n                this.map.zoomToMaxExtent(); \n                break;\n        }\n    },\n    \n        getSlideFactor: function(dim) {\n        return this.slideRatio ?\n            this.map.getSize()[dim] * this.slideRatio :\n            this.slideFactor;\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.PanZoom\"\n});\n\nOpenLayers.Control.PanZoom.X = 4;\n\nOpenLayers.Control.PanZoom.Y = 4;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/PanZoomBar.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Control.PanZoomBar = OpenLayers.Class(OpenLayers.Control.PanZoom, {\n\n        zoomStopWidth: 18,\n\n        zoomStopHeight: 11,\n\n        slider: null,\n\n        sliderEvents: null,\n\n        zoombarDiv: null,\n\n        zoomWorldIcon: false,\n\n        panIcons: true,\n\n        forceFixedZoomLevel: false,\n\n        mouseDragStart: null,\n\n        deltaY: null,\n\n        zoomStart: null,\n\n        destroy: function() {\n\n        this._removeZoomBar();\n\n        this.map.events.un({\n            \"changebaselayer\": this.redraw,\n            \"updatesize\": this.redraw,\n            scope: this\n        });\n\n        OpenLayers.Control.PanZoom.prototype.destroy.apply(this, arguments);\n\n        delete this.mouseDragStart;\n        delete this.zoomStart;\n    },\n    \n        setMap: function(map) {\n        OpenLayers.Control.PanZoom.prototype.setMap.apply(this, arguments);\n        \n        if (this.outsideViewport) {\n            this.events.attachToElement(this.div);\n        }\n\n        this.map.events.on({\n            \"changebaselayer\": this.redraw,\n            \"updatesize\": this.redraw,\n            scope: this\n        });\n    },\n\n        redraw: function() {\n        if (this.div != null) {\n            this.removeButtons();\n            this._removeZoomBar();\n        }  \n        this.draw();\n    },\n    \n        draw: function(px) {\n        OpenLayers.Control.prototype.draw.apply(this, arguments);\n        px = this.position.clone();\n        this.buttons = [];\n\n        var sz = {w: 18, h: 18};\n        if (this.panIcons) {\n            var centered = new OpenLayers.Pixel(px.x+sz.w/2, px.y);\n            var wposition = sz.w;\n\n            if (this.zoomWorldIcon) {\n                centered = new OpenLayers.Pixel(px.x+sz.w, px.y);\n            }\n\n            this._addButton(\"panup\", \"north-mini.png\", centered, sz);\n            px.y = centered.y+sz.h;\n            this._addButton(\"panleft\", \"west-mini.png\", px, sz);\n            if (this.zoomWorldIcon) {\n                this._addButton(\"zoomworld\", \"zoom-world-mini.png\", px.add(sz.w, 0), sz);\n\n                wposition *= 2;\n            }\n            this._addButton(\"panright\", \"east-mini.png\", px.add(wposition, 0), sz);\n            this._addButton(\"pandown\", \"south-mini.png\", centered.add(0, sz.h*2), sz);\n            this._addButton(\"zoomin\", \"zoom-plus-mini.png\", centered.add(0, sz.h*3+5), sz);\n            centered = this._addZoomBar(centered.add(0, sz.h*4 + 5));\n            this._addButton(\"zoomout\", \"zoom-minus-mini.png\", centered, sz);\n        }\n        else {\n            this._addButton(\"zoomin\", \"zoom-plus-mini.png\", px, sz);\n            centered = this._addZoomBar(px.add(0, sz.h));\n            this._addButton(\"zoomout\", \"zoom-minus-mini.png\", centered, sz);\n            if (this.zoomWorldIcon) {\n                centered = centered.add(0, sz.h+3);\n                this._addButton(\"zoomworld\", \"zoom-world-mini.png\", centered, sz);\n            }\n        }\n        return this.div;\n    },\n\n        _addZoomBar:function(centered) {\n        var imgLocation = OpenLayers.Util.getImageLocation(\"slider.png\");\n        var id = this.id + \"_\" + this.map.id;\n        var minZoom = this.map.getMinZoom();\n        var zoomsToEnd = this.map.getNumZoomLevels() - 1 - this.map.getZoom();\n        var slider = OpenLayers.Util.createAlphaImageDiv(id,\n                       centered.add(-1, zoomsToEnd * this.zoomStopHeight), \n                       {w: 20, h: 9},\n                       imgLocation,\n                       \"absolute\");\n        slider.style.cursor = \"move\";\n        this.slider = slider;\n        \n        this.sliderEvents = new OpenLayers.Events(this, slider, null, true,\n                                            {includeXY: true});\n        this.sliderEvents.on({\n            \"touchstart\": this.zoomBarDown,\n            \"touchmove\": this.zoomBarDrag,\n            \"touchend\": this.zoomBarUp,\n            \"mousedown\": this.zoomBarDown,\n            \"mousemove\": this.zoomBarDrag,\n            \"mouseup\": this.zoomBarUp\n        });\n        \n        var sz = {\n            w: this.zoomStopWidth,\n            h: this.zoomStopHeight * (this.map.getNumZoomLevels() - minZoom)\n        };\n        var imgLocation = OpenLayers.Util.getImageLocation(\"zoombar.png\");\n        var div = null;\n        \n        if (OpenLayers.Util.alphaHack()) {\n            var id = this.id + \"_\" + this.map.id;\n            div = OpenLayers.Util.createAlphaImageDiv(id, centered,\n                                      {w: sz.w, h: this.zoomStopHeight},\n                                      imgLocation,\n                                      \"absolute\", null, \"crop\");\n            div.style.height = sz.h + \"px\";\n        } else {\n            div = OpenLayers.Util.createDiv(\n                        'OpenLayers_Control_PanZoomBar_Zoombar' + this.map.id,\n                        centered,\n                        sz,\n                        imgLocation);\n        }\n        div.style.cursor = \"pointer\";\n        div.className = \"olButton\";\n        this.zoombarDiv = div;\n        \n        this.div.appendChild(div);\n\n        this.startTop = parseInt(div.style.top);\n        this.div.appendChild(slider);\n\n        this.map.events.register(\"zoomend\", this, this.moveZoomBar);\n\n        centered = centered.add(0, \n            this.zoomStopHeight * (this.map.getNumZoomLevels() - minZoom));\n        return centered; \n    },\n    \n        _removeZoomBar: function() {\n        this.sliderEvents.un({\n            \"touchstart\": this.zoomBarDown,\n            \"touchmove\": this.zoomBarDrag,\n            \"touchend\": this.zoomBarUp,\n            \"mousedown\": this.zoomBarDown,\n            \"mousemove\": this.zoomBarDrag,\n            \"mouseup\": this.zoomBarUp\n        });\n        this.sliderEvents.destroy();\n        \n        this.div.removeChild(this.zoombarDiv);\n        this.zoombarDiv = null;\n        this.div.removeChild(this.slider);\n        this.slider = null;\n        \n        this.map.events.unregister(\"zoomend\", this, this.moveZoomBar);\n    },\n    \n        onButtonClick: function(evt) {\n        OpenLayers.Control.PanZoom.prototype.onButtonClick.apply(this, arguments);\n        if (evt.buttonElement === this.zoombarDiv) {\n            var levels = evt.buttonXY.y / this.zoomStopHeight;\n            if(this.forceFixedZoomLevel || !this.map.fractionalZoom) {\n                levels = Math.floor(levels);\n            }    \n            var zoom = (this.map.getNumZoomLevels() - 1) - levels; \n            zoom = Math.min(Math.max(zoom, 0), this.map.getNumZoomLevels() - 1);\n            this.map.zoomTo(zoom);\n        }\n    },\n    \n        passEventToSlider:function(evt) {\n        this.sliderEvents.handleBrowserEvent(evt);\n    },\n    \n    /*\n     * Method: zoomBarDown\n     * event listener for clicks on the slider\n     *\n     * Parameters:\n     * evt - {<OpenLayers.Event>} \n     */\n    zoomBarDown:function(evt) {\n        if (!OpenLayers.Event.isLeftClick(evt) && !OpenLayers.Event.isSingleTouch(evt)) {\n            return;\n        }\n        var target = this.outsideViewport ? this : this.map;\n        target.events.on({\n            touchmove: this.passEventToSlider,\n            mousemove: this.passEventToSlider,\n            mouseup: this.passEventToSlider,\n            scope: this\n        });\n        \n        this.mouseDragStart = evt.xy.clone();\n        this.zoomStart = evt.xy.clone();\n        this.div.style.cursor = \"move\";\n        this.zoombarDiv.offsets = null; \n        OpenLayers.Event.stop(evt);\n    },\n    \n    /*\n     * Method: zoomBarDrag\n     * This is what happens when a click has occurred, and the client is\n     * dragging.  Here we must ensure that the slider doesn't go beyond the\n     * bottom/top of the zoombar div, as well as moving the slider to its new\n     * visual location\n     *\n     * Parameters:\n     * evt - {<OpenLayers.Event>} \n     */\n    zoomBarDrag:function(evt) {\n        if (this.mouseDragStart != null) {\n            var deltaY = this.mouseDragStart.y - evt.xy.y;\n            var offsets = OpenLayers.Util.pagePosition(this.zoombarDiv);\n            if ((evt.clientY - offsets[1]) > 0 && \n                (evt.clientY - offsets[1]) < parseInt(this.zoombarDiv.style.height) - 2) {\n                var newTop = parseInt(this.slider.style.top) - deltaY;\n                this.slider.style.top = newTop+\"px\";\n                this.mouseDragStart = evt.xy.clone();\n            }\n            this.deltaY = this.zoomStart.y - evt.xy.y;\n            OpenLayers.Event.stop(evt);\n        }\n    },\n    \n    /*\n     * Method: zoomBarUp\n     * Perform cleanup when a mouseup event is received -- discover new zoom\n     * level and switch to it.\n     *\n     * Parameters:\n     * evt - {<OpenLayers.Event>} \n     */\n    zoomBarUp:function(evt) {\n        if (!OpenLayers.Event.isLeftClick(evt) && evt.type !== \"touchend\") {\n            return;\n        }\n        if (this.mouseDragStart) {\n            this.div.style.cursor=\"\";\n            var target = this.outsideViewport ? this : this.map;\n            target.events.un({\n                \"touchmove\": this.passEventToSlider,\n                \"mouseup\": this.passEventToSlider,\n                \"mousemove\": this.passEventToSlider,\n                scope: this\n            });\n            var zoomLevel = this.map.zoom;\n            if (!this.forceFixedZoomLevel && this.map.fractionalZoom) {\n                zoomLevel += this.deltaY/this.zoomStopHeight;\n                zoomLevel = Math.min(Math.max(zoomLevel, 0), \n                                     this.map.getNumZoomLevels() - 1);\n            } else {\n                zoomLevel += this.deltaY/this.zoomStopHeight;\n                zoomLevel = Math.max(Math.round(zoomLevel), 0);      \n            }\n            this.map.zoomTo(zoomLevel);\n            this.mouseDragStart = null;\n            this.zoomStart = null;\n            this.deltaY = 0;\n            OpenLayers.Event.stop(evt);\n        }\n    },\n    \n    /*\n    * Method: moveZoomBar\n    * Change the location of the slider to match the current zoom level.\n    */\n    moveZoomBar:function() {\n        var newTop = \n            ((this.map.getNumZoomLevels()-1) - this.map.getZoom()) * \n            this.zoomStopHeight + this.startTop + 1;\n        this.slider.style.top = newTop + \"px\";\n    },    \n    \n    CLASS_NAME: \"OpenLayers.Control.PanZoomBar\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/Panel.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.Panel = OpenLayers.Class(OpenLayers.Control, {\n        controls: null,    \n    \n        autoActivate: true,\n\n        defaultControl: null,\n    \n        saveState: false,\n      \n        allowDepress: false,\n    \n        activeState: null,\n\n        initialize: function(options) {\n        OpenLayers.Control.prototype.initialize.apply(this, [options]);\n        this.controls = [];\n        this.activeState = {};\n    },\n\n        destroy: function() {\n        if (this.map) {\n            this.map.events.unregister(\"buttonclick\", this, this.onButtonClick);\n        }\n        OpenLayers.Control.prototype.destroy.apply(this, arguments);\n        for (var ctl, i = this.controls.length - 1; i >= 0; i--) {\n            ctl = this.controls[i];\n            if (ctl.events) {\n                ctl.events.un({\n                    activate: this.iconOn,\n                    deactivate: this.iconOff\n                });\n            }\n            ctl.panel_div = null;\n        }\n        this.activeState = null;\n    },\n\n        activate: function() {\n        if (OpenLayers.Control.prototype.activate.apply(this, arguments)) {\n            var control;\n            for (var i=0, len=this.controls.length; i<len; i++) {\n                control = this.controls[i];\n                if (control === this.defaultControl ||\n                            (this.saveState && this.activeState[control.id])) {\n                    control.activate();\n                }\n            }    \n            if (this.saveState === true) {\n                this.defaultControl = null;\n            }\n            this.redraw();\n            return true;\n        } else {\n            return false;\n        }\n    },\n    \n        deactivate: function() {\n        if (OpenLayers.Control.prototype.deactivate.apply(this, arguments)) {\n            var control;\n            for (var i=0, len=this.controls.length; i<len; i++) {\n                control = this.controls[i];\n                this.activeState[control.id] = control.deactivate();\n            }    \n            this.redraw();\n            return true;\n        } else {\n            return false;\n        }\n    },\n    \n        redraw: function() {\n        for (var l=this.div.childNodes.length, i=l-1; i>=0; i--) {\n            this.div.removeChild(this.div.childNodes[i]);\n        }\n        this.div.innerHTML = \"\";\n        if (this.active) {\n            for (var i=0, len=this.controls.length; i<len; i++) {\n                this.div.appendChild(this.controls[i].panel_div);\n            }\n        }\n    },\n    \n        activateControl: function (control) {\n        if (!this.active) { return false; }\n        if (control.type == OpenLayers.Control.TYPE_BUTTON) {\n            control.trigger();\n            return;\n        }\n        if (control.type == OpenLayers.Control.TYPE_TOGGLE) {\n            if (control.active) {\n                control.deactivate();\n            } else {\n                control.activate();\n            }\n            return;\n        }\n        if (this.allowDepress && control.active) {\n            control.deactivate();\n        } else {\n            var c;\n            for (var i=0, len=this.controls.length; i<len; i++) {\n                c = this.controls[i];\n                if (c != control &&\n                   (c.type === OpenLayers.Control.TYPE_TOOL || c.type == null)) {\n                    c.deactivate();\n                }\n            }\n            control.activate();\n        }\n    },\n\n        createControlMarkup: function(control) {\n        return document.createElement(\"div\");\n    },\n   \n         iconOn: function() {\n        var d = this.panel_div; // \"this\" refers to a control on panel!\n        var re = new RegExp(\"\\\\b(\" + this.displayClass + \"Item)Inactive\\\\b\");\n        d.className = d.className.replace(re, \"$1Active\");\n    },\n\n         iconOff: function() {\n        var d = this.panel_div; // \"this\" refers to a control on panel!\n        var re = new RegExp(\"\\\\b(\" + this.displayClass + \"Item)Active\\\\b\");\n        d.className = d.className.replace(re, \"$1Inactive\");\n    },\n    \n        onButtonClick: function (evt) {\n        var controls = this.controls,\n            button = evt.buttonElement;\n        for (var i=controls.length-1; i>=0; --i) {\n            if (controls[i].panel_div === button) {\n                this.activateControl(controls[i]);\n                break;\n            }\n        }\n    },\n\n        getControlsBy: function(property, match) {\n        var test = (typeof match.test == \"function\");\n        var found = OpenLayers.Array.filter(this.controls, function(item) {\n            return item[property] == match || (test && match.test(item[property]));\n        });\n        return found;\n    },\n\n        getControlsByName: function(match) {\n        return this.getControlsBy(\"name\", match);\n    },\n\n        getControlsByClass: function(match) {\n        return this.getControlsBy(\"CLASS_NAME\", match);\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.Panel\"\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/Permalink.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Control.Permalink = OpenLayers.Class(OpenLayers.Control, {\n    \n        argParserClass: OpenLayers.Control.ArgParser,\n\n        element: null,\n    \n        anchor: false,\n\n        base: '',\n\n        displayProjection: null, \n\n        initialize: function(element, base, options) {\n        if (element !== null && typeof element == 'object' && !OpenLayers.Util.isElement(element)) {\n            options = element;\n            this.base = document.location.href;\n            OpenLayers.Control.prototype.initialize.apply(this, [options]);\n            if (this.element != null) {\n                this.element = OpenLayers.Util.getElement(this.element);\n            }\n        }\n        else {\n            OpenLayers.Control.prototype.initialize.apply(this, [options]);\n            this.element = OpenLayers.Util.getElement(element);\n            this.base = base || document.location.href;\n        }\n    },\n    \n        destroy: function()  {\n        if (this.element && this.element.parentNode == this.div) {\n            this.div.removeChild(this.element);\n            this.element = null;\n        }\n        if (this.map) {\n            this.map.events.unregister('moveend', this, this.updateLink);\n        }\n\n        OpenLayers.Control.prototype.destroy.apply(this, arguments); \n    },\n\n        setMap: function(map) {\n        OpenLayers.Control.prototype.setMap.apply(this, arguments);\n        for(var i=0, len=this.map.controls.length; i<len; i++) {\n            var control = this.map.controls[i];\n            if (control.CLASS_NAME == this.argParserClass.CLASS_NAME) {\n                if (control.displayProjection != this.displayProjection) {\n                    this.displayProjection = control.displayProjection;\n                }    \n                \n                break;\n            }\n        }\n        if (i == this.map.controls.length) {\n            this.map.addControl(new this.argParserClass(\n                { 'displayProjection': this.displayProjection }));       \n        }\n\n    },\n\n        updateLink: function() {\n        var separator = this.anchor ? '#' : '?';\n        var href = this.base;\n        var anchor = null;\n        if (href.indexOf(\"#\") != -1 && this.anchor == false) {\n            anchor = href.substring( href.indexOf(\"#\"), href.length);\n        }\n        if (href.indexOf(separator) != -1) {\n            href = href.substring( 0, href.indexOf(separator) );\n        }\n        var splits = href.split(\"#\");\n        href = splits[0] + separator+ OpenLayers.Util.getParameterString(this.createParams());\n        if (anchor) {\n            href += anchor;\n        }\n        if (this.anchor && !this.element) {\n            window.location.href = href;\n        }\n        else {\n            this.element.href = href;\n        }\n    }, \n    \n        createParams: function(center, zoom, layers) {\n        center = center || this.map.getCenter();\n          \n        var params = OpenLayers.Util.getParameters(this.base);\n        if (center) { \n            params.zoom = zoom || this.map.getZoom(); \n            var lat = center.lat;\n            var lon = center.lon;\n            \n            if (this.displayProjection) {\n                var mapPosition = OpenLayers.Projection.transform(\n                  { x: lon, y: lat }, \n                  this.map.getProjectionObject(), \n                  this.displayProjection );\n                lon = mapPosition.x;  \n                lat = mapPosition.y;  \n            }       \n            params.lat = Math.round(lat*100000)/100000;\n            params.lon = Math.round(lon*100000)/100000;\n            layers = layers || this.map.layers;  \n            params.layers = '';\n            for (var i=0, len=layers.length; i<len; i++) {\n                var layer = layers[i];\n    \n                if (layer.isBaseLayer) {\n                    params.layers += (layer == this.map.baseLayer) ? \"B\" : \"0\";\n                } else {\n                    params.layers += (layer.getVisibility()) ? \"T\" : \"F\";           \n                }\n            }\n        }\n\n        return params;\n    }, \n\n    CLASS_NAME: \"OpenLayers.Control.Permalink\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/PinchZoom.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.PinchZoom = OpenLayers.Class(OpenLayers.Control, {\n\n        type: OpenLayers.Control.TYPE_TOOL,\n\n        pinchOrigin: null,    \n    \n        currentCenter: null,    \n\n        autoActivate: true,\n\n        preserveCenter: false,\n    \n    \n        initialize: function(options) {\n        OpenLayers.Control.prototype.initialize.apply(this, arguments);\n        this.handler = new OpenLayers.Handler.Pinch(this, {\n            start: this.pinchStart,\n            move: this.pinchMove,\n            done: this.pinchDone\n        }, this.handlerOptions);\n    },\n    \n        pinchStart: function(evt, pinchData) {\n        var xy = (this.preserveCenter) ?\n            this.map.getPixelFromLonLat(this.map.getCenter()) : evt.xy;\n        this.pinchOrigin = xy;\n        this.currentCenter = xy;\n    },\n    \n        pinchMove: function(evt, pinchData) {\n        var scale = pinchData.scale;\n        var containerOrigin = this.map.layerContainerOriginPx;\n        var pinchOrigin = this.pinchOrigin;\n        var current = (this.preserveCenter) ?\n            this.map.getPixelFromLonLat(this.map.getCenter()) : evt.xy;\n\n        var dx = Math.round((containerOrigin.x + current.x - pinchOrigin.x) + (scale - 1) * (containerOrigin.x - pinchOrigin.x));\n        var dy = Math.round((containerOrigin.y + current.y - pinchOrigin.y) + (scale - 1) * (containerOrigin.y - pinchOrigin.y));\n\n        this.map.applyTransform(dx, dy, scale);\n        this.currentCenter = current;\n    },\n\n        pinchDone: function(evt, start, last) {\n        this.map.applyTransform();\n        var zoom = this.map.getZoomForResolution(this.map.getResolution() / last.scale, true);\n        if (zoom !== this.map.getZoom() || !this.currentCenter.equals(this.pinchOrigin)) {\n            var resolution = this.map.getResolutionForZoom(zoom);\n\n            var location = this.map.getLonLatFromPixel(this.pinchOrigin);\n            var zoomPixel = this.currentCenter;        \n            var size = this.map.getSize();\n\n            location.lon += resolution * ((size.w / 2) - zoomPixel.x);\n            location.lat -= resolution * ((size.h / 2) - zoomPixel.y);\n            this.map.div.clientWidth = this.map.div.clientWidth;\n\n            this.map.setCenter(location, zoom);\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.PinchZoom\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/SLDSelect.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.SLDSelect = OpenLayers.Class(OpenLayers.Control, {\n\n    \n        clearOnDeactivate: false,\n\n        layers: null,\n\n        callbacks: null,\n\n        selectionSymbolizer: {\n        'Polygon': {fillColor: '#FF0000', stroke: false},\n        'Line': {strokeColor: '#FF0000', strokeWidth: 2},\n        'Point': {graphicName: 'square', fillColor: '#FF0000', pointRadius: 5}\n    },\n\n        layerOptions: null,\n\n    \n        sketchStyle: null,\n\n        wfsCache: {},\n\n        layerCache: {},\n\n        initialize: function(handler, options) {\n        OpenLayers.Control.prototype.initialize.apply(this, [options]);\n\n        this.callbacks = OpenLayers.Util.extend({done: this.select, \n            click: this.select}, this.callbacks);\n        this.handlerOptions = this.handlerOptions || {};\n        this.layerOptions = OpenLayers.Util.applyDefaults(this.layerOptions, {\n            displayInLayerSwitcher: false,\n            tileOptions: {maxGetUrlLength: 2048}\n        });\n        if (this.sketchStyle) {\n            this.handlerOptions.layerOptions = OpenLayers.Util.applyDefaults(\n                this.handlerOptions.layerOptions,\n                {styleMap: new OpenLayers.StyleMap({\"default\": this.sketchStyle})}\n            );\n        }\n        this.handler = new handler(this, this.callbacks, this.handlerOptions);\n    },\n\n        destroy: function() {\n        for (var key in this.layerCache) {\n            delete this.layerCache[key];\n        }\n        for (var key in this.wfsCache) {\n            delete this.wfsCache[key];\n        }\n        OpenLayers.Control.prototype.destroy.apply(this, arguments);\n    },\n\n        coupleLayerVisiblity: function(evt) {\n        this.setVisibility(evt.object.getVisibility());\n    },\n\n        createSelectionLayer: function(source) {\n        var selectionLayer;\n        if (!this.layerCache[source.id]) {\n            selectionLayer = new OpenLayers.Layer.WMS(source.name, \n                source.url, source.params, \n                OpenLayers.Util.applyDefaults(\n                    this.layerOptions,\n                    source.getOptions())\n            );\n            this.layerCache[source.id] = selectionLayer;\n            if (this.layerOptions.displayInLayerSwitcher === false) {\n                source.events.on({\n                    \"visibilitychanged\": this.coupleLayerVisiblity,\n                    scope: selectionLayer});\n            }\n            this.map.addLayer(selectionLayer);\n        } else {\n            selectionLayer = this.layerCache[source.id];\n        }\n        return selectionLayer;\n    },\n\n        createSLD: function(layer, filters, geometryAttributes) {\n        var sld = {version: \"1.0.0\", namedLayers: {}};\n        var layerNames = [layer.params.LAYERS].join(\",\").split(\",\");\n        for (var i=0, len=layerNames.length; i<len; i++) { \n            var name = layerNames[i];\n            sld.namedLayers[name] = {name: name, userStyles: []};\n            var symbolizer = this.selectionSymbolizer;\n            var geometryAttribute = geometryAttributes[i];\n            if (geometryAttribute.type.indexOf('Polygon') >= 0) {\n                symbolizer = {Polygon: this.selectionSymbolizer['Polygon']};\n            } else if (geometryAttribute.type.indexOf('LineString') >= 0) {\n                symbolizer = {Line: this.selectionSymbolizer['Line']};\n            } else if (geometryAttribute.type.indexOf('Point') >= 0) {\n                symbolizer = {Point: this.selectionSymbolizer['Point']};\n            }\n            var filter = filters[i];\n            sld.namedLayers[name].userStyles.push({name: 'default', rules: [\n                new OpenLayers.Rule({symbolizer: symbolizer, \n                    filter: filter, \n                    maxScaleDenominator: layer.options.minScale})\n            ]});\n        }\n        return new OpenLayers.Format.SLD({srsName: this.map.getProjection()}).write(sld);\n    },\n\n        parseDescribeLayer: function(request) {\n        var format = new OpenLayers.Format.WMSDescribeLayer();\n        var doc = request.responseXML;\n        if(!doc || !doc.documentElement) {\n            doc = request.responseText;\n        }\n        var describeLayer = format.read(doc);\n        var typeNames = [];\n        var url = null;\n        for (var i=0, len=describeLayer.length; i<len; i++) {\n            if (describeLayer[i].owsType == \"WFS\") {\n                typeNames.push(describeLayer[i].typeName);\n                url = describeLayer[i].owsURL;\n            }\n        }\n        var options = {\n            url: url,\n            params: {\n                SERVICE: \"WFS\",\n                TYPENAME: typeNames.toString(),\n                REQUEST: \"DescribeFeatureType\",\n                VERSION: \"1.0.0\"\n            },\n            callback: function(request) {\n                var format = new OpenLayers.Format.WFSDescribeFeatureType();\n                var doc = request.responseXML;\n                if(!doc || !doc.documentElement) {\n                    doc = request.responseText;\n                }\n                var describeFeatureType = format.read(doc);\n                this.control.wfsCache[this.layer.id] = describeFeatureType;\n                this.control._queue && this.control.applySelection();\n            },\n            scope: this\n        };\n        OpenLayers.Request.GET(options);\n    },\n\n       activate: function() {\n        var activated = OpenLayers.Control.prototype.activate.call(this);\n        if(activated) {\n            for (var i=0, len=this.layers.length; i<len; i++) {\n                var layer = this.layers[i];\n                if (layer && !this.wfsCache[layer.id]) {\n                    var options = {\n                        url: layer.url,\n                        params: {\n                            SERVICE: \"WMS\",\n                            VERSION: layer.params.VERSION,\n                            LAYERS: layer.params.LAYERS,\n                            REQUEST: \"DescribeLayer\"\n                        },\n                        callback: this.parseDescribeLayer,\n                        scope: {layer: layer, control: this}\n                    };\n                    OpenLayers.Request.GET(options);\n                }\n            }\n        }\n        return activated;\n    },\n\n        deactivate: function() {\n        var deactivated = OpenLayers.Control.prototype.deactivate.call(this);\n        if(deactivated) {\n            for (var i=0, len=this.layers.length; i<len; i++) {\n                var layer = this.layers[i];\n                if (layer && this.clearOnDeactivate === true) {\n                    var layerCache = this.layerCache;\n                    var selectionLayer = layerCache[layer.id];\n                    if (selectionLayer) {\n                        layer.events.un({\n                            \"visibilitychanged\": this.coupleLayerVisiblity,\n                            scope: selectionLayer});\n                        selectionLayer.destroy();\n                        delete layerCache[layer.id];\n                    }\n                }\n            }\n        }\n        return deactivated;\n    },\n\n        setLayers: function(layers) {\n        if(this.active) {\n            this.deactivate();\n            this.layers = layers;\n            this.activate();\n        } else {\n            this.layers = layers;\n        }\n    },\n\n        createFilter: function(geometryAttribute, geometry) {\n        var filter = null;\n        if (this.handler instanceof OpenLayers.Handler.RegularPolygon) {\n            if (this.handler.irregular === true) {\n                filter = new OpenLayers.Filter.Spatial({\n                    type: OpenLayers.Filter.Spatial.BBOX,\n                    property: geometryAttribute.name,\n                    value: geometry.getBounds()}\n                );\n            } else {\n                filter = new OpenLayers.Filter.Spatial({\n                    type: OpenLayers.Filter.Spatial.INTERSECTS,\n                    property: geometryAttribute.name,\n                    value: geometry}\n                );\n            }\n        } else if (this.handler instanceof OpenLayers.Handler.Polygon) {\n            filter = new OpenLayers.Filter.Spatial({\n                type: OpenLayers.Filter.Spatial.INTERSECTS,\n                property: geometryAttribute.name,\n                value: geometry}\n            );\n        } else if (this.handler instanceof OpenLayers.Handler.Path) {\n            if (geometryAttribute.type.indexOf('Point') >= 0) {\n                filter = new OpenLayers.Filter.Spatial({\n                    type: OpenLayers.Filter.Spatial.DWITHIN,\n                    property: geometryAttribute.name,\n                    distance: this.map.getExtent().getWidth()*0.01 ,\n                    distanceUnits: this.map.getUnits(),\n                    value: geometry}\n                );\n            } else {\n                filter = new OpenLayers.Filter.Spatial({\n                    type: OpenLayers.Filter.Spatial.INTERSECTS,\n                    property: geometryAttribute.name,\n                    value: geometry}\n                );\n            }\n        } else if (this.handler instanceof OpenLayers.Handler.Click) {\n            if (geometryAttribute.type.indexOf('Polygon') >= 0) {\n                filter = new OpenLayers.Filter.Spatial({\n                    type: OpenLayers.Filter.Spatial.INTERSECTS,\n                    property: geometryAttribute.name,\n                    value: geometry}\n                );\n            } else {\n                filter = new OpenLayers.Filter.Spatial({\n                    type: OpenLayers.Filter.Spatial.DWITHIN,\n                    property: geometryAttribute.name,\n                    distance: this.map.getExtent().getWidth()*0.01 ,\n                    distanceUnits: this.map.getUnits(),\n                    value: geometry}\n                );\n            }\n        }\n        return filter;\n    },\n\n        select: function(geometry) {\n        this._queue = function() {\n            for (var i=0, len=this.layers.length; i<len; i++) {\n                var layer = this.layers[i];\n                var geometryAttributes = this.getGeometryAttributes(layer);\n                var filters = [];\n                for (var j=0, lenj=geometryAttributes.length; j<lenj; j++) {\n                    var geometryAttribute = geometryAttributes[j];\n                    if (geometryAttribute !== null) {\n                        if (!(geometry instanceof OpenLayers.Geometry)) {\n                            var point = this.map.getLonLatFromPixel(\n                                geometry.xy);\n                            geometry = new OpenLayers.Geometry.Point(\n                                point.lon, point.lat);\n                        }\n                        var filter = this.createFilter(geometryAttribute,\n                        geometry);\n                        if (filter !== null) {\n                            filters.push(filter);\n                        }\n                    }\n                }\n    \n                var selectionLayer = this.createSelectionLayer(layer);\n    \n                this.events.triggerEvent(\"selected\", {\n                    layer: layer,\n                    filters: filters\n                });\n\n                var sld = this.createSLD(layer, filters, geometryAttributes);\n    \n                selectionLayer.mergeNewParams({SLD_BODY: sld});\n                delete this._queue;\n            }\n        };\n        this.applySelection();\n    },\n    \n        applySelection: function() {\n        var canApply = true;\n        for (var i=0, len=this.layers.length; i<len; i++) {\n            if(!this.wfsCache[this.layers[i].id]) {\n                canApply = false;\n                break;\n            }\n        }\n        canApply && this._queue.call(this);\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.SLDSelect\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/Scale.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Control.Scale = OpenLayers.Class(OpenLayers.Control, {\n    \n        element: null,\n    \n        geodesic: false,\n\n    \ttemplate: \"Scale = 1 : ${scaleDenom}\",\n\n        initialize: function(element, options) {\n        OpenLayers.Control.prototype.initialize.apply(this, [options]);\n        this.element = OpenLayers.Util.getElement(element);        \n    },\n\n        updateScale: function() {\n        var scale;\n        if(this.geodesic === true) {\n            var units = this.map.getUnits();\n            if(!units) {\n                return;\n            }\n            var inches = OpenLayers.INCHES_PER_UNIT;\n            scale = (this.map.getGeodesicPixelSize().w || 0.000001) *\n                    inches[\"km\"] * OpenLayers.DOTS_PER_INCH;\n        } else {\n            scale = this.map.getScale();\n        }\n            \n        if (!scale) {\n            return;\n        }\n\n        if (scale >= 9500 && scale <= 950000) {\n            scale = Math.round(scale / 1000) + \"K\";\n        } else if (scale >= 950000) {\n            scale = Math.round(scale / 1000000) + \"M\";\n        } else {\n            scale = Math.round(scale);\n        }    \n        \n        var scaleStr = OpenLayers.i18n(this.template, {'scaleDenom':scale});\n        this.element.innerHTML = scaleStr;\n    }, \n\n    CLASS_NAME: \"OpenLayers.Control.Scale\"\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/ScaleLine.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.ScaleLine = OpenLayers.Class(OpenLayers.Control, {\n\n        maxWidth: 100,\n\n        topOutUnits: \"km\",\n    \n        topInUnits: \"m\",\n\n        bottomOutUnits: \"mi\",\n\n        bottomInUnits: \"ft\",\n    \n        eTop: null,\n\n        eBottom:null,\n    \n        geodesic: false,\n\n    \n        draw: function() {\n        OpenLayers.Control.prototype.draw.apply(this, arguments);\n        if (!this.eTop) {\n            this.eTop = document.createElement(\"div\");\n            this.eTop.className = this.displayClass + \"Top\";\n            var theLen = this.topInUnits.length;\n            this.div.appendChild(this.eTop);\n            if((this.topOutUnits == \"\") || (this.topInUnits == \"\")) {\n                this.eTop.style.visibility = \"hidden\";\n            } else {\n                this.eTop.style.visibility = \"visible\";\n            }\n            this.eBottom = document.createElement(\"div\");\n            this.eBottom.className = this.displayClass + \"Bottom\";\n            this.div.appendChild(this.eBottom);\n            if((this.bottomOutUnits == \"\") || (this.bottomInUnits == \"\")) {\n                this.eBottom.style.visibility = \"hidden\";\n            } else {\n                this.eBottom.style.visibility = \"visible\";\n            }\n        }\n        this.map.events.register('moveend', this, this.update);\n        this.update();\n        return this.div;\n    },\n\n        getBarLen: function(maxLen) {\n        var digits = parseInt(Math.log(maxLen) / Math.log(10));\n        var pow10 = Math.pow(10, digits);\n        var firstChar = parseInt(maxLen / pow10);\n        var barLen;\n        if(firstChar > 5) {\n            barLen = 5;\n        } else if(firstChar > 2) {\n            barLen = 2;\n        } else {\n            barLen = 1;\n        }\n        return barLen * pow10;\n    },\n\n        update: function() {\n        var res = this.map.getResolution();\n        if (!res) {\n            return;\n        }\n\n        var curMapUnits = this.map.getUnits();\n        var inches = OpenLayers.INCHES_PER_UNIT;\n        var maxSizeData = this.maxWidth * res * inches[curMapUnits];\n        var geodesicRatio = 1;\n        if(this.geodesic === true) {\n            var maxSizeGeodesic = (this.map.getGeodesicPixelSize().w ||\n                0.000001) * this.maxWidth;\n            var maxSizeKilometers = maxSizeData / inches[\"km\"];\n            geodesicRatio = maxSizeGeodesic / maxSizeKilometers;\n            maxSizeData *= geodesicRatio;\n        }\n        var topUnits;\n        var bottomUnits;\n        if(maxSizeData > 100000) {\n            topUnits = this.topOutUnits;\n            bottomUnits = this.bottomOutUnits;\n        } else {\n            topUnits = this.topInUnits;\n            bottomUnits = this.bottomInUnits;\n        }\n        var topMax = maxSizeData / inches[topUnits];\n        var bottomMax = maxSizeData / inches[bottomUnits];\n        var topRounded = this.getBarLen(topMax);\n        var bottomRounded = this.getBarLen(bottomMax);\n        topMax = topRounded / inches[curMapUnits] * inches[topUnits];\n        bottomMax = bottomRounded / inches[curMapUnits] * inches[bottomUnits];\n        var topPx = topMax / res / geodesicRatio;\n        var bottomPx = bottomMax / res / geodesicRatio;\n        \n        if (this.eBottom.style.visibility == \"visible\"){\n            this.eBottom.style.width = Math.round(bottomPx) + \"px\"; \n            this.eBottom.innerHTML = bottomRounded + \" \" + bottomUnits ;\n        }\n            \n        if (this.eTop.style.visibility == \"visible\"){\n            this.eTop.style.width = Math.round(topPx) + \"px\";\n            this.eTop.innerHTML = topRounded + \" \" + topUnits;\n        }\n        \n    }, \n\n    CLASS_NAME: \"OpenLayers.Control.ScaleLine\"\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/SelectFeature.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Control.SelectFeature = OpenLayers.Class(OpenLayers.Control, {\n\n    \n        multipleKey: null,\n\n        toggleKey: null,\n\n        multiple: false,\n\n        clickout: true,\n\n        toggle: false,\n\n        hover: false,\n\n        highlightOnly: false,\n\n        box: false,\n\n        onBeforeSelect: function() {},\n\n        onSelect: function() {},\n\n        onUnselect: function() {},\n\n        scope: null,\n\n        geometryTypes: null,\n\n        layer: null,\n\n        layers: null,\n\n        callbacks: null,\n\n        selectStyle: null,\n\n        renderIntent: \"select\",\n\n        handlers: null,\n\n        initialize: function(layers, options) {\n        OpenLayers.Control.prototype.initialize.apply(this, [options]);\n\n        if(this.scope === null) {\n            this.scope = this;\n        }\n        this.initLayer(layers);\n        var callbacks = {\n            click: this.clickFeature,\n            clickout: this.clickoutFeature\n        };\n        if (this.hover) {\n            callbacks.over = this.overFeature;\n            callbacks.out = this.outFeature;\n        }\n\n        this.callbacks = OpenLayers.Util.extend(callbacks, this.callbacks);\n        this.handlers = {\n            feature: new OpenLayers.Handler.Feature(\n                this, this.layer, this.callbacks,\n                {geometryTypes: this.geometryTypes}\n            )\n        };\n\n        if (this.box) {\n            this.handlers.box = new OpenLayers.Handler.Box(\n                this, {done: this.selectBox},\n                {boxDivClassName: \"olHandlerBoxSelectFeature\"}\n            );\n        }\n    },\n\n        initLayer: function(layers) {\n        if(OpenLayers.Util.isArray(layers)) {\n            this.layers = layers;\n            this.layer = new OpenLayers.Layer.Vector.RootContainer(\n                this.id + \"_container\", {\n                    layers: layers\n                }\n            );\n        } else {\n            this.layer = layers;\n        }\n    },\n\n        destroy: function() {\n        if(this.active && this.layers) {\n            this.map.removeLayer(this.layer);\n        }\n        OpenLayers.Control.prototype.destroy.apply(this, arguments);\n        if(this.layers) {\n            this.layer.destroy();\n        }\n    },\n\n        activate: function () {\n        if (!this.active) {\n            if(this.layers) {\n                this.map.addLayer(this.layer);\n            }\n            this.handlers.feature.activate();\n            if(this.box && this.handlers.box) {\n                this.handlers.box.activate();\n            }\n        }\n        return OpenLayers.Control.prototype.activate.apply(\n            this, arguments\n        );\n    },\n\n        deactivate: function () {\n        if (this.active) {\n            this.handlers.feature.deactivate();\n            if(this.handlers.box) {\n                this.handlers.box.deactivate();\n            }\n            if(this.layers) {\n                this.map.removeLayer(this.layer);\n            }\n        }\n        return OpenLayers.Control.prototype.deactivate.apply(\n            this, arguments\n        );\n    },\n\n        unselectAll: function(options) {\n        var layers = this.layers || [this.layer],\n            layer, feature, l, numExcept;\n        for(l=0; l<layers.length; ++l) {\n            layer = layers[l];\n            numExcept = 0;\n            if(layer.selectedFeatures != null) {\n                while(layer.selectedFeatures.length > numExcept) {\n                    feature = layer.selectedFeatures[numExcept];\n                    if(!options || options.except != feature) {\n                        this.unselect(feature);\n                    } else {\n                        ++numExcept;\n                    }\n                }\n            }\n        }\n    },\n\n        clickFeature: function(feature) {\n        if(!this.hover) {\n            var selected = (OpenLayers.Util.indexOf(\n                feature.layer.selectedFeatures, feature) > -1);\n            if(selected) {\n                if(this.toggleSelect()) {\n                    this.unselect(feature);\n                } else if(!this.multipleSelect()) {\n                    this.unselectAll({except: feature});\n                }\n            } else {\n                if(!this.multipleSelect()) {\n                    this.unselectAll({except: feature});\n                }\n                this.select(feature);\n            }\n        }\n    },\n\n        multipleSelect: function() {\n        return this.multiple || (this.handlers.feature.evt &&\n                                 this.handlers.feature.evt[this.multipleKey]);\n    },\n\n        toggleSelect: function() {\n        return this.toggle || (this.handlers.feature.evt &&\n                               this.handlers.feature.evt[this.toggleKey]);\n    },\n\n        clickoutFeature: function(feature) {\n        if(!this.hover && this.clickout) {\n            this.unselectAll();\n        }\n    },\n\n        overFeature: function(feature) {\n        var layer = feature.layer;\n        if(this.hover) {\n            if(this.highlightOnly) {\n                this.highlight(feature);\n            } else if(OpenLayers.Util.indexOf(\n                layer.selectedFeatures, feature) == -1) {\n                this.select(feature);\n            }\n        }\n    },\n\n        outFeature: function(feature) {\n        if(this.hover) {\n            if(this.highlightOnly) {\n                if(feature._lastHighlighter == this.id) {\n                    if(feature._prevHighlighter &&\n                       feature._prevHighlighter != this.id) {\n                        delete feature._lastHighlighter;\n                        var control = this.map.getControl(\n                            feature._prevHighlighter);\n                        if(control) {\n                            control.highlight(feature);\n                        }\n                    } else {\n                        this.unhighlight(feature);\n                    }\n                }\n            } else {\n                this.unselect(feature);\n            }\n        }\n    },\n\n        highlight: function(feature) {\n        var layer = feature.layer;\n        var cont = this.events.triggerEvent(\"beforefeaturehighlighted\", {\n            feature : feature\n        });\n        if(cont !== false) {\n            feature._prevHighlighter = feature._lastHighlighter;\n            feature._lastHighlighter = this.id;\n            var style = this.selectStyle || this.renderIntent;\n            layer.drawFeature(feature, style);\n            this.events.triggerEvent(\"featurehighlighted\", {feature : feature});\n        }\n    },\n\n        unhighlight: function(feature) {\n        var layer = feature.layer;\n        if(feature._prevHighlighter == undefined) {\n            delete feature._lastHighlighter;\n        } else if(feature._prevHighlighter == this.id) {\n            delete feature._prevHighlighter;\n        } else {\n            feature._lastHighlighter = feature._prevHighlighter;\n            delete feature._prevHighlighter;\n        }\n        layer.drawFeature(feature, feature.style || feature.layer.style ||\n            \"default\");\n        this.events.triggerEvent(\"featureunhighlighted\", {feature : feature});\n    },\n\n        select: function(feature) {\n        var cont = this.onBeforeSelect.call(this.scope, feature);\n        var layer = feature.layer;\n        if(cont !== false) {\n            cont = layer.events.triggerEvent(\"beforefeatureselected\", {\n                feature: feature\n            });\n            if(cont !== false) {\n                layer.selectedFeatures.push(feature);\n                this.highlight(feature);\n                if(!this.handlers.feature.lastFeature) {\n                    this.handlers.feature.lastFeature = layer.selectedFeatures[0];\n                }\n                layer.events.triggerEvent(\"featureselected\", {feature: feature});\n                this.onSelect.call(this.scope, feature);\n            }\n        }\n    },\n\n        unselect: function(feature) {\n        var layer = feature.layer;\n        this.unhighlight(feature);\n        OpenLayers.Util.removeItem(layer.selectedFeatures, feature);\n        layer.events.triggerEvent(\"featureunselected\", {feature: feature});\n        this.onUnselect.call(this.scope, feature);\n    },\n\n        selectBox: function(position) {\n        if (position instanceof OpenLayers.Bounds) {\n            var minXY = this.map.getLonLatFromPixel({\n                x: position.left,\n                y: position.bottom\n            });\n            var maxXY = this.map.getLonLatFromPixel({\n                x: position.right,\n                y: position.top\n            });\n            var bounds = new OpenLayers.Bounds(\n                minXY.lon, minXY.lat, maxXY.lon, maxXY.lat\n            );\n            if (!this.multipleSelect()) {\n                this.unselectAll();\n            }\n            var prevMultiple = this.multiple;\n            this.multiple = true;\n            var layers = this.layers || [this.layer];\n            this.events.triggerEvent(\"boxselectionstart\", {layers: layers});\n            var layer;\n            for(var l=0; l<layers.length; ++l) {\n                layer = layers[l];\n                for(var i=0, len = layer.features.length; i<len; ++i) {\n                    var feature = layer.features[i];\n                    if (!feature.getVisibility()) {\n                        continue;\n                    }\n\n                    if (this.geometryTypes == null || OpenLayers.Util.indexOf(\n                            this.geometryTypes, feature.geometry.CLASS_NAME) > -1) {\n                        if (bounds.toGeometry().intersects(feature.geometry)) {\n                            if (OpenLayers.Util.indexOf(layer.selectedFeatures, feature) == -1) {\n                                this.select(feature);\n                            }\n                        }\n                    }\n                }\n            }\n            this.multiple = prevMultiple;\n            this.events.triggerEvent(\"boxselectionend\", {layers: layers});\n        }\n    },\n\n        setMap: function(map) {\n        this.handlers.feature.setMap(map);\n        if (this.box) {\n            this.handlers.box.setMap(map);\n        }\n        OpenLayers.Control.prototype.setMap.apply(this, arguments);\n    },\n\n        setLayer: function(layers) {\n        var isActive = this.active;\n        this.unselectAll();\n        this.deactivate();\n        if(this.layers) {\n            this.layer.destroy();\n            this.layers = null;\n        }\n        this.initLayer(layers);\n        this.handlers.feature.layer = this.layer;\n        if (isActive) {\n            this.activate();\n        }\n    },\n    \n        addLayer: function( layer ) {\n        var isActive = this.active;\n        this.deactivate();\n        if (this.layers == null) {\n            if (this.layer != null) {\n                this.layers = [this.layer];\n                this.layers.push(layer);\n            } else {\n                this.layers = [layer];\n            }\n        } else {\t\n            this.layers.push(layer);\n        }\n        this.initLayer(this.layers);\n        this.handlers.feature.layer = this.layer;\n        if (isActive) {\n            this.activate();\n        }\n    },\t    \n\n    CLASS_NAME: \"OpenLayers.Control.SelectFeature\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/Snapping.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.Snapping = OpenLayers.Class(OpenLayers.Control, {\n\n        \n        DEFAULTS: {\n        tolerance: 10,\n        node: true,\n        edge: true,\n        vertex: true\n    },\n    \n        greedy: true,\n    \n        precedence: [\"node\", \"vertex\", \"edge\"],\n    \n        resolution: null,\n    \n        geoToleranceCache: null,\n    \n        layer: null,\n    \n        feature: null,\n    \n        point: null,\n\n        initialize: function(options) {\n        OpenLayers.Control.prototype.initialize.apply(this, [options]);\n        this.options = options || {}; // TODO: this could be done by the super\n        if(this.options.layer) {\n            this.setLayer(this.options.layer);\n        }\n        var defaults = OpenLayers.Util.extend({}, this.options.defaults);\n        this.defaults = OpenLayers.Util.applyDefaults(defaults, this.DEFAULTS);\n        this.setTargets(this.options.targets);\n        if(this.targets.length === 0 && this.layer) {\n            this.addTargetLayer(this.layer);\n        }\n\n        this.geoToleranceCache = {};\n    },\n    \n        setLayer: function(layer) {\n        if(this.active) {\n            this.deactivate();\n            this.layer = layer;\n            this.activate();\n        } else {\n            this.layer = layer;\n        }\n    },\n    \n        setTargets: function(targets) {\n        this.targets = [];\n        if(targets && targets.length) {\n            var target;\n            for(var i=0, len=targets.length; i<len; ++i) {\n                target = targets[i];\n                if(target instanceof OpenLayers.Layer.Vector) {\n                    this.addTargetLayer(target);\n                } else {\n                    this.addTarget(target);\n                }\n            }\n        }\n    },\n    \n        addTargetLayer: function(layer) {\n        this.addTarget({layer: layer});\n    },\n    \n        addTarget: function(target) {\n        target = OpenLayers.Util.applyDefaults(target, this.defaults);\n        target.nodeTolerance = target.nodeTolerance || target.tolerance;\n        target.vertexTolerance = target.vertexTolerance || target.tolerance;\n        target.edgeTolerance = target.edgeTolerance || target.tolerance;\n        this.targets.push(target);\n    },\n    \n        removeTargetLayer: function(layer) {\n        var target;\n        for(var i=this.targets.length-1; i>=0; --i) {\n            target = this.targets[i];\n            if(target.layer === layer) {\n                this.removeTarget(target);\n            }\n        }\n    },\n    \n        removeTarget: function(target) {\n        return OpenLayers.Util.removeItem(this.targets, target);\n    },\n    \n        activate: function() {\n        var activated = OpenLayers.Control.prototype.activate.call(this);\n        if(activated) {\n            if(this.layer && this.layer.events) {\n                this.layer.events.on({\n                    sketchstarted: this.onSketchModified,\n                    sketchmodified: this.onSketchModified,\n                    vertexmodified: this.onVertexModified,\n                    scope: this\n                });\n            }\n        }\n        return activated;\n    },\n    \n        deactivate: function() {\n        var deactivated = OpenLayers.Control.prototype.deactivate.call(this);\n        if(deactivated) {\n            if(this.layer && this.layer.events) {\n                this.layer.events.un({\n                    sketchstarted: this.onSketchModified,\n                    sketchmodified: this.onSketchModified,\n                    vertexmodified: this.onVertexModified,\n                    scope: this\n                });\n            }\n        }\n        this.feature = null;\n        this.point = null;\n        return deactivated;\n    },\n    \n        onSketchModified: function(event) {\n        this.feature = event.feature;\n        this.considerSnapping(event.vertex, event.vertex);\n    },\n    \n        onVertexModified: function(event) {\n        this.feature = event.feature;\n        var loc = this.layer.map.getLonLatFromViewPortPx(event.pixel);\n        this.considerSnapping(\n            event.vertex, new OpenLayers.Geometry.Point(loc.lon, loc.lat)\n        );\n    },\n\n        considerSnapping: function(point, loc) {\n        var best = {\n            rank: Number.POSITIVE_INFINITY,\n            dist: Number.POSITIVE_INFINITY,\n            x: null, y: null\n        };\n        var snapped = false;\n        var result, target;\n        for(var i=0, len=this.targets.length; i<len; ++i) {\n            target = this.targets[i];\n            result = this.testTarget(target, loc);\n            if(result) {\n                if(this.greedy) {\n                    best = result;\n                    best.target = target; \n                    snapped = true;\n                    break;\n                } else {\n                    if((result.rank < best.rank) ||\n                       (result.rank === best.rank && result.dist < best.dist)) {\n                        best = result;\n                        best.target = target;\n                        snapped = true;\n                    }\n                }\n            }\n        }\n        if(snapped) {\n            var proceed = this.events.triggerEvent(\"beforesnap\", {\n                point: point, x: best.x, y: best.y, distance: best.dist,\n                layer: best.target.layer, snapType: this.precedence[best.rank]\n            });\n            if(proceed !== false) {\n                point.x = best.x;\n                point.y = best.y;\n                this.point = point;\n                this.events.triggerEvent(\"snap\", {\n                    point: point,\n                    snapType: this.precedence[best.rank],\n                    layer: best.target.layer,\n                    distance: best.dist\n                });\n            } else {\n                snapped = false;\n            }\n        }\n        if(this.point && !snapped) {\n            point.x = loc.x;\n            point.y = loc.y;\n            this.point = null;\n            this.events.triggerEvent(\"unsnap\", {point: point});\n        }\n    },\n    \n        testTarget: function(target, loc) {\n        var resolution = this.layer.map.getResolution();\n        if (\"minResolution\" in target) {\n            if (resolution < target.minResolution) {\n                return null;\n            }\n        }\n        if (\"maxResolution\" in target) {\n            if (resolution >= target.maxResolution) {\n                return null;\n            }\n        }\n        var tolerance = {\n            node: this.getGeoTolerance(target.nodeTolerance, resolution),\n            vertex: this.getGeoTolerance(target.vertexTolerance, resolution),\n            edge: this.getGeoTolerance(target.edgeTolerance, resolution)\n        };\n        var maxTolerance = Math.max(\n            tolerance.node, tolerance.vertex, tolerance.edge\n        );\n        var result = {\n            rank: Number.POSITIVE_INFINITY, dist: Number.POSITIVE_INFINITY\n        };\n        var eligible = false;\n        var features = target.layer.features;\n        var feature, type, vertices, vertex, closest, dist, found;\n        var numTypes = this.precedence.length;\n        var ll = new OpenLayers.LonLat(loc.x, loc.y);\n        for(var i=0, len=features.length; i<len; ++i) {\n            feature = features[i];\n            if(feature !== this.feature && !feature._sketch &&\n               feature.state !== OpenLayers.State.DELETE &&\n               (!target.filter || target.filter.evaluate(feature))) {\n                if(feature.atPoint(ll, maxTolerance, maxTolerance)) {\n                    for(var j=0, stop=Math.min(result.rank+1, numTypes); j<stop; ++j) {\n                        type = this.precedence[j];\n                        if(target[type]) {\n                            if(type === \"edge\") {\n                                closest = feature.geometry.distanceTo(loc, {details: true});\n                                dist = closest.distance;\n                                if(dist <= tolerance[type] && dist < result.dist) {\n                                    result = {\n                                        rank: j, dist: dist,\n                                        x: closest.x0, y: closest.y0 // closest coords on feature\n                                    };\n                                    eligible = true;\n                                    break;\n                                }\n                            } else {\n                                vertices = feature.geometry.getVertices(type === \"node\");\n                                found = false;\n                                for(var k=0, klen=vertices.length; k<klen; ++k) {\n                                    vertex = vertices[k];\n                                    dist = vertex.distanceTo(loc);\n                                    if(dist <= tolerance[type] &&\n                                       (j < result.rank || (j === result.rank && dist < result.dist))) {\n                                        result = {\n                                            rank: j, dist: dist,\n                                            x: vertex.x, y: vertex.y\n                                        };\n                                        eligible = true;\n                                        found = true;\n                                    }\n                                }\n                                if(found) {\n                                    break;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        return eligible ? result : null;\n    },\n    \n        getGeoTolerance: function(tolerance, resolution) {\n        if(resolution !== this.resolution) {\n            this.resolution = resolution;\n            this.geoToleranceCache = {};\n        }\n        var geoTolerance = this.geoToleranceCache[tolerance];\n        if(geoTolerance === undefined) {\n            geoTolerance = tolerance * resolution;\n            this.geoToleranceCache[tolerance] = geoTolerance;\n        }\n        return geoTolerance;\n    },\n    \n        destroy: function() {\n        if(this.active) {\n            this.deactivate(); // TODO: this should be handled by the super\n        }\n        delete this.layer;\n        delete this.targets;\n        OpenLayers.Control.prototype.destroy.call(this);\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.Snapping\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/Split.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.Split = OpenLayers.Class(OpenLayers.Control, {\n\n        \n        layer: null,\n    \n        source: null,\n    \n        sourceOptions: null,\n\n        tolerance: null,\n    \n        edge: true,\n    \n        deferDelete: false,\n    \n        mutual: true,\n    \n        targetFilter: null,\n    \n        sourceFilter: null,\n    \n        handler: null,\n\n        initialize: function(options) {\n        OpenLayers.Control.prototype.initialize.apply(this, [options]);\n        this.options = options || {}; // TODO: this could be done by the super\n        if(this.options.source) {\n            this.setSource(this.options.source);\n        }\n    },\n    \n        setSource: function(layer) {\n        if(this.active) {\n            this.deactivate();\n            if(this.handler) {\n                this.handler.destroy();\n                delete this.handler;\n            }\n            this.source = layer;\n            this.activate();\n        } else {\n            this.source = layer;\n        }\n    },\n    \n        activate: function() {\n        var activated = OpenLayers.Control.prototype.activate.call(this);\n        if(activated) {\n            if(!this.source) {\n                if(!this.handler) {\n                    this.handler = new OpenLayers.Handler.Path(this,\n                        {done: function(geometry) {\n                            this.onSketchComplete({\n                                feature: new OpenLayers.Feature.Vector(geometry)\n                            });\n                        }},\n                        {layerOptions: this.sourceOptions}\n                    );\n                }\n                this.handler.activate();\n            } else if(this.source.events) {\n                this.source.events.on({\n                    sketchcomplete: this.onSketchComplete,\n                    afterfeaturemodified: this.afterFeatureModified,\n                    scope: this\n                });\n            }\n        }\n        return activated;\n    },\n    \n        deactivate: function() {\n        var deactivated = OpenLayers.Control.prototype.deactivate.call(this);\n        if(deactivated) {\n            if(this.source && this.source.events) {\n                this.source.events.un({\n                    sketchcomplete: this.onSketchComplete,\n                    afterfeaturemodified: this.afterFeatureModified,\n                    scope: this\n                });\n            }\n        }\n        return deactivated;\n    },\n    \n        onSketchComplete: function(event) {\n        this.feature = null;\n        return !this.considerSplit(event.feature);\n    },\n    \n        afterFeatureModified: function(event) {\n        if(event.modified) {\n            var feature = event.feature;\n            if (typeof feature.geometry.split === \"function\") {\n                this.feature = event.feature;\n                this.considerSplit(event.feature);\n            }\n        }\n    },\n    \n        removeByGeometry: function(features, geometry) {\n        for(var i=0, len=features.length; i<len; ++i) {\n            if(features[i].geometry === geometry) {\n                features.splice(i, 1);\n                break;\n            }\n        }\n    },\n    \n        isEligible: function(target) {\n        if (!target.geometry) {\n            return false;\n        } else {\n            return (\n                target.state !== OpenLayers.State.DELETE\n            ) && (\n                typeof target.geometry.split === \"function\"\n            ) && (\n                this.feature !== target\n            ) && (\n                !this.targetFilter ||\n                this.targetFilter.evaluate(target.attributes)\n            );\n        }\n    },\n\n        considerSplit: function(feature) {\n        var sourceSplit = false;\n        var targetSplit = false;\n        if(!this.sourceFilter ||\n           this.sourceFilter.evaluate(feature.attributes)) {\n            var features = this.layer && this.layer.features || [];\n            var target, results, proceed;\n            var additions = [], removals = [];\n            var mutual = (this.layer === this.source) && this.mutual;\n            var options = {\n                edge: this.edge,\n                tolerance: this.tolerance,\n                mutual: mutual\n            };\n            var sourceParts = [feature.geometry];\n            var targetFeature, targetParts;\n            var source, parts;\n            for(var i=0, len=features.length; i<len; ++i) {\n                targetFeature = features[i];\n                if(this.isEligible(targetFeature)) {\n                    targetParts = [targetFeature.geometry];\n                    for(var j=0; j<sourceParts.length; ++j) { \n                        source = sourceParts[j];\n                        for(var k=0; k<targetParts.length; ++k) {\n                            target = targetParts[k];\n                            if(source.getBounds().intersectsBounds(target.getBounds())) {\n                                results = source.split(target, options);\n                                if(results) {\n                                    proceed = this.events.triggerEvent(\n                                        \"beforesplit\", {source: feature, target: targetFeature}\n                                    );\n                                    if(proceed !== false) {\n                                        if(mutual) {\n                                            parts = results[0];\n                                            if(parts.length > 1) {\n                                                parts.unshift(j, 1); // add args for splice below\n                                                Array.prototype.splice.apply(sourceParts, parts);\n                                                j += parts.length - 3;\n                                            }\n                                            results = results[1];\n                                        }\n                                        if(results.length > 1) {\n                                            results.unshift(k, 1); // add args for splice below\n                                            Array.prototype.splice.apply(targetParts, results);\n                                            k += results.length - 3;\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                    if(targetParts && targetParts.length > 1) {\n                        this.geomsToFeatures(targetFeature, targetParts);\n                        this.events.triggerEvent(\"split\", {\n                            original: targetFeature,\n                            features: targetParts\n                        });\n                        Array.prototype.push.apply(additions, targetParts);\n                        removals.push(targetFeature);\n                        targetSplit = true;\n                    }\n                }\n            }\n            if(sourceParts && sourceParts.length > 1) {\n                this.geomsToFeatures(feature, sourceParts);\n                this.events.triggerEvent(\"split\", {\n                    original: feature,\n                    features: sourceParts\n                });\n                Array.prototype.push.apply(additions, sourceParts);\n                removals.push(feature);\n                sourceSplit = true;\n            }\n            if(sourceSplit || targetSplit) {\n                if(this.deferDelete) {\n                    var feat, destroys = [];\n                    for(var i=0, len=removals.length; i<len; ++i) {\n                        feat = removals[i];\n                        if(feat.state === OpenLayers.State.INSERT) {\n                            destroys.push(feat);\n                        } else {\n                            feat.state = OpenLayers.State.DELETE;\n                            this.layer.drawFeature(feat);\n                        }\n                    }\n                    this.layer.destroyFeatures(destroys, {silent: true});\n                    for(var i=0, len=additions.length; i<len; ++i) {\n                        additions[i].state = OpenLayers.State.INSERT;\n                    }\n                } else {\n                    this.layer.destroyFeatures(removals, {silent: true});\n                }\n                this.layer.addFeatures(additions, {silent: true});\n                this.events.triggerEvent(\"aftersplit\", {\n                    source: feature,\n                    features: additions\n                });\n            }\n        }\n        return sourceSplit;\n    },\n    \n        geomsToFeatures: function(feature, geoms) {\n        var clone = feature.clone();\n        delete clone.geometry;\n        var newFeature;\n        for(var i=0, len=geoms.length; i<len; ++i) {\n            newFeature = clone.clone();\n            newFeature.geometry = geoms[i];\n            newFeature.state = OpenLayers.State.INSERT;\n            geoms[i] = newFeature;\n        }\n    },\n    \n        destroy: function() {\n        if(this.active) {\n            this.deactivate(); // TODO: this should be handled by the super\n        }\n        OpenLayers.Control.prototype.destroy.call(this);\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.Split\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/TextButtonPanel.js",
    "content": "/* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.TextButtonPanel = OpenLayers.Class(\n  OpenLayers.Control.Panel, {\n\n        vertical: false,\n\n        additionalClass: null,\n\n    \n        draw: function() {\n        OpenLayers.Control.Panel.prototype.draw.apply(this, arguments);\n        this.setOrientationClass();\n        this.setAdditionalClass();\n        return this.div;\n    },\n\n        redraw: function() {\n        OpenLayers.Control.Panel.prototype.redraw.apply(this, arguments);\n        this.setOrientationClass();\n    },\n\n        setOrientationClass: function() {\n        if (this.vertical) {\n            OpenLayers.Element.addClass(this.div, \"vertical\");\n        }\n        else {\n            OpenLayers.Element.removeClass(this.div, \"vertical\");\n        }\n    },\n    \n        setAdditionalClass: function() {\n        if (!!this.additionalClass) {\n            OpenLayers.Element.addClass(this.div, this.additionalClass);\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.TextButtonPanel\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/TouchNavigation.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.TouchNavigation = OpenLayers.Class(OpenLayers.Control, {\n\n        dragPan: null,\n\n        dragPanOptions: null,\n\n        pinchZoom: null,\n\n        pinchZoomOptions: null,\n\n        clickHandlerOptions: null,\n\n        documentDrag: false,\n\n        autoActivate: true,\n\n        initialize: function(options) {\n        this.handlers = {};\n        OpenLayers.Control.prototype.initialize.apply(this, arguments);\n    },\n\n        destroy: function() {\n        this.deactivate();\n        if(this.dragPan) {\n            this.dragPan.destroy();\n        }\n        this.dragPan = null;\n        if (this.pinchZoom) {\n            this.pinchZoom.destroy();\n            delete this.pinchZoom;\n        }\n        OpenLayers.Control.prototype.destroy.apply(this,arguments);\n    },\n\n        activate: function() {\n        if(OpenLayers.Control.prototype.activate.apply(this,arguments)) {\n            this.dragPan.activate();\n            this.handlers.click.activate();\n            this.pinchZoom.activate();\n            return true;\n        }\n        return false;\n    },\n\n        deactivate: function() {\n        if(OpenLayers.Control.prototype.deactivate.apply(this,arguments)) {\n            this.dragPan.deactivate();\n            this.handlers.click.deactivate();\n            this.pinchZoom.deactivate();\n            return true;\n        }\n        return false;\n    },\n    \n        draw: function() {\n        var clickCallbacks = {\n            click: this.defaultClick,\n            dblclick: this.defaultDblClick\n        };\n        var clickOptions = OpenLayers.Util.extend({\n            \"double\": true,\n            stopDouble: true,\n            pixelTolerance: 2\n        }, this.clickHandlerOptions);\n        this.handlers.click = new OpenLayers.Handler.Click(\n            this, clickCallbacks, clickOptions\n        );\n        this.dragPan = new OpenLayers.Control.DragPan(\n            OpenLayers.Util.extend({\n                map: this.map,\n                documentDrag: this.documentDrag\n            }, this.dragPanOptions)\n        );\n        this.dragPan.draw();\n        this.pinchZoom = new OpenLayers.Control.PinchZoom(\n            OpenLayers.Util.extend({map: this.map}, this.pinchZoomOptions)\n        );\n    },\n\n        defaultClick: function (evt) {\n        if(evt.lastTouches && evt.lastTouches.length == 2) {\n            this.map.zoomOut();\n        }\n    },\n\n        defaultDblClick: function (evt) {\n        this.map.zoomTo(this.map.zoom + 1, evt.xy);\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.TouchNavigation\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/TransformFeature.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Control.TransformFeature = OpenLayers.Class(OpenLayers.Control, {\n\n    \n        geometryTypes: null,\n\n        layer: null,\n    \n        preserveAspectRatio: false,\n    \n        rotate: true,\n    \n        feature: null,\n    \n        renderIntent: \"temporary\",\n    \n        rotationHandleSymbolizer: null,\n    \n        box: null,\n    \n        center: null,\n    \n        scale: 1,\n    \n        ratio: 1,\n    \n        rotation: 0,\n    \n        handles: null,\n    \n        rotationHandles: null,\n    \n        dragControl: null,\n    \n        irregular: false,\n    \n        initialize: function(layer, options) {\n        OpenLayers.Control.prototype.initialize.apply(this, [options]);\n\n        this.layer = layer;\n\n        if(!this.rotationHandleSymbolizer) {\n            this.rotationHandleSymbolizer = {\n                stroke: false,\n                pointRadius: 10,\n                fillOpacity: 0,\n                cursor: \"pointer\"\n            };\n        }\n\n        this.createBox();\n        this.createControl();        \n    },\n    \n        activate: function() {\n        var activated = false;\n        if(OpenLayers.Control.prototype.activate.apply(this, arguments)) {\n            this.dragControl.activate();\n            this.layer.addFeatures([this.box]);\n            this.rotate && this.layer.addFeatures(this.rotationHandles);\n            this.layer.addFeatures(this.handles);        \n            activated = true;\n        }\n        return activated;\n    },\n    \n        deactivate: function() {\n        var deactivated = false;\n        if(OpenLayers.Control.prototype.deactivate.apply(this, arguments)) {\n            this.layer.removeFeatures(this.handles);\n            this.rotate && this.layer.removeFeatures(this.rotationHandles);\n            this.layer.removeFeatures([this.box]);\n            this.dragControl.deactivate();\n            deactivated = true;\n        }\n        return deactivated;\n    },\n    \n        setMap: function(map) {\n        this.dragControl.setMap(map);\n        OpenLayers.Control.prototype.setMap.apply(this, arguments);\n    },\n\n        setFeature: function(feature, initialParams) {\n        initialParams = OpenLayers.Util.applyDefaults(initialParams, {\n            rotation: 0,\n            scale: 1,\n            ratio: 1\n        });\n\n        var oldRotation = this.rotation;\n        var oldCenter = this.center;\n        OpenLayers.Util.extend(this, initialParams);\n\n        var cont = this.events.triggerEvent(\"beforesetfeature\",\n            {feature: feature}\n        );\n        if (cont === false) {\n            return;\n        }\n\n        this.feature = feature;\n        this.activate();\n\n        this._setfeature = true;\n\n        var featureBounds = this.feature.geometry.getBounds();\n        this.box.move(featureBounds.getCenterLonLat());\n        this.box.geometry.rotate(-oldRotation, oldCenter);\n        this._angle = 0;\n\n        var ll;\n        if(this.rotation) {\n            var geom = feature.geometry.clone();\n            geom.rotate(-this.rotation, this.center);\n            var box = new OpenLayers.Feature.Vector(\n                geom.getBounds().toGeometry());\n            box.geometry.rotate(this.rotation, this.center);\n            this.box.geometry.rotate(this.rotation, this.center);\n            this.box.move(box.geometry.getBounds().getCenterLonLat());\n            var llGeom = box.geometry.components[0].components[0];\n            ll = llGeom.getBounds().getCenterLonLat();\n        } else {\n            ll = new OpenLayers.LonLat(featureBounds.left, featureBounds.bottom);\n        }\n        this.handles[0].move(ll);\n        \n        delete this._setfeature;\n\n        this.events.triggerEvent(\"setfeature\", {feature: feature});\n    },\n    \n        unsetFeature: function() {\n        if (this.active) {\n            this.deactivate();\n        } else {\n            this.feature = null;\n            this.rotation = 0;\n            this.scale = 1;\n            this.ratio = 1;\n        }\n    },\n    \n        createBox: function() {\n        var control = this;\n        \n        this.center = new OpenLayers.Geometry.Point(0, 0);\n        this.box = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.LineString([\n                new OpenLayers.Geometry.Point(-1, -1),\n                new OpenLayers.Geometry.Point(0, -1),\n                new OpenLayers.Geometry.Point(1, -1),\n                new OpenLayers.Geometry.Point(1, 0),\n                new OpenLayers.Geometry.Point(1, 1),\n                new OpenLayers.Geometry.Point(0, 1),\n                new OpenLayers.Geometry.Point(-1, 1),\n                new OpenLayers.Geometry.Point(-1, 0),\n                new OpenLayers.Geometry.Point(-1, -1)\n            ]), null,\n            typeof this.renderIntent == \"string\" ? null : this.renderIntent\n        );\n        this.box.geometry.move = function(x, y) {\n            control._moving = true;\n            OpenLayers.Geometry.LineString.prototype.move.apply(this, arguments);\n            control.center.move(x, y);\n            delete control._moving;\n        };\n        var vertexMoveFn = function(x, y) {\n            OpenLayers.Geometry.Point.prototype.move.apply(this, arguments);\n            this._rotationHandle && this._rotationHandle.geometry.move(x, y);\n            this._handle.geometry.move(x, y);\n        };\n        var vertexResizeFn = function(scale, center, ratio) {\n            OpenLayers.Geometry.Point.prototype.resize.apply(this, arguments);\n            this._rotationHandle && this._rotationHandle.geometry.resize(\n                scale, center, ratio);\n            this._handle.geometry.resize(scale, center, ratio);\n        };\n        var vertexRotateFn = function(angle, center) {\n            OpenLayers.Geometry.Point.prototype.rotate.apply(this, arguments);\n            this._rotationHandle && this._rotationHandle.geometry.rotate(\n                angle, center);\n            this._handle.geometry.rotate(angle, center);\n        };\n        var handleMoveFn = function(x, y) {\n            var oldX = this.x, oldY = this.y;\n            OpenLayers.Geometry.Point.prototype.move.call(this, x, y);\n            if(control._moving) {\n                return;\n            }\n            var evt = control.dragControl.handlers.drag.evt;\n            var preserveAspectRatio = !control._setfeature &&\n                control.preserveAspectRatio;\n            var reshape = !preserveAspectRatio && !(evt && evt.shiftKey);\n            var oldGeom = new OpenLayers.Geometry.Point(oldX, oldY);\n            var centerGeometry = control.center;\n            this.rotate(-control.rotation, centerGeometry);\n            oldGeom.rotate(-control.rotation, centerGeometry);\n            var dx1 = this.x - centerGeometry.x;\n            var dy1 = this.y - centerGeometry.y;\n            var dx0 = dx1 - (this.x - oldGeom.x);\n            var dy0 = dy1 - (this.y - oldGeom.y);\n            if (control.irregular && !control._setfeature) {\n               dx1 -= (this.x - oldGeom.x) / 2;\n               dy1 -= (this.y - oldGeom.y) / 2;\n            }\n            this.x = oldX;\n            this.y = oldY;\n            var scale, ratio = 1;\n            if (reshape) {\n                scale = Math.abs(dy0) < 0.00001 ? 1 : dy1 / dy0;\n                ratio = (Math.abs(dx0) < 0.00001 ? 1 : (dx1 / dx0)) / scale;\n            } else {\n                var l0 = Math.sqrt((dx0 * dx0) + (dy0 * dy0));\n                var l1 = Math.sqrt((dx1 * dx1) + (dy1 * dy1));\n                scale = l1 / l0;\n            }\n            control._moving = true;\n            control.box.geometry.rotate(-control.rotation, centerGeometry);\n            delete control._moving;\n\n            control.box.geometry.resize(scale, centerGeometry, ratio);\n            control.box.geometry.rotate(control.rotation, centerGeometry);\n            control.transformFeature({scale: scale, ratio: ratio});\n            if (control.irregular && !control._setfeature) {\n               var newCenter = centerGeometry.clone();\n               newCenter.x += Math.abs(oldX - centerGeometry.x) < 0.00001 ? 0 : (this.x - oldX);\n               newCenter.y += Math.abs(oldY - centerGeometry.y) < 0.00001 ? 0 : (this.y - oldY);\n               control.box.geometry.move(this.x - oldX, this.y - oldY);\n               control.transformFeature({center: newCenter});\n            }\n        };\n        var rotationHandleMoveFn = function(x, y){\n            var oldX = this.x, oldY = this.y;\n            OpenLayers.Geometry.Point.prototype.move.call(this, x, y);\n            if(control._moving) {\n                return;\n            }\n            var evt = control.dragControl.handlers.drag.evt;\n            var constrain = (evt && evt.shiftKey) ? 45 : 1;\n            var centerGeometry = control.center;\n            var dx1 = this.x - centerGeometry.x;\n            var dy1 = this.y - centerGeometry.y;\n            var dx0 = dx1 - x;\n            var dy0 = dy1 - y;\n            this.x = oldX;\n            this.y = oldY;\n            var a0 = Math.atan2(dy0, dx0);\n            var a1 = Math.atan2(dy1, dx1);\n            var angle = a1 - a0;\n            angle *= 180 / Math.PI;\n            control._angle = (control._angle + angle) % 360;\n            var diff = control.rotation % constrain;\n            if(Math.abs(control._angle) >= constrain || diff !== 0) {\n                angle = Math.round(control._angle / constrain) * constrain -\n                    diff;\n                control._angle = 0;\n                control.box.geometry.rotate(angle, centerGeometry);\n                control.transformFeature({rotation: angle});\n            } \n        };\n\n        var handles = new Array(8);\n        var rotationHandles = new Array(4);\n        var geom, handle, rotationHandle;\n        var positions = [\"sw\", \"s\", \"se\", \"e\", \"ne\", \"n\", \"nw\", \"w\"];\n        for(var i=0; i<8; ++i) {\n            geom = this.box.geometry.components[i];\n            handle = new OpenLayers.Feature.Vector(geom.clone(), {\n                role: positions[i] + \"-resize\"\n            }, typeof this.renderIntent == \"string\" ? null :\n                this.renderIntent);\n            if(i % 2 == 0) {\n                rotationHandle = new OpenLayers.Feature.Vector(geom.clone(), {\n                    role: positions[i] + \"-rotate\"\n                }, typeof this.rotationHandleSymbolizer == \"string\" ?\n                    null : this.rotationHandleSymbolizer);\n                rotationHandle.geometry.move = rotationHandleMoveFn;\n                geom._rotationHandle = rotationHandle;\n                rotationHandles[i/2] = rotationHandle;\n            }\n            geom.move = vertexMoveFn;\n            geom.resize = vertexResizeFn;\n            geom.rotate = vertexRotateFn;\n            handle.geometry.move = handleMoveFn;\n            geom._handle = handle;\n            handles[i] = handle;\n        }\n        \n        this.rotationHandles = rotationHandles;\n        this.handles = handles;\n    },\n    \n        createControl: function() {\n        var control = this;\n        this.dragControl = new OpenLayers.Control.DragFeature(this.layer, {\n            documentDrag: true,\n            moveFeature: function(pixel) {\n                if(this.feature === control.feature) {\n                    this.feature = control.box;\n                }\n                OpenLayers.Control.DragFeature.prototype.moveFeature.apply(this,\n                    arguments);\n            },\n            onDrag: function(feature, pixel) {\n                if(feature === control.box) {\n                    control.transformFeature({center: control.center});\n                }\n            },\n            onStart: function(feature, pixel) {\n                var eligible = !control.geometryTypes ||\n                    OpenLayers.Util.indexOf(control.geometryTypes,\n                        feature.geometry.CLASS_NAME) !== -1;\n                var i = OpenLayers.Util.indexOf(control.handles, feature);\n                i += OpenLayers.Util.indexOf(control.rotationHandles,\n                    feature);\n                if(feature !== control.feature && feature !== control.box &&\n                                                        i == -2 && eligible) {\n                    control.setFeature(feature);\n                }\n            },\n            onComplete: function(feature, pixel) {\n                control.events.triggerEvent(\"transformcomplete\",\n                    {feature: control.feature});\n            }\n        });\n    },\n    \n        drawHandles: function() {\n        var layer = this.layer;\n        for(var i=0; i<8; ++i) {\n            if(this.rotate && i % 2 === 0) {\n                layer.drawFeature(this.rotationHandles[i/2],\n                    this.rotationHandleSymbolizer);\n            }\n            layer.drawFeature(this.handles[i], this.renderIntent);\n        }\n    },\n    \n        transformFeature: function(mods) {\n        if(!this._setfeature) {\n            this.scale *= (mods.scale || 1);\n            this.ratio *= (mods.ratio || 1);\n            var oldRotation = this.rotation;\n            this.rotation = (this.rotation + (mods.rotation || 0)) % 360;\n            \n            if(this.events.triggerEvent(\"beforetransform\", mods) !== false) {\n                var feature = this.feature;\n                var geom = feature.geometry;\n                var center = this.center;\n                geom.rotate(-oldRotation, center);\n                if(mods.scale || mods.ratio) {\n                    geom.resize(mods.scale, center, mods.ratio);\n                } else if(mods.center) {\n                    feature.move(mods.center.getBounds().getCenterLonLat());\n                }\n                geom.rotate(this.rotation, center);\n                this.layer.drawFeature(feature);\n                feature.toState(OpenLayers.State.UPDATE);\n                this.events.triggerEvent(\"transform\", mods);\n            }\n        }\n        this.layer.drawFeature(this.box, this.renderIntent);\n        this.drawHandles();\n    },\n        \n        destroy: function() {\n        var geom;\n        for(var i=0; i<8; ++i) {\n            geom = this.box.geometry.components[i];\n            geom._handle.destroy();\n            geom._handle = null;\n            geom._rotationHandle && geom._rotationHandle.destroy();\n            geom._rotationHandle = null;\n        }\n        this.center = null;\n        this.feature = null;\n        this.handles = null;\n        this.rotationHandleSymbolizer = null;\n        this.rotationHandles = null;\n        this.box.destroy();\n        this.box = null;\n        this.layer = null;\n        this.dragControl.destroy();\n        this.dragControl = null;\n        OpenLayers.Control.prototype.destroy.apply(this, arguments);\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.TransformFeature\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/UTFGrid.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.UTFGrid = OpenLayers.Class(OpenLayers.Control, {\n    \n        autoActivate: true,\n\n        layers: null,\n\n    /* Property: defaultHandlerOptions\n     * The default opts passed to the handler constructors\n     */\n    defaultHandlerOptions: {\n        'delay': 300,\n        'pixelTolerance': 4,\n        'stopMove': false,\n        'single': true,\n        'double': false,\n        'stopSingle': false,\n        'stopDouble': false\n    },\n\n    /* APIProperty: handlerMode\n     * Defaults to 'click'. Can be 'hover' or 'move'.\n     */\n    handlerMode: 'click',\n\n        setHandler: function(hm) {\n        this.handlerMode = hm;\n        this.resetHandler();\n    },\n\n        resetHandler: function() {\n        if (this.handler) {\n            this.handler.deactivate();\n            this.handler.destroy();\n            this.handler = null;\n        }\n   \n        if (this.handlerMode == 'hover') {\n            this.handler = new OpenLayers.Handler.Hover(\n                this,\n                {'pause': this.handleEvent, 'move': this.reset},\n                this.handlerOptions\n            );\n        } else if (this.handlerMode == 'click') {\n            this.handler = new OpenLayers.Handler.Click(\n                this, {\n                    'click': this.handleEvent\n                }, this.handlerOptions\n            );\n        } else if (this.handlerMode == 'move') {\n            this.handler = new OpenLayers.Handler.Hover(\n                this,\n                {'pause': this.handleEvent, 'move': this.handleEvent},\n                this.handlerOptions\n            );\n        }\n        if (this.handler) {\n            return true;\n        } else {\n            return false;\n        }\n    },\n\n        initialize: function(options) {\n        options = options || {};\n        options.handlerOptions = options.handlerOptions || this.defaultHandlerOptions;\n        OpenLayers.Control.prototype.initialize.apply(this, [options]);\n        this.resetHandler();\n    }, \n\n        handleEvent: function(evt) {\n        if (evt == null) {\n            this.reset();\n            return;\n        }\n\n        var lonLat = this.map.getLonLatFromPixel(evt.xy);\n        if (!lonLat) { \n            return;\n        }    \n        \n        var layers = this.findLayers();\n        if (layers.length > 0) {\n            var infoLookup = {};\n            var layer, idx;\n            for (var i=0, len=layers.length; i<len; i++) {\n                layer = layers[i];\n                idx = OpenLayers.Util.indexOf(this.map.layers, layer);\n                infoLookup[idx] = layer.getFeatureInfo(lonLat);\n            }\n            this.callback(infoLookup, lonLat, evt.xy);\n        }\n    },\n\n        callback: function(infoLookup) {\n    },\n\n        reset: function(evt) {\n        this.callback(null);\n    },\n\n        findLayers: function() {\n        var candidates = this.layers || this.map.layers;\n        var layers = [];\n        var layer;\n        for (var i=candidates.length-1; i>=0; --i) {\n            layer = candidates[i];\n            if (layer instanceof OpenLayers.Layer.UTFGrid ) { \n                layers.push(layer);\n            }\n        }\n        return layers;\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.UTFGrid\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/WMSGetFeatureInfo.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Control.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {\n\n       hover: false,\n\n        drillDown: false,\n\n        maxFeatures: 10,\n\n        clickCallback: \"click\",\n\n        output: \"features\",\n\n        layers: null,\n\n        queryVisible: false,\n\n        url: null,\n\n        layerUrls: null,\n\n        infoFormat: 'text/html',\n\n        vendorParams: {},\n\n        format: null,\n\n        formatOptions: null,\n\n    \n        handler: null,\n\n        hoverRequest: null,\n\n    \n        initialize: function(options) {\n        options = options || {};\n        options.handlerOptions = options.handlerOptions || {};\n\n        OpenLayers.Control.prototype.initialize.apply(this, [options]);\n\n        if(!this.format) {\n            this.format = new OpenLayers.Format.WMSGetFeatureInfo(\n                options.formatOptions\n            );\n        }\n\n        if(this.drillDown === true) {\n            this.hover = false;\n        }\n\n        if(this.hover) {\n            this.handler = new OpenLayers.Handler.Hover(\n                   this, {\n                       'move': this.cancelHover,\n                       'pause': this.getInfoForHover\n                   },\n                   OpenLayers.Util.extend(this.handlerOptions.hover || {}, {\n                       'delay': 250\n                   }));\n        } else {\n            var callbacks = {};\n            callbacks[this.clickCallback] = this.getInfoForClick;\n            this.handler = new OpenLayers.Handler.Click(\n                this, callbacks, this.handlerOptions.click || {});\n        }\n    },\n\n        getInfoForClick: function(evt) {\n        this.events.triggerEvent(\"beforegetfeatureinfo\", {xy: evt.xy});\n        OpenLayers.Element.addClass(this.map.viewPortDiv, \"olCursorWait\");\n        this.request(evt.xy, {});\n    },\n\n        getInfoForHover: function(evt) {\n        this.events.triggerEvent(\"beforegetfeatureinfo\", {xy: evt.xy});\n        this.request(evt.xy, {hover: true});\n    },\n\n        cancelHover: function() {\n        if (this.hoverRequest) {\n            this.hoverRequest.abort();\n            this.hoverRequest = null;\n        }\n    },\n\n        findLayers: function() {\n\n        var candidates = this.layers || this.map.layers;\n        var layers = [];\n        var layer, url;\n        for(var i = candidates.length - 1; i >= 0; --i) {\n            layer = candidates[i];\n            if(layer instanceof OpenLayers.Layer.WMS &&\n               (!this.queryVisible || layer.getVisibility())) {\n                url = OpenLayers.Util.isArray(layer.url) ? layer.url[0] : layer.url;\n                if(this.drillDown === false && !this.url) {\n                    this.url = url;\n                }\n                if(this.drillDown === true || this.urlMatches(url)) {\n                    layers.push(layer);\n                }\n            }\n        }\n        return layers;\n    },\n\n        urlMatches: function(url) {\n        var matches = OpenLayers.Util.isEquivalentUrl(this.url, url);\n        if(!matches && this.layerUrls) {\n            for(var i=0, len=this.layerUrls.length; i<len; ++i) {\n                if(OpenLayers.Util.isEquivalentUrl(this.layerUrls[i], url)) {\n                    matches = true;\n                    break;\n                }\n            }\n        }\n        return matches;\n    },\n\n        buildWMSOptions: function(url, layers, clickPosition, format) {\n        var layerNames = [], styleNames = [];\n        for (var i = 0, len = layers.length; i < len; i++) {\n            if (layers[i].params.LAYERS != null) {\n                layerNames = layerNames.concat(layers[i].params.LAYERS);\n                styleNames = styleNames.concat(this.getStyleNames(layers[i]));\n            }\n        }\n        var firstLayer = layers[0];\n        var projection = this.map.getProjection();\n        var layerProj = firstLayer.projection;\n        if (layerProj && layerProj.equals(this.map.getProjectionObject())) {\n            projection = layerProj.getCode();\n        }\n        var params = OpenLayers.Util.extend({\n            service: \"WMS\",\n            version: firstLayer.params.VERSION,\n            request: \"GetFeatureInfo\",\n            exceptions: firstLayer.params.EXCEPTIONS,\n            bbox: this.map.getExtent().toBBOX(null,\n                firstLayer.reverseAxisOrder()),\n            feature_count: this.maxFeatures,\n            height: this.map.getSize().h,\n            width: this.map.getSize().w,\n            format: format,\n            info_format: firstLayer.params.INFO_FORMAT || this.infoFormat\n        }, (parseFloat(firstLayer.params.VERSION) >= 1.3) ?\n            {\n                crs: projection,\n                i: parseInt(clickPosition.x),\n                j: parseInt(clickPosition.y)\n            } :\n            {\n                srs: projection,\n                x: parseInt(clickPosition.x),\n                y: parseInt(clickPosition.y)\n            }\n        );\n        if (layerNames.length != 0) {\n            params = OpenLayers.Util.extend({\n                layers: layerNames,\n                query_layers: layerNames,\n                styles: styleNames\n            }, params);\n        }\n        OpenLayers.Util.applyDefaults(params, this.vendorParams);\n        return {\n            url: url,\n            params: OpenLayers.Util.upperCaseObject(params),\n            callback: function(request) {\n                this.handleResponse(clickPosition, request, url);\n            },\n            scope: this\n        };\n    },\n\n        getStyleNames: function(layer) {\n        var styleNames;\n        if (layer.params.STYLES) {\n            styleNames = layer.params.STYLES;\n        } else {\n            if (OpenLayers.Util.isArray(layer.params.LAYERS)) {\n                styleNames = new Array(layer.params.LAYERS.length);\n            } else {\n                styleNames = layer.params.LAYERS.toString().replace(/[^,]/g, \"\");\n            }\n        }\n        return styleNames;\n    },\n\n        request: function(clickPosition, options) {\n        var layers = this.findLayers();\n        if(layers.length == 0) {\n            this.events.triggerEvent(\"nogetfeatureinfo\");\n            OpenLayers.Element.removeClass(this.map.viewPortDiv, \"olCursorWait\");\n            return;\n        }\n\n        options = options || {};\n        if(this.drillDown === false) {\n            var wmsOptions = this.buildWMSOptions(this.url, layers,\n                clickPosition, layers[0].params.FORMAT);\n            var request = OpenLayers.Request.GET(wmsOptions);\n\n            if (options.hover === true) {\n                this.hoverRequest = request;\n            }\n        } else {\n            this._requestCount = 0;\n            this._numRequests = 0;\n            this.features = [];\n            var services = {}, url;\n            for(var i=0, len=layers.length; i<len; i++) {\n                var layer = layers[i];\n                var service, found = false;\n                url = OpenLayers.Util.isArray(layer.url) ? layer.url[0] : layer.url;\n                if(url in services) {\n                    services[url].push(layer);\n                } else {\n                    this._numRequests++;\n                    services[url] = [layer];\n                }\n            }\n            var layers;\n            for (var url in services) {\n                layers = services[url];\n                var wmsOptions = this.buildWMSOptions(url, layers,\n                    clickPosition, layers[0].params.FORMAT);\n                OpenLayers.Request.GET(wmsOptions);\n            }\n        }\n    },\n\n        triggerGetFeatureInfo: function(request, xy, features) {\n        this.events.triggerEvent(\"getfeatureinfo\", {\n            text: request.responseText,\n            features: features,\n            request: request,\n            xy: xy\n        });\n        OpenLayers.Element.removeClass(this.map.viewPortDiv, \"olCursorWait\");\n    },\n\n        handleResponse: function(xy, request, url) {\n\n        var doc = request.responseXML;\n        if(!doc || !doc.documentElement) {\n            doc = request.responseText;\n        }\n\n        var features = [];\n        var responseHeaders = request.getAllResponseHeaders();\n        if(responseHeaders && this.infoFormat === \"application/json\" && responseHeaders.indexOf(\"application/json\") !== -1) {\n            features = new OpenLayers.Format.GeoJSON().read(doc);\n        }\n        else {\n            features = this.format.read(doc);\n        }\n\n        if (this.drillDown === false) {\n            this.triggerGetFeatureInfo(request, xy, features);\n        } else {\n            this._requestCount++;\n            if (this.output === \"object\") {\n                this._features = (this._features || []).concat(\n                    {url: url, features: features}\n                );\n            } else {\n            this._features = (this._features || []).concat(features);\n            }\n\n            if (this._requestCount === this._numRequests) {\n                this.triggerGetFeatureInfo(request, xy, this._features.concat());\n                delete this._features;\n                delete this._requestCount;\n                delete this._numRequests;\n            }\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.WMSGetFeatureInfo\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/WMTSGetFeatureInfo.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Control.WMTSGetFeatureInfo = OpenLayers.Class(OpenLayers.Control, {\n\n       hover: false,\n    \n        requestEncoding: \"KVP\",\n\n        drillDown: false,\n\n        maxFeatures: 10,\n\n        clickCallback: \"click\",\n    \n        layers: null,\n\n        queryVisible: true,\n\n        infoFormat: 'text/html',\n    \n        vendorParams: {},\n    \n        format: null,\n    \n        formatOptions: null,\n\n        \n        handler: null,\n    \n        hoverRequest: null,\n    \n        \n        pending: 0,\n\n        initialize: function(options) {\n        options = options || {};\n        options.handlerOptions = options.handlerOptions || {};\n\n        OpenLayers.Control.prototype.initialize.apply(this, [options]);\n        \n        if (!this.format) {\n            this.format = new OpenLayers.Format.WMSGetFeatureInfo(\n                options.formatOptions\n            );\n        }\n        \n        if (this.drillDown === true) {\n            this.hover = false;\n        }\n\n        if (this.hover) {\n            this.handler = new OpenLayers.Handler.Hover(\n                this, {\n                    move: this.cancelHover,\n                    pause: this.getInfoForHover\n                },\n                OpenLayers.Util.extend(\n                    this.handlerOptions.hover || {}, {delay: 250}\n                )\n            );\n        } else {\n            var callbacks = {};\n            callbacks[this.clickCallback] = this.getInfoForClick;\n            this.handler = new OpenLayers.Handler.Click(\n                this, callbacks, this.handlerOptions.click || {}\n            );\n        }\n    },\n\n        getInfoForClick: function(evt) {\n        this.request(evt.xy, {});\n    },\n   \n        getInfoForHover: function(evt) {\n        this.request(evt.xy, {hover: true});\n    },\n\n        cancelHover: function() {\n        if (this.hoverRequest) {\n            --this.pending;\n            if (this.pending <= 0) {\n                OpenLayers.Element.removeClass(this.map.viewPortDiv, \"olCursorWait\");\n                this.pending = 0;\n            }            \n            this.hoverRequest.abort();\n            this.hoverRequest = null;\n        }\n    },\n\n        findLayers: function() {\n        var candidates = this.layers || this.map.layers;\n        var layers = [];\n        var layer;\n        for (var i=candidates.length-1; i>=0; --i) {\n            layer = candidates[i];\n            if (layer instanceof OpenLayers.Layer.WMTS &&\n                layer.requestEncoding === this.requestEncoding &&\n                (!this.queryVisible || layer.getVisibility())) {\n                layers.push(layer);\n                if (!this.drillDown || this.hover) {\n                    break;\n                }\n            }\n        }\n        return layers;\n    },\n    \n        buildRequestOptions: function(layer, xy) {\n        var loc = this.map.getLonLatFromPixel(xy);\n        var getTileUrl = layer.getURL(\n            new OpenLayers.Bounds(loc.lon, loc.lat, loc.lon, loc.lat)\n        );\n        var params = OpenLayers.Util.getParameters(getTileUrl);\n        var tileInfo = layer.getTileInfo(loc);\n        OpenLayers.Util.extend(params, {\n            service: \"WMTS\",\n            version: layer.version,\n            request: \"GetFeatureInfo\",\n            infoFormat: this.infoFormat,\n            feature_count: this.maxFeatures,\n            i: tileInfo.i,\n            j: tileInfo.j\n        });\n        OpenLayers.Util.applyDefaults(params, this.vendorParams);\n        return {\n            url: OpenLayers.Util.isArray(layer.url) ? layer.url[0] : layer.url,\n            params: OpenLayers.Util.upperCaseObject(params),\n            callback: function(request) {\n                this.handleResponse(xy, request, layer);\n            },\n            scope: this\n        };\n    },\n\n        request: function(xy, options) {\n        options = options || {};\n        var layers = this.findLayers();\n        if (layers.length > 0) {\n            var issue, layer;\n            for (var i=0, len=layers.length; i<len; i++) {\n                layer = layers[i];\n                issue = this.events.triggerEvent(\"beforegetfeatureinfo\", {\n                    xy: xy,\n                    layer: layer\n                });\n                if (issue !== false) {\n                    ++this.pending;\n                    var requestOptions = this.buildRequestOptions(layer, xy);\n                    var request = OpenLayers.Request.GET(requestOptions);\n                    if (options.hover === true) {\n                        this.hoverRequest = request;\n                    }\n                }\n            }\n            if (this.pending > 0) {\n                OpenLayers.Element.addClass(this.map.viewPortDiv, \"olCursorWait\");\n            }\n        }\n    },\n\n        handleResponse: function(xy, request, layer) {\n        --this.pending;\n        if (this.pending <= 0) {\n            OpenLayers.Element.removeClass(this.map.viewPortDiv, \"olCursorWait\");\n            this.pending = 0;\n        }\n        if (request.status && (request.status < 200 || request.status >= 300)) {\n            this.events.triggerEvent(\"exception\", {\n                xy: xy, \n                request: request,\n                layer: layer\n            });\n        } else {\n            var doc = request.responseXML;\n            if (!doc || !doc.documentElement) {\n                doc = request.responseText;\n            }\n            var features, except;\n            try {\n                features = this.format.read(doc);\n            } catch (error) {\n                except = true;\n                this.events.triggerEvent(\"exception\", {\n                    xy: xy,\n                    request: request,\n                    error: error,\n                    layer: layer\n                });\n            }\n            if (!except) {\n                this.events.triggerEvent(\"getfeatureinfo\", {\n                    text: request.responseText,\n                    features: features,\n                    request: request,\n                    xy: xy,\n                    layer: layer\n                });\n            }\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.WMTSGetFeatureInfo\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/Zoom.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.Zoom = OpenLayers.Class(OpenLayers.Control, {\n    \n        zoomInText: \"+\",\n\n        zoomInId: \"olZoomInLink\",\n\n        zoomOutText: \"\\u2212\",\n\n        zoomOutId: \"olZoomOutLink\",\n\n        draw: function() {\n        var div = OpenLayers.Control.prototype.draw.apply(this),\n            links = this.getOrCreateLinks(div),\n            zoomIn = links.zoomIn,\n            zoomOut = links.zoomOut,\n            eventsInstance = this.map.events;\n        \n        if (zoomOut.parentNode !== div) {\n            eventsInstance = this.events;\n            eventsInstance.attachToElement(zoomOut.parentNode);\n        }\n        eventsInstance.register(\"buttonclick\", this, this.onZoomClick);\n        \n        this.zoomInLink = zoomIn;\n        this.zoomOutLink = zoomOut;\n        return div;\n    },\n    \n        getOrCreateLinks: function(el) {\n        var zoomIn = document.getElementById(this.zoomInId),\n            zoomOut = document.getElementById(this.zoomOutId);\n        if (!zoomIn) {\n            zoomIn = document.createElement(\"a\");\n            zoomIn.href = \"#zoomIn\";\n            zoomIn.appendChild(document.createTextNode(this.zoomInText));\n            zoomIn.className = \"olControlZoomIn\";\n            el.appendChild(zoomIn);\n        }\n        OpenLayers.Element.addClass(zoomIn, \"olButton\");\n        if (!zoomOut) {\n            zoomOut = document.createElement(\"a\");\n            zoomOut.href = \"#zoomOut\";\n            zoomOut.appendChild(document.createTextNode(this.zoomOutText));\n            zoomOut.className = \"olControlZoomOut\";\n            el.appendChild(zoomOut);\n        }\n        OpenLayers.Element.addClass(zoomOut, \"olButton\");\n        return {\n            zoomIn: zoomIn, zoomOut: zoomOut\n        };\n    },\n    \n        onZoomClick: function(evt) {\n        var button = evt.buttonElement;\n        if (button === this.zoomInLink) {\n            this.map.zoomIn();\n        } else if (button === this.zoomOutLink) {\n            this.map.zoomOut();\n        }\n    },\n\n        destroy: function() {\n        if (this.map) {\n            this.map.events.unregister(\"buttonclick\", this, this.onZoomClick);\n        }\n        delete this.zoomInLink;\n        delete this.zoomOutLink;\n        OpenLayers.Control.prototype.destroy.apply(this);\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.Zoom\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/ZoomBox.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.ZoomBox = OpenLayers.Class(OpenLayers.Control, {\n        type: OpenLayers.Control.TYPE_TOOL,\n\n        out: false,\n\n        keyMask: null,\n\n        alwaysZoom: false,\n    \n        zoomOnClick: true,\n\n        zoomBox: function (position) {\n        if (position instanceof OpenLayers.Bounds) {\n            var bounds,\n                targetCenterPx = position.getCenterPixel();\n            if (!this.out) {\n                var minXY = this.map.getLonLatFromPixel({\n                    x: position.left,\n                    y: position.bottom\n                });\n                var maxXY = this.map.getLonLatFromPixel({\n                    x: position.right,\n                    y: position.top\n                });\n                bounds = new OpenLayers.Bounds(minXY.lon, minXY.lat,\n                                               maxXY.lon, maxXY.lat);\n            } else {\n                var pixWidth = position.right - position.left;\n                var pixHeight = position.bottom - position.top;\n                var zoomFactor = Math.min((this.map.size.h / pixHeight),\n                    (this.map.size.w / pixWidth));\n                var extent = this.map.getExtent();\n                var center = this.map.getLonLatFromPixel(targetCenterPx);\n                var xmin = center.lon - (extent.getWidth()/2)*zoomFactor;\n                var xmax = center.lon + (extent.getWidth()/2)*zoomFactor;\n                var ymin = center.lat - (extent.getHeight()/2)*zoomFactor;\n                var ymax = center.lat + (extent.getHeight()/2)*zoomFactor;\n                bounds = new OpenLayers.Bounds(xmin, ymin, xmax, ymax);\n            }\n            var lastZoom = this.map.getZoom(),\n                size = this.map.getSize(),\n                centerPx = {x: size.w / 2, y: size.h / 2},\n                zoom = this.map.getZoomForExtent(bounds),\n                oldRes = this.map.getResolution(),\n                newRes = this.map.getResolutionForZoom(zoom);\n            if (oldRes == newRes) {\n                this.map.setCenter(this.map.getLonLatFromPixel(targetCenterPx));\n            } else {\n              var zoomOriginPx = {\n                    x: (oldRes * targetCenterPx.x - newRes * centerPx.x) /\n                        (oldRes - newRes),\n                    y: (oldRes * targetCenterPx.y - newRes * centerPx.y) /\n                        (oldRes - newRes)\n                };\n                this.map.zoomTo(zoom, zoomOriginPx);\n            }\n            if (lastZoom == this.map.getZoom() && this.alwaysZoom == true){ \n                this.map.zoomTo(lastZoom + (this.out ? -1 : 1)); \n            }\n        } else if (this.zoomOnClick) { // it's a pixel\n            if (!this.out) {\n                this.map.zoomTo(this.map.getZoom() + 1, position);\n            } else {\n                this.map.zoomTo(this.map.getZoom() - 1, position);\n            }\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.ZoomBox\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/ZoomIn.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.ZoomIn = OpenLayers.Class(OpenLayers.Control.Button, {\n\n        trigger: function(){\n        if (this.map) {\n            this.map.zoomIn();\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.ZoomIn\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/ZoomOut.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.ZoomOut = OpenLayers.Class(OpenLayers.Control.Button, {\n\n        trigger: function(){\n        if (this.map) {\n            this.map.zoomOut();\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.ZoomOut\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/ZoomPanel.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.ZoomPanel = OpenLayers.Class(OpenLayers.Control.Panel, {\n\n        initialize: function(options) {\n        OpenLayers.Control.Panel.prototype.initialize.apply(this, [options]);\n        this.addControls([\n            new OpenLayers.Control.ZoomIn(),\n            new OpenLayers.Control.ZoomToMaxExtent(),\n            new OpenLayers.Control.ZoomOut()\n        ]);\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.ZoomPanel\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control/ZoomToMaxExtent.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control.ZoomToMaxExtent = OpenLayers.Class(OpenLayers.Control.Button, {\n\n        trigger: function() {\n        if (this.map) {\n            this.map.zoomToMaxExtent();\n        }    \n    },\n\n    CLASS_NAME: \"OpenLayers.Control.ZoomToMaxExtent\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Control.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Control = OpenLayers.Class({\n\n        id: null,\n    \n        map: null,\n\n        div: null,\n\n        type: null, \n\n        allowSelection: false,  \n\n        displayClass: \"\",\n    \n        autoActivate: false,\n\n        active: null,\n\n        handlerOptions: null,\n\n        handler: null,\n\n        eventListeners: null,\n\n        events: null,\n\n        initialize: function (options) {\n        this.displayClass = \n            this.CLASS_NAME.replace(\"OpenLayers.\", \"ol\").replace(/\\./g, \"\");\n        \n        OpenLayers.Util.extend(this, options);\n        \n        this.events = new OpenLayers.Events(this);\n        if(this.eventListeners instanceof Object) {\n            this.events.on(this.eventListeners);\n        }\n        if (this.id == null) {\n            this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + \"_\");\n        }\n    },\n\n        destroy: function () {\n        if(this.events) {\n            if(this.eventListeners) {\n                this.events.un(this.eventListeners);\n            }\n            this.events.destroy();\n            this.events = null;\n        }\n        this.eventListeners = null;\n        if (this.handler) {\n            this.handler.destroy();\n            this.handler = null;\n        }\n        if(this.handlers) {\n            for(var key in this.handlers) {\n                if(this.handlers.hasOwnProperty(key) &&\n                   typeof this.handlers[key].destroy == \"function\") {\n                    this.handlers[key].destroy();\n                }\n            }\n            this.handlers = null;\n        }\n        if (this.map) {\n            this.map.removeControl(this);\n            this.map = null;\n        }\n        this.div = null;\n    },\n\n        setMap: function(map) {\n        this.map = map;\n        if (this.handler) {\n            this.handler.setMap(map);\n        }\n    },\n  \n        draw: function (px) {\n        if (this.div == null) {\n            this.div = OpenLayers.Util.createDiv(this.id);\n            this.div.className = this.displayClass;\n            if (!this.allowSelection) {\n                this.div.className += \" olControlNoSelect\";\n                this.div.setAttribute(\"unselectable\", \"on\", 0);\n                this.div.onselectstart = OpenLayers.Function.False; \n            }    \n            if (this.title != \"\") {\n                this.div.title = this.title;\n            }\n        }\n        if (px != null) {\n            this.position = px.clone();\n        }\n        this.moveTo(this.position);\n        return this.div;\n    },\n\n        moveTo: function (px) {\n        if ((px != null) && (this.div != null)) {\n            this.div.style.left = px.x + \"px\";\n            this.div.style.top = px.y + \"px\";\n        }\n    },\n\n        activate: function () {\n        if (this.active) {\n            return false;\n        }\n        if (this.handler) {\n            this.handler.activate();\n        }\n        this.active = true;\n        if(this.map) {\n            OpenLayers.Element.addClass(\n                this.map.viewPortDiv,\n                this.displayClass.replace(/ /g, \"\") + \"Active\"\n            );\n        }\n        this.events.triggerEvent(\"activate\");\n        return true;\n    },\n    \n        deactivate: function () {\n        if (this.active) {\n            if (this.handler) {\n                this.handler.deactivate();\n            }\n            this.active = false;\n            if(this.map) {\n                OpenLayers.Element.removeClass(\n                    this.map.viewPortDiv,\n                    this.displayClass.replace(/ /g, \"\") + \"Active\"\n                );\n            }\n            this.events.triggerEvent(\"deactivate\");\n            return true;\n        }\n        return false;\n    },\n\n    CLASS_NAME: \"OpenLayers.Control\"\n});\n\nOpenLayers.Control.TYPE_BUTTON = 1;\n\nOpenLayers.Control.TYPE_TOGGLE = 2;\n\nOpenLayers.Control.TYPE_TOOL   = 3;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Events/buttonclick.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Events.buttonclick = OpenLayers.Class({\n    \n        target: null,\n    \n        events: [\n        'mousedown', 'mouseup', 'click', 'dblclick',\n        'touchstart', 'touchmove', 'touchend', 'keydown'\n    ],\n    \n        startRegEx: /^mousedown|touchstart$/,\n\n        cancelRegEx: /^touchmove$/,\n\n        completeRegEx: /^mouseup|touchend$/,\n\n        isDeviceTouchCapable: 'ontouchstart' in window ||\n        window.DocumentTouch && document instanceof window.DocumentTouch,\n    \n        \n        initialize: function(target) {\n        this.target = target;\n        for (var i=this.events.length-1; i>=0; --i) {\n            this.target.register(this.events[i], this, this.buttonClick, {\n                extension: true\n            });\n        }\n    },\n    \n        destroy: function() {\n        for (var i=this.events.length-1; i>=0; --i) {\n            this.target.unregister(this.events[i], this, this.buttonClick);\n        }\n        delete this.target;\n    },\n\n        getPressedButton: function(element) {\n        var depth = 3, // limit the search depth\n            button;\n        do {\n            if(OpenLayers.Element.hasClass(element, \"olButton\")) {\n                button = element;\n                break;\n            }\n            element = element.parentNode;\n        } while(--depth > 0 && element);\n        return button;\n    },\n    \n        ignore: function(element) {\n        var depth = 3,\n            ignore = false;\n        do {\n            if (element.nodeName.toLowerCase() === 'a') {\n                ignore = true;\n                break;\n            }\n            element = element.parentNode;\n        } while (--depth > 0 && element);\n        return ignore;\n    },\n\n        buttonClick: function(evt) {\n        var propagate = true,\n            element = OpenLayers.Event.element(evt);\n\n        if (element &&\n           (OpenLayers.Event.isLeftClick(evt) &&\n            !this.isDeviceTouchCapable ||\n            !~evt.type.indexOf(\"mouse\"))) {\n            var button = this.getPressedButton(element);\n            if (button) {\n                if (evt.type === \"keydown\") {\n                    switch (evt.keyCode) {\n                    case OpenLayers.Event.KEY_RETURN:\n                    case OpenLayers.Event.KEY_SPACE:\n                        this.target.triggerEvent(\"buttonclick\", {\n                            buttonElement: button\n                        });\n                        OpenLayers.Event.stop(evt);\n                        propagate = false;\n                        break;\n                    }\n                } else if (this.startEvt) {\n                    if (this.completeRegEx.test(evt.type)) {\n                        var pos = OpenLayers.Util.pagePosition(button);\n                        var viewportElement = OpenLayers.Util.getViewportElement();\n                        var scrollTop = window.pageYOffset || viewportElement.scrollTop;\n                        var scrollLeft = window.pageXOffset || viewportElement.scrollLeft;\n                        pos[0] = pos[0] - scrollLeft;\n                        pos[1] = pos[1] - scrollTop;\n                        \n                        this.target.triggerEvent(\"buttonclick\", {\n                            buttonElement: button,\n                            buttonXY: {\n                                x: this.startEvt.clientX - pos[0],\n                                y: this.startEvt.clientY - pos[1]\n                            }\n                        });\n                    }\n                    if (this.cancelRegEx.test(evt.type)) {\n                        if (evt.touches && this.startEvt.touches &&\n                                (Math.abs(evt.touches[0].olClientX - this.startEvt.touches[0].olClientX) > 4 ||\n                                Math.abs(evt.touches[0].olClientY - this.startEvt.touches[0].olClientY)) > 4) {\n                            delete this.startEvt;\n                        }\n                    }\n                    OpenLayers.Event.stop(evt);\n                    propagate = false;\n                }\n                if (this.startRegEx.test(evt.type)) {\n                    this.startEvt = evt;\n                    OpenLayers.Event.stop(evt);\n                    propagate = false;\n                }\n            } else {\n                propagate = !this.ignore(OpenLayers.Event.element(evt));\n                delete this.startEvt;\n            }\n        }\n        return propagate;\n    }\n    \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Events/featureclick.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Events.featureclick = OpenLayers.Class({\n    \n        cache: null,\n    \n        map: null,\n    \n        provides: [\"featureclick\", \"nofeatureclick\", \"featureover\", \"featureout\"],\n    \n    lastClientX: 0,\n\n    lastClientY: 0,\n    \n        initialize: function(target) {\n        this.target = target;\n        if (target.object instanceof OpenLayers.Map) {\n            this.setMap(target.object);\n        } else if (target.object instanceof OpenLayers.Layer.Vector) {\n            if (target.object.map) {\n                this.setMap(target.object.map);\n            } else {\n                target.object.events.register(\"added\", this, function(evt) {\n                    this.setMap(target.object.map);\n                });\n            }\n        } else {\n            throw(\"Listeners for '\" + this.provides.join(\"', '\") +\n                \"' events can only be registered for OpenLayers.Layer.Vector \" + \n                \"or OpenLayers.Map instances\");\n        }\n        for (var i=this.provides.length-1; i>=0; --i) {\n            target.extensions[this.provides[i]] = true;\n        }\n    },\n    \n        setMap: function(map) {\n        this.map = map;\n        this.cache = {};\n        map.events.register(\"mousedown\", this, this.start, {extension: true});\n        map.events.register(\"mouseup\", this, this.onClick, {extension: true});\n        map.events.register(\"touchstart\", this, this.start, {extension: true});\n        map.events.register(\"touchmove\", this, this.cancel, {extension: true});\n        map.events.register(\"touchend\", this, this.onClick, {extension: true});\n        map.events.register(\"mousemove\", this, this.onMousemove, {extension: true});\n    },\n    \n        start: function(evt) {\n        this.startEvt = evt;\n    },\n    \n        onClick: function(evt) {\n        if (!this.startEvt || evt.type !== \"touchend\" &&\n                !OpenLayers.Event.isLeftClick(evt)) {\n            return;\n        }\n        var features = this.getFeatures(this.startEvt);\n        delete this.startEvt;\n        var feature, layer, more, clicked = {};\n        for (var i=0, len=features.length; i<len; ++i) {\n            feature = features[i];\n            layer = feature.layer;\n            clicked[layer.id] = true;\n            more = this.triggerEvent(\"featureclick\", {feature: feature});\n            if (more === false) {\n                break;\n            }\n        }\n        for (i=0, len=this.map.layers.length; i<len; ++i) {\n            layer = this.map.layers[i];\n            if (layer instanceof OpenLayers.Layer.Vector && !clicked[layer.id]) {\n                this.triggerEvent(\"nofeatureclick\", {layer: layer});\n            }\n        }\n    },\n    \n        onMousemove: function(evt) {\n        delete this.startEvt;\n        var clientX = evt.clientX;\n        var clientY = evt.clientY;\n        if (this.lastClientX == clientX && this.lastClientY == clientY) {\n            return;\n        } else {\n            this.lastClientX = clientX;\n            this.lastClientY = clientY;\n        }\n        var features = this.getFeatures(evt);\n        var over = {}, newly = [], feature;\n        for (var i=0, len=features.length; i<len; ++i) {\n            feature = features[i];\n            over[feature.id] = feature;\n            if (!this.cache[feature.id]) {\n                newly.push(feature);\n            }\n        }\n        var out = [];\n        for (var id in this.cache) {\n            feature = this.cache[id];\n            if (feature.layer && feature.layer.map) {\n                if (!over[feature.id]) {\n                    out.push(feature);\n                }\n            } else {\n                delete this.cache[id];\n            }\n        }\n        var more;\n        for (i=0, len=newly.length; i<len; ++i) {\n            feature = newly[i];\n            this.cache[feature.id] = feature;\n            more = this.triggerEvent(\"featureover\", {feature: feature});\n            if (more === false) {\n                break;\n            }\n        }\n        for (i=0, len=out.length; i<len; ++i) {\n            feature = out[i];\n            delete this.cache[feature.id];\n            more = this.triggerEvent(\"featureout\", {feature: feature});\n            if (more === false) {\n                break;\n            }\n        }\n    },\n    \n        triggerEvent: function(type, evt) {\n        var layer = evt.feature ? evt.feature.layer : evt.layer,\n            object = this.target.object;\n        if (object instanceof OpenLayers.Map || object === layer) {\n            return this.target.triggerEvent(type, evt);\n        }\n    },\n\n        getFeatures: function(evt) {\n        var x = evt.clientX, y = evt.clientY,\n            features = [], targets = [], layers = [],\n            layer, renderer, target, feature, i, len, featureId;\n        for (i=this.map.layers.length-1; i>=0; --i) {\n            layer = this.map.layers[i];\n            renderer = layer.renderer;\n            if (layer.div.style.display !== \"none\") {\n                if (renderer instanceof OpenLayers.Renderer.Elements) {\n                    if (layer instanceof OpenLayers.Layer.Vector) {\n                        target = document.elementFromPoint(x, y);\n                        while (target && (featureId = renderer.getFeatureIdFromEvent({target: target}))) {\n                            feature = layer.getFeatureById(featureId);\n                            if (feature) {\n                                features.push(feature);\n                                target.style.display = \"none\";\n                                targets.push(target);\n                                target = document.elementFromPoint(x, y);\n                            } else {\n                                target = false;\n                            }\n                        }\n                    }\n                    layers.push(layer);\n                    layer.div.style.display = \"none\";\n                } else if (renderer instanceof OpenLayers.Renderer.Canvas) {\n                    feature = renderer.getFeatureIdFromEvent(evt);\n                    if (feature) {\n                        features.push(feature);\n                        layers.push(layer);\n                    }\n                }\n            }\n        }\n        for (i=0, len=targets.length; i<len; ++i) {\n            targets[i].style.display = \"\";\n        }\n        for (i=layers.length-1; i>=0; --i) {\n            layers[i].div.style.display = \"block\";\n        }\n        return features;\n    },\n    \n        destroy: function() {\n        for (var i=this.provides.length-1; i>=0; --i) {\n            delete this.target.extensions[this.provides[i]];\n        }        \n        this.map.events.un({\n            mousemove: this.onMousemove,\n            mousedown: this.start,\n            mouseup: this.onClick,\n            touchstart: this.start,\n            touchmove: this.cancel,\n            touchend: this.onClick,\n            scope: this\n        });\n        delete this.cache;\n        delete this.map;\n        delete this.target;\n    }\n    \n});\n \nOpenLayers.Events.nofeatureclick = OpenLayers.Events.featureclick;\n\nOpenLayers.Events.featureover = OpenLayers.Events.featureclick;\n\nOpenLayers.Events.featureout = OpenLayers.Events.featureclick;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Events.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Event = {\n\n        observers: false,\n\n        KEY_SPACE: 32,\n    \n        KEY_BACKSPACE: 8,\n\n        KEY_TAB: 9,\n\n        KEY_RETURN: 13,\n\n        KEY_ESC: 27,\n\n        KEY_LEFT: 37,\n\n        KEY_UP: 38,\n\n        KEY_RIGHT: 39,\n\n        KEY_DOWN: 40,\n\n        KEY_DELETE: 46,\n\n\n        element: function(event) {\n        return event.target || event.srcElement;\n    },\n\n        isSingleTouch: function(event) {\n        return event.touches && event.touches.length == 1;\n    },\n\n        isMultiTouch: function(event) {\n        return event.touches && event.touches.length > 1;\n    },\n\n        isTouchEvent: function(evt) {\n        return (\"\" + evt.type).indexOf(\"touch\") === 0 || (\n                \"pointerType\" in evt && (\n                     evt.pointerType === evt.MSPOINTER_TYPE_MOUSE /*IE10 pointer*/ ||\n                     evt.pointerType === \"touch\" /*W3C pointer*/));\n    },\n\n        isLeftClick: function(event) {\n        return (((event.which) && (event.which == 1)) ||\n                ((event.button) && (event.button == 1)));\n    },\n\n         isRightClick: function(event) {\n        return (((event.which) && (event.which == 3)) ||\n                ((event.button) && (event.button == 2)));\n    },\n     \n        stop: function(event, allowDefault) {\n        \n        if (!allowDefault) { \n            OpenLayers.Event.preventDefault(event);\n        }\n                \n        if (event.stopPropagation) {\n            event.stopPropagation();\n        } else {\n            event.cancelBubble = true;\n        }\n    },\n\n        preventDefault: function(event) {\n        if (event.preventDefault) {\n            event.preventDefault();\n        } else {\n            event.returnValue = false;\n        }\n    },\n\n        findElement: function(event, tagName) {\n        var element = OpenLayers.Event.element(event);\n        while (element.parentNode && (!element.tagName ||\n              (element.tagName.toUpperCase() != tagName.toUpperCase()))){\n            element = element.parentNode;\n        }\n        return element;\n    },\n\n        observe: function(elementParam, name, observer, useCapture) {\n        var element = OpenLayers.Util.getElement(elementParam);\n        useCapture = useCapture || false;\n\n        if (name == 'keypress' &&\n           (navigator.appVersion.match(/Konqueror|Safari|KHTML/)\n           || element.attachEvent)) {\n            name = 'keydown';\n        }\n        if (!this.observers) {\n            this.observers = {};\n        }\n        if (!element._eventCacheID) {\n            var idPrefix = \"eventCacheID_\";\n            if (element.id) {\n                idPrefix = element.id + \"_\" + idPrefix;\n            }\n            element._eventCacheID = OpenLayers.Util.createUniqueID(idPrefix);\n        }\n\n        var cacheID = element._eventCacheID;\n        if (!this.observers[cacheID]) {\n            this.observers[cacheID] = [];\n        }\n        this.observers[cacheID].push({\n            'element': element,\n            'name': name,\n            'observer': observer,\n            'useCapture': useCapture\n        });\n        if (element.addEventListener) {\n            element.addEventListener(name, observer, useCapture);\n        } else if (element.attachEvent) {\n            element.attachEvent('on' + name, observer);\n        }\n    },\n\n        stopObservingElement: function(elementParam) {\n        var element = OpenLayers.Util.getElement(elementParam);\n        var cacheID = element._eventCacheID;\n\n        this._removeElementObservers(OpenLayers.Event.observers[cacheID]);\n    },\n\n        _removeElementObservers: function(elementObservers) {\n        if (elementObservers) {\n            for(var i = elementObservers.length-1; i >= 0; i--) {\n                var entry = elementObservers[i];\n                OpenLayers.Event.stopObserving.apply(this, [\n                    entry.element, entry.name, entry.observer, entry.useCapture\n                ]);\n            }\n        }\n    },\n\n        stopObserving: function(elementParam, name, observer, useCapture) {\n        useCapture = useCapture || false;\n    \n        var element = OpenLayers.Util.getElement(elementParam);\n        var cacheID = element._eventCacheID;\n\n        if (name == 'keypress') {\n            if ( navigator.appVersion.match(/Konqueror|Safari|KHTML/) || \n                 element.detachEvent) {\n              name = 'keydown';\n            }\n        }\n        var foundEntry = false;\n        var elementObservers = OpenLayers.Event.observers[cacheID];\n        if (elementObservers) {\n            var i=0;\n            while(!foundEntry && i < elementObservers.length) {\n                var cacheEntry = elementObservers[i];\n    \n                if ((cacheEntry.name == name) &&\n                    (cacheEntry.observer == observer) &&\n                    (cacheEntry.useCapture == useCapture)) {\n    \n                    elementObservers.splice(i, 1);\n                    if (elementObservers.length == 0) {\n                        delete OpenLayers.Event.observers[cacheID];\n                    }\n                    foundEntry = true;\n                    break; \n                }\n                i++;           \n            }\n        }\n        if (foundEntry) {\n            if (element.removeEventListener) {\n                element.removeEventListener(name, observer, useCapture);\n            } else if (element && element.detachEvent) {\n                element.detachEvent('on' + name, observer);\n            }\n        }\n        return foundEntry;\n    },\n    \n        unloadCache: function() {\n        if (OpenLayers.Event && OpenLayers.Event.observers) {\n            for (var cacheID in OpenLayers.Event.observers) {\n                var elementObservers = OpenLayers.Event.observers[cacheID];\n                OpenLayers.Event._removeElementObservers.apply(this, \n                                                           [elementObservers]);\n            }\n            OpenLayers.Event.observers = false;\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Event\"\n};\n\n/* prevent memory leaks in IE */\nOpenLayers.Event.observe(window, 'unload', OpenLayers.Event.unloadCache, false);\n\nOpenLayers.Events = OpenLayers.Class({\n\n        BROWSER_EVENTS: [\n        \"mouseover\", \"mouseout\",\n        \"mousedown\", \"mouseup\", \"mousemove\", \n        \"click\", \"dblclick\", \"rightclick\", \"dblrightclick\",\n        \"resize\", \"focus\", \"blur\",\n        \"touchstart\", \"touchmove\", \"touchend\",\n        \"keydown\"\n    ],\n    \n        TOUCH_MODEL_POINTER: \"pointer\",\n\n        TOUCH_MODEL_MSPOINTER: \"MSPointer\",\n\n        TOUCH_MODEL_TOUCH: \"touch\",\n\n        listeners: null,\n\n        object: null,\n\n        element: null,\n\n        eventHandler: null,\n\n        fallThrough: null,\n\n        includeXY: false,      \n    \n        extensions: null,\n    \n        extensionCount: null,\n\n        clearMouseListener: null,\n\n        initialize: function (object, element, eventTypes, fallThrough, options) {\n        OpenLayers.Util.extend(this, options);\n        this.object     = object;\n        this.fallThrough = fallThrough;\n        this.listeners  = {};\n        this.extensions = {};\n        this.extensionCount = {};\n        this._pointerTouches = [];\n        if (element != null) {\n            this.attachToElement(element);\n        }\n    },\n\n        destroy: function () {\n        for (var e in this.extensions) {\n            if (typeof this.extensions[e] !== \"boolean\") {\n                this.extensions[e].destroy();\n            }\n        }\n        this.extensions = null;\n        if (this.element) {\n            OpenLayers.Event.stopObservingElement(this.element);\n            if(this.element.hasScrollEvent) {\n                OpenLayers.Event.stopObserving(\n                    window, \"scroll\", this.clearMouseListener\n                );\n            }\n        }\n        this.element = null;\n\n        this.listeners = null;\n        this.object = null;\n        this.fallThrough = null;\n        this.eventHandler = null;\n    },\n\n        addEventType: function(eventName) {\n    },\n\n        attachToElement: function (element) {\n        if (this.element) {\n            OpenLayers.Event.stopObservingElement(this.element);\n        } else {\n            this.eventHandler = OpenLayers.Function.bindAsEventListener(\n                this.handleBrowserEvent, this\n            );\n            this.clearMouseListener = OpenLayers.Function.bind(\n                this.clearMouseCache, this\n            );\n        }\n        this.element = element;\n        var touchModel = this.getTouchModel();\n        var type;\n        for (var i = 0, len = this.BROWSER_EVENTS.length; i < len; i++) {\n            type = this.BROWSER_EVENTS[i];\n            OpenLayers.Event.observe(element, type, this.eventHandler\n            );\n            if ((touchModel === this.TOUCH_MODEL_POINTER ||\n                    touchModel === this.TOUCH_MODEL_MSPOINTER) &&\n                    type.indexOf('touch') === 0) {\n                this.addPointerTouchListener(element, type, this.eventHandler);\n            }\n        }\n        OpenLayers.Event.observe(element, \"dragstart\", OpenLayers.Event.stop);\n    },\n    \n        on: function(object) {\n        for(var type in object) {\n            if(type != \"scope\" && object.hasOwnProperty(type)) {\n                this.register(type, object.scope, object[type]);\n            }\n        }\n    },\n\n        register: function (type, obj, func, priority) {\n        if (type in OpenLayers.Events && !this.extensions[type]) {\n            this.extensions[type] = new OpenLayers.Events[type](this);\n        }\n        if (func != null) {\n            if (obj == null)  {\n                obj = this.object;\n            }\n            var listeners = this.listeners[type];\n            if (!listeners) {\n                listeners = [];\n                this.listeners[type] = listeners;\n                this.extensionCount[type] = 0;\n            }\n            var listener = {obj: obj, func: func};\n            if (priority) {\n                listeners.splice(this.extensionCount[type], 0, listener);\n                if (typeof priority === \"object\" && priority.extension) {\n                    this.extensionCount[type]++;\n                }\n            } else {\n                listeners.push(listener);\n            }\n        }\n    },\n\n        registerPriority: function (type, obj, func) {\n        this.register(type, obj, func, true);\n    },\n    \n        un: function(object) {\n        for(var type in object) {\n            if(type != \"scope\" && object.hasOwnProperty(type)) {\n                this.unregister(type, object.scope, object[type]);\n            }\n        }\n    },\n\n        unregister: function (type, obj, func) {\n        if (obj == null)  {\n            obj = this.object;\n        }\n        var listeners = this.listeners[type];\n        if (listeners != null) {\n            for (var i=0, len=listeners.length; i<len; i++) {\n                if (listeners[i].obj == obj && listeners[i].func == func) {\n                    listeners.splice(i, 1);\n                    break;\n                }\n            }\n        }\n    },\n\n        remove: function(type) {\n        if (this.listeners[type] != null) {\n            this.listeners[type] = [];\n        }\n    },\n\n        triggerEvent: function (type, evt) {\n        var listeners = this.listeners[type];\n        if(!listeners || listeners.length == 0) {\n            return undefined;\n        }\n        if (evt == null) {\n            evt = {};\n        }\n        evt.object = this.object;\n        evt.element = this.element;\n        if(!evt.type) {\n            evt.type = type;\n        }\n        listeners = listeners.slice();\n        var continueChain;\n        for (var i=0, len=listeners.length; i<len; i++) {\n            var callback = listeners[i];\n            continueChain = callback.func.apply(callback.obj, [evt]);\n\n            if ((continueChain != undefined) && (continueChain == false)) {\n                break;\n            }\n        }\n        if (!this.fallThrough) {           \n            OpenLayers.Event.stop(evt, true);\n        }\n        return continueChain;\n    },\n\n        handleBrowserEvent: function (evt) {\n        var type = evt.type, listeners = this.listeners[type];\n        if(!listeners || listeners.length == 0) {\n            return;\n        }\n        var touches = evt.touches;\n        if (touches && touches[0]) {\n            var x = 0;\n            var y = 0;\n            var num = touches.length;\n            var touch;\n            for (var i=0; i<num; ++i) {\n                touch = this.getTouchClientXY(touches[i]);\n                x += touch.clientX;\n                y += touch.clientY;\n            }\n            evt.clientX = x / num;\n            evt.clientY = y / num;\n        }\n        if (this.includeXY) {\n            evt.xy = this.getMousePosition(evt);\n        } \n        this.triggerEvent(type, evt);\n    },\n    \n        getTouchClientXY: function (evt) {\n        var win = window.olMockWin || window,\n            winPageX = win.pageXOffset,\n            winPageY = win.pageYOffset,\n            x = evt.clientX,\n            y = evt.clientY;\n        \n        if (evt.pageY === 0 && Math.floor(y) > Math.floor(evt.pageY) ||\n            evt.pageX === 0 && Math.floor(x) > Math.floor(evt.pageX)) {\n            x = x - winPageX;\n            y = y - winPageY;\n        } else if (y < (evt.pageY - winPageY) || x < (evt.pageX - winPageX) ) {\n            x = evt.pageX - winPageX;\n            y = evt.pageY - winPageY;\n        }\n        \n        evt.olClientX = x;\n        evt.olClientY = y;\n        \n        return {\n            clientX: x,\n            clientY: y\n        };\n    },\n    \n        clearMouseCache: function() { \n        this.element.scrolls = null;\n        this.element.lefttop = null;\n        this.element.offsets = null;\n    },      \n\n        getMousePosition: function (evt) {\n        if (!this.includeXY) {\n            this.clearMouseCache();\n        } else if (!this.element.hasScrollEvent) {\n            OpenLayers.Event.observe(window, \"scroll\", this.clearMouseListener);\n            this.element.hasScrollEvent = true;\n        }\n        \n        if (!this.element.scrolls) {\n            var viewportElement = OpenLayers.Util.getViewportElement();\n            this.element.scrolls = [\n                window.pageXOffset || viewportElement.scrollLeft,\n                window.pageYOffset || viewportElement.scrollTop\n            ];\n        }\n\n        if (!this.element.lefttop) {\n            this.element.lefttop = [\n                (document.documentElement.clientLeft || 0),\n                (document.documentElement.clientTop  || 0)\n            ];\n        }\n        \n        if (!this.element.offsets) {\n            this.element.offsets = OpenLayers.Util.pagePosition(this.element);\n        }\n\n        return new OpenLayers.Pixel(\n            (evt.clientX + this.element.scrolls[0]) - this.element.offsets[0]\n                         - this.element.lefttop[0], \n            (evt.clientY + this.element.scrolls[1]) - this.element.offsets[1]\n                         - this.element.lefttop[1]\n        ); \n    },\n\n        getTouchModel: function() {\n        if (!(\"_TOUCH_MODEL\" in OpenLayers.Events)) {\n            OpenLayers.Events._TOUCH_MODEL =\n                    (window.PointerEvent && \"pointer\") ||\n                    (window.MSPointerEvent && \"MSPointer\") ||\n                    ((\"ontouchdown\" in document) && \"touch\") ||\n                    null;\n        }\n        return OpenLayers.Events._TOUCH_MODEL;\n    },\n\n        addPointerTouchListener: function (element, type, handler) {\n        var eventHandler = this.eventHandler;\n        var touches = this._pointerTouches;\n\n        function pointerHandler(evt) {\n            handler(OpenLayers.Util.applyDefaults({\n                stopPropagation: function() {\n                    for (var i=touches.length-1; i>=0; --i) {\n                        touches[i].stopPropagation();\n                    }\n                },\n                preventDefault: function() {\n                    for (var i=touches.length-1; i>=0; --i) {\n                        touches[i].preventDefault();\n                    }\n                },\n                type: type\n            }, evt));\n        }\n\n        switch (type) {\n            case 'touchstart':\n                return this.addPointerTouchListenerStart(element, type, pointerHandler);\n            case 'touchend':\n                return this.addPointerTouchListenerEnd(element, type, pointerHandler);\n            case 'touchmove':\n                return this.addPointerTouchListenerMove(element, type, pointerHandler);\n            default:\n                throw 'Unknown touch event type';\n        }\n    },\n\n        addPointerTouchListenerStart: function(element, type, handler) {\n        var touches = this._pointerTouches;\n\n        var cb = function(e) {\n            if (!OpenLayers.Event.isTouchEvent(e)) {\n                return;\n            }\n\n            var alreadyInArray = false;\n            for (var i=0, ii=touches.length; i<ii; ++i) {\n                if (touches[i].pointerId == e.pointerId) {\n                    alreadyInArray = true;\n                    break;\n                }\n            }\n            if (!alreadyInArray) {\n                touches.push(e);\n            }\n\n            e.touches = touches.slice();\n            handler(e);\n        };\n\n        OpenLayers.Event.observe(element,\n                this.getTouchModel() === this.TOUCH_MODEL_MSPOINTER ?\n                        'MSPointerDown' : 'pointerdown',\n                cb);\n        var internalCb = function (e) {\n            if (!OpenLayers.Event.isTouchEvent(e)) {\n            \treturn;\n            }\n\n            var up = false;\n            for (var i = 0, ii = touches.length; i < ii; ++i) {\n                if (touches[i].pointerId == e.pointerId) {\n                    if (this.clientWidth != 0 && this.clientHeight != 0) {\n                        if ((Math.ceil(e.clientX) >= this.clientWidth || Math.ceil(e.clientY) >= this.clientHeight)) {\n                            touches.splice(i, 1);\n                        }\n                    }\n                    break;\n                }\n            }\n        };\n        OpenLayers.Event.observe(element,\n                this.getTouchModel() === this.TOUCH_MODEL_MSPOINTER ?\n                        'MSPointerOut' : 'pointerout',\n                internalCb);\n    },\n\n        addPointerTouchListenerMove: function (element, type, handler) {\n        var touches = this._pointerTouches;\n        var cb = function(e) {\n            if (!OpenLayers.Event.isTouchEvent(e)) {\n                return;\n            }\n\n            if (touches.length == 1 && touches[0].pageX == e.pageX &&\n                    touches[0].pageY == e.pageY) {\n                return;\n            }\n            for (var i=0, ii=touches.length; i<ii; ++i) {\n                if (touches[i].pointerId == e.pointerId) {\n                    touches[i] = e;\n                    break;\n                }\n            }\n\n            e.touches = touches.slice();\n            handler(e);\n        };\n\n        OpenLayers.Event.observe(element,\n                this.getTouchModel() === this.TOUCH_MODEL_MSPOINTER ?\n                        'MSPointerMove' : 'pointermove',\n                cb);\n    },\n\n        addPointerTouchListenerEnd: function (element, type, handler) {\n        var touches = this._pointerTouches;\n\n        var cb = function(e) {\n            if (!OpenLayers.Event.isTouchEvent(e)) {\n            \treturn;\n            }\n\n            for (var i=0, ii=touches.length; i<ii; ++i) {\n                if (touches[i].pointerId == e.pointerId) {\n                    touches.splice(i, 1);\n                    break;\n                }\n            }\n            \n            e.touches = touches.slice();\n            handler(e);\n        };\n\n        OpenLayers.Event.observe(element,\n                this.getTouchModel() === this.TOUCH_MODEL_MSPOINTER ?\n                        'MSPointerUp' : 'pointerup',\n                cb);\n    },\n\n    CLASS_NAME: \"OpenLayers.Events\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Feature/Vector.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\nOpenLayers.State = {\n        UNKNOWN: 'Unknown',\n    INSERT: 'Insert',\n    UPDATE: 'Update',\n    DELETE: 'Delete'\n};\n\n\nOpenLayers.Feature.Vector = OpenLayers.Class(OpenLayers.Feature, {\n\n        fid: null,\n    \n        geometry: null,\n\n        attributes: null,\n\n        bounds: null,\n\n        state: null,\n    \n        style: null,\n\n        url: null,\n    \n        renderIntent: \"default\",\n    \n        modified: null,\n\n        initialize: function(geometry, attributes, style) {\n        OpenLayers.Feature.prototype.initialize.apply(this,\n                                                      [null, null, attributes]);\n        this.lonlat = null;\n        this.geometry = geometry ? geometry : null;\n        this.state = null;\n        this.attributes = {};\n        if (attributes) {\n            this.attributes = OpenLayers.Util.extend(this.attributes,\n                                                     attributes);\n        }\n        this.style = style ? style : null; \n    },\n    \n        destroy: function() {\n        if (this.layer) {\n            this.layer.removeFeatures(this);\n            this.layer = null;\n        }\n            \n        this.geometry = null;\n        this.modified = null;\n        OpenLayers.Feature.prototype.destroy.apply(this, arguments);\n    },\n    \n        clone: function () {\n        return new OpenLayers.Feature.Vector(\n            this.geometry ? this.geometry.clone() : null,\n            this.attributes,\n            this.style);\n    },\n\n        onScreen:function(boundsOnly) {\n        var onScreen = false;\n        if(this.layer && this.layer.map) {\n            var screenBounds = this.layer.map.getExtent();\n            if(boundsOnly) {\n                var featureBounds = this.geometry.getBounds();\n                onScreen = screenBounds.intersectsBounds(featureBounds);\n            } else {\n                var screenPoly = screenBounds.toGeometry();\n                onScreen = screenPoly.intersects(this.geometry);\n            }\n        }    \n        return onScreen;\n    },\n\n        getVisibility: function() {\n        return !(this.style && this.style.display == 'none' ||\n                 !this.layer ||\n                 this.layer && this.layer.styleMap &&\n                 this.layer.styleMap.createSymbolizer(this, this.renderIntent).display == 'none' ||\n                 this.layer && !this.layer.getVisibility());\n    },\n    \n        createMarker: function() {\n        return null;\n    },\n\n        destroyMarker: function() {\n    },\n\n        createPopup: function() {\n        return null;\n    },\n\n        atPoint: function(lonlat, toleranceLon, toleranceLat) {\n        var atPoint = false;\n        if(this.geometry) {\n            atPoint = this.geometry.atPoint(lonlat, toleranceLon, \n                                                    toleranceLat);\n        }\n        return atPoint;\n    },\n\n        destroyPopup: function() {\n    },\n\n        move: function(location) {\n\n        if(!this.layer || !this.geometry.move){\n            return undefined;\n        }\n\n        var pixel;\n        if (location.CLASS_NAME == \"OpenLayers.LonLat\") {\n            pixel = this.layer.getViewPortPxFromLonLat(location);\n        } else {\n            pixel = location;\n        }\n        \n        var lastPixel = this.layer.getViewPortPxFromLonLat(this.geometry.getBounds().getCenterLonLat());\n        var res = this.layer.map.getResolution();\n        this.geometry.move(res * (pixel.x - lastPixel.x),\n                           res * (lastPixel.y - pixel.y));\n        this.layer.drawFeature(this);\n        return lastPixel;\n    },\n    \n        toState: function(state) {\n        if (state == OpenLayers.State.UPDATE) {\n            switch (this.state) {\n                case OpenLayers.State.UNKNOWN:\n                case OpenLayers.State.DELETE:\n                    this.state = state;\n                    break;\n                case OpenLayers.State.UPDATE:\n                case OpenLayers.State.INSERT:\n                    break;\n            }\n        } else if (state == OpenLayers.State.INSERT) {\n            switch (this.state) {\n                case OpenLayers.State.UNKNOWN:\n                    break;\n                default:\n                    this.state = state;\n                    break;\n            }\n        } else if (state == OpenLayers.State.DELETE) {\n            switch (this.state) {\n                case OpenLayers.State.INSERT:\n                    break;\n                case OpenLayers.State.DELETE:\n                    break;\n                case OpenLayers.State.UNKNOWN:\n                case OpenLayers.State.UPDATE:\n                    this.state = state;\n                    break;\n            }\n        } else if (state == OpenLayers.State.UNKNOWN) {\n            this.state = state;\n        }\n    },\n    \n    CLASS_NAME: \"OpenLayers.Feature.Vector\"\n});\n\n\n/**\n * Constant: OpenLayers.Feature.Vector.style\n * OpenLayers features can have a number of style attributes. The 'default' \n *     style will typically be used if no other style is specified. These\n *     styles correspond for the most part, to the styling properties defined\n *     by the SVG standard. \n *     Information on fill properties: http://www.w3.org/TR/SVG/painting.html#FillProperties\n *     Information on stroke properties: http://www.w3.org/TR/SVG/painting.html#StrokeProperties\n *\n * Symbolizer properties:\n * fill - {Boolean} Set to false if no fill is desired.\n * fillColor - {String} Hex fill color.  Default is \"#ee9900\".\n * fillOpacity - {Number} Fill opacity (0-1).  Default is 0.4 \n * stroke - {Boolean} Set to false if no stroke is desired.\n * strokeColor - {String} Hex stroke color.  Default is \"#ee9900\".\n * strokeOpacity - {Number} Stroke opacity (0-1).  Default is 1.\n * strokeWidth - {Number} Pixel stroke width.  Default is 1.\n * strokeLinecap - {String} Stroke cap type.  Default is \"round\".  [butt | round | square]\n * strokeDashstyle - {String} Stroke dash style.  Default is \"solid\". [dot | dash | dashdot | longdash | longdashdot | solid]\n * graphic - {Boolean} Set to false if no graphic is desired.\n * pointRadius - {Number} Pixel point radius.  Default is 6.\n * pointerEvents - {String}  Default is \"visiblePainted\".\n * cursor - {String} Default is \"\".\n * externalGraphic - {String} Url to an external graphic that will be used for rendering points.\n * graphicWidth - {Number} Pixel width for sizing an external graphic.\n * graphicHeight - {Number} Pixel height for sizing an external graphic.\n * graphicOpacity - {Number} Opacity (0-1) for an external graphic.\n * graphicXOffset - {Number} Pixel offset along the positive x axis for displacing an external graphic.\n * graphicYOffset - {Number} Pixel offset along the positive y axis for displacing an external graphic.\n * rotation - {Number} For point symbolizers, this is the rotation of a graphic in the clockwise direction about its center point (or any point off center as specified by graphicXOffset and graphicYOffset).\n * graphicZIndex - {Number} The integer z-index value to use in rendering.\n * graphicName - {String} Named graphic to use when rendering points.  Supported values include \"circle\" (default),\n *     \"square\", \"star\", \"x\", \"cross\", \"triangle\".\n * graphicTitle - {String} Tooltip when hovering over a feature. *deprecated*, use title instead\n * title - {String} Tooltip when hovering over a feature. Not supported by the canvas renderer.\n * backgroundGraphic - {String} Url to a graphic to be used as the background under an externalGraphic.\n * backgroundGraphicZIndex - {Number} The integer z-index value to use in rendering the background graphic.\n * backgroundXOffset - {Number} The x offset (in pixels) for the background graphic.\n * backgroundYOffset - {Number} The y offset (in pixels) for the background graphic.\n * backgroundHeight - {Number} The height of the background graphic.  If not provided, the graphicHeight will be used.\n * backgroundWidth - {Number} The width of the background width.  If not provided, the graphicWidth will be used.\n * label - {String} The text for an optional label. For browsers that use the canvas renderer, this requires either\n *     fillText or mozDrawText to be available.\n * labelAlign - {String} Label alignment. This specifies the insertion point relative to the text. It is a string\n *     composed of two characters. The first character is for the horizontal alignment, the second for the vertical\n *     alignment. Valid values for horizontal alignment: \"l\"=left, \"c\"=center, \"r\"=right. Valid values for vertical\n *     alignment: \"t\"=top, \"m\"=middle, \"b\"=bottom. Example values: \"lt\", \"cm\", \"rb\". Default is \"cm\".\n * labelXOffset - {Number} Pixel offset along the positive x axis for displacing the label. Not supported by the canvas renderer.\n * labelYOffset - {Number} Pixel offset along the positive y axis for displacing the label. Not supported by the canvas renderer.\n * labelSelect - {Boolean} If set to true, labels will be selectable using SelectFeature or similar controls.\n *     Default is false.\n * labelOutlineColor - {String} The color of the label outline. Default is 'white'. Only supported by the canvas & SVG renderers.\n * labelOutlineWidth - {Number} The width of the label outline. Default is 3, set to 0 or null to disable. Only supported by the  SVG renderers.\n * labelOutlineOpacity - {Number} The opacity (0-1) of the label outline. Default is fontOpacity. Only supported by the canvas & SVG renderers.\n * fontColor - {String} The font color for the label, to be provided like CSS.\n * fontOpacity - {Number} Opacity (0-1) for the label\n * fontFamily - {String} The font family for the label, to be provided like in CSS.\n * fontSize - {String} The font size for the label, to be provided like in CSS.\n * fontStyle - {String} The font style for the label, to be provided like in CSS.\n * fontWeight - {String} The font weight for the label, to be provided like in CSS.\n * display - {String} Symbolizers will have no effect if display is set to \"none\".  All other values have no effect.\n */ \nOpenLayers.Feature.Vector.style = {\n    'default': {\n        fillColor: \"#ee9900\",\n        fillOpacity: 0.4, \n        hoverFillColor: \"white\",\n        hoverFillOpacity: 0.8,\n        strokeColor: \"#ee9900\",\n        strokeOpacity: 1,\n        strokeWidth: 1,\n        strokeLinecap: \"round\",\n        strokeDashstyle: \"solid\",\n        hoverStrokeColor: \"red\",\n        hoverStrokeOpacity: 1,\n        hoverStrokeWidth: 0.2,\n        pointRadius: 6,\n        hoverPointRadius: 1,\n        hoverPointUnit: \"%\",\n        pointerEvents: \"visiblePainted\",\n        cursor: \"inherit\",\n        fontColor: \"#000000\",\n        labelAlign: \"cm\",\n        labelOutlineColor: \"white\",\n        labelOutlineWidth: 3\n    },\n    'select': {\n        fillColor: \"blue\",\n        fillOpacity: 0.4, \n        hoverFillColor: \"white\",\n        hoverFillOpacity: 0.8,\n        strokeColor: \"blue\",\n        strokeOpacity: 1,\n        strokeWidth: 2,\n        strokeLinecap: \"round\",\n        strokeDashstyle: \"solid\",\n        hoverStrokeColor: \"red\",\n        hoverStrokeOpacity: 1,\n        hoverStrokeWidth: 0.2,\n        pointRadius: 6,\n        hoverPointRadius: 1,\n        hoverPointUnit: \"%\",\n        pointerEvents: \"visiblePainted\",\n        cursor: \"pointer\",\n        fontColor: \"#000000\",\n        labelAlign: \"cm\",\n        labelOutlineColor: \"white\",\n        labelOutlineWidth: 3\n\n    },\n    'temporary': {\n        fillColor: \"#66cccc\",\n        fillOpacity: 0.2, \n        hoverFillColor: \"white\",\n        hoverFillOpacity: 0.8,\n        strokeColor: \"#66cccc\",\n        strokeOpacity: 1,\n        strokeLinecap: \"round\",\n        strokeWidth: 2,\n        strokeDashstyle: \"solid\",\n        hoverStrokeColor: \"red\",\n        hoverStrokeOpacity: 1,\n        hoverStrokeWidth: 0.2,\n        pointRadius: 6,\n        hoverPointRadius: 1,\n        hoverPointUnit: \"%\",\n        pointerEvents: \"visiblePainted\",\n        cursor: \"inherit\",\n        fontColor: \"#000000\",\n        labelAlign: \"cm\",\n        labelOutlineColor: \"white\",\n        labelOutlineWidth: 3\n\n    },\n    'delete': {\n        display: \"none\"\n    }\n};    \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Feature.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Feature = OpenLayers.Class({\n\n        layer: null,\n\n        id: null,\n    \n        lonlat: null,\n\n        data: null,\n\n        marker: null,\n\n        popupClass: null,\n\n        popup: null,\n\n        initialize: function(layer, lonlat, data) {\n        this.layer = layer;\n        this.lonlat = lonlat;\n        this.data = (data != null) ? data : {};\n        this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + \"_\"); \n    },\n\n        destroy: function() {\n        if ((this.layer != null) && (this.layer.map != null)) {\n            if (this.popup != null) {\n                this.layer.map.removePopup(this.popup);\n            }\n        }\n        if (this.layer != null && this.marker != null) {\n            this.layer.removeMarker(this.marker);\n        }\n\n        this.layer = null;\n        this.id = null;\n        this.lonlat = null;\n        this.data = null;\n        if (this.marker != null) {\n            this.destroyMarker(this.marker);\n            this.marker = null;\n        }\n        if (this.popup != null) {\n            this.destroyPopup(this.popup);\n            this.popup = null;\n        }\n    },\n    \n        onScreen:function() {\n        \n        var onScreen = false;\n        if ((this.layer != null) && (this.layer.map != null)) {\n            var screenBounds = this.layer.map.getExtent();\n            onScreen = screenBounds.containsLonLat(this.lonlat);\n        }    \n        return onScreen;\n    },\n    \n\n        createMarker: function() {\n\n        if (this.lonlat != null) {\n            this.marker = new OpenLayers.Marker(this.lonlat, this.data.icon);\n        }\n        return this.marker;\n    },\n\n        destroyMarker: function() {\n        this.marker.destroy();  \n    },\n\n        createPopup: function(closeBox) {\n\n        if (this.lonlat != null) {\n            if (!this.popup) {\n                var anchor = (this.marker) ? this.marker.icon : null;\n                var popupClass = this.popupClass ? \n                    this.popupClass : OpenLayers.Popup.Anchored;\n                this.popup = new popupClass(this.id + \"_popup\", \n                                            this.lonlat,\n                                            this.data.popupSize,\n                                            this.data.popupContentHTML,\n                                            anchor, \n                                            closeBox); \n            }    \n            if (this.data.overflow != null) {\n                this.popup.contentDiv.style.overflow = this.data.overflow;\n            }    \n            \n            this.popup.feature = this;\n        }        \n        return this.popup;\n    },\n\n    \n        destroyPopup: function() {\n        if (this.popup) {\n            this.popup.feature = null;\n            this.popup.destroy();\n            this.popup = null;\n        }    \n    },\n\n    CLASS_NAME: \"OpenLayers.Feature\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Filter/Comparison.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Filter.Comparison = OpenLayers.Class(OpenLayers.Filter, {\n\n        type: null,\n    \n        property: null,\n    \n        value: null,\n    \n        matchCase: true,\n    \n        lowerBoundary: null,\n    \n        upperBoundary: null,\n\n        initialize: function(options) {\n        OpenLayers.Filter.prototype.initialize.apply(this, [options]);\n        if (this.type === OpenLayers.Filter.Comparison.LIKE \n            && options.matchCase === undefined) {\n                this.matchCase = null;\n        }\n    },\n\n        evaluate: function(context) {\n        if (context instanceof OpenLayers.Feature.Vector) {\n            context = context.attributes;\n        }\n        var result = false;\n        var got = context[this.property];\n        if (got === undefined) {\n            return false;\n        }\n        var exp;\n        switch(this.type) {\n            case OpenLayers.Filter.Comparison.EQUAL_TO:\n                exp = this.value;\n                if(!this.matchCase &&\n                   typeof got == \"string\" && typeof exp == \"string\") {\n                    result = (got.toUpperCase() == exp.toUpperCase());\n                } else {\n                    result = (got == exp);\n                }\n                break;\n            case OpenLayers.Filter.Comparison.NOT_EQUAL_TO:\n                exp = this.value;\n                if(!this.matchCase &&\n                   typeof got == \"string\" && typeof exp == \"string\") {\n                    result = (got.toUpperCase() != exp.toUpperCase());\n                } else {\n                    result = (got != exp);\n                }\n                break;\n            case OpenLayers.Filter.Comparison.LESS_THAN:\n                result = got < this.value;\n                break;\n            case OpenLayers.Filter.Comparison.GREATER_THAN:\n                result = got > this.value;\n                break;\n            case OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO:\n                result = got <= this.value;\n                break;\n            case OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO:\n                result = got >= this.value;\n                break;\n            case OpenLayers.Filter.Comparison.BETWEEN:\n                result = (got >= this.lowerBoundary) &&\n                    (got <= this.upperBoundary);\n                break;\n            case OpenLayers.Filter.Comparison.LIKE:\n                var regexp = new RegExp(this.value, \"gi\");\n                result = regexp.test(got);\n                break;\n            case OpenLayers.Filter.Comparison.IS_NULL:\n                result = (got === null);\n                break;\n        }\n        return result;\n    },\n    \n        value2regex: function(wildCard, singleChar, escapeChar) {\n        if (wildCard == \".\") {\n            throw new Error(\"'.' is an unsupported wildCard character for \" +\n                            \"OpenLayers.Filter.Comparison\");\n        }\n        wildCard = wildCard ? wildCard : \"*\";\n        singleChar = singleChar ? singleChar : \".\";\n        escapeChar = escapeChar ? escapeChar : \"!\";\n        \n        this.value = this.value.replace(\n                new RegExp(\"\\\\\"+escapeChar+\"(.|$)\", \"g\"), \"\\\\$1\");\n        this.value = this.value.replace(\n                new RegExp(\"\\\\\"+singleChar, \"g\"), \".\");\n        this.value = this.value.replace(\n                new RegExp(\"\\\\\"+wildCard, \"g\"), \".*\");\n        this.value = this.value.replace(\n                new RegExp(\"\\\\\\\\.\\\\*\", \"g\"), \"\\\\\"+wildCard);\n        this.value = this.value.replace(\n                new RegExp(\"\\\\\\\\\\\\.\", \"g\"), \"\\\\\"+singleChar);\n        \n        return this.value;\n    },\n    \n        regex2value: function() {\n        \n        var value = this.value;\n        value = value.replace(/!/g, \"!!\");\n        value = value.replace(/(\\\\)?\\\\\\./g, function($0, $1) {\n            return $1 ? $0 : \"!.\";\n        });\n        value = value.replace(/(\\\\)?\\\\\\*/g, function($0, $1) {\n            return $1 ? $0 : \"!*\";\n        });\n        value = value.replace(/\\\\\\\\/g, \"\\\\\");\n        value = value.replace(/\\.\\*/g, \"*\");\n        \n        return value;\n    },\n    \n        clone: function() {\n        return OpenLayers.Util.extend(new OpenLayers.Filter.Comparison(), this);\n    },\n    \n    CLASS_NAME: \"OpenLayers.Filter.Comparison\"\n});\n\n\nOpenLayers.Filter.Comparison.EQUAL_TO                 = \"==\";\nOpenLayers.Filter.Comparison.NOT_EQUAL_TO             = \"!=\";\nOpenLayers.Filter.Comparison.LESS_THAN                = \"<\";\nOpenLayers.Filter.Comparison.GREATER_THAN             = \">\";\nOpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO    = \"<=\";\nOpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO = \">=\";\nOpenLayers.Filter.Comparison.BETWEEN                  = \"..\";\nOpenLayers.Filter.Comparison.LIKE                     = \"~\";\nOpenLayers.Filter.Comparison.IS_NULL                  = \"NULL\";\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Filter/FeatureId.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Filter.FeatureId = OpenLayers.Class(OpenLayers.Filter, {\n\n        fids: null,\n    \n        type: \"FID\",\n    \n        initialize: function(options) {\n        this.fids = [];\n        OpenLayers.Filter.prototype.initialize.apply(this, [options]);\n    },\n\n        evaluate: function(feature) {\n        for (var i=0, len=this.fids.length; i<len; i++) {\n            var fid = feature.fid || feature.id;\n            if (fid == this.fids[i]) {\n                return true;\n            }\n        }\n        return false;\n    },\n    \n        clone: function() {\n        var filter = new OpenLayers.Filter.FeatureId();\n        OpenLayers.Util.extend(filter, this);\n        filter.fids = this.fids.slice();\n        return filter;\n    },\n    \n    CLASS_NAME: \"OpenLayers.Filter.FeatureId\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Filter/Function.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Filter.Function = OpenLayers.Class(OpenLayers.Filter, {\n\n        name: null,\n    \n        params: null,  \n    \n    \n    CLASS_NAME: \"OpenLayers.Filter.Function\"\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Filter/Logical.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Filter.Logical = OpenLayers.Class(OpenLayers.Filter, {\n\n        filters: null, \n     \n        type: null,\n\n        initialize: function(options) {\n        this.filters = [];\n        OpenLayers.Filter.prototype.initialize.apply(this, [options]);\n    },\n    \n        destroy: function() {\n        this.filters = null;\n        OpenLayers.Filter.prototype.destroy.apply(this);\n    },\n\n        evaluate: function(context) {\n        var i, len;\n        switch(this.type) {\n            case OpenLayers.Filter.Logical.AND:\n                for (i=0, len=this.filters.length; i<len; i++) {\n                    if (this.filters[i].evaluate(context) == false) {\n                        return false;\n                    }\n                }\n                return true;\n                \n            case OpenLayers.Filter.Logical.OR:\n                for (i=0, len=this.filters.length; i<len; i++) {\n                    if (this.filters[i].evaluate(context) == true) {\n                        return true;\n                    }\n                }\n                return false;\n            \n            case OpenLayers.Filter.Logical.NOT:\n                return (!this.filters[0].evaluate(context));\n        }\n        return undefined;\n    },\n    \n        clone: function() {\n        var filters = [];        \n        for(var i=0, len=this.filters.length; i<len; ++i) {\n            filters.push(this.filters[i].clone());\n        }\n        return new OpenLayers.Filter.Logical({\n            type: this.type,\n            filters: filters\n        });\n    },\n    \n    CLASS_NAME: \"OpenLayers.Filter.Logical\"\n});\n\n\nOpenLayers.Filter.Logical.AND = \"&&\";\nOpenLayers.Filter.Logical.OR  = \"||\";\nOpenLayers.Filter.Logical.NOT = \"!\";\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Filter/Spatial.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Filter.Spatial = OpenLayers.Class(OpenLayers.Filter, {\n\n        type: null,\n    \n        property: null,\n    \n        value: null,\n\n        distance: null,\n\n        distanceUnits: null,\n    \n    \n       evaluate: function(feature) {\n        var intersect = false;\n        switch(this.type) {\n            case OpenLayers.Filter.Spatial.BBOX:\n            case OpenLayers.Filter.Spatial.INTERSECTS:\n                if(feature.geometry) {\n                    var geom = this.value;\n                    if(this.value.CLASS_NAME == \"OpenLayers.Bounds\") {\n                        geom = this.value.toGeometry();\n                    }\n                    if(feature.geometry.intersects(geom)) {\n                        intersect = true;\n                    }\n                }\n                break;\n            default:\n                throw new Error('evaluate is not implemented for this filter type.');\n        }\n        return intersect;\n    },\n\n        clone: function() {\n        var options = OpenLayers.Util.applyDefaults({\n            value: this.value && this.value.clone && this.value.clone()\n        }, this);\n        return new OpenLayers.Filter.Spatial(options);\n    },\n    CLASS_NAME: \"OpenLayers.Filter.Spatial\"\n});\n\nOpenLayers.Filter.Spatial.BBOX = \"BBOX\";\nOpenLayers.Filter.Spatial.INTERSECTS = \"INTERSECTS\";\nOpenLayers.Filter.Spatial.DWITHIN = \"DWITHIN\";\nOpenLayers.Filter.Spatial.WITHIN = \"WITHIN\";\nOpenLayers.Filter.Spatial.CONTAINS = \"CONTAINS\";\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Filter.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Filter = OpenLayers.Class({\n    \n        initialize: function(options) {\n        OpenLayers.Util.extend(this, options);\n    },\n\n        destroy: function() {\n    },\n\n        evaluate: function(context) {\n        return true;\n    },\n    \n        clone: function() {\n        return null;\n    },\n    \n        toString: function() {\n        var string;\n        if (OpenLayers.Format && OpenLayers.Format.CQL) {\n            string = OpenLayers.Format.CQL.prototype.write(this);\n        } else {\n            string = Object.prototype.toString.call(this);\n        }\n        return string;\n    },\n    \n    CLASS_NAME: \"OpenLayers.Filter\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/ArcXML/Features.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.ArcXML.Features = OpenLayers.Class(OpenLayers.Format.XML, {\n\n        \n        read: function(data) {\n        var axl = new OpenLayers.Format.ArcXML();\n        var parsed = axl.read(data);\n        \n        return parsed.features.feature;\n    }\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/ArcXML.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.ArcXML = OpenLayers.Class(OpenLayers.Format.XML, {\n\n        fontStyleKeys: [\n        'antialiasing', 'blockout', 'font', 'fontcolor','fontsize', 'fontstyle',\n        'glowing', 'interval', 'outline', 'printmode', 'shadow', 'transparency'\n    ],\n\n        request: null,\n    \n        response: null,\n\n        initialize: function(options) {\n        this.request = new OpenLayers.Format.ArcXML.Request();\n        this.response = new OpenLayers.Format.ArcXML.Response();\n\n        if (options) {\n            if (options.requesttype == \"feature\") {\n                this.request.get_image = null;\n            \n                var qry = this.request.get_feature.query;\n                this.addCoordSys(qry.featurecoordsys, options.featureCoordSys);\n                this.addCoordSys(qry.filtercoordsys, options.filterCoordSys);\n            \n                if (options.polygon) {\n                    qry.isspatial = true;\n                    qry.spatialfilter.polygon = options.polygon;\n                } else if (options.envelope) {\n                    qry.isspatial = true;\n                    qry.spatialfilter.envelope = {minx:0, miny:0, maxx:0, maxy:0};\n                    this.parseEnvelope(qry.spatialfilter.envelope, options.envelope);\n                }\n            } else if (options.requesttype == \"image\") {\n                this.request.get_feature = null;\n            \n                var props = this.request.get_image.properties;\n                this.parseEnvelope(props.envelope, options.envelope);\n            \n                this.addLayers(props.layerlist, options.layers);\n                this.addImageSize(props.imagesize, options.tileSize);\n                this.addCoordSys(props.featurecoordsys, options.featureCoordSys);\n                this.addCoordSys(props.filtercoordsys, options.filterCoordSys);\n            } else {\n                this.request = null;\n            }\n        }\n        \n        OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);\n    },\n    \n        parseEnvelope: function(env, arr) {\n        if (arr && arr.length == 4) {          \n            env.minx = arr[0];\n            env.miny = arr[1];\n            env.maxx = arr[2];\n            env.maxy = arr[3];\n        }\n    },\n    \n        addLayers: function(ll, lyrs) {\n        for(var lind = 0, len=lyrs.length; lind < len; lind++) {\n            ll.push(lyrs[lind]);\n        }\n    },\n    \n        addImageSize: function(imsize, olsize) {\n        if (olsize !== null) {\n            imsize.width = olsize.w;\n            imsize.height = olsize.h;\n            imsize.printwidth = olsize.w;\n            imsize.printheight = olsize.h;\n        }\n    },\n\n        addCoordSys: function(featOrFilt, fsys) {\n        if (typeof fsys == \"string\") {\n            featOrFilt.id = parseInt(fsys);\n            featOrFilt.string = fsys;\n        }\n        else if (typeof fsys == \"object\" && fsys.proj !== null){\n            featOrFilt.id = fsys.proj.srsProjNumber;\n            featOrFilt.string = fsys.proj.srsCode;\n        } else {\n            featOrFilt = fsys;\n        }\n    },\n\n        iserror: function(data) {\n        var ret = null; \n        \n        if (!data) {\n            ret = (this.response.error !== '');\n        } else {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n            var errorNodes = data.documentElement.getElementsByTagName(\"ERROR\");\n            ret = (errorNodes !== null && errorNodes.length > 0);\n        }\n\n        return ret;\n    },\n\n        read: function(data) {\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        \n        var arcNode = null;\n        if (data && data.documentElement) {\n            if(data.documentElement.nodeName == \"ARCXML\") {\n                arcNode = data.documentElement;\n            } else {\n                arcNode = data.documentElement.getElementsByTagName(\"ARCXML\")[0];\n            }\n        }\n        if (!arcNode || arcNode.firstChild.nodeName === 'parsererror') {\n            var error, source;\n            try {\n                error = data.firstChild.nodeValue;\n                source = data.firstChild.childNodes[1].firstChild.nodeValue;\n            } catch (err) {\n            }\n            throw {\n                message: \"Error parsing the ArcXML request\", \n                error: error,\n                source: source\n            };\n        }\n        \n        var response = this.parseResponse(arcNode);\n        return response;\n    },\n    \n        write: function(request) {       \n        if (!request) {\n            request = this.request;\n        }    \n        var root = this.createElementNS(\"\", \"ARCXML\");\n        root.setAttribute(\"version\",\"1.1\");\n\n        var reqElem = this.createElementNS(\"\", \"REQUEST\");\n        \n        if (request.get_image != null) {\n            var getElem = this.createElementNS(\"\", \"GET_IMAGE\");\n            reqElem.appendChild(getElem);\n\n            var propElem = this.createElementNS(\"\", \"PROPERTIES\");\n            getElem.appendChild(propElem);\n\n            var props = request.get_image.properties;\n            if (props.featurecoordsys != null) {\n                var feat = this.createElementNS(\"\", \"FEATURECOORDSYS\");\n                propElem.appendChild(feat);\n                \n                if (props.featurecoordsys.id === 0) {\n                    feat.setAttribute(\"string\", props.featurecoordsys['string']);\n                }\n                else {\n                    feat.setAttribute(\"id\", props.featurecoordsys.id);\n                }\n            }\n          \n            if (props.filtercoordsys != null) {\n                var filt = this.createElementNS(\"\", \"FILTERCOORDSYS\");\n                propElem.appendChild(filt);\n\n                if (props.filtercoordsys.id === 0) {\n                    filt.setAttribute(\"string\", props.filtercoordsys.string);\n                }\n                else {\n                    filt.setAttribute(\"id\", props.filtercoordsys.id);\n                }\n            }\n          \n            if (props.envelope != null) {\n                var env = this.createElementNS(\"\", \"ENVELOPE\");\n                propElem.appendChild(env);\n\n                env.setAttribute(\"minx\", props.envelope.minx);\n                env.setAttribute(\"miny\", props.envelope.miny);\n                env.setAttribute(\"maxx\", props.envelope.maxx);\n                env.setAttribute(\"maxy\", props.envelope.maxy);\n            }        \n          \n            var imagesz = this.createElementNS(\"\", \"IMAGESIZE\");\n            propElem.appendChild(imagesz);\n          \n            imagesz.setAttribute(\"height\", props.imagesize.height);\n            imagesz.setAttribute(\"width\", props.imagesize.width);\n          \n            if (props.imagesize.height != props.imagesize.printheight ||\n                 props.imagesize.width != props.imagesize.printwidth) {\n                imagesz.setAttribute(\"printheight\", props.imagesize.printheight);\n                imagesz.setArrtibute(\"printwidth\", props.imagesize.printwidth);\n            }\n          \n            if (props.background != null) {\n                var backgrnd = this.createElementNS(\"\", \"BACKGROUND\");\n                propElem.appendChild(backgrnd);\n            \n                backgrnd.setAttribute(\"color\", \n                    props.background.color.r + \",\" + \n                    props.background.color.g + \",\" + \n                    props.background.color.b);\n              \n                if (props.background.transcolor !== null) {\n                    backgrnd.setAttribute(\"transcolor\", \n                        props.background.transcolor.r + \",\" + \n                        props.background.transcolor.g + \",\" + \n                        props.background.transcolor.b);\n                }\n            }\n          \n            if (props.layerlist != null && props.layerlist.length > 0) {\n                var layerlst = this.createElementNS(\"\", \"LAYERLIST\");\n                propElem.appendChild(layerlst);\n            \n                for (var ld = 0; ld < props.layerlist.length; ld++) {\n                    var ldef = this.createElementNS(\"\", \"LAYERDEF\");\n                    layerlst.appendChild(ldef);\n              \n                    ldef.setAttribute(\"id\", props.layerlist[ld].id);\n                    ldef.setAttribute(\"visible\", props.layerlist[ld].visible);\n              \n                    if (typeof props.layerlist[ld].query == \"object\") {\n                        var query = props.layerlist[ld].query;\n\n                        if (query.where.length < 0) {\n                            continue;\n                        }\n                  \n                        var queryElem = null;\n                        if (typeof query.spatialfilter == \"boolean\" && query.spatialfilter) {\n                            queryElem = this.createElementNS(\"\", \"SPATIALQUERY\");\n                        }\n                        else {\n                            queryElem = this.createElementNS(\"\", \"QUERY\");\n                        }\n                \n                        queryElem.setAttribute(\"where\", query.where);\n                \n                        if (typeof query.accuracy == \"number\" && query.accuracy > 0) {\n                            queryElem.setAttribute(\"accuracy\", query.accuracy);\n                        }\n                        if (typeof query.featurelimit == \"number\" && query.featurelimit < 2000) {\n                            queryElem.setAttribute(\"featurelimit\", query.featurelimit);\n                        }\n                        if (typeof query.subfields == \"string\" && query.subfields != \"#ALL#\") {\n                            queryElem.setAttribute(\"subfields\", query.subfields);\n                        }\n                        if (typeof query.joinexpression == \"string\" && query.joinexpression.length > 0) {\n                            queryElem.setAttribute(\"joinexpression\", query.joinexpression);\n                        }\n                        if (typeof query.jointables == \"string\" && query.jointables.length > 0) {\n                            queryElem.setAttribute(\"jointables\", query.jointables);\n                        }\n\n                        ldef.appendChild(queryElem);\n                    }\n              \n                    if (typeof props.layerlist[ld].renderer == \"object\") {\n                        this.addRenderer(ldef, props.layerlist[ld].renderer);                  \n                    }\n                }\n            }\n        } else if (request.get_feature != null) {\n            var getElem = this.createElementNS(\"\", \"GET_FEATURES\");\n            getElem.setAttribute(\"outputmode\", \"newxml\");\n            getElem.setAttribute(\"checkesc\", \"true\");\n          \n            if (request.get_feature.geometry) {\n                getElem.setAttribute(\"geometry\", request.get_feature.geometry);\n            }\n            else {\n                getElem.setAttribute(\"geometry\", \"false\");\n            }\n          \n            if (request.get_feature.compact) {\n                getElem.setAttribute(\"compact\", request.get_feature.compact);\n            }\n          \n            if (request.get_feature.featurelimit == \"number\") {\n                getElem.setAttribute(\"featurelimit\", request.get_feature.featurelimit);\n            }\n          \n            getElem.setAttribute(\"globalenvelope\", \"true\");\n            reqElem.appendChild(getElem);\n          \n            if (request.get_feature.layer != null && request.get_feature.layer.length > 0) {\n                var lyrElem = this.createElementNS(\"\", \"LAYER\");\n                lyrElem.setAttribute(\"id\", request.get_feature.layer);\n                getElem.appendChild(lyrElem);\n            }\n          \n            var fquery = request.get_feature.query;\n            if (fquery != null) {\n                var qElem = null;\n                if (fquery.isspatial) {\n                    qElem = this.createElementNS(\"\", \"SPATIALQUERY\");\n                } else {\n                    qElem = this.createElementNS(\"\", \"QUERY\");\n                }\n                getElem.appendChild(qElem);\n                \n                if (typeof fquery.accuracy == \"number\") {\n                    qElem.setAttribute(\"accuracy\", fquery.accuracy);\n                }\n            \n                if (fquery.featurecoordsys != null) {\n                    var fcsElem1 = this.createElementNS(\"\", \"FEATURECOORDSYS\");\n              \n                    if (fquery.featurecoordsys.id == 0) {\n                        fcsElem1.setAttribute(\"string\", fquery.featurecoordsys.string);\n                    } else {\n                        fcsElem1.setAttribute(\"id\", fquery.featurecoordsys.id);\n                    }\n                    qElem.appendChild(fcsElem1);\n                }\n            \n                if (fquery.filtercoordsys != null) {\n                    var fcsElem2 = this.createElementNS(\"\", \"FILTERCOORDSYS\");\n              \n                    if (fquery.filtercoordsys.id === 0) {\n                        fcsElem2.setAttribute(\"string\", fquery.filtercoordsys.string);\n                    } else {\n                        fcsElem2.setAttribute(\"id\", fquery.filtercoordsys.id);\n                    }\n                    qElem.appendChild(fcsElem2);\n                }\n            \n                if (fquery.buffer > 0) {   \n                    var bufElem = this.createElementNS(\"\", \"BUFFER\");\n                    bufElem.setAttribute(\"distance\", fquery.buffer);\n                    qElem.appendChild(bufElem);\n                }\n            \n                if (fquery.isspatial) {\n                    var spfElem = this.createElementNS(\"\", \"SPATIALFILTER\");\n                    spfElem.setAttribute(\"relation\", fquery.spatialfilter.relation);\n                    qElem.appendChild(spfElem);\n              \n                    if (fquery.spatialfilter.envelope) {\n                        var envElem = this.createElementNS(\"\", \"ENVELOPE\"); \n                        envElem.setAttribute(\"minx\", fquery.spatialfilter.envelope.minx);\n                        envElem.setAttribute(\"miny\", fquery.spatialfilter.envelope.miny);\n                        envElem.setAttribute(\"maxx\", fquery.spatialfilter.envelope.maxx);\n                        envElem.setAttribute(\"maxy\", fquery.spatialfilter.envelope.maxy);\n                        spfElem.appendChild(envElem);\n                    } else if(typeof fquery.spatialfilter.polygon == \"object\") {\n                        spfElem.appendChild(this.writePolygonGeometry(fquery.spatialfilter.polygon));                \n                    }\n                }\n            \n                if (fquery.where != null && fquery.where.length > 0) {\n                    qElem.setAttribute(\"where\", fquery.where);\n                }\n            }\n        }\n\n        root.appendChild(reqElem);\n\n        return OpenLayers.Format.XML.prototype.write.apply(this, [root]);\n    },\n    \n    \n    addGroupRenderer: function(ldef, toprenderer) {\n        var topRelem = this.createElementNS(\"\", \"GROUPRENDERER\");\n        ldef.appendChild(topRelem);\n      \n        for (var rind = 0; rind < toprenderer.length; rind++) {\n            var renderer = toprenderer[rind];\n            this.addRenderer(topRelem, renderer);\n        }\n    },\n    \n    \n    addRenderer: function(topRelem, renderer) {\n        if (OpenLayers.Util.isArray(renderer)) {\n            this.addGroupRenderer(topRelem, renderer);\n        } else {\n            var renderElem = this.createElementNS(\"\", renderer.type.toUpperCase() + \"RENDERER\");\n            topRelem.appendChild(renderElem);\n          \n            if (renderElem.tagName == \"VALUEMAPRENDERER\") {\n                this.addValueMapRenderer(renderElem, renderer);\n            } else if (renderElem.tagName == \"VALUEMAPLABELRENDERER\") {\n                this.addValueMapLabelRenderer(renderElem, renderer);\n            } else if (renderElem.tagName == \"SIMPLELABELRENDERER\") {\n                this.addSimpleLabelRenderer(renderElem, renderer);\n            } else if (renderElem.tagName == \"SCALEDEPENDENTRENDERER\") {\n                this.addScaleDependentRenderer(renderElem, renderer);\n            }\n        }             \n    },\n    \n    \n    addScaleDependentRenderer: function(renderElem, renderer) {\n        if (typeof renderer.lower == \"string\" || typeof renderer.lower == \"number\") {\n            renderElem.setAttribute(\"lower\", renderer.lower);\n        }\n        if (typeof renderer.upper == \"string\" || typeof renderer.upper == \"number\") {\n            renderElem.setAttribute(\"upper\", renderer.upper);\n        }\n        \n        this.addRenderer(renderElem, renderer.renderer);\n    },\n    \n    \n    addValueMapLabelRenderer: function(renderElem, renderer) {\n        renderElem.setAttribute(\"lookupfield\", renderer.lookupfield);\n        renderElem.setAttribute(\"labelfield\", renderer.labelfield);\n      \n        if (typeof renderer.exacts == \"object\") {\n            for (var ext=0, extlen=renderer.exacts.length; ext<extlen; ext++) {\n                var exact = renderer.exacts[ext];\n          \n                var eelem = this.createElementNS(\"\", \"EXACT\");\n          \n                if (typeof exact.value == \"string\") {\n                    eelem.setAttribute(\"value\", exact.value);\n                }\n                if (typeof exact.label == \"string\") {\n                    eelem.setAttribute(\"label\", exact.label);\n                }\n                if (typeof exact.method == \"string\") {\n                    eelem.setAttribute(\"method\", exact.method);\n                }\n\n                renderElem.appendChild(eelem);\n            \n                if (typeof exact.symbol == \"object\") {\n                    var selem = null;\n                \n                    if (exact.symbol.type == \"text\") {\n                        selem = this.createElementNS(\"\", \"TEXTSYMBOL\");\n                    }\n                \n                    if (selem != null) {\n                        var keys = this.fontStyleKeys;\n                        for (var i = 0, len = keys.length; i < len; i++) {\n                            var key = keys[i];\n                            if (exact.symbol[key]) {\n                                selem.setAttribute(key, exact.symbol[key]);\n                            }\n                        }    \n                        eelem.appendChild(selem);\n                    }\n                }\n            } // for each exact\n        }      \n    },\n    \n    addValueMapRenderer: function(renderElem, renderer) {\n        renderElem.setAttribute(\"lookupfield\", renderer.lookupfield);\n        \n        if (typeof renderer.ranges == \"object\") {\n            for(var rng=0, rnglen=renderer.ranges.length; rng<rnglen; rng++) {\n                var range = renderer.ranges[rng];\n                \n                var relem = this.createElementNS(\"\", \"RANGE\");\n                relem.setAttribute(\"lower\", range.lower);\n                relem.setAttribute(\"upper\", range.upper);\n                \n                renderElem.appendChild(relem);\n                \n                if (typeof range.symbol == \"object\") {\n                    var selem = null;\n              \n                    if (range.symbol.type == \"simplepolygon\") {\n                        selem = this.createElementNS(\"\", \"SIMPLEPOLYGONSYMBOL\");\n                    }\n              \n                    if (selem != null) {\n                        if (typeof range.symbol.boundarycolor == \"string\") {\n                            selem.setAttribute(\"boundarycolor\", range.symbol.boundarycolor);\n                        }\n                        if (typeof range.symbol.fillcolor == \"string\") {\n                            selem.setAttribute(\"fillcolor\", range.symbol.fillcolor);\n                        }\n                        if (typeof range.symbol.filltransparency == \"number\") {\n                            selem.setAttribute(\"filltransparency\", range.symbol.filltransparency);\n                        }\n                        relem.appendChild(selem);\n                    }   \n                }\n            } // for each range\n        } else if (typeof renderer.exacts == \"object\") {\n            for (var ext=0, extlen=renderer.exacts.length; ext<extlen; ext++) {\n                var exact = renderer.exacts[ext];\n          \n                var eelem = this.createElementNS(\"\", \"EXACT\");\n                if (typeof exact.value == \"string\") {\n                    eelem.setAttribute(\"value\", exact.value);\n                }\n                if (typeof exact.label == \"string\") {\n                    eelem.setAttribute(\"label\", exact.label);\n                }\n                if (typeof exact.method == \"string\") {\n                    eelem.setAttribute(\"method\", exact.method);\n                }\n            \n                renderElem.appendChild(eelem);\n            \n                if (typeof exact.symbol == \"object\") {\n                    var selem = null;\n            \n                    if (exact.symbol.type == \"simplemarker\") {\n                        selem = this.createElementNS(\"\", \"SIMPLEMARKERSYMBOL\");\n                    }\n            \n                    if (selem != null) {\n                        if (typeof exact.symbol.antialiasing == \"string\") {\n                            selem.setAttribute(\"antialiasing\", exact.symbol.antialiasing);\n                        }\n                        if (typeof exact.symbol.color == \"string\") {\n                            selem.setAttribute(\"color\", exact.symbol.color);\n                        }\n                        if (typeof exact.symbol.outline == \"string\") {\n                            selem.setAttribute(\"outline\", exact.symbol.outline);\n                        }\n                        if (typeof exact.symbol.overlap == \"string\") {\n                            selem.setAttribute(\"overlap\", exact.symbol.overlap);\n                        }\n                        if (typeof exact.symbol.shadow == \"string\") {\n                            selem.setAttribute(\"shadow\", exact.symbol.shadow);\n                        }\n                        if (typeof exact.symbol.transparency == \"number\") {\n                            selem.setAttribute(\"transparency\", exact.symbol.transparency);\n                        }\n                        if (typeof exact.symbol.usecentroid == \"string\") {\n                            selem.setAttribute(\"usecentroid\", exact.symbol.usecentroid);\n                        }\n                        if (typeof exact.symbol.width == \"number\") {\n                            selem.setAttribute(\"width\", exact.symbol.width);\n                        }\n                \n                        eelem.appendChild(selem);\n                    }\n                }\n            } // for each exact\n        }\n    },\n    \n    \n    addSimpleLabelRenderer: function(renderElem, renderer) {\n        renderElem.setAttribute(\"field\", renderer.field);\n        var keys = ['featureweight', 'howmanylabels', 'labelbufferratio', \n                    'labelpriorities', 'labelweight', 'linelabelposition',\n                    'rotationalangles'];\n        for (var i=0, len=keys.length; i<len; i++) {\n            var key = keys[i];\n            if (renderer[key]) {\n                renderElem.setAttribute(key, renderer[key]);\n            }\n        }     \n           \n        if (renderer.symbol.type == \"text\") {\n            var symbol = renderer.symbol;\n            var selem = this.createElementNS(\"\", \"TEXTSYMBOL\");\n            renderElem.appendChild(selem);\n          \n            var keys = this.fontStyleKeys;\n            for (var i=0, len=keys.length; i<len; i++) {\n                var key = keys[i];\n                if (symbol[key]) {\n                    selem.setAttribute(key, renderer[key]);\n                }\n            }    \n        }    \n    },\n    \n    writePolygonGeometry: function(polygon) {\n        if (!(polygon instanceof OpenLayers.Geometry.Polygon)) {\n            throw { \n                message:'Cannot write polygon geometry to ArcXML with an ' +\n                    polygon.CLASS_NAME + ' object.',\n                geometry: polygon\n            };\n        }\n        \n        var polyElem = this.createElementNS(\"\", \"POLYGON\");\n      \n        for (var ln=0, lnlen=polygon.components.length; ln<lnlen; ln++) {\n            var ring = polygon.components[ln];\n            var ringElem = this.createElementNS(\"\", \"RING\");\n        \n            for (var rn=0, rnlen=ring.components.length; rn<rnlen; rn++) {\n                var point = ring.components[rn];\n                var pointElem = this.createElementNS(\"\", \"POINT\");\n            \n                pointElem.setAttribute(\"x\", point.x);\n                pointElem.setAttribute(\"y\", point.y);\n            \n                ringElem.appendChild(pointElem);\n            }\n        \n            polyElem.appendChild(ringElem);\n        }\n      \n        return polyElem;\n    },\n    \n        parseResponse: function(data) {\n        if(typeof data == \"string\") { \n            var newData = new OpenLayers.Format.XML();\n            data = newData.read(data);\n        }\n        var response = new OpenLayers.Format.ArcXML.Response();\n        \n        var errorNode = data.getElementsByTagName(\"ERROR\");\n        \n        if (errorNode != null && errorNode.length > 0) {\n            response.error = this.getChildValue(errorNode, \"Unknown error.\");\n        } else {\n            var responseNode = data.getElementsByTagName(\"RESPONSE\");\n          \n            if (responseNode == null || responseNode.length == 0) {\n                response.error = \"No RESPONSE tag found in ArcXML response.\";\n                return response;\n            }\n          \n            var rtype = responseNode[0].firstChild.nodeName;\n            if (rtype == \"#text\") {\n                rtype = responseNode[0].firstChild.nextSibling.nodeName;\n            }\n          \n            if (rtype == \"IMAGE\") {\n                var envelopeNode = data.getElementsByTagName(\"ENVELOPE\");\n                var outputNode = data.getElementsByTagName(\"OUTPUT\");\n                \n                if (envelopeNode == null || envelopeNode.length == 0) {\n                    response.error = \"No ENVELOPE tag found in ArcXML response.\";\n                } else if (outputNode == null || outputNode.length == 0) {\n                    response.error = \"No OUTPUT tag found in ArcXML response.\";\n                } else {\n                    var envAttr = this.parseAttributes(envelopeNode[0]);            \n                    var outputAttr = this.parseAttributes(outputNode[0]);\n                  \n                    if (typeof outputAttr.type == \"string\") {\n                        response.image = { \n                            envelope: envAttr, \n                            output: { \n                                type: outputAttr.type, \n                                data: this.getChildValue(outputNode[0])\n                            }\n                        };\n                    } else {\n                        response.image = { envelope: envAttr, output: outputAttr };\n                    }\n                }\n            } else if (rtype == \"FEATURES\") {\n                var features = responseNode[0].getElementsByTagName(\"FEATURES\");\n                var featureCount = features[0].getElementsByTagName(\"FEATURECOUNT\");\n                response.features.featurecount = featureCount[0].getAttribute(\"count\");\n            \n                if (response.features.featurecount > 0) {\n                    var envelope = features[0].getElementsByTagName(\"ENVELOPE\");\n                    response.features.envelope = this.parseAttributes(envelope[0], typeof(0));\n                    var featureList = features[0].getElementsByTagName(\"FEATURE\");\n                    for (var fn = 0; fn < featureList.length; fn++) {\n                        var feature = new OpenLayers.Feature.Vector();\n                        var fields = featureList[fn].getElementsByTagName(\"FIELD\");\n\n                        for (var fdn = 0; fdn < fields.length; fdn++) {\n                            var fieldName = fields[fdn].getAttribute(\"name\");\n                            var fieldValue = fields[fdn].getAttribute(\"value\");\n                            feature.attributes[ fieldName ] = fieldValue;\n                        }\n\n                        var geom = featureList[fn].getElementsByTagName(\"POLYGON\");\n\n                        if (geom.length > 0) {\n                            var ring = geom[0].getElementsByTagName(\"RING\");\n\n                            var polys = [];\n                            for (var rn = 0; rn < ring.length; rn++) {\n                                var linearRings = [];\n                                linearRings.push(this.parsePointGeometry(ring[rn]));\n\n                                var holes = ring[rn].getElementsByTagName(\"HOLE\");\n                                for (var hn = 0; hn < holes.length; hn++) {\n                                    linearRings.push(this.parsePointGeometry(holes[hn]));\n                                }\n                                holes = null;\n                                polys.push(new OpenLayers.Geometry.Polygon(linearRings));\n                                linearRings = null;\n                            }\n                            ring = null;\n                          \n                            if (polys.length == 1) {\n                                feature.geometry = polys[0];\n                            } else\n                            {\n                                feature.geometry = new OpenLayers.Geometry.MultiPolygon(polys);\n                            }\n                        }\n\n                        response.features.feature.push(feature);\n                    }\n                }\n            } else {\n                response.error = \"Unidentified response type.\";\n            }\n        }\n        return response;\n    },\n    \n    \n        parseAttributes: function(node,type) {\n        var attributes = {};\n        for(var attr = 0; attr < node.attributes.length; attr++) {\n            if (type == \"number\") {\n                attributes[node.attributes[attr].nodeName] = parseFloat(node.attributes[attr].nodeValue);\n            } else {\n                attributes[node.attributes[attr].nodeName] = node.attributes[attr].nodeValue;\n            }\n        }\n        return attributes;\n    },\n    \n    \n        parsePointGeometry: function(node) {\n        var ringPoints = [];\n        var coords = node.getElementsByTagName(\"COORDS\");\n\n        if (coords.length > 0) {\n            var coordArr = this.getChildValue(coords[0]);\n            coordArr = coordArr.split(/;/);\n            for (var cn = 0; cn < coordArr.length; cn++) {\n                var coordItems = coordArr[cn].split(/ /);\n                ringPoints.push(new OpenLayers.Geometry.Point(coordItems[0], coordItems[1]));\n            }\n            coords = null;\n        } else {\n            var point = node.getElementsByTagName(\"POINT\");\n            if (point.length > 0) {\n                for (var pn = 0; pn < point.length; pn++) {\n                    ringPoints.push(\n                        new OpenLayers.Geometry.Point(\n                            parseFloat(point[pn].getAttribute(\"x\")),\n                            parseFloat(point[pn].getAttribute(\"y\"))\n                        )\n                    );\n                }\n            }\n            point = null;\n        }\n\n        return new OpenLayers.Geometry.LinearRing(ringPoints);      \n    },\n    \n    CLASS_NAME: \"OpenLayers.Format.ArcXML\" \n});\n\nOpenLayers.Format.ArcXML.Request = OpenLayers.Class({\n    initialize: function(params) {\n        var defaults = {\n            get_image: {\n                properties: {\n                    background: null,\n                    /*{ \n                        color: { r:255, g:255, b:255 },\n                        transcolor: null\n                    },*/\n                    draw: true,\n                    envelope: {\n                        minx: 0, \n                        miny: 0, \n                        maxx: 0, \n                        maxy: 0\n                    },\n                    featurecoordsys: { \n                        id:0, \n                        string:\"\",\n                        datumtransformid:0,\n                        datumtransformstring:\"\"\n                    },\n                    filtercoordsys:{\n                        id:0,\n                        string:\"\",\n                        datumtransformid:0,\n                        datumtransformstring:\"\"\n                    },\n                    imagesize:{\n                        height:0,\n                        width:0,\n                        dpi:96,\n                        printheight:0,\n                        printwidth:0,\n                        scalesymbols:false\n                    },\n                    layerlist:[],\n                    /* no support for legends */\n                    output:{\n                        baseurl:\"\",\n                        legendbaseurl:\"\",\n                        legendname:\"\",\n                        legendpath:\"\",\n                        legendurl:\"\",\n                        name:\"\",\n                        path:\"\",\n                        type:\"jpg\",\n                        url:\"\"\n                    }\n                }\n            },\n\n            get_feature: {\n                layer: \"\",\n                query: {\n                    isspatial: false,\n                    featurecoordsys: {\n                        id:0,\n                        string:\"\",\n                        datumtransformid:0,\n                        datumtransformstring:\"\"\n                    },\n                    filtercoordsys: {\n                        id:0,\n                        string:\"\",\n                        datumtransformid:0,\n                        datumtransformstring:\"\"\n                    },\n                    buffer:0,\n                    where:\"\",\n                    spatialfilter: {\n                        relation: \"envelope_intersection\",\n                        envelope: null\n                    }\n                }\n            },\n      \n            environment: {\n                separators: {\n                    cs:\" \",\n                    ts:\";\"\n                }\n            },\n      \n            layer: [],\n            workspaces: []\n        };\n      \n        return OpenLayers.Util.extend(this, defaults);      \n    },\n  \n    CLASS_NAME: \"OpenLayers.Format.ArcXML.Request\"\n});\n\nOpenLayers.Format.ArcXML.Response = OpenLayers.Class({  \n    initialize: function(params) {\n        var defaults = {\n            image: {\n                envelope:null,\n                output:''\n            },\n      \n            features: {\n                featurecount: 0,\n                envelope: null,\n                feature: []\n            },\n      \n            error:''\n        };\n  \n        return OpenLayers.Util.extend(this, defaults);\n    },\n  \n    CLASS_NAME: \"OpenLayers.Format.ArcXML.Response\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/Atom.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.Atom = OpenLayers.Class(OpenLayers.Format.XML, {\n    \n        namespaces: {\n        atom: \"http://www.w3.org/2005/Atom\",\n        georss: \"http://www.georss.org/georss\"\n    },\n    \n        feedTitle: \"untitled\",\n\n        defaultEntryTitle: \"untitled\",\n\n        gmlParser: null,\n    \n        xy: false,\n    \n        \n        read: function(doc) {\n        if (typeof doc == \"string\") {\n            doc = OpenLayers.Format.XML.prototype.read.apply(this, [doc]);\n        }\n        return this.parseFeatures(doc);\n    },\n    \n        write: function(features) {\n        var doc;\n        if (OpenLayers.Util.isArray(features)) {\n            doc = this.createElementNSPlus(\"atom:feed\");\n            doc.appendChild(\n                this.createElementNSPlus(\"atom:title\", {\n                    value: this.feedTitle\n                })\n            );\n            for (var i=0, ii=features.length; i<ii; i++) {\n                doc.appendChild(this.buildEntryNode(features[i]));\n            }\n        }\n        else {\n            doc = this.buildEntryNode(features);\n        }\n        return OpenLayers.Format.XML.prototype.write.apply(this, [doc]);\n    },\n    \n        buildContentNode: function(content) {\n        var node = this.createElementNSPlus(\"atom:content\", {\n            attributes: {\n                type: content.type || null\n            }\n        });\n        if (content.src) {\n            node.setAttribute(\"src\", content.src);\n        } else {\n            if (content.type == \"text\" || content.type == null) {\n                node.appendChild(\n                    this.createTextNode(content.value)\n                );\n            } else if (content.type == \"html\") {\n                if (typeof content.value != \"string\") {\n                    throw \"HTML content must be in form of an escaped string\";\n                }\n                node.appendChild(\n                    this.createTextNode(content.value)\n                );\n            } else if (content.type == \"xhtml\") {\n                node.appendChild(content.value);\n            } else if (content.type == \"xhtml\" ||\n                           content.type.match(/(\\+|\\/)xml$/)) {\n                node.appendChild(content.value);\n            }\n            else { // MUST be a valid Base64 encoding\n                node.appendChild(\n                    this.createTextNode(content.value)\n                );\n            }\n        }\n        return node;\n    },\n    \n        buildEntryNode: function(feature) {\n        var attrib = feature.attributes;\n        var atomAttrib = attrib.atom || {};\n        var entryNode = this.createElementNSPlus(\"atom:entry\");\n        if (atomAttrib.authors) {\n            var authors = OpenLayers.Util.isArray(atomAttrib.authors) ?\n                atomAttrib.authors : [atomAttrib.authors];\n            for (var i=0, ii=authors.length; i<ii; i++) {\n                entryNode.appendChild(\n                    this.buildPersonConstructNode(\n                        \"author\", authors[i]\n                    )\n                );\n            }\n        }\n        if (atomAttrib.categories) {\n            var categories = OpenLayers.Util.isArray(atomAttrib.categories) ?\n                atomAttrib.categories : [atomAttrib.categories];\n            var category;\n            for (var i=0, ii=categories.length; i<ii; i++) {\n                category = categories[i];\n                entryNode.appendChild(\n                    this.createElementNSPlus(\"atom:category\", {\n                        attributes: {\n                            term: category.term,\n                            scheme: category.scheme || null,\n                            label: category.label || null\n                        }\n                    })\n                );\n            }\n        }\n        if (atomAttrib.content) {\n            entryNode.appendChild(this.buildContentNode(atomAttrib.content));\n        }\n        if (atomAttrib.contributors) {\n            var contributors = OpenLayers.Util.isArray(atomAttrib.contributors) ?\n                atomAttrib.contributors : [atomAttrib.contributors];\n            for (var i=0, ii=contributors.length; i<ii; i++) {\n                entryNode.appendChild(\n                    this.buildPersonConstructNode(\n                        \"contributor\",\n                        contributors[i]\n                        )\n                    );\n            }\n        }\n        if (feature.fid) {\n            entryNode.appendChild(\n                this.createElementNSPlus(\"atom:id\", {\n                    value: feature.fid\n                })\n            );\n        }\n        if (atomAttrib.links) {\n            var links = OpenLayers.Util.isArray(atomAttrib.links) ?\n                atomAttrib.links : [atomAttrib.links];\n            var link;\n            for (var i=0, ii=links.length; i<ii; i++) {\n                link = links[i];\n                entryNode.appendChild(\n                    this.createElementNSPlus(\"atom:link\", {\n                        attributes: {\n                            href: link.href,\n                            rel: link.rel || null,\n                            type: link.type || null,\n                            hreflang: link.hreflang || null,\n                            title: link.title || null,\n                            length: link.length || null\n                        }\n                    })\n                );\n            }\n        }\n        if (atomAttrib.published) {\n            entryNode.appendChild(\n                this.createElementNSPlus(\"atom:published\", {\n                    value: atomAttrib.published\n                })\n            );\n        }\n        if (atomAttrib.rights) {\n            entryNode.appendChild(\n                this.createElementNSPlus(\"atom:rights\", {\n                    value: atomAttrib.rights\n                })\n            );\n        }\n        if (atomAttrib.summary || attrib.description) {\n            entryNode.appendChild(\n                this.createElementNSPlus(\"atom:summary\", {\n                    value: atomAttrib.summary || attrib.description\n                })\n            );\n        }\n        entryNode.appendChild(\n            this.createElementNSPlus(\"atom:title\", {\n                value: atomAttrib.title || attrib.title || this.defaultEntryTitle\n            })\n        );\n        if (atomAttrib.updated) {\n            entryNode.appendChild(\n                this.createElementNSPlus(\"atom:updated\", {\n                    value: atomAttrib.updated\n                })\n            );\n        }\n        if (feature.geometry) {\n            var whereNode = this.createElementNSPlus(\"georss:where\");\n            whereNode.appendChild(\n                this.buildGeometryNode(feature.geometry)\n            );\n            entryNode.appendChild(whereNode);\n        }\n        \n        return entryNode;\n    },\n    \n        initGmlParser: function() {\n        this.gmlParser = new OpenLayers.Format.GML.v3({\n            xy: this.xy,\n            featureNS: \"http://example.com#feature\",\n            internalProjection: this.internalProjection,\n            externalProjection: this.externalProjection\n        });\n    },\n    \n        buildGeometryNode: function(geometry) {\n        if (!this.gmlParser) {\n            this.initGmlParser();\n        }\n        var node = this.gmlParser.writeNode(\"feature:_geometry\", geometry);\n        return node.firstChild;\n    },\n    \n        buildPersonConstructNode: function(name, value) {\n        var oNames = [\"uri\", \"email\"];\n        var personNode = this.createElementNSPlus(\"atom:\" + name);\n        personNode.appendChild(\n            this.createElementNSPlus(\"atom:name\", {\n                value: value.name\n            })\n        );\n        for (var i=0, ii=oNames.length; i<ii; i++) {\n            if (value[oNames[i]]) {\n                personNode.appendChild(\n                    this.createElementNSPlus(\"atom:\" + oNames[i], {\n                        value: value[oNames[i]]\n                    })\n                );\n            }\n        }\n        return personNode;\n    },\n    \n        getFirstChildValue: function(node, nsuri, name, def) {\n        var value;\n        var nodes = this.getElementsByTagNameNS(node, nsuri, name);\n        if (nodes && nodes.length > 0) {\n            value = this.getChildValue(nodes[0], def);\n        } else {\n            value = def;\n        }\n        return value;\n    },\n    \n        parseFeature: function(node) {\n        var atomAttrib = {};\n        var value = null;\n        var nodes = null;\n        var attval = null;\n        var atomns = this.namespaces.atom;\n        this.parsePersonConstructs(node, \"author\", atomAttrib);\n        nodes = this.getElementsByTagNameNS(node, atomns, \"category\");\n        if (nodes.length > 0) {\n            atomAttrib.categories = [];\n        }\n        for (var i=0, ii=nodes.length; i<ii; i++) {\n            value = {};\n            value.term = nodes[i].getAttribute(\"term\");\n            attval = nodes[i].getAttribute(\"scheme\");\n            if (attval) { value.scheme = attval; }\n            attval = nodes[i].getAttribute(\"label\");\n            if (attval) { value.label = attval; }\n            atomAttrib.categories.push(value);\n        }\n        nodes = this.getElementsByTagNameNS(node, atomns, \"content\");\n        if (nodes.length > 0) {\n            value = {};\n            attval = nodes[0].getAttribute(\"type\");\n            if (attval) {\n                value.type = attval;\n            }\n            attval = nodes[0].getAttribute(\"src\");\n            if (attval) {\n                value.src = attval;\n            } else {\n                if (value.type == \"text\" || \n                    value.type == \"html\" || \n                    value.type == null ) {\n                    value.value = this.getFirstChildValue(\n                                        node,\n                                        atomns,\n                                        \"content\",\n                                        null\n                                        );\n                } else if (value.type == \"xhtml\" ||\n                           value.type.match(/(\\+|\\/)xml$/)) {\n                    value.value = this.getChildEl(nodes[0]);\n                } else { // MUST be base64 encoded\n                    value.value = this.getFirstChildValue(\n                                        node,\n                                        atomns,\n                                        \"content\",\n                                        null\n                                        );\n                }\n                atomAttrib.content = value;\n            }\n        }\n        this.parsePersonConstructs(node, \"contributor\", atomAttrib);\n        atomAttrib.id = this.getFirstChildValue(node, atomns, \"id\", null);\n        nodes = this.getElementsByTagNameNS(node, atomns, \"link\");\n        if (nodes.length > 0) {\n            atomAttrib.links = new Array(nodes.length);\n        }\n        var oAtts = [\"rel\", \"type\", \"hreflang\", \"title\", \"length\"];\n        for (var i=0, ii=nodes.length; i<ii; i++) {\n            value = {};\n            value.href = nodes[i].getAttribute(\"href\");\n            for (var j=0, jj=oAtts.length; j<jj; j++) {\n                attval = nodes[i].getAttribute(oAtts[j]);\n                if (attval) {\n                    value[oAtts[j]] = attval;\n                }\n            }\n            atomAttrib.links[i] = value;\n        }\n        value = this.getFirstChildValue(node, atomns, \"published\", null);\n        if (value) {\n            atomAttrib.published = value;\n        }\n        value = this.getFirstChildValue(node, atomns, \"rights\", null);\n        if (value) {\n            atomAttrib.rights = value;\n        }\n        value = this.getFirstChildValue(node, atomns, \"summary\", null);\n        if (value) {\n            atomAttrib.summary = value;\n        }\n        atomAttrib.title = this.getFirstChildValue(\n                                node, atomns, \"title\", null\n                                );\n        atomAttrib.updated = this.getFirstChildValue(\n                                node, atomns, \"updated\", null\n                                );\n        \n        var featureAttrib = {\n            title: atomAttrib.title,\n            description: atomAttrib.summary,\n            atom: atomAttrib\n        };\n        var geometry = this.parseLocations(node)[0];\n        var feature = new OpenLayers.Feature.Vector(geometry, featureAttrib);\n        feature.fid = atomAttrib.id;\n        return feature;\n    },\n    \n        parseFeatures: function(node) {\n        var features = [];\n        var entries = this.getElementsByTagNameNS(\n            node, this.namespaces.atom, \"entry\"\n        );\n        if (entries.length == 0) {\n            entries = [node];\n        }\n        for (var i=0, ii=entries.length; i<ii; i++) {\n            features.push(this.parseFeature(entries[i]));\n        }\n        return features;\n    },\n    \n        parseLocations: function(node) {\n        var georssns = this.namespaces.georss;\n\n        var locations = {components: []};\n        var where = this.getElementsByTagNameNS(node, georssns, \"where\");\n        if (where && where.length > 0) {\n            if (!this.gmlParser) {\n                this.initGmlParser();\n            }\n            for (var i=0, ii=where.length; i<ii; i++) {\n                this.gmlParser.readChildNodes(where[i], locations);\n            }\n        }\n        \n        var components = locations.components;\n        var point = this.getElementsByTagNameNS(node, georssns, \"point\");\n        if (point && point.length > 0) {\n            for (var i=0, ii=point.length; i<ii; i++) {\n                var xy = OpenLayers.String.trim(\n                            point[i].firstChild.nodeValue\n                            ).split(/\\s+/);\n                if (xy.length !=2) {\n                    xy = OpenLayers.String.trim(\n                                point[i].firstChild.nodeValue\n                                ).split(/\\s*,\\s*/);\n                }\n                components.push(new OpenLayers.Geometry.Point(xy[1], xy[0]));\n            }\n        }\n\n        var line = this.getElementsByTagNameNS(node, georssns, \"line\");\n        if (line && line.length > 0) {\n            var coords;\n            var p;\n            var points;\n            for (var i=0, ii=line.length; i<ii; i++) {\n                coords = OpenLayers.String.trim(\n                                line[i].firstChild.nodeValue\n                                ).split(/\\s+/);\n                points = [];\n                for (var j=0, jj=coords.length; j<jj; j+=2) {\n                    p = new OpenLayers.Geometry.Point(coords[j+1], coords[j]);\n                    points.push(p);\n                }\n                components.push(\n                    new OpenLayers.Geometry.LineString(points)\n                );\n            }\n        }        \n\n        var polygon = this.getElementsByTagNameNS(node, georssns, \"polygon\");\n        if (polygon && polygon.length > 0) {\n            var coords;\n            var p;\n            var points;\n            for (var i=0, ii=polygon.length; i<ii; i++) {\n                coords = OpenLayers.String.trim(\n                            polygon[i].firstChild.nodeValue\n                            ).split(/\\s+/);\n                points = [];\n                for (var j=0, jj=coords.length; j<jj; j+=2) {\n                    p = new OpenLayers.Geometry.Point(coords[j+1], coords[j]);\n                    points.push(p);\n                }\n                components.push(\n                    new OpenLayers.Geometry.Polygon(\n                        [new OpenLayers.Geometry.LinearRing(points)]\n                    )\n                );\n            }\n        }\n        \n        if (this.internalProjection && this.externalProjection) {\n            for (var i=0, ii=components.length; i<ii; i++) {\n                if (components[i]) {\n                    components[i].transform(\n                        this.externalProjection,\n                        this.internalProjection\n                    );\n                }\n            }\n        }\n        \n        return components;\n    },\n    \n        parsePersonConstructs: function(node, name, data) {\n        var persons = [];\n        var atomns = this.namespaces.atom;\n        var nodes = this.getElementsByTagNameNS(node, atomns, name);\n        var oAtts = [\"uri\", \"email\"];\n        for (var i=0, ii=nodes.length; i<ii; i++) {\n            var value = {};\n            value.name = this.getFirstChildValue(\n                            nodes[i],\n                            atomns,\n                            \"name\",\n                            null\n                            );\n            for (var j=0, jj=oAtts.length; j<jj; j++) {\n                var attval = this.getFirstChildValue(\n                            nodes[i],\n                            atomns,\n                            oAtts[j],\n                            null);\n                if (attval) {\n                    value[oAtts[j]] = attval;\n                }\n            }\n            persons.push(value);\n        }\n        if (persons.length > 0) {\n            data[name + \"s\"] = persons;\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.Atom\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/CQL.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.CQL = (function() {\n    \n    var tokens = [\n        \"PROPERTY\", \"COMPARISON\", \"VALUE\", \"LOGICAL\"\n    ],\n\n    patterns = {\n        PROPERTY: /^[_a-zA-Z]\\w*/,\n        COMPARISON: /^(=|<>|<=|<|>=|>|LIKE)/i,\n        IS_NULL: /^IS NULL/i,\n        COMMA: /^,/,\n        LOGICAL: /^(AND|OR)/i,\n        VALUE: /^('([^']|'')*'|\\d+(\\.\\d*)?|\\.\\d+)/,\n        LPAREN: /^\\(/,\n        RPAREN: /^\\)/,\n        SPATIAL: /^(BBOX|INTERSECTS|DWITHIN|WITHIN|CONTAINS)/i,\n        NOT: /^NOT/i,\n        BETWEEN: /^BETWEEN/i,\n        GEOMETRY: function(text) {\n            var type = /^(POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON|GEOMETRYCOLLECTION)/.exec(text);\n            if (type) {\n                var len = text.length;\n                var idx = text.indexOf(\"(\", type[0].length);\n                if (idx > -1) {\n                    var depth = 1;\n                    while (idx < len && depth > 0) {\n                        idx++;\n                        switch(text.charAt(idx)) {\n                            case '(':\n                                depth++;\n                                break;\n                            case ')':\n                                depth--;\n                                break;\n                            default:\n                        }\n                    }\n                }\n                return [text.substr(0, idx+1)];\n            }\n        },\n        END: /^$/\n    },\n\n    follows = {\n        LPAREN: ['GEOMETRY', 'SPATIAL', 'PROPERTY', 'VALUE', 'LPAREN'],\n        RPAREN: ['NOT', 'LOGICAL', 'END', 'RPAREN'],\n        PROPERTY: ['COMPARISON', 'BETWEEN', 'COMMA', 'IS_NULL'],\n        BETWEEN: ['VALUE'],\n        IS_NULL: ['END'],\n        COMPARISON: ['VALUE'],\n        COMMA: ['GEOMETRY', 'VALUE', 'PROPERTY'],\n        VALUE: ['LOGICAL', 'COMMA', 'RPAREN', 'END'],\n        SPATIAL: ['LPAREN'],\n        LOGICAL: ['NOT', 'VALUE', 'SPATIAL', 'PROPERTY', 'LPAREN'],\n        NOT: ['PROPERTY', 'LPAREN'],\n        GEOMETRY: ['COMMA', 'RPAREN']\n    },\n\n    operators = {\n        '=': OpenLayers.Filter.Comparison.EQUAL_TO,\n        '<>': OpenLayers.Filter.Comparison.NOT_EQUAL_TO,\n        '<': OpenLayers.Filter.Comparison.LESS_THAN,\n        '<=': OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO,\n        '>': OpenLayers.Filter.Comparison.GREATER_THAN,\n        '>=': OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO,\n        'LIKE': OpenLayers.Filter.Comparison.LIKE,\n        'BETWEEN': OpenLayers.Filter.Comparison.BETWEEN,\n        'IS NULL': OpenLayers.Filter.Comparison.IS_NULL\n    },\n\n    operatorReverse = {},\n\n    logicals = {\n        'AND': OpenLayers.Filter.Logical.AND,\n        'OR': OpenLayers.Filter.Logical.OR\n    },\n\n    logicalReverse = {},\n\n    precedence = {\n        'RPAREN': 3,\n        'LOGICAL': 2,\n        'COMPARISON': 1\n    };\n\n    var i;\n    for (i in operators) {\n        if (operators.hasOwnProperty(i)) {\n            operatorReverse[operators[i]] = i;\n        }\n    }\n\n    for (i in logicals) {\n        if (logicals.hasOwnProperty(i)) {\n            logicalReverse[logicals[i]] = i;\n        }\n    }\n\n    function tryToken(text, pattern) {\n        if (pattern instanceof RegExp) {\n            return pattern.exec(text);\n        } else {\n            return pattern(text);\n        }\n    }\n\n    function nextToken(text, tokens) {\n        var i, token, len = tokens.length;\n        for (i=0; i<len; i++) {\n            token = tokens[i];\n            var pat = patterns[token];\n            var matches = tryToken(text, pat);\n            if (matches) {\n                var match = matches[0];\n                var remainder = text.substr(match.length).replace(/^\\s*/, \"\");\n                return {\n                    type: token,\n                    text: match,\n                    remainder: remainder\n                };\n            }\n        }\n\n        var msg = \"ERROR: In parsing: [\" + text + \"], expected one of: \";\n        for (i=0; i<len; i++) {\n            token = tokens[i];\n            msg += \"\\n    \" + token + \": \" + patterns[token];\n        }\n\n        throw new Error(msg);\n    }\n\n    function tokenize(text) {\n        var results = [];\n        var token, expect = [\"NOT\", \"GEOMETRY\", \"SPATIAL\", \"PROPERTY\", \"LPAREN\"];\n\n        do {\n            token = nextToken(text, expect);\n            text = token.remainder;\n            expect = follows[token.type];\n            if (token.type != \"END\" && !expect) {\n                throw new Error(\"No follows list for \" + token.type);\n            }\n            results.push(token);\n        } while (token.type != \"END\");\n\n        return results;\n    }\n\n    function buildAst(tokens) {\n        var operatorStack = [],\n            postfix = [];\n\n        while (tokens.length) {\n            var tok = tokens.shift();\n            switch (tok.type) {\n                case \"PROPERTY\":\n                case \"GEOMETRY\":\n                case \"VALUE\":\n                    postfix.push(tok);\n                    break;\n                case \"COMPARISON\":\n                case \"BETWEEN\":\n                case \"IS_NULL\":\n                case \"LOGICAL\":\n                    var p = precedence[tok.type];\n\n                    while (operatorStack.length > 0 &&\n                        (precedence[operatorStack[operatorStack.length - 1].type] <= p)\n                    ) {\n                        postfix.push(operatorStack.pop());\n                    }\n\n                    operatorStack.push(tok);\n                    break;\n                case \"SPATIAL\":\n                case \"NOT\":\n                case \"LPAREN\":\n                    operatorStack.push(tok);\n                    break;\n                case \"RPAREN\":\n                    while (operatorStack.length > 0 &&\n                        (operatorStack[operatorStack.length - 1].type != \"LPAREN\")\n                    ) {\n                        postfix.push(operatorStack.pop());\n                    }\n                    operatorStack.pop(); // toss out the LPAREN\n\n                    if (operatorStack.length > 0 &&\n                        operatorStack[operatorStack.length-1].type == \"SPATIAL\") {\n                        postfix.push(operatorStack.pop());\n                    }\n                case \"COMMA\":\n                case \"END\":\n                    break;\n                default:\n                    throw new Error(\"Unknown token type \" + tok.type);\n            }\n        }\n\n        while (operatorStack.length > 0) {\n            postfix.push(operatorStack.pop());\n        }\n\n        function buildTree() {\n            var tok = postfix.pop();\n            switch (tok.type) {\n                case \"LOGICAL\":\n                    var rhs = buildTree(),\n                        lhs = buildTree();\n                    return new OpenLayers.Filter.Logical({\n                        filters: [lhs, rhs],\n                        type: logicals[tok.text.toUpperCase()]\n                    });\n                case \"NOT\":\n                    var operand = buildTree();\n                    return new OpenLayers.Filter.Logical({\n                        filters: [operand],\n                        type: OpenLayers.Filter.Logical.NOT\n                    });\n                case \"BETWEEN\":\n                    var min, max, property;\n                    postfix.pop(); // unneeded AND token here\n                    max = buildTree();\n                    min = buildTree();\n                    property = buildTree();\n                    return new OpenLayers.Filter.Comparison({\n                        property: property,\n                        lowerBoundary: min,\n                        upperBoundary: max,\n                        type: OpenLayers.Filter.Comparison.BETWEEN\n                    });\n                case \"COMPARISON\":\n                    var value = buildTree(),\n                        property = buildTree();\n                    return new OpenLayers.Filter.Comparison({\n                        property: property,\n                        value: value,\n                        type: operators[tok.text.toUpperCase()]\n                    });\n                case \"IS_NULL\":\n                    var property = buildTree();\n                    return new OpenLayers.Filter.Comparison({\n                        property: property,\n                        type: operators[tok.text.toUpperCase()]\n                    });\n                case \"VALUE\":\n                    var match = tok.text.match(/^'(.*)'$/);\n                    if (match) {\n                        return match[1].replace(/''/g, \"'\");\n                    } else {\n                        return Number(tok.text);\n                    }\n                case \"SPATIAL\":\n                    switch(tok.text.toUpperCase()) {\n                        case \"BBOX\":\n                            var maxy = buildTree(),\n                                maxx = buildTree(),\n                                miny = buildTree(),\n                                minx = buildTree(),\n                                prop = buildTree();\n\n                            return new OpenLayers.Filter.Spatial({\n                                type: OpenLayers.Filter.Spatial.BBOX,\n                                property: prop,\n                                value: OpenLayers.Bounds.fromArray(\n                                    [minx, miny, maxx, maxy]\n                                )\n                            });\n                        case \"INTERSECTS\":\n                            var value = buildTree(),\n                                property = buildTree();\n                            return new OpenLayers.Filter.Spatial({\n                                type: OpenLayers.Filter.Spatial.INTERSECTS,\n                                property: property,\n                                value: value\n                            });\n                        case \"WITHIN\":\n                            var value = buildTree(),\n                                property = buildTree();\n                            return new OpenLayers.Filter.Spatial({\n                                type: OpenLayers.Filter.Spatial.WITHIN,\n                                property: property,\n                                value: value\n                            });\n                        case \"CONTAINS\":\n                            var value = buildTree(),\n                                property = buildTree();\n                            return new OpenLayers.Filter.Spatial({\n                                type: OpenLayers.Filter.Spatial.CONTAINS,\n                                property: property,\n                                value: value\n                            });\n                        case \"DWITHIN\":\n                            var distance = buildTree(),\n                                value = buildTree(),\n                                property = buildTree();\n                            return new OpenLayers.Filter.Spatial({\n                                type: OpenLayers.Filter.Spatial.DWITHIN,\n                                value: value,\n                                property: property,\n                                distance: Number(distance)\n                            });\n                    }\n                case \"GEOMETRY\":\n                    return OpenLayers.Geometry.fromWKT(tok.text);\n                default:\n                    return tok.text;\n            }\n        }\n\n        var result = buildTree();\n        if (postfix.length > 0) {\n            var msg = \"Remaining tokens after building AST: \\n\";\n            for (var i = postfix.length - 1; i >= 0; i--) {\n                msg += postfix[i].type + \": \" + postfix[i].text + \"\\n\";\n            }\n            throw new Error(msg);\n        }\n\n        return result;\n    }\n\n    return OpenLayers.Class(OpenLayers.Format, {\n                read: function(text) { \n            var result = buildAst(tokenize(text));\n            if (this.keepData) {\n                this.data = result;\n            }\n            return result;\n        },\n\n                write: function(filter) {\n            if (filter instanceof OpenLayers.Geometry) {\n                return filter.toString();\n            }\n            switch (filter.CLASS_NAME) {\n                case \"OpenLayers.Filter.Spatial\":\n                    switch(filter.type) {\n                        case OpenLayers.Filter.Spatial.BBOX:\n                            return \"BBOX(\" +\n                                filter.property + \",\" +\n                                filter.value.toBBOX() +\n                                \")\";\n                        case OpenLayers.Filter.Spatial.DWITHIN:\n                            return \"DWITHIN(\" +\n                                filter.property + \", \" +\n                                this.write(filter.value) + \", \" +\n                                filter.distance + \")\";\n                        case OpenLayers.Filter.Spatial.WITHIN:\n                            return \"WITHIN(\" +\n                                filter.property + \", \" +\n                                this.write(filter.value) + \")\";\n                        case OpenLayers.Filter.Spatial.INTERSECTS:\n                            return \"INTERSECTS(\" +\n                                filter.property + \", \" +\n                                this.write(filter.value) + \")\";\n                        case OpenLayers.Filter.Spatial.CONTAINS:\n                            return \"CONTAINS(\" +\n                                filter.property + \", \" +\n                                this.write(filter.value) + \")\";\n                        default:\n                            throw new Error(\"Unknown spatial filter type: \" + filter.type);\n                    }\n                case \"OpenLayers.Filter.Logical\":\n                    if (filter.type == OpenLayers.Filter.Logical.NOT) {\n                        return \"NOT (\" + this.write(filter.filters[0]) + \")\";\n                    } else {\n                        var res = \"(\";\n                        var first = true;\n                        for (var i = 0; i < filter.filters.length; i++) {\n                            if (first) {\n                                first = false;\n                            } else {\n                                res += \") \" + logicalReverse[filter.type] + \" (\";\n                            }\n                            res += this.write(filter.filters[i]);\n                        }\n                        return res + \")\";\n                    }\n                case \"OpenLayers.Filter.Comparison\":\n                    if (filter.type == OpenLayers.Filter.Comparison.BETWEEN) {\n                        return filter.property + \" BETWEEN \" + \n                            this.write(filter.lowerBoundary) + \" AND \" + \n                            this.write(filter.upperBoundary);\n                    } else {\n                        return (filter.value !== null) ? filter.property +\n                            \" \" + operatorReverse[filter.type] + \" \" + \n                            this.write(filter.value) : filter.property +\n                            \" \" + operatorReverse[filter.type];\n                    }\n                case undefined:\n                    if (typeof filter === \"string\") {\n                        return \"'\" + filter.replace(/'/g, \"''\") + \"'\";\n                    } else if (typeof filter === \"number\") {\n                        return String(filter);\n                    }\n                default:\n                    throw new Error(\"Can't encode: \" + filter.CLASS_NAME + \" \" + filter);\n            }\n        },\n\n        CLASS_NAME: \"OpenLayers.Format.CQL\"\n\n    });\n})();\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/CSWGetDomain/v2_0_2.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.CSWGetDomain.v2_0_2 = OpenLayers.Class(OpenLayers.Format.XML, {\n    \n        namespaces: {\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\",\n        csw: \"http://www.opengis.net/cat/csw/2.0.2\"\n    },\n\n        defaultPrefix: \"csw\",\n    \n        version: \"2.0.2\",\n    \n        schemaLocation: \"http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd\",\n\n        PropertyName: null,\n\n        ParameterName: null,\n    \n    \n        read: function(data) {\n        if(typeof data == \"string\") { \n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        if(data && data.nodeType == 9) {\n            data = data.documentElement;\n        }\n        var obj = {};\n        this.readNode(data, obj);\n        return obj;\n    },\n    \n        readers: {\n        \"csw\": {\n            \"GetDomainResponse\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"DomainValues\": function(node, obj) {\n                if (!(OpenLayers.Util.isArray(obj.DomainValues))) {\n                    obj.DomainValues = [];\n                }\n                var attrs = node.attributes;\n                var domainValue = {};\n                for(var i=0, len=attrs.length; i<len; ++i) {\n                    domainValue[attrs[i].name] = attrs[i].nodeValue;\n                }\n                this.readChildNodes(node, domainValue);\n                obj.DomainValues.push(domainValue);\n            },\n            \"PropertyName\": function(node, obj) {\n                obj.PropertyName = this.getChildValue(node);\n            },\n            \"ParameterName\": function(node, obj) {\n                obj.ParameterName = this.getChildValue(node);\n            },\n            \"ListOfValues\": function(node, obj) {\n                if (!(OpenLayers.Util.isArray(obj.ListOfValues))) {\n                    obj.ListOfValues = [];\n                }\n                this.readChildNodes(node, obj.ListOfValues);\n            },\n            \"Value\": function(node, obj) {\n                var attrs = node.attributes;\n                var value = {};\n                for(var i=0, len=attrs.length; i<len; ++i) {\n                    value[attrs[i].name] = attrs[i].nodeValue;\n                }\n                value.value = this.getChildValue(node);\n                obj.push({Value: value});\n            },\n            \"ConceptualScheme\": function(node, obj) {\n                obj.ConceptualScheme = {};\n                this.readChildNodes(node, obj.ConceptualScheme);\n            },\n            \"Name\": function(node, obj) {\n                obj.Name = this.getChildValue(node);\n            },\n            \"Document\": function(node, obj) {\n                obj.Document = this.getChildValue(node);\n            },\n            \"Authority\": function(node, obj) {\n                obj.Authority = this.getChildValue(node);\n            },\n            \"RangeOfValues\": function(node, obj) {\n                obj.RangeOfValues = {};\n                this.readChildNodes(node, obj.RangeOfValues);\n            },\n            \"MinValue\": function(node, obj) {\n                var attrs = node.attributes;\n                var value = {};\n                for(var i=0, len=attrs.length; i<len; ++i) {\n                    value[attrs[i].name] = attrs[i].nodeValue;\n                }\n                value.value = this.getChildValue(node);\n                obj.MinValue = value;\n            },\n            \"MaxValue\": function(node, obj) {\n                var attrs = node.attributes;\n                var value = {};\n                for(var i=0, len=attrs.length; i<len; ++i) {\n                    value[attrs[i].name] = attrs[i].nodeValue;\n                }\n                value.value = this.getChildValue(node);\n                obj.MaxValue = value;\n            }\n        }\n    },\n    \n        write: function(options) {\n        var node = this.writeNode(\"csw:GetDomain\", options);\n        return OpenLayers.Format.XML.prototype.write.apply(this, [node]);\n    },\n\n        writers: {\n        \"csw\": {\n            \"GetDomain\": function(options) {\n                var node = this.createElementNSPlus(\"csw:GetDomain\", {\n                    attributes: {\n                        service: \"CSW\",\n                        version: this.version\n                    }\n                });\n                if (options.PropertyName || this.PropertyName) {\n                    this.writeNode(\n                        \"csw:PropertyName\",\n                        options.PropertyName || this.PropertyName,\n                        node\n                    );\n                } else if (options.ParameterName || this.ParameterName) {\n                    this.writeNode(\n                        \"csw:ParameterName\",\n                        options.ParameterName || this.ParameterName,\n                        node\n                    );\n                }\n                this.readChildNodes(node, options);\n                return node;\n            },\n            \"PropertyName\": function(value) {\n                var node = this.createElementNSPlus(\"csw:PropertyName\", {\n                    value: value\n                });\n                return node;\n            },\n            \"ParameterName\": function(value) {\n                var node = this.createElementNSPlus(\"csw:ParameterName\", {\n                    value: value\n                });\n                return node;\n            }\n        }\n    },\n   \n    CLASS_NAME: \"OpenLayers.Format.CSWGetDomain.v2_0_2\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/CSWGetDomain.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.CSWGetDomain = function(options) {\n    options = OpenLayers.Util.applyDefaults(\n        options, OpenLayers.Format.CSWGetDomain.DEFAULTS\n    );\n    var cls = OpenLayers.Format.CSWGetDomain[\"v\"+options.version.replace(/\\./g, \"_\")];\n    if(!cls) {\n        throw \"Unsupported CSWGetDomain version: \" + options.version;\n    }\n    return new cls(options);\n};\n\nOpenLayers.Format.CSWGetDomain.DEFAULTS = {\n    \"version\": \"2.0.2\"\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/CSWGetRecords/v2_0_2.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.CSWGetRecords.v2_0_2 = OpenLayers.Class(OpenLayers.Format.XML, {\n    \n        namespaces: {\n        csw: \"http://www.opengis.net/cat/csw/2.0.2\",\n        dc: \"http://purl.org/dc/elements/1.1/\",\n        dct: \"http://purl.org/dc/terms/\",\n        gmd: \"http://www.isotc211.org/2005/gmd\",\n        geonet: \"http://www.fao.org/geonetwork\",\n        ogc: \"http://www.opengis.net/ogc\",\n        ows: \"http://www.opengis.net/ows\",\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\",\n        xmlns: \"http://www.w3.org/2000/xmlns/\"\n    },\n    \n        defaultPrefix: \"csw\",\n    \n        version: \"2.0.2\",\n    \n        schemaLocation: \"http://www.opengis.net/cat/csw/2.0.2 http://schemas.opengis.net/csw/2.0.2/CSW-discovery.xsd\",\n\n        requestId: null,\n\n        resultType: null,\n\n        outputFormat: null,\n\n        outputSchema: null,\n\n        startPosition: null,\n\n        maxRecords: null,\n\n        DistributedSearch: null,\n\n        ResponseHandler: null,\n\n        Query: null,\n\n        regExes: {\n        trimSpace: (/^\\s*|\\s*$/g),\n        removeSpace: (/\\s*/g),\n        splitSpace: (/\\s+/),\n        trimComma: (/\\s*,\\s*/g)\n    },\n\n        initialize: function(options) {\n        OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);\n    },\n\n        read: function(data) {\n        if(typeof data == \"string\") { \n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        if(data && data.nodeType == 9) {\n            data = data.documentElement;\n        }\n        var obj = {};\n        this.readNode(data, obj);\n        return obj;\n    },\n    \n        readers: {\n        \"csw\": {\n            \"GetRecordsResponse\": function(node, obj) {\n                obj.records = [];\n                this.readChildNodes(node, obj);\n                var version = this.getAttributeNS(node, \"\", 'version');\n                if (version != \"\") {\n                    obj.version = version;\n                }\n            },\n            \"RequestId\": function(node, obj) {\n                obj.RequestId = this.getChildValue(node);\n            },\n            \"SearchStatus\": function(node, obj) {\n                obj.SearchStatus = {};\n                var timestamp = this.getAttributeNS(node, \"\", 'timestamp');\n                if (timestamp != \"\") {\n                    obj.SearchStatus.timestamp = timestamp;\n                }\n            },\n            \"SearchResults\": function(node, obj) {\n                this.readChildNodes(node, obj);\n                var attrs = node.attributes;\n                var SearchResults = {};\n                for(var i=0, len=attrs.length; i<len; ++i) {\n                    if ((attrs[i].name == \"numberOfRecordsMatched\") ||\n                        (attrs[i].name == \"numberOfRecordsReturned\") ||\n                        (attrs[i].name == \"nextRecord\")) {\n                        SearchResults[attrs[i].name] = parseInt(attrs[i].nodeValue);\n                    } else {\n                        SearchResults[attrs[i].name] = attrs[i].nodeValue;\n                    }\n                }\n                obj.SearchResults = SearchResults;\n            },\n            \"SummaryRecord\": function(node, obj) {\n                var record = {type: \"SummaryRecord\"};\n                this.readChildNodes(node, record);\n                obj.records.push(record);\n            },\n            \"BriefRecord\": function(node, obj) {\n                var record = {type: \"BriefRecord\"};\n                this.readChildNodes(node, record);\n                obj.records.push(record);\n            },\n            \"DCMIRecord\": function(node, obj) {\n                var record = {type: \"DCMIRecord\"};\n                this.readChildNodes(node, record);\n                obj.records.push(record);\n            },\n            \"Record\": function(node, obj) {\n                var record = {type: \"Record\"};\n                this.readChildNodes(node, record);\n                obj.records.push(record);\n            },\n            \"*\": function(node, obj) {\n                var name = node.localName || node.nodeName.split(\":\").pop();\n                obj[name] = this.getChildValue(node);\n            }\n        },\n        \"geonet\": {\n            \"info\": function(node, obj) {\n                var gninfo = {};\n                this.readChildNodes(node, gninfo);\n                obj.gninfo = gninfo;\n            }\n        },\n        \"dc\": {\n            \"*\": function(node, obj) {\n                var name = node.localName || node.nodeName.split(\":\").pop();\n                if (!(OpenLayers.Util.isArray(obj[name]))) {\n                    obj[name] = [];\n                }\n                var dc_element = {};\n                var attrs = node.attributes;\n                for(var i=0, len=attrs.length; i<len; ++i) {\n                    dc_element[attrs[i].name] = attrs[i].nodeValue;\n                }\n                dc_element.value = this.getChildValue(node);\n                if (dc_element.value != \"\") {\n                    obj[name].push(dc_element);\n                }\n            }\n        },\n        \"dct\": {\n            \"*\": function(node, obj) {\n                var name = node.localName || node.nodeName.split(\":\").pop();\n                if (!(OpenLayers.Util.isArray(obj[name]))) {\n                    obj[name] = [];\n                }\n                obj[name].push(this.getChildValue(node));\n            }\n        },\n        \"ows\": OpenLayers.Util.applyDefaults({\n            \"BoundingBox\": function(node, obj) {\n                if (obj.bounds) {\n                    obj.BoundingBox = [{crs: obj.projection, value: \n                        [\n                            obj.bounds.left, \n                            obj.bounds.bottom, \n                            obj.bounds.right, \n                            obj.bounds.top\n                    ]\n                    }];\n                    delete obj.projection;\n                    delete obj.bounds;\n                }\n                OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers[\"ows\"][\"BoundingBox\"].apply(\n                    this, arguments);\n            }\n        }, OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers[\"ows\"])\n    },\n    \n        write: function(options) {\n        var node = this.writeNode(\"csw:GetRecords\", options);\n        this.setAttributeNS(\n            node, this.namespaces.xmlns,\n            \"xmlns:gmd\", this.namespaces.gmd\n        );\n        return OpenLayers.Format.XML.prototype.write.apply(this, [node]);\n    },\n\n        writers: {\n        \"csw\": {\n            \"GetRecords\": function(options) {\n                if (!options) {\n                    options = {};\n                }\n                var node = this.createElementNSPlus(\"csw:GetRecords\", {\n                    attributes: {\n                        service: \"CSW\",\n                        version: this.version,\n                        requestId: options.requestId || this.requestId,\n                        resultType: options.resultType || this.resultType,\n                        outputFormat: options.outputFormat || this.outputFormat,\n                        outputSchema: options.outputSchema || this.outputSchema,\n                        startPosition: options.startPosition || this.startPosition,\n                        maxRecords: options.maxRecords || this.maxRecords\n                    }\n                });\n                if (options.DistributedSearch || this.DistributedSearch) {\n                    this.writeNode(\n                        \"csw:DistributedSearch\",\n                        options.DistributedSearch || this.DistributedSearch,\n                        node\n                    );\n                }\n                var ResponseHandler = options.ResponseHandler || this.ResponseHandler;\n                if (OpenLayers.Util.isArray(ResponseHandler) && ResponseHandler.length > 0) {\n                    for(var i=0, len=ResponseHandler.length; i<len; i++) {\n                        this.writeNode(\n                            \"csw:ResponseHandler\",\n                            ResponseHandler[i],\n                            node\n                        );\n                    }\n                }\n                this.writeNode(\"Query\", options.Query || this.Query, node);\n                return node;\n            },\n            \"DistributedSearch\": function(options) {\n                var node = this.createElementNSPlus(\"csw:DistributedSearch\", {\n                    attributes: {\n                        hopCount: options.hopCount\n                    }\n                });\n                return node;\n            },\n            \"ResponseHandler\": function(options) {\n                var node = this.createElementNSPlus(\"csw:ResponseHandler\", {\n                    value: options.value\n                });\n                return node;\n            },\n            \"Query\": function(options) {\n                if (!options) {\n                    options = {};\n                }\n                var node = this.createElementNSPlus(\"csw:Query\", {\n                    attributes: {\n                        typeNames: options.typeNames || \"csw:Record\"\n                    }\n                });\n                var ElementName = options.ElementName;\n                if (OpenLayers.Util.isArray(ElementName) && ElementName.length > 0) {\n                    for(var i=0, len=ElementName.length; i<len; i++) {\n                        this.writeNode(\n                            \"csw:ElementName\",\n                            ElementName[i],\n                            node\n                        );\n                    }\n                } else {\n                    this.writeNode(\n                        \"csw:ElementSetName\",\n                        options.ElementSetName || {value: 'summary'},\n                        node\n                    );\n                }\n                if (options.Constraint) {\n                    this.writeNode(\n                        \"csw:Constraint\",\n                        options.Constraint,\n                        node\n                    );\n                }\n                if (options.SortBy) {\n                    this.writeNode(\n                        \"ogc:SortBy\",\n                        options.SortBy,\n                        node\n                    );\n                }\n                return node;\n            },\n            \"ElementName\": function(options) {\n                var node = this.createElementNSPlus(\"csw:ElementName\", {\n                    value: options.value\n                });\n                return node;\n            },\n            \"ElementSetName\": function(options) {\n                var node = this.createElementNSPlus(\"csw:ElementSetName\", {\n                    attributes: {\n                        typeNames: options.typeNames\n                    },\n                    value: options.value\n                });\n                return node;\n            },\n            \"Constraint\": function(options) {\n                var node = this.createElementNSPlus(\"csw:Constraint\", {\n                    attributes: {\n                        version: options.version\n                    }\n                });\n                if (options.Filter) {\n                    var format = new OpenLayers.Format.Filter({\n                        version: options.version\n                    });\n                    node.appendChild(format.write(options.Filter));\n                } else if (options.CqlText) {\n                    var child = this.createElementNSPlus(\"CqlText\", {\n                        value: options.CqlText.value\n                    });\n                    node.appendChild(child);\n                }\n                return node;\n            }\n        },\n        \"ogc\": OpenLayers.Format.Filter.v1_1_0.prototype.writers[\"ogc\"]\n    },\n   \n    CLASS_NAME: \"OpenLayers.Format.CSWGetRecords.v2_0_2\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/CSWGetRecords.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.CSWGetRecords = function(options) {\n    options = OpenLayers.Util.applyDefaults(\n        options, OpenLayers.Format.CSWGetRecords.DEFAULTS\n    );\n    var cls = OpenLayers.Format.CSWGetRecords[\"v\"+options.version.replace(/\\./g, \"_\")];\n    if(!cls) {\n        throw \"Unsupported CSWGetRecords version: \" + options.version;\n    }\n    return new cls(options);\n};\n\nOpenLayers.Format.CSWGetRecords.DEFAULTS = {\n    \"version\": \"2.0.2\"\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/Context.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.Context = OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC, {\n\n        layerOptions: null,\n\n        layerParams: null,\n\n    \n        read: function(data, options) {\n        var context = OpenLayers.Format.XML.VersionedOGC.prototype.read.apply(this, \n            arguments);\n        var map;\n        if(options && options.map) {\n            this.context = context;\n            if(options.map instanceof OpenLayers.Map) {\n                map = this.mergeContextToMap(context, options.map);\n            } else {\n                var mapOptions = options.map;\n                if(OpenLayers.Util.isElement(mapOptions) ||\n                   typeof mapOptions == \"string\") {\n                    mapOptions = {div: mapOptions};\n                }\n                map = this.contextToMap(context, mapOptions);\n            }\n        } else {\n            map = context;\n        }\n        return map;\n    },\n\n        getLayerFromContext: function(layerContext) {\n        var i, len;\n        var options = {\n            queryable: layerContext.queryable, //keep queryable for api compatibility\n            visibility: layerContext.visibility,\n            maxExtent: layerContext.maxExtent,\n            metadata: OpenLayers.Util.applyDefaults(layerContext.metadata, \n            {styles: layerContext.styles,\n             formats: layerContext.formats,\n             \"abstract\": layerContext[\"abstract\"],\n             dataURL: layerContext.dataURL\n            }),\n            numZoomLevels: layerContext.numZoomLevels,\n            units: layerContext.units,\n            isBaseLayer: layerContext.isBaseLayer,\n            opacity: layerContext.opacity,\n            gutter: layerContext.gutter,\n            displayInLayerSwitcher: layerContext.displayInLayerSwitcher,\n            singleTile: layerContext.singleTile,\n            tileSize: (layerContext.tileSize) ? \n                new OpenLayers.Size(\n                    layerContext.tileSize.width, \n                    layerContext.tileSize.height\n                ) : undefined,\n            minScale: layerContext.minScale || layerContext.maxScaleDenominator,\n            maxScale: layerContext.maxScale || layerContext.minScaleDenominator,\n            srs: layerContext.srs,\n            dimensions: layerContext.dimensions,\n            metadataURL: layerContext.metadataURL,\n            attribution: layerContext.attribution\n        };\n        if (this.layerOptions) {\n            OpenLayers.Util.applyDefaults(options, this.layerOptions);\n        }\n\n        var params = {\n            layers: layerContext.name,\n            transparent: layerContext.transparent,\n            version: layerContext.version\n        };\n        if (layerContext.formats && layerContext.formats.length>0) {\n            params.format = layerContext.formats[0].value;\n            for (i=0, len=layerContext.formats.length; i<len; i++) {\n                var format = layerContext.formats[i];\n                if (format.current == true) {\n                    params.format = format.value;\n                    break;\n                }\n            }\n        }\n        if (layerContext.styles && layerContext.styles.length>0) {\n            for (i=0, len=layerContext.styles.length; i<len; i++) {\n                var style = layerContext.styles[i];\n                if (style.current == true) {\n                    if(style.href) {\n                        params.sld = style.href;\n                    } else if(style.body) {\n                        params.sld_body = style.body;\n                    } else {\n                        params.styles = style.name;\n                    }\n                    break;\n                }\n            }\n        }\n        if (this.layerParams) {\n            OpenLayers.Util.applyDefaults(params, this.layerParams);\n        }\n\n        var layer = null;\n        var service = layerContext.service;\n        if (service == OpenLayers.Format.Context.serviceTypes.WFS) {\n            options.strategies = [new OpenLayers.Strategy.BBOX()];\n            options.protocol = new OpenLayers.Protocol.WFS({\n                url: layerContext.url,\n                featurePrefix: layerContext.name.split(\":\")[0],\n                featureType: layerContext.name.split(\":\").pop()\n            });\n            layer = new OpenLayers.Layer.Vector(\n                layerContext.title || layerContext.name,\n                options\n            );\n        } else if (service == OpenLayers.Format.Context.serviceTypes.KML) {\n            options.strategies = [new OpenLayers.Strategy.Fixed()];\n            options.protocol = new OpenLayers.Protocol.HTTP({\n                url: layerContext.url, \n                format: new OpenLayers.Format.KML()\n            });\n            layer = new OpenLayers.Layer.Vector(\n                layerContext.title || layerContext.name,\n                options\n            );\n        } else if (service == OpenLayers.Format.Context.serviceTypes.GML) {\n            options.strategies = [new OpenLayers.Strategy.Fixed()];\n            options.protocol = new OpenLayers.Protocol.HTTP({\n                url: layerContext.url, \n                format: new OpenLayers.Format.GML()\n            });\n            layer = new OpenLayers.Layer.Vector(\n                layerContext.title || layerContext.name,\n                options\n            );\n        } else if (layerContext.features) {\n            layer = new OpenLayers.Layer.Vector(\n                layerContext.title || layerContext.name,\n                options\n            );\n            layer.addFeatures(layerContext.features);\n        } else if (layerContext.categoryLayer !== true) {\n            layer = new OpenLayers.Layer.WMS(\n                layerContext.title || layerContext.name,\n                layerContext.url,\n                params,\n                options\n            );\n        }\n        return layer;\n    },\n\n        getLayersFromContext: function(layersContext) {\n        var layers = [];\n        for (var i=0, len=layersContext.length; i<len; i++) {\n            var layer = this.getLayerFromContext(layersContext[i]);\n            if (layer !== null) {\n                layers.push(layer);\n            }\n        }\n        return layers;\n    },\n\n        contextToMap: function(context, options) {\n        options = OpenLayers.Util.applyDefaults({\n            maxExtent:  context.maxExtent,\n            projection: context.projection,\n            units:      context.units\n        }, options);\n\n        if (options.maxExtent) {\n            options.maxResolution = \n                options.maxExtent.getWidth() / OpenLayers.Map.TILE_WIDTH;\n        }\n\n        var metadata = {\n            contactInformation: context.contactInformation,\n            \"abstract\":         context[\"abstract\"],\n            keywords:           context.keywords,\n            logo:               context.logo,\n            descriptionURL:     context.descriptionURL\n        };\n\n        options.metadata = metadata;\n\n        var map = new OpenLayers.Map(options);\n        map.addLayers(this.getLayersFromContext(context.layersContext));\n        map.setCenter(\n            context.bounds.getCenterLonLat(),\n            map.getZoomForExtent(context.bounds, true)\n        );\n        return map;\n    },\n\n        mergeContextToMap: function(context, map) {\n        map.addLayers(this.getLayersFromContext(context.layersContext));\n        return map;\n    },\n\n        write: function(obj, options) {\n        obj = this.toContext(obj);\n        return OpenLayers.Format.XML.VersionedOGC.prototype.write.apply(this,\n            arguments);\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.Context\"\n});\n\nOpenLayers.Format.Context.serviceTypes = {\n    \"WMS\": \"urn:ogc:serviceType:WMS\",\n    \"WFS\": \"urn:ogc:serviceType:WFS\",\n    \"WCS\": \"urn:ogc:serviceType:WCS\",\n    \"GML\": \"urn:ogc:serviceType:GML\",\n    \"SLD\": \"urn:ogc:serviceType:SLD\",\n    \"FES\": \"urn:ogc:serviceType:FES\",\n    \"KML\": \"urn:ogc:serviceType:KML\"\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/EncodedPolyline.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.EncodedPolyline = OpenLayers.Class(OpenLayers.Format, {\n\n        geometryType: \"linestring\",\n\n        initialize: function(options) {\n        OpenLayers.Format.prototype.initialize.apply(this, [options]);\n    },\n\n        read: function(encoded) {\n        var geomType;\n        if (this.geometryType == \"linestring\")\n            geomType = OpenLayers.Geometry.LineString;\n        else if (this.geometryType == \"linearring\")\n            geomType = OpenLayers.Geometry.LinearRing;\n        else if (this.geometryType == \"multipoint\")\n            geomType = OpenLayers.Geometry.MultiPoint;\n        else if (this.geometryType != \"point\" && this.geometryType != \"polygon\")\n            return null;\n\n        var flatPoints = this.decodeDeltas(encoded, 2);\n        var flatPointsLength = flatPoints.length;\n\n        var pointGeometries = [];\n        for (var i = 0; i + 1 < flatPointsLength;) {\n            var y = flatPoints[i++], x = flatPoints[i++];\n            pointGeometries.push(new OpenLayers.Geometry.Point(x, y));\n        }\n\n\n        if (this.geometryType == \"point\")\n            return new OpenLayers.Feature.Vector(\n                pointGeometries[0]\n            );\n\n        if (this.geometryType == \"polygon\")\n            return new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.Polygon([\n                    new OpenLayers.Geometry.LinearRing(pointGeometries)\n                ])\n            );\n\n        return new OpenLayers.Feature.Vector(\n            new geomType(pointGeometries)\n        );\n    },\n\n        decode: function(encoded, dims, opt_factor) {\n        var factor = opt_factor || 1e5;\n        var flatPoints = this.decodeDeltas(encoded, dims, factor);\n        var flatPointsLength = flatPoints.length;\n\n        var points = [];\n        for (var i = 0; i + (dims - 1) < flatPointsLength;) {\n            var point = [];\n\n            for (var dim = 0; dim < dims; ++dim) {\n                point.push(flatPoints[i++])\n            }\n\n            points.push(point);\n        }\n\n        return points;\n    },\n\n        write: function(features) {\n        var feature;\n        if (features.constructor == Array)\n            feature = features[0];\n        else\n            feature = features;\n\n        var geometry = feature.geometry;\n        var type = geometry.CLASS_NAME.split('.')[2].toLowerCase();\n\n        var pointGeometries;\n        if (type == \"point\")\n            pointGeometries = new Array(geometry);\n        else if (type == \"linestring\" ||\n                 type == \"linearring\" ||\n                 type == \"multipoint\")\n            pointGeometries = geometry.components;\n        else if (type == \"polygon\")\n            pointGeometries = geometry.components[0].components;\n        else\n            return null;\n\n        var flatPoints = [];\n\n        var pointGeometriesLength = pointGeometries.length;\n        for (var i = 0; i < pointGeometriesLength; ++i) {\n            var pointGeometry = pointGeometries[i];\n            flatPoints.push(pointGeometry.y);\n            flatPoints.push(pointGeometry.x);\n        }\n\n        return this.encodeDeltas(flatPoints, 2);\n    },\n\n        encode: function (points, dims, opt_factor) {\n        var factor = opt_factor || 1e5;\n        var flatPoints = [];\n\n        var pointsLength = points.length;\n        for (var i = 0; i < pointsLength; ++i) {\n            var point = points[i];\n\n            for (var dim = 0; dim < dims; ++dim) {\n                flatPoints.push(point[dim]);\n            }\n        }\n\n        return this.encodeDeltas(flatPoints, dims, factor);\n    },\n\n        encodeDeltas: function(numbers, dimension, opt_factor) {\n      var factor = opt_factor || 1e5;\n      var d;\n\n      var lastNumbers = new Array(dimension);\n      for (d = 0; d < dimension; ++d) {\n        lastNumbers[d] = 0;\n      }\n\n      var numbersLength = numbers.length;\n      for (var i = 0; i < numbersLength;) {\n        for (d = 0; d < dimension; ++d, ++i) {\n          var num = numbers[i];\n          var delta = num - lastNumbers[d];\n          lastNumbers[d] = num;\n\n          numbers[i] = delta;\n        }\n      }\n\n      return this.encodeFloats(numbers, factor);\n    },\n\n\n        decodeDeltas: function(encoded, dimension, opt_factor) {\n      var factor = opt_factor || 1e5;\n      var d;\n\n      var lastNumbers = new Array(dimension);\n      for (d = 0; d < dimension; ++d) {\n        lastNumbers[d] = 0;\n      }\n\n      var numbers = this.decodeFloats(encoded, factor);\n\n      var numbersLength = numbers.length;\n      for (var i = 0; i < numbersLength;) {\n        for (d = 0; d < dimension; ++d, ++i) {\n          lastNumbers[d] += numbers[i];\n\n          numbers[i] = lastNumbers[d];\n        }\n      }\n\n      return numbers;\n    },\n\n\n        encodeFloats: function(numbers, opt_factor) {\n      var factor = opt_factor || 1e5;\n\n      var numbersLength = numbers.length;\n      for (var i = 0; i < numbersLength; ++i) {\n        numbers[i] = Math.round(numbers[i] * factor);\n      }\n\n      return this.encodeSignedIntegers(numbers);\n    },\n\n\n        decodeFloats: function(encoded, opt_factor) {\n      var factor = opt_factor || 1e5;\n\n      var numbers = this.decodeSignedIntegers(encoded);\n\n      var numbersLength = numbers.length;\n      for (var i = 0; i < numbersLength; ++i) {\n        numbers[i] /= factor;\n      }\n\n      return numbers;\n    },\n\n\n        encodeSignedIntegers: function(numbers) {\n      var numbersLength = numbers.length;\n      for (var i = 0; i < numbersLength; ++i) {\n        var num = numbers[i];\n\n        var signedNum = num << 1;\n        if (num < 0) {\n          signedNum = ~(signedNum);\n        }\n\n        numbers[i] = signedNum;\n      }\n\n      return this.encodeUnsignedIntegers(numbers);\n    },\n\n\n        decodeSignedIntegers: function(encoded) {\n      var numbers = this.decodeUnsignedIntegers(encoded);\n\n      var numbersLength = numbers.length;\n      for (var i = 0; i < numbersLength; ++i) {\n        var num = numbers[i];\n        numbers[i] = (num & 1) ? ~(num >> 1) : (num >> 1);\n      }\n\n      return numbers;\n    },\n\n\n        encodeUnsignedIntegers: function(numbers) {\n      var encoded = '';\n\n      var numbersLength = numbers.length;\n      for (var i = 0; i < numbersLength; ++i) {\n        encoded += this.encodeUnsignedInteger(numbers[i]);\n      }\n\n      return encoded;\n    },\n\n\n        decodeUnsignedIntegers: function(encoded) {\n      var numbers = [];\n\n      var current = 0;\n      var shift = 0;\n\n      var encodedLength = encoded.length;\n      for (var i = 0; i < encodedLength; ++i) {\n        var b = encoded.charCodeAt(i) - 63;\n\n        current |= (b & 0x1f) << shift;\n\n        if (b < 0x20) {\n          numbers.push(current);\n          current = 0;\n          shift = 0;\n        } else {\n          shift += 5;\n        }\n      }\n\n      return numbers;\n    },\n\n\n        encodeFloat: function(num, opt_factor) {\n      num = Math.round(num * (opt_factor || 1e5));\n      return this.encodeSignedInteger(num);\n    },\n\n\n        decodeFloat: function(encoded, opt_factor) {\n      var result = this.decodeSignedInteger(encoded);\n      return result / (opt_factor || 1e5);\n    },\n\n\n        encodeSignedInteger: function(num) {\n      var signedNum = num << 1;\n      if (num < 0) {\n        signedNum = ~(signedNum);\n      }\n\n      return this.encodeUnsignedInteger(signedNum);\n    },\n\n\n        decodeSignedInteger: function(encoded) {\n      var result = this.decodeUnsignedInteger(encoded);\n      return ((result & 1) ? ~(result >> 1) : (result >> 1));\n    },\n\n\n        encodeUnsignedInteger: function(num) {\n      var value, encoded = '';\n      while (num >= 0x20) {\n        value = (0x20 | (num & 0x1f)) + 63;\n        encoded += (String.fromCharCode(value));\n        num >>= 5;\n      }\n      value = num + 63;\n      encoded += (String.fromCharCode(value));\n      return encoded;\n    },\n\n\n        decodeUnsignedInteger: function(encoded) {\n      var result = 0;\n      var shift = 0;\n\n      var encodedLength = encoded.length;\n      for (var i = 0; i < encodedLength; ++i) {\n        var b = encoded.charCodeAt(i) - 63;\n\n        result |= (b & 0x1f) << shift;\n\n        if (b < 0x20)\n          break;\n\n        shift += 5;\n      }\n\n      return result;\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.EncodedPolyline\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/Filter/v1.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\nOpenLayers.Format.Filter.v1 = OpenLayers.Class(OpenLayers.Format.XML, {\n    \n        namespaces: {\n        ogc: \"http://www.opengis.net/ogc\",\n        gml: \"http://www.opengis.net/gml\",\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\"\n    },\n\n        defaultPrefix: \"ogc\",\n\n        schemaLocation: null,\n    \n        initialize: function(options) {\n        OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);\n    },\n    \n        read: function(data) {\n        var obj = {};\n        this.readers.ogc[\"Filter\"].apply(this, [data, obj]);\n        return obj.filter;\n    },\n    \n        readers: {\n        \"ogc\": {\n            \"_expression\": function(node) {\n                var obj, value = \"\";\n                for(var child=node.firstChild; child; child=child.nextSibling) {\n                    switch(child.nodeType) {\n                        case 1:\n                            obj = this.readNode(child);\n                            if (obj.property) {\n                                value += \"${\" + obj.property + \"}\";\n                            } else if (obj.value !== undefined) {\n                                value += obj.value;\n                            }\n                            break;\n                        case 3: // text node\n                        case 4: // cdata section\n                            value += child.nodeValue;\n                    }\n                }\n                return value;\n            },\n            \"Filter\": function(node, parent) {\n                var obj = {\n                    fids: [],\n                    filters: []\n                };\n                this.readChildNodes(node, obj);\n                if(obj.fids.length > 0) {\n                    parent.filter = new OpenLayers.Filter.FeatureId({\n                        fids: obj.fids\n                    });\n                } else if(obj.filters.length > 0) {\n                    parent.filter = obj.filters[0];\n                }\n            },\n            \"FeatureId\": function(node, obj) {\n                var fid = node.getAttribute(\"fid\");\n                if(fid) {\n                    obj.fids.push(fid);\n                }\n            },\n            \"And\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Logical({\n                    type: OpenLayers.Filter.Logical.AND\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"Or\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Logical({\n                    type: OpenLayers.Filter.Logical.OR\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"Not\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Logical({\n                    type: OpenLayers.Filter.Logical.NOT\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"PropertyIsLessThan\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.LESS_THAN\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"PropertyIsGreaterThan\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.GREATER_THAN\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"PropertyIsLessThanOrEqualTo\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"PropertyIsGreaterThanOrEqualTo\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"PropertyIsBetween\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.BETWEEN\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"Literal\": function(node, obj) {\n                obj.value = OpenLayers.String.numericIf(\n                    this.getChildValue(node), true);\n            },\n            \"PropertyName\": function(node, filter) {\n                filter.property = this.getChildValue(node);\n            },\n            \"LowerBoundary\": function(node, filter) {\n                filter.lowerBoundary = OpenLayers.String.numericIf(\n                    this.readers.ogc._expression.call(this, node), true);\n            },\n            \"UpperBoundary\": function(node, filter) {\n                filter.upperBoundary = OpenLayers.String.numericIf(\n                    this.readers.ogc._expression.call(this, node), true);\n            },\n            \"Intersects\": function(node, obj) {\n                this.readSpatial(node, obj, OpenLayers.Filter.Spatial.INTERSECTS);\n            },\n            \"Within\": function(node, obj) {\n                this.readSpatial(node, obj, OpenLayers.Filter.Spatial.WITHIN);\n            },\n            \"Contains\": function(node, obj) {\n                this.readSpatial(node, obj, OpenLayers.Filter.Spatial.CONTAINS);\n            },\n            \"DWithin\": function(node, obj) {\n                this.readSpatial(node, obj, OpenLayers.Filter.Spatial.DWITHIN);\n            },\n            \"Distance\": function(node, obj) {\n                obj.distance = parseInt(this.getChildValue(node));\n                obj.distanceUnits = node.getAttribute(\"units\");\n            },\n            \"Function\": function(node, obj) {\n                return;\n            },\n            \"PropertyIsNull\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.IS_NULL\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            }\n        }\n    },\n    \n        readSpatial: function(node, obj, type) {\n        var filter = new OpenLayers.Filter.Spatial({\n            type: type\n        });\n        this.readChildNodes(node, filter);\n        filter.value = filter.components[0];\n        delete filter.components;\n        obj.filters.push(filter);\n    },\n\n        encodeLiteral: function(value) {\n        if (value instanceof Date) {\n            value = OpenLayers.Date.toISOString(value);\n        }\n        return value;\n    },\n\n        writeOgcExpression: function(value, node) {\n        if (value instanceof OpenLayers.Filter.Function){\n            this.writeNode(\"Function\", value, node);\n        } else {\n            this.writeNode(\"Literal\", value, node);\n        }\n        return node;\n    },    \n    \n        write: function(filter) {\n        return this.writers.ogc[\"Filter\"].apply(this, [filter]);\n    },\n    \n        writers: {\n        \"ogc\": {\n            \"Filter\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:Filter\");\n                this.writeNode(this.getFilterType(filter), filter, node);\n                return node;\n            },\n            \"_featureIds\": function(filter) {\n                var node = this.createDocumentFragment();\n                for (var i=0, ii=filter.fids.length; i<ii; ++i) {\n                    this.writeNode(\"ogc:FeatureId\", filter.fids[i], node);\n                }\n                return node;\n            },\n            \"FeatureId\": function(fid) {\n                return this.createElementNSPlus(\"ogc:FeatureId\", {\n                    attributes: {fid: fid}\n                });\n            },\n            \"And\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:And\");\n                var childFilter;\n                for (var i=0, ii=filter.filters.length; i<ii; ++i) {\n                    childFilter = filter.filters[i];\n                    this.writeNode(\n                        this.getFilterType(childFilter), childFilter, node\n                    );\n                }\n                return node;\n            },\n            \"Or\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:Or\");\n                var childFilter;\n                for (var i=0, ii=filter.filters.length; i<ii; ++i) {\n                    childFilter = filter.filters[i];\n                    this.writeNode(\n                        this.getFilterType(childFilter), childFilter, node\n                    );\n                }\n                return node;\n            },\n            \"Not\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:Not\");\n                var childFilter = filter.filters[0];\n                this.writeNode(\n                    this.getFilterType(childFilter), childFilter, node\n                );\n                return node;\n            },\n            \"PropertyIsLessThan\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:PropertyIsLessThan\");\n                this.writeNode(\"PropertyName\", filter, node);\n                this.writeOgcExpression(filter.value, node);\n                return node;\n            },\n            \"PropertyIsGreaterThan\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:PropertyIsGreaterThan\");\n                this.writeNode(\"PropertyName\", filter, node);\n                this.writeOgcExpression(filter.value, node);\n                return node;\n            },\n            \"PropertyIsLessThanOrEqualTo\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:PropertyIsLessThanOrEqualTo\");\n                this.writeNode(\"PropertyName\", filter, node);\n                this.writeOgcExpression(filter.value, node);\n                return node;\n            },\n            \"PropertyIsGreaterThanOrEqualTo\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:PropertyIsGreaterThanOrEqualTo\");\n                this.writeNode(\"PropertyName\", filter, node);\n                this.writeOgcExpression(filter.value, node);\n                return node;\n            },\n            \"PropertyIsBetween\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:PropertyIsBetween\");\n                this.writeNode(\"PropertyName\", filter, node);\n                this.writeNode(\"LowerBoundary\", filter, node);\n                this.writeNode(\"UpperBoundary\", filter, node);\n                return node;\n            },\n            \"PropertyName\": function(filter) {\n                return this.createElementNSPlus(\"ogc:PropertyName\", {\n                    value: filter.property\n                });\n            },\n            \"Literal\": function(value) {\n                var encode = this.encodeLiteral ||\n                    OpenLayers.Format.Filter.v1.prototype.encodeLiteral;\n                return this.createElementNSPlus(\"ogc:Literal\", {\n                    value: encode(value)\n                });\n            },\n            \"LowerBoundary\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:LowerBoundary\");\n                this.writeOgcExpression(filter.lowerBoundary, node);\n                return node;\n            },\n            \"UpperBoundary\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:UpperBoundary\");\n                this.writeNode(\"Literal\", filter.upperBoundary, node);\n                return node;\n            },\n            \"INTERSECTS\": function(filter) {\n                return this.writeSpatial(filter, \"Intersects\");\n            },\n            \"WITHIN\": function(filter) {\n                return this.writeSpatial(filter, \"Within\");\n            },\n            \"CONTAINS\": function(filter) {\n                return this.writeSpatial(filter, \"Contains\");\n            },\n            \"DWITHIN\": function(filter) {\n                var node = this.writeSpatial(filter, \"DWithin\");\n                this.writeNode(\"Distance\", filter, node);\n                return node;\n            },\n            \"Distance\": function(filter) {\n                return this.createElementNSPlus(\"ogc:Distance\", {\n                    attributes: {\n                        units: filter.distanceUnits\n                    },\n                    value: filter.distance\n                });\n            },\n            \"Function\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:Function\", {\n                    attributes: {\n                        name: filter.name\n                    }\n                });\n                var params = filter.params;\n                for(var i=0, len=params.length; i<len; i++){\n                    this.writeOgcExpression(params[i], node);\n                }\n                return node;\n            },\n            \"PropertyIsNull\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:PropertyIsNull\");\n                this.writeNode(\"PropertyName\", filter, node);\n                return node;\n            }\n        }\n    },\n\n        getFilterType: function(filter) {\n        var filterType = this.filterMap[filter.type];\n        if(!filterType) {\n            throw \"Filter writing not supported for rule type: \" + filter.type;\n        }\n        return filterType;\n    },\n    \n        filterMap: {\n        \"&&\": \"And\",\n        \"||\": \"Or\",\n        \"!\": \"Not\",\n        \"==\": \"PropertyIsEqualTo\",\n        \"!=\": \"PropertyIsNotEqualTo\",\n        \"<\": \"PropertyIsLessThan\",\n        \">\": \"PropertyIsGreaterThan\",\n        \"<=\": \"PropertyIsLessThanOrEqualTo\",\n        \">=\": \"PropertyIsGreaterThanOrEqualTo\",\n        \"..\": \"PropertyIsBetween\",\n        \"~\": \"PropertyIsLike\",\n        \"NULL\": \"PropertyIsNull\",\n        \"BBOX\": \"BBOX\",\n        \"DWITHIN\": \"DWITHIN\",\n        \"WITHIN\": \"WITHIN\",\n        \"CONTAINS\": \"CONTAINS\",\n        \"INTERSECTS\": \"INTERSECTS\",\n        \"FID\": \"_featureIds\"\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.Filter.v1\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/Filter/v1_0_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.Filter.v1_0_0 = OpenLayers.Class(\n    OpenLayers.Format.GML.v2, OpenLayers.Format.Filter.v1, {\n    \n        VERSION: \"1.0.0\",\n    \n        schemaLocation: \"http://www.opengis.net/ogc/filter/1.0.0/filter.xsd\",\n\n        initialize: function(options) {\n        OpenLayers.Format.GML.v2.prototype.initialize.apply(\n            this, [options]\n        );\n    },\n\n        readers: {\n        \"ogc\": OpenLayers.Util.applyDefaults({\n            \"PropertyIsEqualTo\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.EQUAL_TO\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"PropertyIsNotEqualTo\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"PropertyIsLike\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.LIKE\n                });\n                this.readChildNodes(node, filter);\n                var wildCard = node.getAttribute(\"wildCard\");\n                var singleChar = node.getAttribute(\"singleChar\");\n                var esc = node.getAttribute(\"escape\");\n                filter.value2regex(wildCard, singleChar, esc);\n                obj.filters.push(filter);\n            }\n        }, OpenLayers.Format.Filter.v1.prototype.readers[\"ogc\"]),\n        \"gml\": OpenLayers.Format.GML.v2.prototype.readers[\"gml\"],\n        \"feature\": OpenLayers.Format.GML.v2.prototype.readers[\"feature\"]        \n    },\n\n        writers: {\n        \"ogc\": OpenLayers.Util.applyDefaults({\n            \"PropertyIsEqualTo\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:PropertyIsEqualTo\");\n                this.writeNode(\"PropertyName\", filter, node);\n                this.writeOgcExpression(filter.value, node);\n                return node;\n            },\n            \"PropertyIsNotEqualTo\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:PropertyIsNotEqualTo\");\n                this.writeNode(\"PropertyName\", filter, node);\n                this.writeOgcExpression(filter.value, node);\n                return node;\n            },\n            \"PropertyIsLike\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:PropertyIsLike\", {\n                    attributes: {\n                        wildCard: \"*\", singleChar: \".\", escape: \"!\"\n                    }\n                });\n                this.writeNode(\"PropertyName\", filter, node);\n                this.writeNode(\"Literal\", filter.regex2value(), node);\n                return node;\n            },\n            \"BBOX\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:BBOX\");\n                filter.property && this.writeNode(\"PropertyName\", filter, node);\n                var box = this.writeNode(\"gml:Box\", filter.value, node);\n                if(filter.projection) {\n                    box.setAttribute(\"srsName\", filter.projection);\n                }\n                return node;\n            }\n        }, OpenLayers.Format.Filter.v1.prototype.writers[\"ogc\"]),\n        \"gml\": OpenLayers.Format.GML.v2.prototype.writers[\"gml\"],\n        \"feature\": OpenLayers.Format.GML.v2.prototype.writers[\"feature\"]\n    },\n\n        writeSpatial: function(filter, name) {\n        var node = this.createElementNSPlus(\"ogc:\"+name);\n        this.writeNode(\"PropertyName\", filter, node);\n        if(filter.value instanceof OpenLayers.Filter.Function) {\n            this.writeNode(\"Function\", filter.value, node);\n        } else {\n        var child;\n        if(filter.value instanceof OpenLayers.Geometry) {\n            child = this.writeNode(\"feature:_geometry\", filter.value).firstChild;\n        } else {\n            child = this.writeNode(\"gml:Box\", filter.value);\n        }\n        if(filter.projection) {\n            child.setAttribute(\"srsName\", filter.projection);\n        }\n        node.appendChild(child);\n        }\n        return node;\n    },\n\n\n    CLASS_NAME: \"OpenLayers.Format.Filter.v1_0_0\" \n\n});"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/Filter/v1_1_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.Filter.v1_1_0 = OpenLayers.Class(\n    OpenLayers.Format.GML.v3, OpenLayers.Format.Filter.v1, {\n    \n        VERSION: \"1.1.0\",\n    \n        schemaLocation: \"http://www.opengis.net/ogc/filter/1.1.0/filter.xsd\",\n\n        initialize: function(options) {\n        OpenLayers.Format.GML.v3.prototype.initialize.apply(\n            this, [options]\n        );\n    },\n\n        readers: {\n        \"ogc\": OpenLayers.Util.applyDefaults({\n            \"PropertyIsEqualTo\": function(node, obj) {\n                var matchCase = node.getAttribute(\"matchCase\");\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                    matchCase: !(matchCase === \"false\" || matchCase === \"0\")\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"PropertyIsNotEqualTo\": function(node, obj) {\n                var matchCase = node.getAttribute(\"matchCase\");\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,\n                    matchCase: !(matchCase === \"false\" || matchCase === \"0\")\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"PropertyIsLike\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.LIKE\n                });\n                this.readChildNodes(node, filter);\n                var wildCard = node.getAttribute(\"wildCard\");\n                var singleChar = node.getAttribute(\"singleChar\");\n                var esc = node.getAttribute(\"escapeChar\");\n                filter.value2regex(wildCard, singleChar, esc);\n                obj.filters.push(filter);\n            }\n        }, OpenLayers.Format.Filter.v1.prototype.readers[\"ogc\"]),\n        \"gml\": OpenLayers.Format.GML.v3.prototype.readers[\"gml\"],\n        \"feature\": OpenLayers.Format.GML.v3.prototype.readers[\"feature\"]        \n    },\n\n        writers: {\n        \"ogc\": OpenLayers.Util.applyDefaults({\n            \"PropertyIsEqualTo\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:PropertyIsEqualTo\", {\n                    attributes: {matchCase: filter.matchCase}\n                });\n                this.writeNode(\"PropertyName\", filter, node);\n                this.writeOgcExpression(filter.value, node);\n                return node;\n            },\n            \"PropertyIsNotEqualTo\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:PropertyIsNotEqualTo\", {\n                    attributes: {matchCase: filter.matchCase}\n                });\n                this.writeNode(\"PropertyName\", filter, node);\n                this.writeOgcExpression(filter.value, node);\n                return node;\n            },\n            \"PropertyIsLike\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:PropertyIsLike\", {\n                    attributes: {\n                        matchCase: filter.matchCase,\n                        wildCard: \"*\", singleChar: \".\", escapeChar: \"!\"\n                    }\n                });\n                this.writeNode(\"PropertyName\", filter, node);\n                this.writeNode(\"Literal\", filter.regex2value(), node);\n                return node;\n            },\n            \"BBOX\": function(filter) {\n                var node = this.createElementNSPlus(\"ogc:BBOX\");\n                filter.property && this.writeNode(\"PropertyName\", filter, node);\n                var box = this.writeNode(\"gml:Envelope\", filter.value);\n                if(filter.projection) {\n                    box.setAttribute(\"srsName\", filter.projection);\n                }\n                node.appendChild(box); \n                return node;\n            },\n            \"SortBy\": function(sortProperties) {\n                var node = this.createElementNSPlus(\"ogc:SortBy\");\n                for (var i=0,l=sortProperties.length;i<l;i++) {\n                    this.writeNode(\n                        \"ogc:SortProperty\",\n                        sortProperties[i],\n                        node\n                    );\n                }\n                return node;\n            }, \n            \"SortProperty\": function(sortProperty) {\n                var node = this.createElementNSPlus(\"ogc:SortProperty\");\n                this.writeNode(\n                    \"ogc:PropertyName\",\n                    sortProperty,\n                    node\n                );\n                this.writeNode(\n                    \"ogc:SortOrder\",\n                    (sortProperty.order == 'DESC') ? 'DESC' : 'ASC',\n                    node\n                );\n                return node;\n            },\n            \"SortOrder\": function(value) {\n                var node = this.createElementNSPlus(\"ogc:SortOrder\", {\n                    value: value\n                });\n                return node;\n            }\n        }, OpenLayers.Format.Filter.v1.prototype.writers[\"ogc\"]),\n        \"gml\": OpenLayers.Format.GML.v3.prototype.writers[\"gml\"],\n        \"feature\": OpenLayers.Format.GML.v3.prototype.writers[\"feature\"]\n    },\n\n        writeSpatial: function(filter, name) {\n        var node = this.createElementNSPlus(\"ogc:\"+name);\n        this.writeNode(\"PropertyName\", filter, node);\n        if(filter.value instanceof OpenLayers.Filter.Function) {\n            this.writeNode(\"Function\", filter.value, node);\n        } else {\n        var child;\n        if(filter.value instanceof OpenLayers.Geometry) {\n            child = this.writeNode(\"feature:_geometry\", filter.value).firstChild;\n        } else {\n            child = this.writeNode(\"gml:Envelope\", filter.value);\n        }\n        if(filter.projection) {\n            child.setAttribute(\"srsName\", filter.projection);\n        }\n        node.appendChild(child);\n        }\n        return node;\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.Filter.v1_1_0\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/Filter/v2.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\nOpenLayers.Format.Filter.v2 = OpenLayers.Class(OpenLayers.Format.XML, {\n    \n        namespaces: {\n        fes: \"http://www.opengis.net/fes/2.0\",\n        gml: \"http://www.opengis.net/gml/3.2\",\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\"\n    },\n\n        defaultPrefix: \"fes\",\n\n        schemaLocation: null,\n    \n        initialize: function(options) {\n        OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);\n    },\n    \n        read: function(data) {\n        var obj = {};\n        this.readers.fes[\"Filter\"].apply(this, [data, obj]);\n        return obj.filter;\n    },\n    \n        readers: {\n        \"fes\": {\n            \"_expression\": function(node) {\n                var obj, value = \"\";\n                for(var child=node.firstChild; child; child=child.nextSibling) {\n                    switch(child.nodeType) {\n                        case 1:\n                            obj = this.readNode(child);\n                            if (obj.property) {\n                                value += \"${\" + obj.property + \"}\";\n                            } else if (obj.value !== undefined) {\n                                value += obj.value;\n                            }\n                            break;\n                        case 3: // text node\n                        case 4: // cdata section\n                            value += child.nodeValue;\n                    }\n                }\n                return value;\n            },\n            \"Filter\": function(node, parent) {\n                var obj = {\n                    fids: [],\n                    filters: []\n                };\n                this.readChildNodes(node, obj);\n                if(obj.fids.length > 0) {\n                    parent.filter = new OpenLayers.Filter.FeatureId({\n                        fids: obj.fids\n                    });\n                } else if(obj.filters.length > 0) {\n                    parent.filter = obj.filters[0];\n                }\n            },\n            \"ResourceId\": function(node, obj) {\n                var fid = node.getAttribute(\"rid\");\n                if(fid) {\n                    obj.fids.push(fid);\n                }\n            },\n\n            \"And\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Logical({\n                    type: OpenLayers.Filter.Logical.AND\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"Or\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Logical({\n                    type: OpenLayers.Filter.Logical.OR\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"Not\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Logical({\n                    type: OpenLayers.Filter.Logical.NOT\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"PropertyIsLessThan\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.LESS_THAN\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"PropertyIsGreaterThan\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.GREATER_THAN\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"PropertyIsLessThanOrEqualTo\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"PropertyIsGreaterThanOrEqualTo\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"PropertyIsBetween\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.BETWEEN\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"Literal\": function(node, obj) {\n                obj.value = OpenLayers.String.numericIf(\n                    this.getChildValue(node), true);\n            },\n            \"ValueReference\": function(node, filter) {\n                filter.property = this.getChildValue(node);\n            },\n            \"LowerBoundary\": function(node, filter) {\n                filter.lowerBoundary = OpenLayers.String.numericIf(\n                    this.readers.fes._expression.call(this, node), true);\n            },\n            \"UpperBoundary\": function(node, filter) {\n                filter.upperBoundary = OpenLayers.String.numericIf(\n                    this.readers.fes._expression.call(this, node), true);\n            },\n            \"Intersects\": function(node, obj) {\n                this.readSpatial(node, obj, OpenLayers.Filter.Spatial.INTERSECTS);\n            },\n            \"Within\": function(node, obj) {\n                this.readSpatial(node, obj, OpenLayers.Filter.Spatial.WITHIN);\n            },\n            \"Contains\": function(node, obj) {\n                this.readSpatial(node, obj, OpenLayers.Filter.Spatial.CONTAINS);\n            },\n            \"DWithin\": function(node, obj) {\n                this.readSpatial(node, obj, OpenLayers.Filter.Spatial.DWITHIN);\n            },\n            \"Distance\": function(node, obj) {\n                obj.distance = parseInt(this.getChildValue(node));\n                obj.distanceUnits = node.getAttribute(\"units\");\n            },\n            \"Function\": function(node, obj) {\n                return;\n            },\n            \"PropertyIsNull\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.IS_NULL\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            }\n        }\n    },\n    \n        readSpatial: function(node, obj, type) {\n        var filter = new OpenLayers.Filter.Spatial({\n            type: type\n        });\n        this.readChildNodes(node, filter);\n        filter.value = filter.components[0];\n        delete filter.components;\n        obj.filters.push(filter);\n    },\n\n        encodeLiteral: function(value) {\n        if (value instanceof Date) {\n            value = OpenLayers.Date.toISOString(value);\n        }\n        return value;\n    },\n\n        writeOgcExpression: function(value, node) {\n        if (value instanceof OpenLayers.Filter.Function){\n            this.writeNode(\"Function\", value, node);\n        } else {\n            this.writeNode(\"Literal\", value, node);\n        }\n        return node;\n    },    \n    \n        write: function(filter) {\n        return this.writers.fes[\"Filter\"].apply(this, [filter]);\n    },\n    \n        writers: {\n        \"fes\": {\n            \"Filter\": function(filter) {\n                var node = this.createElementNSPlus(\"fes:Filter\");\n                this.writeNode(this.getFilterType(filter), filter, node);\n                return node;\n            },\n            \"_featureIds\": function(filter) {\n                var node = this.createDocumentFragment();\n                for (var i=0, ii=filter.fids.length; i<ii; ++i) {\n                    this.writeNode(\"fes:ResourceId\", filter.fids[i], node);\n                }\n                return node;\n            },\n            \"ResourceId\": function(fid) {\n                return this.createElementNSPlus(\"fes:ResourceId\", {\n                    attributes: {rid: fid}\n                });\n            },\n\n            \"And\": function(filter) {\n                var node = this.createElementNSPlus(\"fes:And\");\n                var childFilter;\n                for (var i=0, ii=filter.filters.length; i<ii; ++i) {\n                    childFilter = filter.filters[i];\n                    this.writeNode(\n                        this.getFilterType(childFilter), childFilter, node\n                    );\n                }\n                return node;\n            },\n            \"Or\": function(filter) {\n                var node = this.createElementNSPlus(\"fes:Or\");\n                var childFilter;\n                for (var i=0, ii=filter.filters.length; i<ii; ++i) {\n                    childFilter = filter.filters[i];\n                    this.writeNode(\n                        this.getFilterType(childFilter), childFilter, node\n                    );\n                }\n                return node;\n            },\n            \"Not\": function(filter) {\n                var node = this.createElementNSPlus(\"fes:Not\");\n                var childFilter = filter.filters[0];\n                this.writeNode(\n                    this.getFilterType(childFilter), childFilter, node\n                );\n                return node;\n            },\n            \"PropertyIsLessThan\": function(filter) {\n                var node = this.createElementNSPlus(\"fes:PropertyIsLessThan\");\n                this.writeNode(\"ValueReference\", filter, node);\n                this.writeOgcExpression(filter.value, node);\n                return node;\n            },\n            \"PropertyIsGreaterThan\": function(filter) {\n                var node = this.createElementNSPlus(\"fes:PropertyIsGreaterThan\");\n                this.writeNode(\"ValueReference\", filter, node);\n                this.writeOgcExpression(filter.value, node);\n                return node;\n            },\n            \"PropertyIsLessThanOrEqualTo\": function(filter) {\n                var node = this.createElementNSPlus(\"fes:PropertyIsLessThanOrEqualTo\");\n                this.writeNode(\"ValueReference\", filter, node);\n                this.writeOgcExpression(filter.value, node);\n                return node;\n            },\n            \"PropertyIsGreaterThanOrEqualTo\": function(filter) {\n                var node = this.createElementNSPlus(\"fes:PropertyIsGreaterThanOrEqualTo\");\n                this.writeNode(\"ValueReference\", filter, node);\n                this.writeOgcExpression(filter.value, node);\n                return node;\n            },\n            \"PropertyIsBetween\": function(filter) {\n                var node = this.createElementNSPlus(\"fes:PropertyIsBetween\");\n                this.writeNode(\"ValueReference\", filter, node);\n                this.writeNode(\"LowerBoundary\", filter, node);\n                this.writeNode(\"UpperBoundary\", filter, node);\n                return node;\n            },\n            \"ValueReference\": function(filter) {\n                return this.createElementNSPlus(\"fes:ValueReference\", {\n                    value: filter.property\n                });\n            },\n            \"Literal\": function(value) {\n                var encode = this.encodeLiteral ||\n                    OpenLayers.Format.Filter.v1.prototype.encodeLiteral;\n                return this.createElementNSPlus(\"fes:Literal\", {\n                    value: encode(value)\n                });\n            },\n            \"LowerBoundary\": function(filter) {\n                var node = this.createElementNSPlus(\"fes:LowerBoundary\");\n                this.writeOgcExpression(filter.lowerBoundary, node);\n                return node;\n            },\n            \"UpperBoundary\": function(filter) {\n                var node = this.createElementNSPlus(\"fes:UpperBoundary\");\n                this.writeNode(\"Literal\", filter.upperBoundary, node);\n                return node;\n            },\n            \"INTERSECTS\": function(filter) {\n                return this.writeSpatial(filter, \"Intersects\");\n            },\n            \"WITHIN\": function(filter) {\n                return this.writeSpatial(filter, \"Within\");\n            },\n            \"CONTAINS\": function(filter) {\n                return this.writeSpatial(filter, \"Contains\");\n            },\n            \"DWITHIN\": function(filter) {\n                var node = this.writeSpatial(filter, \"DWithin\");\n                this.writeNode(\"Distance\", filter, node);\n                return node;\n            },\n            \"Distance\": function(filter) {\n                return this.createElementNSPlus(\"fes:Distance\", {\n                    attributes: {\n                        units: filter.distanceUnits\n                    },\n                    value: filter.distance\n                });\n            },\n            \"Function\": function(filter) {\n                var node = this.createElementNSPlus(\"fes:Function\", {\n                    attributes: {\n                        name: filter.name\n                    }\n                });\n                var params = filter.params;\n                for(var i=0, len=params.length; i<len; i++){\n                    this.writeOgcExpression(params[i], node);\n                }\n                return node;\n            },\n            \"PropertyIsNull\": function(filter) {\n                var node = this.createElementNSPlus(\"fes:PropertyIsNull\");\n                this.writeNode(\"ValueReference\", filter, node);\n                return node;\n            }\n        }\n    },\n\n        getFilterType: function(filter) {\n        var filterType = this.filterMap[filter.type];\n        if(!filterType) {\n            throw \"Filter writing not supported for rule type: \" + filter.type;\n        }\n        return filterType;\n    },\n    \n        filterMap: {\n        \"&&\": \"And\",\n        \"||\": \"Or\",\n        \"!\": \"Not\",\n        \"==\": \"PropertyIsEqualTo\",\n        \"!=\": \"PropertyIsNotEqualTo\",\n        \"<\": \"PropertyIsLessThan\",\n        \">\": \"PropertyIsGreaterThan\",\n        \"<=\": \"PropertyIsLessThanOrEqualTo\",\n        \">=\": \"PropertyIsGreaterThanOrEqualTo\",\n        \"..\": \"PropertyIsBetween\",\n        \"~\": \"PropertyIsLike\",\n        \"NULL\": \"PropertyIsNull\",\n        \"BBOX\": \"BBOX\",\n        \"DWITHIN\": \"DWITHIN\",\n        \"WITHIN\": \"WITHIN\",\n        \"CONTAINS\": \"CONTAINS\",\n        \"INTERSECTS\": \"INTERSECTS\",\n        \"FID\": \"_featureIds\"\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.Filter.v2\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/Filter/v2_0_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.Filter.v2_0_0 = OpenLayers.Class(\n    OpenLayers.Format.GML.v3, OpenLayers.Format.Filter.v2, {\n    \n        VERSION: \"2.0.0\",\n    \n        schemaLocation: \"http://schemas.opengis.net/filter/2.0/filterAll.xsd\",\n\n        initialize: function(options) {\n        OpenLayers.Format.GML.v3.prototype.initialize.apply(\n            this, [options]\n        );\n    },\n\n        readers: {\n        \"fes\": OpenLayers.Util.applyDefaults({\n            \"PropertyIsEqualTo\": function(node, obj) {\n                var matchCase = node.getAttribute(\"matchCase\");\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                    matchCase: !(matchCase === \"false\" || matchCase === \"0\")\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"PropertyIsNotEqualTo\": function(node, obj) {\n                var matchCase = node.getAttribute(\"matchCase\");\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,\n                    matchCase: !(matchCase === \"false\" || matchCase === \"0\")\n                });\n                this.readChildNodes(node, filter);\n                obj.filters.push(filter);\n            },\n            \"PropertyIsLike\": function(node, obj) {\n                var filter = new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.LIKE\n                });\n                this.readChildNodes(node, filter);\n                var wildCard = node.getAttribute(\"wildCard\");\n                var singleChar = node.getAttribute(\"singleChar\");\n                var esc = node.getAttribute(\"escapeChar\");\n                filter.value2regex(wildCard, singleChar, esc);\n                obj.filters.push(filter);\n            }\n        }, OpenLayers.Format.Filter.v2.prototype.readers[\"fes\"]),\n        \"gml\": OpenLayers.Format.GML.v3.prototype.readers[\"gml\"],\n        \"feature\": OpenLayers.Format.GML.v3.prototype.readers[\"feature\"]\n    },\n\n        writers: {\n        \"fes\": OpenLayers.Util.applyDefaults({\n            \"PropertyIsEqualTo\": function(filter) {\n                var node = this.createElementNSPlus(\"fes:PropertyIsEqualTo\", {\n                    attributes: {matchCase: filter.matchCase}\n                });\n                this.writeNode(\"ValueReference\", filter, node);\n                this.writeOgcExpression(filter.value, node);\n                return node;\n            },\n            \"PropertyIsNotEqualTo\": function(filter) {\n                var node = this.createElementNSPlus(\"fes:PropertyIsNotEqualTo\", {\n                    attributes: {matchCase: filter.matchCase}\n                });\n                this.writeNode(\"ValueReference\", filter, node);\n                this.writeOgcExpression(filter.value, node);\n                return node;\n            },\n            \"PropertyIsLike\": function(filter) {\n                var node = this.createElementNSPlus(\"fes:PropertyIsLike\", {\n                    attributes: {\n                        matchCase: filter.matchCase,\n                        wildCard: \"*\", singleChar: \".\", escapeChar: \"!\"\n                    }\n                });\n                this.writeNode(\"ValueReference\", filter, node);\n                this.writeNode(\"Literal\", filter.regex2value(), node);\n                return node;\n            },\n            \"BBOX\": function(filter) {\n                var node = this.createElementNSPlus(\"fes:BBOX\");\n                filter.property && this.writeNode(\"ValueReference\", filter, node);\n                var box = this.writeNode(\"gml:Envelope\", filter.value);\n                if(filter.projection) {\n                    box.setAttribute(\"srsName\", filter.projection);\n                }\n                node.appendChild(box); \n                return node;\n            },\n            \"SortBy\": function(sortProperties) {\n                var node = this.createElementNSPlus(\"fes:SortBy\");\n                for (var i=0,l=sortProperties.length;i<l;i++) {\n                    this.writeNode(\n                        \"fes:SortProperty\",\n                        sortProperties[i],\n                        node\n                    );\n                }\n                return node;\n            }, \n            \"SortProperty\": function(sortProperty) {\n                var node = this.createElementNSPlus(\"fes:SortProperty\");\n                this.writeNode(\n                    \"fes:ValueReference\",\n                    sortProperty,\n                    node\n                );\n                this.writeNode(\n                    \"fes:SortOrder\",\n                    (sortProperty.order == 'DESC') ? 'DESC' : 'ASC',\n                    node\n                );\n                return node;\n            },\n            \"SortOrder\": function(value) {\n                var node = this.createElementNSPlus(\"fes:SortOrder\", {\n                    value: value\n                });\n                return node;\n            }\n        }, OpenLayers.Format.Filter.v2.prototype.writers[\"fes\"]),\n        \"gml\": OpenLayers.Format.GML.v3.prototype.writers[\"gml\"],\n        \"feature\": OpenLayers.Format.GML.v3.prototype.writers[\"feature\"]\n    },\n\n        writeSpatial: function(filter, name) {\n        var node = this.createElementNSPlus(\"fes:\"+name);\n        this.writeNode(\"ValueReference\", filter, node);\n        if(filter.value instanceof OpenLayers.Filter.Function) {\n            this.writeNode(\"Function\", filter.value, node);\n        } else {\n        var child;\n        if(filter.value instanceof OpenLayers.Geometry) {\n            child = this.writeNode(\"feature:_geometry\", filter.value).firstChild;\n        } else {\n            child = this.writeNode(\"gml:Envelope\", filter.value);\n        }\n        if(filter.projection) {\n            child.setAttribute(\"srsName\", filter.projection);\n        }\n        node.appendChild(child);\n        }\n        return node;\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.Filter.v2_0_0\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/Filter.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.Filter = OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC, {\n    \n        defaultVersion: \"1.0.0\",\n    \n        \n    \n    CLASS_NAME: \"OpenLayers.Format.Filter\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/GML/Base.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nif(!OpenLayers.Format.GML) {\n    OpenLayers.Format.GML = {};\n}\n\nOpenLayers.Format.GML.Base = OpenLayers.Class(OpenLayers.Format.XML, {\n    \n        namespaces: {\n        gml: \"http://www.opengis.net/gml\",\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\",\n        wfs: \"http://www.opengis.net/wfs\" // this is a convenience for reading wfs:FeatureCollection\n    },\n    \n        defaultPrefix: \"gml\",\n\n        schemaLocation: null,\n    \n        featureType: null,\n    \n        featureNS: null,\n\n        featurePrefix: \"feature\",\n\n        geometryName: \"geometry\",\n\n        extractAttributes: true,\n    \n        srsName: null,\n\n        geometryTypes: null,\n\n        singleFeatureType: null,\n    \n    \n        regExes: {\n        trimSpace: (/^\\s*|\\s*$/g),\n        removeSpace: (/\\s*/g),\n        splitSpace: (/\\s+/),\n        trimComma: (/\\s*,\\s*/g),\n        featureMember: (/^(.*:)?featureMembers?$/)\n    },\n\n        initialize: function(options) {\n        OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);\n        this.setGeometryTypes();\n        if(options && options.featureNS) {\n            this.setNamespace(this.featurePrefix, options.featureNS);\n        }\n        this.singleFeatureType = !options || (typeof options.featureType === \"string\");\n    },\n    \n        read: function(data) {\n        if(typeof data == \"string\") { \n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        if(data && data.nodeType == 9) {\n            data = data.documentElement;\n        }\n        var features = [];\n        this.readNode(data, {features: features}, true);\n        if(features.length == 0) {\n            var elements = this.getElementsByTagNameNS(\n                data, this.namespaces.gml, \"featureMember\"\n            );\n            if(elements.length) {\n                for(var i=0, len=elements.length; i<len; ++i) {\n                    this.readNode(elements[i], {features: features}, true);\n                }\n            } else {\n                var elements = this.getElementsByTagNameNS(\n                    data, this.namespaces.gml, \"featureMembers\"\n                );\n                if(elements.length) {\n                    this.readNode(elements[0], {features: features}, true);\n                }\n            }\n        }\n        return features;\n    },\n    \n        readNode: function(node, obj, first) {\n        if (first === true && this.autoConfig === true) {\n            this.featureType = null;\n            delete this.namespaceAlias[this.featureNS];\n            delete this.namespaces[\"feature\"];\n            this.featureNS = null;\n        }\n        if (!this.featureNS && (!(node.prefix in this.namespaces) &&\n                node.parentNode.namespaceURI == this.namespaces[\"gml\"] &&\n                this.regExes.featureMember.test(node.parentNode.nodeName))) {\n            this.featureType = node.nodeName.split(\":\").pop();\n            this.setNamespace(\"feature\", node.namespaceURI);\n            this.featureNS = node.namespaceURI;\n            this.autoConfig = true;\n        }\n        return OpenLayers.Format.XML.prototype.readNode.apply(this, [node, obj]);\n    },\n    \n        readers: {\n        \"gml\": {\n            \"_inherit\": function(node, obj, container) {\n            },\n            \"featureMember\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"featureMembers\": function(node, obj) {\n                this.readChildNodes(node, obj);                \n            },\n            \"name\": function(node, obj) {\n                obj.name = this.getChildValue(node);\n            },\n            \"boundedBy\": function(node, obj) {\n                var container = {};\n                this.readChildNodes(node, container);\n                if(container.components && container.components.length > 0) {\n                    obj.bounds = container.components[0];\n                }\n            },\n            \"Point\": function(node, container) {\n                var obj = {points: []};\n                this.readChildNodes(node, obj);\n                if(!container.components) {\n                    container.components = [];\n                }\n                container.components.push(obj.points[0]);\n            },\n            \"coordinates\": function(node, obj) {\n                var str = this.getChildValue(node).replace(\n                    this.regExes.trimSpace, \"\"\n                );\n                str = str.replace(this.regExes.trimComma, \",\");\n                var pointList = str.split(this.regExes.splitSpace);\n                var coords;\n                var numPoints = pointList.length;\n                var points = new Array(numPoints);\n                for(var i=0; i<numPoints; ++i) {\n                    coords = pointList[i].split(\",\");\n                    if (this.xy) {\n                        points[i] = new OpenLayers.Geometry.Point(\n                            coords[0], coords[1], coords[2]\n                        );\n                    } else {\n                        points[i] = new OpenLayers.Geometry.Point(\n                            coords[1], coords[0], coords[2]\n                        );\n                    }\n                }\n                obj.points = points;\n            },\n            \"coord\": function(node, obj) {\n                var coord = {};\n                this.readChildNodes(node, coord);\n                if(!obj.points) {\n                    obj.points = [];\n                }\n                obj.points.push(new OpenLayers.Geometry.Point(\n                    coord.x, coord.y, coord.z\n                ));\n            },\n            \"X\": function(node, coord) {\n                coord.x = this.getChildValue(node);\n            },\n            \"Y\": function(node, coord) {\n                coord.y = this.getChildValue(node);\n            },\n            \"Z\": function(node, coord) {\n                coord.z = this.getChildValue(node);\n            },\n            \"MultiPoint\": function(node, container) {\n                var obj = {components: []};\n                this.readers.gml._inherit.apply(this, [node, obj, container]);\n                this.readChildNodes(node, obj);\n                container.components = [\n                    new OpenLayers.Geometry.MultiPoint(obj.components)\n                ];\n            },\n            \"pointMember\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"LineString\": function(node, container) {\n                var obj = {};\n                this.readers.gml._inherit.apply(this, [node, obj, container]);\n                this.readChildNodes(node, obj);\n                if(!container.components) {\n                    container.components = [];\n                }\n                container.components.push(\n                    new OpenLayers.Geometry.LineString(obj.points)\n                );\n            },\n            \"MultiLineString\": function(node, container) {\n                var obj = {components: []};\n                this.readers.gml._inherit.apply(this, [node, obj, container]);\n                this.readChildNodes(node, obj);\n                container.components = [\n                    new OpenLayers.Geometry.MultiLineString(obj.components)\n                ];\n            },\n            \"lineStringMember\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"Polygon\": function(node, container) {\n                var obj = {outer: null, inner: []};\n                this.readers.gml._inherit.apply(this, [node, obj, container]);\n                this.readChildNodes(node, obj);\n                obj.inner.unshift(obj.outer);\n                if(!container.components) {\n                    container.components = [];\n                }\n                container.components.push(\n                    new OpenLayers.Geometry.Polygon(obj.inner)\n                );\n            },\n            \"LinearRing\": function(node, obj) {\n                var container = {};\n                this.readers.gml._inherit.apply(this, [node, container]);\n                this.readChildNodes(node, container);\n                obj.components = [new OpenLayers.Geometry.LinearRing(\n                    container.points\n                )];\n            },\n            \"MultiPolygon\": function(node, container) {\n                var obj = {components: []};\n                this.readers.gml._inherit.apply(this, [node, obj, container]);\n                this.readChildNodes(node, obj);\n                container.components = [\n                    new OpenLayers.Geometry.MultiPolygon(obj.components)\n                ];\n            },\n            \"polygonMember\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"GeometryCollection\": function(node, container) {\n                var obj = {components: []};\n                this.readers.gml._inherit.apply(this, [node, obj, container]);\n                this.readChildNodes(node, obj);\n                container.components = [\n                    new OpenLayers.Geometry.Collection(obj.components)\n                ];\n            },\n            \"geometryMember\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            }\n        },\n        \"feature\": {\n            \"*\": function(node, obj) {\n                var name;\n                var local = node.localName || node.nodeName.split(\":\").pop();\n                if (obj.features) {\n                    if (!this.singleFeatureType &&\n                        (OpenLayers.Util.indexOf(this.featureType, local) !== -1)) {\n                        name = \"_typeName\";\n                    } else if(local === this.featureType) {\n                        name = \"_typeName\";\n                    }\n                } else {\n                    if(node.childNodes.length == 0 ||\n                       (node.childNodes.length == 1 && node.firstChild.nodeType == 3)) {\n                        if(this.extractAttributes) {\n                            name = \"_attribute\";\n                        }\n                    } else {\n                        name = \"_geometry\";\n                    }\n                }\n                if(name) {\n                    this.readers.feature[name].apply(this, [node, obj]);\n                }\n            },\n            \"_typeName\": function(node, obj) {\n                var container = {components: [], attributes: {}};\n                this.readChildNodes(node, container);\n                if(container.name) {\n                    container.attributes.name = container.name;\n                }\n                var feature = new OpenLayers.Feature.Vector(\n                    container.components[0], container.attributes\n                );\n                if (!this.singleFeatureType) {\n                    feature.type = node.nodeName.split(\":\").pop();\n                    feature.namespace = node.namespaceURI;\n                }\n                var fid = node.getAttribute(\"fid\") ||\n                    this.getAttributeNS(node, this.namespaces[\"gml\"], \"id\");\n                if(fid) {\n                    feature.fid = fid;\n                }\n                if(this.internalProjection && this.externalProjection &&\n                   feature.geometry) {\n                    feature.geometry.transform(\n                        this.externalProjection, this.internalProjection\n                    );\n                }\n                if(container.bounds) {\n                    feature.bounds = container.bounds;\n                }\n                obj.features.push(feature);\n            },\n            \"_geometry\": function(node, obj) {\n                if (!this.geometryName) {\n                    this.geometryName = node.nodeName.split(\":\").pop();\n                }\n                this.readChildNodes(node, obj);\n            },\n            \"_attribute\": function(node, obj) {\n                var local = node.localName || node.nodeName.split(\":\").pop();\n                var value = this.getChildValue(node);\n                obj.attributes[local] = value;\n            }\n        },\n        \"wfs\": {\n            \"FeatureCollection\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            }\n        }\n    },\n    \n        write: function(features) {\n        var name;\n        if(OpenLayers.Util.isArray(features)) {\n            name = \"featureMembers\";\n        } else {\n            name = \"featureMember\";\n        }\n        var root = this.writeNode(\"gml:\" + name, features);\n        this.setAttributeNS(\n            root, this.namespaces[\"xsi\"],\n            \"xsi:schemaLocation\", this.schemaLocation\n        );\n\n        return OpenLayers.Format.XML.prototype.write.apply(this, [root]);\n    },\n    \n        writers: {\n        \"gml\": {\n            \"featureMember\": function(feature) {\n                var node = this.createElementNSPlus(\"gml:featureMember\");\n                this.writeNode(\"feature:_typeName\", feature, node);\n                return node;\n            },\n            \"MultiPoint\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:MultiPoint\");\n                var components = geometry.components || [geometry];\n                for(var i=0, ii=components.length; i<ii; ++i) {\n                    this.writeNode(\"pointMember\", components[i], node);\n                }\n                return node;\n            },\n            \"pointMember\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:pointMember\");\n                this.writeNode(\"Point\", geometry, node);\n                return node;\n            },\n            \"MultiLineString\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:MultiLineString\");\n                var components = geometry.components || [geometry];\n                for(var i=0, ii=components.length; i<ii; ++i) {\n                    this.writeNode(\"lineStringMember\", components[i], node);\n                }\n                return node;\n            },\n            \"lineStringMember\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:lineStringMember\");\n                this.writeNode(\"LineString\", geometry, node);\n                return node;\n            },\n            \"MultiPolygon\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:MultiPolygon\");\n                var components = geometry.components || [geometry];\n                for(var i=0, ii=components.length; i<ii; ++i) {\n                    this.writeNode(\n                        \"polygonMember\", components[i], node\n                    );\n                }\n                return node;\n            },\n            \"polygonMember\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:polygonMember\");\n                this.writeNode(\"Polygon\", geometry, node);\n                return node;\n            },\n            \"GeometryCollection\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:GeometryCollection\");\n                for(var i=0, len=geometry.components.length; i<len; ++i) {\n                    this.writeNode(\"geometryMember\", geometry.components[i], node);\n                }\n                return node;\n            },\n            \"geometryMember\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:geometryMember\");\n                var child = this.writeNode(\"feature:_geometry\", geometry);\n                node.appendChild(child.firstChild);\n                return node;\n            }\n        },\n        \"feature\": {\n            \"_typeName\": function(feature) {\n                var node = this.createElementNSPlus(this.featurePrefix + \":\" + this.featureType, {\n                    attributes: {fid: feature.fid}\n                });\n                if(feature.geometry) {\n                    this.writeNode(\"feature:_geometry\", feature.geometry, node);\n                }\n                for(var name in feature.attributes) {\n                    var value = feature.attributes[name];\n                    if(value != null) {\n                        this.writeNode(\n                            \"feature:_attribute\",\n                            {name: name, value: value}, node\n                        );\n                    }\n                }\n                return node;\n            },\n            \"_geometry\": function(geometry) {\n                if(this.externalProjection && this.internalProjection) {\n                    geometry = geometry.clone().transform(\n                        this.internalProjection, this.externalProjection\n                    );\n                }    \n                var node = this.createElementNSPlus(\n                    this.featurePrefix + \":\" + this.geometryName\n                );\n                var type = this.geometryTypes[geometry.CLASS_NAME];\n                var child = this.writeNode(\"gml:\" + type, geometry, node);\n                if(this.srsName) {\n                    child.setAttribute(\"srsName\", this.srsName);\n                }\n                return node;\n            },\n            \"_attribute\": function(obj) {\n                return this.createElementNSPlus(this.featurePrefix + \":\" + obj.name, {\n                    value: obj.value\n                });\n            }\n        },\n        \"wfs\": {\n            \"FeatureCollection\": function(features) {\n                                var node = this.createElementNSPlus(\"wfs:FeatureCollection\");\n                for(var i=0, len=features.length; i<len; ++i) {\n                    this.writeNode(\"gml:featureMember\", features[i], node);\n                }\n                return node;\n            }\n        }\n    },\n    \n        setGeometryTypes: function() {\n        this.geometryTypes = {\n            \"OpenLayers.Geometry.Point\": \"Point\",\n            \"OpenLayers.Geometry.MultiPoint\": \"MultiPoint\",\n            \"OpenLayers.Geometry.LineString\": \"LineString\",\n            \"OpenLayers.Geometry.MultiLineString\": \"MultiLineString\",\n            \"OpenLayers.Geometry.Polygon\": \"Polygon\",\n            \"OpenLayers.Geometry.MultiPolygon\": \"MultiPolygon\",\n            \"OpenLayers.Geometry.Collection\": \"GeometryCollection\"\n        };\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.GML.Base\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/GML/v2.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.GML.v2 = OpenLayers.Class(OpenLayers.Format.GML.Base, {\n    \n        schemaLocation: \"http://www.opengis.net/gml http://schemas.opengis.net/gml/2.1.2/feature.xsd\",\n\n        initialize: function(options) {\n        OpenLayers.Format.GML.Base.prototype.initialize.apply(this, [options]);\n    },\n\n        readers: {\n        \"gml\": OpenLayers.Util.applyDefaults({\n            \"outerBoundaryIs\": function(node, container) {\n                var obj = {};\n                this.readChildNodes(node, obj);\n                container.outer = obj.components[0];\n            },\n            \"innerBoundaryIs\": function(node, container) {\n                var obj = {};\n                this.readChildNodes(node, obj);\n                container.inner.push(obj.components[0]);\n            },\n            \"Box\": function(node, container) {\n                var obj = {};\n                this.readChildNodes(node, obj);\n                if(!container.components) {\n                    container.components = [];\n                }\n                var min = obj.points[0];\n                var max = obj.points[1];\n                container.components.push(\n                    new OpenLayers.Bounds(min.x, min.y, max.x, max.y)\n                );\n            }\n        }, OpenLayers.Format.GML.Base.prototype.readers[\"gml\"]),\n        \"feature\": OpenLayers.Format.GML.Base.prototype.readers[\"feature\"],\n        \"wfs\": OpenLayers.Format.GML.Base.prototype.readers[\"wfs\"]\n    },\n\n        write: function(features) {\n        var name;\n        if(OpenLayers.Util.isArray(features)) {\n            name = \"wfs:FeatureCollection\";\n        } else {\n            name = \"gml:featureMember\";\n        }\n        var root = this.writeNode(name, features);\n        this.setAttributeNS(\n            root, this.namespaces[\"xsi\"],\n            \"xsi:schemaLocation\", this.schemaLocation\n        );\n\n        return OpenLayers.Format.XML.prototype.write.apply(this, [root]);\n    },\n\n        writers: {\n        \"gml\": OpenLayers.Util.applyDefaults({\n            \"Point\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:Point\");\n                this.writeNode(\"coordinates\", [geometry], node);\n                return node;\n            },\n            \"coordinates\": function(points) {\n                var numPoints = points.length;\n                var parts = new Array(numPoints);\n                var point;\n                for(var i=0; i<numPoints; ++i) {\n                    point = points[i];\n                    if(this.xy) {\n                        parts[i] = point.x + \",\" + point.y;\n                    } else {\n                        parts[i] = point.y + \",\" + point.x;\n                    }\n                    if(point.z != undefined) { // allow null or undefined\n                        parts[i] += \",\" + point.z;\n                    }\n                }\n                return this.createElementNSPlus(\"gml:coordinates\", {\n                    attributes: {\n                        decimal: \".\", cs: \",\", ts: \" \"\n                    },\n                    value: (numPoints == 1) ? parts[0] : parts.join(\" \")\n                });\n            },\n            \"LineString\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:LineString\");\n                this.writeNode(\"coordinates\", geometry.components, node);\n                return node;\n            },\n            \"Polygon\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:Polygon\");\n                this.writeNode(\"outerBoundaryIs\", geometry.components[0], node);\n                for(var i=1; i<geometry.components.length; ++i) {\n                    this.writeNode(\n                        \"innerBoundaryIs\", geometry.components[i], node\n                    );\n                }\n                return node;\n            },\n            \"outerBoundaryIs\": function(ring) {\n                var node = this.createElementNSPlus(\"gml:outerBoundaryIs\");\n                this.writeNode(\"LinearRing\", ring, node);\n                return node;\n            },\n            \"innerBoundaryIs\": function(ring) {\n                var node = this.createElementNSPlus(\"gml:innerBoundaryIs\");\n                this.writeNode(\"LinearRing\", ring, node);\n                return node;\n            },\n            \"LinearRing\": function(ring) {\n                var node = this.createElementNSPlus(\"gml:LinearRing\");\n                this.writeNode(\"coordinates\", ring.components, node);\n                return node;\n            },\n            \"Box\": function(bounds) {\n                var node = this.createElementNSPlus(\"gml:Box\");\n                this.writeNode(\"coordinates\", [\n                    {x: bounds.left, y: bounds.bottom},\n                    {x: bounds.right, y: bounds.top}\n                ], node);\n                if(this.srsName) {\n                    node.setAttribute(\"srsName\", this.srsName);\n                }\n                return node;\n            }\n        }, OpenLayers.Format.GML.Base.prototype.writers[\"gml\"]),\n        \"feature\": OpenLayers.Format.GML.Base.prototype.writers[\"feature\"],\n        \"wfs\": OpenLayers.Format.GML.Base.prototype.writers[\"wfs\"]\n    },\n    \n    CLASS_NAME: \"OpenLayers.Format.GML.v2\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/GML/v3.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.GML.v3 = OpenLayers.Class(OpenLayers.Format.GML.Base, {\n    \n        schemaLocation: \"http://www.opengis.net/gml http://schemas.opengis.net/gml/3.1.1/profiles/gmlsfProfile/1.0.0/gmlsf.xsd\",\n\n        curve: false,\n    \n        multiCurve: true,\n    \n        surface: false,\n\n        multiSurface: true,\n\n        initialize: function(options) {\n        OpenLayers.Format.GML.Base.prototype.initialize.apply(this, [options]);\n    },\n\n        readers: {\n        \"gml\": OpenLayers.Util.applyDefaults({\n            \"_inherit\": function(node, obj, container) {\n                var dim = parseInt(node.getAttribute(\"srsDimension\"), 10) ||\n                    (container && container.srsDimension);\n                if (dim) {\n                    obj.srsDimension = dim;\n                }\n            },\n            \"featureMembers\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"Curve\": function(node, container) {\n                var obj = {points: []};\n                this.readers.gml._inherit.apply(this, [node, obj, container]);\n                this.readChildNodes(node, obj);\n                if(!container.components) {\n                    container.components = [];\n                }\n                container.components.push(\n                    new OpenLayers.Geometry.LineString(obj.points)\n                );\n            },\n            \"segments\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"LineStringSegment\": function(node, container) {\n                var obj = {};\n                this.readChildNodes(node, obj);\n                if(obj.points) {\n                    Array.prototype.push.apply(container.points, obj.points);\n                }\n            },\n            \"pos\": function(node, obj) {\n                var str = this.getChildValue(node).replace(\n                    this.regExes.trimSpace, \"\"\n                );\n                var coords = str.split(this.regExes.splitSpace);\n                var point;\n                if(this.xy) {\n                    point = new OpenLayers.Geometry.Point(\n                        coords[0], coords[1], coords[2]\n                    );\n                } else {\n                    point = new OpenLayers.Geometry.Point(\n                        coords[1], coords[0], coords[2]\n                    );\n                }\n                if(!!!obj.points) {\n                    obj.points = [];\n                }\n                obj.points.push(point);\n            },\n            \"posList\": function(node, obj) {\n                var str = this.getChildValue(node).replace(\n                    this.regExes.trimSpace, \"\"\n                );\n                var coords = str.split(this.regExes.splitSpace);\n                var dim = obj.srsDimension ||\n                    parseInt(node.getAttribute(\"srsDimension\") || node.getAttribute(\"dimension\"), 10) || 2;\n                var j, x, y, z;\n                var numPoints = coords.length / dim;\n                var points = new Array(numPoints);\n                for(var i=0, len=coords.length; i<len; i += dim) {\n                    x = coords[i];\n                    y = coords[i+1];\n                    z = (dim == 2) ? undefined : coords[i+2];\n                    if (this.xy) {\n                        points[i/dim] = new OpenLayers.Geometry.Point(x, y, z);\n                    } else {\n                        points[i/dim] = new OpenLayers.Geometry.Point(y, x, z);\n                    }\n                }\n                obj.points = points;\n            },\n            \"Surface\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"patches\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"PolygonPatch\": function(node, obj) {\n                this.readers.gml.Polygon.apply(this, [node, obj]);\n            },\n            \"exterior\": function(node, container) {\n                var obj = {};\n                this.readChildNodes(node, obj);\n                container.outer = obj.components[0];\n            },\n            \"interior\": function(node, container) {\n                var obj = {};\n                this.readChildNodes(node, obj);\n                container.inner.push(obj.components[0]);\n            },\n            \"MultiCurve\": function(node, container) {\n                var obj = {components: []};\n                this.readers.gml._inherit.apply(this, [node, obj, container]);\n                this.readChildNodes(node, obj);\n                if(obj.components.length > 0) {\n                    container.components = [\n                        new OpenLayers.Geometry.MultiLineString(obj.components)\n                    ];\n                }\n            },\n            \"curveMember\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"MultiSurface\": function(node, container) {\n                var obj = {components: []};\n                this.readers.gml._inherit.apply(this, [node, obj, container]);\n                this.readChildNodes(node, obj);\n                if(obj.components.length > 0) {\n                    container.components = [\n                        new OpenLayers.Geometry.MultiPolygon(obj.components)\n                    ];\n                }\n            },\n            \"surfaceMember\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"surfaceMembers\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"pointMembers\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"lineStringMembers\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"polygonMembers\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"geometryMembers\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"Envelope\": function(node, container) {\n                var obj = {points: new Array(2)};\n                this.readChildNodes(node, obj);\n                if(!container.components) {\n                    container.components = [];\n                }\n\n                var min = obj.points[0];\n                var max = obj.points[1];\n                container.components.push(\n                    new OpenLayers.Bounds(min.x, min.y, max.x, max.y)\n                );\n            },\n            \"lowerCorner\": function(node, container) {\n                var obj = {};\n                this.readers.gml.pos.apply(this, [node, obj]);\n                container.points[0] = obj.points[0];\n            },\n            \"upperCorner\": function(node, container) {\n                var obj = {};\n                this.readers.gml.pos.apply(this, [node, obj]);\n                container.points[1] = obj.points[0];\n            }\n        }, OpenLayers.Format.GML.Base.prototype.readers[\"gml\"]),            \n        \"feature\": OpenLayers.Format.GML.Base.prototype.readers[\"feature\"],\n        \"wfs\": OpenLayers.Format.GML.Base.prototype.readers[\"wfs\"]\n    },\n    \n        write: function(features) {\n        var name;\n        if(OpenLayers.Util.isArray(features)) {\n            name = \"featureMembers\";\n        } else {\n            name = \"featureMember\";\n        }\n        var root = this.writeNode(\"gml:\" + name, features);\n        this.setAttributeNS(\n            root, this.namespaces[\"xsi\"],\n            \"xsi:schemaLocation\", this.schemaLocation\n        );\n\n        return OpenLayers.Format.XML.prototype.write.apply(this, [root]);\n    },\n\n        writers: {\n        \"gml\": OpenLayers.Util.applyDefaults({\n            \"featureMembers\": function(features) {\n                var node = this.createElementNSPlus(\"gml:featureMembers\");\n                for(var i=0, len=features.length; i<len; ++i) {\n                    this.writeNode(\"feature:_typeName\", features[i], node);\n                }\n                return node;\n            },\n            \"Point\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:Point\");\n                this.writeNode(\"pos\", geometry, node);\n                return node;\n            },\n            \"pos\": function(point) {\n                var pos = (this.xy) ?\n                    (point.x + \" \" + point.y) : (point.y + \" \" + point.x);\n                return this.createElementNSPlus(\"gml:pos\", {\n                    value: pos\n                });\n            },\n            \"LineString\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:LineString\");\n                this.writeNode(\"posList\", geometry.components, node);\n                return node;\n            },\n            \"Curve\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:Curve\");\n                this.writeNode(\"segments\", geometry, node);\n                return node;\n            },\n            \"segments\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:segments\");\n                this.writeNode(\"LineStringSegment\", geometry, node);\n                return node;\n            },\n            \"LineStringSegment\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:LineStringSegment\");\n                this.writeNode(\"posList\", geometry.components, node);\n                return node;\n            },\n            \"posList\": function(points) {\n                var len = points.length;\n                var parts = new Array(len);\n                var point;\n                for(var i=0; i<len; ++i) {\n                    point = points[i];\n                    if(this.xy) {\n                        parts[i] = point.x + \" \" + point.y;\n                    } else {\n                        parts[i] = point.y + \" \" + point.x;\n                    }\n                }\n                return this.createElementNSPlus(\"gml:posList\", {\n                    value: parts.join(\" \")\n                }); \n            },\n            \"Surface\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:Surface\");\n                this.writeNode(\"patches\", geometry, node);\n                return node;\n            },\n            \"patches\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:patches\");\n                this.writeNode(\"PolygonPatch\", geometry, node);\n                return node;\n            },\n            \"PolygonPatch\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:PolygonPatch\", {\n                    attributes: {interpolation: \"planar\"}\n                });\n                this.writeNode(\"exterior\", geometry.components[0], node);\n                for(var i=1, len=geometry.components.length; i<len; ++i) {\n                    this.writeNode(\n                        \"interior\", geometry.components[i], node\n                    );\n                }\n                return node;\n            },\n            \"Polygon\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:Polygon\");\n                this.writeNode(\"exterior\", geometry.components[0], node);\n                for(var i=1, len=geometry.components.length; i<len; ++i) {\n                    this.writeNode(\n                        \"interior\", geometry.components[i], node\n                    );\n                }\n                return node;\n            },\n            \"exterior\": function(ring) {\n                var node = this.createElementNSPlus(\"gml:exterior\");\n                this.writeNode(\"LinearRing\", ring, node);\n                return node;\n            },\n            \"interior\": function(ring) {\n                var node = this.createElementNSPlus(\"gml:interior\");\n                this.writeNode(\"LinearRing\", ring, node);\n                return node;\n            },\n            \"LinearRing\": function(ring) {\n                var node = this.createElementNSPlus(\"gml:LinearRing\");\n                this.writeNode(\"posList\", ring.components, node);\n                return node;\n            },\n            \"MultiCurve\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:MultiCurve\");\n                var components = geometry.components || [geometry];\n                for(var i=0, len=components.length; i<len; ++i) {\n                    this.writeNode(\"curveMember\", components[i], node);\n                }\n                return node;\n            },\n            \"curveMember\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:curveMember\");\n                if(this.curve) {\n                    this.writeNode(\"Curve\", geometry, node);\n                } else {\n                    this.writeNode(\"LineString\", geometry, node);\n                }\n                return node;\n            },\n            \"MultiSurface\": function(geometry) {\n                var node = this.createElementNSPlus(\"gml:MultiSurface\");\n                var components = geometry.components || [geometry];\n                for(var i=0, len=components.length; i<len; ++i) {\n                    this.writeNode(\"surfaceMember\", components[i], node);\n                }\n                return node;\n            },\n            \"surfaceMember\": function(polygon) {\n                var node = this.createElementNSPlus(\"gml:surfaceMember\");\n                if(this.surface) {\n                    this.writeNode(\"Surface\", polygon, node);\n                } else {\n                    this.writeNode(\"Polygon\", polygon, node);\n                }\n                return node;\n            },\n            \"Envelope\": function(bounds) {\n                var node = this.createElementNSPlus(\"gml:Envelope\");\n                this.writeNode(\"lowerCorner\", bounds, node);\n                this.writeNode(\"upperCorner\", bounds, node);\n                if(this.srsName) {\n                    node.setAttribute(\"srsName\", this.srsName);\n                }\n                return node;\n            },\n            \"lowerCorner\": function(bounds) {\n                var pos = (this.xy) ?\n                    (bounds.left + \" \" + bounds.bottom) :\n                    (bounds.bottom + \" \" + bounds.left);\n                return this.createElementNSPlus(\"gml:lowerCorner\", {\n                    value: pos\n                });\n            },\n            \"upperCorner\": function(bounds) {\n                var pos = (this.xy) ?\n                    (bounds.right + \" \" + bounds.top) :\n                    (bounds.top + \" \" + bounds.right);\n                return this.createElementNSPlus(\"gml:upperCorner\", {\n                    value: pos\n                });\n            }\n        }, OpenLayers.Format.GML.Base.prototype.writers[\"gml\"]),\n        \"feature\": OpenLayers.Format.GML.Base.prototype.writers[\"feature\"],\n        \"wfs\": OpenLayers.Format.GML.Base.prototype.writers[\"wfs\"]\n    },\n\n        setGeometryTypes: function() {\n        this.geometryTypes = {\n            \"OpenLayers.Geometry.Point\": \"Point\",\n            \"OpenLayers.Geometry.MultiPoint\": \"MultiPoint\",\n            \"OpenLayers.Geometry.LineString\": (this.curve === true) ? \"Curve\": \"LineString\",\n            \"OpenLayers.Geometry.MultiLineString\": (this.multiCurve === false) ? \"MultiLineString\" : \"MultiCurve\",\n            \"OpenLayers.Geometry.Polygon\": (this.surface === true) ? \"Surface\" : \"Polygon\",\n            \"OpenLayers.Geometry.MultiPolygon\": (this.multiSurface === false) ? \"MultiPolygon\" : \"MultiSurface\",\n            \"OpenLayers.Geometry.Collection\": \"GeometryCollection\"\n        };\n    },\n    \n    CLASS_NAME: \"OpenLayers.Format.GML.v3\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/GML.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.GML = OpenLayers.Class(OpenLayers.Format.XML, {\n    \n        featureNS: \"http://mapserver.gis.umn.edu/mapserver\",\n    \n        featurePrefix: \"feature\",\n    \n        featureName: \"featureMember\", \n    \n        layerName: \"features\",\n    \n        geometryName: \"geometry\",\n    \n        collectionName: \"FeatureCollection\",\n    \n        gmlns: \"http://www.opengis.net/gml\",\n\n        extractAttributes: true,\n    \n        initialize: function(options) {\n        this.regExes = {\n            trimSpace: (/^\\s*|\\s*$/g),\n            removeSpace: (/\\s*/g),\n            splitSpace: (/\\s+/),\n            trimComma: (/\\s*,\\s*/g)\n        };\n        OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);\n    },\n\n        read: function(data) {\n        if(typeof data == \"string\") { \n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        var featureNodes = this.getElementsByTagNameNS(data.documentElement,\n                                                       this.gmlns,\n                                                       this.featureName);\n        var features = [];\n        for(var i=0; i<featureNodes.length; i++) {\n            var feature = this.parseFeature(featureNodes[i]);\n            if(feature) {\n                features.push(feature);\n            }\n        }\n        return features;\n    },\n    \n        parseFeature: function(node) {\n        var order = [\"MultiPolygon\", \"Polygon\",\n                     \"MultiLineString\", \"LineString\",\n                     \"MultiPoint\", \"Point\", \"Envelope\"];\n        var type, nodeList, geometry, parser;\n        for(var i=0; i<order.length; ++i) {\n            type = order[i];\n            nodeList = this.getElementsByTagNameNS(node, this.gmlns, type);\n            if(nodeList.length > 0) {\n                parser = this.parseGeometry[type.toLowerCase()];\n                if(parser) {\n                    geometry = parser.apply(this, [nodeList[0]]);\n                    if (this.internalProjection && this.externalProjection) {\n                        geometry.transform(this.externalProjection, \n                                           this.internalProjection); \n                    }                       \n                } else {\n                    throw new TypeError(\"Unsupported geometry type: \" + type);\n                }\n                break;\n            }\n        }\n\n        var bounds;\n        var boxNodes = this.getElementsByTagNameNS(node, this.gmlns, \"Box\");\n        for(i=0; i<boxNodes.length; ++i) {\n            var boxNode = boxNodes[i];\n            var box = this.parseGeometry[\"box\"].apply(this, [boxNode]);\n            var parentNode = boxNode.parentNode;\n            var parentName = parentNode.localName ||\n                             parentNode.nodeName.split(\":\").pop();\n            if(parentName === \"boundedBy\") {\n                bounds = box;\n            } else {\n                geometry = box.toGeometry();\n            }\n        }\n        var attributes;\n        if(this.extractAttributes) {\n            attributes = this.parseAttributes(node);\n        }\n        var feature = new OpenLayers.Feature.Vector(geometry, attributes);\n        feature.bounds = bounds;\n        \n        var firstChild = this.getFirstElementChild(node);\n        feature.gml = {\n            featureType: firstChild.nodeName.split(\":\")[1],\n            featureNS: firstChild.namespaceURI,\n            featureNSPrefix: firstChild.prefix\n        };\n        feature.type = feature.gml.featureType;\n        var childNode = node.firstChild;\n        var fid;\n        while(childNode) {\n            if(childNode.nodeType == 1) {\n                fid = childNode.getAttribute(\"fid\") ||\n                      childNode.getAttribute(\"id\");\n                if(fid) {\n                    break;\n                }\n            }\n            childNode = childNode.nextSibling;\n        }\n        feature.fid = fid;\n        return feature;\n    },\n    \n        parseGeometry: {\n        \n                point: function(node) {\n                        var nodeList, coordString;\n            var coords = [];\n            var nodeList = this.getElementsByTagNameNS(node, this.gmlns, \"pos\");\n            if(nodeList.length > 0) {\n                coordString = nodeList[0].firstChild.nodeValue;\n                coordString = coordString.replace(this.regExes.trimSpace, \"\");\n                coords = coordString.split(this.regExes.splitSpace);\n            }\n            if(coords.length == 0) {\n                nodeList = this.getElementsByTagNameNS(node, this.gmlns,\n                                                       \"coordinates\");\n                if(nodeList.length > 0) {\n                    coordString = nodeList[0].firstChild.nodeValue;\n                    coordString = coordString.replace(this.regExes.removeSpace,\n                                                      \"\");\n                    coords = coordString.split(\",\");\n                }\n            }\n            if(coords.length == 0) {\n                nodeList = this.getElementsByTagNameNS(node, this.gmlns,\n                                                       \"coord\");\n                if(nodeList.length > 0) {\n                    var xList = this.getElementsByTagNameNS(nodeList[0],\n                                                            this.gmlns, \"X\");\n                    var yList = this.getElementsByTagNameNS(nodeList[0],\n                                                            this.gmlns, \"Y\");\n                    if(xList.length > 0 && yList.length > 0) {\n                        coords = [xList[0].firstChild.nodeValue,\n                                  yList[0].firstChild.nodeValue];\n                    }\n                }\n            }\n            if(coords.length == 2) {\n                coords[2] = null;\n            }\n            \n            if (this.xy) {\n                return new OpenLayers.Geometry.Point(coords[0], coords[1],\n                                                 coords[2]);\n            }\n            else{\n                return new OpenLayers.Geometry.Point(coords[1], coords[0],\n                                                 coords[2]);\n            }\n        },\n        \n                multipoint: function(node) {\n            var nodeList = this.getElementsByTagNameNS(node, this.gmlns,\n                                                       \"Point\");\n            var components = [];\n            if(nodeList.length > 0) {\n                var point;\n                for(var i=0; i<nodeList.length; ++i) {\n                    point = this.parseGeometry.point.apply(this, [nodeList[i]]);\n                    if(point) {\n                        components.push(point);\n                    }\n                }\n            }\n            return new OpenLayers.Geometry.MultiPoint(components);\n        },\n        \n                linestring: function(node, ring) {\n                        var nodeList, coordString;\n            var coords = [];\n            var points = [];\n            nodeList = this.getElementsByTagNameNS(node, this.gmlns, \"posList\");\n            if(nodeList.length > 0) {\n                coordString = this.getChildValue(nodeList[0]);\n                coordString = coordString.replace(this.regExes.trimSpace, \"\");\n                coords = coordString.split(this.regExes.splitSpace);\n                var dim = parseInt(nodeList[0].getAttribute(\"dimension\"));\n                var j, x, y, z;\n                for(var i=0; i<coords.length/dim; ++i) {\n                    j = i * dim;\n                    x = coords[j];\n                    y = coords[j+1];\n                    z = (dim == 2) ? null : coords[j+2];\n                    if (this.xy) {\n                        points.push(new OpenLayers.Geometry.Point(x, y, z));\n                    } else {\n                        points.push(new OpenLayers.Geometry.Point(y, x, z));\n                    }\n                }\n            }\n            if(coords.length == 0) {\n                nodeList = this.getElementsByTagNameNS(node, this.gmlns,\n                                                       \"coordinates\");\n                if(nodeList.length > 0) {\n                    coordString = this.getChildValue(nodeList[0]);\n                    coordString = coordString.replace(this.regExes.trimSpace,\n                                                      \"\");\n                    coordString = coordString.replace(this.regExes.trimComma,\n                                                      \",\");\n                    var pointList = coordString.split(this.regExes.splitSpace);\n                    for(var i=0; i<pointList.length; ++i) {\n                        coords = pointList[i].split(\",\");\n                        if(coords.length == 2) {\n                            coords[2] = null;\n                        }\n                        if (this.xy) {\n                            points.push(new OpenLayers.Geometry.Point(coords[0],\n                                                                  coords[1],\n                                                                  coords[2]));\n                        } else {\n                            points.push(new OpenLayers.Geometry.Point(coords[1],\n                                                                  coords[0],\n                                                                  coords[2]));\n                        }\n                    }\n                }\n            }\n\n            var line = null;\n            if(points.length != 0) {\n                if(ring) {\n                    line = new OpenLayers.Geometry.LinearRing(points);\n                } else {\n                    line = new OpenLayers.Geometry.LineString(points);\n                }\n            }\n            return line;\n        },\n        \n                multilinestring: function(node) {\n            var nodeList = this.getElementsByTagNameNS(node, this.gmlns,\n                                                       \"LineString\");\n            var components = [];\n            if(nodeList.length > 0) {\n                var line;\n                for(var i=0; i<nodeList.length; ++i) {\n                    line = this.parseGeometry.linestring.apply(this,\n                                                               [nodeList[i]]);\n                    if(line) {\n                        components.push(line);\n                    }\n                }\n            }\n            return new OpenLayers.Geometry.MultiLineString(components);\n        },\n        \n                polygon: function(node) {\n            var nodeList = this.getElementsByTagNameNS(node, this.gmlns,\n                                                       \"LinearRing\");\n            var components = [];\n            if(nodeList.length > 0) {\n                var ring;\n                for(var i=0; i<nodeList.length; ++i) {\n                    ring = this.parseGeometry.linestring.apply(this,\n                                                        [nodeList[i], true]);\n                    if(ring) {\n                        components.push(ring);\n                    }\n                }\n            }\n            return new OpenLayers.Geometry.Polygon(components);\n        },\n        \n                multipolygon: function(node) {\n            var nodeList = this.getElementsByTagNameNS(node, this.gmlns,\n                                                       \"Polygon\");\n            var components = [];\n            if(nodeList.length > 0) {\n                var polygon;\n                for(var i=0; i<nodeList.length; ++i) {\n                    polygon = this.parseGeometry.polygon.apply(this,\n                                                               [nodeList[i]]);\n                    if(polygon) {\n                        components.push(polygon);\n                    }\n                }\n            }\n            return new OpenLayers.Geometry.MultiPolygon(components);\n        },\n        \n        envelope: function(node) {\n            var components = [];\n            var coordString;\n            var envelope;\n            \n            var lpoint = this.getElementsByTagNameNS(node, this.gmlns, \"lowerCorner\");\n            if (lpoint.length > 0) {\n                var coords = [];\n                \n                if(lpoint.length > 0) {\n                    coordString = lpoint[0].firstChild.nodeValue;\n                    coordString = coordString.replace(this.regExes.trimSpace, \"\");\n                    coords = coordString.split(this.regExes.splitSpace);\n                }\n                \n                if(coords.length == 2) {\n                    coords[2] = null;\n                }\n                if (this.xy) {\n                    var lowerPoint = new OpenLayers.Geometry.Point(coords[0], coords[1],coords[2]);\n                } else {\n                    var lowerPoint = new OpenLayers.Geometry.Point(coords[1], coords[0],coords[2]);\n                }\n            }\n            \n            var upoint = this.getElementsByTagNameNS(node, this.gmlns, \"upperCorner\");\n            if (upoint.length > 0) {\n                var coords = [];\n                \n                if(upoint.length > 0) {\n                    coordString = upoint[0].firstChild.nodeValue;\n                    coordString = coordString.replace(this.regExes.trimSpace, \"\");\n                    coords = coordString.split(this.regExes.splitSpace);\n                }\n                \n                if(coords.length == 2) {\n                    coords[2] = null;\n                }\n                if (this.xy) {\n                    var upperPoint = new OpenLayers.Geometry.Point(coords[0], coords[1],coords[2]);\n                } else {\n                    var upperPoint = new OpenLayers.Geometry.Point(coords[1], coords[0],coords[2]);\n                }\n            }\n            \n            if (lowerPoint && upperPoint) {\n                components.push(new OpenLayers.Geometry.Point(lowerPoint.x, lowerPoint.y));\n                components.push(new OpenLayers.Geometry.Point(upperPoint.x, lowerPoint.y));\n                components.push(new OpenLayers.Geometry.Point(upperPoint.x, upperPoint.y));\n                components.push(new OpenLayers.Geometry.Point(lowerPoint.x, upperPoint.y));\n                components.push(new OpenLayers.Geometry.Point(lowerPoint.x, lowerPoint.y));\n                \n                var ring = new OpenLayers.Geometry.LinearRing(components);\n                envelope = new OpenLayers.Geometry.Polygon([ring]);\n            }\n            return envelope; \n        },\n\n                box: function(node) {\n            var nodeList = this.getElementsByTagNameNS(node, this.gmlns,\n                                                   \"coordinates\");\n            var coordString;\n            var coords, beginPoint = null, endPoint = null;\n            if (nodeList.length > 0) {\n                coordString = nodeList[0].firstChild.nodeValue;\n                coords = coordString.split(\" \");\n                if (coords.length == 2) {\n                    beginPoint = coords[0].split(\",\");\n                    endPoint = coords[1].split(\",\");\n                }\n            }\n            if (beginPoint !== null && endPoint !== null) {\n                return new OpenLayers.Bounds(parseFloat(beginPoint[0]),\n                    parseFloat(beginPoint[1]),\n                    parseFloat(endPoint[0]),\n                    parseFloat(endPoint[1]) );\n            }\n        }\n        \n    },\n    \n        parseAttributes: function(node) {\n        var attributes = {};\n        var childNode = node.firstChild;\n        var children, i, child, grandchildren, grandchild, name, value;\n        while(childNode) {\n            if(childNode.nodeType == 1) {\n                children = childNode.childNodes;\n                for(i=0; i<children.length; ++i) {\n                    child = children[i];\n                    if(child.nodeType == 1) {\n                        grandchildren = child.childNodes;\n                        if(grandchildren.length == 1) {\n                            grandchild = grandchildren[0];\n                            if(grandchild.nodeType == 3 ||\n                               grandchild.nodeType == 4) {\n                                name = (child.prefix) ?\n                                        child.nodeName.split(\":\")[1] :\n                                        child.nodeName;\n                                value = grandchild.nodeValue.replace(\n                                                this.regExes.trimSpace, \"\");\n                                attributes[name] = value;\n                            }\n                        } else {\n                            attributes[child.nodeName.split(\":\").pop()] = null;\n                        }\n                    }\n                }\n                break;\n            }\n            childNode = childNode.nextSibling;\n        }\n        return attributes;\n    },\n    \n        write: function(features) {\n        if(!(OpenLayers.Util.isArray(features))) {\n            features = [features];\n        }\n        var gml = this.createElementNS(\"http://www.opengis.net/wfs\",\n                                       \"wfs:\" + this.collectionName);\n        for(var i=0; i<features.length; i++) {\n            gml.appendChild(this.createFeatureXML(features[i]));\n        }\n        return OpenLayers.Format.XML.prototype.write.apply(this, [gml]);\n    },\n\n        createFeatureXML: function(feature) {\n        var geometry = feature.geometry;\n        var geometryNode = this.buildGeometryNode(geometry);\n        var geomContainer = this.createElementNS(this.featureNS,\n                                                 this.featurePrefix + \":\" +\n                                                 this.geometryName);\n        geomContainer.appendChild(geometryNode);\n        var featureNode = this.createElementNS(this.gmlns,\n                                               \"gml:\" + this.featureName);\n        var featureContainer = this.createElementNS(this.featureNS,\n                                                    this.featurePrefix + \":\" +\n                                                    this.layerName);\n        var fid = feature.fid || feature.id;\n        featureContainer.setAttribute(\"fid\", fid);\n        featureContainer.appendChild(geomContainer);\n        for(var attr in feature.attributes) {\n            var attrText = this.createTextNode(feature.attributes[attr]); \n            var nodename = attr.substring(attr.lastIndexOf(\":\") + 1);\n            var attrContainer = this.createElementNS(this.featureNS,\n                                                     this.featurePrefix + \":\" +\n                                                     nodename);\n            attrContainer.appendChild(attrText);\n            featureContainer.appendChild(attrContainer);\n        }    \n        featureNode.appendChild(featureContainer);\n        return featureNode;\n    },\n    \n        buildGeometryNode: function(geometry) {\n        if (this.externalProjection && this.internalProjection) {\n            geometry = geometry.clone();\n            geometry.transform(this.internalProjection, \n                               this.externalProjection);\n        }    \n        var className = geometry.CLASS_NAME;\n        var type = className.substring(className.lastIndexOf(\".\") + 1);\n        var builder = this.buildGeometry[type.toLowerCase()];\n        return builder.apply(this, [geometry]);\n    },\n\n        buildGeometry: {\n\n                point: function(geometry) {\n            var gml = this.createElementNS(this.gmlns, \"gml:Point\");\n            gml.appendChild(this.buildCoordinatesNode(geometry));\n            return gml;\n        },\n        \n                multipoint: function(geometry) {\n            var gml = this.createElementNS(this.gmlns, \"gml:MultiPoint\");\n            var points = geometry.components;\n            var pointMember, pointGeom;\n            for(var i=0; i<points.length; i++) { \n                pointMember = this.createElementNS(this.gmlns,\n                                                   \"gml:pointMember\");\n                pointGeom = this.buildGeometry.point.apply(this,\n                                                               [points[i]]);\n                pointMember.appendChild(pointGeom);\n                gml.appendChild(pointMember);\n            }\n            return gml;            \n        },\n        \n                linestring: function(geometry) {\n            var gml = this.createElementNS(this.gmlns, \"gml:LineString\");\n            gml.appendChild(this.buildCoordinatesNode(geometry));\n            return gml;\n        },\n        \n                multilinestring: function(geometry) {\n            var gml = this.createElementNS(this.gmlns, \"gml:MultiLineString\");\n            var lines = geometry.components;\n            var lineMember, lineGeom;\n            for(var i=0; i<lines.length; ++i) {\n                lineMember = this.createElementNS(this.gmlns,\n                                                  \"gml:lineStringMember\");\n                lineGeom = this.buildGeometry.linestring.apply(this,\n                                                                   [lines[i]]);\n                lineMember.appendChild(lineGeom);\n                gml.appendChild(lineMember);\n            }\n            return gml;\n        },\n        \n                linearring: function(geometry) {\n            var gml = this.createElementNS(this.gmlns, \"gml:LinearRing\");\n            gml.appendChild(this.buildCoordinatesNode(geometry));\n            return gml;\n        },\n        \n                polygon: function(geometry) {\n            var gml = this.createElementNS(this.gmlns, \"gml:Polygon\");\n            var rings = geometry.components;\n            var ringMember, ringGeom, type;\n            for(var i=0; i<rings.length; ++i) {\n                type = (i==0) ? \"outerBoundaryIs\" : \"innerBoundaryIs\";\n                ringMember = this.createElementNS(this.gmlns,\n                                                  \"gml:\" + type);\n                ringGeom = this.buildGeometry.linearring.apply(this,\n                                                                   [rings[i]]);\n                ringMember.appendChild(ringGeom);\n                gml.appendChild(ringMember);\n            }\n            return gml;\n        },\n        \n                multipolygon: function(geometry) {\n            var gml = this.createElementNS(this.gmlns, \"gml:MultiPolygon\");\n            var polys = geometry.components;\n            var polyMember, polyGeom;\n            for(var i=0; i<polys.length; ++i) {\n                polyMember = this.createElementNS(this.gmlns,\n                                                  \"gml:polygonMember\");\n                polyGeom = this.buildGeometry.polygon.apply(this,\n                                                                [polys[i]]);\n                polyMember.appendChild(polyGeom);\n                gml.appendChild(polyMember);\n            }\n            return gml;\n\n        },\n \n                bounds: function(bounds) {\n            var gml = this.createElementNS(this.gmlns, \"gml:Box\");\n            gml.appendChild(this.buildCoordinatesNode(bounds));\n            return gml;\n        }\n    },\n\n        buildCoordinatesNode: function(geometry) {\n        var coordinatesNode = this.createElementNS(this.gmlns,\n                                                   \"gml:coordinates\");\n        coordinatesNode.setAttribute(\"decimal\", \".\");\n        coordinatesNode.setAttribute(\"cs\", \",\");\n        coordinatesNode.setAttribute(\"ts\", \" \");\n\n        var parts = [];\n\n        if(geometry instanceof OpenLayers.Bounds){\n            parts.push(geometry.left + \",\" + geometry.bottom);\n            parts.push(geometry.right + \",\" + geometry.top);\n        } else {\n            var points = (geometry.components) ? geometry.components : [geometry];\n            for(var i=0; i<points.length; i++) {\n                parts.push(points[i].x + \",\" + points[i].y);                \n            }            \n        }\n\n        var txtNode = this.createTextNode(parts.join(\" \"));\n        coordinatesNode.appendChild(txtNode);\n        \n        return coordinatesNode;\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.GML\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/GPX.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.GPX = OpenLayers.Class(OpenLayers.Format.XML, {\n    \n\n        defaultDesc: \"No description available\",\n\n       extractWaypoints: true,\n    \n       extractTracks: true,\n    \n       extractRoutes: true,\n    \n        extractAttributes: true,\n\n        namespaces: {\n        gpx: \"http://www.topografix.com/GPX/1/1\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\"\n    },\n\n        schemaLocation: \"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\",\n\n        creator: \"OpenLayers\",\n    \n        initialize: function(options) {\n        this.externalProjection = new OpenLayers.Projection(\"EPSG:4326\");\n\n        OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);\n    },\n    \n        read: function(doc) {\n        if (typeof doc == \"string\") { \n            doc = OpenLayers.Format.XML.prototype.read.apply(this, [doc]);\n        }\n        var features = [];\n        \n        if(this.extractTracks) {\n            var tracks = doc.getElementsByTagName(\"trk\");\n            for (var i=0, len=tracks.length; i<len; i++) {\n                var attrs = {};\n                if(this.extractAttributes) {\n                    attrs = this.parseAttributes(tracks[i]);\n                }\n                \n                var segs = this.getElementsByTagNameNS(tracks[i], tracks[i].namespaceURI, \"trkseg\");\n                for (var j = 0, seglen = segs.length; j < seglen; j++) {\n                    var track = this.extractSegment(segs[j], \"trkpt\");\n                    features.push(new OpenLayers.Feature.Vector(track, attrs));\n                }\n            }\n        }\n        \n        if(this.extractRoutes) {\n            var routes = doc.getElementsByTagName(\"rte\");\n            for (var k=0, klen=routes.length; k<klen; k++) {\n                var attrs = {};\n                if(this.extractAttributes) {\n                    attrs = this.parseAttributes(routes[k]);\n                }\n                var route = this.extractSegment(routes[k], \"rtept\");\n                features.push(new OpenLayers.Feature.Vector(route, attrs));\n            }\n        }\n        \n        if(this.extractWaypoints) {\n            var waypoints = doc.getElementsByTagName(\"wpt\");\n            for (var l = 0, len = waypoints.length; l < len; l++) {\n                var attrs = {};\n                if(this.extractAttributes) {\n                    attrs = this.parseAttributes(waypoints[l]);\n                }\n                var wpt = new OpenLayers.Geometry.Point(waypoints[l].getAttribute(\"lon\"), waypoints[l].getAttribute(\"lat\"));\n                features.push(new OpenLayers.Feature.Vector(wpt, attrs));\n            }\n        }\n        \n        if (this.internalProjection && this.externalProjection) {\n            for (var g = 0, featLength = features.length; g < featLength; g++) {\n                features[g].geometry.transform(this.externalProjection,\n                                    this.internalProjection);\n            }\n        }\n        \n        return features;\n    },\n    \n       extractSegment: function(segment, segmentType) {\n        var points = this.getElementsByTagNameNS(segment, segment.namespaceURI, segmentType);\n        var point_features = [];\n        for (var i = 0, len = points.length; i < len; i++) {\n            point_features.push(new OpenLayers.Geometry.Point(points[i].getAttribute(\"lon\"), points[i].getAttribute(\"lat\")));\n        }\n        return new OpenLayers.Geometry.LineString(point_features);\n    },\n    \n        parseAttributes: function(node) {\n        var attributes = {};\n        var attrNode = node.firstChild, value, name;\n        while(attrNode) {\n            if(attrNode.nodeType == 1 && attrNode.firstChild) {\n                value = attrNode.firstChild;\n                if(value.nodeType == 3 || value.nodeType == 4) {\n                    name = (attrNode.prefix) ?\n                        attrNode.nodeName.split(\":\")[1] :\n                        attrNode.nodeName;\n                    if(name != \"trkseg\" && name != \"rtept\") {\n                        attributes[name] = value.nodeValue;\n                    }\n                }\n            }\n            attrNode = attrNode.nextSibling;\n        }\n        return attributes;\n    },\n\n        write: function(features, metadata) {\n        features = OpenLayers.Util.isArray(features) ?\n            features : [features];\n        var gpx = this.createElementNS(this.namespaces.gpx, \"gpx\");\n        gpx.setAttribute(\"version\", \"1.1\");\n        gpx.setAttribute(\"creator\", this.creator);\n        this.setAttributes(gpx, {\n            \"xsi:schemaLocation\": this.schemaLocation\n        });\n\n        if (metadata && typeof metadata == 'object') {\n            gpx.appendChild(this.buildMetadataNode(metadata));\n        }\n        for(var i=0, len=features.length; i<len; i++) {\n            gpx.appendChild(this.buildFeatureNode(features[i]));\n        }\n        return OpenLayers.Format.XML.prototype.write.apply(this, [gpx]);\n    },\n\n        buildMetadataNode: function(metadata) {\n        var types = ['name', 'desc', 'author'],\n            node = this.createElementNS(this.namespaces.gpx, 'metadata');\n        for (var i=0; i < types.length; i++) {\n            var type = types[i];\n            if (metadata[type]) {\n                var n = this.createElementNS(this.namespaces.gpx, type);\n                n.appendChild(this.createTextNode(metadata[type]));\n                node.appendChild(n);\n            }\n        }\n        return node;\n    },\n\n        buildFeatureNode: function(feature) {\n        var geometry = feature.geometry;\n            geometry = geometry.clone();\n        if (this.internalProjection && this.externalProjection) {\n            geometry.transform(this.internalProjection, \n                               this.externalProjection);\n        }\n        if (geometry.CLASS_NAME == \"OpenLayers.Geometry.Point\") {\n            var wpt = this.buildWptNode(geometry);\n            this.appendAttributesNode(wpt, feature);\n            return wpt;\n        } else {\n            var trkNode = this.createElementNS(this.namespaces.gpx, \"trk\");\n            this.appendAttributesNode(trkNode, feature);\n            var trkSegNodes = this.buildTrkSegNode(geometry);\n            trkSegNodes = OpenLayers.Util.isArray(trkSegNodes) ?\n                trkSegNodes : [trkSegNodes];\n            for (var i = 0, len = trkSegNodes.length; i < len; i++) {\n                trkNode.appendChild(trkSegNodes[i]);\n            }\n            return trkNode;\n        }\n    },\n\n        buildTrkSegNode: function(geometry) {\n        var node,\n            i,\n            len,\n            point,\n            nodes;\n        if (geometry.CLASS_NAME == \"OpenLayers.Geometry.LineString\" ||\n            geometry.CLASS_NAME == \"OpenLayers.Geometry.LinearRing\") {\n            node = this.createElementNS(this.namespaces.gpx, \"trkseg\");\n            for (i = 0, len=geometry.components.length; i < len; i++) {\n                point = geometry.components[i];\n                node.appendChild(this.buildTrkPtNode(point));\n            }\n            return node;\n        } else {\n            nodes = [];\n            for (i = 0, len = geometry.components.length; i < len; i++) {\n                nodes.push(this.buildTrkSegNode(geometry.components[i]));\n            }\n            return nodes;\n        }\n    },\n    \n        buildTrkPtNode: function(point) {\n        var node = this.createElementNS(this.namespaces.gpx, \"trkpt\");\n        node.setAttribute(\"lon\", point.x);\n        node.setAttribute(\"lat\", point.y);\n        return node;\n    },\n\n        buildWptNode: function(geometry) {\n        var node = this.createElementNS(this.namespaces.gpx, \"wpt\");\n        node.setAttribute(\"lon\", geometry.x);\n        node.setAttribute(\"lat\", geometry.y);\n        return node;\n    },\n\n        appendAttributesNode: function(node, feature) {\n        var name = this.createElementNS(this.namespaces.gpx, 'name');\n        name.appendChild(this.createTextNode(\n            feature.attributes.name || feature.id));\n        node.appendChild(name);\n        var desc = this.createElementNS(this.namespaces.gpx, 'desc');\n        desc.appendChild(this.createTextNode(\n            feature.attributes.description || feature.attributes.desc || this.defaultDesc));\n        node.appendChild(desc);\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.GPX\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/GeoJSON.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.GeoJSON = OpenLayers.Class(OpenLayers.Format.JSON, {\n\n    \n        read: function(json, type, filter) {\n        type = (type) ? type : \"FeatureCollection\";\n        var results = null;\n        var obj = null;\n        if (typeof json == \"string\") {\n            obj = OpenLayers.Format.JSON.prototype.read.apply(this,\n                                                              [json, filter]);\n        } else { \n            obj = json;\n        }    \n        if(!obj) {\n            OpenLayers.Console.error(\"Bad JSON: \" + json);\n        } else if(typeof(obj.type) != \"string\") {\n            OpenLayers.Console.error(\"Bad GeoJSON - no type: \" + json);\n        } else if(this.isValidType(obj, type)) {\n            switch(type) {\n                case \"Geometry\":\n                    try {\n                        results = this.parseGeometry(obj);\n                    } catch(err) {\n                        OpenLayers.Console.error(err);\n                    }\n                    break;\n                case \"Feature\":\n                    try {\n                        results = this.parseFeature(obj);\n                        results.type = \"Feature\";\n                    } catch(err) {\n                        OpenLayers.Console.error(err);\n                    }\n                    break;\n                case \"FeatureCollection\":\n                    results = [];\n                    switch(obj.type) {\n                        case \"Feature\":\n                            try {\n                                results.push(this.parseFeature(obj));\n                            } catch(err) {\n                                results = null;\n                                OpenLayers.Console.error(err);\n                            }\n                            break;\n                        case \"FeatureCollection\":\n                            for(var i=0, len=obj.features.length; i<len; ++i) {\n                                try {\n                                    results.push(this.parseFeature(obj.features[i]));\n                                } catch(err) {\n                                    results = null;\n                                    OpenLayers.Console.error(err);\n                                }\n                            }\n                            break;\n                        default:\n                            try {\n                                var geom = this.parseGeometry(obj);\n                                results.push(new OpenLayers.Feature.Vector(geom));\n                            } catch(err) {\n                                results = null;\n                                OpenLayers.Console.error(err);\n                            }\n                    }\n                break;\n            }\n        }\n        return results;\n    },\n    \n        isValidType: function(obj, type) {\n        var valid = false;\n        switch(type) {\n            case \"Geometry\":\n                if(OpenLayers.Util.indexOf(\n                    [\"Point\", \"MultiPoint\", \"LineString\", \"MultiLineString\",\n                     \"Polygon\", \"MultiPolygon\", \"Box\", \"GeometryCollection\"],\n                    obj.type) == -1) {\n                    OpenLayers.Console.error(\"Unsupported geometry type: \" +\n                                              obj.type);\n                } else {\n                    valid = true;\n                }\n                break;\n            case \"FeatureCollection\":\n                valid = true;\n                break;\n            default:\n                if(obj.type == type) {\n                    valid = true;\n                } else {\n                    OpenLayers.Console.error(\"Cannot convert types from \" +\n                                              obj.type + \" to \" + type);\n                }\n        }\n        return valid;\n    },\n    \n        parseFeature: function(obj) {\n        var feature, geometry, attributes, bbox;\n        attributes = (obj.properties) ? obj.properties : {};\n        bbox = (obj.geometry && obj.geometry.bbox) || obj.bbox;\n        try {\n            geometry = this.parseGeometry(obj.geometry);\n        } catch(err) {\n            throw err;\n        }\n        feature = new OpenLayers.Feature.Vector(geometry, attributes);\n        if(bbox) {\n            feature.bounds = OpenLayers.Bounds.fromArray(bbox);\n        }\n        if(obj.id) {\n            feature.fid = obj.id;\n        }\n        return feature;\n    },\n    \n        parseGeometry: function(obj) {\n        if (obj == null) {\n            return null;\n        }\n        var geometry, collection = false;\n        if(obj.type == \"GeometryCollection\") {\n            if(!(OpenLayers.Util.isArray(obj.geometries))) {\n                throw \"GeometryCollection must have geometries array: \" + obj;\n            }\n            var numGeom = obj.geometries.length;\n            var components = new Array(numGeom);\n            for(var i=0; i<numGeom; ++i) {\n                components[i] = this.parseGeometry.apply(\n                    this, [obj.geometries[i]]\n                );\n            }\n            geometry = new OpenLayers.Geometry.Collection(components);\n            collection = true;\n        } else {\n            if(!(OpenLayers.Util.isArray(obj.coordinates))) {\n                throw \"Geometry must have coordinates array: \" + obj;\n            }\n            if(!this.parseCoords[obj.type.toLowerCase()]) {\n                throw \"Unsupported geometry type: \" + obj.type;\n            }\n            try {\n                geometry = this.parseCoords[obj.type.toLowerCase()].apply(\n                    this, [obj.coordinates]\n                );\n            } catch(err) {\n                throw err;\n            }\n        }\n        if (this.internalProjection && this.externalProjection && !collection) {\n            geometry.transform(this.externalProjection, \n                               this.internalProjection); \n        }                       \n        return geometry;\n    },\n    \n        parseCoords: {\n                \"point\": function(array) {\n            if (this.ignoreExtraDims == false && \n                  array.length != 2) {\n                    throw \"Only 2D points are supported: \" + array;\n            }\n            return new OpenLayers.Geometry.Point(array[0], array[1]);\n        },\n        \n                \"multipoint\": function(array) {\n            var points = [];\n            var p = null;\n            for(var i=0, len=array.length; i<len; ++i) {\n                try {\n                    p = this.parseCoords[\"point\"].apply(this, [array[i]]);\n                } catch(err) {\n                    throw err;\n                }\n                points.push(p);\n            }\n            return new OpenLayers.Geometry.MultiPoint(points);\n        },\n\n                \"linestring\": function(array) {\n            var points = [];\n            var p = null;\n            for(var i=0, len=array.length; i<len; ++i) {\n                try {\n                    p = this.parseCoords[\"point\"].apply(this, [array[i]]);\n                } catch(err) {\n                    throw err;\n                }\n                points.push(p);\n            }\n            return new OpenLayers.Geometry.LineString(points);\n        },\n        \n                \"multilinestring\": function(array) {\n            var lines = [];\n            var l = null;\n            for(var i=0, len=array.length; i<len; ++i) {\n                try {\n                    l = this.parseCoords[\"linestring\"].apply(this, [array[i]]);\n                } catch(err) {\n                    throw err;\n                }\n                lines.push(l);\n            }\n            return new OpenLayers.Geometry.MultiLineString(lines);\n        },\n        \n                \"polygon\": function(array) {\n            var rings = [];\n            var r, l;\n            for(var i=0, len=array.length; i<len; ++i) {\n                try {\n                    l = this.parseCoords[\"linestring\"].apply(this, [array[i]]);\n                } catch(err) {\n                    throw err;\n                }\n                r = new OpenLayers.Geometry.LinearRing(l.components);\n                rings.push(r);\n            }\n            return new OpenLayers.Geometry.Polygon(rings);\n        },\n\n                \"multipolygon\": function(array) {\n            var polys = [];\n            var p = null;\n            for(var i=0, len=array.length; i<len; ++i) {\n                try {\n                    p = this.parseCoords[\"polygon\"].apply(this, [array[i]]);\n                } catch(err) {\n                    throw err;\n                }\n                polys.push(p);\n            }\n            return new OpenLayers.Geometry.MultiPolygon(polys);\n        },\n\n                \"box\": function(array) {\n            if(array.length != 2) {\n                throw \"GeoJSON box coordinates must have 2 elements\";\n            }\n            return new OpenLayers.Geometry.Polygon([\n                new OpenLayers.Geometry.LinearRing([\n                    new OpenLayers.Geometry.Point(array[0][0], array[0][1]),\n                    new OpenLayers.Geometry.Point(array[1][0], array[0][1]),\n                    new OpenLayers.Geometry.Point(array[1][0], array[1][1]),\n                    new OpenLayers.Geometry.Point(array[0][0], array[1][1]),\n                    new OpenLayers.Geometry.Point(array[0][0], array[0][1])\n                ])\n            ]);\n        }\n\n    },\n\n        write: function(obj, pretty) {\n        var geojson = {\n            \"type\": null\n        };\n        if(OpenLayers.Util.isArray(obj)) {\n            geojson.type = \"FeatureCollection\";\n            var numFeatures = obj.length;\n            geojson.features = new Array(numFeatures);\n            for(var i=0; i<numFeatures; ++i) {\n                var element = obj[i];\n                if(!element instanceof OpenLayers.Feature.Vector) {\n                    var msg = \"FeatureCollection only supports collections \" +\n                              \"of features: \" + element;\n                    throw msg;\n                }\n                geojson.features[i] = this.extract.feature.apply(\n                    this, [element]\n                );\n            }\n        } else if (obj.CLASS_NAME.indexOf(\"OpenLayers.Geometry\") == 0) {\n            geojson = this.extract.geometry.apply(this, [obj]);\n        } else if (obj instanceof OpenLayers.Feature.Vector) {\n            geojson = this.extract.feature.apply(this, [obj]);\n            if(obj.layer && obj.layer.projection) {\n                geojson.crs = this.createCRSObject(obj);\n            }\n        }\n        return OpenLayers.Format.JSON.prototype.write.apply(this,\n                                                            [geojson, pretty]);\n    },\n\n        createCRSObject: function(object) {\n       var proj = object.layer.projection.toString();\n       var crs = {};\n       if (proj.match(/epsg:/i)) {\n           var code = parseInt(proj.substring(proj.indexOf(\":\") + 1));\n           if (code == 4326) {\n               crs = {\n                   \"type\": \"name\",\n                   \"properties\": {\n                       \"name\": \"urn:ogc:def:crs:OGC:1.3:CRS84\"\n                   }\n               };\n           } else {    \n               crs = {\n                   \"type\": \"name\",\n                   \"properties\": {\n                       \"name\": \"EPSG:\" + code\n                   }\n               };\n           }    \n       }\n       return crs;\n    },\n    \n        extract: {\n                'feature': function(feature) {\n            var geom = this.extract.geometry.apply(this, [feature.geometry]);\n            var json = {\n                \"type\": \"Feature\",\n                \"properties\": feature.attributes,\n                \"geometry\": geom\n            };\n            if (feature.fid != null) {\n                json.id = feature.fid;\n            }\n            return json;\n        },\n        \n                'geometry': function(geometry) {\n            if (geometry == null) {\n                return null;\n            }\n            if (this.internalProjection && this.externalProjection) {\n                geometry = geometry.clone();\n                geometry.transform(this.internalProjection, \n                                   this.externalProjection);\n            }                       \n            var geometryType = geometry.CLASS_NAME.split('.')[2];\n            var data = this.extract[geometryType.toLowerCase()].apply(this, [geometry]);\n            var json;\n            if(geometryType == \"Collection\") {\n                json = {\n                    \"type\": \"GeometryCollection\",\n                    \"geometries\": data\n                };\n            } else {\n                json = {\n                    \"type\": geometryType,\n                    \"coordinates\": data\n                };\n            }\n            \n            return json;\n        },\n\n                'point': function(point) {\n            return [point.x, point.y];\n        },\n\n                'multipoint': function(multipoint) {\n            var array = [];\n            for(var i=0, len=multipoint.components.length; i<len; ++i) {\n                array.push(this.extract.point.apply(this, [multipoint.components[i]]));\n            }\n            return array;\n        },\n        \n                'linestring': function(linestring) {\n            var array = [];\n            for(var i=0, len=linestring.components.length; i<len; ++i) {\n                array.push(this.extract.point.apply(this, [linestring.components[i]]));\n            }\n            return array;\n        },\n\n                'multilinestring': function(multilinestring) {\n            var array = [];\n            for(var i=0, len=multilinestring.components.length; i<len; ++i) {\n                array.push(this.extract.linestring.apply(this, [multilinestring.components[i]]));\n            }\n            return array;\n        },\n        \n                'polygon': function(polygon) {\n            var array = [];\n            for(var i=0, len=polygon.components.length; i<len; ++i) {\n                array.push(this.extract.linestring.apply(this, [polygon.components[i]]));\n            }\n            return array;\n        },\n\n                'multipolygon': function(multipolygon) {\n            var array = [];\n            for(var i=0, len=multipolygon.components.length; i<len; ++i) {\n                array.push(this.extract.polygon.apply(this, [multipolygon.components[i]]));\n            }\n            return array;\n        },\n        \n                'collection': function(collection) {\n            var len = collection.components.length;\n            var array = new Array(len);\n            for(var i=0; i<len; ++i) {\n                array[i] = this.extract.geometry.apply(\n                    this, [collection.components[i]]\n                );\n            }\n            return array;\n        }\n        \n\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.GeoJSON\" \n\n});     \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/GeoRSS.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.GeoRSS = OpenLayers.Class(OpenLayers.Format.XML, {\n    \n        rssns: \"http://backend.userland.com/rss2\",\n    \n        featureNS: \"http://mapserver.gis.umn.edu/mapserver\",\n    \n        georssns: \"http://www.georss.org/georss\",\n\n        geons: \"http://www.w3.org/2003/01/geo/wgs84_pos#\",\n    \n        featureTitle: \"Untitled\",\n    \n        featureDescription: \"No Description\",\n    \n        gmlParser: null,\n\n        \n        createGeometryFromItem: function(item) {\n        var point = this.getElementsByTagNameNS(item, this.georssns, \"point\");\n        var lat = this.getElementsByTagNameNS(item, this.geons, 'lat');\n        var lon = this.getElementsByTagNameNS(item, this.geons, 'long');\n        \n        var line = this.getElementsByTagNameNS(item,\n                                                this.georssns,\n                                                \"line\");\n        var polygon = this.getElementsByTagNameNS(item,\n                                                this.georssns,\n                                                \"polygon\");\n        var where = this.getElementsByTagNameNS(item, \n                                                this.georssns, \n                                                \"where\");\n        var box = this.getElementsByTagNameNS(item, \n                                              this.georssns, \n                                              \"box\");\n\n        if (point.length > 0 || (lat.length > 0 && lon.length > 0)) {\n            var location;\n            if (point.length > 0) {\n                location = OpenLayers.String.trim(\n                                point[0].firstChild.nodeValue).split(/\\s+/);\n                if (location.length !=2) {\n                    location = OpenLayers.String.trim(\n                                point[0].firstChild.nodeValue).split(/\\s*,\\s*/);\n                }\n            } else {\n                location = [parseFloat(lat[0].firstChild.nodeValue),\n                                parseFloat(lon[0].firstChild.nodeValue)];\n            }    \n\n            var geometry = new OpenLayers.Geometry.Point(location[1], location[0]);\n              \n        } else if (line.length > 0) {\n            var coords = OpenLayers.String.trim(this.getChildValue(line[0])).split(/\\s+/);\n            var components = []; \n            var point;\n            for (var i=0, len=coords.length; i<len; i+=2) {\n                point = new OpenLayers.Geometry.Point(coords[i+1], coords[i]);\n                components.push(point);\n            }\n            geometry = new OpenLayers.Geometry.LineString(components);\n        } else if (polygon.length > 0) { \n            var coords = OpenLayers.String.trim(this.getChildValue(polygon[0])).split(/\\s+/);\n            var components = []; \n            var point;\n            for (var i=0, len=coords.length; i<len; i+=2) {\n                point = new OpenLayers.Geometry.Point(coords[i+1], coords[i]);\n                components.push(point);\n            }\n            geometry = new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(components)]);\n        } else if (where.length > 0) { \n            if (!this.gmlParser) {\n              this.gmlParser = new OpenLayers.Format.GML({'xy': this.xy});\n            }\n            var feature = this.gmlParser.parseFeature(where[0]);\n            geometry = feature.geometry;\n        } else if (box.length  > 0) {\n            var coords = OpenLayers.String.trim(box[0].firstChild.nodeValue).split(/\\s+/);\n            var components = [];\n            var point;\n            if (coords.length > 3) {\n                point = new OpenLayers.Geometry.Point(coords[1], coords[0]);\n                components.push(point);\n                point = new OpenLayers.Geometry.Point(coords[1], coords[2]);\n                components.push(point);\n                point = new OpenLayers.Geometry.Point(coords[3], coords[2]);\n                components.push(point);\n                point = new OpenLayers.Geometry.Point(coords[3], coords[0]);\n                components.push(point);\n                point = new OpenLayers.Geometry.Point(coords[1], coords[0]);\n                components.push(point);\n            }\n            geometry = new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing(components)]);\n        }\n        \n        if (geometry && this.internalProjection && this.externalProjection) {\n            geometry.transform(this.externalProjection, \n                               this.internalProjection);\n        }\n\n        return geometry;\n    },        \n\n        createFeatureFromItem: function(item) {\n        var geometry = this.createGeometryFromItem(item);\n     \n        /* Provide defaults for title and description */\n        var title = this._getChildValue(item, \"*\", \"title\", this.featureTitle);\n       \n        /* First try RSS descriptions, then Atom summaries */\n        var description = this._getChildValue(\n            item, \"*\", \"description\",\n            this._getChildValue(item, \"*\", \"content\",\n                this._getChildValue(item, \"*\", \"summary\", this.featureDescription)));\n\n        /* If no link URL is found in the first child node, try the\n           href attribute */\n        var link = this._getChildValue(item, \"*\", \"link\");\n        if(!link) {\n            try {\n                link = this.getElementsByTagNameNS(item, \"*\", \"link\")[0].getAttribute(\"href\");\n            } catch(e) {\n                link = null;\n            }\n        }\n\n        var id = this._getChildValue(item, \"*\", \"id\", null);\n        \n        var data = {\n            \"title\": title,\n            \"description\": description,\n            \"link\": link\n        };\n        var feature = new OpenLayers.Feature.Vector(geometry, data);\n        feature.fid = id;\n        return feature;\n    },        \n    \n        _getChildValue: function(node, nsuri, name, def) {\n        var value;\n        var eles = this.getElementsByTagNameNS(node, nsuri, name);\n        if(eles && eles[0] && eles[0].firstChild\n            && eles[0].firstChild.nodeValue) {\n            value = this.getChildValue(eles[0]);\n        } else {\n            value = (def == undefined) ? \"\" : def;\n        }\n        return value;\n    },\n    \n        read: function(doc) {\n        if (typeof doc == \"string\") { \n            doc = OpenLayers.Format.XML.prototype.read.apply(this, [doc]);\n        }\n\n        /* Try RSS items first, then Atom entries */\n        var itemlist = null;\n        itemlist = this.getElementsByTagNameNS(doc, '*', 'item');\n        if (itemlist.length == 0) {\n            itemlist = this.getElementsByTagNameNS(doc, '*', 'entry');\n        }\n        \n        var numItems = itemlist.length;\n        var features = new Array(numItems);\n        for(var i=0; i<numItems; i++) {\n            features[i] = this.createFeatureFromItem(itemlist[i]);\n        }\n        return features;\n    },\n    \n\n        write: function(features) {\n        var georss;\n        if(OpenLayers.Util.isArray(features)) {\n            georss = this.createElementNS(this.rssns, \"rss\");\n            for(var i=0, len=features.length; i<len; i++) {\n                georss.appendChild(this.createFeatureXML(features[i]));\n            }\n        } else {\n            georss = this.createFeatureXML(features);\n        }\n        return OpenLayers.Format.XML.prototype.write.apply(this, [georss]);\n    },\n\n        createFeatureXML: function(feature) {\n        var geometryNode = this.buildGeometryNode(feature.geometry);\n        var featureNode = this.createElementNS(this.rssns, \"item\");\n        var titleNode = this.createElementNS(this.rssns, \"title\");\n        titleNode.appendChild(this.createTextNode(feature.attributes.title ? feature.attributes.title : \"\"));\n        var descNode = this.createElementNS(this.rssns, \"description\");\n        descNode.appendChild(this.createTextNode(feature.attributes.description ? feature.attributes.description : \"\"));\n        featureNode.appendChild(titleNode);\n        featureNode.appendChild(descNode);\n        if (feature.attributes.link) {\n            var linkNode = this.createElementNS(this.rssns, \"link\");\n            linkNode.appendChild(this.createTextNode(feature.attributes.link));\n            featureNode.appendChild(linkNode);\n        }    \n        for(var attr in feature.attributes) {\n            if (attr == \"link\" || attr == \"title\" || attr == \"description\") { continue; } \n            var attrText = this.createTextNode(feature.attributes[attr]); \n            var nodename = attr;\n            if (attr.search(\":\") != -1) {\n                nodename = attr.split(\":\")[1];\n            }    \n            var attrContainer = this.createElementNS(this.featureNS, \"feature:\"+nodename);\n            attrContainer.appendChild(attrText);\n            featureNode.appendChild(attrContainer);\n        }    \n        featureNode.appendChild(geometryNode);\n        return featureNode;\n    },    \n    \n        buildGeometryNode: function(geometry) {\n        if (this.internalProjection && this.externalProjection) {\n            geometry = geometry.clone();\n            geometry.transform(this.internalProjection, \n                               this.externalProjection);\n        }\n        var node;\n        if (geometry.CLASS_NAME == \"OpenLayers.Geometry.Polygon\") {\n            node = this.createElementNS(this.georssns, 'georss:polygon');\n            \n            node.appendChild(this.buildCoordinatesNode(geometry.components[0]));\n        }\n        else if (geometry.CLASS_NAME == \"OpenLayers.Geometry.LineString\") {\n            node = this.createElementNS(this.georssns, 'georss:line');\n            \n            node.appendChild(this.buildCoordinatesNode(geometry));\n        }\n        else if (geometry.CLASS_NAME == \"OpenLayers.Geometry.Point\") {\n            node = this.createElementNS(this.georssns, 'georss:point');\n            node.appendChild(this.buildCoordinatesNode(geometry));\n        } else {\n            throw \"Couldn't parse \" + geometry.CLASS_NAME;\n        }  \n        return node;         \n    },\n    \n        buildCoordinatesNode: function(geometry) {\n        var points = null;\n        \n        if (geometry.components) {\n            points = geometry.components;\n        }\n\n        var path;\n        if (points) {\n            var numPoints = points.length;\n            var parts = new Array(numPoints);\n            for (var i = 0; i < numPoints; i++) {\n                parts[i] = points[i].y + \" \" + points[i].x;\n            }\n            path = parts.join(\" \");\n        } else {\n            path = geometry.y + \" \" + geometry.x;\n        }\n        return this.createTextNode(path);\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.GeoRSS\" \n});     \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/JSON.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Format.JSON = OpenLayers.Class(OpenLayers.Format, {\n    \n        indent: \"    \",\n    \n        space: \" \",\n    \n        newline: \"\\n\",\n    \n        level: 0,\n\n        pretty: false,\n\n        nativeJSON: (function() {\n        return !!(window.JSON && typeof JSON.parse == \"function\" && typeof JSON.stringify == \"function\");\n    })(),\n\n    \n        read: function(json, filter) {\n        var object;\n        if (this.nativeJSON) {\n            object = JSON.parse(json, filter);\n        } else try {\n                        if (/^[\\],:{}\\s]*$/.test(json.replace(/\\\\[\"\\\\\\/bfnrtu]/g, '@').\n                                replace(/\"[^\"\\\\\\n\\r]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/g, ']').\n                                replace(/(?:^|:|,)(?:\\s*\\[)+/g, ''))) {\n\n                                object = eval('(' + json + ')');\n\n                                if(typeof filter === 'function') {\n                    function walk(k, v) {\n                        if(v && typeof v === 'object') {\n                            for(var i in v) {\n                                if(v.hasOwnProperty(i)) {\n                                    v[i] = walk(i, v[i]);\n                                }\n                            }\n                        }\n                        return filter(k, v);\n                    }\n                    object = walk('', object);\n                }\n            }\n        } catch(e) {\n        }\n\n        if(this.keepData) {\n            this.data = object;\n        }\n\n        return object;\n    },\n\n        write: function(value, pretty) {\n        this.pretty = !!pretty;\n        var json = null;\n        var type = typeof value;\n        if(this.serialize[type]) {\n            try {\n                json = (!this.pretty && this.nativeJSON) ?\n                    JSON.stringify(value) :\n                    this.serialize[type].apply(this, [value]);\n            } catch(err) {\n                OpenLayers.Console.error(\"Trouble serializing: \" + err);\n            }\n        }\n        return json;\n    },\n    \n        writeIndent: function() {\n        var pieces = [];\n        if(this.pretty) {\n            for(var i=0; i<this.level; ++i) {\n                pieces.push(this.indent);\n            }\n        }\n        return pieces.join('');\n    },\n    \n        writeNewline: function() {\n        return (this.pretty) ? this.newline : '';\n    },\n    \n        writeSpace: function() {\n        return (this.pretty) ? this.space : '';\n    },\n\n        serialize: {\n                'object': function(object) {\n            if(object == null) {\n                return \"null\";\n            }\n            if(object.constructor == Date) {\n                return this.serialize.date.apply(this, [object]);\n            }\n            if(object.constructor == Array) {\n                return this.serialize.array.apply(this, [object]);\n            }\n            var pieces = ['{'];\n            this.level += 1;\n            var key, keyJSON, valueJSON;\n            \n            var addComma = false;\n            for(key in object) {\n                if(object.hasOwnProperty(key)) {\n                    keyJSON = OpenLayers.Format.JSON.prototype.write.apply(this,\n                                                    [key, this.pretty]);\n                    valueJSON = OpenLayers.Format.JSON.prototype.write.apply(this,\n                                                    [object[key], this.pretty]);\n                    if(keyJSON != null && valueJSON != null) {\n                        if(addComma) {\n                            pieces.push(',');\n                        }\n                        pieces.push(this.writeNewline(), this.writeIndent(),\n                                    keyJSON, ':', this.writeSpace(), valueJSON);\n                        addComma = true;\n                    }\n                }\n            }\n            \n            this.level -= 1;\n            pieces.push(this.writeNewline(), this.writeIndent(), '}');\n            return pieces.join('');\n        },\n        \n                'array': function(array) {\n            var json;\n            var pieces = ['['];\n            this.level += 1;\n    \n            for(var i=0, len=array.length; i<len; ++i) {\n                json = OpenLayers.Format.JSON.prototype.write.apply(this,\n                                                    [array[i], this.pretty]);\n                if(json != null) {\n                    if(i > 0) {\n                        pieces.push(',');\n                    }\n                    pieces.push(this.writeNewline(), this.writeIndent(), json);\n                }\n            }\n\n            this.level -= 1;    \n            pieces.push(this.writeNewline(), this.writeIndent(), ']');\n            return pieces.join('');\n        },\n        \n                'string': function(string) {\n            var m = {\n                '\\b': '\\\\b',\n                '\\t': '\\\\t',\n                '\\n': '\\\\n',\n                '\\f': '\\\\f',\n                '\\r': '\\\\r',\n                '\"' : '\\\\\"',\n                '\\\\': '\\\\\\\\'\n            };\n            if(/[\"\\\\\\x00-\\x1f]/.test(string)) {\n                return '\"' + string.replace(/([\\x00-\\x1f\\\\\"])/g, function(a, b) {\n                    var c = m[b];\n                    if(c) {\n                        return c;\n                    }\n                    c = b.charCodeAt();\n                    return '\\\\u00' +\n                        Math.floor(c / 16).toString(16) +\n                        (c % 16).toString(16);\n                }) + '\"';\n            }\n            return '\"' + string + '\"';\n        },\n\n                'number': function(number) {\n            return isFinite(number) ? String(number) : \"null\";\n        },\n        \n                'boolean': function(bool) {\n            return String(bool);\n        },\n        \n                'date': function(date) {    \n            function format(number) {\n                return (number < 10) ? '0' + number : number;\n            }\n            return '\"' + date.getFullYear() + '-' +\n                    format(date.getMonth() + 1) + '-' +\n                    format(date.getDate()) + 'T' +\n                    format(date.getHours()) + ':' +\n                    format(date.getMinutes()) + ':' +\n                    format(date.getSeconds()) + '\"';\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.JSON\" \n\n});     \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/KML.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.KML = OpenLayers.Class(OpenLayers.Format.XML, {\n    \n        namespaces: {\n        kml: \"http://www.opengis.net/kml/2.2\",\n        gx: \"http://www.google.com/kml/ext/2.2\"\n    },\n\n        kmlns: \"http://earth.google.com/kml/2.0\",\n    \n        placemarksDesc: \"No description available\",\n    \n        foldersName: \"OpenLayers export\",\n    \n        foldersDesc: \"Exported on \" + new Date(),\n    \n        extractAttributes: true,\n    \n        kvpAttributes: false,\n    \n        extractStyles: false,\n    \n        extractTracks: false,\n    \n        trackAttributes: null,\n    \n        internalns: null,\n\n        features: null,\n\n        styles: null,\n    \n        styleBaseUrl: \"\",\n\n        fetched: null,\n\n        maxDepth: 0,\n\n        initialize: function(options) {\n        this.regExes = {\n            trimSpace: (/^\\s*|\\s*$/g),\n            removeSpace: (/\\s*/g),\n            splitSpace: (/\\s+/),\n            trimComma: (/\\s*,\\s*/g),\n            kmlColor: (/(\\w{2})(\\w{2})(\\w{2})(\\w{2})/),\n            kmlIconPalette: (/root:\\/\\/icons\\/palette-(\\d+)(\\.\\w+)/),\n            straightBracket: (/\\$\\[(.*?)\\]/g)\n        };\n        this.externalProjection = new OpenLayers.Projection(\"EPSG:4326\");\n\n        OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);\n    },\n\n        read: function(data) {\n        this.features = [];\n        this.styles   = {};\n        this.fetched  = {};\n        var options = {\n            depth: 0,\n            styleBaseUrl: this.styleBaseUrl\n        };\n\n        return this.parseData(data, options);\n    },\n\n        parseData: function(data, options) {\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        var types = [\"Link\", \"NetworkLink\", \"Style\", \"StyleMap\", \"Placemark\"];\n        for(var i=0, len=types.length; i<len; ++i) {\n            var type = types[i];\n\n            var nodes = this.getElementsByTagNameNS(data, \"*\", type);\n            if(nodes.length == 0) { \n                continue;\n            }\n\n            switch (type.toLowerCase()) {\n                case \"link\":\n                case \"networklink\":\n                    this.parseLinks(nodes, options);\n                    break;\n                case \"style\":\n                    if (this.extractStyles) {\n                        this.parseStyles(nodes, options);\n                    }\n                    break;\n                case \"stylemap\":\n                    if (this.extractStyles) {\n                        this.parseStyleMaps(nodes, options);\n                    }\n                    break;\n                case \"placemark\":\n                    this.parseFeatures(nodes, options);\n                    break;\n            }\n        }\n        \n        return this.features;\n    },\n\n        parseLinks: function(nodes, options) {\n        if (options.depth >= this.maxDepth) {\n            return false;\n        }\n        var newOptions = OpenLayers.Util.extend({}, options);\n        newOptions.depth++;\n\n        for(var i=0, len=nodes.length; i<len; i++) {\n            var href = this.parseProperty(nodes[i], \"*\", \"href\");\n            if(href && !this.fetched[href]) {\n                this.fetched[href] = true; // prevent reloading the same urls\n                var data = this.fetchLink(href);\n                if (data) {\n                    this.parseData(data, newOptions);\n                }\n            } \n        }\n\n    },\n\n        fetchLink: function(href) {\n        var request = OpenLayers.Request.GET({url: href, async: false});\n        if (request) {\n            return request.responseText;\n        }\n    },\n\n        parseStyles: function(nodes, options) {\n        for(var i=0, len=nodes.length; i<len; i++) {\n            var style = this.parseStyle(nodes[i]);\n            if(style) {\n                var styleName = (options.styleBaseUrl || \"\") + \"#\" + style.id;\n                \n                this.styles[styleName] = style;\n            }\n        }\n    },\n\n        parseKmlColor: function(kmlColor) {\n        var color = null;\n        if (kmlColor) {\n            var matches = kmlColor.match(this.regExes.kmlColor);\n            if (matches) {\n                color = {\n                    color: '#' + matches[4] + matches[3] + matches[2],\n                    opacity: parseInt(matches[1], 16) / 255\n                };\n            }\n        }\n        return color;\n    },\n\n        parseStyle: function(node) {\n        var style = {};\n        \n        var types = [\"LineStyle\", \"PolyStyle\", \"IconStyle\", \"BalloonStyle\", \n                     \"LabelStyle\"];\n        var type, styleTypeNode, nodeList, geometry, parser;\n        for(var i=0, len=types.length; i<len; ++i) {\n            type = types[i];\n            styleTypeNode = this.getElementsByTagNameNS(node, \"*\", type)[0];\n            if(!styleTypeNode) { \n                continue;\n            }\n            switch (type.toLowerCase()) {\n                case \"linestyle\":\n                    var kmlColor = this.parseProperty(styleTypeNode, \"*\", \"color\");\n                    var color = this.parseKmlColor(kmlColor);\n                    if (color) {\n                        style[\"strokeColor\"] = color.color;\n                        style[\"strokeOpacity\"] = color.opacity;\n                    }\n                    \n                    var width = this.parseProperty(styleTypeNode, \"*\", \"width\");\n                    if (width) {\n                        style[\"strokeWidth\"] = width;\n                    }\n                    break;\n\n                case \"polystyle\":\n                    var kmlColor = this.parseProperty(styleTypeNode, \"*\", \"color\");\n                    var color = this.parseKmlColor(kmlColor);\n                    if (color) {\n                        style[\"fillOpacity\"] = color.opacity;\n                        style[\"fillColor\"] = color.color;\n                    }\n                    var fill = this.parseProperty(styleTypeNode, \"*\", \"fill\");\n                    if (fill == \"0\") {\n                        style[\"fillColor\"] = \"none\";\n                    }\n                    var outline = this.parseProperty(styleTypeNode, \"*\", \"outline\");\n                    if (outline == \"0\") {\n                        style[\"strokeWidth\"] = \"0\";\n                    }\n                   \n                    break;\n\n                case \"iconstyle\":\n                    var scale = parseFloat(this.parseProperty(styleTypeNode, \n                                                          \"*\", \"scale\") || 1);\n                    var width = 32 * scale;\n                    var height = 32 * scale;\n\n                    var iconNode = this.getElementsByTagNameNS(styleTypeNode, \n                                               \"*\", \n                                               \"Icon\")[0];\n                    if (iconNode) {\n                        var href = this.parseProperty(iconNode, \"*\", \"href\");\n                        if (href) {                                                   \n\n                            var w = this.parseProperty(iconNode, \"*\", \"w\");\n                            var h = this.parseProperty(iconNode, \"*\", \"h\");\n                            var google = \"http://maps.google.com/mapfiles/kml\";\n                            if (OpenLayers.String.startsWith(\n                                                 href, google) && !w && !h) {\n                                w = 64;\n                                h = 64;\n                                scale = scale / 2;\n                            }\n                            w = w || h;\n                            h = h || w;\n\n                            if (w) {\n                                width = parseInt(w) * scale;\n                            }\n\n                            if (h) {\n                                height = parseInt(h) * scale;\n                            }\n                            var matches = href.match(this.regExes.kmlIconPalette);\n                            if (matches)  {\n                                var palette = matches[1];\n                                var file_extension = matches[2];\n\n                                var x = this.parseProperty(iconNode, \"*\", \"x\");\n                                var y = this.parseProperty(iconNode, \"*\", \"y\");\n\n                                var posX = x ? x/32 : 0;\n                                var posY = y ? (7 - y/32) : 7;\n\n                                var pos = posY * 8 + posX;\n                                href = \"http://maps.google.com/mapfiles/kml/pal\" \n                                     + palette + \"/icon\" + pos + file_extension;\n                            }\n\n                            style[\"graphicOpacity\"] = 1; // fully opaque\n                            style[\"externalGraphic\"] = href;\n                        }\n\n                    }\n                    var hotSpotNode = this.getElementsByTagNameNS(styleTypeNode, \n                                               \"*\", \n                                               \"hotSpot\")[0];\n                    if (hotSpotNode) {\n                        var x = parseFloat(hotSpotNode.getAttribute(\"x\"));\n                        var y = parseFloat(hotSpotNode.getAttribute(\"y\"));\n\n                        var xUnits = hotSpotNode.getAttribute(\"xunits\");\n                        if (xUnits == \"pixels\") {\n                            style[\"graphicXOffset\"] = -x * scale;\n                        }\n                        else if (xUnits == \"insetPixels\") {\n                            style[\"graphicXOffset\"] = -width + (x * scale);\n                        }\n                        else if (xUnits == \"fraction\") {\n                            style[\"graphicXOffset\"] = -width * x;\n                        }\n\n                        var yUnits = hotSpotNode.getAttribute(\"yunits\");\n                        if (yUnits == \"pixels\") {\n                            style[\"graphicYOffset\"] = -height + (y * scale) + 1;\n                        }\n                        else if (yUnits == \"insetPixels\") {\n                            style[\"graphicYOffset\"] = -(y * scale) + 1;\n                        }\n                        else if (yUnits == \"fraction\") {\n                            style[\"graphicYOffset\"] =  -height * (1 - y) + 1;\n                        }\n                    }\n\n                    style[\"graphicWidth\"] = width;\n                    style[\"graphicHeight\"] = height;\n                    break;\n\n                case \"balloonstyle\":\n                    var balloonStyle = OpenLayers.Util.getXmlNodeValue(\n                                            styleTypeNode);\n                    if (balloonStyle) {\n                        style[\"balloonStyle\"] = balloonStyle.replace(\n                                       this.regExes.straightBracket, \"${$1}\");\n                    }\n                    break;\n                case \"labelstyle\":\n                    var kmlColor = this.parseProperty(styleTypeNode, \"*\", \"color\");\n                    var color = this.parseKmlColor(kmlColor);\n                    if (color) {\n                        style[\"fontColor\"] = color.color;\n                        style[\"fontOpacity\"] = color.opacity;\n                    }\n                    break;\n\n                default:\n            }\n        }\n        if (!style[\"strokeColor\"] && style[\"fillColor\"]) {\n            style[\"strokeColor\"] = style[\"fillColor\"];\n        }\n\n        var id = node.getAttribute(\"id\");\n        if (id && style) {\n            style.id = id;\n        }\n\n        return style;\n    },\n\n        parseStyleMaps: function(nodes, options) {\n\n        for(var i=0, len=nodes.length; i<len; i++) {\n            var node = nodes[i];\n            var pairs = this.getElementsByTagNameNS(node, \"*\", \n                            \"Pair\");\n\n            var id = node.getAttribute(\"id\");\n            for (var j=0, jlen=pairs.length; j<jlen; j++) {\n                var pair = pairs[j];\n                var key = this.parseProperty(pair, \"*\", \"key\");\n                var styleUrl = this.parseProperty(pair, \"*\", \"styleUrl\");\n\n                if (styleUrl && key == \"normal\") {\n                    this.styles[(options.styleBaseUrl || \"\") + \"#\" + id] =\n                        this.styles[(options.styleBaseUrl || \"\") + styleUrl];\n                }\n\n            }\n        }\n\n    },\n\n\n        parseFeatures: function(nodes, options) {\n        var features = [];\n        for(var i=0, len=nodes.length; i<len; i++) {\n            var featureNode = nodes[i];\n            var feature = this.parseFeature.apply(this,[featureNode]) ;\n            if(feature) {\n                if (this.extractStyles && feature.attributes &&\n                    feature.attributes.styleUrl) {\n                    feature.style = this.getStyle(feature.attributes.styleUrl, options);\n                }\n\n                if (this.extractStyles) {\n                    var inlineStyleNode = this.getElementsByTagNameNS(featureNode,\n                                                        \"*\",\n                                                        \"Style\")[0];\n                    if (inlineStyleNode) {\n                        var inlineStyle= this.parseStyle(inlineStyleNode);\n                        if (inlineStyle) {\n                            feature.style = OpenLayers.Util.extend(\n                                feature.style, inlineStyle\n                            );\n                        }\n                    }\n                }\n                if (this.extractTracks) {\n                    var tracks = this.getElementsByTagNameNS(\n                        featureNode, this.namespaces.gx, \"Track\"\n                    );\n                    if (tracks && tracks.length > 0) {\n                        var track = tracks[0];\n                        var container = {\n                            features: [],\n                            feature: feature\n                        };\n                        this.readNode(track, container);\n                        if (container.features.length > 0) {\n                            features.push.apply(features, container.features);\n                        }\n                    }\n                } else {\n                    features.push(feature);                    \n                }\n            } else {\n                throw \"Bad Placemark: \" + i;\n            }\n        }\n        this.features = this.features.concat(features);\n    },\n    \n        readers: {\n        \"kml\": {\n            \"when\": function(node, container) {\n                container.whens.push(OpenLayers.Date.parse(\n                    this.getChildValue(node)\n                ));\n            },\n            \"_trackPointAttribute\": function(node, container) {\n                var name = node.nodeName.split(\":\").pop();\n                container.attributes[name].push(this.getChildValue(node));\n            }\n        },\n        \"gx\": {\n            \"Track\": function(node, container) {\n                var obj = {\n                    whens: [],\n                    points: [],\n                    angles: []\n                };\n                if (this.trackAttributes) {\n                    var name;\n                    obj.attributes = {};\n                    for (var i=0, ii=this.trackAttributes.length; i<ii; ++i) {\n                        name = this.trackAttributes[i];\n                        obj.attributes[name] = [];\n                        if (!(name in this.readers.kml)) {\n                            this.readers.kml[name] = this.readers.kml._trackPointAttribute;\n                        }\n                    }\n                }\n                this.readChildNodes(node, obj);\n                if (obj.whens.length !== obj.points.length) {\n                    throw new Error(\"gx:Track with unequal number of when (\" +\n                                    obj.whens.length + \") and gx:coord (\" +\n                                    obj.points.length + \") elements.\");\n                }\n                var hasAngles = obj.angles.length > 0;\n                if (hasAngles && obj.whens.length !== obj.angles.length) {\n                    throw new Error(\"gx:Track with unequal number of when (\" +\n                                    obj.whens.length + \") and gx:angles (\" +\n                                    obj.angles.length + \") elements.\");\n                }\n                var feature, point, angles;\n                for (var i=0, ii=obj.whens.length; i<ii; ++i) {\n                    feature = container.feature.clone();\n                    feature.fid = container.feature.fid || container.feature.id;\n                    point = obj.points[i];\n                    feature.geometry = point;\n                    if (\"z\" in point) {\n                        feature.attributes.altitude = point.z;\n                    }\n                    if (this.internalProjection && this.externalProjection) {\n                        feature.geometry.transform(\n                            this.externalProjection, this.internalProjection\n                        ); \n                    }\n                    if (this.trackAttributes) {\n                        for (var j=0, jj=this.trackAttributes.length; j<jj; ++j) {\n                            var name = this.trackAttributes[j];\n                            feature.attributes[name] = obj.attributes[name][i];\n                        }\n                    }\n                    feature.attributes.when = obj.whens[i];\n                    feature.attributes.trackId = container.feature.id;\n                    if (hasAngles) {\n                        angles = obj.angles[i];\n                        feature.attributes.heading = parseFloat(angles[0]);\n                        feature.attributes.tilt = parseFloat(angles[1]);\n                        feature.attributes.roll = parseFloat(angles[2]);\n                    }\n                    container.features.push(feature);\n                }\n            },\n            \"coord\": function(node, container) {\n                var str = this.getChildValue(node);\n                var coords = str.replace(this.regExes.trimSpace, \"\").split(/\\s+/);\n                var point = new OpenLayers.Geometry.Point(coords[0], coords[1]);\n                if (coords.length > 2) {\n                    point.z = parseFloat(coords[2]);\n                }\n                container.points.push(point);\n            },\n            \"angles\": function(node, container) {\n                var str = this.getChildValue(node);\n                var parts = str.replace(this.regExes.trimSpace, \"\").split(/\\s+/);\n                container.angles.push(parts);\n            }\n        }\n    },\n    \n        parseFeature: function(node) {\n        var order = [\"MultiGeometry\", \"Polygon\", \"LineString\", \"Point\"];\n        var type, nodeList, geometry, parser;\n        for(var i=0, len=order.length; i<len; ++i) {\n            type = order[i];\n            this.internalns = node.namespaceURI ? \n                    node.namespaceURI : this.kmlns;\n            nodeList = this.getElementsByTagNameNS(node, \n                                                   this.internalns, type);\n            if(nodeList.length > 0) {\n                var parser = this.parseGeometry[type.toLowerCase()];\n                if(parser) {\n                    geometry = parser.apply(this, [nodeList[0]]);\n                    if (this.internalProjection && this.externalProjection) {\n                        geometry.transform(this.externalProjection, \n                                           this.internalProjection); \n                    }                       \n                } else {\n                    throw new TypeError(\"Unsupported geometry type: \" + type);\n                }\n                break;\n            }\n        }\n        var attributes;\n        if(this.extractAttributes) {\n            attributes = this.parseAttributes(node);\n        }\n        var feature = new OpenLayers.Feature.Vector(geometry, attributes);\n\n        var fid = node.getAttribute(\"id\") || node.getAttribute(\"name\");\n        if(fid != null) {\n            feature.fid = fid;\n        }\n\n        return feature;\n    },        \n    \n        getStyle: function(styleUrl, options) {\n\n        var styleBaseUrl = OpenLayers.Util.removeTail(styleUrl);\n\n        var newOptions = OpenLayers.Util.extend({}, options);\n        newOptions.depth++;\n        newOptions.styleBaseUrl = styleBaseUrl;\n        if (!this.styles[styleUrl] \n                && !OpenLayers.String.startsWith(styleUrl, \"#\") \n                && newOptions.depth <= this.maxDepth\n                && !this.fetched[styleBaseUrl] ) {\n\n            var data = this.fetchLink(styleBaseUrl);\n            if (data) {\n                this.parseData(data, newOptions);\n            }\n\n        }\n        var style = OpenLayers.Util.extend({}, this.styles[styleUrl]);\n        return style;\n    },\n    \n        parseGeometry: {\n        \n                point: function(node) {\n            var nodeList = this.getElementsByTagNameNS(node, this.internalns,\n                                                       \"coordinates\");\n            var coords = [];\n            if(nodeList.length > 0) {\n                var coordString = nodeList[0].firstChild.nodeValue;\n                coordString = coordString.replace(this.regExes.removeSpace, \"\");\n                coords = coordString.split(\",\");\n            }\n\n            var point = null;\n            if(coords.length > 1) {\n                if(coords.length == 2) {\n                    coords[2] = null;\n                }\n                point = new OpenLayers.Geometry.Point(coords[0], coords[1],\n                                                      coords[2]);\n            } else {\n                throw \"Bad coordinate string: \" + coordString;\n            }\n            return point;\n        },\n        \n                linestring: function(node, ring) {\n            var nodeList = this.getElementsByTagNameNS(node, this.internalns,\n                                                       \"coordinates\");\n            var line = null;\n            if(nodeList.length > 0) {\n                var coordString = this.getChildValue(nodeList[0]);\n\n                coordString = coordString.replace(this.regExes.trimSpace,\n                                                  \"\");\n                coordString = coordString.replace(this.regExes.trimComma,\n                                                  \",\");\n                var pointList = coordString.split(this.regExes.splitSpace);\n                var numPoints = pointList.length;\n                var points = new Array(numPoints);\n                var coords, numCoords;\n                for(var i=0; i<numPoints; ++i) {\n                    coords = pointList[i].split(\",\");\n                    numCoords = coords.length;\n                    if(numCoords > 1) {\n                        if(coords.length == 2) {\n                            coords[2] = null;\n                        }\n                        points[i] = new OpenLayers.Geometry.Point(coords[0],\n                                                                  coords[1],\n                                                                  coords[2]);\n                    } else {\n                        throw \"Bad LineString point coordinates: \" +\n                              pointList[i];\n                    }\n                }\n                if(numPoints) {\n                    if(ring) {\n                        line = new OpenLayers.Geometry.LinearRing(points);\n                    } else {\n                        line = new OpenLayers.Geometry.LineString(points);\n                    }\n                } else {\n                    throw \"Bad LineString coordinates: \" + coordString;\n                }\n            }\n\n            return line;\n        },\n        \n                polygon: function(node) {\n            var nodeList = this.getElementsByTagNameNS(node, this.internalns,\n                                                       \"LinearRing\");\n            var numRings = nodeList.length;\n            var components = new Array(numRings);\n            if(numRings > 0) {\n                var ring;\n                for(var i=0, len=nodeList.length; i<len; ++i) {\n                    ring = this.parseGeometry.linestring.apply(this,\n                                                        [nodeList[i], true]);\n                    if(ring) {\n                        components[i] = ring;\n                    } else {\n                        throw \"Bad LinearRing geometry: \" + i;\n                    }\n                }\n            }\n            return new OpenLayers.Geometry.Polygon(components);\n        },\n        \n                multigeometry: function(node) {\n            var child, parser;\n            var parts = [];\n            var children = node.childNodes;\n            for(var i=0, len=children.length; i<len; ++i ) {\n                child = children[i];\n                if(child.nodeType == 1) {\n                    var type = (child.prefix) ?\n                            child.nodeName.split(\":\")[1] :\n                            child.nodeName;\n                    var parser = this.parseGeometry[type.toLowerCase()];\n                    if(parser) {\n                        parts.push(parser.apply(this, [child]));\n                    }\n                }\n            }\n            return new OpenLayers.Geometry.Collection(parts);\n        }\n        \n    },\n\n        parseAttributes: function(node) {\n        var attributes = {};\n        var edNodes = node.getElementsByTagName(\"ExtendedData\");\n        if (edNodes.length) {\n            attributes = this.parseExtendedData(edNodes[0]);\n        }\n        var child, grandchildren, grandchild;\n        var children = node.childNodes;\n\n        for(var i=0, len=children.length; i<len; ++i) {\n            child = children[i];\n            if(child.nodeType == 1) {\n                grandchildren = child.childNodes;\n                if(grandchildren.length >= 1 && grandchildren.length <= 3) {\n                    var grandchild;\n                    switch (grandchildren.length) {\n                        case 1:\n                            grandchild = grandchildren[0];\n                            break;\n                        case 2:\n                            var c1 = grandchildren[0];\n                            var c2 = grandchildren[1];\n                            grandchild = (c1.nodeType == 3 || c1.nodeType == 4) ?\n                                c1 : c2;\n                            break;\n                        case 3:\n                        default:\n                            grandchild = grandchildren[1];\n                            break;\n                    }\n                    if(grandchild.nodeType == 3 || grandchild.nodeType == 4) {\n                        var name = (child.prefix) ?\n                                child.nodeName.split(\":\")[1] :\n                                child.nodeName;\n                        var value = OpenLayers.Util.getXmlNodeValue(grandchild);\n                        if (value) {\n                            value = value.replace(this.regExes.trimSpace, \"\");\n                            attributes[name] = value;\n                        }\n                    }\n                } \n            }\n        }\n        return attributes;\n    },\n\n        parseExtendedData: function(node) {\n        var attributes = {};\n        var i, len, data, key;\n        var dataNodes = node.getElementsByTagName(\"Data\");\n        for (i = 0, len = dataNodes.length; i < len; i++) {\n            data = dataNodes[i];\n            key = data.getAttribute(\"name\");\n            var ed = {};\n            var valueNode = data.getElementsByTagName(\"value\");\n            if (valueNode.length) {\n                ed['value'] = this.getChildValue(valueNode[0]);\n            }\n            if (this.kvpAttributes) {\n                attributes[key] = ed['value'];\n            } else {\n                var nameNode = data.getElementsByTagName(\"displayName\");\n                if (nameNode.length) {\n                    ed['displayName'] = this.getChildValue(nameNode[0]);\n                }\n                attributes[key] = ed;\n            } \n        }\n        var simpleDataNodes = node.getElementsByTagName(\"SimpleData\");\n        for (i = 0, len = simpleDataNodes.length; i < len; i++) {\n            var ed = {};\n            data = simpleDataNodes[i];\n            key = data.getAttribute(\"name\");\n            ed['value'] = this.getChildValue(data);\n            if (this.kvpAttributes) {\n                attributes[key] = ed['value'];\n            } else {\n                ed['displayName'] = key;\n                attributes[key] = ed;\n            }\n        }\n        \n        return attributes;    \n    },\n    \n        write: function(features) {\n        if(!(OpenLayers.Util.isArray(features))) {\n            features = [features];\n        }\n        var kml = this.createElementNS(this.kmlns, \"kml\");\n        var folder = this.createFolderXML();\n        for(var i=0, len=features.length; i<len; ++i) {\n            folder.appendChild(this.createPlacemarkXML(features[i]));\n        }\n        kml.appendChild(folder);\n        return OpenLayers.Format.XML.prototype.write.apply(this, [kml]);\n    },\n\n        createFolderXML: function() {\n        var folder = this.createElementNS(this.kmlns, \"Folder\");\n        if (this.foldersName) {\n            var folderName = this.createElementNS(this.kmlns, \"name\");\n            var folderNameText = this.createTextNode(this.foldersName); \n            folderName.appendChild(folderNameText);\n            folder.appendChild(folderName);\n        }\n        if (this.foldersDesc) {\n            var folderDesc = this.createElementNS(this.kmlns, \"description\");        \n            var folderDescText = this.createTextNode(this.foldersDesc); \n            folderDesc.appendChild(folderDescText);\n            folder.appendChild(folderDesc);\n        }\n\n        return folder;\n    },\n\n        createPlacemarkXML: function(feature) {        \n        var placemarkName = this.createElementNS(this.kmlns, \"name\");\n        var label = (feature.style && feature.style.label) ? feature.style.label : feature.id;\n        var name = feature.attributes.name || label;\n        placemarkName.appendChild(this.createTextNode(name));\n        var placemarkDesc = this.createElementNS(this.kmlns, \"description\");\n        var desc = feature.attributes.description || this.placemarksDesc;\n        placemarkDesc.appendChild(this.createTextNode(desc));\n        var placemarkNode = this.createElementNS(this.kmlns, \"Placemark\");\n        if(feature.fid != null) {\n            placemarkNode.setAttribute(\"id\", feature.fid);\n        }\n        placemarkNode.appendChild(placemarkName);\n        placemarkNode.appendChild(placemarkDesc);\n        if (feature.attributes) {\n            var edNode = this.buildExtendedData(feature.attributes);\n            if (edNode) {\n                placemarkNode.appendChild(edNode);\n            }\n        }\n        var geometryNode = this.buildGeometryNode(feature.geometry);\n        placemarkNode.appendChild(geometryNode);        \n        \n        return placemarkNode;\n    },    \n\n        buildGeometryNode: function(geometry) {\n        var className = geometry.CLASS_NAME;\n        var type = className.substring(className.lastIndexOf(\".\") + 1);\n        var builder = this.buildGeometry[type.toLowerCase()];\n        var node = null;\n        if(builder) {\n            node = builder.apply(this, [geometry]);\n        }\n        return node;\n    },\n\n        buildGeometry: {\n\n                point: function(geometry) {\n            var kml = this.createElementNS(this.kmlns, \"Point\");\n            kml.appendChild(this.buildCoordinatesNode(geometry));\n            return kml;\n        },\n        \n                multipoint: function(geometry) {\n            return this.buildGeometry.collection.apply(this, [geometry]);\n        },\n\n                linestring: function(geometry) {\n            var kml = this.createElementNS(this.kmlns, \"LineString\");\n            kml.appendChild(this.buildCoordinatesNode(geometry));\n            return kml;\n        },\n        \n                multilinestring: function(geometry) {\n            return this.buildGeometry.collection.apply(this, [geometry]);\n        },\n\n                linearring: function(geometry) {\n            var kml = this.createElementNS(this.kmlns, \"LinearRing\");\n            kml.appendChild(this.buildCoordinatesNode(geometry));\n            return kml;\n        },\n        \n                polygon: function(geometry) {\n            var kml = this.createElementNS(this.kmlns, \"Polygon\");\n            var rings = geometry.components;\n            var ringMember, ringGeom, type;\n            for(var i=0, len=rings.length; i<len; ++i) {\n                type = (i==0) ? \"outerBoundaryIs\" : \"innerBoundaryIs\";\n                ringMember = this.createElementNS(this.kmlns, type);\n                ringGeom = this.buildGeometry.linearring.apply(this,\n                                                               [rings[i]]);\n                ringMember.appendChild(ringGeom);\n                kml.appendChild(ringMember);\n            }\n            return kml;\n        },\n        \n                multipolygon: function(geometry) {\n            return this.buildGeometry.collection.apply(this, [geometry]);\n        },\n\n                collection: function(geometry) {\n            var kml = this.createElementNS(this.kmlns, \"MultiGeometry\");\n            var child;\n            for(var i=0, len=geometry.components.length; i<len; ++i) {\n                child = this.buildGeometryNode.apply(this,\n                                                     [geometry.components[i]]);\n                if(child) {\n                    kml.appendChild(child);\n                }\n            }\n            return kml;\n        }\n    },\n\n        buildCoordinates: function(point) {\n        if (this.internalProjection && this.externalProjection) {\n            point = point.clone();\n            point.transform(this.internalProjection, \n                               this.externalProjection);\n        }\n        return point.x + \",\" + point.y;                     \n    },\n\n        buildExtendedData: function(attributes) {\n        var extendedData = this.createElementNS(this.kmlns, \"ExtendedData\");\n        for (var attributeName in attributes) {\n            if (attributes[attributeName] && attributeName != \"name\" && attributeName != \"description\" && attributeName != \"styleUrl\") {\n                var data = this.createElementNS(this.kmlns, \"Data\");\n                data.setAttribute(\"name\", attributeName);\n                var value = this.createElementNS(this.kmlns, \"value\");\n                if (typeof attributes[attributeName] == \"object\") {\n                    if (attributes[attributeName].value) {\n                        value.appendChild(this.createTextNode(attributes[attributeName].value));\n                    }\n                    if (attributes[attributeName].displayName) {\n                        var displayName = this.createElementNS(this.kmlns, \"displayName\");\n                        displayName.appendChild(this.getXMLDoc().createCDATASection(attributes[attributeName].displayName));\n                        data.appendChild(displayName);\n                    }\n                } else {\n                    value.appendChild(this.createTextNode(attributes[attributeName]));\n                }\n                data.appendChild(value);\n                extendedData.appendChild(data);\n            }\n        }\n        if (this.isSimpleContent(extendedData)) {\n            return null;\n        } else {\n            return extendedData;\n        }\n    },\n    \n    CLASS_NAME: \"OpenLayers.Format.KML\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/OGCExceptionReport.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.OGCExceptionReport = OpenLayers.Class(OpenLayers.Format.XML, {\n\n        namespaces: {\n        ogc: \"http://www.opengis.net/ogc\"\n    },\n\n        regExes: {\n        trimSpace: (/^\\s*|\\s*$/g),\n        removeSpace: (/\\s*/g),\n        splitSpace: (/\\s+/),\n        trimComma: (/\\s*,\\s*/g)\n    },\n\n        defaultPrefix: \"ogc\",\n\n    \n        read: function(data) {\n        var result;\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        var root = data.documentElement;\n        var exceptionInfo = {exceptionReport: null}; \n        if (root) {\n            this.readChildNodes(data, exceptionInfo);\n            if (exceptionInfo.exceptionReport === null) {\n                exceptionInfo = new OpenLayers.Format.OWSCommon().read(data);\n            }\n        }\n        return exceptionInfo;\n    },\n\n        readers: {\n        \"ogc\": {\n            \"ServiceExceptionReport\": function(node, obj) {\n                obj.exceptionReport = {exceptions: []};\n                this.readChildNodes(node, obj.exceptionReport);\n            },\n            \"ServiceException\": function(node, exceptionReport) {\n                var exception = {\n                    code: node.getAttribute(\"code\"),\n                    locator: node.getAttribute(\"locator\"),\n                    text: this.getChildValue(node)\n                };\n                exceptionReport.exceptions.push(exception);\n            }\n        }\n    },\n    \n    CLASS_NAME: \"OpenLayers.Format.OGCExceptionReport\"\n    \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/OSM.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.OSM = OpenLayers.Class(OpenLayers.Format.XML, {\n\n        checkTags: false,\n\n        shareNode: false,\n\n        interestingTagsExclude: null,\n\n        areaTags: null,\n\n        relationsParsers: {},\n\n        initialize: function(options) {\n        var layer_defaults = {\n          'interestingTagsExclude': ['source', 'source_ref',\n              'source:ref', 'history', 'attribution', 'created_by'],\n          'areaTags': ['area', 'building', 'leisure', 'tourism', 'ruins',\n              'historic', 'landuse', 'military', 'natural', 'sport']\n        };\n        options = options ? options : {};\n\n        layer_defaults = OpenLayers.Util.extend(layer_defaults, options);\n\n        var interesting = {};\n        for (var i = 0; i < layer_defaults.interestingTagsExclude.length; i++) {\n            interesting[layer_defaults.interestingTagsExclude[i]] = true;\n        }\n        layer_defaults.interestingTagsExclude = interesting;\n\n        var area = {};\n        for (var i = 0; i < layer_defaults.areaTags.length; i++) {\n            area[layer_defaults.areaTags[i]] = true;\n        }\n        layer_defaults.areaTags = area;\n        this.externalProjection = new OpenLayers.Projection(\"EPSG:4326\");\n\n        OpenLayers.Format.XML.prototype.initialize.apply(this, [layer_defaults]);\n    },\n\n        read: function(doc) {\n        if (typeof doc == \"string\") {\n            doc = OpenLayers.Format.XML.prototype.read.apply(this, [doc]);\n        }\n\n        var nodes = this.getNodes(doc);\n        var ways = this.getWays(doc);\n        var relations = this.getRelations(doc);\n        var feat_list = [];\n\n        for (var relation_id in relations) {\n            var relation = relations[relation_id];\n            if (this.relationsParsers[relation.tags.type]) {\n                var features = this.relationsParsers[relation.tags.type](relation, this, nodes, ways, relations);\n                for (var i = 0, len = features.length ; i < len ; i++) {\n                    feat_list.push(features[i]);\n                }\n            }\n        }\n\n        for (var way_id in ways) {\n            var way = ways[way_id];\n\n            if (way.interesting) {\n                var poly = this.isWayArea(way) ? 1 : 0;\n                var point_list = this.getPointList(way, nodes);\n                var geometry = null;\n                if (poly) {\n                    geometry = new OpenLayers.Geometry.Polygon(\n                        new OpenLayers.Geometry.LinearRing(point_list));\n                }\n                else {\n                    geometry = new OpenLayers.Geometry.LineString(point_list);\n                }\n                var feat = new OpenLayers.Feature.Vector(geometry,\n                    way.tags);\n                feat.osm_id = parseInt(way.id);\n                feat.osm_version = parseInt(way.version);\n                feat.geometry.osm_id = feat.osm_id;\n                feat.type = \"way\";\n                feat.fid = \"way.\" + feat.osm_id;\n                feat_list.push(feat);\n            }\n        }\n        for (var node_id in nodes) {\n            var node = nodes[node_id];\n            if (!node.used || !this.checkTags || Object.keys(node.attributes).length > 1) {\n                feat_list.push(node);\n            }\n        }\n        return feat_list;\n    },\n\n        getPointList: function(way, nodes) {\n        if (!way) {\n            return [];\n        }\n        var point_list = new Array(way.nodes.length);\n        for (var j = 0; j < way.nodes.length; j++) {\n            var node = nodes[way.nodes[j]];\n            node.used = true;\n\n            var point = node.geometry;\n            if (!this.shareNode) {\n                point = new OpenLayers.Geometry.Point(node.geometry.x, node.geometry.y);\n                point.osm_id = node.osm_id;\n            }\n\n            point_list[j] = point;\n        }\n        return point_list;\n    },\n\n        concatPathsIfLinear: function(lastPointList, pointList) {\n        var result = {};\n        if (lastPointList.length == 0) {\n            result.succed = true;\n            result.lastPointList = pointList;\n            return result;\n        }\n        if (pointList.length == 0) {\n            result.succed = true;\n            result.lastPointList = lastPointList;\n            return result;\n        }\n        if (lastPointList[lastPointList.length-1].x == pointList[0].x\n         && lastPointList[lastPointList.length-1].y == pointList[0].y) {\n            pointList = pointList.slice(1, pointList.length);\n            lastPointList = lastPointList.concat(pointList);\n            result.succed = true;\n            result.lastPointList = lastPointList;\n            return result;\n        }\n        else if (lastPointList[0].x == pointList[pointList.length-1].x\n              && lastPointList[0].y == pointList[pointList.length-1].y) {\n            lastPointList = lastPointList.slice(1, lastPointList.length);\n            lastPointList = pointList.concat(lastPointList);\n            result.succed = true;\n            result.lastPointList = lastPointList;\n            return result;\n        }\n        else if (lastPointList[0].x == pointList[0].x\n              && lastPointList[0].y == pointList[0].y) {\n            if (lastPointList.length > pointList.length) {\n                pointList = pointList.slice(1, pointList.length);\n                lastPointList = pointList.reverse().concat(lastPointList);\n            }\n            else {\n                lastPointList = lastPointList.slice(1, lastPointList.length);\n                lastPointList = lastPointList.reverse().concat(pointList);\n            }\n            result.succed = true;\n            result.lastPointList = lastPointList;\n            return result;\n        }\n        else if (lastPointList[lastPointList.length-1].x == pointList[pointList.length-1].x\n              && lastPointList[lastPointList.length-1].y == pointList[pointList.length-1].y) {\n            if (lastPointList.length > pointList.length) {\n                pointList = pointList.slice(0, pointList.length - 1);\n                lastPointList = lastPointList.concat(pointList.reverse());\n            }\n            else {\n                lastPointList = lastPointList.slice(0, lastPointList.length - 1);\n                lastPointList = pointList.concat(lastPointList.reverse());\n            }\n            result.succed = true;\n            result.lastPointList = lastPointList;\n            return result;\n        }\n        result.succed = false;\n        return result;\n    },\n\n        getNodes: function(doc) {\n        var node_list = doc.getElementsByTagName(\"node\");\n        var nodes = {};\n        for (var i = 0; i < node_list.length; i++) {\n            var node = node_list[i];\n            var id = node.getAttribute(\"id\");\n            var geom = new OpenLayers.Geometry.Point(\n                    node.getAttribute(\"lon\"),\n                    node.getAttribute(\"lat\"))\n            if (this.internalProjection && this.externalProjection) {\n                geom.transform(this.externalProjection,\n                    this.internalProjection);\n            }\n            var feat = new OpenLayers.Feature.Vector(geom, this.getTags(node));\n            feat.osm_id = parseInt(id);\n            feat.osm_version = parseInt(node.getAttribute(\"version\"));\n            feat.type = \"node\";\n            feat.fid = \"node.\" + feat.osm_id;\n            feat.geometry.osm_id = feat.osm_id;\n\n            nodes[id] = feat;\n        }\n        return nodes;\n    },\n\n        getRelations: function(doc) {\n        var relation_list = doc.getElementsByTagName(\"relation\");\n        var return_relations = {};\n        for (var i = 0; i < relation_list.length; i++) {\n            var relation = relation_list[i];\n            var id = relation.getAttribute(\"id\");\n            var relation_object = {\n              id: id,\n              version: relation.getAttribute(\"version\")\n            };\n\n            relation_object.tags = this.getTags(relation);\n            relation_object.nodes = [];\n            relation_object.ways = [];\n            relation_object.relations = [];\n\n            var member_list = relation.getElementsByTagName(\"member\");\n\n            for (var j = 0; j < member_list.length; j++) {\n                var member = member_list[j];\n                var type = member.getAttribute(\"type\");\n                if (type == 'node') {\n                    relation_object.nodes[relation_object.nodes.length] = member;\n                }\n                else if (type == 'way') {\n                    relation_object.ways[relation_object.ways.length] = member;\n                }\n                else if (type == 'relation') {\n                    relation_object.relations[relation_object.relations.length] = member;\n                }\n            }\n            return_relations[id] = relation_object;\n        }\n        return return_relations;\n\n    },\n\n        getWays: function(doc) {\n        var way_list = doc.getElementsByTagName(\"way\");\n        var return_ways = {};\n        for (var i = 0; i < way_list.length; i++) {\n            var way = way_list[i];\n            var id = way.getAttribute(\"id\");\n            var way_object = {\n              id: id,\n              version: way.getAttribute(\"version\")\n            };\n\n            if (this.checkTags) {\n                var result = this.getTags(way, true);\n                way_object.interesting = result[1];\n                way_object.tags = result[0];\n            } else {\n                way_object.interesting = true;\n                way_object.tags = this.getTags(way);\n            }\n\n            var node_list = way.getElementsByTagName(\"nd\");\n\n            way_object.nodes = new Array(node_list.length);\n\n            for (var j = 0; j < node_list.length; j++) {\n                way_object.nodes[j] = node_list[j].getAttribute(\"ref\");\n            }\n            return_ways[id] = way_object;\n        }\n        return return_ways;\n\n    },\n\n        getTags: function(dom_node, interesting_tags) {\n        var tag_list = dom_node.getElementsByTagName(\"tag\");\n        var tags = {};\n        var interesting = false;\n        for (var j = 0; j < tag_list.length; j++) {\n            var key = tag_list[j].getAttribute(\"k\");\n            if (!this.checkTags || !this.interestingTagsExclude[key]) {\n                tags[key] = tag_list[j].getAttribute(\"v\");\n            }\n            if (interesting_tags && !this.interestingTagsExclude[key]) {\n                interesting = true;\n            }\n        }\n        return interesting_tags ? [tags, interesting] : tags;\n    },\n\n        isWayArea: function(way) {\n        var poly_shaped = false;\n        var poly_tags = false;\n\n        if (way.nodes[0] == way.nodes[way.nodes.length - 1]) {\n            poly_shaped = true;\n        }\n        if (this.checkTags) {\n            for(var key in way.tags) {\n                if (this.areaTags[key]) {\n                    poly_tags = true;\n                    break;\n                }\n            }\n        }\n        return poly_shaped && (this.checkTags ? poly_tags : true);\n    },\n\n        write: function(features) {\n        if (!(OpenLayers.Util.isArray(features))) {\n            features = [features];\n        }\n\n        this.osm_id = 1;\n        this.created_nodes = {};\n        var root_node = this.createElementNS(null, \"osm\");\n        root_node.setAttribute(\"version\", \"0.5\");\n        root_node.setAttribute(\"generator\", \"OpenLayers \"+ OpenLayers.VERSION_NUMBER);\n        for(var i = features.length - 1; i >= 0; i--) {\n            var nodes = this.createFeatureNodes(features[i]);\n            for (var j = 0; j < nodes.length; j++) {\n                root_node.appendChild(nodes[j]);\n            }\n        }\n        return OpenLayers.Format.XML.prototype.write.apply(this, [root_node]);\n    },\n\n        createFeatureNodes: function(feature) {\n        var nodes = [];\n        var className = feature.geometry.CLASS_NAME;\n        var type = className.substring(className.lastIndexOf(\".\") + 1);\n        type = type.toLowerCase();\n        var builder = this.createXML[type];\n        if (builder) {\n            nodes = builder.apply(this, [feature]);\n        }\n        return nodes;\n    },\n\n        createXML: {\n        'point': function(point) {\n            var id = null;\n            var geometry = point.geometry ? point.geometry : point;\n\n            if (this.internalProjection && this.externalProjection) {\n                geometry = geometry.clone();\n                geometry.transform(this.internalProjection,\n                                   this.externalProjection);\n            }\n\n            var already_exists = false; // We don't return anything if the node\n            if (point.osm_id) {\n                id = point.osm_id;\n                if (this.created_nodes[id]) {\n                    already_exists = true;\n                }\n            } else {\n               id = -this.osm_id;\n               this.osm_id++;\n            }\n            if (already_exists) {\n                node = this.created_nodes[id];\n            } else {\n                var node = this.createElementNS(null, \"node\");\n            }\n            this.created_nodes[id] = node;\n            node.setAttribute(\"id\", id);\n            node.setAttribute(\"lon\", geometry.x);\n            node.setAttribute(\"lat\", geometry.y);\n            if (point.attributes) {\n                this.serializeTags(point, node);\n            }\n            this.setState(point, node);\n            return already_exists ? [] : [node];\n        },\n        linestring: function(feature) {\n            var id;\n            var nodes = [];\n            var geometry = feature.geometry;\n            if (feature.osm_id) {\n                id = feature.osm_id;\n            } else {\n                id = -this.osm_id;\n                this.osm_id++;\n            }\n            var way = this.createElementNS(null, \"way\");\n            way.setAttribute(\"id\", id);\n            for (var i = 0; i < geometry.components.length; i++) {\n                var node = this.createXML['point'].apply(this, [geometry.components[i]]);\n                if (node.length) {\n                    node = node[0];\n                    var node_ref = node.getAttribute(\"id\");\n                    nodes.push(node);\n                } else {\n                    node_ref = geometry.components[i].osm_id;\n                    node = this.created_nodes[node_ref];\n                }\n                this.setState(feature, node);\n                var nd_dom = this.createElementNS(null, \"nd\");\n                nd_dom.setAttribute(\"ref\", node_ref);\n                way.appendChild(nd_dom);\n            }\n            this.serializeTags(feature, way);\n            nodes.push(way);\n\n            return nodes;\n        },\n        polygon: function(feature) {\n            var attrs = OpenLayers.Util.extend({'area':'yes'}, feature.attributes);\n            var feat = new OpenLayers.Feature.Vector(feature.geometry.components[0], attrs);\n            feat.osm_id = feature.osm_id;\n            feat.geometry.osm_id = feat.osm_id;\n            return this.createXML['linestring'].apply(this, [feat]);\n        }\n    },\n\n        serializeTags: function(feature, node) {\n        for (var key in feature.attributes) {\n            var tag = this.createElementNS(null, \"tag\");\n            tag.setAttribute(\"k\", key);\n            tag.setAttribute(\"v\", feature.attributes[key]);\n            node.appendChild(tag);\n        }\n    },\n\n        setState: function(feature, node) {\n        if (feature.state) {\n            var state = null;\n            switch(feature.state) {\n                case OpenLayers.State.UPDATE:\n                    state = \"modify\";\n                case OpenLayers.State.DELETE:\n                    state = \"delete\";\n            }\n            if (state) {\n                node.setAttribute(\"action\", state);\n            }\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.OSM\"\n});\n\nOpenLayers.Format.OSM.multipolygonParser = function(relation, parser, nodes, ways, relations) {\n    var lastRole = '';\n    var lastPointList = [];\n    var innerLignes = [];\n    var outerLignes = [];\n\n    for (var j = 0; j < relation.ways.length; j++) {\n        var way = relation.ways[j]\n        var ref = way.getAttribute(\"ref\");\n        var role = way.getAttribute(\"role\");\n\n        var pointList = parser.getPointList(ways[ref], nodes);\n        if (pointList.length == 0) {\n            continue;\n        }\n        var newPath = true;\n        if (lastRole == '') {\n            lastRole = role;\n        }\n        if (lastRole == role) {\n            var result = parser.concatPathsIfLinear(lastPointList, pointList);\n            if (result.succed) {\n                newPath = false;\n                lastPointList = result.lastPointList;\n            }\n        }\n\n        if (newPath) {\n            if (lastPointList.length > 0) {\n                if (lastRole == 'inner' || lastRole == 'enclave') {\n                    var geometry = new OpenLayers.Geometry.LinearRing(lastPointList)\n                    innerLignes.push(geometry);\n                }\n                else { // if (lastRole == 'outer') {\n                    var geometry = new OpenLayers.Geometry.LinearRing(lastPointList)\n                    outerLignes.push(geometry);\n                }\n            }\n            lastPointList = pointList;\n            lastRole = role;\n        }\n    }\n    if (lastPointList.length > 0) {\n        if (lastRole == 'inner' || lastRole == 'enclave') {\n            var geometry = new OpenLayers.Geometry.LinearRing(lastPointList)\n            innerLignes.push(geometry);\n        }\n        else { // if (lastRole == 'outer') {\n            var geometry = new OpenLayers.Geometry.LinearRing(lastPointList)\n            outerLignes.push(geometry);\n        }\n    }\n\n    var polygons = [];\n    for (var j = 0 ; j < outerLignes.length ; j++) {\n        if (innerLignes.length == 0) {\n            polygons.push(new OpenLayers.Geometry.Polygon([outerLignes[j]]));\n        }\n        else {\n            var currentInners = [];\n            for (var k = 0 ; k < innerLignes.length ; k++) {\n                var inner = innerLignes[k];\n                if (outerLignes[j].containsPoint(inner.getCentroid())) {\n                    currentInners.push(inner);\n                }\n            }\n            polygons.push(new OpenLayers.Geometry.Polygon(\n                    [outerLignes[j]].concat(currentInners)));\n        }\n    }\n    var geometry = new OpenLayers.Geometry.MultiPolygon(polygons);\n    var feat = new OpenLayers.Feature.Vector(geometry, relation.tags);\n    feat.osm_id = parseInt(relation.id);\n    feat.type = \"relation\";\n    feat.fid = \"relation.\" + feat.osm_id;\n    return [feat];\n},\n\nOpenLayers.Format.OSM.getLineStrings = function(relation, parser, nodes, ways) {\n    var geometries = [];\n    for (var j = 0; j < relation.ways.length; j++) {\n        var way = relation.ways[j]\n        var ref = way.getAttribute(\"ref\");\n        var pointList = parser.getPointList(ways[ref], nodes);\n        if (pointList.length == 0) {\n            continue;\n        }\n\n        geometries.push(new OpenLayers.Geometry.LineString(pointList));\n    }\n    return geometries;\n}\n\nOpenLayers.Format.OSM.routeParser = function(relation, parser, nodes, ways, relations) {\n    var geometries = OpenLayers.Format.OSM.getLineStrings(relation, parser, nodes, ways);\n    var geometry = new OpenLayers.Geometry.MultiLineString(geometries);\n    var feat = new OpenLayers.Feature.Vector(geometry, relation.tags);\n    feat.osm_id = parseInt(relation.id);\n    feat.type = \"relation\";\n    feat.fid = \"relation.\" + feat.osm_id;\n    return [feat];\n}\n\nOpenLayers.Format.OSM.genericParser = function(relation, parser, nodes, ways, relations) {\n    var geometries = OpenLayers.Format.OSM.getLineStrings(relation, parser, nodes, ways);\n    for (var j = 0; j < relation.nodes.length; j++) {\n        var node = relation.nodes[j]\n        geometries.push(new OpenLayers.Geometry.Node(node));\n    }\n    var geometry = new OpenLayers.Geometry.Collection(geometries);\n    var feat = new OpenLayers.Feature.Vector(geometry, relation.tags);\n    feat.osm_id = parseInt(relation.id);\n    feat.type = \"relation\";\n    feat.fid = \"relation.\" + feat.osm_id;\n    return [feat];\n}\n\nOpenLayers.Format.OSM.routeParserWithRoles = function(relation, parser, nodes, ways, relations) {\n    var geometries = [];\n    var lastRole = '';\n    var lastPointList = [];\n    var features = [];\n\n    for (var j = 0; j < relation.ways.length; j++) {\n        var way = relation.ways[j]\n        var ref = way.getAttribute(\"ref\");\n        var role = way.getAttribute(\"role\");\n\n        var pointList = parser.getPointList(ways[ref], nodes);\n        if (pointList.length == 0) {\n            continue;\n        }\n        var newPath = true;\n        if (lastRole == '') {\n            lastRole = role;\n        }\n        if (lastRole == role) {\n            var result = parser.concatPathsIfLinear(lastPointList, pointList);\n            if (result.succed) {\n                newPath = false;\n                lastPointList = result.lastPointList;\n            }\n        }\n        if (newPath) {\n            var geometry = new OpenLayers.Geometry.LineString(lastPointList)\n            var feat = new OpenLayers.Feature.Vector(geometry, relation.tags);\n            if (role) {\n                feat.attributes.role = role;\n            }\n            feat.osm_id = parseInt(relation.id);\n            feat.type = \"relation\";\n            feat.fid = \"relation.\" + feat.osm_id + \".\" + j;\n            features.push(feat);\n            lastPointList = pointList;\n            lastRole = role;\n        }\n    }\n    var geometry = new OpenLayers.Geometry.LineString(lastPointList)\n    var feat = new OpenLayers.Feature.Vector(geometry, relation.tags);\n    if (role) {\n        feat.attributes.role = role;\n    }\n    feat.osm_id = parseInt(relation.id);\n    feat.type = \"relation\";\n    feat.fid = \"relation.\" + feat.osm_id;\n    features.push(feat);\n    return features;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/OWSCommon/v1.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.OWSCommon.v1 = OpenLayers.Class(OpenLayers.Format.XML, {\n   \n        regExes: {\n        trimSpace: (/^\\s*|\\s*$/g),\n        removeSpace: (/\\s*/g),\n        splitSpace: (/\\s+/),\n        trimComma: (/\\s*,\\s*/g)\n    },\n\n        read: function(data, options) {\n        options = OpenLayers.Util.applyDefaults(options, this.options);\n        var ows = {};\n        this.readChildNodes(data, ows);\n        return ows;\n    },\n\n        readers: {\n        \"ows\": {\n            \"Exception\": function(node, exceptionReport) {\n                var exception = {\n                    code: node.getAttribute('exceptionCode'),\n                    locator: node.getAttribute('locator'),\n                    texts: []\n                };\n                exceptionReport.exceptions.push(exception);\n                this.readChildNodes(node, exception);\n            },\n            \"ExceptionText\": function(node, exception) {\n                var text = this.getChildValue(node);\n                exception.texts.push(text);\n            },\n            \"ServiceIdentification\": function(node, obj) {\n                obj.serviceIdentification = {};\n                this.readChildNodes(node, obj.serviceIdentification);\n            },\n            \"Title\": function(node, obj) {\n                obj.title = this.getChildValue(node);\n            },\n            \"Abstract\": function(node, serviceIdentification) {\n                serviceIdentification[\"abstract\"] = this.getChildValue(node);\n            },\n            \"Keywords\": function(node, serviceIdentification) {\n                serviceIdentification.keywords = {};\n                this.readChildNodes(node, serviceIdentification.keywords);\n            },\n            \"Keyword\": function(node, keywords) {\n                keywords[this.getChildValue(node)] = true;\n            },\n            \"ServiceType\": function(node, serviceIdentification) {\n                serviceIdentification.serviceType = {\n                    codeSpace: node.getAttribute('codeSpace'), \n                    value: this.getChildValue(node)};\n            },\n            \"ServiceTypeVersion\": function(node, serviceIdentification) {\n                serviceIdentification.serviceTypeVersion = this.getChildValue(node);\n            },\n            \"Fees\": function(node, serviceIdentification) {\n                serviceIdentification.fees = this.getChildValue(node);\n            },\n            \"AccessConstraints\": function(node, serviceIdentification) {\n                serviceIdentification.accessConstraints = \n                    this.getChildValue(node);\n            },\n            \"ServiceProvider\": function(node, obj) {\n                obj.serviceProvider = {};\n                this.readChildNodes(node, obj.serviceProvider);\n            },\n            \"ProviderName\": function(node, serviceProvider) {\n                serviceProvider.providerName = this.getChildValue(node);\n            },\n            \"ProviderSite\": function(node, serviceProvider) {\n                serviceProvider.providerSite = this.getAttributeNS(node, \n                    this.namespaces.xlink, \"href\");\n            },\n            \"ServiceContact\": function(node, serviceProvider) {\n                serviceProvider.serviceContact = {};\n                this.readChildNodes(node, serviceProvider.serviceContact);\n            },\n            \"IndividualName\": function(node, serviceContact) {\n                serviceContact.individualName = this.getChildValue(node);\n            },\n            \"PositionName\": function(node, serviceContact) {\n                serviceContact.positionName = this.getChildValue(node);\n            },\n            \"ContactInfo\": function(node, serviceContact) {\n                serviceContact.contactInfo = {};\n                this.readChildNodes(node, serviceContact.contactInfo);\n            },\n            \"Phone\": function(node, contactInfo) {\n                contactInfo.phone = {};\n                this.readChildNodes(node, contactInfo.phone);\n            },\n            \"Voice\": function(node, phone) {\n                phone.voice = this.getChildValue(node);\n            },\n            \"Facsimile\": function(node, phone) {\n                phone.facsimile = this.getChildValue(node);\n            },\n            \"Address\": function(node, contactInfo) {\n                contactInfo.address = {};\n                this.readChildNodes(node, contactInfo.address);\n            },\n            \"DeliveryPoint\": function(node, address) {\n                address.deliveryPoint = this.getChildValue(node);\n            },\n            \"City\": function(node, address) {\n                address.city = this.getChildValue(node);\n            },\n            \"AdministrativeArea\": function(node, address) {\n                address.administrativeArea = this.getChildValue(node);\n            },\n            \"PostalCode\": function(node, address) {\n                address.postalCode = this.getChildValue(node);\n            },\n            \"Country\": function(node, address) {\n                address.country = this.getChildValue(node);\n            },\n            \"ElectronicMailAddress\": function(node, address) {\n                address.electronicMailAddress = this.getChildValue(node);\n            },\n            \"Role\": function(node, serviceContact) {\n                serviceContact.role = this.getChildValue(node);\n            },\n            \"OperationsMetadata\": function(node, obj) {\n                obj.operationsMetadata = {};\n                this.readChildNodes(node, obj.operationsMetadata);\n            },\n            \"Operation\": function(node, operationsMetadata) {\n                var name = node.getAttribute(\"name\");\n                operationsMetadata[name] = {};\n                this.readChildNodes(node, operationsMetadata[name]);\n            },\n            \"DCP\": function(node, operation) {\n                operation.dcp = {};\n                this.readChildNodes(node, operation.dcp);\n            },\n            \"HTTP\": function(node, dcp) {\n                dcp.http = {};\n                this.readChildNodes(node, dcp.http);\n            },\n            \"Get\": function(node, http) {\n                if (!http.get) {\n                    http.get = [];\n                }\n                var obj = {\n                    url: this.getAttributeNS(node, this.namespaces.xlink, \"href\")\n                };\n                this.readChildNodes(node, obj);\n                http.get.push(obj);\n            },\n            \"Post\": function(node, http) {\n                if (!http.post) {\n                    http.post = [];\n                }\n                var obj = {\n                    url: this.getAttributeNS(node, this.namespaces.xlink, \"href\")\n                };\n                this.readChildNodes(node, obj);\n                http.post.push(obj);\n            },\n            \"Parameter\": function(node, operation) {\n                if (!operation.parameters) {\n                    operation.parameters = {};\n                }\n                var name = node.getAttribute(\"name\");\n                operation.parameters[name] = {};\n                this.readChildNodes(node, operation.parameters[name]);\n            },\n            \"Constraint\": function(node, obj) {\n                if (!obj.constraints) {\n                    obj.constraints = {};\n                }\n                var name = node.getAttribute(\"name\");\n                obj.constraints[name] = {};\n                this.readChildNodes(node, obj.constraints[name]);\n            },\n            \"Value\": function(node, allowedValues) {\n                allowedValues[this.getChildValue(node)] = true;\n            },\n            \"OutputFormat\": function(node, obj) {\n                obj.formats.push({value: this.getChildValue(node)});\n                this.readChildNodes(node, obj);\n            },\n            \"WGS84BoundingBox\": function(node, obj) {\n                var boundingBox = {};\n                boundingBox.crs = node.getAttribute(\"crs\");\n                if (obj.BoundingBox) {\n                    obj.BoundingBox.push(boundingBox);\n                } else {\n                    obj.projection = boundingBox.crs;\n                    boundingBox = obj;\n               }\n               this.readChildNodes(node, boundingBox);\n            },\n            \"BoundingBox\": function(node, obj) {\n                this.readers['ows']['WGS84BoundingBox'].apply(this, [node, obj]);\n            },\n            \"LowerCorner\": function(node, obj) {\n                var str = this.getChildValue(node).replace(\n                    this.regExes.trimSpace, \"\");\n                str = str.replace(this.regExes.trimComma, \",\");\n                var pointList = str.split(this.regExes.splitSpace);\n                obj.left = pointList[0];\n                obj.bottom = pointList[1];\n            },\n            \"UpperCorner\": function(node, obj) {\n                var str = this.getChildValue(node).replace(\n                    this.regExes.trimSpace, \"\");\n                str = str.replace(this.regExes.trimComma, \",\");\n                var pointList = str.split(this.regExes.splitSpace);\n                obj.right = pointList[0];\n                obj.top = pointList[1];\n                obj.bounds = new OpenLayers.Bounds(obj.left, obj.bottom,\n                    obj.right, obj.top);\n                delete obj.left;\n                delete obj.bottom;\n                delete obj.right;\n                delete obj.top;\n            },\n            \"Language\": function(node, obj) {\n                obj.language = this.getChildValue(node);\n            }\n        }\n    },\n\n        writers: {\n        \"ows\": {\n            \"BoundingBox\": function(options, nodeName) {\n                var node = this.createElementNSPlus(nodeName || \"ows:BoundingBox\", {\n                    attributes: {\n                        crs: options.projection\n                    }\n                });\n                this.writeNode(\"ows:LowerCorner\", options, node);\n                this.writeNode(\"ows:UpperCorner\", options, node);\n                return node;\n            },\n            \"LowerCorner\": function(options) {\n                var node = this.createElementNSPlus(\"ows:LowerCorner\", {\n                    value: options.bounds.left + \" \" + options.bounds.bottom });\n                return node;\n            },\n            \"UpperCorner\": function(options) {\n                var node = this.createElementNSPlus(\"ows:UpperCorner\", {\n                    value: options.bounds.right + \" \" + options.bounds.top });\n                return node;\n            },\n            \"Identifier\": function(identifier) {\n                var node = this.createElementNSPlus(\"ows:Identifier\", {\n                    value: identifier });\n                return node;\n            },\n            \"Title\": function(title) {\n                var node = this.createElementNSPlus(\"ows:Title\", {\n                    value: title });\n                return node;\n            },\n            \"Abstract\": function(abstractValue) {\n                var node = this.createElementNSPlus(\"ows:Abstract\", {\n                    value: abstractValue });\n                return node;\n            },\n            \"OutputFormat\": function(format) {\n                var node = this.createElementNSPlus(\"ows:OutputFormat\", {\n                    value: format });\n                return node;\n            }\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.OWSCommon.v1\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/OWSCommon/v1_0_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.OWSCommon.v1_0_0 = OpenLayers.Class(OpenLayers.Format.OWSCommon.v1, {\n    \n        namespaces: {\n        ows: \"http://www.opengis.net/ows\",\n        xlink: \"http://www.w3.org/1999/xlink\"\n    },    \n    \n        readers: {\n        \"ows\": OpenLayers.Util.applyDefaults({\n            \"ExceptionReport\": function(node, obj) {\n                obj.success = false;\n                obj.exceptionReport = {\n                    version: node.getAttribute('version'),\n                    language: node.getAttribute('language'),\n                    exceptions: []\n                };\n                this.readChildNodes(node, obj.exceptionReport);\n            } \n        }, OpenLayers.Format.OWSCommon.v1.prototype.readers.ows)\n    },\n\n        writers: {\n        \"ows\": OpenLayers.Format.OWSCommon.v1.prototype.writers.ows\n    },\n    \n    CLASS_NAME: \"OpenLayers.Format.OWSCommon.v1_0_0\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/OWSCommon/v1_1_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.OWSCommon.v1_1_0 = OpenLayers.Class(OpenLayers.Format.OWSCommon.v1, {\n\n        namespaces: {\n        ows: \"http://www.opengis.net/ows/1.1\",\n        xlink: \"http://www.w3.org/1999/xlink\"\n    },    \n    \n        readers: {\n        \"ows\": OpenLayers.Util.applyDefaults({\n            \"ExceptionReport\": function(node, obj) {\n                obj.exceptionReport = {\n                    version: node.getAttribute('version'),\n                    language: node.getAttribute('xml:lang'),\n                    exceptions: []\n                };\n                this.readChildNodes(node, obj.exceptionReport);\n            },\n            \"AllowedValues\": function(node, parameter) {\n                parameter.allowedValues = {};\n                this.readChildNodes(node, parameter.allowedValues);\n            },\n            \"AnyValue\": function(node, parameter) {\n                parameter.anyValue = true;\n            },\n            \"DataType\": function(node, parameter) {\n                parameter.dataType = this.getChildValue(node);\n            },\n            \"Range\": function(node, allowedValues) {\n                allowedValues.range = {};\n                this.readChildNodes(node, allowedValues.range);\n            },\n            \"MinimumValue\": function(node, range) {\n                range.minValue = this.getChildValue(node);\n            },\n            \"MaximumValue\": function(node, range) {\n                range.maxValue = this.getChildValue(node);\n            },\n            \"Identifier\": function(node, obj) {\n                obj.identifier = this.getChildValue(node);\n            },\n            \"SupportedCRS\": function(node, obj) {\n                obj.supportedCRS = this.getChildValue(node);\n            }\n        }, OpenLayers.Format.OWSCommon.v1.prototype.readers[\"ows\"])\n    },\n\n        writers: {\n        \"ows\": OpenLayers.Util.applyDefaults({\n            \"Range\": function(range) {\n                var node = this.createElementNSPlus(\"ows:Range\", {\n                    attributes: {\n                        'ows:rangeClosure': range.closure\n                    }\n                });\n                this.writeNode(\"ows:MinimumValue\", range.minValue, node);\n                this.writeNode(\"ows:MaximumValue\", range.maxValue, node);\n                return node;\n            },\n            \"MinimumValue\": function(minValue) {\n                var node = this.createElementNSPlus(\"ows:MinimumValue\", {\n                    value: minValue\n                });\n                return node;\n            },\n            \"MaximumValue\": function(maxValue) {\n                var node = this.createElementNSPlus(\"ows:MaximumValue\", {\n                    value: maxValue\n                });\n                return node;\n            },\n            \"Value\": function(value) {\n                var node = this.createElementNSPlus(\"ows:Value\", {\n                    value: value\n                });\n                return node;\n            }\n        }, OpenLayers.Format.OWSCommon.v1.prototype.writers[\"ows\"])\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.OWSCommon.v1_1_0\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/OWSCommon.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.OWSCommon = OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC, {\n    \n        defaultVersion: \"1.0.0\",\n    \n    \n        getVersion: function(root, options) {\n        var version = this.version;\n        if(!version) {\n            var uri = root.getAttribute(\"xmlns:ows\");\n            if (uri && uri.substring(uri.lastIndexOf(\"/\")+1) === \"1.1\") {\n                version =\"1.1.0\";\n            } \n            if(!version) {\n                version = this.defaultVersion;\n            }\n        }\n        return version;\n    },\n\n    \n    CLASS_NAME: \"OpenLayers.Format.OWSCommon\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/OWSContext/v0_3_1.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.OWSContext.v0_3_1 = OpenLayers.Class(OpenLayers.Format.XML, {\n    \n        namespaces: {\n        owc: \"http://www.opengis.net/ows-context\",\n        gml: \"http://www.opengis.net/gml\",\n        kml: \"http://www.opengis.net/kml/2.2\",\n        ogc: \"http://www.opengis.net/ogc\",\n        ows: \"http://www.opengis.net/ows\",\n        sld: \"http://www.opengis.net/sld\",\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\"\n    },\n\n        VERSION: \"0.3.1\", \n\n        schemaLocation: \"http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd\",\n\n        defaultPrefix: \"owc\",\n\n        extractAttributes: true,\n    \n        regExes: {\n        trimSpace: (/^\\s*|\\s*$/g),\n        removeSpace: (/\\s*/g),\n        splitSpace: (/\\s+/),\n        trimComma: (/\\s*,\\s*/g)\n    },\n\n        featureNS: \"http://mapserver.gis.umn.edu/mapserver\",\n\n        featureType: 'vector',\n              \n        geometryName: 'geometry',\n\n        nestingLayerLookup: null,\n\n        initialize: function(options) {\n        OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);\n        OpenLayers.Format.GML.v2.prototype.setGeometryTypes.call(this);\n    },\n\n        setNestingPath : function(l){\n        if(l.layersContext){\n            for (var i = 0, len = l.layersContext.length; i < len; i++) {\n                var layerContext = l.layersContext[i];\n                var nPath = [];\n                var nTitle = l.title || \"\";\n                if(l.metadata && l.metadata.nestingPath){\n                    nPath = l.metadata.nestingPath.slice();\n                }\n                if (nTitle != \"\") {\n                    nPath.push(nTitle);\n                }\n                layerContext.metadata.nestingPath = nPath;\n                if(layerContext.layersContext){\n                    this.setNestingPath(layerContext);\n                }\n            }\n        }\n    },\n\n        decomposeNestingPath: function(nPath){\n        var a = [];\n        if (OpenLayers.Util.isArray(nPath)) {\n            var path = nPath.slice();\n            while (path.length > 0) {\n                a.push(path.slice());\n                path.pop();\n            }\n            a.reverse();\n        }\n        return a;\n    },\n\n        read: function(data) {\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        if(data && data.nodeType == 9) {\n            data = data.documentElement;\n        }\n        var context = {};\n        this.readNode(data, context);\n        this.setNestingPath({layersContext : context.layersContext});\n        var layers = [];\n        this.processLayer(layers, context);\n        delete context.layersContext;\n        context.layersContext = layers;\n        return context;\n    },\n\n        processLayer: function(layerArray, layer) {\n        if (layer.layersContext) {\n            for (var i=0, len = layer.layersContext.length; i<len; i++) {\n                var l = layer.layersContext[i];\n                layerArray.push(l);\n                if (l.layersContext) {\n                    this.processLayer(layerArray, l);\n                }\n            }\n        }\n    },\n\n        write: function(context, options) {\n        var name = \"OWSContext\";\n        this.nestingLayerLookup = {}; //start with empty lookup\n        options = options || {};\n        OpenLayers.Util.applyDefaults(options, context);\n        var root = this.writeNode(name, options);\n        this.nestingLayerLookup = null; //clear lookup\n        this.setAttributeNS(\n            root, this.namespaces[\"xsi\"],\n            \"xsi:schemaLocation\", this.schemaLocation\n        );\n        return OpenLayers.Format.XML.prototype.write.apply(this, [root]);\n    }, \n\n        readers: {\n        \"kml\": {\n            \"Document\": function(node, obj) {\n                obj.features = new OpenLayers.Format.KML(\n                    {kmlns: this.namespaces.kml, \n                        extractStyles: true}).read(node);\n            }\n        },\n        \"owc\": { \n            \"OWSContext\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            }, \n            \"General\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"ResourceList\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"Layer\": function(node, obj) {\n                var layerContext = {\n                    metadata: {},\n                    visibility: (node.getAttribute(\"hidden\") != \"1\"),\n                    queryable: (node.getAttribute(\"queryable\") == \"1\"),\n                    opacity: ((node.getAttribute(\"opacity\") != null) ? \n                        parseFloat(node.getAttribute(\"opacity\")) : null),\n                    name: node.getAttribute(\"name\"),\n                    /* A category layer is a dummy layer meant for creating\n                       hierarchies. It is not a physical layer in the \n                       OpenLayers sense. The assumption we make here is that\n                       category layers do not have a name attribute */\n                    categoryLayer: (node.getAttribute(\"name\") == null),\n                    formats: [],\n                    styles: []\n                };\n                if (!obj.layersContext) {\n                    obj.layersContext = [];\n                }\n                obj.layersContext.push(layerContext);\n                this.readChildNodes(node, layerContext);\n            },\n            \"InlineGeometry\": function(node, obj) {\n                obj.features = [];\n                var elements = this.getElementsByTagNameNS(node, \n                    this.namespaces.gml, \"featureMember\");\n                var el;\n                if (elements.length >= 1) {\n                    el = elements[0];\n                }\n                if (el && el.firstChild) {\n                    var featurenode = (el.firstChild.nextSibling) ? \n                        el.firstChild.nextSibling : el.firstChild;\n                    this.setNamespace(\"feature\", featurenode.namespaceURI);\n                    this.featureType = featurenode.localName || \n                        featurenode.nodeName.split(\":\").pop();\n                    this.readChildNodes(node, obj);\n                }\n            },\n            \"Server\": function(node, obj) {\n                if ((!obj.service && !obj.version) || \n                    (obj.service != \n                        OpenLayers.Format.Context.serviceTypes.WMS)) {\n                            obj.service = node.getAttribute(\"service\");\n                            obj.version = node.getAttribute(\"version\");\n                            this.readChildNodes(node, obj);\n                }\n            },\n            \"Name\": function(node, obj) {\n                obj.name = this.getChildValue(node);\n                this.readChildNodes(node, obj);\n            },\n            \"Title\": function(node, obj) {\n                obj.title = this.getChildValue(node);\n                this.readChildNodes(node, obj);\n            },\n            \"StyleList\": function(node, obj) {\n                this.readChildNodes(node, obj.styles);\n            },\n            \"Style\": function(node, obj) {\n                var style = {};\n                obj.push(style);\n                this.readChildNodes(node, style);\n            },\n            \"LegendURL\": function(node, obj) {\n                var legend = {};\n                obj.legend = legend;\n                this.readChildNodes(node, legend);\n            },\n            \"OnlineResource\": function(node, obj) {\n                obj.url = this.getAttributeNS(node, this.namespaces.xlink, \n                    \"href\");\n                this.readChildNodes(node, obj);\n            }\n        },\n        \"ows\": OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers.ows,\n        \"gml\": OpenLayers.Format.GML.v2.prototype.readers.gml,\n        \"sld\": OpenLayers.Format.SLD.v1_0_0.prototype.readers.sld,\n        \"feature\": OpenLayers.Format.GML.v2.prototype.readers.feature\n    },\n\n        writers: {\n        \"owc\": {\n            \"OWSContext\": function(options) {\n                var node = this.createElementNSPlus(\"OWSContext\", {\n                    attributes: {\n                        version: this.VERSION,\n                        id: options.id || OpenLayers.Util.createUniqueID(\"OpenLayers_OWSContext_\")\n                    } \n                }); \n                this.writeNode(\"General\", options, node);\n                this.writeNode(\"ResourceList\", options, node);\n                return node; \n            },\n            \"General\": function(options) {\n                var node = this.createElementNSPlus(\"General\");\n                this.writeNode(\"ows:BoundingBox\", options, node);\n                this.writeNode(\"ows:Title\", options.title || 'OpenLayers OWSContext', node);\n                return node;\n            },\n            \"ResourceList\": function(options) {\n                var node = this.createElementNSPlus(\"ResourceList\");\n                for (var i=0, len=options.layers.length; i<len; i++) {\n                    var layer = options.layers[i];\n                    var decomposedPath = this.decomposeNestingPath(layer.metadata.nestingPath);\n                    this.writeNode(\"_Layer\", {layer: layer, subPaths: decomposedPath}, node);\n                }\n                return node;\n            },\n            \"Server\": function(options) {\n                var node = this.createElementNSPlus(\"Server\", {attributes: {\n                    version: options.version,\n                    service: options.service }\n                });\n                this.writeNode(\"OnlineResource\", options, node);\n                return node;\n            },\n            \"OnlineResource\": function(options) {\n                var node = this.createElementNSPlus(\"OnlineResource\", {attributes: {\n                    \"xlink:href\": options.url }\n                });\n                return node;\n            },\n            \"InlineGeometry\": function(layer) {\n                var node = this.createElementNSPlus(\"InlineGeometry\"),\n                    dataExtent = layer.getDataExtent();\n                if (dataExtent !== null) {\n                    this.writeNode(\"gml:boundedBy\", dataExtent, node);\n                }\n                for (var i=0, len=layer.features.length; i<len; i++) {\n                    this.writeNode(\"gml:featureMember\", layer.features[i], node);\n                }\n                return node;\n            },\n            \"StyleList\": function(styles) {\n                var node = this.createElementNSPlus(\"StyleList\");\n                for (var i=0, len=styles.length; i<len; i++) {\n                    this.writeNode(\"Style\", styles[i], node);\n                }\n                return node;\n            },\n            \"Style\": function(style) {\n                var node = this.createElementNSPlus(\"Style\");\n                this.writeNode(\"Name\", style, node);\n                this.writeNode(\"Title\", style, node);\n                if (style.legend) {\n                    this.writeNode(\"LegendURL\", style, node);\n                }\n                return node;\n            },\n            \"Name\": function(obj) {\n                var node = this.createElementNSPlus(\"Name\", {\n                    value: obj.name });\n                return node;\n            },\n            \"Title\": function(obj) {\n                var node = this.createElementNSPlus(\"Title\", {\n                    value: obj.title });\n                return node;\n            },\n            \"LegendURL\": function(style) {\n                var node = this.createElementNSPlus(\"LegendURL\");\n                this.writeNode(\"OnlineResource\", style.legend, node);\n                return node;\n            },\n            \"_WMS\": function(layer) {\n                var node = this.createElementNSPlus(\"Layer\", {attributes: {\n                    name: layer.params.LAYERS,\n                    queryable: layer.queryable ? \"1\" : \"0\",\n                    hidden: layer.visibility ? \"0\" : \"1\",\n                    opacity: layer.hasOwnProperty(\"opacity\") ? layer.opacity : null}\n                });\n                this.writeNode(\"ows:Title\", layer.name, node);\n                this.writeNode(\"ows:OutputFormat\", layer.params.FORMAT, node);\n                this.writeNode(\"Server\", {service: \n                    OpenLayers.Format.Context.serviceTypes.WMS,\n                    version: layer.params.VERSION, url: layer.url}, node);\n                if (layer.metadata.styles && layer.metadata.styles.length > 0) {\n                    this.writeNode(\"StyleList\", layer.metadata.styles, node);\n                }\n                return node;\n            },\n            \"_Layer\": function(options) {\n                var layer, subPaths, node, title;\n                layer = options.layer;\n                subPaths = options.subPaths;\n                node = null;\n                title = null;\n                if(subPaths.length > 0){\n                    var path = subPaths[0].join(\"/\");\n                    var index = path.lastIndexOf(\"/\");\n                    node = this.nestingLayerLookup[path];\n                    title = (index > 0)?path.substring(index + 1, path.length):path;\n                    if(!node){\n                        node = this.createElementNSPlus(\"Layer\");\n                        this.writeNode(\"ows:Title\", title, node);\n                        this.nestingLayerLookup[path] = node;\n                    }\n                    options.subPaths.shift();//remove a path after each call\n                    this.writeNode(\"_Layer\", options, node);\n                    return node;\n                } else {\n                    if (layer instanceof OpenLayers.Layer.WMS) {\n                        node = this.writeNode(\"_WMS\", layer);\n                    } else if (layer instanceof OpenLayers.Layer.Vector) {\n                        if (layer.protocol instanceof OpenLayers.Protocol.WFS.v1) {\n                            node = this.writeNode(\"_WFS\", layer);\n                        } else if (layer.protocol instanceof OpenLayers.Protocol.HTTP) {\n                            if (layer.protocol.format instanceof OpenLayers.Format.GML) {\n                                layer.protocol.format.version = \"2.1.2\";\n                                node = this.writeNode(\"_GML\", layer);\n                            } else if (layer.protocol.format instanceof OpenLayers.Format.KML) {\n                                layer.protocol.format.version = \"2.2\";\n                                node = this.writeNode(\"_KML\", layer);\n                            }\n                        } else {\n                            this.setNamespace(\"feature\", this.featureNS);\n                            node = this.writeNode(\"_InlineGeometry\", layer);\n                        }\n                    }\n                    if (layer.options.maxScale) {\n                        this.writeNode(\"sld:MinScaleDenominator\", \n                            layer.options.maxScale, node);\n                    }\n                    if (layer.options.minScale) {\n                        this.writeNode(\"sld:MaxScaleDenominator\", \n                            layer.options.minScale, node);\n                    }\n                    this.nestingLayerLookup[layer.name] = node;\n                    return node;\n                }\n            },\n            \"_WFS\": function(layer) {\n                var node = this.createElementNSPlus(\"Layer\", {attributes: {\n                    name: layer.protocol.featurePrefix + \":\" + layer.protocol.featureType,\n                    hidden: layer.visibility ? \"0\" : \"1\" }\n                });\n                this.writeNode(\"ows:Title\", layer.name, node);\n                this.writeNode(\"Server\", {service: \n                    OpenLayers.Format.Context.serviceTypes.WFS, \n                    version: layer.protocol.version, \n                    url: layer.protocol.url}, node);\n                return node;\n            },\n            \"_InlineGeometry\": function(layer) {\n                var node = this.createElementNSPlus(\"Layer\", {attributes: {\n                    name: this.featureType,\n                    hidden: layer.visibility ? \"0\" : \"1\" }\n                });\n                this.writeNode(\"ows:Title\", layer.name, node);\n                this.writeNode(\"InlineGeometry\", layer, node);\n                return node;\n            },\n            \"_GML\": function(layer) {\n                var node = this.createElementNSPlus(\"Layer\");\n                this.writeNode(\"ows:Title\", layer.name, node);\n                this.writeNode(\"Server\", {service: \n                    OpenLayers.Format.Context.serviceTypes.GML, \n                    url: layer.protocol.url, version: \n                    layer.protocol.format.version}, node);\n                return node;\n            },\n            \"_KML\": function(layer) {\n                var node = this.createElementNSPlus(\"Layer\");\n                this.writeNode(\"ows:Title\", layer.name, node);\n                this.writeNode(\"Server\", {service: \n                    OpenLayers.Format.Context.serviceTypes.KML,\n                    version: layer.protocol.format.version, url: \n                    layer.protocol.url}, node);\n                return node;\n            }\n        },\n        \"gml\": OpenLayers.Util.applyDefaults({\n            \"boundedBy\": function(bounds) {\n                var node = this.createElementNSPlus(\"gml:boundedBy\");\n                this.writeNode(\"gml:Box\", bounds, node);\n                return node;\n            }\n        }, OpenLayers.Format.GML.v2.prototype.writers.gml),\n        \"ows\": OpenLayers.Format.OWSCommon.v1_0_0.prototype.writers.ows,\n        \"sld\": OpenLayers.Format.SLD.v1_0_0.prototype.writers.sld,\n        \"feature\": OpenLayers.Format.GML.v2.prototype.writers.feature\n    },\n    \n    CLASS_NAME: \"OpenLayers.Format.OWSContext.v0_3_1\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/OWSContext.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.OWSContext = OpenLayers.Class(OpenLayers.Format.Context,{\n    \n        defaultVersion: \"0.3.1\",\n\n        \n        getVersion: function(root, options) {\n        var version = OpenLayers.Format.XML.VersionedOGC.prototype.getVersion.apply(\n            this, arguments);\n        if (version === \"0.3.0\") {\n            version = this.defaultVersion;\n        }\n        return version;\n    },\n\n        toContext: function(obj) {\n        var context = {};\n        if(obj.CLASS_NAME == \"OpenLayers.Map\") {\n            context.bounds = obj.getExtent();\n            context.maxExtent = obj.maxExtent;\n            context.projection = obj.projection;\n            context.size = obj.getSize();\n            context.layers = obj.layers;\n        }\n        return context;\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.OWSContext\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/QueryStringFilter.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.QueryStringFilter = (function() {\n\n        var cmpToStr = {};\n    cmpToStr[OpenLayers.Filter.Comparison.EQUAL_TO] = \"eq\";\n    cmpToStr[OpenLayers.Filter.Comparison.NOT_EQUAL_TO] = \"ne\";\n    cmpToStr[OpenLayers.Filter.Comparison.LESS_THAN] = \"lt\";\n    cmpToStr[OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO] = \"lte\";\n    cmpToStr[OpenLayers.Filter.Comparison.GREATER_THAN] = \"gt\";\n    cmpToStr[OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO] = \"gte\";\n    cmpToStr[OpenLayers.Filter.Comparison.LIKE] = \"ilike\";\n\n        function regex2value(value) {\n        value = value.replace(/%/g, \"\\\\%\");\n        value = value.replace(/\\\\\\\\\\.(\\*)?/g, function($0, $1) {\n            return $1 ? $0 : \"\\\\\\\\_\";\n        });\n        value = value.replace(/\\\\\\\\\\.\\*/g, \"\\\\\\\\%\");\n        value = value.replace(/(\\\\)?\\.(\\*)?/g, function($0, $1, $2) {\n            return $1 || $2 ? $0 : \"_\";\n        });\n        value = value.replace(/(\\\\)?\\.\\*/g, function($0, $1) {\n            return $1 ? $0 : \"%\";\n        });\n        value = value.replace(/\\\\\\./g, \".\");\n        value = value.replace(/(\\\\)?\\\\\\*/g, function($0, $1) {\n            return $1 ? $0 : \"*\";\n        });\n\n        return value;\n    }\n    \n    return OpenLayers.Class(OpenLayers.Format, {\n        \n                wildcarded: false,\n\n                srsInBBOX: false,\n\n                write: function(filter, params) {\n            params = params || {};\n            var className = filter.CLASS_NAME;\n            var filterType = className.substring(className.lastIndexOf(\".\") + 1);\n            switch (filterType) {\n                case \"Spatial\":\n                    switch (filter.type) {\n                        case OpenLayers.Filter.Spatial.BBOX:\n                            params.bbox = filter.value.toArray();\n                            if (this.srsInBBOX && filter.projection) {\n                                params.bbox.push(filter.projection.getCode());\n                            }\n                            break;\n                        case OpenLayers.Filter.Spatial.DWITHIN:\n                            params.tolerance = filter.distance;\n                        case OpenLayers.Filter.Spatial.WITHIN:\n                            params.lon = filter.value.x;\n                            params.lat = filter.value.y;\n                            break;\n                        default:\n                            OpenLayers.Console.warn(\n                                \"Unknown spatial filter type \" + filter.type);\n                    }\n                    break;\n                case \"Comparison\":\n                    var op = cmpToStr[filter.type];\n                    if (op !== undefined) {\n                        var value = filter.value;\n                        if (filter.type == OpenLayers.Filter.Comparison.LIKE) {\n                            value = regex2value(value);\n                            if (this.wildcarded) {\n                                value = \"%\" + value + \"%\";\n                            }\n                        }\n                        params[filter.property + \"__\" + op] = value;\n                        params.queryable = params.queryable || [];\n                        params.queryable.push(filter.property);\n                    } else {\n                        OpenLayers.Console.warn(\n                            \"Unknown comparison filter type \" + filter.type);\n                    }\n                    break;\n                case \"Logical\":\n                    if (filter.type === OpenLayers.Filter.Logical.AND) {\n                        for (var i=0,len=filter.filters.length; i<len; i++) {\n                            params = this.write(filter.filters[i], params);\n                        }\n                    } else {\n                        OpenLayers.Console.warn(\n                            \"Unsupported logical filter type \" + filter.type);\n                    }\n                    break;\n                default:\n                    OpenLayers.Console.warn(\"Unknown filter type \" + filterType);\n            }\n            return params;\n        },\n        \n        CLASS_NAME: \"OpenLayers.Format.QueryStringFilter\"\n        \n    });\n\n\n})();\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/SLD/v1.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {\n    \n        namespaces: {\n        sld: \"http://www.opengis.net/sld\",\n        ogc: \"http://www.opengis.net/ogc\",\n        gml: \"http://www.opengis.net/gml\",\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\",\n        xmlns: \"http://www.w3.org/2000/xmlns/\"\n    },\n    \n        defaultPrefix: \"sld\",\n\n        schemaLocation: null,\n    \n        multipleSymbolizers: false,\n\n        featureTypeCounter: null,\n\n        defaultSymbolizer: {\n        fillColor: \"#808080\",\n        fillOpacity: 1,\n        strokeColor: \"#000000\",\n        strokeOpacity: 1,\n        strokeWidth: 1,\n        strokeDashstyle: \"solid\",\n        pointRadius: 3,\n        graphicName: \"square\"\n    },\n    \n        \n        read: function(data, options) {\n        options = OpenLayers.Util.applyDefaults(options, this.options);\n        var sld = {\n            namedLayers: options.namedLayersAsArray === true ? [] : {}\n        };\n        this.readChildNodes(data, sld);\n        return sld;\n    },\n    \n        readers: OpenLayers.Util.applyDefaults({\n        \"sld\": {\n            \"StyledLayerDescriptor\": function(node, sld) {\n                sld.version = node.getAttribute(\"version\");\n                this.readChildNodes(node, sld);\n            },\n            \"Name\": function(node, obj) {\n                obj.name = this.getChildValue(node);\n            },\n            \"Title\": function(node, obj) {\n                obj.title = this.getChildValue(node);\n            },\n            \"Abstract\": function(node, obj) {\n                obj.description = this.getChildValue(node);\n            },\n            \"NamedLayer\": function(node, sld) {\n                var layer = {\n                    userStyles: [],\n                    namedStyles: []\n                };\n                this.readChildNodes(node, layer);\n                for(var i=0, len=layer.userStyles.length; i<len; ++i) {\n                    layer.userStyles[i].layerName = layer.name;\n                }\n                if(OpenLayers.Util.isArray(sld.namedLayers)) {\n                    sld.namedLayers.push(layer);                \n                } else {\n                    sld.namedLayers[layer.name] = layer;\n                }\n            },\n            \"NamedStyle\": function(node, layer) {\n                layer.namedStyles.push(\n                    this.getChildValue(node.firstChild)\n                );\n            },\n            \"UserStyle\": function(node, layer) {\n                var obj = {defaultsPerSymbolizer: true, rules: []};\n                this.featureTypeCounter = -1;\n                this.readChildNodes(node, obj);\n                var style;\n                if (this.multipleSymbolizers) {\n                    delete obj.defaultsPerSymbolizer;\n                    style = new OpenLayers.Style2(obj);\n                } else {\n                    style = new OpenLayers.Style(this.defaultSymbolizer, obj);\n                }\n                layer.userStyles.push(style);\n            },\n            \"IsDefault\": function(node, style) {\n                if(this.getChildValue(node) == \"1\") {\n                    style.isDefault = true;\n                }\n            },\n            \"FeatureTypeStyle\": function(node, style) {\n                ++this.featureTypeCounter;\n                var obj = {\n                    rules: this.multipleSymbolizers ? style.rules : []\n                };\n                this.readChildNodes(node, obj);\n                if (!this.multipleSymbolizers) {\n                    style.rules = obj.rules;\n                }\n            },\n            \"Rule\": function(node, obj) {\n                var config;\n                if (this.multipleSymbolizers) {\n                    config = {symbolizers: []};\n                }\n                var rule = new OpenLayers.Rule(config);\n                this.readChildNodes(node, rule);\n                obj.rules.push(rule);\n            },\n            \"ElseFilter\": function(node, rule) {\n                rule.elseFilter = true;\n            },\n            \"MinScaleDenominator\": function(node, rule) {\n                rule.minScaleDenominator = parseFloat(this.getChildValue(node));\n            },\n            \"MaxScaleDenominator\": function(node, rule) {\n                rule.maxScaleDenominator = parseFloat(this.getChildValue(node));\n            },\n            \"TextSymbolizer\": function(node, rule) {\n                var config = {};\n                this.readChildNodes(node, config);\n                if (this.multipleSymbolizers) {\n                    config.zIndex = this.featureTypeCounter;\n                    rule.symbolizers.push(\n                        new OpenLayers.Symbolizer.Text(config)\n                    );\n                } else {\n                    rule.symbolizer[\"Text\"] = OpenLayers.Util.applyDefaults(\n                        config, rule.symbolizer[\"Text\"]\n                    );\n                }\n            },\n            \"LabelPlacement\": function(node, symbolizer) {\n                this.readChildNodes(node, symbolizer);\n            },\n            \"PointPlacement\": function(node, symbolizer) {\n                var config = {};\n                this.readChildNodes(node, config);\n                config.labelRotation = config.rotation;\n                delete config.rotation;\n                var labelAlign,\n                    x = symbolizer.labelAnchorPointX,\n                    y = symbolizer.labelAnchorPointY;\n                if (x <= 1/3) {\n                    labelAlign = 'l';\n                } else if (x > 1/3 && x < 2/3) {\n                    labelAlign = 'c';\n                } else if (x >= 2/3) {\n                    labelAlign = 'r';\n                }\n                if (y <= 1/3) {\n                    labelAlign += 'b';\n                } else if (y > 1/3 && y < 2/3) {\n                    labelAlign += 'm';\n                } else if (y >= 2/3) {\n                    labelAlign += 't';\n                }\n                config.labelAlign = labelAlign;\n                OpenLayers.Util.applyDefaults(symbolizer, config);\n            },\n            \"AnchorPoint\": function(node, symbolizer) {\n                this.readChildNodes(node, symbolizer);\n            },\n            \"AnchorPointX\": function(node, symbolizer) {\n                var labelAnchorPointX = this.readers.ogc._expression.call(this, node);\n                if(labelAnchorPointX) {\n                    symbolizer.labelAnchorPointX = labelAnchorPointX;\n                }\n            },\n            \"AnchorPointY\": function(node, symbolizer) {\n                var labelAnchorPointY = this.readers.ogc._expression.call(this, node);\n                if(labelAnchorPointY) {\n                    symbolizer.labelAnchorPointY = labelAnchorPointY;\n                }\n            },\n            \"Displacement\": function(node, symbolizer) {\n                this.readChildNodes(node, symbolizer);\n            },\n            \"DisplacementX\": function(node, symbolizer) {\n                var labelXOffset = this.readers.ogc._expression.call(this, node);\n                if(labelXOffset) {\n                    symbolizer.labelXOffset = labelXOffset;\n                }\n            },\n            \"DisplacementY\": function(node, symbolizer) {\n                var labelYOffset = this.readers.ogc._expression.call(this, node);\n                if(labelYOffset) {\n                    symbolizer.labelYOffset = labelYOffset;\n                }\n            },\n            \"LinePlacement\": function(node, symbolizer) {\n                this.readChildNodes(node, symbolizer);\n            },\n            \"PerpendicularOffset\": function(node, symbolizer) {\n                var labelPerpendicularOffset = this.readers.ogc._expression.call(this, node);\n                if(labelPerpendicularOffset) {\n                    symbolizer.labelPerpendicularOffset = labelPerpendicularOffset;\n                }\n            },\n            \"Label\": function(node, symbolizer) {\n                var value = this.readers.ogc._expression.call(this, node);\n                if (value) {\n                    symbolizer.label = OpenLayers.String.trim(value);\n                }\n            },\n            \"Font\": function(node, symbolizer) {\n                this.readChildNodes(node, symbolizer);\n            },\n            \"Halo\": function(node, symbolizer) {\n                var obj = {};\n                this.readChildNodes(node, obj);\n                symbolizer.haloRadius = obj.haloRadius;\n                symbolizer.haloColor = obj.fillColor;\n                symbolizer.haloOpacity = obj.fillOpacity;\n            },\n            \"Radius\": function(node, symbolizer) {\n                var radius = this.readers.ogc._expression.call(this, node);\n                if(radius != null) {\n                    symbolizer.haloRadius = radius;\n                }\n            },\n            \"RasterSymbolizer\": function(node, rule) {\n                var config = {};\n                this.readChildNodes(node, config);\n                if (this.multipleSymbolizers) {\n                    config.zIndex = this.featureTypeCounter;\n                    rule.symbolizers.push(\n                        new OpenLayers.Symbolizer.Raster(config)\n                    );\n                } else {\n                    rule.symbolizer[\"Raster\"] = OpenLayers.Util.applyDefaults(\n                        config, rule.symbolizer[\"Raster\"]\n                    );\n                }\n            },\n            \"Geometry\": function(node, obj) {\n                obj.geometry = {};\n                this.readChildNodes(node, obj.geometry);\n            },\n            \"ColorMap\": function(node, symbolizer) {\n                symbolizer.colorMap = [];\n                this.readChildNodes(node, symbolizer.colorMap);\n            },\n            \"ColorMapEntry\": function(node, colorMap) {\n                var q = node.getAttribute(\"quantity\");\n                var o = node.getAttribute(\"opacity\");\n                colorMap.push({\n                    color: node.getAttribute(\"color\"),\n                    quantity: q !== null ? parseFloat(q) : undefined,\n                    label: node.getAttribute(\"label\") || undefined,\n                    opacity: o !== null ? parseFloat(o) : undefined\n                });\n            },\n            \"LineSymbolizer\": function(node, rule) {\n                var config = {};\n                this.readChildNodes(node, config);\n                if (this.multipleSymbolizers) {\n                    config.zIndex = this.featureTypeCounter;\n                    rule.symbolizers.push(\n                        new OpenLayers.Symbolizer.Line(config)\n                    );\n                } else {\n                    rule.symbolizer[\"Line\"] = OpenLayers.Util.applyDefaults(\n                        config, rule.symbolizer[\"Line\"]\n                    );\n                }\n            },\n            \"PolygonSymbolizer\": function(node, rule) {\n                var config = {\n                    fill: false,\n                    stroke: false\n                };\n                if (!this.multipleSymbolizers) {\n                    config = rule.symbolizer[\"Polygon\"] || config;\n                }\n                this.readChildNodes(node, config);\n                if (this.multipleSymbolizers) {\n                    config.zIndex = this.featureTypeCounter;\n                    rule.symbolizers.push(\n                        new OpenLayers.Symbolizer.Polygon(config)\n                    );\n                } else {\n                    rule.symbolizer[\"Polygon\"] = config;\n                }\n            },\n            \"PointSymbolizer\": function(node, rule) {\n                var config = {\n                    fill: false,\n                    stroke: false,\n                    graphic: false\n                };\n                if (!this.multipleSymbolizers) {\n                    config = rule.symbolizer[\"Point\"] || config;\n                }\n                this.readChildNodes(node, config);\n                if (this.multipleSymbolizers) {\n                    config.zIndex = this.featureTypeCounter;\n                    rule.symbolizers.push(\n                        new OpenLayers.Symbolizer.Point(config)\n                    );\n                } else {\n                    rule.symbolizer[\"Point\"] = config;\n                }\n            },\n            \"Stroke\": function(node, symbolizer) {\n                symbolizer.stroke = true;\n                this.readChildNodes(node, symbolizer);\n            },\n            \"Fill\": function(node, symbolizer) {\n                symbolizer.fill = true;\n                this.readChildNodes(node, symbolizer);\n            },\n            \"CssParameter\": function(node, symbolizer) {\n                var cssProperty = node.getAttribute(\"name\");\n                var symProperty = this.cssMap[cssProperty];\n                if (symbolizer.label) {\n                    if (cssProperty === 'fill') {\n                        symProperty = \"fontColor\";\n                    } else if (cssProperty === 'fill-opacity') {\n                        symProperty = \"fontOpacity\";\n                    }\n                }\n                if(symProperty) {\n                    var value = this.readers.ogc._expression.call(this, node);\n                    if(value) {\n                        symbolizer[symProperty] = value;\n                    }\n                }\n            },\n            \"Graphic\": function(node, symbolizer) {\n                symbolizer.graphic = true;\n                var graphic = {};\n                this.readChildNodes(node, graphic);\n                var properties = [\n                    \"stroke\", \"strokeColor\", \"strokeWidth\", \"strokeOpacity\",\n                    \"strokeLinecap\", \"fill\", \"fillColor\", \"fillOpacity\",\n                    \"graphicName\", \"rotation\", \"graphicFormat\"\n                ];\n                var prop, value;\n                for(var i=0, len=properties.length; i<len; ++i) {\n                    prop = properties[i];\n                    value = graphic[prop];\n                    if(value != undefined) {\n                        symbolizer[prop] = value;\n                    }\n                }\n                if(graphic.opacity != undefined) {\n                    symbolizer.graphicOpacity = graphic.opacity;\n                }\n                if(graphic.size != undefined) {\n                    var pointRadius = graphic.size / 2;\n                    if (isNaN(pointRadius)) {\n                        symbolizer.graphicWidth = graphic.size;\n                    } else {\n                        symbolizer.pointRadius = graphic.size / 2;\n                    }\n                }\n                if(graphic.href != undefined) {\n                    symbolizer.externalGraphic = graphic.href;\n                }\n                if(graphic.rotation != undefined) {\n                    symbolizer.rotation = graphic.rotation;\n                }\n            },\n            \"ExternalGraphic\": function(node, graphic) {\n                this.readChildNodes(node, graphic);\n            },\n            \"Mark\": function(node, graphic) {\n                this.readChildNodes(node, graphic);\n            },\n            \"WellKnownName\": function(node, graphic) {\n                graphic.graphicName = this.getChildValue(node);\n            },\n            \"Opacity\": function(node, obj) {\n                var opacity = this.readers.ogc._expression.call(this, node);\n                if(opacity) {\n                    obj.opacity = opacity;\n                }\n            },\n            \"Size\": function(node, obj) {\n                var size = this.readers.ogc._expression.call(this, node);\n                if(size) {\n                    obj.size = size;\n                }\n            },\n            \"Rotation\": function(node, obj) {\n                var rotation = this.readers.ogc._expression.call(this, node);\n                if(rotation) {\n                    obj.rotation = rotation;\n                }\n            },\n            \"OnlineResource\": function(node, obj) {\n                obj.href = this.getAttributeNS(\n                    node, this.namespaces.xlink, \"href\"\n                );\n            },\n            \"Format\": function(node, graphic) {\n                graphic.graphicFormat = this.getChildValue(node);\n            }\n        }\n    }, OpenLayers.Format.Filter.v1_0_0.prototype.readers),\n    \n        cssMap: {\n        \"stroke\": \"strokeColor\",\n        \"stroke-opacity\": \"strokeOpacity\",\n        \"stroke-width\": \"strokeWidth\",\n        \"stroke-linecap\": \"strokeLinecap\",\n        \"stroke-dasharray\": \"strokeDashstyle\",\n        \"fill\": \"fillColor\",\n        \"fill-opacity\": \"fillOpacity\",\n        \"font-family\": \"fontFamily\",\n        \"font-size\": \"fontSize\",\n        \"font-weight\": \"fontWeight\",\n        \"font-style\": \"fontStyle\"\n    },\n    \n        getCssProperty: function(sym) {\n        var css = null;\n        for(var prop in this.cssMap) {\n            if(this.cssMap[prop] == sym) {\n                css = prop;\n                break;\n            }\n        }\n        return css;\n    },\n    \n        getGraphicFormat: function(href) {\n        var format, regex;\n        for(var key in this.graphicFormats) {\n            if(this.graphicFormats[key].test(href)) {\n                format = key;\n                break;\n            }\n        }\n        return format || this.defaultGraphicFormat;\n    },\n    \n        defaultGraphicFormat: \"image/png\",\n    \n        graphicFormats: {\n        \"image/jpeg\": /\\.jpe?g$/i,\n        \"image/gif\": /\\.gif$/i,\n        \"image/png\": /\\.png$/i\n    },\n\n        write: function(sld) {\n        return this.writers.sld.StyledLayerDescriptor.apply(this, [sld]);\n    },\n    \n        writers: OpenLayers.Util.applyDefaults({\n        \"sld\": {\n            \"_OGCExpression\": function(nodeName, value) {\n                var node = this.createElementNSPlus(nodeName);\n                var tokens = typeof value == \"string\" ?\n                    value.split(\"${\") :\n                    [value];\n                node.appendChild(this.createTextNode(tokens[0]));\n                var item, last;\n                for(var i=1, len=tokens.length; i<len; i++) {\n                    item = tokens[i];\n                    last = item.indexOf(\"}\"); \n                    if(last > 0) {\n                        this.writeNode(\n                            \"ogc:PropertyName\",\n                            {property: item.substring(0, last)},\n                            node\n                        );\n                        node.appendChild(\n                            this.createTextNode(item.substring(++last))\n                        );\n                    } else {\n                        node.appendChild(\n                            this.createTextNode(\"${\" + item)\n                        );\n                    }\n                }\n                return node;\n            },\n            \"StyledLayerDescriptor\": function(sld) {\n                var root = this.createElementNSPlus(\n                    \"sld:StyledLayerDescriptor\",\n                    {attributes: {\n                        \"version\": this.VERSION,\n                        \"xsi:schemaLocation\": this.schemaLocation\n                    }}\n                );\n                this.setAttributeNS(\n                    root, this.namespaces.xmlns,\n                    \"xmlns:ogc\", this.namespaces.ogc\n                );\n                this.setAttributeNS(\n                    root, this.namespaces.xmlns,\n                    \"xmlns:gml\", this.namespaces.gml\n                );\n                if(sld.name) {\n                    this.writeNode(\"Name\", sld.name, root);\n                }\n                if(sld.title) {\n                    this.writeNode(\"Title\", sld.title, root);\n                }\n                if(sld.description) {\n                    this.writeNode(\"Abstract\", sld.description, root);\n                }\n                if(OpenLayers.Util.isArray(sld.namedLayers)) {\n                    for(var i=0, len=sld.namedLayers.length; i<len; ++i) {\n                        this.writeNode(\"NamedLayer\", sld.namedLayers[i], root);\n                    }\n                } else {\n                    for(var name in sld.namedLayers) {\n                        this.writeNode(\"NamedLayer\", sld.namedLayers[name], root);\n                    }\n                }\n                return root;\n            },\n            \"Name\": function(name) {\n                return this.createElementNSPlus(\"sld:Name\", {value: name});\n            },\n            \"Title\": function(title) {\n                return this.createElementNSPlus(\"sld:Title\", {value: title});\n            },\n            \"Abstract\": function(description) {\n                return this.createElementNSPlus(\n                    \"sld:Abstract\", {value: description}\n                );\n            },\n            \"NamedLayer\": function(layer) {\n                var node = this.createElementNSPlus(\"sld:NamedLayer\");\n                this.writeNode(\"Name\", layer.name, node);\n                if(layer.namedStyles) {\n                    for(var i=0, len=layer.namedStyles.length; i<len; ++i) {\n                        this.writeNode(\n                            \"NamedStyle\", layer.namedStyles[i], node\n                        );\n                    }\n                }\n                if(layer.userStyles) {\n                    for(var i=0, len=layer.userStyles.length; i<len; ++i) {\n                        this.writeNode(\n                            \"UserStyle\", layer.userStyles[i], node\n                        );\n                    }\n                }\n                \n                return node;\n            },\n            \"NamedStyle\": function(name) {\n                var node = this.createElementNSPlus(\"sld:NamedStyle\");\n                this.writeNode(\"Name\", name, node);\n                return node;\n            },\n            \"UserStyle\": function(style) {\n                var node = this.createElementNSPlus(\"sld:UserStyle\");\n                if(style.name) {\n                    this.writeNode(\"Name\", style.name, node);\n                }\n                if(style.title) {\n                    this.writeNode(\"Title\", style.title, node);\n                }\n                if(style.description) {\n                    this.writeNode(\"Abstract\", style.description, node);\n                }\n                if(style.isDefault) {\n                    this.writeNode(\"IsDefault\", style.isDefault, node);\n                }\n                if (this.multipleSymbolizers && style.rules) {\n                    var rulesByZ = {\n                        0: []\n                    };\n                    var zValues = [0];\n                    var rule, ruleMap, symbolizer, zIndex, clone;\n                    for (var i=0, ii=style.rules.length; i<ii; ++i) {\n                        rule = style.rules[i];\n                        if (rule.symbolizers) {\n                            ruleMap = {};\n                            for (var j=0, jj=rule.symbolizers.length; j<jj; ++j) {\n                                symbolizer = rule.symbolizers[j];\n                                zIndex = symbolizer.zIndex;\n                                if (!(zIndex in ruleMap)) {\n                                    clone = rule.clone();\n                                    clone.symbolizers = [];\n                                    ruleMap[zIndex] = clone;\n                                }\n                                ruleMap[zIndex].symbolizers.push(symbolizer.clone());\n                            }\n                            for (zIndex in ruleMap) {\n                                if (!(zIndex in rulesByZ)) {\n                                    zValues.push(zIndex);\n                                    rulesByZ[zIndex] = [];\n                                }\n                                rulesByZ[zIndex].push(ruleMap[zIndex]);\n                            }\n                        } else {\n                            rulesByZ[0].push(rule.clone());\n                        }\n                    }\n                    zValues.sort();\n                    var rules;\n                    for (var i=0, ii=zValues.length; i<ii; ++i) {\n                        rules = rulesByZ[zValues[i]];\n                        if (rules.length > 0) {\n                            clone = style.clone();\n                            clone.rules = rulesByZ[zValues[i]];\n                            this.writeNode(\"FeatureTypeStyle\", clone, node);\n                        }\n                    }                    \n                } else {\n                    this.writeNode(\"FeatureTypeStyle\", style, node);\n                }\n                \n                return node;\n            },\n            \"IsDefault\": function(bool) {\n                return this.createElementNSPlus(\n                    \"sld:IsDefault\", {value: (bool) ? \"1\" : \"0\"}\n                );\n            },\n            \"FeatureTypeStyle\": function(style) {\n                var node = this.createElementNSPlus(\"sld:FeatureTypeStyle\");\n                for(var i=0, len=style.rules.length; i<len; ++i) {\n                    this.writeNode(\"Rule\", style.rules[i], node);\n                }\n                \n                return node;\n            },\n            \"Rule\": function(rule) {\n                var node = this.createElementNSPlus(\"sld:Rule\");\n                if(rule.name) {\n                    this.writeNode(\"Name\", rule.name, node);\n                }\n                if(rule.title) {\n                    this.writeNode(\"Title\", rule.title, node);\n                }\n                if(rule.description) {\n                    this.writeNode(\"Abstract\", rule.description, node);\n                }\n                if(rule.elseFilter) {\n                    this.writeNode(\"ElseFilter\", null, node);\n                } else if(rule.filter) {\n                    this.writeNode(\"ogc:Filter\", rule.filter, node);\n                }\n                if(rule.minScaleDenominator != undefined) {\n                    this.writeNode(\n                        \"MinScaleDenominator\", rule.minScaleDenominator, node\n                    );\n                }\n                if(rule.maxScaleDenominator != undefined) {\n                    this.writeNode(\n                        \"MaxScaleDenominator\", rule.maxScaleDenominator, node\n                    );\n                }\n                \n                var type, symbolizer;\n                if (this.multipleSymbolizers && rule.symbolizers) {\n                    var symbolizer;\n                    for (var i=0, ii=rule.symbolizers.length; i<ii; ++i) {\n                        symbolizer = rule.symbolizers[i];\n                        type = symbolizer.CLASS_NAME.split(\".\").pop();\n                        this.writeNode(\n                            type + \"Symbolizer\", symbolizer, node\n                        );\n                    }\n                } else {\n                    var types = OpenLayers.Style.SYMBOLIZER_PREFIXES;\n                    for(var i=0, len=types.length; i<len; ++i) {\n                        type = types[i];\n                        symbolizer = rule.symbolizer[type];\n                        if(symbolizer) {\n                            this.writeNode(\n                                type + \"Symbolizer\", symbolizer, node\n                            );\n                        }\n                    }\n                }\n                return node;\n\n            },\n            \"ElseFilter\": function() {\n                return this.createElementNSPlus(\"sld:ElseFilter\");\n            },\n            \"MinScaleDenominator\": function(scale) {\n                return this.createElementNSPlus(\n                    \"sld:MinScaleDenominator\", {value: scale}\n                );\n            },\n            \"MaxScaleDenominator\": function(scale) {\n                return this.createElementNSPlus(\n                    \"sld:MaxScaleDenominator\", {value: scale}\n                );\n            },\n            \"LineSymbolizer\": function(symbolizer) {\n                var node = this.createElementNSPlus(\"sld:LineSymbolizer\");\n                if (symbolizer.geometry) {\n                    this.writeNode(\"Geometry\", symbolizer.geometry, node);\n                }\n                this.writeNode(\"Stroke\", symbolizer, node);\n                return node;\n            },\n            \"Stroke\": function(symbolizer) {\n                var node = this.createElementNSPlus(\"sld:Stroke\");\n                if(symbolizer.strokeColor != undefined) {\n                    this.writeNode(\n                        \"CssParameter\",\n                        {symbolizer: symbolizer, key: \"strokeColor\"},\n                        node\n                    );\n                }\n                if(symbolizer.strokeOpacity != undefined) {\n                    this.writeNode(\n                        \"CssParameter\",\n                        {symbolizer: symbolizer, key: \"strokeOpacity\"},\n                        node\n                    );\n                }\n                if(symbolizer.strokeWidth != undefined) {\n                    this.writeNode(\n                        \"CssParameter\",\n                        {symbolizer: symbolizer, key: \"strokeWidth\"},\n                        node\n                    );\n                }\n                if(symbolizer.strokeDashstyle != undefined && symbolizer.strokeDashstyle !== \"solid\") {\n                    this.writeNode(\n                        \"CssParameter\", \n                        {symbolizer: symbolizer, key: \"strokeDashstyle\"},\n                        node\n                    );\n                }\n                if(symbolizer.strokeLinecap != undefined) {\n                    this.writeNode(\n                        \"CssParameter\", \n                        {symbolizer: symbolizer, key: \"strokeLinecap\"},\n                        node\n                    );\n                }\n                return node;\n            },\n            \"CssParameter\": function(obj) {\n                return this.createElementNSPlus(\"sld:CssParameter\", {\n                    attributes: {name: this.getCssProperty(obj.key)},\n                    value: obj.symbolizer[obj.key]\n                });\n            },\n            \"TextSymbolizer\": function(symbolizer) {\n                var node = this.createElementNSPlus(\"sld:TextSymbolizer\");\n                if (symbolizer.geometry) {\n                    this.writeNode(\"Geometry\", symbolizer.geometry, node);\n                }\n                if(symbolizer.label != null) {\n                    this.writeNode(\"Label\", symbolizer.label, node);\n                }\n                if(symbolizer.fontFamily != null ||\n                    symbolizer.fontSize != null ||\n                    symbolizer.fontWeight != null ||\n                    symbolizer.fontStyle != null) {\n                        this.writeNode(\"Font\", symbolizer, node);\n                }\n                if (symbolizer.labelAnchorPointX != null ||\n                    symbolizer.labelAnchorPointY != null || \n                    symbolizer.labelAlign != null ||\n                    symbolizer.labelXOffset != null ||\n                    symbolizer.labelYOffset != null ||\n                    symbolizer.labelRotation != null ||\n                    symbolizer.labelPerpendicularOffset != null) {\n                        this.writeNode(\"LabelPlacement\", symbolizer, node);\n                }\n                if(symbolizer.haloRadius != null ||\n                    symbolizer.haloColor != null ||\n                    symbolizer.haloOpacity != null) {\n                        this.writeNode(\"Halo\", symbolizer, node);\n                }\n                if(symbolizer.fontColor != null ||\n                   symbolizer.fontOpacity != null) {\n                    this.writeNode(\"Fill\", {\n                        fillColor: symbolizer.fontColor,\n                        fillOpacity: symbolizer.fontOpacity\n                    }, node);\n                }\n                return node;\n            },\n            \"LabelPlacement\": function(symbolizer) {\n                var node = this.createElementNSPlus(\"sld:LabelPlacement\");\n                if ((symbolizer.labelAnchorPointX != null ||\n                    symbolizer.labelAnchorPointY != null ||\n                    symbolizer.labelAlign != null ||\n                    symbolizer.labelXOffset != null ||\n                    symbolizer.labelYOffset != null ||\n                    symbolizer.labelRotation != null) && \n                    symbolizer.labelPerpendicularOffset == null) {\n                        this.writeNode(\"PointPlacement\", symbolizer, node);\n                }\n                if (symbolizer.labelPerpendicularOffset != null) {\n                    this.writeNode(\"LinePlacement\", symbolizer, node);\n                }\n                return node;\n            },\n            \"LinePlacement\": function(symbolizer) {\n                var node = this.createElementNSPlus(\"sld:LinePlacement\");\n                this.writeNode(\"PerpendicularOffset\", symbolizer.labelPerpendicularOffset, node);\n                return node;\n            },\n            \"PerpendicularOffset\": function(value) {\n                return this.createElementNSPlus(\"sld:PerpendicularOffset\", {\n                    value: value\n                });\n            },\n            \"PointPlacement\": function(symbolizer) {\n                var node = this.createElementNSPlus(\"sld:PointPlacement\");\n                if (symbolizer.labelAnchorPointX != null ||\n                    symbolizer.labelAnchorPointY != null ||\n                    symbolizer.labelAlign != null) {\n                        this.writeNode(\"AnchorPoint\", symbolizer, node);\n                }\n                if (symbolizer.labelXOffset != null ||\n                    symbolizer.labelYOffset != null) {\n                        this.writeNode(\"Displacement\", symbolizer, node);\n                }\n                if (symbolizer.labelRotation != null) {\n                    this.writeNode(\"Rotation\", symbolizer.labelRotation, node);\n                }\n                return node;\n            },\n            \"AnchorPoint\": function(symbolizer) {\n                var node = this.createElementNSPlus(\"sld:AnchorPoint\");\n                var x = symbolizer.labelAnchorPointX,\n                    y = symbolizer.labelAnchorPointY;\n                if (x != null) {\n                    this.writeNode(\"AnchorPointX\", x, node);\n                }\n                if (y != null) {\n                    this.writeNode(\"AnchorPointY\", y, node);\n                }\n                if (x == null && y == null) {\n                    var xAlign = symbolizer.labelAlign.substr(0, 1),\n                        yAlign = symbolizer.labelAlign.substr(1, 1);\n                    if (xAlign === \"l\") {\n                        x = 0;\n                    } else if (xAlign === \"c\") {\n                        x = 0.5;\n                    } else if (xAlign === \"r\") {\n                        x = 1;\n                    }\n                    if (yAlign === \"b\") {\n                        y = 0;\n                    } else if (yAlign === \"m\") {\n                        y = 0.5;\n                    } else if (yAlign === \"t\") {\n                        y = 1;\n                    }\n                    this.writeNode(\"AnchorPointX\", x, node);\n                    this.writeNode(\"AnchorPointY\", y, node);\n                }\n                return node;\n            },\n            \"AnchorPointX\": function(value) {\n                return this.createElementNSPlus(\"sld:AnchorPointX\", {\n                    value: value\n                }); \n            },\n            \"AnchorPointY\": function(value) {\n                return this.createElementNSPlus(\"sld:AnchorPointY\", {\n                    value: value\n                });\n            },\n            \"Displacement\": function(symbolizer) {\n                var node = this.createElementNSPlus(\"sld:Displacement\");\n                if (symbolizer.labelXOffset != null) {\n                    this.writeNode(\"DisplacementX\", symbolizer.labelXOffset, node);\n                }\n                if (symbolizer.labelYOffset != null) {\n                    this.writeNode(\"DisplacementY\", symbolizer.labelYOffset, node);\n                }\n                return node;\n            },\n            \"DisplacementX\": function(value) {\n                return this.createElementNSPlus(\"sld:DisplacementX\", {\n                    value: value\n                });\n            },\n            \"DisplacementY\": function(value) {\n                return this.createElementNSPlus(\"sld:DisplacementY\", {\n                    value: value\n                });\n            },\n            \"Font\": function(symbolizer) {\n                var node = this.createElementNSPlus(\"sld:Font\");\n                if(symbolizer.fontFamily) {\n                    this.writeNode(\n                        \"CssParameter\",\n                        {symbolizer: symbolizer, key: \"fontFamily\"},\n                        node\n                    );\n                }\n                if(symbolizer.fontSize) {\n                    this.writeNode(\n                        \"CssParameter\",\n                        {symbolizer: symbolizer, key: \"fontSize\"},\n                        node\n                    );\n                }\n                if(symbolizer.fontWeight) {\n                    this.writeNode(\n                        \"CssParameter\",\n                        {symbolizer: symbolizer, key: \"fontWeight\"},\n                        node\n                    );\n                }\n                if(symbolizer.fontStyle) {\n                    this.writeNode(\n                        \"CssParameter\",\n                        {symbolizer: symbolizer, key: \"fontStyle\"},\n                        node\n                    );\n                }\n                return node;\n            },\n            \"Label\": function(label) {\n                return this.writers.sld._OGCExpression.call(\n                    this, \"sld:Label\", label\n                );\n            },\n            \"Halo\": function(symbolizer) {\n                var node = this.createElementNSPlus(\"sld:Halo\");\n                if(symbolizer.haloRadius) {\n                    this.writeNode(\"Radius\", symbolizer.haloRadius, node);\n                }\n                if(symbolizer.haloColor || symbolizer.haloOpacity) {\n                    this.writeNode(\"Fill\", {\n                        fillColor: symbolizer.haloColor,\n                        fillOpacity: symbolizer.haloOpacity\n                    }, node);\n                }\n                return node;\n            },\n            \"Radius\": function(value) {\n                return this.createElementNSPlus(\"sld:Radius\", {\n                    value: value\n                });\n            },\n            \"RasterSymbolizer\": function(symbolizer) {\n                var node = this.createElementNSPlus(\"sld:RasterSymbolizer\");\n                if (symbolizer.geometry) {\n                    this.writeNode(\"Geometry\", symbolizer.geometry, node);\n                }\n                if (symbolizer.opacity) {\n                    this.writeNode(\"Opacity\", symbolizer.opacity, node);\n                }\n                if (symbolizer.colorMap) {\n                    this.writeNode(\"ColorMap\", symbolizer.colorMap, node);\n                }\n                return node;\n            },\n            \"Geometry\": function(geometry) {\n                var node = this.createElementNSPlus(\"sld:Geometry\");\n                if (geometry.property) {\n                    this.writeNode(\"ogc:PropertyName\", geometry, node);\n                }\n                return node;\n            },\n            \"ColorMap\": function(colorMap) {\n                var node = this.createElementNSPlus(\"sld:ColorMap\");\n                for (var i=0, len=colorMap.length; i<len; ++i) {\n                    this.writeNode(\"ColorMapEntry\", colorMap[i], node);\n                }\n                return node;\n            },\n            \"ColorMapEntry\": function(colorMapEntry) {\n                var node = this.createElementNSPlus(\"sld:ColorMapEntry\");\n                var a = colorMapEntry;\n                node.setAttribute(\"color\", a.color);\n                a.opacity !== undefined && node.setAttribute(\"opacity\",\n                    parseFloat(a.opacity));\n                a.quantity !== undefined && node.setAttribute(\"quantity\",\n                    parseFloat(a.quantity));\n                a.label !== undefined && node.setAttribute(\"label\", a.label);\n                return node;\n            },\n            \"PolygonSymbolizer\": function(symbolizer) {\n                var node = this.createElementNSPlus(\"sld:PolygonSymbolizer\");\n                if (symbolizer.geometry) {\n                    this.writeNode(\"Geometry\", symbolizer.geometry, node);\n                }\n                if(symbolizer.fill !== false) {\n                    this.writeNode(\"Fill\", symbolizer, node);\n                }\n                if(symbolizer.stroke !== false) {\n                    this.writeNode(\"Stroke\", symbolizer, node);\n                }\n                return node;\n            },\n            \"Fill\": function(symbolizer) {\n                var node = this.createElementNSPlus(\"sld:Fill\");\n                if(symbolizer.fillColor) {\n                    this.writeNode(\n                        \"CssParameter\",\n                        {symbolizer: symbolizer, key: \"fillColor\"},\n                        node\n                    );\n                }\n                if(symbolizer.fillOpacity != null) {\n                    this.writeNode(\n                        \"CssParameter\",\n                        {symbolizer: symbolizer, key: \"fillOpacity\"},\n                        node\n                    );\n                }\n                return node;\n            },\n            \"PointSymbolizer\": function(symbolizer) {\n                var node = this.createElementNSPlus(\"sld:PointSymbolizer\");\n                if (symbolizer.geometry) {\n                    this.writeNode(\"Geometry\", symbolizer.geometry, node);\n                }\n                this.writeNode(\"Graphic\", symbolizer, node);\n                return node;\n            },\n            \"Graphic\": function(symbolizer) {\n                var node = this.createElementNSPlus(\"sld:Graphic\");\n                if(symbolizer.externalGraphic != undefined) {\n                    this.writeNode(\"ExternalGraphic\", symbolizer, node);\n                } else {\n                    this.writeNode(\"Mark\", symbolizer, node);\n                }\n                \n                if(symbolizer.graphicOpacity != undefined) {\n                    this.writeNode(\"Opacity\", symbolizer.graphicOpacity, node);\n                }\n                if(symbolizer.pointRadius != undefined) {\n                    this.writeNode(\"Size\", symbolizer.pointRadius * 2, node);\n                } else if (symbolizer.graphicWidth != undefined) {\n                    this.writeNode(\"Size\", symbolizer.graphicWidth, node);\n                }\n                if(symbolizer.rotation != undefined) {\n                    this.writeNode(\"Rotation\", symbolizer.rotation, node);\n                }\n                return node;\n            },\n            \"ExternalGraphic\": function(symbolizer) {\n                var node = this.createElementNSPlus(\"sld:ExternalGraphic\");\n                this.writeNode(\n                    \"OnlineResource\", symbolizer.externalGraphic, node\n                );\n                var format = symbolizer.graphicFormat ||\n                             this.getGraphicFormat(symbolizer.externalGraphic);\n                this.writeNode(\"Format\", format, node);\n                return node;\n            },\n            \"Mark\": function(symbolizer) {\n                var node = this.createElementNSPlus(\"sld:Mark\");\n                if(symbolizer.graphicName) {\n                    this.writeNode(\"WellKnownName\", symbolizer.graphicName, node);\n                }\n                if (symbolizer.fill !== false) {\n                    this.writeNode(\"Fill\", symbolizer, node);\n                }\n                if (symbolizer.stroke !== false) {\n                    this.writeNode(\"Stroke\", symbolizer, node);\n                }\n                return node;\n            },\n            \"WellKnownName\": function(name) {\n                return this.createElementNSPlus(\"sld:WellKnownName\", {\n                    value: name\n                });\n            },\n            \"Opacity\": function(value) {\n                return this.createElementNSPlus(\"sld:Opacity\", {\n                    value: value\n                });\n            },\n            \"Size\": function(value) {\n                return this.writers.sld._OGCExpression.call(\n                    this, \"sld:Size\", value\n                );\n            },\n            \"Rotation\": function(value) {\n                return this.createElementNSPlus(\"sld:Rotation\", {\n                    value: value\n                });\n            },\n            \"OnlineResource\": function(href) {\n                return this.createElementNSPlus(\"sld:OnlineResource\", {\n                    attributes: {\n                        \"xlink:type\": \"simple\",\n                        \"xlink:href\": href\n                    }\n                });\n            },\n            \"Format\": function(format) {\n                return this.createElementNSPlus(\"sld:Format\", {\n                    value: format\n                });\n            }\n        }\n    }, OpenLayers.Format.Filter.v1_0_0.prototype.writers),\n    \n    CLASS_NAME: \"OpenLayers.Format.SLD.v1\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/SLD/v1_0_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.SLD.v1_0_0 = OpenLayers.Class(\n    OpenLayers.Format.SLD.v1, {\n    \n        VERSION: \"1.0.0\",\n    \n        schemaLocation: \"http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd\",\n\n    \n    CLASS_NAME: \"OpenLayers.Format.SLD.v1_0_0\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/SLD/v1_0_0_GeoServer.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.SLD.v1_0_0_GeoServer = OpenLayers.Class(\n    OpenLayers.Format.SLD.v1_0_0, {\n\n        version: \"1.0.0\",\n\n        profile: \"GeoServer\",\n\n   \n        readers: OpenLayers.Util.applyDefaults({\n        \"sld\": OpenLayers.Util.applyDefaults({\n            \"Priority\": function(node, obj) {\n                var value = this.readers.ogc._expression.call(this, node);\n                if (value) {\n                    obj.priority = OpenLayers.String.trim(value);\n                }\n            },\n            \"VendorOption\": function(node, obj) {\n                if (!obj.vendorOptions) {\n                    obj.vendorOptions = {};\n                }\n                obj.vendorOptions[node.getAttribute(\"name\")] = this.getChildValue(node);\n            },\n            \"TextSymbolizer\": function(node, rule) {\n                OpenLayers.Format.SLD.v1_0_0.prototype.readers.sld.TextSymbolizer.apply(this, arguments);\n                var symbolizer = this.multipleSymbolizers ? rule.symbolizers[rule.symbolizers.length-1] : rule.symbolizer[\"Text\"];\n                if (symbolizer.graphic === undefined) {\n                    symbolizer.graphic = false;\n                }\n            }\n        }, OpenLayers.Format.SLD.v1_0_0.prototype.readers[\"sld\"])\n    }, OpenLayers.Format.SLD.v1_0_0.prototype.readers),\n\n        writers: OpenLayers.Util.applyDefaults({\n        \"sld\": OpenLayers.Util.applyDefaults({\n            \"Priority\": function(priority) {\n                return this.writers.sld._OGCExpression.call(\n                    this, \"sld:Priority\", priority\n                );\n            },\n            \"VendorOption\": function(option) {\n                return this.createElementNSPlus(\"sld:VendorOption\", {\n                    attributes: {name: option.name},\n                    value: option.value\n                });\n            },\n            \"TextSymbolizer\": function(symbolizer) {\n                var writers = OpenLayers.Format.SLD.v1_0_0.prototype.writers;\n                var node = writers[\"sld\"][\"TextSymbolizer\"].apply(this, arguments);\n                if (symbolizer.graphic !== false && (symbolizer.externalGraphic || symbolizer.graphicName)) {\n                    this.writeNode(\"Graphic\", symbolizer, node);\n                }\n                if (\"priority\" in symbolizer) {\n                    this.writeNode(\"Priority\", symbolizer.priority, node);\n                }\n                return this.addVendorOptions(node, symbolizer);\n            },\n            \"PointSymbolizer\": function(symbolizer) {\n                var writers = OpenLayers.Format.SLD.v1_0_0.prototype.writers;\n                var node = writers[\"sld\"][\"PointSymbolizer\"].apply(this, arguments);\n                return this.addVendorOptions(node, symbolizer);\n            },\n            \"LineSymbolizer\": function(symbolizer) {\n                var writers = OpenLayers.Format.SLD.v1_0_0.prototype.writers;\n                var node = writers[\"sld\"][\"LineSymbolizer\"].apply(this, arguments);\n                return this.addVendorOptions(node, symbolizer);\n            },\n            \"PolygonSymbolizer\": function(symbolizer) {\n                var writers = OpenLayers.Format.SLD.v1_0_0.prototype.writers;\n                var node = writers[\"sld\"][\"PolygonSymbolizer\"].apply(this, arguments);\n                return this.addVendorOptions(node, symbolizer);\n            }\n        }, OpenLayers.Format.SLD.v1_0_0.prototype.writers[\"sld\"])\n    }, OpenLayers.Format.SLD.v1_0_0.prototype.writers),\n\n        addVendorOptions: function(node, symbolizer) {\n        var options = symbolizer.vendorOptions;\n        if (options) {\n            for (var key in symbolizer.vendorOptions) {\n                this.writeNode(\"VendorOption\", {\n                    name: key, \n                    value: symbolizer.vendorOptions[key]\n                }, node);\n            }\n        }\n        return node;\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.SLD.v1_0_0_GeoServer\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/SLD.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.SLD = OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC, {\n    \n        profile: null,\n\n        defaultVersion: \"1.0.0\",\n    \n        stringifyOutput: true,\n    \n        namedLayersAsArray: false,\n    \n        \n    \n    CLASS_NAME: \"OpenLayers.Format.SLD\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/SOSCapabilities/v1_0_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.SOSCapabilities.v1_0_0 = OpenLayers.Class(\n    OpenLayers.Format.SOSCapabilities, {\n\n        namespaces: {\n        ows: \"http://www.opengis.net/ows/1.1\",\n        sos: \"http://www.opengis.net/sos/1.0\",\n        gml: \"http://www.opengis.net/gml\",\n        xlink: \"http://www.w3.org/1999/xlink\"\n    },\n\n        regExes: {\n        trimSpace: (/^\\s*|\\s*$/g),\n        removeSpace: (/\\s*/g),\n        splitSpace: (/\\s+/),\n        trimComma: (/\\s*,\\s*/g)\n    },\n    \n        initialize: function(options) {\n        OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);\n        this.options = options;\n    },\n\n        read: function(data) {\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        if(data && data.nodeType == 9) {\n            data = data.documentElement;\n        }\n        var capabilities = {};\n        this.readNode(data, capabilities);\n        return capabilities;\n    },\n\n        readers: {\n        \"gml\": OpenLayers.Util.applyDefaults({\n            \"name\": function(node, obj) {\n                obj.name = this.getChildValue(node);\n            },\n            \"TimePeriod\": function(node, obj) {\n                obj.timePeriod = {};\n                this.readChildNodes(node, obj.timePeriod);\n            },\n            \"beginPosition\": function(node, timePeriod) {\n                timePeriod.beginPosition = this.getChildValue(node);\n            },\n            \"endPosition\": function(node, timePeriod) {\n                timePeriod.endPosition = this.getChildValue(node);\n            }\n        }, OpenLayers.Format.GML.v3.prototype.readers[\"gml\"]),\n        \"sos\": {\n            \"Capabilities\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"Contents\": function(node, obj) {\n                obj.contents = {};\n                this.readChildNodes(node, obj.contents);\n            },\n            \"ObservationOfferingList\": function(node, contents) {\n                contents.offeringList = {};\n                this.readChildNodes(node, contents.offeringList);\n            },\n            \"ObservationOffering\": function(node, offeringList) {\n                var id = this.getAttributeNS(node, this.namespaces.gml, \"id\");\n                offeringList[id] = {\n                    procedures: [],\n                    observedProperties: [],\n                    featureOfInterestIds: [],\n                    responseFormats: [],\n                    resultModels: [],\n                    responseModes: []\n                };\n                this.readChildNodes(node, offeringList[id]);\n            },\n            \"time\": function(node, offering) {\n                offering.time = {};\n                this.readChildNodes(node, offering.time);\n            },\n            \"procedure\": function(node, offering) {\n                offering.procedures.push(this.getAttributeNS(node, \n                    this.namespaces.xlink, \"href\"));\n            },\n            \"observedProperty\": function(node, offering) {\n                offering.observedProperties.push(this.getAttributeNS(node, \n                    this.namespaces.xlink, \"href\"));\n            },\n            \"featureOfInterest\": function(node, offering) {\n                offering.featureOfInterestIds.push(this.getAttributeNS(node, \n                    this.namespaces.xlink, \"href\"));\n            },\n            \"responseFormat\": function(node, offering) {\n                offering.responseFormats.push(this.getChildValue(node));\n            },\n            \"resultModel\": function(node, offering) {\n                offering.resultModels.push(this.getChildValue(node));\n            },\n            \"responseMode\": function(node, offering) {\n                offering.responseModes.push(this.getChildValue(node));\n            }\n        },\n        \"ows\": OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers[\"ows\"]\n    },    \n    \n    CLASS_NAME: \"OpenLayers.Format.SOSCapabilities.v1_0_0\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/SOSCapabilities.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n \nOpenLayers.Format.SOSCapabilities = OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC, {\n    \n        defaultVersion: \"1.0.0\",\n    \n    \n        \n    CLASS_NAME: \"OpenLayers.Format.SOSCapabilities\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/SOSGetFeatureOfInterest.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n \n\nOpenLayers.Format.SOSGetFeatureOfInterest = OpenLayers.Class(\n    OpenLayers.Format.XML, {\n    \n        VERSION: \"1.0.0\",\n\n        namespaces: {\n        sos: \"http://www.opengis.net/sos/1.0\",\n        gml: \"http://www.opengis.net/gml\",\n        sa: \"http://www.opengis.net/sampling/1.0\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\"\n    },\n\n        schemaLocation: \"http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosAll.xsd\",\n\n        defaultPrefix: \"sos\",\n\n        regExes: {\n        trimSpace: (/^\\s*|\\s*$/g),\n        removeSpace: (/\\s*/g),\n        splitSpace: (/\\s+/),\n        trimComma: (/\\s*,\\s*/g)\n    },\n    \n    \n        read: function(data) {\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        if(data && data.nodeType == 9) {\n            data = data.documentElement;\n        }\n\n        var info = {features: []};\n        this.readNode(data, info);\n       \n        var features = [];\n        for (var i=0, len=info.features.length; i<len; i++) {\n            var container = info.features[i];\n            if(this.internalProjection && this.externalProjection &&\n                container.components[0]) {\n                    container.components[0].transform(\n                        this.externalProjection, this.internalProjection\n                    );\n            }             \n            var feature = new OpenLayers.Feature.Vector(\n                container.components[0], container.attributes);\n            features.push(feature);\n        }\n        return features;\n    },\n\n        readers: {\n        \"sa\": {\n            \"SamplingPoint\": function(node, obj) {\n                if (!obj.attributes) {\n                    var feature = {attributes: {}};\n                    obj.features.push(feature);\n                    obj = feature;\n                }\n                obj.attributes.id = this.getAttributeNS(node, \n                    this.namespaces.gml, \"id\");\n                this.readChildNodes(node, obj);\n            },\n            \"position\": function (node, obj) {\n                this.readChildNodes(node, obj);\n            }\n        },\n        \"gml\": OpenLayers.Util.applyDefaults({\n            \"FeatureCollection\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"featureMember\": function(node, obj) {\n                var feature = {attributes: {}};\n                obj.features.push(feature);\n                this.readChildNodes(node, feature);\n            },\n            \"name\": function(node, obj) {\n                obj.attributes.name = this.getChildValue(node);\n            },\n            \"pos\": function(node, obj) {\n                if (!this.externalProjection) {\n                    this.externalProjection = new OpenLayers.Projection(\n                        node.getAttribute(\"srsName\"));\n                }\n             OpenLayers.Format.GML.v3.prototype.readers.gml.pos.apply(\n                    this, [node, obj]);\n            }\n        }, OpenLayers.Format.GML.v3.prototype.readers.gml)\n    },\n    \n        writers: {\n        \"sos\": {\n            \"GetFeatureOfInterest\": function(options) {\n                var node = this.createElementNSPlus(\"GetFeatureOfInterest\", {\n                    attributes: {\n                        version: this.VERSION,\n                        service: 'SOS',\n                        \"xsi:schemaLocation\": this.schemaLocation\n                    } \n                }); \n                for (var i=0, len=options.fois.length; i<len; i++) {\n                    this.writeNode(\"FeatureOfInterestId\", {foi: options.fois[i]}, node);\n                }\n                return node; \n            },\n            \"FeatureOfInterestId\": function(options) {\n                var node = this.createElementNSPlus(\"FeatureOfInterestId\", {value: options.foi});\n                return node;\n            }\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.SOSGetFeatureOfInterest\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/SOSGetObservation.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.SOSGetObservation = OpenLayers.Class(OpenLayers.Format.XML, {\n    \n        namespaces: {\n        ows: \"http://www.opengis.net/ows\",\n        gml: \"http://www.opengis.net/gml\",\n        sos: \"http://www.opengis.net/sos/1.0\",\n        ogc: \"http://www.opengis.net/ogc\",\n        om: \"http://www.opengis.net/om/1.0\",\n        sa: \"http://www.opengis.net/sampling/1.0\",\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\",\n        xmlns: \"http://www.w3.org/2000/xmlns/\"\n    },\n\n        regExes: {\n        trimSpace: (/^\\s*|\\s*$/g),\n        removeSpace: (/\\s*/g),\n        splitSpace: (/\\s+/),\n        trimComma: (/\\s*,\\s*/g)\n    },\n\n        VERSION: \"1.0.0\",\n\n        schemaLocation: \"http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosGetObservation.xsd\",\n\n        defaultPrefix: \"sos\",\n\n    \n        read: function(data) {\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        if(data && data.nodeType == 9) {\n            data = data.documentElement;\n        }\n        var info = {measurements: [], observations: []};\n        this.readNode(data, info);\n        return info;\n    },\n\n        write: function(options) {\n        var node = this.writeNode(\"sos:GetObservation\", options);\n        this.setAttributeNS(\n            node, this.namespaces.xmlns,\n            \"xmlns:om\", this.namespaces.om\n        );\n        this.setAttributeNS(\n            node, this.namespaces.xmlns,\n            \"xmlns:ogc\", this.namespaces.ogc\n        );\n        this.setAttributeNS(\n            node, this.namespaces.xsi,\n            \"xsi:schemaLocation\", this.schemaLocation\n        );\n        return OpenLayers.Format.XML.prototype.write.apply(this, [node]);\n    }, \n\n        readers: {\n        \"om\": {\n            \"ObservationCollection\": function(node, obj) {\n                obj.id = this.getAttributeNS(node, this.namespaces.gml, \"id\");\n                this.readChildNodes(node, obj);\n            },\n            \"member\": function(node, observationCollection) {\n                this.readChildNodes(node, observationCollection);\n            },\n            \"Measurement\": function(node, observationCollection) {\n                var measurement = {};\n                observationCollection.measurements.push(measurement);\n                this.readChildNodes(node, measurement);\n            },\n            \"Observation\": function(node, observationCollection) {\n                var observation = {};\n                observationCollection.observations.push(observation);\n                this.readChildNodes(node, observation);\n            },\n            \"samplingTime\": function(node, measurement) {\n                var samplingTime = {};\n                measurement.samplingTime = samplingTime;\n                this.readChildNodes(node, samplingTime);\n            },\n            \"observedProperty\": function(node, measurement) {\n                measurement.observedProperty = \n                    this.getAttributeNS(node, this.namespaces.xlink, \"href\");\n                this.readChildNodes(node, measurement);\n            },\n            \"procedure\": function(node, measurement) {\n                measurement.procedure = \n                    this.getAttributeNS(node, this.namespaces.xlink, \"href\");\n                this.readChildNodes(node, measurement);\n            },\n            \"featureOfInterest\": function(node, observation) {\n                var foi = {features: []};\n                observation.fois = [];\n                observation.fois.push(foi);\n                this.readChildNodes(node, foi);\n                var features = [];\n                for (var i=0, len=foi.features.length; i<len; i++) {\n                    var feature = foi.features[i];\n                    features.push(new OpenLayers.Feature.Vector(\n                        feature.components[0], feature.attributes));\n                }\n                foi.features = features;\n            },\n            \"result\": function(node, measurement) {\n                var result = {};\n                measurement.result = result;\n                if (this.getChildValue(node) !== '') {\n                    result.value = this.getChildValue(node);\n                    result.uom = node.getAttribute(\"uom\");\n                } else {\n                    this.readChildNodes(node, result);\n                }\n            }\n        },\n        \"sa\": OpenLayers.Format.SOSGetFeatureOfInterest.prototype.readers.sa,\n        \"gml\": OpenLayers.Util.applyDefaults({\n            \"TimeInstant\": function(node, samplingTime) {\n               var timeInstant = {};\n                samplingTime.timeInstant = timeInstant;\n                this.readChildNodes(node, timeInstant);\n            },\n            \"timePosition\": function(node, timeInstant) {\n                timeInstant.timePosition = this.getChildValue(node);\n            }\n        }, OpenLayers.Format.SOSGetFeatureOfInterest.prototype.readers.gml)\n    },\n\n        writers: {\n        \"sos\": {\n            \"GetObservation\": function(options) {\n                var node = this.createElementNSPlus(\"GetObservation\", {\n                    attributes: {\n                        version: this.VERSION,\n                        service: 'SOS'\n                    } \n                }); \n                this.writeNode(\"offering\", options, node);\n                if (options.eventTime) {\n                    this.writeNode(\"eventTime\", options, node);\n                }\n                for (var procedure in options.procedures) {\n                    this.writeNode(\"procedure\", options.procedures[procedure], node);\n                }\n                for (var observedProperty in options.observedProperties) {\n                    this.writeNode(\"observedProperty\", options.observedProperties[observedProperty], node);\n                }\n                if (options.foi) {\n                    this.writeNode(\"featureOfInterest\", options.foi, node);\n                }\n                this.writeNode(\"responseFormat\", options, node);\n                if (options.resultModel) {\n                    this.writeNode(\"resultModel\", options, node);\n                }\n                if (options.responseMode) {\n                    this.writeNode(\"responseMode\", options, node);\n                }\n                return node; \n            },\n            \"featureOfInterest\": function(foi) {\n                var node = this.createElementNSPlus(\"featureOfInterest\");\n                this.writeNode(\"ObjectID\", foi.objectId, node);\n                return node;\n            },\n            \"ObjectID\": function(options) {\n                return this.createElementNSPlus(\"ObjectID\",\n                    {value: options});\n            },\n            \"responseFormat\": function(options) {\n                return this.createElementNSPlus(\"responseFormat\", \n                    {value: options.responseFormat});\n            },\n            \"procedure\": function(procedure) {\n                return this.createElementNSPlus(\"procedure\", \n                    {value: procedure});\n            },\n            \"offering\": function(options) {\n                return this.createElementNSPlus(\"offering\", {value: \n                    options.offering});\n            },\n            \"observedProperty\": function(observedProperty) {\n                return this.createElementNSPlus(\"observedProperty\", \n                    {value: observedProperty});\n            },\n            \"eventTime\": function(options) {\n                var node = this.createElementNSPlus(\"eventTime\");\n                if (options.eventTime === 'latest') {\n                    this.writeNode(\"ogc:TM_Equals\", options, node);\n                }\n                return node;\n            },\n            \"resultModel\": function(options) {\n                return this.createElementNSPlus(\"resultModel\", {value: \n                    options.resultModel});\n            },\n            \"responseMode\": function(options) {\n                return this.createElementNSPlus(\"responseMode\", {value: \n                    options.responseMode});\n            }\n        },\n        \"ogc\": {\n            \"TM_Equals\": function(options) {\n                var node = this.createElementNSPlus(\"ogc:TM_Equals\");\n                this.writeNode(\"ogc:PropertyName\", {property: \n                    \"urn:ogc:data:time:iso8601\"}, node);\n                if (options.eventTime === 'latest') {\n                    this.writeNode(\"gml:TimeInstant\", {value: 'latest'}, node);\n                }\n                return node;\n            },\n            \"PropertyName\": function(options) {\n                return this.createElementNSPlus(\"ogc:PropertyName\", \n                    {value: options.property});\n            }\n        },\n        \"gml\": {\n            \"TimeInstant\": function(options) {\n                var node = this.createElementNSPlus(\"gml:TimeInstant\");\n                this.writeNode(\"gml:timePosition\", options, node);\n                return node;\n            },\n            \"timePosition\": function(options) {\n                var node = this.createElementNSPlus(\"gml:timePosition\", \n                    {value: options.value});\n                return node;\n            }\n        }\n    },\n    \n    CLASS_NAME: \"OpenLayers.Format.SOSGetObservation\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/TMSCapabilities.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.TMSCapabilities = OpenLayers.Class(\n    OpenLayers.Format.XML, {\n\n        defaultPrefix: \"tms\",\n\n        readers: {\n        \"tms\": {\n            \"Services\": function(node, obj) {\n                obj.services = [];\n                this.readChildNodes(node, obj);\n            },\n            \"TileMapService\": function(node, obj) {\n                if (obj.services) {\n                    obj.services.push({\n                        service: 'TMS', \n                        version: node.getAttribute(\"version\"),\n                        title: node.getAttribute(\"title\"),\n                        href: node.getAttribute(\"href\")\n                    });\n                } else {\n                    this.readChildNodes(node, obj);\n                }\n            },\n            \"TileMaps\": function(node, obj) {\n                obj.tileMaps = [];\n                this.readChildNodes(node, obj);\n            },\n            \"TileMap\": function(node, obj) {\n                if (obj.tileMaps) {\n                    obj.tileMaps.push({\n                        href: node.getAttribute(\"href\"),\n                        srs: node.getAttribute(\"srs\"),\n                        title: node.getAttribute(\"title\"),\n                        profile: node.getAttribute(\"profile\")\n                    });\n                } else {\n                    obj.version =  node.getAttribute(\"version\");\n                    obj.tileMapService = node.getAttribute(\"tilemapservice\");\n                    this.readChildNodes(node, obj);\n                }\n            },\n            \"Title\": function(node, obj) {\n                obj.title = this.getChildValue(node);\n            },\n            \"Abstract\": function(node, obj) {\n                obj['abstract'] = this.getChildValue(node);\n            },\n            \"SRS\": function(node, obj) {\n                obj.srs = this.getChildValue(node);\n            },\n            \"BoundingBox\": function(node, obj) {\n                obj.bbox = new OpenLayers.Bounds(\n                    node.getAttribute(\"minx\"),\n                    node.getAttribute(\"miny\"),\n                    node.getAttribute(\"maxx\"),\n                    node.getAttribute(\"maxy\"));\n            },\n            \"Origin\": function(node, obj) {\n                obj.origin = new OpenLayers.LonLat(\n                    node.getAttribute(\"x\"),\n                    node.getAttribute(\"y\"));\n            },\n            \"TileFormat\": function(node, obj) {\n                obj.tileFormat = {\n                    width: parseInt(node.getAttribute(\"width\"), 10),\n                    height: parseInt(node.getAttribute(\"height\"), 10),\n                    mimeType: node.getAttribute(\"mime-type\"),\n                    extension: node.getAttribute(\"extension\")\n                };\n            },\n            \"TileSets\": function(node, obj) {\n                obj.tileSets = [];\n                this.readChildNodes(node, obj);\n            },\n            \"TileSet\": function(node, obj) {\n                obj.tileSets.push({\n                    href: node.getAttribute(\"href\"),\n                    unitsPerPixel: parseFloat(node.getAttribute(\"units-per-pixel\")),\n                    order: parseInt(node.getAttribute(\"order\"), 10)\n                });\n            },\n            \"TileMapServerError\": function(node, obj) {\n                obj.error = true;\n            },\n            \"Message\": function(node, obj) {\n                obj.message = this.getChildValue(node);\n            }\n        }\n    },\n\n        read: function(data) {\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        var raw = data;\n        if(data && data.nodeType == 9) {\n            data = data.documentElement;\n        }\n        var capabilities = {};\n        this.readNode(data, capabilities);\n        return capabilities;\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.TMSCapabilities\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/Text.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.Text = OpenLayers.Class(OpenLayers.Format, {\n    \n        defaultStyle: null,\n     \n        extractStyles: true,\n\n        initialize: function(options) {\n        options = options || {};\n\n        if(options.extractStyles !== false) {\n            options.defaultStyle = {\n                'externalGraphic': OpenLayers.Util.getImageLocation(\"marker.png\"),\n                'graphicWidth': 21,\n                'graphicHeight': 25,\n                'graphicXOffset': -10.5,\n                'graphicYOffset': -12.5\n            };\n        }\n        \n        OpenLayers.Format.prototype.initialize.apply(this, [options]);\n    }, \n\n        read: function(text) {\n        var lines = text.split('\\n');\n        var columns;\n        var features = [];\n        for (var lcv = 0; lcv < (lines.length - 1); lcv++) {\n            var currLine = lines[lcv].replace(/^\\s*/,'').replace(/\\s*$/,'');\n        \n            if (currLine.charAt(0) != '#') { /* not a comment */\n            \n                if (!columns) {\n                    columns = currLine.split('\\t');\n                } else {\n                    var vals = currLine.split('\\t');\n                    var geometry = new OpenLayers.Geometry.Point(0,0);\n                    var attributes = {};\n                    var style = this.defaultStyle ? \n                        OpenLayers.Util.applyDefaults({}, this.defaultStyle) :\n                        null;  \n                    var icon, iconSize, iconOffset, overflow;\n                    var set = false;\n                    for (var valIndex = 0; valIndex < vals.length; valIndex++) {\n                        if (vals[valIndex]) {\n                            if (columns[valIndex] == 'point') {\n                                var coords = vals[valIndex].split(',');\n                                geometry.y = parseFloat(coords[0]);\n                                geometry.x = parseFloat(coords[1]);\n                                set = true;\n                            } else if (columns[valIndex] == 'lat') {\n                                geometry.y = parseFloat(vals[valIndex]);\n                                set = true;\n                            } else if (columns[valIndex] == 'lon') {\n                                geometry.x = parseFloat(vals[valIndex]);\n                                set = true;\n                            } else if (columns[valIndex] == 'title')\n                                attributes['title'] = vals[valIndex];\n                            else if (columns[valIndex] == 'image' ||\n                                     columns[valIndex] == 'icon' && style) {\n                                style['externalGraphic'] = vals[valIndex];\n                            } else if (columns[valIndex] == 'iconSize' && style) {\n                                var size = vals[valIndex].split(',');\n                                style['graphicWidth'] = parseFloat(size[0]);\n                                style['graphicHeight'] = parseFloat(size[1]);\n                            } else if (columns[valIndex] == 'iconOffset' && style) {\n                                var offset = vals[valIndex].split(',');\n                                style['graphicXOffset'] = parseFloat(offset[0]);\n                                style['graphicYOffset'] = parseFloat(offset[1]);\n                            } else if (columns[valIndex] == 'description') {\n                                attributes['description'] = vals[valIndex];\n                            } else if (columns[valIndex] == 'overflow') {\n                                attributes['overflow'] = vals[valIndex];\n                            } else {\n                                attributes[columns[valIndex]] = vals[valIndex];\n                            }    \n                        }\n                    }\n                    if (set) {\n                      if (this.internalProjection && this.externalProjection) {\n                          geometry.transform(this.externalProjection, \n                                             this.internalProjection); \n                      }\n                      var feature = new OpenLayers.Feature.Vector(geometry, attributes, style);\n                      features.push(feature);\n                    }\n                }\n            }\n        }\n        return features;\n    },   \n\n    CLASS_NAME: \"OpenLayers.Format.Text\" \n});    \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WCSCapabilities/v1.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WCSCapabilities.v1 = OpenLayers.Class(\n    OpenLayers.Format.XML, {\n\n    regExes: {\n        trimSpace: (/^\\s*|\\s*$/g),\n        splitSpace: (/\\s+/)\n    },\n\n        defaultPrefix: \"wcs\",\n\n        read: function(data) {\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        var raw = data;\n        if(data && data.nodeType == 9) {\n            data = data.documentElement;\n        }\n        var capabilities = {};\n        this.readNode(data, capabilities);\n        return capabilities;\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WCSCapabilities.v1\" \n\n});"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WCSCapabilities/v1_0_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WCSCapabilities.v1_0_0 = OpenLayers.Class(\n    OpenLayers.Format.GML.v3, OpenLayers.Format.WCSCapabilities.v1, {\n\n    \n        namespaces: {\n        wcs: \"http://www.opengis.net/wcs\",\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\",\n        ows: \"http://www.opengis.net/ows\"\n    },\n\n        errorProperty: \"serviceIdentification\",\n\n        readers: {\n        \"wcs\": {\n            \"WCS_Capabilities\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"Service\": function(node, obj) {\n                var children = {};\n                this.readChildNodes(node, children);\n                var providerName = children.serviceContact.providerName;\n                delete children.serviceContact.providerName;\n\n                obj.serviceProvider = { \n                    providerName:   providerName,\n                    serviceContact: children.serviceContact };\n                children.serviceContact = undefined;\n                obj.serviceIdentification = children;\n            },\n            \"keywords\": function(node, serviceIdentification) { \n                serviceIdentification.keywords = []; \n                this.readChildNodes(node, serviceIdentification.keywords);\n            },\n            \"keyword\": function(node, keywords) { \n                keywords.push(this.getChildValue(node));      \n            },\n            \"responsibleParty\": function(node, serviceIdentification) {\n                serviceIdentification.serviceContact = {};\n                this.readChildNodes(node, serviceIdentification.serviceContact);   \n            },\n            \"individualName\": function(node, serviceContact) {\n                serviceContact.individualName = this.getChildValue(node);\n            },\n            \"organisationName\": function(node, serviceContact) {\n                serviceContact.providerName = this.getChildValue(node);\n            },\n            \"positionName\": function(node, serviceContact) {\n                serviceContact.positionName = this.getChildValue(node);\n            },\n            \"contactInfo\": function(node, serviceContact) {\n                serviceContact.contactInfo = {};\n                this.readChildNodes(node, serviceContact.contactInfo);\n            },\n            \"phone\": function(node, contactInfo) {\n                contactInfo.phone = {};\n                this.readChildNodes(node, contactInfo.phone);\n            },\n            \"voice\": function(node, phone) {\n                phone.voice = this.getChildValue(node);\n            },\n            \"facsimile\": function(node, phone) {\n                phone.facsimile = this.getChildValue(node);\n            },\n            \"address\": function(node, contactInfo) {\n                contactInfo.address = {};\n                this.readChildNodes(node, contactInfo.address);\n            },\n            \"deliveryPoint\": function(node, address) {\n                address.deliveryPoint = this.getChildValue(node);\n            },\n            \"city\": function(node, address) {\n                address.city = this.getChildValue(node);\n            },\n            \"postalCode\": function(node, address) {\n                address.postalCode = this.getChildValue(node);\n            },\n            \"country\": function(node, address) {\n                address.country = this.getChildValue(node);\n            },\n            \"electronicMailAddress\": function(node, address) {\n                address.electronicMailAddress = this.getChildValue(node);\n            },\n            \"fees\": function(node, serviceIdentification) {\n                serviceIdentification.fees = this.getChildValue(node);\n            },\n            \"accessConstraints\": function(node, serviceIdentification) {\n                serviceIdentification.accessConstraints = this.getChildValue(node);\n            },\n            \"ContentMetadata\": function(node, obj) {\n                obj.contentMetadata = [];\n                this.readChildNodes(node, obj.contentMetadata);\n            },\n            \"CoverageOfferingBrief\": function(node, contentMetadata) {\n                var coverageOfferingBrief = {};\n                this.readChildNodes(node, coverageOfferingBrief);\n                contentMetadata.push(coverageOfferingBrief);\n            },\n            \"name\": function(node, serviceOrCoverageOfferingBrief) {\n                if(node.parentNode.nodeName.split(':').pop() === \"Service\") {\n                    serviceOrCoverageOfferingBrief.title = this.getChildValue(node);\n                }\n                else {      // node.parentNode.nodeName === \"CoverageOfferingBrief\"\n                    serviceOrCoverageOfferingBrief.identifier = this.getChildValue(node);\n                }\n            },\n            \"label\": function(node, serviceOrCoverageOfferingBrief) {\n                if(node.parentNode.nodeName.split(':').pop() === \"Service\") {\n                    serviceOrCoverageOfferingBrief['abstract'] = this.getChildValue(node);\n                }\n                else {      // node.parentNode.nodeName === \"CoverageOfferingBrief\"\n                    serviceOrCoverageOfferingBrief.title = this.getChildValue(node);\n                }\n            },\n            \"lonLatEnvelope\": function(node, coverageOfferingBrief) {\n                var nodeList = this.getElementsByTagNameNS(node, \"http://www.opengis.net/gml\", \"pos\");\n                if(nodeList.length == 2) {\n                    var min = {};\n                    var max = {};\n\n                    this.xy = true; // Affirm we don't want our coordinates switched around\n                    this.readers.gml.pos.apply(this, [nodeList[0], min]);\n                    this.readers.gml.pos.apply(this, [nodeList[1], max]);\n\n                    coverageOfferingBrief.lonLatEnvelope = {};\n                    coverageOfferingBrief.lonLatEnvelope.srsName = node.getAttribute(\"srsName\");\n                    coverageOfferingBrief.lonLatEnvelope.min = min.points[0];\n                    coverageOfferingBrief.lonLatEnvelope.max = max.points[0];\n                }\n            }\n        },\n        \"gml\": OpenLayers.Format.GML.v3.prototype.readers[\"gml\"]\n    },\n    \n    CLASS_NAME: \"OpenLayers.Format.WCSCapabilities.v1_0_0\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WCSCapabilities/v1_1_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WCSCapabilities.v1_1_0 = OpenLayers.Class(\n    OpenLayers.Format.WCSCapabilities.v1, {\n\n        namespaces: {\n        wcs: \"http://www.opengis.net/wcs/1.1\",\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\",\n        ows: \"http://www.opengis.net/ows/1.1\"\n    },\n\n        errorProperty: \"operationsMetadata\",\n\n    \n        readers: {\n        \"wcs\": OpenLayers.Util.applyDefaults({\n            \"Capabilities\": function(node, obj) {           \n                this.readChildNodes(node, obj);\n            },\n            \"Contents\": function(node, request) {\n                request.contentMetadata = [];\n                this.readChildNodes(node, request.contentMetadata);\n            },\n            \"CoverageSummary\": function(node, contentMetadata) {\n                var coverageSummary = {};\n                this.readChildNodes(node, coverageSummary);   \n                contentMetadata.push(coverageSummary);                 \n            },\n            \"Identifier\": function(node, coverageSummary) {\n                coverageSummary.identifier = this.getChildValue(node);\n            },\n            \"Title\": function(node, coverageSummary) {\n              coverageSummary.title = this.getChildValue(node);\n            },\n            \"Abstract\": function(node, coverageSummary) {\n                coverageSummary[\"abstract\"] = this.getChildValue(node);\n            },\n            \"SupportedCRS\": function(node, coverageSummary) {\n                var crs = this.getChildValue(node);\n                if(crs) {\n                    if(!coverageSummary.supportedCRS) { \n                        coverageSummary.supportedCRS = [];\n                    }\n                    coverageSummary.supportedCRS.push(crs);\n                }\n            },\n            \"SupportedFormat\": function(node, coverageSummary) {\n                var format = this.getChildValue(node);\n                if(format) {\n                    if(!coverageSummary.supportedFormat) { \n                        coverageSummary.supportedFormat = [];\n                    }\n                    coverageSummary.supportedFormat.push(format);\n                }\n            }\n        }, OpenLayers.Format.WCSCapabilities.v1.prototype.readers[\"wcs\"]),\n        \"ows\": OpenLayers.Util.applyDefaults({\n            \"Keywords\": function(node, serviceIdentification) {\n                serviceIdentification.keywords = [];\n                this.readChildNodes(node, serviceIdentification.keywords);\n            },\n            \"Keyword\": function(node, keywords) {\n                keywords.push(this.getChildValue(node));   \n            }\n        }, OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers[\"ows\"])\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WCSCapabilities.v1_1_0\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WCSCapabilities.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WCSCapabilities = OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC, {\n    \n        defaultVersion: \"1.1.0\",\n\n    \n        \n    CLASS_NAME: \"OpenLayers.Format.WCSCapabilities\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WCSDescribeCoverage/v1.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for \n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WCSDescribeCoverage.v1 = OpenLayers.Class(\n    OpenLayers.Format.XML, {\n\n    regExes: {\n        trimSpace: (/^\\s*|\\s*$/g),\n        splitSpace: (/\\s+/)\n    },\n\n        defaultPrefix: \"wcs\",\n\n        read: function(data) {\n        if(typeof data == \"string\") { \n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        if(data && data.nodeType == 9) {\n            data = data.documentElement;\n        }\n        var schema = {};\n        if (data.nodeName.split(\":\").pop() === 'ExceptionReport') {\n            var parser = new OpenLayers.Format.OGCExceptionReport();\n            schema.error = parser.read(data);\n        } else {\n            this.readNode(data, schema);\n        }\n        return schema;\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WCSDescribeCoverage.v1\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WCSDescribeCoverage/v1_0_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for \n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WCSDescribeCoverage.v1_0_0 = OpenLayers.Class(\n    OpenLayers.Format.WCSDescribeCoverage.v1, {\n\n        namespaces: {\n        wcs: \"http://www.opengis.net/wcs\",\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\",\n        ows: \"http://www.opengis.net/ows\",\n        gml: \"http://www.opengis.net/gml\"\n    },\n\n    \n        readers: {\n        \"wcs\": {\n            \"CoverageDescription\": function(node, obj) {\n                obj.coverageDescriptions = {};        \n                this.readChildNodes(node, obj.coverageDescriptions);\n                obj.coverageDescriptionKeys = [];\n                for(var key in obj.coverageDescriptions) {\n                    obj.coverageDescriptionKeys.push(key);\n                }\n            },\n            \"CoverageOffering\": function(node, descriptions) {\n                var description = {};\n                this.readChildNodes(node, description);\n                descriptions[description.identifier] = description;\n                description.nativeCRS = description.supportedCRSs.nativeCRSs[0];\n            },\n            \"name\": function(node, description) {\n                description.identifier = this.getChildValue(node);\n            },\n            \"label\": function(node, description) {\n                description.title = this.getChildValue(node);\n            },\n            \"lonLatEnvelope\": function(node, description) {\n                OpenLayers.Format.WCSCapabilities.v1_0_0.prototype.readers.wcs.lonLatEnvelope.call(this, node, description);\n            },\n            \"domainSet\": function(node, description) {\n                description.domain = {};\n                this.readChildNodes(node, description.domain);\n            },\n            \"spatialDomain\": function(node, domain) {\n                domain.spatialDomain = { boundingBoxes: {} };\n                this.readChildNodes(node, domain.spatialDomain);\n            },\n             \"nativeCRSs\": function(node, description) {\n                if(!description.nativeCRSs) {\n                    description.nativeCRSs = [];\n                }\n                var crs = this.getChildValue(node);\n                description.nativeCRSs.push(crs);\n            },\n            \"supportedCRSs\": function(node, description) {\n                if(!description.supportedCRSs) {\n                    description.supportedCRSs = [];\n                }\n                this.readChildNodes(node, description.supportedCRSs)\n            },\n            \"requestResponseCRSs\" : function(node, supportedCRSs) {\n                supportedCRSs.push(this.getChildValue(node));\n            },\n             \"supportedFormats\": function(node, description) {\n                if(!description.supportedFormats) {\n                    description.supportedFormats = [];\n                }\n                this.readChildNodes(node, description.supportedFormats)\n            },\n            \"formats\" : function(node, supportedFormats) {\n                supportedFormats.push(this.getChildValue(node));\n            }\n        }, \n \n        \"ows\": OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers[\"ows\"],\n        \"gml\": OpenLayers.Util.applyDefaults({\n            \"Envelope\": function(node, spatialDomain) {\n                var srsName = node.getAttribute(\"srsName\");\n                if(!srsName) { // No SRS?  What does this envelope mean?!?\n                    return;\n                }\n\n                var obj = {points: []};\n                this.readChildNodes(node, obj);\n\n                var min = obj.points[0];\n                var max = obj.points[1];\n                var bounds = new OpenLayers.Bounds(min.x, min.y, max.x, max.y);\n                spatialDomain.boundingBoxes[srsName] = bounds;\n            }\n        }, OpenLayers.Format.GML.v3.prototype.readers[\"gml\"])\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WCSDescribeCoverage.v1_0_0\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WCSDescribeCoverage/v1_1_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for \n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WCSDescribeCoverage.v1_1_0 = OpenLayers.Class(\n    OpenLayers.Format.WCSDescribeCoverage.v1, {\n\n        namespaces: {\n        wcs: \"http://www.opengis.net/wcs/1.1\",\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\",\n        ows: \"http://www.opengis.net/ows/1.1\",\n        owsesri: \"http://www.opengis.net/ows\"\n    },\n\n    \n        readers: {\n        \"wcs\": {\n            \"CoverageDescriptions\": function(node, obj) {\n                obj.coverageDescriptions = {};        \n                this.readChildNodes(node, obj.coverageDescriptions);\n\n                obj.coverageDescriptionKeys = [];\n                for(var key in obj.coverageDescriptions) {\n                    obj.coverageDescriptionKeys.push(key);\n                }\n            },\n            \"CoverageDescription\": function(node, descriptions) {\n                var description = {};\n                this.readChildNodes(node, description);\n                descriptions[description.identifier] = description;\n                description.nativeCRS = \n                        description.domain.spatialDomain.gridCRS.gridBaseCRS;\n            },\n            \"Identifier\": function(node, description) {\n                description.identifier = this.getChildValue(node);\n            },\n            \"Title\": function(node, description) {\n                description.title = this.getChildValue(node);\n            },\n            \"Domain\": function(node, description) {\n                description.domain = {};\n                this.readChildNodes(node, description.domain);\n            },\n            \"SpatialDomain\": function(node, domain) {\n                domain.spatialDomain = { boundingBoxes:{} };\n\n                var bb = { BoundingBox:[] };\n\n                this.readChildNodes(node, bb);\n                for(var i=0, len=bb.BoundingBox.length; i<len;i++) {\n                    if(!!bb.BoundingBox[i].crs) {\n                        domain.spatialDomain.boundingBoxes[bb.BoundingBox[i].crs] = \n                            bb.BoundingBox[i].bounds;\n                        }\n                }\n                domain.spatialDomain.gridCRS = bb.gridCRS;\n            },\n            \"GridCRS\": function(node, spatialDomain) {\n                spatialDomain.gridCRS = {};\n                this.readChildNodes(node, spatialDomain.gridCRS);\n            },\n            \"GridBaseCRS\": function(node, gridCRS) {\n                gridCRS.gridBaseCRS = this.getChildValue(node);\n            },\n            \"GridType\": function(node, gridCRS) {\n                gridCRS.gridType = this.getChildValue(node);\n            },\n            \"GridOrigin\": function(node, gridCRS) {\n                var xy = this.getChildValue(node).split(' '); \n                if(xy.length == 2) {\n                    gridCRS.gridOrigin = {};\n                    gridCRS.gridOrigin.x = Number(xy[0]);\n                    gridCRS.gridOrigin.y = Number(xy[1]);\n                }\n            },\n            \"GridOffsets\": function(node, gridCRS) {\n                var xy = this.getChildValue(node).split(' '); \n                if(xy.length == 2) {\n                    gridCRS.gridOffsets = {};\n                    gridCRS.gridOffsets.x = Number(xy[0]);\n                    gridCRS.gridOffsets.y = Number(xy[1]);\n                }\n            },\n            \"GridCS\": function(node, gridCRS) {\n                gridCRS.gridCS = this.getChildValue(node);\n            },\n            \"SupportedCRS\": function(node, description) {\n                if(!!!description.supportedCRSs) {\n                    description.supportedCRSs = [];\n                }\n\n                var crs = this.getChildValue(node);\n                description.supportedCRSs.push(crs);\n            },\n            \"SupportedFormat\": function(node, description) {\n                if(!!!description.supportedFormats) {\n                    description.supportedFormats = [];\n                }\n\n                var format = this.getChildValue(node);\n                description.supportedFormats.push(format);\n            }\n        },\n        \"ows\": OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers[\"ows\"],\n        \"owsesri\": OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers[\"ows\"]\n\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WCSDescribeCoverage.v1_1_0\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WCSDescribeCoverage.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for \n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WCSDescribeCoverage = OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC, {\n    \n        defaultVersion: \"1.1.0\",\n\n    \n       \n    CLASS_NAME: \"OpenLayers.Format.WCSDescribeCoverage\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WCSGetCoverage.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WCSGetCoverage = OpenLayers.Class(OpenLayers.Format.XML, {\n    \n        namespaces: {\n        ows: \"http://www.opengis.net/ows/1.1\",\n        wcs: \"http://www.opengis.net/wcs/1.1\",\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\"\n    },\n\n        regExes: {\n        trimSpace: (/^\\s*|\\s*$/g),\n        removeSpace: (/\\s*/g),\n        splitSpace: (/\\s+/),\n        trimComma: (/\\s*,\\s*/g)\n    },\n\n        VERSION: \"1.1.2\",\n\n        schemaLocation: \"http://www.opengis.net/wcs/1.1 http://schemas.opengis.net/wcs/1.1/wcsGetCoverage.xsd\",\n\n    \n        write: function(options) {\n        var node = this.writeNode(\"wcs:GetCoverage\", options);\n        this.setAttributeNS(\n            node, this.namespaces.xsi,\n            \"xsi:schemaLocation\", this.schemaLocation\n        );\n        return OpenLayers.Format.XML.prototype.write.apply(this, [node]);\n    }, \n\n        writers: {\n        \"wcs\": {\n            \"GetCoverage\": function(options) {\n                var node = this.createElementNSPlus(\"wcs:GetCoverage\", {\n                    attributes: {\n                        version: options.version || this.VERSION,\n                        service: 'WCS'\n                    } \n                }); \n                this.writeNode(\"ows:Identifier\", options.identifier, node);\n                this.writeNode(\"wcs:DomainSubset\", options.domainSubset, node);\n                this.writeNode(\"wcs:Output\", options.output, node);\n                return node; \n            },\n            \"DomainSubset\": function(domainSubset) {\n                var node = this.createElementNSPlus(\"wcs:DomainSubset\", {});\n                this.writeNode(\"ows:BoundingBox\", domainSubset.boundingBox, node);\n                if (domainSubset.temporalSubset) {\n                    this.writeNode(\"wcs:TemporalSubset\", domainSubset.temporalSubset, node);\n                }\n                return node;\n            },\n            \"TemporalSubset\": function(temporalSubset) {\n                var node = this.createElementNSPlus(\"wcs:TemporalSubset\", {});\n                for (var i=0, len=temporalSubset.timePeriods.length; i<len; ++i) {\n                    this.writeNode(\"wcs:TimePeriod\", temporalSubset.timePeriods[i], node);\n                }\n                return node;\n            },\n            \"TimePeriod\": function(timePeriod) {\n                var node = this.createElementNSPlus(\"wcs:TimePeriod\", {});\n                this.writeNode(\"wcs:BeginPosition\", timePeriod.begin, node);\n                this.writeNode(\"wcs:EndPosition\", timePeriod.end, node);\n                if (timePeriod.resolution) {\n                    this.writeNode(\"wcs:TimeResolution\", timePeriod.resolution, node);\n                }\n                return node;\n            },\n            \"BeginPosition\": function(begin) {\n                var node = this.createElementNSPlus(\"wcs:BeginPosition\", {\n                    value: begin\n                });\n                return node;\n            },\n            \"EndPosition\": function(end) {\n                var node = this.createElementNSPlus(\"wcs:EndPosition\", {\n                    value: end\n                });\n                return node;\n            },\n            \"TimeResolution\": function(resolution) {\n                var node = this.createElementNSPlus(\"wcs:TimeResolution\", {\n                    value: resolution\n                });\n                return node;\n            },\n            \"Output\": function(output) {\n                var node = this.createElementNSPlus(\"wcs:Output\", {\n                    attributes: {\n                        format: output.format,\n                        store: output.store\n                    }\n                });\n                if (output.gridCRS) {\n                    this.writeNode(\"wcs:GridCRS\", output.gridCRS, node);\n                }\n                return node;\n            },\n            \"GridCRS\": function(gridCRS) {\n                var node = this.createElementNSPlus(\"wcs:GridCRS\", {});\n                this.writeNode(\"wcs:GridBaseCRS\", gridCRS.baseCRS, node);\n                if (gridCRS.type) {\n                    this.writeNode(\"wcs:GridType\", gridCRS.type, node);\n                }\n                if (gridCRS.origin) {\n                    this.writeNode(\"wcs:GridOrigin\", gridCRS.origin, node);\n                }\n                this.writeNode(\"wcs:GridOffsets\", gridCRS.offsets, node);\n                if (gridCRS.CS) {\n                    this.writeNode(\"wcs:GridCS\", gridCRS.CS, node);\n                }\n                return node;\n            },\n            \"GridBaseCRS\": function(baseCRS) {\n                return this.createElementNSPlus(\"wcs:GridBaseCRS\", {\n                    value: baseCRS\n                });\n            },\n            \"GridOrigin\": function(origin) {\n                return this.createElementNSPlus(\"wcs:GridOrigin\", {\n                    value: origin\n                });\n            },\n            \"GridType\": function(type) {\n                return this.createElementNSPlus(\"wcs:GridType\", {\n                    value: type\n                });\n            },\n            \"GridOffsets\": function(offsets) {\n                return this.createElementNSPlus(\"wcs:GridOffsets\", {\n                    value: offsets\n                });\n            },\n            \"GridCS\": function(CS) {\n                return this.createElementNSPlus(\"wcs:GridCS\", {\n                    value: CS\n                });\n            }\n        },\n        \"ows\": OpenLayers.Format.OWSCommon.v1_1_0.prototype.writers.ows\n    },\n    \n    CLASS_NAME: \"OpenLayers.Format.WCSGetCoverage\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WFS.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WFS = OpenLayers.Class(OpenLayers.Format.GML, {\n    \n        layer: null,\n    \n        wfsns: \"http://www.opengis.net/wfs\",\n    \n        ogcns: \"http://www.opengis.net/ogc\",\n    \n        initialize: function(options, layer) {\n        OpenLayers.Format.GML.prototype.initialize.apply(this, [options]);\n        this.layer = layer;\n        if (this.layer.featureNS) {\n            this.featureNS = this.layer.featureNS;\n        }    \n        if (this.layer.options.geometry_column) {\n            this.geometryName = this.layer.options.geometry_column;\n        }\n        if (this.layer.options.typename) {\n            this.featureName = this.layer.options.typename;\n        }\n    },\n    \n        write: function(features) {\n    \n        var transaction = this.createElementNS(this.wfsns, 'wfs:Transaction');\n        transaction.setAttribute(\"version\",\"1.0.0\");\n        transaction.setAttribute(\"service\",\"WFS\");\n        for (var i=0; i < features.length; i++) {\n            switch (features[i].state) {\n                case OpenLayers.State.INSERT:\n                    transaction.appendChild(this.insert(features[i]));\n                    break;\n                case OpenLayers.State.UPDATE:\n                    transaction.appendChild(this.update(features[i]));\n                    break;\n                case OpenLayers.State.DELETE:\n                    transaction.appendChild(this.remove(features[i]));\n                    break;\n            }\n        }\n        \n        return OpenLayers.Format.XML.prototype.write.apply(this,[transaction]);\n    },\n   \n        insert: function(feature) {\n        var insertNode = this.createElementNS(this.wfsns, 'wfs:Insert');\n        insertNode.appendChild(this.createFeatureXML(feature));\n        return insertNode;\n    },\n    \n        update: function(feature) {\n        if (!feature.fid) { OpenLayers.Console.userError(OpenLayers.i18n(\"noFID\")); }\n        var updateNode = this.createElementNS(this.wfsns, 'wfs:Update');\n        updateNode.setAttribute(\"typeName\", this.featurePrefix + ':' + this.featureName); \n        updateNode.setAttribute(\"xmlns:\" + this.featurePrefix, this.featureNS); \n\n        var propertyNode = this.createElementNS(this.wfsns, 'wfs:Property');\n        var nameNode = this.createElementNS(this.wfsns, 'wfs:Name');\n        \n        var txtNode = this.createTextNode(this.geometryName);\n        nameNode.appendChild(txtNode);\n        propertyNode.appendChild(nameNode);\n        \n        var valueNode = this.createElementNS(this.wfsns, 'wfs:Value');\n        \n        var geometryNode = this.buildGeometryNode(feature.geometry);\n        \n        if(feature.layer){\n            geometryNode.setAttribute(\n                \"srsName\", feature.layer.projection.getCode()\n            );\n        }\n        \n        valueNode.appendChild(geometryNode);\n        \n        propertyNode.appendChild(valueNode);\n        updateNode.appendChild(propertyNode);\n        for(var propName in feature.attributes) {\n            propertyNode = this.createElementNS(this.wfsns, 'wfs:Property');\n            nameNode = this.createElementNS(this.wfsns, 'wfs:Name');\n            nameNode.appendChild(this.createTextNode(propName));\n            propertyNode.appendChild(nameNode);\n            valueNode = this.createElementNS(this.wfsns, 'wfs:Value');\n            valueNode.appendChild(this.createTextNode(feature.attributes[propName]));\n            propertyNode.appendChild(valueNode);\n            updateNode.appendChild(propertyNode);\n        }\n        \n        \n        var filterNode = this.createElementNS(this.ogcns, 'ogc:Filter');\n        var filterIdNode = this.createElementNS(this.ogcns, 'ogc:FeatureId');\n        filterIdNode.setAttribute(\"fid\", feature.fid);\n        filterNode.appendChild(filterIdNode);\n        updateNode.appendChild(filterNode);\n\n        return updateNode;\n    },\n    \n        remove: function(feature) {\n        if (!feature.fid) { \n            OpenLayers.Console.userError(OpenLayers.i18n(\"noFID\")); \n            return false; \n        }\n        var deleteNode = this.createElementNS(this.wfsns, 'wfs:Delete');\n        deleteNode.setAttribute(\"typeName\", this.featurePrefix + ':' + this.featureName); \n        deleteNode.setAttribute(\"xmlns:\" + this.featurePrefix, this.featureNS); \n\n        var filterNode = this.createElementNS(this.ogcns, 'ogc:Filter');\n        var filterIdNode = this.createElementNS(this.ogcns, 'ogc:FeatureId');\n        filterIdNode.setAttribute(\"fid\", feature.fid);\n        filterNode.appendChild(filterIdNode);\n        deleteNode.appendChild(filterNode);\n\n        return deleteNode;\n    },\n\n        destroy: function() {\n        this.layer = null;\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WFS\" \n});    \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WFSCapabilities/v1.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WFSCapabilities.v1 = OpenLayers.Class(\n    OpenLayers.Format.XML, {\n\n        namespaces: {\n        wfs: \"http://www.opengis.net/wfs\",\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\",\n        ows: \"http://www.opengis.net/ows\"\n    },\n\n\n        errorProperty: \"featureTypeList\",\n\n        defaultPrefix: \"wfs\",\n    \n    \n        read: function(data) {\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        var raw = data;\n        if(data && data.nodeType == 9) {\n            data = data.documentElement;\n        }\n        var capabilities = {};\n        this.readNode(data, capabilities);\n        return capabilities;\n    },\n\n        readers: {\n        \"wfs\": {\n            \"WFS_Capabilities\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"FeatureTypeList\": function(node, request) {\n                request.featureTypeList = {\n                    featureTypes: []\n                };\n                this.readChildNodes(node, request.featureTypeList);\n            },\n            \"FeatureType\": function(node, featureTypeList) {\n                var featureType = {};\n                this.readChildNodes(node, featureType);\n                featureTypeList.featureTypes.push(featureType);\n            },\n            \"Name\": function(node, obj) {\n                var name = this.getChildValue(node);\n                if(name) {\n                    var parts = name.split(\":\");\n                    obj.name = parts.pop();\n                    if(parts.length > 0) {\n                        obj.featureNS = this.lookupNamespaceURI(node, parts[0]);\n                    }\n                }\n            },\n            \"Title\": function(node, obj) {\n                var title = this.getChildValue(node);\n                if(title) {\n                    obj.title = title;\n                }\n            },\n            \"Abstract\": function(node, obj) {\n                var abst = this.getChildValue(node);\n                if(abst) {\n                    obj[\"abstract\"] = abst;\n                }\n            }\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WFSCapabilities.v1\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WFSCapabilities/v1_0_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WFSCapabilities.v1_0_0 = OpenLayers.Class(\n    OpenLayers.Format.WFSCapabilities.v1, {\n    \n    \n        readers: {\n        \"wfs\": OpenLayers.Util.applyDefaults({\n            \"Service\": function(node, capabilities) {\n                capabilities.service = {};\n                this.readChildNodes(node, capabilities.service);\n            },\n            \"Fees\": function(node, service) {\n                var fees = this.getChildValue(node);\n                if (fees && fees.toLowerCase() != \"none\") {\n                    service.fees = fees;\n                }\n            },\n            \"AccessConstraints\": function(node, service) {\n                var constraints = this.getChildValue(node);\n                if (constraints && constraints.toLowerCase() != \"none\") {\n                    service.accessConstraints = constraints;\n                }\n            },\n            \"OnlineResource\": function(node, service) {\n                var onlineResource = this.getChildValue(node);\n                if (onlineResource && onlineResource.toLowerCase() != \"none\") {\n                    service.onlineResource = onlineResource;\n                }\n            },\n            \"Keywords\": function(node, service) {\n                var keywords = this.getChildValue(node);\n                if (keywords && keywords.toLowerCase() != \"none\") {\n                    service.keywords = keywords.split(', ');\n                }\n            },\n            \"Capability\": function(node, capabilities) {\n                capabilities.capability = {};\n                this.readChildNodes(node, capabilities.capability);\n            },\n            \"Request\": function(node, obj) {\n                obj.request = {};\n                this.readChildNodes(node, obj.request);\n            },\n            \"GetFeature\": function(node, request) {\n                request.getfeature = {\n                    href: {}, // DCPType\n                    formats: [] // ResultFormat\n                };\n                this.readChildNodes(node, request.getfeature);\n            },\n            \"ResultFormat\": function(node, obj) {\n                var children = node.childNodes;\n                var childNode;\n                for(var i=0; i<children.length; i++) {\n                    childNode = children[i];\n                    if(childNode.nodeType == 1) {\n                        obj.formats.push(childNode.nodeName);\n                    }\n                }\n            },\n            \"DCPType\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"HTTP\": function(node, obj) {\n                this.readChildNodes(node, obj.href);\n            },\n            \"Get\": function(node, obj) {\n                obj.get = node.getAttribute(\"onlineResource\");\n            },\n            \"Post\": function(node, obj) {\n                obj.post = node.getAttribute(\"onlineResource\");\n            },\n            \"SRS\": function(node, obj) {\n                var srs = this.getChildValue(node);\n                if (srs) {\n                    obj.srs = srs;\n                }\n            },\n            \"LatLongBoundingBox\": function(node, obj) {\n                obj.latLongBoundingBox = [\n                    parseFloat(node.getAttribute(\"minx\")),\n                    parseFloat(node.getAttribute(\"miny\")),\n                    parseFloat(node.getAttribute(\"maxx\")),\n                    parseFloat(node.getAttribute(\"maxy\"))\n                ];\n            }\n        }, OpenLayers.Format.WFSCapabilities.v1.prototype.readers[\"wfs\"])\n    },\n    \n    CLASS_NAME: \"OpenLayers.Format.WFSCapabilities.v1_0_0\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WFSCapabilities/v1_1_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WFSCapabilities.v1_1_0 = OpenLayers.Class(\n    OpenLayers.Format.WFSCapabilities.v1, {\n\n        regExes: {\n        trimSpace: (/^\\s*|\\s*$/g),\n        removeSpace: (/\\s*/g),\n        splitSpace: (/\\s+/),\n        trimComma: (/\\s*,\\s*/g)\n    },\n    \n    \n        readers: {\n        \"wfs\": OpenLayers.Util.applyDefaults({\n            \"DefaultSRS\": function(node, obj) {\n                var defaultSRS = this.getChildValue(node);\n                if (defaultSRS) {\n                    obj.srs = defaultSRS;\n                }\n            }\n        }, OpenLayers.Format.WFSCapabilities.v1.prototype.readers[\"wfs\"]),\n        \"ows\": OpenLayers.Format.OWSCommon.v1.prototype.readers.ows\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WFSCapabilities.v1_1_0\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WFSCapabilities/v2_0_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WFSCapabilities.v2_0_0 = OpenLayers.Class(\n    OpenLayers.Format.XML, {\n\n        namespaces: {\n        wfs: \"http://www.opengis.net/wfs/2.0\",\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\",\n        ows: \"http://www.opengis.net/ows/1.1\"\n    },\n\n        regExes: {\n        trimSpace: (/^\\s*|\\s*$/g),\n        removeSpace: (/\\s*/g),\n        splitSpace: (/\\s+/),\n        trimComma: (/\\s*,\\s*/g)\n    },\n\n        errorProperty: \"featureTypeList\",\n\n        defaultPrefix: \"wfs\",\n    \n    \n        read: function(data) {\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        var raw = data;\n        if(data && data.nodeType == 9) {\n            data = data.documentElement;\n        }\n        var capabilities = {};\n        this.readNode(data, capabilities);\n        return capabilities;\n    },\n\n        readers: {\n        \"wfs\": {\n            \"WFS_Capabilities\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"FeatureTypeList\": function(node, request) {\n                request.featureTypeList = {\n                    featureTypes: []\n                };\n                this.readChildNodes(node, request.featureTypeList);\n            },\n            \"FeatureType\": function(node, featureTypeList) {\n                var featureType = {};\n                this.readChildNodes(node, featureType);\n                featureTypeList.featureTypes.push(featureType);\n            },\n            \"Name\": function(node, obj) {\n                var name = this.getChildValue(node);\n                if(name) {\n                    var parts = name.split(\":\");\n                    obj.name = parts.pop();\n                    if(parts.length > 0) {\n                        obj.featureNS = this.lookupNamespaceURI(node, parts[0]);\n                    }\n                }\n            },\n            \"Title\": function(node, obj) {\n                var title = this.getChildValue(node);\n                if(title) {\n                    obj.title = title;\n                }\n            },\n            \"Abstract\": function(node, obj) {\n                var abst = this.getChildValue(node);\n                if(abst) {\n                    obj[\"abstract\"] = abst;\n                }\n            },\n            \"DefaultCRS\": function(node, obj) {\n                var defaultCRS = this.getChildValue(node);\n                if (defaultCRS) {\n                    obj.srs = defaultCRS;\n                }\n            }\n        },\n        \"ows\": OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers.ows\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WFSCapabilities.v2_0_0\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WFSCapabilities.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WFSCapabilities = OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC, {\n    \n        defaultVersion: \"1.1.0\",\n\n    \n        \n    CLASS_NAME: \"OpenLayers.Format.WFSCapabilities\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WFSDescribeFeatureType.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n \nOpenLayers.Format.WFSDescribeFeatureType = OpenLayers.Class(\n    OpenLayers.Format.XML, {\n\n        regExes: {\n        trimSpace: (/^\\s*|\\s*$/g)\n    },\n    \n        namespaces: {\n        xsd: \"http://www.w3.org/2001/XMLSchema\"\n    },\n    \n        \n        readers: {\n        \"xsd\": {\n            \"schema\": function(node, obj) {\n                var complexTypes = [];\n                var customTypes = {};\n                var schema = {\n                    complexTypes: complexTypes,\n                    customTypes: customTypes\n                };\n                var i, len;\n                \n                this.readChildNodes(node, schema);\n\n                var attributes = node.attributes;\n                var attr, name;\n                for(i=0, len=attributes.length; i<len; ++i) {\n                    attr = attributes[i];\n                    name = attr.name;\n                    if(name.indexOf(\"xmlns\") === 0) {\n                        this.setNamespace(name.split(\":\")[1] || \"\", attr.value);\n                    } else {\n                        obj[name] = attr.value;\n                    }\n                }\n                obj.featureTypes = complexTypes;                \n                obj.targetPrefix = this.namespaceAlias[obj.targetNamespace];\n                var complexType, customType;\n                for(i=0, len=complexTypes.length; i<len; ++i) {\n                    complexType = complexTypes[i];\n                    customType = customTypes[complexType.typeName];\n                    if(customTypes[complexType.typeName]) {\n                        complexType.typeName = customType.name;\n                    }\n                }\n            },\n            \"complexType\": function(node, obj) {\n                var complexType = {\n                    \"typeName\": node.getAttribute(\"name\")\n                };\n                this.readChildNodes(node, complexType);\n                obj.complexTypes.push(complexType);\n            },\n            \"complexContent\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"extension\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"sequence\": function(node, obj) {\n                var sequence = {\n                    elements: []\n                };\n                this.readChildNodes(node, sequence);\n                obj.properties = sequence.elements;\n            },\n            \"element\": function(node, obj) {\n                var type;\n                if(obj.elements) {\n                    var element = {};\n                    var attributes = node.attributes;\n                    var attr;\n                    for(var i=0, len=attributes.length; i<len; ++i) {\n                        attr = attributes[i];\n                        element[attr.name] = attr.value;\n                    }\n                    \n                    type = element.type;\n                    if(!type) {\n                        type = {};\n                        this.readChildNodes(node, type);\n                        element.restriction = type;\n                        element.type = type.base;\n                    }\n                    var fullType = type.base || type;\n                    element.localType = fullType.split(\":\").pop();\n                    obj.elements.push(element);\n                    this.readChildNodes(node, element);\n                }\n                \n                if(obj.complexTypes) {\n                    type = node.getAttribute(\"type\");\n                    var localType = type.split(\":\").pop();\n                    obj.customTypes[localType] = {\n                        \"name\": node.getAttribute(\"name\"),\n                        \"type\": type\n                    };\n                }\n            },\n            \"annotation\": function(node, obj) {\n                obj.annotation = {};\n                this.readChildNodes(node, obj.annotation);\n            },\n            \"appinfo\": function(node, obj) {\n                if (!obj.appinfo) {\n                    obj.appinfo = [];\n                }\n                obj.appinfo.push(this.getChildValue(node));\n            },\n            \"documentation\": function(node, obj) {\n                if (!obj.documentation) {\n                    obj.documentation = [];\n                }\n                var value = this.getChildValue(node);\n                obj.documentation.push({\n                    lang: node.getAttribute(\"xml:lang\"),\n                    textContent: value.replace(this.regExes.trimSpace, \"\")\n                });\n            },\n            \"simpleType\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"restriction\": function(node, obj) {\n                obj.base = node.getAttribute(\"base\");\n                this.readRestriction(node, obj);\n            }\n        }\n    },\n    \n        readRestriction: function(node, obj) {\n        var children = node.childNodes;\n        var child, nodeName, value;\n        for(var i=0, len=children.length; i<len; ++i) {\n            child = children[i];\n            if(child.nodeType == 1) {\n                nodeName = child.nodeName.split(\":\").pop();\n                value = child.getAttribute(\"value\");\n                if(!obj[nodeName]) {\n                    obj[nodeName] = value;\n                } else {\n                    if(typeof obj[nodeName] == \"string\") {\n                        obj[nodeName] = [obj[nodeName]];\n                    }\n                    obj[nodeName].push(value);\n                }\n            }\n        }\n    },\n    \n        read: function(data) {\n        if(typeof data == \"string\") { \n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        if(data && data.nodeType == 9) {\n            data = data.documentElement;\n        }\n        var schema = {};\n        if (data.nodeName.split(\":\").pop() === 'ExceptionReport') {\n            var parser = new OpenLayers.Format.OGCExceptionReport();\n            schema.error = parser.read(data);\n        } else {\n            this.readNode(data, schema);\n        }\n        return schema;\n    },\n    \n    CLASS_NAME: \"OpenLayers.Format.WFSDescribeFeatureType\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WFST/v1.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WFST.v1 = OpenLayers.Class(OpenLayers.Format.XML, {\n    \n        namespaces: {\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\",\n        wfs: \"http://www.opengis.net/wfs\",\n        gml: \"http://www.opengis.net/gml\",\n        ogc: \"http://www.opengis.net/ogc\",\n        ows: \"http://www.opengis.net/ows\",\n        xmlns: \"http://www.w3.org/2000/xmlns/\"\n    },\n    \n        defaultPrefix: \"wfs\",\n\n        version: null,\n\n        schemaLocations: null,\n    \n        srsName: null,\n\n        extractAttributes: true,\n    \n        stateName: null,\n    \n        initialize: function(options) {\n        this.stateName = {};\n        this.stateName[OpenLayers.State.INSERT] = \"wfs:Insert\";\n        this.stateName[OpenLayers.State.UPDATE] = \"wfs:Update\";\n        this.stateName[OpenLayers.State.DELETE] = \"wfs:Delete\";\n        OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);\n    },\n    \n        getSrsName: function(feature, options) {\n        var srsName = options && options.srsName;\n        if(!srsName) {\n            if(feature && feature.layer) {\n                srsName = feature.layer.projection.getCode();\n            } else {\n                srsName = this.srsName;\n            }\n        }\n        return srsName;\n    },\n\n        read: function(data, options) {\n        options = options || {};\n        OpenLayers.Util.applyDefaults(options, {\n            output: \"features\"\n        });\n        \n        if(typeof data == \"string\") { \n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        if(data && data.nodeType == 9) {\n            data = data.documentElement;\n        }\n        var obj = {};\n        if(data) {\n            this.readNode(data, obj, true);\n        }\n        if(obj.features && options.output === \"features\") {\n            obj = obj.features;\n        }\n        return obj;\n    },\n    \n        readers: {\n        \"wfs\": {\n            \"FeatureCollection\": function(node, obj) {\n                obj.features = [];\n                this.readChildNodes(node, obj);\n            }\n        }\n    },\n    \n        write: function(features, options) {\n        var node = this.writeNode(\"wfs:Transaction\", {\n            features:features,\n            options: options\n        });\n        var value = this.schemaLocationAttr();\n        if(value) {\n            this.setAttributeNS(\n                node, this.namespaces[\"xsi\"], \"xsi:schemaLocation\",  value\n            );\n        }\n        return OpenLayers.Format.XML.prototype.write.apply(this, [node]);\n    },\n    \n        writers: {\n        \"wfs\": {\n            \"GetFeature\": function(options) {\n                var node = this.createElementNSPlus(\"wfs:GetFeature\", {\n                    attributes: {\n                        service: \"WFS\",\n                        version: this.version,\n                        handle: options && options.handle,\n                        outputFormat: options && options.outputFormat,\n                        maxFeatures: options && options.maxFeatures,\n                        viewParams: options && options.viewParams,\n                        \"xsi:schemaLocation\": this.schemaLocationAttr(options)\n                    }\n                });\n                if (typeof this.featureType == \"string\") {\n                    this.writeNode(\"Query\", options, node);\n                } else {\n                    for (var i=0,len = this.featureType.length; i<len; i++) { \n                        options.featureType = this.featureType[i]; \n                        this.writeNode(\"Query\", options, node); \n                    } \n                }\n                return node;\n            },\n            \"Transaction\": function(obj) {\n                obj = obj || {};\n                var options = obj.options || {};\n                var node = this.createElementNSPlus(\"wfs:Transaction\", {\n                    attributes: {\n                        service: \"WFS\",\n                        version: this.version,\n                        handle: options.handle\n                    }\n                });\n                var i, len;\n                var features = obj.features;\n                if(features) {\n                    if (options.multi === true) {\n                        OpenLayers.Util.extend(this.geometryTypes, {\n                            \"OpenLayers.Geometry.Point\": \"MultiPoint\",\n                            \"OpenLayers.Geometry.LineString\": (this.multiCurve === true) ? \"MultiCurve\": \"MultiLineString\",\n                            \"OpenLayers.Geometry.Polygon\": (this.multiSurface === true) ? \"MultiSurface\" : \"MultiPolygon\"\n                        });\n                    }\n                    var name, feature;\n                    for(i=0, len=features.length; i<len; ++i) {\n                        feature = features[i];\n                        name = this.stateName[feature.state];\n                        if(name) {\n                            this.writeNode(name, {\n                                feature: feature, \n                                options: options\n                            }, node);\n                        }\n                    }\n                    if (options.multi === true) {\n                        this.setGeometryTypes();\n                    }\n                }\n                if (options.nativeElements) {\n                    for (i=0, len=options.nativeElements.length; i<len; ++i) {\n                        this.writeNode(\"wfs:Native\", \n                            options.nativeElements[i], node);\n                    }\n                }\n                return node;\n            },\n            \"Native\": function(nativeElement) {\n                var node = this.createElementNSPlus(\"wfs:Native\", {\n                    attributes: {\n                        vendorId: nativeElement.vendorId,\n                        safeToIgnore: nativeElement.safeToIgnore\n                    },\n                    value: nativeElement.value\n                });\n                return node;\n            },\n            \"Insert\": function(obj) {\n                var feature = obj.feature;\n                var options = obj.options;\n                var node = this.createElementNSPlus(\"wfs:Insert\", {\n                    attributes: {\n                        handle: options && options.handle\n                    }\n                });\n                this.srsName = this.getSrsName(feature);\n                this.writeNode(\"feature:_typeName\", feature, node);\n                return node;\n            },\n            \"Update\": function(obj) {\n                var feature = obj.feature;\n                var options = obj.options;\n                var node = this.createElementNSPlus(\"wfs:Update\", {\n                    attributes: {\n                        handle: options && options.handle,\n                        typeName: (this.featureNS ? this.featurePrefix + \":\" : \"\") +\n                            this.featureType\n                    }\n                });\n                if(this.featureNS) {\n                    this.setAttributeNS(\n                        node, this.namespaces.xmlns,\n                        \"xmlns:\" + this.featurePrefix, this.featureNS\n                    );\n                }\n                var modified = feature.modified;\n                if (this.geometryName !== null && (!modified || modified.geometry !== undefined)) {\n                    this.srsName = this.getSrsName(feature);\n                    this.writeNode(\n                        \"Property\", {name: this.geometryName, value: feature.geometry}, node\n                    );\n                }\n                for(var key in feature.attributes) {\n                    if(feature.attributes[key] !== undefined &&\n                                (!modified || !modified.attributes ||\n                                (modified.attributes && (key in modified.attributes)))) {\n                        this.writeNode(\n                            \"Property\", {name: key, value: feature.attributes[key]}, node\n                        );\n                    }\n                }\n                this.writeNode(\"ogc:Filter\", new OpenLayers.Filter.FeatureId({\n                    fids: [feature.fid]\n                }), node);\n        \n                return node;\n            },\n            \"Property\": function(obj) {\n                var node = this.createElementNSPlus(\"wfs:Property\");\n                this.writeNode(\"Name\", obj.name, node);\n                if(obj.value !== null) {\n                    this.writeNode(\"Value\", obj.value, node);\n                }\n                return node;\n            },\n            \"Name\": function(name) {\n                return this.createElementNSPlus(\"wfs:Name\", {value: name});\n            },\n            \"Value\": function(obj) {\n                var node;\n                if(obj instanceof OpenLayers.Geometry) {\n                    node = this.createElementNSPlus(\"wfs:Value\");\n                    var geom = this.writeNode(\"feature:_geometry\", obj).firstChild;\n                    node.appendChild(geom);\n                } else {\n                    node = this.createElementNSPlus(\"wfs:Value\", {value: obj});                \n                }\n                return node;\n            },\n            \"Delete\": function(obj) {\n                var feature = obj.feature;\n                var options = obj.options;\n                var node = this.createElementNSPlus(\"wfs:Delete\", {\n                    attributes: {\n                        handle: options && options.handle,\n                        typeName: (this.featureNS ? this.featurePrefix + \":\" : \"\") +\n                            this.featureType\n                    }\n                });\n                if(this.featureNS) {\n                    this.setAttributeNS(\n                        node, this.namespaces.xmlns,\n                        \"xmlns:\" + this.featurePrefix, this.featureNS\n                    );\n                }\n                this.writeNode(\"ogc:Filter\", new OpenLayers.Filter.FeatureId({\n                    fids: [feature.fid]\n                }), node);\n                return node;\n            }\n        }\n    },\n\n        schemaLocationAttr: function(options) {\n        options = OpenLayers.Util.extend({\n            featurePrefix: this.featurePrefix,\n            schema: this.schema\n        }, options);\n        var schemaLocations = OpenLayers.Util.extend({}, this.schemaLocations);\n        if(options.schema) {\n            schemaLocations[options.featurePrefix] = options.schema;\n        }\n        var parts = [];\n        var uri;\n        for(var key in schemaLocations) {\n            uri = this.namespaces[key];\n            if(uri) {\n                parts.push(uri + \" \" + schemaLocations[key]);\n            }\n        }\n        var value = parts.join(\" \") || undefined;\n        return value;\n    },\n    \n        setFilterProperty: function(filter) {\n        if(filter.filters) {\n            for(var i=0, len=filter.filters.length; i<len; ++i) {\n                OpenLayers.Format.WFST.v1.prototype.setFilterProperty.call(this, filter.filters[i]);\n            }\n        } else {\n            if(filter instanceof OpenLayers.Filter.Spatial && !filter.property) {\n                filter.property = this.geometryName;\n            }\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WFST.v1\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WFST/v1_0_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WFST.v1_0_0 = OpenLayers.Class(\n    OpenLayers.Format.Filter.v1_0_0, OpenLayers.Format.WFST.v1, {\n    \n        version: \"1.0.0\",\n\n        srsNameInQuery: false,\n    \n        schemaLocations: {\n        \"wfs\": \"http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd\"\n    },\n\n        initialize: function(options) {\n        OpenLayers.Format.Filter.v1_0_0.prototype.initialize.apply(this, [options]);\n        OpenLayers.Format.WFST.v1.prototype.initialize.apply(this, [options]);\n    },\n    \n        readNode: function(node, obj, first) {\n        return OpenLayers.Format.GML.v2.prototype.readNode.apply(this, arguments);\n    },\n    \n        readers: {\n        \"wfs\": OpenLayers.Util.applyDefaults({\n            \"WFS_TransactionResponse\": function(node, obj) {\n                obj.insertIds = [];\n                obj.success = false;\n                this.readChildNodes(node, obj);\n            },\n            \"InsertResult\": function(node, container) {\n                var obj = {fids: []};\n                this.readChildNodes(node, obj);\n                container.insertIds = container.insertIds.concat(obj.fids);\n            },\n            \"TransactionResult\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"Status\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"SUCCESS\": function(node, obj) {\n                obj.success = true;\n            }\n        }, OpenLayers.Format.WFST.v1.prototype.readers[\"wfs\"]),\n        \"gml\": OpenLayers.Format.GML.v2.prototype.readers[\"gml\"],\n        \"feature\": OpenLayers.Format.GML.v2.prototype.readers[\"feature\"],\n        \"ogc\": OpenLayers.Format.Filter.v1_0_0.prototype.readers[\"ogc\"]\n    },\n\n        writers: {\n        \"wfs\": OpenLayers.Util.applyDefaults({\n            \"Query\": function(options) {\n                options = OpenLayers.Util.extend({\n                    featureNS: this.featureNS,\n                    featurePrefix: this.featurePrefix,\n                    featureType: this.featureType,\n                    srsName: this.srsName,\n                    srsNameInQuery: this.srsNameInQuery\n                }, options);\n                var prefix = options.featurePrefix;\n                var node = this.createElementNSPlus(\"wfs:Query\", {\n                    attributes: {\n                        typeName: (prefix ? prefix + \":\" : \"\") +\n                            options.featureType\n                    }\n                });\n                if(options.srsNameInQuery && options.srsName) {\n                    node.setAttribute(\"srsName\", options.srsName);\n                }\n                if(options.featureNS) {\n                    this.setAttributeNS(\n                        node, this.namespaces.xmlns,\n                        \"xmlns:\" + prefix, options.featureNS\n                    );\n                }\n                if(options.propertyNames) {\n                    for(var i=0,len = options.propertyNames.length; i<len; i++) {\n                        this.writeNode(\n                            \"ogc:PropertyName\", \n                            {property: options.propertyNames[i]},\n                            node\n                        );\n                    }\n                }\n                if(options.filter) {\n                    this.setFilterProperty(options.filter);\n                    this.writeNode(\"ogc:Filter\", options.filter, node);\n                }\n                return node;\n            }\n        }, OpenLayers.Format.WFST.v1.prototype.writers[\"wfs\"]),\n        \"gml\": OpenLayers.Format.GML.v2.prototype.writers[\"gml\"],\n        \"feature\": OpenLayers.Format.GML.v2.prototype.writers[\"feature\"],\n        \"ogc\": OpenLayers.Format.Filter.v1_0_0.prototype.writers[\"ogc\"]\n    },\n   \n    CLASS_NAME: \"OpenLayers.Format.WFST.v1_0_0\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WFST/v1_1_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WFST.v1_1_0 = OpenLayers.Class(\n    OpenLayers.Format.Filter.v1_1_0, OpenLayers.Format.WFST.v1, {\n    \n        version: \"1.1.0\",\n    \n        schemaLocations: {\n        \"wfs\": \"http://schemas.opengis.net/wfs/1.1.0/wfs.xsd\"\n    },\n    \n        initialize: function(options) {\n        OpenLayers.Format.Filter.v1_1_0.prototype.initialize.apply(this, [options]);\n        OpenLayers.Format.WFST.v1.prototype.initialize.apply(this, [options]);\n    },\n    \n        readNode: function(node, obj, first) {\n        return OpenLayers.Format.GML.v3.prototype.readNode.apply(this, arguments);\n    },\n    \n        readers: {\n        \"wfs\": OpenLayers.Util.applyDefaults({\n            \"FeatureCollection\": function(node, obj) {\n                obj.numberOfFeatures = parseInt(node.getAttribute(\n                    \"numberOfFeatures\"));\n                OpenLayers.Format.WFST.v1.prototype.readers[\"wfs\"][\"FeatureCollection\"].apply(\n                    this, arguments);\n            },\n            \"TransactionResponse\": function(node, obj) {\n                obj.insertIds = [];\n                obj.success = false;\n                this.readChildNodes(node, obj);\n            },\n            \"TransactionSummary\": function(node, obj) {\n                obj.success = true;\n            },\n            \"InsertResults\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"Feature\": function(node, container) {\n                var obj = {fids: []};\n                this.readChildNodes(node, obj);\n                container.insertIds.push(obj.fids[0]);\n            }\n        }, OpenLayers.Format.WFST.v1.prototype.readers[\"wfs\"]),\n        \"gml\": OpenLayers.Format.GML.v3.prototype.readers[\"gml\"],\n        \"feature\": OpenLayers.Format.GML.v3.prototype.readers[\"feature\"],\n        \"ogc\": OpenLayers.Format.Filter.v1_1_0.prototype.readers[\"ogc\"],\n        \"ows\": OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers[\"ows\"]\n    },\n\n        writers: {\n        \"wfs\": OpenLayers.Util.applyDefaults({\n            \"GetFeature\": function(options) {\n                var node = OpenLayers.Format.WFST.v1.prototype.writers[\"wfs\"][\"GetFeature\"].apply(this, arguments);\n                options && this.setAttributes(node, {\n                    resultType: options.resultType,\n                    startIndex: options.startIndex,\n                    count: options.count\n                });\n                return node;\n            },\n            \"Query\": function(options) {\n                options = OpenLayers.Util.extend({\n                    featureNS: this.featureNS,\n                    featurePrefix: this.featurePrefix,\n                    featureType: this.featureType,\n                    srsName: this.srsName\n                }, options);\n                var prefix = options.featurePrefix;\n                var node = this.createElementNSPlus(\"wfs:Query\", {\n                    attributes: {\n                        typeName: (prefix ? prefix + \":\" : \"\") +\n                            options.featureType,\n                        srsName: options.srsName\n                    }\n                });\n                if(options.featureNS) {\n                    this.setAttributeNS(node, this.namespaces.xmlns,\n                        \"xmlns:\" + prefix, options.featureNS);\n                }\n                if(options.propertyNames) {\n                    for(var i=0,len = options.propertyNames.length; i<len; i++) {\n                        this.writeNode(\n                            \"wfs:PropertyName\", \n                            {property: options.propertyNames[i]},\n                            node\n                        );\n                    }\n                }\n                if(options.filter) {\n                    OpenLayers.Format.WFST.v1_1_0.prototype.setFilterProperty.call(this, options.filter);\n                    this.writeNode(\"ogc:Filter\", options.filter, node);\n                }\n                return node;\n            },\n            \"PropertyName\": function(obj) {\n                return this.createElementNSPlus(\"wfs:PropertyName\", {\n                    value: obj.property\n                });\n            }            \n        }, OpenLayers.Format.WFST.v1.prototype.writers[\"wfs\"]),\n        \"gml\": OpenLayers.Format.GML.v3.prototype.writers[\"gml\"],\n        \"feature\": OpenLayers.Format.GML.v3.prototype.writers[\"feature\"],\n        \"ogc\": OpenLayers.Format.Filter.v1_1_0.prototype.writers[\"ogc\"]\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WFST.v1_1_0\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WFST/v2_0_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WFST.v2_0_0 = OpenLayers.Class(\n    OpenLayers.Format.Filter.v2_0_0, OpenLayers.Format.WFST.v1, {\n    \n        namespaces: {\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\",\n        wfs: \"http://www.opengis.net/wfs/2.0\",\n        gml: \"http://www.opengis.net/gml/3.2\",\n        fes: \"http://www.opengis.net/fes/2.0\",\n        xmlns: \"http://www.w3.org/2000/xmlns/\"\n    },\n        \n        version: \"2.0.0\",\n    \n        schemaLocations: {\n        \"wfs\": \"http://schemas.opengis.net/wfs/2.0/wfs.xsd\"\n    },\n\n        initialize: function(options) {\n        OpenLayers.Format.Filter.v2_0_0.prototype.initialize.apply(this, [options]);\n        OpenLayers.Format.WFST.v1.prototype.initialize.apply(this, [options]);\n    },\n    \n        readNode: function(node, obj, first) {\n        return OpenLayers.Format.GML.v3.prototype.readNode.apply(this, arguments);\n    },\n    \n        readers: {\n        \"wfs\": OpenLayers.Util.applyDefaults({\n            \"FeatureCollection\": function(node, obj) {\n                obj.numberReturned = parseInt(node.getAttribute(\n                    \"numberReturned\"));\n                obj.numberMatched = parseInt(node.getAttribute(\n                \"numberMatched\"));\n                OpenLayers.Format.WFST.v1.prototype.readers[\"wfs\"][\"FeatureCollection\"].apply(\n                    this, arguments);\n            },\n            \"TransactionResponse\": function(node, obj) {\n                obj.insertIds = [];\n                obj.success = false;\n                this.readChildNodes(node, obj);\n            },\n            \"TransactionSummary\": function(node, obj) {\n                obj.success = true;\n            },\n            \"InsertResults\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"Feature\": function(node, container) {\n                var obj = {fids: []};\n                this.readChildNodes(node, obj);\n                container.insertIds.push(obj.fids[0]);\n            },\n            \"member\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"boundedBy\": function(node, obj) {\n                var container = {};\n                this.readChildNodes(node, container);\n                if(container.components && container.components.length > 0) {\n                    obj.bounds = container.components[0];\n                }\n            }\n\n        }, OpenLayers.Format.WFST.v1.prototype.readers[\"wfs\"]),\n        \"gml\": OpenLayers.Format.GML.v3.prototype.readers[\"gml\"],\n        \"feature\": OpenLayers.Format.GML.v3.prototype.readers[\"feature\"],\n        \"ows\": OpenLayers.Format.OWSCommon.v1_0_0.prototype.readers[\"ows\"],\n        \"fes\": OpenLayers.Format.Filter.v2_0_0.prototype.readers[\"fes\"]\n    },\n\n        writers: {\n        \"wfs\": OpenLayers.Util.applyDefaults({\n        \t\"GetFeature\": function(options) {\n                var node = OpenLayers.Format.WFST.v1.prototype.writers[\"wfs\"][\"GetFeature\"].apply(this, arguments);\n                options && this.setAttributes(node, {\n                    resultType: options.resultType,\n                    startIndex: options.startIndex,\n                    count: options.count\n                });\n                return node;\n            },\n            \"Query\": function(options) {\n                options = OpenLayers.Util.extend({\n                    featureNS: this.featureNS,\n                    featurePrefix: this.featurePrefix,\n                    featureType: this.featureType,\n                    srsName: this.srsName\n                }, options);\n                var prefix = options.featurePrefix;\n                var node = this.createElementNSPlus(\"wfs:Query\", {\n                    attributes: {\n                        typeNames: (prefix ? prefix + \":\" : \"\") +\n                            options.featureType,\n                        srsName: options.srsName\n                    }\n                });\n                if(options.featureNS) {\n                    this.setAttributeNS(\n                        node, this.namespaces.xmlns,\n                        \"xmlns:\" + prefix, options.featureNS\n                    );\n                }\n                if(options.propertyNames) {\n                    for(var i=0,len = options.propertyNames.length; i<len; i++) {\n                        this.writeNode(\n                            \"wfs:PropertyName\", \n                            {property: options.propertyNames[i]},\n                            node\n                        );\n                    }\n                }\n                if(options.filter) {\n                    this.setFilterProperty(options.filter);\n                    this.writeNode(\"fes:Filter\", options.filter, node);\n                }\n                return node;\n            },\n            \"Update\": function(obj) {\n                var feature = obj.feature;\n                var options = obj.options;\n                var node = this.createElementNSPlus(\"wfs:Update\", {\n                    attributes: {\n                        handle: options && options.handle,\n                        typeName: (this.featureNS ? this.featurePrefix + \":\" : \"\") +\n                            this.featureType\n                    }\n                });\n                if(this.featureNS) {\n                    this.setAttributeNS(\n                        node, this.namespaces.xmlns,\n                        \"xmlns:\" + this.featurePrefix, this.featureNS\n                    );\n                }\n                var modified = feature.modified;\n                if (this.geometryName !== null && (!modified || modified.geometry !== undefined)) {\n                    this.srsName = this.getSrsName(feature);\n                    this.writeNode(\n                        \"Property\", {name: this.geometryName, value: feature.geometry}, node\n                    );\n                }\n                for(var key in feature.attributes) {\n                    if(feature.attributes[key] !== undefined &&\n                                (!modified || !modified.attributes ||\n                                (modified.attributes && (key in modified.attributes)))) {\n                        this.writeNode(\n                            \"Property\", {name: key, value: feature.attributes[key]}, node\n                        );\n                    }\n                }\n                this.writeNode(\"fes:Filter\", new OpenLayers.Filter.FeatureId({\n                    fids: [feature.fid]\n                }), node);\n        \n                return node;\n            },\n            \"Property\": function(obj) {\n                var node = this.createElementNSPlus(\"wfs:Property\");\n                this.writeNode(\"ValueReference\", obj.name, node);\n                if(obj.value !== null) {\n                    this.writeNode(\"Value\", obj.value, node);\n                }\n                return node;\n            },\n            \"PropertyName\": function(obj) {\n                return this.createElementNSPlus(\"wfs:PropertyName\", {\n                    value: obj.property\n                });\n            },\n            \"ValueReference\": function(name) {\n                return this.createElementNSPlus(\"wfs:ValueReference\", {value: name});\n            },\n            \"Delete\": function(obj) {\n                var feature = obj.feature;\n                var options = obj.options;\n                var node = this.createElementNSPlus(\"wfs:Delete\", {\n                    attributes: {\n                        handle: options && options.handle,\n                        typeName: (this.featureNS ? this.featurePrefix + \":\" : \"\") +\n                            this.featureType\n                    }\n                });\n                if(this.featureNS) {\n                    this.setAttributeNS(\n                        node, this.namespaces.xmlns,\n                        \"xmlns:\" + this.featurePrefix, this.featureNS\n                    );\n                }\n                this.writeNode(\"fes:Filter\", new OpenLayers.Filter.FeatureId({\n                    fids: [feature.fid]\n                }), node);\n                return node;\n            }\n        }, OpenLayers.Format.WFST.v1.prototype.writers[\"wfs\"]),\n        \"gml\": OpenLayers.Format.GML.v3.prototype.writers[\"gml\"],\n        \"feature\": OpenLayers.Format.GML.v3.prototype.writers[\"feature\"],\n        \"fes\": OpenLayers.Format.Filter.v2_0_0.prototype.writers[\"fes\"]\n    },\n   \n    CLASS_NAME: \"OpenLayers.Format.WFST.v2_0_0\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WFST.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WFST = function(options) {\n    options = OpenLayers.Util.applyDefaults(\n        options, OpenLayers.Format.WFST.DEFAULTS\n    );\n    var cls = OpenLayers.Format.WFST[\"v\"+options.version.replace(/\\./g, \"_\")];\n    if(!cls) {\n        throw \"Unsupported WFST version: \" + options.version;\n    }\n    return new cls(options);\n};\n\nOpenLayers.Format.WFST.DEFAULTS = {\n    \"version\": \"1.0.0\"\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WKT.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WKT = OpenLayers.Class(OpenLayers.Format, {\n    \n        initialize: function(options) {\n        this.regExes = {\n            'typeStr': /^\\s*(\\w+)\\s*\\(\\s*(.*)\\s*\\)\\s*$/,\n            'spaces': /\\s+/,\n            'parenComma': /\\)\\s*,\\s*\\(/,\n            'doubleParenComma': /\\)\\s*\\)\\s*,\\s*\\(\\s*\\(/,  // can't use {2} here\n            'trimParens': /^\\s*\\(?(.*?)\\)?\\s*$/\n        };\n        OpenLayers.Format.prototype.initialize.apply(this, [options]);\n    },\n\n        read: function(wkt) {\n        var features, type, str;\n        wkt = wkt.replace(/[\\n\\r]/g, \" \");\n        var matches = this.regExes.typeStr.exec(wkt);\n        if(matches) {\n            type = matches[1].toLowerCase();\n            str = matches[2];\n            if(this.parse[type]) {\n                features = this.parse[type].apply(this, [str]);\n            }\n            if (this.internalProjection && this.externalProjection) {\n                if (features && \n                    features.CLASS_NAME == \"OpenLayers.Feature.Vector\") {\n                    features.geometry.transform(this.externalProjection,\n                                                this.internalProjection);\n                } else if (features &&\n                           type != \"geometrycollection\" &&\n                           typeof features == \"object\") {\n                    for (var i=0, len=features.length; i<len; i++) {\n                        var component = features[i];\n                        component.geometry.transform(this.externalProjection,\n                                                     this.internalProjection);\n                    }\n                }\n            }\n        }    \n        return features;\n    },\n\n        write: function(features) {\n        var collection, geometry, isCollection;\n        if (features.constructor == Array) {\n            collection = features;\n            isCollection = true;\n        } else {\n            collection = [features];\n            isCollection = false;\n        }\n        var pieces = [];\n        if (isCollection) {\n            pieces.push('GEOMETRYCOLLECTION(');\n        }\n        for (var i=0, len=collection.length; i<len; ++i) {\n            if (isCollection && i>0) {\n                pieces.push(',');\n            }\n            geometry = collection[i].geometry;\n            pieces.push(this.extractGeometry(geometry));\n        }\n        if (isCollection) {\n            pieces.push(')');\n        }\n        return pieces.join('');\n    },\n\n        extractGeometry: function(geometry) {\n        var type = geometry.CLASS_NAME.split('.')[2].toLowerCase();\n        if (!this.extract[type]) {\n            return null;\n        }\n        if (this.internalProjection && this.externalProjection) {\n            geometry = geometry.clone();\n            geometry.transform(this.internalProjection, this.externalProjection);\n        }                       \n        var wktType = type == 'collection' ? 'GEOMETRYCOLLECTION' : type.toUpperCase();\n        var data = wktType + '(' + this.extract[type].apply(this, [geometry]) + ')';\n        return data;\n    },\n    \n        extract: {\n                'point': function(point) {\n            return point.x + ' ' + point.y;\n        },\n\n                'multipoint': function(multipoint) {\n            var array = [];\n            for(var i=0, len=multipoint.components.length; i<len; ++i) {\n                array.push('(' +\n                           this.extract.point.apply(this, [multipoint.components[i]]) +\n                           ')');\n            }\n            return array.join(',');\n        },\n        \n                'linestring': function(linestring) {\n            var array = [];\n            for(var i=0, len=linestring.components.length; i<len; ++i) {\n                array.push(this.extract.point.apply(this, [linestring.components[i]]));\n            }\n            return array.join(',');\n        },\n\n                'multilinestring': function(multilinestring) {\n            var array = [];\n            for(var i=0, len=multilinestring.components.length; i<len; ++i) {\n                array.push('(' +\n                           this.extract.linestring.apply(this, [multilinestring.components[i]]) +\n                           ')');\n            }\n            return array.join(',');\n        },\n        \n                'polygon': function(polygon) {\n            var array = [];\n            for(var i=0, len=polygon.components.length; i<len; ++i) {\n                array.push('(' +\n                           this.extract.linestring.apply(this, [polygon.components[i]]) +\n                           ')');\n            }\n            return array.join(',');\n        },\n\n                'multipolygon': function(multipolygon) {\n            var array = [];\n            for(var i=0, len=multipolygon.components.length; i<len; ++i) {\n                array.push('(' +\n                           this.extract.polygon.apply(this, [multipolygon.components[i]]) +\n                           ')');\n            }\n            return array.join(',');\n        },\n\n                'collection': function(collection) {\n            var array = [];\n            for(var i=0, len=collection.components.length; i<len; ++i) {\n                array.push(this.extractGeometry.apply(this, [collection.components[i]]));\n            }\n            return array.join(',');\n        }\n\n    },\n\n        parse: {\n                'point': function(str) {\n            var coords = OpenLayers.String.trim(str).split(this.regExes.spaces);\n            return new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.Point(coords[0], coords[1])\n            );\n        },\n\n                'multipoint': function(str) {\n            var point;\n            var points = OpenLayers.String.trim(str).split(',');\n            var components = [];\n            for(var i=0, len=points.length; i<len; ++i) {\n                point = points[i].replace(this.regExes.trimParens, '$1');\n                components.push(this.parse.point.apply(this, [point]).geometry);\n            }\n            return new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.MultiPoint(components)\n            );\n        },\n        \n                'linestring': function(str) {\n            var points = OpenLayers.String.trim(str).split(',');\n            var components = [];\n            for(var i=0, len=points.length; i<len; ++i) {\n                components.push(this.parse.point.apply(this, [points[i]]).geometry);\n            }\n            return new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.LineString(components)\n            );\n        },\n\n                'multilinestring': function(str) {\n            var line;\n            var lines = OpenLayers.String.trim(str).split(this.regExes.parenComma);\n            var components = [];\n            for(var i=0, len=lines.length; i<len; ++i) {\n                line = lines[i].replace(this.regExes.trimParens, '$1');\n                components.push(this.parse.linestring.apply(this, [line]).geometry);\n            }\n            return new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.MultiLineString(components)\n            );\n        },\n        \n                'polygon': function(str) {\n            var ring, linestring, linearring;\n            var rings = OpenLayers.String.trim(str).split(this.regExes.parenComma);\n            var components = [];\n            for(var i=0, len=rings.length; i<len; ++i) {\n                ring = rings[i].replace(this.regExes.trimParens, '$1');\n                linestring = this.parse.linestring.apply(this, [ring]).geometry;\n                linearring = new OpenLayers.Geometry.LinearRing(linestring.components);\n                components.push(linearring);\n            }\n            return new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.Polygon(components)\n            );\n        },\n\n                'multipolygon': function(str) {\n            var polygon;\n            var polygons = OpenLayers.String.trim(str).split(this.regExes.doubleParenComma);\n            var components = [];\n            for(var i=0, len=polygons.length; i<len; ++i) {\n                polygon = polygons[i].replace(this.regExes.trimParens, '$1');\n                components.push(this.parse.polygon.apply(this, [polygon]).geometry);\n            }\n            return new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.MultiPolygon(components)\n            );\n        },\n\n                'geometrycollection': function(str) {\n            str = str.replace(/,\\s*([A-Za-z])/g, '|$1');\n            var wktArray = OpenLayers.String.trim(str).split('|');\n            var components = [];\n            for(var i=0, len=wktArray.length; i<len; ++i) {\n                components.push(OpenLayers.Format.WKT.prototype.read.apply(this,[wktArray[i]]));\n            }\n            return components;\n        }\n\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WKT\" \n});     \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WMC/v1.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WMC.v1 = OpenLayers.Class(OpenLayers.Format.XML, {\n    \n        namespaces: {\n        ol: \"http://openlayers.org/context\",\n        wmc: \"http://www.opengis.net/context\",\n        sld: \"http://www.opengis.net/sld\",\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\"\n    },\n    \n        schemaLocation: \"\",\n\n        getNamespacePrefix: function(uri) {\n        var prefix = null;\n        if(uri == null) {\n            prefix = this.namespaces[this.defaultPrefix];\n        } else {\n            for(prefix in this.namespaces) {\n                if(this.namespaces[prefix] == uri) {\n                    break;\n                }\n            }\n        }\n        return prefix;\n    },\n    \n        defaultPrefix: \"wmc\",\n\n        rootPrefix: null,\n    \n        defaultStyleName: \"\",\n    \n        defaultStyleTitle: \"Default\",\n    \n        initialize: function(options) {\n        OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);\n    },\n\n        read: function(data) {\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        var root = data.documentElement;\n        this.rootPrefix = root.prefix;\n        var context = {\n            version: root.getAttribute(\"version\")\n        };\n        this.runChildNodes(context, root);\n        return context;\n    },\n    \n        runChildNodes: function(obj, node) {\n        var children = node.childNodes;\n        var childNode, processor, prefix, local;\n        for(var i=0, len=children.length; i<len; ++i) {\n            childNode = children[i];\n            if(childNode.nodeType == 1) {\n                prefix = this.getNamespacePrefix(childNode.namespaceURI);\n                local = childNode.nodeName.split(\":\").pop();\n                processor = this[\"read_\" + prefix + \"_\" + local];\n                if(processor) {\n                    processor.apply(this, [obj, childNode]);\n                }\n            }\n        }\n    },\n    \n        read_wmc_General: function(context, node) {\n        this.runChildNodes(context, node);\n    },\n    \n        read_wmc_BoundingBox: function(context, node) {\n        context.projection = node.getAttribute(\"SRS\");\n        context.bounds = new OpenLayers.Bounds(\n            node.getAttribute(\"minx\"), node.getAttribute(\"miny\"),\n            node.getAttribute(\"maxx\"), node.getAttribute(\"maxy\")\n        );\n    },\n    \n        read_wmc_LayerList: function(context, node) {\n        context.layersContext = [];\n        this.runChildNodes(context, node);\n    },\n    \n        read_wmc_Layer: function(context, node) {\n        var layerContext = {\n            visibility: (node.getAttribute(\"hidden\") != \"1\"),\n            queryable: (node.getAttribute(\"queryable\") == \"1\"),\n            formats: [],\n             styles: [],\n             metadata: {}\n        };\n\n        this.runChildNodes(layerContext, node);\n        context.layersContext.push(layerContext);\n    },\n    \n        read_wmc_Extension: function(obj, node) {\n        this.runChildNodes(obj, node);\n    },\n\n        read_ol_units: function(layerContext, node) {\n        layerContext.units = this.getChildValue(node);\n    },\n    \n        read_ol_maxExtent: function(obj, node) {\n        var bounds = new OpenLayers.Bounds(\n            node.getAttribute(\"minx\"), node.getAttribute(\"miny\"),\n            node.getAttribute(\"maxx\"), node.getAttribute(\"maxy\")\n        );\n        obj.maxExtent = bounds;\n    },\n    \n        read_ol_transparent: function(layerContext, node) {\n        layerContext.transparent = this.getChildValue(node);\n    },\n\n        read_ol_numZoomLevels: function(layerContext, node) {\n        layerContext.numZoomLevels = parseInt(this.getChildValue(node));\n    },\n\n        read_ol_opacity: function(layerContext, node) {\n        layerContext.opacity = parseFloat(this.getChildValue(node));\n    },\n\n        read_ol_singleTile: function(layerContext, node) {\n        layerContext.singleTile = (this.getChildValue(node) == \"true\");\n    },\n\n        read_ol_tileSize: function(layerContext, node) {\n        var obj = {\"width\": node.getAttribute(\"width\"), \"height\": node.getAttribute(\"height\")};\n        layerContext.tileSize = obj;\n    },\n\n        read_ol_gutter: function(layerContext, node) {\n        layerContext.gutter = parseInt(this.getChildValue(node));\n    },\n\n        read_ol_isBaseLayer: function(layerContext, node) {\n        layerContext.isBaseLayer = (this.getChildValue(node) == \"true\");\n    },\n\n        read_ol_displayInLayerSwitcher: function(layerContext, node) {\n        layerContext.displayInLayerSwitcher = (this.getChildValue(node) == \"true\");\n    },\n\n        read_ol_attribution: function(obj, node) {\n        obj.attribution = {};\n        this.runChildNodes(obj.attribution, node);\n    },\n\n        read_wmc_Server: function(layerContext, node) {\n        layerContext.version = node.getAttribute(\"version\");\n         layerContext.url = this.getOnlineResource_href(node);\n         layerContext.metadata.servertitle = node.getAttribute(\"title\");\n    },\n\n        read_wmc_FormatList: function(layerContext, node) {\n        this.runChildNodes(layerContext, node);\n    },\n\n        read_wmc_Format: function(layerContext, node) {\n        var format = {\n            value: this.getChildValue(node)\n        };\n        if(node.getAttribute(\"current\") == \"1\") {\n            format.current = true;\n        }\n        layerContext.formats.push(format);\n    },\n    \n        read_wmc_StyleList: function(layerContext, node) {\n        this.runChildNodes(layerContext, node);\n    },\n\n        read_wmc_Style: function(layerContext, node) {\n        var style = {};\n        this.runChildNodes(style, node);\n        if(node.getAttribute(\"current\") == \"1\") {\n            style.current = true;\n        }\n        layerContext.styles.push(style);\n    },\n    \n        read_wmc_SLD: function(style, node) {\n        this.runChildNodes(style, node);\n    },\n    \n        read_sld_StyledLayerDescriptor: function(sld, node) {\n        var xml = OpenLayers.Format.XML.prototype.write.apply(this, [node]);\n        sld.body = xml;\n    },\n\n         read_sld_FeatureTypeStyle: function(sld, node) {\n         var xml = OpenLayers.Format.XML.prototype.write.apply(this, [node]);\n         sld.body = xml;\n     },\n\n         read_wmc_OnlineResource: function(obj, node) {\n        obj.href = this.getAttributeNS(\n            node, this.namespaces.xlink, \"href\"\n        );\n    },\n    \n        read_wmc_Name: function(obj, node) {\n        var name = this.getChildValue(node);\n        if(name) {\n            obj.name = name;\n        }\n    },\n\n        read_wmc_Title: function(obj, node) {\n        var title = this.getChildValue(node);\n        if(title) {\n            obj.title = title;\n        }\n    },\n\n        read_wmc_MetadataURL: function(layerContext, node) {\n         layerContext.metadataURL = this.getOnlineResource_href(node);\n     },\n\n          read_wmc_KeywordList: function(context, node) {\n         context.keywords = [];\n         this.runChildNodes(context.keywords, node);\n    },\n\n         read_wmc_Keyword: function(keywords, node) {\n         keywords.push(this.getChildValue(node));\n     },\n\n         read_wmc_Abstract: function(obj, node) {\n        var abst = this.getChildValue(node);\n        if(abst) {\n            obj[\"abstract\"] = abst;\n        }\n    },\n    \n         read_wmc_LogoURL: function(context, node) {\n         context.logo = {\n             width:  node.getAttribute(\"width\"),\n             height: node.getAttribute(\"height\"),\n             format: node.getAttribute(\"format\"),\n             href:   this.getOnlineResource_href(node)\n         };\n     },\n\n          read_wmc_DescriptionURL: function(context, node) {\n         context.descriptionURL = this.getOnlineResource_href(node);\n     },\n\n          read_wmc_ContactInformation: function(obj, node) {\n         var contact = {};\n         this.runChildNodes(contact, node);\n         obj.contactInformation = contact;\n     },\n\n          read_wmc_ContactPersonPrimary: function(contact, node) {\n         var personPrimary = {};\n         this.runChildNodes(personPrimary, node);\n         contact.personPrimary = personPrimary;\n     },\n\n          read_wmc_ContactPerson: function(primaryPerson, node) {\n         var person = this.getChildValue(node);\n         if (person) {\n             primaryPerson.person = person;\n         }\n     },\n\n          read_wmc_ContactOrganization: function(primaryPerson, node) {\n         var organization = this.getChildValue(node);\n         if (organization) {\n             primaryPerson.organization = organization;\n         }\n     },\n\n          read_wmc_ContactPosition: function(contact, node) {\n         var position = this.getChildValue(node);\n         if (position) {\n             contact.position = position;\n         }\n     },\n\n          read_wmc_ContactAddress: function(contact, node) {\n         var contactAddress = {};\n         this.runChildNodes(contactAddress, node);\n         contact.contactAddress = contactAddress;\n     },\n\n          read_wmc_AddressType: function(contactAddress, node) {\n         var type = this.getChildValue(node);\n         if (type) {\n             contactAddress.type = type;\n         }\n     },\n\n          read_wmc_Address: function(contactAddress, node) {\n         var address = this.getChildValue(node);\n         if (address) {\n             contactAddress.address = address;\n         }\n     },\n\n          read_wmc_City: function(contactAddress, node) {\n         var city = this.getChildValue(node);\n         if (city) {\n             contactAddress.city = city;\n         }\n     },\n\n          read_wmc_StateOrProvince: function(contactAddress, node) {\n         var stateOrProvince = this.getChildValue(node);\n         if (stateOrProvince) {\n             contactAddress.stateOrProvince = stateOrProvince;\n         }\n     },\n\n          read_wmc_PostCode: function(contactAddress, node) {\n         var postcode = this.getChildValue(node);\n         if (postcode) {\n             contactAddress.postcode = postcode;\n         }\n     },\n\n          read_wmc_Country: function(contactAddress, node) {\n         var country = this.getChildValue(node);\n         if (country) {\n             contactAddress.country = country;\n         }\n     },\n\n          read_wmc_ContactVoiceTelephone: function(contact, node) {\n         var phone = this.getChildValue(node);\n         if (phone) {\n             contact.phone = phone;\n         }\n     },\n\n          read_wmc_ContactFacsimileTelephone: function(contact, node) {\n         var fax = this.getChildValue(node);\n         if (fax) {\n             contact.fax = fax;\n         }\n     },\n\n          read_wmc_ContactElectronicMailAddress: function(contact, node) {\n         var email = this.getChildValue(node);\n         if (email) {\n             contact.email = email;\n         }\n     },\n\n          read_wmc_DataURL: function(layerContext, node) {\n         layerContext.dataURL = this.getOnlineResource_href(node);\n     },\n\n         read_wmc_LegendURL: function(style, node) {\n        var legend = {\n            width: node.getAttribute('width'),\n             height: node.getAttribute('height'),\n             format: node.getAttribute('format'),\n             href:   this.getOnlineResource_href(node)\n        };\n        style.legend = legend;\n    },\n    \n         read_wmc_DimensionList: function(layerContext, node) {\n         layerContext.dimensions = {};\n         this.runChildNodes(layerContext.dimensions, node);\n     },\n          read_wmc_Dimension: function(dimensions, node) {\n         var name = node.getAttribute(\"name\").toLowerCase();\n\n         var dim = {\n             name:           name,\n             units:          node.getAttribute(\"units\")          ||  \"\",\n             unitSymbol:     node.getAttribute(\"unitSymbol\")     ||  \"\",\n             userValue:      node.getAttribute(\"userValue\")      ||  \"\",\n             nearestValue:   node.getAttribute(\"nearestValue\")   === \"1\",\n             multipleValues: node.getAttribute(\"multipleValues\") === \"1\",\n             current:        node.getAttribute(\"current\")        === \"1\",\n             \"default\":      node.getAttribute(\"default\")        ||  \"\"\n         };\n         var values = this.getChildValue(node);\n         dim.values = values.split(\",\");\n\n         dimensions[dim.name] = dim;\n     },\n\n         write: function(context, options) {\n        var root = this.createElementDefaultNS(\"ViewContext\");\n        this.setAttributes(root, {\n            version: this.VERSION,\n            id: (options && typeof options.id == \"string\") ?\n                    options.id :\n                    OpenLayers.Util.createUniqueID(\"OpenLayers_Context_\")\n        });\n        this.setAttributeNS(\n            root, this.namespaces.xsi,\n            \"xsi:schemaLocation\", this.schemaLocation\n        );\n        root.appendChild(this.write_wmc_General(context));\n        root.appendChild(this.write_wmc_LayerList(context));\n\n        return OpenLayers.Format.XML.prototype.write.apply(this, [root]);\n    },\n    \n        createElementDefaultNS: function(name, childValue, attributes) {\n        var node = this.createElementNS(\n            this.namespaces[this.defaultPrefix],\n            name\n        );\n        if(childValue) {\n            node.appendChild(this.createTextNode(childValue));\n        }\n        if(attributes) {\n            this.setAttributes(node, attributes);\n        }\n        return node;\n    },\n    \n        setAttributes: function(node, obj) {\n        var value;\n        for(var name in obj) {\n            value = obj[name].toString();\n            if(value.match(/[A-Z]/)) {\n                this.setAttributeNS(node, null, name, value);\n            } else {\n                node.setAttribute(name, value);\n            }\n        }\n    },\n\n        write_wmc_General: function(context) {\n        var node = this.createElementDefaultNS(\"General\");\n        if(context.size) {\n            node.appendChild(this.createElementDefaultNS(\n                \"Window\", null,\n                {\n                    width: context.size.w,\n                    height: context.size.h\n                }\n            ));\n        }\n        var bounds = context.bounds;\n        node.appendChild(this.createElementDefaultNS(\n            \"BoundingBox\", null,\n            {\n                minx: bounds.left.toPrecision(18),\n                miny: bounds.bottom.toPrecision(18),\n                maxx: bounds.right.toPrecision(18),\n                maxy: bounds.top.toPrecision(18),\n                SRS: context.projection\n            }\n        ));\n        node.appendChild(this.createElementDefaultNS(\n            \"Title\", context.title\n        ));\n         if (context.keywords) {\n             node.appendChild(this.write_wmc_KeywordList(context.keywords));\n         }\n         if (context[\"abstract\"]) {\n             node.appendChild(this.createElementDefaultNS(\n                 \"Abstract\", context[\"abstract\"]\n             ));\n         }\n         if (context.logo) {\n             node.appendChild(this.write_wmc_URLType(\"LogoURL\", context.logo.href, context.logo));\n         }\n         if (context.descriptionURL) {\n             node.appendChild(this.write_wmc_URLType(\"DescriptionURL\", context.descriptionURL));\n         }\n         if (context.contactInformation) {\n             node.appendChild(this.write_wmc_ContactInformation(context.contactInformation));\n         }\n        node.appendChild(this.write_ol_MapExtension(context));\n        \n        return node;\n    },\n    \n         write_wmc_KeywordList: function(keywords) {\n         var node = this.createElementDefaultNS(\"KeywordList\");\n\n         for (var i=0, len=keywords.length; i<len; i++) {\n             node.appendChild(this.createElementDefaultNS(\n                 \"Keyword\", keywords[i]\n             ));\n         }\n         return node;\n     },\n          write_wmc_ContactInformation: function(contact) {\n         var node = this.createElementDefaultNS(\"ContactInformation\");\n\n         if (contact.personPrimary) {\n             node.appendChild(this.write_wmc_ContactPersonPrimary(contact.personPrimary));\n         }\n         if (contact.position) {\n             node.appendChild(this.createElementDefaultNS(\n                 \"ContactPosition\", contact.position\n             ));\n         }\n         if (contact.contactAddress) {\n             node.appendChild(this.write_wmc_ContactAddress(contact.contactAddress));\n         }\n         if (contact.phone) {\n             node.appendChild(this.createElementDefaultNS(\n                 \"ContactVoiceTelephone\", contact.phone\n             ));\n         }\n         if (contact.fax) {\n             node.appendChild(this.createElementDefaultNS(\n                 \"ContactFacsimileTelephone\", contact.fax\n             ));\n         }\n         if (contact.email) {\n             node.appendChild(this.createElementDefaultNS(\n                 \"ContactElectronicMailAddress\", contact.email\n             ));\n         }\n         return node;\n     },\n\n          write_wmc_ContactPersonPrimary: function(personPrimary) {\n         var node = this.createElementDefaultNS(\"ContactPersonPrimary\");\n         if (personPrimary.person) {\n             node.appendChild(this.createElementDefaultNS(\n                 \"ContactPerson\", personPrimary.person\n             ));\n         }\n         if (personPrimary.organization) {\n             node.appendChild(this.createElementDefaultNS(\n                 \"ContactOrganization\", personPrimary.organization\n             ));\n         }\n         return node;\n     },\n\n          write_wmc_ContactAddress: function(contactAddress) {\n         var node = this.createElementDefaultNS(\"ContactAddress\");\n         if (contactAddress.type) {\n             node.appendChild(this.createElementDefaultNS(\n                 \"AddressType\", contactAddress.type\n             ));\n         }\n         if (contactAddress.address) {\n             node.appendChild(this.createElementDefaultNS(\n                 \"Address\", contactAddress.address\n             ));\n         }\n         if (contactAddress.city) {\n             node.appendChild(this.createElementDefaultNS(\n                 \"City\", contactAddress.city\n             ));\n         }\n         if (contactAddress.stateOrProvince) {\n             node.appendChild(this.createElementDefaultNS(\n                 \"StateOrProvince\", contactAddress.stateOrProvince\n             ));\n         }\n         if (contactAddress.postcode) {\n             node.appendChild(this.createElementDefaultNS(\n                 \"PostCode\", contactAddress.postcode\n             ));\n         }\n         if (contactAddress.country) {\n             node.appendChild(this.createElementDefaultNS(\n                 \"Country\", contactAddress.country\n             ));\n         }\n         return node;\n     },\n\n         write_ol_MapExtension: function(context) {\n        var node = this.createElementDefaultNS(\"Extension\");\n        \n        var bounds = context.maxExtent;\n        if(bounds) {\n            var maxExtent = this.createElementNS(\n                this.namespaces.ol, \"ol:maxExtent\"\n            );\n            this.setAttributes(maxExtent, {\n                minx: bounds.left.toPrecision(18),\n                miny: bounds.bottom.toPrecision(18),\n                maxx: bounds.right.toPrecision(18),\n                maxy: bounds.top.toPrecision(18)\n            });\n            node.appendChild(maxExtent);\n        }\n        \n        return node;\n    },\n    \n        write_wmc_LayerList: function(context) {\n        var list = this.createElementDefaultNS(\"LayerList\");\n        \n        for(var i=0, len=context.layersContext.length; i<len; ++i) {\n            list.appendChild(this.write_wmc_Layer(context.layersContext[i]));\n        }\n        \n        return list;\n    },\n\n        write_wmc_Layer: function(context) {\n        var node = this.createElementDefaultNS(\n            \"Layer\", null, {\n                queryable: context.queryable ? \"1\" : \"0\",\n                hidden: context.visibility ? \"0\" : \"1\"\n            }\n        );\n        node.appendChild(this.write_wmc_Server(context));\n        node.appendChild(this.createElementDefaultNS(\n            \"Name\", context.name\n        ));\n        node.appendChild(this.createElementDefaultNS(\n            \"Title\", context.title\n        ));\n         if (context[\"abstract\"]) {\n             node.appendChild(this.createElementDefaultNS(\n                 \"Abstract\", context[\"abstract\"]\n             ));\n         }\n         if (context.dataURL) {\n             node.appendChild(this.write_wmc_URLType(\"DataURL\", context.dataURL));\n         }\n        if (context.metadataURL) {\n             node.appendChild(this.write_wmc_URLType(\"MetadataURL\", context.metadataURL));\n        }\n        \n        return node;\n    },\n\n        write_ol_attribution: function(attribution) {\n        if (typeof attribution == \"string\") {\n            attribution = {title: attribution};\n        }\n        var node = this.createElementNS(this.namespaces.ol, \"ol:attribution\");\n        node.appendChild(this.createElementDefaultNS(\n            \"Title\", attribution.title\n        ));\n        if (attribution.href) {\n            node.appendChild(this.write_wmc_OnlineResource(attribution.href));\n        }\n        if (attribution.logo) {\n            node.appendChild(\n                this.write_wmc_URLType(\"LogoURL\", \n                    attribution.logo.href, attribution.logo)\n            );\n        }\n        return node;\n    },\n\n        write_wmc_LayerExtension: function(context) {\n        var node = this.createElementDefaultNS(\"Extension\");\n        \n        var bounds = context.maxExtent;\n        var maxExtent = this.createElementNS(\n            this.namespaces.ol, \"ol:maxExtent\"\n        );\n        this.setAttributes(maxExtent, {\n            minx: bounds.left.toPrecision(18),\n            miny: bounds.bottom.toPrecision(18),\n            maxx: bounds.right.toPrecision(18),\n            maxy: bounds.top.toPrecision(18)\n        });\n        node.appendChild(maxExtent);\n        \n        if (context.tileSize && !context.singleTile) {\n            var size = this.createElementNS(\n                this.namespaces.ol, \"ol:tileSize\"\n            );\n            this.setAttributes(size, context.tileSize);\n            node.appendChild(size);\n        }\n\n        var properties = [\n            \"transparent\", \"numZoomLevels\", \"units\", \"isBaseLayer\",\n            \"opacity\", \"displayInLayerSwitcher\", \"singleTile\", \"gutter\"\n        ];\n        var child;\n        for(var i=0, len=properties.length; i<len; ++i) {\n            child = this.createOLPropertyNode(context, properties[i]);\n            if(child) {\n                node.appendChild(child);\n            }\n        }\n\n        if (context.attribution) {\n            var attribution = this.write_ol_attribution(context.attribution);\n            node.appendChild(attribution);\n        }\n\n        return node;\n    },\n    \n        createOLPropertyNode: function(obj, prop) {\n        var node = null;\n        if(obj[prop] != null) {\n            node = this.createElementNS(this.namespaces.ol, \"ol:\" + prop);\n            node.appendChild(this.createTextNode(obj[prop].toString()));\n        }\n        return node;\n    },\n\n        write_wmc_Server: function(context) {\n         var server = context.server;\n        var node = this.createElementDefaultNS(\"Server\");\n         var attributes = {\n            service: \"OGC:WMS\",\n             version: server.version\n         };\n         if (server.title) {\n             attributes.title = server.title;\n         }\n         this.setAttributes(node, attributes);\n         node.appendChild(this.write_wmc_OnlineResource(server.url));\n        \n        return node;\n    },\n\n         write_wmc_URLType: function(elName, url, attr) {\n         var node = this.createElementDefaultNS(elName);\n         node.appendChild(this.write_wmc_OnlineResource(url));\n         if (attr) {\n             var optionalAttributes = [\"width\", \"height\", \"format\"];\n             for (var i=0; i<optionalAttributes.length; i++) {\n                 if (optionalAttributes[i] in attr) {\n                     node.setAttribute(optionalAttributes[i], attr[optionalAttributes[i]]);\n                 }\n             }\n         }\n         return node;\n     },\n\n          write_wmc_DimensionList: function(context) {\n         var node = this.createElementDefaultNS(\"DimensionList\");\n         var required_attributes = {\n             name: true,\n             units: true,\n             unitSymbol: true,\n             userValue: true\n         };\n         for (var dim in context.dimensions) {\n             var attributes = {};\n             var dimension = context.dimensions[dim];\n             for (var name in dimension) {\n                 if (typeof dimension[name] == \"boolean\") {\n                     attributes[name] = Number(dimension[name]);\n                 } else {\n                     attributes[name] = dimension[name];\n                 }\n             }\n             var values = \"\";\n             if (attributes.values) {\n                 values = attributes.values.join(\",\");\n                 delete attributes.values;\n             }\n\n             node.appendChild(this.createElementDefaultNS(\n                 \"Dimension\", values, attributes\n             ));\n         }\n        return node;\n    },\n\n        write_wmc_FormatList: function(context) {\n        var node = this.createElementDefaultNS(\"FormatList\");\n        for (var i=0, len=context.formats.length; i<len; i++) {\n            var format = context.formats[i];\n            node.appendChild(this.createElementDefaultNS(\n                \"Format\",\n                format.value,\n                (format.current && format.current == true) ?\n                    {current: \"1\"} : null\n            ));\n        }\n\n        return node;\n    },\n\n        write_wmc_StyleList: function(layer) {\n        var node = this.createElementDefaultNS(\"StyleList\");\n\n        var styles = layer.styles;\n        if (styles && OpenLayers.Util.isArray(styles)) {\n            var sld;\n            for (var i=0, len=styles.length; i<len; i++) {\n                var s = styles[i];\n                var style = this.createElementDefaultNS(\n                    \"Style\",\n                    null,\n                    (s.current && s.current == true) ?\n                    {current: \"1\"} : null\n                );\n                if(s.href) { // [1]\n                    sld = this.createElementDefaultNS(\"SLD\");\n                     if (s.name) {\n                    sld.appendChild(this.createElementDefaultNS(\"Name\", s.name));\n                     }\n                    if (s.title) {\n                        sld.appendChild(this.createElementDefaultNS(\"Title\", s.title));\n                    }\n                     if (s.legend) {\n                         sld.appendChild(this.write_wmc_URLType(\"LegendURL\", s.legend.href, s.legend));\n                     }\n\n                     var link = this.write_wmc_OnlineResource(s.href);\n                     sld.appendChild(link);\n                    style.appendChild(sld);\n                } else if(s.body) { // [2]\n                    sld = this.createElementDefaultNS(\"SLD\");\n                     if (s.name) {\n                         sld.appendChild(this.createElementDefaultNS(\"Name\", s.name));\n                     }\n                     if (s.title) {\n                         sld.appendChild(this.createElementDefaultNS(\"Title\", s.title));\n                     }\n                     if (s.legend) {\n                         sld.appendChild(this.write_wmc_URLType(\"LegendURL\", s.legend.href, s.legend));\n                     }\n                    var doc = OpenLayers.Format.XML.prototype.read.apply(this, [s.body]);\n                    var imported = doc.documentElement;\n                    if(sld.ownerDocument && sld.ownerDocument.importNode) {\n                        imported = sld.ownerDocument.importNode(imported, true);\n                    }\n                    sld.appendChild(imported);\n                    style.appendChild(sld);            \n                } else { // [3]\n                    style.appendChild(this.createElementDefaultNS(\"Name\", s.name));\n                    style.appendChild(this.createElementDefaultNS(\"Title\", s.title));\n                    if (s['abstract']) { // abstract is a js keyword\n                        style.appendChild(this.createElementDefaultNS(\n                            \"Abstract\", s['abstract']\n                        ));\n                    }\n                     if (s.legend) {\n                         style.appendChild(this.write_wmc_URLType(\"LegendURL\", s.legend.href, s.legend));\n                }\n                 }\n                node.appendChild(style);\n            }\n        }\n\n        return node;\n    },\n\n        write_wmc_OnlineResource: function(href) {\n        var node = this.createElementDefaultNS(\"OnlineResource\");\n        this.setAttributeNS(node, this.namespaces.xlink, \"xlink:type\", \"simple\");\n        this.setAttributeNS(node, this.namespaces.xlink, \"xlink:href\", href);\n        return node;\n    },\n\n          getOnlineResource_href: function(node) {\n         var object = {};\n         var links = node.getElementsByTagName(\"OnlineResource\");\n         if(links.length > 0) {\n             this.read_wmc_OnlineResource(object, links[0]);\n         }\n         return object.href;\n     },\n\n\n    CLASS_NAME: \"OpenLayers.Format.WMC.v1\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WMC/v1_0_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WMC.v1_0_0 = OpenLayers.Class(\n    OpenLayers.Format.WMC.v1, {\n    \n        VERSION: \"1.0.0\",\n    \n        schemaLocation: \"http://www.opengis.net/context http://schemas.opengis.net/context/1.0.0/context.xsd\",\n\n        initialize: function(options) {\n        OpenLayers.Format.WMC.v1.prototype.initialize.apply(\n            this, [options]\n        );\n    },\n\n        read_wmc_SRS: function(layerContext, node) {\n        var srs    = this.getChildValue(node);\n        if (typeof layerContext.projections != \"object\") {\n            layerContext.projections = {};\n        }\n        var values = srs.split(/ +/);\n        for (var i=0, len=values.length; i<len; i++) {\n            layerContext.projections[values[i]] = true;\n        }\n    },\n\n        write_wmc_Layer: function(context) {\n        var node = OpenLayers.Format.WMC.v1.prototype.write_wmc_Layer.apply(\n            this, [context]\n        );\n        if (context.srs) {\n            var projections = [];\n            for(var name in context.srs) {\n                projections.push(name);\n            }\n            node.appendChild(this.createElementDefaultNS(\"SRS\", projections.join(\" \")));\n        }\n        node.appendChild(this.write_wmc_FormatList(context));\n        node.appendChild(this.write_wmc_StyleList(context));\n        if (context.dimensions) {\n            node.appendChild(this.write_wmc_DimensionList(context));\n        }\n        node.appendChild(this.write_wmc_LayerExtension(context));\n    },    \n\n    CLASS_NAME: \"OpenLayers.Format.WMC.v1_0_0\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WMC/v1_1_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WMC.v1_1_0 = OpenLayers.Class(\n    OpenLayers.Format.WMC.v1, {\n    \n        VERSION: \"1.1.0\",\n\n        schemaLocation: \"http://www.opengis.net/context http://schemas.opengis.net/context/1.1.0/context.xsd\",\n\n        initialize: function(options) {\n        OpenLayers.Format.WMC.v1.prototype.initialize.apply(\n            this, [options]\n        );\n    },\n\n        read_sld_MinScaleDenominator: function(layerContext, node) {\n        var minScaleDenominator = parseFloat(this.getChildValue(node));\n        if (minScaleDenominator > 0) {\n            layerContext.maxScale = minScaleDenominator;\n        }\n    },\n\n        read_sld_MaxScaleDenominator: function(layerContext, node) {\n        layerContext.minScale = parseFloat(this.getChildValue(node));\n    },\n\n        read_wmc_SRS: function(layerContext, node) {\n        if (! (\"srs\" in layerContext)) {\n            layerContext.srs = {};\n        }\n        layerContext.srs[this.getChildValue(node)] = true;\n    },\n\n        write_wmc_Layer: function(context) {\n        var node = OpenLayers.Format.WMC.v1.prototype.write_wmc_Layer.apply(\n            this, [context]\n        );\n        if(context.maxScale) {\n            var minSD = this.createElementNS(\n                this.namespaces.sld, \"sld:MinScaleDenominator\"\n            );\n            minSD.appendChild(this.createTextNode(context.maxScale.toPrecision(16)));\n            node.appendChild(minSD);\n        }\n        \n        if(context.minScale) {\n            var maxSD = this.createElementNS(\n                this.namespaces.sld, \"sld:MaxScaleDenominator\"\n            );\n            maxSD.appendChild(this.createTextNode(context.minScale.toPrecision(16)));\n            node.appendChild(maxSD);\n        }\n        if (context.srs) {\n            for(var name in context.srs) {\n                node.appendChild(this.createElementDefaultNS(\"SRS\", name));\n            }\n        }\n        node.appendChild(this.write_wmc_FormatList(context));\n        node.appendChild(this.write_wmc_StyleList(context));\n        if (context.dimensions) {\n            node.appendChild(this.write_wmc_DimensionList(context));\n        }\n        node.appendChild(this.write_wmc_LayerExtension(context));\n        \n        return node;\n        \n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WMC.v1_1_0\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WMC.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WMC = OpenLayers.Class(OpenLayers.Format.Context, {\n    \n        defaultVersion: \"1.1.0\",\n\n        \n        layerToContext: function(layer) {\n        var parser = this.getParser();\n        var layerContext = {\n            queryable: layer.queryable,\n            visibility: layer.visibility,\n            name: layer.params[\"LAYERS\"],\n            title: layer.name,\n            \"abstract\": layer.metadata[\"abstract\"],\n            dataURL: layer.metadata.dataURL,\n            metadataURL: layer.metadataURL,\n            attribution: layer.attribution,\n            server: {\n                version: layer.params[\"VERSION\"],\n                url: layer.url\n            },\n            maxExtent: layer.maxExtent,\n            transparent: layer.params[\"TRANSPARENT\"],\n            numZoomLevels: layer.numZoomLevels,\n            units: layer.units,\n            isBaseLayer: layer.isBaseLayer,\n            opacity: layer.opacity == 1 ? undefined : layer.opacity,\n            gutter: layer.gutter == 0 ? undefined : layer.gutter,\n            displayInLayerSwitcher: layer.displayInLayerSwitcher,\n            singleTile: layer.singleTile,\n            tileSize: (layer.singleTile || !layer.tileSize) ? \n                undefined : {width: layer.tileSize.w, height: layer.tileSize.h},\n            minScale : (layer.options.resolutions ||\n                        layer.options.scales || \n                        layer.options.maxResolution || \n                        layer.options.minScale) ? \n                        layer.minScale : undefined,\n            maxScale : (layer.options.resolutions ||\n                        layer.options.scales || \n                        layer.options.minResolution || \n                        layer.options.maxScale) ? \n                        layer.maxScale : undefined,\n            formats: [],\n            styles: [],\n            srs: layer.srs,\n            dimensions: layer.dimensions\n        };\n\n\n        if (layer.metadata.servertitle) {\n            layerContext.server.title = layer.metadata.servertitle;\n        }\n\n        if (layer.metadata.formats && layer.metadata.formats.length > 0) {\n            for (var i=0, len=layer.metadata.formats.length; i<len; i++) {\n                var format = layer.metadata.formats[i];\n                layerContext.formats.push({\n                    value: format.value,\n                    current: (format.value == layer.params[\"FORMAT\"])\n                });\n            }\n        } else {\n            layerContext.formats.push({\n                value: layer.params[\"FORMAT\"],\n                current: true\n            });\n        }\n\n        if (layer.metadata.styles && layer.metadata.styles.length > 0) {\n            for (var i=0, len=layer.metadata.styles.length; i<len; i++) {\n                var style = layer.metadata.styles[i];\n                if ((style.href == layer.params[\"SLD\"]) ||\n                    (style.body == layer.params[\"SLD_BODY\"]) ||\n                    (style.name == layer.params[\"STYLES\"])) {\n                    style.current = true;\n                } else {\n                    style.current = false;\n                }\n                layerContext.styles.push(style);\n            }\n        } else {\n            layerContext.styles.push({\n                href: layer.params[\"SLD\"],\n                body: layer.params[\"SLD_BODY\"],\n                name: layer.params[\"STYLES\"] || parser.defaultStyleName,\n                title: parser.defaultStyleTitle,\n                current: true\n            });\n        }\n\n        return layerContext;\n    },\n    \n        toContext: function(obj) {\n        var context = {};\n        var layers = obj.layers;\n        if (obj.CLASS_NAME == \"OpenLayers.Map\") {\n            var metadata = obj.metadata || {};\n            context.size = obj.getSize();\n            context.bounds = obj.getExtent();\n            context.projection = obj.projection;\n            context.title = obj.title;\n            context.keywords = metadata.keywords;\n            context[\"abstract\"] = metadata[\"abstract\"];\n            context.logo = metadata.logo;\n            context.descriptionURL = metadata.descriptionURL;\n            context.contactInformation = metadata.contactInformation;\n            context.maxExtent = obj.maxExtent;\n        } else {\n            OpenLayers.Util.applyDefaults(context, obj);\n            if (context.layers != undefined) {\n                delete(context.layers);\n            }\n        }\n\n        if (context.layersContext == undefined) {\n            context.layersContext = [];\n        }\n        if (layers != undefined && OpenLayers.Util.isArray(layers)) {\n            for (var i=0, len=layers.length; i<len; i++) {\n                var layer = layers[i];\n                if (layer instanceof OpenLayers.Layer.WMS) {\n                    context.layersContext.push(this.layerToContext(layer));\n                }\n            }\n        }\n        return context;\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WMC\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WMSCapabilities.v1 = OpenLayers.Class(\n    OpenLayers.Format.XML, {\n    \n        namespaces: {\n        wms: \"http://www.opengis.net/wms\",\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\"\n    },\n\n        defaultPrefix: \"wms\",\n    \n    \n        read: function(data) {\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        var raw = data;\n        if(data && data.nodeType == 9) {\n            data = data.documentElement;\n        }\n        var capabilities = {};\n        this.readNode(data, capabilities);\n        if (capabilities.service === undefined) {\n            var parser = new OpenLayers.Format.OGCExceptionReport();\n            capabilities.error = parser.read(raw);\n        }\n        return capabilities;\n    },\n\n        readers: {\n        \"wms\": {\n            \"Service\": function(node, obj) {\n                obj.service = {};\n                this.readChildNodes(node, obj.service);\n            },\n            \"Name\": function(node, obj) {\n                obj.name = this.getChildValue(node);\n            },\n            \"Title\": function(node, obj) {\n                obj.title = this.getChildValue(node);\n            },\n            \"Abstract\": function(node, obj) {\n                obj[\"abstract\"] = this.getChildValue(node);\n            },\n            \"BoundingBox\": function(node, obj) {\n                var bbox = {};\n                bbox.bbox = [\n                    parseFloat(node.getAttribute(\"minx\")),\n                    parseFloat(node.getAttribute(\"miny\")),\n                    parseFloat(node.getAttribute(\"maxx\")),\n                    parseFloat(node.getAttribute(\"maxy\"))\n                ];\n                var res = {\n                    x: parseFloat(node.getAttribute(\"resx\")),\n                    y: parseFloat(node.getAttribute(\"resy\"))\n                };\n\n                if (! (isNaN(res.x) && isNaN(res.y))) {\n                    bbox.res = res;\n                }\n                return bbox;\n            },\n            \"OnlineResource\": function(node, obj) {\n                obj.href = this.getAttributeNS(node, this.namespaces.xlink, \n                    \"href\");\n            },\n            \"ContactInformation\": function(node, obj) {\n                obj.contactInformation = {};\n                this.readChildNodes(node, obj.contactInformation);\n            },\n            \"ContactPersonPrimary\": function(node, obj) {\n                obj.personPrimary = {};\n                this.readChildNodes(node, obj.personPrimary);\n            },\n            \"ContactPerson\": function(node, obj) {\n                obj.person = this.getChildValue(node);\n            },\n            \"ContactOrganization\": function(node, obj) {\n                obj.organization = this.getChildValue(node);\n            },\n            \"ContactPosition\": function(node, obj) {\n                obj.position = this.getChildValue(node);\n            },\n            \"ContactAddress\": function(node, obj) {\n                obj.contactAddress = {};\n                this.readChildNodes(node, obj.contactAddress);\n            },\n            \"AddressType\": function(node, obj) {\n                obj.type = this.getChildValue(node);\n            },\n            \"Address\": function(node, obj) {\n                obj.address = this.getChildValue(node);\n            },\n            \"City\": function(node, obj) {\n                obj.city = this.getChildValue(node);\n            },\n            \"StateOrProvince\": function(node, obj) {\n                obj.stateOrProvince = this.getChildValue(node);\n            },\n            \"PostCode\": function(node, obj) {\n                obj.postcode = this.getChildValue(node);\n            },\n            \"Country\": function(node, obj) {\n                obj.country = this.getChildValue(node);\n            },\n            \"ContactVoiceTelephone\": function(node, obj) {\n                obj.phone = this.getChildValue(node);\n            },\n            \"ContactFacsimileTelephone\": function(node, obj) {\n                obj.fax = this.getChildValue(node);\n            },\n            \"ContactElectronicMailAddress\": function(node, obj) {\n                obj.email = this.getChildValue(node);\n            },\n            \"Fees\": function(node, obj) {\n                var fees = this.getChildValue(node);\n                if (fees && fees.toLowerCase() != \"none\") {\n                    obj.fees = fees;\n                }\n            },\n            \"AccessConstraints\": function(node, obj) {\n                var constraints = this.getChildValue(node);\n                if (constraints && constraints.toLowerCase() != \"none\") {\n                    obj.accessConstraints = constraints;\n                }\n            },\n            \"Capability\": function(node, obj) {\n                obj.capability = {\n                    nestedLayers: [],\n                    layers: []\n                };\n                this.readChildNodes(node, obj.capability);\n            },\n            \"Request\": function(node, obj) {\n                obj.request = {};\n                this.readChildNodes(node, obj.request);\n            },\n            \"GetCapabilities\": function(node, obj) {\n                obj.getcapabilities = {formats: []};\n                this.readChildNodes(node, obj.getcapabilities);\n            },\n            \"Format\": function(node, obj) {\n                if (OpenLayers.Util.isArray(obj.formats)) {\n                    obj.formats.push(this.getChildValue(node));\n                } else {\n                    obj.format = this.getChildValue(node);\n                }\n            },\n            \"DCPType\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"HTTP\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"Get\": function(node, obj) {\n                obj.get = {};\n                this.readChildNodes(node, obj.get);\n                if (!obj.href) {\n                    obj.href = obj.get.href;\n                }\n            },\n            \"Post\": function(node, obj) {\n                obj.post = {};\n                this.readChildNodes(node, obj.post);\n                if (!obj.href) {\n                    obj.href = obj.get.href;\n                }\n            },\n            \"GetMap\": function(node, obj) {\n                obj.getmap = {formats: []};\n                this.readChildNodes(node, obj.getmap);\n            },\n            \"GetFeatureInfo\": function(node, obj) {\n                obj.getfeatureinfo = {formats: []};\n                this.readChildNodes(node, obj.getfeatureinfo);\n            },\n            \"Exception\": function(node, obj) {\n                obj.exception = {formats: []};\n                this.readChildNodes(node, obj.exception);\n            },\n            \"Layer\": function(node, obj) {\n                var parentLayer, capability;\n                if (obj.capability) {\n                    capability = obj.capability;\n                    parentLayer = obj;\n                } else {\n                    capability = obj;\n                }\n                var attrNode = node.getAttributeNode(\"queryable\");\n                var queryable = (attrNode && attrNode.specified) ? \n                    node.getAttribute(\"queryable\") : null;\n                attrNode = node.getAttributeNode(\"cascaded\");\n                var cascaded = (attrNode && attrNode.specified) ?\n                    node.getAttribute(\"cascaded\") : null;\n                attrNode = node.getAttributeNode(\"opaque\");\n                var opaque = (attrNode && attrNode.specified) ?\n                    node.getAttribute('opaque') : null;\n                var noSubsets = node.getAttribute('noSubsets');\n                var fixedWidth = node.getAttribute('fixedWidth');\n                var fixedHeight = node.getAttribute('fixedHeight');\n                var parent = parentLayer || {},\n                    extend = OpenLayers.Util.extend;\n                var layer = {\n                    nestedLayers: [],\n                    styles: parentLayer ? [].concat(parentLayer.styles) : [],\n                    srs: parentLayer ? extend({}, parent.srs) : {}, \n                    metadataURLs: [],\n                    bbox: parentLayer ? extend({}, parent.bbox) : {},\n                    llbbox: parent.llbbox,\n                    dimensions: parentLayer ? extend({}, parent.dimensions) : {},\n                    authorityURLs: parentLayer ? extend({}, parent.authorityURLs) : {},\n                    identifiers: {},\n                    keywords: [],\n                    queryable: (queryable && queryable !== \"\") ? \n                        (queryable === \"1\" || queryable === \"true\" ) :\n                        (parent.queryable || false),\n                    cascaded: (cascaded !== null) ? parseInt(cascaded) :\n                        (parent.cascaded || 0),\n                    opaque: opaque ? \n                        (opaque === \"1\" || opaque === \"true\" ) :\n                        (parent.opaque || false),\n                    noSubsets: (noSubsets !== null) ? \n                        (noSubsets === \"1\" || noSubsets === \"true\" ) :\n                        (parent.noSubsets || false),\n                    fixedWidth: (fixedWidth != null) ? \n                        parseInt(fixedWidth) : (parent.fixedWidth || 0),\n                    fixedHeight: (fixedHeight != null) ? \n                        parseInt(fixedHeight) : (parent.fixedHeight || 0),\n                    minScale: parent.minScale,\n                    maxScale: parent.maxScale,\n                    attribution: parent.attribution\n                };\n                obj.nestedLayers.push(layer);\n                layer.capability = capability;\n                this.readChildNodes(node, layer);\n                delete layer.capability;\n                if(layer.name) {\n                    var parts = layer.name.split(\":\"),\n                        request = capability.request,\n                        gfi = request.getfeatureinfo;\n                    if(parts.length > 0) {\n                        layer.prefix = parts[0];\n                    }\n                    capability.layers.push(layer);\n                    if (layer.formats === undefined) {\n                        layer.formats = request.getmap.formats;\n                    }\n                    if (layer.infoFormats === undefined && gfi) {\n                        layer.infoFormats = gfi.formats;\n                    }\n                }\n            },\n            \"Attribution\": function(node, obj) {\n                obj.attribution = {};\n                this.readChildNodes(node, obj.attribution);\n            },\n            \"LogoURL\": function(node, obj) {\n                obj.logo = {\n                    width: node.getAttribute(\"width\"),\n                    height: node.getAttribute(\"height\")\n                };\n                this.readChildNodes(node, obj.logo);\n            },\n            \"Style\": function(node, obj) {\n                var style = {};\n                obj.styles.push(style);\n                this.readChildNodes(node, style);\n            },\n            \"LegendURL\": function(node, obj) {\n                var legend = {\n                    width: node.getAttribute(\"width\"),\n                    height: node.getAttribute(\"height\")\n                };\n                obj.legend = legend;\n                this.readChildNodes(node, legend);\n            },\n            \"MetadataURL\": function(node, obj) {\n                var metadataURL = {type: node.getAttribute(\"type\")};\n                obj.metadataURLs.push(metadataURL);\n                this.readChildNodes(node, metadataURL);\n            },\n            \"DataURL\": function(node, obj) {\n                obj.dataURL = {};\n                this.readChildNodes(node, obj.dataURL);\n            },\n            \"FeatureListURL\": function(node, obj) {\n                obj.featureListURL = {};\n                this.readChildNodes(node, obj.featureListURL);\n            },\n            \"AuthorityURL\": function(node, obj) {\n                var name = node.getAttribute(\"name\");\n                var authority = {};\n                this.readChildNodes(node, authority);\n                obj.authorityURLs[name] = authority.href;\n            },\n            \"Identifier\": function(node, obj) {\n                var authority = node.getAttribute(\"authority\");\n                obj.identifiers[authority] = this.getChildValue(node);\n            },\n            \"KeywordList\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"SRS\": function(node, obj) {\n                obj.srs[this.getChildValue(node)] = true;\n            }\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WMSCapabilities.v1\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1_1.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WMSCapabilities.v1_1 = OpenLayers.Class(\n    OpenLayers.Format.WMSCapabilities.v1, {\n    \n        readers: {\n        \"wms\": OpenLayers.Util.applyDefaults({\n            \"WMT_MS_Capabilities\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"Keyword\": function(node, obj) {\n                if (obj.keywords) {\n                    obj.keywords.push(this.getChildValue(node));\n                }\n            },\n            \"DescribeLayer\": function(node, obj) {\n                obj.describelayer = {formats: []};\n                this.readChildNodes(node, obj.describelayer);\n            },\n            \"GetLegendGraphic\": function(node, obj) {\n                obj.getlegendgraphic = {formats: []};\n                this.readChildNodes(node, obj.getlegendgraphic);\n            },\n            \"GetStyles\": function(node, obj) {\n                obj.getstyles = {formats: []};\n                this.readChildNodes(node, obj.getstyles);\n            },\n            \"PutStyles\": function(node, obj) {\n                obj.putstyles = {formats: []};\n                this.readChildNodes(node, obj.putstyles);\n            },\n            \"UserDefinedSymbolization\": function(node, obj) {\n                var userSymbols = {\n                    supportSLD: parseInt(node.getAttribute(\"SupportSLD\")) == 1,\n                    userLayer: parseInt(node.getAttribute(\"UserLayer\")) == 1,\n                    userStyle: parseInt(node.getAttribute(\"UserStyle\")) == 1,\n                    remoteWFS: parseInt(node.getAttribute(\"RemoteWFS\")) == 1\n                };\n                obj.userSymbols = userSymbols;\n            },\n            \"LatLonBoundingBox\": function(node, obj) {\n                obj.llbbox = [\n                    parseFloat(node.getAttribute(\"minx\")),\n                    parseFloat(node.getAttribute(\"miny\")),\n                    parseFloat(node.getAttribute(\"maxx\")),\n                    parseFloat(node.getAttribute(\"maxy\"))\n                ];\n            },\n            \"BoundingBox\": function(node, obj) {\n                var bbox = OpenLayers.Format.WMSCapabilities.v1.prototype.readers[\"wms\"].BoundingBox.apply(this, [node, obj]);\n                bbox.srs  = node.getAttribute(\"SRS\");\n                obj.bbox[bbox.srs] = bbox;\n            },\n            \"ScaleHint\": function(node, obj) {\n                var min = node.getAttribute(\"min\");\n                var max = node.getAttribute(\"max\");\n                var rad2 = Math.pow(2, 0.5);\n                var ipm = OpenLayers.INCHES_PER_UNIT[\"m\"];\n                if (min != 0) {\n                    obj.maxScale = parseFloat(\n                        ((min / rad2) * ipm * \n                            OpenLayers.DOTS_PER_INCH).toPrecision(13)\n                    );\n                }\n                if (max != Number.POSITIVE_INFINITY) {\n                    obj.minScale = parseFloat(\n                        ((max / rad2) * ipm * \n                            OpenLayers.DOTS_PER_INCH).toPrecision(13)\n                    );\n                }\n            },\n            \"Dimension\": function(node, obj) {\n                var name = node.getAttribute(\"name\").toLowerCase();\n                var dim = {\n                    name: name,\n                    units: node.getAttribute(\"units\"),\n                    unitsymbol: node.getAttribute(\"unitSymbol\")\n                };\n                obj.dimensions[dim.name] = dim;\n            },\n            \"Extent\": function(node, obj) {\n                var name = node.getAttribute(\"name\").toLowerCase();\n                if (name in obj[\"dimensions\"]) {\n                    var extent = obj.dimensions[name];\n                    extent.nearestVal = \n                        node.getAttribute(\"nearestValue\") === \"1\";\n                    extent.multipleVal = \n                        node.getAttribute(\"multipleValues\") === \"1\";\n                    extent.current = node.getAttribute(\"current\") === \"1\";\n                    extent[\"default\"] = node.getAttribute(\"default\") || \"\";\n                    var values = this.getChildValue(node);\n                    extent.values = values.split(\",\");\n                }\n                }\n        }, OpenLayers.Format.WMSCapabilities.v1.prototype.readers[\"wms\"])\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WMSCapabilities.v1_1\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1_1_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WMSCapabilities.v1_1_0 = OpenLayers.Class(\n    OpenLayers.Format.WMSCapabilities.v1_1, {\n    \n        version: \"1.1.0\",\n    \n    \n        readers: {\n        \"wms\": OpenLayers.Util.applyDefaults({\n            \"SRS\": function(node, obj) {\n                var srs = this.getChildValue(node);\n                var values = srs.split(/ +/);\n                for (var i=0, len=values.length; i<len; i++) {\n                    obj.srs[values[i]] = true;\n                }\n            }\n        }, OpenLayers.Format.WMSCapabilities.v1_1.prototype.readers[\"wms\"])\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WMSCapabilities.v1_1_0\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1_1_1.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WMSCapabilities.v1_1_1 = OpenLayers.Class(\n    OpenLayers.Format.WMSCapabilities.v1_1, {\n    \n        version: \"1.1.1\",\n    \n    \n        readers: {\n        \"wms\": OpenLayers.Util.applyDefaults({\n            \"SRS\": function(node, obj) {\n                obj.srs[this.getChildValue(node)] = true;\n            }\n        }, OpenLayers.Format.WMSCapabilities.v1_1.prototype.readers[\"wms\"])\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WMSCapabilities.v1_1_1\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1_1_1_WMSC.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WMSCapabilities.v1_1_1_WMSC = OpenLayers.Class(\n    OpenLayers.Format.WMSCapabilities.v1_1_1, {\n    \n        version: \"1.1.1\",\n    \n        profile: \"WMSC\",\n    \n    \n        readers: {\n        \"wms\": OpenLayers.Util.applyDefaults({\n            \"VendorSpecificCapabilities\": function(node, obj) {\n                obj.vendorSpecific = {tileSets: []};\n                this.readChildNodes(node, obj.vendorSpecific);\n            },\n            \"TileSet\": function(node, vendorSpecific) {\n                var tileset = {srs: {}, bbox: {}, resolutions: []};\n                this.readChildNodes(node, tileset);\n                vendorSpecific.tileSets.push(tileset);\n            },\n            \"Resolutions\": function(node, tileset) {\n                var res = this.getChildValue(node).split(\" \");\n                for (var i=0, len=res.length; i<len; i++) {\n                    if (res[i] != \"\") {\n                        tileset.resolutions.push(parseFloat(res[i]));\n                    }\n                }\n            },\n            \"Width\": function(node, tileset) {\n                tileset.width = parseInt(this.getChildValue(node));\n            },\n            \"Height\": function(node, tileset) {\n                tileset.height = parseInt(this.getChildValue(node));\n            },\n            \"Layers\": function(node, tileset) {\n                tileset.layers = this.getChildValue(node);\n            },\n            \"Styles\": function(node, tileset) {\n                tileset.styles = this.getChildValue(node);\n            }\n        }, OpenLayers.Format.WMSCapabilities.v1_1_1.prototype.readers[\"wms\"])\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WMSCapabilities.v1_1_1_WMSC\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1_3.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\r\n * full list of contributors). Published under the 2-clause BSD license.\r\n * See license.txt in the OpenLayers distribution or repository for the\r\n * full text of the license. */\r\n\r\n/**\r\n * @requires OpenLayers/Format/WMSCapabilities/v1.js\r\n */\r\n\r\n/**\r\n * Class: OpenLayers.Format.WMSCapabilities/v1_3\r\n * Abstract base class for WMS Capabilities version 1.3.X. \r\n * SLD 1.1.0 adds in the extra operations DescribeLayer and GetLegendGraphic, \r\n * see: http://schemas.opengis.net/sld/1.1.0/sld_capabilities.xsd\r\n * \r\n * Note on <MinScaleDenominator> and <MaxScaleDenominator> parsing: If\r\n * the <MinScaleDenominator> value is set to \"0\", no maxScale will be\r\n * set on the layer object. If the <MaxScaleDenominator> value is set to\r\n * \"Infinity\", no minScale will be set. This makes it easy to create proper\r\n * {<OpenLayers.Layer.WMS>} configurations directly from the layer object\r\n * literals returned by this format, because no minScale/maxScale modifications\r\n * need to be made.\r\n *\r\n * Inherits from:\r\n *  - <OpenLayers.Format.WMSCapabilities.v1>\r\n */\r\nOpenLayers.Format.WMSCapabilities.v1_3 = OpenLayers.Class(\r\n    OpenLayers.Format.WMSCapabilities.v1, {\r\n    \r\n    /**\r\n     * Property: readers\r\n     * Contains public functions, grouped by namespace prefix, that will\r\n     *     be applied when a namespaced node is found matching the function\r\n     *     name.  The function will be applied in the scope of this parser\r\n     *     with two arguments: the node being read and a context object passed\r\n     *     from the parent.\r\n     */\r\n    readers: {\r\n        \"wms\": OpenLayers.Util.applyDefaults({\r\n            \"WMS_Capabilities\": function(node, obj) {\r\n                this.readChildNodes(node, obj);\r\n            },\r\n            \"LayerLimit\": function(node, obj) {\r\n                obj.layerLimit = parseInt(this.getChildValue(node));\r\n            },\r\n            \"MaxWidth\": function(node, obj) {\r\n                obj.maxWidth = parseInt(this.getChildValue(node));\r\n            },\r\n            \"MaxHeight\": function(node, obj) {\r\n                obj.maxHeight = parseInt(this.getChildValue(node));\r\n            },\r\n            \"BoundingBox\": function(node, obj) {\r\n                var bbox = OpenLayers.Format.WMSCapabilities.v1.prototype.readers[\"wms\"].BoundingBox.apply(this, [node, obj]);\r\n                bbox.srs  = node.getAttribute(\"CRS\");\r\n                obj.bbox[bbox.srs] = bbox;\r\n            },\r\n            \"CRS\": function(node, obj) {\r\n                this.readers.wms.SRS.apply(this, [node, obj]); \r\n            },\r\n            \"EX_GeographicBoundingBox\": function(node, obj) {\r\n                obj.llbbox = [];\r\n                this.readChildNodes(node, obj.llbbox);\r\n                \r\n            },\r\n            \"westBoundLongitude\": function(node, obj) {\r\n                obj[0] = this.getChildValue(node);\r\n            },\r\n            \"eastBoundLongitude\": function(node, obj) {\r\n                obj[2] = this.getChildValue(node);\r\n            },\r\n            \"southBoundLatitude\": function(node, obj) {\r\n                obj[1] = this.getChildValue(node);\r\n            },\r\n            \"northBoundLatitude\": function(node, obj) {\r\n                obj[3] = this.getChildValue(node);\r\n            },\r\n            \"MinScaleDenominator\": function(node, obj) {\r\n                var maxScale = parseFloat(this.getChildValue(node)).toPrecision(16);\r\n                if (maxScale != 0) {\r\n                    obj.maxScale = maxScale;\r\n                }\r\n            },\r\n            \"MaxScaleDenominator\": function(node, obj) {\r\n                var minScale = parseFloat(this.getChildValue(node)).toPrecision(16);\r\n                if (minScale != Number.POSITIVE_INFINITY) {\r\n                    obj.minScale = minScale;\r\n                }\r\n            },\r\n            \"Dimension\": function(node, obj) {\r\n                var name = node.getAttribute(\"name\").toLowerCase();\r\n                var dim = {\r\n                    name: name,\r\n                    units: node.getAttribute(\"units\"),\r\n                    unitsymbol: node.getAttribute(\"unitSymbol\"),\r\n                    nearestVal: node.getAttribute(\"nearestValue\") === \"1\",\r\n                    multipleVal: node.getAttribute(\"multipleValues\") === \"1\",\r\n                    \"default\": node.getAttribute(\"default\") || \"\",\r\n                    current: node.getAttribute(\"current\") === \"1\",\r\n                    values: this.getChildValue(node).split(\",\")\r\n                    \r\n                };\r\n                obj.dimensions[dim.name] = dim;\r\n            },\r\n            \"Keyword\": function(node, obj) {\r\n                var keyword = {value: this.getChildValue(node), \r\n                    vocabulary: node.getAttribute(\"vocabulary\")};\r\n                if (obj.keywords) {\r\n                    obj.keywords.push(keyword);\r\n                }\r\n            }\r\n        }, OpenLayers.Format.WMSCapabilities.v1.prototype.readers[\"wms\"]),\r\n        \"sld\": {\r\n            \"UserDefinedSymbolization\": function(node, obj) {\r\n                this.readers.wms.UserDefinedSymbolization.apply(this, [node, obj]);\r\n                obj.userSymbols.inlineFeature = parseInt(node.getAttribute(\"InlineFeature\")) == 1;\r\n                obj.userSymbols.remoteWCS = parseInt(node.getAttribute(\"RemoteWCS\")) == 1;\r\n            },\r\n            \"DescribeLayer\": function(node, obj) {\r\n                this.readers.wms.DescribeLayer.apply(this, [node, obj]);\r\n            },\r\n            \"GetLegendGraphic\": function(node, obj) {\r\n                this.readers.wms.GetLegendGraphic.apply(this, [node, obj]);\r\n            }\r\n        }\r\n    },\r\n    \r\n    CLASS_NAME: \"OpenLayers.Format.WMSCapabilities.v1_3\" \r\n\r\n});\r\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WMSCapabilities/v1_3_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\r\n * full list of contributors). Published under the 2-clause BSD license.\r\n * See license.txt in the OpenLayers distribution or repository for the\r\n * full text of the license. */\r\n\r\n/**\r\n * @requires OpenLayers/Format/WMSCapabilities/v1_3.js\r\n */\r\n\r\n/**\r\n * Class: OpenLayers.Format.WMSCapabilities/v1_3_0\r\n * Read WMS Capabilities version 1.3.0. \r\n * SLD 1.1.0 adds in the extra operations DescribeLayer and GetLegendGraphic, \r\n * see: http://schemas.opengis.net/sld/1.1.0/sld_capabilities.xsd\r\n * \r\n * Inherits from:\r\n *  - <OpenLayers.Format.WMSCapabilities.v1_3>\r\n */\r\nOpenLayers.Format.WMSCapabilities.v1_3_0 = OpenLayers.Class(\r\n    OpenLayers.Format.WMSCapabilities.v1_3, {\r\n    \r\n    /**\r\n     * Property: version\r\n     * {String} The specific parser version.\r\n     */\r\n    version: \"1.3.0\",\r\n    \r\n    CLASS_NAME: \"OpenLayers.Format.WMSCapabilities.v1_3_0\" \r\n\r\n});\r\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WMSCapabilities.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WMSCapabilities = OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC, {\n    \n        defaultVersion: \"1.1.1\",\n    \n        profile: null,\n    \n    \n        \n    CLASS_NAME: \"OpenLayers.Format.WMSCapabilities\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WMSDescribeLayer/v1_1.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WMSDescribeLayer.v1_1_1 = OpenLayers.Class(\n    OpenLayers.Format.WMSDescribeLayer, {\n    \n        initialize: function(options) {\n        OpenLayers.Format.WMSDescribeLayer.prototype.initialize.apply(this, \n            [options]);\n    },\n\n        read: function(data) {\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        var root = data.documentElement;\n        var children = root.childNodes; \n        var describelayer = {layerDescriptions: []};\n        var childNode, nodeName;\n        for(var i=0; i<children.length; ++i) { \n            childNode = children[i];\n            nodeName = childNode.nodeName; \n            if (nodeName == 'LayerDescription') {\n                var layerName = childNode.getAttribute('name');\n                var owsType = '';\n                var owsURL = '';\n                var typeName = '';\n                if (childNode.getAttribute('owsType')) {\n                  owsType = childNode.getAttribute('owsType');\n                  owsURL = childNode.getAttribute('owsURL');\n                } else {\n                    if (childNode.getAttribute('wfs') != '') {\n                        owsType = 'WFS';\n                        owsURL = childNode.getAttribute('wfs');\n                    } else if (childNode.getAttribute('wcs') != '') {\n                        owsType = 'WCS';\n                        owsURL = childNode.getAttribute('wcs');\n                    }\n                }\n                var query = childNode.getElementsByTagName('Query');\n                if(query.length > 0) {\n                    typeName = query[0].getAttribute('typeName');\n                    if (!typeName) {\n                        typeName = query[0].getAttribute('typename');\n                    }\n                }\n                var layerDescription = {\n                    layerName: layerName, owsType: owsType, \n                    owsURL: owsURL, typeName: typeName\n                };\n                describelayer.layerDescriptions.push(layerDescription);\n                describelayer.length = describelayer.layerDescriptions.length;\n                describelayer[describelayer.length - 1] = layerDescription; \n                \n            } else if (nodeName == 'ServiceException') {\n                var parser = new OpenLayers.Format.OGCExceptionReport();\n                return {\n                    error: parser.read(data)\n                };\n            }\n        }\n        return describelayer;\n    },\n    \n    CLASS_NAME: \"OpenLayers.Format.WMSDescribeLayer.v1_1_1\"\n\n});\nOpenLayers.Format.WMSDescribeLayer.v1_1_0 =\n    OpenLayers.Format.WMSDescribeLayer.v1_1_1;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WMSDescribeLayer.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WMSDescribeLayer = OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC, {\n\n        defaultVersion: \"1.1.1\",\n   \n    \n        \n    CLASS_NAME: \"OpenLayers.Format.WMSDescribeLayer\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WMSGetFeatureInfo.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WMSGetFeatureInfo = OpenLayers.Class(OpenLayers.Format.XML, {\n\n        layerIdentifier: '_layer',\n\n        featureIdentifier: '_feature',\n\n        regExes: {\n        trimSpace: (/^\\s*|\\s*$/g),\n        removeSpace: (/\\s*/g),\n        splitSpace: (/\\s+/),\n        trimComma: (/\\s*,\\s*/g)\n    },\n\n        gmlFormat: null,\n\n    \n        read: function(data) {\n        var result;\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        var root = data.documentElement;\n        if(root) {\n            var scope = this;\n            var read = this[\"read_\" + root.nodeName];\n            if(read) {\n                result = read.call(this, root);\n            } else {\n                result = new OpenLayers.Format.GML((this.options ? this.options : {})).read(data);\n            }\n        } else {\n            result = data;\n        }\n        return result;\n    },\n\n\n        read_msGMLOutput: function(data) {\n        var response = [];\n        var layerNodes = this.getSiblingNodesByTagCriteria(data,\n            this.layerIdentifier);\n        if (layerNodes) {\n            for (var i=0, len=layerNodes.length; i<len; ++i) {\n                var node = layerNodes[i];\n                var layerName = node.nodeName;\n                if (node.prefix) {\n                    layerName = layerName.split(':')[1];\n                }\n                var layerName = layerName.replace(this.layerIdentifier, '');\n                var featureNodes = this.getSiblingNodesByTagCriteria(node,\n                    this.featureIdentifier);\n                if (featureNodes) {\n                    for (var j = 0; j < featureNodes.length; j++) {\n                        var featureNode = featureNodes[j];\n                        var geomInfo = this.parseGeometry(featureNode);\n                        var attributes = this.parseAttributes(featureNode);\n                        var feature = new OpenLayers.Feature.Vector(geomInfo.geometry,\n                            attributes, null);\n                        feature.bounds = geomInfo.bounds;\n                        feature.type = layerName;\n                        response.push(feature);\n                    }\n                }\n            }\n        }\n        return response;\n    },\n\n        read_FeatureInfoResponse: function(data) {\n        var response = [];\n        var featureNodes = this.getElementsByTagNameNS(data, '*',\n            'FIELDS');\n\n        for(var i=0, len=featureNodes.length;i<len;i++) {\n            var featureNode = featureNodes[i];\n            var geom = null;\n            var attributes = {};\n            var j;\n            var jlen = featureNode.attributes.length;\n            if (jlen > 0) {\n                for(j=0; j<jlen; j++) {\n                    var attribute = featureNode.attributes[j];\n                    attributes[attribute.nodeName] = attribute.nodeValue;\n                }\n            } else {\n                var nodes = featureNode.childNodes;\n                for (j=0, jlen=nodes.length; j<jlen; ++j) {\n                    var node = nodes[j];\n                    if (node.nodeType != 3) {\n                        attributes[node.getAttribute(\"name\")] =\n                            node.getAttribute(\"value\");\n                    }\n                }\n            }\n\n            response.push(\n                new OpenLayers.Feature.Vector(geom, attributes, null)\n            );\n        }\n        return response;\n    },\n\n        getSiblingNodesByTagCriteria: function(node, criteria){\n        var nodes = [];\n        var children, tagName, n, matchNodes, child;\n        if (node && node.hasChildNodes()) {\n            children = node.childNodes;\n            n = children.length;\n\n            for(var k=0; k<n; k++){\n                child = children[k];\n                while (child && child.nodeType != 1) {\n                    child = child.nextSibling;\n                    k++;\n                }\n                tagName = (child ? child.nodeName : '');\n                if (tagName.length > 0 && tagName.indexOf(criteria) > -1) {\n                    nodes.push(child);\n                } else {\n                    matchNodes = this.getSiblingNodesByTagCriteria(\n                        child, criteria);\n\n                    if(matchNodes.length > 0){\n                        (nodes.length == 0) ?\n                            nodes = matchNodes : nodes.push(matchNodes);\n                    }\n                }\n            }\n\n        }\n        return nodes;\n    },\n\n        parseAttributes: function(node){\n        var attributes = {};\n        if (node.nodeType == 1) {\n            var children = node.childNodes;\n            var n = children.length;\n            for (var i = 0; i < n; ++i) {\n                var child = children[i];\n                if (child.nodeType == 1) {\n                    var grandchildren = child.childNodes;\n                    var name = (child.prefix) ?\n                        child.nodeName.split(\":\")[1] : child.nodeName;\n                    if (grandchildren.length == 0) {\n                        attributes[name] = null;\n                    } else if (grandchildren.length == 1 ||\n                            grandchildren[0].nodeValue.replace(\n                                this.regExes.trimSpace, \"\").length > 0) {\n                        var grandchild = grandchildren[0];\n                        if (grandchild.nodeType == 3 ||\n                                grandchild.nodeType == 4) {\n                            var attribute = grandchild.wholeText ?\n                                grandchild.wholeText :\n                                grandchild.nodeValue;\n                            attributes[name] = attribute.replace(\n                                    this.regExes.trimSpace, \"\");\n                        }\n                    }\n                }\n            }\n        }\n        return attributes;\n    },\n\n        parseGeometry: function(node) {\n        if (!this.gmlFormat) {\n            this.gmlFormat = new OpenLayers.Format.GML();\n        }\n        var feature = this.gmlFormat.parseFeature(node);\n        var geometry, bounds = null;\n        if (feature) {\n            geometry = feature.geometry && feature.geometry.clone();\n            bounds = feature.bounds && feature.bounds.clone();\n            feature.destroy();\n        }\n        return {geometry: geometry, bounds: bounds};\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WMSGetFeatureInfo\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WMTSCapabilities/v1_0_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WMTSCapabilities.v1_0_0 = OpenLayers.Class(\n    OpenLayers.Format.OWSCommon.v1_1_0, {\n        \n        version: \"1.0.0\",\n\n        namespaces: {\n        ows: \"http://www.opengis.net/ows/1.1\",\n        wmts: \"http://www.opengis.net/wmts/1.0\",\n        xlink: \"http://www.w3.org/1999/xlink\"\n    },    \n    \n        yx: null,\n\n        defaultPrefix: \"wmts\",\n\n        initialize: function(options) {\n        OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);\n        this.options = options;\n        var yx = OpenLayers.Util.extend(\n            {}, OpenLayers.Format.WMTSCapabilities.prototype.yx\n        );\n        this.yx = OpenLayers.Util.extend(yx, this.yx);\n    },\n\n        read: function(data) {\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        if(data && data.nodeType == 9) {\n            data = data.documentElement;\n        }\n        var capabilities = {};\n        this.readNode(data, capabilities);\n        capabilities.version = this.version;\n        return capabilities;\n    },\n\n        readers: {        \n        \"wmts\": {\n            \"Capabilities\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"Contents\": function(node, obj) {\n                obj.contents = {};                \n                obj.contents.layers = [];\n                obj.contents.tileMatrixSets = {};                \n                this.readChildNodes(node, obj.contents);\n            },\n            \"Layer\": function(node, obj) {\n                var layer = {\n                    styles: [],\n                    formats: [],\n                    dimensions: [],\n                    tileMatrixSetLinks: []\n                };\n                this.readChildNodes(node, layer);\n                obj.layers.push(layer);\n            },\n            \"Style\": function(node, obj) {\n                var style = {};\n                style.isDefault = (node.getAttribute(\"isDefault\") === \"true\");\n                this.readChildNodes(node, style);\n                obj.styles.push(style);\n            },\n            \"Format\": function(node, obj) {\n                obj.formats.push(this.getChildValue(node)); \n            },\n            \"TileMatrixSetLink\": function(node, obj) {\n                var tileMatrixSetLink = {};\n                this.readChildNodes(node, tileMatrixSetLink);\n                obj.tileMatrixSetLinks.push(tileMatrixSetLink);\n            },\n            \"TileMatrixSet\": function(node, obj) {\n                if (obj.layers) {\n                    var tileMatrixSet = {\n                        matrixIds: []\n                    };\n                    this.readChildNodes(node, tileMatrixSet);\n                    obj.tileMatrixSets[tileMatrixSet.identifier] = tileMatrixSet;\n                } else {\n                    obj.tileMatrixSet = this.getChildValue(node);\n                }\n            },\n            \"TileMatrixSetLimits\": function(node, obj) {\n                obj.tileMatrixSetLimits = [];\n                this.readChildNodes(node, obj);\n            },\n            \"TileMatrixLimits\": function(node, obj) {\n                var tileMatrixLimits = {};\n                this.readChildNodes(node, tileMatrixLimits);\n                obj.tileMatrixSetLimits.push(tileMatrixLimits);\n            },\n            \"MinTileRow\": function(node, obj) {\n                obj.minTileRow = parseInt(this.getChildValue(node)); \n            },\n            \"MaxTileRow\": function(node, obj) {\n                obj.maxTileRow = parseInt(this.getChildValue(node)); \n            },\n            \"MinTileCol\": function(node, obj) {\n                obj.minTileCol = parseInt(this.getChildValue(node)); \n            },\n            \"MaxTileCol\": function(node, obj) {\n                obj.maxTileCol = parseInt(this.getChildValue(node)); \n            },\n            \"TileMatrix\": function(node, obj) {\n                if (obj.identifier) {\n                    var tileMatrix = {\n                        supportedCRS: obj.supportedCRS\n                    };\n                    this.readChildNodes(node, tileMatrix);\n                    obj.matrixIds.push(tileMatrix);\n                } else {\n                    obj.tileMatrix = this.getChildValue(node);\n                }\n            },\n            \"ScaleDenominator\": function(node, obj) {\n                obj.scaleDenominator = parseFloat(this.getChildValue(node)); \n            },\n            \"TopLeftCorner\": function(node, obj) {                \n                var topLeftCorner = this.getChildValue(node);\n                var coords = topLeftCorner.split(\" \");\n                var yx;\n                if (obj.supportedCRS) {\n                    var crs = obj.supportedCRS.replace(\n                        /urn:ogc:def:crs:(\\w+):.+:(\\w+)$/, \n                        \"urn:ogc:def:crs:$1::$2\"\n                    );\n                    yx = !!this.yx[crs];\n                }\n                if (yx) {\n                    obj.topLeftCorner = new OpenLayers.LonLat(\n                        coords[1], coords[0]\n                    );\n                } else {\n                    obj.topLeftCorner = new OpenLayers.LonLat(\n                        coords[0], coords[1]\n                    );\n                }\n            },\n            \"TileWidth\": function(node, obj) {\n                obj.tileWidth = parseInt(this.getChildValue(node)); \n            },\n            \"TileHeight\": function(node, obj) {\n                obj.tileHeight = parseInt(this.getChildValue(node)); \n            },\n            \"MatrixWidth\": function(node, obj) {\n                obj.matrixWidth = parseInt(this.getChildValue(node)); \n            },\n            \"MatrixHeight\": function(node, obj) {\n                obj.matrixHeight = parseInt(this.getChildValue(node)); \n            },\n            \"ResourceURL\": function(node, obj) {\n                obj.resourceUrl = obj.resourceUrl || {};\n                var resourceType = node.getAttribute(\"resourceType\");\n                if (!obj.resourceUrls) {\n                    obj.resourceUrls = [];\n                }\n                var resourceUrl = obj.resourceUrl[resourceType] = {\n                    format: node.getAttribute(\"format\"),\n                    template: node.getAttribute(\"template\"),\n                    resourceType: resourceType\n                };\n                obj.resourceUrls.push(resourceUrl);\n            },\n            \"LegendURL\": function(node, obj) {\n                obj.legends = obj.legends || [];\n                var legend = {\n                    format: node.getAttribute(\"format\"),\n                    href: node.getAttribute(\"xlink:href\")\n                };\n                var width = node.getAttribute(\"width\"),\n                    height = node.getAttribute(\"height\"),\n                    minScaleDenominator = node.getAttribute(\"minScaleDenominator\"),\n                    maxScaleDenominator = node.getAttribute(\"maxScaleDenominator\");\n                if (width !== null) {\n                    legend.width = parseInt(width);\n                }\n                if (height !== null) {\n                    legend.height = parseInt(height);\n                }\n                if (minScaleDenominator !== null) {\n                    legend.minScaleDenominator = parseInt(minScaleDenominator);\n                }\n                if (maxScaleDenominator !== null) {\n                    legend.maxScaleDenominator = parseInt(maxScaleDenominator);\n                }\n                obj.legends.push(legend);\n            },\n            \"InfoFormat\": function(node, obj) {\n                obj.infoFormats = obj.infoFormats || [];\n                obj.infoFormats.push(this.getChildValue(node));\n            },\n            /*\"Themes\": function(node, obj) {\n                obj.themes = [];\n                this.readChildNodes(node, obj.themes);\n            },\n            \"Theme\": function(node, obj) {\n                var theme = {};                \n                this.readChildNodes(node, theme);\n                obj.push(theme);\n            },*/\n            \"WSDL\": function(node, obj) {\n                obj.wsdl = {};\n                obj.wsdl.href = node.getAttribute(\"xlink:href\");\n            },\n            \"ServiceMetadataURL\": function(node, obj) {\n                obj.serviceMetadataUrl = {};\n                obj.serviceMetadataUrl.href = node.getAttribute(\"xlink:href\");\n            },\n            \"Dimension\": function(node, obj) {\n                var dimension = {values: []};\n                this.readChildNodes(node, dimension);\n                obj.dimensions.push(dimension);\n            },\n            \"Default\": function(node, obj) {\n                obj[\"default\"] = this.getChildValue(node);\n            },\n            \"Value\": function(node, obj) {\n                obj.values.push(this.getChildValue(node));\n            }\n        },\n        \"ows\": OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers[\"ows\"]\n    },    \n    \n    CLASS_NAME: \"OpenLayers.Format.WMTSCapabilities.v1_0_0\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WMTSCapabilities.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WMTSCapabilities = OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC, {\n\n        defaultVersion: \"1.0.0\",\n\n        yx: {\n        \"urn:ogc:def:crs:EPSG::4326\": true\n    },\n\n    \n    \n        createLayer: function(capabilities, config) {\n        var layer;\n        if (!('layer' in config)) {\n            throw new Error(\"Missing property 'layer' in configuration.\");\n        }\n\n        var contents = capabilities.contents;\n        var layers = contents.layers;\n        var layerDef;\n        for (var i=0, ii=contents.layers.length; i<ii; ++i) {\n            if (contents.layers[i].identifier === config.layer) {\n                layerDef = contents.layers[i];\n                break;\n            }\n        }\n        if (!layerDef) {\n            throw new Error(\"Layer not found\");\n        }\n        \n        var format = config.format;\n        if (!format && layerDef.formats && layerDef.formats.length) {\n            format = layerDef.formats[0];\n        }\n        var matrixSet;\n        if (config.matrixSet) {\n            matrixSet = contents.tileMatrixSets[config.matrixSet];\n        } else if (config.projection) {\n            for (var i=0,l=layerDef.tileMatrixSetLinks.length;i<l;i++) {\n                if (contents.tileMatrixSets[\n                        layerDef.tileMatrixSetLinks[i].tileMatrixSet\n                    ].supportedCRS.replace(\n                        /urn:ogc:def:crs:(\\w+):(.*:)?(\\w+)$/, \"$1:$3\"\n                    ) === config.projection) {\n\n                    matrixSet = contents.tileMatrixSets[\n                        layerDef.tileMatrixSetLinks[i].tileMatrixSet];\n                    break;\n                }\n            }\n        } else if (layerDef.tileMatrixSetLinks.length >= 1) {\n            matrixSet = contents.tileMatrixSets[\n                layerDef.tileMatrixSetLinks[0].tileMatrixSet];\n        }\n        if (!matrixSet) {\n            throw new Error(\"matrixSet not found\");\n        }\n        var style;\n        for (var i=0, ii=layerDef.styles.length; i<ii; ++i) {\n            style = layerDef.styles[i];\n            if (style.isDefault) {\n                break;\n            }\n        }\n\n        var requestEncoding = config.requestEncoding;\n        if (!requestEncoding) {\n            requestEncoding = \"KVP\";\n            if (capabilities.operationsMetadata.GetTile.dcp.http) {\n                var http = capabilities.operationsMetadata.GetTile.dcp.http;\n                if (http.get[0].constraints) {\n                    var constraints = http.get[0].constraints;\n                    var allowedValues = constraints.GetEncoding.allowedValues;\n                    if (!allowedValues.KVP &&\n                            (allowedValues.REST || allowedValues.RESTful)) {\n                        requestEncoding = \"REST\";\n                    }\n                }\n            }\n        }\n\n        var dimensions = [];\n        var params = config.params || {};\n        delete config.params;\n        for (var id = 0, ld = layerDef.dimensions.length ; id < ld ; id++) {\n            var dimension = layerDef.dimensions[id];\n            dimensions.push(dimension.identifier);\n            if (!params.hasOwnProperty(dimension.identifier)) {\n                params[dimension.identifier] = dimension['default'];\n            }\n        }\n\n        var projection = config.projection || matrixSet.supportedCRS.replace(\n                /urn:ogc:def:crs:(\\w+):(.*:)?(\\w+)$/, \"$1:$3\");\n        var units = config.units ||\n                (projection === (\"EPSG:4326\" || \"OGC:CRS84\") ? \"degrees\" : \"m\");\n        var resolutions = [], minScaleDenominator, maxScaleDenominator,\n            reducedMatrixIds = [], tileMatrixSetLink,\n            tileMatrixSetLinks = layerDef.tileMatrixSetLinks;\n        var buildResolutionsArray = function(scaleDenominator) {\n            resolutions.push(\n                scaleDenominator * 0.28E-3 / OpenLayers.METERS_PER_INCH /\n                    OpenLayers.INCHES_PER_UNIT[units]\n            );\n            if (!minScaleDenominator || minScaleDenominator > scaleDenominator) {\n                minScaleDenominator = scaleDenominator;\n            }\n            if (!maxScaleDenominator || maxScaleDenominator < scaleDenominator) {\n                maxScaleDenominator = scaleDenominator;\n            }\n        };\n        for (var j=0, l=tileMatrixSetLinks.length; j<l; j++) {\n            tileMatrixSetLink = tileMatrixSetLinks[j];\n            if (tileMatrixSetLink.tileMatrixSet === matrixSet.identifier) {\n                if (tileMatrixSetLink.tileMatrixSetLimits) {\n                    var tmpMatrixIds = {}, mid;\n                    for (var k=0, ll=matrixSet.matrixIds.length; k<ll; k++) {\n                        tmpMatrixIds[matrixSet.matrixIds[k].identifier] = matrixSet.matrixIds[k];\n                    }\n                    for (var k=0, ll=tileMatrixSetLink.tileMatrixSetLimits.length; k<ll; k++) {\n                        mid = tmpMatrixIds[tileMatrixSetLink.tileMatrixSetLimits[k].tileMatrix];\n                        reducedMatrixIds.push(mid);\n                        buildResolutionsArray(mid.scaleDenominator);\n                    }\n                } else {\n                    for (var k=0, ll=matrixSet.matrixIds.length; k<ll; k++) {\n                        buildResolutionsArray(matrixSet.matrixIds[k].scaleDenominator);\n                    };\n                }\n                break;\n            }\n        }\n\n        var url;\n        if (requestEncoding === \"REST\" && layerDef.resourceUrls) {\n            url = [];\n            var resourceUrls = layerDef.resourceUrls,\n                resourceUrl;\n            for (var t = 0, tt = layerDef.resourceUrls.length; t < tt; ++t) {\n                resourceUrl = layerDef.resourceUrls[t];\n                if (resourceUrl.format === format && resourceUrl.resourceType === \"tile\") {\n                    url.push(resourceUrl.template);\n                }\n            }\n        } else {\n            var httpGet = capabilities.operationsMetadata.GetTile.dcp.http.get;\n            url = [];\n            var constraint;\n            for (var i = 0, ii = httpGet.length; i < ii; i++) {\n                constraint = httpGet[i].constraints;\n                if (!constraint || (constraint && constraint.\n                        GetEncoding.allowedValues[requestEncoding])) {\n                    url.push(httpGet[i].url);\n                }\n            }\n        }\n\n        resolutions.sort(function(a,b){\n            return b-a;\n        });\n        var options = OpenLayers.Util.applyDefaults(config, {\n            url: url,\n            requestEncoding: requestEncoding,\n            name: layerDef.title,\n            style: style && style.identifier || \"\",\n            format: format,\n            matrixIds: reducedMatrixIds.length ? \n                reducedMatrixIds : matrixSet.matrixIds,\n            matrixSet: matrixSet.identifier,\n            projection: projection,\n            units: units,\n            tileFullExtent: matrixSet.bounds,\n            dimensions: dimensions,\n            params: params,\n            resolutions: config.isBaseLayer === false ? undefined :\n                resolutions,\n            serverResolutions: resolutions,\n            minScale: 1/Math.ceil(maxScaleDenominator),\n            maxScale: 1/Math.floor(minScaleDenominator)\n        });\n        return new OpenLayers.Layer.WMTS(options);\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.WMTSCapabilities\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WPSCapabilities/v1_0_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WPSCapabilities.v1_0_0 = OpenLayers.Class(\n    OpenLayers.Format.XML, {\n\n        namespaces: {\n        ows: \"http://www.opengis.net/ows/1.1\",\n        wps: \"http://www.opengis.net/wps/1.0.0\",\n        xlink: \"http://www.w3.org/1999/xlink\"\n    },\n\n        regExes: {\n        trimSpace: (/^\\s*|\\s*$/g),\n        removeSpace: (/\\s*/g),\n        splitSpace: (/\\s+/),\n        trimComma: (/\\s*,\\s*/g)\n    },\n    \n        initialize: function(options) {\n        OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);\n    },\n\n        read: function(data) {\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        if(data && data.nodeType == 9) {\n            data = data.documentElement;\n        }\n        var capabilities = {};\n        this.readNode(data, capabilities);\n        return capabilities;\n    },\n\n        readers: {\n        \"wps\": {\n            \"Capabilities\": function(node, obj) {\n                this.readChildNodes(node, obj);\n            },\n            \"ProcessOfferings\": function(node, obj) {\n                obj.processOfferings = {};\n                this.readChildNodes(node, obj.processOfferings);\n            },\n            \"Process\": function(node, processOfferings) {\n                var processVersion = this.getAttributeNS(node, this.namespaces.wps, \"processVersion\");\n                var process = {processVersion: processVersion};\n                this.readChildNodes(node, process);\n                processOfferings[process.identifier] = process;\n            },\n            \"Languages\": function(node, obj) {\n                obj.languages = [];\n                this.readChildNodes(node, obj.languages);\n            },\n            \"Default\": function(node, languages) {\n                var language = {isDefault: true};\n                this.readChildNodes(node, language);\n                languages.push(language);\n            },\n            \"Supported\": function(node, languages) {\n                var language = {};\n                this.readChildNodes(node, language);     \n                languages.push(language);\n            }\n        },\n        \"ows\": OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers[\"ows\"]\n    },    \n    \n    CLASS_NAME: \"OpenLayers.Format.WPSCapabilities.v1_0_0\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WPSCapabilities.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n \nOpenLayers.Format.WPSCapabilities = OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC, {\n    \n        defaultVersion: \"1.0.0\",\n    \n    \n        \n    CLASS_NAME: \"OpenLayers.Format.WPSCapabilities\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WPSDescribeProcess/v1_0_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n \n\nOpenLayers.Format.WPSDescribeProcess.v1_0_0 = OpenLayers.Class(\n    OpenLayers.Format.XML, {\n    \n        namespaces: {\n        wps: \"http://www.opengis.net/wps/1.0.0\",\n        ows: \"http://www.opengis.net/ows/1.1\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\"\n    },\n\n        errorProperty: \"processDescriptions\",\n\n        schemaLocation: \"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd\",\n\n        defaultPrefix: \"wps\",\n\n        regExes: {\n        trimSpace: (/^\\s*|\\s*$/g),\n        removeSpace: (/\\s*/g),\n        splitSpace: (/\\s+/),\n        trimComma: (/\\s*,\\s*/g)\n    },\n    \n    \n        read: function(data) {\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        if(data && data.nodeType == 9) {\n            data = data.documentElement;\n        }\n        var info = {};\n        this.readNode(data, info);\n        return info;\n    },\n\n        readers: {\n        \"wps\": {\n            \"ProcessDescriptions\": function(node, obj) {\n                obj.processDescriptions = {};\n                this.readChildNodes(node, obj.processDescriptions);\n            },\n            \"ProcessDescription\": function(node, processDescriptions) {\n                var processVersion = this.getAttributeNS(node, this.namespaces.wps, \"processVersion\");\n                var processDescription = {\n                    processVersion: processVersion,\n                    statusSupported: (node.getAttribute(\"statusSupported\") === \"true\"),\n                    storeSupported: (node.getAttribute(\"storeSupported\") === \"true\")\n                };\n                this.readChildNodes(node, processDescription);\n                processDescriptions[processDescription.identifier] = processDescription;\n            },\n            \"DataInputs\": function(node, processDescription) {\n                processDescription.dataInputs = [];\n                this.readChildNodes(node, processDescription.dataInputs);\n            },\n            \"ProcessOutputs\": function(node, processDescription) {\n                processDescription.processOutputs = [];\n                this.readChildNodes(node, processDescription.processOutputs);\n            },\n            \"Output\": function(node, processOutputs) {\n                var output = {};\n                this.readChildNodes(node, output);\n                processOutputs.push(output);\n            },\n            \"ComplexOutput\": function(node, output) {\n                output.complexOutput = {};\n                this.readChildNodes(node, output.complexOutput);\n            },\n            \"LiteralOutput\": function(node, output) {\n                output.literalOutput = {};\n                this.readChildNodes(node, output.literalOutput);\n            },\n            \"Input\": function(node, dataInputs) {\n                var input = {\n                    maxOccurs: parseInt(node.getAttribute(\"maxOccurs\")),\n                    minOccurs: parseInt(node.getAttribute(\"minOccurs\"))\n                };\n                this.readChildNodes(node, input);\n                dataInputs.push(input);\n            },\n            \"BoundingBoxData\": function(node, input) {\n                input.boundingBoxData = {};\n                this.readChildNodes(node, input.boundingBoxData);\n            },\n            \"CRS\": function(node, obj) {\n                if (!obj.CRSs) {\n                    obj.CRSs = {};\n                }\n                obj.CRSs[this.getChildValue(node)] = true;\n            },\n            \"LiteralData\": function(node, input) {\n                input.literalData = {};\n                this.readChildNodes(node, input.literalData);\n            },\n            \"ComplexData\": function(node, input) {\n                input.complexData = {};\n                this.readChildNodes(node,  input.complexData);\n            },\n            \"Default\": function(node, complexData) {\n                complexData[\"default\"] = {};\n                this.readChildNodes(node,  complexData[\"default\"]);\n            },\n            \"Supported\": function(node, complexData) {\n                complexData[\"supported\"] = {};\n                this.readChildNodes(node,  complexData[\"supported\"]);\n            },\n            \"Format\": function(node, obj) {\n                var format = {};\n                this.readChildNodes(node, format);\n                if (!obj.formats) {\n                    obj.formats = {};\n                }\n                obj.formats[format.mimeType] = true;\n            },\n            \"MimeType\": function(node, format) {\n                format.mimeType = this.getChildValue(node);\n            }\n        },\n        \"ows\": OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers[\"ows\"]\n    },\n    \n    CLASS_NAME: \"OpenLayers.Format.WPSDescribeProcess\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WPSDescribeProcess.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n \n\nOpenLayers.Format.WPSDescribeProcess = OpenLayers.Class(\n    OpenLayers.Format.XML.VersionedOGC, {\n \n\n        defaultVersion: \"1.0.0\",\n\n    \n    \n    CLASS_NAME: \"OpenLayers.Format.WPSDescribeProcess\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/WPSExecute.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.WPSExecute = OpenLayers.Class(OpenLayers.Format.XML,\n                                            OpenLayers.Format.Filter.v1_1_0, {\n    \n        namespaces: {\n        ows: \"http://www.opengis.net/ows/1.1\",\n        gml: \"http://www.opengis.net/gml\",\n        wps: \"http://www.opengis.net/wps/1.0.0\",\n        wfs: \"http://www.opengis.net/wfs\",\n        ogc: \"http://www.opengis.net/ogc\",\n        wcs: \"http://www.opengis.net/wcs\",\n        xlink: \"http://www.w3.org/1999/xlink\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\"\n    },\n\n        regExes: {\n        trimSpace: (/^\\s*|\\s*$/g),\n        removeSpace: (/\\s*/g),\n        splitSpace: (/\\s+/),\n        trimComma: (/\\s*,\\s*/g)\n    },\n\n        VERSION: \"1.0.0\",\n\n        schemaLocation: \"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd\",\n\n    schemaLocationAttr: function(options) {\n        return undefined;\n    },\n\n    \n        write: function(options) {\n        var doc;\n        if (OpenLayers.Format.XML.supportActiveX) {\n            doc = new ActiveXObject(\"Microsoft.XMLDOM\");\n            this.xmldom = doc;\n        } else {\n            doc = document.implementation.createDocument(\"\", \"\", null);\n        }\n        var node = this.writeNode(\"wps:Execute\", options, doc);\n        this.setAttributeNS(\n            node, this.namespaces.xsi,\n            \"xsi:schemaLocation\", this.schemaLocation\n        );\n        return OpenLayers.Format.XML.prototype.write.apply(this, [node]);\n    }, \n\n        read: function(data) {\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        if(data && data.nodeType == 9) {\n            data = data.documentElement;\n        }\n        var info = {};\n        this.readNode(data, info);\n        return info;\n    },\n\n        writers: {\n        \"wps\": {\n            \"Execute\": function(options) {\n                var node = this.createElementNSPlus(\"wps:Execute\", {\n                    attributes: {\n                        version: this.VERSION,\n                        service: 'WPS'\n                    } \n                }); \n                this.writeNode(\"ows:Identifier\", options.identifier, node);\n                this.writeNode(\"wps:DataInputs\", options.dataInputs, node);\n                this.writeNode(\"wps:ResponseForm\", options.responseForm, node);\n                return node; \n            },\n            \"ResponseForm\": function(responseForm) {\n                var node = this.createElementNSPlus(\"wps:ResponseForm\", {});\n                if (responseForm.rawDataOutput) {\n                    this.writeNode(\"wps:RawDataOutput\", responseForm.rawDataOutput, node);\n                }\n                if (responseForm.responseDocument) {\n                    this.writeNode(\"wps:ResponseDocument\", responseForm.responseDocument, node);\n                }\n                return node;\n            },\n            \"ResponseDocument\": function(responseDocument) {\n                var node = this.createElementNSPlus(\"wps:ResponseDocument\", {\n                    attributes: {\n                        storeExecuteResponse: responseDocument.storeExecuteResponse,\n                        lineage: responseDocument.lineage,\n                        status: responseDocument.status\n                    }\n                });\n                if (responseDocument.outputs) {\n                    for (var i = 0, len = responseDocument.outputs.length; i < len; i++) {\n                        this.writeNode(\"wps:Output\", responseDocument.outputs[i], node);\n                    }\n                }\n                return node;\n            },\n            \"Output\": function(output) {\n                var node = this.createElementNSPlus(\"wps:Output\", {\n                    attributes: {\n                        asReference: output.asReference,\n                        mimeType: output.mimeType,\n                        encoding: output.encoding,\n                        schema: output.schema\n                    }\n                });\n                this.writeNode(\"ows:Identifier\", output.identifier, node);\n                this.writeNode(\"ows:Title\", output.title, node);\n                this.writeNode(\"ows:Abstract\", output[\"abstract\"], node);\n                return node;\n            },\n            \"RawDataOutput\": function(rawDataOutput) {\n                var node = this.createElementNSPlus(\"wps:RawDataOutput\", {\n                    attributes: {\n                        mimeType: rawDataOutput.mimeType,\n                        encoding: rawDataOutput.encoding,\n                        schema: rawDataOutput.schema\n                    }\n                });\n                this.writeNode(\"ows:Identifier\", rawDataOutput.identifier, node);\n                return node;\n            },\n            \"DataInputs\": function(dataInputs) {\n                var node = this.createElementNSPlus(\"wps:DataInputs\", {});\n                for (var i=0, ii=dataInputs.length; i<ii; ++i) {\n                    this.writeNode(\"wps:Input\", dataInputs[i], node);\n                }\n                return node;\n            },\n            \"Input\": function(input) {\n                var node = this.createElementNSPlus(\"wps:Input\", {});\n                this.writeNode(\"ows:Identifier\", input.identifier, node);\n                if (input.title) {\n                    this.writeNode(\"ows:Title\", input.title, node);\n                }\n                if (input.data) {\n                    this.writeNode(\"wps:Data\", input.data, node);\n                }\n                if (input.reference) {\n                    this.writeNode(\"wps:Reference\", input.reference, node);\n                }\n                if (input.boundingBoxData) {\n                    this.writeNode(\"wps:BoundingBoxData\", input.boundingBoxData, node);\n                }\n                return node;\n            },\n            \"Data\": function(data) {\n                var node = this.createElementNSPlus(\"wps:Data\", {});\n                if (data.literalData) {\n                    this.writeNode(\"wps:LiteralData\", data.literalData, node);\n                } else if (data.complexData) {\n                    this.writeNode(\"wps:ComplexData\", data.complexData, node);\n                } else if (data.boundingBoxData) {\n                    this.writeNode(\"ows:BoundingBox\", data.boundingBoxData, node);\n                }\n                return node;\n            },\n            \"LiteralData\": function(literalData) {\n                var node = this.createElementNSPlus(\"wps:LiteralData\", {\n                    attributes: {\n                        uom: literalData.uom\n                    },\n                    value: literalData.value\n                });\n                return node;\n            },\n            \"ComplexData\": function(complexData) {\n                var node = this.createElementNSPlus(\"wps:ComplexData\", {\n                    attributes: {\n                        mimeType: complexData.mimeType,\n                        encoding: complexData.encoding,\n                        schema: complexData.schema\n                    } \n                });\n                var data = complexData.value;\n                if (typeof data === \"string\") {\n                    node.appendChild(\n                        this.getXMLDoc().createCDATASection(complexData.value)\n                    );\n                } else {\n                    node.appendChild(data);\n                }\n                return node;\n            },\n            \"Reference\": function(reference) {\n                var node = this.createElementNSPlus(\"wps:Reference\", {\n                    attributes: {\n                        mimeType: reference.mimeType,\n                        \"xlink:href\": reference.href,\n                        method: reference.method,\n                        encoding: reference.encoding,\n                        schema: reference.schema\n                    }\n                });\n                if (reference.body) {\n                    this.writeNode(\"wps:Body\", reference.body, node);\n                }\n                return node;\n            },\n            \"BoundingBoxData\": function(node, obj) {\n                this.writers['ows']['BoundingBox'].apply(this, [node, obj, \"wps:BoundingBoxData\"]);\n            },\n            \"Body\": function(body) {\n                var node = this.createElementNSPlus(\"wps:Body\", {});\n                if (body.wcs) {\n                    this.writeNode(\"wcs:GetCoverage\", body.wcs, node);\n                }\n                else if (body.wfs) {\n                    this.featureType = body.wfs.featureType;\n                    this.version = body.wfs.version;\n                    this.writeNode(\"wfs:GetFeature\", body.wfs, node);\n                } else {\n                    this.writeNode(\"wps:Execute\", body, node);\n                }\n                return node;                \n            }\n        },\n        \"wcs\": OpenLayers.Format.WCSGetCoverage.prototype.writers.wcs,\n        \"wfs\": OpenLayers.Format.WFST.v1_1_0.prototype.writers.wfs,\n        \"ogc\": OpenLayers.Format.Filter.v1_1_0.prototype.writers.ogc,\n        \"ows\": OpenLayers.Format.OWSCommon.v1_1_0.prototype.writers.ows\n    },\n\n        readers: {\n        \"wps\": {\n            \"ExecuteResponse\": function(node, obj) {\n                obj.executeResponse = {\n                    lang: node.getAttribute(\"lang\"),\n                    statusLocation: node.getAttribute(\"statusLocation\"),\n                    serviceInstance: node.getAttribute(\"serviceInstance\"),\n                    service: node.getAttribute(\"service\")\n                };\n                this.readChildNodes(node, obj.executeResponse);\n            },\n            \"Process\":function(node,obj) {\n                obj.process = {};\n                this.readChildNodes(node, obj.process);\n            },\n            \"Status\":function(node,obj) {\n                obj.status = {\n                    creationTime: node.getAttribute(\"creationTime\")\n                };\n                this.readChildNodes(node, obj.status);\n            },\n            \"ProcessSucceeded\": function(node,obj) {\n                obj.processSucceeded = true;\n            },\n            \"ProcessOutputs\": function(node, processDescription) {\n                processDescription.processOutputs = [];\n                this.readChildNodes(node, processDescription.processOutputs);\n            },\n            \"Output\": function(node, processOutputs) {\n                var output = {};\n                this.readChildNodes(node, output);\n                processOutputs.push(output);\n            },\n            \"Reference\": function(node, output) {\n                output.reference = {\n                    href: node.getAttribute(\"href\"),\n                    mimeType: node.getAttribute(\"mimeType\"),\n                    encoding: node.getAttribute(\"encoding\"),\n                    schema: node.getAttribute(\"schema\")\n                };\n            },\n            \"Data\": function(node, output) {\n                output.data = {};\n                this.readChildNodes(node, output);\n            },\n            \"LiteralData\": function(node, output) {\n                output.literalData = {\n                    dataType: node.getAttribute(\"dataType\"),\n                    uom: node.getAttribute(\"uom\"),\n                    value: this.getChildValue(node)\n                };\n            },\n            \"ComplexData\": function(node, output) {\n                output.complexData = {\n                    mimeType: node.getAttribute(\"mimeType\"),\n                    schema: node.getAttribute(\"schema\"),\n                    encoding: node.getAttribute(\"encoding\"),\n                    value: \"\"\n                };\n                if (this.isSimpleContent(node)) {\n                    var child;\n                    for(child=node.firstChild; child; child=child.nextSibling) {\n                        switch(child.nodeType) {\n                            case 3: // text node\n                            case 4: // cdata section\n                                output.complexData.value += child.nodeValue;\n                        }\n                    }\n                }\n                else {\n                    for(child=node.firstChild; child; child=child.nextSibling) {\n                        if (child.nodeType == 1) {\n                            output.complexData.value = child;\n                        }\n                    }\n                }\n\n            },\n            \"BoundingBox\": function(node, output) {\n                output.boundingBoxData = {\n                    dimensions: node.getAttribute(\"dimensions\"),\n                    crs: node.getAttribute(\"crs\")\n                };\n                this.readChildNodes(node, output.boundingBoxData);\n            }\n        },\n        \"ows\": OpenLayers.Format.OWSCommon.v1_1_0.prototype.readers[\"ows\"]\n    },\n    \n    CLASS_NAME: \"OpenLayers.Format.WPSExecute\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/XLS/v1.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.XLS.v1 = OpenLayers.Class(OpenLayers.Format.XML, {\n    \n        namespaces: {\n        xls: \"http://www.opengis.net/xls\",\n        gml: \"http://www.opengis.net/gml\",\n        xsi: \"http://www.w3.org/2001/XMLSchema-instance\"\n    },\n\n        regExes: {\n        trimSpace: (/^\\s*|\\s*$/g),\n        removeSpace: (/\\s*/g),\n        splitSpace: (/\\s+/),\n        trimComma: (/\\s*,\\s*/g)\n    },\n\n        xy: true,\n    \n        defaultPrefix: \"xls\",\n\n        schemaLocation: null,\n    \n        \n        read: function(data, options) {\n        options = OpenLayers.Util.applyDefaults(options, this.options);\n        var xls = {};\n        this.readChildNodes(data, xls);\n        return xls;\n    },\n    \n        readers: {\n        \"xls\": {\n            \"XLS\": function(node, xls) {\n                xls.version = node.getAttribute(\"version\");\n                this.readChildNodes(node, xls);\n            },\n            \"Response\": function(node, xls) {\n               this.readChildNodes(node, xls);\n            },\n            \"GeocodeResponse\": function(node, xls) {\n               xls.responseLists = [];\n               this.readChildNodes(node, xls);\n            },\n            \"GeocodeResponseList\": function(node, xls) {\n                var responseList = {\n                    features: [], \n                    numberOfGeocodedAddresses: \n                        parseInt(node.getAttribute(\"numberOfGeocodedAddresses\"))\n                };\n                xls.responseLists.push(responseList);\n                this.readChildNodes(node, responseList);\n            },\n            \"GeocodedAddress\": function(node, responseList) {\n                var feature = new OpenLayers.Feature.Vector();\n                responseList.features.push(feature);\n                this.readChildNodes(node, feature);\n                feature.geometry = feature.components[0];\n            },\n            \"GeocodeMatchCode\": function(node, feature) {\n                feature.attributes.matchCode = {\n                    accuracy: parseFloat(node.getAttribute(\"accuracy\")),\n                    matchType: node.getAttribute(\"matchType\")\n                };\n            },\n            \"Address\": function(node, feature) {\n                var address = {\n                    countryCode: node.getAttribute(\"countryCode\"),\n                    addressee: node.getAttribute(\"addressee\"),\n                    street: [],\n                    place: []\n                };\n                feature.attributes.address = address;\n                this.readChildNodes(node, address);\n            },\n            \"freeFormAddress\": function(node, address) {\n                address.freeFormAddress = this.getChildValue(node);\n            },\n            \"StreetAddress\": function(node, address) {\n                this.readChildNodes(node, address);\n            },\n            \"Building\": function(node, address) {\n                address.building = {\n                    'number': node.getAttribute(\"number\"),\n                    subdivision: node.getAttribute(\"subdivision\"),\n                    buildingName: node.getAttribute(\"buildingName\")\n                };\n            },\n            \"Street\": function(node, address) {\n                address.street.push(this.getChildValue(node));\n            },\n            \"Place\": function(node, address) {\n                address.place[node.getAttribute(\"type\")] = \n                    this.getChildValue(node);\n            },\n            \"PostalCode\": function(node, address) {\n                address.postalCode = this.getChildValue(node);\n            }\n        },\n        \"gml\": OpenLayers.Format.GML.v3.prototype.readers.gml\n    },\n    \n        write: function(request) {\n        return this.writers.xls.XLS.apply(this, [request]);\n    },\n    \n        writers: {\n        \"xls\": {\n            \"XLS\": function(request) {\n                var root = this.createElementNSPlus(\n                    \"xls:XLS\",\n                    {attributes: {\n                        \"version\": this.VERSION,\n                        \"xsi:schemaLocation\": this.schemaLocation\n                    }}\n                );\n                this.writeNode(\"RequestHeader\", request.header, root);\n                this.writeNode(\"Request\", request, root);\n                return root;\n            },\n            \"RequestHeader\": function(header) {\n                return this.createElementNSPlus(\"xls:RequestHeader\");\n            },\n            \"Request\": function(request) {\n                var node = this.createElementNSPlus(\"xls:Request\", {\n                    attributes: {\n                        methodName: \"GeocodeRequest\",\n                        requestID: request.requestID || \"\",\n                        version: this.VERSION\n                    }\n                });\n                this.writeNode(\"GeocodeRequest\", request.addresses, node);\n                return node;\n            },\n            \"GeocodeRequest\": function(addresses) {\n                var node = this.createElementNSPlus(\"xls:GeocodeRequest\");\n                for (var i=0, len=addresses.length; i<len; i++) {\n                    this.writeNode(\"Address\", addresses[i], node);\n                }\n                return node;\n            },\n            \"Address\": function(address) {\n                var node = this.createElementNSPlus(\"xls:Address\", {\n                    attributes: {\n                        countryCode: address.countryCode\n                    }\n                });\n                if (address.freeFormAddress) {\n                    this.writeNode(\"freeFormAddress\", address.freeFormAddress, node);\n                } else {\n                    if (address.street) {\n                        this.writeNode(\"StreetAddress\", address, node);\n                    }\n                    if (address.municipality) {\n                        this.writeNode(\"Municipality\", address.municipality, node);\n                    }\n                    if (address.countrySubdivision) {\n                        this.writeNode(\"CountrySubdivision\", address.countrySubdivision, node);\n                    }\n                    if (address.postalCode) {\n                        this.writeNode(\"PostalCode\", address.postalCode, node);\n                    }\n                }\n                return node;\n            },\n            \"freeFormAddress\": function(freeFormAddress) {\n                return this.createElementNSPlus(\"freeFormAddress\", \n                    {value: freeFormAddress});\n            },\n            \"StreetAddress\": function(address) {\n                var node = this.createElementNSPlus(\"xls:StreetAddress\");\n                if (address.building) {\n                    this.writeNode(node, \"Building\", address.building);\n                }\n                var street = address.street;\n                if (!(OpenLayers.Util.isArray(street))) {\n                    street = [street];\n                }\n                for (var i=0, len=street.length; i < len; i++) {\n                    this.writeNode(\"Street\", street[i], node);\n                }\n                return node;\n            },\n            \"Building\": function(building) {\n                return this.createElementNSPlus(\"xls:Building\", {\n                    attributes: {\n                        \"number\": building[\"number\"],\n                        \"subdivision\": building.subdivision,\n                        \"buildingName\": building.buildingName\n                    }\n                });\n            },\n            \"Street\": function(street) {\n                return this.createElementNSPlus(\"xls:Street\", {value: street});\n            },\n            \"Municipality\": function(municipality) {\n                return this.createElementNSPlus(\"xls:Place\", {\n                    attributes: {\n                        type: \"Municipality\"\n                    },\n                    value: municipality\n                });\n            },\n            \"CountrySubdivision\": function(countrySubdivision) {\n                return this.createElementNSPlus(\"xls:Place\", {\n                    attributes: {\n                        type: \"CountrySubdivision\"\n                    },\n                    value: countrySubdivision\n                });\n            },\n            \"PostalCode\": function(postalCode) {\n                return this.createElementNSPlus(\"xls:PostalCode\", {\n                    value: postalCode\n                });\n            }\n        }\n    },\n    \n    CLASS_NAME: \"OpenLayers.Format.XLS.v1\" \n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/XLS/v1_1_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.XLS.v1_1_0 = OpenLayers.Class(\n    OpenLayers.Format.XLS.v1, {\n    \n        VERSION: \"1.1\",\n    \n        schemaLocation: \"http://www.opengis.net/xls http://schemas.opengis.net/ols/1.1.0/LocationUtilityService.xsd\",\n\n    \n    CLASS_NAME: \"OpenLayers.Format.XLS.v1_1_0\"\n\n});\nOpenLayers.Format.XLS.v1_1 = OpenLayers.Format.XLS.v1_1_0;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/XLS.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.XLS = OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC, {\n    \n        defaultVersion: \"1.1.0\",\n \n        stringifyOutput: true,\n    \n    \n        \n    \n    CLASS_NAME: \"OpenLayers.Format.XLS\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/XML/VersionedOGC.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.XML.VersionedOGC = OpenLayers.Class(OpenLayers.Format.XML, {\n    \n        defaultVersion: null,\n    \n        version: null,\n\n        profile: null,\n\n        allowFallback: false,\n\n        name: null,\n\n        stringifyOutput: false,\n\n        parser: null,\n\n        initialize: function(options) {\n        OpenLayers.Format.XML.prototype.initialize.apply(this, [options]);\n        var className = this.CLASS_NAME;\n        this.name = className.substring(className.lastIndexOf(\".\")+1);\n    },\n\n        getVersion: function(root, options) {\n        var version;\n        if (root) {\n            version = this.version;\n            if(!version) {\n                version = root.getAttribute(\"version\");\n                if(!version) {\n                    version = this.defaultVersion;\n                }\n            }\n        } else { // write\n            version = (options && options.version) || \n                this.version || this.defaultVersion;\n        }\n        return version;\n    },\n\n        getParser: function(version) {\n        version = version || this.defaultVersion;\n        var profile = this.profile ? \"_\" + this.profile : \"\";\n        if(!this.parser || this.parser.VERSION != version) {\n            var format = OpenLayers.Format[this.name][\n                \"v\" + version.replace(/\\./g, \"_\") + profile\n            ];\n            if(!format) {\n                if (profile !== \"\" && this.allowFallback) {\n                    profile = \"\";\n                    format = OpenLayers.Format[this.name][\n                        \"v\" + version.replace(/\\./g, \"_\")\n                    ];\n                }\n                if (!format) {\n                    throw \"Can't find a \" + this.name + \" parser for version \" +\n                          version + profile;\n                }\n            }\n            this.parser = new format(this.options);\n        }\n        return this.parser;\n    },\n\n        write: function(obj, options) {\n        var version = this.getVersion(null, options);\n        this.parser = this.getParser(version);\n        var root = this.parser.write(obj, options);\n        if (this.stringifyOutput === false) {\n            return root;\n        } else {\n            return OpenLayers.Format.XML.prototype.write.apply(this, [root]);\n        }\n    },\n\n        read: function(data, options) {\n        if(typeof data == \"string\") {\n            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]);\n        }\n        var root = data.documentElement;\n        var version = this.getVersion(root);\n        this.parser = this.getParser(version);          // Select the parser\n        var obj = this.parser.read(data, options);      // Parse the data\n\n        var errorProperty = this.parser.errorProperty || null;\n        if (errorProperty !== null && obj[errorProperty] === undefined) {\n            var format = new OpenLayers.Format.OGCExceptionReport();\n            obj.error = format.read(data);\n        }\n        obj.version = version;\n        obj.requestType = this.name;\n        return obj;\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.XML.VersionedOGC\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format/XML.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format.XML = OpenLayers.Class(OpenLayers.Format, {\n    \n        namespaces: null,\n    \n        namespaceAlias: null,\n    \n        defaultPrefix: null,\n    \n        readers: {},\n    \n        writers: {},\n\n        xmldom: null,\n\n        initialize: function(options) {\n        if (OpenLayers.Format.XML.supportActiveX) {\n            this.xmldom = new ActiveXObject(\"Microsoft.XMLDOM\");\n        }\n        OpenLayers.Format.prototype.initialize.apply(this, [options]);\n        this.namespaces = OpenLayers.Util.extend({}, this.namespaces);\n        this.namespaceAlias = {};\n        for(var alias in this.namespaces) {\n            this.namespaceAlias[this.namespaces[alias]] = alias;\n        }\n    },\n    \n        destroy: function() {\n        this.xmldom = null;\n        OpenLayers.Format.prototype.destroy.apply(this, arguments);\n    },\n    \n        setNamespace: function(alias, uri) {\n        this.namespaces[alias] = uri;\n        this.namespaceAlias[uri] = alias;\n    },\n\n        read: function(text) {\n        var index = text.indexOf('<');\n        if(index > 0) {\n            text = text.substring(index);\n        }\n        var node = OpenLayers.Util.Try(\n            OpenLayers.Function.bind((\n                function() {\n                    var xmldom;\n                                        if (OpenLayers.Format.XML.supportActiveX && !this.xmldom) {\n                        xmldom = new ActiveXObject(\"Microsoft.XMLDOM\");\n                    } else {\n                        xmldom = this.xmldom;\n                        \n                    }\n                    xmldom.loadXML(text);\n                    return xmldom;\n                }\n            ), this),\n            function() {\n                return new DOMParser().parseFromString(text, 'text/xml');\n            },\n            function() {\n                var req = new XMLHttpRequest();\n                req.open(\"GET\", \"data:\" + \"text/xml\" +\n                         \";charset=utf-8,\" + encodeURIComponent(text), false);\n                if(req.overrideMimeType) {\n                    req.overrideMimeType(\"text/xml\");\n                }\n                req.send(null);\n                return req.responseXML;\n            }\n        );\n\n        if(this.keepData) {\n            this.data = node;\n        }\n\n        return node;\n    },\n\n        write: function(node) {\n        var data;\n        if(this.xmldom) {\n            data = node.xml;\n        } else {\n            var serializer = new XMLSerializer();\n            if (node.nodeType == 1) {\n                var doc = document.implementation.createDocument(\"\", \"\", null);\n                if (doc.importNode) {\n                    node = doc.importNode(node, true);\n                }\n                doc.appendChild(node);\n                data = serializer.serializeToString(doc);\n            } else {\n                data = serializer.serializeToString(node);\n            }\n        }\n        return data;\n    },\n\n        createElementNS: function(uri, name) {\n        var element;\n        if(this.xmldom) {\n            if(typeof uri == \"string\") {\n                element = this.xmldom.createNode(1, name, uri);\n            } else {\n                element = this.xmldom.createNode(1, name, \"\");\n            }\n        } else {\n            element = document.createElementNS(uri, name);\n        }\n        return element;\n    },\n\n        createDocumentFragment: function() {\n        var element;\n        if (this.xmldom) {\n            element = this.xmldom.createDocumentFragment();\n        } else {\n            element = document.createDocumentFragment();\n        }\n        return element;\n    },\n\n        createTextNode: function(text) {\n        var node;\n        if (typeof text !== \"string\") {\n            text = String(text);\n        }\n        if(this.xmldom) {\n            node = this.xmldom.createTextNode(text);\n        } else {\n            node = document.createTextNode(text);\n        }\n        return node;\n    },\n\n        getElementsByTagNameNS: function(node, uri, name) {\n        var elements = [];\n        if(node.getElementsByTagNameNS) {\n            elements = node.getElementsByTagNameNS(uri, name);\n        } else {\n            var allNodes = node.getElementsByTagName(\"*\");\n            var potentialNode, fullName;\n            for(var i=0, len=allNodes.length; i<len; ++i) {\n                potentialNode = allNodes[i];\n                fullName = (potentialNode.prefix) ?\n                           (potentialNode.prefix + \":\" + name) : name;\n                if((name == \"*\") || (fullName == potentialNode.nodeName)) {\n                    if((uri == \"*\") || (uri == potentialNode.namespaceURI)) {\n                        elements.push(potentialNode);\n                    }\n                }\n            }\n        }\n        return elements;\n    },\n\n        getAttributeNodeNS: function(node, uri, name) {\n        var attributeNode = null;\n        if(node.getAttributeNodeNS) {\n            attributeNode = node.getAttributeNodeNS(uri, name);\n        } else {\n            var attributes = node.attributes;\n            var potentialNode, fullName;\n            for(var i=0, len=attributes.length; i<len; ++i) {\n                potentialNode = attributes[i];\n                if(potentialNode.namespaceURI == uri) {\n                    fullName = (potentialNode.prefix) ?\n                               (potentialNode.prefix + \":\" + name) : name;\n                    if(fullName == potentialNode.nodeName) {\n                        attributeNode = potentialNode;\n                        break;\n                    }\n                }\n            }\n        }\n        return attributeNode;\n    },\n\n        getAttributeNS: function(node, uri, name) {\n        var attributeValue = \"\";\n        if(node.getAttributeNS) {\n            attributeValue = node.getAttributeNS(uri, name) || \"\";\n        } else {\n            var attributeNode = this.getAttributeNodeNS(node, uri, name);\n            if(attributeNode) {\n                attributeValue = attributeNode.nodeValue;\n            }\n        }\n        return attributeValue;\n    },\n    \n        getChildValue: function(node, def) {\n        var value = def || \"\";\n        if(node) {\n            for(var child=node.firstChild; child; child=child.nextSibling) {\n                switch(child.nodeType) {\n                    case 3: // text node\n                    case 4: // cdata section\n                        value += child.nodeValue;\n                }\n            }\n        }\n        return value;\n    },\n\n        isSimpleContent: function(node) {\n        var simple = true;\n        for(var child=node.firstChild; child; child=child.nextSibling) {\n            if(child.nodeType === 1) {\n                simple = false;\n                break;\n            }\n        }\n        return simple;\n    },\n    \n        contentType: function(node) {\n        var simple = false,\n            complex = false;\n            \n        var type = OpenLayers.Format.XML.CONTENT_TYPE.EMPTY;\n\n        for(var child=node.firstChild; child; child=child.nextSibling) {\n            switch(child.nodeType) {\n                case 1: // element\n                    complex = true;\n                    break;\n                case 8: // comment\n                    break;\n                default:\n                    simple = true;\n            }\n            if(complex && simple) {\n                break;\n            }\n        }\n        \n        if(complex && simple) {\n            type = OpenLayers.Format.XML.CONTENT_TYPE.MIXED;\n        } else if(complex) {\n            return OpenLayers.Format.XML.CONTENT_TYPE.COMPLEX;\n        } else if(simple) {\n            return OpenLayers.Format.XML.CONTENT_TYPE.SIMPLE;\n        }\n        return type;\n    },\n\n        hasAttributeNS: function(node, uri, name) {\n        var found = false;\n        if(node.hasAttributeNS) {\n            found = node.hasAttributeNS(uri, name);\n        } else {\n            found = !!this.getAttributeNodeNS(node, uri, name);\n        }\n        return found;\n    },\n    \n        setAttributeNS: function(node, uri, name, value) {\n        if(node.setAttributeNS) {\n            node.setAttributeNS(uri, name, value);\n        } else {\n            if(this.xmldom) {\n                if(uri) {\n                    var attribute = node.ownerDocument.createNode(\n                        2, name, uri\n                    );\n                    attribute.nodeValue = value;\n                    node.setAttributeNode(attribute);\n                } else {\n                    node.setAttribute(name, value);\n                }\n            } else {\n                throw \"setAttributeNS not implemented\";\n            }\n        }\n    },\n\n        createElementNSPlus: function(name, options) {\n        options = options || {};\n        var uri = options.uri || this.namespaces[options.prefix];\n        if(!uri) {\n            var loc = name.indexOf(\":\");\n            uri = this.namespaces[name.substring(0, loc)];\n        }\n        if(!uri) {\n            uri = this.namespaces[this.defaultPrefix];\n        }\n        var node = this.createElementNS(uri, name);\n        if(options.attributes) {\n            this.setAttributes(node, options.attributes);\n        }\n        var value = options.value;\n        if(value != null) {\n            node.appendChild(this.createTextNode(value));\n        }\n        return node;\n    },\n    \n        setAttributes: function(node, obj) {\n        var value, uri;\n        for(var name in obj) {\n            if(obj[name] != null && obj[name].toString) {\n                value = obj[name].toString();\n                uri = this.namespaces[name.substring(0, name.indexOf(\":\"))] || null;\n                this.setAttributeNS(node, uri, name, value);\n            }\n        }\n    },\n\n        getFirstElementChild: function(node) {\n        if (node.firstElementChild) {\n            return node.firstElementChild;\n        }\n        else {\n            var child = node.firstChild;\n            while (child.nodeType != 1 && (child = child.nextSibling)) {}\n            return child;\n        }\n    },\n\n        readNode: function(node, obj) {\n        if(!obj) {\n            obj = {};\n        }\n        var group = this.readers[node.namespaceURI ? this.namespaceAlias[node.namespaceURI]: this.defaultPrefix];\n        if(group) {\n            var local = node.localName || node.nodeName.split(\":\").pop();\n            var reader = group[local] || group[\"*\"];\n            if(reader) {\n                reader.apply(this, [node, obj]);\n            }\n        }\n        return obj;\n    },\n\n        readChildNodes: function(node, obj) {\n        if(!obj) {\n            obj = {};\n        }\n        var children = node.childNodes;\n        var child;\n        for(var i=0, len=children.length; i<len; ++i) {\n            child = children[i];\n            if(child.nodeType == 1) {\n                this.readNode(child, obj);\n            }\n        }\n        return obj;\n    },\n\n        writeNode: function(name, obj, parent) {\n        var prefix, local;\n        var split = name.indexOf(\":\");\n        if(split > 0) {\n            prefix = name.substring(0, split);\n            local = name.substring(split + 1);\n        } else {\n            if(parent) {\n                prefix = this.namespaceAlias[parent.namespaceURI];\n            } else {\n                prefix = this.defaultPrefix;\n            }\n            local = name;\n        }\n        var child = this.writers[prefix][local].apply(this, [obj]);\n        if(parent) {\n            parent.appendChild(child);\n        }\n        return child;\n    },\n\n        getChildEl: function(node, name, uri) {\n        return node && this.getThisOrNextEl(node.firstChild, name, uri);\n    },\n    \n        getNextEl: function(node, name, uri) {\n        return node && this.getThisOrNextEl(node.nextSibling, name, uri);\n    },\n    \n        getThisOrNextEl: function(node, name, uri) {\n        outer: for(var sibling=node; sibling; sibling=sibling.nextSibling) {\n            switch(sibling.nodeType) {\n                case 1: // Element\n                    if((!name || name === (sibling.localName || sibling.nodeName.split(\":\").pop())) &&\n                       (!uri || uri === sibling.namespaceURI)) {\n                        break outer;\n                    }\n                    sibling = null;\n                    break outer;\n                case 3: // Text\n                    if(/^\\s*$/.test(sibling.nodeValue)) {\n                        break;\n                    }\n                case 4: // CDATA\n                case 6: // ENTITY_NODE\n                case 12: // NOTATION_NODE\n                case 10: // DOCUMENT_TYPE_NODE\n                case 11: // DOCUMENT_FRAGMENT_NODE\n                    sibling = null;\n                    break outer;\n            } // ignore comments and processing instructions\n        }\n        return sibling || null;\n    },\n    \n        lookupNamespaceURI: function(node, prefix) {\n        var uri = null;\n        if(node) {\n            if(node.lookupNamespaceURI) {\n                uri = node.lookupNamespaceURI(prefix);\n            } else {\n                outer: switch(node.nodeType) {\n                    case 1: // ELEMENT_NODE\n                        if(node.namespaceURI !== null && node.prefix === prefix) {\n                            uri = node.namespaceURI;\n                            break outer;\n                        }\n                        var len = node.attributes.length;\n                        if(len) {\n                            var attr;\n                            for(var i=0; i<len; ++i) {\n                                attr = node.attributes[i];\n                                if(attr.prefix === \"xmlns\" && attr.name === \"xmlns:\" + prefix) {\n                                    uri = attr.value || null;\n                                    break outer;\n                                } else if(attr.name === \"xmlns\" && prefix === null) {\n                                    uri = attr.value || null;\n                                    break outer;\n                                }\n                            }\n                        }\n                        uri = this.lookupNamespaceURI(node.parentNode, prefix);\n                        break outer;\n                    case 2: // ATTRIBUTE_NODE\n                        uri = this.lookupNamespaceURI(node.ownerElement, prefix);\n                        break outer;\n                    case 9: // DOCUMENT_NODE\n                        uri = this.lookupNamespaceURI(node.documentElement, prefix);\n                        break outer;\n                    case 6: // ENTITY_NODE\n                    case 12: // NOTATION_NODE\n                    case 10: // DOCUMENT_TYPE_NODE\n                    case 11: // DOCUMENT_FRAGMENT_NODE\n                        break outer;\n                    default: \n                        uri =  this.lookupNamespaceURI(node.parentNode, prefix);\n                        break outer;\n                }\n            }\n        }\n        return uri;\n    },\n    \n        getXMLDoc: function() {\n        if (!OpenLayers.Format.XML.document && !this.xmldom) {\n            if (document.implementation && document.implementation.createDocument) {\n                OpenLayers.Format.XML.document =\n                    document.implementation.createDocument(\"\", \"\", null);\n            } else if (!this.xmldom && OpenLayers.Format.XML.supportActiveX) {\n                this.xmldom = new ActiveXObject(\"Microsoft.XMLDOM\");\n            }\n        }\n        return OpenLayers.Format.XML.document || this.xmldom;\n    },\n\n    CLASS_NAME: \"OpenLayers.Format.XML\" \n\n});     \n\nOpenLayers.Format.XML.CONTENT_TYPE = {EMPTY: 0, SIMPLE: 1, COMPLEX: 2, MIXED: 3};\n\nOpenLayers.Format.XML.lookupNamespaceURI = OpenLayers.Function.bind(\n    OpenLayers.Format.XML.prototype.lookupNamespaceURI,\n    OpenLayers.Format.XML.prototype\n);\n\nOpenLayers.Format.XML.document = null;\n\nOpenLayers.Format.XML.supportActiveX = (function () {\n    return (Object.getOwnPropertyDescriptor &&\n            Object.getOwnPropertyDescriptor(window, \"ActiveXObject\")) ||\n            (\"ActiveXObject\" in window);\n})();\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Format.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Format = OpenLayers.Class({\n    \n        options: null,\n    \n        externalProjection: null,\n\n        internalProjection: null,\n\n        data: null,\n\n        keepData: false,\n\n        initialize: function(options) {\n        OpenLayers.Util.extend(this, options);\n        this.options = options;\n    },\n    \n        destroy: function() {\n    },\n\n        read: function(data) {\n        throw new Error('Read not implemented.');\n    },\n    \n        write: function(object) {\n        throw new Error('Write not implemented.');\n    },\n\n    CLASS_NAME: \"OpenLayers.Format\"\n});     \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Geometry/Collection.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Geometry.Collection = OpenLayers.Class(OpenLayers.Geometry, {\n\n        components: null,\n    \n        componentTypes: null,\n\n        initialize: function (components) {\n        OpenLayers.Geometry.prototype.initialize.apply(this, arguments);\n        this.components = [];\n        if (components != null) {\n            this.addComponents(components);\n        }\n    },\n\n        destroy: function () {\n        this.components.length = 0;\n        this.components = null;\n        OpenLayers.Geometry.prototype.destroy.apply(this, arguments);\n    },\n\n        clone: function() {\n        var Constructor = OpenLayers.Util.getConstructor(this.CLASS_NAME);\n        var geometry = new Constructor();\n        for(var i=0, len=this.components.length; i<len; i++) {\n            geometry.addComponent(this.components[i].clone());\n        }\n        OpenLayers.Util.applyDefaults(geometry, this);\n        \n        return geometry;\n    },\n\n        getComponentsString: function(){\n        var strings = [];\n        for(var i=0, len=this.components.length; i<len; i++) {\n            strings.push(this.components[i].toShortString()); \n        }\n        return strings.join(\",\");\n    },\n\n        calculateBounds: function() {\n        this.bounds = null;\n        var bounds = new OpenLayers.Bounds();\n        var components = this.components;\n        if (components) {\n            for (var i=0, len=components.length; i<len; i++) {\n                bounds.extend(components[i].getBounds());\n            }\n        }\n        if (bounds.left != null && bounds.bottom != null && \n            bounds.right != null && bounds.top != null) {\n            this.setBounds(bounds);\n        }\n    },\n\n        addComponents: function(components){\n        if(!(OpenLayers.Util.isArray(components))) {\n            components = [components];\n        }\n        for(var i=0, len=components.length; i<len; i++) {\n            this.addComponent(components[i]);\n        }\n    },\n\n        removeComponents: function(components) {\n        var removed = false;\n\n        if(!(OpenLayers.Util.isArray(components))) {\n            components = [components];\n        }\n        for(var i=components.length-1; i>=0; --i) {\n            removed = this.removeComponent(components[i]) || removed;\n        }\n        return removed;\n    },\n    \n        removeComponent: function(component) {\n        \n        OpenLayers.Util.removeItem(this.components, component);\n        this.clearBounds();\n        return true;\n    },\n\n        getLength: function() {\n        var length = 0.0;\n        for (var i=0, len=this.components.length; i<len; i++) {\n            length += this.components[i].getLength();\n        }\n        return length;\n    },\n    \n        getArea: function() {\n        var area = 0.0;\n        for (var i=0, len=this.components.length; i<len; i++) {\n            area += this.components[i].getArea();\n        }\n        return area;\n    },\n\n        getGeodesicArea: function(projection) {\n        var area = 0.0;\n        for(var i=0, len=this.components.length; i<len; i++) {\n            area += this.components[i].getGeodesicArea(projection);\n        }\n        return area;\n    },\n    \n        getCentroid: function(weighted) {\n        if (!weighted) {\n            return this.components.length && this.components[0].getCentroid();\n        }\n        var len = this.components.length;\n        if (!len) {\n            return false;\n        }\n        \n        var areas = [];\n        var centroids = [];\n        var areaSum = 0;\n        var minArea = Number.MAX_VALUE;\n        var component;\n        for (var i=0; i<len; ++i) {\n            component = this.components[i];\n            var area = component.getArea();\n            var centroid = component.getCentroid(true);\n            if (isNaN(area) || isNaN(centroid.x) || isNaN(centroid.y)) {\n                continue;\n            }\n            areas.push(area);\n            areaSum += area;\n            minArea = (area < minArea && area > 0) ? area : minArea;\n            centroids.push(centroid);\n        }\n        len = areas.length;\n        if (areaSum === 0) {\n            for (var i=0; i<len; ++i) {\n                areas[i] = 1;\n            }\n            areaSum = areas.length;\n        } else {\n            for (var i=0; i<len; ++i) {\n                areas[i] /= minArea;\n            }\n            areaSum /= minArea;\n        }\n        \n        var xSum = 0, ySum = 0, centroid, area;\n        for (var i=0; i<len; ++i) {\n            centroid = centroids[i];\n            area = areas[i];\n            xSum += centroid.x * area;\n            ySum += centroid.y * area;\n        }\n        \n        return new OpenLayers.Geometry.Point(xSum/areaSum, ySum/areaSum);\n    },\n\n        getGeodesicLength: function(projection) {\n        var length = 0.0;\n        for(var i=0, len=this.components.length; i<len; i++) {\n            length += this.components[i].getGeodesicLength(projection);\n        }\n        return length;\n    },\n\n        move: function(x, y) {\n        for(var i=0, len=this.components.length; i<len; i++) {\n            this.components[i].move(x, y);\n        }\n    },\n\n        rotate: function(angle, origin) {\n        for(var i=0, len=this.components.length; i<len; ++i) {\n            this.components[i].rotate(angle, origin);\n        }\n    },\n\n        resize: function(scale, origin, ratio) {\n        for(var i=0; i<this.components.length; ++i) {\n            this.components[i].resize(scale, origin, ratio);\n        }\n        return this;\n    },\n\n        distanceTo: function(geometry, options) {\n        var edge = !(options && options.edge === false);\n        var details = edge && options && options.details;\n        var result, best, distance;\n        var min = Number.POSITIVE_INFINITY;\n        for(var i=0, len=this.components.length; i<len; ++i) {\n            result = this.components[i].distanceTo(geometry, options);\n            distance = details ? result.distance : result;\n            if(distance < min) {\n                min = distance;\n                best = result;\n                if(min == 0) {\n                    break;\n                }\n            }\n        }\n        return best;\n    },\n\n        equals: function(geometry) {\n        var equivalent = true;\n        if(!geometry || !geometry.CLASS_NAME ||\n           (this.CLASS_NAME != geometry.CLASS_NAME)) {\n            equivalent = false;\n        } else if(!(OpenLayers.Util.isArray(geometry.components)) ||\n                  (geometry.components.length != this.components.length)) {\n            equivalent = false;\n        } else {\n            for(var i=0, len=this.components.length; i<len; ++i) {\n                if(!this.components[i].equals(geometry.components[i])) {\n                    equivalent = false;\n                    break;\n                }\n            }\n        }\n        return equivalent;\n    },\n\n        transform: function(source, dest) {\n        if (source && dest) {\n            for (var i=0, len=this.components.length; i<len; i++) {  \n                var component = this.components[i];\n                component.transform(source, dest);\n            }\n            this.bounds = null;\n        }\n        return this;\n    },\n\n        intersects: function(geometry) {\n        var intersect = false;\n        for(var i=0, len=this.components.length; i<len; ++ i) {\n            intersect = geometry.intersects(this.components[i]);\n            if(intersect) {\n                break;\n            }\n        }\n        return intersect;\n    },\n\n        getVertices: function(nodes) {\n        var vertices = [];\n        for(var i=0, len=this.components.length; i<len; ++i) {\n            Array.prototype.push.apply(\n                vertices, this.components[i].getVertices(nodes)\n            );\n        }\n        return vertices;\n    },\n\n\n    CLASS_NAME: \"OpenLayers.Geometry.Collection\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Geometry/Curve.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Geometry.Curve = OpenLayers.Class(OpenLayers.Geometry.MultiPoint, {\n\n        componentTypes: [\"OpenLayers.Geometry.Point\"],\n\n        \n        getLength: function() {\n        var length = 0.0;\n        if ( this.components && (this.components.length > 1)) {\n            for(var i=1, len=this.components.length; i<len; i++) {\n                length += this.components[i-1].distanceTo(this.components[i]);\n            }\n        }\n        return length;\n    },\n\n        getGeodesicLength: function(projection) {\n        var geom = this;  // so we can work with a clone if needed\n        if(projection) {\n            var gg = new OpenLayers.Projection(\"EPSG:4326\");\n            if(!gg.equals(projection)) {\n                geom = this.clone().transform(projection, gg);\n            }\n        }\n        var length = 0.0;\n        if(geom.components && (geom.components.length > 1)) {\n            var p1, p2;\n            for(var i=1, len=geom.components.length; i<len; i++) {\n                p1 = geom.components[i-1];\n                p2 = geom.components[i];\n                length += OpenLayers.Util.distVincenty(\n                    {lon: p1.x, lat: p1.y}, {lon: p2.x, lat: p2.y}\n                );\n            }\n        }\n        return length * 1000;\n    },\n\n    CLASS_NAME: \"OpenLayers.Geometry.Curve\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Geometry/LineString.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Geometry.LineString = OpenLayers.Class(OpenLayers.Geometry.Curve, {\n\n    \n        removeComponent: function(point) {\n        var removed = this.components && (this.components.length > 2);\n        if (removed) {\n            OpenLayers.Geometry.Collection.prototype.removeComponent.apply(this, \n                                                                  arguments);\n        }\n        return removed;\n    },\n    \n        intersects: function(geometry) {\n        var intersect = false;\n        var type = geometry.CLASS_NAME;\n        if(type == \"OpenLayers.Geometry.LineString\" ||\n           type == \"OpenLayers.Geometry.LinearRing\" ||\n           type == \"OpenLayers.Geometry.Point\") {\n            var segs1 = this.getSortedSegments();\n            var segs2;\n            if(type == \"OpenLayers.Geometry.Point\") {\n                segs2 = [{\n                    x1: geometry.x, y1: geometry.y,\n                    x2: geometry.x, y2: geometry.y\n                }];\n            } else {\n                segs2 = geometry.getSortedSegments();\n            }\n            var seg1, seg1x1, seg1x2, seg1y1, seg1y2,\n                seg2, seg2y1, seg2y2;\n            outer: for(var i=0, len=segs1.length; i<len; ++i) {\n                seg1 = segs1[i];\n                seg1x1 = seg1.x1;\n                seg1x2 = seg1.x2;\n                seg1y1 = seg1.y1;\n                seg1y2 = seg1.y2;\n                inner: for(var j=0, jlen=segs2.length; j<jlen; ++j) {\n                    seg2 = segs2[j];\n                    if(seg2.x1 > seg1x2) {\n                        break;\n                    }\n                    if(seg2.x2 < seg1x1) {\n                        continue;\n                    }\n                    seg2y1 = seg2.y1;\n                    seg2y2 = seg2.y2;\n                    if(Math.min(seg2y1, seg2y2) > Math.max(seg1y1, seg1y2)) {\n                        continue;\n                    }\n                    if(Math.max(seg2y1, seg2y2) < Math.min(seg1y1, seg1y2)) {\n                        continue;\n                    }\n                    if(OpenLayers.Geometry.segmentsIntersect(seg1, seg2)) {\n                        intersect = true;\n                        break outer;\n                    }\n                }\n            }\n        } else {\n            intersect = geometry.intersects(this);\n        }\n        return intersect;\n    },\n    \n        getSortedSegments: function() {\n        var numSeg = this.components.length - 1;\n        var segments = new Array(numSeg), point1, point2;\n        for(var i=0; i<numSeg; ++i) {\n            point1 = this.components[i];\n            point2 = this.components[i + 1];\n            if(point1.x < point2.x) {\n                segments[i] = {\n                    x1: point1.x,\n                    y1: point1.y,\n                    x2: point2.x,\n                    y2: point2.y\n                };\n            } else {\n                segments[i] = {\n                    x1: point2.x,\n                    y1: point2.y,\n                    x2: point1.x,\n                    y2: point1.y\n                };\n            }\n        }\n        function byX1(seg1, seg2) {\n            return seg1.x1 - seg2.x1;\n        }\n        return segments.sort(byX1);\n    },\n    \n        splitWithSegment: function(seg, options) {\n        var edge = !(options && options.edge === false);\n        var tolerance = options && options.tolerance;\n        var lines = [];\n        var verts = this.getVertices();\n        var points = [];\n        var intersections = [];\n        var split = false;\n        var vert1, vert2, point;\n        var node, vertex, target;\n        var interOptions = {point: true, tolerance: tolerance};\n        var result = null;\n        for(var i=0, stop=verts.length-2; i<=stop; ++i) {\n            vert1 = verts[i];\n            points.push(vert1.clone());\n            vert2 = verts[i+1];\n            target = {x1: vert1.x, y1: vert1.y, x2: vert2.x, y2: vert2.y};\n            point = OpenLayers.Geometry.segmentsIntersect(\n                seg, target, interOptions\n            );\n            if(point instanceof OpenLayers.Geometry.Point) {\n                if((point.x === seg.x1 && point.y === seg.y1) ||\n                   (point.x === seg.x2 && point.y === seg.y2) ||\n                   point.equals(vert1) || point.equals(vert2)) {\n                    vertex = true;\n                } else {\n                    vertex = false;\n                }\n                if(vertex || edge) {\n                    if(!point.equals(intersections[intersections.length-1])) {\n                        intersections.push(point.clone());\n                    }\n                    if(i === 0) {\n                        if(point.equals(vert1)) {\n                            continue;\n                        }\n                    }\n                    if(point.equals(vert2)) {\n                        continue;\n                    }\n                    split = true;\n                    if(!point.equals(vert1)) {\n                        points.push(point);\n                    }\n                    lines.push(new OpenLayers.Geometry.LineString(points));\n                    points = [point.clone()];\n                }\n            }\n        }\n        if(split) {\n            points.push(vert2.clone());\n            lines.push(new OpenLayers.Geometry.LineString(points));\n        }\n        if(intersections.length > 0) {\n            var xDir = seg.x1 < seg.x2 ? 1 : -1;\n            var yDir = seg.y1 < seg.y2 ? 1 : -1;\n            result = {\n                lines: lines,\n                points: intersections.sort(function(p1, p2) {\n                    return (xDir * p1.x - xDir * p2.x) || (yDir * p1.y - yDir * p2.y);\n                })\n            };\n        }\n        return result;\n    },\n\n        split: function(target, options) {\n        var results = null;\n        var mutual = options && options.mutual;\n        var sourceSplit, targetSplit, sourceParts, targetParts;\n        if(target instanceof OpenLayers.Geometry.LineString) {\n            var verts = this.getVertices();\n            var vert1, vert2, seg, splits, lines, point;\n            var points = [];\n            sourceParts = [];\n            for(var i=0, stop=verts.length-2; i<=stop; ++i) {\n                vert1 = verts[i];\n                vert2 = verts[i+1];\n                seg = {\n                    x1: vert1.x, y1: vert1.y,\n                    x2: vert2.x, y2: vert2.y\n                };\n                targetParts = targetParts || [target];\n                if(mutual) {\n                    points.push(vert1.clone());\n                }\n                for(var j=0; j<targetParts.length; ++j) {\n                    splits = targetParts[j].splitWithSegment(seg, options);\n                    if(splits) {\n                        lines = splits.lines;\n                        if(lines.length > 0) {\n                            lines.unshift(j, 1);\n                            Array.prototype.splice.apply(targetParts, lines);\n                            j += lines.length - 2;\n                        }\n                        if(mutual) {\n                            for(var k=0, len=splits.points.length; k<len; ++k) {\n                                point = splits.points[k];\n                                if(!point.equals(vert1)) {\n                                    points.push(point);\n                                    sourceParts.push(new OpenLayers.Geometry.LineString(points));\n                                    if(point.equals(vert2)) {\n                                        points = [];\n                                    } else {\n                                        points = [point.clone()];\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n            if(mutual && sourceParts.length > 0 && points.length > 0) {\n                points.push(vert2.clone());\n                sourceParts.push(new OpenLayers.Geometry.LineString(points));\n            }\n        } else {\n            results = target.splitWith(this, options);\n        }\n        if(targetParts && targetParts.length > 1) {\n            targetSplit = true;\n        } else {\n            targetParts = [];\n        }\n        if(sourceParts && sourceParts.length > 1) {\n            sourceSplit = true;\n        } else {\n            sourceParts = [];\n        }\n        if(targetSplit || sourceSplit) {\n            if(mutual) {\n                results = [sourceParts, targetParts];\n            } else {\n                results = targetParts;\n            }\n        }\n        return results;\n    },\n\n        splitWith: function(geometry, options) {\n        return geometry.split(this, options);\n\n    },\n\n        getVertices: function(nodes) {\n        var vertices;\n        if(nodes === true) {\n            vertices = [\n                this.components[0],\n                this.components[this.components.length-1]\n            ];\n        } else if (nodes === false) {\n            vertices = this.components.slice(1, this.components.length-1);\n        } else {\n            vertices = this.components.slice();\n        }\n        return vertices;\n    },\n\n        distanceTo: function(geometry, options) {\n        var edge = !(options && options.edge === false);\n        var details = edge && options && options.details;\n        var result, best = {};\n        var min = Number.POSITIVE_INFINITY;\n        if(geometry instanceof OpenLayers.Geometry.Point) {\n            var segs = this.getSortedSegments();\n            var x = geometry.x;\n            var y = geometry.y;\n            var seg;\n            for(var i=0, len=segs.length; i<len; ++i) {\n                seg = segs[i];\n                result = OpenLayers.Geometry.distanceToSegment(geometry, seg);\n                if(result.distance < min) {\n                    min = result.distance;\n                    if(details) {\n                        best = {\n                            distance: min,\n                            x0: result.x, y0: result.y,\n                            x1: x, y1: y,\n                            index: i,\n                            indexDistance: new OpenLayers.Geometry.Point(seg.x1, seg.y1).distanceTo(geometry)\n                        };\n                    } else {\n                        best = min;\n                    }\n                    if(min === 0) {\n                        break;\n                    }\n                }\n            }\n        } else if(geometry instanceof OpenLayers.Geometry.LineString) { \n            var segs0 = this.getSortedSegments();\n            var segs1 = geometry.getSortedSegments();\n            var seg0, seg1, intersection, x0, y0;\n            var len1 = segs1.length;\n            var interOptions = {point: true};\n            outer: for(var i=0, len=segs0.length; i<len; ++i) {\n                seg0 = segs0[i];\n                x0 = seg0.x1;\n                y0 = seg0.y1;\n                for(var j=0; j<len1; ++j) {\n                    seg1 = segs1[j];\n                    intersection = OpenLayers.Geometry.segmentsIntersect(seg0, seg1, interOptions);\n                    if(intersection) {\n                        min = 0;\n                        best = {\n                            distance: 0,\n                            x0: intersection.x, y0: intersection.y,\n                            x1: intersection.x, y1: intersection.y\n                        };\n                        break outer;\n                    } else {\n                        result = OpenLayers.Geometry.distanceToSegment({x: x0, y: y0}, seg1);\n                        if(result.distance < min) {\n                            min = result.distance;\n                            best = {\n                                distance: min,\n                                x0: x0, y0: y0,\n                                x1: result.x, y1: result.y\n                            };\n                        }\n                    }\n                }\n            }\n            if(!details) {\n                best = best.distance;\n            }\n            if(min !== 0) {\n                if(seg0) {\n                    result = geometry.distanceTo(\n                        new OpenLayers.Geometry.Point(seg0.x2, seg0.y2),\n                        options\n                    );\n                    var dist = details ? result.distance : result;\n                    if(dist < min) {\n                        if(details) {\n                            best = {\n                                distance: min,\n                                x0: result.x1, y0: result.y1,\n                                x1: result.x0, y1: result.y0\n                            };\n                        } else {\n                            best = dist;\n                        }\n                    }\n                }\n            }\n        } else {\n            best = geometry.distanceTo(this, options);\n            if(details) {\n                best = {\n                    distance: best.distance,\n                    x0: best.x1, y0: best.y1,\n                    x1: best.x0, y1: best.y0\n                };\n            }\n        }\n        return best;\n    },\n    \n        simplify: function(tolerance){\n        if (this && this !== null) {\n            var points = this.getVertices();\n            if (points.length < 3) {\n                return this;\n            }\n    \n            var compareNumbers = function(a, b){\n                return (a-b);\n            };\n    \n                        var douglasPeuckerReduction = function(points, firstPoint, lastPoint, tolerance){\n                var maxDistance = 0;\n                var indexFarthest = 0;\n    \n                for (var index = firstPoint, distance; index < lastPoint; index++) {\n                    distance = perpendicularDistance(points[firstPoint], points[lastPoint], points[index]);\n                    if (distance > maxDistance) {\n                        maxDistance = distance;\n                        indexFarthest = index;\n                    }\n                }\n    \n                if (maxDistance > tolerance && indexFarthest != firstPoint) {\n                    pointIndexsToKeep.push(indexFarthest);\n                    douglasPeuckerReduction(points, firstPoint, indexFarthest, tolerance);\n                    douglasPeuckerReduction(points, indexFarthest, lastPoint, tolerance);\n                }\n            };\n    \n                        var perpendicularDistance = function(point1, point2, point){\n    \n                var area = Math.abs(0.5 * (point1.x * point2.y + point2.x * point.y + point.x * point1.y - point2.x * point1.y - point.x * point2.y - point1.x * point.y));\n                var bottom = Math.sqrt(Math.pow(point1.x - point2.x, 2) + Math.pow(point1.y - point2.y, 2));\n                var height = area / bottom * 2;\n    \n                return height;\n            };\n    \n            var firstPoint = 0;\n            var lastPoint = points.length - 1;\n            var pointIndexsToKeep = [];\n            pointIndexsToKeep.push(firstPoint);\n            pointIndexsToKeep.push(lastPoint);\n            while (points[firstPoint].equals(points[lastPoint])) {\n                lastPoint--;\n                pointIndexsToKeep.push(lastPoint);\n            }\n    \n            douglasPeuckerReduction(points, firstPoint, lastPoint, tolerance);\n            var returnPoints = [];\n            pointIndexsToKeep.sort(compareNumbers);\n            for (var index = 0; index < pointIndexsToKeep.length; index++) {\n                returnPoints.push(points[pointIndexsToKeep[index]]);\n            }\n            return new OpenLayers.Geometry.LineString(returnPoints);\n    \n        }\n        else {\n            return this;\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Geometry.LineString\"\n});\n\n\nOpenLayers.Geometry.LineString.geodesic =\n        function(interpolate, transform, squaredTolerance) {\n\n    var components = [];\n\n    var geoA = interpolate(0);\n    var geoB = interpolate(1);\n\n    var a = transform(geoA);\n    var b = transform(geoB);\n\n    var geoStack = [geoB, geoA];\n    var stack = [b, a];\n    var fractionStack = [1, 0];\n\n    var fractions = {};\n\n    var maxIterations = 1e5;\n    var geoM, m, fracA, fracB, fracM, key;\n\n    while (--maxIterations > 0 && fractionStack.length > 0) {\n        fracA = fractionStack.pop();\n        geoA = geoStack.pop();\n        a = stack.pop();\n        key = fracA.toString();\n        if (!(key in fractions)) {\n            components.push(a);\n            fractions[key] = true;\n        }\n        fracB = fractionStack.pop();\n        geoB = geoStack.pop();\n        b = stack.pop();\n        fracM = (fracA + fracB) / 2;\n        geoM = interpolate(fracM);\n        m = transform(geoM);\n        if (OpenLayers.Geometry.distanceSquaredToSegment(m, {x1: a.x, y1: a.y,\n                x2: b.x, y2: b.y}).distance < squaredTolerance) {\n            components.push(b);\n            key = fracB.toString();\n            fractions[key] = true;\n        } else {\n            fractionStack.push(fracB, fracM, fracM, fracA);\n            stack.push(b, m, m, a);\n            geoStack.push(geoB, geoM, geoM, geoA);\n        }\n    }\n\n    return new OpenLayers.Geometry.LineString(components);\n};\n\n\nOpenLayers.Geometry.LineString.geodesicMeridian =\n        function(lon, lat1, lat2, projection, squaredTolerance) {\n    var epsg4326Projection = new OpenLayers.Projection('EPSG:4326');\n    return OpenLayers.Geometry.LineString.geodesic(\n        function(frac) {\n            return new OpenLayers.Geometry.Point(\n                    lon, lat1 + ((lat2 - lat1) * frac));\n        },\n        function(point) {\n            return point.transform(epsg4326Projection, projection);\n        },\n        squaredTolerance\n  );\n};\n\n\nOpenLayers.Geometry.LineString.geodesicParallel =\n        function(lat, lon1, lon2, projection, squaredTolerance) {\n    var epsg4326Projection = new OpenLayers.Projection('EPSG:4326');\n    return OpenLayers.Geometry.LineString.geodesic(\n        function(frac) {\n            return new OpenLayers.Geometry.Point(\n                    lon1 + ((lon2 - lon1) * frac), lat);\n        },\n        function(point) {\n            return point.transform(epsg4326Projection, projection);\n        },\n        squaredTolerance\n    );\n};\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Geometry/LinearRing.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Geometry.LinearRing = OpenLayers.Class(\n  OpenLayers.Geometry.LineString, {\n\n        componentTypes: [\"OpenLayers.Geometry.Point\"],\n\n    \n        addComponent: function(point, index) {\n        var added = false;\n        var lastPoint = this.components.pop();\n        if(index != null || !point.equals(lastPoint)) {\n            added = OpenLayers.Geometry.Collection.prototype.addComponent.apply(this, \n                                                                    arguments);\n        }\n        var firstPoint = this.components[0];\n        OpenLayers.Geometry.Collection.prototype.addComponent.apply(this, \n                                                                [firstPoint]);\n        \n        return added;\n    },\n    \n        removeComponent: function(point) {\n        var removed = this.components && (this.components.length > 3);\n        if (removed) {\n            this.components.pop();\n            OpenLayers.Geometry.Collection.prototype.removeComponent.apply(this, \n                                                                    arguments);\n            var firstPoint = this.components[0];\n            OpenLayers.Geometry.Collection.prototype.addComponent.apply(this, \n                                                                [firstPoint]);\n        }\n        return removed;\n    },\n    \n        move: function(x, y) {\n        for(var i = 0, len=this.components.length; i<len - 1; i++) {\n            this.components[i].move(x, y);\n        }\n    },\n\n        rotate: function(angle, origin) {\n        for(var i=0, len=this.components.length; i<len - 1; ++i) {\n            this.components[i].rotate(angle, origin);\n        }\n    },\n\n        resize: function(scale, origin, ratio) {\n        for(var i=0, len=this.components.length; i<len - 1; ++i) {\n            this.components[i].resize(scale, origin, ratio);\n        }\n        return this;\n    },\n    \n        transform: function(source, dest) {\n        if (source && dest) {\n            for (var i=0, len=this.components.length; i<len - 1; i++) {\n                var component = this.components[i];\n                component.transform(source, dest);\n            }\n            this.bounds = null;\n        }\n        return this;\n    },\n    \n        getCentroid: function() {\n        if (this.components) {\n            var len = this.components.length;\n            if (len > 0 && len <= 2) {\n                return this.components[0].clone();\n            } else if (len > 2) {\n                var sumX = 0.0;\n                var sumY = 0.0;\n                var x0 = this.components[0].x;\n                var y0 = this.components[0].y;\n                var area = -1 * this.getArea();\n                if (area != 0) {\n                    for (var i = 0; i < len - 1; i++) {\n                        var b = this.components[i];\n                        var c = this.components[i+1];\n                        sumX += (b.x + c.x - 2 * x0) * ((b.x - x0) * (c.y - y0) - (c.x - x0) * (b.y - y0));\n                        sumY += (b.y + c.y - 2 * y0) * ((b.x - x0) * (c.y - y0) - (c.x - x0) * (b.y - y0));\n                    }\n                    var x = x0 + sumX / (6 * area);\n                    var y = y0 + sumY / (6 * area);\n                } else {\n                    for (var i = 0; i < len - 1; i++) {\n                        sumX += this.components[i].x;\n                        sumY += this.components[i].y;\n                    }\n                    var x = sumX / (len - 1);\n                    var y = sumY / (len - 1);\n                }\n                return new OpenLayers.Geometry.Point(x, y);\n            } else {\n                return null;\n            }\n        }\n    },\n\n        getArea: function() {\n        var area = 0.0;\n        if ( this.components && (this.components.length > 2)) {\n            var sum = 0.0;\n            for (var i=0, len=this.components.length; i<len - 1; i++) {\n                var b = this.components[i];\n                var c = this.components[i+1];\n                sum += (b.x + c.x) * (c.y - b.y);\n            }\n            area = - sum / 2.0;\n        }\n        return area;\n    },\n    \n        getGeodesicArea: function(projection) {\n        var ring = this;  // so we can work with a clone if needed\n        if(projection) {\n            var gg = new OpenLayers.Projection(\"EPSG:4326\");\n            if(!gg.equals(projection)) {\n                ring = this.clone().transform(projection, gg);\n            }\n        }\n        var area = 0.0;\n        var len = ring.components && ring.components.length;\n        if(len > 2) {\n            var p1, p2;\n            for(var i=0; i<len-1; i++) {\n                p1 = ring.components[i];\n                p2 = ring.components[i+1];\n                area += OpenLayers.Util.rad(p2.x - p1.x) *\n                        (2 + Math.sin(OpenLayers.Util.rad(p1.y)) +\n                        Math.sin(OpenLayers.Util.rad(p2.y)));\n            }\n            area = area * OpenLayers.Util.VincentyConstants.a * OpenLayers.Util.VincentyConstants.a / 2.0;\n        }\n        return area;\n    },\n    \n        containsPoint: function(point) {\n        var approx = OpenLayers.Number.limitSigDigs;\n        var digs = 14;\n        var px = approx(point.x, digs);\n        var py = approx(point.y, digs);\n        function getX(y, x1, y1, x2, y2) {\n            return (y - y2) * ((x2 - x1) / (y2 - y1)) + x2;\n        }\n        var numSeg = this.components.length - 1;\n        var start, end, x1, y1, x2, y2, cx, cy;\n        var crosses = 0;\n        for(var i=0; i<numSeg; ++i) {\n            start = this.components[i];\n            x1 = approx(start.x, digs);\n            y1 = approx(start.y, digs);\n            end = this.components[i + 1];\n            x2 = approx(end.x, digs);\n            y2 = approx(end.y, digs);\n            \n                        if(y1 == y2) {\n                if(py == y1) {\n                    if(x1 <= x2 && (px >= x1 && px <= x2) || // right or vert\n                       x1 >= x2 && (px <= x1 && px >= x2)) { // left or vert\n                        crosses = -1;\n                        break;\n                    }\n                }\n                continue;\n            }\n            cx = approx(getX(py, x1, y1, x2, y2), digs);\n            if(cx == px) {\n                if(y1 < y2 && (py >= y1 && py <= y2) || // upward\n                   y1 > y2 && (py <= y1 && py >= y2)) { // downward\n                    crosses = -1;\n                    break;\n                }\n            }\n            if(cx <= px) {\n                continue;\n            }\n            if(x1 != x2 && (cx < Math.min(x1, x2) || cx > Math.max(x1, x2))) {\n                continue;\n            }\n            if(y1 < y2 && (py >= y1 && py < y2) || // upward\n               y1 > y2 && (py < y1 && py >= y2)) { // downward\n                ++crosses;\n            }\n        }\n        var contained = (crosses == -1) ?\n            1 :\n            !!(crosses & 1);\n\n        return contained;\n    },\n\n        intersects: function(geometry) {\n        var intersect = false;\n        if(geometry.CLASS_NAME == \"OpenLayers.Geometry.Point\") {\n            intersect = this.containsPoint(geometry);\n        } else if(geometry.CLASS_NAME == \"OpenLayers.Geometry.LineString\") {\n            intersect = geometry.intersects(this);\n        } else if(geometry.CLASS_NAME == \"OpenLayers.Geometry.LinearRing\") {\n            intersect = OpenLayers.Geometry.LineString.prototype.intersects.apply(\n                this, [geometry]\n            );\n        } else {\n            for(var i=0, len=geometry.components.length; i<len; ++ i) {\n                intersect = geometry.components[i].intersects(this);\n                if(intersect) {\n                    break;\n                }\n            }\n        }\n        return intersect;\n    },\n\n        getVertices: function(nodes) {\n        return (nodes === true) ? [] : this.components.slice(0, this.components.length-1);\n    },\n\n    CLASS_NAME: \"OpenLayers.Geometry.LinearRing\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Geometry/MultiLineString.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Geometry.MultiLineString = OpenLayers.Class(\n  OpenLayers.Geometry.Collection, {\n\n        componentTypes: [\"OpenLayers.Geometry.LineString\"],\n\n        \n        split: function(geometry, options) {\n        var results = null;\n        var mutual = options && options.mutual;\n        var splits, sourceLine, sourceLines, sourceSplit, targetSplit;\n        var sourceParts = [];\n        var targetParts = [geometry];\n        for(var i=0, len=this.components.length; i<len; ++i) {\n            sourceLine = this.components[i];\n            sourceSplit = false;\n            for(var j=0; j < targetParts.length; ++j) { \n                splits = sourceLine.split(targetParts[j], options);\n                if(splits) {\n                    if(mutual) {\n                        sourceLines = splits[0];\n                        for(var k=0, klen=sourceLines.length; k<klen; ++k) {\n                            if(k===0 && sourceParts.length) {\n                                sourceParts[sourceParts.length-1].addComponent(\n                                    sourceLines[k]\n                                );\n                            } else {\n                                sourceParts.push(\n                                    new OpenLayers.Geometry.MultiLineString([\n                                        sourceLines[k]\n                                    ])\n                                );\n                            }\n                        }\n                        sourceSplit = true;\n                        splits = splits[1];\n                    }\n                    if(splits.length) {\n                        splits.unshift(j, 1);\n                        Array.prototype.splice.apply(targetParts, splits);\n                        break;\n                    }\n                }\n            }\n            if(!sourceSplit) {\n                if(sourceParts.length) {\n                    sourceParts[sourceParts.length-1].addComponent(\n                        sourceLine.clone()\n                    );\n                } else {\n                    sourceParts = [\n                        new OpenLayers.Geometry.MultiLineString(\n                            sourceLine.clone()\n                        )\n                    ];\n                }\n            }\n        }\n        if(sourceParts && sourceParts.length > 1) {\n            sourceSplit = true;\n        } else {\n            sourceParts = [];\n        }\n        if(targetParts && targetParts.length > 1) {\n            targetSplit = true;\n        } else {\n            targetParts = [];\n        }\n        if(sourceSplit || targetSplit) {\n            if(mutual) {\n                results = [sourceParts, targetParts];\n            } else {\n                results = targetParts;\n            }\n        }\n        return results;\n    },\n    \n        splitWith: function(geometry, options) {\n        var results = null;\n        var mutual = options && options.mutual;\n        var splits, targetLine, sourceLines, sourceSplit, targetSplit, sourceParts, targetParts;\n        if(geometry instanceof OpenLayers.Geometry.LineString) {\n            targetParts = [];\n            sourceParts = [geometry];\n            for(var i=0, len=this.components.length; i<len; ++i) {\n                targetSplit = false;\n                targetLine = this.components[i];\n                for(var j=0; j<sourceParts.length; ++j) {\n                    splits = sourceParts[j].split(targetLine, options);\n                    if(splits) {\n                        if(mutual) {\n                            sourceLines = splits[0];\n                            if(sourceLines.length) {\n                                sourceLines.unshift(j, 1);\n                                Array.prototype.splice.apply(sourceParts, sourceLines);\n                                j += sourceLines.length - 2;\n                            }\n                            splits = splits[1];\n                            if(splits.length === 0) {\n                                splits = [targetLine.clone()];\n                            }\n                        }\n                        for(var k=0, klen=splits.length; k<klen; ++k) {\n                            if(k===0 && targetParts.length) {\n                                targetParts[targetParts.length-1].addComponent(\n                                    splits[k]\n                                );\n                            } else {\n                                targetParts.push(\n                                    new OpenLayers.Geometry.MultiLineString([\n                                        splits[k]\n                                    ])\n                                );\n                            }\n                        }\n                        targetSplit = true;                    \n                    }\n                }\n                if(!targetSplit) {\n                    if(targetParts.length) {\n                        targetParts[targetParts.length-1].addComponent(\n                            targetLine.clone()\n                        );\n                    } else {\n                        targetParts = [\n                            new OpenLayers.Geometry.MultiLineString([\n                                targetLine.clone()\n                            ])\n                        ];\n                    }\n                    \n                }\n            }\n        } else {\n            results = geometry.split(this);\n        }\n        if(sourceParts && sourceParts.length > 1) {\n            sourceSplit = true;\n        } else {\n            sourceParts = [];\n        }\n        if(targetParts && targetParts.length > 1) {\n            targetSplit = true;\n        } else {\n            targetParts = [];\n        }\n        if(sourceSplit || targetSplit) {\n            if(mutual) {\n                results = [sourceParts, targetParts];\n            } else {\n                results = targetParts;\n            }\n        }\n        return results;\n    },\n\n    CLASS_NAME: \"OpenLayers.Geometry.MultiLineString\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Geometry/MultiPoint.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Geometry.MultiPoint = OpenLayers.Class(\n  OpenLayers.Geometry.Collection, {\n\n        componentTypes: [\"OpenLayers.Geometry.Point\"],\n\n    \n        addPoint: function(point, index) {\n        this.addComponent(point, index);\n    },\n    \n        removePoint: function(point){\n        this.removeComponent(point);\n    },\n\n    CLASS_NAME: \"OpenLayers.Geometry.MultiPoint\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Geometry/MultiPolygon.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Geometry.MultiPolygon = OpenLayers.Class(\n  OpenLayers.Geometry.Collection, {\n\n        componentTypes: [\"OpenLayers.Geometry.Polygon\"],\n\n    \n    CLASS_NAME: \"OpenLayers.Geometry.MultiPolygon\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Geometry/Point.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Geometry.Point = OpenLayers.Class(OpenLayers.Geometry, {\n\n        x: null,\n\n        y: null,\n\n        initialize: function(x, y) {\n        OpenLayers.Geometry.prototype.initialize.apply(this, arguments);\n        \n        this.x = parseFloat(x);\n        this.y = parseFloat(y);\n    },\n\n        clone: function(obj) {\n        if (obj == null) {\n            obj = new OpenLayers.Geometry.Point(this.x, this.y);\n        }\n        OpenLayers.Util.applyDefaults(obj, this);\n\n        return obj;\n    },\n\n        calculateBounds: function () {\n        this.bounds = new OpenLayers.Bounds(this.x, this.y,\n                                            this.x, this.y);\n    },\n\n        distanceTo: function(geometry, options) {\n        var edge = !(options && options.edge === false);\n        var details = edge && options && options.details;\n        var distance, x0, y0, x1, y1, result;\n        if(geometry instanceof OpenLayers.Geometry.Point) {\n            x0 = this.x;\n            y0 = this.y;\n            x1 = geometry.x;\n            y1 = geometry.y;\n            distance = Math.sqrt(Math.pow(x0 - x1, 2) + Math.pow(y0 - y1, 2));\n            result = !details ?\n                distance : {x0: x0, y0: y0, x1: x1, y1: y1, distance: distance};\n        } else {\n            result = geometry.distanceTo(this, options);\n            if(details) {\n                result = {\n                    x0: result.x1, y0: result.y1,\n                    x1: result.x0, y1: result.y0,\n                    distance: result.distance\n                };\n            }\n        }\n        return result;\n    },\n    \n        equals: function(geom) {\n        var equals = false;\n        if (geom != null) {\n            equals = ((this.x == geom.x && this.y == geom.y) ||\n                      (isNaN(this.x) && isNaN(this.y) && isNaN(geom.x) && isNaN(geom.y)));\n        }\n        return equals;\n    },\n    \n        toShortString: function() {\n        return (this.x + \", \" + this.y);\n    },\n    \n        move: function(x, y) {\n        this.x = this.x + x;\n        this.y = this.y + y;\n        this.clearBounds();\n    },\n\n        rotate: function(angle, origin) {\n        angle *= Math.PI / 180;\n        var radius = this.distanceTo(origin);\n        var theta = angle + Math.atan2(this.y - origin.y, this.x - origin.x);\n        this.x = origin.x + (radius * Math.cos(theta));\n        this.y = origin.y + (radius * Math.sin(theta));\n        this.clearBounds();\n    },\n    \n        getCentroid: function() {\n        return new OpenLayers.Geometry.Point(this.x, this.y);\n    },\n\n        resize: function(scale, origin, ratio) {\n        ratio = (ratio == undefined) ? 1 : ratio;\n        this.x = origin.x + (scale * ratio * (this.x - origin.x));\n        this.y = origin.y + (scale * (this.y - origin.y));\n        this.clearBounds();\n        return this;\n    },\n    \n        intersects: function(geometry) {\n        var intersect = false;\n        if(geometry.CLASS_NAME == \"OpenLayers.Geometry.Point\") {\n            intersect = this.equals(geometry);\n        } else {\n            intersect = geometry.intersects(this);\n        }\n        return intersect;\n    },\n    \n        transform: function(source, dest) {\n        if ((source && dest)) {\n            OpenLayers.Projection.transform(\n                this, source, dest); \n            this.bounds = null;\n        }       \n        return this;\n    },\n\n        getVertices: function(nodes) {\n        return [this];\n    },\n\n    CLASS_NAME: \"OpenLayers.Geometry.Point\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Geometry/Polygon.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Geometry.Polygon = OpenLayers.Class(\n  OpenLayers.Geometry.Collection, {\n\n        componentTypes: [\"OpenLayers.Geometry.LinearRing\"],\n\n    \n        getArea: function() {\n        var area = 0.0;\n        if ( this.components && (this.components.length > 0)) {\n            area += Math.abs(this.components[0].getArea());\n            for (var i=1, len=this.components.length; i<len; i++) {\n                area -= Math.abs(this.components[i].getArea());\n            }\n        }\n        return area;\n    },\n\n        getGeodesicArea: function(projection) {\n        var area = 0.0;\n        if(this.components && (this.components.length > 0)) {\n            area += Math.abs(this.components[0].getGeodesicArea(projection));\n            for(var i=1, len=this.components.length; i<len; i++) {\n                area -= Math.abs(this.components[i].getGeodesicArea(projection));\n            }\n        }\n        return area;\n    },\n\n        containsPoint: function(point) {\n        var numRings = this.components.length;\n        var contained = false;\n        if(numRings > 0) {\n            contained = this.components[0].containsPoint(point);\n            if(contained !== 1) {\n                if(contained && numRings > 1) {\n                    var hole;\n                    for(var i=1; i<numRings; ++i) {\n                        hole = this.components[i].containsPoint(point);\n                        if(hole) {\n                            if(hole === 1) {\n                                contained = 1;\n                            } else {\n                                contained = false;\n                            }                            \n                            break;\n                        }\n                    }\n                }\n            }\n        }\n        return contained;\n    },\n\n        intersects: function(geometry) {\n        var intersect = false;\n        var i, len;\n        if(geometry.CLASS_NAME == \"OpenLayers.Geometry.Point\") {\n            intersect = this.containsPoint(geometry);\n        } else if(geometry.CLASS_NAME == \"OpenLayers.Geometry.LineString\" ||\n                  geometry.CLASS_NAME == \"OpenLayers.Geometry.LinearRing\") {\n            for(i=0, len=this.components.length; i<len; ++i) {\n                intersect = geometry.intersects(this.components[i]);\n                if(intersect) {\n                    break;\n                }\n            }\n            if(!intersect) {\n                for(i=0, len=geometry.components.length; i<len; ++i) {\n                    intersect = this.containsPoint(geometry.components[i]);\n                    if(intersect) {\n                        break;\n                    }\n                }\n            }\n        } else {\n            for(i=0, len=geometry.components.length; i<len; ++ i) {\n                intersect = this.intersects(geometry.components[i]);\n                if(intersect) {\n                    break;\n                }\n            }\n        }\n        if(!intersect && geometry.CLASS_NAME == \"OpenLayers.Geometry.Polygon\") {\n            var ring = this.components[0];\n            for(i=0, len=ring.components.length; i<len; ++i) {\n                intersect = geometry.containsPoint(ring.components[i]);\n                if(intersect) {\n                    break;\n                }\n            }\n        }\n        return intersect;\n    },\n\n        distanceTo: function(geometry, options) {\n        var edge = !(options && options.edge === false);\n        var result;\n        if(!edge && this.intersects(geometry)) {\n            result = 0;\n        } else {\n            result = OpenLayers.Geometry.Collection.prototype.distanceTo.apply(\n                this, [geometry, options]\n            );\n        }\n        return result;\n    },\n\n    CLASS_NAME: \"OpenLayers.Geometry.Polygon\"\n});\n\nOpenLayers.Geometry.Polygon.createRegularPolygon = function(origin, radius, sides, rotation) {  \n    var angle = Math.PI * ((1/sides) - (1/2));\n    if(rotation) {\n        angle += (rotation / 180) * Math.PI;\n    }\n    var rotatedAngle, x, y;\n    var points = [];\n    for(var i=0; i<sides; ++i) {\n        rotatedAngle = angle + (i * 2 * Math.PI / sides);\n        x = origin.x + (radius * Math.cos(rotatedAngle));\n        y = origin.y + (radius * Math.sin(rotatedAngle));\n        points.push(new OpenLayers.Geometry.Point(x, y));\n    }\n    var ring = new OpenLayers.Geometry.LinearRing(points);\n    return new OpenLayers.Geometry.Polygon([ring]);\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Geometry.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n \n\nOpenLayers.Geometry = OpenLayers.Class({\n\n        id: null,\n\n        parent: null,\n\n        bounds: null,\n\n        initialize: function() {\n        this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME+ \"_\");\n    },\n    \n        destroy: function() {\n        this.id = null;\n        this.bounds = null;\n    },\n    \n        clone: function() {\n        return new OpenLayers.Geometry();\n    },\n    \n        setBounds: function(bounds) {\n        if (bounds) {\n            this.bounds = bounds.clone();\n        }\n    },\n    \n        clearBounds: function() {\n        this.bounds = null;\n        if (this.parent) {\n            this.parent.clearBounds();\n        }    \n    },\n    \n        extendBounds: function(newBounds){\n        var bounds = this.getBounds();\n        if (!bounds) {\n            this.setBounds(newBounds);\n        } else {\n            this.bounds.extend(newBounds);\n        }\n    },\n    \n        getBounds: function() {\n        if (this.bounds == null) {\n            this.calculateBounds();\n        }\n        return this.bounds;\n    },\n    \n        calculateBounds: function() {\n    },\n    \n        distanceTo: function(geometry, options) {\n    },\n    \n        getVertices: function(nodes) {\n    },\n\n        atPoint: function(lonlat, toleranceLon, toleranceLat) {\n        var atPoint = false;\n        var bounds = this.getBounds();\n        if ((bounds != null) && (lonlat != null)) {\n\n            var dX = (toleranceLon != null) ? toleranceLon : 0;\n            var dY = (toleranceLat != null) ? toleranceLat : 0;\n    \n            var toleranceBounds = \n                new OpenLayers.Bounds(this.bounds.left - dX,\n                                      this.bounds.bottom - dY,\n                                      this.bounds.right + dX,\n                                      this.bounds.top + dY);\n\n            atPoint = toleranceBounds.containsLonLat(lonlat);\n        }\n        return atPoint;\n    },\n    \n        getLength: function() {\n        return 0.0;\n    },\n\n        getArea: function() {\n        return 0.0;\n    },\n    \n        getCentroid: function() {\n        return null;\n    },\n\n        toString: function() {\n        var string;\n        if (OpenLayers.Format && OpenLayers.Format.WKT) {\n            string = OpenLayers.Format.WKT.prototype.write(\n                new OpenLayers.Feature.Vector(this)\n            );\n        } else {\n            string = Object.prototype.toString.call(this);\n        }\n        return string;\n    },\n\n    CLASS_NAME: \"OpenLayers.Geometry\"\n});\n\nOpenLayers.Geometry.fromWKT = function(wkt) {\n    var geom;\n    if (OpenLayers.Format && OpenLayers.Format.WKT) {\n        var format = OpenLayers.Geometry.fromWKT.format;\n        if (!format) {\n            format = new OpenLayers.Format.WKT();\n            OpenLayers.Geometry.fromWKT.format = format;\n        }\n        var result = format.read(wkt);\n        if (result instanceof OpenLayers.Feature.Vector) {\n            geom = result.geometry;\n        } else if (OpenLayers.Util.isArray(result)) {\n            var len = result.length;\n            var components = new Array(len);\n            for (var i=0; i<len; ++i) {\n                components[i] = result[i].geometry;\n            }\n            geom = new OpenLayers.Geometry.Collection(components);\n        }\n    }\n    return geom;\n};\n    \nOpenLayers.Geometry.segmentsIntersect = function(seg1, seg2, options) {\n    var point = options && options.point;\n    var tolerance = options && options.tolerance;\n    var intersection = false;\n    var x11_21 = seg1.x1 - seg2.x1;\n    var y11_21 = seg1.y1 - seg2.y1;\n    var x12_11 = seg1.x2 - seg1.x1;\n    var y12_11 = seg1.y2 - seg1.y1;\n    var y22_21 = seg2.y2 - seg2.y1;\n    var x22_21 = seg2.x2 - seg2.x1;\n    var d = (y22_21 * x12_11) - (x22_21 * y12_11);\n    var n1 = (x22_21 * y11_21) - (y22_21 * x11_21);\n    var n2 = (x12_11 * y11_21) - (y12_11 * x11_21);\n    if(d == 0) {\n        if(n1 == 0 && n2 == 0) {\n            intersection = true;\n        }\n    } else {\n        var along1 = n1 / d;\n        var along2 = n2 / d;\n        if(along1 >= 0 && along1 <= 1 && along2 >=0 && along2 <= 1) {\n            if(!point) {\n                intersection = true;\n            } else {\n                var x = seg1.x1 + (along1 * x12_11);\n                var y = seg1.y1 + (along1 * y12_11);\n                intersection = new OpenLayers.Geometry.Point(x, y);\n            }\n        }\n    }\n    if(tolerance) {\n        var dist;\n        if(intersection) {\n            if(point) {\n                var segs = [seg1, seg2];\n                var seg, x, y;\n                outer: for(var i=0; i<2; ++i) {\n                    seg = segs[i];\n                    for(var j=1; j<3; ++j) {\n                        x = seg[\"x\" + j];\n                        y = seg[\"y\" + j];\n                        dist = Math.sqrt(\n                            Math.pow(x - intersection.x, 2) +\n                            Math.pow(y - intersection.y, 2)\n                        );\n                        if(dist < tolerance) {\n                            intersection.x = x;\n                            intersection.y = y;\n                            break outer;\n                        }\n                    }\n                }\n                \n            }\n        } else {\n            var segs = [seg1, seg2];\n            var source, target, x, y, p, result;\n            outer: for(var i=0; i<2; ++i) {\n                source = segs[i];\n                target = segs[(i+1)%2];\n                for(var j=1; j<3; ++j) {\n                    p = {x: source[\"x\"+j], y: source[\"y\"+j]};\n                    result = OpenLayers.Geometry.distanceToSegment(p, target);\n                    if(result.distance < tolerance) {\n                        if(point) {\n                            intersection = new OpenLayers.Geometry.Point(p.x, p.y);\n                        } else {\n                            intersection = true;\n                        }\n                        break outer;\n                    }\n                }\n            }\n        }\n    }\n    return intersection;\n};\n\nOpenLayers.Geometry.distanceToSegment = function(point, segment) {\n    var result = OpenLayers.Geometry.distanceSquaredToSegment(point, segment);\n    result.distance = Math.sqrt(result.distance);\n    return result;\n};\n\nOpenLayers.Geometry.distanceSquaredToSegment = function(point, segment) {\n    var x0 = point.x;\n    var y0 = point.y;\n    var x1 = segment.x1;\n    var y1 = segment.y1;\n    var x2 = segment.x2;\n    var y2 = segment.y2;\n    var dx = x2 - x1;\n    var dy = y2 - y1;\n    var along = (dx == 0 && dy == 0) ? 0 : ((dx * (x0 - x1)) + (dy * (y0 - y1))) /\n                (Math.pow(dx, 2) + Math.pow(dy, 2));\n    var x, y;\n    if(along <= 0.0) {\n        x = x1;\n        y = y1;\n    } else if(along >= 1.0) {\n        x = x2;\n        y = y2;\n    } else {\n        x = x1 + along * dx;\n        y = y1 + along * dy;\n    }\n    return {\n        distance: Math.pow(x - x0, 2) + Math.pow(y - y0, 2),\n        x: x, y: y,\n        along: along\n    };\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Handler/Box.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Handler.Box = OpenLayers.Class(OpenLayers.Handler, {\n\n        dragHandler: null,\n\n        boxDivClassName: 'olHandlerBoxZoomBox',\n    \n        boxOffsets: null,\n\n        initialize: function(control, callbacks, options) {\n        OpenLayers.Handler.prototype.initialize.apply(this, arguments);\n        this.dragHandler = new OpenLayers.Handler.Drag(\n            this, \n            {\n                down: this.startBox, \n                move: this.moveBox, \n                out: this.removeBox,\n                up: this.endBox\n            }, \n            {keyMask: this.keyMask}\n        );\n    },\n\n        destroy: function() {\n        OpenLayers.Handler.prototype.destroy.apply(this, arguments);\n        if (this.dragHandler) {\n            this.dragHandler.destroy();\n            this.dragHandler = null;\n        }            \n    },\n\n        setMap: function (map) {\n        OpenLayers.Handler.prototype.setMap.apply(this, arguments);\n        if (this.dragHandler) {\n            this.dragHandler.setMap(map);\n        }\n    },\n\n        startBox: function (xy) {\n        this.callback(\"start\", []);\n        this.zoomBox = OpenLayers.Util.createDiv('zoomBox', {\n            x: -9999, y: -9999\n        });\n        this.zoomBox.className = this.boxDivClassName;                                         \n        this.zoomBox.style.zIndex = this.map.Z_INDEX_BASE[\"Popup\"] - 1;\n        \n        this.map.viewPortDiv.appendChild(this.zoomBox);\n        \n        OpenLayers.Element.addClass(\n            this.map.viewPortDiv, \"olDrawBox\"\n        );\n    },\n\n        moveBox: function (xy) {\n        var startX = this.dragHandler.start.x;\n        var startY = this.dragHandler.start.y;\n        var deltaX = Math.abs(startX - xy.x);\n        var deltaY = Math.abs(startY - xy.y);\n\n        var offset = this.getBoxOffsets();\n        this.zoomBox.style.width = (deltaX + offset.width + 1) + \"px\";\n        this.zoomBox.style.height = (deltaY + offset.height + 1) + \"px\";\n        this.zoomBox.style.left = (xy.x < startX ?\n            startX - deltaX - offset.left : startX - offset.left) + \"px\";\n        this.zoomBox.style.top = (xy.y < startY ?\n            startY - deltaY - offset.top : startY - offset.top) + \"px\";\n    },\n\n        endBox: function(end) {\n        var result;\n        if (Math.abs(this.dragHandler.start.x - end.x) > 5 ||    \n            Math.abs(this.dragHandler.start.y - end.y) > 5) {   \n            var start = this.dragHandler.start;\n            var top = Math.min(start.y, end.y);\n            var bottom = Math.max(start.y, end.y);\n            var left = Math.min(start.x, end.x);\n            var right = Math.max(start.x, end.x);\n            result = new OpenLayers.Bounds(left, bottom, right, top);\n        } else {\n            result = this.dragHandler.start.clone(); // i.e. OL.Pixel\n        } \n        this.removeBox();\n\n        this.callback(\"done\", [result]);\n    },\n\n        removeBox: function() {\n        this.map.viewPortDiv.removeChild(this.zoomBox);\n        this.zoomBox = null;\n        this.boxOffsets = null;\n        OpenLayers.Element.removeClass(\n            this.map.viewPortDiv, \"olDrawBox\"\n        );\n\n    },\n\n        activate: function () {\n        if (OpenLayers.Handler.prototype.activate.apply(this, arguments)) {\n            this.dragHandler.activate();\n            return true;\n        } else {\n            return false;\n        }\n    },\n\n        deactivate: function () {\n        if (OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {\n            if (this.dragHandler.deactivate()) {\n                if (this.zoomBox) {\n                    this.removeBox();\n                }\n            }\n            return true;\n        } else {\n            return false;\n        }\n    },\n    \n        getBoxOffsets: function() {\n        if (!this.boxOffsets) {\n            var testDiv = document.createElement(\"div\");\n            testDiv.style.position = \"absolute\";\n            testDiv.style.border = \"1px solid black\";\n            testDiv.style.width = \"3px\";\n            document.body.appendChild(testDiv);\n            var w3cBoxModel = testDiv.clientWidth == 3;\n            document.body.removeChild(testDiv);\n            \n            var left = parseInt(OpenLayers.Element.getStyle(this.zoomBox,\n                \"border-left-width\"));\n            var right = parseInt(OpenLayers.Element.getStyle(\n                this.zoomBox, \"border-right-width\"));\n            var top = parseInt(OpenLayers.Element.getStyle(this.zoomBox,\n                \"border-top-width\"));\n            var bottom = parseInt(OpenLayers.Element.getStyle(\n                this.zoomBox, \"border-bottom-width\"));\n            this.boxOffsets = {\n                left: left,\n                right: right,\n                top: top,\n                bottom: bottom,\n                width: w3cBoxModel === false ? left + right : 0,\n                height: w3cBoxModel === false ? top + bottom : 0\n            };\n        }\n        return this.boxOffsets;\n    },\n  \n    CLASS_NAME: \"OpenLayers.Handler.Box\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Handler/Click.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Handler.Click = OpenLayers.Class(OpenLayers.Handler, {\n        delay: 300,\n    \n        single: true,\n    \n        'double': false,\n    \n        pixelTolerance: 0,\n        \n        dblclickTolerance: 13,\n        \n        stopSingle: false,\n    \n        stopDouble: false,\n\n        timerId: null,\n    \n        down: null,\n\n        last: null,\n\n        first: null,\n\n        rightclickTimerId: null,\n    \n        \n        touchstart: function(evt) {\n        this.startTouch();\n        this.down = this.getEventInfo(evt);\n        this.last = this.getEventInfo(evt);\n        return true;\n    },\n    \n        touchmove: function(evt) {\n        this.last = this.getEventInfo(evt);\n        return true;\n    },\n\n        touchend: function(evt) {\n        if (this.down) {\n            evt.xy = this.last.xy;\n            evt.lastTouches = this.last.touches;\n            this.handleSingle(evt);\n            this.down = null;\n        }\n        return true;\n    },\n\n        mousedown: function(evt) {\n        this.down = this.getEventInfo(evt);\n        this.last = this.getEventInfo(evt);\n        return true;\n    },\n\n        mouseup: function (evt) {\n        var propagate = true;\n        if (this.checkModifiers(evt) && this.control.handleRightClicks &&\n           OpenLayers.Event.isRightClick(evt)) {\n            propagate = this.rightclick(evt);\n        }\n\n        return propagate;\n    },\n    \n        rightclick: function(evt) {\n        if(this.passesTolerance(evt)) {\n           if(this.rightclickTimerId != null) {\n                this.clearTimer();\n                this.callback('dblrightclick', [evt]);\n                return !this.stopDouble;\n            } else { \n                var clickEvent = this['double'] ?\n                    OpenLayers.Util.extend({}, evt) : \n                    this.callback('rightclick', [evt]);\n\n                var delayedRightCall = OpenLayers.Function.bind(\n                    this.delayedRightCall, \n                    this, \n                    clickEvent\n                );\n                this.rightclickTimerId = window.setTimeout(\n                    delayedRightCall, this.delay\n                );\n            } \n        }\n        return !this.stopSingle;\n    },\n    \n        delayedRightCall: function(evt) {\n        this.rightclickTimerId = null;\n        if (evt) {\n           this.callback('rightclick', [evt]);\n        }\n    },\n    \n        click: function(evt) {\n        if (!this.last) {\n            this.last = this.getEventInfo(evt);\n        }\n        this.handleSingle(evt);\n        return !this.stopSingle;\n    },\n\n        dblclick: function(evt) {\n        this.handleDouble(evt);\n        return !this.stopDouble;\n    },\n    \n        handleDouble: function(evt) {\n        if (this.passesDblclickTolerance(evt)) {\n            if (this[\"double\"]) {\n                this.callback(\"dblclick\", [evt]);\n            }\n            this.clearTimer();\n        }\n    },\n    \n        handleSingle: function(evt) {\n        if (this.passesTolerance(evt)) {\n            if (this.timerId != null) {\n                if (this.last.touches && this.last.touches.length === 1) {\n                    if (this[\"double\"]) {\n                        OpenLayers.Event.preventDefault(evt);\n                    }\n                    this.handleDouble(evt);\n                }\n                if (!this.last.touches || this.last.touches.length !== 2) {\n                    this.clearTimer();\n                }\n            } else {\n                this.first = this.getEventInfo(evt);\n                var clickEvent = this.single ?\n                    OpenLayers.Util.extend({}, evt) : null;\n                this.queuePotentialClick(clickEvent);\n            }\n        }\n    },\n    \n        queuePotentialClick: function(evt) {\n        this.timerId = window.setTimeout(\n            OpenLayers.Function.bind(this.delayedCall, this, evt),\n            this.delay\n        );\n    },\n\n        passesTolerance: function(evt) {\n        var passes = true;\n        if (this.pixelTolerance != null && this.down && this.down.xy) {\n            passes = this.pixelTolerance >= this.down.xy.distanceTo(evt.xy);\n            if (passes && this.touch && \n                this.down.touches.length === this.last.touches.length) {\n                for (var i=0, ii=this.down.touches.length; i<ii; ++i) {\n                    if (this.getTouchDistance(\n                            this.down.touches[i], \n                            this.last.touches[i]\n                        ) > this.pixelTolerance) {\n                        passes = false;\n                        break;\n                    }\n                }\n            }\n        }\n        return passes;\n    },\n    \n        getTouchDistance: function(from, to) {\n        return Math.sqrt(\n            Math.pow(from.clientX - to.clientX, 2) +\n            Math.pow(from.clientY - to.clientY, 2)\n        );\n    },\n    \n        passesDblclickTolerance: function(evt) {\n        var passes = true;\n        if (this.down && this.first) {\n            passes = this.down.xy.distanceTo(this.first.xy) <= this.dblclickTolerance;\n        }\n        return passes;\n    },\n\n        clearTimer: function() {\n        if (this.timerId != null) {\n            window.clearTimeout(this.timerId);\n            this.timerId = null;\n        }\n        if (this.rightclickTimerId != null) {\n            window.clearTimeout(this.rightclickTimerId);\n            this.rightclickTimerId = null;\n        }\n    },\n    \n        delayedCall: function(evt) {\n        this.timerId = null;\n        if (evt) {\n            this.callback(\"click\", [evt]);\n        }\n    },\n\n        getEventInfo: function(evt) {\n        var touches;\n        if (evt.touches) {\n            var len = evt.touches.length;\n            touches = new Array(len);\n            var touch;\n            for (var i=0; i<len; i++) {\n                touch = evt.touches[i];\n                touches[i] = {\n                    clientX: touch.olClientX,\n                    clientY: touch.olClientY\n                };\n            }\n        }\n        return {\n            xy: evt.xy,\n            touches: touches\n        };\n    },\n\n        deactivate: function() {\n        var deactivated = false;\n        if(OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {\n            this.clearTimer();\n            this.down = null;\n            this.first = null;\n            this.last = null;\n            deactivated = true;\n        }\n        return deactivated;\n    },\n\n    CLASS_NAME: \"OpenLayers.Handler.Click\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Handler/Drag.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Handler.Drag = OpenLayers.Class(OpenLayers.Handler, {\n  \n        started: false,\n\n        stopDown: true,\n\n        dragging: false,\n\n        last: null,\n\n        start: null,\n\n        lastMoveEvt: null,\n\n        oldOnselectstart: null,\n    \n        interval: 0,\n    \n        timeoutId: null,\n    \n        documentDrag: false,\n    \n        documentEvents: null,\n\n        initialize: function(control, callbacks, options) {\n        OpenLayers.Handler.prototype.initialize.apply(this, arguments);\n        \n        if (this.documentDrag === true) {\n            var me = this;\n            this._docMove = function(evt) {\n                me.mousemove({\n                    xy: {x: evt.clientX, y: evt.clientY},\n                    element: document\n                });\n            };\n            this._docUp = function(evt) {\n                me.mouseup({xy: {x: evt.clientX, y: evt.clientY}});\n            };\n        }\n    },\n\n    \n        dragstart: function (evt) {\n        var propagate = true;\n        this.dragging = false;\n        if (this.checkModifiers(evt) &&\n               this._pointerId == evt.pointerId &&\n               (OpenLayers.Event.isLeftClick(evt) ||\n                OpenLayers.Event.isSingleTouch(evt))) {\n            this.started = true;\n            this.start = evt.xy;\n            this.last = evt.xy;\n            OpenLayers.Element.addClass(\n                this.map.viewPortDiv, \"olDragDown\"\n            );\n            this.down(evt);\n            this.callback(\"down\", [evt.xy]);\n            OpenLayers.Event.preventDefault(evt);\n\n            if(!this.oldOnselectstart) {\n                this.oldOnselectstart = document.onselectstart ?\n                    document.onselectstart : OpenLayers.Function.True;\n            }\n            document.onselectstart = OpenLayers.Function.False;\n\n            propagate = !this.stopDown;\n        } else {\n            delete this._pointerId;\n            this.started = false;\n            this.start = null;\n            this.last = null;\n        }\n        return propagate;\n    },\n\n        dragmove: function (evt) {\n        this.lastMoveEvt = evt;\n        if (this.started && this._pointerId == evt.pointerId &&\n            !this.timeoutId && (evt.xy.x != this.last.x ||\n                                evt.xy.y != this.last.y)) {\n            if(this.documentDrag === true && this.documentEvents) {\n                if(evt.element === document) {\n                    this.adjustXY(evt);\n                    this.setEvent(evt);\n                } else {\n                    this.removeDocumentEvents();\n                }\n            }\n            if (this.interval > 0) {\n                this.timeoutId = setTimeout(\n                    OpenLayers.Function.bind(this.removeTimeout, this),\n                    this.interval);\n            }\n            this.dragging = true;\n\n            this.move(evt);\n            this.callback(\"move\", [evt.xy]);\n            if(!this.oldOnselectstart) {\n                this.oldOnselectstart = document.onselectstart;\n                document.onselectstart = OpenLayers.Function.False;\n            }\n            this.last = evt.xy;\n        }\n        return true;\n    },\n\n        dragend: function (evt) {\n        if (this.started && this._pointerId == evt.pointerId) {\n            if(this.documentDrag === true && this.documentEvents) {\n                this.adjustXY(evt);\n                this.removeDocumentEvents();\n            }\n            var dragged = (this.start != this.last);\n            this.started = false;\n            this.dragging = false;\n            delete this._pointerId;\n            OpenLayers.Element.removeClass(\n                this.map.viewPortDiv, \"olDragDown\"\n            );\n            this.up(evt);\n            this.callback(\"up\", [evt.xy]);\n            if(dragged) {\n                this.callback(\"done\", [evt.xy]);\n            }\n            document.onselectstart = this.oldOnselectstart;\n        }\n        return true;\n    },\n\n    \n        down: function(evt) {\n    },\n\n        move: function(evt) {\n    },\n\n        up: function(evt) {\n    },\n\n        out: function(evt) {\n    },\n\n    \n        mousedown: function(evt) {\n        return this.dragstart(evt);\n    },\n\n        touchstart: function(evt) {\n        this.startTouch();\n        if (!(\"_pointerId\" in this)) {\n            this._pointerId = evt.pointerId;\n        }\n        return this.dragstart(evt);\n    },\n\n        mousemove: function(evt) {\n        return this.dragmove(evt);\n    },\n\n        touchmove: function(evt) {\n        return this.dragmove(evt);\n    },\n\n        removeTimeout: function() {\n        this.timeoutId = null;\n        if(this.dragging) {\n            this.mousemove(this.lastMoveEvt);\n        }\n    },\n\n        mouseup: function(evt) {\n        return this.dragend(evt);\n    },\n\n        touchend: function(evt) {\n        evt.xy = this.last;\n        return this.dragend(evt);\n    },\n\n        mouseout: function (evt) {\n        if (this.started && OpenLayers.Util.mouseLeft(evt, this.map.viewPortDiv)) {\n            if(this.documentDrag === true) {\n                this.addDocumentEvents();\n            } else {\n                var dragged = (this.start != this.last);\n                this.started = false; \n                this.dragging = false;\n                OpenLayers.Element.removeClass(\n                    this.map.viewPortDiv, \"olDragDown\"\n                );\n                this.out(evt);\n                this.callback(\"out\", []);\n                if(dragged) {\n                    this.callback(\"done\", [evt.xy]);\n                }\n                if(document.onselectstart) {\n                    document.onselectstart = this.oldOnselectstart;\n                }\n            }\n        }\n        return true;\n    },\n\n        click: function (evt) {\n        return (this.start == this.last);\n    },\n\n        activate: function() {\n        var activated = false;\n        if(OpenLayers.Handler.prototype.activate.apply(this, arguments)) {\n            this.dragging = false;\n            activated = true;\n        }\n        return activated;\n    },\n\n        deactivate: function() {\n        var deactivated = false;\n        if(OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {\n            this.started = false;\n            this.dragging = false;\n            this.start = null;\n            this.last = null;\n            deactivated = true;\n            OpenLayers.Element.removeClass(\n                this.map.viewPortDiv, \"olDragDown\"\n            );\n        }\n        return deactivated;\n    },\n    \n        adjustXY: function(evt) {\n        var pos = OpenLayers.Util.pagePosition(this.map.viewPortDiv);\n        evt.xy.x -= pos[0];\n        evt.xy.y -= pos[1];\n    },\n    \n        addDocumentEvents: function() {\n        OpenLayers.Element.addClass(document.body, \"olDragDown\");\n        this.documentEvents = true;\n        OpenLayers.Event.observe(document, \"mousemove\", this._docMove);\n        OpenLayers.Event.observe(document, \"mouseup\", this._docUp);\n    },\n    \n        removeDocumentEvents: function() {\n        OpenLayers.Element.removeClass(document.body, \"olDragDown\");\n        this.documentEvents = false;\n        OpenLayers.Event.stopObserving(document, \"mousemove\", this._docMove);\n        OpenLayers.Event.stopObserving(document, \"mouseup\", this._docUp);\n    },\n\n    CLASS_NAME: \"OpenLayers.Handler.Drag\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Handler/Feature.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Handler.Feature = OpenLayers.Class(OpenLayers.Handler, {\n\n        EVENTMAP: {\n        'click': {'in': 'click', 'out': 'clickout'},\n        'mousemove': {'in': 'over', 'out': 'out'},\n        'dblclick': {'in': 'dblclick', 'out': null},\n        'mousedown': {'in': null, 'out': null},\n        'mouseup': {'in': null, 'out': null},\n        'touchstart': {'in': 'click', 'out': 'clickout'}\n    },\n\n        feature: null,\n\n        lastFeature: null,\n\n        down: null,\n\n        up: null,\n    \n        clickTolerance: 4,\n\n        geometryTypes: null,\n\n        stopClick: true,\n\n        stopDown: true,\n\n        stopUp: false,\n    \n        initialize: function(control, layer, callbacks, options) {\n        OpenLayers.Handler.prototype.initialize.apply(this, [control, callbacks, options]);\n        this.layer = layer;\n    },\n\n        touchstart: function(evt) {\n        this.startTouch(); \n        return OpenLayers.Event.isMultiTouch(evt) ?\n                true : this.mousedown(evt);\n    },\n\n        touchmove: function(evt) {\n        OpenLayers.Event.preventDefault(evt);\n    },\n\n        mousedown: function(evt) {\n        if (OpenLayers.Event.isLeftClick(evt) || OpenLayers.Event.isSingleTouch(evt)) {\n            this.down = evt.xy;\n        }\n        return this.handle(evt) ? !this.stopDown : true;\n    },\n    \n        mouseup: function(evt) {\n        this.up = evt.xy;\n        return this.handle(evt) ? !this.stopUp : true;\n    },\n\n        click: function(evt) {\n        return this.handle(evt) ? !this.stopClick : true;\n    },\n        \n        mousemove: function(evt) {\n        if (!this.callbacks['over'] && !this.callbacks['out']) {\n            return true;\n        }     \n        this.handle(evt);\n        return true;\n    },\n    \n        dblclick: function(evt) {\n        return !this.handle(evt);\n    },\n\n        geometryTypeMatches: function(feature) {\n        return this.geometryTypes == null ||\n            OpenLayers.Util.indexOf(this.geometryTypes,\n                                    feature.geometry.CLASS_NAME) > -1;\n    },\n\n        handle: function(evt) {\n        if(this.feature && !this.feature.layer) {\n            this.feature = null;\n        }\n        var type = evt.type;\n        var handled = false;\n        var previouslyIn = !!(this.feature); // previously in a feature\n        var click = (type == \"click\" || type == \"dblclick\" || type == \"touchstart\");\n        this.feature = this.layer.getFeatureFromEvent(evt);\n        if(this.feature && !this.feature.layer) {\n            this.feature = null;\n        }\n        if(this.lastFeature && !this.lastFeature.layer) {\n            this.lastFeature = null;\n        }\n        if(this.feature) {\n            if(type === \"touchstart\") {\n                OpenLayers.Event.preventDefault(evt);\n            }\n            var inNew = (this.feature != this.lastFeature);\n            if(this.geometryTypeMatches(this.feature)) {\n                if(previouslyIn && inNew) {\n                    if(this.lastFeature) {\n                        this.triggerCallback(type, 'out', [this.lastFeature]);\n                    }\n                    this.triggerCallback(type, 'in', [this.feature]);\n                } else if(!previouslyIn || click) {\n                    this.triggerCallback(type, 'in', [this.feature]);\n                }\n                this.lastFeature = this.feature;\n                handled = true;\n            } else {\n                if(this.lastFeature && (previouslyIn && inNew || click)) {\n                    this.triggerCallback(type, 'out', [this.lastFeature]);\n                }\n                this.feature = null;\n            }\n        } else if(this.lastFeature && (previouslyIn || click)) {\n            this.triggerCallback(type, 'out', [this.lastFeature]);\n        }\n        return handled;\n    },\n    \n        triggerCallback: function(type, mode, args) {\n        var key = this.EVENTMAP[type][mode];\n        if(key) {\n            if(type == 'click' && this.up && this.down) {\n                var dpx = Math.sqrt(\n                    Math.pow(this.up.x - this.down.x, 2) +\n                    Math.pow(this.up.y - this.down.y, 2)\n                );\n                if(dpx <= this.clickTolerance) {\n                    this.callback(key, args);\n                }\n                this.up = this.down = null;\n            } else {\n                this.callback(key, args);\n            }\n        }\n    },\n\n        activate: function() {\n        var activated = false;\n        if(OpenLayers.Handler.prototype.activate.apply(this, arguments)) {\n            this.moveLayerToTop();\n            this.map.events.on({\n                \"removelayer\": this.handleMapEvents,\n                \"changelayer\": this.handleMapEvents,\n                scope: this\n            });\n            activated = true;\n        }\n        return activated;\n    },\n    \n        deactivate: function() {\n        var deactivated = false;\n        if(OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {\n            this.moveLayerBack();\n            this.feature = null;\n            this.lastFeature = null;\n            this.down = null;\n            this.up = null;\n            this.map.events.un({\n                \"removelayer\": this.handleMapEvents,\n                \"changelayer\": this.handleMapEvents,\n                scope: this\n            });\n            deactivated = true;\n        }\n        return deactivated;\n    },\n    \n        handleMapEvents: function(evt) {\n        if (evt.type == \"removelayer\" || evt.property == \"order\") {\n            this.moveLayerToTop();\n        }\n    },\n    \n        moveLayerToTop: function() {\n        var index = Math.max(this.map.Z_INDEX_BASE['Feature'] - 1,\n            this.layer.getZIndex()) + 1;\n        this.layer.setZIndex(index);\n        \n    },\n    \n        moveLayerBack: function() {\n        var index = this.layer.getZIndex() - 1;\n        if (index >= this.map.Z_INDEX_BASE['Feature']) {\n            this.layer.setZIndex(index);\n        } else {\n            this.map.setLayerZIndex(this.layer,\n                this.map.getLayerIndex(this.layer));\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Handler.Feature\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Handler/Hover.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Handler.Hover = OpenLayers.Class(OpenLayers.Handler, {\n\n        delay: 500,\n    \n        pixelTolerance: null,\n\n        stopMove: false,\n\n        px: null,\n\n        timerId: null,\n \n    \n        mousemove: function(evt) {\n        if(this.passesTolerance(evt.xy)) {\n            this.clearTimer();\n            this.callback('move', [evt]);\n            this.px = evt.xy;\n            evt = OpenLayers.Util.extend({}, evt);\n            this.timerId = window.setTimeout(\n                OpenLayers.Function.bind(this.delayedCall, this, evt),\n                this.delay\n            );\n        }\n        return !this.stopMove;\n    },\n\n        mouseout: function(evt) {\n        if (OpenLayers.Util.mouseLeft(evt, this.map.viewPortDiv)) {\n            this.clearTimer();\n            this.callback('move', [evt]);\n        }\n        return true;\n    },\n\n        passesTolerance: function(px) {\n        var passes = true;\n        if(this.pixelTolerance && this.px) {\n            var dpx = Math.sqrt(\n                Math.pow(this.px.x - px.x, 2) +\n                Math.pow(this.px.y - px.y, 2)\n            );\n            if(dpx < this.pixelTolerance) {\n                passes = false;\n            }\n        }\n        return passes;\n    },\n\n        clearTimer: function() {\n        if(this.timerId != null) {\n            window.clearTimeout(this.timerId);\n            this.timerId = null;\n        }\n    },\n\n        delayedCall: function(evt) {\n        this.callback('pause', [evt]);\n    },\n\n        deactivate: function() {\n        var deactivated = false;\n        if(OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {\n            this.clearTimer();\n            deactivated = true;\n        }\n        return deactivated;\n    },\n\n    CLASS_NAME: \"OpenLayers.Handler.Hover\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Handler/Keyboard.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Handler.Keyboard = OpenLayers.Class(OpenLayers.Handler, {\n\n    /* http://www.quirksmode.org/js/keys.html explains key x-browser\n        key handling quirks in pretty nice detail */\n\n        KEY_EVENTS: [\"keydown\", \"keyup\"],\n\n        eventListener: null,\n\n        observeElement: null,\n\n        initialize: function(control, callbacks, options) {\n        OpenLayers.Handler.prototype.initialize.apply(this, arguments);\n        this.eventListener = OpenLayers.Function.bindAsEventListener(\n            this.handleKeyEvent, this\n        );\n    },\n    \n        destroy: function() {\n        this.deactivate();\n        this.eventListener = null;\n        OpenLayers.Handler.prototype.destroy.apply(this, arguments);\n    },\n\n        activate: function() {\n        if (OpenLayers.Handler.prototype.activate.apply(this, arguments)) {\n            this.observeElement = this.observeElement || document;\n            for (var i=0, len=this.KEY_EVENTS.length; i<len; i++) {\n                OpenLayers.Event.observe(\n                    this.observeElement, this.KEY_EVENTS[i], this.eventListener);\n            }\n            return true;\n        } else {\n            return false;\n        }\n    },\n\n        deactivate: function() {\n        var deactivated = false;\n        if (OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {\n            for (var i=0, len=this.KEY_EVENTS.length; i<len; i++) {\n                OpenLayers.Event.stopObserving(\n                    this.observeElement, this.KEY_EVENTS[i], this.eventListener);\n            }\n            deactivated = true;\n        }\n        return deactivated;\n    },\n\n        handleKeyEvent: function (evt) {\n        if (this.checkModifiers(evt)) {\n            this.callback(evt.type, [evt]);\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Handler.Keyboard\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Handler/MouseWheel.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Handler.MouseWheel = OpenLayers.Class(OpenLayers.Handler, {\n        wheelListener: null,\n\n        interval: 0,\n    \n        maxDelta: Number.POSITIVE_INFINITY,\n    \n        delta: 0,\n    \n        cumulative: true,\n    \n        initialize: function(control, callbacks, options) {\n        OpenLayers.Handler.prototype.initialize.apply(this, arguments);\n        this.wheelListener = OpenLayers.Function.bindAsEventListener(\n            this.onWheelEvent, this\n        );\n    },\n\n    \n        onWheelEvent: function(e){\n        if (!this.map || !this.checkModifiers(e)) {\n            return;\n        }\n        var overScrollableDiv = false;\n        var allowScroll = false;\n        var overMapDiv = false;\n        \n        var elem = OpenLayers.Event.element(e);\n        while((elem != null) && !overMapDiv && !overScrollableDiv) {\n\n            if (!overScrollableDiv) {\n                try {\n                    var overflow;\n                    if (elem.currentStyle) {\n                        overflow = elem.currentStyle[\"overflow\"];\n                    } else {\n                        var style = \n                            document.defaultView.getComputedStyle(elem, null);\n                        overflow = style.getPropertyValue(\"overflow\");\n                    }\n                    overScrollableDiv = ( overflow && \n                        (overflow == \"auto\") || (overflow == \"scroll\") );\n                } catch(err) {\n                }\n            }\n\n            if (!allowScroll) {\n                allowScroll = OpenLayers.Element.hasClass(elem, 'olScrollable');\n                if (!allowScroll) {\n                    for (var i = 0, len = this.map.layers.length; i < len; i++) {\n                        var layer = this.map.layers[i];\n                        if (elem == layer.div || elem == layer.pane) {\n                            allowScroll = true;\n                            break;\n                        }\n                    }\n                }\n            }\n            overMapDiv = (elem == this.map.div);\n\n            elem = elem.parentNode;\n        }\n        if (!overScrollableDiv && overMapDiv) {\n            if (allowScroll) {\n                var delta = 0;\n                \n                if (e.wheelDelta) {\n                    delta = e.wheelDelta;\n                    if (delta % 160 === 0) {\n                        delta = delta * 0.75;\n                    }\n                    delta = delta / 120;\n                } else if (e.detail) {\n                    delta = - (e.detail / Math.abs(e.detail));\n                }\n                this.delta += delta;\n\n                window.clearTimeout(this._timeoutId);\n                if(this.interval && Math.abs(this.delta) < this.maxDelta) {\n                    var evt = OpenLayers.Util.extend({}, e);\n                    this._timeoutId = window.setTimeout(\n                        OpenLayers.Function.bind(function(){\n                            this.wheelZoom(evt);\n                        }, this),\n                        this.interval\n                    );\n                } else {\n                    this.wheelZoom(e);\n                }\n            }\n            OpenLayers.Event.stop(e);\n        }\n    },\n\n        wheelZoom: function(e) {\n        var delta = this.delta;\n        this.delta = 0;\n        \n        if (delta) {\n            e.xy = this.map.events.getMousePosition(e);\n            if (delta < 0) {\n                this.callback(\"down\",\n                    [e, this.cumulative ? Math.max(-this.maxDelta, delta) : -1]);\n            } else {\n                this.callback(\"up\",\n                    [e, this.cumulative ? Math.min(this.maxDelta, delta) : 1]);\n            }\n        }\n    },\n    \n        activate: function (evt) {\n        if (OpenLayers.Handler.prototype.activate.apply(this, arguments)) {\n            var wheelListener = this.wheelListener;\n            OpenLayers.Event.observe(window, \"DOMMouseScroll\", wheelListener);\n            OpenLayers.Event.observe(window, \"mousewheel\", wheelListener);\n            OpenLayers.Event.observe(document, \"mousewheel\", wheelListener);\n            return true;\n        } else {\n            return false;\n        }\n    },\n\n        deactivate: function (evt) {\n        if (OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {\n            var wheelListener = this.wheelListener;\n            OpenLayers.Event.stopObserving(window, \"DOMMouseScroll\", wheelListener);\n            OpenLayers.Event.stopObserving(window, \"mousewheel\", wheelListener);\n            OpenLayers.Event.stopObserving(document, \"mousewheel\", wheelListener);\n            return true;\n        } else {\n            return false;\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Handler.MouseWheel\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Handler/Path.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Handler.Path = OpenLayers.Class(OpenLayers.Handler.Point, {\n    \n        line: null,\n\n        maxVertices: null,\n\n        doubleTouchTolerance: 20,\n\n        freehand: false,\n    \n        freehandToggle: 'shiftKey',\n\n        timerId: null,\n\n        redoStack: null,\n\n    \n        createFeature: function(pixel) {\n        var lonlat = this.layer.getLonLatFromViewPortPx(pixel); \n        var geometry = new OpenLayers.Geometry.Point(\n            lonlat.lon, lonlat.lat\n        );\n        this.point = new OpenLayers.Feature.Vector(geometry);\n        this.line = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.LineString([this.point.geometry])\n        );\n        this.callback(\"create\", [this.point.geometry, this.getSketch()]);\n        this.point.geometry.clearBounds();\n        this.layer.addFeatures([this.line, this.point], {silent: true});\n    },\n        \n        destroyFeature: function(force) {\n        OpenLayers.Handler.Point.prototype.destroyFeature.call(\n            this, force);\n        this.line = null;\n    },\n\n        destroyPersistedFeature: function() {\n        var layer = this.layer;\n        if(layer && layer.features.length > 2) {\n            this.layer.features[0].destroy();\n        }\n    },\n\n        removePoint: function() {\n        if(this.point) {\n            this.layer.removeFeatures([this.point]);\n        }\n    },\n    \n        addPoint: function(pixel) {\n        this.layer.removeFeatures([this.point]);\n        var lonlat = this.layer.getLonLatFromViewPortPx(pixel); \n        this.point = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat)\n        );\n        this.line.geometry.addComponent(\n            this.point.geometry, this.line.geometry.components.length\n        );\n        this.layer.addFeatures([this.point]);\n        this.callback(\"point\", [this.point.geometry, this.getGeometry()]);\n        this.callback(\"modify\", [this.point.geometry, this.getSketch()]);\n        this.drawFeature();\n        delete this.redoStack;\n    },\n    \n        insertXY: function(x, y) {\n        this.line.geometry.addComponent(\n            new OpenLayers.Geometry.Point(x, y), \n            this.getCurrentPointIndex()\n        );\n        this.drawFeature();\n        delete this.redoStack;\n    },\n\n        insertDeltaXY: function(dx, dy) {\n        var previousIndex = this.getCurrentPointIndex() - 1;\n        var p0 = this.line.geometry.components[previousIndex];\n        if (p0 && !isNaN(p0.x) && !isNaN(p0.y)) {\n            this.insertXY(p0.x + dx, p0.y + dy);\n        }\n    },\n\n        insertDirectionLength: function(direction, length) {\n        direction *= Math.PI / 180;\n        var dx = length * Math.cos(direction);\n        var dy = length * Math.sin(direction);\n        this.insertDeltaXY(dx, dy);\n    },\n\n        insertDeflectionLength: function(deflection, length) {\n        var previousIndex = this.getCurrentPointIndex() - 1;\n        if (previousIndex > 0) {\n            var p1 = this.line.geometry.components[previousIndex];\n            var p0 = this.line.geometry.components[previousIndex-1];\n            var theta = Math.atan2(p1.y - p0.y, p1.x - p0.x);\n            this.insertDirectionLength(\n                (theta * 180 / Math.PI) + deflection, length\n            );\n        }\n    },\n\n        getCurrentPointIndex: function() {\n        return this.line.geometry.components.length - 1;\n    },\n    \n    \n        undo: function() {\n        var geometry = this.line.geometry;\n        var components = geometry.components;\n        var index = this.getCurrentPointIndex() - 1;\n        var target = components[index];\n        var undone = geometry.removeComponent(target);\n        if (undone) {\n            if (this.touch && index > 0) {\n                components = geometry.components; // safety\n                var lastpt = components[index - 1];\n                var curptidx = this.getCurrentPointIndex();\n                var curpt = components[curptidx];\n                curpt.x = lastpt.x;\n                curpt.y = lastpt.y;\n            }\n            if (!this.redoStack) {\n                this.redoStack = [];\n            }\n            this.redoStack.push(target);\n            this.drawFeature();\n        }\n        return undone;\n    },\n    \n        redo: function() {\n        var target = this.redoStack && this.redoStack.pop();\n        if (target) {\n            this.line.geometry.addComponent(target, this.getCurrentPointIndex());\n            this.drawFeature();\n        }\n        return !!target;\n    },\n    \n        freehandMode: function(evt) {\n        return (this.freehandToggle && evt[this.freehandToggle]) ?\n                    !this.freehand : this.freehand;\n    },\n\n        modifyFeature: function(pixel, drawing) {\n        if(!this.line) {\n            this.createFeature(pixel);\n        }\n        var lonlat = this.layer.getLonLatFromViewPortPx(pixel); \n        this.point.geometry.x = lonlat.lon;\n        this.point.geometry.y = lonlat.lat;\n        this.callback(\"modify\", [this.point.geometry, this.getSketch(), drawing]);\n        this.point.geometry.clearBounds();\n        this.drawFeature();\n    },\n\n        drawFeature: function() {\n        this.layer.drawFeature(this.line, this.style);\n        this.layer.drawFeature(this.point, this.style);\n    },\n\n        getSketch: function() {\n        return this.line;\n    },\n\n        getGeometry: function() {\n        var geometry = this.line && this.line.geometry;\n        if(geometry && this.multi) {\n            geometry = new OpenLayers.Geometry.MultiLineString([geometry]);\n        }\n        return geometry;\n    },\n\n        touchstart: function(evt) {\n        if (this.timerId &&\n            this.passesTolerance(this.lastTouchPx, evt.xy,\n                                 this.doubleTouchTolerance)) {\n            this.finishGeometry();\n            window.clearTimeout(this.timerId);\n            this.timerId = null;\n            return false;\n        } else {\n            if (this.timerId) {\n                window.clearTimeout(this.timerId);\n                this.timerId = null;\n            }\n            this.timerId = window.setTimeout(\n                OpenLayers.Function.bind(function() {\n                    this.timerId = null;\n                }, this), 300);\n            return OpenLayers.Handler.Point.prototype.touchstart.call(this, evt);\n        }\n    },\n\n        down: function(evt) {\n        var stopDown = this.stopDown;\n        if(this.freehandMode(evt)) {\n            stopDown = true;\n            if (this.touch) {\n                this.modifyFeature(evt.xy, !!this.lastUp);\n                OpenLayers.Event.stop(evt);\n            }\n        }\n        if (!this.touch && (!this.lastDown ||\n                            !this.passesTolerance(this.lastDown, evt.xy,\n                                                  this.pixelTolerance))) {\n            this.modifyFeature(evt.xy, !!this.lastUp);\n        }\n        this.mouseDown = true;\n        this.lastDown = evt.xy;\n        this.stoppedDown = stopDown;\n        return !stopDown;\n    },\n\n        move: function (evt) {\n        if(this.stoppedDown && this.freehandMode(evt)) {\n            if(this.persist) {\n                this.destroyPersistedFeature();\n            }\n            if(this.maxVertices && this.line &&\n                    this.line.geometry.components.length === this.maxVertices) {\n                this.removePoint();\n                this.finalize();\n            } else {\n                this.addPoint(evt.xy);\n            }\n            return false;\n        }\n        if (!this.touch && (!this.mouseDown || this.stoppedDown)) {\n            this.modifyFeature(evt.xy, !!this.lastUp);\n        }\n        return true;\n    },\n    \n        up: function (evt) {\n        if (this.mouseDown && (!this.lastUp || !this.lastUp.equals(evt.xy))) {\n            if(this.stoppedDown && this.freehandMode(evt)) {\n                if (this.persist) {\n                    this.destroyPersistedFeature();\n                }\n                this.removePoint();\n                this.finalize();\n            } else {\n                if (this.passesTolerance(this.lastDown, evt.xy,\n                                         this.pixelTolerance)) {\n                    if (this.touch) {\n                        this.modifyFeature(evt.xy);\n                    }\n                    if(this.lastUp == null && this.persist) {\n                        this.destroyPersistedFeature();\n                    }\n                    this.addPoint(evt.xy);\n                    this.lastUp = evt.xy;\n                    if(this.line.geometry.components.length === this.maxVertices + 1) {\n                        this.finishGeometry();\n                    }\n                }\n            }\n        }\n        this.stoppedDown = this.stopDown;\n        this.mouseDown = false;\n        return !this.stopUp;\n    },\n\n        finishGeometry: function() {\n        var index = this.line.geometry.components.length - 1;\n        this.line.geometry.removeComponent(this.line.geometry.components[index]);\n        this.removePoint();\n        this.finalize();\n    },\n  \n        dblclick: function(evt) {\n        if(!this.freehandMode(evt)) {\n            this.finishGeometry();\n        }\n        return false;\n    },\n\n    CLASS_NAME: \"OpenLayers.Handler.Path\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Handler/Pinch.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Handler.Pinch = OpenLayers.Class(OpenLayers.Handler, {\n\n        started: false,\n\n        stopDown: false,\n\n        pinching: false,\n\n        last: null,\n\n        start: null,\n\n    \n        touchstart: function(evt) {\n        var propagate = true;\n        this.pinching = false;\n        if (OpenLayers.Event.isMultiTouch(evt)) {\n            this.started = true;\n            this.last = this.start = {\n                distance: this.getDistance(evt.touches),\n                delta: 0,\n                scale: 1\n            };\n            this.callback(\"start\", [evt, this.start]);\n            propagate = !this.stopDown;\n        } else if (this.started) {\n            return false;\n        } else {\n            this.started = false;\n            this.start = null;\n            this.last = null;\n        }\n        OpenLayers.Event.preventDefault(evt);\n        return propagate;\n    },\n\n        touchmove: function(evt) {\n        if (this.started && OpenLayers.Event.isMultiTouch(evt)) {\n            this.pinching = true;\n            var current = this.getPinchData(evt);\n            this.callback(\"move\", [evt, current]);\n            this.last = current;\n            OpenLayers.Event.stop(evt);\n        } else if (this.started) {\n            return false;\n        }\n        return true;\n    },\n\n        touchend: function(evt) {\n        if (this.started && !OpenLayers.Event.isMultiTouch(evt)) {\n            this.started = false;\n            this.pinching = false;\n            this.callback(\"done\", [evt, this.start, this.last]);\n            this.start = null;\n            this.last = null;\n            return false;\n        }\n        return true;\n    },\n\n        activate: function() {\n        var activated = false;\n        if (OpenLayers.Handler.prototype.activate.apply(this, arguments)) {\n            this.pinching = false;\n            activated = true;\n        }\n        return activated;\n    },\n\n        deactivate: function() {\n        var deactivated = false;\n        if (OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {\n            this.started = false;\n            this.pinching = false;\n            this.start = null;\n            this.last = null;\n            deactivated = true;\n        }\n        return deactivated;\n    },\n\n        getDistance: function(touches) {\n        var t0 = touches[0];\n        var t1 = touches[1];\n        return Math.sqrt(\n            Math.pow(t0.olClientX - t1.olClientX, 2) +\n            Math.pow(t0.olClientY - t1.olClientY, 2)\n        );\n    },\n\n\n        getPinchData: function(evt) {\n        var distance = this.getDistance(evt.touches);\n        var scale = distance / this.start.distance;\n        return {\n            distance: distance,\n            delta: this.last.distance - distance,\n            scale: scale\n        };\n    },\n\n    CLASS_NAME: \"OpenLayers.Handler.Pinch\"\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Handler/Point.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Handler.Point = OpenLayers.Class(OpenLayers.Handler, {\n    \n        point: null,\n\n        layer: null,\n    \n        multi: false,\n    \n        citeCompliant: false,\n    \n        mouseDown: false,\n\n        stoppedDown: null,\n\n        lastDown: null,\n\n        lastUp: null,\n\n        persist: false,\n\n        stopDown: false,\n\n        stopUp: false,\n\n        layerOptions: null,\n    \n        pixelTolerance: 5,\n\n        lastTouchPx: null,\n\n        initialize: function(control, callbacks, options) {\n        if(!(options && options.layerOptions && options.layerOptions.styleMap)) {\n            this.style = OpenLayers.Util.extend(OpenLayers.Feature.Vector.style['default'], {});\n        }\n\n        OpenLayers.Handler.prototype.initialize.apply(this, arguments);\n    },\n    \n        activate: function() {\n        if(!OpenLayers.Handler.prototype.activate.apply(this, arguments)) {\n            return false;\n        }\n        var options = OpenLayers.Util.extend({\n            displayInLayerSwitcher: false,\n            calculateInRange: OpenLayers.Function.True,\n            wrapDateLine: this.citeCompliant\n        }, this.layerOptions);\n        this.layer = new OpenLayers.Layer.Vector(this.CLASS_NAME, options);\n        this.map.addLayer(this.layer);\n        return true;\n    },\n    \n        createFeature: function(pixel) {\n        var lonlat = this.layer.getLonLatFromViewPortPx(pixel); \n        var geometry = new OpenLayers.Geometry.Point(\n            lonlat.lon, lonlat.lat\n        );\n        this.point = new OpenLayers.Feature.Vector(geometry);\n        this.callback(\"create\", [this.point.geometry, this.point]);\n        this.point.geometry.clearBounds();\n        this.layer.addFeatures([this.point], {silent: true});\n    },\n\n        deactivate: function() {\n        if(!OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {\n            return false;\n        }\n        this.cancel();\n        if (this.layer.map != null) {\n            this.destroyFeature(true);\n            this.layer.destroy(false);\n        }\n        this.layer = null;\n        return true;\n    },\n    \n        destroyFeature: function(force) {\n        if(this.layer && (force || !this.persist)) {\n            this.layer.destroyFeatures();\n        }\n        this.point = null;\n    },\n\n        destroyPersistedFeature: function() {\n        var layer = this.layer;\n        if(layer && layer.features.length > 1) {\n            this.layer.features[0].destroy();\n        }\n    },\n\n        finalize: function(cancel) {\n        var key = cancel ? \"cancel\" : \"done\";\n        this.mouseDown = false;\n        this.lastDown = null;\n        this.lastUp = null;\n        this.lastTouchPx = null;\n        this.callback(key, [this.geometryClone()]);\n        this.destroyFeature(cancel);\n    },\n\n        cancel: function() {\n        this.finalize(true);\n    },\n\n        click: function(evt) {\n        OpenLayers.Event.stop(evt);\n        return false;\n    },\n\n        dblclick: function(evt) {\n        OpenLayers.Event.stop(evt);\n        return false;\n    },\n    \n        modifyFeature: function(pixel) {\n        if(!this.point) {\n            this.createFeature(pixel);\n        }\n        var lonlat = this.layer.getLonLatFromViewPortPx(pixel); \n        this.point.geometry.x = lonlat.lon;\n        this.point.geometry.y = lonlat.lat;\n        this.callback(\"modify\", [this.point.geometry, this.point, false]);\n        this.point.geometry.clearBounds();\n        this.drawFeature();\n    },\n\n        drawFeature: function() {\n        this.layer.drawFeature(this.point, this.style);\n    },\n    \n        getGeometry: function() {\n        var geometry = this.point && this.point.geometry;\n        if(geometry && this.multi) {\n            geometry = new OpenLayers.Geometry.MultiPoint([geometry]);\n        }\n        return geometry;\n    },\n\n        geometryClone: function() {\n        var geom = this.getGeometry();\n        return geom && geom.clone();\n    },\n\n        mousedown: function(evt) {\n        return this.down(evt);\n    },\n\n        touchstart: function(evt) {\n        this.startTouch();\n        this.lastTouchPx = evt.xy;\n        return this.down(evt);\n    },\n\n        mousemove: function(evt) {\n        return this.move(evt);\n    },\n\n        touchmove: function(evt) {\n        this.lastTouchPx = evt.xy;\n        return this.move(evt);\n    },\n\n        mouseup: function(evt) {\n        return this.up(evt);\n    },\n\n        touchend: function(evt) {\n        evt.xy = this.lastTouchPx;\n        return this.up(evt);\n    },\n  \n        down: function(evt) {\n        this.mouseDown = true;\n        this.lastDown = evt.xy;\n        if(!this.touch) { // no point displayed until up on touch devices\n            this.modifyFeature(evt.xy);\n        }\n        this.stoppedDown = this.stopDown;\n        return !this.stopDown;\n    },\n\n        move: function (evt) {\n        if(!this.touch // no point displayed until up on touch devices\n           && (!this.mouseDown || this.stoppedDown)) {\n            this.modifyFeature(evt.xy);\n        }\n        return true;\n    },\n\n        up: function (evt) {\n        this.mouseDown = false;\n        this.stoppedDown = this.stopDown;\n        if(!this.checkModifiers(evt)) {\n            return true;\n        }\n        if (this.lastUp && this.lastUp.equals(evt.xy)) {\n            return true;\n        }\n        if (this.lastDown && this.passesTolerance(this.lastDown, evt.xy,\n                                                  this.pixelTolerance)) {\n            if (this.touch) {\n                this.modifyFeature(evt.xy);\n            }\n            if(this.persist) {\n                this.destroyPersistedFeature();\n            }\n            this.lastUp = evt.xy;\n            this.finalize();\n            return !this.stopUp;\n        } else {\n            return true;\n        }\n    },\n\n        mouseout: function(evt) {\n        if(OpenLayers.Util.mouseLeft(evt, this.map.viewPortDiv)) {\n            this.stoppedDown = this.stopDown;\n            this.mouseDown = false;\n        }\n    },\n\n        passesTolerance: function(pixel1, pixel2, tolerance) {\n        var passes = true;\n\n        if (tolerance != null && pixel1 && pixel2) {\n            var dist = pixel1.distanceTo(pixel2);\n            if (dist > tolerance) {\n                passes = false;\n            }\n        }\n        return passes;\n    },\n    \n    CLASS_NAME: \"OpenLayers.Handler.Point\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Handler/Polygon.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Handler.Polygon = OpenLayers.Class(OpenLayers.Handler.Path, {\n    \n        holeModifier: null,\n    \n        drawingHole: false,\n    \n        polygon: null,\n\n        \n        createFeature: function(pixel) {\n        var lonlat = this.layer.getLonLatFromViewPortPx(pixel);\n        var geometry = new OpenLayers.Geometry.Point(\n            lonlat.lon, lonlat.lat\n        );\n        this.point = new OpenLayers.Feature.Vector(geometry);\n        this.line = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.LinearRing([this.point.geometry])\n        );\n        this.polygon = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Polygon([this.line.geometry])\n        );\n        this.callback(\"create\", [this.point.geometry, this.getSketch()]);\n        this.point.geometry.clearBounds();\n        this.layer.addFeatures([this.polygon, this.point], {silent: true});\n    },\n\n        addPoint: function(pixel) {\n        if(!this.drawingHole && this.holeModifier &&\n           this.evt && this.evt[this.holeModifier]) {\n            var geometry = this.point.geometry;\n            var features = this.control.layer.features;\n            var candidate, polygon;\n            for (var i=features.length-1; i>=0; --i) {\n                candidate = features[i].geometry;\n                if ((candidate instanceof OpenLayers.Geometry.Polygon || \n                    candidate instanceof OpenLayers.Geometry.MultiPolygon) && \n                    candidate.intersects(geometry)) {\n                    polygon = features[i];\n                    this.control.layer.removeFeatures([polygon], {silent: true});\n                    this.control.layer.events.registerPriority(\n                        \"sketchcomplete\", this, this.finalizeInteriorRing\n                    );\n                    this.control.layer.events.registerPriority(\n                        \"sketchmodified\", this, this.enforceTopology\n                    );\n                    polygon.geometry.addComponent(this.line.geometry);\n                    this.polygon = polygon;\n                    this.drawingHole = true;\n                    break;\n                }\n            }\n        }\n        OpenLayers.Handler.Path.prototype.addPoint.apply(this, arguments);\n    },\n\n        getCurrentPointIndex: function() {\n        return this.line.geometry.components.length - 2;\n    },\n\n        enforceTopology: function(event) {\n        var point = event.vertex;\n        var components = this.line.geometry.components;\n        if (!this.polygon.geometry.intersects(point)) {\n            var last = components[components.length-3];\n            point.x = last.x;\n            point.y = last.y;\n        }\n    },\n\n        finishGeometry: function() {\n        var index = this.line.geometry.components.length - 2;\n        this.line.geometry.removeComponent(this.line.geometry.components[index]);\n        this.removePoint();\n        this.finalize();\n    },\n\n        finalizeInteriorRing: function() {\n        var ring = this.line.geometry;\n        var modified = (ring.getArea() !== 0);\n        if (modified) {\n            var rings = this.polygon.geometry.components;\n            for (var i=rings.length-2; i>=0; --i) {\n                if (ring.intersects(rings[i])) {\n                    modified = false;\n                    break;\n                }\n            }\n            if (modified) {\n                var target;\n                outer: for (var i=rings.length-2; i>0; --i) {\n                    var points = rings[i].components;\n                    for (var j=0, jj=points.length; j<jj; ++j) {\n                        if (ring.containsPoint(points[j])) {\n                            modified = false;\n                            break outer;\n                        }\n                    }\n                }\n            }\n        }\n        if (modified) {\n            if (this.polygon.state !== OpenLayers.State.INSERT) {\n                this.polygon.state = OpenLayers.State.UPDATE;\n            }\n        } else {\n            this.polygon.geometry.removeComponent(ring);\n        }\n        this.restoreFeature();\n        return false;\n    },\n\n        cancel: function() {\n        if (this.drawingHole) {\n            this.polygon.geometry.removeComponent(this.line.geometry);\n            this.restoreFeature(true);\n        }\n        return OpenLayers.Handler.Path.prototype.cancel.apply(this, arguments);\n    },\n    \n        restoreFeature: function(cancel) {\n        this.control.layer.events.unregister(\n            \"sketchcomplete\", this, this.finalizeInteriorRing\n        );\n        this.control.layer.events.unregister(\n            \"sketchmodified\", this, this.enforceTopology\n        );\n        this.layer.removeFeatures([this.polygon], {silent: true});\n        this.control.layer.addFeatures([this.polygon], {silent: true});\n        this.drawingHole = false;\n        if (!cancel) {\n            this.control.layer.events.triggerEvent(\n                \"sketchcomplete\", {feature : this.polygon}\n            );\n        }\n    },\n\n        destroyFeature: function(force) {\n        OpenLayers.Handler.Path.prototype.destroyFeature.call(\n            this, force);\n        this.polygon = null;\n    },\n\n        drawFeature: function() {\n        this.layer.drawFeature(this.polygon, this.style);\n        this.layer.drawFeature(this.point, this.style);\n    },\n    \n        getSketch: function() {\n        return this.polygon;\n    },\n\n        getGeometry: function() {\n        var geometry = this.polygon && this.polygon.geometry;\n        if(geometry && this.multi) {\n            geometry = new OpenLayers.Geometry.MultiPolygon([geometry]);\n        }\n        return geometry;\n    },\n\n    CLASS_NAME: \"OpenLayers.Handler.Polygon\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Handler/RegularPolygon.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Handler.RegularPolygon = OpenLayers.Class(OpenLayers.Handler.Drag, {\n    \n        sides: 4,\n\n        radius: null,\n    \n        snapAngle: null,\n    \n        snapToggle: 'shiftKey',\n    \n        layerOptions: null,\n\n        persist: false,\n\n        irregular: false,\n\n        citeCompliant: false,\n\n        angle: null,\n\n        fixedRadius: false,\n\n        feature: null,\n\n        layer: null,\n\n        origin: null,\n\n        initialize: function(control, callbacks, options) {\n        if(!(options && options.layerOptions && options.layerOptions.styleMap)) {\n            this.style = OpenLayers.Util.extend(OpenLayers.Feature.Vector.style['default'], {});\n        }\n\n        OpenLayers.Handler.Drag.prototype.initialize.apply(this,\n                                                [control, callbacks, options]);\n        this.options = (options) ? options : {};\n    },\n    \n        setOptions: function (newOptions) {\n        OpenLayers.Util.extend(this.options, newOptions);\n        OpenLayers.Util.extend(this, newOptions);\n    },\n    \n        activate: function() {\n        var activated = false;\n        if(OpenLayers.Handler.Drag.prototype.activate.apply(this, arguments)) {\n            var options = OpenLayers.Util.extend({\n                displayInLayerSwitcher: false,\n                calculateInRange: OpenLayers.Function.True,\n                wrapDateLine: this.citeCompliant\n            }, this.layerOptions);\n            this.layer = new OpenLayers.Layer.Vector(this.CLASS_NAME, options);\n            this.map.addLayer(this.layer);\n            activated = true;\n        }\n        return activated;\n    },\n\n        deactivate: function() {\n        var deactivated = false;\n        if(OpenLayers.Handler.Drag.prototype.deactivate.apply(this, arguments)) {\n            if(this.dragging) {\n                this.cancel();\n            }\n            if (this.layer.map != null) {\n                this.layer.destroy(false);\n                if (this.feature) {\n                    this.feature.destroy();\n                }\n            }\n            this.layer = null;\n            this.feature = null;\n            deactivated = true;\n        }\n        return deactivated;\n    },\n    \n        down: function(evt) {\n        this.fixedRadius = !!(this.radius);\n        var maploc = this.layer.getLonLatFromViewPortPx(evt.xy); \n        this.origin = new OpenLayers.Geometry.Point(maploc.lon, maploc.lat);\n        if(!this.fixedRadius || this.irregular) {\n            this.radius = this.map.getResolution();\n        }\n        if(this.persist) {\n            this.clear();\n        }\n        this.feature = new OpenLayers.Feature.Vector();\n        this.createGeometry();\n        this.callback(\"create\", [this.origin, this.feature]);\n        this.layer.addFeatures([this.feature], {silent: true});\n        this.layer.drawFeature(this.feature, this.style);\n    },\n    \n        move: function(evt) {\n        var maploc = this.layer.getLonLatFromViewPortPx(evt.xy); \n        var point = new OpenLayers.Geometry.Point(maploc.lon, maploc.lat);\n        if(this.irregular) {\n            var ry = Math.sqrt(2) * Math.abs(point.y - this.origin.y) / 2;\n            this.radius = Math.max(this.map.getResolution() / 2, ry);\n        } else if(this.fixedRadius) {\n            this.origin = point;\n        } else {\n            this.calculateAngle(point, evt);\n            this.radius = Math.max(this.map.getResolution() / 2,\n                                   point.distanceTo(this.origin));\n        }\n        this.modifyGeometry();\n        if(this.irregular) {\n            var dx = point.x - this.origin.x;\n            var dy = point.y - this.origin.y;\n            var ratio;\n            if(dy == 0) {\n                ratio = dx / (this.radius * Math.sqrt(2));\n            } else {\n                ratio = dx / dy;\n            }\n            this.feature.geometry.resize(1, this.origin, ratio);\n            this.feature.geometry.move(dx / 2, dy / 2);\n        }\n        this.layer.drawFeature(this.feature, this.style);\n    },\n\n        up: function(evt) {\n        this.finalize();\n        if (this.start == this.last) {\n            this.callback(\"done\", [evt.xy]);\n        }\n    },\n\n        out: function(evt) {\n        this.finalize();\n    },\n\n        createGeometry: function() {\n        this.angle = Math.PI * ((1/this.sides) - (1/2));\n        if(this.snapAngle) {\n            this.angle += this.snapAngle * (Math.PI / 180);\n        }\n        this.feature.geometry = OpenLayers.Geometry.Polygon.createRegularPolygon(\n            this.origin, this.radius, this.sides, this.snapAngle\n        );\n    },\n    \n        modifyGeometry: function() {\n        var angle, point;\n        var ring = this.feature.geometry.components[0];\n        if(ring.components.length != (this.sides + 1)) {\n            this.createGeometry();\n            ring = this.feature.geometry.components[0];\n        }\n        for(var i=0; i<this.sides; ++i) {\n            point = ring.components[i];\n            angle = this.angle + (i * 2 * Math.PI / this.sides);\n            point.x = this.origin.x + (this.radius * Math.cos(angle));\n            point.y = this.origin.y + (this.radius * Math.sin(angle));\n            point.clearBounds();\n        }\n    },\n    \n        calculateAngle: function(point, evt) {\n        var alpha = Math.atan2(point.y - this.origin.y,\n                               point.x - this.origin.x);\n        if(this.snapAngle && (this.snapToggle && !evt[this.snapToggle])) {\n            var snapAngleRad = (Math.PI / 180) * this.snapAngle;\n            this.angle = Math.round(alpha / snapAngleRad) * snapAngleRad;\n        } else {\n            this.angle = alpha;\n        }\n    },\n\n        cancel: function() {\n        this.callback(\"cancel\", null);\n        this.finalize();\n    },\n\n        finalize: function() {\n        this.origin = null;\n        this.radius = this.options.radius;\n    },\n\n        clear: function() {\n        if (this.layer) {\n            this.layer.renderer.clear();\n            this.layer.destroyFeatures();\n        }\n    },\n    \n        callback: function (name, args) {\n        if (this.callbacks[name]) {\n            this.callbacks[name].apply(this.control,\n                                       [this.feature.geometry.clone()]);\n        }\n        if(!this.persist && (name == \"done\" || name == \"cancel\")) {\n            this.clear();\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Handler.RegularPolygon\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Handler.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Handler = OpenLayers.Class({\n\n        id: null,\n        \n        control: null,\n\n        map: null,\n\n        keyMask: null,\n\n        active: false,\n    \n        evt: null,\n    \n        touch: false,\n\n        initialize: function(control, callbacks, options) {\n        OpenLayers.Util.extend(this, options);\n        this.control = control;\n        this.callbacks = callbacks;\n\n        var map = this.map || control.map;\n        if (map) {\n            this.setMap(map); \n        }\n        \n        this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + \"_\");\n    },\n    \n        setMap: function (map) {\n        this.map = map;\n    },\n\n        checkModifiers: function (evt) {\n        if(this.keyMask == null) {\n            return true;\n        }\n        /* calculate the keyboard modifier mask for this event */\n        var keyModifiers =\n            (evt.shiftKey ? OpenLayers.Handler.MOD_SHIFT : 0) |\n            (evt.ctrlKey  ? OpenLayers.Handler.MOD_CTRL  : 0) |\n            (evt.altKey   ? OpenLayers.Handler.MOD_ALT   : 0) |\n            (evt.metaKey  ? OpenLayers.Handler.MOD_META  : 0);\n    \n        /* if it differs from the handler object's key mask,\n           bail out of the event handler */\n        return (keyModifiers == this.keyMask);\n    },\n\n        activate: function() {\n        if(this.active) {\n            return false;\n        }\n        var events = OpenLayers.Events.prototype.BROWSER_EVENTS;\n        for (var i=0, len=events.length; i<len; i++) {\n            if (this[events[i]]) {\n                this.register(events[i], this[events[i]]); \n            }\n        } \n        this.active = true;\n        return true;\n    },\n    \n        deactivate: function() {\n        if(!this.active) {\n            return false;\n        }\n        var events = OpenLayers.Events.prototype.BROWSER_EVENTS;\n        for (var i=0, len=events.length; i<len; i++) {\n            if (this[events[i]]) {\n                this.unregister(events[i], this[events[i]]); \n            }\n        } \n        this.touch = false;\n        this.active = false;\n        return true;\n    },\n\n        startTouch: function() {\n        if (!this.touch) {\n            this.touch = true;\n            var events = [\n                \"mousedown\", \"mouseup\", \"mousemove\", \"click\", \"dblclick\",\n                \"mouseout\"\n            ];\n            for (var i=0, len=events.length; i<len; i++) {\n                if (this[events[i]]) {\n                    this.unregister(events[i], this[events[i]]); \n                }\n            } \n        }\n    },\n\n        callback: function (name, args) {\n        if (name && this.callbacks[name]) {\n            this.callbacks[name].apply(this.control, args);\n        }\n    },\n\n        register: function (name, method) {\n        this.map.events.registerPriority(name, this, method);\n        this.map.events.registerPriority(name, this, this.setEvent);\n    },\n\n        unregister: function (name, method) {\n        this.map.events.unregister(name, this, method);   \n        this.map.events.unregister(name, this, this.setEvent);\n    },\n    \n        setEvent: function(evt) {\n        this.evt = evt;\n        return true;\n    },\n\n        destroy: function () {\n        this.deactivate();\n        this.control = this.map = null;        \n    },\n\n    CLASS_NAME: \"OpenLayers.Handler\"\n});\n\nOpenLayers.Handler.MOD_NONE  = 0;\n\nOpenLayers.Handler.MOD_SHIFT = 1;\n\nOpenLayers.Handler.MOD_CTRL  = 2;\n\nOpenLayers.Handler.MOD_ALT   = 4;\n\nOpenLayers.Handler.MOD_META  = 8;\n\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Icon.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Icon = OpenLayers.Class({\n    \n        url: null,\n    \n        size: null,\n\n        offset: null,    \n    \n        calculateOffset: null,    \n    \n        imageDiv: null,\n\n        px: null,\n    \n        initialize: function(url, size, offset, calculateOffset) {\n        this.url = url;\n        this.size = size || {w: 20, h: 20};\n        this.offset = offset || {x: -(this.size.w/2), y: -(this.size.h/2)};\n        this.calculateOffset = calculateOffset;\n\n        var id = OpenLayers.Util.createUniqueID(\"OL_Icon_\");\n        this.imageDiv = OpenLayers.Util.createAlphaImageDiv(id);\n    },\n    \n        destroy: function() {\n        this.erase();\n\n        OpenLayers.Event.stopObservingElement(this.imageDiv.firstChild); \n        this.imageDiv.innerHTML = \"\";\n        this.imageDiv = null;\n    },\n\n        clone: function() {\n        return new OpenLayers.Icon(this.url, \n                                   this.size, \n                                   this.offset, \n                                   this.calculateOffset);\n    },\n    \n        setSize: function(size) {\n        if (size != null) {\n            this.size = size;\n        }\n        this.draw();\n    },\n    \n        setUrl: function(url) {\n        if (url != null) {\n            this.url = url;\n        }\n        this.draw();\n    },\n\n        draw: function(px) {\n        OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv, \n                                            null, \n                                            null, \n                                            this.size, \n                                            this.url, \n                                            \"absolute\");\n        this.moveTo(px);\n        return this.imageDiv;\n    }, \n\n        erase: function() {\n        if (this.imageDiv != null && this.imageDiv.parentNode != null) {\n            OpenLayers.Element.remove(this.imageDiv);\n        }\n    }, \n    \n        setOpacity: function(opacity) {\n        OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv, null, null, null, \n                                            null, null, null, null, opacity);\n\n    },\n    \n        moveTo: function (px) {\n        if (px != null) {\n            this.px = px;\n        }\n\n        if (this.imageDiv != null) {\n            if (this.px == null) {\n                this.display(false);\n            } else {\n                if (this.calculateOffset) {\n                    this.offset = this.calculateOffset(this.size);  \n                }\n                OpenLayers.Util.modifyAlphaImageDiv(this.imageDiv, null, {\n                    x: this.px.x + this.offset.x,\n                    y: this.px.y + this.offset.y\n                });\n            }\n        }\n    },\n    \n        display: function(display) {\n        this.imageDiv.style.display = (display) ? \"\" : \"none\"; \n    },\n    \n\n        isDrawn: function() {\n        var isDrawn = (this.imageDiv && this.imageDiv.parentNode && \n                       (this.imageDiv.parentNode.nodeType != 11));    \n\n        return isDrawn;   \n    },\n\n    CLASS_NAME: \"OpenLayers.Icon\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Kinetic.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Kinetic = OpenLayers.Class({\n\n        threshold: 0,\n\n        deceleration: 0.0035,\n\n        nbPoints: 100,\n\n        delay: 200,\n\n        points: undefined,\n\n        timerId: undefined,\n\n        initialize: function(options) {\n        OpenLayers.Util.extend(this, options);\n    },\n\n        begin: function() {\n        OpenLayers.Animation.stop(this.timerId);\n        this.timerId = undefined;\n        this.points = [];\n    },\n\n        update: function(xy) {\n        this.points.unshift({xy: xy, tick: new Date().getTime()});\n        if (this.points.length > this.nbPoints) {\n            this.points.pop();\n        }\n    },\n\n        end: function(xy) {\n        var last, now = new Date().getTime();\n        for (var i = 0, l = this.points.length, point; i < l; i++) {\n            point = this.points[i];\n            if (now - point.tick > this.delay) {\n                break;\n            }\n            last = point;\n        }\n        if (!last) {\n            return;\n        }\n        var time = new Date().getTime() - last.tick;\n        var dist = Math.sqrt(Math.pow(xy.x - last.xy.x, 2) +\n                             Math.pow(xy.y - last.xy.y, 2));\n        var speed = dist / time;\n        if (speed == 0 || speed < this.threshold) {\n            return;\n        }\n        var theta = Math.asin((xy.y - last.xy.y) / dist);\n        if (last.xy.x <= xy.x) {\n            theta = Math.PI - theta;\n        }\n        return {speed: speed, theta: theta};\n    },\n\n        move: function(info, callback) {\n        var v0 = info.speed;\n        var fx = Math.cos(info.theta);\n        var fy = -Math.sin(info.theta);\n\n        var initialTime = new Date().getTime();\n\n        var lastX = 0;\n        var lastY = 0;\n\n        var timerCallback = function() {\n            if (this.timerId == null) {\n                return;\n            }\n\n            var t = new Date().getTime() - initialTime;\n\n            var p = (-this.deceleration * Math.pow(t, 2)) / 2.0 + v0 * t;\n            var x = p * fx;\n            var y = p * fy;\n\n            var args = {};\n            args.end = false;\n            var v = -this.deceleration * t + v0;\n\n            if (v <= 0) {\n                OpenLayers.Animation.stop(this.timerId);\n                this.timerId = null;\n                args.end = true;\n            }\n\n            args.x = x - lastX;\n            args.y = y - lastY;\n            lastX = x;\n            lastY = y;\n            callback(args.x, args.y, args.end);\n        };\n\n        this.timerId = OpenLayers.Animation.start(\n            OpenLayers.Function.bind(timerCallback, this)\n        );\n    },\n\n    CLASS_NAME: \"OpenLayers.Kinetic\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/ar.js",
    "content": "/* Translators (2009 onwards):\n *  - Meno25\n *  - Mutarjem horr\n */\n\n\nOpenLayers.Lang[\"ar\"] = OpenLayers.Util.applyDefaults({\n\n    'Permalink': \"وصلة دائمة\",\n\n    'Base Layer': \"الطبقة الاساسية\",\n\n    'Scale = 1 : ${scaleDenom}': \"النسبة = 1 : ${scaleDenom}\",\n\n    'W': \"غ\",\n\n    'E': \"شر\",\n\n    'N': \"شم\",\n\n    'S': \"ج\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/be-tarask.js",
    "content": "/* Translators (2009 onwards):\n *  - EugeneZelenko\n *  - Jim-by\n */\n\n\nOpenLayers.Lang[\"be-tarask\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Неапрацаваны вынік запыту ${statusText}\",\n\n    'Permalink': \"Сталая спасылка\",\n\n    'Overlays': \"Слаі\",\n\n    'Base Layer': \"Базавы слой\",\n\n    'noFID': \"Немагчыма абнавіць магчымасьць, для якога не існуе FID.\",\n\n    'browserNotSupported': \"Ваш браўзэр не падтрымлівае вэктарную графіку. У цяперашні момант падтрымліваюцца: ${renderers}\",\n\n    'minZoomLevelError': \"Уласьцівасьць minZoomLevel прызначана толькі для выкарыстаньня са слаямі вытворнымі ад FixedZoomLevels. Тое, што  гэты wfs-слой правяраецца на minZoomLevel — рэха прошлага. Але мы ня можам выдаліць гэтую магчымасьць, таму што ад яе залежаць некаторыя заснаваныя на OL дастасаваньні. Тым ня менш, праверка minZoomLevel будзе выдаленая ў вэрсіі 3.0. Калі ласка, выкарыстоўваеце замест яе ўстаноўкі мінімальнага/максымальнага памераў, як апісана тут: http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"WFS-транзакцыя: ПОСЬПЕХ ${response}\",\n\n    'commitFailed': \"WFS-транзакцыя: ПАМЫЛКА ${response}\",\n\n    'googleWarning': \"Не атрымалася загрузіць слой Google. \\x3cbr\\x3e\\x3cbr\\x3eКаб пазбавіцца гэтага паведамленьня, выберыце новы базавы слой у сьпісе ў верхнім правым куце.\\x3cbr\\x3e\\x3cbr\\x3e Хутчэй за ўсё, прычына ў тым, што скрыпт бібліятэкі Google Maps ня быў уключаныя альбо не ўтрымлівае слушны API-ключ для Вашага сайта.\\x3cbr\\x3e\\x3cbr\\x3eРаспрацоўшчыкам: Для таго, каб даведацца як зрабіць так, каб усё працавала, \\x3ca href=\\'http://trac.openlayers.org/wiki/Google\\' target=\\'_blank\\'\\x3eнацісьніце тут\\x3c/a\\x3e\",\n\n    'getLayerWarning': \"Немагчыма загрузіць слой ${layerType}.\\x3cbr\\x3e\\x3cbr\\x3eКаб пазбавіцца гэтага паведамленьня, выберыце новы базавы слой у сьпісе ў верхнім правым куце.\\x3cbr\\x3e\\x3cbr\\x3eХутчэй за ўсё, прычына ў тым, што скрыпт бібліятэкі ${layerLib} ня быў слушна ўключаны.\\x3cbr\\x3e\\x3cbr\\x3eРаспрацоўшчыкам: Для таго, каб даведацца як зрабіць так, каб усё працавала, \\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3eнацісьніце тут\\x3c/a\\x3e\",\n\n    'Scale = 1 : ${scaleDenom}': \"Маштаб = 1 : ${scaleDenom}\",\n\n    'W': \"З\",\n\n    'E': \"У\",\n\n    'N': \"Пн\",\n\n    'S': \"Пд\",\n\n    'reprojectDeprecated': \"Вы выкарыстоўваеце ўстаноўку \\'reproject\\' для слоя ${layerName}. Гэтая ўстаноўка зьяўляецца састарэлай: яна выкарыстоўвалася для падтрымкі паказу зьвестак на камэрцыйных базавых мапах, але гэта функцыя цяпер рэалізаваная ў убудаванай падтрымцы сфэрычнай праекцыі Мэркатара. Дадатковая інфармацыя ёсьць на http://trac.openlayers.org/wiki/SphericalMercator.\",\n\n    'methodDeprecated': \"Гэты мэтад састарэлы і будзе выдалены ў вэрсіі 3.0. Калі ласка, замест яго выкарыстоўвайце ${newMethod}.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/bg.js",
    "content": "/* Translators (2009 onwards):\n *  - DCLXVI\n */\n\n\nOpenLayers.Lang[\"bg\"] = OpenLayers.Util.applyDefaults({\n\n    'Permalink': \"Постоянна препратка\",\n\n    'Base Layer': \"Основен слой\",\n\n    'Scale = 1 : ${scaleDenom}': \"Мащаб = 1 : ${scaleDenom}\",\n\n    'methodDeprecated': \"Този метод е остарял и ще бъде премахват в 3.0. Вместо него използвайте ${newMethod}.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/br.js",
    "content": "/* Translators (2009 onwards):\n *  - Fulup\n */\n\n\nOpenLayers.Lang[\"br\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Distro evel reked anveret ${statusText}\",\n\n    'Permalink': \"Peurliamm\",\n\n    'Overlays': \"Gwiskadoù\",\n\n    'Base Layer': \"Gwiskad diazez\",\n\n    'noFID': \"N\\'haller ket hizivaat un elfenn ma n\\'eus ket a niverenn-anaout (FID) eviti.\",\n\n    'browserNotSupported': \"N\\'eo ket skoret an daskor vektorel gant ho merdeer. Setu aze an daskorerioù skoret evit ar poent :\\n${renderers}\",\n\n    'minZoomLevelError': \"Ne zleer implijout ar perzh minZoomLevel nemet evit gwiskadoù FixedZoomLevels-descendent. Ar fed ma wiria ar gwiskad WHS-se hag-eñ ez eus eus minZoomLevel zo un aspadenn gozh. Koulskoude n\\'omp ket evit e ziverkañ kuit da derriñ arloadoù diazezet war OL a c\\'hallfe bezañ stag outañ. Setu perak eo dispredet -- Lamet kuit e vo ar gwiriañ minZoomLevel a-is er stumm 3.0. Ober gant an arventennoù bihanañ/brasañ evel deskrivet amañ e plas : http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"Treuzgread WFS : MAT EO ${response}\",\n\n    'commitFailed': \"Treuzgread WFS Transaction: C\\'HWITET ${response}\",\n\n    'googleWarning': \"N\\'eus ket bet gallet kargañ ar gwiskad Google ent reizh.\\x3cbr\\x3e\\x3cbr\\x3eEvit en em zizober eus ar c\\'hemenn-mañ, dibabit ur BaseLayer nevez en diuzer gwiskadoù er c\\'horn dehoù el laez.\\x3cbr\\x3e\\x3cbr\\x3eSur a-walc\\'h eo peogwir n\\'eo ket bet ensoc\\'het levraoueg Google Maps pe neuze ne glot ket an alc\\'hwez API gant ho lec\\'hienn.\\x3cbr\\x3e\\x3cbr\\x3eDiorroerien : Evit reizhañ an dra-se, \\x3ca href=\\'http://trac.openlayers.org/wiki/Google\\' target=\\'_blank\\'\\x3eclick here\\x3c/a\\x3e\",\n\n    'getLayerWarning': \"N\\'haller ket kargañ ar gwiskad ${layerType} ent reizh.\\x3cbr\\x3e\\x3cbr\\x3eEvit en em zizober eus ar c\\'hemenn-mañ, dibabit ur BaseLayer nevez en diuzer gwiskadoù er c\\'horn dehoù el laez.\\x3cbr\\x3e\\x3cbr\\x3eSur a-walc\\'h eo peogwir n\\'eo ket bet ensoc\\'het mat al levraoueg ${layerLib}.\\x3cbr\\x3e\\x3cbr\\x3eDiorroerien : Evit gouzout penaos reizhañ an dra-se, \\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3eclick here\\x3c/a\\x3e\",\n\n    'Scale = 1 : ${scaleDenom}': \"Skeul = 1 : ${scaleDenom}\",\n\n    'W': \"K\",\n\n    'E': \"R\",\n\n    'N': \"N\",\n\n    'S': \"S\",\n\n    'reprojectDeprecated': \"Emaoc\\'h oc\\'h implijout an dibarzh \\'reproject\\' war ar gwiskad ${layerName}. Dispredet eo an dibarzh-mañ : bet eo hag e talveze da ziskwel roadennoù war-c\\'horre kartennoù diazez kenwerzhel, un dra hag a c\\'haller ober bremañ gant an arc\\'hwel dre skor banndres boullek Mercator. Muioc\\'h a ditouroù a c\\'haller da gaout war http://trac.openlayers.org/wiki/SphericalMercator.\",\n\n    'methodDeprecated': \"Dispredet eo an daore-se ha tennet e vo kuit eus ar stumm 3.0. Grit gant ${newMethod} e plas.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/ca.js",
    "content": "\nOpenLayers.Lang.ca = {\n\n    'unhandledRequest': \"Resposta a petició no gestionada ${statusText}\",\n\n    'Permalink': \"Enllaç permanent\",\n\n    'Overlays': \"Capes addicionals\",\n\n    'Base Layer': \"Capa Base\",\n\n    'noFID': \"No es pot actualitzar un element per al que no existeix FID.\",\n\n    'browserNotSupported':\n        \"El seu navegador no suporta renderització vectorial. Els renderitzadors suportats actualment són:\\n${renderers}\",\n    'minZoomLevelError':\n        \"La propietat minZoomLevel s'ha d'utilitzar només \" +\n        \"amb les capes que tenen FixedZoomLevels. El fet que \" +\n        \"una capa wfs comprovi minZoomLevel és una relíquia del \" +\n        \"passat. No podem, però, eliminar-la sense trencar \" +\n        \"les aplicacions d'OpenLayers que en puguin dependre. \" +\n        \"Així doncs estem fent-la obsoleta -- la comprovació \" +\n        \"minZoomLevel s'eliminarà a la versió 3.0. Feu servir \" +\n        \"els paràmetres min/max resolution en substitució, tal com es descriu aquí: \" +\n        \"http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"Transacció WFS: CORRECTA ${response}\",\n\n    'commitFailed': \"Transacció WFS: HA FALLAT ${response}\",\n\n    'googleWarning':\n        \"La capa Google no s'ha pogut carregar correctament.<br><br>\" +\n        \"Per evitar aquest missatge, seleccioneu una nova Capa Base \" +\n        \"al gestor de capes de la cantonada superior dreta.<br><br>\" +\n        \"Probablement això és degut a que l'script de la biblioteca de \" +\n    \"Google Maps no ha estat inclòs a la vostra pàgina, o no \" +\n    \"conté la clau de l'API correcta per a la vostra adreça.<br><br>\" +\n        \"Desenvolupadors: Per obtenir consells sobre com fer anar això, \" +\n        \"<a href='http://trac.openlayers.org/wiki/Google' \" +\n        \"target='_blank'>féu clic aquí</a>\",\n\n    'getLayerWarning':\n        \"Per evitar aquest missatge, seleccioneu una nova Capa Base \" +\n        \"al gestor de capes de la cantonada superior dreta.<br><br>\" +\n        \"Probablement això és degut a que l'script de la biblioteca \" +\n        \"${layerLib} \" +\n        \"no ha estat inclòs a la vostra pàgina.<br><br>\" +\n        \"Desenvolupadors: Per obtenir consells sobre com fer anar això, \" +\n        \"<a href='http://trac.openlayers.org/wiki/${layerLib}' \" +\n        \"target='_blank'>féu clic aquí</a>\",\n\n    'Scale = 1 : ${scaleDenom}': \"Escala = 1 : ${scaleDenom}\",\n    'W': 'O',\n    'E': 'E',\n    'N': 'N',\n    'S': 'S',\n    'Graticule': 'Retícula',    \n    'reprojectDeprecated':\n        \"Esteu fent servir l'opció 'reproject' a la capa \" +\n        \"${layerName}. Aquesta opció és obsoleta: el seu ús fou concebut \" +\n        \"per suportar la visualització de dades sobre mapes base comercials, \" + \n        \"però ara aquesta funcionalitat s'hauria d'assolir mitjançant el suport \" +\n        \"de la projecció Spherical Mercator. Més informació disponible a \" +\n        \"http://trac.openlayers.org/wiki/SphericalMercator.\",\n    'methodDeprecated':\n        \"Aquest mètode és obsolet i s'eliminarà a la versió 3.0. \" +\n        \"Si us plau feu servir em mètode alternatiu ${newMethod}.\",\n    'end': ''\n\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/cs-CZ.js",
    "content": "/* Translators (2009 onwards):\n *  - Mormegil\n */\n\n\nOpenLayers.Lang[\"cs-CZ\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Nezpracovaná návratová hodnota ${statusText}\",\n\n    'Permalink': \"Trvalý odkaz\",\n\n    'Overlays': \"Překryvné vrstvy\",\n\n    'Base Layer': \"Podkladové vrstvy\",\n\n    'noFID': \"Nelze aktualizovat prvek, pro který neexistuje FID.\",\n\n    'browserNotSupported': \"Váš prohlížeč nepodporuje vykreslování vektorů. Momentálně podporované nástroje jsou::\\n${renderers}\",\n\n    'minZoomLevelError': \"Vlastnost minZoomLevel by se měla používat pouze s potomky FixedZoomLevels vrstvami. To znamená, že vrstva wfs kontroluje, zda-li minZoomLevel není zbytek z minulosti.Nelze to ovšem vyjmout bez možnosti, že bychom rozbili aplikace postavené na OL, které by na tom mohly záviset. Proto tuto vlastnost nedoporučujeme používat --  kontrola minZoomLevel bude odstraněna ve verzi 3.0. Použijte prosím raději nastavení min/max podle příkaldu popsaného na: http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"WFS Transaction: ÚSPĚCH ${response}\",\n\n    'commitFailed': \"WFS Transaction: CHYBA ${response}\",\n\n    'googleWarning': \"Nepodařilo se správně načíst vrstvu Google.\\x3cbr\\x3e\\x3cbr\\x3eAbyste se zbavili této zprávy, zvolte jinou základní vrstvu v přepínači vrstev.\\x3cbr\\x3e\\x3cbr\\x3eTo se většinou stává, pokud nebyl načten skript, nebo neobsahuje správný klíč pro API pro tuto stránku.\\x3cbr\\x3e\\x3cbr\\x3eVývojáři: Pro pomoc, aby tohle fungovalo , \\x3ca href=\\'http://trac.openlayers.org/wiki/Google\\' target=\\'_blank\\'\\x3eklikněte sem\\x3c/a\\x3e\",\n\n    'getLayerWarning': \"The ${layerType} Layer was unable to load correctly.\\x3cbr\\x3e\\x3cbr\\x3eTo get rid of this message, select a new BaseLayer in the layer switcher in the upper-right corner.\\x3cbr\\x3e\\x3cbr\\x3eMost likely, this is because the ${layerLib} library script was either not correctly included.\\x3cbr\\x3e\\x3cbr\\x3eDevelopers: For help getting this working correctly, \\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3eclick here\\x3c/a\\x3e\",\n\n    'Scale = 1 : ${scaleDenom}': \"Měřítko = 1 : ${scaleDenom}\",\n\n    'reprojectDeprecated': \"Použil jste volbu \\'reproject\\' ve vrstvě ${layerName}. Tato volba není doporučená: byla zde proto, aby bylo možno zobrazovat data z okomerčních serverů, ale tato funkce je nyní zajištěna pomocí podpory Spherical Mercator. Více informací naleznete na http://trac.openlayers.org/wiki/SphericalMercator.\",\n\n    'methodDeprecated': \"Tato metoda je zavržená a bude ve verzi 3.0 odstraněna. Prosím, použijte raději ${newMethod}.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/da-DK.js",
    "content": "\nOpenLayers.Lang['da-DK'] = {\n\n    'unhandledRequest': \"En ikke håndteret forespørgsel returnerede ${statusText}\",\n\n    'Permalink': \"Permalink\",\n\n    'Overlays': \"Kortlag\",\n\n    'Base Layer': \"Baggrundslag\",\n\n    'noFID': \"Kan ikke opdateret en feature (et objekt) der ikke har et FID.\",\n\n    'browserNotSupported':\n        \"Din browser understøtter ikke vektor visning. Følgende vektor visninger understøttes:\\n${renderers}\",\n    'minZoomLevelError':\n        \"Egenskaben minZoomLevel er kun beregnet til brug \" +\n        \"med FixedZoomLevels. At dette WFS lag kontrollerer \" +\n        \"minZoomLevel egenskaben, er et levn fra en tidligere \" +\n        \"version. Vi kan desværre ikke fjerne dette uden at risikere \" +\n        \"at ødelægge eksisterende OL baserede programmer der \" +\n        \" benytter denne funktionalitet. \" +\n        \"Egenskaben bør derfor ikke anvendes, og minZoomLevel \" +\n        \"kontrollen herunder vil blive fjernet i version 3.0. \" +\n        \"Benyt istedet min/max opløsnings indstillingerne, som \" +\n        \"er beskrevet her: \" +\n        \"http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"WFS transaktion: LYKKEDES ${response}\",\n\n    'commitFailed': \"WFS transaktion: MISLYKKEDES ${response}\",\n\n    'googleWarning':\n        \"Google laget kunne ikke indlæses.<br><br>\" +\n        \"For at fjerne denne besked, vælg et nyt bagrundskort i \" +\n        \"lagskifteren i øverste højre hjørne.<br><br>\" +\n        \"Fejlen skyldes formentlig at Google Maps bibliotekts \" +\n        \"scriptet ikke er inkluderet, eller ikke indeholder den \" +\n        \"korrkte API nøgle for dit site.<br><br>\" +\n        \"Udviklere: For hjælp til at få dette til at fungere, \" +\n        \"<a href='http://trac.openlayers.org/wiki/Google' \" +\n        \"target='_blank'>klik her</a>\",\n\n    'getLayerWarning':\n        \"${layerType}-laget kunne ikke indlæses.<br><br>\" +\n        \"For at fjerne denne besked, vælg et nyt bagrundskort i \" +\n        \"lagskifteren i øverste højre hjørne.<br><br>\" +\n        \"Fejlen skyldes formentlig at ${layerLib} bibliotekts \" +\n        \"scriptet ikke er inkluderet.<br><br>\" +\n        \"Udviklere: For hjælp til at få dette til at fungere, \" +\n        \"<a href='http://trac.openlayers.org/wiki/${layerLib}' \" +\n        \"target='_blank'>klik her</a>\",\n\n    'Scale = 1 : ${scaleDenom}': \"Målforhold = 1 : ${scaleDenom}\",\n    'reprojectDeprecated':\n        \"Du anvender indstillingen 'reproject' på laget ${layerName}.\" + \n        \"Denne indstilling bør ikke længere anvendes. Den var beregnet \" +\n        \"til at vise data ovenpå kommercielle grundkort, men den funktionalitet \" +\n        \"bør nu opnås ved at anvende Spherical Mercator understøttelsen. \" +\n        \"Mere information er tilgængelig her: \" +\n        \"http://trac.openlayers.org/wiki/SphericalMercator.\",\n    'methodDeprecated':\n        \"Denne funktion bør ikke længere anvendes, og vil blive fjernet i version 3.0. \" +\n        \"Anvend venligst funktionen ${newMethod} istedet.\"\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/de.js",
    "content": "/* Translators (2009 onwards):\n *  - Grille chompa\n *  - Nikiwaibel\n *  - Umherirrender\n */\n\n\nOpenLayers.Lang[\"de\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Unbehandelte Anfragerückmeldung ${statusText}\",\n\n    'Permalink': \"Permalink\",\n\n    'Overlays': \"Overlays\",\n\n    'Base Layer': \"Grundkarte\",\n\n    'noFID': \"Ein Feature, für das keine FID existiert, kann nicht aktualisiert werden.\",\n\n    'browserNotSupported': \"Ihr Browser unterstützt keine Vektordarstellung. Aktuell unterstützte Renderer:\\n${renderers}\",\n\n    'minZoomLevelError': \"Die \\x3ccode\\x3eminZoomLevel\\x3c/code\\x3e-Eigenschaft ist nur für die Verwendung mit \\x3ccode\\x3eFixedZoomLevels\\x3c/code\\x3e-untergeordneten Layers vorgesehen. Das dieser \\x3ctt\\x3ewfs\\x3c/tt\\x3e-Layer die \\x3ccode\\x3eminZoomLevel\\x3c/code\\x3e-Eigenschaft überprüft ist ein Relikt der Vergangenheit. Wir können diese Überprüfung nicht entfernen, ohne das OL basierende Applikationen nicht mehr funktionieren. Daher markieren wir es als veraltet - die \\x3ccode\\x3eminZoomLevel\\x3c/code\\x3e-Überprüfung wird in Version 3.0 entfernt werden. Bitte verwenden Sie stattdessen die Min-/Max-Lösung, wie sie unter http://trac.openlayers.org/wiki/SettingZoomLevels beschrieben ist.\",\n\n    'commitSuccess': \"WFS-Transaktion: Erfolgreich ${response}\",\n\n    'commitFailed': \"WFS-Transaktion: Fehlgeschlagen ${response}\",\n\n    'googleWarning': \"Der Google-Layer konnte nicht korrekt geladen werden.\\x3cbr\\x3e\\x3cbr\\x3eUm diese Meldung nicht mehr zu erhalten, wählen Sie einen anderen Hintergrundlayer aus dem LayerSwitcher in der rechten oberen Ecke.\\x3cbr\\x3e\\x3cbr\\x3eSehr wahrscheinlich tritt dieser Fehler auf, weil das Skript der Google-Maps-Bibliothek nicht eingebunden wurde oder keinen gültigen API-Schlüssel für Ihre URL enthält.\\x3cbr\\x3e\\x3cbr\\x3eEntwickler: Besuche \\x3ca href=\\'http://trac.openlayers.org/wiki/Google\\' target=\\'_blank\\'\\x3edas Wiki\\x3c/a\\x3e für Hilfe zum korrekten Einbinden des Google-Layers\",\n\n    'getLayerWarning': \"Der ${layerType}-Layer konnte nicht korrekt geladen werden.\\x3cbr\\x3e\\x3cbr\\x3eUm diese Meldung nicht mehr zu erhalten, wählen Sie einen anderen Hintergrundlayer aus dem LayerSwitcher in der rechten oberen Ecke.\\x3cbr\\x3e\\x3cbr\\x3eSehr wahrscheinlich tritt dieser Fehler auf, weil das Skript der \\'${layerLib}\\'-Bibliothek nicht eingebunden wurde.\\x3cbr\\x3e\\x3cbr\\x3eEntwickler: Besuche \\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3edas Wiki\\x3c/a\\x3e für Hilfe zum korrekten Einbinden von Layern\",\n\n    'Scale = 1 : ${scaleDenom}': \"Maßstab = 1 : ${scaleDenom}\",\n\n    'W': \"W\",\n\n    'E': \"O\",\n\n    'N': \"N\",\n\n    'S': \"S\",\n\n    'reprojectDeprecated': \"Sie verwenden die „Reproject“-Option des Layers ${layerName}. Diese Option ist veraltet: Sie wurde entwickelt um die Anzeige von Daten auf kommerziellen Basiskarten zu unterstützen, aber diese Funktion sollte jetzt durch Unterstützung der „Spherical Mercator“ erreicht werden. Weitere Informationen sind unter http://trac.openlayers.org/wiki/SphericalMercator verfügbar.\",\n\n    'methodDeprecated': \"Die Methode ist veraltet und wird in 3.0 entfernt. Bitte verwende stattdessen ${newMethod}.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/el.js",
    "content": "/* Translators (2009 onwards):\n *  - Omnipaedista\n */\n\n\nOpenLayers.Lang[\"el\"] = OpenLayers.Util.applyDefaults({\n\n    'Scale = 1 : ${scaleDenom}': \"Κλίμακα ~ 1 : ${scaleDenom}\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/en-CA.js",
    "content": "\nOpenLayers.Lang['en-CA'] = OpenLayers.Util.applyDefaults({\n    \n}, OpenLayers.Lang[\"en\"]);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/en.js",
    "content": "\nOpenLayers.Lang.en = {\n\n    'unhandledRequest': \"Unhandled request return ${statusText}\",\n\n    'Permalink': \"Permalink\",\n\n    'Overlays': \"Overlays\",\n\n    'Base Layer': \"Base Layer\",\n\n    'noFID': \"Can't update a feature for which there is no FID.\",\n\n    'browserNotSupported':\n        \"Your browser does not support vector rendering. Currently supported renderers are:\\n${renderers}\",\n    'minZoomLevelError':\n        \"The minZoomLevel property is only intended for use \" +\n        \"with the FixedZoomLevels-descendent layers. That this \" +\n        \"wfs layer checks for minZoomLevel is a relic of the\" +\n        \"past. We cannot, however, remove it without possibly \" +\n        \"breaking OL based applications that may depend on it.\" +\n        \" Therefore we are deprecating it -- the minZoomLevel \" +\n        \"check below will be removed at 3.0. Please instead \" +\n        \"use min/max resolution setting as described here: \" +\n        \"http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"WFS Transaction: SUCCESS ${response}\",\n\n    'commitFailed': \"WFS Transaction: FAILED ${response}\",\n\n    'googleWarning':\n        \"The Google Layer was unable to load correctly.<br><br>\" +\n        \"To get rid of this message, select a new BaseLayer \" +\n        \"in the layer switcher in the upper-right corner.<br><br>\" +\n        \"Most likely, this is because the Google Maps library \" +\n        \"script was either not included, or does not contain the \" +\n        \"correct API key for your site.<br><br>\" +\n        \"Developers: For help getting this working correctly, \" +\n        \"<a href='http://trac.openlayers.org/wiki/Google' \" +\n        \"target='_blank'>click here</a>\",\n\n    'getLayerWarning':\n        \"The ${layerType} Layer was unable to load correctly.<br><br>\" +\n        \"To get rid of this message, select a new BaseLayer \" +\n        \"in the layer switcher in the upper-right corner.<br><br>\" +\n        \"Most likely, this is because the ${layerLib} library \" +\n        \"script was not correctly included.<br><br>\" +\n        \"Developers: For help getting this working correctly, \" +\n        \"<a href='http://trac.openlayers.org/wiki/${layerLib}' \" +\n        \"target='_blank'>click here</a>\",\n\n    'Scale = 1 : ${scaleDenom}': \"Scale = 1 : ${scaleDenom}\",\n    'W': 'W',\n    'E': 'E',\n    'N': 'N',\n    'S': 'S',\n    'Graticule': 'Graticule',\n    'reprojectDeprecated':\n        \"You are using the 'reproject' option \" +\n        \"on the ${layerName} layer. This option is deprecated: \" +\n        \"its use was designed to support displaying data over commercial \" + \n        \"basemaps, but that functionality should now be achieved by using \" +\n        \"Spherical Mercator support. More information is available from \" +\n        \"http://trac.openlayers.org/wiki/SphericalMercator.\",\n    'methodDeprecated':\n        \"This method has been deprecated and will be removed in 3.0. \" +\n        \"Please use ${newMethod} instead.\",\n    'end': ''\n    \n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/es.js",
    "content": "\nOpenLayers.Lang.es = {\n\n    'unhandledRequest': \"Respuesta a petición no gestionada ${statusText}\",\n\n    'Permalink': \"Enlace permanente\",\n\n    'Overlays': \"Capas superpuestas\",\n\n    'Base Layer': \"Capa Base\",\n\n    'noFID': \"No se puede actualizar un elemento para el que no existe FID.\",\n\n    'browserNotSupported':\n        \"Su navegador no soporta renderización vectorial. Los renderizadores soportados actualmente son:\\n${renderers}\",\n    'minZoomLevelError':\n        \"La propiedad minZoomLevel debe sólo utilizarse \" +\n        \"con las capas que tienen FixedZoomLevels. El hecho de que \" +\n        \"una capa wfs compruebe minZoomLevel es una reliquia del \" +\n        \"pasado. Sin embargo, no podemos eliminarla sin discontinuar \" +\n        \"probablemente las aplicaciones OL que puedan depender de ello. \" +\n        \"Así pues estamos haciéndolo obsoleto --la comprobación \" +\n        \"minZoomLevel se eliminará en la versión 3.0. Utilice el ajuste \" +\n        \"de resolution min/max en su lugar, tal como se describe aquí: \" +\n        \"http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"Transacción WFS: ÉXITO ${response}\",\n\n    'commitFailed': \"Transacción WFS: FALLÓ ${response}\",\n\n    'googleWarning':\n        \"La capa Google no pudo ser cargada correctamente.<br><br>\" +\n        \"Para evitar este mensaje, seleccione una nueva Capa Base \" +\n        \"en el selector de capas en la esquina superior derecha.<br><br>\" +\n        \"Probablemente, esto se debe a que el script de la biblioteca de \" +\n        \"Google Maps no fue correctamente incluido en su página, o no \" +\n        \"contiene la clave del API correcta para su sitio.<br><br>\" +\n        \"Desarrolladores: Para ayudar a hacer funcionar esto correctamente, \" +\n        \"<a href='http://trac.openlayers.org/wiki/Google' \" +\n        \"target='_blank'>haga clic aquí</a>\",\n\n    'getLayerWarning':\n        \"La capa ${layerType} no pudo ser cargada correctamente.<br><br>\" +\n        \"Para evitar este mensaje, seleccione una nueva Capa Base \" +\n        \"en el selector de capas en la esquina superior derecha.<br><br>\" +\n        \"Probablemente, esto se debe a que el script de \" +\n        \"la biblioteca ${layerLib} \" +\n        \"no fue correctamente incluido en su página.<br><br>\" +\n        \"Desarrolladores: Para ayudar a hacer funcionar esto correctamente, \" +\n        \"<a href='http://trac.openlayers.org/wiki/${layerLib}' \" +\n        \"target='_blank'>haga clic aquí</a>\",\n\n    'Scale = 1 : ${scaleDenom}': \"Escala = 1 : ${scaleDenom}\",\n    'W': 'O',\n    'E': 'E',\n    'N': 'N',\n    'S': 'S',\n    'Graticule': 'Retícula',\n    'reprojectDeprecated':\n        \"Está usando la opción 'reproject' en la capa \" +\n        \"${layerName}. Esta opción es obsoleta: su uso fue diseñado \" +\n        \"para soportar la visualización de datos sobre mapas base comerciales, \" + \n        \"pero ahora esa funcionalidad debería conseguirse mediante el soporte \" +\n        \"de la proyección Spherical Mercator. Más información disponible en \" +\n        \"http://trac.openlayers.org/wiki/SphericalMercator.\",\n    'methodDeprecated':\n        \"Este método es obsoleto y se eliminará en la versión 3.0. \" +\n        \"Por favor utilice el método ${newMethod} en su lugar.\",\n    'end': ''\n\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/fi.js",
    "content": "/* Translators (2009 onwards):\n *  - Nike\n *  - Str4nd\n */\n\n\nOpenLayers.Lang[\"fi\"] = OpenLayers.Util.applyDefaults({\n\n    'Permalink': \"Ikilinkki\",\n\n    'Overlays': \"Kerrokset\",\n\n    'Base Layer': \"Peruskerros\",\n\n    'W': \"L\",\n\n    'E': \"I\",\n\n    'N': \"P\",\n\n    'S': \"E\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/fr.js",
    "content": "/* Translators (2009 onwards):\n *  - Damouns\n *  - IAlex\n */\n\n\nOpenLayers.Lang[\"fr\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Requête non gérée, retournant ${statusText}\",\n\n    'Permalink': \"Permalien\",\n\n    'Overlays': \"Calques\",\n\n    'Base Layer': \"Calque de base\",\n\n    'noFID': \"Impossible de mettre à jour un objet sans identifiant (fid).\",\n\n    'browserNotSupported': \"Votre navigateur ne supporte pas le rendu vectoriel. Les renderers actuellement supportés sont : \\n${renderers}\",\n\n    'minZoomLevelError': \"La propriété minZoomLevel doit seulement être utilisée pour des couches FixedZoomLevels-descendent. Le fait que cette couche WFS vérifie la présence de minZoomLevel est une relique du passé. Nous ne pouvons toutefois la supprimer sans casser des applications qui pourraient en dépendre. C\\'est pourquoi nous la déprécions -- la vérification du minZoomLevel sera supprimée en version 3.0. A la place, merci d\\'utiliser les paramètres de résolutions min/max tel que décrit sur : http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"Transaction WFS : SUCCES ${response}\",\n\n    'commitFailed': \"Transaction WFS : ECHEC ${response}\",\n\n    'googleWarning': \"La couche Google n\\'a pas été en mesure de se charger correctement.\\x3cbr\\x3e\\x3cbr\\x3ePour supprimer ce message, choisissez une nouvelle BaseLayer dans le sélecteur de couche en haut à droite.\\x3cbr\\x3e\\x3cbr\\x3eCela est possiblement causé par la non-inclusion de la librairie Google Maps, ou alors parce que la clé de l\\'API ne correspond pas à votre site.\\x3cbr\\x3e\\x3cbr\\x3eDéveloppeurs : pour savoir comment corriger ceci, \\x3ca href=\\'http://trac.openlayers.org/wiki/Google\\' target=\\'_blank\\'\\x3ecliquez ici\\x3c/a\\x3e\",\n\n    'getLayerWarning': \"La couche ${layerType} n\\'est pas en mesure de se charger correctement.\\x3cbr\\x3e\\x3cbr\\x3ePour supprimer ce message, choisissez une nouvelle BaseLayer dans le sélecteur de couche en haut à droite.\\x3cbr\\x3e\\x3cbr\\x3eCela est possiblement causé par la non-inclusion de la librairie ${layerLib}.\\x3cbr\\x3e\\x3cbr\\x3eDéveloppeurs : pour savoir comment corriger ceci, \\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3ecliquez ici\\x3c/a\\x3e\",\n\n    'Scale = 1 : ${scaleDenom}': \"Echelle ~ 1 : ${scaleDenom}\",\n\n    'W': \"O\",\n\n    'E': \"E\",\n\n    'N': \"N\",\n\n    'S': \"S\",\n\n    'reprojectDeprecated': \"Vous utilisez l\\'option \\'reproject\\' sur la couche ${layerName}. Cette option est dépréciée : Son usage permettait d\\'afficher des données au dessus de couches raster commerciales.Cette fonctionalité est maintenant supportée en utilisant le support de la projection Mercator Sphérique. Plus d\\'information est disponible sur http://trac.openlayers.org/wiki/SphericalMercator.\",\n\n    'methodDeprecated': \"Cette méthode est dépréciée, et sera supprimée à la version 3.0. Merci d\\'utiliser ${newMethod} à la place.\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/fur.js",
    "content": "/* Translators (2009 onwards):\n *  - Klenje\n */\n\n\nOpenLayers.Lang[\"fur\"] = OpenLayers.Util.applyDefaults({\n\n    'Permalink': \"Leam Permanent\",\n\n    'Overlays': \"Livei parsore\",\n\n    'Base Layer': \"Livel di base\",\n\n    'browserNotSupported': \"Il to sgarfadôr nol supuarte la renderizazion vetoriâl. Al moment a son supuartâts:\\n${renderers}\",\n\n    'Scale = 1 : ${scaleDenom}': \"Scjale = 1 : ${scaleDenom}\",\n\n    'W': \"O\",\n\n    'E': \"E\",\n\n    'N': \"N\",\n\n    'S': \"S\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/gl.js",
    "content": "/* Translators (2009 onwards):\n *  - Toliño\n */\n\n\nOpenLayers.Lang[\"gl\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Solicitude non xerada; a resposta foi: ${statusText}\",\n\n    'Permalink': \"Ligazón permanente\",\n\n    'Overlays': \"Capas superpostas\",\n\n    'Base Layer': \"Capa base\",\n\n    'noFID': \"Non se pode actualizar a funcionalidade para a que non hai FID.\",\n\n    'browserNotSupported': \"O seu navegador non soporta a renderización de vectores. Os renderizadores soportados actualmente son:\\n${renderers}\",\n\n    'minZoomLevelError': \"A propiedade minZoomLevel é só para uso conxuntamente coas capas FixedZoomLevels-descendent. O feito de que esa capa wfs verifique o minZoomLevel é unha reliquia do pasado. Non podemos, con todo, eliminala sen a posibilidade de non romper as aplicacións baseadas en OL que poidan depender dela. Por iso a estamos deixando obsoleta (a comprobación minZoomLevel de embaixo será eliminada na versión 3.0). Por favor, no canto diso use o axuste de resolución mín/máx tal e como está descrito aquí: http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"Transacción WFS: ÉXITO ${response}\",\n\n    'commitFailed': \"Transacción WFS: FALLIDA ${response}\",\n\n    'googleWarning': \"A capa do Google non puido cargarse correctamente.\\x3cbr\\x3e\\x3cbr\\x3ePara evitar esta mensaxe, escolla unha nova capa base no seleccionador de capas na marxe superior dereita.\\x3cbr\\x3e\\x3cbr\\x3eProbablemente, isto acontece porque a escritura da libraría do Google Maps ou ben non foi incluída ou ben non contén a clave API correcta para o seu sitio.\\x3cbr\\x3e\\x3cbr\\x3eDesenvolvedores: para axudar a facer funcionar isto correctamente, \\x3ca href=\\'http://trac.openlayers.org/wiki/Google\\' target=\\'_blank\\'\\x3epremede aquí\\x3c/a\\x3e\",\n\n    'getLayerWarning': \"A capa ${layerType} foi incapaz de cargarse correctamente.\\x3cbr\\x3e\\x3cbr\\x3ePara evitar esta mensaxe, escolla unha nova capa base no seleccionador de capas na marxe superior dereita.\\x3cbr\\x3e\\x3cbr\\x3eProbablemente, isto acontece porque a escritura da libraría ${layerLib} non foi ben incluída.\\x3cbr\\x3e\\x3cbr\\x3eDesenvolvedores: para axudar a facer funcionar isto correctamente, \\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3epremede aquí\\x3c/a\\x3e\",\n\n    'Scale = 1 : ${scaleDenom}': \"Escala = 1 : ${scaleDenom}\",\n\n    'W': \"O\",\n\n    'E': \"L\",\n\n    'N': \"N\",\n\n    'S': \"S\",\n\n    'reprojectDeprecated': \"Está usando a opción \\\"reproject\\\" na capa ${layerName}. Esta opción está obsoleta: o seu uso foi deseñado para a visualización de datos sobre mapas base comerciais, pero esta funcionalidade debera agora ser obtida utilizando a proxección Spherical Mercator. Hai dispoñible máis información en http://trac.openlayers.org/wiki/SphericalMercator.\",\n\n    'methodDeprecated': \"Este método está obsoleto e será eliminado na versión 3.0. Por favor, no canto deste use ${newMethod}.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/gsw.js",
    "content": "/* Translators (2009 onwards):\n *  - Als-Holder\n */\n\n\nOpenLayers.Lang[\"gsw\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Nit behandleti Aafrogsruckmäldig ${statusText}\",\n\n    'Permalink': \"Permalink\",\n\n    'Overlays': \"Iberlagerige\",\n\n    'Base Layer': \"Grundcharte\",\n\n    'noFID': \"E Feature, wu s kei FID derfir git, cha nit aktualisiert wäre.\",\n\n    'browserNotSupported': \"Dyy Browser unterstitzt kei Vektordarstellig. Aktuäll unterstitzti Renderer:\\n${renderers}\",\n\n    'minZoomLevelError': \"D minZoomLevel-Eigeschaft isch nume dänk fir d Layer, wu vu dr FixedZoomLevels abstamme. Ass dää wfs-Layer minZoomLevel prieft, scih e Relikt us dr Vergangeheit. Mir chenne s aber nit ändere ohni OL_basierti Aawändige villicht kaputt gehn, wu dervu abhänge.  Us däm Grund het die Funktion d Eigeschaft \\'deprecated\\' iberchuu. D minZoomLevel-Priefig unte wird in dr Version 3.0 usegnuu. Bitte verwänd statt däm e min/max-Uflesig wie s do bschriben isch: http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"WFS-Transaktion: ERFOLGRYCH ${response}\",\n\n    'commitFailed': \"WFS-Transaktion: FÄHLGSCHLAA ${response}\",\n\n    'googleWarning': \"Dr Google-Layer het nit korräkt chenne glade wäre.\\x3cbr\\x3e\\x3cbr\\x3eGo die Mäldig nimi z kriege, wehl e andere Hintergrundlayer us em LayerSwitcher im rächte obere Ecke.\\x3cbr\\x3e\\x3cbr\\x3eDää Fähler git s seli hyfig, wel s Skript vu dr Google-Maps-Bibliothek nit yybunde woren isch oder wel s kei giltige API-Schlissel fir Dyy URL din het.\\x3cbr\\x3e\\x3cbr\\x3eEntwickler: Fir Hilf zum korräkte Yybinde vum Google-Layer \\x3ca href=\\'http://trac.openlayers.org/wiki/Google\\' target=\\'_blank\\'\\x3edoo drucke\\x3c/a\\x3e\",\n\n    'getLayerWarning': \"Dr ${layerType}-Layer het nit korräkt chenne glade wäre.\\x3cbr\\x3e\\x3cbr\\x3eGo die Mäldig nimi z kriege, wehl e andere Hintergrundlayer us em LayerSwitcher im rächte obere Ecke.\\x3cbr\\x3e\\x3cbr\\x3eDää Fähler git s seli hyfig, wel s Skript vu dr \\'${layerLib}\\'-Bibliothek nit yybunde woren isch oder wel s kei giltige API-Schlissel fir Dyy URL din het.\\x3cbr\\x3e\\x3cbr\\x3eEntwickler: Fir Hilf zum korräkte Yybinde vu Layer \\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3edoo drucke\\x3c/a\\x3e\",\n\n    'Scale = 1 : ${scaleDenom}': \"Maßstab = 1 : ${scaleDenom}\",\n\n    'W': \"W\",\n\n    'E': \"O\",\n\n    'N': \"N\",\n\n    'S': \"S\",\n\n    'reprojectDeprecated': \"Du bruchsch d \\'reproject\\'-Option bim ${layerName}-Layer. Die Option isch nimi giltig: si isch aagleit wore go   Date iber kommerziälli Grundcharte lege, aber des sott mer jetz mache mit dr Unterstitzig vu Spherical Mercator. Meh Informatione git s uf http://trac.openlayers.org/wiki/SphericalMercator.\",\n\n    'methodDeprecated': \"Die Methode isch veraltet un wird us dr Version 3.0 usegnuu. Bitte verwäbnd statt däm ${newMethod}.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/hr.js",
    "content": "/* Translators (2009 onwards):\n *  - Mvrban\n */\n\n\nOpenLayers.Lang[\"hr\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Nepodržani zahtjev ${statusText}\",\n\n    'Permalink': \"Permalink\",\n\n    'Overlays': \"Overlays\",\n\n    'Base Layer': \"Osnovna karta\",\n\n    'noFID': \"Ne mogu ažurirati značajku za koju ne postoji FID.\",\n\n    'browserNotSupported': \"Vaš preglednik ne podržava vektorsko renderiranje. Trenutno podržani rendereri su: ${renderers}\",\n\n    'commitSuccess': \"WFS Transakcija: USPJEŠNA ${response}\",\n\n    'commitFailed': \"WFS Transakcija: NEUSPJEŠNA ${response}\",\n\n    'Scale = 1 : ${scaleDenom}': \"Mjerilo = 1 : ${scaleDenom}\",\n\n    'methodDeprecated': \"Ova metoda nije odobrena i biti će maknuta u 3.0. Koristite ${newMethod}.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/hsb.js",
    "content": "/* Translators (2009 onwards):\n *  - Michawiki\n */\n\n\nOpenLayers.Lang[\"hsb\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Wotmołwa njewobdźěłaneho naprašowanja ${statusText}\",\n\n    'Permalink': \"Trajny wotkaz\",\n\n    'Overlays': \"Naworštowanja\",\n\n    'Base Layer': \"Zakładna runina\",\n\n    'noFID': \"Funkcija, za kotruž FID njeje, njeda so aktualizować.\",\n\n    'browserNotSupported': \"Twój wobhladowak wektorowe rysowanje njepodpěruje. Tuchwilu podpěrowane rysowaki su:\\n${renderers}\",\n\n    'minZoomLevelError': \"Kajkosć minZoomLevel je jenož za wužiwanje z worštami myslena, kotrež wot FixedZoomLevels pochadźeja. Zo tuta woršta wfs za minZoomLevel přepruwuje, je relikt zańdźenosće. Njemóžemy wšak ju wotstronić, bjeztoho zo aplikacije, kotrež na OpenLayers bazěruja a snano tutu kajkosć wužiwaja, hižo njefunguja. Tohodla smy ju jako zestarjenu woznamjenili -- přepruwowanje za minZoomLevel budu so we wersiji 3.0 wotstronjeć. Prošu wužij město toho nastajenje min/max, kaž je tu wopisane: http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"WFS-Transakcija: WUSPĚŠNA ${response}\",\n\n    'commitFailed': \"WFS-Transakcija: NJEPORADŹENA ${response}\",\n\n    'googleWarning': \"Woršta Google njemóžeše so korektnje začitać.\\x3cbr\\x3e\\x3cbr\\x3eZo by tutu zdźělenku wotbył, wubjer nowy BaseLayer z wuběra worštow horjeka naprawo.\\x3cbr\\x3e\\x3cbr\\x3eNajskerje so to stawa, dokelž skript biblioteki Google Maps pak njebu zapřijaty pak njewobsahuje korektny kluč API za twoje sydło.\\x3cbr\\x3e\\x3cbr\\x3eWuwiwarjo: Za pomoc ke korektnemu fungowanju worštow\\n\\x3ca href=\\'http://trac.openlayers.org/wiki/Google\\' target=\\'_blank\\'\\x3etu kliknyć\\x3c/a\\x3e\",\n\n    'getLayerWarning': \"Woršta ${layerType} njemóžeše so korektnje začitać.\\x3cbr\\x3e\\x3cbr\\x3eZo by tutu zdźělenku wotbył, wubjer nowy BaseLayer z wuběra worštow horjeka naprawo.\\x3cbr\\x3e\\x3cbr\\x3eNajskerje so to stawa, dokelž skript biblioteki ${layerLib} njebu korektnje zapřijaty.\\x3cbr\\x3e\\x3cbr\\x3eWuwiwarjo: Za pomoc ke korektnemu fungowanju worštow\\n\\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3etu kliknyć\\x3c/a\\x3e\",\n\n    'Scale = 1 : ${scaleDenom}': \"Měritko = 1 : ${scaleDenom}\",\n\n    'W': \"Z\",\n\n    'E': \"W\",\n\n    'N': \"S\",\n\n    'S': \"J\",\n\n    'reprojectDeprecated': \"Wužiwaš opciju \\\"reproject\\\" wořšty ${layerName}. Tuta opcija je zestarjena: jeje wužiwanje bě myslene, zo by zwobraznjenje datow nad komercielnymi bazowymi kartami podpěrało, ale funkcionalnosć měła so nětko z pomocu Sperical Mercator docpěć. Dalše informacije steja na http://trac.openlayers.org/wiki/SphericalMercator k dispoziciji.\",\n\n    'methodDeprecated': \"Tuta metoda je so njeschwaliła a budźe so w 3.0 wotstronjeć. Prošu wužij ${newMethod} město toho.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/hu.js",
    "content": "/* Translators (2009 onwards):\n *  - City-busz\n *  - Glanthor Reviol\n */\n\n\nOpenLayers.Lang[\"hu\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Nem kezelt kérés visszatérése ${statusText}\",\n\n    'Permalink': \"Permalink\",\n\n    'Overlays': \"Rávetítések\",\n\n    'Base Layer': \"Alapréteg\",\n\n    'noFID': \"Nem frissíthető olyan jellemző, amely nem rendelkezik FID-del.\",\n\n    'browserNotSupported': \"A böngészője nem támogatja a vektoros renderelést. A jelenleg támogatott renderelők:\\n${renderers}\",\n\n    'minZoomLevelError': \"A minZoomLevel tulajdonságot csak a következővel való használatra szánták: FixedZoomLevels-leszármazott fóliák. Ez azt jelenti, hogy a minZoomLevel wfs fólia jelölőnégyzetei már a múlté. Mi azonban nem távolíthatjuk el annak a veszélye nélkül, hogy az esetlegesen ettől függő OL alapú alkalmazásokat tönkretennénk. Ezért ezt érvénytelenítjük -- a minZoomLevel az alul levő jelölőnégyzet a 3.0-s verzióból el lesz távolítva. Kérjük, helyette használja a  min/max felbontás beállítást, amelyről az alábbi helyen talál leírást: http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"WFS tranzakció: SIKERES ${response}\",\n\n    'commitFailed': \"WFS tranzakció: SIKERTELEN ${response}\",\n\n    'googleWarning': \"A Google fólia betöltése sikertelen.\\x3cbr\\x3e\\x3cbr\\x3eAhhoz, hogy ez az üzenet eltűnjön, válasszon egy új BaseLayer fóliát a jobb felső sarokban található fóliakapcsoló segítségével.\\x3cbr\\x3e\\x3cbr\\x3eNagy valószínűséggel ez azért van, mert a Google Maps könyvtár parancsfájlja nem található, vagy nem tartalmazza az Ön oldalához tartozó megfelelő API-kulcsot.\\x3cbr\\x3e\\x3cbr\\x3eFejlesztőknek: A helyes működtetésre vonatkozó segítség az alábbi helyen érhető el, \\x3ca href=\\'http://trac.openlayers.org/wiki/Google\\' target=\\'_blank\\'\\x3ekattintson ide\\x3c/a\\x3e\",\n\n    'getLayerWarning': \"A(z) ${layerType} fólia nem töltődött be helyesen.\\x3cbr\\x3e\\x3cbr\\x3eAhhoz, hogy ez az üzenet eltűnjön, válasszon egy új BaseLayer fóliát a jobb felső sarokban található fóliakapcsoló segítségével.\\x3cbr\\x3e\\x3cbr\\x3eNagy valószínűséggel ez azért van, mert a(z) ${layerLib} könyvtár parancsfájlja helytelen.\\x3cbr\\x3e\\x3cbr\\x3eFejlesztőknek: A helyes működtetésre vonatkozó segítség az alábbi helyen érhető el, \\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3ekattintson ide\\x3c/a\\x3e\",\n\n    'Scale = 1 : ${scaleDenom}': \"Lépték = 1 : ${scaleDenom}\",\n\n    'W': \"Ny\",\n\n    'E': \"K\",\n\n    'N': \"É\",\n\n    'S': \"D\",\n\n    'reprojectDeprecated': \"Ön a \\'reproject\\' beállítást használja a(z) ${layerName} fólián. Ez a beállítás érvénytelen: használata az üzleti alaptérképek fölötti adatok megjelenítésének támogatására szolgált, de ezt a funkció ezentúl a Gömbi Mercator használatával érhető el. További információ az alábbi helyen érhető el: http://trac.openlayers.org/wiki/SphericalMercator\",\n\n    'methodDeprecated': \"Ez a módszer érvénytelenítve lett és a 3.0-s verzióból el lesz távolítva. Használja a(z) ${newMethod} módszert helyette.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/ia.js",
    "content": "/* Translators (2009 onwards):\n *  - McDutchie\n */\n\n\nOpenLayers.Lang[\"ia\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Le responsa a un requesta non esseva maneate: ${statusText}\",\n\n    'Permalink': \"Permaligamine\",\n\n    'Overlays': \"Superpositiones\",\n\n    'Base Layer': \"Strato de base\",\n\n    'noFID': \"Non pote actualisar un elemento sin FID.\",\n\n    'browserNotSupported': \"Tu navigator non supporta le rendition de vectores. Le renditores actualmente supportate es:\\n${renderers}\",\n\n    'minZoomLevelError': \"Le proprietate minZoomLevel es solmente pro uso con le stratos descendente de FixedZoomLevels. Le facto que iste strato WFS verifica minZoomLevel es un reliquia del passato. Nonobstante, si nos lo remove immediatemente, nos pote rumper applicationes a base de OL que depende de illo. Ergo nos lo declara obsolete; le verification de minZoomLevel in basso essera removite in version 3.0. Per favor usa in su loco le configuration de resolutiones min/max como describite a: http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"Transaction WFS: SUCCESSO ${response}\",\n\n    'commitFailed': \"Transaction WFS: FALLEVA ${response}\",\n\n    'googleWarning': \"Le strato Google non poteva esser cargate correctemente.\\x3cbr\\x3e\\x3cbr\\x3ePro disfacer te de iste message, selige un nove BaseLayer in le selector de strato in alto a dextra.\\x3cbr\\x3e\\x3cbr\\x3eMulto probabilemente, isto es proque le script del libreria de Google Maps non esseva includite o non contine le clave API correcte pro tu sito.\\x3cbr\\x3e\\x3cbr\\x3eDisveloppatores: Pro adjuta de corriger isto, \\x3ca href=\\'http://trac.openlayers.org/wiki/Google\\' target=\\'_blank\\'\\x3eclicca hic\\x3c/a\",\n\n    'getLayerWarning': \"Le strato ${layerType} non poteva esser cargate correctemente.\\x3cbr\\x3e\\x3cbr\\x3ePro disfacer te de iste message, selige un nove BaseLayer in le selector de strato in alto a dextra.\\x3cbr\\x3e\\x3cbr\\x3eMulto probabilemente, isto es proque le script del libreria de ${layerLib} non esseva correctemente includite.\\x3cbr\\x3e\\x3cbr\\x3eDisveloppatores: Pro adjuta de corriger isto, \\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3eclicca hic\\x3c/a\\x3e\",\n\n    'Scale = 1 : ${scaleDenom}': \"Scala = 1 : ${scaleDenom}\",\n\n    'W': \"W\",\n\n    'E': \"E\",\n\n    'N': \"N\",\n\n    'S': \"S\",\n\n    'reprojectDeprecated': \"Tu usa le option \\'reproject\\' in le strato ${layerName} layer. Iste option es obsolescente: illo esseva pro poter monstrar datos super cartas de base commercial, ma iste functionalitate pote ora esser attingite con le uso de Spherical Mercator. Ulterior information es disponibile a http://trac.openlayers.org/wiki/SphericalMercator.\",\n\n    'methodDeprecated': \"Iste methodo ha essite declarate obsolescente e essera removite in version 3.0. Per favor usa ${newMethod} in su loco.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/id.js",
    "content": "/* Translators (2009 onwards):\n *  - Irwangatot\n *  - IvanLanin\n */\n\n\nOpenLayers.Lang[\"id\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Permintaan yang tak tertangani menghasilkan ${statusText}\",\n\n    'Permalink': \"Pranala permanen\",\n\n    'Overlays': \"Hamparan\",\n\n    'Base Layer': \"Lapisan Dasar\",\n\n    'noFID': \"Tidak dapat memperbarui fitur yang tidak memiliki FID.\",\n\n    'browserNotSupported': \"Peramban Anda tidak mendukung penggambaran vektor. Penggambar yang didukung saat ini adalah:\\n${renderers}\",\n\n    'minZoomLevelError': \"Properti minZoomLevel hanya ditujukan bekerja dengan lapisan FixedZoomLevels-descendent. Pengecekan minZoomLevel oleh lapisan wfs adalah peninggalan masa lalu. Kami tidak dapat menghapusnya tanpa kemungkinan merusak aplikasi berbasis OL yang mungkin bergantung padanya. Karenanya, kami menganggapnya tidak berlaku -- Cek minZoomLevel di bawah ini akan dihapus pada 3.0. Silakan gunakan penyetelan resolusi min/maks seperti dijabarkan di sini: http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"WFS Transaksi: BERHASIL ${respon}\",\n\n    'commitFailed': \"WFS Transaksi: GAGAL ${respon}\",\n\n    'googleWarning': \"Lapisan Google tidak dapat dimuat dengan benar.\\x3cbr\\x3e\\x3cbr\\x3eUntuk menghilangkan pesan ini, pilih suatu BaseLayer baru melalui penukar lapisan (layer switcher) di ujung kanan atas.\\x3cbr\\x3e\\x3cbr\\x3eKemungkinan besar ini karena pustaka skrip Google Maps tidak disertakan atau tidak mengandung kunci API yang tepat untuk situs Anda.\\x3cbr\\x3e\\x3cbr\\x3ePengembang: Untuk bantuan mengatasi masalah ini, \\x3ca href=\\'http://trac.openlayers.org/wiki/Google\\' target=\\'_blank\\'\\x3eklik di sini\\x3c/a\\x3e\",\n\n    'getLayerWarning': \"Lapisan ${layerType} tidak dapat dimuat dengan benar.\\x3cbr\\x3e\\x3cbr\\x3eUntuk menghilangkan pesan ini, pilih suatu BaseLayer baru melalui penukar lapisan (layer switcher) di ujung kanan atas.\\x3cbr\\x3e\\x3cbr\\x3eKemungkinan besar ini karena pustaka skrip Google Maps tidak disertakan dengan benar.\\x3cbr\\x3e\\x3cbr\\x3ePengembang: Untuk bantuan mengatasi masalah ini, \\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3eklik di sini\\x3c/a\\x3e\",\n\n    'Scale = 1 : ${scaleDenom}': \"Sekala = 1 : ${scaleDenom}\",\n\n    'W': \"B\",\n\n    'E': \"T\",\n\n    'N': \"U\",\n\n    'S': \"S\",\n\n    'reprojectDeprecated': \"Anda menggunakan opsi \\'reproject\\' pada lapisan ${layerName}. Opsi ini telah ditinggalkan: penggunaannya dirancang untuk mendukung tampilan data melalui peta dasar komersial, tapi fungsionalitas tersebut saat ini harus dilakukan dengan menggunakan dukungan Spherical Mercator. Informasi lebih lanjut tersedia di http://trac.openlayers.org/wiki/SphericalMercator.\",\n\n    'methodDeprecated': \"Metode ini telah usang dan akan dihapus di 3.0. Sebaliknya, harap gunakan ${newMethod}.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/io.js",
    "content": "/* Translators (2009 onwards):\n *  - Malafaya\n */\n\n\nOpenLayers.Lang[\"io\"] = OpenLayers.Util.applyDefaults({\n\n    'Scale = 1 : ${scaleDenom}': \"Skalo = 1 : ${scaleDenom}\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/is.js",
    "content": "/* Translators (2009 onwards):\n *  - Ævar Arnfjörð Bjarmason\n */\n\n\nOpenLayers.Lang[\"is\"] = OpenLayers.Util.applyDefaults({\n\n    'Permalink': \"Varanlegur tengill\",\n\n    'Overlays': \"Þekjur\",\n\n    'Base Layer': \"Grunnlag\",\n\n    'Scale = 1 : ${scaleDenom}': \"Skali = 1 : ${scaleDenom}\",\n\n    'methodDeprecated': \"Þetta fall hefur verið úrelt og verður fjarlægt í 3.0. Notaðu ${newMethod} í staðin.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/it.js",
    "content": "\nOpenLayers.Lang.it = {\n\n    'unhandledRequest': \"Codice di ritorno della richiesta ${statusText}\",\n\n    'Permalink': \"Permalink\",\n\n    'Overlays': \"Overlay\",\n\n    'Base Layer': \"Livello base\",\n\n    'noFID': \"Impossibile aggiornare un elemento grafico che non abbia il FID.\",\n\n    'browserNotSupported':\n        \"Il tuo browser non supporta il rendering vettoriale. I renderizzatori attualmente supportati sono:\\n${renderers}\",\n    'minZoomLevelError':\n        \"La proprietà minZoomLevel è da utilizzare solamente \" +\n        \"con livelli discendenti da FixedZoomLevels. Il fatto che \" +\n        \"questo livello wfs controlli la proprietà minZoomLevel è \" +\n        \"un retaggio del passato. Non possiamo comunque rimuoverla \" +\n        \"senza rompere le vecchie applicazioni che dipendono da essa.\" +\n        \" Quindi la deprechiamo -- il controllo di minZoomLevel \" +\n        \"sarà rimosso dalla versione 3.0. Si prega di utilizzare \" +\n        \"l'impostazione della risoluzione min/max come descritto qui: \" +\n        \"http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"Transazione WFS: SUCCESSO ${response}\",\n\n    'commitFailed': \"Transazione WFS: FALLIMENTO ${response}\",\n\n    'googleWarning':\n        \"Il livello Google non è stato caricato correttamente.<br><br>\" +\n        \"Per evitare questo messaggio, seleziona un nuovo livello di base \" +\n        \"nel selettore di livelli nell'angolo in alto a destra.<br><br>\" +\n        \"Probabilmente, ciò accade perchè la libreria Google Maps \" +\n        \"non è stata inclusa nella pagina, oppure non contiene la \" +\n        \"corretta API key per il tuo sito.<br><br>\" +\n        \"Sviluppatori: per aiuto su come farlo funzionare correttamente, \" +\n        \"<a href='http://trac.openlayers.org/wiki/Google' \" +\n        \"target='_blank'>fare clic qui</a>\",\n\n    'getLayerWarning':\n        \"Il livello ${layerType} non è stato caricato correttamente.<br><br>\" +\n        \"Per evitare questo messaggio, seleziona un nuovo livello di base \" +\n        \"nel selettore di livelli nell'angolo in alto a destra.<br><br>\" +\n        \"Probabilmente, ciò accade perché la libreria ${layerLib} \" +\n        \"non è stata inclusa correttamente.<br><br>\" +\n        \"Sviluppatori: per aiuto su come farlo funzionare correttamente, \" +\n        \"<a href='http://trac.openlayers.org/wiki/${layerLib}' \" +\n        \"target='_blank'>fare clic qui</a>\",\n\n    'Scale = 1 : ${scaleDenom}': \"Scala = 1 : ${scaleDenom}\",\n    'W': 'O',\n    'E': 'E',\n    'N': 'N',\n    'S': 'S',\n    'Graticule': 'Reticolato',\n    'reprojectDeprecated':\n        \"Stai utilizzando l'opzione 'reproject' sul livello ${layerName}. \" +\n        \"Questa opzione è deprecata: il suo utilizzo è stato introdotto per\" +\n        \"supportare il disegno dei dati sopra mappe commerciali, ma tale \" + \n        \"funzionalità dovrebbe essere ottenuta tramite l'utilizzo della proiezione \" +\n        \"Spherical Mercator. Per maggiori informazioni consultare \" +\n        \"http://trac.openlayers.org/wiki/SphericalMercator.\",\n    'methodDeprecated':\n        \"Questo metodo è stato deprecato e sarà rimosso dalla versione 3.0. \" +\n        \"Si prega di utilizzare il metodo ${newMethod} in alternativa.\",\n    'end': ''\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/ja.js",
    "content": "/* Translators (2009 onwards):\n *  - Fryed-peach\n *  - Mage Whopper\n */\n\n\nOpenLayers.Lang[\"ja\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"未処理の要求は ${statusText} を返します\",\n\n    'Permalink': \"パーマリンク\",\n\n    'Overlays': \"オーバーレイ\",\n\n    'Base Layer': \"基底レイヤー\",\n\n    'noFID': \"FID のない地物は更新できません。\",\n\n    'browserNotSupported': \"あなたのブラウザはベクターグラフィックスの描写に対応していません。現時点で対応しているソフトウェアは以下のものです。\\n${renderers}\",\n\n    'minZoomLevelError': \"minZoomLevel プロパティは FixedZoomLevels を継承するレイヤーでの使用のみを想定しています。この minZoomLevel に対する WFS レイヤーの検査は歴史的なものです。しかしながら、この検査を除去するとそれに依存する OpenLayers ベースのアプリケーションを破壊してしまう可能性があります。よって廃止が予定されており、この minZoomLevel 検査はバージョン3.0で除去されます。代わりに、http://trac.openlayers.org/wiki/SettingZoomLevels で解説されている、最小および最大解像度設定を使用してください。\",\n\n    'commitSuccess': \"WFS トランザクション: 成功 ${response}\",\n\n    'commitFailed': \"WFS トランザクション: 失敗 ${response}\",\n\n    'googleWarning': \"Google レイヤーが正しく読み込みを行えませんでした。\\x3cbr\\x3e\\x3cbr\\x3eこのメッセージを消すには、右上の隅にあるレイヤー切り替え部分で新しい基底レイヤーを選んでください。\\x3cbr\\x3e\\x3cbr\\x3eおそらく、これは Google マップ用ライブラリのスクリプトが組み込まれていないか、あなたのサイトに対応する正しい API キーが設定されていないためです。\\x3cbr\\x3e\\x3cbr\\x3e開発者の方へ: 正しい動作をさせるために\\x3ca href=\\'http://trac.openlayers.org/wiki/Google\\' target=\\'_blank\\'\\x3eこちらのウィキ\\x3c/a\\x3eを参照してください。\",\n\n    'getLayerWarning': \"${layerType} レイヤーが正しく読み込みを行えませんでした。\\x3cbr\\x3e\\x3cbr\\x3eこのメッセージを消すには、右上の隅にあるレイヤー切り替え部分で新しい基底レイヤーを選んでください。\\x3cbr\\x3e\\x3cbr\\x3eおそらく、これは ${layerLib} ライブラリのスクリプトが正しく組み込まれていないためです。\\x3cbr\\x3e\\x3cbr\\x3e開発者の方へ: 正しい動作をさせるために\\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3eこちらのウィキ\\x3c/a\\x3eを参照してください。\",\n\n    'Scale = 1 : ${scaleDenom}': \"縮尺 = 1 : ${scaleDenom}\",\n\n    'W': \"西\",\n\n    'E': \"東\",\n\n    'N': \"北\",\n\n    'S': \"南\",\n\n    'reprojectDeprecated': \"あなたは「${layerName}」レイヤーで reproject オプションを使っています。このオプションは商用の基底地図上に情報を表示する目的で設計されましたが、現在ではその機能は Spherical Mercator サポートを利用して実現されており、このオプションの使用は非推奨です。追加の情報は http://trac.openlayers.org/wiki/SphericalMercator で入手できます。\",\n\n    'methodDeprecated': \"このメソッドは廃止が予定されており、バージョン3.0で除去されます。代わりに ${newMethod} を使用してください。\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/km.js",
    "content": "/* Translators (2009 onwards):\n *  - វ័ណថារិទ្ធ\n */\n\n\nOpenLayers.Lang[\"km\"] = OpenLayers.Util.applyDefaults({\n\n    'Permalink': \"តំណភ្ជាប់អចិន្ត្រៃយ៍\",\n\n    'Base Layer': \"ស្រទាប់បាត​\",\n\n    'Scale = 1 : ${scaleDenom}': \"មាត្រដ្ឋាន = ១ ៖ ${scaleDenom}\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/ksh.js",
    "content": "/* Translators (2009 onwards):\n *  - Purodha\n */\n\n\nOpenLayers.Lang[\"ksh\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Met dä Antwoot op en Aanfrooch ham_mer nix aanjefange: ${statusText}\",\n\n    'Permalink': \"Lengk op Duuer\",\n\n    'Overlays': \"Drövver jelaat\",\n\n    'Base Layer': \"Jrund-Nivoh\",\n\n    'noFID': \"En Saach, woh kein \\x3ci lang=\\\"en\\\"\\x3eFID\\x3c/i\\x3e för doh es, löht sesch nit ändere.\",\n\n    'browserNotSupported': \"Dinge Brauser kann kein Väktore ußjävve. De Zoote Ußjaabe, di em Momang jon, sen:\\n${renderers}\",\n\n    'minZoomLevelError': \"De Eijeschaff „\\x3ccode lang=\\\"en\\\"\\x3eminZoomLevel\\x3c/code\\x3e“ es bloß doför jedaach, dat mer se met dä Nivvohß bruch, di vun \\x3ccode lang=\\\"en\\\"\\x3eFixedZoomLevels\\x3c/code\\x3e affhange don. Dat dat \\x3ci lang=\\\"en\\\"\\x3eWFS\\x3c/i\\x3e-Nivvoh övverhoup de Eijeschaff „\\x3ccode lang=\\\"en\\\"\\x3eminZoomLevel\\x3c/code\\x3e“ pröhfe deiht, es noch övveresch vun fröhjer. Mer künne dat ävver jez nit fott lohße, oohne dat mer Jevaa loufe, dat Aanwendunge vun OpenLayers nit mieh loufe, di sesch doh velleijsch noch drop am verlohße sin. Dröm sare mer, dat mer et nit mieh han welle, un de „\\x3ccode lang=\\\"en\\\"\\x3eminZoomLevel\\x3c/code\\x3e“-Eijeschaff weed hee vun de Version 3.0 af nit mieh jeprööf wäde. Nemm doför de Enstellung för de hühßte un de kleinßte Oplöhsung, esu wi et en http://trac.openlayers.org/wiki/SettingZoomLevels opjeschrevve es.\",\n\n    'commitSuccess': \"Dä \\x3ci lang=\\\"en\\\"\\x3eWFS\\x3c/i\\x3e-Vörjang es joot jeloufe: ${response}\",\n\n    'commitFailed': \"Dä \\x3ci lang=\\\"en\\\"\\x3eWFS\\x3c/i\\x3e-Vörjang es scheif jejange: ${response}\",\n\n    'googleWarning': \"Dat Nivvoh \\x3ccode lang=\\\"en\\\"\\x3eGoogle\\x3c/code\\x3e kunnt nit reschtesch jelaade wääde.\\x3cbr /\\x3e\\x3cbr /\\x3eÖm hee di Nohreesch loß ze krijje, donn en ander Jrund-Nivvoh ußsöhke, rähß bovve en de Äk.\\x3cbr /\\x3e\\x3cbr /\\x3eWascheinlesch es dat wiel dat \\x3ci lang=\\\"en\\\"\\x3eGoogle-Maps\\x3c/i\\x3e-Skrepp entweeder nit reschtesch enjebonge wood, udder nit dä reschtejje \\x3ci lang=\\\"en\\\"\\x3eAPI\\x3c/i\\x3e-Schlößel för Ding Web-ßait scheke deiht.\\x3cbr /\\x3e\\x3cbr /\\x3eFör Projrammierer jidd_et Hölp do_drövver, \\x3ca href=\\\"http://trac.openlayers.org/wiki/Google\\\" target=\\\"_blank\\\"\\x3ewi mer dat aan et Loufe brengk\\x3c/a\\x3e.\",\n\n    'getLayerWarning': \"Dat Nivvoh \\x3ccode\\x3e${layerType}\\x3c/code\\x3e kunnt nit reschtesch jelaade wääde.\\x3cbr /\\x3e\\x3cbr /\\x3eÖm hee di Nohreesch loß ze krijje, donn en ander Jrund-Nivvoh ußsöhkre, rähß bovve en de Äk.\\x3cbr /\\x3e\\x3cbr /\\x3eWascheinlesch es dat, wiel dat Skrepp \\x3ccode\\x3e${layerLib}\\x3c/code\\x3e nit reschtesch enjebonge wood.\\x3cbr /\\x3e\\x3cbr /\\x3eFör Projrammierer jidd_Et Hölp do_drövver, \\x3ca href=\\\"http://trac.openlayers.org/wiki/${layerLib}\\\" target=\\\"_blank\\\"\\x3ewi mer dat aan et Loufe brengk\\x3c/a\\x3e.\",\n\n    'Scale = 1 : ${scaleDenom}': \"Mohßshtaab = 1 : ${scaleDenom}\",\n\n    'W': \"W\",\n\n    'E': \"O\",\n\n    'N': \"N\",\n\n    'S': \"S\",\n\n    'reprojectDeprecated': \"Do bruchs de Ußwahl \\x3ccode\\x3ereproject\\x3c/code\\x3e op däm Nivvoh \\x3ccode\\x3e${layerName}\\x3c/code\\x3e. Di Ußwahl es nit mieh jähn jesinn. Se wohr doför jedaach, öm Date op jeschääfsmäßesch eruß jejovve Kaate bovve drop ze moole, wat ävver enzwesche besser met dä Öngershtözung för de ßfääresche Mäkaator Beldscher jeiht. Doh kanns De mieh drövver fenge op dä Sigg: http://trac.openlayers.org/wiki/SphericalMercator.\",\n\n    'methodDeprecated': \"Hee di Metood es nim_mih aktoäll un et weed se en dä Version 3.0 nit mieh jävve. Nemm \\x3ccode\\x3e${newMethod}\\x3c/code\\x3e doföör.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/lt.js",
    "content": "\nOpenLayers.Lang['lt'] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Neapdorota užklausa gražino ${statusText}\",\n\n    'Permalink': \"Pastovi nuoroda\",\n\n    'Overlays': \"Papildomi sluoksniai\",\n\n    'Base Layer': \"Pagrindinis sluoksnis\",\n\n    'noFID': \"Negaliu atnaujinti objekto, kuris neturi FID.\",\n\n    'browserNotSupported':\n    \"Jūsų naršyklė nemoka parodyti vektorių. Šiuo metu galima naudotis tokiais rodymo varikliais:\\n{renderers}\",\n\n    'commitSuccess': \"WFS Tranzakcija: PAVYKO ${response}\",\n\n    'commitFailed': \"WFS Tranzakcija: ŽLUGO ${response}\",\n\n    'Scale = 1 : ${scaleDenom}': \"Mastelis = 1 : ${scaleDenom}\",\n    'W': 'V',\n    'E': 'R',\n    'N': 'Š',\n    'S': 'P',\n    'Graticule': 'Tinklelis',\n    'methodDeprecated':\n    \"Šis metodas yra pasenęs ir 3.0 versijoje bus pašalintas. \" +\n    \"Prašome naudoti ${newMethod}.\",\n    'end': ''\n    \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/nb.js",
    "content": "\nOpenLayers.Lang[\"nb\"] = {\n\n    'unhandledRequest': \"Ubehandlet forespørsel returnerte ${statusText}\",\n\n    'Permalink': \"Kobling til denne siden\",\n\n    'Overlays': \"Kartlag\",\n\n    'Base Layer': \"Bakgrunnskart\",\n\n    'noFID': \"Kan ikke oppdatere et feature (et objekt) som ikke har FID.\",\n\n    'browserNotSupported':\n        \"Din nettleser støtter ikke vektortegning. Tegnemetodene som støttes er:\\n${renderers}\",\n    'minZoomLevelError':\n        \"Egenskapen minZoomLevel er kun ment til bruk på lag \" +\n        \"basert på FixedZoomLevels. At dette wfs-laget sjekker \" +\n        \"minZoomLevel er en etterlevning fra tidligere versjoner. Det kan dog ikke \" +\n        \"tas bort uten å risikere at OL-baserte applikasjoner \" +\n        \"slutter å virke, så det er merket som foreldet: \" +\n        \"minZoomLevel i sjekken nedenfor vil fjernes i 3.0. \" +\n        \"Vennligst bruk innstillingene for min/maks oppløsning \" +\n        \"som er beskrevet her: \"+\n        \"http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"WFS-transaksjon: LYKTES ${response}\",\n\n    'commitFailed': \"WFS-transaksjon: MISLYKTES ${response}\",\n\n    'googleWarning':\n        \"Google-laget kunne ikke lastes.<br><br>\" +\n        \"Bytt til et annet bakgrunnslag i lagvelgeren i \" +\n        \"øvre høyre hjørne for å slippe denne meldingen.<br><br>\" +\n        \"Sannsynligvis forårsakes feilen av at Google Maps-biblioteket \" +\n        \"ikke er riktig inkludert på nettsiden, eller at det ikke er \" +\n        \"angitt riktig API-nøkkel for nettstedet.<br><br>\" +\n        \"Utviklere: For hjelp til å få dette til å virke se \"+\n        \"<a href='http://trac.openlayers.org/wiki/Google' \" +\n        \"target='_blank'>her</a>.\",\n\n    'getLayerWarning':\n        \"${layerType}-laget kunne ikke lastes.<br><br>\" +\n        \"Bytt til et annet bakgrunnslag i lagvelgeren i \" +\n        \"øvre høyre hjørne for å slippe denne meldingen.<br><br>\" +\n        \"Sannsynligvis forårsakes feilen av at \" +\n        \"${layerLib}-biblioteket ikke var riktig inkludert \" +\n        \"på nettsiden.<br><br>\" +\n        \"Utviklere: For hjelp til å få dette til å virke se \" +\n        \"<a href='http://trac.openlayers.org/wiki/${layerLib}' \" +\n        \"target='_blank'>her</a>.\",\n\n    'Scale = 1 : ${scaleDenom}': \"Skala = 1 : ${scaleDenom}\",\n    'W': 'V',\n    'E': 'Ø',\n    'N': 'N',\n    'S': 'S',\n    'Graticule': 'Gradnett',\n    'reprojectDeprecated':\n        \"Du bruker innstillingen 'reproject' på laget ${layerName}. \" +\n        \"Denne innstillingen er foreldet, den var ment for å støtte \" +\n        \"visning av kartdata over kommersielle bakgrunnskart, men det \" +\n        \"bør nå gjøres med støtten for Spherical Mercator. Mer informasjon \" +\n        \"finnes på http://trac.openlayers.org/wiki/SphericalMercator.\",\n    'methodDeprecated':\n        \"Denne metoden er markert som foreldet og vil bli fjernet i 3.0. \" +\n        \"Vennligst bruk ${newMethod} i stedet.\",\n\n    'end': ''\n};\n\nOpenLayers.Lang[\"no\"] = OpenLayers.Lang[\"nb\"];\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/nds.js",
    "content": "/* Translators (2009 onwards):\n *  - Slomox\n */\n\n\nOpenLayers.Lang[\"nds\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Unbehannelt Trüchmellels för de Anfraag ${statusText}\",\n\n    'Permalink': \"Permalink\",\n\n    'Overlays': \"Overlays\",\n\n    'Base Layer': \"Achtergrundkoort\",\n\n    'noFID': \"En Feature, dat keen FID hett, kann nich aktuell maakt warrn.\",\n\n    'browserNotSupported': \"Dien Browser ünnerstütt keen Vektorbiller. Ünnerstütt Renderers:\\n${renderers}\",\n\n    'commitSuccess': \"WFS-Transakschoon: hett klappt ${response}\",\n\n    'commitFailed': \"WFS-Transakschoon: hett nich klappt ${response}\",\n\n    'Scale = 1 : ${scaleDenom}': \"Skaal = 1 : ${scaleDenom}\",\n\n    'methodDeprecated': \"Disse Methood is oold un schall dat in 3.0 nich mehr geven. Bruuk dor man beter ${newMethod} för.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/nl.js",
    "content": "/* Translators (2009 onwards):\n *  - Siebrand\n */\n\n\nOpenLayers.Lang[\"nl\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Het verzoek is niet afgehandeld met de volgende melding: ${statusText}\",\n\n    'Permalink': \"Permanente verwijzing\",\n\n    'Overlays': \"Overlays\",\n\n    'Base Layer': \"Achtergrondkaart\",\n\n    'noFID': \"Een optie die geen FID heeft kan niet bijgewerkt worden.\",\n\n    'browserNotSupported': \"Uw browser ondersteunt het weergeven van vectoren niet.\\nMomenteel ondersteunde weergavemogelijkheden:\\n${renderers}\",\n\n    'minZoomLevelError': \"De eigenschap minZoomLevel is alleen bedoeld voor gebruik lagen met die afstammen van FixedZoomLevels-lagen.\\nDat deze WFS-laag minZoomLevel controleert, is een overblijfsel uit het verleden.\\nWe kunnen deze controle echter niet verwijderen zonder op OL gebaseerde applicaties die hervan afhankelijk zijn stuk te maken.\\nDaarom heeft deze functionaliteit de eigenschap \\'deprecated\\' gekregen - de minZoomLevel wordt verwijderd in versie 3.0.\\nGebruik in plaats van deze functie de mogelijkheid om min/max voor resolutie in te stellen zoals op de volgende pagina wordt beschreven:\\nhttp://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"WFS-transactie: succesvol ${response}\",\n\n    'commitFailed': \"WFS-transactie: mislukt ${response}\",\n\n    'googleWarning': \"De Google-Layer kon niet correct geladen worden.\\x3cbr /\\x3e\\x3cbr /\\x3e\\nOm deze melding niet meer te krijgen, moet u een andere achtergrondkaart kiezen in de laagwisselaar in de rechterbovenhoek.\\x3cbr /\\x3e\\x3cbr /\\x3e\\nDit komt waarschijnlijk doordat de bibliotheek ${layerLib} niet correct ingevoegd is.\\x3cbr /\\x3e\\x3cbr /\\x3e\\nOntwikkelaars: \\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3eklik hier\\x3c/a\\x3e om dit werkend te krijgen.\",\n\n    'getLayerWarning': \"De laag ${layerType} kon niet goed geladen worden.\\x3cbr /\\x3e\\x3cbr /\\x3e\\nOm deze melding niet meer te krijgen, moet u een andere achtergrondkaart kiezen in de laagwisselaar in de rechterbovenhoek.\\x3cbr /\\x3e\\x3cbr /\\x3e\\nDit komt waarschijnlijk doordat de bibliotheek ${layerLib} niet correct is ingevoegd.\\x3cbr /\\x3e\\x3cbr /\\x3e\\nOntwikkelaars: \\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3eklik hier\\x3c/a\\x3e om dit werkend te krijgen.\",\n\n    'Scale = 1 : ${scaleDenom}': \"Schaal = 1 : ${scaleDenom}\",\n\n    'W': \"W\",\n\n    'E': \"O\",\n\n    'N': \"N\",\n\n    'S': \"Z\",\n\n    'reprojectDeprecated': \"U gebruikt de optie \\'reproject\\' op de laag ${layerName}.\\nDeze optie is vervallen: deze optie was ontwikkeld om gegevens over commerciële basiskaarten weer te geven, maar deze functionaliteit wordt nu bereikt door ondersteuning van Spherical Mercator.\\nMeer informatie is beschikbaar op http://trac.openlayers.org/wiki/SphericalMercator.\",\n\n    'methodDeprecated': \"Deze methode is verouderd en wordt verwijderd in versie 3.0.\\nGebruik ${newMethod}.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/nn.js",
    "content": "/* Translators (2009 onwards):\n *  - Harald Khan\n */\n\n\nOpenLayers.Lang[\"nn\"] = OpenLayers.Util.applyDefaults({\n\n    'Scale = 1 : ${scaleDenom}': \"Skala = 1 : ${scaleDenom}\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/oc.js",
    "content": "/* Translators (2009 onwards):\n *  - Cedric31\n */\n\n\nOpenLayers.Lang[\"oc\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Requèsta pas gerida, retorna ${statusText}\",\n\n    'Permalink': \"Permaligam\",\n\n    'Overlays': \"Calques\",\n\n    'Base Layer': \"Calc de basa\",\n\n    'noFID': \"Impossible de metre a jorn un objècte sens identificant (fid).\",\n\n    'browserNotSupported': \"Vòstre navegidor supòrta pas lo rendut vectorial. Los renderers actualament suportats son : \\n${renderers}\",\n\n    'minZoomLevelError': \"La proprietat minZoomLevel deu èsser utilizada solament per de jaces FixedZoomLevels-descendent. Lo fach qu\\'aqueste jaç WFS verifique la preséncia de minZoomLevel es una relica del passat. Çaquelà, la podèm suprimir sens copar d\\'aplicacions que ne poirián dependre. Es per aquò que la depreciam -- la verificacion del minZoomLevel serà suprimida en version 3.0. A la plaça, mercés d\\'utilizar los paramètres de resolucions min/max tal coma descrich sus : http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"Transaccion WFS : SUCCES ${response}\",\n\n    'commitFailed': \"Transaccion WFS : FRACAS ${response}\",\n\n    'googleWarning': \"Lo jaç Google es pas estat en mesura de se cargar corrèctament.\\x3cbr\\x3e\\x3cbr\\x3ePer suprimir aqueste messatge, causissètz una BaseLayer novèla dins lo selector de jaç en naut a drecha.\\x3cbr\\x3e\\x3cbr\\x3eAquò es possiblament causat par la non-inclusion de la librariá Google Maps, o alara perque que la clau de l\\'API correspond pas a vòstre site.\\x3cbr\\x3e\\x3cbr\\x3eDesvolopaires : per saber cossí corregir aquò, \\x3ca href=\\'http://trac.openlayers.org/wiki/Google\\' target=\\'_blank\\'\\x3eclicatz aicí\\x3c/a\\x3e\",\n\n    'getLayerWarning': \"Lo jaç ${layerType} es pas en mesura de se cargar corrèctament.\\x3cbr\\x3e\\x3cbr\\x3ePer suprimir aqueste messatge, causissètz una  BaseLayer novèla dins lo selector de jaç en naut a drecha.\\x3cbr\\x3e\\x3cbr\\x3eAquò es possiblament causat per la non-inclusion de la librariá ${layerLib}.\\x3cbr\\x3e\\x3cbr\\x3eDesvolopaires : per saber cossí corregir aquí, \\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3eclicatz aicí\\x3c/a\\x3e\",\n\n    'Scale = 1 : ${scaleDenom}': \"Escala ~ 1 : ${scaleDenom}\",\n\n    'W': \"O\",\n\n    'E': \"È\",\n\n    'N': \"N\",\n\n    'S': \"S\",\n\n    'reprojectDeprecated': \"Utilizatz l\\'opcion \\'reproject\\' sul jaç ${layerName}. Aquesta opcion es despreciada : Son usatge permetiá d\\'afichar de donadas al dessús de jaces raster comercials. Aquesta foncionalitat ara es suportada en utilizant lo supòrt de la projeccion Mercator Esferica. Mai d\\'informacion es disponibla sus http://trac.openlayers.org/wiki/SphericalMercator.\",\n\n    'methodDeprecated': \"Aqueste metòde es despreciada, e serà suprimida a la version 3.0. Mercés d\\'utilizar ${newMethod} a la plaça.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/pl.js",
    "content": "/* Translators:\n *  - Arkadiusz Grabka\n */\n\n\nOpenLayers.Lang[\"pl\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Nieobsługiwane żądanie zwróciło ${statusText}\",\n\n    'Permalink': \"Permalink\",\n\n    'Overlays': \"Nakładki\",\n\n    'Base Layer': \"Warstwa podstawowa\",\n\n    'noFID': \"Nie można zaktualizować funkcji, dla których nie ma FID.\",\n\n    'browserNotSupported':\n        \"Twoja przeglądarka nie obsługuje renderowania wektorów. Obecnie obsługiwane renderowanie to:\\n${renderers}\",\n    'minZoomLevelError':\n        \"Właściwość minZoomLevel jest przeznaczona tylko do użytku \" +\n        \"z warstwami FixedZoomLevels-descendent.\" +\n        \"Warstwa wfs, która sprawdza minZoomLevel jest reliktem przeszłości.\" +\n        \"Nie możemy jej jednak usunąc bez mozliwości łamania OL aplikacji, \" +\n        \"które mogą być od niej zależne. \" +\n        \"Dlatego jesteśmy za deprecjację -- minZoomLevel \" +\n        \"zostanie usunięta w wersji 3.0. W zamian prosze użyj \" +\n        \"min/max rozdzielczości w sposób opisany tutaj: \" +\n        \"http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"Transakcja WFS: SUKCES ${response}\",\n\n    'commitFailed': \"Transakcja WFS: FAILED ${response}\",\n\n    'googleWarning':\n        \"Warstwa Google nie był w stanie załadować się poprawnie.<br><br>\" +\n        \"Aby pozbyć się tej wiadomości, wybierz nową Warstwe podstawową \" +\n        \"w przełączniku warstw w górnym prawym rogu mapy.<br><br>\" +\n        \"Najprawdopodobniej jest to spowodowane tym, że biblioteka Google Maps \" +\n        \"nie jest załadowana, lub nie zawiera poprawnego klucza do API dla twojej strony<br><br>\" +\n        \"Programisto: Aby uzyskać pomoc , \" +\n        \"<a href='http://trac.openlayers.org/wiki/Google' \" +\n        \"target='_blank'>kliknij tutaj</a>\",\n\n    'getLayerWarning':\n        \"Warstwa ${layerType} nie mogła zostać załadowana poprawnie.<br><br>\" +\n        \"Aby pozbyć się tej wiadomości, wybierz nową Warstwe podstawową \" +\n        \"w przełączniku warstw w górnym prawym rogu mapy.<br><br>\" +\n        \"Najprawdopodobniej jest to spowodowane tym, że biblioteka ${layerLib} \" +\n        \"nie jest załadowana, lub może(o ile biblioteka tego wymaga) \" +\n        \"byc potrzebny klucza do API dla twojej strony<br><br>\" +\n        \"Programisto: Aby uzyskać pomoc , \" +\n        \"<a href='http://trac.openlayers.org/wiki/${layerLib}' \" +\n        \"target='_blank'>kliknij tutaj</a>\",\n\n    'Scale = 1 : ${scaleDenom}': \"Skala = 1 : ${scaleDenom}\",\n    'W': 'ZACH',\n    'E': 'WSCH',\n    'N': 'PN',\n    'S': 'PD',\n    'Graticule': 'Siatka',\n    'reprojectDeprecated':\n        \"w warstwie ${layerName} używasz opcji 'reproject'. \" +\n        \"Ta opcja jest przestarzała: \" +\n        \"jej zastosowanie został zaprojektowany, aby wspierać wyświetlania danych przez komercyjne mapy, \"+\n        \"jednak obecnie ta funkcjonalność powinien zostać osiągnięty za pomocą Spherical Mercator \" +\n        \"its use was designed to support displaying data over commercial. Więcje informacji na ten temat możesz znaleźć na stronie \" + \n        \"http://trac.openlayers.org/wiki/SphericalMercator.\",\n    'methodDeprecated':\n        \"Ta metoda jest przestarzała i będzie usunięta od wersji 3.0. \" +\n        \"W zamian użyj ${newMethod}.\"\n});"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/pt-BR.js",
    "content": "/* Translators (2009 onwards):\n *  - Luckas Blade\n *  - Rodrigo Avila\n */\n\n\nOpenLayers.Lang[\"pt-BR\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"A requisição retornou um erro não tratado: ${statusText}\",\n\n    'Permalink': \"Link para essa página\",\n\n    'Overlays': \"Camadas de Sobreposição\",\n\n    'Base Layer': \"Camada Base\",\n\n    'noFID': \"Não é possível atualizar uma feição que não tenha um FID.\",\n\n    'browserNotSupported': \"Seu navegador não suporta renderização de vetores. Os renderizadores suportados atualmente são:\\n${renderers}\",\n\n    'minZoomLevelError': \"A propriedade minZoomLevel é de uso restrito das camadas descendentes de FixedZoomLevels. A verificação dessa propriedade pelas camadas wfs é um resíduo do passado. Não podemos, entretanto não é possível removê-la sem possívelmente quebrar o funcionamento de aplicações OL que possuem depência com ela. Portanto estamos tornando seu uso obsoleto -- a verificação desse atributo será removida na versão 3.0. Ao invés, use as opções de resolução min/max como descrito em: http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"Transação WFS : SUCESSO ${response}\",\n\n    'commitFailed': \"Transação WFS : ERRO ${response}\",\n\n    'googleWarning': \"Não foi possível carregar a camada Google corretamente.\\x3cbr\\x3e\\x3cbr\\x3ePara se livrar dessa mensagem, selecione uma nova Camada Base, na ferramenta de alternação de camadas localização do canto superior direito.\\x3cbr\\x3e\\x3cbr\\x3eMuito provavelmente, isso foi causado porque o script da biblioteca do Google Maps não foi incluído, ou porque ele não contém a chave correta da API para o seu site.\\x3cbr\\x3e\\x3cbr\\x3eDesenvolvedores: Para obter ajuda em solucionar esse problema \\x3ca href=\\'http://trac.openlayers.org/wiki/Google\\' target=\\'_blank\\'\\x3ecliquem aqui\\x3c/a\\x3e\",\n\n    'getLayerWarning': \"Não foi possível carregar a camada ${layerType} corretamente.\\x3cbr\\x3e\\x3cbr\\x3ePara se livrar dessa mensagem, selecione uma nova Camada Base, na ferramenta de alternação de camadas localização do canto superior direito.\\x3cbr\\x3e\\x3cbr\\x3eMuito provavelmente, isso foi causado porque o script da biblioteca ${layerLib} não foi incluído corretamente.\\x3cbr\\x3e\\x3cbr\\x3eDesenvolvedores: Para obter ajuda em solucionar esse problema \\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3ecliquem aqui\\x3c/a\\x3e\",\n\n    'Scale = 1 : ${scaleDenom}': \"Escala = 1 : ${scaleDenom}\",\n\n    'W': \"O\",\n\n    'E': \"L\",\n\n    'N': \"N\",\n\n    'S': \"S\",\n\n    'reprojectDeprecated': \"Você está usando a opção \\'reproject\\' na camada ${layerName}. Essa opção está obsoleta: seu uso foi projetado para suportar a visualização de dados sobre bases de mapas comerciais, entretanto essa funcionalidade deve agora ser alcançada usando o suporte à projeção Mercator. Mais informação está disponível em: http://trac.openlayers.org/wiki/SphericalMercator.\",\n\n    'methodDeprecated': \"Esse método está obsoleto e será removido na versão 3.0. Ao invés, por favor use ${newMethod}.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/pt.js",
    "content": "/* Translators (2009 onwards):\n *  - Hamilton Abreu\n *  - Malafaya\n *  - Waldir\n */\n\n\nOpenLayers.Lang[\"pt\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Servidor devolveu erro não contemplado ${statusText}\",\n\n    'Permalink': \"Ligação permanente\",\n\n    'Overlays': \"Sobreposições\",\n\n    'Base Layer': \"Camada Base\",\n\n    'noFID': \"Não é possível atualizar um elemento para a qual não há FID.\",\n\n    'browserNotSupported': \"O seu navegador não suporta renderização vetorial. Actualmente os renderizadores suportados são:\\n${renderers}\",\n\n    'minZoomLevelError': \"A propriedade minZoomLevel só deve ser usada com as camadas descendentes da FixedZoomLevels. A verificação da propriedade por esta camada wfs é uma relíquia do passado. No entanto, não podemos removê-la sem correr o risco de afectar aplicações OL que dependam dela. Portanto, estamos a torná-la obsoleta -- a verificação minZoomLevel será removida na versão 3.0. Em vez dela, por favor, use as opções de resolução min/max descritas aqui: http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"Transacção WFS: SUCESSO ${response}\",\n\n    'commitFailed': \"Transacção WFS: FALHOU ${response}\",\n\n    'googleWarning': \"A Camada Google não foi correctamente carregada.\\x3cbr\\x3e\\x3cbr\\x3ePara deixar de receber esta mensagem, seleccione uma nova Camada-Base no \\'\\'switcher\\'\\' de camadas no canto superior direito.\\x3cbr\\x3e\\x3cbr\\x3eProvavelmente, isto acontece porque o \\'\\'script\\'\\' da biblioteca do Google Maps não foi incluído ou não contém a chave API correcta para o seu sítio.\\x3cbr\\x3e\\x3cbr\\x3eProgramadores: Para ajuda sobre como solucionar o problema \\x3ca href=\\'http://trac.openlayers.org/wiki/Google\\' target=\\'_blank\\'\\x3eclique aqui\\x3c/a\\x3e .\",\n\n    'getLayerWarning': \"A camada ${layerType} não foi correctamente carregada.\\x3cbr\\x3e\\x3cbr\\x3ePara desactivar esta mensagem, seleccione uma nova Camada-Base no \\'\\'switcher\\'\\' de camadas no canto superior direito.\\x3cbr\\x3e\\x3cbr\\x3eProvavelmente, isto acontece porque o \\'\\'script\\'\\' da biblioteca ${layerLib} não foi incluído correctamente.\\x3cbr\\x3e\\x3cbr\\x3eProgramadores: Para ajuda sobre como solucionar o problema \\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3eclique aqui\\x3c/a\\x3e .\",\n\n    'Scale = 1 : ${scaleDenom}': \"Escala = 1 : ${scaleDenom}\",\n\n    'W': \"O\",\n\n    'E': \"E\",\n\n    'N': \"N\",\n\n    'S': \"S\",\n\n    'reprojectDeprecated': \"Está usando a opção \\'reproject\\' na camada ${layerName}. Esta opção é obsoleta: foi concebida para permitir a apresentação de dados sobre mapas-base comerciais, mas esta funcionalidade é agora suportada pelo Mercator Esférico. Mais informação está disponível em http://trac.openlayers.org/wiki/SphericalMercator.\",\n\n    'methodDeprecated': \"Este método foi declarado obsoleto e será removido na versão 3.0. Por favor, use ${newMethod} em vez disso.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/ro.js",
    "content": "OpenLayers.Lang.ro = {\n    'unhandledRequest': \"Cerere nesoluționată return ${statusText}\",\n    'Permalink': \"Legatură permanentă\",\n    'Overlays': \"Straturi vector\",\n    'Base Layer': \"Straturi de bază\",\n    'noFID': \"Nu pot actualiza un feature pentru care nu există FID.\",\n    'browserNotSupported':\n        \"Browserul tău nu suportă afișarea vectorilor. Supoetul curent pentru randare:\\n${renderers}\",\n    'minZoomLevelError':\n        \"Proprietatea minZoomLevel este doar pentru a fi folosită \" +\n        \"cu straturile FixedZoomLevels-descendent. De aceea acest \" +\n        \"strat wfs verifică dacă minZoomLevel este o relicvă\" +\n        \". Nu îl putem , oricum, înlătura fără \" +\n        \"a afecta aplicațiile Openlayers care depind de ea.\" +\n        \" De aceea considerăm depreciat -- minZoomLevel \" +\n        \"și îl vom înlătura în 3.0. Folosește \" +\n        \"min/max resolution cum este descrisă aici: \" +\n        \"http://trac.openlayers.org/wiki/SettingZoomLevels\",\n    'commitSuccess': \"Tranzacție WFS: SUCCES ${response}\",\n    'commitFailed': \"Tranzacție WFS : EȘEC ${response}\",\n    'googleWarning':\n        \"Stratul Google nu a putut fi încărcat corect.<br><br>\" +\n        \"Pentru a elimina acest mesaj, selectează un nou strat de bază \" +\n        \"în Layerswitcher din colțul dreata-sus.<br><br>\" +\n        \"Asta datorită, faptului că Google Maps library \" +\n        \"script nu este inclus, sau nu conține \" +\n        \"cheia API corectă pentru situl tău.<br><br>\" +\n        \"Developeri: Pentru ajutor, \" +\n        \"<a href='http://trac.openlayers.org/wiki/Google' \" +\n        \"target='_blank'>apăsați aici</a>\",\n    'getLayerWarning':\n        \"Stratul ${layerType} nu a putut fi încărcat corect.<br><br>\" +\n        \"pentru a înlătura acest mesaj, selectează un nou strat de bază \" +\n        \"Acesta eroare apare de obicei când ${layerLib} library \" +\n        \"script nu a fost încărcat corect.<br><br>\" +\n        \"Developeri: Pentru ajutor privind utilizarea corectă, \" +\n        \"<a href='http://trac.openlayers.org/wiki/${layerLib}' \" +\n        \"target='_blank'>apasă aici</a>\",\n    'Scale = 1 : ${scaleDenom}': \"Scara = 1 : ${scaleDenom}\",\n    'W': 'V',\n    'E': 'E',\n    'N': 'N',\n    'S': 'S',\n    'Graticule': 'Graticule',\n    'reprojectDeprecated':\n        \"folosești opțiunea 'reproject' \" +\n        \"pentru stratul ${layerName} . Această opțiune este depreciată: \" +\n        \"a fost utilizată pentru afișarea straturilor de bază comerciale \" + \n        \"Mai multe informații despre proiecția Mercator sunt disponibile aici \" +\n        \"http://trac.openlayers.org/wiki/SphericalMercator.\",\n    'methodDeprecated':\n        \"Această metodă este depreciată și va fi înlăturată in versiunea 3.0. \" +\n        \"folosește metoda ${newMethod}.\",\n    'end': ''\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/ru.js",
    "content": "/* Translators (2009 onwards):\n *  - Ferrer\n *  - Komzpa\n *  - Lockal\n *  - Александр Сигачёв\n */\n\n\nOpenLayers.Lang[\"ru\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Необработанный запрос вернул ${statusText}\",\n\n    'Permalink': \"Постоянная ссылка\",\n\n    'Overlays': \"Слои\",\n\n    'Base Layer': \"Основной слой\",\n\n    'noFID': \"Невозможно обновить объект, для которого нет FID.\",\n\n    'browserNotSupported': \"Ваш браузер не поддерживает векторную графику. На данный момент поддерживаются:\\n${renderers}\",\n\n    'minZoomLevelError': \"Свойство minZoomLevel предназначено только для использования со слоями, являющимися потомками FixedZoomLevels. То, что этот WFS-слой проверяется на minZoomLevel — реликт прошлого. Однако мы не можем удалить эту функцию, так как, возможно, от неё зависят некоторые основанные на OpenLayers приложения. Функция объявлена устаревшей — проверка minZoomLevel будет удалена в 3.0. Пожалуйста, используйте вместо неё настройку мин/макс разрешения, описанную здесь: http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"Транзакция WFS: УСПЕШНО ${response}\",\n\n    'commitFailed': \"Транзакция WFS: ОШИБКА ${response}\",\n\n    'googleWarning': \"Слой Google не удалось нормально загрузить.\\x3cbr\\x3e\\x3cbr\\x3eЧтобы избавиться от этого сообщения, выбите другой основной слой в переключателе в правом верхнем углу.\\x3cbr\\x3e\\x3cbr\\x3eСкорее всего, причина в том, что библиотека Google Maps не была включена или не содержит корректного API-ключа для вашего сайта.\\x3cbr\\x3e\\x3cbr\\x3eРазработчикам: чтобы узнать, как сделать, чтобы всё заработало, \\x3ca href=\\'http://trac.openlayers.org/wiki/Google\\' target=\\'_blank\\'\\x3eщёлкните тут\\x3c/a\\x3e\",\n\n    'getLayerWarning': \"Слой ${layerType} не удалось нормально загрузить. \\x3cbr\\x3e\\x3cbr\\x3eЧтобы избавиться от этого сообщения, выбите другой основной слой в переключателе в правом верхнем углу.\\x3cbr\\x3e\\x3cbr\\x3eСкорее всего, причина в том, что библиотека ${layerLib} не была включена или была включена некорректно.\\x3cbr\\x3e\\x3cbr\\x3eРазработчикам: чтобы узнать, как сделать, чтобы всё заработало, \\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3eщёлкните тут\\x3c/a\\x3e\",\n\n    'Scale = 1 : ${scaleDenom}': \"Масштаб = 1 : ${scaleDenom}\",\n\n    'W': \"З\",\n\n    'E': \"В\",\n\n    'N': \"С\",\n\n    'S': \"Ю\",\n\n    'reprojectDeprecated': \"Вы используете опцию \\'reproject\\' для слоя ${layerName}. Эта опция является устаревшей: ее использование предполагалось для поддержки показа данных поверх коммерческих базовых карт, но теперь этот функционал несёт встроенная поддержка сферической проекции Меркатора. Больше сведений доступно на http://trac.openlayers.org/wiki/SphericalMercator.\",\n\n    'methodDeprecated': \"Этот метод считается устаревшим и будет удалён в версии 3.0. Пожалуйста, пользуйтесь ${newMethod}.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/sk.js",
    "content": "/* Translators (2009 onwards):\n *  - Helix84\n */\n\n\nOpenLayers.Lang[\"sk\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Neobslúžené požiadavky vracajú ${statusText}\",\n\n    'Permalink': \"Trvalý odkaz\",\n\n    'Overlays': \"Prekrytia\",\n\n    'Base Layer': \"Základná vrstva\",\n\n    'noFID': \"Nie je možné aktualizovať vlastnosť, pre ktorú neexistuje FID.\",\n\n    'browserNotSupported': \"Váš prehliadač nepodporuje vykresľovanie vektorov. Momentálne podporované vykresľovače sú:\\n${renderers}\",\n\n    'minZoomLevelError': \"Vlastnosť minZoomLevel je určený iba na použitie s vrstvami odvodenými od FixedZoomLevels. To, že táto wfs vrstva kontroluje minZoomLevel je pozostatok z minulosti. Nemôžeme ho však odstrániť, aby sme sa vyhli možnému porušeniu aplikácií založených na Open Layers, ktoré na tomto môže závisieť. Preto ho označujeme ako zavrhovaný - dolu uvedená kontrola minZoomLevel bude odstránená vo verzii 3.0. Použite prosím namiesto toho kontrolu min./max. rozlíšenia podľa tu uvedeného popisu: http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"Transakcia WFS: ÚSPEŠNÁ ${response}\",\n\n    'commitFailed': \"Transakcia WFS: ZLYHALA ${response}\",\n\n    'googleWarning': \"Vrstvu Google nebolo možné správne načítať.\\x3cbr\\x3e\\x3cbr\\x3eAby ste sa tejto správy zbavili vyberte novú BaseLayer v prepínači vrstiev v pravom hornom rohu.\\x3cbr\\x3e\\x3cbr\\x3eToto sa stalo pravdepodobne preto, že skript knižnice Google Maps buď nebol načítaný alebo neobsahuje správny kľúč API pre vašu lokalitu.\\x3cbr\\x3e\\x3cbr\\x3eVývojári: Tu môžete získať \\x3ca href=\\'http://trac.openlayers.org/wiki/Google\\' target=\\'_blank\\'\\x3epomoc so sfunkčnením\\x3c/a\\x3e\",\n\n    'getLayerWarning': \"Vrstvu ${layerType} nebolo možné správne načítať.\\x3cbr\\x3e\\x3cbr\\x3eAby ste sa tejto správy zbavili vyberte novú BaseLayer v prepínači vrstiev v pravom hornom rohu.\\x3cbr\\x3e\\x3cbr\\x3eToto sa stalo pravdepodobne preto, že skript knižnice ${layerType} buď nebol načítaný alebo neobsahuje správny kľúč API pre vašu lokalitu.\\x3cbr\\x3e\\x3cbr\\x3eVývojári: Tu môžete získať \\x3ca href=\\'http://trac.openlayers.org/wiki/${layerType}\\' target=\\'_blank\\'\\x3epomoc so sfunkčnením\\x3c/a\\x3e\",\n\n    'Scale = 1 : ${scaleDenom}': \"Mierka = 1 : ${scaleDenom}\",\n\n    'reprojectDeprecated': \"Používate voľby „reproject“ vrstvy ${layerType}. Táto voľba je zzavrhovaná: jej použitie bolo navrhnuté na podporu zobrazovania údajov nad komerčnými základovými mapami, ale túto funkcionalitu je teraz možné dosiahnuť pomocou Spherical Mercator. Ďalšie informácie získate na stránke http://trac.openlayers.org/wiki/SphericalMercator.\",\n\n    'methodDeprecated': \"Táto metóda je zavrhovaná a bude odstránená vo verzii 3.0. Použite prosím namiesto nej metódu ${newMethod}.\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/sv-SE.js",
    "content": "/* Translators (2009 onwards):\n *  - Sannab\n */\n\n\nOpenLayers.Lang[\"sv\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Ej hanterad fråga retur ${statusText}\",\n\n    'Permalink': \"Permalänk\",\n\n    'Overlays': \"Kartlager\",\n\n    'Base Layer': \"Bakgrundskarta\",\n\n    'noFID': \"Kan ej uppdatera feature (objekt) för vilket FID saknas.\",\n\n    'browserNotSupported': \"Din webbläsare stöder inte vektorvisning. För närvarande stöds följande visning:\\n${renderers}\",\n\n    'minZoomLevelError': \"Egenskapen minZoomLevel är endast avsedd att användas med lager med FixedZoomLevels. Att detta WFS-lager kontrollerar minZoomLevel är en relik från äldre versioner. Vi kan dock inte ta bort det utan att riskera att OL-baserade tillämpningar som använder detta slutar fungera. Därför är det satt som deprecated, minZoomLevel kommer att tas bort i version 3.0. Använd i stället inställning av min/max resolution som beskrivs här: http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"WFS-transaktion: LYCKADES ${response}\",\n\n    'commitFailed': \"WFS-transaktion: MISSLYCKADES ${response}\",\n\n    'googleWarning': \"Google-lagret kunde inte laddas korrekt.\\x3cbr\\x3e\\x3cbr\\x3eFör att slippa detta meddelande, välj en annan bakgrundskarta i lagerväljaren i övre högra hörnet.\\x3cbr\\x3e\\x3cbr\\x3eSannolikt beror felet på att Google Maps-biblioteket inte är inkluderat på webbsidan eller på att sidan inte anger korrekt API-nyckel för webbplatsen.\\x3cbr\\x3e\\x3cbr\\x3eUtvecklare: hjälp för att åtgärda detta, \\x3ca href=\\'http://trac.openlayers.org/wiki/Google\\' target=\\'_blank\\'\\x3eklicka här\\x3c/a\\x3e.\",\n\n    'getLayerWarning': \"${layerType}-lagret kunde inte laddas korrekt.\\x3cbr\\x3e\\x3cbr\\x3eFör att slippa detta meddelande, välj en annan bakgrundskarta i lagerväljaren i övre högra hörnet.\\x3cbr\\x3e\\x3cbr\\x3eSannolikt beror felet på att ${layerLib}-biblioteket inte är inkluderat på webbsidan.\\x3cbr\\x3e\\x3cbr\\x3eUtvecklare: hjälp för att åtgärda detta, \\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3eklicka här\\x3c/a\\x3e.\",\n\n    'Scale = 1 : ${scaleDenom}': \"\\x3cstrong\\x3eSkala\\x3c/strong\\x3e 1 : ${scaleDenom}\",\n\n    'reprojectDeprecated': \"Du använder inställningen \\'reproject\\' på lagret ${layerName}. Denna inställning markerad som deprecated: den var avsedd att användas för att stödja visning av kartdata på kommersiella bakgrundskartor, men nu bör man i stället använda Spherical Mercator-stöd för den funktionaliteten. Mer information finns på http://trac.openlayers.org/wiki/SphericalMercator.\",\n\n    'methodDeprecated': \"Denna metod är markerad som deprecated och kommer att tas bort i 3.0. Använd ${newMethod} i stället.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/te.js",
    "content": "/* Translators (2009 onwards):\n *  - Veeven\n */\n\n\nOpenLayers.Lang[\"te\"] = OpenLayers.Util.applyDefaults({\n\n    'Permalink': \"స్థిరలింకు\",\n\n    'W': \"ప\",\n\n    'E': \"తూ\",\n\n    'N': \"ఉ\",\n\n    'S': \"ద\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/vi.js",
    "content": "/* Translators (2009 onwards):\n *  - Minh Nguyen\n */\n\n\nOpenLayers.Lang[\"vi\"] = OpenLayers.Util.applyDefaults({\n\n    'unhandledRequest': \"Không xử lý được phản hồi ${statusText} cho yêu cầu\",\n\n    'Permalink': \"Liên kết thường trực\",\n\n    'Overlays': \"Lấp bản đồ\",\n\n    'Base Layer': \"Lớp nền\",\n\n    'noFID': \"Không thể cập nhật tính năng thiếu FID.\",\n\n    'browserNotSupported': \"Trình duyệt của bạn không hỗ trợ chức năng vẽ bằng vectơ. Hiện hỗ trợ các bộ kết xuất:\\n${renderers}\",\n\n    'minZoomLevelError': \"Chỉ nên sử dụng thuộc tính minZoomLevel với các lớp FixedZoomLevels-descendent. Việc lớp wfs này tìm cho minZoomLevel là di tích còn lại từ xưa. Tuy nhiên, nếu chúng tôi dời nó thì sẽ vỡ các chương trình OpenLayers mà dựa trên nó. Bởi vậy chúng tôi phản đối sử dụng nó\\x26nbsp;– bước tìm cho minZoomLevel sẽ được dời vào phiên bản 3.0. Xin sử dụng thiết lập độ phân tích tối thiểu / tối đa thay thế, theo hướng dẫn này: http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"Giao dịch WFS: THÀNH CÔNG ${response}\",\n\n    'commitFailed': \"Giao dịch WFS: THẤT BẠI ${response}\",\n\n    'googleWarning': \"Không thể tải lớp Google đúng đắn.\\x3cbr\\x3e\\x3cbr\\x3eĐể tránh thông báo này lần sau, hãy chọn BaseLayer mới dùng điều khiển chọn lớp ở góc trên phải.\\x3cbr\\x3e\\x3cbr\\x3eChắc script thư viện Google Maps hoặc không được bao gồm hoặc không chứa khóa API hợp với website của bạn.\\x3cbr\\x3e\\x3cbr\\x3e\\x3ca href=\\'http://trac.openlayers.org/wiki/Google\\' target=\\'_blank\\'\\x3eTrợ giúp về tính năng này\\x3c/a\\x3e cho người phát triển.\",\n\n    'getLayerWarning': \"Không thể tải lớp ${layerType} đúng đắn.\\x3cbr\\x3e\\x3cbr\\x3eĐể tránh thông báo này lần sau, hãy chọn BaseLayer mới dùng điều khiển chọn lớp ở góc trên phải.\\x3cbr\\x3e\\x3cbr\\x3eChắc script thư viện ${layerLib} không được bao gồm đúng kiểu.\\x3cbr\\x3e\\x3cbr\\x3e\\x3ca href=\\'http://trac.openlayers.org/wiki/${layerLib}\\' target=\\'_blank\\'\\x3eTrợ giúp về tính năng này\\x3c/a\\x3e cho người phát triển.\",\n\n    'Scale = 1 : ${scaleDenom}': \"Tỷ lệ = 1 : ${scaleDenom}\",\n\n    'W': \"T\",\n\n    'E': \"Đ\",\n\n    'N': \"B\",\n\n    'S': \"N\",\n\n    'reprojectDeprecated': \"Bạn đang áp dụng chế độ “reproject” vào lớp ${layerName}. Chế độ này đã bị phản đối: nó có mục đích hỗ trợ lấp dữ liệu trên các nền bản đồ thương mại; nên thực hiện hiệu ứng đó dùng tính năng Mercator Hình cầu. Có sẵn thêm chi tiết tại http://trac.openlayers.org/wiki/SphericalMercator .\",\n\n    'methodDeprecated': \"Phương thức này đã bị phản đối và sẽ bị dời vào phiên bản 3.0. Xin hãy sử dụng ${newMethod} thay thế.\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/zh-CN.js",
    "content": "\nOpenLayers.Lang[\"zh-CN\"] = {\n\n    'unhandledRequest': \"未处理的请求，返回值为 ${statusText}\",\n\n    'Permalink': \"永久链接\",\n\n    'Overlays': \"叠加层\",\n\n    'Base Layer': \"基础图层\",\n\n    'noFID': \"无法更新feature，缺少FID。\",\n\n    'browserNotSupported':\n        \"你使用的浏览器不支持矢量渲染。当前支持的渲染方式包括：\\n${renderers}\",\n    'minZoomLevelError':\n        \"minZoomLevel属性仅适合用于\" +\n        \"使用了固定缩放级别的图层。这个 \" +\n        \"wfs 图层检查 minZoomLevel 是过去遗留下来的。\" +\n        \"然而，我们不能移除它，\" +\n        \"而破坏依赖于它的基于OL的应用程序。\" +\n        \"因此，我们废除了它 -- minZoomLevel \" +\n        \"将会在3.0中被移除。请改用 \" +\n        \"min/max resolution 设置，参考：\" +\n        \"http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"WFS Transaction: 成功。 ${response}\",\n\n    'commitFailed': \"WFS Transaction: 失败。 ${response}\",\n\n    'googleWarning':\n        \"Google图层不能正确加载。<br><br>\" +\n        \"要消除这个信息，请在右上角的\" +\n        \"图层控制面板中选择其他的基础图层。<br><br>\" +\n        \"这种情况很可能是没有正确的包含Google地图脚本库，\" +\n        \"或者是没有包含在你的站点上\" +\n        \"使用的正确的Google Maps API密匙。<br><br>\" +\n        \"开发者：获取使其正确工作的帮助信息，\" +\n        \"<a href='http://trac.openlayers.org/wiki/Google' \" +\n        \"target='_blank'>点击这里</a>\",\n\n    'getLayerWarning':\n        \"${layerType} 图层不能正确加载。<br><br>\" +\n        \"要消除这个信息，请在右上角的\" +\n        \"图层控制面板中选择其他的基础图层。<br><br>\" +\n        \"这种情况很可能是没有正确的包含\" +\n        \"${layerLib} 脚本库。<br><br>\" +\n        \"开发者：获取使其正确工作的帮助信息，\" +\n        \"<a href='http://trac.openlayers.org/wiki/${layerLib}' \" +\n        \"target='_blank'>点击这里</a>\",\n\n    'Scale = 1 : ${scaleDenom}': \"比例尺 = 1 : ${scaleDenom}\",\n    'reprojectDeprecated':\n        \"你正在使用 ${layerName} 图层上的'reproject'选项。\" +\n        \"这个选项已经不再使用：\" +\n        \"它是被设计用来支持显示商业的地图数据，\" + \n        \"不过现在该功能可以通过使用Spherical Mercator来实现。\" +\n        \"更多信息可以参阅\" +\n        \"http://trac.openlayers.org/wiki/SphericalMercator.\",\n    'methodDeprecated':\n        \"该方法已经不再被支持，并且将在3.0中被移除。\" +\n        \"请使用 ${newMethod} 方法来替代。\",\n\n    'end': ''\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang/zh-TW.js",
    "content": "\nOpenLayers.Lang[\"zh-TW\"] = {\n\n    'unhandledRequest': \"未處理的請求，傳回值為 ${statusText}。\",\n\n    'Permalink': \"永久連結\",\n\n    'Overlays': \"額外圖層\",\n\n    'Base Layer': \"基礎圖層\",\n\n    'noFID': \"因為沒有 FID 所以無法更新 feature。\",\n\n    'browserNotSupported':\n        \"您的瀏覽器未支援向量渲染. 目前支援的渲染方式是:\\n${renderers}\",\n    'minZoomLevelError':\n        \"minZoomLevel 屬性僅適合用在 \" +\n        \"FixedZoomLevels-descendent 類型的圖層. 這個\" +\n        \"wfs layer 的 minZoomLevel 是過去所遺留下來的，\" +\n        \"然而我們不能移除它而不讓它將\" +\n        \"過去的程式相容性給破壞掉。\" +\n        \"因此我們將會迴避使用它 -- minZoomLevel \" +\n        \"會在3.0被移除，請改\" +\n        \"用在這邊描述的 min/max resolution 設定: \" +\n        \"http://trac.openlayers.org/wiki/SettingZoomLevels\",\n\n    'commitSuccess': \"WFS Transaction: 成功 ${response}\",\n\n    'commitFailed': \"WFS Transaction: 失敗 ${response}\",\n\n    'googleWarning':\n        \"The Google Layer 圖層無法被正確的載入。<br><br>\" +\n        \"要迴避這個訊息, 請在右上角的圖層改變器裡，\" +\n        \"選一個新的基礎圖層。<br><br>\" +\n        \"很有可能是因為 Google Maps 的函式庫\" +\n        \"腳本沒有被正確的置入，或沒有包含 \" +\n        \"您網站上正確的 API key <br><br>\" +\n        \"開發者: 要幫助這個行為正確完成，\" +\n        \"<a href='http://trac.openlayers.org/wiki/Google' \" +\n        \"target='_blank'>請按這裡</a>\",\n\n    'getLayerWarning':\n        \"${layerType} 圖層無法被正確的載入。<br><br>\" +\n        \"要迴避這個訊息, 請在右上角的圖層改變器裡，\" +\n        \"選一個新的基礎圖層。<br><br>\" +\n        \"很有可能是因為 ${layerLib} 的函式庫\" +\n        \"腳本沒有被正確的置入。<br><br>\" +\n        \"開發者: 要幫助這個行為正確完成，\" +\n        \"<a href='http://trac.openlayers.org/wiki/${layerLib}' \" +\n        \"target='_blank'>請按這裡</a>\",\n\n    'Scale = 1 : ${scaleDenom}': \"Scale = 1 : ${scaleDenom}\",\n    'reprojectDeprecated':\n        \"你正使用 'reproject' 這個選項 \" +\n        \"在 ${layerName} 層。這個選項已經不再使用:\" +\n        \"它的使用原本是設計用來支援在商業地圖上秀出資料，\" + \n        \"但這個功能已經被\" +\n        \"Spherical Mercator所取代。更多的資訊可以在 \" +\n        \"http://trac.openlayers.org/wiki/SphericalMercator 找到。\",\n    'methodDeprecated':\n        \"這個方法已經不再使用且在3.0將會被移除，\" +\n        \"請使用 ${newMethod} 來代替。\",\n\n    'end': ''\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Lang.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Lang = {\n    \n        code: null,\n\n        defaultCode: \"en\",\n        \n        getCode: function() {\n        if(!OpenLayers.Lang.code) {\n            OpenLayers.Lang.setCode();\n        }\n        return OpenLayers.Lang.code;\n    },\n    \n        setCode: function(code) {\n        var lang;\n        if(!code) {\n            code = (OpenLayers.BROWSER_NAME == \"msie\") ?\n                navigator.userLanguage : navigator.language;\n        }\n        var parts = code.split('-');\n        parts[0] = parts[0].toLowerCase();\n        if(typeof OpenLayers.Lang[parts[0]] == \"object\") {\n            lang = parts[0];\n        }\n        if(parts[1]) {\n            var testLang = parts[0] + '-' + parts[1].toUpperCase();\n            if(typeof OpenLayers.Lang[testLang] == \"object\") {\n                lang = testLang;\n            }\n        }\n        if(!lang) {\n            OpenLayers.Console.warn(\n                'Failed to find OpenLayers.Lang.' + parts.join(\"-\") +\n                ' dictionary, falling back to default language'\n            );\n            lang = OpenLayers.Lang.defaultCode;\n        }\n        \n        OpenLayers.Lang.code = lang;\n    },\n\n        translate: function(key, context) {\n        var dictionary = OpenLayers.Lang[OpenLayers.Lang.getCode()];\n        var message = dictionary && dictionary[key];\n        if(!message) {\n            message = key;\n        }\n        if(context) {\n            message = OpenLayers.String.format(message, context);\n        }\n        return message;\n    }\n    \n};\n\n\nOpenLayers.i18n = OpenLayers.Lang.translate;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/ArcGIS93Rest.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Layer.ArcGIS93Rest = OpenLayers.Class(OpenLayers.Layer.Grid, {\n\n        DEFAULT_PARAMS: { \n      format: \"png\"\n    },\n        \n        isBaseLayer: true,\n \n \n        initialize: function(name, url, params, options) {\n        var newArguments = [];\n        params = OpenLayers.Util.upperCaseObject(params);\n        newArguments.push(name, url, params, options);\n        OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);\n        OpenLayers.Util.applyDefaults(\n                       this.params, \n                       OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS)\n                       );\n        if (this.params.TRANSPARENT && \n            this.params.TRANSPARENT.toString().toLowerCase() == \"true\") {\n            if ( (options == null) || (!options.isBaseLayer) ) {\n                this.isBaseLayer = false;\n            } \n            if (this.params.FORMAT == \"jpg\") {\n                this.params.FORMAT = OpenLayers.Util.alphaHack() ? \"gif\"\n                                                                 : \"png\";\n            }\n        }\n    },    \n\n        clone: function (obj) {\n        \n        if (obj == null) {\n            obj = new OpenLayers.Layer.ArcGIS93Rest(this.name,\n                                           this.url,\n                                           this.params,\n                                           this.getOptions());\n        }\n        obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);\n\n        return obj;\n    },\n    \n    \n        getURL: function (bounds) {\n        bounds = this.adjustBounds(bounds);\n        var projWords = this.projection.getCode().split(\":\");\n        var srid = projWords[projWords.length - 1];\n\n        var imageSize = this.getImageSize(bounds); \n        var newParams = {\n            'BBOX': bounds.toBBOX(),\n            'SIZE': imageSize.w + \",\" + imageSize.h,\n            'F': \"image\",\n            'BBOXSR': srid,\n            'IMAGESR': srid\n        };\n        if (this.layerDefs) {\n            var layerDefStrList = [];\n            var layerID;\n            for(layerID in this.layerDefs) {\n                if (this.layerDefs.hasOwnProperty(layerID)) {\n                    if (this.layerDefs[layerID]) {\n                        layerDefStrList.push(layerID);\n                        layerDefStrList.push(\":\");\n                        layerDefStrList.push(this.layerDefs[layerID]);\n                        layerDefStrList.push(\";\");\n                    }\n                }\n            }\n            if (layerDefStrList.length > 0) {\n                newParams['LAYERDEFS'] = layerDefStrList.join(\"\");\n            }\n        }\n        var requestString = this.getFullRequestString(newParams);\n        return requestString;\n    },\n    \n        setLayerFilter: function ( id, queryDef ) {\n        if (!this.layerDefs) {\n            this.layerDefs = {};\n        }\n        if (queryDef) {\n            this.layerDefs[id] = queryDef;\n        } else {\n            delete this.layerDefs[id];\n        }\n    },\n    \n        clearLayerFilter: function ( id ) {\n        if (id) {\n            delete this.layerDefs[id];\n        } else {\n            delete this.layerDefs;\n        }\n    },\n    \n        mergeNewParams:function(newParams) {\n        var upperParams = OpenLayers.Util.upperCaseObject(newParams);\n        var newArguments = [upperParams];\n        return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this, \n                                                             newArguments);\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.ArcGIS93Rest\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/ArcGISCache.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n    url: null,\n    \n        tileOrigin: null, \n   \n        tileSize: new OpenLayers.Size(256, 256),\n    \n        type: 'png',\n    \n        useScales: false,\n    \n        overrideDPI: false,\n\n        hexZoom: false,\n    \n        getContainingTileCoords: function(point, res) {\n        return new OpenLayers.Pixel(\n           Math.max(Math.floor((point.x - this.tileOrigin.lon) / (this.tileSize.w * res)),0),\n           Math.max(Math.floor((this.tileOrigin.lat - point.y) / (this.tileSize.h * res)),0)\n        );\n    },\n    \n        calculateMaxExtentWithLOD: function(lod) {\n\n        var numTileCols = (lod.endTileCol - lod.startTileCol) + 1;\n        var numTileRows = (lod.endTileRow - lod.startTileRow) + 1;        \n\n        var minX = this.tileOrigin.lon + (lod.startTileCol * this.tileSize.w * lod.resolution);\n        var maxX = minX + (numTileCols * this.tileSize.w * lod.resolution);\n\n        var maxY = this.tileOrigin.lat - (lod.startTileRow * this.tileSize.h * lod.resolution);\n        var minY = maxY - (numTileRows * this.tileSize.h * lod.resolution);\n        return new OpenLayers.Bounds(minX, minY, maxX, maxY);\n    },\n    \n        calculateMaxExtentWithExtent: function(extent, res) {\n        var upperLeft = new OpenLayers.Geometry.Point(extent.left, extent.top);\n        var bottomRight = new OpenLayers.Geometry.Point(extent.right, extent.bottom);\n        var start = this.getContainingTileCoords(upperLeft, res);\n        var end = this.getContainingTileCoords(bottomRight, res);\n        var lod = {\n            resolution: res,\n            startTileCol: start.x,\n            startTileRow: start.y,\n            endTileCol: end.x,\n            endTileRow: end.y\n        };\n        return this.calculateMaxExtentWithLOD(lod);\n    },\n    \n        getUpperLeftTileCoord: function(res) {\n        var upperLeft = new OpenLayers.Geometry.Point(\n            this.maxExtent.left,\n            this.maxExtent.top);\n        return this.getContainingTileCoords(upperLeft, res);\n    },\n\n        getLowerRightTileCoord: function(res) {\n        var bottomRight = new OpenLayers.Geometry.Point(\n            this.maxExtent.right,\n            this.maxExtent.bottom);\n        return this.getContainingTileCoords(bottomRight, res);\n    },\n    \n        initGriddedTiles: function(bounds) {\n        delete this._tileOrigin;\n        OpenLayers.Layer.XYZ.prototype.initGriddedTiles.apply(this, arguments);\n    },\n    \n        getMaxExtent: function() {\n        var resolution = this.map.getResolution();\n        return this.maxExtent = this.getMaxExtentForResolution(resolution);\n    },\n\n        getTileOrigin: function() {\n        if (!this._tileOrigin) {\n            var extent = this.getMaxExtent();\n            this._tileOrigin = new OpenLayers.LonLat(extent.left, extent.bottom);\n        }\n        return this._tileOrigin;\n    },\n\n        getURL: function (bounds) {\n        var res = this.getResolution(); \n        var originTileX = (this.tileOrigin.lon + (res * this.tileSize.w/2)); \n        var originTileY = (this.tileOrigin.lat - (res * this.tileSize.h/2));\n\n        var center = bounds.getCenterLonLat();\n        var point = { x: center.lon, y: center.lat };\n        var x = (Math.round(Math.abs((center.lon - originTileX) / (res * this.tileSize.w)))); \n        var y = (Math.round(Math.abs((originTileY - center.lat) / (res * this.tileSize.h)))); \n        var z = this.map.getZoom();\n        if (this.lods) {        \n            var lod = this.lods[this.map.getZoom()];\n            if ((x < lod.startTileCol || x > lod.endTileCol) \n                || (y < lod.startTileRow || y > lod.endTileRow)) {\n                    return null;\n            }\n        }\n        else {\n            var start = this.getUpperLeftTileCoord(res);\n            var end = this.getLowerRightTileCoord(res);\n            if ((x < start.x || x >= end.x)\n                || (y < start.y || y >= end.y)) {\n                    return null;\n            }        \n        }\n        var url = this.url;\n        var s = '' + x + y + z;\n\n        if (OpenLayers.Util.isArray(url)) {\n            url = this.selectUrl(s, url);\n        }\n        if (this.useArcGISServer) {\n            url = url + '/tile/${z}/${y}/${x}';\n        } else {\n            x = 'C' + OpenLayers.Number.zeroPad(x, 8, 16);\n            y = 'R' + OpenLayers.Number.zeroPad(y, 8, 16);\n            z = 'L' + OpenLayers.Number.zeroPad(z, 2, this.hexZoom ? 16 : 10);\n            url = url + '/${z}/${y}/${x}.' + this.type;\n        }\n        url = OpenLayers.String.format(url, {'x': x, 'y': y, 'z': z});\n\n        return OpenLayers.Util.urlAppend(\n            url, OpenLayers.Util.getParameterString(this.params)\n        );\n    },\n\n    CLASS_NAME: 'OpenLayers.Layer.ArcGISCache' \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/ArcIMS.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Layer.ArcIMS = OpenLayers.Class(OpenLayers.Layer.Grid, {\n\n        DEFAULT_PARAMS: { \n        ClientVersion: \"9.2\",\n        ServiceName: ''\n    },\n    \n        featureCoordSys: \"4326\",\n    \n        filterCoordSys: \"4326\",\n    \n        layers: null,\n    \n        async: true,\n    \n        name: \"ArcIMS\",\n\n        isBaseLayer: true,\n\n        DEFAULT_OPTIONS: {\n        tileSize: new OpenLayers.Size(512, 512),\n        featureCoordSys: \"4326\",\n        filterCoordSys: \"4326\",\n        layers: null,\n        isBaseLayer: true,\n        async: true,\n        name: \"ArcIMS\"\n    }, \n \n        initialize: function(name, url, options) {\n        \n        this.tileSize = new OpenLayers.Size(512, 512);\n        this.params = OpenLayers.Util.applyDefaults(\n            {ServiceName: options.serviceName},\n            this.DEFAULT_PARAMS\n        );\n        this.options = OpenLayers.Util.applyDefaults(\n            options, this.DEFAULT_OPTIONS\n        );\n          \n        OpenLayers.Layer.Grid.prototype.initialize.apply(\n            this, [name, url, this.params, options]\n        );\n        if (this.transparent) {\n            if (!this.isBaseLayer) {\n                this.isBaseLayer = false;\n            } \n            if (this.format == \"image/jpeg\") {\n                this.format = OpenLayers.Util.alphaHack() ? \"image/gif\" : \"image/png\";\n            }\n        }\n        if (this.options.layers === null) {\n            this.options.layers = [];\n        }\n    },    \n\n        getURL: function(bounds) {\n        var url = \"\";\n        bounds = this.adjustBounds(bounds);\n        var axlReq = new OpenLayers.Format.ArcXML( \n            OpenLayers.Util.extend(this.options, {\n                requesttype: \"image\",\n                envelope: bounds.toArray(),\n                tileSize: this.tileSize\n            })\n        );\n        var req = new OpenLayers.Request.POST({\n            url: this.getFullRequestString(),\n            data: axlReq.write(),\n            async: false\n        });\n        if (req != null) {\n            var doc = req.responseXML;\n\n            if (!doc || !doc.documentElement) {            \n                doc = req.responseText;\n            }\n            var axlResp = new OpenLayers.Format.ArcXML();\n            var arcxml = axlResp.read(doc);\n            url = this.getUrlOrImage(arcxml.image.output);\n        }\n        \n        return url;\n    },\n    \n    \n        getURLasync: function(bounds, callback, scope) {\n        bounds = this.adjustBounds(bounds);\n        var axlReq = new OpenLayers.Format.ArcXML(  \n            OpenLayers.Util.extend(this.options, { \n                requesttype: \"image\",\n                envelope: bounds.toArray(),\n                tileSize: this.tileSize\n            })\n        );\n        OpenLayers.Request.POST({\n            url: this.getFullRequestString(),\n            async: true,\n            data: axlReq.write(),\n            callback: function(req) {\n                var doc = req.responseXML;\n                if (!doc || !doc.documentElement) {            \n                    doc = req.responseText;\n                }\n                var axlResp = new OpenLayers.Format.ArcXML();\n                var arcxml = axlResp.read(doc);\n                \n                callback.call(scope, this.getUrlOrImage(arcxml.image.output));\n            },\n            scope: this\n        });\n    },\n    \n        getUrlOrImage: function(output) {\n        var ret = \"\";\n        if(output.url) {\n            ret = output.url;\n        } else if(output.data) {\n            ret = \"data:image/\" + output.type + \n                  \";base64,\" + output.data;\n        }\n        return ret;\n    },\n    \n        setLayerQuery: function(id, querydef) {\n        for (var lyr = 0; lyr < this.options.layers.length; lyr++) {\n            if (id == this.options.layers[lyr].id) {\n                this.options.layers[lyr].query = querydef;\n                return;\n            }\n        }\n        this.options.layers.push({id: id, visible: true, query: querydef});\n    },\n    \n        getFeatureInfo: function(geometry, layer, options) {\n        var buffer = options.buffer || 1;\n        var callback = options.callback || function() {};\n        var scope = options.scope || window;\n        var requestOptions = {};\n        OpenLayers.Util.extend(requestOptions, this.options);\n        requestOptions.requesttype = \"feature\";\n\n        if (geometry instanceof OpenLayers.LonLat) {\n            requestOptions.polygon = null;\n            requestOptions.envelope = [ \n                geometry.lon - buffer, \n                geometry.lat - buffer,\n                geometry.lon + buffer,\n                geometry.lat + buffer\n            ];\n        } else if (geometry instanceof OpenLayers.Geometry.Polygon) {\n            requestOptions.envelope = null;\n            requestOptions.polygon = geometry;\n        }\n        var arcxml = new OpenLayers.Format.ArcXML(requestOptions);\n        OpenLayers.Util.extend(arcxml.request.get_feature, options);\n\n        arcxml.request.get_feature.layer = layer.id;\n        if (typeof layer.query.accuracy == \"number\") {\n            arcxml.request.get_feature.query.accuracy = layer.query.accuracy;\n        } else {\n            var mapCenter = this.map.getCenter();\n            var viewPx = this.map.getViewPortPxFromLonLat(mapCenter);\n            viewPx.x++;\n            var mapOffCenter = this.map.getLonLatFromPixel(viewPx);\n            arcxml.request.get_feature.query.accuracy = mapOffCenter.lon - mapCenter.lon;\n        }\n        arcxml.request.get_feature.query.where = layer.query.where;\n        arcxml.request.get_feature.query.spatialfilter.relation = \"area_intersection\";\n        OpenLayers.Request.POST({\n            url: this.getFullRequestString({'CustomService': 'Query'}),\n            data: arcxml.write(),\n            callback: function(request) {\n                var response = arcxml.parseResponse(request.responseText);\n                \n                if (!arcxml.iserror()) {\n                    callback.call(scope, response.features);\n                } else {\n                    callback.call(scope, null);\n                }\n            }\n        });\n    },\n\n        clone: function (obj) {\n\n        if (obj == null) {\n            obj = new OpenLayers.Layer.ArcIMS(this.name,\n                                           this.url,\n                                           this.getOptions());\n        }\n        obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);\n\n        return obj;\n    },\n    \n    CLASS_NAME: \"OpenLayers.Layer.ArcIMS\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/Bing.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Layer.Bing = OpenLayers.Class(OpenLayers.Layer.XYZ, {\n\n        key: null,\n\n        serverResolutions: [\n        156543.03390625, 78271.516953125, 39135.7584765625,\n        19567.87923828125, 9783.939619140625, 4891.9698095703125,\n        2445.9849047851562, 1222.9924523925781, 611.4962261962891,\n        305.74811309814453, 152.87405654907226, 76.43702827453613,\n        38.218514137268066, 19.109257068634033, 9.554628534317017,\n        4.777314267158508, 2.388657133579254, 1.194328566789627,\n        0.5971642833948135, 0.29858214169740677, 0.14929107084870338,\n        0.07464553542435169, 0.03732276771218, 0.01866138385609\n    ],\n    \n        attributionTemplate: '<span class=\"olBingAttribution ${type}\">' +\n         '<div><a target=\"_blank\" href=\"http://www.bing.com/maps/\">' +\n         '<img src=\"${logo}\" /></a></div>${copyrights}' +\n         '<a style=\"white-space: nowrap\" target=\"_blank\" '+\n         'href=\"http://www.microsoft.com/maps/product/terms.html\">' +\n         'Terms of Use</a></span>',\n\n        metadata: null,\n\n        protocolRegex: /^http:/i,\n    \n        type: \"Road\",\n    \n        culture: \"en-US\",\n    \n        metadataParams: null,\n\n        tileOptions: null,\n\n        protocol: ~window.location.href.indexOf('http') ? '' : 'http:',\n\n        initialize: function(options) {\n        options = OpenLayers.Util.applyDefaults({\n            sphericalMercator: true\n        }, options);\n        var name = options.name || \"Bing \" + (options.type || this.type);\n        \n        var newArgs = [name, null, options];\n        OpenLayers.Layer.XYZ.prototype.initialize.apply(this, newArgs);\n        this.tileOptions = OpenLayers.Util.extend({\n            crossOriginKeyword: 'anonymous'\n        }, this.options.tileOptions);\n        this.loadMetadata(); \n    },\n\n        loadMetadata: function() {\n        this._callbackId = \"_callback_\" + this.id.replace(/\\./g, \"_\");\n        window[this._callbackId] = OpenLayers.Function.bind(\n            OpenLayers.Layer.Bing.processMetadata, this\n        );\n        var params = OpenLayers.Util.applyDefaults({\n            key: this.key,\n            jsonp: this._callbackId,\n            include: \"ImageryProviders\"\n        }, this.metadataParams);\n        var url = this.protocol + \"//dev.virtualearth.net/REST/v1/Imagery/Metadata/\" +\n            this.type + \"?\" + OpenLayers.Util.getParameterString(params);\n        var script = document.createElement(\"script\");\n        script.type = \"text/javascript\";\n        script.src = url;\n        script.id = this._callbackId;\n        document.getElementsByTagName(\"head\")[0].appendChild(script);\n    },\n    \n        initLayer: function() {\n        var res = this.metadata.resourceSets[0].resources[0];\n        var url = res.imageUrl.replace(\"{quadkey}\", \"${quadkey}\");\n        url = url.replace(\"{culture}\", this.culture);\n        url = url.replace(this.protocolRegex, this.protocol);\n        this.url = [];\n        for (var i=0; i<res.imageUrlSubdomains.length; ++i) {\n            this.url.push(url.replace(\"{subdomain}\", res.imageUrlSubdomains[i]));\n        }\n        this.addOptions({\n            maxResolution: Math.min(\n                this.serverResolutions[res.zoomMin],\n                this.maxResolution || Number.POSITIVE_INFINITY\n            ),\n            numZoomLevels: Math.min(\n                res.zoomMax + 1 - res.zoomMin, this.numZoomLevels\n            )\n        }, true);\n        if (!this.isBaseLayer) {\n            this.redraw();\n        }\n        this.updateAttribution();\n    },\n    \n        getURL: function(bounds) {\n        if (!this.url) {\n            return;\n        }\n        var xyz = this.getXYZ(bounds), x = xyz.x, y = xyz.y, z = xyz.z;\n        var quadDigits = [];\n        for (var i = z; i > 0; --i) {\n            var digit = '0';\n            var mask = 1 << (i - 1);\n            if ((x & mask) != 0) {\n                digit++;\n            }\n            if ((y & mask) != 0) {\n                digit++;\n                digit++;\n            }\n            quadDigits.push(digit);\n        }\n        var quadKey = quadDigits.join(\"\");\n        var url = this.selectUrl('' + x + y + z, this.url);\n\n        return OpenLayers.String.format(url, {'quadkey': quadKey});\n    },\n    \n        updateAttribution: function() {\n        var metadata = this.metadata;\n        if (!metadata.resourceSets || !this.map || !this.map.center) {\n            return;\n        }\n        var res = metadata.resourceSets[0].resources[0];\n        var extent = this.map.getExtent().transform(\n            this.map.getProjectionObject(),\n            new OpenLayers.Projection(\"EPSG:4326\")\n        );\n        var providers = res.imageryProviders || [],\n            zoom = OpenLayers.Util.indexOf(this.serverResolutions,\n                                           this.getServerResolution()),\n            copyrights = \"\", provider, i, ii, j, jj, bbox, coverage;\n        for (i=0,ii=providers.length; i<ii; ++i) {\n            provider = providers[i];\n            for (j=0,jj=provider.coverageAreas.length; j<jj; ++j) {\n                coverage = provider.coverageAreas[j];\n                bbox = OpenLayers.Bounds.fromArray(coverage.bbox, true);\n                if (extent.intersectsBounds(bbox) &&\n                        zoom <= coverage.zoomMax && zoom >= coverage.zoomMin) {\n                    copyrights += provider.attribution + \" \";\n                }\n            }\n        }\n        var logo = metadata.brandLogoUri.replace(this.protocolRegex, this.protocol);\n        this.attribution = OpenLayers.String.format(this.attributionTemplate, {\n            type: this.type.toLowerCase(),\n            logo: logo,\n            copyrights: copyrights\n        });\n        this.map && this.map.events.triggerEvent(\"changelayer\", {\n            layer: this,\n            property: \"attribution\"\n        });\n    },\n    \n        setMap: function() {\n        OpenLayers.Layer.XYZ.prototype.setMap.apply(this, arguments);\n        this.map.events.register(\"moveend\", this, this.updateAttribution);\n    },\n    \n        clone: function(obj) {\n        if (obj == null) {\n            obj = new OpenLayers.Layer.Bing(this.options);\n        }\n        obj = OpenLayers.Layer.XYZ.prototype.clone.apply(this, [obj]);\n        return obj;\n    },\n    \n        destroy: function() {\n        this.map &&\n            this.map.events.unregister(\"moveend\", this, this.updateAttribution);\n        OpenLayers.Layer.XYZ.prototype.destroy.apply(this, arguments);\n    },\n    \n    CLASS_NAME: \"OpenLayers.Layer.Bing\"\n});\n\nOpenLayers.Layer.Bing.processMetadata = function(metadata) {\n    this.metadata = metadata;\n    this.initLayer();\n    var script = document.getElementById(this._callbackId);\n    script.parentNode.removeChild(script);\n    window[this._callbackId] = undefined; // cannot delete from window in IE\n    delete this._callbackId;\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/Boxes.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Layer.Boxes = OpenLayers.Class(OpenLayers.Layer.Markers, {\n\n        \n        drawMarker: function(marker) {\n        var topleft = this.map.getLayerPxFromLonLat({\n            lon: marker.bounds.left,\n            lat: marker.bounds.top\n        });\n        var botright = this.map.getLayerPxFromLonLat({\n            lon: marker.bounds.right,\n            lat: marker.bounds.bottom\n        });\n        if (botright == null || topleft == null) {\n            marker.display(false);\n        } else {\n            var markerDiv = marker.draw(topleft, {\n                w: Math.max(1, botright.x - topleft.x),\n                h: Math.max(1, botright.y - topleft.y)\n            });\n            if (!marker.drawn) {\n                this.div.appendChild(markerDiv);\n                marker.drawn = true;\n            }\n        }\n    },\n\n\n        removeMarker: function(marker) {\n        OpenLayers.Util.removeItem(this.markers, marker);\n        if ((marker.div != null) &&\n            (marker.div.parentNode == this.div) ) {\n            this.div.removeChild(marker.div);    \n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.Boxes\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/EventPane.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Layer.EventPane = OpenLayers.Class(OpenLayers.Layer, {\n    \n        smoothDragPan: true,\n\n        pane: null,\n\n\n        initialize: function(name, options) {\n        OpenLayers.Layer.prototype.initialize.apply(this, arguments);\n        if (this.pane == null) {\n            this.pane = OpenLayers.Util.createDiv(this.div.id + \"_EventPane\");\n        }\n    },\n    \n        destroy: function() {\n        this.mapObject = null;\n        this.pane = null;\n        OpenLayers.Layer.prototype.destroy.apply(this, arguments); \n    },\n\n    \n        setMap: function(map) {\n        OpenLayers.Layer.prototype.setMap.apply(this, arguments);\n        \n        this.pane.style.zIndex = parseInt(this.div.style.zIndex) + 1;\n        this.pane.style.display = this.div.style.display;\n        this.pane.style.width=\"100%\";\n        this.pane.style.height=\"100%\";\n        if (OpenLayers.BROWSER_NAME == \"msie\") {\n            this.pane.style.background = \n                \"url(\" + OpenLayers.Util.getImageLocation(\"blank.gif\") + \")\";\n        }\n\n        if (this.isFixed) {\n            this.map.viewPortDiv.appendChild(this.pane);\n        } else {\n            this.map.layerContainerDiv.appendChild(this.pane);\n        }\n        this.loadMapObject();\n        if (this.mapObject == null) {\n            this.loadWarningMessage();\n        }\n\n        this.map.events.register('zoomstart', this, this.onZoomStart);\n    },\n\n        removeMap: function(map) {\n        this.map.events.unregister('zoomstart', this, this.onZoomStart);\n\n        if (this.pane && this.pane.parentNode) {\n            this.pane.parentNode.removeChild(this.pane);\n        }\n        OpenLayers.Layer.prototype.removeMap.apply(this, arguments);\n    },\n\n        onZoomStart: function(evt) {\n        if (this.mapObject != null) {\n            var center = this.getMapObjectLonLatFromOLLonLat(evt.center);\n            var zoom = this.getMapObjectZoomFromOLZoom(evt.zoom);\n            this.setMapObjectCenter(center, zoom, false);\n        }\n    },\n  \n        loadWarningMessage:function() {\n\n        this.div.style.backgroundColor = \"darkblue\";\n\n        var viewSize = this.map.getSize();\n        \n        var msgW = Math.min(viewSize.w, 300);\n        var msgH = Math.min(viewSize.h, 200);\n        var size = new OpenLayers.Size(msgW, msgH);\n\n        var centerPx = new OpenLayers.Pixel(viewSize.w/2, viewSize.h/2);\n\n        var topLeft = centerPx.add(-size.w/2, -size.h/2);            \n\n        var div = OpenLayers.Util.createDiv(this.name + \"_warning\", \n                                            topLeft, \n                                            size,\n                                            null,\n                                            null,\n                                            null,\n                                            \"auto\");\n\n        div.style.padding = \"7px\";\n        div.style.backgroundColor = \"yellow\";\n\n        div.innerHTML = this.getWarningHTML();\n        this.div.appendChild(div);\n    },\n  \n        getWarningHTML:function() {\n        return \"\";\n    },\n  \n        display: function(display) {\n        OpenLayers.Layer.prototype.display.apply(this, arguments);\n        this.pane.style.display = this.div.style.display;\n    },\n  \n        setZIndex: function (zIndex) {\n        OpenLayers.Layer.prototype.setZIndex.apply(this, arguments);\n        this.pane.style.zIndex = parseInt(this.div.style.zIndex) + 1;\n    },\n    \n        moveByPx: function(dx, dy) {\n        OpenLayers.Layer.prototype.moveByPx.apply(this, arguments);\n        \n        if (this.dragPanMapObject) {\n            this.dragPanMapObject(dx, -dy);\n        } else {\n            this.moveTo(this.map.getCachedCenter());\n        }\n    },\n\n        moveTo:function(bounds, zoomChanged, dragging) {\n        OpenLayers.Layer.prototype.moveTo.apply(this, arguments);\n\n        if (this.mapObject != null) {\n\n            var newCenter = this.map.getCenter();\n            var newZoom = this.map.getZoom();\n\n            if (newCenter != null) {\n\n                var moOldCenter = this.getMapObjectCenter();\n                var oldCenter = this.getOLLonLatFromMapObjectLonLat(moOldCenter);\n\n                var moOldZoom = this.getMapObjectZoom();\n                var oldZoom= this.getOLZoomFromMapObjectZoom(moOldZoom);\n\n                if (!(newCenter.equals(oldCenter)) || newZoom != oldZoom) {\n\n                    if (!zoomChanged && oldCenter && this.dragPanMapObject && \n                        this.smoothDragPan) {\n                        var oldPx = this.map.getViewPortPxFromLonLat(oldCenter);\n                        var newPx = this.map.getViewPortPxFromLonLat(newCenter);\n                        this.dragPanMapObject(newPx.x-oldPx.x, oldPx.y-newPx.y);\n                    } else {\n                        var center = this.getMapObjectLonLatFromOLLonLat(newCenter);\n                        var zoom = this.getMapObjectZoomFromOLZoom(newZoom);\n                        this.setMapObjectCenter(center, zoom, dragging);\n                    }\n                }\n            }\n        }\n    },\n\n\n    /*                                                      */\n  /*                 Baselayer Functions                  */\n  /*                                                      */\n  \n        getLonLatFromViewPortPx: function (viewPortPx) {\n        var lonlat = null;\n        if ( (this.mapObject != null) && \n             (this.getMapObjectCenter() != null) ) {\n            var moPixel = this.getMapObjectPixelFromOLPixel(viewPortPx);\n            var moLonLat = this.getMapObjectLonLatFromMapObjectPixel(moPixel);\n            lonlat = this.getOLLonLatFromMapObjectLonLat(moLonLat);\n        }\n        return lonlat;\n    },\n\n \n        getViewPortPxFromLonLat: function (lonlat) {\n        var viewPortPx = null;\n        if ( (this.mapObject != null) && \n             (this.getMapObjectCenter() != null) ) {\n\n            var moLonLat = this.getMapObjectLonLatFromOLLonLat(lonlat);\n            var moPixel = this.getMapObjectPixelFromMapObjectLonLat(moLonLat);\n        \n            viewPortPx = this.getOLPixelFromMapObjectPixel(moPixel);\n        }\n        return viewPortPx;\n    },\n\n    /*                                                      */\n  /*               Translation Functions                  */\n  /*                                                      */\n  /*   The following functions translate Map Object and   */\n  /*            OL formats for Pixel, LonLat              */\n  /*                                                      */\n\n        getOLLonLatFromMapObjectLonLat: function(moLonLat) {\n        var olLonLat = null;\n        if (moLonLat != null) {\n            var lon = this.getLongitudeFromMapObjectLonLat(moLonLat);\n            var lat = this.getLatitudeFromMapObjectLonLat(moLonLat);\n            olLonLat = new OpenLayers.LonLat(lon, lat);\n        }\n        return olLonLat;\n    },\n\n        getMapObjectLonLatFromOLLonLat: function(olLonLat) {\n        var moLatLng = null;\n        if (olLonLat != null) {\n            moLatLng = this.getMapObjectLonLatFromLonLat(olLonLat.lon,\n                                                         olLonLat.lat);\n        }\n        return moLatLng;\n    },\n\n        getOLPixelFromMapObjectPixel: function(moPixel) {\n        var olPixel = null;\n        if (moPixel != null) {\n            var x = this.getXFromMapObjectPixel(moPixel);\n            var y = this.getYFromMapObjectPixel(moPixel);\n            olPixel = new OpenLayers.Pixel(x, y);\n        }\n        return olPixel;\n    },\n\n        getMapObjectPixelFromOLPixel: function(olPixel) {\n        var moPixel = null;\n        if (olPixel != null) {\n            moPixel = this.getMapObjectPixelFromXY(olPixel.x, olPixel.y);\n        }\n        return moPixel;\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.EventPane\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/FixedZoomLevels.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Layer.FixedZoomLevels = OpenLayers.Class({\n      \n    /*                                                      */\n  /*                 Baselayer Functions                  */\n  /*                                                      */\n  /*    The following functions must all be implemented   */\n  /*                  by all base layers                  */\n  /*                                                      */\n      \n        initialize: function() {\n    },\n    \n        initResolutions: function() {\n\n        var props = ['minZoomLevel', 'maxZoomLevel', 'numZoomLevels'];\n          \n        for(var i=0, len=props.length; i<len; i++) {\n            var property = props[i];\n            this[property] = (this.options[property] != null)  \n                                     ? this.options[property] \n                                     : this.map[property];\n        }\n\n        if ( (this.minZoomLevel == null) ||\n             (this.minZoomLevel < this.MIN_ZOOM_LEVEL) ){\n            this.minZoomLevel = this.MIN_ZOOM_LEVEL;\n        }        \n        var desiredZoomLevels;\n        var limitZoomLevels = this.MAX_ZOOM_LEVEL - this.minZoomLevel + 1;\n\n        if ( ((this.options.numZoomLevels == null) && \n              (this.options.maxZoomLevel != null)) // (2)\n              ||\n             ((this.numZoomLevels == null) &&\n              (this.maxZoomLevel != null)) // (4)\n           ) {\n            desiredZoomLevels = this.maxZoomLevel - this.minZoomLevel + 1;\n        } else {\n            desiredZoomLevels = this.numZoomLevels;\n        }\n\n        if (desiredZoomLevels != null) {\n            this.numZoomLevels = Math.min(desiredZoomLevels, limitZoomLevels);\n        } else {\n            this.numZoomLevels = limitZoomLevels;\n        }\n        this.maxZoomLevel = this.minZoomLevel + this.numZoomLevels - 1;\n\n        if (this.RESOLUTIONS != null) {\n            var resolutionsIndex = 0;\n            this.resolutions = [];\n            for(var i= this.minZoomLevel; i <= this.maxZoomLevel; i++) {\n                this.resolutions[resolutionsIndex++] = this.RESOLUTIONS[i];            \n            }\n            this.maxResolution = this.resolutions[0];\n            this.minResolution = this.resolutions[this.resolutions.length - 1];\n        }       \n    },\n    \n        getResolution: function() {\n\n        if (this.resolutions != null) {\n            return OpenLayers.Layer.prototype.getResolution.apply(this, arguments);\n        } else {\n            var resolution = null;\n            \n            var viewSize = this.map.getSize();\n            var extent = this.getExtent();\n            \n            if ((viewSize != null) && (extent != null)) {\n                resolution = Math.max( extent.getWidth()  / viewSize.w,\n                                       extent.getHeight() / viewSize.h );\n            }\n            return resolution;\n        }\n     },\n\n        getExtent: function () {\n        var size = this.map.getSize();\n        var tl = this.getLonLatFromViewPortPx({\n            x: 0, y: 0\n        });\n        var br = this.getLonLatFromViewPortPx({\n            x: size.w, y: size.h\n        });\n        \n        if ((tl != null) && (br != null)) {\n            return new OpenLayers.Bounds(tl.lon, br.lat, br.lon, tl.lat);\n        } else {\n            return null;\n        }\n    },\n\n        getZoomForResolution: function(resolution) {\n      \n        if (this.resolutions != null) {\n            return OpenLayers.Layer.prototype.getZoomForResolution.apply(this, arguments);\n        } else {\n            var extent = OpenLayers.Layer.prototype.getExtent.apply(this, []);\n            return this.getZoomForExtent(extent);\n        }\n    },\n\n\n\n    \n        /*                                                      */\n    /*             Translation Functions                    */\n    /*                                                      */\n    /*    The following functions translate GMaps and OL    */ \n    /*     formats for Pixel, LonLat, Bounds, and Zoom      */\n    /*                                                      */\n  \n        getOLZoomFromMapObjectZoom: function(moZoom) {\n        var zoom = null;\n        if (moZoom != null) {\n            zoom = moZoom - this.minZoomLevel;\n            if (this.map.baseLayer !== this) {\n                zoom = this.map.baseLayer.getZoomForResolution(\n                    this.getResolutionForZoom(zoom)\n                );\n            }\n        }\n        return zoom;\n    },\n    \n        getMapObjectZoomFromOLZoom: function(olZoom) {\n        var zoom = null; \n        if (olZoom != null) {\n            zoom = olZoom + this.minZoomLevel;\n            if (this.map.baseLayer !== this) {\n                zoom = this.getZoomForResolution(\n                    this.map.baseLayer.getResolutionForZoom(zoom)\n                );\n            }\n        }\n        return zoom;\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.FixedZoomLevels\"\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/GeoRSS.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Layer.GeoRSS = OpenLayers.Class(OpenLayers.Layer.Markers, {\n\n        location: null,\n\n        features: null,\n    \n        formatOptions: null, \n\n        selectedFeature: null,\n\n        icon: null,\n\n        popupSize: null, \n    \n        useFeedTitle: true,\n    \n        initialize: function(name, location, options) {\n        OpenLayers.Layer.Markers.prototype.initialize.apply(this, [name, options]);\n        this.location = location;\n        this.features = [];\n    },\n\n        destroy: function() {\n        OpenLayers.Layer.Markers.prototype.destroy.apply(this, arguments);\n        this.clearFeatures();\n        this.features = null;\n    },\n\n        loadRSS: function() {\n        if (!this.loaded) {\n            this.events.triggerEvent(\"loadstart\");\n            OpenLayers.Request.GET({\n                url: this.location,\n                success: this.parseData,\n                scope: this\n            });\n            this.loaded = true;\n        }    \n    },    \n    \n        moveTo:function(bounds, zoomChanged, minor) {\n        OpenLayers.Layer.Markers.prototype.moveTo.apply(this, arguments);\n        if(this.visibility && !this.loaded){\n            this.loadRSS();\n        }\n    },\n        \n        parseData: function(ajaxRequest) {\n        var doc = ajaxRequest.responseXML;\n        if (!doc || !doc.documentElement) {\n            doc = OpenLayers.Format.XML.prototype.read(ajaxRequest.responseText);\n        }\n        \n        if (this.useFeedTitle) {\n            var name = null;\n            try {\n                name = doc.getElementsByTagNameNS('*', 'title')[0].firstChild.nodeValue;\n            }\n            catch (e) {\n                name = doc.getElementsByTagName('title')[0].firstChild.nodeValue;\n            }\n            if (name) {\n                this.setName(name);\n            }    \n        }\n       \n        var options = {};\n        \n        OpenLayers.Util.extend(options, this.formatOptions);\n        \n        if (this.map && !this.projection.equals(this.map.getProjectionObject())) {\n            options.externalProjection = this.projection;\n            options.internalProjection = this.map.getProjectionObject();\n        }    \n        \n        var format = new OpenLayers.Format.GeoRSS(options);\n        var features = format.read(doc);\n        \n        for (var i=0, len=features.length; i<len; i++) {\n            var data = {};\n            var feature = features[i];\n            if (!feature.geometry) {\n                continue;\n            }    \n            \n            var title = feature.attributes.title ? \n                         feature.attributes.title : \"Untitled\";\n            \n            var description = feature.attributes.description ? \n                         feature.attributes.description : \"No description.\";\n            \n            var link = feature.attributes.link ? feature.attributes.link : \"\";\n\n            var location = feature.geometry.getBounds().getCenterLonLat();\n            \n            \n            data.icon = this.icon == null ? \n                                     OpenLayers.Marker.defaultIcon() : \n                                     this.icon.clone();\n            \n            data.popupSize = this.popupSize ? \n                             this.popupSize.clone() :\n                             new OpenLayers.Size(250, 120);\n            \n            if (title || description) {\n                data.title = title;\n                data.description = description;\n            \n                var contentHTML = '<div class=\"olLayerGeoRSSClose\">[x]</div>'; \n                contentHTML += '<div class=\"olLayerGeoRSSTitle\">';\n                if (link) {\n                    contentHTML += '<a class=\"link\" href=\"'+link+'\" target=\"_blank\">';\n                }\n                contentHTML += title;\n                if (link) {\n                    contentHTML += '</a>';\n                }\n                contentHTML += '</div>';\n                contentHTML += '<div style=\"\" class=\"olLayerGeoRSSDescription\">';\n                contentHTML += description;\n                contentHTML += '</div>';\n                data['popupContentHTML'] = contentHTML;                \n            }\n            var feature = new OpenLayers.Feature(this, location, data);\n            this.features.push(feature);\n            var marker = feature.createMarker();\n            marker.events.register('click', feature, this.markerClick);\n            this.addMarker(marker);\n        }\n        this.events.triggerEvent(\"loadend\");\n    },\n    \n        markerClick: function(evt) {\n        var sameMarkerClicked = (this == this.layer.selectedFeature);\n        this.layer.selectedFeature = (!sameMarkerClicked) ? this : null;\n        for(var i=0, len=this.layer.map.popups.length; i<len; i++) {\n            this.layer.map.removePopup(this.layer.map.popups[i]);\n        }\n        if (!sameMarkerClicked) {\n            var popup = this.createPopup();\n            OpenLayers.Event.observe(popup.div, \"click\",\n                OpenLayers.Function.bind(function() { \n                    for(var i=0, len=this.layer.map.popups.length; i<len; i++) { \n                        this.layer.map.removePopup(this.layer.map.popups[i]); \n                    }\n                }, this)\n            );\n            this.layer.map.addPopup(popup); \n        }\n        OpenLayers.Event.stop(evt);\n    },\n\n        clearFeatures: function() {\n        if (this.features != null) {\n            while(this.features.length > 0) {\n                var feature = this.features[0];\n                OpenLayers.Util.removeItem(this.features, feature);\n                feature.destroy();\n            }\n        }        \n    },\n    \n    CLASS_NAME: \"OpenLayers.Layer.GeoRSS\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/Google/v3.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Layer.Google.v3 = {\n    \n        DEFAULTS: {\n        sphericalMercator: true,\n        projection: \"EPSG:900913\"\n    },\n\n        animationEnabled: true, \n\n        loadMapObject: function() {\n        if (!this.type) {\n            this.type = google.maps.MapTypeId.ROADMAP;\n        }\n        var mapObject;\n        var cache = OpenLayers.Layer.Google.cache[this.map.id];\n        if (cache) {\n            mapObject = cache.mapObject;\n            ++cache.count;\n        } else {\n            var center = this.map.getCenter();\n            var container = document.createElement('div');\n            container.className = \"olForeignContainer\";\n            container.style.width = '100%';\n            container.style.height = '100%';\n            mapObject = new google.maps.Map(container, {\n                center: center ?\n                    new google.maps.LatLng(center.lat, center.lon) :\n                    new google.maps.LatLng(0, 0),\n                zoom: this.map.getZoom() || 0,\n                mapTypeId: this.type,\n                disableDefaultUI: true,\n                keyboardShortcuts: false,\n                draggable: false,\n                disableDoubleClickZoom: true,\n                scrollwheel: false,\n                streetViewControl: false,\n                tilt: (this.useTiltImages ? 45: 0)\n            });\n            var googleControl = document.createElement('div');\n            googleControl.style.width = '100%';\n            googleControl.style.height = '100%';\n            mapObject.controls[google.maps.ControlPosition.TOP_LEFT].push(googleControl);\n            cache = {\n                googleControl: googleControl,\n                mapObject: mapObject,\n                count: 1\n            };\n            OpenLayers.Layer.Google.cache[this.map.id] = cache;\n        }\n        this.mapObject = mapObject;\n        this.setGMapVisibility(this.visibility);\n    },\n    \n        onMapResize: function() {\n        if (this.visibility) {\n            google.maps.event.trigger(this.mapObject, \"resize\");\n        }\n    },\n\n        setGMapVisibility: function(visible) {\n        var cache = OpenLayers.Layer.Google.cache[this.map.id];\n        var map = this.map;\n        if (cache) {\n            var type = this.type;\n            var layers = map.layers;\n            var layer;\n            for (var i=layers.length-1; i>=0; --i) {\n                layer = layers[i];\n                if (layer instanceof OpenLayers.Layer.Google &&\n                            layer.visibility === true && layer.inRange === true) {\n                    type = layer.type;\n                    visible = true;\n                    break;\n                }\n            }\n            var container = this.mapObject.getDiv();\n            if (visible === true) {\n                if (container.parentNode !== map.div) {\n                    if (!cache.rendered) {\n                        var me = this;\n                        google.maps.event.addListenerOnce(this.mapObject, 'tilesloaded', function() {\n                            cache.rendered = true;\n                            me.setGMapVisibility(me.getVisibility());\n                            me.moveTo(me.map.getCenter());\n                        });\n                    } else {\n                        map.div.appendChild(container);\n                        cache.googleControl.appendChild(map.viewPortDiv);\n                        google.maps.event.trigger(this.mapObject, 'resize');\n                    }\n                }\n                this.mapObject.setMapTypeId(type);                \n            } else if (cache.googleControl.hasChildNodes()) {\n                map.div.appendChild(map.viewPortDiv);\n                map.div.removeChild(container);\n            }\n        }\n    },\n    \n        getMapContainer: function() {\n        return this.mapObject.getDiv();\n    },\n\n        getMapObjectBoundsFromOLBounds: function(olBounds) {\n        var moBounds = null;\n        if (olBounds != null) {\n            var sw = this.sphericalMercator ? \n              this.inverseMercator(olBounds.bottom, olBounds.left) : \n              new OpenLayers.LonLat(olBounds.bottom, olBounds.left);\n            var ne = this.sphericalMercator ? \n              this.inverseMercator(olBounds.top, olBounds.right) : \n              new OpenLayers.LonLat(olBounds.top, olBounds.right);\n            moBounds = new google.maps.LatLngBounds(\n                new google.maps.LatLng(sw.lat, sw.lon),\n                new google.maps.LatLng(ne.lat, ne.lon)\n            );\n        }\n        return moBounds;\n    },\n  \n        getMapObjectLonLatFromMapObjectPixel: function(moPixel) {\n        var size = this.map.getSize();\n        var lon = this.getLongitudeFromMapObjectLonLat(this.mapObject.center);\n        var lat = this.getLatitudeFromMapObjectLonLat(this.mapObject.center);\n        var res = this.map.getResolution();\n\n        var delta_x = moPixel.x - (size.w / 2);\n        var delta_y = moPixel.y - (size.h / 2);\n    \n        var lonlat = new OpenLayers.LonLat(\n            lon + delta_x * res,\n            lat - delta_y * res\n        ); \n\n        if (this.wrapDateLine) {\n            lonlat = lonlat.wrapDateLine(this.maxExtent);\n        }\n        return this.getMapObjectLonLatFromLonLat(lonlat.lon, lonlat.lat);\n    },\n\n        getMapObjectPixelFromMapObjectLonLat: function(moLonLat) {\n        var lon = this.getLongitudeFromMapObjectLonLat(moLonLat);\n        var lat = this.getLatitudeFromMapObjectLonLat(moLonLat);\n        var res = this.map.getResolution();\n        var extent = this.map.getExtent();\n        return this.getMapObjectPixelFromXY((1/res * (lon - extent.left)),\n                                            (1/res * (extent.top - lat)));\n    },\n\n  \n        setMapObjectCenter: function(center, zoom) {\n        if (this.animationEnabled === false && zoom != this.mapObject.zoom) {\n            var mapContainer = this.getMapContainer();\n            google.maps.event.addListenerOnce(\n                this.mapObject, \n                \"idle\", \n                function() {\n                    mapContainer.style.visibility = \"\";\n                }\n            );\n            mapContainer.style.visibility = \"hidden\";\n        }\n        this.mapObject.setOptions({\n            center: center,\n            zoom: zoom\n        });\n    },\n  \n        getMapObjectZoomFromMapObjectBounds: function(moBounds) {\n        return this.mapObject.getBoundsZoomLevel(moBounds);\n    },\n    \n        getMapObjectLonLatFromLonLat: function(lon, lat) {\n        var gLatLng;\n        if(this.sphericalMercator) {\n            var lonlat = this.inverseMercator(lon, lat);\n            gLatLng = new google.maps.LatLng(lonlat.lat, lonlat.lon);\n        } else {\n            gLatLng = new google.maps.LatLng(lat, lon);\n        }\n        return gLatLng;\n    },\n    \n        getMapObjectPixelFromXY: function(x, y) {\n        return new google.maps.Point(x, y);\n    }\n    \n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/Google.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Layer.Google = OpenLayers.Class(\n    OpenLayers.Layer.EventPane, \n    OpenLayers.Layer.FixedZoomLevels, {\n    \n        MIN_ZOOM_LEVEL: 0,\n    \n        MAX_ZOOM_LEVEL: 21,\n\n        RESOLUTIONS: [\n        1.40625, \n        0.703125, \n        0.3515625, \n        0.17578125, \n        0.087890625, \n        0.0439453125,\n        0.02197265625, \n        0.010986328125, \n        0.0054931640625, \n        0.00274658203125,\n        0.001373291015625, \n        0.0006866455078125, \n        0.00034332275390625,\n        0.000171661376953125, \n        0.0000858306884765625, \n        0.00004291534423828125,\n        0.00002145767211914062, \n        0.00001072883605957031,\n        0.00000536441802978515, \n        0.00000268220901489257,\n        0.0000013411045074462891,\n        0.00000067055225372314453\n    ],\n\n        type: null,\n\n        wrapDateLine: true,\n\n        sphericalMercator: false, \n    \n        useTiltImages: false, \n    \n        version: null,\n\n        initialize: function(name, options) {\n        options = options || {};\n        options.version = \"3\";\n        var mixin = OpenLayers.Layer.Google[\"v\" +\n            options.version.replace(/\\./g, \"_\")];\n        if (mixin) {\n            OpenLayers.Util.applyDefaults(options, mixin);\n        } else {\n            throw \"Unsupported Google Maps API version: \" + options.version;\n        }\n\n        OpenLayers.Util.applyDefaults(options, mixin.DEFAULTS);\n        if (options.maxExtent) {\n            options.maxExtent = options.maxExtent.clone();\n        }\n\n        OpenLayers.Layer.EventPane.prototype.initialize.apply(this,\n            [name, options]);\n        OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this, \n            [name, options]);\n\n        if (this.sphericalMercator) {\n            OpenLayers.Util.extend(this, OpenLayers.Layer.SphericalMercator);\n            this.initMercatorParameters();\n        }    \n    },\n\n        clone: function() {\n                return new OpenLayers.Layer.Google(\n            this.name, this.getOptions()\n        );\n    },\n\n        setVisibility: function(visible) {\n        var opacity = this.opacity == null ? 1 : this.opacity;\n        OpenLayers.Layer.EventPane.prototype.setVisibility.apply(this, arguments);\n        this.setOpacity(opacity);\n    },\n    \n        display: function(visible) {\n        if (!this._dragging) {\n            this.setGMapVisibility(visible);\n        }\n        OpenLayers.Layer.EventPane.prototype.display.apply(this, arguments);\n    },\n    \n        moveTo: function(bounds, zoomChanged, dragging) {\n        this._dragging = dragging;\n        OpenLayers.Layer.EventPane.prototype.moveTo.apply(this, arguments);\n        delete this._dragging;\n    },\n    \n        setOpacity: function(opacity) {\n        if (opacity !== this.opacity) {\n            if (this.map != null) {\n                this.map.events.triggerEvent(\"changelayer\", {\n                    layer: this,\n                    property: \"opacity\"\n                });\n            }\n            this.opacity = opacity;\n        }\n        if (this.getVisibility()) {\n            var container = this.getMapContainer();\n            OpenLayers.Util.modifyDOMElement(\n                container, null, null, null, null, null, null, opacity\n            );\n        }\n    },\n\n        destroy: function() {\n                if (this.map) {\n            this.setGMapVisibility(false);\n            var cache = OpenLayers.Layer.Google.cache[this.map.id];\n            if (cache && cache.count <= 1) {\n                this.removeGMapElements();\n            }            \n        }\n        OpenLayers.Layer.EventPane.prototype.destroy.apply(this, arguments);\n    },\n    \n        removeGMapElements: function() {\n        var cache = OpenLayers.Layer.Google.cache[this.map.id];\n        if (cache) {\n            var container = this.mapObject && this.getMapContainer();                \n            if (container && container.parentNode) {\n                container.parentNode.removeChild(container);\n            }\n            var termsOfUse = cache.termsOfUse;\n            if (termsOfUse && termsOfUse.parentNode) {\n                termsOfUse.parentNode.removeChild(termsOfUse);\n            }\n            var poweredBy = cache.poweredBy;\n            if (poweredBy && poweredBy.parentNode) {\n                poweredBy.parentNode.removeChild(poweredBy);\n            }\n            if (this.mapObject && window.google && google.maps &&\n                    google.maps.event && google.maps.event.clearListeners) {\n                google.maps.event.clearListeners(this.mapObject, 'tilesloaded');\n            }\n        }\n    },\n\n        removeMap: function(map) {\n        if (this.visibility && this.mapObject) {\n            this.setGMapVisibility(false);\n        }\n        var cache = OpenLayers.Layer.Google.cache[map.id];\n        if (cache) {\n            if (cache.count <= 1) {\n                this.removeGMapElements();\n                delete OpenLayers.Layer.Google.cache[map.id];\n            } else {\n                --cache.count;\n            }\n        }\n        delete this.termsOfUse;\n        delete this.poweredBy;\n        delete this.mapObject;\n        delete this.dragObject;\n        OpenLayers.Layer.EventPane.prototype.removeMap.apply(this, arguments);\n    },\n\n        getOLBoundsFromMapObjectBounds: function(moBounds) {\n        var olBounds = null;\n        if (moBounds != null) {\n            var sw = moBounds.getSouthWest();\n            var ne = moBounds.getNorthEast();\n            if (this.sphericalMercator) {\n                sw = this.forwardMercator(sw.lng(), sw.lat());\n                ne = this.forwardMercator(ne.lng(), ne.lat());\n            } else {\n                sw = new OpenLayers.LonLat(sw.lng(), sw.lat()); \n                ne = new OpenLayers.LonLat(ne.lng(), ne.lat()); \n            }    \n            olBounds = new OpenLayers.Bounds(sw.lon, \n                                             sw.lat, \n                                             ne.lon, \n                                             ne.lat );\n        }\n        return olBounds;\n    },\n\n        getWarningHTML:function() {\n        return OpenLayers.i18n(\"googleWarning\");\n    },\n\n        getMapObjectCenter: function() {\n        return this.mapObject.getCenter();\n    },\n\n        getMapObjectZoom: function() {\n        return this.mapObject.getZoom();\n    },\n    \n        getLongitudeFromMapObjectLonLat: function(moLonLat) {\n        return this.sphericalMercator ? \n          this.forwardMercator(moLonLat.lng(), moLonLat.lat()).lon :\n          moLonLat.lng();  \n    },\n\n        getLatitudeFromMapObjectLonLat: function(moLonLat) {\n        var lat = this.sphericalMercator ? \n          this.forwardMercator(moLonLat.lng(), moLonLat.lat()).lat :\n          moLonLat.lat(); \n        return lat;  \n    },\n    \n        getXFromMapObjectPixel: function(moPixel) {\n        return moPixel.x;\n    },\n\n        getYFromMapObjectPixel: function(moPixel) {\n        return moPixel.y;\n    },\n    \n    CLASS_NAME: \"OpenLayers.Layer.Google\"\n});\n\nOpenLayers.Layer.Google.cache = {};"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/Grid.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {\n    \n        tileSize: null,\n\n        tileOriginCorner: \"bl\",\n    \n        tileOrigin: null,\n    \n        tileOptions: null,\n\n        tileClass: OpenLayers.Tile.Image,\n    \n        grid: null,\n\n        singleTile: false,\n\n        ratio: 1.5,\n\n        buffer: 0,\n\n        transitionEffect: \"resize\",\n\n        numLoadingTiles: 0,\n\n        serverResolutions: null,\n\n        loading: false,\n    \n        backBuffer: null,\n\n        gridResolution: null,\n\n        backBufferResolution: null,\n\n        backBufferLonLat: null,\n\n        backBufferTimerId: null,\n\n        removeBackBufferDelay: null,\n\n        className: null,\n    \n    \n        gridLayout: null,\n    \n        rowSign: null,\n\n        transitionendEvents: [\n        'transitionend', 'webkitTransitionEnd', 'otransitionend',\n        'oTransitionEnd'\n    ],\n\n        initialize: function(name, url, params, options) {\n        OpenLayers.Layer.HTTPRequest.prototype.initialize.apply(this, \n                                                                arguments);\n        this.grid = [];\n        this._removeBackBuffer = OpenLayers.Function.bind(this.removeBackBuffer, this);\n\n        this.initProperties();\n\n        this.rowSign = this.tileOriginCorner.substr(0, 1) === \"t\" ? 1 : -1;\n    },\n\n        initProperties: function() {\n        if (this.options.removeBackBufferDelay === undefined) {\n            this.removeBackBufferDelay = this.singleTile ? 0 : 2500;\n        }\n\n        if (this.options.className === undefined) {\n            this.className = this.singleTile ? 'olLayerGridSingleTile' :\n                                               'olLayerGrid';\n        }\n    },\n\n        setMap: function(map) {\n        OpenLayers.Layer.HTTPRequest.prototype.setMap.call(this, map);\n        OpenLayers.Element.addClass(this.div, this.className);\n    },\n\n        removeMap: function(map) {\n        this.removeBackBuffer();\n    },\n\n        destroy: function() {\n        this.removeBackBuffer();\n        this.clearGrid();\n\n        this.grid = null;\n        this.tileSize = null;\n        OpenLayers.Layer.HTTPRequest.prototype.destroy.apply(this, arguments); \n    },\n\n    \n        clearGrid:function() {\n        if (this.grid) {\n            for(var iRow=0, len=this.grid.length; iRow<len; iRow++) {\n                var row = this.grid[iRow];\n                for(var iCol=0, clen=row.length; iCol<clen; iCol++) {\n                    var tile = row[iCol];\n                    this.destroyTile(tile);\n                }\n            }\n            this.grid = [];\n            this.gridResolution = null;\n            this.gridLayout = null;\n        }\n    },\n\n       addOptions: function (newOptions, reinitialize) {\n        var singleTileChanged = newOptions.singleTile !== undefined && \n            newOptions.singleTile !== this.singleTile;\n        OpenLayers.Layer.HTTPRequest.prototype.addOptions.apply(this, arguments);\n        if (this.map && singleTileChanged) {\n            this.initProperties();\n            this.clearGrid();\n            this.tileSize = this.options.tileSize;\n            this.setTileSize();\n            if (this.visibility) {\n                this.moveTo(null, true);\n            }\n        }\n    },\n    \n        clone: function (obj) {\n        \n        if (obj == null) {\n            obj = new OpenLayers.Layer.Grid(this.name,\n                                            this.url,\n                                            this.params,\n                                            this.getOptions());\n        }\n        obj = OpenLayers.Layer.HTTPRequest.prototype.clone.apply(this, [obj]);\n        if (this.tileSize != null) {\n            obj.tileSize = this.tileSize.clone();\n        }\n        obj.grid = [];\n        obj.gridResolution = null;\n        obj.backBuffer = null;\n        obj.backBufferTimerId = null;\n        obj.loading = false;\n        obj.numLoadingTiles = 0;\n\n        return obj;\n    },    \n\n        moveTo:function(bounds, zoomChanged, dragging) {\n\n        OpenLayers.Layer.HTTPRequest.prototype.moveTo.apply(this, arguments);\n\n        bounds = bounds || this.map.getExtent();\n\n        if (bounds != null) {\n            var forceReTile = !this.grid.length || zoomChanged;\n            var tilesBounds = this.getTilesBounds();            \n            var resolution = this.map.getResolution();\n            var serverResolution = this.getServerResolution(resolution);\n\n            if (this.singleTile) {\n\n                if ( forceReTile ||\n                     (!dragging && !tilesBounds.containsBounds(bounds))) {\n\n                    if(zoomChanged && this.transitionEffect !== 'resize') {\n                        this.removeBackBuffer();\n                    }\n\n                    if(!zoomChanged || this.transitionEffect === 'resize') {\n                        this.applyBackBuffer(resolution);\n                    }\n\n                    this.initSingleTile(bounds);\n                }\n            } else {\n                forceReTile = forceReTile ||\n                    !tilesBounds.intersectsBounds(bounds, {\n                        worldBounds: this.map.baseLayer.wrapDateLine &&\n                            this.map.getMaxExtent()\n                    });\n\n                if(forceReTile) {\n                    if(zoomChanged && (this.transitionEffect === 'resize' ||\n                                          this.gridResolution === resolution)) {\n                        this.applyBackBuffer(resolution);\n                    }\n                    this.initGriddedTiles(bounds);\n                } else {\n                    this.moveGriddedTiles();\n                }\n            }\n        }\n    },\n\n        getTileData: function(loc) {\n        var data = null,\n            x = loc.lon,\n            y = loc.lat,\n            numRows = this.grid.length;\n\n        if (this.map && numRows) {\n            var res = this.map.getResolution(),\n                tileWidth = this.tileSize.w,\n                tileHeight = this.tileSize.h,\n                bounds = this.grid[0][0].bounds,\n                left = bounds.left,\n                top = bounds.top;\n\n            if (x < left) {\n                if (this.map.baseLayer.wrapDateLine) {\n                    var worldWidth = this.map.getMaxExtent().getWidth();\n                    var worldsAway = Math.ceil((left - x) / worldWidth);\n                    x += worldWidth * worldsAway;\n                }\n            }\n            var dtx = (x - left) / (res * tileWidth);\n            var dty = (top - y) / (res * tileHeight);\n            var col = Math.floor(dtx);\n            var row = Math.floor(dty);\n            if (row >= 0 && row < numRows) {\n                var tile = this.grid[row][col];\n                if (tile) {\n                    data = {\n                        tile: tile,\n                        i: Math.floor((dtx - col) * tileWidth),\n                        j: Math.floor((dty - row) * tileHeight)\n                    };                    \n                }\n            }\n        }\n        return data;\n    },\n    \n        destroyTile: function(tile) {\n        this.removeTileMonitoringHooks(tile);\n        tile.destroy();\n    },\n\n        getServerResolution: function(resolution) {\n        var distance = Number.POSITIVE_INFINITY;\n        resolution = resolution || this.map.getResolution();\n        if(this.serverResolutions &&\n           OpenLayers.Util.indexOf(this.serverResolutions, resolution) === -1) {\n            var i, newDistance, newResolution, serverResolution;\n            for(i=this.serverResolutions.length-1; i>= 0; i--) {\n                newResolution = this.serverResolutions[i];\n                newDistance = Math.abs(newResolution - resolution);\n                if (newDistance > distance) {\n                    break;\n                }\n                distance = newDistance;\n                serverResolution = newResolution;\n            }\n            resolution = serverResolution;\n        }\n        return resolution;\n    },\n\n        getServerZoom: function() {\n        var resolution = this.getServerResolution();\n        return this.serverResolutions ?\n            OpenLayers.Util.indexOf(this.serverResolutions, resolution) :\n            this.map.getZoomForResolution(resolution) + (this.zoomOffset || 0);\n    },\n\n        applyBackBuffer: function(resolution) {\n        if(this.backBufferTimerId !== null) {\n            this.removeBackBuffer();\n        }\n        var backBuffer = this.backBuffer;\n        if(!backBuffer) {\n            backBuffer = this.createBackBuffer();\n            if(!backBuffer) {\n                return;\n            }\n            if (resolution === this.gridResolution) {\n                this.div.insertBefore(backBuffer, this.div.firstChild);\n            } else {\n                this.map.baseLayer.div.parentNode.insertBefore(backBuffer, this.map.baseLayer.div);\n            }\n            this.backBuffer = backBuffer;\n            var topLeftTileBounds = this.grid[0][0].bounds;\n            this.backBufferLonLat = {\n                lon: topLeftTileBounds.left,\n                lat: topLeftTileBounds.top\n            };\n            this.backBufferResolution = this.gridResolution;\n        }\n        \n        var ratio = this.backBufferResolution / resolution;\n        var tiles = backBuffer.childNodes, tile;\n        for (var i=tiles.length-1; i>=0; --i) {\n            tile = tiles[i];\n            tile.style.top = ((ratio * tile._i * backBuffer._th) | 0) + 'px';\n            tile.style.left = ((ratio * tile._j * backBuffer._tw) | 0) + 'px';\n            tile.style.width = Math.round(ratio * tile._w) + 'px';\n            tile.style.height = Math.round(ratio * tile._h) + 'px';\n        }\n        var position = this.getViewPortPxFromLonLat(\n                this.backBufferLonLat, resolution);\n        var leftOffset = this.map.layerContainerOriginPx.x;\n        var topOffset = this.map.layerContainerOriginPx.y;\n        backBuffer.style.left = Math.round(position.x - leftOffset) + 'px';\n        backBuffer.style.top = Math.round(position.y - topOffset) + 'px';\n    },\n\n        createBackBuffer: function() {\n        var backBuffer;\n        if(this.grid.length > 0) {\n            backBuffer = document.createElement('div');\n            backBuffer.id = this.div.id + '_bb';\n            backBuffer.className = 'olBackBuffer';\n            backBuffer.style.position = 'absolute';\n            var map = this.map;\n            backBuffer.style.zIndex = this.transitionEffect === 'resize' ?\n                    this.getZIndex() - 1 :\n                    map.Z_INDEX_BASE.BaseLayer -\n                            (map.getNumLayers() - map.getLayerIndex(this));\n            for(var i=0, lenI=this.grid.length; i<lenI; i++) {\n                for(var j=0, lenJ=this.grid[i].length; j<lenJ; j++) {\n                    var tile = this.grid[i][j],\n                        markup = this.grid[i][j].createBackBuffer();\n                    if (markup) {\n                        markup._i = i;\n                        markup._j = j;\n                        markup._w = this.singleTile ?\n                                this.getImageSize(tile.bounds).w : tile.size.w;\n                        markup._h = tile.size.h;\n                        markup.id = tile.id + '_bb';\n                        backBuffer.appendChild(markup);\n                    }\n                }\n            }\n            backBuffer._tw = this.tileSize.w;\n            backBuffer._th = this.tileSize.h;\n        }\n        return backBuffer;\n    },\n\n        removeBackBuffer: function() {\n        if (this._transitionElement) {\n            for (var i=this.transitionendEvents.length-1; i>=0; --i) {\n                OpenLayers.Event.stopObserving(this._transitionElement,\n                    this.transitionendEvents[i], this._removeBackBuffer);\n            }\n            delete this._transitionElement;\n        }\n        if(this.backBuffer) {\n            if (this.backBuffer.parentNode) {\n                this.backBuffer.parentNode.removeChild(this.backBuffer);\n            }\n            this.backBuffer = null;\n            this.backBufferResolution = null;\n            if(this.backBufferTimerId !== null) {\n                window.clearTimeout(this.backBufferTimerId);\n                this.backBufferTimerId = null;\n            }\n        }\n    },\n\n        moveByPx: function(dx, dy) {\n        if (!this.singleTile) {\n            this.moveGriddedTiles();\n        }\n    },\n\n        setTileSize: function(size) { \n        if (this.singleTile) {\n            size = this.map.getSize();\n            size.h = parseInt(size.h * this.ratio, 10);\n            size.w = parseInt(size.w * this.ratio, 10);\n        } \n        OpenLayers.Layer.HTTPRequest.prototype.setTileSize.apply(this, [size]);\n    },\n\n        getTilesBounds: function() {    \n        var bounds = null; \n        \n        var length = this.grid.length;\n        if (length) {\n            var bottomLeftTileBounds = this.grid[length - 1][0].bounds,\n                width = this.grid[0].length * bottomLeftTileBounds.getWidth(),\n                height = this.grid.length * bottomLeftTileBounds.getHeight();\n            \n            bounds = new OpenLayers.Bounds(bottomLeftTileBounds.left, \n                                           bottomLeftTileBounds.bottom,\n                                           bottomLeftTileBounds.left + width, \n                                           bottomLeftTileBounds.bottom + height);\n        }   \n        return bounds;\n    },\n\n        initSingleTile: function(bounds) {\n        this.events.triggerEvent(\"retile\");\n        var center = bounds.getCenterLonLat();\n        var tileWidth = bounds.getWidth() * this.ratio;\n        var tileHeight = bounds.getHeight() * this.ratio;\n                                       \n        var tileBounds = \n            new OpenLayers.Bounds(center.lon - (tileWidth/2),\n                                  center.lat - (tileHeight/2),\n                                  center.lon + (tileWidth/2),\n                                  center.lat + (tileHeight/2));\n        this.gridResolution = this.getServerResolution();\n        var maxExtent = this.maxExtent;\n        if (maxExtent && (!this.displayOutsideMaxExtent ||\n                (this.map.baseLayer.wrapDateLine &&\n                this.maxExtent.equals(this.map.getMaxExtent())))) {\n            tileBounds.left = Math.max(tileBounds.left, maxExtent.left);\n            tileBounds.right = Math.min(tileBounds.right, maxExtent.right);\n        }\n\n        var px = this.map.getLayerPxFromLonLat({\n            lon: tileBounds.left,\n            lat: tileBounds.top\n        });\n\n        if (!this.grid.length) {\n            this.grid[0] = [];\n        }\n\n        var tile = this.grid[0][0];\n        if (!tile) {\n            tile = this.addTile(tileBounds, px);\n\n            this.addTileMonitoringHooks(tile);\n            tile.draw();\n            this.grid[0][0] = tile;\n        } else {\n            tile.moveTo(tileBounds, px);\n        }           \n        this.removeExcessTiles(1,1);\n    },\n\n        calculateGridLayout: function(bounds, origin, resolution) {\n        var tilelon = resolution * this.tileSize.w;\n        var tilelat = resolution * this.tileSize.h;\n        \n        var offsetlon = bounds.left - origin.lon;\n        var tilecol = Math.floor(offsetlon/tilelon) - this.buffer;\n        \n        var rowSign = this.rowSign;\n\n        var offsetlat = rowSign * (origin.lat - bounds.top + tilelat);  \n        var tilerow = Math[~rowSign ? 'floor' : 'ceil'](offsetlat/tilelat) - this.buffer * rowSign;\n        \n        return { \n          tilelon: tilelon, tilelat: tilelat,\n          startcol: tilecol, startrow: tilerow\n        };\n\n    },\n\n    getImageSize: function(bounds) {\n        var tileSize = OpenLayers.Layer.HTTPRequest.prototype.getImageSize.apply(this, arguments);\n        if (this.singleTile) {\n            tileSize = new OpenLayers.Size(\n                Math.round(bounds.getWidth() / this.gridResolution),\n                tileSize.h\n            );\n        }\n        return tileSize;\n    },\n\n        getTileOrigin: function() {\n        var origin = this.tileOrigin;\n        if (!origin) {\n            var extent = this.getMaxExtent();\n            var edges = ({\n                \"tl\": [\"left\", \"top\"],\n                \"tr\": [\"right\", \"top\"],\n                \"bl\": [\"left\", \"bottom\"],\n                \"br\": [\"right\", \"bottom\"]\n            })[this.tileOriginCorner];\n            origin = new OpenLayers.LonLat(extent[edges[0]], extent[edges[1]]);\n        }\n        return origin;\n    },\n\n        getTileBoundsForGridIndex: function(row, col) {\n        var origin = this.getTileOrigin();\n        var tileLayout = this.gridLayout;\n        var tilelon = tileLayout.tilelon;\n        var tilelat = tileLayout.tilelat;\n        var startcol = tileLayout.startcol;\n        var startrow = tileLayout.startrow;\n        var rowSign = this.rowSign;\n        return new OpenLayers.Bounds(\n            origin.lon + (startcol + col) * tilelon,\n            origin.lat - (startrow + row * rowSign) * tilelat * rowSign,\n            origin.lon + (startcol + col + 1) * tilelon,\n            origin.lat - (startrow + (row - 1) * rowSign) * tilelat * rowSign\n        );\n    },\n\n        initGriddedTiles:function(bounds) {\n        this.events.triggerEvent(\"retile\");\n\n        var viewSize = this.map.getSize();\n        \n        var origin = this.getTileOrigin();\n        var resolution = this.map.getResolution(),\n            serverResolution = this.getServerResolution(),\n            ratio = resolution / serverResolution,\n            tileSize = {\n                w: this.tileSize.w / ratio,\n                h: this.tileSize.h / ratio\n            };\n\n        var minRows = Math.ceil(viewSize.h/tileSize.h) + \n                      2 * this.buffer + 1;\n        var minCols = Math.ceil(viewSize.w/tileSize.w) +\n                      2 * this.buffer + 1;\n\n        var tileLayout = this.calculateGridLayout(bounds, origin, serverResolution);\n        this.gridLayout = tileLayout;\n        \n        var tilelon = tileLayout.tilelon;\n        var tilelat = tileLayout.tilelat;\n        \n        var layerContainerDivLeft = this.map.layerContainerOriginPx.x;\n        var layerContainerDivTop = this.map.layerContainerOriginPx.y;\n\n        var tileBounds = this.getTileBoundsForGridIndex(0, 0);\n        var startPx = this.map.getViewPortPxFromLonLat(\n            new OpenLayers.LonLat(tileBounds.left, tileBounds.top)\n        );\n        startPx.x = Math.round(startPx.x) - layerContainerDivLeft;\n        startPx.y = Math.round(startPx.y) - layerContainerDivTop;\n\n        var tileData = [], center = this.map.getCenter();\n\n        var rowidx = 0;\n        do {\n            var row = this.grid[rowidx];\n            if (!row) {\n                row = [];\n                this.grid.push(row);\n            }\n            \n            var colidx = 0;\n            do {\n                tileBounds = this.getTileBoundsForGridIndex(rowidx, colidx);\n                var px = startPx.clone();\n                px.x = px.x + colidx * Math.round(tileSize.w);\n                px.y = px.y + rowidx * Math.round(tileSize.h);\n                var tile = row[colidx];\n                if (!tile) {\n                    tile = this.addTile(tileBounds, px);\n                    this.addTileMonitoringHooks(tile);\n                    row.push(tile);\n                } else {\n                    tile.moveTo(tileBounds, px, false);\n                }\n                var tileCenter = tileBounds.getCenterLonLat();\n                tileData.push({\n                    tile: tile,\n                    distance: Math.pow(tileCenter.lon - center.lon, 2) +\n                        Math.pow(tileCenter.lat - center.lat, 2)\n                });\n     \n                colidx += 1;\n            } while ((tileBounds.right <= bounds.right + tilelon * this.buffer)\n                     || colidx < minCols);\n             \n            rowidx += 1;\n        } while((tileBounds.bottom >= bounds.bottom - tilelat * this.buffer)\n                || rowidx < minRows);\n        this.removeExcessTiles(rowidx, colidx);\n\n        var resolution = this.getServerResolution();\n        this.gridResolution = resolution;\n        tileData.sort(function(a, b) {\n            return a.distance - b.distance; \n        });\n        for (var i=0, ii=tileData.length; i<ii; ++i) {\n            tileData[i].tile.draw();\n        }\n    },\n\n        getMaxExtent: function() {\n        return this.maxExtent;\n    },\n\n        addTile: function(bounds, position) {\n        var tile = new this.tileClass(\n            this, position, bounds, null, this.tileSize, this.tileOptions\n        );\n        this.events.triggerEvent(\"addtile\", {tile: tile});\n        return tile;\n    },\n    \n        addTileMonitoringHooks: function(tile) {\n        \n        var replacingCls = 'olTileReplacing';\n\n        tile.onLoadStart = function() {\n            if (this.loading === false) {\n                this.loading = true;\n                this.events.triggerEvent(\"loadstart\");\n            }\n            this.events.triggerEvent(\"tileloadstart\", {tile: tile});\n            this.numLoadingTiles++;\n            if (!this.singleTile && this.backBuffer && this.gridResolution === this.backBufferResolution) {\n                OpenLayers.Element.addClass(tile.getTile(), replacingCls);\n            }\n        };\n      \n        tile.onLoadEnd = function(evt) {\n            this.numLoadingTiles--;\n            var aborted = evt.type === 'unload';\n            this.events.triggerEvent(\"tileloaded\", {\n                tile: tile,\n                aborted: aborted\n            });\n            if (!this.singleTile && !aborted && this.backBuffer && this.gridResolution === this.backBufferResolution) {\n                var tileDiv = tile.getTile();\n                if (OpenLayers.Element.getStyle(tileDiv, 'display') === 'none') {\n                    var bufferTile = document.getElementById(tile.id + '_bb');\n                    if (bufferTile) {\n                        bufferTile.parentNode.removeChild(bufferTile);\n                    }\n                }\n                OpenLayers.Element.removeClass(tileDiv, replacingCls);\n            }\n            if (this.numLoadingTiles === 0) {\n                if (this.backBuffer) {\n                    if (this.backBuffer.childNodes.length === 0) {\n                        this.removeBackBuffer();\n                    } else {\n                        this._transitionElement = aborted ?\n                            this.div.lastChild : tile.imgDiv;\n                        var transitionendEvents = this.transitionendEvents;\n                        for (var i=transitionendEvents.length-1; i>=0; --i) {\n                            OpenLayers.Event.observe(this._transitionElement,\n                                transitionendEvents[i],\n                                this._removeBackBuffer);\n                        }\n                        this.backBufferTimerId = window.setTimeout(\n                            this._removeBackBuffer, this.removeBackBufferDelay\n                        );\n                    }\n                }\n                this.loading = false;\n                this.events.triggerEvent(\"loadend\");\n            }\n        };\n        \n        tile.onLoadError = function() {\n            this.events.triggerEvent(\"tileerror\", {tile: tile});\n        };\n        \n        tile.events.on({\n            \"loadstart\": tile.onLoadStart,\n            \"loadend\": tile.onLoadEnd,\n            \"unload\": tile.onLoadEnd,\n            \"loaderror\": tile.onLoadError,\n            scope: this\n        });\n    },\n\n        removeTileMonitoringHooks: function(tile) {\n        tile.unload();\n        tile.events.un({\n            \"loadstart\": tile.onLoadStart,\n            \"loadend\": tile.onLoadEnd,\n            \"unload\": tile.onLoadEnd,\n            \"loaderror\": tile.onLoadError,\n            scope: this\n        });\n    },\n    \n        moveGriddedTiles: function() {\n        var buffer = this.buffer + 1;\n        while(true) {\n            var tlTile = this.grid[0][0];\n            var tlViewPort = {\n                x: tlTile.position.x +\n                    this.map.layerContainerOriginPx.x,\n                y: tlTile.position.y +\n                    this.map.layerContainerOriginPx.y\n            };\n            var ratio = this.getServerResolution() / this.map.getResolution();\n            var tileSize = {\n                w: Math.round(this.tileSize.w * ratio),\n                h: Math.round(this.tileSize.h * ratio)\n            };\n            if (tlViewPort.x > -tileSize.w * (buffer - 1)) {\n                this.shiftColumn(true, tileSize);\n            } else if (tlViewPort.x < -tileSize.w * buffer) {\n                this.shiftColumn(false, tileSize);\n            } else if (tlViewPort.y > -tileSize.h * (buffer - 1)) {\n                this.shiftRow(true, tileSize);\n            } else if (tlViewPort.y < -tileSize.h * buffer) {\n                this.shiftRow(false, tileSize);\n            } else {\n                break;\n            }\n        }\n    },\n\n        shiftRow: function(prepend, tileSize) {\n        var grid = this.grid;\n        var rowIndex = prepend ? 0 : (grid.length - 1);\n        var sign = prepend ? -1 : 1;\n        var rowSign = this.rowSign;\n        var tileLayout = this.gridLayout;\n        tileLayout.startrow += sign * rowSign;\n\n        var modelRow = grid[rowIndex];\n        var row = grid[prepend ? 'pop' : 'shift']();\n        for (var i=0, len=row.length; i<len; i++) {\n            var tile = row[i];\n            var position = modelRow[i].position.clone();\n            position.y += tileSize.h * sign;\n            tile.moveTo(this.getTileBoundsForGridIndex(rowIndex, i), position);\n        }\n        grid[prepend ? 'unshift' : 'push'](row);\n    },\n\n        shiftColumn: function(prepend, tileSize) {\n        var grid = this.grid;\n        var colIndex = prepend ? 0 : (grid[0].length - 1);\n        var sign = prepend ? -1 : 1;\n        var tileLayout = this.gridLayout;\n        tileLayout.startcol += sign;\n\n        for (var i=0, len=grid.length; i<len; i++) {\n            var row = grid[i];\n            var position = row[colIndex].position.clone();\n            var tile = row[prepend ? 'pop' : 'shift']();            \n            position.x += tileSize.w * sign;\n            tile.moveTo(this.getTileBoundsForGridIndex(i, colIndex), position);\n            row[prepend ? 'unshift' : 'push'](tile);\n        }\n    },\n\n        removeExcessTiles: function(rows, columns) {\n        var i, l;\n        while (this.grid.length > rows) {\n            var row = this.grid.pop();\n            for (i=0, l=row.length; i<l; i++) {\n                var tile = row[i];\n                this.destroyTile(tile);\n            }\n        }\n        for (i=0, l=this.grid.length; i<l; i++) {\n            while (this.grid[i].length > columns) {\n                var row = this.grid[i];\n                var tile = row.pop();\n                this.destroyTile(tile);\n            }\n        }\n    },\n\n        onMapResize: function() {\n        if (this.singleTile) {\n            this.clearGrid();\n            this.setTileSize();\n        }\n    },\n    \n        getTileBounds: function(viewPortPx) {\n        var maxExtent = this.maxExtent;\n        var resolution = this.getResolution();\n        var tileMapWidth = resolution * this.tileSize.w;\n        var tileMapHeight = resolution * this.tileSize.h;\n        var mapPoint = this.getLonLatFromViewPortPx(viewPortPx);\n        var tileLeft = maxExtent.left + (tileMapWidth *\n                                         Math.floor((mapPoint.lon -\n                                                     maxExtent.left) /\n                                                    tileMapWidth));\n        var tileBottom = maxExtent.bottom + (tileMapHeight *\n                                             Math.floor((mapPoint.lat -\n                                                         maxExtent.bottom) /\n                                                        tileMapHeight));\n        return new OpenLayers.Bounds(tileLeft, tileBottom,\n                                     tileLeft + tileMapWidth,\n                                     tileBottom + tileMapHeight);\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.Grid\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/HTTPRequest.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Layer.HTTPRequest = OpenLayers.Class(OpenLayers.Layer, {\n\n    \n        URL_HASH_FACTOR: (Math.sqrt(5) - 1) / 2,\n\n        url: null,\n\n        params: null,\n    \n        reproject: false,\n\n        initialize: function(name, url, params, options) {\n        OpenLayers.Layer.prototype.initialize.apply(this, [name, options]);\n        this.url = url;\n        if (!this.params) {\n            this.params = OpenLayers.Util.extend({}, params);\n        }\n    },\n\n        destroy: function() {\n        this.url = null;\n        this.params = null;\n        OpenLayers.Layer.prototype.destroy.apply(this, arguments); \n    },\n    \n        clone: function (obj) {\n        \n        if (obj == null) {\n            obj = new OpenLayers.Layer.HTTPRequest(this.name,\n                                                   this.url,\n                                                   this.params,\n                                                   this.getOptions());\n        }\n        obj = OpenLayers.Layer.prototype.clone.apply(this, [obj]);\n        \n        return obj;\n    },\n\n        setUrl: function(newUrl) {\n        this.url = newUrl;\n    },\n\n        mergeNewParams:function(newParams) {\n        this.params = OpenLayers.Util.extend(this.params, newParams);\n        var ret = this.redraw();\n        if(this.map != null) {\n            this.map.events.triggerEvent(\"changelayer\", {\n                layer: this,\n                property: \"params\"\n            });\n        }\n        return ret;\n    },\n\n        redraw: function(force) { \n        if (force) {\n            this.events.triggerEvent('refresh');\n            return this.mergeNewParams({\"_olSalt\": Math.random()});\n        } else {\n            return OpenLayers.Layer.prototype.redraw.apply(this, []);\n        }\n    },\n    \n        selectUrl: function(paramString, urls) {\n        var product = 1;\n        for (var i=0, len=paramString.length; i<len; i++) { \n            product *= paramString.charCodeAt(i) * this.URL_HASH_FACTOR; \n            product -= Math.floor(product); \n        }\n        return urls[Math.floor(product * urls.length)];\n    },\n\n        getFullRequestString:function(newParams, altUrl) {\n        var url = altUrl || this.url;\n        var allParams = OpenLayers.Util.extend({}, this.params);\n        allParams = OpenLayers.Util.extend(allParams, newParams);\n        var paramsString = OpenLayers.Util.getParameterString(allParams);\n        if (OpenLayers.Util.isArray(url)) {\n            url = this.selectUrl(paramsString, url);\n        }   \n        var urlParams = \n            OpenLayers.Util.upperCaseObject(OpenLayers.Util.getParameters(url));\n        for(var key in allParams) {\n            if(key.toUpperCase() in urlParams) {\n                delete allParams[key];\n            }\n        }\n        paramsString = OpenLayers.Util.getParameterString(allParams);\n        \n        return OpenLayers.Util.urlAppend(url, paramsString);\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.HTTPRequest\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/Image.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n \n\nOpenLayers.Layer.Image = OpenLayers.Class(OpenLayers.Layer, {\n\n        isBaseLayer: true,\n    \n        url: null,\n\n        extent: null,\n    \n        size: null,\n\n        tile: null,\n\n        aspectRatio: null,\n\n        initialize: function(name, url, extent, size, options) {\n        this.url = url;\n        this.extent = extent;\n        this.maxExtent = extent;\n        this.size = size;\n        OpenLayers.Layer.prototype.initialize.apply(this, [name, options]);\n\n        this.aspectRatio = (this.extent.getHeight() / this.size.h) /\n                           (this.extent.getWidth() / this.size.w);\n    },    \n\n        destroy: function() {\n        if (this.tile) {\n            this.removeTileMonitoringHooks(this.tile);\n            this.tile.destroy();\n            this.tile = null;\n        }\n        OpenLayers.Layer.prototype.destroy.apply(this, arguments);\n    },\n    \n        clone: function(obj) {\n        \n        if(obj == null) {\n            obj = new OpenLayers.Layer.Image(this.name,\n                                               this.url,\n                                               this.extent,\n                                               this.size,\n                                               this.getOptions());\n        }\n        obj = OpenLayers.Layer.prototype.clone.apply(this, [obj]);\n\n        return obj;\n    },    \n    \n        setMap: function(map) {\n                if( this.options.maxResolution == null ) {\n            this.options.maxResolution = this.aspectRatio *\n                                         this.extent.getWidth() /\n                                         this.size.w;\n        }\n        OpenLayers.Layer.prototype.setMap.apply(this, arguments);\n    },\n\n        moveTo:function(bounds, zoomChanged, dragging) {\n        OpenLayers.Layer.prototype.moveTo.apply(this, arguments);\n\n        var firstRendering = (this.tile == null);\n\n        if(zoomChanged || firstRendering) {\n            this.setTileSize();\n            var ulPx = this.map.getLayerPxFromLonLat({\n                lon: this.extent.left,\n                lat: this.extent.top\n            });\n\n            if(firstRendering) {\n                this.tile = new OpenLayers.Tile.Image(this, ulPx, this.extent, \n                                                      null, this.tileSize);\n                this.addTileMonitoringHooks(this.tile);\n            } else {\n                this.tile.size = this.tileSize.clone();\n                this.tile.position = ulPx.clone();\n            }\n            this.tile.draw();\n        }\n    }, \n\n        setTileSize: function() {\n        var tileWidth = this.extent.getWidth() / this.map.getResolution();\n        var tileHeight = this.extent.getHeight() / this.map.getResolution();\n        this.tileSize = new OpenLayers.Size(tileWidth, tileHeight);\n    },\n\n        addTileMonitoringHooks: function(tile) {\n        tile.onLoadStart = function() {\n            this.events.triggerEvent(\"loadstart\");\n        };\n        tile.events.register(\"loadstart\", this, tile.onLoadStart);\n      \n        tile.onLoadEnd = function() {\n            this.events.triggerEvent(\"loadend\");\n        };\n        tile.events.register(\"loadend\", this, tile.onLoadEnd);\n        tile.events.register(\"unload\", this, tile.onLoadEnd);\n    },\n\n        removeTileMonitoringHooks: function(tile) {\n        tile.unload();\n        tile.events.un({\n            \"loadstart\": tile.onLoadStart,\n            \"loadend\": tile.onLoadEnd,\n            \"unload\": tile.onLoadEnd,\n            scope: this\n        });\n    },\n    \n        setUrl: function(newUrl) {\n        this.url = newUrl;\n        this.tile.draw();\n    },\n\n        getURL: function(bounds) {\n        return this.url;\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.Image\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/KaMap.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Layer.KaMap = OpenLayers.Class(OpenLayers.Layer.Grid, {\n\n        DEFAULT_PARAMS: {\n        i: 'jpeg',\n        map: ''\n    },\n        \n        initialize: function(name, url, params, options) {\n        OpenLayers.Layer.Grid.prototype.initialize.apply(this, arguments);\n        this.params = OpenLayers.Util.applyDefaults(\n            this.params, this.DEFAULT_PARAMS\n        );\n    },\n\n        getURL: function (bounds) {\n        bounds = this.adjustBounds(bounds);\n        var mapRes = this.map.getResolution();\n        var scale = Math.round((this.map.getScale() * 10000)) / 10000;\n        var pX = Math.round(bounds.left / mapRes);\n        var pY = -Math.round(bounds.top / mapRes);\n        return this.getFullRequestString(\n                      { t: pY, \n                        l: pX,\n                        s: scale\n                      });\n    },\n\n        calculateGridLayout: function(bounds, origin, resolution) {\n        var tilelon = resolution*this.tileSize.w;\n        var tilelat = resolution*this.tileSize.h;\n        \n        var offsetlon = bounds.left;\n        var tilecol = Math.floor(offsetlon/tilelon) - this.buffer;\n        \n        var offsetlat = bounds.top;  \n        var tilerow = Math.floor(offsetlat/tilelat) + this.buffer;\n        \n        return { \n          tilelon: tilelon, tilelat: tilelat,\n          startcol: tilecol, startrow: tilerow\n        };\n    },    \n\n        getTileBoundsForGridIndex: function(row, col) {\n        var origin = this.getTileOrigin();\n        var tileLayout = this.gridLayout;\n        var tilelon = tileLayout.tilelon;\n        var tilelat = tileLayout.tilelat;\n        var minX = (tileLayout.startcol + col) * tilelon;\n        var minY = (tileLayout.startrow - row) * tilelat;\n        return new OpenLayers.Bounds(\n            minX, minY,\n            minX + tilelon, minY + tilelat\n        );\n    },\n\n        clone: function (obj) {\n        \n        if (obj == null) {\n            obj = new OpenLayers.Layer.KaMap(this.name,\n                                            this.url,\n                                            this.params,\n                                            this.getOptions());\n        }\n        obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);\n        if (this.tileSize != null) {\n            obj.tileSize = this.tileSize.clone();\n        }\n        obj.grid = [];\n\n        return obj;\n    },    \n    \n        getTileBounds: function(viewPortPx) {\n        var resolution = this.getResolution();\n        var tileMapWidth = resolution * this.tileSize.w;\n        var tileMapHeight = resolution * this.tileSize.h;\n        var mapPoint = this.getLonLatFromViewPortPx(viewPortPx);\n        var tileLeft = tileMapWidth * Math.floor(mapPoint.lon / tileMapWidth);\n        var tileBottom = tileMapHeight * Math.floor(mapPoint.lat / tileMapHeight);\n        return new OpenLayers.Bounds(tileLeft, tileBottom,\n                                     tileLeft + tileMapWidth,\n                                     tileBottom + tileMapHeight);\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.KaMap\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/KaMapCache.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Layer.KaMapCache = OpenLayers.Class(OpenLayers.Layer.KaMap, {\n\n        IMAGE_EXTENSIONS: {\n        'jpeg': 'jpg',\n        'gif' : 'gif',\n        'png' : 'png',\n        'png8' : 'png',\n        'png24' : 'png',\n        'dithered' : 'png'\n    },\n    \n        DEFAULT_FORMAT: 'jpeg',\n    \n        initialize: function(name, url, params, options) {\n        OpenLayers.Layer.KaMap.prototype.initialize.apply(this, arguments);\n        this.extension = this.IMAGE_EXTENSIONS[this.params.i.toLowerCase() || this.DEFAULT_FORMAT];\n    },\n\n        getURL: function (bounds) {\n        bounds = this.adjustBounds(bounds);\n        var mapRes = this.map.getResolution();\n        var scale = Math.round((this.map.getScale() * 10000)) / 10000;\n        var pX = Math.round(bounds.left / mapRes);\n        var pY = -Math.round(bounds.top / mapRes);\n\n        var metaX = Math.floor(pX / this.tileSize.w / this.params.metaTileSize.w) * this.tileSize.w * this.params.metaTileSize.w;\n        var metaY = Math.floor(pY / this.tileSize.h / this.params.metaTileSize.h) * this.tileSize.h * this.params.metaTileSize.h;\n    \n        var components = [\n            \"/\",\n            this.params.map,\n            \"/\",\n            scale,\n            \"/\",\n            this.params.g.replace(/\\s/g, '_'),\n            \"/def/t\", \n            metaY,\n            \"/l\",\n            metaX,\n            \"/t\",\n            pY,\n            \"l\",\n            pX,\n            \".\",\n            this.extension\n          ];\n\n        var url = this.url;\n\n        if (OpenLayers.Util.isArray(url)) {\n            url = this.selectUrl(components.join(''), url);\n        }\n        return url + components.join(\"\");\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.KaMapCache\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/MapGuide.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Layer.MapGuide = OpenLayers.Class(OpenLayers.Layer.Grid, {\n\n        isBaseLayer: true,\n    \n        useHttpTile: false,\n    \n        singleTile: false,\n    \n        useOverlay: false,\n    \n        useAsyncOverlay: true,\n    \n        TILE_PARAMS: {\n         operation: 'GETTILEIMAGE',\n         version: '1.2.0'\n    },\n\n        SINGLE_TILE_PARAMS: {\n        operation: 'GETMAPIMAGE',\n        format: 'PNG',\n        locale: 'en',\n        clip: '1',\n        version: '1.0.0'\n    },\n    \n        OVERLAY_PARAMS: {\n        operation: 'GETDYNAMICMAPOVERLAYIMAGE',\n        format: 'PNG',\n        locale: 'en',\n        clip: '1',\n        version: '2.0.0'\n    },\n    \n        FOLDER_PARAMS: {\n        tileColumnsPerFolder: 30,\n        tileRowsPerFolder: 30,\n        format: 'png',\n        querystring: null\n    },\n\n        defaultSize: new OpenLayers.Size(300,300),\n\n        tileOriginCorner: \"tl\",\n\n        initialize: function(name, url, params, options) {\n        \n        OpenLayers.Layer.Grid.prototype.initialize.apply(this, arguments);\n        if (options == null || options.isBaseLayer == null) {\n            this.isBaseLayer = ((this.transparent != \"true\") && \n                                (this.transparent != true));\n        }\n\n        if (options && options.useOverlay!=null) {\n          this.useOverlay = options.useOverlay;\n        }\n        if (this.singleTile) {\n          if (this.useOverlay) {\n            OpenLayers.Util.applyDefaults(\n                           this.params,\n                           this.OVERLAY_PARAMS\n                           );\n            if (!this.useAsyncOverlay) {\n              this.params.version = \"1.0.0\";\n            }\n          } else {\n            OpenLayers.Util.applyDefaults(\n                           this.params,\n                           this.SINGLE_TILE_PARAMS\n                           );\n          }         \n        } else {\n            if (this.useHttpTile) {\n                OpenLayers.Util.applyDefaults(\n                               this.params,\n                               this.FOLDER_PARAMS\n                               );\n            } else {\n                OpenLayers.Util.applyDefaults(\n                               this.params,\n                               this.TILE_PARAMS\n                               );\n            }\n            this.setTileSize(this.defaultSize); \n        }\n    },\n\n        clone: function (obj) {\n      if (obj == null) {\n            obj = new OpenLayers.Layer.MapGuide(this.name,\n                                           this.url,\n                                           this.params,\n                                           this.getOptions());\n      }\n      obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);\n\n      return obj;\n    },\n\n        getURL: function (bounds) {\n        var url;\n        var center = bounds.getCenterLonLat();\n        var mapSize = this.map.getSize();\n\n        if (this.singleTile) {\n          var params = {\n            setdisplaydpi: OpenLayers.DOTS_PER_INCH,\n            setdisplayheight: mapSize.h*this.ratio,\n            setdisplaywidth: mapSize.w*this.ratio,\n            setviewcenterx: center.lon,\n            setviewcentery: center.lat,\n            setviewscale: this.map.getScale()\n          };\n          \n          if (this.useOverlay && !this.useAsyncOverlay) {\n            var getVisParams = {};\n            getVisParams = OpenLayers.Util.extend(getVisParams, params);\n            getVisParams.operation = \"GETVISIBLEMAPEXTENT\";\n            getVisParams.version = \"1.0.0\";\n            getVisParams.session = this.params.session;\n            getVisParams.mapName = this.params.mapName;\n            getVisParams.format = 'text/xml';\n            url = this.getFullRequestString( getVisParams );\n            \n            OpenLayers.Request.GET({url: url, async: false});\n          }\n          url = this.getFullRequestString( params );\n        } else {\n          var currentRes = this.map.getResolution();\n          var colidx = Math.floor((bounds.left-this.maxExtent.left)/currentRes);\n          colidx = Math.round(colidx/this.tileSize.w);\n          var rowidx = Math.floor((this.maxExtent.top-bounds.top)/currentRes);\n          rowidx = Math.round(rowidx/this.tileSize.h);\n\n          if (this.useHttpTile){\n              url = this.getImageFilePath(\n                   {\n                       tilecol: colidx,\n                       tilerow: rowidx,\n                       scaleindex: this.resolutions.length - this.map.zoom - 1\n                    });\n\n          } else {\n            url = this.getFullRequestString(\n                   {\n                       tilecol: colidx,\n                       tilerow: rowidx,\n                       scaleindex: this.resolutions.length - this.map.zoom - 1\n                    });\n          }\n       }\n       return url;\n    },\n\n        getFullRequestString:function(newParams, altUrl) {\n        var url = (altUrl == null) ? this.url : altUrl;\n        if (typeof url == \"object\") {\n            url = url[Math.floor(Math.random()*url.length)];\n        }   \n        var requestString = url;        \n        var allParams = OpenLayers.Util.extend({}, this.params);\n        allParams = OpenLayers.Util.extend(allParams, newParams);\n        var urlParams = OpenLayers.Util.upperCaseObject(\n                            OpenLayers.Util.getParameters(url));\n        for(var key in allParams) {\n            if(key.toUpperCase() in urlParams) {\n                delete allParams[key];\n            }\n        }\n        var paramsString = OpenLayers.Util.getParameterString(allParams);\n        \n        /* MapGuide needs '+' separating things like bounds/height/width.\n           Since typically this is URL encoded, we use a slight hack: we\n           depend on the list-like functionality of getParameterString to\n           leave ',' only in the case of list items (since otherwise it is\n           encoded) then do a regular expression replace on the , characters\n           to '+' */\n        paramsString = paramsString.replace(/,/g, \"+\");\n        \n        if (paramsString != \"\") {\n            var lastServerChar = url.charAt(url.length - 1);\n            if ((lastServerChar == \"&\") || (lastServerChar == \"?\")) {\n                requestString += paramsString;\n            } else {\n                if (url.indexOf('?') == -1) {\n                    requestString += '?' + paramsString;\n                } else {\n                    requestString += '&' + paramsString;\n                }\n            }\n        }\n        return requestString;\n    },\n\n         getImageFilePath:function(newParams, altUrl) {\n        var url = (altUrl == null) ? this.url : altUrl;\n        if (typeof url == \"object\") {\n            url = url[Math.floor(Math.random()*url.length)];\n        }   \n        var requestString = url;        \n\n        var tileRowGroup = \"\";\n        var tileColGroup = \"\";\n        \n        if (newParams.tilerow < 0) {\n          tileRowGroup =  '-';\n        }\n          \n        if (newParams.tilerow == 0 ) {\n          tileRowGroup += '0';\n        } else {\n          tileRowGroup += Math.floor(Math.abs(newParams.tilerow/this.params.tileRowsPerFolder)) * this.params.tileRowsPerFolder;\n        }\n          \n        if (newParams.tilecol < 0) {\n          tileColGroup =  '-';\n        }\n        \n        if (newParams.tilecol == 0) {\n          tileColGroup += '0';\n        } else {\n          tileColGroup += Math.floor(Math.abs(newParams.tilecol/this.params.tileColumnsPerFolder)) * this.params.tileColumnsPerFolder;\n        }\n        \n        var tilePath = '/S' + Math.floor(newParams.scaleindex)\n                + '/' + this.params.basemaplayergroupname\n                + '/R' + tileRowGroup\n                + '/C' + tileColGroup\n                + '/' + (newParams.tilerow % this.params.tileRowsPerFolder) \n                + '_' + (newParams.tilecol % this.params.tileColumnsPerFolder) \n                + '.' + this.params.format;\n    \n        if (this.params.querystring) {\n               tilePath += \"?\" + this.params.querystring;\n        }\n        \n        requestString += tilePath;\n        return requestString;\n    },\n    \n    CLASS_NAME: \"OpenLayers.Layer.MapGuide\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/MapServer.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Layer.MapServer = OpenLayers.Class(OpenLayers.Layer.Grid, {\n\n        DEFAULT_PARAMS: {\n        mode: \"map\",\n        map_imagetype: \"png\"\n    },\n\n        initialize: function(name, url, params, options) {\n        OpenLayers.Layer.Grid.prototype.initialize.apply(this, arguments);\n\n        this.params = OpenLayers.Util.applyDefaults(\n            this.params, this.DEFAULT_PARAMS\n        );\n        if (options == null || options.isBaseLayer == null) {\n            this.isBaseLayer = ((this.params.transparent != \"true\") && \n                                (this.params.transparent != true));\n        }\n    },\n\n        clone: function (obj) {\n        if (obj == null) {\n            obj = new OpenLayers.Layer.MapServer(this.name,\n                                           this.url,\n                                           this.params,\n                                           this.getOptions());\n        }\n        obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);\n\n        return obj;\n    },\n    \n        getURL: function (bounds) {\n        bounds = this.adjustBounds(bounds);\n        var extent = [bounds.left, bounds. bottom, bounds.right, bounds.top];\n\n        var imageSize = this.getImageSize(bounds); \n        var url = this.getFullRequestString(\n                     {mapext:   extent,\n                      imgext:   extent,\n                      map_size: [imageSize.w, imageSize.h],\n                      imgx:     imageSize.w / 2,\n                      imgy:     imageSize.h / 2,\n                      imgxy:    [imageSize.w, imageSize.h]\n                      });\n        \n        return url;\n    },\n    \n        getFullRequestString:function(newParams, altUrl) {\n        var url = (altUrl == null) ? this.url : altUrl;\n        var allParams = OpenLayers.Util.extend({}, this.params);\n        allParams = OpenLayers.Util.extend(allParams, newParams);\n        var paramsString = OpenLayers.Util.getParameterString(allParams);\n        if (OpenLayers.Util.isArray(url)) {\n            url = this.selectUrl(paramsString, url);\n        }   \n        var urlParams = OpenLayers.Util.upperCaseObject(\n                            OpenLayers.Util.getParameters(url));\n        for(var key in allParams) {\n            if(key.toUpperCase() in urlParams) {\n                delete allParams[key];\n            }\n        }\n        paramsString = OpenLayers.Util.getParameterString(allParams);\n        var requestString = url;        \n        paramsString = paramsString.replace(/,/g, \"+\");\n        \n        if (paramsString != \"\") {\n            var lastServerChar = url.charAt(url.length - 1);\n            if ((lastServerChar == \"&\") || (lastServerChar == \"?\")) {\n                requestString += paramsString;\n            } else {\n                if (url.indexOf('?') == -1) {\n                    requestString += '?' + paramsString;\n                } else {\n                    requestString += '&' + paramsString;\n                }\n            }\n        }\n        return requestString;\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.MapServer\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/Markers.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Layer.Markers = OpenLayers.Class(OpenLayers.Layer, {\n    \n        isBaseLayer: false,\n    \n        markers: null,\n\n\n        drawn: false,\n    \n        initialize: function(name, options) {\n        OpenLayers.Layer.prototype.initialize.apply(this, arguments);\n        this.markers = [];\n    },\n    \n        destroy: function() {\n        this.clearMarkers();\n        this.markers = null;\n        OpenLayers.Layer.prototype.destroy.apply(this, arguments);\n    },\n\n        setOpacity: function(opacity) {\n        if (opacity != this.opacity) {\n            this.opacity = opacity;\n            for (var i=0, len=this.markers.length; i<len; i++) {\n                this.markers[i].setOpacity(this.opacity);\n            }\n        }\n    },\n\n        moveTo:function(bounds, zoomChanged, dragging) {\n        OpenLayers.Layer.prototype.moveTo.apply(this, arguments);\n\n        if (zoomChanged || !this.drawn) {\n            for(var i=0, len=this.markers.length; i<len; i++) {\n                this.drawMarker(this.markers[i]);\n            }\n            this.drawn = true;\n        }\n    },\n\n        addMarker: function(marker) {\n        this.markers.push(marker);\n\n        if (this.opacity < 1) {\n            marker.setOpacity(this.opacity);\n        }\n\n        if (this.map && this.map.getExtent()) {\n            marker.map = this.map;\n            this.drawMarker(marker);\n        }\n    },\n\n        removeMarker: function(marker) {\n        if (this.markers && this.markers.length) {\n            OpenLayers.Util.removeItem(this.markers, marker);\n            marker.erase();\n        }\n    },\n\n        clearMarkers: function() {\n        if (this.markers != null) {\n            while(this.markers.length > 0) {\n                this.removeMarker(this.markers[0]);\n            }\n        }\n    },\n\n        drawMarker: function(marker) {\n        var px = this.map.getLayerPxFromLonLat(marker.lonlat);\n        if (px == null) {\n            marker.display(false);\n        } else {\n            if (!marker.isDrawn()) {\n                var markerImg = marker.draw(px);\n                this.div.appendChild(markerImg);\n            } else if(marker.icon) {\n                marker.icon.moveTo(px);\n            }\n        }\n    },\n    \n        getDataExtent: function () {\n        var maxExtent = null;\n        \n        if ( this.markers && (this.markers.length > 0)) {\n            var maxExtent = new OpenLayers.Bounds();\n            for(var i=0, len=this.markers.length; i<len; i++) {\n                var marker = this.markers[i];\n                maxExtent.extend(marker.lonlat);\n            }\n        }\n\n        return maxExtent;\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.Markers\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/OSM.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Layer.OSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {\n\n        name: \"OpenStreetMap\",\n\n        url: [\n        '//a.tile.openstreetmap.org/${z}/${x}/${y}.png',\n        '//b.tile.openstreetmap.org/${z}/${x}/${y}.png',\n        '//c.tile.openstreetmap.org/${z}/${x}/${y}.png'\n    ],\n\n        attribution: \"&copy; <a href='//www.openstreetmap.org/copyright'>OpenStreetMap</a> contributors\",\n\n        sphericalMercator: true,\n\n        wrapDateLine: true,\n\n        tileOptions: null,\n\n        initialize: function(name, url, options) {\n        OpenLayers.Layer.XYZ.prototype.initialize.apply(this, arguments);\n        this.tileOptions = OpenLayers.Util.extend({\n            crossOriginKeyword: 'anonymous'\n        }, this.options && this.options.tileOptions);\n    },\n\n        clone: function(obj) {\n        if (obj == null) {\n            obj = new OpenLayers.Layer.OSM(\n                this.name, this.url, this.getOptions());\n        }\n        obj = OpenLayers.Layer.XYZ.prototype.clone.apply(this, [obj]);\n        return obj;\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.OSM\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/PointGrid.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Layer.PointGrid = OpenLayers.Class(OpenLayers.Layer.Vector, {\n\n        dx: null,\n\n        dy: null,\n\n        ratio: 1.5,\n\n        maxFeatures: 250,\n\n        rotation: 0,\n\n        origin: null,\n\n        gridBounds: null,\n\n        initialize: function(config) {\n        config = config || {};\n        OpenLayers.Layer.Vector.prototype.initialize.apply(this, [config.name, config]);\n    },\n    \n        setMap: function(map) {        \n        OpenLayers.Layer.Vector.prototype.setMap.apply(this, arguments);\n        map.events.register(\"moveend\", this, this.onMoveEnd);\n    },\n\n        removeMap: function(map) {\n        map.events.unregister(\"moveend\", this, this.onMoveEnd);\n        OpenLayers.Layer.Vector.prototype.removeMap.apply(this, arguments);\n    },\n    \n        setRatio: function(ratio) {\n        this.ratio = ratio;\n        this.updateGrid(true);\n    },\n    \n        setMaxFeatures: function(maxFeatures) {\n        this.maxFeatures = maxFeatures;\n        this.updateGrid(true);\n    },\n\n        setSpacing: function(dx, dy) {\n        this.dx = dx;\n        this.dy = dy || dx;\n        this.updateGrid(true);\n    },\n    \n        setOrigin: function(origin) {\n        this.origin = origin;\n        this.updateGrid(true);\n    },\n    \n        getOrigin: function() {\n        if (!this.origin) {\n            this.origin = this.map.getExtent().getCenterLonLat();\n        }\n        return this.origin;\n    },\n    \n        setRotation: function(rotation) {\n        this.rotation = rotation;\n        this.updateGrid(true);\n    },\n    \n        onMoveEnd: function() {\n        this.updateGrid();\n    },\n    \n        getViewBounds: function() {\n        var bounds = this.map.getExtent();\n        if (this.rotation) {\n            var origin = this.getOrigin();\n            var rotationOrigin = new OpenLayers.Geometry.Point(origin.lon, origin.lat);\n            var rect = bounds.toGeometry();\n            rect.rotate(-this.rotation, rotationOrigin);\n            bounds = rect.getBounds();\n        }\n        return bounds;\n    },\n    \n        updateGrid: function(force) {\n        if (force || this.invalidBounds()) {\n            var viewBounds = this.getViewBounds();\n            var origin = this.getOrigin();\n            var rotationOrigin = new OpenLayers.Geometry.Point(origin.lon, origin.lat);\n            var viewBoundsWidth = viewBounds.getWidth();\n            var viewBoundsHeight = viewBounds.getHeight();\n            var aspectRatio = viewBoundsWidth / viewBoundsHeight;\n            var maxHeight = Math.sqrt(this.dx * this.dy * this.maxFeatures / aspectRatio);\n            var maxWidth = maxHeight * aspectRatio; \n            var gridWidth = Math.min(viewBoundsWidth * this.ratio, maxWidth);\n            var gridHeight = Math.min(viewBoundsHeight * this.ratio, maxHeight);\n            var center = viewBounds.getCenterLonLat();\n            this.gridBounds = new OpenLayers.Bounds(\n                center.lon - (gridWidth / 2),\n                center.lat - (gridHeight / 2),\n                center.lon + (gridWidth / 2),\n                center.lat + (gridHeight / 2)\n            );\n            var rows = Math.floor(gridHeight / this.dy);\n            var cols = Math.floor(gridWidth / this.dx);\n            var gridLeft = origin.lon + (this.dx * Math.ceil((this.gridBounds.left - origin.lon) / this.dx));\n            var gridBottom = origin.lat + (this.dy * Math.ceil((this.gridBounds.bottom - origin.lat) / this.dy));\n            var features = new Array(rows * cols);\n            var x, y, point;\n            for (var i=0; i<cols; ++i) {\n                x = gridLeft + (i * this.dx);\n                for (var j=0; j<rows; ++j) {\n                    y = gridBottom + (j * this.dy);\n                    point = new OpenLayers.Geometry.Point(x, y);\n                    if (this.rotation) {\n                        point.rotate(this.rotation, rotationOrigin);\n                    }\n                    features[(i*rows)+j] = new OpenLayers.Feature.Vector(point);\n                }\n            }\n            this.destroyFeatures(this.features, {silent: true});\n            this.addFeatures(features, {silent: true});\n        }\n    },\n\n        invalidBounds: function() {\n        return !this.gridBounds || !this.gridBounds.containsBounds(this.getViewBounds());\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.PointGrid\"\n    \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/PointTrack.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Layer.PointTrack = OpenLayers.Class(OpenLayers.Layer.Vector, {\n  \n        dataFrom: null,\n    \n        styleFrom: null,\n    \n        addNodes: function(pointFeatures, options) {\n        if (pointFeatures.length < 2) {\n            throw new Error(\"At least two point features have to be added to \" +\n                            \"create a line from\");\n        }\n        \n        var lines = new Array(pointFeatures.length-1);\n        \n        var pointFeature, startPoint, endPoint;\n        for(var i=0, len=pointFeatures.length; i<len; i++) {\n            pointFeature = pointFeatures[i];\n            endPoint = pointFeature.geometry;\n            \n            if (!endPoint) {\n              var lonlat = pointFeature.lonlat;\n              endPoint = new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat);\n            } else if(endPoint.CLASS_NAME != \"OpenLayers.Geometry.Point\") {\n                throw new TypeError(\"Only features with point geometries are supported.\");\n            }\n            \n            if(i > 0) {\n                var attributes = (this.dataFrom != null) ?\n                        (pointFeatures[i+this.dataFrom].data ||\n                                pointFeatures[i+this.dataFrom].attributes) :\n                        null;\n                var style = (this.styleFrom != null) ?\n                        (pointFeatures[i+this.styleFrom].style) :\n                        null;\n                var line = new OpenLayers.Geometry.LineString([startPoint,\n                        endPoint]);\n                        \n                lines[i-1] = new OpenLayers.Feature.Vector(line, attributes,\n                    style);\n            }\n            \n            startPoint = endPoint;\n        }\n\n        this.addFeatures(lines, options);\n    },\n    \n    CLASS_NAME: \"OpenLayers.Layer.PointTrack\"\n});\n\nOpenLayers.Layer.PointTrack.SOURCE_NODE = -1;\n\nOpenLayers.Layer.PointTrack.TARGET_NODE = 0;\n\nOpenLayers.Layer.PointTrack.dataFrom = {'SOURCE_NODE': -1, 'TARGET_NODE': 0};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/SphericalMercator.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Layer.SphericalMercator = {\n\n        getExtent: function() {\n        var extent = null;\n        if (this.sphericalMercator) {\n            extent = this.map.calculateBounds();\n        } else {\n            extent = OpenLayers.Layer.FixedZoomLevels.prototype.getExtent.apply(this);\n        }\n        return extent;\n    },\n\n        getLonLatFromViewPortPx: function (viewPortPx) {\n        return OpenLayers.Layer.prototype.getLonLatFromViewPortPx.apply(this, arguments);\n    },\n    \n        getViewPortPxFromLonLat: function (lonlat) {\n        return OpenLayers.Layer.prototype.getViewPortPxFromLonLat.apply(this, arguments);\n    },\n\n        initMercatorParameters: function() {\n        this.RESOLUTIONS = [];\n        var maxResolution = 156543.03390625;\n        for(var zoom=0; zoom<=this.MAX_ZOOM_LEVEL; ++zoom) {\n            this.RESOLUTIONS[zoom] = maxResolution / Math.pow(2, zoom);\n        }\n        this.units = \"m\";\n        this.projection = this.projection || \"EPSG:900913\";\n    },\n\n        forwardMercator: (function() {\n        var gg = new OpenLayers.Projection(\"EPSG:4326\");\n        var sm = new OpenLayers.Projection(\"EPSG:900913\");\n        return function(lon, lat) {\n            var point = OpenLayers.Projection.transform({x: lon, y: lat}, gg, sm);\n            return new OpenLayers.LonLat(point.x, point.y);\n        };\n    })(),\n\n        inverseMercator: (function() {\n        var gg = new OpenLayers.Projection(\"EPSG:4326\");\n        var sm = new OpenLayers.Projection(\"EPSG:900913\");\n        return function(x, y) {\n            var point = OpenLayers.Projection.transform({x: x, y: y}, sm, gg);\n            return new OpenLayers.LonLat(point.x, point.y);\n        };\n    })()\n\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/TMS.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Layer.TMS = OpenLayers.Class(OpenLayers.Layer.Grid, {\n\n        serviceVersion: \"1.0.0\",\n\n        layername: null,\n\n        type: null,\n\n        isBaseLayer: true,\n\n        tileOrigin: null,\n\n        serverResolutions: null,\n\n        zoomOffset: 0,\n    \n        initialize: function(name, url, options) {\n        var newArguments = [];\n        newArguments.push(name, url, {}, options);\n        OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);\n    },    \n\n        clone: function (obj) {\n        \n        if (obj == null) {\n            obj = new OpenLayers.Layer.TMS(this.name,\n                                           this.url,\n                                           this.getOptions());\n        }\n        obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);\n\n        return obj;\n    },    \n    \n        getURL: function (bounds) {\n        bounds = this.adjustBounds(bounds);\n        var res = this.getServerResolution();\n        var x = Math.round((bounds.left - this.tileOrigin.lon) / (res * this.tileSize.w));\n        var y = Math.round((bounds.bottom - this.tileOrigin.lat) / (res * this.tileSize.h));\n        var z = this.getServerZoom();\n        var path = this.serviceVersion + \"/\" + this.layername + \"/\" + z + \"/\" + x + \"/\" + y + \".\" + this.type; \n        var url = this.url;\n        if (OpenLayers.Util.isArray(url)) {\n            url = this.selectUrl(path, url);\n        }\n        return url + path;\n    },\n\n        setMap: function(map) {\n        OpenLayers.Layer.Grid.prototype.setMap.apply(this, arguments);\n        if (!this.tileOrigin) { \n            this.tileOrigin = new OpenLayers.LonLat(this.map.maxExtent.left,\n                                                this.map.maxExtent.bottom);\n        }                                       \n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.TMS\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/Text.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Layer.Text = OpenLayers.Class(OpenLayers.Layer.Markers, {\n\n        location:null,\n\n        features: null,\n    \n        formatOptions: null, \n\n        selectedFeature: null,\n\n        initialize: function(name, options) {\n        OpenLayers.Layer.Markers.prototype.initialize.apply(this, arguments);\n        this.features = [];\n    },\n\n        destroy: function() {\n        OpenLayers.Layer.Markers.prototype.destroy.apply(this, arguments);\n        this.clearFeatures();\n        this.features = null;\n    },\n    \n        loadText: function() {\n        if (!this.loaded) {\n            if (this.location != null) {\n\n                var onFail = function(e) {\n                    this.events.triggerEvent(\"loadend\");\n                };\n\n                this.events.triggerEvent(\"loadstart\");\n                OpenLayers.Request.GET({\n                    url: this.location,\n                    success: this.parseData,\n                    failure: onFail,\n                    scope: this\n                });\n                this.loaded = true;\n            }\n        }    \n    },    \n    \n        moveTo:function(bounds, zoomChanged, minor) {\n        OpenLayers.Layer.Markers.prototype.moveTo.apply(this, arguments);\n        if(this.visibility && !this.loaded){\n            this.loadText();\n        }\n    },\n    \n        parseData: function(ajaxRequest) {\n        var text = ajaxRequest.responseText;\n        \n        var options = {};\n        \n        OpenLayers.Util.extend(options, this.formatOptions);\n        \n        if (this.map && !this.projection.equals(this.map.getProjectionObject())) {\n            options.externalProjection = this.projection;\n            options.internalProjection = this.map.getProjectionObject();\n        }    \n        \n        var parser = new OpenLayers.Format.Text(options);\n        var features = parser.read(text);\n        for (var i=0, len=features.length; i<len; i++) {\n            var data = {};\n            var feature = features[i];\n            var location;\n            var iconSize, iconOffset;\n            \n            location = new OpenLayers.LonLat(feature.geometry.x, \n                                             feature.geometry.y);\n            \n            if (feature.style.graphicWidth \n                && feature.style.graphicHeight) {\n                iconSize = new OpenLayers.Size(\n                    feature.style.graphicWidth,\n                    feature.style.graphicHeight);\n            }        \n                        if (feature.style.graphicXOffset !== undefined\n                && feature.style.graphicYOffset !== undefined) {\n                iconOffset = new OpenLayers.Pixel(\n                    feature.style.graphicXOffset, \n                    feature.style.graphicYOffset);\n            }\n            \n            if (feature.style.externalGraphic != null) {\n                data.icon = new OpenLayers.Icon(feature.style.externalGraphic, \n                                                iconSize, \n                                                iconOffset);\n            } else {\n                data.icon = OpenLayers.Marker.defaultIcon();\n                if (iconSize != null) {\n                    data.icon.setSize(iconSize);\n                }\n            }\n            \n            if ((feature.attributes.title != null) \n                && (feature.attributes.description != null)) {\n                data['popupContentHTML'] = \n                    '<h2>'+feature.attributes.title+'</h2>' + \n                    '<p>'+feature.attributes.description+'</p>';\n            }\n            \n            data['overflow'] = feature.attributes.overflow || \"auto\"; \n            \n            var markerFeature = new OpenLayers.Feature(this, location, data);\n            this.features.push(markerFeature);\n            var marker = markerFeature.createMarker();\n            if ((feature.attributes.title != null) \n                && (feature.attributes.description != null)) {\n              marker.events.register('click', markerFeature, this.markerClick);\n            }\n            this.addMarker(marker);\n        }\n        this.events.triggerEvent(\"loadend\");\n    },\n    \n        markerClick: function(evt) {\n        var sameMarkerClicked = (this == this.layer.selectedFeature);\n        this.layer.selectedFeature = (!sameMarkerClicked) ? this : null;\n        for(var i=0, len=this.layer.map.popups.length; i<len; i++) {\n            this.layer.map.removePopup(this.layer.map.popups[i]);\n        }\n        if (!sameMarkerClicked) {\n            this.layer.map.addPopup(this.createPopup()); \n        }\n        OpenLayers.Event.stop(evt);\n    },\n\n        clearFeatures: function() {\n        if (this.features != null) {\n            while(this.features.length > 0) {\n                var feature = this.features[0];\n                OpenLayers.Util.removeItem(this.features, feature);\n                feature.destroy();\n            }\n        }        \n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.Text\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/TileCache.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Layer.TileCache = OpenLayers.Class(OpenLayers.Layer.Grid, {\n\n        isBaseLayer: true,\n    \n        format: 'image/png',\n\n        serverResolutions: null,\n\n        initialize: function(name, url, layername, options) {\n        this.layername = layername;\n        OpenLayers.Layer.Grid.prototype.initialize.apply(this,\n                                                         [name, url, {}, options]);\n        this.extension = this.format.split('/')[1].toLowerCase();\n        this.extension = (this.extension == 'jpg') ? 'jpeg' : this.extension;\n    },    \n\n        clone: function (obj) {\n        \n        if (obj == null) {\n            obj = new OpenLayers.Layer.TileCache(this.name,\n                                                 this.url,\n                                                 this.layername,\n                                                 this.getOptions());\n        }\n        obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);\n\n        return obj;\n    },    \n    \n        getURL: function(bounds) {\n        var res = this.getServerResolution();\n        var bbox = this.maxExtent;\n        var size = this.tileSize;\n        var tileX = Math.round((bounds.left - bbox.left) / (res * size.w));\n        var tileY = Math.round((bounds.bottom - bbox.bottom) / (res * size.h));\n        var tileZ = this.serverResolutions != null ?\n            OpenLayers.Util.indexOf(this.serverResolutions, res) :\n            this.map.getZoom();\n\n        var components = [\n            this.layername,\n            OpenLayers.Number.zeroPad(tileZ, 2),\n            OpenLayers.Number.zeroPad(parseInt(tileX / 1000000), 3),\n            OpenLayers.Number.zeroPad((parseInt(tileX / 1000) % 1000), 3),\n            OpenLayers.Number.zeroPad((parseInt(tileX) % 1000), 3),\n            OpenLayers.Number.zeroPad(parseInt(tileY / 1000000), 3),\n            OpenLayers.Number.zeroPad((parseInt(tileY / 1000) % 1000), 3),\n            OpenLayers.Number.zeroPad((parseInt(tileY) % 1000), 3) + '.' + this.extension\n        ];\n        var path = components.join('/'); \n        var url = this.url;\n        if (OpenLayers.Util.isArray(url)) {\n            url = this.selectUrl(path, url);\n        }\n        url = (url.charAt(url.length - 1) == '/') ? url : url + '/';\n        return url + path;\n    },\n    \n    CLASS_NAME: \"OpenLayers.Layer.TileCache\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/UTFGrid.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Layer.UTFGrid = OpenLayers.Class(OpenLayers.Layer.XYZ, {\n    \n        isBaseLayer: false,\n    \n        projection: new OpenLayers.Projection(\"EPSG:900913\"),\n\n        useJSONP: false,\n    \n    \n    \n        tileClass: OpenLayers.Tile.UTFGrid,\n\n        initialize: function(options) {\n        OpenLayers.Layer.Grid.prototype.initialize.apply(\n            this, [options.name, options.url, {}, options]\n        );\n        this.tileOptions = OpenLayers.Util.extend({\n            utfgridResolution: this.utfgridResolution\n        }, this.tileOptions);\n    },\n\n        createBackBuffer: function() {},\n    \n        clone: function (obj) {\n        if (obj == null) {\n            obj = new OpenLayers.Layer.UTFGrid(this.getOptions());\n        }\n        obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);\n\n        return obj;\n    },\n\n        getFeatureInfo: function(location) {\n        var info = null;\n        var tileInfo = this.getTileData(location);\n        if (tileInfo && tileInfo.tile) {\n            info = tileInfo.tile.getFeatureInfo(tileInfo.i, tileInfo.j);\n        }\n        return info;\n    },\n\n        getFeatureId: function(location) {\n        var id = null;\n        var info = this.getTileData(location);\n        if (info.tile) {\n            id = info.tile.getFeatureId(info.i, info.j);\n        }\n        return id;\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.UTFGrid\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/Vector/RootContainer.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Layer.Vector.RootContainer = OpenLayers.Class(OpenLayers.Layer.Vector, {\n    \n        displayInLayerSwitcher: false,\n    \n        layers: null,\n    \n        \n        display: function() {},\n    \n        getFeatureFromEvent: function(evt) {\n        var layers = this.layers;\n        var feature;\n        for(var i=0; i<layers.length; i++) {\n            feature = layers[i].getFeatureFromEvent(evt);\n            if(feature) {\n                return feature;\n            }\n        }\n    },\n    \n        setMap: function(map) {\n        OpenLayers.Layer.Vector.prototype.setMap.apply(this, arguments);\n        this.collectRoots();\n        map.events.register(\"changelayer\", this, this.handleChangeLayer);\n    },\n    \n        removeMap: function(map) {\n        map.events.unregister(\"changelayer\", this, this.handleChangeLayer);\n        this.resetRoots();\n        OpenLayers.Layer.Vector.prototype.removeMap.apply(this, arguments);\n    },\n    \n        collectRoots: function() {\n        var layer;\n        for(var i=0; i<this.map.layers.length; ++i) {\n            layer = this.map.layers[i];\n            if(OpenLayers.Util.indexOf(this.layers, layer) != -1) {\n                layer.renderer.moveRoot(this.renderer);\n            }\n        }\n    },\n    \n        resetRoots: function() {\n        var layer;\n        for(var i=0; i<this.layers.length; ++i) {\n            layer = this.layers[i];\n            if(this.renderer && layer.renderer.getRenderLayerId() == this.id) {\n                this.renderer.moveRoot(layer.renderer);\n            }\n        }\n    },\n    \n        handleChangeLayer: function(evt) {\n        var layer = evt.layer;\n        if(evt.property == \"order\" &&\n                        OpenLayers.Util.indexOf(this.layers, layer) != -1) {\n            this.resetRoots();\n            this.collectRoots();\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.Vector.RootContainer\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/Vector.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, {\n\n    \n        isBaseLayer: false,\n\n        isFixed: false,\n\n        features: null,\n    \n        filter: null,\n    \n        selectedFeatures: null,\n    \n        unrenderedFeatures: null,\n\n        reportError: true, \n\n        style: null,\n    \n        styleMap: null,\n    \n        strategies: null,\n    \n        protocol: null,\n    \n        renderers: ['SVG', 'VML', 'Canvas'],\n    \n        renderer: null,\n    \n        rendererOptions: null,\n    \n        geometryType: null,\n\n        drawn: false,\n    \n        initialize: function(name, options) {\n        OpenLayers.Layer.prototype.initialize.apply(this, arguments);\n        if (!this.renderer || !this.renderer.supported()) {  \n            this.assignRenderer();\n        }\n        if (!this.renderer || !this.renderer.supported()) {\n            this.renderer = null;\n            this.displayError();\n        } \n\n        if (!this.styleMap) {\n            this.styleMap = new OpenLayers.StyleMap();\n        }\n\n        this.features = [];\n        this.selectedFeatures = [];\n        this.unrenderedFeatures = {};\n        if(this.strategies){\n            for(var i=0, len=this.strategies.length; i<len; i++) {\n                this.strategies[i].setLayer(this);\n            }\n        }\n\n    },\n\n        destroy: function() {\n        if (this.strategies) {\n            var strategy, i, len;\n            for(i=0, len=this.strategies.length; i<len; i++) {\n                strategy = this.strategies[i];\n                if(strategy.autoDestroy) {\n                    strategy.destroy();\n                }\n            }\n            this.strategies = null;\n        }\n        if (this.protocol) {\n            if(this.protocol.autoDestroy) {\n                this.protocol.destroy();\n            }\n            this.protocol = null;\n        }\n        this.destroyFeatures();\n        this.features = null;\n        this.selectedFeatures = null;\n        this.unrenderedFeatures = null;\n        if (this.renderer) {\n            this.renderer.destroy();\n        }\n        this.renderer = null;\n        this.geometryType = null;\n        this.drawn = null;\n        OpenLayers.Layer.prototype.destroy.apply(this, arguments);  \n    },\n\n        clone: function (obj) {\n        \n        if (obj == null) {\n            obj = new OpenLayers.Layer.Vector(this.name, this.getOptions());\n        }\n        obj = OpenLayers.Layer.prototype.clone.apply(this, [obj]);\n        var features = this.features;\n        var len = features.length;\n        var clonedFeatures = new Array(len);\n        for(var i=0; i<len; ++i) {\n            clonedFeatures[i] = features[i].clone();\n        }\n        obj.features = clonedFeatures;\n\n        return obj;\n    },    \n    \n        refresh: function(obj) {\n        if(this.calculateInRange() && this.visibility) {\n            this.events.triggerEvent(\"refresh\", obj);\n        }\n    },\n\n        displayError: function() {\n        if (this.reportError) {\n            OpenLayers.Console.userError(OpenLayers.i18n(\"browserNotSupported\", \n                                     {renderers: this. renderers.join('\\n')}));\n        }    \n    },\n\n        setMap: function(map) {        \n        OpenLayers.Layer.prototype.setMap.apply(this, arguments);\n\n        if (!this.renderer) {\n            this.map.removeLayer(this);\n        } else {\n            this.renderer.map = this.map;\n\n            var newSize = this.map.getSize();\n            newSize.w = newSize.w * this.ratio;\n            newSize.h = newSize.h * this.ratio;\n            this.renderer.setSize(newSize);\n        }\n    },\n\n        afterAdd: function() {\n        if(this.strategies) {\n            var strategy, i, len;\n            for(i=0, len=this.strategies.length; i<len; i++) {\n                strategy = this.strategies[i];\n                if(strategy.autoActivate) {\n                    strategy.activate();\n                }\n            }\n        }\n    },\n\n        removeMap: function(map) {\n        this.drawn = false;\n        if(this.strategies) {\n            var strategy, i, len;\n            for(i=0, len=this.strategies.length; i<len; i++) {\n                strategy = this.strategies[i];\n                if(strategy.autoActivate) {\n                    strategy.deactivate();\n                }\n            }\n        }\n    },\n    \n        onMapResize: function() {\n        OpenLayers.Layer.prototype.onMapResize.apply(this, arguments);\n        \n        var newSize = this.map.getSize();\n        newSize.w = newSize.w * this.ratio;\n        newSize.h = newSize.h * this.ratio;\n        this.renderer.setSize(newSize);\n    },\n\n        moveTo: function(bounds, zoomChanged, dragging) {\n        OpenLayers.Layer.prototype.moveTo.apply(this, arguments);\n        \n        var coordSysUnchanged = true;\n        if (!dragging) {\n            this.renderer.root.style.visibility = 'hidden';\n\n            var viewSize = this.map.getSize(),\n                viewWidth = viewSize.w,\n                viewHeight = viewSize.h,\n                offsetLeft = (viewWidth / 2 * this.ratio) - viewWidth / 2,\n                offsetTop = (viewHeight / 2 * this.ratio) - viewHeight / 2;\n            offsetLeft += this.map.layerContainerOriginPx.x;\n            offsetLeft = -Math.round(offsetLeft);\n            offsetTop += this.map.layerContainerOriginPx.y;\n            offsetTop = -Math.round(offsetTop);\n\n            this.div.style.left = offsetLeft + 'px';\n            this.div.style.top = offsetTop + 'px';\n\n            var extent = this.map.getExtent().scale(this.ratio);\n            coordSysUnchanged = this.renderer.setExtent(extent, zoomChanged);\n\n            this.renderer.root.style.visibility = 'visible';\n            if (OpenLayers.IS_GECKO === true) {\n                this.div.scrollLeft = this.div.scrollLeft;\n            }\n            \n            if (!zoomChanged && coordSysUnchanged) {\n                for (var i in this.unrenderedFeatures) {\n                    var feature = this.unrenderedFeatures[i];\n                    this.drawFeature(feature);\n                }\n            }\n        }\n        if (!this.drawn || zoomChanged || !coordSysUnchanged) {\n            this.drawn = true;\n            var feature;\n            for(var i=0, len=this.features.length; i<len; i++) {\n                this.renderer.locked = (i !== (len - 1));\n                feature = this.features[i];\n                this.drawFeature(feature);\n            }\n        }    \n    },\n    \n        display: function(display) {\n        OpenLayers.Layer.prototype.display.apply(this, arguments);\n        var currentDisplay = this.div.style.display;\n        if(currentDisplay != this.renderer.root.style.display) {\n            this.renderer.root.style.display = currentDisplay;\n        }\n    },\n\n        addFeatures: function(features, options) {\n        if (!(OpenLayers.Util.isArray(features))) {\n            features = [features];\n        }\n        \n        var notify = !options || !options.silent;\n        if(notify) {\n            var event = {features: features};\n            var ret = this.events.triggerEvent(\"beforefeaturesadded\", event);\n            if(ret === false) {\n                return;\n            }\n            features = event.features;\n        }\n        var featuresAdded = [];\n        for (var i=0, len=features.length; i<len; i++) {\n            if (i != (features.length - 1)) {\n                this.renderer.locked = true;\n            } else {\n                this.renderer.locked = false;\n            }    \n            var feature = features[i];\n            \n            if (this.geometryType &&\n              !(feature.geometry instanceof this.geometryType)) {\n                throw new TypeError('addFeatures: component should be an ' +\n                                    this.geometryType.prototype.CLASS_NAME);\n              }\n            feature.layer = this;\n\n            if (!feature.style && this.style) {\n                feature.style = OpenLayers.Util.extend({}, this.style);\n            }\n\n            if (notify) {\n                if(this.events.triggerEvent(\"beforefeatureadded\",\n                                            {feature: feature}) === false) {\n                    continue;\n                }\n                this.preFeatureInsert(feature);\n            }\n\n            featuresAdded.push(feature);\n            this.features.push(feature);\n            this.drawFeature(feature);\n            \n            if (notify) {\n                this.events.triggerEvent(\"featureadded\", {\n                    feature: feature\n                });\n                this.onFeatureInsert(feature);\n            }\n        }\n        \n        if(notify) {\n            this.events.triggerEvent(\"featuresadded\", {features: featuresAdded});\n        }\n    },\n\n\n        removeFeatures: function(features, options) {\n        if(!features || features.length === 0) {\n            return;\n        }\n        if (features === this.features) {\n            return this.removeAllFeatures(options);\n        }\n        if (!(OpenLayers.Util.isArray(features))) {\n            features = [features];\n        }\n        if (features === this.selectedFeatures) {\n            features = features.slice();\n        }\n\n        var notify = !options || !options.silent;\n        \n        if (notify) {\n            this.events.triggerEvent(\n                \"beforefeaturesremoved\", {features: features}\n            );\n        }\n\n        for (var i = features.length - 1; i >= 0; i--) {\n            if (i != 0 && features[i-1].geometry) {\n                this.renderer.locked = true;\n            } else {\n                this.renderer.locked = false;\n            }\n    \n            var feature = features[i];\n            delete this.unrenderedFeatures[feature.id];\n\n            if (notify) {\n                this.events.triggerEvent(\"beforefeatureremoved\", {\n                    feature: feature\n                });\n            }\n\n            this.features = OpenLayers.Util.removeItem(this.features, feature);\n            feature.layer = null;\n\n            if (feature.geometry) {\n                this.renderer.eraseFeatures(feature);\n            }\n            if (OpenLayers.Util.indexOf(this.selectedFeatures, feature) != -1){\n                OpenLayers.Util.removeItem(this.selectedFeatures, feature);\n            }\n\n            if (notify) {\n                this.events.triggerEvent(\"featureremoved\", {\n                    feature: feature\n                });\n            }\n        }\n\n        if (notify) {\n            this.events.triggerEvent(\"featuresremoved\", {features: features});\n        }\n    },\n    \n        removeAllFeatures: function(options) {\n        var notify = !options || !options.silent;\n        var features = this.features;\n        if (notify) {\n            this.events.triggerEvent(\n                \"beforefeaturesremoved\", {features: features}\n            );\n        }\n        var feature;\n        for (var i = features.length-1; i >= 0; i--) {\n            feature = features[i];\n            if (notify) {\n                this.events.triggerEvent(\"beforefeatureremoved\", {\n                    feature: feature\n                });\n            }\n            feature.layer = null;\n            if (notify) {\n                this.events.triggerEvent(\"featureremoved\", {\n                    feature: feature\n                });\n            }\n        }\n        this.renderer.clear();\n        this.features = [];\n        this.unrenderedFeatures = {};\n        this.selectedFeatures = [];\n        if (notify) {\n            this.events.triggerEvent(\"featuresremoved\", {features: features});\n        }\n    },\n\n        destroyFeatures: function(features, options) {\n        var all = (features == undefined); // evaluates to true if\n        if(all) {\n            features = this.features;\n        }\n        if(features) {\n            this.removeFeatures(features, options);\n            for(var i=features.length-1; i>=0; i--) {\n                features[i].destroy();\n            }\n        }\n    },\n\n        drawFeature: function(feature, style) {\n        if (!this.drawn) {\n            return;\n        }\n        if (typeof style != \"object\") {\n            if(!style && feature.state === OpenLayers.State.DELETE) {\n                style = \"delete\";\n            }\n            var renderIntent = style || feature.renderIntent;\n            style = feature.style || this.style;\n            if (!style) {\n                style = this.styleMap.createSymbolizer(feature, renderIntent);\n            }\n        }\n        \n        var drawn = this.renderer.drawFeature(feature, style);\n        if (drawn === false || drawn === null) {\n            this.unrenderedFeatures[feature.id] = feature;\n        } else {\n            delete this.unrenderedFeatures[feature.id];\n        }\n    },\n    \n        eraseFeatures: function(features) {\n        this.renderer.eraseFeatures(features);\n    },\n\n        getFeatureFromEvent: function(evt) {\n        if (!this.renderer) {\n            throw new Error('getFeatureFromEvent called on layer with no ' +\n                            'renderer. This usually means you destroyed a ' +\n                            'layer, but not some handler which is associated ' +\n                            'with it.');\n        }\n        var feature = null;\n        var featureId = this.renderer.getFeatureIdFromEvent(evt);\n        if (featureId) {\n            if (typeof featureId === \"string\") {\n                feature = this.getFeatureById(featureId);\n            } else {\n                feature = featureId;\n            }\n        }\n        return feature;\n    },\n\n        getFeatureBy: function(property, value) {\n        var feature = null;\n        for(var i=0, len=this.features.length; i<len; ++i) {\n            if(this.features[i][property] == value) {\n                feature = this.features[i];\n                break;\n            }\n        }\n        return feature;\n    },\n\n        getFeatureById: function(featureId) {\n        return this.getFeatureBy('id', featureId);\n    },\n\n        getFeatureByFid: function(featureFid) {\n        return this.getFeatureBy('fid', featureFid);\n    },\n    \n        getFeaturesByAttribute: function(attrName, attrValue) {\n        var i,\n            feature,    \n            len = this.features.length,\n            foundFeatures = [];\n        for(i = 0; i < len; i++) {            \n            feature = this.features[i];\n            if(feature && feature.attributes) {\n                if (feature.attributes[attrName] === attrValue) {\n                    foundFeatures.push(feature);\n                }\n            }\n        }\n        return foundFeatures;\n    },\n\n    \n\n        onFeatureInsert: function(feature) {\n    },\n    \n        preFeatureInsert: function(feature) {\n    },\n\n        getDataExtent: function () {\n        var maxExtent = null;\n        var features = this.features;\n        if(features && (features.length > 0)) {\n            var geometry = null;\n            for(var i=0, len=features.length; i<len; i++) {\n                geometry = features[i].geometry;\n                if (geometry) {\n                    if (maxExtent === null) {\n                        maxExtent = new OpenLayers.Bounds();\n                    }\n                    maxExtent.extend(geometry.getBounds());\n                }\n            }\n        }\n        return maxExtent;\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.Vector\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/WMS.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Layer.WMS = OpenLayers.Class(OpenLayers.Layer.Grid, {\n\n        DEFAULT_PARAMS: { service: \"WMS\",\n                      version: \"1.1.1\",\n                      request: \"GetMap\",\n                      styles: \"\",\n                      format: \"image/jpeg\"\n                     },\n    \n        isBaseLayer: true,\n    \n        encodeBBOX: false,\n    \n        yx: {},\n    \n        initialize: function(name, url, params, options) {\n        var newArguments = [];\n        params = OpenLayers.Util.upperCaseObject(params);\n        if (parseFloat(params.VERSION) >= 1.3 && !params.EXCEPTIONS) {\n            params.EXCEPTIONS = \"INIMAGE\";\n        } \n        newArguments.push(name, url, params, options);\n        OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);\n        OpenLayers.Util.applyDefaults(\n                       this.params, \n                       OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS)\n                       );\n        if (!this.noMagic && this.params.TRANSPARENT && \n            this.params.TRANSPARENT.toString().toLowerCase() == \"true\") {\n            if ( (options == null) || (!options.isBaseLayer) ) {\n                this.isBaseLayer = false;\n            } \n            if (this.params.FORMAT == \"image/jpeg\") {\n                this.params.FORMAT = OpenLayers.Util.alphaHack() ? \"image/gif\"\n                                                                 : \"image/png\";\n            }\n        }\n\n    },    \n\n        clone: function (obj) {\n        \n        if (obj == null) {\n            obj = new OpenLayers.Layer.WMS(this.name,\n                                           this.url,\n                                           this.params,\n                                           this.getOptions());\n        }\n        obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);\n\n        return obj;\n    },    \n    \n        reverseAxisOrder: function() {\n        var projCode = this.projection.getCode();\n        return parseFloat(this.params.VERSION) >= 1.3 && \n            !!(this.yx[projCode] || (OpenLayers.Projection.defaults[projCode] && \n            OpenLayers.Projection.defaults[projCode].yx));\n    },\n    \n        getURL: function (bounds) {\n        bounds = this.adjustBounds(bounds);\n        \n        var imageSize = this.getImageSize(bounds);\n        var newParams = {};\n        var reverseAxisOrder = this.reverseAxisOrder();\n        newParams.BBOX = this.encodeBBOX ?\n            bounds.toBBOX(null, reverseAxisOrder) :\n            bounds.toArray(reverseAxisOrder);\n        newParams.WIDTH = imageSize.w;\n        newParams.HEIGHT = imageSize.h;\n        var requestString = this.getFullRequestString(newParams);\n        return requestString;\n    },\n\n        mergeNewParams:function(newParams) {\n        var upperParams = OpenLayers.Util.upperCaseObject(newParams);\n        var newArguments = [upperParams];\n        return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(this, \n                                                             newArguments);\n    },\n\n        getFullRequestString:function(newParams, altUrl) {\n        var mapProjection = this.map.getProjectionObject();\n        var projectionCode = this.projection && this.projection.equals(mapProjection) ?\n            this.projection.getCode() :\n            mapProjection.getCode();\n        var value = (projectionCode == \"none\") ? null : projectionCode;\n        if (parseFloat(this.params.VERSION) >= 1.3) {\n            this.params.CRS = value;\n        } else {\n            this.params.SRS = value;\n        }\n        \n        if (typeof this.params.TRANSPARENT == \"boolean\") {\n            newParams.TRANSPARENT = this.params.TRANSPARENT ? \"TRUE\" : \"FALSE\";\n        }\n\n        return OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(\n                                                    this, arguments);\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.WMS\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/WMTS.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Layer.WMTS = OpenLayers.Class(OpenLayers.Layer.Grid, {\n    \n        isBaseLayer: true,\n\n        version: \"1.0.0\",\n    \n        requestEncoding: \"KVP\",\n    \n        url: null,\n\n        layer: null,\n    \n        matrixSet: null,\n\n        style: null,\n    \n        format: \"image/jpeg\",\n    \n        tileOrigin: null,\n    \n        tileFullExtent: null,\n\n        formatSuffix: null,    \n\n        matrixIds: null,\n    \n        dimensions: null,\n    \n        params: null,\n    \n        zoomOffset: 0,\n\n        serverResolutions: null,\n\n        formatSuffixMap: {\n        \"image/png\": \"png\",\n        \"image/png8\": \"png\",\n        \"image/png24\": \"png\",\n        \"image/png32\": \"png\",\n        \"png\": \"png\",\n        \"image/jpeg\": \"jpg\",\n        \"image/jpg\": \"jpg\",\n        \"jpeg\": \"jpg\",\n        \"jpg\": \"jpg\"\n    },\n    \n        matrix: null,\n    \n        initialize: function(config) {\n        var required = {\n            url: true,\n            layer: true,\n            style: true,\n            matrixSet: true\n        };\n        for (var prop in required) {\n            if (!(prop in config)) {\n                throw new Error(\"Missing property '\" + prop + \"' in layer configuration.\");\n            }\n        }\n\n        config.params = OpenLayers.Util.upperCaseObject(config.params);\n        var args = [config.name, config.url, config.params, config];\n        OpenLayers.Layer.Grid.prototype.initialize.apply(this, args);\n        if (!this.formatSuffix) {\n            this.formatSuffix = this.formatSuffixMap[this.format] || this.format.split(\"/\").pop();            \n        }\n        if (this.matrixIds) {\n            var len = this.matrixIds.length;\n            if (len && typeof this.matrixIds[0] === \"string\") {\n                var ids = this.matrixIds;\n                this.matrixIds = new Array(len);\n                for (var i=0; i<len; ++i) {\n                    this.matrixIds[i] = {identifier: ids[i]};\n                }\n            }\n        }\n\n    },\n    \n        setMap: function() {\n        OpenLayers.Layer.Grid.prototype.setMap.apply(this, arguments);\n    },\n    \n        updateMatrixProperties: function() {\n        this.matrix = this.getMatrix();\n        if (this.matrix) {\n            if (this.matrix.topLeftCorner) {\n                this.tileOrigin = this.matrix.topLeftCorner;\n            }\n            if (this.matrix.tileWidth && this.matrix.tileHeight) {\n                this.tileSize = new OpenLayers.Size(\n                    this.matrix.tileWidth, this.matrix.tileHeight\n                );\n            }\n            if (!this.tileOrigin) { \n                this.tileOrigin = new OpenLayers.LonLat(\n                    this.maxExtent.left, this.maxExtent.top\n                );\n            }   \n            if (!this.tileFullExtent) { \n                this.tileFullExtent = this.maxExtent;\n            }\n        }\n    },\n    \n        moveTo:function(bounds, zoomChanged, dragging) {\n        if (zoomChanged || !this.matrix) {\n            this.updateMatrixProperties();\n        }\n        return OpenLayers.Layer.Grid.prototype.moveTo.apply(this, arguments);\n    },\n\n        clone: function(obj) {\n        if (obj == null) {\n            obj = new OpenLayers.Layer.WMTS(this.options);\n        }\n        obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);\n        return obj;\n    },\n\n        getIdentifier: function() {\n        return this.getServerZoom();\n    },\n    \n        getMatrix: function() {\n        var matrix;\n        if (!this.matrixIds || this.matrixIds.length === 0) {\n            matrix = {identifier: this.getIdentifier()};\n        } else {\n            if (\"scaleDenominator\" in this.matrixIds[0]) {\n                var denom = \n                    OpenLayers.METERS_PER_INCH * \n                    OpenLayers.INCHES_PER_UNIT[this.units] * \n                    this.getServerResolution() / 0.28E-3;\n                var diff = Number.POSITIVE_INFINITY;\n                var delta;\n                for (var i=0, ii=this.matrixIds.length; i<ii; ++i) {\n                    delta = Math.abs(1 - (this.matrixIds[i].scaleDenominator / denom));\n                    if (delta < diff) {\n                        diff = delta;\n                        matrix = this.matrixIds[i];\n                    }\n                }\n            } else {\n                matrix = this.matrixIds[this.getIdentifier()];\n            }\n        }\n        return matrix;\n    },\n    \n        getTileInfo: function(loc) {\n        var res = this.getServerResolution();\n        \n        var fx = (loc.lon - this.tileOrigin.lon) / (res * this.tileSize.w);\n        var fy = (this.tileOrigin.lat - loc.lat) / (res * this.tileSize.h);\n\n        var col = Math.floor(fx);\n        var row = Math.floor(fy);\n        \n        return {\n            col: col, \n            row: row,\n            i: Math.floor((fx - col) * this.tileSize.w),\n            j: Math.floor((fy - row) * this.tileSize.h)\n        };\n    },\n    \n        getURL: function(bounds) {\n        bounds = this.adjustBounds(bounds);\n        var url = \"\";\n        if (!this.tileFullExtent || this.tileFullExtent.intersectsBounds(bounds)) {            \n\n            var center = bounds.getCenterLonLat();            \n            var info = this.getTileInfo(center);\n            var matrixId = this.matrix.identifier;\n            var dimensions = this.dimensions, params;\n\n            if (OpenLayers.Util.isArray(this.url)) {\n                url = this.selectUrl([\n                    this.version, this.style, this.matrixSet,\n                    this.matrix.identifier, info.row, info.col\n                ].join(\",\"), this.url);\n            } else {\n                url = this.url;\n            }\n\n            if (this.requestEncoding.toUpperCase() === \"REST\") {\n                params = this.params;\n                if (url.indexOf(\"{\") !== -1) {\n                    var template = url.replace(/\\{/g, \"${\");\n                    var context = {\n                        style: this.style, Style: this.style,\n                        TileMatrixSet: this.matrixSet,\n                        TileMatrix: this.matrix.identifier,\n                        TileRow: info.row,\n                        TileCol: info.col\n                    };\n                    if (dimensions) {\n                        var dimension, i;\n                        for (i=dimensions.length-1; i>=0; --i) {\n                            dimension = dimensions[i];\n                            context[dimension] = params[dimension.toUpperCase()];\n                        }\n                    }\n                    url = OpenLayers.String.format(template, context);\n                } else {\n                    var path = this.version + \"/\" + this.layer + \"/\" + this.style + \"/\";\n                    if (dimensions) {\n                        for (var i=0; i<dimensions.length; i++) {\n                            if (params[dimensions[i]]) {\n                                path = path + params[dimensions[i]] + \"/\";\n                            }\n                        }\n                    }\n                    path = path + this.matrixSet + \"/\" + this.matrix.identifier + \n                        \"/\" + info.row + \"/\" + info.col + \".\" + this.formatSuffix;\n\n                    if (!url.match(/\\/$/)) {\n                        url = url + \"/\";\n                    }\n                    url = url + path;\n                }\n            } else if (this.requestEncoding.toUpperCase() === \"KVP\") {\n                params = {\n                    SERVICE: \"WMTS\",\n                    REQUEST: \"GetTile\",\n                    VERSION: this.version,\n                    LAYER: this.layer,\n                    STYLE: this.style,\n                    TILEMATRIXSET: this.matrixSet,\n                    TILEMATRIX: this.matrix.identifier,\n                    TILEROW: info.row,\n                    TILECOL: info.col,\n                    FORMAT: this.format\n                };\n                url = OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(this, [params]);\n\n            }\n        }\n        return url;    \n    },\n    \n        mergeNewParams: function(newParams) {\n        if (this.requestEncoding.toUpperCase() === \"KVP\") {\n            return OpenLayers.Layer.Grid.prototype.mergeNewParams.apply(\n                this, [OpenLayers.Util.upperCaseObject(newParams)]\n            );\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.WMTS\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/WorldWind.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Layer.WorldWind = OpenLayers.Class(OpenLayers.Layer.Grid, {\n    \n    DEFAULT_PARAMS: {\n    },\n\n        isBaseLayer: true,\n\n        lzd: null,\n\n        zoomLevels: null,\n    \n        initialize: function(name, url, lzd, zoomLevels, params, options) {\n        this.lzd = lzd;\n        this.zoomLevels = zoomLevels;\n        var newArguments = [];\n        newArguments.push(name, url, params, options);\n        OpenLayers.Layer.Grid.prototype.initialize.apply(this, newArguments);\n        this.params = OpenLayers.Util.applyDefaults(\n            this.params, this.DEFAULT_PARAMS\n        );\n    },\n\n        getZoom: function () {\n        var zoom = this.map.getZoom();\n        var extent = this.map.getMaxExtent();\n        zoom = zoom - Math.log(this.maxResolution / (this.lzd/512))/Math.log(2);\n        return zoom;\n    },\n\n        getURL: function (bounds) {\n        bounds = this.adjustBounds(bounds);\n        var zoom = this.getZoom();\n        var extent = this.map.getMaxExtent();\n        var deg = this.lzd/Math.pow(2,this.getZoom());\n        var x = Math.floor((bounds.left - extent.left)/deg);\n        var y = Math.floor((bounds.bottom - extent.bottom)/deg);\n        if (this.map.getResolution() <= (this.lzd/512)\n            && this.getZoom() <= this.zoomLevels) {\n            return this.getFullRequestString(\n              { L: zoom, \n                X: x,\n                Y: y\n              });\n        } else {\n            return OpenLayers.Util.getImageLocation(\"blank.gif\");\n        }\n\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.WorldWind\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/XYZ.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Layer.XYZ = OpenLayers.Class(OpenLayers.Layer.Grid, {\n    \n        isBaseLayer: true,\n    \n        sphericalMercator: false,\n\n        zoomOffset: 0,\n    \n        serverResolutions: null,\n\n        initialize: function(name, url, options) {\n        if (options && options.sphericalMercator || this.sphericalMercator) {\n            options = OpenLayers.Util.extend({\n                projection: \"EPSG:900913\",\n                numZoomLevels: this.serverResolutions ?\n                        this.serverResolutions.length : 19\n            }, options);\n        }\n        OpenLayers.Layer.Grid.prototype.initialize.apply(this, [\n            name || this.name, url || this.url, {}, options\n        ]);\n    },\n    \n        clone: function (obj) {\n        \n        if (obj == null) {\n            obj = new OpenLayers.Layer.XYZ(this.name,\n                                            this.url,\n                                            this.getOptions());\n        }\n        obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);\n\n        return obj;\n    },    \n\n        getURL: function (bounds) {\n        var xyz = this.getXYZ(bounds);\n        var url = this.url;\n        if (OpenLayers.Util.isArray(url)) {\n            var s = '' + xyz.x + xyz.y + xyz.z;\n            url = this.selectUrl(s, url);\n        }\n        \n        return OpenLayers.String.format(url, xyz);\n    },\n    \n        getXYZ: function(bounds) {\n        var res = this.getServerResolution();\n        var x = Math.round((bounds.left - this.tileOrigin.lon) /\n            (res * this.tileSize.w));\n        var y = Math.round((this.tileOrigin.lat - bounds.top) /\n            (res * this.tileSize.h));\n        var z = this.getServerZoom();\n\n        if (this.wrapDateLine) {\n            var limit = Math.pow(2, z);\n            x = ((x % limit) + limit) % limit;\n        }\n\n        return {'x': x, 'y': y, 'z': z};\n    },\n    \n    /* APIMethod: setMap\n     * When the layer is added to a map, then we can fetch our origin \n     *    (if we don't have one.) \n     * \n     * Parameters:\n     * map - {<OpenLayers.Map>}\n     */\n    setMap: function(map) {\n        OpenLayers.Layer.Grid.prototype.setMap.apply(this, arguments);\n        if (!this.tileOrigin) { \n            this.tileOrigin = new OpenLayers.LonLat(this.maxExtent.left,\n                                                this.maxExtent.top);\n        }                                       \n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.XYZ\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer/Zoomify.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n/*\n * Development supported by a R&D grant DC08P02OUK006 - Old Maps Online\n * (www.oldmapsonline.org) from Ministry of Culture of the Czech Republic.\n */\n\n\n\nOpenLayers.Layer.Zoomify = OpenLayers.Class(OpenLayers.Layer.Grid, {\n\n        size: null,\n\n        isBaseLayer: true,\n\n        standardTileSize: 256,\n\n        tileOriginCorner: \"tl\",\n\n        numberOfTiers: 0,\n\n        tileCountUpToTier: null,\n\n        tierSizeInTiles: null,\n\n        tierImageSize: null,\n\n        initialize: function(name, url, size, options) {\n        this.initializeZoomify(size);\n\n        OpenLayers.Layer.Grid.prototype.initialize.apply(this, [\n            name, url, {}, options\n        ]);\n    },\n\n        initializeZoomify: function( size ) {\n\n        var imageSize = size.clone();\n        this.size = size.clone();\n        var tiles = new OpenLayers.Size(\n            Math.ceil( imageSize.w / this.standardTileSize ),\n            Math.ceil( imageSize.h / this.standardTileSize )\n            );\n\n        this.tierSizeInTiles = [tiles];\n        this.tierImageSize = [imageSize];\n\n        while (imageSize.w > this.standardTileSize ||\n               imageSize.h > this.standardTileSize ) {\n\n            imageSize = new OpenLayers.Size(\n                Math.floor( imageSize.w / 2 ),\n                Math.floor( imageSize.h / 2 )\n                );\n            tiles = new OpenLayers.Size(\n                Math.ceil( imageSize.w / this.standardTileSize ),\n                Math.ceil( imageSize.h / this.standardTileSize )\n                );\n            this.tierSizeInTiles.push( tiles );\n            this.tierImageSize.push( imageSize );\n        }\n\n        this.tierSizeInTiles.reverse();\n        this.tierImageSize.reverse();\n\n        this.numberOfTiers = this.tierSizeInTiles.length;\n        var resolutions = [1];\n        this.tileCountUpToTier = [0];\n        for (var i = 1; i < this.numberOfTiers; i++) {\n            resolutions.unshift(Math.pow(2, i));\n            this.tileCountUpToTier.push(\n                this.tierSizeInTiles[i-1].w * this.tierSizeInTiles[i-1].h +\n                this.tileCountUpToTier[i-1]\n                );\n        }\n        if (!this.serverResolutions) {\n            this.serverResolutions = resolutions;\n        }\n    },\n\n        destroy: function() {\n        OpenLayers.Layer.Grid.prototype.destroy.apply(this, arguments);\n        this.tileCountUpToTier.length = 0;\n        this.tierSizeInTiles.length = 0;\n        this.tierImageSize.length = 0;\n\n    },\n\n        clone: function (obj) {\n\n        if (obj == null) {\n            obj = new OpenLayers.Layer.Zoomify(this.name,\n                                           this.url,\n                                           this.size,\n                                           this.options);\n        }\n        obj = OpenLayers.Layer.Grid.prototype.clone.apply(this, [obj]);\n\n        return obj;\n    },\n\n        createBackBuffer: function() {\n        var backBuffer = OpenLayers.Layer.Grid.prototype.createBackBuffer.apply(this, arguments);\n        if(backBuffer) {\n            var image;\n            for (var i=backBuffer.childNodes.length-1; i>=0; --i) {\n                image = backBuffer.childNodes[i];\n                image._w = image.width;\n                image._h = image.height;\n            }\n        }\n        return backBuffer;\n    },\n\n        getURL: function (bounds) {\n        bounds = this.adjustBounds(bounds);\n        var res = this.getServerResolution();\n        var x = Math.round((bounds.left - this.tileOrigin.lon) / (res * this.tileSize.w));\n        var y = Math.round((this.tileOrigin.lat - bounds.top) / (res * this.tileSize.h));\n        var z = this.getZoomForResolution( res );\n\n        var tileIndex = x + y * this.tierSizeInTiles[z].w + this.tileCountUpToTier[z];\n        var path = \"TileGroup\" + Math.floor( (tileIndex) / 256 ) +\n            \"/\" + z + \"-\" + x + \"-\" + y + \".jpg\";\n        var url = this.url;\n        if (OpenLayers.Util.isArray(url)) {\n            url = this.selectUrl(path, url);\n        }\n        return url + path;\n    },\n\n        getImageSize: function() {\n        if (arguments.length > 0) {\n            var bounds = this.adjustBounds(arguments[0]);\n            var res = this.getServerResolution();\n            var x = Math.round((bounds.left - this.tileOrigin.lon) / (res * this.tileSize.w));\n            var y = Math.round((this.tileOrigin.lat - bounds.top) / (res * this.tileSize.h));\n            var z = this.getZoomForResolution( res );\n            var w = this.standardTileSize;\n            var h = this.standardTileSize;\n            if (x == this.tierSizeInTiles[z].w -1 ) {\n                var w = this.tierImageSize[z].w % this.standardTileSize;\n                if (w == 0) {\n                    w = this.standardTileSize;\n                }\n            }\n            if (y == this.tierSizeInTiles[z].h -1 ) {\n                var h = this.tierImageSize[z].h % this.standardTileSize;\n                if (h == 0) {\n                    h = this.standardTileSize;\n                }\n            }\n            if (x == this.tierSizeInTiles[z].w) {\n                w = Math.ceil(this.size.w / Math.pow(2, this.numberOfTiers - 1 - z) - this.tierImageSize[z].w);\n            }\n            if (y == this.tierSizeInTiles[z].h) {\n                h = Math.ceil(this.size.h / Math.pow(2, this.numberOfTiers - 1 - z) - this.tierImageSize[z].h);\n            }\n            return (new OpenLayers.Size(w, h));\n        } else {\n            return this.tileSize;\n        }\n    },\n\n        setMap: function(map) {\n        OpenLayers.Layer.Grid.prototype.setMap.apply(this, arguments);\n        this.tileOrigin = new OpenLayers.LonLat(this.map.maxExtent.left,\n                                                this.map.maxExtent.top);\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.Zoomify\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Layer.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Layer = OpenLayers.Class({\n\n        id: null,\n\n        name: null,\n\n        div: null,\n\n        opacity: 1,\n\n        alwaysInRange: null,   \n\n        RESOLUTION_PROPERTIES: [\n        'scales', 'resolutions',\n        'maxScale', 'minScale',\n        'maxResolution', 'minResolution',\n        'numZoomLevels', 'maxZoomLevel'\n    ],\n\n        events: null,\n\n        map: null,\n    \n        isBaseLayer: false,\n \n        alpha: false,\n\n        displayInLayerSwitcher: true,\n\n        visibility: true,\n\n        attribution: null,\n\n        inRange: false,\n    \n        imageSize: null,\n\n        options: null,\n\n        eventListeners: null,\n\n        projection: null,    \n    \n        units: null,\n\n        scales: null,\n\n        resolutions: null,\n    \n        maxExtent: null,\n    \n        minExtent: null,\n    \n        maxResolution: null,\n\n        minResolution: null,\n\n        numZoomLevels: null,\n    \n        minScale: null,\n    \n        maxScale: null,\n\n        displayOutsideMaxExtent: false,\n\n        wrapDateLine: false,\n    \n        metadata: null,\n    \n        initialize: function(name, options) {\n\n        this.metadata = {};\n        \n        options = OpenLayers.Util.extend({}, options);\n        if (this.alwaysInRange != null) {\n            options.alwaysInRange = this.alwaysInRange;\n        }\n        this.addOptions(options);\n\n        this.name = name;\n        \n        if (this.id == null) {\n\n            this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + \"_\");\n\n            this.div = OpenLayers.Util.createDiv(this.id);\n            this.div.style.width = \"100%\";\n            this.div.style.height = \"100%\";\n            this.div.dir = \"ltr\";\n\n            this.events = new OpenLayers.Events(this, this.div);\n            if(this.eventListeners instanceof Object) {\n                this.events.on(this.eventListeners);\n            }\n\n        }\n    },\n    \n        destroy: function(setNewBaseLayer) {\n        if (setNewBaseLayer == null) {\n            setNewBaseLayer = true;\n        }\n        if (this.map != null) {\n            this.map.removeLayer(this, setNewBaseLayer);\n        }\n        this.projection = null;\n        this.map = null;\n        this.name = null;\n        this.div = null;\n        this.options = null;\n\n        if (this.events) {\n            if(this.eventListeners) {\n                this.events.un(this.eventListeners);\n            }\n            this.events.destroy();\n        }\n        this.eventListeners = null;\n        this.events = null;\n    },\n    \n       clone: function (obj) {\n        \n        if (obj == null) {\n            obj = new OpenLayers.Layer(this.name, this.getOptions());\n        }\n        OpenLayers.Util.applyDefaults(obj, this);\n        obj.map = null;\n        \n        return obj;\n    },\n    \n        getOptions: function() {\n        var options = {};\n        for(var o in this.options) {\n            options[o] = this[o];\n        }\n        return options;\n    },\n    \n        setName: function(newName) {\n        if (newName != this.name) {\n            this.name = newName;\n            if (this.map != null) {\n                this.map.events.triggerEvent(\"changelayer\", {\n                    layer: this,\n                    property: \"name\"\n                });\n            }\n        }\n    },    \n    \n       addOptions: function (newOptions, reinitialize) {\n\n        if (this.options == null) {\n            this.options = {};\n        }\n        \n        if (newOptions) {\n            if(typeof newOptions.projection == \"string\") {\n                newOptions.projection = new OpenLayers.Projection(newOptions.projection);\n            }\n            if (newOptions.projection) {\n                OpenLayers.Util.applyDefaults(newOptions,\n                    OpenLayers.Projection.defaults[newOptions.projection.getCode()]);\n            }\n            if (newOptions.maxExtent && !(newOptions.maxExtent instanceof OpenLayers.Bounds)) {\n                newOptions.maxExtent = new OpenLayers.Bounds(newOptions.maxExtent);\n            }\n            if (newOptions.minExtent && !(newOptions.minExtent instanceof OpenLayers.Bounds)) {\n                newOptions.minExtent = new OpenLayers.Bounds(newOptions.minExtent);\n            }\n        }\n        OpenLayers.Util.extend(this.options, newOptions);\n        OpenLayers.Util.extend(this, newOptions);\n        if(this.projection && this.projection.getUnits()) {\n            this.units = this.projection.getUnits();\n        }\n        if(this.map) {\n            var resolution = this.map.getResolution();\n            var properties = this.RESOLUTION_PROPERTIES.concat(\n                [\"projection\", \"units\", \"minExtent\", \"maxExtent\"]\n            );\n            for(var o in newOptions) {\n                if(newOptions.hasOwnProperty(o) &&\n                   OpenLayers.Util.indexOf(properties, o) >= 0) {\n\n                    this.initResolutions();\n                    if (reinitialize && this.map.baseLayer === this) {\n                        this.map.setCenter(this.map.getCenter(),\n                            this.map.getZoomForResolution(resolution),\n                            false, true\n                        );\n                        this.map.events.triggerEvent(\"changebaselayer\", {\n                            layer: this\n                        });\n                    }\n                    break;\n                }\n            }\n        }\n    },\n\n        onMapResize: function() {\n    },\n\n        redraw: function() {\n        var redrawn = false;\n        if (this.map) {\n            this.inRange = this.calculateInRange();\n            var extent = this.getExtent();\n\n            if (extent && this.inRange && this.visibility) {\n                var zoomChanged = true;\n                this.moveTo(extent, zoomChanged, false);\n                this.events.triggerEvent(\"moveend\",\n                    {\"zoomChanged\": zoomChanged});\n                redrawn = true;\n            }\n        }\n        return redrawn;\n    },\n\n        moveTo:function(bounds, zoomChanged, dragging) {\n        var display = this.visibility;\n        if (!this.isBaseLayer) {\n            display = display && this.inRange;\n        }\n        this.display(display);\n    },\n\n        moveByPx: function(dx, dy) {\n    },\n\n        setMap: function(map) {\n        if (this.map == null) {\n        \n            this.map = map;\n            this.maxExtent = this.maxExtent || this.map.maxExtent;\n            this.minExtent = this.minExtent || this.map.minExtent;\n\n            this.projection = this.projection || this.map.projection;\n            if (typeof this.projection == \"string\") {\n                this.projection = new OpenLayers.Projection(this.projection);\n            }\n            if (this.projection && this.projection.getUnits()) {\n                this.units = this.projection.getUnits();\n            }\n            else {\n                this.units = this.units || this.map.units;\n            }\n            \n            this.initResolutions();\n            \n            if (!this.isBaseLayer) {\n                this.inRange = this.calculateInRange();\n                var show = ((this.visibility) && (this.inRange));\n                this.div.style.display = show ? \"\" : \"none\";\n            }\n            this.setTileSize();\n        }\n    },\n    \n        afterAdd: function() {\n    },\n    \n        removeMap: function(map) {\n    },\n    \n        setTileSize: function(size) {\n        var tileSize = (size) ? size :\n                                ((this.tileSize) ? this.tileSize :\n                                                   this.map.getTileSize());\n        this.tileSize = tileSize;\n        if(this.gutter) {\n            this.imageSize = new OpenLayers.Size(tileSize.w + (2*this.gutter), \n                                                 tileSize.h + (2*this.gutter)); \n        }\n    },\n\n        getVisibility: function() {\n        return this.visibility;\n    },\n\n        setVisibility: function(visibility) {\n        if (visibility != this.visibility) {\n            this.visibility = visibility;\n            this.display(visibility);\n            this.redraw();\n            if (this.map != null) {\n                this.map.events.triggerEvent(\"changelayer\", {\n                    layer: this,\n                    property: \"visibility\"\n                });\n            }\n            this.events.triggerEvent(\"visibilitychanged\");\n        }\n    },\n\n        display: function(display) {\n        if (display != (this.div.style.display != \"none\")) {\n            this.div.style.display = (display && this.calculateInRange()) ? \"block\" : \"none\";\n        }\n    },\n\n        calculateInRange: function() {\n        var inRange = false;\n\n        if (this.alwaysInRange) {\n            inRange = true;\n        } else {\n            if (this.map) {\n                var resolution = this.map.getResolution();\n                inRange = ( (resolution >= this.minResolution) &&\n                            (resolution <= this.maxResolution) );\n            }\n        }\n        return inRange;\n    },\n\n        setIsBaseLayer: function(isBaseLayer) {\n        if (isBaseLayer != this.isBaseLayer) {\n            this.isBaseLayer = isBaseLayer;\n            if (this.map != null) {\n                this.map.events.triggerEvent(\"changebaselayer\", {\n                    layer: this\n                });\n            }\n        }\n    },\n\n    /*                                                      */\n  /*                 Baselayer Functions                  */\n  /*                                                      */\n    \n        initResolutions: function() {\n\n        var i, len, p;\n        var props = {}, alwaysInRange = true;\n        for(i=0, len=this.RESOLUTION_PROPERTIES.length; i<len; i++) {\n            p = this.RESOLUTION_PROPERTIES[i];\n            props[p] = this.options[p];\n            if(alwaysInRange && this.options[p]) {\n                alwaysInRange = false;\n            }\n        }\n        if(this.options.alwaysInRange == null) {\n            this.alwaysInRange = alwaysInRange;\n        }\n        if(props.resolutions == null) {\n            props.resolutions = this.resolutionsFromScales(props.scales);\n        }\n        if(props.resolutions == null) {\n            props.resolutions = this.calculateResolutions(props);\n        }\n        if(props.resolutions == null) {\n            for(i=0, len=this.RESOLUTION_PROPERTIES.length; i<len; i++) {\n                p = this.RESOLUTION_PROPERTIES[i];\n                props[p] = this.options[p] != null ?\n                    this.options[p] : this.map[p];\n            }\n            if(props.resolutions == null) {\n                props.resolutions = this.resolutionsFromScales(props.scales);\n            }\n            if(props.resolutions == null) {\n                props.resolutions = this.calculateResolutions(props);\n            }\n        }\n        var maxResolution;\n        if(this.options.maxResolution &&\n           this.options.maxResolution !== \"auto\") {\n            maxResolution = this.options.maxResolution;\n        }\n        if(this.options.minScale) {\n            maxResolution = OpenLayers.Util.getResolutionFromScale(\n                this.options.minScale, this.units);\n        }\n        var minResolution;\n        if(this.options.minResolution &&\n           this.options.minResolution !== \"auto\") {\n            minResolution = this.options.minResolution;\n        }\n        if(this.options.maxScale) {\n            minResolution = OpenLayers.Util.getResolutionFromScale(\n                this.options.maxScale, this.units);\n        }\n\n        if(props.resolutions) {\n            props.resolutions.sort(function(a, b) {\n                return (b - a);\n            });\n            if(!maxResolution) {\n                maxResolution = props.resolutions[0];\n            }\n            if(!minResolution) {\n                var lastIdx = props.resolutions.length - 1;\n                minResolution = props.resolutions[lastIdx];\n            }\n        }\n\n        this.resolutions = props.resolutions;\n        if(this.resolutions) {\n            len = this.resolutions.length;\n            this.scales = new Array(len);\n            for(i=0; i<len; i++) {\n                this.scales[i] = OpenLayers.Util.getScaleFromResolution(\n                    this.resolutions[i], this.units);\n            }\n            this.numZoomLevels = len;\n        }\n        this.minResolution = minResolution;\n        if(minResolution) {\n            this.maxScale = OpenLayers.Util.getScaleFromResolution(\n                minResolution, this.units);\n        }\n        this.maxResolution = maxResolution;\n        if(maxResolution) {\n            this.minScale = OpenLayers.Util.getScaleFromResolution(\n                maxResolution, this.units);\n        }\n    },\n\n        resolutionsFromScales: function(scales) {\n        if(scales == null) {\n            return;\n        }\n        var resolutions, i, len;\n        len = scales.length;\n        resolutions = new Array(len);\n        for(i=0; i<len; i++) {\n            resolutions[i] = OpenLayers.Util.getResolutionFromScale(\n                scales[i], this.units);\n        }\n        return resolutions;\n    },\n\n        calculateResolutions: function(props) {\n\n        var viewSize, wRes, hRes;\n        var maxResolution = props.maxResolution;\n        if(props.minScale != null) {\n            maxResolution =\n                OpenLayers.Util.getResolutionFromScale(props.minScale,\n                                                       this.units);\n        } else if(maxResolution == \"auto\" && this.maxExtent != null) {\n            viewSize = this.map.getSize();\n            wRes = this.maxExtent.getWidth() / viewSize.w;\n            hRes = this.maxExtent.getHeight() / viewSize.h;\n            maxResolution = Math.max(wRes, hRes);\n        }\n        var minResolution = props.minResolution;\n        if(props.maxScale != null) {\n            minResolution =\n                OpenLayers.Util.getResolutionFromScale(props.maxScale,\n                                                       this.units);\n        } else if(props.minResolution == \"auto\" && this.minExtent != null) {\n            viewSize = this.map.getSize();\n            wRes = this.minExtent.getWidth() / viewSize.w;\n            hRes = this.minExtent.getHeight()/ viewSize.h;\n            minResolution = Math.max(wRes, hRes);\n        }\n\n        if(typeof maxResolution !== \"number\" &&\n           typeof minResolution !== \"number\" &&\n           this.maxExtent != null) {\n            var tileSize = this.map.getTileSize();\n            maxResolution = Math.max(\n                this.maxExtent.getWidth() / tileSize.w,\n                this.maxExtent.getHeight() / tileSize.h\n            );\n        }\n        var maxZoomLevel = props.maxZoomLevel;\n        var numZoomLevels = props.numZoomLevels;\n        if(typeof minResolution === \"number\" &&\n           typeof maxResolution === \"number\" && numZoomLevels === undefined) {\n            var ratio = maxResolution / minResolution;\n            numZoomLevels = Math.floor(Math.log(ratio) / Math.log(2)) + 1;\n        } else if(numZoomLevels === undefined && maxZoomLevel != null) {\n            numZoomLevels = maxZoomLevel + 1;\n        }\n        if(typeof numZoomLevels !== \"number\" || numZoomLevels <= 0 ||\n           (typeof maxResolution !== \"number\" &&\n                typeof minResolution !== \"number\")) {\n            return;\n        }\n\n        var resolutions = new Array(numZoomLevels);\n        var base = 2;\n        if(typeof minResolution == \"number\" &&\n           typeof maxResolution == \"number\") {\n            base = Math.pow(\n                    (maxResolution / minResolution),\n                (1 / (numZoomLevels - 1))\n            );\n        }\n\n        var i;\n        if(typeof maxResolution === \"number\") {\n            for(i=0; i<numZoomLevels; i++) {\n                resolutions[i] = maxResolution / Math.pow(base, i);\n            }\n        } else {\n            for(i=0; i<numZoomLevels; i++) {\n                resolutions[numZoomLevels - 1 - i] =\n                    minResolution * Math.pow(base, i);\n            }\n        }\n\n        return resolutions;\n    },\n\n        getResolution: function() {\n        var zoom = this.map.getZoom();\n        return this.getResolutionForZoom(zoom);\n    },\n\n        getExtent: function() {\n        return this.map.calculateBounds();\n    },\n\n        getZoomForExtent: function(extent, closest) {\n        var viewSize = this.map.getSize();\n        var idealResolution = Math.max( extent.getWidth()  / viewSize.w,\n                                        extent.getHeight() / viewSize.h );\n\n        return this.getZoomForResolution(idealResolution, closest);\n    },\n    \n        getDataExtent: function () {\n    },\n\n        getResolutionForZoom: function(zoom) {\n        zoom = Math.max(0, Math.min(zoom, this.resolutions.length - 1));\n        var resolution;\n        if(this.map.fractionalZoom) {\n            var low = Math.floor(zoom);\n            var high = Math.ceil(zoom);\n            resolution = this.resolutions[low] -\n                ((zoom-low) * (this.resolutions[low]-this.resolutions[high]));\n        } else {\n            resolution = this.resolutions[Math.round(zoom)];\n        }\n        return resolution;\n    },\n\n        getZoomForResolution: function(resolution, closest) {\n        var zoom, i, len;\n        if(this.map.fractionalZoom) {\n            var lowZoom = 0;\n            var highZoom = this.resolutions.length - 1;\n            var highRes = this.resolutions[lowZoom];\n            var lowRes = this.resolutions[highZoom];\n            var res;\n            for(i=0, len=this.resolutions.length; i<len; ++i) {\n                res = this.resolutions[i];\n                if(res >= resolution) {\n                    highRes = res;\n                    lowZoom = i;\n                }\n                if(res <= resolution) {\n                    lowRes = res;\n                    highZoom = i;\n                    break;\n                }\n            }\n            var dRes = highRes - lowRes;\n            if(dRes > 0) {\n                zoom = lowZoom + ((highRes - resolution) / dRes);\n            } else {\n                zoom = lowZoom;\n            }\n        } else {\n            var diff;\n            var minDiff = Number.POSITIVE_INFINITY;\n            for(i=0, len=this.resolutions.length; i<len; i++) {            \n                if (closest) {\n                    diff = Math.abs(this.resolutions[i] - resolution);\n                    if (diff > minDiff) {\n                        break;\n                    }\n                    minDiff = diff;\n                } else {\n                    if (this.resolutions[i] < resolution) {\n                        break;\n                    }\n                }\n            }\n            zoom = Math.max(0, i-1);\n        }\n        return zoom;\n    },\n    \n        getLonLatFromViewPortPx: function (viewPortPx) {\n        var lonlat = null;\n        var map = this.map;\n        if (viewPortPx != null && map.minPx) {\n            var res = map.getResolution();\n            var maxExtent = map.getMaxExtent({restricted: true});\n            var lon = (viewPortPx.x - map.minPx.x) * res + maxExtent.left;\n            var lat = (map.minPx.y - viewPortPx.y) * res + maxExtent.top;\n            lonlat = new OpenLayers.LonLat(lon, lat);\n\n            if (this.wrapDateLine) {\n                lonlat = lonlat.wrapDateLine(this.maxExtent);\n            }\n        }\n        return lonlat;\n    },\n\n        getViewPortPxFromLonLat: function (lonlat, resolution) {\n        var px = null; \n        if (lonlat != null) {\n            resolution = resolution || this.map.getResolution();\n            var extent = this.map.calculateBounds(null, resolution);\n            px = new OpenLayers.Pixel(\n                (1/resolution * (lonlat.lon - extent.left)),\n                (1/resolution * (extent.top - lonlat.lat))\n            );    \n        }\n        return px;\n    },\n    \n        setOpacity: function(opacity) {\n        if (opacity != this.opacity) {\n            this.opacity = opacity;\n            var childNodes = this.div.childNodes;\n            for(var i = 0, len = childNodes.length; i < len; ++i) {\n                var element = childNodes[i].firstChild || childNodes[i];\n                var lastChild = childNodes[i].lastChild;\n                if (lastChild && lastChild.nodeName.toLowerCase() === \"iframe\") {\n                    element = lastChild.parentNode;\n                }\n                OpenLayers.Util.modifyDOMElement(element, null, null, null, \n                                                 null, null, null, opacity);\n            }\n            if (this.map != null) {\n                this.map.events.triggerEvent(\"changelayer\", {\n                    layer: this,\n                    property: \"opacity\"\n                });\n            }\n        }\n    },\n\n        adjustBounds: function (bounds) {\n\n        if (this.gutter) {\n            var mapGutter = this.gutter * this.map.getResolution();\n            bounds = new OpenLayers.Bounds(bounds.left - mapGutter,\n                                           bounds.bottom - mapGutter,\n                                           bounds.right + mapGutter,\n                                           bounds.top + mapGutter);\n        }\n\n        if (this.wrapDateLine) {\n            var wrappingOptions = { \n                'rightTolerance':this.getResolution(),\n                'leftTolerance':this.getResolution()\n            };    \n            bounds = bounds.wrapDateLine(this.maxExtent, wrappingOptions);\n                              \n        }\n        return bounds;\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Map.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Map = OpenLayers.Class({\n    \n        Z_INDEX_BASE: {\n        BaseLayer: 100,\n        Overlay: 325,\n        Feature: 725,\n        Popup: 750,\n        Control: 1000\n    },\n\n    \n        id: null,\n    \n        fractionalZoom: false,\n    \n        events: null,\n    \n        allOverlays: false,\n\n        div: null,\n    \n        dragging: false,\n\n        size: null,\n    \n        viewPortDiv: null,\n\n        layerContainerOrigin: null,\n\n        layerContainerDiv: null,\n\n        layers: null,\n\n        controls: null,\n\n        popups: null,\n\n        baseLayer: null,\n    \n        center: null,\n\n        resolution: null,\n\n        zoom: 0,    \n\n        panRatio: 1.5,    \n\n        options: null,\n\n        tileSize: null,\n\n        projection: \"EPSG:4326\",    \n        \n        units: null,\n\n        resolutions: null,\n\n        maxResolution: null,\n\n        minResolution: null,\n\n        maxScale: null,\n\n        minScale: null,\n\n        maxExtent: null,\n    \n        minExtent: null,\n    \n        restrictedExtent: null,\n\n        numZoomLevels: 16,\n\n        theme: null,\n    \n        displayProjection: null,\n\n    \n        fallThrough: false,\n\n        autoUpdateSize: true,\n    \n        eventListeners: null,\n\n        panTween: null,\n\n        panMethod: OpenLayers.Easing.Expo.easeOut,\n    \n        panDuration: 50,\n    \n        zoomTween: null,\n\n        zoomMethod: OpenLayers.Easing.Quad.easeOut,\n    \n        zoomDuration: 20,\n    \n        paddingForPopups : null,\n    \n        layerContainerOriginPx: null,\n    \n        minPx: null,\n    \n        maxPx: null,\n    \n                delete this.center;\n            delete this.zoom;\n            this.addLayers(options.layers);\n            if (options.center && !this.getCenter()) {\n                this.setCenter(options.center, options.zoom);\n            }\n        }\n\n        if (this.panMethod) {\n            this.panTween = new OpenLayers.Tween(this.panMethod);\n        }\n        if (this.zoomMethod && this.applyTransform.transform) {\n            this.zoomTween = new OpenLayers.Tween(this.zoomMethod);\n        }\n    },\n\n        getViewport: function() {\n        return this.viewPortDiv;\n    },\n    \n        render: function(div) {\n        this.div = OpenLayers.Util.getElement(div);\n        OpenLayers.Element.addClass(this.div, 'olMap');\n        this.viewPortDiv.parentNode.removeChild(this.viewPortDiv);\n        this.div.appendChild(this.viewPortDiv);\n        this.updateSize();\n    },\n\n        unloadDestroy: null,\n    \n        updateSizeDestroy: null,\n\n        destroy:function() {\n        if (!this.unloadDestroy) {\n            return false;\n        }\n        if(this.panTween) {\n            this.panTween.stop();\n            this.panTween = null;\n        }\n        if(this.zoomTween) {\n            this.zoomTween.stop();\n            this.zoomTween = null;\n        }\n        OpenLayers.Event.stopObserving(window, 'unload', this.unloadDestroy);\n        this.unloadDestroy = null;\n\n        if (this.updateSizeDestroy) {\n            OpenLayers.Event.stopObserving(window, 'resize', \n                                           this.updateSizeDestroy);\n        }\n        \n        this.paddingForPopups = null;    \n\n        if (this.controls != null) {\n            for (var i = this.controls.length - 1; i>=0; --i) {\n                this.controls[i].destroy();\n            } \n            this.controls = null;\n        }\n        if (this.layers != null) {\n            for (var i = this.layers.length - 1; i>=0; --i) {\n                this.layers[i].destroy(false);\n            } \n            this.layers = null;\n        }\n        if (this.viewPortDiv && this.viewPortDiv.parentNode) {\n            this.viewPortDiv.parentNode.removeChild(this.viewPortDiv);\n        }\n        this.viewPortDiv = null;\n        \n        if (this.tileManager) {\n            this.tileManager.removeMap(this);\n            this.tileManager = null;\n        }\n\n        if(this.eventListeners) {\n            this.events.un(this.eventListeners);\n            this.eventListeners = null;\n        }\n        this.events.destroy();\n        this.events = null;\n\n        this.options = null;\n    },\n\n        setOptions: function(options) {\n        var updatePxExtent = this.minPx &&\n            options.restrictedExtent != this.restrictedExtent;\n        OpenLayers.Util.extend(this, options);\n        updatePxExtent && this.moveTo(this.getCachedCenter(), this.zoom, {\n            forceZoomChange: true\n        });\n    },\n\n         getTileSize: function() {\n         return this.tileSize;\n     },\n\n\n        getBy: function(array, property, match) {\n        var test = (typeof match.test == \"function\");\n        var found = OpenLayers.Array.filter(this[array], function(item) {\n            return item[property] == match || (test && match.test(item[property]));\n        });\n        return found;\n    },\n\n        getLayersBy: function(property, match) {\n        return this.getBy(\"layers\", property, match);\n    },\n\n        getLayersByName: function(match) {\n        return this.getLayersBy(\"name\", match);\n    },\n\n        getLayersByClass: function(match) {\n        return this.getLayersBy(\"CLASS_NAME\", match);\n    },\n\n        getControlsBy: function(property, match) {\n        return this.getBy(\"controls\", property, match);\n    },\n\n        getControlsByClass: function(match) {\n        return this.getControlsBy(\"CLASS_NAME\", match);\n    },\n\n    /*                                                      */\n  /*                  Layer Functions                     */\n  /*                                                      */\n  /*     The following functions deal with adding and     */\n  /*        removing Layers to and from the Map           */\n  /*                                                      */\n      getLayer: function(id) {\n        var foundLayer = null;\n        for (var i=0, len=this.layers.length; i<len; i++) {\n            var layer = this.layers[i];\n            if (layer.id == id) {\n                foundLayer = layer;\n                break;\n            }\n        }\n        return foundLayer;\n    },\n\n        resetLayersZIndex: function() {\n        for (var i=0, len=this.layers.length; i<len; i++) {\n            var layer = this.layers[i];\n            this.setLayerZIndex(layer, i);\n        }\n    },\n\n        removeLayer: function(layer, setNewBaseLayer) {\n        if (this.events.triggerEvent(\"preremovelayer\", {layer: layer}) === false) {\n            return;\n        }\n        if (setNewBaseLayer == null) {\n            setNewBaseLayer = true;\n        }\n\n        if (layer.isFixed) {\n            this.viewPortDiv.removeChild(layer.div);\n        } else {\n            this.layerContainerDiv.removeChild(layer.div);\n        }\n        OpenLayers.Util.removeItem(this.layers, layer);\n        layer.removeMap(this);\n        layer.map = null;\n        if(this.baseLayer == layer) {\n            this.baseLayer = null;\n            if(setNewBaseLayer) {\n                for(var i=0, len=this.layers.length; i<len; i++) {\n                    var iLayer = this.layers[i];\n                    if (iLayer.isBaseLayer || this.allOverlays) {\n                        this.setBaseLayer(iLayer);\n                        break;\n                    }\n                }\n            }\n        }\n\n        this.resetLayersZIndex();\n\n        this.events.triggerEvent(\"removelayer\", {layer: layer});\n        layer.events.triggerEvent(\"removed\", {map: this, layer: layer});\n    },\n\n        getNumLayers: function () {\n        return this.layers.length;\n    },\n\n        getLayerIndex: function (layer) {\n        return OpenLayers.Util.indexOf(this.layers, layer);\n    },\n    \n        setLayerIndex: function (layer, idx) {\n        var base = this.getLayerIndex(layer);\n        if (idx < 0) {\n            idx = 0;\n        } else if (idx > this.layers.length) {\n            idx = this.layers.length;\n        }\n        if (base != idx) {\n            this.layers.splice(base, 1);\n            this.layers.splice(idx, 0, layer);\n            for (var i=0, len=this.layers.length; i<len; i++) {\n                this.setLayerZIndex(this.layers[i], i);\n            }\n            this.events.triggerEvent(\"changelayer\", {\n                layer: layer, property: \"order\"\n            });\n            if(this.allOverlays) {\n                if(idx === 0) {\n                    this.setBaseLayer(layer);\n                } else if(this.baseLayer !== this.layers[0]) {\n                    this.setBaseLayer(this.layers[0]);\n                }\n            }\n        }\n    },\n\n        raiseLayer: function (layer, delta) {\n        var idx = this.getLayerIndex(layer) + delta;\n        this.setLayerIndex(layer, idx);\n    },\n    \n        setBaseLayer: function(newBaseLayer) {\n        \n        if (newBaseLayer != this.baseLayer) {\n            if (OpenLayers.Util.indexOf(this.layers, newBaseLayer) != -1) {\n                var center = this.getCachedCenter();\n                var oldResolution = this.getResolution();\n                var newResolution = OpenLayers.Util.getResolutionFromScale(\n                    this.getScale(), newBaseLayer.units\n                );\n                if (this.baseLayer != null && !this.allOverlays) {\n                    this.baseLayer.setVisibility(false);\n                }\n                this.baseLayer = newBaseLayer;\n                \n                if(!this.allOverlays || this.baseLayer.visibility) {\n                    this.baseLayer.setVisibility(true);\n                    if (this.baseLayer.inRange === false) {\n                        this.baseLayer.redraw();\n                    }\n                }\n                if (center != null) {\n                    var newZoom = this.getZoomForResolution(\n                        newResolution || this.resolution, true\n                    );\n                    this.setCenter(center, newZoom, false, oldResolution != newResolution);\n                }\n\n                this.events.triggerEvent(\"changebaselayer\", {\n                    layer: this.baseLayer\n                });\n            }        \n        }\n    },\n\n\n    /*                                                      */\n  /*                 Control Functions                    */\n  /*                                                      */\n  /*     The following functions deal with adding and     */\n  /*        removing Controls to and from the Map         */\n  /*                                                      */\n    /*                                                      */\n  /*                  Popup Functions                     */\n  /*                                                      */\n  /*     The following functions deal with adding and     */\n  /*        removing Popups to and from the Map           */\n  /*                                                      */\n      addPopup: function(popup, exclusive) {\n\n        if (exclusive) {\n            for (var i = this.popups.length - 1; i >= 0; --i) {\n                this.removePopup(this.popups[i]);\n            }\n        }\n\n        popup.map = this;\n        this.popups.push(popup);\n        var popupDiv = popup.draw();\n        if (popupDiv) {\n            popupDiv.style.zIndex = this.Z_INDEX_BASE['Popup'] +\n                                    this.popups.length;\n            this.layerContainerDiv.appendChild(popupDiv);\n        }\n    },\n    \n        removePopup: function(popup) {\n        OpenLayers.Util.removeItem(this.popups, popup);\n        if (popup.div) {\n            try { this.layerContainerDiv.removeChild(popup.div); }\n            catch (e) { } // Popups sometimes apparently get disconnected\n        }\n        popup.map = null;\n    },\n\n    /*                                                      */\n  /*              Container Div Functions                 */\n  /*                                                      */\n  /*   The following functions deal with the access to    */\n  /*    and maintenance of the size of the container div  */\n  /*                                                      */\n      getSize: function () {\n        var size = null;\n        if (this.size != null) {\n            size = this.size.clone();\n        }\n        return size;\n    },\n\n        updateSize: function() {\n        var newSize = this.getCurrentSize();\n        if (newSize && !isNaN(newSize.h) && !isNaN(newSize.w)) {\n            this.events.clearMouseCache();\n            var oldSize = this.getSize();\n            if (oldSize == null) {\n                this.size = oldSize = newSize;\n            }\n            if (!newSize.equals(oldSize)) {\n                this.size = newSize;\n                for(var i=0, len=this.layers.length; i<len; i++) {\n                    this.layers[i].onMapResize();                \n                }\n    \n                var center = this.getCachedCenter();\n    \n                if (this.baseLayer != null && center != null) {\n                    var zoom = this.getZoom();\n                    this.zoom = null;\n                    this.setCenter(center, zoom);\n                }\n    \n            }\n        }\n        this.events.triggerEvent(\"updatesize\");\n    },\n    \n        getCurrentSize: function() {\n\n        var size = new OpenLayers.Size(this.div.clientWidth, \n                                       this.div.clientHeight);\n\n        if (size.w == 0 && size.h == 0 || isNaN(size.w) && isNaN(size.h)) {\n            size.w = this.div.offsetWidth;\n            size.h = this.div.offsetHeight;\n        }\n        if (size.w == 0 && size.h == 0 || isNaN(size.w) && isNaN(size.h)) {\n            size.w = parseInt(this.div.style.width);\n            size.h = parseInt(this.div.style.height);\n        }\n        return size;\n    },\n\n        calculateBounds: function(center, resolution) {\n\n        var extent = null;\n        \n        if (center == null) {\n            center = this.getCachedCenter();\n        }                \n        if (resolution == null) {\n            resolution = this.getResolution();\n        }\n    \n        if ((center != null) && (resolution != null)) {\n            var halfWDeg = (this.size.w * resolution) / 2;\n            var halfHDeg = (this.size.h * resolution) / 2;\n        \n            extent = new OpenLayers.Bounds(center.lon - halfWDeg,\n                                           center.lat - halfHDeg,\n                                           center.lon + halfWDeg,\n                                           center.lat + halfHDeg);\n        }\n\n        return extent;\n    },\n\n\n    /*                                                      */\n  /*            Zoom, Center, Pan Functions               */\n  /*                                                      */\n  /*    The following functions handle the validation,    */\n  /*   getting and setting of the Zoom Level and Center   */\n  /*       as well as the panning of the Map              */\n  /*                                                      */\n          getCenter: function () {\n        var center = null;\n        var cachedCenter = this.getCachedCenter();\n        if (cachedCenter) {\n            center = cachedCenter.clone();\n        }\n        return center;\n    },\n\n        getCachedCenter: function() {\n        if (!this.center && this.size) {\n            this.center = this.getLonLatFromViewPortPx({\n                x: this.size.w / 2,\n                y: this.size.h / 2\n            });\n        }\n        return this.center;\n    },\n\n        getZoom: function () {\n        return this.zoom;\n    },\n    \n        pan: function(dx, dy, options) {\n        options = OpenLayers.Util.applyDefaults(options, {\n            animate: true,\n            dragging: false\n        });\n        if (options.dragging) {\n            if (dx != 0 || dy != 0) {\n                this.moveByPx(dx, dy);\n            }\n        } else {\n            var centerPx = this.getViewPortPxFromLonLat(this.getCachedCenter());\n            var newCenterPx = centerPx.add(dx, dy);\n\n            if (this.dragging || !newCenterPx.equals(centerPx)) {\n                var newCenterLonLat = this.getLonLatFromViewPortPx(newCenterPx);\n                if (options.animate) {\n                    this.panTo(newCenterLonLat);\n                } else {\n                    this.moveTo(newCenterLonLat);\n                    if(this.dragging) {\n                        this.dragging = false;\n                        this.events.triggerEvent(\"moveend\");\n                    }\n                }    \n            }\n        }        \n\n   },\n   \n       panTo: function(lonlat) {\n        if (this.panTween && this.getExtent().scale(this.panRatio).containsLonLat(lonlat)) {\n            var center = this.getCachedCenter();\n            if (lonlat.equals(center)) {\n                return;\n            }\n\n            var from = this.getPixelFromLonLat(center);\n            var to = this.getPixelFromLonLat(lonlat);\n            var vector = { x: to.x - from.x, y: to.y - from.y };\n            var last = { x: 0, y: 0 };\n\n            this.panTween.start( { x: 0, y: 0 }, vector, this.panDuration, {\n                callbacks: {\n                    eachStep: OpenLayers.Function.bind(function(px) {\n                        var x = px.x - last.x,\n                            y = px.y - last.y;\n                        this.moveByPx(x, y);\n                        last.x = Math.round(px.x);\n                        last.y = Math.round(px.y);\n                    }, this),\n                    done: OpenLayers.Function.bind(function(px) {\n                        this.moveTo(lonlat);\n                        this.dragging = false;\n                        this.events.triggerEvent(\"moveend\");\n                    }, this)\n                }\n            });\n        } else {\n            this.setCenter(lonlat);\n        }\n    },\n\n        setCenter: function(lonlat, zoom, dragging, forceZoomChange) {\n        if (this.panTween) {\n            this.panTween.stop();\n        }\n        if (this.zoomTween) {\n            this.zoomTween.stop();\n        }            \n        this.moveTo(lonlat, zoom, {\n            'dragging': dragging,\n            'forceZoomChange': forceZoomChange\n        });\n    },\n    \n        moveByPx: function(dx, dy) {\n        var hw = this.size.w / 2;\n        var hh = this.size.h / 2;\n        var x = hw + dx;\n        var y = hh + dy;\n        var wrapDateLine = this.baseLayer.wrapDateLine;\n        var xRestriction = 0;\n        var yRestriction = 0;\n        if (this.restrictedExtent) {\n            xRestriction = hw;\n            yRestriction = hh;\n            wrapDateLine = false;\n        }\n        dx = wrapDateLine ||\n                    x <= this.maxPx.x - xRestriction &&\n                    x >= this.minPx.x + xRestriction ? Math.round(dx) : 0;\n        dy = y <= this.maxPx.y - yRestriction &&\n                    y >= this.minPx.y + yRestriction ? Math.round(dy) : 0;\n        if (dx || dy) {\n            if (!this.dragging) {\n                this.dragging = true;\n                this.events.triggerEvent(\"movestart\");\n            }\n            this.center = null;\n            if (dx) {\n                this.layerContainerOriginPx.x -= dx;\n                this.minPx.x -= dx;\n                this.maxPx.x -= dx;\n            }\n            if (dy) {\n                this.layerContainerOriginPx.y -= dy;\n                this.minPx.y -= dy;\n                this.maxPx.y -= dy;\n            }\n            this.applyTransform();\n            var layer, i, len;\n            for (i=0, len=this.layers.length; i<len; ++i) {\n                layer = this.layers[i];\n                if (layer.visibility &&\n                    (layer === this.baseLayer || layer.inRange)) {\n                    layer.moveByPx(dx, dy);\n                    layer.events.triggerEvent(\"move\");\n                }\n            }\n            this.events.triggerEvent(\"move\");\n        }\n    },\n    \n        adjustZoom: function(zoom) {\n        if (this.baseLayer && this.baseLayer.wrapDateLine) {\n            var resolution, resolutions = this.baseLayer.resolutions,\n                maxResolution = this.getMaxExtent().getWidth() / this.size.w;\n            if (this.getResolutionForZoom(zoom) > maxResolution) {\n                if (this.fractionalZoom) {\n                    zoom = this.getZoomForResolution(maxResolution);\n                } else {\n                    for (var i=zoom|0, ii=resolutions.length; i<ii; ++i) {\n                        if (resolutions[i] <= maxResolution) {\n                            zoom = i;\n                            break;\n                        }\n                    }\n                } \n            }\n        }\n        return zoom;\n    },\n    \n        getMinZoom: function() {\n        return this.adjustZoom(0);\n    },\n\n        moveTo: function(lonlat, zoom, options) {\n        if (lonlat != null && !(lonlat instanceof OpenLayers.LonLat)) {\n            lonlat = new OpenLayers.LonLat(lonlat);\n        }\n        if (!options) { \n            options = {};\n        }\n        if (zoom != null) {\n            zoom = parseFloat(zoom);\n            if (!this.fractionalZoom) {\n                zoom = Math.round(zoom);\n            }\n        }\n        var requestedZoom = zoom;\n        zoom = this.adjustZoom(zoom);\n        if (zoom !== requestedZoom) {\n            lonlat = this.getCenter();\n        }\n        var dragging = options.dragging || this.dragging;\n        var forceZoomChange = options.forceZoomChange;\n\n        if (!this.getCachedCenter() && !this.isValidLonLat(lonlat)) {\n            lonlat = this.maxExtent.getCenterLonLat();\n            this.center = lonlat.clone();\n        }\n\n        if(this.restrictedExtent != null) {\n            if(lonlat == null) { \n                lonlat = this.center; \n            }\n            if(zoom == null) { \n                zoom = this.getZoom(); \n            }\n            var resolution = this.getResolutionForZoom(zoom);\n            var extent = this.calculateBounds(lonlat, resolution); \n            if(!this.restrictedExtent.containsBounds(extent)) {\n                var maxCenter = this.restrictedExtent.getCenterLonLat(); \n                if(extent.getWidth() > this.restrictedExtent.getWidth()) { \n                    lonlat = new OpenLayers.LonLat(maxCenter.lon, lonlat.lat); \n                } else if(extent.left < this.restrictedExtent.left) {\n                    lonlat = lonlat.add(this.restrictedExtent.left -\n                                        extent.left, 0); \n                } else if(extent.right > this.restrictedExtent.right) { \n                    lonlat = lonlat.add(this.restrictedExtent.right -\n                                        extent.right, 0); \n                } \n                if(extent.getHeight() > this.restrictedExtent.getHeight()) { \n                    lonlat = new OpenLayers.LonLat(lonlat.lon, maxCenter.lat); \n                } else if(extent.bottom < this.restrictedExtent.bottom) { \n                    lonlat = lonlat.add(0, this.restrictedExtent.bottom -\n                                        extent.bottom); \n                } \n                else if(extent.top > this.restrictedExtent.top) { \n                    lonlat = lonlat.add(0, this.restrictedExtent.top -\n                                        extent.top); \n                } \n            }\n        }\n        \n        var zoomChanged = forceZoomChange || (\n                            (this.isValidZoomLevel(zoom)) && \n                            (zoom != this.getZoom()) );\n\n        var centerChanged = (this.isValidLonLat(lonlat)) && \n                            (!lonlat.equals(this.center));\n        if (zoomChanged || centerChanged || dragging) {\n            dragging || this.events.triggerEvent(\"movestart\", {\n                zoomChanged: zoomChanged\n            });\n\n            if (centerChanged) {\n                if (!zoomChanged && this.center) { \n                    this.centerLayerContainer(lonlat);\n                }\n                this.center = lonlat.clone();\n            }\n\n            var res = zoomChanged ?\n                this.getResolutionForZoom(zoom) : this.getResolution();\n            if (zoomChanged || this.layerContainerOrigin == null) {\n                this.layerContainerOrigin = this.getCachedCenter();\n                this.layerContainerOriginPx.x = 0;\n                this.layerContainerOriginPx.y = 0;\n                this.applyTransform();\n                var maxExtent = this.getMaxExtent({restricted: true});\n                var maxExtentCenter = maxExtent.getCenterLonLat();\n                var lonDelta = this.center.lon - maxExtentCenter.lon;\n                var latDelta = maxExtentCenter.lat - this.center.lat;\n                var extentWidth = Math.round(maxExtent.getWidth() / res);\n                var extentHeight = Math.round(maxExtent.getHeight() / res);\n                this.minPx = {\n                    x: (this.size.w - extentWidth) / 2 - lonDelta / res,\n                    y: (this.size.h - extentHeight) / 2 - latDelta / res\n                };\n                this.maxPx = {\n                    x: this.minPx.x + Math.round(maxExtent.getWidth() / res),\n                    y: this.minPx.y + Math.round(maxExtent.getHeight() / res)\n                };\n            }\n\n            if (zoomChanged) {\n                this.zoom = zoom;\n                this.resolution = res;\n            }    \n            \n            var bounds = this.getExtent();\n\n            if(this.baseLayer.visibility) {\n                this.baseLayer.moveTo(bounds, zoomChanged, options.dragging);\n                options.dragging || this.baseLayer.events.triggerEvent(\n                    \"moveend\", {zoomChanged: zoomChanged}\n                );\n            }\n            \n            bounds = this.baseLayer.getExtent();\n            \n            for (var i=this.layers.length-1; i>=0; --i) {\n                var layer = this.layers[i];\n                if (layer !== this.baseLayer && !layer.isBaseLayer) {\n                    var inRange = layer.calculateInRange();\n                    if (layer.inRange != inRange) {\n                        layer.inRange = inRange;\n                        if (!inRange) {\n                            layer.display(false);\n                        }\n                        this.events.triggerEvent(\"changelayer\", {\n                            layer: layer, property: \"visibility\"\n                        });\n                    }\n                    if (inRange && layer.visibility) {\n                        layer.moveTo(bounds, zoomChanged, options.dragging);\n                        options.dragging || layer.events.triggerEvent(\n                            \"moveend\", {zoomChanged: zoomChanged}\n                        );\n                    }\n                }                \n            }\n            \n            this.events.triggerEvent(\"move\");\n            dragging || this.events.triggerEvent(\"moveend\");\n\n            if (zoomChanged) {\n                for (var i=0, len=this.popups.length; i<len; i++) {\n                    this.popups[i].updatePosition();\n                }\n                this.events.triggerEvent(\"zoomend\");\n            }\n        }\n    },\n\n        centerLayerContainer: function (lonlat) {\n        var originPx = this.getViewPortPxFromLonLat(this.layerContainerOrigin);\n        var newPx = this.getViewPortPxFromLonLat(lonlat);\n\n        if ((originPx != null) && (newPx != null)) {\n            var oldLeft = this.layerContainerOriginPx.x;\n            var oldTop = this.layerContainerOriginPx.y;\n            var newLeft = Math.round(originPx.x - newPx.x);\n            var newTop = Math.round(originPx.y - newPx.y);\n            this.applyTransform(\n                (this.layerContainerOriginPx.x = newLeft),\n                (this.layerContainerOriginPx.y = newTop));\n            var dx = oldLeft - newLeft;\n            var dy = oldTop - newTop;\n            this.minPx.x -= dx;\n            this.maxPx.x -= dx;\n            this.minPx.y -= dy;\n            this.maxPx.y -= dy;\n        }        \n    },\n\n        isValidZoomLevel: function(zoomLevel) {\n        return ( (zoomLevel != null) &&\n                 (zoomLevel >= 0) && \n                 (zoomLevel < this.getNumZoomLevels()) );\n    },\n    \n        isValidLonLat: function(lonlat) {\n        var valid = false;\n        if (lonlat != null) {\n            var maxExtent = this.getMaxExtent();\n            var worldBounds = this.baseLayer.wrapDateLine && maxExtent;\n            valid = maxExtent.containsLonLat(lonlat, {worldBounds: worldBounds});\n        }\n        return valid;\n    },\n\n    /*                                                      */\n  /*                 Layer Options                        */\n  /*                                                      */\n  /*    Accessor functions to Layer Options parameters    */\n  /*                                                      */\n      \n        getProjection: function() {\n        var projection = this.getProjectionObject();\n        return projection ? projection.getCode() : null;\n    },\n    \n        getProjectionObject: function() {\n        var projection = null;\n        if (this.baseLayer != null) {\n            projection = this.baseLayer.projection;\n        }\n        return projection;\n    },\n    \n        getMaxResolution: function() {\n        var maxResolution = null;\n        if (this.baseLayer != null) {\n            maxResolution = this.baseLayer.maxResolution;\n        }\n        return maxResolution;\n    },\n        \n        getMaxExtent: function (options) {\n        var maxExtent = null;\n        if(options && options.restricted && this.restrictedExtent){\n            maxExtent = this.restrictedExtent;\n        } else if (this.baseLayer != null) {\n            maxExtent = this.baseLayer.maxExtent;\n        }        \n        return maxExtent;\n    },\n    \n        getNumZoomLevels: function() {\n        var numZoomLevels = null;\n        if (this.baseLayer != null) {\n            numZoomLevels = this.baseLayer.numZoomLevels;\n        }\n        return numZoomLevels;\n    },\n\n    /*                                                      */\n  /*                 Baselayer Functions                  */\n  /*                                                      */\n  /*    The following functions, all publicly exposed     */\n  /*       in the API?, are all merely wrappers to the    */\n  /*       the same calls on whatever layer is set as     */\n  /*                the current base layer                */\n  /*                                                      */\n  \n        getExtent: function () {\n        var extent = null;\n        if (this.baseLayer != null) {\n            extent = this.baseLayer.getExtent();\n        }\n        return extent;\n    },\n\n        getResolution: function () {\n        var resolution = null;\n        if (this.baseLayer != null) {\n            resolution = this.baseLayer.getResolution();\n        } else if(this.allOverlays === true && this.layers.length > 0) {\n            resolution = this.layers[0].getResolution();\n        }\n        return resolution;\n    },\n\n        getUnits: function () {\n        var units = null;\n        if (this.baseLayer != null) {\n            units = this.baseLayer.units;\n        }\n        return units;\n    },\n\n         getScale: function () {\n        var scale = null;\n        if (this.baseLayer != null) {\n            var res = this.getResolution();\n            var units = this.baseLayer.units;\n            scale = OpenLayers.Util.getScaleFromResolution(res, units);\n        }\n        return scale;\n    },\n\n\n        getZoomForExtent: function (bounds, closest) {\n        var zoom = null;\n        if (this.baseLayer != null) {\n            zoom = this.baseLayer.getZoomForExtent(bounds, closest);\n        }\n        return zoom;\n    },\n\n        getResolutionForZoom: function(zoom) {\n        var resolution = null;\n        if(this.baseLayer) {\n            resolution = this.baseLayer.getResolutionForZoom(zoom);\n        }\n        return resolution;\n    },\n\n        getZoomForResolution: function(resolution, closest) {\n        var zoom = null;\n        if (this.baseLayer != null) {\n            zoom = this.baseLayer.getZoomForResolution(resolution, closest);\n        }\n        return zoom;\n    },\n\n    /*                                                      */\n  /*                  Zooming Functions                   */\n  /*                                                      */\n  /*    The following functions, all publicly exposed     */\n  /*       in the API, are all merely wrappers to the     */\n  /*               the setCenter() function               */\n  /*                                                      */\n    \n        zoomTo: function(zoom, xy) {\n        \n        var map = this;\n        if (map.isValidZoomLevel(zoom)) {\n            if (map.baseLayer.wrapDateLine) {\n                zoom = map.adjustZoom(zoom);\n            }\n            var center = xy ?\n                map.getZoomTargetCenter(xy, map.getResolutionForZoom(zoom)) :\n                map.getCenter();\n            if (center) {\n                map.events.triggerEvent('zoomstart', {\n                    center: center,\n                    zoom: zoom\n                });\n            }\n            if (map.zoomTween) {\n                map.zoomTween.stop();\n                var currentRes = map.getResolution(),\n                    targetRes = map.getResolutionForZoom(zoom),\n                    start = {scale: 1},\n                    end = {scale: currentRes / targetRes};\n                if (!xy) {\n                    var size = map.getSize();\n                    xy = {x: size.w / 2, y: size.h / 2};\n                }\n                map.zoomTween.start(start, end, map.zoomDuration, {\n                    minFrameRate: 50, // don't spend much time zooming\n                    callbacks: {\n                        eachStep: function(data) {\n                            var containerOrigin = map.layerContainerOriginPx,\n                                scale = data.scale,\n                                dx = ((scale - 1) * (containerOrigin.x - xy.x)) | 0,\n                                dy = ((scale - 1) * (containerOrigin.y - xy.y)) | 0;\n                            map.applyTransform(containerOrigin.x + dx, containerOrigin.y + dy, scale);\n                        },\n                        done: function(data) {\n                            map.applyTransform();\n                            var resolution = map.getResolution() / data.scale,\n                                newZoom = map.getZoomForResolution(resolution, true),\n                                newCenter = data.scale === 1 ? center :\n                                        map.getZoomTargetCenter(xy, resolution);\n                            map.moveTo(newCenter, newZoom);\n                        }\n                    }\n                });\n            } else {\n                map.setCenter(center, zoom);\n            }\n        }\n    },\n        \n        zoomIn: function() {\n        if (this.zoomTween) {\n            this.zoomTween.stop();\n        }\n        this.zoomTo(this.getZoom() + 1);\n    },\n    \n        zoomOut: function() {\n        if (this.zoomTween) {\n            this.zoomTween.stop();\n        }\n        this.zoomTo(this.getZoom() - 1);\n    },\n\n        zoomToExtent: function(bounds, closest) {\n        if (!(bounds instanceof OpenLayers.Bounds)) {\n            bounds = new OpenLayers.Bounds(bounds);\n        }\n        var center = bounds.getCenterLonLat();\n        if (this.baseLayer.wrapDateLine) {\n            var maxExtent = this.getMaxExtent();\n            bounds = bounds.clone();\n            while (bounds.right < bounds.left) {\n                bounds.right += maxExtent.getWidth();\n            }\n            center = bounds.getCenterLonLat().wrapDateLine(maxExtent);\n        }\n        this.setCenter(center, this.getZoomForExtent(bounds, closest));\n    },\n\n        zoomToMaxExtent: function(options) {\n        var restricted = (options) ? options.restricted : true;\n\n        var maxExtent = this.getMaxExtent({\n            'restricted': restricted \n        });\n        this.zoomToExtent(maxExtent);\n    },\n\n        zoomToScale: function(scale, closest) {\n        var res = OpenLayers.Util.getResolutionFromScale(scale, \n                                                         this.baseLayer.units);\n\n        var halfWDeg = (this.size.w * res) / 2;\n        var halfHDeg = (this.size.h * res) / 2;\n        var center = this.getCachedCenter();\n\n        var extent = new OpenLayers.Bounds(center.lon - halfWDeg,\n                                           center.lat - halfHDeg,\n                                           center.lon + halfWDeg,\n                                           center.lat + halfHDeg);\n        this.zoomToExtent(extent, closest);\n    },\n    \n    /*                                                      */\n  /*             Translation Functions                    */\n  /*                                                      */\n  /*      The following functions translate between       */\n  /*           LonLat, LayerPx, and ViewPortPx            */\n  /*                                                      */\n\n        getLonLatFromViewPortPx: function (viewPortPx) {\n        var lonlat = null; \n        if (this.baseLayer != null) {\n            lonlat = this.baseLayer.getLonLatFromViewPortPx(viewPortPx);\n        }\n        return lonlat;\n    },\n\n        getViewPortPxFromLonLat: function (lonlat) {\n        var px = null; \n        if (this.baseLayer != null) {\n            px = this.baseLayer.getViewPortPxFromLonLat(lonlat);\n        }\n        return px;\n    },\n\n        getZoomTargetCenter: function (xy, resolution) {\n        var lonlat = null,\n            size = this.getSize(),\n            deltaX  = size.w/2 - xy.x,\n            deltaY  = xy.y - size.h/2,\n            zoomPoint = this.getLonLatFromPixel(xy);\n        if (zoomPoint) {\n            lonlat = new OpenLayers.LonLat(\n                zoomPoint.lon + deltaX * resolution,\n                zoomPoint.lat + deltaY * resolution\n            );\n        }\n        return lonlat;\n    },\n\n        getLonLatFromPixel: function (px) {\n        return this.getLonLatFromViewPortPx(px);\n    },\n\n        getPixelFromLonLat: function (lonlat) {\n        var px = this.getViewPortPxFromLonLat(lonlat);\n        px.x = Math.round(px.x);\n        px.y = Math.round(px.y);\n        return px;\n    },\n    \n        getGeodesicPixelSize: function(px) {\n        var lonlat = px ? this.getLonLatFromPixel(px) : (\n            this.getCachedCenter() || new OpenLayers.LonLat(0, 0));\n        var res = this.getResolution();\n        var left = lonlat.add(-res / 2, 0);\n        var right = lonlat.add(res / 2, 0);\n        var bottom = lonlat.add(0, -res / 2);\n        var top = lonlat.add(0, res / 2);\n        var dest = new OpenLayers.Projection(\"EPSG:4326\");\n        var source = this.getProjectionObject() || dest;\n        if(!source.equals(dest)) {\n            left.transform(source, dest);\n            right.transform(source, dest);\n            bottom.transform(source, dest);\n            top.transform(source, dest);\n        }\n        \n        return new OpenLayers.Size(\n            OpenLayers.Util.distVincenty(left, right),\n            OpenLayers.Util.distVincenty(bottom, top)\n        );\n    },\n\n        getViewPortPxFromLayerPx:function(layerPx) {\n        var viewPortPx = null;\n        if (layerPx != null) {\n            var dX = this.layerContainerOriginPx.x;\n            var dY = this.layerContainerOriginPx.y;\n            viewPortPx = layerPx.add(dX, dY);            \n        }\n        return viewPortPx;\n    },\n    \n        getLayerPxFromViewPortPx:function(viewPortPx) {\n        var layerPx = null;\n        if (viewPortPx != null) {\n            var dX = -this.layerContainerOriginPx.x;\n            var dY = -this.layerContainerOriginPx.y;\n            layerPx = viewPortPx.add(dX, dY);\n            if (isNaN(layerPx.x) || isNaN(layerPx.y)) {\n                layerPx = null;\n            }\n        }\n        return layerPx;\n    },\n\n        getLonLatFromLayerPx: function (px) {\n       px = this.getViewPortPxFromLayerPx(px);\n       return this.getLonLatFromViewPortPx(px);         \n    },\n    \n        getLayerPxFromLonLat: function (lonlat) {\n       var px = this.getPixelFromLonLat(lonlat);\n       return this.getLayerPxFromViewPortPx(px);         \n    },\n\n         applyTransform: function(x, y, scale) {\n         scale = scale || 1;\n         var origin = this.layerContainerOriginPx,\n             needTransform = scale !== 1;\n         x = x || origin.x;\n         y = y || origin.y;\n            \n         var style = this.layerContainerDiv.style,\n             transform = this.applyTransform.transform,\n             template = this.applyTransform.template;\n        \n         if (transform === undefined) {\n             transform = OpenLayers.Util.vendorPrefix.style('transform');\n             this.applyTransform.transform = transform;\n             if (transform) {\n                 var computedStyle = OpenLayers.Element.getStyle(this.viewPortDiv,\n                     OpenLayers.Util.vendorPrefix.css('transform'));\n                 if (!computedStyle || computedStyle !== 'none') {\n                     template = ['translate3d(', ',0) ', 'scale3d(', ',1)'];\n                     style[transform] = [template[0], '0,0', template[1]].join('');\n                 }\n                 if (!template || !~style[transform].indexOf(template[0])) {\n                     template = ['translate(', ') ', 'scale(', ')'];\n                 }\n                 this.applyTransform.template = template;\n             }\n         }\n         if (transform !== null && (template[0] === 'translate3d(' || needTransform === true)) {\n             if (needTransform === true && template[0] === 'translate(') {\n                 x -= origin.x;\n                 y -= origin.y;\n                 style.left = origin.x + 'px';\n                 style.top = origin.y + 'px';\n             }\n             style[transform] = [\n                 template[0], x, 'px,', y, 'px', template[1],\n                 template[2], scale, ',', scale, template[3]\n             ].join('');\n         } else {\n             style.left = x + 'px';\n             style.top = y + 'px';\n             if (transform !== null) {\n                 style[transform] = '';\n             }\n         }\n     },\n    \n    CLASS_NAME: \"OpenLayers.Map\"\n});\n\nOpenLayers.Map.TILE_WIDTH = 256;\nOpenLayers.Map.TILE_HEIGHT = 256;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Marker/Box.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Marker.Box = OpenLayers.Class(OpenLayers.Marker, {\n\n        bounds: null,\n\n        div: null,\n    \n        initialize: function(bounds, borderColor, borderWidth) {\n        this.bounds = bounds;\n        this.div    = OpenLayers.Util.createDiv();\n        this.div.style.overflow = 'hidden';\n        this.events = new OpenLayers.Events(this, this.div);\n        this.setBorder(borderColor, borderWidth);\n    },\n\n        setBorder: function (color, width) {\n        if (!color) {\n            color = \"red\";\n        }\n        if (!width) {\n            width = 2;\n        }\n        this.div.style.border = width + \"px solid \" + color;\n    },\n    \n        draw: function(px, sz) {\n        OpenLayers.Util.modifyDOMElement(this.div, null, px, sz);\n        return this.div;\n    }, \n\n        onScreen:function() {\n        var onScreen = false;\n        if (this.map) {\n            var screenBounds = this.map.getExtent();\n            onScreen = screenBounds.containsBounds(this.bounds, true, true);\n        }    \n        return onScreen;\n    },\n    \n        display: function(display) {\n        this.div.style.display = (display) ? \"\" : \"none\";\n    },\n\n    CLASS_NAME: \"OpenLayers.Marker.Box\"\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Marker.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Marker = OpenLayers.Class({\n    \n        icon: null,\n\n        lonlat: null,\n    \n        events: null,\n    \n        map: null,\n    \n        initialize: function(lonlat, icon) {\n        this.lonlat = lonlat;\n        \n        var newIcon = (icon) ? icon : OpenLayers.Marker.defaultIcon();\n        if (this.icon == null) {\n            this.icon = newIcon;\n        } else {\n            this.icon.url = newIcon.url;\n            this.icon.size = newIcon.size;\n            this.icon.offset = newIcon.offset;\n            this.icon.calculateOffset = newIcon.calculateOffset;\n        }\n        this.events = new OpenLayers.Events(this, this.icon.imageDiv);\n    },\n    \n        destroy: function() {\n        this.erase();\n\n        this.map = null;\n\n        this.events.destroy();\n        this.events = null;\n\n        if (this.icon != null) {\n            this.icon.destroy();\n            this.icon = null;\n        }\n    },\n    \n        draw: function(px) {\n        return this.icon.draw(px);\n    }, \n\n        erase: function() {\n        if (this.icon != null) {\n            this.icon.erase();\n        }\n    }, \n\n        moveTo: function (px) {\n        if ((px != null) && (this.icon != null)) {\n            this.icon.moveTo(px);\n        }           \n        this.lonlat = this.map.getLonLatFromLayerPx(px);\n    },\n\n        isDrawn: function() {\n        var isDrawn = (this.icon && this.icon.isDrawn());\n        return isDrawn;   \n    },\n\n        onScreen:function() {\n        \n        var onScreen = false;\n        if (this.map) {\n            var screenBounds = this.map.getExtent();\n            onScreen = screenBounds.containsLonLat(this.lonlat);\n        }    \n        return onScreen;\n    },\n    \n        inflate: function(inflate) {\n        if (this.icon) {\n            this.icon.setSize({\n                w: this.icon.size.w * inflate,\n                h: this.icon.size.h * inflate\n            });\n        }        \n    },\n    \n        setOpacity: function(opacity) {\n        this.icon.setOpacity(opacity);\n    },\n\n        setUrl: function(url) {\n        this.icon.setUrl(url);\n    },    \n\n        display: function(display) {\n        this.icon.display(display);\n    },\n\n    CLASS_NAME: \"OpenLayers.Marker\"\n});\n\n\nOpenLayers.Marker.defaultIcon = function() {\n    return new OpenLayers.Icon(OpenLayers.Util.getImageLocation(\"marker.png\"),\n                               {w: 21, h: 25}, {x: -10.5, y: -25});\n};\n    \n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Popup/Anchored.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Popup.Anchored = \n  OpenLayers.Class(OpenLayers.Popup, {\n\n        relativePosition: null,\n    \n        keepInMap: true,\n\n        anchor: null,\n\n        initialize:function(id, lonlat, contentSize, contentHTML, anchor, closeBox,\n                        closeBoxCallback) {\n        var newArguments = [\n            id, lonlat, contentSize, contentHTML, closeBox, closeBoxCallback\n        ];\n        OpenLayers.Popup.prototype.initialize.apply(this, newArguments);\n\n        this.anchor = (anchor != null) ? anchor \n                                       : { size: new OpenLayers.Size(0,0),\n                                           offset: new OpenLayers.Pixel(0,0)};\n    },\n\n        destroy: function() {\n        this.anchor = null;\n        this.relativePosition = null;\n        \n        OpenLayers.Popup.prototype.destroy.apply(this, arguments);        \n    },\n\n        show: function() {\n        this.updatePosition();\n        OpenLayers.Popup.prototype.show.apply(this, arguments);\n    },\n\n        moveTo: function(px) {\n        var oldRelativePosition = this.relativePosition;\n        this.relativePosition = this.calculateRelativePosition(px);\n\n        OpenLayers.Popup.prototype.moveTo.call(this, this.calculateNewPx(px));\n        if (this.relativePosition != oldRelativePosition) {\n            this.updateRelativePosition();\n        }\n    },\n\n        setSize:function(contentSize) { \n        OpenLayers.Popup.prototype.setSize.apply(this, arguments);\n\n        if ((this.lonlat) && (this.map)) {\n            var px = this.map.getLayerPxFromLonLat(this.lonlat);\n            this.moveTo(px);\n        }\n    },  \n    \n        calculateRelativePosition:function(px) {\n        var lonlat = this.map.getLonLatFromLayerPx(px);        \n        \n        var extent = this.map.getExtent();\n        var quadrant = extent.determineQuadrant(lonlat);\n        \n        return OpenLayers.Bounds.oppositeQuadrant(quadrant);\n    }, \n\n        updateRelativePosition: function() {\n    },\n\n        calculateNewPx:function(px) {\n        var newPx = px.offset(this.anchor.offset);\n        var size = this.size || this.contentSize;\n\n        var top = (this.relativePosition.charAt(0) == 't');\n        newPx.y += (top) ? -size.h : this.anchor.size.h;\n        \n        var left = (this.relativePosition.charAt(1) == 'l');\n        newPx.x += (left) ? -size.w : this.anchor.size.w;\n\n        return newPx;   \n    },\n\n    CLASS_NAME: \"OpenLayers.Popup.Anchored\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Popup/Framed.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Popup.Framed =\n  OpenLayers.Class(OpenLayers.Popup.Anchored, {\n\n        imageSrc: null,\n\n        imageSize: null,\n\n        isAlphaImage: false,\n\n        positionBlocks: null,\n\n        blocks: null,\n\n        fixedRelativePosition: false,\n\n        initialize:function(id, lonlat, contentSize, contentHTML, anchor, closeBox, \n                        closeBoxCallback) {\n\n        OpenLayers.Popup.Anchored.prototype.initialize.apply(this, arguments);\n\n        if (this.fixedRelativePosition) {\n            this.updateRelativePosition();\n            this.calculateRelativePosition = function(px) {\n                return this.relativePosition;\n            };\n        }\n\n        this.contentDiv.style.position = \"absolute\";\n        this.contentDiv.style.zIndex = 1;\n\n        if (closeBox) {\n            this.closeDiv.style.zIndex = 1;\n        }\n\n        this.groupDiv.style.position = \"absolute\";\n        this.groupDiv.style.top = \"0px\";\n        this.groupDiv.style.left = \"0px\";\n        this.groupDiv.style.height = \"100%\";\n        this.groupDiv.style.width = \"100%\";\n    },\n\n        destroy: function() {\n        this.imageSrc = null;\n        this.imageSize = null;\n        this.isAlphaImage = null;\n\n        this.fixedRelativePosition = false;\n        this.positionBlocks = null;\n        for(var i = 0; i < this.blocks.length; i++) {\n            var block = this.blocks[i];\n\n            if (block.image) {\n                block.div.removeChild(block.image);\n            }\n            block.image = null;\n\n            if (block.div) {\n                this.groupDiv.removeChild(block.div);\n            }\n            block.div = null;\n        }\n        this.blocks = null;\n\n        OpenLayers.Popup.Anchored.prototype.destroy.apply(this, arguments);\n    },\n\n        setBackgroundColor:function(color) {\n    },\n\n        setBorder:function() {\n    },\n\n        setOpacity:function(opacity) {\n    },\n\n        setSize:function(contentSize) { \n        OpenLayers.Popup.Anchored.prototype.setSize.apply(this, arguments);\n\n        this.updateBlocks();\n    },\n\n        updateRelativePosition: function() {\n        this.padding = this.positionBlocks[this.relativePosition].padding;\n        if (this.closeDiv) {\n            var contentDivPadding = this.getContentDivPadding();\n\n            this.closeDiv.style.right = contentDivPadding.right + \n                                        this.padding.right + \"px\";\n            this.closeDiv.style.top = contentDivPadding.top + \n                                      this.padding.top + \"px\";\n        }\n\n        this.updateBlocks();\n    },\n\n        calculateNewPx:function(px) {\n        var newPx = OpenLayers.Popup.Anchored.prototype.calculateNewPx.apply(\n            this, arguments\n        );\n\n        newPx = newPx.offset(this.positionBlocks[this.relativePosition].offset);\n\n        return newPx;\n    },\n\n        createBlocks: function() {\n        this.blocks = [];\n        var firstPosition = null;\n        for(var key in this.positionBlocks) {\n            firstPosition = key;\n            break;\n        }\n        \n        var position = this.positionBlocks[firstPosition];\n        for (var i = 0; i < position.blocks.length; i++) {\n\n            var block = {};\n            this.blocks.push(block);\n\n            var divId = this.id + '_FrameDecorationDiv_' + i;\n            block.div = OpenLayers.Util.createDiv(divId, \n                null, null, null, \"absolute\", null, \"hidden\", null\n            );\n\n            var imgId = this.id + '_FrameDecorationImg_' + i;\n            var imageCreator = \n                (this.isAlphaImage) ? OpenLayers.Util.createAlphaImageDiv\n                                    : OpenLayers.Util.createImage;\n\n            block.image = imageCreator(imgId, \n                null, this.imageSize, this.imageSrc, \n                \"absolute\", null, null, null\n            );\n\n            block.div.appendChild(block.image);\n            this.groupDiv.appendChild(block.div);\n        }\n    },\n\n        updateBlocks: function() {\n        if (!this.blocks) {\n            this.createBlocks();\n        }\n        \n        if (this.size && this.relativePosition) {\n            var position = this.positionBlocks[this.relativePosition];\n            for (var i = 0; i < position.blocks.length; i++) {\n    \n                var positionBlock = position.blocks[i];\n                var block = this.blocks[i];\n                var l = positionBlock.anchor.left;\n                var b = positionBlock.anchor.bottom;\n                var r = positionBlock.anchor.right;\n                var t = positionBlock.anchor.top;\n                var w = (isNaN(positionBlock.size.w)) ? this.size.w - (r + l) \n                                                      : positionBlock.size.w;\n    \n                var h = (isNaN(positionBlock.size.h)) ? this.size.h - (b + t) \n                                                      : positionBlock.size.h;\n    \n                block.div.style.width = (w < 0 ? 0 : w) + 'px';\n                block.div.style.height = (h < 0 ? 0 : h) + 'px';\n    \n                block.div.style.left = (l != null) ? l + 'px' : '';\n                block.div.style.bottom = (b != null) ? b + 'px' : '';\n                block.div.style.right = (r != null) ? r + 'px' : '';            \n                block.div.style.top = (t != null) ? t + 'px' : '';\n    \n                block.image.style.left = positionBlock.position.x + 'px';\n                block.image.style.top = positionBlock.position.y + 'px';\n            }\n    \n            this.contentDiv.style.left = this.padding.left + \"px\";\n            this.contentDiv.style.top = this.padding.top + \"px\";\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Popup.Framed\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Popup/FramedCloud.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Popup.FramedCloud = \n  OpenLayers.Class(OpenLayers.Popup.Framed, {\n\n        contentDisplayClass: \"olFramedCloudPopupContent\",\n\n        autoSize: true,\n\n        panMapIfOutOfView: true,\n\n        imageSize: new OpenLayers.Size(1276, 736),\n\n        isAlphaImage: false,\n\n        fixedRelativePosition: false,\n\n        positionBlocks: {\n        \"tl\": {\n            'offset': new OpenLayers.Pixel(44, 0),\n            'padding': new OpenLayers.Bounds(8, 40, 8, 9),\n            'blocks': [\n                { // top-left\n                    size: new OpenLayers.Size('auto', 'auto'),\n                    anchor: new OpenLayers.Bounds(0, 51, 22, 0),\n                    position: new OpenLayers.Pixel(0, 0)\n                },\n                { //top-right\n                    size: new OpenLayers.Size(22, 'auto'),\n                    anchor: new OpenLayers.Bounds(null, 50, 0, 0),\n                    position: new OpenLayers.Pixel(-1238, 0)\n                },\n                { //bottom-left\n                    size: new OpenLayers.Size('auto', 19),\n                    anchor: new OpenLayers.Bounds(0, 32, 22, null),\n                    position: new OpenLayers.Pixel(0, -631)\n                },\n                { //bottom-right\n                    size: new OpenLayers.Size(22, 18),\n                    anchor: new OpenLayers.Bounds(null, 32, 0, null),\n                    position: new OpenLayers.Pixel(-1238, -632)\n                },\n                { // stem\n                    size: new OpenLayers.Size(81, 35),\n                    anchor: new OpenLayers.Bounds(null, 0, 0, null),\n                    position: new OpenLayers.Pixel(0, -688)\n                }\n            ]\n        },\n        \"tr\": {\n            'offset': new OpenLayers.Pixel(-45, 0),\n            'padding': new OpenLayers.Bounds(8, 40, 8, 9),\n            'blocks': [\n                { // top-left\n                    size: new OpenLayers.Size('auto', 'auto'),\n                    anchor: new OpenLayers.Bounds(0, 51, 22, 0),\n                    position: new OpenLayers.Pixel(0, 0)\n                },\n                { //top-right\n                    size: new OpenLayers.Size(22, 'auto'),\n                    anchor: new OpenLayers.Bounds(null, 50, 0, 0),\n                    position: new OpenLayers.Pixel(-1238, 0)\n                },\n                { //bottom-left\n                    size: new OpenLayers.Size('auto', 19),\n                    anchor: new OpenLayers.Bounds(0, 32, 22, null),\n                    position: new OpenLayers.Pixel(0, -631)\n                },\n                { //bottom-right\n                    size: new OpenLayers.Size(22, 19),\n                    anchor: new OpenLayers.Bounds(null, 32, 0, null),\n                    position: new OpenLayers.Pixel(-1238, -631)\n                },\n                { // stem\n                    size: new OpenLayers.Size(81, 35),\n                    anchor: new OpenLayers.Bounds(0, 0, null, null),\n                    position: new OpenLayers.Pixel(-215, -687)\n                }\n            ]\n        },\n        \"bl\": {\n            'offset': new OpenLayers.Pixel(45, 0),\n            'padding': new OpenLayers.Bounds(8, 9, 8, 40),\n            'blocks': [\n                { // top-left\n                    size: new OpenLayers.Size('auto', 'auto'),\n                    anchor: new OpenLayers.Bounds(0, 21, 22, 32),\n                    position: new OpenLayers.Pixel(0, 0)\n                },\n                { //top-right\n                    size: new OpenLayers.Size(22, 'auto'),\n                    anchor: new OpenLayers.Bounds(null, 21, 0, 32),\n                    position: new OpenLayers.Pixel(-1238, 0)\n                },\n                { //bottom-left\n                    size: new OpenLayers.Size('auto', 21),\n                    anchor: new OpenLayers.Bounds(0, 0, 22, null),\n                    position: new OpenLayers.Pixel(0, -629)\n                },\n                { //bottom-right\n                    size: new OpenLayers.Size(22, 21),\n                    anchor: new OpenLayers.Bounds(null, 0, 0, null),\n                    position: new OpenLayers.Pixel(-1238, -629)\n                },\n                { // stem\n                    size: new OpenLayers.Size(81, 33),\n                    anchor: new OpenLayers.Bounds(null, null, 0, 0),\n                    position: new OpenLayers.Pixel(-101, -674)\n                }\n            ]\n        },\n        \"br\": {\n            'offset': new OpenLayers.Pixel(-44, 0),\n            'padding': new OpenLayers.Bounds(8, 9, 8, 40),\n            'blocks': [\n                { // top-left\n                    size: new OpenLayers.Size('auto', 'auto'),\n                    anchor: new OpenLayers.Bounds(0, 21, 22, 32),\n                    position: new OpenLayers.Pixel(0, 0)\n                },\n                { //top-right\n                    size: new OpenLayers.Size(22, 'auto'),\n                    anchor: new OpenLayers.Bounds(null, 21, 0, 32),\n                    position: new OpenLayers.Pixel(-1238, 0)\n                },\n                { //bottom-left\n                    size: new OpenLayers.Size('auto', 21),\n                    anchor: new OpenLayers.Bounds(0, 0, 22, null),\n                    position: new OpenLayers.Pixel(0, -629)\n                },\n                { //bottom-right\n                    size: new OpenLayers.Size(22, 21),\n                    anchor: new OpenLayers.Bounds(null, 0, 0, null),\n                    position: new OpenLayers.Pixel(-1238, -629)\n                },\n                { // stem\n                    size: new OpenLayers.Size(81, 33),\n                    anchor: new OpenLayers.Bounds(0, null, null, 0),\n                    position: new OpenLayers.Pixel(-311, -674)\n                }\n            ]\n        }\n    },\n\n        minSize: new OpenLayers.Size(105, 10),\n\n        maxSize: new OpenLayers.Size(1200, 660),\n\n        initialize:function(id, lonlat, contentSize, contentHTML, anchor, closeBox, \n                        closeBoxCallback) {\n\n        this.imageSrc = OpenLayers.Util.getImageLocation('cloud-popup-relative.png');\n        OpenLayers.Popup.Framed.prototype.initialize.apply(this, arguments);\n        this.contentDiv.className = this.contentDisplayClass;\n    },\n\n    CLASS_NAME: \"OpenLayers.Popup.FramedCloud\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Popup.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Popup = OpenLayers.Class({\n\n        events: null,\n    \n        id: \"\",\n\n        lonlat: null,\n\n        div: null,\n\n        contentSize: null,    \n\n        size: null,    \n\n        contentHTML: null,\n    \n        backgroundColor: \"\",\n    \n        opacity: \"\",\n\n        border: \"\",\n    \n        contentDiv: null,\n    \n        groupDiv: null,\n\n        closeDiv: null,\n\n        autoSize: false,\n\n        minSize: null,\n\n        maxSize: null,\n\n        displayClass: \"olPopup\",\n\n        contentDisplayClass: \"olPopupContent\",\n\n        padding: 0,\n\n        disableFirefoxOverflowHack: false,\n\n        fixPadding: function() {\n        if (typeof this.padding == \"number\") {\n            this.padding = new OpenLayers.Bounds(\n                this.padding, this.padding, this.padding, this.padding\n            );\n        }\n    },\n\n        panMapIfOutOfView: false,\n    \n        keepInMap: false,\n\n        closeOnMove: false,\n    \n        map: null,\n\n        initialize:function(id, lonlat, contentSize, contentHTML, closeBox, closeBoxCallback) {\n        if (id == null) {\n            id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + \"_\");\n        }\n\n        this.id = id;\n        this.lonlat = lonlat;\n\n        this.contentSize = (contentSize != null) ? contentSize \n                                  : new OpenLayers.Size(\n                                                   OpenLayers.Popup.WIDTH,\n                                                   OpenLayers.Popup.HEIGHT);\n        if (contentHTML != null) { \n             this.contentHTML = contentHTML;\n        }\n        this.backgroundColor = OpenLayers.Popup.COLOR;\n        this.opacity = OpenLayers.Popup.OPACITY;\n        this.border = OpenLayers.Popup.BORDER;\n\n        this.div = OpenLayers.Util.createDiv(this.id, null, null, \n                                             null, null, null, \"hidden\");\n        this.div.className = this.displayClass;\n        \n        var groupDivId = this.id + \"_GroupDiv\";\n        this.groupDiv = OpenLayers.Util.createDiv(groupDivId, null, null, \n                                                    null, \"relative\", null,\n                                                    \"hidden\");\n\n        var id = this.div.id + \"_contentDiv\";\n        this.contentDiv = OpenLayers.Util.createDiv(id, null, this.contentSize.clone(), \n                                                    null, \"relative\");\n        this.contentDiv.className = this.contentDisplayClass;\n        this.groupDiv.appendChild(this.contentDiv);\n        this.div.appendChild(this.groupDiv);\n\n        if (closeBox) {\n            this.addCloseBox(closeBoxCallback);\n        } \n\n        this.registerEvents();\n    },\n\n        destroy: function() {\n\n        this.id = null;\n        this.lonlat = null;\n        this.size = null;\n        this.contentHTML = null;\n        \n        this.backgroundColor = null;\n        this.opacity = null;\n        this.border = null;\n        \n        if (this.closeOnMove && this.map) {\n            this.map.events.unregister(\"movestart\", this, this.hide);\n        }\n\n        this.events.destroy();\n        this.events = null;\n        \n        if (this.closeDiv) {\n            OpenLayers.Event.stopObservingElement(this.closeDiv); \n            this.groupDiv.removeChild(this.closeDiv);\n        }\n        this.closeDiv = null;\n        \n        this.div.removeChild(this.groupDiv);\n        this.groupDiv = null;\n\n        if (this.map != null) {\n            this.map.removePopup(this);\n        }\n        this.map = null;\n        this.div = null;\n        \n        this.autoSize = null;\n        this.minSize = null;\n        this.maxSize = null;\n        this.padding = null;\n        this.panMapIfOutOfView = null;\n    },\n\n        draw: function(px) {\n        if (px == null) {\n            if ((this.lonlat != null) && (this.map != null)) {\n                px = this.map.getLayerPxFromLonLat(this.lonlat);\n            }\n        }\n        if (this.closeOnMove) {\n            this.map.events.register(\"movestart\", this, this.hide);\n        }\n        if (!this.disableFirefoxOverflowHack && OpenLayers.BROWSER_NAME == 'firefox') {\n            this.map.events.register(\"movestart\", this, function() {\n                var style = document.defaultView.getComputedStyle(\n                    this.contentDiv, null\n                );\n                var currentOverflow = style.getPropertyValue(\"overflow\");\n                if (currentOverflow != \"hidden\") {\n                    this.contentDiv._oldOverflow = currentOverflow;\n                    this.contentDiv.style.overflow = \"hidden\";\n                }\n            });\n            this.map.events.register(\"moveend\", this, function() {\n                var oldOverflow = this.contentDiv._oldOverflow;\n                if (oldOverflow) {\n                    this.contentDiv.style.overflow = oldOverflow;\n                    this.contentDiv._oldOverflow = null;\n                }\n            });\n        }\n\n        this.moveTo(px);\n        if (!this.autoSize && !this.size) {\n            this.setSize(this.contentSize);\n        }\n        this.setBackgroundColor();\n        this.setOpacity();\n        this.setBorder();\n        this.setContentHTML();\n        \n        if (this.panMapIfOutOfView) {\n            this.panIntoView();\n        }    \n\n        return this.div;\n    },\n\n        updatePosition: function() {\n        if ((this.lonlat) && (this.map)) {\n            var px = this.map.getLayerPxFromLonLat(this.lonlat);\n            if (px) {\n                this.moveTo(px);           \n            }    \n        }\n    },\n\n        moveTo: function(px) {\n        if ((px != null) && (this.div != null)) {\n            this.div.style.left = px.x + \"px\";\n            this.div.style.top = px.y + \"px\";\n        }\n    },\n\n        visible: function() {\n        return OpenLayers.Element.visible(this.div);\n    },\n\n        toggle: function() {\n        if (this.visible()) {\n            this.hide();\n        } else {\n            this.show();\n        }\n    },\n\n        show: function() {\n        this.div.style.display = '';\n\n        if (this.panMapIfOutOfView) {\n            this.panIntoView();\n        }    \n    },\n\n        hide: function() {\n        this.div.style.display = 'none';\n    },\n\n        setSize:function(contentSize) { \n        this.size = contentSize.clone(); \n        var contentDivPadding = this.getContentDivPadding();\n        var wPadding = contentDivPadding.left + contentDivPadding.right;\n        var hPadding = contentDivPadding.top + contentDivPadding.bottom;\n        this.fixPadding();\n        wPadding += this.padding.left + this.padding.right;\n        hPadding += this.padding.top + this.padding.bottom;\n        if (this.closeDiv) {\n            var closeDivWidth = parseInt(this.closeDiv.style.width);\n            wPadding += closeDivWidth + contentDivPadding.right;\n        }\n        this.size.w += wPadding;\n        this.size.h += hPadding;\n        if (OpenLayers.BROWSER_NAME == \"msie\") {\n            this.contentSize.w += \n                contentDivPadding.left + contentDivPadding.right;\n            this.contentSize.h += \n                contentDivPadding.bottom + contentDivPadding.top;\n        }\n\n        if (this.div != null) {\n            this.div.style.width = this.size.w + \"px\";\n            this.div.style.height = this.size.h + \"px\";\n        }\n        if (this.contentDiv != null){\n            this.contentDiv.style.width = contentSize.w + \"px\";\n            this.contentDiv.style.height = contentSize.h + \"px\";\n        }\n    },  \n\n        updateSize: function() {\n        var preparedHTML = \"<div class='\" + this.contentDisplayClass+ \"'>\" + \n            this.contentDiv.innerHTML + \n            \"</div>\";\n \n        var containerElement = (this.map) ? this.map.div : document.body;\n        var realSize = OpenLayers.Util.getRenderedDimensions(\n            preparedHTML, null, {\n                displayClass: this.displayClass,\n                containerElement: containerElement\n            }\n        );\n        var safeSize = this.getSafeContentSize(realSize);\n\n        var newSize = null;\n        if (safeSize.equals(realSize)) {\n            newSize = realSize;\n\n        } else {\n            var fixedSize = {\n                w: (safeSize.w < realSize.w) ? safeSize.w : null,\n                h: (safeSize.h < realSize.h) ? safeSize.h : null\n            };\n        \n            if (fixedSize.w && fixedSize.h) {\n                newSize = safeSize;\n            } else {\n                var clippedSize = OpenLayers.Util.getRenderedDimensions(\n                    preparedHTML, fixedSize, {\n                        displayClass: this.contentDisplayClass,\n                        containerElement: containerElement\n                    }\n                );\n                var currentOverflow = OpenLayers.Element.getStyle(\n                    this.contentDiv, \"overflow\"\n                );\n                if ( (currentOverflow != \"hidden\") && \n                     (clippedSize.equals(safeSize)) ) {\n                    var scrollBar = OpenLayers.Util.getScrollbarWidth();\n                    if (fixedSize.w) {\n                        clippedSize.h += scrollBar;\n                    } else {\n                        clippedSize.w += scrollBar;\n                    }\n                }\n                \n                newSize = this.getSafeContentSize(clippedSize);\n            }\n        }                        \n        this.setSize(newSize);     \n    },    \n\n        setBackgroundColor:function(color) { \n        if (color != undefined) {\n            this.backgroundColor = color; \n        }\n        \n        if (this.div != null) {\n            this.div.style.backgroundColor = this.backgroundColor;\n        }\n    },  \n    \n        setOpacity:function(opacity) { \n        if (opacity != undefined) {\n            this.opacity = opacity; \n        }\n        \n        if (this.div != null) {\n            this.div.style.opacity = this.opacity;\n            this.div.style.filter = 'alpha(opacity=' + this.opacity*100 + ')';\n        }\n    },  \n    \n        setBorder:function(border) { \n        if (border != undefined) {\n            this.border = border;\n        }\n        \n        if (this.div != null) {\n            this.div.style.border = this.border;\n        }\n    },      \n    \n        setContentHTML:function(contentHTML) {\n\n        if (contentHTML != null) {\n            this.contentHTML = contentHTML;\n        }\n       \n        if ((this.contentDiv != null) && \n            (this.contentHTML != null) &&\n            (this.contentHTML != this.contentDiv.innerHTML)) {\n       \n            this.contentDiv.innerHTML = this.contentHTML;\n       \n            if (this.autoSize) {\n                this.registerImageListeners();\n                this.updateSize();\n            }\n        }    \n\n    },\n    \n        getSafeContentSize: function(size) {\n\n        var safeContentSize = size.clone();\n        var contentDivPadding = this.getContentDivPadding();\n        var wPadding = contentDivPadding.left + contentDivPadding.right;\n        var hPadding = contentDivPadding.top + contentDivPadding.bottom;\n        this.fixPadding();\n        wPadding += this.padding.left + this.padding.right;\n        hPadding += this.padding.top + this.padding.bottom;\n\n        if (this.closeDiv) {\n            var closeDivWidth = parseInt(this.closeDiv.style.width);\n            wPadding += closeDivWidth + contentDivPadding.right;\n        }\n        if (this.minSize) {\n            safeContentSize.w = Math.max(safeContentSize.w, \n                (this.minSize.w - wPadding));\n            safeContentSize.h = Math.max(safeContentSize.h, \n                (this.minSize.h - hPadding));\n        }\n        if (this.maxSize) {\n            safeContentSize.w = Math.min(safeContentSize.w, \n                (this.maxSize.w - wPadding));\n            safeContentSize.h = Math.min(safeContentSize.h, \n                (this.maxSize.h - hPadding));\n        }\n        if (this.map && this.map.size) {\n            \n            var extraX = 0, extraY = 0;\n            if (this.keepInMap && !this.panMapIfOutOfView) {\n                var px = this.map.getPixelFromLonLat(this.lonlat);\n                switch (this.relativePosition) {\n                    case \"tr\":\n                        extraX = px.x;\n                        extraY = this.map.size.h - px.y;\n                        break;\n                    case \"tl\":\n                        extraX = this.map.size.w - px.x;\n                        extraY = this.map.size.h - px.y;\n                        break;\n                    case \"bl\":\n                        extraX = this.map.size.w - px.x;\n                        extraY = px.y;\n                        break;\n                    case \"br\":\n                        extraX = px.x;\n                        extraY = px.y;\n                        break;\n                    default:    \n                        extraX = px.x;\n                        extraY = this.map.size.h - px.y;\n                        break;\n                }\n            }    \n          \n            var maxY = this.map.size.h - \n                this.map.paddingForPopups.top - \n                this.map.paddingForPopups.bottom - \n                hPadding - extraY;\n            \n            var maxX = this.map.size.w - \n                this.map.paddingForPopups.left - \n                this.map.paddingForPopups.right - \n                wPadding - extraX;\n            \n            safeContentSize.w = Math.min(safeContentSize.w, maxX);\n            safeContentSize.h = Math.min(safeContentSize.h, maxY);\n        }\n        \n        return safeContentSize;\n    },\n    \n        getContentDivPadding: function() {\n        var contentDivPadding = this._contentDivPadding;\n        if (!contentDivPadding) {\n\n            if (this.div.parentNode == null) {\n                this.div.style.display = \"none\";\n                document.body.appendChild(this.div);\n            }\n            contentDivPadding = new OpenLayers.Bounds(\n                OpenLayers.Element.getStyle(this.contentDiv, \"padding-left\"),\n                OpenLayers.Element.getStyle(this.contentDiv, \"padding-bottom\"),\n                OpenLayers.Element.getStyle(this.contentDiv, \"padding-right\"),\n                OpenLayers.Element.getStyle(this.contentDiv, \"padding-top\")\n            );\n            this._contentDivPadding = contentDivPadding;\n\n            if (this.div.parentNode == document.body) {\n                document.body.removeChild(this.div);\n                this.div.style.display = \"\";\n            }\n        }\n        return contentDivPadding;\n    },\n\n        addCloseBox: function(callback) {\n\n        this.closeDiv = OpenLayers.Util.createDiv(\n            this.id + \"_close\", null, {w: 17, h: 17}\n        );\n        this.closeDiv.className = \"olPopupCloseBox\"; \n        var contentDivPadding = this.getContentDivPadding();\n         \n        this.closeDiv.style.right = contentDivPadding.right + \"px\";\n        this.closeDiv.style.top = contentDivPadding.top + \"px\";\n        this.groupDiv.appendChild(this.closeDiv);\n\n        var closePopup = callback || function(e) {\n            this.hide();\n            OpenLayers.Event.stop(e);\n        };\n        OpenLayers.Event.observe(this.closeDiv, \"touchend\", \n                OpenLayers.Function.bindAsEventListener(closePopup, this));\n        OpenLayers.Event.observe(this.closeDiv, \"click\", \n                OpenLayers.Function.bindAsEventListener(closePopup, this));\n    },\n\n        panIntoView: function() {\n        \n        var mapSize = this.map.getSize();\n        var origTL = this.map.getViewPortPxFromLayerPx( new OpenLayers.Pixel(\n            parseInt(this.div.style.left),\n            parseInt(this.div.style.top)\n        ));\n        var newTL = origTL.clone();\n        if (origTL.x < this.map.paddingForPopups.left) {\n            newTL.x = this.map.paddingForPopups.left;\n        } else \n        if ( (origTL.x + this.size.w) > (mapSize.w - this.map.paddingForPopups.right)) {\n            newTL.x = mapSize.w - this.map.paddingForPopups.right - this.size.w;\n        }\n        if (origTL.y < this.map.paddingForPopups.top) {\n            newTL.y = this.map.paddingForPopups.top;\n        } else \n        if ( (origTL.y + this.size.h) > (mapSize.h - this.map.paddingForPopups.bottom)) {\n            newTL.y = mapSize.h - this.map.paddingForPopups.bottom - this.size.h;\n        }\n        \n        var dx = origTL.x - newTL.x;\n        var dy = origTL.y - newTL.y;\n        \n        this.map.pan(dx, dy);\n    },\n\n         registerEvents:function() {\n        this.events = new OpenLayers.Events(this, this.div, null, true);\n\n        function onTouchstart(evt) {\n            OpenLayers.Event.stop(evt, true);\n        }\n        this.events.on({\n            \"mousedown\": this.onmousedown,\n            \"mousemove\": this.onmousemove,\n            \"mouseup\": this.onmouseup,\n            \"click\": this.onclick,\n            \"mouseout\": this.onmouseout,\n            \"dblclick\": this.ondblclick,\n            \"touchstart\": onTouchstart,\n            scope: this\n        });\n        \n     },\n\n        onmousedown: function (evt) {\n        this.mousedown = true;\n        OpenLayers.Event.stop(evt, true);\n    },\n\n        onmousemove: function (evt) {\n        if (this.mousedown) {\n            OpenLayers.Event.stop(evt, true);\n        }\n    },\n\n        onmouseup: function (evt) {\n        if (this.mousedown) {\n            this.mousedown = false;\n            OpenLayers.Event.stop(evt, true);\n        }\n    },\n\n        onclick: function (evt) {\n        OpenLayers.Event.stop(evt, true);\n    },\n\n        onmouseout: function (evt) {\n        this.mousedown = false;\n    },\n    \n        ondblclick: function (evt) {\n        OpenLayers.Event.stop(evt, true);\n    },\n\n    CLASS_NAME: \"OpenLayers.Popup\"\n});\n\nOpenLayers.Popup.WIDTH = 200;\nOpenLayers.Popup.HEIGHT = 200;\nOpenLayers.Popup.COLOR = \"white\";\nOpenLayers.Popup.OPACITY = 1;\nOpenLayers.Popup.BORDER = \"0px\";\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Projection.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Projection = OpenLayers.Class({\n\n        proj: null,\n    \n        projCode: null,\n    \n        titleRegEx: /\\+title=[^\\+]*/,\n\n        initialize: function(projCode, options) {\n        OpenLayers.Util.extend(this, options);\n        this.projCode = projCode;\n        if (typeof Proj4js == \"object\") {\n            this.proj = new Proj4js.Proj(projCode);\n        }\n    },\n    \n        getCode: function() {\n        return this.proj ? this.proj.srsCode : this.projCode;\n    },\n   \n        getUnits: function() {\n        return this.proj ? this.proj.units : null;\n    },\n\n        toString: function() {\n        return this.getCode();\n    },\n\n        equals: function(projection) {\n        var p = projection, equals = false;\n        if (p) {\n            if (!(p instanceof OpenLayers.Projection)) {\n                p = new OpenLayers.Projection(p);\n            }\n            if ((typeof Proj4js == \"object\") && this.proj.defData && p.proj.defData) {\n                equals = this.proj.defData.replace(this.titleRegEx, \"\") ==\n                    p.proj.defData.replace(this.titleRegEx, \"\");\n            } else if (p.getCode) {\n                var source = this.getCode(), target = p.getCode();\n                equals = source == target ||\n                    !!OpenLayers.Projection.transforms[source] &&\n                    OpenLayers.Projection.transforms[source][target] ===\n                        OpenLayers.Projection.nullTransform;\n            }\n        }\n        return equals;   \n    },\n\n    /* Method: destroy\n     * Destroy projection object.\n     */\n    destroy: function() {\n        delete this.proj;\n        delete this.projCode;\n    },\n    \n    CLASS_NAME: \"OpenLayers.Projection\" \n});     \n\nOpenLayers.Projection.transforms = {};\n\nOpenLayers.Projection.defaults = {\n    \"EPSG:4326\": {\n        units: \"degrees\",\n        maxExtent: [-180, -90, 180, 90],\n        worldExtent: [-180, -90, 180, 90],\n        yx: true\n    },\n    \"CRS:84\": {\n        units: \"degrees\",\n        maxExtent: [-180, -90, 180, 90],\n        worldExtent: [-180, -90, 180, 90]\n    },\n    \"EPSG:900913\": {\n        units: \"m\",\n        maxExtent: [-20037508.34, -20037508.34, 20037508.34, 20037508.34],\n        worldExtent: [-180, -89, 180, 89]\n    }\n};\n\nOpenLayers.Projection.addTransform = function(from, to, method) {\n    if (method === OpenLayers.Projection.nullTransform) {\n        var defaults = OpenLayers.Projection.defaults[from];\n        if (defaults && !OpenLayers.Projection.defaults[to]) {\n            OpenLayers.Projection.defaults[to] = defaults;\n        }\n    }\n    if(!OpenLayers.Projection.transforms[from]) {\n        OpenLayers.Projection.transforms[from] = {};\n    }\n    OpenLayers.Projection.transforms[from][to] = method;\n};\n\nOpenLayers.Projection.transform = function(point, source, dest) {\n    if (source && dest) {\n        if (!(source instanceof OpenLayers.Projection)) {\n            source = new OpenLayers.Projection(source);\n        }\n        if (!(dest instanceof OpenLayers.Projection)) {\n            dest = new OpenLayers.Projection(dest);\n        }\n        if (source.proj && dest.proj) {\n            point = Proj4js.transform(source.proj, dest.proj, point);\n        } else {\n            var sourceCode = source.getCode();\n            var destCode = dest.getCode();\n            var transforms = OpenLayers.Projection.transforms;\n            if (transforms[sourceCode] && transforms[sourceCode][destCode]) {\n                transforms[sourceCode][destCode](point);\n            }\n        }\n    }\n    return point;\n};\n\nOpenLayers.Projection.nullTransform = function(point) {\n    return point;\n};\n\n(function() {\n\n    var pole = 20037508.34;\n\n    function inverseMercator(xy) {\n        xy.x = 180 * xy.x / pole;\n        xy.y = 180 / Math.PI * (2 * Math.atan(Math.exp((xy.y / pole) * Math.PI)) - Math.PI / 2);\n        return xy;\n    }\n\n    function forwardMercator(xy) {\n        xy.x = xy.x * pole / 180;\n        var y = Math.log(Math.tan((90 + xy.y) * Math.PI / 360)) / Math.PI * pole;\n        xy.y = Math.max(-20037508.34, Math.min(y, 20037508.34));\n        return xy;\n    }\n\n    function map(base, codes) {\n        var add = OpenLayers.Projection.addTransform;\n        var same = OpenLayers.Projection.nullTransform;\n        var i, len, code, other, j;\n        for (i=0, len=codes.length; i<len; ++i) {\n            code = codes[i];\n            add(base, code, forwardMercator);\n            add(code, base, inverseMercator);\n            for (j=i+1; j<len; ++j) {\n                other = codes[j];\n                add(code, other, same);\n                add(other, code, same);\n            }\n        }\n    }\n    var mercator = [\"EPSG:900913\", \"EPSG:3857\", \"EPSG:102113\", \"EPSG:102100\", \"OSGEO:41001\"],\n        geographic = [\"CRS:84\", \"urn:ogc:def:crs:EPSG:6.6:4326\", \"EPSG:4326\"],\n        i;\n    for (i=mercator.length-1; i>=0; --i) {\n        map(mercator[i], geographic);\n    }\n    for (i=geographic.length-1; i>=0; --i) {\n        map(geographic[i], mercator);\n    }\n\n})();\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Protocol/CSW/v2_0_2.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Protocol.CSW.v2_0_2 = OpenLayers.Class(OpenLayers.Protocol, {\n\n        formatOptions: null,\n\n        initialize: function(options) {\n        OpenLayers.Protocol.prototype.initialize.apply(this, [options]);\n        if(!options.format) {\n            this.format = new OpenLayers.Format.CSWGetRecords.v2_0_2(OpenLayers.Util.extend({\n            }, this.formatOptions));\n        }\n    },\n\n        destroy: function() {\n        if(this.options && !this.options.format) {\n            this.format.destroy();\n        }\n        this.format = null;\n        OpenLayers.Protocol.prototype.destroy.apply(this);\n    },\n\n        read: function(options) {\n        options = OpenLayers.Util.extend({}, options);\n        OpenLayers.Util.applyDefaults(options, this.options || {});\n        var response = new OpenLayers.Protocol.Response({requestType: \"read\"});\n\n        var data = this.format.write(options.params || options);\n\n        response.priv = OpenLayers.Request.POST({\n            url: options.url,\n            callback: this.createCallback(this.handleRead, response, options),\n            params: options.params,\n            headers: options.headers,\n            data: data\n        });\n\n        return response;\n    },\n\n        handleRead: function(response, options) {\n        if(options.callback) {\n            var request = response.priv;\n            if(request.status >= 200 && request.status < 300) {\n                response.data = this.parseData(request);\n                response.code = OpenLayers.Protocol.Response.SUCCESS;\n            } else {\n                response.code = OpenLayers.Protocol.Response.FAILURE;\n            }\n            options.callback.call(options.scope, response);\n        }\n    },\n\n        parseData: function(request) {\n        var doc = request.responseXML;\n        if(!doc || !doc.documentElement) {\n            doc = request.responseText;\n        }\n        if(!doc || doc.length <= 0) {\n            return null;\n        }\n        return this.format.read(doc);\n    },\n\n    CLASS_NAME: \"OpenLayers.Protocol.CSW.v2_0_2\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Protocol/CSW.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Protocol.CSW = function(options) {\n    options = OpenLayers.Util.applyDefaults(\n        options, OpenLayers.Protocol.CSW.DEFAULTS\n    );\n    var cls = OpenLayers.Protocol.CSW[\"v\"+options.version.replace(/\\./g, \"_\")];\n    if(!cls) {\n        throw \"Unsupported CSW version: \" + options.version;\n    }\n    return new cls(options);\n};\n\nOpenLayers.Protocol.CSW.DEFAULTS = {\n    \"version\": \"2.0.2\"\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Protocol/HTTP.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Protocol.HTTP = OpenLayers.Class(OpenLayers.Protocol, {\n\n        url: null,\n\n        headers: null,\n\n        params: null,\n    \n        callback: null,\n\n        scope: null,\n\n        readWithPOST: false,\n\n        updateWithPOST: false,\n    \n        deleteWithPOST: false,\n\n        wildcarded: false,\n\n        srsInBBOX: false,\n\n        initialize: function(options) {\n        options = options || {};\n        this.params = {};\n        this.headers = {};\n        OpenLayers.Protocol.prototype.initialize.apply(this, arguments);\n\n        if (!this.filterToParams && OpenLayers.Format.QueryStringFilter) {\n            var format = new OpenLayers.Format.QueryStringFilter({\n                wildcarded: this.wildcarded,\n                srsInBBOX: this.srsInBBOX\n            });\n            this.filterToParams = function(filter, params) {\n                return format.write(filter, params);\n            };\n        }\n    },\n    \n        destroy: function() {\n        this.params = null;\n        this.headers = null;\n        OpenLayers.Protocol.prototype.destroy.apply(this);\n    },\n\n        \n        read: function(options) {\n        OpenLayers.Protocol.prototype.read.apply(this, arguments);\n        options = options || {};\n        options.params = OpenLayers.Util.applyDefaults(\n            options.params, this.options.params);\n        options = OpenLayers.Util.applyDefaults(options, this.options);\n        if (options.filter && this.filterToParams) {\n            options.params = this.filterToParams(\n                options.filter, options.params\n            );\n        }\n        var readWithPOST = (options.readWithPOST !== undefined) ?\n                           options.readWithPOST : this.readWithPOST;\n        var resp = new OpenLayers.Protocol.Response({requestType: \"read\"});\n        if(readWithPOST) {\n            var headers = options.headers || {};\n            headers[\"Content-Type\"] = \"application/x-www-form-urlencoded\";\n            resp.priv = OpenLayers.Request.POST({\n                url: options.url,\n                callback: this.createCallback(this.handleRead, resp, options),\n                data: OpenLayers.Util.getParameterString(options.params),\n                headers: headers\n            });\n        } else {\n            resp.priv = OpenLayers.Request.GET({\n                url: options.url,\n                callback: this.createCallback(this.handleRead, resp, options),\n                params: options.params,\n                headers: options.headers\n            });\n        }\n        return resp;\n    },\n\n        handleRead: function(resp, options) {\n        this.handleResponse(resp, options);\n    },\n\n        create: function(features, options) {\n        options = OpenLayers.Util.applyDefaults(options, this.options);\n\n        var resp = new OpenLayers.Protocol.Response({\n            reqFeatures: features,\n            requestType: \"create\"\n        });\n\n        resp.priv = OpenLayers.Request.POST({\n            url: options.url,\n            callback: this.createCallback(this.handleCreate, resp, options),\n            headers: options.headers,\n            data: this.format.write(features)\n        });\n\n        return resp;\n    },\n\n        handleCreate: function(resp, options) {\n        this.handleResponse(resp, options);\n    },\n\n        update: function(feature, options) {\n        options = options || {};\n        var url = options.url ||\n                  feature.url ||\n                  this.options.url + \"/\" + feature.fid;\n        options = OpenLayers.Util.applyDefaults(options, this.options);\n\n        var resp = new OpenLayers.Protocol.Response({\n            reqFeatures: feature,\n            requestType: \"update\"\n        });\n\n        var method = this.updateWithPOST ? \"POST\" : \"PUT\";\n        resp.priv = OpenLayers.Request[method]({\n            url: url,\n            callback: this.createCallback(this.handleUpdate, resp, options),\n            headers: options.headers,\n            data: this.format.write(feature)\n        });\n\n        return resp;\n    },\n\n        handleUpdate: function(resp, options) {\n        this.handleResponse(resp, options);\n    },\n\n        \"delete\": function(feature, options) {\n        options = options || {};\n        var url = options.url ||\n                  feature.url ||\n                  this.options.url + \"/\" + feature.fid;\n        options = OpenLayers.Util.applyDefaults(options, this.options);\n\n        var resp = new OpenLayers.Protocol.Response({\n            reqFeatures: feature,\n            requestType: \"delete\"\n        });\n\n        var method = this.deleteWithPOST ? \"POST\" : \"DELETE\";\n        var requestOptions = {\n            url: url,\n            callback: this.createCallback(this.handleDelete, resp, options),\n            headers: options.headers\n        };\n        if (this.deleteWithPOST) {\n            requestOptions.data = this.format.write(feature);\n        }\n        resp.priv = OpenLayers.Request[method](requestOptions);\n\n        return resp;\n    },\n\n        handleDelete: function(resp, options) {\n        this.handleResponse(resp, options);\n    },\n\n        handleResponse: function(resp, options) {\n        var request = resp.priv;\n        if(options.callback) {\n            if(request.status >= 200 && request.status < 300) {\n                if(resp.requestType != \"delete\") {\n                    resp.features = this.parseFeatures(request);\n                }\n                resp.code = OpenLayers.Protocol.Response.SUCCESS;\n            } else {\n                resp.code = OpenLayers.Protocol.Response.FAILURE;\n            }\n            options.callback.call(options.scope, resp);\n        }\n    },\n\n        parseFeatures: function(request) {\n        var doc = request.responseXML;\n        if (!doc || !doc.documentElement) {\n            doc = request.responseText;\n        }\n        if (!doc || doc.length <= 0) {\n            return null;\n        }\n        return this.format.read(doc);\n    },\n\n        commit: function(features, options) {\n        options = OpenLayers.Util.applyDefaults(options, this.options);\n        var resp = [], nResponses = 0;\n        var types = {};\n        types[OpenLayers.State.INSERT] = [];\n        types[OpenLayers.State.UPDATE] = [];\n        types[OpenLayers.State.DELETE] = [];\n        var feature, list, requestFeatures = [];\n        for(var i=0, len=features.length; i<len; ++i) {\n            feature = features[i];\n            list = types[feature.state];\n            if(list) {\n                list.push(feature);\n                requestFeatures.push(feature); \n            }\n        }\n        var nRequests = (types[OpenLayers.State.INSERT].length > 0 ? 1 : 0) +\n            types[OpenLayers.State.UPDATE].length +\n            types[OpenLayers.State.DELETE].length;\n        var success = true;\n        var finalResponse = new OpenLayers.Protocol.Response({\n            reqFeatures: requestFeatures        \n        });\n        \n        function insertCallback(response) {\n            var len = response.features ? response.features.length : 0;\n            var fids = new Array(len);\n            for(var i=0; i<len; ++i) {\n                fids[i] = response.features[i].fid;\n            }   \n            finalResponse.insertIds = fids;\n            callback.apply(this, [response]);\n        }\n \n        function callback(response) {\n            this.callUserCallback(response, options);\n            success = success && response.success();\n            nResponses++;\n            if (nResponses >= nRequests) {\n                if (options.callback) {\n                    finalResponse.code = success ? \n                        OpenLayers.Protocol.Response.SUCCESS :\n                        OpenLayers.Protocol.Response.FAILURE;\n                    options.callback.apply(options.scope, [finalResponse]);\n                }    \n            }\n        }\n        var queue = types[OpenLayers.State.INSERT];\n        if(queue.length > 0) {\n            resp.push(this.create(\n                queue, OpenLayers.Util.applyDefaults(\n                    {callback: insertCallback, scope: this}, options.create\n                )\n            ));\n        }\n        queue = types[OpenLayers.State.UPDATE];\n        for(var i=queue.length-1; i>=0; --i) {\n            resp.push(this.update(\n                queue[i], OpenLayers.Util.applyDefaults(\n                    {callback: callback, scope: this}, options.update\n                ))\n            );\n        }\n        queue = types[OpenLayers.State.DELETE];\n        for(var i=queue.length-1; i>=0; --i) {\n            resp.push(this[\"delete\"](\n                queue[i], OpenLayers.Util.applyDefaults(\n                    {callback: callback, scope: this}, options[\"delete\"]\n                ))\n            );\n        }\n        return resp;\n    },\n\n        abort: function(response) {\n        if (response) {\n            response.priv.abort();\n        }\n    },\n\n        callUserCallback: function(resp, options) {\n        var opt = options[resp.requestType];\n        if(opt && opt.callback) {\n            opt.callback.call(opt.scope, resp);\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Protocol.HTTP\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Protocol/SOS/v1_0_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n OpenLayers.Protocol.SOS.v1_0_0 = OpenLayers.Class(OpenLayers.Protocol, {\n\n        fois: null,\n\n        formatOptions: null,\n   \n        initialize: function(options) {\n        OpenLayers.Protocol.prototype.initialize.apply(this, [options]);\n        if(!options.format) {\n            this.format = new OpenLayers.Format.SOSGetFeatureOfInterest(\n                this.formatOptions);\n        }\n    },\n   \n        destroy: function() {\n        if(this.options && !this.options.format) {\n            this.format.destroy();\n        }\n        this.format = null;\n        OpenLayers.Protocol.prototype.destroy.apply(this);\n    },\n\n        read: function(options) {\n        options = OpenLayers.Util.extend({}, options);\n        OpenLayers.Util.applyDefaults(options, this.options || {});\n        var response = new OpenLayers.Protocol.Response({requestType: \"read\"});\n        var format = this.format;\n        var data = OpenLayers.Format.XML.prototype.write.apply(format,\n            [format.writeNode(\"sos:GetFeatureOfInterest\", {fois: this.fois})]\n        );\n        response.priv = OpenLayers.Request.POST({\n            url: options.url,\n            callback: this.createCallback(this.handleRead, response, options),\n            data: data\n        });\n        return response;\n    },\n   \n        handleRead: function(response, options) {\n        if(options.callback) {\n            var request = response.priv;\n            if(request.status >= 200 && request.status < 300) {\n                response.features = this.parseFeatures(request);\n                response.code = OpenLayers.Protocol.Response.SUCCESS;\n            } else {\n                response.code = OpenLayers.Protocol.Response.FAILURE;\n            }\n            options.callback.call(options.scope, response);\n        }\n    },\n\n        parseFeatures: function(request) {\n        var doc = request.responseXML;\n        if(!doc || !doc.documentElement) {\n            doc = request.responseText;\n        }\n        if(!doc || doc.length <= 0) {\n            return null;\n        }\n        return this.format.read(doc);\n    },\n\n    CLASS_NAME: \"OpenLayers.Protocol.SOS.v1_0_0\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Protocol/SOS.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Protocol.SOS = function(options) {\n    options = OpenLayers.Util.applyDefaults(\n        options, OpenLayers.Protocol.SOS.DEFAULTS\n    );\n    var cls = OpenLayers.Protocol.SOS[\"v\"+options.version.replace(/\\./g, \"_\")];\n    if(!cls) {\n        throw \"Unsupported SOS version: \" + options.version;\n    }\n    return new cls(options);\n};\n\nOpenLayers.Protocol.SOS.DEFAULTS = {\n    \"version\": \"1.0.0\"\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Protocol/Script.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Protocol.Script = OpenLayers.Class(OpenLayers.Protocol, {\n\n        url: null,\n\n        params: null,\n    \n        callback: null,\n\n        callbackTemplate: \"OpenLayers.Protocol.Script.registry.${id}\",\n\n        callbackKey: \"callback\",\n\n        callbackPrefix: \"\",\n\n        scope: null,\n\n        format: null,\n\n        pendingRequests: null,\n\n        srsInBBOX: false,\n\n        initialize: function(options) {\n        options = options || {};\n        this.params = {};\n        this.pendingRequests = {};\n        OpenLayers.Protocol.prototype.initialize.apply(this, arguments);\n        if (!this.format) {\n            this.format = new OpenLayers.Format.GeoJSON();\n        }\n\n        if (!this.filterToParams && OpenLayers.Format.QueryStringFilter) {\n            var format = new OpenLayers.Format.QueryStringFilter({\n                srsInBBOX: this.srsInBBOX\n            });\n            this.filterToParams = function(filter, params) {\n                return format.write(filter, params);\n            };\n        }\n    },\n    \n        read: function(options) {\n        OpenLayers.Protocol.prototype.read.apply(this, arguments);\n        options = OpenLayers.Util.applyDefaults(options, this.options);\n        options.params = OpenLayers.Util.applyDefaults(\n            options.params, this.options.params\n        );\n        if (options.filter && this.filterToParams) {\n            options.params = this.filterToParams(\n                options.filter, options.params\n            );\n        }\n        var response = new OpenLayers.Protocol.Response({requestType: \"read\"});\n        var request = this.createRequest(\n            options.url, \n            options.params, \n            OpenLayers.Function.bind(function(data) {\n                response.data = data;\n                this.handleRead(response, options);\n            }, this)\n        );\n        response.priv = request;\n        return response;\n    },\n\n    \n        createRequest: function(url, params, callback) {\n        var id = OpenLayers.Protocol.Script.register(callback);\n        var name = OpenLayers.String.format(this.callbackTemplate, {id: id});\n        params = OpenLayers.Util.extend({}, params);\n        params[this.callbackKey] = this.callbackPrefix + name;\n        url = OpenLayers.Util.urlAppend(\n            url, OpenLayers.Util.getParameterString(params)\n        );\n        var script = document.createElement(\"script\");\n        script.type = \"text/javascript\";\n        script.src = url;\n        script.id = \"OpenLayers_Protocol_Script_\" + id;\n        this.pendingRequests[script.id] = script;\n        var head = document.getElementsByTagName(\"head\")[0];\n        head.appendChild(script);\n        return script;\n    },\n    \n        destroyRequest: function(script) {\n        OpenLayers.Protocol.Script.unregister(script.id.split(\"_\").pop());\n        delete this.pendingRequests[script.id];\n        if (script.parentNode) {\n            script.parentNode.removeChild(script);\n        }\n    },\n\n        handleRead: function(response, options) {\n        this.handleResponse(response, options);\n    },\n\n        handleResponse: function(response, options) {\n        if (options.callback) {\n            if (response.data) {\n                response.features = this.parseFeatures(response.data);\n                response.code = OpenLayers.Protocol.Response.SUCCESS;\n            } else {\n                response.code = OpenLayers.Protocol.Response.FAILURE;\n            }\n            this.destroyRequest(response.priv);\n            options.callback.call(options.scope, response);\n        }\n    },\n\n        parseFeatures: function(data) {\n        return this.format.read(data);\n    },\n\n        abort: function(response) {\n        if (response) {\n            this.destroyRequest(response.priv);\n        } else {\n            for (var key in this.pendingRequests) {\n                this.destroyRequest(this.pendingRequests[key]);\n            }\n        }\n    },\n    \n        destroy: function() {\n        this.abort();\n        delete this.params;\n        delete this.format;\n        OpenLayers.Protocol.prototype.destroy.apply(this);\n    },\n\n    CLASS_NAME: \"OpenLayers.Protocol.Script\" \n});\n\n(function() {\n    var o = OpenLayers.Protocol.Script;\n    var counter = 0;\n    o.registry = {};\n    \n        o.register = function(callback) {\n        var id = \"c\"+(++counter);\n        o.registry[id] = function() {\n            callback.apply(this, arguments);\n        };\n        return id;\n    };\n    \n        o.unregister = function(id) {\n        delete o.registry[id];\n    };\n})();\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Protocol/WFS/v1.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Protocol.WFS.v1 = OpenLayers.Class(OpenLayers.Protocol, {\n    \n        version: null,\n    \n        srsName: \"EPSG:4326\",\n    \n        featureType: null,\n    \n        featureNS: null,\n    \n        geometryName: \"the_geom\",\n\n        \n        schema: null,\n\n        featurePrefix: \"feature\",\n    \n        formatOptions: null,\n\n        readOptions: null,\n    \n        initialize: function(options) {\n        OpenLayers.Protocol.prototype.initialize.apply(this, [options]);\n        if(!options.format) {\n            this.format = OpenLayers.Format.WFST(OpenLayers.Util.extend({\n                version: this.version,\n                featureType: this.featureType,\n                featureNS: this.featureNS,\n                featurePrefix: this.featurePrefix,\n                geometryName: this.geometryName,\n                srsName: this.srsName,\n                schema: this.schema\n            }, this.formatOptions));\n        }\n        if (!options.geometryName && parseFloat(this.format.version) > 1.0) {\n            this.setGeometryName(null);\n        }\n    },\n    \n        destroy: function() {\n        if(this.options && !this.options.format) {\n            this.format.destroy();\n        }\n        this.format = null;\n        OpenLayers.Protocol.prototype.destroy.apply(this);\n    },\n\n        read: function(options) {\n        OpenLayers.Protocol.prototype.read.apply(this, arguments);\n        options = OpenLayers.Util.extend({}, options);\n        OpenLayers.Util.applyDefaults(options, this.options || {});\n        var response = new OpenLayers.Protocol.Response({requestType: \"read\"});\n        \n        var data = OpenLayers.Format.XML.prototype.write.apply(\n            this.format, [this.format.writeNode(\"wfs:GetFeature\", options)]\n        );\n\n        response.priv = OpenLayers.Request.POST({\n            url: options.url,\n            callback: this.createCallback(this.handleRead, response, options),\n            params: options.params,\n            headers: options.headers,\n            data: data\n        });\n\n        return response;\n    },\n\n        setFeatureType: function(featureType) {\n        this.featureType = featureType;\n        this.format.featureType = featureType;\n    },\n \n        setGeometryName: function(geometryName) {\n        this.geometryName = geometryName;\n        this.format.geometryName = geometryName;\n    },\n    \n        handleRead: function(response, options) {\n        options = OpenLayers.Util.extend({}, options);\n        OpenLayers.Util.applyDefaults(options, this.options);\n\n        if(options.callback) {\n            var request = response.priv;\n            if(request.status >= 200 && request.status < 300) {\n                var result = this.parseResponse(request, options.readOptions);\n                if (result && result.success !== false) { \n                    if (options.readOptions && options.readOptions.output == \"object\") {\n                        OpenLayers.Util.extend(response, result);\n                    } else {\n                        response.features = result;\n                    }\n                    response.code = OpenLayers.Protocol.Response.SUCCESS;\n                } else {\n                    response.code = OpenLayers.Protocol.Response.FAILURE;\n                    response.error = result;\n                }\n            } else {\n                response.code = OpenLayers.Protocol.Response.FAILURE;\n            }\n            options.callback.call(options.scope, response);\n        }\n    },\n\n        parseResponse: function(request, options) {\n        var doc = request.responseXML;\n        if(!doc || !doc.documentElement) {\n            doc = request.responseText;\n        }\n        if(!doc || doc.length <= 0) {\n            return null;\n        }\n        var result = (this.readFormat !== null) ? this.readFormat.read(doc) : \n            this.format.read(doc, options);\n        if (!this.featureNS) {\n            var format = this.readFormat || this.format;\n            this.featureNS = format.featureNS;\n            format.autoConfig = false;\n            if (!this.geometryName) {\n                this.setGeometryName(format.geometryName);\n            }\n        }\n        return result;\n    },\n\n        commit: function(features, options) {\n\n        options = OpenLayers.Util.extend({}, options);\n        OpenLayers.Util.applyDefaults(options, this.options);\n        \n        var response = new OpenLayers.Protocol.Response({\n            requestType: \"commit\",\n            reqFeatures: features\n        });\n        response.priv = OpenLayers.Request.POST({\n            url: options.url,\n            headers: options.headers,\n            data: this.format.write(features, options),\n            callback: this.createCallback(this.handleCommit, response, options)\n        });\n        \n        return response;\n    },\n    \n        handleCommit: function(response, options) {\n        if(options.callback) {\n            var request = response.priv;\n            var data = request.responseXML;\n            if(!data || !data.documentElement) {\n                data = request.responseText;\n            }\n            \n            var obj = this.format.read(data) || {};\n            \n            response.insertIds = obj.insertIds || [];\n            if (obj.success) {\n                response.code = OpenLayers.Protocol.Response.SUCCESS;\n            } else {\n                response.code = OpenLayers.Protocol.Response.FAILURE;\n                response.error = obj;\n            }\n            options.callback.call(options.scope, response);\n        }\n    },\n    \n        filterDelete: function(filter, options) {\n        options = OpenLayers.Util.extend({}, options);\n        OpenLayers.Util.applyDefaults(options, this.options);    \n        \n        var response = new OpenLayers.Protocol.Response({\n            requestType: \"commit\"\n        });    \n        \n        var root = this.format.createElementNSPlus(\"wfs:Transaction\", {\n            attributes: {\n                service: \"WFS\",\n                version: this.version\n            }\n        });\n        \n        var deleteNode = this.format.createElementNSPlus(\"wfs:Delete\", {\n            attributes: {\n                typeName: (options.featureNS ? this.featurePrefix + \":\" : \"\") +\n                    options.featureType\n            }\n        });       \n        \n        if(options.featureNS) {\n            deleteNode.setAttribute(\"xmlns:\" + this.featurePrefix, options.featureNS);\n        }\n        var filterNode = this.format.writeNode(\"ogc:Filter\", filter);\n        \n        deleteNode.appendChild(filterNode);\n        \n        root.appendChild(deleteNode);\n        \n        var data = OpenLayers.Format.XML.prototype.write.apply(\n            this.format, [root]\n        );\n        \n        return OpenLayers.Request.POST({\n            url: this.url,\n            callback : options.callback || function(){},\n            data: data\n        });   \n        \n    },\n\n        abort: function(response) {\n        if (response) {\n            response.priv.abort();\n        }\n    },\n  \n    CLASS_NAME: \"OpenLayers.Protocol.WFS.v1\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Protocol/WFS/v1_0_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Protocol.WFS.v1_0_0 = OpenLayers.Class(OpenLayers.Protocol.WFS.v1, {\n    \n        version: \"1.0.0\",\n    \n       \n    CLASS_NAME: \"OpenLayers.Protocol.WFS.v1_0_0\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Protocol/WFS/v1_1_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Protocol.WFS.v1_1_0 = OpenLayers.Class(OpenLayers.Protocol.WFS.v1, {\n    \n        version: \"1.1.0\",\n    \n        initialize: function(options) {\n        OpenLayers.Protocol.WFS.v1.prototype.initialize.apply(this, arguments);\n        if (this.outputFormat && !this.readFormat) {\n            if (this.outputFormat.toLowerCase() == \"gml2\") {\n                this.readFormat = new OpenLayers.Format.GML.v2({\n                    featureType: this.featureType,\n                    featureNS: this.featureNS,\n                    geometryName: this.geometryName\n                });\n            } else if (this.outputFormat.toLowerCase() == \"json\") {\n                this.readFormat = new OpenLayers.Format.GeoJSON();\n            }\n        }\n    },\n   \n    CLASS_NAME: \"OpenLayers.Protocol.WFS.v1_1_0\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Protocol/WFS/v2_0_0.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Protocol.WFS.v2_0_0 = OpenLayers.Class(OpenLayers.Protocol.WFS.v1, {\n    \n        version: \"2.0.0\",\n    \n        initialize: function(options) {\n        OpenLayers.Protocol.WFS.v1.prototype.initialize.apply(this, arguments);\n        if (this.outputFormat && !this.readFormat) {\n            if (this.outputFormat.toLowerCase() == \"gml3\") {\n                this.readFormat = new OpenLayers.Format.GML.v3({\n                    featureType: this.featureType,\n                    featureNS: this.featureNS,\n                    geometryName: this.geometryName\n                });\n            } else if (this.outputFormat.toLowerCase() == \"json\") {\n                this.readFormat = new OpenLayers.Format.GeoJSON();\n            }\n        }\n    },\n   \n    CLASS_NAME: \"OpenLayers.Protocol.WFS.v2_0_0\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Protocol/WFS.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Protocol.WFS = function(options) {\n    options = OpenLayers.Util.applyDefaults(\n        options, OpenLayers.Protocol.WFS.DEFAULTS\n    );\n    var cls = OpenLayers.Protocol.WFS[\"v\"+options.version.replace(/\\./g, \"_\")];\n    if(!cls) {\n        throw \"Unsupported WFS version: \" + options.version;\n    }\n    return new cls(options);\n};\n\nOpenLayers.Protocol.WFS.fromWMSLayer = function(layer, options) {\n    var typeName, featurePrefix;\n    var param = layer.params[\"LAYERS\"];\n    var parts = (OpenLayers.Util.isArray(param) ? param[0] : param).split(\":\");\n    if(parts.length > 1) {\n        featurePrefix = parts[0];\n    }\n    typeName = parts.pop();\n    var protocolOptions = {\n        url: layer.url,\n        featureType: typeName,\n        featurePrefix: featurePrefix,\n        srsName: layer.projection && layer.projection.getCode() ||\n                 layer.map && layer.map.getProjectionObject().getCode(),\n        version: \"1.1.0\"\n    };\n    return new OpenLayers.Protocol.WFS(OpenLayers.Util.applyDefaults(\n        options, protocolOptions\n    ));\n};\n\nOpenLayers.Protocol.WFS.DEFAULTS = {\n    \"version\": \"1.0.0\"\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Protocol.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Protocol = OpenLayers.Class({\n    \n        format: null,\n    \n        options: null,\n\n        autoDestroy: true,\n   \n        defaultFilter: null,\n    \n        initialize: function(options) {\n        options = options || {};\n        OpenLayers.Util.extend(this, options);\n        this.options = options;\n    },\n\n        mergeWithDefaultFilter: function(filter) {\n        var merged;\n        if (filter && this.defaultFilter) {\n            merged = new OpenLayers.Filter.Logical({\n                type: OpenLayers.Filter.Logical.AND,\n                filters: [this.defaultFilter, filter]\n            });\n        } else {\n            merged = filter || this.defaultFilter || undefined;\n        }\n        return merged;\n    },\n\n        destroy: function() {\n        this.options = null;\n        this.format = null;\n    },\n    \n        read: function(options) {\n        options = options || {};\n        options.filter = this.mergeWithDefaultFilter(options.filter);\n    },\n    \n    \n        create: function() {\n    },\n    \n        update: function() {\n    },\n    \n        \"delete\": function() {\n    },\n\n        commit: function() {\n    },\n\n        abort: function(response) {\n    },\n   \n        createCallback: function(method, response, options) {\n        return OpenLayers.Function.bind(function() {\n            method.apply(this, [response, options]);\n        }, this);\n    },\n   \n    CLASS_NAME: \"OpenLayers.Protocol\" \n});\n\nOpenLayers.Protocol.Response = OpenLayers.Class({\n        code: null,\n\n        requestType: null,\n\n        last: true,\n\n        features: null,\n\n        data: null,\n\n        reqFeatures: null,\n\n        priv: null,\n\n        error: null,\n\n        initialize: function(options) {\n        OpenLayers.Util.extend(this, options);\n    },\n\n        success: function() {\n        return this.code > 0;\n    },\n\n    CLASS_NAME: \"OpenLayers.Protocol.Response\"\n});\n\nOpenLayers.Protocol.Response.SUCCESS = 1;\nOpenLayers.Protocol.Response.FAILURE = 0;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Renderer/Canvas.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Renderer.Canvas = OpenLayers.Class(OpenLayers.Renderer, {\n    \n        hitDetection: true,\n    \n        hitOverflow: 0,\n\n        canvas: null, \n    \n        features: null,\n    \n        pendingRedraw: false,\n    \n        cachedSymbolBounds: {},\n    \n        initialize: function(containerID, options) {\n        OpenLayers.Renderer.prototype.initialize.apply(this, arguments);\n        this.root = document.createElement(\"canvas\");\n        this.container.appendChild(this.root);\n        this.canvas = this.root.getContext(\"2d\");\n        this._clearRectId = OpenLayers.Util.createUniqueID();\n        this.features = {};\n        if (this.hitDetection) {\n            this.hitCanvas = document.createElement(\"canvas\");\n            this.hitContext = this.hitCanvas.getContext(\"2d\");\n        }\n    },\n    \n        setExtent: function() {\n        OpenLayers.Renderer.prototype.setExtent.apply(this, arguments);\n        return false;\n    },\n    \n        eraseGeometry: function(geometry, featureId) {\n        this.eraseFeatures(this.features[featureId][0]);\n    },\n\n        supported: function() {\n        return OpenLayers.CANVAS_SUPPORTED;\n    },    \n    \n        setSize: function(size) {\n        this.size = size.clone();\n        var root = this.root;\n        root.style.width = size.w + \"px\";\n        root.style.height = size.h + \"px\";\n        root.width = size.w;\n        root.height = size.h;\n        this.resolution = null;\n        if (this.hitDetection) {\n            var hitCanvas = this.hitCanvas;\n            hitCanvas.style.width = size.w + \"px\";\n            hitCanvas.style.height = size.h + \"px\";\n            hitCanvas.width = size.w;\n            hitCanvas.height = size.h;\n        }\n    },\n    \n        drawFeature: function(feature, style) {\n        var rendered;\n        if (feature.geometry) {\n            style = this.applyDefaultSymbolizer(style || feature.style);\n            var bounds = feature.geometry.getBounds();\n\n            var worldBounds;\n            if (this.map.baseLayer && this.map.baseLayer.wrapDateLine) {\n                worldBounds = this.map.getMaxExtent();\n            }\n\n            var intersects = bounds && bounds.intersectsBounds(this.extent, {worldBounds: worldBounds});\n\n            rendered = (style.display !== \"none\") && !!bounds && intersects;\n            if (rendered) {\n                this.features[feature.id] = [feature, style];\n            }\n            else {\n                delete(this.features[feature.id]);\n            }\n            this.pendingRedraw = true;\n        }\n        if (this.pendingRedraw && !this.locked) {\n            this.redraw();\n            this.pendingRedraw = false;\n        }\n        return rendered;\n    },\n\n        drawGeometry: function(geometry, style, featureId) {\n        var className = geometry.CLASS_NAME;\n        if ((className == \"OpenLayers.Geometry.Collection\") ||\n            (className == \"OpenLayers.Geometry.MultiPoint\") ||\n            (className == \"OpenLayers.Geometry.MultiLineString\") ||\n            (className == \"OpenLayers.Geometry.MultiPolygon\")) {\n            var worldBounds = (this.map.baseLayer && this.map.baseLayer.wrapDateLine) && this.map.getMaxExtent();\n            for (var i = 0; i < geometry.components.length; i++) {\n                this.calculateFeatureDx(geometry.components[i].getBounds(), worldBounds);\n                this.drawGeometry(geometry.components[i], style, featureId);\n            }\n            return;\n        }\n        switch (geometry.CLASS_NAME) {\n            case \"OpenLayers.Geometry.Point\":\n                this.drawPoint(geometry, style, featureId);\n                break;\n            case \"OpenLayers.Geometry.LineString\":\n                this.drawLineString(geometry, style, featureId);\n                break;\n            case \"OpenLayers.Geometry.LinearRing\":\n                this.drawLinearRing(geometry, style, featureId);\n                break;\n            case \"OpenLayers.Geometry.Polygon\":\n                this.drawPolygon(geometry, style, featureId);\n                break;\n            default:\n                break;\n        }\n    },\n\n        setCanvasStyle: function(type, style) {\n        if (type === \"fill\") {     \n            this.canvas.globalAlpha = style['fillOpacity'];\n            this.canvas.fillStyle = style['fillColor'];\n        } else if (type === \"stroke\") {  \n            this.canvas.globalAlpha = style['strokeOpacity'];\n            this.canvas.strokeStyle = style['strokeColor'];\n            this.canvas.lineWidth = style['strokeWidth'];\n        } else {\n            this.canvas.globalAlpha = 0;\n            this.canvas.lineWidth = 1;\n        }\n    },\n    \n        featureIdToHex: function(featureId) {\n        var id = Number(featureId.split(\"_\").pop()) + 1; // zero for no feature\n        if (id >= 16777216) {\n            this.hitOverflow = id - 16777215;\n            id = id % 16777216 + 1;\n        }\n        var hex = \"000000\" + id.toString(16);\n        var len = hex.length;\n        hex = \"#\" + hex.substring(len-6, len);\n        return hex;\n    },\n    \n        setHitContextStyle: function(type, featureId, symbolizer, strokeScaling) {\n        var hex = this.featureIdToHex(featureId);\n        if (type == \"fill\") {\n            this.hitContext.globalAlpha = 1.0;\n            this.hitContext.fillStyle = hex;\n        } else if (type == \"stroke\") {  \n            this.hitContext.globalAlpha = 1.0;\n            this.hitContext.strokeStyle = hex;\n            if (typeof strokeScaling === \"undefined\") {\n                this.hitContext.lineWidth = symbolizer.strokeWidth + 2;\n            } else {\n                if (!isNaN(strokeScaling)) { this.hitContext.lineWidth = symbolizer.strokeWidth + 2.0 / strokeScaling; }\n            }\n        } else {\n            this.hitContext.globalAlpha = 0;\n            this.hitContext.lineWidth = 1;\n        }\n    },\n\n        renderPath: function(context, geometry, style, featureId, type) {\n        var components = geometry.components;\n        var len = components.length;\n        context.beginPath();\n        var start = this.getLocalXY(components[0]);\n        var x = start[0];\n        var y = start[1];\n        if (!isNaN(x) && !isNaN(y)) {\n            context.moveTo(start[0], start[1]);\n            for (var i=1; i<len; ++i) {\n                var pt = this.getLocalXY(components[i]);\n                context.lineTo(pt[0], pt[1]);\n            }\n            if (type === \"fill\") {\n                context.fill();\n            } else {\n                context.stroke();\n            }\n        }\n    },\n    \n                this.canvas.globalCompositeOperation = \"destination-out\";\n            if (this.hitDetection) {\n                this.hitContext.globalCompositeOperation = \"destination-out\";\n            }\n            this.drawLinearRing(\n                components[i], \n                OpenLayers.Util.applyDefaults({stroke: false, fillOpacity: 1.0}, style),\n                featureId\n            );\n            this.canvas.globalCompositeOperation = \"source-over\";\n            if (this.hitDetection) {\n                this.hitContext.globalCompositeOperation = \"source-over\";\n            }\n            this.drawLinearRing(\n                components[i], \n                OpenLayers.Util.applyDefaults({fill: false}, style),\n                featureId\n            );\n        }\n    },\n    \n        drawText: function(location, style) {\n        var pt = this.getLocalXY(location);\n\n        this.setCanvasStyle(\"reset\");\n        this.canvas.fillStyle = style.fontColor;\n        this.canvas.globalAlpha = style.fontOpacity || 1.0;\n        var fontStyle = [style.fontStyle ? style.fontStyle : \"normal\",\n                         \"normal\", // \"font-variant\" not supported\n                         style.fontWeight ? style.fontWeight : \"normal\",\n                         style.fontSize ? style.fontSize : \"1em\",\n                         style.fontFamily ? style.fontFamily : \"sans-serif\"].join(\" \");\n        var labelRows = style.label.split('\\n');\n        var numRows = labelRows.length;\n        if (this.canvas.fillText) {\n            this.canvas.font = fontStyle;\n            this.canvas.textAlign =\n                OpenLayers.Renderer.Canvas.LABEL_ALIGN[style.labelAlign[0]] ||\n                \"center\";\n            this.canvas.textBaseline =\n                OpenLayers.Renderer.Canvas.LABEL_ALIGN[style.labelAlign[1]] ||\n                \"middle\";\n            var vfactor =\n                OpenLayers.Renderer.Canvas.LABEL_FACTOR[style.labelAlign[1]];\n            if (vfactor == null) {\n                vfactor = -.5;\n            }\n            var lineHeight =\n                this.canvas.measureText('Mg').height ||\n                this.canvas.measureText('xx').width;\n            pt[1] += lineHeight*vfactor*(numRows-1);\n            for (var i = 0; i < numRows; i++) {\n                if (style.labelOutlineWidth) {\n                    this.canvas.save();\n                    this.canvas.globalAlpha = style.labelOutlineOpacity || style.fontOpacity || 1.0;\n                    this.canvas.strokeStyle = style.labelOutlineColor;\n                    this.canvas.lineWidth = style.labelOutlineWidth;\n                    this.canvas.strokeText(labelRows[i], pt[0], pt[1] + (lineHeight*i) + 1);\n                    this.canvas.restore();\n                }\n                this.canvas.fillText(labelRows[i], pt[0], pt[1] + (lineHeight*i));\n            }\n        } else if (this.canvas.mozDrawText) {\n            this.canvas.mozTextStyle = fontStyle;\n            var hfactor =\n                OpenLayers.Renderer.Canvas.LABEL_FACTOR[style.labelAlign[0]];\n            if (hfactor == null) {\n                hfactor = -.5;\n            }\n            var vfactor =\n                OpenLayers.Renderer.Canvas.LABEL_FACTOR[style.labelAlign[1]];\n            if (vfactor == null) {\n                vfactor = -.5;\n            }\n            var lineHeight = this.canvas.mozMeasureText('xx');\n            pt[1] += lineHeight*(1 + (vfactor*numRows));\n            for (var i = 0; i < numRows; i++) {\n                var x = pt[0] + (hfactor*this.canvas.mozMeasureText(labelRows[i]));\n                var y = pt[1] + (i*lineHeight);\n                this.canvas.translate(x, y);\n                this.canvas.mozDrawText(labelRows[i]);\n                this.canvas.translate(-x, -y);\n            }\n        }\n        this.setCanvasStyle(\"reset\");\n    },\n    \n        getLocalXY: function(point) {\n        var resolution = this.getResolution();\n        var extent = this.extent;\n        var x = ((point.x - this.featureDx) / resolution + (-extent.left / resolution));\n        var y = ((extent.top / resolution) - point.y / resolution);\n        return [x, y];\n    },\n\n        getFeatureIdFromEvent: function(evt) {\n        var featureId, feature;\n        \n        if (this.hitDetection && this.root.style.display !== \"none\") {\n            if (!this.map.dragging) {\n                var xy = evt.xy;\n                var x = xy.x | 0;\n                var y = xy.y | 0;\n                var data = this.hitContext.getImageData(x, y, 1, 1).data;\n                if (data[3] === 255) { // antialiased\n                    var id = data[2] + (256 * (data[1] + (256 * data[0])));\n                    if (id) {\n                        featureId = \"OpenLayers_Feature_Vector_\" + (id - 1 + this.hitOverflow);\n                        try {\n                            feature = this.features[featureId][0];\n                        } catch(err) {\n                        }\n                    }\n                }\n            }\n        }\n        return feature;\n    },\n    \n        eraseFeatures: function(features) {\n        if(!(OpenLayers.Util.isArray(features))) {\n            features = [features];\n        }\n        for(var i=0; i<features.length; ++i) {\n            delete this.features[features[i].id];\n        }\n        this.redraw();\n    },\n\n        redraw: function() {\n        if (!this.locked) {\n            this.clearCanvas();\n            var labelMap = [];\n            var feature, geometry, style;\n            var worldBounds = (this.map.baseLayer && this.map.baseLayer.wrapDateLine) && this.map.getMaxExtent();\n            for (var id in this.features) {\n                if (!this.features.hasOwnProperty(id)) { continue; }\n                feature = this.features[id][0];\n                geometry = feature.geometry;\n                this.calculateFeatureDx(geometry.getBounds(), worldBounds);\n                style = this.features[id][1];\n                this.drawGeometry(geometry, style, feature.id);\n                if(style.label) {\n                    labelMap.push([feature, style]);\n                }\n            }\n            var item;\n            for (var i=0, len=labelMap.length; i<len; ++i) {\n                item = labelMap[i];\n                this.drawText(item[0].geometry.getCentroid(), item[1]);\n            }\n        }    \n    },\n\n    CLASS_NAME: \"OpenLayers.Renderer.Canvas\"\n});\n\nOpenLayers.Renderer.Canvas.LABEL_ALIGN = {\n    \"l\": \"left\",\n    \"r\": \"right\",\n    \"t\": \"top\",\n    \"b\": \"bottom\"\n};\n\nOpenLayers.Renderer.Canvas.LABEL_FACTOR = {\n    \"l\": 0,\n    \"r\": -1,\n    \"t\": 0,\n    \"b\": -1\n};\n\nOpenLayers.Renderer.Canvas.drawImageScaleFactor = null;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Renderer/Elements.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.ElementsIndexer = OpenLayers.Class({\n   \n        maxZIndex: null,\n    \n        order: null, \n    \n        indices: null,\n    \n        compare: null,\n    \n        initialize: function(yOrdering) {\n\n        this.compare = yOrdering ? \n            OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER_Y_ORDER :\n            OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER_DRAWING_ORDER;\n\n        this.clear();\n    },\n    \n        insert: function(newNode) {\n        if (this.exists(newNode)) {\n            this.remove(newNode);\n        }\n        \n        var nodeId = newNode.id;\n        \n        this.determineZIndex(newNode);       \n\n        var leftIndex = -1;\n        var rightIndex = this.order.length;\n        var middle;\n\n        while (rightIndex - leftIndex > 1) {\n            middle = parseInt((leftIndex + rightIndex) / 2);\n            \n            var placement = this.compare(this, newNode,\n                OpenLayers.Util.getElement(this.order[middle]));\n            \n            if (placement > 0) {\n                leftIndex = middle;\n            } else {\n                rightIndex = middle;\n            } \n        }\n        \n        this.order.splice(rightIndex, 0, nodeId);\n        this.indices[nodeId] = this.getZIndex(newNode);\n        return this.getNextElement(rightIndex);\n    },\n    \n        remove: function(node) {\n        var nodeId = node.id;\n        var arrayIndex = OpenLayers.Util.indexOf(this.order, nodeId);\n        if (arrayIndex >= 0) {\n            this.order.splice(arrayIndex, 1);\n            delete this.indices[nodeId];\n            if (this.order.length > 0) {\n                var lastId = this.order[this.order.length - 1];\n                this.maxZIndex = this.indices[lastId];\n            } else {\n                this.maxZIndex = 0;\n            }\n        }\n    },\n    \n        clear: function() {\n        this.order = [];\n        this.indices = {};\n        this.maxZIndex = 0;\n    },\n    \n        exists: function(node) {\n        return (this.indices[node.id] != null);\n    },\n\n        getZIndex: function(node) {\n        return node._style.graphicZIndex;  \n    },\n    \n        determineZIndex: function(node) {\n        var zIndex = node._style.graphicZIndex;\n        if (zIndex == null) {\n            zIndex = this.maxZIndex;\n            node._style.graphicZIndex = zIndex; \n        } else if (zIndex > this.maxZIndex) {\n            this.maxZIndex = zIndex;\n        }\n    },\n\n        getNextElement: function(index) {\n        for (var nextIndex = index + 1, nextElement = undefined;\n            (nextIndex < this.order.length) && (nextElement == undefined);\n            nextIndex++) {\n            nextElement = OpenLayers.Util.getElement(this.order[nextIndex]);\n        }\n        \n        return nextElement || null;\n    },\n    \n    CLASS_NAME: \"OpenLayers.ElementsIndexer\"\n});\n\nOpenLayers.ElementsIndexer.IndexingMethods = {\n    \n        Z_ORDER: function(indexer, newNode, nextNode) {\n        var newZIndex = indexer.getZIndex(newNode);\n\n        var returnVal = 0;\n        if (nextNode) {\n            var nextZIndex = indexer.getZIndex(nextNode);\n            returnVal = newZIndex - nextZIndex; \n        }\n        \n        return returnVal;\n    },\n\n        Z_ORDER_DRAWING_ORDER: function(indexer, newNode, nextNode) {\n        var returnVal = OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER(\n            indexer, \n            newNode, \n            nextNode\n        );\n        if (nextNode && returnVal == 0) {\n            returnVal = 1;\n        }\n        \n        return returnVal;\n    },\n\n        Z_ORDER_Y_ORDER: function(indexer, newNode, nextNode) {\n        var returnVal = OpenLayers.ElementsIndexer.IndexingMethods.Z_ORDER(\n            indexer, \n            newNode, \n            nextNode\n        );\n        \n        if (nextNode && returnVal === 0) {            \n            var result = nextNode._boundsBottom - newNode._boundsBottom;\n            returnVal = (result === 0) ? 1 : result;\n        }\n        \n        return returnVal;       \n    }\n};\n\nOpenLayers.Renderer.Elements = OpenLayers.Class(OpenLayers.Renderer, {\n\n        rendererRoot: null,\n    \n        root: null,\n    \n        vectorRoot: null,\n\n        textRoot: null,\n\n        xOffset: 0,\n    \n        \n        indexer: null, \n    \n        BACKGROUND_ID_SUFFIX: \"_background\",\n    \n        LABEL_ID_SUFFIX: \"_label\",\n    \n        LABEL_OUTLINE_SUFFIX: \"_outline\",\n\n        initialize: function(containerID, options) {\n        OpenLayers.Renderer.prototype.initialize.apply(this, arguments);\n\n        this.rendererRoot = this.createRenderRoot();\n        this.root = this.createRoot(\"_root\");\n        this.vectorRoot = this.createRoot(\"_vroot\");\n        this.textRoot = this.createRoot(\"_troot\");\n        \n        this.root.appendChild(this.vectorRoot);\n        this.root.appendChild(this.textRoot);\n        \n        this.rendererRoot.appendChild(this.root);\n        this.container.appendChild(this.rendererRoot);\n        \n        if(options && (options.zIndexing || options.yOrdering)) {\n            this.indexer = new OpenLayers.ElementsIndexer(options.yOrdering);\n        }\n    },\n    \n        destroy: function() {\n\n        this.clear(); \n\n        this.rendererRoot = null;\n        this.root = null;\n        this.xmlns = null;\n\n        OpenLayers.Renderer.prototype.destroy.apply(this, arguments);\n    },\n    \n        setExtent: function(extent, resolutionChanged) {\n        var coordSysUnchanged = OpenLayers.Renderer.prototype.setExtent.apply(this, arguments);\n        var resolution = this.getResolution();\n        if (this.map.baseLayer && this.map.baseLayer.wrapDateLine) {\n            var rightOfDateLine,\n                ratio = extent.getWidth() / this.map.getExtent().getWidth(),\n                extent = extent.scale(1 / ratio),\n                world = this.map.getMaxExtent();\n            if (world.right > extent.left && world.right < extent.right) {\n                rightOfDateLine = true;\n            } else if (world.left > extent.left && world.left < extent.right) {\n                rightOfDateLine = false;\n            }\n            if (rightOfDateLine !== this.rightOfDateLine || resolutionChanged) {\n                coordSysUnchanged = false;\n                this.xOffset = rightOfDateLine === true ?\n                    world.getWidth() / resolution : 0;\n            }\n            this.rightOfDateLine = rightOfDateLine;\n        }\n        return coordSysUnchanged;\n    },\n\n        getNodeType: function(geometry, style) { },\n\n        drawGeometry: function(geometry, style, featureId) {\n        var className = geometry.CLASS_NAME;\n        var rendered = true;\n        if ((className == \"OpenLayers.Geometry.Collection\") ||\n            (className == \"OpenLayers.Geometry.MultiPoint\") ||\n            (className == \"OpenLayers.Geometry.MultiLineString\") ||\n            (className == \"OpenLayers.Geometry.MultiPolygon\")) {\n            for (var i = 0, len=geometry.components.length; i<len; i++) {\n                rendered = this.drawGeometry(\n                    geometry.components[i], style, featureId) && rendered;\n            }\n            return rendered;\n        }\n\n        rendered = false;\n        var removeBackground = false;\n        if (style.display != \"none\") {\n            if (style.backgroundGraphic) {\n                this.redrawBackgroundNode(geometry.id, geometry, style,\n                    featureId);\n            } else {\n                removeBackground = true;\n            }\n            rendered = this.redrawNode(geometry.id, geometry, style,\n                featureId);\n        }\n        if (rendered == false) {\n            var node = document.getElementById(geometry.id);\n            if (node) {\n                if (node._style.backgroundGraphic) {\n                    removeBackground = true;\n                }\n                node.parentNode.removeChild(node);\n            }\n        }\n        if (removeBackground) {\n            var node = document.getElementById(\n                geometry.id + this.BACKGROUND_ID_SUFFIX);\n            if (node) {\n                node.parentNode.removeChild(node);\n            }\n        }\n        return rendered;\n    },\n    \n        redrawNode: function(id, geometry, style, featureId) {\n        style = this.applyDefaultSymbolizer(style);\n        var node = this.nodeFactory(id, this.getNodeType(geometry, style));\n        node._featureId = featureId;\n        node._boundsBottom = geometry.getBounds().bottom;\n        node._geometryClass = geometry.CLASS_NAME;\n        node._style = style;\n\n        var drawResult = this.drawGeometryNode(node, geometry, style);\n        if(drawResult === false) {\n            return false;\n        }\n         \n        node = drawResult.node;\n        if (this.indexer) {\n            var insert = this.indexer.insert(node);\n            if (insert) {\n                this.vectorRoot.insertBefore(node, insert);\n            } else {\n                this.vectorRoot.appendChild(node);\n            }\n        } else {\n            if (node.parentNode !== this.vectorRoot){ \n                this.vectorRoot.appendChild(node);\n            }\n        }\n        \n        this.postDraw(node);\n        \n        return drawResult.complete;\n    },\n    \n        redrawBackgroundNode: function(id, geometry, style, featureId) {\n        var backgroundStyle = OpenLayers.Util.extend({}, style);\n        backgroundStyle.externalGraphic = backgroundStyle.backgroundGraphic;\n        backgroundStyle.graphicXOffset = backgroundStyle.backgroundXOffset;\n        backgroundStyle.graphicYOffset = backgroundStyle.backgroundYOffset;\n        backgroundStyle.graphicZIndex = backgroundStyle.backgroundGraphicZIndex;\n        backgroundStyle.graphicWidth = backgroundStyle.backgroundWidth || backgroundStyle.graphicWidth;\n        backgroundStyle.graphicHeight = backgroundStyle.backgroundHeight || backgroundStyle.graphicHeight;\n        backgroundStyle.backgroundGraphic = null;\n        backgroundStyle.backgroundXOffset = null;\n        backgroundStyle.backgroundYOffset = null;\n        backgroundStyle.backgroundGraphicZIndex = null;\n        \n        return this.redrawNode(\n            id + this.BACKGROUND_ID_SUFFIX, \n            geometry, \n            backgroundStyle, \n            null\n        );\n    },\n\n        drawGeometryNode: function(node, geometry, style) {\n        style = style || node._style;\n\n        var options = {\n            'isFilled': style.fill === undefined ?\n                true :\n                style.fill,\n            'isStroked': style.stroke === undefined ?\n                !!style.strokeWidth :\n                style.stroke\n        };\n        var drawn;\n        switch (geometry.CLASS_NAME) {\n            case \"OpenLayers.Geometry.Point\":\n                if(style.graphic === false) {\n                    options.isFilled = false;\n                    options.isStroked = false;\n                }\n                drawn = this.drawPoint(node, geometry);\n                break;\n            case \"OpenLayers.Geometry.LineString\":\n                options.isFilled = false;\n                drawn = this.drawLineString(node, geometry);\n                break;\n            case \"OpenLayers.Geometry.LinearRing\":\n                drawn = this.drawLinearRing(node, geometry);\n                break;\n            case \"OpenLayers.Geometry.Polygon\":\n                drawn = this.drawPolygon(node, geometry);\n                break;\n            case \"OpenLayers.Geometry.Rectangle\":\n                drawn = this.drawRectangle(node, geometry);\n                break;\n            default:\n                break;\n        }\n\n        node._options = options; \n        if (drawn != false) {\n            return {\n                node: this.setStyle(node, style, options, geometry),\n                complete: drawn\n            };\n        } else {\n            return false;\n        }\n    },\n    \n        postDraw: function(node) {},\n    \n        removeText: function(featureId) {\n        var label = document.getElementById(featureId + this.LABEL_ID_SUFFIX);\n        if (label) {\n            this.textRoot.removeChild(label);\n        }\n        var outline = document.getElementById(featureId + this.LABEL_OUTLINE_SUFFIX);\n        if (outline) {\n            this.textRoot.removeChild(outline);\n        }\n    },\n\n        getFeatureIdFromEvent: function(evt) {\n        var target = evt.target;\n        var useElement = target && target.correspondingUseElement;\n        var node = useElement ? useElement : (target || evt.srcElement);\n        return node._featureId;\n    },\n\n        eraseGeometry: function(geometry, featureId) {\n        if ((geometry.CLASS_NAME == \"OpenLayers.Geometry.MultiPoint\") ||\n            (geometry.CLASS_NAME == \"OpenLayers.Geometry.MultiLineString\") ||\n            (geometry.CLASS_NAME == \"OpenLayers.Geometry.MultiPolygon\") ||\n            (geometry.CLASS_NAME == \"OpenLayers.Geometry.Collection\")) {\n            for (var i=0, len=geometry.components.length; i<len; i++) {\n                this.eraseGeometry(geometry.components[i], featureId);\n            }\n        } else {    \n            var element = OpenLayers.Util.getElement(geometry.id);\n            if (element && element.parentNode) {\n                if (element.geometry) {\n                    element.geometry.destroy();\n                    element.geometry = null;\n                }\n                element.parentNode.removeChild(element);\n\n                if (this.indexer) {\n                    this.indexer.remove(element);\n                }\n                \n                if (element._style.backgroundGraphic) {\n                    var backgroundId = geometry.id + this.BACKGROUND_ID_SUFFIX;\n                    var bElem = OpenLayers.Util.getElement(backgroundId);\n                    if (bElem && bElem.parentNode) {\n                        bElem.parentNode.removeChild(bElem);\n                    }\n                }\n            }\n        }\n    },\n\n        nodeFactory: function(id, type) {\n        var node = OpenLayers.Util.getElement(id);\n        if (node) {\n            if (!this.nodeTypeCompare(node, type)) {\n                node.parentNode.removeChild(node);\n                node = this.nodeFactory(id, type);\n            }\n        } else {\n            node = this.createNode(type, id);\n        }\n        return node;\n    },\n    \n        nodeTypeCompare: function(node, type) {},\n    \n        createNode: function(type, id) {},\n\n        moveRoot: function(renderer) {\n        var root = this.root;\n        if(renderer.root.parentNode == this.rendererRoot) {\n            root = renderer.root;\n        }\n        root.parentNode.removeChild(root);\n        renderer.rendererRoot.appendChild(root);\n    },\n    \n        getRenderLayerId: function() {\n        return this.root.parentNode.parentNode.id;\n    },\n    \n        isComplexSymbol: function(graphicName) {\n        return (graphicName != \"circle\") && !!graphicName;\n    },\n\n    CLASS_NAME: \"OpenLayers.Renderer.Elements\"\n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Renderer/SVG.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Renderer.SVG = OpenLayers.Class(OpenLayers.Renderer.Elements, {\n\n        xmlns: \"http://www.w3.org/2000/svg\",\n    \n        xlinkns: \"http://www.w3.org/1999/xlink\",\n\n        MAX_PIXEL: 15000,\n\n        translationParameters: null,\n    \n        symbolMetrics: null,\n    \n        initialize: function(containerID) {\n        if (!this.supported()) { \n            return; \n        }\n        OpenLayers.Renderer.Elements.prototype.initialize.apply(this, \n                                                                arguments);\n        this.translationParameters = {x: 0, y: 0};\n        \n        this.symbolMetrics = {};\n    },\n\n        supported: function() {\n        var svgFeature = \"http://www.w3.org/TR/SVG11/feature#\";\n        return (document.implementation && \n           (document.implementation.hasFeature(\"org.w3c.svg\", \"1.0\") || \n            document.implementation.hasFeature(svgFeature + \"SVG\", \"1.1\") || \n            document.implementation.hasFeature(svgFeature + \"BasicStructure\", \"1.1\") ));\n    },    \n\n        setExtent: function(extent, resolutionChanged) {\n        var coordSysUnchanged = OpenLayers.Renderer.Elements.prototype.setExtent.apply(this, arguments);\n        \n        var resolution = this.getResolution(),\n            left = -extent.left / resolution,\n            top = extent.top / resolution;\n        if (resolutionChanged) {\n            this.left = left;\n            this.top = top;\n            var extentString = \"0 0 \" + this.size.w + \" \" + this.size.h;\n\n            this.rendererRoot.setAttributeNS(null, \"viewBox\", extentString);\n            this.translate(this.xOffset, 0);\n            return true;\n        } else {\n            var inRange = this.translate(left - this.left + this.xOffset, top - this.top);\n            if (!inRange) {\n                this.setExtent(extent, true);\n            }\n            return coordSysUnchanged && inRange;\n        }\n    },\n    \n        translate: function(x, y) {\n        if (!this.inValidRange(x, y, true)) {\n            return false;\n        } else {\n            var transformString = \"\";\n            if (x || y) {\n                transformString = \"translate(\" + x + \",\" + y + \")\";\n            }\n            this.root.setAttributeNS(null, \"transform\", transformString);\n            this.translationParameters = {x: x, y: y};\n            return true;\n        }\n    },\n\n        setSize: function(size) {\n        OpenLayers.Renderer.prototype.setSize.apply(this, arguments);\n        \n        this.rendererRoot.setAttributeNS(null, \"width\", this.size.w);\n        this.rendererRoot.setAttributeNS(null, \"height\", this.size.h);\n    },\n\n        getNodeType: function(geometry, style) {\n        var nodeType = null;\n        switch (geometry.CLASS_NAME) {\n            case \"OpenLayers.Geometry.Point\":\n                if (style.externalGraphic) {\n                    nodeType = \"image\";\n                } else if (this.isComplexSymbol(style.graphicName)) {\n                    nodeType = \"svg\";\n                } else {\n                    nodeType = \"circle\";\n                }\n                break;\n            case \"OpenLayers.Geometry.Rectangle\":\n                nodeType = \"rect\";\n                break;\n            case \"OpenLayers.Geometry.LineString\":\n                nodeType = \"polyline\";\n                break;\n            case \"OpenLayers.Geometry.LinearRing\":\n                nodeType = \"polygon\";\n                break;\n            case \"OpenLayers.Geometry.Polygon\":\n            case \"OpenLayers.Geometry.Curve\":\n                nodeType = \"path\";\n                break;\n            default:\n                break;\n        }\n        return nodeType;\n    },\n\n        setStyle: function(node, style, options) {\n        style = style  || node._style;\n        options = options || node._options;\n\n        var title = style.title || style.graphicTitle;\n        if (title) {\n            node.setAttributeNS(null, \"title\", title);\n            var titleNode = node.getElementsByTagName(\"title\");\n            if (titleNode.length > 0) {\n                titleNode[0].firstChild.textContent = title;\n            } else {\n                var label = this.nodeFactory(null, \"title\");\n                label.textContent = title;\n                node.appendChild(label);\n            }\n        }\n\n        var r = parseFloat(node.getAttributeNS(null, \"r\"));\n        var widthFactor = 1;\n        var pos;\n        if (node._geometryClass == \"OpenLayers.Geometry.Point\" && r) {\n            node.style.visibility = \"\";\n            if (style.graphic === false) {\n                node.style.visibility = \"hidden\";\n            } else if (style.externalGraphic) {\n                pos = this.getPosition(node);\n                if (style.graphicWidth && style.graphicHeight) {\n                  node.setAttributeNS(null, \"preserveAspectRatio\", \"none\");\n                }\n                var width = style.graphicWidth || style.graphicHeight;\n                var height = style.graphicHeight || style.graphicWidth;\n                width = width ? width : style.pointRadius*2;\n                height = height ? height : style.pointRadius*2;\n                var xOffset = (style.graphicXOffset != undefined) ?\n                    style.graphicXOffset : -(0.5 * width);\n                var yOffset = (style.graphicYOffset != undefined) ?\n                    style.graphicYOffset : -(0.5 * height);\n\n                var opacity = style.graphicOpacity || style.fillOpacity;\n                \n                node.setAttributeNS(null, \"x\", (pos.x + xOffset).toFixed());\n                node.setAttributeNS(null, \"y\", (pos.y + yOffset).toFixed());\n                node.setAttributeNS(null, \"width\", width);\n                node.setAttributeNS(null, \"height\", height);\n                node.setAttributeNS(this.xlinkns, \"xlink:href\", style.externalGraphic);\n                node.setAttributeNS(null, \"style\", \"opacity: \"+opacity);\n                node.onclick = OpenLayers.Event.preventDefault;\n            } else if (this.isComplexSymbol(style.graphicName)) {\n                var offset = style.pointRadius * 3;\n                var size = offset * 2;\n                var src = this.importSymbol(style.graphicName);\n                pos = this.getPosition(node);\n                widthFactor = this.symbolMetrics[src.id][0] * 3 / size;\n                var parent = node.parentNode;\n                var nextSibling = node.nextSibling;\n                if(parent) {\n                    parent.removeChild(node);\n                }\n                node.firstChild && node.removeChild(node.firstChild);\n                node.appendChild(src.firstChild.cloneNode(true));\n                node.setAttributeNS(null, \"viewBox\", src.getAttributeNS(null, \"viewBox\"));\n                \n                node.setAttributeNS(null, \"width\", size);\n                node.setAttributeNS(null, \"height\", size);\n                node.setAttributeNS(null, \"x\", pos.x - offset);\n                node.setAttributeNS(null, \"y\", pos.y - offset);\n                if(nextSibling) {\n                    parent.insertBefore(node, nextSibling);\n                } else if(parent) {\n                    parent.appendChild(node);\n                }\n            } else {\n                node.setAttributeNS(null, \"r\", style.pointRadius);\n            }\n\n            var rotation = style.rotation;\n            \n            if ((rotation !== undefined || node._rotation !== undefined) && pos) {\n                node._rotation = rotation;\n                rotation |= 0;\n                if (node.nodeName !== \"svg\") { \n                    node.setAttributeNS(null, \"transform\", \n                        \"rotate(\" + rotation + \" \" + pos.x + \" \" + \n                        pos.y + \")\"); \n                } else {\n                    var metrics = this.symbolMetrics[src.id];\n                    node.firstChild.setAttributeNS(null, \"transform\", \"rotate(\" \n                        + rotation + \" \" \n                        + metrics[1] + \" \"\n                        + metrics[2] + \")\");\n                }\n            }\n        }\n        \n        if (options.isFilled) {\n            node.setAttributeNS(null, \"fill\", style.fillColor);\n            node.setAttributeNS(null, \"fill-opacity\", style.fillOpacity);\n        } else {\n            node.setAttributeNS(null, \"fill\", \"none\");\n        }\n\n        if (options.isStroked) {\n            node.setAttributeNS(null, \"stroke\", style.strokeColor);\n            node.setAttributeNS(null, \"stroke-opacity\", style.strokeOpacity);\n            node.setAttributeNS(null, \"stroke-width\", style.strokeWidth * widthFactor);\n            node.setAttributeNS(null, \"stroke-linecap\", style.strokeLinecap || \"round\");\n            node.setAttributeNS(null, \"stroke-linejoin\", \"round\");\n            style.strokeDashstyle && node.setAttributeNS(null,\n                \"stroke-dasharray\", this.dashStyle(style, widthFactor));\n        } else {\n            node.setAttributeNS(null, \"stroke\", \"none\");\n        }\n        \n        if (style.pointerEvents) {\n            node.setAttributeNS(null, \"pointer-events\", style.pointerEvents);\n        }\n                \n        if (style.cursor != null) {\n            node.setAttributeNS(null, \"cursor\", style.cursor);\n        }\n        \n        return node;\n    },\n\n        dashStyle: function(style, widthFactor) {\n        var w = style.strokeWidth * widthFactor;\n        var str = style.strokeDashstyle;\n        switch (str) {\n            case 'solid':\n                return 'none';\n            case 'dot':\n                return [1, 4 * w].join();\n            case 'dash':\n                return [4 * w, 4 * w].join();\n            case 'dashdot':\n                return [4 * w, 4 * w, 1, 4 * w].join();\n            case 'longdash':\n                return [8 * w, 4 * w].join();\n            case 'longdashdot':\n                return [8 * w, 4 * w, 1, 4 * w].join();\n            default:\n                return OpenLayers.String.trim(str).replace(/\\s+/g, \",\");\n        }\n    },\n    \n        createNode: function(type, id) {\n        var node = document.createElementNS(this.xmlns, type);\n        if (id) {\n            node.setAttributeNS(null, \"id\", id);\n        }\n        return node;    \n    },\n    \n        nodeTypeCompare: function(node, type) {\n        return (type == node.nodeName);\n    },\n   \n        createRenderRoot: function() {\n        var svg = this.nodeFactory(this.container.id + \"_svgRoot\", \"svg\");\n        svg.style.display = \"block\";\n        return svg;\n    },\n\n        createRoot: function(suffix) {\n        return this.nodeFactory(this.container.id + suffix, \"g\");\n    },\n\n        createDefs: function() {\n        var defs = this.nodeFactory(this.container.id + \"_defs\", \"defs\");\n        this.rendererRoot.appendChild(defs);\n        return defs;\n    },\n\n    \n        drawCircle: function(node, geometry, radius) {\n        var resolution = this.getResolution();\n        var x = ((geometry.x - this.featureDx) / resolution + this.left);\n        var y = (this.top - geometry.y / resolution);\n\n        if (this.inValidRange(x, y)) { \n            node.setAttributeNS(null, \"cx\", x);\n            node.setAttributeNS(null, \"cy\", y);\n            node.setAttributeNS(null, \"r\", radius);\n            return node;\n        } else {\n            return false;\n        }    \n            \n    },\n    \n        drawText: function(featureId, style, location) {\n        var drawOutline = (!!style.labelOutlineWidth);\n        if (drawOutline) {\n            var outlineStyle = OpenLayers.Util.extend({}, style);\n            outlineStyle.fontColor = outlineStyle.labelOutlineColor;\n            outlineStyle.fontStrokeColor = outlineStyle.labelOutlineColor;\n            outlineStyle.fontStrokeWidth = style.labelOutlineWidth;\n            if (style.labelOutlineOpacity) {\n                outlineStyle.fontOpacity = style.labelOutlineOpacity;\n            }\n            delete outlineStyle.labelOutlineWidth;\n            this.drawText(featureId, outlineStyle, location);\n        }\n\n        var resolution = this.getResolution();\n\n        var x = ((location.x - this.featureDx) / resolution + this.left);\n        var y = (location.y / resolution - this.top);\n\n        var suffix = (drawOutline)?this.LABEL_OUTLINE_SUFFIX:this.LABEL_ID_SUFFIX;\n        var label = this.nodeFactory(featureId + suffix, \"text\");\n\n        label.setAttributeNS(null, \"x\", x);\n        label.setAttributeNS(null, \"y\", -y);\n\n        if (style.fontColor) {\n            label.setAttributeNS(null, \"fill\", style.fontColor);\n        }\n        if (style.fontStrokeColor) {\n            label.setAttributeNS(null, \"stroke\", style.fontStrokeColor);\n        }\n        if (style.fontStrokeWidth) {\n            label.setAttributeNS(null, \"stroke-width\", style.fontStrokeWidth);\n        }\n        if (style.fontOpacity) {\n            label.setAttributeNS(null, \"opacity\", style.fontOpacity);\n        }\n        if (style.fontFamily) {\n            label.setAttributeNS(null, \"font-family\", style.fontFamily);\n        }\n        if (style.fontSize) {\n            label.setAttributeNS(null, \"font-size\", style.fontSize);\n        }\n        if (style.fontWeight) {\n            label.setAttributeNS(null, \"font-weight\", style.fontWeight);\n        }\n        if (style.fontStyle) {\n            label.setAttributeNS(null, \"font-style\", style.fontStyle);\n        }\n        if (style.labelSelect === true) {\n            label.setAttributeNS(null, \"pointer-events\", \"visible\");\n            label._featureId = featureId;\n        } else {\n            label.setAttributeNS(null, \"pointer-events\", \"none\");\n        }\n        var align = style.labelAlign || OpenLayers.Renderer.defaultSymbolizer.labelAlign;\n        label.setAttributeNS(null, \"text-anchor\",\n            OpenLayers.Renderer.SVG.LABEL_ALIGN[align[0]] || \"middle\");\n\n        if (OpenLayers.IS_GECKO === true) {\n            label.setAttributeNS(null, \"dominant-baseline\",\n                OpenLayers.Renderer.SVG.LABEL_ALIGN[align[1]] || \"central\");\n        }\n\n        var labelRows = style.label.split('\\n');\n        var numRows = labelRows.length;\n        while (label.childNodes.length > numRows) {\n            label.removeChild(label.lastChild);\n        }\n        for (var i = 0; i < numRows; i++) {\n            var tspan = this.nodeFactory(featureId + suffix + \"_tspan_\" + i, \"tspan\");\n            if (style.labelSelect === true) {\n                tspan._featureId = featureId;\n                tspan._geometry = location;\n                tspan._geometryClass = location.CLASS_NAME;\n            }\n            if (OpenLayers.IS_GECKO === false) {\n                tspan.setAttributeNS(null, \"baseline-shift\",\n                    OpenLayers.Renderer.SVG.LABEL_VSHIFT[align[1]] || \"-35%\");\n            }\n            tspan.setAttribute(\"x\", x);\n            if (i == 0) {\n                var vfactor = OpenLayers.Renderer.SVG.LABEL_VFACTOR[align[1]];\n                if (vfactor == null) {\n                     vfactor = -.5;\n                }\n                tspan.setAttribute(\"dy\", (vfactor*(numRows-1)) + \"em\");\n            } else {\n                tspan.setAttribute(\"dy\", \"1em\");\n            }\n            tspan.textContent = (labelRows[i] === '') ? ' ' : labelRows[i];\n            if (!tspan.parentNode) {\n                label.appendChild(tspan);\n            }\n        }\n\n        if (!label.parentNode) {\n            this.textRoot.appendChild(label);\n        }\n    },\n    \n        getComponentsString: function(components, separator) {\n        var renderCmp = [];\n        var complete = true;\n        var len = components.length;\n        var strings = [];\n        var str, component;\n        for(var i=0; i<len; i++) {\n            component = components[i];\n            renderCmp.push(component);\n            str = this.getShortString(component);\n            if (str) {\n                strings.push(str);\n            } else {\n                if (i > 0) {\n                    if (this.getShortString(components[i - 1])) {\n                        strings.push(this.clipLine(components[i],\n                            components[i-1]));\n                    }\n                }\n                if (i < len - 1) {\n                    if (this.getShortString(components[i + 1])) {\n                        strings.push(this.clipLine(components[i],\n                            components[i+1]));\n                    }\n                }\n                complete = false;\n            }\n        }\n\n        return {\n            path: strings.join(separator || \",\"),\n            complete: complete\n        };\n    },\n    \n        clipLine: function(badComponent, goodComponent) {\n        if (goodComponent.equals(badComponent)) {\n            return \"\";\n        }\n        var resolution = this.getResolution();\n        var maxX = this.MAX_PIXEL - this.translationParameters.x;\n        var maxY = this.MAX_PIXEL - this.translationParameters.y;\n        var x1 = (goodComponent.x - this.featureDx) / resolution + this.left;\n        var y1 = this.top - goodComponent.y / resolution;\n        var x2 = (badComponent.x - this.featureDx) / resolution + this.left;\n        var y2 = this.top - badComponent.y / resolution;\n        var k;\n        if (x2 < -maxX || x2 > maxX) {\n            k = (y2 - y1) / (x2 - x1);\n            x2 = x2 < 0 ? -maxX : maxX;\n            y2 = y1 + (x2 - x1) * k;\n        }\n        if (y2 < -maxY || y2 > maxY) {\n            k = (x2 - x1) / (y2 - y1);\n            y2 = y2 < 0 ? -maxY : maxY;\n            x2 = x1 + (y2 - y1) * k;\n        }\n        return x2 + \",\" + y2;\n    },\n\n        getShortString: function(point) {\n        var resolution = this.getResolution();\n        var x = ((point.x - this.featureDx) / resolution + this.left);\n        var y = (this.top - point.y / resolution);\n\n        if (this.inValidRange(x, y)) { \n            return x + \",\" + y;\n        } else {\n            return false;\n        }\n    },\n    \n        getPosition: function(node) {\n        return({\n            x: parseFloat(node.getAttributeNS(null, \"cx\")),\n            y: parseFloat(node.getAttributeNS(null, \"cy\"))\n        });\n    },\n\n        getFeatureIdFromEvent: function(evt) {\n        var featureId = OpenLayers.Renderer.Elements.prototype.getFeatureIdFromEvent.apply(this, arguments);\n        if(!featureId) {\n            var target = evt.target;\n            featureId = target.parentNode && target != this.rendererRoot ?\n                target.parentNode._featureId : undefined;\n        }\n        return featureId;\n    },\n\n    CLASS_NAME: \"OpenLayers.Renderer.SVG\"\n});\n\nOpenLayers.Renderer.SVG.LABEL_ALIGN = {\n    \"l\": \"start\",\n    \"r\": \"end\",\n    \"b\": \"bottom\",\n    \"t\": \"hanging\"\n};\n\nOpenLayers.Renderer.SVG.LABEL_VSHIFT = {\n    \"t\": \"-70%\",\n    \"b\": \"0\"    \n};\n\nOpenLayers.Renderer.SVG.LABEL_VFACTOR = {\n    \"t\": 0,\n    \"b\": -1\n};\n\nOpenLayers.Renderer.SVG.preventDefault = function(e) {\n    OpenLayers.Event.preventDefault(e);\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Renderer/VML.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Renderer.VML = OpenLayers.Class(OpenLayers.Renderer.Elements, {\n\n        xmlns: \"urn:schemas-microsoft-com:vml\",\n    \n        symbolCache: {},\n\n        offset: null,\n    \n        initialize: function(containerID) {\n        if (!this.supported()) { \n            return; \n        }\n        if (!document.namespaces.olv) {\n            document.namespaces.add(\"olv\", this.xmlns);\n            var style = document.createStyleSheet();\n            var shapes = ['shape','rect', 'oval', 'fill', 'stroke', 'imagedata', 'group','textbox']; \n            for (var i = 0, len = shapes.length; i < len; i++) {\n\n                style.addRule('olv\\\\:' + shapes[i], \"behavior: url(#default#VML); \" +\n                              \"position: absolute; display: inline-block;\");\n            }                  \n        }\n        \n        OpenLayers.Renderer.Elements.prototype.initialize.apply(this, \n                                                                arguments);\n    },\n\n        supported: function() {\n        return !!(document.namespaces);\n    },    \n\n        setExtent: function(extent, resolutionChanged) {\n        var coordSysUnchanged = OpenLayers.Renderer.Elements.prototype.setExtent.apply(this, arguments);\n        var resolution = this.getResolution();\n    \n        var left = (extent.left/resolution) | 0;\n        var top = (extent.top/resolution - this.size.h) | 0;\n        if (resolutionChanged || !this.offset) {\n            this.offset = {x: left, y: top};\n            left = 0;\n            top = 0;\n        } else {\n            left = left - this.offset.x;\n            top = top - this.offset.y;\n        }\n\n        \n        var org = (left - this.xOffset) + \" \" + top;\n        this.root.coordorigin = org;\n        var roots = [this.root, this.vectorRoot, this.textRoot];\n        var root;\n        for(var i=0, len=roots.length; i<len; ++i) {\n            root = roots[i];\n\n            var size = this.size.w + \" \" + this.size.h;\n            root.coordsize = size;\n            \n        }\n        this.root.style.flip = \"y\";\n        \n        return coordSysUnchanged;\n    },\n\n\n        setSize: function(size) {\n        OpenLayers.Renderer.prototype.setSize.apply(this, arguments);\n        var roots = [\n            this.rendererRoot,\n            this.root,\n            this.vectorRoot,\n            this.textRoot\n        ];\n        var w = this.size.w + \"px\";\n        var h = this.size.h + \"px\";\n        var root;\n        for(var i=0, len=roots.length; i<len; ++i) {\n            root = roots[i];\n            root.style.width = w;\n            root.style.height = h;\n        }\n    },\n\n        getNodeType: function(geometry, style) {\n        var nodeType = null;\n        switch (geometry.CLASS_NAME) {\n            case \"OpenLayers.Geometry.Point\":\n                if (style.externalGraphic) {\n                    nodeType = \"olv:rect\";\n                } else if (this.isComplexSymbol(style.graphicName)) {\n                    nodeType = \"olv:shape\";\n                } else {\n                    nodeType = \"olv:oval\";\n                }\n                break;\n            case \"OpenLayers.Geometry.Rectangle\":\n                nodeType = \"olv:rect\";\n                break;\n            case \"OpenLayers.Geometry.LineString\":\n            case \"OpenLayers.Geometry.LinearRing\":\n            case \"OpenLayers.Geometry.Polygon\":\n            case \"OpenLayers.Geometry.Curve\":\n                nodeType = \"olv:shape\";\n                break;\n            default:\n                break;\n        }\n        return nodeType;\n    },\n\n        setStyle: function(node, style, options, geometry) {\n        style = style  || node._style;\n        options = options || node._options;\n        var fillColor = style.fillColor;\n\n        var title = style.title || style.graphicTitle;\n        if (title) {\n            node.title = title;\n        } \n\n        if (node._geometryClass === \"OpenLayers.Geometry.Point\") {\n            if (style.externalGraphic) {\n                options.isFilled = true;\n                var width = style.graphicWidth || style.graphicHeight;\n                var height = style.graphicHeight || style.graphicWidth;\n                width = width ? width : style.pointRadius*2;\n                height = height ? height : style.pointRadius*2;\n\n                var resolution = this.getResolution();\n                var xOffset = (style.graphicXOffset != undefined) ?\n                    style.graphicXOffset : -(0.5 * width);\n                var yOffset = (style.graphicYOffset != undefined) ?\n                    style.graphicYOffset : -(0.5 * height);\n                \n                node.style.left = ((((geometry.x - this.featureDx)/resolution - this.offset.x)+xOffset) | 0) + \"px\";\n                node.style.top = (((geometry.y/resolution - this.offset.y)-(yOffset+height)) | 0) + \"px\";\n                node.style.width = width + \"px\";\n                node.style.height = height + \"px\";\n                node.style.flip = \"y\";\n                fillColor = \"none\";\n                options.isStroked = false;\n            } else if (this.isComplexSymbol(style.graphicName)) {\n                var cache = this.importSymbol(style.graphicName);\n                node.path = cache.path;\n                node.coordorigin = cache.left + \",\" + cache.bottom;\n                var size = cache.size;\n                node.coordsize = size + \",\" + size;        \n                this.drawCircle(node, geometry, style.pointRadius);\n                node.style.flip = \"y\";\n            } else {\n                this.drawCircle(node, geometry, style.pointRadius);\n            }\n        }\n        if (options.isFilled) { \n            node.fillcolor = fillColor; \n        } else { \n            node.filled = \"false\"; \n        }\n        var fills = node.getElementsByTagName(\"fill\");\n        var fill = (fills.length == 0) ? null : fills[0];\n        if (!options.isFilled) {\n            if (fill) {\n                node.removeChild(fill);\n            }\n        } else {\n            if (!fill) {\n                fill = this.createNode('olv:fill', node.id + \"_fill\");\n            }\n            fill.opacity = style.fillOpacity;\n\n            if (node._geometryClass === \"OpenLayers.Geometry.Point\" &&\n                    style.externalGraphic) {\n                if (style.graphicOpacity) {\n                    fill.opacity = style.graphicOpacity;\n                }\n                \n                fill.src = style.externalGraphic;\n                fill.type = \"frame\";\n                \n                if (!(style.graphicWidth && style.graphicHeight)) {\n                  fill.aspect = \"atmost\";\n                }                \n            }\n            if (fill.parentNode != node) {\n                node.appendChild(fill);\n            }\n        }\n        var rotation = style.rotation;\n        if ((rotation !== undefined || node._rotation !== undefined)) {\n            node._rotation = rotation;\n            if (style.externalGraphic) {\n                this.graphicRotate(node, xOffset, yOffset, style);\n                fill.opacity = 0;\n            } else if(node._geometryClass === \"OpenLayers.Geometry.Point\") {\n                node.style.rotation = rotation || 0;\n            }\n        }\n        var strokes = node.getElementsByTagName(\"stroke\");\n        var stroke = (strokes.length == 0) ? null : strokes[0];\n        if (!options.isStroked) {\n            node.stroked = false;\n            if (stroke) {\n                stroke.on = false;\n            }\n        } else {\n            if (!stroke) {\n                stroke = this.createNode('olv:stroke', node.id + \"_stroke\");\n                node.appendChild(stroke);\n            }\n            stroke.on = true;\n            stroke.color = style.strokeColor; \n            stroke.weight = style.strokeWidth + \"px\"; \n            stroke.opacity = style.strokeOpacity;\n            stroke.endcap = style.strokeLinecap == 'butt' ? 'flat' :\n                (style.strokeLinecap || 'round');\n            if (style.strokeDashstyle) {\n                stroke.dashstyle = this.dashStyle(style);\n            }\n        }\n        \n        if (style.cursor != \"inherit\" && style.cursor != null) {\n            node.style.cursor = style.cursor;\n        }\n        return node;\n    },\n\n        graphicRotate: function(node, xOffset, yOffset, style) {\n        var style = style || node._style;\n        var rotation = style.rotation || 0;\n        \n        var aspectRatio, size;\n        if (!(style.graphicWidth && style.graphicHeight)) {\n            var img = new Image();\n            img.onreadystatechange = OpenLayers.Function.bind(function() {\n                if(img.readyState == \"complete\" ||\n                        img.readyState == \"interactive\") {\n                    aspectRatio = img.width / img.height;\n                    size = Math.max(style.pointRadius * 2, \n                        style.graphicWidth || 0,\n                        style.graphicHeight || 0);\n                    xOffset = xOffset * aspectRatio;\n                    style.graphicWidth = size * aspectRatio;\n                    style.graphicHeight = size;\n                    this.graphicRotate(node, xOffset, yOffset, style);\n                }\n            }, this);\n            img.src = style.externalGraphic;\n            return;\n        } else {\n            size = Math.max(style.graphicWidth, style.graphicHeight);\n            aspectRatio = style.graphicWidth / style.graphicHeight;\n        }\n        \n        var width = Math.round(style.graphicWidth || size * aspectRatio);\n        var height = Math.round(style.graphicHeight || size);\n        node.style.width = width + \"px\";\n        node.style.height = height + \"px\";\n        var image = document.getElementById(node.id + \"_image\");\n        if (!image) {\n            image = this.createNode(\"olv:imagedata\", node.id + \"_image\");\n            node.appendChild(image);\n        }\n        image.style.width = width + \"px\";\n        image.style.height = height + \"px\";\n        image.src = style.externalGraphic;\n        image.style.filter =\n            \"progid:DXImageTransform.Microsoft.AlphaImageLoader(\" + \n            \"src='', sizingMethod='scale')\";\n\n        var rot = rotation * Math.PI / 180;\n        var sintheta = Math.sin(rot);\n        var costheta = Math.cos(rot);\n        var filter =\n            \"progid:DXImageTransform.Microsoft.Matrix(M11=\" + costheta +\n            \",M12=\" + (-sintheta) + \",M21=\" + sintheta + \",M22=\" + costheta +\n            \",SizingMethod='auto expand')\\n\";\n        var opacity = style.graphicOpacity || style.fillOpacity;\n        if (opacity && opacity != 1) {\n            filter += \n                \"progid:DXImageTransform.Microsoft.BasicImage(opacity=\" + \n                opacity+\")\\n\";\n        }\n        node.style.filter = filter;\n        var centerPoint = new OpenLayers.Geometry.Point(-xOffset, -yOffset);\n        var imgBox = new OpenLayers.Bounds(0, 0, width, height).toGeometry();\n        imgBox.rotate(style.rotation, centerPoint);\n        var imgBounds = imgBox.getBounds();\n\n        node.style.left = Math.round(\n            parseInt(node.style.left) + imgBounds.left) + \"px\";\n        node.style.top = Math.round(\n            parseInt(node.style.top) - imgBounds.bottom) + \"px\";\n    },\n\n        postDraw: function(node) {\n        node.style.visibility = \"visible\";\n        var fillColor = node._style.fillColor;\n        var strokeColor = node._style.strokeColor;\n        if (fillColor == \"none\" &&\n                node.fillcolor != fillColor) {\n            node.fillcolor = fillColor;\n        }\n        if (strokeColor == \"none\" &&\n                node.strokecolor != strokeColor) {\n            node.strokecolor = strokeColor;\n        }\n    },\n\n\n        setNodeDimension: function(node, geometry) {\n\n        var bbox = geometry.getBounds();\n        if(bbox) {\n            var resolution = this.getResolution();\n        \n            var scaledBox = \n                new OpenLayers.Bounds(((bbox.left - this.featureDx)/resolution - this.offset.x) | 0,\n                                      (bbox.bottom/resolution - this.offset.y) | 0,\n                                      ((bbox.right - this.featureDx)/resolution - this.offset.x) | 0,\n                                      (bbox.top/resolution - this.offset.y) | 0);\n            node.style.left = scaledBox.left + \"px\";\n            node.style.top = scaledBox.top + \"px\";\n            node.style.width = scaledBox.getWidth() + \"px\";\n            node.style.height = scaledBox.getHeight() + \"px\";\n    \n            node.coordorigin = scaledBox.left + \" \" + scaledBox.top;\n            node.coordsize = scaledBox.getWidth()+ \" \" + scaledBox.getHeight();\n        }\n    },\n    \n        dashStyle: function(style) {\n        var dash = style.strokeDashstyle;\n        switch (dash) {\n            case 'solid':\n            case 'dot':\n            case 'dash':\n            case 'dashdot':\n            case 'longdash':\n            case 'longdashdot':\n                return dash;\n            default:\n                var parts = dash.split(/[ ,]/);\n                if (parts.length == 2) {\n                    if (1*parts[0] >= 2*parts[1]) {\n                        return \"longdash\";\n                    }\n                    return (parts[0] == 1 || parts[1] == 1) ? \"dot\" : \"dash\";\n                } else if (parts.length == 4) {\n                    return (1*parts[0] >= 2*parts[1]) ? \"longdashdot\" :\n                        \"dashdot\";\n                }\n                return \"solid\";\n        }\n    },\n\n        createNode: function(type, id) {\n        var node = document.createElement(type);\n        if (id) {\n            node.id = id;\n        }\n        node.unselectable = 'on';\n        node.onselectstart = OpenLayers.Function.False;\n        \n        return node;    \n    },\n    \n        nodeTypeCompare: function(node, type) {\n        var subType = type;\n        var splitIndex = subType.indexOf(\":\");\n        if (splitIndex != -1) {\n            subType = subType.substr(splitIndex+1);\n        }\n        var nodeName = node.nodeName;\n        splitIndex = nodeName.indexOf(\":\");\n        if (splitIndex != -1) {\n            nodeName = nodeName.substr(splitIndex+1);\n        }\n\n        return (subType == nodeName);\n    },\n\n        createRenderRoot: function() {\n        return this.nodeFactory(this.container.id + \"_vmlRoot\", \"div\");\n    },\n\n        createRoot: function(suffix) {\n        return this.nodeFactory(this.container.id + suffix, \"olv:group\");\n    },\n    \n        \n        drawPoint: function(node, geometry) {\n        return this.drawCircle(node, geometry, 1);\n    },\n\n        drawCircle: function(node, geometry, radius) {\n        if(!isNaN(geometry.x)&& !isNaN(geometry.y)) {\n            var resolution = this.getResolution();\n\n            node.style.left = ((((geometry.x - this.featureDx) /resolution - this.offset.x) | 0) - radius) + \"px\";\n            node.style.top = (((geometry.y /resolution - this.offset.y) | 0) - radius) + \"px\";\n    \n            var diameter = radius * 2;\n            \n            node.style.width = diameter + \"px\";\n            node.style.height = diameter + \"px\";\n            return node;\n        }\n        return false;\n    },\n\n\n        drawLineString: function(node, geometry) {\n        return this.drawLine(node, geometry, false);\n    },\n\n        drawLinearRing: function(node, geometry) {\n        return this.drawLine(node, geometry, true);\n    },\n\n        drawLine: function(node, geometry, closeLine) {\n\n        this.setNodeDimension(node, geometry);\n\n        var resolution = this.getResolution();\n        var numComponents = geometry.components.length;\n        var parts = new Array(numComponents);\n\n        var comp, x, y;\n        for (var i = 0; i < numComponents; i++) {\n            comp = geometry.components[i];\n            x = ((comp.x - this.featureDx)/resolution - this.offset.x) | 0;\n            y = (comp.y/resolution - this.offset.y) | 0;\n            parts[i] = \" \" + x + \",\" + y + \" l \";\n        }\n        var end = (closeLine) ? \" x e\" : \" e\";\n        node.path = \"m\" + parts.join(\"\") + end;\n        return node;\n    },\n\n        drawPolygon: function(node, geometry) {\n        this.setNodeDimension(node, geometry);\n\n        var resolution = this.getResolution();\n    \n        var path = [];\n        var j, jj, points, area, first, second, i, ii, comp, pathComp, x, y;\n        for (j=0, jj=geometry.components.length; j<jj; j++) {\n            path.push(\"m\");\n            points = geometry.components[j].components;\n            area = (j === 0);\n            first = null;\n            second = null;\n            for (i=0, ii=points.length; i<ii; i++) {\n                comp = points[i];\n                x = ((comp.x - this.featureDx) / resolution - this.offset.x) | 0;\n                y = (comp.y / resolution - this.offset.y) | 0;\n                pathComp = \" \" + x + \",\" + y;\n                path.push(pathComp);\n                if (i==0) {\n                    path.push(\" l\");\n                }\n                if (!area) {\n                    if (!first) {\n                        first = pathComp;\n                    } else if (first != pathComp) {\n                        if (!second) {\n                            second = pathComp;\n                        } else if (second != pathComp) {\n                            area = true;\n                        }\n                    }\n                }\n            }\n            path.push(area ? \" x \" : \" \");\n        }\n        path.push(\"e\");\n        node.path = path.join(\"\");\n        return node;\n    },\n\n        drawRectangle: function(node, geometry) {\n        var resolution = this.getResolution();\n    \n        node.style.left = (((geometry.x - this.featureDx)/resolution - this.offset.x) | 0) + \"px\";\n        node.style.top = ((geometry.y/resolution - this.offset.y) | 0) + \"px\";\n        node.style.width = ((geometry.width/resolution) | 0) + \"px\";\n        node.style.height = ((geometry.height/resolution) | 0) + \"px\";\n        \n        return node;\n    },\n    \n        drawText: function(featureId, style, location) {\n        var label = this.nodeFactory(featureId + this.LABEL_ID_SUFFIX, \"olv:rect\");\n        var textbox = this.nodeFactory(featureId + this.LABEL_ID_SUFFIX + \"_textbox\", \"olv:textbox\");\n        \n        var resolution = this.getResolution();\n        label.style.left = (((location.x - this.featureDx)/resolution - this.offset.x) | 0) + \"px\";\n        label.style.top = ((location.y/resolution - this.offset.y) | 0) + \"px\";\n        label.style.flip = \"y\";\n\n        textbox.innerText = style.label;\n\n        if (style.cursor != \"inherit\" && style.cursor != null) {\n            textbox.style.cursor = style.cursor;\n        }\n        if (style.fontColor) {\n            textbox.style.color = style.fontColor;\n        }\n        if (style.fontOpacity) {\n            textbox.style.filter = 'alpha(opacity=' + (style.fontOpacity * 100) + ')';\n        }\n        if (style.fontFamily) {\n            textbox.style.fontFamily = style.fontFamily;\n        }\n        if (style.fontSize) {\n            textbox.style.fontSize = style.fontSize;\n        }\n        if (style.fontWeight) {\n            textbox.style.fontWeight = style.fontWeight;\n        }\n        if (style.fontStyle) {\n            textbox.style.fontStyle = style.fontStyle;\n        }\n        if(style.labelSelect === true) {\n            label._featureId = featureId;\n            textbox._featureId = featureId;\n            textbox._geometry = location;\n            textbox._geometryClass = location.CLASS_NAME;\n        }\n        textbox.style.whiteSpace = \"nowrap\";\n        textbox.inset = \"1px,0px,0px,0px\";\n\n        if(!label.parentNode) {\n            label.appendChild(textbox);\n            this.textRoot.appendChild(label);\n        }\n\n        var align = style.labelAlign || \"cm\";\n        if (align.length == 1) {\n            align += \"m\";\n        }\n        var xshift = textbox.clientWidth *\n            (OpenLayers.Renderer.VML.LABEL_SHIFT[align.substr(0,1)]);\n        var yshift = textbox.clientHeight *\n            (OpenLayers.Renderer.VML.LABEL_SHIFT[align.substr(1,1)]);\n        label.style.left = parseInt(label.style.left)-xshift-1+\"px\";\n        label.style.top = parseInt(label.style.top)+yshift+\"px\";\n        \n    },\n    \n        moveRoot: function(renderer) {\n        var layer = this.map.getLayer(renderer.container.id);\n        if(layer instanceof OpenLayers.Layer.Vector.RootContainer) {\n            layer = this.map.getLayer(this.container.id);\n        }\n        layer && layer.renderer.clear();\n        OpenLayers.Renderer.Elements.prototype.moveRoot.apply(this, arguments);\n        layer && layer.redraw();\n    },\n    \n    OpenLayers.Renderer.VML.LABEL_SHIFT = {\n    \"l\": 0,\n    \"c\": .5,\n    \"r\": 1,\n    \"t\": 0,\n    \"m\": .5,\n    \"b\": 1\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Renderer.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Renderer = OpenLayers.Class({\n\n        container: null,\n    \n        root: null,\n\n        extent: null,\n\n        size: null,\n    \n        resolution: null,\n    \n        map: null,\n    \n        featureDx: 0,\n    \n        initialize: function(containerID, options) {\n        this.container = OpenLayers.Util.getElement(containerID);\n        OpenLayers.Util.extend(this, options);\n    },\n    \n        destroy: function() {\n        this.container = null;\n        this.extent = null;\n        this.size =  null;\n        this.resolution = null;\n        this.map = null;\n    },\n\n        supported: function() {\n        return false;\n    },    \n    \n        setExtent: function(extent, resolutionChanged) {\n        this.extent = extent.clone();\n        if (this.map.baseLayer && this.map.baseLayer.wrapDateLine) {\n            var ratio = extent.getWidth() / this.map.getExtent().getWidth(),\n                extent = extent.scale(1 / ratio);\n            this.extent = extent.wrapDateLine(this.map.getMaxExtent()).scale(ratio);\n        }\n        if (resolutionChanged) {\n            this.resolution = null;\n        }\n        return true;\n    },\n    \n        setSize: function(size) {\n        this.size = size.clone();\n        this.resolution = null;\n    },\n    \n        getResolution: function() {\n        this.resolution = this.resolution || this.map.getResolution();\n        return this.resolution;\n    },\n    \n        drawFeature: function(feature, style) {\n        if(style == null) {\n            style = feature.style;\n        }\n        if (feature.geometry) {\n            var bounds = feature.geometry.getBounds();\n            if(bounds) {\n                var worldBounds;\n                if (this.map.baseLayer && this.map.baseLayer.wrapDateLine) {\n                    worldBounds = this.map.getMaxExtent();\n                }\n                if (!bounds.intersectsBounds(this.extent, {worldBounds: worldBounds})) {\n                    style = {display: \"none\"};\n                } else {\n                    this.calculateFeatureDx(bounds, worldBounds);\n                }\n                var rendered = this.drawGeometry(feature.geometry, style, feature.id);\n                if(style.display != \"none\" && style.label && rendered !== false) {\n\n                    var location = feature.geometry.getCentroid(); \n                    if(style.labelXOffset || style.labelYOffset) {\n                        var xOffset = isNaN(style.labelXOffset) ? 0 : style.labelXOffset;\n                        var yOffset = isNaN(style.labelYOffset) ? 0 : style.labelYOffset;\n                        var res = this.getResolution();\n                        location.move(xOffset*res, yOffset*res);\n                    }\n                    this.drawText(feature.id, style, location);\n                } else {\n                    this.removeText(feature.id);\n                }\n                return rendered;\n            }\n        }\n    },\n\n        calculateFeatureDx: function(bounds, worldBounds) {\n        this.featureDx = 0;\n        if (worldBounds) {\n            var worldWidth = worldBounds.getWidth(),\n                rendererCenterX = (this.extent.left + this.extent.right) / 2,\n                featureCenterX = (bounds.left + bounds.right) / 2,\n                worldsAway = Math.round((featureCenterX - rendererCenterX) / worldWidth);\n            this.featureDx = worldsAway * worldWidth;\n        }\n    },\n\n        drawGeometry: function(geometry, style, featureId) {},\n        \n        drawText: function(featureId, style, location) {},\n\n        removeText: function(featureId) {},\n    \n        getFeatureIdFromEvent: function(evt) {},\n    \n        eraseFeatures: function(features) {\n        if(!(OpenLayers.Util.isArray(features))) {\n            features = [features];\n        }\n        for(var i=0, len=features.length; i<len; ++i) {\n            var feature = features[i];\n            this.eraseGeometry(feature.geometry, feature.id);\n            this.removeText(feature.id);\n        }\n    },\n    \n        eraseGeometry: function(geometry, featureId) {},\n    \n        moveRoot: function(renderer) {},\n\n        getRenderLayerId: function() {\n        return this.container.id;\n    },\n    \n        applyDefaultSymbolizer: function(symbolizer) {\n        var result = OpenLayers.Util.extend({},\n            OpenLayers.Renderer.defaultSymbolizer);\n        if(symbolizer.stroke === false) {\n            delete result.strokeWidth;\n            delete result.strokeColor;\n        }\n        if(symbolizer.fill === false) {\n            delete result.fillColor;\n        }\n        OpenLayers.Util.extend(result, symbolizer);\n        return result;\n    },\n\n    CLASS_NAME: \"OpenLayers.Renderer\"\n});\n\nOpenLayers.Renderer.defaultSymbolizer = {\n    fillColor: \"#000000\",\n    strokeColor: \"#000000\",\n    strokeWidth: 2,\n    fillOpacity: 1,\n    strokeOpacity: 1,\n    pointRadius: 0,\n    labelAlign: 'cm'\n};\n    \n\n\nOpenLayers.Renderer.symbol = {\n    \"star\": [350,75, 379,161, 469,161, 397,215, 423,301, 350,250, 277,301,\n            303,215, 231,161, 321,161, 350,75],\n    \"cross\": [4,0, 6,0, 6,4, 10,4, 10,6, 6,6, 6,10, 4,10, 4,6, 0,6, 0,4, 4,4,\n            4,0],\n    \"x\": [0,0, 25,0, 50,35, 75,0, 100,0, 65,50, 100,100, 75,100, 50,65, 25,100, 0,100, 35,50, 0,0],\n    \"square\": [0,0, 0,1, 1,1, 1,0, 0,0],\n    \"triangle\": [0,10, 10,10, 5,0, 0,10]\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Request/XMLHttpRequest.js",
    "content": "\n\n(function () {\n    var oXMLHttpRequest    = window.XMLHttpRequest;\n    var bGecko    = !!window.controllers,\n        bIE        = window.document.all && !window.opera,\n        bIE7    = bIE && window.navigator.userAgent.match(/MSIE 7.0/);\n    function fXMLHttpRequest() {\n        this._object    = oXMLHttpRequest && !bIE7 ? new oXMLHttpRequest : new window.ActiveXObject(\"Microsoft.XMLHTTP\");\n        this._listeners    = [];\n    };\n    function cXMLHttpRequest() {\n        return new fXMLHttpRequest;\n    };\n    cXMLHttpRequest.prototype    = fXMLHttpRequest.prototype;\n    if (bGecko && oXMLHttpRequest.wrapped)\n        cXMLHttpRequest.wrapped    = oXMLHttpRequest.wrapped;\n    cXMLHttpRequest.UNSENT                = 0;\n    cXMLHttpRequest.OPENED                = 1;\n    cXMLHttpRequest.HEADERS_RECEIVED    = 2;\n    cXMLHttpRequest.LOADING                = 3;\n    cXMLHttpRequest.DONE                = 4;\n    cXMLHttpRequest.prototype.readyState    = cXMLHttpRequest.UNSENT;\n    cXMLHttpRequest.prototype.responseText    = '';\n    cXMLHttpRequest.prototype.responseXML    = null;\n    cXMLHttpRequest.prototype.status        = 0;\n    cXMLHttpRequest.prototype.statusText    = '';\n    cXMLHttpRequest.prototype.priority        = \"NORMAL\";\n    cXMLHttpRequest.prototype.onreadystatechange    = null;\n    cXMLHttpRequest.onreadystatechange    = null;\n    cXMLHttpRequest.onopen                = null;\n    cXMLHttpRequest.onsend                = null;\n    cXMLHttpRequest.onabort                = null;\n    cXMLHttpRequest.prototype.open    = function(sMethod, sUrl, bAsync, sUser, sPassword) {\n        delete this._headers;\n        if (arguments.length < 3)\n            bAsync    = true;\n        this._async        = bAsync;\n        var oRequest    = this,\n            nState        = this.readyState,\n            fOnUnload;\n        if (bIE && bAsync) {\n            fOnUnload = function() {\n                if (nState != cXMLHttpRequest.DONE) {\n                    fCleanTransport(oRequest);\n                    oRequest.abort();\n                }\n            };\n            window.attachEvent(\"onunload\", fOnUnload);\n        }\n        if (cXMLHttpRequest.onopen)\n            cXMLHttpRequest.onopen.apply(this, arguments);\n\n        if (arguments.length > 4)\n            this._object.open(sMethod, sUrl, bAsync, sUser, sPassword);\n        else\n        if (arguments.length > 3)\n            this._object.open(sMethod, sUrl, bAsync, sUser);\n        else\n            this._object.open(sMethod, sUrl, bAsync);\n\n        this.readyState    = cXMLHttpRequest.OPENED;\n        fReadyStateChange(this);\n\n        this._object.onreadystatechange    = function() {\n            if (bGecko && !bAsync)\n                return;\n            oRequest.readyState        = oRequest._object.readyState;\n            fSynchronizeValues(oRequest);\n            if (oRequest._aborted) {\n                oRequest.readyState    = cXMLHttpRequest.UNSENT;\n                return;\n            }\n\n            if (oRequest.readyState == cXMLHttpRequest.DONE) {\n                delete oRequest._data;\n/*                if (bAsync)\n                    fQueue_remove(oRequest);*/\n                fCleanTransport(oRequest);\n/*\n                if (!oRequest._object.getResponseHeader(\"Date\")) {\n                    oRequest._cached    = oRequest._object;\n                    cXMLHttpRequest.call(oRequest);\n                    if (sUser) {\n                         if (sPassword)\n                            oRequest._object.open(sMethod, sUrl, bAsync, sUser, sPassword);\n                        else\n                            oRequest._object.open(sMethod, sUrl, bAsync, sUser);\n                    }\n                    else\n                        oRequest._object.open(sMethod, sUrl, bAsync);\n                    oRequest._object.setRequestHeader(\"If-Modified-Since\", oRequest._cached.getResponseHeader(\"Last-Modified\") || new window.Date(0));\n                    if (oRequest._headers)\n                        for (var sHeader in oRequest._headers)\n                            if (typeof oRequest._headers[sHeader] == \"string\")    // Some frameworks prototype objects with functions\n                                oRequest._object.setRequestHeader(sHeader, oRequest._headers[sHeader]);\n\n                    oRequest._object.onreadystatechange    = function() {\n                        oRequest.readyState        = oRequest._object.readyState;\n\n                        if (oRequest._aborted) {\n                            oRequest.readyState    = cXMLHttpRequest.UNSENT;\n                            return;\n                        }\n\n                        if (oRequest.readyState == cXMLHttpRequest.DONE) {\n                            fCleanTransport(oRequest);\n                            if (oRequest.status == 304)\n                                oRequest._object    = oRequest._cached;\n                            delete oRequest._cached;\n                            fSynchronizeValues(oRequest);\n                            fReadyStateChange(oRequest);\n                            if (bIE && bAsync)\n                                window.detachEvent(\"onunload\", fOnUnload);\n                        }\n                    };\n                    oRequest._object.send(null);\n                    return;\n                };\n*/\n                if (bIE && bAsync)\n                    window.detachEvent(\"onunload\", fOnUnload);\n            }\n            if (nState != oRequest.readyState)\n                fReadyStateChange(oRequest);\n\n            nState    = oRequest.readyState;\n        }\n    };\n    function fXMLHttpRequest_send(oRequest) {\n        oRequest._object.send(oRequest._data);\n        if (bGecko && !oRequest._async) {\n            oRequest.readyState    = cXMLHttpRequest.OPENED;\n            fSynchronizeValues(oRequest);\n            while (oRequest.readyState < cXMLHttpRequest.DONE) {\n                oRequest.readyState++;\n                fReadyStateChange(oRequest);\n                if (oRequest._aborted)\n                    return;\n            }\n        }\n    };\n    cXMLHttpRequest.prototype.send    = function(vData) {\n        if (cXMLHttpRequest.onsend)\n            cXMLHttpRequest.onsend.apply(this, arguments);\n\n        if (!arguments.length)\n            vData    = null;\n        if (vData && vData.nodeType) {\n            vData    = window.XMLSerializer ? new window.XMLSerializer().serializeToString(vData) : vData.xml;\n            if (!this._headers[\"Content-Type\"])\n                this._object.setRequestHeader(\"Content-Type\", \"application/xml\");\n        }\n\n        this._data    = vData;\n/*\n        if (this._async)\n            fQueue_add(this);\n        else*/\n            fXMLHttpRequest_send(this);\n    };\n    cXMLHttpRequest.prototype.abort    = function() {\n        if (cXMLHttpRequest.onabort)\n            cXMLHttpRequest.onabort.apply(this, arguments);\n        if (this.readyState > cXMLHttpRequest.UNSENT)\n            this._aborted    = true;\n\n        this._object.abort();\n        fCleanTransport(this);\n\n        this.readyState    = cXMLHttpRequest.UNSENT;\n\n        delete this._data;\n/*        if (this._async)\n            fQueue_remove(this);*/\n    };\n    cXMLHttpRequest.prototype.getAllResponseHeaders    = function() {\n        return this._object.getAllResponseHeaders();\n    };\n    cXMLHttpRequest.prototype.getResponseHeader    = function(sName) {\n        return this._object.getResponseHeader(sName);\n    };\n    cXMLHttpRequest.prototype.setRequestHeader    = function(sName, sValue) {\n        if (!this._headers)\n            this._headers    = {};\n        this._headers[sName]    = sValue;\n\n        return this._object.setRequestHeader(sName, sValue);\n    };\n    cXMLHttpRequest.prototype.addEventListener    = function(sName, fHandler, bUseCapture) {\n        for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++)\n            if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture)\n                return;\n        this._listeners.push([sName, fHandler, bUseCapture]);\n    };\n\n    cXMLHttpRequest.prototype.removeEventListener    = function(sName, fHandler, bUseCapture) {\n        for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++)\n            if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture)\n                break;\n        if (oListener)\n            this._listeners.splice(nIndex, 1);\n    };\n\n    cXMLHttpRequest.prototype.dispatchEvent    = function(oEvent) {\n        var oEventPseudo    = {\n            'type':            oEvent.type,\n            'target':        this,\n            'currentTarget':this,\n            'eventPhase':    2,\n            'bubbles':        oEvent.bubbles,\n            'cancelable':    oEvent.cancelable,\n            'timeStamp':    oEvent.timeStamp,\n            'stopPropagation':    function() {},    // There is no flow\n            'preventDefault':    function() {},    // There is no default action\n            'initEvent':        function() {}    // Original event object should be initialized\n        };\n        if (oEventPseudo.type == \"readystatechange\" && this.onreadystatechange)\n            (this.onreadystatechange.handleEvent || this.onreadystatechange).apply(this, [oEventPseudo]);\n        for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++)\n            if (oListener[0] == oEventPseudo.type && !oListener[2])\n                (oListener[1].handleEvent || oListener[1]).apply(this, [oEventPseudo]);\n    };\n    cXMLHttpRequest.prototype.toString    = function() {\n        return '[' + \"object\" + ' ' + \"XMLHttpRequest\" + ']';\n    };\n\n    cXMLHttpRequest.toString    = function() {\n        return '[' + \"XMLHttpRequest\" + ']';\n    };\n    function fReadyStateChange(oRequest) {\n        if (cXMLHttpRequest.onreadystatechange)\n            cXMLHttpRequest.onreadystatechange.apply(oRequest);\n        oRequest.dispatchEvent({\n            'type':            \"readystatechange\",\n            'bubbles':        false,\n            'cancelable':    false,\n            'timeStamp':    new Date + 0\n        });\n    };\n\n    function fGetDocument(oRequest) {\n        var oDocument    = oRequest.responseXML,\n            sResponse    = oRequest.responseText;\n        if (bIE && sResponse && oDocument && !oDocument.documentElement && oRequest.getResponseHeader(\"Content-Type\").match(/[^\\/]+\\/[^\\+]+\\+xml/)) {\n            oDocument    = new window.ActiveXObject(\"Microsoft.XMLDOM\");\n            oDocument.async                = false;\n            oDocument.validateOnParse    = false;\n            oDocument.loadXML(sResponse);\n        }\n        if (oDocument)\n            if ((bIE && oDocument.parseError != 0) || !oDocument.documentElement || (oDocument.documentElement && oDocument.documentElement.tagName == \"parsererror\"))\n                return null;\n        return oDocument;\n    };\n\n    function fSynchronizeValues(oRequest) {\n        try {    oRequest.responseText    = oRequest._object.responseText;    } catch (e) {}\n        try {    oRequest.responseXML    = fGetDocument(oRequest._object);    } catch (e) {}\n        try {    oRequest.status            = oRequest._object.status;            } catch (e) {}\n        try {    oRequest.statusText        = oRequest._object.statusText;        } catch (e) {}\n    };\n\n    function fCleanTransport(oRequest) {\n        oRequest._object.onreadystatechange    = new window.Function;\n    };\n/*\n    var oQueuePending    = {\"CRITICAL\":[],\"HIGH\":[],\"NORMAL\":[],\"LOW\":[],\"LOWEST\":[]},\n        aQueueRunning    = [];\n    function fQueue_add(oRequest) {\n        oQueuePending[oRequest.priority in oQueuePending ? oRequest.priority : \"NORMAL\"].push(oRequest);\n        setTimeout(fQueue_process);\n    };\n\n    function fQueue_remove(oRequest) {\n        for (var nIndex = 0, bFound    = false; nIndex < aQueueRunning.length; nIndex++)\n            if (bFound)\n                aQueueRunning[nIndex - 1]    = aQueueRunning[nIndex];\n            else\n            if (aQueueRunning[nIndex] == oRequest)\n                bFound    = true;\n        if (bFound)\n            aQueueRunning.length--;\n        setTimeout(fQueue_process);\n    };\n\n    function fQueue_process() {\n        if (aQueueRunning.length < 6) {\n            for (var sPriority in oQueuePending) {\n                if (oQueuePending[sPriority].length) {\n                    var oRequest    = oQueuePending[sPriority][0];\n                    oQueuePending[sPriority]    = oQueuePending[sPriority].slice(1);\n                    aQueueRunning.push(oRequest);\n                    fXMLHttpRequest_send(oRequest);\n                    break;\n                }\n            }\n        }\n    };\n*/\n    if (!window.Function.prototype.apply) {\n        window.Function.prototype.apply    = function(oRequest, oArguments) {\n            if (!oArguments)\n                oArguments    = [];\n            oRequest.__func    = this;\n            oRequest.__func(oArguments[0], oArguments[1], oArguments[2], oArguments[3], oArguments[4]);\n            delete oRequest.__func;\n        };\n    };\n        if (!OpenLayers.Request) {\n                OpenLayers.Request = {};\n    }\n    OpenLayers.Request.XMLHttpRequest = cXMLHttpRequest;\n})();\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Request.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.ProxyHost = \"\";\n\nif (!OpenLayers.Request) {\n        OpenLayers.Request = {};\n}\nOpenLayers.Util.extend(OpenLayers.Request, {\n    \n        DEFAULT_CONFIG: {\n        method: \"GET\",\n        url: window.location.href,\n        async: true,\n        user: undefined,\n        password: undefined,\n        params: null,\n        proxy: OpenLayers.ProxyHost,\n        headers: {},\n        data: null,\n        callback: function() {},\n        success: null,\n        failure: null,\n        scope: null\n    },\n    \n        URL_SPLIT_REGEX: /([^:]*:)\\/\\/([^:]*:?[^@]*@)?([^:\\/\\?]*):?([^\\/\\?]*)/,\n    \n        events: new OpenLayers.Events(this),\n    \n        makeSameOrigin: function(url, proxy) {\n        var sameOrigin = url.indexOf(\"http\") !== 0;\n        var urlParts = !sameOrigin && url.match(this.URL_SPLIT_REGEX);\n        if (urlParts) {\n            var location = window.location;\n            sameOrigin =\n                urlParts[1] == location.protocol &&\n                urlParts[3] == location.hostname;\n            var uPort = urlParts[4], lPort = location.port;\n            if (uPort != 80 && uPort != \"\" || lPort != \"80\" && lPort != \"\") {\n                sameOrigin = sameOrigin && uPort == lPort;\n            }\n        }\n        if (!sameOrigin) {\n            if (proxy) {\n                if (typeof proxy == \"function\") {\n                    url = proxy(url);\n                } else {\n                    url = proxy + encodeURIComponent(url);\n                }\n            }\n        }\n        return url;\n    },\n\n        issue: function(config) {        \n        var defaultConfig = OpenLayers.Util.extend(\n            this.DEFAULT_CONFIG,\n            {proxy: OpenLayers.ProxyHost}\n        );\n        config = config || {};\n        config.headers = config.headers || {};\n        config = OpenLayers.Util.applyDefaults(config, defaultConfig);\n        config.headers = OpenLayers.Util.applyDefaults(config.headers, defaultConfig.headers);\n        var customRequestedWithHeader = false,\n            headerKey;\n        for(headerKey in config.headers) {\n            if (config.headers.hasOwnProperty( headerKey )) {\n                if (headerKey.toLowerCase() === 'x-requested-with') {\n                    customRequestedWithHeader = true;\n                }\n            }\n        }\n        if (customRequestedWithHeader === false) {\n            config.headers['X-Requested-With'] = 'XMLHttpRequest';\n        }\n        var request = new OpenLayers.Request.XMLHttpRequest();\n        var url = OpenLayers.Util.urlAppend(config.url, \n            OpenLayers.Util.getParameterString(config.params || {}));\n        url = OpenLayers.Request.makeSameOrigin(url, config.proxy);\n        request.open(\n            config.method, url, config.async, config.user, config.password\n        );\n        for(var header in config.headers) {\n            request.setRequestHeader(header, config.headers[header]);\n        }\n\n        var events = this.events;\n        var self = this;\n        \n        request.onreadystatechange = function() {\n            if(request.readyState == OpenLayers.Request.XMLHttpRequest.DONE) {\n                var proceed = events.triggerEvent(\n                    \"complete\",\n                    {request: request, config: config, requestUrl: url}\n                );\n                if(proceed !== false) {\n                    self.runCallbacks(\n                        {request: request, config: config, requestUrl: url}\n                    );\n                }\n            }\n        };\n        if(config.async === false) {\n            request.send(config.data);\n        } else {\n            window.setTimeout(function(){\n                if (request.readyState !== 0) { // W3C: 0-UNSENT\n                    request.send(config.data);\n                }\n            }, 0);\n        }\n        return request;\n    },\n    \n        runCallbacks: function(options) {\n        var request = options.request;\n        var config = options.config;\n        var complete = (config.scope) ?\n            OpenLayers.Function.bind(config.callback, config.scope) :\n            config.callback;\n        var success;\n        if(config.success) {\n            success = (config.scope) ?\n                OpenLayers.Function.bind(config.success, config.scope) :\n                config.success;\n        }\n        var failure;\n        if(config.failure) {\n            failure = (config.scope) ?\n                OpenLayers.Function.bind(config.failure, config.scope) :\n                config.failure;\n        }\n\n        if (OpenLayers.Util.createUrlObject(config.url).protocol == \"file:\" &&\n                                                        request.responseText) {\n            request.status = 200;\n        }\n        complete(request);\n\n        if (!request.status || (request.status >= 200 && request.status < 300)) {\n            this.events.triggerEvent(\"success\", options);\n            if(success) {\n                success(request);\n            }\n        }\n        if(request.status && (request.status < 200 || request.status >= 300)) {                    \n            this.events.triggerEvent(\"failure\", options);\n            if(failure) {\n                failure(request);\n            }\n        }\n    },\n    \n        GET: function(config) {\n        config = OpenLayers.Util.extend(config, {method: \"GET\"});\n        return OpenLayers.Request.issue(config);\n    },\n    \n        POST: function(config) {\n        config = OpenLayers.Util.extend(config, {method: \"POST\"});\n        config.headers = config.headers ? config.headers : {};\n        if(!(\"CONTENT-TYPE\" in OpenLayers.Util.upperCaseObject(config.headers))) {\n            config.headers[\"Content-Type\"] = \"application/xml\";\n        }\n        return OpenLayers.Request.issue(config);\n    },\n    \n        PUT: function(config) {\n        config = OpenLayers.Util.extend(config, {method: \"PUT\"});\n        config.headers = config.headers ? config.headers : {};\n        if(!(\"CONTENT-TYPE\" in OpenLayers.Util.upperCaseObject(config.headers))) {\n            config.headers[\"Content-Type\"] = \"application/xml\";\n        }\n        return OpenLayers.Request.issue(config);\n    },\n    \n        DELETE: function(config) {\n        config = OpenLayers.Util.extend(config, {method: \"DELETE\"});\n        return OpenLayers.Request.issue(config);\n    },\n  \n        HEAD: function(config) {\n        config = OpenLayers.Util.extend(config, {method: \"HEAD\"});\n        return OpenLayers.Request.issue(config);\n    },\n    \n        OPTIONS: function(config) {\n        config = OpenLayers.Util.extend(config, {method: \"OPTIONS\"});\n        return OpenLayers.Request.issue(config);\n    }\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Rule.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Rule = OpenLayers.Class({\n    \n        id: null,\n    \n        name: null,\n    \n        title: null,\n    \n        description: null,\n\n        context: null,\n    \n        filter: null,\n\n        elseFilter: false,\n    \n        symbolizer: null,\n    \n        symbolizers: null,\n    \n        minScaleDenominator: null,\n\n        maxScaleDenominator: null,\n    \n        initialize: function(options) {\n        this.symbolizer = {};\n        OpenLayers.Util.extend(this, options);\n        if (this.symbolizers) {\n            delete this.symbolizer;\n        }\n        this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + \"_\");\n    },\n\n        destroy: function() {\n        for (var i in this.symbolizer) {\n            this.symbolizer[i] = null;\n        }\n        this.symbolizer = null;\n        delete this.symbolizers;\n    },\n    \n        evaluate: function(feature) {\n        var context = this.getContext(feature);\n        var applies = true;\n\n        if (this.minScaleDenominator || this.maxScaleDenominator) {\n            var scale = feature.layer.map.getScale();\n        }\n        if (this.minScaleDenominator) {\n            applies = scale >= OpenLayers.Style.createLiteral(\n                    this.minScaleDenominator, context);\n        }\n        if (applies && this.maxScaleDenominator) {\n            applies = scale < OpenLayers.Style.createLiteral(\n                    this.maxScaleDenominator, context);\n        }\n        if(applies && this.filter) {\n            if(this.filter.CLASS_NAME == \"OpenLayers.Filter.FeatureId\") {\n                applies = this.filter.evaluate(feature);\n            } else {\n                applies = this.filter.evaluate(context);\n            }\n        }\n\n        return applies;\n    },\n    \n        getContext: function(feature) {\n        var context = this.context;\n        if (!context) {\n            context = feature.attributes || feature.data;\n        }\n        if (typeof this.context == \"function\") {\n            context = this.context(feature);\n        }\n        return context;\n    },\n    \n        clone: function() {\n        var options = OpenLayers.Util.extend({}, this);\n        if (this.symbolizers) {\n            var len = this.symbolizers.length;\n            options.symbolizers = new Array(len);\n            for (var i=0; i<len; ++i) {\n                options.symbolizers[i] = this.symbolizers[i].clone();\n            }\n        } else {\n            options.symbolizer = {};\n            var value, type;\n            for(var key in this.symbolizer) {\n                value = this.symbolizer[key];\n                type = typeof value;\n                if(type === \"object\") {\n                    options.symbolizer[key] = OpenLayers.Util.extend({}, value);\n                } else if(type === \"string\") {\n                    options.symbolizer[key] = value;\n                }\n            }\n        }\n        options.filter = this.filter && this.filter.clone();\n        options.context = this.context && OpenLayers.Util.extend({}, this.context);\n        return new OpenLayers.Rule(options);\n    },\n        \n    CLASS_NAME: \"OpenLayers.Rule\"\n});"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/SingleFile.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\nvar OpenLayers = {\n        VERSION_NUMBER: \"Release 2.14 dev\",\n\n        singleFile: true,\n\n        _getScriptLocation: (function() {\n        var r = new RegExp(\"(^|(.*?\\\\/))(OpenLayers[^\\\\/]*?\\\\.js)(\\\\?|$)\"),\n            s = document.getElementsByTagName('script'),\n            src, m, l = \"\";\n        for(var i=0, len=s.length; i<len; i++) {\n            src = s[i].getAttribute('src');\n            if(src) {\n                m = src.match(r);\n                if(m) {\n                    l = m[1];\n                    break;\n                }\n            }\n        }\n        return (function() { return l; });\n    })(),\n    \n        ImgPath : ''\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Spherical.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Spherical = OpenLayers.Spherical || {};\n\nOpenLayers.Spherical.DEFAULT_RADIUS = 6378137;\n\nOpenLayers.Spherical.computeDistanceBetween = function(from, to, radius) {\n  var R = radius || OpenLayers.Spherical.DEFAULT_RADIUS;\n  var sinHalfDeltaLon = Math.sin(Math.PI * (to.lon - from.lon) / 360);\n  var sinHalfDeltaLat = Math.sin(Math.PI * (to.lat - from.lat) / 360);\n  var a = sinHalfDeltaLat * sinHalfDeltaLat +\n      sinHalfDeltaLon * sinHalfDeltaLon * Math.cos(Math.PI * from.lat / 180) * Math.cos(Math.PI * to.lat / 180); \n  return 2 * R * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); \n};\n\n\nOpenLayers.Spherical.computeHeading = function(from, to) {\n    var y = Math.sin(Math.PI * (from.lon - to.lon) / 180) * Math.cos(Math.PI * to.lat / 180);\n    var x = Math.cos(Math.PI * from.lat / 180) * Math.sin(Math.PI * to.lat / 180) -\n        Math.sin(Math.PI * from.lat / 180) * Math.cos(Math.PI * to.lat / 180) * Math.cos(Math.PI * (from.lon - to.lon) / 180);\n    return 180 * Math.atan2(y, x) / Math.PI;\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Strategy/BBOX.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Strategy.BBOX = OpenLayers.Class(OpenLayers.Strategy, {\n    \n        bounds: null,\n    \n        ratio: 2,\n\n        response: null,\n\n        \n        activate: function() {\n        var activated = OpenLayers.Strategy.prototype.activate.call(this);\n        if(activated) {\n            this.layer.events.on({\n                \"moveend\": this.update,\n                \"refresh\": this.update,\n                \"visibilitychanged\": this.update,\n                scope: this\n            });\n            this.update();\n        }\n        return activated;\n    },\n    \n        deactivate: function() {\n        var deactivated = OpenLayers.Strategy.prototype.deactivate.call(this);\n        if(deactivated) {\n            this.layer.events.un({\n                \"moveend\": this.update,\n                \"refresh\": this.update,\n                \"visibilitychanged\": this.update,\n                scope: this\n            });\n        }\n        return deactivated;\n    },\n\n        update: function(options) {\n        var mapBounds = this.getMapBounds();\n        if (mapBounds !== null && ((options && options.force) ||\n          (this.layer.visibility && this.layer.calculateInRange() && this.invalidBounds(mapBounds)))) {\n            this.calculateBounds(mapBounds);\n            this.resolution = this.layer.map.getResolution(); \n            this.triggerRead(options);\n        }\n    },\n    \n        getMapBounds: function() {\n        if (this.layer.map === null) {\n            return null;\n        }\n        var bounds = this.layer.map.getExtent();\n        if (bounds && this.layer.projection && !this.layer.projection.equals(\n                this.layer.map.getProjectionObject())) {\n            bounds = bounds.clone().transform(\n                this.layer.map.getProjectionObject(), this.layer.projection\n            );\n        }\n        return bounds;\n    },\n\n        invalidBounds: function(mapBounds) {\n        if(!mapBounds) {\n            mapBounds = this.getMapBounds();\n        }\n        var invalid = !this.bounds || !this.bounds.containsBounds(mapBounds);\n        if(!invalid && this.resFactor) {\n            var ratio = this.resolution / this.layer.map.getResolution();\n            invalid = (ratio >= this.resFactor || ratio <= (1 / this.resFactor));\n        }\n        return invalid;\n    },\n \n        calculateBounds: function(mapBounds) {\n        if(!mapBounds) {\n            mapBounds = this.getMapBounds();\n        }\n        var center = mapBounds.getCenterLonLat();\n        var dataWidth = mapBounds.getWidth() * this.ratio;\n        var dataHeight = mapBounds.getHeight() * this.ratio;\n        this.bounds = new OpenLayers.Bounds(\n            center.lon - (dataWidth / 2),\n            center.lat - (dataHeight / 2),\n            center.lon + (dataWidth / 2),\n            center.lat + (dataHeight / 2)\n        );\n    },\n    \n        triggerRead: function(options) {\n        if (this.response && !(options && options.noAbort === true)) {\n            this.layer.protocol.abort(this.response);\n            this.layer.events.triggerEvent(\"loadend\");\n        }\n        var evt = {filter: this.createFilter()};\n        this.layer.events.triggerEvent(\"loadstart\", evt);\n        this.response = this.layer.protocol.read(\n            OpenLayers.Util.applyDefaults({\n                filter: evt.filter,\n                callback: this.merge,\n                scope: this\n        }, options));\n    },\n \n        createFilter: function() {\n        var filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.BBOX,\n            value: this.bounds,\n            projection: this.layer.projection\n        });\n        if (this.layer.filter) {\n            filter = new OpenLayers.Filter.Logical({\n                type: OpenLayers.Filter.Logical.AND,\n                filters: [this.layer.filter, filter]\n            });\n        }\n        return filter;\n    },\n   \n        merge: function(resp) {\n        this.layer.destroyFeatures();\n        if (resp.success()) {\n            var features = resp.features;\n            if(features && features.length > 0) {\n                var remote = this.layer.projection;\n                var local = this.layer.map.getProjectionObject();\n                if(remote && local && !local.equals(remote)) {\n                    var geom;\n                    for(var i=0, len=features.length; i<len; ++i) {\n                        geom = features[i].geometry;\n                        if(geom) {\n                            geom.transform(remote, local);\n                        }\n                    }\n                }\n                this.layer.addFeatures(features);\n            }\n        } else {\n            this.bounds = null;\n        }\n        this.response = null;\n        this.layer.events.triggerEvent(\"loadend\", {response: resp});\n    },\n   \n    CLASS_NAME: \"OpenLayers.Strategy.BBOX\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Strategy/Cluster.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Strategy.Cluster = OpenLayers.Class(OpenLayers.Strategy, {\n    \n        distance: 20,\n    \n        threshold: null,\n    \n        features: null,\n    \n        clusters: null,\n    \n        clustering: false,\n    \n        resolution: null,\n\n        \n        activate: function() {\n        var activated = OpenLayers.Strategy.prototype.activate.call(this);\n        if(activated) {\n            this.layer.events.on({\n                \"beforefeaturesadded\": this.cacheFeatures,\n                \"featuresremoved\": this.clearCache,\n                \"moveend\": this.cluster,\n                scope: this\n            });\n        }\n        return activated;\n    },\n    \n        deactivate: function() {\n        var deactivated = OpenLayers.Strategy.prototype.deactivate.call(this);\n        if(deactivated) {\n            this.clearCache();\n            this.layer.events.un({\n                \"beforefeaturesadded\": this.cacheFeatures,\n                \"featuresremoved\": this.clearCache,\n                \"moveend\": this.cluster,\n                scope: this\n            });\n        }\n        return deactivated;\n    },\n    \n        cacheFeatures: function(event) {\n        var propagate = true;\n        if(!this.clustering) {\n            this.clearCache();\n            this.features = event.features;\n            this.cluster();\n            propagate = false;\n        }\n        return propagate;\n    },\n    \n        clearCache: function() {\n        if(!this.clustering) {\n            this.features = null;\n        }\n    },\n    \n        cluster: function(event) {\n        if((!event || event.zoomChanged) && this.features) {\n            var resolution = this.layer.map.getResolution();\n            if(resolution != this.resolution || !this.clustersExist()) {\n                this.resolution = resolution;\n                var clusters = [];\n                var feature, clustered, cluster;\n                for(var i=0; i<this.features.length; ++i) {\n                    feature = this.features[i];\n                    if(feature.geometry) {\n                        clustered = false;\n                        for(var j=clusters.length-1; j>=0; --j) {\n                            cluster = clusters[j];\n                            if(this.shouldCluster(cluster, feature)) {\n                                this.addToCluster(cluster, feature);\n                                clustered = true;\n                                break;\n                            }\n                        }\n                        if(!clustered) {\n                            clusters.push(this.createCluster(this.features[i]));\n                        }\n                    }\n                }\n                this.clustering = true;\n                this.layer.removeAllFeatures();\n                this.clustering = false;\n                if(clusters.length > 0) {\n                    if(this.threshold > 1) {\n                        var clone = clusters.slice();\n                        clusters = [];\n                        var candidate;\n                        for(var i=0, len=clone.length; i<len; ++i) {\n                            candidate = clone[i];\n                            if(candidate.attributes.count < this.threshold) {\n                                Array.prototype.push.apply(clusters, candidate.cluster);\n                            } else {\n                                clusters.push(candidate);\n                            }\n                        }\n                    }\n                    this.clustering = true;\n                    this.layer.addFeatures(clusters);\n                    this.clustering = false;\n                }\n                this.clusters = clusters;\n            }\n        }\n    },\n    \n        clustersExist: function() {\n        var exist = false;\n        if(this.clusters && this.clusters.length > 0 &&\n           this.clusters.length == this.layer.features.length) {\n            exist = true;\n            for(var i=0; i<this.clusters.length; ++i) {\n                if(this.clusters[i] != this.layer.features[i]) {\n                    exist = false;\n                    break;\n                }\n            }\n        }\n        return exist;\n    },\n    \n        shouldCluster: function(cluster, feature) {\n        var cc = cluster.geometry.getBounds().getCenterLonLat();\n        var fc = feature.geometry.getBounds().getCenterLonLat();\n        var distance = (\n            Math.sqrt(\n                Math.pow((cc.lon - fc.lon), 2) + Math.pow((cc.lat - fc.lat), 2)\n            ) / this.resolution\n        );\n        return (distance <= this.distance);\n    },\n    \n        addToCluster: function(cluster, feature) {\n        cluster.cluster.push(feature);\n        cluster.attributes.count += 1;\n    },\n    \n        createCluster: function(feature) {\n        var center = feature.geometry.getBounds().getCenterLonLat();\n        var cluster = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(center.lon, center.lat),\n            {count: 1}\n        );\n        cluster.cluster = [feature];\n        return cluster;\n    },\n\n    CLASS_NAME: \"OpenLayers.Strategy.Cluster\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Strategy/Filter.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Strategy.Filter = OpenLayers.Class(OpenLayers.Strategy, {\n    \n        filter: null,\n    \n        cache: null,\n    \n        caching: false,\n    \n    \n        activate: function() {\n        var activated = OpenLayers.Strategy.prototype.activate.apply(this, arguments);\n        if (activated) {\n            this.cache = [];\n            this.layer.events.on({\n                \"beforefeaturesadded\": this.handleAdd,\n                \"beforefeaturesremoved\": this.handleRemove,\n                scope: this\n            });\n        }\n        return activated;\n    },\n    \n        deactivate: function() {\n        this.cache = null;\n        if (this.layer && this.layer.events) {\n            this.layer.events.un({\n                \"beforefeaturesadded\": this.handleAdd,\n                \"beforefeaturesremoved\": this.handleRemove,\n                scope: this\n            });            \n        }\n        return OpenLayers.Strategy.prototype.deactivate.apply(this, arguments);\n    },\n    \n        handleAdd: function(event) {\n        if (!this.caching && this.filter) {\n            var features = event.features;\n            event.features = [];\n            var feature;\n            for (var i=0, ii=features.length; i<ii; ++i) {\n                feature = features[i];\n                if (this.filter.evaluate(feature)) {\n                    event.features.push(feature);\n                } else {\n                    this.cache.push(feature);\n                }\n            }\n        }\n    },\n    \n        handleRemove: function(event) {\n        if (!this.caching) {\n            this.cache = [];\n        }\n    },\n\n        setFilter: function(filter) {\n        this.filter = filter;\n        var previousCache = this.cache;\n        this.cache = [];\n        this.handleAdd({features: this.layer.features});\n        if (this.cache.length > 0) {\n            this.caching = true;\n            this.layer.removeFeatures(this.cache.slice());\n            this.caching = false;\n        }\n        if (previousCache.length > 0) {\n            var event = {features: previousCache};\n            this.handleAdd(event);\n            if (event.features.length > 0) {\n                this.caching = true;\n                this.layer.addFeatures(event.features);\n                this.caching = false;\n            }\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Strategy.Filter\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Strategy/Fixed.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Strategy.Fixed = OpenLayers.Class(OpenLayers.Strategy, {\n    \n        preload: false,\n\n    \n        activate: function() {\n        var activated = OpenLayers.Strategy.prototype.activate.apply(this, arguments);\n        if(activated) {\n            this.layer.events.on({\n                \"refresh\": this.load,\n                scope: this\n            });\n            if(this.layer.visibility == true || this.preload) {\n                this.load();\n            } else {\n                this.layer.events.on({\n                    \"visibilitychanged\": this.load,\n                    scope: this\n                });\n            }\n        }\n        return activated;\n    },\n    \n        deactivate: function() {\n        var deactivated = OpenLayers.Strategy.prototype.deactivate.call(this);\n        if(deactivated) {\n            this.layer.events.un({\n                \"refresh\": this.load,\n                \"visibilitychanged\": this.load,\n                scope: this\n            });\n        }\n        return deactivated;\n    },\n\n        load: function(options) {\n        var layer = this.layer;\n        layer.events.triggerEvent(\"loadstart\", {filter: layer.filter});\n        layer.protocol.read(OpenLayers.Util.applyDefaults({\n            callback: this.merge,\n            filter: layer.filter,\n            scope: this\n        }, options));\n        layer.events.un({\n            \"visibilitychanged\": this.load,\n            scope: this\n        });\n    },\n\n        merge: function(resp) {\n        var layer = this.layer;\n        layer.destroyFeatures();\n        var features = resp.features;\n        if (features && features.length > 0) {\n            var remote = layer.projection;\n            var local = layer.map.getProjectionObject();\n            if(!local.equals(remote)) {\n                var geom;\n                for(var i=0, len=features.length; i<len; ++i) {\n                    geom = features[i].geometry;\n                    if(geom) {\n                        geom.transform(remote, local);\n                    }\n                }\n            }\n            layer.addFeatures(features);\n        }\n        layer.events.triggerEvent(\"loadend\", {response: resp});\n    },\n\n    CLASS_NAME: \"OpenLayers.Strategy.Fixed\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Strategy/Paging.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Strategy.Paging = OpenLayers.Class(OpenLayers.Strategy, {\n    \n        features: null,\n    \n        length: 10,\n    \n        num: null,\n    \n        paging: false,\n\n        \n        activate: function() {\n        var activated = OpenLayers.Strategy.prototype.activate.call(this);\n        if(activated) {\n            this.layer.events.on({\n                \"beforefeaturesadded\": this.cacheFeatures,\n                scope: this\n            });\n        }\n        return activated;\n    },\n    \n        deactivate: function() {\n        var deactivated = OpenLayers.Strategy.prototype.deactivate.call(this);\n        if(deactivated) {\n            this.clearCache();\n            this.layer.events.un({\n                \"beforefeaturesadded\": this.cacheFeatures,\n                scope: this\n            });\n        }\n        return deactivated;\n    },\n    \n        cacheFeatures: function(event) {\n        if(!this.paging) {\n            this.clearCache();\n            this.features = event.features;\n            this.pageNext(event);\n        }\n    },\n    \n        clearCache: function() {\n        if(this.features) {\n            for(var i=0; i<this.features.length; ++i) {\n                this.features[i].destroy();\n            }\n        }\n        this.features = null;\n        this.num = null;\n    },\n    \n        pageCount: function() {\n        var numFeatures = this.features ? this.features.length : 0;\n        return Math.ceil(numFeatures / this.length);\n    },\n\n        pageNum: function() {\n        return this.num;\n    },\n\n        pageLength: function(newLength) {\n        if(newLength && newLength > 0) {\n            this.length = newLength;\n        }\n        return this.length;\n    },\n\n        pageNext: function(event) {\n        var changed = false;\n        if(this.features) {\n            if(this.num === null) {\n                this.num = -1;\n            }\n            var start = (this.num + 1) * this.length;\n            changed = this.page(start, event);\n        }\n        return changed;\n    },\n\n        pagePrevious: function() {\n        var changed = false;\n        if(this.features) {\n            if(this.num === null) {\n                this.num = this.pageCount();\n            }\n            var start = (this.num - 1) * this.length;\n            changed = this.page(start);\n        }\n        return changed;\n    },\n    \n        page: function(start, event) {\n        var changed = false;\n        if(this.features) {\n            if(start >= 0 && start < this.features.length) {\n                var num = Math.floor(start / this.length);\n                if(num != this.num) {\n                    this.paging = true;\n                    var features = this.features.slice(start, start + this.length);\n                    this.layer.removeFeatures(this.layer.features);\n                    this.num = num;\n                    if(event && event.features) {\n                        event.features = features;\n                    } else {\n                        this.layer.addFeatures(features);\n                    }\n                    this.paging = false;\n                    changed = true;\n                }\n            }\n        }\n        return changed;\n    },\n    \n    CLASS_NAME: \"OpenLayers.Strategy.Paging\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Strategy/Refresh.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Strategy.Refresh = OpenLayers.Class(OpenLayers.Strategy, {\n    \n        force: false,\n\n        interval: 0,\n    \n        timer: null,\n\n       \n        activate: function() {\n        var activated = OpenLayers.Strategy.prototype.activate.call(this);\n        if(activated) {\n            if(this.layer.visibility === true) {\n                this.start();\n            } \n            this.layer.events.on({\n                \"visibilitychanged\": this.reset,\n                scope: this\n            });\n        }\n        return activated;\n    },\n    \n        deactivate: function() {\n        var deactivated = OpenLayers.Strategy.prototype.deactivate.call(this);\n        if(deactivated) {\n            this.stop();\n            this.layer.events.un({\n                \"visibilitychanged\": this.reset,\n                scope: this\n            });\n        }\n        return deactivated;\n    },\n    \n        reset: function() {\n        if(this.layer.visibility === true) {\n            this.start();\n        } else {\n            this.stop();\n        }\n    },\n    \n        start: function() {\n        if(this.interval && typeof this.interval === \"number\" && \n            this.interval > 0) {\n\n            this.timer = window.setInterval(\n                OpenLayers.Function.bind(this.refresh, this),\n                this.interval);\n        }\n    },\n    \n        refresh: function() {\n        if (this.layer && this.layer.refresh && \n            typeof this.layer.refresh == \"function\") {\n\n            this.layer.refresh({force: this.force});\n        }\n    },\n   \n        stop: function() {\n        if(this.timer !== null) {\n            window.clearInterval(this.timer);\n            this.timer = null;\n        }\n    },\n    \n    CLASS_NAME: \"OpenLayers.Strategy.Refresh\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Strategy/Save.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Strategy.Save = OpenLayers.Class(OpenLayers.Strategy, {\n    \n     \n        events: null,\n    \n        auto: false,\n    \n        timer: null,\n\n        initialize: function(options) {\n        OpenLayers.Strategy.prototype.initialize.apply(this, [options]);\n        this.events = new OpenLayers.Events(this);\n    },\n   \n        activate: function() {\n        var activated = OpenLayers.Strategy.prototype.activate.call(this);\n        if(activated) {\n            if(this.auto) {\n                if(typeof this.auto === \"number\") {\n                    this.timer = window.setInterval(\n                        OpenLayers.Function.bind(this.save, this),\n                        this.auto * 1000\n                    );\n                } else {\n                    this.layer.events.on({\n                        \"featureadded\": this.triggerSave,\n                        \"afterfeaturemodified\": this.triggerSave,\n                        scope: this\n                    });\n                }\n            }\n        }\n        return activated;\n    },\n    \n        deactivate: function() {\n        var deactivated = OpenLayers.Strategy.prototype.deactivate.call(this);\n        if(deactivated) {\n            if(this.auto) {\n                if(typeof this.auto === \"number\") {\n                    window.clearInterval(this.timer);\n                } else {\n                    this.layer.events.un({\n                        \"featureadded\": this.triggerSave,\n                        \"afterfeaturemodified\": this.triggerSave,\n                        scope: this\n                    });\n                }\n            }\n        }\n        return deactivated;\n    },\n    \n        triggerSave: function(event) {\n        var feature = event.feature;\n        if(feature.state === OpenLayers.State.INSERT ||\n           feature.state === OpenLayers.State.UPDATE ||\n           feature.state === OpenLayers.State.DELETE) {\n            this.save([event.feature]);\n        }\n    },\n    \n        save: function(features) {\n        if(!features) {\n            features = this.layer.features;\n        }\n        this.events.triggerEvent(\"start\", {features:features});\n        var remote = this.layer.projection;\n        var local = this.layer.map.getProjectionObject();\n        if(!local.equals(remote)) {\n            var len = features.length;\n            var clones = new Array(len);\n            var orig, clone;\n            for(var i=0; i<len; ++i) {\n                orig = features[i];\n                clone = orig.clone();\n                clone.fid = orig.fid;\n                clone.state = orig.state;\n                if(orig.url) {\n                    clone.url = orig.url;\n                }\n                clone._original = orig;\n                clone.geometry.transform(local, remote);\n                clones[i] = clone;\n            }\n            features = clones;\n        }\n        this.layer.protocol.commit(features, {\n            callback: this.onCommit,\n            scope: this\n        });\n    },\n    \n        onCommit: function(response) {\n        var evt = {\"response\": response};\n        if(response.success()) {\n            var features = response.reqFeatures;\n            var state, feature;\n            var destroys = [];\n            var insertIds = response.insertIds || [];\n            var j = 0;\n            for(var i=0, len=features.length; i<len; ++i) {\n                feature = features[i];\n                feature = feature._original || feature;\n                state = feature.state;\n                if(state) {\n                    if(state == OpenLayers.State.DELETE) {\n                        destroys.push(feature);\n                    } else if(state == OpenLayers.State.INSERT) {\n                        feature.fid = insertIds[j];\n                        ++j;\n                    }\n                    feature.state = null;\n                }\n            }\n\n            if(destroys.length > 0) {\n                this.layer.destroyFeatures(destroys);\n            }\n\n            this.events.triggerEvent(\"success\", evt);\n\n        } else {\n            this.events.triggerEvent(\"fail\", evt);\n        }\n    },\n   \n    CLASS_NAME: \"OpenLayers.Strategy.Save\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Strategy.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Strategy = OpenLayers.Class({\n    \n        layer: null,\n    \n        options: null,\n\n        active: null,\n\n        autoActivate: true,\n\n        autoDestroy: true,\n\n        initialize: function(options) {\n        OpenLayers.Util.extend(this, options);\n        this.options = options;\n        this.active = false;\n    },\n    \n        destroy: function() {\n        this.deactivate();\n        this.layer = null;\n        this.options = null;\n    },\n\n        setLayer: function(layer) {\n        this.layer = layer;\n    },\n    \n        activate: function() {\n        if (!this.active) {\n            this.active = true;\n            return true;\n        }\n        return false;\n    },\n    \n        deactivate: function() {\n        if (this.active) {\n            this.active = false;\n            return true;\n        }\n        return false;\n    },\n   \n    CLASS_NAME: \"OpenLayers.Strategy\" \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Style.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Style = OpenLayers.Class({\n\n        id: null,\n    \n        name: null,\n    \n        title: null,\n    \n        description: null,\n\n        layerName: null,\n    \n        isDefault: false,\n     \n        rules: null,\n    \n        context: null,\n\n        defaultStyle: null,\n    \n        defaultsPerSymbolizer: false,\n    \n        propertyStyles: null,\n    \n\n        initialize: function(style, options) {\n\n        OpenLayers.Util.extend(this, options);\n        this.rules = [];\n        if(options && options.rules) {\n            this.addRules(options.rules);\n        }\n        this.setDefaultStyle(style ||\n                             OpenLayers.Feature.Vector.style[\"default\"]);\n\n        this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + \"_\");\n    },\n\n        destroy: function() {\n        for (var i=0, len=this.rules.length; i<len; i++) {\n            this.rules[i].destroy();\n            this.rules[i] = null;\n        }\n        this.rules = null;\n        this.defaultStyle = null;\n    },\n    \n        createSymbolizer: function(feature) {\n        var style = this.defaultsPerSymbolizer ? {} : this.createLiterals(\n            OpenLayers.Util.extend({}, this.defaultStyle), feature);\n        \n        var rules = this.rules;\n\n        var rule, context;\n        var elseRules = [];\n        var appliedRules = false;\n        for(var i=0, len=rules.length; i<len; i++) {\n            rule = rules[i];\n            var applies = rule.evaluate(feature);\n            \n            if(applies) {\n                if(rule instanceof OpenLayers.Rule && rule.elseFilter) {\n                    elseRules.push(rule);\n                } else {\n                    appliedRules = true;\n                    this.applySymbolizer(rule, style, feature);\n                }\n            }\n        }\n        if(appliedRules == false && elseRules.length > 0) {\n            appliedRules = true;\n            for(var i=0, len=elseRules.length; i<len; i++) {\n                this.applySymbolizer(elseRules[i], style, feature);\n            }\n        }\n        if(rules.length > 0 && appliedRules == false) {\n            style.display = \"none\";\n        }\n        \n        if (style.label != null && typeof style.label !== \"string\") {\n            style.label = String(style.label);\n        }\n        \n        return style;\n    },\n    \n        applySymbolizer: function(rule, style, feature) {\n        var symbolizerPrefix = feature.geometry ?\n                this.getSymbolizerPrefix(feature.geometry) :\n                OpenLayers.Style.SYMBOLIZER_PREFIXES[0];\n\n        var symbolizer = rule.symbolizer[symbolizerPrefix] || rule.symbolizer;\n        \n        if(this.defaultsPerSymbolizer === true) {\n            var defaults = this.defaultStyle;\n            OpenLayers.Util.applyDefaults(symbolizer, {\n                pointRadius: defaults.pointRadius\n            });\n            if(symbolizer.stroke === true || symbolizer.graphic === true) {\n                OpenLayers.Util.applyDefaults(symbolizer, {\n                    strokeWidth: defaults.strokeWidth,\n                    strokeColor: defaults.strokeColor,\n                    strokeOpacity: defaults.strokeOpacity,\n                    strokeDashstyle: defaults.strokeDashstyle,\n                    strokeLinecap: defaults.strokeLinecap\n                });\n            }\n            if(symbolizer.fill === true || symbolizer.graphic === true) {\n                OpenLayers.Util.applyDefaults(symbolizer, {\n                    fillColor: defaults.fillColor,\n                    fillOpacity: defaults.fillOpacity\n                });\n            }\n            if(symbolizer.graphic === true) {\n                OpenLayers.Util.applyDefaults(symbolizer, {\n                    pointRadius: this.defaultStyle.pointRadius,\n                    externalGraphic: this.defaultStyle.externalGraphic,\n                    graphicName: this.defaultStyle.graphicName,\n                    graphicOpacity: this.defaultStyle.graphicOpacity,\n                    graphicWidth: this.defaultStyle.graphicWidth,\n                    graphicHeight: this.defaultStyle.graphicHeight,\n                    graphicXOffset: this.defaultStyle.graphicXOffset,\n                    graphicYOffset: this.defaultStyle.graphicYOffset\n                });\n            }\n        }\n        return this.createLiterals(\n                OpenLayers.Util.extend(style, symbolizer), feature);\n    },\n    \n        createLiterals: function(style, feature) {\n        var context = OpenLayers.Util.extend({}, feature.attributes || feature.data);\n        OpenLayers.Util.extend(context, this.context);\n        \n        for (var i in this.propertyStyles) {\n            style[i] = OpenLayers.Style.createLiteral(style[i], context, feature, i);\n        }\n        return style;\n    },\n    \n        findPropertyStyles: function() {\n        var propertyStyles = {};\n        var style = this.defaultStyle;\n        this.addPropertyStyles(propertyStyles, style);\n        var rules = this.rules;\n        var symbolizer, value;\n        for (var i=0, len=rules.length; i<len; i++) {\n            symbolizer = rules[i].symbolizer;\n            for (var key in symbolizer) {\n                value = symbolizer[key];\n                if (typeof value == \"object\") {\n                    this.addPropertyStyles(propertyStyles, value);\n                } else {\n                    this.addPropertyStyles(propertyStyles, symbolizer);\n                    break;\n                }\n            }\n        }\n        return propertyStyles;\n    },\n    \n        addPropertyStyles: function(propertyStyles, symbolizer) {\n        var property;\n        for (var key in symbolizer) {\n            property = symbolizer[key];\n            if (typeof property == \"string\" &&\n                    property.match(/\\$\\{\\w+\\}/)) {\n                propertyStyles[key] = true;\n            }\n        }\n        return propertyStyles;\n    },\n    \n        addRules: function(rules) {\n        Array.prototype.push.apply(this.rules, rules);\n        this.propertyStyles = this.findPropertyStyles();\n    },\n    \n        setDefaultStyle: function(style) {\n        this.defaultStyle = style; \n        this.propertyStyles = this.findPropertyStyles();\n    },\n        \n        getSymbolizerPrefix: function(geometry) {\n        var prefixes = OpenLayers.Style.SYMBOLIZER_PREFIXES;\n        for (var i=0, len=prefixes.length; i<len; i++) {\n            if (geometry.CLASS_NAME.indexOf(prefixes[i]) != -1) {\n                return prefixes[i];\n            }\n        }\n    },\n    \n        clone: function() {\n        var options = OpenLayers.Util.extend({}, this);\n        if(this.rules) {\n            options.rules = [];\n            for(var i=0, len=this.rules.length; i<len; ++i) {\n                options.rules.push(this.rules[i].clone());\n            }\n        }\n        options.context = this.context && OpenLayers.Util.extend({}, this.context);\n        var defaultStyle = OpenLayers.Util.extend({}, this.defaultStyle);\n        return new OpenLayers.Style(defaultStyle, options);\n    },\n    \n    CLASS_NAME: \"OpenLayers.Style\"\n});\n\n\nOpenLayers.Style.createLiteral = function(value, context, feature, property) {\n    if (typeof value == \"string\" && value.indexOf(\"${\") != -1) {\n        value = OpenLayers.String.format(value, context, [feature, property]);\n        value = (isNaN(value) || !value) ? value : parseFloat(value);\n    }\n    return value;\n};\n    \nOpenLayers.Style.SYMBOLIZER_PREFIXES = ['Point', 'Line', 'Polygon', 'Text',\n    'Raster'];\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Style2.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Style2 = OpenLayers.Class({\n\n        id: null,\n    \n        name: null,\n    \n        title: null,\n    \n        description: null,\n\n        layerName: null,\n    \n        isDefault: false,\n     \n        rules: null,\n    \n        initialize: function(config) {\n        OpenLayers.Util.extend(this, config);\n        this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + \"_\");\n    },\n\n        destroy: function() {\n        for (var i=0, len=this.rules.length; i<len; i++) {\n            this.rules[i].destroy();\n        }\n        delete this.rules;\n    },\n\n        clone: function() {\n        var config = OpenLayers.Util.extend({}, this);\n        if (this.rules) {\n            config.rules = [];\n            for (var i=0, len=this.rules.length; i<len; ++i) {\n                config.rules.push(this.rules[i].clone());\n            }\n        }\n        return new OpenLayers.Style2(config);\n    },\n    \n    CLASS_NAME: \"OpenLayers.Style2\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/StyleMap.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n \nOpenLayers.StyleMap = OpenLayers.Class({\n    \n        styles: null,\n    \n        extendDefault: true,\n    \n        initialize: function (style, options) {\n        this.styles = {\n            \"default\": new OpenLayers.Style(\n                OpenLayers.Feature.Vector.style[\"default\"]),\n            \"select\": new OpenLayers.Style(\n                OpenLayers.Feature.Vector.style[\"select\"]),\n            \"temporary\": new OpenLayers.Style(\n                OpenLayers.Feature.Vector.style[\"temporary\"]),\n            \"delete\": new OpenLayers.Style(\n                OpenLayers.Feature.Vector.style[\"delete\"])\n        };\n        if(style instanceof OpenLayers.Style) {\n            this.styles[\"default\"] = style;\n            this.styles[\"select\"] = style;\n            this.styles[\"temporary\"] = style;\n            this.styles[\"delete\"] = style;\n        } else if(typeof style == \"object\") {\n            for(var key in style) {\n                if(style[key] instanceof OpenLayers.Style) {\n                    this.styles[key] = style[key];\n                } else if(typeof style[key] == \"object\") {\n                    this.styles[key] = new OpenLayers.Style(style[key]);\n                } else {\n                    this.styles[\"default\"] = new OpenLayers.Style(style);\n                    this.styles[\"select\"] = new OpenLayers.Style(style);\n                    this.styles[\"temporary\"] = new OpenLayers.Style(style);\n                    this.styles[\"delete\"] = new OpenLayers.Style(style);\n                    break;\n                }\n            }\n        }\n        OpenLayers.Util.extend(this, options);\n    },\n\n        destroy: function() {\n        for(var key in this.styles) {\n            this.styles[key].destroy();\n        }\n        this.styles = null;\n    },\n    \n        createSymbolizer: function(feature, intent) {\n        if(!feature) {\n            feature = new OpenLayers.Feature.Vector();\n        }\n        if(!this.styles[intent]) {\n            intent = \"default\";\n        }\n        feature.renderIntent = intent;\n        var defaultSymbolizer = {};\n        if(this.extendDefault && intent != \"default\") {\n            defaultSymbolizer = this.styles[\"default\"].createSymbolizer(feature);\n        }\n        return OpenLayers.Util.extend(defaultSymbolizer,\n            this.styles[intent].createSymbolizer(feature));\n    },\n    \n        addUniqueValueRules: function(renderIntent, property, symbolizers, context) {\n        var rules = [];\n        for (var value in symbolizers) {\n            rules.push(new OpenLayers.Rule({\n                symbolizer: symbolizers[value],\n                context: context,\n                filter: new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                    property: property,\n                    value: value\n                })\n            }));\n        }\n        this.styles[renderIntent].addRules(rules);\n    },\n\n    CLASS_NAME: \"OpenLayers.StyleMap\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Symbolizer/Line.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Symbolizer.Line = OpenLayers.Class(OpenLayers.Symbolizer, {\n\n        \n        \n        \n        \n    \n        initialize: function(config) {\n        OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);\n    },\n    \n    CLASS_NAME: \"OpenLayers.Symbolizer.Line\"\n    \n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Symbolizer/Point.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Symbolizer.Point = OpenLayers.Class(OpenLayers.Symbolizer, {\n    \n        \n        \n        \n        \n    \n        \n    \n    \n        \n        \n        \n        \n        \n    \n        \n        \n        initialize: function(config) {\n        OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);\n    },\n    \n    CLASS_NAME: \"OpenLayers.Symbolizer.Point\"\n    \n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Symbolizer/Polygon.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Symbolizer.Polygon = OpenLayers.Class(OpenLayers.Symbolizer, {\n    \n        \n        \n        \n        \n    \n        \n    \n        initialize: function(config) {\n        OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);\n    },\n    \n    CLASS_NAME: \"OpenLayers.Symbolizer.Polygon\"\n    \n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Symbolizer/Raster.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Symbolizer.Raster = OpenLayers.Class(OpenLayers.Symbolizer, {\n    \n        initialize: function(config) {\n        OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);\n    },\n    \n    CLASS_NAME: \"OpenLayers.Symbolizer.Raster\"\n    \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Symbolizer/Text.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Symbolizer.Text = OpenLayers.Class(OpenLayers.Symbolizer, {\n    \n        \n    \n    \n        \n    \n    \n    \n        initialize: function(config) {\n        OpenLayers.Symbolizer.prototype.initialize.apply(this, arguments);\n    },\n    \n    CLASS_NAME: \"OpenLayers.Symbolizer.Text\"\n    \n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Symbolizer.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Symbolizer = OpenLayers.Class({\n    \n\n        zIndex: 0,\n    \n        initialize: function(config) {\n        OpenLayers.Util.extend(this, config);\n    },\n    \n        clone: function() {\n        var Type = OpenLayers.Util.getConstructor(this.CLASS_NAME);\n        return new Type(OpenLayers.Util.extend({}, this));\n    },\n    \n    CLASS_NAME: \"OpenLayers.Symbolizer\"\n    \n});\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Tile/Image/IFrame.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Tile.Image.IFrame = {\n\n        blankImageUrl: \"data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAQAIBRAA7\",\n\n        draw: function() {\n        var draw = OpenLayers.Tile.Image.prototype.shouldDraw.call(this);\n        if(draw) {\n            var url = this.layer.getURL(this.bounds);\n\n            var usedIFrame = this.useIFrame;\n            this.useIFrame = this.maxGetUrlLength !== null &&\n                             !this.layer.async &&\n                             url.length > this.maxGetUrlLength;\n\n            var fromIFrame = usedIFrame && !this.useIFrame;\n            var toIFrame = !usedIFrame && this.useIFrame;\n\n            if(fromIFrame || toIFrame) {\n\n                if(this.imgDiv && this.imgDiv.parentNode === this.frame) {\n                    this.frame.removeChild(this.imgDiv);\n                }\n                this.imgDiv = null;\n\n                if(fromIFrame) {\n                    this.frame.removeChild(this.frame.firstChild);\n                }\n            }\n        }\n        return OpenLayers.Tile.Image.prototype.draw.apply(this, arguments);\n    },\n\n        getImage: function() {\n        if (this.useIFrame === true) {\n            if (!this.frame.childNodes.length) {\n                var eventPane = document.createElement(\"div\"),\n                    style = eventPane.style;\n                style.position = \"absolute\";\n                style.width = \"100%\";\n                style.height = \"100%\";\n                style.zIndex = 1;\n                style.backgroundImage = \"url(\" + this.blankImageUrl + \")\";\n                this.frame.appendChild(eventPane);\n            }\n\n            var id = this.id + '_iFrame', iframe;\n            if (parseFloat(navigator.appVersion.split(\"MSIE\")[1]) < 9) {\n                iframe = document.createElement('<iframe name=\"'+id+'\">');\n                iframe.style.backgroundColor = '#FFFFFF';\n                iframe.style.filter          = 'chroma(color=#FFFFFF)';\n            }\n            else {\n                iframe = document.createElement('iframe');\n                iframe.style.backgroundColor = 'transparent';\n                iframe.name = id;\n            }\n            iframe.scrolling      = 'no';\n            iframe.marginWidth    = '0px';\n            iframe.marginHeight   = '0px';\n            iframe.frameBorder    = '0';\n\n            iframe.style.position = \"absolute\";\n            iframe.style.width    = \"100%\";\n            iframe.style.height   = \"100%\";\n\n            if (this.layer.opacity < 1) {\n                OpenLayers.Util.modifyDOMElement(iframe, null, null, null,\n                    null, null, null, this.layer.opacity);\n            }\n            this.frame.appendChild(iframe);\n            this.imgDiv = iframe;\n            return iframe;\n        } else {\n            return OpenLayers.Tile.Image.prototype.getImage.apply(this, arguments);\n        }\n    },\n    \n        createRequestForm: function() {\n        var form = document.createElement('form');\n        form.method = 'POST';\n        var cacheId = this.layer.params[\"_OLSALT\"];\n        cacheId = (cacheId ? cacheId + \"_\" : \"\") + this.bounds.toBBOX();\n        form.action = OpenLayers.Util.urlAppend(this.layer.url, cacheId);\n        form.target = this.id + '_iFrame';\n        var imageSize = this.layer.getImageSize(),\n            params = OpenLayers.Util.getParameters(this.url),\n            field;\n            \n        for(var par in params) {\n            field = document.createElement('input');\n            field.type  = 'hidden';\n            field.name  = par;\n            field.value = params[par];\n            form.appendChild(field);\n        }   \n\n        return form;\n    },\n\n        setImgSrc: function(url) {\n        if (this.useIFrame === true) {\n            if (url) {\n                var form = this.createRequestForm();\n                this.frame.appendChild(form);\n                form.submit();\n                this.frame.removeChild(form);\n            } else if (this.imgDiv.parentNode === this.frame) {\n                this.frame.removeChild(this.imgDiv);\n                this.imgDiv = null;\n            }\n        } else {\n            OpenLayers.Tile.Image.prototype.setImgSrc.apply(this, arguments);\n        }\n    },\n    \n        onImageLoad: function() {\n        OpenLayers.Tile.Image.prototype.onImageLoad.apply(this, arguments);\n        if (this.useIFrame === true) {\n            this.imgDiv.style.opacity = 1;\n            this.frame.style.opacity = this.layer.opacity;\n        }\n    },\n\n        createBackBuffer: function() {\n        var backBuffer;\n        if(this.useIFrame === false) {\n            backBuffer = OpenLayers.Tile.Image.prototype.createBackBuffer.call(this);\n        }\n        return backBuffer;\n    }\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Tile/Image.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {\n\n    \n        url: null,\n    \n        imgDiv: null,\n    \n        imageReloadAttempts: null,\n    \n        layerAlphaHack: null,\n    \n        asyncRequestId: null,\n    \n        maxGetUrlLength: null,\n\n        canvasContext: null,\n    \n        crossOriginKeyword: null,\n\n    \n        destroy: function() {\n        if (this.imgDiv)  {\n            this.clear();\n            this.imgDiv = null;\n            this.frame = null;\n        }\n        this.asyncRequestId = null;\n        OpenLayers.Tile.prototype.destroy.apply(this, arguments);\n    },\n    \n        draw: function() {\n        var shouldDraw = OpenLayers.Tile.prototype.draw.apply(this, arguments);\n        if (shouldDraw) {\n            if (this.layer != this.layer.map.baseLayer && this.layer.reproject) {\n                this.bounds = this.getBoundsFromBaseLayer(this.position);\n            }\n            if (this.isLoading) {\n                this._loadEvent = \"reload\";\n            } else {\n                this.isLoading = true;\n                this._loadEvent = \"loadstart\";\n            }\n            this.renderTile();\n            this.positionTile();\n        } else if (shouldDraw === false) {\n            this.unload();\n        }\n        return shouldDraw;\n    },\n    \n        renderTile: function() {\n        if (this.layer.async) {\n            var id = this.asyncRequestId = (this.asyncRequestId || 0) + 1;\n            this.layer.getURLasync(this.bounds, function(url) {\n                if (id == this.asyncRequestId) {\n                    this.url = url;\n                    this.initImage();\n                }\n            }, this);\n        } else {\n            this.url = this.layer.getURL(this.bounds);\n            this.initImage();\n        }\n    },\n\n        positionTile: function() {\n        var style = this.getTile().style,\n            size = this.frame ? this.size :\n                this.layer.getImageSize(this.bounds),\n            ratio = 1;\n        if (this.layer instanceof OpenLayers.Layer.Grid) {\n            ratio = this.layer.getServerResolution() / this.layer.map.getResolution();\n        }\n        style.left = this.position.x + \"px\";\n        style.top = this.position.y + \"px\";\n        style.width = Math.round(ratio * size.w) + \"px\";\n        style.height = Math.round(ratio * size.h) + \"px\";\n    },\n\n        clear: function() {\n        OpenLayers.Tile.prototype.clear.apply(this, arguments);\n        var img = this.imgDiv;\n        if (img) {\n            var tile = this.getTile();\n            if (tile.parentNode === this.layer.div) {\n                this.layer.div.removeChild(tile);\n            }\n            this.setImgSrc();\n            if (this.layerAlphaHack === true) {\n                img.style.filter = \"\";\n            }\n            OpenLayers.Element.removeClass(img, \"olImageLoadError\");\n        }\n        this.canvasContext = null;\n    },\n    \n        getImage: function() {\n        if (!this.imgDiv) {\n            this.imgDiv = OpenLayers.Tile.Image.IMAGE.cloneNode(false);\n\n            var style = this.imgDiv.style;\n            if (this.frame) {\n                var left = 0, top = 0;\n                if (this.layer.gutter) {\n                    left = this.layer.gutter / this.layer.tileSize.w * 100;\n                    top = this.layer.gutter / this.layer.tileSize.h * 100;\n                }\n                style.left = -left + \"%\";\n                style.top = -top + \"%\";\n                style.width = (2 * left + 100) + \"%\";\n                style.height = (2 * top + 100) + \"%\";\n            }\n            style.visibility = \"hidden\";\n            style.opacity = 0;\n            if (this.layer.opacity < 1) {\n                style.filter = 'alpha(opacity=' +\n                               (this.layer.opacity * 100) +\n                               ')';\n            }\n            style.position = \"absolute\";\n            if (this.layerAlphaHack) {\n                style.paddingTop = style.height;\n                style.height = \"0\";\n                style.width = \"100%\";\n            }\n            if (this.frame) {\n                this.frame.appendChild(this.imgDiv);\n            }\n        }\n\n        return this.imgDiv;\n    },\n    \n        setImage: function(img) {\n        this.imgDiv = img;\n    },\n\n        initImage: function() {\n        if (!this.url && !this.imgDiv) {\n            this.isLoading = false;\n            return;\n        }\n        this.events.triggerEvent('beforeload');\n        this.layer.div.appendChild(this.getTile());\n        this.events.triggerEvent(this._loadEvent);\n        var img = this.getImage();\n        var src = img.getAttribute('src') || '';\n        if (this.url && OpenLayers.Util.isEquivalentUrl(src, this.url)) {\n            this._loadTimeout = window.setTimeout(\n                OpenLayers.Function.bind(this.onImageLoad, this), 0\n            );\n        } else {\n            this.stopLoading();\n            if (this.crossOriginKeyword) {\n                img.removeAttribute(\"crossorigin\");\n            }\n            OpenLayers.Event.observe(img, \"load\",\n                OpenLayers.Function.bind(this.onImageLoad, this)\n            );\n            OpenLayers.Event.observe(img, \"error\",\n                OpenLayers.Function.bind(this.onImageError, this)\n            );\n            this.imageReloadAttempts = 0;\n            this.setImgSrc(this.url);\n        }\n    },\n    \n        setImgSrc: function(url) {\n        var img = this.imgDiv;\n        if (url) {\n            img.style.visibility = 'hidden';\n            img.style.opacity = 0;\n            if (this.crossOriginKeyword) {\n                if (url.substr(0, 5) !== 'data:') {\n                    img.setAttribute(\"crossorigin\", this.crossOriginKeyword);\n                } else {\n                    img.removeAttribute(\"crossorigin\");\n                }\n            }\n            img.src = url;\n        } else {\n            this.stopLoading();\n            this.imgDiv = null;\n            if (img.parentNode) {\n                img.parentNode.removeChild(img);\n            }\n        }\n    },\n    \n        getTile: function() {\n        return this.frame ? this.frame : this.getImage();\n    },\n\n        createBackBuffer: function() {\n        if (!this.imgDiv || this.isLoading) {\n            return;\n        }\n        var backBuffer;\n        if (this.frame) {\n            backBuffer = this.frame.cloneNode(false);\n            backBuffer.appendChild(this.imgDiv);\n        } else {\n            backBuffer = this.imgDiv;\n        }\n        this.imgDiv = null;\n        return backBuffer;\n    },\n\n        onImageLoad: function() {\n        var img = this.imgDiv;\n        this.stopLoading();\n        img.style.visibility = 'inherit';\n        img.style.opacity = this.layer.opacity;\n        this.isLoading = false;\n        this.canvasContext = null;\n        this.events.triggerEvent(\"loadend\");\n\n        if (this.layerAlphaHack === true) {\n            img.style.filter =\n                \"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='\" +\n                img.src + \"', sizingMethod='scale')\";\n        }\n    },\n    \n        onImageError: function() {\n        var img = this.imgDiv;\n        if (img.src != null) {\n            this.imageReloadAttempts++;\n            if (this.imageReloadAttempts <= OpenLayers.IMAGE_RELOAD_ATTEMPTS) {\n                this.setImgSrc(this.layer.getURL(this.bounds));\n            } else {\n                OpenLayers.Element.addClass(img, \"olImageLoadError\");\n                this.events.triggerEvent(\"loaderror\");\n                this.onImageLoad();\n            }\n        }\n    },\n    \n        stopLoading: function() {\n        OpenLayers.Event.stopObservingElement(this.imgDiv);\n        window.clearTimeout(this._loadTimeout);\n        delete this._loadTimeout;\n    },\n\n        getCanvasContext: function() {\n        if (OpenLayers.CANVAS_SUPPORTED && this.imgDiv && !this.isLoading) {\n            if (!this.canvasContext) {\n                var canvas = document.createElement(\"canvas\");\n                canvas.width = this.size.w;\n                canvas.height = this.size.h;\n                this.canvasContext = canvas.getContext(\"2d\");\n                this.canvasContext.drawImage(this.imgDiv, 0, 0);\n            }\n            return this.canvasContext;\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Tile.Image\"\n\n});\n\nOpenLayers.Tile.Image.IMAGE = (function() {\n    var img = new Image();\n    img.className = \"olTileImage\";\n    img.galleryImg = \"no\";\n    return img;\n}());\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Tile/UTFGrid.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Tile.UTFGrid = OpenLayers.Class(OpenLayers.Tile, {\n\n        url: null,\n    \n        utfgridResolution: 2,\n    \n        json: null,\n    \n        format: null,\n\n    \n        destroy: function() {\n        this.clear();\n        OpenLayers.Tile.prototype.destroy.apply(this, arguments);\n    },\n    \n        draw: function() {\n        var drawn = OpenLayers.Tile.prototype.draw.apply(this, arguments);\n        if (drawn) {\n            if (this.isLoading) {\n                this.abortLoading();\n                this.events.triggerEvent(\"reload\"); \n            } else {\n                this.isLoading = true;\n                this.events.triggerEvent(\"loadstart\");\n            }\n            this.url = this.layer.getURL(this.bounds);\n\n            if (this.layer.useJSONP) {\n                var ols = new OpenLayers.Protocol.Script({\n                    url: this.url,\n                    callback: function(response) {\n                        this.isLoading = false;\n                        this.events.triggerEvent(\"loadend\");\n                        this.json = response.data;\n                    },\n                    scope: this\n                });\n                ols.read();\n                this.request = ols;\n            } else {\n                this.request = OpenLayers.Request.GET({\n                    url: this.url,\n                    callback: function(response) {\n                        this.isLoading = false;\n                        this.events.triggerEvent(\"loadend\");\n                        if (response.status === 200) {\n                            this.parseData(response.responseText);\n                        }\n                    },\n                    scope: this\n                });\n            }\n        } else {\n            this.unload();\n        }\n        return drawn;\n    },\n    \n        abortLoading: function() {\n        if (this.request) {\n            this.request.abort();\n            delete this.request;\n        }\n        this.isLoading = false;\n    },\n    \n        getFeatureInfo: function(i, j) {\n        var info = null;\n        if (this.json) {\n            var id = this.getFeatureId(i, j);\n            if (id !== null) {\n                info = {id: id, data: this.json.data[id]};\n            }\n        }\n        return info;\n    },\n    \n        getFeatureId: function(i, j) {\n        var id = null;\n        if (this.json) {\n            var resolution = this.utfgridResolution;\n            var row = Math.floor(j / resolution);\n            var col = Math.floor(i / resolution);\n            var charCode = this.json.grid[row].charCodeAt(col);\n            var index = this.indexFromCharCode(charCode);\n            var keys = this.json.keys;\n            if (!isNaN(index) && (index in keys)) {\n                id = keys[index];\n            }\n        }\n        return id;\n    },\n    \n        indexFromCharCode: function(charCode) {\n        if (charCode >= 93) {\n            charCode--;\n        }\n        if (charCode >= 35) {\n            charCode --;\n        }\n        return charCode - 32;\n    },\n    \n        parseData: function(str) {\n        if (!this.format) {\n            this.format = new OpenLayers.Format.JSON();\n        }\n        this.json = this.format.read(str);\n    },\n    \n        clear: function() {\n        this.json = null;\n    },\n    \n    CLASS_NAME: \"OpenLayers.Tile.UTFGrid\"\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Tile.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.Tile = OpenLayers.Class({\n    \n        events: null,\n\n        eventListeners: null,\n\n        id: null,\n    \n        layer: null,\n    \n        url: null,\n\n        bounds: null,\n    \n        size: null,\n    \n        isLoading: false,\n    \n    \n        unload: function() {\n       if (this.isLoading) { \n           this.isLoading = false; \n           this.events.triggerEvent(\"unload\"); \n       }\n    },\n    \n        destroy:function() {\n        this.layer  = null;\n        this.bounds = null;\n        this.size = null;\n        this.position = null;\n        \n        if (this.eventListeners) {\n            this.events.un(this.eventListeners);\n        }\n        this.events.destroy();\n        this.eventListeners = null;\n        this.events = null;\n    },\n    \n        draw: function(force) {\n        if (!force) {\n            this.clear();\n        }\n        var draw = this.shouldDraw();\n        if (draw && !force && this.events.triggerEvent(\"beforedraw\") === false) {\n            draw = null;\n        }\n        return draw;\n    },\n    \n        shouldDraw: function() {        \n        var withinMaxExtent = false,\n            maxExtent = this.layer.maxExtent;\n        if (maxExtent) {\n            var map = this.layer.map;\n            var worldBounds = map.baseLayer.wrapDateLine && map.getMaxExtent();\n            if (this.bounds.intersectsBounds(maxExtent, {inclusive: false, worldBounds: worldBounds})) {\n                withinMaxExtent = true;\n            }\n        }\n        \n        return withinMaxExtent || this.layer.displayOutsideMaxExtent;\n    },\n    \n        setBounds: function(bounds) {\n        bounds = bounds.clone();\n        if (this.layer.map.baseLayer.wrapDateLine) {\n            var worldExtent = this.layer.map.getMaxExtent(),\n                tolerance = this.layer.map.getResolution();\n            bounds = bounds.wrapDateLine(worldExtent, {\n                leftTolerance: tolerance,\n                rightTolerance: tolerance\n            });\n        }\n        this.bounds = bounds;\n    },\n    \n        moveTo: function (bounds, position, redraw) {\n        if (redraw == null) {\n            redraw = true;\n        }\n\n        this.setBounds(bounds);\n        this.position = position.clone();\n        if (redraw) {\n            this.draw();\n        }\n    },\n\n        clear: function(draw) {\n    },\n    \n    CLASS_NAME: \"OpenLayers.Tile\"\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/TileManager.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.TileManager = OpenLayers.Class({\n    \n        cacheSize: 256,\n\n        tilesPerFrame: 2,\n\n        frameDelay: 16,\n\n        moveDelay: 100,\n    \n        zoomDelay: 200,\n    \n        maps: null,\n    \n        tileQueueId: null,\n\n        tileQueue: null,\n    \n        tileCache: null,\n    \n        tileCacheIndex: null,    \n    \n        addMap: function(map) {\n        if (this._destroyed || !OpenLayers.Layer.Grid) {\n            return;\n        }\n        this.maps.push(map);\n        this.tileQueue[map.id] = [];\n        for (var i=0, ii=map.layers.length; i<ii; ++i) {\n            this.addLayer({layer: map.layers[i]});\n        }\n        map.events.on({\n            move: this.move,\n            zoomend: this.zoomEnd,\n            changelayer: this.changeLayer,\n            addlayer: this.addLayer,\n            preremovelayer: this.removeLayer,\n            scope: this\n        });\n    },\n    \n        removeMap: function(map) {\n        if (this._destroyed || !OpenLayers.Layer.Grid) {\n            return;\n        }\n        window.clearTimeout(this.tileQueueId[map.id]);\n        if (map.layers) {\n            for (var i=0, ii=map.layers.length; i<ii; ++i) {\n                this.removeLayer({layer: map.layers[i]});\n            }\n        }\n        if (map.events) {\n            map.events.un({\n                move: this.move,\n                zoomend: this.zoomEnd,\n                changelayer: this.changeLayer,\n                addlayer: this.addLayer,\n                preremovelayer: this.removeLayer,\n                scope: this\n            });\n        }\n        delete this.tileQueue[map.id];\n        delete this.tileQueueId[map.id];\n        OpenLayers.Util.removeItem(this.maps, map);\n    },\n    \n        move: function(evt) {\n        this.updateTimeout(evt.object, this.moveDelay, true);\n    },\n    \n        zoomEnd: function(evt) {\n        this.updateTimeout(evt.object, this.zoomDelay);\n    },\n    \n        changeLayer: function(evt) {\n        if (evt.property === 'visibility' || evt.property === 'params') {\n            this.updateTimeout(evt.object, 0);\n        }\n    },\n    \n        addLayer: function(evt) {\n        var layer = evt.layer;\n        if (layer instanceof OpenLayers.Layer.Grid) {\n            layer.events.on({\n                addtile: this.addTile,\n                refresh: this.handleLayerRefresh,\n                retile: this.clearTileQueue,\n                scope: this\n            });\n            var i, j, tile;\n            for (i=layer.grid.length-1; i>=0; --i) {\n                for (j=layer.grid[i].length-1; j>=0; --j) {\n                    tile = layer.grid[i][j];\n                    this.addTile({tile: tile});\n                    if (tile.url && !tile.imgDiv) {\n                        this.manageTileCache({object: tile});\n                    }\n                }\n            }\n        }\n    },\n    \n        removeLayer: function(evt) {\n        var layer = evt.layer;\n        if (layer instanceof OpenLayers.Layer.Grid) {\n            this.clearTileQueue({object: layer});\n            if (layer.events) {\n                layer.events.un({\n                    addtile: this.addTile,\n                    refresh: this.handleLayerRefresh,\n                    retile: this.clearTileQueue,\n                    scope: this\n                });\n            }\n            if (layer.grid) {\n                var i, j, tile;\n                for (i=layer.grid.length-1; i>=0; --i) {\n                    for (j=layer.grid[i].length-1; j>=0; --j) {\n                        tile = layer.grid[i][j];\n                        this.unloadTile({object: tile});\n                    }\n                }\n            }\n        }\n    },\n\n        handleLayerRefresh: function(evt) {\n        var layer = evt.object;\n        if (layer.grid) {\n            var i, j, tile;\n            for (i=layer.grid.length-1; i>=0; --i) {\n                for (j=layer.grid[i].length-1; j>=0; --j) {\n                    tile = layer.grid[i][j];\n                    OpenLayers.Util.removeItem(this.tileCacheIndex, tile.url);\n                    delete this.tileCache[tile.url];\n                }\n            }\n        }\n    },\n    \n        updateTimeout: function(map, delay, nice) {\n        window.clearTimeout(this.tileQueueId[map.id]);\n        var tileQueue = this.tileQueue[map.id];\n        if (!nice || tileQueue.length) {\n            this.tileQueueId[map.id] = window.setTimeout(\n                OpenLayers.Function.bind(function() {\n                    this.drawTilesFromQueue(map);\n                    if (tileQueue.length) {\n                        this.updateTimeout(map, this.frameDelay);\n                    }\n                }, this), delay\n            );\n        }\n    },\n    \n        addTile: function(evt) {\n        if (evt.tile instanceof OpenLayers.Tile.Image) {\n          if (!evt.tile.layer.singleTile) {\n            evt.tile.events.on({\n                beforedraw: this.queueTileDraw,\n                beforeload: this.manageTileCache,\n                loadend: this.addToCache,\n                unload: this.unloadTile,\n                scope: this\n            });        \n          }\n        } else {\n            this.removeLayer({layer: evt.tile.layer});\n        }\n    },\n    \n        unloadTile: function(evt) {\n        var tile = evt.object;\n        tile.events.un({\n            beforedraw: this.queueTileDraw,\n            beforeload: this.manageTileCache,\n            loadend: this.addToCache,\n            unload: this.unloadTile,\n            scope: this\n        });\n        OpenLayers.Util.removeItem(this.tileQueue[tile.layer.map.id], tile);\n    },\n    \n        queueTileDraw: function(evt) {\n        var tile = evt.object;\n        var queued = false;\n        var layer = tile.layer;\n        var url = layer.getURL(tile.bounds);\n        var img = this.tileCache[url];\n        if (img && img.className !== 'olTileImage') {\n            delete this.tileCache[url];\n            OpenLayers.Util.removeItem(this.tileCacheIndex, url);\n            img = null;\n        }\n        if (layer.url && (layer.async || !img)) {\n            var tileQueue = this.tileQueue[layer.map.id];\n            if (!~OpenLayers.Util.indexOf(tileQueue, tile)) {\n                tileQueue.push(tile);\n            }\n            queued = true;\n        }\n        return !queued;\n    },\n    \n        drawTilesFromQueue: function(map) {\n        var tileQueue = this.tileQueue[map.id];\n        var limit = this.tilesPerFrame;\n        var animating = map.zoomTween && map.zoomTween.playing;\n        while (!animating && tileQueue.length && limit) {\n            tileQueue.shift().draw(true);\n            --limit;\n        }\n    },\n    \n        manageTileCache: function(evt) {\n        var tile = evt.object;\n        var img = this.tileCache[tile.url];\n        if (img) {\n          if (img.parentNode &&\n                  OpenLayers.Element.hasClass(img.parentNode, 'olBackBuffer')) {\n              img.parentNode.removeChild(img);\n              img.id = null;\n          }\n          if (!img.parentNode) {\n              img.style.visibility = 'hidden';\n              img.style.opacity = 0;\n              tile.setImage(img);\n              OpenLayers.Util.removeItem(this.tileCacheIndex, tile.url);\n              this.tileCacheIndex.push(tile.url);\n          }\n        }\n    },\n    \n        addToCache: function(evt) {\n        var tile = evt.object;\n        if (!this.tileCache[tile.url]) {\n            if (!OpenLayers.Element.hasClass(tile.imgDiv, 'olImageLoadError')) {\n                if (this.tileCacheIndex.length >= this.cacheSize) {\n                    delete this.tileCache[this.tileCacheIndex[0]];\n                    this.tileCacheIndex.shift();\n                }\n                this.tileCache[tile.url] = tile.imgDiv;\n                this.tileCacheIndex.push(tile.url);\n            }\n        }\n    },\n\n        clearTileQueue: function(evt) {\n        var layer = evt.object;\n        var tileQueue = this.tileQueue[layer.map.id];\n        for (var i=tileQueue.length-1; i>=0; --i) {\n            if (tileQueue[i].layer === layer) {\n                tileQueue.splice(i, 1);\n            }\n        }\n    },\n    \n        destroy: function() {\n        for (var i=this.maps.length-1; i>=0; --i) {\n            this.removeMap(this.maps[i]);\n        }\n        this.maps = null;\n        this.tileQueue = null;\n        this.tileQueueId = null;\n        this.tileCache = null;\n        this.tileCacheIndex = null;\n        this._destroyed = true;\n    }\n\n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Tween.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Tween = OpenLayers.Class({\n    \n        easing: null,\n    \n        begin: null,\n    \n        finish: null,\n    \n        duration: null,\n    \n        callbacks: null,\n    \n        time: null,\n    \n        minFrameRate: null,\n\n        startTime: null,\n    \n        animationId: null,\n    \n        playing: false,\n    \n        start: function(begin, finish, duration, options) {\n        this.playing = true;\n        this.begin = begin;\n        this.finish = finish;\n        this.duration = duration;\n        this.callbacks = options.callbacks;\n        this.minFrameRate = options.minFrameRate || 30;\n        this.time = 0;\n        this.startTime = new Date().getTime();\n        OpenLayers.Animation.stop(this.animationId);\n        this.animationId = null;\n        if (this.callbacks && this.callbacks.start) {\n            this.callbacks.start.call(this, this.begin);\n        }\n        this.animationId = OpenLayers.Animation.start(\n            OpenLayers.Function.bind(this.play, this)\n        );\n    },\n    \n        stop: function() {\n        if (!this.playing) {\n            return;\n        }\n        \n        if (this.callbacks && this.callbacks.done) {\n            this.callbacks.done.call(this, this.finish);\n        }\n        OpenLayers.Animation.stop(this.animationId);\n        this.animationId = null;\n        this.playing = false;\n    },\n    \n        play: function() {\n        var value = {};\n        for (var i in this.begin) {\n            var b = this.begin[i];\n            var f = this.finish[i];\n            if (b == null || f == null || isNaN(b) || isNaN(f)) {\n                throw new TypeError('invalid value for Tween');\n            }\n\n            var c = f - b;\n            value[i] = this.easing.apply(this, [this.time, b, c, this.duration]);\n        }\n        this.time++;\n        \n        if (this.callbacks && this.callbacks.eachStep) {\n            if ((new Date().getTime() - this.startTime) / this.time <= 1000 / this.minFrameRate) {\n                this.callbacks.eachStep.call(this, value);\n            }\n        }\n        \n        if (this.time > this.duration) {\n            this.stop();\n        }\n    },\n    \n        CLASS_NAME: \"OpenLayers.Tween\"\n});\n\nOpenLayers.Easing = {\n        CLASS_NAME: \"OpenLayers.Easing\"\n};\n\nOpenLayers.Easing.Linear = {\n    \n        easeIn: function(t, b, c, d) {\n        return c*t/d + b;\n    },\n    \n        easeOut: function(t, b, c, d) {\n        return c*t/d + b;\n    },\n    \n        easeInOut: function(t, b, c, d) {\n        return c*t/d + b;\n    },\n\n    CLASS_NAME: \"OpenLayers.Easing.Linear\"\n};\n\nOpenLayers.Easing.Expo = {\n    \n        easeIn: function(t, b, c, d) {\n        return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;\n    },\n    \n        easeOut: function(t, b, c, d) {\n        return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;\n    },\n    \n        easeInOut: function(t, b, c, d) {\n        if (t==0) return b;\n        if (t==d) return b+c;\n        if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;\n        return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;\n    },\n\n    CLASS_NAME: \"OpenLayers.Easing.Expo\"\n};\n\nOpenLayers.Easing.Quad = {\n    \n        easeIn: function(t, b, c, d) {\n        return c*(t/=d)*t + b;\n    },\n    \n        easeOut: function(t, b, c, d) {\n        return -c *(t/=d)*(t-2) + b;\n    },\n    \n        easeInOut: function(t, b, c, d) {\n        if ((t/=d/2) < 1) return c/2*t*t + b;\n        return -c/2 * ((--t)*(t-2) - 1) + b;\n    },\n\n    CLASS_NAME: \"OpenLayers.Easing.Quad\"\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Util/vendorPrefix.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Util = OpenLayers.Util || {};\nOpenLayers.Util.vendorPrefix = (function() {\n    \"use strict\";\n    \n    var VENDOR_PREFIXES = [\"\", \"O\", \"ms\", \"Moz\", \"Webkit\"],\n        divStyle = document.createElement(\"div\").style,\n        cssCache = {},\n        jsCache = {};\n\n    \n        function domToCss(prefixedDom) {\n        if (!prefixedDom) { return null; }\n        return prefixedDom.\n            replace(/([A-Z])/g, function(c) { return \"-\" + c.toLowerCase(); }).\n            replace(/^ms-/, \"-ms-\");\n    }\n\n        function css(property) {\n        if (cssCache[property] === undefined) {\n            var domProperty = property.\n                replace(/(-[\\s\\S])/g, function(c) { return c.charAt(1).toUpperCase(); });\n            var prefixedDom = style(domProperty);\n            cssCache[property] = domToCss(prefixedDom);\n        }\n        return cssCache[property];\n    }\n\n        function js(obj, property) {\n        if (jsCache[property] === undefined) {\n            var tmpProp,\n                i = 0,\n                l = VENDOR_PREFIXES.length,\n                prefix,\n                isStyleObj = (typeof obj.cssText !== \"undefined\");\n\n            jsCache[property] = null;\n            for(; i<l; i++) {\n                prefix = VENDOR_PREFIXES[i];\n                if(prefix) {\n                    if (!isStyleObj) {\n                        prefix = prefix.toLowerCase();\n                    }\n                    tmpProp = prefix + property.charAt(0).toUpperCase() + property.slice(1);\n                } else {\n                    tmpProp = property;\n                }\n\n                if(obj[tmpProp] !== undefined) {\n                    jsCache[property] = tmpProp;\n                    break;\n                }\n            }\n        }\n        return jsCache[property];\n    }\n    \n        function style(property) {\n        return js(divStyle, property);\n    }\n    \n    return {\n        css:      css,\n        js:       js,\n        style:    style,\n        cssCache:       cssCache,\n        jsCache:        jsCache\n    };\n}());"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/Util.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\nOpenLayers.Util = OpenLayers.Util || {};\n\nOpenLayers.Util.getElement = function() {\n    var elements = [];\n\n    for (var i=0, len=arguments.length; i<len; i++) {\n        var element = arguments[i];\n        if (typeof element == 'string') {\n            element = document.getElementById(element);\n        }\n        if (arguments.length == 1) {\n            return element;\n        }\n        elements.push(element);\n    }\n    return elements;\n};\n\nOpenLayers.Util.isElement = function(o) {\n    return !!(o && o.nodeType === 1);\n};\n\nOpenLayers.Util.isArray = function(a) {\n    return (Object.prototype.toString.call(a) === '[object Array]');\n};\n\nOpenLayers.Util.removeItem = function(array, item) {\n    for(var i = array.length - 1; i >= 0; i--) {\n        if(array[i] == item) {\n            array.splice(i,1);\n        }\n    }\n    return array;\n};\n\nOpenLayers.Util.indexOf = function(array, obj) {\n    if (typeof array.indexOf == \"function\") {\n        return array.indexOf(obj);\n    } else {\n        for (var i = 0, len = array.length; i < len; i++) {\n            if (array[i] == obj) {\n                return i;\n            }\n        }\n        return -1;   \n    }\n};\n\n\nOpenLayers.Util.dotless = /\\./g;\n\nOpenLayers.Util.modifyDOMElement = function(element, id, px, sz, position, \n                                            border, overflow, opacity) {\n\n    if (id) {\n        element.id = id.replace(OpenLayers.Util.dotless, \"_\");\n    }\n    if (px) {\n        element.style.left = px.x + \"px\";\n        element.style.top = px.y + \"px\";\n    }\n    if (sz) {\n        element.style.width = sz.w + \"px\";\n        element.style.height = sz.h + \"px\";\n    }\n    if (position) {\n        element.style.position = position;\n    }\n    if (border) {\n        element.style.border = border;\n    }\n    if (overflow) {\n        element.style.overflow = overflow;\n    }\n    if (parseFloat(opacity) >= 0.0 && parseFloat(opacity) < 1.0) {\n        element.style.filter = 'alpha(opacity=' + (opacity * 100) + ')';\n        element.style.opacity = opacity;\n    } else if (parseFloat(opacity) == 1.0) {\n        element.style.filter = '';\n        element.style.opacity = '';\n    }\n};\n\nOpenLayers.Util.createDiv = function(id, px, sz, imgURL, position, \n                                     border, overflow, opacity) {\n\n    var dom = document.createElement('div');\n\n    if (imgURL) {\n        dom.style.backgroundImage = 'url(' + imgURL + ')';\n    }\n    if (!id) {\n        id = OpenLayers.Util.createUniqueID(\"OpenLayersDiv\");\n    }\n    if (!position) {\n        position = \"absolute\";\n    }\n    OpenLayers.Util.modifyDOMElement(dom, id, px, sz, position, \n                                     border, overflow, opacity);\n\n    return dom;\n};\n\nOpenLayers.Util.createImage = function(id, px, sz, imgURL, position, border,\n                                       opacity, delayDisplay) {\n\n    var image = document.createElement(\"img\");\n    if (!id) {\n        id = OpenLayers.Util.createUniqueID(\"OpenLayersDiv\");\n    }\n    if (!position) {\n        position = \"relative\";\n    }\n    OpenLayers.Util.modifyDOMElement(image, id, px, sz, position, \n                                     border, null, opacity);\n\n    if (delayDisplay) {\n        image.style.display = \"none\";\n        function display() {\n            image.style.display = \"\";\n            OpenLayers.Event.stopObservingElement(image);\n        }\n        OpenLayers.Event.observe(image, \"load\", display);\n        OpenLayers.Event.observe(image, \"error\", display);\n    }\n    image.style.alt = id;\n    image.galleryImg = \"no\";\n    if (imgURL) {\n        image.src = imgURL;\n    }\n        \n    return image;\n};\n\nOpenLayers.IMAGE_RELOAD_ATTEMPTS = 0;\n\nOpenLayers.Util.alphaHackNeeded = null;\n\nOpenLayers.Util.alphaHack = function() {\n    if (OpenLayers.Util.alphaHackNeeded == null) {\n        var arVersion = navigator.appVersion.split(\"MSIE\");\n        var version = parseFloat(arVersion[1]);\n        var filter = false;\n    \n        try { \n            filter = !!(document.body.filters);\n        } catch (e) {}    \n    \n        OpenLayers.Util.alphaHackNeeded = (filter && \n                                           (version >= 5.5) && (version < 7));\n    }\n    return OpenLayers.Util.alphaHackNeeded;\n};\n\nOpenLayers.Util.upperCaseObject = function (object) {\n    var uObject = {};\n    for (var key in object) {\n        uObject[key.toUpperCase()] = object[key];\n    }\n    return uObject;\n};\n\nOpenLayers.Util.applyDefaults = function (to, from) {\n    to = to || {};\n    /*\n     * FF/Windows < 2.0.0.13 reports \"Illegal operation on WrappedNative\n     * prototype object\" when calling hawOwnProperty if the source object is an\n     * instance of window.Event.\n     */\n    var fromIsEvt = typeof window.Event == \"function\"\n                    && from instanceof window.Event;\n\n    for (var key in from) {\n        if (to[key] === undefined ||\n            (!fromIsEvt && from.hasOwnProperty\n             && from.hasOwnProperty(key) && !to.hasOwnProperty(key))) {\n            to[key] = from[key];\n        }\n    }\n        if(!fromIsEvt && from && from.hasOwnProperty\n       && from.hasOwnProperty('toString') && !to.hasOwnProperty('toString')) {\n        to.toString = from.toString;\n    }\n    \n    return to;\n};\n\nOpenLayers.Util.getParameterString = function(params) {\n    var paramsArray = [];\n    \n    for (var key in params) {\n      var value = params[key];\n      if ((value != null) && (typeof value != 'function')) {\n        var encodedValue;\n        if (typeof value == 'object' && value.constructor == Array) {\n          /* value is an array; encode items and separate with \",\" */\n          var encodedItemArray = [];\n          var item;\n          for (var itemIndex=0, len=value.length; itemIndex<len; itemIndex++) {\n            item = value[itemIndex];\n            encodedItemArray.push(encodeURIComponent(\n                (item === null || item === undefined) ? \"\" : item)\n            );\n          }\n          encodedValue = encodedItemArray.join(\",\");\n        }\n        else {\n          /* value is a string; simply encode */\n          encodedValue = encodeURIComponent(value);\n        }\n        paramsArray.push(encodeURIComponent(key) + \"=\" + encodedValue);\n      }\n    }\n    \n    return paramsArray.join(\"&\");\n};\n\nOpenLayers.Util.urlAppend = function(url, paramStr) {\n    var newUrl = url;\n    if(paramStr) {\n        var parts = (url + \" \").split(/[?&]/);\n        newUrl += (parts.pop() === \" \" ?\n            paramStr :\n            parts.length ? \"&\" + paramStr : \"?\" + paramStr);\n    }\n    return newUrl;\n};\n\nOpenLayers.Util.getImagesLocation = function() {\n    return OpenLayers.ImgPath || (OpenLayers._getScriptLocation() + \"img/\");\n};\n\nOpenLayers.Util.getImageLocation = function(image) {\n    return OpenLayers.Util.getImagesLocation() + image;\n};\n\n\nOpenLayers.Util.Try = function() {\n    var returnValue = null;\n\n    for (var i=0, len=arguments.length; i<len; i++) {\n      var lambda = arguments[i];\n      try {\n        returnValue = lambda();\n        break;\n      } catch (e) {}\n    }\n\n    return returnValue;\n};\n\nOpenLayers.Util.getXmlNodeValue = function(node) {\n    var val = null;\n    OpenLayers.Util.Try( \n        function() {\n            val = node.text;\n            if (!val) {\n                val = node.textContent;\n            }\n            if (!val) {\n                val = node.firstChild.nodeValue;\n            }\n        }, \n        function() {\n            val = node.textContent;\n        }); \n    return val;\n};\n\nOpenLayers.Util.mouseLeft = function (evt, div) {\n    var target = (evt.relatedTarget) ? evt.relatedTarget : evt.toElement;\n    while (target != div && target != null) {\n        target = target.parentNode;\n    }\n    return (target != div);\n};\n\nOpenLayers.Util.DEFAULT_PRECISION = 14;\n\nOpenLayers.Util.toFloat = function (number, precision) {\n    if (precision == null) {\n        precision = OpenLayers.Util.DEFAULT_PRECISION;\n    }\n    if (typeof number !== \"number\") {\n        number = parseFloat(number);\n    }\n    return precision === 0 ? number :\n                             parseFloat(number.toPrecision(precision));\n};\n\nOpenLayers.Util.rad = function(x) {return x*Math.PI/180;};\n\nOpenLayers.Util.deg = function(x) {return x*180/Math.PI;};\n\nOpenLayers.Util.VincentyConstants = {\n    a: 6378137,\n    b: 6356752.3142,\n    f: 1/298.257223563\n};\n\nOpenLayers.Util.distVincenty = function(p1, p2) {\n    var ct = OpenLayers.Util.VincentyConstants;\n    var a = ct.a, b = ct.b, f = ct.f;\n\n    var L = OpenLayers.Util.rad(p2.lon - p1.lon);\n    var U1 = Math.atan((1-f) * Math.tan(OpenLayers.Util.rad(p1.lat)));\n    var U2 = Math.atan((1-f) * Math.tan(OpenLayers.Util.rad(p2.lat)));\n    var sinU1 = Math.sin(U1), cosU1 = Math.cos(U1);\n    var sinU2 = Math.sin(U2), cosU2 = Math.cos(U2);\n    var lambda = L, lambdaP = 2*Math.PI;\n    var iterLimit = 20;\n    while (Math.abs(lambda-lambdaP) > 1e-12 && --iterLimit>0) {\n        var sinLambda = Math.sin(lambda), cosLambda = Math.cos(lambda);\n        var sinSigma = Math.sqrt((cosU2*sinLambda) * (cosU2*sinLambda) +\n        (cosU1*sinU2-sinU1*cosU2*cosLambda) * (cosU1*sinU2-sinU1*cosU2*cosLambda));\n        if (sinSigma==0) {\n            return 0;  // co-incident points\n        }\n        var cosSigma = sinU1*sinU2 + cosU1*cosU2*cosLambda;\n        var sigma = Math.atan2(sinSigma, cosSigma);\n        var alpha = Math.asin(cosU1 * cosU2 * sinLambda / sinSigma);\n        var cosSqAlpha = Math.cos(alpha) * Math.cos(alpha);\n        var cos2SigmaM = cosSigma - 2*sinU1*sinU2/cosSqAlpha;\n        var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));\n        lambdaP = lambda;\n        lambda = L + (1-C) * f * Math.sin(alpha) *\n        (sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));\n    }\n    if (iterLimit==0) {\n        return NaN;  // formula failed to converge\n    }\n    var uSq = cosSqAlpha * (a*a - b*b) / (b*b);\n    var A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));\n    var B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));\n    var deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-\n        B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));\n    var s = b*A*(sigma-deltaSigma);\n    var d = s.toFixed(3)/1000; // round to 1mm precision\n    return d;\n};\n\nOpenLayers.Util.destinationVincenty = function(lonlat, brng, dist) {\n    var u = OpenLayers.Util;\n    var ct = u.VincentyConstants;\n    var a = ct.a, b = ct.b, f = ct.f;\n\n    var lon1 = lonlat.lon;\n    var lat1 = lonlat.lat;\n\n    var s = dist;\n    var alpha1 = u.rad(brng);\n    var sinAlpha1 = Math.sin(alpha1);\n    var cosAlpha1 = Math.cos(alpha1);\n\n    var tanU1 = (1-f) * Math.tan(u.rad(lat1));\n    var cosU1 = 1 / Math.sqrt((1 + tanU1*tanU1)), sinU1 = tanU1*cosU1;\n    var sigma1 = Math.atan2(tanU1, cosAlpha1);\n    var sinAlpha = cosU1 * sinAlpha1;\n    var cosSqAlpha = 1 - sinAlpha*sinAlpha;\n    var uSq = cosSqAlpha * (a*a - b*b) / (b*b);\n    var A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));\n    var B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));\n\n    var sigma = s / (b*A), sigmaP = 2*Math.PI;\n    while (Math.abs(sigma-sigmaP) > 1e-12) {\n        var cos2SigmaM = Math.cos(2*sigma1 + sigma);\n        var sinSigma = Math.sin(sigma);\n        var cosSigma = Math.cos(sigma);\n        var deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-\n            B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));\n        sigmaP = sigma;\n        sigma = s / (b*A) + deltaSigma;\n    }\n\n    var tmp = sinU1*sinSigma - cosU1*cosSigma*cosAlpha1;\n    var lat2 = Math.atan2(sinU1*cosSigma + cosU1*sinSigma*cosAlpha1,\n        (1-f)*Math.sqrt(sinAlpha*sinAlpha + tmp*tmp));\n    var lambda = Math.atan2(sinSigma*sinAlpha1, cosU1*cosSigma - sinU1*sinSigma*cosAlpha1);\n    var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));\n    var L = lambda - (1-C) * f * sinAlpha *\n        (sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));\n\n    var revAz = Math.atan2(sinAlpha, -tmp);  // final bearing\n\n    return new OpenLayers.LonLat(lon1+u.deg(L), u.deg(lat2));\n};\n\nOpenLayers.Util.getParameters = function(url, options) {\n    options = options || {};\n    url = (url === null || url === undefined) ? window.location.href : url;\n    var paramsString = \"\";\n    if (OpenLayers.String.contains(url, '?')) {\n        var start = url.indexOf('?') + 1;\n        var end = OpenLayers.String.contains(url, \"#\") ?\n                    url.indexOf('#') : url.length;\n        paramsString = url.substring(start, end);\n    }\n\n    var parameters = {};\n    var pairs = paramsString.split(/[&;]/);\n    for(var i=0, len=pairs.length; i<len; ++i) {\n        var keyValue = pairs[i].split('=');\n        if (keyValue[0]) {\n\n            var key = keyValue[0];\n            try {\n                key = decodeURIComponent(key);\n            } catch (err) {\n                key = unescape(key);\n            }\n            var value = (keyValue[1] || '').replace(/\\+/g, \" \");\n\n            try {\n                value = decodeURIComponent(value);\n            } catch (err) {\n                value = unescape(value);\n            }\n            if (options.splitArgs !== false) {\n                value = value.split(\",\");\n            }\n            if (value.length == 1) {\n                value = value[0];\n            }                \n            \n            parameters[key] = value;\n         }\n     }\n    return parameters;\n};\n\nOpenLayers.Util.lastSeqID = 0;\n\nOpenLayers.Util.createUniqueID = function(prefix) {\n    if (prefix == null) {\n        prefix = \"id_\";\n    } else {\n        prefix = prefix.replace(OpenLayers.Util.dotless, \"_\");\n    }\n    OpenLayers.Util.lastSeqID += 1; \n    return prefix + OpenLayers.Util.lastSeqID;        \n};\n\nOpenLayers.INCHES_PER_UNIT = { \n    'inches': 1.0,\n    'ft': 12.0,\n    'mi': 63360.0,\n    'm': 39.37,\n    'km': 39370,\n    'dd': 4374754,\n    'yd': 36\n};\nOpenLayers.INCHES_PER_UNIT[\"in\"]= OpenLayers.INCHES_PER_UNIT.inches;\nOpenLayers.INCHES_PER_UNIT[\"degrees\"] = OpenLayers.INCHES_PER_UNIT.dd;\nOpenLayers.INCHES_PER_UNIT[\"nmi\"] = 1852 * OpenLayers.INCHES_PER_UNIT.m;\nOpenLayers.METERS_PER_INCH = 0.02540005080010160020;\nOpenLayers.Util.extend(OpenLayers.INCHES_PER_UNIT, {\n    \"Inch\": OpenLayers.INCHES_PER_UNIT.inches,\n    \"Meter\": 1.0 / OpenLayers.METERS_PER_INCH,   //EPSG:9001\n    \"Foot\": 0.30480060960121920243 / OpenLayers.METERS_PER_INCH,   //EPSG:9003\n    \"IFoot\": 0.30480000000000000000 / OpenLayers.METERS_PER_INCH,   //EPSG:9002\n    \"ClarkeFoot\": 0.3047972651151 / OpenLayers.METERS_PER_INCH,   //EPSG:9005\n    \"SearsFoot\": 0.30479947153867624624 / OpenLayers.METERS_PER_INCH,   //EPSG:9041\n    \"GoldCoastFoot\": 0.30479971018150881758 / OpenLayers.METERS_PER_INCH,   //EPSG:9094\n    \"IInch\": 0.02540000000000000000 / OpenLayers.METERS_PER_INCH,\n    \"MicroInch\": 0.00002540000000000000 / OpenLayers.METERS_PER_INCH,\n    \"Mil\": 0.00000002540000000000 / OpenLayers.METERS_PER_INCH,\n    \"Centimeter\": 0.01000000000000000000 / OpenLayers.METERS_PER_INCH,\n    \"Kilometer\": 1000.00000000000000000000 / OpenLayers.METERS_PER_INCH,   //EPSG:9036\n    \"Yard\": 0.91440182880365760731 / OpenLayers.METERS_PER_INCH,\n    \"SearsYard\": 0.914398414616029 / OpenLayers.METERS_PER_INCH,   //EPSG:9040\n    \"IndianYard\": 0.91439853074444079983 / OpenLayers.METERS_PER_INCH,   //EPSG:9084\n    \"IndianYd37\": 0.91439523 / OpenLayers.METERS_PER_INCH,   //EPSG:9085\n    \"IndianYd62\": 0.9143988 / OpenLayers.METERS_PER_INCH,   //EPSG:9086\n    \"IndianYd75\": 0.9143985 / OpenLayers.METERS_PER_INCH,   //EPSG:9087\n    \"IndianFoot\": 0.30479951 / OpenLayers.METERS_PER_INCH,   //EPSG:9080\n    \"IndianFt37\": 0.30479841 / OpenLayers.METERS_PER_INCH,   //EPSG:9081\n    \"IndianFt62\": 0.3047996 / OpenLayers.METERS_PER_INCH,   //EPSG:9082\n    \"IndianFt75\": 0.3047995 / OpenLayers.METERS_PER_INCH,   //EPSG:9083\n    \"Mile\": 1609.34721869443738887477 / OpenLayers.METERS_PER_INCH,\n    \"IYard\": 0.91440000000000000000 / OpenLayers.METERS_PER_INCH,   //EPSG:9096\n    \"IMile\": 1609.34400000000000000000 / OpenLayers.METERS_PER_INCH,   //EPSG:9093\n    \"NautM\": 1852.00000000000000000000 / OpenLayers.METERS_PER_INCH,   //EPSG:9030\n    \"Lat-66\": 110943.316488932731 / OpenLayers.METERS_PER_INCH,\n    \"Lat-83\": 110946.25736872234125 / OpenLayers.METERS_PER_INCH,\n    \"Decimeter\": 0.10000000000000000000 / OpenLayers.METERS_PER_INCH,\n    \"Millimeter\": 0.00100000000000000000 / OpenLayers.METERS_PER_INCH,\n    \"Dekameter\": 10.00000000000000000000 / OpenLayers.METERS_PER_INCH,\n    \"Decameter\": 10.00000000000000000000 / OpenLayers.METERS_PER_INCH,\n    \"Hectometer\": 100.00000000000000000000 / OpenLayers.METERS_PER_INCH,\n    \"GermanMeter\": 1.0000135965 / OpenLayers.METERS_PER_INCH,   //EPSG:9031\n    \"CaGrid\": 0.999738 / OpenLayers.METERS_PER_INCH,\n    \"ClarkeChain\": 20.1166194976 / OpenLayers.METERS_PER_INCH,   //EPSG:9038\n    \"GunterChain\": 20.11684023368047 / OpenLayers.METERS_PER_INCH,   //EPSG:9033\n    \"BenoitChain\": 20.116782494375872 / OpenLayers.METERS_PER_INCH,   //EPSG:9062\n    \"SearsChain\": 20.11676512155 / OpenLayers.METERS_PER_INCH,   //EPSG:9042\n    \"ClarkeLink\": 0.201166194976 / OpenLayers.METERS_PER_INCH,   //EPSG:9039\n    \"GunterLink\": 0.2011684023368047 / OpenLayers.METERS_PER_INCH,   //EPSG:9034\n    \"BenoitLink\": 0.20116782494375872 / OpenLayers.METERS_PER_INCH,   //EPSG:9063\n    \"SearsLink\": 0.2011676512155 / OpenLayers.METERS_PER_INCH,   //EPSG:9043\n    \"Rod\": 5.02921005842012 / OpenLayers.METERS_PER_INCH,\n    \"IntnlChain\": 20.1168 / OpenLayers.METERS_PER_INCH,   //EPSG:9097\n    \"IntnlLink\": 0.201168 / OpenLayers.METERS_PER_INCH,   //EPSG:9098\n    \"Perch\": 5.02921005842012 / OpenLayers.METERS_PER_INCH,\n    \"Pole\": 5.02921005842012 / OpenLayers.METERS_PER_INCH,\n    \"Furlong\": 201.1684023368046 / OpenLayers.METERS_PER_INCH,\n    \"Rood\": 3.778266898 / OpenLayers.METERS_PER_INCH,\n    \"CapeFoot\": 0.3047972615 / OpenLayers.METERS_PER_INCH,\n    \"Brealey\": 375.00000000000000000000 / OpenLayers.METERS_PER_INCH,\n    \"ModAmFt\": 0.304812252984505969011938 / OpenLayers.METERS_PER_INCH,\n    \"Fathom\": 1.8288 / OpenLayers.METERS_PER_INCH,\n    \"NautM-UK\": 1853.184 / OpenLayers.METERS_PER_INCH,\n    \"50kilometers\": 50000.0 / OpenLayers.METERS_PER_INCH,\n    \"150kilometers\": 150000.0 / OpenLayers.METERS_PER_INCH\n});\nOpenLayers.Util.extend(OpenLayers.INCHES_PER_UNIT, {\n    \"mm\": OpenLayers.INCHES_PER_UNIT[\"Meter\"] / 1000.0,\n    \"cm\": OpenLayers.INCHES_PER_UNIT[\"Meter\"] / 100.0,\n    \"dm\": OpenLayers.INCHES_PER_UNIT[\"Meter\"] * 100.0,\n    \"km\": OpenLayers.INCHES_PER_UNIT[\"Meter\"] * 1000.0,\n    \"kmi\": OpenLayers.INCHES_PER_UNIT[\"nmi\"],    //International Nautical Mile\n    \"fath\": OpenLayers.INCHES_PER_UNIT[\"Fathom\"], //International Fathom\n    \"ch\": OpenLayers.INCHES_PER_UNIT[\"IntnlChain\"],  //International Chain\n    \"link\": OpenLayers.INCHES_PER_UNIT[\"IntnlLink\"], //International Link\n    \"us-in\": OpenLayers.INCHES_PER_UNIT[\"inches\"], //U.S. Surveyor's Inch\n    \"us-ft\": OpenLayers.INCHES_PER_UNIT[\"Foot\"], //U.S. Surveyor's Foot\n    \"us-yd\": OpenLayers.INCHES_PER_UNIT[\"Yard\"], //U.S. Surveyor's Yard\n    \"us-ch\": OpenLayers.INCHES_PER_UNIT[\"GunterChain\"], //U.S. Surveyor's Chain\n    \"us-mi\": OpenLayers.INCHES_PER_UNIT[\"Mile\"],   //U.S. Surveyor's Statute Mile\n    \"ind-yd\": OpenLayers.INCHES_PER_UNIT[\"IndianYd37\"],  //Indian Yard\n    \"ind-ft\": OpenLayers.INCHES_PER_UNIT[\"IndianFt37\"],  //Indian Foot\n    \"ind-ch\": 20.11669506 / OpenLayers.METERS_PER_INCH  //Indian Chain\n});\n\nOpenLayers.DOTS_PER_INCH = 72;\n\nOpenLayers.Util.normalizeScale = function (scale) {\n    var normScale = (scale > 1.0) ? (1.0 / scale) \n                                  : scale;\n    return normScale;\n};\n\nOpenLayers.Util.getResolutionFromScale = function (scale, units) {\n    var resolution;\n    if (scale) {\n        if (units == null) {\n            units = \"degrees\";\n        }\n        var normScale = OpenLayers.Util.normalizeScale(scale);\n        resolution = 1 / (normScale * OpenLayers.INCHES_PER_UNIT[units]\n                                        * OpenLayers.DOTS_PER_INCH);        \n    }\n    return resolution;\n};\n\nOpenLayers.Util.getScaleFromResolution = function (resolution, units) {\n\n    if (units == null) {\n        units = \"degrees\";\n    }\n\n    var scale = resolution * OpenLayers.INCHES_PER_UNIT[units] *\n                    OpenLayers.DOTS_PER_INCH;\n    return scale;\n};\n\nOpenLayers.Util.pagePosition =  function(forElement) {\n\n    var pos = [0, 0];\n    var viewportElement = OpenLayers.Util.getViewportElement();\n    if (!forElement || forElement == window || forElement == viewportElement) {\n        return pos;\n    }\n    var BUGGY_GECKO_BOX_OBJECT =\n        OpenLayers.IS_GECKO && document.getBoxObjectFor &&\n        OpenLayers.Element.getStyle(forElement, 'position') == 'absolute' &&\n        (forElement.style.top == '' || forElement.style.left == '');\n\n    var parent = null;\n    var box;\n\n    if (forElement.getBoundingClientRect) { // IE\n        box = forElement.getBoundingClientRect();\n        var scrollTop = window.pageYOffset || viewportElement.scrollTop;\n        var scrollLeft = window.pageXOffset || viewportElement.scrollLeft;\n        \n        pos[0] = box.left + scrollLeft;\n        pos[1] = box.top + scrollTop;\n\n    } else if (document.getBoxObjectFor && !BUGGY_GECKO_BOX_OBJECT) { // gecko\n\n        box = document.getBoxObjectFor(forElement);\n        var vpBox = document.getBoxObjectFor(viewportElement);\n        pos[0] = box.screenX - vpBox.screenX;\n        pos[1] = box.screenY - vpBox.screenY;\n\n    } else { // safari/opera\n        pos[0] = forElement.offsetLeft;\n        pos[1] = forElement.offsetTop;\n        parent = forElement.offsetParent;\n        if (parent != forElement) {\n            while (parent) {\n                pos[0] += parent.offsetLeft;\n                pos[1] += parent.offsetTop;\n                parent = parent.offsetParent;\n            }\n        }\n\n        var browser = OpenLayers.BROWSER_NAME;\n        if (browser == \"opera\" || (browser == \"safari\" &&\n              OpenLayers.Element.getStyle(forElement, 'position') == 'absolute')) {\n            pos[1] -= document.body.offsetTop;\n        }\n        parent = forElement.offsetParent;\n        while (parent && parent != document.body) {\n            pos[0] -= parent.scrollLeft;\n            if (browser != \"opera\" || parent.tagName != 'TR') {\n                pos[1] -= parent.scrollTop;\n            }\n            parent = parent.offsetParent;\n        }\n    }\n    \n    return pos;\n};\n\nOpenLayers.Util.getViewportElement = function() {\n    var viewportElement = arguments.callee.viewportElement;\n    if (viewportElement == undefined) {\n        viewportElement = (OpenLayers.BROWSER_NAME == \"msie\" &&\n            document.compatMode != 'CSS1Compat') ? document.body :\n            document.documentElement;\n        arguments.callee.viewportElement = viewportElement;\n    }\n    return viewportElement;\n};\n\nOpenLayers.Util.isEquivalentUrl = function(url1, url2, options) {\n    options = options || {};\n\n    OpenLayers.Util.applyDefaults(options, {\n        ignoreCase: true,\n        ignorePort80: true,\n        ignoreHash: true,\n        splitArgs: false\n    });\n\n    var urlObj1 = OpenLayers.Util.createUrlObject(url1, options);\n    var urlObj2 = OpenLayers.Util.createUrlObject(url2, options);\n    for(var key in urlObj1) {\n        if(key !== \"args\") {\n            if(urlObj1[key] != urlObj2[key]) {\n                return false;\n            }\n        }\n    }\n    for(var key in urlObj1.args) {\n        if(urlObj1.args[key] != urlObj2.args[key]) {\n            return false;\n        }\n        delete urlObj2.args[key];\n    }\n    for(var key in urlObj2.args) {\n        return false;\n    }\n    \n    return true;\n};\n\nOpenLayers.Util.createUrlObject = function(url, options) {\n    options = options || {};\n    if(!(/^\\w+:\\/\\//).test(url)) {\n        var loc = window.location;\n        var port = loc.port ? \":\" + loc.port : \"\";\n        var fullUrl = loc.protocol + \"//\" + loc.host.split(\":\").shift() + port;\n        if(url.indexOf(\"/\") === 0) {\n            url = fullUrl + url;\n        } else {\n            var parts = loc.pathname.split(\"/\");\n            parts.pop();\n            url = fullUrl + parts.join(\"/\") + \"/\" + url;\n        }\n    }\n  \n    if (options.ignoreCase) {\n        url = url.toLowerCase(); \n    }\n\n    var a = document.createElement('a');\n    a.href = url;\n    \n    var urlObject = {};\n    urlObject.host = a.host.split(\":\").shift();\n    urlObject.protocol = a.protocol;  \n    if(options.ignorePort80) {\n        urlObject.port = (a.port == \"80\" || a.port == \"0\") ? \"\" : a.port;\n    } else {\n        urlObject.port = (a.port == \"\" || a.port == \"0\") ? \"80\" : a.port;\n    }\n    urlObject.hash = (options.ignoreHash || a.hash === \"#\") ? \"\" : a.hash;  \n    var queryString = a.search;\n    if (!queryString) {\n        var qMark = url.indexOf(\"?\");\n        queryString = (qMark != -1) ? url.substr(qMark) : \"\";\n    }\n    urlObject.args = OpenLayers.Util.getParameters(queryString,\n            {splitArgs: options.splitArgs});\n    urlObject.pathname = (a.pathname.charAt(0) == \"/\") ? a.pathname : \"/\" + a.pathname;\n    \n    return urlObject; \n};\n \nOpenLayers.Util.removeTail = function(url) {\n    var head = null;\n    \n    var qMark = url.indexOf(\"?\");\n    var hashMark = url.indexOf(\"#\");\n\n    if (qMark == -1) {\n        head = (hashMark != -1) ? url.substr(0,hashMark) : url;\n    } else {\n        head = (hashMark != -1) ? url.substr(0,Math.min(qMark, hashMark)) \n                                  : url.substr(0, qMark);\n    }\n    return head;\n};\n\nOpenLayers.IS_GECKO = (function() {\n    var ua = navigator.userAgent.toLowerCase();\n    return ua.indexOf(\"webkit\") == -1 && ua.indexOf(\"gecko\") != -1;\n})();\n\nOpenLayers.CANVAS_SUPPORTED = (function() {\n    var elem = document.createElement('canvas');\n    return !!(elem.getContext && elem.getContext('2d'));\n})();\n\nOpenLayers.BROWSER_NAME = (function() {\n    var name = \"\";\n    var ua = navigator.userAgent.toLowerCase();\n    if (ua.indexOf(\"opera\") != -1) {\n        name = \"opera\";\n    } else if (ua.indexOf(\"msie\") != -1) {\n        name = \"msie\";\n    } else if (ua.indexOf(\"safari\") != -1) {\n        name = \"safari\";\n    } else if (ua.indexOf(\"mozilla\") != -1) {\n        if (ua.indexOf(\"firefox\") != -1) {\n            name = \"firefox\";\n        } else {\n            name = \"mozilla\";\n        }\n    }\n    return name;\n})();\n\nOpenLayers.Util.getBrowserName = function() {\n    return OpenLayers.BROWSER_NAME;\n};\n\nOpenLayers.Util.getRenderedDimensions = function(contentHTML, size, options) {\n    \n    var w, h;\n    var container = document.createElement(\"div\");\n    container.style.visibility = \"hidden\";\n        \n    var containerElement = (options && options.containerElement) \n        ? options.containerElement : document.body;\n    var parentHasPositionAbsolute = false;\n    var superContainer = null;\n    var parent = containerElement;\n    while (parent && parent.tagName.toLowerCase()!=\"body\") {\n        var parentPosition = OpenLayers.Element.getStyle(parent, \"position\");\n        if(parentPosition == \"absolute\") {\n            parentHasPositionAbsolute = true;\n            break;\n        } else if (parentPosition && parentPosition != \"static\") {\n            break;\n        }\n        parent = parent.parentNode;\n    }\n    if(parentHasPositionAbsolute && (containerElement.clientHeight === 0 || \n                                     containerElement.clientWidth === 0) ){\n        superContainer = document.createElement(\"div\");\n        superContainer.style.visibility = \"hidden\";\n        superContainer.style.position = \"absolute\";\n        superContainer.style.overflow = \"visible\";\n        superContainer.style.width = document.body.clientWidth + \"px\";\n        superContainer.style.height = document.body.clientHeight + \"px\";\n        superContainer.appendChild(container);\n    }\n    container.style.position = \"absolute\";\n    if (size) {\n        if (size.w) {\n            w = size.w;\n            container.style.width = w + \"px\";\n        } else if (size.h) {\n            h = size.h;\n            container.style.height = h + \"px\";\n        }\n    }\n    if (options && options.displayClass) {\n        container.className = options.displayClass;\n    }\n    var content = document.createElement(\"div\");\n    content.innerHTML = contentHTML;\n    content.style.overflow = \"visible\";\n    if (content.childNodes) {\n        for (var i=0, l=content.childNodes.length; i<l; i++) {\n            if (!content.childNodes[i].style) continue;\n            content.childNodes[i].style.overflow = \"visible\";\n        }\n    }\n    container.appendChild(content);\n    if (superContainer) {\n        containerElement.appendChild(superContainer);\n    } else {\n        containerElement.appendChild(container);\n    }\n    if (!w) {\n        w = parseInt(content.scrollWidth);\n        container.style.width = w + \"px\";\n    }        \n    if (!h) {\n        h = parseInt(content.scrollHeight);\n    }\n    container.removeChild(content);\n    if (superContainer) {\n        superContainer.removeChild(container);\n        containerElement.removeChild(superContainer);\n    } else {\n        containerElement.removeChild(container);\n    }\n    \n    return new OpenLayers.Size(w, h);\n};\n\nOpenLayers.Util.getScrollbarWidth = function() {\n    \n    var scrollbarWidth = OpenLayers.Util._scrollbarWidth;\n    \n    if (scrollbarWidth == null) {\n        var scr = null;\n        var inn = null;\n        var wNoScroll = 0;\n        var wScroll = 0;\n        scr = document.createElement('div');\n        scr.style.position = 'absolute';\n        scr.style.top = '-1000px';\n        scr.style.left = '-1000px';\n        scr.style.width = '100px';\n        scr.style.height = '50px';\n        scr.style.overflow = 'hidden';\n        inn = document.createElement('div');\n        inn.style.width = '100%';\n        inn.style.height = '200px';\n        scr.appendChild(inn);\n        document.body.appendChild(scr);\n        wNoScroll = inn.offsetWidth;\n        scr.style.overflow = 'scroll';\n        wScroll = inn.offsetWidth;\n        document.body.removeChild(document.body.lastChild);\n        OpenLayers.Util._scrollbarWidth = (wNoScroll - wScroll);\n        scrollbarWidth = OpenLayers.Util._scrollbarWidth;\n    }\n\n    return scrollbarWidth;\n};\n\nOpenLayers.Util.getFormattedLonLat = function(coordinate, axis, dmsOption) {\n    if (!dmsOption) {\n        dmsOption = 'dms';    //default to show degree, minutes, seconds\n    }\n\n    coordinate = (coordinate+540)%360 - 180; // normalize for sphere being round\n\n    var abscoordinate = Math.abs(coordinate);\n    var coordinatedegrees = Math.floor(abscoordinate);\n\n    var coordinateminutes = (abscoordinate - coordinatedegrees)/(1/60);\n    var tempcoordinateminutes = coordinateminutes;\n    coordinateminutes = Math.floor(coordinateminutes);\n    var coordinateseconds = (tempcoordinateminutes - coordinateminutes)/(1/60);\n    coordinateseconds =  Math.round(coordinateseconds*10);\n    coordinateseconds /= 10;\n\n    if( coordinateseconds >= 60) { \n        coordinateseconds -= 60; \n        coordinateminutes += 1; \n        if( coordinateminutes >= 60) { \n            coordinateminutes -= 60; \n            coordinatedegrees += 1; \n        } \n    }\n    \n    if( coordinatedegrees < 10 ) {\n        coordinatedegrees = \"0\" + coordinatedegrees;\n    }\n    var str = coordinatedegrees + \"\\u00B0\";\n\n    if (dmsOption.indexOf('dm') >= 0) {\n        if( coordinateminutes < 10 ) {\n            coordinateminutes = \"0\" + coordinateminutes;\n        }\n        str += coordinateminutes + \"'\";\n  \n        if (dmsOption.indexOf('dms') >= 0) {\n            if( coordinateseconds < 10 ) {\n                coordinateseconds = \"0\" + coordinateseconds;\n            }\n            str += coordinateseconds + '\"';\n        }\n    }\n    \n    if (axis == \"lon\") {\n        str += coordinate < 0 ? OpenLayers.i18n(\"W\") : OpenLayers.i18n(\"E\");\n    } else {\n        str += coordinate < 0 ? OpenLayers.i18n(\"S\") : OpenLayers.i18n(\"N\");\n    }\n    return str;\n};\n\nOpenLayers.Util.getConstructor = function(className) {\n    var Constructor;\n    var parts = className.split('.');\n    if (parts[0] === \"OpenLayers\") {\n        Constructor = OpenLayers;\n    } else {\n        Constructor = window[parts[0]];\n    }\n    for (var i = 1, ii = parts.length; i < ii; ++i) {\n        Constructor = Constructor[parts[i]];\n    }\n    return Constructor;\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/WPSClient.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.WPSClient = OpenLayers.Class({\n    \n        servers: null,\n    \n        version: '1.0.0',\n    \n        lazy: false,\n    \n        events: null,\n    \n        initialize: function(options) {\n        OpenLayers.Util.extend(this, options);\n        this.events = new OpenLayers.Events(this);\n        this.servers = {};\n        for (var s in options.servers) {\n            this.servers[s] = typeof options.servers[s] == 'string' ? {\n                url: options.servers[s],\n                version: this.version,\n                processDescription: {}\n            } : options.servers[s];\n        }\n    },\n    \n        execute: function(options) {\n        var process = this.getProcess(options.server, options.process);\n        process.execute({\n            inputs: options.inputs,\n            success: options.success,\n            scope: options.scope\n        });\n    },\n    \n        getProcess: function(serverID, processID, options) {\n        var process = new OpenLayers.WPSProcess({\n            client: this,\n            server: serverID,\n            identifier: processID\n        });\n        if (!this.lazy) {\n            process.describe(options);\n        }\n        return process;\n    },\n    \n        describeProcess: function(serverID, processID, callback, scope) {\n        var server = this.servers[serverID];\n        if (!server.processDescription[processID]) {\n            if (!(processID in server.processDescription)) {\n                server.processDescription[processID] = null;\n                OpenLayers.Request.GET({\n                    url: server.url,\n                    params: {\n                        SERVICE: 'WPS',\n                        VERSION: server.version,\n                        REQUEST: 'DescribeProcess',\n                        IDENTIFIER: processID\n                    },\n                    success: function(response) {\n                        server.processDescription[processID] = response.responseText;\n                        this.events.triggerEvent('describeprocess', {\n                            identifier: processID,\n                            raw: response.responseText\n                        });\n                        callback.call(scope, response.responseText);\n                    },\n                    scope: this\n                });\n            } else {\n                this.events.register('describeprocess', this, function describe(evt) {\n                    if (evt.identifier === processID) {\n                        this.events.unregister('describeprocess', this, describe);\n                        callback.call(scope, evt.raw);\n                    }\n                });\n            }\n        } else {\n            window.setTimeout(function() {\n                callback.call(scope, server.processDescription[processID]);\n            }, 0);\n        }\n    },\n    \n        destroy: function() {\n        this.events.destroy();\n        this.events = null;\n        this.servers = null;\n    },\n    \n    CLASS_NAME: 'OpenLayers.WPSClient'\n    \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers/WPSProcess.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n\n\nOpenLayers.WPSProcess = OpenLayers.Class({\n    \n        client: null,\n    \n        server: null,\n    \n        identifier: null,\n    \n        description: null,\n    \n        localWPS: 'http://geoserver/wps',\n    \n        formats: null,\n    \n        chained: 0,\n    \n        executeCallbacks: null,\n    \n        initialize: function(options) {\n        OpenLayers.Util.extend(this, options);        \n        this.executeCallbacks = [];\n        this.formats = {\n            'application/wkt': new OpenLayers.Format.WKT(),\n            'application/json': new OpenLayers.Format.GeoJSON()\n        };\n    },\n    \n        describe: function(options) {\n        options = options || {};\n        if (!this.description) {\n            this.client.describeProcess(this.server, this.identifier, function(description) {\n                if (!this.description) {\n                    this.parseDescription(description);\n                }\n                if (options.callback) {\n                    options.callback.call(options.scope, this.description);\n                }\n            }, this);\n        } else if (options.callback) {\n            var description = this.description;\n            window.setTimeout(function() {\n                options.callback.call(options.scope, description);\n            }, 0);\n        }\n    },\n    \n        configure: function(options) {\n        this.describe({\n            callback: function() {\n                var description = this.description,\n                    inputs = options.inputs,\n                    input, i, ii;\n                for (i=0, ii=description.dataInputs.length; i<ii; ++i) {\n                    input = description.dataInputs[i];\n                    this.setInputData(input, inputs[input.identifier]);\n                }\n                if (options.callback) {\n                    options.callback.call(options.scope);\n                }\n            },\n            scope: this\n        });\n        return this;\n    },\n    \n        execute: function(options) {\n        this.configure({\n            inputs: options.inputs,\n            callback: function() {\n                var me = this;\n                var outputIndex = this.getOutputIndex(\n                    me.description.processOutputs, options.output\n                );\n                me.setResponseForm({outputIndex: outputIndex});\n                (function callback() {\n                    OpenLayers.Util.removeItem(me.executeCallbacks, callback);\n                    if (me.chained !== 0) {\n                        me.executeCallbacks.push(callback);\n                        return;\n                    }\n                    OpenLayers.Request.POST({\n                        url: me.client.servers[me.server].url,\n                        data: new OpenLayers.Format.WPSExecute().write(me.description),\n                        success: function(response) {\n                            var output = me.description.processOutputs[outputIndex];\n                            var result;\n                            if (output.literalOutput) {\n                                 if (output.literalOutput.dataType === \"boolean\") {\n                                   result = (OpenLayers.String.trim(\n                                       response.responseText).toLowerCase() === 'true');\n                                 } else if (output.literalOutput.dataType === \"double\") {\n                                   result = parseFloat(response.responseText);\n                                 } else {\n                                   result = response.responseText;\n                                 }\n                            } else if (output.complexOutput) {\n                                var mimeType = me.findMimeType(\n                                    output.complexOutput.supported.formats\n                                );\n                                result = me.formats[mimeType].read(response.responseText);\n                                if (result instanceof OpenLayers.Feature.Vector) {\n                                    result = [result];\n                                }\n                            }\n                            if (options.success) {\n                                var outputs = {};\n                                outputs[options.output || 'result'] = result;\n                                options.success.call(options.scope, outputs);\n                            }\n                        },\n                        scope: me\n                    });\n                })();\n            },\n            scope: this\n        });\n    },\n    \n        output: function(identifier) {\n        return new OpenLayers.WPSProcess.ChainLink({\n            process: this,\n            output: identifier\n        });\n    },\n    \n        parseDescription: function(description) {\n        var server = this.client.servers[this.server];\n        this.description = new OpenLayers.Format.WPSDescribeProcess()\n            .read(server.processDescription[this.identifier])\n            .processDescriptions[this.identifier];\n    },\n    \n        setInputData: function(input, data) {\n        delete input.data;\n        delete input.reference;\n        if (data instanceof OpenLayers.WPSProcess.ChainLink) {\n            ++this.chained;\n            input.reference = {\n                method: 'POST',\n                href: data.process.server === this.server ?\n                    this.localWPS : this.client.servers[data.process.server].url\n            };\n            data.process.describe({\n                callback: function() {\n                    --this.chained;\n                    this.chainProcess(input, data);\n                },\n                scope: this\n            });\n        } else {\n            input.data = {};\n            var complexData = input.complexData;\n            if (complexData) {\n                var format = this.findMimeType(complexData.supported.formats);\n                input.data.complexData = {\n                    mimeType: format,\n                    value: this.formats[format].write(this.toFeatures(data))\n                };\n            } else {\n                input.data.literalData = {\n                    value: data\n                };\n            }\n        }\n    },\n    \n        setResponseForm: function(options) {\n        options = options || {};\n        var output = this.description.processOutputs[options.outputIndex || 0];\n        var mimeType;\n        if (output.complexOutput) {\n            mimeType = this.findMimeType(output.complexOutput.supported.formats, options.supportedFormats);\n        }\n        this.description.responseForm = {\n            rawDataOutput: {\n                identifier: output.identifier,\n                mimeType: mimeType\n            }\n        };\n    },\n    \n        getOutputIndex: function(outputs, identifier) {\n        var output;\n        if (identifier) {\n            for (var i=outputs.length-1; i>=0; --i) {\n                if (outputs[i].identifier === identifier) {\n                    output = i;\n                    break;\n                }\n            }\n        } else {\n            output = 0;\n        }\n        return output;\n    },\n    \n        chainProcess: function(input, chainLink) {\n        var output = this.getOutputIndex(\n            chainLink.process.description.processOutputs, chainLink.output\n        );\n        input.reference.mimeType = this.findMimeType(\n            input.complexData.supported.formats,\n            chainLink.process.description.processOutputs[output].complexOutput.supported.formats\n        );\n        var formats = {};\n        formats[input.reference.mimeType] = true;\n        chainLink.process.setResponseForm({\n            outputIndex: output,\n            supportedFormats: formats\n        });\n        input.reference.body = chainLink.process.description;\n        while (this.executeCallbacks.length > 0) {\n            this.executeCallbacks[0]();\n        }\n    },\n    \n        toFeatures: function(source) {\n        var isArray = OpenLayers.Util.isArray(source);\n        if (!isArray) {\n            source = [source];\n        }\n        var target = new Array(source.length),\n            current;\n        for (var i=0, ii=source.length; i<ii; ++i) {\n            current = source[i];\n            target[i] = current instanceof OpenLayers.Feature.Vector ?\n                current : new OpenLayers.Feature.Vector(current);\n        }\n        return isArray ? target : target[0];\n    },\n    \n        findMimeType: function(sourceFormats, targetFormats) {\n        targetFormats = targetFormats || this.formats;\n        for (var f in sourceFormats) {\n            if (f in targetFormats) {\n                return f;\n            }\n        }\n    },\n    \n    CLASS_NAME: \"OpenLayers.WPSProcess\"\n    \n});\n\nOpenLayers.WPSProcess.ChainLink = OpenLayers.Class({\n    \n        process: null,\n    \n        output: null,\n    \n        initialize: function(options) {\n        OpenLayers.Util.extend(this, options);\n    },\n    \n    CLASS_NAME: \"OpenLayers.WPSProcess.ChainLink\"\n    \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/OpenLayers.js",
    "content": "/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for\n * full list of contributors). Published under the 2-clause BSD license.\n * See license.txt in the OpenLayers distribution or repository for the\n * full text of the license. */\n\n/* \n * @requires OpenLayers/BaseTypes.js\n * @requires OpenLayers/Lang/en.js\n * @requires OpenLayers/Console.js\n */\n \n/*\n * TODO: In 3.0, we will stop supporting build profiles that include\n * OpenLayers.js. This means we will not need the singleFile and scriptFile\n * variables, because we don't have to handle the singleFile case any more.\n */\n\n(function() {\n        var singleFile = (typeof OpenLayers == \"object\" && OpenLayers.singleFile);\n    \n        var scriptName = (!singleFile) ? \"lib/OpenLayers.js\" : \"OpenLayers.js\";\n\n    /*\n     * If window.OpenLayers isn't set when this script (OpenLayers.js) is\n     * evaluated (and if singleFile is false) then this script will load\n     * *all* OpenLayers scripts. If window.OpenLayers is set to an array\n     * then this script will attempt to load scripts for each string of\n     * the array, using the string as the src of the script.\n     *\n     * Example:\n     * (code)\n     *     <script type=\"text/javascript\">\n     *         window.OpenLayers = [\n     *             \"OpenLayers/Util.js\",\n     *             \"OpenLayers/BaseTypes.js\"\n     *         ];\n     *     </script>\n     *     <script type=\"text/javascript\" src=\"../lib/OpenLayers.js\"></script>\n     * (end)\n     * In this example OpenLayers.js will load Util.js and BaseTypes.js only.\n     */\n    var jsFiles = window.OpenLayers;\n\n        window.OpenLayers = {\n                _getScriptLocation: (function() {\n            var r = new RegExp(\"(^|(.*?\\\\/))(\" + scriptName + \")(\\\\?|$)\"),\n                s = document.getElementsByTagName('script'),\n                src, m, l = \"\";\n            for(var i=0, len=s.length; i<len; i++) {\n                src = s[i].getAttribute('src');\n                if(src) {\n                    m = src.match(r);\n                    if(m) {\n                        l = m[1];\n                        break;\n                    }\n                }\n            }\n            return (function() { return l; });\n        })(),\n        \n                ImgPath : ''\n    };\n\n        if(!singleFile) {\n        if (!jsFiles) {\n            jsFiles = [\n                \"OpenLayers/BaseTypes/Class.js\",\n                \"OpenLayers/Util.js\",\n                \"OpenLayers/Util/vendorPrefix.js\",\n                \"OpenLayers/Animation.js\",\n                \"OpenLayers/BaseTypes.js\",\n                \"OpenLayers/BaseTypes/Bounds.js\",\n                \"OpenLayers/BaseTypes/Date.js\",\n                \"OpenLayers/BaseTypes/Element.js\",\n                \"OpenLayers/BaseTypes/LonLat.js\",\n                \"OpenLayers/BaseTypes/Pixel.js\",\n                \"OpenLayers/BaseTypes/Size.js\",\n                \"OpenLayers/Console.js\",\n                \"OpenLayers/Tween.js\",\n                \"OpenLayers/Kinetic.js\",\n                \"OpenLayers/Events.js\",\n                \"OpenLayers/Events/buttonclick.js\",\n                \"OpenLayers/Events/featureclick.js\",\n                \"OpenLayers/Request.js\",\n                \"OpenLayers/Request/XMLHttpRequest.js\",\n                \"OpenLayers/Projection.js\",\n                \"OpenLayers/Map.js\",\n                \"OpenLayers/Layer.js\",\n                \"OpenLayers/Icon.js\",\n                \"OpenLayers/Marker.js\",\n                \"OpenLayers/Marker/Box.js\",\n                \"OpenLayers/Popup.js\",\n                \"OpenLayers/Tile.js\",\n                \"OpenLayers/Tile/Image.js\",\n                \"OpenLayers/Tile/Image/IFrame.js\",\n                \"OpenLayers/Tile/UTFGrid.js\",\n                \"OpenLayers/Layer/Image.js\",\n                \"OpenLayers/Layer/SphericalMercator.js\",\n                \"OpenLayers/Layer/EventPane.js\",\n                \"OpenLayers/Layer/FixedZoomLevels.js\",\n                \"OpenLayers/Layer/Google.js\",\n                \"OpenLayers/Layer/Google/v3.js\",\n                \"OpenLayers/Layer/HTTPRequest.js\",\n                \"OpenLayers/Layer/Grid.js\",\n                \"OpenLayers/Layer/MapGuide.js\",\n                \"OpenLayers/Layer/MapServer.js\",\n                \"OpenLayers/Layer/KaMap.js\",\n                \"OpenLayers/Layer/KaMapCache.js\",\n                \"OpenLayers/Layer/Markers.js\",\n                \"OpenLayers/Layer/Text.js\",\n                \"OpenLayers/Layer/WorldWind.js\",\n                \"OpenLayers/Layer/ArcGIS93Rest.js\",\n                \"OpenLayers/Layer/WMS.js\",\n                \"OpenLayers/Layer/WMTS.js\",\n                \"OpenLayers/Layer/ArcIMS.js\",\n                \"OpenLayers/Layer/GeoRSS.js\",\n                \"OpenLayers/Layer/Boxes.js\",\n                \"OpenLayers/Layer/XYZ.js\",\n                \"OpenLayers/Layer/UTFGrid.js\",\n                \"OpenLayers/Layer/OSM.js\",\n                \"OpenLayers/Layer/Bing.js\",\n                \"OpenLayers/Layer/TMS.js\",\n                \"OpenLayers/Layer/TileCache.js\",\n                \"OpenLayers/Layer/Zoomify.js\",\n                \"OpenLayers/Layer/ArcGISCache.js\",\n                \"OpenLayers/Popup/Anchored.js\",\n                \"OpenLayers/Popup/Framed.js\",\n                \"OpenLayers/Popup/FramedCloud.js\",\n                \"OpenLayers/Feature.js\",\n                \"OpenLayers/Feature/Vector.js\",\n                \"OpenLayers/Handler.js\",\n                \"OpenLayers/Handler/Click.js\",\n                \"OpenLayers/Handler/Hover.js\",\n                \"OpenLayers/Handler/Point.js\",\n                \"OpenLayers/Handler/Path.js\",\n                \"OpenLayers/Handler/Polygon.js\",\n                \"OpenLayers/Handler/Feature.js\",\n                \"OpenLayers/Handler/Drag.js\",\n                \"OpenLayers/Handler/Pinch.js\",\n                \"OpenLayers/Handler/RegularPolygon.js\",\n                \"OpenLayers/Handler/Box.js\",\n                \"OpenLayers/Handler/MouseWheel.js\",\n                \"OpenLayers/Handler/Keyboard.js\",\n                \"OpenLayers/Control.js\",\n                \"OpenLayers/Control/Attribution.js\",\n                \"OpenLayers/Control/Button.js\",\n                \"OpenLayers/Control/CacheRead.js\",\n                \"OpenLayers/Control/CacheWrite.js\",\n                \"OpenLayers/Control/ZoomBox.js\",\n                \"OpenLayers/Control/ZoomToMaxExtent.js\",\n                \"OpenLayers/Control/DragPan.js\",\n                \"OpenLayers/Control/Navigation.js\",\n                \"OpenLayers/Control/PinchZoom.js\",\n                \"OpenLayers/Control/TouchNavigation.js\",\n                \"OpenLayers/Control/MousePosition.js\",\n                \"OpenLayers/Control/OverviewMap.js\",\n                \"OpenLayers/Control/KeyboardDefaults.js\",\n                \"OpenLayers/Control/PanZoom.js\",\n                \"OpenLayers/Control/PanZoomBar.js\",\n                \"OpenLayers/Control/ArgParser.js\",\n                \"OpenLayers/Control/Permalink.js\",\n                \"OpenLayers/Control/Scale.js\",\n                \"OpenLayers/Control/ScaleLine.js\",\n                \"OpenLayers/Control/Snapping.js\",\n                \"OpenLayers/Control/Split.js\",\n                \"OpenLayers/Control/LayerSwitcher.js\",\n                \"OpenLayers/Control/DrawFeature.js\",\n                \"OpenLayers/Control/DragFeature.js\",\n                \"OpenLayers/Control/ModifyFeature.js\",\n                \"OpenLayers/Control/ModifyFeature/BySegment.js\",\n                \"OpenLayers/Control/Panel.js\",\n                \"OpenLayers/Control/SelectFeature.js\",\n                \"OpenLayers/Control/NavigationHistory.js\",\n                \"OpenLayers/Control/Measure.js\",\n                \"OpenLayers/Control/WMSGetFeatureInfo.js\",\n                \"OpenLayers/Control/WMTSGetFeatureInfo.js\",\n                \"OpenLayers/Control/Graticule.js\",\n                \"OpenLayers/Control/TransformFeature.js\",\n                \"OpenLayers/Control/UTFGrid.js\",\n                \"OpenLayers/Control/SLDSelect.js\",\n                \"OpenLayers/Control/Zoom.js\",\n                \"OpenLayers/Control/TextButtonPanel.js\",\n                \"OpenLayers/Geometry.js\",\n                \"OpenLayers/Geometry/Collection.js\",\n                \"OpenLayers/Geometry/Point.js\",\n                \"OpenLayers/Geometry/MultiPoint.js\",\n                \"OpenLayers/Geometry/Curve.js\",\n                \"OpenLayers/Geometry/LineString.js\",\n                \"OpenLayers/Geometry/LinearRing.js\",\n                \"OpenLayers/Geometry/Polygon.js\",\n                \"OpenLayers/Geometry/MultiLineString.js\",\n                \"OpenLayers/Geometry/MultiPolygon.js\",\n                \"OpenLayers/Renderer.js\",\n                \"OpenLayers/Renderer/Elements.js\",\n                \"OpenLayers/Renderer/SVG.js\",\n                \"OpenLayers/Renderer/Canvas.js\",\n                \"OpenLayers/Renderer/VML.js\",\n                \"OpenLayers/Layer/Vector.js\",\n                \"OpenLayers/Layer/PointGrid.js\",\n                \"OpenLayers/Layer/Vector/RootContainer.js\",\n                \"OpenLayers/Strategy.js\",\n                \"OpenLayers/Strategy/Filter.js\",\n                \"OpenLayers/Strategy/Fixed.js\",\n                \"OpenLayers/Strategy/Cluster.js\",\n                \"OpenLayers/Strategy/Paging.js\",\n                \"OpenLayers/Strategy/BBOX.js\",\n                \"OpenLayers/Strategy/Save.js\",\n                \"OpenLayers/Strategy/Refresh.js\",\n                \"OpenLayers/Filter.js\",\n                \"OpenLayers/Filter/FeatureId.js\",\n                \"OpenLayers/Filter/Logical.js\",\n                \"OpenLayers/Filter/Comparison.js\",\n                \"OpenLayers/Filter/Spatial.js\",\n                \"OpenLayers/Filter/Function.js\",                \n                \"OpenLayers/Protocol.js\",\n                \"OpenLayers/Protocol/HTTP.js\",\n                \"OpenLayers/Protocol/WFS.js\",\n                \"OpenLayers/Protocol/WFS/v1.js\",\n                \"OpenLayers/Protocol/WFS/v1_0_0.js\",\n                \"OpenLayers/Protocol/WFS/v1_1_0.js\",\n                \"OpenLayers/Protocol/WFS/v2_0_0.js\",\n                \"OpenLayers/Protocol/CSW.js\", \n                \"OpenLayers/Protocol/CSW/v2_0_2.js\",\n                \"OpenLayers/Protocol/Script.js\",\n                \"OpenLayers/Protocol/SOS.js\",\n                \"OpenLayers/Protocol/SOS/v1_0_0.js\",\n                \"OpenLayers/Layer/PointTrack.js\",\n                \"OpenLayers/Style.js\",\n                \"OpenLayers/Style2.js\",\n                \"OpenLayers/StyleMap.js\",\n                \"OpenLayers/Rule.js\",\n                \"OpenLayers/Format.js\",\n                \"OpenLayers/Format/QueryStringFilter.js\",\n                \"OpenLayers/Format/XML.js\",\n                \"OpenLayers/Format/XML/VersionedOGC.js\",\n                \"OpenLayers/Format/Context.js\",\n                \"OpenLayers/Format/ArcXML.js\",\n                \"OpenLayers/Format/ArcXML/Features.js\",\n                \"OpenLayers/Format/GML.js\",\n                \"OpenLayers/Format/GML/Base.js\",\n                \"OpenLayers/Format/GML/v2.js\",\n                \"OpenLayers/Format/GML/v3.js\",\n                \"OpenLayers/Format/Atom.js\",\n                \"OpenLayers/Format/EncodedPolyline.js\",\n                \"OpenLayers/Format/KML.js\",\n                \"OpenLayers/Format/GeoRSS.js\",\n                \"OpenLayers/Format/WFS.js\",\n                \"OpenLayers/Format/OWSCommon.js\",\n                \"OpenLayers/Format/OWSCommon/v1.js\",\n                \"OpenLayers/Format/OWSCommon/v1_0_0.js\",\n                \"OpenLayers/Format/OWSCommon/v1_1_0.js\",\n                \"OpenLayers/Format/WCSCapabilities.js\",\n                \"OpenLayers/Format/WCSCapabilities/v1.js\",\n                \"OpenLayers/Format/WCSCapabilities/v1_0_0.js\",\n                \"OpenLayers/Format/WCSCapabilities/v1_1_0.js\",\n                \"OpenLayers/Format/WCSDescribeCoverage.js\",\n                \"OpenLayers/Format/WCSDescribeCoverage/v1.js\",\n                \"OpenLayers/Format/WCSDescribeCoverage/v1_0_0.js\",\n                \"OpenLayers/Format/WCSDescribeCoverage/v1_1_0.js\",\n                \"OpenLayers/Format/WFSCapabilities.js\",\n                \"OpenLayers/Format/WFSCapabilities/v1.js\",\n                \"OpenLayers/Format/WFSCapabilities/v1_0_0.js\",\n                \"OpenLayers/Format/WFSCapabilities/v1_1_0.js\",\n                \"OpenLayers/Format/WFSCapabilities/v2_0_0.js\",\n                \"OpenLayers/Format/WFSDescribeFeatureType.js\",\n                \"OpenLayers/Format/WMSDescribeLayer.js\",\n                \"OpenLayers/Format/WMSDescribeLayer/v1_1.js\",\n                \"OpenLayers/Format/WKT.js\",\n                \"OpenLayers/Format/CQL.js\",\n                \"OpenLayers/Format/OSM.js\",\n                \"OpenLayers/Format/GPX.js\",\n                \"OpenLayers/Format/Filter.js\",\n                \"OpenLayers/Format/Filter/v1.js\",\n                \"OpenLayers/Format/Filter/v2.js\",\n                \"OpenLayers/Format/Filter/v1_0_0.js\",\n                \"OpenLayers/Format/Filter/v1_1_0.js\",\n                \"OpenLayers/Format/Filter/v2_0_0.js\",\n                \"OpenLayers/Format/SLD.js\",\n                \"OpenLayers/Format/SLD/v1.js\",\n                \"OpenLayers/Format/SLD/v1_0_0.js\",\n                \"OpenLayers/Format/SLD/v1_0_0_GeoServer.js\",\n                \"OpenLayers/Format/OWSCommon.js\",\n                \"OpenLayers/Format/OWSCommon/v1.js\",\n                \"OpenLayers/Format/OWSCommon/v1_0_0.js\",\n                \"OpenLayers/Format/OWSCommon/v1_1_0.js\",\n                \"OpenLayers/Format/CSWGetDomain.js\",\n                \"OpenLayers/Format/CSWGetDomain/v2_0_2.js\",\n                \"OpenLayers/Format/CSWGetRecords.js\",\n                \"OpenLayers/Format/CSWGetRecords/v2_0_2.js\",\n                \"OpenLayers/Format/WFST.js\",\n                \"OpenLayers/Format/WFST/v1.js\",\n                \"OpenLayers/Format/WFST/v1_0_0.js\",\n                \"OpenLayers/Format/WFST/v1_1_0.js\",\n                \"OpenLayers/Format/WFST/v2_0_0.js\",\n                \"OpenLayers/Format/Text.js\",\n                \"OpenLayers/Format/JSON.js\",\n                \"OpenLayers/Format/GeoJSON.js\",\n                \"OpenLayers/Format/WMC.js\",\n                \"OpenLayers/Format/WMC/v1.js\",\n                \"OpenLayers/Format/WMC/v1_0_0.js\",\n                \"OpenLayers/Format/WMC/v1_1_0.js\",\n                \"OpenLayers/Format/WCSGetCoverage.js\",\n                \"OpenLayers/Format/WMSCapabilities.js\",\n                \"OpenLayers/Format/WMSCapabilities/v1.js\",\n                \"OpenLayers/Format/WMSCapabilities/v1_1.js\",\n                \"OpenLayers/Format/WMSCapabilities/v1_1_0.js\",\n                \"OpenLayers/Format/WMSCapabilities/v1_1_1.js\",\n                \"OpenLayers/Format/WMSCapabilities/v1_3.js\",\n                \"OpenLayers/Format/WMSCapabilities/v1_3_0.js\",\n                \"OpenLayers/Format/WMSCapabilities/v1_1_1_WMSC.js\",\n                \"OpenLayers/Format/WMSGetFeatureInfo.js\",\n                \"OpenLayers/Format/SOSCapabilities.js\",\n                \"OpenLayers/Format/SOSCapabilities/v1_0_0.js\",\n                \"OpenLayers/Format/SOSGetFeatureOfInterest.js\",\n                \"OpenLayers/Format/SOSGetObservation.js\",\n                \"OpenLayers/Format/OWSContext.js\",\n                \"OpenLayers/Format/OWSContext/v0_3_1.js\",\n                \"OpenLayers/Format/WMTSCapabilities.js\",\n                \"OpenLayers/Format/WMTSCapabilities/v1_0_0.js\",\n                \"OpenLayers/Format/WPSCapabilities.js\",\n                \"OpenLayers/Format/WPSCapabilities/v1_0_0.js\",\n                \"OpenLayers/Format/WPSDescribeProcess.js\",\n                \"OpenLayers/Format/WPSDescribeProcess/v1_0_0.js\",\n                \"OpenLayers/Format/WPSExecute.js\",\n                \"OpenLayers/Format/XLS.js\",\n                \"OpenLayers/Format/XLS/v1.js\",\n                \"OpenLayers/Format/XLS/v1_1_0.js\",\n                \"OpenLayers/Format/OGCExceptionReport.js\",\n                \"OpenLayers/Format/TMSCapabilities.js\",\n                \"OpenLayers/Control/GetFeature.js\",\n                \"OpenLayers/Control/NavToolbar.js\",\n                \"OpenLayers/Control/PanPanel.js\",\n                \"OpenLayers/Control/Pan.js\",\n                \"OpenLayers/Control/ZoomIn.js\",\n                \"OpenLayers/Control/ZoomOut.js\",\n                \"OpenLayers/Control/ZoomPanel.js\",\n                \"OpenLayers/Control/EditingToolbar.js\",\n                \"OpenLayers/Control/Geolocate.js\",\n                \"OpenLayers/Symbolizer.js\",\n                \"OpenLayers/Symbolizer/Point.js\",\n                \"OpenLayers/Symbolizer/Line.js\",\n                \"OpenLayers/Symbolizer/Polygon.js\",\n                \"OpenLayers/Symbolizer/Text.js\",\n                \"OpenLayers/Symbolizer/Raster.js\",\n                \"OpenLayers/Lang.js\",\n                \"OpenLayers/Lang/en.js\",\n                \"OpenLayers/Spherical.js\",\n                \"OpenLayers/TileManager.js\",\n                \"OpenLayers/WPSClient.js\",\n                \"OpenLayers/WPSProcess.js\"\n            ]; // etc.\n        }\n        var scriptTags = new Array(jsFiles.length);\n        var host = OpenLayers._getScriptLocation() + \"lib/\";\n        for (var i=0, len=jsFiles.length; i<len; i++) {\n            scriptTags[i] = \"<script src='\" + host + jsFiles[i] +\n                                   \"'></script>\"; \n        }\n        if (scriptTags.length > 0) {\n            document.write(scriptTags.join(\"\"));\n        }\n    }\n})();\n\nOpenLayers.VERSION_NUMBER=\"Release 2.14 dev\";\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/Rico/Color.js",
    "content": "\n\n/*\n * This file has been edited substantially from the Rico-released version by\n * the OpenLayers development team.\n */\n\nOpenLayers.Console.warn(\"OpenLayers.Rico is deprecated\");\n\nOpenLayers.Rico = OpenLayers.Rico || {};\nOpenLayers.Rico.Color = OpenLayers.Class({\n\n   initialize: function(red, green, blue) {\n      this.rgb = { r: red, g : green, b : blue };\n   },\n\n   setRed: function(r) {\n      this.rgb.r = r;\n   },\n\n   setGreen: function(g) {\n      this.rgb.g = g;\n   },\n\n   setBlue: function(b) {\n      this.rgb.b = b;\n   },\n\n   setHue: function(h) {\n      var hsb = this.asHSB();\n      hsb.h = h;\n      this.rgb = OpenLayers.Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b);\n   },\n\n   setSaturation: function(s) {\n      var hsb = this.asHSB();\n      hsb.s = s;\n      this.rgb = OpenLayers.Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b);\n   },\n\n   setBrightness: function(b) {\n      var hsb = this.asHSB();\n      hsb.b = b;\n      this.rgb = OpenLayers.Rico.Color.HSBtoRGB( hsb.h, hsb.s, hsb.b );\n   },\n\n   darken: function(percent) {\n      var hsb  = this.asHSB();\n      this.rgb = OpenLayers.Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.max(hsb.b - percent,0));\n   },\n\n   brighten: function(percent) {\n      var hsb  = this.asHSB();\n      this.rgb = OpenLayers.Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.min(hsb.b + percent,1));\n   },\n\n   blend: function(other) {\n      this.rgb.r = Math.floor((this.rgb.r + other.rgb.r)/2);\n      this.rgb.g = Math.floor((this.rgb.g + other.rgb.g)/2);\n      this.rgb.b = Math.floor((this.rgb.b + other.rgb.b)/2);\n   },\n\n   isBright: function() {\n      var hsb = this.asHSB();\n      return this.asHSB().b > 0.5;\n   },\n\n   isDark: function() {\n      return ! this.isBright();\n   },\n\n   asRGB: function() {\n      return \"rgb(\" + this.rgb.r + \",\" + this.rgb.g + \",\" + this.rgb.b + \")\";\n   },\n\n   asHex: function() {\n      return \"#\" + this.rgb.r.toColorPart() + this.rgb.g.toColorPart() + this.rgb.b.toColorPart();\n   },\n\n   asHSB: function() {\n      return OpenLayers.Rico.Color.RGBtoHSB(this.rgb.r, this.rgb.g, this.rgb.b);\n   },\n\n   toString: function() {\n      return this.asHex();\n   }\n\n});\n\nOpenLayers.Rico.Color.createFromHex = function(hexCode) {\n  if(hexCode.length==4) {\n    var shortHexCode = hexCode; \n    var hexCode = '#';\n    for(var i=1;i<4;i++) { \n        hexCode += (shortHexCode.charAt(i) + \nshortHexCode.charAt(i)); \n    }\n  }\n   if ( hexCode.indexOf('#') == 0 ) {\n       hexCode = hexCode.substring(1);\n   }\n   var red   = hexCode.substring(0,2);\n   var green = hexCode.substring(2,4);\n   var blue  = hexCode.substring(4,6);\n   return new OpenLayers.Rico.Color( parseInt(red,16), parseInt(green,16), parseInt(blue,16) );\n};\n\nOpenLayers.Rico.Color.createColorFromBackground = function(elem) {\n\n   var actualColor = \n      OpenLayers.Element.getStyle(OpenLayers.Util.getElement(elem), \n                                        \"backgroundColor\");\n\n   if ( actualColor == \"transparent\" && elem.parentNode ) {\n      return OpenLayers.Rico.Color.createColorFromBackground(elem.parentNode);\n   }\n   if ( actualColor == null ) {\n      return new OpenLayers.Rico.Color(255,255,255);\n   }\n   if ( actualColor.indexOf(\"rgb(\") == 0 ) {\n      var colors = actualColor.substring(4, actualColor.length - 1 );\n      var colorArray = colors.split(\",\");\n      return new OpenLayers.Rico.Color( parseInt( colorArray[0] ),\n                            parseInt( colorArray[1] ),\n                            parseInt( colorArray[2] )  );\n\n   }\n   else if ( actualColor.indexOf(\"#\") == 0 ) {\n      return OpenLayers.Rico.Color.createFromHex(actualColor);\n   }\n   else {\n      return new OpenLayers.Rico.Color(255,255,255);\n   }\n};\n\nOpenLayers.Rico.Color.HSBtoRGB = function(hue, saturation, brightness) {\n\n   var red   = 0;\n    var green = 0;\n    var blue  = 0;\n\n   if (saturation == 0) {\n      red = parseInt(brightness * 255.0 + 0.5);\n       green = red;\n       blue = red;\n    }\n    else {\n      var h = (hue - Math.floor(hue)) * 6.0;\n      var f = h - Math.floor(h);\n      var p = brightness * (1.0 - saturation);\n      var q = brightness * (1.0 - saturation * f);\n      var t = brightness * (1.0 - (saturation * (1.0 - f)));\n\n      switch (parseInt(h)) {\n         case 0:\n            red   = (brightness * 255.0 + 0.5);\n            green = (t * 255.0 + 0.5);\n            blue  = (p * 255.0 + 0.5);\n            break;\n         case 1:\n            red   = (q * 255.0 + 0.5);\n            green = (brightness * 255.0 + 0.5);\n            blue  = (p * 255.0 + 0.5);\n            break;\n         case 2:\n            red   = (p * 255.0 + 0.5);\n            green = (brightness * 255.0 + 0.5);\n            blue  = (t * 255.0 + 0.5);\n            break;\n         case 3:\n            red   = (p * 255.0 + 0.5);\n            green = (q * 255.0 + 0.5);\n            blue  = (brightness * 255.0 + 0.5);\n            break;\n         case 4:\n            red   = (t * 255.0 + 0.5);\n            green = (p * 255.0 + 0.5);\n            blue  = (brightness * 255.0 + 0.5);\n            break;\n          case 5:\n            red   = (brightness * 255.0 + 0.5);\n            green = (p * 255.0 + 0.5);\n            blue  = (q * 255.0 + 0.5);\n            break;\n        }\n    }\n\n   return { r : parseInt(red), g : parseInt(green) , b : parseInt(blue) };\n};\n\nOpenLayers.Rico.Color.RGBtoHSB = function(r, g, b) {\n\n   var hue;\n   var saturation;\n   var brightness;\n\n   var cmax = (r > g) ? r : g;\n   if (b > cmax) {\n      cmax = b;\n   }\n   var cmin = (r < g) ? r : g;\n   if (b < cmin) {\n      cmin = b;\n   }\n   brightness = cmax / 255.0;\n   if (cmax != 0) {\n      saturation = (cmax - cmin)/cmax;\n   } else {\n      saturation = 0;\n   }\n   if (saturation == 0) {\n      hue = 0;\n   } else {\n      var redc   = (cmax - r)/(cmax - cmin);\n        var greenc = (cmax - g)/(cmax - cmin);\n        var bluec  = (cmax - b)/(cmax - cmin);\n\n        if (r == cmax) {\n           hue = bluec - greenc;\n        } else if (g == cmax) {\n           hue = 2.0 + redc - bluec;\n      } else {\n           hue = 4.0 + greenc - redc;\n      }\n        hue = hue / 6.0;\n        if (hue < 0) {\n           hue = hue + 1.0;\n        }\n   }\n\n   return { h : hue, s : saturation, b : brightness };\n};\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/Rico/Corner.js",
    "content": "\n\n/*\n * This file has been edited substantially from the Rico-released\n * version by the OpenLayers development team.\n *  \n *  Copyright 2005 Sabre Airline Solutions  \n *  \n *  Licensed under the Apache License, Version 2.0 (the \"License\");\n *  you may not use this file except in compliance with the\n *  License. You may obtain a copy of the License at\n *  \n *         http://www.apache.org/licenses/LICENSE-2.0  \n *  \n * Unless required by applicable law or agreed to in writing, software\n * distributed under the * License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, * either express or\n * implied. See the License for the specific language governing\n * permissions * and limitations under the License.\n *\n */\n\nOpenLayers.Console.warn(\"OpenLayers.Rico is deprecated\");\n\nOpenLayers.Rico = OpenLayers.Rico || {};\nOpenLayers.Rico.Corner = {\n\n    round: function(e, options) {\n        e = OpenLayers.Util.getElement(e);\n        this._setOptions(options);\n\n        var color = this.options.color;\n        if ( this.options.color == \"fromElement\" ) {\n            color = this._background(e);\n        }\n        var bgColor = this.options.bgColor;\n        if ( this.options.bgColor == \"fromParent\" ) {\n            bgColor = this._background(e.offsetParent);\n        }\n        this._roundCornersImpl(e, color, bgColor);\n    },\n\n        changeColor: function(theDiv, newColor) {\n   \n        theDiv.style.backgroundColor = newColor;\n\n        var spanElements = theDiv.parentNode.getElementsByTagName(\"span\");\n        \n        for (var currIdx = 0; currIdx < spanElements.length; currIdx++) {\n            spanElements[currIdx].style.backgroundColor = newColor;\n        }\n    }, \n\n\n        changeOpacity: function(theDiv, newOpacity) {\n   \n        var mozillaOpacity = newOpacity;\n        var ieOpacity = 'alpha(opacity=' + newOpacity * 100 + ')';\n        \n        theDiv.style.opacity = mozillaOpacity;\n        theDiv.style.filter = ieOpacity;\n\n        var spanElements = theDiv.parentNode.getElementsByTagName(\"span\");\n        \n        for (var currIdx = 0; currIdx < spanElements.length; currIdx++) {\n            spanElements[currIdx].style.opacity = mozillaOpacity;\n            spanElements[currIdx].style.filter = ieOpacity;\n        }\n\n    },\n\n        reRound: function(theDiv, options) {\n\n        var topRico = theDiv.parentNode.childNodes[0];\n        var bottomRico = theDiv.parentNode.childNodes[2];\n       \n        theDiv.parentNode.removeChild(topRico);\n        theDiv.parentNode.removeChild(bottomRico); \n\n        this.round(theDiv.parentNode, options);\n    }, \n\n   _roundCornersImpl: function(e, color, bgColor) {\n      if(this.options.border) {\n         this._renderBorder(e,bgColor);\n      }\n      if(this._isTopRounded()) {\n         this._roundTopCorners(e,color,bgColor);\n      }\n      if(this._isBottomRounded()) {\n         this._roundBottomCorners(e,color,bgColor);\n      }\n   },\n\n   _renderBorder: function(el,bgColor) {\n      var borderValue = \"1px solid \" + this._borderColor(bgColor);\n      var borderL = \"border-left: \"  + borderValue;\n      var borderR = \"border-right: \" + borderValue;\n      var style   = \"style='\" + borderL + \";\" + borderR +  \"'\";\n      el.innerHTML = \"<div \" + style + \">\" + el.innerHTML + \"</div>\";\n   },\n\n   _roundTopCorners: function(el, color, bgColor) {\n      var corner = this._createCorner(bgColor);\n      for(var i=0 ; i < this.options.numSlices ; i++ ) {\n         corner.appendChild(this._createCornerSlice(color,bgColor,i,\"top\"));\n      }\n      el.style.paddingTop = 0;\n      el.insertBefore(corner,el.firstChild);\n   },\n\n   _roundBottomCorners: function(el, color, bgColor) {\n      var corner = this._createCorner(bgColor);\n      for(var i=(this.options.numSlices-1) ; i >= 0 ; i-- ) {\n         corner.appendChild(this._createCornerSlice(color,bgColor,i,\"bottom\"));\n      }\n      el.style.paddingBottom = 0;\n      el.appendChild(corner);\n   },\n\n   _createCorner: function(bgColor) {\n      var corner = document.createElement(\"div\");\n      corner.style.backgroundColor = (this._isTransparent() ? \"transparent\" : bgColor);\n      return corner;\n   },\n\n   _createCornerSlice: function(color,bgColor, n, position) {\n      var slice = document.createElement(\"span\");\n\n      var inStyle = slice.style;\n      inStyle.backgroundColor = color;\n      inStyle.display  = \"block\";\n      inStyle.height   = \"1px\";\n      inStyle.overflow = \"hidden\";\n      inStyle.fontSize = \"1px\";\n\n      var borderColor = this._borderColor(color,bgColor);\n      if ( this.options.border && n == 0 ) {\n         inStyle.borderTopStyle    = \"solid\";\n         inStyle.borderTopWidth    = \"1px\";\n         inStyle.borderLeftWidth   = \"0px\";\n         inStyle.borderRightWidth  = \"0px\";\n         inStyle.borderBottomWidth = \"0px\";\n         inStyle.height            = \"0px\"; // assumes css compliant box model\n         inStyle.borderColor       = borderColor;\n      }\n      else if(borderColor) {\n         inStyle.borderColor = borderColor;\n         inStyle.borderStyle = \"solid\";\n         inStyle.borderWidth = \"0px 1px\";\n      }\n\n      if ( !this.options.compact && (n == (this.options.numSlices-1)) ) {\n         inStyle.height = \"2px\";\n      }\n      this._setMargin(slice, n, position);\n      this._setBorder(slice, n, position);\n      return slice;\n   },\n\n   _setOptions: function(options) {\n      this.options = {\n         corners : \"all\",\n         color   : \"fromElement\",\n         bgColor : \"fromParent\",\n         blend   : true,\n         border  : false,\n         compact : false\n      };\n      OpenLayers.Util.extend(this.options, options || {});\n\n      this.options.numSlices = this.options.compact ? 2 : 4;\n      if ( this._isTransparent() ) {\n         this.options.blend = false;\n      }\n   },\n\n   _whichSideTop: function() {\n      if ( this._hasString(this.options.corners, \"all\", \"top\") ) {\n         return \"\";\n      }\n      if ( this.options.corners.indexOf(\"tl\") >= 0 && this.options.corners.indexOf(\"tr\") >= 0 ) {\n         return \"\";\n      }\n      if (this.options.corners.indexOf(\"tl\") >= 0) {\n         return \"left\";\n      } else if (this.options.corners.indexOf(\"tr\") >= 0) {\n          return \"right\";\n      }\n      return \"\";\n   },\n\n   _whichSideBottom: function() {\n      if ( this._hasString(this.options.corners, \"all\", \"bottom\") ) {\n         return \"\";\n      }\n      if ( this.options.corners.indexOf(\"bl\")>=0 && this.options.corners.indexOf(\"br\")>=0 ) {\n         return \"\";\n      }\n\n      if(this.options.corners.indexOf(\"bl\") >=0) {\n         return \"left\";\n      } else if(this.options.corners.indexOf(\"br\")>=0) {\n         return \"right\";\n      }\n      return \"\";\n   },\n\n   _borderColor : function(color,bgColor) {\n      if ( color == \"transparent\" ) {\n         return bgColor;\n      } else if ( this.options.border ) {\n         return this.options.border;\n      } else if ( this.options.blend ) {\n         return this._blend( bgColor, color );\n      } else {\n         return \"\";\n      }\n   },\n\n\n   _setMargin: function(el, n, corners) {\n      var marginSize = this._marginSize(n);\n      var whichSide = corners == \"top\" ? this._whichSideTop() : this._whichSideBottom();\n\n      if ( whichSide == \"left\" ) {\n         el.style.marginLeft = marginSize + \"px\"; el.style.marginRight = \"0px\";\n      }\n      else if ( whichSide == \"right\" ) {\n         el.style.marginRight = marginSize + \"px\"; el.style.marginLeft  = \"0px\";\n      }\n      else {\n         el.style.marginLeft = marginSize + \"px\"; el.style.marginRight = marginSize + \"px\";\n      }\n   },\n\n   _setBorder: function(el,n,corners) {\n      var borderSize = this._borderSize(n);\n      var whichSide = corners == \"top\" ? this._whichSideTop() : this._whichSideBottom();\n      if ( whichSide == \"left\" ) {\n         el.style.borderLeftWidth = borderSize + \"px\"; el.style.borderRightWidth = \"0px\";\n      }\n      else if ( whichSide == \"right\" ) {\n         el.style.borderRightWidth = borderSize + \"px\"; el.style.borderLeftWidth  = \"0px\";\n      }\n      else {\n         el.style.borderLeftWidth = borderSize + \"px\"; el.style.borderRightWidth = borderSize + \"px\";\n      }\n      if (this.options.border != false) {\n        el.style.borderLeftWidth = borderSize + \"px\"; el.style.borderRightWidth = borderSize + \"px\";\n      }\n   },\n\n   _marginSize: function(n) {\n      if ( this._isTransparent() ) {\n         return 0;\n      }\n      var marginSizes          = [ 5, 3, 2, 1 ];\n      var blendedMarginSizes   = [ 3, 2, 1, 0 ];\n      var compactMarginSizes   = [ 2, 1 ];\n      var smBlendedMarginSizes = [ 1, 0 ];\n\n      if ( this.options.compact && this.options.blend ) {\n         return smBlendedMarginSizes[n];\n      } else if ( this.options.compact ) {\n         return compactMarginSizes[n];\n      } else if ( this.options.blend ) {\n         return blendedMarginSizes[n];\n      } else {\n         return marginSizes[n];\n      }\n   },\n\n   _borderSize: function(n) {\n      var transparentBorderSizes = [ 5, 3, 2, 1 ];\n      var blendedBorderSizes     = [ 2, 1, 1, 1 ];\n      var compactBorderSizes     = [ 1, 0 ];\n      var actualBorderSizes      = [ 0, 2, 0, 0 ];\n\n      if ( this.options.compact && (this.options.blend || this._isTransparent()) ) {\n         return 1;\n      } else if ( this.options.compact ) {\n         return compactBorderSizes[n];\n      } else if ( this.options.blend ) {\n         return blendedBorderSizes[n];\n      } else if ( this.options.border ) {\n         return actualBorderSizes[n];\n      } else if ( this._isTransparent() ) {\n         return transparentBorderSizes[n];\n      }\n      return 0;\n   },\n\n   _hasString: function(str) { for(var i=1 ; i<arguments.length ; i++) if (str.indexOf(arguments[i]) >= 0) { return true; } return false; },\n   _blend: function(c1, c2) { var cc1 = OpenLayers.Rico.Color.createFromHex(c1); cc1.blend(OpenLayers.Rico.Color.createFromHex(c2)); return cc1; },\n   _background: function(el) { try { return OpenLayers.Rico.Color.createColorFromBackground(el).asHex(); } catch(err) { return \"#ffffff\"; } },\n   _isTransparent: function() { return this.options.color == \"transparent\"; },\n   _isTopRounded: function() { return this._hasString(this.options.corners, \"all\", \"top\", \"tl\", \"tr\"); },\n   _isBottomRounded: function() { return this._hasString(this.options.corners, \"all\", \"bottom\", \"bl\", \"br\"); },\n   _hasSingleTextChild: function(el) { return el.childNodes.length == 1 && el.childNodes[0].nodeType == 3; }\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/Rico/license.js",
    "content": ""
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/lib/deprecated.js",
    "content": "\n\n\nOpenLayers.Class.isPrototype = function () {};\n\nOpenLayers.Class.create = function() {\n    return function() {\n        if (arguments && arguments[0] != OpenLayers.Class.isPrototype) {\n            this.initialize.apply(this, arguments);\n        }\n    };\n};\n\nOpenLayers.Class.inherit = function (P) {\n    var C = function() {\n       P.call(this);\n    };\n    var newArgs = [C].concat(Array.prototype.slice.call(arguments));\n    OpenLayers.inherit.apply(null, newArgs);\n    return C.prototype;\n};\n\n\nOpenLayers.Util.clearArray = function(array) {\n    OpenLayers.Console.warn(\n        OpenLayers.i18n(\n            \"methodDeprecated\", {'newMethod': 'array = []'}\n        )\n    );\n    array.length = 0;\n};\n\nOpenLayers.Util.setOpacity = function(element, opacity) {\n    OpenLayers.Util.modifyDOMElement(element, null, null, null,\n                                     null, null, null, opacity);\n};\n\nOpenLayers.Util.safeStopPropagation = function(evt) {\n    OpenLayers.Event.stop(evt, true);\n};\n\nOpenLayers.Util.getArgs = function(url) {\n    OpenLayers.Console.warn(\n        OpenLayers.i18n(\n            \"methodDeprecated\", {'newMethod': 'OpenLayers.Util.getParameters'}\n        )\n    );\n    return OpenLayers.Util.getParameters(url);\n};\n\nif(typeof window.$  === \"undefined\") {\n    window.$ = OpenLayers.Util.getElement;\n}\n\n\nOpenLayers.nullHandler = function(request) {\n    OpenLayers.Console.userError(OpenLayers.i18n(\"unhandledRequest\", {'statusText':request.statusText}));\n};\n\nOpenLayers.loadURL = function(uri, params, caller,\n                                  onComplete, onFailure) {\n    \n    if(typeof params == 'string') {\n        params = OpenLayers.Util.getParameters(params);\n    }\n    var success = (onComplete) ? onComplete : OpenLayers.nullHandler;\n    var failure = (onFailure) ? onFailure : OpenLayers.nullHandler;\n    \n    return OpenLayers.Request.GET({\n        url: uri, params: params,\n        success: success, failure: failure, scope: caller\n    });\n};\n\nOpenLayers.parseXMLString = function(text) {\n    var index = text.indexOf('<');\n    if (index > 0) {\n        text = text.substring(index);\n    }\n\n    var ajaxResponse = OpenLayers.Util.Try(\n        function() {\n            var xmldom = new ActiveXObject('Microsoft.XMLDOM');\n            xmldom.loadXML(text);\n            return xmldom;\n        },\n        function() {\n            return new DOMParser().parseFromString(text, 'text/xml');\n        },\n        function() {\n            var req = new XMLHttpRequest();\n            req.open(\"GET\", \"data:\" + \"text/xml\" +\n                     \";charset=utf-8,\" + encodeURIComponent(text), false);\n            if (req.overrideMimeType) {\n                req.overrideMimeType(\"text/xml\");\n            }\n            req.send(null);\n            return req.responseXML;\n        }\n    );\n\n    return ajaxResponse;\n};\n\nOpenLayers.Ajax = {\n\n        emptyFunction: function () {},\n\n        getTransport: function() {\n        return OpenLayers.Util.Try(\n            function() {return new XMLHttpRequest();},\n            function() {return new ActiveXObject('Msxml2.XMLHTTP');},\n            function() {return new ActiveXObject('Microsoft.XMLHTTP');}\n        ) || false;\n    },\n\n        activeRequestCount: 0\n};\n\nOpenLayers.Ajax.Responders = {\n  \n        responders: [],\n\n        register: function(responderToAdd) {\n        for (var i = 0; i < this.responders.length; i++){\n            if (responderToAdd == this.responders[i]){\n                return;\n            }\n        }\n        this.responders.push(responderToAdd);\n    },\n\n        unregister: function(responderToRemove) {\n        OpenLayers.Util.removeItem(this.reponders, responderToRemove);\n    },\n\n        dispatch: function(callback, request, transport) {\n        var responder;\n        for (var i = 0; i < this.responders.length; i++) {\n            responder = this.responders[i];\n     \n            if (responder[callback] && \n                typeof responder[callback] == 'function') {\n                try {\n                    responder[callback].apply(responder, \n                                              [request, transport]);\n                } catch (e) {}\n            }\n        }\n    }\n};\n\nOpenLayers.Ajax.Responders.register({\n        onCreate: function() {\n        OpenLayers.Ajax.activeRequestCount++;\n    },\n\n         onComplete: function() {\n         OpenLayers.Ajax.activeRequestCount--;\n     }\n});\n\nOpenLayers.Ajax.Base = OpenLayers.Class({\n      \n        initialize: function(options) {\n        this.options = {\n            method:       'post',\n            asynchronous: true,\n            contentType:  'application/xml',\n            parameters:   ''\n        };\n        OpenLayers.Util.extend(this.options, options || {});\n        \n        this.options.method = this.options.method.toLowerCase();\n        \n        if (typeof this.options.parameters == 'string') {\n            this.options.parameters = \n                OpenLayers.Util.getParameters(this.options.parameters);\n        }\n    }\n});\n\nOpenLayers.Ajax.Request = OpenLayers.Class(OpenLayers.Ajax.Base, {\n\n        _complete: false,\n      \n        initialize: function(url, options) {\n        OpenLayers.Ajax.Base.prototype.initialize.apply(this, [options]);\n        \n        if (OpenLayers.ProxyHost && OpenLayers.String.startsWith(url, \"http\")) {\n            url = OpenLayers.ProxyHost + encodeURIComponent(url);\n        }\n        \n        this.transport = OpenLayers.Ajax.getTransport();\n        this.request(url);\n    },\n\n        request: function(url) {\n        this.url = url;\n        this.method = this.options.method;\n        var params = OpenLayers.Util.extend({}, this.options.parameters);\n        \n        if (this.method != 'get' && this.method != 'post') {\n            params['_method'] = this.method;\n            this.method = 'post';\n        }\n\n        this.parameters = params;        \n        \n        if (params = OpenLayers.Util.getParameterString(params)) {\n            if (this.method == 'get') {\n                this.url += ((this.url.indexOf('?') > -1) ? '&' : '?') + params;\n            } else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {\n                params += '&_=';\n            }\n        }\n        try {\n            var response = new OpenLayers.Ajax.Response(this);\n            if (this.options.onCreate) {\n                this.options.onCreate(response);\n            }\n            \n            OpenLayers.Ajax.Responders.dispatch('onCreate', \n                                                this, \n                                                response);\n    \n            this.transport.open(this.method.toUpperCase(), \n                                this.url,\n                                this.options.asynchronous);\n    \n            if (this.options.asynchronous) {\n                window.setTimeout(\n                    OpenLayers.Function.bind(this.respondToReadyState, this, 1),\n                    10);\n            }\n            \n            this.transport.onreadystatechange = \n                OpenLayers.Function.bind(this.onStateChange, this);    \n            this.setRequestHeaders();\n    \n            this.body =  this.method == 'post' ?\n                (this.options.postBody || params) : null;\n            this.transport.send(this.body);\n            if (!this.options.asynchronous && \n                this.transport.overrideMimeType) {\n                this.onStateChange();\n            }\n        } catch (e) {\n            this.dispatchException(e);\n        }\n    },\n\n        onStateChange: function() {\n        var readyState = this.transport.readyState;\n        if (readyState > 1 && !((readyState == 4) && this._complete)) {\n            this.respondToReadyState(this.transport.readyState);\n        }\n    },\n     \n        setRequestHeaders: function() {\n        var headers = {\n            'X-Requested-With': 'XMLHttpRequest',\n            'Accept': 'text/javascript, text/html, application/xml, text/xml, */*',\n            'OpenLayers': true\n        };\n\n        if (this.method == 'post') {\n            headers['Content-type'] = this.options.contentType +\n                (this.options.encoding ? '; charset=' + this.options.encoding : '');\n    \n            /* Force \"Connection: close\" for older Mozilla browsers to work\n             * around a bug where XMLHttpRequest sends an incorrect\n             * Content-length header. See Mozilla Bugzilla #246651.\n             */\n            if (this.transport.overrideMimeType &&\n                (navigator.userAgent.match(/Gecko\\/(\\d{4})/) || [0,2005])[1] < 2005) {\n                headers['Connection'] = 'close';\n            }\n        }\n        if (typeof this.options.requestHeaders == 'object') {    \n            var extras = this.options.requestHeaders;\n            \n            if (typeof extras.push == 'function') {\n                for (var i = 0, length = extras.length; i < length; i += 2) {\n                    headers[extras[i]] = extras[i+1];\n                }\n            } else {\n                for (var i in extras) {\n                    headers[i] = extras[i];\n                }\n            }\n        }\n        \n        for (var name in headers) {\n            this.transport.setRequestHeader(name, headers[name]);\n        }\n    },\n    \n        success: function() {\n        var status = this.getStatus();\n        return !status || (status >=200 && status < 300);\n    },\n    \n        getStatus: function() {\n        try {\n            return this.transport.status || 0;\n        } catch (e) {\n            return 0;\n        }\n    },\n\n        respondToReadyState: function(readyState) {\n        var state = OpenLayers.Ajax.Request.Events[readyState];\n        var response = new OpenLayers.Ajax.Response(this);\n    \n        if (state == 'Complete') {\n            try {\n                this._complete = true;\n                (this.options['on' + response.status] ||\n                    this.options['on' + (this.success() ? 'Success' : 'Failure')] ||\n                    OpenLayers.Ajax.emptyFunction)(response);\n            } catch (e) {\n                this.dispatchException(e);\n            }\n    \n            var contentType = response.getHeader('Content-type');\n        }\n    \n        try {\n            (this.options['on' + state] || \n             OpenLayers.Ajax.emptyFunction)(response);\n             OpenLayers.Ajax.Responders.dispatch('on' + state, \n                                                 this, \n                                                 response);\n        } catch (e) {\n            this.dispatchException(e);\n        }\n    \n        if (state == 'Complete') {\n            this.transport.onreadystatechange = OpenLayers.Ajax.emptyFunction;\n        }\n    },\n    \n        getHeader: function(name) {\n        try {\n            return this.transport.getResponseHeader(name);\n        } catch (e) {\n            return null;\n        }\n    },\n\n        dispatchException: function(exception) {\n        var handler = this.options.onException;\n        if(handler) {\n            handler(this, exception);\n            OpenLayers.Ajax.Responders.dispatch('onException', this, exception);\n        } else {\n            var listener = false;\n            var responders = OpenLayers.Ajax.Responders.responders;\n            for (var i = 0; i < responders.length; i++) {\n                if(responders[i].onException) {\n                    listener = true;\n                    break;\n                }\n            }\n            if(listener) {\n                OpenLayers.Ajax.Responders.dispatch('onException', this, exception);\n            } else {\n                throw exception;\n            }\n        }\n    }\n});\n\nOpenLayers.Ajax.Request.Events =\n  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];\n\nOpenLayers.Ajax.Response = OpenLayers.Class({\n\n        status: 0,\n    \n\n        statusText: '',\n      \n        initialize: function(request) {\n        this.request = request;\n        var transport = this.transport = request.transport,\n            readyState = this.readyState = transport.readyState;\n        \n        if ((readyState > 2 &&\n            !(!!(window.attachEvent && !window.opera))) ||\n            readyState == 4) {\n            this.status       = this.getStatus();\n            this.statusText   = this.getStatusText();\n            this.responseText = transport.responseText == null ?\n                '' : String(transport.responseText);\n        }\n        \n        if(readyState == 4) {\n            var xml = transport.responseXML;\n            this.responseXML  = xml === undefined ? null : xml;\n        }\n    },\n    \n        getStatus: OpenLayers.Ajax.Request.prototype.getStatus,\n    \n        getStatusText: function() {\n        try {\n            return this.transport.statusText || '';\n        } catch (e) {\n            return '';\n        }\n    },\n    \n        getHeader: OpenLayers.Ajax.Request.prototype.getHeader,\n    \n        getResponseHeader: function(name) {\n        return this.transport.getResponseHeader(name);\n    }\n});\n\n\nOpenLayers.Ajax.getElementsByTagNameNS  = function(parentnode, nsuri, \n                                                   nsprefix, tagname) {\n    var elem = null;\n    if (parentnode.getElementsByTagNameNS) {\n        elem = parentnode.getElementsByTagNameNS(nsuri, tagname);\n    } else {\n        elem = parentnode.getElementsByTagName(nsprefix + ':' + tagname);\n    }\n    return elem;\n};\n\n\nOpenLayers.Ajax.serializeXMLToString = function(xmldom) {\n    var serializer = new XMLSerializer();\n    var data = serializer.serializeToString(xmldom);\n    return data;\n};\n\nOpenLayers.Util.extend(OpenLayers.Element, {\n\n        hide: function() {\n        OpenLayers.Console.warn(OpenLayers.i18n(\"methodDeprecated\", {\n            newMethod: \"element.style.display = 'none';\"\n        }));\n\n        for (var i=0, len=arguments.length; i<len; i++) {\n            var element = OpenLayers.Util.getElement(arguments[i]);\n            if (element) {\n                element.style.display = 'none';\n            }\n        }\n    },\n\n        show: function() {\n        OpenLayers.Console.warn(OpenLayers.i18n(\"methodDeprecated\", {\n            newMethod: \"element.style.display = '';\"\n        }));\n\n        for (var i=0, len=arguments.length; i<len; i++) {\n            var element = OpenLayers.Util.getElement(arguments[i]);\n            if (element) {\n                element.style.display = '';\n            }\n        }\n    },\n\n        getDimensions: function(element) {\n        element = OpenLayers.Util.getElement(element);\n        if (OpenLayers.Element.getStyle(element, 'display') != 'none') {\n            return {width: element.offsetWidth, height: element.offsetHeight};\n        }\n        var els = element.style;\n        var originalVisibility = els.visibility;\n        var originalPosition = els.position;\n        var originalDisplay = els.display;\n        els.visibility = 'hidden';\n        els.position = 'absolute';\n        els.display = '';\n        var originalWidth = element.clientWidth;\n        var originalHeight = element.clientHeight;\n        els.display = originalDisplay;\n        els.position = originalPosition;\n        els.visibility = originalVisibility;\n        return {width: originalWidth, height: originalHeight};\n    }\n    \n});\n\nif (!String.prototype.startsWith) {\n        String.prototype.startsWith = function(sStart) {\n        OpenLayers.Console.warn(OpenLayers.i18n(\"methodDeprecated\",\n                                {'newMethod':'OpenLayers.String.startsWith'}));\n        return OpenLayers.String.startsWith(this, sStart);\n    };\n}\n\nif (!String.prototype.contains) {\n        String.prototype.contains = function(str) {\n        OpenLayers.Console.warn(OpenLayers.i18n(\"methodDeprecated\",\n                                  {'newMethod':'OpenLayers.String.contains'}));\n        return OpenLayers.String.contains(this, str);\n    };\n}\n\nif (!String.prototype.trim) {\n        String.prototype.trim = function() {\n        OpenLayers.Console.warn(OpenLayers.i18n(\"methodDeprecated\",\n                                      {'newMethod':'OpenLayers.String.trim'}));\n        return OpenLayers.String.trim(this);\n    };\n}\n\nif (!String.prototype.camelize) {\n        String.prototype.camelize = function() {\n        OpenLayers.Console.warn(OpenLayers.i18n(\"methodDeprecated\",\n                                  {'newMethod':'OpenLayers.String.camelize'}));\n        return OpenLayers.String.camelize(this);\n    };\n}\n\nif (!Function.prototype.bind) {\n        Function.prototype.bind = function() {\n        OpenLayers.Console.warn(OpenLayers.i18n(\"methodDeprecated\",\n                                {'newMethod':'OpenLayers.Function.bind'}));\n        Array.prototype.unshift.apply(arguments, [this]);\n        return OpenLayers.Function.bind.apply(null, arguments);\n    };\n}\n\nif (!Function.prototype.bindAsEventListener) {\n        Function.prototype.bindAsEventListener = function(object) {\n        OpenLayers.Console.warn(OpenLayers.i18n(\"methodDeprecated\",\n                        {'newMethod':'OpenLayers.Function.bindAsEventListener'}));\n        return OpenLayers.Function.bindAsEventListener(this, object);\n    };\n}\nif (window.Event) {\n    OpenLayers.Util.applyDefaults(window.Event, OpenLayers.Event);\n} else {\n    var Event = OpenLayers.Event;\n}\n\nOpenLayers.Util.extend(OpenLayers.Tile.prototype, {\n        getBoundsFromBaseLayer: function(position) {\n        var msg = OpenLayers.i18n('reprojectDeprecated',\n                                              {'layerName':this.layer.name});\n        OpenLayers.Console.warn(msg);\n        var topLeft = this.layer.map.getLonLatFromLayerPx(position); \n        var bottomRightPx = position.clone();\n        bottomRightPx.x += this.size.w;\n        bottomRightPx.y += this.size.h;\n        var bottomRight = this.layer.map.getLonLatFromLayerPx(bottomRightPx); \n        if (topLeft.lon > bottomRight.lon) {\n            if (topLeft.lon < 0) {\n                topLeft.lon = -180 - (topLeft.lon+180);\n            } else {\n                bottomRight.lon = 180+bottomRight.lon+180;\n            }        \n        }\n        var bounds = new OpenLayers.Bounds(topLeft.lon, \n                                       bottomRight.lat, \n                                       bottomRight.lon, \n                                       topLeft.lat);  \n        return bounds;\n    }    \n});\n\nOpenLayers.Control.MouseDefaults = OpenLayers.Class(OpenLayers.Control, {\n\n    \n        performedDrag: false,\n\n        wheelObserver: null,\n\n        initialize: function() {\n        OpenLayers.Control.prototype.initialize.apply(this, arguments);\n    },\n\n        draw: function() {\n        this.map.events.on({\n            \"click\": this.defaultClick,\n            \"dblclick\": this.defaultDblClick,\n            \"mousedown\": this.defaultMouseDown,\n            \"mouseup\": this.defaultMouseUp,\n            \"mousemove\": this.defaultMouseMove,\n            \"mouseout\": this.defaultMouseOut,\n            scope: this\n        });\n\n        this.registerWheelEvents();\n\n    },\n\n        registerWheelEvents: function() {\n\n        this.wheelObserver = OpenLayers.Function.bindAsEventListener(\n            this.onWheelEvent, this\n        );\n        OpenLayers.Event.observe(window, \"DOMMouseScroll\", this.wheelObserver);\n        OpenLayers.Event.observe(window, \"mousewheel\", this.wheelObserver);\n        OpenLayers.Event.observe(document, \"mousewheel\", this.wheelObserver);\n    },\n\n        defaultClick: function (evt) {\n        if (!OpenLayers.Event.isLeftClick(evt)) {\n            return;\n        }\n        var notAfterDrag = !this.performedDrag;\n        this.performedDrag = false;\n        return notAfterDrag;\n    },\n\n        defaultDblClick: function (evt) {\n        var newCenter = this.map.getLonLatFromViewPortPx( evt.xy ); \n        this.map.setCenter(newCenter, this.map.zoom + 1);\n        OpenLayers.Event.stop(evt);\n        return false;\n    },\n\n        defaultMouseDown: function (evt) {\n        if (!OpenLayers.Event.isLeftClick(evt)) {\n            return;\n        }\n        this.mouseDragStart = evt.xy.clone();\n        this.performedDrag  = false;\n        if (evt.shiftKey) {\n            this.map.div.style.cursor = \"crosshair\";\n            this.zoomBox = OpenLayers.Util.createDiv('zoomBox',\n                                                     this.mouseDragStart,\n                                                     null,\n                                                     null,\n                                                     \"absolute\",\n                                                     \"2px solid red\");\n            this.zoomBox.style.backgroundColor = \"white\";\n            this.zoomBox.style.filter = \"alpha(opacity=50)\"; // IE\n            this.zoomBox.style.opacity = \"0.50\";\n            this.zoomBox.style.fontSize = \"1px\";\n            this.zoomBox.style.zIndex = this.map.Z_INDEX_BASE[\"Popup\"] - 1;\n            this.map.viewPortDiv.appendChild(this.zoomBox);\n        }\n        document.onselectstart = OpenLayers.Function.False;\n        OpenLayers.Event.stop(evt);\n    },\n\n        defaultMouseMove: function (evt) {\n        this.mousePosition = evt.xy.clone();\n\n        if (this.mouseDragStart != null) {\n            if (this.zoomBox) {\n                var deltaX = Math.abs(this.mouseDragStart.x - evt.xy.x);\n                var deltaY = Math.abs(this.mouseDragStart.y - evt.xy.y);\n                this.zoomBox.style.width = Math.max(1, deltaX) + \"px\";\n                this.zoomBox.style.height = Math.max(1, deltaY) + \"px\";\n                if (evt.xy.x < this.mouseDragStart.x) {\n                    this.zoomBox.style.left = evt.xy.x+\"px\";\n                }\n                if (evt.xy.y < this.mouseDragStart.y) {\n                    this.zoomBox.style.top = evt.xy.y+\"px\";\n                }\n            } else {\n                var deltaX = this.mouseDragStart.x - evt.xy.x;\n                var deltaY = this.mouseDragStart.y - evt.xy.y;\n                var size = this.map.getSize();\n                var newXY = new OpenLayers.Pixel(size.w / 2 + deltaX,\n                                                 size.h / 2 + deltaY);\n                var newCenter = this.map.getLonLatFromViewPortPx( newXY ); \n                this.map.setCenter(newCenter, null, true);\n                this.mouseDragStart = evt.xy.clone();\n                this.map.div.style.cursor = \"move\";\n            }\n            this.performedDrag = true;\n        }\n    },\n\n        defaultMouseUp: function (evt) {\n        if (!OpenLayers.Event.isLeftClick(evt)) {\n            return;\n        }\n        if (this.zoomBox) {\n            this.zoomBoxEnd(evt);    \n        } else {\n            if (this.performedDrag) {\n                this.map.setCenter(this.map.center);\n            }\n        }\n        document.onselectstart=null;\n        this.mouseDragStart = null;\n        this.map.div.style.cursor = \"\";\n    },\n\n        defaultMouseOut: function (evt) {\n        if (this.mouseDragStart != null && \n            OpenLayers.Util.mouseLeft(evt, this.map.viewPortDiv)) {\n            if (this.zoomBox) {\n                this.removeZoomBox();\n            }\n            this.mouseDragStart = null;\n        }\n    },\n\n\n        defaultWheelUp: function(evt) {\n        if (this.map.getZoom() <= this.map.getNumZoomLevels()) {\n            this.map.setCenter(this.map.getLonLatFromPixel(evt.xy),\n                               this.map.getZoom() + 1);\n        }\n    },\n\n        defaultWheelDown: function(evt) {\n        if (this.map.getZoom() > 0) {\n            this.map.setCenter(this.map.getLonLatFromPixel(evt.xy),\n                               this.map.getZoom() - 1);\n        }\n    },\n\n        zoomBoxEnd: function(evt) {\n        if (this.mouseDragStart != null) {\n            if (Math.abs(this.mouseDragStart.x - evt.xy.x) > 5 ||    \n                Math.abs(this.mouseDragStart.y - evt.xy.y) > 5) {   \n                var start = this.map.getLonLatFromViewPortPx( this.mouseDragStart ); \n                var end = this.map.getLonLatFromViewPortPx( evt.xy );\n                var top = Math.max(start.lat, end.lat);\n                var bottom = Math.min(start.lat, end.lat);\n                var left = Math.min(start.lon, end.lon);\n                var right = Math.max(start.lon, end.lon);\n                var bounds = new OpenLayers.Bounds(left, bottom, right, top);\n                this.map.zoomToExtent(bounds);\n            } else {\n                var end = this.map.getLonLatFromViewPortPx( evt.xy );\n                this.map.setCenter(new OpenLayers.LonLat(\n                  (end.lon),\n                  (end.lat)\n                 ), this.map.getZoom() + 1);\n            }    \n            this.removeZoomBox();\n       }\n    },\n\n        removeZoomBox: function() {\n        this.map.viewPortDiv.removeChild(this.zoomBox);\n        this.zoomBox = null;\n    },\n\n\n\n\n        onWheelEvent: function(e){\n        var inMap = false;\n        var elem = OpenLayers.Event.element(e);\n        while(elem != null) {\n            if (this.map && elem == this.map.div) {\n                inMap = true;\n                break;\n            }\n            elem = elem.parentNode;\n        }\n        \n        if (inMap) {\n            \n            var delta = 0;\n            if (!e) {\n                e = window.event;\n            }\n            if (e.wheelDelta) {\n                delta = e.wheelDelta/120; \n                if (window.opera && window.opera.version() < 9.2) {\n                    delta = -delta;\n                }\n            } else if (e.detail) {\n                delta = -e.detail / 3;\n            }\n            if (delta) {\n                e.xy = this.mousePosition;\n\n                if (delta < 0) {\n                   this.defaultWheelDown(e);\n                } else {\n                   this.defaultWheelUp(e);\n                }\n            }\n            OpenLayers.Event.stop(e);\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Control.MouseDefaults\"\n});\n\nOpenLayers.Control.MouseToolbar = OpenLayers.Class(\n                                            OpenLayers.Control.MouseDefaults, {\n    \n        buttons: null,\n    \n        direction: \"vertical\",\n    \n        buttonClicked: null,\n    \n        initialize: function(position, direction) {\n        OpenLayers.Control.prototype.initialize.apply(this, arguments);\n        this.position = new OpenLayers.Pixel(OpenLayers.Control.MouseToolbar.X,\n                                             OpenLayers.Control.MouseToolbar.Y);\n        if (position) {\n            this.position = position;\n        }\n        if (direction) {\n            this.direction = direction; \n        }\n        this.measureDivs = [];\n    },\n    \n        destroy: function() {\n        for( var btnId in this.buttons) {\n            var btn = this.buttons[btnId];\n            btn.map = null;\n            btn.events.destroy();\n        }\n        OpenLayers.Control.MouseDefaults.prototype.destroy.apply(this, \n                                                                 arguments);\n    },\n    \n        draw: function() {\n        OpenLayers.Control.prototype.draw.apply(this, arguments); \n        OpenLayers.Control.MouseDefaults.prototype.draw.apply(this, arguments);\n        this.buttons = {};\n        var sz = new OpenLayers.Size(28,28);\n        var centered = new OpenLayers.Pixel(OpenLayers.Control.MouseToolbar.X,0);\n        this._addButton(\"zoombox\", \"drag-rectangle-off.png\", \"drag-rectangle-on.png\", centered, sz, \"Shift->Drag to zoom to area\");\n        centered = centered.add((this.direction == \"vertical\" ? 0 : sz.w), (this.direction == \"vertical\" ? sz.h : 0));\n        this._addButton(\"pan\", \"panning-hand-off.png\", \"panning-hand-on.png\", centered, sz, \"Drag the map to pan.\");\n        centered = centered.add((this.direction == \"vertical\" ? 0 : sz.w), (this.direction == \"vertical\" ? sz.h : 0));\n        this.switchModeTo(\"pan\");\n\n        return this.div;\n    },\n    \n        _addButton:function(id, img, activeImg, xy, sz, title) {\n        var imgLocation = OpenLayers.Util.getImageLocation(img);\n        var activeImgLocation = OpenLayers.Util.getImageLocation(activeImg);\n        var btn = OpenLayers.Util.createAlphaImageDiv(\n                                    \"OpenLayers_Control_MouseToolbar_\" + id, \n                                    xy, sz, imgLocation, \"absolute\");\n        this.div.appendChild(btn);\n        btn.imgLocation = imgLocation;\n        btn.activeImgLocation = activeImgLocation;\n        \n        btn.events = new OpenLayers.Events(this, btn, null, true);\n        btn.events.on({\n            \"mousedown\": this.buttonDown,\n            \"mouseup\": this.buttonUp,\n            \"dblclick\": OpenLayers.Event.stop,\n            scope: this\n        });\n        btn.action = id;\n        btn.title = title;\n        btn.alt = title;\n        btn.map = this.map;\n        this.buttons[id] = btn;\n        return btn;\n    },\n\n        buttonDown: function(evt) {\n        if (!OpenLayers.Event.isLeftClick(evt)) {\n            return;\n        }\n        this.buttonClicked = evt.element.action;\n        OpenLayers.Event.stop(evt);\n    },\n\n        buttonUp: function(evt) {\n        if (!OpenLayers.Event.isLeftClick(evt)) {\n            return;\n        }\n        if (this.buttonClicked != null) {\n            if (this.buttonClicked == evt.element.action) {\n                this.switchModeTo(evt.element.action);\n            }\n            OpenLayers.Event.stop(evt);\n            this.buttonClicked = null;\n        }\n    },\n    \n        defaultDblClick: function (evt) {\n        this.switchModeTo(\"pan\");\n        this.performedDrag = false;\n        var newCenter = this.map.getLonLatFromViewPortPx( evt.xy ); \n        this.map.setCenter(newCenter, this.map.zoom + 1);\n        OpenLayers.Event.stop(evt);\n        return false;\n    },\n\n        defaultMouseDown: function (evt) {\n        if (!OpenLayers.Event.isLeftClick(evt)) {\n            return;\n        }\n        this.mouseDragStart = evt.xy.clone();\n        this.performedDrag = false;\n        this.startViaKeyboard = false;\n        if (evt.shiftKey && this.mode !=\"zoombox\") {\n            this.switchModeTo(\"zoombox\");\n            this.startViaKeyboard = true;\n        } else if (evt.altKey && this.mode !=\"measure\") {\n            this.switchModeTo(\"measure\");\n        } else if (!this.mode) {\n            this.switchModeTo(\"pan\");\n        }\n        \n        switch (this.mode) {\n            case \"zoombox\":\n                this.map.div.style.cursor = \"crosshair\";\n                this.zoomBox = OpenLayers.Util.createDiv('zoomBox',\n                                                         this.mouseDragStart,\n                                                         null,\n                                                         null,\n                                                         \"absolute\",\n                                                         \"2px solid red\");\n                this.zoomBox.style.backgroundColor = \"white\";\n                this.zoomBox.style.filter = \"alpha(opacity=50)\"; // IE\n                this.zoomBox.style.opacity = \"0.50\";\n                this.zoomBox.style.fontSize = \"1px\";\n                this.zoomBox.style.zIndex = this.map.Z_INDEX_BASE[\"Popup\"] - 1;\n                this.map.viewPortDiv.appendChild(this.zoomBox);\n                this.performedDrag = true;\n                break;\n            case \"measure\":\n                var distance = \"\";\n                if (this.measureStart) {\n                    var measureEnd = this.map.getLonLatFromViewPortPx(this.mouseDragStart);\n                    distance = OpenLayers.Util.distVincenty(this.measureStart, measureEnd);\n                    distance = Math.round(distance * 100) / 100;\n                    distance = distance + \"km\";\n                    this.measureStartBox = this.measureBox;\n                }    \n                this.measureStart = this.map.getLonLatFromViewPortPx(this.mouseDragStart);;\n                this.measureBox = OpenLayers.Util.createDiv(null,\n                                                         this.mouseDragStart.add(\n                                                           -2-parseInt(this.map.layerContainerDiv.style.left),\n                                                           -2-parseInt(this.map.layerContainerDiv.style.top)),\n                                                         null,\n                                                         null,\n                                                         \"absolute\");\n                this.measureBox.style.width=\"4px\";\n                this.measureBox.style.height=\"4px\";\n                this.measureBox.style.fontSize = \"1px\";\n                this.measureBox.style.backgroundColor=\"red\";\n                this.measureBox.style.zIndex = this.map.Z_INDEX_BASE[\"Popup\"] - 1;\n                this.map.layerContainerDiv.appendChild(this.measureBox);\n                if (distance) {\n                    this.measureBoxDistance = OpenLayers.Util.createDiv(null,\n                                                         this.mouseDragStart.add(\n                                                           -2-parseInt(this.map.layerContainerDiv.style.left),\n                                                           2-parseInt(this.map.layerContainerDiv.style.top)),\n                                                         null,\n                                                         null,\n                                                         \"absolute\");\n                    \n                    this.measureBoxDistance.innerHTML = distance;\n                    this.measureBoxDistance.style.zIndex = this.map.Z_INDEX_BASE[\"Popup\"] - 1;\n                    this.map.layerContainerDiv.appendChild(this.measureBoxDistance);\n                    this.measureDivs.push(this.measureBoxDistance);\n                }\n                this.measureBox.style.zIndex = this.map.Z_INDEX_BASE[\"Popup\"] - 1;\n                this.map.layerContainerDiv.appendChild(this.measureBox);\n                this.measureDivs.push(this.measureBox);\n                break;\n            default:\n                this.map.div.style.cursor = \"move\";\n                break;\n        }\n        document.onselectstart = OpenLayers.Function.False;\n        OpenLayers.Event.stop(evt);\n    },\n\n        switchModeTo: function(mode) {\n        if (mode != this.mode) {\n            \n\n            if (this.mode && this.buttons[this.mode]) {\n                OpenLayers.Util.modifyAlphaImageDiv(this.buttons[this.mode], null, null, null, this.buttons[this.mode].imgLocation);\n            }\n            if (this.mode == \"measure\" && mode != \"measure\") {\n                for(var i=0, len=this.measureDivs.length; i<len; i++) {\n                    if (this.measureDivs[i]) { \n                        this.map.layerContainerDiv.removeChild(this.measureDivs[i]);\n                    }\n                }\n                this.measureDivs = [];\n                this.measureStart = null;\n            }\n            this.mode = mode;\n            if (this.buttons[mode]) {\n                OpenLayers.Util.modifyAlphaImageDiv(this.buttons[mode], null, null, null, this.buttons[mode].activeImgLocation);\n            }\n            switch (this.mode) {\n                case \"zoombox\":\n                    this.map.div.style.cursor = \"crosshair\";\n                    break;\n                default:\n                    this.map.div.style.cursor = \"\";\n                    break;\n            }\n\n        } \n    }, \n\n        leaveMode: function() {\n        this.switchModeTo(\"pan\");\n    },\n    \n        defaultMouseMove: function (evt) {\n        if (this.mouseDragStart != null) {\n            switch (this.mode) {\n                case \"zoombox\": \n                    var deltaX = Math.abs(this.mouseDragStart.x - evt.xy.x);\n                    var deltaY = Math.abs(this.mouseDragStart.y - evt.xy.y);\n                    this.zoomBox.style.width = Math.max(1, deltaX) + \"px\";\n                    this.zoomBox.style.height = Math.max(1, deltaY) + \"px\";\n                    if (evt.xy.x < this.mouseDragStart.x) {\n                        this.zoomBox.style.left = evt.xy.x+\"px\";\n                    }\n                    if (evt.xy.y < this.mouseDragStart.y) {\n                        this.zoomBox.style.top = evt.xy.y+\"px\";\n                    }\n                    break;\n                default:\n                    var deltaX = this.mouseDragStart.x - evt.xy.x;\n                    var deltaY = this.mouseDragStart.y - evt.xy.y;\n                    var size = this.map.getSize();\n                    var newXY = new OpenLayers.Pixel(size.w / 2 + deltaX,\n                                                     size.h / 2 + deltaY);\n                    var newCenter = this.map.getLonLatFromViewPortPx( newXY ); \n                    this.map.setCenter(newCenter, null, true);\n                    this.mouseDragStart = evt.xy.clone();\n            }\n            this.performedDrag = true;\n        }\n    },\n\n        defaultMouseUp: function (evt) {\n        if (!OpenLayers.Event.isLeftClick(evt)) {\n            return;\n        }\n        switch (this.mode) {\n            case \"zoombox\":\n                this.zoomBoxEnd(evt);\n                if (this.startViaKeyboard) {\n                    this.leaveMode();\n                }\n                break;\n            case \"pan\":\n                if (this.performedDrag) {\n                    this.map.setCenter(this.map.center);\n                }        \n        }\n        document.onselectstart = null;\n        this.mouseDragStart = null;\n        this.map.div.style.cursor = \"default\";\n    },\n\n        defaultMouseOut: function (evt) {\n        if (this.mouseDragStart != null\n            && OpenLayers.Util.mouseLeft(evt, this.map.viewPortDiv)) {\n            if (this.zoomBox) {\n                this.removeZoomBox();\n                if (this.startViaKeyboard) {\n                    this.leaveMode();\n                }\n            }\n            this.mouseDragStart = null;\n            this.map.div.style.cursor = \"default\";\n        }\n    },\n\n        defaultClick: function (evt) {\n        if (this.performedDrag)  {\n            this.performedDrag = false;\n            return false;\n        }\n    },\n    \n    CLASS_NAME: \"OpenLayers.Control.MouseToolbar\"\n});\n\nOpenLayers.Control.MouseToolbar.X = 6;\nOpenLayers.Control.MouseToolbar.Y = 300;\n\n\nOpenLayers.Util.extend(OpenLayers.Layer.Grid.prototype, {\n\n        getGridBounds: function() {\n        var msg = \"The getGridBounds() function is deprecated. It will be \" +\n                  \"removed in 3.0. Please use getTilesBounds() instead.\";\n        OpenLayers.Console.warn(msg);\n        return this.getTilesBounds();\n    }\n});\n\nOpenLayers.Util.extend(OpenLayers.Format.XML.prototype, {\n\n        concatChildValues: function(node, def) {\n        var value = \"\";\n        var child = node.firstChild;\n        var childValue;\n        while(child) {\n            childValue = child.nodeValue;\n            if(childValue) {\n                value += childValue;\n            }\n            child = child.nextSibling;\n        }\n        if(value == \"\" && def != undefined) {\n            value = def;\n        }\n        return value;\n    }\n\n});\n\nOpenLayers.Layer.WMS.Post = OpenLayers.Class(OpenLayers.Layer.WMS, {\n\n        unsupportedBrowsers: [\"mozilla\", \"firefox\", \"opera\"],\n\n        SUPPORTED_TRANSITIONS: [],\n    \n        usePost: null,\n\n        initialize: function(name, url, params, options) {\n        var newArguments = [];\n        newArguments.push(name, url, params, options);\n        OpenLayers.Layer.WMS.prototype.initialize.apply(this, newArguments);\n\n        this.usePost = OpenLayers.Util.indexOf(\n            this.unsupportedBrowsers, OpenLayers.BROWSER_NAME) == -1;\n    },\n    \n        addTile: function(bounds,position) {\n        return new OpenLayers.Tile.Image(\n            this, position, bounds, null, this.tileSize, {\n                maxGetUrlLength: this.usePost ? 0 : null\n            });\n    },\n\n    CLASS_NAME: 'OpenLayers.Layer.WMS.Post'\n});\n\nOpenLayers.Layer.WMS.Untiled = OpenLayers.Class(OpenLayers.Layer.WMS, {\n\n        singleTile: true,\n\n        initialize: function(name, url, params, options) {\n        OpenLayers.Layer.WMS.prototype.initialize.apply(this, arguments);\n        \n        var msg = \"The OpenLayers.Layer.WMS.Untiled class is deprecated and \" +\n                  \"will be removed in 3.0. Instead, you should use the \" +\n                  \"normal OpenLayers.Layer.WMS class, passing it the option \" +\n                  \"'singleTile' as true.\";\n        OpenLayers.Console.warn(msg);\n    },    \n\n        clone: function (obj) {\n        \n        if (obj == null) {\n            obj = new OpenLayers.Layer.WMS.Untiled(this.name,\n                                                   this.url,\n                                                   this.params,\n                                                   this.getOptions());\n        }\n        obj = OpenLayers.Layer.WMS.prototype.clone.apply(this, [obj]);\n\n        return obj;\n    }, \n\n    CLASS_NAME: \"OpenLayers.Layer.WMS.Untiled\"\n});\n\nOpenLayers.Layer.MapServer.Untiled = OpenLayers.Class(OpenLayers.Layer.MapServer, {\n\n        singleTile: true,\n\n        initialize: function(name, url, params, options) {\n        OpenLayers.Layer.MapServer.prototype.initialize.apply(this, arguments);\n        \n        var msg = \"The OpenLayers.Layer.MapServer.Untiled class is deprecated and \" +\n                  \"will be removed in 3.0. Instead, you should use the \" +\n                  \"normal OpenLayers.Layer.MapServer class, passing it the option \" +\n                  \"'singleTile' as true.\";\n        OpenLayers.Console.warn(msg);\n    },    \n\n        clone: function (obj) {\n        \n        if (obj == null) {\n            obj = new OpenLayers.Layer.MapServer.Untiled(this.name,\n                                                         this.url,\n                                                         this.params,\n                                                         this.getOptions());\n        }\n        obj = OpenLayers.Layer.MapServer.prototype.clone.apply(this, [obj]);\n        \n        return obj;\n    }, \n\n    CLASS_NAME: \"OpenLayers.Layer.MapServer.Untiled\"\n});\n\nOpenLayers.Tile.WFS = OpenLayers.Class(OpenLayers.Tile, {\n\n        features: null,\n\n        url: null,\n\n        request: null,\n\n        initialize: function(layer, position, bounds, url, size) {\n        OpenLayers.Tile.prototype.initialize.apply(this, arguments);\n        this.url = url;\n        this.features = [];\n    },\n\n        destroy: function() {\n        OpenLayers.Tile.prototype.destroy.apply(this, arguments);\n        this.destroyAllFeatures();\n        this.features = null;\n        this.url = null;\n        if(this.request) {\n            this.request.abort();\n            this.request = null;\n        }\n    },\n\n        clear: function() {\n        this.destroyAllFeatures();\n    },\n\n        draw:function() {\n        if (OpenLayers.Tile.prototype.draw.apply(this, arguments)) {\n            if (this.isLoading) {\n                this.events.triggerEvent(\"reload\");\n            } else {\n                this.isLoading = true;\n                this.events.triggerEvent(\"loadstart\");\n            }\n            this.loadFeaturesForRegion(this.requestSuccess);\n        }\n    },\n\n        loadFeaturesForRegion:function(success, failure) {\n        if(this.request) {\n            this.request.abort();\n        }\n        this.request = OpenLayers.Request.GET({\n            url: this.url,\n            success: success,\n            failure: failure,\n            scope: this\n        });\n    },\n\n        requestSuccess:function(request) {\n        if (this.features) {\n            var doc = request.responseXML;\n            if (!doc || !doc.documentElement) {\n                doc = request.responseText;\n            }\n            if (this.layer.vectorMode) {\n                this.layer.addFeatures(this.layer.formatObject.read(doc));\n            } else {\n                var xml = new OpenLayers.Format.XML();\n                if (typeof doc == \"string\") {\n                    doc = xml.read(doc);\n                }\n                var resultFeatures = xml.getElementsByTagNameNS(\n                    doc, \"http://www.opengis.net/gml\", \"featureMember\"\n                );\n                this.addResults(resultFeatures);\n            }\n        }\n        if (this.events) {\n            this.events.triggerEvent(\"loadend\");\n        }\n        this.request = null;\n    },\n\n        addResults: function(results) {\n        for (var i=0; i < results.length; i++) {\n            var feature = new this.layer.featureClass(this.layer,\n                                                      results[i]);\n            this.features.push(feature);\n        }\n    },\n\n\n        destroyAllFeatures: function() {\n        while(this.features.length > 0) {\n            var feature = this.features.shift();\n            feature.destroy();\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Tile.WFS\"\n  }\n);\n\nOpenLayers.Feature.WFS = OpenLayers.Class(OpenLayers.Feature, {\n\n        initialize: function(layer, xmlNode) {\n        var newArguments = arguments;\n        var data = this.processXMLNode(xmlNode);\n        newArguments = new Array(layer, data.lonlat, data);\n        OpenLayers.Feature.prototype.initialize.apply(this, newArguments);\n        this.createMarker();\n        this.layer.addMarker(this.marker);\n    },\n\n        destroy: function() {\n        if (this.marker != null) {\n            this.layer.removeMarker(this.marker);\n        }\n        OpenLayers.Feature.prototype.destroy.apply(this, arguments);\n    },\n\n        processXMLNode: function(xmlNode) {\n        var point = OpenLayers.Ajax.getElementsByTagNameNS(xmlNode, \"http://www.opengis.net/gml\", \"gml\", \"Point\");\n        var text  = OpenLayers.Util.getXmlNodeValue(OpenLayers.Ajax.getElementsByTagNameNS(point[0], \"http://www.opengis.net/gml\",\"gml\", \"coordinates\")[0]);\n        var floats = text.split(\",\");\n        return {lonlat: new OpenLayers.LonLat(parseFloat(floats[0]),\n                                              parseFloat(floats[1])),\n                id: null};\n\n    },\n\n    CLASS_NAME: \"OpenLayers.Feature.WFS\"\n});\n\n\nOpenLayers.Layer.WFS = OpenLayers.Class(\n  OpenLayers.Layer.Vector, OpenLayers.Layer.Markers, {\n\n        isBaseLayer: false,\n\n        tile: null,\n\n        ratio: 2,\n\n        DEFAULT_PARAMS: { service: \"WFS\",\n                      version: \"1.0.0\",\n                      request: \"GetFeature\"\n                    },\n\n        featureClass: null,\n\n        format: null,\n\n        formatObject: null,\n\n        formatOptions: null,\n\n        vectorMode: true,\n\n        encodeBBOX: false,\n\n        extractAttributes: false,\n\n        initialize: function(name, url, params, options) {\n        if (options == undefined) { options = {}; }\n\n        if (options.featureClass ||\n            !OpenLayers.Layer.Vector ||\n            !OpenLayers.Feature.Vector) {\n            this.vectorMode = false;\n        }\n        params = OpenLayers.Util.upperCaseObject(params);\n        OpenLayers.Util.extend(options, {'reportError': false});\n        var newArguments = [];\n        newArguments.push(name, options);\n        OpenLayers.Layer.Vector.prototype.initialize.apply(this, newArguments);\n        if (!this.renderer || !this.vectorMode) {\n            this.vectorMode = false;\n            if (!options.featureClass) {\n                options.featureClass = OpenLayers.Feature.WFS;\n            }\n            OpenLayers.Layer.Markers.prototype.initialize.apply(this,\n                                                                newArguments);\n        }\n\n        if (this.params && this.params.typename && !this.options.typename) {\n            this.options.typename = this.params.typename;\n        }\n\n        if (!this.options.geometry_column) {\n            this.options.geometry_column = \"the_geom\";\n        }\n\n        this.params = OpenLayers.Util.applyDefaults(\n            params,\n            OpenLayers.Util.upperCaseObject(this.DEFAULT_PARAMS)\n        );\n        this.url = url;\n    },\n\n\n        destroy: function() {\n        if (this.vectorMode) {\n            OpenLayers.Layer.Vector.prototype.destroy.apply(this, arguments);\n        } else {\n            OpenLayers.Layer.Markers.prototype.destroy.apply(this, arguments);\n        }\n        if (this.tile) {\n            this.tile.destroy();\n        }\n        this.tile = null;\n\n        this.ratio = null;\n        this.featureClass = null;\n        this.format = null;\n\n        if (this.formatObject && this.formatObject.destroy) {\n            this.formatObject.destroy();\n        }\n        this.formatObject = null;\n\n        this.formatOptions = null;\n        this.vectorMode = null;\n        this.encodeBBOX = null;\n        this.extractAttributes = null;\n    },\n\n        setMap: function(map) {\n        if (this.vectorMode) {\n            OpenLayers.Layer.Vector.prototype.setMap.apply(this, arguments);\n\n            var options = {\n              'extractAttributes': this.extractAttributes\n            };\n\n            OpenLayers.Util.extend(options, this.formatOptions);\n            if (this.map && !this.projection.equals(this.map.getProjectionObject())) {\n                options.externalProjection = this.projection;\n                options.internalProjection = this.map.getProjectionObject();\n            }\n\n            this.formatObject = this.format ? new this.format(options) : new OpenLayers.Format.GML(options);\n        } else {\n            OpenLayers.Layer.Markers.prototype.setMap.apply(this, arguments);\n        }\n    },\n\n        moveTo:function(bounds, zoomChanged, dragging) {\n        if (this.vectorMode) {\n            OpenLayers.Layer.Vector.prototype.moveTo.apply(this, arguments);\n        } else {\n            OpenLayers.Layer.Markers.prototype.moveTo.apply(this, arguments);\n        }\n        if (dragging) {\n            return false;\n        }\n\n        if ( zoomChanged ) {\n            if (this.vectorMode) {\n                this.renderer.clear();\n            }\n        }\n        if (this.options.minZoomLevel) {\n            OpenLayers.Console.warn(OpenLayers.i18n('minZoomLevelError'));\n\n            if (this.map.getZoom() < this.options.minZoomLevel) {\n                return null;\n            }\n        }\n\n        if (bounds == null) {\n            bounds = this.map.getExtent();\n        }\n\n        var firstRendering = (this.tile == null);\n        var outOfBounds = (!firstRendering &&\n                           !this.tile.bounds.containsBounds(bounds));\n\n        if (zoomChanged || firstRendering || (!dragging && outOfBounds)) {\n            var center = bounds.getCenterLonLat();\n            var tileWidth = bounds.getWidth() * this.ratio;\n            var tileHeight = bounds.getHeight() * this.ratio;\n            var tileBounds =\n                new OpenLayers.Bounds(center.lon - (tileWidth / 2),\n                                      center.lat - (tileHeight / 2),\n                                      center.lon + (tileWidth / 2),\n                                      center.lat + (tileHeight / 2));\n            var tileSize = this.map.getSize();\n            tileSize.w = tileSize.w * this.ratio;\n            tileSize.h = tileSize.h * this.ratio;\n            var ul = new OpenLayers.LonLat(tileBounds.left, tileBounds.top);\n            var pos = this.map.getLayerPxFromLonLat(ul);\n            var url = this.getFullRequestString();\n\n            var params = null;\n            var filter = this.params.filter || this.params.FILTER;\n            if (filter) {\n                params = {FILTER: filter};\n            }\n            else {\n                params = {BBOX: this.encodeBBOX ? tileBounds.toBBOX()\n                                                    : tileBounds.toArray()};\n            }\n\n            if (this.map && !this.projection.equals(this.map.getProjectionObject())) {\n                var projectedBounds = tileBounds.clone();\n                projectedBounds.transform(this.map.getProjectionObject(),\n                                          this.projection);\n                if (!filter){\n                    params.BBOX = this.encodeBBOX ? projectedBounds.toBBOX()\n                                                : projectedBounds.toArray();\n                }\n            }\n\n            url += \"&\" + OpenLayers.Util.getParameterString(params);\n\n            if (!this.tile) {\n                this.tile = new OpenLayers.Tile.WFS(this, pos, tileBounds,\n                                                     url, tileSize);\n                this.addTileMonitoringHooks(this.tile);\n                this.tile.draw();\n            } else {\n                if (this.vectorMode) {\n                    this.destroyFeatures();\n                    this.renderer.clear();\n                } else {\n                    this.clearMarkers();\n                }\n                this.removeTileMonitoringHooks(this.tile);\n                this.tile.destroy();\n\n                this.tile = null;\n                this.tile = new OpenLayers.Tile.WFS(this, pos, tileBounds,\n                                                     url, tileSize);\n                this.addTileMonitoringHooks(this.tile);\n                this.tile.draw();\n            }\n        }\n    },\n\n        addTileMonitoringHooks: function(tile) {\n        tile.onLoadStart = function() {\n            if (this == this.layer.tile) {\n                this.layer.events.triggerEvent(\"loadstart\");\n            }\n        };\n        tile.events.register(\"loadstart\", tile, tile.onLoadStart);\n\n        tile.onLoadEnd = function() {\n            if (this == this.layer.tile) {\n                this.layer.events.triggerEvent(\"tileloaded\");\n                this.layer.events.triggerEvent(\"loadend\");\n            }\n        };\n        tile.events.register(\"loadend\", tile, tile.onLoadEnd);\n        tile.events.register(\"unload\", tile, tile.onLoadEnd);\n    },\n\n        removeTileMonitoringHooks: function(tile) {\n        tile.unload();\n        tile.events.un({\n            \"loadstart\": tile.onLoadStart,\n            \"loadend\": tile.onLoadEnd,\n            \"unload\": tile.onLoadEnd,\n            scope: tile\n        });\n    },\n\n        onMapResize: function() {\n        if(this.vectorMode) {\n            OpenLayers.Layer.Vector.prototype.onMapResize.apply(this,\n                                                                arguments);\n        } else {\n            OpenLayers.Layer.Markers.prototype.onMapResize.apply(this,\n                                                                 arguments);\n        }\n    },\n\n        display: function() {\n        if(this.vectorMode) {\n            OpenLayers.Layer.Vector.prototype.display.apply(this,\n                                                                arguments);\n        } else {\n            OpenLayers.Layer.Markers.prototype.display.apply(this,\n                                                                 arguments);\n        }\n    },\n\n        mergeNewParams:function(newParams) {\n        var upperParams = OpenLayers.Util.upperCaseObject(newParams);\n        var newArguments = [upperParams];\n        return OpenLayers.Layer.HTTPRequest.prototype.mergeNewParams.apply(this,\n                                                                 newArguments);\n    },\n\n        clone: function (obj) {\n\n        if (obj == null) {\n            obj = new OpenLayers.Layer.WFS(this.name,\n                                           this.url,\n                                           this.params,\n                                           this.getOptions());\n        }\n        if (this.vectorMode) {\n            obj = OpenLayers.Layer.Vector.prototype.clone.apply(this, [obj]);\n        } else {\n            obj = OpenLayers.Layer.Markers.prototype.clone.apply(this, [obj]);\n        }\n\n        return obj;\n    },\n\n        getFullRequestString:function(newParams, altUrl) {\n        var projectionCode = this.projection.getCode() || this.map.getProjection();\n        this.params.SRS = (projectionCode == \"none\") ? null : projectionCode;\n\n        return OpenLayers.Layer.Grid.prototype.getFullRequestString.apply(\n                                                    this, arguments);\n    },\n\n        commit: function() {\n        if (!this.writer) {\n            var options = {};\n            if (this.map && !this.projection.equals(this.map.getProjectionObject())) {\n                options.externalProjection = this.projection;\n                options.internalProjection = this.map.getProjectionObject();\n            }\n\n            this.writer = new OpenLayers.Format.WFS(options,this);\n        }\n\n        var data = this.writer.write(this.features);\n\n        OpenLayers.Request.POST({\n            url: this.url,\n            data: data,\n            success: this.commitSuccess,\n            failure: this.commitFailure,\n            scope: this\n        });\n    },\n\n        commitSuccess: function(request) {\n        var response = request.responseText;\n        if (response.indexOf('SUCCESS') != -1) {\n            this.commitReport(OpenLayers.i18n(\"commitSuccess\", {'response':response}));\n\n            for(var i = 0; i < this.features.length; i++) {\n                this.features[i].state = null;\n            }\n        } else if (response.indexOf('FAILED') != -1 ||\n            response.indexOf('Exception') != -1) {\n            this.commitReport(OpenLayers.i18n(\"commitFailed\", {'response':response}));\n        }\n    },\n\n        commitFailure: function(request) {},\n\n        commitReport: function(string, response) {\n        OpenLayers.Console.userError(string);\n    },\n\n\n        refresh: function() {\n        if (this.tile) {\n            if (this.vectorMode) {\n                this.renderer.clear();\n                this.features.length = 0;\n            } else {\n                this.clearMarkers();\n                this.markers.length = 0;\n            }\n            this.tile.draw();\n        }\n    },\n\n        getDataExtent: function () {\n        var extent;\n        if (this.vectorMode) {\n            extent = OpenLayers.Layer.Vector.prototype.getDataExtent.apply(this);\n        } else {\n            extent = OpenLayers.Layer.Markers.prototype.getDataExtent.apply(this);\n        }\n\n        return extent;\n    },\n\n        setOpacity: function (opacity) {\n        if (this.vectorMode) {\n            OpenLayers.Layer.Vector.prototype.setOpacity.apply(this, [opacity]);\n        } else {\n            OpenLayers.Layer.Markers.prototype.setOpacity.apply(this, [opacity]);\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.WFS\"\n});\n\nOpenLayers.Layer.VirtualEarth = OpenLayers.Class(\n    OpenLayers.Layer.EventPane,\n    OpenLayers.Layer.FixedZoomLevels, {\n\n        MIN_ZOOM_LEVEL: 1,\n\n        MAX_ZOOM_LEVEL: 19,\n\n        RESOLUTIONS: [\n        1.40625,\n        0.703125,\n        0.3515625,\n        0.17578125,\n        0.087890625,\n        0.0439453125,\n        0.02197265625,\n        0.010986328125,\n        0.0054931640625,\n        0.00274658203125,\n        0.001373291015625,\n        0.0006866455078125,\n        0.00034332275390625,\n        0.000171661376953125,\n        0.0000858306884765625,\n        0.00004291534423828125,\n        0.00002145767211914062,\n        0.00001072883605957031,\n        0.00000536441802978515\n    ],\n\n        type: null,\n\n        wrapDateLine: true,\n\n        sphericalMercator: false,\n\n        animationEnabled: true,\n\n        initialize: function(name, options) {\n        OpenLayers.Layer.EventPane.prototype.initialize.apply(this, arguments);\n        OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,\n                                                                    arguments);\n        if(this.sphericalMercator) {\n            OpenLayers.Util.extend(this, OpenLayers.Layer.SphericalMercator);\n            this.initMercatorParameters();\n        }\n    },\n\n        loadMapObject:function() {\n        var veDiv = OpenLayers.Util.createDiv(this.name);\n        var sz = this.map.getSize();\n        veDiv.style.width = sz.w + \"px\";\n        veDiv.style.height = sz.h + \"px\";\n        this.div.appendChild(veDiv);\n\n        try { // crash prevention\n            this.mapObject = new VEMap(this.name);\n        } catch (e) { }\n\n        if (this.mapObject != null) {\n            try { // this is to catch a Mozilla bug without falling apart\n                this.mapObject.LoadMap(null, null, this.type, true);\n                this.mapObject.AttachEvent(\"onmousedown\", OpenLayers.Function.True);\n\n            } catch (e) { }\n            this.mapObject.HideDashboard();\n            if(typeof this.mapObject.SetAnimationEnabled == \"function\") {\n                this.mapObject.SetAnimationEnabled(this.animationEnabled);\n            }\n        }\n        if ( !this.mapObject ||\n             !this.mapObject.vemapcontrol ||\n             !this.mapObject.vemapcontrol.PanMap ||\n             (typeof this.mapObject.vemapcontrol.PanMap != \"function\")) {\n\n            this.dragPanMapObject = null;\n        }\n\n    },\n\n        onMapResize: function() {\n        this.mapObject.Resize(this.map.size.w, this.map.size.h);\n    },\n\n        getWarningHTML:function() {\n        return OpenLayers.i18n(\n            \"getLayerWarning\", {'layerType':'VE', 'layerLib':'VirtualEarth'}\n        );\n    },\n\n        setMapObjectCenter: function(center, zoom) {\n        this.mapObject.SetCenterAndZoom(center, zoom);\n    },\n\n        getMapObjectCenter: function() {\n        return this.mapObject.GetCenter();\n    },\n\n        dragPanMapObject: function(dX, dY) {\n        this.mapObject.vemapcontrol.PanMap(dX, -dY);\n    },\n\n        getMapObjectZoom: function() {\n        return this.mapObject.GetZoomLevel();\n    },\n\n        getMapObjectLonLatFromMapObjectPixel: function(moPixel) {\n        return (typeof VEPixel != 'undefined')\n            ? this.mapObject.PixelToLatLong(moPixel)\n            : this.mapObject.PixelToLatLong(moPixel.x, moPixel.y);\n    },\n\n        getMapObjectPixelFromMapObjectLonLat: function(moLonLat) {\n        return this.mapObject.LatLongToPixel(moLonLat);\n    },\n\n        getLongitudeFromMapObjectLonLat: function(moLonLat) {\n        return this.sphericalMercator ?\n            this.forwardMercator(moLonLat.Longitude, moLonLat.Latitude).lon :\n            moLonLat.Longitude;\n    },\n\n        getLatitudeFromMapObjectLonLat: function(moLonLat) {\n        return this.sphericalMercator ?\n            this.forwardMercator(moLonLat.Longitude, moLonLat.Latitude).lat :\n            moLonLat.Latitude;\n    },\n\n        getMapObjectLonLatFromLonLat: function(lon, lat) {\n        var veLatLong;\n        if(this.sphericalMercator) {\n            var lonlat = this.inverseMercator(lon, lat);\n            veLatLong = new VELatLong(lonlat.lat, lonlat.lon);\n        } else {\n            veLatLong = new VELatLong(lat, lon);\n        }\n        return veLatLong;\n    },\n\n        getXFromMapObjectPixel: function(moPixel) {\n        return moPixel.x;\n    },\n\n        getYFromMapObjectPixel: function(moPixel) {\n        return moPixel.y;\n    },\n\n        getMapObjectPixelFromXY: function(x, y) {\n        return (typeof VEPixel != 'undefined') ? new VEPixel(x, y)\n                         : new Msn.VE.Pixel(x, y);\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.VirtualEarth\"\n});\n\n/*\n * Copyright 2007, Google Inc.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions are met:\n *\n *  1. Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *  2. Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *  3. Neither the name of Google Inc. nor the names of its contributors may be\n *     used to endorse or promote products derived from this software without\n *     specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED\n * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO\n * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;\n * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\n * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR\n * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\n * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n *\n * Sets up google.gears.*, which is *the only* supported way to access Gears.\n *\n * Circumvent this file at your own risk!\n *\n * In the future, Gears may automatically define google.gears.* without this\n * file. Gears may use these objects to transparently fix bugs and compatibility\n * issues. Applications that use the code below will continue to work seamlessly\n * when that happens.\n */\n\n(function() {\n  if (window.google && google.gears) {\n    return;\n  }\n\n  var factory = null;\n  if (typeof GearsFactory != 'undefined') {\n    factory = new GearsFactory();\n  } else {\n    try {\n      factory = new ActiveXObject('Gears.Factory');\n      if (factory.getBuildInfo().indexOf('ie_mobile') != -1) {\n        factory.privateSetGlobalObject(this);\n      }\n    } catch (e) {\n      if ((typeof navigator.mimeTypes != 'undefined')\n           && navigator.mimeTypes[\"application/x-googlegears\"]) {\n        factory = document.createElement(\"object\");\n        factory.style.display = \"none\";\n        factory.width = 0;\n        factory.height = 0;\n        factory.type = \"application/x-googlegears\";\n        document.documentElement.appendChild(factory);\n      }\n    }\n  }\n  if (!factory) {\n    return;\n  }\n  if (!window.google) {\n    google = {};\n  }\n\n  if (!google.gears) {\n    google.gears = {factory: factory};\n  }\n})();\n\nOpenLayers.Protocol.SQL = OpenLayers.Class(OpenLayers.Protocol, {\n\n        databaseName: 'ol',\n\n        tableName: \"ol_vector_features\",\n\n        postReadFiltering: true,\n\n        initialize: function(options) {\n        OpenLayers.Protocol.prototype.initialize.apply(this, [options]);\n    },\n\n        destroy: function() {\n        OpenLayers.Protocol.prototype.destroy.apply(this);\n    },\n\n        supported: function() {\n        return false;\n    },\n\n        evaluateFilter: function(feature, filter) {\n        return filter && this.postReadFiltering ?\n            filter.evaluate(feature) : true;\n    },\n\n    CLASS_NAME: \"OpenLayers.Protocol.SQL\"\n});\n\nOpenLayers.Protocol.SQL.Gears = OpenLayers.Class(OpenLayers.Protocol.SQL, {\n\n        FID_PREFIX: '__gears_fid__',\n\n        NULL_GEOMETRY: '__gears_null_geometry__',\n\n        NULL_FEATURE_STATE: '__gears_null_feature_state__',\n\n        jsonParser: null,\n\n        wktParser: null,\n\n        fidRegExp: null,\n\n        saveFeatureState: true,\n\n        typeOfFid: \"string\",\n\n        db: null,\n\n        initialize: function(options) {\n        if (!this.supported()) {\n            return;\n        }\n        OpenLayers.Protocol.SQL.prototype.initialize.apply(this, [options]);\n        this.jsonParser = new OpenLayers.Format.JSON();\n        this.wktParser = new OpenLayers.Format.WKT();\n\n        this.fidRegExp = new RegExp('^' + this.FID_PREFIX);\n        this.initializeDatabase();\n\n\n    },\n\n        initializeDatabase: function() {\n        this.db = google.gears.factory.create('beta.database');\n        this.db.open(this.databaseName);\n        this.db.execute(\n            \"CREATE TABLE IF NOT EXISTS \" + this.tableName +\n            \" (fid TEXT UNIQUE, geometry TEXT, properties TEXT,\" +\n            \"  state TEXT)\");\n   },\n\n        destroy: function() {\n        this.db.close();\n        this.db = null;\n\n        this.jsonParser = null;\n        this.wktParser = null;\n\n        OpenLayers.Protocol.SQL.prototype.destroy.apply(this);\n    },\n\n        supported: function() {\n        return !!(window.google && google.gears);\n    },\n\n        read: function(options) {\n        OpenLayers.Protocol.prototype.read.apply(this, arguments);\n        options = OpenLayers.Util.applyDefaults(options, this.options);\n\n        var feature, features = [];\n        var rs = this.db.execute(\"SELECT * FROM \" + this.tableName);\n        while (rs.isValidRow()) {\n            feature = this.unfreezeFeature(rs);\n            if (this.evaluateFilter(feature, options.filter)) {\n                if (!options.noFeatureStateReset) {\n                    feature.state = null;\n                }\n                features.push(feature);\n            }\n            rs.next();\n        }\n        rs.close();\n\n        var resp = new OpenLayers.Protocol.Response({\n            code: OpenLayers.Protocol.Response.SUCCESS,\n            requestType: \"read\",\n            features: features\n        });\n\n        if (options && options.callback) {\n            options.callback.call(options.scope, resp);\n        }\n\n        return resp;\n    },\n\n        unfreezeFeature: function(row) {\n        var feature;\n        var wkt = row.fieldByName('geometry');\n        if (wkt == this.NULL_GEOMETRY) {\n            feature = new OpenLayers.Feature.Vector();\n        } else {\n            feature = this.wktParser.read(wkt);\n        }\n\n        feature.attributes = this.jsonParser.read(\n            row.fieldByName('properties'));\n\n        feature.fid = this.extractFidFromField(row.fieldByName('fid'));\n\n        var state = row.fieldByName('state');\n        if (state == this.NULL_FEATURE_STATE) {\n            state = null;\n        }\n        feature.state = state;\n\n        return feature;\n    },\n\n        extractFidFromField: function(field) {\n        if (!field.match(this.fidRegExp) && this.typeOfFid == \"number\") {\n            field = parseFloat(field);\n        }\n        return field;\n    },\n\n        create: function(features, options) {\n        options = OpenLayers.Util.applyDefaults(options, this.options);\n\n        var resp = this.createOrUpdate(features);\n        resp.requestType = \"create\";\n\n        if (options && options.callback) {\n            options.callback.call(options.scope, resp);\n        }\n\n        return resp;\n    },\n\n        update: function(features, options) {\n        options = OpenLayers.Util.applyDefaults(options, this.options);\n\n        var resp = this.createOrUpdate(features);\n        resp.requestType = \"update\";\n\n        if (options && options.callback) {\n            options.callback.call(options.scope, resp);\n        }\n\n        return resp;\n    },\n\n        createOrUpdate: function(features) {\n        if (!(OpenLayers.Util.isArray(features))) {\n            features = [features];\n        }\n\n        var i, len = features.length, feature;\n        var insertedFeatures = new Array(len);\n\n        for (i = 0; i < len; i++) {\n            feature = features[i];\n            var params = this.freezeFeature(feature);\n            this.db.execute(\n                \"REPLACE INTO \" + this.tableName +\n                \" (fid, geometry, properties, state)\" +\n                \" VALUES (?, ?, ?, ?)\",\n                params);\n\n            var clone = feature.clone();\n            clone.fid = this.extractFidFromField(params[0]);\n            insertedFeatures[i] = clone;\n        }\n\n        return new OpenLayers.Protocol.Response({\n            code: OpenLayers.Protocol.Response.SUCCESS,\n            features: insertedFeatures,\n            reqFeatures: features\n        });\n    },\n\n        freezeFeature: function(feature) {\n        feature.fid = feature.fid != null ?\n            \"\" + feature.fid : OpenLayers.Util.createUniqueID(this.FID_PREFIX);\n\n        var geometry = feature.geometry != null ?\n            feature.geometry.toString() : this.NULL_GEOMETRY;\n\n        var properties = this.jsonParser.write(feature.attributes);\n\n        var state = this.getFeatureStateForFreeze(feature);\n\n        return [feature.fid, geometry, properties, state];\n    },\n\n        getFeatureStateForFreeze: function(feature) {\n        var state;\n        if (!this.saveFeatureState) {\n            state = this.NULL_FEATURE_STATE;\n        } else if (this.createdOffline(feature)) {\n            state = OpenLayers.State.INSERT;\n        } else {\n            state = feature.state;\n        }\n        return state;\n    },\n\n        \"delete\": function(features, options) {\n        if (!(OpenLayers.Util.isArray(features))) {\n            features = [features];\n        }\n\n        options = OpenLayers.Util.applyDefaults(options, this.options);\n\n        var i, len, feature;\n        for (i = 0, len = features.length; i < len; i++) {\n            feature = features[i];\n            if (this.saveFeatureState && !this.createdOffline(feature)) {\n                var toDelete = feature.clone();\n                toDelete.fid = feature.fid;\n                if (toDelete.geometry) {\n                    toDelete.geometry.destroy();\n                    toDelete.geometry = null;\n                }\n                toDelete.state = feature.state;\n                this.createOrUpdate(toDelete);\n            } else {\n                this.db.execute(\n                    \"DELETE FROM \" + this.tableName +\n                    \" WHERE fid = ?\", [feature.fid]);\n            }\n        }\n\n        var resp = new OpenLayers.Protocol.Response({\n            code: OpenLayers.Protocol.Response.SUCCESS,\n            requestType: \"delete\",\n            reqFeatures: features\n        });\n\n        if (options && options.callback) {\n            options.callback.call(options.scope, resp);\n        }\n\n        return resp;\n    },\n\n        createdOffline: function(feature) {\n        return (typeof feature.fid == \"string\" &&\n                !!(feature.fid.match(this.fidRegExp)));\n    },\n\n        commit: function(features, options) {\n        var opt, resp = [], nRequests = 0, nResponses = 0;\n\n        function callback(resp) {\n            if (++nResponses < nRequests) {\n                resp.last = false;\n            }\n            this.callUserCallback(options, resp);\n        }\n\n        var feature, toCreate = [], toUpdate = [], toDelete = [];\n        for (var i = features.length - 1; i >= 0; i--) {\n            feature = features[i];\n            switch (feature.state) {\n            case OpenLayers.State.INSERT:\n                toCreate.push(feature);\n                break;\n            case OpenLayers.State.UPDATE:\n                toUpdate.push(feature);\n                break;\n            case OpenLayers.State.DELETE:\n                toDelete.push(feature);\n                break;\n            }\n        }\n        if (toCreate.length > 0) {\n            nRequests++;\n            opt = OpenLayers.Util.applyDefaults(\n                {\"callback\": callback, \"scope\": this},\n                options.create\n            );\n            resp.push(this.create(toCreate, opt));\n        }\n        if (toUpdate.length > 0) {\n            nRequests++;\n            opt = OpenLayers.Util.applyDefaults(\n                {\"callback\": callback, \"scope\": this},\n                options.update\n            );\n            resp.push(this.update(toUpdate, opt));\n        }\n        if (toDelete.length > 0) {\n            nRequests++;\n            opt = OpenLayers.Util.applyDefaults(\n                {\"callback\": callback, \"scope\": this},\n                options[\"delete\"]\n            );\n            resp.push(this[\"delete\"](toDelete, opt));\n        }\n\n        return resp;\n    },\n\n        clear: function() {\n        this.db.execute(\"DELETE FROM \" + this.tableName);\n    },\n\n        callUserCallback: function(options, resp) {\n        var opt = options[resp.requestType];\n        if (opt && opt.callback) {\n            opt.callback.call(opt.scope, resp);\n        }\n        if (resp.last && options.callback) {\n            options.callback.call(options.scope);\n        }\n    },\n\n    CLASS_NAME: \"OpenLayers.Protocol.SQL.Gears\"\n});\n\nOpenLayers.Layer.Yahoo = OpenLayers.Class(\n  OpenLayers.Layer.EventPane, OpenLayers.Layer.FixedZoomLevels, {\n\n        MIN_ZOOM_LEVEL: 0,\n\n        MAX_ZOOM_LEVEL: 17,\n\n        RESOLUTIONS: [\n        1.40625,\n        0.703125,\n        0.3515625,\n        0.17578125,\n        0.087890625,\n        0.0439453125,\n        0.02197265625,\n        0.010986328125,\n        0.0054931640625,\n        0.00274658203125,\n        0.001373291015625,\n        0.0006866455078125,\n        0.00034332275390625,\n        0.000171661376953125,\n        0.0000858306884765625,\n        0.00004291534423828125,\n        0.00002145767211914062,\n        0.00001072883605957031\n    ],\n\n        type: null,\n\n        wrapDateLine: true,\n\n        sphericalMercator: false,\n\n        initialize: function(name, options) {\n        OpenLayers.Layer.EventPane.prototype.initialize.apply(this, arguments);\n        OpenLayers.Layer.FixedZoomLevels.prototype.initialize.apply(this,\n                                                                    arguments);\n        if(this.sphericalMercator) {\n            OpenLayers.Util.extend(this, OpenLayers.Layer.SphericalMercator);\n            this.initMercatorParameters();\n        }\n    },\n\n        loadMapObject:function() {\n        try { //do not crash!\n            var size = this.getMapObjectSizeFromOLSize(this.map.getSize());\n            this.mapObject = new YMap(this.div, this.type, size);\n            this.mapObject.disableKeyControls();\n            this.mapObject.disableDragMap();\n            if ( !this.mapObject.moveByXY ||\n                 (typeof this.mapObject.moveByXY != \"function\" ) ) {\n\n                this.dragPanMapObject = null;\n            }\n        } catch(e) {}\n    },\n\n        onMapResize: function() {\n        try {\n            var size = this.getMapObjectSizeFromOLSize(this.map.getSize());\n            this.mapObject.resizeTo(size);\n        } catch(e) {}\n    },\n\n\n        setMap: function(map) {\n        OpenLayers.Layer.EventPane.prototype.setMap.apply(this, arguments);\n\n        this.map.events.register(\"moveend\", this, this.fixYahooEventPane);\n    },\n\n        fixYahooEventPane: function() {\n        var yahooEventPane = OpenLayers.Util.getElement(\"ygddfdiv\");\n        if (yahooEventPane != null) {\n            if (yahooEventPane.parentNode != null) {\n                yahooEventPane.parentNode.removeChild(yahooEventPane);\n            }\n            this.map.events.unregister(\"moveend\", this,\n                                       this.fixYahooEventPane);\n        }\n    },\n\n        getWarningHTML:function() {\n        return OpenLayers.i18n(\n            \"getLayerWarning\", {'layerType':'Yahoo', 'layerLib':'Yahoo'}\n        );\n    },\n\n    /*                                                      */\n  /*             Translation Functions                    */\n  /*                                                      */\n  /*    The following functions translate GMaps and OL    */\n  /*     formats for Pixel, LonLat, Bounds, and Zoom      */\n  /*                                                      */\n\n        getOLZoomFromMapObjectZoom: function(moZoom) {\n        var zoom = null;\n        if (moZoom != null) {\n            zoom = OpenLayers.Layer.FixedZoomLevels.prototype.getOLZoomFromMapObjectZoom.apply(this, [moZoom]);\n            zoom = 18 - zoom;\n        }\n        return zoom;\n    },\n\n        getMapObjectZoomFromOLZoom: function(olZoom) {\n        var zoom = null;\n        if (olZoom != null) {\n            zoom = OpenLayers.Layer.FixedZoomLevels.prototype.getMapObjectZoomFromOLZoom.apply(this, [olZoom]);\n            zoom = 18 - zoom;\n        }\n        return zoom;\n    },\n\n        setMapObjectCenter: function(center, zoom) {\n        this.mapObject.drawZoomAndCenter(center, zoom);\n    },\n\n        getMapObjectCenter: function() {\n        return this.mapObject.getCenterLatLon();\n    },\n\n        dragPanMapObject: function(dX, dY) {\n        this.mapObject.moveByXY({\n            'x': -dX,\n            'y': dY\n        });\n    },\n\n        getMapObjectZoom: function() {\n        return this.mapObject.getZoomLevel();\n    },\n\n        getMapObjectLonLatFromMapObjectPixel: function(moPixel) {\n        return this.mapObject.convertXYLatLon(moPixel);\n    },\n\n        getMapObjectPixelFromMapObjectLonLat: function(moLonLat) {\n        return this.mapObject.convertLatLonXY(moLonLat);\n    },\n\n        getLongitudeFromMapObjectLonLat: function(moLonLat) {\n        return this.sphericalMercator ?\n            this.forwardMercator(moLonLat.Lon, moLonLat.Lat).lon :\n            moLonLat.Lon;\n    },\n\n        getLatitudeFromMapObjectLonLat: function(moLonLat) {\n        return this.sphericalMercator ?\n            this.forwardMercator(moLonLat.Lon, moLonLat.Lat).lat :\n            moLonLat.Lat;\n    },\n\n        getMapObjectLonLatFromLonLat: function(lon, lat) {\n        var yLatLong;\n        if(this.sphericalMercator) {\n            var lonlat = this.inverseMercator(lon, lat);\n            yLatLong = new YGeoPoint(lonlat.lat, lonlat.lon);\n        } else {\n            yLatLong = new YGeoPoint(lat, lon);\n        }\n        return yLatLong;\n    },\n\n        getXFromMapObjectPixel: function(moPixel) {\n        return moPixel.x;\n    },\n\n        getYFromMapObjectPixel: function(moPixel) {\n        return moPixel.y;\n    },\n\n        getMapObjectPixelFromXY: function(x, y) {\n        return new YCoordPoint(x, y);\n    },\n\n        getMapObjectSizeFromOLSize: function(olSize) {\n        return new YSize(olSize.w, olSize.h);\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.Yahoo\"\n});\n\nOpenLayers.Layer.GML = OpenLayers.Class(OpenLayers.Layer.Vector, {\n\n        loaded: false,\n\n        format: null,\n\n        formatOptions: null,\n\n         initialize: function(name, url, options) {\n        var newArguments = [];\n        newArguments.push(name, options);\n        OpenLayers.Layer.Vector.prototype.initialize.apply(this, newArguments);\n        this.url = url;\n    },\n\n        setVisibility: function(visibility, noEvent) {\n        OpenLayers.Layer.Vector.prototype.setVisibility.apply(this, arguments);\n        if(this.visibility && !this.loaded){\n            this.loadGML();\n        }\n    },\n\n        moveTo:function(bounds, zoomChanged, minor) {\n        OpenLayers.Layer.Vector.prototype.moveTo.apply(this, arguments);\n        if(this.visibility && !this.loaded){\n            this.loadGML();\n        }\n    },\n\n        loadGML: function() {\n        if (!this.loaded) {\n            this.events.triggerEvent(\"loadstart\");\n            OpenLayers.Request.GET({\n                url: this.url,\n                success: this.requestSuccess,\n                failure: this.requestFailure,\n                scope: this\n            });\n            this.loaded = true;\n        }\n    },\n\n        setUrl:function(url) {\n        this.url = url;\n        this.destroyFeatures();\n        this.loaded = false;\n        this.loadGML();\n    },\n\n        requestSuccess:function(request) {\n        var doc = request.responseXML;\n\n        if (!doc || !doc.documentElement) {\n            doc = request.responseText;\n        }\n\n        var options = {};\n\n        OpenLayers.Util.extend(options, this.formatOptions);\n        if (this.map && !this.projection.equals(this.map.getProjectionObject())) {\n            options.externalProjection = this.projection;\n            options.internalProjection = this.map.getProjectionObject();\n        }\n\n        var gml = this.format ? new this.format(options) : new OpenLayers.Format.GML(options);\n        this.addFeatures(gml.read(doc));\n        this.events.triggerEvent(\"loadend\");\n    },\n\n        requestFailure: function(request) {\n        OpenLayers.Console.userError('Error in loading GML file ' +  this.url);\n        this.events.triggerEvent(\"loadend\");\n    },\n\n    CLASS_NAME: \"OpenLayers.Layer.GML\"\n});\n\n\nOpenLayers.Geometry.Rectangle = OpenLayers.Class(OpenLayers.Geometry, {\n\n        x: null,\n\n        y: null,\n\n        width: null,\n\n        height: null,\n\n        initialize: function(x, y, width, height) {\n        OpenLayers.Geometry.prototype.initialize.apply(this, arguments);\n        \n        this.x = x;\n        this.y = y;\n\n        this.width = width;\n        this.height = height;\n    },\n    \n        calculateBounds: function() {\n        this.bounds = new OpenLayers.Bounds(this.x, this.y,\n                                            this.x + this.width, \n                                            this.y + this.height);\n    },\n    \n    \n        getLength: function() {\n        var length = (2 * this.width) + (2 * this.height);\n        return length;\n    },\n\n        getArea: function() {\n        var area = this.width * this.height;\n        return area;\n    },    \n\n    CLASS_NAME: \"OpenLayers.Geometry.Rectangle\"\n});\n\nOpenLayers.Renderer.NG = OpenLayers.Class(OpenLayers.Renderer.Elements, {\n\n        labelNodeType: null,\n\n    \n        updateDimensions: function(zoomChanged) {\n        var mapExtent = this.map.getExtent();\n        var renderExtent = mapExtent.scale(3);\n        this.setExtent(renderExtent, true);\n        var res = this.getResolution();\n        var div = this.rendererRoot.parentNode;\n        var layerLeft = parseFloat(div.parentNode.style.left);\n        var layerTop = parseFloat(div.parentNode.style.top);\n        div.style.left = ((renderExtent.left - mapExtent.left) / res - layerLeft) + \"px\";\n        div.style.top = ((mapExtent.top - renderExtent.top) / res - layerTop) + \"px\";\n    },\n\n        setSize: function() {\n        this.map.getExtent() && this.updateDimensions();\n    },\n\n        drawFeature: function(feature, style) {\n        if(style == null) {\n            style = feature.style;\n        }\n        if (feature.geometry) {\n            var rendered = this.drawGeometry(feature.geometry, style, feature.id);\n            if(rendered !== false && style.label) {\n                var location = feature.geometry.getCentroid();\n                this.drawText(feature.id, style, location);\n            } else {\n                this.removeText(feature.id);\n            }\n            return rendered;\n        }\n    },\n\n        drawText: function(featureId, style, location) {\n        var label;\n        if (typeof featureId !== \"string\") {\n            label = featureId;\n        } else {\n            label = this.nodeFactory(featureId + this.LABEL_ID_SUFFIX, this.labelNodeType);\n            label._featureId = featureId;\n        }\n        label._style = style;\n        label._x = location.x;\n        label._y = location.y;\n        if(style.labelXOffset || style.labelYOffset) {\n            var xOffset = isNaN(style.labelXOffset) ? 0 : style.labelXOffset;\n            var yOffset = isNaN(style.labelYOffset) ? 0 : style.labelYOffset;\n            var res = this.getResolution();\n            location.move(xOffset*res, yOffset*res);\n        }\n\n        if(label.parentNode !== this.textRoot) {\n            this.textRoot.appendChild(label);\n        }\n\n        return label;\n    },\n\n    CLASS_NAME: \"OpenLayers.Renderer.NG\"\n});\n(function() {\n    var moveTo = OpenLayers.Layer.Vector.prototype.moveTo;\n    OpenLayers.Layer.Vector.prototype.moveTo = function(bounds, zoomChanged, dragging) {\n        if (OpenLayers.Renderer.NG && this.renderer instanceof OpenLayers.Renderer.NG) {\n            OpenLayers.Layer.prototype.moveTo.apply(this, arguments);\n            dragging || this.renderer.updateDimensions(zoomChanged);\n            if (!this.drawn) {\n                this.drawn = true;\n                var feature;\n                for(var i=0, len=this.features.length; i<len; i++) {\n                    this.renderer.locked = (i !== (len - 1));\n                    feature = this.features[i];\n                    this.drawFeature(feature);\n                }\n            }\n        } else {\n            moveTo.apply(this, arguments);\n        }\n    }\n    var redraw = OpenLayers.Layer.Vector.prototype.redraw;\n    OpenLayers.Layer.Vector.prototype.redraw = function() {\n        if (OpenLayers.Renderer.NG && this.renderer instanceof OpenLayers.Renderer.NG) {\n            this.drawn = false;\n        }\n        redraw.apply(this, arguments);\n    }\n})();\n\nOpenLayers.Renderer.SVG2 = OpenLayers.Class(OpenLayers.Renderer.NG, {\n\n        xmlns: \"http://www.w3.org/2000/svg\",\n\n        xlinkns: \"http://www.w3.org/1999/xlink\",\n\n        symbolMetrics: null,\n\n        labelNodeType: \"g\",\n\n        initialize: function(containerID) {\n        if (!this.supported()) {\n            return;\n        }\n        OpenLayers.Renderer.Elements.prototype.initialize.apply(this,\n                                                                arguments);\n\n        this.symbolMetrics = {};\n    },\n\n        supported: function() {\n        var svgFeature = \"http://www.w3.org/TR/SVG11/feature#\";\n        return (document.implementation &&\n           (document.implementation.hasFeature(\"org.w3c.svg\", \"1.0\") ||\n            document.implementation.hasFeature(svgFeature + \"SVG\", \"1.1\") ||\n            document.implementation.hasFeature(svgFeature + \"BasicStructure\", \"1.1\") ));\n    },\n\n        updateDimensions: function(zoomChanged) {\n        OpenLayers.Renderer.NG.prototype.updateDimensions.apply(this, arguments);\n\n        var res = this.getResolution();\n\n        var width = this.extent.getWidth();\n        var height = this.extent.getHeight();\n\n        var extentString = [\n            this.extent.left,\n            -this.extent.top,\n            width,\n            height\n        ].join(\" \");\n        this.rendererRoot.setAttributeNS(null, \"viewBox\", extentString);\n        this.rendererRoot.setAttributeNS(null, \"width\", width / res);\n        this.rendererRoot.setAttributeNS(null, \"height\", height / res);\n\n        if (zoomChanged === true) {\n            var i, len;\n            var nodes = this.vectorRoot.childNodes;\n            for (i=0, len=nodes.length; i<len; ++i) {\n                this.setStyle(nodes[i]);\n            }\n            var textNodes = this.textRoot.childNodes;\n            var label;\n            for (i=0, len=textNodes.length; i<len; ++i) {\n                label = textNodes[i];\n                this.drawText(label, label._style,\n                    new OpenLayers.Geometry.Point(label._x, label._y)\n                );\n            }\n        }\n    },\n\n        getNodeType: function(geometry, style) {\n        var nodeType = null;\n        switch (geometry.CLASS_NAME) {\n            case \"OpenLayers.Geometry.Point\":\n                if (style.externalGraphic) {\n                    nodeType = \"image\";\n                } else if (this.isComplexSymbol(style.graphicName)) {\n                    nodeType = \"svg\";\n                } else {\n                    nodeType = \"circle\";\n                }\n                break;\n            case \"OpenLayers.Geometry.Rectangle\":\n                nodeType = \"rect\";\n                break;\n            case \"OpenLayers.Geometry.LineString\":\n                nodeType = \"polyline\";\n                break;\n            case \"OpenLayers.Geometry.LinearRing\":\n                nodeType = \"polygon\";\n                break;\n            case \"OpenLayers.Geometry.Polygon\":\n            case \"OpenLayers.Geometry.Curve\":\n                nodeType = \"path\";\n                break;\n            default:\n                break;\n        }\n        return nodeType;\n    },\n\n        setStyle: function(node, style, options) {\n        style = style  || node._style;\n        options = options || node._options;\n        var resolution = this.getResolution();\n        var r = node._radius;\n        var widthFactor = resolution;\n        if (node._geometryClass == \"OpenLayers.Geometry.Point\" && r) {\n            node.style.visibility = \"\";\n            if (style.graphic === false) {\n                node.style.visibility = \"hidden\";\n            } else if (style.externalGraphic) {\n\n                if (style.graphicTitle) {\n                    node.setAttributeNS(null, \"title\", style.graphicTitle);\n                    var titleNode = node.getElementsByTagName(\"title\");\n                    if (titleNode.length > 0) {\n                        titleNode[0].firstChild.textContent = style.graphicTitle;\n                    } else {\n                        var label = this.nodeFactory(null, \"title\");\n                        label.textContent = style.graphicTitle;\n                        node.appendChild(label);\n                    }\n                }\n                if (style.graphicWidth && style.graphicHeight) {\n                    node.setAttributeNS(null, \"preserveAspectRatio\", \"none\");\n                }\n                var width = style.graphicWidth || style.graphicHeight;\n                var height = style.graphicHeight || style.graphicWidth;\n                width = width ? width : style.pointRadius*2;\n                height = height ? height : style.pointRadius*2;\n                width *= resolution;\n                height *= resolution;\n\n                var xOffset = (style.graphicXOffset != undefined) ?\n                    style.graphicXOffset * resolution : -(0.5 * width);\n                var yOffset = (style.graphicYOffset != undefined) ?\n                    style.graphicYOffset * resolution : -(0.5 * height);\n\n                var opacity = style.graphicOpacity || style.fillOpacity;\n\n                node.setAttributeNS(null, \"x\", node._x + xOffset);\n                node.setAttributeNS(null, \"y\", node._y + yOffset);\n                node.setAttributeNS(null, \"width\", width);\n                node.setAttributeNS(null, \"height\", height);\n                node.setAttributeNS(this.xlinkns, \"href\", style.externalGraphic);\n                node.setAttributeNS(null, \"style\", \"opacity: \"+opacity);\n                node.onclick = OpenLayers.Renderer.SVG2.preventDefault;\n            } else if (this.isComplexSymbol(style.graphicName)) {\n                var offset = style.pointRadius * 3 * resolution;\n                var size = offset * 2;\n                var src = this.importSymbol(style.graphicName);\n                widthFactor = this.symbolMetrics[src.id].size * 3 / size * resolution;\n                var parent = node.parentNode;\n                var nextSibling = node.nextSibling;\n                if(parent) {\n                    parent.removeChild(node);\n                }\n                node.firstChild && node.removeChild(node.firstChild);\n                node.appendChild(src.firstChild.cloneNode(true));\n                node.setAttributeNS(null, \"viewBox\", src.getAttributeNS(null, \"viewBox\"));\n\n                node.setAttributeNS(null, \"width\", size);\n                node.setAttributeNS(null, \"height\", size);\n                node.setAttributeNS(null, \"x\", node._x - offset);\n                node.setAttributeNS(null, \"y\", node._y - offset);\n                if(nextSibling) {\n                    parent.insertBefore(node, nextSibling);\n                } else if(parent) {\n                    parent.appendChild(node);\n                }\n            } else {\n                node.setAttributeNS(null, \"r\", style.pointRadius * resolution);\n            }\n\n            var rotation = style.rotation;\n            if (rotation !== undefined || node._rotation !== undefined) {\n                node._rotation = rotation;\n                rotation |= 0;\n                if (node.nodeName !== \"svg\") {\n                    node.setAttributeNS(null, \"transform\",\n                        [\"rotate(\", rotation, node._x, node._y, \")\"].join(\" \")\n                    );\n                } else {\n                    var metrics = this.symbolMetrics[src.id];\n                    node.firstChild.setAttributeNS(null, \"transform\",\n                        [\"rotate(\", rotation, metrics.x, metrics.y, \")\"].join(\" \")\n                    );\n                }\n            }\n        }\n\n        if (options.isFilled) {\n            node.setAttributeNS(null, \"fill\", style.fillColor);\n            node.setAttributeNS(null, \"fill-opacity\", style.fillOpacity);\n        } else {\n            node.setAttributeNS(null, \"fill\", \"none\");\n        }\n\n        if (options.isStroked) {\n            node.setAttributeNS(null, \"stroke\", style.strokeColor);\n            node.setAttributeNS(null, \"stroke-opacity\", style.strokeOpacity);\n            node.setAttributeNS(null, \"stroke-width\", style.strokeWidth * widthFactor);\n            node.setAttributeNS(null, \"stroke-linecap\", style.strokeLinecap || \"round\");\n            node.setAttributeNS(null, \"stroke-linejoin\", \"round\");\n            style.strokeDashstyle && node.setAttributeNS(null,\n                \"stroke-dasharray\", this.dashStyle(style, widthFactor));\n        } else {\n            node.setAttributeNS(null, \"stroke\", \"none\");\n        }\n\n        if (style.pointerEvents) {\n            node.setAttributeNS(null, \"pointer-events\", style.pointerEvents);\n        }\n\n        if (style.cursor != null) {\n            node.setAttributeNS(null, \"cursor\", style.cursor);\n        }\n\n        return node;\n    },\n\n        dashStyle: function(style, widthFactor) {\n        var w = style.strokeWidth * widthFactor;\n        var str = style.strokeDashstyle;\n        switch (str) {\n            case 'solid':\n                return 'none';\n            case 'dot':\n                return [widthFactor, 4 * w].join();\n            case 'dash':\n                return [4 * w, 4 * w].join();\n            case 'dashdot':\n                return [4 * w, 4 * w, widthFactor, 4 * w].join();\n            case 'longdash':\n                return [8 * w, 4 * w].join();\n            case 'longdashdot':\n                return [8 * w, 4 * w, widthFactor, 4 * w].join();\n            default:\n                var parts = OpenLayers.String.trim(str).split(/\\s+/g);\n                for (var i=0, ii=parts.length; i<ii; i++) {\n                    parts[i] = parts[i] * widthFactor;\n                }\n                return parts.join();\n        }\n    },\n\n        createNode: function(type, id) {\n        var node = document.createElementNS(this.xmlns, type);\n        if (id) {\n            node.setAttributeNS(null, \"id\", id);\n        }\n        return node;\n    },\n\n        nodeTypeCompare: function(node, type) {\n        return (type == node.nodeName);\n    },\n\n        createRenderRoot: function() {\n        return this.nodeFactory(this.container.id + \"_svgRoot\", \"svg\");\n    },\n\n        createRoot: function(suffix) {\n        return this.nodeFactory(this.container.id + suffix, \"g\");\n    },\n\n        createDefs: function() {\n        var defs = this.nodeFactory(this.container.id + \"_defs\", \"defs\");\n        this.rendererRoot.appendChild(defs);\n        return defs;\n    },\n\n    \n        drawPoint: function(node, geometry) {\n        return this.drawCircle(node, geometry, 1);\n    },\n\n        drawCircle: function(node, geometry, radius) {\n        var x = geometry.x;\n        var y = -geometry.y;\n        node.setAttributeNS(null, \"cx\", x);\n        node.setAttributeNS(null, \"cy\", y);\n        node._x = x;\n        node._y = y;\n        node._radius = radius;\n        return node;\n    },\n\n        drawLineString: function(node, geometry) {\n        var path = this.getComponentsString(geometry.components);\n        node.setAttributeNS(null, \"points\", path);\n        return node;\n    },\n\n        drawLinearRing: function(node, geometry) {\n        var path = this.getComponentsString(geometry.components);\n        node.setAttributeNS(null, \"points\", path);\n        return node;\n    },\n\n        drawPolygon: function(node, geometry) {\n        var d = [];\n        var draw = true;\n        var complete = true;\n        var linearRingResult, path;\n        for (var j=0, len=geometry.components.length; j<len; j++) {\n            d.push(\"M\");\n            path = this.getComponentsString(\n                geometry.components[j].components, \" \");\n            d.push(path);\n        }\n        d.push(\"z\");\n        node.setAttributeNS(null, \"d\", d.join(\" \"));\n        node.setAttributeNS(null, \"fill-rule\", \"evenodd\");\n        return node;\n    },\n\n        drawRectangle: function(node, geometry) {\n        node.setAttributeNS(null, \"x\", geometry.x);\n        node.setAttributeNS(null, \"y\", -geometry.y);\n        node.setAttributeNS(null, \"width\", geometry.width);\n        node.setAttributeNS(null, \"height\", geometry.height);\n        return node;\n    },\n\n        drawText: function(featureId, style, location) {\n        var g = OpenLayers.Renderer.NG.prototype.drawText.apply(this, arguments);\n        var text = g.firstChild ||\n            this.nodeFactory(featureId + this.LABEL_ID_SUFFIX + \"_text\", \"text\");\n\n        var res = this.getResolution();\n        text.setAttributeNS(null, \"x\", location.x / res);\n        text.setAttributeNS(null, \"y\", - location.y / res);\n        g.setAttributeNS(null, \"transform\", \"scale(\" + res + \")\");\n\n        if (style.fontColor) {\n            text.setAttributeNS(null, \"fill\", style.fontColor);\n        }\n        if (style.fontOpacity) {\n            text.setAttributeNS(null, \"opacity\", style.fontOpacity);\n        }\n        if (style.fontFamily) {\n            text.setAttributeNS(null, \"font-family\", style.fontFamily);\n        }\n        if (style.fontSize) {\n            text.setAttributeNS(null, \"font-size\", style.fontSize);\n        }\n        if (style.fontWeight) {\n            text.setAttributeNS(null, \"font-weight\", style.fontWeight);\n        }\n        if (style.fontStyle) {\n            text.setAttributeNS(null, \"font-style\", style.fontStyle);\n        }\n        if (style.labelSelect === true) {\n            text.setAttributeNS(null, \"pointer-events\", \"visible\");\n            text._featureId = featureId;\n        } else {\n            text.setAttributeNS(null, \"pointer-events\", \"none\");\n        }\n        var align = style.labelAlign || OpenLayers.Renderer.defaultSymbolizer.labelAlign;\n        text.setAttributeNS(null, \"text-anchor\",\n            OpenLayers.Renderer.SVG2.LABEL_ALIGN[align[0]] || \"middle\");\n\n        if (OpenLayers.IS_GECKO === true) {\n            text.setAttributeNS(null, \"dominant-baseline\",\n                OpenLayers.Renderer.SVG2.LABEL_ALIGN[align[1]] || \"central\");\n        }\n\n        var labelRows = style.label.split('\\n');\n        var numRows = labelRows.length;\n        while (text.childNodes.length > numRows) {\n            text.removeChild(text.lastChild);\n        }\n        for (var i = 0; i < numRows; i++) {\n            var tspan = text.childNodes[i] ||\n                this.nodeFactory(featureId + this.LABEL_ID_SUFFIX + \"_tspan_\" + i, \"tspan\");\n            if (style.labelSelect === true) {\n                tspan._featureId = featureId;\n            }\n            if (OpenLayers.IS_GECKO === false) {\n                tspan.setAttributeNS(null, \"baseline-shift\",\n                    OpenLayers.Renderer.SVG2.LABEL_VSHIFT[align[1]] || \"-35%\");\n            }\n            tspan.setAttribute(\"x\", location.x / res);\n            if (i == 0) {\n                var vfactor = OpenLayers.Renderer.SVG2.LABEL_VFACTOR[align[1]];\n                if (vfactor == null) {\n                    vfactor = -.5;\n                }\n                tspan.setAttribute(\"dy\", (vfactor*(numRows-1)) + \"em\");\n            } else {\n                tspan.setAttribute(\"dy\", \"1em\");\n            }\n            tspan.textContent = (labelRows[i] === '') ? ' ' : labelRows[i];\n            if (!tspan.parentNode) {\n                text.appendChild(tspan);\n            }\n        }\n\n        if (!text.parentNode) {\n            g.appendChild(text);\n        }\n\n        return g;\n    },\n\n        getComponentsString: function(components, separator) {\n        var len = components.length;\n        var strings = new Array(len);\n        for (var i=0; i<len; i++) {\n            strings[i] = this.getShortString(components[i]);\n        }\n\n        return strings.join(separator || \",\");\n    },\n\n        getShortString: function(point) {\n        return point.x + \",\" + (-point.y);\n    },\n\n        importSymbol: function (graphicName)  {\n        if (!this.defs) {\n            this.defs = this.createDefs();\n        }\n        var id = this.container.id + \"-\" + graphicName;\n        var existing = document.getElementById(id);\n        if (existing != null) {\n            return existing;\n        }\n\n        var symbol = OpenLayers.Renderer.symbol[graphicName];\n        if (!symbol) {\n            throw new Error(graphicName + ' is not a valid symbol name');\n        }\n\n        var symbolNode = this.nodeFactory(id, \"symbol\");\n        var node = this.nodeFactory(null, \"polygon\");\n        symbolNode.appendChild(node);\n        var symbolExtent = new OpenLayers.Bounds(\n                                    Number.MAX_VALUE, Number.MAX_VALUE, 0, 0);\n\n        var points = [];\n        var x,y;\n        for (var i=0, len=symbol.length; i<len; i=i+2) {\n            x = symbol[i];\n            y = symbol[i+1];\n            symbolExtent.left = Math.min(symbolExtent.left, x);\n            symbolExtent.bottom = Math.min(symbolExtent.bottom, y);\n            symbolExtent.right = Math.max(symbolExtent.right, x);\n            symbolExtent.top = Math.max(symbolExtent.top, y);\n            points.push(x, \",\", y);\n        }\n\n        node.setAttributeNS(null, \"points\", points.join(\" \"));\n\n        var width = symbolExtent.getWidth();\n        var height = symbolExtent.getHeight();\n        var viewBox = [symbolExtent.left - width,\n                        symbolExtent.bottom - height, width * 3, height * 3];\n        symbolNode.setAttributeNS(null, \"viewBox\", viewBox.join(\" \"));\n        this.symbolMetrics[id] = {\n            size: Math.max(width, height),\n            x: symbolExtent.getCenterLonLat().lon,\n            y: symbolExtent.getCenterLonLat().lat\n        };\n\n        this.defs.appendChild(symbolNode);\n        return symbolNode;\n    },\n\n        getFeatureIdFromEvent: function(evt) {\n        var featureId = OpenLayers.Renderer.Elements.prototype.getFeatureIdFromEvent.apply(this, arguments);\n        if(!featureId) {\n            var target = evt.target;\n            featureId = target.parentNode && target != this.rendererRoot ?\n                target.parentNode._featureId : undefined;\n        }\n        return featureId;\n    },\n\n    CLASS_NAME: \"OpenLayers.Renderer.SVG2\"\n});\n\nOpenLayers.Renderer.SVG2.LABEL_ALIGN = {\n    \"l\": \"start\",\n    \"r\": \"end\",\n    \"b\": \"bottom\",\n    \"t\": \"hanging\"\n};\n\nOpenLayers.Renderer.SVG2.LABEL_VSHIFT = {\n    \"t\": \"-70%\",\n    \"b\": \"0\"\n};\n\nOpenLayers.Renderer.SVG2.LABEL_VFACTOR = {\n    \"t\": 0,\n    \"b\": -1\n};\n\nOpenLayers.Renderer.SVG2.preventDefault = function(e) {\n    e.preventDefault && e.preventDefault();\n};\n\nOpenLayers.Popup.AnchoredBubble = OpenLayers.Class(OpenLayers.Popup.Anchored, {\n\n        rounded: false,\n\n        initialize:function(id, lonlat, contentSize, contentHTML, anchor, closeBox,\n                        closeBoxCallback) {\n\n        this.padding = new OpenLayers.Bounds(\n            0, OpenLayers.Popup.AnchoredBubble.CORNER_SIZE,\n            0, OpenLayers.Popup.AnchoredBubble.CORNER_SIZE\n        );\n        OpenLayers.Popup.Anchored.prototype.initialize.apply(this, arguments);\n    },\n\n        draw: function(px) {\n\n        OpenLayers.Popup.Anchored.prototype.draw.apply(this, arguments);\n\n        this.setContentHTML();\n        this.setBackgroundColor();\n        this.setOpacity();\n\n        return this.div;\n    },\n\n        updateRelativePosition: function() {\n        this.setRicoCorners();\n    },\n\n        setSize:function(contentSize) {\n        OpenLayers.Popup.Anchored.prototype.setSize.apply(this, arguments);\n\n        this.setRicoCorners();\n    },\n\n        setBackgroundColor:function(color) {\n        if (color != undefined) {\n            this.backgroundColor = color;\n        }\n\n        if (this.div != null) {\n            if (this.contentDiv != null) {\n                this.div.style.background = \"transparent\";\n                OpenLayers.Rico.Corner.changeColor(this.groupDiv,\n                                                   this.backgroundColor);\n            }\n        }\n    },\n\n        setOpacity:function(opacity) {\n        OpenLayers.Popup.Anchored.prototype.setOpacity.call(this, opacity);\n\n        if (this.div != null) {\n            if (this.groupDiv != null) {\n                OpenLayers.Rico.Corner.changeOpacity(this.groupDiv,\n                                                     this.opacity);\n            }\n        }\n    },\n\n        setBorder:function(border) {\n        this.border = 0;\n    },\n\n        setRicoCorners:function() {\n\n        var corners = this.getCornersToRound(this.relativePosition);\n        var options = {corners: corners,\n                         color: this.backgroundColor,\n                       bgColor: \"transparent\",\n                         blend: false};\n\n        if (!this.rounded) {\n            OpenLayers.Rico.Corner.round(this.div, options);\n            this.rounded = true;\n        } else {\n            OpenLayers.Rico.Corner.reRound(this.groupDiv, options);\n            this.setBackgroundColor();\n            this.setOpacity();\n        }\n    },\n\n        getCornersToRound:function() {\n\n        var corners = ['tl', 'tr', 'bl', 'br'];\n        var corner = OpenLayers.Bounds.oppositeQuadrant(this.relativePosition);\n        OpenLayers.Util.removeItem(corners, corner);\n\n        return corners.join(\" \");\n    },\n\n    CLASS_NAME: \"OpenLayers.Popup.AnchoredBubble\"\n});\n\nOpenLayers.Popup.AnchoredBubble.CORNER_SIZE = 5;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/license.txt",
    "content": "Copyright 2005-2013 OpenLayers Contributors. All rights reserved. See\nauthors.txt for full list.\n\nRedistribution and use in source and binary forms, with or without modification,\nare permitted provided that the following conditions are met:\n\n 1. Redistributions of source code must retain the above copyright notice, this\nlist of conditions and the following disclaimer.\n\n 2. Redistributions in binary form must reproduce the above copyright notice,\nthis list of conditions and the following disclaimer in the documentation and/or\nother materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY OPENLAYERS CONTRIBUTORS ``AS IS'' AND ANY EXPRESS\nOR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\nSHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\nPROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\nLIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE\nOR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF\nADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\nThe views and conclusions contained in the software and documentation are those\nof the authors and should not be interpreted as representing official policies,\neither expressed or implied, of OpenLayers Contributors.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/licenses/APACHE-2.0.txt",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/licenses/BSD-LICENSE.txt",
    "content": "Redistribution and use of this software in source and binary forms, with or\nwithout modification, are permitted provided that the following conditions are\nmet:\n\n* Redistributions of source code must retain the above\n  copyright notice, this list of conditions and the\n  following disclaimer.\n\n* Redistributions in binary form must reproduce the above\n  copyright notice, this list of conditions and the\n  following disclaimer in the documentation and/or other\n  materials provided with the distribution.\n\n* Neither the name of Yahoo! Inc. nor the names of its\n  contributors may be used to endorse or promote products\n  derived from this software without specific prior\n  written permission of Yahoo! Inc.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\nANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/licenses/MIT-LICENSE.txt",
    "content": "Permission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/notes/2.12.md",
    "content": "# Major enhancements and additions\n\n## Zoom Control\n\nA simple control to add zoom in/out buttons on the map that can be entirely styled using CSS.\nSee it live in this [example](http://openlayers.org/dev/examples/zoom.html).\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/pull/291\n * https://github.com/openlayers/openlayers/pull/292\n\n## Builds\n\nThis version of OpenLayers ships with three builds:\n\n * `OpenLayers.js`\n * `OpenLayers.light.js`\n * `OpenLayers.mobile.js`\n\nSee the README.md file and the docs on docs.openlayers.org for more information.\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/pull/254\n * https://github.com/openlayers/openlayers/pull/261\n\n## style.mobile.css\n\nThe theme/default directory now includes a mobile-specific CSS file, namely\nstyle.mobile.css. The OpenLayers mobile examples use this file. To use it\nin your mobile pages use tags like this:\n\n<link rel=\"stylesheet\" href=\"openlayers/theme/default/style.mobile.css\" type=\"text/css\">\n\n(This file used to be in the examples/ directory).\n\n## Sensible projection defaults\n\nThe geographic and web mercator projections define default values for the maxExtent, and units. This simplifies the map and layer configuration.\n\nFor example, a map that used to be created with this:\n\n    map = new OpenLayers.Map({\n        div: \"map\",\n        projection: \"EPSG:900913\",\n        units: \"m\",\n        maxExtent: new OpenLayers.Bounds(\n            -20037508.34, -20037508.34, 20037508.34, 20037508.34\n        )\n    });\n\ncan now be created with this:\n\n    map = new OpenLayers.Map({\n        div: \"map\",\n        projection: \"EPSG:900913\"\n    });\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/pull/219\n\n## Tile Offline Storage\n\nWith the new `OpenLayers.Control.CacheRead` and `OpenLayers.Control.CacheWrite` controls, applications can cache tiles for offline use or for use with slow connections.\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/pull/301\n\n## Tile Animation\n\nThe displaying of tiles can now be animated, using CSS3 transitions. Transitions operate on the `opacity` property. Here's the CSS rule defined in OpenLayers' default theme:\n\n    .olLayerGrid .olTileImage {\n        -webkit-transition: opacity 0.2s linear;\n        -moz-transition: opacity 0.2s linear;\n        -o-transition: opacity 0.2s linear;\n        transition: opacity 0.2s linear;\n    }\n\nPeople can override this rule to use other transition settings. To remove tile animation entirely use:\n\n    .olLayerGrid .olTileImage {\n        -webkit-transition: none;\n        -moz-transition: none;\n        -o-transition: all 0 none;\n        transition: none;\n    }\n\nNote that by default tile animation is not enabled for single tile layers.\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/pull/127\n\nNote: Issue #511 has reported that tile animation causes flickering/blinking in\nthe iOS native browser. Forcing the browser to use hardware-accelerated\nanimations fixed the issue, but #542 has reported that it also considerably\nslows down freehand drawing on iOS. If you're experiencing this and want to\ndisable hardware-accelerated animations you can use the following rule in your\nCSS:\n\n    @media (-webkit-transform-3d) {\n        img.olTileImage {\n            -webkit-transform: none;\n        }\n    }\n\n## Tile Queue\n\nThe tiling code has been overhauled so tile loading in grid layers is now done in a queue.\nThe tile queue gives more control on the tile requests sent to the server. Pending requests for tiles that are not needed any more (e.g. after zooming or panning) are avoided, which increases performance and reduces server load.\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/pull/179\n\n## Tile Canvas\n\nImage tiles expose a `getCanvasContext` function that can be used for various\nthings, like changing the image pixels, save the image using the File API, etc.\n\nSee the [osm-grayscale\nexample](http://openlayers.org/dev/examples/osm-grayscale.html).\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/pull/160\n\n## Tile Interaction Event Improvements\n\nThe layer's `tileloaded` event now returns a reference to the loaded tile. The new `tileloaderror` event does the same, and is fired when a tile could not be loaded.\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/pull/283\n\n## Tile and Backbuffer Overhaul\n\nThe whole image tile and backbuffer code (behind `transitionEffect:resize`) has been redesigned and\nrewritten. This overhaul yields better performance and code simplifications.\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/pull/16\n\n## Continuous Zooming\n\nTile layers can now be displayed at resolutions not supported by their tiling\nservices. This works by requesting tiles at higher resolutions and stretching\nthe layer div as appropriate. With this change fractionalZoom:true will work\nfor single tile layers as well as for tiled layers.\n\nSee the [client zoom\nexample](http://openlayers.org/dev/examples/clientzoom.html).\n\nCorresponding issues/pull requests:\n\n * http://trac.osgeo.org/openlayers/ticket/3531\n * https://github.com/openlayers/openlayers/pull/5\n\n# Behavior Changes from Past Releases\n\n## MultiMap Layer Removal\n\nThe `OpenLayers.Layer.MultiMap` class has been removed entirely, as the MultiMap service was discontinued.\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/pull/328\n\n## GPX API change\n\nThe `gpxns` API property has been removed. The GPX namespace is now defined in the `namespaces` property but is not intended to be overriden.\n\nGPX also now has a basic write function.\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/pull/221\n\n## Function return values\n\nPreviously a few functions in the library displayed error messages and returned `undefined`, `null` or `false` if the parameters passed in were bad. In 2.12 these functions now just throw an error/exception. People relying on return values to know if a function call is successful may need to change their code. Here are the modified functions:\n\n * `OpenLayers.Bounds.add` throws a `TypeError` exception if `x` or `y` is null\n * `OpenLayers.LonLat.add` throws a `TypeError` exception if `lon` or `lat` is null\n * `OpenLayers.Pixel.add` throws a `TypeError` exception if `x` or `y` is null\n * `OpenLayers.Filter.Comparison.value2regex` throws an `Error` exception if `wildcard` equals to `\".\"`\n * `OpenLayers.Layer.PointTrack.addNodes` throws a `TypeError` exception if `endPoint` isn't actually a point\n * `OpenLayers.Layer.Vector.getFeatureFromEvent` throws an `Error` exception if the layer has no renderer\n\nCorresponding issues/pull requests:\n\n * http://trac.osgeo.org/openlayers/ticket/3320\n\n## Changes in formats WMTSCapabilities and SOSCapabilities\n\nThe structure of the object returned by `Format.WMTSCapabilities:read` and `Format.SOSCapabilities:read` has slightly changed.\n\nFor `WMTSCapabilities` the GET href used to be made available at `operationsMetadata.GetCapabilities.dcp.http.get`, the latter is now an array of objects with two properties: `url` and `constrains`. People using `operationsMetadata.GetCapabilities.dcp.http.get` in their applications should certainly use `operationsMetadata.GetCapabilities.dcp.http.get[0].url`.\n\nLikewise for `SOSCapabilities`.\n\nLooking at the tests is a good way to understand what the requires changes are. See [SOSCapabilities/v1_0_0.html](https://github.com/openlayers/openlayers/blob/master/tests/Format/SOSCapabilities/v1_0_0.html) and [WMTSCapabilities/v1_0_0.html](https://github.com/openlayers/openlayers/blob/master/tests/Format/WMTSCapabilities/v1_0_0.html).\n\nCorresponding issues/pull requests:\n\n * http://trac.osgeo.org/openlayers/ticket/3568\n * https://github.com/openlayers/openlayers/pull/40\n\n\n## Rico deprecation\n\nWe are deprecating the Rico classes/objects in OpenLayers. This has the following implications:\n\n`Popup.AnchoredBubble` is deprecated. Its constructor now displays a deprecation message on the console. If you want popups with rounded corners either use `Popup.FramedClould`, or use `Popup.Anchored` and round corners using the [border-radius](https://developer.mozilla.org/en/CSS/border-radius) CSS property.\n\nThe `roundedCorner` option of `Control.LayerSwitcher` is deprecated, and it now defaults to `false`. Setting it to true results in deprecation messages being output on the console. If you still want to set `roundedCorner` to `true` (you should not!) you need to make sure that the Rico/Corner.js and Rico/Color.js scripts are loaded in the page. This can be ensured by adding Rico/Corner.js in the build profile. The controls.html example demonstrates how to use `border-radius` to round corners of a layer switcher:\n\n\n    .olControlLayerSwitcher .layersDiv {\n        border-radius: 10px 0 0 10px;\n    }\n\n\nIn future releases we intend to move the Rico and `AnchoredBubble` code into deprecated.js. You really should consider stop using Rico-based functionalities in your applications.\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/pull/99\n\n## Changes in Geometry\n\nThe base `OpenLayers.Geometry` class no longer depends on `OpenLayers.Format.WKT` or `OpenLayers.Feature.Vector`.  If you want to make use of the `OpenLayers.Geometry.fromWKT` method, you must explicitly include the OpenLayers/Format/WKT.js file in your build.  \n\nWithout the WKT format included (by default), the `OpenLayers.Geometry::toString` method now returns \"[object Object].\"  Previously, it returned the Well-Known Text representation of the geometry.  To maintain the previous behavior, include the OpenLayers/Format/WKT.js file in your build.\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/pull/101\n\n## Google v3 Layer\n\nThis release fixes a problem with the clickable elements supplied by Google. `OpenLayers.Layer.Google.v3` is now compatible with the current frozen version of Google's API (3.7) and also with the current release and nightly versions (3.8 and 3.9), but be aware that Google may change these elements in their release and nightly versions at any time, and an interim fix OpenLayers release may be needed.\n\nIt's recommended that production servers always load the frozen version of Google's API, but it would help find potential problems if development pages used the latest nightly version.\n\nSee the class description in the API docs for `OpenLayers.Layer.Google.v3` for more details.\n\nGood ideas on how to improve this unsatisfactory situation welcome!\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/pull/472\n\n## OSM and Bing Layers\n\n`Layer.OSM` is now defined in its own script file, namely `OpenLayers/Layer/OSM.js`. So people using `Layer.OSM` should now include `OpenLayers/Layer/OSM.js`, as opposed to `OpenLayers/Layer/XYZ.js`, in their OpenLayers builds.\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/issues/138\n * https://github.com/openlayers/openlayers/pull/144\n\nThe `OpenLayers.Tile.Image` class now has a method to get a canvas context for processing tiles. Since both OSM and Bing set Access-Control-Allow-Origin headers for their tiles, it is possible to manipulate a canvas that these tiles were rendered to even if the tiles come from a remote origin. Especially when working with custom OSM tilesets from servers that do not send Access-Control-Allow-Origin headers, it is now necessary to configure the layer with\n\n    tileOptions: {crossOriginKeyword: null}\n\nBoth `OpenLayers.Layer.OSM` and `OpenLayers.Layer.Bing` do not have defaults for `maxExtent`, `maxResolutions` and `units` any more. This may break maps that are configured with a `maxResolution` of `156543.0339`, which was used in examples before 2.11, but is incorrect. The correct value is `156543.03390625`, but it is no longer necessary to specify a maxResolution, maxExtent and units if the correct resolution is set. See \"Projection and Spherical Mercator\" below.\n\n## Projection & SphericalMercator\n\nWhen working with Web Mercator layers (e.g. Google, Bing, OSM), it was previously necessary to configure the map or the base layer with the correct `projection`, `maxExtent`, `maxResolutions` and `units`. Now OpenLayers has defaults for WGS84 and Web Mercator in `OpenLayers.Projection.defaults`, so it is enough to provide the `projection`.\n\nOld:\n\n    new OpenLayers.Map({\n        div: \"map\",\n        projection: \"EPSG:900913\",\n        maxResolution: 156543.03390625,\n        maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),\n        units: \"m\",\n        layers: [\n            new OpenLayers.Layer.Google(\"Google Streets\"),\n            new OpenLayers.Layer.OSM(null, null, {isBaseLayer: false, opacity: 0.7})\n        ],\n        zoom: 1\n    });\n\nNew:\n\n    new OpenLayers.Map({\n        div: \"map\",\n        projection: \"EPSG:900913\",\n        layers: [\n            new OpenLayers.Layer.Google(\"Google Streets\"),\n            new OpenLayers.Layer.OSM(null, null, {isBaseLayer: false, opacity: 0.7})\n        ],\n        zoom: 1\n    });\n\nIn previous releases, coordinate transforms between EPSG:4326 and EPSG:900913 were defined in the SphericalMercator.js script.  In 2.12, these default transforms are included in the Projection.js script.  The Projection.js script is included as a dependency in builds with any layer types, so no special build configuration is necessary to get the web mercator transforms.\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/pull/219\n\nIf you were previously using the `OpenLayers.Layer.SphericalMercator.forwardMercator` or `inverseMercator` methods, you may have to explicitly include the SphericalMercator.js script in your build.  The Google layer is the only layer that depends on the SphericalMercator mixin.  If you are not using the Google layer but want to use the SphericalMercator methods listed above, you have to explicitly include the SphericalMercator.js script in your build.\n\nCorresponding issues/pull requests:\n\n* https://github.com/openlayers/openlayers/pull/153\n\n## QueryStringFilter\n\n`OpenLayers.Protocol.HTTP` no longer requires `OpenLayers.Format.QueryStringFilter`. It you need this, make sure it is included in your build config file.\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/issues/147\n * https://github.com/openlayers/openlayers/pull/148\n\n## Changes in getURLasync\n\nThe internal `OpenLayers.Layer.getURLasync` function now take a bound, a callback and a scope. The function no longer needs update the passed property but simply to return to url.\n\n## Changes when base layer configured with wrapDateLine: true\n\nVector editing across the date line works reliably now. To make this work, OpenLayers won't zoom out to resolutions where more than one world is visible any more. For maps that have base layers with wrapDateLine set to false, no zoom restrictions apply.\n\n## OpenLayers.Util.onImageLoadError no longer exists\n\nTo replace a tile that couldn't be loaded with a static image, create a css selector for the `.olImageLoadError` class (e.g. a `background-image`).\n\nFor more complex tile loading error handling, register a listener to the layer's `tileerror` event.\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/pull/283\n\n## Deprecated Components\n\nA number of properties, methods, and constructors have been marked as deprecated for multiple releases in the 2.x series.  For the 2.12 release this deprecated functionality has been moved to a separate deprecated.js file.  If you use any of the constructors or methods below, you will have to explicitly include the deprecated.js file in your build (or add it in a separate `<script>` tag after OpenLayers.js).\n\n * OpenLayers.Class.isPrototype\n * OpenLayers.Class.create\n * OpenLayers.Class.inherit\n * OpenLayers.Util.clearArray\n * OpenLayers.Util.setOpacity\n * OpenLayers.Util.safeStopPropagation\n * OpenLayers.Util.getArgs\n * OpenLayers.nullHandler\n * OpenLayers.loadURL\n * OpenLayers.parseXMLString\n * OpenLayers.Ajax.* (all methods)\n * OpenLayers.Element.hide\n * OpenLayers.Element.show\n * OpenLayers.Element.getDimensions\n * OpenLayers.Tile.prototype.getBoundsFromBaseLayer\n * OpenLayers.Control.MouseDefaults\n * OpenLayers.Control.MouseToolbar\n * OpenLayers.Layer.Grid.prototype.getGridBounds\n * OpenLayers.Format.XML.prototype.concatChildValues\n * OpenLayers.Layer.WMS.Post\n * OpenLayers.Layer.WMS.Untiled\n * OpenLayers.Layer.MapServer.Untiled\n * OpenLayers.Tile.WFS\n * OpenLayers.Feature.WFS\n * OpenLayers.Layer.WFS\n * OpenLayers.Layer.VirtualEarth\n * OpenLayers.Protocol.SQL\n * OpenLayers.Protocol.SQL.Gears\n * OpenLayers.Layer.Yahoo\n * OpenLayers.Layer.GML\n * OpenLayers.Geometry.Rectangle\n * OpenLayers.Renderer.NG\n * OpenLayers.Renderer.SVG2\n\nIn addition, OpenLayers no longer modifies any native prototypes or objects by default.  If you rely on any of the following, you'll need to include deprecated.js explicitly to get the same behavior.\n\n * String.prototype.startsWith\n * String.prototype.contains\n * String.prototype.trim\n * String.prototype.camelize\n * Function.prototype.bind\n * Function.prototype.bindAsEventListener\n * Event.stop\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/notes/2.13.md",
    "content": "# Enhancements and Additions\n\n## Dotless identifiers\n\nPreviously, objects generated by the library were given id properties with values that contained dots (e.g. \"OpenLayers.Control.Navigation_2\").  These same identifiers are also used for DOM elements in some case.  Though uncommon, a developer may want to access these elements with a CSS selector.  To facilitate this, we now always generate ids with underscore instead of dot.\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/pull/416\n\n## Better support for analog scroll wheel\n\nRemoved rounding of zoom level for maps with fractionalZoom == true. So users with an OS and interface device with analog scroll support will now get smooth zooming.\n\nCorresponding issues/pull requests:\n\n * https://github.com/openlayers/openlayers/pull/483\n \n## Google v3 Layer\n\nThis release changes the way Google layers are integrated with OpenLayers. With this change, OpenLayers should be less fragile to changes of the GMaps API version, because no DOM elements inside the Google container need to be modified by OpenLayers any more.\n\nApplication developers should be aware that the Google Map of an `OpenLayers.Layer.Google.v3` instance is no longer added to the map's `viewPortDiv`. Instead, the `viewPortDiv` is added as Google Maps control to the Google map. This means that when switching base layers, the whole DOM structure below the map's `div` changes.\n\nCorresponding issues/pull requests:\n\n* https://github.com/openlayers/openlayers/pull/484\n\n## Bing Layer\n\nAll requests to the Bing Maps service are now sent using the same protocol as the OpenLayers application using the Bing layer. For file:/// URIs, the http\nprotocol is used. A new config option `protocol` has been introduced to set the protocol to use for requests to the Bing Maps service. 'https:' should work fine, but the availability of tiles and attribution logo with the https protocol is not guaranteed. If in doubt, set `protocol` to 'http:'.\n\nCorresponding issues/pull requests:\n\n* http://github.com/openlayers/openlayers/pull/700\n\n## New Map and Vector Layer Events for Feature Interaction\n\nThe featureclick events extension (`lib/Events/featureclick.js`) provides four new events (\"featureclick\", \"nofeatureclick\", \"featureover\", \"featureout\") that can be used as an alternative to the Feature handler or the\nSelectFeature control. It works with multiple layers out of the box and can detect hits on multiple features (except when using the Canvas renderer). See `examples/feature-events.html` for an implementation example.\n\n# Behavior Changes from Past Releases\n\n## Control.DragPan: Kinetic by default\n\nThe `enableKinetic` property for the DragPan control has been changed to true by default.  This will enable kinetic panning only if the `OpenLayers/Kinetic.js` file is included in your build.\n\n## Control.ModifyFeature: no more built-in SelectFeature control\n\nThe ModifyFeature control is now much leaner, making it more reliable when combined with other controls. The most noticeable change is that it has no\n`selectControl` member any more. Users who previously relied on this built-in SelectFeature control will now have to create both a SelectFeature and a ModifyFeature control and configure the ModifyFeature control with `standalone: true`. To get features selected, call the `selectFeature` method e.g. from a `featureselected` listener on the vector layer. Note that other than in the old implementation, calling `selectFeature` on an already selected feature will not do anything.\n\n## Format.GPX: No more prefixes\n\nNo `gpx:` prefix is added in the XML tags anymore when writing GPX from `OpenLayers` features. It seems like it is not supported by most of the tools that are able to read GPX.\n\n## Different return type for OpenLayers.Format.WMSDescribeLayer\n\nThe return type of WMSDescribeLayer format's `read` method was different from the one of the VersionedOGC format superclass. So it was changed from an array to an object with a layerDescriptions property that holds the array. For backwards compatibility, the object still has a length property and 0, ..., n properties with the previous array values.\n\n## Moved errorProperty from the base class to the parser in Format.OWSCommon\n\nThis was necessary for WCS support because there are no properties in common between versions 1.0.0 and 1.1.0 that were appropriate for checking.  The only existing code that this affected was WFS parsing.\n\n## Layer.Grid: Tile queue and tileLoadingDelay changes\n\nWith the introduction of OpenLayers.TileManager, tile queueing has become optional but is enabled by default. To not use a tile queue in 2.13, the map needs to be configured with tileManager: null, e.g.:\n\n    var map = new OpenLayers.Map('map', {\n        tileManager: null\n    });\n\nThe tile queue works differently than before: it no longer loads one tile at a time. Instead, it waits after a zoom or pan, and loads all tiles after a delay. This has the same effect as previously (less burden on the server), but makes use of the browser's request management. The delay can be configured separately for zooming and moving the map, using the `zoomDelay` (default: 200 ms) and `moveDelay` (default: 100 ms) config options of the TileManager. If you want to have the map be associated with a TileManager with non-default options, supply the options instead or create your own TileManager instance and supply it to the Map constructor.\n\nThe `moveDelay` is the replacement for the `tileLoadingDelay` layer config option, which has been removed. There is no magic any more to only use the delay when requestAnimationFrame is not natively available.\n\n## Layer.Grid: Resize transitions by default\n\nThe `transitionEffect` property for grid layers has been changed to \"resize\" by default.  This allows smooth transitions with animated zooming (also enabled by default).  If resize transitions are not wanted for individual layers, set `transitionEffect` to `null`.\n\n## Map: Animated zooming and GPU support\n\nOpenLayers now has animated zooming, which is enabled by default. To turn it off, configure the map with `zoomMethod: null`.\n\nAs methods like `zoomTo` now behave asynchronous when animated, make sure to register a listener like `zoomend` if you want to safely rely on methods like `getZoom`.\n\nTo make the zoom animation smooth, GPU support is active by default for rendering tiles. This may interfere with UI widgets that overlay the map. In this case, it may be necessary to turn GPU support off, which is done with the following css declaration:\n\n    img.olTileImage {\n        -webkit-transform: inherit;\n        -moz-transform: inherit;\n        -o-transform: inherit;\n        -ms-transform: inherit;\n        transform: inherit;\n        -webkit-backface-visibility: inherit;\n        -moz-backface-visibility: inherit;\n        -ms-backface-visibility: inherit;\n        backface-visibility: inherit;\n        -webkit-perspective: inherit;\n        -moz-perspective: inherit;\n        -ms-perspective: inherit;\n        perspective: inherit;\n    }\n\n## Map property fallThrough defaults to false\n\nThe behaviour controlled by map property fallThrough wasn't consistent (some events were swallowed even with fallThrough set to true) and changes have been made to fix that. Defaulting fallThrough to false after this change is sensible in most situations and will probably be what most applications expect, but if you previously relied on pointer or keyboard events being passed through you will probably want to set fallThrough to true.\n\nBehavioural change was made in this commit:\n\n* https://github.com/openlayers/openlayers/commit/a6119f6a7528e013b922fd0d997a07df13f6bd6e\n\n## window.$ is no longer an alias for OpenLayers.Util.getElement\n \nWe do no longer create a global variable `$` when such a symbol isn't already\ndefined. Previous versions of OpenLayers would define `$` to be an alias for \n`OpenLayers.Util.getElement`. If your application requires `window.$` to be \ndefined in such a way you can either\n \n* include deprecated.js in your custom build or as additional ressource in your\n  HTML-file\n* or you do the aliasing in your application code yourself:\n\n    `window.$ = OpenLayers.Util.getElement;`\n\nCorresponding issue/pull requests:\n\n* https://github.com/openlayers/openlayers/pull/423\n\n# New Options for Build Script\n\n* add the contents of a file as a comment at the front of the build, for example, the output of 'git describe --tags' could be saved as a file and then included\n* create build file as an AMD module\n\nrun 'build.py -h' for more details\n\nCorresponding issue/pull requests:\n\n* https://github.com/openlayers/openlayers/pull/528\n\n## Deprecated Components\nA number of properties, methods, and constructors have been marked as\ndeprecated for multiple releases in the 2.x series.\nFor the 2.13 release this deprecated functionality has been moved to a\nseparate deprecated.js file.  If you use any of the constructors or\nmethods below, you will have to explicitly include the deprecated.js\nfile in your build (or add it in a separate `<script>` tag after\nOpenLayers.js).\n\n * OpenLayers.Layer.Popup.AnchoredBubble\n\nBecause the Rico library is now only used by deprecated components, the\nfiles have been removed from the debug loader in lib/OpenLayers.js;\nthe files have now to be explicitly loaded in a script tag.\n\n## LayerSwitcher rounded corner removal\n\nThe deprecated `roundedCorner` and `roundedCornerColor` options have\nbeen removed from the `OpenLayers.Control.LayerSwitcher` control. Use\nCSS3's border-radius instead.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/notes/2.14.md",
    "content": "# Changes in Behavior\n\n## Content Security Policy\n\nTo support running OpenLayers in places where [Content Security Policy](http://en.wikipedia.org/wiki/Content_Security_Policy) restrictions are in place (e.g. a browser extension), changes were made to the `OpenLayers.Symbolizer.prototype.clone` and `OpenLayers.Geometry.Collection.prototype.clone` methods.  These methods previously used `eval` to create clones of the same type.  They now instead use a new `OpenLayers.Util.getConstructor` method to get the appropriate constructor from an object's `CLASS_NAME` property.  If your application extends OpenLayers types and you provide a `CLASS_NAME` outside the OpenLayers namespace, the `clone` methods will work unless you load your application script in a closure (e.g. an immediately-invoked function expression).  In this case, you should override `OpenLayers.Util.getConstructor` to get your constructor from the `CLASS_NAME` property.\n\n## GMaps v2 deprecation\n\nOn Nov 19th 2013 Google deprecated GMaps version 2. This causes effects as can be seen here: http://www.flickr.com/photos/vtcraghead/10963760753/\n\nMore info on: http://googlegeodevelopers.blogspot.nl/2013/04/an-update-on-javascript-maps-api-v2.html\n\n`OpenLayers.Layer.Google` now uses v3 by default. v2 has been removed from the library. Please note that the layer types are different between v2 and v3, so if you were using e.g. `type: G_SATELLITE_MAP` you will now need to use `type: google.maps.MapTypeId.SATELLITE` instead. Also make sure you include the v3 version of the GMaps library, e.g.:\n\n`<script src=\"http://maps.google.com/maps/api/js?v=3&amp;sensor=false\"></script>`\n\n## More options in OpenLayers.Projection.defaults\n\nIn addition to `maxExtent`, `units` and `xy`, projection defaults now include\na `worldExtent` option. This is the extent of the world in geographic coordinates. For most projections, `[-180, -90, 180, 90]` will make sense. But for polar projections, it is recommended to use a world extent that excludes the invisible hemisphere. So for Northern polar projections, `[-180, 0, 180, 90]` would be a good setting.\n\n## OpenLayers.Control.Graticule rewrite\n\n* The Graticule control has a `numPoints` option, which is now deprecated. The graticule lines are optimized with adaptive quantization instead.\n* The Graticul control now uses the projection specific maxExtent and worldExtent settings from `OpenLayers.Projection.defaults`. Make sure to create an `OpenLayers.Projection.defaults` entry for your projection when using a Graticule control.\n* The control's layer (`gratLayer`) now prefers the Canvas renderer. This avoids coordinate range issues with the SVG renderer.\n* Previously, meridians were only labelled at the bottom, and parallels at the right border of the map. To better support polar projections, meridians are now also labelled at the left border, and parallels at the top border, if they do not have an intersection point with the bottom or right border.\n* To avoid maps with missing or short grid lines, make sure you do not use a graticule when working with a projection outside of its validity extent or recommended viewing area.\n* To support date line wrapping, make sure you adjust the min and max longitude in the `worldExtent` setting for your projection in OpenLayers.Projection.defaults. For EPSG:4326, set it to `[-360, -90, 360, 90]`. By using -360 and 360 instead of -180 and 180, the longitudinal grid lines will always connect at the date line.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/readme.md",
    "content": "# OpenLayers 2\n\nCopyright (c) 2005-2014 OpenLayers Contributors. See authors.txt for\nmore details.\n\nOpenLayers is a JavaScript library for building map applications\non the web. OpenLayers is made available under a BSD-license.\nPlease see license.txt in this distribution for more details.\n\n## Getting OpenLayers\n\nOpenLayers lives at http://www.openlayers.org/two/.  Find details on downloading stable releases or the development version the [development site](http://trac.osgeo.org/openlayers/wiki/HowToDownload).\n\n## Installing OpenLayers\n\nYou can use OpenLayers as-is by copying build/OpenLayers.js and the\nentire theme/ and img/ directories up to your webserver and putting them \nin the same directory. The files can be in subdirectories on your website, \nor right in the root of the site, as in these examples. \nTo include the OpenLayers library in your web page from the root of the site, use:\n\n    <script type=\"text/javascript\" src=\"/OpenLayers.js\" />\n\nAs an example, using bash (with the release files in ~/openlayers):\n\n    $ cd /var/www/html\n    $ cp ~/openlayers/OpenLayers.js ./\n    $ cp -R ~/openlayers/theme ./\n    $ cp -R ~/openlayers/img ./\n\nIf you want to use the multiple-file version of OpenLayers (for, say,\ndebugging or development purposes), copy the lib/ directory up to your\nwebserver in the same directory you put the img/ folder. Then add\nthe following to your web page instead:\n\n    <script type=\"text/javascript\" src=\"/lib/OpenLayers.js\" />\n\nAs an example, using bash (with the release files in ~/openlayers):\n\n    $ cd /var/www/html\n    $ cp -R ~/openlayers/lib ./\n    $ cp -R ~/openlayers/theme ./\n    $ cp -R ~/openlayers/img ./\n\n## Alternate OpenLayers Versions in this Release\n\nThe following versions of OpenLayers single file builds are included in this release \nand can be used in place of OpenLayers.js in any of the above instructions:\n\n1. OpenLayers.js - full build --> Includes everything except the alternate language\n    translations and deprecated classes.\n2. OpenLayers.mobile.js - a mobile focused build --> Includes a subset of the OpenLayers \n    library to serve common mobile web app use cases. This build provides access to \n    OpenStreetMap, Bing, WMS, WFS and vector layers; touch optimized controls; geolocation;\n    vector editing and interaction tools. The examples tagged ``mobile`` can use this build.\n3. OpenLayers.light.js - a simple use case focused build --> Includes a subset of the\n    OpenLayers library to serve the basic use case of displaying points and polygons\n    on a map. This build provides access to OpenStreetMap, Bing, Google, WMS, and \n    vector layers; basic map controls; and vector interaction tools. The examples\n    tagged ``light`` can use this build.\n    \n## Using OpenLayers in Your Own Website\n\nThe [examples directory](http://openlayers.org/dev/examples/) is full of useful examples.\n\nDocumentation is available at http://trac.osgeo.org/openlayers/wiki/Documentation.\nYou can generate the API documentation with http://www.naturaldocs.org/\nAs an example, using bash (with the release files in ~/openlayers):\n\n    $ cd ~/openlayers/\n    $ /path/to/NaturalDocs -i lib/ -o HTML doc/ -p doc_config/ -s Default OL\n\nInformation on changes in the API is available in release notes found in the notes folder.\n\n## Contributing to OpenLayers\n\nPlease join the email lists at http://trac.osgeo.org/openlayers/wiki/MailingLists\nPatches are welcome!\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Animation.html",
    "content": "<!DOCTYPE html>\n<html>\n    <head>\n        <title>Animation.js Tests</title>\n        <script>\n\n        // dependencies for tests\n        var OpenLayers = [\n            \"OpenLayers/Util/vendorPrefix.js\",\n            \"OpenLayers/Animation.js\"\n        ];\n\n        </script>\n        <script src=\"OLLoader.js\"></script>\n\n        <script>\n                \n        function test_all(t) {\n            t.plan(8);\n            t.ok(OpenLayers.Animation.isNative !== undefined, \"isNative is set.\");\n            \n            function doIt(win) {\n                win.requestFrame(t);\n                win.start(t);\n                win.startDuration(t);\n                win.stop(t);\n            }\n            \n            // Test in an extra window in Firefox, and directly in other browsers.\n            // This is needed because requestAnimationFrame does not work\n            // correctly in Firefox in a hidden IFrame.\n            if (window.mozRequestAnimationFrame) {\n                t.open_window(\"Animation.html\", doIt);\n            } else {\n                doIt(window);\n            }\n        }\n\n        function requestFrame(t) {\n\n            t.eq(typeof OpenLayers.Animation.requestFrame, \"function\", \"requestFrame is a function\");\n\n            var calls = 0;\n            OpenLayers.Animation.requestFrame(function() {\n                ++calls;\n            });\n            t.delay_call(0.1, function() {\n                t.ok(calls > 0, \"callback called: \" + calls);\n            });\n        }\n\n        function start(t) {\n\n            var calls = 0;\n            var id = OpenLayers.Animation.start(function() {\n                ++calls;\n            });\n            t.delay_call(0.1, function() {\n                t.ok(calls > 1, \"looped: \" + calls);\n                OpenLayers.Animation.stop(id);\n            });\n        }\n\n        function startDuration(t) {\n\n            var calls = 0;\n            var id = OpenLayers.Animation.start(function() {\n                ++calls;\n            }, 100);\n            var first;\n            t.delay_call(0.2, function() {\n                first = calls;\n                t.ok(calls > 1, \"looped: \" + calls);\n            });\n            t.delay_call(0.3, function() {\n                t.eq(calls, first, \"not being called any more\");\n            });\n        }\n\n        function stop(t) {\n\n            var calls = 0;\n            var id = OpenLayers.Animation.start(function() {\n                ++calls;\n            });\n            var first;\n            t.delay_call(0.2, function() {\n                first = calls;\n                t.ok(calls > 1, \"looped: \" + calls);\n                OpenLayers.Animation.stop(id);\n            });\n            t.delay_call(0.3, function() {\n                t.eq(calls, first, \"not being called any more\");\n            });\n        }\n        </script>"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/BaseTypes/Bounds.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var bounds;\n    function test_Bounds_constructor (t) {\n        t.plan( 26 );\n\n        bounds = new OpenLayers.Bounds();\n        t.ok( bounds instanceof OpenLayers.Bounds, \"new OpenLayers.Bounds returns Bounds object\" );\n        t.eq( bounds.CLASS_NAME, \"OpenLayers.Bounds\", \"bounds.CLASS_NAME is set correctly\" );\n        t.eq( bounds.left, null, \"bounds.left is initialized to null\" );\n        t.eq( bounds.bottom, null, \"bounds.bottom is initialized to null\" );\n        t.eq( bounds.right, null, \"bounds.right is initialized to null\" );\n        t.eq( bounds.top, null, \"bounds.top is initialized to null\" );\n\n\n        bounds = new OpenLayers.Bounds(0,2,10,4);\n        t.ok( bounds instanceof OpenLayers.Bounds, \"new OpenLayers.Bounds returns Bounds object\" );\n        t.eq( bounds.CLASS_NAME, \"OpenLayers.Bounds\", \"bounds.CLASS_NAME is set correctly\" );\n        t.eq( bounds.left, 0, \"bounds.left is set correctly\" );\n        t.eq( bounds.bottom, 2, \"bounds.bottom is set correctly\" );\n        t.eq( bounds.right, 10, \"bounds.right is set correctly\" );\n        t.eq( bounds.top, 4, \"bounds.top is set correctly\" );\n        t.eq( bounds.getWidth(), 10, \"bounds.getWidth() returns correct value\" );\n        t.eq( bounds.getHeight(), 2, \"bounds.getHeight() returns correct value\" );\n\n        var sz = bounds.getSize();\n        var size = new OpenLayers.Size(10,2);\n        t.ok(sz.equals(size),\"bounds.getSize() has correct value\" );\n\n        var center = new OpenLayers.Pixel(5,3);\n        var boundsCenter = bounds.getCenterPixel();\n        t.ok( boundsCenter.equals(center), \"bounds.getCenterLonLat() has correct value\" );\n\n        var center = new OpenLayers.LonLat(5,3);\n        var boundsCenter = bounds.getCenterLonLat();\n        t.ok( boundsCenter.equals(center), \"bounds.getCenterLonLat() has correct value\" );\n\n        // This is an actual use case with Mercator projection at global scale\n        bounds = new OpenLayers.Bounds(-40075016.67999999,-20037508.339999992,\n                                        40075016.67999999,20037508.339999992);\n        t.eq( bounds.left, -40075016.68, \"bounds.left adjusted for floating precision\");\n        t.eq( bounds.bottom, -20037508.34, \"bounds.bottom adjusted for floating precision\");\n        t.eq( bounds.right, 40075016.68, \"bounds.right adjusted for floating precision\");\n        t.eq( bounds.top, 20037508.34, \"bounds.top adjusted for floating precision\");\n\n        // allow construction from a single arg\n        bounds = new OpenLayers.Bounds([-180, -90, 180, 90]);\n        t.ok(bounds instanceof OpenLayers.Bounds, \"(array) correct instance\");\n        t.eq(bounds.left, -180, \"(array) left\");\n        t.eq(bounds.bottom, -90, \"(array) bottom\");\n        t.eq(bounds.right, 180, \"(array) right\");\n        t.eq(bounds.top, 90, \"(array) top\");\n\n    }\n\n    function test_Bounds_constructorFromStrings(t) {\n        t.plan( 6 );\n        bounds = new OpenLayers.Bounds(\"0\",\"2\",\"10\",\"4\");\n        t.ok( bounds instanceof OpenLayers.Bounds, \"new OpenLayers.Bounds returns Bounds object\" );\n        t.eq( bounds.CLASS_NAME, \"OpenLayers.Bounds\", \"bounds.CLASS_NAME is set correctly\" );\n        t.eq( bounds.left, 0, \"bounds.left is set correctly\" );\n        t.eq( bounds.bottom, 2, \"bounds.bottom is set correctly\" );\n        t.eq( bounds.right, 10, \"bounds.right is set correctly\" );\n        t.eq( bounds.top, 4, \"bounds.top is set correctly\" );\n\n    }\n\n    function test_Bounds_toBBOX(t) {\n        t.plan( 5 );\n        bounds = new OpenLayers.Bounds(1,2,3,4);\n        t.eq( bounds.toBBOX(), \"1,2,3,4\", \"toBBOX() returns correct value.\" );\n        bounds = new OpenLayers.Bounds(1.00000001,2,3,4);\n        t.eq( bounds.toBBOX(), \"1,2,3,4\", \"toBBOX() rounds off small differences.\" );\n        bounds = new OpenLayers.Bounds(1.00000001,2.5,3,4);\n        t.eq( bounds.toBBOX(), \"1,2.5,3,4\", \"toBBOX() returns correct value. for a half number\" );\n        bounds = new OpenLayers.Bounds(1,2.5555555,3,4);\n        t.eq( bounds.toBBOX(), \"1,2.555556,3,4\", \"toBBOX() rounds to correct value.\" );\n        bounds = new OpenLayers.Bounds(1,2.5555555,3,4);\n        t.eq( bounds.toBBOX(1), \"1,2.6,3,4\", \"toBBOX() rounds to correct value with power provided.\" );\n        bounds = new OpenLayers.Bounds(1,2.5555555,3,4);\n    }\n\n    function test_Bounds_toString(t) {\n        t.plan( 1 );\n        bounds = new OpenLayers.Bounds(1,2,3,4);\n        t.eq( bounds.toString(), \"1,2,3,4\", \"toString() returns correct value.\" );\n    }\n    function test_Bounds_toArray(t) {\n        t.plan( 1 );\n        bounds = new OpenLayers.Bounds(1,2,3,4);\n        t.eq( bounds.toArray(), [1,2,3,4], \"toArray() returns correct value.\" );\n    }\n\n    function test_Bounds_toGeometry(t) {\n        t.plan(7);\n        var minx = Math.random();\n        var miny = Math.random();\n        var maxx = Math.random();\n        var maxy = Math.random();\n        var bounds = new OpenLayers.Bounds(minx, miny, maxx, maxy);\n        var poly = bounds.toGeometry();\n        t.eq(poly.CLASS_NAME, \"OpenLayers.Geometry.Polygon\",\n             \"polygon instance created\");\n        t.eq(poly.components.length, 1,\n             \"polygon with one ring created\");\n        var ring = poly.components[0];\n        t.eq(ring.components.length, 5,\n             \"four sided polygon created\");\n        t.eq(ring.components[0].x, OpenLayers.Util.toFloat(minx),\n             \"bounds left preserved\");\n        t.eq(ring.components[0].y, OpenLayers.Util.toFloat(miny),\n             \"bounds bottom preserved\");\n        t.eq(ring.components[2].x, OpenLayers.Util.toFloat(maxx),\n             \"bounds left preserved\");\n        t.eq(ring.components[2].y, OpenLayers.Util.toFloat(maxy),\n             \"bounds bottom preserved\");\n    }\n\n    function test_Bounds_contains(t) {\n        t.plan( 6 );\n        bounds = new OpenLayers.Bounds(10,10,40,40);\n        t.eq( bounds.contains(20,20), true, \"bounds(10,10,40,40) correctly contains LonLat(20,20)\" );\n        t.eq( bounds.contains(0,0), false, \"bounds(10,10,40,40) correctly does not contain LonLat(0,0)\" );\n        t.eq( bounds.contains(40,40), true, \"bounds(10,10,40,40) correctly contains LonLat(40,40) with inclusive set to true\" );\n        t.eq( bounds.contains(40,40, false), false, \"bounds(10,10,40,40) correctly does not contain LonLat(40,40) with inclusive set to false\" );\n\n        var px = new OpenLayers.Pixel(15,30);\n        t.eq( bounds.containsPixel(px), bounds.contains(px.x, px.y), \"containsPixel works\");\n\n        var ll = new OpenLayers.LonLat(15,30);\n        t.eq( bounds.containsLonLat(ll), bounds.contains(ll.lon, ll.lat), \"containsLonLat works\");\n\n    }\n\n    function test_containsLonLat_wraped(t) {\n\n        var worldBounds = new OpenLayers.Bounds(-180, -90, 180, 90);\n\n        var cases = [{\n            ll: [0, 0], bbox: [-10, -10, 10, 10], contained: true\n        }, {\n            ll: [20, 0], bbox: [-10, -10, 10, 10], contained: false\n        }, {\n            ll: [360, 0], bbox: [-10, -10, 10, 10], contained: true\n        }, {\n            ll: [380, 0], bbox: [-10, -10, 10, 10], contained: false\n        }, {\n            ll: [725, 5], bbox: [-10, -10, 10, 10], contained: true\n        }, {\n            ll: [-355, -5], bbox: [-10, -10, 10, 10], contained: true\n        }, {\n            ll: [-715, 5], bbox: [-10, -10, 10, 10], contained: true\n        }, {\n            ll: [-735, 5], bbox: [-10, -10, 10, 10], contained: false\n        }, {\n            ll: [-180 * 50, 5], bbox: [-10, -10, 10, 10], contained: true\n        }];\n\n        var len = cases.length;\n        t.plan(len);\n\n        var c, bounds, loc;\n        for (var i=0; i<len; ++i) {\n            c = cases[i];\n            loc = new OpenLayers.LonLat(c.ll[0], c.ll[1]);\n            bounds = new OpenLayers.Bounds.fromArray(c.bbox);\n            t.eq(bounds.containsLonLat(loc, {worldBounds: worldBounds}), c.contained, \"case \" + i);\n        }\n\n    }\n\n    function test_Bounds_fromString(t) {\n       t.plan( 12 );\n       bounds = OpenLayers.Bounds.fromString(\"1,2,3,4\");\n       t.ok( bounds instanceof OpenLayers.Bounds, \"new OpenLayers.Bounds returns Bounds object\" );\n       t.eq( bounds.left, 1, \"bounds.left is set correctly\" );\n       t.eq( bounds.bottom, 2, \"bounds.bottom is set correctly\" );\n       t.eq( bounds.right, 3, \"bounds.right is set correctly\" );\n       t.eq( bounds.top, 4, \"bounds.top is set correctly\" );\n\n       // reverse axis order\n       var reverseBbox = bounds.toBBOX(null, true);\n       t.eq(reverseBbox, \"2,1,4,3\", \"toBBOX with reverseAxisOrder set to true works as expected\");\n       var boundsFromReverse = OpenLayers.Bounds.fromString(reverseBbox, true);\n       t.ok(bounds.equals(boundsFromReverse), \"Bounds created from string with reverseAxisOrder are correct\");\n\n       bounds = OpenLayers.Bounds.fromString(\"1.1,2.2,3.3,4.4\");\n       t.ok( bounds instanceof OpenLayers.Bounds, \"new OpenLayers.Bounds returns Bounds object\" );\n       t.eq( bounds.left, 1.1, \"bounds.left is set correctly\" );\n       t.eq( bounds.bottom, 2.2, \"bounds.bottom is set correctly\" );\n       t.eq( bounds.right, 3.3, \"bounds.right is set correctly\" );\n       t.eq( bounds.top, 4.4, \"bounds.top is set correctly\" );\n    }\n\n    function test_Bounds_getSize(t) {\n        t.plan( 1 );\n        var bounds = new OpenLayers.Bounds(0,10,100,120);\n\n        t.ok( bounds.getSize().equals(new OpenLayers.Size(100, 110)), \"getCenterPixel() works correctly\");\n    }\n\n    function test_Bounds_clone(t) {\n       t.plan( 6 );\n       var oldBounds = new OpenLayers.Bounds(1,2,3,4);\n       var bounds = oldBounds.clone();\n       t.ok( bounds instanceof OpenLayers.Bounds, \"clone returns new OpenLayers.Bounds object\" );\n       t.eq( bounds.left, 1, \"bounds.left is set correctly\" );\n       t.eq( bounds.bottom, 2, \"bounds.bottom is set correctly\" );\n       t.eq( bounds.right, 3, \"bounds.right is set correctly\" );\n       t.eq( bounds.top, 4, \"bounds.top is set correctly\" );\n\n       oldBounds.left = 100;\n       t.eq( bounds.left, 1, \"changing olBounds.left does not change bounds.left\" );\n    }\n\n    function test_Bounds_intersectsBounds(t) {\n       t.plan(21);\n\n       var aBounds = new OpenLayers.Bounds(-180, -90, 180, 90);\n\n       //inside\n       var bBounds = new OpenLayers.Bounds(-20, -10, 20, 10);\n       var cBounds = new OpenLayers.Bounds(-181,-90,180,90);\n       t.eq( aBounds.intersectsBounds(bBounds),        true, \"(\" + aBounds.toBBOX() + \") correctly intersects (\" + bBounds.toBBOX() + \")\" );\n       t.eq( aBounds.intersectsBounds(bBounds, true),  true, \"(\" + aBounds.toBBOX() + \") correctly intersects (\" + bBounds.toBBOX() + \"), inclusive is true\" );\n       t.eq( aBounds.intersectsBounds(bBounds, false), true, \"(\" + aBounds.toBBOX() + \") correctly intersects (\" + bBounds.toBBOX() + \"), inclusive is false\" );\n       t.eq( aBounds.intersectsBounds(cBounds, false), true, \"aBounds with cBounds adjusted one degree left passes intersect bounds. (3 sides match, 1 side different).\" );\n       t.eq( cBounds.intersectsBounds(aBounds, false), true, \"cBounds with aBounds adjusted one degree left passes intersect bounds. (3 sides match, 1 side different).\" );\n\n       //outside\n       bBounds = new OpenLayers.Bounds(-181, -91, 181, 91);\n       t.eq( aBounds.intersectsBounds(bBounds),        true, \"(\" + aBounds.toBBOX() + \") correctly intersects (\" + bBounds.toBBOX() + \")\" );\n       t.eq( aBounds.intersectsBounds(bBounds, true),  true, \"(\" + aBounds.toBBOX() + \") correctly intersects (\" + bBounds.toBBOX() + \"), inclusive is true\" );\n       t.eq( aBounds.intersectsBounds(bBounds, false), true, \"(\" + aBounds.toBBOX() + \") correctly intersects (\" + bBounds.toBBOX() + \"), inclusive is false\" );\n\n       //total intersect\n       bBounds = new OpenLayers.Bounds(-185, -100, 20, 50);\n       t.eq( aBounds.intersectsBounds(bBounds),        true, \"(\" + aBounds.toBBOX() + \") correctly intersects (\" + bBounds.toBBOX() + \")\" );\n       t.eq( aBounds.intersectsBounds(bBounds, true),  true, \"(\" + aBounds.toBBOX() + \") correctly intersects (\" + bBounds.toBBOX() + \"), inclusive is true\" );\n       t.eq( aBounds.intersectsBounds(bBounds, false), true, \"(\" + aBounds.toBBOX() + \") correctly intersects (\" + bBounds.toBBOX() + \"), inclusive is false\" );\n\n       //border intersect\n       bBounds = new OpenLayers.Bounds(-360, -180, -180, -90);\n       t.eq( aBounds.intersectsBounds(bBounds),        true, \"(\" + aBounds.toBBOX() + \") correctly intersects (\" + bBounds.toBBOX() + \")\" );\n       t.eq( aBounds.intersectsBounds(bBounds, true),  true, \"(\" + aBounds.toBBOX() + \") correctly intersects (\" + bBounds.toBBOX() + \"), inclusive is true\" );\n       t.eq( aBounds.intersectsBounds(bBounds, false), false, \"(\" + aBounds.toBBOX() + \") does not intersect (\" + bBounds.toBBOX() + \"), inclusive is false\" );\n\n       //no intersect\n       bBounds = new OpenLayers.Bounds(-360, -180, -185, -95);\n       t.eq( aBounds.intersectsBounds(bBounds),        false, \"(\" + aBounds.toBBOX() + \") does not intersect (\" + bBounds.toBBOX() + \")\" );\n       t.eq( aBounds.intersectsBounds(bBounds, true),  false, \"(\" + aBounds.toBBOX() + \") does not intersect (\" + bBounds.toBBOX() + \"), inclusive is true\" );\n       t.eq( aBounds.intersectsBounds(bBounds, false), false, \"(\" + aBounds.toBBOX() + \") does not intersect (\" + bBounds.toBBOX() + \"), inclusive is false\" );\n\n        // This is an actual use case with Mercator tiles at global scale\n        var merc_aBounds = new OpenLayers.Bounds(-40075016.67999999,20037508.339999992,\n                                                 -20037508.339999992,40075016.67999999),\n            merc_bBounds = new OpenLayers.Bounds(-20037508.34,-20037508.34,\n                                                  20037508.34,20037508.34);\n        t.eq( merc_aBounds.intersectsBounds(merc_bBounds, true), true, \"intersect shouldn't fall prey to floating point errors, inclusive is true\");\n        t.eq( merc_aBounds.intersectsBounds(merc_bBounds, false), false, \"intersect shouldn't fall prey to floating point errors, inclusive is false\");\n\n        // test for bounds intersection where none of the corners are contained within the other bounds\n        var b1 = new OpenLayers.Bounds(-1, -2, 1, 2);\n        var b2 = new OpenLayers.Bounds(-2, -1, 2, 1);\n        t.eq(b1.intersectsBounds(b2), true, \"vertical rectangle intersects horizontal rectangle\");\n        t.eq(b2.intersectsBounds(b1), true, \"horizontal rectangle intersects vertical rectangle\");\n\n    }\n\n    function test_Bounds_containsBounds(t) {\n        t.plan( 35 );\n        containerBounds = new OpenLayers.Bounds(10,10,40,40);\n\n        //totally outside\n        bounds = new OpenLayers.Bounds(0,0,5,5);\n        t.eq( containerBounds.containsBounds(bounds)              , false, \"(\" + containerBounds.toBBOX() + \") correctly does not contain (\" + bounds.toBBOX() + \")\");\n        t.eq( containerBounds.containsBounds(bounds, false)       , false, \"(\" + containerBounds.toBBOX() + \") correctly does not contain (\" + bounds.toBBOX() + \") when partial is false\" );\n        t.eq( containerBounds.containsBounds(bounds, false, true) , false, \"(\" + containerBounds.toBBOX() + \") correctly does not contain (\" + bounds.toBBOX() + \") when partial is false, inclusive is true\" );\n        t.eq( containerBounds.containsBounds(bounds, false, false), false, \"(\" + containerBounds.toBBOX() + \") correctly does not contain (\" + bounds.toBBOX() + \") when partial is false, inclusive is false\" );\n        t.eq( containerBounds.containsBounds(bounds, true)        , false , \"(\" + containerBounds.toBBOX() + \") correctly does not contain (\" + bounds.toBBOX() + \") when partial is true\" );\n        t.eq( containerBounds.containsBounds(bounds, true, true)  , false, \"(\" + containerBounds.toBBOX() + \") correctly does not contain (\" + bounds.toBBOX() + \") when partial is true, inclusive is true\" );\n        t.eq( containerBounds.containsBounds(bounds, true, false) , false, \"(\" + containerBounds.toBBOX() + \") correctly does not contain (\" + bounds.toBBOX() + \") when partial is true, inclusive is false\" );\n\n        //totally outside on border\n        bounds = new OpenLayers.Bounds(15,0,30,10);\n        t.eq( containerBounds.containsBounds(bounds)              , false, \"(\" + containerBounds.toBBOX() + \") correctly does not contain (\" + bounds.toBBOX() + \")\");\n        t.eq( containerBounds.containsBounds(bounds, false)       , false, \"(\" + containerBounds.toBBOX() + \") correctly does not contain (\" + bounds.toBBOX() + \") when partial is false\" );\n        t.eq( containerBounds.containsBounds(bounds, false, true) , false, \"(\" + containerBounds.toBBOX() + \") correctly does not contain (\" + bounds.toBBOX() + \") when partial is false, inclusive is true\" );\n        t.eq( containerBounds.containsBounds(bounds, false, false), false, \"(\" + containerBounds.toBBOX() + \") correctly does not contain (\" + bounds.toBBOX() + \") when partial is false, inclusive is false\" );\n        t.eq( containerBounds.containsBounds(bounds, true)        , true, \"(\" + containerBounds.toBBOX() + \") correctly contains (\" + bounds.toBBOX() + \") when partial is true\" );\n        t.eq( containerBounds.containsBounds(bounds, true, true)  , true, \"(\" + containerBounds.toBBOX() + \") correctly contains (\" + bounds.toBBOX() + \") when partial is true, inclusive is true\" );\n        t.eq( containerBounds.containsBounds(bounds, true, false) , false, \"(\" + containerBounds.toBBOX() + \") correctly does not contain (\" + bounds.toBBOX() + \") when partial is true, inclusive is false\" );\n\n        //partially inside\n        bounds = new OpenLayers.Bounds(20,20,50,30);\n        t.eq( containerBounds.containsBounds(bounds)              , false, \"(\" + containerBounds.toBBOX() + \") correctly does not contain (\" + bounds.toBBOX() + \")\");\n        t.eq( containerBounds.containsBounds(bounds, false)       , false, \"(\" + containerBounds.toBBOX() + \") correctly does not contain (\" + bounds.toBBOX() + \") when partial is false\" );\n        t.eq( containerBounds.containsBounds(bounds, false, true) , false, \"(\" + containerBounds.toBBOX() + \") correctly does not contain (\" + bounds.toBBOX() + \") when partial is false, inclusive is true\" );\n        t.eq( containerBounds.containsBounds(bounds, false, false), false, \"(\" + containerBounds.toBBOX() + \") correctly does not contain (\" + bounds.toBBOX() + \") when partial is false, inclusive is false\" );\n        t.eq( containerBounds.containsBounds(bounds, true)        , true, \"(\" + containerBounds.toBBOX() + \") correctly contains (\" + bounds.toBBOX() + \") when partial is true\" );\n        t.eq( containerBounds.containsBounds(bounds, true, true)  , true, \"(\" + containerBounds.toBBOX() + \") correctly contains (\" + bounds.toBBOX() + \") when partial is true, inclusive is true\" );\n        t.eq( containerBounds.containsBounds(bounds, true, false) , true, \"(\" + containerBounds.toBBOX() + \") correctly contains (\" + bounds.toBBOX() + \") when partial is true, inclusive is false\" );\n\n        //totally inside on border\n        bounds = new OpenLayers.Bounds(10,20,30,30);\n        t.eq( containerBounds.containsBounds(bounds)              , true, \"(\" + containerBounds.toBBOX() + \") correctly contains (\" + bounds.toBBOX() + \")\");\n        t.eq( containerBounds.containsBounds(bounds, false)       , true, \"(\" + containerBounds.toBBOX() + \") correctly contains (\" + bounds.toBBOX() + \") when partial is false\" );\n        t.eq( containerBounds.containsBounds(bounds, false, true) , true, \"(\" + containerBounds.toBBOX() + \") correctly contains (\" + bounds.toBBOX() + \") when partial is false, inclusive is true\" );\n        t.eq( containerBounds.containsBounds(bounds, false, false), false, \"(\" + containerBounds.toBBOX() + \") correctly does not contain (\" + bounds.toBBOX() + \") when partial is false, inclusive is false\" );\n        t.eq( containerBounds.containsBounds(bounds, true)        , true, \"(\" + containerBounds.toBBOX() + \") correctly contains (\" + bounds.toBBOX() + \") when partial is true\" );\n        t.eq( containerBounds.containsBounds(bounds, true, true)  , true, \"(\" + containerBounds.toBBOX() + \") correctly contains (\" + bounds.toBBOX() + \") when partial is true, inclusive is true\" );\n        t.eq( containerBounds.containsBounds(bounds, true, false) , true, \"(\" + containerBounds.toBBOX() + \") correctly contains (\" + bounds.toBBOX() + \") when partial is true, inclusive is false\" );\n\n        //totally inside\n        bounds = new OpenLayers.Bounds(20,20,30,30);\n        t.eq( containerBounds.containsBounds(bounds)              , true, \"(\" + containerBounds.toBBOX() + \") correctly contains (\" + bounds.toBBOX() + \")\");\n        t.eq( containerBounds.containsBounds(bounds, false)       , true, \"(\" + containerBounds.toBBOX() + \") correctly contains (\" + bounds.toBBOX() + \") when partial is false\" );\n        t.eq( containerBounds.containsBounds(bounds, false, true) , true, \"(\" + containerBounds.toBBOX() + \") correctly contains (\" + bounds.toBBOX() + \") when partial is false, inclusive is true\" );\n        t.eq( containerBounds.containsBounds(bounds, false, false), true, \"(\" + containerBounds.toBBOX() + \") correctly contains (\" + bounds.toBBOX() + \") when partial is false, inclusive is false\" );\n        t.eq( containerBounds.containsBounds(bounds, true)        , true, \"(\" + containerBounds.toBBOX() + \") correctly contains (\" + bounds.toBBOX() + \") when partial is true\" );\n        t.eq( containerBounds.containsBounds(bounds, true, true)  , true, \"(\" + containerBounds.toBBOX() + \") correctly contains (\" + bounds.toBBOX() + \") when partial is true, inclusive is true\" );\n        t.eq( containerBounds.containsBounds(bounds, true, false) , true, \"(\" + containerBounds.toBBOX() + \") correctly contains (\" + bounds.toBBOX() + \") when partial is true, inclusive is false\" );\n\n    }\n\n    function test_Bounds_determineQuadrant(t) {\n\n       t.plan( 4 );\n       var bounds = new OpenLayers.Bounds(0,0,100,100);\n\n       var tl = new OpenLayers.LonLat(25, 75);\n       var tr = new OpenLayers.LonLat(75, 75);\n       var bl = new OpenLayers.LonLat(25, 25);\n       var br = new OpenLayers.LonLat(75, 25);\n\n       t.eq( bounds.determineQuadrant(tl), \"tl\", \"bounds.determineQuadrant correctly identifies a coordinate in the top left quadrant\");\n       t.eq( bounds.determineQuadrant(tr), \"tr\", \"bounds.determineQuadrant correctly identifies a coordinate in the top right quadrant\");\n       t.eq( bounds.determineQuadrant(bl), \"bl\", \"bounds.determineQuadrant correctly identifies a coordinate in the bottom left quadrant\");\n       t.eq( bounds.determineQuadrant(br), \"br\", \"bounds.determineQuadrant correctly identifies a coordinate in the bottom right quadrant\");\n    }\n\n    function test_Bounds_oppositeQuadrant(t) {\n\n       t.plan( 4 );\n\n       t.eq( OpenLayers.Bounds.oppositeQuadrant(\"tl\"), \"br\", \"OpenLayers.Bounds.oppositeQuadrant returns 'br' for 'tl'\");\n       t.eq( OpenLayers.Bounds.oppositeQuadrant(\"tr\"), \"bl\", \"OpenLayers.Bounds.oppositeQuadrant returns 'bl' for 'tr'\");\n       t.eq( OpenLayers.Bounds.oppositeQuadrant(\"bl\"), \"tr\", \"OpenLayers.Bounds.oppositeQuadrant returns 'tr' for 'bl'\");\n       t.eq( OpenLayers.Bounds.oppositeQuadrant(\"br\"), \"tl\", \"OpenLayers.Bounds.oppositeQuadrant returns 'tl' for 'br'\");\n    }\n\n    function test_Bounds_equals(t) {\n        t.plan( 3 );\n        var boundsA = new OpenLayers.Bounds(1,2,3,4);\n        var boundsB = new OpenLayers.Bounds(1,2,3,4);\n        var boundsC = new OpenLayers.Bounds(1,5,3,4);\n\n        t.ok( boundsA.equals(boundsB), \"equals() returns true on two equal bounds.\" );\n        t.ok( !boundsA.equals(boundsC), \"equals() returns false on two different bounds.\" );\n        t.ok( !boundsA.equals(null), \"equals() returns false on comparison to null\");\n    }\n\n    function test_Bounds_getHeight_getWidth(t) {\n        t.plan( 2 );\n        var bounds = new OpenLayers.Bounds(10,20,100,120);\n\n        t.eq( bounds.getWidth(), 90, \"getWidth() works\" );\n        t.eq( bounds.getHeight(), 100, \"getHeight() works\" );\n\n    }\n\n    function test_Bounds_getCenters(t) {\n        t.plan( 2 );\n        var bounds = new OpenLayers.Bounds(0,20,100,120);\n\n                t.ok( bounds.getCenterPixel().equals(new OpenLayers.Pixel(50, 70)), \"getCenterPixel() works correctly\");\n        t.ok( bounds.getCenterLonLat().equals(new OpenLayers.LonLat(50, 70)), \"getCenterLonLat() works correctly\");\n    }\n\n    function test_getCenterLonLat(t) {\n        t.plan(7);\n        var bounds = new OpenLayers.Bounds(0, 10, 20, 60);\n\n        // set private centerLonLat to confirm that it is getting returned if set\n        bounds.centerLonLat = \"foo\";\n        t.eq(bounds.getCenterLonLat(), \"foo\", \"returns cached value\");\n        bounds.centerLonLat = null;\n\n        // unmodified\n        var center = bounds.getCenterLonLat();\n        t.eq(center.lon, 10, \"unmodified: correct x\");\n        t.eq(center.lat, 35, \"unmodified: correct y\");\n\n        // transformed\n        bounds.transform(new OpenLayers.Projection(\"EPSG:4326\"), new OpenLayers.Projection(\"EPSG:900913\"));\n        center = bounds.getCenterLonLat();\n        t.eq(Math.round(center.lon), 1113195, \"transformed: correct x\");\n        t.eq(Math.round(center.lat), 4759314, \"transformed: correct y\");\n\n        // extended\n        bounds.extend(new OpenLayers.Bounds(-10000000, -10000000, 10000000, 10000000));\n        center = bounds.getCenterLonLat();\n        t.eq(center.lon, 0, \"extended: correct x\");\n        t.eq(center.lat, 0, \"extended: correct y\");\n\n\n    }\n\n    function test_Bounds_fromArray(t) {\n       t.plan( 7 );\n\n       var bbox = [1,2,3,4];\n       bounds = OpenLayers.Bounds.fromArray(bbox);\n       t.ok( bounds instanceof OpenLayers.Bounds, \"new OpenLayers.Bounds returns Bounds object\" );\n       t.eq( bounds.left, 1, \"bounds.left is set correctly\" );\n       t.eq( bounds.bottom, 2, \"bounds.bottom is set correctly\" );\n       t.eq( bounds.right, 3, \"bounds.right is set correctly\" );\n       t.eq( bounds.top, 4, \"bounds.top is set correctly\" );\n\n       // reverse axis order\n       var reverseBbox = bounds.toArray(true);\n       t.eq(reverseBbox, [2,1,4,3], \"toArray with reverseAxisOrder set to true works as expected\");\n       var boundsFromReverse = OpenLayers.Bounds.fromArray(reverseBbox, true);\n       t.ok(bounds.equals(boundsFromReverse), \"Bounds created from array with reverseAxisOrder are correct\");\n    }\n\n    function test_Bounds_fromSize(t) {\n       t.plan( 5 );\n\n       var height = 15;\n       var width = 16;\n       var size = new OpenLayers.Size(width, height);\n       bounds = OpenLayers.Bounds.fromSize(size);\n       t.ok( bounds instanceof OpenLayers.Bounds, \"new OpenLayers.Bounds returns Bounds object\" );\n       t.eq( bounds.left, 0, \"bounds.left is set correctly\" );\n       t.eq( bounds.bottom, height, \"bounds.bottom is set correctly\" );\n       t.eq( bounds.right, width, \"bounds.right is set correctly\" );\n       t.eq( bounds.top, 0, \"bounds.top is set correctly\" );\n    }\n\n\n    function test_Bounds_extend(t) {\n        t.plan( 9 );\n\n        // null bounds to start\n        var originalBounds = new OpenLayers.Bounds();\n        var bounds = originalBounds.clone();\n\n        bounds.extend(new OpenLayers.LonLat(4,5));\n        t.ok(bounds.equals(new OpenLayers.Bounds(4,5,4,5)), \"uninitialized bounds can be safely extended\");\n\n        // extend with null obj\n        originalBounds = new OpenLayers.Bounds(10,20,50,80);\n        bounds = originalBounds.clone();\n\n        bounds.extend(null);\n        t.ok(bounds.equals(originalBounds), \"null to extend does not crash or change original bounds\");\n\n        // obj with no classname\n        var object = {};\n        bounds.extend(object);\n        t.ok(bounds.equals(originalBounds), \"extend() passing object with no classname does not crash or change original bounds\")\n\n\n        // obj is bounds\n\n        // pushing all limits with bounds obj\n        var testBounds = new OpenLayers.Bounds(5, 10, 60, 90);\n        object = testBounds.clone();\n\n        bounds.extend(object);\n        t.ok(bounds.equals(testBounds), \"extend by valid bounds, pushing all limits, correctly extends bounds\");\n\n        // pushing no limits with bounds obj\n        bounds = originalBounds.clone();\n\n        testBounds = new OpenLayers.Bounds(15, 30, 40, 70);\n        object = testBounds.clone();\n\n        bounds.extend(object);\n        t.ok(bounds.equals(originalBounds), \"extend by valid bounds, pushing no limits, correctly does not extend bounds\");\n\n\n        // obj is lonlat\n\n        // left, bottom\n        bounds = originalBounds.clone();\n\n        object = new OpenLayers.LonLat(5, 10);\n\n        bounds.extend(object);\n\n        t.ok( ((bounds.left == object.lon) &&\n               (bounds.bottom == object.lat) &&\n               (bounds.right == originalBounds.right) &&\n               (bounds.top == originalBounds.top)), \"obj lonlat to extends correctly modifies left and bottom\");\n\n        // right, top\n        bounds = originalBounds.clone();\n\n        object = new OpenLayers.LonLat(60,90);\n\n        bounds.extend(object);\n\n        t.ok( ((bounds.left == originalBounds.left) &&\n               (bounds.bottom == originalBounds.bottom) &&\n               (bounds.right == object.lon) &&\n               (bounds.top == object.lat)), \"obj lonlat to extends correctly modifies right and top\");\n\n\n        // obj is point\n\n        // left, bottom\n        bounds = originalBounds.clone();\n\n        object = new OpenLayers.Geometry.Point(5, 10);\n\n        bounds.extend(object);\n\n        t.ok( ((bounds.left == object.x) &&\n               (bounds.bottom == object.y) &&\n               (bounds.right == originalBounds.right) &&\n               (bounds.top == originalBounds.top)), \"obj Point to extends correctly modifies left and bottom\");\n\n        // right, top\n        bounds = originalBounds.clone();\n\n        object = new OpenLayers.Geometry.Point(60,90);\n\n        bounds.extend(object);\n\n        t.ok( ((bounds.left == originalBounds.left) &&\n               (bounds.bottom == originalBounds.bottom) &&\n               (bounds.right == object.x) &&\n               (bounds.top == object.y)), \"obj Point to extends correctly modifies right and top\");\n\n    }\n\n\n    function test_Bounds_extendXY(t) {\n        t.plan(3);\n\n        // null bounds to start\n        var originalBounds = new OpenLayers.Bounds();\n\n        var bounds = originalBounds.clone();\n        bounds.extendXY(4, 5);\n\n        t.ok(bounds.equals(new OpenLayers.Bounds(4,5,4,5)), \"uninitialized bounds can be safely extended\");\n\n        // left, bottom\n        originalBounds = new OpenLayers.Bounds(10,20,50,80);\n\n        bounds = originalBounds.clone();\n        bounds.extendXY(5, 10);\n\n        t.ok( ((bounds.left == 5) &&\n               (bounds.bottom == 10) &&\n               (bounds.right == originalBounds.right) &&\n               (bounds.top == originalBounds.top)), \"extendXY correctly modifies left and bottom\");\n\n        // right, top\n        bounds = originalBounds.clone();\n        bounds.extendXY(60, 90);\n\n        t.ok( ((bounds.left == originalBounds.left) &&\n               (bounds.bottom == originalBounds.bottom) &&\n               (bounds.right == 60) &&\n               (bounds.top == 90)), \"extendXY correctly modifies right and top\");\n    }\n\n\n    function test_Bounds_wrapDateLine(t) {\n        t.plan( 13 );\n\n        var testBounds, wrappedBounds, desiredBounds;\n\n        var maxExtent = new OpenLayers.Bounds(-10,-10,10,10);\n        var exactBounds = maxExtent.clone();\n        var simpleBounds = new OpenLayers.Bounds( -5,-5,5,5);\n\n\n\n    //bad maxextent\n        testBounds = simpleBounds.clone();\n        wrappedBounds = testBounds.wrapDateLine(null);\n        t.ok(wrappedBounds.equals(simpleBounds), \"wrapping a bounds with a bad maxextent does nothing\");\n\n\n\n    //exactly inside\n        testBounds = exactBounds.clone();\n        wrappedBounds = testBounds.wrapDateLine(maxExtent);\n        t.ok(wrappedBounds.equals(exactBounds), \"wrapping a bounds precisely within (equal to) maxextent does nothing\");\n\n\n    //inside\n        testBounds = simpleBounds.clone();\n        wrappedBounds = testBounds.wrapDateLine(maxExtent);\n        t.ok(wrappedBounds.equals(simpleBounds), \"wrapping a bounds within maxextent does nothing\");\n\n// LEFT //\n\n    //straddling left\n        testBounds = simpleBounds.add(-10,0);\n        wrappedBounds = testBounds.wrapDateLine(maxExtent);\n        t.ok(wrappedBounds.equals(testBounds), \"wrapping a bounds that straddles the left of maxextent does nothing\");\n\n    //left rightTolerance\n        testBounds = simpleBounds.add(-14,0);\n        wrappedBounds =\n            testBounds.wrapDateLine(maxExtent, {'rightTolerance': 1} );\n        desiredBounds = simpleBounds.add(6,0);\n        t.ok(wrappedBounds.equals(desiredBounds), \"wrapping a bounds rightTolerance left of maxextent works\");\n\n    //exactly left\n        testBounds = exactBounds.add(-20,0);\n        wrappedBounds = testBounds.wrapDateLine(maxExtent);\n        t.ok(wrappedBounds.equals(exactBounds), \"wrapping an exact bounds once left of maxextent works\");\n\n    //left\n        testBounds = simpleBounds.add(-20,0);\n        wrappedBounds = testBounds.wrapDateLine(maxExtent);\n        t.ok(wrappedBounds.equals(simpleBounds), \"wrapping a bounds once left of maxextent works\");\n\n    //way left\n        testBounds = simpleBounds.add(-200,0);\n        wrappedBounds = testBounds.wrapDateLine(maxExtent);\n        t.ok(wrappedBounds.equals(simpleBounds), \"wrapping a bounds way left of maxextent works\");\n\n// RIGHT //\n\n    //straddling right\n        testBounds = simpleBounds.add(10,0);\n        wrappedBounds = testBounds.wrapDateLine(maxExtent);\n        desiredBounds = testBounds.add(-maxExtent.getWidth(), 0)\n        t.ok(wrappedBounds.equals(desiredBounds), \"wrapping a bounds that straddles the right of maxextent moves extent to left side of the world\");\n\n    //right leftTolerance\n        testBounds = simpleBounds.add(14,0);\n        wrappedBounds =\n            testBounds.wrapDateLine(maxExtent, {'leftTolerance': 1} );\n        desiredBounds = simpleBounds.add(-6,0);\n        t.ok(wrappedBounds.equals(desiredBounds), \"wrapping a bounds leftTolerance right of maxextent works\");\n\n    //exactly right\n        testBounds = exactBounds.add(20,0);\n        wrappedBounds = testBounds.wrapDateLine(maxExtent);\n        t.ok(wrappedBounds.equals(exactBounds), \"wrapping an exact bounds once right of maxextent works\");\n\n    //right\n        testBounds = simpleBounds.add(20,0);\n        wrappedBounds = testBounds.wrapDateLine(maxExtent);\n        t.ok(wrappedBounds.equals(simpleBounds), \"wrapping a bounds once right of maxextent works\");\n\n    //way right\n        testBounds = simpleBounds.add(200,0);\n        wrappedBounds = testBounds.wrapDateLine(maxExtent);\n        t.ok(wrappedBounds.equals(simpleBounds), \"wrapping a bounds way right of maxextent works\");\n\n\n\n    }\n    function test_Bounds_transform(t) {\n        t.plan( 5 );\n        bounds = new OpenLayers.Bounds(10, -10, 20, 10);\n        bounds.transform(new OpenLayers.Projection(\"foo\"), new OpenLayers.Projection(\"Bar\"));\n        t.eq(bounds.toBBOX(), \"10,-10,20,10\", \"null transform okay\");\n        bounds.transform(new OpenLayers.Projection(\"EPSG:4326\"), new OpenLayers.Projection(\"EPSG:900913\"));\n        t.eq(bounds.toBBOX(), \"1113194.907778,-1118889.974702,2226389.815556,1118889.974702\", \"bounds for spherical mercator transform are correct\");\n        bounds.transform(new OpenLayers.Projection(\"EPSG:900913\"), new OpenLayers.Projection(\"EPSG:4326\"));\n        t.eq(bounds.toBBOX(), \"10,-10,20,10\", \"bounds for inverse spherical mercator transform are correct\");\n\n        // transform with string\n        bounds = new OpenLayers.Bounds(10, -10, 20, 10);\n        bounds.transform(\"EPSG:4326\", \"EPSG:900913\");\n        t.eq(bounds.toBBOX(), \"1113194.907778,-1118889.974702,2226389.815556,1118889.974702\", \"(string) bounds for spherical mercator transform are correct\");\n        bounds.transform(\"EPSG:900913\", \"EPSG:4326\");\n        t.eq(bounds.toBBOX(), \"10,-10,20,10\", \"(string) bounds for inverse spherical mercator transform are correct\");\n\n    }\n\n    function test_Bounds_add(t) {\n        t.plan( 6 );\n\n        origBounds = new OpenLayers.Bounds(1,2,3,4);\n        testBounds = origBounds.clone();\n\n        var bounds = testBounds.add(5, 50);\n        t.ok( testBounds.equals(origBounds), \"testBounds is not modified by add operation\");\n\n        var b = new OpenLayers.Bounds(6,52,8,54);\n        t.ok( bounds.equals(b), \"bounds is set correctly\");\n\n    //null values\n        try {\n            bounds = testBounds.add(null, 50);\n        } catch(e) {\n            t.ok(\"exception thrown when passing null value to add()\");\n        }\n        t.ok( testBounds.equals(origBounds), \"testBounds is not modified by erroneous add operation (null x)\");\n\n        try {\n            bounds = testBounds.add(5, null);\n        } catch(e) {\n            t.ok(\"exception thrown when passing null value to add()\");\n        }\n        t.ok( testBounds.equals(origBounds), \"testBounds is not modified by erroneous add operation (null y)\");\n    }\n\n    function test_Bounds_scale(t) {\n        t.plan(3);\n\n        origBounds = new OpenLayers.Bounds(1,2,3,4);\n        bounds = origBounds.scale(2);\n        var b = new OpenLayers.Bounds(0,1,4,5);\n        t.ok(bounds.equals(b), \"Bounds scale correctly with default origin at center\")\n\n        var origin = new OpenLayers.Pixel(0,1);\n        bounds = origBounds.scale(2,origin);\n        b = new OpenLayers.Bounds(2,3,6,7);\n        t.ok(bounds.equals(b), \"Bounds scale correctly with offset origin\");\n\n        origin = new OpenLayers.Pixel(5,1);\n        bounds = bounds.scale(2, origin);\n        b = new OpenLayers.Bounds(-1, 5, 7, 13);\n        t.ok(bounds.equals(b), \"Bounds scale correctly with offset origin\");\n\n    }\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/BaseTypes/Class.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_Class(t) {\n        t.plan(1);\n        var MyClass = OpenLayers.Class({\n            initialize: function () {\n                t.ok(false, \"initialize should not be called\");\n            }\n        });\n        t.ok(true,\n             \"defining a class does not call the constructor for the class\");\n    }\n\n    function test_Class_constructor(t) {\n        t.plan(7);\n        \n        var MyClass = OpenLayers.Class({\n            prop: null,\n            classProp: {'bad': 'practice'},\n            initialize: function(a1, a2) {\n                this.prop = \"instance property\";\n                t.ok(true,\n                     \"initialize is called when a new instance is created\");\n                t.eq(a1, arg1,\n                     \"initialize is called with the proper first argument\");\n                t.eq(a2, arg2,\n                     \"initialize is called with the proper second argument\");\n            },\n            CLASS_NAME: \"MyClass\"\n        });\n\n        var arg1 = \"anArg\";\n        var arg2 = {\"another\": \"arg\"};\n        var myObj = new MyClass(arg1, arg2);\n        t.eq(MyClass.prop, null,\n             \"creating a new instance doesn't modify the class\");\n        t.eq(myObj.prop, \"instance property\",\n             \"the new instance is assigned a property in the constructor\");\n        t.eq(myObj[\"CLASS_NAME\"], \"MyClass\",\n             \"the new object is an instance of MyClass\");\n\n        // allow for modification of class properties\n        MyClass.prototype.classProp.bad = \"good\";\n        t.eq(myObj.classProp.bad, \"good\",\n             \"modifying a class property modifies properties of the instance\");\n    }\n\n    function test_Class_inheritance(t) {\n        t.plan(7);\n        \n        var BaseClass = OpenLayers.Class({\n            prop: \"base\",\n            initialize: function() {\n                t.ok(false,\n                     \"base class constructor is not called during inheritance\");\n            },\n            toString: function() {\n                return \"toString inherited\";\n            },\n            CLASS_NAME: \"BaseClass\"\n        });\n        \n        var ChildClass = OpenLayers.Class(BaseClass, {\n            initialize: function() {\n                t.ok(true,\n                     \"child class constructor is called in creating an instance\");\n            },\n            CLASS_NAME: \"ChildClass\"\n        });\n        \n        var child = new ChildClass();\n        t.eq(child.prop, \"base\",\n             \"instance of child inherits properties from base\");\n        t.eq(child.toString(), \"toString inherited\",\n             \"instance of child inherits toString method from base\");\n        t.eq(child[\"CLASS_NAME\"],\n             \"ChildClass\",\n             \"new object is an instance of the child class\");\n        \n        var F = OpenLayers.Class(Object, {});\n        t.ok(!(\"initialize\" in Object.prototype), \"no messing with non OL prototypes\");\n\n        // test with an abstract class (i.e. a class that doesn't have an initialize\n        // method) as the parent class\n        var Vehicule = OpenLayers.Class({\n            numWheels: null\n        });\n        var Bike = OpenLayers.Class(Vehicule, {\n            initialize: function() {\n                this.numWheels = 2;\n            }\n        });\n        var b = new Bike();\n        t.ok(b instanceof Vehicule, \"a bike is a vehicule\");\n        \n        // test inheritance with something that has a non-function initialize property\n        var P = OpenLayers.Class({\n            initialize: \"foo\"\n        });\n        var C = OpenLayers.Class(P, {\n            initialize: function() {\n                // pass\n            }\n        });\n        var c = new C();\n        t.eq(P.prototype.initialize, \"foo\", \"Class restores custom initialize property.\");\n        \n    }\n    \n    function test_Class_multiple_inheritance(t) {\n        t.plan(7);\n        var BaseClass1 = OpenLayers.Class({\n            override: \"base1\",\n            prop: \"base1\",\n            variable: null,\n            initialize: function() {\n                t.ok(true,\n                     \"only called when an instance of this class is created\");\n            },\n            CLASS_NAME: \"BaseClass1\"\n        });\n\n        var BaseClass2 = OpenLayers.Class({\n            override: \"base2\",\n            initialize: function() {\n                t.ok(false,\n                     \"base class constructor is not called during inheritance\");\n            },\n            CLASS_NAME: \"BaseClass1\"\n        });\n        \n        var ChildClass = OpenLayers.Class(BaseClass1, BaseClass2, {\n            initialize: function(arg) {\n                if(this.prop == \"base1\") {\n                    this.variable = \"child\";\n                }\n                t.ok(true,\n                     \"only child class constructor is called on initialization\");\n            },\n            CLASS_NAME: \"ChildClass\"\n        });\n        \n        var arg = \"child\";\n        var child = new ChildClass(arg);\n        t.eq(child.variable, arg,\n             \"inheritance works before construction\");\n        t.eq(child.prop, \"base1\",\n             \"properties are inherited with multiple classes\")\n        t.eq(child.override, \"base2\",\n             \"properties are inherited in the expected order\");\n        t.eq(child[\"CLASS_NAME\"],\n             \"ChildClass\",\n             \"object is an instance of child class\");\n        \n        var base1 = new BaseClass1();\n        t.eq(base1.override, \"base1\",\n             \"inheritance doesn't mess with parents\");\n\n    }\n\n    function test_inheritance_chain(t) {\n        t.plan(1);\n        var A = new OpenLayers.Class({\n            initialize: function() {\n                this.a = 'foo';\n            }\n        });\n        var B = new OpenLayers.Class(A, {});\n        var C = new OpenLayers.Class(B, {\n            initialize: function() {\n                B.prototype.initialize.apply(this, arguments);\n                this.a = this.a + 'bar';\n            }\n        });\n        var c = new C;\n        t.eq(c.a, 'foobar', 'constructor at the root is called');\n    }\n    \n\n    function test_Class_isInstanceOf(t) {\n        t.plan(7);\n        var wms = new OpenLayers.Layer.WMS({});\n        var drag = new OpenLayers.Control.DragFeature({});\n        t.ok(wms instanceof OpenLayers.Layer.WMS, \"isInstanceOf(WMS)\");\n        t.ok(wms instanceof OpenLayers.Layer, \"isInstanceOf(Layer)\");\n        t.ok(!(wms instanceof OpenLayers.Format), \"not isInstanceOf(Format)\");\n        t.ok(drag instanceof OpenLayers.Control, \"drag is a control\");\n        t.ok(!(drag instanceof OpenLayers.Layer), \"drag is not a layer\");\n\n        //test a class with multiple inheritance\n        var BadClass=OpenLayers.Class(OpenLayers.Layer.WMS, OpenLayers.Control.DragFeature);\n        var bad = new BadClass({});\n        t.ok(!(bad instanceof OpenLayers.Control), \"bad is a control, but it is also a layer and we cannot have two superclasses\");\n        t.ok(bad instanceof OpenLayers.Layer, \"bad is a layer, it inherits from the layer first\");\n    }\n\n    //\n    // IGN's GeoPortal API overwrite prototypes of OpenLayers constructors.\n    // The tests below aim to cover their usage pattens.\n    //\n\n    // the overwrite function under test\n    function overwrite(C, o) {\n        if(typeof o.initialize === \"function\" &&\n            C === C.prototype.initialize) {\n            // OL 2.11\n\n            var proto = C.prototype;\n            var staticProps = OpenLayers.Util.extend({}, C);\n\n            C = o.initialize;\n\n            C.prototype = proto;\n            OpenLayers.Util.extend(C, staticProps);\n        }\n        OpenLayers.Util.extend(C.prototype, o);\n        return C;\n    }\n\n    function test_overwrite_1(t) {\n        // overwrite constructor\n        t.plan(1);\n        var A = OpenLayers.Class({\n            initialize: function() {\n                this.a = \"foo\";\n            }\n        });\n        A = overwrite(A, {\n            initialize: function() {\n                this.a = \"bar\";\n            }\n        });\n        var a = new A;\n        t.eq(a.a, \"bar\", \"ctor overwritten\");\n    }\n\n    function test_overwrite_2(t) {\n        // overwrite regular method\n        t.plan(1);\n        var A = OpenLayers.Class({\n            initialize: function() {\n            },\n            method: function() {\n                this.a = \"foo\";\n            }\n        });\n        A = overwrite(A, {\n            method: function() {\n                this.a = \"bar\";\n            }\n        });\n        var a = new A;\n        a.method();\n        t.eq(a.a, \"bar\", \"method overwritten\");\n    }\n\n    function test_overwrite_3(t) {\n        // overwrite constructor of subclass\n        t.plan(1);\n        var A = OpenLayers.Class({\n            initialize: function() {\n                this.a = \"foo\";\n            }\n        });\n        var B = OpenLayers.Class(A, {\n            initialize: function() {\n                A.prototype.initialize.call(this);\n            }\n        });\n        B = overwrite(B, {\n            initialize: function() {\n                A.prototype.initialize.call(this);\n                this.a = \"bar\";\n            }\n        });\n        var b = new B;\n        t.eq(b.a, \"bar\", \"ctor overwritten\");\n    }\n\n    function test_overwrite_4(t) {\n        // overwrite constructor of parent class\n        t.plan(1);\n        var A = OpenLayers.Class({\n            initialize: function() {\n                this.a = \"foo\";\n            }\n        });\n        var B = OpenLayers.Class(A, {\n            initialize: function() {\n                A.prototype.initialize.call(this);\n            }\n        });\n        A = overwrite(A, {\n            initialize: function() {\n                this.a = \"bar\";\n            }\n        });\n        var b = new B;\n        t.eq(b.a, \"bar\", \"ctor overwritten\");\n    }\n\n    function test_overwrite_5(t) {\n        // overwrite constructor of parent class, which itself\n        // doesn't defined \"initialize\"\n        t.plan(2);\n        var A = OpenLayers.Class({\n            initialize: function() {\n                this.a = \"foo\";\n            }\n        });\n        var B = OpenLayers.Class(A, {});\n        var _A = A;\n        A = overwrite(A, {\n            initialize: function() {\n                this.a = \"bar\";\n            }\n        });\n        var b = new B;\n        t.ok(A.prototype === _A.prototype, \"A and _A share the prototype\");\n        t.eq(b.a, \"bar\", \"ctor overwritten\");\n    }\n\n    function test_overwrite_6(t) {\n        // with static methods\n        t.plan(1);\n        var A = OpenLayers.Class({\n            initialize: function() {\n            }\n        });\n        A.staticMethod = function() {};\n        A = overwrite(A, {\n            initialize: function() {\n            }\n        });\n        var exc = false;\n        try {\n            A.staticMethod();\n        } catch(e) {\n            exc = true;\n        }\n        t.ok(!exc, \"static method still there\");\n    }\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/BaseTypes/Date.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_Date_toISOString(t) {\n        t.plan(3);\n    \n        var date, str;\n\n        // check valid date\n        date = new Date(Date.UTC(2010, 10, 27, 18, 19, 15, 123));\n        str = OpenLayers.Date.toISOString(date);\n        t.eq(str, \"2010-11-27T18:19:15.123Z\", \"valid date\");\n        \n        // check zero padding\n        date = new Date(Date.UTC(2010, 7, 7, 18, 9, 5, 12));\n        str = OpenLayers.Date.toISOString(date);\n        t.eq(str, \"2010-08-07T18:09:05.012Z\", \"zero padding\");\n        \n        // check invalid date\n        date = new Date(\"foo\");\n        try {\n            str = OpenLayers.Date.toISOString(date);\n        } catch (err) {\n            // some implementations throw RangeError\n            // see https://bugzilla.mozilla.org/show_bug.cgi?id=649575\n            if (err instanceof RangeError) {\n                str = \"Invalid Date\";\n            }\n        }\n        t.eq(str, \"Invalid Date\", \"invalid date\");\n\n    }\n    \n    function test_Date_parse(t) {\n        \n        t.plan(114);\n        \n        var cases = {\n            \"2000\": {\n                year: 2000,\n                month: 0,\n                date: 1\n            },\n            \"2005-10\": {\n                year: 2005,\n                month: 9,\n                date: 1\n            },\n            \"1971-07-23\": {\n                year: 1971,\n                month: 6,\n                date: 23\n            },\n            \"1801-11-20T04:30:15Z\": {\n                year: 1801,\n                month: 10,\n                date: 20,\n                hour: 4,\n                minutes: 30,\n                seconds: 15\n            },\n            \"1989-06-15T18:30:15.91Z\": {\n                year: 1989,\n                month: 5,\n                date: 15,\n                hour: 18,\n                minutes: 30,\n                seconds: 15,\n                milliseconds: 910\n            },\n            \"1989-06-15T18:30:15.091Z\": {\n                year: 1989,\n                month: 5,\n                date: 15,\n                hour: 18,\n                minutes: 30,\n                seconds: 15,\n                milliseconds: 91\n            },\n            \"1989-06-15T13:30:15.091-05\": {\n                year: 1989,\n                month: 5,\n                date: 15,\n                hour: 18,\n                minutes: 30,\n                seconds: 15,\n                milliseconds: 91\n            },\n            \"2010-08-06T15:21:25-06\": { // MDT\n                year: 2010,\n                month: 7,\n                date: 6,\n                hour: 21,\n                minutes: 21,\n                seconds: 25\n            },\n            \"2010-08-07T06:21:25+9\": { // JSP\n                year: 2010,\n                month: 7,\n                date: 6,\n                hour: 21,\n                minutes: 21,\n                seconds: 25\n            },\n            \"2010-08-07T02:51:25+05:30\": { // IST\n                year: 2010,\n                month: 7,\n                date: 6,\n                hour: 21,\n                minutes: 21,\n                seconds: 25\n            },\n            \"T21:51:25Z\": {\n                hour: 21,\n                minutes: 51,\n                seconds: 25\n            },\n            \"T02:51:25+05:30\": { // IST\n                hour: 21,\n                minutes: 21,\n                seconds: 25\n            },\n            \"T2:51:25.1234-7\": { // lenient\n                hour: 9,\n                minutes: 51,\n                seconds: 25,\n                milliseconds: 123\n            },\n            \"2000Z\": { // lenient (Chrome accepts this)\n                year: 2000\n            },\n            \"2000-02Z\": { // lenient (Chrome accepts this)\n                year: 2000,\n                month: 1\n            },\n            \"2000-04-15Z\": { // lenient (Chrome accepts this)\n                year: 2000,\n                month: 3,\n                date: 15\n            }\n        };\n\n        var o, got, exp;\n        for (var str in cases) {\n            o = cases[str];\n            got = OpenLayers.Date.parse(str);\n            exp = new Date(Date.UTC(o.year || 0, o.month || 0, o.date || 1, o.hour || 0, o.minutes || 0, o.seconds || 0, o.milliseconds || 0));\n            if (\"year\" in o) {\n                t.eq(got.getUTCFullYear(), exp.getUTCFullYear(), str + \": correct UTCFullYear\");\n                t.eq(got.getUTCMonth(), exp.getUTCMonth(), str + \": correct UTCMonth\");\n                t.eq(got.getUTCDate(), exp.getUTCDate(), str + \": correct UTCDate\");\n            } else {\n                t.ok(true, str + \": ECMA doesn't specify how years are handled in time only strings\");\n                t.ok(true, str + \": ECMA doesn't specify how months are handled in time only strings\");\n                t.ok(true, str + \": ECMA doesn't specify how days are handled in time only strings\");\n            }\n            if (\"hour\" in o) {\n                t.eq(got.getUTCHours(), exp.getUTCHours(), str + \": correct UTCHours\");\n                t.eq(got.getUTCMinutes(), exp.getUTCMinutes(), str + \": correct UTCMinutes\");\n                t.eq(got.getUTCSeconds(), exp.getUTCSeconds(), str + \": correct UTCSeconds\");\n                t.eq(got.getUTCMilliseconds(), exp.getUTCMilliseconds(), str + \": correct UTCMilliseconds\");\n            } else {\n                t.ok(true, str + \": ECMA doesn't specify how hours are handled in date only strings\");\n                t.ok(true, str + \": ECMA doesn't specify how minutes are handled in date only strings\");\n                t.ok(true, str + \": ECMA doesn't specify how seconds are handled in date only strings\");\n                t.ok(true, str + \": ECMA doesn't specify how milliseconds are handled in date only strings\");\n            }\n        }\n        \n        // check invalid date parsing\n        var invalid = OpenLayers.Date.parse(\"foo\");\n        t.ok(invalid instanceof Date, \"invalid is a date\");\n        t.ok(isNaN(invalid.getTime()), \"invalid has no time\");\n    }\n\n    function test_regex(t) {\n        t.plan(1);\n        var regex = OpenLayers.Date.dateRegEx;\n        OpenLayers.Date.dateRegEx = /^(?:(-?\\d{4})(?:-(\\d{2})(?:-(\\d{2}))?)?)?(?:(?:T(\\d{1,2}):(\\d{2}):(\\d{2}(?:\\.\\d+)?)(Z|(?:[+-]\\d{1,2}(?::(\\d{2}))?)))|Z)?$/;\n        var date = OpenLayers.Date.parse(\"-0501-03-01T00:00:00.000Z\");\n        t.ok(!isNaN(date.getTime()), \"date with negative year is parsed when providing alternative regex\");\n        OpenLayers.Date.dateRegEx = regex;\n    }\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/BaseTypes/Element.html",
    "content": "<html>\n  <head>\n  \n    <script src=\"../OLLoader.js\"></script>\n\n    <script type=\"text/javascript\">\n\n    function test_Element_visible(t) {\n        t.plan(3);\n        \n        var elem = {\n            style: {\n                'display': \"\"\n            }\n        };\n        \n        elem.style.display = \"\";\n        t.ok(OpenLayers.Element.visible(elem), \"element with style.display == '' is visible\");\n            \n        elem.style.display = \"block\";\n        t.ok(OpenLayers.Element.visible(elem), \"element with style.display == block is visible\");\n            \n        elem.style.display = \"none\";\n        t.ok(!OpenLayers.Element.visible(elem), \"element with style.display == none is not visible\");\n    }\n    \n    function test_Element_toggle(t) {\n        t.plan(2);\n\n        var elem1 = {\n            style: {\n                'display': \"none\"\n            }\n        };\n        \n        var elem2 = {\n            style: {\n                'display': \"\"\n            }\n        };\n\n        OpenLayers.Element.toggle(elem1, elem2);\n        \n        t.eq(elem1.style.display, \"\", \"hidden element toggled to display\");\n        t.eq(elem2.style.display, \"none\", \"shown element toggled to hidden\");\n    }\n    \n    function test_Element_remove(t) {\n        t.plan(1);\n\n        var elem = {\n            parentNode: {\n                'removeChild': function(elem) {\n                    t.ok(true, \"removeChild called\");\n                }\n            }        \n        };\n        OpenLayers.Element.remove(elem);\n    }\n    \n    function test_Element_getHeight(t) {\n        t.plan(1);\n\n        var elem = {\n            'offsetHeight': {}\n        };\n        \n        t.ok(OpenLayers.Element.getHeight(elem) == elem.offsetHeight, \"offsetHeight returned\");\n    }\n    \n    function test_hasClass(t) {        \n        t.plan(14);\n        var has = OpenLayers.Element.hasClass;\n\n        var element = document.createElement(\"div\");\n        element.className = \"fe fi fo fum one.part two-part three:part four\";\n        \n        t.ok(has(element, \"fe\"), \"has fe\");\n        t.ok(has(element, \"fi\"), \"has fi\");\n        t.ok(has(element, \"fo\"), \"has fo\");\n        t.ok(!has(element, \"f\"), \"hasn't f\");\n        t.ok(!has(element, \"o\"), \"hasn't o\");\n        t.ok(!has(element, \"fumb\"), \"hasn't fumb\");\n        t.ok(!has(element, \"one\"), \"hasn't one\");\n        t.ok(has(element, \"one.part\"), \"has one.part\");\n        t.ok(!has(element, \"two\"), \"hasn't two\");\n        t.ok(has(element, \"two-part\"), \"has two-part\");\n        t.ok(!has(element, \"three\"), \"hasn't three\");\n        t.ok(has(element, \"three:part\"), \"has three:part\");\n        t.ok(has(element, \"four\"), \"has four\");\n        \n        element.className = \"\";\n        t.ok(!has(element, \"nada\"), \"hasn't nada\");\n    }\n\n    function test_addClass(t) {        \n        t.plan(6);\n        var add = OpenLayers.Element.addClass;\n        \n        var element = document.createElement(\"div\");\n        element.id = \"foo\";\n        t.eq(element.className, \"\", \"starts with no class name\");\n        \n        var mod = add(element, \"first\");\n        t.eq(mod.id, element.id, \"returns the same element\");\n        t.eq(element.className, \"first\", \"properly adds first class name\");        \n        t.eq(add(element, \"second\").className, \"first second\",\n             \"properly adds second class name\");\n        t.eq(add(element, \"second\").className, \"first second\",\n             \"doesn't do anything for duplicated names\");\n        t.eq(add(element, \"third\").className, \"first second third\",\n             \"properly adds third class name\");\n    }\n    \n    function test_removeClass(t) {\n        t.plan(5);\n        var remove = OpenLayers.Element.removeClass;\n        \n        var element = document.createElement(\"div\");\n        element.id = \"foo\";\n        element.className = \"first second middle fourth last\";\n        \n        var mod = remove(element, \"last\");\n        t.eq(mod.id, element.id, \"returns the same element\");\n        t.eq(element.className, \"first second middle fourth\",\n             \"properly removes last class name\");\n        t.eq(remove(element, \"first\").className, \"second middle fourth\",\n             \"properly removes first class name\");\n        t.eq(remove(element, \"middle\").className, \"second fourth\",\n             \"properly removes middle class name\");\n        t.eq(remove(element, \"nada\").className, \"second fourth\",\n             \"doesn't do anything for bogus class name\");\n    }\n\n    function test_toggleClass(t) {\n        t.plan(5);\n        var toggle = OpenLayers.Element.toggleClass;\n        \n        var element = document.createElement(\"div\");\n        element.id = \"foo\";\n        \n        var mod = toggle(element, \"first\");\n        t.eq(mod.id, element.id, \"returns the same element\");\n        t.eq(element.className, \"first\", \"adds first new class name\");\n        t.eq(toggle(element, \"second\").className, \"first second\",\n             \"adds second new class name\");\n        t.eq(toggle(element, \"first\").className, \"second\",\n             \"removes first existing class name\");\n        t.eq(toggle(element, \"second\").className, \"\",\n             \"removes second existing class name\");\n    }\n\n    function test_Element_getStyle(t) {\n        t.plan(5);\n\n    //tests for this function are not 100% complete... there is some funky\n    // business going on in there with \n    //  * document.defaultView (moz/ff I believe)\n    // but I cant seem to find a good way to test them.\n    // \n\t\tt.ok(OpenLayers.Element.getStyle(null, null) == null, \"passing null values in to getStyle() doesnt bomb, returns null\");\n\n        var elem = document.getElementById(\"elemID\");\n        elem.style.chickenHead = {}\n\n        var style = \"chickenHead\";\n        t.ok(OpenLayers.Element.getStyle(elem, style) == elem.style.chickenHead, \"get style on basic stylename returns correctly\");\n\n        elem.style.chickenHead = \"auto\";\n        style = \"chickenHead\";\n        t.ok(OpenLayers.Element.getStyle(elem, style) == null, \"get style on 'auto' style returns null\");\n\n        if (OpenLayers.BROWSER_NAME == \"opera\") {\n            elem.style.top = \"15px\";\n            style = \"top\";\n\n            elem.style.position = \"static\";\n            t.ok(OpenLayers.Element.getStyle(elem, style) == null, \"in opera: get (top/left/right/bottom) style when position == 'static' returns null\");\n            \n            elem.style.position = \"\";\n            t.ok(OpenLayers.Element.getStyle(elem, style) == null, \"in opera: get (top/left/right/bottom) style when position != 'static', gets computedStyle as static and returns null\");\n\n        } else {\n            t.ok(true, \"browser is not opera.\");\n            t.ok(true, \"trust me. browser is not opera.\");\n        }\n\n    }    \n\n    </script>\n  </head>\n  <body>\n    <div id=\"elemID\" style=\"width:50px; height:100px; background-color:red\">test</div>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/BaseTypes/LonLat.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    var lonlat; \n\n    function test_LonLat_constructor (t) {\n        t.plan( 8 );\n        lonlat = new OpenLayers.LonLat(6, 5);\n        t.ok( lonlat instanceof OpenLayers.LonLat, \"new OpenLayers.LonLat returns LonLat object\" );\n        t.eq( lonlat.CLASS_NAME, \"OpenLayers.LonLat\", \"lonlat.CLASS_NAME is set correctly\");\n        t.eq( lonlat.lon, 6, \"lonlat.lon is set correctly\");\n        t.eq( lonlat.lat, 5, \"lonlat.lat is set correctly\");\n\n        // possible global Mercator projection values\n        lonlat = new OpenLayers.LonLat(20037508.33999999, -20037508.33999999);\n        t.eq( lonlat.lon, 20037508.34, \"lonlat.lon rounds correctly\");\n        t.eq( lonlat.lat, -20037508.34, \"lonlat.lat rounds correctly\");\n        \n        // allow construction from single arg\n        lonlat = new OpenLayers.LonLat([1, 2]);\n        t.eq(lonlat.lon, 1, \"lon from array\");\n        t.eq(lonlat.lat, 2, \"lat from array\");\n        \n    }\n    \n    function test_LonLat_constructorFromStrings (t) {\n        t.plan( 4 );\n        lonlat = new OpenLayers.LonLat(\"6\", \"5\");\n        t.ok( lonlat instanceof OpenLayers.LonLat, \"new OpenLayers.LonLat returns LonLat object\" );\n        t.eq( lonlat.CLASS_NAME, \"OpenLayers.LonLat\", \"lonlat.CLASS_NAME is set correctly\");\n        t.eq( lonlat.lon, 6, \"lonlat.lon is set correctly\");\n        t.eq( lonlat.lat, 5, \"lonlat.lat is set correctly\");\n    }\n\n    function test_LonLat_toString(t) {\n        t.plan( 1 );\n        lonlat = new OpenLayers.LonLat(5,6);\n        t.eq( lonlat.toString(), \"lon=5,lat=6\", \"lonlat.toString() returns correctly\");\n    }\n\n    function test_LonLat_toShortString(t) {\n        t.plan( 1 );\n        lonlat = new OpenLayers.LonLat(5,6);\n        t.eq( lonlat.toShortString(), \"5, 6\", \"lonlat.toShortString() returns correctly\");\n    }\n\n    function test_LonLat_clone(t) {\n        t.plan( 3 );\n        oldLonLat = new OpenLayers.LonLat(5,6);\n        lonlat = oldLonLat.clone();\n        t.ok( lonlat instanceof OpenLayers.LonLat, \"clone returns new OpenLayers.LonLat object\" );\n        t.ok( lonlat.equals(oldLonLat), \"lonlat is set correctly\");\n        \n        oldLonLat.lon = 100;\n        t.eq( lonlat.lon, 5, \"changing oldLonLat.lon doesn't change lonlat.lon\");\n    }\n\n    function test_LonLat_add(t) {\n        t.plan(8);\n\n        origLL = new OpenLayers.LonLat(10,100);\n        lonlatA = origLL.clone();\n\n        addpx = lonlatA.add(5, 50);\n        t.ok( lonlatA.equals(origLL), \"lonlatA is not modified by add operation\");\n\n        var ll = new OpenLayers.LonLat(15,150);\n        t.ok( addpx.equals(ll), \"addpx is set correctly\");\n        \n    //null values\n        try {\n            addpx = lonlatA.add(null, 50);\n        } catch(e) {\n            t.ok(\"exception thrown when passing null value to add()\");\n        }\n        t.ok( lonlatA.equals(origLL), \"lonlatA is not modified by erroneous add operation (null lon)\");\n \n        try {\n            addpx = lonlatA.add(5, null);\n        } catch(e) {\n            t.ok(\"exception thrown when passing null value to add()\");\n        }\n        t.ok( lonlatA.equals(origLL), \"lonlatA is not modified by erroneous add operation (null lat)\");\n\n        // string values\n        addpx = origLL.clone().add(\"5\", \"50\");\n        t.eq(addpx.lon, 15, \"addpx.lon is set correctly\");\n        t.eq(addpx.lat, 150, \"addpx.lat is set correctly\");\n    }\n    \n    function test_LonLat_equals(t) {\n        t.plan( 5 );\n        lonlat = new OpenLayers.LonLat(5,6);\n\n        ll = new OpenLayers.LonLat(5,6);\n        t.eq( lonlat.equals(ll), true, \"(5,6) equals (5,6)\");\n\n        ll = new OpenLayers.LonLat(1,6);\n        t.eq( lonlat.equals(ll), false, \"(5,6) does not equal (1,6)\");\n\n        ll = new OpenLayers.LonLat(5,2);\n        t.eq( lonlat.equals(ll), false, \"(5,6) does not equal (5,2)\");\n\n        ll = new OpenLayers.LonLat(1,2);\n        t.eq( lonlat.equals(ll), false, \"(5,6) does not equal (1,2)\");\n\n        t.ok( !lonlat.equals(null), \"equals() returns false on comparison to null\");\n\n    }\n\n    function test_LonLat_fromString(t) {\n        t.plan( 2 );\n        lonlat = OpenLayers.LonLat.fromString(\"6,5\");\n        t.ok( lonlat instanceof OpenLayers.LonLat, \"OpenLayers.LonLat.fromString() returns LonLat object\" );\n\n        var ll = new OpenLayers.LonLat(6, 5);\n        t.ok( lonlat.equals(ll), \"lonlat is set correctly\");\n    }\n    \n    function test_LonLat_fromArray(t) {\n        t.plan( 3 );\n        \n        // (1 test) must return a OpenLayers.LonLat-instance \n        lonlat = OpenLayers.LonLat.fromArray([6,5]);\n        t.ok( lonlat instanceof OpenLayers.LonLat, \"OpenLayers.LonLat.fromArray returns LonLat object\" );\n\n        var ll = new OpenLayers.LonLat(6, 5);\n        // (1 test) must return correct LonLat-object\n        t.ok( lonlat.equals(ll), \"lonlat is set correctly\");\n        \n        \n        // (1 test) check how function deals with illegal arguments, it should \n        // never throw an exception and always return an instance of \n        // OpenLayers.LonLat.\n        var unexpectedResult = false,\n            undef,\n            checkArgs = [\n                {},\n                '',\n                6,\n                false,\n                true,\n                [undef, 5],\n                [6, undef]\n            ],\n            returnedVal;\n            \n        try {\n            for(var i = 0, len = checkArgs.length; i < len; i++ ){\n                returnedVal = OpenLayers.LonLat.fromArray( checkArgs[i] );\n                if (!(returnedVal instanceof OpenLayers.LonLat) ) {\n                    unexpectedResult = true;\n                    break;\n                }\n            }\n            // no arguments at all\n            returnedVal = OpenLayers.LonLat.fromArray();\n            unexpectedResult = !(returnedVal instanceof OpenLayers.LonLat);\n        } catch(e) {\n            unexpectedResult = true;\n        } finally {\n            t.ok(!unexpectedResult, \"OpenLayers.LonLat.fromArray always returns an instance of OpenLayers.LonLat and doesn't throw an exception when called with unexpected argument.\");\n        }\n    }\n\n    function test_LonLat_transform(t) {\n        t.plan(10);\n        lonlat = new OpenLayers.LonLat(10, -10);\n        lonlat.transform(new OpenLayers.Projection(\"foo\"), new OpenLayers.Projection(\"Bar\")); \n        t.eq(lonlat.lon, 10, \"lon for null transform is the same\")\n        t.eq(lonlat.lat, -10, \"lat for null transform is the same\")\n        lonlat.transform(new OpenLayers.Projection(\"EPSG:4326\"), new OpenLayers.Projection(\"EPSG:900913\")); \n        t.eq(Math.round(lonlat.lon), 1113195, \"lon for spherical mercator transform is correct\");\n        t.eq(Math.round(lonlat.lat), -1118890, \"lat for spherical mercator correct\")\n        lonlat.transform(new OpenLayers.Projection(\"EPSG:900913\"), new OpenLayers.Projection(\"EPSG:4326\")); \n        t.eq(lonlat.lon, 10, \"lon for inverse spherical mercator transform is correct\");\n        t.eq(Math.round(lonlat.lat), -10, \"lat for inverse spherical mercator correct\")\n        \n        // transform with string\n        lonlat = new OpenLayers.LonLat(10, -10);\n        lonlat.transform(\"EPSG:4326\", \"EPSG:900913\"); \n        t.eq(Math.round(lonlat.lon), 1113195, \"(string) lon for spherical mercator transform is correct\");\n        t.eq(Math.round(lonlat.lat), -1118890, \"(string) lat for spherical mercator correct\")\n        lonlat.transform(\"EPSG:900913\", \"EPSG:4326\"); \n        t.eq(lonlat.lon, 10, \"(string) lon for inverse spherical mercator transform is correct\");\n        t.eq(Math.round(lonlat.lat), -10, \"(string) lat for inverse spherical mercator correct\")\n        \n    }\n    \n    function test_LonLat_wrapDateLine(t) {\n        t.plan( 6 );\n\n        var goodLL = new OpenLayers.LonLat(0,0);\n        var testLL, wrappedLL;\n\n  //bad maxextent\n        var maxExtent = null;\n\n        testLL = goodLL.clone();\n        wrappedLL = testLL.wrapDateLine(maxExtent);\n        t.ok(wrappedLL.equals(goodLL), \"wrapping a ll with a bad maxextent does nothing\");\n        \n        \n  //good maxextent\n        maxExtent = new OpenLayers.Bounds(-10,-10,10,10);\n\n    //inside\n        testLL = goodLL.clone();\n        wrappedLL = testLL.wrapDateLine(maxExtent);\n        t.ok(wrappedLL.equals(goodLL), \"wrapping a ll within the maxextent does nothing\");\n        \n    //left\n        testLL = goodLL.add(-20,0);\n        wrappedLL = testLL.wrapDateLine(maxExtent);\n        t.ok(wrappedLL.equals(goodLL), \"wrapping a ll once left of maxextent works\");\n        \n    //way left\n        testLL = goodLL.add(-200,0);\n        wrappedLL = testLL.wrapDateLine(maxExtent);\n        t.ok(wrappedLL.equals(goodLL), \"wrapping a ll way left of maxextent works\");\n\n    //right\n        testLL = goodLL.add(20,0);\n        wrappedLL = testLL.wrapDateLine(maxExtent);\n        t.ok(wrappedLL.equals(goodLL), \"wrapping a ll once right of maxextent works\");\n        \n    //way right\n        testLL = goodLL.add(200,0);\n        wrappedLL = testLL.wrapDateLine(maxExtent);\n        t.ok(wrappedLL.equals(goodLL), \"wrapping a ll way right of maxextent works\");\n\n    }\n\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/BaseTypes/Pixel.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var pixel; \n    \n    function test_Pixel_constructor (t) {\n        t.plan( 4 );\n        pixel = new OpenLayers.Pixel(5,6);\n        t.ok( pixel instanceof OpenLayers.Pixel, \"new OpenLayers.Pixel returns Pixel object\" );\n        t.eq( pixel.CLASS_NAME, \"OpenLayers.Pixel\", \"pixel.CLASS_NAME is set correctly\");\n        t.eq( pixel.x, 5, \"pixel.x is set correctly\");\n        t.eq( pixel.y, 6, \"pixel.y is set correctly\");\n    }\n\n    function test_Pixel_constructorFromString (t) {\n        t.plan( 4 );\n        pixel = new OpenLayers.Pixel(\"5\",\"6\");\n        t.ok( pixel instanceof OpenLayers.Pixel, \"new OpenLayers.Pixel returns Pixel object\" );\n        t.eq( pixel.CLASS_NAME, \"OpenLayers.Pixel\", \"pixel.CLASS_NAME is set correctly\");\n        t.eq( pixel.x, 5, \"pixel.x is set correctly\");\n        t.eq( pixel.y, 6, \"pixel.y is set correctly\");\n    }\n\n    function test_Pixel_toString(t) {\n        t.plan( 1 );\n        pixel = new OpenLayers.Pixel(5,6);\n        t.eq( pixel.toString(), \"x=5,y=6\", \"pixel.toString() returns correctly\");\n    }\n\n    function test_Pixel_clone(t) {\n        t.plan( 4 );\n        oldPixel = new OpenLayers.Pixel(5,6);\n        pixel = oldPixel.clone();\n        t.ok( pixel instanceof OpenLayers.Pixel, \"clone returns new OpenLayers.Pixel object\" );\n        t.eq( pixel.x, 5, \"pixel.x is set correctly\");\n        t.eq( pixel.y, 6, \"pixel.y is set correctly\");\n        \n        oldPixel.x = 100;\n        t.eq( pixel.x, 5, \"changing oldPixel.x doesn't change pixel.x\");\n    }\n\n    function test_Pixel_distanceTo(t) {\n        t.plan( 2 );\n        var px = new OpenLayers.Pixel(0,-2);\n        pixel = new OpenLayers.Pixel(0,0);\n        t.eq( pixel.distanceTo(px), 2, \"(0,0) distanceTo (0,-2) = 2\");\n\n        px = new OpenLayers.Pixel(-4,6);\n        pixel = new OpenLayers.Pixel(4,6);\n        t.eq( pixel.distanceTo(px), 8, \"(4,6) distanceTo (-4,6) = 8\");\n    }\n\n    function test_Pixel_equals(t) {\n        t.plan( 5 );\n        pixel = new OpenLayers.Pixel(5,6);\n\n        var px = new OpenLayers.Pixel(5,6);\n        t.eq( pixel.equals(px), true, \"(5,6) equals (5,6)\");\n\n        px = new OpenLayers.Pixel(1,6);\n        t.eq( pixel.equals(px), false, \"(5,6) does not equal (1,6)\");\n\n        px = new OpenLayers.Pixel(5,2);\n        t.eq( pixel.equals(px), false, \"(5,6) does not equal (5,2)\");\n\n        px = new OpenLayers.Pixel(1,2);\n        t.eq( pixel.equals(px), false, \"(5,6) does not equal (1,2)\");\n\n        t.ok( !pixel.equals(null), \"equals() returns false on comparison to null\");\n\n    }\n\n    function test_Pixel_add(t) {\n        t.plan( 6 );\n\n        var origPX = new OpenLayers.Pixel(5,6);\n        var oldPixel = origPX.clone();\n\n        var pixel = oldPixel.add(10,20);\n        \n        t.ok( oldPixel.equals(origPX), \"oldPixel not modified by add operation\");\n        \n        var px = new OpenLayers.Pixel(15,26);\n        t.ok( pixel.equals(px), \"returned pixel is correct\");\n\n    //null values\n        try {\n            pixel = oldPixel.add(null, 50);\n        } catch(e) {\n            t.ok(\"exception thrown when passing null value to add()\");\n        }\n        t.ok( oldPixel.equals(origPX), \"oldPixel is not modified by erroneous add operation (null x)\");\n \n        try {\n            addpx = oldPixel.add(5, null);\n        } catch(e) {\n            t.ok(\"exception thrown when passing null value to add()\");\n        }            \n        t.ok( oldPixel.equals(origPX), \"oldPixel is not modified by erroneous add operation (null y)\");\n    }\n\n    function test_Pixel_offset(t) {\n        t.plan( 4 );\n\n        var oldPixel = new OpenLayers.Pixel(5,6);\n        var offset = new OpenLayers.Pixel(10,20);\n\n        pixel = oldPixel.offset(offset);\n\n        t.eq( oldPixel.x, 5, \"oldPixel.x not modified by offset operation\");\n        t.eq( oldPixel.y, 6, \"oldPixel.y not modified by offset operation\");\n\n        t.eq( pixel.x, 15, \"pixel.x is set correctly\");\n        t.eq( pixel.y, 26, \"pixel.y is set correctly\");\n    }\n\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/BaseTypes/Size.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var Size; \n    \n    function test_Size_constructor (t) {\n        t.plan( 4 );\n        size = new OpenLayers.Size(5,6);\n        t.ok( size instanceof OpenLayers.Size, \"new OpenLayers.Size returns size object\" );\n        t.eq( size.CLASS_NAME, \"OpenLayers.Size\", \"size.CLASS_NAME is set correctly\");\n        t.eq( size.w, 5, \"size.w is set correctly\");\n        t.eq( size.h, 6, \"size.h is set correctly\");\n    }\n\n    function test_Size_constructorFromString (t) {\n        t.plan( 4 );\n        size = new OpenLayers.Size(\"5\",\"6\");\n        t.ok( size instanceof OpenLayers.Size, \"new OpenLayers.Size returns size object\" );\n        t.eq( size.CLASS_NAME, \"OpenLayers.Size\", \"size.CLASS_NAME is set correctly\");\n        t.eq( size.w, 5, \"size.w is set correctly\");\n        t.eq( size.h, 6, \"size.h is set correctly\");\n    }\n    \n    function test_Size_toString(t) {\n        t.plan( 1 );\n        size = new OpenLayers.Size(5,6);\n        t.eq( size.toString(), \"w=5,h=6\", \"size.toString() returns correctly\");\n    }\n\n    function test_Size_clone(t) {\n        t.plan( 3 );\n\n        oldSize = new OpenLayers.Size(5,6);\n        size = oldSize.clone();\n        t.ok( size instanceof OpenLayers.Size, \"clone returns new OpenLayers.Size object\" );\n        t.ok( size.equals(oldSize), \"new size is equal to old size correctly\");\n        \n        oldSize.w = 100;\n        t.eq( size.w, 5, \"changing oldSize.w doesn't change size.w\");\n    }\n\n     function test_Size_equals(t) {\n        t.plan( 5 );\n        size = new OpenLayers.Size(5,6);\n\n        sz = new OpenLayers.Size(5,6);\n        t.eq( size.equals(sz), true, \"(5,6) equals (5,6)\");\n\n        sz = new OpenLayers.Size(1,6);\n        t.eq( size.equals(sz), false, \"(5,6) does not equal (1,6)\");\n\n        sz = new OpenLayers.Size(5,2);\n        t.eq( size.equals(sz), false, \"(5,6) does not equal (5,2)\");\n\n        sz = new OpenLayers.Size(1,2);\n        t.eq( size.equals(sz), false, \"(5,6) does not equal (1,2)\");\n\n        t.ok( !size.equals(null), \"equals() returns false on comparison to null\");\n    }\n\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/BaseTypes.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_String_startsWith(t) {\n        t.plan(3);\n        \n        var str = \"chickenHead\";\n        \n        var test1 = \"chicken\";\n        var test2 = \"beet\";\n\n        t.ok(OpenLayers.String.startsWith(str, \"chicken\"),\n             \"'chickenHead' starts with 'chicken'\");\n        t.ok(!OpenLayers.String.startsWith(str, \"Head\"),\n             \"'chickenHead' does not start with 'Head'\");\n        t.ok(!OpenLayers.String.startsWith(str, \"beet\"),\n             \"'chickenHead' doesnt start with 'beet'\");\n    }\n    \n    function test_String_contains(t) {\n        t.plan(4);\n        \n        var str = \"chickenHead\";\n\n        t.ok(OpenLayers.String.contains(str, \"chicken\"),\n             \"(beginning) 'chickenHead' contains with 'chicken'\");\n        t.ok(OpenLayers.String.contains(str, \"ick\"),\n             \"(middle) 'chickenHead' contains with 'ick'\");\n        t.ok(OpenLayers.String.contains(str, \"Head\"),\n             \"(end) 'chickenHead' contains with 'Head'\");\n        t.ok(!OpenLayers.String.startsWith(str, \"beet\"),\n             \"'chickenHead' doesnt start with 'beet'\");\n    }\n    \n    function test_String_trim(t) {\n        t.plan(6);\n        \n        var str = \"chickenHead\";\n        t.eq(OpenLayers.String.trim(str),\n             \"chickenHead\", \"string with no extra whitespace is left alone\");\n\n        str = \"  chickenHead\";\n        t.eq(OpenLayers.String.trim(str),\n             \"chickenHead\", \"string with extra whitespace at beginning is trimmed correctly\");\n\n        str = \"chickenHead    \";\n        t.eq(OpenLayers.String.trim(str),\n             \"chickenHead\", \"string with extra whitespace at end is trimmed correctly\");\n\n        str = \"  chickenHead    \";\n        t.eq(OpenLayers.String.trim(str),\n             \"chickenHead\", \"string with extra whitespace at beginning and end is trimmed correctly\");\n\n        str = \"chicken\\nHead   \";\n        t.eq(OpenLayers.String.trim(str),\n             \"chicken\\nHead\", \"multi-line string with extra whitespace at end is trimmed correctly\");\n        str = \" \";\n        t.eq(OpenLayers.String.trim(str), \"\", \"whitespace string is trimmed correctly\");\n    }\n        \n    function test_String_camelize(t) {\n        t.plan(7);\n        \n        var str = \"chickenhead\";\n        t.eq(OpenLayers.String.camelize(str), \"chickenhead\", \"string with no hyphens is left alone\");\n\n        str = \"chicken-head\";\n        t.eq(OpenLayers.String.camelize(str), \"chickenHead\", \"string with one middle hyphen is camelized correctly\");\n\n        str = \"chicken-head-man\";\n        t.eq(OpenLayers.String.camelize(str), \"chickenHeadMan\", \"string with multiple middle hyphens is camelized correctly\");\n\n        str = \"-chickenhead\";\n        t.eq(OpenLayers.String.camelize(str), \"Chickenhead\", \"string with starting hyphen is camelized correctly (capitalized)\");\n\n        str = \"-chicken-head-man\";\n        t.eq(OpenLayers.String.camelize(str), \"ChickenHeadMan\", \"string with starting hypen and multiple middle hyphens is camelized correctly\");\n\n        str = \"chicken-\";\n        t.eq(OpenLayers.String.camelize(str), \"chicken\", \"string ending in hyphen is camelized correctly (hyphen dropped)\");\n\n        str = \"chicken-head-man-\";\n        t.eq(OpenLayers.String.camelize(str), \"chickenHeadMan\", \"string with multiple middle hyphens and end hyphen is camelized correctly (end hyphen dropped)\");\n\n\n    }\n    \n    function test_String_format(t) {\n        var unchanged = [\n            \"\", \"${ \", \"${\", \" ${\", \"${${\", \"${}\", \"${${}}\", \" ${ ${\",\n            \"}\", \"${${} }\"\n        ]\n        t.plan(7 + unchanged.length);\n\n        var format = OpenLayers.String.format;\n        \n        var expected;\n        for(var i=0; i<unchanged.length; ++i) {\n            expected = unchanged[i];\n            t.eq(format(expected), expected,\n                 \"'\" + expected + \"' left unchanged\");\n        }\n\n        t.eq(format(\"${foo} none\"),\n             \"undefined none\", \"undefined properties don't bomb\");\n\n        window.foo = \"bar\";\n        t.eq(format(\"${foo} none\"),\n             \"bar none\", \"window context used if none passed\");\n        \n        var context = {bar: \"foo\"};\n        t.eq(format(\"${bar} foo\", context), \"foo foo\",\n             \"properties accessed from context\");\n        \n        var context = {bar: \"foo\", foo: \"bar\"};\n        t.eq(format(\"a ${bar} is a ${foo}\", context), \"a foo is a bar\",\n             \"multiple properties replaced correctly\");\n        \n        // test context with properties that are functions\n        var context = {\n            bar: \"church\",\n            getDrunk: function() {\n                return arguments[0];\n            }\n        };\n        t.eq(\n            format(\"I go to the ${bar} to ${getDrunk}.\", context, [\"eat pretzels\"]),\n            \"I go to the church to eat pretzels.\",\n            \"function correctly called in context with arguments\"\n        );\n        \n        // test that things don't break\n        var context = {\n            meaning: function(truth) {\n                return truth;\n            }\n        };\n        t.eq(\n            format(\"In life, truth is ${meaning}.\", context),\n            \"In life, truth is undefined.\",\n            \"still works if arguments are not supplied\"\n        );\n\n        // test contexts where attribute values can be objects\n        var context = {\n            a: {\n                b: {\n                    c: 'd',\n                    e: function() {\n                        return 'f';\n                    }\n                }\n            }\n        };\n        t.eq(\n            format(\"${a.b.c} ${a.b.e} ${a.b.q} ${a} ${a...b...c} ${aa.b} ${a.bb.c}\", context),\n            \"d f undefined [object Object] d undefined undefined\",\n            \"attribute values that are objects are supported\"\n        );\n\n    }\n\n    function test_String_isNumeric(t) {\n        var cases = [\n            {value: \"3\", expect: true},\n            {value: \"+3\", expect: true},\n            {value: \"-3\", expect: true},\n            {value: \"3.0\", expect: true},\n            {value: \"+3.0\", expect: true},\n            {value: \"-3.0\", expect: true},\n            {value: \"6.02e23\", expect: true},\n            {value: \"+1.0e-100\", expect: true},\n            {value: \"-1.0e+100\", expect: true},\n            {value: \"1E100\", expect: true},\n            {value: null, expect: false},\n            {value: true, expect: false},\n            {value: false, expect: false},\n            {value: undefined, expect: false},\n            {value: \"\", expect: false},\n            {value: \"3 \", expect: false},\n            {value: \" 3\", expect: false},\n            {value: \"1e\", expect: false},\n            {value: \"1+e\", expect: false},\n            {value: \"1-e\", expect: false}\n        ];\n        t.plan(cases.length);\n        \n        var func = OpenLayers.String.isNumeric;\n        var obj, val, got, exp;\n        for(var i=0; i<cases.length; ++i) {\n            obj = cases[i];\n            val = obj.value;\n            exp = obj.expect;\n            got = func(val);\n            t.eq(got, exp, \"'\" + val + \"' returns \" + exp);\n        }\n        \n    }\n    \n    function test_Number_numericIf(t) {\n        var cases = [\n            {value: \"3\", expect: 3, expectWithTrim: 3},\n            {value: \"+3\", expect: 3, expectWithTrim: 3},\n            {value: \"-3\", expect: -3, expectWithTrim: -3},\n            {value: \"3.0\", expect: 3, expectWithTrim: 3},\n            {value: \"+3.0\", expect: 3, expectWithTrim: 3},\n            {value: \"-3.0\", expect: -3, expectWithTrim: -3},\n            {value: \"6.02e23\", expect: 6.02e23, expectWithTrim: 6.02e23},\n            {value: \"+1.0e-100\", expect: 1e-100, expectWithTrim: 1e-100},\n            {value: \"-1.0e+100\", expect: -1e100, expectWithTrim: -1e100},\n            {value: \"1E100\", expect: 1e100, expectWithTrim: 1e100},\n            {value: null, expect: null, expectWithTrim: null},\n            {value: true, expect: true, expectWithTrim: true},\n            {value: false, expect: false, expectWithTrim: false},\n            {value: undefined, expect: undefined, expectWithTrim: undefined},\n            {value: \"\", expect: \"\", expectWithTrim: \"\"},\n            {value: \"3 \", expect: \"3 \", expectWithTrim: 3},\n            {value: \" 3\", expect: \" 3\", expectWithTrim: 3},\n            {value: \"1e\", expect: \"1e\", expectWithTrim: \"1e\"},\n            {value: \"1+e\", expect: \"1+e\", expectWithTrim: \"1+e\"},\n            {value: \"1-e\", expect: \"1-e\", expectWithTrim: \"1-e\"},\n            {value: \" 27 \", expect: \" 27 \", expectWithTrim: 27},\n            {value: \" abc \", expect: \" abc \", expectWithTrim: \" abc \"}\n        ];\n        t.plan(cases.length*2);\n        \n        var func = OpenLayers.String.numericIf;\n        var obj, val, got, exp;\n        for(var i=0; i<cases.length; ++i) {\n            obj = cases[i];\n            val = obj.value;\n            exp = obj.expect;\n            got = func(val);\n            t.eq(got, exp, \"'\" + val + \"' returns \" + exp);\n            got = func(val, true);\n            exp = obj.expectWithTrim;\n            t.eq(got, exp, \"'\" + val + \"' returns \" + exp + \" with trimWhitespace true\");\n        }\n    }\n   \n   \n    function test_Number_limitSigDigs(t) {\n        t.plan(9);\n      \n        var num = 123456789; \n        t.eq(OpenLayers.Number.limitSigDigs(num), 0, \"passing 'null' as sig returns 0\");\n        t.eq(OpenLayers.Number.limitSigDigs(num, -1), 0, \"passing -1 as sig returns 0\");\n        t.eq(OpenLayers.Number.limitSigDigs(num, 0), 0, \"passing 0 as sig returns 0\");\n        \n        t.eq(OpenLayers.Number.limitSigDigs(num, 15), 123456789, \"passing sig greater than num digits in number returns number unmodified\");\n        \n        t.eq(OpenLayers.Number.limitSigDigs(num, 1), 100000000, \"passing sig 1 works\");\n        t.eq(OpenLayers.Number.limitSigDigs(num, 3), 123000000, \"passing middle sig works (rounds down)\");\n        t.eq(OpenLayers.Number.limitSigDigs(num, 5), 123460000, \"passing middle sig works (rounds up)\");\n        t.eq(OpenLayers.Number.limitSigDigs(num, 9), 123456789, \"passing sig equal to num digits in number works\");\n\n        num = 1234.56789;\n        t.eq(OpenLayers.Number.limitSigDigs(num, 5), 1234.6, \"running limSigDig() on a floating point number works fine\");\n        \n    }\n    \n    function test_Number_format(t) {\n        t.plan(9);\n        var format = OpenLayers.Number.format;\n        t.eq(format(12345), \"12,345\", \"formatting an integer number works\");\n        t.eq(format(12345, 3), \"12,345.000\", \"zero padding an integer works\");\n        t.eq(format(12345, null, \",\"), \"12,345\", \"adding thousands separator to an integer works\");\n        t.eq(format(12345, 0, \",\"), \"12,345\", \"adding thousands separator to an integer with defined 0 decimal places works\");\n\n        var num = 12345.6789\n        t.eq(format(num, null, \"\", \",\"), \"12345,6789\", \"only changing decimal separator and leaving everything else untouched works\");\n        t.eq(format(num, 5), \"12,345.67890\", \"filling up decimals with trailing zeroes works\");\n        t.eq(format(num, 3, \".\", \",\"), \"12.345,679\", \"rounding and changing decimal/thousands separator in function call works\");\n        t.eq(format(num, 0, \"\"), \"12346\", \"empty thousands separator in function call works\");\n        OpenLayers.Number.thousandsSeparator = \".\";\n        OpenLayers.Number.decimalSeparator = \",\";\n        t.eq(format(num, 3), \"12.345,679\", \"changing thousands/decimal separator globally works\");\n    }\n    \n    function test_Number_zeroPad(t) {\n        t.plan(6);\n        var pad = OpenLayers.Number.zeroPad;\n        t.eq(pad(15, 4), \"0015\", \"left padding works\");\n        t.eq(pad(15, 2), \"15\", \"no left padding when equal to number of digits\");\n        t.eq(pad(15, 1), \"15\", \"no left padding when less than number of digits\");\n        t.eq(pad(10, 5, 2), \"01010\", \"radix modified and padding works\");\n        t.eq(pad(10, 5, 8), \"00012\", \"radix modified and padding works\");\n        t.eq(pad(10, 5, 36), \"0000a\", \"radix modified and padding works\");\n    }\n\n    function test_Function_bind(t) {\n        t.plan(12);\n\n        g_obj = {};\n        g_Arg1 = {};\n        g_Arg2 = {};\n        g_Arg3 = {};\n        g_Arg4 = {};\n        var foo = function(x,y,z,a) {\n            t.ok(this == g_obj, \"context correctly set\");\n            t.ok(x == g_Arg1, \"arg1 passed correctly\");    \n            t.ok(y == g_Arg2, \"arg2 passed correctly\");    \n            t.ok(z == g_Arg3, \"arg3 passed correctly\");    \n            t.ok(a == g_Arg4, \"arg4 passed correctly\");    \n            t.eq(arguments.length, 4, \"correct number of arguments ((regression test for #876))\");\n        };\n\n        var newFoo = OpenLayers.Function.bind(foo, g_obj, g_Arg1, g_Arg2);\n\n        newFoo(g_Arg3, g_Arg4);\n        \n        //run again to make sure the arguments are handled correctly\n        newFoo(g_Arg3, g_Arg4);\n    }\n    \n    function test_Function_Void(t) {\n        \n        t.plan(1);\n        t.eq(OpenLayers.Function.Void(), undefined, \"returns undefined\");\n        \n    }\n\n    function test_Function_bindAsEventListener(t) {\n        t.plan(4);\n\n        g_obj = {};\n        g_Event = {};\n        g_WindowEvent = {};\n\n        var foo = function(x) {\n            t.ok(this == g_obj, \"context correctly set\");\n            g_X = x;\n        };\n\n        var newFoo = OpenLayers.Function.bindAsEventListener(foo, g_obj);\n        \n\n        g_X = null;\n        newFoo(g_Event);\n        t.ok(g_X == g_Event, \"event properly passed as first argument when event specified\");\n    \n        g_X = null;\n        newFoo();\n        t.ok(g_X == window.event, \"window.event properly passed as first argument when nothing specified\");\n    }\n\n    function test_Array_filter(t) {\n        \n        t.plan(8);\n\n        OpenLayers.Array.filter([\"foo\"], function(item, index, array) {\n            t.eq(item, \"foo\", \"callback called with proper item\");\n            t.eq(index, 0, \"callback called with proper index\");\n            t.eq(array, [\"foo\"], \"callback called with proper array\");\n            t.eq(this, {\"foo\": \"bar\"}, \"callback called with this set properly\");\n        }, {\"foo\": \"bar\"});\n\n        var array = [0, 1, 2, 3];\n        var select = OpenLayers.Array.filter(array, function(value) {\n            return value > 1;\n        });\n        t.eq(select, [2, 3], \"filter works for basic callback\");\n        t.eq(array, [0, 1, 2, 3], \"filter doesn't modify original\");\n        \n        var obj = {\n            test: function(value) {\n                if(value > 1) {\n                    return true;\n                }\n            }\n        };\n        var select = OpenLayers.Array.filter(array, function(value) {\n            return this.test(value);\n        }, obj);\n        t.eq(select, [2, 3], \"filter works for callback and caller\");\n        t.eq(array, [0, 1, 2, 3], \"filter doesn't modify original\");\n        \n        \n    }\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Console.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    function test_Console(t) {\n        \n        /**\n         * These tests only assure that OpenLayers works when not\n         * in debug mode.  It means that calls to OpenLayers.Console\n         * will not do anything in this case.  When OpenLayers is in\n         * debug mode, we assume that the Firebug extension or Firebug Lite\n         * works as advertised.\n         */\n        \n        // supported OpenLayers.Console methods\n        var methods = ['log', 'debug', 'info', 'warn', 'error', 'assert',\n               'dir', 'dirxml', 'trace', 'group', 'groupEnd', 'time',\n               'timeEnd', 'profile', 'profileEnd', 'count'];\n\n        t.plan(methods.length * 2);\n\n        var nothing, method;\n        for(var i=0; i<methods.length; ++i) {\n            method = OpenLayers.Console[methods[i]];\n            t.ok(method,\n                 \"OpenLayers.Console.\" + methods[i] + \" exists\");\n            nothing = OpenLayers.Console[methods[i]]();\n            t.eq(nothing, null,\n                 \"OpenLayers.Console.\" + methods[i] + \"() \" +\n                 \"call is harmless when not in debug mode\");\n        }\n\n    }\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/ArgParser.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n      function test_getParameters(t) {\n          t.plan(4);\n\n          var c = new OpenLayers.Control.ArgParser(), p;\n\n          p = c.getParameters('http://example.com?fook=foov&bark=barv');\n          t.eq(p, {fook: 'foov', bark: 'barv'}, 'a) params are correct');\n\n          p = c.getParameters('http://example.com#fook=foov&bark=barv');\n          t.eq(p, {fook: 'foov', bark: 'barv'}, 'b) params are correct');\n\n          p = c.getParameters('http://example.com?a=b&b=c#fook=foov&bark=barv');\n          t.eq(p, {a: 'b', b: 'c', fook: 'foov', bark: 'barv'},\n               'c) params are correct');\n\n          p = c.getParameters('http://example.com?a=b&b=c&fook=a&bark=b#fook=foov&bark=barv');\n          t.eq(p, {a: 'b', b: 'c', fook: 'foov', bark: 'barv'},\n               'd) params are correct');\n        }\n    </script>\n</head>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/Attribution.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var map;\n\n    function test_Control_Attribution_constructor (t) {\n        t.plan( 2 );\n    \n        control = new OpenLayers.Control.Attribution();\n        t.ok( control instanceof OpenLayers.Control.Attribution, \"new OpenLayers.Control returns object\" );\n        t.eq( control.displayClass,  \"olControlAttribution\", \"displayClass is correct\" );\n    }\n\n    function test_Control_Attribution_setBaseLayer (t) {\n        t.plan(1);\n\n        map = new OpenLayers.Map(\"map\");\n        map.addControl(control);\n        map.addLayer(new OpenLayers.Layer(\"name\",{'attribution':'My layer!', isBaseLayer: true}));\n        map.addLayer(new OpenLayers.Layer(\"name\",{'attribution':'My layer 2!', isBaseLayer: true}));\n        map.setBaseLayer(map.layers[1]);\n        t.eq(control.div.innerHTML, 'My layer 2!', \"Attribution correct with changed base layer\");\n    }\n\n    function test_Control_Attribution_draw (t) {\n        t.plan(3);\n\n        control = new OpenLayers.Control.Attribution();\n        map = new OpenLayers.Map(\"map\");\n        map.addControl(control);\n        map.addLayer(new OpenLayers.Layer(\"name\",{'attribution':'My layer!'}));\n        t.eq(control.div.innerHTML, 'My layer!', \"Attribution correct with one layer.\");\n        map.addLayer(new OpenLayers.Layer(\"name\", {'attribution':'My layer 2!'}));\n        t.eq(control.div.innerHTML, 'My layer!, My layer 2!', \"Attribution correct with two layers.\");\n        control.separator = '|';\n        control.template = \"Map Copyright (c) 2012 by Foo Bar; ${layers}\";\n        map.addLayer(new OpenLayers.Layer(\"name\",{'attribution':'My layer 3!'}));\n        t.eq(control.div.innerHTML, 'Map Copyright (c) 2012 by Foo Bar; My layer!|My layer 2!|My layer 3!', \"Attribution correct with three layers and diff seperator.\");\n    }\n\n    function test_Control_Attribution_object (t) {\n        t.plan(1);\n\n        control = new OpenLayers.Control.Attribution();\n        map = new OpenLayers.Map(\"map\");\n        map.addControl(control);\n\n        control.layerTemplate = '<a href=\"${href}\">${title}</a>';\n        map.addLayer(new OpenLayers.Layer(\"name\", {\n            attribution: {\n                title: \"test\",\n                href: \"http://test.org\"\n            }\n        }));\n        t.eq(control.div.innerHTML, '<a href=\"http://test.org\">test</a>', \"Attribution is correct with attribution object.\");\n    }\n\n    function test_Control_Attribution_no_duplicates(t) {\n        t.plan(2);\n\n        map = new OpenLayers.Map(\"map\");\n        map.addLayer(new OpenLayers.Layer(\"Company A: 1\",{'attribution':'company A'}));\n        map.addLayer(new OpenLayers.Layer(\"Company A: 2\",{'attribution':'company A'}));\n\n        control = new OpenLayers.Control.Attribution();\n        map.addControl(control);\n        t.eq(control.div.innerHTML, 'company A', \"Attribution not duplicated.\");\n\n        map.addLayer(new OpenLayers.Layer(\"Company B: 1\",{'attribution':'company B'}));\n        map.addLayer(new OpenLayers.Layer(\"Company A: 3\",{'attribution':'company A'}));\n        t.eq(control.div.innerHTML, 'company A, company B', \"Attribution correct with four layers (3 with same attribution).\");\n    }\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/Button.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n      function test_Control_Button_constructor (t) {\n          t.plan( 2 );\n      \n          control = new OpenLayers.Control.Button();\n          t.ok( control instanceof OpenLayers.Control.Button, \"new OpenLayers.Control returns object\" );\n          t.eq( control.displayClass, \"olControlButton\", \"displayClass is correct\" );\n      }\n    \n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/CacheRead.html",
    "content": "<html>\n<head>\n    <script>\n    /**\n    * Because browsers that implement requestAnimationFrame may not execute\n    * animation functions while a window is not displayed (e.g. in a hidden\n    * iframe as in these tests), we mask the native implementations here.  The\n    * native requestAnimationFrame functionality is tested in Util.html and\n    * in PanZoom.html (where a popup is opened before panning).  The tests\n    * here will test the fallback setTimeout implementation for animation.\n    */\n    window.requestAnimationFrame = \n        window.webkitRequestAnimationFrame =\n        window.mozRequestAnimationFrame =\n        window.oRequestAnimationFrame =\n        window.msRequestAnimationFrame = null;\n    </script>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    function test_addLayer_removeLayer(t) {\n        t.plan(6);\n        var control = new OpenLayers.Control.CacheRead();\n        var map = new OpenLayers.Map({\n            div: \"map\",\n            controls: [control],\n            layers: [\n                new OpenLayers.Layer.WMS(\"One\"),\n                new OpenLayers.Layer.WMS(\"Two\")\n            ]\n        });\n        t.ok(map.layers[0].events.listeners.tileloadstart, \"tileloadstart listener registered on layer One\");\n        t.ok(map.layers[1].events.listeners.tileloadstart, \"tileloadstart listener registered on layer Two\");        \n        control.destroy();\n        t.ok(!map.layers[1].events.listeners.tileloadstart.length, \"tileloadstart listener unregistered\");        \n        \n        control = new OpenLayers.Control.CacheRead({\n            fetchEvent: \"tileerror\",\n            layers: [map.layers[0]]\n        });\n        map.addControl(control);\n        t.ok(map.layers[0].events.listeners.tileerror, \"tileerror listener registered on layer One\");\n        t.ok(!map.layers[1].events.listeners.tileerror, \"tileerror listener not registered on layer Two\");\n        control.destroy();        \n        t.ok(!map.layers[0].events.listeners.tileerror.length, \"tileerror listener unregistered\");\n        \n        map.destroy();\n    }\n    \n    function test_fetch(t) {\n\n        if (!window.localStorage) {\n            t.plan(1);\n            var scope = {active: true};\n            t.eq(OpenLayers.Control.CacheRead.prototype.fetch.call(scope), undefined, \"no tiles fetched when localStorage is not supported.\");\n            return;\n        }\n        \n        t.plan(5);\n        \n        var data = \"data:image/gif;base64,R0lGODlhAQABAIAAAP7//wAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==\";\n        window.localStorage.setItem(\"olCache_foo/1/1/1\", data);\n        window.localStorage.setItem(\"olCache_bar/1/1/1\", data);\n\n        var layer1 = new OpenLayers.Layer.XYZ(\"One\", \"foo/${x}/${y}/${z}\");\n        var layer2 = new OpenLayers.Layer.XYZ(\"Two\", \"bar/${x}/${y}/${z}\", {isBaseLayer: false});\n        var control1 = new OpenLayers.Control.CacheRead({\n            layers: [layer1]\n        });\n        var control2 = new OpenLayers.Control.CacheRead({\n            layers: [layer2],\n            fetchEvent: \"tileerror\"\n        });\n\n        var map = new OpenLayers.Map({\n            div: \"map\",\n            projection: \"EPSG:900913\",\n            controls: [control1, control2],\n            layers: [layer1, layer2],\n            zoom: 1,\n            center: [0, 0]\n        });\n\n        OpenLayers.ProxyHost = \"proxy?url=\";\n        var tile = new OpenLayers.Tile.Image(layer1, new OpenLayers.LonLat(0, 0), new OpenLayers.Bounds(0, 0, 1, 1), \"proxy?url=foo/1/1/1\");\n        OpenLayers.Control.CacheWrite.urlMap[tile.url] = \"foo/1/1/1\";\n        \n        control1.fetch({tile: tile});\n        t.eq(tile.url, data, \"proxied url replaced with data uri for original url\");\n        delete OpenLayers.Control.CacheWrite.urlMap[tile.url];\n\n        t.delay_call(1, function() {\n            t.eq(layer1.grid[1][1].imgDiv.src, data, \"[tileloadstart] tile content from cache\");\n            t.ok(layer1.grid[0][0].imgDiv.src !== data, \"[tileloadstart] tile content from remote resource\");\n            t.eq(layer2.grid[1][1].imgDiv.src, data, \"[tileerror] tile content from cache\");\n            t.ok(layer2.grid[0][0].imgDiv.src !== data, \"[tileerror] tile content from remote resource\");\n\n            window.localStorage.removeItem(\"olCache_foo/1/1/1\");\n            window.localStorage.removeItem(\"olCache_bar/1/1/1\");\n            map.destroy();\n        });\n    }\n    \n    </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 400px; height: 250px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/CacheWrite.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    function test_addLayer_removeLayer(t) {\n        t.plan(6);\n        var control = new OpenLayers.Control.CacheWrite();\n        var map = new OpenLayers.Map({\n            div: \"map\",\n            controls: [control],\n            layers: [\n                new OpenLayers.Layer.WMS(\"One\"),\n                new OpenLayers.Layer.WMS(\"Two\")\n            ]\n        });\n        t.ok(map.layers[0].events.listeners.tileloaded, \"tileloaded listener registered on layer One\");\n        t.ok(map.layers[1].events.listeners.tileloaded, \"tileloaded listener registered on layer Two\");        \n        control.destroy();\n        t.ok(!map.layers[1].events.listeners.tileloaded.length, \"tileloaded listener unregistered\");        \n        \n        control = new OpenLayers.Control.CacheWrite({\n            layers: [map.layers[0]]\n        });\n        map.addControl(control);\n        t.ok(map.layers[0].events.listeners.tileloaded.length, \"tileloaded listener registered on layer One\");\n        t.ok(!map.layers[1].events.listeners.tileloaded.length, \"tileloaded listener not registered on layer Two\");\n        control.destroy();        \n        t.ok(!map.layers[0].events.listeners.tileloaded.length, \"tileloaded listener unregistered\");\n        \n        map.destroy();\n    }\n    \n    function test_cache_clearCache(t) {\n\n        if (!window.localStorage) {\n            t.plan(2);\n            var scope = {active: true};\n            t.eq(OpenLayers.Control.CacheWrite.prototype.cache.call(scope), undefined, \"no tiles cached when localStorage is not supported.\");\n            t.ok(!OpenLayers.Control.CacheWrite.clearCache(), \"clearCache does nothing when localStorage is not supported.\");\n            return;\n        }\n\n        t.plan(4);\n        OpenLayers.Control.CacheWrite.clearCache();\n        var length = window.localStorage.length;\n        \n        var tiles = 0;\n        var layer = new OpenLayers.Layer.XYZ(\"One\", \"../../img/blank.gif?${x},${y},${z}\", {\n            eventListeners: {\n                tileloaded: function() {\n                    tiles++;\n                }\n            }\n        });\n        var control = new OpenLayers.Control.CacheWrite({autoActivate: true});\n        var map = new OpenLayers.Map({\n            div: \"map\",\n            projection: \"EPSG:900913\",\n            controls: [control],\n            layers: [layer],\n            zoom: 1,\n            center: [0, 0]\n        });\n        t.delay_call(1, function() {\n            var canvasContext = layer.grid[1][1].getCanvasContext();\n            t.eq(window.localStorage.length, length + (canvasContext ? tiles : 0), \"cache filled with tiles\");\n            var url = layer.grid[1][1].url;\n            // content will be null for browsers that have localStorage but no canvas support\n            var content = canvasContext ? canvasContext.canvas.toDataURL(\"image/png\") : null;\n            t.eq(window.localStorage.getItem(\"olCache_\"+url), content, \"localStorage contains correct image data\");\n\n            layer.events.triggerEvent('tileloaded', {aborted: true, tile: layer.grid[1][1]});\n            t.eq(window.localStorage.length, length + (canvasContext ? tiles-1 : 0), \"tile aborted during load not cached\");\n            \n            var key = Math.random();\n            window.localStorage.setItem(key, \"bar\");\n            OpenLayers.Control.CacheWrite.clearCache();\n            t.eq(window.localStorage.length, length + 1, \"cache cleared, but foreign entries left in localStorage\");\n            window.localStorage.removeItem(key);\n            \n            map.destroy();\n        });\n    }\n    \n    </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 400px; height: 250px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/DragFeature.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    function test_Control_DragFeature_constructor(t) {\n        t.plan(3);\n        \n        var options = {\n            geometryTypes: \"foo\"\n        };\n        var layer = \"bar\";\n        var control = new OpenLayers.Control.DragFeature(layer, options);\n        t.ok(control instanceof OpenLayers.Control.DragFeature,\n             \"new OpenLayers.Control.DragFeature returns an instance\");\n        t.eq(control.layer, \"bar\",\n             \"constructor sets layer correctly\");        \n        t.eq(control.handlers.feature.geometryTypes, \"foo\",\n             \"constructor sets options correctly on feature handler\");\n    }\n    \n    function test_Control_DragFeature_destroy(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.DragFeature(layer);\n        control.handlers.drag.destroy = function() {\n            t.ok(true,\n                 \"control.destroy calls destroy on drag handler\");\n        }\n        control.handlers.feature.destroy = function() {\n            t.ok(true,\n                 \"control.destroy calls destroy on feature handler\");\n        }\n        \n        control.destroy();\n        \n    }\n    \n    function test_Control_DragFeature_activate(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.DragFeature(layer);\n        map.addControl(control);\n        t.ok(!control.handlers.feature.active,\n             \"feature handler is not active prior to activating control\");\n        control.activate();\n        t.ok(control.handlers.feature.active,\n             \"feature handler is active after activating control\");\n    }\n\n    function test_Control_DragFeature_deactivate(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.DragFeature(layer);\n        map.addControl(control);\n        \n        control.handlers.drag.deactivate = function() {\n            t.ok(true,\n                 \"control.deactivate calls deactivate on drag handler\");\n        }\n        control.handlers.feature.deactivate = function() {\n            t.ok(true,\n                 \"control.deactivate calls deactivate on feature handler\");\n        }\n        control.deactivate();\n    }\n    \n    function test_Control_DragFeature_over(t) {\n        t.plan(5);\n        var log = [];\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.DragFeature(layer, {\n            onEnter: function(f) { log.push({feature: f}); }\n        });\n        map.addControl(control);\n        \n        control.activate();\n        t.ok(!control.handlers.drag.active,\n             \"drag handler is not active before over a feature\");\n        \n        // simulate a mouseover on a feature\n        var feature = new OpenLayers.Feature.Vector();\n        feature.layer = layer;\n        layer.getFeatureFromEvent = function(evt) {\n            return feature;\n        }\n        map.events.triggerEvent(\"mousemove\", {type: \"mousemove\"});\n        \n        t.eq(control.feature.id, feature.id,\n             \"control gets the proper feature from the feature handler\");\n        t.ok(control.handlers.drag.active,\n             \"drag handler activated when over a feature\");\n        t.eq(log.length, 1,\n             \"onEnter called exactly once\");\n        t.eq(log[0].feature.id, feature.id,\n             \"onEnter called with expected feature\");\n    }\n\n    function test_Control_DragFeature_over_touch(t) {\n        t.plan(7);\n        var log = [];\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.DragFeature(layer, {\n            onEnter: function(f) { log.push({feature: f}); }\n        });\n        map.addControl(control);\n\n        control.activate();\n        t.ok(!control.handlers.drag.active,\n             \"drag handler is not active before touch on a feature\");\n\n        // simulate a touch on a feature\n        var feature = new OpenLayers.Feature.Vector();\n        feature.layer = layer;\n        layer.getFeatureFromEvent = function(evt) {\n            return feature;\n        }\n        map.events.triggerEvent(\"touchstart\", {type: \"touchstart\", touches: ['foo']});\n\n        t.eq(control.feature.id, feature.id,\n             \"control gets the proper feature from the feature handler\");\n        t.ok(control.handlers.drag.active,\n             \"drag handler activated when touch on a feature\");\n        t.ok(control.handlers.drag.started, \"drag handler has started\");\n        t.ok(!control.handlers.drag.stopDown, \"drag handler is not stopping down\");\n        t.eq(log.length, 1,\n             \"onEnter called exactly once\");\n        t.eq(log[0].feature.id, feature.id,\n             \"onEnter called with expected feature\");\n    }\n\n    function test_Control_DragFeature_down(t) {\n        t.plan(3);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.DragFeature(layer);\n        map.addControl(control);\n        \n        control.activate();\n        \n        // simulate a mouseover on a feature\n        var feature = new OpenLayers.Feature.Vector();\n        feature.layer = layer;\n        layer.getFeatureFromEvent = function(evt) {\n            return feature;\n        }\n        map.events.triggerEvent(\"mousemove\", {type: \"mousemove\"});\n\n        // simulate a mousedown on a feature\n        control.onStart = function(feat, pixel) {\n            t.eq(feat.id, feature.id, \"onStart called with the correct feature\");\n            t.eq(pixel, \"bar\", \"onStart called with the correct pixel\");\n        }\n        map.events.triggerEvent(\"mousedown\", {xy: \"bar\", which: 1, type: \"mousemove\"});\n\n        t.eq(control.lastPixel, \"bar\",\n             \"mousedown sets the lastPixel correctly\");\n    }\n\n    function test_Control_DragFeature_move(t) {\n        t.plan(3);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.DragFeature(layer);\n        map.addControl(control);\n        map.getResolution = function() {\n            return 2;\n        }\n\n        control.activate();\n\n        // mock up a feature - for the sole purpose of testing mousemove\n        var uid = Math.random();\n        layer.getFeatureFromEvent = function() {\n            var geom = new OpenLayers.Geometry.Point(Math.random(),\n                                                     Math.random());\n            geom.move = function(x, y) {\n                t.eq(x, 2, \"move called with dx * res\");\n                t.eq(y, -4, \"move called with -dy * res\");\n            };\n            var feature = new OpenLayers.Feature.Vector(geom);\n            feature.layer = layer;\n            feature.uid = uid;\n            return feature;\n        };\n        layer.drawFeature = function(feature) {\n            t.eq(feature.uid, uid,\n                 \"layer.drawFeature called with correct feature\");\n        };\n\n        // simulate a mouseover on a feature\n        map.events.triggerEvent(\"mousemove\", {type: \"mousemove\"});\n\n        // simulate a mousedown on a feature\n        var down = new OpenLayers.Pixel(0, 0);\n        map.events.triggerEvent(\"mousedown\", {xy: down, which: 1, type: \"mousemove\"});\n\n        // simulate a mousemove on a feature\n        var move = new OpenLayers.Pixel(1, 2);\n        map.events.triggerEvent(\"mousemove\", {xy: move, which: 1, type: \"mousemove\"});\n        \n    }\n\n    function test_Control_DragFeature_up(t) {\n        t.plan(6);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.DragFeature(layer);\n        map.addControl(control);\n\n        control.activate();\n\n        // simulate a mouseover on a feature\n        var feature = new OpenLayers.Feature.Vector();\n        feature.layer = layer;\n        layer.getFeatureFromEvent = function(evt) {\n            return feature;\n        }\n        map.events.triggerEvent(\"mousemove\", {type: \"mousemove\"});\n        t.eq(control.over, true,\n            \"mouseover on a feature sets the over property to true\");\n        t.ok(OpenLayers.Element.hasClass(control.map.viewPortDiv, \"olControlDragFeatureOver\"),\n            \"mouseover on a feature adds class name to map container\");\n        t.eq(control.handlers.drag.active, true,\n            \"mouseover on a feature activates drag handler\");\n\n        // simulate a mouse-up on the map, with the mouse still\n        // over the dragged feature\n        control.handlers.drag.started = true;\n        map.events.triggerEvent(\"mouseup\", {type: \"mouseup\"});\n        t.eq(control.handlers.drag.active, true,\n            \"mouseup while still over dragged feature does not deactivate drag handler\");\n\n        // simulate a mouse-up on the map, with the mouse out of\n        // the dragged feature\n        control.handlers.drag.started = true;\n        control.over = false;\n        map.events.triggerEvent(\"mouseup\", {type: \"mouseup\"});\n        t.eq(control.handlers.drag.active, false,\n            \"mouseup deactivates drag handler\");\n\n        control.deactivate();\n        t.ok(!OpenLayers.Element.hasClass(control.map.viewPortDiv, \"olControlDragFeatureOver\"),\n            \"deactivate removes class name from map container\");\n    }\n    \n    function test_Control_DragFeature_done(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.DragFeature(layer);\n        map.addControl(control);\n\n        control.activate();\n\n\n        // simulate a mouseover on a feature\n        var feature = new OpenLayers.Feature.Vector();\n        feature.layer = layer;\n        layer.getFeatureFromEvent = function() {\n            return feature;\n        };\n        map.events.triggerEvent(\"mousemove\", {type: \"mousemove\"});\n        t.eq(control.feature.id, feature.id,\n             \"feature is set on mouse over\");\n        control.doneDragging();\n        t.eq(control.feature.id, feature.id, \n          \"feature sticks around after doneDragging is called.\");\n        \n    }\n\n    function test_Control_DragFeature_out(t) {\n        t.plan(4);\n        var log = [];\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.DragFeature(layer, {\n            onLeave: function(f) { log.push({feature: f}); }\n        });\n        map.addControl(control);\n\n        control.activate();\n\n\n        // simulate a mouseover on a feature\n        var feature = new OpenLayers.Feature.Vector();\n        feature.layer = layer;\n        layer.getFeatureFromEvent = function() {\n            return feature;\n        };\n        map.events.triggerEvent(\"mousemove\", {type: \"mousemove\"});\n        t.eq(control.feature.id, feature.id,\n             \"feature is set on mouse over\");\n        \n        // simulate a mouseout on a feature\n        layer.getFeatureFromEvent = function() {\n            return null;\n        };\n        map.events.triggerEvent(\"mousemove\", {type: \"mousemove\"});\n        t.ok(control.feature == null,\n             \"feature is set to null on mouse out\");\n        t.eq(log.length, 1,\n             \"onLeave called exactly once\");\n        t.eq(log[0].feature.id, feature.id,\n             \"onLeave called with expected feature\");\n    }\n\n    function test_Control_DragFeature_out_touch(t) {\n        t.plan(5);\n        var log = [];\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.DragFeature(layer, {\n            onLeave: function(f) { log.push({feature: f}); }\n        });\n        map.addControl(control);\n\n        control.activate();\n\n        // simulate a touch on a feature\n        var feature = new OpenLayers.Feature.Vector();\n        feature.layer = layer;\n        layer.getFeatureFromEvent = function() {\n            return feature;\n        };\n        map.events.triggerEvent(\"touchstart\", {type: \"touchstart\", touches: ['foo']});\n        t.eq(control.feature.id, feature.id,\n             \"feature is set on mouse over\");\n\n        // simulate a touch outside the feature\n        layer.getFeatureFromEvent = function() {\n            return null;\n        };\n        map.events.triggerEvent(\"touchstart\", {type: \"touchstart\", touches: ['foo']});\n        t.ok(control.feature == null,\n             \"feature is set to null on mouse out\");\n        t.ok(control.handlers.drag.stopDown,\n             \"drag handler is stopping down again\");\n        t.eq(log.length, 1,\n             \"onLeave called exactly once\");\n        t.eq(log[0].feature.id, feature.id,\n             \"onLeave called with expected feature\");\n    }\n\n    function test_Control_DragFeature_click(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var feature = new OpenLayers.Feature.Vector();\n        feature.layer = layer;\n        var control = new OpenLayers.Control.DragFeature(layer);\n        map.addControl(control);\n\n        control.activate();\n\n        control.overFeature(feature);\n        control.handlers.feature.evt = {which: 1};\n        control.clickFeature(feature);\n        t.eq(control.handlers.drag.started, false, \"click after over does not start drag handler\");\n    }\n\n    </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 400px; height: 250px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/DragPan.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var map, control, layer; \n\n    function init_map() {\n        control = new OpenLayers.Control.DragPan();\n        map = new OpenLayers.Map(\"map\", {controls:[control]});\n        layer = new OpenLayers.Layer.WMS( \"OpenLayers WMS\", \n                    \"http://labs.metacarta.com/wms/vmap0\",\n                    {layers: 'basic'} );\n        map.addLayer(layer); \n        map.zoomToMaxExtent();\n        map.zoomIn();\n        control.activate();\n        return [map, control];\n    }    \n    function test_Control_DragPan_constructor (t) {\n        t.plan( 1 );\n    \n        control = new OpenLayers.Control.DragPan();\n        t.ok( control instanceof OpenLayers.Control.DragPan, \"new OpenLayers.Control returns object\" );\n    }\n    function test_Control_DragPan_drag (t) {\n        t.plan(4);\n        var data = init_map();\n        map = data[0]; control = data[1];\n        res = map.baseLayer.resolutions[map.getZoom()];\n        t.eq(map.center.lat, 0, \"Lat is 0 before drag\");\n        t.eq(map.center.lon, 0, \"Lon is 0 before drag\");\n        map.events.triggerEvent('mousedown', {'type':'mousedown', 'xy':new OpenLayers.Pixel(0,0), 'which':1});\n        map.events.triggerEvent('mousemove', {'type':'mousemove', 'xy':new OpenLayers.Pixel(5,5), 'which':1});\n        map.events.triggerEvent('mouseup', {'type':'mouseup', 'xy':new OpenLayers.Pixel(5,5), 'which':1});\n        \n        t.eq(map.getCenter().lat, res * 5, \"Lat is \" + (res * 5) + \" after drag\");\n        t.eq(map.getCenter().lon, res * -5, \"Lon is \" + (res * -5) + \" after drag\");\n    }\n    function test_Control_DragPan_drag_documentDrag (t) {\n        t.plan(4);\n        control = new OpenLayers.Control.DragPan({documentDrag: true});\n        map = new OpenLayers.Map(\"map\", {controls:[control]});\n        layer = new OpenLayers.Layer.WMS( \"OpenLayers WMS\",\n                    \"http://labs.metacarta.com/wms/vmap0\",\n                    {layers: 'basic'} );\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        map.zoomIn();\n        control.activate();\n\n        res = map.baseLayer.resolutions[map.getZoom()];\n        t.eq(map.center.lat, 0, \"Lat is 0 before drag\");\n        t.eq(map.center.lon, 0, \"Lon is 0 before drag\");\n        map.events.triggerEvent('mousedown', {'type':'mousedown', 'xy':new OpenLayers.Pixel(0,0), 'which':1});\n        map.events.triggerEvent('mousemove', {'type':'mousemove', 'xy':new OpenLayers.Pixel(5,5), 'which':1});\n        map.events.triggerEvent('mouseup', {'type':'mouseup', 'xy':new OpenLayers.Pixel(5,5), 'which':1});\n        \n        t.eq(map.getCenter().lat, res * 5, \"Lat is \" + (res * 5) + \" after drag\");\n        t.eq(map.getCenter().lon, res * -5, \"Lon is \" + (res * -5) + \" after drag\");\n    }\n    function test_Control_DragPan_click(t) {\n        t.plan(1);\n        var control = new OpenLayers.Control.DragPan();\n        var map = new OpenLayers.Map(\"map\", {controls:[control]});\n        var layer = new OpenLayers.Layer.WMS(\"OpenLayers WMS\", \n                                        \"http://labs.metacarta.com/wms/vmap0\",\n                                        {layers: 'basic'});\n        map.addLayer(layer); \n        map.zoomToMaxExtent();\n        map.zoomIn();\n        control.activate();\n        map.setCenter = function() {\n            t.ok(false, \"map.setCenter should not be called here\");\n        };\n        var xy = new OpenLayers.Pixel(0, 0);\n        var down = {\n            'type': 'mousedown',\n            'xy': xy,\n            'which': 1\n        };\n        var move = {\n            'type': 'mousemove',\n            'xy': xy,\n            'which': 1\n        };\n        var up = {\n            'type': 'mouseup',\n            'xy': xy,\n            'which': 1\n        };\n        map.events.triggerEvent('mousedown', down);\n        map.events.triggerEvent('mousemove', move);\n        map.events.triggerEvent('mouseup', up);\n        t.ok(true, \"clicking without moving the mouse does not call setCenter\");\n    }\n    \n\n  </script>\n</head>\n<body>\n    <a id=\"scale\" href=\"\">DragPan</a> <br />\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/DrawFeature.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(1);\n        var control = new OpenLayers.Control.DrawFeature(\"foo\", function() {});\n        t.ok(control instanceof OpenLayers.Control.DrawFeature,\n             \"constructor returns an instance\");\n    }\n    \n    function test_multi(t) {\n        t.plan(4);\n\n        var layer = new OpenLayers.Layer.Vector();\n        var control;\n        \n        // multi false by default\n        control = new OpenLayers.Control.DrawFeature(\n            layer, OpenLayers.Handler.Polygon\n        );\n        t.ok(!control.multi, \"control.multi false by default\");\n        t.ok(!control.handler.multi, \"handler.multi false by default\");\n        \n        // set on handler\n        control = new OpenLayers.Control.DrawFeature(\n            layer, OpenLayers.Handler.Polygon, {multi: true}\n        );\n        t.ok(control.handler.multi, \"handler.multi set from control options\");\n        \n        // respect handlerOptions\n        control = new OpenLayers.Control.DrawFeature(\n            layer, OpenLayers.Handler.Polygon,\n            {multi: true, handlerOptions: {multi: false}}\n        );\n        t.ok(!control.handler.multi, \"handlerOptions.multi respected\");\n\n    }\n\n    function test_rendererOptions(t) {\n        t.plan(2);\n        \n        var map = new OpenLayers.Map(\"map\");\n        var renderers = [\"Canvas\", \"VML\"];\n\n        var layer = new OpenLayers.Layer.Vector(null, {\n            renderers: renderers,\n            rendererOptions: {zIndexing: true},\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        \n        var control = new OpenLayers.Control.DrawFeature(\n            layer, OpenLayers.Handler.Polygon, {autoActivate: true}\n        );\n        map.addControl(control);\n\n        var sketchLayer = control.handler.layer;\n\n        t.eq(sketchLayer.renderers, renderers, \"Preferred renderers\");\n        t.eq(sketchLayer.rendererOptions.zIndexing, true, \"renderer options\");\n        \n        map.destroy();\n\n    }\n    \n    function test_drawFeature(t) {\n        t.plan(3);\n        var layer = new OpenLayers.Layer.Vector();\n        var control = new OpenLayers.Control.DrawFeature(layer, function() {});\n        var geom = {};\n        \n        layer.addFeatures = function(features) {\n            t.ok(features[0].geometry == geom, \"layer.addFeatures called\");\n            t.eq(features[0].state, OpenLayers.State.INSERT, \"layer state set\");\n        };\n        function handlefeatureadded(event) {\n            t.ok(event.feature.geometry == geom, \"featureadded triggered\");\n        }\n        control.events.on({\"featureadded\": handlefeatureadded});\n        control.drawFeature(geom);\n        control.events.un({\"featureadded\": handlefeatureadded});\n        \n    }\n    \n    function test_sketch_events(t) {\n        t.plan(11);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        var control = new OpenLayers.Control.DrawFeature(\n            layer, OpenLayers.Handler.Path, {\n                handlerOptions: {persist: true}\n            }\n        );\n        map.addLayer(layer);\n        map.addControl(control);\n        map.zoomToMaxExtent();\n        \n        var log;\n        layer.events.on({\n            sketchstarted: function(event) {\n                log['sketchstarted'] = event;\n            },\n            sketchmodified: function(event) {\n                log['sketchmodified'] = event;\n            },\n            sketchcomplete: function(event) {\n                log['sketchcomplete'] = event;\n            }\n        });\n        \n        // mock up draw/modify of a point\n        log = {};\n        control.activate();\n        t.eq(log, {}, \"[activate] no event triggered\");\n\n        log = {};\n        map.events.triggerEvent(\"mousemove\", {xy: new OpenLayers.Pixel(0, 0)});\n        t.eq(log.sketchstarted.type, \"sketchstarted\", \"[mousemove] sketchstarted triggered\");\n        t.geom_eq(log.sketchstarted.vertex, new OpenLayers.Geometry.Point(-200, 125), \"[mousemove] correct vertex\");\n        t.eq(log.sketchmodified.type, \"sketchmodified\", \"[mousemove] sketchmodified triggered\");\n        t.geom_eq(log.sketchmodified.vertex, new OpenLayers.Geometry.Point(-200, 125), \"[mousemove] correct vertex\");\n\n        map.events.triggerEvent(\"mousedown\", {xy: new OpenLayers.Pixel(0, 0)});\n\n        log = {};\n        map.events.triggerEvent(\"mouseup\", {xy: new OpenLayers.Pixel(0, 0)});\n        t.eq(log.sketchmodified.type, \"sketchmodified\", \"[mouseup] sketchmodified triggered\");\n        t.geom_eq(log.sketchmodified.vertex, new OpenLayers.Geometry.Point(-200, 125), \"[mouseup] correct vertex\");\n\n        log = {};\n        map.events.triggerEvent(\"mousemove\", {xy: new OpenLayers.Pixel(10, 10)});\n        t.eq(log.sketchmodified.type, \"sketchmodified\", \"[mousemove] sketchmodified triggered\");\n        t.geom_eq(log.sketchmodified.vertex, new OpenLayers.Geometry.Point(-190, 115), \"[mousemove] correct vertex\");\n\n        log = {};\n        map.events.triggerEvent(\"dblclick\", {xy: new OpenLayers.Pixel(10, 10)});\n        t.eq(log.sketchcomplete.type, \"sketchcomplete\", \"[dblclick] sketchcomplete triggered\");\n        t.geom_eq(log.sketchcomplete.feature.geometry,\n                  new OpenLayers.Geometry.LineString([\n                      new OpenLayers.Geometry.Point(-200, 125),\n                      new OpenLayers.Geometry.Point(-190, 115)\n                  ]),\n                  \"[dblclick] correct geometry\");\n\n        map.destroy();\n    }\n\n    </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 400px; height: 250px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/EditingToolbar.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    function test_ctor_draw(t) {\n        t.plan(5);\n        var map = new OpenLayers.Map('map');\n        var vLayer = new OpenLayers.Layer.Vector();\n        map.addLayer(vLayer);\n        \n        var editingToolbar = new OpenLayers.Control.EditingToolbar(vLayer, {\n            citeCompliant: \"foo\"\n        });\n        map.addControl(editingToolbar);\n        \n        t.ok(editingToolbar instanceof OpenLayers.Control.EditingToolbar,\n                \"new OpenLayers.Control.EditingToolbar returns object\" );\n        t.ok(editingToolbar.controls[0] instanceof OpenLayers.Control.Navigation,\n                \"EditingToolbar contains Control.Navigation object\" );\n        t.eq(editingToolbar.controls[0].active, true,\n                \"First control is active\" );\n        t.eq(editingToolbar.controls.length, 4,\n                \"EditingToolbar contains 4 Controls\" );\n        t.eq(editingToolbar.controls[1].handler.citeCompliant, \"foo\", \"citeCompliant option passed to handler correctly\")\n        \n        map.destroy();\n    }\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/Geolocate.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var map, control, centerLL\n        watch = null,\n        geolocation= {\n            getCurrentPosition: function(f) {\n                f({\n                    coords: { latitude: 10, longitude: 10 }\n                });\n            },\n            watchPosition: function(f) {\n                watch = true;\n            },\n            clearWatch: function() {\n                watch = null;\n            }\n        };\n\n    function test_initialize(t) {\n        t.plan(3);\n        control = new OpenLayers.Control.Geolocate({geolocationOptions: {foo: 'bar'}});\n        t.ok(control instanceof OpenLayers.Control.Geolocate,\n             \"new OpenLayers.Control returns object\" );\n        t.eq(control.displayClass, \"olControlGeolocate\", \"displayClass is correct\" );\n        t.eq(control.geolocationOptions.foo, 'bar',\n             'provided geolocation options are set in the geolocationOptions prop');\n    }\n    function test_bind(t) {\n        t.plan(3);\n        var control = new OpenLayers.Control.Geolocate({\n            geolocation: geolocation\n        });\n        control.events.register('locationupdated', null, function() {\n            t.ok(true, 'locationupdated event is fired when bound');\n        });\n        map.addControl(control);\n        control.activate();\n        var center = map.getCenter();\n        t.eq(center.lon, 10, 'bound control sets the map lon');\n        t.eq(center.lat, 10, 'bound control sets the map lat');\n        control.deactivate();\n        map.removeControl(control);\n        map.setCenter(centerLL);\n    }\n    function test_unbind(t) {\n        t.plan(3);\n        var control = new OpenLayers.Control.Geolocate({\n            geolocation: geolocation,\n            bind: false\n        });\n        control.events.register('locationupdated', null, function() {\n            t.ok(true, 'locationupdated event is fired when unbound');\n        });\n        map.addControl(control);\n        control.activate();\n        var center = map.getCenter();\n        t.eq(center.lon, 0, 'unbound control doesnt sets the map lon');\n        t.eq(center.lat, 0, 'unbound control doesnt sets the map lat');\n        control.deactivate();\n        map.removeControl(control);\n        map.setCenter(centerLL);\n    }\n    function test_getCurrentLocation(t) {\n        t.plan(5);\n        var control = new OpenLayers.Control.Geolocate({\n            geolocation: geolocation\n        });\n        map.addControl(control);\n        t.eq(control.getCurrentLocation(), false, 'getCurrentLocation return false if control hasnt been activated');\n        control.activate();\n        map.setCenter(centerLL);\n        t.eq(control.getCurrentLocation(), true, 'getCurrentLocation return true if control has been activated');\n        var center = map.getCenter();\n        t.eq(center.lon, 10, 'bound control sets the map lon when calling getCurrentLocation');\n        t.eq(center.lat, 10, 'bound control sets the map lat when calling getCurrentLocation');\n        control.deactivate();\n        map.removeControl(control);\n        map.setCenter(centerLL);\n        var control2 = new OpenLayers.Control.Geolocate({\n            geolocation: geolocation\n        });\n        map.addControl(control2);\n        t.eq(control2.getCurrentLocation(), false, 'getCurrentLocation return false if control is in watch mode');\n        control2.deactivate();\n        map.removeControl(control2);\n        map.setCenter(centerLL);\n    }\n    function test_watch(t) {\n        t.plan(2);\n        var control = new OpenLayers.Control.Geolocate({\n            geolocation: geolocation,\n            watch: true\n        });\n        map.addControl(control);\n        control.activate();\n        t.eq(watch, true, 'watch option makes calls to watchPosition');\n        control.deactivate();\n        t.eq(watch, null, 'deactivate control calls the clearwatch');\n        map.removeControl(control);\n        map.setCenter(centerLL);\n    }\n    function test_destroy(t) {\n        t.plan(1);\n        var control = new OpenLayers.Control.Geolocate({\n            geolocation: geolocation,\n            watch: true\n        });\n        control.activate();\n        control.destroy();\n        t.ok(control.active === false, \"control deactivated before being destroyed\");\n    }\n\n    function loader() {\n        map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS(\"Test Layer\",\n            \"http://labs.metacarta.com/wms-c/Basic.py?\",\n            {layers: \"basic\"});\n        map.addLayer(layer);\n        centerLL = new OpenLayers.LonLat(0,0);\n        map.setCenter(centerLL, 5);\n    }\n  </script>\n</head>\n<body onload=\"loader()\">\n    <div id=\"map\" style=\"width: 256px; height: 256px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/GetFeature.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    function test_Control_GetFeature_constructor(t) {\n        t.plan(3);\n        var protocol = \"foo\";\n        var control = new OpenLayers.Control.GetFeature({\n            protocol: protocol\n        });\n        t.ok(control instanceof OpenLayers.Control.GetFeature,\n             \"new OpenLayers.Control.SelectFeature returns an instance\");\n        t.eq(control.protocol, \"foo\",\n             \"constructor sets protocol correctly\");        \n\n        control = new OpenLayers.Control.GetFeature({\n            filterType: OpenLayers.Filter.Spatial.INTERSECTS\n        });\n        t.eq(control.filterType, OpenLayers.Filter.Spatial.INTERSECTS,\n             \"constructor sets filterType correctly\");        \n\n    }\n    \n    function test_Control_GetFeature_select(t) {\n        t.plan(10);\n        var cssAdded;\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.WMS(\"foo\", \"wms\", {\n            layers: \"foo\"\n        });\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(1,2));\n        var feature1 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,2));\n        var feature2 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(2,3));\n        var feature3 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(3,1));\n        var control = new OpenLayers.Control.GetFeature({\n            protocol: new OpenLayers.Protocol({\n                read: function(obj) {\n                    cssAdded = OpenLayers.Element.hasClass(map.viewPortDiv,\n                                                           \"olCursorWait\");\n                    obj.callback.call(obj.scope, {\n                        features: [feature1, feature2, feature3],\n                        success: function() {return true;}\n                    });\n                }\n            }),\n            box: true\n        });\n        map.addControl(control);\n\n        var singleTest = function(evt) {\n            t.eq(evt.feature.id, feature1.id, \"featureselected callback called with closest feature\");\n        }\n        cssAdded = false;\n        control.events.register(\"featureselected\", this, singleTest);\n        control.selectClick({xy: new OpenLayers.Pixel(200, 125)});\n        t.ok(cssAdded,\n             \"select adds CSS class (click)\");\n        t.ok(!OpenLayers.Element.hasClass(map.viewPortDiv, \"olCursorWait\"),\n             \"callback removes CSS class (click)\");\n        control.events.unregister(\"featureselected\", this, singleTest);\n\n        var count = 0;\n        var beforeFeatureSelected = function(evt) {\n             count++;\n             return count < 3;\n        }\n        var features = [];\n        var boxTest = function(evt) {\n            features.push(evt.feature);\n        }\n        var beforeFeaturesSelected = function(evt) {\n            t.eq(evt.features.length, 3, \"3 features passed to the beforefeaturesselected handler\");\n        }\n        var featuresSelected = function(evt) {\n            t.eq(evt.features.length, 2, \"2 features passed to the featuresselected handler\");\n        }\n        control.events.register(\"beforefeatureselected\", this, beforeFeatureSelected);\n        control.events.register(\"featureselected\", this, boxTest);\n        control.events.register(\"beforefeaturesselected\", this, beforeFeaturesSelected);\n        control.events.register(\"featuresselected\", this, featuresSelected);\n        cssAdded = false;\n        control.selectBox(new OpenLayers.Bounds(0,0,4,4));\n        control.events.unregister(\"beforefeatureselected\", this, beforeFeatureSelected);\n        control.events.unregister(\"featureselected\", this, boxTest);\n        control.events.unregister(\"beforefeaturesselected\", this, beforeFeaturesSelected);\n        control.events.unregister(\"featuresselected\", this, featuresSelected);\n        t.eq(features.length, 2, \"2 features inside box selected\");\n        t.eq(features[1].id, feature2.id, \"featureselected callback called with multiple features\");\n        t.ok(cssAdded,\n             \"select adds CSS class (box)\");\n        t.ok(!OpenLayers.Element.hasClass(map.viewPortDiv, \"olCursorWait\"),\n             \"callback removes CSS class (box)\");\n\n        // allow several features even for single click \n        control.single = false;\n        var multiplePointTest = function(evt) {\n            t.eq(evt.features.length, 3, \"3 features passed to the featuresselected handler\");\n        }\n        control.events.register(\"featuresselected\", this, multiplePointTest);\n        control.selectClick({xy: new OpenLayers.Pixel(200, 125)});\n        control.events.unregister(\"featuresselected\", this, multiplePointTest);\n    }\n    \n    function test_Control_GetFeature_hover(t) {\n        t.plan(9);\n        var cssAdded;\n        var abortedResponse = null;\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.WMS(\"foo\", \"wms\", {\n            layers: \"foo\"\n        });\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(1,2));\n        var feature1 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,2));\n        var feature2 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(2,3));\n        var response = new OpenLayers.Protocol.Response();\n        var control = new OpenLayers.Control.GetFeature({\n            protocol: new OpenLayers.Protocol({\n                read: function(obj){\n                    cssAdded = OpenLayers.Element.hasClass(map.viewPortDiv,\n                                                           \"olCursorWait\");\n                    obj.callback.call(obj.scope, {\n                        features: [feature1, feature2],\n                        success: function() {return true;}\n                    });\n                    return response;\n                },\n                abort: function(response) {\n                    abortedResponse = response;\n                }\n            }),\n            hover: true\n        });\n        map.addControl(control);\n\n        var hoverFeature;\n        var hoverTest = function(evt) {\n            t.eq(evt.feature.id, hoverFeature.id, \"hoverfeature callback called with closest feature\");\n        }\n        var outTest = function(evt) {\n            t.eq(evt.feature.id, feature1.id, \"outfeature callback called with previously hovered feature\");\n        }\n        control.events.register(\"hoverfeature\", this, hoverTest);\n        control.events.register(\"outfeature\", this, outTest);\n        hoverFeature = feature1;\n        control.selectHover({xy: new OpenLayers.Pixel(200, 125)});\n        t.ok(control.hoverResponse == response,\n             \"selectHover stores the protocol response in the hoverResponse property\");\n\n        hoverFeature = feature2;\n        cssAdded = false;\n        control.selectHover({xy: new OpenLayers.Pixel(400, 0)});\n        t.ok(cssAdded,\n             \"select adds CSS class (hover)\");\n        t.ok(!OpenLayers.Element.hasClass(map.viewPortDiv, \"olCursorWait\"),\n             \"callback removes CSS class (hover)\");\n\n        OpenLayers.Element.addClass(map.viewPortDiv, \"olCursorWait\");\n        control.cancelHover();\n        t.ok(abortedResponse == response,\n             \"cancelHover calls protocol.abort() with the expected response\");\n        t.eq(control.hoverResponse, null,\n             \"cancelHover sets this.hoverResponse to null\");\n        t.ok(!OpenLayers.Element.hasClass(map.viewPortDiv, \"olCursorWait\"),\n             \"cancelHover removes CSS class\");\n\n        control.events.unregister(\"hoverfeature\", this, hoverTest);\n        control.events.unregister(\"outfeature\", this, outTest);\n    }\n    \n    </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 400px; height: 250px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/Graticule.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script src=\"http://svn.osgeo.org/metacrs/proj4js/trunk/lib/proj4js-compressed.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(2);\n        var options = {};\n        var map = new OpenLayers.Map(\"map\",{projection:\"EPSG:4326\"});\n        var layer = new OpenLayers.Layer.WMS();\n        map.addLayers([layer]);\n\n        var control = new OpenLayers.Control.Graticule(options);\n        map.addControl(control);\n        map.zoomToMaxExtent();\n\n        t.ok(control.gratLayer instanceof OpenLayers.Layer.Vector,\n             \"constructor sets layer correctly\");\n        t.ok(control.gratLayer.features.length > 0,\n             \"graticule has features\");\n        control.destroy();\n    }\n    \n    function test_activate(t) {        \n        t.plan(7);\n        var map = new OpenLayers.Map(\"map\",{projection:\"EPSG:4326\"});\n        var layer = new OpenLayers.Layer.WMS();\n        map.addLayers([layer]);\n\n        var control = new OpenLayers.Control.Graticule({});\n        map.addControl(control);\n        map.zoomToMaxExtent();\n        \n        t.ok(control.gratLayer.visibility, \"Graticule layer is visible by default\"); \n        control.deactivate();\n        t.ok(control.gratLayer.map == null, \n            \"Graticule layer is not in map when control is deactivated\"); \n        control.destroy();\n        \n        var control2 = new OpenLayers.Control.Graticule({autoActivate:false});\n        map.addControl(control2);\n        t.ok(control2.gratLayer.map == null, \n            \"Graticule layer is not in map when autoActivate:false\"); \n        t.ok(control2.gratLayer.features.length == 0, \n            \"Graticule layer is empty when autoActivate:false\");\n        control2.activate();\n        t.ok(control2.gratLayer.map != null, \n            \"Graticule layer is on map when control is activated\");    \n        t.ok(control2.gratLayer.features.length > 0,\n            \"Graticule features refreshed after control is activated\");\n        control2.gratLayer.setVisibility(false);\n       \n        control2.destroy();\n        t.ok(control2.gratLayer == null, \n            \"Graticule layer is destroyed when control is destroyed\");    \n            \n        map.destroy();        \n    }\n\n    </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 400px; height: 250px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/KeyboardDefaults.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var map; \n    function test_Control_KeyboardDefaults_constructor (t) {\n        t.plan( 2 );\n    \n        control = new OpenLayers.Control.KeyboardDefaults();\n        t.ok( control instanceof OpenLayers.Control.KeyboardDefaults, \n                \"new OpenLayers.Control.KeyboardDefaults returns object\" );\n        t.eq( control.displayClass,  \"olControlKeyboardDefaults\", \"displayClass is correct\" );\n    }\n\n    function test_Control_KeyboardDefaults_destroy (t) {\n        t.plan(2);\n    \n        map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control.KeyboardDefaults();\n        map.addControl(control);\n        t.ok(control.handler != null, \"control.handler is created\");\n        control.destroy();\n        t.ok(control.handler == null, \"control.handler is null after destroy\");\n        map.destroy();\n    }\n\n    function test_Control_KeyboardDefaults_addControl (t) {\n        t.plan( 4 );\n\n        map = new OpenLayers.Map('map');\n        control = new OpenLayers.Control.KeyboardDefaults();\n        t.ok( control instanceof OpenLayers.Control.KeyboardDefaults, \n                \"new OpenLayers.Control.KeyboardDefaults returns object\" );\n        t.ok( map instanceof OpenLayers.Map, \n                \"new OpenLayers.Map creates map\" );\n        map.addControl(control);\n        t.ok( control.map === map, \"Control.map is set to the map object\" );\n        t.ok( OpenLayers.Util.indexOf(map.controls, control), \"map.controls contains control\" );\n    }\n\n    /* When interpretting\n     * the keycodes below (including the comments associated with them),\n     * consult the URL below. For instance, the Safari browser returns\n     * \"IE keycodes\", and so is supported by any keycode labeled \"IE\".\n     * \n     * Very informative URL:\n     *    http://unixpapa.com/js/key.html\n     */\n    function test_Control_KeyboardDefaults_KeyDownEvent (t) {\n        t.plan( 25 );\n\n        var evt = {which: 1}, pans = [], zoomIns = 0, zoomOuts = 0;\n\n        map = new OpenLayers.Map('map');\n\n        // mock \"pan\", \"zoomIn\" and \"zoomOut\"\n        map.pan = function(dx, dy) {\n            pans.push({dx: dx, dy: dy});\n        };\n        map.zoomIn = function() {\n            zoomIns++;\n        };\n        map.zoomOut = function() {\n            zoomOuts++;\n        };\n\n        var layer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(layer);\n\n        var control = new OpenLayers.Control.KeyboardDefaults({\n            slideFactor: 100\n        });\n        map.addControl(control);\n        \n        map.setCenter(new OpenLayers.LonLat(0, 0), 4);\n\n        // Start new test.\n        evt.keyCode = OpenLayers.Event.KEY_LEFT;\n        control.defaultKeyPress(evt);\n        t.eq(pans.length, 1, '[KEY_LEFT] pan called once');\n        t.eq(pans[0], {dx: -100, dy: 0},\n             '[KEY LEFT] pan called with expected args');\n\n        evt.keyCode = OpenLayers.Event.KEY_RIGHT;\n        control.defaultKeyPress(evt);\n        t.eq(pans.length, 2, '[KEY_RIGHT] pan called once');\n        t.eq(pans[1], {dx: 100, dy: 0},\n             '[KEY RIGHT] pan called with expected args');\n\n        evt.keyCode = OpenLayers.Event.KEY_UP;\n        control.defaultKeyPress(evt);\n        t.eq(pans.length, 3, '[KEY_UP] pan called once');\n        t.eq(pans[2], {dx: 0, dy: -100},\n             '[KEY UP] pan called with expected args');\n\n        evt.keyCode = OpenLayers.Event.KEY_DOWN;\n        control.defaultKeyPress(evt);\n        t.eq(pans.length, 4, '[KEY_DOWN] pan called once');\n        t.eq(pans[3], {dx: 0, dy: 100},\n             '[KEY DOWN] pan called with expected args');\n\n        evt.keyCode = 33;\n        control.defaultKeyPress(evt);\n        t.eq(pans.length, 5, '[33] pan called once');\n        t.eq(pans[4], {dx: 0, dy: -384},\n             '[33] pan called with expected args');\n\n        evt.keyCode = 34;\n        control.defaultKeyPress(evt);\n        t.eq(pans.length, 6, '[34] pan called once');\n        t.eq(pans[5], {dx: 0, dy: 384},\n             '[34] pan called with expected args');\n\n        evt.keyCode = 35;\n        control.defaultKeyPress(evt);\n        t.eq(pans.length, 7, '[35] pan called once');\n        t.eq(pans[6], {dx: 768, dy: 0},\n             '[35] pan called with expected args');\n\n        evt.keyCode = 36;\n        control.defaultKeyPress(evt);\n        t.eq(pans.length, 8, '[36] pan called once');\n        t.eq(pans[7], {dx: -768, dy: 0},\n             '[36] pan called with expected args');\n\n        evt.keyCode = 43;\n        control.defaultKeyPress(evt);\n        t.eq(zoomIns, 1, '[43] zoomIn called once');\n\n        evt.keyCode = 61;\n        control.defaultKeyPress(evt);\n        t.eq(zoomIns, 2, '[61] zoomIn called once');\n\n        evt.keyCode = 187;\n        control.defaultKeyPress(evt);\n        t.eq(zoomIns, 3, '[187] zoomIn called once');\n\n        evt.keyCode = 107;\n        control.defaultKeyPress(evt);\n        t.eq(zoomIns, 4, '[107] zoomIn called once');\n\n        evt.keyCode = 107;\n        control.defaultKeyPress(evt);\n        t.eq(zoomIns, 5, '[107] zoomIn called once');\n\n        evt.keyCode = 45;\n        control.defaultKeyPress(evt);\n        t.eq(zoomOuts, 1, '[45] zoomOut called once');\n\n        evt.keyCode = 109;\n        control.defaultKeyPress(evt);\n        t.eq(zoomOuts, 2, '[109] zoomOut called once');\n\n        evt.keyCode = 189;\n        control.defaultKeyPress(evt);\n        t.eq(zoomOuts, 3, '[189] zoomOut called once');\n\n        evt.keyCode = 95;\n        control.defaultKeyPress(evt);\n        t.eq(zoomOuts, 4, '[95] zoomOut called once');\n\n        map.destroy();\n    }\n\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/LayerSwitcher.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var map; \n    OpenLayers.Lang.setCode('en');\n\n    function test_Control_LayerSwitcher_constructor (t) {\n        t.plan( 2 );\n    \n        control = new OpenLayers.Control.LayerSwitcher();\n        t.ok( control instanceof OpenLayers.Control.LayerSwitcher, \"new OpenLayers.Control.LayerSwitcher returns object\" );\n        t.eq( control.displayClass,  \"olControlLayerSwitcher\", \"displayClass is correct\" );\n    }\n\n    function test_Control_LayerSwitcher_draw (t) {\n        t.plan( 2 );\n\n        map = new OpenLayers.Map('map');\n        control = new OpenLayers.Control.LayerSwitcher();\n        map.addControl(control);\n\n        var div = control.draw();\n        t.ok( control.div != null, \"draw makes a div\" );\n        t.ok( div != null, \"draw returns its div\" );\n    }\n    function test_Control_LayerSwitcher_outsideViewport (t) {\n        t.plan( 4 );\n\n        map = new OpenLayers.Map('map');\n        control = new OpenLayers.Control.LayerSwitcher({'div':OpenLayers.Util.getElement('layerswitcher')});\n        map.addControl(control);\n        t.eq(control.div.style.width, \"250px\", \"Div is not minimized when added.\");\n        t.ok(control.events.element && control.events.listeners.buttonclick, \"[outside] Events instance attached to div and has buttonclick event\");\n        control = new OpenLayers.Control.LayerSwitcher();\n        map.addControl(control);\n        t.eq(control.div.style.width, \"0px\", \"Div is minimized when added.\");\n        t.ok(!control.events.element && map.events.listeners.buttonclick, \"[inside] Events instance not attached to div and buttonclick event registered on map\");\n    }\n \n    function test_Control_LayerSwitcher_loadContents(t) {\n\n        t.plan( 10 );\n\n        map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS(\"WMS\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(layer);\n\n        markers = new OpenLayers.Layer.Markers(\"markers\");\n        map.addLayer(markers);\n\n        control = new OpenLayers.Control.LayerSwitcher();\n        map.addControl(control);\n\n        t.ok(control.layersDiv != null, \"correctly makes layers div\");\n        t.ok(OpenLayers.Element.hasClass(control.layersDiv, \"layersDiv\"),\n             \"layers div has class layersDiv\");\n        t.ok(control.baseLayersDiv != null, \"correctly makes layers div\");\n        t.ok(OpenLayers.Element.hasClass(control.baseLayersDiv, \"baseLayersDiv\"),\n             \"base layers div has class baseLayersDiv\");\n        t.ok(control.dataLayersDiv != null, \"correctly makes layers div\");\n        t.ok(OpenLayers.Element.hasClass(control.dataLayersDiv, \"dataLayersDiv\"),\n             \"data layers div has class dataLayersDiv\");\n        t.ok(control.maximizeDiv != null, \"correctly makes resize div\");\n        t.ok(OpenLayers.Element.hasClass(control.maximizeDiv, \"maximizeDiv\"),\n             \"maximize div has class maximizeDiv\");\n        t.ok(control.minimizeDiv != null, \"correctly makes resize div\");\n        t.ok(OpenLayers.Element.hasClass(control.minimizeDiv, \"minimizeDiv\"),\n             \"minimize div has class minmizeDiv\");\n    }\n\n\n    function test_Control_LayerSwitcher_redraw (t) {\n\n        t.plan( (OpenLayers.BROWSER_NAME == \"opera\" ? 9 : 19 ) );\n\n        map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS(\"WMS\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(layer);\n\n        markers = new OpenLayers.Layer.Markers(\"markers\");\n        map.addLayer(markers);\n\n        control = new OpenLayers.Control.LayerSwitcher();\n        map.addControl(control);\n\n        var wmsInput = control.div.childNodes[0].childNodes[1].childNodes[0];\n        t.ok(wmsInput != null, \"correctly makes an input for wms layer\");\n        t.eq(wmsInput.type, \"radio\", \"wms correctly made a radio button\");\n        t.eq(wmsInput.name, control.id + \"_baseLayers\", \"wms correctly named\");\n        t.eq(wmsInput.value, layer.name, \"wms correctly valued\");\n        \n        var markersInput = control.div.childNodes[0].childNodes[3].childNodes[0];\n        t.ok(markersInput != null, \"correctly makes an input for markers layer\");\n        t.eq(markersInput.type, \"checkbox\", \"wms correctly made a radio button\");\n        t.eq(markersInput.name, markers.name, \"wms correctly named\");\n        t.eq(markersInput.value, markers.name, \"wms correctly valued\");\n\n        t.eq(false, control.checkRedraw(), \"check redraw is false\");\n        if (OpenLayers.BROWSER_NAME != \"opera\") { \n            control = new OpenLayers.Control.LayerSwitcher();\n            var myredraw = control.redraw;\n            control.redraw = function() { \n                t.ok(true, \"redraw called when setting vis\");\n            }\n            map.addControl(control); \n            var func = OpenLayers.Function.bind(myredraw, control);\n            func();\n            markers.setVisibility(false); \n            t.eq(control.checkRedraw(), true, \"check redraw is true after changing layer and not letting redraw happen.\");\n            map.removeControl(control);\n            \n            control = new OpenLayers.Control.LayerSwitcher();\n            var myredraw = control.redraw;\n            control.redraw = function() { \n                t.ok(true, \"redraw called when setting inRange\");\n            }\n            map.addControl(control); \n            var func = OpenLayers.Function.bind(myredraw, control);\n            func();\n            markers.inRange = false;\n            t.eq(control.checkRedraw(), true, \"check redraw is true after changing layer.inRange and not letting redraw happen.\");\n            map.removeControl(control);\n            \n            control = new OpenLayers.Control.LayerSwitcher();\n            var myredraw = control.redraw;\n            control.redraw = function() { \n                t.ok(true, \"redraw called when raising base layer \");\n            }\n            \n            map.addControl(control); \n            var func = OpenLayers.Function.bind(myredraw, control);\n            func();\n            map.raiseLayer(layer, 1);\n            t.eq(control.checkRedraw(), true, \"check redraw is true after changing layer.inRange and not letting redraw happen.\");\n            map.removeControl(control);\n        } else {\n            t.debug_print(\"FIXME: Some LayerSwitcher tests fail in Opera.\");\n        }    \n\n    }\n    function test_Control_LayerSwitcher_ascending (t) {\n\n        t.plan( 4 );\n\n        map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS(\"WMS\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(layer);\n\n        markers = new OpenLayers.Layer.Markers(\"markers\");\n        map.addLayer(markers);\n\n        control = new OpenLayers.Control.LayerSwitcher();\n        map.addControl(control);\n        control2 = new OpenLayers.Control.LayerSwitcher({'ascending':false});\n        map.addControl(control2);\n        t.ok(control.div.childNodes[0].childNodes[0].innerHTML.match(\"Base Layer\"), \"Base Layers first in LayerSwitcher with ascending true\");\n        t.ok(control.div.childNodes[0].childNodes[2].innerHTML.match(\"Overlays\"), \"Overlays in LayerSwitcher with ascending true\");\n        t.ok(control2.div.childNodes[0].childNodes[2].innerHTML.match(\"Base Layer\"), \"Base Layers last in LayerSwitcher with ascending false\");\n        t.ok(control2.div.childNodes[0].childNodes[0].innerHTML.match(\"Overlays\"), \"Base Layers last in LayerSwitcher with ascending false\");\n    }\n    \n    function test_Control_LayerSwitcher_displayInLayerSwitcher (t) {\n\n        t.plan( 2 );\n\n        map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS(\"WMS\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"}, {'displayInLayerSwitcher': false});\n        map.addLayer(layer);\n\n        control = new OpenLayers.Control.LayerSwitcher();\n        map.addControl(control);\n        t.eq(control.div.childNodes[0].childNodes[0].style.display, \"none\" , \"Base layer display off when no visble base layer\");\n        \n        map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS(\"WMS\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(layer);\n\n        control = new OpenLayers.Control.LayerSwitcher();\n        map.addControl(control);\n        t.eq(control.div.childNodes[0].childNodes[0].style.display, \"\" , \"Base layer display on when visble base layer\");\n    }\n\n    // See e.g. https://github.com/openlayers/openlayers/issues/866\n    function test_Control_LayerSwitcher_validIds(t){\n        t.plan(2);\n\n        // setup\n        var layername = \"Name with spaces & illegal characters * + ~ ` ' ? )\",\n            map = new OpenLayers.Map(\"map\", {\n                controls: [\n                    new OpenLayers.Control.LayerSwitcher()\n                ],\n                layers: [\n                    new OpenLayers.Layer.WMS(\n                        layername,\n                        \"../../img/blank.gif\"\n                    ),\n                    // add another layer with the same name, the generated id\n                    // must be different\n                    new OpenLayers.Layer.WMS(\n                        layername,\n                        \"../../img/blank.gif\"\n                    )\n                ]\n            });\n\n        var baselayerDiv = map.controls[0].div.childNodes[0].childNodes[1],\n            firstGeneratedInputId = baselayerDiv.childNodes[0].id,\n            secondGeneratedInputId = baselayerDiv.childNodes[1].id,\n            // legal ids start with a letter and are followed only by word\n            // characters (letters, digits, and underscores) plus the dash (-)\n            // This is only a subset of all allowed charcters inside of ids.\n            allowedIdChars = (/^[a-zA-Z]{1}[\\w-]*$/g);\n\n        // tests\n        // validity\n        t.ok(\n            allowedIdChars.test(firstGeneratedInputId),\n            \"id only contains letters, digits, underscores and dashes. It \" +\n                \"starts with a letter.\"\n        );\n        // uniqueness\n        t.ok(\n            firstGeneratedInputId !== secondGeneratedInputId,\n            \"generated ids are different even for equal layernames\"\n        );\n\n        // teardown\n        map.destroy();\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n    <div id=\"layerswitcher\" style=\"width:250px; height:256px;\" />\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/Measure.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        \n        t.plan(1);\n        \n        var map = new OpenLayers.Map(\"map\");\n        var control = new OpenLayers.Control.Measure(\n            OpenLayers.Handler.Path, {persist: true}\n        );\n        map.addControl(control);\n        \n        t.eq(control.persist, true, \"passing persist to constructor sets persist on handler\");\n        \n        map.destroy();\n        \n    }\n    \n    function test_cancel(t) {\n        \n        t.plan(4);\n        \n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer(null, {\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        \n        var control = new OpenLayers.Control.Measure(\n            OpenLayers.Handler.Path, {persist: true}\n        );\n        map.addControl(control);\n        \n        control.activate();\n\n        try {\n            control.cancel();\n            t.ok(true, \"calling cancel before drawing works\");\n        } catch(err) {\n            t.fail(\"calling cancel before drawing causes trouble: \" + err);\n        }\n        t.eq(control.active, true, \"control remains active after cancel\");\n        \n        // create a simple measurement\n        function trigger(type, x, y) {\n            map.events.triggerEvent(type, {\n                xy: new OpenLayers.Pixel(x, y)\n            })\n        };\n\n        trigger(\"mousemove\", 0, 0);\n        // keep a reference to the line being drawn\n        var line = control.handler.line;\n        trigger(\"mousedown\", 0, 0);\n        trigger(\"mouseup\", 0, 0);\n        trigger(\"mousemove\", 10, 10);\n        trigger(\"mousedown\", 10, 10);\n        trigger(\"mouseup\", 10, 10);\n        trigger(\"dblclick\", 10, 10);\n\n        // the geometry is finalized, we first confirm that it is persisted\n        t.ok(line.layer === control.handler.layer, \"feature persists\");\n        \n        // cancel and see that sketch is gone\n        control.cancel();\n        t.eq(line.layer, null, \"feature is gone after cancel\");\n\n        map.destroy();\n    }\n\n    // test for <http://trac.openlayers.org/ticket/2691>\n    function test_partial(t) {        \n\n        t.plan(28);        \n        \n        var map = new OpenLayers.Map({\n            div: \"map\",\n            units: \"m\",\n            resolutions: [1],\n            layers: [\n                new OpenLayers.Layer(null, {\n                    isBaseLayer: true\n                })\n            ],\n            center: new OpenLayers.LonLat(0, 0)\n        });\n\n        var log = [];\n        var control = new OpenLayers.Control.Measure(\n            OpenLayers.Handler.Path, {persist: true, \n                eventListeners: {\n                    measurepartial: function(evt) {\n                        log.push(evt);\n                    },\n                    measure: function(evt){\n                        log.push(evt);\n                    }\n                },\n                handlerOptions: {\n                    pixelTolerance: 0,\n                    dblclickTolerance: 0\n                }\n            }\n        );\n        map.addControl(control);\n        control.activate();\n        \n        \n        // convenience function to trigger mouse events\n        function trigger(type, x, y) {\n            map.events.triggerEvent(type, {\n                xy: new OpenLayers.Pixel(x, y)\n            })\n        };\n        \n        // delay in seconds\n        var delay = control.partialDelay / 1000;\n        \n        // establish first point\n        trigger(\"mousemove\", 0, 0);\n        trigger(\"mousedown\", 0, 0);\n        trigger(\"mouseup\", 0, 0);\n\n        \n        // a) move 10 pixels and click\n        trigger(\"mousemove\", 0, 10);\n        trigger(\"mousedown\", 0, 10);\n        trigger(\"mouseup\", 0, 10);\n        \n        // confirm measurepartial is not fired before delay\n        t.eq(log.length, 0, \"a) no event fired yet\")\n\n        t.delay_call( \n            // wait for delay then confirm event was logged\n            delay, function() {\n                t.eq(log.length, 1, \"a) event logged\")\n                t.eq(log[0] && log[0].type, \"measurepartial\", \"a) event logged\");\n                t.eq(log[0] && log[0].measure, 10, \"a) correct measure\");\n                \n                // b) move 10 pixels and click\n                trigger(\"mousemove\", 0, 20);\n                trigger(\"mousedown\", 0, 20);\n                trigger(\"mouseup\", 0, 20);\n                \n                // confirm measurepartial is not fired before delay\n                t.eq(log.length, 1, \"b) no event fired yet\")\n                \n            },\n            delay, function() {\n                t.eq(log.length, 2, \"b) event logged\");\n                t.eq(log[1] && log[1].type, \"measurepartial\", \"b) correct type\");\n                t.eq(log[1] && log[1].measure, 20, \"b) correct measure\");\n\n                // c) move 10 pixels and click\n                trigger(\"mousemove\", 0, 30);\n                trigger(\"mousedown\", 0, 30);\n                trigger(\"mouseup\", 0, 30);\n            },\n            // wait for half delay and confirm event not logged\n            delay / 2, function() {\n                // confirm measurepartial is not fired before delay\n                t.eq(log.length, 2, \"c) no event fired yet\")\n            },\n            // wait for rest of delay and confirm event logged\n            delay / 2, function() {\n                t.eq(log.length, 3, \"c) event logged\");\n                t.eq(log[2] && log[2].type, \"measurepartial\", \"c) correct type\");\n                t.eq(log[2] && log[2].measure, 30, \"c) correct measure\");\n                \n                // d) move 10 pixels and click\n                trigger(\"mousemove\", 0, 40);\n                trigger(\"mousedown\", 0, 40);\n                trigger(\"mouseup\", 0, 40);\n\n                // confirm measurepartial is not fired before delay\n                t.eq(log.length, 3, \"d) no event fired yet\")\n                \n                // e) double click to finish\n                trigger(\"dblclick\", 0, 40);\n\n                t.eq(log.length, 4, \"e) event logged\");\n                t.eq(log[3] && log[3].type, \"measure\", \"e) correct type\");\n                t.eq(log[3] && log[3].measure, 40, \"e) correct measure\");                \n            },\n            // wait for rest of delay and confirm no measurepartial logged\n            delay, function() {\n                // confirm measurepartial is not fired after dblclick\n                t.eq(log.length, 4, \"e) no additional event fired\");\n                \n                // change to freehand mode and confirm synchronous event dispatch\n                control.handler.freehand = true;\n                // clear log\n                log = [];\n                \n                // f) establish first freehand point\n                trigger(\"mousemove\", 0, 0);\n                trigger(\"mousedown\", 0, 0);\n                t.eq(log.length, 0, \"f) no event fired yet\")\n                \n                // g) move 10 pixels\n                trigger(\"mousemove\", 10, 0);\n\n                t.eq(log.length, 1, \"g) event logged\");\n                t.eq(log[0] && log[0].type, \"measurepartial\", \"g) correct type\");\n                t.eq(log[0] && log[0].measure, 10, \"g) correct measure\");\n                \n                // h) move 10 pixels\n                trigger(\"mousemove\", 20, 0);\n\n                t.eq(log.length, 2, \"h) event logged\");\n                t.eq(log[1] && log[1].type, \"measurepartial\", \"h) correct type\");\n                t.eq(log[1] && log[1].measure, 20, \"h) correct measure\");\n\n                // i) mouse up to finish\n                trigger(\"mouseup\", 20, 0);\n\n                t.eq(log.length, 3, \"i) event logged\");\n                t.eq(log[2] && log[2].type, \"measure\", \"i) correct type\");\n                t.eq(log[2] && log[2].measure, 20, \"i) correct measure\");\n\n                // j) clean up\n                log = [];\n                map.destroy();\n            },\n            // wait for delay and confirm event not logged\n            delay, function() {\n                t.eq(log.length, 0, \"j) no event fired after destroy\");\n            }\n        );\n        \n    }\n\n    function test_immediate(t) {\n        t.plan(32);\n        \n        var map = new OpenLayers.Map({\n            div: \"map\",\n            units: \"m\",\n            resolutions: [1],\n            layers: [\n                new OpenLayers.Layer(null, {\n                    isBaseLayer: true\n                })\n            ],\n            center: new OpenLayers.LonLat(0, 0)\n        });\n\n        var log = [];\n        var control = new OpenLayers.Control.Measure(\n            OpenLayers.Handler.Path, {\n                persist: true,\n                immediate: true,\n                eventListeners: {\n                    measurepartial: function(evt) {\n                        log.push(evt);\n                    },\n                    measure: function(evt){\n                        log.push(evt);\n                    }\n                },\n                handlerOptions: {\n                    pixelTolerance: 0,\n                    dblclickTolerance: 0\n                }\n            }\n        );\n        map.addControl(control);\n        control.activate();\n\n        // convenience function to trigger mouse events\n        function trigger(type, x, y) {\n            map.events.triggerEvent(type, {\n                xy: new OpenLayers.Pixel(x, y)\n            })\n        };\n\n        // delay in seconds\n        var delay = control.partialDelay / 1000;\n\n        // a) establish first point\n        trigger(\"mousemove\", 0, 0);\n        trigger(\"mousedown\", 0, 0);\n        trigger(\"mouseup\", 0, 0);\n\n        // move 10 pixels\n        trigger(\"mousemove\", 0, 10);\n\n        t.eq(log.length, 1, \"a) has fired an event\");\n\n        t.delay_call(\n            delay, function() {\n                // confirm measurepartial is fired\n                t.eq(log.length, 1, \"a) one event logged\");\n                t.ok(log[0] && log[0].type == \"measurepartial\", \"a) correct type\");\n                // mousemove within the partialDelay fires no event, so the\n                // measure below is the one of the initial point\n                t.eq(log[0]?log[0].measure:-1 , 10, \"a) correct measure\");\n\n                // b) move 10 pixels\n                trigger(\"mousemove\", 0, 20);\n                // c) move 10 pixels again\n                trigger(\"mousemove\", 0, 30);\n\n                // confirm measurepartial is fired 2 times\n                t.eq(log.length, 3, \"b) event logged\");\n                t.eq(log[1] && log[1].type, \"measurepartial\", \"b) correct type\");\n                t.eq(log[1] && log[1].measure, 20, \"b) correct measure\");\n                t.eq(log[2] && log[2].type, \"measurepartial\", \"c) correct type\");\n                t.eq(log[2] && log[2].measure, 30, \"c) correct measure\");\n\n                // d) switch immediate measurement off\n                control.setImmediate(false);\n                t.eq(control.immediate, false, \"d) immediate is false\");\n\n                // e) move 10 pixels and click\n                trigger(\"mousemove\", 0, 40);\n                trigger(\"mousedown\", 0, 40);\n                trigger(\"mouseup\", 0, 40);\n                // confirm measurepartial is not fired before delay\n                t.eq(log.length, 3, \"e) no event fired yet\")\n            },\n            // wait for delay then confirm event was logged\n            delay, function() {\n                t.eq(log.length, 4, \"e) event logged\")\n                t.ok(log[3] && log[3].type == \"measurepartial\", \"e) correct type\");\n                t.ok(log[3] && log[3].measure == 40, \"e) correct measure\");\n\n                // f) switch immediate measurement on\n                control.setImmediate(true);\n                t.eq(control.immediate, true, \"f) immediate is true\");\n\n                // g) move 10 pixels\n                trigger(\"mousemove\", 0, 50);\n            },\n            delay, function() {\n                t.eq(log.length, 5, \"g) event logged\");\n                t.ok(log[4] && log[4].type == \"measurepartial\", \"g) correct type\");\n                t.ok(log[4] && log[4].measure == 50, \"g) correct measure\");\n\n                // h) move 10 pixels\n                trigger(\"mousemove\", 0, 60);\n\n                t.eq(log.length, 6, \"h) event logged\");\n                t.ok(log[5] && log[5].type == \"measurepartial\", \"h) correct type\");\n                t.ok(log[5] && log[5].measure == 60, \"h) correct measure\");\n\n                // i) double click to finish\n                trigger(\"mousedown\", 0, 60);\n                t.eq(log.length, 7, \"i) event logged\");\n                t.eq(log[6] && log[6].type, \"measurepartial\", \"i) correct type\");\n                t.eq(log[6] && log[6].measure, 60, \"i) correct measure\");\n                trigger(\"mouseup\", 0, 60);\n                t.eq(log.length, 7, \"i) no event fired yet\");\n            },\n            delay, function() {\n                t.eq(log.length, 8, \"j) event logged\");\n                t.eq(log[7] && log[7].type, \"measurepartial\", \"j) correct type\");\n                t.eq(log[7] && log[7].measure, 60, \"j) correct measure\");\n\n                trigger(\"dblclick\", 0, 60);\n                t.eq(log.length, 9, \"k) event logged\");\n                t.eq(log[8] && log[8].type, \"measure\", \"k) correct type\");\n                t.eq(log[8] && log[8].measure, 60, \"k) correct measure\");\n                // clear log\n                log = [];\n\n                // l) clean up\n                map.destroy();\n                // wait for delay and confirm event not logged\n            },\n            delay, function() {\n                t.eq(log.length, 0, \"l) no event fired after destroy\");\n            }\n        );\n    }\n    \n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 512px; height: 256px;\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/ModifyFeature/BySegment.html",
    "content": "<html>\n<head>\n    <script src=\"http://mourner.github.io/rbush/rbush.js\"></script>\n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    \n    function test_initialize(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var options = {\n            bySegment: true\n        };\n        var control = new OpenLayers.Control.ModifyFeature(layer, options);\n        map.addControl(control);\n        t.eq(control.hoverTolerance, 25, \"mixin applied correctly\");\n        t.ok(control.handlers.hover, \"hover handler created\");\n        map.destroy();\n    }\n\n    function test_createBBOX(t) {\n        t.plan(2)\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var options = {\n            bySegment: true\n        };\n        var control = new OpenLayers.Control.ModifyFeature(layer, options);\n        map.addControl(control);\n        var point1 = new OpenLayers.Geometry.Point(100, 100);\n        var point2 = new OpenLayers.Geometry.Point(200, 200);\n        var bbox = control.createBBOX(point1, point2);\n        t.eq(bbox, [100, 100, 200, 200], \"bbox created correctly (minx < maxx, miny < maxy)\");\n        bbox = control.createBBOX(point2, point1);\n        t.eq(bbox, [100, 100, 200, 200], \"bbox created correctly (minx < maxx, miny < maxy)\");\n        map.destroy();\n    }\n\n    function test_spatialIndex(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var options = {\n            bySegment: true\n        };\n        var control = new OpenLayers.Control.ModifyFeature(layer, options);\n        map.addControl(control);\n        var components = [new OpenLayers.Geometry.Point(10,14), new OpenLayers.Geometry.Point(5,3)];\n        var components2 = [new OpenLayers.Geometry.Point(12,15), new OpenLayers.Geometry.Point(2,3), new OpenLayers.Geometry.Point(10,0), new OpenLayers.Geometry.Point(10,10)];\n        var linearRing = new OpenLayers.Geometry.LinearRing(components);\n        var linearRing2 = new OpenLayers.Geometry.LinearRing(components2);\n        var geometry = new OpenLayers.Geometry.Polygon([linearRing, linearRing2]);\n        control.createSpatialIndex({feature: new OpenLayers.Feature.Vector(geometry)});\n        t.ok(control.tree, \"spatial tree created\");\n        t.eq(control.tree.search([12, 15, 12, 15]).length, 2, \"2 items found\");\n        map.destroy();\n    }\n\n    </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 400px; height: 250px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/ModifyFeature.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    \n    function test_initialize(t) {\n        t.plan(3);\n        var layer = {\n            styleMap: {createSymbolizer: function(){}},\n            events: {\n                on: function() {},\n                un: function() {}\n            }\n        };\n        var options = {\n            documentDrag: true\n        };\n        var control = new OpenLayers.Control.ModifyFeature(layer, options);\n        \n        t.ok(control.layer == layer,\n             \"constructor sets layer correctly\");\n        t.eq(control.handlers.drag.documentDrag, true,\n             \"constructor sets options correctly on drag handler\");\n        t.eq(control.mode, OpenLayers.Control.ModifyFeature.RESHAPE,\n             \"constructor initializes modification mode correctly\");\n        control.destroy();\n    }\n\n    function test_destroy(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.ModifyFeature(layer);\n        control.destroy();\n        t.eq(control.layer, null, \"Layer reference removed on destroy.\");\n        map.destroy();\n    }\n    \n    function test_activate(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.ModifyFeature(layer);\n        map.addControl(control);\n        t.ok(!control.handlers.drag.active,\n             \"drag handler is not active prior to activating control\");\n        control.activate();\n        t.ok(control.handlers.drag.active,\n             \"drag handler is active after activating control\");\n\n        map.destroy();\n    }\n\n    function test_initDeleteCodes(t) {\n        t.plan(3);\n        var layer = new OpenLayers.Layer.Vector();\n        var control = new OpenLayers.Control.ModifyFeature(layer, {'deleteCodes': 46});\n        t.eq(control.deleteCodes[0], 46, \"Delete code properly turned into an array.\");\n        var control = new OpenLayers.Control.ModifyFeature(layer);\n        t.eq(control.deleteCodes[0], 46, \"Default deleteCodes include delete\"); \n        t.eq(control.deleteCodes[1], 68, \"Default deleteCodes include 'd'\"); \n        \n        control.destroy();\n        layer.destroy();\n    }\n    \n    function test_handleKeypress(t) {\n        t.plan(16);\n\n        /**\n         * There are two things that we want to test here\n         * 1) test that control.deleteCodes are respected\n         * 3) test that a vertex is properly deleted\n         *\n         * In the future, feature deletion may be added to the control.\n         */\n        \n        var layer = new OpenLayers.Layer.Vector();\n        var control = new OpenLayers.Control.ModifyFeature(layer);\n        var delKey = 46;\n        var dKey = 100;\n        control.deleteCodes = [delKey, dKey];\n        \n        // test that a polygon vertex is deleted for all delete codes\n        var point = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point()\n        );\n        var poly = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Polygon()\n        );\n        \n        // mock up vertex deletion\n        var origGetFeatureFromEvent = layer.getFeatureFromEvent;\n        layer.getFeatureFromEvent = function() { return point; };\n        control.feature = poly;\n        // we cannot use selectFeature since the control is not part of a map\n        control._originalGeometry = poly.geometry.clone();\n        control.vertices = [point];\n        point.geometry.parent = {\n            removeComponent: function(geometry) {\n                t.eq(geometry.id, point.geometry.id,\n                     \"vertex deletion: removeComponent called on parent with proper geometry\");\n            }\n        };\n        layer.events.on({\n            \"featuremodified\": function(event) {\n                t.ok(event.feature.modified !== null, \"modified property of feature should have been set\");\n                t.eq(event.feature.id, poly.id, \"vertex deletion: featuremodifed triggered\");\n            },\n            \"vertexremoved\": function(evt) {\n                layer.events.unregister(\"vertexremoved\", this, arguments.callee);\n                t.eq(evt.feature.id, poly.id, \"vertexremoved triggered with correct feature\");\n                t.eq(evt.vertex.id, point.geometry.id, \"vertexremoved triggered with correct vertex\");\n                t.eq(evt.pixel, \"foo\", \"vertexremoved triggered with correct pixel\");\n            }\n        });\n        layer.drawFeature = function(feature) {\n            t.eq(feature.id, poly.id,\n                 \"vertex deletion: drawFeature called with the proper feature\");\n        };\n        control.resetVertices = function() {\n            t.ok(true, \"vertex deletion: resetVertices called\");\n        };\n        control.onModification = function(feature) {\n            t.eq(feature.id, poly.id,\n                 \"vertex deletion: onModification called with the proper feature\");\n        };\n        // run the above four tests twice\n        control._lastVertex = point;\n        control.handleKeypress({keyCode:delKey, xy: \"foo\"});\n        control.handleKeypress({keyCode:dKey});\n        t.eq(control.feature.state, OpenLayers.State.UPDATE, \"feature state set to update\");\n\n        // now make sure nothing happens if the vertex is mid-drag\n        control.handlers.drag.dragging = true;\n        control.handleKeypress({keyCode:delKey});\n\n        //  clean up\n        layer.getFeatureFromEvent = origGetFeatureFromEvent;\n        control.destroy();\n        layer.destroy();\n    }    \n        \n\n    function test_onUnSelect(t) {\n        t.plan(5);\n        var layer = new OpenLayers.Layer.Vector();\n        var control = new OpenLayers.Control.ModifyFeature(layer);\n        var fakeFeature = {'id':'myid'};\n        control.vertices = 'a';\n        control.virtualVertices = 'b';\n        control.features = true;\n        layer.events.on({\"afterfeaturemodified\": function(event) {\n            t.eq(event.feature, fakeFeature, \"afterfeaturemodified triggered\");\n        }});\n        control.onModificationEnd = function (feature) { t.eq(feature.id, fakeFeature.id, \"onModificationEnd got feature.\") }\n        layer.removeFeatures = function(verts) {\n            t.ok(verts == 'a', \"Normal verts removed correctly\");\n        }\n        layer.destroyFeatures = function(verts) {\n            t.ok(verts == 'b', \"Virtual verts destroyed correctly\");\n        }\n        control.unselectFeature(fakeFeature);\n        t.eq(control.feature, null, \"feature is set to null\");\n        \n        layer.destroyFeatures = function() {};        \n        control.destroy();\n        layer.destroy();\n    }\n    \n    function test_stop_modification(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.Vector(\"Vectors!\", {isBaseLayer: true});\n        var feature = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(0, 0)\n        );\n        layer.addFeatures([feature]);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0, 0));\n\n\n        // If a feature is to be modified, control.selectFeature gets called.\n        // We want this test to fail if selectFeature gets called.\n        var modified = false;\n\n        var control = new OpenLayers.Control.ModifyFeature(layer);\n        map.addControl(control);\n        control.activate();\n\n        // register a listener that will stop feature modification\n        layer.events.on({\"beforefeaturemodified\": function() {return false}});\n\n        // we can initiate feature modification by programmatically selecting\n        // a feature\n        control.selectFeature(feature);\n        \n        if(modified) {\n            t.fail(\"selectFeature called, prepping feature for modification\");\n        } else {\n            t.ok(true, \"the beforefeaturemodified listener stopped feature modification\");\n        }\n    }\n\n    function test_selectFeature(t) {\n        t.plan(12);\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.Vector(\"Vectors!\", {isBaseLayer: true});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0, 0));\n        var control = new OpenLayers.Control.ModifyFeature(layer);\n        control.vertices = [];\n        control.virtualVertices = [];\n        var callback = function(obj) {\n            t.ok(obj.feature == fakeFeature, \"beforefeaturemodified triggered\");\n        };\n        layer.events.on({\"beforefeaturemodified\": callback});\n        control.onModificationStart = function(feature)  { t.eq(feature.id, fakeFeature.id, \"On Modification Start called with correct feature.\"); } \n        \n        // Start of testing\n        \n        control.collectVertices = function() { t.fail(\"Collect vertices called when geom is a point\"); }\n        var fakeFeature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0, 0));\n        \n        // Points don't call collectVertices\n        control.selectFeature(fakeFeature);\n        control.unselectFeature(fakeFeature);\n        \n        control.collectVertices = function() { \n          t.ok(true, \"collectVertices called\"); \n          this.vertices = 'a';\n          this.virtualVertices = 'd';\n          layer.addFeatures(this.vertices);\n          layer.addFeatures(this.virtualVertices);\n        }\n        \n        layer.addFeatures = function(features) { \n            t.ok(features == 'a' || features == 'd', \"features passed correctly\"); \n        }\n        layer.destroyFeatures = function() {};\n\n        fakeFeature.geometry = new OpenLayers.Geometry.Polygon([\n            new OpenLayers.Geometry.LinearRing([\n                new OpenLayers.Geometry.Point(0, 0),\n                new OpenLayers.Geometry.Point(1, 1)\n            ])\n        ]);\n        \n        // OnSelect calls collectVertices and passes features to layer \n        control.selectFeature(fakeFeature);        \n        control.unselectFeature(fakeFeature);\n        layer.destroyFeatures = OpenLayers.Layer.Vector.prototype.destroyFeatures;\n        \n        control.vertices = ['a'];\n        control.virtualVertices = [{destroy: function() {}}];\n        \n        layer.addFeatures = function(features) {} \n        \n        layer.removeFeatures = function(features) { \n            t.eq(features.length, 1, \"Correct feature length passed in\");\n        }    \n\n        // Features are removed whenever they exist\n        control.selectFeature(fakeFeature);\n        \n        control.destroy();\n\n        // layer.destroy() will call removeFeatures with an empty array, make\n        // removeFeatures reference an empty function to prevent the above\n        // test to fail\n        layer.removeFeatures = function(features) {};\n        layer.destroy();\n    }  \n\n    function test_resetVertices(t) {\n        t.plan(20);\n        var layer = new OpenLayers.Layer.Vector();\n        var control = new OpenLayers.Control.ModifyFeature(layer);\n        var point = new OpenLayers.Geometry.Point(5,6);\n        var point2 = new OpenLayers.Geometry.Point(7,8);\n        var point3 = new OpenLayers.Geometry.Point(9,10);\n        \n        control.feature = new OpenLayers.Feature.Vector(point);\n        control.resetVertices();\n        t.eq(control.vertices.length, 0, \"Correct vertices length\");\n        t.eq(control.virtualVertices.length, 0, \"Correct virtual vertices length.\");\n\n        var multiPoint = new OpenLayers.Geometry.MultiPoint([point, point2]);\n        control.feature = new OpenLayers.Feature.Vector(multiPoint);\n        control.resetVertices();\n        t.eq(control.vertices.length, 2, \"Correct vertices length with multipoint\");\n        t.eq(control.virtualVertices.length, 0, \"Correct virtual vertices length (multipoint).\");\n\n        var line = new OpenLayers.Geometry.LineString([point, point2]);\n        control.feature = new OpenLayers.Feature.Vector(line);\n        control.resetVertices();\n        t.eq(control.vertices.length, 2, \"Correct vertices length with line\");\n        t.eq(control.virtualVertices.length, 1, \"Correct virtual vertices length (linestring).\");\n        \n        var polygon = new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing([point, point2, point3])]);\n        control.feature = new OpenLayers.Feature.Vector(polygon);\n        control.resetVertices();\n        t.eq(control.vertices.length, 3, \"Correct vertices length with polygon\");\n        t.eq(control.virtualVertices.length, 3, \"Correct virtual vertices length (polygon).\");\n\n        control.mode = OpenLayers.Control.ModifyFeature.DRAG;\n        control.resetVertices();\n        t.ok(control.dragHandle != null, \"Drag handle is set\");\n        t.eq(control.vertices.length, 0, \"Correct vertices length with polygon (DRAG)\");\n\n        control.mode = OpenLayers.Control.ModifyFeature.ROTATE;\n        control.resetVertices();\n        t.ok(control.radiusHandle != null, \"Radius handle is set\");\n        t.eq(control.vertices.length, 0, \"Correct vertices length with polygon (ROTATE)\");\n\n        control.mode = OpenLayers.Control.ModifyFeature.RESIZE;\n        control.resetVertices();\n        t.ok(control.radiusHandle != null, \"Radius handle is set\");\n        t.eq(control.vertices.length, 0, \"Correct vertices length with polygon (RESIZE)\");\n\n        control.mode = OpenLayers.Control.ModifyFeature.RESHAPE;\n        control.resetVertices();\n        t.ok(control.radiusHandle == null, \"Radius handle is not set (RESHAPE)\");\n        t.eq(control.vertices.length, 3, \"Correct vertices length with polygon (RESHAPE)\");\n        t.eq(control.virtualVertices.length, 3, \"Correct virtual vertices length (RESHAPE)\");\n        \n        control.mode = OpenLayers.Control.ModifyFeature.RESIZE | OpenLayers.Control.ModifyFeature.RESHAPE;\n        control.resetVertices();\n        t.ok(control.radiusHandle != null, \"Radius handle is set (RESIZE|RESHAPE)\");\n        t.eq(control.vertices.length, 0, \"No vertices when both resizing and reshaping (RESIZE|RESHAPE)\");\n        t.eq(control.virtualVertices.length, 0, \"No virtual vertices when both resizing and reshaping (RESIZE|RESHAPE)\");\n        \n        control.destroy();\n        layer.destroy();\n    }\n    \n    function test_dragVertex(t) {\n        t.plan(8);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        \n        var control = new OpenLayers.Control.ModifyFeature(layer);\n        map.addControl(control);\n        control.activate();\n        \n        map.zoomToMaxExtent();\n        \n        var log = {};\n        layer.events.on({\n            \"vertexmodified\": function(event) {\n                log.event = event;\n            }\n        });\n        \n        // pretend to drag a point\n        var feature = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(0, 0)\n        );\n        control.feature = feature;\n        var pixel = new OpenLayers.Pixel(-100, 100);\n        control.dragVertex(feature, pixel);\n        t.eq(log.event.type, \"vertexmodified\", \"[drag point] vertexmodified triggered\");\n        t.geom_eq(log.event.vertex, feature.geometry, \"[drag point] listeners receive correct vertex\");\n        t.eq(log.event.feature.id, feature.id, \"[drag point] listeners receive correct feature\");\n        t.ok(log.event.pixel === pixel, \"[drag point] listeners receive correct pixel\");\n        \n        // pretend to drag vertex of a linestring\n        var vert = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(0, 0)\n        );\n        var feature = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.LineString([\n                vert.geometry, new OpenLayers.Geometry.Point(10, 0)\n            ])\n        );\n        control.feature = feature;\n        var pixel = new OpenLayers.Pixel(-100, 100);\n        control.dragVertex(vert, pixel);\n        t.eq(log.event.type, \"vertexmodified\", \"[drag vertex] vertexmodified triggered\");\n        t.geom_eq(log.event.vertex, vert.geometry, \"[drag vertex] listeners receive correct vertex\");\n        t.eq(log.event.feature.id, feature.id, \"[drag vertex] listeners receive correct feature\");\n        t.ok(log.event.pixel === pixel, \"[drag vertex] listeners receive correct pixel\");\n\n\n        map.destroy();\n    }\n    function test_collectDragHandle(t) {\n        t.plan(4);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,1));\n        layer.addFeatures([feature]);\n        var control = new OpenLayers.Control.ModifyFeature(layer);\n        map.addControl(control);\n        control.activate();\n        control.feature = feature;\n        control.collectDragHandle();\n        t.ok(control.dragHandle != null, \"Drag handle created\");\n        t.ok(control.dragHandle._sketch == true, \"Handle has _sketch true\");\n        t.ok(control.dragHandle.renderIntent == control.vertexRenderIntent,\"Render intent for handle set\");\n        t.ok(control.layer.getFeatureById(control.dragHandle.id) != null, \"Drag handle added to layer\");\n    }\n    function test_collectRadiusHandle(t) {\n        t.plan(4);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,1));\n        layer.addFeatures([feature]);\n        var control = new OpenLayers.Control.ModifyFeature(layer);\n        map.addControl(control);\n        control.activate();\n        control.feature = feature;\n        control.collectRadiusHandle();\n        t.ok(control.radiusHandle != null, \"Radius handle created\");\n        t.ok(control.radiusHandle._sketch == true, \"Radius has _sketch true\");\n        t.ok(control.radiusHandle.renderIntent == control.vertexRenderIntent,\"Render intent for handle set\");\n        t.ok(control.layer.getFeatureById(control.radiusHandle.id) != null, \"Drag radius added to layer\");\n    }\n    function test_onDrag(t) {\n        t.plan(1);\n        t.ok(true, \"onDrag not tested yet.\");\n    }\n    \n    function test_dragComplete(t) {\n        t.plan(8);\n        var layer = new OpenLayers.Layer.Vector();\n        var control = new OpenLayers.Control.ModifyFeature(layer);\n       \n        var fakeFeature = {\n         'geometry': { 'id':'myGeom'},\n         'id': 'fakeFeature'\n        };\n        layer.addFeatures = function (verts) {\n            t.ok(verts == 'virtual' || verts == 'normal', verts + \" verts correct\");\n        }\n        layer.removeFeatures = function (verts) {\n            t.ok(verts == 'previous virtual' || verts == 'previous normal', verts + \" verts correct\");\n        }\n        layer.events.on({\"featuremodified\": function(event) {\n            t.eq(event.feature, fakeFeature, \"featuremodified triggered\");\n        }});\n        control.onModification = function(feat) {\n            t.eq(feat.id, fakeFeature.id, \"onModification gets correct feat\");\n        }\n        control.collectVertices = function() {\n            t.ok(true, \"collectVertices called\");\n            this.vertices = 'normal';\n            this.virtualVertices = 'virtual';\n            layer.addFeatures(this.vertices);\n            layer.addFeatures(this.virtualVertices);\n        }\n        control.feature = fakeFeature;\n        control.vertices = 'previous normal';\n        control.virtualVertices = 'previous virtual';\n        control.dragComplete();\n        t.eq(fakeFeature.state, OpenLayers.State.UPDATE, \"feature state set to UPDATE\");\n        \n        control.destroy();\n\n        // layer.destroy() will call removeFeatures with an empty array, make\n        // removeFeatures reference an empty function to prevent the above\n        // test to fail\n        layer.removeFeatures = function(verts) {};\n        layer.destroy();\n    }\n    \n    function test_deactivate(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.ModifyFeature(layer);\n        map.addControl(control);\n        \n        control.handlers.keyboard.deactivate = function() {\n            t.ok(true,\n                 \"control.deactivate calls deactivate on keyboard handler\");\n        }\n        control.handlers.drag.deactivate = function() {\n            t.ok(true,\n                 \"control.deactivate calls deactivate on drag handler\");\n        }\n        control.active = true;\n        control.deactivate();\n        \n        control.handlers.keyboard.deactivate = OpenLayers.Handler.Keyboard.prototype.deactivate;\n        control.handlers.drag.deactivate = OpenLayers.Handler.Drag.prototype.deactivate;\n        map.destroy();\n    }\n\n    function test_onModificationStart(t) {\n        t.plan(5);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector(null, {\n            styleMap: new OpenLayers.StyleMap({\n                \"vertex\": new OpenLayers.Style({foo: \"bar\"})\n            }, {extendDefault: false})\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.ModifyFeature(layer);\n        map.addControl(control);\n        control.activate();\n        \n        // make sure onModificationStart is called on feature selection\n        var testFeature = new OpenLayers.Feature.Vector(\n            OpenLayers.Geometry.fromWKT(\"LINESTRING(3 4,10 50,20 25)\")\n        );\n        layer.addFeatures([testFeature]);\n        control.onModificationStart = function(feature) {\n            t.eq(feature.id, testFeature.id,\n                 \"onModificationStart called with the right feature\");\n        };\n        control.selectFeature(testFeature);\n        \n        // make sure styles are set correctly from default style\n        t.eq(control.virtualStyle, OpenLayers.Util.applyDefaults({\n            strokeOpacity: 0.3,\n            fillOpacity: 0.3\n        }, OpenLayers.Feature.Vector.style[\"default\"]), \"virtual style set correctly\");\n        var vertex = layer.features[layer.features.length-1];\n        t.eq(vertex.renderIntent, null, \"vertex style set correctly - uses default style\");\n        control.unselectFeature(testFeature);\n        \n        // make sure styles are set correctly with vertexRenderIntent\n        control = new OpenLayers.Control.ModifyFeature(layer, {vertexRenderIntent: \"vertex\"});\n        map.addControl(control);\n        control.activate();\n        control.selectFeature(testFeature);\n        t.eq(control.virtualStyle, {\n            strokeOpacity: 0.3,\n            fillOpacity: 0.3,\n            foo: \"bar\"\n        }, \"virtual style set correctly\");\n        var vertex = layer.features[layer.features.length-1];\n        t.eq(vertex.renderIntent, \"vertex\", \"vertex style set correctly - uses 'vertex' renderIntent\");\n        control.unselectFeature(testFeature);\n        \n        map.destroy();\n    }\n    \n    function test_onModification(t) {\n        t.plan(3);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.ModifyFeature(layer);\n        map.addControl(control);\n        control.activate();\n        \n        // make sure onModification is called on drag complete\n        var point = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(Math.random(), Math.random())\n        );\n        control.feature = point;\n        control.onModification = function(feature) {\n            t.eq(feature.id, point.id,\n                \"onModification called with the right feature on drag complete\");\n        };\n        control.dragComplete();\n        \n        // make sure onModification is called on vertex deletion\n        var poly = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Polygon()\n        );\n        var oldDraw = layer.drawFeature;\n        layer.drawFeature = function() {\n            return;\n        };\n        control.feature = poly;\n        control.vertices = [point];\n        control._lastVertex = point;\n        layer.events.on({\"featuremodified\": function(event) {\n            t.eq(event.feature.id, poly.id, \"featuremodified triggered\");\n        }});\n\n        control.onModification = function(feature) {\n            t.eq(feature.id, poly.id,\n                \"onModification called with the right feature on vertex delete\");\n        };\n        point.geometry.parent = poly.geometry;\n        origGetFeatureFromEvent = layer.getFeatureFromEvent;\n        layer.getFeatureFromEvent = function() { return point; };\n        control.handleKeypress({keyCode:46});\n        layer.drawFeature = oldDraw;\n        layer.getFeatureFromEvent = origGetFeatureFromEvent;\n        \n        map.destroy();\n    }\n\n    function test_onModificationEnd(t) {\n        t.plan(3);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.ModifyFeature(layer);\n        map.addControl(control);\n        control.activate();\n        \n        // make sure onModificationEnd is called on unselect feature\n        var testFeature = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(Math.random(), Math.random())\n        );\n        layer.events.on({\"afterfeaturemodified\": function(event) {\n            t.eq(event.feature.id, testFeature.id, \"afterfeaturemodified triggered\");\n            t.eq(event.modified, false, \"afterfeaturemodified event given proper modified property (false - feature was not modified in this case)\");\n        }});\n        control.onModificationEnd = function(feature) {\n            t.eq(feature.id, testFeature.id,\n                 \"onModificationEnd called with the right feature\");\n        };\n        control.unselectFeature(testFeature);\n        \n        map.destroy();\n    }\n    \n    function test_events(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.ModifyFeature(layer);\n        map.addControl(control);\n        control.activate();\n        \n        // make sure onModificationStart is called on feature selection\n        var testFeature = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(Math.random(), Math.random())\n        );\n        \n        // test that beforefeatureselected is triggered\n        function handle_beforefeatureselected(event) {\n            t.ok(event.feature == testFeature, \"beforefeatureselected called with the correct feature\");\n        }\n        layer.events.on({\n            \"beforefeatureselected\": handle_beforefeatureselected\n        });\n        layer.events.triggerEvent(\"beforefeatureselected\", {\n            feature: testFeature\n        });\n        layer.events.un({\n            \"beforefeatureselected\": handle_beforefeatureselected\n        });\n        \n        // test that beforefeatureselected is triggered\n        function handle_featureselected(event) {\n            t.ok(event.feature == testFeature, \"featureselected called with the correct feature\");\n        }\n        layer.events.on({\n            \"featureselected\": handle_featureselected\n        });\n        layer.events.triggerEvent(\"featureselected\", {\n            feature: testFeature\n        });\n        layer.events.un({\n            \"featureselected\": handle_featureselected\n        });\n\n        map.destroy();\n    }\n    \n    function test_standalone(t) {\n        \n        t.plan(17);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        \n        var f1 = new OpenLayers.Feature.Vector(\n            OpenLayers.Geometry.fromWKT(\"LINESTRING(3 4,10 50,20 25)\")\n        );\n        var f2 = new OpenLayers.Feature.Vector(\n            OpenLayers.Geometry.fromWKT(\"POLYGON((1 1,5 1,5 5,1 5,1 1),(2 2, 3 2, 3 3, 2 3,2 2))\")\n        );\n        var f3 = new OpenLayers.Feature.Vector(\n            OpenLayers.Geometry.fromWKT(\"POINT(10 15)\")\n        );\n        var f4 = new OpenLayers.Feature.Vector(\n            OpenLayers.Geometry.fromWKT(\"POINT(15 10)\")\n        );\n        layer.addFeatures([f1, f2, f3, f4]);\n        \n        map.addLayer(layer);\n        var control = new OpenLayers.Control.ModifyFeature(layer, {standalone: true});\n        map.addControl(control);\n        \n        var log = [];\n        layer.events.on({\n            beforefeaturemodified: function(evt) {\n                layer.events.unregister(\"beforefeaturemodified\", this, arguments.callee);\n                log.push(evt);\n            },\n            featuremodified: function(evt) {\n                log.push(evt);\n            },\n            afterfeaturemodified: function(evt) {\n                log.push(evt);\n            }\n        });\n        \n        // activate control\n        control.activate();\n        t.eq(control.active, true, \"[activate] control activated\");\n        \n        // manually select feature for editing\n        control.selectFeature(f1);\n        t.eq(log.length, 1, \"[select f1] beforefeaturemodified triggered\");\n        t.ok(control.feature === f1, \"[select f1] control.feature set to f1\");\n        log = []\n        \n        // manually unselect feature for editing\n        control.unselectFeature(f1);\n        t.eq(control.feature, null, \"[unselect f1] control.feature set to null\");\n        t.eq(log.length, 1, \"[unselect f1] event logged\");\n        t.eq(log[0].type, \"afterfeaturemodified\", \"[unselect f1] afterfeaturemodified triggered\");\n        t.ok(log[0].feature === f1, \"[unselect f1] correct feature\");\n        t.eq(log[0].modified, false, \"[unselect f1] feature not actually modified\");\n        \n        // clear log and select new feature for editing\n        log = [];\n        control.selectFeature(f2);\n        t.ok(control.feature === f2, \"[select f2] control.feature set to f2\");\n                \n        // deactivate control and confirm feature is unselected\n        control.deactivate();\n        t.eq(log.length, 1, \"[deactivate] event logged\");\n        t.eq(log[0].type, \"afterfeaturemodified\", \"[deactivate] afterfeaturemodified triggered\");\n        t.ok(log[0].feature === f2, \"[deactivate] correct feature\");\n        t.eq(log[0].modified, false, \"[deactivate] feature not actually modified\");\n        \n        // select the polygon feature to make sure that we can drag vertices and\n        // virtual vertices\n        control.selectFeature(f2);\n        var origGetFeatureFromEvent = layer.getFeatureFromEvent;\n        layer.getFeatureFromEvent = function() { return control.vertices[0]; };\n        control.handlers.drag.callbacks.down.call(control, new OpenLayers.Pixel(0,0));\n        t.ok(control.vertex === control.vertices[0], \"can drag vertex of feature f2\");\n        t.ok(control.feature === f2, \"dragging a vertex does not change the selected feature\");\n        layer.getFeatureFromEvent = function() { return control.virtualVertices[0]; };\n        control.handlers.drag.callbacks.down.call(control, new OpenLayers.Pixel(0,0));\n        t.ok(control.vertex === control.virtualVertices[0], \"can drag virtual vertex of feature f2\");\n        t.ok(control.feature === f2, \"dragging a vertex does not change the selected feature\");\n        layer.getFeatureFromEvent = origGetFeatureFromEvent;\n        control.deactivate();\n        \n        map.destroy();\n        \n    }\n    \n    function test_setFeatureState(t) {\n        t.plan(4);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector(\"vector\", {isBaseLayer: true});\n        map.addLayer(layer);\n        var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,2));\n        layer.addFeatures([feature]);\n        var control = new OpenLayers.Control.ModifyFeature(layer, {standalone: true});\n        map.addControl(control);\n        \n        control.selectFeature(feature);\n        var originalGeometry = feature.geometry;\n        \n        t.ok(control._originalGeometry, \"original geometry stored for later use in setFeatureState\");\n        \n        feature.geometry = new OpenLayers.Geometry.Point(2,3);\n        control.modified = true;\n        control.setFeatureState();\n        \n        t.eq(feature.state, OpenLayers.State.UPDATE, \"feature state set to UPDATE\");\n        t.geom_eq(feature.modified.geometry, originalGeometry, \"original geometry stored on the modified property\");\n        t.eq(control._originalGeometry, undefined, \"original geometry deleted once it is set on the modified property\");\n    }\n\n    function test_createVertices(t) {\n        t.plan(2);\n        var layer = new OpenLayers.Layer.Vector();\n        var control = new OpenLayers.Control.ModifyFeature(layer, {\n            createVertices: false\n        });\n        var line = new OpenLayers.Geometry.LineString([\n            new OpenLayers.Geometry.Point(5, 6),\n            new OpenLayers.Geometry.Point(7, 8),\n            new OpenLayers.Geometry.Point(9, 10)\n        ]);\n        control.feature = new OpenLayers.Feature.Vector(line);\n        control.resetVertices();\n\n        t.eq(control.vertices.length, 3, \"Correct vertices length with createVertices is false\");\n        t.eq(control.virtualVertices.length, 0, \"Correct virtual vertices length with createVertices is false\");\n        control.destroy();\n    }\n\n    function test_moveLayerToTop_moveLayerBack(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var layer1 = new OpenLayers.Layer.Vector();\n        var layer2 = new OpenLayers.Layer.Vector();\n        map.addLayers([layer1, layer2]);\n        var control = new OpenLayers.Control.ModifyFeature(layer1);\n        map.addControl(control);\n        control.activate();\n        t.ok(layer1.div.style.zIndex > layer2.div.style.zIndex, \"layer raised so events don't get swallowed\");\n        control.deactivate();\n        t.ok(layer1.div.style.zIndex < layer2.div.style.zIndex, 'layer order restored on deactivation');\n    }\n\n    </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 400px; height: 250px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/MousePosition.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var map, control; \n    function test_initialize (t) {\n        t.plan( 2 );\n    \n        control = new OpenLayers.Control.MousePosition();\n        t.ok( control instanceof OpenLayers.Control.MousePosition, \"new OpenLayers.Control returns object\" );\n        t.eq( control.displayClass,  \"olControlMousePosition\", \"displayClass is correct\" );\n    }\n    function test_destroy(t) {\n        t.plan(1);\n    \n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control.MousePosition();\n        map.addControl(control);\n\n        var listeners = map.events.listeners.mousemove.length;\n        control.destroy();\n        \n        t.eq(map.events.listeners.mousemove.length, listeners - 1, \"mousemove event is unregistered\");\n        map.destroy();     \n    }\n    function test_addControl(t) {\n        t.plan(4);\n\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control.MousePosition();\n        map.addControl(control);\n\n        t.ok(control.map === map, \"Control.map is set to the map object\");\n        t.ok(map.controls[map.controls.length - 1] === control, \"map.controls contains control\");\n        t.eq(parseInt(control.div.style.zIndex), map.Z_INDEX_BASE['Control'] + 5, \"Control div zIndexed properly\" );\n        t.eq(parseInt(map.viewPortDiv.lastChild.style.zIndex), map.Z_INDEX_BASE['Control'] + 5, \"Viewport div contains control div\");\n        map.destroy();     \n    }\n    function test_redraw_noLayer_displayProjection(t) {\n        t.plan(4);\n        var control = new OpenLayers.Control.MousePosition({'emptyString':''});\n        var map = new OpenLayers.Map('map');\n        map.addControl(control);\n        var control2 = new OpenLayers.Control.MousePosition();\n        map.addControl(control2);\n        t.eq(control2.emptyString, null, \"Emptystring is null\");\n        t.eq(control.div.innerHTML, \"\", \"innerHTML set correctly\");\n        control.redraw({'xy': new OpenLayers.Pixel(10,10)});\n        control.redraw({'xy': new OpenLayers.Pixel(12,12)});\n        t.eq(control.div.innerHTML, \"\", \"innerHTML set correctly\");\n        var l = new OpenLayers.Layer('name', {'isBaseLayer': true});\n        map.addLayer(l);\n        map.zoomToMaxExtent();\n        control.redraw({'xy': new OpenLayers.Pixel(10,10)});\n        control.redraw({'xy': new OpenLayers.Pixel(12,12)});\n        t.eq(control.div.innerHTML, \"-175.78125, 85.78125\", \"innerHTML set correctly when triggered.\");\n        map.destroy();     \n    }\n    function test_formatOutput(t) {\n        t.plan(1);\n        var control = new OpenLayers.Control.MousePosition({\n            prefix: 'prefix',\n            suffix: 'suffix',\n            separator: 'separator',\n            numDigits: 3\n        });\n        var lonlat = new OpenLayers.LonLat(0.75699, 0.37365);\n        var val = control.formatOutput(lonlat);\n        t.eq(val, 'prefix0.757separator0.374suffix', 'formatOutput correctly formats the mouse position output');\n    }\n    function test_deactivate(t) {\n        t.plan(4);         \n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer(null, {isBaseLayer: true});\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        // Auxiliary function\n        function trigger(type, x, y) {\n            map.events.triggerEvent(type, {\n                xy: new OpenLayers.Pixel(x, y)\n            })\n        };        \n\n        var control = new OpenLayers.Control.MousePosition();\n        map.addControl(control);\n        trigger(\"mousemove\", 0, 0);\n\n        trigger(\"mousemove\", 0, 1);\n        t.ok(control.div.innerHTML != \"\", \n            \"Shows the position after add control (with autoActivate) and move\");\n        control.deactivate();\n        t.ok(control.div.innerHTML == \"\", \n            \"Position is not displayed after deactivate and move\");        \n        trigger(\"mousemove\", 0, 2);\n        t.ok(control.div.innerHTML == \"\", \n            \"Position is not displayed after move when deactivate\");\n        control.activate();\n        trigger(\"mousemove\", 0, 3);\n        t.ok(control.div.innerHTML != \"\", \n            \"Shows the position after activate and move\");\n        \n        map.destroy();     \n    }\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/NavToolbar.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var map; \n    function test_Control_NavToolbar_constructor (t) {\n        t.plan( 4 );\n        control = new OpenLayers.Control.NavToolbar();\n        t.ok( control instanceof OpenLayers.Control.NavToolbar, \"new OpenLayers.Control.NavToolbar returns object\" );\n        t.eq( control.displayClass,  \"olControlNavToolbar\", \"displayClass is correct\" );\n        t.ok( control.controls[0] instanceof OpenLayers.Control.Navigation, \"NavToolbar contains Control.Navigation object\" );\n        t.ok( control.controls[1] instanceof OpenLayers.Control.ZoomBox, \"NavToolbar contains Control.ZoomBox object\" );\n    }\n    function test_Control_NavToolbar_addControl (t) {\n        t.plan( 6 );\n        map = new OpenLayers.Map('map');\n        control = new OpenLayers.Control.NavToolbar();\n        t.ok( control instanceof OpenLayers.Control.NavToolbar, \"new OpenLayers.Control.NavToolbar returns object\" );\n        t.ok( map instanceof OpenLayers.Map, \"new OpenLayers.Map creates map\" );\n        map.addControl(control);\n        t.ok( control.map === map, \"Control.map is set to the map object\" );\n        t.ok( map.controls[4] === control, \"map.controls contains control\" );\n        t.eq( parseInt(control.div.style.zIndex), map.Z_INDEX_BASE['Control'] + 7, \"Control div zIndexed properly\" );\n        t.eq( parseInt(map.viewPortDiv.lastChild.style.zIndex), map.Z_INDEX_BASE['Control'] + 7, \"Viewport div contains control div\" );\n        // t.eq( control.div.style.top, \"6px\", \"Control div top located correctly by default\");\n\n    }\n    \n    function test_Control_NavToolbar_defaultControl (t) {\n        t.plan( 1 );\n        var map = new OpenLayers.Map('map');\n\n        var nav = new OpenLayers.Control.NavToolbar();\n        map.addControl(nav);\n        \n        t.eq(nav.controls[0].active, true, \"First control is active\" );\n        \n        map.destroy();\n    }\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/Navigation.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_Control_Navigation_constructor (t) {\n        t.plan( 3 );\n        var temp = OpenLayers.Control.prototype.initialize;\n        OpenLayers.Control.prototype.initialize = function() {\n            t.ok(true, \"OpenLayers.Control's constructor called\");\n        };\n\n        var control = new OpenLayers.Control.Navigation();\n        t.ok( control instanceof OpenLayers.Control.Navigation, \"new OpenLayers.Control returns object\" );\n\n        t.ok( !control.handleRightClicks, \"'handleRightClicks' property is disabled by default\");\n\n        OpenLayers.Control.prototype.initialize = temp;\n    }\n\n    function test_draw(t) {\n        t.plan(5);\n        var map = new OpenLayers.Map({div: 'map', controls: []});\n        var control = new OpenLayers.Control.Navigation();\n        map.addControl(control);\n        t.ok(control.handlers.click instanceof OpenLayers.Handler.Click,\n             \"click handler set in instance\");\n        t.ok(control.dragPan instanceof OpenLayers.Control.DragPan,\n             \"drag pan control set in instance\");\n        t.ok(control.zoomBox instanceof OpenLayers.Control.ZoomBox,\n             \"zoom box control set in instance\");\n        t.ok(control.handlers.wheel instanceof OpenLayers.Handler.MouseWheel,\n             \"mousewheel handler set in instance\");\n        t.ok(control.pinchZoom instanceof OpenLayers.Control.PinchZoom,\n             \"pinch zoom control set in instance\");\n        map.destroy();\n    }\n\n    function test_Control_Navigation_destroy (t) {\n        t.plan(12);\n        \n        var temp = OpenLayers.Control.prototype.destroy;\n        OpenLayers.Control.prototype.destroy = function() {\n            t.ok(true, \"OpenLayers.Control's destroy called\");\n            temp.call(this);\n        };\n\n        var control = {\n            events: {\n                destroy: function() {\n                    t.ok(true, \"events destroyed\");\n                }\n            },\n            'deactivate': function() {\n                t.ok(true, \"navigation control deactivated before being destroyed\");\n            },\n            'dragPan': {\n                'destroy': function() {\n                    t.ok(true, \"dragPan destroyed\");\n                }\n            },\n            'zoomBox': {\n                'destroy': function() {\n                    t.ok(true, \"zoomBox destroyed\");\n                }\n            },\n            'pinchZoom': {\n                'destroy': function() {\n                    t.ok(true, \"pinchZoom destroyed\");\n                }\n            },\n            handlers: {\n                'wheel': {\n                    'destroy': function() {\n                        t.ok(true, \"wheelHandler destroyed\");\n                    }\n                },\n                'click': {\n                    'destroy': function() {\n                        t.ok(true, \"clickHandler destroyed\");\n                    }\n                }\n            }\n        };\n\n        //this will also trigger one test by calling OpenLayers.Control's destroy\n        // and three more for the destruction of dragPan, zoomBox, and wheelHandler\n        OpenLayers.Control.Navigation.prototype.destroy.apply(control, []);\n\n        t.eq(control.dragPan, null, \"'dragPan' set to null\");\n        t.eq(control.zoomBox, null, \"'zoomBox' set to null\");\n        t.eq(control.pinchZoom, null, \"'pinchZoom' set to null\");\n        t.eq(control.handlers, null, \"handlers set to null\");\n\n        OpenLayers.Control.prototype.destroy = temp;\n    }\n\n    function test_Control_Navigation_disableZoomBox(t) {\n        t.plan(2);\n        var nav = new OpenLayers.Control.Navigation();\n        var zb = new OpenLayers.Control.ZoomBox({});\n        nav.zoomBox = zb;\n        zb.activate();\n        nav.disableZoomBox();\n        t.eq(nav.zoomBoxEnabled, false, \"zoom box deactivated\");\n        t.eq(zb.active, false, \"zoom box control deactivated\");\n    }\n\n    function test_Control_Navigation_enableZoomBox(t) {\n        t.plan(2);\n        var nav = new OpenLayers.Control.Navigation();\n        var zb = new OpenLayers.Control.ZoomBox({});\n        nav.zoomBox = zb;\n        nav.active = true;\n        nav.enableZoomBox();\n        t.eq(nav.zoomBoxEnabled, true, \"zoom box activated\");\n        t.eq(zb.active, true, \"zoom box control activated\");\n    }\n\n    function test_Control_Navigation_disableZoomWheel(t) {\n        t.plan(2);\n        var nav = new OpenLayers.Control.Navigation();\n        var wheel = new OpenLayers.Handler.MouseWheel(nav, {});\n        nav.handlers.wheel = wheel;\n        wheel.register = function() {};\n        wheel.unregister = function() {};\n        wheel.activate();\n        nav.disableZoomWheel();\n        t.eq(nav.zoomWheelEnabled, false, \"mouse wheel deactivated\");\n        t.eq(wheel.active, false, \"mouse wheel handler deactivated\");\n    }\n\n    function test_Control_Navigation_enableZoomWheel(t) {\n        t.plan(2);\n        var nav = new OpenLayers.Control.Navigation({zoomWheelEnabled: false});\n        nav.active = true;\n        var wheel = new OpenLayers.Handler.MouseWheel(nav, {});\n        wheel.register = function() {};\n        wheel.unregister = function() {};\n        nav.handlers.wheel = wheel;\n        nav.enableZoomWheel();\n        t.eq(nav.zoomWheelEnabled, true, \"mouse wheel activated\");\n        t.eq(wheel.active, true, \"mouse wheel handler activated\");\n    }\n\n    function test_touches_zoom(t) {\n        t.plan(3);\n        var nav = new OpenLayers.Control.Navigation({zoomWheelEnabled: false});\n        var map = new OpenLayers.Map({\n            div: \"map\",\n            zoomMethod: null,\n            controls: [nav],\n            layers: [\n                new OpenLayers.Layer(null, {isBaseLayer: true})\n            ],\n            center: new OpenLayers.LonLat(0, 0),\n            zoom: 3\n        });\n        t.eq(map.getZoom(), 3, \"map zoom starts at 3\");\n        nav.handlers.click.callback(\"click\", [{lastTouches: [\"foo\", \"bar\"]}]);\n        t.eq(map.getZoom(), 2, \"map zooms out with a two touch tap\");\n        nav.handlers.click.callback(\"click\", [{}]);\n        t.eq(map.getZoom(), 2, \"map doesn't do anything with click\");\n        \n        map.destroy();\n    }\n    \n    function test_documentDrag(t) {\n        \n        t.plan(2);\n\n        /**\n         * These tests confirm that the documentDrag property is false by \n         * default and is passed on to the DragPan control.  Tests of panning\n         * while dragging outside the viewport should go in the DragPan tests.\n         * Tests of the document events and appropriate callbacks from the \n         * handler should go in the Drag handler tests.\n         */\n         \n         var nav = new OpenLayers.Control.Navigation();\n         t.eq(nav.documentDrag, false, \"documentDrag false by default\");\n         // nav.destroy(); // fails if called before draw\n         \n         var map = new OpenLayers.Map({\n             div: document.body,\n             controls: [new OpenLayers.Control.Navigation({documentDrag: true})]\n         });\n         nav = map.controls[0];\n\n         t.eq(nav.dragPan.documentDrag, true, \"documentDrag set on the DragPan control\");\n         map.destroy();\n         \n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 256px; height: 256px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/NavigationHistory.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(4);\n        control = new OpenLayers.Control.NavigationHistory();\n        t.ok(control instanceof OpenLayers.Control.NavigationHistory,\n             \"constructor returns correct instance\");\n        t.eq(control.displayClass, \"olControlNavigationHistory\",\n             \"displayClass is correct\");\n        t.ok(control.next instanceof OpenLayers.Control.Button,\n             \"constructor creates next control\");\n        t.ok(control.previous instanceof OpenLayers.Control.Button,\n             \"constructor creates previous control\");\n    }\n\n    function test_destroy(t) {\n        t.plan(2);\n        control = new OpenLayers.Control.NavigationHistory();\n        control.next.destroy = function() {\n            t.ok(true, \"destroy calls next.destroy\");\n        }\n        control.previous.destroy = function() {\n            t.ok(true, \"destroy calls previous.destroy\");\n        }\n        control.destroy();\n    }\n    \n    function test_previous(t) {\n        var numStates = 10;\n        \n        t.plan(\n            numStates * 3 // for lon, lat, zoom\n            + 3 // for confirming that previous with empty stack works\n        );       \n\n        var history = new Array(numStates);\n        for(var i=0; i<numStates; ++i) {\n            history[i] = {\n                center: new OpenLayers.LonLat(\n                    (i * 360 / numStates) - 180, (i * 180 / numStates) - 90\n                ),\n                zoom: i\n            };\n        }\n        \n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer(\n            \"test\", {isBaseLayer: true}\n        );\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.NavigationHistory();\n        map.addControl(control);\n        \n        // set previous states\n        for(i=0; i<numStates; ++i) {\n            map.setCenter(history[i].center, history[i].zoom);\n        }\n        // test previous states\n        for(i=numStates-1; i>=0; --i) {\n            t.eq(map.getCenter().lon, history[i].center.lon, \"(step \" + i + \") lon correct\");\n            t.eq(map.getCenter().lat, history[i].center.lat, \"(step \" + i + \") lat correct\");\n            t.eq(map.getZoom(), history[i].zoom, \"(step \" + i + \") zoom correct\");\n            control.previous.trigger();\n        }\n        // test previous with empty stack\n        t.eq(map.getCenter().lon, history[0].center.lon, \"(step 0 again) lon correct\");\n        t.eq(map.getCenter().lat, history[0].center.lat, \"(step 0 again) lat correct\");\n        t.eq(map.getZoom(), history[0].zoom, \"(step 0 again) zoom correct\");\n    }\n\n    function test_next(t) {\n        var numStates = 10;\n        \n        t.plan(\n            numStates * 3 // for lon, lat, zoom\n            + 3 // for confirming that next with empty stack works\n        );\n\n        var history = new Array(numStates);\n        for(var i=0; i<numStates; ++i) {\n            history[i] = {\n                center: new OpenLayers.LonLat(\n                    (i * 360 / numStates) - 180, (i * 180 / numStates) - 90\n                ),\n                zoom: i\n            };\n        }\n        \n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer(\n            \"test\", {isBaseLayer: true}\n        );\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.NavigationHistory();\n        map.addControl(control);\n        \n        // set previous states\n        for(i=0; i<numStates; ++i) {\n            map.setCenter(history[i].center, history[i].zoom);\n        }\n        // set next states\n        for(i=numStates-1; i>=0; --i) {\n            control.previous.trigger();\n        }\n        // test next states\n        for(i=0; i<numStates; ++i) {\n            t.eq(map.getCenter().lon, history[i].center.lon, \"(step \" + i + \") lon correct\");\n            t.eq(map.getCenter().lat, history[i].center.lat, \"(step \" + i + \") lat correct\");\n            t.eq(map.getZoom(), history[i].zoom, \"(step \" + i + \") zoom correct\");\n            control.next.trigger();\n        }\n        // test next with empty stack\n        t.eq(map.getCenter().lon, history[numStates-1].center.lon, \"(step \" + (numStates-1) + \" again) lon correct\");\n        t.eq(map.getCenter().lat, history[numStates-1].center.lat, \"(step \" + (numStates-1) + \" again) lat correct\");\n        t.eq(map.getZoom(), history[numStates-1].zoom, \"(step \" + (numStates-1) + \" again) zoom correct\");\n    }\n    \n    function test_limit(t) {\n        var numStates = 10;\n        var limit = 3;\n        \n        t.plan(\n            numStates * 6 // for previous & next lon, lat, zoom\n        );\n\n        var history = new Array(numStates);\n        for(var i=0; i<numStates; ++i) {\n            history[i] = {\n                center: new OpenLayers.LonLat(\n                    (i * 360 / numStates) - 180, (i * 180 / numStates) - 90\n                ),\n                zoom: i\n            };\n        }\n        \n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer(\n            \"test\", {isBaseLayer: true}\n        );\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.NavigationHistory({limit: limit});\n        map.addControl(control);\n        \n        // set previous states\n        for(i=0; i<numStates; ++i) {\n            map.setCenter(history[i].center, history[i].zoom);\n        }\n        // test previous states (only up to limit should work)\n        var state;\n        for(i=numStates-1; i>=0; --i) {\n            state = Math.max(i, numStates - limit - 1);\n            t.eq(map.getCenter().lon, history[state].center.lon, \"(previous step \" + i + \") lon correct: state \" + state);\n            t.eq(map.getCenter().lat, history[state].center.lat, \"(previous step \" + i + \") lat correct: state \" + state);\n            t.eq(map.getZoom(), history[state].zoom, \"(previous step \" + i + \") zoom correct: state \" + state);\n            control.previous.trigger();\n        }\n        // test next states\n        for(i=0; i<numStates; ++i) {\n            state = Math.min(numStates - 1, numStates - limit - 1 + i);\n            t.eq(map.getCenter().lon, history[state].center.lon, \"(next step \" + i + \") lon correct: state \" + state);\n            t.eq(map.getCenter().lat, history[state].center.lat, \"(next step \" + i + \") lat correct: state \" + state);\n            t.eq(map.getZoom(), history[state].zoom, \"(next step \" + i + \") zoom correct: state \" + state);\n            control.next.trigger();\n        }\n        \n    }\n\n    function test_clear(t) {\n        t.plan(7);\n        var map = new OpenLayers.Map(\"map\", {zoomMethod: null});\n        var layer = new OpenLayers.Layer(\n            \"test\", {isBaseLayer: true}\n        );\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n\n        var control = new OpenLayers.Control.NavigationHistory();\n        map.addControl(control);\n        \n        t.ok(!control.previous.active, \"previous control not active\");\n        t.ok(!control.next.active, \"next control not active\");\n\n        map.zoomTo(4);\n        t.ok(control.previous.active, \"previous control is active after a move\");\n        t.ok(!control.next.active, \"next control is not active after a move\");\n\n        control.clear();\n        t.eq(control.previousStack.length + control.nextStack.length, 0, \"stacks are empty after a clear\");\n        t.ok(!control.previous.active, \"previous control not active after a clear\");\n        t.ok(!control.next.active, \"next control not active after a clear\");\n\n        control.destroy();\n    }\n\n    function test_reprojection(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer(\n            \"test\", {isBaseLayer: true}\n        );\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n\n        var control = new OpenLayers.Control.NavigationHistory();\n        map.addControl(control);\n\n        map.zoomTo(4);\n        var bounds = map.getExtent().clone();\n        var expected = bounds.transform(new OpenLayers.Projection('EPSG:4326'),\n            new OpenLayers.Projection('EPSG:900913'));\n        // change the projection to EPSG:900913\n        var projSettings = {\n            units: \"m\", \n            maxExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508), \n            maxResolution: 156543.0339\n        };\n        map.setOptions(projSettings);\n        map.projection = 'EPSG:900913';\n        delete projSettings.maxResolution;\n        projSettings.projection = new OpenLayers.Projection('EPSG:900913');\n        layer.addOptions(projSettings);\n        layer.initResolutions();\n\n        map.zoomTo(7);\n\n        // go back one in the history\n        control.previous.trigger();\n\n        t.eq(map.getExtent().left.toFixed(3), expected.left.toFixed(3), \"The extent [left] is reprojected correctly\");\n        t.eq(map.getExtent().right.toFixed(3), expected.right.toFixed(3), \"The extent [right] is reprojected correctly\");\n        // top and bottom cannot be checked here since in EPSG:900913 the extent is not a rectangle so they are adjusted.\n\n        control.destroy();\n\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 100px; height: 100px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/OverviewMap.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var map, control;\n    \n    function test_initialize(t) {\n        t.plan( 2 );\n    \n        control = new OpenLayers.Control.OverviewMap();\n        t.ok( control instanceof OpenLayers.Control.OverviewMap, \n            \"new OpenLayers.Control.OverviewMap returns object\" );\n        t.eq( control.displayClass,\n            \"olControlOverviewMap\", \"displayClass is correct\" );\n    }\n\n    function test_divs_title(t) {\n        t.plan(2);\n    \n        control = new OpenLayers.Control.OverviewMap({\n            maximizeTitle: \"maximize title\",\n            minimizeTitle: \"minimize title\"\n        });\n        map = new OpenLayers.Map('map', {\n            layers: [new OpenLayers.Layer(\"layer\", {isBaseLayer: true})],\n            controls: [control]\n        });\n        map.zoomToMaxExtent();\n        t.eq(control.maximizeDiv.title, \"maximize title\", \"maximizeDiv.title is correct\");\n        t.eq(control.minimizeDiv.title, \"minimize title\", \"minimizeDiv.title is correct\");\n        map.destroy();\n    }\n\n    function test_setMap(t) {\n        t.plan(4);\n\n        var setMapTest = function(map) {\n            t.ok(true, \n                \"Handler.setMap called for \" + this.CLASS_NAME);\n            this.map = map;        \n        };\n        var drag_setMap = OpenLayers.Handler.Drag.prototype.setMap;\n        OpenLayers.Handler.Drag.prototype.setMap = setMapTest;\n        var click_setMap = OpenLayers.Handler.Click.prototype.setMap;\n        OpenLayers.Handler.Click.prototype.setMap = setMapTest;\n\n        map = new OpenLayers.Map('map', {\n            layers  : [new OpenLayers.Layer(\"layer\", {isBaseLayer: true})],\n            controls: []\n        });\n        control = new OpenLayers.Control.OverviewMap();\n    \n        map.addControl(control);\n\n        map.zoomToMaxExtent();\n        t.eq(control.handlers.drag.map.id, control.ovmap.id,\n            \"drag.map is correct\");\n        t.eq(control.handlers.click.map.id, control.ovmap.id,\n            \"click.map is correct\");\n\n        map.destroy();\n        OpenLayers.Handler.Drag.prototype.setMap = drag_setMap;\n        OpenLayers.Handler.Click.prototype.setMap = click_setMap;\n    }\n\n    function test_destroy(t) {\n        t.plan(6);\n\n        // set up\n\n        var log_drag = [], log_click = [], control;\n\n        map = new OpenLayers.Map('map');\n        map.addLayer(new OpenLayers.Layer(\"layer\", {isBaseLayer: true}));\n\n        control = new OpenLayers.Control.OverviewMap();\n        map.addControl(control);\n\n        map.zoomToMaxExtent();\n\n        control.handlers.drag.destroy = function() {\n            log_drag.push({\"map\": !!this.map.events});\n        };\n        control.handlers.click.destroy = function() {\n            log_click.push({\"map\": !!this.map.events});\n        };\n\n        // test\n\n        control.destroy();\n        t.eq(log_drag.length, 2,\n            \"destroy() destroys drag handler twice, expected\");\n        if (log_drag.length == 2) {\n            t.eq(log_drag[0].map, true,\n                \"destroy() destroys drag handler before ovmap is destroyed (0)\");\n            t.eq(log_drag[1].map, false,\n                \"destroy() destroys drag handler after ovmap is destroyed (1)\");\n        }\n        t.eq(log_click.length, 2,\n            \"destroy() destroys click handler twice, expected\");\n        if (log_click.length == 2) {\n            t.eq(log_click[0].map, true,\n                \"destroy() destroys click handler before ovmap is destroyed (0)\");\n            t.eq(log_click[1].map, false,\n                \"destroy() destroys click handler after ovmap is destroyed (1)\");\n        }\n\n        // tear down\n        map.destroy();\n    }\n    \n    function test_addControl (t) {\n        t.plan( 6 );\n        map = new OpenLayers.Map('map');\n        control = new OpenLayers.Control.OverviewMap();\n        t.ok( control instanceof OpenLayers.Control.OverviewMap, \n            \"new OpenLayers.Control.OverviewMap returns object\" );\n        t.ok( map instanceof OpenLayers.Map, \n            \"new OpenLayers.Map creates map\" );\n        map.addControl(control);\n        t.ok( control.map === map, \n            \"Control.map is set to the map object\" );\n        t.ok( map.controls[4] === control, \n            \"map.controls contains control\" );\n        t.eq( parseInt(control.div.style.zIndex), map.Z_INDEX_BASE['Control'] + 5,\n            \"Control div zIndexed properly\" );\n        t.eq( parseInt(map.viewPortDiv.lastChild.style.zIndex), map.Z_INDEX_BASE['Control'] + 5,\n            \"Viewport div contains control div\" );\n\n        map.destroy();\n    }\n    \n    function test_control_events (t) {\n        t.plan( 10 );\n        \n        map = new OpenLayers.Map('map', {\n            // when we recenter, don't waste time animating the panning\n            // without this, the test fails in Firefox 10.0.1 on Linux\n            panMethod: null,\n            layers: [ new OpenLayers.Layer('Test Layer', {isBaseLayer: true}) ]\n        });\n\n        control = new OpenLayers.Control.OverviewMap();\n        map.addControl(control, new OpenLayers.Pixel(20,20));\n\n        var centerLL = new OpenLayers.LonLat(-71,42); \n        map.setCenter(centerLL, 11);\n\n        t.delay_call(\n            0.1, \n            function() {\n                var overviewCenter = control.ovmap.getCenter();\n                var overviewZoom = control.ovmap.getZoom();\n                t.eq(overviewCenter.lon, -71, \n                    \"OverviewMap center lon correct\");\n                t.eq(overviewCenter.lat, 42, \n                    \"OverviewMap center lat correct\");\n                t.eq(overviewZoom, 8, \n                    \"OverviewMap zoom correct\");\n                \n                control.mapDivClick({'xy':new OpenLayers.Pixel(5,5)});\n            },\n            0.1,\n            function() {\n                var cent = map.getCenter();\n                t.eq(cent.lon, -71.3515625, \n                    \"Clicking on OverviewMap has correct effect on map lon\");\n                t.eq(cent.lat, 42.17578125,\n                    \"Clicking on OverviewMap has correct effect on map lat\");\n        \n                control.handlers.drag = {\n                    last: new OpenLayers.Pixel(5,5),\n                    destroy: function() {}\n                };\n                control.rectDrag(new OpenLayers.Pixel(15, 15));\n                control.updateMapToRect();\n            },\n            0.1,\n            function() {\n                var cent = map.getCenter();\n                t.eq(cent.lon, -71.2734375, \n                    \"Dragging on OverviewMap has correct effect on map lon\");\n                t.eq(cent.lat, 42.09765625, \n                    \"Dragging on OverviewMap has correct effect on map lat\");\n                \n                map.setCenter(new OpenLayers.LonLat(0,0), 0);\n                var overviewCenter = control.ovmap.getCenter();\n                var overviewZoom = control.ovmap.getZoom();\n                t.eq(overviewCenter.lon, 0, \n                    \"OverviewMap center lon correct -- second zoom\");\n                t.eq(overviewCenter.lat, 0,\n                    \"OverviewMap center lat correct -- second zoom\");\n                t.eq(overviewZoom, 0,\n                    \"OverviewMap zoomcorrect -- second zoom\");\n                map.destroy();\n            }\n        );\n    }\n\n    function test_initialize_maximized(t) {\n        t.plan(4);\n\n        control = new OpenLayers.Control.OverviewMap()\n        map = new OpenLayers.Map('map', {\n            layers  : [new OpenLayers.Layer(\"layer\", {isBaseLayer: true})],\n            controls: [control]\n        });\n        \n        t.eq(control.maximized, false, \n            \"OverviewMap is not maximized by default\");\n        t.eq(control.element.style.display, 'none', \n            \"OverviewMap.element is not visible\");\n        map.destroy();\n\n        control = new OpenLayers.Control.OverviewMap({\n            maximized: true\n        })\n        map = new OpenLayers.Map('map', {\n            layers  : [new OpenLayers.Layer(\"layer\", {isBaseLayer: true})],\n            controls: [control]\n        });\n        t.eq(control.maximized, true,\n            \"OverviewMap.maximized is set\");\n        t.eq(control.element.style.display, '', \n            \"OverviewMap.element is visible\");\n\n        map.destroy();\n    }\n    \n    function test_custom_div(t) {\n        t.plan(3);\n        var div = document.createElement('div');\n        \n        control = new OpenLayers.Control.OverviewMap({\n          div: div\n        });\n        \n        map = new OpenLayers.Map('map', {\n            layers  : [new OpenLayers.Layer(\"layer\", {isBaseLayer: true})],\n            controls: [control]\n        });\n        \n        t.eq(control.maximizeDiv, null, \n            \"OverviewMap does not create maximize div\");\n        t.eq(control.minimizeDiv, null, \n            \"OverviewMap does not create minimize div\");\n        \n        var exc;\n        try {\n            control.maximizeControl();\n            control.minimizeControl();\n        } catch(e) {\n            exc = e;\n        }\n\n        t.eq(exc, undefined, 'maximize and minimize do not trigger an exception');\n        \n        map.destroy();\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/Pan.html",
    "content": "<!DOCTYPE html>\n<html>\n    <head>\n        <script src=\"../OLLoader.js\"></script>\n        <script type=\"text/javascript\">\n        \nfunction test_Pan_constructor (t) {\n    t.plan( 2 );\n    \n    // setup\n    var control = new OpenLayers.Control.Pan(\n        \"Gargoyle\" // the direction, here mocked up\n    );\n    \n    // tests\n    //\n    t.ok( \n        control instanceof OpenLayers.Control.Pan, \n        \"new OpenLayers.Control.Pan returns object\"\n    );\n    t.eq( \n        control.displayClass, \"olControlPanGargoyle\", \n        \"displayClass is correct\"\n    );\n    \n    // tear down\n    control.destroy();\n}\n\nfunction test_Pan_type (t) {\n    t.plan( 1 );\n    \n    // setup\n    var control = new OpenLayers.Control.Pan();\n    \n    // tests\n    //\n    t.eq( \n        control.type, \n        OpenLayers.Control.TYPE_BUTTON,\n        \"Pan control is of type OpenLayers.Control.TYPE_BUTTON\"\n    );\n    \n    // tear down\n    control.destroy();\n}\n\nfunction test_Pan_constants (t) {\n    var dirs = [\n            'North',\n            'East',\n            'South',\n            'West'\n        ],\n        numDirs = dirs.length,\n        dir, uc_dir;\n    \n    t.plan(numDirs);\n    \n    for ( ; numDirs > 0; numDirs-- ) {\n        dir = dirs[numDirs - 1 ];\n        uc_dir = dir.toUpperCase();\n        \n        t.eq(\n            OpenLayers.Control.Pan[ uc_dir ],\n            dir,\n            \"A constant 'OpenLayers.Control.Pan.\" + uc_dir + \"' is defined \"+\n                \"and has the correct value of '\" + dir + \"'.\"\n        );\n    }\n}\n\nfunction test_Pan_trigger (t) {\n    t.plan( 12 );\n    \n    // set up\n    var controls = {\n            n: new OpenLayers.Control.Pan(OpenLayers.Control.Pan.NORTH),\n            e: new OpenLayers.Control.Pan(OpenLayers.Control.Pan.EAST),\n            s: new OpenLayers.Control.Pan(OpenLayers.Control.Pan.SOUTH),\n            w: new OpenLayers.Control.Pan(OpenLayers.Control.Pan.WEST)\n        },\n        controlKey, control,\n        zoomlevel = 5,\n        center = new OpenLayers.LonLat(25,25),\n        log = {\n            dx: null,\n            dy: null\n        },\n        map = new OpenLayers.Map(\"map\", {\n            allOverlays: true,\n            layers: [\n                new OpenLayers.Layer.Vector()\n            ],\n            center: center,\n            zoom: zoomlevel\n        }),\n        oldZoom;\n    \n    // overwrite native Map::pan\n    map.pan = function(dx, dy) {\n        log = {\n            dx: dx,\n            dy: dy\n        };\n        OpenLayers.Map.prototype.pan.apply(map, arguments);\n    };\n    \n    oldCenter = map.getCenter().toString();\n    \n    for (controlKey in controls) {\n        if (controls.hasOwnProperty(controlKey)) {\n            control = controls[controlKey];\n            // trigger the control; nothing should change, we aren't added yet.\n            control.trigger();\n            \n            t.ok(\n                log.dx === null && log.dy === null, \n                'Calling trigger on a non added control doesn\\'t do anything.'\n            );\n            \n            // reset log object\n            log = {\n                dx: null,\n                dy: null\n            };\n        }\n    }\n    \n    // now lets add the controls, and trigger them again\n    for (controlKey in controls) {\n        if (controls.hasOwnProperty(controlKey)) {\n            control = controls[controlKey];\n            map.addControl(control);\n            // trigger again, now ...\n            control.trigger();\n            \n            // ... the center should change ...\n            t.ok(\n                log.dx !== null && log.dy !== null,\n                'Calling trigger on an added pan control calls map.pan()... '\n            );\n            \n            // ... with sane arguments according to the passed direction.\n            switch (control.direction) {\n                case OpenLayers.Control.Pan.NORTH: \n                    t.ok(\n                        log.dx === 0 && log.dy < 0,\n                        '... with sane arguments: pan north only results in ' +\n                            'negative delta y'\n                    );\n                    break;\n                case OpenLayers.Control.Pan.SOUTH: \n                    t.ok(\n                        log.dx === 0 && log.dy > 0,\n                        '... with sane arguments: pan south only results in ' +\n                            'positive delta y'\n                    );\n                    break;\n                case OpenLayers.Control.Pan.WEST: \n                    t.ok(\n                        log.dx < 0 && log.dy === 0,\n                        '... with sane arguments: pan west only results in ' +\n                            'negative delta x'\n                    );\n                    break;\n                case OpenLayers.Control.Pan.EAST: \n                    t.ok(\n                        log.dx > 0 && log.dy === 0,\n                        '... with sane arguments: pan east only results in ' +\n                            'positive delta x'\n                    );\n                    break;\n            }\n            \n            // reset log-object\n            log = {\n                dx: null,\n                dy: null\n            };\n            // always set to initial center and zoom:\n            map.setCenter(center, zoomlevel);\n        }\n    }\n    \n    // tear down\n    for (controlKey in controls) {\n        if (controls.hasOwnProperty(controlKey)) {\n            control = controls[controlKey];\n            control.destroy();\n        }\n    }\n    map.destroy();\n}\n    \n        </script>\n    </head>\n    <body>\n        <div id=\"map\" style=\"width: 1000px; height: 1000px;\"></div>\n    </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/PanPanel.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    function test_constructor (t) {\n        t.plan(2);\n        \n        // set up\n        var control;\n\n        // tests\n        control = new OpenLayers.Control.PanPanel({slideFactor: 200});\n        t.ok(control.controls[0].slideFactor == 200 &&\n             control.controls[1].slideFactor == 200 &&\n             control.controls[2].slideFactor == 200 &&\n             control.controls[3].slideFactor == 200,\n             \"ctor sets slideFactor in all Pan controls\");\n        \n        control.destroy();\n\n        control = new OpenLayers.Control.PanPanel({slideRatio: .5});\n        t.ok(control.controls[0].slideRatio == .5 &&\n             control.controls[1].slideRatio == .5 &&\n             control.controls[2].slideRatio == .5 &&\n             control.controls[3].slideRatio == .5,\n             \"ctor sets slideRatio in all Pan controls\");\n        \n        control.destroy();\n    }\n    \n    function test_slide(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\", {\n            panMethod: null,\n            controls: [\n                new OpenLayers.Control.PanPanel(),\n                new OpenLayers.Control.PanPanel({slideRatio: .5})\n            ],\n            layers: [new OpenLayers.Layer(null, {isBaseLayer: true})],\n            center: new OpenLayers.LonLat(0, 0),\n            zoom: 1\n        });\n        \n        map.controls[0].controls[0].trigger();\n        map.controls[0].controls[2].trigger();\n        map.pan(-50, 50);\n        t.eq(map.getCenter().toShortString(), \"0, 0\", \"correct pan distance with slideFactor\");\n        \n        map.controls[1].controls[0].trigger();\n        map.controls[1].controls[2].trigger();\n        map.pan(-128, 64);\n        t.eq(map.getCenter().toShortString(), \"0, 0\", \"correct pan distance with slideRatio\");        \n\n        map.destroy();\n    }\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 256px; height: 128px;\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/PanZoom.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var map;\n    function test_Control_PanZoom_constructor (t) {\n        t.plan(4);\n\n        control = new OpenLayers.Control.PanZoom();\n        t.ok(control instanceof OpenLayers.Control.PanZoom, \"new OpenLayers.Control.PanZoom returns object\");\n        t.eq(control.displayClass,  \"olControlPanZoom\", \"displayClass is correct\");\n        control = new OpenLayers.Control.PanZoom({position: new OpenLayers.Pixel(100,100)});\n        t.eq(control.position.x, 100, \"PanZoom X Set correctly.\");\n        t.eq(control.position.y, 100, \"PanZoom y Set correctly.\");\n    }\n    function test_Control_PanZoom_addControl (t) {\n        t.plan(8);\n        map = new OpenLayers.Map('map');\n        control = new OpenLayers.Control.PanZoom();\n        t.ok(control instanceof OpenLayers.Control.PanZoom, \"new OpenLayers.Control.PanZoom returns object\");\n        t.ok(map instanceof OpenLayers.Map, \"new OpenLayers.Map creates map\");\n        map.addControl(control);\n        t.ok(control.map === map, \"Control.map is set to the map object\");\n        t.ok(map.controls[4] === control, \"map.controls contains control\");\n        t.eq(parseInt(control.div.style.zIndex), map.Z_INDEX_BASE['Control'] + 5, \"Control div zIndexed properly\");\n        t.eq(parseInt(map.viewPortDiv.lastChild.style.zIndex), map.Z_INDEX_BASE['Control'] + 5, \"Viewport div contains control div\");\n        t.eq(control.div.style.top, \"4px\", \"Control div top located correctly by default\");\n\n        var control2 = new OpenLayers.Control.PanZoom();\n        map.addControl(control2, new OpenLayers.Pixel(100,100));\n        t.eq(control2.div.style.top, \"100px\", \"2nd control div is located correctly\");\n    }\n\n    function test_Control_PanZoom_removeButtons(t) {\n        t.plan(2);\n        map = new OpenLayers.Map(\"map\");\n        control = new OpenLayers.Control.PanZoom();\n        map.addControl(control);\n        control.removeButtons();\n        t.eq(control.buttons.length, 0, \"buttons array cleared correctly\");\n        t.eq(control.div.childNodes.length, 0, \"control div is empty\");\n    }\n\n    function test_Control_PanZoom_control_events (t) {\n\n        // IE 9+ does support the standard document.createEvent,\n        // event.initMouseEvent, and elem.dispatchEvent calls, so it\n        // should be possible to simulate clicks in this browser.\n        // For example it looks like jQuery UI does simulate events\n        // using document.createElement in IE 9+. See\n        // https://github.com/jquery/jquery-ui/blob/master/tests/jquery.simulate.js.\n        // I haven't been able to make it work though.\n\n        if (!window.document.createEvent ||\n             OpenLayers.BROWSER_NAME == \"msie\" ||\n             OpenLayers.BROWSER_NAME == \"opera\" ||\n             !t.open_window) {\n\n            t.plan(0);\n            t.debug_print(\"FIXME: This browser does not support the PanZoom test at this time.\");\n        } else {\n            t.plan(35);\n            t.open_window(\"Control/PanZoom.html\", function(wnd) {\n                t.delay_call(5, function() {\n                    var flag;\n                    function setFlag(evt) {\n                        flag[evt.type] = true;\n                    }\n                    function resetFlags() {\n                        flag = {\n                            mousedown: false,\n                            mouseup: false,\n                            click: false,\n                            dblclick: false\n                        };\n                    }\n                    resetFlags();\n\n                    wnd.mapper.events.register(\"mousedown\", mapper, setFlag);\n                    wnd.mapper.events.register(\"mouseup\", mapper, setFlag);\n                    wnd.mapper.events.register(\"click\", mapper, setFlag);\n                    wnd.mapper.events.register(\"dblclick\", mapper, setFlag);\n\n                    simulateClick(wnd, wnd.control.buttons[0]);\n                    t.delay_call(2, function() {\n                        t.ok(wnd.mapper.getCenter().lat > wnd.centerLL.lat, \"1) Pan up works correctly\");\n                        t.ok(!flag.mousedown, \"1) mousedown does not get to the map\");\n                        t.ok(!flag.mouseup, \"1) mouseup does not get to the map\");\n                        t.ok(!flag.click, \"1) click does not get to the map\");\n                        t.ok(!flag.dblclick, \"1) dblclick does not get to the map\");\n                        resetFlags();\n\n                        simulateClick(wnd, wnd.control.buttons[1]);\n                    }, 2, function() {\n                        t.ok(wnd.mapper.getCenter().lon < wnd.centerLL.lon, \"2) Pan left works correctly\");\n                        t.ok(!flag.mousedown, \"2) mousedown does not get to the map\");\n                        t.ok(!flag.mouseup, \"2) mouseup does not get to the map\");\n                        t.ok(!flag.click, \"2) click does not get to the map\");\n                        t.ok(!flag.dblclick, \"2) dblclick does not get to the map\");\n                        resetFlags();\n\n                        simulateClick(wnd, wnd.control.buttons[2]);\n                    }, 2, function() {\n                        t.ok(wnd.mapper.getCenter().lon == wnd.centerLL.lon, \"3) Pan right works correctly\");\n                        t.ok(!flag.mousedown, \"3) mousedown does not get to the map\");\n                        t.ok(!flag.mouseup, \"3) mouseup does not get to the map\");\n                        t.ok(!flag.click, \"3) click does not get to the map\");\n                        t.ok(!flag.dblclick, \"3) dblclick does not get to the map\");\n                        resetFlags();\n\n                        simulateClick(wnd, wnd.control.buttons[3]);\n                    }, 2, function() {\n                        t.ok(wnd.mapper.getCenter().lat == wnd.centerLL.lat, \"4) Pan down works correctly\");\n                        t.ok(!flag.mousedown, \"4) mousedown does not get to the map\");\n                        t.ok(!flag.mouseup, \"4) mouseup does not get to the map\");\n                        t.ok(!flag.click, \"4) click does not get to the map\");\n                        t.ok(!flag.dblclick, \"4) dblclick does not get to the map\");\n                        resetFlags();\n\n                        simulateClick(wnd, wnd.control.buttons[4]);\n                    }, 2, function() {\n                        t.eq(wnd.mapper.getZoom(), 6, \"5) zoomin works correctly\");\n                        t.ok(!flag.mousedown, \"5) mousedown does not get to the map\");\n                        t.ok(!flag.mouseup, \"5) mouseup does not get to the map\");\n                        t.ok(!flag.click, \"5) click does not get to the map\");\n                        t.ok(!flag.dblclick, \"5) dblclick does not get to the map\");\n                        resetFlags();\n\n                        simulateClick(wnd, wnd.control.buttons[6]);\n                    }, 2, function() {\n                        t.eq(wnd.mapper.getZoom(), 5, \"6) zoomout works correctly\");\n                        t.ok(!flag.mousedown, \"6) mousedown does not get to the map\");\n                        t.ok(!flag.mouseup, \"6) mouseup does not get to the map\");\n                        t.ok(!flag.click, \"6) click does not get to the map\");\n                        t.ok(!flag.dblclick, \"6) dblclick does not get to the map\");\n                        resetFlags();\n\n                        simulateClick(wnd, wnd.control.buttons[5]);\n                    }, 2, function() {\n                        t.eq(wnd.mapper.getZoom(), 2, \"7) zoomworld works correctly\");\n                        t.ok(!flag.mousedown, \"7) mousedown does not get to the map\");\n                        t.ok(!flag.mouseup, \"7) mouseup does not get to the map\");\n                        t.ok(!flag.click, \"7) click does not get to the map\");\n                        t.ok(!flag.dblclick, \"7) dblclick does not get to the map\");\n                        resetFlags();\n                    });\n                });\n            }, 30);\n        }\n    }\n\n    function test_slideRatio(t) {\n        t.plan(4);\n\n        var control = new OpenLayers.Control.PanZoom({\n            slideRatio: .5\n        });\n\n        var map = new OpenLayers.Map();\n\n        map.addControl(control);\n        control.draw();\n        control.activate();\n\n        map.getSize = function() {\n            return {\n                w: 250,\n                h: 100\n            }\n        };\n\n        var delta, dir;\n        var buttons = control.buttons;\n        map.pan = function(dx, dy){\n            t.eq([dx,dy],delta,\"Panning \" + dir + \" sets right delta with slideRatio\");\n        };\n\n        //up\n        var delta = [0, -50];\n        var dir = \"up\";\n        var evt = {buttonElement: buttons[0]};\n        control.onButtonClick.call(control, evt);\n\n        //left\n        var delta = [-125, 0];\n        var dir = \"left\";\n        evt.buttonElement = buttons[1];\n        control.onButtonClick.call(control, evt);\n\n        //right\n        var delta = [125, 0];\n        var dir = \"right\";\n        evt.buttonElement = buttons[2];\n        control.onButtonClick.call(control, evt);\n\n        //down\n        var delta = [0, 50];\n        var dir = \"down\";\n        evt.buttonElement = buttons[3];\n        control.onButtonClick.call(control, evt);\n\n        map.destroy();\n    }\n\n    function simulateClick(wnd, elem) {\n      var evt = wnd.document.createEvent(\"MouseEvents\");\n      evt.initMouseEvent(\"mousedown\", true, true, wnd, 0, 0, 0, 0, 0, false, false, false, false, 0, null);\n      elem.dispatchEvent(evt);\n\n      evt = wnd.document.createEvent(\"MouseEvents\");\n      evt.initMouseEvent(\"mouseup\", true, true, wnd, 0, 0, 0, 0, 0, false, false, false, false, 0, null);\n      elem.dispatchEvent(evt);\n\n      evt = wnd.document.createEvent(\"MouseEvents\");\n      evt.initMouseEvent(\"click\", true, true, wnd, 0, 0, 0, 0, 0, false, false, false, false, 0, null);\n      elem.dispatchEvent(evt);\n\n      evt = wnd.document.createEvent(\"MouseEvents\");\n      evt.initMouseEvent(\"dblclick\", true, true, wnd, 0, 0, 0, 0, 0, false, false, false, false, 0, null);\n      elem.dispatchEvent(evt);\n    }\n\n    function loader() {\n        control = new OpenLayers.Control.PanZoom();\n\n        mapper = new OpenLayers.Map('map', { controls: [control]});\n\n\n        var layer = new OpenLayers.Layer.WMS(\"Test Layer\",\n            \"http://labs.metacarta.com/wms-c/Basic.py?\",\n            {layers: \"basic\"});\n        mapper.addLayer(layer);\n\n        centerLL = new OpenLayers.LonLat(0,0);\n        mapper.setCenter(centerLL, 5);\n    }\n\n\n  </script>\n</head>\n<body onload=\"loader()\">\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/PanZoomBar.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var map;\n    function test_Control_PanZoomBar_constructor (t) {\n        t.plan( 4 );\n\n        control = new OpenLayers.Control.PanZoomBar({position: new OpenLayers.Pixel(100,100)});\n        t.ok( control instanceof OpenLayers.Control.PanZoomBar, \"new OpenLayers.Control.PanZoomBar returns object\" );\n        t.eq( control.displayClass,  \"olControlPanZoomBar\", \"displayClass is correct\" );\n        t.eq( control.position.x, 100, \"PanZoom X Set correctly.\");\n        t.eq( control.position.y, 100, \"PanZoom y Set correctly.\");\n    }\n    function test_Control_PanZoomBar_addControl (t) {\n        t.plan( 8 );\n        map = new OpenLayers.Map('map', {controls:[]});\n        var layer = new OpenLayers.Layer.WMS(\"Test Layer\",\n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(layer);\n        control = new OpenLayers.Control.PanZoomBar();\n        t.ok( control instanceof OpenLayers.Control.PanZoomBar, \"new OpenLayers.Control.PanZoomBar returns object\" );\n        t.ok( map instanceof OpenLayers.Map, \"new OpenLayers.Map creates map\" );\n        map.addControl(control);\n        t.ok( control.map === map, \"Control.map is set to the map object\" );\n        t.ok( map.controls[0] === control, \"map.controls contains control\" );\n        t.eq( parseInt(control.div.style.zIndex), 1001, \"Control div zIndexed properly\" );\n        t.eq( parseInt(map.viewPortDiv.lastChild.style.zIndex), 1001, \"Viewport div contains control div\" );\n        t.eq( control.div.style.top, \"4px\", \"Control div top located correctly by default\");\n\n        var control2 = new OpenLayers.Control.PanZoomBar();\n        map.addControl(control2, new OpenLayers.Pixel(100,100));\n        t.eq( control2.div.style.top, \"100px\", \"2nd control div is located correctly\");\n    }\n    \n    function test_draw(t) {\n        t.plan(3);\n        map = new OpenLayers.Map('map', {controls:[]});\n        var layer = new OpenLayers.Layer.WMS(\"Test Layer\",\n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        control = new OpenLayers.Control.PanZoomBar();\n        map.addControl(control);\n        t.eq(control.zoombarDiv.style.height, '176px', \"Bar's height is correct.\");\n\n        map.baseLayer.wrapDateLine = true;\n\n        control.redraw();\n        t.eq(control.zoombarDiv.style.height, '154px', \"Bar's height is correct after minZoom restriction.\");\n\n        map.div.style.width = \"512px\";\n        map.updateSize();\n        t.eq(control.zoombarDiv.style.height, '165px', \"Bar's height is correct after resize and minZoom restriction.\");\n\n        map.div.style.width = \"1024px\";\n        map.destroy();\n    }\n\n    function test_Control_PanZoomBar_clearDiv(t) {\n        t.plan(2);\n        map = new OpenLayers.Map('map', {controls:[]});\n        var layer = new OpenLayers.Layer.WMS(\"Test Layer\",\n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(layer);\n        control = new OpenLayers.Control.PanZoomBar();\n        map.addControl(control);\n        control.removeButtons();\n        var div = control.div;\n        map.destroy();\n        t.eq(div.childNodes.length, 0, \"control's div cleared.\");\n        t.eq(control.zoombarDiv, null, \"zoombar div nullified.\")\n    }\n\n    function test_Control_PanZoomBar_onButtonClick (t) {\n        t.plan(2);\n        map = new OpenLayers.Map('map', {controls:[], zoomMethod: null});\n        var layer = new OpenLayers.Layer.WMS(\"Test Layer\",\n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(layer);\n        control = new OpenLayers.Control.PanZoomBar();\n        map.addControl(control);\n        control.onButtonClick({'buttonXY': {'x': 0, 'y': 50}, buttonElement: control.zoombarDiv});\n        t.eq(map.zoom, 11, \"zoom is correct on standard map\");\n\n        map.fractionalZoom = true;\n        control.onButtonClick({'buttonXY': {'x': 0, 'y': 49}, buttonElement: control.zoombarDiv});\n        t.eq(map.zoom.toFixed(3), '10.545', \"zoom is correct on fractional zoom map\");\n\n    }\n\n    function test_Control_PanZoomBar_forceFixedZoomLevel_onButtonClick(t){\n        t.plan(1);\n        map = new OpenLayers.Map('map', {\n            controls: [],\n            fractionalZoom: true,\n            zoomMethod: null\n        });\n        var layer = new OpenLayers.Layer.WMS(\"Test Layer\", \"http://octo.metacarta.com/cgi-bin/mapserv?\", {\n            map: \"/mapdata/vmap_wms.map\",\n            layers: \"basic\"\n        });\n        map.addLayer(layer);\n        control = new OpenLayers.Control.PanZoomBar({\n            forceFixedZoomLevel: true\n        });\n        map.addControl(control);\n        \n        control.onButtonClick({\n            'buttonXY': {\n                'x': 0,\n                'y': 49\n            },\n            buttonElement: control.zoombarDiv\n        });\n        t.eq(map.zoom, 11, \"forceFixedZoomLevel makes sure that after a div click only fixed zoom levels are used even if the map has fractionalZoom\");\n    }     \n         \n    function test_Control_PanZoomBar_forceFixedZoomLevel_zoomBarUp (t) {     \n        var numRandomDrags = 25;\n        // plan one static recorded test and two for every random drag\n        t.plan(1 + (numRandomDrags * 2));\n        \n        \n        var map = new OpenLayers.Map('map', {\n            controls: [],\n            fractionalZoom: true,\n            zoomMethod: null\n        });\n        var layer = new OpenLayers.Layer.WMS(\"Test Layer\", \"http://octo.metacarta.com/cgi-bin/mapserv?\", {\n            map: \"/mapdata/vmap_wms.map\",\n            layers: \"basic\"\n        });\n        map.addLayer(layer);\n        \n        // zoom to a fractional ZoomLevel initially:\n        map.setCenter(new OpenLayers.LonLat(0, 0), 9.545);\n        \n        control = new OpenLayers.Control.PanZoomBar({\n            forceFixedZoomLevel: true\n        });\n        map.addControl(control);\n        \n        // The y values come from manually recording real values in an example\n        var evt = {\n            'xy': {\n                'x': 0,\n                'y': -10.633\n            },\n            which: 1\n        };\n        control.zoomStart = {\n            'x': 0,\n            'y': 5.366\n        };\n        control.mouseDragStart = {\n            'x': 0,\n            'y': -10.633\n        };\n        control.deltaY = control.zoomStart.y - evt.xy.y\n        control.zoomBarUp(evt);\n        t.eq(map.zoom, 11, \"forceFixedZoomLevel makes sure that after dragging of the handle only fixed zoom levels are used even if the map has fractionalZoom\");\n        \n        // randomly drag the handle around\n        // we should never get a zoom < 0 or a non-integer zoom, regardless of\n        // captured random values for start and end of the drag.\n        for (var i = 0; i < numRandomDrags; i++) {\n            var randStartY = Math.random() * 10 * ((i % 2 === 0) ? -1 : 1);\n            var randStopY = Math.random() * 160 * ((i % 2 === 1) ? -1 : 1);\n            var evt = {\n                'xy': {\n                    'x': 0,\n                    'y': randStopY\n                },\n                which: 1\n            };\n            control.zoomStart = {\n                'x': 0,\n                'y': randStartY\n            };\n            control.mouseDragStart = {\n                'x': 0,\n                'y': randStopY\n            };\n            control.deltaY = control.zoomStart.y - evt.xy.y\n            control.zoomBarUp(evt);\n            \n            t.eq(Math.floor(map.zoom), Math.ceil(map.zoom), 'Only integer zooms after random handle drag with forceFixedZoomLevel=true and fractionalZoom=true (current zoom was ' + map.zoom + ')');\n            t.ok(map.zoom >= 0, 'map.zoom is never < 0 after random handle drag with forceFixedZoomLevel=true and fractionalZoom=true');\n        }\n    }\n\n    function test_Control_PanZoomBar_shows (t) {\n        t.plan(22);\n\n        var control, map;\n\n        control = new OpenLayers.Control.PanZoomBar({panIcons: true, zoomWorldIcon: false});\n        map = new OpenLayers.Map('map', {controls: [control]});\n        t.eq(control.buttons.length, 6, \"(a) pan, no world - expected number of buttons\");\n        t.ok(control.buttons[0].id.match(\"_panup$\"), \"(a) pan, no world - pan up\");\n        t.ok(control.buttons[1].id.match(\"_panleft$\"), \"(a) pan, no world - pan left\");\n        t.ok(control.buttons[2].id.match(\"_panright$\"), \"(a) pan, no world - pan right\");\n        t.ok(control.buttons[3].id.match(\"_pandown$\"), \"(a) pan, no world - pan down\");\n        t.ok(control.buttons[4].id.match(\"_zoomin$\"), \"(a) pan, no world - zoom in\");\n        t.ok(control.buttons[5].id.match(\"_zoomout$\"), \"(a) pan, no world - zoom out\");\n        map.destroy();\n\n        control = new OpenLayers.Control.PanZoomBar({panIcons: true, zoomWorldIcon: true});\n        map = new OpenLayers.Map('map', {controls:[control]});\n        t.eq(control.buttons.length, 7, \"(b) pan, world - expected number of buttons\");\n        t.ok(control.buttons[0].id.match(\"_panup$\"), \"(b) pan, world - pan up\");\n        t.ok(control.buttons[1].id.match(\"_panleft$\"), \"(b) pan, world - pan left\");\n        t.ok(control.buttons[2].id.match(\"_zoomworld$\"), \"(b) pan, world - zoom world\");\n        t.ok(control.buttons[3].id.match(\"_panright$\"), \"(b) pan, world - pan right\");\n        t.ok(control.buttons[4].id.match(\"_pandown$\"), \"(b) pan, world - pan down\");\n        t.ok(control.buttons[5].id.match(\"_zoomin$\"), \"(b) pan, world - zoom in\");\n        t.ok(control.buttons[6].id.match(\"_zoomout$\"), \"(b) pan, world - zoom out\");\n        map.destroy();\n\n        control = new OpenLayers.Control.PanZoomBar({panIcons: false, zoomWorldIcon: false});\n        map = new OpenLayers.Map('map', {controls:[control]});\n        t.eq(control.buttons.length, 2, \"(c) no pan, no world - expected number of buttons\");\n        t.ok(control.buttons[0].id.match(\"_zoomin$\"), \"(c) no pan, no world - zoom in\");\n        t.ok(control.buttons[1].id.match(\"_zoomout$\"), \"(c) no pan, no world - zoom out\");\n        map.destroy();\n\n        control = new OpenLayers.Control.PanZoomBar({panIcons: false, zoomWorldIcon: true});\n        map = new OpenLayers.Map('map', {controls:[control]});\n        t.eq(control.buttons.length, 3, \"(d) no pan, world - expected number of buttons\");\n        t.ok(control.buttons[0].id.match(\"_zoomin$\"), \"(d) no pan, world - zoom in\");\n        t.ok(control.buttons[1].id.match(\"_zoomout$\"), \"(d) no pan, world - zoom out\");\n        t.ok(control.buttons[2].id.match(\"_zoomworld$\"), \"(d) no pan, world - zoom world\");\n        map.destroy();\n    }\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/Panel.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    function test_Control_Panel_constructor (t) {\n        t.plan( 2 );\n    \n        control = new OpenLayers.Control.Panel();\n        t.ok( control instanceof OpenLayers.Control.Panel, \"new OpenLayers.Control returns object\" );\n        t.eq( control.displayClass,  \"olControlPanel\", \"displayClass is correct\" );\n    }\n    function test_Control_Panel_constructor2 (t) {\n        t.plan(19);\n        var map = new OpenLayers.Map('map');\n        var toolControl = new OpenLayers.Control.ZoomBox();\n        var AnotherToolControl = OpenLayers.Class(OpenLayers.Control, {\n              CLASS_NAME: 'mbControl.TestTool',\n              type: OpenLayers.Control.TYPE_TOOL\n        });\n        var anotherToolControl = new AnotherToolControl();\n        var ToggleControl = OpenLayers.Class(OpenLayers.Control, {\n              CLASS_NAME: 'mbControl.TestToggle',\n              type: OpenLayers.Control.TYPE_TOGGLE\n        });\n\n        var toggleControl = new ToggleControl();\n        var buttonControl = new OpenLayers.Control.Button({\n            trigger: function () {\n                t.ok(true, \"trigger function of button is called.\");\n            }\n        });\n\n        var panel = new OpenLayers.Control.Panel(\n            {defaultControl: anotherToolControl});\n        t.ok(panel instanceof OpenLayers.Control.Panel,\n              \"new OpenLayers.Control.Panel returns object\");\n        panel.redraw = function(){\n            panel.redrawsCount++;\n            OpenLayers.Control.Panel.prototype.redraw.apply(this, arguments);\n        };\n\n        // To get length of events.listeners error-free\n        var getListenerLength= function(events,key){\n            if(!events) {\n                return -2; // events is destroyed\n            } else if(!events.listeners) {\n                return -1; // events is destroyed\n            } else if(!events.listeners[key]) {\n                return 0; // no listener in event\n            } else {\n                return events.listeners[key].length;\n            }\n        };\n        var toolEventListenerLength = getListenerLength(toolControl.events,\"activate\");\n        panel.addControls([toolControl, anotherToolControl, toggleControl]);\n        t.eq(panel.controls.length, 3,\n              \"added three controls to the panel\");\n        panel.addControls([buttonControl]);\n\n        panel.redrawsCount = 0;\n        map.addControl(panel);\n        t.eq(getListenerLength(toolControl.events,\"activate\"), toolEventListenerLength+1,\n            \"toolControl additional listener for \\\"activate\\\" after adding Panel to the map.\");\n        t.ok((panel.redrawsCount > 0), \"Redraw called on add panel to map \" +\n            panel.redrawsCount + \" times.\");\n        t.ok((panel.active),\"Panel is active after add panel to map.\");\n\n        panel.redrawsCount = 0;\n        panel.addControls(new AnotherToolControl());\n        t.ok((panel.redrawsCount > 0),\n            \"Redraw called on add control to panel after add panel to map \" +\n            panel.redrawsCount + \" times.\");\n\n        panel.deactivate();\n        panel.redrawsCount = 0;\n        panel.activate();\n        t.ok((panel.redrawsCount > 0),\"Redraw called on activate panel \" +\n            panel.redrawsCount + \" times.\");\n\n        panel.activateControl(toolControl);\n        t.ok(toolControl.active && !anotherToolControl.active && !toggleControl.active && !buttonControl.active,\n              \"activated one tool control, the other one is inactive and the toggle & button controls also.\");\n\n        panel.activateControl(toggleControl);\n        t.eq(toggleControl.panel_div.className,\"mbControlTestToggleItemActive olButton\",\n            \"className of icon div for toggle control is active.\");\n        t.ok(toolControl.active && !anotherToolControl.active && toggleControl.active,\n              \"activated the toggle control, which has no influence on the tool & togggle controls.\");\n        panel.activateControl(buttonControl);\n        t.ok(toolControl.active && !anotherToolControl.active && toggleControl.active,\n              \"activateContol calling for button, which has no influence on the tool & togggle controls.\");\n        t.ok(!buttonControl.active,\n              \"activateContol calling for button, button remains inactive.\");\n        buttonControl.activate();\n        t.ok(buttonControl.active && toolControl.active && !anotherToolControl.active && toggleControl.active,\n              \"activated the button control, which has no influence on the tool & togggle controls.\");\n\n        panel.activateControl(anotherToolControl);\n        t.eq(anotherToolControl.panel_div.className,\"mbControlTestToolItemActive olButton\",\n            \"className of icon div for anotherToolControl is active.\");\n        t.eq(toolControl.panel_div.className,\"olControlZoomBoxItemInactive olButton\",\n            \"className of icon div for toolControl is inactive.\");\n        t.ok(!toolControl.active && anotherToolControl.active && toggleControl.active,\n              \"activated the other tool control, the first one is inactive and the toggle control still active.\");\n        t.ok(buttonControl.active,\n              \"activated the other tool control, the button control still active.\");\n\n        panel.destroy();\n        t.eq(getListenerLength(toolControl.events,\"activate\"), toolEventListenerLength,\n            \"toolControl additional listeners removed after destroy Panel.\");\n        map.destroy();\n    }\n    function test_Control_Panel_titles (t) { \n        t.plan(2); \n        var panel = new OpenLayers.Control.Panel(); \n        var toolControl = new OpenLayers.Control.ZoomBox({ \n            title:\"Zoom box: Selecting it you can zoom on an area by clicking and dragging.\" \n        }); \n        panel.addControls([toolControl]); \n        t.eq(panel.controls.length, 1, \"added a control to the panel\"); \n        t.eq(panel.controls[0].title, toolControl.panel_div.title, \"the title is correctly set\"); \n    } \n    \n    function test_Control_Panel_getBy(t) {\n        \n        var panel = {\n            getBy: OpenLayers.Control.Panel.prototype.getBy,\n            getControlsBy: OpenLayers.Control.Panel.prototype.getControlsBy,\n            controls: [\n                {foo: \"foo\", id: Math.random()},\n                {foo: \"bar\", id: Math.random()},\n                {foo: \"foobar\", id: Math.random()},\n                {foo: \"foo bar\", id: Math.random()},\n                {foo: \"foo\", id: Math.random()}\n            ]\n        };\n\n        var cases = [\n            {\n                got: panel.getControlsBy(\"foo\", \"foo\"),\n                expected: [panel.controls[0], panel.controls[4]],\n                message: \"(string literal) got two controls matching foo\"\n            }, {\n                got: panel.getControlsBy(\"foo\", \"bar\"),\n                expected: [panel.controls[1]],\n                message: \"(string literal) got one control matching foo\"\n            }, {\n                got: panel.getControlsBy(\"foo\", \"barfoo\"),\n                expected: [],\n                message: \"(string literal) got empty array for no foo match\"\n            }, {\n                got: panel.getControlsBy(\"foo\", /foo/),\n                expected: [panel.controls[0], panel.controls[2], panel.controls[3], panel.controls[4]],\n                message: \"(regexp literal) got three controls containing string\"\n            }, {\n                got: panel.getControlsBy(\"foo\", /foo$/),\n                expected: [panel.controls[0], panel.controls[4]],\n                message: \"(regexp literal) got three controls ending with string\"\n            }, {\n                got: panel.getControlsBy(\"foo\", /\\s/),\n                expected: [panel.controls[3]],\n                message: \"(regexp literal) got control containing space\"\n            }, {\n                got: panel.getControlsBy(\"foo\", new RegExp(\"BAR\", \"i\")),\n                expected: [panel.controls[1], panel.controls[2], panel.controls[3]],\n                message: \"(regexp object) got layers ignoring case\"\n            }, {\n                got: panel.getControlsBy(\"foo\", {test: function(str) {return str.length > 3;}}),\n                expected: [panel.controls[2], panel.controls[3]],\n                message: \"(custom object) got controls with foo length greater than 3\"\n            }\n        ];\n        t.plan(cases.length);\n        for(var i=0; i<cases.length; ++i) {\n            t.eq(cases[i].got, cases[i].expected, cases[i].message);\n        }\n\n\n    }\n    \n    function test_Control_Panel_saveState (t) { \n        t.plan(11); \n        var map = new OpenLayers.Map('map');\n\n        var defaultControl = new OpenLayers.Control();\n        var panel = new OpenLayers.Control.Panel({\n            defaultControl: defaultControl\n        });\n        panel.addControls([new OpenLayers.Control(), defaultControl]);\n        map.addControl(panel);\n        t.eq(defaultControl.active, true,\n            \"After panel activation default control is active.\");    \n        t.ok(panel.defaultControl,\n            \"defaultControl not nullified after initial panel activation\");          \n        // activate the 1st control\n        panel.activateControl(panel.controls[0]);\n        panel.deactivate();      \n        t.ok(!panel.controls[0].active && !panel.controls[1].active,\n            \"No controls are active after panel deactivation.\");\n        panel.activate();   \n        t.eq(panel.controls[0].active, false,\n            \"After panel reactivation first control is inactive.\");              \n        t.eq(panel.controls[1].active, true,\n            \"After panel reactivation default control is active again.\");\n        panel.destroy();\n\n        defaultControl = new OpenLayers.Control();\n        panel = new OpenLayers.Control.Panel({\n            saveState: true,\n            defaultControl: defaultControl\n        });\n        panel.addControls([new OpenLayers.Control(), defaultControl]);\n        map.addControl(panel);\n        t.eq(defaultControl.active, true,\n            \"After panel activation default control is active.\");    \n        t.eq(panel.defaultControl, null,\n            \"defaultControl nullified after initial panel activation\");          \n        // activate the 1st control, which will deactivate the 2nd\n        panel.activateControl(panel.controls[0]);\n        t.eq(panel.controls[1].active, false,\n            \"2nd control deactivated with activation of 1st\");\n        panel.deactivate();      \n        t.ok(!panel.controls[0].active && !panel.controls[1].active,\n            \"No controls are active after panel deactivation.\");\n        panel.activate();   \n        t.eq(panel.controls[0].active, true,\n            \"After panel reactivation first control is active.\");\n        t.eq(panel.controls[1].active, false,\n            \"After panel reactivation second control is inactive.\");              \n        panel.destroy();\n        map.destroy();\n    } \n\n    function test_Control_Panel_autoActivate (t) {\n        t.plan(1);\n        var map = new OpenLayers.Map('map');\n        var controlNoDeactive = new OpenLayers.Control({autoActivate:true});\n        var chkDeactivate = function () {\n            t.ok(false, \"Tool control autoActivate:true was deactivated unnecessarily\");\n        };\n        controlNoDeactive.events.on({deactivate: chkDeactivate});\n        var panel = new OpenLayers.Control.Panel();\n        \n        map.addControl(panel);\n        panel.addControls([controlNoDeactive]);\n        controlNoDeactive.events.un({deactivate: chkDeactivate});\n        t.ok(!controlNoDeactive.active, \"Tool control autoActivate:true is not active\");\n        \n    }\n\n    function test_Control_Panel_deactivate (t) {\n        t.plan(2);\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        var panel = new OpenLayers.Control.Panel();        \n        map.addControl(panel);\n        panel.addControls([control]);        \n        t.ok(panel.div.innerHTML != \"\", \"Panel displayed after activate\");        \n        \n        panel.deactivate();\n        t.ok(panel.div.innerHTML == \"\", \n            \"Panel is not displayed after deactivate without any active control\");\n\n        map.destroy();\n    }\n\n    function test_allowDepress (t) { \n        t.plan(2); \n        var map = new OpenLayers.Map('map');\n\n        var panel = new OpenLayers.Control.Panel();\n        panel.addControls([new OpenLayers.Control(),new OpenLayers.Control()]);\n        map.addControl(panel);\n        \n        var control1 = panel.controls[1]\n        \n        panel.activateControl(control1);\n        \n        panel.allowDepress = false;\n        panel.activateControl(control1);\n        t.eq(control1.active, true,\n            \"control1 remains active after calling again activateControl when allowDepress = false\");\n        panel.allowDepress = true;\n        panel.activateControl(control1);\n        t.eq(control1.active, false,\n            \"control1 is inactive after calling again activateControl when allowDepress = true\");\n\n        // panel.deactivate();\n        map.destroy();\n    }\n\n    function test_iconOn_iconOff(t) {\n        t.plan(2);\n\n        var map = new OpenLayers.Map('map');\n\n        var panel = new OpenLayers.Control.Panel();\n        var ctrl = new OpenLayers.Control({displayClass: 'ctrl'});\n        panel.addControls([ctrl]);\n\n        map.addControl(panel);\n\n        // add arbitrary classes to the panel div - we want to test\n        // than iconOn and iconOff do their jobs even when the panel\n        // div has application-specific classes.\n\n        ctrl.panel_div.className =\n            'ctrlItemInactive fooItemActive fooItemInactive';\n\n        panel.iconOn.call(ctrl);\n        t.eq(ctrl.panel_div.className,\n             'ctrlItemActive fooItemActive fooItemInactive',\n             'iconOn behaves as expected');\n\n        ctrl.panel_div.className =\n            'ctrlItemActive fooItemActive fooItemInactive';\n\n        panel.iconOff.call(ctrl);\n        t.eq(ctrl.panel_div.className,\n             'ctrlItemInactive fooItemActive fooItemInactive',\n             'iconOff behaves as expected');\n\n        map.destroy();\n    }\n    \n    function test_buttonclick(t) {\n        t.plan(4);\n        var map = new OpenLayers.Map('map');\n        var panel1 = new OpenLayers.Control.Panel();\n        var div = document.createElement(\"div\");\n        var panel2 = new OpenLayers.Control.Panel({div: div});\n        map.addControls([panel1, panel2]);\n        \n        t.ok(map.events.listeners.buttonclick, \"buttonclick event registered on map's Events instance for panel inside map\");\n        t.ok(!panel1.events.element, \"Panel inside map has no element on its Events instance\");\n        t.ok(panel2.events.listeners.buttonclick, \"buttonclick event registered on panel's Events instance if outside map\")\n        t.ok(panel2.events.element === div, \"Panel outside map has the panel's div as element on its Events instance\");\n        \n    }\n    \n    function test_iconOniconOff (t) {\n    \tt.plan(6);\n    \tvar map = new OpenLayers.Map(\"map\"),\n\t\t\tnavControl = new OpenLayers.Control.Navigation({autoActivate: true}),\n\t\t\tzbControl = new OpenLayers.Control.ZoomBox(),\n    \t\tpanel = new OpenLayers.Control.Panel({defaultControl: navControl}),\n    \t\tnavActiveClass, navInactiveClass, zbActiveClass, zbInactiveClass;\n    \t\n    \tpanel.addControls([navControl, zbControl]);\n    \tmap.addControl(panel);\n    \t\n     \tnavControl.panel_div.className += \" foo\";\n    \tzbControl.panel_div.className = \"bar \" + zbControl.panel_div.className;\n    \t\n    \tt.eq(navControl.panel_div.className, \"olControlNavigationItemActive olButton foo\",\n    \t\t\"defaultControl className is set to [displayClass]Active on panel instantiation\");\n    \tt.eq(zbControl.panel_div.className, \"bar olControlZoomBoxItemInactive olButton\",\n        \t\"non-defaultControl className is set to [displayClass]Inactive on panel instantiation\");\n    \t\n    \tpanel.activateControl(zbControl);\n    \t\n    \tt.eq(zbControl.panel_div.className, \"bar olControlZoomBoxItemActive olButton\",\n    \t\t\"active control class name with preceding secondary class name is set to [displayClass]Active\");\n    \tt.eq(navControl.panel_div.className, \"olControlNavigationItemInactive olButton foo\",\n    \t\t\"inactive control class name with trailing secondary class name is set to [displayClass]Inactive\");\n    \t\n    \tpanel.activateControl(navControl);\n    \t\n    \tt.eq(navControl.panel_div.className, \"olControlNavigationItemActive olButton foo\",\n        \t\t\"active control class name with trailing secondary class name is set to [displayClass]Active\");\n    \tt.eq(zbControl.panel_div.className, \"bar olControlZoomBoxItemInactive olButton\",\n        \t\t\"inactive control class name with preceding secondary class name is set to [displayClass]Inactive\");\n    \t\n    \tmap.destroy();\n    }\n    \n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/Permalink.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var map; \n    function test_Control_Permalink_constructor (t) {\n        t.plan(42);\n    \n        control = new OpenLayers.Control.Permalink();\n        t.ok(control instanceof OpenLayers.Control.Permalink, \"new OpenLayers.Control returns object\");\n        t.eq(control.displayClass, \"olControlPermalink\", \"displayClass is correct\");\n        t.eq(control.base, document.location.href, \"base is correct\");\n        t.ok(!control.anchor, \"anchor is correct\");\n        control.destroy();\n\n        control = new OpenLayers.Control.Permalink('permalink', 'test.html');\n        t.ok(control instanceof OpenLayers.Control.Permalink, \"new OpenLayers.Control returns object\");\n        t.eq(control.displayClass, \"olControlPermalink\", \"displayClass is correct\");\n        t.eq(control.base, 'test.html', \"base is correct\");\n        t.ok(OpenLayers.Util.isElement(control.element), \"element is a dom object\");\n        t.ok(!control.anchor, \"anchor is correct\");\n        control.destroy();\n\n        control = new OpenLayers.Control.Permalink('permalink');\n        t.ok(control instanceof OpenLayers.Control.Permalink, \"new OpenLayers.Control returns object\");\n        t.eq(control.displayClass, \"olControlPermalink\", \"displayClass is correct\");\n        t.eq(control.base, document.location.href, \"base is correct\");\n        t.ok(OpenLayers.Util.isElement(control.element), \"element is a dom object\");\n        t.ok(!control.anchor, \"anchor is correct\");\n        control.destroy();\n\n        control = new OpenLayers.Control.Permalink(OpenLayers.Util.getElement('permalink'));\n        t.ok(control instanceof OpenLayers.Control.Permalink, \"new OpenLayers.Control returns object\");\n        t.eq(control.displayClass, \"olControlPermalink\", \"displayClass is correct\");\n        t.eq(control.base, document.location.href, \"base is correct\");\n        t.ok(OpenLayers.Util.isElement(control.element), \"element is a dom object\");\n        t.ok(!control.anchor, \"anchor is correct\");\n        control.destroy();\n\n        control = new OpenLayers.Control.Permalink({anchor: true});\n        t.ok(control instanceof OpenLayers.Control.Permalink, \"new OpenLayers.Control returns object\");\n        t.eq(control.displayClass, \"olControlPermalink\", \"displayClass is correct\");\n        t.eq(control.base, document.location.href, \"base is correct\");\n        t.ok(control.element == null, \"element is null\");\n        t.ok(control.anchor, \"anchor is correct\");\n        control.destroy();\n\n        control = new OpenLayers.Control.Permalink({anchor: false});\n        t.ok(control instanceof OpenLayers.Control.Permalink, \"new OpenLayers.Control returns object\");\n        t.eq(control.displayClass, \"olControlPermalink\", \"displayClass is correct\");\n        t.eq(control.base, document.location.href, \"base is correct\");\n        t.ok(!control.anchor, \"anchor is correct\");\n        control.destroy();\n\n        control = new OpenLayers.Control.Permalink({});\n        t.ok(control instanceof OpenLayers.Control.Permalink, \"new OpenLayers.Control returns object\");\n        t.eq(control.displayClass, \"olControlPermalink\", \"displayClass is correct\");\n        t.eq(control.base, document.location.href, \"base is correct\");\n        t.ok(!control.anchor, \"anchor is correct\");\n        control.destroy();\n\n        control = new OpenLayers.Control.Permalink({element: 'permalink', base: 'test.html'});\n        t.ok(control instanceof OpenLayers.Control.Permalink, \"new OpenLayers.Control returns object\");\n        t.eq(control.displayClass, \"olControlPermalink\", \"displayClass is correct\");\n        t.eq(control.base, 'test.html', \"base is correct\");\n        t.ok(OpenLayers.Util.isElement(control.element), \"element is a dom object\");\n        t.ok(!control.anchor, \"anchor is correct\");\n        control.destroy();\n\n        control = new OpenLayers.Control.Permalink({element: 'permalink', base: 'test.html', anchor: true});\n        t.ok(control instanceof OpenLayers.Control.Permalink, \"new OpenLayers.Control returns object\");\n        t.eq(control.displayClass, \"olControlPermalink\", \"displayClass is correct\");\n        t.eq(control.base, 'test.html', \"base is correct\");\n        t.ok(OpenLayers.Util.isElement(control.element), \"element is a dom object\");\n        t.ok(control.anchor, \"anchor is correct\");\n        control.destroy();\n    }\n    function test_Control_Permalink_uncentered (t) {\n        t.plan( 1 );\n    \n        control = new OpenLayers.Control.Permalink('permalink');\n        map = new OpenLayers.Map('map');\n        map.addControl(control);\n        map.events.triggerEvent(\"changelayer\", {});\n        t.ok(true, \"permalink didn't bomb out.\");\n        map.destroy();\n    }   \n    function test_Control_Permalink_initwithelem (t) {\n        t.plan( 1 );\n    \n        control = new OpenLayers.Control.Permalink(OpenLayers.Util.getElement('permalink'));\n        t.ok(true, \"If the above line doesn't throw an error, we're safe.\"); \n        control.destroy();\n    }\n    function test_Control_Permalink_updateLinks (t) {\n        t.plan( 3 );\n    \n        control = new OpenLayers.Control.Permalink('permalink');\n        t.ok( control instanceof OpenLayers.Control.Permalink, \"new OpenLayers.Control returns object\" );\n        map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS('Test Layer', \"http://octo.metacarta.com/cgi-bin/mapserv\", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});\n        map.addLayer(layer);\n        layer = new OpenLayers.Layer.WMS('Test Layer', \"http://octo.metacarta.com/cgi-bin/mapserv\", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, {'isBaseLayer': false});\n        map.addLayer(layer);\n        layer.setVisibility(true);\n        if (!map.getCenter())  map.zoomToMaxExtent();\n        map.addControl(control);\n        map.pan(5, 0, {animate:false});\n        t.ok(OpenLayers.Util.isEquivalentUrl(OpenLayers.Util.getElement('permalink').href, location+\"?zoom=2&lat=0&lon=1.75781&layers=BT\"), 'pan sets permalink');\n        \n        map.layers[1].setVisibility(false);\n        \n        t.ok(OpenLayers.Util.isEquivalentUrl(OpenLayers.Util.getElement('permalink').href, location+\"?zoom=2&lat=0&lon=1.75781&layers=BF\"), 'setVisibility sets permalink');\n        map.destroy();\n    }\n    function test_Control_Permalink_updateLinksBase (t) {\n        t.plan( 2 );\n    \n        control = new OpenLayers.Control.Permalink('permalink', \"./edit.html\" );\n        t.ok( control instanceof OpenLayers.Control.Permalink, \"new OpenLayers.Control returns object\" );\n        map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS('Test Layer', \"http://octo.metacarta.com/cgi-bin/mapserv\", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});\n        map.addLayer(layer);\n        if (!map.getCenter())  map.zoomToMaxExtent();\n        map.addControl(control);\n        map.pan(5, 0, {animate:false});\n        OpenLayers.Util.getElement('edit_permalink').href = './edit.html?zoom=2&lat=0&lon=1.75781&layers=B';\n        t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, \"Panning sets permalink with base\");\n        map.destroy();\n  }\n  function test_Control_Permalink_noElement (t) {\n        t.plan( 2 );\n        control = new OpenLayers.Control.Permalink( );\n        t.ok( control instanceof OpenLayers.Control.Permalink, \"new OpenLayers.Control returns object\" );\n        map = new OpenLayers.Map('map');\n        map.addControl(control);\n        t.eq(map.controls[4].div.firstChild.nodeName, \"A\", \"Permalink control creates div with 'a' inside.\" );\n        map.destroy();\n  }\n  function test_Control_Permalink_base_with_query (t) {\n      t.plan( 3 );\n\t\n      control = new OpenLayers.Control.Permalink('permalink', \"./edit.html?foo=bar\" );\n      map = new OpenLayers.Map('map');\n      layer = new OpenLayers.Layer.WMS('Test Layer', \"http://example.com\" );\n      map.addLayer(layer);\n      if (!map.getCenter())  map.zoomToMaxExtent();\n      map.addControl(control);\n      map.pan(5, 0, {animate:false});\n      OpenLayers.Util.getElement('edit_permalink').href = './edit.html?foo=bar&zoom=2&lat=0&lon=1.75781&layers=B';\n      t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, \"Panning sets permalink with base and querystring\");\n      \n      control = new OpenLayers.Control.Permalink('permalink', \"./edit.html?foo=bar&\" );\n      map.addControl(control);\n      map.pan(0, 0, {animate:false});\n      t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, \"Panning sets permalink with base and querystring ending with '&'\");\n      \n      control = new OpenLayers.Control.Permalink('permalink', \"./edit.html?\" );\n      OpenLayers.Util.getElement('edit_permalink').href = './edit.html?zoom=2&lat=0&lon=1.75781&layers=B';\n      map.addControl(control);\n      map.pan(5, 0, {animate:false});\n      map.pan(-5, 0, {animate:false});\n      t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, \"Panning sets permalink with base and querystring ending with '?'\");\n      map.destroy();\n  }\n\n  function test_Control_Permalink_base_with_anchor (t) {\n      t.plan( 4 );\n      control = new OpenLayers.Control.Permalink('permalink', \"./edit.html#foo\" );\n      map = new OpenLayers.Map('map');\n      layer = new OpenLayers.Layer.WMS('Test Layer', \"http://example.com\" );\n      map.addLayer(layer);\n      if (!map.getCenter())  map.zoomToMaxExtent();\n      map.addControl(control);\n      map.pan(5, 0, {animate:false});\n      OpenLayers.Util.getElement('edit_permalink').href = './edit.html?zoom=2&lat=0&lon=1.75781&layers=B#foo';\n      t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, \"Panning sets permalink with base and anchor\");\n      \n      control = new OpenLayers.Control.Permalink('permalink', \"./edit.html#\" );\n      map.addControl(control);\n      map.pan(0, 0, {animate:false});\n      OpenLayers.Util.getElement('edit_permalink').href = './edit.html?zoom=2&lat=0&lon=1.75781&layers=B#';\n      t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, \"Panning sets permalink with base and an empty anchor\");\n      \n      control = new OpenLayers.Control.Permalink('permalink', \"./edit.html?foo=bar#test\" );\n      OpenLayers.Util.getElement('edit_permalink').href = './edit.html?foo=bar&zoom=2&lat=0&lon=1.75781&layers=B#test';\n      map.addControl(control);\n      map.pan(5, 0, {animate:false});\n      map.pan(-5, 0, {animate:false});\n      t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, \"Panning sets permalink with base, querystring and an anchor\");\n\t  \n\t  control = new OpenLayers.Control.Permalink('permalink', \"./edit.html#foo\", {anchor : true} );\n      map.addControl(control);\n      map.pan(0, 0, {animate:false});\n      OpenLayers.Util.getElement('edit_permalink').href = './edit.html#zoom=2&lat=0&lon=1.75781&layers=B';\n      t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, \"Panning sets permalink with base and an empty anchor\");\n  }\n\n    function test_Control_Permalink_nonRepeating (t) {\n        t.plan( 2 );\n    \n        control = new OpenLayers.Control.Permalink('permalink', \"./edit.html?zoom=3\" );\n        t.ok( control instanceof OpenLayers.Control.Permalink, \"new OpenLayers.Control returns object\" );\n        map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS('Test Layer', \"http://octo.metacarta.com/cgi-bin/mapserv\", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});\n        map.addLayer(layer);\n        if (!map.getCenter())  map.zoomToMaxExtent();\n        map.addControl(control);\n        map.pan(5, 0, {animate:false});\n        OpenLayers.Util.getElement('edit_permalink').href = './edit.html?zoom=2&lat=0&lon=1.75781&layers=B';\n        t.eq(OpenLayers.Util.getElement('permalink').href, OpenLayers.Util.getElement('edit_permalink').href, \"Panning sets permalink with existing zoom in base\");\n        map.destroy();\n  }\n  \n    function test_Control_Permalink_customized(t) {\n        t.plan(2);\n      \n        var argParserClass = OpenLayers.Class(OpenLayers.Control.ArgParser, {\n            CLASS_NAME: \"CustomArgParser\"\n        });\n      \n        control = new OpenLayers.Control.Permalink(null, \"./edit.html\", {\n            argParserClass: argParserClass,\n            createParams: function(center, zoom, layers) {\n                var params = OpenLayers.Control.Permalink.prototype.createParams.apply(control, arguments);\n                params.customParam = \"foo\";\n                return params;\n            }\n        });\n        map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS('Test Layer', \"http://octo.metacarta.com/cgi-bin/mapserv\", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});\n        map.addLayer(layer);\n        if (!map.getCenter())  map.zoomToMaxExtent();\n        map.addControl(control);\n        map.pan(5, 0, {animate:false});\n      \n        t.eq(this.map.controls[this.map.controls.length-1].CLASS_NAME, \"CustomArgParser\", \"Custom ArgParser added correctly.\");\n        t.eq(control.div.firstChild.getAttribute(\"href\"), \"./edit.html?zoom=2&lat=0&lon=1.75781&layers=B&customParam=foo\", \"Custom parameter encoded correctly.\");\n        map.destroy();\n    }\n    \n    function test_Control_Permalink_createParams(t) {\n        t.plan(18);\n\n        var baseLayer = { 'isBaseLayer': true };\n\n        var m = {\n            'getCenter': function() { return null; }\n        };\n        \n        var pl = {\n            'map': m,\n            'base': {}\n        };\n\n        old_getParameters = OpenLayers.Util.getParameters;\n        OpenLayers.Util.getParameters = function(base) {\n            t.ok(base == pl.base, \"correct base sent in to Util.getParameters()\");\n            return g_Params;\n        };\n        \n      //null center, null map.getCenter()\n        g_Params = {};\n        m.baseLayer = baseLayer;\n        var returnParams = OpenLayers.Control.Permalink.prototype.createParams.apply(pl, []);\n        t.ok(returnParams == g_Params, \"correct params returned on null center\");\n\n      //valid center, zoom, layers\n        g_Params = { 'test': {} };\n        var center = { 'lon': 1.2345678901, 'lat': 9.8765432109 };\n        var zoom = {};\n        var layers = [\n            { 'isBaseLayer': true },\n            baseLayer,\n            { 'isBaseLayer': false, 'getVisibility': function() { return true; } },\n            { 'isBaseLayer': false, 'getVisibility': function() { return false; } }\n        ];\n        var returnParams = OpenLayers.Control.Permalink.prototype.createParams.apply(pl, [center, zoom, layers]);\n\n        t.ok(returnParams.test == g_Params.test, \"correct params returned from Util.getParameters() when valid center, zoom, layers\");\n        t.ok(returnParams.zoom == zoom, \"params.zoom set correctly when valid center, zoom, layers\");\n        t.eq(returnParams.lon, 1.23457, \"lon set and rounded correctly when valid center, zoom, layers\");\n        t.eq(returnParams.lat, 9.87654, \"lat set and rounded correctly when valid center, zoom, layers\");\n        t.eq(returnParams.layers, \"0BTF\", \"layers processed correctly when valid center, zoom, layers\")\n\n\n      //null center, zoom, layers, with displayProjection\n        g_Params = { 'test': {} };\n        g_Projection = {};\n        m = {\n            'baseLayer': baseLayer,\n            'getProjectionObject':  function() { return g_Projection; },\n            'center': { 'lon': {}, 'lat': {} },\n            'getCenter': function() { return this.center; },\n            'zoom': {},\n            'getZoom': function() { return this.zoom; },\n           'layers': [\n                { 'isBaseLayer': false, 'getVisibility': function() { return true; } },\n                baseLayer,\n                { 'isBaseLayer': false, 'getVisibility': function() { return false; } },\n                { 'isBaseLayer': true }\n            ],\n            'getLayers': function() { return this.layers; }\n        };\n        pl = { \n            'base': {},\n            'map': m,\n            'displayProjection': {}\n        };\n        \n        old_transform = OpenLayers.Projection.transform;\n        OpenLayers.Projection.transform = function(point, projObj, dispProj) {\n            t.ok(point.x = m.center.lon, \"correct x value passed into transform\");\n            t.ok(point.y = m.center.lat, \"correct x value passed into transform\");\n            t.ok(projObj == g_Projection, \"correct projection object from map passed into transform\");\n            t.ok(dispProj == pl.displayProjection, \"correct displayProjection from control passed into transform\");\n\n            return { 'x': 9.8765432109, 'y': 1.2345678901 };\n        };\n        \n        center = zoom = layers = null;\n\n        var returnParams = OpenLayers.Control.Permalink.prototype.createParams.apply(pl, [center, zoom, layers]);\n        t.ok(returnParams.test == g_Params.test, \"correct params returned from Util.getParameters() when null center, zoom, layers, with displayProjection\");\n        t.ok(returnParams.zoom == m.zoom, \"params.zoom set correctly when null center, zoom, layers, with displayProjection\");\n        t.eq(returnParams.lon, 9.87654, \"lon set, transformed, and rounded correctly when null center, zoom, layers, with displayProjection\");\n        t.eq(returnParams.lat, 1.23457, \"lat set, transformed, and rounded correctly when null center, zoom, layers, with displayProjection\");\n        t.eq(returnParams.layers, \"TBF0\", \"layers processed correctly when null center, zoom, layers, with displayProjection\");\n\n        OpenLayers.Util.getParameters = old_getParameters;\n        OpenLayers.Projection.transform = old_transform;\n    }\n    function test_Control_Permalink_Anchor (t) {\n        t.plan(3);\n    \n        control = new OpenLayers.Control.Permalink({anchor: true});\n        t.ok( control instanceof OpenLayers.Control.Permalink, \"new OpenLayers.Control returns object\" );\n        map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS('Test Layer', \"http://octo.metacarta.com/cgi-bin/mapserv\", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});\n        map.addLayer(layer);\n        layer = new OpenLayers.Layer.WMS('Test Layer', \"http://octo.metacarta.com/cgi-bin/mapserv\", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, {'isBaseLayer': false});\n        map.addLayer(layer);\n        layer.setVisibility(true);\n        if (!map.getCenter())  map.zoomToMaxExtent();\n        map.addControl(control);\n        map.pan(5, 0, {animate:false});\n        t.ok(OpenLayers.Util.isEquivalentUrl(OpenLayers.Util.getParameterString(control.createParams()), \"zoom=2&lat=0&lon=1.75781&layers=BT\"), 'pan sets permalink');\n        \n        map.layers[1].setVisibility(false);\n        t.ok(OpenLayers.Util.isEquivalentUrl(OpenLayers.Util.getParameterString(control.createParams()), \"zoom=2&lat=0&lon=1.75781&layers=BF\"), 'setVisibility sets permalink');\n        map.destroy();\n    }\n    \n    function test_Control_Permalink_AnchorBaseElement (t) {\n        t.plan(3);\n    \n        control = new OpenLayers.Control.Permalink('permalink', document.location.href, {anchor: true});\n        t.ok( control instanceof OpenLayers.Control.Permalink, \"new OpenLayers.Control returns object\" );\n        map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS('Test Layer', \"http://octo.metacarta.com/cgi-bin/mapserv\", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});\n        map.addLayer(layer);\n        layer = new OpenLayers.Layer.WMS('Test Layer', \"http://octo.metacarta.com/cgi-bin/mapserv\", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, {'isBaseLayer': false});\n        map.addLayer(layer);\n        layer.setVisibility(true);\n        if (!map.getCenter())  map.zoomToMaxExtent();\n        map.addControl(control);\n        map.pan(5, 0, {animate:false});\n        t.ok(OpenLayers.Util.isEquivalentUrl(OpenLayers.Util.getElement('permalink').href, location+\"#zoom=2&lat=0&lon=1.75781&layers=BT\"), 'pan sets permalink');\n        \n        map.layers[1].setVisibility(false);\n        t.ok(OpenLayers.Util.isEquivalentUrl(OpenLayers.Util.getElement('permalink').href, location+\"#zoom=2&lat=0&lon=1.75781&layers=BF\"), 'setVisibility sets permalink');\n        map.destroy();\n    }\n    \n    function test_center_from_map(t) {\n        t.plan(7);\n\n        var previous = window.location.hash;\n        window.location.hash = \"\";\n\n        var err;\n        try {\n            var map = new OpenLayers.Map({\n                layers: [new OpenLayers.Layer(null, {isBaseLayer: true})],\n                controls: [\n                    new OpenLayers.Control.Permalink({anchor: true})\n                ],\n                center: [1, 2],\n                zoom: 3\n            });\n        } catch (e) {\n            err = e;\n        }\n        if (err) {\n            t.fail(\"Map construction failure: \" + err.message);\n        } else {\n            t.ok(true, \"Map construction works\");\n        }\n        \n        // confirm that map center is correctly set\n        var center = map.getCenter();\n        t.eq(center.lon, 1, \"map x\");\n        t.eq(center.lat, 2, \"map y\")\n        t.eq(map.getZoom(), 3, \"map z\");\n\n        // confirm that location from map options has been added to url\n        var params = OpenLayers.Util.getParameters(window.location.hash.replace(\"#\", \"?\"));\n        t.eq(params.lon, \"1\", \"url x\");\n        t.eq(params.lat, \"2\", \"url y\");\n        t.eq(params.zoom, \"3\", \"url z\");\n        \n        map.destroy();\n        window.location.hash = previous;\n    }\n    \n    function test_center_from_url(t) {\n        t.plan(6);\n\n        // In cases where the location is specified in the URL and given in\n        // the map options, we respect the location in the URL.\n        var previous = window.location.hash;\n        window.location.hash = \"#zoom=6&lat=5&lon=4&layers=B\"\n        \n        var map = new OpenLayers.Map({\n            layers: [new OpenLayers.Layer(null, {isBaseLayer: true})],\n            controls: [new OpenLayers.Control.Permalink({anchor: true})],\n            center: [0, 0],\n            zoom: 0\n        });\n        \n        // confirm that map center is correctly set\n        var center = map.getCenter();\n        t.eq(center.lon, 4, \"map x\");\n        t.eq(center.lat, 5, \"map y\")\n        t.eq(map.getZoom(), 6, \"map z\");        \n        \n        var params = OpenLayers.Util.getParameters(window.location.hash.replace(\"#\", \"?\"));\n        t.eq(params.lon, \"4\", \"x set\");\n        t.eq(params.lat, \"5\", \"y set\");\n        t.eq(params.zoom, \"6\", \"z set\");\n        \n        map.destroy();\n        window.location.hash = previous;\n    }\n    \n  </script>\n</head>\n<body>\n    <a id=\"permalink\" href=\"\">Permalink</a> <br />\n    <a id=\"edit_permalink\" href=\"\">Edit</a> <br />\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/PinchZoom.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_constructor(t) {\n        t.plan(2);\n        var control = new OpenLayers.Control.PinchZoom();\n        t.ok(control instanceof OpenLayers.Control.PinchZoom, \"got an instance\");\n        t.ok(control.handler instanceof OpenLayers.Handler.Pinch, \"control has pinch handler\");\n        control.destroy();\n    }\n\n    function test_destroy(t) {\n        t.plan(1);\n        var control = new OpenLayers.Control.PinchZoom();\n        control.destroy();\n        t.ok(!control.handler, \"handler destroyed\");\n    }\n    \n    function test_activate(t) {\n        t.plan(3);\n        var control = new OpenLayers.Control.PinchZoom();\n        t.ok(!control.active, \"control not activated after construction\");\n        \n        var map = new OpenLayers.Map({\n            div: \"map\",\n            controls: [control]\n        });\n        t.ok(control.active, \"control activated after being added to the map\");\n        \n        control.deactivate();\n        t.ok(!control.active, \"control deactivated\");\n        \n        map.destroy();\n    }\n\n    function test_pinchMove(t) {\n\n        var control = new OpenLayers.Control.PinchZoom();\n\n        var map = new OpenLayers.Map({\n            div: \"map\",\n            controls: [control]\n        });\n        \n        var log = [];\n        map.applyTransform = function(x, y, scale) {\n            log.push([x, y, scale]);\n        }\n        \n        map.layerContainerOriginPx = {\n            x: -50, y: -50\n        };\n\n        control.pinchOrigin = {\n            x: 100, y: 50\n        };\n\n        var cases = [\n            {x: 100, y: 60, scale: 1, transform: [-50, -40, 1]},\n            {x: 150, y: 60, scale: 1, transform: [0, -40, 1]},\n            {x: 150, y: 60, scale: 2, transform: [-150, -140, 2]},\n            {x: 50, y: 20, scale: 2.5, transform: [-325, -230, 2.5]},\n            {x: 150, y: 60, scale: 2, transform: [-150, -140, 2]},\n            {x: 50, y: 20, scale: 0.25, transform: [13, -5, 0.25]}\n        ];\n        \n        var len = cases.length;\n        t.plan(len*2);\n        \n        var c;\n        for (var i=0; i<len; ++i) {\n            c = cases[i];\n            control.pinchMove({xy: {x: c.x, y: c.y}}, {scale: c.scale});\n            t.eq(log.length, i+1, i + \" called once\");\n            t.eq(log[i], c.transform, i + \" correct transform\");\n        }\n        \n    }\n\n    function test_pinchMove_preservecenter(t) {\n\n        var control = new OpenLayers.Control.PinchZoom({\n            preserveCenter: true\n        });\n\n        var map = new OpenLayers.Map({\n            div: \"map\",\n            controls: [control],\n            layers: [new OpenLayers.Layer('fake', {isBaseLayer: true})]\n        });\n        map.zoomToMaxExtent();\n\n        var centerPx = map.getPixelFromLonLat(map.getCenter());\n\n        control.pinchStart = function(evt, pinchData) {\n            t.eq(map.layerContainerOriginPx, {x: 0, y: 0}, \"center preserved\");\n            t.eq(map.getPixelFromLonLat(map.getCenter()), centerPx, \"center preserved\");\n        }\n\n        control.pinchStart(null);\n\n        var log = [];\n        map.applyTransform = function(x, y, scale) {\n            log.push([x, y, scale]);\n        }\n        control.pinchOrigin = map.getPixelFromLonLat(map.getCenter());\n\n        var cases = [\n            {scale: 1, transform: [0, 0, 1]},\n            {scale: 2, transform: [-128, -128, 2]},\n            {scale: 2.5, transform: [-192, -192, 2.5]},\n            {scale: 0.25, transform: [96, 96, 0.25]}\n        ];\n\n        var len = cases.length;\n        t.plan(2 + len*2);\n\n        var c;\n        for (var i=0; i<len; ++i) {\n            c = cases[i];\n            control.pinchMove(null, {scale: c.scale});\n            t.eq(log.length, i+1, i + \" called once\");\n            t.eq(log[i], c.transform, i + \" correct transform\");\n        }\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 256px; height: 256px;\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/SLDSelect.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(11);\n        var control = new OpenLayers.Control.SLDSelect(OpenLayers.Handler.Click);\n        t.eq(control.handler instanceof OpenLayers.Handler.Click, true, \"Click handler created\");\n        t.ok(control.handler.callbacks[\"click\"] === control.select, \"Click callback correctly set\");\n        control.destroy();\n        control = new OpenLayers.Control.SLDSelect(OpenLayers.Handler.RegularPolygon, {handlerOptions: {irregular: true}});\n        t.eq(control.handler instanceof OpenLayers.Handler.RegularPolygon, true, \"RegularPolygon handler created\");\n        t.eq(control.handler.irregular, true, \"RegularPolygon handler is irregular\");\n        t.eq(control.handler.persist, false, \"RegularPolygon handler is not persistant\");\n        t.ok(control.handler.callbacks[\"done\"] === control.select, \"Done callback correctly set\");\n        control.destroy();\n        control = new OpenLayers.Control.SLDSelect(OpenLayers.Handler.Polygon);\n        t.eq(control.handler instanceof OpenLayers.Handler.Polygon, true, \"Polygon handler created\");\n        t.ok(control.handler.callbacks[\"done\"] === control.select, \"Done callback correctly set\");\n        control.destroy();\n        control = new OpenLayers.Control.SLDSelect(OpenLayers.Handler.Path);\n        t.eq(control.handler instanceof OpenLayers.Handler.Path, true, \"Path handler created\");\n        t.ok(control.handler.callbacks[\"done\"] === control.select, \"Done callback correctly set\");\n        control.destroy();\n        var layer = new OpenLayers.Layer.WMS('Foo', 'http://foo', {LAYERS: 'A'});\n        control = new OpenLayers.Control.SLDSelect(OpenLayers.Handler.RegularPolygon, {layers: [layer]});\n        t.eq(control.layers.length, 1, \"Layers property correctly set\");\n        control.destroy();\n        layer.destroy();\n    }\n\n    function test_select(t) {\n        t.plan(9);\n        var parser = new OpenLayers.Format.WFSDescribeFeatureType();\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS('Foo', 'http://foo', {LAYERS: 'AAA64'});\n        map.addLayer(layer);\n\n        var text =\n            '<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>' +\n            '<schema' +\n            '   targetNamespace=\"http://mapserver.gis.umn.edu/mapserver\" ' +\n            '   xmlns:rws=\"http://mapserver.gis.umn.edu/mapserver\" ' +\n            '   xmlns:ogc=\"http://www.opengis.net/ogc\"' +\n            '   xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"' +\n            '   xmlns=\"http://www.w3.org/2001/XMLSchema\"' +\n            '   xmlns:gml=\"http://www.opengis.net/gml\"' +\n            '   elementFormDefault=\"qualified\" version=\"0.1\" >' +\n            '  <import namespace=\"http://www.opengis.net/gml\"' +\n            '          schemaLocation=\"http://schemas.opengis.net/gml/2.1.2/feature.xsd\" />' +\n            '  <element name=\"AAA64\" ' +\n            '           type=\"rws:AAA64Type\" ' +\n            '           substitutionGroup=\"gml:_Feature\" />' +\n            '  <complexType name=\"AAA64Type\">' +\n            '    <complexContent>' +\n            '      <extension base=\"gml:AbstractFeatureType\">' +\n            '        <sequence>' +\n            '          <element name=\"geometry\" type=\"gml:MultiLineStringPropertyType\" minOccurs=\"0\" maxOccurs=\"1\"/>' +\n            '          <element name=\"OBJECTID\" type=\"string\"/>' +\n            '        </sequence>' +\n            '      </extension>' +\n            '    </complexContent>' +\n            '  </complexType>' +\n            '</schema>';\n\n        OpenLayers.Control.SLDSelect.prototype.wfsCache[layer.id] = parser.read(text);\n        var control = new OpenLayers.Control.SLDSelect(OpenLayers.Handler.RegularPolygon,\n            {layers: [layer], clearOnDeactivate: true, handlerOptions: {irregular: true} });\n\n        var testEvent = function(evt) {\n            t.eq(evt.filters.length, 1, \"Event has a filters array set\");\n            t.eq(evt.filters[0] instanceof OpenLayers.Filter.Spatial, true, \"Spatial filter has been created\");\n        };\n\n        control.events.register(\"selected\", this, testEvent);\n        map.addControl(control);\n        var geometry = OpenLayers.Geometry.Polygon.createRegularPolygon(\n            new OpenLayers.Geometry.Point(0, 0), 5, 4);\n        control.select(geometry);\n        control.events.unregister(\"selected\", this, testEvent);\n        t.eq(map.layers.length, 2, \"Selection layer has been created and added to the map\");\n        t.eq(map.layers[1] instanceof OpenLayers.Layer.WMS, true, \"A WMS layer has been created as the selection layer\");\n        t.eq(map.layers[1].tileOptions.maxGetUrlLength, 2048, \"Selection layer will automatically switch to HTTP Post if content gets longer than 2048\");\n        var expected_sld = '<sld:StyledLayerDescriptor xmlns:sld=\"http://www.opengis.net/sld\" version=\"1.0.0\" xsi:schemaLocation=\"http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:gml=\"http://www.opengis.net/gml\"><sld:NamedLayer><sld:Name>AAA64</sld:Name><sld:UserStyle><sld:Name>default</sld:Name><sld:FeatureTypeStyle><sld:Rule><ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\"><ogc:BBOX><ogc:PropertyName>geometry</ogc:PropertyName><gml:Box xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"EPSG:4326\"><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">-3.5355339059327,-3.5355339059327 3.5355339059327,3.5355339059327</gml:coordinates></gml:Box></ogc:BBOX></ogc:Filter><sld:LineSymbolizer><sld:Stroke><sld:CssParameter name=\"stroke\">#FF0000</sld:CssParameter><sld:CssParameter name=\"stroke-width\">2</sld:CssParameter></sld:Stroke></sld:LineSymbolizer></sld:Rule></sld:FeatureTypeStyle></sld:UserStyle></sld:NamedLayer></sld:StyledLayerDescriptor>';\n\n        t.xml_eq(map.layers[1].params.SLD_BODY, expected_sld, \"SLD generated correctly\");\n\n        var geometry = OpenLayers.Geometry.Polygon.createRegularPolygon(\n            new OpenLayers.Geometry.Point(0, 0), 7, 4);\n        control.select(geometry);\n        t.eq(map.layers.length, 2, \"Selection layer is reused when new selection is performed\");\n\n        map.layers[0].setVisibility(false);\n        t.eq(map.layers[1].getVisibility(), false, \"Visibility of selection layer is synchronized with source layer\");\n        // activate would issue a SLD WMS DescribeLayer request and we are bypassing this here\n        control.active = true;\n        control.deactivate();\n        t.eq(map.layers.length, 1, \"Selection layer is removed on deactive if clearOnDeactivate is set to true\");\n        map.destroy();\n    }\n\n    function test_filterModificationOnSelected(t) {\n        t.plan(1);\n        var parser = new OpenLayers.Format.WFSDescribeFeatureType();\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS('Foo', 'http://foo', {LAYERS: 'AAA64'});\n        map.addLayer(layer);\n\n        var text =\n            '<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>' +\n            '<schema' +\n            '   targetNamespace=\"http://mapserver.gis.umn.edu/mapserver\" ' +\n            '   xmlns:rws=\"http://mapserver.gis.umn.edu/mapserver\" ' +\n            '   xmlns:ogc=\"http://www.opengis.net/ogc\"' +\n            '   xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"' +\n            '   xmlns=\"http://www.w3.org/2001/XMLSchema\"' +\n            '   xmlns:gml=\"http://www.opengis.net/gml\"' +\n            '   elementFormDefault=\"qualified\" version=\"0.1\" >' +\n            '  <import namespace=\"http://www.opengis.net/gml\"' +\n            '          schemaLocation=\"http://schemas.opengis.net/gml/2.1.2/feature.xsd\" />' +\n            '  <element name=\"AAA64\" ' +\n            '           type=\"rws:AAA64Type\" ' +\n            '           substitutionGroup=\"gml:_Feature\" />' +\n            '  <complexType name=\"AAA64Type\">' +\n            '    <complexContent>' +\n            '      <extension base=\"gml:AbstractFeatureType\">' +\n            '        <sequence>' +\n            '          <element name=\"geometry\" type=\"gml:MultiLineStringPropertyType\" minOccurs=\"0\" maxOccurs=\"1\"/>' +\n            '          <element name=\"OBJECTID\" type=\"string\"/>' +\n            '        </sequence>' +\n            '      </extension>' +\n            '    </complexContent>' +\n            '  </complexType>' +\n            '</schema>';\n\n        OpenLayers.Control.SLDSelect.prototype.wfsCache[layer.id] = parser.read(text);\n        var control = new OpenLayers.Control.SLDSelect(OpenLayers.Handler.RegularPolygon,\n            {layers: [layer], clearOnDeactivate: true, handlerOptions: {irregular: true} });\n\n        var testEvent = function(evt) {\n            // manipulate filter\n            var bbox = OpenLayers.Bounds.fromString('1,2,3,4');\n            evt.filters[0].value = bbox;\n        };\n        control.events.register(\"selected\", this, testEvent);\n        map.addControl(control);\n        var geometry = OpenLayers.Geometry.Polygon.createRegularPolygon(\n            new OpenLayers.Geometry.Point(0, 0), 5, 4);\n        control.select(geometry);\n        control.events.unregister(\"selected\", this, testEvent);\n\n        var expected_sld = '<sld:StyledLayerDescriptor xmlns:sld=\"http://www.opengis.net/sld\" version=\"1.0.0\" xsi:schemaLocation=\"http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:gml=\"http://www.opengis.net/gml\"><sld:NamedLayer><sld:Name>AAA64</sld:Name><sld:UserStyle><sld:Name>default</sld:Name><sld:FeatureTypeStyle><sld:Rule><ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\"><ogc:BBOX><ogc:PropertyName>geometry</ogc:PropertyName><gml:Box xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"EPSG:4326\"><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2 3,4</gml:coordinates></gml:Box></ogc:BBOX></ogc:Filter><sld:LineSymbolizer><sld:Stroke><sld:CssParameter name=\"stroke\">#FF0000</sld:CssParameter><sld:CssParameter name=\"stroke-width\">2</sld:CssParameter></sld:Stroke></sld:LineSymbolizer></sld:Rule></sld:FeatureTypeStyle></sld:UserStyle></sld:NamedLayer></sld:StyledLayerDescriptor>';\n\n        t.xml_eq(map.layers[1].params.SLD_BODY, expected_sld, \"Filter / SLD manipulated in select-callback correctly\");\n\n    }\n\n    function test_multiselect(t) {\n        t.plan(2);\n\n        var parser = new OpenLayers.Format.WFSDescribeFeatureType();\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS('Multi', 'http://foo', {LAYERS: 'KGNAT.VKUNSTWERK,KGNAT.LKUNSTWERK,KGNAT.PKUNSTWERK'});\n        map.addLayer(layer);\n\n        var text =\n            '<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>' +\n            '<schema' +\n            '   targetNamespace=\"http://mapserver.gis.umn.edu/mapserver\" ' +\n            '   xmlns:rws=\"http://mapserver.gis.umn.edu/mapserver\" ' +\n            '   xmlns:ogc=\"http://www.opengis.net/ogc\"' +\n            '   xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"' +\n            '   xmlns=\"http://www.w3.org/2001/XMLSchema\"' +\n            '   xmlns:gml=\"http://www.opengis.net/gml\"' +\n            '   elementFormDefault=\"qualified\" version=\"0.1\" >' +\n            '  <import namespace=\"http://www.opengis.net/gml\"' +\n            '          schemaLocation=\"http://schemas.opengis.net/gml/2.1.2/feature.xsd\" />' +\n            '  <element name=\"KGNAT.VKUNSTWERK\" ' +\n            '           type=\"rws:KGNAT.VKUNSTWERKType\" ' +\n            '           substitutionGroup=\"gml:_Feature\" />' +\n            '  <complexType name=\"KGNAT.VKUNSTWERKType\">' +\n            '    <complexContent>' +\n            '      <extension base=\"gml:AbstractFeatureType\">' +\n            '        <sequence>' +\n            '          <element name=\"geometry\" type=\"gml:MultiPolygonPropertyType\" minOccurs=\"0\" maxOccurs=\"1\"/>' +\n            '        </sequence>' +\n            '      </extension>' +\n            '    </complexContent>' +\n            '  </complexType>' +\n            '  <element name=\"KGNAT.LKUNSTWERK\" ' +\n            '           type=\"rws:KGNAT.LKUNSTWERKType\" ' +\n            '           substitutionGroup=\"gml:_Feature\" />' +\n            '  <complexType name=\"KGNAT.LKUNSTWERKType\">' +\n            '    <complexContent>' +\n            '      <extension base=\"gml:AbstractFeatureType\">' +\n            '        <sequence>' +\n            '          <element name=\"geometry\" type=\"gml:MultiLineStringPropertyType\" minOccurs=\"0\" maxOccurs=\"1\"/>' +\n            '        </sequence>' +\n            '      </extension>' +\n            '    </complexContent>' +\n            '  </complexType>' +\n            '  <element name=\"KGNAT.PKUNSTWERK\" ' +\n            '           type=\"rws:KGNAT.PKUNSTWERKType\" ' +\n            '           substitutionGroup=\"gml:_Feature\" />' +\n            '  <complexType name=\"KGNAT.PKUNSTWERKType\">' +\n            '    <complexContent>' +\n            '      <extension base=\"gml:AbstractFeatureType\">' +\n            '        <sequence>' +\n            '          <element name=\"geometry\" type=\"gml:MultiPointPropertyType\" minOccurs=\"0\" maxOccurs=\"1\"/>' +\n            '        </sequence>' +\n            '      </extension>' +\n            '    </complexContent>' +\n            '  </complexType>' +\n            '</schema>';\n\n        OpenLayers.Control.SLDSelect.prototype.wfsCache[layer.id] = parser.read(text);\n        var control = new OpenLayers.Control.SLDSelect(OpenLayers.Handler.RegularPolygon, {handlerOptions: {irregular: true}, layers: [layer]});\n        var testEvent = function(evt) {\n            t.eq(evt.filters.length, 3, \"Event has a filters array set with length tree\");\n        };\n        control.events.register(\"selected\", this, testEvent);\n\n        map.addControl(control);\n        var geometry = OpenLayers.Geometry.Polygon.createRegularPolygon(\n            new OpenLayers.Geometry.Point(0, 0), 5, 4);\n        control.select(geometry);\n        var expected_sld = '<sld:StyledLayerDescriptor xmlns:sld=\"http://www.opengis.net/sld\" version=\"1.0.0\" xsi:schemaLocation=\"http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:gml=\"http://www.opengis.net/gml\"><sld:NamedLayer><sld:Name>KGNAT.VKUNSTWERK</sld:Name><sld:UserStyle><sld:Name>default</sld:Name><sld:FeatureTypeStyle><sld:Rule><ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\"><ogc:BBOX><ogc:PropertyName>geometry</ogc:PropertyName><gml:Box xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"EPSG:4326\"><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">-3.5355339059327,-3.5355339059327 3.5355339059327,3.5355339059327</gml:coordinates></gml:Box></ogc:BBOX></ogc:Filter><sld:PolygonSymbolizer><sld:Fill><sld:CssParameter name=\"fill\">#FF0000</sld:CssParameter></sld:Fill></sld:PolygonSymbolizer></sld:Rule></sld:FeatureTypeStyle></sld:UserStyle></sld:NamedLayer><sld:NamedLayer><sld:Name>KGNAT.LKUNSTWERK</sld:Name><sld:UserStyle><sld:Name>default</sld:Name><sld:FeatureTypeStyle><sld:Rule><ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\"><ogc:BBOX><ogc:PropertyName>geometry</ogc:PropertyName><gml:Box xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"EPSG:4326\"><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">-3.5355339059327,-3.5355339059327 3.5355339059327,3.5355339059327</gml:coordinates></gml:Box></ogc:BBOX></ogc:Filter><sld:LineSymbolizer><sld:Stroke><sld:CssParameter name=\"stroke\">#FF0000</sld:CssParameter><sld:CssParameter name=\"stroke-width\">2</sld:CssParameter></sld:Stroke></sld:LineSymbolizer></sld:Rule></sld:FeatureTypeStyle></sld:UserStyle></sld:NamedLayer><sld:NamedLayer><sld:Name>KGNAT.PKUNSTWERK</sld:Name><sld:UserStyle><sld:Name>default</sld:Name><sld:FeatureTypeStyle><sld:Rule><ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\"><ogc:BBOX><ogc:PropertyName>geometry</ogc:PropertyName><gml:Box xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"EPSG:4326\"><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">-3.5355339059327,-3.5355339059327 3.5355339059327,3.5355339059327</gml:coordinates></gml:Box></ogc:BBOX></ogc:Filter><sld:PointSymbolizer><sld:Graphic><sld:Mark><sld:WellKnownName>square</sld:WellKnownName><sld:Fill><sld:CssParameter name=\"fill\">#FF0000</sld:CssParameter></sld:Fill><sld:Stroke/></sld:Mark><sld:Size>10</sld:Size></sld:Graphic></sld:PointSymbolizer></sld:Rule></sld:FeatureTypeStyle></sld:UserStyle></sld:NamedLayer></sld:StyledLayerDescriptor>';\n\n        t.xml_eq(map.layers[1].params.SLD_BODY, expected_sld, \"SLD generated correctly\");\n        map.destroy();\n    }\n    \n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 100px; height: 100px;\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/Scale.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    OpenLayers.Lang.setCode('en');\n    var map; \n    function test_Control_Scale_constructor (t) {\n        t.plan( 2 );\n    \n        control = new OpenLayers.Control.Scale();\n        t.ok( control instanceof OpenLayers.Control.Scale, \"new OpenLayers.Control returns object\" );\n        t.eq( control.displayClass,  \"olControlScale\", \"displayClass is correct\" );\n    }\n    function test_Control_Scale_initwithelem (t) {\n        t.plan( 1 );\n    \n        control = new OpenLayers.Control.Scale(OpenLayers.Util.getElement('scale'));\n        t.ok(true, \"If this happens, then we passed. (FF throws an error above otherwise)\");\n    }\n    function test_Control_Scale_updateScale (t) {\n        t.plan( 4 );\n    \n        control = new OpenLayers.Control.Scale('scale');\n        t.ok( control instanceof OpenLayers.Control.Scale, \"new OpenLayers.Control returns object\" );\n        map = new OpenLayers.Map('map', {zoomMethod: null});\n        layer = new OpenLayers.Layer.WMS('Test Layer', \"http://octo.metacarta.com/cgi-bin/mapserv\", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});\n        map.addLayer(layer);\n        map.zoomTo(0);\n        map.addControl(control);\n        t.eq(OpenLayers.Util.getElement('scale').innerHTML, \"Scale = 1 : 443M\", \"Scale set by default.\"  );\n        map.zoomIn();\n        t.eq(OpenLayers.Util.getElement('scale').innerHTML, \"Scale = 1 : 221M\", \"Zooming in changes scale\"  );\n        map.baseLayer.resolutions = [OpenLayers.Util.getResolutionFromScale(110)];\n        map.zoomTo(0);\n        t.eq(OpenLayers.Util.getElement('scale').innerHTML, \"Scale = 1 : 110\", \"Scale of 100 isn't rounded\"  );\n    }\n    function test_Control_Scale_internalScale (t) {\n        t.plan(2);\n        control = new OpenLayers.Control.Scale();\n        t.ok( control instanceof OpenLayers.Control.Scale, \"new OpenLayers.Control returns object\" );\n        map = new OpenLayers.Map('map', {zoomMethod: null});\n        layer = new OpenLayers.Layer.WMS('Test Layer', \"http://octo.metacarta.com/cgi-bin/mapserv\", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});\n        map.addLayer(layer);\n        map.zoomTo(0);\n        map.addControl(control);\n        t.eq(control.div.firstChild.innerHTML, \"Scale = 1 : 443M\", \"Internal scale displayed properly.\");\n    }    \n  </script>\n</head>\n<body>\n    <a id=\"scale\" href=\"\">Scale</a> <br />\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/ScaleLine.html",
    "content": "<html>\n<head>\n    <script type=\"text/javascript\">var oldAlert = window.alert, gMess; window.alert = function(message) {gMess = message; return true;};</script>\n  <script src=\"http://maps.google.com/maps/api/js?v=3&amp;sensor=false\"></script>\n  <script type=\"text/javascript\">window.alert = oldAlert;</script>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n  var validkey = (window.location.protocol == \"file:\") ||\n                 (window.location.host == \"localhost\") ||\n                 (window.location.host == \"openlayers.org\");\n\n    function test_initialize(t) {\n        t.plan(2);    \n        var control = new OpenLayers.Control.ScaleLine();\n        t.ok(control instanceof OpenLayers.Control.ScaleLine, \"new OpenLayers.Control returns object\" );\n        t.eq(control.displayClass,  \"olControlScaleLine\", \"displayClass is correct\" );\n        control.destroy();\n    }\n\n    function test_initwithelem(t) {\n        t.plan(1);\n        var control = new OpenLayers.Control.ScaleLine({\"div\":OpenLayers.Util.getElement('ScaleLine')});\n        t.ok(true, \"If this happens, then we passed. (FF throws an error above otherwise)\");\n        control.destroy();\n    }\n\n    function test_calcDegrees(t) {\n        t.plan(5);\n        var control = new OpenLayers.Control.ScaleLine();\n        t.ok(control instanceof OpenLayers.Control.ScaleLine, \"new OpenLayers.Control returns object\" );\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS('Test Layer', \"http://octo.metacarta.com/cgi-bin/mapserv\", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});\n        map.addLayer(layer);\n        map.zoomTo(0);\n        map.addControl(control);\n        t.eq(control.div.firstChild.style.visibility, \"visible\", \"top scale is present.\");\n        t.eq(control.div.lastChild.style.visibility, \"visible\", \"bottom scale is present.\");\n        t.eq(control.div.firstChild.innerHTML, \"10000 km\", \"top scale has correct text.\");\n        t.eq(control.div.lastChild.innerHTML, \"5000 mi\", \"bottom scale has correct text.\");\n        map.destroy();\n    }\n\n    function test_calcsOther (t) {\n        t.plan(5);\n        var control = new OpenLayers.Control.ScaleLine();\n        t.ok(control instanceof OpenLayers.Control.ScaleLine, \"new OpenLayers.Control returns object\" );\n        var map = new OpenLayers.Map('map');\n        map.units = \"mi\";\n        var layer = new OpenLayers.Layer.WMS('Test Layer', \"http://octo.metacarta.com/cgi-bin/mapserv\", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});\n        map.addLayer(layer);\n        map.zoomTo(0);\n        map.addControl(control);\n        t.eq(control.div.firstChild.style.visibility, \"visible\", \"top scale is present.\");\n        t.eq(control.div.lastChild.style.visibility, \"visible\", \"bottom scale is present.\");\n        t.eq(control.div.firstChild.innerHTML, \"100 km\", \"top scale has correct text.\");\n        t.eq(control.div.lastChild.innerHTML, \"100 mi\", \"bottom scale has correct text.\");\n        map.destroy();\n    }\n\n    function test_calcMeters (t) {        \n        t.plan(5);         \n        // this example is taken from the projected-map.html OpenLayers example\n        var lat = 900863; \n        var lon = 235829;\n        var zoom = 6;\n        var map = new OpenLayers.Map( 'map' );\n        var basemap = new OpenLayers.Layer.WMS( \"Boston\", \n          \"http://boston.freemap.in/cgi-bin/mapserv?\",\n                {\n                 map: '/www/freemap.in/boston/map/gmaps.map', \n                 layers: 'border,water,roads,rapid_transit,buildings', \n                 format: 'png', \n                 transparent: 'off'\n                },\n        \n            {\n              maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), \n              maxResolution: 296985/1024,  \n              projection:\"EPSG:2805\",     // Used in WMS/WFS requests.   \n              units: \"m\"                  // Only neccesary for working with scales.\n              } );\n            \n        map.addLayer(basemap);        \n        map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);\n        map.addControl(new OpenLayers.Control.LayerSwitcher());                \n        var control = new OpenLayers.Control.ScaleLine();\n        t.ok( control instanceof OpenLayers.Control.ScaleLine, \"new OpenLayers.Control returns object\" );\n        map.addControl(control);\n        t.eq(control.div.firstChild.style.visibility, \"visible\", \"top scale is present.\");\n        t.eq(control.div.lastChild.style.visibility, \"visible\", \"bottom scale is present.\");\n        t.eq(control.div.firstChild.innerHTML, \"200 m\", \"top scale has correct text.\");\n        t.eq(control.div.lastChild.innerHTML, \"1000 ft\", \"bottom scale has correct text.\");\n        map.destroy();\n    }\n    \n    function test_useArguments (t) {\n        t.plan(5);\n        var control = new OpenLayers.Control.ScaleLine({topOutUnits: 'dd'} );\n        t.ok( control instanceof OpenLayers.Control.ScaleLine, \"new OpenLayers.Control returns object\" );\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS('Test Layer', \"http://octo.metacarta.com/cgi-bin/mapserv\", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});\n        map.addLayer(layer);\n        map.zoomTo(0);\n        map.addControl(control);\n        t.eq(control.div.firstChild.style.visibility, \"visible\", \"top scale is present.\");\n        t.eq(control.div.lastChild.style.visibility, \"visible\", \"bottom scale is present.\");\n        t.eq(control.div.firstChild.innerHTML, \"100 dd\", \"top scale has correct text.\");\n        t.eq(control.div.lastChild.innerHTML, \"5000 mi\", \"bottom scale has correct text.\");\n        map.destroy();\n    }\n\n    function test_respectZoom (t) {\n        if(validkey) {\n            t.plan( 4 );\n        } else {\n            t.plan( 3 );\n        }\n        // ok, switch the units we use for zoomed in values.  This will test that we're both\n        //   correctly respecting all specified parameters and that we're switching to the \n        //   \"in\" units when zoomed in\n        var control = new OpenLayers.Control.ScaleLine({topOutUnits : \"mi\", bottomOutUnits: \"km\", topInUnits: 'ft', bottomInUnits: 'm'});\n        t.ok( control instanceof OpenLayers.Control.ScaleLine, \"new OpenLayers.Control returns object\" );\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS('Test Layer', \"http://octo.metacarta.com/cgi-bin/mapserv\", {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'});\n        map.addLayer(layer);\n        map.zoomTo(0);\n        map.addControl(control);\n        var widthIsOk = true;\n        for (var i=0; i<map.numZoomLevels && widthIsOk; i++) {\n            map.zoomTo(i);\n            var w1 = parseInt(control.eTop.style.width);\n            var w2 = parseInt(control.eBottom.style.width);\n            widthIsOk = w1 <= control.maxWidth && w2 <= control.maxWidth;\n        }\n        t.ok(widthIsOk, \"respects maxWidth at all zoom levels in dd\");\n        \n        widthIsOk = true;\n        control.maxWidth = 200;\n        for (var i=0; i<map.numZoomLevels && widthIsOk; i++) {\n            map.zoomTo(i);\n            var w1 = parseInt(control.eTop.style.width);\n            var w2 = parseInt(control.eBottom.style.width);\n            widthIsOk = w1 <= control.maxWidth && w2 <= control.maxWidth;\n        }\n        t.ok(widthIsOk, \"respects modified maxWidth at all zoom levels in dd\");\n\n        if (validkey) {\n            var map = new OpenLayers.Map('map');\n            var layer = new OpenLayers.Layer.Google('Goog Layer');\n            var control = new OpenLayers.Control.ScaleLine({topOutUnits : \"mi\", bottomOutUnits: \"km\", topInUnits: 'ft', bottomInUnits: 'm'});\n            map.addLayer(layer);\n            map.zoomTo(0);\n            map.addControl(control);\n            var widthIsOk = true;\n            for (var i=0; i<map.numZoomLevels && widthIsOk; i++) {\n                map.zoomTo(i);\n                var w1 = parseInt(control.eTop.style.width);\n                var w2 = parseInt(control.eBottom.style.width);\n                widthIsOk = w1 <= control.maxWidth && w2 <= control.maxWidth;\n            }\n            t.ok(widthIsOk, \"respects maxWidth at all zoom levels in m\");\n        } else {\n            t.debug_print(\"Google tests can't be run from \" +\n                          window.location.host);          \n        }\n\n        map.destroy();\n    }   \n    function test_ie_oneunit(t) {\n        t.plan(2);\n        var control = new OpenLayers.Control.ScaleLine({bottomOutUnits:'',bottomInUnits:'',maxWidth:150});\n        t.ok(control instanceof OpenLayers.Control.ScaleLine, \"new OpenLayers.Control returns object\" );\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS('Test Layer', \"bogus\", {});\n        map.addLayer(layer);\n        map.zoomTo(0);\n        map.addControl(control);\n        t.ok(true, \"invisible bottom scale doesn't cause scaleline failure (IE only)\");\n        map.destroy();\n    }\n  </script>\n</head>\n<body>\n    <a id=\"ScaleLine\" href=\"\">ScaleLine</a> <br/>\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/SelectFeature.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    function test_Control_SelectFeature_constructor(t) {\n        t.plan(5);\n        var options = {\n//            geometryTypes: \"foo\"\n        };\n        var layer = \"bar\";\n        var control = new OpenLayers.Control.SelectFeature([layer], options);\n        t.ok(control instanceof OpenLayers.Control.SelectFeature,\n             \"new OpenLayers.Control.SelectFeature returns an instance\");\n        t.eq(control.layers[0], \"bar\",\n             \"constructor with array of layers sets layer correctly\");\n//        t.eq(control.handlers.feature.geometryTypes, \"foo\",\n//             \"constructor sets options correctly on feature handler\");\n        t.ok(control.layer instanceof OpenLayers.Layer.Vector.RootContainer, \"control has a root container layer if constructor was called with an array of layers\");\n\n        control = new OpenLayers.Control.SelectFeature(layer, options);\n        t.eq(control.layers, null, \"this.layers is null if constructor called with a single layer\");\n        t.eq(control.layer, layer, \"this.layer holds the layer that was passed with the constructor if called with a single layer\")\n    }\n\n    function test_Control_SelectFeature_destroy(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.SelectFeature(layer, {box: true});\n        control.handlers.feature.deactivate = function() {\n            t.ok(true,\n                 \"control.deactivate calls deactivate on feature handler\");\n        }\n        control.handlers.box.deactivate = function() {\n            t.ok(true,\n                 \"control.deactivate calls deactivate on box handler\");\n        }\n// should nullify the layer property here\n        control.destroy();\n\n    }\n\n    function test_Control_SelectFeature_select(t) {\n        t.plan(4);\n        var map = new OpenLayers.Map(\"map\");\n        var layer1 = new OpenLayers.Layer.Vector();\n        var layer2 = new OpenLayers.Layer.Vector();\n        map.addLayers([layer1, layer2]);\n        var control = new OpenLayers.Control.SelectFeature([layer1, layer2]);\n        var feature1 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,1));\n        var feature2 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,0));\n        layer1.addFeatures(feature1);\n        layer2.addFeatures(feature2);\n        var drawFeature = function(feature, style) {\n            feature.layer.styleMap.createSymbolizer(feature, style);\n        }\n        layer1.drawFeature = drawFeature;\n        layer2.drawFeature = drawFeature;\n        control.select(feature1);\n        t.eq(feature1.renderIntent, \"select\", \"render intent is set to select\");\n        control.select(feature2);\n        t.eq(feature2.renderIntent, \"select\", \"render intent is set to select\");\n        control.unselect(feature1);\n        t.eq(feature1.renderIntent, \"default\", \"render intent is set back to default\");\n        control.unselect(feature2);\n        t.eq(feature2.renderIntent, \"default\", \"render intent is set back to default\");\n    }\n\n    function test_Control_SelectFeature_clickFeature(t) {\n        t.plan(6);\n        // mock up layer\n        var layer = {\n            selectedFeatures: [],\n            drawFeature: function() {},\n            events: {\n                triggerEvent: function() {}\n            }\n        };\n        // mock up active control\n        var control = new OpenLayers.Control.SelectFeature(layer);\n        control.handlers.feature = {\n            evt: {}\n        };\n        // mock up features\n        var features = new Array(4);\n        for(var i=0; i<features.length; ++i) {\n            features[i] = {\n                id: Math.random(),\n                tested: 0,\n                style: \"\",\n                layer: layer\n            };\n        }\n\n        // test that onSelect gets called properly\n        control.onSelect = function(feature) {\n            feature.tested += 1;\n            t.eq(feature.id, features[feature.index].id,\n                 \"onSelect called with proper feature (\" + feature.index + \")\");\n            t.eq(feature.tested, feature.test,\n                 \"onSelect called only once for feature (\" + feature.index + \")\");\n            t.ok(this == control, \"onSelect called in the scope of the control if control.scope is not provided\");\n        }\n\n        // test that onUnselect gets called properly\n        control.onUnselect = function(feature) {\n            feature.tested += 1;\n            t.eq(feature.id, features[feature.index].id,\n                 \"onUnselect called with proper feature (\" + feature.index + \")\");\n            t.eq(feature.tested, feature.test,\n                 \"onUnselect called only once for feature (\" + feature.index + \")\");\n            t.ok(this == control, \"onUnselect called in the scope of the control if control.scope is not provided\");\n        }\n\n        // mock up first click on first feature (runs 3 tests from onSelect)\n        var feature = features[0];\n        feature.index = 0;\n        feature.test = 1;\n        control.clickFeature(feature);\n\n        // mock up second click on first feature (runs no tests - already selected)\n        control.toggle = false;\n        control.clickFeature(feature);\n\n        // mock up second click on first feature (runs 3 tests from onUnselect)\n        control.toggle = true;\n        feature.test = 2;\n        control.clickFeature(feature);\n\n\n    }\n\n    function test_box(t) {\n        t.plan(5);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        map.setBaseLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(1,1));\n        var control = new OpenLayers.Control.SelectFeature(layer, {'multiple': true, box: true });\n        var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0));\n        var feature2 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,1));\n        var feature3 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(-2,-2));\n        var feature4 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString([\n            new OpenLayers.Geometry.Point(0, 0), new OpenLayers.Geometry.Point(1, 1)\n        ]));\n        layer.addFeatures([feature, feature2, feature3, feature4]);\n        control.setMap(map);\n        map.getLonLatFromPixel = function(arg) {\n            return new OpenLayers.LonLat(arg.x, arg.y);\n        }\n        control.selectBox(new OpenLayers.Bounds(-1, -1, 2, 2));\n        t.eq(layer.selectedFeatures.length, 3, \"box around all features selects 3 features\");\n\n        control.selectBox(new OpenLayers.Bounds(-3, -3, -1, -1));\n        t.eq(layer.selectedFeatures.length, 4, \"box around other features doesn't turn off already selected features.\");\n\n        control.multipleSelect = function() {\n            return false;\n        };\n        control.selectBox(new OpenLayers.Bounds(-3, -3, -1, -1));\n        t.eq(layer.selectedFeatures.length, 1, \"box around other features correctly turns off already selected features.\");\n\n        control.geometryTypes = null;\n        control.selectBox(new OpenLayers.Bounds(-100, -100, 100, 100));\n        t.eq(layer.selectedFeatures.length, layer.features.length, \"all features selected with no geometryTypes filter\");\n\n        control.geometryTypes = [\"OpenLayers.Geometry.Point\"];\n        control.selectBox(new OpenLayers.Bounds(-100, -100, 100, 100));\n        t.eq(layer.selectedFeatures.length, 3, \"3 features selected with geometryTypes filter\");\n\n\n    }\n\n\n    function test_selectBox_events(t){\n        t.plan(8);\n        var map = new OpenLayers.Map(\"map\");\n        var layer1 = new OpenLayers.Layer.Vector();\n        map.addLayer(layer1);\n        map.setBaseLayer(layer1);\n        var layer2 = new OpenLayers.Layer.Vector();\n        map.addLayer(layer2);\n        map.setCenter(new OpenLayers.LonLat(1,1));\n        var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,1));\n        layer1.addFeatures([feature]);\n        var control = new OpenLayers.Control.SelectFeature(layer1);\n        control.setMap(map);\n        map.getLonLatFromPixel = function(arg) {\n            return new OpenLayers.LonLat(arg.x, arg.y);\n        }\n        control.activate();\n        var firesBoxselectionstart = false;\n        var beforeSelectingNumberOfFeatures = -1;\n        var firesBoxselectionend = false;\n        var afterSelectingNumberOfFeatures = -1;\n        control.events.register(\"boxselectionstart\",null, function(e){\n            firesBoxselectionstart=true;\n            t.eq(e.layers.length,1,\"right number of layers in event boxselectionstart\");\n            t.eq(layer1.id, e.layers[0].id,\"correct layer in event boxselectionstart\");\n            beforeSelectingNumberOfFeatures = e.layers[0].selectedFeatures.length;\n        });\n        control.events.register(\"boxselectionend\",null, function(e){\n            firesBoxselectionend=true;\n            t.eq(e.layers.length,1,\"right number of layers in event boxselectionend\");\n            t.eq(layer1.id, e.layers[0].id,\"correct layer in event boxselectionend\");\n            afterSelectingNumberOfFeatures = e.layers[0].selectedFeatures.length;\n        });\n        var bounds = new OpenLayers.Bounds(-1, -1, 2, 2);\n        control.selectBox(bounds);\n        t.ok(firesBoxselectionstart,\"selectBox fires boxselectionstart event\");\n        t.eq(beforeSelectingNumberOfFeatures,0,\"boxselectionstart fires before selection of feature\");\n        t.ok(firesBoxselectionend,\"selectBox fires boxselectionend event\");\n        t.eq(afterSelectingNumberOfFeatures,1,\"boxselectionend fires after feature selected\");\n    }\n    function test_Control_SelectFeature_activate(t) {\n        t.plan(4);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.SelectFeature(layer, {box: true});\n        map.addControl(control);\n        t.ok(!control.handlers.feature.active,\n             \"feature handler is not active prior to activating control\");\n        t.ok(!control.handlers.box.active,\n             \"box handler is not active prior to activating control\");\n        control.activate();\n        t.ok(control.handlers.feature.active,\n             \"feature handler is active after activating control\");\n        t.ok(control.handlers.box.active,\n             \"box handler is active after activating control\");\n    }\n\n    function test_Control_SelectFeature_deactivate(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.SelectFeature(layer, {box: true});\n        map.addControl(control);\n\n        control.activate();\n        control.handlers.feature.deactivate = function() {\n            t.ok(true,\n                 \"control.deactivate calls deactivate on feature handler\");\n            OpenLayers.Handler.Feature.prototype.deactivate.apply(this, arguments);\n        }\n        control.handlers.box.deactivate = function() {\n            t.ok(true,\n                 \"control.deactivate calls deactivate on box handler\");\n        }\n        control.deactivate();\n    }\n\n    function test_highlighyOnly(t) {\n        t.plan(23);\n\n        /*\n         * setup\n         */\n\n        var map, layer, ctrl1, ctrl2, _feature, feature, evt, _style;\n\n        map = new OpenLayers.Map(\"map\");\n        layer = new OpenLayers.Layer.Vector(\"name\", {isBaseLayer: true});\n        map.addLayer(layer);\n\n        ctrl1 = new OpenLayers.Control.SelectFeature(layer, {\n            highlightOnly: false,\n            hover: false\n        });\n        map.addControl(ctrl1);\n\n        ctrl2 = new OpenLayers.Control.SelectFeature(layer, {\n            highlightOnly: true,\n            hover: true\n        });\n        map.addControl(ctrl2);\n\n        ctrl2.activate();\n        ctrl1.activate();\n\n        feature = new OpenLayers.Feature.Vector();\n        feature.layer = layer;\n\n        // override the layer's getFeatureFromEvent func so that it always\n        // returns the feature referenced to by _feature\n        layer.getFeatureFromEvent = function(evt) { return _feature; };\n\n        evt = {xy: new OpenLayers.Pixel(Math.random(), Math.random())};\n\n        map.zoomToMaxExtent();\n\n        /*\n         * tests\n         */\n\n        // with renderIntent\n\n        ctrl1.renderIntent = \"select\";\n        ctrl2.renderIntent = \"temporary\";\n\n        // mouse over feature, feature is drawn with \"temporary\"\n        _feature = feature;\n        evt.type = \"mousemove\";\n        map.events.triggerEvent(\"mousemove\", evt);\n        t.eq(feature.renderIntent, \"temporary\",\n             \"feature drawn with expected render intent after \\\"mouseover\\\"\");\n        t.eq(feature._lastHighlighter, ctrl2.id,\n             \"feature._lastHighlighter properly set after \\\"mouseover\\\"\");\n        t.eq(feature._prevHighlighter, undefined,\n             \"feature._prevHighlighter properly set after \\\"mouseover\\\"\");\n\n        // click in feature, feature is drawn with \"select\"\n        _feature = feature;\n        evt.type = \"click\";\n        map.events.triggerEvent(\"click\", evt);\n        t.eq(feature.renderIntent, \"select\",\n             \"feature drawn with expected render intent after \\\"clickin\\\"\");\n        t.eq(feature._lastHighlighter, ctrl1.id,\n             \"feature._lastHighlighter properly set after \\\"clickin\\\"\");\n        t.eq(feature._prevHighlighter, ctrl2.id,\n             \"feature._prevHighlighter properly set after \\\"clickin\\\"\");\n\n        // mouse out of feature, feature is still drawn with \"select\"\n        _feature = null;\n        evt.type = \"mousemove\";\n        map.events.triggerEvent(\"mousemove\", evt);\n        t.eq(feature.renderIntent, \"select\",\n             \"feature drawn with expected render intent after \\\"mouseout\\\"\");\n        t.eq(feature._lastHighlighter, ctrl1.id,\n             \"feature._lastHighlighter properly set after \\\"nouseout\\\"\");\n        t.ok(feature._prevHighlighter, ctrl2.id,\n             \"feature._prevHighlighter properly set after \\\"mouseout\\\"\");\n\n        // mouse over feature again, feature is drawn with \"temporary\"\n        _feature = feature;\n        evt.type = \"mousemove\";\n        map.events.triggerEvent(\"mousemove\", evt);\n        t.eq(feature.renderIntent, \"temporary\",\n             \"feature drawn with expected render intent after \\\"mouseover\\\"\");\n        t.eq(feature._lastHighlighter, ctrl2.id,\n             \"feature._lastHighlighter properly set after \\\"mouseover\\\"\");\n        t.eq(feature._prevHighlighter, ctrl1.id,\n             \"feature._prevHighlighter properly set after \\\"mouseover\\\"\");\n\n        // mouve out of feature again, feature is still drawn with \"select\"\n        _feature = null;\n        evt.type = \"mousemove\";\n        map.events.triggerEvent(\"mousemove\", evt);\n        t.eq(feature.renderIntent, \"select\",\n             \"feature drawn with expected render intent after \\\"mouseout\\\"\");\n        t.eq(feature._lastHighlighter, ctrl1.id,\n             \"feature._lastHighlighter properly set after \\\"mouseout\\\"\");\n        t.eq(feature._prevHighlighter, undefined,\n             \"feature._prevHighlighter properly set after \\\"mouseout\\\"\");\n\n        // click out of feature, feature is drawn with \"default\"\n        _feature = null;\n        evt.type = \"click\";\n        map.events.triggerEvent(\"click\", evt);\n        t.eq(feature.renderIntent, \"default\",\n             \"feature drawn with expected render intent after \\\"clickout\\\"\");\n        t.eq(feature._lastHighlighter, undefined,\n             \"feature._lastHighlighter properly set after \\\"clickout\\\"\");\n        t.eq(feature._prevHighlighter, undefined,\n             \"feature._prevHighlighter properly set after \\\"clickout\\\"\");\n\n        // with selectStyle\n\n        ctrl1.selectStyle = OpenLayers.Feature.Vector.style[\"select\"];\n        ctrl2.selectStyle = OpenLayers.Feature.Vector.style[\"temporary\"];\n\n        layer.renderer.drawFeature = function(f, s) {\n            var style = OpenLayers.Feature.Vector.style[_style];\n            t.eq(s, style, \"renderer drawFeature called with expected style obj (\" + _style + \")\");\n        };\n\n        // mouse over feature, feature is drawn with \"temporary\"\n        _feature = feature;\n        _style = \"temporary\";\n        evt.type = \"mousemove\";\n        map.events.triggerEvent(\"mousemove\", evt);\n\n        // click in feature, feature is drawn with \"select\"\n        _feature = feature;\n        _style = \"select\";\n        evt.type = \"click\";\n        map.events.triggerEvent(\"click\", evt);\n\n        // mouse out of feature, feature is still drawn with \"select\" and\n        // the renderer drawFeature method should not be called\n        _feature = null;\n        evt.type = \"mousemove\";\n        map.events.triggerEvent(\"mousemove\", evt);\n\n        // mouse over feature again, feature is drawn with \"temporary\"\n        _feature = feature;\n        _style = \"temporary\";\n        evt.type = \"mousemove\";\n        map.events.triggerEvent(\"mousemove\", evt);\n\n        // mouve out of feature again, feature is still drawn with \"select\"\n        _feature = null;\n        _style = \"select\";\n        evt.type = \"mousemove\";\n        map.events.triggerEvent(\"mousemove\", evt);\n\n        // click out of feature, feature is drawn with \"default\"\n        _feature = null;\n        _style = \"default\";\n        evt.type = \"click\";\n        map.events.triggerEvent(\"click\", evt);\n    }\n\n    // test for http://trac.openlayers.org/ticket/2812\n    function test_highlightOnly_toggle(t) {\n        t.plan(8);\n\n        /*\n         * setup\n         */\n\n        var map, layer, ctrl1, ctrl2, _feature, feature, evt, _style;\n\n        map = new OpenLayers.Map(\"map\");\n        layer = new OpenLayers.Layer.Vector(\"name\", {isBaseLayer: true});\n        map.addLayer(layer);\n\n        ctrl1 = new OpenLayers.Control.SelectFeature(layer, {\n            highlightOnly: false,\n            hover: false,\n            clickout: false,\n            toggle: true\n        });\n        map.addControl(ctrl1);\n\n        ctrl2 = new OpenLayers.Control.SelectFeature(layer, {\n            highlightOnly: true,\n            hover: true\n        });\n        map.addControl(ctrl2);\n\n        ctrl2.activate();\n        ctrl1.activate();\n\n        feature = new OpenLayers.Feature.Vector();\n        feature.layer = layer;\n\n        // override the layer's getFeatureFromEvent func so that it always\n        // returns the feature referenced to by _feature\n        layer.getFeatureFromEvent = function(evt) { return _feature; };\n\n        evt = {xy: new OpenLayers.Pixel(Math.random(), Math.random())};\n\n        map.zoomToMaxExtent();\n\n        /*\n         * tests\n         */\n\n        // with renderIntent\n\n        ctrl1.renderIntent = \"select\";\n        ctrl2.renderIntent = \"temporary\";\n\n        // mouse over feature, feature is drawn with \"temporary\"\n        _feature = feature;\n        evt.type = \"mousemove\";\n        map.events.triggerEvent(\"mousemove\", evt);\n        t.eq(feature.renderIntent, \"temporary\",\n             \"feature drawn with expected render intent after \\\"mouseover\\\"\");\n\n        // click in feature, feature is drawn with \"select\"\n        _feature = feature;\n        evt.type = \"click\";\n        map.events.triggerEvent(\"click\", evt);\n        t.eq(feature.renderIntent, \"select\",\n             \"feature drawn with expected render intent after \\\"clickin\\\"\");\n\n        // mouse out of feature, feature is still drawn with \"select\"\n        _feature = null;\n        evt.type = \"mousemove\";\n        map.events.triggerEvent(\"mousemove\", evt);\n        t.eq(feature.renderIntent, \"select\",\n             \"feature drawn with expected render intent after \\\"mouseout\\\"\");\n\n        // mouse over feature again, feature is drawn with \"temporary\"\n        _feature = feature;\n        evt.type = \"mousemove\";\n        map.events.triggerEvent(\"mousemove\", evt);\n        t.eq(feature.renderIntent, \"temporary\",\n             \"feature drawn with expected render intent after \\\"mouseover\\\"\");\n\n        // click in feature again, feature is drawn with \"default\"\n        _feature = feature;\n        evt.type = \"click\";\n        map.events.triggerEvent(\"click\", evt);\n        t.eq(feature.renderIntent, \"default\",\n             \"feature drawn with expected render intent after \\\"clickin\\\"\");\n\n        // mouse out of feature again, feature is still drawn with \"default\"\n        _feature = null;\n        evt.type = \"mousemove\";\n        map.events.triggerEvent(\"mousemove\", evt);\n        t.eq(feature.renderIntent, \"default\",\n             \"feature drawn with expected render intent after \\\"mouseout\\\"\");\n\n        // mouse over feature again, feature is drawn with \"temporary\"\n        _feature = feature;\n        evt.type = \"mousemove\";\n        map.events.triggerEvent(\"mousemove\", evt);\n        t.eq(feature.renderIntent, \"temporary\",\n             \"feature drawn with expected render intent after \\\"mouseover\\\"\");\n\n        // mouse out of feature again, feature is still drawn with \"default\"\n        _feature = null;\n        evt.type = \"mousemove\";\n        map.events.triggerEvent(\"mousemove\", evt);\n        t.eq(feature.renderIntent, \"default\",\n             \"feature drawn with expected render intent after \\\"mouseout\\\"\");\n    }\n    \n    function test_setLayer(t) {\n        t.plan(5);\n        var map = new OpenLayers.Map(\"map\");\n        var layer1 = new OpenLayers.Layer.Vector();\n        var layer2 = new OpenLayers.Layer.Vector();\n        var layer3 = new OpenLayers.Layer.Vector();\n        map.addLayer(layer1, layer2, layer3);\n        // initialize it with a single layer\n        var control = new OpenLayers.Control.SelectFeature(layer1);\n        map.addControl(control);\n        control.activate();\n        control.setLayer([layer2, layer3]);\n        t.eq(control.layer instanceof OpenLayers.Layer.Vector.RootContainer, true, \"Root container created correctly on setLayer with multiple layers\");\n        t.eq(control.active, true, \"Control should be active still after using setLayer\");\n        t.eq((control.handlers.feature.layer === control.layer), true, \"Feature handler layer set correctly\");\n        control.destroy();\n        // initialize with an array of layers\n        control = new OpenLayers.Control.SelectFeature([layer1, layer2]);\n        t.eq((control.layers !== null), true, \"Control has a layers property\");\n        control.setLayer(layer3);\n        t.eq((control.layers === null), true, \"When using setLayer with a single layer, the layers property is removed if present before\");\n        map.destroy();\n    }\n\t\n    function test_setLayerWithRemoving(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var layer1 = new OpenLayers.Layer.Vector();\n        var layer2 = new OpenLayers.Layer.Vector();\n        map.addLayer(layer1, layer2);\n        // initialize it with a single layer\n        var control = new OpenLayers.Control.SelectFeature(layer1);\n        map.addControl(control);\n        control.activate();\n\t\tvar noError = null;\n\t\tmap.events.register(\"preremovelayer\", this, function(e) {\n\t\t\ttry {\n\t\t\t\tcontrol.setLayer(layer2);\n\t\t\t} catch (e) {\n\t\t\t\tnoError = e;\n\t\t\t}\n\t\t});\n\t\tlayer1.destroy();\n\t\tt.eq(layer2.id, control.layer.id, \"Layer is set correctly without error\");\n\t\tt.eq(noError, null,\"No error occured during setLayer. Error is: '\"+noError+\"'\");\n        control.destroy();\n        map.destroy();\n    }\n\n    function test_destroy(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map(\"map\");\n        var layer1 = new OpenLayers.Layer.Vector();\n        map.addLayer(layer1);\n        var control = new OpenLayers.Control.SelectFeature([layer1]);\n        map.addControl(control);\n        control.activate();\n        control.destroy();\n        t.eq(layer1.renderer.getRenderLayerId(), layer1.id, \n            \"Root container moved correctly when control is destroyed and layers was an array parameter\");\n    }   \n\n    function test_unselectAll(t) {\n        t.plan(2);\n\n        var layer = new OpenLayers.Layer.Vector();\n\n        var control = new OpenLayers.Control.SelectFeature(layer);\n\n        var feature1 = new OpenLayers.Feature.Vector();\n        feature1.id = 1;\n        var feature2 = new OpenLayers.Feature.Vector();\n        feature2.id = 2;\n        var feature3 = new OpenLayers.Feature.Vector();\n        feature3.id = 3;\n        var feature4 = new OpenLayers.Feature.Vector();\n        feature4.id = 4;\n\n        layer.addFeatures([feature1, feature2, feature3, feature4]);\n\n        control.select(feature1);\n        control.select(feature2);\n        control.select(feature3);\n        control.select(feature4);\n\n        layer.events.on({\n            featureunselected: function(e) {\n                // we change the selectedFeatures array while\n                // unselectAll is iterating over that array.\n                if(feature2.layer) {\n                    layer.removeFeatures([feature2]);\n                }\n            }\n        });\n\n        control.unselectAll({except: feature3});\n        t.eq(layer.selectedFeatures.length, 1,\n             'unselectAll unselected all but one');\n        t.eq(layer.selectedFeatures[0].id, 3,\n             'the remaining selected features is the one expected');\n    }\n    \n    function test_addLayer(t) {\n        t.plan(5);\n        \n        var layer = new OpenLayers.Layer.Vector();\n        var layers = [new OpenLayers.Layer.Vector(), new OpenLayers.Layer.Vector()]\n        var layerToAdd = new OpenLayers.Layer.Vector();\n        \n        var controlWithLayer = new OpenLayers.Control.SelectFeature(layer);\n        var controlWithLayers = new OpenLayers.Control.SelectFeature(layers);\n        \n        t.ok(controlWithLayer.layer instanceof OpenLayers.Layer.Vector, \"layer is an instance of OpenLayers.Layer.Vector\");\n        \n        controlWithLayer.addLayer(layerToAdd);\n        controlWithLayers.addLayer(layerToAdd);\n        \n        t.eq(controlWithLayer.layers.length, 2, \"the added layer is added and all layers are active\");\n        t.eq(controlWithLayers.layers.length, 3, \"the added layer is added and all layers are active\");\n\n        t.ok(controlWithLayer.layer instanceof OpenLayers.Layer.Vector.RootContainer, \"layer has changed from OpenLayers.Layer.Vector to OpenLayers.Layer.Vector.RootContainer\");\n        t.ok(controlWithLayers.layer instanceof OpenLayers.Layer.Vector.RootContainer, \"layer still a OpenLayers.Layer.Vector.RootContainer\");\n    }    \n   \n    </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 400px; height: 250px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/Snapping.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        \n        t.plan(5);\n        \n        // construct with a single layer\n        var layer = new OpenLayers.Layer.Vector();\n        var control = new OpenLayers.Control.Snapping({\n            layer: layer\n        });\n        \n        t.ok(control.layer === layer, \"[a] source layer properly set\");\n        t.eq(control.targets.length, 1, \"[a] one target layer\");\n        t.ok(control.targets[0].layer === layer, \"[a] target set\");\n        control.destroy();\n        \n        // construct with a different target, default target config\n        var layer2 = new OpenLayers.Layer.Vector();\n        control = new OpenLayers.Control.Snapping({\n            layer: layer,\n            targets: [layer2]\n        });\n        \n        t.eq(control.targets.length, 1, \"[b] one target layer\");\n        t.ok(control.targets[0].layer == layer2, \"[b] target set\");\n        control.destroy();\n    }\n    \n    function test_setLayer(t) {\n        \n        t.plan(4);\n        \n        var layer = new OpenLayers.Layer.Vector();\n        var control = new OpenLayers.Control.Snapping();\n        control.setLayer(layer);\n        \n        t.ok(control.layer === layer, \"layer properly set\");\n        \n        // confirm that the control is deactivated and reactivated when setting new layer\n        var log = {\n            activated: 0,\n            deactivated: 0\n        };\n        control.activate = function() {\n            log.activated++;\n        }\n        control.deactivate = function() {\n            log.deactivated++;\n        }\n        control.active = true;\n        \n        var layer2 = new OpenLayers.Layer.Vector();\n        control.setLayer(layer2);\n        \n        t.eq(log.deactivated, 1, \"control deactivated\");\n        t.ok(control.layer === layer2, \"layer properly reset\");\n        t.eq(log.activated, 1, \"control reactivated\");\n        \n        control.destroy();\n    }\n    \n    function test_setTargets(t) {\n        \n        t.plan(4);\n        \n        var layer1 = new OpenLayers.Layer.Vector();\n        var layer2 = new OpenLayers.Layer.Vector();\n        var control = new OpenLayers.Control.Snapping();\n        \n        var log = {\n            addTarget: [],\n            addTargetLayer: []\n        };\n        control.addTarget = function(target) {\n            log.addTarget.push(target);\n        };\n        control.addTargetLayer = function(target) {\n            log.addTargetLayer.push(target);\n        };\n\n        control.setTargets([layer1, {layer: layer2}]);\n        \n        t.eq(log.addTargetLayer.length, 1, \"setTargetLayer called once\");\n        t.ok(log.addTargetLayer[0] === layer1, \"setTargetLayer called with layer1\");\n        t.eq(log.addTarget.length, 1, \"setTarget called once\");\n        t.ok(log.addTarget[0].layer === layer2, \"setTarget called with layer2\");\n        \n        control.destroy();\n    }\n    \n    function test_addTarget(t) {\n        t.plan(5);\n        \n        var layer = new OpenLayers.Layer.Vector();\n\n        var control = new OpenLayers.Control.Snapping({\n            defaults: {\n                nodeTolerance: 30,\n                tolerance: 40\n            }\n        });\n        \n        var log = {};\n        control.addTarget({layer: layer});\n        \n        t.eq(control.targets.length, 1, \"single target\");\n        var target = control.targets[0];\n        t.ok(target.layer === layer, \"correct target layer\");\n        t.eq(target.nodeTolerance, 30, \"correct nodeTolerance\");\n        t.eq(target.edgeTolerance, 40, \"correct edgeTolerance\");\n        t.eq(target.vertexTolerance, 40, \"correct vertexTolerance\");\n        \n        control.destroy();\n    }\n    \n    function test_removeTargetLayer(t) {\n        \n        t.plan(3);\n        \n        var layer1 = new OpenLayers.Layer.Vector();\n        var layer2 = new OpenLayers.Layer.Vector();\n        var layer3 = new OpenLayers.Layer.Vector();\n        var control = new OpenLayers.Control.Snapping({\n            targets: [layer1, layer2, layer3]\n        });\n        \n        control.removeTargetLayer(layer2);\n        \n        t.eq(control.targets.length, 2, \"correct targets length\");\n        t.ok(control.targets[0].layer === layer1, \"layer1 remains\");\n        t.ok(control.targets[1].layer === layer3, \"layer3 remains\");\n        \n        control.destroy();\n        \n    }\n    \n    function test_activate(t) {\n        \n        t.plan(4);\n        var layer = new OpenLayers.Layer.Vector();\n        var control = new OpenLayers.Control.Snapping({\n            layer: layer\n        });\n        \n        control.activate();\n        \n        t.eq(layer.events.listeners.sketchmodified.length, 1, \"one sketchmodified listener\");\n        t.ok(layer.events.listeners.sketchmodified[0].func === control.onSketchModified, \"correct sketchmodified listener\");\n        t.eq(layer.events.listeners.vertexmodified.length, 1, \"one vertexmodified listener\");\n        t.ok(layer.events.listeners.vertexmodified[0].func === control.onVertexModified, \"correct vertexmodified listener\");\n        \n        control.destroy();\n    }\n    \n    function test_deactivate(t) {\n        \n        t.plan(2);\n        var layer = new OpenLayers.Layer.Vector();\n        var control = new OpenLayers.Control.Snapping({\n            layer: layer\n        });\n        \n        control.activate();\n        control.deactivate();\n        \n        t.eq(layer.events.listeners.sketchmodified.length, 0, \"no sketchmodified listeners\");\n        t.eq(layer.events.listeners.vertexmodified.length, 0, \"no vertexmodified listeners\");\n        \n        control.destroy();\n    }\n    \n    function test_resolution_limits(t) {\n        t.plan(7);\n\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1],\n            maxExtent: new OpenLayers.Bounds(0, 0, 100, 100)\n        });\n\n        var layer = new OpenLayers.Layer.Vector(null, {\n            isBaseLayer: true\n        });\n        layer.addFeatures([\n            new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(\n                \"POINT(50 50)\"\n            ))\n        ]);\n\n        map.addLayer(layer);\n        map.zoomToMaxExtent();        \n        \n        var control = new OpenLayers.Control.Snapping({layer: layer});\n        \n        var result;\n        var loc = new OpenLayers.Geometry.Point(49, 49);\n\n        // 1) test a target with no constraints\n        control.setTargets([{layer: layer}]);\n        result = control.testTarget(control.targets[0], loc);\n        t.ok(result !== null, \"1) target is eligible\");\n        \n        // 2) test a target with minResolution < map.resolution\n        control.setTargets([{layer: layer, minResolution: 0.5}]);\n        result = control.testTarget(control.targets[0], loc);\n        t.ok(result !== null, \"2) target is eligible\");\n\n        // 3) test a target with minResolution === map.resolution\n        control.setTargets([{layer: layer, minResolution: 1}]);\n        result = control.testTarget(control.targets[0], loc);\n        t.ok(result !== null, \"3) target is eligible\");\n\n        // 4) test a target with minResolution > map.resolution\n        control.setTargets([{layer: layer, minResolution: 1.5}]);\n        result = control.testTarget(control.targets[0], loc);\n        t.ok(result === null, \"4) target is not eligible\");\n\n        // 5) test a target with maxResolution < map.resolution\n        control.setTargets([{layer: layer, maxResolution: 0.5}]);\n        result = control.testTarget(control.targets[0], loc);\n        t.ok(result === null, \"5) target is not eligible\");\n        \n        // 6) test a target with maxResolution === map.resolution\n        control.setTargets([{layer: layer, maxResolution: 1}]);\n        result = control.testTarget(control.targets[0], loc);\n        t.ok(result === null, \"6) target is not eligible\");\n        \n        // 7) test a target with maxResolution > map.resolution\n        control.setTargets([{layer: layer, maxResolution: 1.5}]);\n        result = control.testTarget(control.targets[0], loc);\n        t.ok(result !== null, \"7) target is eligible\");\n        \n        map.destroy();\n    \n    }\n\n    function test_filter(t) {\n        t.plan(3);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1],\n            maxExtent: new OpenLayers.Bounds(0, 0, 100, 100)\n        });\n\n        var layer1 = new OpenLayers.Layer.Vector(null, {\n            isBaseLayer: true\n        });\n        var f1 = new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(\n            \"LINESTRING(0 0, 10 10, 20 20, 30 30)\"\n        ), {foo: 'bar'});\n        f1.fid = \"FID1\";\n        var f2 = new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(\n            \"LINESTRING(11 10, 20 10, 30 10)\"\n        ), {foo: 'bar'});\n        f2.fid = \"FID2\";\n        layer1.addFeatures([f1, f2]);\n        map.addLayers([layer1]);\n        map.zoomToMaxExtent();\n\n        var control = new OpenLayers.Control.Snapping({\n            layer: layer1,\n            targets: [layer1],\n            defaults: {tolerance: 4}\n        });\n        control.activate();\n\n        var result;\n        var loc = new OpenLayers.Geometry.Point(1, 1);\n\n        control.setTargets([{layer: layer1}]);\n        result = control.testTarget(control.targets[0], loc);\n        t.ok(result !== null, \"target is eligible without a filter set\");\n        var filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.NOT, \n            filters: [\n                new OpenLayers.Filter.FeatureId({fids: [\"FID1\", \"FID2\"]})\n            ]\n        });\n        control.setTargets([{layer: layer1, filter: filter}]);\n        result = control.testTarget(control.targets[0], loc);\n        t.ok(result === null, \"target is not eligible with a filter set which excludes the target's features\");\n        filter = new OpenLayers.Filter.Comparison({type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO, value: 'bar', property: 'foo'});\n        control.setTargets([{layer: layer1, filter: filter}]);\n        result = control.testTarget(control.targets[0], loc);\n        t.ok(result === null, \"target is not eligible with a filter set which excludes the target's features using a comparison filter\");\n    }\n    \n    function test_snapping(t) {\n        \n        t.plan(46);\n        \n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1],\n            maxExtent: new OpenLayers.Bounds(0, 0, 100, 100)\n        });\n        \n        var layer1 = new OpenLayers.Layer.Vector(null, {\n            isBaseLayer: true\n        });\n        layer1.addFeatures([\n            new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(\n                \"LINESTRING(0 0, 10 10, 20 20, 30 30)\"\n            )),\n            new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(\n                \"LINESTRING(11 10, 20 10, 30 10)\"\n            ))\n        ]);\n\n        var layer2 = new OpenLayers.Layer.Vector();\n        layer2.addFeatures([\n            new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(\n                \"LINESTRING(10 10, 20 20, 30 30)\"\n            )),\n            new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(\n                \"LINESTRING(21 10, 20 20, 20 30)\"\n            ))\n        ]);\n\n        map.addLayers([layer1, layer2]);\n        map.zoomToMaxExtent();        \n        \n        var control = new OpenLayers.Control.Snapping({\n            layer: layer1,\n            targets: [layer1, layer2],\n            defaults: {tolerance: 4}\n        });\n        control.activate();\n        map.addControl(control);\n        \n        // log beforesnap, snap, and unsnap events\n        var events = [];\n        function listener(event) {\n            events.push(event);\n        }\n        control.events.on({\n            beforesnap: listener,\n            snap: listener,\n            unsnap: listener\n        });\n        \n        // create a vertex and a convenience method for mocking the drag\n        var vertex = new OpenLayers.Geometry.Point(-100, -100);\n        function drag(x, y) {\n            var px = map.getPixelFromLonLat(new OpenLayers.LonLat(x, y));\n            layer1.events.triggerEvent(\"vertexmodified\", {\n                vertex: vertex, pixel: px\n            });\n        }\n\n        // mock up drag far from features\n        drag(-100, -100);\n        t.eq(events.length, 0, \"no snapping\");\n        \n        // mock up drag near first node of first feature\n        drag(0, 1);\n        t.eq(events.length, 2, \"[a] 2 events triggered\");\n        t.eq(events[0].type, \"beforesnap\", \"[a] beforesnap triggered\");\n        t.eq(events[0].snapType, \"node\", \"[a] beforesnap triggered for node\");\n        t.ok(events[0].point === vertex, \"[a] beforesnap triggered with vertex\");\n        t.eq(events[0].x, 0, \"[a] beforesnap triggered correct x\");\n        t.eq(events[0].y, 0, \"[a] beforesnap triggered with correct y\");\n        t.eq(events[1].type, \"snap\", \"[a] snap triggered\");\n        t.eq(events[1].snapType, \"node\", \"[a] snap triggered for node\");\n        t.ok(events[1].point === vertex, \"[a] snap triggered with point\");\n        t.eq(events[1].distance, 1, \"[a] snap triggered correct distance\");\n        t.ok(events[1].layer === layer1, \"[a] snap triggered with correct target layer\");\n        t.eq(vertex.x, 0, \"[a] vertex x modified\");\n        t.eq(vertex.y, 0, \"[a] vertex y modified\");\n        events = [];\n        \n        // mock up drag that unsnaps\n        drag(-100, -50);\n        t.eq(events.length, 1, \"[b] 1 event triggered\");\n        t.eq(events[0].type, \"unsnap\", \"[b] unsnap triggered\");\n        t.ok(events[0].point === vertex, \"[b] unsnap triggered with vertex\");\n        t.eq(vertex.x, -100, \"[b] vertex x unsnapped\");\n        t.eq(vertex.y, -50, \"[b] vertex y unsnapped\");\n        events = [];\n        \n        // drag near node of second feature in first layer to demonstrate precedence of node snapping\n        drag(9, 10);\n        t.eq(events.length, 2, \"[c] 2 events triggered\");\n        t.eq(events[0].type, \"beforesnap\", \"[c] beforesnap triggered first\");\n        t.eq(events[1].type, \"snap\", \"[c] snap triggered second\");\n        t.eq(events[1].snapType, \"node\", \"[c] snap to node\");\n        // unsnap & reset\n        drag(-100, -50);\n        events = [];\n        \n        // drag near node of second feature in second layer to demonstrate greedy property\n        // with greedy true (default) the best target from the first layer with eligible targets is used\n        drag(22, 10);\n        t.eq(events.length, 2, \"[d] 2 events triggered\");\n        t.eq(events[1].type, \"snap\", \"[d] snap triggered second\");\n        t.eq(events[1].snapType, \"vertex\", \"[d] snap to vertex\");\n        t.ok(events[1].layer === layer1, \"[d] snap to vertex in first layer\");\n        t.eq(vertex.x, 20, \"[d] vertex x modified\");\n        t.eq(vertex.y, 10, \"[d] vertex y modified\");\n        // unsnap & reset\n        drag(-100, -50);\n        events = [];\n        \n        // do the same drag but with greedy false - this will look for best target in all layers\n        control.greedy = false;\n        drag(22, 10);\n        t.eq(events.length, 2, \"[d] 2 events triggered\");\n        t.eq(events[1].type, \"snap\", \"[d] snap triggered second\");\n        t.eq(events[1].snapType, \"node\", \"[d] snap to node\");\n        t.ok(events[1].layer === layer2, \"[d] snap to node in second layer\");\n        // unsnap & reset        \n        drag(-100, -50);\n        control.greedy = true;\n        events = [];        \n        \n        // demonstrate snapping on sketchstarted\n        var p = new OpenLayers.Geometry.Point(0, 1);\n        layer1.events.triggerEvent(\"sketchstarted\", {\n            vertex: p,\n            feature: new OpenLayers.Feature.Vector(p)\n        });\n        t.eq(events.length, 2, \"[sketchstarted] 2 events triggered\");\n        t.eq(events[0].type, \"beforesnap\", \"[sketchstarted] beforesnap triggered\");\n        t.eq(events[0].snapType, \"node\", \"[sketchstarted] beforesnap triggered for node\");\n        t.ok(events[0].point === p, \"[sketchstarted] beforesnap triggered with vertex\");\n        t.eq(events[0].x, 0, \"[sketchstarted] beforesnap triggered correct x\");\n        t.eq(events[0].y, 0, \"[sketchstarted] beforesnap triggered with correct y\");\n        t.eq(events[1].type, \"snap\", \"[sketchstarted] snap triggered\");\n        t.eq(events[1].snapType, \"node\", \"[sketchstarted] snap triggered for node\");\n        t.ok(events[1].point === p, \"[sketchstarted] snap triggered with point\");\n        t.eq(events[1].distance, 1, \"[sketchstarted] snap triggered correct distance\");\n        t.ok(events[1].layer === layer1, \"[sketchstarted] snap triggered with correct target layer\");\n        t.eq(p.x, 0, \"[sketchstarted] vertex x modified\");\n        t.eq(p.y, 0, \"[sketchstarted] vertex y modified\");\n        // reset\n        events = [];        \n        \n        map.destroy();\n\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 100px; height: 100px;\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/Split.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        \n        t.plan(4);\n\n        var layer = new OpenLayers.Layer.Vector();\n        var control;\n        \n        // construct with nothing\n        control = new OpenLayers.Control.Split();\n        t.ok(control instanceof OpenLayers.Control, \"instanceof OpenLayers.Control\");\n        t.ok(control instanceof OpenLayers.Control, \"instanceof OpenLayers.Control.Split\")\n        control.destroy();\n        \n        // construct with a single target layer\n        control = new OpenLayers.Control.Split({\n            layer: layer\n        });        \n        t.ok(control.layer === layer, \"target layer properly set\");\n        control.destroy();\n        \n        // construct with same target and source\n        control = new OpenLayers.Control.Split({\n            layer: layer,\n            source: layer\n        });        \n        t.ok(control.source === layer, \"source layer properly set\");\n        control.destroy();\n    }\n    \n    function test_setSource(t) {\n        t.plan(5);\n        \n        var layer1 = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        var layer2 = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        \n        var control = new OpenLayers.Control.Split({layer: layer1});\n\n        var map = new OpenLayers.Map(\"map\");\n        map.addLayers([layer1, layer2]);\n        map.zoomToMaxExtent();\n        map.addControl(control);\n        control.activate();\n        \n        // confirm sketch hander created\n        t.ok(control.handler, \"sketch handler created\");\n        t.eq(control.handler.active, true, \"sketch handler active\");\n        \n        control.setSource(layer1);\n        t.ok(control.source === layer1, \"layer1 properly set\");\n        t.ok(!control.handler, \"no more sketch handler\");\n        \n        // activate and switch to new source layer\n        control.setSource(layer2);\n        t.ok(control.source === layer2, \"layer2 properly set\");\n        \n        map.destroy();\n        \n    }\n    \n    function test_activate(t) {\n        t.plan(8);\n        \n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        var control = new OpenLayers.Control.Split({layer: layer});\n        var map = new OpenLayers.Map(\"map\");\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        map.addControl(control);\n\n        // test activation with no source layer\n        control.activate();\n        t.eq(control.active, true, \"control is active\");\n        t.ok(control.handler instanceof OpenLayers.Handler.Path, \"line sketch handler created\");\n        t.ok(control.handler.callbacks.done, \"done callback set on sketch handler\");\n        t.eq(control.handler.active, true, \"sketch handler is active\");\n        \n        // change the source layer - this should call activate again\n        control.setSource(layer);\n        \n        t.eq(control.active, true, \"control is still active\");\n        t.ok(control.source === layer, \"source layer set\");\n        t.ok(layer.events.listeners.sketchcomplete, \"sketchcomplete listener registered\");\n        t.ok(layer.events.listeners.afterfeaturemodified, \"afterfeaturemodified listener registered\");\n        \n        map.destroy();\n        \n    }\n    \n    function test_deactivate(t) {\n        \n        t.plan(7);\n        \n        var layer1 = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        var layer2 = new OpenLayers.Layer.Vector(\"bar\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: false\n        });\n        var control = new OpenLayers.Control.Split({layer: layer1});\n        var map = new OpenLayers.Map(\"map\");\n        map.addLayer(layer1);\n        map.addLayer(layer2);\n        map.zoomToMaxExtent();\n        map.addControl(control);\n\n        // activate and check sketch handler\n        control.activate();\n        t.ok(control.handler, \"sketch handler present\");\n        t.eq(control.handler.active, true, \"sketch handler active\");\n        \n        // deactivate and check sketch handler\n        control.deactivate();\n        t.eq(control.handler.active, false, \"sketch handler deactivated\");\n        \n        // set a source layer\n        control.setSource(layer2);\n\n        // activate and check that listeners are registered\n        control.activate();\n        t.ok(layer2.events.listeners.sketchcomplete, \"sketchcomplete listener registered\");\n        t.ok(layer2.events.listeners.afterfeaturemodified, \"afterfeaturemodified listener registered\");\n\n        // deactivate and confirm no draw related events\n        control.deactivate();\n        t.eq(layer2.events.listeners.sketchcomplete.length, 0, \"no sketchcomplete listeners\");\n        t.eq(layer2.events.listeners.afterfeaturemodified.length, 0, \"no afterfeaturemodified listeners\");\n        \n        map.destroy();\n    }\n    \n    function test_isEligible(t) {\n        \n        t.plan(10);\n        \n        var control = new OpenLayers.Control.Split();\n        var geometry = OpenLayers.Geometry.fromWKT(\"LINESTRING(0 1, 1 2)\");\n        var feature = new OpenLayers.Feature.Vector(\n            geometry,\n            {foo: \"bar\"}\n        );\n        \n        t.eq(control.isEligible(feature), true, \"plain old feature is eligible\");\n        \n        feature.state = OpenLayers.State.DELETE;\n        t.eq(control.isEligible(feature), false, \"feature slated for deletion is not eligible\");\n        delete feature.state;\n        t.eq(control.isEligible(feature), true, \"feature with no state is eligible\");\n        \n        feature.geometry = new OpenLayers.Geometry.Point(1, 1);\n        t.eq(control.isEligible(feature), false, \"feature with point geometry is not eligible\");\n        feature.geometry = new OpenLayers.Geometry.MultiLineString([geometry]);\n        t.eq(control.isEligible(feature), true, \"feature with multilinestring geometry is eligible\");\n        \n        control.feature = feature;\n        t.eq(control.isEligible(feature), false, \"source feature is not eligible as target\");\n        control.feature = new OpenLayers.Feature.Vector();\n        t.eq(control.isEligible(feature), true, \"feature is eligible if different than source feature\");\n        \n        control.targetFilter = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,\n            property: \"foo\",\n            value: \"bar\"\n        });\n        t.eq(control.isEligible(feature), false, \"feature is not eligible unless it matches filter\");\n        control.targetFilter.value = \"baz\";\n        t.eq(control.isEligible(feature), true, \"feature is eligible if it matches filter\");\n        \n        delete feature.geometry;\n        t.eq(control.isEligible(feature), false, \"feature with no geometry is not eligible\");\n        \n        control.destroy();\n        \n    }\n    \n    function test_considerSplit(t) {\n\n        var layer = new OpenLayers.Layer.Vector();\n        \n        var wkt = OpenLayers.Geometry.fromWKT;\n        var geoms = {\n            abc: wkt(\"LINESTRING(0 0, 2 2)\"),\n            ab: wkt(\"LINESTRING(0 0, 1 1)\"),\n            bc: wkt(\"LINESTRING(1 1, 2 2)\"),\n            dbe: wkt(\"LINESTRING(2 0, 0 2)\"),\n            db: wkt(\"LINESTRING(2 0, 1 1)\"),\n            be: wkt(\"LINESTRING(1 1, 0 2)\")\n        };\n        \n        var Feature = OpenLayers.Feature.Vector;\n        var feats = {\n            abc: new Feature(geoms.abc),\n            ab: new Feature(geoms.ab),\n            bc: new Feature(geoms.bc),\n            dbe: new Feature(geoms.dbe),\n            db: new Feature(geoms.db),\n            be: new Feature(geoms.be)\n        };\n        \n        function feature(id, options) {\n            var f = OpenLayers.Util.extend(feats[id].clone(), options);\n            // for testing, we want to check when features are destroyed\n            f.destroy = function() {\n                f.state = \"destroyed\";\n            }\n            return f;\n        }\n        var DELETE = OpenLayers.State.DELETE;\n        var INSERT = OpenLayers.State.INSERT;\n        var UPDATE = OpenLayers.State.UPDATE;\n        \n        var cases = [{\n            targets: [\n                feature(\"abc\")\n            ],\n            source: feature(\"dbe\"),\n            splits: [{\n                original: feature(\"abc\", {state: \"destroyed\"}),\n                features: [feature(\"ab\", {state: INSERT}), feature(\"bc\", {state: INSERT})]\n            }, {\n                original: feature(\"dbe\", {state: \"destroyed\"}),\n                features: [feature(\"db\", {state: INSERT}), feature(\"be\", {state: INSERT})]\n            }]\n        }, {\n            options: {deferDelete: true},\n            targets: [\n                feature(\"abc\", {state: INSERT})\n            ],\n            source: feature(\"dbe\"),\n            splits: [{\n                original: feature(\"abc\", {state: \"destroyed\"}),\n                features: [feature(\"ab\", {state: INSERT}), feature(\"bc\", {state: INSERT})]\n            }, {\n                original: feature(\"dbe\", {state: DELETE}),\n                features: [feature(\"db\", {state: INSERT}), feature(\"be\", {state: INSERT})]\n            }]\n        }, {\n            options: {deferDelete: true},\n            targets: [\n                feature(\"abc\", {state: UPDATE})\n            ],\n            source: feature(\"dbe\", {state: INSERT}),\n            splits: [{\n                original: feature(\"abc\", {state: DELETE}),\n                features: [feature(\"ab\", {state: INSERT}), feature(\"bc\", {state: INSERT})]\n            }, {\n                original: feature(\"dbe\", {state: \"destroyed\"}),\n                features: [feature(\"db\", {state: INSERT}), feature(\"be\", {state: INSERT})]\n            }]\n        }];\n        \n        var count = 0;\n        var c, control, options, log, event, split;\n        for(var i=0; i<cases.length; ++i) {\n            c = cases[i];\n            ++count; // test number of splits\n            for(var j=0; j<c.splits.length; ++j) {\n                split = c.splits[j];\n                ++count; // test original state\n                ++count; // test original geometry\n                ++count; // test number of parts\n                for(var k=0; k<split.features.length; ++k) {\n                    ++count; // test part state\n                    ++count; // test part geometry\n                }\n            }\n        }\n        t.plan(count);\n\n        for(var i=0; i<cases.length; ++i) {\n            c = cases[i];\n            log = {events: []};\n            options = OpenLayers.Util.extend({layer: layer, source: layer}, c.options);\n            control = new OpenLayers.Control.Split(options);\n            control.events.on({\n                split: function(e) {\n                    log.events.push(e);\n                }\n            });\n            layer.features = c.targets;\n            control.considerSplit(c.source);\n            t.eq(log.events.length, c.splits.length, \"case \" + i + \": correct number of split events\");\n            for(var j=0; j<log.events.length; ++j) {\n                event = log.events[j];\n                split = c.splits[j];\n                t.eq(event.original.state, split.original.state, \"case \" + i + \" split \" + j + \": correct original state\");\n                t.geom_eq(event.original.geometry, split.original.geometry, \"case \" + i + \" split \" + j + \": correct original geometry\");\n                t.eq(event.features.length, split.features.length, \"case \" + i + \" split \" + j + \": correct number of parts\");\n                for(var k=0; k<split.features.length; ++k) {\n                    t.eq(event.features[k].state, split.features[k].state, \"case \" + i + \" split \" + j + \" feature \" + k + \": correct state\");\n                    t.geom_eq(event.features[k].geometry, split.features[k].geometry, \"case \" + i + \" split \" + j + \" feature \" + k + \": correct geometry\");\n                }\n            }\n            control.destroy();\n        }\n        \n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 100px; height: 100px;\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/TextButtonPanel.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    function test_Control_TextButtonpanelPanel_constructor (t) {\n        t.plan( 2 );\n    \n        control = new OpenLayers.Control.TextButtonPanel();\n        t.ok( control instanceof OpenLayers.Control.TextButtonPanel, \"new OpenLayers.Control.TextButtonPanel returns object\" );\n        t.eq( control.displayClass,  \"olControlTextButtonPanel\", \"displayClass is correct\" );\n    }\n    \n    function test_Control_TextButtonPanel_setOrientationClass (t) {\n        t.plan( 2 );\n        var b1 = new OpenLayers.Control.Button({\n            trigger: function() {  },\n        });\n        var panel = new OpenLayers.Control.TextButtonPanel({\n            vertical: true,\n        });\n        panel.addControls( [ b1 ] );\n        var map = new OpenLayers.Map( 'map', {} );\n        map.addControl(panel);\n        t.ok( OpenLayers.Element.hasClass(panel.div, \"vertical\"),\n            \"'vertical' class set from 'vertical' option\" );\n        panel.vertical = false;\n        panel.setOrientationClass();\n        t.ok( !OpenLayers.Element.hasClass(panel.div, \"vertical\"),\n            \"'vertical' class properly removed by setOrientationClass\");\n        map.destroy();\n    }\n    \n    function test_Control_TextButtonPanel_setAdditionalClass (t) {\n        t.plan( 1 );\n        var b1 = new OpenLayers.Control.Button({\n            trigger: function() {  },\n        });\n        var panel = new OpenLayers.Control.TextButtonPanel({\n            additionalClass: \"panel2\",\n        });\n        panel.addControls( [ b1 ] );\n        var map = new OpenLayers.Map( 'map', {} );\n        map.addControl(panel);\n        t.ok( OpenLayers.Element.hasClass(panel.div, \"panel2\"),\n            \"class set from 'additionalClass' option\" );\n        map.destroy();\n    }\n    \n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/TouchNavigation.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_Control_TouchNavigation_constructor (t) {\n        t.plan( 2 );\n        var options = {bar: \"foo\"};\n        var temp = OpenLayers.Control.prototype.initialize;\n        OpenLayers.Control.prototype.initialize = function(opt) {\n            t.eq(opt, options,\n                 \"constructor calls parent with the correct options\");\n        };\n\n        var control = new OpenLayers.Control.TouchNavigation(options);\n        t.ok(control instanceof OpenLayers.Control.TouchNavigation,\n            \"new OpenLayers.Control returns object\");\n\n        OpenLayers.Control.prototype.initialize = temp;\n    }\n\n    function test_Control_TouchNavigation_destroy(t) {\n        t.plan(6);\n\n        var control = {\n            events: {\n                destroy: function() {\n                    t.ok(true, \"events destroyed\");\n                }\n            },\n            deactivate: function() {\n                t.ok(true, \"navigation control deactivated before being destroyed\");\n            },\n            dragPan: {\n                destroy: function() {\n                    t.ok(true, \"dragPan destroyed\");\n                }\n            },\n            handlers: {\n                click: {\n                    destroy: function() {\n                        t.ok(true, \"clickHandler destroyed\");\n                    }\n                }\n            }\n        };\n\n        //this will also trigger one test by calling OpenLayers.Control's destroy\n        // and three more for the destruction of dragPan, zoomBox, and wheelHandler\n        OpenLayers.Control.TouchNavigation.prototype.destroy.apply(control, []);\n\n        t.eq(control.dragPan, null, \"'dragPan' set to null\");\n        t.eq(control.handlers, null, \"handlers set to null\");\n    }\n\n    function test_documentDrag(t) {\n\n        t.plan(2);\n\n        /**\n         * These tests confirm that the documentDrag property is false by\n         * default and is passed on to the DragPan control.  Tests of panning\n         * while dragging outside the viewport should go in the DragPan tests.\n         * Tests of the document events and appropriate callbacks from the\n         * handler should go in the Drag handler tests.\n         */\n\n         var nav = new OpenLayers.Control.TouchNavigation();\n         t.eq(nav.documentDrag, false, \"documentDrag false by default\");\n\n         var map = new OpenLayers.Map({\n             div: document.body,\n             controls: [new OpenLayers.Control.TouchNavigation({documentDrag: true})]\n         });\n         nav = map.controls[0];\n\n         t.eq(nav.dragPan.documentDrag, true, \"documentDrag set on the DragPan control\");\n         map.destroy();\n\n    }\n\n    function test_dragPanOptions(t) {\n\n        t.plan(2);\n\n         var nav = new OpenLayers.Control.TouchNavigation();\n         t.eq(nav.dragPanOptions, null, \"dragPanOptions null by default\");\n\n         var map = new OpenLayers.Map({\n             div: document.body,\n             controls: [\n                 new OpenLayers.Control.TouchNavigation({\n                     dragPanOptions: {foo: 'bar'}\n                 })\n             ]\n         });\n         nav = map.controls[0];\n\n         t.eq(nav.dragPan.foo, 'bar',\n            \"foo property is set on the DragPan control\");\n         map.destroy();\n\n    }\n\n    function test_clickHandlerOptions(t) {\n\n        t.plan(3);\n\n         var nav = new OpenLayers.Control.TouchNavigation();\n         t.eq(nav.clickHandlerOptions, null, \"clickHandlerOptions null by default\");\n\n         var map = new OpenLayers.Map({\n             div: document.body,\n             controls: [\n                 new OpenLayers.Control.TouchNavigation({\n                     clickHandlerOptions: {foo: \"bar\"}\n                 })\n             ]\n         });\n         nav = map.controls[0];\n\n         t.eq(nav.handlers.click.foo, \"bar\", \"foo property is set on the click handler\");\n         t.eq(nav.handlers.click.pixelTolerance, 2, \"pixelTolerance is 2 by default\");\n         map.destroy();\n\n    }\n\n    function test_zoomOut(t) {\n        t.plan(1);\n\n        var map = new OpenLayers.Map('map', {zoomMethod: null});\n        var layer = new OpenLayers.Layer.WMS( \"OpenLayers WMS\",\n                    \"http://labs.metacarta.com/wms/vmap0\",\n                    {layers: 'basic'} );\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 5);\n        var origSetTimeout = window.setTimeout;\n        window.setTimeout = function(fn) { fn(); return 'id'; };\n        var control = new OpenLayers.Control.TouchNavigation();\n        map.addControl(control);\n        var handler = control.handlers.click;\n        handler.touchstart({xy: new OpenLayers.Pixel(1 ,1), touches: [\"foo\", \"bar\"]});\n        handler.touchend({});\n        t.eq(map.getZoom(), 4, \"Did we zoom out?\");\n        // tear down\n        map.destroy();\n        window.setTimeout = origSetTimeout;\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width:512px;height:256px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/TransformFeature.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(6);\n        var layer = \"foo\";\n        var control = new OpenLayers.Control.TransformFeature(layer);\n        \n        t.ok(control.layer == layer,\n             \"constructor sets layer correctly\");\n        t.ok(control.dragControl instanceof OpenLayers.Control.DragFeature,\n             \"constructor sets the drag control correctly\");\n        t.ok(control.box instanceof OpenLayers.Feature.Vector,\n             \"box feature created\");\n        t.eq(control.handles.length, 8, \"8 handles created\");\n        t.eq(control.rotationHandles.length, 4, \"4 rotation handles created\")\n        t.eq(typeof control.rotationHandleSymbolizer, \"object\",\n            \"rotationHandleSymbolizer initialized\");\n        control.destroy();\n    }\n\n    function test_destroy(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.TransformFeature(layer);\n        control.dragControl.destroy = function() {\n            t.ok(true,\n                 \"control.destroy calls destroy on drag control\");\n        };\n        control.destroy();\n        map.destroy();\n    }\n    \n    function test_activate(t) {\n        t.plan(3);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.TransformFeature(layer);\n        map.addControl(control);\n        \n        t.ok(!control.dragControl.active,\n             \"drag control is not active prior to activating control\");\n        control.activate();\n        t.ok(control.dragControl.active,\n             \"drag control is active after activating control\");\n        t.ok(control.box.layer === layer, \"box added to layer\");\n\n        map.destroy();\n    }\n    \n    function test_setFeature(t) {\n        t.plan(6);\n        var map = new OpenLayers.Map(\"map\", {allOverlays: true});\n        var layer = new OpenLayers.Layer.Vector();\n        var feature = new OpenLayers.Feature.Vector(\n            OpenLayers.Geometry.fromWKT(\"POLYGON((-1 -1, 1 -1, 1 1, -1 1))\"));\n        layer.addFeatures([feature]);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 18);\n        var control = new OpenLayers.Control.TransformFeature(layer);\n        map.addControl(control);\n        var log = [];\n        control.events.on({\n            \"beforesetfeature\": function(e) { log.push(e); },\n            \"setfeature\": function(e) { log.push(e); }\n        });\n        control.setFeature(feature);\n        \n        t.eq(log[0].type, \"beforesetfeature\", \"beforesetfeature event fired with correct event type\");\n        t.eq(log[1].type, \"setfeature\", \"setfeature event fired with correct event type\");\n        \n        t.ok(control.active, \"control activated on setFeature\");\n        t.ok(feature.geometry.getBounds().equals(control.box.geometry.getBounds()), \"box positioned correctly\");\n        t.geom_eq(control.handles[0].geometry, control.box.geometry.components[0], \"handle positioned with box\");\n        \n        var center = new OpenLayers.LonLat(1, 1);\n        control.box.move(center);\n        t.geom_eq(control.handles[0].geometry, control.box.geometry.components[0], \"handle moved with box\");\n    }\n    \n    function test_handleMove(t) {\n        t.plan(16);\n        var map = new OpenLayers.Map(\"map\", {allOverlays: true});\n        var layer = new OpenLayers.Layer.Vector();\n        var feature = new OpenLayers.Feature.Vector(\n            OpenLayers.Geometry.fromWKT(\"POLYGON((-1 -1, 1 -1, 1 1, -1 1))\"));\n        layer.addFeatures([feature]);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 18);\n        var control = new OpenLayers.Control.TransformFeature(layer);\n        map.addControl(control);\n        control.setFeature(feature);\n        \n        var bottomLeft = new OpenLayers.LonLat(-2, -2);\n        control.handles[0].move(bottomLeft);\n        t.geom_eq(control.handles[0].geometry, new OpenLayers.Geometry.Point(-2, -2), \"bottom left handle at -2,-2\");\n        t.geom_eq(control.handles[1].geometry, new OpenLayers.Geometry.Point(0, -2), \"bottom handle at 0,-2\");\n        t.geom_eq(control.handles[2].geometry, new OpenLayers.Geometry.Point(2, -2), \"bottom right handle at 2,-2\");\n        t.geom_eq(control.handles[3].geometry, new OpenLayers.Geometry.Point(2, 0), \"right handle at 2,0\");\n        t.geom_eq(control.handles[4].geometry, new OpenLayers.Geometry.Point(2, 2), \"top right handle at 2,2\");\n        t.geom_eq(control.handles[5].geometry, new OpenLayers.Geometry.Point(0, 2), \"top handle at 0,2\");\n        t.geom_eq(control.handles[6].geometry, new OpenLayers.Geometry.Point(-2, 2), \"top left handle at -2,2\");\n        t.geom_eq(control.handles[7].geometry, new OpenLayers.Geometry.Point(-2, 0), \"left handle at -2,0\");\n        \n        control.irregular = true;\n        \n        var bottomLeft = new OpenLayers.LonLat(-3, -3);\n        control.handles[0].move(bottomLeft);\n        t.geom_eq(control.handles[0].geometry, new OpenLayers.Geometry.Point(-3, -3), \"bottom left handle at -3,-3\");\n        t.geom_eq(control.handles[1].geometry, new OpenLayers.Geometry.Point(-0.5, -3), \"bottom handle at 0,-3\");\n        t.geom_eq(control.handles[2].geometry, new OpenLayers.Geometry.Point(2, -3), \"bottom right handle at 2,-3\");\n        t.geom_eq(control.handles[3].geometry, new OpenLayers.Geometry.Point(2, -0.5), \"right handle at 2,0\");\n        t.geom_eq(control.handles[4].geometry, new OpenLayers.Geometry.Point(2, 2), \"top right handle at 2,2\");\n        t.geom_eq(control.handles[5].geometry, new OpenLayers.Geometry.Point(-0.5, 2), \"top handle at 0,2\");\n        t.geom_eq(control.handles[6].geometry, new OpenLayers.Geometry.Point(-3, 2), \"top left handle at -3,2\");\n        t.geom_eq(control.handles[7].geometry, new OpenLayers.Geometry.Point(-3, -0.5), \"left handle at -3,0\");\n    }\n\n    </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 400px; height: 250px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/UTFGrid.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n  <script>\n      /**\n      * Because browsers that implement requestAnimationFrame may not execute\n      * animation functions while a window is not displayed (e.g. in a hidden\n      * iframe as in these tests), we mask the native implementations here.  The\n      * native requestAnimationFrame functionality is tested in Util.html and\n      * in PanZoom.html (where a popup is opened before panning).  The panTo tests\n      * here will test the fallback setTimeout implementation for animation.\n      */\n      window.requestAnimationFrame = \n          window.webkitRequestAnimationFrame =\n          window.mozRequestAnimationFrame =\n          window.oRequestAnimationFrame =\n          window.msRequestAnimationFrame = null;\n  </script>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    var map, layer, control;\n    var log;\n    function setUp() {\n        layer = new OpenLayers.Layer.UTFGrid({\n            url: \"../data/utfgrid/world_utfgrid/${z}/${x}/${y}.json\",\n            isBaseLayer: true, \n            utfgridResolution: 4\n        });\n        map = new OpenLayers.Map({\n            div: \"map\",\n            tileManager: null,\n            projection: \"EPSG:900913\",\n            layers: [layer],\n            center: [0, 0],\n            zoom: 1\n        });\n        log = [];\n        control = new OpenLayers.Control.UTFGrid({\n            callback: function(infoLookup, loc, pixel) {\n                log.push([infoLookup, loc, pixel]);\n            }\n        });\n        map.addControl(control);\n    }\n    \n    function tearDown() {\n        map.destroy();\n        map = null;\n        layer = null;\n        control = null;\n        log = [];\n    }\n\n    function test_constructor(t) {\n        t.plan(2);\n        \n        var control = new OpenLayers.Control.UTFGrid();\n        t.ok(control instanceof OpenLayers.Control.UTFGrid, \"utfgrid instance\");\n        t.eq(control.handlerMode, \"click\", \"control mode\");\n\n        control.destroy();\n\n    }\n    \n    function test_handleEvent(t) {\n        setUp();\n        \n        var cases = [{\n            evt: {xy: {x: 100, y: 70}},\n            lookup: {\n                \"0\": {\n                    id: \"207\",\n                    data: {\n                        NAME: \"United States\",\n                        POP2005: 299846449\n                    }\n                }\n            }\n        }, {\n            evt: {xy: {x: 350, y: 20}},\n            lookup: {\n                \"0\": {\n                    id: \"245\",\n                    data: {\n                        NAME: \"Russia\",\n                        POP2005: 143953092\n                    }\n                }\n            }\n        }];\n        \n        var len = cases.length;\n        t.plan(4*len);\n                \n        // wait for tile loading to finish\n        t.delay_call(0.5, function() {\n            var c, arg;\n            for (var i=0; i<len; ++i) {\n                c = cases[i];\n                t.eq(log.length, i, i + \": log length before\");\n                control.handleEvent(c.evt);\n                t.eq(log.length, i+1, i + \": log length after\");\n                t.eq(log[i][0], c.lookup, i + \": callback infoLookup\");\n                t.eq(log[i][2], c.evt.xy, i + \": callback pixel\");\n            }\n            \n            tearDown();\n        });\n        \n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"height: 256px; width: 512px\"></div>\n</body>\n</html>\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/WMSGetFeatureInfo.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(5);\n\n        var options = {\n            url: 'http://localhost/wms',\n            layers: [\"foo\"],\n            formatOptions: {\n                foo: \"bar\"\n            }\n        };\n        var control = new OpenLayers.Control.WMSGetFeatureInfo(options);\n        t.ok(control instanceof OpenLayers.Control.WMSGetFeatureInfo,\n             \"new OpenLayers.Control.WMSGetFeatureInfo returns an instance\");\n        t.eq(control.url, 'http://localhost/wms',\n             \"constructor sets url correctly\");\n        t.eq(control.layers, [\"foo\"],\n             \"constructor layers\"\n            );\n        t.ok(control.format instanceof OpenLayers.Format.WMSGetFeatureInfo, \"format created\");\n        t.eq(control.format.foo, \"bar\", \"format options used\")\n    }\n\n    function test_clickCallBack_option(t) {\n        t.plan(9);\n\n        var control;\n\n        control = new OpenLayers.Control.WMSGetFeatureInfo({\n            hover: true\n        });\n        t.ok(control.handler instanceof OpenLayers.Handler.Hover,\n             'constructor creates hover handler');\n        t.ok(control.handler.callbacks[\"move\"] === control.cancelHover,\n             'constructor registers proper \"move\" callback in handler');\n        t.ok(control.handler.callbacks[\"pause\"] === control.getInfoForHover,\n             'constructor registers proper \"pause\" callback in handler');\n\n        control = new OpenLayers.Control.WMSGetFeatureInfo();\n        t.ok(control.handler instanceof OpenLayers.Handler.Click,\n             'constructor creates click handler');\n        t.ok(control.handler.callbacks[\"click\"] === control.getInfoForClick,\n             'constructor registers proper \"click\" callback in handler');\n\n        control = new OpenLayers.Control.WMSGetFeatureInfo({\n            clickCallback: \"rightclick\"\n        });\n        t.ok(control.handler.callbacks[\"rightclick\"] === control.getInfoForClick,\n             'constructor registers proper \"rightclick\" callback in handler');\n\n        control = new OpenLayers.Control.WMSGetFeatureInfo({\n            clickCallback: \"dblclick\",\n            handlerOptions: {\n                click: {\n                    \"single\": false,\n                    \"double\": true\n                }\n            }\n        });\n        t.ok(control.handler.callbacks[\"dblclick\"] === control.getInfoForClick,\n             'constructor registers proper \"dblclick\" callback in handler');\n        t.eq(control.handler[\"single\"], false,\n             'constructor sets \"single\" to false in handler');\n        t.eq(control.handler[\"double\"], true,\n             'constructor sets \"double\" to true in handler');\n     }\n\n    function test_destroy(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var click = new OpenLayers.Control.WMSGetFeatureInfo({\n            url: 'http://localhost/wms',\n            layers: [\"foo\"]\n        });\n\n        var hover = new OpenLayers.Control.WMSGetFeatureInfo({\n            url: 'http://localhost/wms',\n            layers: [\"foo\"],\n            hover: true\n        });\n\n        click.handler.deactivate = function() {\n            t.ok(true,\n                 \"control.deactivate calls deactivate on click handler\");\n        };\n        hover.handler.deactivate = function() {\n            t.ok(true,\n                 \"control.deactivate calls deactivate on hover handler\");\n        };\n        click.destroy();\n        hover.destroy();\n    }\n\n    function test_click(t) {\n        t.plan(4);\n        var map = new OpenLayers.Map('map');\n\n        // mock up active control\n        var control = new OpenLayers.Control.WMSGetFeatureInfo();\n        map.addControl(control);\n        control.activate();\n\n        control.request = function(position) {\n            t.eq(position.x, 50,\n                 \"x position is as expected\");\n            t.eq(position.y, 50,\n                 \"y position is as expected\");\n        };\n\n        control.getInfoForClick({xy: {x: 50, y: 50}});\n        control.getInfoForHover({xy: {x: 50, y: 50}});\n    }\n\n    function test_getfeatureinfo_event(t) {\n\n        t.plan(5);\n\n        var text =\n            '<?xml version=\"1.0\" encoding=\"UTF-8\" ?>' +\n            '<FeatureInfoResponse>' +\n            '  <FIELDS OBJECTID=\"1188\" HECTARES=\"1819.734\" ZONENR=\"5854\" NULZONES=\" \" AREA=\"18197340.1426\" PERIMETER=\"19177.4073627\" SHAPE=\"NULL\" SE_ANNO_CAD_DATA=\"NULL\" SHAPE.AREA=\"0\" SHAPE.LEN=\"0\"/>' +\n            '</FeatureInfoResponse>';\n\n        var map = new OpenLayers.Map('map');\n\n        var xy;\n        var url = \"http://foo\";\n\n        // mock up a control with output \"object\" and drillDown true\n        var control = new OpenLayers.Control.WMSGetFeatureInfo({\n            output: \"object\",\n            drillDown: true,\n            request: function(position) {},\n            eventListeners: {\n                getfeatureinfo: function(evt) {\n                    t.ok(evt.features[0].url === url, \"features is an object with a property url when output is object\");\n                    var features = evt.features[0].features;\n                    t.ok(features.length === 1, \"features properties has a length of 1\");\n                    t.ok(features[0] instanceof OpenLayers.Feature.Vector, \"Feature array contains 1 feature\");\n                }\n            }\n        });\n\n        // mock up a control with output \"features\" and drillDown true\n        var control2 = new OpenLayers.Control.WMSGetFeatureInfo({\n            autoActivate: true,\n            drillDown: true,\n            request: function(position) {},\n            eventListeners: {\n                getfeatureinfo: function(evt) {\n                    var features = evt.features;\n                    t.ok(features.length === 1, \"features properties has a length of 1\");\n                    t.ok(features[0] instanceof OpenLayers.Feature.Vector, \"Feature array contains 1 feature\");\n                }\n            }\n        });\n\n        map.addControls([control, control2]);\n        control.activate();\n\n        xy = {x: 50, y: 50};\n        control._requestCount = control2._requestCount = 0;\n        control._numRequests = control2._numRequests = 1;\n        control.handleResponse({xy: xy}, {responseText: text}, url);\n        control2.handleResponse({xy: xy}, {responseText: text}, url);\n        map.destroy();\n    }\n\n    function test_beforegetfeatureinfo_event(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map('map');\n\n        var xy, mode;\n\n        // mock up active control\n        var control = new OpenLayers.Control.WMSGetFeatureInfo({\n            request: function(position) {},\n            eventListeners: {\n                beforegetfeatureinfo: function(evt) {\n                    t.eq(evt.xy, xy,\n                         \"beforegetfeatureinfo listener gets \" +\n                         \"expected xy (\" + mode + \")\");\n                }\n            }\n        });\n        map.addControl(control);\n        control.activate();\n\n        // 1 test\n        mode = \"click\";\n        xy = {x: 50, y: 50};\n        control.getInfoForClick({xy: xy});\n\n        // 1 test\n        mode = \"hover\";\n        xy = {x: 70, y: 70};\n        control.getInfoForHover({xy: xy});\n    }\n\n    function test_nogetfeatureinfo_event(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map('map');\n        // mock up active control\n        var control = new OpenLayers.Control.WMSGetFeatureInfo({\n            eventListeners: {\n                nogetfeatureinfo: function(evt) {\n                    t.ok((evt.type == \"nogetfeatureinfo\"), \"nogetfeatureinfo listener gets called when there are no queryable layers\");\n                }\n            }\n        });\n        map.addControl(control);\n        control.activate();\n\n        // 1 test\n        mode = \"click\";\n        xy = {x: 50, y: 50};\n        control.getInfoForClick({xy: xy});\n    }\n\n    function test_activate(t) {\n        t.plan(4);\n        var map = new OpenLayers.Map(\"map\");\n        var click = new OpenLayers.Control.WMSGetFeatureInfo({\n            url: 'http://localhost/wms',\n            featureType: 'type',\n            featureNS: 'http://localhost/ns',\n            layers: 'ns:type'\n        });\n        var hover = new OpenLayers.Control.WMSGetFeatureInfo({\n            url: 'http://localhost/wms',\n            featureType: 'type',\n            featureNS: 'http://localhost/ns',\n            layers: 'ns:type',\n            hover: true\n        });\n        map.addControl(click);\n        map.addControl(hover);\n        t.ok(!click.handler.active,\n             \"click handler is not active prior to activating control\");\n        t.ok(!hover.handler.active,\n             \"hover handler is not active prior to activating control\");\n        click.activate();\n        hover.activate();\n        t.ok(click.handler.active,\n             \"click handler is active after activating control\");\n        t.ok(hover.handler.active,\n             \"hover handler is active after activating control\");\n    }\n\n    function test_deactivate(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var click = new OpenLayers.Control.WMSGetFeatureInfo({\n            url: 'http://localhost/wms',\n            featureType: 'type',\n            featureNS: 'http://localhost/ns',\n            layers: 'ns:type'\n        });\n        var hover = new OpenLayers.Control.WMSGetFeatureInfo({\n            url: 'http://localhost/wms',\n            featureType: 'type',\n            featureNS: 'http://localhost/ns',\n            layers: 'ns:type'\n        });\n        map.addControl(click);\n        map.addControl(hover);\n        click.activate();\n        hover.activate();\n\n        click.handler.deactivate = function() {\n            t.ok(true,\n                 \"control.deactivate calls deactivate on click handler\");\n            OpenLayers.Handler.Click.prototype.deactivate.apply(this, arguments);\n        };\n        hover.handler.deactivate = function() {\n            t.ok(true,\n                 \"control.deactivate calls deactivate on hover handler\");\n            OpenLayers.Handler.Hover.prototype.deactivate.apply(this, arguments);\n        };\n        click.deactivate();\n        hover.deactivate();\n    }\n\n    // Verify that things work all right when we combine different types for the STYLES and LAYERS\n    // params in the WMS Layers involved\n    function test_mixedParams(t) {\n        t.plan(5);\n        var map = new OpenLayers.Map(\"map\", {\n            getExtent: function() {return(new OpenLayers.Bounds(-180,-90,180,90));}\n        });\n        var geographic = new OpenLayers.Projection(\"EPSG:4326\");\n\n        var a = new OpenLayers.Layer.WMS(\"dummy\",\"http://localhost/wms\", {\n            layers: \"a,b,c,d\",\n            styles: \"a,b,c,d\"\n        }, {projection: geographic});\n\n        var b = new OpenLayers.Layer.WMS(\"dummy\",\"http://localhost/wms\", {\n            layers: [\"a\",\"b\",\"c\",\"d\"],\n            styles: [\"a\",\"b\",\"c\",\"d\"]\n        }, {projection: geographic});\n\n        var c = new OpenLayers.Layer.WMS(\"dummy\",\"http://localhost/wms\", {\n            layers: [\"a\",\"b\",\"c\",\"d\"]\n        });\n\n        var d = new OpenLayers.Layer.WMS(\"dummy\",\"http://localhost/wms\", {\n            layers: \"a,b,c,d\"\n        }, {projection: geographic});\n\n        var click = new OpenLayers.Control.WMSGetFeatureInfo({\n            featureType: 'type',\n            featureNS: 'ns',\n            layers: [a, b, c, d]\n        }, {projection: geographic});\n\n        map.addControl(click);\n\n        var log = {};\n        var _request = OpenLayers.Request.GET;\n        OpenLayers.Request.GET = function(options) {\n            log.options = options;\n        };\n        click.activate();\n        click.getInfoForClick({xy: {x: 50.2, y: 50.1}});\n        OpenLayers.Request.GET = _request;\n\n        t.eq(\n            log.options && log.options.params.X,\n            50,\n            \"X should be an integer\"\n        );\n\n        t.eq(\n            log.options && log.options.params.Y,\n            50,\n            \"Y should be an integer\" \n        );\n\n        t.eq(\n            log.options && log.options.url,\n            \"http://localhost/wms\",\n            \"url from first layer used\"\n        );\n        t.eq(\n            log.options && log.options.params.STYLES.join(\",\"),\n            \",,,,,,,,a,b,c,d,a,b,c,d\",\n            \"Styles merged correctly\"\n        );\n\n        t.eq(\n            log.options && log.options.params.FORMAT,\n            \"image/jpeg\",\n            \"Required 'format' parameter included\"\n \t    );\n\n    }\n\n    function test_urlMatches(t) {\n\n        t.plan(5);\n\n        var control = new OpenLayers.Control.WMSGetFeatureInfo({\n            url: \"http://host/wms?one=1&two=2\"\n        });\n\n        t.ok(!control.urlMatches(\"foo\"), \"doesn't match garbage\");\n        t.ok(control.urlMatches(\"http://host:80/wms?two=2&one=1\"), \"matches equivalent url\");\n\n        // give the control more urls to match from\n        control.layerUrls = [\"http://a.host/wms\", \"http://b.host/wms\"];\n\n        t.ok(control.urlMatches(\"http://host:80/wms?two=2&one=1\"), \"still matches equivalent url\");\n        t.ok(control.urlMatches(\"http://a.host:80/wms\"), \"matches equivalent of first of layerUrls\");\n        t.ok(control.urlMatches(\"http://b.host:80/wms\"), \"matches equivalent of second of layerUrls\");\n\n    }\n\n    function test_layerUrls(t) {\n\n        t.plan(4);\n        var map = new OpenLayers.Map({\n            div: \"map\",\n            getExtent: function() {\n                return new OpenLayers.Bounds(-180,-90,180,90);\n            }\n        });\n\n        var a = new OpenLayers.Layer.WMS(\n            null, \"http://a.mirror/wms\", {layers: \"a\"}\n        );\n        var b = new OpenLayers.Layer.WMS(\n            null, \"http://b.mirror/wms\", {layers: \"b\"}\n        );\n        var c = new OpenLayers.Layer.WMS(\n            null, [\"http://c.mirror/wms\", \"http://d.mirror/wms\"], {layers: \"c\"}\n        );\n        map.addLayers([a, b, c]);\n\n        var control = new OpenLayers.Control.WMSGetFeatureInfo({\n            url: \"http://host/wms\",\n            layers: [a, b, c]\n        });\n        map.addControl(control);\n        control.activate();\n\n        // log calls to GET\n        var log;\n        var _request = OpenLayers.Request.GET;\n        OpenLayers.Request.GET = function(options) {\n            log.options = options;\n        };\n\n        // control url doesn't match layer urls, no request issued\n        log = {};\n        control.getInfoForClick({xy: {x: 50, y: 50}});\n        t.ok(!log.options, \"no url match, no request issued\");\n\n        // give control a list of urls to match\n        log = {};\n        control.layerUrls = [\"http://a.mirror/wms\", \"http://b.mirror/wms\"];\n        control.getInfoForClick({xy: {x: 50, y: 50}});\n        t.eq(log.options && log.options.url, \"http://host/wms\", \"some match, request issued\");\n        t.eq(log.options && log.options.params[\"QUERY_LAYERS\"].join(\",\"), \"b,a\", \"selected layers queried\");\n\n        // show that a layer can be matched if it has a urls array itself (first needs to be matched)\n        log = {};\n        control.layerUrls = [\"http://c.mirror/wms\"];\n        control.getInfoForClick({xy: {x: 50, y: 50}});\n        t.eq(log.options && log.options.params[\"QUERY_LAYERS\"].join(\",\"), \"c\", \"layer with urls array can be queried\");\n\n        // clean up\n        OpenLayers.Request.GET = _request;\n        map.destroy();\n\n    }\n    \n    function test_hover(t) {\n        \n        t.plan(2);\n        \n        var map = new OpenLayers.Map({\n            div: \"map\",\n            layers: [\n                new OpenLayers.Layer.WMS(null, \"/dummywms\", {layers: \"one\"})\n            ],\n            center: new OpenLayers.LonLat(0, 0),\n            zoom: 1\n        });\n        \n        var control = new OpenLayers.Control.WMSGetFeatureInfo({\n            hover: true\n        });\n        map.addControl(control);\n        control.activate();\n        \n        // mock up a mousemove\n        control.getInfoForHover({xy: new OpenLayers.Pixel(10, 10)});\n        t.ok(!!control.hoverRequest, \"hoverRequest set\");\n        \n        // confirm that request is canceled on next move\n        var called = 0;\n        control.hoverRequest.abort = function() {\n            ++called;\n        };\n        control.handler.px = null;\n        control.handler.mousemove({xy: new OpenLayers.Pixel(20, 20)});\n        t.eq(called, 1, \"hover request aborted\");\n        \n        map.destroy();\n        \n    }\n\n    function test_exceptions(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map(\"map\", {\n            getExtent: function() {return(new OpenLayers.Bounds(-180,-90,180,90));}\n            }\n        );\n\n        var a = new OpenLayers.Layer.WMS(\"dummy\",\"http://myhost/wms\", {\n            layers: \"x\",\n            exceptions: \"text/xml\"\n        });\n\n        map.addLayer(a);\n\n        var click = new OpenLayers.Control.WMSGetFeatureInfo({\n        });\n\n        map.addControl(click);\n\n        var _request = OpenLayers.Request.GET;\n        OpenLayers.Request.GET = function(options) {\n            t.eq(options.params[\"EXCEPTIONS\"], \"text/xml\", \"Exceptions parameter taken from the WMS layer if provided\");\n        };\n        click.activate();\n        click.getInfoForClick({xy: {x: 50, y: 50}});\n        OpenLayers.Request.GET = _request;\n        map.destroy();\n    }\n\n    function test_drillDown(t) {\n        t.plan(6);\n        var map = new OpenLayers.Map(\"map\", {\n            getExtent: function() {return(new OpenLayers.Bounds(-180,-90,180,90));}\n            }\n        );\n\n        var a = new OpenLayers.Layer.WMS(\"dummy\",\"http://localhost/wms\", {\n            layers: \"a\"\n        });\n\n        var b = new OpenLayers.Layer.WMS(\"dummy\",\"http://localhost/wms\", {\n            layers: \"c\"\n        });\n\n        // this service does not support application/vnd.ogc.gml for GetFeatureInfo, only text/xml\n        var c = new OpenLayers.Layer.WMS(\"dummy\",\"http://myhost/wms\", {\n            layers: \"x\",\n            info_format: \"text/xml\"\n        });\n\n        map.addLayers([a, b, c]);\n\n        var click = new OpenLayers.Control.WMSGetFeatureInfo({\n            drillDown: true,\n            infoFormat: \"application/vnd.ogc.gml\"\n        });\n\n        map.addControl(click);\n\n        var count = 0;\n        var _request = OpenLayers.Request.GET;\n        OpenLayers.Request.GET = function(options) {\n            count++;\n            if (count == 2) {\n                t.eq(options.params[\"INFO_FORMAT\"], \"application/vnd.ogc.gml\", \"Default info format of the control is used\");\n                t.eq(options.params[\"QUERY_LAYERS\"].join(\",\"), \"c,a\", \"Layers should be grouped by service url\");\n                t.eq(options.url, \"http://localhost/wms\", \"Correct url used for second request\");\n            } else if (count == 1) {\n                t.eq(options.params[\"INFO_FORMAT\"], \"text/xml\", \"Overridden info format is used instead of the control's infoFormat\");\n                t.eq(options.url, \"http://myhost/wms\", \"Correct url used for first request\");\n            }\n        };\n        click.activate();\n        click.getInfoForClick({xy: {x: 50, y: 50}});\n        OpenLayers.Request.GET = _request;\n        t.eq(count, 2, \"We expect 2 requests to go off\");\n        map.destroy();\n    }\n    \n    function test_GetFeatureInfo_buildWMSOptions(t) {\n        t.plan(3);\n        \n        var map = new OpenLayers.Map(\"map\", {\n            getExtent: function() {return(new OpenLayers.Bounds(-180,-90,180,90));},\n            projection: \"EPSG:900913\"\n        });\n        var a = new OpenLayers.Layer.WMS(\"dummy\", \"http://localhost/wms\", {\n            layers: \"a\"\n        }, {projection: \"EPSG:3857\"});\n        var b = new OpenLayers.Layer.WMS(\"dummy\", \"http://localhost/wms\", {\n            layers: \"b\"\n        });\n        var c = new OpenLayers.Layer.WMS(\"dummy\", \"http://localhost/wms\", {\n            layers: \"c\"\n        }, {projection: \"EPSG:4326\"});\n        map.addLayers([a, b, c]);\n        var gfi = new OpenLayers.Control.WMSGetFeatureInfo();\n        map.addControl(gfi);\n        gfi.activate();\n\n        var options = gfi.buildWMSOptions(\"http://localhost/wms\", [a], {xy: {x: 50, y: 50}}, \"text/html\");\n        t.eq(options.params.SRS, \"EPSG:3857\", \"layer projection used if provided and equal map projection\");\n\n        options = gfi.buildWMSOptions(\"http://localhost/wms\", [b], {xy: {x: 50, y: 50}}, \"text/html\");\n        t.eq(options.params.SRS, \"EPSG:900913\", \"map projection used if layer has no projection configured\");\n\n        options = gfi.buildWMSOptions(\"http://localhost/wms\", [b], {xy: {x: 50, y: 50}}, \"text/html\");\n        t.eq(options.params.SRS, \"EPSG:900913\", \"map projection used if layer configured with an incompatible projection\");\n    }\n\n    function test_GetFeatureInfo_WMS13(t) {\n        t.plan(4);\n        var map = new OpenLayers.Map(\"map\", {\n            getExtent: function() {return(new OpenLayers.Bounds(-180,-90,180,90));}\n            }\n        );\n\n        var a = new OpenLayers.Layer.WMS(null, \"http://localhost/wms\", {\n            layers: \"a\",\n            version: \"1.3.0\"\n        });\n        map.addLayer(a);\n\n        var click = new OpenLayers.Control.WMSGetFeatureInfo({\n        });\n\n        map.addControl(click);\n        var log = {};\n        var _request = OpenLayers.Request.GET;\n        OpenLayers.Request.GET = function(options) {\n            log.options = options;\n        };\n        click.activate();\n        click.getInfoForClick({xy: {x: 50.1, y: 60.2}});\n        OpenLayers.Request.GET = _request;\n        t.eq(\n            log.options && log.options.params.CRS,\n            \"EPSG:4326\",\n            \"Since it is WMS 1.3 use CRS parameter instead of SRS in the GetFeatureInfo request\"\n        );\n\n        t.eq(\n            log.options && log.options.params.I,\n            50,\n            \"Since it is WMS 1.3 use I parameter instead of X in the GetFeatureInfo request\"\n        );\n\n        t.eq(\n            log.options && log.options.params.J,\n            60,\n            \"Since it is WMS 1.3 use J parameter instead of Y in the GetFeatureInfo request\"\n        );\n\n        t.eq(\n            log.options && log.options.params.BBOX,\n            \"-90,-180,90,180\",\n            \"Since it is WMS 1.3 the BBOX should respect axis order\"\n        );\n\n    }\n\n    function test_handleResponse_JSON(t) {\n        t.plan(5);\n\n        var clickCoordinate = {'xy': {'x': 50, 'y': 50}};\n        var request = {\n            'responseText': \"{\\\"type\\\":\\\"FeatureCollection\\\",\\\"features\\\":[{\\\"type\\\":\\\"Feature\\\",\\\"id\\\":\\\"buildings.8359\\\",\\\"geometry\\\":{\\\"type\\\":\\\"MultiPolygon\\\",\\\"coordinates\\\":[[[[-1.3154005920528281E7,4044522.989129901],[-1.3154005851109248E7,4044516.519693766],[-1.3153997359215712E7,4044516.611228658],[-1.3153997376215957E7,4044518.0115422606],[-1.3153991465984887E7,4044518.073011226],[-1.315399104407448E7,4044477.984995398],[-1.3154005865324631E7,4044477.827667067],[-1.3154005904349212E7,4044481.415238877],[-1.3154007327546554E7,4044481.40174741],[-1.3154007326878684E7,4044480.991660189],[-1.315400926879267E7,4044480.9700426213],[-1.3154009229231585E7,4044476.979656877],[-1.3154014543494673E7,4044476.9229164813],[-1.3154014548324812E7,4044477.5916807987],[-1.3154018354806663E7,4044477.5484488346],[-1.3154018350072712E7,4044476.9388398607],[-1.3154023840985721E7,4044476.881804511],[-1.315402384562935E7,4044477.5098391017],[-1.315402758599418E7,4044477.4704705887],[-1.315402757752542E7,4044476.790681231],[-1.3154038257694557E7,4044476.6769741727],[-1.3154038262405435E7,4044477.3457386605],[-1.315404269041407E7,4044477.2978384267],[-1.315404286439716E7,4044493.7800058103],[-1.3154007524848279E7,4044494.155989673],[-1.3154007646710869E7,4044505.7094379417],[-1.3154022107703935E7,4044505.556316444],[-1.3154022094344625E7,4044504.170787319],[-1.3154018346731113E7,4044504.21016599],[-1.3154018290260306E7,4044498.878616157],[-1.315402591048427E7,4044498.795894118],[-1.315402596710939E7,4044504.145869147],[-1.3154023609634686E7,4044504.171931162],[-1.3154023626849018E7,4044505.7015852067],[-1.3154042883521369E7,4044505.4999371967],[-1.3154043053740704E7,4044521.893539395],[-1.3154034951699786E7,4044521.9808243145],[-1.3154034960102554E7,4044522.6938309614],[-1.3154027829018425E7,4044522.768359982],[-1.315402782070021E7,4044522.180937892],[-1.3154024176006297E7,4044522.220149225],[-1.3154024180475479E7,4044522.74114868],[-1.3154018700641066E7,4044522.798166171],[-1.3154018696220534E7,4044522.30686572],[-1.3154014871261876E7,4044522.350007108],[-1.3154014875893366E7,4044522.8968263282],[-1.3154005920528281E7,4044522.989129901]]]]},\\\"geometry_name\\\":\\\"the_geom\\\",\\\"properties\\\":{\\\"CODE\\\":\\\"Building\\\",\\\"BLD_ID\\\":\\\"511910864932\\\",\\\"HEIGHT\\\":26.76,\\\"ELEV\\\":677.3,\\\"AREA\\\":0,\\\"SOURCE\\\":\\\"LARIAC2\\\",\\\"DATE_\\\":\\\"2008\\\",\\\"AIN\\\":\\\"5313004018\\\",\\\"Shape_Leng\\\":830.711543857,\\\"Shape_Area\\\":13794.2724736}}],\\\"crs\\\":{\\\"type\\\":\\\"EPSG\\\",\\\"properties\\\":{\\\"code\\\":\\\"3857\\\"}}}\",\n            'getAllResponseHeaders': function() {\n               return \"application/json\";\n            }\n        };\n        var url = \"http://localhost/wms\";\n\n        var map = new OpenLayers.Map(\"map\", {\n            getExtent: function() {return(new OpenLayers.Bounds(-180,-90,180,90));}\n            }\n        );\n\n        var a = new OpenLayers.Layer.WMS(null, url, {\n            layers: \"a\",\n            version: \"1.3.0\"\n        });\n        map.addLayer(a);\n\n        var click = new OpenLayers.Control.WMSGetFeatureInfo({\n        });\n        click.infoFormat = \"application/json\";\n        click.events.register('getfeatureinfo', click, function(evt) {\n            t.ok(evt, \"Event object exists\");\n            t.ok(evt.text, \"Event text exists\");\n            t.ok(evt.features, \"Event features exists\");\n            t.ok(evt.xy, \"Event coordinate exists\");\n\n            t.eq(evt.features.length, 1, \"Should contain one element\");\n        });\n\n        map.addControl(click);\n        click.activate();\n\n        click.handleResponse(clickCoordinate, request, url);\n    }\n\n    </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 400px; height: 250px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/WMTSGetFeatureInfo.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(4);\n\n        var options = {\n            url: \"http://localhost/wmts\",\n            layers: [\"foo\"],\n            formatOptions: {\n                foo: \"bar\"\n            }\n        };\n        var control = new OpenLayers.Control.WMTSGetFeatureInfo(options);\n        t.ok(control instanceof OpenLayers.Control.WMTSGetFeatureInfo,\n             \"new OpenLayers.Control.WMTSGetFeatureInfo returns an instance\");\n        t.eq(control.layers, [\"foo\"],\n             \"constructor layers\"\n            );\n        t.ok(control.format instanceof OpenLayers.Format.WMSGetFeatureInfo, \"format created\");\n        t.eq(control.format.foo, \"bar\", \"format options used\")\n    }\n\n    function test_clickCallBack_option(t) {\n        t.plan(9);\n\n        var control;\n\n        control = new OpenLayers.Control.WMTSGetFeatureInfo({\n            hover: true\n        });\n        t.ok(control.handler instanceof OpenLayers.Handler.Hover,\n             'constructor creates hover handler');\n        t.ok(control.handler.callbacks[\"move\"] === control.cancelHover,\n             'constructor registers proper \"move\" callback in handler');\n        t.ok(control.handler.callbacks[\"pause\"] === control.getInfoForHover,\n             'constructor registers proper \"pause\" callback in handler');\n\n        control = new OpenLayers.Control.WMTSGetFeatureInfo();\n        t.ok(control.handler instanceof OpenLayers.Handler.Click,\n             'constructor creates click handler');\n        t.ok(control.handler.callbacks[\"click\"] === control.getInfoForClick,\n             'constructor registers proper \"click\" callback in handler');\n\n        control = new OpenLayers.Control.WMTSGetFeatureInfo({\n            clickCallback: \"rightclick\"\n        });\n        t.ok(control.handler.callbacks[\"rightclick\"] === control.getInfoForClick,\n             'constructor registers proper \"rightclick\" callback in handler');\n\n        control = new OpenLayers.Control.WMTSGetFeatureInfo({\n            clickCallback: \"dblclick\",\n            handlerOptions: {\n                click: {\n                    \"single\": false,\n                    \"double\": true\n                }\n            }\n        });\n        t.ok(control.handler.callbacks[\"dblclick\"] === control.getInfoForClick,\n             'constructor registers proper \"dblclick\" callback in handler');\n        t.eq(control.handler[\"single\"], false,\n             'constructor sets \"single\" to false in handler');\n        t.eq(control.handler[\"double\"], true,\n             'constructor sets \"double\" to true in handler');\n     }\n\n    function test_destroy(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var click = new OpenLayers.Control.WMTSGetFeatureInfo({\n            url: 'http://localhost/wms',\n            layers: [\"foo\"]\n        });\n\n        var hover = new OpenLayers.Control.WMTSGetFeatureInfo({\n            url: 'http://localhost/wms',\n            layers: [\"foo\"],\n            hover: true\n        });\n\n        click.handler.deactivate = function() {\n            t.ok(true,\n                 \"control.deactivate calls deactivate on click handler\");\n        };\n        hover.handler.deactivate = function() {\n            t.ok(true,\n                 \"control.deactivate calls deactivate on hover handler\");\n        };\n        click.destroy();\n        hover.destroy();\n    }\n\n    function test_click(t) {\n        t.plan(4);\n        var map = new OpenLayers.Map('map');\n\n        // mock up active control\n        var control = new OpenLayers.Control.WMTSGetFeatureInfo();\n        map.addControl(control);\n        control.activate();\n\n        control.request = function(position) {\n            t.eq(position.x, 200,\n                 \"x position is as expected\");\n            t.eq(position.y, 125,\n                 \"y position is as expected\");\n        };\n\n        control.getInfoForClick({xy: {x: 200, y: 125}});\n        control.getInfoForHover({xy: {x: 200, y: 125}});\n    }\n\n    function test_beforegetfeatureinfo_event(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map({\n            div: \"map\",\n            allOverlays: true,\n            layers: [\n                new OpenLayers.Layer.WMTS({\n                    name: \"Test WMTS 1\", \n                    url: \"/testwmts/\",\n                    layer: \"test1\",\n                    style: \"\",\n                    matrixSet: \"set-id\",\n                    isBaseLayer: false\n                }),\n                new OpenLayers.Layer.WMTS({\n                    name: \"Test WMTS 2\", \n                    url: \"/testwmts/\",\n                    layer: \"test2\",\n                    style: \"\",\n                    matrixSet: \"set-id\",\n                    isBaseLayer: false\n                })\n            ],\n            center: new OpenLayers.LonLat(0, 0),\n            zoom: 0\n        });\n\n        var log = [];\n\n        // test click\n        var click = new OpenLayers.Control.WMTSGetFeatureInfo({\n            drillDown: true,\n            eventListeners: {\n                beforegetfeatureinfo: function(evt) {\n                    log.push({xy: evt.xy});\n                }\n            }\n        });\n        map.addControl(click);\n        click.activate();\n        click.getInfoForClick({xy: {x: 200, y: 125}});\n        t.eq(log.length, 2, \"click: beforegetfeatureinfo triggered twice\");\n        log = [];\n        click.deactivate();\n\n        // test hover\n        var hover = new OpenLayers.Control.WMTSGetFeatureInfo({\n            hover: true,\n            eventListeners: {\n                beforegetfeatureinfo: function(evt) {\n                    log.push({xy: evt.xy});\n                }\n            }\n        });\n        map.addControl(hover);\n        hover.activate();\n        xy = {x: 70, y: 70};\n        hover.getInfoForHover({xy: {x: 70, y: 70}});\n        t.eq(log.length, 1, \"hover: beforegetfeatureinfo triggered once\");\n        log = [];\n        hover.deactivate();\n        \n        map.destroy();\n    }\n\n    function test_activate(t) {\n        t.plan(4);\n        var map = new OpenLayers.Map(\"map\");\n        var click = new OpenLayers.Control.WMTSGetFeatureInfo({\n            url: 'http://localhost/wms',\n            layers: ['ns:type']\n        });\n        var hover = new OpenLayers.Control.WMTSGetFeatureInfo({\n            url: 'http://localhost/wms',\n            featureType: 'type',\n            featureNS: 'http://localhost/ns',\n            layers: 'ns:type',\n            hover: true\n        });\n        map.addControl(click);\n        map.addControl(hover);\n        t.ok(!click.handler.active,\n             \"click handler is not active prior to activating control\");\n        t.ok(!hover.handler.active,\n             \"hover handler is not active prior to activating control\");\n        click.activate();\n        hover.activate();\n        t.ok(click.handler.active,\n             \"click handler is active after activating control\");\n        t.ok(hover.handler.active,\n             \"hover handler is active after activating control\");\n    }\n\n    function test_deactivate(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var click = new OpenLayers.Control.WMTSGetFeatureInfo({\n            url: 'http://localhost/wms',\n            featureType: 'type',\n            featureNS: 'http://localhost/ns',\n            layers: 'ns:type'\n        });\n        var hover = new OpenLayers.Control.WMTSGetFeatureInfo({\n            url: 'http://localhost/wms',\n            featureType: 'type',\n            featureNS: 'http://localhost/ns',\n            layers: 'ns:type'\n        });\n        map.addControl(click);\n        map.addControl(hover);\n        click.activate();\n        hover.activate();\n\n        click.handler.deactivate = function() {\n            t.ok(true,\n                 \"control.deactivate calls deactivate on click handler\");\n            OpenLayers.Handler.Click.prototype.deactivate.apply(this, arguments);\n        };\n        hover.handler.deactivate = function() {\n            t.ok(true,\n                 \"control.deactivate calls deactivate on hover handler\");\n            OpenLayers.Handler.Hover.prototype.deactivate.apply(this, arguments);\n        };\n        click.deactivate();\n        hover.deactivate();\n    }\n\n    function test_getInfoForClick(t) {\n\n        t.plan(13);\n        var map = new OpenLayers.Map({\n            div: \"map\",\n            getExtent: function() {\n                return new OpenLayers.Bounds(-180,-90,180,90);\n            }\n        });\n\n        var a = new OpenLayers.Layer.WMTS({\n            url: \"http://a.example.com/wmts\",\n            layer: \"a\",\n            matrixSet: \"bar\",\n            style: \"default\"\n        });\n\n        var b = new OpenLayers.Layer.WMTS({\n            url: \"http://b.example.com/wmts\",\n            layer: \"b\",\n            matrixSet: \"bar\",\n            style: \"default\",\n            isBaseLayer: false\n        });\n\n        var c = new OpenLayers.Layer.WMTS({\n            url: [\"http://c1.example.com/wmts\", \"http://c2.example.com\"],\n            layer: \"c\",\n            matrixSet: \"bar\",\n            style: \"default\",\n            isBaseLayer: false\n        });\n        map.addLayers([a, b, c]);\n        map.zoomToMaxExtent();\n\n        var control = new OpenLayers.Control.WMTSGetFeatureInfo({\n            layers: [a, b, c]\n        });\n        map.addControl(control);\n        control.activate();\n\n        // log calls to GET\n        var log;\n        var _request = OpenLayers.Request.GET;\n        OpenLayers.Request.GET = function(options) {\n            log.push(options);\n        };\n\n        // query first layer (drillDown false)\n        log = [];\n        control.drillDown = false;\n        control.queryVisible = false;\n        control.getInfoForClick({xy: {x: 200, y: 125}});\n        t.eq(log.length, 1, \"one requests issued\");\n        t.eq(log[0].url, \"http://c1.example.com/wmts\", \"{drillDown: false} correct url\");\n        t.eq(log[0].params[\"LAYER\"], \"c\", \"{drillDown: false} correct layer parameter\");\n\n        // query all layers\n        log = [];\n        control.drillDown = true;\n        control.queryVisible = false;\n        control.getInfoForClick({xy: {x: 200, y: 125}});\n        t.eq(log.length, 3, \"three requests issued\");\n        t.eq(log[0].url, \"http://c1.example.com/wmts\", \"[c] correct url\");\n        t.eq(log[0].params[\"LAYER\"], \"c\", \"[c] correct layer parameter\");\n        t.eq(log[1].url, \"http://b.example.com/wmts\", \"[b] correct url\");\n        t.eq(log[1].params[\"LAYER\"], \"b\", \"[b] correct layer parameter\");\n        t.eq(log[2].url, \"http://a.example.com/wmts\", \"[a] correct url\");\n        t.eq(log[2].params[\"LAYER\"], \"a\", \"[a] correct layer parameter\");\n\n        // query only visible layers\n        log = [];\n        control.drillDown = true;\n        control.queryVisible = true;\n        b.setVisibility(false);\n        control.getInfoForClick({xy: {x: 200, y: 125}});\n        t.eq(log.length, 2, \"two requests issued\");\n        t.eq(log[0].url, \"http://c1.example.com/wmts\", \"correct url for second visible layer\");\n        t.eq(log[1].url, \"http://a.example.com/wmts\", \"correct url for first visible layer\");\n\n        // clean up\n        OpenLayers.Request.GET = _request;\n        map.destroy();\n\n    }\n\n    </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 400px; height: 250px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/Zoom.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_constructor(t) {\n        t.plan(5);\n\n        var control = new OpenLayers.Control.Zoom();\n        t.ok(control instanceof OpenLayers.Control, \"instance of Control\");\n        t.ok(control instanceof OpenLayers.Control.Zoom, \"instance of Zoom\");\n        t.eq(control.displayClass, \"olControlZoom\", \"displayClass\");\n        control.destroy();\n        \n        control = new OpenLayers.Control.Zoom({\n            zoomInText: \"zoom in!\",\n            zoomOutText: \"zoom out!\"\n        });\n        t.eq(control.zoomInText, \"zoom in!\", \"zoomInText\");\n        t.eq(control.zoomOutText, \"zoom out!\", \"zoomOutText\");\n        control.destroy();        \n    }\n\n    function test_addControl(t) {\n        t.plan(3);\n        var map = new OpenLayers.Map(\"map\");\n        var control = new OpenLayers.Control.Zoom();\n        map.addControl(control);\n        t.ok(control.map === map, \"Control.map set\");\n        t.ok(!!~OpenLayers.Util.indexOf(map.controls, control), \"map.controls contains control\");\n\n        control = new OpenLayers.Control.Zoom({zoomInId: \"in\", zoomOutId: \"out\"});\n        map.addControl(control);\n        var eventsEl = document.getElementById(\"out\").parentNode;\n        t.ok(control.events.element === eventsEl, \"Events instance listens to custom div's parentNode\");\n\n        map.destroy();\n    }\n    \n    function test_zoomIn(t) {\n        t.plan(2);\n        \n        var map = new OpenLayers.Map({\n            div: \"map\",\n            layers: [new OpenLayers.Layer(null, {isBaseLayer: true})],\n            zoomMethod: null\n        });\n        var control = new OpenLayers.Control.Zoom();\n        map.addControl(control);\n        map.setCenter([0, 0], 0);\n        \n        t.eq(map.getZoom(), 0, \"initial center\");\n        map.events.triggerEvent(\"buttonclick\", {buttonElement: control.zoomInLink});\n        t.eq(map.getZoom(), 1, \"after zoom in\");\n        map.destroy();\n    }\n\n    function test_zoomOut(t) {\n        t.plan(2);\n        \n        var map = new OpenLayers.Map({\n            div: \"map\",\n            layers: [new OpenLayers.Layer(null, {isBaseLayer: true})],\n            zoomMethod: null\n        });\n        var control = new OpenLayers.Control.Zoom();\n        map.addControl(control);\n        map.setCenter([0, 0], 1);\n        \n        t.eq(map.getZoom(), 1, \"initial center\");\n        map.events.triggerEvent(\"buttonclick\", {buttonElement: control.zoomOutLink});\n        t.eq(map.getZoom(), 0, \"after zoom out\");\n        map.destroy();\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 512px; height: 256px;\"/>\n    <div id=\"in\">in</div><div id=\"out\">out</out>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/ZoomBox.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_constructor(t) {\n        t.plan(4);\n\n        var control = new OpenLayers.Control.ZoomBox();\n        t.ok(control instanceof OpenLayers.Control, \"instance of Control\");\n        t.ok(control instanceof OpenLayers.Control.ZoomBox, \"instance of ZoomBox\");\n        t.eq(control.displayClass, \"olControlZoomBox\", \"displayClass\");\n        control.destroy();\n        \n        control = new OpenLayers.Control.ZoomBox({\n            zoomOnClick: false\n        });\n        t.eq(control.zoomOnClick, false, \"zoomOnClick\");\n        control.destroy();        \n    }\n\n    function test_zoomBox(t) {\n        t.plan(4);\n        var map = new OpenLayers.Map(\"map\", {\n            zoomMethod: null,\n            layers: [new OpenLayers.Layer(\"\", {isBaseLayer: true})],\n            center: [0, 0],\n            zoom: 1\n        });\n        var control = new OpenLayers.Control.ZoomBox();\n        map.addControl(control);\n        control.zoomBox(new OpenLayers.Pixel(50, 60));\n        t.eq(map.getZoom(), 2, \"zoomed on click\");\n        \n        control.zoomOnClick = false;\n        control.zoomBox(new OpenLayers.Pixel(-50, -60));\n        t.eq(map.getZoom(), 2, \"not zoomed with zoomOnClick set to false\");\n        \n        map.zoomToMaxExtent();\n        // pixel bounds bottom > top\n        control.zoomBox(new OpenLayers.Bounds(128, 128, 256, 64));\n        t.eq(map.getCenter().toShortString(), \"-45, 22.5\", \"centered to box center\");\n        t.eq(map.getZoom(), 3, \"zoomed to box extent\");\n        \n        map.destroy();\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 512px; height: 256px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/ZoomIn.html",
    "content": "<!DOCTYPE html>\n<html>\n    <head>\n        <script src=\"../OLLoader.js\"></script>\n        <script type=\"text/javascript\">\n        \nfunction test_ZoomIn_constructor (t) {\n    t.plan( 2 );\n    \n    // setup\n    var control = new OpenLayers.Control.ZoomIn();\n    \n    // tests\n    //\n    t.ok( \n        control instanceof OpenLayers.Control.ZoomIn, \n        \"new OpenLayers.Control.ZoomIn returns object\"\n    );\n    t.eq( \n        control.displayClass, \"olControlZoomIn\", \n        \"displayClass is correct\"\n    );\n    \n    // tear down\n    control.destroy();\n}\n\nfunction test_ZoomIn_type (t) {\n    t.plan( 1 );\n    \n    // setup\n    var control = new OpenLayers.Control.ZoomIn();\n    \n    // tests\n    //\n    t.eq( \n        control.type, \n        OpenLayers.Control.TYPE_BUTTON,\n        \"ZoomIn control is of type OpenLayers.Control.TYPE_BUTTON\"\n    );\n    \n    // tear down\n    control.destroy();\n}\n\nfunction test_ZoomIn_trigger (t) {\n    t.plan( 2 );\n    \n    // set up\n    var control = new OpenLayers.Control.ZoomIn(),\n        zoomlevel = 5,\n        map = new OpenLayers.Map(\"map\", {\n            allOverlays: true,\n            layers: [\n                new OpenLayers.Layer.Vector()\n            ],\n            center: new OpenLayers.LonLat(1,1),\n            zoom: zoomlevel\n        }),\n        oldZoom;\n    \n    oldZoom = map.getZoom();\n    \n    // tests\n    //\n    // trigger the control before it is being added,\n    // nothing should change\n    control.trigger();\n    \n    t.eq(\n        oldZoom, \n        zoomlevel,\n        'Calling trigger on a non added control doesn\\'t do anything ' +\n            '(map zoom is ' + oldZoom + ').'\n    );\n            \n    // now lets add the control\n    map.addControl(control);\n\n    // trigger it again, now the map should have a different extent\n    control.trigger();\n    \n    t.eq(\n        map.getZoom(),\n        zoomlevel + 1,\n        'Calling trigger on a added control changes the map zoom ' +\n            '(map zoom was ' + zoomlevel + \n            ' and is now ' + map.getZoom() + ').'\n    );\n    \n    // tear down\n    control.destroy();\n    map.destroy();\n}\n    \n        </script>\n    </head>\n    <body>\n        <div id=\"map\" style=\"width: 1000px; height: 1000px;\"></div>\n    </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/ZoomOut.html",
    "content": "<!DOCTYPE html>\n<html>\n    <head>\n        <script src=\"../OLLoader.js\"></script>\n        <script type=\"text/javascript\">\n        \nfunction test_ZoomOut_constructor (t) {\n    t.plan( 2 );\n    \n    // setup\n    var control = new OpenLayers.Control.ZoomOut();\n    \n    // tests\n    //\n    t.ok( \n        control instanceof OpenLayers.Control.ZoomOut, \n        \"new OpenLayers.Control.ZoomOut returns object\"\n    );\n    t.eq( \n        control.displayClass, \"olControlZoomOut\", \n        \"displayClass is correct\"\n    );\n    \n    // tear down\n    control.destroy();\n}\n\nfunction test_ZoomOut_type(t){\n    t.plan( 1 );\n    \n    // setup\n    var control = new OpenLayers.Control.ZoomOut();\n    \n    // check that the type of the control equals OpenLayers.Control.TYPE_BUTTON\n    t.eq(\n        control.type,\n        OpenLayers.Control.TYPE_BUTTON,\n        'ZoomOut-control is of type \"OpenLayers.Control.TYPE_BUTTON\".'\n    );\n    \n    // tear down\n    control.destroy();\n}\n\nfunction test_ZoomOut_trigger (t) {\n    t.plan( 2 );\n    \n    // set up\n    var control = new OpenLayers.Control.ZoomOut(),\n        zoomlevel = 5,\n        map = new OpenLayers.Map(\"map\", {\n            allOverlays: true,\n            layers: [\n                new OpenLayers.Layer.Vector()\n            ],\n            center: new OpenLayers.LonLat(1,1),\n            zoom: zoomlevel\n        }),\n        oldZoom;\n    \n    oldZoom = map.getZoom();\n    \n    // tests\n    //\n    // trigger the control before it is being added,\n    // nothing should change\n    control.trigger();\n    \n    t.eq(\n        oldZoom, \n        zoomlevel,\n        'Calling trigger on a non added control doesn\\'t do anything ' +\n            '(map zoom is ' + oldZoom + ').'\n    );\n            \n    // now lets add the control\n    map.addControl(control);\n\n    // trigger it again, now the map should have a different extent\n    control.trigger();\n    \n    t.eq(\n        map.getZoom(),\n        zoomlevel - 1,\n        'Calling trigger on a added control changes the map zoom ' +\n            '(map zoom was ' + zoomlevel + \n            ' and is now ' + map.getZoom() + ').'\n    );\n    \n    // tear down\n    control.destroy();\n    map.destroy();\n}\n    \n        </script>\n    </head>\n    <body>\n        <div id=\"map\" style=\"width: 1000px; height: 1000px;\"></div>\n    </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control/ZoomToMaxExtent.html",
    "content": "<!DOCTYPE html>\n<html>\n    <head>\n        <script src=\"../OLLoader.js\"></script>\n        <script type=\"text/javascript\">\n        \nfunction test_ZoomToMaxExtent_constructor (t) {\n    t.plan( 2 );\n    \n    // setup\n    var control = new OpenLayers.Control.ZoomToMaxExtent();\n    \n    // tests\n    //\n    t.ok( \n        control instanceof OpenLayers.Control.ZoomToMaxExtent, \n        \"new OpenLayers.Control.ZoomToMaxExtent returns object\"\n    );\n    t.eq( \n        control.displayClass, \"olControlZoomToMaxExtent\", \n        \"displayClass is correct\"\n    );\n    \n    // tear down\n    control.destroy();\n}\n\nfunction test_ZoomToMaxExtent_type (t) {\n    t.plan( 1 );\n    \n    // setup\n    var control = new OpenLayers.Control.ZoomToMaxExtent();\n    \n    // check that the type of the control equals OpenLayers.Control.TYPE_BUTTON\n    t.eq(\n        control.type,\n        OpenLayers.Control.TYPE_BUTTON,\n        'ZoomToMaxExtent-control is of type \"OpenLayers.Control.TYPE_BUTTON\".'\n    );\n    \n    // tear down\n    control.destroy();\n}\n\nfunction test_ZoomToMaxExtent_trigger (t) {\n    t.plan( 2 );\n    \n    // set up\n    var mapsMaxExtent = new OpenLayers.Bounds(0, 0, 45, 45),\n        mapsInitialExtent = new OpenLayers.Bounds(5, 5, 7, 7),\n        control = new OpenLayers.Control.ZoomToMaxExtent(),\n        map = new OpenLayers.Map(\"map\", {\n            maxExtent: mapsMaxExtent,\n            allOverlays: true,\n            fractionalZoom: true,\n            layers: [\n                new OpenLayers.Layer.Vector()\n            ]\n        }),\n        oldExtent;\n    \n    map.zoomToExtent(mapsInitialExtent);\n    \n    oldExtent = map.getExtent().toString();\n    \n    // tests\n    //\n    // trigger the control before it is being added,\n    // nothing should change\n    control.trigger();\n    t.eq(\n        oldExtent, \n        map.getExtent().toString(),\n        'Calling trigger on a non added control doesn\\'t do anything ' +\n            '(map extent is \"' + oldExtent + '\").'\n    );\n            \n    // now lets add the control\n    map. addControl(control);\n    \n    // trigger it again, now the map should have a different extent\n    control.trigger();\n    \n    t.eq(\n        map.getExtent().toString(),\n        mapsMaxExtent.toString(),\n        'Calling trigger on a added control changes the map extent ' +\n            '(map extent was \"' + oldExtent + '\"' + \n            ' and is now \"' + mapsMaxExtent.toString() + '\").'\n    );\n    \n    // tear down\n    control.destroy();\n    map.destroy();\n}\n    \n        </script>\n    </head>\n    <body>\n        <div id=\"map\" style=\"width: 1000px; height: 1000px;\"></div>\n    </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Control.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    function test_Control_constructor(t) {\n        t.plan(4);\n    \n        var control = new OpenLayers.Control();\n\n        t.ok(control instanceof OpenLayers.Control, \"new OpenLayers.Control returns object\");\n        t.eq(control.displayClass, \"olControl\", \"displayClass set correctly\");\n        t.ok(control.id != null, \"default id assigned to control\");\n        \n        var testID = {};\n        control = new OpenLayers.Control({ 'id': testID });\n        t.ok(control.id == testID, \"if id specified in options, no default assigned.\");\n    }\n\n    function test_Control_addControl(t) {\n        t.plan(2);\n    \n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n\n        t.ok(control.map === map, \"Control.map is set to the map object\" );\n        t.ok(map.controls[map.controls.length - 1] === control, \"map.controls contains control\");\n    }\n    \n    function test_Control_title(t) { \n        t.plan( 1 ); \n        var titleText = 'Title test'; \n        control = new OpenLayers.Control({title:titleText}); \n        t.eq( control.title, titleText, \"control.title set correctly\" ); \n    }\n    \n    function test_eventListeners(t) {\n        t.plan(1);\n        \n        var method = OpenLayers.Events.prototype.on;\n        // test that events.on is called at control construction\n        var options = {\n            eventListeners: {foo: \"bar\"}\n        };\n        OpenLayers.Events.prototype.on = function(obj) {\n            t.eq(obj, options.eventListeners, \"events.on called with eventListeners\");\n        }\n        var control = new OpenLayers.Control(options);\n        OpenLayers.Events.prototype.on = method;\n        control.destroy();\n\n        // if events.on is called again, this will fail due to an extra test\n        // test control without eventListeners\n        OpenLayers.Events.prototype.on = function(obj) {\n            t.fail(\"events.on called without eventListeners\");\n        }\n        var control2 = new OpenLayers.Control();\n        OpenLayers.Events.prototype.on = method;\n        control2.destroy();\n    }\n\n    function test_Control_destroy(t) {\n        t.plan(4);\n    \n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n\n        control.destroy();\n        t.ok(map.controls[map.controls.length - 1] != control, \"map.controls doesn't contains control\");\n\n        t.ok(control.map == null, \"Control.map is null\");\n        t.ok(control.div == null, \"Control.div is null\");\n        t.ok(control.handler == null, \"Control.handler is null\");\n    }\n    \n    function test_autoActivate(t) {\n        \n        t.plan(3);\n        \n        var control, map = new OpenLayers.Map(\"map\");\n\n        // confirm that a control is not activated by default\n        control = new OpenLayers.Control();\n        map.addControl(control);\n        t.ok(!control.active, \"control is not activated by default\");\n        \n        // confirm that control is activated with autoActivate true\n        control = new OpenLayers.Control({autoActivate: true});\n        map.addControl(control);\n        t.ok(control.active, \"control is activated with autoActivate true\");\n       \n        // confirm that control is not activated with autoActivate false\n        control = new OpenLayers.Control({autoActivate: false});\n        map.addControl(control);\n        t.ok(!control.active, \"control is not activated with autoActivate false\");\n        \n        map.destroy();\n        \n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Events/buttonclick.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    var log, buttonClick, events, element, button;\n    function init() {\n        element = document.getElementById(\"map\");\n        button = document.getElementById(\"button\");\n    }\n    function trigger(evt) {\n        OpenLayers.Util.applyDefaults(evt, {\n            button: 1,\n            target: button\n        });\n        events.handleBrowserEvent(evt);\n    }\n    function logEvent(evt) {\n        log.push(evt);\n    }\n   \n    function test_ButtonClick(t) {\n        t.plan(1);\n        events = new OpenLayers.Events({}, element);\n        buttonClick = new OpenLayers.Events.buttonclick(events);\n        t.ok(buttonClick.target === events, \"target set from constructor arg\");\n        buttonClick.destroy();\n        events.destroy();\n    }\n\n    function test_getPressedButton(t) {\n        t.plan(4);\n\n        // set up\n\n        events = new OpenLayers.Events({}, element);\n        buttonClick = new OpenLayers.Events.buttonclick(events);\n\n        var button = document.createElement('button'),\n            span1 = document.createElement('span'),\n            span2 = document.createElement('span'),\n            span3 = document.createElement('span');\n        button.className = 'olButton';\n        button.appendChild(span1);\n        span1.appendChild(span2);\n        span2.appendChild(span3);\n\n        t.ok(buttonClick.getPressedButton(button) === button,\n             'getPressedButton returns button when element is button');\n        t.ok(buttonClick.getPressedButton(span1) === button,\n             'getPressedButton returns button when element is button descendant level 1');\n        t.ok(buttonClick.getPressedButton(span2) === button,\n             'getPressedButton returns button when element is button descendant level 2');\n        t.eq(buttonClick.getPressedButton(span3), undefined,\n             'getPressedButton returns undefined when element is button descendant level 3');\n\n        // test\n\n\n        // tear down\n\n        buttonClick.destroy();\n        events.destroy();\n    }\n    \n    function test_ignore(t) {\n        t.plan(5);\n\n        // set up\n\n        events = new OpenLayers.Events({}, element);\n        buttonClick = new OpenLayers.Events.buttonclick(events);\n\n        var link = document.createElement('a'),\n            span1 = document.createElement('span'),\n            span2 = document.createElement('span'),\n            span3 = document.createElement('span');\n        link.appendChild(span1);\n        span1.appendChild(span2);\n        span2.appendChild(span3);\n\n        t.eq(buttonClick.ignore(link), true,\n             'ignore returns true when element is a link');\n        t.eq(buttonClick.ignore(span1), true,\n             'ignore returns true when element is link descendant level 1');\n        t.eq(buttonClick.ignore(span2), true,\n             'ignore returns true when element is link descendant level 2');\n        t.eq(buttonClick.ignore(span3), false,\n             'ignore returns false when element is link descendant level 3');\n        t.eq(buttonClick.ignore(element), false,\n             'ignore returns false when element is not a link');\n\n\n        // tear down\n\n        buttonClick.destroy();\n        events.destroy();\n    }\n    \n    function test_ignore(t) {\n        t.plan(5);\n\n        // set up\n\n        events = new OpenLayers.Events({}, element);\n        buttonClick = new OpenLayers.Events.buttonclick(events);\n\n        var link = document.createElement('a'),\n            span1 = document.createElement('span'),\n            span2 = document.createElement('span'),\n            span3 = document.createElement('span');\n        link.appendChild(span1);\n        span1.appendChild(span2);\n        span2.appendChild(span3);\n\n        t.eq(buttonClick.ignore(link), true,\n             'ignore returns true when element is a link');\n        t.eq(buttonClick.ignore(span1), true,\n             'ignore returns true when element is link descendant level 1');\n        t.eq(buttonClick.ignore(span2), true,\n             'ignore returns true when element is link descendant level 2');\n        t.eq(buttonClick.ignore(span3), false,\n             'ignore returns false when element is link descendant level 3');\n        t.eq(buttonClick.ignore(element), false,\n             'ignore returns false when element is not a link');\n\n\n        // tear down\n\n        buttonClick.destroy();\n        events.destroy();\n    }\n    \n    function test_ButtonClick_buttonClick(t) {\n        t.plan(27);\n        events = new OpenLayers.Events({}, element);\n        events.on({\n            \"buttonclick\": logEvent,\n            \"mousedown\": logEvent,\n            \"mouseup\": logEvent,\n            \"click\": logEvent,\n            \"dblclick\": logEvent,\n            \"touchstart\": logEvent,\n            \"touchend\": logEvent,\n            \"keydown\": logEvent\n        });\n        buttonClick = events.extensions[\"buttonclick\"];\n        \n        // a complete click\n        log = [];\n        trigger({type: \"mousedown\"});\n        trigger({type: \"mouseup\"});\n        t.eq(log.length, 1, \"one event fired for mousedown-mouseup\");\n        t.eq(log[0].type, \"buttonclick\", \"buttonclick event fired\");\n        \n        // a complete tap\n        log = [];\n        trigger({type: \"touchstart\"});\n        trigger({type: \"touchend\"});\n        t.eq(log.length, 1, \"one event fired for touchstart-touchend\");\n        t.eq(log[0].type, \"buttonclick\", \"buttonclick event fired\");\n        \n        // mouse sequence started on button\n        log = [];\n        trigger({type: \"mousedown\"});\n        trigger({type: \"mouseup\", target: element});\n        t.eq(log.length, 1, \"one event fired for mousedown-(leave)-mouseup\");\n        t.eq(log[0].type, \"mouseup\", \"mouseup event goes through when sequence not finished on button\");\n\n        // touch sequence started on button\n        log = [];\n        trigger({type: \"touchstart\"});\n        trigger({type: \"touchmove\"});\n        trigger({type: \"touchend\"});\n        t.eq(log.length, 1, \"one event fired for touchstart-(leave)-touchend\");\n        t.eq(log[0].type, \"touchend\", \"touchend event goes through when sequence not finished on button\");\n\n        // mouse sequence finished on button\n        log = [];\n        trigger({type: \"mousedown\", target: element});\n        trigger({type: \"mouseup\"});\n        t.eq(log.length, 2, \"two event fired for mousedown-(enter)-mouseup\");\n        t.eq(log[0].type, \"mousedown\", \"mousedown unrelated to button goes through\");\n        t.eq(log[1].type, \"mouseup\", \"mouseup goes through when sequence started outside button\");\n\n        // touch sequence finished on button\n        log = [];\n        trigger({type: \"touchstart\", target: element});\n        trigger({type: \"touchend\"});\n        t.eq(log.length, 2, \"two event fired for touchstart-(enter)-touchend\");\n        t.eq(log[0].type, \"touchstart\", \"touchstart unrelated to button goes through\");\n        t.eq(log[1].type, \"touchend\", \"touchend goes through when sequence started outside button\");\n        \n        // dblclick\n        log = [];\n        trigger({type: \"mousedown\"});\n        trigger({type: \"mouseup\"});\n        trigger({type: \"click\"});\n        trigger({type: \"mousedown\"});\n        trigger({type: \"mouseup\"});\n        trigger({type: \"click\"});\n        trigger({type: \"dblclick\"});\n        t.eq(log.length, 2, \"two events fired for doubleclick\");\n        t.eq(log[0].type, \"buttonclick\", \"buttonclick for 1st click\");\n        t.eq(log[1].type, \"buttonclick\", \"buttonclick for 2nd click\");\n        \n        // dblclick - IE\n        log = [];\n        trigger({type: \"mousedown\"});\n        trigger({type: \"mouseup\"});\n        trigger({type: \"mouseup\"});\n        trigger({type: \"dblclick\"});\n        t.eq(log.length, 2, \"two events fired for dblclick in IE\");\n        t.eq(log[0].type, \"buttonclick\", \"buttonclick for 1st click in IE\");\n        t.eq(log[1].type, \"buttonclick\", \"buttonclick for 2nd click IE\");\n\n        // rightclick\n        log = [];\n        trigger({type: \"mousedown\", button: 2});\n        trigger({type: \"mouseup\", button: 2});\n        t.eq(log.length, 2, \"two events fired for rightclick\");\n        t.eq(log[0].type, \"mousedown\", \"mousedown from rightclick goes through\");\n        t.eq(log[1].type, \"mouseup\", \"mouseup from rightclick goes through\");\n\n        // keydown RETURN\n        log = [];\n        trigger({type: \"keydown\", keyCode: OpenLayers.Event.KEY_RETURN});\n        trigger({type: \"click\"});\n        t.eq(log.length, 1, \"one event fired for RETURN keydown\");\n        t.eq(log[0].type, \"buttonclick\", \"buttonclick for RETURN keydown\");\n\n        // keydown SPACE\n        log = [];\n        trigger({type: \"keydown\", keyCode: OpenLayers.Event.KEY_SPACE});\n        trigger({type: \"click\"});\n        t.eq(log.length, 1, \"one event fired for SPACE keydown\");\n        t.eq(log[0].type, \"buttonclick\", \"buttonclick for SPACE keydown\");\n    }\n  </script>\n</head>\n<body onload=\"init()\">\n    <div id=\"map\" style=\"width: 600px; height: 300px;\">\n        <div id=\"button\" class=\"olButton\">\n            <img class=\"olAlphaImg\">\n        </div>\n    </div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Events/featureclick.html",
    "content": "<html>\n<head>\n<script src=\"../OLLoader.js\"></script>\n<script type=\"text/javascript\">\n\nvar layer1, style, logevt, lognoevt, map, lonlat, pixel, element;\n\nfunction init() {\n\n\telement = document.getElementById(\"map\");\n\n\tstyle = new OpenLayers.StyleMap({\n\t\t 'default': OpenLayers.Util.applyDefaults(\n\t\t     {label: \"${l}\", pointRadius: 30},\n\t\t     OpenLayers.Feature.Vector.style[\"default\"]\n\t\t ),\n\t\t 'select': OpenLayers.Util.applyDefaults(\n\t\t     {pointRadius: 30},\n\t\t     OpenLayers.Feature.Vector.style.select\n\t\t )\n\t});\n\t\n\tlayer1 = new OpenLayers.Layer.Vector(\"Layer 1\", {\n\t\tstyleMap: style\n\t});\n\n\tlayer1.addFeatures([\n\t\t new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(\"POINT(0 0)\"), {l:1}),\n\t\t new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(\"POINT(0 0)\"), {l:1}),\n\t\t new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(\"POINT(0 0)\"), {l:1}),\n\t\t new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(\"POINT(0 0)\"), {l:1})\n\t]);\n\n\tmap = new OpenLayers.Map({\n\t\tdiv: \"map\",\n\t\tallOverlays: true,\n\t\tlayers: [layer1],\n\t\tzoom: 6,\n\t\tcenter: [0, 0],\n\t\teventListeners: {\n            featureclick: logEvent,\n            nofeatureclick: logNoEvent\n\t\t}\n\t});\t\n}\n\nfunction logNoEvent(e) {\n\tlognoevt.push(e);\n}\n\nfunction logEvent(e) {\n\tlogevt.push(e);\t\n}\n\nfunction trigger(type, pxl) {\n\tvar map_position = OpenLayers.Util.pagePosition(element);\n\tmap.events.triggerEvent(type, {\n\t\txy: pxl, \n\t\tclientX: pxl.x + map_position[0], \n\t\tclientY: pxl.y + map_position[1], \n\t\twhich: 1  // which == 1 means left-click\n\t}); \t\n}\n\n// TESTS\n\nfunction test_onClick(t) {\n\tt.plan(2);\n\tlogevt = [];\n\tlognoevt = [];\n\tlonlat = new OpenLayers.LonLat(0,0);\n\tpixel = map.getPixelFromLonLat(lonlat);\n\n\ttrigger('mousedown', pixel);\n\ttrigger('mouseup', pixel);\n\t\n\tt.eq(logevt.length, 4, \"4 features hit\");\n    \n    trigger('mousedown', {x: 40, y: 40});\n    trigger('mouseup', {x: 40, y: 40});\n\tt.eq(lognoevt.length, 1, \"nofeatureclick fired for click outside features.\");\n}\n\n// END TESTS\n\n</script>\n</head>\n<body onload=\"init()\">\n<div id=\"map\" style=\"width: 300px; height: 150px; border: 1px solid black\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Events.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var map; \n    var a;\n    \n    function test_Events_constructor (t) {\n        t.plan(4);\n\n        var mapDiv = OpenLayers.Util.getElement('map');\n        var obj = {result: 0};\n\n        events = new OpenLayers.Events(obj, mapDiv);\n        t.ok( events instanceof OpenLayers.Events, \"new OpenLayers.Control returns object\" );\n        t.ok(events.object ==obj, \" 'object' property correctly set\");\n        t.ok(events.element == mapDiv, \" 'element' property correctly set\");\n        events.destroy();\n\n        // default/nulls\n        events = new OpenLayers.Events(null, null, null);\n        t.ok( events.listeners != null,\n              \"init of Events with null object/element/eventTypes still creates listeners array\" );\n        events.destroy();\n    }\n\n    function test_Events_register(t){\n        t.plan(4);\n\n        var ev = {\n            'object': {},\n            'extensionCount': {\n                'listenerA': 0,\n                'listenerB': 0\n            },\n            'listeners': {\n                'listenerA': { \n                    'push': function(options){\n                                gObjA = options.obj;\n                                gFuncA = options.func;\n                            }\n                },\n                'listenerB': { \n                    'push': function(options){\n                                gObjB = options.obj;\n                                gFuncB = options.func;\n                            }\n                }\n            }\n        };\n\n        var type = null;\n        var object = null;\n        var func = null;\n\n      //func null\n        gObjA = null; gFuncA = null; gObjB = null; gFuncB = null;\n        OpenLayers.Events.prototype.register.apply(ev, [type, object, func]);\n        t.ok((gObjA == null) && (gFuncA == null) && \n             (gObjB == null) && (gFuncB == null), \"no push called func null\"); \n\n      //valid func, type not in ev.eventTypes\n        func = function() {};\n        gObjA = null; gFuncA = null; gObjB = null; gFuncB = null;\n        OpenLayers.Events.prototype.register.apply(ev, [type, object, func]);\n        t.ok((gObjA == null) && (gFuncA == null) && \n             (gObjB == null) && (gFuncB == null), \"no push called func null\"); \n\n      //valid func, type in ev.eventTypes, null obj\n        type = 'listenerA';\n        gObjA = null; gFuncA = null; gObjB = null; gFuncB = null;\n        OpenLayers.Events.prototype.register.apply(ev, [type, object, func]);\n        t.ok((gObjA == ev.object) && (gFuncA == func) && \n             (gObjB == null) && (gFuncB == null), \"push called on listenerA's mock array when type passed in 'listenerA'. events.object taken since obj is null.\"); \n        \n      //valid func, type in ev.eventTypes, valid obj\n        type = 'listenerB';\n        object = {};\n        gObjA = null; gFuncA = null; gObjB = null; gFuncB = null;\n        OpenLayers.Events.prototype.register.apply(ev, [type, object, func]);\n        t.ok((gObjA == null) && (gFuncA == null) && \n             (gObjB == object) && (gFuncB == func), \"push called on listenerB's mock array when type passed in 'listenerB'.\"); \n        \n    }\n\n    function test_Events_register_unregister(t) {\n \n        t.plan(20);\n \n        var mapDiv = OpenLayers.Util.getElement('map');\n        var obj = {result: 0};\n        \n        events = new OpenLayers.Events(obj, mapDiv);\n        \n        var func = function () { this.result++ }\n        events.register( \"doThingA\", obj, func );\n\n        var listenerList = events.listeners[\"doThingA\"];\n        t.eq( listenerList.length, 1, \"register correctly adds to event.listeners\" );\n        t.ok( listenerList[0].obj == obj, \"obj property correctly registered\");\n        t.ok( listenerList[0].func == func, \"func property correctly registered\");\n\n        var func2 = function () { this.result-- }\n        events.register( \"doThingA\", obj, func2 );\n\n        var listenerList = events.listeners[\"doThingA\"];\n        t.eq( listenerList.length, 2, \"register correctly appends new callback to event.listeners[doThingA]\" );\n        t.ok( listenerList[1].obj == obj, \"obj property correctly registered\");\n        t.ok( listenerList[1].func == func2, \"func property correctly registered\");\n\n        var func3 = function () { this.result = this.result + 3; }\n        events.register( \"doThingA\", null, func3 );\n\n        var listenerList = events.listeners[\"doThingA\"];\n        t.eq( listenerList.length, 3, \"register correctly appends new callback to event.listeners[doThingA] even when obj passed in is null\" );\n        t.ok( listenerList[2].obj == obj, \"obj is correctly set to Events.object default when null is passed in.\");\n        t.ok( listenerList[2].func == func3, \"func property correctly registered\");\n\n        events.register( \"doThingA\", obj, null);\n\n        var listenerList = events.listeners[\"doThingA\"];\n        t.eq( listenerList.length, 3, \"register correctly does not append null callback to event.listeners[doThingA] even when obj passed in is null\" );\n\n        events.register(\"chicken\", obj, func);\n        t.eq(events.listeners[\"chicken\"].length, 1, \"register() allows listeners for any named event\");\n\n        events.unregister(\"chicken\", obj, func);\n        t.eq(events.listeners[\"chicken\"].length, 0, \"unregistering an event that is not in eventTypes list works\")\n\n        events.unregister(\"doThingA\", obj, null);\n        var listenerList = events.listeners[\"doThingA\"];\n        t.eq( listenerList.length, 3, \"trying to unregister a null callback does nothing -- but doesnt crash :-)\" );\n    \n        events.unregister(\"doThingA\", obj, func);\n        var found = false;\n        for (var i = 0; i < listenerList.length; i++) {\n            var listener = listenerList[i];\n            if (listener.obj == obj && listener.func == func) {\n                found = true;\n            }\n        }                \n        t.ok( (listenerList.length == 2) && !found, \"unregister correctly removes callback\" );\n\n        events.unregister(\"doThingA\", null, func3);\n        var found = false;\n        for (var i = 0; i < listenerList.length; i++) {\n            var listener = listenerList[i];\n            if (listener.obj == obj && listener.func == func) {\n                found = true;\n            }\n        }                \n        t.ok( (listenerList.length == 1) && !found, \"unregister correctly removes callback when no obj specified\" );\n        \n        var func4 = function () { this.result = \"chicken\"; }\n        events.unregister(\"doThingA\", obj, func4);\n        t.ok( (listenerList.length == 1), \"unregister does not bomb if you try to remove an unregistered callback\" );\n\n        var obj2 = { chicken: 151 };\n        events.unregister(\"doThingA\", obj2, func2);\n        t.ok( (listenerList.length == 1), \"unregister does not bomb or accidntally remove if you try to remove a valid callback on a valid event type, but with the wrong context object\" );\n\n        events.unregister(\"doThingA\", obj, null);\n        t.ok( (listenerList.length == 1), \"unregister does not bomb if you try to remove a null callback\" );\n\n        try {\n            events.unregister(\"asdf\", obj, func);\n            t.ok(\"unregistering for an event with no registered listeners works\");\n        } catch (err) {\n            t.fail(\"unregistering for an event with no registered listeners causes trouble: \" + err);\n        }\n        \n        events.register(\"buttonclick\", obj, func);\n        t.ok(events.extensions.buttonclick, \"buttonclick extension registered\");\n\n    }\n\n    function test_Events_remove(t) {\n\n        t.plan( 2 );\n \n        var mapDiv = OpenLayers.Util.getElement('map');\n        var obj = {result: 0};\n        \n        events = new OpenLayers.Events(obj, mapDiv);\n        \n        var func = function () { this.result++ }\n        var func2 = function () { this.result-- }\n        var func3 = function () { this.result = this.result + 3; }\n\n        events.register( \"doThingA\", obj, func );\n        events.register( \"doThingA\", obj, func2 );\n        events.register( \"doThingA\", null, func3 );\n\n        events.remove(\"doThingA\");\n\n        t.eq( events.listeners[\"doThingA\"].length, 0, \"remove() correctly clears the event listeners\" );\n\n        events.remove(\"chicken\");\n        t.ok( events.listeners[\"chicken\"] == null, \"remove on non-enabled event does not break or accidentally enable the event\");\n\n    }\n\n    function test_Events_triggerEvent(t) {\n    \n        t.plan(13);\n \n        var mapDiv = OpenLayers.Util.getElement('map');\n        var obj = {result: 0};\n        \n        events = new OpenLayers.Events(obj, mapDiv);\n        \n        \n        var func = function () { this.result++ }\n        events.register( \"doThingA\", obj, func );\n\n        events.triggerEvent(\"doThingA\", {});\n        t.eq( obj.result, 1, \"result is 1 after we call triggerEvent\" );\n        events.triggerEvent(\"doThingA\");\n        t.eq( obj.result, 2, \"result is 2 after we call triggerEvent with no event\" );\n\n        var funcB = function() { this.FUNK = \"B\"; return false; }\n        events.register( \"doThingA\", obj, funcB);\n\n        events.triggerEvent(\"doThingA\");\n        t.ok ((obj.result == 3) && (obj.FUNK == \"B\"), \"executing multiple callbacks works\")\n\n        var funcZ = function() { this.FUNK = \"Z\"; }\n        events.register( \"doThingA\", obj, funcZ);\n\n        events.triggerEvent(\"doThingA\");\n        t.ok ((obj.result == 4) && (obj.FUNK == \"B\"), \"executing multiple callbacks works, and when one returns false, it stops chain correctly\")\n\n\n        var func2 = function() { this.result = this.result + 10; }\n        events.register( \"doThingB\", null, func2);\n        \n        events.triggerEvent(\"doThingB\");\n        t.eq( obj.result, 14, \"passing a null object default gets set correctly\");\n        \n        //no specific t.ok for this one, but if it breaks, you will know it.\n        events.triggerEvent(\"chicken\");\n\n        events = new OpenLayers.Events(null, mapDiv);\n        \n        // a is global variable (context-irrelevant)\n        a = 0;\n        var func = function () { a = 5; }\n        events.register( \"doThingC\", null, func );\n        events.triggerEvent(\"doThingC\");\n\n        t.eq(a, 5, \"if Events has no object set and an event is registered also with no object, triggerEvent() calls it without trying to set the context to null\");\n        \n        // trigger events with additional arguments\n        events = new OpenLayers.Events();\n        var instance = {id: Math.random()};\n        var listener = function(obj) {\n            t.eq(this.id, instance.id,\n                 \"listener called with proper scope\");\n            t.eq(arguments.length, 1,\n                 \"listener called with a single argument\");\n            t.eq(typeof arguments, \"object\",\n                 \"listener called with an object\");\n            t.eq(obj.foo, evt.foo,\n                 \"foo property set on the layer\");\n        };\n        events.register(\"something\", instance, listener);        \n        var evt = {\n            id: Math.random(),\n            \"foo\": \"bar\"\n        };\n        events.triggerEvent(\"something\", evt);\n        events.unregister(\"something\", instance, listener);\n        \n        // test return from triggerEvent\n        var listener1 = function() {\n            return \"foo\";\n        }\n        var listener2 = function() {\n            return false;\n        }\n        var listener3 = function() {\n            t.fail(\"never call me again!\");\n        }\n        events.register(\"something\", instance, listener1);\n        var ret = events.triggerEvent(\"something\", evt);\n        t.eq(ret, \"foo\", \"correct return from single listener\");\n        \n        events.register(\"something\", instance, listener2);\n        ret = events.triggerEvent(\"something\", evt);\n        t.eq(ret, false, \"correct return for two listeners\");\n        \n        events.register(\"something\", instance, listener3);\n        ret = events.triggerEvent(\"something\", evt);\n        t.eq(ret, false, \"correct return for three listeners where second cancels\");\n        \n        events.unregister(\"something\", instance, listener1);\n        events.unregister(\"something\", instance, listener2);\n        events.unregister(\"something\", instance, listener3);\n    }\n\n    function test_Events_handleBrowserEvent(t) {\n        t.plan(8);\n        var events = new OpenLayers.Events({}, null);\n        events.on({'sometouchevent': function() {}});\n\n        // this test verifies that when handling a touch event we correctly\n        // set clientX and clientY in the event object \n        var evt = {type: 'sometouchevent',\n                   touches: [{clientX: 1, clientY: 1}, {clientX: 2, clientY: 2}]\n                  };\n        events.handleBrowserEvent(evt);\n        t.eq(evt.clientX, 1.5, \"evt.clientX value is correct\");\n        t.eq(evt.clientY, 1.5, \"evt.clientY value is correct\");\n        \n        // test bug where clientX/clientY includes scroll offset\n        window.olMockWin = {\n            pageXOffset: 10,\n            pageYOffset: 20\n        };\n        evt = {type: 'sometouchevent',\n               touches: [{\n                   clientX: 11,\n                   clientY: 21,\n                   pageX: 0,\n                   pageY: 0\n               }]\n              };\n        events.handleBrowserEvent(evt);\n        t.eq(evt.clientX, 1, \"evt.clientX value is correct\");\n        t.eq(evt.clientY, 1, \"evt.clientY value is correct\");\n        \n        \n        // test bug where clientX/clientY have negative values\n        evt = {\n            type: 'sometouchevent',\n            touches: [{\n                clientX: -412,\n                clientY: -1005,\n                pageX: 11,\n                pageY: 21\n            }]\n        };\n        events.handleBrowserEvent(evt);\n        t.eq(evt.clientX, 1, \"evt.clientX value is correct\");\n        t.eq(evt.clientY, 1, \"evt.clientY value is correct\");\n        \n        window.olMockWin = {\n            pageXOffset: 11,\n            pageYOffset: 299\n        };\n        evt = {\n            type: 'sometouchevent',\n                touches: [{\n                clientX: 223,\n                clientY: 119,\n                pageX: 242,\n                pageY: 623\n            }]\n        };\n        events.handleBrowserEvent(evt);\n        t.eq(evt.clientX, 231, \"evt.clientX value is correct\");\n        t.eq(evt.clientY, 324, \"evt.clientY value is correct\");\n        \n        window.olMockWin = undefined;\n    }\n    \n    function test_Events_attachToElement(t) {\n        t.plan(3);\n        var events = new OpenLayers.Events({}, null);\n        var element = document.createElement(\"div\");\n        events.attachToElement(element);\n        t.ok(events.eventHandler, \"eventHandler method bound\");\n        t.ok(events.clearMouseListener, \"clearMouseListener method bound\");\n        t.ok(events.element === element, \"element set\");\n    }\n\n    function test_Events_destroy (t) {\n        t.plan(2);\n\n        var div   = OpenLayers.Util.getElement('test');\n        var obj   = {};\n        var events = new OpenLayers.Events(obj, div);\n        var touchModel = events.getTouchModel();\n        // +5 because of additional binding to pointer events (down, up, move, out)\n        // +1 because of blocking dragstart in attachToElement()\n        var eventsOffset = ((touchModel === events.TOUCH_MODEL_MSPOINTER) ||\n                (touchModel === events.TOUCH_MODEL_POINTER)) ? 5 : 1;\n        t.eq(OpenLayers.Event.observers[div._eventCacheID].length,\n             OpenLayers.Events.prototype.BROWSER_EVENTS.length + eventsOffset);\n             \n        events.destroy();\n        events = null;\n        t.eq(OpenLayers.Event.observers[\"test\"], null,\n             \"destruction removes the event observer from hash\");\n    }\n    \n    function test_Event(t) {\n        t.plan(24);\n        \n        var div   = OpenLayers.Util.getElement('test');\n        var name = \"mouseover\";\n        var func = function() {};\n\n      //1st elem 1st listener        \n        OpenLayers.Event.observe(div, name, func);\n\n        var cacheID = div._eventCacheID;\n        t.ok(cacheID, \"element given new cache id\");\n        \n        var elementObservers = OpenLayers.Event.observers[cacheID];\n        \n        t.ok(elementObservers, \"new cache bucket made for event\");\n        t.eq(elementObservers.length, 1, \"one listener registered\");        \n        \n        var listener = elementObservers[0];\n        \n        t.ok(listener.element == div, \"element registered\");\n        t.eq(listener.name, name, \"name registered\");\n        t.ok(listener.observer == func, \"function registered\");\n        t.eq(listener.useCapture, false, \"useCapture defaults to false\");\n\n      //1st elem 2nd listener        \n        name = \"mouseout\";\n        var newFunc = function() {};\n      \n        OpenLayers.Event.observe(div, name, newFunc, true);\n        var newCacheID = div._eventCacheID;\n        t.eq(newCacheID, cacheID, \"element's cache id not overridden\");\n        \n        t.eq(elementObservers.length, 2, \"listener added to existing bucket\");        \n        \n        var listener = elementObservers[1];\n        \n        t.ok(listener.element == div, \"element registered\");\n        t.eq(listener.name, name, \"name registered\");\n        t.ok(listener.observer == newFunc, \"function registered\");\n        t.eq(listener.useCapture, true, \"useCapture correctly registered\");\n\n      //2st elem 1st listener        \n        div = OpenLayers.Util.getElement('test2'); \n        OpenLayers.Event.observe(div, name, func);\n\n        var cacheID = div._eventCacheID;\n        t.ok(cacheID, \"new element given new cache id\");\n        t.ok(cacheID != newCacheID, \"new cache id is unique\");\n        \n        elementObservers = OpenLayers.Event.observers[cacheID];\n        \n        t.ok(elementObservers, \"new cache bucket made for event\");\n        t.eq(elementObservers.length, 1, \"one listener registered\");        \n        \n        var listener = elementObservers[0];\n        \n        t.ok(listener.element == div, \"element registered\");\n        t.eq(listener.name, name, \"name registered\");\n        t.ok(listener.observer == func, \"function registered\");\n        t.eq(listener.useCapture, false, \"useCapture defaults to false\");\n\n      //stopObservingElement by element\n        OpenLayers.Event.stopObservingElement(div);\n        elementObservers = OpenLayers.Event.observers[cacheID];\n        t.ok(elementObservers == null, \"stopObservingElement by elem works\");\n\n      //stopObservingElement by id\n        OpenLayers.Event.stopObservingElement(\"test\");\n        elementObservers = OpenLayers.Event.observers[newCacheID];\n        t.ok(elementObservers == null, \"stopObservingElement by id works\");\n\n\n      //unloadCache by element\n        OpenLayers.Event.observe(div, name, func);\n        \n        OpenLayers.Event.unloadCache();\n\n        elementObservers = OpenLayers.Event.observers[cacheID];\n        t.ok(elementObservers == null, \"stopObservingElement by elem works\");\n\n        \n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n    <div id=\"test\"></div>\n    <div id=\"test2\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Extras.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    var map;\n    \n    // Ensure that we continue to work if silly Javascript frameworks\n    // extend object.\n    Object.prototype.foo = function() { }\n    function test_Events_Object_Extension(t) {\n        t.plan(1)\n        map = new OpenLayers.Map(\"map\");\n        t.ok(true, \"Map created if object prototype is extended.\");\n    }\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 600px; height: 300px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Feature/Vector.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var map; \n    var feature; \n    \n    function test_Feature_Vector_constructor(t) {\n        t.plan(3);\n        \n        var geometry = new OpenLayers.Geometry();\n        geometry.id = Math.random();\n        var style = {foo: \"bar\"};\n        var attributes = {bar: \"foo\"};\n\n        feature = new OpenLayers.Feature.Vector(geometry, attributes, style);\n\n        t.ok(feature instanceof OpenLayers.Feature.Vector,\n             \"new OpenLayers.Feature.Vector returns Feature.Vector object\" );\n        t.eq(feature.attributes, attributes,\n             \"attributes property set properly\" );\n        t.eq(feature.geometry.id, geometry.id,\n             \"geometry.property set properly\" );\n    }\n    \n    function test_Feature_onScreen(t) {\n        t.plan(6);\n        var line = new OpenLayers.Geometry.LineString([\n            new OpenLayers.Geometry.Point(0, 0),\n            new OpenLayers.Geometry.Point(10, 20)\n        ]);\n        var feature = new OpenLayers.Feature.Vector(line);\n        feature.layer = {\n            map: {\n                getExtent: function() {\n                    return new OpenLayers.Bounds(5, 5, 10, 10);\n                }\n            }\n        };\n        t.eq(feature.onScreen(), true,\n             \"intersecting feature returns true for intersection\");\n        t.eq(feature.onScreen(true), true,\n             \"intersecting feature returns true for bounds only\");\n        \n        // move the line so only the bounds intersects\n        line.move(0, 5);\n        t.eq(feature.onScreen(), false,\n             \"bounds-only feature returns false for intersection\");\n        t.eq(feature.onScreen(true), true,\n             \"bounds-only feature returns true for bounds only\");\n\n        // move the line so bounds does not intersect\n        line.move(0, 10);\n        t.eq(feature.onScreen(), false,\n             \"off-screen feature returns false for intersection\");\n        t.eq(feature.onScreen(true), false,\n             \"off-screen feature returns false for bounds only\");\n        \n    }\n    \n    function test_Feature_getVisibility(t) {\n        t.plan(5);\n        var feature = new OpenLayers.Feature.Vector();\n        feature.layer = {\n            getVisibility: function() {return true}\n        };\n\n        t.ok(feature.getVisibility(),\n             \"returns true in a not specific case\");\n\n        feature.style = {display: 'none'};\n        t.eq(feature.getVisibility(), false,\n             \"returns false when feature style display property is set to 'none'\");\n\n        feature.style = null;\n        feature.layer.styleMap = {\n            createSymbolizer: function() {\n                return {display: 'none'}\n            }\n        }\n        t.eq(feature.getVisibility(), false,\n             \"returns false when layer styleMap is configured so that the feature\" +\n              \"should not be displayed\");\n\n        delete feature.layer.styleMap;\n        feature.layer.getVisibility = function() {return false}\n        t.eq(feature.getVisibility(), false,\n             \"returns false when layer it belongs to is not visible\");\n        \n        feature.layer = null;\n        t.eq(feature.getVisibility(), false,\n             \"returns false when it doesn't belong to any layer\");\n    }\n    \n    function test_Feature_Vector_clone(t) {\n        t.plan(6);\n\n        var geometry = new OpenLayers.Geometry.Point(Math.random(),\n                                                     Math.random());\n        var style = {foo: \"bar\"};\n        var attributes = {bar: \"foo\"};\n\n        feature = new OpenLayers.Feature.Vector(geometry, attributes, style);\n        var clone = feature.clone();\n\n        t.ok(clone instanceof OpenLayers.Feature.Vector,\n             \"new OpenLayers.Feature.Vector returns Feature.Vector object\");\n        t.eq(clone.attributes, attributes,\n             \"attributes property set properly\");\n        t.eq(clone.style, style,\n             \"style property set properly\");\n        t.eq(clone.geometry.x, geometry.x,\n             \"geometry.x property set properly\");\n        t.eq(clone.geometry.y, geometry.y,\n             \"geometry.y property set properly\");\n\n        feature = new OpenLayers.Feature.Vector();\n        clone = feature.clone();\n        t.ok(clone instanceof OpenLayers.Feature.Vector,\n             \"clone can clone geometry-less features\");\n    }\n        \n    function test_Feature_Vector_move(t) {\n        t.plan(3);\n\n        var oldx = 26;\n        var oldy = 14;\n        var newx = 6;\n        var newy = 4;\n        var res = 10;\n\n        var geometry = new OpenLayers.Geometry.Point(oldx,\n                                                     oldy);\n\n        var drawn = false;\n\n        feature = new OpenLayers.Feature.Vector(geometry);\n\n        feature.layer = {\n            getViewPortPxFromLonLat : function(lonlat){\n                return new OpenLayers.Pixel(lonlat.lon,lonlat.lat);\n            },\n            map: {\n                getResolution: function(){\n                    return res;\n                }\n            },\n            drawFeature: function(){\n                drawn = true;\n            }\n        }\n\n        var pixel = new OpenLayers.Pixel(newx,newy)\n\n        feature.move(pixel);\n\n        geometry = feature.geometry;\n\n        t.ok(drawn, \"The feature is redrawn after the move\");\n        t.eq(geometry.x, res * (newx - oldx) + oldx, \"New geometry has proper x coordinate\");\n        t.eq(geometry.y, res * (oldy - newy) + oldy, \"New geometry has proper y coordinate\");\n    }\n        \n\n  </script>\n</head>\n<body>\n  <div id=\"map\" style=\"width: 500px; height: 300px;\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Feature.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var map; \n    var feature, layer; \n    \n    function test_Feature_constructor (t) {\n        t.plan( 6 );\n\n        var layer = {};\n        var lonlat = new OpenLayers.LonLat(2,1);\n        var iconURL = 'http://boston.openguides.org/features/ORANGE.png';\n        var iconSize = new OpenLayers.Size(12, 17);\n        var data =  { iconURL: iconURL,\n                      iconSize: iconSize \n                    };\n        \n        feature = new OpenLayers.Feature(layer, lonlat, data);\n\n        t.ok( feature instanceof OpenLayers.Feature, \"new OpenLayers.Feature returns Feature object\" );\n        t.eq( feature.layer, layer, \"feature.layer set correctly\" );\n        t.ok(OpenLayers.String.startsWith(feature.id, \"OpenLayers_Feature_\"),\n             \"feature.id set correctly\");\n        t.ok( feature.lonlat.equals(lonlat), \"feature.lonlat set correctly\" );\n        t.eq( feature.data.iconURL, iconURL, \"feature.data.iconURL set correctly\" );\n        t.ok( feature.data.iconSize.equals(iconSize), \"feature.data.iconSize set correctly\" );\n    }\n    \n    function test_Feature_createPopup (t) {\n        t.plan(3);\n        var layer = {};\n        var lonlat = new OpenLayers.LonLat(2,1);\n        var iconURL = 'http://boston.openguides.org/features/ORANGE.png';\n        var iconSize = new OpenLayers.Size(12, 17);\n        var data =  { iconURL: iconURL,\n                      iconSize: iconSize,\n                      'overflow':'auto'\n                    };\n        \n        feature = new OpenLayers.Feature(layer, lonlat, data);\n        popup = feature.createPopup(); \n        //Safari 3 separates style overflow into overflow-x and overflow-y\n        var prop = (OpenLayers.BROWSER_NAME == 'safari') ? 'overflowX' : 'overflow';\n        t.eq(popup.contentDiv.style[prop], \"auto\", 'overflow on popup is correct');\n        t.ok( popup instanceof OpenLayers.Popup.Anchored, \"popup is a Popup.Anchored by default\");\n        feature.destroyPopup();\n        \n        feature.popupClass = OpenLayers.Popup.FramedCloud;\n        popup = feature.createPopup(); \n        t.ok( popup instanceof OpenLayers.Popup.FramedCloud, \"setting feature.popupClass works\");\n    }    \n    function test_Feature_createMarker (t) {\n        t.plan(1);\n        t.ok(true);\n/*\n\n        t.plan( 11 );\n        feature = new OpenLayers.Feature(\"myfeature\", new OpenLayers.LonLat(2,1), \n               {\n                iconURL:'http://boston.openguides.org/features/ORANGE.png',\n                iconW: 12,\n                iconH: 17\n               });\n        layer = new OpenLayers.Layer.Markers('Marker Layer');\n        t.ok( feature instanceof OpenLayers.Feature, \"new OpenLayers.Feature returns Feature object\" );\n        t.ok( layer instanceof OpenLayers.Layer.Markers, \"Layer is a marker layer\" );\n        feature.createMarker(layer);\n        \n        t.ok( feature.marker instanceof OpenLayers.Marker, \n              \"createMarker sets a marker property to a marker\" );\n        t.ok( layer.markers[0] === feature.marker, \n              \"First marker in layer is the feature marker\" );\n        \n        t.ok( feature.marker.lonlat instanceof OpenLayers.LonLat, \n              \"createMarker sets a marker lontlat property to a lonlat\" );\n        t.ok( layer.markers[0].lonlat === feature.lonlat, \n              \"First marker in the layer matches feature lonlat\" );\n        \n        t.ok( feature.marker.icon instanceof OpenLayers.Icon, \n              \"createMarker sets a marker icon property to an icon\" );\n        \n        t.eq( feature.marker.icon.url, \n              \"http://boston.openguides.org/features/ORANGE.png\", \n              \"createMarker sets marker url correctly\" );\n       \n        var map = new OpenLayers.Map('map');\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0),0);\n        t.ok( map.layers[0] == layer,\n              \"Marker layer added to map okay.\" );\n        if (!isMozilla)\n            t.ok( true, \"skipping element test outside of Mozilla\");\n        else\n            t.ok( map.layers[0].div.firstChild instanceof HTMLImageElement,\n                  \"layer div firstChild is an image\" );\n        t.eq( map.layers[0].div.firstChild.src,\n              \"http://boston.openguides.org/features/ORANGE.png\", \n              \"Layer div img contains correct url\" );\n*/\n    }\n    \n    function test_Feature_onScreen(t) {\n        t.plan( 2 );\n\n        var map = new OpenLayers.Map(\"map\");\n\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        var wms = new OpenLayers.Layer.WMS(name, url);\n\n        map.addLayer(wms);\n\n        var layer = new OpenLayers.Layer(\"foo\");\n        map.addLayer(layer);\n        \n        map.zoomToExtent(new OpenLayers.Bounds(-50,-50,50,50));\n\n        //onscreen feature\n        var feature1 = new OpenLayers.Feature(layer, \n                                              new OpenLayers.LonLat(0,0));\n        t.ok( feature1.onScreen(), \"feature knows it's onscreen\" );\n\n        //onscreen feature\n        var feature2 = new OpenLayers.Feature(layer, \n                                              new OpenLayers.LonLat(100,100));\n        t.ok( !feature2.onScreen(), \"feature knows it's offscreen\" );\n    }\n\n    function test_Feature_createPopup_2(t) {\n        t.plan(11);\n\n    //no lonlat        \n        var f = {\n            'popup': null\n        };\n        \n        var ret = OpenLayers.Feature.prototype.createPopup.apply(f, []);\n        t.ok((ret == f.popup) && (f.popup == null), \"if no 'lonlat' set on feature, still returns reference to this.popup (though it is null)\");\n\n\n\n        f.popupClass = OpenLayers.Class({\n            initialize: function(id, lonlat, size, contentHTML, anchor, closeBox) {\n                t.eq(id, \"Campion_popup\", \"correctly generates new popup id from feature's id\");\n                t.eq(lonlat, f.lonlat, \"correctly passes feature's lonlat to popup constructor\");\n                t.eq(size, f.data.popupSize, \"correctly passes feature's data.popupSize to popup constructor\");\n                t.eq(contentHTML, f.data.popupContentHTML, \"correctly passes feature's data.popupContentHTML to popup constructor\");\n                t.eq(anchor, g_ExpectedAnchor, \"passes correct anchor to popup constructor\");\n                t.eq(closeBox, g_CloseBox, \"correctly relays closeBox argument to popup constructor\");\n            }\n        });\n        \n\n    //valid lonlat but no anchor    \n        f.popup = null;\n        \n        f.id = \"Campion\";\n        f.lonlat = {};\n        f.data = {\n            'popupSize': {},\n            'popupContentHTML': {}\n        };\n        g_ExpectedAnchor = null;\n        g_CloseBox = {};\n\n        ret = OpenLayers.Feature.prototype.createPopup.apply(f, [g_CloseBox]);\n        \n        t.ok((ret == f.popup) && (f.popup != null), \"a valid popup has been set and returned\")\n        t.ok( f.popup.feature == f, \"popup's 'feature' property correctly set\");\n\n    \n    //valid lonlat with anchor    \n\n        f.marker = {\n            'icon': {}\n        };\n        g_ExpectedAnchor = f.marker.icon;\n        ret = OpenLayers.Feature.prototype.createPopup.apply(f, [g_CloseBox]);\n        t.ok((ret == f.popup) && (f.popup != null), \"a valid popup has been set and returned\")\n        t.ok( f.popup.feature == f, \"popup's 'feature' property correctly set\");\n    }\n\n    function test_Feature_destroyPopup(t) {\n        t.plan(2);\n\n        var f = {\n            'popup': {\n                'feature': {},\n                'destroy': function() {\n                    t.ok(true, \"default destroyPopup() calls popup.destroy\");\n                }\n            }\n        };\n        \n        OpenLayers.Feature.prototype.destroyPopup.apply(f, []);\n        t.ok(f.popup == null, \"popup property nullified on destroy\");\n    }\n\n  </script>\n</head>\n<body>\n  <div id=\"map\" style=\"width: 500px; height: 300px;\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Filter/Comparison.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_initialize(t) { \n        t.plan(3); \n         \n        var options = {'foo': 'bar'}; \n        var filter = new OpenLayers.Filter.Comparison(options); \n        t.ok(filter instanceof OpenLayers.Filter.Comparison, \n             \"new OpenLayers.Filter.Comparison returns object\" ); \n        t.eq(filter.foo, \"bar\", \"constructor sets options correctly\"); \n        t.eq(typeof filter.evaluate, \"function\", \"filter has an evaluate function\"); \n    }\n\n    function test_destroy(t) {\n        t.plan(1);\n        \n        var filter = new OpenLayers.Filter.Comparison();\n        filter.destroy();\n        t.eq(filter.symbolizer, null, \"symbolizer hash nulled properly\");\n    }\n    \n    function test_value2regex(t) {\n        t.plan(4);\n        \n        var filter = new OpenLayers.Filter.Comparison({\n                property: \"foo\",\n                value: \"*b?r\\\\*\\\\?*\",\n                type: OpenLayers.Filter.Comparison.LIKE});\n        filter.value2regex(\"*\", \"?\", \"\\\\\");\n        t.eq(filter.value, \".*b.r\\\\*\\\\?.*\", \"Regular expression generated correctly.\");\n        \n        filter.value = \"%b.r!%!.%\";\n        filter.value2regex(\"%\", \".\", \"!\");\n        t.eq(filter.value, \".*b.r\\\\%\\\\..*\", \"Regular expression with different wildcard and escape chars generated correctly.\");\n    \n        filter.value = \"!!\";\n        filter.value2regex();\n        t.eq(filter.value, \"\\\\!\", \"!! successfully unescaped to \\\\!\");\n        \n        // Big one.\n        filter.value = \"!!c!!!d!e\";\n        filter.value2regex();\n        t.eq(filter.value, \"\\\\!c\\\\!\\\\d\\\\e\", \"!!c!!!d!e successfully unescaped to \\\\!c\\\\!\\\\d\\\\e\");\n    }\n    \n    function test_regex2value(t) {\n        t.plan(8);\n        \n        function r2v(regex) {\n            return OpenLayers.Filter.Comparison.prototype.regex2value.call(\n                {value: regex}\n            );\n        }\n        \n        t.eq(r2v(\"foo\"), \"foo\", \"doesn't change string without special chars\");\n        t.eq(r2v(\"foo.*foo\"), \"foo*foo\", \"wildCard replaced\");\n        t.eq(r2v(\"foo.foo\"), \"foo.foo\", \"singleChar replaced\");\n        t.eq(r2v(\"foo\\\\\\\\foo\"), \"foo\\\\foo\", \"escape removed\");\n        t.eq(r2v(\"foo!foo\"), \"foo!!foo\", \"escapes !\");\n        t.eq(r2v(\"foo\\\\*foo\"), \"foo!*foo\", \"replaces escape on *\");\n        t.eq(r2v(\"foo\\\\.foo\"), \"foo!.foo\", \"replaces escape on .\");\n        t.eq(r2v(\"foo\\\\\\\\.foo\"), \"foo\\\\.foo\", \"unescapes only \\\\ before .\");\n        \n    }\n    \n    function test_evaluate(t) {\n        \n        var cases = [{\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.BETWEEN,\n                property: \"area\",\n                lowerBoundary: 1000,\n                upperBoundary: 4999\n            }),\n            context: {area: 999},\n            expect: false\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.BETWEEN,\n                property: \"area\",\n                lowerBoundary: 1000,\n                upperBoundary: 4999\n            }),\n            context: {area: 1000},\n            expect: true\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.BETWEEN,\n                property: \"area\",\n                lowerBoundary: 1000,\n                upperBoundary: 4999\n            }),\n            context: {area: 4999},\n            expect: true\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.BETWEEN,\n                property: \"area\",\n                lowerBoundary: 1000,\n                upperBoundary: 4999\n            }),\n            context: {area: 5000},\n            expect: false\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.BETWEEN,\n                property: \"area\",\n                lowerBoundary: 1000,\n                upperBoundary: 4999\n            }),\n            context: {area: 999},\n            expect: false\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                property: \"prop\",\n                value: \"Foo\"\n            }),\n            context: {prop: \"Foo\"},\n            expect: true\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                property: \"prop\",\n                value: \"Foo\"\n            }),\n            context: {prop: \"foo\"},\n            expect: false\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                matchCase: true,\n                property: \"prop\",\n                value: \"Foo\"\n            }),\n            context: {prop: \"foo\"},\n            expect: false\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,\n                property: \"prop\",\n                value: \"foo\"\n            }),\n            context: {prop: \"FOO\"},\n            expect: true\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,\n                matchCase: true,\n                property: \"prop\",\n                value: \"foo\"\n            }),\n            context: {prop: \"FOO\"},\n            expect: true\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,\n                matchCase: false,\n                property: \"prop\",\n                value: \"foo\"\n            }),\n            context: {prop: \"FOO\"},\n            expect: false\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.IS_NULL,\n                property: \"prop\"\n            }),\n            context: {prop: null},\n            expect: true\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.IS_NULL,\n                property: \"prop\"\n            }),\n            context: {},\n            expect: false\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.IS_NULL,\n                property: \"prop\"\n            }),\n            context: {prop: \"foo\"},\n            expect: false\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.IS_NULL,\n                property: \"prop\"\n            }),\n            context: {prop: 0},\n            expect: false\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.LIKE,\n                property: \"prop\",\n                value: \".+\"\n            }),\n            context: {prop: \"FOO\"},\n            expect: true\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.LIKE,\n                property: \"prop\",\n                value: \".+\"\n            }),\n            context: {},\n            expect: false\n        }];\n        \n        t.plan(cases.length);\n        \n        var c;\n        for(var i=0; i<cases.length; ++i) {\n            c = cases[i];\n            t.eq(c.filter.evaluate(c.context), c.expect, \"case \" + i + \": \" + c.filter.type);\n        }\n        \n    }\n\n    function test_evaluate_feature(t) {\n        \n        var cases = [{\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.BETWEEN,\n                property: \"area\",\n                lowerBoundary: 1000,\n                upperBoundary: 4999\n            }),\n            context: new OpenLayers.Feature.Vector(null, {area: 999}),\n            expect: false\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.BETWEEN,\n                property: \"area\",\n                lowerBoundary: 1000,\n                upperBoundary: 4999\n            }),\n            context: new OpenLayers.Feature.Vector(null, {area: 1000}),\n            expect: true\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.BETWEEN,\n                property: \"area\",\n                lowerBoundary: 1000,\n                upperBoundary: 4999\n            }),\n            context: new OpenLayers.Feature.Vector(null, {area: 4999}),\n            expect: true\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.BETWEEN,\n                property: \"area\",\n                lowerBoundary: 1000,\n                upperBoundary: 4999\n            }),\n            context: new OpenLayers.Feature.Vector(null, {area: 5000}),\n            expect: false\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.BETWEEN,\n                property: \"area\",\n                lowerBoundary: 1000,\n                upperBoundary: 4999\n            }),\n            context: new OpenLayers.Feature.Vector(null, {area: 999}),\n            expect: false\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                property: \"prop\",\n                value: \"Foo\"\n            }),\n            context: new OpenLayers.Feature.Vector(null, {prop: \"Foo\"}),\n            expect: true\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                property: \"prop\",\n                value: \"Foo\"\n            }),\n            context: new OpenLayers.Feature.Vector(null, {prop: \"foo\"}),\n            expect: false\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                matchCase: true,\n                property: \"prop\",\n                value: \"Foo\"\n            }),\n            context: new OpenLayers.Feature.Vector(null, {prop: \"foo\"}),\n            expect: false\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,\n                property: \"prop\",\n                value: \"foo\"\n            }),\n            context: {prop: \"FOO\"},\n            expect: true\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,\n                matchCase: true,\n                property: \"prop\",\n                value: \"foo\"\n            }),\n            context: new OpenLayers.Feature.Vector(null, {prop: \"FOO\"}),\n            expect: true\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,\n                matchCase: false,\n                property: \"prop\",\n                value: \"foo\"\n            }),\n            context: new OpenLayers.Feature.Vector(null, {prop: \"FOO\"}),\n            expect: false\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.IS_NULL,\n                property: \"prop\"\n            }),\n            context: new OpenLayers.Feature.Vector(null, {prop: null}),\n            expect: true\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.IS_NULL,\n                property: \"prop\"\n            }),\n            context: new OpenLayers.Feature.Vector(null, {}),\n            expect: false\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.IS_NULL,\n                property: \"prop\"\n            }),\n            context: new OpenLayers.Feature.Vector(null, {prop: \"foo\"}),\n            expect: false\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.IS_NULL,\n                property: \"prop\"\n            }),\n            context: new OpenLayers.Feature.Vector(null, {prop: 0}),\n            expect: false\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.LIKE,\n                property: \"prop\",\n                value: \".+\"\n            }),\n            context: new OpenLayers.Feature.Vector(null, {prop: \"FOO\"}),\n            expect: true\n        }, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.LIKE,\n                property: \"prop\",\n                value: \".+\"\n            }),\n            context: new OpenLayers.Feature.Vector(null, {}),\n            expect: false\n        }];\n        \n        t.plan(cases.length);\n\n        var c;\n        for(var i=0; i<cases.length; ++i) {\n            c = cases[i];\n            t.eq(c.filter.evaluate(c.context), c.expect, \"case \" + i + \": \" + c.filter.type);\n        }\n        \n    }\n        \n    function test_clone(t) {\n        \n        t.plan(3);\n        \n        var filter = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.EQUAL_TO,\n            property: \"prop\",\n            value: \"val\"\n        });\n        \n        var clone = filter.clone();\n        \n        // modify the original\n        filter.type = OpenLayers.Filter.Comparison.NOT_EQUAL_TO;\n        \n        t.eq(clone.type, OpenLayers.Filter.Comparison.EQUAL_TO, \"clone has proper type\");\n        t.eq(clone.property, \"prop\", \"clone has proper property\");\n        t.eq(clone.value, \"val\", \"clone has proper value\");\n        \n        filter.destroy();\n\n    }\n\n\n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Filter/FeatureId.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_initialize(t) { \n        t.plan(3); \n         \n        var options = {'foo': 'bar'}; \n        var filter = new OpenLayers.Filter.FeatureId(options); \n        t.ok(filter instanceof OpenLayers.Filter.FeatureId, \n             \"new OpenLayers.Filter.FeatureId returns object\" ); \n        t.eq(filter.foo, \"bar\", \"constructor sets options correctly\"); \n        t.eq(typeof filter.evaluate, \"function\", \"filter has an evaluate function\"); \n    }\n\n    function test_destroy(t) {\n        t.plan(1);\n        \n        var filter = new OpenLayers.Filter.FeatureId();\n        filter.destroy();\n        t.eq(filter.symbolizer, null, \"symbolizer hash nulled properly\");\n    }\n    \n    function test_evaluate(t) {\n        t.plan(3);\n        \n        var filter = new OpenLayers.Filter.FeatureId(\n                {fids: [\"fid_1\", \"fid_3\"]});\n\n        var filterResults = {\n                \"fid_1\" : true,\n                \"fid_2\" : false,\n                \"fid_3\" : true};\n        for (var i in filterResults) {\n            var feature = new OpenLayers.Feature.Vector();\n            feature.fid = i;\n            var result = filter.evaluate(feature);\n            t.eq(result, filterResults[i], \"feature \"+i+\" evaluates to \"+result.toString()+\" correctly.\");\n            feature.destroy();\n        }\n    }\n\n    function test_clone(t) {\n        \n        t.plan(1);\n        \n        var filter = new OpenLayers.Filter.FeatureId({\n            fids: [1, 2, 3]\n        });\n        \n        var clone = filter.clone();\n        \n        // modify the original\n        filter.fids.push(4);\n        \n        t.eq(clone.fids.length, 3, \"clone has proper fids length\");\n        \n        filter.destroy();\n\n    }\n\n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Filter/Logical.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_initialize(t) { \n        t.plan(3); \n         \n        var options = {'foo': 'bar'}; \n        var filter = new OpenLayers.Filter.Logical(options); \n        t.ok(filter instanceof OpenLayers.Filter.Logical, \n             \"new OpenLayers.Filter.Logical returns object\" ); \n        t.eq(filter.foo, \"bar\", \"constructor sets options correctly\"); \n        t.eq(typeof filter.evaluate, \"function\", \"filter has an evaluate function\"); \n    }\n\n    function test_destroy(t) {\n        t.plan(1);\n        \n        var filter = new OpenLayers.Filter.Logical();\n        filter.destroy();\n        t.eq(filter.filters, null, \"filters array nulled properly\");\n    }\n    \n    function test_evaluate(t) {\n        t.plan(1);\n        \n        var filter = new OpenLayers.Filter.Logical({\n                type: OpenLayers.Filter.Logical.NOT});\n        filter.filters.push(new OpenLayers.Filter());\n        \n        var feature = new OpenLayers.Feature.Vector();\n\n        t.eq(filter.evaluate(feature.attributes), false,\n                \"feature evaluates to false correctly.\");\n    }\n\n    function test_evaluate_feature(t) {\n        t.plan(6);\n        \n        var feature = new OpenLayers.Feature.Vector(null, {\n            pop: 200,\n            name: \"foo\"\n        });\n        \n        var smallPop = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.LESS_THAN,\n            property: \"pop\",\n            value: 120\n        });\n        \n        var bigPop = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.GREATER_THAN,\n            property: \"pop\",\n            value: 120\n        });\n        \n        var namedFoo = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.EQUAL_TO,\n            property: \"name\",\n            value: \"foo\"\n        });\n        \n        var filter;\n        \n        // test simple not\n        filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.NOT,\n            filters: [smallPop]\n        });\n        t.eq(filter.evaluate(feature), true, \"not smallPop\");\n\n        filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.NOT,\n            filters: [bigPop]\n        });\n        t.eq(filter.evaluate(feature), false, \"not bigPop\");\n\n        // test or\n        filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.OR,\n            filters: [smallPop, namedFoo]\n        });\n        t.eq(filter.evaluate(feature), true, \"smallPop or namedFoo\");\n\n        filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.OR,\n            filters: [bigPop, namedFoo]\n        });\n        t.eq(filter.evaluate(feature), true, \"bigPop or namedFoo\");\n\n        // test and\n        filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.AND,\n            filters: [smallPop, namedFoo]\n        });\n        t.eq(filter.evaluate(feature), false, \"smallPop and namedFoo\");\n\n        filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.AND,\n            filters: [bigPop, namedFoo]\n        });\n        t.eq(filter.evaluate(feature), true, \"bigPop and namedFoo\");\n\n    }\n\n    function test_clone(t) {\n        \n        t.plan(2);\n        \n        var filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.AND,\n            filters: [\n                new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                    property: \"prop1\",\n                    value: \"val1\"\n                }),\n                new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,\n                    property: \"prop2\",\n                    value: \"val2\"\n                })\n            ]\n        });\n\n        var clone = filter.clone();\n        \n        // modify the original\n        filter.type = OpenLayers.Filter.Logical.OR;\n        filter.filters[0].value = \"nada\";\n        \n        t.eq(clone.type, OpenLayers.Filter.Logical.AND, \"clone has proper type\");\n        t.eq(clone.filters[0].value, \"val1\", \"clone has cloned child filters\");\n        \n        filter.destroy();\n\n    }\n    \n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Filter/Spatial.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_constructor(t) { \n        t.plan(3); \n         \n        var options = {'foo': 'bar'}; \n        var filter = new OpenLayers.Filter.Spatial(options); \n        t.ok(filter instanceof OpenLayers.Filter.Spatial, \n             \"new OpenLayers.Filter.Spatial returns object\" ); \n        t.eq(filter.foo, \"bar\", \"constructor sets options correctly\"); \n        t.eq(typeof filter.evaluate, \"function\", \"filter has an evaluate function\"); \n    }\n\n    function test_destroy(t) {\n        t.plan(1);\n        \n        var filter = new OpenLayers.Filter.Spatial();\n        filter.destroy();\n        t.eq(filter.symbolizer, null, \"symbolizer hash nulled properly\");\n    }\n    \n    function test_evaluate(t) {\n        t.plan(8);\n        \n        var filer, feature, res, geom, bounds;\n\n        bounds = new OpenLayers.Bounds(0, 0, 10, 10);\n        filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.BBOX,\n            value: bounds\n        });\n\n        var not = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.NOT,\n            filters: [filter]\n        });\n\n        feature = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(2, 2));\n        res = filter.evaluate(feature);\n        t.eq(res, true,\n            \"evaluates returns correct value when feature intersects bounds\");\n        t.eq(not.evaluate(feature), !res, \"not bbox\");\n        \n        feature = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(20, 20));\n        res = filter.evaluate(feature);\n        t.eq(res, false,\n            \"evaluates returns correct value when feature does not intersect bounds\");\n        t.eq(not.evaluate(feature), !res, \"not outside bbox\");\n\n        geom = bounds.toGeometry();\n        feature = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(2, 2));\n        filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.INTERSECTS,\n            value: geom\n        });\n        res = filter.evaluate(feature);\n        t.eq(res, true,\n            \"evaluates returns correct value when feature intersects bounds\");\n        not.filters = [filter];\n        t.eq(not.evaluate(feature), !res, \"not intersection\");\n\n        geom = bounds.toGeometry();\n        feature = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(20, 20));\n        filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.INTERSECTS,\n            value: geom\n        });\n        not.filters = [filter];\n        res = filter.evaluate(feature);\n        t.eq(res, false,\n            \"evaluates returns correct value when feature does not intersect bounds\");\n        t.eq(not.evaluate(feature), !res, \"not non-intersection\");\n\n\n    }\n    \n    function test_clone(t) {\n        \n        t.plan(2);\n        \n        var bounds = new OpenLayers.Bounds(0, 0, 10, 10);\n        var filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.BBOX,\n            value: bounds\n        });\n        \n        var clone = filter.clone();\n        \n        // modify the original\n        filter.value.bottom = -100;\n        \n        t.eq(clone.type, OpenLayers.Filter.Spatial.BBOX, \"clone has proper type\");\n        t.eq(clone.value.toBBOX(), \"0,0,10,10\", \"clone has proper value\");\n        \n        filter.destroy();\n        clone.destroy();\n\n    }\n\n    \n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Filter.html",
    "content": "<html> \n<head> \n    <script src=\"OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_initialize(t) { \n        t.plan(3); \n         \n        var options = {'foo': 'bar'}; \n        var filter = new OpenLayers.Filter(options); \n        t.ok(filter instanceof OpenLayers.Filter, \n             \"new OpenLayers.Filter returns object\" ); \n        t.eq(filter.foo, \"bar\", \"constructor sets options correctly\"); \n        t.eq(typeof filter.evaluate, \"function\", \"filter has an evaluate function\"); \n    }\n    \n    function test_toString(t) {\n        t.plan(1);\n        var filter = new OpenLayers.Filter.Comparison({\n            property: \"PERSONS\",\n            value: 2000000,\n            type: OpenLayers.Filter.Comparison.LESS_THAN\n        });\n        t.eq(filter.toString(), \"PERSONS < 2000000\", \"toString returns CQL representation\");\n    }\n\n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/ArcXML/Features.html",
    "content": "<html> \n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    \n    var axl_feature_response = '<?xml version=\"1.0\" encoding=\"Cp1252\"?><ARCXML version=\"1.1\"><RESPONSE><FEATURES><FEATURE><FIELDS><FIELD name=\"UNIQUE_ID\" value=\"514504b5-0458-461d-b540-8e18a454f619\" /><FIELD name=\"LABEL\" value=\"LIBRARY\" /><FIELD name=\"Y_COORD\" value=\"39.57\" /><FIELD name=\"X_COORD\" value=\"-104.24\" /><FIELD name=\"#SHAPE#\" value=\"[Geometry]\" /><FIELD name=\"OBJECTID\" value=\"1\" /><FIELD name=\"shape.area\" value=\"0\" /><FIELD name=\"shape.len\" value=\"0\" /></FIELDS></FEATURE><FEATURE><FIELDS><FIELD name=\"UNIQUE_ID\" value=\"514504b5-0458-461d-b540-8e81a454f619\" /><FIELD name=\"LABEL\" value=\"LIBRARY2\" /><FIELD name=\"Y_COORD\" value=\"39.75\" /><FIELD name=\"X_COORD\" value=\"-104.42\" /><FIELD name=\"#SHAPE#\" value=\"[Geometry]\" /><FIELD name=\"OBJECTID\" value=\"2\" /><FIELD name=\"shape.area\" value=\"0\" /><FIELD name=\"shape.len\" value=\"0\" /></FIELDS></FEATURE><FEATURECOUNT count=\"2\" hasmore=\"false\" /><ENVELOPE minx=\"-678853.220047791\" miny=\"1810.22081371862\" maxx=\"-678853.220047791\" maxy=\"1810.22081371862\"/></FEATURES></RESPONSE></ARCXML>';\n    \n    //\n    // creating a new arcxml features format creates an object that has a read and write function\n    //\n    function test_initialize(t) { \n        t.plan(3); \n         \n        var format = new OpenLayers.Format.ArcXML.Features(); \n        t.ok(format instanceof OpenLayers.Format.ArcXML.Features, \n             \"new OpenLayers.Format.ArcXML.Features returns object\" ); \n\t\t\t\t\t\t \n        t.eq(typeof format.read, \"function\", \"format has a read function\"); \n        t.eq(typeof format.write, \"function\", \"format has a write function\"); \n    }\n    \n    //\n    // read in a known good axl feature response\n    //\n    function test_read1(t) {\n        t.plan(8);\n        var f = new OpenLayers.Format.ArcXML.Features();\n        var features = f.read(axl_feature_response);\n        \n        t.ok(features !== null, \"features are not null\" );\n        t.eq(features.length, 2, \"feature count is 2\" );\n        \n        // test the second feature parsed\n        // <FIELD name=\"UNIQUE_ID\" value=\"514504b5-0458-461d-b540-8e81a454f619\" />\n        // <FIELD name=\"LABEL\" value=\"LIBRARY2\" />\n        // <FIELD name=\"Y_COORD\" value=\"39.75\" />\n        // <FIELD name=\"X_COORD\" value=\"-104.42\" />\n        // <FIELD name=\"#SHAPE#\" value=\"[Geometry]\" />\n        // <FIELD name=\"OBJECTID\" value=\"2\" />\n        // <FIELD name=\"shape.area\" value=\"0\" />\n        // <FIELD name=\"shape.len\" value=\"0\" />\n        t.eq( features[1].attributes['UNIQUE_ID'], \"514504b5-0458-461d-b540-8e81a454f619\", \"field 1 for feature 2 is correct\" );\n        t.eq( features[1].attributes['LABEL'], \"LIBRARY2\", \"field 2 for feature 2 is correct\" );\n        t.eq( features[1].attributes['Y_COORD'], \"39.75\", \"field 3 for feature 2 is correct\" );\n        t.eq( features[1].attributes['X_COORD'], \"-104.42\", \"field 4 for feature 2 is correct\" );\n        t.eq( features[1].attributes['#SHAPE#'], \"[Geometry]\", \"field 5 for feature 2 is correct\" );\n        t.eq( features[1].attributes['OBJECTID'], \"2\", \"field 6 for feature 2 is correct\" );\n    }\n    \n    //\n    // cause an error by parsing bad axl\n    //\n    function test_parseerror(t) {\n        t.plan(1);\n        var f = new OpenLayers.Format.ArcXML.Features();\n        \n        try {\n            f.read( '<?xml version=\"1.0\" encoding=\"Cp1252\"?><ARCXML version=\"1.1\"><NO END TAG>' );\n            t.fail(\"reading didn't fail\");\n        }  catch (ex) {\n            t.eq( ex.message, \"Error parsing the ArcXML request\", \"Exception message indicates parsing error.\" );\n        }\n    }\n    \n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/ArcXML.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    var axl_image_response = '<?xml version=\"1.0\" encoding=\"UTF-8\"?><ARCXML version=\"1.1\"><RESPONSE><IMAGE><ENVELOPE minx=\"-2471.42857142857\" miny=\"0\" maxx=\"105671.428571429\" maxy=\"75700\" /><OUTPUT url=\"http://localhost/output/364826560.png\" /></IMAGE></RESPONSE></ARCXML>';\n    var axl_feature_response = '<?xml version=\"1.0\" encoding=\"Cp1252\"?><ARCXML version=\"1.1\"><RESPONSE><FEATURES><FEATURE><FIELDS><FIELD name=\"UNIQUE_ID\" value=\"514504b5-0458-461d-b540-8e18a454f619\" /><FIELD name=\"LABEL\" value=\"LIBRARY\" /><FIELD name=\"Y_COORD\" value=\"39.57\" /><FIELD name=\"X_COORD\" value=\"-104.24\" /><FIELD name=\"#SHAPE#\" value=\"[Geometry]\" /><FIELD name=\"OBJECTID\" value=\"1\" /><FIELD name=\"shape.area\" value=\"0\" /><FIELD name=\"shape.len\" value=\"0\" /></FIELDS></FEATURE><FEATURE><FIELDS><FIELD name=\"UNIQUE_ID\" value=\"514504b5-0458-461d-b540-8e81a454f619\" /><FIELD name=\"LABEL\" value=\"LIBRARY2\" /><FIELD name=\"Y_COORD\" value=\"39.75\" /><FIELD name=\"X_COORD\" value=\"-104.42\" /><FIELD name=\"#SHAPE#\" value=\"[Geometry]\" /><FIELD name=\"OBJECTID\" value=\"2\" /><FIELD name=\"shape.area\" value=\"0\" /><FIELD name=\"shape.len\" value=\"0\" /></FIELDS></FEATURE><FEATURECOUNT count=\"2\" hasmore=\"false\" /><ENVELOPE minx=\"-678853.220047791\" miny=\"1810.22081371862\" maxx=\"-678853.220047791\" maxy=\"1810.22081371862\"/></FEATURES></RESPONSE></ARCXML>';\n\n    //\n    // creating a new arcxml format creates an object that has a read and write function\n    //\n    function test_Format_ArcXML_constructor1(t) {\n        t.plan(4); \n         \n        var format = new OpenLayers.Format.ArcXML(); \n        t.ok(format instanceof OpenLayers.Format.ArcXML, \n             \"new OpenLayers.Format.ArcXML returns object\" ); \n\n        t.ok(format.request, null, \"no options creates a null request\");\n\n        t.eq(typeof format.read, \"function\", \"format has a read function\"); \n        t.eq(typeof format.write, \"function\", \"format has a write function\"); \n    }\n\n    //\n    // creating a new arcxml format with a set of options for an image request\n    // creates a request child object, and a get_image grandchild.\n    //\n    function test_Format_ArcXML_constructor2(t) { \n        t.plan(6); \n        \n        var options = {\n          requesttype:'image',\n          envelope: new OpenLayers.Bounds( -180, -90, 180, 90 ).toArray(),\n          layers: [],\n          tileSize: new OpenLayers.Size( 256,256 ),\n          featureCoordSys: '4326',\n          filterCoordSys: '4326'\n        };\n        \n        var format = new OpenLayers.Format.ArcXML( options );\n        t.ok(format instanceof OpenLayers.Format.ArcXML, \n             \"new OpenLayers.Format.ArcXML returns object\" ); \n    \t\t \n        t.ok(format.request instanceof OpenLayers.Format.ArcXML.Request, \n            \"constructor with 'image' requesttype generates a request\");\n        t.ok( format.request.get_image !== null, \"get_image property exists\" );\n        t.ok( format.request.get_feature === null, \"get_feature property does not exists\" );        \n\n        t.eq(typeof format.read, \"function\", \"format has a read function\"); \n        t.eq(typeof format.write, \"function\", \"format has a write function\"); \n    }\n\n    //\n    // creating a new arcxml format with a set of options for a feature request\n    // creates a request child object, and a get_feature grandchild\n    //\n    function test_Format_ArcXML_constructor3(t) { \n        t.plan(6); \n         \n        var options = {\n          requesttype:'feature'\n        };\n        \n        var format = new OpenLayers.Format.ArcXML( options ); \n        t.ok(format instanceof OpenLayers.Format.ArcXML, \n             \"new OpenLayers.Format.ArcXML returns object\" ); \n    \t\t \n        t.ok(format.request instanceof OpenLayers.Format.ArcXML.Request, \n            \"constructor with 'feature' requesttype generates a request\");\n        t.ok( format.request.get_feature !== null, \"get_feature property exists\" );\n        t.ok( format.request.get_image === null, \"get_image property does not exists\" );        \n\n        t.eq(typeof format.read, \"function\", \"format has a read function\"); \n        t.eq(typeof format.write, \"function\", \"format has a write function\"); \n    }\n\n    //\n    // read in a known good axl image response\n    //\n    function test_Format_ArcXML_read1(t) {\n        t.plan(4);\n        var f = new OpenLayers.Format.ArcXML();\n        var response = f.read(axl_image_response);\n        \n        t.ok(response !== null, \"get_image response object is not null\" );\n        t.ok(response.image !== null, \"get_image image tag is not null\");\n        t.ok(response.image.envelope !== null, \"get_image image envelope tag is not null\");\n        t.ok(response.image.output !== null, \"get_image image output tag is not null\");\n    }\n\n    //\n    // read in a known good axl feature response\n    //\n    function test_Format_ArcXML_read2(t) {\n        t.plan(10);\n        var f = new OpenLayers.Format.ArcXML();\n        var response = f.read(axl_feature_response);\n        \n        t.ok(response !== null, \"get_feature response object is not null\" );\n        t.ok(response.features !== null, \"get_feature features tag is not null\");\n        t.ok(response.features.envelope !== null, \"get_feature envelope tag is not null\");\n        t.eq(response.features.featurecount, \"2\", \"feature count is 2\" );\n        \n        // test the second feature parsed\n        // <FIELD name=\"UNIQUE_ID\" value=\"514504b5-0458-461d-b540-8e81a454f619\" />\n        // <FIELD name=\"LABEL\" value=\"LIBRARY2\" />\n        // <FIELD name=\"Y_COORD\" value=\"39.75\" />\n        // <FIELD name=\"X_COORD\" value=\"-104.42\" />\n        // <FIELD name=\"#SHAPE#\" value=\"[Geometry]\" />\n        // <FIELD name=\"OBJECTID\" value=\"2\" />\n        // <FIELD name=\"shape.area\" value=\"0\" />\n        // <FIELD name=\"shape.len\" value=\"0\" />\n        t.eq( response.features.feature[1].attributes['UNIQUE_ID'], \"514504b5-0458-461d-b540-8e81a454f619\", \"field 1 for feature 2 is correct\" );\n        t.eq( response.features.feature[1].attributes['LABEL'], \"LIBRARY2\", \"field 2 for feature 2 is correct\" );\n        t.eq( response.features.feature[1].attributes['Y_COORD'], \"39.75\", \"field 3 for feature 2 is correct\" );\n        t.eq( response.features.feature[1].attributes['X_COORD'], \"-104.42\", \"field 4 for feature 2 is correct\" );\n        t.eq( response.features.feature[1].attributes['#SHAPE#'], \"[Geometry]\", \"field 5 for feature 2 is correct\" );\n        t.eq( response.features.feature[1].attributes['OBJECTID'], \"2\", \"field 6 for feature 2 is correct\" );\n    }\n\n    //\n    // cause an error by parsing bad axl\n    //\n    function test_Format_ArcXML_parseerror(t) {\n        t.plan(1);\n        var f = new OpenLayers.Format.ArcXML();\n        \n        try {\n            f.read( '<?xml version=\"1.0\" encoding=\"Cp1252\"?><ARCXML version=\"1.1\"><NO END TAG>' );\n            t.fail(\"parsing failed to fail\")\n        } catch (ex) {\n            t.ok( true, \"Exception message indicates parsing error.\" );\n        }\n    }\n\n    //\n    // create an arcxml image request, and verify that it matches a known image request\n    //\n    function test_format_ArcXML_write1(t) {\n        var options = {\n            requesttype:'image',\n            envelope: new OpenLayers.Bounds( -180, -90, 180, 90 ).toArray(),\n            layers: [],\n            tileSize: new OpenLayers.Size( 256,256 ),\n            featureCoordSys: '4326',\n            filterCoordSys: '4326'\n        };\n        var truth = '<ARCXML version=\"1.1\"><REQUEST><GET_IMAGE><PROPERTIES><FEATURECOORDSYS id=\"4326\"/><FILTERCOORDSYS id=\"4326\"/><ENVELOPE minx=\"-180\" miny=\"-90\" maxx=\"180\" maxy=\"90\"/><IMAGESIZE height=\"256\" width=\"256\"/></PROPERTIES></GET_IMAGE></REQUEST></ARCXML>';\n        axl_write(t,options,truth);\n    }\n\n    //\n    // create an arcxml image request that specifies layer visibilities, and\n    // verify that it matches a known image request\n    //\n    function test_format_ArcXML_write2(t) {\n        var options = {\n            requesttype:'image',\n            envelope: new OpenLayers.Bounds( -180, -90, 180, 90 ).toArray(),\n            layers: [{\n                id: \"0\",\n                visible: \"true\"\n            }],\n            tileSize: new OpenLayers.Size( 256,256 ),\n            featureCoordSys: '4326',\n            filterCoordSys: '4326'\n        };\n        var truth = '<ARCXML version=\"1.1\"><REQUEST><GET_IMAGE><PROPERTIES><FEATURECOORDSYS id=\"4326\"/><FILTERCOORDSYS id=\"4326\"/><ENVELOPE minx=\"-180\" miny=\"-90\" maxx=\"180\" maxy=\"90\"/><IMAGESIZE height=\"256\" width=\"256\"/><LAYERLIST><LAYERDEF id=\"0\" visible=\"true\"/></LAYERLIST></PROPERTIES></GET_IMAGE></REQUEST></ARCXML>';\n        axl_write(t, options, truth );\n    }\n\n    //\n    // create an arcxml image request that performs a query for thematic mapping,\n    // and verify that it matches a known image request\n    //\n    function test_format_ArcXML_write3(t) {\n        var options = {\n            requesttype:'image',\n            envelope: new OpenLayers.Bounds( -180, -90, 180, 90 ).toArray(),\n            layers: [{\n                id: \"0\",\n                visible: \"true\",\n                query: {\n                    where: \"COMPANY='AVENCIA'\"\n                }\n            }],\n            tileSize: new OpenLayers.Size( 256,256 ),\n            featureCoordSys: '4326',\n            filterCoordSys: '4326'\n        };\n        var truth = '<ARCXML version=\"1.1\"><REQUEST><GET_IMAGE><PROPERTIES><FEATURECOORDSYS id=\"4326\"/><FILTERCOORDSYS id=\"4326\"/><ENVELOPE minx=\"-180\" miny=\"-90\" maxx=\"180\" maxy=\"90\"/><IMAGESIZE height=\"256\" width=\"256\"/><LAYERLIST><LAYERDEF id=\"0\" visible=\"true\"><QUERY where=\"COMPANY=\\'AVENCIA\\'\"/></LAYERDEF></LAYERLIST></PROPERTIES></GET_IMAGE></REQUEST></ARCXML>';\n        axl_write(t, options, truth );\n    }\n\n    //\n    // create an arcxml image request that performs a spatial query for thematic mapping,\n    // and verify that it matches a known image request\n    //\n    function test_format_ArcXML_write4(t) {\n        var options = {\n            requesttype:'image',\n            envelope: new OpenLayers.Bounds( -180, -90, 180, 90 ).toArray(),\n            layers: [{\n                id: \"0\",\n                visible: \"true\",\n                query: {\n                    spatialfilter: true,\n                    where: \"COMPANY='AVENCIA'\"\n                }\n            }],\n            tileSize: new OpenLayers.Size( 256,256 ),\n            featureCoordSys: '4326',\n            filterCoordSys: '4326'\n        };\n        var truth = '<ARCXML version=\"1.1\"><REQUEST><GET_IMAGE><PROPERTIES><FEATURECOORDSYS id=\"4326\"/><FILTERCOORDSYS id=\"4326\"/><ENVELOPE minx=\"-180\" miny=\"-90\" maxx=\"180\" maxy=\"90\"/><IMAGESIZE height=\"256\" width=\"256\"/><LAYERLIST><LAYERDEF id=\"0\" visible=\"true\"><SPATIALQUERY where=\"COMPANY=\\'AVENCIA\\'\"/></LAYERDEF></LAYERLIST></PROPERTIES></GET_IMAGE></REQUEST></ARCXML>';\n        axl_write(t, options, truth );\n    }\n\n    //\n    // create an arcxml image request that performs a thematic map request, and\n    // verify that it matches a known image request.\n    //\n    function test_format_ArcXML_write5(t) {\n        var options = {\n            requesttype:'image',\n            envelope: new OpenLayers.Bounds( -180, -90, 180, 90 ).toArray(),\n            layers: [{\n                id: \"0\",\n                visible: \"true\",\n                query: {\n                    spatialfilter: true,\n                    where: \"COMPANY='AVENCIA'\"\n                },\n                renderer: {\n                    type: 'valuemap',\n                    lookupfield: 'lookup',\n                    ranges: [{\n                        lower: 0,\n                        upper: 10,\n                        symbol: {\n                            type: 'simplepolygon',\n                            fillcolor: '0,0,0'\n                        }\n                    },{\n                        lower: 10,\n                        upper: 20,\n                        symbol: {\n                            type: 'simplepolygon',\n                            fillcolor: '255,255,255'\n                        }\n                    }]\n                }\n            }],\n            tileSize: new OpenLayers.Size( 256,256 ),\n            featureCoordSys: '4326',\n            filterCoordSys: '4326'\n        };\n        var truth = '<ARCXML version=\"1.1\"><REQUEST><GET_IMAGE><PROPERTIES><FEATURECOORDSYS id=\"4326\"/><FILTERCOORDSYS id=\"4326\"/><ENVELOPE minx=\"-180\" miny=\"-90\" maxx=\"180\" maxy=\"90\"/><IMAGESIZE height=\"256\" width=\"256\"/><LAYERLIST><LAYERDEF id=\"0\" visible=\"true\"><SPATIALQUERY where=\"COMPANY=\\'AVENCIA\\'\"/><VALUEMAPRENDERER lookupfield=\"lookup\"><RANGE lower=\"0\" upper=\"10\"><SIMPLEPOLYGONSYMBOL fillcolor=\"0,0,0\"/></RANGE><RANGE lower=\"10\" upper=\"20\"><SIMPLEPOLYGONSYMBOL fillcolor=\"255,255,255\"/></RANGE></VALUEMAPRENDERER></LAYERDEF></LAYERLIST></PROPERTIES></GET_IMAGE></REQUEST></ARCXML>';\n        axl_write(t, options, truth );\n    }\n\n    //\n    // helper function to write some axl, and compare it against a truth axl string\n    //\n    function axl_write(t, options, truth) {\n        t.plan(1);\n        \n        var f = new OpenLayers.Format.ArcXML( options );\n        var arcxml = f.write();\n        t.eq( arcxml, truth, \"ArcXML request is correct.\");\n    }\n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/Atom.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_constructor(t) { \n        t.plan(4); \n        var options = {'foo': 'bar'}; \n        var format = new OpenLayers.Format.Atom(options); \n        t.ok(format instanceof OpenLayers.Format.Atom, \n             \"new OpenLayers.Format.GeoRSS returns object\" ); \n        t.eq(format.foo, \"bar\", \"constructor sets options correctly\"); \n        t.eq(typeof format.read, \"function\", \"format has a read function\"); \n        t.eq(typeof format.write, \"function\", \"format has a write function\"); \n    }\n\n    /* Reading tests */\n\n    function test_reproject_null(t) { \n        t.plan(1);\n        var parser = new OpenLayers.Format.Atom({'internalProjection':new OpenLayers.Projection(\"EPSG:4326\"), 'externalProjection': new OpenLayers.Projection(\"EPSG:4326\")});\n        var data = parser.read(\n          // begin document\n          '<feed xmlns=\"http://www.w3.org/2005/Atom\">'  +\n          '<entry></entry>'                             +\n          '</feed>'\n          // end document\n          );\n        t.eq(\n          data.length, 1, \n          \"Parsing items with null geometry and reprojection doesn't fail\"\n          );\n    }\n\n    // read entry 1: basic entry, no categories or persons\n    function test_readentry1(t) { \n        t.plan(10);\n        var parser = new OpenLayers.Format.Atom();\n        var data = parser.read(\n          // begin document\n          '<entry xmlns=\"http://www.w3.org/2005/Atom\">'                 +\n          '  <id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>'    +\n          '  <link href=\"http://example.com/blog/1\" rel=\"alternate\"/>'  +\n          '  <summary>An Atom testing entry</summary>'                  +\n          '  <title>Atom test</title>'                                  +\n          '  <updated>2009-06-02T10:00:00Z</updated>'                   +\n          '</entry>'\n          // end document\n          );\n        t.ok(data instanceof Array, \"Read features\");\n        var fx = data[0];\n        t.ok(fx instanceof OpenLayers.Feature.Vector, \"Read feature\");\n        t.eq(fx.geometry, null, \"Geometry is null\");\n        t.eq(\n            fx.fid, \n            \"urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed\", \n            \"Read fid\"\n            );\n        var attrib = fx.attributes;\n        t.eq(attrib.title, \"Atom test\", \"Correct title attribute\");\n        t.eq(\n            attrib.description, \n            \"An Atom testing entry\", \n            \"Correct description attribute\"\n            );\n        var atomAttrib = attrib.atom;\n        t.eq(\n            atomAttrib.links, \n            [{href: \"http://example.com/blog/1\", rel: \"alternate\"}], \n            \"Correct links in atom namespace\"\n            );\n        t.eq(\n            atomAttrib.summary, \n            \"An Atom testing entry\", \n            \"Correct summary in atom namespace\"\n            );\n        t.eq(\n            atomAttrib.title, \n            \"Atom test\", \n            \"Correct title in atom namespace\"\n            );\n        t.eq(\n            atomAttrib.updated, \n            \"2009-06-02T10:00:00Z\", \n            \"Correct timestamp in atom namespace\"\n            );\n    }\n\n    // read entry 2: with georss:where\n    function test_readentry2(t) { \n        t.plan(5);\n        var parser = new OpenLayers.Format.Atom();\n        var data = parser.read(\n          // begin document\n          '<entry xmlns=\"http://www.w3.org/2005/Atom\">'                   +\n          '  <id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>'      +\n          '  <georss:where xmlns:georss=\"http://www.georss.org/georss\">'  +\n          '    <gml:Point xmlns:gml=\"http://www.opengis.net/gml\">'        +\n          '      <gml:pos>45.68 -111.04</gml:pos>'                        +\n          '    </gml:Point>'                                              +\n          '  </georss:where>'                                             +\n          '</entry>'\n          // end document\n          );\n        t.ok(data instanceof Array, \"Read features\");\n        var fx = data[0];\n        t.ok(fx instanceof OpenLayers.Feature.Vector, \"Read feature\");\n        t.ok(fx.geometry instanceof OpenLayers.Geometry.Point, \"Read geometry\");\n        t.eq(fx.geometry.x, -111.04, \"Read x\");\n        t.eq(fx.geometry.y, 45.68, \"Read y\");\n    }\n\n    // read entry 3: with georss:point\n    function test_readentry3(t) { \n        t.plan(5);\n        var parser = new OpenLayers.Format.Atom();\n        var data = parser.read(\n          // begin document\n          '<entry xmlns=\"http://www.w3.org/2005/Atom\">'                   +\n          '  <id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>'      +\n          '  <georss:point xmlns:georss=\"http://www.georss.org/georss\">45.68 -111.04</georss:point>'                                                   +\n          '</entry>'\n          // end document\n          );\n        t.ok(data instanceof Array, \"Read features\");\n        var fx = data[0];\n        t.ok(fx instanceof OpenLayers.Feature.Vector, \"Read feature\");\n        t.ok(fx.geometry instanceof OpenLayers.Geometry.Point, \"Read geometry\");\n        t.eq(fx.geometry.x, -111.04, \"Read x\");\n        t.eq(fx.geometry.y, 45.68, \"Read y\");\n    }\n\n    // read entry 4: basic entry, text content\n    function test_readentry4(t) { \n        t.plan(3);\n        var parser = new OpenLayers.Format.Atom();\n        var data = parser.read(\n          // begin document\n          '<entry xmlns=\"http://www.w3.org/2005/Atom\">'                 +\n          '  <id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>'    +\n          '  <link href=\"http://example.com/blog/1\" rel=\"alternate\"/>'  +\n          '  <summary>An Atom testing entry</summary>'                  +\n          '  <title>Atom test</title>'                                  +\n          '  <updated>2009-06-02T10:00:00Z</updated>'                   +\n          '  <content type=\"text\">Blah, blah, blah</content>'           +\n          '</entry>'\n          // end document\n          );\n        t.ok(data instanceof Array, \"Read features\");\n        var fx = data[0];\n        var attrib = fx.attributes;\n        var atomAttrib = attrib.atom;\n        t.eq(\n            atomAttrib.content.type, \n            \"text\", \n            \"Correct content.type in atom namespace\"\n            );\n        t.eq(\n            atomAttrib.content.value, \n            \"Blah, blah, blah\", \n            \"Correct content.value in atom namespace\"\n            );\n    }\n\n    // read entry 5: basic entry, KML content\n    function test_readentry5(t) { \n        t.plan(3);\n        var parser = new OpenLayers.Format.Atom();\n        var data = parser.read(\n          // begin document\n          '<entry xmlns=\"http://www.w3.org/2005/Atom\">'                 +\n          '  <id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>'    +\n          '  <link href=\"http://example.com/blog/1\" rel=\"alternate\"/>'  +\n          '  <summary>An Atom testing entry</summary>'                  +\n          '  <title>Atom test</title>'                                  +\n          '  <updated>2009-06-02T10:00:00Z</updated>'                   +\n          '  <content type=\"application/vnd.google-earth.kml+xml\"><kml xmlns=\"http://earth.google.com/kml/2.0\"><Folder><name>A folder</name><description>It\\'s a folder</description></Folder></kml></content>'                          +\n          '</entry>'\n          // end document\n          );\n        t.ok(data instanceof Array, \"Read features\");\n        var fx = data[0];\n        var attrib = fx.attributes;\n        var atomAttrib = attrib.atom;\n        t.eq(\n            atomAttrib.content.type, \n            \"application/vnd.google-earth.kml+xml\", \n            \"Correct content.type in atom namespace\"\n            );\n        var node = atomAttrib.content.value;\n        var name = node.localName || node.nodeName.split(\":\").pop();\n        t.eq(\n            name, \n            \"kml\", \n            \"Correct content.value in atom namespace\"\n            );\n    }\n    \n    // read feed 1\n    function test_readfeed1(t) { \n        t.plan(2);\n        var parser = new OpenLayers.Format.Atom();\n        var data = parser.read(\n          // begin document\n          '<feed xmlns=\"http://www.w3.org/2005/Atom\">'                  +\n          '  <entry>'                                                   +\n          '    <id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>'  +\n          '  </entry>'                                                  +\n          '</feed>'\n          // end document\n          );\n        t.ok(data instanceof Array, \"Read features\");\n        var fx = data[0];\n        t.ok(fx instanceof OpenLayers.Feature.Vector, \"Read feature\");\n    }\n    \n    /* Writing tests */\n  \n    // write entry 1: null geometry, no attributes\n    function test_writeentry1(t) { \n        t.plan(1);\n        var writer = new OpenLayers.Format.Atom();\n        var feature = new OpenLayers.Feature.Vector(null, {});\n        feature.fid = '1';\n        var data = writer.write(feature);\n        t.xml_eq(\n          data,\n          // begin document\n          '<entry xmlns=\"http://www.w3.org/2005/Atom\">' +\n          '<id>1</id>'                                  +\n          '<title>untitled</title>'                     +\n          '</entry>',\n          // end document \n          'Writes an entry doc with id, no attributes'\n          );\n    }\n\n    // write entry 2: null geometry, well-known attributes\n    function test_writeentry2(t) { \n        t.plan(1);\n        var writer = new OpenLayers.Format.Atom();\n        var feature = new OpenLayers.Feature.Vector(null, {title: \"Test\", description: \"A testing feature\"});\n        feature.fid = '1';\n        var data = writer.write(feature);\n        t.xml_eq(\n          data,\n          // begin document\n          '<entry xmlns=\"http://www.w3.org/2005/Atom\">' +\n          '<id>1</id>'                                  +\n          '<summary>A testing feature</summary>'        +\n          '<title>Test</title>'                         +\n          '</entry>',\n          // end document\n          'Writes an entry doc with id, well-known attributes'\n          );\n    }\n\n    // write entry 3: null geometry, Atom constructs to override \n    // well-known attributes\n    function test_writeentry3(t) { \n        t.plan(1);\n        var writer = new OpenLayers.Format.Atom();\n        var feature = new OpenLayers.Feature.Vector(null, {title: \"Test\", description: \"A testing feature\", atom: {title: \"Atom test\", summary: \"An Atom testing feature\", updated: \"2009-06-02T10:00:00Z\"}});\n        feature.fid = '1';\n        var data = writer.write(feature);\n        t.xml_eq(\n          data,\n          // begin document\n          '<entry xmlns=\"http://www.w3.org/2005/Atom\">' +\n          '<id>1</id>'                                  +\n          '<summary>An Atom testing feature</summary>'  +\n          '<title>Atom test</title>'                    +\n          '<updated>2009-06-02T10:00:00Z</updated>'     +\n          '</entry>',\n          // end document\n          'Writes an entry doc with Atom constructs overriding well-known atts'\n          );\n    }\n\n    // write entry 4: Atom categories\n    function test_writeentry4(t) { \n        t.plan(1);\n        var writer = new OpenLayers.Format.Atom();\n        var feature = new OpenLayers.Feature.Vector(null, {title: \"Test\", description: \"A testing feature\", atom: {title: \"Atom test\", summary: \"An Atom testing feature\", updated: \"2009-06-02T10:00:00Z\", categories: [{term: \"blog\", scheme: \"http://example.com/terms\", label: \"A blog post\"}]}});\n        feature.fid = '1';\n        var data = writer.write(feature);\n        t.xml_eq(\n          data,\n          // begin document\n          '<entry xmlns=\"http://www.w3.org/2005/Atom\">' +\n          '<category term=\"blog\" scheme=\"http://example.com/terms\" label=\"A blog post\"/>'                                           +\n          '<id>1</id>'                                  +\n          '<summary>An Atom testing feature</summary>'  +\n          '<title>Atom test</title>'                    +\n          '<updated>2009-06-02T10:00:00Z</updated>'     +\n          '</entry>',\n          // end document\n          'Writes an entry doc with Atom constructs and categories'\n          );\n    }\n\n    // write entry 5: Atom authors, contributors\n    function test_writeentry5(t) { \n        t.plan(1);\n        var writer = new OpenLayers.Format.Atom();\n        var feature = new OpenLayers.Feature.Vector(null, {title: \"Test\", description: \"A testing feature\", atom: {title: \"Atom test\", summary: \"An Atom testing feature\", updated: \"2009-06-02T10:00:00Z\", authors: [{name: \"John Doe\", uri: \"http://example.com/people/jdoe\", email: \"jdoe@example.com\"}], contributors: [{name: \"Pikov Andropov\", uri: \"http://example.com/people/pandropov\", email: \"pandropov@example.com\"}]}});\n        feature.fid = '1';\n        var data = writer.write(feature);\n        t.xml_eq(\n          data,\n          // begin document\n          '<entry xmlns=\"http://www.w3.org/2005/Atom\">' +\n          '<author>'                                    +\n          '  <name>John Doe</name>'                     +\n          '  <uri>http://example.com/people/jdoe</uri>' +\n          '  <email>jdoe@example.com</email>'           +\n          '</author>'                                   +\n          '<contributor>'                               +\n          '  <name>Pikov Andropov</name>'               +\n          '  <uri>http://example.com/people/pandropov</uri>' +\n          '  <email>pandropov@example.com</email>'      +\n          '</contributor>'                              +\n          '<id>1</id>'                                  +\n          '<summary>An Atom testing feature</summary>'  +\n          '<title>Atom test</title>'                    +\n          '<updated>2009-06-02T10:00:00Z</updated>'     +\n          '</entry>',\n          // end document\n          'Writes an entry doc with Atom constructs and persons'\n          );\n    }\n\n    // write entry 6: Atom links\n    function test_writeentry6(t) { \n        t.plan(1);\n        \n        // Feature attributes in Atom namespace\n        var atomAttrib = {\n              title: \"Atom test\", \n              summary: \"An Atom testing feature\", \n              updated: \"2009-06-02T10:00:00Z\", \n              links: [\n                { href: \"http://example.com/blog/1\", rel: \"alternate\" }\n                ]\n              };\n        var fx = new OpenLayers.Feature.Vector(null, {atom: atomAttrib});\n        fx.fid = 'urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed';\n        \n        var writer = new OpenLayers.Format.Atom();\n        var data = writer.write(fx);\n        \n        t.xml_eq(\n          data,\n          // begin document\n          '<entry xmlns=\"http://www.w3.org/2005/Atom\">'               +\n          '<id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>'    +\n          '<link href=\"http://example.com/blog/1\" rel=\"alternate\"/>'  +\n          '<summary>An Atom testing feature</summary>'                +\n          '<title>Atom test</title>'                                  +\n          '<updated>2009-06-02T10:00:00Z</updated>'                   +\n          '</entry>',\n          // end document\n          'Writes an entry doc with Atom constructs and links'\n          );\n    }\n\n    // write out point -- just enough to see that we're getting the\n    // georss:where element with a Point. We'll trust GML.v3 to get the\n    // details right.\n    function test_writepoint(t) { \n        t.plan(1);\n\n        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);  \n        var fx = new OpenLayers.Feature.Vector(point, {});\n        fx.fid = 'urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed';\n        \n        var writer = new OpenLayers.Format.Atom();\n        var data = writer.write(fx);\n        \n        t.xml_eq(\n          data,\n          // begin document\n          '<entry xmlns=\"http://www.w3.org/2005/Atom\">'                 +\n          '<id>urn:uuid:82ede847-b31a-4e3d-b773-7471bad154ed</id>'      +\n          '<title>untitled</title>'                                     +\n          '<georss:where xmlns:georss=\"http://www.georss.org/georss\">'  +\n          '  <gml:Point xmlns:gml=\"http://www.opengis.net/gml\">'        +\n          '    <gml:pos>45.68 -111.04</gml:pos>'                        +\n          '  </gml:Point>'                                              +\n          '</georss:where>'                                             +\n          '</entry>',\n          // end document\n          'Writes an entry doc with a point location'\n          );\n    }\n\n    // write entry 7: text type content\n    function test_writeentry7(t) { \n        t.plan(1);\n        var writer = new OpenLayers.Format.Atom();\n        var feature = new OpenLayers.Feature.Vector(null, {title: \"Test\", description: \"A testing feature\", atom: {title: \"Atom test\", summary: \"An Atom testing feature\", updated: \"2009-06-02T10:00:00Z\", content: {type: \"text\", value: \"Blah, blah, blah\"}}});\n        feature.fid = '1';\n        var data = writer.write(feature);\n        t.xml_eq(\n          data,\n          // begin document\n          '<entry xmlns=\"http://www.w3.org/2005/Atom\">'     +\n          '<content type=\"text\">Blah, blah, blah</content>' +\n          '<id>1</id>'                                      +\n          '<summary>An Atom testing feature</summary>'      +\n          '<title>Atom test</title>'                        +\n          '<updated>2009-06-02T10:00:00Z</updated>'         +\n          '</entry>',\n          // end document\n          'Writes an entry doc with Atom constructs overriding well-known atts'\n          );\n    }\n\n    // write entry 8: +xml type content\n    function test_writeentry8(t) { \n        t.plan(1);\n        var kml = new OpenLayers.Format.KML();\n        kml.foldersName = \"A folder\";\n        kml.foldersDesc = \"It's a folder\";\n        var kmlDoc = kml.createElementNS(kml.kmlns, \"kml\");\n        var kmlFolder = kml.createFolderXML();\n        kmlDoc.appendChild(kmlFolder);\n        var writer = new OpenLayers.Format.Atom();\n        var feature = new OpenLayers.Feature.Vector(null, {title: \"Test\", description: \"A testing feature\", atom: {title: \"Atom test\", summary: \"An Atom testing feature\", updated: \"2009-06-02T10:00:00Z\", content: {type: \"application/vnd.google-earth.kml+xml\", value: kmlDoc}}});\n        feature.fid = '1';\n        var data = writer.write(feature);\n        t.xml_eq(\n          data,\n          // begin document\n          '<entry xmlns=\"http://www.w3.org/2005/Atom\">'     +\n          '<content type=\"application/vnd.google-earth.kml+xml\"><kml xmlns=\"http://earth.google.com/kml/2.0\"><Folder><name>A folder</name><description>It\\'s a folder</description></Folder></kml></content>' +\n          '<id>1</id>'                                      +\n          '<summary>An Atom testing feature</summary>'      +\n          '<title>Atom test</title>'                        +\n          '<updated>2009-06-02T10:00:00Z</updated>'         +\n          '</entry>',\n          // end document\n          'Writes an entry doc with Atom constructs overriding well-known atts'\n          );\n    }\n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/CQL.html",
    "content": "<html>\n    <head>\n        <script src=\"../OLLoader.js\"></script>\n\n        <script type=\"text/javascript\">\n\nfunction test_CQL_Constructor(t) {\n    t.plan(5);\n    var options = {'foo': 'bar'};\n    var format  = new OpenLayers.Format.CQL(options);\n    t.ok(format instanceof OpenLayers.Format.CQL,\n         \"new OpenLayers.Format.CQL object\");\n    t.eq(format.foo, \"bar\", \"constructor sets options correctly\")\n    t.eq(typeof format.read, 'function', 'format has a read function');\n    t.eq(typeof format.write, 'function', 'format has a write function');\n    t.eq(format.options, options, \"format.options correctly set\");\n}\n\nfunction test_Comparison_string(t) {\n    t.plan(5);\n    var test_cql, format, filter;\n    test_cql = \"X >= 'B'\";\n    format = new OpenLayers.Format.CQL();\n    filter = format.read(test_cql);\n    t.ok(filter instanceof OpenLayers.Filter.Comparison,\n         \"Parsing a simple >= filter produces a Filter.Comparison\");\n    t.eq(filter.type, OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO,\n         \">= parsed as Filter.Comparison.GREATER_THAN_OR_EQUAL_TO\");\n    t.eq(filter.property, 'X',\n         \"Property extracted from CQL text\");\n    t.eq(filter.value, 'B',\n         \"Value extracted from CQL text\");\n         \n         \n    t.eq(format.write(filter), test_cql, \"write returned test cql\");\n}\n\nfunction test_read_whitespace(t) {\n    t.plan(4);\n    var cql = \"TYPEDESC = 'BOE Numbered Plans'\";\n    var format = new OpenLayers.Format.CQL();\n    var filter = format.read(cql);\n    t.ok(filter instanceof OpenLayers.Filter.Comparison, \"filter parsed correctly with whitespace in string\");\n    t.eq(filter.property, 'TYPEDESC', \"filter property parsed correctly\");\n    t.eq(filter.value, 'BOE Numbered Plans', \"value parsed correctly\");\n    t.eq(filter.type, '==', 'filter type parsed correctly');\n}\n\nfunction test_read_escaped_quotes(t) {\n    t.plan(14);\n    var cql = \"PROP = 'don''t worry' or PROP = 'value''s value' or PROP = 'foo'\";\n    var format = new OpenLayers.Format.CQL();\n\n    var filter = format.read(cql);\n    t.ok(filter instanceof OpenLayers.Filter.Logical, \"filter type\");\n    t.eq(filter.filters.length, 2, \"filter children\");\n\n    var f0 = filter.filters[0];\n    t.ok(f0 instanceof OpenLayers.Filter.Logical, \"f0 type\");\n    t.eq(f0.filters.length, 2, \"f0 children\");\n\n    var f00 = f0.filters[0];\n    t.eq(f00.property, \"PROP\", \"f000 property\");\n    t.eq(f00.type, \"==\", \"f000 type\");\n    t.eq(f00.value, \"don't worry\", \"f000 value\");\n\n    var f01 = f0.filters[1];\n    t.eq(f01.property, \"PROP\", \"f001 property\");\n    t.eq(f01.type, \"==\", \"f001 type\");\n    t.eq(f01.value, \"value's value\", \"f001 value\");\n\n    var f1 = filter.filters[1];\n    t.ok(f1 instanceof OpenLayers.Filter.Comparison, \"f1 type\");\n    t.eq(f1.property, \"PROP\", \"f1 property\");\n    t.eq(f1.type, \"==\", \"f1 type\");\n    t.eq(f1.value, \"foo\", \"f1 value\");\n}\n\nfunction test_write_escaped_quotes(t) {\n    t.plan(1);\n    var filter = new OpenLayers.Filter.Logical({\n        type: OpenLayers.Filter.Logical.OR,\n        filters: [\n            new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                property: \"PROP\",\n                value: \"quot'd string\"\n            }),\n            new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                property: \"PROP\",\n                value: \"don't quote's\"\n            })\n        ]\n    });\n    var format = new OpenLayers.Format.CQL();\n    var cql = format.write(filter);\n    t.eq(cql, \"(PROP = 'quot''d string') OR (PROP = 'don''t quote''s')\", \"escaped\");\n}\n\nfunction test_Comparison_number(t) {\n    t.plan(5);\n    var test_cql, format, filter;\n    test_cql = \"X >= 10\";\n    format = new OpenLayers.Format.CQL();\n    filter = format.read(test_cql);\n    t.ok(filter instanceof OpenLayers.Filter.Comparison,\n         \"Parsing a simple >= filter produces a Filter.Comparison\");\n    t.eq(filter.type, OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO,\n         \">= parsed as Filter.Comparison.GREATER_THAN_OR_EQUAL_TO\");\n    t.eq(filter.property, 'X',\n         \"Property extracted from CQL text\");\n    t.eq(filter.value, 10,\n         \"Value extracted from CQL text\");\n         \n         \n    t.eq(format.write(filter), test_cql, \"write returned test cql\");\n}\n\nfunction test_Logical(t) {\n    t.plan(7);\n    var test_cql, format, filter;\n    test_cql = \"X >= 'B' AND X < 'M'\";\n    format = new OpenLayers.Format.CQL();\n    filter = format.read(test_cql);\n    t.ok(filter instanceof OpenLayers.Filter.Logical,\n         \"Parsing ANDed filters produces a Filter.Logical\");\n    t.eq(filter.type, OpenLayers.Filter.Logical.AND,\n         \"AND parsed as Filter.Logical.AND\");\n    t.eq(filter.filters.length, 2,\n         \"AND Filter contains two subfilters\");\n    t.ok(filter.filters[0] instanceof OpenLayers.Filter.Comparison,\n         \"First sub-filter is a Filter.Comparison\");\n    t.eq(filter.filters[0].type, OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO,\n         \"First sub-filter is the first filter in the CQL text\");\n    t.ok(filter.filters[1] instanceof OpenLayers.Filter.Comparison,\n         \"Second sub-filter is a Filter.Comparison\");\n    t.eq(filter.filters[1].type, OpenLayers.Filter.Comparison.LESS_THAN,\n         \"Second sub-filter is the second filter in the CQL text\");\n\n}\n\nfunction test_Logical_write(t) {\n    t.plan(1);\n    var cql = \"(X >= 'B') AND (X < 'M')\";\n    var format = new OpenLayers.Format.CQL();\n    var filter = format.read(cql);\n    t.eq(format.write(filter), cql, \"write returned test cql\");\n}\n\nfunction test_Logical_spatial(t) {\n    t.plan(9);\n    var test_cql, format, filter;\n    test_cql = \"INTERSECTS(the_geom, POLYGON((-111 41,-115 41,-115 45,-110 45,-111 41))) AND CONTAINS(the_geom, POINT(-111 41))\";\n    format = new OpenLayers.Format.CQL();\n    filter = format.read(test_cql);\n    t.ok(filter instanceof OpenLayers.Filter.Logical,\n         \"Parsing ANDed filters produces a Filter.Logical\");\n    t.eq(filter.type, OpenLayers.Filter.Logical.AND,\n         \"AND parsed as Filter.Logical.AND\");\n    t.eq(filter.filters.length, 2,\n         \"AND Filter contains two subfilters\");\n    t.ok(filter.filters[0] instanceof OpenLayers.Filter.Spatial,\n         \"First sub-filter is a Filter.Spatial\");\n    t.eq(filter.filters[0].type, OpenLayers.Filter.Spatial.INTERSECTS,\n         \"First sub-filter is the first filter in the CQL text\");\n    t.geom_eq(filter.filters[0].value, OpenLayers.Geometry.fromWKT(\"POLYGON((-111 41,-115 41,-115 45,-110 45,-111 41))\"),\n         \"First sub-filter is has correct geometry\");\n    t.ok(filter.filters[1] instanceof OpenLayers.Filter.Spatial,\n         \"Second sub-filter is a Filter.Comparison\");\n    t.eq(filter.filters[1].type, OpenLayers.Filter.Spatial.CONTAINS,\n         \"Second sub-filter is the second filter in the CQL text\");\n    t.geom_eq(filter.filters[1].value, OpenLayers.Geometry.fromWKT(\"POINT(-111 41)\"),\n         \"Second sub-filter is has correct geometry\");\n}\n\nfunction test_Logical_spatial_write(t) {\n    // TODO: remove this if extra parentheses are avoided by checking logical operator precedence\n    t.plan(1);\n    var cql = \"(INTERSECTS(the_geom, POLYGON((-111 41,-115 41,-115 45,-110 45,-111 41)))) AND (CONTAINS(the_geom, POINT(-111 41)))\";\n    var format = new OpenLayers.Format.CQL();\n    var filter = format.read(cql);\n    t.eq(format.write(filter), cql, \"write returned test cql\");\n}\n\nfunction test_Parentheticals(t) {\n    t.plan(2);\n    var format, cqlA, filterA, cqlB, filterB;\n    format = new OpenLayers.Format.CQL();\n    cqlA = \"A = '1' AND B = '2' OR C = '3'\";\n    cqlB = \"A = '1' AND (B = '2' OR C = '3')\";\n    filterA = format.read(cqlA);\n    filterB = format.read(cqlB);\n\n    t.ok(filterA instanceof OpenLayers.Filter.Logical &&\n         filterA.filters[0] instanceof OpenLayers.Filter.Logical &&\n         filterA.filters[1] instanceof OpenLayers.Filter.Comparison,\n         \"Unparenthesized expression groups left to right\");\n    t.ok(filterB instanceof OpenLayers.Filter.Logical &&\n         filterB.filters[0] instanceof OpenLayers.Filter.Comparison &&\n         filterB.filters[1] instanceof OpenLayers.Filter.Logical,\n         \"Parenthesized expression groups as specified by parentheses\");\n}\n\nfunction test_Parentheticals_write(t) {\n    // TODO: remove this if extra parentheses are avoided by checking logical operator precedence\n    t.plan(1);\n    var format = new OpenLayers.Format.CQL();\n    var cql = \"(A = '1') AND ((B = '2') OR (C = '3'))\";\n    var filter = format.read(cql);\n    t.eq(format.write(filter), cql, \"write returned test cql\");\n}\n\nfunction test_BBOX(t) {\n    t.plan(5);\n    var format = new OpenLayers.Format.CQL(),\n        cql = \"BBOX(the_geom,1,2,3,4)\",\n        filter = format.read(cql);\n    t.ok(filter instanceof OpenLayers.Filter.Spatial,\n         \"Parsing BBOX expression produces Filter.Spatial\");\n    t.eq(filter.type, OpenLayers.Filter.Spatial.BBOX,\n         \"Spatial filter is a bbox filter\");\n    t.eq(filter.property, \"the_geom\",\n         \"Property name is as specified in CQL\");\n    t.eq(filter.value.toBBOX(), \"1,2,3,4\",\n         \"Value is as specified in CQL\");\n\n    t.eq(format.write(filter), cql, \"write returned test cql\");\n\n}\n\nfunction test_INTERSECTS(t) {\n    t.plan(5);\n    var format = new OpenLayers.Format.CQL(),\n        cql = \"INTERSECTS(the_geom, POINT(1 2))\",\n        filter = format.read(cql);\n    t.ok(filter instanceof OpenLayers.Filter.Spatial,\n         \"Parsing BBOX expression produces Filter.Spatial\");\n    t.eq(filter.type, OpenLayers.Filter.Spatial.INTERSECTS,\n         \"Spatial filter is an intersects filter\");\n    t.eq(filter.property, \"the_geom\",\n         \"Property name is as specified in CQL\");\n    t.ok(filter.value instanceof OpenLayers.Geometry,\n         \"Value is a geometry\");\n    \n    t.eq(format.write(filter), cql, \"write returned test cql\");\n\n}\n\nfunction test_WITHIN(t) {\n    t.plan(5);\n    var format = new OpenLayers.Format.CQL(),\n        cql = \"WITHIN(the_geom, POLYGON((1 2,3 4,5 6,3 8,1 6,1 2)))\",\n        filter = format.read(cql);\n    t.ok(filter instanceof OpenLayers.Filter.Spatial,\n         \"Parsing BBOX expression produces Filter.Spatial\");\n    t.eq(filter.type, OpenLayers.Filter.Spatial.WITHIN,\n         \"Spatial filter is a within filter\");\n    t.eq(filter.property, \"the_geom\",\n         \"Property name is as specified in CQL\");\n    t.ok(filter.value instanceof OpenLayers.Geometry,\n         \"Value is a geometry\");\n\n    t.eq(format.write(filter), cql, \"write returned test cql\");\n\n}\n\nfunction test_DWITHIN(t) {\n    t.plan(6);\n    var format = new OpenLayers.Format.CQL(),\n        cql = \"DWITHIN(the_geom, POINT(1 2), 6)\",\n        filter = format.read(cql);\n    t.ok(filter instanceof OpenLayers.Filter.Spatial,\n         \"Parsing DWITHIN expression produces Filter.Spatial\");\n    t.eq(filter.type, OpenLayers.Filter.Spatial.DWITHIN,\n         \"Spatial filter is a DWITHIN filter\");\n    t.eq(filter.property, \"the_geom\",\n         \"Property name is as specified in CQL\");\n    t.ok(filter.value instanceof OpenLayers.Geometry,\n         \"Value is a geometry\");\n    t.eq(filter.distance, 6,\n         \"Distance is as specified in CQL\");\n\n    t.eq(format.write(filter), cql, \"write returned test cql\");\n\n}\n\nfunction test_CONTAINS(t) {\n    t.plan(5);\n    var format = new OpenLayers.Format.CQL(),\n        cql = \"CONTAINS(the_geom, POINT(1 2))\",\n        filter = format.read(cql);\n    t.ok(filter instanceof OpenLayers.Filter.Spatial,\n         \"Parsing BBOX expression produces Filter.Spatial\");\n    t.eq(filter.type, OpenLayers.Filter.Spatial.CONTAINS,\n         \"Spatial filter is a within filter\");\n    t.eq(filter.property, \"the_geom\",\n         \"Property name is as specified in CQL\");\n    t.ok(filter.value instanceof OpenLayers.Geometry,\n         \"Value is a geometry\");\n\n    t.eq(format.write(filter), cql, \"write returned test cql\");\n\n}\n\nfunction test_NOT(t) {\n    t.plan(4);\n    var format = new OpenLayers.Format.CQL(),\n        cql = \"NOT X < 12\",\n        filter = format.read(cql);\n    t.ok(filter instanceof OpenLayers.Filter.Logical,\n         \"Parsing NOT expression produces Logical.Not\");\n    t.eq(filter.type, OpenLayers.Filter.Logical.NOT,\n         \"Logical filter is a NOT filter\");\n    t.eq(filter.filters[0].property, \"X\",\n         \"Property name is as specified in CQL\");\n    t.eq(filter.filters[0].value, 12, \"Value is as specified in CQL\");\n}\n\nfunction test_NOT_write(t) {\n    // TODO: remove this if extra parentheses are avoided by checking logical operator precedence\n    t.plan(1);\n    var format = new OpenLayers.Format.CQL(),\n        cql = \"NOT (X < 12)\",\n        filter = format.read(cql);\n    t.eq(format.write(filter), cql, \"write returned test cql\");\n}\n\nfunction test_BETWEEN(t) {\n    t.plan(6);\n    var format = new OpenLayers.Format.CQL(),\n        cql = \"A BETWEEN 0 AND 5\",\n        filter = format.read(cql);\n    t.ok(filter instanceof OpenLayers.Filter.Comparison,\n         \"Parsing BETWEEN expression produces Filter.Comparison\");\n    t.eq(filter.type, OpenLayers.Filter.Comparison.BETWEEN,\n         \"Comparison filter is a between filter\");\n    t.eq(filter.property, \"A\",\n         \"Property name is as specified in CQL\");\n    t.eq(filter.lowerBoundary, 0, 'Lower boundary is as specified in CQL');\n    t.eq(filter.upperBoundary, 5, 'Upper bondary is as specified in CQL');\n\n    t.eq(format.write(filter), cql, \"write returned test cql\");\n\n}\n\nfunction test_NULL(t) {\n    t.plan(3);\n    var filter = new OpenLayers.Filter.Comparison({\n        property: \"GEOM\",\n        type: \"NULL\"\n    });\n    var format = new OpenLayers.Format.CQL();\n    var str = 'GEOM IS NULL';\n    t.eq(format.write(filter), str, \"NULL filter written correctly\");\n    filter = format.read(str);\n    t.eq(filter.type, OpenLayers.Filter.Comparison.IS_NULL, \"filter type is correctly parsed\");\n    t.eq(filter.property, \"GEOM\", \"filter property is correctly parsed\");\n}\n\n        </script>\n    </head>\n    <body></body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/CSWGetDomain/v2_0_2.html",
    "content": "<html> \n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script src=\"v2_0_2.js\"></script>\n    <script type=\"text/javascript\">\n\n    var format = new OpenLayers.Format.CSWGetDomain();\n    \n    function test_write(t) {\n\n        t.plan(1);\n\n        var options = {\n            PropertyName: \"type\"\n        };\n\n        var result = format.write(options);\n\n        t.eq(result, csw_request, \"check value returned by format \" +\n                \"CSWGetDomain: write method\");\n\n    }\n\n    \n    function test_read(t) {\n        \n        t.plan(9);\n        \n        var obj = format.read(csw_response);\n        \n        var domainValues = obj.DomainValues;\n        // test getRecordsResponse object\n        t.ok(domainValues, \"object contains DomainValues property\");\n\n        // test DomainValues\n        t.eq(domainValues.length, 1, \"object contains 1 object in DomainValues\");\n        var domainValue = domainValues[0];\n        t.eq(domainValue.type, \"csw:Record\", \"check value for attribute type\");\n        t.eq(domainValue.PropertyName, \"type\", \"check value for element PropertyName\");\n        t.ok(domainValue.ListOfValues, \"object contains ListOfValues property\");\n\n        // test ListOfValues\n        t.eq(domainValue.ListOfValues.length, 2, \"object contains 2 objects \" +\n                \"in ListOfValues\");\n        var val = domainValue.ListOfValues[0];\n        t.ok(val.Value, \"object contains Value property\");\n        t.eq(val.Value.my_attr, \"my_value\", \"check value for attribute my_attr\");\n        t.eq(val.Value.value, \"dataset\", \"check value for element Value\");\n        \n    }\n    \n    </script> \n</head> \n<body>\n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/CSWGetDomain/v2_0_2.js",
    "content": "var csw_request = \n'<csw:GetDomain xmlns:csw=\"http://www.opengis.net/cat/csw/2.0.2\" service=\"CSW\" version=\"2.0.2\">' +\n  '<csw:PropertyName>type</csw:PropertyName>' +\n'</csw:GetDomain>';\n\nvar csw_response = \n'<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n'<csw:GetDomainResponse xmlns:csw=\"http://www.opengis.net/cat/csw/2.0.2\">' +\n  '<csw:DomainValues type=\"csw:Record\">' +\n    '<csw:PropertyName>type</csw:PropertyName>' +\n    '<csw:ListOfValues>' +\n      '<csw:Value my_attr=\"my_value\">dataset</csw:Value>' +\n      '<csw:Value>service</csw:Value>' +\n    '</csw:ListOfValues>' +\n  '</csw:DomainValues>' +\n'</csw:GetDomainResponse>'\n;\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/CSWGetDomain.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(2);\n\n        var format = new OpenLayers.Format.CSWGetDomain();\n        t.ok(format instanceof OpenLayers.Format.CSWGetDomain.v2_0_2, \"constructor returns instance with default versioned format\");\n\n        format = new OpenLayers.Format.CSWGetDomain({\n            version: \"2.0.2\"\n        });\n        t.ok(format instanceof OpenLayers.Format.CSWGetDomain.v2_0_2, \"constructor returns instance with custom versioned format\");\n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:512px; height:256px\"> </div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/CSWGetRecords/v2_0_2.html",
    "content": "<html> \n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script src=\"v2_0_2.js\"></script>\n    <script type=\"text/javascript\">\n\n    var format = new OpenLayers.Format.CSWGetRecords();\n    \n    function test_write(t) {\n\n        t.plan(1);\n\n        var filter =  new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.LIKE,\n            property: \"my_prop\",\n            value: \"my_prop_value\"\n        });\n\n        var options = {\n            \"resultType\": \"results\",\n            \"startPosition\": \"10\",\n            \"maxRecords\": \"20\",\n            \"Query\": {\n                \"ElementSetName\": {\n                    \"value\": \"brief\"\n                },\n                \"Constraint\": {\n                    \"version\": \"1.1.0\",\n                    \"Filter\": filter\n                }\n            }\n        };\n\n        var result = format.write(options);\n\n        t.eq(result, csw_request, \"check value returned by format \" +\n                \"CSWGetRecords: write method\");\n\n    }\n\n    \n    function test_read(t) {\n        \n        t.plan(17);\n        \n        var obj = format.read(csw_response);\n                \n        var searchStatus = obj.SearchStatus;\n        var searchResults = obj.SearchResults;\n        var records = obj.records;\n        // test getRecordsResponse object\n        t.ok(searchStatus, \"object contains SearchStatus property\");\n        t.ok(searchResults, \"object contains SearchResults property\");\n        t.ok(records, \"object contains records property\");\n\n        // test SearchResults attributes\n        t.eq(searchResults.numberOfRecordsMatched, 10, \"check value for SearchResults.numberOfRecordsMatched\");\n        t.eq(searchResults.numberOfRecordsReturned, 2, \"check value for SearchResults.numberOfRecordsReturned\");\n        t.eq(searchResults.elementSet, \"brief\", \"check value for SearchResults.elementSet\");\n        t.eq(searchResults.nextRecord, 3, \"check value for SearchResults.nextRecord\");\n\n        // test records\n        t.eq(records.length, 2, \"object contains 10 records\");\n        var testRecord = records[0];\n        t.eq(testRecord.type, \"BriefRecord\", \"check value for record.type\");\n        t.eq(testRecord.title, [{value:\"Sample title\"}], \"check value for record.title\");\n\n        // test empty subject\n        t.eq(testRecord.subject, [], \"Empty subject tags are ignored\");\n\n        //test bbox\n        t.eq(testRecord.BoundingBox.length, 2, \"object contains 2 BoundingBoxes\");\n        var bbox = testRecord.BoundingBox[0];\n        t.ok(bbox, \"object contains BoundingBox properties\");\n        t.eq(bbox.crs, \"::Lambert Azimuthal Projection\", \"check value for BoundingBox.crs\");\n        t.eq(bbox.value, [156, -3, 37, 83], \"check value for record.BoundingBox\");\n        \n        // test gninfo\n        testRecord = records[1];\n        t.ok(testRecord.gninfo, \"object contains gninfo properties\");\n        t.eq(testRecord.gninfo.schema, \"iso19139\", \"check value for schema property in record.gninfo\");\n    }\n    \n    </script> \n</head> \n<body>\n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/CSWGetRecords/v2_0_2.js",
    "content": "var csw_request = \n'<csw:GetRecords xmlns:csw=\"http://www.opengis.net/cat/csw/2.0.2\" service=\"CSW\" version=\"2.0.2\" resultType=\"results\" startPosition=\"10\" maxRecords=\"20\" xmlns:gmd=\"http://www.isotc211.org/2005/gmd\">' +\n  '<csw:Query typeNames=\"csw:Record\">' +\n    '<csw:ElementSetName>brief</csw:ElementSetName>' +\n    '<csw:Constraint version=\"1.1.0\">' +\n      '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n        '<ogc:PropertyIsLike wildCard=\"*\" singleChar=\".\" escapeChar=\"!\">' +\n          '<ogc:PropertyName>my_prop</ogc:PropertyName>' +\n          '<ogc:Literal>my_prop_value</ogc:Literal>' +\n        '</ogc:PropertyIsLike>' +\n      '</ogc:Filter>' +\n    '</csw:Constraint>' +\n  '</csw:Query>' +\n'</csw:GetRecords>';\n\nvar csw_response = \n'<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n'<csw:GetRecordsResponse xmlns:csw=\"http://www.opengis.net/cat/csw/2.0.2\">' +\n  '<csw:SearchStatus timestamp=\"2009-06-08T12:03:34\" />' +\n  '<csw:SearchResults numberOfRecordsMatched=\"10\" numberOfRecordsReturned=\"2\" elementSet=\"brief\" nextRecord=\"3\">' +\n    '<csw:BriefRecord xmlns:geonet=\"http://www.fao.org/geonetwork\" xmlns:ows=\"http://www.opengis.net/ows\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">' +\n      '<dc:identifier>895ac38b-7aef-4a21-b593-b35a6fc7bba9</dc:identifier>' +\n      '<dc:title>Sample title</dc:title>' +\n      '<dc:subject />' +\n      '<dc:subject />' +\n      '<ows:BoundingBox crs=\"::Lambert Azimuthal Projection\">' +\n        '<ows:LowerCorner>156 -3</ows:LowerCorner>' +\n        '<ows:UpperCorner>37 83</ows:UpperCorner>' +\n      '</ows:BoundingBox>' +\n      '<ows:BoundingBox crs=\"::WGS 1984\">' +\n        '<ows:LowerCorner>51.1 -34.6</ows:LowerCorner>' +\n        '<ows:UpperCorner>-17.3 38.2</ows:UpperCorner>' +\n      '</ows:BoundingBox>' +\n    '</csw:BriefRecord>' +\n    '<csw:BriefRecord xmlns:geonet=\"http://www.fao.org/geonetwork\" xmlns:ows=\"http://www.opengis.net/ows\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">' +\n      '<dc:identifier>8a7245c3-8546-42de-8e6f-8fb8b5fd1bc3</dc:identifier>' +\n      '<dc:title>Second record : sample title</dc:title>' +\n      '<ows:BoundingBox crs=\"::WGS 1984\">' +\n        '<ows:LowerCorner>51.1 -34.6</ows:LowerCorner>' +\n        '<ows:UpperCorner>-17.3 38.2</ows:UpperCorner>' +\n      '</ows:BoundingBox>' +\n      '<geonet:info xmlns:gmd=\"http://www.isotc211.org/2005/gmd\" xmlns:gco=\"http://www.isotc211.org/2005/gco\" xmlns:gts=\"http://www.isotc211.org/2005/gts\" xmlns:gml=\"http://www.opengis.net/gml\">' +\n        '<id>859</id>' +\n        '<schema>iso19139</schema>' +\n      '</geonet:info>' +\n    '</csw:BriefRecord>' +\n  '</csw:SearchResults>' +\n'</csw:GetRecordsResponse>'\n;\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/CSWGetRecords.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(2);\n\n        var format = new OpenLayers.Format.CSWGetRecords();\n        t.ok(format instanceof OpenLayers.Format.CSWGetRecords.v2_0_2, \"constructor returns instance with default versioned format\");\n\n        format = new OpenLayers.Format.CSWGetRecords({\n            version: \"2.0.2\"\n        });\n        t.ok(format instanceof OpenLayers.Format.CSWGetRecords.v2_0_2, \"constructor returns instance with custom versioned format\");\n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:512px; height:256px\"> </div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/EncodedPolyline.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    var flatPoints;\n    var floats, smallFloats, encodedFloats;\n    var signedIntegers, encodedSignedIntegers;\n    var unsignedIntegers, encodedUnsignedIntegers;\n\n    function resetTestingData() {\n        flatPoints = [38.50000, -120.20000,\n                      40.70000, -120.95000,\n                      43.25200, -126.45300];\n\n        floats = [0.00, 0.15, -0.01, -0.16, 0.16, 0.01];\n        smallFloats = [0.00000, 0.00015, -0.00001, -0.00016, 0.00016, 0.00001];\n        encodedFloats = '?]@^_@A';\n\n        signedIntegers = [0, 15, -1, -16, 16, 1];\n        encodedSignedIntegers = '?]@^_@A';\n\n        unsignedIntegers = [0, 30, 1, 31, 32, 2, 174];\n        encodedUnsignedIntegers = '?]@^_@AmD';\n    }\n\n    var basePoints = new Array(\n        new Array(3850000, -12020000),\n        new Array(4070000, -12095000),\n        new Array(4325200, -12645300)\n    );\n\n    var points = [\n        new OpenLayers.Geometry.Point(-120.200, 38.500),\n        new OpenLayers.Geometry.Point(-120.950, 40.700),\n        new OpenLayers.Geometry.Point(-126.453, 43.252)\n    ];\n\n    var singlePoint = new OpenLayers.Feature.Vector(points[0]);\n\n    var linestring = new OpenLayers.Feature.Vector(\n        new OpenLayers.Geometry.LineString(points)\n    );\n\n    var multipoint = new OpenLayers.Feature.Vector(\n        new OpenLayers.Geometry.MultiPoint(points)\n    );\n\n    var linearring = new OpenLayers.Feature.Vector(\n        new OpenLayers.Geometry.LinearRing(points)\n    );\n\n    var polygon = new OpenLayers.Feature.Vector(\n        new OpenLayers.Geometry.Polygon([\n            new OpenLayers.Geometry.LinearRing(points)\n        ])\n    );\n\n    var encoded = \"_p~iF~ps|U_ulLnnqC_mqNvxq`@\";\n\n    function test_Format_EncodedPolyline_constructor(t) {\n        t.plan(4);\n\n        var options = {'foo': 'bar'};\n        var format = new OpenLayers.Format.EncodedPolyline(options);\n        t.ok(format instanceof OpenLayers.Format.EncodedPolyline,\n             \"new OpenLayers.Format.EncodedPolyline returns object\" );\n        t.eq(format.foo, \"bar\", \"constructor sets options correctly\");\n        t.eq(typeof format.read, \"function\", \"format has a read function\");\n        t.eq(typeof format.write, \"function\", \"format has a write function\");\n    }\n\n    function test_Format_EncodedPolyline_read(t) {\n        t.plan(5);\n\n        var format = new OpenLayers.Format.EncodedPolyline();\n\n        t.ok(linestring.geometry.equals(format.read(encoded).geometry),\n             \"format correctly reads encoded polyline\");\n\n        format = new OpenLayers.Format.EncodedPolyline({\n            geometryType: \"multipoint\"\n        });\n        t.ok(multipoint.geometry.equals(format.read(encoded).geometry),\n             \"format correctly reads encoded multipoint\");\n\n        format.geometryType = \"linearring\";\n        t.ok(linearring.geometry.equals(format.read(encoded).geometry),\n             \"format correctly reads encoded linearring\");\n\n        format.geometryType = \"polygon\";\n        t.ok(polygon.geometry.equals(format.read(encoded).geometry),\n             \"format correctly reads encoded polygon\");\n\n        format.geometryType = \"point\";\n        t.ok(points[0].equals(format.read(encoded).geometry),\n             \"format correctly reads encoded point\");\n    }\n\n    function test_Format_EncodedPolyline_decode(t) {\n        t.plan(6);\n\n        var format = new OpenLayers.Format.EncodedPolyline();\n\n        var decodedPoints = format.decode(encoded, 2);\n        for (i in decodedPoints) {\n            var point = basePoints[i];\n            var decodedPoint = decodedPoints[i];\n            t.eq(parseInt(decodedPoint[0] * 1e5), point[0]);\n            t.eq(parseInt(decodedPoint[1] * 1e5), point[1]);\n        }\n    }\n\n    function test_Format_EncodedPolyline_write(t) {\n        t.plan(5);\n\n        var format = new OpenLayers.Format.EncodedPolyline();\n\n        t.eq(format.write(linestring), encoded,\n             \"format correctly writes encoded polyline\");\n\n        t.eq(format.write(multipoint), encoded,\n             \"format correctly writes encoded multipoint\");\n\n        // Different output than encoded,\n        // because polygon closing point is included\n        t.eq(format.write(linearring),\n             \"_p~iF~ps|U_ulLnnqC_mqNvxq`@~b_\\\\ghde@\",\n             \"format correctly writes encoded linearring\");\n\n        t.eq(format.write(polygon),\n             \"_p~iF~ps|U_ulLnnqC_mqNvxq`@~b_\\\\ghde@\",\n             \"format correctly writes encoded polygon\");\n\n        t.eq(format.write(singlePoint), \"_p~iF~ps|U\",\n             \"format correctly writes encoded point\");\n    }\n\n    function test_Format_EncodedPolyline_encode(t) {\n        t.plan(1);\n\n        var format = new OpenLayers.Format.EncodedPolyline();\n\n        t.eq(format.encode(basePoints, 2, 1), encoded);\n    }\n\n    function test_encodeDeltas_returns_expected_value(t) {\n        t.plan(1);\n        resetTestingData();\n\n        var format = new OpenLayers.Format.EncodedPolyline();\n\n        t.eq(format.encodeDeltas(flatPoints, 2), encoded);\n    }\n\n    function test_decodeDeltas_returns_expected_value(t) {\n        t.plan(1);\n        resetTestingData();\n\n        var format = new OpenLayers.Format.EncodedPolyline();\n\n        t.eq(format.decodeDeltas(encoded, 2), flatPoints);\n    }\n\n\n\n    function test_encodeFloats_returns_expected_value(t) {\n        t.plan(3);\n        resetTestingData();\n\n        var format = new OpenLayers.Format.EncodedPolyline();\n\n        t.eq(format.encodeFloats(smallFloats), encodedFloats);\n\n        resetTestingData();\n        t.eq(format.encodeFloats(smallFloats, 1e5), encodedFloats);\n\n        t.eq(format.encodeFloats(floats, 1e2), encodedFloats);\n    }\n\n    function test_decodeFloats_returns_expected_value(t) {\n        t.plan(3);\n        resetTestingData();\n\n        var format = new OpenLayers.Format.EncodedPolyline();\n\n        t.eq(format.decodeFloats(encodedFloats), smallFloats);\n        t.eq(format.decodeFloats(encodedFloats, 1e5), smallFloats);\n        t.eq(format.decodeFloats(encodedFloats, 1e2), floats);\n    }\n\n\n\n    function test_encodeSignedIntegers_returns_expected_value(t) {\n        t.plan(1);\n        resetTestingData();\n\n        var format = new OpenLayers.Format.EncodedPolyline();\n\n        t.eq(format.encodeSignedIntegers(\n            signedIntegers), encodedSignedIntegers);\n    }\n\n    function test_decodeSignedIntegers_returns_expected_value(t) {\n        t.plan(1);\n        resetTestingData();\n\n        var format = new OpenLayers.Format.EncodedPolyline();\n\n        t.eq(format.decodeSignedIntegers(\n            encodedSignedIntegers), signedIntegers);\n    }\n\n\n\n    function test_encodeUnsignedIntegers_returns_expected_value(t) {\n        t.plan(1);\n        resetTestingData();\n\n        var format = new OpenLayers.Format.EncodedPolyline();\n\n        t.eq(format.encodeUnsignedIntegers(\n            unsignedIntegers), encodedUnsignedIntegers);\n    }\n\n    function test_decodeUnsignedIntegers_returns_expected_value(t) {\n        t.plan(1);\n        resetTestingData();\n\n        var format = new OpenLayers.Format.EncodedPolyline();\n\n        t.eq(format.decodeUnsignedIntegers(\n          encodedUnsignedIntegers), unsignedIntegers);\n    }\n\n\n\n    function test_encodeFloat_returns_expected_value(t) {\n        t.plan(12);\n        resetTestingData();\n\n        var format = new OpenLayers.Format.EncodedPolyline();\n\n        t.eq(format.encodeFloat(0.00000), '?');\n        t.eq(format.encodeFloat(-0.00001), '@');\n        t.eq(format.encodeFloat(0.00001), 'A');\n        t.eq(format.encodeFloat(-0.00002), 'B');\n        t.eq(format.encodeFloat(0.00002), 'C');\n        t.eq(format.encodeFloat(0.00015), ']');\n        t.eq(format.encodeFloat(-0.00016), '^');\n\n        t.eq(format.encodeFloat(-0.1, 10), '@');\n        t.eq(format.encodeFloat(0.1, 10), 'A');\n\n        t.eq(format.encodeFloat(16 * 32 / 1e5), '__@');\n        t.eq(format.encodeFloat(16 * 32 * 32 / 1e5), '___@');\n\n        // from the \"Encoded Polyline Algorithm Format\" page at Google\n        t.eq(format.encodeFloat(-179.9832104), '`~oia@');\n    }\n\n    function test_decodeFloat_returns_expected_value(t) {\n        t.plan(12);\n        resetTestingData();\n\n        var format = new OpenLayers.Format.EncodedPolyline();\n\n        t.eq(format.decodeFloat('?'), 0.00000);\n        t.eq(format.decodeFloat('@'), -0.00001);\n        t.eq(format.decodeFloat('A'), 0.00001);\n        t.eq(format.decodeFloat('B'), -0.00002);\n        t.eq(format.decodeFloat('C'), 0.00002);\n        t.eq(format.decodeFloat(']'), 0.00015);\n        t.eq(format.decodeFloat('^'), -0.00016);\n\n        t.eq(format.decodeFloat('@', 10), -0.1);\n        t.eq(format.decodeFloat('A', 10), 0.1);\n\n        t.eq(format.decodeFloat('__@'), 16 * 32 / 1e5);\n        t.eq(format.decodeFloat('___@'), 16 * 32 * 32 / 1e5);\n\n        // from the \"Encoded Polyline Algorithm Format\" page at Google\n        t.eq(format.decodeFloat('`~oia@'), -179.98321);\n    }\n\n\n\n    function test_encodeSignedInteger_returns_expected_value(t) {\n        t.plan(10);\n        resetTestingData();\n\n        var format = new OpenLayers.Format.EncodedPolyline();\n\n        t.eq(format.encodeSignedInteger(0), '?');\n        t.eq(format.encodeSignedInteger(-1), '@');\n        t.eq(format.encodeSignedInteger(1), 'A');\n        t.eq(format.encodeSignedInteger(-2), 'B');\n        t.eq(format.encodeSignedInteger(2), 'C');\n        t.eq(format.encodeSignedInteger(15), ']');\n        t.eq(format.encodeSignedInteger(-16), '^');\n\n        t.eq(format.encodeSignedInteger(16), '_@');\n        t.eq(format.encodeSignedInteger(16 * 32), '__@');\n        t.eq(format.encodeSignedInteger(16 * 32 * 32), '___@');\n    }\n\n    function test_decodeSignedInteger_returns_expected_value(t) {\n        t.plan(10);\n        resetTestingData();\n\n        var format = new OpenLayers.Format.EncodedPolyline();\n\n        t.eq(format.decodeSignedInteger('?'), 0);\n        t.eq(format.decodeSignedInteger('@'), -1);\n        t.eq(format.decodeSignedInteger('A'), 1);\n        t.eq(format.decodeSignedInteger('B'), -2);\n        t.eq(format.decodeSignedInteger('C'), 2);\n        t.eq(format.decodeSignedInteger(']'), 15);\n        t.eq(format.decodeSignedInteger('^'), -16);\n\n        t.eq(format.decodeSignedInteger('__@'), 16 * 32);\n        t.eq(format.decodeSignedInteger('___@'), 16 * 32 * 32);\n        t.eq(format.decodeSignedInteger('_@'), 16);\n    }\n\n\n\n    function test_encodeUnsignedInteger_returns_expected_value(t) {\n        t.plan(10);\n\n        var format = new OpenLayers.Format.EncodedPolyline();\n\n        t.eq(format.encodeUnsignedInteger(0), '?');\n        t.eq(format.encodeUnsignedInteger(1), '@');\n        t.eq(format.encodeUnsignedInteger(2), 'A');\n        t.eq(format.encodeUnsignedInteger(30), ']');\n        t.eq(format.encodeUnsignedInteger(31), '^');\n        t.eq(format.encodeUnsignedInteger(32), '_@');\n\n        t.eq(format.encodeUnsignedInteger(32 * 32), '__@');\n        t.eq(format.encodeUnsignedInteger(5 * 32 * 32), '__D');\n        t.eq(format.encodeUnsignedInteger(32 * 32 * 32), '___@');\n\n        // from the \"Encoded Polyline Algorithm Format\" page at Google\n        t.eq(format.encodeUnsignedInteger(174), 'mD');\n    }\n\n    function test_decodeUnsignedInteger_returns_expected_value(t) {\n        t.plan(10);\n\n        var format = new OpenLayers.Format.EncodedPolyline();\n\n        t.eq(format.decodeUnsignedInteger('?'), 0);\n        t.eq(format.decodeUnsignedInteger('@'), 1);\n        t.eq(format.decodeUnsignedInteger('A'), 2);\n        t.eq(format.decodeUnsignedInteger(']'), 30);\n        t.eq(format.decodeUnsignedInteger('^'), 31);\n        t.eq(format.decodeUnsignedInteger('_@'), 32);\n\n        t.eq(format.decodeUnsignedInteger('__@'), 32 * 32);\n        t.eq(format.decodeUnsignedInteger('__D'), 5 * 32 * 32);\n        t.eq(format.decodeUnsignedInteger('___@'), 32 * 32 * 32);\n\n        // from the \"Encoded Polyline Algorithm Format\" page at Google\n        t.eq(format.decodeUnsignedInteger('mD'), 174);\n    }\n\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/Filter/v1.html",
    "content": "<html> \n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    \n    function test_PropertyIsBetween(t) {\n\n        t.plan(6);\n\n        var test_xml, parser, xml;\n\n        parser = new OpenLayers.Format.Filter.v1();\n        xml = new OpenLayers.Format.XML();\n\n        test_xml =\n            '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                '<ogc:PropertyIsBetween>' +\n                    '<ogc:PropertyName>number</ogc:PropertyName>' +\n                    '<ogc:LowerBoundary>' +\n                        '<ogc:Literal>0</ogc:Literal>' +\n                    '</ogc:LowerBoundary>' +\n                    '<ogc:UpperBoundary>' +\n                        '<ogc:Literal>100</ogc:Literal>' +\n                    '</ogc:UpperBoundary>' +\n                '</ogc:PropertyIsBetween>' +\n            '</ogc:Filter>';\n\n        var filter = parser.read(xml.read(test_xml).documentElement);\n        t.eq(filter.type, OpenLayers.Filter.Comparison.BETWEEN,\n             \"[0] read correct type\");\n        t.eq(filter.lowerBoundary, 0,\n             \"[0] record correct lower boundary value\");\n        t.eq(filter.upperBoundary, 100,\n             \"[0] record correct upper boundary value\");\n\n        test_xml =\n            '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                '<ogc:PropertyIsBetween>' +\n                    '<ogc:PropertyName>number</ogc:PropertyName>' +\n                    '<ogc:LowerBoundary>0</ogc:LowerBoundary>' +\n                    '<ogc:UpperBoundary>100</ogc:UpperBoundary>' +\n                '</ogc:PropertyIsBetween>' +\n            '</ogc:Filter>';\n\n        var filter = parser.read(xml.read(test_xml).documentElement);\n        t.eq(filter.type, OpenLayers.Filter.Comparison.BETWEEN,\n             \"[1] read correct type\");\n        t.eq(filter.lowerBoundary, 0,\n             \"[1] record correct lower boundary value\");\n        t.eq(filter.upperBoundary, 100,\n             \"[1] record correct upper boundary value\");\n    }\n\n    function test_PropertyIsNull(t) {\n\n        t.plan(3);\n\n        var format, test_xml, xml, filter, node;\n\n        format = new OpenLayers.Format.Filter.v1();\n\n        test_xml =\n            '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                '<ogc:PropertyIsNull>' +\n                    '<ogc:PropertyName>prop</ogc:PropertyName>' +\n                '</ogc:PropertyIsNull>' +\n            '</ogc:Filter>';\n\n        // Test reading a PropertyIsNull filter from an XML doc\n        xml = new OpenLayers.Format.XML();\n        filter = format.read(xml.read(test_xml).documentElement);\n        t.eq(filter.type, OpenLayers.Filter.Comparison.IS_NULL,\n             \"[0] read correct type\");\n        t.eq(filter.property, 'prop',\n             \"[0] record correct property name\");\n\n        // Test writing a PropertyIsNull filter out to XML\n        filter = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.IS_NULL,\n            property: \"prop\"\n        });\n        node = format.write(filter);\n        t.xml_eq(node, test_xml, \"filter correctly written\");\n\n    }\n\n    function test_Intersects(t) {\n        \n        t.plan(4);\n        \n        var str =\n            '<Filter xmlns=\"http://www.opengis.net/ogc\">' +\n                '<Intersects>' +\n                    '<PropertyName>Geometry</PropertyName>' +\n                    '<gml:Polygon xmlns:gml=\"http://www.opengis.net/gml\">' +\n                        '<gml:outerBoundaryIs>' +\n                            '<gml:LinearRing>' +\n                                '<gml:coordinates decimal=\".\" cs=\",\" ts=\" \">2488789,289552 2588789,289552 2588789,389552 2488789,389552 2488789,289552</gml:coordinates>' +\n                            '</gml:LinearRing>' +\n                        '</gml:outerBoundaryIs>' +\n                    '</gml:Polygon>' +\n                '</Intersects>' +\n            '</Filter>';\n\n        var format = new OpenLayers.Format.Filter.v1_0_0();\n        var filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.INTERSECTS,\n            property: \"Geometry\",\n            value: OpenLayers.Geometry.fromWKT(\"POLYGON((2488789 289552, 2588789 289552, 2588789 389552, 2488789 389552, 2488789 289552))\")\n        });\n        \n        // test writing\n        var node = format.write(filter);\n        t.xml_eq(node, str, \"filter correctly written\");\n        \n        // test reading\n        var doc = (new OpenLayers.Format.XML).read(str);\n        var got = format.read(doc.firstChild);\n        t.eq(got.type, filter.type, \"read correct type\");\n        t.eq(got.property, filter.property, \"read correct property\");\n        t.geom_eq(got.value, filter.value, \"read correct value\");\n\n    }\n\n    function test_Within(t) {\n        \n        t.plan(4);\n        \n        var str =\n            '<Filter xmlns=\"http://www.opengis.net/ogc\">' +\n                '<Within>' +\n                    '<PropertyName>Geometry</PropertyName>' +\n                    '<gml:Polygon xmlns:gml=\"http://www.opengis.net/gml\">' +\n                        '<gml:outerBoundaryIs>' +\n                            '<gml:LinearRing>' +\n                                '<gml:coordinates decimal=\".\" cs=\",\" ts=\" \">2488789,289552 2588789,289552 2588789,389552 2488789,389552 2488789,289552</gml:coordinates>' +\n                            '</gml:LinearRing>' +\n                        '</gml:outerBoundaryIs>' +\n                    '</gml:Polygon>' +\n                '</Within>' +\n            '</Filter>';\n\n        var format = new OpenLayers.Format.Filter.v1_0_0();\n        var filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.WITHIN,\n            property: \"Geometry\",\n            value: OpenLayers.Geometry.fromWKT(\"POLYGON((2488789 289552, 2588789 289552, 2588789 389552, 2488789 389552, 2488789 289552))\")\n        });\n        \n        // test writing\n        var node = format.write(filter);\n        t.xml_eq(node, str, \"filter correctly written\");\n        \n        // test reading\n        var doc = (new OpenLayers.Format.XML).read(str);\n        var got = format.read(doc.firstChild);\n        t.eq(got.type, filter.type, \"read correct type\");\n        t.eq(got.property, filter.property, \"read correct property\");\n        t.geom_eq(got.value, filter.value, \"read correct value\");\n\n    }\n\n    function test_Contains(t) {\n        \n        t.plan(4);\n        \n        var str =\n            '<Filter xmlns=\"http://www.opengis.net/ogc\">' +\n                '<Contains>' +\n                    '<PropertyName>Geometry</PropertyName>' +\n                    '<gml:Polygon xmlns:gml=\"http://www.opengis.net/gml\">' +\n                        '<gml:outerBoundaryIs>' +\n                            '<gml:LinearRing>' +\n                                '<gml:coordinates decimal=\".\" cs=\",\" ts=\" \">2488789,289552 2588789,289552 2588789,389552 2488789,389552 2488789,289552</gml:coordinates>' +\n                            '</gml:LinearRing>' +\n                        '</gml:outerBoundaryIs>' +\n                    '</gml:Polygon>' +\n                '</Contains>' +\n            '</Filter>';\n\n        var format = new OpenLayers.Format.Filter.v1_0_0();\n        var filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.CONTAINS,\n            property: \"Geometry\",\n            value: OpenLayers.Geometry.fromWKT(\"POLYGON((2488789 289552, 2588789 289552, 2588789 389552, 2488789 389552, 2488789 289552))\")\n        });\n        \n        // test writing\n        var node = format.write(filter);\n        t.xml_eq(node, str, \"filter correctly written\");\n        \n        // test reading\n        var doc = (new OpenLayers.Format.XML).read(str);\n        var got = format.read(doc.firstChild);\n        t.eq(got.type, filter.type, \"read correct type\");\n        t.eq(got.property, filter.property, \"read correct property\");\n        t.geom_eq(got.value, filter.value, \"read correct value\");\n\n    }\n\n    function test_logical_fid(t) {\n        // the Filter Encoding spec doesn't allow for FID filters inside logical filters\n        // however, to be liberal, we will write them without complaining\n        t.plan(3);\n\n        var filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.OR,\n            filters: [\n                new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.LIKE,\n                    property: \"person\",\n                    value: \"me\"\n                }),\n                new OpenLayers.Filter.FeatureId({fids: [\"foo.1\", \"foo.2\"]})\n            ]\n        });\n        var format = new OpenLayers.Format.Filter.v1_0_0();\n        \n        var got = format.write(filter);\n        var exp = readXML(\"LogicalFeatureId\");\n        t.xml_eq(got, exp, \"wrote FID filter in logical OR without complaint\");\n\n        filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.AND,\n            filters: [\n                new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.LIKE,\n                    property: \"person\",\n                    value: \"me\"\n                }),\n                new OpenLayers.Filter.FeatureId({fids: [\"foo.1\", \"foo.2\"]})\n            ]\n        });\n        got = format.write(filter);\n        exp = readXML(\"LogicalFeatureIdAnd\");\n        t.xml_eq(got, exp, \"wrote FID filter in logical AND without complaint\");\n\n        filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.NOT,\n            filters: [\n                new OpenLayers.Filter.FeatureId({fids: [\"foo.2\"]})\n            ]\n        });\n        got = format.write(filter);\n        exp = readXML(\"LogicalFeatureIdNot\");\n        t.xml_eq(got, exp, \"wrote FID filter in logical NOT without complaint\");\n    }\n\n    function test_between_literal(t) {\n        t.plan(3);\n\n        var filter = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.BETWEEN,\n            property: \"foo\",\n            lowerBoundary: 1.0,\n            upperBoundary: 2.0\n        });\n        var format = new OpenLayers.Format.Filter.v1_0_0();\n        \n        var exp = format.read(readXML(\"BetweenLiteral\"));\n\n        // confirm that reading works as expected\n        t.eq(exp.property, \"foo\", \"property\");\n        t.eq(exp.lowerBoundary, 1.0, \"lowerBoundary\");\n        t.eq(exp.upperBoundary, 2.0, \"upperBoundary\");\n    }\n\n\n    function test_date_writing(t) {\n        t.plan(1);\n\n        // ISO 8601: 2010-11-27T18:19:15.123Z\n        var start = new Date(Date.UTC(2010, 10, 27, 18, 19, 15, 123));\n\n        // ISO 8601: 2011-12-27T18:19:15.123Z\n        var end = new Date(Date.UTC(2011, 11, 27, 18, 19, 15, 123));\n\n        var filter = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.BETWEEN,\n            property: \"when\",\n            lowerBoundary: start,\n            upperBoundary: end\n        });\n\n        var format = new OpenLayers.Format.Filter.v1_0_0();\n\n        var got = format.write(filter);\n        var exp = readXML(\"BetweenDates\");\n        t.xml_eq(got, exp, \"comparison filter with dates\");\n    }\n\n\n    function test_custom_date_writing(t) {\n        t.plan(1);\n\n        // ISO 8601: 2010-11-27T18:19:15.123Z\n        var start = new Date(Date.UTC(2010, 10, 27, 18, 19, 15, 123));\n\n        // ISO 8601: 2011-12-27T18:19:15.123Z\n        var end = new Date(Date.UTC(2011, 11, 27, 18, 19, 15, 123));\n\n        var filter = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.BETWEEN,\n            property: \"when\",\n            lowerBoundary: start,\n            upperBoundary: end\n        });\n\n        var format = new OpenLayers.Format.Filter({\n            encodeLiteral: function(value) {\n                // return just the date and not the time portion\n                return OpenLayers.Date.toISOString(value).split(\"T\").shift();\n            }\n        });\n\n        var got = format.write(filter);\n        var exp = readXML(\"CustomBetweenDates\");\n        t.xml_eq(got, exp, \"comparison filter with dates\");\n    }\n\n\n    function readXML(id) {\n        var xml = document.getElementById(id).firstChild.nodeValue;\n        return new OpenLayers.Format.XML().read(xml).documentElement;\n    }\n\n\n    </script> \n</head> \n<body>\n\n<div id=\"LogicalFeatureId\"><!--\n<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n    <ogc:Or>\n        <ogc:PropertyIsLike wildCard=\"*\" singleChar=\".\" escape=\"!\">\n            <ogc:PropertyName>person</ogc:PropertyName>\n            <ogc:Literal>me</ogc:Literal>\n        </ogc:PropertyIsLike>\n        <ogc:FeatureId fid=\"foo.1\"/>\n        <ogc:FeatureId fid=\"foo.2\"/>\n    </ogc:Or>\n</ogc:Filter>\n--></div>\n<div id=\"LogicalFeatureIdAnd\"><!--\n<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n    <ogc:And>\n        <ogc:PropertyIsLike wildCard=\"*\" singleChar=\".\" escape=\"!\">\n            <ogc:PropertyName>person</ogc:PropertyName>\n            <ogc:Literal>me</ogc:Literal>\n        </ogc:PropertyIsLike>\n        <ogc:FeatureId fid=\"foo.1\"/>\n        <ogc:FeatureId fid=\"foo.2\"/>\n    </ogc:And>\n</ogc:Filter>\n--></div>\n<div id=\"LogicalFeatureIdNot\"><!--\n<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n    <ogc:Not>\n        <ogc:FeatureId fid=\"foo.2\"/>\n    </ogc:Not>\n</ogc:Filter>\n--></div>\n<div id=\"BetweenLiteral\"><!--\n<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n    <ogc:PropertyIsBetween>\n        <ogc:PropertyName>foo</ogc:PropertyName>\n        <ogc:LowerBoundary>\n            <ogc:Literal>1.0</ogc:Literal>\n        </ogc:LowerBoundary>\n        <ogc:UpperBoundary>\n            <ogc:Literal>2.0</ogc:Literal>\n        </ogc:UpperBoundary>\n    </ogc:PropertyIsBetween>\n</ogc:Filter>\n--></div>\n<div id=\"BetweenDates\"><!--\n<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n    <ogc:PropertyIsBetween>\n        <ogc:PropertyName>when</ogc:PropertyName>\n        <ogc:LowerBoundary>\n            <ogc:Literal>2010-11-27T18:19:15.123Z</ogc:Literal>\n        </ogc:LowerBoundary>\n        <ogc:UpperBoundary>\n            <ogc:Literal>2011-12-27T18:19:15.123Z</ogc:Literal>\n        </ogc:UpperBoundary>\n    </ogc:PropertyIsBetween>\n</ogc:Filter>\n--></div>\n<div id=\"CustomBetweenDates\"><!--\n<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n    <ogc:PropertyIsBetween>\n        <ogc:PropertyName>when</ogc:PropertyName>\n        <ogc:LowerBoundary>\n            <ogc:Literal>2010-11-27</ogc:Literal>\n        </ogc:LowerBoundary>\n        <ogc:UpperBoundary>\n            <ogc:Literal>2011-12-27</ogc:Literal>\n        </ogc:UpperBoundary>\n    </ogc:PropertyIsBetween>\n</ogc:Filter>\n--></div>\n\n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/Filter/v1_0_0.html",
    "content": "<html> \n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    \n    var test_xml =\n        '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n            '<ogc:Or>' +\n                '<ogc:PropertyIsBetween>' +\n                    '<ogc:PropertyName>number</ogc:PropertyName>' +\n                    '<ogc:LowerBoundary>' +\n                        '<ogc:Literal>1064866676</ogc:Literal>' +\n                    '</ogc:LowerBoundary>' +\n                    '<ogc:UpperBoundary>' +\n                        '<ogc:Literal>1065512599</ogc:Literal>' +\n                    '</ogc:UpperBoundary>' +\n                '</ogc:PropertyIsBetween>' +\n                '<ogc:PropertyIsLike wildCard=\"*\" singleChar=\".\" escape=\"!\">' +\n                    '<ogc:PropertyName>cat</ogc:PropertyName>' +\n                    '<ogc:Literal>*dog.food!*good</ogc:Literal>' +\n                '</ogc:PropertyIsLike>' +\n                '<ogc:Not>' +\n                    '<ogc:PropertyIsLessThanOrEqualTo>' +\n                        '<ogc:PropertyName>FOO</ogc:PropertyName>' +\n                        '<ogc:Literal>5000</ogc:Literal>' +\n                    '</ogc:PropertyIsLessThanOrEqualTo>' +\n                '</ogc:Not>' +\n            '</ogc:Or>' +\n        '</ogc:Filter>';\n\n    function test_read(t) {\n        t.plan(3);\n\n        var parser = new OpenLayers.Format.Filter.v1_0_0();\n        var xml = new OpenLayers.Format.XML();\n        var filter = parser.read(xml.read(test_xml).documentElement);\n\n        t.ok(filter instanceof OpenLayers.Filter.Logical, \"instance of correct class\");\n        t.eq(filter.type, OpenLayers.Filter.Logical.OR, \"correct type\");\n        t.eq(filter.filters.length, 3, \"correct number of child filters\");\n    }\n    \n    function test_write(t) {\n        t.plan(1);\n\n        // read first - testing that write produces the ogc:Filter element above\n        var parser = new OpenLayers.Format.Filter.v1_0_0();\n        var xml = new OpenLayers.Format.XML();\n        var filter = parser.read(xml.read(test_xml).documentElement);\n        \n        var node = parser.write(filter);\n        t.xml_eq(node, test_xml, \"filter correctly written\");\n        \n    }\n    \n    function test_BBOX(t) {\n        t.plan(1);\n        var filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.BBOX,\n            property: \"the_geom\",\n            value: new OpenLayers.Bounds(-180, -90, 180, 90),\n            projection: \"EPSG:4326\"\n        });\n        \n        var out =\n            '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                '<ogc:BBOX>' +\n                    '<ogc:PropertyName>the_geom</ogc:PropertyName>' +\n                    '<gml:Box xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"EPSG:4326\">' +\n                        '<gml:coordinates decimal=\".\" cs=\",\" ts=\" \">-180,-90 180,90</gml:coordinates>' +\n                    '</gml:Box>' +\n                '</ogc:BBOX>' +\n            '</ogc:Filter>';\n        \n        var parser = new OpenLayers.Format.Filter.v1_0_0();\n        var node = parser.write(filter);\n        \n        t.xml_eq(node, out, \"bbox correctly written\");\n    }\n\n    function test_BBOX_noGeometryName(t) {\n        t.plan(1);\n        // WFS 1.0.0 does not allow BBOX filters without property, but\n        // GeoServer accepts them.\n        var filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.BBOX,\n            value: new OpenLayers.Bounds(-180, -90, 180, 90),\n            projection: \"EPSG:4326\"\n        });\n        \n        var out =\n            '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                '<ogc:BBOX>' +\n                    '<gml:Box xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"EPSG:4326\">' +\n                        '<gml:coordinates decimal=\".\" cs=\",\" ts=\" \">-180,-90 180,90</gml:coordinates>' +\n                    '</gml:Box>' +\n                '</ogc:BBOX>' +\n            '</ogc:Filter>';\n        \n        var parser = new OpenLayers.Format.Filter.v1_0_0();\n        var node = parser.write(filter);\n        \n        t.xml_eq(node, out, \"bbox correctly written\");\n    }\n\n    function test_DWithin(t) {\n        \n        t.plan(6);\n        \n        var str =\n            '<Filter xmlns=\"http://www.opengis.net/ogc\">' +\n                '<DWithin>' +\n                    '<PropertyName>Geometry</PropertyName>' +\n                    '<gml:Point xmlns:gml=\"http://www.opengis.net/gml\">' +\n                        '<gml:coordinates decimal=\".\" cs=\",\" ts=\" \">2488789,289552</gml:coordinates>' +\n                    '</gml:Point>' +\n                    '<Distance units=\"m\">1000</Distance>' +\n                '</DWithin>' +\n            '</Filter>';\n\n        var format = new OpenLayers.Format.Filter.v1_0_0();\n        var filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.DWITHIN,\n            property: \"Geometry\",\n            value: new OpenLayers.Geometry.Point(2488789,289552),\n            distance: 1000,\n            distanceUnits: \"m\"\n        });\n        \n        // test writing\n        var node = format.write(filter);\n        t.xml_eq(node, str, \"filter correctly written\");\n        \n        // test reading\n        var doc = (new OpenLayers.Format.XML).read(str);\n        var got = format.read(doc.firstChild);\n        t.eq(got.type, filter.type, \"read correct type\");\n        t.eq(got.property, filter.property, \"read correct property\");\n        t.geom_eq(got.value, filter.value, \"read correct value\");\n        t.eq(got.distance, filter.distance, \"read correct distance\");\n        t.eq(got.distanceUnits, filter.distanceUnits, \"read correct distance units\");\n\n    }\n\n    function test_Intersects(t) {\n        \n        t.plan(4);\n        \n        var str =\n            '<Filter xmlns=\"http://www.opengis.net/ogc\">' +\n                '<Intersects>' +\n                    '<PropertyName>Geometry</PropertyName>' +\n                    '<gml:Box xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"EPSG:4326\">' +\n                        '<gml:coordinates decimal=\".\" cs=\",\" ts=\" \">-180,-90 180,90</gml:coordinates>' +\n                    '</gml:Box>' +\n                '</Intersects>' +\n            '</Filter>';\n\n        var format = new OpenLayers.Format.Filter.v1_0_0();\n        var filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.INTERSECTS,\n            property: \"Geometry\",\n            value: new OpenLayers.Bounds(-180, -90, 180, 90),\n            projection: \"EPSG:4326\"\n        });\n        \n        // test writing\n        var node = format.write(filter);\n        t.xml_eq(node, str, \"filter correctly written\");\n        \n        // test reading\n        var doc = (new OpenLayers.Format.XML).read(str);\n        var got = format.read(doc.firstChild);\n        t.eq(got.type, filter.type, \"read correct type\");\n        t.eq(got.property, filter.property, \"read correct property\");\n        t.eq(got.value.toArray(), filter.value.toArray(), \"read correct value\");\n\n    }\n\n    function test_FilterFunctions(t) {\n        t.plan(2);\n\n        var parser = new OpenLayers.Format.Filter.v1_0_0();\n\n        //test spatial intersects with filter function\n        var filter = new OpenLayers.Filter.Spatial({\n            property: 'the_geom',\n            type: OpenLayers.Filter.Spatial.INTERSECTS,\n            value: new OpenLayers.Filter.Function({\n                name  : 'querySingle',\n                params: ['sf:restricted', 'the_geom', 'cat=3']\n            })\n        });\n\n        var out =\n            '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                '<ogc:Intersects>' +\n                    '<ogc:PropertyName>the_geom</ogc:PropertyName>' +\n                    '<ogc:Function name=\"querySingle\">' +\n                        '<ogc:Literal>sf:restricted</ogc:Literal>' +\n                        '<ogc:Literal>the_geom</ogc:Literal>' +\n                        '<ogc:Literal>cat=3</ogc:Literal>' +\n                    '</ogc:Function>' +\n                '</ogc:Intersects>' +\n            '</ogc:Filter>';\n\n\n        var node = parser.write(filter);\n\n        //test writer\n        t.xml_eq(node, out, \"spatial intersect filter with functions correctly written\");\n\n        //test logical filter with custom function\n        filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.AND,\n            filters: [\n                new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,\n                    property: \"FOO\",\n                    value: new OpenLayers.Filter.Function({\n                        name : 'customFunction',\n                        params : ['param1', 'param2']\n                    })\n                })\n            ]\n        });\n\n        out =\n            '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                '<ogc:And>' +\n                    '<ogc:PropertyIsNotEqualTo>' +\n                        '<ogc:PropertyName>FOO</ogc:PropertyName>' +\n                        '<ogc:Function name=\"customFunction\">' +\n                            '<ogc:Literal>param1</ogc:Literal>' +\n                            '<ogc:Literal>param2</ogc:Literal>' +\n                        '</ogc:Function>' +\n                    '</ogc:PropertyIsNotEqualTo>' +\n                '</ogc:And>' +\n            '</ogc:Filter>';\n\n        node = parser.write(filter);\n\n        //test writer\n        t.xml_eq(node, out, \"comparison filter with filter functions correctly written\");\n\n    }\n\n    function test_NestedFilterFunctions(t) {\n        t.plan(1);\n\n        //test spatial dwithin with nested filter function\n        var filter = new OpenLayers.Filter.Spatial({\n           property: 'the_geom',\n           type: OpenLayers.Filter.Spatial.DWITHIN,\n           value: new OpenLayers.Filter.Function({\n               name : 'collectGeometries',\n               params: [\n                    new OpenLayers.Filter.Function({\n                        name  : 'queryCollection',\n                        params: ['sf:roads', 'the_geom', 'INCLUDE']\n                    })\n               ]\n           }),\n           distanceUnits: \"meters\",\n           distance: 200\n        });\n\n        var out =\n            '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                '<ogc:DWithin>' +\n                    '<ogc:PropertyName>the_geom</ogc:PropertyName>' +\n                    '<ogc:Function name=\"collectGeometries\">' +\n                        '<ogc:Function name=\"queryCollection\">' +\n                            '<ogc:Literal>sf:roads</ogc:Literal>' +\n                            '<ogc:Literal>the_geom</ogc:Literal>' +\n                            '<ogc:Literal>INCLUDE</ogc:Literal>' +\n                        '</ogc:Function>' +\n                    '</ogc:Function>' +\n                    '<ogc:Distance units=\"meters\">200</ogc:Distance>' +\n                '</ogc:DWithin>' +\n            '</ogc:Filter>';\n\n        var parser = new OpenLayers.Format.Filter.v1_0_0();\n        var node = parser.write(filter);\n\n        //test writer\n        t.xml_eq(node, out, \"spatial dwithin filter with nested functions correctly written\");\n    }\n\n\n    </script> \n</head> \n<body>\n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/Filter/v1_1_0.html",
    "content": "<html> \n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    \n    var test_xml =\n        '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n            '<ogc:Or>' +\n                '<ogc:PropertyIsBetween>' +\n                    '<ogc:PropertyName>number</ogc:PropertyName>' +\n                    '<ogc:LowerBoundary>' +\n                        '<ogc:Literal>1064866676</ogc:Literal>' +\n                    '</ogc:LowerBoundary>' +\n                    '<ogc:UpperBoundary>' +\n                        '<ogc:Literal>1065512599</ogc:Literal>' +\n                    '</ogc:UpperBoundary>' +\n                '</ogc:PropertyIsBetween>' +\n                '<ogc:PropertyIsLike wildCard=\"*\" singleChar=\".\" escapeChar=\"!\">' +\n                    '<ogc:PropertyName>cat</ogc:PropertyName>' +\n                    '<ogc:Literal>*dog.food!*good</ogc:Literal>' +\n                '</ogc:PropertyIsLike>' +\n                '<ogc:Not>' +\n                    '<ogc:PropertyIsLessThanOrEqualTo>' +\n                        '<ogc:PropertyName>FOO</ogc:PropertyName>' +\n                        '<ogc:Literal>5000</ogc:Literal>' +\n                    '</ogc:PropertyIsLessThanOrEqualTo>' +\n                '</ogc:Not>' +\n                '<ogc:PropertyIsEqualTo matchCase=\"true\">' +\n                    '<ogc:PropertyName>cat</ogc:PropertyName>' +\n                    '<ogc:Literal>dog</ogc:Literal>' +\n                '</ogc:PropertyIsEqualTo>' +\n                '<ogc:PropertyIsEqualTo matchCase=\"false\">' +\n                    '<ogc:PropertyName>cat</ogc:PropertyName>' +\n                    '<ogc:Literal>dog</ogc:Literal>' +\n                '</ogc:PropertyIsEqualTo>' +\n            '</ogc:Or>' +\n        '</ogc:Filter>';\n\n    function test_read(t) {\n        t.plan(3);\n\n        var parser = new OpenLayers.Format.Filter.v1_1_0();\n        var xml = new OpenLayers.Format.XML();\n        var filter = parser.read(xml.read(test_xml).documentElement);\n\n        t.ok(filter instanceof OpenLayers.Filter.Logical, \"instance of correct class\");\n        t.eq(filter.type, OpenLayers.Filter.Logical.OR, \"correct type\");\n        t.eq(filter.filters.length, 5, \"correct number of child filters\");\n    }\n    \n    function test_write(t) {\n        t.plan(1);\n\n        // read first - testing that write produces the ogc:Filter element above\n        var parser = new OpenLayers.Format.Filter.v1_1_0();\n        var xml = new OpenLayers.Format.XML();\n        var filter = parser.read(xml.read(test_xml).documentElement);\n        \n        var node = parser.write(filter);\n        t.xml_eq(node, test_xml, \"filter correctly written\");\n        \n    }\n    \n    function test_matchCase(t) {\n        var parser = new OpenLayers.Format.Filter.v1_1_0();\n        var xml = new OpenLayers.Format.XML();\n        \n        var cases = [{\n            str:\n                '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                    '<ogc:PropertyIsEqualTo>' +\n                        '<ogc:PropertyName>cat</ogc:PropertyName>' +\n                        '<ogc:Literal>dog</ogc:Literal>' +\n                    '</ogc:PropertyIsEqualTo>' +\n                '</ogc:Filter>',\n            exp: true\n        }, {\n            str:\n                '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                    '<ogc:PropertyIsEqualTo matchCase=\"1\">' +\n                        '<ogc:PropertyName>cat</ogc:PropertyName>' +\n                        '<ogc:Literal>dog</ogc:Literal>' +\n                    '</ogc:PropertyIsEqualTo>' +\n                '</ogc:Filter>',\n            exp: true\n        }, {\n            str:\n                '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                    '<ogc:PropertyIsEqualTo matchCase=\"true\">' +\n                        '<ogc:PropertyName>cat</ogc:PropertyName>' +\n                        '<ogc:Literal>dog</ogc:Literal>' +\n                    '</ogc:PropertyIsEqualTo>' +\n                '</ogc:Filter>',\n            exp: true\n        }, {\n            str:\n                '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                    '<ogc:PropertyIsEqualTo matchCase=\"0\">' +\n                        '<ogc:PropertyName>cat</ogc:PropertyName>' +\n                        '<ogc:Literal>dog</ogc:Literal>' +\n                    '</ogc:PropertyIsEqualTo>' +\n                '</ogc:Filter>',\n            exp: false\n        }, {\n            str:\n                '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                    '<ogc:PropertyIsEqualTo matchCase=\"0\">' +\n                        '<ogc:PropertyName>cat</ogc:PropertyName>' +\n                        '<ogc:Literal>dog</ogc:Literal>' +\n                    '</ogc:PropertyIsEqualTo>' +\n                '</ogc:Filter>',\n            exp: false\n        }, {\n            str:\n                '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                    '<ogc:PropertyIsNotEqualTo matchCase=\"true\">' +\n                        '<ogc:PropertyName>cat</ogc:PropertyName>' +\n                        '<ogc:Literal>dog</ogc:Literal>' +\n                    '</ogc:PropertyIsNotEqualTo>' +\n                '</ogc:Filter>',\n            exp: true\n        }, {\n            str:\n                '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                    '<ogc:PropertyIsNotEqualTo matchCase=\"false\">' +\n                        '<ogc:PropertyName>cat</ogc:PropertyName>' +\n                        '<ogc:Literal>dog</ogc:Literal>' +\n                    '</ogc:PropertyIsNotEqualTo>' +\n                '</ogc:Filter>',\n            exp: false\n        }];\n        \n        t.plan(cases.length);\n        \n        var filter, c;\n        for(var i=0; i<cases.length; ++i) {\n            c = cases[i];\n            filter = parser.read(xml.read(c.str).documentElement);\n            t.eq(filter.matchCase, c.exp, \"case \" + i);\n        }\n        \n    }\n\n    function test_BBOX(t) {\n        t.plan(1);\n        var filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.BBOX,\n            property: \"the_geom\",\n            value: new OpenLayers.Bounds(-180, -90, 180, 90),\n            projection: \"EPSG:4326\"\n        });\n        \n        var out =\n            '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                '<ogc:BBOX>' +\n                    '<ogc:PropertyName>the_geom</ogc:PropertyName>' +\n                    '<gml:Envelope xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"EPSG:4326\">' +\n                        '<gml:lowerCorner>-180 -90</gml:lowerCorner>' +\n                        '<gml:upperCorner>180 90</gml:upperCorner>' +\n                    '</gml:Envelope>' +\n                '</ogc:BBOX>' +\n            '</ogc:Filter>';\n        \n        var parser = new OpenLayers.Format.Filter.v1_1_0();\n        var node = parser.write(filter);\n        \n        t.xml_eq(node, out, \"bbox correctly written\");\n    }\n    \n    function test_BBOX_noGeometryName(t) {\n        t.plan(1);\n        var filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.BBOX,\n            value: new OpenLayers.Bounds(-180, -90, 180, 90),\n            projection: \"EPSG:4326\"\n        });\n        \n        var out =\n            '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                '<ogc:BBOX>' +\n                    '<gml:Envelope xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"EPSG:4326\">' +\n                        '<gml:lowerCorner>-180 -90</gml:lowerCorner>' +\n                        '<gml:upperCorner>180 90</gml:upperCorner>' +\n                    '</gml:Envelope>' +\n                '</ogc:BBOX>' +\n            '</ogc:Filter>';\n        \n        var parser = new OpenLayers.Format.Filter.v1_1_0();\n        var node = parser.write(filter);\n        \n        t.xml_eq(node, out, \"bbox correctly written\");\n    }\n\n\n    function test_Intersects(t) {\n        \n        t.plan(4);\n        \n        var str =\n            '<Filter xmlns=\"http://www.opengis.net/ogc\">' +\n                '<Intersects>' +\n                    '<PropertyName>Geometry</PropertyName>' +\n                    '<gml:Envelope xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"EPSG:4326\">' +\n                        '<gml:lowerCorner>-180 -90</gml:lowerCorner>' +\n                        '<gml:upperCorner>180 90</gml:upperCorner>' +\n                    '</gml:Envelope>' +\n                '</Intersects>' +\n            '</Filter>';\n\n        var format = new OpenLayers.Format.Filter.v1_1_0();\n        var filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.INTERSECTS,\n            property: \"Geometry\",\n            value: new OpenLayers.Bounds(-180, -90, 180, 90),\n            projection: \"EPSG:4326\"\n        });\n        \n        // test writing\n        var node = format.write(filter);\n        t.xml_eq(node, str, \"filter correctly written\");\n        \n        // test reading\n        var doc = (new OpenLayers.Format.XML).read(str);\n        var got = format.read(doc.firstChild);\n        t.eq(got.type, filter.type, \"read correct type\");\n        t.eq(got.property, filter.property, \"read correct property\");\n        t.eq(got.value.toArray(), filter.value.toArray(), \"read correct value\");\n\n    }\n\n    function test_FilterFunctions(t) {\n        t.plan(2);\n\n        var parser = new OpenLayers.Format.Filter.v1_1_0();\n\n        //test spatial intersects with filter function\n        var filter = new OpenLayers.Filter.Spatial({\n            property: 'the_geom',\n            type: OpenLayers.Filter.Spatial.INTERSECTS,\n            value: new OpenLayers.Filter.Function({\n                name  : 'querySingle',\n                params: ['sf:restricted', 'the_geom', 'cat=3']\n            })\n        });\n\n        var out =\n            '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                '<ogc:Intersects>' +\n                    '<ogc:PropertyName>the_geom</ogc:PropertyName>' +\n                    '<ogc:Function name=\"querySingle\">' +\n                        '<ogc:Literal>sf:restricted</ogc:Literal>' +\n                        '<ogc:Literal>the_geom</ogc:Literal>' +\n                        '<ogc:Literal>cat=3</ogc:Literal>' +\n                    '</ogc:Function>' +\n                '</ogc:Intersects>' +\n            '</ogc:Filter>';\n\n\n        var node = parser.write(filter);\n\n        //test writer\n        t.xml_eq(node, out, \"spatial intersect filter with functions correctly written\");\n\n        //test logical filter with custom function\n        filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.AND,\n            filters: [\n                new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,\n                    matchCase: false,\n                    property: \"FOO\",\n                    value: new OpenLayers.Filter.Function({\n                        name : 'customFunction',\n                        params : ['param1', 'param2']\n                    })\n                })\n            ]\n        });\n\n        out =\n            '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                '<ogc:And>' +\n                    '<ogc:PropertyIsNotEqualTo matchCase=\"false\">' +\n                        '<ogc:PropertyName>FOO</ogc:PropertyName>' +\n                        '<ogc:Function name=\"customFunction\">' +\n                            '<ogc:Literal>param1</ogc:Literal>' +\n                            '<ogc:Literal>param2</ogc:Literal>' +\n                        '</ogc:Function>' +\n                    '</ogc:PropertyIsNotEqualTo>' +\n                '</ogc:And>' +\n            '</ogc:Filter>';\n\n        node = parser.write(filter);\n\n        //test writer\n        t.xml_eq(node, out, \"comparison filter with filter functions correctly written\");\n\n    }\n\n    function test_NestedFilterFunctions(t) {\n        t.plan(1);\n\n        //test spatial dwithin with nested filter function\n        var filter = new OpenLayers.Filter.Spatial({\n           property: 'the_geom',\n           type: OpenLayers.Filter.Spatial.DWITHIN,\n           value: new OpenLayers.Filter.Function({\n               name : 'collectGeometries',\n               params: [\n                    new OpenLayers.Filter.Function({\n                        name  : 'queryCollection',\n                        params: ['sf:roads', 'the_geom', 'INCLUDE']\n                    })\n               ]\n           }),\n           distanceUnits: \"meters\",\n           distance: 200\n        });\n\n        var out =\n            '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                '<ogc:DWithin>' +\n                    '<ogc:PropertyName>the_geom</ogc:PropertyName>' +\n                    '<ogc:Function name=\"collectGeometries\">' +\n                        '<ogc:Function name=\"queryCollection\">' +\n                            '<ogc:Literal>sf:roads</ogc:Literal>' +\n                            '<ogc:Literal>the_geom</ogc:Literal>' +\n                            '<ogc:Literal>INCLUDE</ogc:Literal>' +\n                        '</ogc:Function>' +\n                    '</ogc:Function>' +\n                    '<ogc:Distance units=\"meters\">200</ogc:Distance>' +\n                '</ogc:DWithin>' +\n            '</ogc:Filter>';\n\n        var parser = new OpenLayers.Format.Filter.v1_1_0();\n        var node = parser.write(filter);\n\n        //test writer\n        t.xml_eq(node, out, \"spatial dwithin filter with nested functions correctly written\");\n    }\n\n    function test_write_like_matchcase(t) {\n        t.plan(1);\n\n        var filter = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.LIKE,\n            property: \"person\",\n            value: \"*me*\",\n            matchCase: false\n        });\n\n        var format = new OpenLayers.Format.Filter.v1_1_0();\n        \n        var got = format.write(filter);\n        var exp = readXML(\"LikeMatchCase\");\n        t.xml_eq(got, exp, \"wrote matchCase attribute on PropertyIsLike\");\n    }\n\n    function readXML(id) {\n        var xml = document.getElementById(id).firstChild.nodeValue;\n        return new OpenLayers.Format.XML().read(xml).documentElement;\n    }\n\n    function test_SortBy(t) {\n        t.plan(1);\n    \n        var out =\n            '<ogc:SortBy xmlns:ogc=\"http://www.opengis.net/ogc\">'+\n                '<ogc:SortProperty>'+\n                    '<ogc:PropertyName>Title</ogc:PropertyName>'+\n                    '<ogc:SortOrder>ASC</ogc:SortOrder>'+\n                '</ogc:SortProperty>'+\n                '<ogc:SortProperty>'+\n                    '<ogc:PropertyName>Relevance</ogc:PropertyName>'+\n                    '<ogc:SortOrder>DESC</ogc:SortOrder>'+\n                '</ogc:SortProperty>'+\n            '</ogc:SortBy>';\n        \n        var parser = new OpenLayers.Format.Filter.v1_1_0();\n        var node = parser.writers['ogc'].SortBy.call(parser, [{\n            \"property\": 'Title',\n            \"order\": \"ASC\"\n        },{\n            \"property\": 'Relevance',\n            \"order\": \"DESC\"\n        }]);\n        \n        t.xml_eq(node, out, \"Check SortBy\");\n    }\n    </script> \n</head> \n<body>\n<div id=\"LikeMatchCase\"><!--\n<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n    <ogc:PropertyIsLike wildCard=\"*\" singleChar=\".\" escapeChar=\"!\" matchCase=\"false\">\n        <ogc:PropertyName>person</ogc:PropertyName>\n        <ogc:Literal>*me*</ogc:Literal>\n    </ogc:PropertyIsLike>\n</ogc:Filter>\n--></div>\n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/Filter/v2_0_0.html",
    "content": "<html> \n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    \n    var test_xml =\n        '<fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">' +\n            '<fes:Or>' +\n                '<fes:PropertyIsBetween>' +\n                    '<fes:ValueReference>DEPTH</fes:ValueReference>' +\n                    '<fes:LowerBoundary>' +\n                        '<fes:Literal>100</fes:Literal>' +\n                    '</fes:LowerBoundary>' +\n                    '<fes:UpperBoundary>' +\n                        '<fes:Literal>200</fes:Literal>' +\n                    '</fes:UpperBoundary>' +\n                '</fes:PropertyIsBetween>' +\n                '<fes:PropertyIsEqualTo matchCase=\"true\">' +\n                    '<fes:ValueReference>FIELD1</fes:ValueReference>' +\n                    '<fes:Literal>10</fes:Literal>' +\n                '</fes:PropertyIsEqualTo>' +\n            '</fes:Or>' +\n        '</fes:Filter>';\n\n\n    function test_read(t) {\n        t.plan(3);\n\n        var parser = new OpenLayers.Format.Filter.v2_0_0();\n        var xml = new OpenLayers.Format.XML();\n        var filter = parser.read(xml.read(test_xml).documentElement);\n\n        t.ok(filter instanceof OpenLayers.Filter.Logical, \"instance of correct class\");\n        t.eq(filter.type, OpenLayers.Filter.Logical.OR, \"correct type\");\n        t.eq(filter.filters.length, 2, \"correct number of child filters\");\n    }\n    \n    function test_write(t) {\n        t.plan(1);\n\n        // read first - testing that write produces the fes:Filter element above\n        var parser = new OpenLayers.Format.Filter.v2_0_0();\n        var xml = new OpenLayers.Format.XML();\n        var filter = parser.read(xml.read(test_xml).documentElement);\n        \n        var node = parser.write(filter);\n        t.xml_eq(node, test_xml, \"filter correctly written\");\n        \n    }\n    \n    function test_matchCase(t) {\n        var parser = new OpenLayers.Format.Filter.v2_0_0();\n        var xml = new OpenLayers.Format.XML();\n        \n        var cases = [{\n            str:\n                '<fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">' +\n                    '<fes:PropertyIsEqualTo>' +\n                        '<fes:ValueReference>cat</fes:ValueReference>' +\n                        '<fes:Literal>dog</fes:Literal>' +\n                    '</fes:PropertyIsEqualTo>' +\n                '</fes:Filter>',\n            exp: true\n        }, {\n            str:\n                '<fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">' +\n                    '<fes:PropertyIsEqualTo matchCase=\"1\">' +\n                        '<fes:ValueReference>cat</fes:ValueReference>' +\n                        '<fes:Literal>dog</fes:Literal>' +\n                    '</fes:PropertyIsEqualTo>' +\n                '</fes:Filter>',\n            exp: true\n        }, {\n            str:\n                '<fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">' +\n                    '<fes:PropertyIsEqualTo matchCase=\"true\">' +\n                        '<fes:ValueReference>cat</fes:ValueReference>' +\n                        '<fes:Literal>dog</fes:Literal>' +\n                    '</fes:PropertyIsEqualTo>' +\n                '</fes:Filter>',\n            exp: true\n        }, {\n            str:\n                '<fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">' +\n                    '<fes:PropertyIsEqualTo matchCase=\"0\">' +\n                        '<fes:ValueReference>cat</fes:ValueReference>' +\n                        '<fes:Literal>dog</fes:Literal>' +\n                    '</fes:PropertyIsEqualTo>' +\n                '</fes:Filter>',\n            exp: false\n        }, {\n            str:\n                '<fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">' +\n                    '<fes:PropertyIsEqualTo matchCase=\"0\">' +\n                        '<fes:ValueReference>cat</fes:ValueReference>' +\n                        '<fes:Literal>dog</fes:Literal>' +\n                    '</fes:PropertyIsEqualTo>' +\n                '</fes:Filter>',\n            exp: false\n        }, {\n            str:\n                '<fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">' +\n                    '<fes:PropertyIsNotEqualTo matchCase=\"true\">' +\n                        '<fes:ValueReference>cat</fes:ValueReference>' +\n                        '<fes:Literal>dog</fes:Literal>' +\n                    '</fes:PropertyIsNotEqualTo>' +\n                '</fes:Filter>',\n            exp: true\n        }, {\n            str:\n                '<fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">' +\n                    '<fes:PropertyIsNotEqualTo matchCase=\"false\">' +\n                        '<fes:ValueReference>cat</fes:ValueReference>' +\n                        '<fes:Literal>dog</fes:Literal>' +\n                    '</fes:PropertyIsNotEqualTo>' +\n                '</fes:Filter>',\n            exp: false\n        }];\n        \n        t.plan(cases.length);\n        \n        var filter, c;\n        for(var i=0; i<cases.length; ++i) {\n            c = cases[i];\n            filter = parser.read(xml.read(c.str).documentElement);\n            t.eq(filter.matchCase, c.exp, \"case \" + i);\n        }\n        \n    }\n\n    function test_BBOX(t) {\n        t.plan(1);\n        var filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.BBOX,\n            property: \"the_geom\",\n            value: new OpenLayers.Bounds(-180, -90, 180, 90),\n            projection: \"EPSG:4326\"\n        });\n        \n        var out =\n            '<fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">' +\n                '<fes:BBOX>' +\n                    '<fes:ValueReference>the_geom</fes:ValueReference>' +\n                    '<gml:Envelope xmlns:gml=\"http://www.opengis.net/gml/3.2\" srsName=\"EPSG:4326\">' +\n                        '<gml:lowerCorner>-180 -90</gml:lowerCorner>' +\n                        '<gml:upperCorner>180 90</gml:upperCorner>' +\n                    '</gml:Envelope>' +\n                '</fes:BBOX>' +\n            '</fes:Filter>';\n        \n        var parser = new OpenLayers.Format.Filter.v2_0_0();\n        var node = parser.write(filter);\n        \n        t.xml_eq(node, out, \"bbox correctly written\");\n    }\n    \n    function test_BBOX_noGeometryName(t) {\n        t.plan(1);\n        var filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.BBOX,\n            value: new OpenLayers.Bounds(-180, -90, 180, 90),\n            projection: \"EPSG:4326\"\n        });\n        \n        var out =\n            '<fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">' +\n                '<fes:BBOX>' +\n                    '<gml:Envelope xmlns:gml=\"http://www.opengis.net/gml/3.2\" srsName=\"EPSG:4326\">' +\n                        '<gml:lowerCorner>-180 -90</gml:lowerCorner>' +\n                        '<gml:upperCorner>180 90</gml:upperCorner>' +\n                    '</gml:Envelope>' +\n                '</fes:BBOX>' +\n            '</fes:Filter>';\n        \n        var parser = new OpenLayers.Format.Filter.v2_0_0();\n        var node = parser.write(filter);\n        \n        t.xml_eq(node, out, \"bbox correctly written\");\n    }\n\n\n    function test_Intersects(t) {\n        \n        t.plan(4);\n        \n        var str =\n            '<Filter xmlns=\"http://www.opengis.net/fes/2.0\">' +\n                '<Intersects>' +\n                    '<ValueReference>Geometry</ValueReference>' +\n                    '<gml:Envelope xmlns:gml=\"http://www.opengis.net/gml/3.2\" srsName=\"EPSG:4326\">' +\n                        '<gml:lowerCorner>-180 -90</gml:lowerCorner>' +\n                        '<gml:upperCorner>180 90</gml:upperCorner>' +\n                    '</gml:Envelope>' +\n                '</Intersects>' +\n            '</Filter>';\n\n        var format = new OpenLayers.Format.Filter.v2_0_0();\n        var filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.INTERSECTS,\n            property: \"Geometry\",\n            value: new OpenLayers.Bounds(-180, -90, 180, 90),\n            projection: \"EPSG:4326\"\n        });\n        \n        // test writing\n        var node = format.write(filter);\n        t.xml_eq(node, str, \"filter correctly written\");\n        \n        // test reading\n        var doc = (new OpenLayers.Format.XML).read(str);\n        var got = format.read(doc.firstChild);\n        t.eq(got.type, filter.type, \"read correct type\");\n        t.eq(got.property, filter.property, \"read correct property\");\n        t.eq(got.value.toArray(), filter.value.toArray(), \"read correct value\");\n\n    }\n\n    function test_FilterFunctions(t) {\n        t.plan(2);\n\n        var parser = new OpenLayers.Format.Filter.v2_0_0();\n\n        //test spatial intersects with filter function\n        var filter = new OpenLayers.Filter.Spatial({\n            property: 'the_geom',\n            type: OpenLayers.Filter.Spatial.INTERSECTS,\n            value: new OpenLayers.Filter.Function({\n                name  : 'querySingle',\n                params: ['sf:restricted', 'the_geom', 'cat=3']\n            })\n        });\n\n        var out =\n            '<fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">' +\n                '<fes:Intersects>' +\n                    '<fes:ValueReference>the_geom</fes:ValueReference>' +\n                    '<fes:Function name=\"querySingle\">' +\n                        '<fes:Literal>sf:restricted</fes:Literal>' +\n                        '<fes:Literal>the_geom</fes:Literal>' +\n                        '<fes:Literal>cat=3</fes:Literal>' +\n                    '</fes:Function>' +\n                '</fes:Intersects>' +\n            '</fes:Filter>';\n\n\n        var node = parser.write(filter);\n\n        //test writer\n        t.xml_eq(node, out, \"spatial intersect filter with functions correctly written\");\n\n        //test logical filter with custom function\n        filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.AND,\n            filters: [\n                new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,\n                    matchCase: false,\n                    property: \"FOO\",\n                    value: new OpenLayers.Filter.Function({\n                        name : 'customFunction',\n                        params : ['param1', 'param2']\n                    })\n                })\n            ]\n        });\n\n        out =\n            '<fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">' +\n                '<fes:And>' +\n                    '<fes:PropertyIsNotEqualTo matchCase=\"false\">' +\n                        '<fes:ValueReference>FOO</fes:ValueReference>' +\n                        '<fes:Function name=\"customFunction\">' +\n                            '<fes:Literal>param1</fes:Literal>' +\n                            '<fes:Literal>param2</fes:Literal>' +\n                        '</fes:Function>' +\n                    '</fes:PropertyIsNotEqualTo>' +\n                '</fes:And>' +\n            '</fes:Filter>';\n\n        node = parser.write(filter);\n\n        //test writer\n        t.xml_eq(node, out, \"comparison filter with filter functions correctly written\");\n\n    }\n\n    function test_NestedFilterFunctions(t) {\n        t.plan(1);\n\n        //test spatial dwithin with nested filter function\n        var filter = new OpenLayers.Filter.Spatial({\n           property: 'the_geom',\n           type: OpenLayers.Filter.Spatial.DWITHIN,\n           value: new OpenLayers.Filter.Function({\n               name : 'collectGeometries',\n               params: [\n                    new OpenLayers.Filter.Function({\n                        name  : 'queryCollection',\n                        params: ['sf:roads', 'the_geom', 'INCLUDE']\n                    })\n               ]\n           }),\n           distanceUnits: \"meters\",\n           distance: 200\n        });\n\n        var out =\n            '<fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">' +\n                '<fes:DWithin>' +\n                    '<fes:ValueReference>the_geom</fes:ValueReference>' +\n                    '<fes:Function name=\"collectGeometries\">' +\n                        '<fes:Function name=\"queryCollection\">' +\n                            '<fes:Literal>sf:roads</fes:Literal>' +\n                            '<fes:Literal>the_geom</fes:Literal>' +\n                            '<fes:Literal>INCLUDE</fes:Literal>' +\n                        '</fes:Function>' +\n                    '</fes:Function>' +\n                    '<fes:Distance units=\"meters\">200</fes:Distance>' +\n                '</fes:DWithin>' +\n            '</fes:Filter>';\n\n        var parser = new OpenLayers.Format.Filter.v2_0_0();\n        var node = parser.write(filter);\n\n        //test writer\n        t.xml_eq(node, out, \"spatial dwithin filter with nested functions correctly written\");\n    }\n\n    function test_write_like_matchcase(t) {\n        t.plan(1);\n\n        var filter = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.LIKE,\n            property: \"person\",\n            value: \"*me*\",\n            matchCase: false\n        });\n\n        var format = new OpenLayers.Format.Filter.v2_0_0();\n        \n        var got = format.write(filter);\n        var exp = readXML(\"LikeMatchCase\");\n        t.xml_eq(got, exp, \"wrote matchCase attribute on PropertyIsLike\");\n    }\n\n    function readXML(id) {\n        var xml = document.getElementById(id).firstChild.nodeValue;\n        return new OpenLayers.Format.XML().read(xml).documentElement;\n    }\n\n    function test_SortBy(t) {\n        t.plan(1);\n    \n        var out =\n            '<fes:SortBy xmlns:fes=\"http://www.opengis.net/fes/2.0\">'+\n                '<fes:SortProperty>'+\n                    '<fes:ValueReference>Title</fes:ValueReference>'+\n                    '<fes:SortOrder>ASC</fes:SortOrder>'+\n                '</fes:SortProperty>'+\n                '<fes:SortProperty>'+\n                    '<fes:ValueReference>Relevance</fes:ValueReference>'+\n                    '<fes:SortOrder>DESC</fes:SortOrder>'+\n                '</fes:SortProperty>'+\n            '</fes:SortBy>';\n        \n        var parser = new OpenLayers.Format.Filter.v2_0_0();\n        var node = parser.writers['fes'].SortBy.call(parser, [{\n            \"property\": 'Title',\n            \"order\": \"ASC\"\n        },{\n            \"property\": 'Relevance',\n            \"order\": \"DESC\"\n        }]);\n        \n        t.xml_eq(node, out, \"Check SortBy\");\n    }\n    </script> \n</head> \n<body>\n<div id=\"LikeMatchCase\"><!--\n<fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">\n    <fes:PropertyIsLike wildCard=\"*\" singleChar=\".\" escapeChar=\"!\" matchCase=\"false\">\n        <fes:ValueReference>person</fes:ValueReference>\n        <fes:Literal>*me*</fes:Literal>\n    </fes:PropertyIsLike>\n</fes:Filter>\n--></div>\n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/Filter.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_initialize(t) { \n        t.plan(3); \n         \n        var options = {'foo': 'bar'}; \n        var format = new OpenLayers.Format.Filter(options); \n        t.ok(format instanceof OpenLayers.Format.Filter, \n             \"new OpenLayers.Format.Filter returns object\" ); \n        t.eq(format.foo, \"bar\", \"constructor sets options correctly\"); \n        t.eq(typeof format.read, \"function\", \"format has a read function\"); \n    }\n\n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/GML/cases.js",
    "content": "var xml = new OpenLayers.Format.XML(); \nfunction readXML(file) {\n    return xml.read(document.getElementById(file).firstChild.nodeValue);\n}\n\nvar cases = {\n\n    \"v2/point-coord.xml\": new OpenLayers.Geometry.Point(1, 2),\n\n    \"v2/point-coordinates.xml\": new OpenLayers.Geometry.Point(1, 2),\n\n    \"v2/linestring-coord.xml\": new OpenLayers.Geometry.LineString([\n        new OpenLayers.Geometry.Point(1, 2),\n        new OpenLayers.Geometry.Point(3, 4)\n    ]),\n    \n    \"v2/linestring-coordinates.xml\": new OpenLayers.Geometry.LineString([\n        new OpenLayers.Geometry.Point(1, 2),\n        new OpenLayers.Geometry.Point(3, 4)\n    ]),\n    \n    \"v2/linearring-coord.xml\": new OpenLayers.Geometry.LinearRing([\n        new OpenLayers.Geometry.Point(1, 2),\n        new OpenLayers.Geometry.Point(3, 4),\n        new OpenLayers.Geometry.Point(5, 6),\n        new OpenLayers.Geometry.Point(1, 2)\n    ]),\n    \n    \"v2/linearring-coordinates.xml\": new OpenLayers.Geometry.LinearRing([\n        new OpenLayers.Geometry.Point(1, 2),\n        new OpenLayers.Geometry.Point(3, 4),\n        new OpenLayers.Geometry.Point(5, 6),\n        new OpenLayers.Geometry.Point(1, 2)\n    ]),\n    \n    \"v2/polygon-coord.xml\": new OpenLayers.Geometry.Polygon([\n        new OpenLayers.Geometry.LinearRing([\n            new OpenLayers.Geometry.Point(1, 2),\n            new OpenLayers.Geometry.Point(3, 4),\n            new OpenLayers.Geometry.Point(5, 6),\n            new OpenLayers.Geometry.Point(1, 2)\n        ]),\n        new OpenLayers.Geometry.LinearRing([\n            new OpenLayers.Geometry.Point(2, 3),\n            new OpenLayers.Geometry.Point(4, 5),\n            new OpenLayers.Geometry.Point(6, 7),\n            new OpenLayers.Geometry.Point(2, 3)\n        ]),\n        new OpenLayers.Geometry.LinearRing([\n            new OpenLayers.Geometry.Point(3, 4),\n            new OpenLayers.Geometry.Point(5, 6),\n            new OpenLayers.Geometry.Point(7, 8),\n            new OpenLayers.Geometry.Point(3, 4)\n        ])\n    ]),\n    \n    \"v2/polygon-coordinates.xml\": new OpenLayers.Geometry.Polygon([\n        new OpenLayers.Geometry.LinearRing([\n            new OpenLayers.Geometry.Point(1, 2),\n            new OpenLayers.Geometry.Point(3, 4),\n            new OpenLayers.Geometry.Point(5, 6),\n            new OpenLayers.Geometry.Point(1, 2)\n        ]),\n        new OpenLayers.Geometry.LinearRing([\n            new OpenLayers.Geometry.Point(2, 3),\n            new OpenLayers.Geometry.Point(4, 5),\n            new OpenLayers.Geometry.Point(6, 7),\n            new OpenLayers.Geometry.Point(2, 3)\n        ]),\n        new OpenLayers.Geometry.LinearRing([\n            new OpenLayers.Geometry.Point(3, 4),\n            new OpenLayers.Geometry.Point(5, 6),\n            new OpenLayers.Geometry.Point(7, 8),\n            new OpenLayers.Geometry.Point(3, 4)\n        ])\n    ]),\n    \n    \"v2/multipoint-coord.xml\": new OpenLayers.Geometry.MultiPoint([\n        new OpenLayers.Geometry.Point(1, 2),\n        new OpenLayers.Geometry.Point(2, 3),\n        new OpenLayers.Geometry.Point(3, 4)\n    ]),\n    \n    \"v2/multipoint-coordinates.xml\": new OpenLayers.Geometry.MultiPoint([\n        new OpenLayers.Geometry.Point(1, 2),\n        new OpenLayers.Geometry.Point(2, 3),\n        new OpenLayers.Geometry.Point(3, 4)\n    ]),\n    \n    \"v2/multilinestring-coord.xml\": new OpenLayers.Geometry.MultiLineString([\n        new OpenLayers.Geometry.LineString([\n            new OpenLayers.Geometry.Point(1, 2),\n            new OpenLayers.Geometry.Point(2, 3)\n        ]),\n        new OpenLayers.Geometry.LineString([\n            new OpenLayers.Geometry.Point(3, 4),\n            new OpenLayers.Geometry.Point(4, 5)\n        ])\n    ]),\n    \n    \"v2/multilinestring-coordinates.xml\": new OpenLayers.Geometry.MultiLineString([\n        new OpenLayers.Geometry.LineString([\n            new OpenLayers.Geometry.Point(1, 2),\n            new OpenLayers.Geometry.Point(2, 3)\n        ]),\n        new OpenLayers.Geometry.LineString([\n            new OpenLayers.Geometry.Point(3, 4),\n            new OpenLayers.Geometry.Point(4, 5)\n        ])\n    ]),\n    \n    \"v2/multipolygon-coord.xml\": new OpenLayers.Geometry.MultiPolygon([\n        new OpenLayers.Geometry.Polygon([\n            new OpenLayers.Geometry.LinearRing([\n                new OpenLayers.Geometry.Point(1, 2),\n                new OpenLayers.Geometry.Point(3, 4),\n                new OpenLayers.Geometry.Point(5, 6),\n                new OpenLayers.Geometry.Point(1, 2)\n            ]),\n            new OpenLayers.Geometry.LinearRing([\n                new OpenLayers.Geometry.Point(2, 3),\n                new OpenLayers.Geometry.Point(4, 5),\n                new OpenLayers.Geometry.Point(6, 7),\n                new OpenLayers.Geometry.Point(2, 3)\n            ]),\n            new OpenLayers.Geometry.LinearRing([\n                new OpenLayers.Geometry.Point(3, 4),\n                new OpenLayers.Geometry.Point(5, 6),\n                new OpenLayers.Geometry.Point(7, 8),\n                new OpenLayers.Geometry.Point(3, 4)\n            ])\n        ]),\n        new OpenLayers.Geometry.Polygon([\n            new OpenLayers.Geometry.LinearRing([\n                new OpenLayers.Geometry.Point(1, 2),\n                new OpenLayers.Geometry.Point(3, 4),\n                new OpenLayers.Geometry.Point(5, 6),\n                new OpenLayers.Geometry.Point(1, 2)\n            ])\n        ])\n    ]),\n    \n    \"v2/multipolygon-coordinates.xml\": new OpenLayers.Geometry.MultiPolygon([\n        new OpenLayers.Geometry.Polygon([\n            new OpenLayers.Geometry.LinearRing([\n                new OpenLayers.Geometry.Point(1, 2),\n                new OpenLayers.Geometry.Point(3, 4),\n                new OpenLayers.Geometry.Point(5, 6),\n                new OpenLayers.Geometry.Point(1, 2)\n            ]),\n            new OpenLayers.Geometry.LinearRing([\n                new OpenLayers.Geometry.Point(2, 3),\n                new OpenLayers.Geometry.Point(4, 5),\n                new OpenLayers.Geometry.Point(6, 7),\n                new OpenLayers.Geometry.Point(2, 3)\n            ]),\n            new OpenLayers.Geometry.LinearRing([\n                new OpenLayers.Geometry.Point(3, 4),\n                new OpenLayers.Geometry.Point(5, 6),\n                new OpenLayers.Geometry.Point(7, 8),\n                new OpenLayers.Geometry.Point(3, 4)\n            ])\n        ]),\n        new OpenLayers.Geometry.Polygon([\n            new OpenLayers.Geometry.LinearRing([\n                new OpenLayers.Geometry.Point(1, 2),\n                new OpenLayers.Geometry.Point(3, 4),\n                new OpenLayers.Geometry.Point(5, 6),\n                new OpenLayers.Geometry.Point(1, 2)\n            ])\n        ])\n    ]),\n    \n    \"v2/geometrycollection-coordinates.xml\": new OpenLayers.Geometry.Collection([\n        new OpenLayers.Geometry.Point(1, 2),\n        new OpenLayers.Geometry.LineString([\n            new OpenLayers.Geometry.Point(1, 2),\n            new OpenLayers.Geometry.Point(3, 4)\n        ]),\n        new OpenLayers.Geometry.Polygon([\n            new OpenLayers.Geometry.LinearRing([\n                new OpenLayers.Geometry.Point(1, 2),\n                new OpenLayers.Geometry.Point(3, 4),\n                new OpenLayers.Geometry.Point(5, 6),\n                new OpenLayers.Geometry.Point(1, 2)\n            ]),\n            new OpenLayers.Geometry.LinearRing([\n                new OpenLayers.Geometry.Point(2, 3),\n                new OpenLayers.Geometry.Point(4, 5),\n                new OpenLayers.Geometry.Point(6, 7),\n                new OpenLayers.Geometry.Point(2, 3)\n            ]),\n            new OpenLayers.Geometry.LinearRing([\n                new OpenLayers.Geometry.Point(3, 4),\n                new OpenLayers.Geometry.Point(5, 6),\n                new OpenLayers.Geometry.Point(7, 8),\n                new OpenLayers.Geometry.Point(3, 4)\n            ])\n        ])\n    ]),\n    \n    \"v2/box-coord.xml\": new OpenLayers.Bounds(1, 2, 3, 4),\n    \n    \"v2/box-coordinates.xml\": new OpenLayers.Bounds(1, 2, 3, 4),\n    \n    \"v3/linestring3d.xml\": new OpenLayers.Geometry.LineString([\n        new OpenLayers.Geometry.Point(1, 2, 3),\n        new OpenLayers.Geometry.Point(4, 5, 6)\n    ])\n    \n};\nOpenLayers.Util.extend(cases, {\n    \"v3/point.xml\": cases[\"v2/point-coordinates.xml\"],\n    \"v3/linestring.xml\": cases[\"v2/linestring-coordinates.xml\"],\n    \"v3/curve.xml\": cases[\"v2/linestring-coordinates.xml\"],\n    \"v3/polygon.xml\": cases[\"v2/polygon-coordinates.xml\"],\n    \"v3/surface.xml\": cases[\"v2/polygon-coordinates.xml\"],\n    \"v3/multipoint-singular.xml\": cases[\"v2/multipoint-coordinates.xml\"],\n    \"v3/multipoint-plural.xml\": cases[\"v2/multipoint-coordinates.xml\"],\n    \"v3/multilinestring-singular.xml\": cases[\"v2/multilinestring-coordinates.xml\"],\n    \"v3/multilinestring-plural.xml\": cases[\"v2/multilinestring-coordinates.xml\"],\n    \"v3/multicurve-singular.xml\": cases[\"v2/multilinestring-coordinates.xml\"],\n    \"v3/multicurve-curve.xml\": cases[\"v2/multilinestring-coordinates.xml\"],\n    \"v3/multipolygon-singular.xml\": cases[\"v2/multipolygon-coordinates.xml\"],\n    \"v3/multipolygon-plural.xml\": cases[\"v2/multipolygon-coordinates.xml\"],\n    \"v3/multisurface-singular.xml\": cases[\"v2/multipolygon-coordinates.xml\"],\n    \"v3/multisurface-plural.xml\": cases[\"v2/multipolygon-coordinates.xml\"],\n    \"v3/multisurface-surface.xml\": cases[\"v2/multipolygon-coordinates.xml\"],\n    \"v3/envelope.xml\": cases[\"v2/box-coordinates.xml\"]\n});"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/GML/v2.html",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<html xmlns=\"http://www.w3.org/1999/xhtml\"> \n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script src=\"cases.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_readNode_geometry(t) {\n        var files = [\n            \"v2/point-coord.xml\", \"v2/point-coordinates.xml\",\n            \"v2/linestring-coord.xml\", \"v2/linestring-coordinates.xml\",\n            \"v2/polygon-coord.xml\", \"v2/polygon-coordinates.xml\",\n            \"v2/multipoint-coord.xml\", \"v2/multipoint-coordinates.xml\",\n            \"v2/multilinestring-coord.xml\", \"v2/multilinestring-coordinates.xml\",\n            \"v2/multipolygon-coord.xml\", \"v2/multipolygon-coordinates.xml\",\n            \"v2/geometrycollection-coordinates.xml\"\n        ];\n\n        var len = files.length;\n        t.plan(len);\n\n        var format = new OpenLayers.Format.GML.v2({\n            featureType: \"feature\",\n            featureNS: \"http://example.com/feature\"\n        });\n        var file, doc, expect, out;\n        for(var i=0; i<len; ++i) {\n            file = files[i];\n            expect = cases[file];\n            if(expect) {\n                doc = readXML(file);\n                if(doc && doc.documentElement) {\n                    out = format.readNode(doc.documentElement);\n                    if(out.components && out.components.length == 1) {\n                        t.geom_eq(out.components[0], expect, \"[\" + file + \"] geometry read\");\n                    } else {\n                        t.fail(\"[\" + file + \"] gml parsing\");\n                    }\n                } else {\n                    t.fail(\"[\" + file + \"] xml parsing\");\n                }\n            } else {\n                t.fail(\"[\" + file + \"] case not found\");\n            }\n        }\n        \n    }\n    \n    function test_readNode_bounds(t) {\n        var files = [\"v2/box-coord.xml\", \"v2/box-coordinates.xml\"];\n\n        var len = files.length;\n        t.plan(len);\n        \n        var file, doc, expect, got;\n        var format = new OpenLayers.Format.GML.v2({\n            featureType: \"feature\",\n            featureNS: \"http://example.com/feature\"\n        });\n        for(var i=0; i<len; ++i) {\n            file = files[i];\n            expect = cases[file];\n            if(expect) {\n                doc = readXML(file);\n                if(doc && doc.documentElement) {\n                    out = format.readNode(doc.documentElement);\n                    if(out.components && out.components.length == 1) {\n                        got = out.components[0];\n                        if(got instanceof OpenLayers.Bounds) {\n                            t.ok(out.components[0].equals(expect), \"[\" + file + \"] bounds read\")\n                        } else {\n                            t.fail(\"[\" + file + \"] expected a bounds, got \" + got);\n                        }\n                    } else {\n                        t.fail(\"[\" + file + \"] gml parsing\");\n                    }\n                } else {\n                    t.fail(\"[\" + file + \"] xml parsing\");\n                }\n            } else {\n                t.fail(\"[\" + file + \"] case not found\");\n            }\n        }\n        \n    }\n    \n    function test_writeNode_geometry(t) {\n        // we only care to write the 'coordinates' variant of GML 2\n        var files = [\n            \"v2/point-coordinates.xml\",\n            \"v2/linestring-coordinates.xml\",\n            \"v2/polygon-coordinates.xml\",\n            \"v2/multipoint-coordinates.xml\",\n            \"v2/multilinestring-coordinates.xml\",\n            \"v2/multipolygon-coordinates.xml\",\n            \"v2/geometrycollection-coordinates.xml\"\n        ];\n\n        var len = files.length;\n        t.plan(len);\n\n        var format = new OpenLayers.Format.GML.v2({\n            featureType: \"feature\",\n            featureNS: \"http://example.com/feature\",\n            srsName: \"foo\" // GML geometry collections require srsName, we only write if provided\n        });\n        var file, geom, doc, node;\n        for(var i=0; i<len; ++i) {\n            file = files[i];\n            geom = cases[file];\n            if(geom) {\n                doc = readXML(file);\n                if(doc && doc.documentElement) {\n                    node = format.writeNode(\"feature:_geometry\", geom);\n                    t.xml_eq(node.firstChild, doc.documentElement, \"[\" + file + \"] geometry written\");\n                } else {\n                    t.fail(\"[\" + file + \"] xml parsing\");\n                }\n            } else {\n                t.fail(\"[\" + file + \"] case not found\");\n            }\n        }\n    }\n\n    function test_writeNode_bounds(t) {\n        // we only care to write the 'coordinates' variant of GML 2\n        var files = [\n            \"v2/box-coordinates.xml\"\n        ];\n\n        var len = files.length;\n        t.plan(len);\n\n        var format = new OpenLayers.Format.GML.v2({\n            featureType: \"feature\",\n            featureNS: \"http://example.com/feature\",\n            srsName: \"foo\" // GML box does not require srsName, we only write if provided\n        });\n        var file, bounds, doc, node;\n        for(var i=0; i<len; ++i) {\n            file = files[i];\n            bounds = cases[file];\n            if(bounds) {\n                doc = readXML(file);\n                if(doc && doc.documentElement) {\n                    node = format.writeNode(\"gml:Box\", bounds);\n                    t.xml_eq(node, doc.documentElement, \"[\" + file + \"] bounds written\");\n                } else {\n                    t.fail(\"[\" + file + \"] xml parsing\");\n                }\n            } else {\n                t.fail(\"[\" + file + \"] case not found\");\n            }\n        }\n    }\n    \n    function test_read(t) {\n        t.plan(8);\n        var doc = readXML(\"v2/topp-states.xml\");\n        var format = new OpenLayers.Format.GML.v2({\n            featureType: \"states\",\n            featureNS: \"http://www.openplans.org/topp\",\n            geometryName: \"the_geom\"\n        });\n        var features = format.read(doc.documentElement);\n        \n        t.eq(features.length, 3, \"read 3 features\");\n        var feature = features[0];\n        t.eq(feature.fid, \"states.1\", \"read fid\");\n        t.eq(feature.geometry.CLASS_NAME, \"OpenLayers.Geometry.MultiPolygon\",\n             \"read multipolygon geometry\");\n        var attributes = feature.attributes;\n        t.eq(attributes[\"STATE_NAME\"], \"Illinois\", \"read STATE_NAME\");\n        t.eq(attributes[\"STATE_FIPS\"], \"17\", \"read STATE_FIPS\");\n        t.eq(attributes[\"SUB_REGION\"], \"E N Cen\", \"read SUB_REGION\");\n        t.eq(attributes[\"STATE_ABBR\"], \"IL\", \"read STATE_ABBR\");\n        t.eq(attributes[\"LAND_KM\"], \"143986.61\", \"read LAND_KM\");\n    }\n\n    function test_read_autoconfig(t) {\n        t.plan(5);\n        var doc = readXML(\"v2/topp-states.xml\");\n        var format = new OpenLayers.Format.GML.v2();\n        var features = format.read(doc.documentElement);\n        \n        t.eq(features.length, 3, \"read 3 features\");\n        var feature = features[0];\n        t.eq(feature.fid, \"states.1\", \"read fid\");\n        t.eq(feature.geometry.CLASS_NAME, \"OpenLayers.Geometry.MultiPolygon\",\n             \"read multipolygon geometry\");\n        t.eq(format.featureType, \"states\", \"featureType correctly auto-configured\");\n        t.eq(format.featureNS, \"http://www.openplans.org/topp\", \"featureNS correctly auto-configured\");\n    }\n    \n    function test_boundedBy(t) {\n        t.plan(5);\n        \n        var doc = readXML(\"v2/boundedBy.xml\");\n        var format = new OpenLayers.Format.GML.v2({\n            featureType: \"states\",\n            featureNS: \"http://www.openplans.org/topp\",\n            geometryName: \"the_geom\",\n            xy: false\n        });\n        var features = format.read(doc.documentElement);\n        var bounds = features[0].bounds;\n\n        t.ok(bounds instanceof OpenLayers.Bounds, \"feature given a bounds\");\n        t.eq(bounds.left.toFixed(2), \"-91.52\", \"bounds left correct\");\n        t.eq(bounds.bottom.toFixed(2), \"36.99\", \"bounds bottom correct\");\n        t.eq(bounds.right.toFixed(2), \"-87.51\", \"bounds right correct\");\n        t.eq(bounds.top.toFixed(2), \"42.51\", \"bounds top correct\");\n    }\n    \n    function test_write(t) {\n        t.plan(1);\n        var doc = readXML(\"v2/topp-states.xml\");\n        var format = new OpenLayers.Format.GML.v2({\n            featureType: \"states\",\n            featureNS: \"http://www.openplans.org/topp\",\n            geometryName: \"the_geom\",\n            schemaLocation: \"http://www.openplans.org/topp http://sigma.openplans.org:80/geoserver/wfs?service=WFS&version=1.0.0&request=DescribeFeatureType&typeName=topp:states http://www.opengis.net/wfs http://sigma.openplans.org:80/geoserver/schemas/wfs/1.0.0/WFS-basic.xsd\",\n            srsName: \"http://www.opengis.net/gml/srs/epsg.xml#4326\"\n        });\n        var features = format.read(doc.documentElement);\n        \n        var got = format.write(features);\n        t.xml_eq(got, doc.documentElement, \"wfs:FeatureCollection round trip\");\n        \n    }\n\n    function test_multipleTypenames(t) {\n        t.plan(5);\n        var doc = readXML(\"v2/multipletypenames.xml\");\n        var format = new OpenLayers.Format.GML.v2({\n            featureType: [\"LKUNSTWERK\", \"PKUNSTWERK\", \"VKUNSTWERK\"],\n            featureNS: \"http://mapserver.gis.umn.edu/mapserver\",\n            geometry_name: \"geometry\"\n        });\n        var features = format.read(doc.documentElement);\n        t.eq(features.length, 3, \"Expected 3 features from GML containing multiple typenames\");\n        t.eq(features[0].type, \"VKUNSTWERK\", \"First feature type is from the VKUNSTWERK typename\");\n        t.eq(features[1].type, \"LKUNSTWERK\", \"Second feature type is from the LKUNSTWERK typename\");\n        t.eq(features[2].type, \"PKUNSTWERK\", \"Third feature type is from the PKUNSTWERK typename\");\n        t.eq(features[0].namespace, \"http://mapserver.gis.umn.edu/mapserver\", \"Namespace is set correctly on feature\");\n    }\n\n    function test_noGeom(t) {\n        t.plan(7);\n        var doc = readXML(\"v2/nogeom.xml\");\n        var format = new OpenLayers.Format.GML.v2({\n            featureType: \"DEPARTEMENT\",\n            featureNS: \"http://server.fr/geoserver/loc\"\n        });\n        var features = format.read(doc.documentElement);\n        t.eq(features.length, 2, \"Expected 2 features from GML with no geom\");\n        var feature = features[0];\n        t.ok(feature.geometry == null, \"feature 0 has no geometry\");\n        var bounds = feature.bounds;\n        t.ok(bounds && (bounds instanceof OpenLayers.Bounds), \"feature 0 has been assigned bounds\");\n        t.eq(bounds.left, 209565, \"bounds left correct\");\n        t.eq(bounds.bottom, 6785323, \"bounds bottom correct\");\n        t.eq(bounds.right, 337568, \"bounds right correct\");\n        t.eq(bounds.top, 6885985, \"bounds top correct\");\n    }\n\n   </script>\n</head>\n<body>\n<div id=\"v2/point-coord.xml\"><!--\n<gml:Point xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n  <gml:coord>\n    <gml:X>1</gml:X>\n    <gml:Y>2</gml:Y>\n  </gml:coord>\n</gml:Point>\n--></div>\n<div id=\"v2/point-coordinates.xml\"><!--\n<gml:Point xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n  <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2</gml:coordinates>\n</gml:Point>\n--></div>\n<div id=\"v2/linestring-coord.xml\"><!--\n<gml:LineString xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n  <gml:coord>\n    <gml:X>1</gml:X>\n    <gml:Y>2</gml:Y>\n  </gml:coord>\n  <gml:coord>\n    <gml:X>3</gml:X>\n    <gml:Y>4</gml:Y>\n  </gml:coord>\n</gml:LineString>\n--></div>\n<div id=\"v2/linestring-coordinates.xml\"><!--\n<gml:LineString xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n  <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2 3,4</gml:coordinates>\n</gml:LineString>\n--></div>\n<div id=\"v2/polygon-coord.xml\"><!--\n<gml:Polygon xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:outerBoundaryIs>\n        <gml:LinearRing>\n            <gml:coord>\n                <gml:X>1</gml:X>\n                <gml:Y>2</gml:Y>\n            </gml:coord>\n            <gml:coord>\n                <gml:X>3</gml:X>\n                <gml:Y>4</gml:Y>\n            </gml:coord>\n            <gml:coord>\n                <gml:X>5</gml:X>\n                <gml:Y>6</gml:Y>\n            </gml:coord>\n            <gml:coord>\n                <gml:X>1</gml:X>\n                <gml:Y>2</gml:Y>\n            </gml:coord>\n        </gml:LinearRing>\n    </gml:outerBoundaryIs>\n    <gml:innerBoundaryIs>\n        <gml:LinearRing>\n            <gml:coord>\n                <gml:X>2</gml:X>\n                <gml:Y>3</gml:Y>\n            </gml:coord>\n            <gml:coord>\n                <gml:X>4</gml:X>\n                <gml:Y>5</gml:Y>\n            </gml:coord>\n            <gml:coord>\n                <gml:X>6</gml:X>\n                <gml:Y>7</gml:Y>\n            </gml:coord>\n            <gml:coord>\n                <gml:X>2</gml:X>\n                <gml:Y>3</gml:Y>\n            </gml:coord>\n        </gml:LinearRing>\n    </gml:innerBoundaryIs>    \n    <gml:innerBoundaryIs>\n        <gml:LinearRing>\n            <gml:coord>\n                <gml:X>3</gml:X>\n                <gml:Y>4</gml:Y>\n            </gml:coord>\n            <gml:coord>\n                <gml:X>5</gml:X>\n                <gml:Y>6</gml:Y>\n            </gml:coord>\n            <gml:coord>\n                <gml:X>7</gml:X>\n                <gml:Y>8</gml:Y>\n            </gml:coord>\n            <gml:coord>\n                <gml:X>3</gml:X>\n                <gml:Y>4</gml:Y>\n            </gml:coord>\n        </gml:LinearRing>\n    </gml:innerBoundaryIs>    \n</gml:Polygon>\n--></div>\n<div id=\"v2/polygon-coordinates.xml\"><!--\n<gml:Polygon xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:outerBoundaryIs>\n        <gml:LinearRing>\n            <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2 3,4 5,6 1,2</gml:coordinates>\n        </gml:LinearRing>\n    </gml:outerBoundaryIs>\n    <gml:innerBoundaryIs>\n        <gml:LinearRing>\n            <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">2,3 4,5 6,7 2,3</gml:coordinates>\n        </gml:LinearRing>\n    </gml:innerBoundaryIs>    \n    <gml:innerBoundaryIs>\n        <gml:LinearRing>\n            <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">3,4 5,6 7,8 3,4</gml:coordinates>\n        </gml:LinearRing>\n    </gml:innerBoundaryIs>    \n</gml:Polygon>\n--></div>\n<div id=\"v2/multipoint-coord.xml\"><!--\n<gml:MultiPoint xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:pointMember>\n        <gml:Point>\n            <gml:coord>\n                <gml:X>1</gml:X>\n                <gml:Y>2</gml:Y>\n            </gml:coord>\n        </gml:Point>\n    </gml:pointMember>\n    <gml:pointMember>\n        <gml:Point>\n            <gml:coord>\n                <gml:X>2</gml:X>\n                <gml:Y>3</gml:Y>\n            </gml:coord>\n        </gml:Point>\n    </gml:pointMember>\n    <gml:pointMember>\n        <gml:Point>\n            <gml:coord>\n                <gml:X>3</gml:X>\n                <gml:Y>4</gml:Y>\n            </gml:coord>\n        </gml:Point>\n    </gml:pointMember>\n</gml:MultiPoint>\n--></div>\n<div id=\"v2/multipoint-coordinates.xml\"><!--\n<gml:MultiPoint xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:pointMember>\n        <gml:Point>\n            <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2</gml:coordinates>\n        </gml:Point>\n    </gml:pointMember>\n    <gml:pointMember>\n        <gml:Point>\n            <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">2,3</gml:coordinates>\n        </gml:Point>\n    </gml:pointMember>\n    <gml:pointMember>\n        <gml:Point>\n            <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">3,4</gml:coordinates>\n        </gml:Point>\n    </gml:pointMember>\n</gml:MultiPoint>\n--></div>\n<div id=\"v2/multilinestring-coord.xml\"><!--\n<gml:MultiLineString xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:lineStringMember>\n        <gml:LineString>\n            <gml:coord>\n                <gml:X>1</gml:X>\n                <gml:Y>2</gml:Y>\n            </gml:coord>\n            <gml:coord>\n                <gml:X>2</gml:X>\n                <gml:Y>3</gml:Y>\n            </gml:coord>\n        </gml:LineString>\n    </gml:lineStringMember>\n    <gml:lineStringMember>\n        <gml:LineString>\n            <gml:coord>\n                <gml:X>3</gml:X>\n                <gml:Y>4</gml:Y>\n            </gml:coord>\n            <gml:coord>\n                <gml:X>4</gml:X>\n                <gml:Y>5</gml:Y>\n            </gml:coord>\n        </gml:LineString>\n    </gml:lineStringMember>\n</gml:MultiLineString>\n--></div>\n<div id=\"v2/multilinestring-coordinates.xml\"><!--\n<gml:MultiLineString xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:lineStringMember>\n        <gml:LineString>\n            <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2 2,3</gml:coordinates>\n        </gml:LineString>\n    </gml:lineStringMember>\n    <gml:lineStringMember>\n        <gml:LineString>\n            <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">3,4 4,5</gml:coordinates>\n        </gml:LineString>\n    </gml:lineStringMember>\n</gml:MultiLineString>\n--></div>\n<div id=\"v2/multipolygon-coord.xml\"><!--\n<gml:MultiPolygon xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:polygonMember>\n        <gml:Polygon>\n            <gml:outerBoundaryIs>\n                <gml:LinearRing>\n                    <gml:coord>\n                        <gml:X>1</gml:X>\n                        <gml:Y>2</gml:Y>\n                    </gml:coord>\n                    <gml:coord>\n                        <gml:X>3</gml:X>\n                        <gml:Y>4</gml:Y>\n                    </gml:coord>\n                    <gml:coord>\n                        <gml:X>5</gml:X>\n                        <gml:Y>6</gml:Y>\n                    </gml:coord>\n                    <gml:coord>\n                        <gml:X>1</gml:X>\n                        <gml:Y>2</gml:Y>\n                    </gml:coord>\n                </gml:LinearRing>\n            </gml:outerBoundaryIs>\n            <gml:innerBoundaryIs>\n                <gml:LinearRing>\n                    <gml:coord>\n                        <gml:X>2</gml:X>\n                        <gml:Y>3</gml:Y>\n                    </gml:coord>\n                    <gml:coord>\n                        <gml:X>4</gml:X>\n                        <gml:Y>5</gml:Y>\n                    </gml:coord>\n                    <gml:coord>\n                        <gml:X>6</gml:X>\n                        <gml:Y>7</gml:Y>\n                    </gml:coord>\n                    <gml:coord>\n                        <gml:X>2</gml:X>\n                        <gml:Y>3</gml:Y>\n                    </gml:coord>\n                </gml:LinearRing>\n            </gml:innerBoundaryIs>    \n            <gml:innerBoundaryIs>\n                <gml:LinearRing>\n                    <gml:coord>\n                        <gml:X>3</gml:X>\n                        <gml:Y>4</gml:Y>\n                    </gml:coord>\n                    <gml:coord>\n                        <gml:X>5</gml:X>\n                        <gml:Y>6</gml:Y>\n                    </gml:coord>\n                    <gml:coord>\n                        <gml:X>7</gml:X>\n                        <gml:Y>8</gml:Y>\n                    </gml:coord>\n                    <gml:coord>\n                        <gml:X>3</gml:X>\n                        <gml:Y>4</gml:Y>\n                    </gml:coord>\n                </gml:LinearRing>\n            </gml:innerBoundaryIs>    \n        </gml:Polygon>\n    </gml:polygonMember>\n    <gml:polygonMember>\n        <gml:Polygon>\n            <gml:outerBoundaryIs>\n                <gml:LinearRing>\n                    <gml:coord>\n                        <gml:X>1</gml:X>\n                        <gml:Y>2</gml:Y>\n                    </gml:coord>\n                    <gml:coord>\n                        <gml:X>3</gml:X>\n                        <gml:Y>4</gml:Y>\n                    </gml:coord>\n                    <gml:coord>\n                        <gml:X>5</gml:X>\n                        <gml:Y>6</gml:Y>\n                    </gml:coord>\n                    <gml:coord>\n                        <gml:X>1</gml:X>\n                        <gml:Y>2</gml:Y>\n                    </gml:coord>\n                </gml:LinearRing>\n            </gml:outerBoundaryIs>\n        </gml:Polygon>\n    </gml:polygonMember>\n</gml:MultiPolygon>\n--></div>\n<div id=\"v2/multipolygon-coordinates.xml\"><!--\n<gml:MultiPolygon xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:polygonMember>\n        <gml:Polygon>\n            <gml:outerBoundaryIs>\n                <gml:LinearRing>\n                    <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2 3,4 5,6 1,2</gml:coordinates>\n                </gml:LinearRing>\n            </gml:outerBoundaryIs>\n            <gml:innerBoundaryIs>\n                <gml:LinearRing>\n                    <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">2,3 4,5 6,7 2,3</gml:coordinates>\n                </gml:LinearRing>\n            </gml:innerBoundaryIs>    \n            <gml:innerBoundaryIs>\n                <gml:LinearRing>\n                    <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">3,4 5,6 7,8 3,4</gml:coordinates>\n                </gml:LinearRing>\n            </gml:innerBoundaryIs>    \n        </gml:Polygon>\n    </gml:polygonMember>\n    <gml:polygonMember>\n        <gml:Polygon>\n            <gml:outerBoundaryIs>\n                <gml:LinearRing>\n                    <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2 3,4 5,6 1,2</gml:coordinates>\n                </gml:LinearRing>\n            </gml:outerBoundaryIs>\n        </gml:Polygon>\n    </gml:polygonMember>\n</gml:MultiPolygon>\n--></div>\n<div id=\"v2/geometrycollection-coordinates.xml\"><!--\n<gml:GeometryCollection xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:geometryMember>\n        <gml:Point srsName=\"foo\">\n          <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2</gml:coordinates>\n        </gml:Point>\n    </gml:geometryMember>\n    <gml:geometryMember>\n        <gml:LineString srsName=\"foo\">\n          <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2 3,4</gml:coordinates>\n        </gml:LineString>\n    </gml:geometryMember>\n    <gml:geometryMember>\n        <gml:Polygon srsName=\"foo\">\n            <gml:outerBoundaryIs>\n                <gml:LinearRing>\n                    <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2 3,4 5,6 1,2</gml:coordinates>\n                </gml:LinearRing>\n            </gml:outerBoundaryIs>\n            <gml:innerBoundaryIs>\n                <gml:LinearRing>\n                    <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">2,3 4,5 6,7 2,3</gml:coordinates>\n                </gml:LinearRing>\n            </gml:innerBoundaryIs>    \n            <gml:innerBoundaryIs>\n                <gml:LinearRing>\n                    <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">3,4 5,6 7,8 3,4</gml:coordinates>\n                </gml:LinearRing>\n            </gml:innerBoundaryIs>    \n        </gml:Polygon>\n    </gml:geometryMember>\n</gml:GeometryCollection>\n--></div>\n<div id=\"v2/box-coord.xml\"><!--\n<gml:Box xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n  <gml:coord>\n    <gml:X>1</gml:X>\n    <gml:Y>2</gml:Y>\n  </gml:coord>\n  <gml:coord>\n    <gml:X>3</gml:X>\n    <gml:Y>4</gml:Y>\n  </gml:coord>\n</gml:Box>\n--></div>\n<div id=\"v2/box-coordinates.xml\"><!--\n<gml:Box xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n  <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2 3,4</gml:coordinates>\n</gml:Box>\n--></div>\n<div id=\"v2/linearring-coord.xml\"><!--\n<gml:LinearRing xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:coord>\n        <gml:X>1</gml:X>\n        <gml:Y>2</gml:Y>\n    </gml:coord>\n    <gml:coord>\n        <gml:X>3</gml:X>\n        <gml:Y>4</gml:Y>\n    </gml:coord>\n    <gml:coord>\n        <gml:X>5</gml:X>\n        <gml:Y>6</gml:Y>\n    </gml:coord>\n    <gml:coord>\n        <gml:X>1</gml:X>\n        <gml:Y>2</gml:Y>\n    </gml:coord>\n</gml:LinearRing>\n--></div>\n<div id=\"v2/linearring-coordinates.xml\"><!--\n<gml:LinearRing xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n  <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2 3,4 5,6 1,2</gml:coordinates>\n</gml:LinearRing>\n--></div>\n<div id=\"v2/topp-states.xml\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\"?><wfs:FeatureCollection xmlns=\"http://www.opengis.net/wfs\" xmlns:wfs=\"http://www.opengis.net/wfs\" xmlns:topp=\"http://www.openplans.org/topp\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.openplans.org/topp http://sigma.openplans.org:80/geoserver/wfs?service=WFS&amp;version=1.0.0&amp;request=DescribeFeatureType&amp;typeName=topp:states http://www.opengis.net/wfs http://sigma.openplans.org:80/geoserver/schemas/wfs/1.0.0/WFS-basic.xsd\"><gml:featureMember><topp:states fid=\"states.1\"><topp:the_geom><gml:MultiPolygon srsName=\"http://www.opengis.net/gml/srs/epsg.xml#4326\"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates xmlns:gml=\"http://www.opengis.net/gml\" decimal=\".\" cs=\",\" ts=\" \">37.5101,-88.0711 37.4761,-88.0871 37.4421,-88.3111 37.4091,-88.3591 37.4201,-88.4191 37.4001,-88.4671 37.2961,-88.5111 37.2571,-88.5011 37.2051,-88.4501 37.1561,-88.4221 37.0981,-88.4501 37.0721,-88.4761 37.0681,-88.4901 37.0641,-88.5171 37.0721,-88.5591 37.1091,-88.6141 37.1351,-88.6881 37.1411,-88.7391 37.1521,-88.7461 37.2021,-88.8631 37.2181,-88.9321 37.2201,-88.9931 37.1851,-89.0651 37.1121,-89.1161 37.0931,-89.1461 37.0641,-89.1691 37.0251,-89.1741 36.9981,-89.1501 36.9881,-89.1291 36.9861,-89.1931 37.0281,-89.2101 37.0411,-89.2371 37.0871,-89.2641 37.0911,-89.2841 37.0851,-89.3031 37.0601,-89.3091 37.0271,-89.2641 37.0081,-89.2621 36.9991,-89.2821 37.0091,-89.3101 37.0491,-89.3821 37.0991,-89.3791 37.1371,-89.4231 37.1651,-89.4401 37.2241,-89.4681 37.2531,-89.4651 37.2561,-89.4891 37.2761,-89.5131 37.3041,-89.5131 37.3291,-89.5001 37.3391,-89.4681 37.3551,-89.4351 37.4111,-89.4271 37.4531,-89.4531 37.4911,-89.4941 37.5711,-89.5241 37.6151,-89.5131 37.6501,-89.5191 37.6791,-89.5131 37.6941,-89.5211 37.7061,-89.5811 37.7451,-89.6661 37.7831,-89.6751 37.8041,-89.6911 37.8401,-89.7281 37.9051,-89.8511 37.9051,-89.8611 37.8911,-89.8661 37.8751,-89.9001 37.8781,-89.9371 37.9111,-89.9781 37.9631,-89.9581 37.9691,-90.0101 37.9931,-90.0411 38.0321,-90.1191 38.0531,-90.1341 38.0881,-90.2071 38.1221,-90.2541 38.1661,-90.2891 38.1881,-90.3361 38.2341,-90.3641 38.3231,-90.3691 38.3651,-90.3581 38.3901,-90.3391 38.4271,-90.3011 38.5181,-90.2651 38.5321,-90.2611 38.5621,-90.2401 38.6101,-90.1831 38.6581,-90.1831 38.7001,-90.2021 38.7231,-90.1961 38.7731,-90.1631 38.7851,-90.1351 38.8001,-90.1211 38.8301,-90.1131 38.8531,-90.1321 38.9141,-90.2431 38.9241,-90.2781 38.9241,-90.3191 38.9621,-90.4131 38.9591,-90.4691 38.8911,-90.5301 38.8711,-90.5701 38.8801,-90.6271 38.9351,-90.6681 39.0371,-90.7061 39.0581,-90.7071 39.0931,-90.6901 39.1441,-90.7161 39.1951,-90.7181 39.2241,-90.7321 39.2471,-90.7381 39.2961,-90.7791 39.3501,-90.8501 39.4001,-90.9471 39.4441,-91.0361 39.4731,-91.0641 39.5281,-91.0931 39.5521,-91.1561 39.6001,-91.2031 39.6851,-91.3171 39.7241,-91.3671 39.7611,-91.3731 39.8031,-91.3811 39.8631,-91.4491 39.8851,-91.4501 39.9011,-91.4341 39.9211,-91.4301 39.9461,-91.4471 40.0051,-91.4871 40.0661,-91.5041 40.1341,-91.5161 40.2001,-91.5061 40.2511,-91.4981 40.3091,-91.4861 40.3711,-91.4481 40.3861,-91.4181 40.3921,-91.3851 40.4021,-91.3721 40.4471,-91.3851 40.5031,-91.3741 40.5281,-91.3821 40.5471,-91.4121 40.5721,-91.4111 40.6031,-91.3751 40.6391,-91.2621 40.6431,-91.2141 40.6561,-91.1621 40.6821,-91.1291 40.7051,-91.1191 40.7611,-91.0921 40.8331,-91.0881 40.8791,-91.0491 40.9231,-90.9831 40.9501,-90.9601 41.0701,-90.9541 41.1041,-90.9571 41.1441,-90.9901 41.1651,-91.0181 41.1761,-91.0561 41.2311,-91.1011 41.2671,-91.1021 41.3341,-91.0731 41.4011,-91.0551 41.4231,-91.0271 41.4311,-91.0001 41.4211,-90.9491 41.4441,-90.8441 41.4491,-90.7791 41.4501,-90.7081 41.4621,-90.6581 41.5091,-90.6001 41.5251,-90.5401 41.5271,-90.4541 41.5431,-90.4341 41.5671,-90.4231 41.5861,-90.3481 41.6021,-90.3391 41.6491,-90.3411 41.7221,-90.3261 41.7561,-90.3041 41.7811,-90.2551 41.8061,-90.1951 41.9301,-90.1541 41.9831,-90.1421 42.0331,-90.1501 42.0611,-90.1681 42.1031,-90.1661 42.1201,-90.1761 42.1221,-90.1911 42.1591,-90.2301 42.1971,-90.3231 42.2101,-90.3671 42.2421,-90.4071 42.2631,-90.4171 42.3401,-90.4271 42.3601,-90.4411 42.3881,-90.4911 42.4211,-90.5631 42.4601,-90.6051 42.4751,-90.6481 42.4941,-90.6511 42.5091,-90.6381 42.5081,-90.4191 42.5041,-89.9231 42.5031,-89.8341 42.4971,-89.4001 42.4971,-89.3591 42.4901,-88.9391 42.4901,-88.7641 42.4891,-88.7061 42.4911,-88.2971 42.4891,-88.1941 42.4891,-87.7971 42.3141,-87.8361 42.1561,-87.7601 42.0591,-87.6701 41.8471,-87.6121 41.7231,-87.5291 41.4691,-87.5321 41.3011,-87.5321 41.1731,-87.5311 41.0091,-87.5321 40.7451,-87.5321 40.4941,-87.5371 40.4831,-87.5351 40.1661,-87.5351 39.8871,-87.5351 39.6091,-87.5351 39.4771,-87.5381 39.3501,-87.5401 39.3381,-87.5971 39.3071,-87.6251 39.2971,-87.6101 39.2811,-87.6151 39.2581,-87.6061 39.2481,-87.5841 39.2081,-87.5881 39.1981,-87.5941 39.1961,-87.6071 39.1681,-87.6441 39.1461,-87.6701 39.1301,-87.6591 39.1131,-87.6621 39.1031,-87.6311 39.0881,-87.6301 39.0841,-87.6121 39.0621,-87.5851 38.9951,-87.5811 38.9941,-87.5911 38.9771,-87.5471 38.9631,-87.5331 38.9311,-87.5301 38.9041,-87.5391 38.8691,-87.5591 38.8571,-87.5501 38.7951,-87.5071 38.7761,-87.5191 38.7691,-87.5081 38.7361,-87.5081 38.6851,-87.5431 38.6721,-87.5881 38.6421,-87.6251 38.6221,-87.6281 38.5991,-87.6191 38.5931,-87.6401 38.5731,-87.6521 38.5471,-87.6721 38.5151,-87.6511 38.5001,-87.6531 38.5041,-87.6791 38.4811,-87.6921 38.4661,-87.7561 38.4571,-87.7581 38.4451,-87.7381 38.4171,-87.7481 38.3781,-87.7841 38.3521,-87.8341 38.2861,-87.8501 38.2851,-87.8631 38.3161,-87.8741 38.3151,-87.8831 38.3001,-87.8881 38.2811,-87.9141 38.3021,-87.9131 38.3041,-87.9251 38.2411,-87.9801 38.2341,-87.9861 38.2001,-87.9771 38.1711,-87.9321 38.1571,-87.9311 38.1361,-87.9501 38.1311,-87.9731 38.1031,-88.0181 38.0921,-88.0121 38.0961,-87.9641 38.0731,-87.9751 38.0541,-88.0341 38.0451,-88.0431 38.0381,-88.0411 38.0331,-88.0211 38.0081,-88.0291 37.9751,-88.0211 37.9561,-88.0421 37.9341,-88.0411 37.9291,-88.0641 37.944,-88.0781 37.9231,-88.084 37.9171,-88.0301 37.9051,-88.0261 37.8961,-88.0441 37.9061,-88.1001 37.8951,-88.1011 37.8671,-88.0751 37.8431,-88.0341 37.8271,-88.0421 37.8311,-88.0891 37.8171,-88.0861 37.8051,-88.0351 37.7351,-88.0721 37.7001,-88.1331 37.6601,-88.1591 37.6281,-88.1571 37.5831,-88.1341 37.5101,-88.0711</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></topp:the_geom><topp:STATE_NAME>Illinois</topp:STATE_NAME><topp:STATE_FIPS>17</topp:STATE_FIPS><topp:SUB_REGION>E N Cen</topp:SUB_REGION><topp:STATE_ABBR>IL</topp:STATE_ABBR><topp:LAND_KM>143986.61</topp:LAND_KM><topp:WATER_KM>1993.335</topp:WATER_KM><topp:PERSONS>1.1431E7</topp:PERSONS><topp:FAMILIES>2924880.0</topp:FAMILIES><topp:HOUSHOLD>4202240.0</topp:HOUSHOLD><topp:MALE>5552233.0</topp:MALE><topp:FEMALE>5878369.0</topp:FEMALE><topp:WORKERS>4199206.0</topp:WORKERS><topp:DRVALONE>3741715.0</topp:DRVALONE><topp:CARPOOL>652603.0</topp:CARPOOL><topp:PUBTRANS>538071.0</topp:PUBTRANS><topp:EMPLOYED>5417967.0</topp:EMPLOYED><topp:UNEMPLOY>385040.0</topp:UNEMPLOY><topp:SERVICE>1360159.0</topp:SERVICE><topp:MANUAL>828906.0</topp:MANUAL><topp:P_MALE>0.486</topp:P_MALE><topp:P_FEMALE>0.514</topp:P_FEMALE><topp:SAMP_POP>1747776.0</topp:SAMP_POP></topp:states></gml:featureMember><gml:featureMember><topp:states fid=\"states.2\"><topp:the_geom><gml:MultiPolygon srsName=\"http://www.opengis.net/gml/srs/epsg.xml#4326\"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates xmlns:gml=\"http://www.opengis.net/gml\" decimal=\".\" cs=\",\" ts=\" \">38.9661,-77.0081 38.8891,-76.9111 38.7881,-77.0451 38.8131,-77.0351 38.8291,-77.0451 38.8381,-77.0401 38.8621,-77.0391 38.8861,-77.0671 38.9151,-77.0781 38.9321,-77.1221 38.9931,-77.0421 38.9661,-77.0081</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></topp:the_geom><topp:STATE_NAME>District of Columbia</topp:STATE_NAME><topp:STATE_FIPS>11</topp:STATE_FIPS><topp:SUB_REGION>S Atl</topp:SUB_REGION><topp:STATE_ABBR>DC</topp:STATE_ABBR><topp:LAND_KM>159.055</topp:LAND_KM><topp:WATER_KM>17.991</topp:WATER_KM><topp:PERSONS>606900.0</topp:PERSONS><topp:FAMILIES>122087.0</topp:FAMILIES><topp:HOUSHOLD>249634.0</topp:HOUSHOLD><topp:MALE>282970.0</topp:MALE><topp:FEMALE>323930.0</topp:FEMALE><topp:WORKERS>229975.0</topp:WORKERS><topp:DRVALONE>106694.0</topp:DRVALONE><topp:CARPOOL>36621.0</topp:CARPOOL><topp:PUBTRANS>111422.0</topp:PUBTRANS><topp:EMPLOYED>303994.0</topp:EMPLOYED><topp:UNEMPLOY>23442.0</topp:UNEMPLOY><topp:SERVICE>65498.0</topp:SERVICE><topp:MANUAL>22407.0</topp:MANUAL><topp:P_MALE>0.466</topp:P_MALE><topp:P_FEMALE>0.534</topp:P_FEMALE><topp:SAMP_POP>72696.0</topp:SAMP_POP></topp:states></gml:featureMember><gml:featureMember><topp:states fid=\"states.3\"><topp:the_geom><gml:MultiPolygon srsName=\"http://www.opengis.net/gml/srs/epsg.xml#4326\"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates xmlns:gml=\"http://www.opengis.net/gml\" decimal=\".\" cs=\",\" ts=\" \">38.5571,-75.7071 38.6491,-75.7111 38.8301,-75.7241 39.1411,-75.7521 39.2471,-75.7611 39.2951,-75.7641 39.3831,-75.7721 39.7231,-75.7911 39.7241,-75.7751 39.7741,-75.7451 39.8201,-75.6951 39.8381,-75.6441 39.8401,-75.5831 39.8261,-75.4701 39.7981,-75.4201 39.7891,-75.4121 39.7781,-75.4281 39.7631,-75.4601 39.7411,-75.4751 39.7191,-75.4761 39.7141,-75.4891 39.6121,-75.6101 39.5661,-75.5621 39.4631,-75.5901 39.3661,-75.5151 39.2571,-75.4021 39.0731,-75.3971 39.0121,-75.3241 38.9451,-75.3071 38.8081,-75.1901 38.7991,-75.0831 38.4491,-75.0451 38.4491,-75.0681 38.4501,-75.0931 38.4551,-75.3501 38.4631,-75.6991 38.5571,-75.7071</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></topp:the_geom><topp:STATE_NAME>Delaware</topp:STATE_NAME><topp:STATE_FIPS>10</topp:STATE_FIPS><topp:SUB_REGION>S Atl</topp:SUB_REGION><topp:STATE_ABBR>DE</topp:STATE_ABBR><topp:LAND_KM>5062.456</topp:LAND_KM><topp:WATER_KM>1385.022</topp:WATER_KM><topp:PERSONS>666168.0</topp:PERSONS><topp:FAMILIES>175867.0</topp:FAMILIES><topp:HOUSHOLD>247497.0</topp:HOUSHOLD><topp:MALE>322968.0</topp:MALE><topp:FEMALE>343200.0</topp:FEMALE><topp:WORKERS>247566.0</topp:WORKERS><topp:DRVALONE>258087.0</topp:DRVALONE><topp:CARPOOL>42968.0</topp:CARPOOL><topp:PUBTRANS>8069.0</topp:PUBTRANS><topp:EMPLOYED>335147.0</topp:EMPLOYED><topp:UNEMPLOY>13945.0</topp:UNEMPLOY><topp:SERVICE>87973.0</topp:SERVICE><topp:MANUAL>44140.0</topp:MANUAL><topp:P_MALE>0.485</topp:P_MALE><topp:P_FEMALE>0.515</topp:P_FEMALE><topp:SAMP_POP>102776.0</topp:SAMP_POP></topp:states></gml:featureMember></wfs:FeatureCollection>\n--></div>\n<div id=\"v2/boundedBy.xml\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\"?><wfs:FeatureCollection xmlns=\"http://www.opengis.net/wfs\" xmlns:wfs=\"http://www.opengis.net/wfs\" xmlns:topp=\"http://www.openplans.org/topp\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.openplans.org/topp http://publicus.opengeo.org:80/geoserver/wfs?service=WFS&amp;version=1.0.0&amp;request=DescribeFeatureType&amp;typeName=topp:states http://www.opengis.net/wfs http://publicus.opengeo.org:80/geoserver/schemas/wfs/1.0.0/WFS-basic.xsd\"><gml:featureMember><topp:states fid=\"states.1\"><gml:boundedBy><gml:Box srsName=\"http://www.opengis.net/gml/srs/epsg.xml#4326\"><gml:coordinates xmlns:gml=\"http://www.opengis.net/gml\" decimal=\".\" cs=\",\" ts=\" \">36.9861,-91.5161 42.5091,-87.5071</gml:coordinates></gml:Box></gml:boundedBy><topp:the_geom><gml:MultiPolygon srsName=\"http://www.opengis.net/gml/srs/epsg.xml#4326\"><gml:polygonMember><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates xmlns:gml=\"http://www.opengis.net/gml\" decimal=\".\" cs=\",\" ts=\" \">37.5101,-88.0711 37.4761,-88.0871 37.4421,-88.3111 37.4091,-88.3591 37.4201,-88.4191 37.4001,-88.4671 37.2961,-88.5111 37.2571,-88.5011 37.2051,-88.4501 37.1561,-88.4221 37.0981,-88.4501 37.0721,-88.4761 37.0681,-88.4901 37.0641,-88.5171 37.0721,-88.5591 37.1091,-88.6141 37.1351,-88.6881 37.1411,-88.7391 37.1521,-88.7461 37.2021,-88.8631 37.2181,-88.9321 37.2201,-88.9931 37.1851,-89.0651 37.1121,-89.1161 37.0931,-89.1461 37.0641,-89.1691 37.0251,-89.1741 36.9981,-89.1501 36.9881,-89.1291 36.9861,-89.1931 37.0281,-89.2101 37.0411,-89.2371 37.0871,-89.2641 37.0911,-89.2841 37.0851,-89.3031 37.0601,-89.3091 37.0271,-89.2641 37.0081,-89.2621 36.9991,-89.2821 37.0091,-89.3101 37.0491,-89.3821 37.0991,-89.3791 37.1371,-89.4231 37.1651,-89.4401 37.2241,-89.4681 37.2531,-89.4651 37.2561,-89.4891 37.2761,-89.5131 37.3041,-89.5131 37.3291,-89.5001 37.3391,-89.4681 37.3551,-89.4351 37.4111,-89.4271 37.4531,-89.4531 37.4911,-89.4941 37.5711,-89.5241 37.6151,-89.5131 37.6501,-89.5191 37.6791,-89.5131 37.6941,-89.5211 37.7061,-89.5811 37.7451,-89.6661 37.7831,-89.6751 37.8041,-89.6911 37.8401,-89.7281 37.9051,-89.8511 37.9051,-89.8611 37.8911,-89.8661 37.8751,-89.9001 37.8781,-89.9371 37.9111,-89.9781 37.9631,-89.9581 37.9691,-90.0101 37.9931,-90.0411 38.0321,-90.1191 38.0531,-90.1341 38.0881,-90.2071 38.1221,-90.2541 38.1661,-90.2891 38.1881,-90.3361 38.2341,-90.3641 38.3231,-90.3691 38.3651,-90.3581 38.3901,-90.3391 38.4271,-90.3011 38.5181,-90.2651 38.5321,-90.2611 38.5621,-90.2401 38.6101,-90.1831 38.6581,-90.1831 38.7001,-90.2021 38.7231,-90.1961 38.7731,-90.1631 38.7851,-90.1351 38.8001,-90.1211 38.8301,-90.1131 38.8531,-90.1321 38.9141,-90.2431 38.9241,-90.2781 38.9241,-90.3191 38.9621,-90.4131 38.9591,-90.4691 38.8911,-90.5301 38.8711,-90.5701 38.8801,-90.6271 38.9351,-90.6681 39.0371,-90.7061 39.0581,-90.7071 39.0931,-90.6901 39.1441,-90.7161 39.1951,-90.7181 39.2241,-90.7321 39.2471,-90.7381 39.2961,-90.7791 39.3501,-90.8501 39.4001,-90.9471 39.4441,-91.0361 39.4731,-91.0641 39.5281,-91.0931 39.5521,-91.1561 39.6001,-91.2031 39.6851,-91.3171 39.7241,-91.3671 39.7611,-91.3731 39.8031,-91.3811 39.8631,-91.4491 39.8851,-91.4501 39.9011,-91.4341 39.9211,-91.4301 39.9461,-91.4471 40.0051,-91.4871 40.0661,-91.5041 40.1341,-91.5161 40.2001,-91.5061 40.2511,-91.4981 40.3091,-91.4861 40.3711,-91.4481 40.3861,-91.4181 40.3921,-91.3851 40.4021,-91.3721 40.4471,-91.3851 40.5031,-91.3741 40.5281,-91.3821 40.5471,-91.4121 40.5721,-91.4111 40.6031,-91.3751 40.6391,-91.2621 40.6431,-91.2141 40.6561,-91.1621 40.6821,-91.1291 40.7051,-91.1191 40.7611,-91.0921 40.8331,-91.0881 40.8791,-91.0491 40.9231,-90.9831 40.9501,-90.9601 41.0701,-90.9541 41.1041,-90.9571 41.1441,-90.9901 41.1651,-91.0181 41.1761,-91.0561 41.2311,-91.1011 41.2671,-91.1021 41.3341,-91.0731 41.4011,-91.0551 41.4231,-91.0271 41.4311,-91.0001 41.4211,-90.9491 41.4441,-90.8441 41.4491,-90.7791 41.4501,-90.7081 41.4621,-90.6581 41.5091,-90.6001 41.5251,-90.5401 41.5271,-90.4541 41.5431,-90.4341 41.5671,-90.4231 41.5861,-90.3481 41.6021,-90.3391 41.6491,-90.3411 41.7221,-90.3261 41.7561,-90.3041 41.7811,-90.2551 41.8061,-90.1951 41.9301,-90.1541 41.9831,-90.1421 42.0331,-90.1501 42.0611,-90.1681 42.1031,-90.1661 42.1201,-90.1761 42.1221,-90.1911 42.1591,-90.2301 42.1971,-90.3231 42.2101,-90.3671 42.2421,-90.4071 42.2631,-90.4171 42.3401,-90.4271 42.3601,-90.4411 42.3881,-90.4911 42.4211,-90.5631 42.4601,-90.6051 42.4751,-90.6481 42.4941,-90.6511 42.5091,-90.6381 42.5081,-90.4191 42.5041,-89.9231 42.5031,-89.8341 42.4971,-89.4001 42.4971,-89.3591 42.4901,-88.9391 42.4901,-88.7641 42.4891,-88.7061 42.4911,-88.2971 42.4891,-88.1941 42.4891,-87.7971 42.3141,-87.8361 42.1561,-87.7601 42.0591,-87.6701 41.8471,-87.6121 41.7231,-87.5291 41.4691,-87.5321 41.3011,-87.5321 41.1731,-87.5311 41.0091,-87.5321 40.7451,-87.5321 40.4941,-87.5371 40.4831,-87.5351 40.1661,-87.5351 39.8871,-87.5351 39.6091,-87.5351 39.4771,-87.5381 39.3501,-87.5401 39.3381,-87.5971 39.3071,-87.6251 39.2971,-87.6101 39.2811,-87.6151 39.2581,-87.6061 39.2481,-87.5841 39.2081,-87.5881 39.1981,-87.5941 39.1961,-87.6071 39.1681,-87.6441 39.1461,-87.6701 39.1301,-87.6591 39.1131,-87.6621 39.1031,-87.6311 39.0881,-87.6301 39.0841,-87.6121 39.0621,-87.5851 38.9951,-87.5811 38.9941,-87.5911 38.9771,-87.5471 38.9631,-87.5331 38.9311,-87.5301 38.9041,-87.5391 38.8691,-87.5591 38.8571,-87.5501 38.7951,-87.5071 38.7761,-87.5191 38.7691,-87.5081 38.7361,-87.5081 38.6851,-87.5431 38.6721,-87.5881 38.6421,-87.6251 38.6221,-87.6281 38.5991,-87.6191 38.5931,-87.6401 38.5731,-87.6521 38.5471,-87.6721 38.5151,-87.6511 38.5001,-87.6531 38.5041,-87.6791 38.4811,-87.6921 38.4661,-87.7561 38.4571,-87.7581 38.4451,-87.7381 38.4171,-87.7481 38.3781,-87.7841 38.3521,-87.8341 38.2861,-87.8501 38.2851,-87.8631 38.3161,-87.8741 38.3151,-87.8831 38.3001,-87.8881 38.2811,-87.9141 38.3021,-87.9131 38.3041,-87.9251 38.2411,-87.9801 38.2341,-87.9861 38.2001,-87.9771 38.1711,-87.9321 38.1571,-87.9311 38.1361,-87.9501 38.1311,-87.9731 38.1031,-88.0181 38.0921,-88.0121 38.0961,-87.9641 38.0731,-87.9751 38.0541,-88.0341 38.0451,-88.0431 38.0381,-88.0411 38.0331,-88.0211 38.0081,-88.0291 37.9751,-88.0211 37.9561,-88.0421 37.9341,-88.0411 37.9291,-88.0641 37.944,-88.0781 37.9231,-88.084 37.9171,-88.0301 37.9051,-88.0261 37.8961,-88.0441 37.9061,-88.1001 37.8951,-88.1011 37.8671,-88.0751 37.8431,-88.0341 37.8271,-88.0421 37.8311,-88.0891 37.8171,-88.0861 37.8051,-88.0351 37.7351,-88.0721 37.7001,-88.1331 37.6601,-88.1591 37.6281,-88.1571 37.5831,-88.1341 37.5101,-88.0711</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></gml:polygonMember></gml:MultiPolygon></topp:the_geom><topp:STATE_NAME>Illinois</topp:STATE_NAME><topp:STATE_FIPS>17</topp:STATE_FIPS><topp:SUB_REGION>E N Cen</topp:SUB_REGION><topp:STATE_ABBR>IL</topp:STATE_ABBR><topp:LAND_KM>143986.61</topp:LAND_KM><topp:WATER_KM>1993.335</topp:WATER_KM><topp:PERSONS>1.1431E7</topp:PERSONS><topp:FAMILIES>2924880.0</topp:FAMILIES><topp:HOUSHOLD>4202240.0</topp:HOUSHOLD><topp:MALE>5552233.0</topp:MALE><topp:FEMALE>5878369.0</topp:FEMALE><topp:WORKERS>4199206.0</topp:WORKERS><topp:DRVALONE>3741715.0</topp:DRVALONE><topp:CARPOOL>652603.0</topp:CARPOOL><topp:PUBTRANS>538071.0</topp:PUBTRANS><topp:EMPLOYED>5417967.0</topp:EMPLOYED><topp:UNEMPLOY>385040.0</topp:UNEMPLOY><topp:SERVICE>1360159.0</topp:SERVICE><topp:MANUAL>828906.0</topp:MANUAL><topp:P_MALE>0.486</topp:P_MALE><topp:P_FEMALE>0.514</topp:P_FEMALE><topp:SAMP_POP>1747776.0</topp:SAMP_POP></topp:states></gml:featureMember></wfs:FeatureCollection>\n--></div>\n<div id=\"v2/multipletypenames.xml\"><!--\n<?xml version='1.0' encoding=\"ISO-8859-1\" ?><wfs:FeatureCollection   xmlns:rws=\"http://mapserver.gis.umn.edu/mapserver\"   xmlns:wfs=\"http://www.opengis.net/wfs\"   xmlns:gml=\"http://www.opengis.net/gml\"   xmlns:ogc=\"http://www.opengis.net/ogc\"   xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"   xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-basic.xsd                        http://mapserver.gis.umn.edu/mapserver http://intranet.rijkswaterstaat.nl/services/geoservices/kerngisnat_utre?SERVICE=WFS&amp;VERSION=1.0.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=VKUNSTWERK,LKUNSTWERK,PKUNSTWERK&amp;OUTPUTFORMAT=XMLSCHEMA\">      <gml:boundedBy>      \t<gml:Box srsName=\"EPSG:28992\">      \t\t<gml:coordinates>134503.789000,455332.337000 135149.909000,455893.926000</gml:coordinates>      \t</gml:Box>      </gml:boundedBy>    <gml:featureMember>      <rws:VKUNSTWERK fid=\"VKUNSTWERK.16\">        <gml:boundedBy>        \t<gml:Box srsName=\"EPSG:28992\">        \t\t<gml:coordinates>134949.571000,455438.845000 134978.799000,455471.762000</gml:coordinates>        \t</gml:Box>        </gml:boundedBy>        <rws:geometry>        <gml:MultiPolygon srsName=\"EPSG:28992\">        <gml:polygonMember>          <gml:Polygon>            <gml:outerBoundaryIs>              <gml:LinearRing>                <gml:coordinates>134974.191000,455471.587000 134973.974000,455471.762000 134973.558000,455471.248000 134973.579000,455471.230000 134963.143000,455458.768000 134962.787000,455458.653000 134960.514000,455456.003000 134960.440000,455455.539000 134950.207000,455443.320000 134950.158000,455443.360000 134949.571000,455442.638000 134949.810000,455442.462000 134951.417000,455441.223000 134951.435000,455441.209000 134954.158000,455439.108000 134954.507000,455438.845000 134955.000000,455439.420000 134954.954000,455439.458000 134965.046000,455451.520000 134965.568000,455451.606000 134968.159000,455454.642000 134968.120000,455455.195000 134978.294000,455467.355000 134978.330000,455467.326000 134978.799000,455467.881000 134978.598000,455468.042000 134975.885000,455470.224000 134974.191000,455471.587000 </gml:coordinates>              </gml:LinearRing>            </gml:outerBoundaryIs>            <gml:innerBoundaryIs>              <gml:LinearRing>                <gml:coordinates>134960.590000,455455.163000 134963.589000,455458.755000 134973.756000,455470.929000 134973.836000,455471.019000 134974.216000,455471.445000 134975.807000,455470.163000 134978.485000,455468.005000 134978.077000,455467.534000 134978.015000,455467.462000 134967.969000,455455.479000 134964.782000,455451.678000 134954.705000,455439.660000 134954.622000,455439.561000 134954.271000,455439.152000 134951.498000,455441.284000 134949.973000,455442.456000 134950.452000,455443.023000 134950.501000,455443.081000 134960.590000,455455.163000 </gml:coordinates>              </gml:LinearRing>            </gml:innerBoundaryIs>          </gml:Polygon>        </gml:polygonMember>        </gml:MultiPolygon>        </rws:geometry>        <rws:OBJECTID>16</rws:OBJECTID>        <rws:OBJECTSUBCATEGORIE>31</rws:OBJECTSUBCATEGORIE>      </rws:VKUNSTWERK>    </gml:featureMember>    <gml:featureMember>      <rws:LKUNSTWERK fid=\"LKUNSTWERK.14\">        <gml:boundedBy>        \t<gml:Box srsName=\"EPSG:28992\">        \t\t<gml:coordinates>135080.966000,455332.337000 135149.909000,455390.384000</gml:coordinates>        \t</gml:Box>        </gml:boundedBy>        <rws:geometry>        <gml:MultiLineString srsName=\"EPSG:28992\">          <gml:lineStringMember>            <gml:LineString>              <gml:coordinates>135080.966000,455390.384000 135096.654000,455377.009000 135109.082000,455366.755000 135122.769000,455355.276000 135141.565000,455339.633000 135149.909000,455332.337000 </gml:coordinates>            </gml:LineString>          </gml:lineStringMember>        </gml:MultiLineString>        </rws:geometry>        <rws:OBJECTID>14</rws:OBJECTID>        <rws:OBJECTSUBCATEGORIE>30</rws:OBJECTSUBCATEGORIE>      </rws:LKUNSTWERK>    </gml:featureMember>    <gml:featureMember>      <rws:PKUNSTWERK fid=\"PKUNSTWERK.29\">        <gml:boundedBy>        \t<gml:Box srsName=\"EPSG:28992\">        \t\t<gml:coordinates>134832.017000,455596.187000 134832.017000,455596.187000</gml:coordinates>        \t</gml:Box>        </gml:boundedBy>        <rws:geometry>        <gml:MultiPoint srsName=\"EPSG:28992\">          <gml:pointMember>            <gml:Point>              <gml:coordinates>134832.017000,455596.187000</gml:coordinates>            </gml:Point>          </gml:pointMember>        </gml:MultiPoint>        </rws:geometry>        <rws:OBJECTID>29</rws:OBJECTID>        <rws:OBJECTSUBCATEGORIE>30</rws:OBJECTSUBCATEGORIE>      </rws:PKUNSTWERK>    </gml:featureMember></wfs:FeatureCollection>\n--></div>\n<div id=\"v2/nogeom.xml\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\"?><wfs:FeatureCollection xmlns=\"http://www.opengis.net/wfs\" xmlns:wfs=\"http://www.opengis.net/wfs\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:loc=\"http://server.fr/geoserver/loc\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/wfs http://server.fr:80/geoserver/schemas/wfs/1.0.0/WFS-basic.xsd http://server.fr/geoserver/loc http://server.fr:80/geoserver/wfs?service=WFS&amp;version=1.0.0&amp;request=DescribeFeatureType&amp;typeName=loc:DEPARTEMENT\"><gml:boundedBy><gml:Box srsName=\"http://www.opengis.net/gml/srs/epsg.xml#2154\"><gml:coordinates xmlns:gml=\"http://www.opengis.net/gml\" decimal=\".\" cs=\",\" ts=\" \">199373,6704170 337568,6885985</gml:coordinates></gml:Box></gml:boundedBy><gml:featureMember><loc:DEPARTEMENT fid=\"DEPARTEMENT.1\"><gml:boundedBy><gml:Box srsName=\"http://www.opengis.net/gml/srs/epsg.xml#2154\"><gml:coordinates xmlns:gml=\"http://www.opengis.net/gml\" decimal=\".\" cs=\",\" ts=\" \">209565,6785323 337568,6885985</gml:coordinates></gml:Box></gml:boundedBy><loc:NOM_DEPT>COTES-D'ARMOR</loc:NOM_DEPT></loc:DEPARTEMENT></gml:featureMember><gml:featureMember><loc:DEPARTEMENT fid=\"DEPARTEMENT.3\"><gml:boundedBy><gml:Box srsName=\"http://www.opengis.net/gml/srs/epsg.xml#2154\"><gml:coordinates xmlns:gml=\"http://www.opengis.net/gml\" decimal=\".\" cs=\",\" ts=\" \">199373,6704170 323518,6807542</gml:coordinates></gml:Box></gml:boundedBy><loc:NOM_DEPT>MORBIHAN</loc:NOM_DEPT></loc:DEPARTEMENT></gml:featureMember></wfs:FeatureCollection>\n--></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/GML/v3.html",
    "content": "<html> \n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script src=\"cases.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_readNode_geometry(t) {\n        var files = [\n            \"v2/point-coord.xml\", \"v2/point-coordinates.xml\",\n            \"v2/linestring-coord.xml\", \"v2/linestring-coordinates.xml\",\n            \"v2/multipoint-coord.xml\", \"v2/multipoint-coordinates.xml\",\n            \"v2/multilinestring-coord.xml\", \"v2/multilinestring-coordinates.xml\",\n            \"v3/point.xml\", \"v3/linestring.xml\", \"v3/linestring3d.xml\",\n            \"v3/curve.xml\", \"v3/polygon.xml\", \"v3/surface.xml\",\n            \"v3/multipoint-singular.xml\", \"v3/multipoint-plural.xml\",\n            \"v3/multilinestring-singular.xml\", \"v3/multilinestring-plural.xml\",\n            \"v3/multicurve-singular.xml\", \"v3/multicurve-curve.xml\",\n            \"v3/multipolygon-singular.xml\", \"v3/multipolygon-plural.xml\",\n            \"v3/multisurface-singular.xml\", \"v3/multisurface-plural.xml\",\n            \"v3/multisurface-surface.xml\"\n        ];\n\n        var len = files.length;\n        t.plan(len);\n\n        var format = new OpenLayers.Format.GML.v3({\n            featureType: \"feature\",\n            featureNS: \"http://example.com/feature\"\n        });\n        var file, doc, expect, out;\n        for(var i=0; i<len; ++i) {\n            file = files[i];\n            expect = cases[file];\n            if(expect) {\n                doc = readXML(file);\n                if(doc && doc.documentElement) {\n                    out = format.readNode(doc.documentElement);\n                    if(out.components && out.components.length == 1) {\n                        t.geom_eq(out.components[0], expect, \"[\" + file + \"] geometry read\");\n                    } else {\n                        t.fail(\"[\" + file + \"] gml parsing\");\n                    }\n                } else {\n                    t.fail(\"[\" + file + \"] xml parsing\");\n                }\n            } else {\n                t.fail(\"[\" + file + \"] case not found\");\n            }\n        }\n        \n    }\n\n    function test_read_setGeometryName(t) {\n        t.plan(1);\n        var doc = readXML(\"v3/topp-states-gml.xml\");\n        var format = new OpenLayers.Format.GML.v3({\n            featureType: \"states\",\n            featureNS: \"http://www.openplans.org/topp\",\n            geometryName: null\n        });\n        var features = format.read(doc.documentElement);\n\n        t.eq(format.geometryName, \"the_geom\", \"geometryName set when parsing features\");\n    }\n\n    function test_readNode_bounds(t) {\n        var files = [\"v3/envelope.xml\"];\n\n        var len = files.length;\n        t.plan(len);\n        \n        var file, doc, expect, got;\n        var format = new OpenLayers.Format.GML.v3({\n            featureType: \"feature\",\n            featureNS: \"http://example.com/feature\"\n        });\n        for(var i=0; i<len; ++i) {\n            file = files[i];\n            expect = cases[file];\n            if(expect) {\n                doc = readXML(file);\n                if(doc && doc.documentElement) {\n                    out = format.readNode(doc.documentElement);\n                    if(out.components && out.components.length == 1) {\n                        got = out.components[0];\n                        if(got instanceof OpenLayers.Bounds) {\n                            t.ok(out.components[0].equals(expect), \"[\" + file + \"] bounds read\")\n                        } else {\n                            t.fail(\"[\" + file + \"] expected a bounds, got \" + got);\n                        }\n                    } else {\n                        t.fail(\"[\" + file + \"] gml parsing\");\n                    }\n                } else {\n                    t.fail(\"[\" + file + \"] xml parsing\");\n                }\n            } else {\n                t.fail(\"[\" + file + \"] case not found\");\n            }\n        }\n        \n    }\n\n    function test_writeNode_geometry(t) {\n        // we only care to write the 'pos' and 'posList' variants of GML 3 - conforming with simple features profile\n        var files = [\n            {path: \"v3/point.xml\"},\n            {path: \"v3/linestring.xml\"},\n            {path: \"v3/curve.xml\", options: {curve: true}},\n            {path: \"v3/polygon.xml\"},\n            {path: \"v3/surface.xml\", options: {surface: true}},\n            {path: \"v3/multipoint-singular.xml\"},\n            {path: \"v3/multilinestring-singular.xml\", options: {multiCurve: false}},\n            {path: \"v3/multicurve-singular.xml\"},\n            {path: \"v3/multicurve-curve.xml\", options: {curve: true}},\n            {path: \"v3/multipolygon-singular.xml\", options: {multiSurface: false}},\n            {path: \"v3/multisurface-singular.xml\"},\n            {path: \"v3/multisurface-surface.xml\", options: {surface: true}}\n        ];\n\n        var len = files.length;\n        t.plan(len);\n\n        var defaults = {\n            featureType: \"feature\",\n            featureNS: \"http://example.com/feature\",\n            srsName: \"foo\" // GML geometry collections require srsName, we only write if provided\n        };\n\n        var format, options, file, geom, doc, node;\n        for(var i=0; i<len; ++i) {\n            file = files[i].path;\n            geom = cases[file];\n            if(geom) {\n                doc = readXML(file);\n                if(doc && doc.documentElement) {\n                    options = OpenLayers.Util.extend({}, defaults);\n                    if(files[i].options) {\n                        OpenLayers.Util.extend(options, files[i].options);\n                    }\n                    format = new OpenLayers.Format.GML.v3(options);\n                    node = format.writeNode(\"feature:_geometry\", geom);\n                    t.xml_eq(node.firstChild, doc.documentElement, \"[\" + file + \"] geometry written\");\n                } else {\n                    t.fail(\"[\" + file + \"] xml parsing\");\n                }\n            } else {\n                t.fail(\"[\" + file + \"] case not found\");\n            }\n        }\n    }\n\n    function test_writeNode_bounds(t) {\n        var files = [\n            \"v3/envelope.xml\"\n        ];\n\n        var len = files.length;\n        t.plan(len);\n\n        var format = new OpenLayers.Format.GML.v3({\n            featureType: \"feature\",\n            featureNS: \"http://example.com/feature\",\n            srsName: \"foo\" // GML envelopes require srsName, we only write if provided\n        });\n        var file, bounds, doc, node;\n        for(var i=0; i<len; ++i) {\n            file = files[i];\n            bounds = cases[file];\n            if(bounds) {\n                doc = readXML(file);\n                if(doc && doc.documentElement) {\n                    node = format.writeNode(\"gml:Envelope\", bounds);\n                    t.xml_eq(node, doc.documentElement, \"[\" + file + \"] bounds written\");\n                } else {\n                    t.fail(\"[\" + file + \"] xml parsing\");\n                }\n            } else {\n                t.fail(\"[\" + file + \"] case not found\");\n            }\n        }\n    }\n    \n    function test_boundedBy(t) {\n        t.plan(5);\n        \n        var doc = readXML(\"v3/topp-states-wfs.xml\");\n        var format = new OpenLayers.Format.GML.v3({\n            featureType: \"states\",\n            featureNS: \"http://www.openplans.org/topp\",\n            geometryName: \"the_geom\",\n            xy: false\n        });\n        var features = format.read(doc.documentElement);\n        var bounds = features[0].bounds;\n\n        t.ok(bounds instanceof OpenLayers.Bounds, \"feature given a bounds\");\n        t.eq(bounds.left.toFixed(2), \"-91.52\", \"bounds left correct\");\n        t.eq(bounds.bottom.toFixed(2), \"36.99\", \"bounds bottom correct\");\n        t.eq(bounds.right.toFixed(2), \"-87.51\", \"bounds right correct\");\n        t.eq(bounds.top.toFixed(2), \"42.51\", \"bounds top correct\");\n    }\n\n    function test_read(t) {\n        t.plan(8);\n        var doc = readXML(\"v3/topp-states-wfs.xml\");\n        var format = new OpenLayers.Format.GML.v3({\n            featureType: \"states\",\n            featureNS: \"http://www.openplans.org/topp\",\n            geometryName: \"the_geom\",\n            xy: false\n        });\n        var features = format.read(doc.documentElement);\n        \n        t.eq(features.length, 3, \"read 3 features\");\n        var feature = features[0];\n        t.eq(feature.fid, \"states.1\", \"read fid\");\n        t.eq(feature.geometry.CLASS_NAME, \"OpenLayers.Geometry.MultiPolygon\",\n             \"read multipolygon geometry\");\n        var attributes = feature.attributes;\n        t.eq(attributes[\"STATE_NAME\"], \"Illinois\", \"read STATE_NAME\");\n        t.eq(attributes[\"STATE_FIPS\"], \"17\", \"read STATE_FIPS\");\n        t.eq(attributes[\"SUB_REGION\"], \"E N Cen\", \"read SUB_REGION\");\n        t.eq(attributes[\"STATE_ABBR\"], \"IL\", \"read STATE_ABBR\");\n        t.eq(attributes[\"LAND_KM\"], \"143986.61\", \"read LAND_KM\");\n    }\n    \n    function test_read_autoconfig(t) {\n        t.plan(7);\n        var doc = readXML(\"v3/topp-states-wfs.xml\");\n        var format = new OpenLayers.Format.GML.v3();\n        var features = format.read(doc.documentElement);\n        \n        t.eq(features.length, 3, \"read 3 features\");\n        var feature = features[0];\n        t.eq(feature.fid, \"states.1\", \"read fid\");\n        t.eq(feature.geometry.CLASS_NAME, \"OpenLayers.Geometry.MultiPolygon\",\n             \"read multipolygon geometry\");\n        t.eq(format.featureType, \"states\", \"featureType correctly auto-configured\");\n        t.eq(format.featureNS, \"http://www.openplans.org/topp\", \"featureNS correctly auto-configured\");\n\n        t.eq(format.autoConfig, true, \"autoConfig set to true\");\n        format.autoConfig = false;\n        format.read(doc.documentElement);\n        t.eq(format.autoConfig, false, \"now that featureNS is set, the format does not auto-configure again\");\n    }\n    \n    function test_emptyAttribute(t) {\n        t.plan(4);\n        var str =\n            '<gml:featureMembers xmlns:gml=\"http://www.opengis.net/gml\">' +\n                '<topp:gnis_pop gml:id=\"gnis_pop.148604\" xmlns:topp=\"http://www.openplans.org/topp\">' +\n                    '<gml:name>Aflu</gml:name>' +\n                    '<topp:the_geom>' +\n                        '<gml:Point srsName=\"urn:x-ogc:def:crs:EPSG:4326\">' +\n                            '<gml:pos>34.12 2.09</gml:pos>' +\n                        '</gml:Point>' +\n                    '</topp:the_geom>' +\n                    '<topp:population>84683</topp:population>' +\n                    '<topp:country>Algeria</topp:country>' +\n                    '<topp:type>place</topp:type>' +\n                    '<topp:name>Aflu</topp:name>' +\n                    '<topp:empty></topp:empty>' +\n                '</topp:gnis_pop>' +\n            '</gml:featureMembers>';\n\n        var format = new OpenLayers.Format.GML.v3({\n            featureType: \"gnis_pop\",\n            featureNS: \"http://www.openplans.org/topp\",\n            geometryName: \"the_geom\"\n        });\n        \n        var features = format.read(str);\n        t.eq(features.length, 1, \"read one feature\");\n        var attr = features[0].attributes;\n        t.eq(attr.name, \"Aflu\", \"correctly read attribute value\");\n        t.eq(attr.foo, undefined, \"bogus attribute is undefined\");\n        t.eq(attr.empty, \"\", \"empty attribute value is empty string\");\n    }\n    \n    function test_repeatedName(t) {\n        // test that if an attribute name matches the featureType, all goes well\n        t.plan(2);\n        var doc = readXML(\"v3/repeated-name.xml\");\n        var format = new OpenLayers.Format.GML.v3({\n            featureType: \"zoning\",\n            featureNS: \"http://opengeo.org/#medford\",\n            geometryName: \"the_geom\",\n            xy: false\n        });\n        var features = format.read(doc.documentElement);\n        \n        t.eq(features.length, 1, \"read one feature\");\n        var atts = features[0].attributes;\n        t.eq(atts.zoning, \"I-L\", \"correct zoning attribute on zoning feature type\");\n\n    }\n\n    function test_write(t) {\n        t.plan(1);\n        var doc = readXML(\"v3/topp-states-gml.xml\");\n        var format = new OpenLayers.Format.GML.v3({\n            featureType: \"states\",\n            featureNS: \"http://www.openplans.org/topp\",\n            geometryName: \"the_geom\",\n            srsName: \"urn:x-ogc:def:crs:EPSG:4326\",\n            xy: false,\n            schemaLocation: \"http://www.openplans.org/topp http://sigma.openplans.org:80/geoserver/wfs?service=WFS&version=1.1.0&request=DescribeFeatureType&typeName=topp:states http://www.opengis.net/gml http://schemas.opengis.net/gml/3.2.1/gml.xsd\"\n        });\n        var features = format.read(doc.documentElement);\n        \n        var got = format.write(features);\n        t.xml_eq(got, doc.documentElement, \"gml:featureMembers round trip\");\n    }\n\n   </script>\n</head>\n<body>\n<div id=\"v3/envelope.xml\"><!--\n<gml:Envelope xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:lowerCorner>1 2</gml:lowerCorner>\n    <gml:upperCorner>3 4</gml:upperCorner>\n</gml:Envelope>\n--></div>\n<div id=\"v3/linearring.xml\"><!--\n<gml:LinearRing xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:posList>1 2 3 4 5 6 1 2</gml:posList>\n</gml:LinearRing>\n--></div>\n<div id=\"v3/linestring.xml\"><!--\n<gml:LineString xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n  <gml:posList>1 2 3 4</gml:posList>\n</gml:LineString>\n--></div>\n<div id=\"v3/linestring3d.xml\"><!--\n<gml:LineString xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\" srsDimension=\"3\">\n  <gml:posList>1 2 3 4 5 6</gml:posList>\n</gml:LineString>\n--></div>\n<div id=\"v3/curve.xml\"><!--\n<gml:Curve xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:segments>\n        <gml:LineStringSegment>\n            <gml:posList>1 2 3 4</gml:posList>\n        </gml:LineStringSegment>\n    </gml:segments>\n</gml:Curve>\n--></div>\n<div id=\"v3/multilinestring-plural.xml\"><!--\n<gml:MultiLineString xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:lineStringMembers>\n        <gml:LineString>\n            <gml:posList>1 2 2 3</gml:posList>\n        </gml:LineString>\n        <gml:LineString>\n            <gml:posList>3 4 4 5</gml:posList>\n        </gml:LineString>\n    </gml:lineStringMembers>\n</gml:MultiLineString>\n--></div>\n<div id=\"v3/multilinestring-singular.xml\"><!--\n<gml:MultiLineString xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:lineStringMember>\n        <gml:LineString>\n            <gml:posList>1 2 2 3</gml:posList>\n        </gml:LineString>\n    </gml:lineStringMember>\n    <gml:lineStringMember>\n        <gml:LineString>\n            <gml:posList>3 4 4 5</gml:posList>\n        </gml:LineString>\n    </gml:lineStringMember>\n</gml:MultiLineString>\n--></div>\n<div id=\"v3/multicurve-singular.xml\"><!--\n<gml:MultiCurve xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:curveMember>\n        <gml:LineString>\n            <gml:posList>1 2 2 3</gml:posList>\n        </gml:LineString>\n    </gml:curveMember>\n    <gml:curveMember>\n        <gml:LineString>\n            <gml:posList>3 4 4 5</gml:posList>\n        </gml:LineString>\n    </gml:curveMember>\n</gml:MultiCurve>\n--></div>\n<div id=\"v3/multicurve-curve.xml\"><!--\n<gml:MultiCurve xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:curveMember>\n        <gml:Curve>\n            <gml:segments>\n                <gml:LineStringSegment>\n                    <gml:posList>1 2 2 3</gml:posList>\n                </gml:LineStringSegment>\n            </gml:segments>\n        </gml:Curve>\n    </gml:curveMember>\n    <gml:curveMember>\n        <gml:Curve>\n            <gml:segments>\n                <gml:LineStringSegment>\n                    <gml:posList>3 4 4 5</gml:posList>\n                </gml:LineStringSegment>\n            </gml:segments>\n        </gml:Curve>\n    </gml:curveMember>\n</gml:MultiCurve>\n--></div>\n<div id=\"v3/multipoint-plural.xml\"><!--\n<gml:MultiPoint xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:pointMembers>\n        <gml:Point>\n            <gml:pos>1 2</gml:pos>\n        </gml:Point>\n        <gml:Point>\n            <gml:pos>2 3</gml:pos>\n        </gml:Point>\n        <gml:Point>\n            <gml:pos>3 4</gml:pos>\n        </gml:Point>\n    </gml:pointMembers>\n</gml:MultiPoint>\n--></div>\n<div id=\"v3/multipoint-singular.xml\"><!--\n<gml:MultiPoint xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:pointMember>\n        <gml:Point>\n            <gml:pos>1 2</gml:pos>\n        </gml:Point>\n    </gml:pointMember>\n    <gml:pointMember>\n        <gml:Point>\n            <gml:pos>2 3</gml:pos>\n        </gml:Point>\n    </gml:pointMember>\n    <gml:pointMember>\n        <gml:Point>\n            <gml:pos>3 4</gml:pos>\n        </gml:Point>\n    </gml:pointMember>\n</gml:MultiPoint>\n--></div>\n<div id=\"v3/multipolygon-plural.xml\"><!--\n<gml:MultiPolygon xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:polygonMembers>\n        <gml:Polygon>\n            <gml:exterior>\n                <gml:LinearRing>\n                    <gml:posList>1 2 3 4 5 6 1 2</gml:posList>\n                </gml:LinearRing>\n            </gml:exterior>\n            <gml:interior>\n                <gml:LinearRing>\n                    <gml:posList>2 3 4 5 6 7 2 3</gml:posList>\n                </gml:LinearRing>\n            </gml:interior>    \n            <gml:interior>\n                <gml:LinearRing>\n                    <gml:posList>3 4 5 6 7 8 3 4</gml:posList>\n                </gml:LinearRing>\n            </gml:interior>\n        </gml:Polygon>\n        <gml:Polygon>\n            <gml:exterior>\n                <gml:LinearRing>\n                    <gml:posList>1 2 3 4 5 6 1 2</gml:posList>\n                </gml:LinearRing>\n            </gml:exterior>\n        </gml:Polygon>\n    </gml:polygonMembers>\n</gml:MultiPolygon>\n--></div>\n<div id=\"v3/multipolygon-singular.xml\"><!--\n<gml:MultiPolygon xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:polygonMember>\n        <gml:Polygon>\n            <gml:exterior>\n                <gml:LinearRing>\n                    <gml:posList>1 2 3 4 5 6 1 2</gml:posList>\n                </gml:LinearRing>\n            </gml:exterior>\n            <gml:interior>\n                <gml:LinearRing>\n                    <gml:posList>2 3 4 5 6 7 2 3</gml:posList>\n                </gml:LinearRing>\n            </gml:interior>    \n            <gml:interior>\n                <gml:LinearRing>\n                    <gml:posList>3 4 5 6 7 8 3 4</gml:posList>\n                </gml:LinearRing>\n            </gml:interior>\n        </gml:Polygon>\n    </gml:polygonMember>\n    <gml:polygonMember>\n        <gml:Polygon>\n            <gml:exterior>\n                <gml:LinearRing>\n                    <gml:posList>1 2 3 4 5 6 1 2</gml:posList>\n                </gml:LinearRing>\n            </gml:exterior>\n        </gml:Polygon>\n    </gml:polygonMember>\n</gml:MultiPolygon>\n--></div>\n<div id=\"v3/multisurface-plural.xml\"><!--\n<gml:MultiSurface xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:surfaceMembers>\n        <gml:Polygon>\n            <gml:exterior>\n                <gml:LinearRing>\n                    <gml:posList>1 2 3 4 5 6 1 2</gml:posList>\n                </gml:LinearRing>\n            </gml:exterior>\n            <gml:interior>\n                <gml:LinearRing>\n                    <gml:posList>2 3 4 5 6 7 2 3</gml:posList>\n                </gml:LinearRing>\n            </gml:interior>    \n            <gml:interior>\n                <gml:LinearRing>\n                    <gml:posList>3 4 5 6 7 8 3 4</gml:posList>\n                </gml:LinearRing>\n            </gml:interior>\n        </gml:Polygon>\n        <gml:Polygon>\n            <gml:exterior>\n                <gml:LinearRing>\n                    <gml:posList>1 2 3 4 5 6 1 2</gml:posList>\n                </gml:LinearRing>\n            </gml:exterior>\n        </gml:Polygon>\n    </gml:surfaceMembers>\n</gml:MultiSurface>\n--></div>\n<div id=\"v3/multisurface-singular.xml\"><!--\n<gml:MultiSurface xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:surfaceMember>\n        <gml:Polygon>\n            <gml:exterior>\n                <gml:LinearRing>\n                    <gml:posList>1 2 3 4 5 6 1 2</gml:posList>\n                </gml:LinearRing>\n            </gml:exterior>\n            <gml:interior>\n                <gml:LinearRing>\n                    <gml:posList>2 3 4 5 6 7 2 3</gml:posList>\n                </gml:LinearRing>\n            </gml:interior>    \n            <gml:interior>\n                <gml:LinearRing>\n                    <gml:posList>3 4 5 6 7 8 3 4</gml:posList>\n                </gml:LinearRing>\n            </gml:interior>\n        </gml:Polygon>\n    </gml:surfaceMember>\n    <gml:surfaceMember>\n        <gml:Polygon>\n            <gml:exterior>\n                <gml:LinearRing>\n                    <gml:posList>1 2 3 4 5 6 1 2</gml:posList>\n                </gml:LinearRing>\n            </gml:exterior>\n        </gml:Polygon>\n    </gml:surfaceMember>\n</gml:MultiSurface>\n--></div>\n<div id=\"v3/multisurface-surface.xml\"><!--\n<gml:MultiSurface xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:surfaceMember>\n        <gml:Surface>\n            <gml:patches>\n                <gml:PolygonPatch interpolation=\"planar\">\n                    <gml:exterior>\n                        <gml:LinearRing>\n                            <gml:posList>1 2 3 4 5 6 1 2</gml:posList>\n                        </gml:LinearRing>\n                    </gml:exterior>\n                    <gml:interior>\n                        <gml:LinearRing>\n                            <gml:posList>2 3 4 5 6 7 2 3</gml:posList>\n                        </gml:LinearRing>\n                    </gml:interior>    \n                    <gml:interior>\n                        <gml:LinearRing>\n                            <gml:posList>3 4 5 6 7 8 3 4</gml:posList>\n                        </gml:LinearRing>\n                    </gml:interior>\n                </gml:PolygonPatch>\n            </gml:patches>\n        </gml:Surface>\n    </gml:surfaceMember>\n    <gml:surfaceMember>\n        <gml:Surface>\n            <gml:patches>\n                <gml:PolygonPatch interpolation=\"planar\">\n                    <gml:exterior>\n                        <gml:LinearRing>\n                            <gml:posList>1 2 3 4 5 6 1 2</gml:posList>\n                        </gml:LinearRing>\n                    </gml:exterior>\n                </gml:PolygonPatch>\n            </gml:patches>\n        </gml:Surface>\n    </gml:surfaceMember>\n</gml:MultiSurface>\n--></div>\n<div id=\"v3/point.xml\"><!--\n<gml:Point xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n  <gml:pos>1 2</gml:pos>\n</gml:Point>\n--></div>\n<div id=\"v3/polygon.xml\"><!--\n<gml:Polygon xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:exterior>\n        <gml:LinearRing>\n            <gml:posList>1 2 3 4 5 6 1 2</gml:posList>\n        </gml:LinearRing>\n    </gml:exterior>\n    <gml:interior>\n        <gml:LinearRing>\n            <gml:posList>2 3 4 5 6 7 2 3</gml:posList>\n        </gml:LinearRing>\n    </gml:interior>    \n    <gml:interior>\n        <gml:LinearRing>\n            <gml:posList>3 4 5 6 7 8 3 4</gml:posList>\n        </gml:LinearRing>\n    </gml:interior>    \n</gml:Polygon>\n--></div>\n<div id=\"v3/surface.xml\"><!--\n<gml:Surface xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:patches>\n        <gml:PolygonPatch interpolation=\"planar\">\n            <gml:exterior>\n                <gml:LinearRing>\n                    <gml:posList>1 2 3 4 5 6 1 2</gml:posList>\n                </gml:LinearRing>\n            </gml:exterior>\n            <gml:interior>\n                <gml:LinearRing>\n                    <gml:posList>2 3 4 5 6 7 2 3</gml:posList>\n                </gml:LinearRing>\n            </gml:interior>    \n            <gml:interior>\n                <gml:LinearRing>\n                    <gml:posList>3 4 5 6 7 8 3 4</gml:posList>\n                </gml:LinearRing>\n            </gml:interior>\n        </gml:PolygonPatch>\n    </gml:patches>\n</gml:Surface>\n--></div>\n<div id=\"v3/topp-states-gml.xml\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<gml:featureMembers xsi:schemaLocation=\"http://www.openplans.org/topp http://sigma.openplans.org:80/geoserver/wfs?service=WFS&amp;version=1.1.0&amp;request=DescribeFeatureType&amp;typeName=topp:states http://www.opengis.net/gml http://schemas.opengis.net/gml/3.2.1/gml.xsd\" xmlns:topp=\"http://www.openplans.org/topp\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:gml=\"http://www.opengis.net/gml\"><topp:states fid=\"states.1\"><topp:the_geom><gml:MultiSurface srsName=\"urn:x-ogc:def:crs:EPSG:4326\"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>37.5101 -88.0711 37.4761 -88.0871 37.4421 -88.3111 37.4091 -88.3591 37.4201 -88.4191 37.4001 -88.4671 37.2961 -88.5111 37.2571 -88.5011 37.2051 -88.4501 37.1561 -88.4221 37.0981 -88.4501 37.0721 -88.4761 37.0681 -88.4901 37.0641 -88.5171 37.0721 -88.5591 37.1091 -88.6141 37.1351 -88.6881 37.1411 -88.7391 37.1521 -88.7461 37.2021 -88.8631 37.2181 -88.9321 37.2201 -88.9931 37.1851 -89.0651 37.1121 -89.1161 37.0931 -89.1461 37.0641 -89.1691 37.0251 -89.1741 36.9981 -89.1501 36.9881 -89.1291 36.9861 -89.1931 37.0281 -89.2101 37.0411 -89.2371 37.0871 -89.2641 37.0911 -89.2841 37.0851 -89.3031 37.0601 -89.3091 37.0271 -89.2641 37.0081 -89.2621 36.9991 -89.2821 37.0091 -89.3101 37.0491 -89.3821 37.0991 -89.3791 37.1371 -89.4231 37.1651 -89.4401 37.2241 -89.4681 37.2531 -89.4651 37.2561 -89.4891 37.2761 -89.5131 37.3041 -89.5131 37.3291 -89.5001 37.3391 -89.4681 37.3551 -89.4351 37.4111 -89.4271 37.4531 -89.4531 37.4911 -89.4941 37.5711 -89.5241 37.6151 -89.5131 37.6501 -89.5191 37.6791 -89.5131 37.6941 -89.5211 37.7061 -89.5811 37.7451 -89.6661 37.7831 -89.6751 37.8041 -89.6911 37.8401 -89.7281 37.9051 -89.8511 37.9051 -89.8611 37.8911 -89.8661 37.8751 -89.9001 37.8781 -89.9371 37.9111 -89.9781 37.9631 -89.9581 37.9691 -90.0101 37.9931 -90.0411 38.0321 -90.1191 38.0531 -90.1341 38.0881 -90.2071 38.1221 -90.2541 38.1661 -90.2891 38.1881 -90.3361 38.2341 -90.3641 38.3231 -90.3691 38.3651 -90.3581 38.3901 -90.3391 38.4271 -90.3011 38.5181 -90.2651 38.5321 -90.2611 38.5621 -90.2401 38.6101 -90.1831 38.6581 -90.1831 38.7001 -90.2021 38.7231 -90.1961 38.7731 -90.1631 38.7851 -90.1351 38.8001 -90.1211 38.8301 -90.1131 38.8531 -90.1321 38.9141 -90.2431 38.9241 -90.2781 38.9241 -90.3191 38.9621 -90.4131 38.9591 -90.4691 38.8911 -90.5301 38.8711 -90.5701 38.8801 -90.6271 38.9351 -90.6681 39.0371 -90.7061 39.0581 -90.7071 39.0931 -90.6901 39.1441 -90.7161 39.1951 -90.7181 39.2241 -90.7321 39.2471 -90.7381 39.2961 -90.7791 39.3501 -90.8501 39.4001 -90.9471 39.4441 -91.0361 39.4731 -91.0641 39.5281 -91.0931 39.5521 -91.1561 39.6001 -91.2031 39.6851 -91.3171 39.7241 -91.3671 39.7611 -91.3731 39.8031 -91.3811 39.8631 -91.4491 39.8851 -91.4501 39.9011 -91.4341 39.9211 -91.4301 39.9461 -91.4471 40.0051 -91.4871 40.0661 -91.5041 40.1341 -91.5161 40.2001 -91.5061 40.2511 -91.4981 40.3091 -91.4861 40.3711 -91.4481 40.3861 -91.4181 40.3921 -91.3851 40.4021 -91.3721 40.4471 -91.3851 40.5031 -91.3741 40.5281 -91.3821 40.5471 -91.4121 40.5721 -91.4111 40.6031 -91.3751 40.6391 -91.2621 40.6431 -91.2141 40.6561 -91.1621 40.6821 -91.1291 40.7051 -91.1191 40.7611 -91.0921 40.8331 -91.0881 40.8791 -91.0491 40.9231 -90.9831 40.9501 -90.9601 41.0701 -90.9541 41.1041 -90.9571 41.1441 -90.9901 41.1651 -91.0181 41.1761 -91.0561 41.2311 -91.1011 41.2671 -91.1021 41.3341 -91.0731 41.4011 -91.0551 41.4231 -91.0271 41.4311 -91.0001 41.4211 -90.9491 41.4441 -90.8441 41.4491 -90.7791 41.4501 -90.7081 41.4621 -90.6581 41.5091 -90.6001 41.5251 -90.5401 41.5271 -90.4541 41.5431 -90.4341 41.5671 -90.4231 41.5861 -90.3481 41.6021 -90.3391 41.6491 -90.3411 41.7221 -90.3261 41.7561 -90.3041 41.7811 -90.2551 41.8061 -90.1951 41.9301 -90.1541 41.9831 -90.1421 42.0331 -90.1501 42.0611 -90.1681 42.1031 -90.1661 42.1201 -90.1761 42.1221 -90.1911 42.1591 -90.2301 42.1971 -90.3231 42.2101 -90.3671 42.2421 -90.4071 42.2631 -90.4171 42.3401 -90.4271 42.3601 -90.4411 42.3881 -90.4911 42.4211 -90.5631 42.4601 -90.6051 42.4751 -90.6481 42.4941 -90.6511 42.5091 -90.6381 42.5081 -90.4191 42.5041 -89.9231 42.5031 -89.8341 42.4971 -89.4001 42.4971 -89.3591 42.4901 -88.9391 42.4901 -88.7641 42.4891 -88.7061 42.4911 -88.2971 42.4891 -88.1941 42.4891 -87.7971 42.3141 -87.8361 42.1561 -87.7601 42.0591 -87.6701 41.8471 -87.6121 41.7231 -87.5291 41.4691 -87.5321 41.3011 -87.5321 41.1731 -87.5311 41.0091 -87.5321 40.7451 -87.5321 40.4941 -87.5371 40.4831 -87.5351 40.1661 -87.5351 39.8871 -87.5351 39.6091 -87.5351 39.4771 -87.5381 39.3501 -87.5401 39.3381 -87.5971 39.3071 -87.6251 39.2971 -87.6101 39.2811 -87.6151 39.2581 -87.6061 39.2481 -87.5841 39.2081 -87.5881 39.1981 -87.5941 39.1961 -87.6071 39.1681 -87.6441 39.1461 -87.6701 39.1301 -87.6591 39.1131 -87.6621 39.1031 -87.6311 39.0881 -87.6301 39.0841 -87.6121 39.0621 -87.5851 38.9951 -87.5811 38.9941 -87.5911 38.9771 -87.5471 38.9631 -87.5331 38.9311 -87.5301 38.9041 -87.5391 38.8691 -87.5591 38.8571 -87.5501 38.7951 -87.5071 38.7761 -87.5191 38.7691 -87.5081 38.7361 -87.5081 38.6851 -87.5431 38.6721 -87.5881 38.6421 -87.6251 38.6221 -87.6281 38.5991 -87.6191 38.5931 -87.6401 38.5731 -87.6521 38.5471 -87.6721 38.5151 -87.6511 38.5001 -87.6531 38.5041 -87.6791 38.4811 -87.6921 38.4661 -87.7561 38.4571 -87.7581 38.4451 -87.7381 38.4171 -87.7481 38.3781 -87.7841 38.3521 -87.8341 38.2861 -87.8501 38.2851 -87.8631 38.3161 -87.8741 38.3151 -87.8831 38.3001 -87.8881 38.2811 -87.9141 38.3021 -87.9131 38.3041 -87.9251 38.2411 -87.9801 38.2341 -87.9861 38.2001 -87.9771 38.1711 -87.9321 38.1571 -87.9311 38.1361 -87.9501 38.1311 -87.9731 38.1031 -88.0181 38.0921 -88.0121 38.0961 -87.9641 38.0731 -87.9751 38.0541 -88.0341 38.0451 -88.0431 38.0381 -88.0411 38.0331 -88.0211 38.0081 -88.0291 37.9751 -88.0211 37.9561 -88.0421 37.9341 -88.0411 37.9291 -88.0641 37.944 -88.0781 37.9231 -88.084 37.9171 -88.0301 37.9051 -88.0261 37.8961 -88.0441 37.9061 -88.1001 37.8951 -88.1011 37.8671 -88.0751 37.8431 -88.0341 37.8271 -88.0421 37.8311 -88.0891 37.8171 -88.0861 37.8051 -88.0351 37.7351 -88.0721 37.7001 -88.1331 37.6601 -88.1591 37.6281 -88.1571 37.5831 -88.1341 37.5101 -88.0711</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Illinois</topp:STATE_NAME><topp:STATE_FIPS>17</topp:STATE_FIPS><topp:SUB_REGION>E N Cen</topp:SUB_REGION><topp:STATE_ABBR>IL</topp:STATE_ABBR><topp:LAND_KM>143986.61</topp:LAND_KM><topp:WATER_KM>1993.335</topp:WATER_KM><topp:PERSONS>1.1431E7</topp:PERSONS><topp:FAMILIES>2924880.0</topp:FAMILIES><topp:HOUSHOLD>4202240.0</topp:HOUSHOLD><topp:MALE>5552233.0</topp:MALE><topp:FEMALE>5878369.0</topp:FEMALE><topp:WORKERS>4199206.0</topp:WORKERS><topp:DRVALONE>3741715.0</topp:DRVALONE><topp:CARPOOL>652603.0</topp:CARPOOL><topp:PUBTRANS>538071.0</topp:PUBTRANS><topp:EMPLOYED>5417967.0</topp:EMPLOYED><topp:UNEMPLOY>385040.0</topp:UNEMPLOY><topp:SERVICE>1360159.0</topp:SERVICE><topp:MANUAL>828906.0</topp:MANUAL><topp:P_MALE>0.486</topp:P_MALE><topp:P_FEMALE>0.514</topp:P_FEMALE><topp:SAMP_POP>1747776.0</topp:SAMP_POP></topp:states><topp:states fid=\"states.2\"><topp:the_geom><gml:MultiSurface srsName=\"urn:x-ogc:def:crs:EPSG:4326\"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.9661 -77.0081 38.8891 -76.9111 38.7881 -77.0451 38.8131 -77.0351 38.8291 -77.0451 38.8381 -77.0401 38.8621 -77.0391 38.8861 -77.0671 38.9151 -77.0781 38.9321 -77.1221 38.9931 -77.0421 38.9661 -77.0081</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>District of Columbia</topp:STATE_NAME><topp:STATE_FIPS>11</topp:STATE_FIPS><topp:SUB_REGION>S Atl</topp:SUB_REGION><topp:STATE_ABBR>DC</topp:STATE_ABBR><topp:LAND_KM>159.055</topp:LAND_KM><topp:WATER_KM>17.991</topp:WATER_KM><topp:PERSONS>606900.0</topp:PERSONS><topp:FAMILIES>122087.0</topp:FAMILIES><topp:HOUSHOLD>249634.0</topp:HOUSHOLD><topp:MALE>282970.0</topp:MALE><topp:FEMALE>323930.0</topp:FEMALE><topp:WORKERS>229975.0</topp:WORKERS><topp:DRVALONE>106694.0</topp:DRVALONE><topp:CARPOOL>36621.0</topp:CARPOOL><topp:PUBTRANS>111422.0</topp:PUBTRANS><topp:EMPLOYED>303994.0</topp:EMPLOYED><topp:UNEMPLOY>23442.0</topp:UNEMPLOY><topp:SERVICE>65498.0</topp:SERVICE><topp:MANUAL>22407.0</topp:MANUAL><topp:P_MALE>0.466</topp:P_MALE><topp:P_FEMALE>0.534</topp:P_FEMALE><topp:SAMP_POP>72696.0</topp:SAMP_POP></topp:states><topp:states fid=\"states.3\"><topp:the_geom><gml:MultiSurface srsName=\"urn:x-ogc:def:crs:EPSG:4326\"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.5571 -75.7071 38.6491 -75.7111 38.8301 -75.7241 39.1411 -75.7521 39.2471 -75.7611 39.2951 -75.7641 39.3831 -75.7721 39.7231 -75.7911 39.7241 -75.7751 39.7741 -75.7451 39.8201 -75.6951 39.8381 -75.6441 39.8401 -75.5831 39.8261 -75.4701 39.7981 -75.4201 39.7891 -75.4121 39.7781 -75.4281 39.7631 -75.4601 39.7411 -75.4751 39.7191 -75.4761 39.7141 -75.4891 39.6121 -75.6101 39.5661 -75.5621 39.4631 -75.5901 39.3661 -75.5151 39.2571 -75.4021 39.0731 -75.3971 39.0121 -75.3241 38.9451 -75.3071 38.8081 -75.1901 38.7991 -75.0831 38.4491 -75.0451 38.4491 -75.0681 38.4501 -75.0931 38.4551 -75.3501 38.4631 -75.6991 38.5571 -75.7071</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Delaware</topp:STATE_NAME><topp:STATE_FIPS>10</topp:STATE_FIPS><topp:SUB_REGION>S Atl</topp:SUB_REGION><topp:STATE_ABBR>DE</topp:STATE_ABBR><topp:LAND_KM>5062.456</topp:LAND_KM><topp:WATER_KM>1385.022</topp:WATER_KM><topp:PERSONS>666168.0</topp:PERSONS><topp:FAMILIES>175867.0</topp:FAMILIES><topp:HOUSHOLD>247497.0</topp:HOUSHOLD><topp:MALE>322968.0</topp:MALE><topp:FEMALE>343200.0</topp:FEMALE><topp:WORKERS>247566.0</topp:WORKERS><topp:DRVALONE>258087.0</topp:DRVALONE><topp:CARPOOL>42968.0</topp:CARPOOL><topp:PUBTRANS>8069.0</topp:PUBTRANS><topp:EMPLOYED>335147.0</topp:EMPLOYED><topp:UNEMPLOY>13945.0</topp:UNEMPLOY><topp:SERVICE>87973.0</topp:SERVICE><topp:MANUAL>44140.0</topp:MANUAL><topp:P_MALE>0.485</topp:P_MALE><topp:P_FEMALE>0.515</topp:P_FEMALE><topp:SAMP_POP>102776.0</topp:SAMP_POP></topp:states><topp:states fid=\"states.4\"><topp:the_geom><gml:MultiSurface srsName=\"urn:x-ogc:def:crs:EPSG:4326\"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.4801 -79.2311 38.4371 -79.2721 38.4121 -79.3171 38.4621 -79.4861 38.5531 -79.5361 38.5921 -79.6421 38.5501 -79.6691 38.5201 -79.6651 38.5001 -79.6921 38.4301 -79.6841 38.3941 -79.7201 38.3511 -79.7331 38.3531 -79.7641 38.3141 -79.8001 38.2981 -79.8031 38.2841 -79.7861 38.2681 -79.7931 38.2501 -79.8311 38.1791 -79.9161 38.1621 -79.9101 38.1211 -79.9351 38.1031 -79.9281 38.0671 -79.9571 38.0381 -79.9661 37.9891 -80.0001 37.9551 -80.0551 37.9141 -80.1061 37.8911 -80.1181 37.8771 -80.1601 37.8601 -80.1721 37.8421 -80.1711 37.8021 -80.2231 37.7781 -80.2201 37.7571 -80.2541 37.7251 -80.2501 37.6821 -80.3031 37.6711 -80.2951 37.6521 -80.3051 37.6401 -80.3011 37.6401 -80.2541 37.6241 -80.2191 37.5961 -80.2461 37.5661 -80.3161 37.5331 -80.3261 37.5281 -80.3081 37.5361 -80.2801 37.5111 -80.2881 37.4911 -80.3471 37.4751 -80.3521 37.4651 -80.3881 37.4341 -80.4251 37.4221 -80.4741 37.4331 -80.4871 37.4601 -80.4881 37.4741 -80.5081 37.4691 -80.5421 37.4451 -80.5971 37.3881 -80.7051 37.3921 -80.7291 37.3871 -80.7461 37.3781 -80.7471 37.3711 -80.7631 37.3861 -80.7701 37.3911 -80.7991 37.4121 -80.7991 37.4231 -80.8501 37.3881 -80.8771 37.3501 -80.8481 37.3391 -80.8551 37.3011 -80.9341 37.2911 -80.9681 37.2961 -80.9781 37.3061 -80.9861 37.2851 -81.0251 37.2741 -81.1401 37.2401 -81.2231 37.2931 -81.3121 37.3381 -81.3581 37.3111 -81.3911 37.2821 -81.4031 37.2541 -81.4751 37.2521 -81.4951 37.2341 -81.5051 37.2061 -81.5561 37.2041 -81.6661 37.2351 -81.7011 37.2501 -81.7381 37.2721 -81.7521 37.2871 -81.7921 37.2791 -81.8151 37.2851 -81.8391 37.3061 -81.8581 37.3251 -81.8631 37.3401 -81.8971 37.3711 -81.9261 37.4151 -81.9201 37.4661 -81.9881 37.4821 -81.9761 37.4921 -81.9481 37.5061 -81.9351 37.5311 -81.9591 37.5431 -81.9761 37.5301 -82.0261 37.5511 -82.0491 37.5251 -82.0551 37.5481 -82.0841 37.5571 -82.1421 37.5651 -82.1461 37.5691 -82.1371 37.5901 -82.1311 37.5931 -82.1591 37.6401 -82.1851 37.6231 -82.2051 37.6561 -82.2381 37.6681 -82.2951 37.7441 -82.3291 37.7581 -82.3191 37.7841 -82.3391 37.8111 -82.4051 37.8721 -82.4211 37.8941 -82.4371 37.9221 -82.5001 37.9421 -82.4931 37.9541 -82.4801 37.9751 -82.4751 38.0151 -82.5241 38.1091 -82.5931 38.1461 -82.6461 38.1691 -82.6471 38.1781 -82.6131 38.1931 -82.6061 38.2381 -82.6161 38.2451 -82.5891 38.2551 -82.5741 38.2921 -82.5801 38.3071 -82.5721 38.3681 -82.5981 38.4121 -82.5861 38.4031 -82.5751 38.4001 -82.5471 38.4051 -82.4951 38.4301 -82.4151 38.4281 -82.3941 38.4411 -82.3291 38.4651 -82.3141 38.5791 -82.2901 38.5941 -82.2711 38.5841 -82.2131 38.5941 -82.1841 38.6321 -82.1731 38.6771 -82.1891 38.7101 -82.1841 38.7781 -82.2161 38.8041 -82.1971 38.8381 -82.1461 38.8991 -82.1391 38.9521 -82.1011 38.9771 -82.0851 38.9881 -82.0581 39.0141 -82.0431 39.0151 -81.9991 38.9921 -81.9751 38.9911 -81.9371 38.9841 -81.9271 38.9321 -81.8981 38.8941 -81.9311 38.8841 -81.9151 38.8731 -81.8921 38.8851 -81.8661 38.9371 -81.8411 38.9481 -81.8231 38.9231 -81.7831 38.9301 -81.7621 38.9681 -81.7811 39.0161 -81.7751 39.0441 -81.8131 39.0661 -81.8241 39.0761 -81.8191 39.0771 -81.7861 39.0941 -81.7531 39.1251 -81.7441 39.1751 -81.7591 39.2131 -81.7231 39.2191 -81.6981 39.2601 -81.6891 39.2701 -81.6671 39.2651 -81.5721 39.3321 -81.5571 39.3521 -81.5401 39.4061 -81.4651 39.4101 -81.4481 39.4051 -81.4341 39.3451 -81.3761 39.3531 -81.3381 39.3861 -81.2841 39.3881 -81.2371 39.4081 -81.2251 39.4151 -81.2001 39.4371 -81.1801 39.4671 -81.1171 39.4961 -81.0981 39.5321 -81.0371 39.5441 -81.0321 39.5811 -80.9831 39.6061 -80.9321 39.6071 -80.9121 39.6241 -80.8811 39.6621 -80.8721 39.6801 -80.8631 39.7031 -80.8321 39.7181 -80.8321 39.7361 -80.8561 39.7591 -80.8701 39.8081 -80.8191 39.8391 -80.8261 39.8561 -80.7981 39.8721 -80.7911 39.9041 -80.8121 39.9151 -80.8081 39.9191 -80.7961 39.9131 -80.7681 39.9211 -80.7591 39.9461 -80.7631 39.9831 -80.7391 40.0351 -80.7381 40.1541 -80.7021 40.1681 -80.7011 40.1941 -80.6781 40.2451 -80.6501 40.2761 -80.6141 40.3061 -80.6041 40.3731 -80.6091 40.3881 -80.6291 40.3981 -80.6281 40.4801 -80.6021 40.5041 -80.6251 40.5391 -80.6331 40.5681 -80.6681 40.5821 -80.6671 40.6131 -80.6371 40.6191 -80.6111 40.6151 -80.5741 40.6371 -80.5221 40.4781 -80.5241 40.4021 -80.5231 40.1621 -80.5261 40.0221 -80.5251 39.9581 -80.5241 39.7211 -80.5241 39.7191 -80.4291 39.7211 -79.9181 39.7211 -79.7651 39.7201 -79.4811 39.1971 -79.4901 39.2131 -79.4611 39.2111 -79.4491 39.2691 -79.3851 39.2911 -79.3461 39.3001 -79.2951 39.3251 -79.2801 39.3481 -79.2601 39.3931 -79.1631 39.4131 -79.1581 39.4161 -79.1311 39.4471 -79.1041 39.4641 -79.0961 39.4701 -79.1041 39.4701 -79.0701 39.4851 -79.0641 39.4831 -79.0491 39.4381 -78.9701 39.4601 -78.9551 39.5251 -78.8711 39.5631 -78.8381 39.5661 -78.8061 39.5851 -78.8221 39.6151 -78.7981 39.6301 -78.7981 39.6441 -78.7721 39.6261 -78.7671 39.6261 -78.7321 39.6211 -78.7301 39.6081 -78.7361 39.6011 -78.7741 39.5811 -78.7611 39.5761 -78.7321 39.5591 -78.7161 39.5361 -78.6661 39.5371 -78.6491 39.5291 -78.6371 39.5351 -78.6041 39.5201 -78.5641 39.5251 -78.5091 39.5191 -78.4811 39.5331 -78.4561 39.5481 -78.4461 39.5491 -78.4211 39.5801 -78.4621 39.5921 -78.4501 39.5871 -78.4041 39.6201 -78.4321 39.6141 -78.3841 39.6311 -78.3771 39.6321 -78.3571 39.6401 -78.3481 39.6181 -78.2731 39.6411 -78.2571 39.6581 -78.2291 39.6731 -78.2271 39.6751 -78.2041 39.6941 -78.1831 39.6751 -78.0941 39.6221 -78.0261 39.5981 -77.9951 39.6111 -77.9641 39.5851 -77.9451 39.5911 -77.9351 39.6141 -77.9471 39.6181 -77.9381 39.5961 -77.9031 39.6001 -77.8911 39.6161 -77.8881 39.6021 -77.8551 39.6051 -77.8421 39.5721 -77.8401 39.5651 -77.8531 39.5641 -77.8851 39.5571 -77.8901 39.5451 -77.8691 39.5141 -77.8641 39.5311 -77.8441 39.5251 -77.8351 39.5291 -77.8291 39.5111 -77.8251 39.5011 -77.8481 39.4931 -77.8251 39.4981 -77.7711 39.4801 -77.7991 39.4591 -77.7851 39.4631 -77.8041 39.4501 -77.7961 39.4391 -77.8041 39.4321 -77.8021 39.4251 -77.7571 39.4031 -77.7411 39.3961 -77.7371 39.3781 -77.7561 39.3601 -77.7451 39.3381 -77.7541 39.3261 -77.7501 39.3171 -77.7271 39.2841 -77.7591 39.2461 -77.7681 39.1961 -77.8051 39.1411 -77.8201 39.1321 -77.8301 39.2651 -78.0331 39.3911 -78.2291 39.4231 -78.2771 39.4561 -78.3471 39.3801 -78.3501 39.3611 -78.3651 39.3501 -78.3441 39.3411 -78.3411 39.2571 -78.4131 39.2441 -78.3991 39.2121 -78.4231 39.1971 -78.4241 39.1701 -78.4021 39.1481 -78.4301 39.1181 -78.4481 39.1111 -78.4851 39.0931 -78.5011 39.0571 -78.5361 39.0351 -78.5641 39.0231 -78.5491 39.0131 -78.5531 38.9671 -78.5981 38.9791 -78.6311 38.9501 -78.6471 38.9211 -78.6801 38.9041 -78.7191 38.9301 -78.7241 38.9291 -78.7371 38.9111 -78.7491 38.8801 -78.7931 38.8331 -78.8161 38.7631 -78.8661 38.8461 -78.9871 38.7991 -79.0331 38.7901 -79.0551 38.7611 -79.0561 38.7071 -79.0871 38.6591 -79.0881 38.6631 -79.1211 38.6581 -79.1271 38.4801 -79.2311</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>West Virginia</topp:STATE_NAME><topp:STATE_FIPS>54</topp:STATE_FIPS><topp:SUB_REGION>S Atl</topp:SUB_REGION><topp:STATE_ABBR>WV</topp:STATE_ABBR><topp:LAND_KM>62384.2</topp:LAND_KM><topp:WATER_KM>375.199</topp:WATER_KM><topp:PERSONS>1793477.0</topp:PERSONS><topp:FAMILIES>500259.0</topp:FAMILIES><topp:HOUSHOLD>688557.0</topp:HOUSHOLD><topp:MALE>861536.0</topp:MALE><topp:FEMALE>931941.0</topp:FEMALE><topp:WORKERS>661702.0</topp:WORKERS><topp:DRVALONE>493164.0</topp:DRVALONE><topp:CARPOOL>106918.0</topp:CARPOOL><topp:PUBTRANS>7237.0</topp:PUBTRANS><topp:EMPLOYED>671085.0</topp:EMPLOYED><topp:UNEMPLOY>71142.0</topp:UNEMPLOY><topp:SERVICE>205950.0</topp:SERVICE><topp:MANUAL>124172.0</topp:MANUAL><topp:P_MALE>0.48</topp:P_MALE><topp:P_FEMALE>0.52</topp:P_FEMALE><topp:SAMP_POP>317564.0</topp:SAMP_POP></topp:states><topp:states fid=\"states.5\"><topp:the_geom><gml:MultiSurface srsName=\"urn:x-ogc:def:crs:EPSG:4326\"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.6491 -75.7111 38.5571 -75.7071 38.4631 -75.6991 38.4551 -75.3501 38.4501 -75.0931 38.3691 -75.1551 38.2731 -75.1501 38.2011 -75.2621 38.0681 -75.3731 38.0161 -75.3721 37.9961 -75.6261 37.9701 -75.6481 37.9791 -75.8651 38.0971 -75.7691 38.1741 -75.8971 38.2311 -75.8381 38.2401 -75.8611 38.2631 -75.7941 38.2581 -75.8941 38.3571 -75.8721 38.3751 -75.8861 38.2821 -75.9491 38.2821 -75.9951 38.3211 -76.0201 38.2581 -76.0651 38.4361 -76.2941 38.4781 -76.2911 38.5431 -76.1921 38.5951 -76.2511 38.5711 -76.0311 38.6221 -76.0281 38.5911 -76.0461 38.6101 -76.0751 38.7071 -76.1241 38.7091 -76.1741 38.7621 -76.2231 38.7691 -76.2671 38.6791 -76.3371 38.6991 -76.3501 38.834 -76.2721 38.7651 -76.1951 38.7881 -76.1651 38.8851 -76.1141 38.8891 -76.0751 38.8981 -76.1021 38.9481 -76.0951 38.9201 -76.1131 38.9731 -76.1991 39.1181 -76.1111 39.0921 -76.2211 39.1301 -76.2381 39.2041 -76.2181 39.3211 -76.1121 39.3581 -76.0371 39.3791 -75.8491 39.3941 -75.9781 39.4711 -75.9521 39.5241 -75.9741 39.5691 -76.0311 39.5421 -76.0781 39.4011 -76.1541 39.3741 -76.2261 39.3931 -76.3641 39.2311 -76.3991 39.2421 -76.5311 39.2591 -76.6041 39.2311 -76.5651 39.1981 -76.5761 39.1801 -76.6071 39.1581 -76.5951 39.1961 -76.5631 39.1181 -76.4231 38.9081 -76.4721 38.7581 -76.5491 38.7091 -76.5251 38.5221 -76.5081 38.3911 -76.3851 38.3461 -76.4051 38.3201 -76.4211 38.3351 -76.4711 38.4101 -76.5201 38.4501 -76.6471 38.2131 -76.3431 38.0451 -76.3301 38.2221 -76.5771 38.2341 -76.7601 38.3911 -76.8641 38.2991 -76.9081 38.3311 -76.9731 38.4261 -77.0021 38.3901 -77.2201 38.4131 -77.2551 38.4871 -77.2771 38.6481 -77.1291 38.6771 -77.1251 38.7031 -77.0931 38.7151 -77.0811 38.7121 -77.0571 38.7181 -77.0461 38.7881 -77.0451 38.8891 -76.9111 38.9661 -77.0081 38.9931 -77.0421 38.9321 -77.1221 38.9641 -77.1521 38.9751 -77.2431 39.0271 -77.2551 39.0621 -77.3241 39.0681 -77.3461 39.0661 -77.4331 39.0801 -77.4591 39.1031 -77.4791 39.1161 -77.5131 39.1571 -77.5161 39.1761 -77.4781 39.2181 -77.4611 39.2291 -77.4641 39.2491 -77.4941 39.2681 -77.5421 39.2981 -77.5681 39.2991 -77.6161 39.3181 -77.6791 39.3171 -77.7271 39.3261 -77.7501 39.3381 -77.7541 39.3601 -77.7451 39.3781 -77.7561 39.3961 -77.7371 39.4031 -77.7411 39.4251 -77.7571 39.4321 -77.8021 39.4391 -77.8041 39.4501 -77.7961 39.4631 -77.8041 39.4591 -77.7851 39.4801 -77.7991 39.4981 -77.7711 39.4931 -77.8251 39.5011 -77.8481 39.5111 -77.8251 39.5291 -77.8291 39.5251 -77.8351 39.5311 -77.8441 39.5141 -77.8641 39.5451 -77.8691 39.5571 -77.8901 39.5641 -77.8851 39.5651 -77.8531 39.5721 -77.8401 39.6051 -77.8421 39.6021 -77.8551 39.6161 -77.8881 39.6001 -77.8911 39.5961 -77.9031 39.6181 -77.9381 39.6141 -77.9471 39.5911 -77.9351 39.5851 -77.9451 39.6111 -77.9641 39.5981 -77.9951 39.6221 -78.0261 39.6751 -78.0941 39.6941 -78.1831 39.6751 -78.2041 39.6731 -78.2271 39.6581 -78.2291 39.6411 -78.2571 39.6181 -78.2731 39.6401 -78.3481 39.6321 -78.3571 39.6311 -78.3771 39.6141 -78.3841 39.6201 -78.4321 39.5871 -78.4041 39.5921 -78.4501 39.5801 -78.4621 39.5491 -78.4211 39.5481 -78.4461 39.5331 -78.4561 39.5191 -78.4811 39.5251 -78.5091 39.5201 -78.5641 39.5351 -78.6041 39.5291 -78.6371 39.5371 -78.6491 39.5361 -78.6661 39.5591 -78.7161 39.5761 -78.7321 39.5811 -78.7611 39.6011 -78.7741 39.6081 -78.7361 39.6211 -78.7301 39.6261 -78.7321 39.6261 -78.7671 39.6441 -78.7721 39.6301 -78.7981 39.6151 -78.7981 39.5851 -78.8221 39.5661 -78.8061 39.5631 -78.8381 39.5251 -78.8711 39.4601 -78.9551 39.4381 -78.9701 39.4831 -79.0491 39.4851 -79.0641 39.4701 -79.0701 39.4701 -79.1041 39.4641 -79.0961 39.4471 -79.1041 39.4161 -79.1311 39.4131 -79.1581 39.3931 -79.1631 39.3481 -79.2601 39.3251 -79.2801 39.3001 -79.2951 39.2911 -79.3461 39.2691 -79.3851 39.2111 -79.4491 39.2131 -79.4611 39.1971 -79.4901 39.7201 -79.4811 39.7191 -79.3961 39.7221 -78.9301 39.7231 -78.8181 39.7231 -78.3851 39.7241 -78.3341 39.7251 -78.0961 39.7191 -77.4761 39.7191 -77.4641 39.7201 -77.2211 39.7201 -76.9971 39.7211 -76.7901 39.7201 -76.5701 39.7211 -76.2331 39.7221 -76.1391 39.7231 -75.7911 39.3831 -75.7721 39.2951 -75.7641 39.2471 -75.7611 39.1411 -75.7521 38.8301 -75.7241 38.6491 -75.7111</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.9071 -76.2931 38.9671 -76.2941 38.9561 -76.3391 38.9411 -76.3141 38.9121 -76.3221 38.9241 -76.3421 38.8751 -76.3291 38.8541 -76.3751 38.9581 -76.3561 39.0401 -76.2991 38.9781 -76.2481 38.9231 -76.2461 38.9491 -76.2731 38.9071 -76.2931</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.4491 -75.0681 38.4491 -75.0451 38.3221 -75.0871 38.4491 -75.0681</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.0271 -75.2701 38.0371 -75.2441 38.0941 -75.2091 38.2041 -75.1641 38.3201 -75.0941 38.1241 -75.1731 38.0281 -75.2421 38.0271 -75.2701</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Maryland</topp:STATE_NAME><topp:STATE_FIPS>24</topp:STATE_FIPS><topp:SUB_REGION>S Atl</topp:SUB_REGION><topp:STATE_ABBR>MD</topp:STATE_ABBR><topp:LAND_KM>25316.345</topp:LAND_KM><topp:WATER_KM>6188.794</topp:WATER_KM><topp:PERSONS>4781468.0</topp:PERSONS><topp:FAMILIES>1245814.0</topp:FAMILIES><topp:HOUSHOLD>1748991.0</topp:HOUSHOLD><topp:MALE>2318671.0</topp:MALE><topp:FEMALE>2462797.0</topp:FEMALE><topp:WORKERS>1783061.0</topp:WORKERS><topp:DRVALONE>1732837.0</topp:DRVALONE><topp:CARPOOL>376449.0</topp:CARPOOL><topp:PUBTRANS>202169.0</topp:PUBTRANS><topp:EMPLOYED>2481342.0</topp:EMPLOYED><topp:UNEMPLOY>111536.0</topp:UNEMPLOY><topp:SERVICE>586994.0</topp:SERVICE><topp:MANUAL>260308.0</topp:MANUAL><topp:P_MALE>0.485</topp:P_MALE><topp:P_FEMALE>0.515</topp:P_FEMALE><topp:SAMP_POP>684773.0</topp:SAMP_POP></topp:states><topp:states fid=\"states.6\"><topp:the_geom><gml:MultiSurface srsName=\"urn:x-ogc:def:crs:EPSG:4326\"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>37.6411 -102.0431 37.3861 -102.0411 36.9881 -102.0361 36.9981 -102.9971 36.9991 -103.0771 36.9941 -103.9931 36.9931 -105.1451 36.9921 -105.2121 36.9941 -105.7121 36.9921 -105.9911 36.9911 -106.4711 36.9891 -106.8601 36.9991 -106.8891 36.9971 -107.4101 36.9981 -107.4711 36.9991 -108.3711 36.9961 -109.0471 37.6301 -109.0441 37.8871 -109.0421 38.1521 -109.0421 38.2441 -109.0551 38.4941 -109.0531 39.3601 -109.0501 39.5181 -109.0521 39.6571 -109.0511 40.2101 -109.0501 40.6651 -109.0451 40.9981 -109.0471 41.0031 -107.9181 41.0001 -107.3031 40.9981 -106.8641 41.0011 -106.3281 41.0001 -106.2021 40.9961 -105.2781 40.9941 -104.9331 41.0031 -104.0511 40.9991 -103.5711 41.0001 -103.3821 40.9981 -102.6511 41.0001 -102.6201 40.9981 -102.0471 40.7431 -102.0461 40.6971 -102.0451 40.4311 -102.0471 40.3421 -102.0471 39.9981 -102.0511 39.5681 -102.0481 39.5621 -102.0481 39.1261 -102.0471 39.0361 -102.0481 38.6921 -102.0471 38.6151 -102.0471 38.2631 -102.0451 38.2531 -102.0451 37.7341 -102.0431 37.6411 -102.0431</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Colorado</topp:STATE_NAME><topp:STATE_FIPS>08</topp:STATE_FIPS><topp:SUB_REGION>Mtn</topp:SUB_REGION><topp:STATE_ABBR>CO</topp:STATE_ABBR><topp:LAND_KM>268659.501</topp:LAND_KM><topp:WATER_KM>960.364</topp:WATER_KM><topp:PERSONS>3294394.0</topp:PERSONS><topp:FAMILIES>854214.0</topp:FAMILIES><topp:HOUSHOLD>1282489.0</topp:HOUSHOLD><topp:MALE>1631295.0</topp:MALE><topp:FEMALE>1663099.0</topp:FEMALE><topp:WORKERS>1233023.0</topp:WORKERS><topp:DRVALONE>1216639.0</topp:DRVALONE><topp:CARPOOL>210274.0</topp:CARPOOL><topp:PUBTRANS>46983.0</topp:PUBTRANS><topp:EMPLOYED>1633281.0</topp:EMPLOYED><topp:UNEMPLOY>99438.0</topp:UNEMPLOY><topp:SERVICE>421079.0</topp:SERVICE><topp:MANUAL>181760.0</topp:MANUAL><topp:P_MALE>0.495</topp:P_MALE><topp:P_FEMALE>0.505</topp:P_FEMALE><topp:SAMP_POP>512677.0</topp:SAMP_POP></topp:states><topp:states fid=\"states.7\"><topp:the_geom><gml:MultiSurface srsName=\"urn:x-ogc:def:crs:EPSG:4326\"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>36.6551 -86.5101 36.6521 -86.7701 36.6501 -87.0681 36.6511 -87.1121 36.6491 -87.3461 36.6451 -87.6401 36.6441 -87.6931 36.6411 -87.8531 36.6691 -87.8701 36.6791 -88.0711 36.5821 -88.0411 36.5381 -88.0351 36.4961 -88.0421 36.4981 -88.4951 36.4991 -88.5121 36.4981 -88.8101 36.4991 -88.8261 36.4991 -88.8301 36.5021 -89.3461 36.5021 -89.4141 36.5101 -89.4181 36.6161 -89.3731 36.6251 -89.3631 36.6281 -89.3421 36.6221 -89.3221 36.5751 -89.2831 36.5691 -89.2411 36.5811 -89.2101 36.6311 -89.2001 36.6531 -89.1771 36.6711 -89.1671 36.7131 -89.1971 36.7271 -89.1961 36.7601 -89.1771 36.7591 -89.1511 36.7681 -89.1251 36.7921 -89.1251 36.8041 -89.1641 36.8291 -89.1731 36.8431 -89.1661 36.8661 -89.1291 36.9531 -89.1041 36.9771 -89.1071 36.9881 -89.1291 36.9981 -89.1501 37.0251 -89.1741 37.0641 -89.1691 37.0931 -89.1461 37.1121 -89.1161 37.1851 -89.0651 37.2201 -88.9931 37.2181 -88.9321 37.2021 -88.8631 37.1521 -88.7461 37.1411 -88.7391 37.1351 -88.6881 37.1091 -88.6141 37.0721 -88.5591 37.0641 -88.5171 37.0681 -88.4901 37.0721 -88.4761 37.0981 -88.4501 37.1561 -88.4221 37.2051 -88.4501 37.2571 -88.5011 37.2961 -88.5111 37.4001 -88.4671 37.4201 -88.4191 37.4091 -88.3591 37.4421 -88.3111 37.4761 -88.0871 37.5101 -88.0711 37.5831 -88.1341 37.6281 -88.1571 37.6601 -88.1591 37.7001 -88.1331 37.7351 -88.0721 37.8051 -88.0351 37.8011 -88.0111 37.7761 -87.9581 37.7991 -87.9391 37.8091 -87.9201 37.8381 -87.9101 37.8751 -87.9361 37.9041 -87.9341 37.9191 -87.9211 37.9241 -87.8991 37.8901 -87.8571 37.8781 -87.8231 37.8981 -87.7531 37.8941 -87.7281 37.8991 -87.7091 37.8971 -87.6791 37.8361 -87.6841 37.8281 -87.6511 37.8431 -87.6071 37.8641 -87.5931 37.8901 -87.5941 37.9231 -87.6271 37.9711 -87.6041 37.9151 -87.5041 37.9361 -87.4521 37.9341 -87.3871 37.8931 -87.3101 37.8701 -87.2721 37.8491 -87.2261 37.8381 -87.1751 37.8261 -87.1581 37.7891 -87.1311 37.7841 -87.1061 37.8071 -87.0711 37.9071 -87.0361 37.9241 -87.0131 37.9301 -86.9891 37.9371 -86.9311 37.9531 -86.9001 37.9861 -86.8631 37.9911 -86.8261 37.9781 -86.8021 37.8981 -86.7531 37.8941 -86.7281 37.9111 -86.6891 37.9131 -86.6681 37.9021 -86.6601 37.8601 -86.6701 37.8471 -86.6651 37.8451 -86.6451 37.8571 -86.6141 37.9211 -86.5981 37.9251 -86.5811 37.9211 -86.5411 37.9271 -86.5221 37.9421 -86.5161 37.9871 -86.5301 38.0181 -86.5271 38.0461 -86.5191 38.0511 -86.5031 38.0591 -86.4581 38.0751 -86.4421 38.0881 -86.4421 38.1111 -86.4741 38.1291 -86.4641 38.1291 -86.4521 38.1081 -86.4071 38.1231 -86.3931 38.1341 -86.3441 38.1431 -86.3351 38.1551 -86.3431 38.1671 -86.3871 38.1941 -86.3881 38.1931 -86.3641 38.1771 -86.3411 38.1501 -86.2971 38.0781 -86.2911 38.0581 -86.2771 38.0401 -86.2521 38.0171 -86.1901 38.0111 -86.1051 37.9661 -86.0521 37.9921 -86.0311 38.0011 -86.0061 38.0111 -85.9581 38.0331 -85.9301 38.0641 -85.9141 38.1791 -85.9121 38.2381 -85.8521 38.2761 -85.8391 38.2861 -85.8061 38.2821 -85.7861 38.2701 -85.7461 38.3001 -85.6811 38.3371 -85.6541 38.3831 -85.6431 38.4461 -85.6121 38.4711 -85.5071 38.5181 -85.4661 38.5361 -85.4321 38.5611 -85.4171 38.5841 -85.4241 38.6941 -85.4531 38.7241 -85.4461 38.7381 -85.4181 38.7361 -85.3351 38.7441 -85.2711 38.6951 -85.2051 38.6951 -85.1601 38.7141 -85.1191 38.7501 -85.0681 38.7641 -85.0251 38.7801 -84.9751 38.7931 -84.8181 38.8341 -84.8241 38.8661 -84.7871 38.8841 -84.7881 38.8971 -84.8031 38.9011 -84.8591 38.9091 -84.8751 38.9271 -84.8751 38.9541 -84.8461 38.9821 -84.8341 39.0051 -84.8441 39.0321 -84.8761 39.0501 -84.8901 39.0641 -84.8861 39.1031 -84.8271 39.1021 -84.8111 39.1061 -84.7891 39.1421 -84.7421 39.0891 -84.6671 39.0741 -84.6221 39.0701 -84.5931 39.0941 -84.5151 39.1071 -84.4921 39.1111 -84.4441 39.0841 -84.4251 39.0471 -84.4191 39.0351 -84.3911 39.0371 -84.3451 39.0141 -84.3131 38.9441 -84.2901 38.9171 -84.2611 38.8741 -84.2351 38.8121 -84.2281 38.7881 -84.1761 38.7651 -84.0881 38.7631 -84.0531 38.7771 -83.9621 38.7571 -83.9121 38.7441 -83.8571 38.7111 -83.8371 38.6931 -83.7901 38.6501 -83.7701 38.6351 -83.7121 38.6201 -83.6781 38.6231 -83.6551 38.6351 -83.6431 38.6641 -83.6331 38.6771 -83.6181 38.6961 -83.5261 38.6901 -83.5001 38.6631 -83.4531 38.6541 -83.3711 38.6311 -83.3301 38.6061 -83.3201 38.5961 -83.3061 38.5961 -83.2901 38.6091 -83.2721 38.6241 -83.2451 38.6091 -83.1821 38.6191 -83.1431 38.6641 -83.1111 38.6851 -83.0601 38.7141 -83.0271 38.7191 -82.9721 38.7461 -82.9211 38.7421 -82.8901 38.7181 -82.8731 38.6831 -82.8801 38.6521 -82.8601 38.6001 -82.8531 38.5711 -82.8271 38.5571 -82.8021 38.5521 -82.7421 38.5391 -82.6951 38.5021 -82.6691 38.4721 -82.6131 38.4121 -82.5861 38.3681 -82.5981 38.3071 -82.5721 38.2921 -82.5801 38.2551 -82.5741 38.2451 -82.5891 38.2381 -82.6161 38.1931 -82.6061 38.1781 -82.6131 38.1691 -82.6471 38.1461 -82.6461 38.1091 -82.5931 38.0151 -82.5241 37.9751 -82.4751 37.9541 -82.4801 37.9421 -82.4931 37.9221 -82.5001 37.8941 -82.4371 37.8721 -82.4211 37.8111 -82.4051 37.7841 -82.3391 37.7581 -82.3191 37.7441 -82.3291 37.6681 -82.2951 37.6561 -82.2381 37.6231 -82.2051 37.6401 -82.1851 37.5931 -82.1591 37.5901 -82.1311 37.5691 -82.1371 37.5651 -82.1461 37.5571 -82.1421 37.5481 -82.0841 37.5251 -82.0551 37.5511 -82.0491 37.5301 -82.0261 37.5431 -81.9761 37.5311 -81.9591 37.3041 -82.2891 37.2601 -82.3531 37.2501 -82.4061 37.1991 -82.5501 37.1931 -82.5681 37.1091 -82.7191 37.0931 -82.7211 37.0751 -82.7091 37.0651 -82.7201 37.0331 -82.7231 37.0051 -82.8121 36.9741 -82.8661 36.9321 -82.8601 36.8931 -82.8781 36.8631 -82.9501 36.8581 -83.0461 36.8501 -83.0681 36.7791 -83.1281 36.7511 -83.1241 36.7391 -83.1381 36.7341 -83.2031 36.7091 -83.3211 36.6881 -83.3851 36.6721 -83.4041 36.6611 -83.4601 36.6611 -83.5301 36.6161 -83.6461 36.5981 -83.6751 36.5841 -83.6951 36.5911 -83.9351 36.5921 -84.0061 36.5951 -84.2541 36.5951 -84.2561 36.6051 -84.7811 36.6051 -84.7911 36.6201 -84.9981 36.6251 -85.2721 36.6261 -85.3001 36.6181 -85.4371 36.6261 -85.7851 36.6331 -85.9801 36.6431 -86.1991 36.6501 -86.4151 36.6551 -86.5101</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>36.4981 -89.5331 36.5181 -89.5661 36.5411 -89.5681 36.5571 -89.5561 36.5641 -89.5301 36.5591 -89.4931 36.5471 -89.4811 36.5251 -89.4711 36.5041 -89.4811 36.4981 -89.4751 36.4981 -89.5331</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Kentucky</topp:STATE_NAME><topp:STATE_FIPS>21</topp:STATE_FIPS><topp:SUB_REGION>E S Cen</topp:SUB_REGION><topp:STATE_ABBR>KY</topp:STATE_ABBR><topp:LAND_KM>103961.904</topp:LAND_KM><topp:WATER_KM>1772.542</topp:WATER_KM><topp:PERSONS>4551524.0</topp:PERSONS><topp:FAMILIES>1237346.0</topp:FAMILIES><topp:HOUSHOLD>1718663.0</topp:HOUSHOLD><topp:MALE>2195130.0</topp:MALE><topp:FEMALE>2356394.0</topp:FEMALE><topp:WORKERS>1656590.0</topp:WORKERS><topp:DRVALONE>1502949.0</topp:DRVALONE><topp:CARPOOL>273091.0</topp:CARPOOL><topp:PUBTRANS>48158.0</topp:PUBTRANS><topp:EMPLOYED>1970934.0</topp:EMPLOYED><topp:UNEMPLOY>148125.0</topp:UNEMPLOY><topp:SERVICE>556744.0</topp:SERVICE><topp:MANUAL>361621.0</topp:MANUAL><topp:P_MALE>0.482</topp:P_MALE><topp:P_FEMALE>0.518</topp:P_FEMALE><topp:SAMP_POP>646517.0</topp:SAMP_POP></topp:states><topp:states fid=\"states.8\"><topp:the_geom><gml:MultiSurface srsName=\"urn:x-ogc:def:crs:EPSG:4326\"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>37.0011 -95.0711 37.0001 -95.4061 37.0001 -95.5251 36.9981 -95.7851 37.0001 -95.9571 36.9981 -96.0051 37.0001 -96.5181 37.0001 -96.7481 36.9991 -97.1371 36.9961 -97.4651 36.9981 -97.8031 36.9981 -98.1041 36.9991 -98.3461 36.9981 -98.5391 36.9981 -98.9991 36.9941 -99.4371 36.9951 -99.5441 36.9951 -99.9981 36.9971 -100.0881 36.9971 -100.6331 36.9961 -100.9501 36.9971 -101.0711 36.9961 -101.5531 36.9881 -102.0241 36.9881 -102.0361 37.3861 -102.0411 37.6411 -102.0431 37.7341 -102.0431 38.2531 -102.0451 38.2631 -102.0451 38.6151 -102.0471 38.6921 -102.0471 39.0361 -102.0481 39.1261 -102.0471 39.5621 -102.0481 39.5681 -102.0481 39.9981 -102.0511 40.0011 -101.4061 40.0011 -101.3211 40.0001 -100.7541 39.9991 -100.7341 40.0001 -100.1901 40.0001 -100.1801 40.0021 -99.6271 39.9991 -99.1771 39.9981 -99.0641 39.9981 -98.7201 39.9971 -98.5041 39.9981 -98.2631 39.9981 -97.9291 39.9991 -97.8161 39.9971 -97.3611 39.9961 -96.9071 39.9941 -96.8011 39.9941 -96.4531 39.9941 -96.2401 39.9951 -96.0001 39.9931 -95.7801 39.9921 -95.3291 39.9991 -95.3081 39.9421 -95.2401 39.9381 -95.2071 39.9101 -95.1931 39.9081 -95.1501 39.8691 -95.1001 39.8661 -95.0621 39.8771 -95.0331 39.8961 -95.0211 39.9001 -94.9641 39.8961 -94.9371 39.8491 -94.9361 39.8331 -94.9231 39.8281 -94.8981 39.8171 -94.8881 39.7931 -94.8991 39.7821 -94.9331 39.7751 -94.9341 39.7571 -94.9211 39.7601 -94.8761 39.7541 -94.8701 39.7391 -94.8771 39.7261 -94.9051 39.7271 -94.9301 39.7361 -94.9521 39.7321 -94.9611 39.6841 -94.9781 39.6611 -95.0281 39.6251 -95.0551 39.5861 -95.0531 39.5601 -95.1081 39.5321 -95.1011 39.4851 -95.0471 39.4621 -95.0401 39.4391 -94.9851 39.4111 -94.9581 39.3811 -94.9251 39.3801 -94.8981 39.3401 -94.9111 39.3231 -94.9071 39.2861 -94.8801 39.2611 -94.8331 39.2111 -94.8201 39.1961 -94.7891 39.1711 -94.7301 39.1741 -94.6751 39.1581 -94.6461 39.1511 -94.6121 39.1411 -94.6001 39.1121 -94.6071 39.0441 -94.6091 38.8371 -94.6121 38.7371 -94.6121 38.4711 -94.6181 38.3921 -94.6181 38.0551 -94.6171 38.0301 -94.6161 37.6791 -94.6191 37.6501 -94.6181 37.3601 -94.6181 37.3271 -94.6181 37.0601 -94.6201 36.9961 -94.6201 37.0001 -95.0321 37.0011 -95.0711</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Kansas</topp:STATE_NAME><topp:STATE_FIPS>20</topp:STATE_FIPS><topp:SUB_REGION>W N Cen</topp:SUB_REGION><topp:STATE_ABBR>KS</topp:STATE_ABBR><topp:LAND_KM>211921.641</topp:LAND_KM><topp:WATER_KM>1188.865</topp:WATER_KM><topp:PERSONS>2477574.0</topp:PERSONS><topp:FAMILIES>658600.0</topp:FAMILIES><topp:HOUSHOLD>944726.0</topp:HOUSHOLD><topp:MALE>1214645.0</topp:MALE><topp:FEMALE>1262929.0</topp:FEMALE><topp:WORKERS>907383.0</topp:WORKERS><topp:DRVALONE>928575.0</topp:DRVALONE><topp:CARPOOL>135598.0</topp:CARPOOL><topp:PUBTRANS>7585.0</topp:PUBTRANS><topp:EMPLOYED>1172214.0</topp:EMPLOYED><topp:UNEMPLOY>57772.0</topp:UNEMPLOY><topp:SERVICE>346339.0</topp:SERVICE><topp:MANUAL>166429.0</topp:MANUAL><topp:P_MALE>0.49</topp:P_MALE><topp:P_FEMALE>0.51</topp:P_FEMALE><topp:SAMP_POP>453411.0</topp:SAMP_POP></topp:states><topp:states fid=\"states.9\"><topp:the_geom><gml:MultiSurface srsName=\"urn:x-ogc:def:crs:EPSG:4326\"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>36.5461 -79.1441 36.5491 -79.2171 36.5471 -79.5101 36.5471 -79.7171 36.5451 -80.0241 36.5471 -80.0481 36.5511 -80.4351 36.5571 -80.6111 36.5631 -80.8381 36.5651 -80.9031 36.5721 -81.3451 36.5891 -81.6691 36.6071 -81.6521 36.6111 -81.8291 36.6131 -81.9181 36.5951 -81.9291 36.5951 -82.1541 36.5931 -82.2161 36.5911 -82.2961 36.5911 -82.6101 36.5901 -82.8491 36.5911 -82.9861 36.5881 -83.2111 36.5891 -83.2481 36.6001 -83.2751 36.5981 -83.4641 36.5981 -83.6751 36.6161 -83.6461 36.6611 -83.5301 36.6611 -83.4601 36.6721 -83.4041 36.6881 -83.3851 36.7091 -83.3211 36.7341 -83.2031 36.7391 -83.1381 36.7511 -83.1241 36.7791 -83.1281 36.8501 -83.0681 36.8581 -83.0461 36.8631 -82.9501 36.8931 -82.8781 36.9321 -82.8601 36.9741 -82.8661 37.0051 -82.8121 37.0331 -82.7231 37.0651 -82.7201 37.0751 -82.7091 37.0931 -82.7211 37.1091 -82.7191 37.1931 -82.5681 37.1991 -82.5501 37.2501 -82.4061 37.2601 -82.3531 37.3041 -82.2891 37.5311 -81.9591 37.5061 -81.9351 37.4921 -81.9481 37.4821 -81.9761 37.4661 -81.9881 37.4151 -81.9201 37.3711 -81.9261 37.3401 -81.8971 37.3251 -81.8631 37.3061 -81.8581 37.2851 -81.8391 37.2791 -81.8151 37.2871 -81.7921 37.2721 -81.7521 37.2501 -81.7381 37.2351 -81.7011 37.2041 -81.6661 37.2061 -81.5561 37.2341 -81.5051 37.2521 -81.4951 37.2541 -81.4751 37.2821 -81.4031 37.3111 -81.3911 37.3381 -81.3581 37.2931 -81.3121 37.2401 -81.2231 37.2741 -81.1401 37.2851 -81.0251 37.3061 -80.9861 37.2961 -80.9781 37.2911 -80.9681 37.3011 -80.9341 37.3391 -80.8551 37.3501 -80.8481 37.3881 -80.8771 37.4231 -80.8501 37.4121 -80.7991 37.3911 -80.7991 37.3861 -80.7701 37.3711 -80.7631 37.3781 -80.7471 37.3871 -80.7461 37.3921 -80.7291 37.3881 -80.7051 37.4451 -80.5971 37.4691 -80.5421 37.4741 -80.5081 37.4601 -80.4881 37.4331 -80.4871 37.4221 -80.4741 37.4341 -80.4251 37.4651 -80.3881 37.4751 -80.3521 37.4911 -80.3471 37.5111 -80.2881 37.5361 -80.2801 37.5281 -80.3081 37.5331 -80.3261 37.5661 -80.3161 37.5961 -80.2461 37.6241 -80.2191 37.6401 -80.2541 37.6401 -80.3011 37.6521 -80.3051 37.6711 -80.2951 37.6821 -80.3031 37.7251 -80.2501 37.7571 -80.2541 37.7781 -80.2201 37.8021 -80.2231 37.8421 -80.1711 37.8601 -80.1721 37.8771 -80.1601 37.8911 -80.1181 37.9141 -80.1061 37.9551 -80.0551 37.9891 -80.0001 38.0381 -79.9661 38.0671 -79.9571 38.1031 -79.9281 38.1211 -79.9351 38.1621 -79.9101 38.1791 -79.9161 38.2501 -79.8311 38.2681 -79.7931 38.2841 -79.7861 38.2981 -79.8031 38.3141 -79.8001 38.3531 -79.7641 38.3511 -79.7331 38.3941 -79.7201 38.4301 -79.6841 38.5001 -79.6921 38.5201 -79.6651 38.5501 -79.6691 38.5921 -79.6421 38.5531 -79.5361 38.4621 -79.4861 38.4121 -79.3171 38.4371 -79.2721 38.4801 -79.2311 38.6581 -79.1271 38.6631 -79.1211 38.6591 -79.0881 38.7071 -79.0871 38.7611 -79.0561 38.7901 -79.0551 38.7991 -79.0331 38.8461 -78.9871 38.7631 -78.8661 38.8331 -78.8161 38.8801 -78.7931 38.9111 -78.7491 38.9291 -78.7371 38.9301 -78.7241 38.9041 -78.7191 38.9211 -78.6801 38.9501 -78.6471 38.9791 -78.6311 38.9671 -78.5981 39.0131 -78.5531 39.0231 -78.5491 39.0351 -78.5641 39.0571 -78.5361 39.0931 -78.5011 39.1111 -78.4851 39.1181 -78.4481 39.1481 -78.4301 39.1701 -78.4021 39.1971 -78.4241 39.2121 -78.4231 39.2441 -78.3991 39.2571 -78.4131 39.3411 -78.3411 39.3501 -78.3441 39.3611 -78.3651 39.3801 -78.3501 39.4561 -78.3471 39.4231 -78.2771 39.3911 -78.2291 39.2651 -78.0331 39.1321 -77.8301 39.1411 -77.8201 39.1961 -77.8051 39.2461 -77.7681 39.2841 -77.7591 39.3171 -77.7271 39.3181 -77.6791 39.2991 -77.6161 39.2981 -77.5681 39.2681 -77.5421 39.2491 -77.4941 39.2291 -77.4641 39.2181 -77.4611 39.1761 -77.4781 39.1571 -77.5161 39.1161 -77.5131 39.1031 -77.4791 39.0801 -77.4591 39.0661 -77.4331 39.0681 -77.3461 39.0621 -77.3241 39.0271 -77.2551 38.9751 -77.2431 38.9641 -77.1521 38.9321 -77.1221 38.9151 -77.0781 38.8861 -77.0671 38.8621 -77.0391 38.8381 -77.0401 38.8291 -77.0451 38.8131 -77.0351 38.7881 -77.0451 38.7181 -77.0461 38.7121 -77.0571 38.7151 -77.0811 38.7031 -77.0931 38.6771 -77.1251 38.6481 -77.1291 38.6221 -77.1971 38.6601 -77.1941 38.6501 -77.2271 38.5011 -77.3031 38.4361 -77.3381 38.3621 -77.2891 38.3431 -77.3211 38.3311 -77.2401 38.3751 -77.0541 38.2801 -76.9991 38.2021 -76.9361 38.1201 -76.5951 38.0741 -76.5491 38.0251 -76.5581 38.0031 -76.5731 38.0121 -76.5241 37.9561 -76.3671 37.8901 -76.2591 37.8501 -76.2511 37.7981 -76.3241 37.7191 -76.3091 37.7001 -76.3571 37.6771 -76.3231 37.6221 -76.3441 37.6561 -76.5071 37.7701 -76.5801 37.7961 -76.6311 37.9161 -76.7711 37.9191 -76.8181 37.7981 -76.7321 37.7741 -76.6811 37.6411 -76.5691 37.5511 -76.3141 37.5251 -76.3481 37.5521 -76.5121 37.5151 -76.4341 37.5151 -76.3551 37.3901 -76.2541 37.3301 -76.2751 37.3341 -76.3001 37.3931 -76.3391 37.4571 -76.4461 37.4181 -76.4631 37.4121 -76.4171 37.3731 -76.4031 37.3771 -76.4551 37.2931 -76.3921 37.2551 -76.4611 37.4121 -76.6531 37.4181 -76.7041 37.3711 -76.6691 37.2911 -76.5951 37.2071 -76.4241 37.1521 -76.4121 37.1731 -76.3961 37.1461 -76.3631 37.1771 -76.3371 37.1221 -76.2851 37.1071 -76.3951 37.0741 -76.2781 37.0201 -76.2931 36.9901 -76.3841 36.9651 -76.4261 37.0671 -76.5311 37.0881 -76.5151 37.1171 -76.5641 37.0801 -76.5681 37.1321 -76.6241 37.1781 -76.6101 37.2251 -76.6481 37.2321 -76.6971 37.1931 -76.7461 37.2401 -76.7951 37.2431 -76.8571 37.3221 -76.8751 37.2591 -76.8781 37.2361 -76.9411 37.2011 -76.9001 37.2071 -76.7971 37.1501 -76.7291 37.1971 -76.6851 37.1471 -76.6711 37.0541 -76.6651 37.0241 -76.5771 36.9941 -76.6131 37.0061 -76.5551 36.9611 -76.4891 36.9121 -76.5171 36.9191 -76.4821 36.8951 -76.4861 36.8411 -76.5601 36.7951 -76.5611 36.8691 -76.5071 36.9011 -76.4101 36.9131 -76.3481 36.8601 -76.3411 36.8351 -76.3941 36.8261 -76.4011 36.8451 -76.3171 36.8281 -76.2921 36.9421 -76.3071 36.9621 -76.2841 36.9351 -76.2021 36.9041 -76.1911 36.9311 -76.1181 36.9231 -75.9951 36.5551 -75.8781 36.5561 -75.9011 36.5991 -75.8921 36.7211 -75.9501 36.5561 -75.9981 36.5561 -76.0271 36.6031 -76.0611 36.5561 -76.0451 36.5571 -76.1271 36.5561 -76.3301 36.5551 -76.4971 36.5551 -76.5631 36.5541 -76.9211 36.5541 -76.9241 36.5561 -77.1771 36.5531 -77.3201 36.5531 -77.7631 36.5521 -77.8981 36.5521 -78.0511 36.5451 -78.3211 36.5411 -78.4581 36.5461 -78.7371 36.5431 -78.7961 36.5461 -79.1441</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.0271 -75.2701 38.0281 -75.2421 37.9621 -75.2981 37.8881 -75.3391 37.8751 -75.3861 37.9011 -75.3441 37.9001 -75.3781 37.9181 -75.3461 38.0271 -75.2701</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>37.5521 -75.8671 37.5611 -75.9411 37.5851 -75.9291 37.5801 -75.8871 37.5921 -75.9051 37.7111 -75.7991 37.7891 -75.7821 37.8241 -75.6961 37.8581 -75.6861 37.9301 -75.7331 37.9411 -75.6581 37.9701 -75.6481 37.9961 -75.6261 38.0161 -75.3721 37.6971 -75.6171 37.6771 -75.5891 37.5891 -75.6991 37.5591 -75.6501 37.5581 -75.7271 37.5101 -75.7561 37.4931 -75.7051 37.4691 -75.8131 37.4261 -75.8201 37.4081 -75.7901 37.4181 -75.8261 37.3671 -75.8971 37.1421 -75.9311 37.1261 -75.9701 37.3081 -76.0181 37.4841 -75.9341 37.4791 -75.9651 37.5211 -75.9541 37.5561 -75.9301 37.5521 -75.8671</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Virginia</topp:STATE_NAME><topp:STATE_FIPS>51</topp:STATE_FIPS><topp:SUB_REGION>S Atl</topp:SUB_REGION><topp:STATE_ABBR>VA</topp:STATE_ABBR><topp:LAND_KM>102537.328</topp:LAND_KM><topp:WATER_KM>4263.82</topp:WATER_KM><topp:PERSONS>6180651.0</topp:PERSONS><topp:FAMILIES>1627615.0</topp:FAMILIES><topp:HOUSHOLD>2289067.0</topp:HOUSHOLD><topp:MALE>3030948.0</topp:MALE><topp:FEMALE>3149703.0</topp:FEMALE><topp:WORKERS>2343200.0</topp:WORKERS><topp:DRVALONE>2278600.0</topp:DRVALONE><topp:CARPOOL>499251.0</topp:CARPOOL><topp:PUBTRANS>125792.0</topp:PUBTRANS><topp:EMPLOYED>3025109.0</topp:EMPLOYED><topp:UNEMPLOY>141926.0</topp:UNEMPLOY><topp:SERVICE>777181.0</topp:SERVICE><topp:MANUAL>420070.0</topp:MANUAL><topp:P_MALE>0.49</topp:P_MALE><topp:P_FEMALE>0.51</topp:P_FEMALE><topp:SAMP_POP>898089.0</topp:SAMP_POP></topp:states><topp:states fid=\"states.10\"><topp:the_geom><gml:MultiSurface srsName=\"urn:x-ogc:def:crs:EPSG:4326\"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>36.9531 -89.1041 36.8661 -89.1291 36.8431 -89.1661 36.8291 -89.1731 36.8041 -89.1641 36.7921 -89.1251 36.7681 -89.1251 36.7591 -89.1511 36.7601 -89.1771 36.7271 -89.1961 36.7131 -89.1971 36.6711 -89.1671 36.6531 -89.1771 36.6311 -89.2001 36.5811 -89.2101 36.5691 -89.2411 36.5751 -89.2831 36.6221 -89.3221 36.6281 -89.3421 36.6251 -89.3631 36.6161 -89.3731 36.5101 -89.4181 36.5021 -89.4141 36.4561 -89.4481 36.4451 -89.4701 36.4651 -89.4911 36.4981 -89.4751 36.5041 -89.4811 36.5251 -89.4711 36.5471 -89.4811 36.5591 -89.4931 36.5641 -89.5301 36.5571 -89.5561 36.5411 -89.5681 36.5181 -89.5661 36.4981 -89.5331 36.4711 -89.5161 36.4401 -89.5451 36.4011 -89.5201 36.3551 -89.5191 36.3451 -89.5441 36.3541 -89.6051 36.3341 -89.6221 36.3081 -89.6061 36.2801 -89.5421 36.2641 -89.5351 36.2571 -89.5411 36.2401 -89.6181 36.2541 -89.6701 36.2521 -89.6941 36.2401 -89.6951 36.2201 -89.6761 36.1831 -89.6181 36.1521 -89.5891 36.1291 -89.5891 36.0991 -89.6671 36.0821 -89.6781 36.0251 -89.6881 35.9991 -89.7211 35.9961 -89.9631 35.9911 -90.2831 35.9891 -90.3781 36.0911 -90.3151 36.1151 -90.2841 36.1181 -90.2631 36.1371 -90.2341 36.1611 -90.2321 36.1721 -90.2191 36.1961 -90.1611 36.2121 -90.1311 36.2571 -90.1091 36.2721 -90.0661 36.3001 -90.0491 36.3251 -90.0671 36.3621 -90.0501 36.3821 -90.0521 36.3971 -90.0801 36.4041 -90.1161 36.4221 -90.1231 36.4531 -90.1171 36.4571 -90.1371 36.4911 -90.1501 36.4921 -90.2241 36.4901 -90.5811 36.4891 -90.8041 36.4871 -91.1331 36.4911 -91.4111 36.4901 -91.4521 36.4901 -91.6881 36.4911 -92.1271 36.4911 -92.1461 36.4901 -92.5221 36.4891 -92.7771 36.4891 -92.8521 36.4901 -93.2971 36.4901 -93.3281 36.4891 -93.5961 36.4891 -93.8571 36.4901 -94.0801 36.4891 -94.6171 36.6701 -94.6201 36.7631 -94.6211 36.9961 -94.6201 37.0601 -94.6201 37.3271 -94.6181 37.3601 -94.6181 37.6501 -94.6181 37.6791 -94.6191 38.0301 -94.6161 38.0551 -94.6171 38.3921 -94.6181 38.4711 -94.6181 38.7371 -94.6121 38.8371 -94.6121 39.0441 -94.6091 39.1121 -94.6071 39.1411 -94.6001 39.1511 -94.6121 39.1581 -94.6461 39.1741 -94.6751 39.1711 -94.7301 39.1961 -94.7891 39.2111 -94.8201 39.2611 -94.8331 39.2861 -94.8801 39.3231 -94.9071 39.3401 -94.9111 39.3801 -94.8981 39.3811 -94.9251 39.4111 -94.9581 39.4391 -94.9851 39.4621 -95.0401 39.4851 -95.0471 39.5321 -95.1011 39.5601 -95.1081 39.5861 -95.0531 39.6251 -95.0551 39.6611 -95.0281 39.6841 -94.9781 39.7321 -94.9611 39.7361 -94.9521 39.7271 -94.9301 39.7261 -94.9051 39.7391 -94.8771 39.7541 -94.8701 39.7601 -94.8761 39.7571 -94.9211 39.7751 -94.9341 39.7821 -94.9331 39.7931 -94.8991 39.8171 -94.8881 39.8281 -94.8981 39.8331 -94.9231 39.8491 -94.9361 39.8961 -94.9371 39.9001 -94.9641 39.8961 -95.0211 39.8771 -95.0331 39.8661 -95.0621 39.8691 -95.1001 39.9081 -95.1501 39.9101 -95.1931 39.9381 -95.2071 39.9421 -95.2401 39.9991 -95.3081 40.0241 -95.3441 40.0281 -95.3701 40.0431 -95.3901 40.0481 -95.4131 40.0801 -95.4031 40.0951 -95.3841 40.1151 -95.3921 40.1311 -95.4221 40.1731 -95.4601 40.2131 -95.4661 40.2261 -95.4761 40.2661 -95.5461 40.3091 -95.5951 40.3091 -95.6461 40.3221 -95.6451 40.3311 -95.6171 40.3461 -95.6151 40.3581 -95.6331 40.3961 -95.6361 40.4851 -95.6951 40.5121 -95.6841 40.5301 -95.6571 40.5581 -95.6621 40.5651 -95.6751 40.5611 -95.6871 40.5241 -95.6911 40.5321 -95.7361 40.5491 -95.7631 40.5891 -95.7671 40.5841 -95.3821 40.5811 -95.2171 40.5771 -94.9201 40.5751 -94.6391 40.5741 -94.4841 40.5701 -94.2381 40.5741 -94.0171 40.5781 -93.7861 40.5801 -93.5621 40.5801 -93.3701 40.5841 -93.1001 40.5891 -92.7171 40.5911 -92.6461 40.5991 -92.3611 40.6001 -92.1921 40.6081 -91.9461 40.6091 -91.7411 40.5931 -91.7161 40.5811 -91.6891 40.5511 -91.6911 40.5321 -91.6221 40.5041 -91.6161 40.4841 -91.5851 40.4631 -91.5791 40.4551 -91.5331 40.4411 -91.5381 40.4351 -91.5291 40.4101 -91.5271 40.4051 -91.5001 40.3901 -91.4901 40.3901 -91.4761 40.3711 -91.4481 40.3091 -91.4861 40.2511 -91.4981 40.2001 -91.5061 40.1341 -91.5161 40.0661 -91.5041 40.0051 -91.4871 39.9461 -91.4471 39.9211 -91.4301 39.9011 -91.4341 39.8851 -91.4501 39.8631 -91.4491 39.8031 -91.3811 39.7611 -91.3731 39.7241 -91.3671 39.6851 -91.3171 39.6001 -91.2031 39.5521 -91.1561 39.5281 -91.0931 39.4731 -91.0641 39.4441 -91.0361 39.4001 -90.9471 39.3501 -90.8501 39.2961 -90.7791 39.2471 -90.7381 39.2241 -90.7321 39.1951 -90.7181 39.1441 -90.7161 39.0931 -90.6901 39.0581 -90.7071 39.0371 -90.7061 38.9351 -90.6681 38.8801 -90.6271 38.8711 -90.5701 38.8911 -90.5301 38.9591 -90.4691 38.9621 -90.4131 38.9241 -90.3191 38.9241 -90.2781 38.9141 -90.2431 38.8531 -90.1321 38.8301 -90.1131 38.8001 -90.1211 38.7851 -90.1351 38.7731 -90.1631 38.7231 -90.1961 38.7001 -90.2021 38.6581 -90.1831 38.6101 -90.1831 38.5621 -90.2401 38.5321 -90.2611 38.5181 -90.2651 38.4271 -90.3011 38.3901 -90.3391 38.3651 -90.3581 38.3231 -90.3691 38.2341 -90.3641 38.1881 -90.3361 38.1661 -90.2891 38.1221 -90.2541 38.0881 -90.2071 38.0531 -90.1341 38.0321 -90.1191 37.9931 -90.0411 37.9691 -90.0101 37.9631 -89.9581 37.9111 -89.9781 37.8781 -89.9371 37.8751 -89.9001 37.8911 -89.8661 37.9051 -89.8611 37.9051 -89.8511 37.8401 -89.7281 37.8041 -89.6911 37.7831 -89.6751 37.7451 -89.6661 37.7061 -89.5811 37.6941 -89.5211 37.6791 -89.5131 37.6501 -89.5191 37.6151 -89.5131 37.5711 -89.5241 37.4911 -89.4941 37.4531 -89.4531 37.4111 -89.4271 37.3551 -89.4351 37.3391 -89.4681 37.3291 -89.5001 37.3041 -89.5131 37.2761 -89.5131 37.2561 -89.4891 37.2531 -89.4651 37.2241 -89.4681 37.1651 -89.4401 37.1371 -89.4231 37.0991 -89.3791 37.0491 -89.3821 37.0091 -89.3101 36.9991 -89.2821 37.0081 -89.2621 37.0271 -89.2641 37.0601 -89.3091 37.0851 -89.3031 37.0911 -89.2841 37.0871 -89.2641 37.0411 -89.2371 37.0281 -89.2101 36.9861 -89.1931 36.9881 -89.1291 36.9771 -89.1071 36.9531 -89.1041</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Missouri</topp:STATE_NAME><topp:STATE_FIPS>29</topp:STATE_FIPS><topp:SUB_REGION>W N Cen</topp:SUB_REGION><topp:STATE_ABBR>MO</topp:STATE_ABBR><topp:LAND_KM>178445.951</topp:LAND_KM><topp:WATER_KM>2100.115</topp:WATER_KM><topp:PERSONS>5117073.0</topp:PERSONS><topp:FAMILIES>1368334.0</topp:FAMILIES><topp:HOUSHOLD>1961206.0</topp:HOUSHOLD><topp:MALE>2464315.0</topp:MALE><topp:FEMALE>2652758.0</topp:FEMALE><topp:WORKERS>1861192.0</topp:WORKERS><topp:DRVALONE>1816079.0</topp:DRVALONE><topp:CARPOOL>312042.0</topp:CARPOOL><topp:PUBTRANS>47129.0</topp:PUBTRANS><topp:EMPLOYED>2367395.0</topp:EMPLOYED><topp:UNEMPLOY>155388.0</topp:UNEMPLOY><topp:SERVICE>659782.0</topp:SERVICE><topp:MANUAL>386746.0</topp:MANUAL><topp:P_MALE>0.482</topp:P_MALE><topp:P_FEMALE>0.518</topp:P_FEMALE><topp:SAMP_POP>864999.0</topp:SAMP_POP></topp:states></gml:featureMembers>\n--></div>\n<div id=\"v3/topp-states-wfs.xml\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<wfs:FeatureCollection numberOfFeatures=\"3\" timeStamp=\"2008-09-12T00:24:21.013-04:00\" xsi:schemaLocation=\"http://www.openplans.org/topp http://sigma.openplans.org:80/geoserver/wfs?service=WFS&amp;version=1.1.0&amp;request=DescribeFeatureType&amp;typeName=topp:states http://www.opengis.net/wfs http://sigma.openplans.org:80/geoserver/schemas/wfs/1.1.0/wfs.xsd\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:opengeo=\"http://open-geo.com\" xmlns:tiger=\"http://www.census.gov\" xmlns:wfs=\"http://www.opengis.net/wfs\" xmlns:topp=\"http://www.openplans.org/topp\" xmlns:seb=\"http://seb.com\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ows=\"http://www.opengis.net/ows\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><gml:featureMembers><topp:states gml:id=\"states.1\"><gml:boundedBy><gml:Envelope srsName=\"urn:x-ogc:def:crs:EPSG:4326\"><gml:lowerCorner>36.986 -91.516</gml:lowerCorner><gml:upperCorner>42.509 -87.507</gml:upperCorner></gml:Envelope></gml:boundedBy><topp:the_geom><gml:MultiSurface srsName=\"urn:x-ogc:def:crs:EPSG:4326\"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>37.511 -88.071 37.476 -88.087 37.442 -88.311 37.409 -88.359 37.421 -88.419 37.401 -88.467 37.296 -88.511 37.257 -88.501 37.205 -88.451 37.156 -88.422 37.098 -88.451 37.072 -88.476 37.068 -88.491 37.064 -88.517 37.072 -88.559 37.109 -88.614 37.135 -88.688 37.141 -88.739 37.152 -88.746 37.202 -88.863 37.218 -88.932 37.221 -88.993 37.185 -89.065 37.112 -89.116 37.093 -89.146 37.064 -89.169 37.025 -89.174 36.998 -89.151 36.988 -89.129 36.986 -89.193 37.028 -89.211 37.041 -89.237 37.087 -89.264 37.091 -89.284 37.085 -89.303 37.061 -89.309 37.027 -89.264 37.008 -89.262 36.999 -89.282 37.009 -89.311 37.049 -89.382 37.099 -89.379 37.137 -89.423 37.165 -89.441 37.224 -89.468 37.253 -89.465 37.256 -89.489 37.276 -89.513 37.304 -89.513 37.329 -89.501 37.339 -89.468 37.355 -89.435 37.411 -89.427 37.453 -89.453 37.491 -89.494 37.571 -89.524 37.615 -89.513 37.651 -89.519 37.679 -89.513 37.694 -89.521 37.706 -89.581 37.745 -89.666 37.783 -89.675 37.804 -89.691 37.841 -89.728 37.905 -89.851 37.905 -89.861 37.891 -89.866 37.875 -89.901 37.878 -89.937 37.911 -89.978 37.963 -89.958 37.969 -90.011 37.993 -90.041 38.032 -90.119 38.053 -90.134 38.088 -90.207 38.122 -90.254 38.166 -90.289 38.188 -90.336 38.234 -90.364 38.323 -90.369 38.365 -90.358 38.391 -90.339 38.427 -90.301 38.518 -90.265 38.532 -90.261 38.562 -90.241 38.611 -90.183 38.658 -90.183 38.701 -90.202 38.723 -90.196 38.773 -90.163 38.785 -90.135 38.801 -90.121 38.831 -90.113 38.853 -90.132 38.914 -90.243 38.924 -90.278 38.924 -90.319 38.962 -90.413 38.959 -90.469 38.891 -90.531 38.871 -90.571 38.881 -90.627 38.935 -90.668 39.037 -90.706 39.058 -90.707 39.093 -90.691 39.144 -90.716 39.195 -90.718 39.224 -90.732 39.247 -90.738 39.296 -90.779 39.351 -90.851 39.401 -90.947 39.444 -91.036 39.473 -91.064 39.528 -91.093 39.552 -91.156 39.601 -91.203 39.685 -91.317 39.724 -91.367 39.761 -91.373 39.803 -91.381 39.863 -91.449 39.885 -91.451 39.901 -91.434 39.921 -91.431 39.946 -91.447 40.005 -91.487 40.066 -91.504 40.134 -91.516 40.201 -91.506 40.251 -91.498 40.309 -91.486 40.371 -91.448 40.386 -91.418 40.392 -91.385 40.402 -91.372 40.447 -91.385 40.503 -91.374 40.528 -91.382 40.547 -91.412 40.572 -91.411 40.603 -91.375 40.639 -91.262 40.643 -91.214 40.656 -91.162 40.682 -91.129 40.705 -91.119 40.761 -91.092 40.833 -91.088 40.879 -91.049 40.923 -90.983 40.951 -90.961 41.071 -90.954 41.104 -90.957 41.144 -90.991 41.165 -91.018 41.176 -91.056 41.231 -91.101 41.267 -91.102 41.334 -91.073 41.401 -91.055 41.423 -91.027 41.431 -91.001 41.421 -90.949 41.444 -90.844 41.449 -90.779 41.451 -90.708 41.462 -90.658 41.509 -90.601 41.525 -90.541 41.527 -90.454 41.543 -90.434 41.567 -90.423 41.586 -90.348 41.602 -90.339 41.649 -90.341 41.722 -90.326 41.756 -90.304 41.781 -90.255 41.806 -90.195 41.931 -90.154 41.983 -90.142 42.033 -90.151 42.061 -90.168 42.103 -90.166 42.121 -90.176 42.122 -90.191 42.159 -90.231 42.197 -90.323 42.211 -90.367 42.242 -90.407 42.263 -90.417 42.341 -90.427 42.361 -90.441 42.388 -90.491 42.421 -90.563 42.461 -90.605 42.475 -90.648 42.494 -90.651 42.509 -90.638 42.508 -90.419 42.504 -89.923 42.503 -89.834 42.497 -89.401 42.497 -89.359 42.491 -88.939 42.491 -88.764 42.489 -88.706 42.491 -88.297 42.489 -88.194 42.489 -87.797 42.314 -87.836 42.156 -87.761 42.059 -87.671 41.847 -87.612 41.723 -87.529 41.469 -87.532 41.301 -87.532 41.173 -87.531 41.009 -87.532 40.745 -87.532 40.494 -87.537 40.483 -87.535 40.166 -87.535 39.887 -87.535 39.609 -87.535 39.477 -87.538 39.351 -87.541 39.338 -87.597 39.307 -87.625 39.297 -87.611 39.281 -87.615 39.258 -87.606 39.248 -87.584 39.208 -87.588 39.198 -87.594 39.196 -87.607 39.168 -87.644 39.146 -87.671 39.131 -87.659 39.113 -87.662 39.103 -87.631 39.088 -87.631 39.084 -87.612 39.062 -87.585 38.995 -87.581 38.994 -87.591 38.977 -87.547 38.963 -87.533 38.931 -87.531 38.904 -87.539 38.869 -87.559 38.857 -87.551 38.795 -87.507 38.776 -87.519 38.769 -87.508 38.736 -87.508 38.685 -87.543 38.672 -87.588 38.642 -87.625 38.622 -87.628 38.599 -87.619 38.593 -87.641 38.573 -87.652 38.547 -87.672 38.515 -87.651 38.501 -87.653 38.504 -87.679 38.481 -87.692 38.466 -87.756 38.457 -87.758 38.445 -87.738 38.417 -87.748 38.378 -87.784 38.352 -87.834 38.286 -87.851 38.285 -87.863 38.316 -87.874 38.315 -87.883 38.301 -87.888 38.281 -87.914 38.302 -87.913 38.304 -87.925 38.241 -87.981 38.234 -87.986 38.201 -87.977 38.171 -87.932 38.157 -87.931 38.136 -87.951 38.131 -87.973 38.103 -88.018 38.092 -88.012 38.096 -87.964 38.073 -87.975 38.054 -88.034 38.045 -88.043 38.038 -88.041 38.033 -88.021 38.008 -88.029 37.975 -88.021 37.956 -88.042 37.934 -88.041 37.929 -88.064 37.944 -88.078 37.923 -88.084 37.917 -88.031 37.905 -88.026 37.896 -88.044 37.906 -88.101 37.895 -88.101 37.867 -88.075 37.843 -88.034 37.827 -88.042 37.831 -88.089 37.817 -88.086 37.805 -88.035 37.735 -88.072 37.701 -88.133 37.661 -88.159 37.628 -88.157 37.583 -88.134 37.511 -88.071</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Illinois</topp:STATE_NAME><topp:STATE_FIPS>17</topp:STATE_FIPS><topp:SUB_REGION>E N Cen</topp:SUB_REGION><topp:STATE_ABBR>IL</topp:STATE_ABBR><topp:LAND_KM>143986.61</topp:LAND_KM><topp:WATER_KM>1993.335</topp:WATER_KM><topp:PERSONS>1.143E7</topp:PERSONS><topp:FAMILIES>2924880.0</topp:FAMILIES><topp:HOUSHOLD>4202240.0</topp:HOUSHOLD><topp:MALE>5552233.0</topp:MALE><topp:FEMALE>5878369.0</topp:FEMALE><topp:WORKERS>4199206.0</topp:WORKERS><topp:DRVALONE>3741715.0</topp:DRVALONE><topp:CARPOOL>652603.0</topp:CARPOOL><topp:PUBTRANS>538071.0</topp:PUBTRANS><topp:EMPLOYED>5417967.0</topp:EMPLOYED><topp:UNEMPLOY>385040.0</topp:UNEMPLOY><topp:SERVICE>1360159.0</topp:SERVICE><topp:MANUAL>828906.0</topp:MANUAL><topp:P_MALE>0.486</topp:P_MALE><topp:P_FEMALE>0.514</topp:P_FEMALE><topp:SAMP_POP>1747776.0</topp:SAMP_POP></topp:states><topp:states gml:id=\"states.2\"><gml:boundedBy><gml:Envelope srsName=\"urn:x-ogc:def:crs:EPSG:4326\"><gml:lowerCorner>38.788 -77.122</gml:lowerCorner><gml:upperCorner>38.993 -76.911</gml:upperCorner></gml:Envelope></gml:boundedBy><topp:the_geom><gml:MultiSurface srsName=\"urn:x-ogc:def:crs:EPSG:4326\"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.966 -77.008 38.889 -76.911 38.788 -77.045 38.813 -77.035 38.829 -77.045 38.838 -77.041 38.862 -77.039 38.886 -77.067 38.915 -77.078 38.932 -77.122 38.993 -77.042 38.966 -77.008</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>District of Columbia</topp:STATE_NAME><topp:STATE_FIPS>11</topp:STATE_FIPS><topp:SUB_REGION>S Atl</topp:SUB_REGION><topp:STATE_ABBR>DC</topp:STATE_ABBR><topp:LAND_KM>159.055</topp:LAND_KM><topp:WATER_KM>17.991</topp:WATER_KM><topp:PERSONS>606900.0</topp:PERSONS><topp:FAMILIES>122087.0</topp:FAMILIES><topp:HOUSHOLD>249634.0</topp:HOUSHOLD><topp:MALE>282970.0</topp:MALE><topp:FEMALE>323930.0</topp:FEMALE><topp:WORKERS>229975.0</topp:WORKERS><topp:DRVALONE>106694.0</topp:DRVALONE><topp:CARPOOL>36621.0</topp:CARPOOL><topp:PUBTRANS>111422.0</topp:PUBTRANS><topp:EMPLOYED>303994.0</topp:EMPLOYED><topp:UNEMPLOY>23442.0</topp:UNEMPLOY><topp:SERVICE>65498.0</topp:SERVICE><topp:MANUAL>22407.0</topp:MANUAL><topp:P_MALE>0.466</topp:P_MALE><topp:P_FEMALE>0.534</topp:P_FEMALE><topp:SAMP_POP>72696.0</topp:SAMP_POP></topp:states><topp:states gml:id=\"states.3\"><gml:boundedBy><gml:Envelope srsName=\"urn:x-ogc:def:crs:EPSG:4326\"><gml:lowerCorner>38.449 -75.791</gml:lowerCorner><gml:upperCorner>39.841 -75.045</gml:upperCorner></gml:Envelope></gml:boundedBy><topp:the_geom><gml:MultiSurface srsName=\"urn:x-ogc:def:crs:EPSG:4326\"><gml:surfaceMember><gml:Polygon><gml:exterior><gml:LinearRing><gml:posList>38.557 -75.707 38.649 -75.711 38.831 -75.724 39.141 -75.752 39.247 -75.761 39.295 -75.764 39.383 -75.772 39.723 -75.791 39.724 -75.775 39.774 -75.745 39.821 -75.695 39.838 -75.644 39.841 -75.583 39.826 -75.471 39.798 -75.421 39.789 -75.412 39.778 -75.428 39.763 -75.461 39.741 -75.475 39.719 -75.476 39.714 -75.489 39.612 -75.611 39.566 -75.562 39.463 -75.591 39.366 -75.515 39.257 -75.402 39.073 -75.397 39.012 -75.324 38.945 -75.307 38.808 -75.191 38.799 -75.083 38.449 -75.045 38.449 -75.068 38.451 -75.093 38.455 -75.351 38.463 -75.699 38.557 -75.707</gml:posList></gml:LinearRing></gml:exterior></gml:Polygon></gml:surfaceMember></gml:MultiSurface></topp:the_geom><topp:STATE_NAME>Delaware</topp:STATE_NAME><topp:STATE_FIPS>10</topp:STATE_FIPS><topp:SUB_REGION>S Atl</topp:SUB_REGION><topp:STATE_ABBR>DE</topp:STATE_ABBR><topp:LAND_KM>5062.456</topp:LAND_KM><topp:WATER_KM>1385.022</topp:WATER_KM><topp:PERSONS>666168.0</topp:PERSONS><topp:FAMILIES>175867.0</topp:FAMILIES><topp:HOUSHOLD>247497.0</topp:HOUSHOLD><topp:MALE>322968.0</topp:MALE><topp:FEMALE>343200.0</topp:FEMALE><topp:WORKERS>247566.0</topp:WORKERS><topp:DRVALONE>258087.0</topp:DRVALONE><topp:CARPOOL>42968.0</topp:CARPOOL><topp:PUBTRANS>8069.0</topp:PUBTRANS><topp:EMPLOYED>335147.0</topp:EMPLOYED><topp:UNEMPLOY>13945.0</topp:UNEMPLOY><topp:SERVICE>87973.0</topp:SERVICE><topp:MANUAL>44140.0</topp:MANUAL><topp:P_MALE>0.485</topp:P_MALE><topp:P_FEMALE>0.515</topp:P_FEMALE><topp:SAMP_POP>102776.0</topp:SAMP_POP></topp:states></gml:featureMembers></wfs:FeatureCollection>\n--></div>\n<div id=\"v2/point-coord.xml\"><!--\n<gml:Point xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n  <gml:coord>\n    <gml:X>1</gml:X>\n    <gml:Y>2</gml:Y>\n  </gml:coord>\n</gml:Point>\n--></div>\n<div id=\"v2/point-coordinates.xml\"><!--\n<gml:Point xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n  <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2</gml:coordinates>\n</gml:Point>\n--></div>\n<div id=\"v2/linestring-coord.xml\"><!--\n<gml:LineString xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n  <gml:coord>\n    <gml:X>1</gml:X>\n    <gml:Y>2</gml:Y>\n  </gml:coord>\n  <gml:coord>\n    <gml:X>3</gml:X>\n    <gml:Y>4</gml:Y>\n  </gml:coord>\n</gml:LineString>\n--></div>\n<div id=\"v2/linestring-coordinates.xml\"><!--\n<gml:LineString xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n  <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2 3,4</gml:coordinates>\n</gml:LineString>\n--></div>\n<div id=\"v2/multipoint-coord.xml\"><!--\n<gml:MultiPoint xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:pointMember>\n        <gml:Point>\n            <gml:coord>\n                <gml:X>1</gml:X>\n                <gml:Y>2</gml:Y>\n            </gml:coord>\n        </gml:Point>\n    </gml:pointMember>\n    <gml:pointMember>\n        <gml:Point>\n            <gml:coord>\n                <gml:X>2</gml:X>\n                <gml:Y>3</gml:Y>\n            </gml:coord>\n        </gml:Point>\n    </gml:pointMember>\n    <gml:pointMember>\n        <gml:Point>\n            <gml:coord>\n                <gml:X>3</gml:X>\n                <gml:Y>4</gml:Y>\n            </gml:coord>\n        </gml:Point>\n    </gml:pointMember>\n</gml:MultiPoint>\n--></div>\n<div id=\"v2/multipoint-coordinates.xml\"><!--\n<gml:MultiPoint xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:pointMember>\n        <gml:Point>\n            <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2</gml:coordinates>\n        </gml:Point>\n    </gml:pointMember>\n    <gml:pointMember>\n        <gml:Point>\n            <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">2,3</gml:coordinates>\n        </gml:Point>\n    </gml:pointMember>\n    <gml:pointMember>\n        <gml:Point>\n            <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">3,4</gml:coordinates>\n        </gml:Point>\n    </gml:pointMember>\n</gml:MultiPoint>\n--></div>\n<div id=\"v2/multilinestring-coord.xml\"><!--\n<gml:MultiLineString xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:lineStringMember>\n        <gml:LineString>\n            <gml:coord>\n                <gml:X>1</gml:X>\n                <gml:Y>2</gml:Y>\n            </gml:coord>\n            <gml:coord>\n                <gml:X>2</gml:X>\n                <gml:Y>3</gml:Y>\n            </gml:coord>\n        </gml:LineString>\n    </gml:lineStringMember>\n    <gml:lineStringMember>\n        <gml:LineString>\n            <gml:coord>\n                <gml:X>3</gml:X>\n                <gml:Y>4</gml:Y>\n            </gml:coord>\n            <gml:coord>\n                <gml:X>4</gml:X>\n                <gml:Y>5</gml:Y>\n            </gml:coord>\n        </gml:LineString>\n    </gml:lineStringMember>\n</gml:MultiLineString>\n--></div>\n<div id=\"v2/multilinestring-coordinates.xml\"><!--\n<gml:MultiLineString xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"foo\">\n    <gml:lineStringMember>\n        <gml:LineString>\n            <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2 2,3</gml:coordinates>\n        </gml:LineString>\n    </gml:lineStringMember>\n    <gml:lineStringMember>\n        <gml:LineString>\n            <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">3,4 4,5</gml:coordinates>\n        </gml:LineString>\n    </gml:lineStringMember>\n</gml:MultiLineString>\n--></div>\n<div id=\"v3/repeated-name.xml\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<wfs:FeatureCollection numberOfFeatures=\"1\" timeStamp=\"2010-01-29T15:10:38.921-07:00\"\n        xsi:schemaLocation=\"http://medford.opengeo.org http://localhost:8080/geoserver/wfs?service=WFS&amp;version=1.1.0&amp;request=DescribeFeatureType&amp;typeName=medford%3Azoning http://www.opengis.net/wfs http://localhost:8080/geoserver/schemas/wfs/1.1.0/wfs.xsd\"\n        xmlns:ogc=\"http://www.opengis.net/ogc\"\n        xmlns:wfs=\"http://www.opengis.net/wfs\"\n        xmlns:medford=\"http://opengeo.org/#medford\"\n        xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n        xmlns:ows=\"http://www.opengis.net/ows\"\n        xmlns:gml=\"http://www.opengis.net/gml\"\n        xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n    <gml:featureMembers>\n        <medford:zoning gml:id=\"zoning.1\">\n            <medford:the_geom>\n                <gml:MultiSurface srsName=\"urn:x-ogc:def:crs:EPSG:4326\">\n                    <gml:surfaceMember>\n                        <gml:Polygon>\n                            <gml:exterior>\n                                <gml:LinearRing>\n                                    <gml:posList>42.397027571297585 -122.88465674265922 42.39702893980587 -122.88509730796012 42.397029086785146 -122.88511582432085 42.39702379767053 -122.88528111596624 42.39748517484964 -122.88529300380065 42.39748473847452 -122.88509914138723 42.39748482219041 -122.8849959517568 42.397485082635576 -122.8846741899541 42.3974853307826 -122.88436529392652 42.39702663751206 -122.88435664014142 42.397027571297585 -122.88465674265922</gml:posList>\n                                </gml:LinearRing>\n                            </gml:exterior>\n                        </gml:Polygon>\n                    </gml:surfaceMember>\n                </gml:MultiSurface>\n            </medford:the_geom>\n            <medford:objectid>1</medford:objectid>\n            <medford:cityzone>YES</medford:cityzone>\n            <medford:zoning>I-L</medford:zoning>\n            <medford:revdate>2004-04-12T00:00:00-06:00</medford:revdate>\n            <medford:finord></medford:finord>\n            <medford:filenum></medford:filenum>\n            <medford:acres>0.95741118624</medford:acres>\n            <medford:misc></medford:misc>\n            <medford:shape_leng>835.705330224</medford:shape_leng>\n            <medford:perimeter>835.705330224</medford:perimeter>\n            <medford:area>41704.8312728</medford:area>\n            <medford:shape_le_1>835.705330224</medford:shape_le_1>\n            <medford:shape_area>41704.8312728</medford:shape_area>\n            <medford:hectares>0.38745056079</medford:hectares>\n        </medford:zoning>\n    </gml:featureMembers>\n</wfs:FeatureCollection>\n-->\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/GML.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_Format_GML_constructor(t) { \n        t.plan(4); \n         \n        var options = {'foo': 'bar'}; \n        var format = new OpenLayers.Format.GML(options); \n        t.ok(format instanceof OpenLayers.Format.GML, \n             \"new OpenLayers.Format.GML returns object\" ); \n        t.eq(format.foo, \"bar\", \"constructor sets options correctly\"); \n        t.eq(typeof format.read, \"function\", \"format has a read function\"); \n        t.eq(typeof format.write, \"function\", \"format has a write function\"); \n    } \n    function test_Format_GML_getFid(t) { \n        t.plan(2);\n        var parser = new OpenLayers.Format.GML();\n        data = parser.read(test_content[1]);\n        t.eq(data[0].fid, '221', 'fid on polygons set correctly (with whitespace)');\n        t.eq(data[1].fid, '8', 'fid on linestrings set correctly with whitespace'); \n    }\n    function test_Format_GML_no_clobber(t) { \n        t.plan(1); \n        var parser = new OpenLayers.Format.GML(); \n        data = parser.read(test_content[1]); \n        t.eq(window.i, undefined,\n             \"i is undefined in window scope after reading.\"); \n    }\n    function test_Format_GML_read_3d(t) {\n        t.plan(2);\n        var parser = new OpenLayers.Format.GML();\n        data = parser.read(test_content[0]);\n        t.eq(data[0].geometry.getBounds().toBBOX(), \"-1254041.389712,250906.951598,-634517.119991,762236.29408\", \"Reading 3d content returns geometry with correct bounds (no 0,0)\");\n        t.eq(data[0].geometry.CLASS_NAME, \"OpenLayers.Geometry.Polygon\", \"Reading 3d content returns polygon geometry\");\n    }   \n    function test_Format_GML_write_geoms(t) {\n        t.plan(5);\n        var parser = new OpenLayers.Format.GML();\n        \n        var point = shell_start + serialize_geoms['point'] + shell_end;\n        data = parser.read(point);\n        var output = parser.write(data);\n        var output = output.replace(/<\\?[^>]*\\?>/, ''); // Remove XML Prolog\n        t.eq(output, point, \"Point geometry round trips correctly.\");\n        \n        var linestring = shell_start + serialize_geoms['linestring'] + shell_end;\n        data = parser.read(linestring);\n        var output = parser.write(data);\n        var output = output.replace(/<\\?[^>]*\\?>/, ''); // Remove XML Prolog\n        t.eq(output, linestring, \"Line geometry round trips correctly.\");\n        \n        var polygon = shell_start + serialize_geoms['polygon'] + shell_end;\n        data = parser.read(polygon);\n        var output = parser.write(data);\n        output = output.replace(/<\\?[^>]*\\?>/, ''); // Remove XML Prolog\n        t.eq(output, polygon, \"Poly geometry round trips correctly.\");\n        \n        var multipoint = shell_start + serialize_geoms['multipoint'] + shell_end;\n        data = parser.read(multipoint);\n        var output = parser.write(data);\n        var output = output.replace(/<\\?[^>]*\\?>/, ''); // Remove XML Prolog\n        t.eq(output, multipoint, \"MultiPoint geometry round trips correctly.\");\n        \n        var multilinestring = shell_start + serialize_geoms['multilinestring'] + shell_end;\n        data = parser.read(multilinestring);\n        var output = parser.write(data);\n        var output = output.replace(/<\\?[^>]*\\?>/, ''); // Remove XML Prolog\n        t.eq(output, multilinestring, \"MultiLine geometry round trips correctly.\");\n\n    }    \n    function test_Format_GML_read_point_geom(t) {\n        t.plan(3);\n        \n        var point = shell_start + geoms['point'] + shell_end;\n        var parser = new OpenLayers.Format.GML();\n        data = parser.read(point);\n        t.eq(data[0].geometry.CLASS_NAME, \"OpenLayers.Geometry.Point\", \"Point GML returns correct classname\");\n        t.eq(data[0].geometry.x, 1, \"x coord correct\");\n        t.eq(data[0].geometry.y, 2, \"y coord correct\");\n    }\n    function test_Format_GML_read_linestring_geom(t) {\n        t.plan(5);\n        \n        var line = shell_start + geoms['linestring'] + shell_end;\n        var parser = new OpenLayers.Format.GML();\n        data = parser.read(line);\n        t.eq(data[0].geometry.CLASS_NAME, \"OpenLayers.Geometry.LineString\", \"LineString GML returns correct classname\");\n        t.eq(data[0].geometry.components[0].x, 1, \"first x coord correct\");\n        t.eq(data[0].geometry.components[0].y, 2, \"first y coord correct\");\n        t.eq(data[0].geometry.components[1].x, 4, \"second x coord correct\");\n        t.eq(data[0].geometry.components[1].y, 5, \"second y coord correct\");\n    }    \n    function test_Format_GML_read_polygon_geom(t) {\n        t.plan(7);\n        \n        var polygon = shell_start + geoms['polygon'] + shell_end;\n        var parser = new OpenLayers.Format.GML();\n        data = parser.read(polygon);\n        t.eq(data[0].geometry.CLASS_NAME, \"OpenLayers.Geometry.Polygon\", \"Polygon GML returns correct classname\");\n        t.eq(data[0].geometry.components[0].components[0].x, 1, \"first x coord correct\");\n        t.eq(data[0].geometry.components[0].components[0].y, 2, \"first y coord correct\");\n        t.eq(data[0].geometry.components[0].components[1].x, 4, \"second x coord correct\");\n        t.eq(data[0].geometry.components[0].components[1].y, 5, \"second y coord correct\");\n        t.eq(data[0].geometry.components[0].components.length, 4, \"coords length correct\");\n        t.eq(data[0].geometry.components.length, 1, \"rings length correct\");\n    }   \n    function test_Format_GML_read_multipoint_geom(t) {\n        t.plan(6);\n        \n        var multipoint = shell_start + geoms['multipoint'] + shell_end;\n        var parser = new OpenLayers.Format.GML();\n        data = parser.read(multipoint);\n        t.eq(data[0].geometry.CLASS_NAME, \"OpenLayers.Geometry.MultiPoint\", \"MultiPoint GML returns correct classname\");\n        t.eq(data[0].geometry.components[0].x, 1, \"x coord correct\");\n        t.eq(data[0].geometry.components[0].y, 2, \"y coord correct\");\n        t.eq(data[0].geometry.components.length, 2, \"length correct\");\n        t.eq(data[0].geometry.components[1].x, 4, \"x coord correct\");\n        t.eq(data[0].geometry.components[1].y, 5, \"y coord correct\");\n    }    \n    function test_Format_GML_read_multilinestring_geom(t) {\n        t.plan(6);\n        \n        var multilinestring = shell_start + geoms['multilinestring'] + shell_end;\n        var parser = new OpenLayers.Format.GML();\n        data = parser.read(multilinestring);\n        t.eq(data[0].geometry.CLASS_NAME, \"OpenLayers.Geometry.MultiLineString\", \"MultiLineString GML returns correct classname\");\n        t.eq(data[0].geometry.components[0].components[0].x, 1, \"x coord correct\");\n        t.eq(data[0].geometry.components[0].components[0].y, 2, \"y coord correct\");\n        t.eq(data[0].geometry.components[0].components.length, 2, \"length correct\");\n        t.eq(data[0].geometry.components[0].components[1].x, 4, \"x coord correct\");\n        t.eq(data[0].geometry.components[0].components[1].y, 5, \"y coord correct\");\n        \n    }    \n    function test_Format_GML_read_polygon_with_holes_geom(t) {\n        t.plan(12);\n        \n        var polygon_with_holes = shell_start + geoms['polygon_with_holes'] + shell_end;\n        var parser = new OpenLayers.Format.GML();\n        data = parser.read(polygon_with_holes);\n        t.eq(data[0].geometry.CLASS_NAME, \"OpenLayers.Geometry.Polygon\", \"Polygon GML returns correct classname\");\n        t.eq(data[0].geometry.components[0].components[0].x, 1, \"first x coord correct\");\n        t.eq(data[0].geometry.components[0].components[0].y, 2, \"first y coord correct\");\n        t.eq(data[0].geometry.components[0].components[1].x, 4, \"second x coord correct\");\n        t.eq(data[0].geometry.components[0].components[1].y, 5, \"second y coord correct\");\n        t.eq(data[0].geometry.components[0].components.length, 4, \"coords length correct\");\n        t.eq(data[0].geometry.components[1].components[0].x, 11, \"first x coord correct\");\n        t.eq(data[0].geometry.components[1].components[0].y, 12, \"first y coord correct\");\n        t.eq(data[0].geometry.components[1].components[1].x, 14, \"second x coord correct\");\n        t.eq(data[0].geometry.components[1].components[1].y, 15, \"second y coord correct\");\n        t.eq(data[0].geometry.components[1].components.length, 4, \"coords length correct\");\n        t.eq(data[0].geometry.components.length, 2, \"rings length correct\");\n    }\n    function test_Format_GML_read_attributes(t) {\n        t.plan(3);\n        var parser = new OpenLayers.Format.GML();\n        data = parser.read(test_content[0]);\n        t.eq(data[0].attributes['NAME'], \"WY\", \"Simple Attribute data is read correctly.\");\n        t.eq(data[0].attributes['LONGNAME'], \"Wyoming\", \"Attribute data is read from CDATA node correctly.\");\n        t.ok(data[0].attributes['EMPTYATTR'] === null, \"Attribute set to null for empty element.\");\n    }\n    function test_Format_GML_read_envelope_geom(t) {\n        t.plan(13);\n        \n        var envelope = shell_start + geoms['envelope'] + shell_end;\n        var parser = new OpenLayers.Format.GML();\n        data = parser.read(envelope);\n        t.eq(data[0].geometry.CLASS_NAME, \"OpenLayers.Geometry.Polygon\", \"Envelope GML returns correct classname\");\n        t.eq(data[0].geometry.components[0].components[0].x, 0, \"first x coord correct\");\n        t.eq(data[0].geometry.components[0].components[0].y, 1, \"first y coord correct\");\n        t.eq(data[0].geometry.components[0].components[1].x, 20, \"second x coord correct\");\n        t.eq(data[0].geometry.components[0].components[1].y, 1, \"second y coord correct\");\n        t.eq(data[0].geometry.components[0].components[2].x, 20, \"third x coord correct\");\n        t.eq(data[0].geometry.components[0].components[2].y, 21, \"third y coord correct\");\n        t.eq(data[0].geometry.components[0].components[3].x, 0, \"fouth x coord correct\");\n        t.eq(data[0].geometry.components[0].components[3].y, 21, \"fourth y coord correct\");\n        t.eq(data[0].geometry.components[0].components[4].x, 0, \"fifth x coord correct\");\n        t.eq(data[0].geometry.components[0].components[4].y, 1, \"fifth y coord correct\");\n        t.eq(data[0].geometry.components[0].components.length, 5, \"coords length correct\");\n        t.eq(data[0].geometry.components.length, 1, \"rings length correct\");\n    }    \n    ///////////////////////////////////////////////////////////////\n    // tests the y x order of gml point\n    /////////////////////////////////////////////////////////////\n    function test_Format_GML_read_point_geom_yx(t) {\n        t.plan(3);\n        \n        var point = shell_start + geoms_yx['point'] + shell_end;\n        var parser = new OpenLayers.Format.GML({'xy':false});\n        data = parser.read(point);\n        t.eq(data[0].geometry.CLASS_NAME, \"OpenLayers.Geometry.Point\", \"Point GML returns correct classname\");\n        t.eq(data[0].geometry.x, 1, \"x coord correct\");\n        t.eq(data[0].geometry.y, 2, \"y coord correct\");\n    } \n    function test_Format_GML_read_linestring_geom_yx(t) {\n        t.plan(5);\n        \n        var line = shell_start + geoms_yx['linestring'] + shell_end;\n        var parser = new OpenLayers.Format.GML({'xy':false});\n        data = parser.read(line);\n        t.eq(data[0].geometry.CLASS_NAME, \"OpenLayers.Geometry.LineString\", \"LineString GML returns correct classname\");\n        t.eq(data[0].geometry.components[0].x, 1, \"first x coord correct\");\n        t.eq(data[0].geometry.components[0].y, 2, \"first y coord correct\");\n        t.eq(data[0].geometry.components[1].x, 4, \"second x coord correct\");\n        t.eq(data[0].geometry.components[1].y, 5, \"second y coord correct\");\n    }    \n    function test_Format_GML_read_polygon_geom_yx(t) {\n        t.plan(7);\n        \n        var polygon = shell_start + geoms_yx['polygon'] + shell_end;\n        var parser = new OpenLayers.Format.GML({'xy':false});\n        data = parser.read(polygon);\n        t.eq(data[0].geometry.CLASS_NAME, \"OpenLayers.Geometry.Polygon\", \"Polygon GML returns correct classname\");\n        t.eq(data[0].geometry.components[0].components[0].x, 1, \"first x coord correct\");\n        t.eq(data[0].geometry.components[0].components[0].y, 2, \"first y coord correct\");\n        t.eq(data[0].geometry.components[0].components[1].x, 4, \"second x coord correct\");\n        t.eq(data[0].geometry.components[0].components[1].y, 5, \"second y coord correct\");\n        t.eq(data[0].geometry.components[0].components.length, 4, \"coords length correct\");\n        t.eq(data[0].geometry.components.length, 1, \"rings length correct\");\n    }   \n    function test_Format_GML_read_multipoint_geom_yx(t) {\n        t.plan(6);\n        \n        var multipoint = shell_start + geoms_yx['multipoint'] + shell_end;\n        var parser = new OpenLayers.Format.GML({'xy':false});\n        data = parser.read(multipoint);\n        t.eq(data[0].geometry.CLASS_NAME, \"OpenLayers.Geometry.MultiPoint\", \"MultiPoint GML returns correct classname\");\n        t.eq(data[0].geometry.components[0].x, 1, \"x coord correct\");\n        t.eq(data[0].geometry.components[0].y, 2, \"y coord correct\");\n        t.eq(data[0].geometry.components.length, 2, \"length correct\");\n        t.eq(data[0].geometry.components[1].x, 4, \"x coord correct\");\n        t.eq(data[0].geometry.components[1].y, 5, \"y coord correct\");\n    }    \n    function test_Format_GML_read_multilinestring_geom_yx(t) {\n        t.plan(6);\n        \n        var multilinestring = shell_start + geoms_yx['multilinestring'] + shell_end;\n        var parser = new OpenLayers.Format.GML({'xy':false});\n        data = parser.read(multilinestring);\n        t.eq(data[0].geometry.CLASS_NAME, \"OpenLayers.Geometry.MultiLineString\", \"MultiLineString GML returns correct classname\");\n        t.eq(data[0].geometry.components[0].components[0].x, 1, \"x coord correct\");\n        t.eq(data[0].geometry.components[0].components[0].y, 2, \"y coord correct\");\n        t.eq(data[0].geometry.components[0].components.length, 2, \"length correct\");\n        t.eq(data[0].geometry.components[0].components[1].x, 4, \"x coord correct\");\n        t.eq(data[0].geometry.components[0].components[1].y, 5, \"y coord correct\");\n        \n    }    \n    function test_Format_GML_read_polygon_with_holes_geom_yx(t) {\n        t.plan(12);\n        \n        var polygon_with_holes = shell_start + geoms_yx['polygon_with_holes'] + shell_end;\n        var parser = new OpenLayers.Format.GML({'xy':false});\n        data = parser.read(polygon_with_holes);\n        t.eq(data[0].geometry.CLASS_NAME, \"OpenLayers.Geometry.Polygon\", \"Polygon GML returns correct classname\");\n        t.eq(data[0].geometry.components[0].components[0].x, 1, \"first x coord correct\");\n        t.eq(data[0].geometry.components[0].components[0].y, 2, \"first y coord correct\");\n        t.eq(data[0].geometry.components[0].components[1].x, 4, \"second x coord correct\");\n        t.eq(data[0].geometry.components[0].components[1].y, 5, \"second y coord correct\");\n        t.eq(data[0].geometry.components[0].components.length, 4, \"coords length correct\");\n        t.eq(data[0].geometry.components[1].components[0].x, 11, \"first x coord correct\");\n        t.eq(data[0].geometry.components[1].components[0].y, 12, \"first y coord correct\");\n        t.eq(data[0].geometry.components[1].components[1].x, 14, \"second x coord correct\");\n        t.eq(data[0].geometry.components[1].components[1].y, 15, \"second y coord correct\");\n        t.eq(data[0].geometry.components[1].components.length, 4, \"coords length correct\");\n        t.eq(data[0].geometry.components.length, 2, \"rings length correct\");\n    }\n\n    function test_Format_GML_read_envelope_geom_yx(t) {\n        t.plan(13);\n        \n        var envelope = shell_start + geoms_yx['envelope'] + shell_end;\n        var parser = new OpenLayers.Format.GML({'xy':false});\n        data = parser.read(envelope);\n        t.eq(data[0].geometry.CLASS_NAME, \"OpenLayers.Geometry.Polygon\", \"Envelope GML returns correct classname\");\n        t.eq(data[0].geometry.components[0].components[0].x, 0, \"first x coord correct\");\n        t.eq(data[0].geometry.components[0].components[0].y, 1, \"first y coord correct\");\n        t.eq(data[0].geometry.components[0].components[1].x, 20, \"second x coord correct\");\n        t.eq(data[0].geometry.components[0].components[1].y, 1, \"second y coord correct\");\n        t.eq(data[0].geometry.components[0].components[2].x, 20, \"third x coord correct\");\n        t.eq(data[0].geometry.components[0].components[2].y, 21, \"third y coord correct\");\n        t.eq(data[0].geometry.components[0].components[3].x, 0, \"fouth x coord correct\");\n        t.eq(data[0].geometry.components[0].components[3].y, 21, \"fourth y coord correct\");\n        t.eq(data[0].geometry.components[0].components[4].x, 0, \"fifth x coord correct\");\n        t.eq(data[0].geometry.components[0].components[4].y, 1, \"fifth y coord correct\");\n        t.eq(data[0].geometry.components[0].components.length, 5, \"coords length correct\");\n        t.eq(data[0].geometry.components.length, 1, \"rings length correct\");\n    }\n    \n    function test_Format_GML_write_geoms_yx(t) {\n        t.plan(5);\n        var parser = new OpenLayers.Format.GML({'xy':false});\n        \n        var point_xy = shell_start + serialize_geoms['point'] + shell_end;\n        var point = shell_start + serialize_geoms_yx['point'] + shell_end;\n        data = parser.read(point);\n        var output = parser.write(data);\n        var output = output.replace(/<\\?[^>]*\\?>/, ''); // Remove XML Prolog\n        t.eq(output, point_xy, \"Point geometry round trips correctly.\");\n        \n        var linestring_xy = shell_start + serialize_geoms['linestring'] + shell_end;\n        var linestring = shell_start + serialize_geoms_yx['linestring'] + shell_end;\n        data = parser.read(linestring);\n        var output = parser.write(data);\n        var output = output.replace(/<\\?[^>]*\\?>/, ''); // Remove XML Prolog\n        t.eq(output, linestring_xy, \"Line geometry round trips correctly.\");\n        \n        var polygon_xy = shell_start + serialize_geoms['polygon'] + shell_end;\n        var polygon = shell_start + serialize_geoms_yx['polygon'] + shell_end;\n        data = parser.read(polygon);\n        var output = parser.write(data);\n        output = output.replace(/<\\?[^>]*\\?>/, ''); // Remove XML Prolog\n        t.eq(output, polygon_xy, \"Poly geometry round trips correctly.\");\n        \n        var multipoint_xy = shell_start + serialize_geoms['multipoint'] + shell_end;\n        var multipoint = shell_start + serialize_geoms_yx['multipoint'] + shell_end;\n        data = parser.read(multipoint);\n        var output = parser.write(data);\n        var output = output.replace(/<\\?[^>]*\\?>/, ''); // Remove XML Prolog\n        t.eq(output, multipoint_xy, \"MultiPoint geometry round trips correctly.\");\n        \n        var multilinestring_xy = shell_start + serialize_geoms['multilinestring'] + shell_end;\n        var multilinestring = shell_start + serialize_geoms_yx['multilinestring'] + shell_end;\n        data = parser.read(multilinestring);\n        var output = parser.write(data);\n        var output = output.replace(/<\\?[^>]*\\?>/, ''); // Remove XML Prolog\n        t.eq(output, multilinestring_xy, \"MultiLine geometry round trips correctly.\");\n    }\n    \n    function test_buildGeometryNode_bounds(t) {\n        t.plan(1);\n        var parser = new OpenLayers.Format.GML();\n        var bounds = new OpenLayers.Bounds(-180, -90, 180, 90);\n        var output, expect;\n        \n        // test that bounds are written as gml:Box\n        var output = parser.buildGeometryNode(bounds);\n        var expect = '<gml:Box xmlns:gml=\"http://www.opengis.net/gml\"><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">-180,-90 180,90</gml:coordinates></gml:Box>';\n        t.xml_eq(output, expect, \"[xy true] Bounds correctly written as gml:Box\");\n    }\n    \n    function test_parseFeatureBox(t) {\n        t.plan(8); \n        var parser = new OpenLayers.Format.GML();\n        var xmlparser = new OpenLayers.Format.XML();\n\n        var data = xmlparser.read(test_box[0]);\n        var feature = parser.parseFeature(data);\n        t.ok(feature.bounds instanceof OpenLayers.Bounds, \n             \"got bounds object for feature.bounds when with boundedBy Box, without geometry\");\n        t.eq(feature.geometry, null, 'geometry is null for a feature with boundedBy Box, but no geometry');\n\n        var data = xmlparser.read(test_box[1]);\n        feature = parser.parseFeature(data);\n        t.eq(feature.bounds, null,\n             \"feature is null when without boundedBy Box, with Box geometry\");\n        t.ok(feature.geometry instanceof OpenLayers.Geometry.Polygon,\n             \"got polygon object for feature.geometry when without boundedBy Box, with Box geometry\");\n\n        data = xmlparser.read(test_box[2]);\n        feature = parser.parseFeature(data);\n        t.eq(feature.bounds, null, \n             \"feature.bounds is null when without boundedBy Box, without geometry\");\n        t.eq(feature.geometry, null, 'geometry is null when without boundedBy Box, without geometry');\n\n        data = xmlparser.read(test_box[3]);\n        feature = parser.parseFeature(data);\n        t.ok(feature.bounds instanceof OpenLayers.Bounds, \n             \"got bounds object for feature.bounds when with boundedBy Box, with Box geometry\");\n        t.ok(feature.geometry instanceof OpenLayers.Geometry.Polygon,\n             \"got polygon object for feature.geometry when with boundedBy Box, with Box geometry\");\n    }\n    \n    var test_box = [\n        // with boundedBy Box, without geometry\n        '<Sentiers_littoraux_feature><gml:boundedBy xmlns:gml=\"http://www.opengis.net/gml\"><gml:Box srsName=\"EPSG:2154\"><gml:coordinates>143564.081753,6817901.121957 144209.641321,6819104.781451</gml:coordinates></gml:Box></gml:boundedBy><DEPARTEMENT>Finistère</DEPARTEMENT></Sentiers_littoraux_feature>',\n        // without boundedBy Box, with Box geometry\n        '<Sentiers_littoraux_feature><msGeometry><gml:Box srsName=\"EPSG:2154\" xmlns:gml=\"http://www.opengis.net/gml\"><gml:coordinates>143564.081753,6817901.121957 144209.641321,6819104.781451</gml:coordinates></gml:Box></msGeometry><DEPARTEMENT>Finistère</DEPARTEMENT></Sentiers_littoraux_feature>',\n        // without boundedBy, without geometry\n        '<Sentiers_littoraux_feature><DEPARTEMENT>Finistère</DEPARTEMENT></Sentiers_littoraux_feature>',\n        // with boundedBy Box, with Box geometry\n        '<Sentiers_littoraux_feature><msGeometry><gml:Box srsName=\"EPSG:2154\" xmlns:gml=\"http://www.opengis.net/gml\"><gml:coordinates>143564.081753,6817901.121957 144209.641321,6819104.781451</gml:coordinates></gml:Box></msGeometry><gml:boundedBy xmlns:gml=\"http://www.opengis.net/gml\"><gml:Box srsName=\"EPSG:2154\"><gml:coordinates>143564.081753,6817901.121957 144209.641321,6819104.781451</gml:coordinates></gml:Box></gml:boundedBy><DEPARTEMENT>Finistère</DEPARTEMENT></Sentiers_littoraux_feature>'];\n\n    var test_content = ['<?xml version=\"1.0\" encoding=\"utf-8\" ?>\\n<ogr:FeatureCollection\\n     xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\\n     xsi:schemaLocation=\"http://ogr.maptools.org/ testoutput.xsd\"\\n     xmlns:ogr=\"http://ogr.maptools.org/\"\\n     xmlns:gml=\"http://www.opengis.net/gml\">\\n  <gml:boundedBy>\\n    <gml:Box>\\n      <gml:coord><gml:X>-1254041.389711702</gml:X><gml:Y>250906.9515983529</gml:Y></gml:coord>\\n      <gml:coord><gml:X>-634517.1199908922</gml:X><gml:Y>762236.2940800377</gml:Y></gml:coord>\\n    </gml:Box>\\n  </gml:boundedBy>                    \\n  <gml:featureMember>\\n    <ogr:states fid=\"F0\">\\n      <ogr:geometryProperty><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>-634517.11999089224,691849.77929356066,0 -653761.64509297756,471181.53429472551,0 -673343.60852865304,250906.9515983529,0 -1088825.734430399,299284.85108220269,0 -1254041.3897117018,324729.27754874947,0 -1235750.4212498858,434167.33911316615,0 -1190777.7803201093,704392.96327195223,0 -1181607.835811228,762236.29408003774,0 -634517.11999089224,691849.77929356066,0</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></ogr:geometryProperty>\\n      <ogr:NAME>WY</ogr:NAME>\\n    <ogr:EMPTYATTR/><ogr:LONGNAME><![CDATA[Wyoming]]></ogr:LONGNAME>\\n    </ogr:states>\\n  </gml:featureMember>\\n</ogr:FeatureCollection>\\n',\n '<wfs:FeatureCollection' + \n '   xmlns:fs=\"http://example.com/featureserver\"' + \n '   xmlns:wfs=\"http://www.opengis.net/wfs\"' + \n '   xmlns:gml=\"http://www.opengis.net/gml\"' + \n '   xmlns:ogc=\"http://www.opengis.net/ogc\"' + \n '   xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"' + \n '   xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengeospatial.net//wfs/1.0.0/WFS-basic.xsd\">' + \n '        ' + \n '' + \n '        <gml:featureMember>' + \n '  \\n<fs:scribble fid=\"221\">' + \n '        <fs:geometry>' + \n '        <gml:Polygon>' + \n '              ' + \n '              <gml:outerBoundaryIs><gml:LinearRing>' + \n '              <gml:coordinates>149.105072021,-35.1816558838 149.100608826,-35.1844024658 149.098892212,-35.1898956299  149.105072021,-35.1816558838</gml:coordinates>' + \n '              </gml:LinearRing></gml:outerBoundaryIs>' + \n '             ' + \n '              </gml:Polygon>' + \n '        </fs:geometry>' + \n '        <fs:title>random test features</fs:title>' + \n '        </fs:scribble>' + \n '</gml:featureMember> ' +\n ' <gml:featureMember><fs:scribble fid=\"8\">    <fs:geometry>        <gml:Point><gml:coordinates>-81.38671875,27.0703125</gml:coordinates></gml:Point>         </fs:geometry> ' +\n '        <fs:down>south</fs:down><fs:title>Florida</fs:title>        </fs:scribble></gml:featureMember>' + \n '</wfs:FeatureCollection>'\n ];\n   \n    var shell_start = '<wfs:FeatureCollection xmlns:wfs=\"http://www.opengis.net/wfs\"><gml:featureMember xmlns:gml=\"http://www.opengis.net/gml\"><feature:features xmlns:feature=\"http://mapserver.gis.umn.edu/mapserver\" fid=\"221\"><feature:geometry>'; \n    if (OpenLayers.BROWSER_NAME == \"opera\") {\n        shell_start = '<wfs:FeatureCollection xmlns:wfs=\"http://www.opengis.net/wfs\"><gml:featureMember xmlns:gml=\"http://www.opengis.net/gml\"><feature:features fid=\"221\" xmlns:feature=\"http://mapserver.gis.umn.edu/mapserver\"><feature:geometry>'; \n    }    \n    var shell_end = '</feature:geometry></feature:features></gml:featureMember></wfs:FeatureCollection>';\n    var serialize_geoms = {\n        'point': '<gml:Point><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2</gml:coordinates></gml:Point>',\n        'linestring': '<gml:LineString><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2 4,5</gml:coordinates></gml:LineString>',\n        'polygon': '<gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2 4,5 3,6 1,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon>',\n        'multipoint': '<gml:MultiPoint><gml:pointMember><gml:Point><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">4,5</gml:coordinates></gml:Point></gml:pointMember></gml:MultiPoint>',\n        'multilinestring': '<gml:MultiLineString><gml:lineStringMember><gml:LineString><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2 4,5</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">11,12 14,15</gml:coordinates></gml:LineString></gml:lineStringMember></gml:MultiLineString>'\n    };\n    var geoms = {\n        'point': '<gml:Point><gml:coordinates>1,2,3</gml:coordinates></gml:Point>',\n        'linestring': '<gml:LineString><gml:coordinates>1,2,3 4,5,6</gml:coordinates></gml:LineString>',\n        'polygon': '<gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>1,2 4,5 3,6 1,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon>',\n        'polygon_with_holes': '<gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>1,2 4,5 3,6 1,2</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:coordinates>11,12 14,15 13,16 11,12</gml:coordinates></gml:LinearRing></gml:innerBoundaryIs></gml:Polygon>',\n        'multipoint': '<gml:MultiPoint><gml:Point><gml:coordinates>1,2,3</gml:coordinates></gml:Point><gml:Point><gml:coordinates>4,5,6</gml:coordinates></gml:Point></gml:MultiPoint>',\n        'multilinestring': '<gml:MultiLineString><gml:LineString><gml:coordinates>1,2,3 4,5,6</gml:coordinates></gml:LineString><gml:LineString><gml:coordinates>11,12,13 14,15,16</gml:coordinates></gml:LineString></gml:MultiLineString>',\n        'envelope': '<gml:Envelope><gml:lowerCorner>0 1</gml:lowerCorner><gml:upperCorner>20 21</gml:upperCorner></gml:Envelope>' // ,\n        // 'multipolygon_with_holes': '<gml:MultiPolygon><gml:Polygon><gml:outerBoundaryIs>1,2 4,5 3,6 1,2</gml:outerBoundaryIs><gml:innerBoundaryIs>11,12 14,15 13,16 11,12</gml:innerBoundaryIs></gml:Polygon><gml:Polygon><gml:outerBoundaryIs>101,102 104,105 103,106 101,102</gml:outerBoundaryIs><gml:innerBoundaryIs>111,112 114,115 113,116 111,112</gml:innerBoundaryIs></gml:Polygon></gml:MultiPolygon>'\n    };\n\n\n//\n// The following data has the (x y) reordered to (y x), in 3 dimensions it goes from (x y z) to (y x z)\n//\n    \n    var serialize_geoms_yx = {\n        'point': '<gml:Point><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">2,1</gml:coordinates></gml:Point>',\n        'linestring': '<gml:LineString><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">2,1 5,4</gml:coordinates></gml:LineString>',\n        'polygon': '<gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">2,1 5,4 6,3 2,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon>',\n        'multipoint': '<gml:MultiPoint><gml:pointMember><gml:Point><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">2,1</gml:coordinates></gml:Point></gml:pointMember><gml:pointMember><gml:Point><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">5,4</gml:coordinates></gml:Point></gml:pointMember></gml:MultiPoint>',\n        'multilinestring': '<gml:MultiLineString><gml:lineStringMember><gml:LineString><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">2,1 5,4</gml:coordinates></gml:LineString></gml:lineStringMember><gml:lineStringMember><gml:LineString><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">12,11 15,14</gml:coordinates></gml:LineString></gml:lineStringMember></gml:MultiLineString>'\n    };\n    var geoms_yx = {\n        'point': '<gml:Point><gml:coordinates>2,1,3</gml:coordinates></gml:Point>',\n        'linestring': '<gml:LineString><gml:coordinates>2,1,3 5,4,6</gml:coordinates></gml:LineString>',\n        'polygon': '<gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2,1 5,4 6,3 2,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon>',\n        'polygon_with_holes': '<gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>2,1 5,4 6,3 2,1</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs><gml:innerBoundaryIs><gml:LinearRing><gml:coordinates>12,11 15,14 16,13 12,11</gml:coordinates></gml:LinearRing></gml:innerBoundaryIs></gml:Polygon>',\n        'multipoint': '<gml:MultiPoint><gml:Point><gml:coordinates>2,1,3</gml:coordinates></gml:Point><gml:Point><gml:coordinates>5,4,6</gml:coordinates></gml:Point></gml:MultiPoint>',\n        'multilinestring': '<gml:MultiLineString><gml:LineString><gml:coordinates>2,1,3 5,4,6</gml:coordinates></gml:LineString><gml:LineString><gml:coordinates>12,11,13 15,14,16</gml:coordinates></gml:LineString></gml:MultiLineString>',\n        'envelope': '<gml:Envelope><gml:lowerCorner>1 0</gml:lowerCorner><gml:upperCorner>21 20</gml:upperCorner></gml:Envelope>'\n    };\n    \n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/GPX.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    \n    var gpx_data = '<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><gpx version=\"1.1\" creator=\"Memory-Map 5.1.3.715 http://www.memory-map.com\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.topografix.com/GPX/1/1\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\"><wpt lat=\"51.3697845627\" lon=\"-0.1853562259\"><name>Mark</name><desc>A waypoint</desc><sym><![CDATA[Flag]]></sym><type><![CDATA[Marks]]></type></wpt><rte><name><![CDATA[Route8]]></name><desc>A route</desc><type><![CDATA[Route]]></type><rtept lat=\"51.3761803674\" lon=\"-0.1829991904\"><name><![CDATA[WP0801]]></name><desc>Some waypoints</desc><sym><![CDATA[Dot]]></sym><type><![CDATA[Waypoints]]></type></rtept><rtept lat=\"51.3697894659\" lon=\"-0.1758887005\"><name><![CDATA[WP0802]]></name><desc>More waypoints</desc><sym><![CDATA[Dot]]></sym><type><![CDATA[Waypoints]]></type></rtept><rtept lat=\"51.3639790884\" lon=\"-0.1833202965\"><name><![CDATA[WP0803]]></name><desc>Even more waypoints</desc><sym><![CDATA[Dot]]></sym><type><![CDATA[Waypoints]]></type></rtept><rtept lat=\"51.3567607069\" lon=\"-0.1751119509\"><name><![CDATA[WP0804]]></name><desc>The final run of waypoints</desc><sym><![CDATA[Dot]]></sym><type><![CDATA[Waypoints]]></type></rtept></rte><trk><name><![CDATA[Track]]></name><desc>A track</desc><type><![CDATA[Track]]></type><trkseg><trkpt lat=\"51.3768216433\" lon=\"-0.1721292044\"></trkpt><trkpt lat=\"51.3708337670\" lon=\"-0.1649230916\"></trkpt><trkpt lat=\"51.3644368725\" lon=\"-0.1736741378\"></trkpt><trkpt lat=\"51.3576354272\" lon=\"-0.1662595250\"></trkpt></trkseg></trk></gpx>';\n    \n    function test_Format_GPX_constructor(t) { \n        t.plan(5); \n         \n        var options = {'foo': 'bar'}; \n        var format = new OpenLayers.Format.GPX(options); \n        t.ok(format instanceof OpenLayers.Format.GPX, \n             \"new OpenLayers.Format.GPX returns object\" ); \n        t.eq(format.foo, \"bar\", \"constructor sets options correctly\"); \n        t.eq(typeof format.read, \"function\", \"format has a read function\"); \n        t.eq(typeof format.write, \"function\", \"format has a write function\"); \n        t.eq(format.externalProjection.getCode(), \"EPSG:4326\", \n             \"default external projection is EPSG:4326\"); \n    }\n    function test_Format_GPX_read(t) {\n        t.plan(7);\n        \n        var origDefaultPrecision = OpenLayers.Util.DEFAULT_PRECISION;\n        OpenLayers.Util.DEFAULT_PRECISION = 9;\n        \n        var expected,\n            P = OpenLayers.Geometry.Point,\n            LS = OpenLayers.Geometry.LineString;\n        var f = new OpenLayers.Format.GPX();\n        var features = f.read(gpx_data);\n        t.eq(features.length, 3, \"Number of features read is correct\");\n        expected = new P(-0.1853562259, 51.3697845627);\n        t.geom_eq(features[2].geometry, expected, \"waypoint feature correctly created\");\n        expected = new LS([\n                new P(-0.1721292044, 51.3768216433),\n                new P(-0.1649230916, 51.370833767),\n                new P(-0.1736741378, 51.3644368725),\n                new P(-0.166259525, 51.3576354272)\n        ]);\n        t.geom_eq(features[0].geometry, expected, \"track feature correctly created\");\n        expected = new LS([\n                new P(-0.1829991904, 51.3761803674),\n                new P(-0.1758887005, 51.3697894659),\n                new P(-0.1833202965, 51.3639790884),\n                new P(-0.1751119509, 51.3567607069)\n        ]);\n        t.geom_eq(features[1].geometry, expected, \"route feature correctly created\");\n\n        f.internalProjection = new OpenLayers.Projection(\"EPSG:3857\");\n        features = f.read(gpx_data);\n        expected = new P(-20633.760679678744, 6686966.841929403);\n        t.geom_eq(features[2].geometry, expected, \"transformed waypoint feature correctly created\");\n        expected = new LS([\n                new P(-19161.33538179203, 6688221.743275255),\n                new P(-18359.1545744088, 6687153.931130851),\n                new P(-19333.316581165607, 6686013.33343931),\n                new P(-18507.925659955214, 6684800.777090962)\n        ]);\n        t.geom_eq(features[0].geometry, expected, \"transformed track feature correctly created\");\n        expected = new LS([\n                new P(-20371.3766880736, 6688107.378491073),\n                new P(-19579.84057322507, 6686967.716235109),\n                new P(-20407.12205561124, 6685931.714395953),\n                new P(-19493.373203291227, 6684644.845706556)\n        ]);\n        t.geom_eq(features[1].geometry, expected, \"transformed route feature correctly created\");\n\n        OpenLayers.Util.DEFAULT_PRECISION = origDefaultPrecision;\n    }\n    function test_format_GPX_read_attributes(t) {\n        t.plan(2);\n        var f = new OpenLayers.Format.GPX();\n        var features = f.read(gpx_data);\n        t.eq(features[2].attributes['name'], \"Mark\", \"Text attribute node read correctly.\");\n        t.eq(features[2].attributes['sym'], \"Flag\", \"CDATA attribute node read correctly.\");\n    }\n    function test_Format_GPX_serialize_points(t) { \n        t.plan(2);\n\n        var parser = new OpenLayers.Format.GPX();\n\n        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);  \n        var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68); \n        var features = [\n            new OpenLayers.Feature.Vector(point, {name: 'foo', description: 'bar'}),\n            new OpenLayers.Feature.Vector(point2, {name: 'foo', description: 'bar'})\n        ];\n        var data = parser.write(features);\n        t.xml_eq(data, '<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" version=\"1.1\" creator=\"OpenLayers\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><wpt lon=\"-111.04\" lat=\"45.68\"><name>foo</name><desc>bar</desc></wpt><wpt lon=\"-112.04\" lat=\"45.68\"><name>foo</name><desc>bar</desc></wpt></gpx>', 'GPX serializes points correctly');\n\n        parser.internalProjection = new OpenLayers.Projection(\"EPSG:3857\");\n        point = new OpenLayers.Geometry.Point(-12367595.42541111, 5621521.485409545);  \n        point2 = new OpenLayers.Geometry.Point(-12472235.746742222, 5621521.485409545); \n        features = [\n            new OpenLayers.Feature.Vector(point, {name: 'foo', description: 'bar'}),\n            new OpenLayers.Feature.Vector(point2, {name: 'foo', description: 'bar'})\n        ];\n        data = parser.write(features);\n        t.xml_eq(data, '<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" version=\"1.1\" creator=\"OpenLayers\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><wpt lon=\"-111.1\" lat=\"45\"><name>foo</name><desc>bar</desc></wpt><wpt lon=\"-112.04\" lat=\"45\"><name>foo</name><desc>bar</desc></wpt></gpx>', 'GPX serializes transformed points correctly');\n    }\n    function test_Format_GPX_serialize_line(t) { \n        t.plan(2);\n\n        var parser = new OpenLayers.Format.GPX();\n\n        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);  \n        var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68); \n        var line = new OpenLayers.Geometry.LineString([point, point2]);\n        var f = new OpenLayers.Feature.Vector(line, {name: 'foo', description: 'bar'});\n        var data = parser.write(f);\n        t.xml_eq(data, '<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" version=\"1.1\" creator=\"OpenLayers\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon=\"-111.04\" lat=\"45.68\"/><trkpt lon=\"-112.04\" lat=\"45.68\"/></trkseg></trk></gpx>', 'GPX serializes line correctly');\n\n        parser.internalProjection = new OpenLayers.Projection(\"EPSG:3857\");\n        point = new OpenLayers.Geometry.Point(-12367595.42541111, 5621521.485409545);  \n        point2 = new OpenLayers.Geometry.Point(-12472235.746742222, 5621521.485409545); \n        line = new OpenLayers.Geometry.LineString([point, point2]);\n        f = new OpenLayers.Feature.Vector(line, {name: 'foo', description: 'bar'});\n        data = parser.write(f);\n        t.xml_eq(data, '<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" version=\"1.1\" creator=\"OpenLayers\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon=\"-111.1\" lat=\"45\"/><trkpt lon=\"-112.04\" lat=\"45\"/></trkseg></trk></gpx>', 'GPX serializes transformed line correctly');\n    }\n    function test_Format_GPX_serialize_lines(t) { \n        t.plan(1);\n\n        var parser = new OpenLayers.Format.GPX();\n\n        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);  \n        var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68); \n        var line = new OpenLayers.Geometry.LineString([point, point2]);\n        var point3 = new OpenLayers.Geometry.Point(1, 2);  \n        var point4 = new OpenLayers.Geometry.Point(3, 4); \n        var line2 = new OpenLayers.Geometry.LineString([point3, point4]);\n        var f = new OpenLayers.Feature.Vector(line, {name: 'foo', description: 'bar'});\n        var f2 = new OpenLayers.Feature.Vector(line2, {name: 'dude', description: 'truite'});\n        var data = parser.write([f, f2]);\n        t.xml_eq(data, '<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" version=\"1.1\" creator=\"OpenLayers\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon=\"-111.04\" lat=\"45.68\"/><trkpt lon=\"-112.04\" lat=\"45.68\"/></trkseg></trk><trk><name>dude</name><desc>truite</desc><trkseg><trkpt lon=\"1\" lat=\"2\"/><trkpt lon=\"3\" lat=\"4\"/></trkseg></trk></gpx>', 'GPX serializes lines correctly');\n    }\n    function test_Format_GPX_serialize_multiline(t) { \n        t.plan(1);\n\n        var parser = new OpenLayers.Format.GPX();\n\n        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);  \n        var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68); \n        var line = new OpenLayers.Geometry.LineString([point, point2]);\n        var point3 = new OpenLayers.Geometry.Point(1, 2);  \n        var point4 = new OpenLayers.Geometry.Point(3, 4); \n        var line2 = new OpenLayers.Geometry.LineString([point3, point4]);\n        var multiline = new OpenLayers.Geometry.MultiLineString([line, line2]);\n        var f = new OpenLayers.Feature.Vector(multiline, {name: 'foo', description: 'bar'});\n        var data = parser.write([f]);\n        t.xml_eq(data, '<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" version=\"1.1\" creator=\"OpenLayers\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon=\"-111.04\" lat=\"45.68\"/><trkpt lon=\"-112.04\" lat=\"45.68\"/></trkseg><trkseg><trkpt lon=\"1\" lat=\"2\"/><trkpt lon=\"3\" lat=\"4\"/></trkseg></trk></gpx>', 'GPX serializes multiline correctly');\n    }\n    function test_Format_GPX_serialize_polygon(t) { \n        t.plan(1);\n\n        var parser = new OpenLayers.Format.GPX();\n\n        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);  \n        var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68); \n        var linearRing = new OpenLayers.Geometry.LinearRing([point, point2, point.clone()]);\n        var polygon = new OpenLayers.Geometry.Polygon([linearRing]);\n        var f = new OpenLayers.Feature.Vector(polygon, {name: 'foo', description: 'bar'});\n        var data = parser.write([f]);\n        t.xml_eq(data, '<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" version=\"1.1\" creator=\"OpenLayers\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><trk><name>foo</name><desc>bar</desc><trkseg><trkpt lon=\"-111.04\" lat=\"45.68\"/><trkpt lon=\"-112.04\" lat=\"45.68\"/><trkpt lon=\"-111.04\" lat=\"45.68\"/></trkseg></trk></gpx>', 'GPX serializes polygon correctly');\n    }\n    function test_Format_GPX_serialize_metadata(t) { \n        t.plan(1);\n\n        var parser = new OpenLayers.Format.GPX();\n\n        var data = parser.write([], {name: 'foo', desc: 'bar'});\n        t.xml_eq(data, '<gpx xmlns=\"http://www.topografix.com/GPX/1/1\" version=\"1.1\" creator=\"OpenLayers\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><metadata><name>foo</name><desc>bar</desc></metadata></gpx>', 'GPX serializes metadata correctly');\n    }\n    function test_Format_GPX_description_roundtrip(t) {\n        // especifically written to test for mismatch between <desc> element and .description attribute\n        // as seen in github issue https://github.com/openlayers/openlayers/issues/267\n        t.plan(2);\n\n        var parser = new OpenLayers.Format.GPX();\n        var features = parser.read(gpx_data);\n\n        features[2].attributes['description'] = \"A waypoint, but different\"\n        var re_gpx_data = parser.write(features);\n        var re_features = parser.read(re_gpx_data);\n\n        // this tests the fix for issue 267\n        t.eq(re_features[1].attributes['desc'], features[1].attributes['desc'], \"GPX <desc> xml element roundtrip to .desc js attribute, back to xml, and back to js successful\");\n        // this tests for regressions against previous behaviour\n        t.eq(re_features[2].attributes['desc'], features[2].attributes['description'], \"GPX exports the .description attribute to a <desc> xml node, and it gets correctly imported into a .desc attribute\");\n    }\n\n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/GeoJSON.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    var poly_content = '{\"type\": \"FeatureCollection\", \"features\": [{\"geometry\": {\"type\": \"Polygon\", \"coordinates\": [[[-131.484375, -5.9765625], [-112.5, -58.0078125], [-32.34375, -50.2734375], [-114.609375, 52.3828125], [-167.34375, -35.5078125], [-146.953125, -57.3046875], [-139.921875, -34.1015625], [-131.484375, -5.9765625]]]}, \"type\": \"Feature\", \"id\": 562, \"properties\": {\"strokeColor\": \"red\", \"title\": \"Feature 2\", \"author\": \"Your Name Here\"}}]}'; \n    var null_geom_feature = '{\"type\":\"Feature\",\"properties\":{\"strokeColor\":\"blue\",\"title\":\"Feature 5\",\"author\":\"Your Name Here\"},\"geometry\":null,\"id\":573}';\n    var point_feature = '{\"geometry\": {\"type\": \"Point\", \"coordinates\": [94.21875, 72.94921875]}, \"type\": \"Feature\", \"id\": 573, \"properties\": {\"strokeColor\": \"blue\", \"title\": \"Feature 5\", \"author\": \"Your Name Here\"}}';\n    var line_feature = '{\"type\": \"FeatureCollection\", \"features\": [{\"geometry\": {\"type\": \"LineString\", \"coordinates\": [[-27.0703125, 59.4140625], [-77.6953125, 20.7421875], [30.5859375, -36.2109375], [67.1484375, 34.8046875]]}, \"type\": \"Feature\", \"id\": 559, \"properties\": {\"strokeColor\": \"red\", \"title\": \"Feature 1\", \"author\": \"Your Name Here\"}}]}';\n    var multiple_features = '{\"type\": \"FeatureCollection\", \"features\": [{\"geometry\": {\"type\": \"Point\", \"coordinates\": [-91.0546875, 43.9453125]}, \"type\": \"Feature\", \"id\": 577, \"properties\": {\"strokeColor\": \"red\", \"title\": \"Feature 2\", \"image\": \"foo.gif\", \"author\": \"Your Name Here\"}}, {\"geometry\": {\"type\": \"LineString\", \"coordinates\": [[91.40625, -1.40625], [116.015625, -42.890625], [153.28125, -28.125], [108.984375, 11.25], [75.234375, 8.4375], [76.640625, 9.140625], [67.5, -36.5625], [67.5, -35.859375]]}, \"type\": \"Feature\", \"id\": 576, \"properties\": {\"strokeColor\": \"red\", \"title\": \"Feature 1\", \"author\": \"Your Name Here\"}}, {\"geometry\": {\"type\": \"Point\", \"coordinates\": [139.5703125, 57.48046875]}, \"type\": \"Feature\", \"id\": 575, \"properties\": {\"strokeColor\": \"blue\", \"title\": \"Feature 7\", \"author\": \"Your Name Here\"}}, {\"geometry\": {\"type\": \"Point\", \"coordinates\": [107.2265625, 82.44140625]}, \"type\": \"Feature\", \"id\": 574, \"properties\": {\"strokeColor\": \"blue\", \"title\": \"Feature 6\", \"author\": \"Your Name Here\"}}, {\"geometry\": {\"type\": \"Point\", \"coordinates\": [94.21875, 72.94921875]}, \"type\": \"Feature\", \"id\": 573, \"properties\": {\"strokeColor\": \"blue\", \"title\": \"Feature 5\", \"author\": \"Your Name Here\"}}, {\"geometry\": {\"type\": \"Point\", \"coordinates\": [116.3671875, 61.69921875]}, \"type\": \"Feature\", \"id\": 572, \"properties\": {\"strokeColor\": \"blue\", \"title\": \"Feature 4\", \"author\": \"Your Name Here\"}}, {\"geometry\": {\"type\": \"Point\", \"coordinates\": [145.8984375, 73.65234375]}, \"type\": \"Feature\", \"id\": 571, \"properties\": {\"strokeColor\": \"blue\", \"title\": \"Feature 3\", \"author\": \"Your Name Here\"}}, {\"geometry\": {\"type\": \"Polygon\", \"coordinates\": [[[32.34375, 52.20703125], [87.1875, 70.13671875], [122.6953125, 37.44140625], [75.234375, 42.36328125], [40.078125, 42.36328125], [28.828125, 48.33984375], [18.6328125, 56.77734375], [23.203125, 65.56640625], [32.34375, 52.20703125]]]}, \"type\": \"Feature\", \"id\": 570, \"properties\": {\"strokeColor\": \"blue\", \"title\": \"Feature 2\", \"author\": \"Your Name Here\"}}, {\"geometry\": {\"type\": \"Point\", \"coordinates\": [62.578125, -53.4375]}, \"type\": \"Feature\", \"id\": 569, \"properties\": {\"strokeColor\": \"red\", \"title\": \"Feature 3\", \"author\": \"Your Name Here\"}}, {\"geometry\": {\"type\": \"Point\", \"coordinates\": [121.640625, 16.875]}, \"type\": \"Feature\", \"id\": 568, \"properties\": {\"strokeColor\": \"red\", \"title\": \"Feature 6\", \"author\": \"Your Name Here\"}}, {\"geometry\": {\"type\": \"Point\", \"coordinates\": [135.703125, 8.4375]}, \"type\": \"Feature\", \"id\": 567, \"properties\": {\"strokeColor\": \"red\", \"title\": \"Feature 4\", \"author\": \"Your Name Here\"}}, {\"geometry\": {\"type\": \"Point\", \"coordinates\": [137.109375, 48.515625]}, \"type\": \"Feature\", \"id\": 566, \"properties\": {\"strokeColor\": \"red\", \"title\": \"Feature 274\", \"author\": \"Your Name Here\"}}, {\"geometry\": {\"type\": \"Point\", \"coordinates\": [0, 5]}, \"type\": \"Feature\", \"id\": 565, \"properties\": {}}, {\"geometry\": {\"type\": \"Point\", \"coordinates\": [0, 5]}, \"type\": \"Feature\", \"id\": 564, \"properties\": {}}, {\"geometry\": {\"type\": \"Point\", \"coordinates\": [0, 5]}, \"type\": \"Feature\", \"id\": 563, \"properties\": {}}, {\"geometry\": {\"type\": \"Polygon\", \"coordinates\": [[[-131.484375, -5.9765625], [-112.5, -58.0078125], [-32.34375, -50.2734375], [-114.609375, 52.3828125], [-167.34375, -35.5078125], [-146.953125, -57.3046875], [-139.921875, -34.1015625], [-131.484375, -5.9765625]]]}, \"type\": \"Feature\", \"id\": 562, \"properties\": {\"strokeColor\": \"red\", \"title\": \"Feature 2\", \"author\": \"Your Name Here\"}}, {\"geometry\": {\"type\": \"Point\", \"coordinates\": [48.8671875, -15.8203125]}, \"type\": \"Feature\", \"id\": 560, \"properties\": {\"strokeColor\": \"red\", \"title\": \"Feature 2\", \"author\": \"Your Name Here\"}}, {\"geometry\": {\"type\": \"LineString\", \"coordinates\": [[-27.0703125, 59.4140625], [-77.6953125, 20.7421875], [30.5859375, -36.2109375], [67.1484375, 34.8046875]]}, \"type\": \"Feature\", \"id\": 559, \"properties\": {\"strokeColor\": \"red\", \"title\": \"Feature 1\", \"author\": \"Your Name Here\"}}, {\"geometry\": {\"type\": \"Point\", \"coordinates\": [12.65625, 16.5234375]}, \"type\": \"Feature\", \"id\": 558, \"properties\": {\"styleUrl\": \"#allstyle\", \"title\": \"Feature 1\", \"strokeColor\": \"red\", \"author\": \"Your Name Here\"}}]}';\n    var parser = new OpenLayers.Format.GeoJSON();\n    var data;\n\n    function test_Format_GeoJSON_constructor(t) { \n        t.plan(4); \n         \n        var options = {'foo': 'bar'}; \n        var format = new OpenLayers.Format.GeoJSON(options); \n        t.ok(format instanceof OpenLayers.Format.GeoJSON, \n             \"new OpenLayers.Format.GeoJSON returns object\" ); \n        t.eq(format.foo, \"bar\", \"constructor sets options correctly\"); \n        t.eq(typeof format.read, \"function\", \"format has a read function\"); \n        t.eq(typeof format.write, \"function\", \"format has a write function\"); \n    }\n\n    function test_Format_GeoJSON_null_geom(t) {\n        t.plan(2);\n        var f = new OpenLayers.Format.GeoJSON();\n        var fs = f.read(null_geom_feature);\n        t.ok(fs[0].geometry == null, \"Reading feature with null geom works okay\");\n        t.eq(f.write(fs[0]), null_geom_feature, \"round trip null okay\"); \n\n    }   \n    function test_Format_GeoJSON_valid_type(t) { \n        t.plan(14);\n\n        OpenLayers.Console.error = function(error) { window.global_error = error;};\n        var types = [\"Point\", \"MultiPoint\", \"LineString\", \"MultiLineString\", \"Polygon\", \"MultiPolygon\", \"Box\", \"GeometryCollection\"];\n        for (var i = 0; i < types.length; i++) {\n            t.ok(parser.isValidType({'type':types[i]}, \"Geometry\"), \"Geometry with type \" + types[i] + \" is valid\");\n        }\n        t.ok(!parser.isValidType({'type':\"foo\"}, \"Geometry\"), \"Geometry with type foo is not valid\");\n        t.eq(global_error, \"Unsupported geometry type: foo\", \"error message set correctly for 'foo' geom.\");\n        t.ok(parser.isValidType({}, \"FeatureCollection\"), \"Feature collection type is always valid\"); \n        t.ok(parser.isValidType({'type':\"GeometryCollection\"}, \"GeometryCollection\"), \"Geometry Collection type is valid\"); \n        t.ok(!parser.isValidType({'type':\"GeometryCollection2\"}, \"GeometryCollection\"), \"Geometry Collection 2 type is invalid\"); \n        t.eq(global_error, \"Cannot convert types from GeometryCollection2 to GeometryCollection\", \"error message set correctly for bad geometrycollection type\");\n    }\n\n    function test_Format_GeoJSON_point(t) { \n        t.plan(3);\n\n        data = parser.read(point_feature);\n        t.eq(data[0].fid, 573, \"Fid is correct on point feature\"); \n        t.eq(data[0].geometry.x, 94.21875, 'Reading point feature gives correct x');\n        data = parser.read(point_feature, \"Feature\");\n        t.eq(data.fid, 573, 'Reading point feature with type gives feature instead of array of features ');\n    }\n\n    function test_Format_GeoJSON_line(t) { \n        t.plan(5);\n\n        data = parser.read(line_feature);\n        t.eq(data[0].fid, 559, \"Fid is correct on line feature\"); \n        t.eq(data[0].geometry.components.length, 4, 'Reading line feature gives correct length');\n        t.eq(data[0].geometry.CLASS_NAME, 'OpenLayers.Geometry.LineString', 'Reading line feature gives correct class');\n        t.eq(data[0].geometry.components[0].x, -27.0703125, 'Reading line feature gives correct x');\n        t.eq(data[0].geometry.components[0].y, 59.4140625, 'Reading line feature gives correct y');\n    }\n\n    function test_Format_GeoJSON_poly(t) { \n        t.plan(2);\n\n        data = parser.read(poly_content);\n        t.eq(data[0].fid, 562, \"poly id is correct\");\n        t.eq(data[0].geometry.components[0].components.length, 8, \n                'Reading polygon first ring  on feature from featurecollection gives correct length');\n    }\n\n    function test_Format_GeoJSON_multipoint(t) { \n        t.plan(5);\n\n        var multipoint = {\n           \"type\": \"MultiPoint\",\n           \"coordinates\": [\n               [100.0, 0.0], [101.0, 1.0]\n           ]\n        };\n        data = parser.read(multipoint, \"Geometry\");\n        t.eq(data.components.length, 2, \n            \"Right number of components\");\n        t.eq(data.components[0].CLASS_NAME, \"OpenLayers.Geometry.Point\", \"First component is point\");    \n        t.eq(data.components[1].CLASS_NAME, \"OpenLayers.Geometry.Point\", \"Second component is point\");    \n        t.eq(data.components[1].x, 101, \"x of second component is right\");    \n        t.eq(data.components[1].y, 1, \"y of second component is right\");    \n    }\n\n    function test_Format_GeoJSON_multipoint_projected(t) {\n        t.plan(1);\n        var f = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.MultiPoint([\n            new OpenLayers.Geometry.Point(15555162, 4247484)]));\n        var format = new OpenLayers.Format.GeoJSON({\n            internalProjection: new OpenLayers.Projection(\"EPSG:900913\"),\n            externalProjection: new OpenLayers.Projection(\"EPSG:4326\")\n        });\n        var data = format.write(f);\n        var found = (data.search('139.734') != -1);\n        t.ok(found, \"Found 139.734 (correct reprojection) in data output.\");\n    }        \n\n    function test_Format_GeoJSON_multiline(t) {\n        t.plan(3);\n\n        var multiline = {\n           \"type\": \"MultiLineString\",\n           \"coordinates\": [\n               [ [100.0, 0.0], [101.0, 1.0] ],\n               [ [102.0, 2.0], [103.0, 3.0] ]\n           ]\n        };\n        data = parser.read(multiline, \"Geometry\");\n        t.eq(data.CLASS_NAME, \"OpenLayers.Geometry.MultiLineString\", \"Correct class retrieved\");\n        t.eq(data.components[0].components[0].CLASS_NAME, \"OpenLayers.Geometry.Point\", \"correct type of components\");\n        t.eq(data.components[0].CLASS_NAME, \"OpenLayers.Geometry.LineString\", \"correct type of components\");\n    }\n\n    function test_Format_GeoJSON_multipol(t) {\n        t.plan(2);\n\n        var multipol = {\n            \"type\": \"MultiPolygon\",\n            \"coordinates\": [\n                [\n                    [ [102.0, 2.0], [103.0, 2.0], [103.0, 3.0], [102.0, 3.0], [102.0, 2.0] ]\n                ],\n                [\n                    [ [100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0] ],\n                    [ [100.2, 0.2], [100.8, 0.2], [100.8, 0.8], [100.2, 0.8], [100.2, 0.2] ]\n                ]\n            ]\n        };\n        OpenLayers.Console.error = function(error) { window.global_error = error; };\n        data = parser.read(multipol, \"Geometry\");\n        t.eq(data.CLASS_NAME, \"OpenLayers.Geometry.MultiPolygon\", \"Correct class retrieved\");\n        t.eq(data.components[1].components[0].components[0].CLASS_NAME, \"OpenLayers.Geometry.Point\", \"correct type of components\");\n    }\n\n    function test_Format_GeoJSON_box(t) {\n        t.plan(6);\n\n        var box = {\n            \"type\": \"Box\",\n            \"coordinates\": [[100.0, 0.0], [101.0, 1.0]]\n        };\n        var poly = parser.read(box, \"Geometry\");\n        t.eq(poly.CLASS_NAME, \"OpenLayers.Geometry.Polygon\", \"Box creates polygon\"); \n        t.eq(poly.components[0].components[1].x, 101, \"x of lower right is correct\");\n        t.eq(poly.components[0].components[1].y, 0, \"y of lower right is correct\");\n        t.eq(poly.components[0].components[3].x, 100, \"x of upper left is correct\");\n        t.eq(poly.components[0].components[3].y, 1, \"y of upper left is correct\");\n        box = parser.write(poly );\n        t.ok(box.search(\"Polygon\") != -1 , \"Serializes back to polygon\");\n    }\n\n    // This test is from the geom_collection example on geojson spec.\n    function test_Format_GeoJSON_collection(t) {\n       t.plan(12);\n\n       var geomcol = {\n           \"type\": \"GeometryCollection\",\n           \"geometries\": [\n               {\n                   \"type\": \"Point\",\n                   \"coordinates\": [100.0, 0.0]\n               },\n               {\n                   \"type\": \"LineString\",\n                   \"coordinates\": [\n                       [101.0, 0.0], [102.0, 1.0]\n                   ]\n               }\n           ]\n        };\n        data = parser.read(geomcol, \"Geometry\");\n        t.eq(data.CLASS_NAME, \"OpenLayers.Geometry.Collection\",\n             \"GeometryCollection deserialized into geometry.collection\");  \n        t.eq(data.components[0].CLASS_NAME, \"OpenLayers.Geometry.Point\",\n             \"First geom is correct type\");  \n        t.eq(data.components[0].x, 100,\n             \"First geom in geom collection has correct x\");  \n        t.eq(data.components[0].y, 0,\n             \"First geom in geom collection has correct x\");  \n        \n        t.eq(data.components[1].CLASS_NAME, \"OpenLayers.Geometry.LineString\",\n             \"Second geom in geom collection is point linestring\");  \n        t.eq(data.components[1].components.length, 2,\n             \"linestring is correct length\");\n        t.eq(data.components[1].components[1].x, 102,\n             \"linestring is correct x end\");\n        t.eq(data.components[1].components[1].y, 1,\n             \"linestring is correct y end\");\n\n        data = parser.read(geomcol, \"FeatureCollection\");\n        t.eq(data[0].CLASS_NAME, \"OpenLayers.Feature.Vector\",\n             \"GeometryCollection can be read in as a feature collection\");\n        t.eq(data[0].geometry.CLASS_NAME, \"OpenLayers.Geometry.Collection\",\n             \"feature contains the correct geometry type\");\n        var feature = {\n           \"type\": \"Feature\",\n           \"geometry\": {\n              \"type\": \"GeometryCollection\",\n              \"geometries\": [\n                  {\n                    \"type\": \"Point\",\n                    \"coordinates\": [100.0, 0.0]\n                  },\n                  {\n                    \"type\": \"LineString\",\n                    \"coordinates\": [\n                        [101.0, 0.0], [102.0, 1.0]\n                    ]\n                  }\n              ]\n           },\n           \"properties\": {\n               \"prop0\": \"value0\",\n               \"prop1\": \"value1\"\n           }\n        };\n        data = parser.read(feature, \"Feature\");\n        t.eq(data.geometry.CLASS_NAME, \"OpenLayers.Geometry.Collection\", \"Geometry of feature is a collection\");\n        var l = new OpenLayers.Layer.Vector();\n        l.addFeatures(data);\n        t.ok(true, \"adding a feature with geomcollection to layer doesn't cause error.\"); \n    }\n\n    function test_Format_GeoJSON_multipleFeatures(t) {\n        t.plan(2);\n\n        var feats = parser.read(multiple_features);\n        t.eq(feats.length, 19, \"parsing a feature collection returns the correct number of features.\");\n        var types = {'Point':0, 'LineString':0, 'Polygon':0};\n        for(var i = 0; i < feats.length; i++) {\n            var type = feats[i].geometry.CLASS_NAME.replace(\"OpenLayers.Geometry.\", \"\");\n            types[type]++;\n        }\n        t.eq(types, {'Point':15, 'Polygon': 2, 'LineString':2}, \"Correct number of each type\"); \n    }\n\n    function test_Format_GeoJSON_writeWithCRS(t) {\n        t.plan(2);\n        var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,2));\n        feature.fid = 0;\n        var output = '{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Point\",\"coordinates\":[1,2]},\"id\":0,\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"urn:ogc:def:crs:OGC:1.3:CRS84\"}}}';\n        var layer = new OpenLayers.Layer.Vector();\n        layer.projection = \"EPSG:4326\";\n        feature.layer = layer;\n        var parser = new OpenLayers.Format.GeoJSON();\n        var test_out = parser.write(feature);\n        t.eq(test_out, output, \"Output is equal for vector with layer in EPSG:4326 \");\n        feature.layer.projection = \"EPSG:2805\";\n        output = '{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Point\",\"coordinates\":[1,2]},\"id\":0,\"crs\":{\"type\":\"name\",\"properties\":{\"name\":\"EPSG:2805\"}}}';\n        test_out = parser.write(feature);\n        t.eq(test_out, output, \"Output is equal for vector with point\");\n    }    \n        \n    function test_Format_GeoJSON_write(t) {\n        t.plan(10);\n\n        var line_object = {\n            \"type\": \"FeatureCollection\", \n            \"features\": [\n                {\n                    \"geometry\": {\n                        \"type\": \"LineString\", \n                        \"coordinates\": [\n                            [-27.0703125, 59.4140625], \n                            [-77.6953125, 20.7421875], \n                            [30.5859375, -36.2109375], \n                            [67.1484375, 34.8046875]\n                        ]\n                    },\n                    \"type\": \"Feature\", \n                    \"id\": 559, \n                    \"properties\": {\n                        \"strokeColor\": \"red\", \n                        \"title\": \"Feature 1\", \n                        \"author\": \"Your Name Here\"\n                    }\n                }\n            ]\n        };\n        data = parser.read(line_object);\n        out = parser.write(data);\n        serialized = '{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"properties\":{\"strokeColor\":\"red\",\"title\":\"Feature 1\",\"author\":\"Your Name Here\"},\"geometry\":{\"type\":\"LineString\",\"coordinates\":[[-27.0703125,59.4140625],[-77.6953125,20.7421875],[30.5859375,-36.2109375],[67.1484375,34.8046875]]},\"id\":559}]}';\n        t.eq(out, serialized, \"input and output on line collections are the same\");\n        \n        var serialize_tests = [\n            [\n                new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,2)),\n                '{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Point\",\"coordinates\":[1,2]},\"id\":0}'\n            ],\n            [\n                new OpenLayers.Geometry.Point(1,2), \n                '{\"type\":\"Point\",\"coordinates\":[1,2]}'\n            ], \n            [\n                new OpenLayers.Geometry.MultiPoint([\n                    new OpenLayers.Geometry.Point(1,2)\n                ]),\n                '{\"type\":\"MultiPoint\",\"coordinates\":[[1,2]]}'\n            ],\n            [\n                new OpenLayers.Geometry.LineString([\n                    new OpenLayers.Geometry.Point(1,2), \n                    new OpenLayers.Geometry.Point(3,4)\n                ]),\n                '{\"type\":\"LineString\",\"coordinates\":[[1,2],[3,4]]}'\n            ], \n            [\n                new OpenLayers.Geometry.Polygon([\n                    new OpenLayers.Geometry.LinearRing([\n                        new OpenLayers.Geometry.Point(1,2), \n                        new OpenLayers.Geometry.Point(3,4), \n                        new OpenLayers.Geometry.Point(5,6)\n                    ])\n                ]), \n                '{\"type\":\"Polygon\",\"coordinates\":[[[1,2],[3,4],[5,6],[1,2]]]}'\n            ],\n            [\n                new OpenLayers.Geometry.Collection([\n                    new OpenLayers.Geometry.Polygon([\n                        new OpenLayers.Geometry.LinearRing([\n                            new OpenLayers.Geometry.Point(1,2), \n                            new OpenLayers.Geometry.Point(3,4), \n                            new OpenLayers.Geometry.Point(5,6)\n                        ])\n                    ]), \n                    new OpenLayers.Geometry.LineString([\n                        new OpenLayers.Geometry.Point(1,2), \n                        new OpenLayers.Geometry.Point(3,4)\n                    ]),\n                    new OpenLayers.Geometry.Point(1,2)\n                ]),\n                '{\"type\":\"GeometryCollection\",\"geometries\":[{\"type\":\"Polygon\",\"coordinates\":[[[1,2],[3,4],[5,6],[1,2]]]},{\"type\":\"LineString\",\"coordinates\":[[1,2],[3,4]]},{\"type\":\"Point\",\"coordinates\":[1,2]}]}'\n            ]\n        ];\n        serialize_tests[0][0].fid = 0;\n        multiline = new OpenLayers.Geometry.MultiLineString([serialize_tests[3][0], serialize_tests[3][0]]);\n        serialize_tests.push([multiline, '{\"type\":\"MultiLineString\",\"coordinates\":[[[1,2],[3,4]],[[1,2],[3,4]]]}']);\n        multipolygon = new OpenLayers.Geometry.MultiPolygon([serialize_tests[4][0],  serialize_tests[4][0]]);\n        serialize_tests.push([multipolygon, '{\"type\":\"MultiPolygon\",\"coordinates\":[[[[1,2],[3,4],[5,6],[1,2]]],[[[1,2],[3,4],[5,6],[1,2]]]]}']);\n        serialize_tests.push([ [ serialize_tests[0][0] ], '{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Point\",\"coordinates\":[1,2]},\"id\":0}]}' ]);\n        for (var i = 0; i < serialize_tests.length; i++) {\n            var input = serialize_tests[i][0];\n            var output = serialize_tests[i][1];\n            test_out = parser.write(input);\n            t.eq(test_out, output, \"Serializing \" + input.toString() + \" saved correctly.\");\n        }\n    }\n\n    function test_write_no_fid(t) {\n        t.plan(4);\n\n        var geojson;\n        var feature = new OpenLayers.Feature.Vector();\n\n        feature.fid = null;\n        geojson = parser.write(feature);\n        t.eq(geojson, '{\"type\":\"Feature\",\"properties\":{},\"geometry\":null}',\n             \"no id set in the GeoJSON string when fid is null\");\n\n        feature.fid = undefined;\n        geojson = parser.write(feature);\n        t.eq(geojson, '{\"type\":\"Feature\",\"properties\":{},\"geometry\":null}',\n             \"no id set in the GeoJSON string when fid is undefined\");\n\n        feature.fid = 0;\n        geojson = parser.write(feature);\n        t.eq(geojson, '{\"type\":\"Feature\",\"properties\":{},\"geometry\":null,\"id\":0}',\n             \"id set in the GeoJSON string when fid is 0\");\n\n        delete feature.fid;\n        geojson = parser.write(feature);\n        t.eq(geojson, '{\"type\":\"Feature\",\"properties\":{},\"geometry\":null}',\n             \"id not set in the GeoJSON string when fid is delected\");\n    }\n\n    function test_Format_GeoJSON_read_object(t) {\n        t.plan(1);\n\n        var line_object = {\n            \"type\": \"FeatureCollection\", \n            \"features\": [\n                {\n                    \"geometry\": {\n                        \"type\": \"LineString\", \n                        \"coordinates\": [\n                            [-27.0703125, 59.4140625], \n                            [-77.6953125, 20.7421875], \n                            [30.5859375, -36.2109375], \n                            [67.1484375, 34.8046875]\n                        ]\n                    }, \n                    \"type\": \"Feature\", \n                    \"id\": 559, \n                    \"properties\": {\n                        \"strokeColor\": \"red\", \n                        \"title\": \"Feature 1\", \n                        \"author\": \"Your Name Here\"\n                    }\n                }\n            ]\n        };\n        data = parser.read(line_object);\n        t.eq(data[0].fid, 559, \"Can read data from an object correctly.\");\n    }\n\n    function test_Format_GeoJSON_read_attributes(t) {\n        t.plan(3);\n\n        var parser = new OpenLayers.Format.GeoJSON();\n        data = parser.read(line_feature);\n        t.eq(data[0].attributes['strokeColor'], 'red', 'read strokeColor attribute properly'); \n        t.eq(data[0].attributes['title'], 'Feature 1', 'read title attribute properly'); \n        t.eq(data[0].attributes['author'], 'Your Name Here', 'read author attribute properly'); \n    }\n\n    function test_read_bbox(t) {\n        t.plan(8);\n\n        var f;\n        parser = new OpenLayers.Format.GeoJSON();\n\n        // 4 tests\n        f = '{\"geometry\": {\"type\": \"Point\", \"coordinates\": [94.21875, 72.94921875], \"bbox\": [94.21875, 72.94921875, 94.21875, 72.94921875]}, \"type\": \"Feature\", \"id\": 573, \"properties\": {}, \"bbox\": [95.0, 73.0]}';\n        data = parser.read(f);\n        t.eq(data[0].bounds.left, 94.21875, \"read left bound is correct\");\n        t.eq(data[0].bounds.bottom, 72.94921875, \"read bottom left bound is correct\");\n        t.eq(data[0].bounds.right, 94.21875, \"read right bound is correct\");\n        t.eq(data[0].bounds.top, 72.94921875, \"read top left bound is correct\");\n\n        // 4 tests\n        f = '{\"geometry\": {\"type\": \"Point\", \"coordinates\": [94.21875, 72.94921875]}, \"type\": \"Feature\", \"id\": 573, \"properties\": {}, \"bbox\": [95.0, 73.0, 96.0, 74.0]}';\n        data = parser.read(f);\n        t.eq(data[0].bounds.left, 95.0, \"read left bound is correct\");\n        t.eq(data[0].bounds.bottom, 73.0, \"read bottom left bound is correct\");\n        t.eq(data[0].bounds.right, 96.0, \"read right bound is correct\");\n        t.eq(data[0].bounds.top, 74.0, \"read top left bound is correct\");\n    }\n\n    function test_Format_GeoJSON_point_extradims(t) { \n        t.plan(3);\n        var point_feature_3d = '{\"geometry\": {\"type\": \"Point\", \"coordinates\": [94.21875, 72.94921875, 0.0]}, \"type\": \"Feature\", \"id\": 573, \"properties\": {\"strokeColor\": \"blue\", \"title\": \"Feature 5\", \"author\": \"Your Name Here\"}}';\n        p = new OpenLayers.Format.GeoJSON({\"ignoreExtraDims\": true});\n        data = p.read(point_feature_3d);\n        t.eq(data[0].fid, 573, \"Fid is correct on point feature\"); \n        t.eq(data[0].geometry.x, 94.21875, 'Reading point feature gives correct x');\n        data = p.read(point_feature_3d, \"Feature\");\n        t.eq(data.fid, 573, 'Reading point feature with type gives feature instead of array of features ');\n    }\n\n\n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/GeoRSS.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_Format_GeoRSS_constructor(t) { \n        t.plan(4); \n         \n        var options = {'foo': 'bar'}; \n        var format = new OpenLayers.Format.GeoRSS(options); \n        t.ok(format instanceof OpenLayers.Format.GeoRSS, \n             \"new OpenLayers.Format.GeoRSS returns object\" ); \n        t.eq(format.foo, \"bar\", \"constructor sets options correctly\"); \n        t.eq(typeof format.read, \"function\", \"format has a read function\"); \n        t.eq(typeof format.write, \"function\", \"format has a write function\"); \n    }\n\n    function test_Format_GeoRSS_serializeline(t) { \n        t.plan(1);\n\n        var parser = new OpenLayers.Format.GeoRSS();\n        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);  \n        var point2 = new OpenLayers.Geometry.Point(-112.04, 45.68); \n        var l = new OpenLayers.Geometry.LineString([point, point2]);\n        var f = new OpenLayers.Feature.Vector(l);\n        var data = parser.write([f]);\n        t.xml_eq(data, '<rss xmlns=\"http://backend.userland.com/rss2\"><item><title></title><description></description><georss:line xmlns:georss=\"http://www.georss.org/georss\">45.68 -111.04 45.68 -112.04</georss:line></item></rss>', 'GeoRSS serializes a line correctly');\n    }\n    function test_Format_GeoRSS_box(t) {\n        t.plan(4);\n        var xml = '<rss xmlns=\"http://backend.userland.com/rss2\"><item><title></title><description></description><georss:box xmlns:georss=\"http://www.georss.org/georss\">45.68 -112.04 47.68 -111.04</georss:box></item></rss>';\n        var format = new OpenLayers.Format.GeoRSS();\n        var features = format.read(xml);\n        t.eq(features.length, 1, \"one feature returned\");\n        t.eq(features[0].geometry.components[0].components.length, 5, \"polygon returned\");\n        t.eq(features[0].geometry.components[0].components[0].x, -112.04, \"polygon returned with correct first x\");\n        t.eq(features[0].geometry.components[0].components[0].y, 45.68, \"polygon returned with correct first y\");\n    }\n    function test_Format_GeoRSS_w3cgeo(t) { \n        t.plan(2);\n\n        var parser = new OpenLayers.Format.GeoRSS();\n        var data = parser.read('<rss xmlns=\"http://backend.userland.com/rss2\" xmlns:geo=\"http://www.w3.org/2003/01/geo/wgs84_pos#\"><item><geo:long>-1</geo:long><geo:lat>1</geo:lat></item></rss>');\n        t.eq(data[0].geometry.x, -1, \"w3c geo x read correctly\"); \n        t.eq(data[0].geometry.y, 1, \"w3c geo y read correctly\"); \n    }\n    function test_Format_GeoRSS_reproject_null(t) { \n        t.plan(1);\n\n        var parser = new OpenLayers.Format.GeoRSS({'internalProjection':new OpenLayers.Projection(\"EPSG:4326\"), 'externalProjection': new OpenLayers.Projection(\"EPSG:4326\")});\n        var data = parser.read('<rss xmlns=\"http://backend.userland.com/rss2\" xmlns:geo=\"http://www.w3.org/2003/01/geo/wgs84_pos#\"><item></item></rss>');\n        t.eq(data.length, 1, \"Parsing items with null geometry and reprojection doesn't fail\");\n    }\n    function test_Format_GeoRSS_roundtrip(t) {\n        t.plan(input.length);\n        var parser = new OpenLayers.Format.GeoRSS();\n        for(var i=0; i < input.length; i++) {\n            var feed = shell_start+input[i]+shell_end;\n            var data = parser.read(feed);\n            var out = parser.write(data);\n            var expected_result = output[i];\n            t.xml_eq(out, expected_result, \"Output gave expected value\");\n        }\n    }\n    function test_Format_GeoRSS_gml_roundtrip(t) {\n        t.plan(input_gml.length);\n        var parser = new OpenLayers.Format.GeoRSS();\n        for(var i=0; i < input_gml.length; i++) {\n            var feed = shell_start_gml+input_gml[i]+shell_end_gml;\n            var data = parser.read(feed);\n            var out = parser.write(data);\n            var expected_result = output_gml[i];\n            t.xml_eq(out, expected_result, \"Output gave expected value\");\n        }\n    }\n\n    function test_leading_space(t) {\n        t.plan(2);\n        \n        var parser = new OpenLayers.Format.GeoRSS();\n        var items = parser.read('<rss version=\"2.0\" xmlns:georss=\"http://www.georss.org/georss\"><item><description>  <![CDATA[foo]]></description></item></rss>');\n        t.eq(items.length, 1, \"item created\");\n\n        // when parsing a node composed of both spaces and a cdata section\n        // (e.g. <description>  <![DATA[foo]]></description> IE8 ignores\n        // the leading white spaces, and reports that the node does not\n        // include a text node. For that reason, we need to trim the\n        // string value resulting from the parsing.\n\n        var description = OpenLayers.String.trim(items[0].attributes.description);\n        t.eq(description, \"foo\", \"description value is ok\");\n    }\n             \n    var shell_start = '<feed xmlns=\"http://www.w3.org/2005/Atom\" \\n              xmlns:georss=\"http://www.georss.org/georss\">\\n              <title>scribble</title>\\n              <id>http://featureserver.org/featureserver.cgi/scribble?format=atom</id>\\n              <author><name>FeatureServer</name></author>\\n';             \n    var shell_end = '</feed>'; \n    var input = ['<entry><id>http://featureserver.org/featureserver.cgi/scribble/562.atom</id><link href=\"http://featureserver.org/featureserver.cgi/scribble/562.atom\"/><title>Feature 2</title><content type=\"html\">&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</content><georss:polygon>-5.9765625 -131.484375 -58.0078125 -112.5 -50.2734375 -32.34375 52.3828125 -114.609375 -35.5078125 -167.34375 -57.3046875 -146.953125 -34.1015625 -139.921875 -5.9765625 -131.484375</georss:polygon></entry>',\n    '<entry><id>http://featureserver.org/featureserver.cgi/scribble/796.atom</id><link href=\"http://featureserver.org/featureserver.cgi/scribble/796.atom\"/><title>Feature 2</title><content type=\"html\">&lt;b&gt;strokeColor&lt;/b&gt;: 00ccff&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</content><georss:point>75.5859375 15.46875</georss:point></entry>',\n    '<entry><id>http://featureserver.org/featureserver.cgi/scribble/794.atom</id><link href=\"http://featureserver.org/featureserver.cgi/scribble/794.atom\"/><title>Feature 5</title><content type=\"html\">&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 5&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</content><georss:line>28.828125 32.6953125 49.921875 34.8046875 39.375 58.0078125 39.375 58.0078125 40.078125 58.0078125 41.484375 58.0078125 43.59375 58.0078125 45.703125 58.7109375 47.8125 58.7109375 49.21875 58.7109375 51.328125 59.4140625 52.03125 59.4140625 54.140625 60.8203125 56.25 61.5234375 56.25 62.2265625 57.65625 62.2265625 57.65625 62.9296875 58.359375 63.6328125 58.359375 65.0390625 58.359375 65.7421875 59.0625 66.4453125 59.0625 67.1484375 59.0625 68.5546875 59.765625 69.9609375 59.765625 72.0703125 59.765625 73.4765625 59.765625 76.2890625 59.765625 78.3984375 59.765625 79.8046875 59.765625 81.9140625 59.765625 83.3203125 59.0625 84.7265625 59.0625 86.8359375 58.359375 87.5390625 58.359375 88.2421875 56.953125 89.6484375 56.25 91.0546875 54.84375 93.8671875 52.03125 96.6796875 51.328125 98.7890625 50.625 100.1953125 49.21875 102.3046875 48.515625 103.7109375 47.8125 104.4140625 47.109375 105.8203125 46.40625 106.5234375 46.40625 107.9296875 45.703125 109.3359375 45 110.7421875 43.59375 112.8515625 43.59375 114.2578125 43.59375 114.9609375 42.890625 117.0703125 42.890625 117.7734375 42.1875 118.4765625 42.1875 119.1796875 42.1875 119.8828125</georss:line></entry>' \n    ];\n    var output= ['<rss xmlns=\"http://backend.userland.com/rss2\"><item><title>Feature 2</title><description>&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</description><link>http://featureserver.org/featureserver.cgi/scribble/562.atom</link><georss:polygon xmlns:georss=\"http://www.georss.org/georss\">-5.9765625 -131.484375 -58.0078125 -112.5 -50.2734375 -32.34375 52.3828125 -114.609375 -35.5078125 -167.34375 -57.3046875 -146.953125 -34.1015625 -139.921875 -5.9765625 -131.484375</georss:polygon></item></rss>',\n       '<rss xmlns=\"http://backend.userland.com/rss2\"><item><title>Feature 2</title><description>&lt;b&gt;strokeColor&lt;/b&gt;: 00ccff&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</description><link>http://featureserver.org/featureserver.cgi/scribble/796.atom</link><georss:point xmlns:georss=\"http://www.georss.org/georss\">75.5859375 15.46875</georss:point></item></rss>',\n       '<rss xmlns=\"http://backend.userland.com/rss2\"><item><title>Feature 5</title><description>&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 5&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</description><link>http://featureserver.org/featureserver.cgi/scribble/794.atom</link><georss:line xmlns:georss=\"http://www.georss.org/georss\">28.828125 32.6953125 49.921875 34.8046875 39.375 58.0078125 39.375 58.0078125 40.078125 58.0078125 41.484375 58.0078125 43.59375 58.0078125 45.703125 58.7109375 47.8125 58.7109375 49.21875 58.7109375 51.328125 59.4140625 52.03125 59.4140625 54.140625 60.8203125 56.25 61.5234375 56.25 62.2265625 57.65625 62.2265625 57.65625 62.9296875 58.359375 63.6328125 58.359375 65.0390625 58.359375 65.7421875 59.0625 66.4453125 59.0625 67.1484375 59.0625 68.5546875 59.765625 69.9609375 59.765625 72.0703125 59.765625 73.4765625 59.765625 76.2890625 59.765625 78.3984375 59.765625 79.8046875 59.765625 81.9140625 59.765625 83.3203125 59.0625 84.7265625 59.0625 86.8359375 58.359375 87.5390625 58.359375 88.2421875 56.953125 89.6484375 56.25 91.0546875 54.84375 93.8671875 52.03125 96.6796875 51.328125 98.7890625 50.625 100.1953125 49.21875 102.3046875 48.515625 103.7109375 47.8125 104.4140625 47.109375 105.8203125 46.40625 106.5234375 46.40625 107.9296875 45.703125 109.3359375 45 110.7421875 43.59375 112.8515625 43.59375 114.2578125 43.59375 114.9609375 42.890625 117.0703125 42.890625 117.7734375 42.1875 118.4765625 42.1875 119.1796875 42.1875 119.8828125</georss:line></item></rss>'   \n   ];\n   \n    var shell_start_gml = '<feed xmlns=\"http://www.w3.org/2005/Atom\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:georss=\"http://www.georss.org/georss\"> <title>scribble</title><id>http://featureserver.org/featureserver.cgi/scribble?format=atom</id><author><name>FeatureServer</name></author>';\n       var shell_end_gml = '</feed>';\n       var input_gml = ['<entry><id>http://featureserver.org/featureserver.cgi/scribble/111.atom</id><link href=\"http://featureserver.org/featureserver.cgi/scribble/111.atom\"/><title>Feature 2</title><content type=\"html\">&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</content><georss:where><gml:Point><gml:pos>0 10</gml:pos></gml:Point></georss:where></entry>',\n           '<entry><id>http://featureserver.org/featureserver.cgi/scribble/111.atom</id><link href=\"http://featureserver.org/featureserver.cgi/scribble/111.atom\"/><title>Feature 2</title><content type=\"html\">&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</content><georss:where><gml:Polygon><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>110,-50 110,-10 155,-10 155,-50 110,-50</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></georss:where></entry>',\n           '<entry><id>http://featureserver.org/featureserver.cgi/scribble/111.atom</id><link href=\"http://featureserver.org/featureserver.cgi/scribble/111.atom\"/><title>Feature 2</title><content type=\"html\">&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</content><georss:where><gml:LineString><gml:coordinates>0,10 10,20</gml:coordinates></gml:LineString></georss:where></entry>',\n           '<entry><id>http://featureserver.org/featureserver.cgi/scribble/111.atom</id><link href=\"http://featureserver.org/featureserver.cgi/scribble/111.atom\"/><title>Feature 2</title><content type=\"html\">&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</content><georss:where><gml:Envelope><gml:lowerCorner>0 1</gml:lowerCorner><gml:upperCorner>20 21</gml:upperCorner></gml:Envelope></georss:where></entry>'\n       ];\n       var output_gml = ['<rss xmlns=\"http://backend.userland.com/rss2\"><item><title>Feature 2</title><description>&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</description><link>http://featureserver.org/featureserver.cgi/scribble/111.atom</link><georss:point xmlns:georss=\"http://www.georss.org/georss\">0 10</georss:point></item></rss>',\n           '<rss xmlns=\"http://backend.userland.com/rss2\"><item><title>Feature 2</title><description>&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</description><link>http://featureserver.org/featureserver.cgi/scribble/111.atom</link><georss:polygon xmlns:georss=\"http://www.georss.org/georss\">110 -50 110 -10 155 -10 155 -50 110 -50</georss:polygon></item></rss>',\n           '<rss xmlns=\"http://backend.userland.com/rss2\"><item><title>Feature 2</title><description>&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</description><link>http://featureserver.org/featureserver.cgi/scribble/111.atom</link><georss:line xmlns:georss=\"http://www.georss.org/georss\">0 10 10 20</georss:line></item></rss>',\n           '<rss xmlns=\"http://backend.userland.com/rss2\"><item><title>Feature 2</title><description>&lt;b&gt;strokeColor&lt;/b&gt;: red&lt;br /&gt;&lt;b&gt;title&lt;/b&gt;: Feature 2&lt;br /&gt;&lt;b&gt;author&lt;/b&gt;: Your Name Here</description><link>http://featureserver.org/featureserver.cgi/scribble/111.atom</link><georss:polygon xmlns:georss=\"http://www.georss.org/georss\">0 1 0 21 20 21 20 1 0 1</georss:polygon></item></rss>'\n       ];\n\n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/JSON.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_Format_JSON_constructor(t) { \n        t.plan(4); \n         \n        var options = {'foo': 'bar'}; \n        var format = new OpenLayers.Format.JSON(options); \n        t.ok(format instanceof OpenLayers.Format.JSON, \n             \"new OpenLayers.Format.JSON returns object\" ); \n        t.eq(format.foo, \"bar\", \"constructor sets options correctly\"); \n        t.eq(typeof format.read, \"function\", \"format has a read function\"); \n        t.eq(typeof format.write, \"function\", \"format has a write function\"); \n    }\n\n    function test_Format_JSON_parser(t) { \n        t.plan(2); \n         \n        var format = new OpenLayers.Format.JSON(); \n        var data = format.read('{\"a\":[\"b\"], \"c\":1}');\n        var obj = {\"a\":[\"b\"], \"c\":1};\n        t.eq(obj['a'], data['a'], \"element with array parsed correctly.\");  \n        t.eq(obj['c'], data['c'], \"element with number parsed correctly.\");  \n    }\n\n    function test_Format_JSON_writer(t) { \n        t.plan(1); \n         \n        var format = new OpenLayers.Format.JSON(); \n        var data = format.write({\"a\":[\"b\"], \"c\":1});\n        var obj = '{\"a\":[\"b\"],\"c\":1}';\n        t.eq(data, obj, \"writing data to json works.\");\n    }\n\n\n    function test_keepData(t) { \n        t.plan(2);\n\n        var options = {'keepData': true};\n        var format = new OpenLayers.Format.JSON(options); \n        format.read('{\"a\":[\"b\"], \"c\":1}');\n\n        t.ok(format.data != null, 'data property is not null after read with keepData=true');\n        t.eq(format.data.c,1,'keepData keeps the right data');\n    }\n\n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/KML.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    var test_content = '<kml xmlns=\"http://earth.google.com/kml/2.0\"><Folder><name>OpenLayers export</name><description>Vector geometries from OpenLayers</description><Placemark id=\"KML.Polygon\"><name>OpenLayers.Feature.Vector_344</name><description>A KLM Polygon</description><Polygon><outerBoundaryIs><LinearRing><coordinates>5.001370157823406,49.26855713824488 8.214706453896161,49.630662409673505 8.397385910100951,48.45172350357396 5.001370157823406,49.26855713824488</coordinates></LinearRing></outerBoundaryIs></Polygon></Placemark><Placemark id=\"KML.LineString\"><name>OpenLayers.Feature.Vector_402</name><description>A KML LineString</description><LineString><coordinates>5.838523393080493,49.74814616928052 5.787079558782349,48.410795432216574 8.91427702008381,49.28932499608202</coordinates></LineString></Placemark><Placemark id=\"KML.Point\"><name>OpenLayers.Feature.Vector_451</name><description>A KML Point</description><Point><coordinates>6.985073041685488,49.8682250149058</coordinates></Point></Placemark><Placemark id=\"KML.MultiGeometry\"><name>SF Marina Harbor Master</name><description>KML MultiGeometry</description><MultiGeometry><LineString><coordinates>-122.4425587930444,37.80666418607323 -122.4428379594768,37.80663578323093</coordinates></LineString><LineString><coordinates>-122.4425509770566,37.80662588061205 -122.4428340530617,37.8065999493009</coordinates></LineString></MultiGeometry></Placemark></Folder></kml>';\n    var test_style = '<kml xmlns=\"http://earth.google.com/kml/2.0\"> <Placemark>    <Style> <LineStyle> <color>870000ff</color> <width>10</width> </LineStyle> </Style>  <LineString> <coordinates> -112,36 -113,37 </coordinates> </LineString> </Placemark></kml>';\n    var test_style_fill = '<kml xmlns=\"http://earth.google.com/kml/2.0\"> <Placemark>    <Style> <PolyStyle> <fill>1</fill> <color>870000ff</color> <width>10</width> </PolyStyle> </Style>  <LineString> <coordinates> -112,36 -113,37 </coordinates> </LineString> </Placemark><Placemark>    <Style> <PolyStyle> <fill>0</fill> <color>870000ff</color> <width>10</width> </PolyStyle> </Style>  <LineString> <coordinates> -112,36 -113,37 </coordinates> </LineString> </Placemark></kml>';\n    var test_style_outline = '<kml xmlns=\"http://earth.google.com/kml/2.0\"> <Placemark>    <Style> <PolyStyle> <outline>0</outline> <color>870000ff</color> <width>10</width> </PolyStyle> </Style>  <LineString> <coordinates> -112,36 -113,37 </coordinates> </LineString> </Placemark></kml>';\n    var test_style_font = '<kml xmlns=\"http://earth.google.com/kml/2.0\"> <Placemark><Style><LabelStyle><color>870000ff</color><scale>1.5</scale></LabelStyle></Style><LineString><coordinates> -112,36 -113,37 </coordinates></LineString></Placemark></kml>';\n    var test_nl = '<kml xmlns=\"http://earth.google.com/kml/2.2\"> <Document> <NetworkLink> <Link> <href>http://maker.geocommons.com/maps/1717/overlays/0</href> </Link> </NetworkLink> </Document></kml>';\n    function test_Format_KML_constructor(t) { \n        t.plan(5); \n         \n        var options = {'foo': 'bar'}; \n        var format = new OpenLayers.Format.KML(options); \n        t.ok(format instanceof OpenLayers.Format.KML, \n             \"new OpenLayers.Format.KML returns object\" ); \n        t.eq(format.foo, \"bar\", \"constructor sets options correctly\"); \n        t.eq(typeof format.read, \"function\", \"format has a read function\"); \n        t.eq(typeof format.write, \"function\", \"format has a write function\");\n        t.eq(format.externalProjection.getCode(), \"EPSG:4326\", \n             \"default external projection is EPSG:4326\"); \n    }\n    function test_Format_KML_multipoint(t) {\n        t.plan(1);\n        var f = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.MultiPoint([\n            new OpenLayers.Geometry.Point(15555162, 4247484)]));\n        var format = new OpenLayers.Format.KML({\n            extractStyles:      true, \n            extractAttributes:  true,\n            internalProjection: new OpenLayers.Projection(\"EPSG:900913\"),\n            externalProjection: new OpenLayers.Projection(\"EPSG:4326\")\n        });\n        var data = format.write(f);\n        var found = (data.search('139.734') != -1);\n        t.ok(found, \"Found 139.734 (correct reprojection) in data output.\");\n    }        \n    function test_Format_KML_read(t) {\n        t.plan(5);\n        var features = (new OpenLayers.Format.KML()).read(this.test_content);\n        t.eq(features.length, 4, \"Number of features read is correct\");\n        t.ok(features[0].geometry.toString() == \"POLYGON((5.001370157823406 49.26855713824488,8.214706453896161 49.630662409673505,8.397385910100951 48.45172350357396,5.001370157823406 49.26855713824488))\", \"polygon feature geometry correctly created\");\n        t.ok(features[1].geometry.toString() == \"LINESTRING(5.838523393080493 49.74814616928052,5.787079558782349 48.410795432216574,8.91427702008381 49.28932499608202)\", \"linestring feature geometry correctly created\");\n        t.ok(features[2].geometry.toString() == \"POINT(6.985073041685488 49.8682250149058)\", \"point feature geometry correctly created\");\n        t.ok(features[3].geometry.CLASS_NAME == \"OpenLayers.Geometry.Collection\",\n             \"read geometry collection\");\n    }\n\n    \n    function test_Format_KML_readCdataAttributes_20(t) {\n        t.plan(2);\n        var cdata = '<kml xmlns=\"http://earth.google.com/kml/2.0\"><Document><Placemark><name><![CDATA[Pezinok]]> </name><description><![CDATA[Full of text.]]></description><styleUrl>#rel1.0</styleUrl><Point> <coordinates>17.266666, 48.283333</coordinates></Point></Placemark></Document></kml>';\n        var features = (new OpenLayers.Format.KML()).read(cdata);\n        t.eq(features[0].attributes.description, \"Full of text.\", \"Description attribute in cdata read correctly\");\n        t.eq(features[0].attributes.name, \"Pezinok\", \"title attribute in cdata read correctly\");\n        \n    }\n    \n    function test_Format_KML_networklink(t) {\n        t.plan(1);\n        var f = new OpenLayers.Format.KML({'maxDepth':1});\n        f.fetchLink = function(url) {\n            t.eq(url, \"http://maker.geocommons.com/maps/1717/overlays/0\", \"network link fetched a link correctly.\");\n            return '';\n        }\n        f.read(test_nl);\n    }\n    function test_Format_KML_readCdataAttributes_21(t) {\n        t.plan(2);\n        var cdata = '<kml xmlns=\"http://earth.google.com/kml/2.1\"><Document><Placemark><name><![CDATA[Pezinok]]></name><description><![CDATA[Full of text.]]></description><styleUrl>#rel1.0</styleUrl><Point> <coordinates>17.266666, 48.283333</coordinates></Point></Placemark></Document></kml>';\n        var features = (new OpenLayers.Format.KML()).read(cdata);\n        t.eq(features[0].attributes.description, \"Full of text.\", \"Description attribute in cdata read correctly\");\n        t.eq(features[0].attributes.name, \"Pezinok\", \"title attribute in cdata read correctly\");\n        \n    }\n    \n    function test_Format_KML_write(t) {\n        // make sure id, name, and description are preserved\n        t.plan(1);\n        var kmlExpected = this.test_content;\n        var options = {\n            foldersName: \"OpenLayers export\",\n            foldersDesc: \"Vector geometries from OpenLayers\"\n        };\n\n        var format = new OpenLayers.Format.KML(options);\n        var features = format.read(kmlExpected);\n        var kmlOut = format.write(features);\n        var kmlOut = kmlOut.replace(/<\\?[^>]*\\?>/, ''); // Remove XML Prolog\n        t.eq(kmlOut, kmlExpected, \"correctly writes an KML doc string\");\n    }\n\n    function test_Format_KML_write_noNameDesc(t) {\n        t.plan(1);\n        var format = new OpenLayers.Format.KML({\n            foldersName: null,\n            foldersDesc: null\n        });\n        var geom = new OpenLayers.Geometry.Point(0, 0)\n        var feature = new OpenLayers.Feature.Vector(geom);\n        feature.id = 42;\n        var kmlOut = format.write(feature);\n        var expected = '<kml xmlns=\"http://earth.google.com/kml/2.0\"><Folder><Placemark><name>42</name><description>No description available</description><Point><coordinates>0,0</coordinates></Point></Placemark></Folder></kml>'\n        t.eq(kmlOut, expected, \"null foldersName or foldersDesc don't create elements\");\n    }\n    \n    function test_Format_KML_write_multis(t) {\n        /**\n         * KML doesn't have a representation for multi geometries of a\n         * specific type.  KML MultiGeometry maps to OL Geometry.Collection.\n         * Because of this, multi-geometries in OL can't make a round trip\n         * through KML (an OL MultiPoint maps to a KML MultiGeometry\n         * containing points, which maps back to an OL Collection containing\n         * points).  So we need to acceptance tests for the writing of\n         * multi-geometries specifically instead of relying on the round-trip\n         * write test above.\n         */\n        t.plan(3);\n        var format = new OpenLayers.Format.KML({foldersDesc: \"test output\"});\n        var multi, feature, output, expected;\n        \n        // test multipoint\n        var multi = new OpenLayers.Geometry.MultiPoint([\n            new OpenLayers.Geometry.Point(0, 1)\n        ]);\n        feature = new OpenLayers.Feature.Vector(multi, {name: \"test name\"});\n        output = format.write(feature);\n        expected = '<kml xmlns=\"http://earth.google.com/kml/2.0\"><Folder><name>OpenLayers export</name><description>test output</description><Placemark><name>test name</name><description>No description available</description><MultiGeometry><Point><coordinates>0,1</coordinates></Point></MultiGeometry></Placemark></Folder></kml>';\n        var output = output.replace(/<\\?[^>]*\\?>/, ''); // Remove XML Prolog\n        t.eq(output, expected, \"multipoint correctly written\");\n        \n        // test multilinestring\n        var multi = new OpenLayers.Geometry.MultiLineString([\n            new OpenLayers.Geometry.LineString([\n                new OpenLayers.Geometry.Point(1, 0),\n                new OpenLayers.Geometry.Point(0, 1)\n            ])\n        ]);\n        feature = new OpenLayers.Feature.Vector(multi, {name: \"test name\"});\n        output = format.write(feature);\n        expected = '<kml xmlns=\"http://earth.google.com/kml/2.0\"><Folder><name>OpenLayers export</name><description>test output</description><Placemark><name>test name</name><description>No description available</description><MultiGeometry><LineString><coordinates>1,0 0,1</coordinates></LineString></MultiGeometry></Placemark></Folder></kml>';\n        var output = output.replace(/<\\?[^>]*\\?>/, ''); // Remove XML Prolog\n        t.eq(output, expected, \"multilinestring correctly written\");\n\n        // test multipolygon\n        var multi = new OpenLayers.Geometry.MultiPolygon([\n            new OpenLayers.Geometry.Polygon([\n                new OpenLayers.Geometry.LinearRing([\n                    new OpenLayers.Geometry.Point(0, 0),\n                    new OpenLayers.Geometry.Point(1, 0),\n                    new OpenLayers.Geometry.Point(0, 1)\n                ])\n            ])\n        ]);\n        feature = new OpenLayers.Feature.Vector(multi, {name: \"test name\"});\n        output = format.write(feature);\n        expected = '<kml xmlns=\"http://earth.google.com/kml/2.0\"><Folder><name>OpenLayers export</name><description>test output</description><Placemark><name>test name</name><description>No description available</description><MultiGeometry><Polygon><outerBoundaryIs><LinearRing><coordinates>0,0 1,0 0,1 0,0</coordinates></LinearRing></outerBoundaryIs></Polygon></MultiGeometry></Placemark></Folder></kml>';\n        var output = output.replace(/<\\?[^>]*\\?>/, ''); // Remove XML Prolog\n        t.eq(output, expected, \"multilinestring correctly written\");\n\n    }\n    function test_Format_KML_extractStyle(t) {\n        t.plan(1);\n        var f = new OpenLayers.Format.KML();\n        var features = f.read(test_style);    \n        t.ok(features[0].style == undefined, \"KML Feature has no style with extractStyle false\");        \n    } \n    function test_Format_KML_extractStyleFill(t) {\n        t.plan(2);\n        var f = new OpenLayers.Format.KML({extractStyles: true});\n        var features = f.read(test_style_fill);    \n        t.eq(features[0].style.fillColor, \"#ff0000\", \"default fill is set\");  \n        t.eq(features[1].style.fillColor, \"none\", \"KML Feature has none fill\");        \n    } \n    function test_Format_KML_extractStyleOutline(t) {\n        t.plan(2);\n        var f = new OpenLayers.Format.KML({extractStyles: true});\n        var features = f.read(test_style);\n        t.eq(features[0].style.strokeWidth, \"10\", \"default stroke is set\");\n        var features = f.read(test_style_outline);\n        t.eq(features[0].style.strokeWidth, \"0\", \"KML Feature has no outline\");\n    } \n    function test_Format_KML_extractStyleFont(t) {\n        t.plan(2);\n        var f = new OpenLayers.Format.KML({extractStyles: true});\n        var features = f.read(test_style_font);\n        t.eq(features[0].style.fontColor, \"#ff0000\", \"font color is set\");\n        t.eq(features[0].style.fontOpacity, parseInt('87', 16) / 255, \"font opacity is set\");\n    } \n    function test_Format_KML_getStyle(t) {\n        t.plan(1);\n        var style = {t: true};\n        var f = new OpenLayers.Format.KML();\n        f.styles = {test: style};\n        var gotStyle = f.getStyle('test');\n        gotStyle.t = false;\n        t.ok(style.t, \"getStyle returns copy of style rather than reference\");\n    }\n    function test_Format_KML_extendedData(t) {\n        t.plan(6);\n        var f = new OpenLayers.Format.KML();\n        var features = f.read(OpenLayers.Util.getElement(\"kml_extendeddata\").value);\n        t.eq(features[0].attributes.holeYardage.value, \"234\", \"read value from extendeddata correctly.\");\n        t.eq(features[0].attributes.holeYardage.displayName, \"<b><i>The yardage is </i></b>\", \"read displayName from extendeddata correctly.\");\n        t.eq(f.read(f.write(features[0]))[0].attributes.holeYardage.value, features[0].attributes.holeYardage.value, \"attribute value written correctly\");\n        t.eq(f.read(f.write(features[0]))[0].attributes.holeYardage.displayName, features[0].attributes.holeYardage.displayName, \"attribute displayName written correctly\");\n        f.kvpAttributes = true;\n        features = f.read(OpenLayers.Util.getElement(\"kml_extendeddata\").value);\n        t.eq(features[0].attributes.holeYardage, \"234\", \"read kvp value from extendeddata correctly.\");\n        t.eq(f.read(f.write(features[0]))[0].attributes.holeYardage, features[0].attributes.holeYardage, \"kvp attribute value written correctly\");\n    }\n\n    function test_Format_KML_extendedData_SchemaData(t) {\n        t.plan(10);\n        var f = new OpenLayers.Format.KML();\n        var features = f.read(OpenLayers.Util.getElement(\"kml_extendeddata2\").value);\n        t.eq(features[0].attributes.TrailHeadName.value, \"Pi in the sky\", \"read value from extendeddata (schema data) correctly.\");\n        t.eq(features[0].attributes.TrailHeadName.displayName, \"TrailHeadName\", \"read displayName from extendeddata correctly\");\n        t.eq(features[0].attributes.ElevationGain.value, \"10\", \"read value from extendeddata (schema data) correctly.\");\n        t.eq(features[0].attributes.ElevationGain.displayName, \"ElevationGain\", \"read displayName from extendeddata correctly\");\n        t.eq(f.read(f.write(features[0]))[0].attributes.TrailHeadName.value, features[0].attributes.TrailHeadName.value, \"attribute value from extendeddata (schema data) written correctly\");\n        t.eq(f.read(f.write(features[0]))[0].attributes.ElevationGain.value, features[0].attributes.ElevationGain.value, \"attribute value from extendeddata (schema data) written correctly\");\n        f.kvpAttributes = true;\n        features = f.read(OpenLayers.Util.getElement(\"kml_extendeddata2\").value);\n        t.eq(features[0].attributes.TrailHeadName, \"Pi in the sky\", \"read kvp value from extendeddata (schema data) correctly.\");\n        t.eq(features[0].attributes.ElevationGain, \"10\", \"read kvp value from extendeddata (schema data) correctly.\");\n        t.eq(f.read(f.write(features[0]))[0].attributes.TrailHeadName, features[0].attributes.TrailHeadName, \"kvp attribute value from extendeddata (schema data) written correctly\");\n        t.eq(f.read(f.write(features[0]))[0].attributes.ElevationGain, features[0].attributes.ElevationGain, \"kvp attribute value from extendeddata (schema data) written correctly\");\n    }\n\n    function test_Format_KML_placemarkName(t) {\n        t.plan(3);\n        \n        var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0));\n        var f = new OpenLayers.Format.KML();\n\n        t.eq(f.read(f.write(feature))[0].attributes.name, feature.id, \"placemark name from feature.id\");\n        feature.style = {\n            label: \"placemark name from style.label\"\n        };\n        t.eq(f.read(f.write(feature))[0].attributes.name, feature.style.label, \"placemark name from style.label\");\n\n        feature.attributes.name = \"placemark name from attributes.name\";\n        t.eq(f.read(f.write(feature))[0].attributes.name, feature.attributes.name, \"placemark name from attributes.name\");\n    }\n    function test_Format_KML_linestring_projected(t) {\n        t.plan(1);\n        var f = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString([\n            new OpenLayers.Geometry.Point(15555162, 4247484), new OpenLayers.Geometry.Point(15555163, 4247485)]));\n        var format = new OpenLayers.Format.KML({\n            internalProjection: new OpenLayers.Projection(\"EPSG:900913\"),\n            externalProjection: new OpenLayers.Projection(\"EPSG:4326\")\n        });\n        var data = format.write(f);\n        var found = (data.search('139.734') != -1);\n        t.ok(found, \"Found 139.734 (correct reprojection) in data output.\");\n    }        \n    \n    function test_extractTracks(t) {\n        \n        t.plan(13);\n        \n        var xml = new OpenLayers.Format.XML(); \n        var doc = xml.read(document.getElementById(\"macnoise.kml\").firstChild.nodeValue);\n        \n        var format = new OpenLayers.Format.KML({\n            extractTracks: true,\n            trackAttributes: [\"speed\", \"num\"] // additional custom attributes\n        });\n        \n        var features = format.read(doc.documentElement);\n        t.eq(features.length, 170, \"got 170 features\");\n        \n        var attr = features[4].attributes;\n        \n        // standard track point attributes\n        t.ok(attr.when instanceof Date, \"features have when attribute\");\n        t.eq(attr.when.getTime(), 1272736815000, \"correct time for fifth feature\");\n        t.eq(attr.altitude, 1006, \"altitude parsed\");\n        t.eq(attr.heading, 230, \"heading parsed\");\n        t.eq(attr.tilt, 0, \"tilt parsed\");\n        t.eq(attr.roll, 0, \"roll parsed\");\n        \n        // custom track attributes (all features acquire from the placemark)\n        t.eq(attr.name, \"B752\", \"correct name\");\n        t.eq(attr.adflag, \"A\", \"correct adflag\");\n        t.eq(attr.flightid, \"DAL2973\", \"correct flightid\");\n        \n        // additional per point attributes (determined by trackAttributes property)\n        t.eq(attr.speed, \"166\", \"correct speed\");\n        t.eq(attr.num, \"50\", \"correct num\");\n        \n        var exp = new OpenLayers.Geometry.Point(-93.0753620391713, 44.9879724110872);\n        exp.z = 1006;\n        t.geom_eq(features[4].geometry, exp, \"correct geometry\");\n        \n    }\n    \n\n    </script> \n</head> \n<body> \n    <textarea id=\"kml_extendeddata\" style=\"display:none\">\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<kml xmlns=\"http://www.opengis.net/kml/2.2\">\n  <Document>\n    <name>Entity-Replacement</name>\n    <Placemark>\n      <name>Club house</name>\n      <ExtendedData>\n        <Data name=\"holeNumber\">\n          <displayName><![CDATA[\n            <b>This is hole </b>\n          ]]></displayName>\n          <value>1</value>\n        </Data>\n        <Data name=\"holePar\">\n          <displayName><![CDATA[\n            <i>The par for this hole is </i>\n          ]]></displayName>\n          <value>4</value>\n        </Data>\n        <Data name=\"holeYardage\">\n          <displayName><![CDATA[<b><i>The yardage is </i></b>]]></displayName>\n          <value>234</value>\n        </Data>\n      </ExtendedData>\n      <Point>\n        <coordinates>-111.956,33.5043</coordinates>\n      </Point>\n    </Placemark>\n    <Placemark>\n      <name>By the lake</name>\n      <ExtendedData>\n        <Data name=\"holeNumber\">\n          <displayName><![CDATA[\n            <b>This is hole </b>\n          ]]></displayName>\n          <value>5</value>\n        </Data>\n        <Data name=\"holePar\">\n          <displayName><![CDATA[\n            <i>The par for this hole is </i>\n          ]]></displayName>\n          <value>5</value>\n        </Data>\n        <Data name=\"holeYardage\">\n          <displayName><![CDATA[\n            <b><i>The yardage is </i></b>\n          ]]></displayName>\n          <value>523</value>\n        </Data>\n      </ExtendedData>\n      <Point>\n        <coordinates>-111.95,33.5024</coordinates>\n      </Point>\n    </Placemark>\n  </Document>\n</kml>\n</textarea>\n    <textarea id=\"kml_extendeddata2\" style=\"display:none\">\n<kml xmlns=\"http://earth.google.com/kml/2.2\">\n<Document>\n<Placemark>\n  <name>Easy trail</name>\n  <ExtendedData>\n    <SchemaData schemaUrl=\"#TrailHeadTypeId\">\n      <SimpleData name=\"TrailHeadName\">Pi in the sky</SimpleData>\n      <SimpleData name=\"TrailLength\">3.14159</SimpleData>\n      <SimpleData name=\"ElevationGain\">10</SimpleData>\n    </SchemaData>\n    </ExtendedData>\n    <Point>\n      <coordinates>-122.000,37.002</coordinates>\n    </Point>\n</Placemark>\n<Placemark>\n  <name>Difficult trail</name>\n  <ExtendedData>\n    <SchemaData schemaUrl=\"#TrailHeadTypeId\">\n      <SimpleData name=\"TrailHeadName\">Mount Everest</SimpleData>\n      <SimpleData name=\"TrailLength\">347.45</SimpleData>\n      <SimpleData name=\"ElevationGain\">10000</SimpleData>\n    </SchemaData>\n  </ExtendedData>\n  <Point>\n    <coordinates>-122.000,37.002</coordinates>\n  </Point>\n</Placemark>\n</Document>\n</kml>\n</textarea>\n\n<div id=\"macnoise.kml\"><!--\n<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\">\n<Document>\n<Camera>\n  <gx:TimeStamp>\n    <when>2010-05-01T13:00:00-05:00</when>\n  </gx:TimeStamp>\n  <longitude>-93.2207</longitude>\n  <latitude>44.882</latitude>\n  <altitude>50000</altitude>\n  <heading>0</heading>\n  <tilt>0</tilt>\n</Camera>\n<Style id=\"arrival\">\n  <IconStyle>\n    <Icon>\n      <href>http://maps.macnoise.com/scripts/plane.png</href>\n    </Icon>\n  </IconStyle>\n  <LineStyle>\n    <color>ff0000ff</color>\n    <width>3</width>\n  </LineStyle>\n  <PolyStyle>\n    <color>7fffffff</color>\n  </PolyStyle>\n</Style>\n<Style id=\"departure\">\n  <IconStyle>\n    <Icon>\n      <href>http://maps.macnoise.com/scripts/plane.png</href>\n    </Icon>\n  </IconStyle>\n  <LineStyle>\n    <color>ff00ff00</color>\n    <width>3</width>\n  </LineStyle>\n  <PolyStyle>\n    <color>7fffffff</color>\n  </PolyStyle>\n</Style>\n<Style id=\"overflight\">\n  <IconStyle>\n    <Icon>\n      <href>http://maps.macnoise.com/scripts/plane.png</href>\n    </Icon>\n  </IconStyle>\n  <LineStyle>\n    <color>ff222222</color>\n    <width>3</width>\n  </LineStyle>\n  <PolyStyle>\n    <color>7fffffff</color>\n  </PolyStyle>\n</Style>\n<Style id='rmt'>\n  <LabelStyle>\n    <color>ff0000cc</color>\n    <colorMode>normal</colorMode>\n    <scale>1</scale>\n  </LabelStyle>\n</Style>\n\n<name>Flight Tracks</name>\n<Folder>\n  <name>Arrivals</name>\n<Placemark>\n  <name>B752</name>\n  <adflag>A</adflag>\n  <flightid>DAL2973</flightid>\n  <styleUrl>#arrival</styleUrl>\n<gx:Track>\n    <altitudeMode>absolute</altitudeMode>\n    <extrude>1</extrude>\n    <when>2010-05-01T13:00:00-05</when>\n    <when>2010-05-01T13:00:01-05</when>\n    <when>2010-05-01T13:00:06-05</when>\n    <when>2010-05-01T13:00:10-05</when>\n    <when>2010-05-01T13:00:15-05</when>\n    <when>2010-05-01T13:00:20-05</when>\n    <when>2010-05-01T13:00:24-05</when>\n    <when>2010-05-01T13:00:29-05</when>\n    <when>2010-05-01T13:00:33-05</when>\n    <when>2010-05-01T13:00:38-05</when>\n    <when>2010-05-01T13:00:43-05</when>\n    <when>2010-05-01T13:00:47-05</when>\n    <when>2010-05-01T13:00:52-05</when>\n    <when>2010-05-01T13:00:57-05</when>\n    <when>2010-05-01T13:01:00-05</when>\n    <gx:coord>-93.0658625188843 44.9949645987875 1036</gx:coord>\n    <gx:coord>-93.0664690096445 44.9945424635331 1036</gx:coord>\n    <gx:coord>-93.0694347065378 44.9923936108644 1036</gx:coord>\n    <gx:coord>-93.0722946883822 44.9901649091109 1006</gx:coord>\n    <gx:coord>-93.0753620391713 44.9879724110872 1006</gx:coord>\n    <gx:coord>-93.078638650624 44.985904678007 975</gx:coord>\n    <gx:coord>-93.0817463907976 44.9836868456013 975</gx:coord>\n    <gx:coord>-93.0847749343212 44.9813998515538 945</gx:coord>\n    <gx:coord>-93.0879207383429 44.9791066547511 914</gx:coord>\n    <gx:coord>-93.091282218058 44.976822731273 914</gx:coord>\n    <gx:coord>-93.0945882606646 44.9745372955479 884</gx:coord>\n    <gx:coord>-93.0979053364864 44.9722421846492 884</gx:coord>\n    <gx:coord>-93.1012678619471 44.9698451058525 853</gx:coord>\n    <gx:coord>-93.1044570741037 44.967424293466 853</gx:coord>\n    <gx:coord>-93.1068079756418 44.9657037851018 853</gx:coord>\n    <gx:angles>230 0 0</gx:angles>\n    <gx:angles>220 0 0</gx:angles>\n    <gx:angles>220 0 0</gx:angles>\n    <gx:angles>230 0 0</gx:angles>\n    <gx:angles>230 0 0</gx:angles>\n    <gx:angles>230 0 0</gx:angles>\n    <gx:angles>230 0 0</gx:angles>\n    <gx:angles>220 0 0</gx:angles>\n    <gx:angles>220 0 0</gx:angles>\n    <gx:angles>230 0 0</gx:angles>\n    <gx:angles>230 0 0</gx:angles>\n    <gx:angles>220 0 0</gx:angles>\n    <gx:angles>220 0 0</gx:angles>\n    <gx:angles>220 0 0</gx:angles>\n    <gx:angles>220 0 0</gx:angles>\n    <speed>162</speed>\n    <speed>160</speed>\n    <speed>159</speed>\n    <speed>165</speed>\n    <speed>166</speed>\n    <speed>174</speed>\n    <speed>170</speed>\n    <speed>172</speed>\n    <speed>180</speed>\n    <speed>176</speed>\n    <speed>177</speed>\n    <speed>177</speed>\n    <speed>180</speed>\n    <speed>184</speed>\n    <speed>177</speed>\n    <num>10</num>\n    <num>20</num>\n    <num>30</num>\n    <num>40</num>\n    <num>50</num>\n    <num>60</num>\n    <num>70</num>\n    <num>80</num>\n    <num>90</num>\n    <num>100</num>\n    <num>110</num>\n    <num>120</num>\n    <num>130</num>\n    <num>140</num>\n    <num>150</num>\n</gx:Track></Placemark>\n<Placemark>\n  <name>E170</name>\n  <adflag>A</adflag>\n  <flightid>TCF7521</flightid>\n  <styleUrl>#arrival</styleUrl>\n<gx:Track>\n    <altitudeMode>absolute</altitudeMode>\n    <extrude>1</extrude>\n    <when>2010-05-01T13:00:00-05</when>\n    <when>2010-05-01T13:00:04-05</when>\n    <when>2010-05-01T13:00:09-05</when>\n    <when>2010-05-01T13:00:13-05</when>\n    <when>2010-05-01T13:00:18-05</when>\n    <when>2010-05-01T13:00:23-05</when>\n    <when>2010-05-01T13:00:27-05</when>\n    <when>2010-05-01T13:00:32-05</when>\n    <when>2010-05-01T13:00:37-05</when>\n    <when>2010-05-01T13:00:41-05</when>\n    <when>2010-05-01T13:00:46-05</when>\n    <when>2010-05-01T13:00:51-05</when>\n    <when>2010-05-01T13:00:55-05</when>\n    <when>2010-05-01T13:01:00-05</when>\n    <gx:coord>-93.3806146339391 44.8823651507134 2743</gx:coord>\n    <gx:coord>-93.3773041814209 44.887531728655 2743</gx:coord>\n    <gx:coord>-93.3742856469083 44.8942041806778 2743</gx:coord>\n    <gx:coord>-93.3722375106026 44.9009231720158 2743</gx:coord>\n    <gx:coord>-93.3711934089417 44.9077495987718 2712</gx:coord>\n    <gx:coord>-93.3707288919852 44.9145219645156 2712</gx:coord>\n    <gx:coord>-93.3703882714439 44.921240089024 2682</gx:coord>\n    <gx:coord>-93.3700882719793 44.9278850664392 2682</gx:coord>\n    <gx:coord>-93.369810041597 44.934389356737 2651</gx:coord>\n    <gx:coord>-93.3696836566166 44.9408553642446 2651</gx:coord>\n    <gx:coord>-93.3695425129226 44.9473561165969 2621</gx:coord>\n    <gx:coord>-93.3693185423471 44.9537360442564 2621</gx:coord>\n    <gx:coord>-93.3693194298816 44.9599975904123 2590</gx:coord>\n    <gx:coord>-93.3694031671108 44.9661411653607 2590</gx:coord>\n    <gx:angles>20 0 0</gx:angles>\n    <gx:angles>20 0 0</gx:angles>\n    <gx:angles>20 0 0</gx:angles>\n    <gx:angles>10 0 0</gx:angles>\n    <gx:angles>10 0 0</gx:angles>\n    <gx:angles>0 0 0</gx:angles>\n    <gx:angles>0 0 0</gx:angles>\n    <gx:angles>0 0 0</gx:angles>\n    <gx:angles>0 0 0</gx:angles>\n    <gx:angles>0 0 0</gx:angles>\n    <gx:angles>0 0 0</gx:angles>\n    <gx:angles>0 0 0</gx:angles>\n    <gx:angles>0 0 0</gx:angles>\n    <gx:angles>360 0 0</gx:angles>\n    <speed>376</speed>\n    <speed>367</speed>\n    <speed>361</speed>\n    <speed>371</speed>\n    <speed>367</speed>\n    <speed>363</speed>\n    <speed>359</speed>\n    <speed>356</speed>\n    <speed>352</speed>\n    <speed>347</speed>\n    <speed>343</speed>\n    <speed>347</speed>\n    <speed>334</speed>\n    <speed>337</speed>\n    <num>10</num>\n    <num>20</num>\n    <num>30</num>\n    <num>40</num>\n    <num>50</num>\n    <num>60</num>\n    <num>70</num>\n    <num>80</num>\n    <num>90</num>\n    <num>100</num>\n    <num>110</num>\n    <num>120</num>\n    <num>130</num>\n    <num>140</num>\n</gx:Track></Placemark>\n<Placemark>\n  <name>BE33</name>\n  <adflag>A</adflag>\n  <flightid>N38175</flightid>\n  <styleUrl>#arrival</styleUrl>\n<gx:Track>\n    <altitudeMode>absolute</altitudeMode>\n    <extrude>1</extrude>\n    <when>2010-05-01T13:00:00-05</when>\n    <when>2010-05-01T13:00:02-05</when>\n    <when>2010-05-01T13:00:07-05</when>\n    <when>2010-05-01T13:00:12-05</when>\n    <when>2010-05-01T13:00:16-05</when>\n    <when>2010-05-01T13:00:21-05</when>\n    <when>2010-05-01T13:00:25-05</when>\n    <when>2010-05-01T13:00:30-05</when>\n    <when>2010-05-01T13:00:35-05</when>\n    <when>2010-05-01T13:00:39-05</when>\n    <when>2010-05-01T13:00:44-05</when>\n    <when>2010-05-01T13:00:49-05</when>\n    <when>2010-05-01T13:00:53-05</when>\n    <when>2010-05-01T13:00:58-05</when>\n    <when>2010-05-01T13:01:00-05</when>\n    <gx:coord>-93.0144637208028 44.6541474764804 1006</gx:coord>\n    <gx:coord>-93.0162681345228 44.6547274296664 1006</gx:coord>\n    <gx:coord>-93.0196734868835 44.6559915702004 975</gx:coord>\n    <gx:coord>-93.0231899415297 44.657188463998 945</gx:coord>\n    <gx:coord>-93.0267619421777 44.6582849847887 945</gx:coord>\n    <gx:coord>-93.0302021384369 44.6594728216183 914</gx:coord>\n    <gx:coord>-93.0338776768471 44.6606515995762 914</gx:coord>\n    <gx:coord>-93.0375866343814 44.6618806707998 884</gx:coord>\n    <gx:coord>-93.0411146687035 44.6632657982455 884</gx:coord>\n    <gx:coord>-93.0447829038862 44.6646495821585 884</gx:coord>\n    <gx:coord>-93.0486933143218 44.6659856209571 914</gx:coord>\n    <gx:coord>-93.0525604964428 44.6672664774449 884</gx:coord>\n    <gx:coord>-93.0559892061682 44.6686325276705 884</gx:coord>\n    <gx:coord>-93.0595122787868 44.6700360197293 884</gx:coord>\n    <gx:coord>-93.0610274392619 44.6706087373734 884</gx:coord>\n    <gx:angles>300 0 0</gx:angles>\n    <gx:angles>300 0 0</gx:angles>\n    <gx:angles>300 0 0</gx:angles>\n    <gx:angles>300 0 0</gx:angles>\n    <gx:angles>290 0 0</gx:angles>\n    <gx:angles>290 0 0</gx:angles>\n    <gx:angles>300 0 0</gx:angles>\n    <gx:angles>300 0 0</gx:angles>\n    <gx:angles>300 0 0</gx:angles>\n    <gx:angles>300 0 0</gx:angles>\n    <gx:angles>300 0 0</gx:angles>\n    <gx:angles>300 0 0</gx:angles>\n    <gx:angles>300 0 0</gx:angles>\n    <gx:angles>300 0 0</gx:angles>\n    <gx:angles>300 0 0</gx:angles>\n    <speed>150</speed>\n    <speed>156</speed>\n    <speed>152</speed>\n    <speed>156</speed>\n    <speed>151</speed>\n    <speed>152</speed>\n    <speed>160</speed>\n    <speed>157</speed>\n    <speed>159</speed>\n    <speed>158</speed>\n    <speed>158</speed>\n    <speed>160</speed>\n    <speed>155</speed>\n    <speed>155</speed>\n    <speed>156</speed>\n    <num>10</num>\n    <num>20</num>\n    <num>30</num>\n    <num>40</num>\n    <num>50</num>\n    <num>60</num>\n    <num>70</num>\n    <num>80</num>\n    <num>90</num>\n    <num>100</num>\n    <num>110</num>\n    <num>120</num>\n    <num>130</num>\n    <num>140</num>\n    <num>150</num>\n</gx:Track></Placemark>\n<Placemark>\n  <name>A319</name>\n  <adflag>A</adflag>\n  <flightid>DAL1588</flightid>\n  <styleUrl>#arrival</styleUrl>\n<gx:Track>\n    <altitudeMode>absolute</altitudeMode>\n    <extrude>1</extrude>\n    <when>2010-05-01T13:00:00-05</when>\n    <when>2010-05-01T13:00:04-05</when>\n    <when>2010-05-01T13:00:08-05</when>\n    <when>2010-05-01T13:00:13-05</when>\n    <when>2010-05-01T13:00:18-05</when>\n    <when>2010-05-01T13:00:22-05</when>\n    <when>2010-05-01T13:00:27-05</when>\n    <when>2010-05-01T13:00:31-05</when>\n    <when>2010-05-01T13:00:36-05</when>\n    <when>2010-05-01T13:00:41-05</when>\n    <when>2010-05-01T13:00:45-05</when>\n    <when>2010-05-01T13:00:50-05</when>\n    <when>2010-05-01T13:00:55-05</when>\n    <when>2010-05-01T13:00:59-05</when>\n    <when>2010-05-01T13:01:00-05</when>\n    <gx:coord>-93.6927825194056 44.7952011849485 3011</gx:coord>\n    <gx:coord>-93.6850156681578 44.7968042586582 2987</gx:coord>\n    <gx:coord>-93.6752785488692 44.7990458605003 2956</gx:coord>\n    <gx:coord>-93.6657083011645 44.8014897663497 2926</gx:coord>\n    <gx:coord>-93.6560029615388 44.803768841381 2865</gx:coord>\n    <gx:coord>-93.6462045264035 44.8058749817725 2834</gx:coord>\n    <gx:coord>-93.6365671200126 44.8080848199989 2804</gx:coord>\n    <gx:coord>-93.6269933807039 44.8102767000109 2773</gx:coord>\n    <gx:coord>-93.6175405757462 44.8123960709083 2743</gx:coord>\n    <gx:coord>-93.6082528975965 44.8146455509748 2743</gx:coord>\n    <gx:coord>-93.599077315807 44.816765612372 2743</gx:coord>\n    <gx:coord>-93.5899428762254 44.8186933623744 2743</gx:coord>\n    <gx:coord>-93.5809104439923 44.8205403457841 2743</gx:coord>\n    <gx:coord>-93.5720785209701 44.8224608846058 2743</gx:coord>\n    <gx:coord>-93.5703603013364 44.8228739543212 2743</gx:coord>\n    <gx:angles>70 0 0</gx:angles>\n    <gx:angles>70 0 0</gx:angles>\n    <gx:angles>70 0 0</gx:angles>\n    <gx:angles>70 0 0</gx:angles>\n    <gx:angles>70 0 0</gx:angles>\n    <gx:angles>70 0 0</gx:angles>\n    <gx:angles>70 0 0</gx:angles>\n    <gx:angles>70 0 0</gx:angles>\n    <gx:angles>70 0 0</gx:angles>\n    <gx:angles>70 0 0</gx:angles>\n    <gx:angles>70 0 0</gx:angles>\n    <gx:angles>70 0 0</gx:angles>\n    <gx:angles>70 0 0</gx:angles>\n    <gx:angles>70 0 0</gx:angles>\n    <gx:angles>70 0 0</gx:angles>\n    <speed>390</speed>\n    <speed>383</speed>\n    <speed>397</speed>\n    <speed>390</speed>\n    <speed>405</speed>\n    <speed>388</speed>\n    <speed>386</speed>\n    <speed>397</speed>\n    <speed>377</speed>\n    <speed>373</speed>\n    <speed>367</speed>\n    <speed>362</speed>\n    <speed>365</speed>\n    <speed>350</speed>\n    <speed>354</speed>\n    <num>10</num>\n    <num>20</num>\n    <num>30</num>\n    <num>40</num>\n    <num>50</num>\n    <num>60</num>\n    <num>70</num>\n    <num>80</num>\n    <num>90</num>\n    <num>100</num>\n    <num>110</num>\n    <num>120</num>\n    <num>130</num>\n    <num>140</num>\n    <num>150</num>\n</gx:Track></Placemark>\n<Placemark>\n  <name>E145</name>\n  <adflag>A</adflag>\n  <flightid>CHQ1453</flightid>\n  <styleUrl>#arrival</styleUrl>\n<gx:Track>\n    <altitudeMode>absolute</altitudeMode>\n    <extrude>1</extrude>\n    <when>2010-05-01T13:00:00-05</when>\n    <when>2010-05-01T13:00:01-05</when>\n    <when>2010-05-01T13:00:06-05</when>\n    <when>2010-05-01T13:00:11-05</when>\n    <when>2010-05-01T13:00:15-05</when>\n    <when>2010-05-01T13:00:20-05</when>\n    <when>2010-05-01T13:00:24-05</when>\n    <when>2010-05-01T13:00:29-05</when>\n    <when>2010-05-01T13:00:34-05</when>\n    <when>2010-05-01T13:00:38-05</when>\n    <when>2010-05-01T13:00:43-05</when>\n    <when>2010-05-01T13:00:48-05</when>\n    <when>2010-05-01T13:00:52-05</when>\n    <when>2010-05-01T13:00:57-05</when>\n    <when>2010-05-01T13:01:00-05</when>\n    <gx:coord>-92.5727580977974 45.0236058844647 2530</gx:coord>\n    <gx:coord>-92.5742776202954 45.0237913896498 2530</gx:coord>\n    <gx:coord>-92.5803397933112 45.0241784662561 2499</gx:coord>\n    <gx:coord>-92.5865075192046 45.0247891381303 2469</gx:coord>\n    <gx:coord>-92.5926877928765 45.0257073410966 2469</gx:coord>\n    <gx:coord>-92.5986546763805 45.0261844476041 2438</gx:coord>\n    <gx:coord>-92.6046737535477 45.0267206733977 2438</gx:coord>\n    <gx:coord>-92.6106885874739 45.0275061986719 2438</gx:coord>\n    <gx:coord>-92.616359210337 45.027935793162 2438</gx:coord>\n    <gx:coord>-92.6220735719954 45.028379077688 2438</gx:coord>\n    <gx:coord>-92.6280403097635 45.0290552550566 2438</gx:coord>\n    <gx:coord>-92.6341725652711 45.029824064212 2438</gx:coord>\n    <gx:coord>-92.640279209769 45.0304963952702 2438</gx:coord>\n    <gx:coord>-92.6463747377703 45.0311129317319 2438</gx:coord>\n    <gx:coord>-92.650043383232 45.0314890298388 2438</gx:coord>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <speed>235</speed>\n    <speed>246</speed>\n    <speed>239</speed>\n    <speed>244</speed>\n    <speed>234</speed>\n    <speed>232</speed>\n    <speed>238</speed>\n    <speed>227</speed>\n    <speed>228</speed>\n    <speed>229</speed>\n    <speed>229</speed>\n    <speed>232</speed>\n    <speed>228</speed>\n    <speed>232</speed>\n    <speed>236</speed>\n    <num>10</num>\n    <num>20</num>\n    <num>30</num>\n    <num>40</num>\n    <num>50</num>\n    <num>60</num>\n    <num>70</num>\n    <num>80</num>\n    <num>90</num>\n    <num>100</num>\n    <num>110</num>\n    <num>120</num>\n    <num>130</num>\n    <num>140</num>\n    <num>150</num>\n</gx:Track></Placemark>\n<Placemark>\n  <name>E170</name>\n  <adflag>A</adflag>\n  <flightid>CPZ5695</flightid>\n  <styleUrl>#arrival</styleUrl>\n<gx:Track>\n    <altitudeMode>absolute</altitudeMode>\n    <extrude>1</extrude>\n    <when>2010-05-01T13:00:11-05</when>\n    <when>2010-05-01T13:00:15-05</when>\n    <when>2010-05-01T13:00:20-05</when>\n    <when>2010-05-01T13:00:25-05</when>\n    <when>2010-05-01T13:00:29-05</when>\n    <when>2010-05-01T13:00:34-05</when>\n    <when>2010-05-01T13:00:38-05</when>\n    <when>2010-05-01T13:00:43-05</when>\n    <when>2010-05-01T13:00:48-05</when>\n    <when>2010-05-01T13:00:52-05</when>\n    <when>2010-05-01T13:00:57-05</when>\n    <when>2010-05-01T13:01:00-05</when>\n    <gx:coord>-92.3689380245182 45.0389467469425 2804</gx:coord>\n    <gx:coord>-92.3759530819834 45.0380951007958 2773</gx:coord>\n    <gx:coord>-92.3831159633175 45.0369957486846 2712</gx:coord>\n    <gx:coord>-92.3901362714549 45.0355238496347 2651</gx:coord>\n    <gx:coord>-92.3970814910858 45.0339385808083 2621</gx:coord>\n    <gx:coord>-92.4043121546626 45.032585906621 2560</gx:coord>\n    <gx:coord>-92.4118367565321 45.0319048652958 2499</gx:coord>\n    <gx:coord>-92.419078934653 45.030875157485 2469</gx:coord>\n    <gx:coord>-92.4262095560369 45.0291153314744 2438</gx:coord>\n    <gx:coord>-92.4335237384463 45.0273941113051 2438</gx:coord>\n    <gx:coord>-92.4408178608932 45.0260076351757 2438</gx:coord>\n    <gx:coord>-92.4451575746228 45.0254275529773 2438</gx:coord>\n    <gx:angles>260 0 0</gx:angles>\n    <gx:angles>260 0 0</gx:angles>\n    <gx:angles>260 0 0</gx:angles>\n    <gx:angles>250 0 0</gx:angles>\n    <gx:angles>260 0 0</gx:angles>\n    <gx:angles>260 0 0</gx:angles>\n    <gx:angles>260 0 0</gx:angles>\n    <gx:angles>260 0 0</gx:angles>\n    <gx:angles>250 0 0</gx:angles>\n    <gx:angles>250 0 0</gx:angles>\n    <gx:angles>250 0 0</gx:angles>\n    <gx:angles>260 0 0</gx:angles>\n    <speed>277</speed>\n    <speed>288</speed>\n    <speed>283</speed>\n    <speed>291</speed>\n    <speed>283</speed>\n    <speed>284</speed>\n    <speed>298</speed>\n    <speed>288</speed>\n    <speed>288</speed>\n    <speed>278</speed>\n    <speed>283</speed>\n    <speed>288</speed>\n    <num>10</num>\n    <num>20</num>\n    <num>30</num>\n    <num>40</num>\n    <num>50</num>\n    <num>60</num>\n    <num>70</num>\n    <num>80</num>\n    <num>90</num>\n    <num>100</num>\n    <num>110</num>\n    <num>120</num>\n</gx:Track></Placemark>\n<Placemark>\n  <name>DC95</name>\n  <adflag>A</adflag>\n  <flightid>DAL2858</flightid>\n  <styleUrl>#arrival</styleUrl>\n<gx:Track>\n    <altitudeMode>absolute</altitudeMode>\n    <extrude>1</extrude>\n    <when>2010-05-01T13:00:00-05</when>\n    <when>2010-05-01T13:00:03-05</when>\n    <when>2010-05-01T13:00:07-05</when>\n    <when>2010-05-01T13:00:12-05</when>\n    <when>2010-05-01T13:00:17-05</when>\n    <when>2010-05-01T13:00:21-05</when>\n    <when>2010-05-01T13:00:26-05</when>\n    <when>2010-05-01T13:00:30-05</when>\n    <when>2010-05-01T13:00:35-05</when>\n    <when>2010-05-01T13:00:40-05</when>\n    <when>2010-05-01T13:00:44-05</when>\n    <when>2010-05-01T13:00:49-05</when>\n    <when>2010-05-01T13:00:54-05</when>\n    <when>2010-05-01T13:00:58-05</when>\n    <when>2010-05-01T13:01:00-05</when>\n    <gx:coord>-93.1962465696187 44.4584257162471 3078</gx:coord>\n    <gx:coord>-93.1954858158128 44.462643897726 3078</gx:coord>\n    <gx:coord>-93.1945524569257 44.4696206853623 3048</gx:coord>\n    <gx:coord>-93.1935347734104 44.4765680167011 3048</gx:coord>\n    <gx:coord>-93.1921548885013 44.4834366892852 3048</gx:coord>\n    <gx:coord>-93.1912787899895 44.4902740201102 3048</gx:coord>\n    <gx:coord>-93.190869393024 44.496999598511 3048</gx:coord>\n    <gx:coord>-93.190355669541 44.503701889363 3048</gx:coord>\n    <gx:coord>-93.1899042890233 44.510392533924 3048</gx:coord>\n    <gx:coord>-93.1894352972433 44.5171043633827 3048</gx:coord>\n    <gx:coord>-93.1887272976791 44.523838031578 3017</gx:coord>\n    <gx:coord>-93.1882343860587 44.5305421014878 2987</gx:coord>\n    <gx:coord>-93.1878483537445 44.5373007218153 2987</gx:coord>\n    <gx:coord>-93.187206305476 44.5440099500882 2956</gx:coord>\n    <gx:coord>-93.1870547021374 44.5466877366242 2956</gx:coord>\n    <gx:angles>10 0 0</gx:angles>\n    <gx:angles>10 0 0</gx:angles>\n    <gx:angles>10 0 0</gx:angles>\n    <gx:angles>10 0 0</gx:angles>\n    <gx:angles>10 0 0</gx:angles>\n    <gx:angles>0 0 0</gx:angles>\n    <gx:angles>0 0 0</gx:angles>\n    <gx:angles>0 0 0</gx:angles>\n    <gx:angles>0 0 0</gx:angles>\n    <gx:angles>0 0 0</gx:angles>\n    <gx:angles>0 0 0</gx:angles>\n    <gx:angles>0 0 0</gx:angles>\n    <gx:angles>0 0 0</gx:angles>\n    <gx:angles>0 0 0</gx:angles>\n    <gx:angles>0 0 0</gx:angles>\n    <speed>378</speed>\n    <speed>370</speed>\n    <speed>381</speed>\n    <speed>373</speed>\n    <speed>384</speed>\n    <speed>367</speed>\n    <speed>365</speed>\n    <speed>377</speed>\n    <speed>362</speed>\n    <speed>362</speed>\n    <speed>362</speed>\n    <speed>362</speed>\n    <speed>368</speed>\n    <speed>355</speed>\n    <speed>362</speed>\n    <num>10</num>\n    <num>20</num>\n    <num>30</num>\n    <num>40</num>\n    <num>50</num>\n    <num>60</num>\n    <num>70</num>\n    <num>80</num>\n    <num>90</num>\n    <num>100</num>\n    <num>110</num>\n    <num>120</num>\n    <num>130</num>\n    <num>140</num>\n    <num>150</num>\n</gx:Track></Placemark>\n<Placemark>\n  <name>B737</name>\n  <adflag>A</adflag>\n  <flightid>SWA1488</flightid>\n  <styleUrl>#arrival</styleUrl>\n<gx:Track>\n    <altitudeMode>absolute</altitudeMode>\n    <extrude>1</extrude>\n    <when>2010-05-01T13:00:00-05</when>\n    <when>2010-05-01T13:00:01-05</when>\n    <when>2010-05-01T13:00:06-05</when>\n    <when>2010-05-01T13:00:11-05</when>\n    <when>2010-05-01T13:00:15-05</when>\n    <when>2010-05-01T13:00:20-05</when>\n    <when>2010-05-01T13:00:24-05</when>\n    <when>2010-05-01T13:00:29-05</when>\n    <when>2010-05-01T13:00:34-05</when>\n    <when>2010-05-01T13:00:38-05</when>\n    <when>2010-05-01T13:00:43-05</when>\n    <when>2010-05-01T13:00:48-05</when>\n    <when>2010-05-01T13:00:52-05</when>\n    <when>2010-05-01T13:00:57-05</when>\n    <when>2010-05-01T13:01:00-05</when>\n    <gx:coord>-92.7436038977339 45.0176449723009 2438</gx:coord>\n    <gx:coord>-92.745419752639 45.0178405701636 2438</gx:coord>\n    <gx:coord>-92.7525586927583 45.0181852080204 2438</gx:coord>\n    <gx:coord>-92.7599978682742 45.0189437491361 2438</gx:coord>\n    <gx:coord>-92.7673964649616 45.0200176804669 2438</gx:coord>\n    <gx:coord>-92.7743047878147 45.0206512321095 2438</gx:coord>\n    <gx:coord>-92.7812211106102 45.0212438545962 2438</gx:coord>\n    <gx:coord>-92.7880905786106 45.0219352711124 2438</gx:coord>\n    <gx:coord>-92.7948110303679 45.0225135550872 2438</gx:coord>\n    <gx:coord>-92.8016256231407 45.0231539091809 2377</gx:coord>\n    <gx:coord>-92.808436321378 45.0237782407713 2316</gx:coord>\n    <gx:coord>-92.8153060032773 45.0245123996427 2255</gx:coord>\n    <gx:coord>-92.8220950756464 45.0250388052127 2194</gx:coord>\n    <gx:coord>-92.8289929014999 45.0256725515916 2164</gx:coord>\n    <gx:coord>-92.8342709686589 45.0263726025032 2118.25</gx:coord>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <gx:angles>280 0 0</gx:angles>\n    <speed>280</speed>\n    <speed>293</speed>\n    <speed>284</speed>\n    <speed>288</speed>\n    <speed>274</speed>\n    <speed>272</speed>\n    <speed>279</speed>\n    <speed>263</speed>\n    <speed>263</speed>\n    <speed>262</speed>\n    <speed>262</speed>\n    <speed>275</speed>\n    <speed>270</speed>\n    <speed>277</speed>\n    <speed>287</speed>\n    <num>10</num>\n    <num>20</num>\n    <num>30</num>\n    <num>40</num>\n    <num>50</num>\n    <num>60</num>\n    <num>70</num>\n    <num>80</num>\n    <num>90</num>\n    <num>100</num>\n    <num>110</num>\n    <num>120</num>\n    <num>130</num>\n    <num>140</num>\n    <num>150</num>\n</gx:Track></Placemark>\n<Placemark>\n  <name>A318</name>\n  <adflag>A</adflag>\n  <flightid>FFT106</flightid>\n  <styleUrl>#arrival</styleUrl>\n<gx:Track>\n    <altitudeMode>absolute</altitudeMode>\n    <extrude>1</extrude>\n    <when>2010-05-01T13:00:00-05</when>\n    <when>2010-05-01T13:00:05-05</when>\n    <when>2010-05-01T13:00:09-05</when>\n    <when>2010-05-01T13:00:14-05</when>\n    <when>2010-05-01T13:00:19-05</when>\n    <when>2010-05-01T13:00:23-05</when>\n    <when>2010-05-01T13:00:28-05</when>\n    <when>2010-05-01T13:00:33-05</when>\n    <when>2010-05-01T13:00:37-05</when>\n    <when>2010-05-01T13:00:42-05</when>\n    <when>2010-05-01T13:00:47-05</when>\n    <when>2010-05-01T13:00:51-05</when>\n    <when>2010-05-01T13:00:56-05</when>\n    <when>2010-05-01T13:01:00-05</when>\n    <gx:coord>-93.2974568508014 45.0687622602847 1432</gx:coord>\n    <gx:coord>-93.2934457905393 45.0660257042941 1371</gx:coord>\n    <gx:coord>-93.2902010482642 45.0627382200457 1341</gx:coord>\n    <gx:coord>-93.2880735868205 45.0592062737728 1280</gx:coord>\n    <gx:coord>-93.2866251180089 45.0556538417996 1280</gx:coord>\n    <gx:coord>-93.2855706436895 45.0521555770546 1249</gx:coord>\n    <gx:coord>-93.2848929213344 45.0486326683558 1249</gx:coord>\n    <gx:coord>-93.284149302237 45.0450445279501 1219</gx:coord>\n    <gx:coord>-93.2832681542582 45.0414770478452 1219</gx:coord>\n    <gx:coord>-93.2822163760078 45.0378266141909 1219</gx:coord>\n    <gx:coord>-93.2810695206555 45.0339762188888 1249</gx:coord>\n    <gx:coord>-93.2800852709943 45.0300242656845 1249</gx:coord>\n    <gx:coord>-93.2789451826991 45.026165428423 1249</gx:coord>\n    <gx:coord>-93.2776553627852 45.0222881273358 1219</gx:coord>\n    <gx:angles>140 0 0</gx:angles>\n    <gx:angles>150 0 0</gx:angles>\n    <gx:angles>150 0 0</gx:angles>\n    <gx:angles>160 0 0</gx:angles>\n    <gx:angles>170 0 0</gx:angles>\n    <gx:angles>170 0 0</gx:angles>\n    <gx:angles>170 0 0</gx:angles>\n    <gx:angles>170 0 0</gx:angles>\n    <gx:angles>170 0 0</gx:angles>\n    <gx:angles>170 0 0</gx:angles>\n    <gx:angles>170 0 0</gx:angles>\n    <gx:angles>170 0 0</gx:angles>\n    <gx:angles>170 0 0</gx:angles>\n    <gx:angles>170 0 0</gx:angles>\n    <speed>212</speed>\n    <speed>205</speed>\n    <speed>208</speed>\n    <speed>203</speed>\n    <speed>201</speed>\n    <speed>196</speed>\n    <speed>196</speed>\n    <speed>197</speed>\n    <speed>202</speed>\n    <speed>205</speed>\n    <speed>216</speed>\n    <speed>215</speed>\n    <speed>222</speed>\n    <speed>231</speed>\n    <num>10</num>\n    <num>20</num>\n    <num>30</num>\n    <num>40</num>\n    <num>50</num>\n    <num>60</num>\n    <num>70</num>\n    <num>80</num>\n    <num>90</num>\n    <num>100</num>\n    <num>110</num>\n    <num>120</num>\n    <num>130</num>\n    <num>140</num>\n</gx:Track></Placemark>\n<Placemark>\n  <name></name>\n  <adflag>A</adflag>\n  <flightid></flightid>\n  <styleUrl>#arrival</styleUrl>\n<gx:Track>\n    <altitudeMode>absolute</altitudeMode>\n    <extrude>1</extrude>\n    <when>2010-05-01T13:00:00-05</when>\n    <when>2010-05-01T13:00:05-05</when>\n    <when>2010-05-01T13:00:10-05</when>\n    <when>2010-05-01T13:00:14-05</when>\n    <when>2010-05-01T13:00:24-05</when>\n    <when>2010-05-01T13:00:33-05</when>\n    <when>2010-05-01T13:00:37-05</when>\n    <when>2010-05-01T13:00:42-05</when>\n    <when>2010-05-01T13:00:47-05</when>\n    <when>2010-05-01T13:00:51-05</when>\n    <when>2010-05-01T13:00:56-05</when>\n    <when>2010-05-01T13:01:00-05</when>\n    <gx:coord>-93.5287325331323 45.3502794027397 731</gx:coord>\n    <gx:coord>-93.5305174337715 45.3463816209029 731</gx:coord>\n    <gx:coord>-93.532323089283 45.3433065196778 731</gx:coord>\n    <gx:coord>-93.5344374505075 45.3397938806867 731</gx:coord>\n    <gx:coord>-93.5365879669744 45.3355152994798 731</gx:coord>\n    <gx:coord>-93.538455345577 45.3317693717468 731</gx:coord>\n    <gx:coord>-93.5402440337749 45.3288175816964 731</gx:coord>\n    <gx:coord>-93.5420054353005 45.3261482119682 701</gx:coord>\n    <gx:coord>-93.5437972875724 45.3236486426325 701</gx:coord>\n    <gx:coord>-93.5449025453586 45.3213557809437 670</gx:coord>\n    <gx:coord>-93.5460939368394 45.3190373998605 670</gx:coord>\n    <gx:coord>-93.5479457332637 45.3165177805485 670</gx:coord>\n    <gx:angles>200 0 0</gx:angles>\n    <gx:angles>200 0 0</gx:angles>\n    <gx:angles>200 0 0</gx:angles>\n    <gx:angles>200 0 0</gx:angles>\n    <gx:angles>200 0 0</gx:angles>\n    <gx:angles>200 0 0</gx:angles>\n    <gx:angles>200 0 0</gx:angles>\n    <gx:angles>200 0 0</gx:angles>\n    <gx:angles>200 0 0</gx:angles>\n    <gx:angles>200 0 0</gx:angles>\n    <gx:angles>200 0 0</gx:angles>\n    <gx:angles>200 0 0</gx:angles>\n    <speed>202</speed>\n    <speed>180</speed>\n    <speed>166</speed>\n    <speed>171</speed>\n    <speed>162</speed>\n    <speed>157</speed>\n    <speed>143</speed>\n    <speed>145</speed>\n    <speed>156</speed>\n    <speed>147</speed>\n    <speed>147</speed>\n    <speed>150</speed>\n    <num>10</num>\n    <num>20</num>\n    <num>30</num>\n    <num>40</num>\n    <num>50</num>\n    <num>60</num>\n    <num>70</num>\n    <num>80</num>\n    <num>90</num>\n    <num>100</num>\n    <num>110</num>\n    <num>120</num>\n</gx:Track></Placemark>\n<Placemark>\n  <name>CRJ2</name>\n  <adflag>A</adflag>\n  <flightid>SKW4805</flightid>\n  <styleUrl>#arrival</styleUrl>\n</Placemark>\n<Placemark>\n  <name>CRJ2</name>\n  <adflag>A</adflag>\n  <flightid>FLG4092</flightid>\n  <styleUrl>#arrival</styleUrl>\n<gx:Track>\n    <altitudeMode>absolute</altitudeMode>\n    <extrude>1</extrude>\n    <when>2010-05-01T13:00:00-05</when>\n    <when>2010-05-01T13:00:01-05</when>\n    <when>2010-05-01T13:00:06-05</when>\n    <when>2010-05-01T13:00:10-05</when>\n    <when>2010-05-01T13:00:15-05</when>\n    <when>2010-05-01T13:00:20-05</when>\n    <when>2010-05-01T13:00:24-05</when>\n    <when>2010-05-01T13:00:29-05</when>\n    <when>2010-05-01T13:00:34-05</when>\n    <when>2010-05-01T13:00:38-05</when>\n    <when>2010-05-01T13:00:44-05</when>\n    <when>2010-05-01T13:00:49-05</when>\n    <when>2010-05-01T13:00:54-05</when>\n    <gx:coord>-93.1836067392297 44.9110362339843 432.2</gx:coord>\n    <gx:coord>-93.1841170614853 44.910663862492 426</gx:coord>\n    <gx:coord>-93.1867007876887 44.908842129317 426</gx:coord>\n    <gx:coord>-93.1893728799637 44.9069842219291 396</gx:coord>\n    <gx:coord>-93.1919479660705 44.9051548529609 365</gx:coord>\n    <gx:coord>-93.1944798212107 44.9032897679148 365</gx:coord>\n    <gx:coord>-93.197164452306 44.9014210542153 335</gx:coord>\n    <gx:coord>-93.1996234874761 44.8995719817206 335</gx:coord>\n    <gx:coord>-93.2021701211426 44.8975674983317 304</gx:coord>\n    <gx:coord>-93.2050345971567 44.8955942303701 304</gx:coord>\n    <gx:coord>-93.2075455037487 44.8938556558558 304</gx:coord>\n    <gx:coord>-93.2100820128846 44.8918590963212 304</gx:coord>\n    <gx:coord>-93.2127524858241 44.89000250047 256</gx:coord>\n    <gx:angles>220 0 0</gx:angles>\n    <gx:angles>230 0 0</gx:angles>\n    <gx:angles>230 0 0</gx:angles>\n    <gx:angles>230 0 0</gx:angles>\n    <gx:angles>230 0 0</gx:angles>\n    <gx:angles>220 0 0</gx:angles>\n    <gx:angles>220 0 0</gx:angles>\n    <gx:angles>220 0 0</gx:angles>\n    <gx:angles>220 0 0</gx:angles>\n    <gx:angles>220 0 0</gx:angles>\n    <gx:angles>220 0 0</gx:angles>\n    <gx:angles>220 0 0</gx:angles>\n    <gx:angles>220 0 0</gx:angles>\n    <speed>141</speed>\n    <speed>138</speed>\n    <speed>136</speed>\n    <speed>141</speed>\n    <speed>141</speed>\n    <speed>142</speed>\n    <speed>143</speed>\n    <speed>139</speed>\n    <speed>140</speed>\n    <speed>134</speed>\n    <speed>136</speed>\n    <speed>136</speed>\n    <speed>123</speed>\n    <num>10</num>\n    <num>20</num>\n    <num>30</num>\n    <num>40</num>\n    <num>50</num>\n    <num>60</num>\n    <num>70</num>\n    <num>80</num>\n    <num>90</num>\n    <num>100</num>\n    <num>110</num>\n    <num>120</num>\n    <num>130</num>\n</gx:Track></Placemark>\n<Placemark>\n  <name>E170</name>\n  <adflag>A</adflag>\n  <flightid>CPZ5667</flightid>\n  <styleUrl>#arrival</styleUrl>\n<gx:Track>\n    <altitudeMode>absolute</altitudeMode>\n    <extrude>1</extrude>\n    <when>2010-05-01T13:00:00-05</when>\n    <when>2010-05-01T13:00:01-05</when>\n    <when>2010-05-01T13:00:06-05</when>\n    <when>2010-05-01T13:00:10-05</when>\n    <when>2010-05-01T13:00:15-05</when>\n    <when>2010-05-01T13:00:20-05</when>\n    <when>2010-05-01T13:00:24-05</when>\n    <when>2010-05-01T13:00:29-05</when>\n    <when>2010-05-01T13:00:34-05</when>\n    <when>2010-05-01T13:00:38-05</when>\n    <when>2010-05-01T13:00:43-05</when>\n    <when>2010-05-01T13:00:47-05</when>\n    <when>2010-05-01T13:00:52-05</when>\n    <when>2010-05-01T13:00:57-05</when>\n    <when>2010-05-01T13:01:00-05</when>\n    <gx:coord>-92.9496238812799 45.0117549407746 1438.2</gx:coord>\n    <gx:coord>-92.9507065768732 45.0116702587604 1432</gx:coord>\n    <gx:coord>-92.9563739191926 45.0116271226204 1432</gx:coord>\n    <gx:coord>-92.9620225732021 45.0115639668496 1432</gx:coord>\n    <gx:coord>-92.9673675587699 45.0113432900049 1402</gx:coord>\n    <gx:coord>-92.9725115032188 45.0111442254373 1402</gx:coord>\n    <gx:coord>-92.9778810091229 45.0112050922639 1371</gx:coord>\n    <gx:coord>-92.9832227114571 45.0112143826731 1371</gx:coord>\n    <gx:coord>-92.9884546803523 45.0110418166788 1341</gx:coord>\n    <gx:coord>-92.9938268606229 45.0109652220709 1341</gx:coord>\n    <gx:coord>-92.9991151069756 45.010802144845 1310</gx:coord>\n    <gx:coord>-93.0041467584036 45.0105516668541 1310</gx:coord>\n    <gx:coord>-93.0090742909164 45.0105233046799 1280</gx:coord>\n    <gx:coord>-93.0139435770527 45.0106265340001 1280</gx:coord>\n    <gx:coord>-93.0174882575928 45.0106328449121 1256.75</gx:coord>\n    <gx:angles>270 0 0</gx:angles>\n    <gx:angles>270 0 0</gx:angles>\n    <gx:angles>270 0 0</gx:angles>\n    <gx:angles>270 0 0</gx:angles>\n    <gx:angles>270 0 0</gx:angles>\n    <gx:angles>270 0 0</gx:angles>\n    <gx:angles>270 0 0</gx:angles>\n    <gx:angles>270 0 0</gx:angles>\n    <gx:angles>270 0 0</gx:angles>\n    <gx:angles>270 0 0</gx:angles>\n    <gx:angles>270 0 0</gx:angles>\n    <gx:angles>270 0 0</gx:angles>\n    <gx:angles>270 0 0</gx:angles>\n    <gx:angles>270 0 0</gx:angles>\n    <gx:angles>270 0 0</gx:angles>\n    <speed>214</speed>\n    <speed>207</speed>\n    <speed>202</speed>\n    <speed>208</speed>\n    <speed>207</speed>\n    <speed>205</speed>\n    <speed>203</speed>\n    <speed>202</speed>\n    <speed>209</speed>\n    <speed>199</speed>\n    <speed>196</speed>\n    <speed>200</speed>\n    <speed>193</speed>\n    <speed>194</speed>\n    <speed>185</speed>\n    <num>10</num>\n    <num>20</num>\n    <num>30</num>\n    <num>40</num>\n    <num>50</num>\n    <num>60</num>\n    <num>70</num>\n    <num>80</num>\n    <num>90</num>\n    <num>100</num>\n    <num>110</num>\n    <num>120</num>\n    <num>130</num>\n    <num>140</num>\n    <num>150</num>\n</gx:Track></Placemark>\n</Folder>\n<Folder>\n  <name>Departures</name>\n</Folder>\n<Folder>\n  <name>Overflights</name>\n</Folder>\n</Document>\n</kml>\n--></div>\n\n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/OGCExceptionReport.html",
    "content": "<html>\n<head> \n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_read_exception(t) {\n\n        t.plan(21);\n\n        // OCG WMS 1.3.0 exceptions\n        var text = '<?xml version=\"1.0\" encoding=\"UTF-8\"?> ' +\n'<ServiceExceptionReport version=\"1.3.0\" xmlns=\"http://www.opengis.net/ogc\"' +\n'    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"' +\n'    xsi:schemaLocation=\"http://www.opengis.net/ogc' +\n'    http://schemas.opengis.net/wms/1.3.0/exceptions_1_3_0.xsd\">' +\n'    <ServiceException> Plain text message about an error. </ServiceException>' +\n'    <ServiceException code=\"InvalidUpdateSequence\"> Another error message, this one with a service exception code supplied. </ServiceException>' +\n'    <ServiceException>' +\n'        <![CDATA[ Error in module <foo.c>, line 42' +\n'A message that includes angle brackets in text must be enclosed in a Character Data Section as in this example. All XML-like markup is ignored except for this sequence of three closing characters:' +\n']]>' +\n'    </ServiceException>' +\n'    <ServiceException>' +\n'        <![CDATA[ <Module>foo.c</Module> <Error>An error occurred</Error> <Explanation>Similarly, actual XML can be enclosed in a CDATA section. A generic parser will ignore that XML, but application-specific software may choose to process it.</Explanation> ]]>' +\n'    </ServiceException>' +\n'</ServiceExceptionReport>';\n\n        var parser = new OpenLayers.Format.OGCExceptionReport();\n        var result = parser.read(text);\n\n        var exceptions = result.exceptionReport.exceptions;\n\n        var testWMS = function(exceptions) {\n            t.eq(exceptions.length, 4, \"We expect 4 exception messages\");\n            t.eq(exceptions[0].text, \" Plain text message about an error. \", \"First error message correctly parsed\");\n            t.eq(exceptions[1].code, \"InvalidUpdateSequence\", \"Code of second error message correctly parsed\");\n            t.eq(exceptions[1].text, \" Another error message, this one with a service exception code supplied. \", \"Text of second error message correctly parsed\");\n            t.eq(OpenLayers.String.trim(exceptions[2].text), \"Error in module <foo.c>, line 42A message that includes angle brackets in text must be enclosed in a Character Data Section as in this example. All XML-like markup is ignored except for this sequence of three closing characters:\", \"Third message correctly parsed\");\n            t.eq(OpenLayers.String.trim(exceptions[3].text), \"<Module>foo.c</Module> <Error>An error occurred</Error> <Explanation>Similarly, actual XML can be enclosed in a CDATA section. A generic parser will ignore that XML, but application-specific software may choose to process it.</Explanation>\", \"Fourth message correctly parsed\");\n        };\n\n        testWMS(exceptions);\n\n        // OGC WMS 1.1.1 exceptions\n        text = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?> <!DOCTYPE ServiceExceptionReport SYSTEM \"http://schemas.opengis.net/wms/1.1.1/WMS_exception_1_1_1.dtd\"> ' +\n'<ServiceExceptionReport version=\"1.1.1\">' +\n'    <ServiceException> Plain text message about an error. </ServiceException>' +\n'    <ServiceException code=\"InvalidUpdateSequence\"> Another error message, this one with a service exception code supplied. </ServiceException>' +\n'    <ServiceException>' +\n'        <![CDATA[ Error in module <foo.c>, line 42' +\n'A message that includes angle brackets in text must be enclosed in a Character Data Section as in this example. All XML-like markup is ignored except for this sequence of three closing characters:' +\n']]>' +\n'    </ServiceException>' +\n'    <ServiceException>' +\n'        <![CDATA[ <Module>foo.c</Module> <Error>An error occurred</Error> <Explanation>Similarly, actual XML can be enclosed in a CDATA section. A generic parser will ignore that XML, but application-specific software may choose to process it.</Explanation> ]]>' +\n'    </ServiceException>' +\n'</ServiceExceptionReport>';\n        result = parser.read(text);\n        exceptions = result.exceptionReport.exceptions;\n        testWMS(exceptions);\n\n        // OGC WFS 1.0.0 exceptions\n        text = '<?xml version=\"1.0\" ?> ' +\n'<ServiceExceptionReport version=\"1.2.0\" xmlns=\"http://www.opengis.net/ogc\"' +\n'    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"' +\n'    xsi:schemaLocation=\"http://www.opengis.net/ogc http://schemas.opengis.net/wfs/1.0.0/OGC-exception.xsd\">' +\n'    <ServiceException code=\"999\" locator=\"INSERT STMT 01\"> parse error: missing closing tag for element WKB_GEOM </ServiceException>' +\n'</ServiceExceptionReport>';\n        result = parser.read(text);\n        t.eq(result.exceptionReport.exceptions[0].code, \"999\", \"code parsed correctly\");\n        t.eq(result.exceptionReport.exceptions[0].locator, \"INSERT STMT 01\", \"locator parsed correctly\");\n        t.eq(result.exceptionReport.exceptions[0].text, \" parse error: missing closing tag for element WKB_GEOM \", \"error text parsed correctly\");\n\n        // OGC WFS 1.1.0 exceptions that use OWSCommon 1.0\n        text = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n'<ows:ExceptionReport language=\"en\" version=\"1.0.0\"' +\n'    xsi:schemaLocation=\"http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/owsExceptionReport.xsd\"' +\n'    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ows=\"http://www.opengis.net/ows\">' +\n'    <ows:Exception locator=\"foo\" exceptionCode=\"InvalidParameterValue\">' +\n'        <ows:ExceptionText>Update error: Error occured updating features</ows:ExceptionText>' +\n'        <ows:ExceptionText>Second exception line</ows:ExceptionText>' +\n'    </ows:Exception>' +\n'</ows:ExceptionReport>';\n\n        var result = parser.read(text);\n        var report = result.exceptionReport;\n        t.eq(report.version, \"1.0.0\", \"Version parsed correctly\");\n        t.eq(report.language, \"en\", \"Language parsed correctly\");\n        var exception = report.exceptions[0];\n        t.eq(exception.code, \"InvalidParameterValue\", \"exceptionCode properly parsed\");\n        t.eq(exception.locator, \"foo\", \"locator properly parsed\");\n        t.eq(exception.texts[0], \"Update error: Error occured updating features\", \"ExceptionText correctly parsed\");\n        t.eq(exception.texts[1], \"Second exception line\", \"Second ExceptionText correctly parsed\");\n    }\n\n    </script> \n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/OSM.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script src=\"../data/osm.js\"></script> \n    <script type=\"text/javascript\">\n    \n    function test_Format_OSM_constructor(t) { \n        t.plan(5); \n         \n        var options = {'foo': 'bar'}; \n        var format = new OpenLayers.Format.OSM(options); \n        t.ok(format instanceof OpenLayers.Format.OSM, \n             \"new OpenLayers.Format.OSM returns object\" ); \n        t.eq(format.foo, \"bar\", \"constructor sets options correctly\"); \n        t.eq(typeof format.read, \"function\", \"format has a read function\"); \n        t.eq(typeof format.write, \"function\", \"format has a write function\"); \n        t.eq(format.externalProjection.getCode(), \"EPSG:4326\", \n             \"default external projection is EPSG:4326\"); \n    } \n\n    function test_Format_OSM_node(t) {\n        t.plan(4);\n        var f = new OpenLayers.Format.OSM();\n        var features = f.read(osm_test_data['node']);\n        var feat = features[0];\n        t.eq(feat.attributes, {}, \"attributes is empty\");\n        t.eq(feat.osm_id, 200545, \"internal osm_id property set correctly\");\n        t.eq(feat.geometry.x, -1.8166417, \"lon is correct\"); \n        t.eq(feat.geometry.y, 52.5503033, \"lat is correct\"); \n    }\n\n    function test_Format_OSM_node_with_tags(t) {\n        t.plan(5);\n        var f = new OpenLayers.Format.OSM();\n        var features = f.read(osm_test_data['node_with_tags']);\n        var feat = features[0];\n        t.eq(feat.attributes, {'a':'b'}, \"attributes match\");\n        t.eq(feat.osm_id, 200545, \"internal osm_id property set correctly\");\n        t.eq(feat.fid, \"node.200545\", \"OSM-based FID set correctly.\");\n        t.eq(feat.geometry.x, -1.8166417, \"lon is correct\"); \n        t.eq(feat.geometry.y, 52.5503033, \"lat is correct\"); \n    }\n\n    function test_Format_OSM_way(t) {\n        t.plan(1);\n        var f = new OpenLayers.Format.OSM();\n        var features = f.read(osm_test_data['way']);\n        t.eq(features.length, 11, \"Multiple features\");\n    }\n\n    function test_Format_OSM_way_checkTags(t) {\n        t.plan(8);\n        var f = new OpenLayers.Format.OSM({checkTags: true});\n        var features = f.read(osm_test_data['way']);\n        t.eq(features.length, 1, \"One feature\");\n        var feat = features[0];\n        t.eq(feat.osm_id, 4685537, \"OSM ID set correctly.\");\n        t.eq(feat.fid, \"way.4685537\", \"OSM-based FID set correctly.\");\n        t.eq(feat.geometry.CLASS_NAME, \"OpenLayers.Geometry.Polygon\", \"returned as polygon\");\n        t.eq(feat.geometry.components[0].components.length, 11, \"Correct number of components\"); \n        t.eq(feat.geometry.components[0].components[0].osm_id, 29783472, \"OSM ID set on components\");\n        t.eq(feat.geometry.toString(), \"POLYGON((-1.8164007 52.5501836,-1.8170311 52.5506035,-1.8164092 52.5509559,-1.8169385 52.5513103,-1.8159626 52.5517893,-1.8145067 52.5518461,-1.8143197 52.5511883,-1.8141177 52.5506446,-1.8151451 52.5501275,-1.8157703 52.5505521,-1.8164007 52.5501836))\", \"WKT of feature is correct\");\n        t.eq(feat.attributes.landuse, \"school\", \"landuse attribute correct\");\n    }\n\n    function test_Format_OSM_node_way(t) {\n        t.plan(1)\n        var f = new OpenLayers.Format.OSM();\n        var features = f.read(osm_test_data['node_way']);\n        t.eq(features.length, 13, \"Multiple features\");\n    }\n\n    function test_Format_OSM_node_way_checkTags(t) {\n        t.plan(9)\n        var f = new OpenLayers.Format.OSM({checkTags: true});\n        var features = f.read(osm_test_data['node_way']);\n        t.eq(features.length, 3, \"Multiple features\");\n        \n        var feat = features[1];\n        t.eq(feat.geometry.CLASS_NAME, \"OpenLayers.Geometry.Point\", \"point class\");\n        t.ok(feat.attributes != {}, \"feature has attributes\");\n        \n        var feat = features[2];\n        t.eq(feat.geometry.CLASS_NAME, \"OpenLayers.Geometry.Point\", \"point class\");\n        t.ok(feat.attributes != {}, \"feature has attributes\");\n        \n        feat = features[0];\n        t.eq(feat.osm_id, 21329267, \"OSM ID set correctly\");\n        t.eq(feat.attributes.highway, \"unclassified\", \"highway attribute is correct.\"); \n        t.eq(feat.geometry.CLASS_NAME, \"OpenLayers.Geometry.LineString\", \"returned as linestring\");\n        t.eq(feat.geometry.components.length, 12, \"correct number of segments\");\n    }\n\n    function test_Format_OSM_node_way_checkTags2(t) {\n        t.plan(5)\n        var f = new OpenLayers.Format.OSM({checkTags: true});\n        var features = f.read(osm_test_data['node_way2']);\n        t.eq(features.length, 1, \"One feature\");\n        var feat = features[0];\n        t.eq(feat.osm_id, 21329267, \"OSM ID set correctly\");\n        t.eq(feat.attributes.highway, \"unclassified\", \"highway attribute is correct.\"); \n        t.eq(feat.geometry.CLASS_NAME, \"OpenLayers.Geometry.LineString\", \"returned as linestring\");\n        t.eq(feat.geometry.components.length, 12, \"correct number of segments\");\n    }\n    \n    function test_Format_OSM_serialize(t) {\n        t.plan(4);\n        var f = new OpenLayers.Format.OSM({checkTags: true});\n        for (var key in osm_serialized_data) {\n            var input = f.read(osm_test_data[key]);\n            var output = f.write(input);\n            output = output.replace(/<\\?[^>]*\\?>/, '');\n            t.eq(output, osm_serialized_data[key], key + \" serialized correctly\");\n        }\n    }\n\n    function test_Format_OSM_write_reproject(t) {\n        t.plan(1);\n        var f = new OpenLayers.Format.OSM({checkTags: true, 'internalProjection': new OpenLayers.Projection(\"EPSG:900913\")});\n        var feat = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(100000, 100000)\n            );\n        var data = f.write([feat]);\n        var f = new OpenLayers.Format.OSM();\n        var features = f.read(data);\n        t.eq(OpenLayers.Util.toFloat(features[0].geometry.x, 3), .898, \"exported to lonlat and re-read as lonlat correctly\")\n    }\n    \n    function test_Format_OSM_route(t) {\n        t.plan(1)\n        var f = new OpenLayers.Format.OSM({relationsParsers: {route: OpenLayers.Format.OSM.routeParser}});\n        var features = f.read(osm_test_data['route_simple']);\n        t.eq(features.length, 7, \"Multiple features\");\n    }\n\n    function test_Format_OSM_route_checkTags(t) {\n        t.plan(8)\n        var f = new OpenLayers.Format.OSM({checkTags: true, relationsParsers: {route: OpenLayers.Format.OSM.routeParser}});\n        var features = f.read(osm_test_data['route_simple']);\n        t.eq(features.length, 1, \"Nb features\");\n        var feat = features[0];\n        t.eq(feat.osm_id, -1131, \"OSM ID set correctly\");\n        t.eq(feat.attributes.type, \"route\", \"type is correct.\"); \n        t.eq(feat.attributes.route, \"bicycle\", \"highway is correct.\"); \n        t.eq(feat.geometry.CLASS_NAME, \"OpenLayers.Geometry.MultiLineString\", \"returned as linestring\");\n        t.eq(feat.geometry.components.length, 2, \"correct number of lines\");\n        t.eq(feat.geometry.components[0].components.length, 2, \"correct number of componemt\");\n        t.eq(feat.geometry.components[1].components.length, 3, \"correct number of componemt\");\n    }\n\n    function test_Format_OSM_boundary(t) {\n        t.plan(1)\n        var f = new OpenLayers.Format.OSM({relationsParsers: {boundary: OpenLayers.Format.OSM.multipolygonParser}});\n        var features = f.read(osm_test_data['boundary']);\n        t.eq(features.length, 8, \"Multiple features\");\n    }\n\n    function test_Format_OSM_boundary_checkTags(t) {\n        t.plan(7)\n        var f = new OpenLayers.Format.OSM({checkTags: true, relationsParsers: {boundary: OpenLayers.Format.OSM.multipolygonParser}});\n        var features = f.read(osm_test_data['boundary']);\n        t.eq(features.length, 1, \"Nb features\");\n        var feat = features[0];\n        t.eq(feat.osm_id, 365555, \"OSM ID set correctly\");\n        t.eq(feat.attributes.name, \"Name\", \"name is correct.\"); \n        t.eq(feat.attributes.type, \"boundary\", \"type is correct.\"); \n        t.eq(feat.attributes.admin_level, \"8\", \"admin_level is correct.\"); \n        t.eq(feat.geometry.CLASS_NAME, \"OpenLayers.Geometry.MultiPolygon\", \"returned as MultiPolygon\");\n        t.eq(feat.geometry.components.length, 1, \"correct number of componemt\");\n    }\n\n    function test_Format_OSM_multipolygon(t) {\n        t.plan(1)\n        var f = new OpenLayers.Format.OSM({relationsParsers: {multipolygon: OpenLayers.Format.OSM.multipolygonParser}});\n        var features = f.read(osm_test_data['multipolygon']);\n        t.eq(features.length, 14, \"Multiple features\");\n    }\n\n    function test_Format_OSM_multipolygon_checkTags(t) {\n        t.plan(8)\n        var f = new OpenLayers.Format.OSM({checkTags: true, relationsParsers: {multipolygon: OpenLayers.Format.OSM.multipolygonParser}});\n        var features = f.read(osm_test_data['multipolygon']);\n        t.eq(features.length, 1, \"Nb features\");\n        var feat = features[0];\n        t.eq(feat.osm_id, -1131, \"OSM ID set correctly\");\n        t.eq(feat.attributes.name, \"Name\", \"name is correct.\"); \n        t.eq(feat.attributes.type, \"multipolygon\", \"type is correct.\"); \n        t.eq(feat.attributes.landuse, \"forest\", \"landuse is correct.\"); \n        t.eq(feat.geometry.CLASS_NAME, \"OpenLayers.Geometry.MultiPolygon\", \"returned as multipolygon\");\n        t.eq(feat.geometry.components.length, 1, \"correct number of componemt\");\n        t.eq(feat.geometry.components[0].components.length, 2, \"correct number of sub componemt\");\n    }\n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/OWSCommon/v1_0_0.html",
    "content": "<html>\n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_read_exception(t) {\n        t.plan(6);\n        var text = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n'<ows:ExceptionReport language=\"en\" version=\"1.0.0\"' +\n'    xsi:schemaLocation=\"http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/owsExceptionReport.xsd\"' +\n'    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ows=\"http://www.opengis.net/ows\">' +\n'    <ows:Exception locator=\"foo\" exceptionCode=\"InvalidParameterValue\">' +\n'        <ows:ExceptionText>Update error: Error occured updating features</ows:ExceptionText>' +\n'        <ows:ExceptionText>Second exception line</ows:ExceptionText>' +\n'    </ows:Exception>' +\n'</ows:ExceptionReport>';\n\n        var format = new OpenLayers.Format.OWSCommon();\n        var result = format.read(text);\n        var report = result.exceptionReport;\n        t.eq(report.version, \"1.0.0\", \"Version parsed correctly\");\n        t.eq(report.language, \"en\", \"Language parsed correctly\");\n        var exception = report.exceptions[0];\n        t.eq(exception.code, \"InvalidParameterValue\", \"exceptionCode properly parsed\");\n        t.eq(exception.locator, \"foo\", \"locator properly parsed\");\n        t.eq(exception.texts[0], \"Update error: Error occured updating features\", \"ExceptionText correctly parsed\");\n        t.eq(exception.texts[1], \"Second exception line\", \"Second ExceptionText correctly parsed\");\n    }\n\n    </script> \n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/OWSCommon/v1_1_0.html",
    "content": "<html>\n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_read_exception(t) {\n        t.plan(6);\n        var text = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n'<ows:ExceptionReport xml:lang=\"en\" version=\"1.1.0\"' +\n'    xsi:schemaLocation=\"http://www.opengis.net/ows http://schemas.opengis.net/ows/1.1.0/owsExceptionReport.xsd\"' +\n'    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ows=\"http://www.opengis.net/ows/1.1\">' +\n'    <ows:Exception locator=\"foo\" exceptionCode=\"InvalidParameterValue\">' +\n'        <ows:ExceptionText>Update error: Error occured updating features</ows:ExceptionText>' +\n'        <ows:ExceptionText>Second exception line</ows:ExceptionText>' +\n'    </ows:Exception>' +\n'</ows:ExceptionReport>';\n\n        var format = new OpenLayers.Format.OWSCommon();\n        var result = format.read(text);\n        var report = result.exceptionReport;\n        t.eq(report.version, \"1.1.0\", \"Version parsed correctly\");\n        t.eq(report.language, \"en\", \"Language parsed correctly\");\n        var exception = report.exceptions[0];\n        t.eq(exception.code, \"InvalidParameterValue\", \"exceptionCode properly parsed\");\n        t.eq(exception.locator, \"foo\", \"locator properly parsed\");\n        t.eq(exception.texts[0], \"Update error: Error occured updating features\", \"ExceptionText correctly parsed\");\n        t.eq(exception.texts[1], \"Second exception line\", \"Second ExceptionText correctly parsed\");\n    }\n\n    </script> \n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/OWSContext/v0_3_1.html",
    "content": "<html> \n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_read_wmswfs(t) {\n        t.plan(17);\n        // taken from http://www.ogcnetwork.net/schemas/owc/0.3.1/context_nested.xml\n        // adapted: add an extra slash (roads/railways) in the Title of the WMS layer to test nesting\n        var text = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n            '<OWSContext version=\"0.3.1\" id=\"ows-context-ex-1-v3\" xmlns=\"http://www.opengis.net/ows-context\"' +\n            '\txmlns:gml=\"http://www.opengis.net/gml\" xmlns:kml=\"http://www.opengis.net/kml/2.2\"' +\n            '\txmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:ows=\"http://www.opengis.net/ows\"' +\n            '\txmlns:sld=\"http://www.opengis.net/sld\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"' +\n            '\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"' +\n            '\txsi:schemaLocation=\"http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd\">' +\n            '\t<General>' +\n            '\t\t<ows:BoundingBox crs=\"EPSG:4326\">' +\n            '\t\t\t<ows:LowerCorner>-117 32</ows:LowerCorner>' +\n            '\t\t\t<ows:UpperCorner>-116 33</ows:UpperCorner>' +\n            '\t\t</ows:BoundingBox>' +\n            '\t\t<ows:Title>OWS Context version 0.3.1 showing nested layers</ows:Title>' +\n            '\t</General>' +\n            '\t<ResourceList>' +\n            '\t\t<!-- WMS Example -->' +\n            '\t\t<Layer name=\"topp:major_roads\" queryable=\"1\" hidden=\"1\">' +\n            '\t\t\t<ows:Title>Tiger 2005fe major roads/railways</ows:Title>' +\n            '\t\t\t<ows:OutputFormat>image/png</ows:OutputFormat>' +\n            '\t\t\t<Server service=\"urn:ogc:serviceType:WMS\" version=\"1.1.1\">' +\n            '\t\t\t\t<OnlineResource' +\n            '\t\t\t\t\txlink:href=\"http://sigma.openplans.org:8080/geoserver/wms?SERVICE=WMS\"/>' +\n            '\t\t\t</Server>' +\n            '\t\t\t<!-- WFS Example -->' +\n            '\t\t\t<Layer name=\"topp:gnis_pop\" hidden=\"0\">' +\n            '\t\t\t\t<ows:Title>GNIS Population</ows:Title>' +\n            '\t\t\t\t<Server service=\"urn:ogc:serviceType:WFS\" version=\"1.0.0\">' +\n            '\t\t\t\t\t<OnlineResource xlink:href=\"geoserver/wfs?\"/>' +\n            '\t\t\t\t</Server>' +\n            '\t\t\t</Layer>' +\n            '\t\t</Layer>' +\n            '\t</ResourceList>' +\n            '</OWSContext>';\n        var parser = new OpenLayers.Format.OWSContext();\n        var map = new OpenLayers.Map('map', {allOverlays: true, fractionalZoom: true});\n        var context = parser.read(text, {map: map});\n        t.eq(context.layers.length, 2, \"2 layers parsed from OWSContext document\");\n        t.eq(context.layers[1].metadata.nestingPath[0], \"Tiger 2005fe major roads/railways\", \"Nesting path correctly set\");\n        t.ok(context.layers[0] instanceof OpenLayers.Layer.WMS, \"First layer is a WMS layer\"); \n        t.ok(context.layers[1] instanceof OpenLayers.Layer.Vector, \"Second layer is a vector layer\");\n        t.eq(context.layers[0].params.LAYERS, \"topp:major_roads\", \"WMS layer name correctly read\");\n        t.eq(context.layers[0].params.FORMAT, \"image/png\", \"WMS format correctly read\");\n        t.eq(context.layers[0].url, \"http://sigma.openplans.org:8080/geoserver/wms?SERVICE=WMS\", \"Layer url correctly read\");\n        t.eq(context.layers[0].getVisibility(), false, \"WMS Layer is hidden\");\n        t.ok(context.layers[0].queryable, \"WMS layer is queryable\");\n        t.eq(context.layers[0].name, \"Tiger 2005fe major roads/railways\", \"Title correctly set\");\n        t.ok(context.layers[1].protocol instanceof OpenLayers.Protocol.WFS.v1_0_0, \"Vector layer configured with a WFS Protocol\");\n        t.eq(context.layers[1].protocol.url, \"geoserver/wfs?\", \"WFS url set correctly\");\n        t.ok(context.layers[1].strategies[0] instanceof OpenLayers.Strategy.BBOX, \"BBOX strategy configured correctly\");\n        t.eq(context.layers[1].name, \"GNIS Population\", \"Title of second layer correctly set\");\n        t.eq(context.layers[1].getVisibility(), true, \"Second layer is visible\");\n        map.zoomToExtent(new OpenLayers.Bounds(-117, 32, -116, 33));\n        var owc = parser.write(map, {id: 'ows-context-ex-1-v3', title: 'OWS Context version 0.3.1 showing nested layers'});\n        t.xml_eq(text, owc, \"Can we roundtrip this nested OWSContext with a WMS and WFS layer?\");\n        t.eq(context.layers[1].metadata.nestingPath[0], \"Tiger 2005fe major roads/railways\", \"Nesting path is preserved even after calling write\");\n    }\n\n    function test_write_wmswfs(t) {\n        t.plan(1);\n        var lon = 5;\n        var lat = 40;\n        var zoom = 5;\n        var map = new OpenLayers.Map( 'map' );\n        var layer = new OpenLayers.Layer.WMS(\n            \"OpenLayers WMS\",\n            \"http://labs.metacarta.com/wms/vmap0\",\n            {layers: 'basic'},\n            {singleTile: true}\n        );\n        var wfs = new OpenLayers.Layer.Vector(\"myroads\", {\n            strategies: [new OpenLayers.Strategy.BBOX()],\n            protocol: new OpenLayers.Protocol.WFS({\n                url:  \"foo/wfs?\",\n                featureType: \"roads\",\n                featureNS: \"http://foo/myns\"\n            })\n        });\n        map.addLayers([layer, wfs]);\n        map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);\n\n        var owc = new OpenLayers.Format.OWSContext();\n        var output = owc.write(map, {id: 'foo'});\n        var expected = '<OWSContext xmlns=\"http://www.opengis.net/ows-context\" version=\"0.3.1\" id=\"foo\" xsi:schemaLocation=\"http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><General><ows:BoundingBox xmlns:ows=\"http://www.opengis.net/ows\" crs=\"EPSG:4326\"><ows:LowerCorner>-5.986328125 29.013671875</ows:LowerCorner><ows:UpperCorner>15.986328125 50.986328125</ows:UpperCorner></ows:BoundingBox><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">OpenLayers OWSContext</ows:Title></General><ResourceList><Layer name=\"basic\" queryable=\"0\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">OpenLayers WMS</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/jpeg</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://labs.metacarta.com/wms/vmap0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server></Layer><Layer name=\"feature:roads\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">myroads</ows:Title><Server version=\"1.0.0\" service=\"urn:ogc:serviceType:WFS\"><OnlineResource xlink:href=\"foo/wfs?\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server></Layer></ResourceList></OWSContext>';\n        t.xml_eq(output, expected, \"OWSContext with a WMS and a WFS layer generated correctly\");\n    }\n\n    function test_write_wmsinlinegml(t) {\n        t.plan(1);\n        var lon = 5;\n        var lat = 40;\n        var zoom = 5;\n        var map = new OpenLayers.Map( 'map' );\n        var layer = new OpenLayers.Layer.WMS(\n            \"OpenLayers WMS\",\n            \"http://labs.metacarta.com/wms/vmap0\",\n            {layers: 'basic'},\n            {singleTile: true}\n        );\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);\n\n        var vector = new OpenLayers.Layer.Vector();\n        map.addLayer(vector);\n        var feature1 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,1));\n        var feature2 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,0));\n        vector.addFeatures(feature1);\n        vector.addFeatures(feature2);\n        var owc = new OpenLayers.Format.OWSContext();\n        var output = owc.write(map, {id: 'foo'});\n        var expected = '<OWSContext xmlns=\"http://www.opengis.net/ows-context\" version=\"0.3.1\" id=\"foo\" xsi:schemaLocation=\"http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><General><ows:BoundingBox xmlns:ows=\"http://www.opengis.net/ows\" crs=\"EPSG:4326\"><ows:LowerCorner>-5.986328125 29.013671875</ows:LowerCorner><ows:UpperCorner>15.986328125 50.986328125</ows:UpperCorner></ows:BoundingBox><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">OpenLayers OWSContext</ows:Title></General><ResourceList><Layer name=\"basic\" queryable=\"0\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">OpenLayers WMS</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/jpeg</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://labs.metacarta.com/wms/vmap0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server></Layer><Layer name=\"vector\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\"/><InlineGeometry><gml:boundedBy xmlns:gml=\"http://www.opengis.net/gml\"><gml:Box><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">0,0 1,1</gml:coordinates></gml:Box></gml:boundedBy><gml:featureMember xmlns:gml=\"http://www.opengis.net/gml\"><feature:vector xmlns:feature=\"http://mapserver.gis.umn.edu/mapserver\"><feature:geometry><gml:Point><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">0,1</gml:coordinates></gml:Point></feature:geometry></feature:vector></gml:featureMember><gml:featureMember xmlns:gml=\"http://www.opengis.net/gml\"><feature:vector xmlns:feature=\"http://mapserver.gis.umn.edu/mapserver\"><feature:geometry><gml:Point><gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,0</gml:coordinates></gml:Point></feature:geometry></feature:vector></gml:featureMember></InlineGeometry></Layer></ResourceList></OWSContext>';\n        t.xml_eq(output, expected, \"OWSContext with a WMS and an inline GML vector layer generated correctly\");\n    }\n\n    function test_write_inlinegml_no_features(t){\n        var lon = 5,\n            lat = 40,\n            zoom = 5,\n            map = new OpenLayers.Map( 'map' ),\n            layer = new OpenLayers.Layer.WMS(\n                \"OpenLayers WMS\",\n                \"http://labs.metacarta.com/wms/vmap0\",\n                {layers: 'basic'},\n                {singleTile: true}\n            ),\n            vector = new OpenLayers.Layer.Vector();\n\n        map.addLayers( [ layer, vector ] );\n        map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);\n\n        var owc = new OpenLayers.Format.OWSContext(),\n            output,\n            caughtException = false,\n            expectedXml = '<OWSContext xmlns=\"http://www.opengis.net/ows-context\" version=\"0.3.1\" id=\"foo\" xsi:schemaLocation=\"http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><General><ows:BoundingBox xmlns:ows=\"http://www.opengis.net/ows\" crs=\"EPSG:4326\"><ows:LowerCorner>-5.986328125 29.013671875</ows:LowerCorner><ows:UpperCorner>15.986328125 50.986328125</ows:UpperCorner></ows:BoundingBox><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">OpenLayers OWSContext</ows:Title></General><ResourceList><Layer name=\"basic\" queryable=\"0\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">OpenLayers WMS</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/jpeg</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://labs.metacarta.com/wms/vmap0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server></Layer><Layer name=\"vector\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\"/><InlineGeometry/></Layer></ResourceList></OWSContext>';\n\n        try {\n            output = owc.write(map, {id: 'foo'});\n        } catch (e){\n            caughtException = true;\n        }\n\n        if (caughtException) {\n            t.plan(1);\n            t.fail('OWSContext with a WMS and an inline vector layer failed and threw an exception');\n        } else {\n            t.plan(2);\n            t.ok(true, 'OWSContext with a WMS and an inline vector layer generated without exception');\n            t.xml_eq(output, expectedXml, \"OWSContext with a WMS and an inline vector layer generated correctly\");\n        }\n    }\n\n    function test_read_inline(t) {\n        t.plan(10);\n        var text = '<?xml version=\"1.0\" encoding=\"UTF-8\"?><OWSContext xmlns=\"http://www.opengis.net/ows-context\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:kml=\"http://www.opengis.net/kml/2.2\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:ows=\"http://www.opengis.net/ows\" xmlns:sld=\"http://www.opengis.net/sld\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" version=\"0.3.1\" id=\"ows-context-ex-1-v3\" xsi:schemaLocation=\"http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.0/owsContext.xsd\"><General><ows:BoundingBox crs=\"urn:ogc:def:crs:EPSG:6.6:4326\"><ows:LowerCorner>-117.44667178362664 32.57086210449395</ows:LowerCorner><ows:UpperCorner>-116.74066794885977 32.921986352104064</ows:UpperCorner></ows:BoundingBox><ows:Title>OWS Context version 0.3.0 Inline KML and GML examples</ows:Title></General><ResourceList><!-- WMS Example --><Layer name=\"topp:major_roads\" queryable=\"1\" hidden=\"1\">\t<ows:Title>Tiger 2005fe major roads</ows:Title>\t<ows:OutputFormat>image/png</ows:OutputFormat><Server service=\"urn:ogc:serviceType:WMS\" version=\"1.1.1\"><OnlineResource xlink:href=\"http://sigma.openplans.org:8080/geoserver/wms?SERVICE=WMS\"/></Server></Layer><!-- Inline KML Example --><Layer name=\"archsites\"><ows:Title>Architectural Sites</ows:Title><kml:Document><kml:name>opengeo:archsites 1 to 100</kml:name><kml:Style id=\"archsitesStyle\"><kml:IconStyle><kml:color>ffffffff</kml:color><kml:colorMode>normal</kml:colorMode><kml:Icon><kml:href>http://maps.google.com/mapfiles/kml/pal4/icon25.png</kml:href></kml:Icon></kml:IconStyle></kml:Style><kml:Placemark id=\"archsites.1\"><kml:name>Signature Rock</kml:name><kml:description>Signature Rock Description</kml:description><kml:styleUrl>#archsitesStyle</kml:styleUrl><kml:Point><kml:coordinates>-103.82681673,44.38162255</kml:coordinates></kml:Point></kml:Placemark></kml:Document></Layer><!-- Inline GML Example --><Layer name=\"coastg\"><ows:Title>Coastg as GML Points</ows:Title><InlineGeometry><gml:boundedBy><gml:Box><gml:coord><gml:X>-43.379</gml:X><gml:Y>72.746</gml:Y></gml:coord><gml:coord><gml:X>-43.390</gml:X><gml:Y>72.755</gml:Y></gml:coord></gml:Box></gml:boundedBy><gml:featureMember><au1:coastg xmlns:au1=\"http://www.ionicsoft.com/wfs\" fid=\"coastg.0\"><au1:MERGE>1</au1:MERGE><au1:AREA>0.0020000000000000005</au1:AREA><au1:PERIMETER>0.167</au1:PERIMETER><au1:GEOMETRY><gml:Polygon srsName=\"urn:ogc:def:crs:EPSG:6.6:4326\"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>129.29167335893825,71.9583353847737 129.29167335893825,72.0000014248896 129.33332733905414,72.0000014248896 129.33332733905414,71.9583353847737 129.29167335893825,71.9583353847737</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></au1:GEOMETRY></au1:coastg></gml:featureMember><gml:featureMember><au1:coastg xmlns:au1=\"http://www.ionicsoft.com/wfs\" fid=\"coastg.1\"><au1:MERGE>1</au1:MERGE><au1:AREA>0.0020000000000000005</au1:AREA><au1:PERIMETER>0.167</au1:PERIMETER><au1:GEOMETRY><gml:Polygon srsName=\"urn:ogc:def:crs:EPSG:6.6:4326\"><gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>135.45832829609282,35.66666796381659 135.41667179597695,35.66666796381659 135.41667179597695,35.70833202393249 135.45832829609282,35.70833202393249 135.45832829609282,35.66666796381659</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs></gml:Polygon></au1:GEOMETRY></au1:coastg></gml:featureMember></InlineGeometry></Layer></ResourceList></OWSContext>';\n        var parser = new OpenLayers.Format.OWSContext();\n        var context = parser.read(text, {map: 'map'});\n        t.ok(context.layers[1] instanceof OpenLayers.Layer.Vector, \"Inline KML results in a vector layer\");\n        t.eq(context.layers[1].features.length, 1, \"Inline KML layer has one feature\");\n        t.ok(context.layers[1].features[0].geometry instanceof OpenLayers.Geometry.Point, \"KML feature is a point\");\n        t.eq(context.layers[1].features[0].attributes.description, \"Signature Rock Description\", \"KML Description correctly parsed\");\n        t.eq(context.layers[1].features[0].fid, \"archsites.1\", \"KML feature id correctly parsed\");\n        t.eq(context.layers[1].features[0].style.externalGraphic, \"http://maps.google.com/mapfiles/kml/pal4/icon25.png\", \"Style url for KML feature correctly parsed\");\n        t.ok(context.layers[2] instanceof OpenLayers.Layer.Vector, \"Inline GML results in a vector layer\");\n        t.eq(context.layers[2].features.length, 2, \"Inline GML layer has two features\");\n        t.ok(context.layers[2].features[0].geometry instanceof OpenLayers.Geometry.Polygon, \"GML feature is a polygon\");\n        t.eq(context.layers[2].features[0].attributes.MERGE, \"1\", \"GML attribute read correctly\");\n    }\n\n    function test_read_gml(t) {\n        t.plan(5);\n        var text = '<?xml version=\"1.0\" encoding=\"UTF-8\"?><OWSContext version=\"0.3.0\" id=\"ows-context-ex-1-v3\" xmlns=\"http://www.opengis.net/ows-context\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:kml=\"http://www.opengis.net/kml/2.2\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:ows=\"http://www.opengis.net/ows\" xmlns:sld=\"http://www.opengis.net/sld\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.0/owsContext.xsd\"><General><ows:BoundingBox crs=\"urn:ogc:def:crs:EPSG:6.6:4326\"><ows:LowerCorner>-117.44667178362664 32.57086210449395</ows:LowerCorner><ows:UpperCorner>-116.74066794885977 32.921986352104064</ows:UpperCorner></ows:BoundingBox><ows:Title>OWS Context version 0.3.0 examples</ows:Title></General><ResourceList><Layer name=\"basic\" queryable=\"0\" hidden=\"0\" opacity=\"1\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">OpenLayers WMS</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/jpeg</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://labs.metacarta.com/wms/vmap0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server></Layer><!-- Referenced GML Example --><Layer name=\"Landuse\"><ows:Title>Boston Landuse Polygons</ows:Title><Server service=\"urn:ogc:serviceType:GML\" version=\"2.1.2\" title=\"Cadcorp GeognoSIS.NET Web Feature Service\"><OnlineResource xlink:href=\"gml/MassGIS/LandUse.gml\"/></Server><sld:MinScaleDenominator>5000</sld:MinScaleDenominator><sld:MaxScaleDenominator>50000</sld:MaxScaleDenominator><MaxFeatures>99</MaxFeatures></Layer></ResourceList></OWSContext>';\n        var parser = new OpenLayers.Format.OWSContext();\n        var context = parser.read(text, {map: 'map'});\n        t.ok(context.layers[1].protocol instanceof OpenLayers.Protocol.HTTP, \"serviceType GML is translated into an HTTP Protocol\");\n        t.eq(context.layers[1].protocol.url, \"gml/MassGIS/LandUse.gml\", \"Url of GML file correctly set\");\n        t.ok(context.layers[1].protocol.format instanceof OpenLayers.Format.GML, \"GML Format associated with protocol\");\n        t.eq(Math.round(context.layers[1].minScale), 50000, \"Minscale correctly read\");\n        t.eq(Math.round(context.layers[1].maxScale), 5000, \"Maxscale correctly read\");\n    }\n\n    function test_read_kml(t) {\n        t.plan(3);\n        var text = '<OWSContext xmlns=\"http://www.opengis.net/ows-context\" version=\"0.3.1\" id=\"foo\" xsi:schemaLocation=\"http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><General><ows:BoundingBox xmlns:ows=\"http://www.opengis.net/ows\" crs=\"EPSG:4326\"><ows:LowerCorner>-5.986328125 27.9150390625</ows:LowerCorner><ows:UpperCorner>15.986328125 52.0849609375</ows:UpperCorner></ows:BoundingBox><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">OpenLayers OWSContext</ows:Title></General><ResourceList><Layer name=\"basic\" queryable=\"0\" hidden=\"0\" opacity=\"1\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">OpenLayers WMS</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/jpeg</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://labs.metacarta.com/wms/vmap0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server></Layer><Layer><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">KML</ows:Title><Server version=\"2.2\" service=\"urn:ogc:serviceType:KML\"><OnlineResource xlink:href=\"foo/sundials.kml\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server></Layer></ResourceList></OWSContext>';\n        var parser = new OpenLayers.Format.OWSContext();\n        var context = parser.read(text, {map: 'map'});\n        t.ok(context.layers[1].protocol instanceof OpenLayers.Protocol.HTTP, \"serviceType KML is translated into an HTTP Protocol\");\n        t.eq(context.layers[1].protocol.url, \"foo/sundials.kml\", \"Url of KML file correctly set\");\n        t.ok(context.layers[1].protocol.format instanceof OpenLayers.Format.KML, \"KML Format associated with protocol\");\n    }\n\n    function test_write_gml(t) {\n        t.plan(1);\n        var lon = 5;\n        var lat = 40;\n        var zoom = 5;\n        var map = new OpenLayers.Map( 'map' );\n        var layer = new OpenLayers.Layer.WMS(\n            \"OpenLayers WMS\",\n            \"http://labs.metacarta.com/wms/vmap0\",\n            {layers: 'basic'},\n            {singleTile: true}\n        );\n        var sundials = new OpenLayers.Layer.Vector(\"GML\", {\n            projection: map.displayProjection,\n            strategies: [new OpenLayers.Strategy.Fixed()],\n            protocol: new OpenLayers.Protocol.HTTP({\n                url: \"foo/sundials.gml\",\n                format: new OpenLayers.Format.GML()\n            })\n        });\n        map.addLayers([layer, sundials]);\n        map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);\n\n        var owc = new OpenLayers.Format.OWSContext();\n        var output = owc.write(map, {id: 'foo'});\n        var expected = '<OWSContext xmlns=\"http://www.opengis.net/ows-context\" version=\"0.3.1\" id=\"foo\" xsi:schemaLocation=\"http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><General><ows:BoundingBox xmlns:ows=\"http://www.opengis.net/ows\" crs=\"EPSG:4326\"><ows:LowerCorner>-5.986328125 29.013671875</ows:LowerCorner><ows:UpperCorner>15.986328125 50.986328125</ows:UpperCorner></ows:BoundingBox><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">OpenLayers OWSContext</ows:Title></General><ResourceList><Layer name=\"basic\" queryable=\"0\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">OpenLayers WMS</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/jpeg</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://labs.metacarta.com/wms/vmap0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server></Layer><Layer><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">GML</ows:Title><Server version=\"2.1.2\" service=\"urn:ogc:serviceType:GML\"><OnlineResource xlink:href=\"foo/sundials.gml\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server></Layer></ResourceList></OWSContext>';\n        t.xml_eq(output, expected, \"OWSContext with a WMS and a GML vector layer generated correctly\");\n    }\n\n    function test_write_kml(t) {\n        t.plan(1);\n        var lon = 5;\n        var lat = 40;\n        var zoom = 5;\n        var map = new OpenLayers.Map( 'map' );\n        var layer = new OpenLayers.Layer.WMS(\n            \"OpenLayers WMS\",\n            \"http://labs.metacarta.com/wms/vmap0\",\n            {layers: 'basic'},\n            {singleTile: true}\n        );\n        var sundials = new OpenLayers.Layer.Vector(\"KML\", {\n            projection: map.displayProjection,\n            strategies: [new OpenLayers.Strategy.Fixed()],\n            protocol: new OpenLayers.Protocol.HTTP({\n                url: \"foo/sundials.kml\",\n                format: new OpenLayers.Format.KML({\n                    extractStyles: true\n                })\n            })\n        });\n        map.addLayers([layer, sundials]);\n        map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);\n\n        var owc = new OpenLayers.Format.OWSContext();\n        var output = owc.write(map, {id: 'foo'});\n        var expected = '<OWSContext xmlns=\"http://www.opengis.net/ows-context\" version=\"0.3.1\" id=\"foo\" xsi:schemaLocation=\"http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><General><ows:BoundingBox xmlns:ows=\"http://www.opengis.net/ows\" crs=\"EPSG:4326\"><ows:LowerCorner>-5.986328125 29.013671875</ows:LowerCorner><ows:UpperCorner>15.986328125 50.986328125</ows:UpperCorner></ows:BoundingBox><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">OpenLayers OWSContext</ows:Title></General><ResourceList><Layer name=\"basic\" queryable=\"0\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">OpenLayers WMS</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/jpeg</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://labs.metacarta.com/wms/vmap0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server></Layer><Layer><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">KML</ows:Title><Server version=\"2.2\" service=\"urn:ogc:serviceType:KML\"><OnlineResource xlink:href=\"foo/sundials.kml\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server></Layer></ResourceList></OWSContext>';\n        t.xml_eq(output, expected, \"OWSContext with a WMS and a KML vector layer generated correctly\");\n    }\n\n    function test_nested(t) {\n        t.plan(4);\n        var text = '<OWSContext xmlns=\"http://www.opengis.net/ows-context\" version=\"0.3.1\" id=\"machu\" xsi:schemaLocation=\"http://www.opengis.net/ows-context http://www.ogcnetwork.net/schemas/owc/0.3.1/owsContext.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><General><ows:BoundingBox xmlns:ows=\"http://www.opengis.net/ows\" crs=\"EPSG:4326\"><ows:LowerCorner>-40 30</ows:LowerCorner><ows:UpperCorner>55 125</ows:UpperCorner></ows:BoundingBox><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">OpenLayers OWSContext</ows:Title></General><ResourceList><Layer><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">General Bathymetric Chart</ows:Title><Layer><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">GEBCO</ows:Title><Layer name=\"GEBCO\" queryable=\"1\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">GEBCO</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/jpeg</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://foo/bar_bathymetry?\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href=\"http://foo/services/geoservices/legends/machu/gebco.png\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></LegendURL></Style></StyleList></Layer></Layer></Layer><Layer><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">Administrative boundaries</ows:Title><Layer><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">National boundaries</ows:Title><Layer name=\"GAUL\" queryable=\"1\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">GAUL</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/png</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://foo/bar_topography?\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href=\"http://foo/services/geoservices/legends/machu/administrative_boundaries_land.png\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></LegendURL></Style></StyleList></Layer></Layer><Layer><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">Maritime boundaries</ows:Title><Layer name=\"World_Maritime_Boundaries_v4_20090811\" queryable=\"1\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">World_Maritime_Boundaries_v4_20090811</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/png</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://foo/bar_topography?\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href=\"http://foo/services/geoservices/legends/machu/administrative_boundaries_sea.png\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></LegendURL></Style></StyleList></Layer></Layer></Layer><Layer><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">Cultural Heritage Underwater</ows:Title><Layer><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">Sites</ows:Title><Layer name=\"ARCH_NL\" queryable=\"1\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">ARCH_NL</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/png</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://foo/bar_nl?\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href=\"http://foo/services/geoservices/legends/machu/cultural_heritage_underwater.png\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></LegendURL></Style></StyleList></Layer><Layer name=\"ARCH_PL\" queryable=\"1\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">ARCH_PL</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/png</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://foo/bar_pl?\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href=\"http://foo/services/geoservices/legends/machu/cultural_heritage_underwater.png\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></LegendURL></Style></StyleList></Layer><Layer name=\"ARCH_PT\" queryable=\"1\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">ARCH_PT</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/png</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://foo/bar_pt?\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href=\"http://foo/services/geoservices/legends/machu/cultural_heritage_underwater.png\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></LegendURL></Style></StyleList></Layer><Layer name=\"ARCH_BE\" queryable=\"1\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">ARCH_BE</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/png</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://foo/bar_be?\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href=\"http://foo/services/geoservices/legends/machu/cultural_heritage_underwater.png\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></LegendURL></Style></StyleList></Layer><Layer name=\"ARCH_SE\" queryable=\"1\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">ARCH_SE</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/png</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://foo/bar_se?\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href=\"http://foo/services/geoservices/legends/machu/cultural_heritage_underwater.png\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></LegendURL></Style></StyleList></Layer><Layer name=\"ARCH_DE\" queryable=\"1\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">ARCH_DE</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/png</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://foo/bar_de?\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href=\"http://foo/services/geoservices/legends/machu/cultural_heritage_underwater.png\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></LegendURL></Style></StyleList></Layer><Layer name=\"ARCH_UK\" queryable=\"1\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">ARCH_UK</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/png</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://foo/bar_uk?\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server><StyleList><Style><Name>default</Name><Title>default</Title><LegendURL><OnlineResource xlink:href=\"http://foo/services/geoservices/legends/machu/cultural_heritage_underwater.png\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></LegendURL></Style></StyleList></Layer></Layer></Layer><Layer><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">Theme1</ows:Title><Layer><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">layer1</ows:Title><Layer name=\"TEST_AREA_BE\" queryable=\"1\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">TEST_AREA_BE</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/png</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://foo/bar_be?\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server></Layer><Layer name=\"TEST_AREA_PT\" queryable=\"1\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">TEST_AREA_PT</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/png</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://foo/bar_pt?\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server></Layer></Layer></Layer><Layer><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">Theme2</ows:Title><Layer><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">layer1</ows:Title><Layer name=\"TEST_AREA_SE\" queryable=\"1\" hidden=\"0\"><ows:Title xmlns:ows=\"http://www.opengis.net/ows\">TEST_AREA_SE</ows:Title><ows:OutputFormat xmlns:ows=\"http://www.opengis.net/ows\">image/png</ows:OutputFormat><Server version=\"1.1.1\" service=\"urn:ogc:serviceType:WMS\"><OnlineResource xlink:href=\"http://foo/bar_se?\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></Server></Layer></Layer></Layer></ResourceList></OWSContext>';\n        var parser = new OpenLayers.Format.OWSContext();\n        var map = new OpenLayers.Map('map', {allOverlays: true, fractionalZoom: true});\n        var context = parser.read(text, {map: map});\n        t.eq(map.layers.length, 13, \"13 layers parsed from document\");\n        t.eq(map.layers[0].metadata.nestingPath.join(\"/\"), \"General Bathymetric Chart/GEBCO\", \"Category layers read correctly\");\n        t.eq(map.layers[0].metadata.styles[0].legend.url, \"http://foo/services/geoservices/legends/machu/gebco.png\", \"Legend url correctly parsed\");\n        map.zoomToExtent(new OpenLayers.Bounds(-40, 30, 55, 125));\n        var owc = parser.write(map, {id: 'machu'});\n        t.xml_eq(text, owc, \"Can we roundtrip nested OWSContext successfully?\");\n    }\n\n    </script> \n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:500px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/QueryStringFilter.html",
    "content": "<html>\n<head>\n  <script src=\"../../lib/OpenLayers.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_constructor(t) {\n        t.plan(4);\n        var options = {'foo': 'bar'};\n        var format  = new OpenLayers.Format.QueryStringFilter(options);\n        t.ok(format instanceof OpenLayers.Format.QueryStringFilter,\n           \"new OpenLayers.Format.QueryStringFilter object\");\n        t.eq(format.foo, \"bar\", \"constructor sets options correctly\")\n        t.eq(typeof format.write, 'function', 'format has a write function');\n        t.eq(format.options, options, \"format.options correctly set\");\n    }\n\n    function test_write(t) {\n        t.plan(30);\n\n        // setup\n\n        var format, filter, params;\n\n        format = new OpenLayers.Format.QueryStringFilter();\n\n        // 1 test\n        filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.BBOX,\n            value: new OpenLayers.Bounds(0, 1, 2, 3)\n        });\n        params = format.write(filter);\n        t.eq(params.bbox, [0, 1, 2, 3], \"correct bbox param if passed a BBOX filter\");\n\n        // 3 tests\n        var lon = 100, lat = 200, tolerance = 10;\n        filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.DWITHIN,\n            value: new OpenLayers.Geometry.Point(lon, lat),\n            distance: tolerance\n        });\n        params = format.write(filter);\n        t.eq(params.lon, lon, \"correct lon param if passed a DWITHIN filter\");\n        t.eq(params.lat, lat, \"correct lat param if passed a DWITHIN filter\");\n        t.eq(params.tolerance, tolerance, \"correct tolerance param if passed a DWITHIN filter\");\n\n        // 2 tests\n        filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.WITHIN,\n            value: new OpenLayers.Geometry.Point(lon, lat)\n        });\n        params = format.write(filter);\n        t.eq(params.lon, lon, \"correct lon param if passed a WITHIN filter\");\n        t.eq(params.lat, lat, \"correct lat param if passed a WITHIN filter\");\n\n        // Some bbox filters used in the next tests.\n\n        var bboxFilter1 = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.BBOX,\n            value:  new OpenLayers.Bounds(0, 0, 10, 10)\n        });\n\n        var bboxFilter2 = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.BBOX,\n            value:  new OpenLayers.Bounds(0, 0, 20, 20)\n        });\n\n        // 1 test\n        filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.AND,\n            filters: []\n        });\n        params = format.write(filter);\n        t.eq(params, {}, \"returns empty object if given empty AND Logical filter\");\n\n        // 1 test\n        filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.OR,\n            filters: [\n                bboxFilter1\n            ]\n        });\n        params = format.write(filter);\n        t.eq(params, {}, \"does not support OR Logical filter\");\n\n        // 1 test\n        filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.AND,\n            filters: [\n                bboxFilter1\n            ]\n        });\n        params = format.write(filter);\n        t.eq(params.bbox, [0, 0, 10, 10],\n             \"correct bbox param if passed a Logical filter containing a BBOX\");\n\n        // 1 test\n        filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.AND,\n            filters: [\n                bboxFilter1, bboxFilter2\n            ]\n        });\n        params = format.write(filter);\n        t.eq(params.bbox, [0, 0, 20, 20],\n             \"correct bbox param if passed multiple BBOX filter in a Logical filter\");\n\n        // 2 tests\n        filter = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.EQUAL_TO,\n            property: \"foo\",\n            value: \"bar\"\n        });\n        params = format.write(filter);\n        t.eq(params.queryable[0], \"foo\",\n             \"correct queryable param if passed an EQUAL_TO filter\");\n        t.eq(params[\"foo__eq\"], \"bar\",\n             \"correct param key and value if passed an EQUAL_TO filter\");\n\n        // 2 tests\n        filter = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.NOT_EQUAL_TO,\n            property: \"foo\",\n            value: \"bar\"\n        });\n        params = format.write(filter);\n        t.eq(params.queryable[0], \"foo\",\n             \"correct queryable param if passed an NOT_EQUAL_TO filter\");\n        t.eq(params[\"foo__ne\"], \"bar\",\n             \"correct param key and value if passed an NOT_EQUAL_TO filter\");\n\n        // 2 tests\n        filter = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.LESS_THAN,\n            property: \"foo\",\n            value: \"bar\"\n        });\n        var params = format.write(filter);\n        t.eq(params.queryable[0], \"foo\",\n             \"correct queryable param if passed an LESS_THAN filter\");\n        t.eq(params[\"foo__lt\"], \"bar\",\n             \"correct param key and value if passed an LESS_THAN filter\");\n\n        // 2 tests\n        filter = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.LESS_THAN_OR_EQUAL_TO,\n            property: \"foo\",\n            value: \"bar\"\n        });\n        var params = format.write(filter);\n        t.eq(params.queryable[0], \"foo\",\n             \"correct queryable param if passed an LESS_THAN_OR_EQUAL_TO filter\");\n        t.eq(params[\"foo__lte\"], \"bar\",\n             \"correct param key and value if passed an LESS_THAN_OR_EQUAL_TO filter\");\n\n        // 2 tests\n        filter = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.GREATER_THAN,\n            property: \"foo\",\n            value: \"bar\"\n        });\n        params = format.write(filter);\n        t.eq(params.queryable[0], \"foo\",\n             \"correct queryable param if passed an GREATER_THAN filter\");\n        t.eq(params[\"foo__gt\"], \"bar\",\n             \"correct param key and value if passed an GREATER_THAN filter\");\n\n        // 2 tests\n        filter = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO,\n            property: \"foo\",\n            value: \"bar\"\n        });\n        params = format.write(filter);\n        t.eq(params.queryable[0], \"foo\",\n             \"correct queryable param if passed an GREATER_THAN_OR_EQUAL_TO filter\");\n        t.eq(params[\"foo__gte\"], \"bar\",\n             \"correct param key and value if passed an GREATER_THAN_OR_EQUAL_TO filter\");\n\n        // 2 tests\n        filter = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.LIKE,\n            property: \"foo\",\n            value: \"bar\"\n        });\n        params = format.write(filter);\n        t.eq(params.queryable[0], \"foo\",\n             \"correct queryable param if passed a LIKE filter\");\n        t.eq(params[\"foo__ilike\"], \"bar\",\n             \"correct param key and value if passed an LIKE filter\");\n\n        // 4 tests\n        filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.AND,\n            filters: [\n                new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                    property: \"foo\",\n                    value: \"bar\"\n                }),\n                new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.LESS_THAN,\n                    property: \"foo2\",\n                    value: \"baz\"\n                })\n            ]\n        });\n        params = format.write(filter);\n        t.eq(params.queryable[0], \"foo\",\n             \"correct queryable param if passed an EQUAL_TO filter within a AND filter\");\n        t.eq(params[\"foo__eq\"], \"bar\",\n             \"correct param key and value if passed an EQUAL_TO filter within a AND filter\");\n        t.eq(params.queryable[1], \"foo2\",\n             \"correct queryable param if passed a LESS_THAN filter within a AND filter\");\n        t.eq(params[\"foo2__lt\"], \"baz\",\n             \"correct param key and value if passed a LESS_THAN filter within a AND filter\");\n\n        // 2 tests\n        format = new OpenLayers.Format.QueryStringFilter({wildcarded: true});\n        filter = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.LIKE,\n            property: \"foo\",\n            value: \"bar\"\n        });\n        params = format.write(filter);\n        t.eq(params.queryable[0], \"foo\",\n             \"correct queryable param if passed a LIKE filter (wildcarded true)\");\n        t.eq(params[\"foo__ilike\"], \"%bar%\",\n             \"correct param key and value if passed an LIKE filter (wildcarded true)\");\n    }\n\n    function test_regex2value(t) {\n        t.plan(16);\n\n        // setup\n\n        var format = new OpenLayers.Format.QueryStringFilter();\n\n        var value;\n        var filter = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.LIKE,\n            property: \"prop\"\n        });\n        \n        function serialize(value) {\n            filter.value = value;\n            return format.write(filter).prop__ilike;\n        }\n\n        // test\n\n        value = serialize(\"foo\");\n        t.eq(value, \"foo\", 'regex2value converts \"foo\" to \"foo\"');\n\n        value = serialize(\"foo%\");\n        t.eq(value, \"foo\\\\%\", 'regex2value converts \"foo%\" to \"foo\\\\%\"');\n\n        value = serialize(\"foo.*\");\n        t.eq(value, \"foo%\", 'regex2value converts \"foo.*\" to \"foo%\"');\n\n        value = serialize(\"f.*oo.*\");\n        t.eq(value, \"f%oo%\", 'regex2value converts \"f.*oo.*\" to \"f%oo%\"');\n\n        value = serialize(\"foo.\");\n        t.eq(value, \"foo_\", 'regex2value converts \"foo.\" to \"foo_\"');\n\n        value = serialize(\"f.oo.\");\n        t.eq(value, \"f_oo_\", 'regex2value converts \"f.oo.\" to \"f_oo_\"');\n\n        value = serialize(\"f.oo.*\");\n        t.eq(value, \"f_oo%\", 'regex2value converts \"f.oo.*\" to \"f_oo%\"');\n\n        value = serialize(\"foo\\\\\\\\\");\n        t.eq(value, \"foo\\\\\\\\\", 'regex2value converts \"foo\\\\\\\\\" to \"foo\\\\\\\\\"');\n\n        value = serialize(\"foo\\\\.\");\n        t.eq(value, \"foo.\", 'regex2value converts \"foo\\\\.\" to \"foo.\"');\n\n        value = serialize(\"foo\\\\\\\\.\");\n        t.eq(value, \"foo\\\\\\\\_\", 'regex2value converts \"foo\\\\\\\\.\" to \"foo\\\\\\\\_\"');\n\n        value = serialize(\"foo\\\\*\");\n        t.eq(value, \"foo*\", 'regex2value converts \"foo\\\\*\" to \"foo*\"');\n\n        value = serialize(\"foo\\\\\\\\*\");\n        t.eq(value, \"foo\\\\\\\\*\", 'regex2value converts \"foo\\\\\\\\*\" to \"foo\\\\\\\\*\"');\n\n        value = serialize(\"foo\\\\\\\\.*\");\n        t.eq(value, \"foo\\\\\\\\%\", 'regex2value converts \"foo\\\\\\\\.*\" to \"foo\\\\\\\\%\"');\n\n        value = serialize(\"fo\\\\.o.*\");\n        t.eq(value, \"fo.o%\", 'regex2value converts from \"fo\\\\.o.*\" to \"fo.o%\"');\n\n        value = serialize(\"fo.*o\\\\.\");\n        t.eq(value, \"fo%o.\", 'regex2value converts from \"fo.*o\\\\.\" to \"to%o.\"');\n\n        value = serialize(\"\\\\*\\\\..*.\\\\\\\\.*\\\\\\\\.%\");\n        t.eq(value, \"*.%_\\\\\\\\%\\\\\\\\_\\\\%\",\n             'regex2value converts from \"\\\\*\\\\..*.\\\\\\\\.*\\\\\\\\.%\" ' +\n             'to \"*.%_\\\\\\\\%\\\\\\\\_\\\\%\"');\n    }\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/SLD/v1_0_0.html",
    "content": "<html> \n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    var xml = new OpenLayers.Format.XML();\n    function readXML(id) {\n        return xml.read(document.getElementById(id).firstChild.nodeValue);\n    }\n\n    var sld =\n        '<StyledLayerDescriptor version=\"1.0.0\" ' +\n            'xmlns=\"http://www.opengis.net/sld\" ' +\n            'xmlns:gml=\"http://www.opengis.net/gml\" ' +\n            'xmlns:ogc=\"http://www.opengis.net/ogc\" ' +\n            'xmlns:xlink=\"http://www.w3.org/1999/xlink\" ' +\n            'xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" ' +\n            'xsi:schemaLocation=\"http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd\">' +\n            '<NamedLayer>' +\n                '<Name>AAA161</Name>' +\n                '<UserStyle>' +\n                    '<FeatureTypeStyle>' +\n                        '<Rule>' +\n                            '<Name>stortsteen</Name>' +\n                            '<ogc:Filter>' +\n                                '<ogc:PropertyIsEqualTo>' +\n                                    '<ogc:PropertyName>CTE</ogc:PropertyName>' +\n                                    '<ogc:Literal>V0305</ogc:Literal>' +\n                                '</ogc:PropertyIsEqualTo>' +\n                            '</ogc:Filter>' +\n                            '<MaxScaleDenominator>50000</MaxScaleDenominator>' +\n                            '<PolygonSymbolizer>' +\n                                '<Fill>' +\n                                    '<CssParameter name=\"fill\">#ffffff</CssParameter>' +\n                                '</Fill>' +\n                                '<Stroke>' +\n                                    '<CssParameter name=\"stroke\">#000000</CssParameter>' +\n                                '</Stroke>' +\n                            '</PolygonSymbolizer>' +\n                            '<TextSymbolizer>' +\n                                '<Label>' +\n                                    'A <ogc:PropertyName>FOO</ogc:PropertyName> label' +\n                                '</Label>' +\n                                '<Font>' +\n                                    '<CssParameter name=\"font-family\">Arial</CssParameter>' +\n                                    '<CssParameter name=\"font-size\">14</CssParameter>' +\n                                    '<CssParameter name=\"font-weight\">bold</CssParameter>' +\n                                    '<CssParameter name=\"font-style\">normal</CssParameter>' +\n                                '</Font>' +\n                                '<LabelPlacement>' +\n                                    '<PointPlacement>' +\n                                        '<AnchorPoint>' +\n                                            '<AnchorPointX>0.5</AnchorPointX>' +\n                                            '<AnchorPointY>0.5</AnchorPointY>' +\n                                        '</AnchorPoint>' +\n                                        '<Displacement>' +\n                                            '<DisplacementX>5</DisplacementX>' +\n                                            '<DisplacementY>5</DisplacementY>' +\n                                        '</Displacement>' +\n                                        '<Rotation>45</Rotation>' +\n                                    '</PointPlacement>' +\n                                '</LabelPlacement>' +\n                                '<Halo>' +\n                                    '<Radius>3</Radius>' +\n                                    '<Fill>' +\n                                        '<CssParameter name=\"fill\">#ffffff</CssParameter>' +\n                                    '</Fill>' +\n                                '</Halo>' +\n                                '<Fill>' +\n                                    '<CssParameter name=\"fill\">#000000</CssParameter>' +\n                                '</Fill>' +\n                            '</TextSymbolizer>' +\n                        '</Rule>' +\n                        '<Rule>' +\n                            '<Name>betonbekleding</Name>' +\n                            '<ogc:Filter>' +\n                                '<ogc:PropertyIsLessThan>' +\n                                    '<ogc:PropertyName>CTE</ogc:PropertyName>' +\n                                    '<ogc:Literal>1000</ogc:Literal>' +\n                                '</ogc:PropertyIsLessThan>' +\n                            '</ogc:Filter>' +\n                            '<MaxScaleDenominator>50000</MaxScaleDenominator>' +\n                            '<PolygonSymbolizer>' +\n                                '<Fill>' +\n                                    '<CssParameter name=\"fill\">#ffff00</CssParameter>' +\n                                '</Fill>' +\n                                '<Stroke>' +\n                                    '<CssParameter name=\"stroke\">#0000ff</CssParameter>' +\n                                '</Stroke>' +\n                            '</PolygonSymbolizer>' +\n                        '</Rule>' +\n                    '</FeatureTypeStyle>' +\n                '</UserStyle>' +\n            '</NamedLayer>' +\n            '<NamedLayer>' +\n                '<Name>Second Layer</Name>' +\n                '<UserStyle>' +\n                    '<FeatureTypeStyle>' +\n                        '<Rule>' +\n                            '<Name>first rule second layer</Name>' +\n                            '<ogc:Filter>' +\n                                '<ogc:Or>' +\n                                    '<ogc:PropertyIsBetween>' +\n                                        '<ogc:PropertyName>number</ogc:PropertyName>' +\n                                        '<ogc:LowerBoundary>' +\n                                            '<ogc:Literal>1064866676</ogc:Literal>' +\n                                        '</ogc:LowerBoundary>' +\n                                        '<ogc:UpperBoundary>' +\n                                            '<ogc:Literal>1065512599</ogc:Literal>' +\n                                        '</ogc:UpperBoundary>' +\n                                    '</ogc:PropertyIsBetween>' +\n                                    '<ogc:PropertyIsLike wildCard=\"*\" singleChar=\".\" escape=\"!\">' +\n                                        '<ogc:PropertyName>cat</ogc:PropertyName>' +\n                                        '<ogc:Literal>*dog.food!*good</ogc:Literal>' +\n                                    '</ogc:PropertyIsLike>' +\n                                    '<ogc:Not>' +\n                                        '<ogc:PropertyIsLessThanOrEqualTo>' +\n                                            '<ogc:PropertyName>FOO</ogc:PropertyName>' +\n                                            '<ogc:Literal>5000</ogc:Literal>' +\n                                        '</ogc:PropertyIsLessThanOrEqualTo>' +\n                                    '</ogc:Not>' +\n                                '</ogc:Or>' +\n                            '</ogc:Filter>' +\n                            '<MaxScaleDenominator>10000</MaxScaleDenominator>' +\n                            '<PointSymbolizer>' +\n                                '<Graphic>' +\n                                    '<Mark>' +\n                                        '<WellKnownName>star</WellKnownName>' +\n                                        '<Fill>' +\n                                            '<CssParameter name=\"fill\">lime</CssParameter>' +\n                                        '</Fill>' +\n                                        '<Stroke>' +\n                                            '<CssParameter name=\"stroke\">olive</CssParameter>' +\n                                            '<CssParameter name=\"stroke-width\">2</CssParameter>' +\n                                        '</Stroke>' +\n                                    '</Mark>' +\n                                    '<Size><ogc:PropertyName>SIZE</ogc:PropertyName></Size>' +\n                                '</Graphic>' +\n                            '</PointSymbolizer>' +\n                        '</Rule>' +\n                    '</FeatureTypeStyle>' +\n                '</UserStyle>' +\n            '</NamedLayer>' +\n        '</StyledLayerDescriptor>';\n\n    function test_read(t) {\n        t.plan(23);\n\n        var xml = new OpenLayers.Format.XML();\n        var sldxml = xml.read(sld);\n\n        // test that format options are considered in read\n        var parser = new OpenLayers.Format.SLD({\n            version: \"1.0.0\",\n            namedLayersAsArray: true\n        });\n        var obj = parser.read(sldxml);\n        t.ok(obj.namedLayers instanceof Array, \"namedLayersAsArray option for read works\");\n\n        parser = new OpenLayers.Format.SLD.v1_0_0();\n        var obj = parser.read(sldxml, {namedLayersAsArray: true});\n        t.ok(obj.namedLayers instanceof Array, \"namedLayersAsArray option for read works\");\n        var arrayLen = obj.namedLayers.length;\n\n        var obj = parser.read(sldxml);\n        t.eq(typeof obj.namedLayers, \"object\", \"read returns a namedLayers object by default\");\n        // test the named layer count\n        var count = 0;\n        for(var key in obj.namedLayers) {\n            ++count;\n        }\n        t.eq(count, arrayLen, \"number of named layers in array equals number of named layers in object\");\n\n        var layer, style, rule;\n\n        // check the first named layer\n        layer = obj.namedLayers[\"AAA161\"];\n        t.ok(layer, \"first named layer exists\");\n        t.ok(layer.userStyles instanceof Array, \"(AAA161) layer has array of user styles\");\n        t.eq(layer.userStyles.length, 1, \"(AAA161) first layer has a single user style\");\n        t.eq(layer.userStyles[0].rules.length, 2, \"(AAA161) first style has two rules\");\n        var rule = layer.userStyles[0].rules[0];\n        t.ok(rule.filter, \"(AAA161) first rule has a filter\");\n        var symbolizer = rule.symbolizer;\n        t.ok(symbolizer, \"(AAA161) first rule has a symbolizer\");\n        var poly = symbolizer[\"Polygon\"];\n        t.eq(poly.fillColor, \"#ffffff\", \"(AAA161) first rule has proper fill\");\n        t.eq(poly.strokeColor, \"#000000\", \"(AAA161) first rule has proper stroke\");\n        var text = symbolizer[\"Text\"];\n        t.eq(text.label, \"A ${FOO} label\", \"(AAA161) first rule has proper text label\");\n        t.eq(layer.userStyles[0].propertyStyles[\"label\"], true, \"label added to propertyStyles\");\n        t.eq(text.fontFamily, \"Arial\", \"(AAA161) first rule has proper font family\");\n        t.eq(text.fontColor, \"#000000\", \"(AAA161) first rule has proper text fill\");\n        t.eq(text.haloRadius, \"3\", \"(AAA161) first rule has proper halo radius\");\n        t.eq(text.haloColor, \"#ffffff\", \"(AAA161) first rule has proper halo color\");\n\n\n        // check the first user style\n        style = layer.userStyles[0];\n        t.ok(style instanceof OpenLayers.Style, \"(AAA161,0) user style is instance of OpenLayers.Style\");\n        t.eq(style.rules.length, 2, \"(AAA161,0) user style has 2 rules\");\n\n        // check the second rule\n        rule = style.rules[1];\n        var feature = {\n            layer: {\n                map: {\n                    getScale: function(){\n                        return 40000;\n                    }\n                }\n            },\n            attributes: {\n                CTE: \"900\"\n            }\n        };\n        t.ok(typeof rule.maxScaleDenominator == \"number\", \"MaxScaleDenominator is a number\");\n        t.eq(rule.evaluate(feature), true, \"numeric filter comparison evaluates correctly\");\n\n        // check for PropertyName size\n        layer = obj.namedLayers[\"Second Layer\"];\n        style = layer.userStyles[0];\n        rule = style.rules[0];\n        t.eq(rule.symbolizer[\"Point\"].graphicWidth, \"${SIZE}\", \"dynamic size correctly set on graphicWidth\");\n\n        // etc.  I'm convinced read works, really wanted to test write (since examples don't test that)\n        // I'll add more tests here later.\n\n    }\n\n    function test_write(t) {\n        t.plan(3);\n\n        // read first - testing that write produces the SLD above\n        var parser = new OpenLayers.Format.SLD.v1_0_0();\n        var xml = new OpenLayers.Format.XML();\n        var sldxml = xml.read(sld);\n        var obj = parser.read(sldxml);\n\n        var node = parser.write(obj);\n        t.xml_eq(node, sld, \"SLD correctly written\");\n\n        obj = parser.read(sldxml, {namedLayersAsArray: true});\n        node = parser.write(obj);\n        t.xml_eq(node, sld, \"SLD from namedLayers array correctly written\");\n\n        // test that 0 fill opacity gets written\n        var symbolizer = {\n            fillColor: \"red\",\n            fillOpacity: 0\n        };\n        var root = parser.createElementNSPlus(\"PolygonSymbolizer\");\n        var got = parser.writeNode(\"Fill\", symbolizer, root);\n        var expect =\n            '<Fill xmlns=\"http://www.opengis.net/sld\">' +\n                '<CssParameter name=\"fill\">red</CssParameter>' +\n                '<CssParameter name=\"fill-opacity\">0</CssParameter>' +\n            '</Fill>';\n        t.xml_eq(got, expect, \"zero fill opacity written\");\n    }\n\n    function test_writePointSymbolizer(t) {\n\n        t.plan(4);\n\n        var parser = new OpenLayers.Format.SLD.v1_0_0();\n        var symbolizer, node, exp;\n\n        // test symbolizer with fill color only\n        symbolizer = {\n            \"fillColor\": \"blue\"\n        };\n        node = parser.writeNode(\"sld:PointSymbolizer\", symbolizer);\n        exp =\n            '<PointSymbolizer xmlns=\"http://www.opengis.net/sld\">' +\n                '<Graphic>' +\n                    '<Mark>' +\n                        '<Fill>' +\n                            '<CssParameter name=\"fill\">blue</CssParameter>' +\n                        '</Fill>' +\n                        '<Stroke/>' +\n                    '</Mark>' +\n                '</Graphic>' +\n            '</PointSymbolizer>';\n        t.xml_eq(node, exp, \"fillColor only written\");\n\n        // test symbolizer with stroke color only\n        symbolizer = {\n            \"strokeColor\": \"blue\"\n        };\n        node = parser.writeNode(\"sld:PointSymbolizer\", symbolizer);\n        exp =\n            '<PointSymbolizer xmlns=\"http://www.opengis.net/sld\">' +\n                '<Graphic>' +\n                    '<Mark>' +\n                        '<Fill/>' +\n                        '<Stroke>' +\n                            '<CssParameter name=\"stroke\">blue</CssParameter>' +\n                        '</Stroke>' +\n                    '</Mark>' +\n                '</Graphic>' +\n            '</PointSymbolizer>';\n        t.xml_eq(node, exp, \"strokeColor only written\");\n\n        // test symbolizer with graphic name only\n        symbolizer = {\n            \"graphicName\": \"star\"\n        };\n        node = parser.writeNode(\"sld:PointSymbolizer\", symbolizer);\n        exp =\n            '<PointSymbolizer xmlns=\"http://www.opengis.net/sld\">' +\n                '<Graphic>' +\n                    '<Mark>' +\n                        '<WellKnownName>star</WellKnownName>' +\n                        '<Fill/>' +\n                        '<Stroke/>' +\n                    '</Mark>' +\n                '</Graphic>' +\n            '</PointSymbolizer>';\n        t.xml_eq(node, exp, \"graphicName only written\");\n\n        // test symbolizer with geometry and some graphic\n        symbolizer = {\n            geometry: {\n                property: \"SOME_GEOM\"\n            },\n            \"graphicName\": \"star\"\n        };\n        node = parser.writeNode(\"sld:PointSymbolizer\", symbolizer);\n        exp =\n            '<PointSymbolizer xmlns=\"http://www.opengis.net/sld\">' +\n                '<Geometry>' +\n                    '<ogc:PropertyName xmlns:ogc=\"http://www.opengis.net/ogc\">SOME_GEOM</ogc:PropertyName>' +\n                '</Geometry>' +\n                 '<Graphic>' +\n                    '<Mark>' +\n                        '<WellKnownName>star</WellKnownName>' +\n                        '<Fill/>' +\n                        '<Stroke/>' +\n                    '</Mark>' +\n                '</Graphic>' +\n            '</PointSymbolizer>';\n        t.xml_eq(node, exp, \"geometry (with some graphic) written\");\n    }\n\n\n    function test_writeLineSymbolizer(t) {\n\n        t.plan(2);\n\n        var parser = new OpenLayers.Format.SLD.v1_0_0();\n        var symbolizer, node, exp;\n\n        // test symbolizer with fill color only\n        symbolizer = {\n            strokeDashstyle: \"4 4\",\n            strokeLinecap: \"round\",\n            strokeColor: \"#0000ff\",\n            strokeWidth: 2\n        };\n        node = parser.writeNode(\"sld:LineSymbolizer\", symbolizer);\n        exp =\n            '<LineSymbolizer xmlns=\"http://www.opengis.net/sld\">' +\n                '<Stroke>' +\n                    '<CssParameter name=\"stroke\">#0000ff</CssParameter>' +\n                    '<CssParameter name=\"stroke-width\">2</CssParameter>' +\n                    '<CssParameter name=\"stroke-dasharray\">4 4</CssParameter>' +\n                    '<CssParameter name=\"stroke-linecap\">round</CssParameter>' +\n                '</Stroke>' +\n            '</LineSymbolizer>';\n        t.xml_eq(node, exp, \"line symbolizer correctly written\");\n\n        // test symbolizer with geometry and some stroke\n        symbolizer = {\n            geometry: {\n                property: \"SOME_GEOM\"\n            },\n            strokeDashstyle: \"4 4\",\n            strokeLinecap: \"round\",\n            strokeColor: \"#0000ff\",\n            strokeWidth: 2\n        };\n        node = parser.writeNode(\"sld:LineSymbolizer\", symbolizer);\n        exp =\n            '<LineSymbolizer xmlns=\"http://www.opengis.net/sld\">' +\n                '<Geometry>' +\n                    '<ogc:PropertyName xmlns:ogc=\"http://www.opengis.net/ogc\">SOME_GEOM</ogc:PropertyName>' +\n                '</Geometry>' +\n                '<Stroke>' +\n                    '<CssParameter name=\"stroke\">#0000ff</CssParameter>' +\n                    '<CssParameter name=\"stroke-width\">2</CssParameter>' +\n                    '<CssParameter name=\"stroke-dasharray\">4 4</CssParameter>' +\n                    '<CssParameter name=\"stroke-linecap\">round</CssParameter>' +\n                '</Stroke>' +\n            '</LineSymbolizer>';\n        t.xml_eq(node, exp, \"line symbolizer with geometry (and some stroke) written\");\n\n    }\n\n    function test_writePolygonSymbolizer(t) {\n\n        t.plan(1);\n        var parser = new OpenLayers.Format.SLD.v1_0_0();\n        // test symbolizer with geometry and some stroke\n        var symbolizer = {\n            Polygon: {\n                geometry: {\n                    property: \"SOME_GEOM\"\n                }\n            }\n        };\n        var node = parser.writers[\"sld\"][\"PolygonSymbolizer\"].apply(\n            parser, [symbolizer[\"Polygon\"]]\n        );\n\n        var exp =\n            '<PolygonSymbolizer xmlns=\"http://www.opengis.net/sld\">' +\n                 '<Geometry>' +\n                     '<ogc:PropertyName xmlns:ogc=\"http://www.opengis.net/ogc\">SOME_GEOM</ogc:PropertyName>' +\n                 '</Geometry>' +\n                 '<Fill />' +\n                 '<Stroke />' +\n             '</PolygonSymbolizer>';\n        t.xml_eq(node, exp, \"polygon symbolizer with geometry written\");\n    }\n\n    function test_writeTextSymbolizer(t) {\n        t.plan(2);\n        var parser = new OpenLayers.Format.SLD.v1_0_0();\n        var symbolizer = {\n            \"Text\": {\n                \"label\": \"This is the ${city} in ${state}.\",\n                \"fontFamily\": \"Arial\",\n                \"fontSize\": 10,\n                \"fontColor\": \"blue\",\n                \"fontWeight\": \"bold\",\n                \"fontStyle\": \"normal\",\n                \"haloRadius\": 2,\n                \"haloColor\": \"white\"\n            }\n        };\n        var node = parser.writers[\"sld\"][\"TextSymbolizer\"].apply(\n            parser, [symbolizer[\"Text\"]]\n        );\n\n        var expected =\n            '<TextSymbolizer xmlns=\"http://www.opengis.net/sld\">' +\n                '<Label>' +\n                    'This is the ' +\n                    '<ogc:PropertyName xmlns:ogc=\"http://www.opengis.net/ogc\">city</ogc:PropertyName>' +\n                    ' in ' +\n                    '<ogc:PropertyName xmlns:ogc=\"http://www.opengis.net/ogc\">state</ogc:PropertyName>' +\n                    '.' +\n                '</Label>' +\n                '<Font>' +\n                    '<CssParameter name=\"font-family\">Arial</CssParameter>' +\n                    '<CssParameter name=\"font-size\">10</CssParameter>' +\n                    '<CssParameter name=\"font-weight\">bold</CssParameter>' +\n                    '<CssParameter name=\"font-style\">normal</CssParameter>' +\n                '</Font>' +\n                '<Halo>' +\n                    '<Radius>2</Radius>' +\n                    '<Fill>' +\n                        '<CssParameter name=\"fill\">white</CssParameter>' +\n                    '</Fill>' +\n                '</Halo>' +\n                '<Fill>' +\n                    '<CssParameter name=\"fill\">blue</CssParameter>' +\n                '</Fill>' +\n            '</TextSymbolizer>';\n\n        t.xml_eq(node, expected, \"Basic TextSymbolizer correctly written\");\n\n        // with geometry\n        symbolizer = {\n            \"Text\": {\n                geometry: {\n                    property: \"SOME_GEOM\"\n                },\n                \"label\": \"This is the ${city} in ${state}.\",\n                \"fontFamily\": \"Arial\",\n                \"fontSize\": 10,\n                \"fontColor\": \"blue\",\n                \"fontWeight\": \"bold\",\n                \"fontStyle\": \"normal\",\n                \"haloRadius\": 2,\n                \"haloColor\": \"white\"\n            }\n        };\n        node = parser.writers[\"sld\"][\"TextSymbolizer\"].apply(\n            parser, [symbolizer[\"Text\"]]\n        );\n\n        expected =\n            '<TextSymbolizer xmlns=\"http://www.opengis.net/sld\">' +\n                '<Geometry>' +\n                    '<ogc:PropertyName xmlns:ogc=\"http://www.opengis.net/ogc\">SOME_GEOM</ogc:PropertyName>' +\n                '</Geometry>' +\n                '<Label>' +\n                    'This is the ' +\n                    '<ogc:PropertyName xmlns:ogc=\"http://www.opengis.net/ogc\">city</ogc:PropertyName>' +\n                    ' in ' +\n                    '<ogc:PropertyName xmlns:ogc=\"http://www.opengis.net/ogc\">state</ogc:PropertyName>' +\n                    '.' +\n                '</Label>' +\n                '<Font>' +\n                    '<CssParameter name=\"font-family\">Arial</CssParameter>' +\n                    '<CssParameter name=\"font-size\">10</CssParameter>' +\n                    '<CssParameter name=\"font-weight\">bold</CssParameter>' +\n                    '<CssParameter name=\"font-style\">normal</CssParameter>' +\n                '</Font>' +\n                '<Halo>' +\n                    '<Radius>2</Radius>' +\n                    '<Fill>' +\n                        '<CssParameter name=\"fill\">white</CssParameter>' +\n                    '</Fill>' +\n                '</Halo>' +\n                '<Fill>' +\n                    '<CssParameter name=\"fill\">blue</CssParameter>' +\n                '</Fill>' +\n            '</TextSymbolizer>';\n\n        t.xml_eq(node, expected, \"TextSymbolizer with geometry correctly written\");\n\n    }\n\n    function test_writeSpatialFilter(t) {\n\n        t.plan(1);\n\n        var format = new OpenLayers.Format.SLD.v1_0_0();\n\n        var rule = new OpenLayers.Rule({\n            name: \"test\",\n            filter: new OpenLayers.Filter.Spatial({\n                type: OpenLayers.Filter.Spatial.BBOX,\n                value: new OpenLayers.Bounds(0, 0, 10, 10)\n            })\n        });\n\n        var sld = format.writeNode(\"sld:Rule\", rule);\n\n        var expect =\n            '<Rule xmlns=\"http://www.opengis.net/sld\">' +\n                '<Name>test</Name>' +\n                '<ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                    '<ogc:BBOX>' +\n                        '<gml:Box xmlns:gml=\"http://www.opengis.net/gml\">' +\n                            '<gml:coordinates decimal=\".\" cs=\",\" ts=\" \">0,0 10,10</gml:coordinates>' +\n                        '</gml:Box>' +\n                    '</ogc:BBOX>' +\n                '</ogc:Filter>' +\n            '</Rule>';\n\n        t.xml_eq(sld, expect, \"rule with spatial filter correctly written\");\n\n    }\n\n    function test_RasterSymbolizer(t) {\n        t.plan(4);\n\n        var format = new OpenLayers.Format.SLD.v1_0_0();\n\n        var snippet =\n            '<sld:RasterSymbolizer xmlns:sld=\"http://www.opengis.net/sld\" xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                '<sld:Geometry>' +\n                    '<ogc:PropertyName>geom</ogc:PropertyName>' +\n                '</sld:Geometry>' +\n                '<sld:Opacity>1</sld:Opacity>' +\n                '<sld:ColorMap>' +\n                    '<sld:ColorMapEntry color=\"#000000\" opacity=\"0.5\" quantity=\"0\" label=\"nodata\"/>' +\n                    '<sld:ColorMapEntry color=\"#00FFFF\" quantity=\"1\" label=\"values\"/>' +\n                    '<sld:ColorMapEntry color=\"#FF0000\" quantity=\"1000\" label=\"values\"/>' +\n                '</sld:ColorMap>' +\n            '</sld:RasterSymbolizer>';\n        var expected = new OpenLayers.Format.XML().read(snippet).documentElement;\n\n        var symbolizer = {};\n        format.readNode(expected, {symbolizer: symbolizer});\n\n        t.eq(symbolizer.Raster.colorMap[0].quantity, 0, \"quantity set correctly\");\n        t.eq(symbolizer.Raster.colorMap[0].opacity, 0.5, \"opacity set correctly\");\n        t.eq(symbolizer.Raster.colorMap[1].opacity, undefined, \"non-existent opacity results in undefined\");\n\n        var got = format.writeNode(\"sld:RasterSymbolizer\", symbolizer[\"Raster\"]);\n\n        t.xml_eq(got, expected, \"Successfully round tripped RasterSymbolizer\");\n    }\n\n    function test_zIndex(t) {\n        t.plan(1);\n\n        var format = new OpenLayers.Format.SLD.v1_0_0({\n            multipleSymbolizers: true\n        });\n\n        // three zIndex values -> three FeatureTypeStyle elements\n        var style = new OpenLayers.Style2({\n            rules: [\n                new OpenLayers.Rule({\n                    filter: new OpenLayers.Filter.Comparison({\n                        type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                        property: \"foo\",\n                        value: \"bar\"\n                    }),\n                    minScaleDenominator: 100000,\n                    maxScaleDenominator: 200000,\n                    symbolizers: [\n                        new OpenLayers.Symbolizer.Line({\n                            strokeColor: \"green\",\n                            strokeWidth: 2,\n                            zIndex: 2\n                        }),\n                        new OpenLayers.Symbolizer.Line({\n                            strokeColor: \"red\",\n                            strokeWidth: 3,\n                            zIndex: -1\n                        }),\n                        new OpenLayers.Symbolizer.Line({\n                            strokeColor: \"blue\",\n                            strokeWidth: 1,\n                            zIndex: 5\n                        })\n                    ]\n                }),\n                new OpenLayers.Rule({\n                    filter: new OpenLayers.Filter.Comparison({\n                        type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                        property: \"foo\",\n                        value: \"baz\"\n                    }),\n                    symbolizers: [\n                        new OpenLayers.Symbolizer.Line({\n                            strokeColor: \"#000000\",\n                            strokeWidth: 2,\n                            zIndex: 2\n                        })\n                    ]\n                })\n            ]\n        });\n\n        var got = format.writeNode(\"sld:UserStyle\", style);\n        var exp = readXML(\"zindex_test.sld\").documentElement;\n        t.xml_eq(got, exp, \"duplicated rules to write zIndex as FeatureTypeStyle elements\");\n\n    }\n\n    function test_whitespace(t) {\n        t.plan(1);\n        var xml = readXML(\"propertyisbetweenwhitespace.sld\");\n        var output = new OpenLayers.Format.SLD().read(xml);\n        var filter = output.namedLayers['geonode:US_Stat0'].userStyles[0].rules[0].filter;\n        t.eq(filter.lowerBoundary, 29.7, \"whitespace ignored in values and value transformed to number\");\n    }\n\n    function test_label_LinePlacement(t) {\n        t.plan(1);\n        var format = new OpenLayers.Format.SLD.v1_0_0({\n            multipleSymbolizers: true\n        });\n        // labelPerpendicularOffset takes precedence over labelAlign\n        var style = new OpenLayers.Style2({\n            rules: [\n                new OpenLayers.Rule({\n                    symbolizers: [\n                        new OpenLayers.Symbolizer.Line({\n                            strokeColor: \"red\",\n                            strokeWidth: 3\n                        }),\n                        new OpenLayers.Symbolizer.Text({\n                            label: \"${FOO}\",\n                            labelPerpendicularOffset: 10,\n                            labelAlign: \"rb\"\n                        })\n                    ]\n                })\n            ]\n        });\n        var got = format.writeNode(\"sld:UserStyle\", style);\n        var exp = readXML(\"label_lineplacement_test.sld\").documentElement;\n        t.xml_eq(got, exp, \"LinePlacement written out correctly\");\n    }\n\n    function test_labelAlignToAnchorPosition(t) {\n        t.plan(1);\n        var format = new OpenLayers.Format.SLD.v1_0_0({\n            multipleSymbolizers: true\n        });\n        var style = new OpenLayers.Style2({\n            rules: [\n                new OpenLayers.Rule({\n                    symbolizers: [\n                        new OpenLayers.Symbolizer.Text({\n                            label: \"${FOO}\",\n                            labelAlign: \"rb\"\n                        })\n                    ]\n                })\n            ]\n        });\n        var got = format.writeNode(\"sld:UserStyle\", style);\n        var exp = readXML(\"label_pointplacement_test.sld\").documentElement;\n        t.xml_eq(got, exp, \"PointPlacement with labelAlign written out correctly\");\n    }\n\n    function test_read_FeatureTypeStyles(t) {\n\n        t.plan(13);\n\n        var format = new OpenLayers.Format.SLD.v1_0_0({\n            multipleSymbolizers: true,\n            namedLayersAsArray: true\n        });\n        var doc = readXML(\"line_linewithborder.sld\");\n\n        var obj = format.read(doc);\n\n        t.eq(obj.namedLayers.length, 1, \"got one named layer\");\n        var namedLayer = obj.namedLayers[0];\n\n        t.eq(namedLayer.userStyles.length, 1, \"got one user style\");\n        var userStyle = namedLayer.userStyles[0];\n        t.ok(userStyle instanceof OpenLayers.Style2, \"user style represented with OpenLayers.Style2\");\n\n        // check rules and symbolizers\n        var rule, symbolizer;\n\n        t.eq(userStyle.rules.length, 2, \"pulled two rules (from two FeatureTypeStyle elements)\");\n        rule = userStyle.rules[0];\n        t.ok(rule instanceof OpenLayers.Rule, \"first rule is an OpenLayers.Rule\");\n\n        t.eq(rule.symbolizers && rule.symbolizers.length, 1, \"first rule has one symbolizer\");\n        symbolizer = rule.symbolizers[0];\n        t.ok(symbolizer instanceof OpenLayers.Symbolizer, \"first symbolizer in first rule is an OpenLayers.Symbolizer\");\n        t.ok(symbolizer instanceof OpenLayers.Symbolizer.Line, \"first symbolizer in first rule is an OpenLayers.Symbolizer.Line\");\n        t.eq(symbolizer.zIndex, 0, \"symbolizer from first FeatureTypeStyle element has zIndex 0\");\n\n        rule = userStyle.rules[1];\n        t.eq(rule.symbolizers && rule.symbolizers.length, 1, \"second rule has one symbolizer\");\n        symbolizer = rule.symbolizers[0];\n        t.ok(symbolizer instanceof OpenLayers.Symbolizer, \"first symbolizer in second rule is an OpenLayers.Symbolizer\");\n        t.ok(symbolizer instanceof OpenLayers.Symbolizer.Line, \"first symbolizer in second rule is an OpenLayers.Symbolizer.Line\");\n        t.eq(symbolizer.zIndex, 1, \"symbolizer from second FeatureTypeStyle element has zIndex 1\");\n\n    }\n\n    function test_labelWhiteSpace(t) {\n        t.plan(1);\n        var doc = readXML(\"point_pointwithdefaultlabel.sld\");\n        var format = new OpenLayers.Format.SLD();\n        var obj = format.read(doc);\n        t.eq(obj.namedLayers[\"Point with default label\"].userStyles[0].rules[0].symbolizer[\"Text\"].label,\n            \"${name}\", \"Whitespace in front or after column name ignored\");\n    }\n\n    function test_roundtrip(t) {\n\n        t.plan(5);\n\n        var format = new OpenLayers.Format.SLD.v1_0_0({\n            multipleSymbolizers: true,\n            namedLayersAsArray: true\n        });\n        var doc, out;\n\n        // two FeatureTypeStyle elements and line symbolizers\n        doc = readXML(\"line_linewithborder.sld\");\n        out = format.write(format.read(doc));\n        t.xml_eq(out, doc.documentElement, \"round-tripped line_linewithborder.sld\");\n\n        // three FeatureTypeStyle elements and line symbolizers\n        doc = readXML(\"line_attributebasedline.sld\");\n        out = format.write(format.read(doc));\n        t.xml_eq(out, doc.documentElement, \"round-tripped line_attributebasedline.sld\");\n\n        // point symbolizer and text symbolizer\n        doc = readXML(\"point_pointwithdefaultlabel.sld\");\n        out = format.write(format.read(doc));\n        t.xml_eq(out, doc.documentElement, \"round-tripped point_pointwithdefaultlabel.sld\");\n\n        // polygon symbolizer with fill only\n        doc = readXML(\"polygon_simplepolygon.sld\");\n        out = format.write(format.read(doc));\n        t.xml_eq(out, doc.documentElement, \"round-tripped polygon_simplepolygon.sld\");\n\n        // polygon symbolizer and text symbolizer with halo\n        doc = readXML(\"polygon_labelhalo.sld\");\n        out = format.write(format.read(doc));\n        t.xml_eq(out, doc.documentElement, \"round-tripped polygon_labelhalo.sld\");\n    }\n\n    </script> \n</head> \n<body>\n<div id=\"line_linewithborder.sld\"><!--\n<StyledLayerDescriptor version=\"1.0.0\" \n    xsi:schemaLocation=\"http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd\" \n    xmlns=\"http://www.opengis.net/sld\" \n    xmlns:ogc=\"http://www.opengis.net/ogc\" \n    xmlns:xlink=\"http://www.w3.org/1999/xlink\" \n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <NamedLayer>\n    <Name>Line with border</Name>\n    <UserStyle>\n    <Title>SLD Cook Book: Line w2th border</Title>\n      <FeatureTypeStyle>\n         <Rule>\n          <LineSymbolizer>\n            <Stroke>\n              <CssParameter name=\"stroke\">#333333</CssParameter>                           \n              <CssParameter name=\"stroke-width\">5</CssParameter>    \n              <CssParameter name=\"stroke-linecap\">round</CssParameter>    \n            </Stroke> \n          </LineSymbolizer>\n        </Rule>\n      </FeatureTypeStyle>\n      <FeatureTypeStyle>\n         <Rule>\n          <LineSymbolizer>\n          <Stroke>\n              <CssParameter name=\"stroke\">#6699FF</CssParameter>                           \n              <CssParameter name=\"stroke-width\">3</CssParameter> \n              <CssParameter name=\"stroke-linecap\">round</CssParameter>  \n            </Stroke>\n          </LineSymbolizer>                                          \n         </Rule>\n      </FeatureTypeStyle>\n    </UserStyle>\n  </NamedLayer>\n</StyledLayerDescriptor>\n--></div>\n<div id=\"line_attributebasedline.sld\"><!--\n<StyledLayerDescriptor version=\"1.0.0\" \n    xsi:schemaLocation=\"http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd\" \n    xmlns=\"http://www.opengis.net/sld\" \n    xmlns:ogc=\"http://www.opengis.net/ogc\" \n    xmlns:xlink=\"http://www.w3.org/1999/xlink\" \n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <NamedLayer>\n    <Name>Attribute-based line</Name>\n    <UserStyle>\n      <Title>SLD Cook Book: Attribute-based line</Title>\n      <FeatureTypeStyle>\n        <Rule>\n          <Name>local-road</Name>\n          <ogc:Filter>\n            <ogc:PropertyIsEqualTo>\n              <ogc:PropertyName>type</ogc:PropertyName>\n              <ogc:Literal>local-road</ogc:Literal>\n            </ogc:PropertyIsEqualTo>\n          </ogc:Filter>\n          <LineSymbolizer>\n            <Stroke>\n              <CssParameter name=\"stroke\">#009933</CssParameter>\n              <CssParameter name=\"stroke-width\">2</CssParameter>\n            </Stroke>\n          </LineSymbolizer>\n        </Rule>\n      </FeatureTypeStyle>\n      <FeatureTypeStyle>\n        <Rule>\n          <Name>secondary</Name>\n          <ogc:Filter>\n            <ogc:PropertyIsEqualTo>\n              <ogc:PropertyName>type</ogc:PropertyName>\n              <ogc:Literal>secondary</ogc:Literal>\n            </ogc:PropertyIsEqualTo>\n          </ogc:Filter>\n          <LineSymbolizer>\n            <Stroke>\n              <CssParameter name=\"stroke\">#0055CC</CssParameter>\n              <CssParameter name=\"stroke-width\">3</CssParameter>\n            </Stroke>\n          </LineSymbolizer>\n        </Rule>\n      </FeatureTypeStyle>\n      <FeatureTypeStyle>\n        <Rule>\n        <Name>highway</Name>\n          <ogc:Filter>\n            <ogc:PropertyIsEqualTo>\n              <ogc:PropertyName>type</ogc:PropertyName>\n              <ogc:Literal>highway</ogc:Literal>\n            </ogc:PropertyIsEqualTo>\n          </ogc:Filter>\n          <LineSymbolizer>\n            <Stroke>\n              <CssParameter name=\"stroke\">#FF0000</CssParameter>\n              <CssParameter name=\"stroke-width\">6</CssParameter>\n            </Stroke>\n          </LineSymbolizer>\n        </Rule>\n      </FeatureTypeStyle>\n    </UserStyle>\n  </NamedLayer>\n</StyledLayerDescriptor> \n--></div>\n<div id=\"point_pointwithdefaultlabel.sld\"><!--\n<StyledLayerDescriptor version=\"1.0.0\" \n    xsi:schemaLocation=\"http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd\" \n    xmlns=\"http://www.opengis.net/sld\" \n    xmlns:ogc=\"http://www.opengis.net/ogc\" \n    xmlns:xlink=\"http://www.w3.org/1999/xlink\" \n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <NamedLayer>\n    <Name>Point with default label</Name>\n    <UserStyle>\n      <Title>GeoServer SLD Cook Book: Point with default label</Title>\n      <FeatureTypeStyle>\n        <Rule>\n          <PointSymbolizer>\n            <Graphic>\n              <Mark>\n                <WellKnownName>circle</WellKnownName>\n                <Fill>\n                  <CssParameter name=\"fill\">#FF0000</CssParameter>\n                </Fill>\n              </Mark>\n              <Size>6</Size>\n            </Graphic>\n          </PointSymbolizer>\n          <TextSymbolizer>\n            <Label>\n              <ogc:PropertyName>name</ogc:PropertyName>\n            </Label>\n            <Fill>\n              <CssParameter name=\"fill\">#000000</CssParameter>\n            </Fill>\n          </TextSymbolizer>\n        </Rule>\n      </FeatureTypeStyle>\n    </UserStyle>\n  </NamedLayer>\n</StyledLayerDescriptor>\n--></div>\n<div id=\"polygon_simplepolygon.sld\"><!--\n<StyledLayerDescriptor version=\"1.0.0\" \n    xsi:schemaLocation=\"http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd\" \n    xmlns=\"http://www.opengis.net/sld\" \n    xmlns:ogc=\"http://www.opengis.net/ogc\" \n    xmlns:xlink=\"http://www.w3.org/1999/xlink\" \n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <NamedLayer>\n    <Name>Simple polygon</Name>\n    <UserStyle>\n      <Title>SLD Cook Book: Simple polygon</Title>\n      <FeatureTypeStyle>\n        <Rule>\n          <PolygonSymbolizer>\n            <Fill>\n              <CssParameter name=\"fill\">#000080</CssParameter>\n            </Fill>\n          </PolygonSymbolizer>\n        </Rule>\n      </FeatureTypeStyle>\n    </UserStyle>\n  </NamedLayer>\n</StyledLayerDescriptor>\n--></div>\n<div id=\"polygon_labelhalo.sld\"><!--\n<StyledLayerDescriptor version=\"1.0.0\" \n    xsi:schemaLocation=\"http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd\" \n    xmlns=\"http://www.opengis.net/sld\" \n    xmlns:ogc=\"http://www.opengis.net/ogc\" \n    xmlns:xlink=\"http://www.w3.org/1999/xlink\" \n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <NamedLayer>\n    <Name>Label halo</Name>\n    <UserStyle>\n      <Title>SLD Cook Book: Label halo</Title>\n      <FeatureTypeStyle>\n        <Rule>\n          <PolygonSymbolizer>\n            <Fill>\n              <CssParameter name=\"fill\">#40FF40</CssParameter>\n            </Fill>\n            <Stroke>\n              <CssParameter name=\"stroke\">#FFFFFF</CssParameter>\n              <CssParameter name=\"stroke-width\">2</CssParameter>\n            </Stroke>\n          </PolygonSymbolizer>        \n          <TextSymbolizer>\n            <Label>\n              <ogc:PropertyName>name</ogc:PropertyName>\n            </Label>\n            <Halo>\n              <Radius>3</Radius>\n              <Fill>\n                <CssParameter name=\"fill\">#FFFFFF</CssParameter>\n              </Fill>\n            </Halo>\n          </TextSymbolizer>\n        </Rule>\n      </FeatureTypeStyle>\n    </UserStyle>\n  </NamedLayer>\n</StyledLayerDescriptor>\n--></div>\n<div id=\"zindex_test.sld\"><!--\n<sld:UserStyle xmlns:sld=\"http://www.opengis.net/sld\">\n    <sld:FeatureTypeStyle>\n        <sld:Rule>\n            <ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n                <ogc:PropertyIsEqualTo>\n                    <ogc:PropertyName>foo</ogc:PropertyName>\n                    <ogc:Literal>bar</ogc:Literal>\n                </ogc:PropertyIsEqualTo>\n            </ogc:Filter>\n            <sld:MinScaleDenominator>100000</sld:MinScaleDenominator>\n            <sld:MaxScaleDenominator>200000</sld:MaxScaleDenominator>\n            <sld:LineSymbolizer>\n                <sld:Stroke>\n                    <sld:CssParameter name=\"stroke\">red</sld:CssParameter>\n                    <sld:CssParameter name=\"stroke-width\">3</sld:CssParameter>\n                </sld:Stroke>\n            </sld:LineSymbolizer>\n        </sld:Rule>\n    </sld:FeatureTypeStyle>\n    <sld:FeatureTypeStyle>\n        <sld:Rule>\n            <ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n                <ogc:PropertyIsEqualTo>\n                    <ogc:PropertyName>foo</ogc:PropertyName>\n                    <ogc:Literal>bar</ogc:Literal>\n                </ogc:PropertyIsEqualTo>\n            </ogc:Filter>\n            <sld:MinScaleDenominator>100000</sld:MinScaleDenominator>\n            <sld:MaxScaleDenominator>200000</sld:MaxScaleDenominator>\n            <sld:LineSymbolizer>\n                <sld:Stroke>\n                    <sld:CssParameter name=\"stroke\">green</sld:CssParameter>\n                    <sld:CssParameter name=\"stroke-width\">2</sld:CssParameter>\n                </sld:Stroke>\n            </sld:LineSymbolizer>\n        </sld:Rule>\n        <sld:Rule>\n            <ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n                <ogc:PropertyIsEqualTo>\n                    <ogc:PropertyName>foo</ogc:PropertyName>\n                    <ogc:Literal>baz</ogc:Literal>\n                </ogc:PropertyIsEqualTo>\n            </ogc:Filter>\n            <sld:LineSymbolizer>\n                <sld:Stroke>\n                    <sld:CssParameter name=\"stroke\">#000000</sld:CssParameter>\n                    <sld:CssParameter name=\"stroke-width\">2</sld:CssParameter>\n                </sld:Stroke>\n            </sld:LineSymbolizer>\n        </sld:Rule>\n    </sld:FeatureTypeStyle>\n    <sld:FeatureTypeStyle>\n        <sld:Rule>\n            <ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n                <ogc:PropertyIsEqualTo>\n                    <ogc:PropertyName>foo</ogc:PropertyName>\n                    <ogc:Literal>bar</ogc:Literal>\n                </ogc:PropertyIsEqualTo>\n            </ogc:Filter>\n            <sld:MinScaleDenominator>100000</sld:MinScaleDenominator>\n            <sld:MaxScaleDenominator>200000</sld:MaxScaleDenominator>\n            <sld:LineSymbolizer>\n                <sld:Stroke>\n                    <sld:CssParameter name=\"stroke\">blue</sld:CssParameter>\n                    <sld:CssParameter name=\"stroke-width\">1</sld:CssParameter>\n                </sld:Stroke>\n            </sld:LineSymbolizer>\n        </sld:Rule>\n    </sld:FeatureTypeStyle>\n</sld:UserStyle>\n--></div>\n<div id=\"label_lineplacement_test.sld\"><!--\n<sld:UserStyle xmlns:sld=\"http://www.opengis.net/sld\">\n    <sld:FeatureTypeStyle>\n        <sld:Rule>\n            <sld:LineSymbolizer>\n                <sld:Stroke>\n                    <sld:CssParameter name=\"stroke\">red</sld:CssParameter>\n                    <sld:CssParameter name=\"stroke-width\">3</sld:CssParameter>\n                </sld:Stroke>\n            </sld:LineSymbolizer>\n            <sld:TextSymbolizer>\n                <sld:Label><ogc:PropertyName xmlns:ogc=\"http://www.opengis.net/ogc\">FOO</ogc:PropertyName></sld:Label>\n                <sld:LabelPlacement>\n                    <sld:LinePlacement>\n                        <sld:PerpendicularOffset>10</sld:PerpendicularOffset>\n                    </sld:LinePlacement>\n                </sld:LabelPlacement>\n            </sld:TextSymbolizer>\n        </sld:Rule>\n    </sld:FeatureTypeStyle>\n</sld:UserStyle>\n--></div>\n<div id=\"label_pointplacement_test.sld\"><!--\n<sld:UserStyle xmlns:sld=\"http://www.opengis.net/sld\">\n    <sld:FeatureTypeStyle>\n        <sld:Rule>\n            <sld:TextSymbolizer>\n                <sld:Label><ogc:PropertyName xmlns:ogc=\"http://www.opengis.net/ogc\">FOO</ogc:PropertyName></sld:Label>\n                <sld:LabelPlacement>\n                    <sld:PointPlacement>\n                        <sld:AnchorPoint>\n                            <sld:AnchorPointX>1</sld:AnchorPointX>\n                            <sld:AnchorPointY>0</sld:AnchorPointY>\n                        </sld:AnchorPoint>\n                    </sld:PointPlacement>\n                </sld:LabelPlacement>\n            </sld:TextSymbolizer>\n        </sld:Rule>\n    </sld:FeatureTypeStyle>\n</sld:UserStyle>\n--></div>\n<div id=\"propertyisbetweenwhitespace.sld\"><!--\n<sld:StyledLayerDescriptor xmlns=\"http://www.opengis.net/sld\" xmlns:sld=\"http://www.opengis.net/sld\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:gml=\"http://www.opengis.net/gml\" version=\"1.0.0\">\n    <sld:NamedLayer>\n        <sld:Name>geonode:US_Stat0</sld:Name>\n        <sld:UserStyle>\n            <sld:Name>US_Stat0_5cbbe918</sld:Name>\n            <sld:Title>BMI&lt;25</sld:Title>\n            <sld:FeatureTypeStyle>\n                <sld:Name>name</sld:Name>\n                <sld:Rule>\n                    <sld:Title>BMI&lt;25</sld:Title>\n                    <ogc:Filter>\n                        <ogc:PropertyIsBetween>\n                            <ogc:PropertyName>Hlt_st_BMI</ogc:PropertyName>\n                            <ogc:LowerBoundary>\n                                <ogc:Literal>\n\n\n                                \t29.7\n\n\n                            </ogc:Literal>\n                            </ogc:LowerBoundary>\n                            <ogc:UpperBoundary>\n                                <ogc:Literal>\n\n\n                                 36.2\n\n\n                            </ogc:Literal>\n                            </ogc:UpperBoundary>\n                        </ogc:PropertyIsBetween>\n                    </ogc:Filter>\n                    <sld:PolygonSymbolizer>\n                        <sld:Fill>\n                            <sld:CssParameter name=\"fill\">#C0F58C</sld:CssParameter>\n                        </sld:Fill>\n                        <sld:Stroke/>\n                    </sld:PolygonSymbolizer>\n                </sld:Rule>\n            </sld:FeatureTypeStyle>\n        </sld:UserStyle>\n    </sld:NamedLayer>\n</sld:StyledLayerDescriptor>\n--></div>\n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/SLD/v1_0_0_GeoServer.html",
    "content": "<html> \n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    var xml = new OpenLayers.Format.XML(); \n    function readXML(id) {\n        return xml.read(document.getElementById(id).firstChild.nodeValue);\n    }\n\n    function test_VendorExtensions(t) {\n\n        var cases = [\n            \"poly_label.sld\"\n        ];\n        var len = cases.length;\n        t.plan(len+1);\n\n        var format = new OpenLayers.Format.SLD({\n            profile: \"GeoServer\",\n            multipleSymbolizers: true,\n            namedLayersAsArray: true,\n            schemaLocation: \"http://www.opengis.net/sld StyledLayerDescriptor.xsd\"\n        });\n            \n        var c, doc, data, out;\n        for (var i=0; i<len; ++i) {\n            c = cases[i];\n            doc = readXML(c);\n            data = format.read(doc);\n            out = format.write(data);\n            t.xml_eq(out, doc.documentElement, \"round-tripped \" + c);\n        }\n        doc = readXML(\"poly_label.sld\");\n        data = format.read(doc);\n        data.namedLayers[0].userStyles[0].rules[0].symbolizers[1].graphic = false;\n        out = format.write(data);\n        t.xml_eq(out, readXML(\"poly_label_nographic.sld\").documentElement, \"If graphic is false no Graphic is outputted\");\n    }\n\n    function test_readTextSymbolizer(t) {\n        t.plan(1);\n        var format = new OpenLayers.Format.SLD({\n            profile: \"GeoServer\",\n            multipleSymbolizers: true,\n            namedLayersAsArray: true\n        });\n        doc = readXML(\"point_pointwithdefaultlabel.sld\");\n        var sld = format.read(doc);\n        t.eq(sld.namedLayers[0].userStyles[0].rules[0].symbolizers[1].graphic, false, \"graphic set to false on TextSymbolizer\");\n    }\n    \n    </script> \n</head> \n<body>\n<div id=\"poly_label.sld\"><!--\n<StyledLayerDescriptor version=\"1.0.0\"\n    xsi:schemaLocation=\"http://www.opengis.net/sld StyledLayerDescriptor.xsd\"\n    xmlns=\"http://www.opengis.net/sld\"\n    xmlns:ogc=\"http://www.opengis.net/ogc\"\n    xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <NamedLayer>\n    <Name>Polygon with styled label</Name>\n    <UserStyle>\n      <Title>SLD Cook Book: Polygon with styled label</Title>\n      <FeatureTypeStyle>\n        <Rule>\n          <PolygonSymbolizer>\n            <Fill>\n              <CssParameter name=\"fill\">#40FF40</CssParameter>\n            </Fill>\n            <Stroke>\n              <CssParameter name=\"stroke\">#FFFFFF</CssParameter>\n              <CssParameter name=\"stroke-width\">2</CssParameter>\n            </Stroke>\n          </PolygonSymbolizer>        \n          <TextSymbolizer>\n            <Label>\n              <ogc:PropertyName>name</ogc:PropertyName>\n            </Label>\n            <Font>\n              <CssParameter name=\"font-family\">Arial</CssParameter>\n              <CssParameter name=\"font-size\">11</CssParameter>\n              <CssParameter name=\"font-weight\">bold</CssParameter>\n              <CssParameter name=\"font-style\">normal</CssParameter>\n            </Font>\n            <Fill>\n              <CssParameter name=\"fill\">#000000</CssParameter>\n              <CssParameter name=\"fill-opacity\">0.5</CssParameter>\n            </Fill>\n            <Graphic>\n              <Mark>\n                <WellKnownName>square</WellKnownName>\n                  <Fill>\n                    <CssParameter name=\"fill\">#59BF34</CssParameter>\n                    <CssParameter name=\"fill-opacity\">0.8</CssParameter>\n                  </Fill>\n                  <Stroke>\n                    <CssParameter name=\"stroke\">#2D6917</CssParameter>\n                  </Stroke>\n              </Mark>\n              <Size>24</Size>\n            </Graphic>\n            <Priority>\n                <ogc:PropertyName>population</ogc:PropertyName>\n            </Priority>\n            <VendorOption name=\"autoWrap\">60</VendorOption>\n            <VendorOption name=\"followLine\">true</VendorOption> \n            <VendorOption name=\"repeat\">300</VendorOption>\n            <VendorOption name=\"maxDisplacement\">150</VendorOption>\n            <VendorOption name=\"forceLeftToRight\">false</VendorOption>\n            <VendorOption name=\"graphic-margin\">3</VendorOption>\n            <VendorOption name=\"graphic-resize\">stretch</VendorOption>\n            <VendorOption name=\"group\">yes</VendorOption>\n            <VendorOption name=\"spaceAround\">10</VendorOption>\n            <VendorOption name=\"labelAllGroup\">true</VendorOption>\n            <VendorOption name=\"maxAngleDelta\">15</VendorOption>\n            <VendorOption name=\"conflictResolution\">false</VendorOption>\n            <VendorOption name=\"goodnessOfFit\">0.3</VendorOption>\n            <VendorOption name=\"polygonAlign\">mbr</VendorOption>\n          </TextSymbolizer>\n        </Rule>\n      </FeatureTypeStyle>\n    </UserStyle>\n  </NamedLayer>\n</StyledLayerDescriptor>\n--></div>\n<div id=\"poly_label_nographic.sld\"><!--\n<StyledLayerDescriptor version=\"1.0.0\"\n    xsi:schemaLocation=\"http://www.opengis.net/sld StyledLayerDescriptor.xsd\"\n    xmlns=\"http://www.opengis.net/sld\"\n    xmlns:ogc=\"http://www.opengis.net/ogc\"\n    xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <NamedLayer>\n    <Name>Polygon with styled label</Name>\n    <UserStyle>\n      <Title>SLD Cook Book: Polygon with styled label</Title>\n      <FeatureTypeStyle>\n        <Rule>\n          <PolygonSymbolizer>\n            <Fill>\n              <CssParameter name=\"fill\">#40FF40</CssParameter>\n            </Fill>\n            <Stroke>\n              <CssParameter name=\"stroke\">#FFFFFF</CssParameter>\n              <CssParameter name=\"stroke-width\">2</CssParameter>\n            </Stroke>\n          </PolygonSymbolizer>        \n          <TextSymbolizer>\n            <Label>\n              <ogc:PropertyName>name</ogc:PropertyName>\n            </Label>\n            <Font>\n              <CssParameter name=\"font-family\">Arial</CssParameter>\n              <CssParameter name=\"font-size\">11</CssParameter>\n              <CssParameter name=\"font-weight\">bold</CssParameter>\n              <CssParameter name=\"font-style\">normal</CssParameter>\n            </Font>\n            <Fill>\n              <CssParameter name=\"fill\">#000000</CssParameter>\n              <CssParameter name=\"fill-opacity\">0.5</CssParameter>\n            </Fill>\n            <Priority>\n                <ogc:PropertyName>population</ogc:PropertyName>\n            </Priority>\n            <VendorOption name=\"autoWrap\">60</VendorOption>\n            <VendorOption name=\"followLine\">true</VendorOption> \n            <VendorOption name=\"repeat\">300</VendorOption>\n            <VendorOption name=\"maxDisplacement\">150</VendorOption>\n            <VendorOption name=\"forceLeftToRight\">false</VendorOption>\n            <VendorOption name=\"graphic-margin\">3</VendorOption>\n            <VendorOption name=\"graphic-resize\">stretch</VendorOption>\n            <VendorOption name=\"group\">yes</VendorOption>\n            <VendorOption name=\"spaceAround\">10</VendorOption>\n            <VendorOption name=\"labelAllGroup\">true</VendorOption>\n            <VendorOption name=\"maxAngleDelta\">15</VendorOption>\n            <VendorOption name=\"conflictResolution\">false</VendorOption>\n            <VendorOption name=\"goodnessOfFit\">0.3</VendorOption>\n            <VendorOption name=\"polygonAlign\">mbr</VendorOption>\n          </TextSymbolizer>\n        </Rule>\n      </FeatureTypeStyle>\n    </UserStyle>\n  </NamedLayer>\n</StyledLayerDescriptor>\n--></div>\n<div id=\"point_pointwithdefaultlabel.sld\"><!--\n<StyledLayerDescriptor version=\"1.0.0\" \n    xsi:schemaLocation=\"http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd\" \n    xmlns=\"http://www.opengis.net/sld\" \n    xmlns:ogc=\"http://www.opengis.net/ogc\" \n    xmlns:xlink=\"http://www.w3.org/1999/xlink\" \n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n  <NamedLayer>\n    <Name>Point with default label</Name>\n    <UserStyle>\n      <Title>GeoServer SLD Cook Book: Point with default label</Title>\n      <FeatureTypeStyle>\n        <Rule>\n          <PointSymbolizer>\n            <Graphic>\n              <Mark>\n                <WellKnownName>circle</WellKnownName>\n                <Fill>\n                  <CssParameter name=\"fill\">#FF0000</CssParameter>\n                </Fill>\n              </Mark>\n              <Size>6</Size>\n            </Graphic>\n          </PointSymbolizer>\n          <TextSymbolizer>\n            <Label>\n              <ogc:PropertyName>name</ogc:PropertyName>\n            </Label>\n            <Fill>\n              <CssParameter name=\"fill\">#000000</CssParameter>\n            </Fill>\n          </TextSymbolizer>\n        </Rule>\n      </FeatureTypeStyle>\n    </UserStyle>\n  </NamedLayer>\n</StyledLayerDescriptor>\n--></div>\n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/SLD.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    var test_content = '<sld:StyledLayerDescriptor xmlns:sld=\"http://www.opengis.net/sld\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:gml=\"http://www.opengis.net/gml\"><sld:NamedLayer><sld:Name>TestLayer</sld:Name><sld:UserStyle><sld:Name>foo</sld:Name><sld:FeatureTypeStyle><sld:Rule><sld:Name>bar</sld:Name><ogc:Filter></ogc:Filter><sld:PolygonSymbolizer><sld:Fill><sld:CssParameter name=\"fill\"><ogc:Literal>blue</ogc:Literal></sld:CssParameter></sld:Fill></sld:PolygonSymbolizer></sld:Rule></sld:FeatureTypeStyle></sld:UserStyle></sld:NamedLayer></sld:StyledLayerDescriptor>';\n\n    function test_Format_SLD_constructor(t) { \n        t.plan(3); \n         \n        var options = {'foo': 'bar'}; \n        var format = new OpenLayers.Format.SLD(options); \n        t.ok(format instanceof OpenLayers.Format.SLD, \n             \"new OpenLayers.Format.SLD returns object\" ); \n        t.eq(format.foo, \"bar\", \"constructor sets options correctly\"); \n        t.eq(typeof format.read, \"function\", \"format has a read function\"); \n    }\n\n    function test_Format_SLD_read(t) {\n        t.plan(4);\n        var sld = new OpenLayers.Format.SLD().read(this.test_content);\n        \n        var testLayer = sld.namedLayers[\"TestLayer\"];\n        var userStyles = testLayer.userStyles;\n        \n        t.eq(userStyles[0].name, \"foo\", \"SLD correctly reads a UserStyle named 'foo'\");\n        t.eq(userStyles[0].rules.length, 1, \"The number of rules for the UserStyle is correct\");\n        t.eq(userStyles[0].rules[0].name, \"bar\", \"The first rule's name is 'bar'\");\n        t.eq(userStyles[0].rules[0].symbolizer.Polygon.fillColor, \"blue\", \"The fillColor for the Polygon symbolizer is correct\");\n    }\n\n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/SOSCapabilities/v1_0_0.html",
    "content": "<html>\n<head>\n    <script src=\"../../OLLoader.js\"></script>\n    <script src=\"v1_0_0.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_read(t) {\n\n        t.plan(41);\n\n        var format = new OpenLayers.Format.SOSCapabilities();\n        var obj = format.read(doc);\n\n        t.eq(obj.version, \"1.0.0\", \"Version parsed correctly\");\n\n        // service identification (from OWSCommon)\n        t.eq(obj.serviceIdentification.abstract, \"WeatherSOS (stable) at IfGI, Muenster, Germany. For more info: http://ifgipedia.uni-muenster.de/kms/documentation/swsl/sos/\", \"Abstract parsed correctly\");\n        t.eq(obj.serviceIdentification.accessConstraints, \"NONE\", \"AccessConstraints parsed correctly\");\n        t.eq(obj.serviceIdentification.fees, \"NONE\", \"Fees parsed correctly\");\n        for (var key in obj.serviceIdentification.keywords) {\n            t.eq(key, \"rain gauge, radiation, pressure, windspeed, winddirection, temperature\", \"Keywords parsed correctly\");\n        }\n        t.eq(obj.serviceIdentification.serviceType.codeSpace, \"http://opengeospatial.net\", \"codeSpace correctly parsed\");\n        t.eq(obj.serviceIdentification.serviceType.value, \"OGC:SOS\", \"ServiceType correctly parsed\");\n        t.eq(obj.serviceIdentification.serviceTypeVersion, \"1.0.0\", \"ServiceTypeVersion correctly parsed\");\n        t.eq(obj.serviceIdentification.title, \"IFGI WeatherSOS (stable)\", \"Title correctly parsed\");\n\n        // service provider (from OWSCommon)\n        t.eq(obj.serviceProvider.providerName, \"Institute for Geoinformatics, University of Muenster\", \"ProviderName correctly parsed\");\n        t.eq(obj.serviceProvider.providerSite, \"http://ifgi.uni-muenster.de\", \"ProviderSite correctly parsed\");\n        t.eq(obj.serviceProvider.serviceContact.individualName, \"Eike Hinderk Juerrens\", \"IndividualName parsed correctly\");\n        t.eq(obj.serviceProvider.serviceContact.positionName, \"Student Associate\", \"PositionName parsed correctly\");\n        t.eq(obj.serviceProvider.serviceContact.role, \"\", \"Role parsed correctly\");\n        t.eq(obj.serviceProvider.serviceContact.contactInfo.address.administrativeArea, \"NRW\", \"AdministrativeArea correctly parsed\");\n        t.eq(obj.serviceProvider.serviceContact.contactInfo.address.city, \"Muenster\", \"City correctly parsed\");\n        t.eq(obj.serviceProvider.serviceContact.contactInfo.address.country, \"Germany\", \"Country correctly parsed\");\n        t.eq(obj.serviceProvider.serviceContact.contactInfo.address.deliveryPoint, \"Weselerstrasse 253\", \"DeliveryPoint correctly parsed\");\n        t.eq(obj.serviceProvider.serviceContact.contactInfo.address.electronicMailAddress, \"ehjuerrens@uni-muenster.de\", \"ElectronicMailAddress correctly parsed\");\n        t.eq(obj.serviceProvider.serviceContact.contactInfo.address.postalCode, \"48149\", \"Postalcode correctly parsed\");\n        t.eq(obj.serviceProvider.serviceContact.contactInfo.phone.voice, \"+49-251-83-30088\", \"Voice phone correctly parsed\");\n\n        // operationsMetadata (from OWSCommon)\n        t.eq(obj.operationsMetadata.DescribeSensor.dcp.http.post[0].url, \"http://v-swe.uni-muenster.de:8080/WeatherSOS/sos\", \"POST url for DescribeSensor correctly parsed\");\n        var counter = 0;\n        for (var key in obj.operationsMetadata.DescribeSensor.parameters.procedure.allowedValues) {\n            if (counter == 0) {\n                t.eq(key, \"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\", \"Allowed value (1) for procedure parameter in DescribeSensor request correctly parsed\");\n            } else if (counter == 1) {\n                t.eq(key, \"urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93\", \"Allowed value (2) for procedure parameter in DescribeSensor request correctly parsed\");\n            }\n            counter++;\n        }\n        t.eq(obj.operationsMetadata.GetFeatureOfInterest.parameters.location.anyValue, true, \"AnyValue parsed correctly\");\n\n        t.eq(obj.operationsMetadata.GetObservation.parameters.eventTime.allowedValues.range.maxValue, \"2009-11-04T14:45:00+01\", \"Range maxValue parsed correctly\");\n        t.eq(obj.operationsMetadata.GetObservation.parameters.eventTime.allowedValues.range.minValue, \"2008-02-14T11:03:02+01\", \"Range minValue parsed correctly\");\n\n        // Contents (from SOS)\n        t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.name, \"Pressure of the atmosphere\", \"Name of offering correctly parsed\");\n        t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.observedProperties[0], \"urn:x-ogc:def:property:OGC::BarometricPressure\", \"ObservedProperty correctly parsed\");\n        t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.featureOfInterestIds[0], \"urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93\", \"Allowed value (1) for featureOfInterest correctly parsed\");\n        t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.featureOfInterestIds[1], \"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\", \"Allowed value (2) for featureOfInterest correctly parsed\");\n        t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.procedures[0], \"urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93\", \"Allowed value (1) for procedures correctly parsed\");\n        t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.procedures[1], \"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\", \"Allowed value (2) for procedures correctly parsed\");\n        t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.responseFormats[0], 'text/xml;subtype=\"om/1.0.0\"', \"Allowed value (1) for responseFormats correctly parsed\");\n        t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.responseFormats[1], \"application/zip\", \"Allowed value (2) for responseFormats correctly parsed\");\n        t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.responseModes[0], \"inline\", \"Allowed value (1) for responseModes correctly parsed\");\n        t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.responseModes[1], \"resultTemplate\", \"Allowed value (2) for responseModes correctly parsed\");\n        t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.resultModels[0], \"ns:Measurement\", \"Allowed value (1) for resultModels correctly parsed\");\n        t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.resultModels[1], \"ns:Observation\", \"Allowed value (2) for resultModels correctly parsed\");\n        t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.time.timePeriod.beginPosition, \"2008-12-20T02:29:27+01:00\", \"TimePeriod beginPosition correctly parsed\");\n        t.eq(obj.contents.offeringList.ATMOSPHERIC_PRESSURE.time.timePeriod.endPosition, \"2009-11-04T14:45:00+01:00\", \"TimePeriod endPosition correctly parsed\");\n\n    }\n\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/SOSCapabilities/v1_0_0.js",
    "content": "var doc = new OpenLayers.Format.XML().read(\n'<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n'<sos:Capabilities version=\"1.0.0\" updateSequence=\"2005-12-14T10:12:39+01\" xsi:schemaLocation=\"http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosAll.xsd\" xmlns:sos=\"http://www.opengis.net/sos/1.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">' +\n  '<ows:ServiceIdentification xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:om=\"http://www.opengis.net/om/1.0\" xmlns:swe=\"http://www.opengis.net/swe/1.0\">' +\n    '<ows:Title>IFGI WeatherSOS (stable)</ows:Title>' +\n    '<ows:Abstract>WeatherSOS (stable) at IfGI, Muenster, Germany. For more info: http://ifgipedia.uni-muenster.de/kms/documentation/swsl/sos/</ows:Abstract>' +\n    '<ows:Keywords>' +\n      '<ows:Keyword>rain gauge, radiation, pressure, windspeed, winddirection, temperature</ows:Keyword>' +\n    '</ows:Keywords>' +\n    '<ows:ServiceType codeSpace=\"http://opengeospatial.net\">OGC:SOS</ows:ServiceType>' +\n    '<ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion>' +\n    '<ows:Fees>NONE</ows:Fees>' +\n    '<ows:AccessConstraints>NONE</ows:AccessConstraints>' +\n  '</ows:ServiceIdentification>' +\n  '<ows:ServiceProvider xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:om=\"http://www.opengis.net/om/1.0\" xmlns:swe=\"http://www.opengis.net/swe/1.0\">' +\n    '<ows:ProviderName>Institute for Geoinformatics, University of Muenster</ows:ProviderName>' +\n    '<ows:ProviderSite xlink:href=\"http://ifgi.uni-muenster.de\"/>' +\n    '<ows:ServiceContact>' +\n      '<ows:IndividualName>Eike Hinderk Juerrens</ows:IndividualName>' +\n      '<ows:PositionName>Student Associate</ows:PositionName>' +\n      '<ows:ContactInfo>' +\n        '<ows:Phone>' +\n          '<ows:Voice>+49-251-83-30088</ows:Voice>' +\n        '</ows:Phone>' +\n        '<ows:Address>' +\n          '<ows:DeliveryPoint>Weselerstrasse 253</ows:DeliveryPoint>' +\n          '<ows:City>Muenster</ows:City>' +\n          '<ows:AdministrativeArea>NRW</ows:AdministrativeArea>' +\n          '<ows:PostalCode>48149</ows:PostalCode>' +\n          '<ows:Country>Germany</ows:Country>' +\n          '<ows:ElectronicMailAddress>ehjuerrens@uni-muenster.de</ows:ElectronicMailAddress>' +\n        '</ows:Address>' +\n      '</ows:ContactInfo>' +\n      '<ows:Role/>' +\n    '</ows:ServiceContact>' +\n  '</ows:ServiceProvider>' +\n  '<ows:OperationsMetadata xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:om=\"http://www.opengis.net/om/1.0\" xmlns:swe=\"http://www.opengis.net/swe/1.0\">' +\n    '<ows:Operation name=\"GetCapabilities\">' +\n      '<ows:DCP>' +\n        '<ows:HTTP>' +\n          '<ows:Get xlink:href=\"http://v-swe.uni-muenster.de:8080/WeatherSOS/sos?\"/>' +\n          '<ows:Post xlink:href=\"http://v-swe.uni-muenster.de:8080/WeatherSOS/sos\"/>' +\n        '</ows:HTTP>' +\n      '</ows:DCP>' +\n      '<ows:Parameter name=\"service\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>SOS</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"updateSequence\">' +\n        '<ows:AnyValue/>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"AcceptVersions\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>1.0.0</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"Sections\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>ServiceIdentification</ows:Value>' +\n          '<ows:Value>ServiceProvider</ows:Value>' +\n          '<ows:Value>OperationsMetadata</ows:Value>' +\n          '<ows:Value>Contents</ows:Value>' +\n          '<ows:Value>All</ows:Value>' +\n          '<ows:Value>Filter_Capabilities</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"AcceptFormats\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>text/xml</ows:Value>' +\n          '<ows:Value>application/zip</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n    '</ows:Operation>' +\n    '<ows:Operation name=\"GetObservation\">' +\n      '<ows:DCP>' +\n        '<ows:HTTP>' +\n          '<ows:Post xlink:href=\"http://v-swe.uni-muenster.de:8080/WeatherSOS/sos\"/>' +\n        '</ows:HTTP>' +\n      '</ows:DCP>' +\n      '<ows:Parameter name=\"version\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>1.0.0</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"service\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>SOS</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"srsName\">' +\n        '<ows:AnyValue/>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"offering\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>ATMOSPHERIC_TEMPERATURE</ows:Value>' +\n          '<ows:Value>RAIN_GAUGE</ows:Value>' +\n          '<ows:Value>WIND_DIRECTION</ows:Value>' +\n          '<ows:Value>WIND_SPEED</ows:Value>' +\n          '<ows:Value>HUMIDITY</ows:Value>' +\n          '<ows:Value>LUMINANCE</ows:Value>' +\n          '<ows:Value>ATMOSPHERIC_PRESSURE</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"eventTime\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Range>' +\n            '<ows:MinimumValue>2008-02-14T11:03:02+01</ows:MinimumValue>' +\n            '<ows:MaximumValue>2009-11-04T14:45:00+01</ows:MaximumValue>' +\n          '</ows:Range>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"procedure\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111</ows:Value>' +\n          '<ows:Value>urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"observedProperty\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>urn:x-ogc:def:property:OGC::Temperature</ows:Value>' +\n          '<ows:Value>urn:x-ogc:def:property:OGC::Precipitation1Hour</ows:Value>' +\n          '<ows:Value>urn:x-ogc:def:property:OGC::WindDirection</ows:Value>' +\n          '<ows:Value>urn:x-ogc:def:property:OGC::WindSpeed</ows:Value>' +\n          '<ows:Value>urn:x-ogc:def:property:OGC::RelativeHumidity</ows:Value>' +\n          '<ows:Value>urn:x-ogc:def:property:OGC::Luminance</ows:Value>' +\n          '<ows:Value>urn:x-ogc:def:property:OGC::BarometricPressure</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"featureOfInterest\">' +\n        '<ows:AnyValue/>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"result\">' +\n        '<ows:AnyValue/>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"responseFormat\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>text/xml;subtype=\"OM/1.0.0\"</ows:Value>' +\n          '<ows:Value>application/zip</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"resultModel\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>om:Observation</ows:Value>' +\n          '<ows:Value>om:CategoryObservation</ows:Value>' +\n          '<ows:Value>om:Measurement</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"responseMode\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>resultTemplate</ows:Value>' +\n          '<ows:Value>inline</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n    '</ows:Operation>' +\n    '<ows:Operation name=\"GetObservationById\">' +\n      '<ows:DCP>' +\n        '<ows:HTTP>' +\n          '<ows:Post xlink:href=\"http://v-swe.uni-muenster.de:8080/WeatherSOS/sos\"/>' +\n        '</ows:HTTP>' +\n      '</ows:DCP>' +\n      '<ows:Parameter name=\"version\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>1.0.0</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"service\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>SOS</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"srsName\">' +\n        '<ows:AnyValue/>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"ObservationId\">' +\n        '<ows:AnyValue/>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"responseFormat\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>text/xml;subtype=\"OM/1.0.0\"</ows:Value>' +\n          '<ows:Value>application/zip</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"resultModel\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>om:Observation</ows:Value>' +\n          '<ows:Value>om:CategoryObservation</ows:Value>' +\n          '<ows:Value>om:Measurement</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"responseMode\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>inline</ows:Value>' +\n          '<ows:Value>resultTemplate</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n    '</ows:Operation>' +\n    '<ows:Operation name=\"DescribeSensor\">' +\n      '<ows:DCP>' +\n        '<ows:HTTP>' +\n          '<ows:Post xlink:href=\"http://v-swe.uni-muenster.de:8080/WeatherSOS/sos\"/>' +\n        '</ows:HTTP>' +\n      '</ows:DCP>' +\n      '<ows:Parameter name=\"version\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>1.0.0</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"service\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>SOS</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"outputFormat\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>text/xml;subtype=\"sensorML/1.0.1\"</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"procedure\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111</ows:Value>' +\n          '<ows:Value>urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n    '</ows:Operation>' +\n    '<ows:Operation name=\"GetFeatureOfInterest\">' +\n      '<ows:DCP>' +\n        '<ows:HTTP>' +\n          '<ows:Post xlink:href=\"http://v-swe.uni-muenster.de:8080/WeatherSOS/sos\"/>' +\n        '</ows:HTTP>' +\n      '</ows:DCP>' +\n      '<ows:Parameter name=\"service\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>SOS</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"version\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>1.0.0</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"featureOfInterestId\">' +\n        '<ows:AllowedValues>' +\n          '<ows:Value>urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93</ows:Value>' +\n          '<ows:Value>urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111</ows:Value>' +\n        '</ows:AllowedValues>' +\n      '</ows:Parameter>' +\n      '<ows:Parameter name=\"location\">' +\n        '<ows:AnyValue/>' +\n      '</ows:Parameter>' +\n    '</ows:Operation>' +\n  '</ows:OperationsMetadata>' +\n  '<sos:Filter_Capabilities xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:om=\"http://www.opengis.net/om/1.0\" xmlns:swe=\"http://www.opengis.net/swe/1.0\">' +\n    '<ogc:Spatial_Capabilities>' +\n      '<ogc:GeometryOperands>' +\n        '<ogc:GeometryOperand>gml:Envelope</ogc:GeometryOperand>' +\n        '<ogc:GeometryOperand>gml:Polygon</ogc:GeometryOperand>' +\n        '<ogc:GeometryOperand>gml:Point</ogc:GeometryOperand>' +\n        '<ogc:GeometryOperand>gml:LineString</ogc:GeometryOperand>' +\n      '</ogc:GeometryOperands>' +\n      '<ogc:SpatialOperators>' +\n        '<ogc:SpatialOperator name=\"BBOX\"/>' +\n        '<ogc:SpatialOperator name=\"Contains\"/>' +\n        '<ogc:SpatialOperator name=\"Intersects\"/>' +\n        '<ogc:SpatialOperator name=\"Overlaps\"/>' +\n      '</ogc:SpatialOperators>' +\n    '</ogc:Spatial_Capabilities>' +\n    '<ogc:Temporal_Capabilities>' +\n      '<ogc:TemporalOperands>' +\n        '<ogc:TemporalOperand>gml:TimeInstant</ogc:TemporalOperand>' +\n        '<ogc:TemporalOperand>gml:TimePeriod</ogc:TemporalOperand>' +\n      '</ogc:TemporalOperands>' +\n      '<ogc:TemporalOperators>' +\n        '<ogc:TemporalOperator name=\"TM_During\"/>' +\n        '<ogc:TemporalOperator name=\"TM_Equals\"/>' +\n        '<ogc:TemporalOperator name=\"TM_After\"/>' +\n        '<ogc:TemporalOperator name=\"TM_Before\"/>' +\n      '</ogc:TemporalOperators>' +\n    '</ogc:Temporal_Capabilities>' +\n    '<ogc:Scalar_Capabilities>' +\n      '<ogc:ComparisonOperators>' +\n        '<ogc:ComparisonOperator>Between</ogc:ComparisonOperator>' +\n        '<ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator>' +\n        '<ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator>' +\n        '<ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator>' +\n        '<ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator>' +\n        '<ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator>' +\n        '<ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator>' +\n        '<ogc:ComparisonOperator>Like</ogc:ComparisonOperator>' +\n      '</ogc:ComparisonOperators>' +\n    '</ogc:Scalar_Capabilities>' +\n    '<ogc:Id_Capabilities>' +\n      '<ogc:FID/>' +\n      '<ogc:EID/>' +\n    '</ogc:Id_Capabilities>' +\n  '</sos:Filter_Capabilities>' +\n  '<sos:Contents>' +\n    '<sos:ObservationOfferingList>' +\n      '<sos:ObservationOffering gml:id=\"ATMOSPHERIC_TEMPERATURE\">' +\n        '<gml:name>Temperature of the atmosphere</gml:name>' +\n        '<gml:boundedBy>' +\n          '<gml:Envelope srsName=\"urn:ogc:def:crs:EPSG:4326\">' +\n            '<gml:lowerCorner>46.611644 7.6103</gml:lowerCorner>' +\n            '<gml:upperCorner>51.9412 13.883498</gml:upperCorner>' +\n          '</gml:Envelope>' +\n        '</gml:boundedBy>' +\n        '<sos:time>' +\n          '<gml:TimePeriod xsi:type=\"gml:TimePeriodType\">' +\n            '<gml:beginPosition>2008-11-20T15:20:22+01:00</gml:beginPosition>' +\n            '<gml:endPosition>2009-11-04T14:45:00+01:00</gml:endPosition>' +\n          '</gml:TimePeriod>' +\n        '</sos:time>' +\n        '<sos:procedure xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93\"/>' +\n        '<sos:procedure xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\"/>' +\n        '<sos:observedProperty xlink:href=\"urn:x-ogc:def:property:OGC::Temperature\"/>' +\n        '<sos:featureOfInterest xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93\"/>' +\n        '<sos:featureOfInterest xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\"/>' +\n        '<sos:responseFormat>text/xml;subtype=\"om/1.0.0\"</sos:responseFormat>' +\n        '<sos:responseFormat>application/zip</sos:responseFormat>' +\n        '<sos:resultModel xmlns:ns=\"http://www.opengis.net/om/1.0\">ns:Measurement</sos:resultModel>' +\n        '<sos:resultModel xmlns:ns=\"http://www.opengis.net/om/1.0\">ns:Observation</sos:resultModel>' +\n        '<sos:responseMode>inline</sos:responseMode>' +\n        '<sos:responseMode>resultTemplate</sos:responseMode>' +\n      '</sos:ObservationOffering>' +\n      '<sos:ObservationOffering gml:id=\"RAIN_GAUGE\">' +\n        '<gml:name>Rain</gml:name>' +\n        '<gml:boundedBy>' +\n          '<gml:Envelope srsName=\"urn:ogc:def:crs:EPSG:4326\">' +\n            '<gml:lowerCorner>46.611644 7.6103</gml:lowerCorner>' +\n            '<gml:upperCorner>51.9412 13.883498</gml:upperCorner>' +\n          '</gml:Envelope>' +\n        '</gml:boundedBy>' +\n        '<sos:time>' +\n          '<gml:TimePeriod xsi:type=\"gml:TimePeriodType\">' +\n            '<gml:beginPosition>2008-11-20T15:35:22+01:00</gml:beginPosition>' +\n            '<gml:endPosition>2009-11-04T14:45:00+01:00</gml:endPosition>' +\n          '</gml:TimePeriod>' +\n        '</sos:time>' +\n        '<sos:procedure xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93\"/>' +\n        '<sos:procedure xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\"/>' +\n        '<sos:observedProperty xlink:href=\"urn:x-ogc:def:property:OGC::Precipitation1Hour\"/>' +\n        '<sos:featureOfInterest xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93\"/>' +\n        '<sos:featureOfInterest xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\"/>' +\n        '<sos:responseFormat>text/xml;subtype=\"om/1.0.0\"</sos:responseFormat>' +\n        '<sos:responseFormat>application/zip</sos:responseFormat>' +\n        '<sos:resultModel xmlns:ns=\"http://www.opengis.net/om/1.0\">ns:Measurement</sos:resultModel>' +\n        '<sos:resultModel xmlns:ns=\"http://www.opengis.net/om/1.0\">ns:Observation</sos:resultModel>' +\n        '<sos:responseMode>inline</sos:responseMode>' +\n        '<sos:responseMode>resultTemplate</sos:responseMode>' +\n      '</sos:ObservationOffering>' +\n      '<sos:ObservationOffering gml:id=\"WIND_DIRECTION\">' +\n        '<gml:name>Direction of the wind</gml:name>' +\n        '<gml:boundedBy>' +\n          '<gml:Envelope srsName=\"urn:ogc:def:crs:EPSG:4326\">' +\n            '<gml:lowerCorner>46.611644 7.6103</gml:lowerCorner>' +\n            '<gml:upperCorner>51.9412 13.883498</gml:upperCorner>' +\n          '</gml:Envelope>' +\n        '</gml:boundedBy>' +\n        '<sos:time>' +\n          '<gml:TimePeriod xsi:type=\"gml:TimePeriodType\">' +\n            '<gml:beginPosition>2008-11-20T15:20:22+01:00</gml:beginPosition>' +\n            '<gml:endPosition>2009-11-04T14:45:00+01:00</gml:endPosition>' +\n          '</gml:TimePeriod>' +\n        '</sos:time>' +\n        '<sos:procedure xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93\"/>' +\n        '<sos:procedure xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\"/>' +\n        '<sos:observedProperty xlink:href=\"urn:x-ogc:def:property:OGC::WindDirection\"/>' +\n        '<sos:featureOfInterest xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93\"/>' +\n        '<sos:featureOfInterest xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\"/>' +\n        '<sos:responseFormat>text/xml;subtype=\"om/1.0.0\"</sos:responseFormat>' +\n        '<sos:responseFormat>application/zip</sos:responseFormat>' +\n        '<sos:resultModel xmlns:ns=\"http://www.opengis.net/om/1.0\">ns:Measurement</sos:resultModel>' +\n        '<sos:resultModel xmlns:ns=\"http://www.opengis.net/om/1.0\">ns:Observation</sos:resultModel>' +\n        '<sos:responseMode>inline</sos:responseMode>' +\n        '<sos:responseMode>resultTemplate</sos:responseMode>' +\n      '</sos:ObservationOffering>' +\n      '<sos:ObservationOffering gml:id=\"WIND_SPEED\">' +\n        '<gml:name>Speed of the wind</gml:name>' +\n        '<gml:boundedBy>' +\n          '<gml:Envelope srsName=\"urn:ogc:def:crs:EPSG:4326\">' +\n            '<gml:lowerCorner>46.611644 7.6103</gml:lowerCorner>' +\n            '<gml:upperCorner>51.9412 13.883498</gml:upperCorner>' +\n          '</gml:Envelope>' +\n        '</gml:boundedBy>' +\n        '<sos:time>' +\n          '<gml:TimePeriod xsi:type=\"gml:TimePeriodType\">' +\n            '<gml:beginPosition>2008-11-20T15:20:22+01:00</gml:beginPosition>' +\n            '<gml:endPosition>2009-11-04T14:45:00+01:00</gml:endPosition>' +\n          '</gml:TimePeriod>' +\n        '</sos:time>' +\n        '<sos:procedure xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93\"/>' +\n        '<sos:procedure xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\"/>' +\n        '<sos:observedProperty xlink:href=\"urn:x-ogc:def:property:OGC::WindSpeed\"/>' +\n        '<sos:featureOfInterest xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93\"/>' +\n        '<sos:featureOfInterest xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\"/>' +\n        '<sos:responseFormat>text/xml;subtype=\"om/1.0.0\"</sos:responseFormat>' +\n        '<sos:responseFormat>application/zip</sos:responseFormat>' +\n        '<sos:resultModel xmlns:ns=\"http://www.opengis.net/om/1.0\">ns:Measurement</sos:resultModel>' +\n        '<sos:resultModel xmlns:ns=\"http://www.opengis.net/om/1.0\">ns:Observation</sos:resultModel>' +\n        '<sos:responseMode>inline</sos:responseMode>' +\n        '<sos:responseMode>resultTemplate</sos:responseMode>' +\n      '</sos:ObservationOffering>' +\n      '<sos:ObservationOffering gml:id=\"HUMIDITY\">' +\n        '<gml:name>Humidity of the atmosphere</gml:name>' +\n        '<gml:boundedBy>' +\n          '<gml:Envelope srsName=\"urn:ogc:def:crs:EPSG:4326\">' +\n            '<gml:lowerCorner>46.611644 7.6103</gml:lowerCorner>' +\n            '<gml:upperCorner>51.9412 13.883498</gml:upperCorner>' +\n          '</gml:Envelope>' +\n        '</gml:boundedBy>' +\n        '<sos:time>' +\n          '<gml:TimePeriod xsi:type=\"gml:TimePeriodType\">' +\n            '<gml:beginPosition>2008-02-14T11:03:02+01:00</gml:beginPosition>' +\n            '<gml:endPosition>2009-11-04T14:45:00+01:00</gml:endPosition>' +\n          '</gml:TimePeriod>' +\n        '</sos:time>' +\n        '<sos:procedure xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93\"/>' +\n        '<sos:procedure xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\"/>' +\n        '<sos:observedProperty xlink:href=\"urn:x-ogc:def:property:OGC::RelativeHumidity\"/>' +\n        '<sos:featureOfInterest xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93\"/>' +\n        '<sos:featureOfInterest xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\"/>' +\n        '<sos:responseFormat>text/xml;subtype=\"om/1.0.0\"</sos:responseFormat>' +\n        '<sos:responseFormat>application/zip</sos:responseFormat>' +\n        '<sos:resultModel xmlns:ns=\"http://www.opengis.net/om/1.0\">ns:Measurement</sos:resultModel>' +\n        '<sos:resultModel xmlns:ns=\"http://www.opengis.net/om/1.0\">ns:Observation</sos:resultModel>' +\n        '<sos:responseMode>inline</sos:responseMode>' +\n        '<sos:responseMode>resultTemplate</sos:responseMode>' +\n      '</sos:ObservationOffering>' +\n      '<sos:ObservationOffering gml:id=\"LUMINANCE\">' +\n        '<gml:name>Luminance</gml:name>' +\n        '<gml:boundedBy>' +\n          '<gml:Envelope srsName=\"urn:ogc:def:crs:EPSG:4326\">' +\n            '<gml:lowerCorner>46.611644 7.6103</gml:lowerCorner>' +\n            '<gml:upperCorner>51.9412 13.883498</gml:upperCorner>' +\n          '</gml:Envelope>' +\n        '</gml:boundedBy>' +\n        '<sos:time>' +\n          '<gml:TimePeriod xsi:type=\"gml:TimePeriodType\">' +\n            '<gml:beginPosition>2008-11-20T15:20:22+01:00</gml:beginPosition>' +\n            '<gml:endPosition>2009-11-04T14:45:00+01:00</gml:endPosition>' +\n          '</gml:TimePeriod>' +\n        '</sos:time>' +\n        '<sos:procedure xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93\"/>' +\n        '<sos:procedure xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\"/>' +\n        '<sos:observedProperty xlink:href=\"urn:x-ogc:def:property:OGC::Luminance\"/>' +\n        '<sos:featureOfInterest xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93\"/>' +\n        '<sos:featureOfInterest xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\"/>' +\n        '<sos:responseFormat>text/xml;subtype=\"om/1.0.0\"</sos:responseFormat>' +\n        '<sos:responseFormat>application/zip</sos:responseFormat>' +\n        '<sos:resultModel xmlns:ns=\"http://www.opengis.net/om/1.0\">ns:Measurement</sos:resultModel>' +\n        '<sos:resultModel xmlns:ns=\"http://www.opengis.net/om/1.0\">ns:Observation</sos:resultModel>' +\n        '<sos:responseMode>inline</sos:responseMode>' +\n        '<sos:responseMode>resultTemplate</sos:responseMode>' +\n      '</sos:ObservationOffering>' +\n      '<sos:ObservationOffering gml:id=\"ATMOSPHERIC_PRESSURE\">' +\n        '<gml:name>Pressure of the atmosphere</gml:name>' +\n        '<gml:boundedBy>' +\n          '<gml:Envelope srsName=\"urn:ogc:def:crs:EPSG:4326\">' +\n            '<gml:lowerCorner>46.611644 7.6103</gml:lowerCorner>' +\n            '<gml:upperCorner>51.9412 13.883498</gml:upperCorner>' +\n          '</gml:Envelope>' +\n        '</gml:boundedBy>' +\n        '<sos:time>' +\n          '<gml:TimePeriod xsi:type=\"gml:TimePeriodType\">' +\n            '<gml:beginPosition>2008-12-20T02:29:27+01:00</gml:beginPosition>' +\n            '<gml:endPosition>2009-11-04T14:45:00+01:00</gml:endPosition>' +\n          '</gml:TimePeriod>' +\n        '</sos:time>' +\n        '<sos:procedure xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93\"/>' +\n        '<sos:procedure xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\"/>' +\n        '<sos:observedProperty xlink:href=\"urn:x-ogc:def:property:OGC::BarometricPressure\"/>' +\n        '<sos:featureOfInterest xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93\"/>' +\n        '<sos:featureOfInterest xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\"/>' +\n        '<sos:responseFormat>text/xml;subtype=\"om/1.0.0\"</sos:responseFormat>' +\n        '<sos:responseFormat>application/zip</sos:responseFormat>' +\n        '<sos:resultModel xmlns:ns=\"http://www.opengis.net/om/1.0\">ns:Measurement</sos:resultModel>' +\n        '<sos:resultModel xmlns:ns=\"http://www.opengis.net/om/1.0\">ns:Observation</sos:resultModel>' +\n        '<sos:responseMode>inline</sos:responseMode>' +\n        '<sos:responseMode>resultTemplate</sos:responseMode>' +\n      '</sos:ObservationOffering>' +\n    '</sos:ObservationOfferingList>' +\n  '</sos:Contents>' +\n'</sos:Capabilities>'\n);"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/SOSGetFeatureOfInterest.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_read_SOSGetFeatureOfInterest_single(t) {\n        t.plan(6);\n\n        var parser = new OpenLayers.Format.SOSGetFeatureOfInterest();\n        var text =\n            '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n            '<sa:SamplingPoint xmlns:sa=\"http://www.opengis.net/sampling/1.0\" xmlns:gml=\"http://www.opengis.net/gml\" gml:id=\"urn:ogc:object:feature:OSIRIS-HWS:4fc335bc-06d7-4d5e-a72a-1ac73b9f3b56\">' +\n            '<gml:name>Roof of the IfGI</gml:name>' +\n            '<sa:position>' +\n            '<gml:Point>' +\n            '<gml:pos srsName=\"urn:ogc:def:crs:EPSG:4326\">52.1524 5.3722</gml:pos>' +\n            '</gml:Point>' +\n            '</sa:position>' +\n            '</sa:SamplingPoint>';\n\n        var res = parser.read(text);\n        t.eq(res.length, 1, \"One feature parsed from response\");\n        t.eq(res[0].attributes.id, \"urn:ogc:object:feature:OSIRIS-HWS:4fc335bc-06d7-4d5e-a72a-1ac73b9f3b56\", \"gml:id correctly parsed\");\n        t.eq(res[0].attributes.name, \"Roof of the IfGI\", \"gml:name correctly parsed\");\n        t.eq(res[0].geometry instanceof OpenLayers.Geometry.Point, true, \"Geometry is a point geometry\");\n        t.eq(res[0].geometry.x, 5.3722, \"Geometry x coordinate correctly parsed\");\n        t.eq(res[0].geometry.y, 52.1524, \"Geometry y coordinate correctly parsed\");\n    }\n\n    function test_read_SOSGetFeatureOfInterest_multiple(t) {\n        t.plan(6);\n\n        var parser = new OpenLayers.Format.SOSGetFeatureOfInterest();\n        var text =\n            '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n            '<gml:FeatureCollection xmlns:gml=\"http://www.opengis.net/gml\" xmlns:sa=\"http://www.opengis.net/sampling/1.0\">' +\n            '<gml:featureMember>' +\n            '<sa:SamplingPoint gml:id=\"urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93\">' +\n            '<gml:name>weather @ roof of the ifgi, MS, Germany</gml:name>' +\n            '<sa:position>' +\n            '<gml:Point>' +\n            '<gml:pos srsName=\"urn:ogc:def:crs:EPSG:4326\">51.9412 7.6103</gml:pos>' +\n            '</gml:Point>' +\n            '</sa:position>' +\n            '</sa:SamplingPoint>' +\n            '</gml:featureMember>' +\n            '<gml:featureMember>' +\n            '<sa:SamplingPoint gml:id=\"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\">' +\n            '<gml:name>waether @ roof of the FH Kaernten, Villach, Austria</gml:name>' +\n            '<sa:position>' +\n            '<gml:Point>' +\n            '<gml:pos srsName=\"urn:ogc:def:crs:EPSG:4326\">46.611644 13.883498</gml:pos>' +\n            '</gml:Point>' +\n            '</sa:position>' +\n            '</sa:SamplingPoint>' +\n            '</gml:featureMember>' +\n            '</gml:FeatureCollection>';\n\n        var res = parser.read(text);\n        t.eq(res.length, 2, \"Two features parsed from response\");\n        t.eq(res[0].attributes.id, \"urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93\", \"gml:id correctly parsed\");\n        t.eq(res[1].attributes.name, \"waether @ roof of the FH Kaernten, Villach, Austria\", \"gml:name correctly parsed\");\n        t.eq(res[1].geometry instanceof OpenLayers.Geometry.Point, true, \"Geometry is a point geometry\");\n        t.eq(res[1].geometry.x, 13.883498, \"Geometry x coordinate correctly parsed\");\n        t.eq(res[1].geometry.y, 46.611644, \"Geometry y coordinate correctly parsed\");\n    }\n\n    function test_write_SOSGetFeatureOfInterest(t) {\n        t.plan(1);\n        var expect = '<GetFeatureOfInterest xmlns=\"http://www.opengis.net/sos/1.0\" version=\"1.0.0\" service=\"SOS\" xsi:schemaLocation=\"http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosAll.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><FeatureOfInterestId>urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93</FeatureOfInterestId><FeatureOfInterestId>urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111</FeatureOfInterestId></GetFeatureOfInterest>';\n        var format = new OpenLayers.Format.SOSGetFeatureOfInterest();\n        var output = format.writeNode(\"sos:GetFeatureOfInterest\", {fois: ['urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93', 'urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111']});\n        t.xml_eq(output, expect, \"Request XML is written out correctly\");\n    }\n\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/SOSGetObservation.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_read_SOSGetObservation(t) {\n        t.plan(13);\n\n        var parser = new OpenLayers.Format.SOSGetObservation();\n        var text =\n            '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n            '<om:ObservationCollection xmlns:om=\"http://www.opengis.net/om/1.0\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:sa=\"http://www.opengis.net/sampling/1.0\" gml:id=\"oc_0\" xsi:schemaLocation=\"http://www.opengis.net/om/1.0 http://schemas.opengis.net/om/1.0.0/om.xsd http://www.opengis.net/sampling/1.0 http://schemas.opengis.net/sampling/1.0.0/sampling.xsd\">' +\n            '<gml:boundedBy>' +\n            '<gml:Envelope srsName=\"urn:ogc:def:crs:EPSG:4326\">' +\n            '<gml:lowerCorner>52.1524 5.3722</gml:lowerCorner>' +\n            '<gml:upperCorner>52.1524 5.3722</gml:upperCorner>' +\n            '</gml:Envelope>' +\n            '</gml:boundedBy>' +\n            '<om:member>' +\n            '<om:Measurement gml:id=\"o_51082\">' +\n            '<om:samplingTime>' +\n            '<gml:TimeInstant xsi:type=\"gml:TimeInstantType\">' +\n            '<gml:timePosition>2009-12-02T10:35:00.000+01:00</gml:timePosition>' +\n            '</gml:TimeInstant>' +\n            '</om:samplingTime>' +\n            '<om:procedure xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:4fc335bc-06d7-4d5e-a72a-1ac73b9f3b56\"/>' +\n            '<om:observedProperty xlink:href=\"urn:x-ogc:def:property:OGC::Temperature\"/>' +\n            '<om:featureOfInterest>' +\n            '<sa:SamplingPoint gml:id=\"urn:ogc:object:feature:OSIRIS-HWS:4fc335bc-06d7-4d5e-a72a-1ac73b9f3b56\">' +\n            '<gml:name>Roof of the IfGI</gml:name>' +\n            '<sa:position>' +\n            '<gml:Point>' +\n            '<gml:pos srsName=\"urn:ogc:def:crs:EPSG:4326\">52.1524 5.3722</gml:pos>' +\n            '</gml:Point>' +\n            '</sa:position>' +\n            '</sa:SamplingPoint>' +\n            '</om:featureOfInterest>' +\n            '<om:result uom=\"Cel\">4.9</om:result>' +\n            '</om:Measurement>' +\n            '</om:member>' +\n            '</om:ObservationCollection>';\n\n        var res = parser.read(text);\n        t.eq(res.measurements.length, 1, \"One measurement parsed\");\n        t.eq(res.id, \"oc_0\", \"Observation collection id correctly parsed\");\n        var measurement = res.measurements[0];\n        t.eq(measurement.observedProperty, \"urn:x-ogc:def:property:OGC::Temperature\", \"Observed property correctly parsed\");\n        t.eq(measurement.procedure, \"urn:ogc:object:feature:OSIRIS-HWS:4fc335bc-06d7-4d5e-a72a-1ac73b9f3b56\", \"Procedure correctly parsed\");\n        t.eq(measurement.result.uom, \"Cel\", \"Units of measurement correctly parsed\");\n        t.eq(measurement.result.value, \"4.9\", \"Value correctly parsed\");\n        t.eq(measurement.samplingTime.timeInstant.timePosition, \"2009-12-02T10:35:00.000+01:00\", \"Sampling time correctly parsed\");\n\n        var response = [];\n        response.push('<?xml version=\"1.0\" encoding=\"UTF-8\"?>',\n'<om:ObservationCollection gml:id=\"oc_0\" xsi:schemaLocation=\"http://www.opengis.net/om/1.0 http://schemas.opengis.net/om/1.0.0/om.xsd http://www.opengis.net/sampling/1.0 http://schemas.opengis.net/sampling/1.0.0/sampling.xsd\" xmlns:om=\"http://www.opengis.net/om/1.0\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:swe=\"http://www.opengis.net/swe/1.0.1\" xmlns:sa=\"http://www.opengis.net/sampling/1.0\">',\n'  <gml:boundedBy>',\n'    <gml:Envelope srsName=\"urn:ogc:def:crs:EPSG:4326\">',\n'      <gml:lowerCorner>46.611644 7.6103</gml:lowerCorner>',\n'      <gml:upperCorner>51.9412 13.883498</gml:upperCorner>',\n'    </gml:Envelope>',\n'  </gml:boundedBy>',\n'  <om:member>',\n'    <om:Observation gml:id=\"ot_583227\">',\n'      <om:samplingTime>',\n'        <gml:TimePeriod xsi:type=\"gml:TimePeriodType\">',\n'          <gml:beginPosition>2009-09-28T13:45:00.000+02:00</gml:beginPosition>',\n'          <gml:endPosition>2009-09-28T13:45:00.000+02:00</gml:endPosition>',\n'        </gml:TimePeriod>',\n'      </om:samplingTime>',\n'      <om:procedure xlink:href=\"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\"/>',\n'      <om:observedProperty>',\n'        <swe:CompositePhenomenon gml:id=\"cpid0\" dimension=\"1\">',\n'          <gml:name>resultComponents</gml:name>',\n'          <swe:component xlink:href=\"urn:ogc:data:time:iso8601\"/>',\n'          <swe:component xlink:href=\"urn:ogc:def:property:OGC::Precipitation1Hour\"/>',\n'        </swe:CompositePhenomenon>',\n'      </om:observedProperty>',\n'      <om:featureOfInterest>',\n'        <gml:FeatureCollection>',\n'          <gml:featureMember>',\n'            <sa:SamplingPoint gml:id=\"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\" xsi:schemaLocation=\" http://www.opengis.net/sampling/1.0 http://schemas.opengis.net/sampling/1.0.0/sampling.xsd\">',\n'              <gml:name>waether @ roof of the FH Kaernten, Villach, Austria</gml:name>',\n'              <sa:sampledFeature xlink:href=\"urn:ogc:def:nil:OGC:unknown\"/>',\n'              <sa:position>',\n'                <gml:Point>',\n'                  <gml:pos srsName=\"urn:ogc:def:crs:EPSG:4326\">46.611644 13.883498</gml:pos>',\n'                </gml:Point>',\n'              </sa:position>',\n'            </sa:SamplingPoint>',\n'          </gml:featureMember>',\n'        </gml:FeatureCollection>',\n'      </om:featureOfInterest>',\n'      <om:result>',\n'        <swe:DataArray>',\n'          <swe:elementCount>',\n'            <swe:Count>',\n'              <swe:value>1</swe:value>',\n'            </swe:Count>',\n'          </swe:elementCount>',\n'          <swe:elementType name=\"Components\">',\n'            <swe:DataRecord>',\n'              <swe:field name=\"Time\">',\n'                <swe:Time definition=\"urn:ogc:data:time:iso8601\"/>',\n'              </swe:field>',\n'              <swe:field name=\"feature\">',\n'                <swe:Text definition=\"urn:ogc:data:feature\"/>',\n'              </swe:field>',\n'              <swe:field name=\"urn:ogc:def:property:OGC::Precipitation1Hour\">',\n'                <swe:Quantity definition=\"urn:ogc:def:property:OGC::Precipitation1Hour\">',\n'                  <swe:uom code=\"mm\"/>',\n'                </swe:Quantity>',\n'              </swe:field>',\n'            </swe:DataRecord>',\n'          </swe:elementType>',\n'          <swe:encoding>',\n'            <swe:TextBlock decimalSeparator=\".\" tokenSeparator=\",\" blockSeparator=\";\"/>',\n'          </swe:encoding>',\n'          <swe:values>2009-09-28T13:45:00.000+02:00,urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111,0.0;</swe:values>',\n'        </swe:DataArray>',\n'      </om:result>',\n'    </om:Observation>',\n'  </om:member>',\n'</om:ObservationCollection>');\n        text = response.join(\"\");\n        var res = parser.read(text);\n        t.eq(res.observations.length, 1, \"1 observation parsed\");\n        var observation = res.observations[0];\n        t.eq(observation.procedure, \"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\", \"procedure parsed correctly\");\n        t.eq(observation.fois.length, 1, \"One foi parsed for the observation\");\n        var foi = observation.fois[0];\n        var feature = foi.features[0];\n        t.eq(feature.attributes.id, \"urn:ogc:object:feature:OSIRIS-HWS:efeb807b-bd24-4128-a920-f6729bcdd111\", \"Foi id correctly parsed\");\n        t.eq(feature.attributes.name, \"waether @ roof of the FH Kaernten, Villach, Austria\", \"Foi name correctly parsed\");\n        t.ok(feature.geometry instanceof OpenLayers.Geometry.Point, \"Geometry correctly parsed\");\n    }\n\n    function test_write_SOSGetObservation(t) {\n        t.plan(2);\n        var expect = '<GetObservation xmlns=\"http://www.opengis.net/sos/1.0\" version=\"1.0.0\" service=\"SOS\" xsi:schemaLocation=\"http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosGetObservation.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><offering>TEMPERATURE</offering><eventTime><ogc:TM_Equals xmlns:ogc=\"http://www.opengis.net/ogc\"><ogc:PropertyName>urn:ogc:data:time:iso8601</ogc:PropertyName><gml:TimeInstant xmlns:gml=\"http://www.opengis.net/gml\"><gml:timePosition>latest</gml:timePosition></gml:TimeInstant></ogc:TM_Equals></eventTime><procedure>urn:ogc:object:feature:OSIRIS-HWS:4fc335bc-06d7-4d5e-a72a-1ac73b9f3b56</procedure><observedProperty>urn:x-ogc:def:property:OGC::Temperature</observedProperty><responseFormat>text/xml;subtype=\"om/1.0.0\"</responseFormat><resultModel>Measurement</resultModel><responseMode>inline</responseMode></GetObservation>';\n        var format = new OpenLayers.Format.SOSGetObservation();\n        var output = format.write({eventTime: 'latest', resultModel: 'Measurement', responseMode: 'inline',\n            procedures: ['urn:ogc:object:feature:OSIRIS-HWS:4fc335bc-06d7-4d5e-a72a-1ac73b9f3b56'], responseFormat: 'text/xml;subtype=\"om/1.0.0\"',\n            offering: 'TEMPERATURE', observedProperties: ['urn:x-ogc:def:property:OGC::Temperature']});\n        t.xml_eq(output, expect, \"Request XML is written out correctly\");\n\n        var expected = [];\n\n        expected.push('<?xml version=\"1.0\" encoding=\"UTF-8\"?>',\n'<GetObservation xmlns=\"http://www.opengis.net/sos/1.0\"',\n'  xmlns:gml=\"http://www.opengis.net/gml\"',\n'  xmlns:om=\"http://www.opengis.net/om/1.0\"',\n'  xmlns:ogc=\"http://www.opengis.net/ogc\"',\n'  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"',\n'  xsi:schemaLocation=\"http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosGetObservation.xsd\"',\n'  service=\"SOS\" version=\"1.0.0\">',\n'  <offering>RAIN_GAUGE</offering>',\n'  <eventTime>',\n'    <ogc:TM_Equals>',\n'      <ogc:PropertyName>urn:ogc:data:time:iso8601</ogc:PropertyName>',\n'      <gml:TimeInstant>',\n'        <gml:timePosition>latest</gml:timePosition>',\n'      </gml:TimeInstant>',\n'    </ogc:TM_Equals>',\n'  </eventTime>',\n'  <observedProperty>urn:ogc:def:property:OGC::Precipitation1Hour</observedProperty>',\n'  <featureOfInterest>',\n'    <ObjectID>urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93</ObjectID>',\n'  </featureOfInterest>',\n'  <responseFormat>text/xml;subtype=\"om/1.0.0\"</responseFormat>',\n'</GetObservation>');\n        expect = expected.join(\"\");\n        var output = format.write({eventTime: 'latest', offering: 'RAIN_GAUGE',\n            observedProperties: ['urn:ogc:def:property:OGC::Precipitation1Hour'],\n            responseFormat: 'text/xml;subtype=\"om/1.0.0\"',\n            foi: {objectId: 'urn:ogc:object:feature:OSIRIS-HWS:3d3b239f-7696-4864-9d07-15447eae2b93'}});\n        t.xml_eq(output, expect, \"Request XML is written out correctly\");\n    }\n\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/TMSCapabilities.html",
    "content": "<html>\n<head> \n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_read_services(t) {\n        t.plan(3);\n        var xml = document.getElementById(\"services\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n        var format = new OpenLayers.Format.TMSCapabilities();\n        var obj = format.read(doc);\n        t.eq(obj.services.length, 1, \"1 service expected\");\n        t.eq(obj.services[0].href, \"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/\", \"href correctly parsed\");\n        t.eq(obj.services[0].version, \"1.0.0\", \"version correctly parsed\");\n    }\n\n    function test_read_v1(t) {\n        t.plan(5);\n        var xml = document.getElementById(\"v1\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n        var format = new OpenLayers.Format.TMSCapabilities();\n        var obj = format.read(doc);\n        t.eq(obj.tileMaps.length, 39, \"39 tileMaps parsed\");\n        t.eq(obj.tileMaps[0].href, \"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/linktothepast/\", \"tileMap href correct\");\n        t.eq(obj.tileMaps[0].srs, \"EPSG:4326\", \"tileMap srs correct\");\n        t.eq(obj.tileMaps[0].title, \"linktothepast\", \"tileMap title correct\");\n        t.eq(obj.tileMaps[0].profile, \"global-geodetic\", \"tileMap profile correct\");\n    }\n\n    function test_read_tilemap(t) {\n        t.plan(13);\n        var xml = document.getElementById(\"tilemap\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n        var format = new OpenLayers.Format.TMSCapabilities();\n        var obj = format.read(doc);\n        t.eq(obj.title, \"basic\", \"tileMap title read correctly\");\n        t.eq(obj['abstract'], \"VMap0-based vector layer, styled by Schuyler Erle.\", \"tileMap abstract correct\");\n        t.eq(obj.srs, \"EPSG:4326\", \"tileMap srs correct\");\n        t.ok(obj.bbox.equals(new OpenLayers.Bounds(-180, -90, 180, 90)), \"bbox correct\");\n        t.ok(obj.origin.equals(new OpenLayers.LonLat(-180, -90)), \"origin correct\");\n        t.eq(obj.tileFormat.width, 256, \"width correct\");\n        t.eq(obj.tileFormat.height, 256, \"height correct\");\n        t.eq(obj.tileFormat.mimeType, \"image/png\", \"MIME type correct\");\n        t.eq(obj.tileFormat.extension, \"png\", \"extension correct\");\n        t.eq(obj.tileSets.length, 20, \"20 tileSets\");\n        t.eq(obj.tileSets[0].href, \"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/0\", \"tileSet href correct\");\n        t.eq(obj.tileSets[0].unitsPerPixel, 0.70312500000000000000, \"unitsPerPixel correct\");\n        t.eq(obj.tileSets[0].order, 0, \"order correct\");\n    }\n\n    </script> \n</head>\n<body>\n<div id=\"services\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<Services>\n    <TileMapService version=\"1.0.0\" href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/\" />\n</Services>\n-->\n</div>\n<div id=\"v1\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<TileMapService version=\"1.0.0\">\n    <TileMaps>\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/linktothepast/\"\n            srs=\"EPSG:4326\" title=\"linktothepast\" profile=\"global-geodetic\"/>\n\n        <TileMap\n            href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/xkcd-onlinecommunities/\"\n            srs=\"EPSG:4326\" title=\"xkcd-onlinecommunities\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-7-2/\"\n            srs=\"EPSG:4326\" title=\"mario-7-2\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-7-3/\"\n            srs=\"EPSG:4326\" title=\"mario-7-3\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-7-1/\"\n            srs=\"EPSG:4326\" title=\"mario-7-1\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-6-3/\"\n            srs=\"EPSG:4326\" title=\"mario-6-3\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-6-2/\"\n            srs=\"EPSG:4326\" title=\"mario-6-2\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-6-1/\"\n            srs=\"EPSG:4326\" title=\"mario-6-1\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-6-4/\"\n            srs=\"EPSG:4326\" title=\"mario-6-4\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/dragonwarrior/\"\n            srs=\"EPSG:4326\" title=\"dragonwarrior\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/DRG/\" srs=\"EPSG:4326\"\n            title=\"DRG\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/basic/\" srs=\"EPSG:4326\"\n            title=\"basic\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-5-4/\"\n            srs=\"EPSG:4326\" title=\"mario-5-4\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-5-1/\"\n            srs=\"EPSG:4326\" title=\"mario-5-1\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-5-2/\"\n            srs=\"EPSG:4326\" title=\"mario-5-2\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-5-3/\"\n            srs=\"EPSG:4326\" title=\"mario-5-3\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/avalon/\"\n            srs=\"EPSG:4326\" title=\"avalon\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-4-1/\"\n            srs=\"EPSG:4326\" title=\"mario-4-1\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-4-3/\"\n            srs=\"EPSG:4326\" title=\"mario-4-3\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-4-2/\"\n            srs=\"EPSG:4326\" title=\"mario-4-2\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-4-4/\"\n            srs=\"EPSG:4326\" title=\"mario-4-4\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-8-4/\"\n            srs=\"EPSG:4326\" title=\"mario-8-4\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-8-1/\"\n            srs=\"EPSG:4326\" title=\"mario-8-1\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-3-4/\"\n            srs=\"EPSG:4326\" title=\"mario-3-4\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-8-3/\"\n            srs=\"EPSG:4326\" title=\"mario-8-3\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-8-2/\"\n            srs=\"EPSG:4326\" title=\"mario-8-2\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-3-2/\"\n            srs=\"EPSG:4326\" title=\"mario-3-2\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-7-4/\"\n            srs=\"EPSG:4326\" title=\"mario-7-4\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-2-3/\"\n            srs=\"EPSG:4326\" title=\"mario-2-3\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-2-2/\"\n            srs=\"EPSG:4326\" title=\"mario-2-2\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-2-1/\"\n            srs=\"EPSG:4326\" title=\"mario-2-1\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-2-4/\"\n            srs=\"EPSG:4326\" title=\"mario-2-4\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/DOQ/\" srs=\"EPSG:4326\"\n            title=\"DOQ\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-1-1/\"\n            srs=\"EPSG:4326\" title=\"mario-1-1\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-1-2/\"\n            srs=\"EPSG:4326\" title=\"mario-1-2\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-1-3/\"\n            srs=\"EPSG:4326\" title=\"mario-1-3\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-1-4/\"\n            srs=\"EPSG:4326\" title=\"mario-1-4\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-3-3/\"\n            srs=\"EPSG:4326\" title=\"mario-3-3\" profile=\"global-geodetic\"/>\n\n        <TileMap href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/1.0.0/mario-3-1/\"\n            srs=\"EPSG:4326\" title=\"mario-3-1\" profile=\"global-geodetic\"/>\n\n    </TileMaps>\n</TileMapService>\n-->\n</div>\n<div id=\"tilemap\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<TileMap version=\"1.0.0\"\n    tilemapservice=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/\">\n    <Title>basic</Title>\n    <Abstract>VMap0-based vector layer, styled by Schuyler Erle.</Abstract>\n    <SRS>EPSG:4326</SRS>\n    <BoundingBox minx=\"-180.000000\" miny=\"-90.000000\" maxx=\"180.000000\" maxy=\"90.000000\"/>\n    <Origin x=\"-180.000000\" y=\"-90.000000\"/>\n    <TileFormat width=\"256\" height=\"256\" mime-type=\"image/png\" extension=\"png\"/>\n    <TileSets>\n\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/0\"\n            units-per-pixel=\"0.70312500000000000000\" order=\"0\"/>\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/1\"\n            units-per-pixel=\"0.35156250000000000000\" order=\"1\"/>\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/2\"\n            units-per-pixel=\"0.17578125000000000000\" order=\"2\"/>\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/3\"\n            units-per-pixel=\"0.08789062500000000000\" order=\"3\"/>\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/4\"\n            units-per-pixel=\"0.04394531250000000000\" order=\"4\"/>\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/5\"\n            units-per-pixel=\"0.02197265625000000000\" order=\"5\"/>\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/6\"\n            units-per-pixel=\"0.01098632812500000000\" order=\"6\"/>\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/7\"\n            units-per-pixel=\"0.00549316406250000000\" order=\"7\"/>\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/8\"\n            units-per-pixel=\"0.00274658203125000000\" order=\"8\"/>\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/9\"\n            units-per-pixel=\"0.00137329101562500000\" order=\"9\"/>\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/10\"\n            units-per-pixel=\"0.00068664550781250000\" order=\"10\"/>\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/11\"\n            units-per-pixel=\"0.00034332275390625000\" order=\"11\"/>\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/12\"\n            units-per-pixel=\"0.00017166137695312500\" order=\"12\"/>\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/13\"\n            units-per-pixel=\"0.00008583068847656250\" order=\"13\"/>\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/14\"\n            units-per-pixel=\"0.00004291534423828125\" order=\"14\"/>\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/15\"\n            units-per-pixel=\"0.00002145767211914062\" order=\"15\"/>\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/16\"\n            units-per-pixel=\"0.00001072883605957031\" order=\"16\"/>\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/17\"\n            units-per-pixel=\"0.00000536441802978516\" order=\"17\"/>\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/18\"\n            units-per-pixel=\"0.00000268220901489258\" order=\"18\"/>\n        <TileSet href=\"http://tilecache.osgeo.org/wms-c/Basic.py/1.0.0/basic/1.0.0/basic/19\"\n            units-per-pixel=\"0.00000134110450744629\" order=\"19\"/>\n    </TileSets>\n</TileMap>\n-->\n</div>\n</body>\n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/Text.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n    function test_basic(t) {\n        t.plan(5);\n        var format = new OpenLayers.Format.Text({extractStyles: true});\n        var features = format.read(OpenLayers.Util.getElement(\"content\").value);\n        t.eq(features[0].style.externalGraphic, format.defaultStyle.externalGraphic, \"style is set to defaults if no style props set in text file\");\n        var features = format.read(OpenLayers.Util.getElement(\"contentMarker\").value);\n        t.eq(features[0].style.externalGraphic, OpenLayers.Util.getImagesLocation() + \"marker.png\", \"marker set correctly by default.\");\n        \n        var features = format.read(OpenLayers.Util.getElement(\"content2\").value);\n        t.eq(features.length, 2, \"two features read\");\n        t.eq(features[0].style.externalGraphic, \"marker.png\", \"marker set correctly from data.\");\n        // t.eq(format.defaultStyle.externalGraphic, \"../../img/marker.png\", \"defaultStyle externalGraphic not changed by pulling from data\");\n\n        var format = new OpenLayers.Format.Text({extractStyles: false});\n        var features = format.read(OpenLayers.Util.getElement(\"content2\").value);\n        t.eq(features[0].style, null, \"extractStyles: false results in null style property, even with style properties used\");\n    }\n\tfunction test_extra(t) {\n        t.plan(1);\n        var format = new OpenLayers.Format.Text();\n        var features = format.read(OpenLayers.Util.getElement(\"content3\").value);\n        t.eq(features[0].attributes.whee, \"chicken\", \"extra attributes are stored for later use\");\n\t}\n    </script>\n</head>\n<body>\n<textarea id=\"content\">\npoint\n5,5\n</textarea>\n<textarea id=\"contentMarker\">\npoint\ticonSize\n5,5\t8,8\n</textarea>\n<textarea id=\"content2\">\npoint\ticon\n5,5\tmarker.png\n10,10\tmarker2.png\n</textarea>\n<textarea id=\"content3\">\npoint\twhee\n5,5\tchicken\t\n</textarea>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WCSCapabilities/v1.html",
    "content": "<html> \n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_read_exception(t) {\n        t.plan(1);\n        var parser = new OpenLayers.Format.WCSCapabilities();\n        var text = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n            '<ows:ExceptionReport language=\"en\" version=\"1.0.0\"' +\n            '    xsi:schemaLocation=\"http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/owsExceptionReport.xsd\"' +\n            '    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ows=\"http://www.opengis.net/ows\">' +\n            '    <ows:Exception locator=\"foo\" exceptionCode=\"InvalidParameterValue\">' +\n            '        <ows:ExceptionText>Update error: Error occured updating features</ows:ExceptionText>' +\n            '        <ows:ExceptionText>Second exception line</ows:ExceptionText>' +\n            '    </ows:Exception>' +\n            '</ows:ExceptionReport>';\n\n        var obj = parser.read(text);\n        t.ok(!!obj.error, \"Error reported correctly\");      // The above should place an error in obj.error\n    }\n    \n    function test_read(t) {\n        t.plan(54);     // Number of tests performed: If you add a test below, be sure to increment this accordingly\n       \n        var parser = new OpenLayers.Format.WCSCapabilities();\n\n        // MapServer, v1.0.0\n        var text = '<?xml version=\"1.0\" encoding=\"UTF-8\"?><WCS_Capabilities xmlns=\"http://www.opengis.net/wcs\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" version=\"1.0.0\" updateSequence=\"0\" xsi:schemaLocation=\"http://www.opengis.net/wcs http://schemas.opengis.net/wcs/1.0.0/wcsCapabilities.xsd\"><Service><name>MapServer WCS</name><label>This installation serves data for testing</label><keywords><keyword>Geospatial WebServices</keyword><keyword>Luxembourg!</keyword></keywords><responsibleParty><individualName>Leroy Dumerde</individualName><organisationName>CRP Henri Tudor</organisationName><positionName>R+D engineer</positionName><contactInfo><phone><voice>6463320</voice><facsimile>6465955</facsimile></phone><address><deliveryPoint>66, rue de Luxembourg</deliveryPoint><city>Esch-sur-Alzette</city><administrativeArea/><postalCode>97202</postalCode><country>Luxembourg</country><electronicMailAddress>flappy@tutones.com</electronicMailAddress></address><onlineResource xlink:type=\"simple\" xlink:href=\"http://services.magnificent.lu/cgi-bin/mapserv?map=/var/www/MapFiles/wcs_test.map&amp;\"/></contactInfo></responsibleParty><fees>mucho dinero</fees><accessConstraints>Open to the public</accessConstraints></Service><Capability><Request><GetCapabilities><DCPType><HTTP><Get><OnlineResource xlink:type=\"simple\" xlink:href=\"http://services.magnificent.get.lu/cgi-bin/mapserv?map=/var/www/MapFiles/wcs_test.map&amp;\"/></Get></HTTP></DCPType><DCPType><HTTP><Post><OnlineResource xlink:type=\"simple\" xlink:href=\"http://services.magnificent.post.lu/cgi-bin/mapserv?map=/var/www/MapFiles/wcs_test.map&amp;\"/></Post></HTTP></DCPType></GetCapabilities><DescribeCoverage><DCPType><HTTP><Get><OnlineResource xlink:type=\"simple\" xlink:href=\"http://services.magnificent.lu/cgi-bin/mapserv?map=/var/www/MapFiles/wcs_test.map&amp;\"/></Get></HTTP></DCPType><DCPType><HTTP><Post><OnlineResource xlink:type=\"simple\" xlink:href=\"http://services.magnificent.lu/cgi-bin/mapserv?map=/var/www/MapFiles/wcs_test.map&amp;\"/></Post></HTTP></DCPType></DescribeCoverage><GetCoverage><DCPType><HTTP><Get><OnlineResource xlink:type=\"simple\" xlink:href=\"http://services.magnificent.lu/cgi-bin/mapserv?map=/var/www/MapFiles/wcs_test.map&amp;\"/></Get></HTTP></DCPType><DCPType><HTTP><Post><OnlineResource xlink:type=\"simple\" xlink:href=\"http://services.magnificent.lu/cgi-bin/mapserv?map=/var/www/MapFiles/wcs_test.map&amp;\"/></Post></HTTP></DCPType></GetCoverage></Request><Exception><Format>application/vnd.ogc.se_xml</Format></Exception></Capability><ContentMetadata><CoverageOfferingBrief><name>ro_dsm</name><label>Rotterdam DSM</label><lonLatEnvelope srsName=\"urn:ogc:def:crs:OGC:1.3:CRS84\"><gml:pos>4.44444 51.515151</gml:pos><gml:pos>5.55555 52.525252</gml:pos></lonLatEnvelope></CoverageOfferingBrief><CoverageOfferingBrief><name>ro_dsm_mini</name><label>ro_dsm_mini</label><lonLatEnvelope srsName=\"urn:ogc:def:crs:OGC:1.3:CRS84\"><gml:pos>4.47489346945755 51.9159453786927</gml:pos><gml:pos>4.47687824892444 51.9170706688033</gml:pos></lonLatEnvelope></CoverageOfferingBrief><CoverageOfferingBrief><name>ro_irra</name><label>ro_irra</label><lonLatEnvelope srsName=\"urn:ogc:def:crs:OGC:1.3:CRS84\"><gml:pos>4.471333734139 51.912813427383</gml:pos><gml:pos>4.4808508475645 51.9248713705576</gml:pos></lonLatEnvelope></CoverageOfferingBrief><CoverageOfferingBrief><name>ro_irra_ext</name><label>ro_irra_ext</label><lonLatEnvelope srsName=\"urn:ogc:def:crs:OGC:1.3:CRS84\"><gml:pos>4.10024171314823 51.9359764992844</gml:pos><gml:pos>4.21909054278063 52.001415228243</gml:pos></lonLatEnvelope></CoverageOfferingBrief></ContentMetadata></WCS_Capabilities>'; \n\n        var res1_0_0 = parser.read(text);\n\n        t.ok(!res1_0_0.error, \"Parsing XML generated no errors\");\n        \n        t.eq(res1_0_0.serviceIdentification.keywords.length, 2, \"Correct number of Service>Keywords found\");\n        t.eq(res1_0_0.serviceIdentification.keywords[0], \"Geospatial WebServices\", \"Service>Keywords correctly parsed\");\n        \n        var serviceIdentification = res1_0_0.serviceIdentification;\n        t.eq(serviceIdentification.fees, \"mucho dinero\", \"Service>Fees correctly parsed\");\n        t.eq(serviceIdentification.accessConstraints, \"Open to the public\", \"Service>AccessConstraints correctly parsed\");\n        t.eq(serviceIdentification.title, \"MapServer WCS\", \"Service>Name correctly parsed\");\n        t.eq(serviceIdentification.abstract, \"This installation serves data for testing\", \"Service>Title correctly parsed\");\n\n        var serviceProvider = res1_0_0.serviceProvider;\n\n        t.eq(serviceProvider.providerName, \"CRP Henri Tudor\", \"Service>ResponsibleParty>OrganisationName correctly parsed\");\n\n        var serviceContact = serviceProvider.serviceContact;\n        t.eq(serviceContact.individualName, \"Leroy Dumerde\", \"Service>ResponsibleParty>IndividualName correctly parsed\");\n        t.eq(serviceContact.positionName, \"R+D engineer\", \"Service>ResponsibleParty>PositionName correctly parsed\");\n        t.eq(serviceContact.contactInfo.phone.facsimile, \"6465955\", \"Service>responsibleParty>ContactInfo>Phone>Facsimile correctly parsed\");\n        t.eq(serviceContact.contactInfo.phone.voice, \"6463320\", \"Service>responsibleParty>ContactInfo>Phone>Voice correctly parsed\");\n\n        var address = serviceContact.contactInfo.address;\n        t.eq(address.city, \"Esch-sur-Alzette\", \"Service>responsibleParty>ContactInfo>Address>City correctly parsed\");\n        t.eq(address.country, \"Luxembourg\", \"Service>responsibleParty>ContactInfo>Address>Country correctly parsed\");\n        t.eq(address.deliveryPoint, \"66, rue de Luxembourg\", \"Service>responsibleParty>ContactInfo>Address>DeliveryPoint correctly parsed\");\n        t.eq(address.electronicMailAddress, \"flappy@tutones.com\", \"Service>responsibleParty>ContactInfo>Address>ElectronicMailAddress correctly parsed\");\n        t.eq(address.postalCode, \"97202\", \"Service>responsibleParty>ContactInfo>Address>PostalCode correctly parsed\");\n\n        var metadata = res1_0_0.contentMetadata[0];\n        t.eq(metadata.identifier, \"ro_dsm\", \"ContentMetadata>Name correctly parsed\");\n        t.eq(metadata.title, \"Rotterdam DSM\", \"ContentMetadata>Title correctly parsed\");\n        t.eq(metadata.lonLatEnvelope.min.x, 4.44444, \"ContentMetadata>lonLatEnvelope>Min>Lat correctly parsed\");\n        t.eq(metadata.lonLatEnvelope.min.y, 51.515151, \"ContentMetadata>lonLatEnvelope>Min>Lon correctly parsed\");\n        t.eq(metadata.lonLatEnvelope.max.x, 5.55555, \"ContentMetadata>lonLatEnvelope>Max>Lat correctly parsed\");\n        t.eq(metadata.lonLatEnvelope.max.y, 52.525252, \"ContentMetadata>lonLatEnvelope>Max>Lon correctly parsed\");\n        t.eq(metadata.lonLatEnvelope.srsName, \"urn:ogc:def:crs:OGC:1.3:CRS84\", \"ContentMetadata>lonLatEnvelope>SrsName correctly parsed\");\n        t.eq(res1_0_0.contentMetadata.length, 4, \"Correct number of metadata records found\");\n\n\n        // MapServer, v1.1.0\n        text = '<?xml version=\"1.0\" encoding=\"UTF-8\"?><Capabilities xmlns=\"http://www.opengis.net/wcs/1.1\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ogc=\"http://www.opengis.net/ogc\" version=\"1.1.0\" xsi:schemaLocation=\"http://www.opengis.net/wcs/1.1 http://schemas.opengis.net/wcs/1.1/wcsGetCapabilities.xsd http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsAll.xsd\"><ows:ServiceIdentification><ows:Title>MapServer WCS</ows:Title><ows:Abstract>This installation serves data for testing</ows:Abstract><ows:Keywords><ows:Keyword>Geospatial WebServices</ows:Keyword><ows:Keyword>Luxembourg!</ows:Keyword></ows:Keywords><ows:ServiceType codeSpace=\"OGC\">OGC WCS</ows:ServiceType><ows:ServiceTypeVersion>1.1.0</ows:ServiceTypeVersion><ows:Fees>mucho dinero</ows:Fees><ows:AccessConstraints>Open to the public</ows:AccessConstraints></ows:ServiceIdentification><ows:ServiceProvider><ows:ProviderName>CRP Henri Tudor</ows:ProviderName><ows:ProviderSite xlink:type=\"simple\" xlink:href=\"http://services.testorama.lu/cgi-bin/mapserv?map=/var/www/MapFiles/RO_localOWS_test.map&amp;\"/><ows:ServiceContact><ows:IndividualName>Leroy Dumerde</ows:IndividualName><ows:PositionName>R+D engineer</ows:PositionName><ows:ContactInfo><ows:Phone><ows:Voice>6463320</ows:Voice><ows:Facsimile>6465955</ows:Facsimile></ows:Phone><ows:Address><ows:DeliveryPoint>66, rue de Luxembourg</ows:DeliveryPoint><ows:City>Esch-sur-Alzette</ows:City><ows:AdministrativeArea/><ows:PostalCode>97202</ows:PostalCode><ows:Country>Luxembourg</ows:Country><ows:ElectronicMailAddress>flappy@tutones.com</ows:ElectronicMailAddress></ows:Address><ows:OnlineResource xlink:type=\"simple\" xlink:href=\"http://services.testorama.lu/cgi-bin/mapserv?map=/var/www/MapFiles/RO_localOWS_test.map&amp;\"/><ows:HoursOfService>24/7</ows:HoursOfService><ows:ContactInstructions>by phone</ows:ContactInstructions></ows:ContactInfo><ows:Role>GIS-Analyst</ows:Role></ows:ServiceContact></ows:ServiceProvider><ows:OperationsMetadata><ows:Operation name=\"GetCapabilities\"><ows:DCP><ows:HTTP><ows:Get xlink:type=\"simple\" xlink:href=\"http://services.testorama.lu/cgi-bin/mapserv?map=/var/www/MapFiles/RO_localOWS_test.map&amp;\"/><ows:Post xlink:type=\"simple\" xlink:href=\"http://services.testorama.lu/cgi-bin/mapserv?map=/var/www/MapFiles/RO_localOWS_test.map&amp;\"/></ows:HTTP></ows:DCP><ows:Parameter name=\"service\"><ows:AllowedValues><ows:Value>WCS</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name=\"version\"><ows:AllowedValues><ows:Value>1.1.0</ows:Value></ows:AllowedValues></ows:Parameter></ows:Operation><ows:Operation name=\"DescribeCoverage\"><ows:DCP><ows:HTTP><ows:Get xlink:type=\"simple\" xlink:href=\"http://services.testorama.lu/cgi-bin/mapserv?map=/var/www/MapFiles/RO_localOWS_test.map&amp;\"/><ows:Post xlink:type=\"simple\" xlink:href=\"http://services.testorama.lu/cgi-bin/mapserv?map=/var/www/MapFiles/RO_localOWS_test.map&amp;\"/></ows:HTTP></ows:DCP><ows:Parameter name=\"service\"><ows:AllowedValues><ows:Value>WCS</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name=\"version\"><ows:AllowedValues><ows:Value>1.1.0</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name=\"identifiers\"><ows:AllowedValues><ows:Value>ro_dsm</ows:Value><ows:Value>ro_dsm_mini</ows:Value><ows:Value>ro_irra</ows:Value><ows:Value>ro_irra_ext</ows:Value></ows:AllowedValues></ows:Parameter></ows:Operation><ows:Operation name=\"GetCoverage\"><ows:DCP><ows:HTTP><ows:Get xlink:type=\"simple\" xlink:href=\"http://services.testorama.lu/cgi-bin/mapserv?map=/var/www/MapFiles/RO_localOWS_test.map&amp;\"/><ows:Post xlink:type=\"simple\" xlink:href=\"http://services.testorama.lu/cgi-bin/mapserv?map=/var/www/MapFiles/RO_localOWS_test.map&amp;\"/></ows:HTTP></ows:DCP><ows:Parameter name=\"service\"><ows:AllowedValues><ows:Value>WCS</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name=\"version\"><ows:AllowedValues><ows:Value>1.1.0</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name=\"Identifier\"><ows:AllowedValues><ows:Value>ro_dsm</ows:Value><ows:Value>ro_dsm_mini</ows:Value><ows:Value>ro_irra</ows:Value><ows:Value>ro_irra_ext</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name=\"InterpolationType\"><ows:AllowedValues><ows:Value>NEAREST_NEIGHBOUR</ows:Value><ows:Value>BILINEAR</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name=\"format\"><ows:AllowedValues><ows:Value>image/tiff</ows:Value><ows:Value>image/png</ows:Value><ows:Value>image/jpeg</ows:Value><ows:Value>image/gif</ows:Value><ows:Value>image/png; mode=8bit</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name=\"store\"><ows:AllowedValues><ows:Value>false</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name=\"GridBaseCRS\"><ows:AllowedValues><ows:Value>urn:ogc:def:crs:epsg::4326</ows:Value></ows:AllowedValues></ows:Parameter></ows:Operation></ows:OperationsMetadata><Contents><CoverageSummary><ows:Title>Rotterdam DSM</ows:Title><ows:Abstract>Digital Surface Model (DSM) raster data set of inner city Rotterdam</ows:Abstract><ows:WGS84BoundingBox dimensions=\"2\"><ows:LowerCorner>4.471333734139 51.912813427383</ows:LowerCorner><ows:UpperCorner>4.4808508475645 51.9248713705576</ows:UpperCorner></ows:WGS84BoundingBox><SupportedCRS>urn:ogc:def:crs:EPSG::28992</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::900913</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::3857</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::4326</SupportedCRS><SupportedFormat>image/tiff</SupportedFormat><Identifier>ro_dsm</Identifier></CoverageSummary><CoverageSummary><ows:Title>Rotterdam sample DSM subset</ows:Title><ows:Abstract>This a test data set of Rotterdams DSM subset</ows:Abstract><ows:WGS84BoundingBox dimensions=\"2\"><ows:LowerCorner>4.47489346945755 51.9159453786927</ows:LowerCorner><ows:UpperCorner>4.47687824892444 51.9170706688033</ows:UpperCorner></ows:WGS84BoundingBox><SupportedCRS>urn:ogc:def:crs:EPSG::28992</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::900913</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::3857</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::4326</SupportedCRS><SupportedFormat>image/tiff</SupportedFormat><Identifier>ro_dsm_mini</Identifier></CoverageSummary><CoverageSummary><ows:Title>Rotterdam (Ljinbaan) solar irradiation data 2010</ows:Title><ows:Abstract>This a result data set of a solar computation of Ljinbaan area. It shows the sum of kWh/a per sqmeter for 2010</ows:Abstract><ows:WGS84BoundingBox dimensions=\"2\"><ows:LowerCorner>4.471333734139 51.912813427383</ows:LowerCorner><ows:UpperCorner>4.4808508475645 51.9248713705576</ows:UpperCorner></ows:WGS84BoundingBox><SupportedCRS>urn:ogc:def:crs:EPSG::28992</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::900913</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::3857</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::4326</SupportedCRS><SupportedFormat>image/tiff</SupportedFormat><Identifier>ro_irra</Identifier></CoverageSummary><CoverageSummary><ows:Title>Rotterdam (extended) solar irradiation data 2010</ows:Title><ows:Abstract>This a result data set of a solar computation of extended Rotterdam area. It shows the sum of kWh/a per sqmeter for 2010</ows:Abstract><ows:WGS84BoundingBox dimensions=\"2\"><ows:LowerCorner>4.10024171314823 51.9359764992844</ows:LowerCorner><ows:UpperCorner>4.21909054278063 52.001415228243</ows:UpperCorner></ows:WGS84BoundingBox><SupportedCRS>urn:ogc:def:crs:EPSG::28992</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::900913</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::3857</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::4326</SupportedCRS><SupportedFormat>image/tiff</SupportedFormat><Identifier>ro_irra_ext</Identifier></CoverageSummary></Contents></Capabilities>';\n\n        var res1_1_0 = parser.read(text);\n\n        // Most of the parsing is handled by other objects, so not much actually requires testing here\n        t.ok(!res1_1_0.error, \"Parsing XML generated no errors\");\n        t.eq(res1_1_0.contentMetadata.length, 4, \"number of features correct\");\n \n        var metadata = res1_1_0.contentMetadata[0];\n        t.eq(metadata.identifier, \"ro_dsm\", \"correct identifier\");\n        t.eq(metadata.title, \"Rotterdam DSM\", \"correct title\");\n        t.eq(metadata.abstract, \"Digital Surface Model (DSM) raster data set of inner city Rotterdam\", \"correct abstract\");\n        t.eq(metadata.supportedFormat.length, 1, \"correct number of supported formats\");\n        t.eq(metadata.supportedFormat[0], \"image/tiff\", \"correct format\");\n        t.eq(metadata.supportedCRS.length, 4, \"correct number of CRS records\");\n        t.eq(metadata.supportedCRS[2], \"urn:ogc:def:crs:EPSG::3857\", \"correct CRS\");\n\n        // Check for consistency between 1.0.0 and 1.1.0\n        t.eq(res1_0_0.serviceIdentification.fees, \n             res1_1_0.serviceIdentification.fees,\n                     \"serviceIdentification.fees matches between 1.0.0 and 1.1.0\");\n        t.eq(res1_0_0.serviceIdentification.accessConstraints, \n             res1_1_0.serviceIdentification.accessConstraints,\n                     \"serviceIdentification.accessConstraints matches between 1.0.0 and 1.1.0\");\n        t.eq(res1_0_0.serviceIdentification.title, \n             res1_1_0.serviceIdentification.title,\n                     \"serviceIdentification.title matches between 1.0.0 and 1.1.0\");\n        t.eq(res1_0_0.serviceIdentification.abstract, \n             res1_1_0.serviceIdentification.abstract,\n                     \"serviceIdentification.abstract matches between 1.0.0 and 1.1.0\");\n        t.eq(res1_0_0.serviceProvider.providerName, \n             res1_1_0.serviceProvider.providerName,\n                     \"serviceProvider.providerName matches between 1.0.0 and 1.1.0\");\n        t.eq(res1_0_0.serviceProvider.serviceContact.individualName, \n             res1_1_0.serviceProvider.serviceContact.individualName,\n                     \"serviceProvider.serviceContact.individualName matches between 1.0.0 and 1.1.0\");\n        t.eq(res1_0_0.serviceProvider.serviceContact.positionName, \n             res1_1_0.serviceProvider.serviceContact.positionName,\n                     \"serviceProvider.serviceContact.positionName matches between 1.0.0 and 1.1.0\");\n        t.eq(res1_0_0.serviceProvider.serviceContact.contactInfo.address.city, \n             res1_1_0.serviceProvider.serviceContact.contactInfo.address.city,\n                     \"serviceProvider.serviceContact.contactInfo.address.city matches between 1.0.0 and 1.1.0\");\n        t.eq(res1_0_0.serviceProvider.serviceContact.contactInfo.address.country, \n             res1_1_0.serviceProvider.serviceContact.contactInfo.address.country,\n                     \"serviceProvider.serviceContact.contactInfo.address.country matches between 1.0.0 and 1.1.0\");\n        t.eq(res1_0_0.serviceProvider.serviceContact.contactInfo.address.deliveryPoint, \n             res1_1_0.serviceProvider.serviceContact.contactInfo.address.deliveryPoint,\n                     \"serviceProvider.serviceContact.contactInfo.address.deliveryPoint matches between 1.0.0 and 1.1.0\");\n        t.eq(res1_0_0.serviceProvider.serviceContact.contactInfo.address.electronicMailAddress, \n             res1_1_0.serviceProvider.serviceContact.contactInfo.address.electronicMailAddress,\n                     \"serviceProvider.serviceContact.contactInfo.address.electronicMailAddress matches between 1.0.0 and 1.1.0\");\n        t.eq(res1_0_0.serviceProvider.serviceContact.contactInfo.address.postalCode, \n             res1_1_0.serviceProvider.serviceContact.contactInfo.address.postalCode,\n                     \"serviceProvider.serviceContact.contactInfo.address.postalCode matches between 1.0.0 and 1.1.0\");\n        t.eq(res1_0_0.serviceProvider.serviceContact.contactInfo.phone.facsimile, \n             res1_1_0.serviceProvider.serviceContact.contactInfo.phone.facsimile,\n                     \"serviceProvider.serviceContact.contactInfo.phone.facsimile matches between 1.0.0 and 1.1.0\");\n        t.eq(res1_0_0.serviceProvider.serviceContact.contactInfo.phone.voice, \n             res1_1_0.serviceProvider.serviceContact.contactInfo.phone.voice,\n                     \"serviceProvider.serviceContact.contactInfo.phone.voice matches between 1.0.0 and 1.1.0\");\n\n        // More consistency checks, but on the dataset level.  More detailed than this, we cannot really go, unfortunately.\n        t.eq(res1_0_0.contentMetadata[0].identifier, \n             res1_1_0.contentMetadata[0].identifier, \n                     \"contentMetadata[0].identifier matches between 1.0.0 and 1.1.0\");\n        t.eq(res1_0_0.contentMetadata[0].title, \n             res1_1_0.contentMetadata[0].title, \n                     \"contentMetadata[0].title matches between 1.0.0 and 1.1.0\");\n        t.eq(res1_0_0.contentMetadata.length, \n             res1_1_0.contentMetadata.length, \n                     \"contentMetadata.length matches between 1.0.0 and 1.1.0\");\n\n        t.eq(res1_0_0.serviceIdentification.keywords[0], \n             res1_1_0.serviceIdentification.keywords[0],\n                     \"serviceIdentification keyword 1 matches between 1.0.0 and 1.1.0\");\n        t.eq(res1_0_0.serviceIdentification.keywords[1], \n             res1_1_0.serviceIdentification.keywords[1],\n                     \"serviceIdentification keyword 2 matches between 1.0.0 and 1.1.0\");\n        t.eq(res1_0_0.serviceIdentification.keywords.length, \n             res1_1_0.serviceIdentification.keywords.length,\n                     \"serviceIdentification keyword count matches between 1.0.0 and 1.1.0\");\n    }\n\n    </script> \n</head> \n<body> </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WCSCapabilities.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    \n    function test_read(t) {\n        t.plan(4);\n\n        var parser = new OpenLayers.Format.WCSCapabilities();\n\n        // version 1.0.0\n\n        // Save original reader\n        var _v1_0_0 = OpenLayers.Format.WCSCapabilities.v1_0_0.prototype.read;\n\n        OpenLayers.Format.WCSCapabilities.v1_0_0.prototype.read = function() {\n            t.ok(true, \"Version 1.0.0 detected\");\n            return {};\n        }\n        \n        var text =\n            '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n            '<WCS_Capabilities version=\"1.0.0\" xmlns:wcs=\"http://www.opengis.net/wcs\"></WCS_Capabilities>';\n        var res = parser.read(text);\n        t.eq(res.version, \"1.0.0\", \"version 1.0.0 written to result object\");\n        \n        // Restore original reader\n        OpenLayers.Format.WCSCapabilities.v1_0_0.prototype.read = _v1_0_0;\n\n\n        // version 1.1.0\n\n        // Save original reader\n        var _v1_1_0 = OpenLayers.Format.WCSCapabilities.v1_1_0.prototype.read;\n\n        OpenLayers.Format.WCSCapabilities.v1_1_0.prototype.read = function() {\n            t.ok(true, \"Version 1.1.0 detected\");\n            return {};\n        }\n\n        var text =\n            '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n            '<Capabilities version=\"1.1.0\" xmlns:wcs=\"http://www.opengis.net/wcs/1.1\"></Capabilities>';\n        var res = parser.read(text);\n        t.eq(res.version, \"1.1.0\", \"version 1.1.0 written to result object\");\n\n        // Restore original reader\n        OpenLayers.Format.WCSCapabilities.v1_1_0.prototype.read = _v1_1_0;\n    }\n\n    </script> \n</head> \n<body>\n</body> \n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WCSDescribeCoverage/v1.html",
    "content": "<html> \n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_read_exception(t) {\n        t.plan(1);\n        var parser = new OpenLayers.Format.WCSDescribeCoverage();\n        var text = '<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>' +\n                    '<ows:ExceptionReport xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" version=\"1.1.0\" xml:lang=\"en-US\" xsi:schemaLocation=\"http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsExceptionReport.xsd\">' +\n                      '<ows:Exception exceptionCode=\"CoverageNotDefined\" locator=\"coverage\">' +\n                        '<ows:ExceptionText>msWCSDescribeCoverage(): WCS server error. COVERAGE blahblah cannot be opened / does not exist</ows:ExceptionText>' +\n                      '</ows:Exception>' +\n                    '</ows:ExceptionReport>';\n        var obj = parser.read(text);\n        t.ok(!!obj.error, \"Error reported correctly\");      // The above should place an error in obj.error\n    }\n    \n    function test_read(t) {\n        t.plan(84);     // Number of tests performed: If you add a test below, be sure to increment this accordingly\n       \n        var parser = new OpenLayers.Format.WCSDescribeCoverage();\n\n        // MapServer, v1.0.0\n        var text = '<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><CoverageDescription version=\"1.0.0\" updateSequence=\"0\" xmlns=\"http://www.opengis.net/wcs\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/wcs http://schemas.opengis.net/wcs/1.0.0/describeCoverage.xsd\"><CoverageOffering><name>ro_dsm</name><label>RO DSM</label><lonLatEnvelope srsName=\"urn:ogc:def:crs:OGC:1.3:CRS84\"><gml:pos>4.471333734139 51.912813427383</gml:pos><gml:pos>4.4808508475645 51.9248713705576</gml:pos></lonLatEnvelope><domainSet><spatialDomain><gml:Envelope srsName=\"EPSG:4326\"><gml:pos>4.471333734139 51.912813427383</gml:pos><gml:pos>4.4808508475645 51.9248713705576</gml:pos></gml:Envelope><gml:Envelope srsName=\"EPSG:28992\"><gml:pos>91979 437659.5</gml:pos><gml:pos>92617 436326</gml:pos></gml:Envelope><gml:RectifiedGrid dimension=\"2\"><gml:limits><gml:GridEnvelope><gml:low>0 0</gml:low><gml:high>1275 2666</gml:high></gml:GridEnvelope></gml:limits><gml:axisName>x</gml:axisName><gml:axisName>y</gml:axisName><gml:origin><gml:pos>91979 437659.5</gml:pos></gml:origin><gml:offsetVector>0.5 0</gml:offsetVector><gml:offsetVector>0 -0.5</gml:offsetVector></gml:RectifiedGrid></spatialDomain></domainSet><rangeSet><RangeSet><name>Range 1</name><label>My Label</label></RangeSet></rangeSet><supportedCRSs><requestResponseCRSs>EPSG:28992</requestResponseCRSs><requestResponseCRSs>EPSG:900913</requestResponseCRSs><requestResponseCRSs>EPSG:3857</requestResponseCRSs><requestResponseCRSs>EPSG:4326</requestResponseCRSs><nativeCRSs>EPSG:28992</nativeCRSs></supportedCRSs><supportedFormats><formats>GTiff</formats></supportedFormats><supportedInterpolations default=\"nearest neighbor\"><interpolationMethod>nearest neighbor</interpolationMethod><interpolationMethod>bilinear</interpolationMethod></supportedInterpolations></CoverageOffering><CoverageOffering><name>ro_dsm_mini</name><label>ro_dsm_mini</label><lonLatEnvelope srsName=\"urn:ogc:def:crs:OGC:1.3:CRS84\"><gml:pos>4.47489346945755 51.9159453786927</gml:pos><gml:pos>4.47687824892444 51.9170706688033</gml:pos></lonLatEnvelope><domainSet><spatialDomain><gml:Envelope srsName=\"EPSG:4326\"><gml:pos>4.47489346945755 51.9159453786927</gml:pos><gml:pos>4.47687824892444 51.9170706688033</gml:pos></gml:Envelope><gml:Envelope srsName=\"EPSG:28992\"><gml:pos>92213 436671.5</gml:pos><gml:pos>92348 436795</gml:pos></gml:Envelope><gml:RectifiedGrid dimension=\"2\"><gml:limits><gml:GridEnvelope><gml:low>0 0</gml:low><gml:high>269 246</gml:high></gml:GridEnvelope></gml:limits><gml:axisName>x</gml:axisName><gml:axisName>y</gml:axisName><gml:origin><gml:pos>92213 436795</gml:pos></gml:origin><gml:offsetVector>0.5 0</gml:offsetVector><gml:offsetVector>0 -0.5</gml:offsetVector></gml:RectifiedGrid></spatialDomain></domainSet><rangeSet><RangeSet><name>Range 1</name><label>My Label</label></RangeSet></rangeSet><supportedCRSs><requestResponseCRSs>EPSG:28992</requestResponseCRSs><requestResponseCRSs>EPSG:900913</requestResponseCRSs><requestResponseCRSs>EPSG:3857</requestResponseCRSs><requestResponseCRSs>EPSG:4326</requestResponseCRSs><nativeCRSs>EPSG:28992</nativeCRSs></supportedCRSs><supportedFormats><formats>GTiff</formats></supportedFormats><supportedInterpolations default=\"nearest neighbor\"><interpolationMethod>nearest neighbor</interpolationMethod><interpolationMethod>bilinear</interpolationMethod></supportedInterpolations></CoverageOffering><CoverageOffering><name>ro_irra</name><label>ro_irra</label><lonLatEnvelope srsName=\"urn:ogc:def:crs:OGC:1.3:CRS84\"><gml:pos>4.471333734139 51.912813427383</gml:pos><gml:pos>4.4808508475645 51.9248713705576</gml:pos></lonLatEnvelope><domainSet><spatialDomain><gml:Envelope srsName=\"EPSG:4326\"><gml:pos>4.471333734139 51.912813427383</gml:pos><gml:pos>4.4808508475645 51.9248713705576</gml:pos></gml:Envelope><gml:Envelope srsName=\"EPSG:28992\"><gml:pos>91979 437659.5</gml:pos><gml:pos>92617 436326</gml:pos></gml:Envelope><gml:RectifiedGrid dimension=\"2\"><gml:limits><gml:GridEnvelope><gml:low>0 0</gml:low><gml:high>1275 2666</gml:high></gml:GridEnvelope></gml:limits><gml:axisName>x</gml:axisName><gml:axisName>y</gml:axisName><gml:origin><gml:pos>91979 437659.5</gml:pos></gml:origin><gml:offsetVector>0.5 0</gml:offsetVector><gml:offsetVector>0 -0.5</gml:offsetVector></gml:RectifiedGrid></spatialDomain></domainSet><rangeSet><RangeSet><name>Range 1</name><label>My Label</label></RangeSet></rangeSet><supportedCRSs><requestResponseCRSs>EPSG:28992</requestResponseCRSs><requestResponseCRSs>EPSG:900913</requestResponseCRSs><requestResponseCRSs>EPSG:3857</requestResponseCRSs><requestResponseCRSs>EPSG:4326</requestResponseCRSs><nativeCRSs>EPSG:28992</nativeCRSs></supportedCRSs><supportedFormats><formats>GTiff</formats></supportedFormats><supportedInterpolations default=\"nearest neighbor\"><interpolationMethod>nearest neighbor</interpolationMethod><interpolationMethod>bilinear</interpolationMethod></supportedInterpolations></CoverageOffering><CoverageOffering><name>ro_irra_ext</name><label>ro_irra_ext</label><lonLatEnvelope srsName=\"urn:ogc:def:crs:OGC:1.3:CRS84\"><gml:pos>4.10024171314823 51.9359764992844</gml:pos><gml:pos>4.21909054278063 52.001415228243</gml:pos></lonLatEnvelope><domainSet><spatialDomain><gml:Envelope srsName=\"EPSG:4326\"><gml:pos>4.10024171314823 51.9359764992844</gml:pos><gml:pos>4.21909054278063 52.001415228243</gml:pos></gml:Envelope><gml:Envelope srsName=\"EPSG:28992\"><gml:pos>66606.5 439287.5</gml:pos><gml:pos>74653.5 446432.5</gml:pos></gml:Envelope><gml:RectifiedGrid dimension=\"2\"><gml:limits><gml:GridEnvelope><gml:low>0 0</gml:low><gml:high>16093 14289</gml:high></gml:GridEnvelope></gml:limits><gml:axisName>x</gml:axisName><gml:axisName>y</gml:axisName><gml:origin><gml:pos>66606.5 446432.5</gml:pos></gml:origin><gml:offsetVector>0.5 0</gml:offsetVector><gml:offsetVector>0 -0.5</gml:offsetVector></gml:RectifiedGrid></spatialDomain></domainSet><rangeSet><RangeSet><name>Range 1</name><label>My Label</label></RangeSet></rangeSet><supportedCRSs><requestResponseCRSs>EPSG:28992</requestResponseCRSs><requestResponseCRSs>EPSG:900913</requestResponseCRSs><requestResponseCRSs>EPSG:3857</requestResponseCRSs><requestResponseCRSs>EPSG:4326</requestResponseCRSs><nativeCRSs>EPSG:28992</nativeCRSs></supportedCRSs><supportedFormats><formats>GTiff</formats></supportedFormats><supportedInterpolations default=\"nearest neighbor\"><interpolationMethod>nearest neighbor</interpolationMethod><interpolationMethod>bilinear</interpolationMethod></supportedInterpolations></CoverageOffering></CoverageDescription>'; \n\n        var res1_0_0 = parser.read(text);\n\n        t.ok(!res1_0_0.error, \"Parsing XML generated no errors\");\n\n        var count = 0;\n        for (var k in res1_0_0.coverageDescriptions) {\n            if (res1_0_0.coverageDescriptions.hasOwnProperty(k)) {\n               count++;\n            }\n        }\n\n        t.eq(count, 4, \"number of coverages correct\");\n        t.eq(res1_0_0.coverageDescriptionKeys.length, 4, \"number of coverage keys correct\");\n        t.eq(res1_0_0.version, \"1.0.0\", \"version correct\");\n\n        var metadata = res1_0_0.coverageDescriptions.ro_dsm;\n\n        t.eq(metadata.identifier, \"ro_dsm\", \"correct identifier\");\n        t.eq(metadata.title, \"RO DSM\", \"correct title\");\n        t.eq(metadata.supportedCRSs.length, 4, \"correct number of supported CRSs\");\n        t.eq(metadata.supportedCRSs[3], \"EPSG:4326\", \"correct value for selected supported CRS\");\n\n        t.eq(metadata.supportedFormats.length, 1, \"correct number of supported formats\");\n        t.eq(metadata.supportedFormats[0], \"GTiff\", \"correct value for supported format\");\n\n        var lonLatEnvelope = metadata.lonLatEnvelope;\n\n        t.eq(lonLatEnvelope.min.x, 4.471333734139, \"correct lonLatEnvelope.min.x\");\n        t.eq(lonLatEnvelope.min.y, 51.912813427383, \"correct lonLatEnvelope.min.y\");\n        t.eq(lonLatEnvelope.max.x, 4.4808508475645, \"correct lonLatEnvelope.max.x\");\n        t.eq(lonLatEnvelope.max.y, 51.9248713705576, \"correct lonLatEnvelope.max.y\");\n        t.eq(lonLatEnvelope.srsName, \"urn:ogc:def:crs:OGC:1.3:CRS84\", \"correct lonLatEnvelope.srsName\");\n\n        var nativeCRSs = metadata.supportedCRSs.nativeCRSs;\n        t.eq(nativeCRSs.length, 1, \"correct number of supported CRSs\");\n        t.eq(nativeCRSs[0], \"EPSG:28992\", \"correct sample native CRS\");\n\n        var supportedCRSs = metadata.supportedCRSs;\n        t.eq(supportedCRSs.length, 4, \"correct number of native CRSs\");\n        t.eq(supportedCRSs[3], \"EPSG:4326\", \"correct sample supported CRS\");\n\n        t.eq(metadata.nativeCRS, \"EPSG:28992\", \"correct native CRS\");\n\n        var nativeBB = metadata.domain.spatialDomain.boundingBoxes[metadata.nativeCRS];\n        t.ok(!!nativeBB, \"found native bounding box\");\n        t.eq(nativeBB.top,    436326,   \"correct native bounding box top value\");\n        t.eq(nativeBB.bottom, 437659.5, \"correct native bounding box bottom value\");\n        t.eq(nativeBB.left,   91979,    \"correct native bounding box left value\");\n        t.eq(nativeBB.right,  92617,    \"correct native bounding box right value\");\n\n\n        // MapServer, v1.1.0\n        text = '<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?><CoverageDescriptions xmlns=\"http://www.opengis.net/wcs/1.1\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ogc=\"http://www.opengis.net/ogc\" xsi:schemaLocation=\"http://www.opengis.net/wcs/1.1 http://schemas.opengis.net/wcs/1.1/wcsDescribeCoverage.xsd http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsAll.xsd\"><CoverageDescription><ows:Title>RO DSM</ows:Title><ows:Abstract>Digital Surface Model (DSM) raster data set of inner city Rotterdam</ows:Abstract><Identifier>ro_dsm</Identifier><Domain><SpatialDomain><ows:BoundingBox crs=\"urn:ogc:def:crs:OGC::imageCRS\" dimensions=\"2\"><ows:LowerCorner>0 0</ows:LowerCorner><ows:UpperCorner>1275 2666</ows:UpperCorner></ows:BoundingBox><ows:BoundingBox crs=\"urn:ogc:def:crs:EPSG::28992\" dimensions=\"2\"><ows:LowerCorner>91979 437659.5</ows:LowerCorner><ows:UpperCorner>92617 436326</ows:UpperCorner></ows:BoundingBox><ows:WGS84BoundingBox dimensions=\"2\"><ows:LowerCorner>4.471333734139 51.912813427383</ows:LowerCorner><ows:UpperCorner>4.4808508475645 51.9248713705576</ows:UpperCorner></ows:WGS84BoundingBox><GridCRS><GridBaseCRS>urn:ogc:def:crs:EPSG::28992</GridBaseCRS><GridType>urn:ogc:def:method:WCS:1.1:2dSimpleGrid</GridType><GridOrigin>91979.25 437659.25</GridOrigin><GridOffsets>0.5 -0.5</GridOffsets><GridCS>urn:ogc:def:cs:OGC:0.0:Grid2dSquareCS</GridCS></GridCRS></SpatialDomain></Domain><Range><Field><ows:Title>My Label</ows:Title><Identifier>Range 1</Identifier><Definition><ows:AnyValue/></Definition><InterpolationMethods><InterpolationMethod>bilinear</InterpolationMethod><Default>nearest neighbor</Default></InterpolationMethods><Axis identifier=\"bands\"><AvailableKeys><Key>1</Key></AvailableKeys></Axis></Field></Range><SupportedCRS>urn:ogc:def:crs:EPSG::28992</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::900913</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::3857</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::4326</SupportedCRS><SupportedFormat>image/tiff</SupportedFormat></CoverageDescription><CoverageDescription><ows:Title>ro_dsm_mini</ows:Title><ows:Abstract>This a test data set of Rotterdams DSM subset</ows:Abstract><Identifier>ro_dsm_mini</Identifier><Domain><SpatialDomain><ows:BoundingBox crs=\"urn:ogc:def:crs:OGC::imageCRS\" dimensions=\"2\"><ows:LowerCorner>0 0</ows:LowerCorner><ows:UpperCorner>269 246</ows:UpperCorner></ows:BoundingBox><ows:BoundingBox crs=\"urn:ogc:def:crs:EPSG::28992\" dimensions=\"2\"><ows:LowerCorner>92213 436671.5</ows:LowerCorner><ows:UpperCorner>92348 436795</ows:UpperCorner></ows:BoundingBox><ows:WGS84BoundingBox dimensions=\"2\"><ows:LowerCorner>4.47489346945755 51.9159453786927</ows:LowerCorner><ows:UpperCorner>4.47687824892444 51.9170706688033</ows:UpperCorner></ows:WGS84BoundingBox><GridCRS><GridBaseCRS>urn:ogc:def:crs:EPSG::28992</GridBaseCRS><GridType>urn:ogc:def:method:WCS:1.1:2dSimpleGrid</GridType><GridOrigin>92213.25 436794.75</GridOrigin><GridOffsets>0.5 -0.5</GridOffsets><GridCS>urn:ogc:def:cs:OGC:0.0:Grid2dSquareCS</GridCS></GridCRS></SpatialDomain></Domain><Range><Field><ows:Title>My Label</ows:Title><Identifier>Range 1</Identifier><Definition><ows:AnyValue/></Definition><InterpolationMethods><InterpolationMethod>bilinear</InterpolationMethod><Default>nearest neighbor</Default></InterpolationMethods><Axis identifier=\"bands\"><AvailableKeys><Key>1</Key></AvailableKeys></Axis></Field></Range><SupportedCRS>urn:ogc:def:crs:EPSG::28992</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::900913</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::3857</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::4326</SupportedCRS><SupportedFormat>image/tiff</SupportedFormat></CoverageDescription><CoverageDescription><ows:Title>ro_irra</ows:Title><ows:Abstract>This a result data set of a solar computation of Ljinbaan area. It shows the sum of kWh/a per sqmeter for 2010</ows:Abstract><Identifier>ro_irra</Identifier><Domain><SpatialDomain><ows:BoundingBox crs=\"urn:ogc:def:crs:OGC::imageCRS\" dimensions=\"2\"><ows:LowerCorner>0 0</ows:LowerCorner><ows:UpperCorner>1275 2666</ows:UpperCorner></ows:BoundingBox><ows:BoundingBox crs=\"urn:ogc:def:crs:EPSG::28992\" dimensions=\"2\"><ows:LowerCorner>91979 437659.5</ows:LowerCorner><ows:UpperCorner>92617 436326</ows:UpperCorner></ows:BoundingBox><ows:WGS84BoundingBox dimensions=\"2\"><ows:LowerCorner>4.471333734139 51.912813427383</ows:LowerCorner><ows:UpperCorner>4.4808508475645 51.9248713705576</ows:UpperCorner></ows:WGS84BoundingBox><GridCRS><GridBaseCRS>urn:ogc:def:crs:EPSG::28992</GridBaseCRS><GridType>urn:ogc:def:method:WCS:1.1:2dSimpleGrid</GridType><GridOrigin>91979.25 437659.25</GridOrigin><GridOffsets>0.5 -0.5</GridOffsets><GridCS>urn:ogc:def:cs:OGC:0.0:Grid2dSquareCS</GridCS></GridCRS></SpatialDomain></Domain><Range><Field><ows:Title>My Label</ows:Title><Identifier>Range 1</Identifier><Definition><ows:AnyValue/></Definition><InterpolationMethods><InterpolationMethod>bilinear</InterpolationMethod><Default>nearest neighbor</Default></InterpolationMethods><Axis identifier=\"bands\"><AvailableKeys><Key>1</Key></AvailableKeys></Axis></Field></Range><SupportedCRS>urn:ogc:def:crs:EPSG::28992</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::900913</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::3857</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::4326</SupportedCRS><SupportedFormat>image/tiff</SupportedFormat></CoverageDescription><CoverageDescription><ows:Title>ro_irra_ext</ows:Title><ows:Abstract>This a result data set of a solar computation of extended Rotterdam area. It shows the sum of kWh/a per sqmeter for 2010</ows:Abstract><Identifier>ro_irra_ext</Identifier><Domain><SpatialDomain><ows:BoundingBox crs=\"urn:ogc:def:crs:OGC::imageCRS\" dimensions=\"2\"><ows:LowerCorner>0 0</ows:LowerCorner><ows:UpperCorner>16093 14289</ows:UpperCorner></ows:BoundingBox><ows:BoundingBox crs=\"urn:ogc:def:crs:EPSG::28992\" dimensions=\"2\"><ows:LowerCorner>66606.5 439287.5</ows:LowerCorner><ows:UpperCorner>74653.5 446432.5</ows:UpperCorner></ows:BoundingBox><ows:WGS84BoundingBox dimensions=\"2\"><ows:LowerCorner>4.10024171314823 51.9359764992844</ows:LowerCorner><ows:UpperCorner>4.21909054278063 52.001415228243</ows:UpperCorner></ows:WGS84BoundingBox><GridCRS><GridBaseCRS>urn:ogc:def:crs:EPSG::28992</GridBaseCRS><GridType>urn:ogc:def:method:WCS:1.1:2dSimpleGrid</GridType><GridOrigin>66606.75 446432.25</GridOrigin><GridOffsets>0.5 -0.5</GridOffsets><GridCS>urn:ogc:def:cs:OGC:0.0:Grid2dSquareCS</GridCS></GridCRS></SpatialDomain></Domain><Range><Field><ows:Title>My Label</ows:Title><Identifier>Range 1</Identifier><Definition><ows:AnyValue/></Definition><InterpolationMethods><InterpolationMethod>bilinear</InterpolationMethod><Default>nearest neighbor</Default></InterpolationMethods><Axis identifier=\"bands\"><AvailableKeys><Key>1</Key></AvailableKeys></Axis></Field></Range><SupportedCRS>urn:ogc:def:crs:EPSG::28992</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::900913</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::3857</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::4326</SupportedCRS><SupportedFormat>image/tiff</SupportedFormat></CoverageDescription></CoverageDescriptions>';\n\n        res1_1_0 = parser.read(text);\n\n        // Most of the parsing is handled by other objects, so not much actually requires testing here\n        t.ok(!res1_1_0.error, \"Parsing XML generated no errors\");\n\n        var count = 0;\n        for (var k in res1_1_0.coverageDescriptions) {\n            if (res1_1_0.coverageDescriptions.hasOwnProperty(k)) {\n               count++;\n            }\n        }\n\n        t.eq(count, 4, \"number of coverages correct\");\n        t.eq(res1_1_0.coverageDescriptionKeys.length, 4, \"number of coverage keys correct\");\n        t.eq(res1_1_0.version, \"1.1.0\", \"version correct\");\n\n        var metadata = res1_1_0.coverageDescriptions.ro_dsm;\n\n        t.eq(metadata.identifier, \"ro_dsm\", \"correct identifier\");\n        t.eq(metadata.title, \"RO DSM\", \"correct title\");\n        t.eq(metadata.abstract, \"Digital Surface Model (DSM) raster data set of inner city Rotterdam\", \"correct abstract\");\n        t.eq(metadata.supportedCRSs.length, 4, \"correct number of supported CRSs\");\n        t.eq(metadata.supportedCRSs[3], \"urn:ogc:def:crs:EPSG::4326\", \"correct value for first supported CRS\");\n        t.eq(metadata.supportedFormats.length, 1, \"correct number of supported formats\");\n        t.eq(metadata.supportedFormats[0], \"image/tiff\", \"correct value for first supported format\");\n\n        var gridCRS = metadata.domain.spatialDomain.gridCRS;\n        t.eq(gridCRS.gridBaseCRS, \"urn:ogc:def:crs:EPSG::28992\", \"correct gridBaseCRS\");\n        t.eq(gridCRS.gridCS, \"urn:ogc:def:cs:OGC:0.0:Grid2dSquareCS\", \"correct gridCS\");\n        t.eq(gridCRS.gridOffsets.x,  0.5, \"correct gridOffsets.x\");\n        t.eq(gridCRS.gridOffsets.y, -0.5, \"correct gridOffsets.y\");\n        t.eq(gridCRS.gridOrigin.x, 91979.25, \"correct gridOrigin.x\");\n        t.eq(gridCRS.gridOrigin.y, 437659.25, \"correct gridOrigin.y\");\n        t.eq(gridCRS.gridType, \"urn:ogc:def:method:WCS:1.1:2dSimpleGrid\", \"correct gridType\");\n\n        t.eq(metadata.nativeCRS, \"urn:ogc:def:crs:EPSG::28992\", \"correct native CRS\");\n\n        var nativeBB = metadata.domain.spatialDomain.boundingBoxes[metadata.nativeCRS];\n        t.ok(!!nativeBB, \"found native bounding box\");\n        t.eq(nativeBB.top,    436326,   \"correct native bounding box top value\");\n        t.eq(nativeBB.bottom, 437659.5, \"correct native bounding box bottom value\");\n        t.eq(nativeBB.left,   91979,    \"correct native bounding box left value\");\n        t.eq(nativeBB.right,  92617,    \"correct native bounding box right value\");\n\n        t.eq(metadata.supportedFormats.length, 1, \"correct number of supported formats\");\n        t.eq(metadata.supportedFormats[0], \"image/tiff\", \"correct initial supported format value\");\n\n        // Check consistency between 1.0.0 and 1.1.0\n        t.eq(res1_0_0.coverageDescriptions.ro_dsm.identifier, res1_1_0.coverageDescriptions.ro_dsm.identifier, \"1.0.0 and 1.1.0 have same identifier\");\n        t.eq(res1_0_0.coverageDescriptions.ro_dsm.title, res1_1_0.coverageDescriptions.ro_dsm.title, \"1.0.0 and 1.1.0 have same title\");\n        // Actual supported formats will be expressed differently (image/tiff v GTiff), so we can't easily compare directly\n        t.eq(res1_0_0.coverageDescriptions.ro_dsm.supportedFormats.length, \n             res1_1_0.coverageDescriptions.ro_dsm.supportedFormats.length, \n             \"1.0.0 and 1.1.0 have same supportedFormats.length\");\n\n        // Use substr here to account for differing CRS formats\n        t.eq(res1_0_0.coverageDescriptions.ro_dsm.nativeCRS.substr(-5),    // EPSG:28992\n             res1_1_0.coverageDescriptions.ro_dsm.nativeCRS.substr(-5),    // urn:ogc:def:crs:EPSG::28992\n             \"1.0.0 and 1.1.0 have same native crs\");\n        t.eq(res1_0_0.coverageDescriptions.ro_dsm.domain.spatialDomain.boundingBoxes[res1_0_0.coverageDescriptions.ro_dsm.nativeCRS].top, \n             res1_1_0.coverageDescriptions.ro_dsm.domain.spatialDomain.boundingBoxes[res1_1_0.coverageDescriptions.ro_dsm.nativeCRS].top, \n             \"1.0.0 and 1.1.0 have same native bounding box top coordinate\");\n        t.eq(res1_0_0.coverageDescriptions.ro_dsm.domain.spatialDomain.boundingBoxes[res1_0_0.coverageDescriptions.ro_dsm.nativeCRS].bottom, \n             res1_1_0.coverageDescriptions.ro_dsm.domain.spatialDomain.boundingBoxes[res1_1_0.coverageDescriptions.ro_dsm.nativeCRS].bottom, \n             \"1.0.0 and 1.1.0 have same native bounding box bottom coordinate\");\n        t.eq(res1_0_0.coverageDescriptions.ro_dsm.domain.spatialDomain.boundingBoxes[res1_0_0.coverageDescriptions.ro_dsm.nativeCRS].left, \n             res1_1_0.coverageDescriptions.ro_dsm.domain.spatialDomain.boundingBoxes[res1_1_0.coverageDescriptions.ro_dsm.nativeCRS].left, \n             \"1.0.0 and 1.1.0 have same native bounding box left coordinate\");\n        t.eq(res1_0_0.coverageDescriptions.ro_dsm.domain.spatialDomain.boundingBoxes[res1_0_0.coverageDescriptions.ro_dsm.nativeCRS].right, \n             res1_1_0.coverageDescriptions.ro_dsm.domain.spatialDomain.boundingBoxes[res1_1_0.coverageDescriptions.ro_dsm.nativeCRS].right, \n             \"1.0.0 and 1.1.0 have same native bounding box right coordinate\");\n\n\n         // ArcGIS Server WCS DescribeCoverage, v1.1.0\n        text = '<CoverageDescriptions xmlns=\"http://www.opengis.net/wcs/1.1\" xmlns:ows=\"http://www.opengis.net/ows\" xmlns:owcs=\"http://www.opengis.net/wcs/1.1/ows\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:gml=\"http://www.opengis.net/gml\" xsi:schemaLocation=\"http://www.opengis.net/wcs/1.1 ../wcsDescribeCoverage.xsd http://www.opengis.net/wcs/1.1/ows ../owsDataIdentification.xsd\"><CoverageDescription><ows:Title>OSDATA.OS_25K_RASTER_1</ows:Title><ows:Abstract>Sample abstract</ows:Abstract><Identifier>1</Identifier><Domain><SpatialDomain><ows:BoundingBox crs=\"urn:ogc:def:crs:OGC::imageCRS\" dimension=\"2\"><ows:LowerCorner>0 0</ows:LowerCorner><ows:UpperCorner>16273 8848</ows:UpperCorner></ows:BoundingBox><ows:BoundingBox crs=\"urn:ogc:def:crs:EPSG::4326\"><ows:LowerCorner>-2.49 57.00</ows:LowerCorner><ows:UpperCorner>-2.00 57.27</ows:UpperCorner></ows:BoundingBox><GridCRS><GridBaseCRS>urn:ogc:def:crs:EPSG::4326</GridBaseCRS><GridOrigin>-2.4975072449484337 57.27084662228944</GridOrigin><GridOffsets>3.057015857620272e-005 -3.0570158576202496e-005</GridOffsets></GridCRS></SpatialDomain></Domain><Range><Field><Title>Field_1</Title><Abstract>Field_1</Abstract><Identifier>Field_1</Identifier><Definition><owcs:AnyValue/></Definition><NullValue>256</NullValue><NullValue>256</NullValue><NullValue>256</NullValue><owcs:InterpolationMethods><owcs:DefaultMethod>nearest</owcs:DefaultMethod><owcs:OtherMethod>bilinear</owcs:OtherMethod><owcs:OtherMethod>bicubic</owcs:OtherMethod></owcs:InterpolationMethods><Axis identifier=\"BAND\"><AvailableKeys><Key>1</Key><Key>2</Key><Key>3</Key></AvailableKeys><owcs:DataType>Byte</owcs:DataType></Axis></Field></Range><SupportedCRS>urn:ogc:def:crs:EPSG::4326</SupportedCRS><SupportedCRS>urn:ogc:def:crs:EPSG::9876</SupportedCRS><SupportedFormat>image/GeoTIFF</SupportedFormat><SupportedFormat>image/NITF</SupportedFormat><SupportedFormat>image/HDF</SupportedFormat><SupportedFormat>image/PNG</SupportedFormat></CoverageDescription></CoverageDescriptions>';\n\n        parser = new OpenLayers.Format.WCSDescribeCoverage();\n        var results = parser.read(text);\n\n        count = 0;\n        for (var k in results.coverageDescriptions) {\n            if (results.coverageDescriptions.hasOwnProperty(k)) {\n               count++;\n            }\n        }\n\n        t.eq(count, 1, \"number of coverages correct\");\n\n        t.eq(results.coverageDescriptionKeys.length, 1, \"number of coverage keys correct\");\n        t.eq(results.version, \"1.1.0\", \"version correct\");\n\n        var metadata = results.coverageDescriptions[\"1\"];\n\n        t.eq(metadata.identifier, \"1\", \"correct identifier\");\n        t.eq(metadata.title, \"OSDATA.OS_25K_RASTER_1\", \"correct title\");\n        t.eq(metadata.abstract, \"Sample abstract\", \"correct abstract\");\n\n        var supportedCRSs = metadata.supportedCRSs;\n        t.eq(supportedCRSs.length, 2, \"correct number of supported CRSs\");\n        t.eq(supportedCRSs[0], \"urn:ogc:def:crs:EPSG::4326\", \"correct value for selected supported CRS\");\n        t.eq(supportedCRSs[1], \"urn:ogc:def:crs:EPSG::9876\", \"correct value for selected supported CRS\");\n\n        t.eq(metadata.supportedFormats.length, 4, \"correct number of supported formats\");\n        t.eq(metadata.supportedFormats[0], \"image/GeoTIFF\", \"correct value for supported format\");\n        t.eq(metadata.supportedFormats[1], \"image/NITF\", \"correct value for supported format\");\n\n        t.eq(metadata.nativeCRS, \"urn:ogc:def:crs:EPSG::4326\", \"correct native CRS\");\n\n        var nativeBB = metadata.domain.spatialDomain.boundingBoxes[metadata.nativeCRS];\n        t.ok(!!nativeBB, \"found native bounding box\");\n        t.eq(nativeBB.top,    57.27, \"correct native bounding box top value\");\n        t.eq(nativeBB.bottom, 57.00, \"correct native bounding box bottom value\");\n        t.eq(nativeBB.left,   -2.49, \"correct native bounding box left value\");\n        t.eq(nativeBB.right,  -2.00, \"correct native bounding box right value\");\n\n\n        var gridCRS = metadata.domain.spatialDomain.gridCRS;\n        t.eq(gridCRS.gridBaseCRS, \"urn:ogc:def:crs:EPSG::4326\", \"correct gridBaseCRS\");\n        t.eq(gridCRS.gridCS, undefined, \"no gridCS specified\");\n        t.eq(gridCRS.gridOffsets.x,  3.057015857620272e-005, \"correct gridOffsets.x\");\n        t.eq(gridCRS.gridOffsets.y, -3.0570158576202496e-005, \"correct gridOffsets.y\");\n        t.eq(gridCRS.gridOrigin.x, -2.4975072449484337, \"correct gridOrigin.x\");\n        t.eq(gridCRS.gridOrigin.y, 57.27084662228944, \"correct gridOrigin.y\");\n        t.eq(gridCRS.gridType, undefined, \"no gird type specified\");\n \n    }\n\n    </script> \n</head> \n<body> </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WCSDescribeCoverage.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    \n    function test_read(t) {\n        t.plan(2);\n\n        var parser = new OpenLayers.Format.WCSDescribeCoverage();\n\n        // Save original reader\n        var _v1_1_0 = OpenLayers.Format.WCSDescribeCoverage.v1_1_0.prototype.read;\n\n        OpenLayers.Format.WCSDescribeCoverage.v1_1_0.prototype.read = function() {\n            t.ok(true, \"Version 1.1.0 detected\");\n            return {};\n        }\n\n        var text =\n            '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n            '<CoverageDescriptions xmlns=\"http://www.opengis.net/wcs/1.1\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ogc=\"http://www.opengis.net/ogc\" xsi:schemaLocation=\"http://www.opengis.net/wcs/1.1 http://schemas.opengis.net/wcs/1.1/wcsDescribeCoverage.xsd http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsAll.xsd\">';\n\n        var res = parser.read(text);\n        t.eq(res.version, \"1.1.0\", \"version 1.1.0 written to result object\");\n\n        // Restore original reader\n        OpenLayers.Format.WCSDescribeCoverage.v1_1_0.prototype.read = _v1_1_0;\n    }\n\n    </script> \n</head> \n<body>\n</body> \n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WCSGetCoverage.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_write_WCSGetCoverage(t) {\n        t.plan(1);\n        var expected = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n'<GetCoverage xmlns=\"http://www.opengis.net/wcs/1.1\" xmlns:ows=\"http://www.opengis.net/ows/1.1\"' +\n'    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"' +\n'    xsi:schemaLocation=\"http://www.opengis.net/wcs/1.1 http://schemas.opengis.net/wcs/1.1/wcsGetCoverage.xsd\"' +\n'    service=\"WCS\" version=\"1.1.2\">' +\n'    <ows:Identifier>Cov123</ows:Identifier>' +\n'    <DomainSubset>' +\n'        <ows:BoundingBox crs=\"urn:ogc:def:crs:OGC:2:84\">' +\n'            <ows:LowerCorner>-71 47</ows:LowerCorner>' +\n'            <ows:UpperCorner>-66 51</ows:UpperCorner>' +\n'        </ows:BoundingBox>' +\n'        <TemporalSubset>' +\n'            <TimePeriod>' +\n'                <BeginPosition>2006-08-01</BeginPosition>' +\n'                <EndPosition>2006-09-01</EndPosition>' +\n'                <TimeResolution>P1D</TimeResolution>' +\n'            </TimePeriod>' +\n'            <TimePeriod>' +\n'                <BeginPosition>2007-08-01</BeginPosition>' +\n'                <EndPosition>2007-09-01</EndPosition>' +\n'                <TimeResolution>P1D</TimeResolution>' +\n'            </TimePeriod>' +\n'        </TemporalSubset>' +\n'    </DomainSubset>' +\n'    <Output format=\"image/netcdf\">' +\n'        <GridCRS>' +\n'            <GridBaseCRS>urn:ogc:def:crs:EPSG:6.6:32618</GridBaseCRS>' +\n'            <GridType>urn:ogc:def:method:WCS:1.1:2dGridin2dCrs</GridType>' +\n'            <GridOrigin>3000 4000</GridOrigin>' +\n'            <GridOffsets>6.0 8.0 -8.0 6.0</GridOffsets>' +\n'            <GridCS>urn:ogc:def:cs:OGC:0.0:Grid2dSquareCS</GridCS>' +\n'        </GridCRS>' +\n'    </Output>' +\n'</GetCoverage>';\n\n        var format = new OpenLayers.Format.WCSGetCoverage();\n        var result = format.write({\n            identifier: 'Cov123',\n            domainSubset: {\n                boundingBox: {projection: 'urn:ogc:def:crs:OGC:2:84', bounds: new OpenLayers.Bounds(-71, 47, -66, 51)},\n                temporalSubset: {\n                    timePeriods: [\n                        {\n                            begin: '2006-08-01',\n                            end: '2006-09-01',\n                            resolution: 'P1D'\n                        }, {\n                            begin: '2007-08-01',\n                            end: '2007-09-01',\n                            resolution: 'P1D'\n                        }\n                    ]\n                }\n            },\n            output: {\n                format: 'image/netcdf',\n                gridCRS: {\n                    baseCRS: 'urn:ogc:def:crs:EPSG:6.6:32618',\n                    type: 'urn:ogc:def:method:WCS:1.1:2dGridin2dCrs',\n                    origin: '3000 4000',\n                    offsets: '6.0 8.0 -8.0 6.0',\n                    CS: 'urn:ogc:def:cs:OGC:0.0:Grid2dSquareCS'\n                }\n            }\n        });\n        t.xml_eq(result, expected, \"WCS GetCoverage written out correctly\");\n    }\n\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WFS.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script>  \n    function test_wfs_update_node(t) {\n        t.plan(2);\n        var expected = readXML(\"Update\");\n        var updateFeature = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(1,2),\n            {foo: \"bar\"});\n        updateFeature.fid = \"fid.42\";\n        updateFeature.state = OpenLayers.State.UPDATE;\n        var format = new OpenLayers.Format.WFS({\n            'featureNS':'http://www.openplans.org/topp',\n            'featureName': 'states',\n            'geometryName': 'the_geom',\n            'featurePrefix': 'topp'\n        }, {options:{}});\n        var updateNode = format.update(updateFeature);\n        t.xml_eq(updateNode, expected, \"update node matches expected XML value.\");\n        var format = new OpenLayers.Format.WFS({\n            'featurePrefix': 'topp'\n        }, {options:{typename: 'states', 'featureNS': 'http://www.openplans.org/topp', 'geometry_column': 'the_geom' }});\n        var updateNode = format.update(updateFeature);\n        t.xml_eq(updateNode, expected, \"update node matches expected XML value.\");\n    }\n    function test_wfs_delete_node(t) {\n        t.plan(2);\n        var expected = readXML(\"Delete\");\n        var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0));\n        feature.state = OpenLayers.State.DELETE;\n        feature.fid = \"fid.37\";\n        var format = new OpenLayers.Format.WFS({\n            'featureNS':'http://www.openplans.org/topp',\n            'featureName': 'states',\n            'featurePrefix': 'topp'\n        }, {options:{}});\n        var deleteNode = format.remove(feature);\n        t.xml_eq(deleteNode, expected, \"delete node matches expected XML value.\");\n        var format = new OpenLayers.Format.WFS({\n            'featurePrefix': 'topp'\n        }, {options:{typename: 'states', 'featureNS': 'http://www.openplans.org/topp'}});\n        var deleteNode = format.remove(feature);\n        t.xml_eq(deleteNode, expected, \"delete node matches expected XML value.\");\n    }\n    function readXML(id) {\n        var xml = document.getElementById(id).firstChild.nodeValue;\n        return new OpenLayers.Format.XML().read(xml).documentElement;        \n    }\n\n  </script>\n</head>\n<body>\n<div id=\"Update\"><!--\n<wfs:Update xmlns:wfs=\"http://www.opengis.net/wfs\" typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\">\n    <wfs:Property>\n        <wfs:Name>the_geom</wfs:Name>\n        <wfs:Value>\n            <gml:Point xmlns:gml=\"http://www.opengis.net/gml\">\n                <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2</gml:coordinates>\n            </gml:Point>\n        </wfs:Value>\n    </wfs:Property>\n    <wfs:Property>\n        <wfs:Name>foo</wfs:Name>\n        <wfs:Value>bar</wfs:Value>\n    </wfs:Property>\n    <ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n        <ogc:FeatureId fid=\"fid.42\"/>\n    </ogc:Filter>\n</wfs:Update>\n--></div>\n<div id=\"Delete\"><!--\n<wfs:Delete xmlns:wfs=\"http://www.opengis.net/wfs\" typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\">\n    <ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n        <ogc:FeatureId fid=\"fid.37\"/>\n    </ogc:Filter>\n</wfs:Delete>\n--></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WFSCapabilities/v1.html",
    "content": "<html> \n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_read_exception(t) {\n        t.plan(1);\n        var parser = new OpenLayers.Format.WFSCapabilities();\n        var text = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n'<ows:ExceptionReport language=\"en\" version=\"1.0.0\"' +\n'    xsi:schemaLocation=\"http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/owsExceptionReport.xsd\"' +\n'    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ows=\"http://www.opengis.net/ows\">' +\n'    <ows:Exception locator=\"foo\" exceptionCode=\"InvalidParameterValue\">' +\n'        <ows:ExceptionText>Update error: Error occured updating features</ows:ExceptionText>' +\n'        <ows:ExceptionText>Second exception line</ows:ExceptionText>' +\n'    </ows:Exception>' +\n'</ows:ExceptionReport>';\n\n        var obj = parser.read(text);\n        t.ok(!!obj.error, \"Error reported correctly\");      // The above should place an error in obj.error\n    }\n    \n    function test_read(t) {\n        t.plan(41);     // Number of tests performed: If you add a test below, be sure to increment this accordingly\n       \n        var parser = new OpenLayers.Format.WFSCapabilities();\n\n        // GeoServer, v1.1.0\n        var text = '<?xml version=\"1.0\" encoding=\"UTF-8\"?><wfs:WFS_Capabilities version=\"1.1.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.opengis.net/wfs\" xmlns:wfs=\"http://www.opengis.net/wfs\" xmlns:ows=\"http://www.opengis.net/ows\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xsi:schemaLocation=\"http://www.opengis.net/wfs http://localhost:80/geoserver/schemas/wfs/1.1.0/wfs.xsd\" xmlns:it.geosolutions=\"http://www.geo-solutions.it\" xmlns:cite=\"http://www.opengeospatial.net/cite\" xmlns:tiger=\"http://www.census.gov\" xmlns:sde=\"http://geoserver.sf.net\" xmlns:topp=\"http://www.openplans.org/topp\" xmlns:sf=\"http://www.openplans.org/spearfish\" xmlns:nurc=\"http://www.nurc.nato.int\" updateSequence=\"57\"><ows:ServiceIdentification><ows:Title>GeoServer Web Feature Service</ows:Title><ows:Abstract>This is the reference implementation of WFS 1.0.0 and WFS 1.1.0, supports all WFS operations including Transaction.</ows:Abstract><ows:Keywords><ows:Keyword>WFS</ows:Keyword><ows:Keyword>WMS</ows:Keyword><ows:Keyword>GEOSERVER</ows:Keyword></ows:Keywords><ows:ServiceType>WFS</ows:ServiceType><ows:ServiceTypeVersion>1.1.0</ows:ServiceTypeVersion><ows:Fees>NONE</ows:Fees><ows:AccessConstraints>NONE</ows:AccessConstraints></ows:ServiceIdentification><ows:ServiceProvider><ows:ProviderName>The ancient geographes INC</ows:ProviderName><ows:ServiceContact><ows:IndividualName>Claudius Ptolomaeus</ows:IndividualName><ows:PositionName>Chief geographer</ows:PositionName><ows:ContactInfo><ows:Phone><ows:Voice/><ows:Facsimile/></ows:Phone><ows:Address><ows:City>Alexandria</ows:City><ows:AdministrativeArea/><ows:PostalCode/><ows:Country>Egypt</ows:Country></ows:Address></ows:ContactInfo></ows:ServiceContact></ows:ServiceProvider><ows:OperationsMetadata><ows:Operation name=\"GetCapabilities\"><ows:DCP><ows:HTTP><ows:Get xlink:href=\"http://localhost:80/geoserver/wfs?\"/><ows:Post xlink:href=\"http://localhost:80/geoserver/wfs?\"/></ows:HTTP></ows:DCP><ows:Parameter name=\"AcceptVersions\"><ows:Value>1.0.0</ows:Value><ows:Value>1.1.0</ows:Value></ows:Parameter><ows:Parameter name=\"AcceptFormats\"><ows:Value>text/xml</ows:Value></ows:Parameter></ows:Operation><ows:Operation name=\"DescribeFeatureType\"><ows:DCP><ows:HTTP><ows:Get xlink:href=\"http://localhost:80/geoserver/wfs?\"/><ows:Post xlink:href=\"http://localhost:80/geoserver/wfs?\"/></ows:HTTP></ows:DCP><ows:Parameter name=\"outputFormat\"><ows:Value>text/xml; subtype=gml/3.1.1</ows:Value></ows:Parameter></ows:Operation><ows:Operation name=\"GetFeature\"><ows:DCP><ows:HTTP><ows:Get xlink:href=\"http://localhost:80/geoserver/wfs?\"/><ows:Post xlink:href=\"http://localhost:80/geoserver/wfs?\"/></ows:HTTP></ows:DCP><ows:Parameter name=\"resultType\"><ows:Value>results</ows:Value><ows:Value>hits</ows:Value></ows:Parameter><ows:Parameter name=\"outputFormat\"><ows:Value>text/xml; subtype=gml/3.1.1</ows:Value><ows:Value>GML2</ows:Value><ows:Value>GML2-GZIP</ows:Value><ows:Value>SHAPE-ZIP</ows:Value><ows:Value>csv</ows:Value><ows:Value>gml3</ows:Value><ows:Value>json</ows:Value><ows:Value>text/xml; subtype=gml/2.1.2</ows:Value></ows:Parameter><ows:Constraint name=\"LocalTraverseXLinkScope\"><ows:Value>2</ows:Value></ows:Constraint></ows:Operation><ows:Operation name=\"GetGmlObject\"><ows:DCP><ows:HTTP><ows:Get xlink:href=\"http://localhost:80/geoserver/wfs?\"/><ows:Post xlink:href=\"http://localhost:80/geoserver/wfs?\"/></ows:HTTP></ows:DCP></ows:Operation><ows:Operation name=\"LockFeature\"><ows:DCP><ows:HTTP><ows:Get xlink:href=\"http://localhost:80/geoserver/wfs?\"/><ows:Post xlink:href=\"http://localhost:80/geoserver/wfs?\"/></ows:HTTP></ows:DCP><ows:Parameter name=\"releaseAction\"><ows:Value>ALL</ows:Value><ows:Value>SOME</ows:Value></ows:Parameter></ows:Operation><ows:Operation name=\"GetFeatureWithLock\"><ows:DCP><ows:HTTP><ows:Get xlink:href=\"http://localhost:80/geoserver/wfs?\"/><ows:Post xlink:href=\"http://localhost:80/geoserver/wfs?\"/></ows:HTTP></ows:DCP><ows:Parameter name=\"resultType\"><ows:Value>results</ows:Value><ows:Value>hits</ows:Value></ows:Parameter><ows:Parameter name=\"outputFormat\"><ows:Value>text/xml; subtype=gml/3.1.1</ows:Value><ows:Value>GML2</ows:Value><ows:Value>GML2-GZIP</ows:Value><ows:Value>SHAPE-ZIP</ows:Value><ows:Value>csv</ows:Value><ows:Value>gml3</ows:Value><ows:Value>json</ows:Value><ows:Value>text/xml; subtype=gml/2.1.2</ows:Value></ows:Parameter></ows:Operation><ows:Operation name=\"Transaction\"><ows:DCP><ows:HTTP><ows:Get xlink:href=\"http://localhost:80/geoserver/wfs?\"/><ows:Post xlink:href=\"http://localhost:80/geoserver/wfs?\"/></ows:HTTP></ows:DCP><ows:Parameter name=\"inputFormat\"><ows:Value>text/xml; subtype=gml/3.1.1</ows:Value></ows:Parameter><ows:Parameter name=\"idgen\"><ows:Value>GenerateNew</ows:Value><ows:Value>UseExisting</ows:Value><ows:Value>ReplaceDuplicate</ows:Value></ows:Parameter><ows:Parameter name=\"releaseAction\"><ows:Value>ALL</ows:Value><ows:Value>SOME</ows:Value></ows:Parameter></ows:Operation></ows:OperationsMetadata><FeatureTypeList><Operations><Operation>Query</Operation><Operation>Insert</Operation><Operation>Update</Operation><Operation>Delete</Operation><Operation>Lock</Operation></Operations><FeatureType xmlns:tiger=\"http://www.census.gov\"><Name>tiger:poly_landmarks</Name><Title>Manhattan (NY) landmarks</Title><Abstract>Manhattan landmarks, identifies water, lakes, parks, interesting buildilngs</Abstract><ows:Keywords><ows:Keyword>DS_poly_landmarks</ows:Keyword><ows:Keyword>poly_landmarks</ows:Keyword><ows:Keyword>landmarks</ows:Keyword><ows:Keyword>manhattan</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-74.047185 40.679648</ows:LowerCorner><ows:UpperCorner>-73.90782 40.882078</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:tiger=\"http://www.census.gov\"><Name>tiger:poi</Name><Title>Manhattan (NY) points of interest</Title><Abstract>Points of interest in New York, New York (on Manhattan). One of the attributes contains the name of a file with a picture of the point of interest.</Abstract><ows:Keywords><ows:Keyword>poi</ows:Keyword><ows:Keyword>DS_poi</ows:Keyword><ows:Keyword>points_of_interest</ows:Keyword><ows:Keyword>Manhattan</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-74.0118315772888 40.70754683896324</ows:LowerCorner><ows:UpperCorner>-74.00857344353275 40.711945649065406</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:tiger=\"http://www.census.gov\"><Name>tiger:tiger_roads</Name><Title>Manhattan (NY) roads</Title><Abstract>Highly simplified road layout of Manhattan in New York..</Abstract><ows:Keywords><ows:Keyword>DS_tiger_roads</ows:Keyword><ows:Keyword>tiger_roads</ows:Keyword><ows:Keyword>roads</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-74.02722 40.684221</ows:LowerCorner><ows:UpperCorner>-73.907005 40.878178</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:sf=\"http://www.openplans.org/spearfish\"><Name>sf:archsites</Name><Title>Spearfish archeological sites</Title><Abstract>Sample data from GRASS, archeological sites location, Spearfish, South Dakota, USA</Abstract><ows:Keywords><ows:Keyword>archsites</ows:Keyword><ows:Keyword>sfArchsites</ows:Keyword><ows:Keyword>spearfish</ows:Keyword><ows:Keyword>archeology</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:26713</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-103.8725637911543 44.37740330855979</ows:LowerCorner><ows:UpperCorner>-103.63794182141925 44.48804280772808</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:sf=\"http://www.openplans.org/spearfish\"><Name>sf:bugsites</Name><Title>Spearfish bug locations</Title><Abstract>Sample data from GRASS, bug sites location, Spearfish, South Dakota, USA</Abstract><ows:Keywords><ows:Keyword>sfBugsites</ows:Keyword><ows:Keyword>bugsites</ows:Keyword><ows:Keyword>insects</ows:Keyword><ows:Keyword>spearfish</ows:Keyword><ows:Keyword>tiger_beetles</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:26713</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-103.86796131703647 44.373938816704396</ows:LowerCorner><ows:UpperCorner>-103.63773523234195 44.43418821380063</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:sf=\"http://www.openplans.org/spearfish\"><Name>sf:restricted</Name><Title>Spearfish restricted areas</Title><Abstract>Sample data from GRASS, restricted areas, Spearfish, South Dakota, USA</Abstract><ows:Keywords><ows:Keyword>restricted</ows:Keyword><ows:Keyword>sfRestricted</ows:Keyword><ows:Keyword>spearfish</ows:Keyword><ows:Keyword>areas</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:26713</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-103.85057172920756 44.39436387625042</ows:LowerCorner><ows:UpperCorner>-103.74741494853805 44.48215752041131</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:sf=\"http://www.openplans.org/spearfish\"><Name>sf:roads</Name><Title>Spearfish roads</Title><Abstract>Sample data from GRASS, road layout, Spearfish, South Dakota, USA</Abstract><ows:Keywords><ows:Keyword>sfRoads</ows:Keyword><ows:Keyword>roads</ows:Keyword><ows:Keyword>spearfish</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:26713</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-103.87741691493184 44.37087275281798</ows:LowerCorner><ows:UpperCorner>-103.62231404880659 44.50015918338962</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:sf=\"http://www.openplans.org/spearfish\"><Name>sf:streams</Name><Title>Spearfish streams</Title><Abstract>Sample data from GRASS, streams, Spearfish, South Dakota, USA</Abstract><ows:Keywords><ows:Keyword>sfStreams</ows:Keyword><ows:Keyword>streams</ows:Keyword><ows:Keyword>spearfish</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:26713</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-103.87789019829768 44.372335260095554</ows:LowerCorner><ows:UpperCorner>-103.62287788915457 44.502218486214815</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:topp=\"http://www.openplans.org/topp\"><Name>topp:tasmania_cities</Name><Title>Tasmania cities</Title><Abstract>Cities in Tasmania (actually, just the capital)</Abstract><ows:Keywords><ows:Keyword>cities</ows:Keyword><ows:Keyword>Tasmania</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>145.19754 -43.423512</ows:LowerCorner><ows:UpperCorner>148.27298000000002 -40.852802</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:topp=\"http://www.openplans.org/topp\"><Name>topp:tasmania_roads</Name><Title>Tasmania roads</Title><Abstract>Main Tasmania roads</Abstract><ows:Keywords><ows:Keyword>Roads</ows:Keyword><ows:Keyword>Tasmania</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>145.19754 -43.423512</ows:LowerCorner><ows:UpperCorner>148.27298000000002 -40.852802</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:topp=\"http://www.openplans.org/topp\"><Name>topp:tasmania_state_boundaries</Name><Title>Tasmania state boundaries</Title><Abstract>Tasmania state boundaries</Abstract><ows:Keywords><ows:Keyword>tasmania_state_boundaries</ows:Keyword><ows:Keyword>Tasmania</ows:Keyword><ows:Keyword>boundaries</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>143.83482400000003 -43.648056</ows:LowerCorner><ows:UpperCorner>148.47914100000003 -39.573891</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:topp=\"http://www.openplans.org/topp\"><Name>topp:tasmania_water_bodies</Name><Title>Tasmania water bodies</Title><Abstract>Tasmania water bodies</Abstract><ows:Keywords><ows:Keyword>Lakes</ows:Keyword><ows:Keyword>Bodies</ows:Keyword><ows:Keyword>Australia</ows:Keyword><ows:Keyword>Water</ows:Keyword><ows:Keyword>Tasmania</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>145.97161899999998 -43.031944</ows:LowerCorner><ows:UpperCorner>147.219696 -41.775558</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:topp=\"http://www.openplans.org/topp\"><Name>topp:states</Name><Title>USA Population</Title><Abstract>This is some census data on the states.</Abstract><ows:Keywords><ows:Keyword>census</ows:Keyword><ows:Keyword>united</ows:Keyword><ows:Keyword>boundaries</ows:Keyword><ows:Keyword>state</ows:Keyword><ows:Keyword>states</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-124.731422 24.955967</ows:LowerCorner><ows:UpperCorner>-66.969849 49.371735</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:tiger=\"http://www.census.gov\"><Name>tiger:giant_polygon</Name><Title>World rectangle</Title><Abstract>A simple rectangular polygon covering most of the world, it\\'s only used for the purpose of providing a background (WMS bgcolor could be used instead)</Abstract><ows:Keywords><ows:Keyword>DS_giant_polygon</ows:Keyword><ows:Keyword>giant_polygon</ows:Keyword></ows:Keywords><DefaultSRS>urn:x-ogc:def:crs:EPSG:4326</DefaultSRS><ows:WGS84BoundingBox><ows:LowerCorner>-180.0 -90.0</ows:LowerCorner><ows:UpperCorner>180.0 90.0</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType></FeatureTypeList><ogc:Filter_Capabilities><ogc:Spatial_Capabilities><ogc:GeometryOperands><ogc:GeometryOperand>gml:Envelope</ogc:GeometryOperand><ogc:GeometryOperand>gml:Point</ogc:GeometryOperand><ogc:GeometryOperand>gml:LineString</ogc:GeometryOperand><ogc:GeometryOperand>gml:Polygon</ogc:GeometryOperand></ogc:GeometryOperands><ogc:SpatialOperators><ogc:SpatialOperator name=\"Disjoint\"/><ogc:SpatialOperator name=\"Equals\"/><ogc:SpatialOperator name=\"DWithin\"/><ogc:SpatialOperator name=\"Beyond\"/><ogc:SpatialOperator name=\"Intersects\"/><ogc:SpatialOperator name=\"Touches\"/><ogc:SpatialOperator name=\"Crosses\"/><ogc:SpatialOperator name=\"Contains\"/><ogc:SpatialOperator name=\"Overlaps\"/><ogc:SpatialOperator name=\"BBOX\"/></ogc:SpatialOperators></ogc:Spatial_Capabilities><ogc:Scalar_Capabilities><ogc:LogicalOperators/><ogc:ComparisonOperators><ogc:ComparisonOperator>LessThan</ogc:ComparisonOperator><ogc:ComparisonOperator>GreaterThan</ogc:ComparisonOperator><ogc:ComparisonOperator>LessThanEqualTo</ogc:ComparisonOperator><ogc:ComparisonOperator>GreaterThanEqualTo</ogc:ComparisonOperator><ogc:ComparisonOperator>EqualTo</ogc:ComparisonOperator><ogc:ComparisonOperator>NotEqualTo</ogc:ComparisonOperator><ogc:ComparisonOperator>Like</ogc:ComparisonOperator><ogc:ComparisonOperator>Between</ogc:ComparisonOperator><ogc:ComparisonOperator>NullCheck</ogc:ComparisonOperator></ogc:ComparisonOperators><ogc:ArithmeticOperators><ogc:SimpleArithmetic/><ogc:Functions><ogc:FunctionNames><ogc:FunctionName nArgs=\"1\">abs</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">abs_2</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">abs_3</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">abs_4</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">acos</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">Area</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">asin</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">atan</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">atan2</ogc:FunctionName><ogc:FunctionName nArgs=\"3\">between</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">boundary</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">boundaryDimension</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">buffer</ogc:FunctionName><ogc:FunctionName nArgs=\"3\">bufferWithSegments</ogc:FunctionName><ogc:FunctionName nArgs=\"0\">Categorize</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">ceil</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">centroid</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">classify</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">Collection_Average</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">Collection_Bounds</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">Collection_Count</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">Collection_Max</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">Collection_Median</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">Collection_Min</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">Collection_Sum</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">Collection_Unique</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">Concatenate</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">contains</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">convexHull</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">cos</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">crosses</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">dateFormat</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">dateParse</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">difference</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">dimension</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">disjoint</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">distance</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">double2bool</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">endPoint</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">envelope</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">EqualInterval</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">equalsExact</ogc:FunctionName><ogc:FunctionName nArgs=\"3\">equalsExactTolerance</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">equalTo</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">exp</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">exteriorRing</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">floor</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">geometryType</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">geomFromWKT</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">geomLength</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">getGeometryN</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">getX</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">getY</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">getZ</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">greaterEqualThan</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">greaterThan</ogc:FunctionName><ogc:FunctionName nArgs=\"0\">id</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">IEEEremainder</ogc:FunctionName><ogc:FunctionName nArgs=\"3\">if_then_else</ogc:FunctionName><ogc:FunctionName nArgs=\"11\">in10</ogc:FunctionName><ogc:FunctionName nArgs=\"3\">in2</ogc:FunctionName><ogc:FunctionName nArgs=\"4\">in3</ogc:FunctionName><ogc:FunctionName nArgs=\"5\">in4</ogc:FunctionName><ogc:FunctionName nArgs=\"6\">in5</ogc:FunctionName><ogc:FunctionName nArgs=\"7\">in6</ogc:FunctionName><ogc:FunctionName nArgs=\"8\">in7</ogc:FunctionName><ogc:FunctionName nArgs=\"9\">in8</ogc:FunctionName><ogc:FunctionName nArgs=\"10\">in9</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">int2bbool</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">int2ddouble</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">interiorPoint</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">interiorRingN</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">intersection</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">intersects</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">isClosed</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">isEmpty</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">isLike</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">isNull</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">isRing</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">isSimple</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">isValid</ogc:FunctionName><ogc:FunctionName nArgs=\"3\">isWithinDistance</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">length</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">lessEqualThan</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">lessThan</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">log</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">max</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">max_2</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">max_3</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">max_4</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">min</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">min_2</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">min_3</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">min_4</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">not</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">notEqualTo</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">numGeometries</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">numInteriorRing</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">numPoints</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">overlaps</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">parseBoolean</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">parseDouble</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">parseInt</ogc:FunctionName><ogc:FunctionName nArgs=\"0\">pi</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">pointN</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">pow</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">PropertyExists</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">Quantile</ogc:FunctionName><ogc:FunctionName nArgs=\"0\">random</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">relate</ogc:FunctionName><ogc:FunctionName nArgs=\"3\">relatePattern</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">rint</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">round</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">round_2</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">roundDouble</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">sin</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">sqrt</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">StandardDeviation</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">startPoint</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">strConcat</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">strEndsWith</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">strEqualsIgnoreCase</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">strIndexOf</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">strLastIndexOf</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">strLength</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">strMatches</ogc:FunctionName><ogc:FunctionName nArgs=\"4\">strReplace</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">strStartsWith</ogc:FunctionName><ogc:FunctionName nArgs=\"3\">strSubstring</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">strSubstringStart</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">strToLowerCase</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">strToUpperCase</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">strTrim</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">symDifference</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">tan</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">toDegrees</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">toRadians</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">touches</ogc:FunctionName><ogc:FunctionName nArgs=\"1\">toWKT</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">union</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">UniqueInterval</ogc:FunctionName><ogc:FunctionName nArgs=\"2\">within</ogc:FunctionName></ogc:FunctionNames></ogc:Functions></ogc:ArithmeticOperators></ogc:Scalar_Capabilities><ogc:Id_Capabilities><ogc:FID/><ogc:EID/></ogc:Id_Capabilities></ogc:Filter_Capabilities></wfs:WFS_Capabilities>';\n        var res = parser.read(text);\n\n        t.ok(!res.error, \"Parsing XML generated no errors\");\n        t.eq(res.operationsMetadata[\"GetFeature\"].dcp.http.get[0].url, \"http://localhost:80/geoserver/wfs?\", \"GetFeature GET endpoint correctly parsed\");\n        t.eq(res.operationsMetadata[\"GetFeature\"].dcp.http.post[0].url, \"http://localhost:80/geoserver/wfs?\", \"GetFeature POST endpoint correctly parsed\");\n        var ft = res.featureTypeList.featureTypes;\n        t.eq(ft.length, 14, \"number of feature types correct\");\n        t.eq(ft[0][\"abstract\"], \"Manhattan landmarks, identifies water, lakes, parks, interesting buildilngs\", \"abstract of first feature type correct\");\n        t.eq(ft[0][\"title\"], \"Manhattan (NY) landmarks\", \"title of first feature type correct\");\n        t.eq(ft[0][\"name\"], \"poly_landmarks\", \"name of first feature type correct\");\n        t.eq(ft[0][\"featureNS\"], \"http://www.census.gov\", \"ns of first feature type correct\");\n        t.eq(ft[0][\"srs\"], \"urn:x-ogc:def:crs:EPSG:4326\", \"srs of first feature type correct\");\n\n        // GeoServer, v1.0.0\n        text = '<?xml version=\"1.0\" encoding=\"UTF-8\"?><WFS_Capabilities version=\"1.0.0\" xmlns=\"http://www.opengis.net/wfs\" xmlns:it.geosolutions=\"http://www.geo-solutions.it\" xmlns:cite=\"http://www.opengeospatial.net/cite\" xmlns:tiger=\"http://www.census.gov\" xmlns:sde=\"http://geoserver.sf.net\" xmlns:topp=\"http://www.openplans.org/topp\" xmlns:sf=\"http://www.openplans.org/spearfish\" xmlns:nurc=\"http://www.nurc.nato.int\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/wfs http://localhost:80/geoserver/schemas/wfs/1.0.0/WFS-capabilities.xsd\"><Service><Name>WFS</Name><Title>GeoServer Web Feature Service</Title><Abstract>This is the reference implementation of WFS 1.0.0 and WFS 1.1.0, supports all WFS operations including Transaction.</Abstract><Keywords>WFS, WMS, GEOSERVER</Keywords><OnlineResource>http://localhost:80/geoserver/wfs</OnlineResource><Fees>NONE</Fees><AccessConstraints>NONE</AccessConstraints></Service><Capability><Request><GetCapabilities><DCPType><HTTP><Get onlineResource=\"http://localhost:80/geoserver/wfs?request=GetCapabilities\"/></HTTP></DCPType><DCPType><HTTP><Post onlineResource=\"http://localhost:80/geoserver/wfs?\"/></HTTP></DCPType></GetCapabilities><DescribeFeatureType><SchemaDescriptionLanguage><XMLSCHEMA/></SchemaDescriptionLanguage><DCPType><HTTP><Get onlineResource=\"http://localhost:80/geoserver/wfs?request=DescribeFeatureType\"/></HTTP></DCPType><DCPType><HTTP><Post onlineResource=\"http://localhost:80/geoserver/wfs?\"/></HTTP></DCPType></DescribeFeatureType><GetFeature><ResultFormat><GML2/><SHAPE-ZIP/><GEOJSON/><csv/><GML3/></ResultFormat><DCPType><HTTP><Get onlineResource=\"http://localhost:80/geoserver/wfs?request=GetFeature\"/></HTTP></DCPType><DCPType><HTTP><Post onlineResource=\"http://localhost:80/geoserver/wfs?\"/></HTTP></DCPType></GetFeature><Transaction><DCPType><HTTP><Get onlineResource=\"http://localhost:80/geoserver/wfs?request=Transaction\"/></HTTP></DCPType><DCPType><HTTP><Post onlineResource=\"http://localhost:80/geoserver/wfs?\"/></HTTP></DCPType></Transaction><LockFeature><DCPType><HTTP><Get onlineResource=\"http://localhost:80/geoserver/wfs?request=LockFeature\"/></HTTP></DCPType><DCPType><HTTP><Post onlineResource=\"http://localhost:80/geoserver/wfs?\"/></HTTP></DCPType></LockFeature><GetFeatureWithLock><ResultFormat><GML2/></ResultFormat><DCPType><HTTP><Get onlineResource=\"http://localhost:80/geoserver/wfs?request=GetFeatureWithLock\"/></HTTP></DCPType><DCPType><HTTP><Post onlineResource=\"http://localhost:80/geoserver/wfs?\"/></HTTP></DCPType></GetFeatureWithLock></Request></Capability><FeatureTypeList><Operations><Query/><Insert/><Update/><Delete/><Lock/></Operations><FeatureType><Name>tiger:poly_landmarks</Name><Title>Manhattan (NY) landmarks</Title><Abstract>Manhattan landmarks, identifies water, lakes, parks, interesting buildilngs</Abstract><Keywords>DS_poly_landmarks, poly_landmarks, landmarks, manhattan</Keywords><SRS>EPSG:4326</SRS><LatLongBoundingBox minx=\"-74.047185\" miny=\"40.679648\" maxx=\"-73.90782\" maxy=\"40.882078\"/></FeatureType><FeatureType><Name>tiger:poi</Name><Title>Manhattan (NY) points of interest</Title><Abstract>Points of interest in New York, New York (on Manhattan). One of the attributes contains the name of a file with a picture of the point of interest.</Abstract><Keywords>poi, DS_poi, points_of_interest, Manhattan</Keywords><SRS>EPSG:4326</SRS><LatLongBoundingBox minx=\"-74.0118315772888\" miny=\"40.70754683896324\" maxx=\"-74.00857344353275\" maxy=\"40.711945649065406\"/></FeatureType><FeatureType><Name>tiger:tiger_roads</Name><Title>Manhattan (NY) roads</Title><Abstract>Highly simplified road layout of Manhattan in New York..</Abstract><Keywords>DS_tiger_roads, tiger_roads, roads</Keywords><SRS>EPSG:4326</SRS><LatLongBoundingBox minx=\"-74.02722\" miny=\"40.684221\" maxx=\"-73.907005\" maxy=\"40.878178\"/></FeatureType><FeatureType><Name>sf:archsites</Name><Title>Spearfish archeological sites</Title><Abstract>Sample data from GRASS, archeological sites location, Spearfish, South Dakota, USA</Abstract><Keywords>archsites, sfArchsites, spearfish, archeology</Keywords><SRS>EPSG:26713</SRS><LatLongBoundingBox minx=\"-103.8725637911543\" miny=\"44.37740330855979\" maxx=\"-103.63794182141925\" maxy=\"44.48804280772808\"/></FeatureType><FeatureType><Name>sf:bugsites</Name><Title>Spearfish bug locations</Title><Abstract>Sample data from GRASS, bug sites location, Spearfish, South Dakota, USA</Abstract><Keywords>sfBugsites, bugsites, insects, spearfish, tiger_beetles</Keywords><SRS>EPSG:26713</SRS><LatLongBoundingBox minx=\"-103.86796131703647\" miny=\"44.373938816704396\" maxx=\"-103.63773523234195\" maxy=\"44.43418821380063\"/></FeatureType><FeatureType><Name>sf:restricted</Name><Title>Spearfish restricted areas</Title><Abstract>Sample data from GRASS, restricted areas, Spearfish, South Dakota, USA</Abstract><Keywords>restricted, sfRestricted, spearfish, areas</Keywords><SRS>EPSG:26713</SRS><LatLongBoundingBox minx=\"-103.85057172920756\" miny=\"44.39436387625042\" maxx=\"-103.74741494853805\" maxy=\"44.48215752041131\"/></FeatureType><FeatureType><Name>sf:roads</Name><Title>Spearfish roads</Title><Abstract>Sample data from GRASS, road layout, Spearfish, South Dakota, USA</Abstract><Keywords>sfRoads, roads, spearfish</Keywords><SRS>EPSG:26713</SRS><LatLongBoundingBox minx=\"-103.87741691493184\" miny=\"44.37087275281798\" maxx=\"-103.62231404880659\" maxy=\"44.50015918338962\"/></FeatureType><FeatureType><Name>sf:streams</Name><Title>Spearfish streams</Title><Abstract>Sample data from GRASS, streams, Spearfish, South Dakota, USA</Abstract><Keywords>sfStreams, streams, spearfish</Keywords><SRS>EPSG:26713</SRS><LatLongBoundingBox minx=\"-103.87789019829768\" miny=\"44.372335260095554\" maxx=\"-103.62287788915457\" maxy=\"44.502218486214815\"/></FeatureType><FeatureType><Name>topp:tasmania_cities</Name><Title>Tasmania cities</Title><Abstract>Cities in Tasmania (actually, just the capital)</Abstract><Keywords>cities, Tasmania</Keywords><SRS>EPSG:4326</SRS><LatLongBoundingBox minx=\"145.19754\" miny=\"-43.423512\" maxx=\"148.27298000000002\" maxy=\"-40.852802\"/></FeatureType><FeatureType><Name>topp:tasmania_roads</Name><Title>Tasmania roads</Title><Abstract>Main Tasmania roads</Abstract><Keywords>Roads, Tasmania</Keywords><SRS>EPSG:4326</SRS><LatLongBoundingBox minx=\"145.19754\" miny=\"-43.423512\" maxx=\"148.27298000000002\" maxy=\"-40.852802\"/></FeatureType><FeatureType><Name>topp:tasmania_state_boundaries</Name><Title>Tasmania state boundaries</Title><Abstract>Tasmania state boundaries</Abstract><Keywords>tasmania_state_boundaries, Tasmania, boundaries</Keywords><SRS>EPSG:4326</SRS><LatLongBoundingBox minx=\"143.83482400000003\" miny=\"-43.648056\" maxx=\"148.47914100000003\" maxy=\"-39.573891\"/></FeatureType><FeatureType><Name>topp:tasmania_water_bodies</Name><Title>Tasmania water bodies</Title><Abstract>Tasmania water bodies</Abstract><Keywords>Lakes, Bodies, Australia, Water, Tasmania</Keywords><SRS>EPSG:4326</SRS><LatLongBoundingBox minx=\"145.97161899999998\" miny=\"-43.031944\" maxx=\"147.219696\" maxy=\"-41.775558\"/></FeatureType><FeatureType><Name>topp:states</Name><Title>USA Population</Title><Abstract>This is some census data on the states.</Abstract><Keywords>census, united, boundaries, state, states</Keywords><SRS>EPSG:4326</SRS><LatLongBoundingBox minx=\"-124.731422\" miny=\"24.955967\" maxx=\"-66.969849\" maxy=\"49.371735\"/></FeatureType><FeatureType><Name>tiger:giant_polygon</Name><Title>World rectangle</Title><Abstract>A simple rectangular polygon covering most of the world, it\\'s only used for the purpose of providing a background (WMS bgcolor could be used instead)</Abstract><Keywords>DS_giant_polygon, giant_polygon</Keywords><SRS>EPSG:4326</SRS><LatLongBoundingBox minx=\"-180.0\" miny=\"-90.0\" maxx=\"180.0\" maxy=\"90.0\"/></FeatureType></FeatureTypeList><ogc:Filter_Capabilities><ogc:Spatial_Capabilities><ogc:Spatial_Operators><ogc:Disjoint/><ogc:Equals/><ogc:DWithin/><ogc:Beyond/><ogc:Intersect/><ogc:Touches/><ogc:Crosses/><ogc:Within/><ogc:Contains/><ogc:Overlaps/><ogc:BBOX/></ogc:Spatial_Operators></ogc:Spatial_Capabilities><ogc:Scalar_Capabilities><ogc:Logical_Operators/><ogc:Comparison_Operators><ogc:Simple_Comparisons/><ogc:Between/><ogc:Like/><ogc:NullCheck/></ogc:Comparison_Operators><ogc:Arithmetic_Operators><ogc:Simple_Arithmetic/><ogc:Functions><ogc:Function_Names><ogc:Function_Name nArgs=\"1\">abs</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">abs_2</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">abs_3</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">abs_4</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">acos</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">Area</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">asin</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">atan</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">atan2</ogc:Function_Name><ogc:Function_Name nArgs=\"3\">between</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">boundary</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">boundaryDimension</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">buffer</ogc:Function_Name><ogc:Function_Name nArgs=\"3\">bufferWithSegments</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">ceil</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">centroid</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">classify</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">Collection_Average</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">Collection_Bounds</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">Collection_Count</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">Collection_Max</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">Collection_Median</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">Collection_Min</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">Collection_Sum</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">Collection_Unique</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">Concatenate</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">contains</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">convexHull</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">cos</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">crosses</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">dateFormat</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">dateParse</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">difference</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">dimension</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">disjoint</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">distance</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">double2bool</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">endPoint</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">envelope</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">EqualInterval</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">equalsExact</ogc:Function_Name><ogc:Function_Name nArgs=\"3\">equalsExactTolerance</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">equalTo</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">exp</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">exteriorRing</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">floor</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">geometryType</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">geomFromWKT</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">geomLength</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">getGeometryN</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">getX</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">getY</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">getZ</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">greaterEqualThan</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">greaterThan</ogc:Function_Name><ogc:Function_Name nArgs=\"0\">id</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">IEEEremainder</ogc:Function_Name><ogc:Function_Name nArgs=\"3\">if_then_else</ogc:Function_Name><ogc:Function_Name nArgs=\"11\">in10</ogc:Function_Name><ogc:Function_Name nArgs=\"3\">in2</ogc:Function_Name><ogc:Function_Name nArgs=\"4\">in3</ogc:Function_Name><ogc:Function_Name nArgs=\"5\">in4</ogc:Function_Name><ogc:Function_Name nArgs=\"6\">in5</ogc:Function_Name><ogc:Function_Name nArgs=\"7\">in6</ogc:Function_Name><ogc:Function_Name nArgs=\"8\">in7</ogc:Function_Name><ogc:Function_Name nArgs=\"9\">in8</ogc:Function_Name><ogc:Function_Name nArgs=\"10\">in9</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">int2bbool</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">int2ddouble</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">interiorPoint</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">interiorRingN</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">intersection</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">intersects</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">isClosed</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">isEmpty</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">isLike</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">isNull</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">isRing</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">isSimple</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">isValid</ogc:Function_Name><ogc:Function_Name nArgs=\"3\">isWithinDistance</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">length</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">lessEqualThan</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">lessThan</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">log</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">max</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">max_2</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">max_3</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">max_4</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">min</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">min_2</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">min_3</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">min_4</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">not</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">notEqualTo</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">numGeometries</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">numInteriorRing</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">numPoints</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">overlaps</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">parseBoolean</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">parseDouble</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">parseInt</ogc:Function_Name><ogc:Function_Name nArgs=\"0\">pi</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">pointN</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">pow</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">PropertyExists</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">Quantile</ogc:Function_Name><ogc:Function_Name nArgs=\"0\">random</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">relate</ogc:Function_Name><ogc:Function_Name nArgs=\"3\">relatePattern</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">rint</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">round</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">round_2</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">roundDouble</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">sin</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">sqrt</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">StandardDeviation</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">startPoint</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">strConcat</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">strEndsWith</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">strEqualsIgnoreCase</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">strIndexOf</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">strLastIndexOf</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">strLength</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">strMatches</ogc:Function_Name><ogc:Function_Name nArgs=\"4\">strReplace</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">strStartsWith</ogc:Function_Name><ogc:Function_Name nArgs=\"3\">strSubstring</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">strSubstringStart</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">strToLowerCase</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">strToUpperCase</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">strTrim</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">symDifference</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">tan</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">toDegrees</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">toRadians</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">touches</ogc:Function_Name><ogc:Function_Name nArgs=\"1\">toWKT</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">union</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">UniqueInterval</ogc:Function_Name><ogc:Function_Name nArgs=\"2\">within</ogc:Function_Name></ogc:Function_Names></ogc:Functions></ogc:Arithmetic_Operators></ogc:Scalar_Capabilities></ogc:Filter_Capabilities></WFS_Capabilities>';\n        res = parser.read(text);\n\n        t.ok(!res.error, \"Parsing XML generated no errors\");\n        ft = res.featureTypeList.featureTypes;\n        t.eq(ft.length, 14, \"number of feature types correct\");\n        t.eq(ft[0][\"abstract\"], \"Manhattan landmarks, identifies water, lakes, parks, interesting buildilngs\", \"abstract of first feature type correct\");\n        t.eq(ft[0][\"title\"], \"Manhattan (NY) landmarks\", \"title of first feature type correct\");\n        t.eq(ft[0][\"name\"], \"poly_landmarks\", \"name of first feature type correct\");\n        t.eq(ft[0][\"featureNS\"], \"http://www.census.gov\", \"ns of first feature type correct\");\n        t.eq(ft[0][\"srs\"], \"EPSG:4326\", \"srs of first feature type correct\");\n        t.eq(ft[0][\"latLongBoundingBox\"][0], -74.047185, \"latLongBoundingBox[0] (minx) is correct\");\n        t.eq(ft[0][\"latLongBoundingBox\"][1], 40.679648,  \"latLongBoundingBox[1] (miny) is correct\");\n        t.eq(ft[0][\"latLongBoundingBox\"][2], -73.90782,  \"latLongBoundingBox[2] (maxx) is correct\");\n        t.eq(ft[0][\"latLongBoundingBox\"][3], 40.882078,  \"latLongBoundingBox[3] (maxy) is correct\");\n\n        var service = res.service;\n        t.eq(service.name, 'WFS', \"service name correct\");\n        t.eq(service.title, 'GeoServer Web Feature Service', \"service title correct\");\n        t.eq(service.abstract, 'This is the reference implementation of WFS 1.0.0 and WFS 1.1.0, supports all WFS operations including Transaction.', \"service title correct\");\n        t.eq(service.keywords[0], 'WFS', \"service keyword [0] correct\");\n        t.eq(service.keywords[2], 'GEOSERVER', \"service keyword [2] correct\");\n        t.eq(service.onlineResource, 'http://localhost:80/geoserver/wfs', \"service onlineresource correct\");\n        t.ok(typeof service.fees == 'undefined', \"service fees correct\");\n        t.ok(typeof service.accessConstraints == 'undefined', \"service accessconstraints correct\");\n        \n        t.eq(res.capability.request.getfeature.href.post, \"http://localhost:80/geoserver/wfs?\", \"getfeature request post href correct\");\n        t.eq(res.capability.request.getfeature.href.get, \"http://localhost:80/geoserver/wfs?request=GetFeature\", \"getfeature request get href correct\");\n        \n        t.eq(res.capability.request.getfeature.formats[0], \"GML2\", \"getfeature response format [0] correct\");\n        t.eq(res.capability.request.getfeature.formats[4], \"GML3\", \"getfeature response format [4] correct\");\n        \n        // UMN Mapserer, v1.0.0\n        text =\n            '<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>' +\n            '<WFS_Capabilities' +\n            '   version=\"1.0.0\"' +\n            '   updateSequence=\"0\"' +\n            '   xmlns=\"http://www.opengis.net/wfs\"' +\n            '   xmlns:ogc=\"http://www.opengis.net/ogc\"' +\n            '   xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"' +\n            '   xsi:schemaLocation=\"http://www.opengis.net/wfs http://ogc.dmsolutions.ca/wfs/1.0.0/WFS-capabilities.xsd\">' +\n            '' +\n            '<!-- MapServer version 4.0 (development) OUTPUT=GIF OUTPUT=PNG OUTPUT=JPEG OUTPUT=WBMP OUTPUT=PDF OUTPUT=SWF SUPPORTS=PROJ SUPPORTS=FREETYPE SUPPORTS=WMS_SERVER SUPPORTS=WMS_CLIENT SUPPORTS=WFS_SERVER SUPPORTS=WFS_CLIENT INPUT=POSTGIS INPUT=OGR INPUT=GDAL INPUT=SHAPEFILE -->' +\n            '' +\n            '<Service>' +\n            '  <Name>MapServer WFS</Name>' +\n            '  <Title>GMap WMS Demo Server</Title>' +\n            '  <OnlineResource>http://127.0.0.1/cgi-bin/mapserv_40?map=/msroot/apache/htdocs/gmap/htdocs/gmap75_wfs.map&amp;service=WFS&amp;</OnlineResource>' +\n            '</Service>' +\n            '' +\n            '<Capability>' +\n            '  <Request>' +\n            '    <GetCapabilities>' +\n            '      <DCPType>' +\n            '        <HTTP>' +\n            '          <Get onlineResource=\"http://127.0.0.1/cgi-bin/mapserv_40?map=/msroot/apache/htdocs/gmap/htdocs/gmap75_wfs.map&amp;service=WFS&amp;\" />' +\n            '        </HTTP>' +\n            '      </DCPType>' +\n            '    </GetCapabilities>' +\n            '' +\n            '    <DescribeFeatureType>' +\n            '      <SchemaDescriptionLanguage>' +\n            '        <XMLSCHEMA/>' +\n            '      </SchemaDescriptionLanguage>' +\n            '      <DCPType>' +\n            '        <HTTP>' +\n            '          <Get onlineResource=\"http://127.0.0.1/cgi-bin/mapserv_40?map=/msroot/apache/htdocs/gmap/htdocs/gmap75_wfs.map&amp;service=WFS&amp;\" />' +\n            '        </HTTP>' +\n            '      </DCPType>' +\n            '' +\n            '    </DescribeFeatureType>' +\n            '    <GetFeature>' +\n            '      <ResultFormat>' +\n            '        <GML2/>' +\n            '      </ResultFormat>' +\n            '      <DCPType>' +\n            '        <HTTP>' +\n            '          <Get onlineResource=\"http://127.0.0.1/cgi-bin/mapserv_40?map=/msroot/apache/htdocs/gmap/htdocs/gmap75_wfs.map&amp;service=WFS&amp;\" />' +\n            '        </HTTP>' +\n            '' +\n            '      </DCPType>' +\n            '    </GetFeature>' +\n            '  </Request>' +\n            '</Capability>' +\n            '' +\n            '<FeatureTypeList>' +\n            '  <Operations>' +\n            '    <Query/>' +\n            '  </Operations>' +\n            '    <FeatureType>' +\n            '' +\n            '        <Name>park</Name>' +\n            '        <Title>Parks</Title>' +\n            '        <SRS>EPSG:42304</SRS>' +\n            '        <LatLongBoundingBox minx=\"-173.433\" miny=\"41.4271\" maxx=\"-13.3643\" maxy=\"83.7466\" />' +\n            '    </FeatureType>' +\n            '    <FeatureType>' +\n            '        <Name>popplace</Name>' +\n            '' +\n            '        <Title>Cities</Title>' +\n            '        <SRS>EPSG:42304</SRS>' +\n            '        <LatLongBoundingBox minx=\"-172.301\" miny=\"36.3541\" maxx=\"-12.9698\" maxy=\"83.4832\" />' +\n            '    </FeatureType>' +\n            '</FeatureTypeList>' +\n            '' +\n            '<ogc:Filter_Capabilities>' +\n            '  <ogc:Spatial_Capabilities>' +\n            '    <ogc:Spatial_Operators>' +\n            '' +\n            '      <ogc:BBOX/>' +\n            '    </ogc:Spatial_Operators>' +\n            '  </ogc:Spatial_Capabilities>' +\n            '  <!-- Provide some ScalarCapabilties just for the XML to validate against the schema even if we don\\'t support any.  (Yes this is stupid!) -->' +\n            '  <ogc:Scalar_Capabilities>' +\n            '    <ogc:Logical_Operators />' +\n            '  </ogc:Scalar_Capabilities>' +\n            '</ogc:Filter_Capabilities>' +\n            '' +\n            '</WFS_Capabilities>';\n        res = parser.read(text);\n        var ft = res.featureTypeList.featureTypes;\n        t.eq(ft.length, 2, \"number of feature types correct\");\n        t.eq(ft[0][\"title\"], \"Parks\", \"title of first feature type correct\");\n        t.eq(ft[0][\"name\"], \"park\", \"name of first feature type correct\");\n        t.eq(ft[0][\"srs\"], \"EPSG:42304\", \"srs of first feature type correct\");\n        \n        var service = res.service;\n        t.eq(service.name, 'MapServer WFS', \"service name correct\");\n        t.eq(service.title, 'GMap WMS Demo Server', \"service title correct\");\n        t.eq(service.onlineResource, 'http://127.0.0.1/cgi-bin/mapserv_40?map=/msroot/apache/htdocs/gmap/htdocs/gmap75_wfs.map&service=WFS&', \"service onlineresource correct\");\n        t.eq(res.capability.request.getfeature.href.get, \"http://127.0.0.1/cgi-bin/mapserv_40?map=/msroot/apache/htdocs/gmap/htdocs/gmap75_wfs.map&service=WFS&\", \"getfeature request get href correct\");\n        t.eq(res.capability.request.getfeature.formats[0], \"GML2\", \"getfeature response format [0] correct\");        \n    }\n\n    </script> \n</head> \n<body>\n</body> \n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WFSCapabilities/v2.html",
    "content": "<html> \n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_read_exception(t) {\n        t.plan(1);\n        var parser = new OpenLayers.Format.WFSCapabilities();\n        var text = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n'<ows:ExceptionReport language=\"en\" version=\"1.0.0\"' +\n'    xsi:schemaLocation=\"http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/owsExceptionReport.xsd\"' +\n'    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ows=\"http://www.opengis.net/ows\">' +\n'    <ows:Exception locator=\"foo\" exceptionCode=\"InvalidParameterValue\">' +\n'        <ows:ExceptionText>Update error: Error occured updating features</ows:ExceptionText>' +\n'        <ows:ExceptionText>Second exception line</ows:ExceptionText>' +\n'    </ows:Exception>' +\n'</ows:ExceptionReport>';\n\n        var obj = parser.read(text);\n        t.ok(!!obj.error, \"Error reported correctly\");      // The above should place an error in obj.error\n    }\n    \n    function test_read(t) {\n        t.plan(9);     // Number of tests performed: If you add a test below, be sure to increment this accordingly\n       \n        var parser = new OpenLayers.Format.WFSCapabilities();\n\n        // GeoServer, v2.0.0\n        var text = '<?xml version=\"1.0\" encoding=\"UTF-8\"?><wfs:WFS_Capabilities version=\"2.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.opengis.net/wfs/2.0\" xmlns:wfs=\"http://www.opengis.net/wfs/2.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:gml=\"http://www.opengis.net/gml/3.2\" xmlns:fes=\"http://www.opengis.net/fes/2.0\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:schemaLocation=\"http://www.opengis.net/wfs/2.0 http://localhost:8080/geoserver/schemas/wfs/2.0/wfs.xsd\" xmlns:xml=\"http://www.w3.org/XML/1998/namespace\" xmlns:it.geosolutions=\"http://www.geo-solutions.it\" xmlns:cite=\"http://www.opengeospatial.net/cite\" xmlns:tiger=\"http://www.census.gov\" xmlns:sde=\"http://geoserver.sf.net\" xmlns:topp=\"http://www.openplans.org/topp\" xmlns:sf=\"http://www.openplans.org/spearfish\" xmlns:nurc=\"http://www.nurc.nato.int\" updateSequence=\"78\"><ows:ServiceIdentification><ows:Title>GeoServer Web Feature Service</ows:Title><ows:Abstract>This is the reference implementation of WFS 1.0.0 and WFS 1.1.0, supports all WFS operations including Transaction.</ows:Abstract><ows:Keywords><ows:Keyword>WFS</ows:Keyword><ows:Keyword>WMS</ows:Keyword><ows:Keyword>GEOSERVER</ows:Keyword></ows:Keywords><ows:ServiceType>WFS</ows:ServiceType><ows:ServiceTypeVersion>2.0.0</ows:ServiceTypeVersion><ows:Fees>NONE</ows:Fees><ows:AccessConstraints>NONE</ows:AccessConstraints></ows:ServiceIdentification><ows:ServiceProvider><ows:ProviderName>The ancient geographes INC</ows:ProviderName><ows:ServiceContact><ows:IndividualName>Claudius Ptolomaeus</ows:IndividualName><ows:PositionName>Chief geographer</ows:PositionName><ows:ContactInfo><ows:Phone><ows:Voice/><ows:Facsimile/></ows:Phone><ows:Address><ows:City>Alexandria</ows:City><ows:AdministrativeArea/><ows:PostalCode/><ows:Country>Egypt</ows:Country></ows:Address></ows:ContactInfo></ows:ServiceContact></ows:ServiceProvider><ows:OperationsMetadata><ows:Operation name=\"GetCapabilities\"><ows:DCP><ows:HTTP><ows:Get xlink:href=\"http://localhost:8080/geoserver/wfs\"/><ows:Post xlink:href=\"http://localhost:8080/geoserver/wfs\"/></ows:HTTP></ows:DCP><ows:Parameter name=\"AcceptVersions\"><ows:AllowedValues><ows:Value>1.0.0</ows:Value><ows:Value>1.1.0</ows:Value><ows:Value>2.0.0</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name=\"AcceptFormats\"><ows:AllowedValues><ows:Value>text/xml</ows:Value></ows:AllowedValues></ows:Parameter></ows:Operation><ows:Operation name=\"DescribeFeatureType\"><ows:DCP><ows:HTTP><ows:Get xlink:href=\"http://localhost:8080/geoserver/wfs\"/><ows:Post xlink:href=\"http://localhost:8080/geoserver/wfs\"/></ows:HTTP></ows:DCP><ows:Parameter name=\"outputFormat\"><ows:AllowedValues><ows:Value>text/xml; subtype=gml/3.2</ows:Value></ows:AllowedValues></ows:Parameter></ows:Operation><ows:Operation name=\"GetFeature\"><ows:DCP><ows:HTTP><ows:Get xlink:href=\"http://localhost:8080/geoserver/wfs\"/><ows:Post xlink:href=\"http://localhost:8080/geoserver/wfs\"/></ows:HTTP></ows:DCP><ows:Parameter name=\"resultType\"><ows:AllowedValues><ows:Value>results</ows:Value><ows:Value>hits</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name=\"outputFormat\"><ows:AllowedValues><ows:Value>text/xml; subtype=gml/3.2</ows:Value><ows:Value>GML2</ows:Value><ows:Value>SHAPE-ZIP</ows:Value><ows:Value>application/gml+xml; version=3.2</ows:Value><ows:Value>application/json</ows:Value><ows:Value>csv</ows:Value><ows:Value>gml3</ows:Value><ows:Value>gml32</ows:Value><ows:Value>json</ows:Value><ows:Value>text/xml; subtype=gml/2.1.2</ows:Value><ows:Value>text/xml; subtype=gml/3.1.1</ows:Value></ows:AllowedValues></ows:Parameter><ows:Constraint name=\"PagingIsTransactionSafe\"><ows:NoValues/><ows:DefaultValue>FALSE</ows:DefaultValue></ows:Constraint><ows:Constraint name=\"CountDefault\"><ows:NoValues/><ows:DefaultValue>1000000</ows:DefaultValue></ows:Constraint></ows:Operation><ows:Operation name=\"GetPropertyValue\"><ows:DCP><ows:HTTP><ows:Get xlink:href=\"http://localhost:8080/geoserver/wfs\"/><ows:Post xlink:href=\"http://localhost:8080/geoserver/wfs\"/></ows:HTTP></ows:DCP><ows:Parameter name=\"resolve\"><ows:AllowedValues><ows:Value>none</ows:Value></ows:AllowedValues></ows:Parameter></ows:Operation><ows:Operation name=\"ListStoredQueries\"><ows:DCP><ows:HTTP><ows:Get xlink:href=\"http://localhost:8080/geoserver/wfs\"/><ows:Post xlink:href=\"http://localhost:8080/geoserver/wfs\"/></ows:HTTP></ows:DCP></ows:Operation><ows:Operation name=\"DescribeStoredQueries\"><ows:DCP><ows:HTTP><ows:Get xlink:href=\"http://localhost:8080/geoserver/wfs\"/><ows:Post xlink:href=\"http://localhost:8080/geoserver/wfs\"/></ows:HTTP></ows:DCP></ows:Operation><ows:Operation name=\"CreateStoredQuery\"><ows:DCP><ows:HTTP><ows:Post xlink:href=\"http://localhost:8080/geoserver/wfs\"/></ows:HTTP></ows:DCP></ows:Operation><ows:Operation name=\"DropStoredQuery\"><ows:DCP><ows:HTTP><ows:Get xlink:href=\"http://localhost:8080/geoserver/wfs\"/><ows:Post xlink:href=\"http://localhost:8080/geoserver/wfs\"/></ows:HTTP></ows:DCP></ows:Operation><ows:Operation name=\"LockFeature\"><ows:DCP><ows:HTTP><ows:Get xlink:href=\"http://localhost:8080/geoserver/wfs\"/><ows:Post xlink:href=\"http://localhost:8080/geoserver/wfs\"/></ows:HTTP></ows:DCP><ows:Parameter name=\"releaseAction\"><ows:AllowedValues><ows:Value>ALL</ows:Value><ows:Value>SOME</ows:Value></ows:AllowedValues></ows:Parameter></ows:Operation><ows:Operation name=\"GetFeatureWithLock\"><ows:DCP><ows:HTTP><ows:Get xlink:href=\"http://localhost:8080/geoserver/wfs\"/><ows:Post xlink:href=\"http://localhost:8080/geoserver/wfs\"/></ows:HTTP></ows:DCP><ows:Parameter name=\"resultType\"><ows:AllowedValues><ows:Value>results</ows:Value><ows:Value>hits</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name=\"outputFormat\"><ows:AllowedValues><ows:Value>text/xml; subtype=gml/3.2</ows:Value><ows:Value>GML2</ows:Value><ows:Value>SHAPE-ZIP</ows:Value><ows:Value>application/gml+xml; version=3.2</ows:Value><ows:Value>application/json</ows:Value><ows:Value>csv</ows:Value><ows:Value>gml3</ows:Value><ows:Value>gml32</ows:Value><ows:Value>json</ows:Value><ows:Value>text/xml; subtype=gml/2.1.2</ows:Value><ows:Value>text/xml; subtype=gml/3.1.1</ows:Value></ows:AllowedValues></ows:Parameter><ows:Constraint name=\"PagingIsTransactionSafe\"><ows:NoValues/><ows:DefaultValue>FALSE</ows:DefaultValue></ows:Constraint><ows:Constraint name=\"CountDefault\"><ows:NoValues/><ows:DefaultValue>1000000</ows:DefaultValue></ows:Constraint></ows:Operation><ows:Operation name=\"Transaction\"><ows:DCP><ows:HTTP><ows:Get xlink:href=\"http://localhost:8080/geoserver/wfs\"/><ows:Post xlink:href=\"http://localhost:8080/geoserver/wfs\"/></ows:HTTP></ows:DCP><ows:Parameter name=\"inputFormat\"><ows:AllowedValues><ows:Value>text/xml; subtype=gml/3.2</ows:Value></ows:AllowedValues></ows:Parameter><ows:Parameter name=\"releaseAction\"><ows:AllowedValues><ows:Value>ALL</ows:Value><ows:Value>SOME</ows:Value></ows:AllowedValues></ows:Parameter></ows:Operation><ows:Constraint name=\"ImplementsBasicWFS\"><ows:NoValues/><ows:DefaultValue>TRUE</ows:DefaultValue></ows:Constraint><ows:Constraint name=\"ImplementsTransactionalWFS\"><ows:NoValues/><ows:DefaultValue>TRUE</ows:DefaultValue></ows:Constraint><ows:Constraint name=\"ImplementsLockingWFS\"><ows:NoValues/><ows:DefaultValue>TRUE</ows:DefaultValue></ows:Constraint><ows:Constraint name=\"KVPEncoding\"><ows:NoValues/><ows:DefaultValue>TRUE</ows:DefaultValue></ows:Constraint><ows:Constraint name=\"XMLEncoding\"><ows:NoValues/><ows:DefaultValue>TRUE</ows:DefaultValue></ows:Constraint><ows:Constraint name=\"SOAPEncoding\"><ows:NoValues/><ows:DefaultValue>TRUE</ows:DefaultValue></ows:Constraint><ows:Constraint name=\"ImplementsInheritance\"><ows:NoValues/><ows:DefaultValue>FALSE</ows:DefaultValue></ows:Constraint><ows:Constraint name=\"ImplementsRemoteResolve\"><ows:NoValues/><ows:DefaultValue>FALSE</ows:DefaultValue></ows:Constraint><ows:Constraint name=\"ImplementsResultPaging\"><ows:NoValues/><ows:DefaultValue>TRUE</ows:DefaultValue></ows:Constraint><ows:Constraint name=\"ImplementsStandardJoins\"><ows:NoValues/><ows:DefaultValue>TRUE</ows:DefaultValue></ows:Constraint><ows:Constraint name=\"ImplementsSpatialJoins\"><ows:NoValues/><ows:DefaultValue>TRUE</ows:DefaultValue></ows:Constraint><ows:Constraint name=\"ImplementsTemporalJoins\"><ows:NoValues/><ows:DefaultValue>TRUE</ows:DefaultValue></ows:Constraint><ows:Constraint name=\"ImplementsFeatureVersioning\"><ows:NoValues/><ows:DefaultValue>FALSE</ows:DefaultValue></ows:Constraint><ows:Constraint name=\"ManageStoredQueries\"><ows:NoValues/><ows:DefaultValue>TRUE</ows:DefaultValue></ows:Constraint><ows:Constraint name=\"PagingIsTransactionSafe\"><ows:NoValues/><ows:DefaultValue>FALSE</ows:DefaultValue></ows:Constraint><ows:Constraint name=\"QueryExpressions\"><ows:AllowedValues><ows:Value>wfs:Query</ows:Value><ows:Value>wfs:StoredQuery</ows:Value></ows:AllowedValues></ows:Constraint></ows:OperationsMetadata><FeatureTypeList><FeatureType xmlns:tiger=\"http://www.census.gov\"><Name>tiger:poly_landmarks</Name><Title>Manhattan (NY) landmarks</Title><Abstract>Manhattan landmarks, identifies water, lakes, parks, interesting buildilngs</Abstract><ows:Keywords><ows:Keyword>landmarks</ows:Keyword><ows:Keyword>DS_poly_landmarks</ows:Keyword><ows:Keyword>manhattan</ows:Keyword><ows:Keyword>poly_landmarks</ows:Keyword></ows:Keywords><DefaultCRS>urn:ogc:def:crs:EPSG::4326</DefaultCRS><ows:WGS84BoundingBox><ows:LowerCorner>-74.047185 40.679648</ows:LowerCorner><ows:UpperCorner>-73.90782 40.882078</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:tiger=\"http://www.census.gov\"><Name>tiger:poi</Name><Title>Manhattan (NY) points of interest</Title><Abstract>Points of interest in New York, New York (on Manhattan). One of the attributes contains the name of a file with a picture of the point of interest.</Abstract><ows:Keywords><ows:Keyword>poi</ows:Keyword><ows:Keyword>Manhattan</ows:Keyword><ows:Keyword>DS_poi</ows:Keyword><ows:Keyword>points_of_interest</ows:Keyword></ows:Keywords><DefaultCRS>urn:ogc:def:crs:EPSG::4326</DefaultCRS><ows:WGS84BoundingBox><ows:LowerCorner>-74.0118315772888 40.70754683896324</ows:LowerCorner><ows:UpperCorner>-74.00857344353275 40.711945649065406</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:tiger=\"http://www.census.gov\"><Name>tiger:tiger_roads</Name><Title>Manhattan (NY) roads</Title><Abstract>Highly simplified road layout of Manhattan in New York..</Abstract><ows:Keywords><ows:Keyword>DS_tiger_roads</ows:Keyword><ows:Keyword>tiger_roads</ows:Keyword><ows:Keyword>roads</ows:Keyword></ows:Keywords><DefaultCRS>urn:ogc:def:crs:EPSG::4326</DefaultCRS><ows:WGS84BoundingBox><ows:LowerCorner>-74.02722 40.684221</ows:LowerCorner><ows:UpperCorner>-73.907005 40.878178</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:sf=\"http://www.openplans.org/spearfish\"><Name>sf:archsites</Name><Title>Spearfish archeological sites</Title><Abstract>Sample data from GRASS, archeological sites location, Spearfish, South Dakota, USA</Abstract><ows:Keywords><ows:Keyword>archsites</ows:Keyword><ows:Keyword>spearfish</ows:Keyword><ows:Keyword>sfArchsites</ows:Keyword><ows:Keyword>archeology</ows:Keyword></ows:Keywords><DefaultCRS>urn:ogc:def:crs:EPSG::26713</DefaultCRS><ows:WGS84BoundingBox><ows:LowerCorner>-103.8725637911543 44.37740330855979</ows:LowerCorner><ows:UpperCorner>-103.63794182141925 44.48804280772808</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:sf=\"http://www.openplans.org/spearfish\"><Name>sf:bugsites</Name><Title>Spearfish bug locations</Title><Abstract>Sample data from GRASS, bug sites location, Spearfish, South Dakota, USA</Abstract><ows:Keywords><ows:Keyword>spearfish</ows:Keyword><ows:Keyword>sfBugsites</ows:Keyword><ows:Keyword>insects</ows:Keyword><ows:Keyword>bugsites</ows:Keyword><ows:Keyword>tiger_beetles</ows:Keyword></ows:Keywords><DefaultCRS>urn:ogc:def:crs:EPSG::26713</DefaultCRS><ows:WGS84BoundingBox><ows:LowerCorner>-103.86796131703647 44.373938816704396</ows:LowerCorner><ows:UpperCorner>-103.63773523234195 44.43418821380063</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:sf=\"http://www.openplans.org/spearfish\"><Name>sf:restricted</Name><Title>Spearfish restricted areas</Title><Abstract>Sample data from GRASS, restricted areas, Spearfish, South Dakota, USA</Abstract><ows:Keywords><ows:Keyword>spearfish</ows:Keyword><ows:Keyword>restricted</ows:Keyword><ows:Keyword>areas</ows:Keyword><ows:Keyword>sfRestricted</ows:Keyword></ows:Keywords><DefaultCRS>urn:ogc:def:crs:EPSG::26713</DefaultCRS><ows:WGS84BoundingBox><ows:LowerCorner>-103.85057172920756 44.39436387625042</ows:LowerCorner><ows:UpperCorner>-103.74741494853805 44.48215752041131</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:sf=\"http://www.openplans.org/spearfish\"><Name>sf:roads</Name><Title>Spearfish roads</Title><Abstract>Sample data from GRASS, road layout, Spearfish, South Dakota, USA</Abstract><ows:Keywords><ows:Keyword>sfRoads</ows:Keyword><ows:Keyword>spearfish</ows:Keyword><ows:Keyword>roads</ows:Keyword></ows:Keywords><DefaultCRS>urn:ogc:def:crs:EPSG::26713</DefaultCRS><ows:WGS84BoundingBox><ows:LowerCorner>-103.87741691493184 44.37087275281798</ows:LowerCorner><ows:UpperCorner>-103.62231404880659 44.50015918338962</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:sf=\"http://www.openplans.org/spearfish\"><Name>sf:streams</Name><Title>Spearfish streams</Title><Abstract>Sample data from GRASS, streams, Spearfish, South Dakota, USA</Abstract><ows:Keywords><ows:Keyword>spearfish</ows:Keyword><ows:Keyword>sfStreams</ows:Keyword><ows:Keyword>streams</ows:Keyword></ows:Keywords><DefaultCRS>urn:ogc:def:crs:EPSG::26713</DefaultCRS><ows:WGS84BoundingBox><ows:LowerCorner>-103.87789019829768 44.372335260095554</ows:LowerCorner><ows:UpperCorner>-103.62287788915457 44.502218486214815</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:topp=\"http://www.openplans.org/topp\"><Name>topp:tasmania_cities</Name><Title>Tasmania cities</Title><Abstract>Cities in Tasmania (actually, just the capital)</Abstract><ows:Keywords><ows:Keyword>cities</ows:Keyword><ows:Keyword>Tasmania</ows:Keyword></ows:Keywords><DefaultCRS>urn:ogc:def:crs:EPSG::4326</DefaultCRS><ows:WGS84BoundingBox><ows:LowerCorner>145.19754 -43.423512</ows:LowerCorner><ows:UpperCorner>148.27298000000002 -40.852802</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:topp=\"http://www.openplans.org/topp\"><Name>topp:tasmania_roads</Name><Title>Tasmania roads</Title><Abstract>Main Tasmania roads</Abstract><ows:Keywords><ows:Keyword>Roads</ows:Keyword><ows:Keyword>Tasmania</ows:Keyword></ows:Keywords><DefaultCRS>urn:ogc:def:crs:EPSG::4326</DefaultCRS><ows:WGS84BoundingBox><ows:LowerCorner>145.19754 -43.423512</ows:LowerCorner><ows:UpperCorner>148.27298000000002 -40.852802</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:topp=\"http://www.openplans.org/topp\"><Name>topp:tasmania_state_boundaries</Name><Title>Tasmania state boundaries</Title><Abstract>Tasmania state boundaries</Abstract><ows:Keywords><ows:Keyword>boundaries</ows:Keyword><ows:Keyword>tasmania_state_boundaries</ows:Keyword><ows:Keyword>Tasmania</ows:Keyword></ows:Keywords><DefaultCRS>urn:ogc:def:crs:EPSG::4326</DefaultCRS><ows:WGS84BoundingBox><ows:LowerCorner>143.83482400000003 -43.648056</ows:LowerCorner><ows:UpperCorner>148.47914100000003 -39.573891</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:topp=\"http://www.openplans.org/topp\"><Name>topp:tasmania_water_bodies</Name><Title>Tasmania water bodies</Title><Abstract>Tasmania water bodies</Abstract><ows:Keywords><ows:Keyword>Lakes</ows:Keyword><ows:Keyword>Bodies</ows:Keyword><ows:Keyword>Australia</ows:Keyword><ows:Keyword>Water</ows:Keyword><ows:Keyword>Tasmania</ows:Keyword></ows:Keywords><DefaultCRS>urn:ogc:def:crs:EPSG::4326</DefaultCRS><ows:WGS84BoundingBox><ows:LowerCorner>145.97161899999998 -43.031944</ows:LowerCorner><ows:UpperCorner>147.219696 -41.775558</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:topp=\"http://www.openplans.org/topp\"><Name>topp:states</Name><Title>USA Population</Title><Abstract>This is some census data on the states.</Abstract><ows:Keywords><ows:Keyword>census</ows:Keyword><ows:Keyword>united</ows:Keyword><ows:Keyword>boundaries</ows:Keyword><ows:Keyword>state</ows:Keyword><ows:Keyword>states</ows:Keyword></ows:Keywords><DefaultCRS>urn:ogc:def:crs:EPSG::4326</DefaultCRS><ows:WGS84BoundingBox><ows:LowerCorner>-124.731422 24.955967</ows:LowerCorner><ows:UpperCorner>-66.969849 49.371735</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType><FeatureType xmlns:tiger=\"http://www.census.gov\"><Name>tiger:giant_polygon</Name><Title>World rectangle</Title><Abstract>A simple rectangular polygon covering most of the world, it\\'s only used for the purpose of providing a background (WMS bgcolor could be used instead)</Abstract><ows:Keywords><ows:Keyword>DS_giant_polygon</ows:Keyword><ows:Keyword>giant_polygon</ows:Keyword></ows:Keywords><DefaultCRS>urn:ogc:def:crs:EPSG::4326</DefaultCRS><ows:WGS84BoundingBox><ows:LowerCorner>-180.0 -90.0</ows:LowerCorner><ows:UpperCorner>180.0 90.0</ows:UpperCorner></ows:WGS84BoundingBox></FeatureType></FeatureTypeList></wfs:WFS_Capabilities>';\n        var res = parser.read(text);\n\n        t.ok(!res.error, \"Parsing XML generated no errors\");\n        t.eq(res.operationsMetadata[\"GetFeature\"].dcp.http.get[0].url, \"http://localhost:8080/geoserver/wfs\", \"GetFeature GET endpoint correctly parsed\");\n        t.eq(res.operationsMetadata[\"GetFeature\"].dcp.http.post[0].url, \"http://localhost:8080/geoserver/wfs\", \"GetFeature POST endpoint correctly parsed\");\n        var ft = res.featureTypeList.featureTypes;\n        t.eq(ft.length, 14, \"number of feature types correct\");\n        t.eq(ft[0][\"abstract\"], \"Manhattan landmarks, identifies water, lakes, parks, interesting buildilngs\", \"abstract of first feature type correct\");\n        t.eq(ft[0][\"title\"], \"Manhattan (NY) landmarks\", \"title of first feature type correct\");\n        t.eq(ft[0][\"name\"], \"poly_landmarks\", \"name of first feature type correct\");\n        t.eq(ft[0][\"featureNS\"], \"http://www.census.gov\", \"ns of first feature type correct\");\n        t.eq(ft[0][\"srs\"], \"urn:ogc:def:crs:EPSG::4326\", \"srs of first feature type correct\");\n    }\n\n    </script> \n</head> \n<body>\n</body> \n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WFSCapabilities.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    \n    function test_read(t) {\n        t.plan(6);\n       \n        var _v1_0_0 = OpenLayers.Format.WFSCapabilities.v1_0_0.prototype.read;\n        var _v1_1_0 = OpenLayers.Format.WFSCapabilities.v1_1_0.prototype.read;\n        var _v2_0_0 = OpenLayers.Format.WFSCapabilities.v2_0_0.prototype.read;\n\n        var parser = new OpenLayers.Format.WFSCapabilities();\n\n        // version 1.0.0\n        var text =\n            '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n            '<wfs:WFS_Capabilities version=\"1.0.0\" xmlns:wfs=\"http://www.opengis.net/wfs\"></wfs:WFS_Capabilities>';\n        OpenLayers.Format.WFSCapabilities.v1_0_0.prototype.read = function() {\n            t.ok(true, \"Version 1.0.0 detected\");\n            return {};\n        }\n        var res = parser.read(text);\n        t.eq(res.version, \"1.0.0\", \"version 1.0.0 written to result object\");\n        OpenLayers.Format.WFSCapabilities.v1_1_0.prototype.read = _v1_1_0;\n\n        // version 1.1.0\n        var text =\n            '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n            '<wfs:WFS_Capabilities version=\"1.1.0\" xmlns:wfs=\"http://www.opengis.net/wfs\"></wfs:WFS_Capabilities>';\n        OpenLayers.Format.WFSCapabilities.v1_1_0.prototype.read = function() {\n            t.ok(true, \"Version 1.1.0 detected\");\n            return {};\n        }\n        var res = parser.read(text);\n        t.eq(res.version, \"1.1.0\", \"version 1.1.0 written to result object\");\n        OpenLayers.Format.WFSCapabilities.v1_1_0.prototype.read = _v1_1_0;\n        \n        // version 2.0.0\n        var text =\n            '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n            '<wfs:WFS_Capabilities version=\"2.0.0\" xmlns:wfs=\"http://www.opengis.net/wfs\"></wfs:WFS_Capabilities>';\n        OpenLayers.Format.WFSCapabilities.v2_0_0.prototype.read = function() {\n            t.ok(true, \"Version 2.0.0 detected\");\n            return {};\n        }\n        var res = parser.read(text);\n        t.eq(res.version, \"2.0.0\", \"version 2.0.0 written to result object\");\n        OpenLayers.Format.WFSCapabilities.v2_0_0.prototype.read = _v2_0_0;\n    }\n\n    </script> \n</head> \n<body>\n</body> \n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WFSDescribeFeatureType.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    \n    function test_read_WFSDescribeFeatureType(t) {\n        t.plan(39);\n       \n        var parser = new OpenLayers.Format.WFSDescribeFeatureType();\n\n        // single typeName from UMN Mapserver\n        var text = \n            '<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>' +\n            '<schema' +\n            '   targetNamespace=\"http://mapserver.gis.umn.edu/mapserver\" ' +\n            '   xmlns:rws=\"http://mapserver.gis.umn.edu/mapserver\" ' +\n            '   xmlns:ogc=\"http://www.opengis.net/ogc\"' +\n            '   xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"' +\n            '   xmlns=\"http://www.w3.org/2001/XMLSchema\"' +\n            '   xmlns:gml=\"http://www.opengis.net/gml\"' +\n            '   elementFormDefault=\"qualified\" version=\"0.1\" >' +\n            '  <import namespace=\"http://www.opengis.net/gml\"' +\n            '          schemaLocation=\"http://schemas.opengis.net/gml/2.1.2/feature.xsd\" />' +\n            '  <element name=\"AAA64\" ' +\n            '           type=\"rws:AAA64Type\" ' +\n            '           substitutionGroup=\"gml:_Feature\" />' +\n            '  <complexType name=\"AAA64Type\">' +\n            '    <complexContent>' +\n            '      <extension base=\"gml:AbstractFeatureType\">' +\n            '        <sequence>' +\n            '          <element name=\"geometry\" type=\"gml:MultiLineStringPropertyType\" minOccurs=\"0\" maxOccurs=\"1\"/>' +\n            '          <element name=\"OBJECTID\" type=\"string\"/>' +\n            '          <element name=\"ROUTE\" type=\"string\"/>' +\n            '          <element name=\"ROUTE_CH\" type=\"string\"/>' +\n            '          <element name=\"COUNT\" type=\"string\"/>' +\n            '          <element name=\"BEHEERDER\" type=\"string\"/>' +\n            '          <element name=\"LENGTH\" type=\"string\"/>' +\n            '          <element name=\"SHAPE\" type=\"string\"/>' +\n            '          <element name=\"SE_ANNO_CAD_DATA\" type=\"string\"/>' +\n            '        </sequence>' +\n            '      </extension>' +\n            '    </complexContent>' +\n            '  </complexType>' +\n            '</schema>';\n        var res = parser.read(text);\n\n        t.eq(res.featureTypes.length, 1,\n            \"There is only 1 typename, so length should be 1\");\n\n        t.eq(res.featureTypes[0].properties[0].type, 'gml:MultiLineStringPropertyType',\n            \"The first attribute is of type multi line string\");\n\n        t.eq(res.featureTypes[0].properties[2].name, 'ROUTE',\n            \"The third attribute is named ROUTE\");\n\n        t.eq(res.featureTypes[0].properties[2].type, 'string',\n            \"The third attribute is of type string\");\n\n        // three typeNames in one response from UMN Mapserver\n        text = \n            '<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>' +\n            '<schema' +\n            '   targetNamespace=\"http://mapserver.gis.umn.edu/mapserver\" ' +\n            '   xmlns:rws=\"http://mapserver.gis.umn.edu/mapserver\" ' +\n            '   xmlns:ogc=\"http://www.opengis.net/ogc\"' +\n            '   xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"' +\n            '   xmlns=\"http://www.w3.org/2001/XMLSchema\"' +\n            '   xmlns:gml=\"http://www.opengis.net/gml\"' +\n            '   elementFormDefault=\"qualified\" version=\"0.1\" >' +\n            '  <import namespace=\"http://www.opengis.net/gml\"' +\n            '          schemaLocation=\"http://schemas.opengis.net/gml/2.1.2/feature.xsd\" />' +\n            '  <element name=\"KGNAT.VKUNSTWERK\" ' +\n            '           type=\"rws:KGNAT.VKUNSTWERKType\" ' +\n            '           substitutionGroup=\"gml:_Feature\" />' +\n            '  <complexType name=\"KGNAT.VKUNSTWERKType\">' +\n            '    <complexContent>' +\n            '      <extension base=\"gml:AbstractFeatureType\">' +\n            '        <sequence>' +\n            '          <element name=\"geometry\" type=\"gml:MultiPolygonPropertyType\" minOccurs=\"0\" maxOccurs=\"1\"/>' +\n            '          <element name=\"OBJECTID\" type=\"string\"/>' +\n            '          <element name=\"OBJECTSUBCATEGORIE\" type=\"string\"/>' +\n            '          <element name=\"DIENSTCODE\" type=\"string\"/>' +\n            '          <element name=\"DISTRICTNAAM\" type=\"string\"/>' +\n            '          <element name=\"CODEBPN\" type=\"string\"/>' +\n            '          <element name=\"WSD\" type=\"string\"/>' +\n            '          <element name=\"SUBCAT\" type=\"string\"/>' +\n            '          <element name=\"ZIJDE\" type=\"string\"/>' +\n            '          <element name=\"KM\" type=\"string\"/>' +\n            '          <element name=\"ELEMENTCODE\" type=\"string\"/>' +\n            '          <element name=\"COMPLEXCODE\" type=\"string\"/>' +\n            '          <element name=\"BEHEEROBJECTCODE\" type=\"string\"/>' +\n            '          <element name=\"BEGINDATUM\" type=\"string\"/>' +\n            '          <element name=\"NAAMCONTACTPERSOON\" type=\"string\"/>' +\n            '          <element name=\"KMTOT\" type=\"string\"/>' +\n            '          <element name=\"HOOFDWATERSYSTEEM\" type=\"string\"/>' +\n            '          <element name=\"WATERSYSTEEMNAAM\" type=\"string\"/>' +\n            '          <element name=\"OBJECTNAAM\" type=\"string\"/>' +\n            '          <element name=\"HERKOMST\" type=\"string\"/>' +\n            '          <element name=\"BEHEERSREGIME\" type=\"string\"/>' +\n            '          <element name=\"VERSIE\" type=\"string\"/>' +\n            '          <element name=\"KWALITEITSNIVEAU\" type=\"string\"/>' +\n            '          <element name=\"STICHTINGSJAAR\" type=\"string\"/>' +\n            '          <element name=\"OBJECTTYPE\" type=\"string\"/>' +\n            '          <element name=\"OPMERKING\" type=\"string\"/>' +\n            '          <element name=\"OPPERVLAKTE\" type=\"string\"/>' +\n            '          <element name=\"SE_ANNO_CAD_DATA\" type=\"string\"/>' +\n            '          <element name=\"SHAPE\" type=\"string\"/>' +\n            '        </sequence>' +\n            '      </extension>' +\n            '    </complexContent>' +\n            '  </complexType>' +\n            '  <element name=\"KGNAT.LKUNSTWERK\" ' +\n            '           type=\"rws:KGNAT.LKUNSTWERKType\" ' +\n            '           substitutionGroup=\"gml:_Feature\" />' +\n            '  <complexType name=\"KGNAT.LKUNSTWERKType\">' +\n            '    <complexContent>' +\n            '      <extension base=\"gml:AbstractFeatureType\">' +\n            '        <sequence>' +\n            '          <element name=\"geometry\" type=\"gml:MultiLineStringPropertyType\" minOccurs=\"0\" maxOccurs=\"1\"/>' +\n            '          <element name=\"OBJECTID\" type=\"string\"/>' +\n            '          <element name=\"OBJECTSUBCATEGORIE\" type=\"string\"/>' +\n            '          <element name=\"DIENSTCODE\" type=\"string\"/>' +\n            '          <element name=\"DISTRICTNAAM\" type=\"string\"/>' +\n            '          <element name=\"CODEBPN\" type=\"string\"/>' +\n            '          <element name=\"WSD\" type=\"string\"/>' +\n            '          <element name=\"SUBCAT\" type=\"string\"/>' +\n            '          <element name=\"ZIJDE\" type=\"string\"/>' +\n            '          <element name=\"KM\" type=\"string\"/>' +\n            '          <element name=\"ELEMENTCODE\" type=\"string\"/>' +\n            '          <element name=\"COMPLEXCODE\" type=\"string\"/>' +\n            '          <element name=\"BEHEEROBJECTCODE\" type=\"string\"/>' +\n            '          <element name=\"BEGINDATUM\" type=\"string\"/>' +\n            '          <element name=\"NAAMCONTACTPERSOON\" type=\"string\"/>' +\n            '          <element name=\"KMTOT\" type=\"string\"/>' +\n            '          <element name=\"HOOFDWATERSYSTEEM\" type=\"string\"/>' +\n            '          <element name=\"WATERSYSTEEMNAAM\" type=\"string\"/>' +\n            '          <element name=\"OBJECTNAAM\" type=\"string\"/>' +\n            '          <element name=\"HERKOMST\" type=\"string\"/>' +\n            '          <element name=\"BEHEERSREGIME\" type=\"string\"/>' +\n            '          <element name=\"VERSIE\" type=\"string\"/>' +\n            '          <element name=\"KWALITEITSNIVEAU\" type=\"string\"/>' +\n            '          <element name=\"STICHTINGSJAAR\" type=\"string\"/>' +\n            '          <element name=\"OBJECTTYPE\" type=\"string\"/>' +\n            '          <element name=\"OPMERKING\" type=\"string\"/>' +\n            '          <element name=\"LENGTE\" type=\"string\"/>' +\n            '          <element name=\"SE_ANNO_CAD_DATA\" type=\"string\"/>' +\n            '          <element name=\"SHAPE\" type=\"string\"/>' +\n            '        </sequence>' +\n            '      </extension>' +\n            '    </complexContent>' +\n            '  </complexType>' +\n            '  <element name=\"KGNAT.PKUNSTWERK\" ' +\n            '           type=\"rws:KGNAT.PKUNSTWERKType\" ' +\n            '           substitutionGroup=\"gml:_Feature\" />' +\n            '  <complexType name=\"KGNAT.PKUNSTWERKType\">' +\n            '    <complexContent>' +\n            '      <extension base=\"gml:AbstractFeatureType\">' +\n            '        <sequence>' +\n            '          <element name=\"geometry\" type=\"gml:MultiPointPropertyType\" minOccurs=\"0\" maxOccurs=\"1\"/>' +\n            '          <element name=\"OBJECTID\" type=\"string\"/>' +\n            '          <element name=\"OBJECTSUBCATEGORIE\" type=\"string\"/>' +\n            '          <element name=\"DIENSTCODE\" type=\"string\"/>' +\n            '          <element name=\"DISTRICTNAAM\" type=\"string\"/>' +\n            '          <element name=\"CODEBPN\" type=\"string\"/>' +\n            '          <element name=\"WSD\" type=\"string\"/>' +\n            '          <element name=\"SUBCAT\" type=\"string\"/>' +\n            '          <element name=\"ZIJDE\" type=\"string\"/>' +\n            '          <element name=\"KM\" type=\"string\"/>' +\n            '          <element name=\"ELEMENTCODE\" type=\"string\"/>' +\n            '          <element name=\"COMPLEXCODE\" type=\"string\"/>' +\n            '          <element name=\"BEHEEROBJECTCODE\" type=\"string\"/>' +\n            '          <element name=\"BEGINDATUM\" type=\"string\"/>' +\n            '          <element name=\"NAAMCONTACTPERSOON\" type=\"string\"/>' +\n            '          <element name=\"KMTOT\" type=\"string\"/>' +\n            '          <element name=\"HOOFDWATERSYSTEEM\" type=\"string\"/>' +\n            '          <element name=\"WATERSYSTEEMNAAM\" type=\"string\"/>' +\n            '          <element name=\"OBJECTNAAM\" type=\"string\"/>' +\n            '          <element name=\"HERKOMST\" type=\"string\"/>' +\n            '          <element name=\"BEHEERSREGIME\" type=\"string\"/>' +\n            '          <element name=\"VERSIE\" type=\"string\"/>' +\n            '          <element name=\"KWALITEITSNIVEAU\" type=\"string\"/>' +\n            '          <element name=\"STICHTINGSJAAR\" type=\"string\"/>' +\n            '          <element name=\"OBJECTTYPE\" type=\"string\"/>' +\n            '          <element name=\"OPMERKING\" type=\"string\"/>' +\n            '          <element name=\"X\" type=\"string\"/>' +\n            '          <element name=\"Y\" type=\"string\"/>' +\n            '          <element name=\"SE_ANNO_CAD_DATA\" type=\"string\"/>' +\n            '          <element name=\"SHAPE\" type=\"string\"/>' +\n            '        </sequence>' +\n            '      </extension>' +\n            '    </complexContent>' +\n            '  </complexType>' +\n            '</schema>';\n\n        parser = new OpenLayers.Format.WFSDescribeFeatureType();\n        res = parser.read(text);\n\n        t.eq(res.featureTypes.length, 3,\n            \"There are 3 typenames, so length should be 3\");\n\n        t.eq(res.featureTypes[0].typeName, 'KGNAT.VKUNSTWERK',\n            \"There name of the first typename is KGNAT.VKUNSTWERK\");\n\n        t.eq(res.featureTypes[2].properties.length, 30,\n            \"We expect 30 attributes in the third typename\");\n\n        t.eq(res.featureTypes[2].properties[1].name, 'OBJECTID',\n            \"The second attribute has name OBJECTID\");\n\n        t.eq(res.featureTypes[2].properties[1].type, 'string',\n            \"The second attribute has type string\");\n\n        t.eq(res.targetNamespace, 'http://mapserver.gis.umn.edu/mapserver',\n            \"The targetNamespace should be http://mapserver.gis.umn.edu/mapserver\");\n\n        t.eq(res.targetPrefix, 'rws', \"the targetPrefix should be rws\");\n\n        // response from Ionic WFS, taken from:\n        // http://webservices.ionicsoft.com/ionicweb/wfs/BOSTON_ORA?service=WFS&request=DescribeFeatureType&version=1.0.0&typename=wfs:highways\n        text =\n            \"<?xml version='1.0' encoding='utf-8' ?>\" +\n            '  <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:wfs=\"http://www.ionicsoft.com/wfs\" targetNamespace=\"http://www.ionicsoft.com/wfs\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" elementFormDefault=\"qualified\" version=\"0.1\">' +\n            '    <xsd:import namespace=\"http://www.opengis.net/gml\" schemaLocation=\"http://schemas.opengis.net/gml/2.1.2/feature.xsd\"/>' +\n            '    <xsd:element name=\"highways\" substitutionGroup=\"gml:_Feature\" type=\"wfs:highways\"/>' +\n            '    <xsd:complexType name=\"highways\">' +\n            '      <xsd:complexContent>' +\n            '        <xsd:extension base=\"gml:AbstractFeatureType\">' +\n            '          <xsd:sequence>' +\n            '            <xsd:element name=\"ROUTE_\" minOccurs=\"0\" nillable=\"true\" type=\"xsd:int\"/>' +\n            '            <xsd:element name=\"ROUTE_ID\" minOccurs=\"0\" nillable=\"true\" type=\"xsd:int\"/>' +\n            '            <xsd:element name=\"RT_NUMBER\" minOccurs=\"0\" nillable=\"true\" type=\"xsd:string\"/>' +\n            '            <xsd:element name=\"GEOMETRY\" minOccurs=\"0\" nillable=\"true\" type=\"gml:GeometryAssociationType\"/>' +\n            '          </xsd:sequence>' +\n            '        </xsd:extension>' +\n            '      </xsd:complexContent>' +\n            '    </xsd:complexType>' +\n            '  </xsd:schema>';\n\n        parser = new OpenLayers.Format.WFSDescribeFeatureType();\n        res = parser.read(text);\n\n        t.eq(res.featureTypes.length, 1,\n            \"There is 1 typename, so length should be 1\");\n\n        t.eq(res.featureTypes[0].typeName, \"highways\",\n            \"The name of the typename is highways\");\n\n        t.eq(res.featureTypes[0].properties.length, 4,\n            \"We expect 4 attributes in the first typename\");\n\n        t.eq(res.featureTypes[0].properties[1].name, 'ROUTE_ID',\n            \"The second attribute has name ROUTE_ID\");\n\n        t.eq(res.featureTypes[0].properties[1].type, 'xsd:int',\n            \"The second attribute has type integer\");\n\n        t.eq(parseInt(res.featureTypes[0].properties[1].minOccurs), 0,\n            \"The second attribute has minOccurs 0\");\n\n        t.eq(res.targetNamespace, 'http://www.ionicsoft.com/wfs',\n            \"The targetNamespace should be http://www.ionicsoft.com/wfs\");\n\n        t.eq(res.targetPrefix, 'wfs', \"the targetPrefix should be wfs\");\n\n\n        // GeoServer tests\n        \n        function geoServerTests(text) {\n            parser = new OpenLayers.Format.WFSDescribeFeatureType();\n            res = parser.read(text);\n    \n            t.eq(res.featureTypes.length, 1,\n                \"There is 1 typename, so length should be 1\");\n    \n            t.eq(res.featureTypes[0].typeName, \"railroads\",\n                \"The name of the typeName is railroads\");\n    \n            t.eq(res.featureTypes[0].properties.length, 2,\n                \"We expect 2 attributes in the typename\");\n    \n            t.eq(res.featureTypes[0].properties[0].name, 'cat',\n                \"The first attribute has name cat\");\n    \n            t.eq(res.featureTypes[0].properties[0].type.split(\":\")[1], 'long',\n                \"The first attribute has type long with a prefix\");\n\n            t.eq(res.featureTypes[0].properties[0].localType, 'long',\n                \"The first attribute has localType long\");\n    \n            t.eq(res.targetNamespace, 'http://opengeo.org',\n                \"The targetNamespace should be http://opengeo.org\");\n    \n            t.eq(res.targetPrefix, 'opengeo', \"the targetPrefix should be opengeo\");\n        }\n        \n\n        // Read Geoserver WFS 1.0.0 response\n        // Taken from: http://demo.opengeo.org/geoserver/wfs?service=WFS&request=DescribeFeatureType&typename=opengeo:railroads&version=1.0.0\n        text = \n            '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n            '<xs:schema  targetNamespace=\"http://opengeo.org\"  xmlns:opengeo=\"http://opengeo.org\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" version=\"1.0\">' +\n            '  <xs:import namespace=\"http://www.opengis.net/gml\" schemaLocation=\"http://demo.opengeo.org:80/geoserver/schemas/gml/2.1.2.1/feature.xsd\"/>' + \n            '  <xs:complexType xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://www.w3.org/2001/XMLSchema\" name=\"railroads_Type\">' +\n            '    <xs:complexContent>' +\n            '      <xs:extension base=\"gml:AbstractFeatureType\">' +\n            '        <xs:sequence>' +\n            '          <xs:element name=\"cat\" minOccurs=\"0\" nillable=\"true\" type=\"xs:long\"/>' +\n            '          <xs:element name=\"the_geom\" minOccurs=\"0\" nillable=\"true\" type=\"gml:MultiLineStringPropertyType\"/>' +\n            '        </xs:sequence>' +\n            '      </xs:extension>' +\n            '    </xs:complexContent>' +\n            '  </xs:complexType>' +\n            '  <xs:element name=\"railroads\" type=\"opengeo:railroads_Type\" substitutionGroup=\"gml:_Feature\"/>' +\n            '</xs:schema>';\n\n        geoServerTests(text);\n        \n\n        // Read GeoServer WFS 1.1.0 response\n        // taken from http://demo.opengeo.org/geoserver/wfs?service=WFS&request=DescribeFeatureType&typename=opengeo:railroads&version=1.1.0\n        text = \n            '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n            '   <xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:opengeo=\"http://opengeo.org\" elementFormDefault=\"qualified\" targetNamespace=\"http://opengeo.org\">' +\n            '     <xsd:import namespace=\"http://www.opengis.net/gml\" schemaLocation=\"http://demo.opengeo.org:80/geoserver/wfs/schemas/gml/3.1.1/base/gml.xsd\"/>' +\n            '     <xsd:complexType name=\"railroadsType\">' +\n            '       <xsd:complexContent>' +\n            '         <xsd:extension base=\"gml:AbstractFeatureType\">' +\n            '           <xsd:sequence>' +\n            '             <xsd:element maxOccurs=\"1\" minOccurs=\"0\" name=\"cat\" nillable=\"true\" type=\"xsd:long\"/>' +\n            '             <xsd:element maxOccurs=\"1\" minOccurs=\"0\" name=\"the_geom\" nillable=\"true\" type=\"gml:MultiLineStringPropertyType\"/>' +\n            '           </xsd:sequence>' +\n            '         </xsd:extension>' +\n            '       </xsd:complexContent>' +\n            '     </xsd:complexType>' +\n            '     <xsd:element name=\"railroads\" substitutionGroup=\"gml:_Feature\" type=\"opengeo:railroadsType\"/>' +\n            '   </xsd:schema>';\n        \n        geoServerTests(text);\n        \n        // Another GeoServer response with type restrictions\n        // taken from http://sigma.openplans.org/geoserver/wfs?service=WFS&request=DescribeFeatureType&typename=topp:states&version=1.0.0\n        text = '<?xml version=\"1.0\" encoding=\"UTF-8\"?><xs:schema  targetNamespace=\"http://www.openplans.org/topp\"  xmlns:topp=\"http://www.openplans.org/topp\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" elementFormDefault=\"qualified\" attributeFormDefault=\"unqualified\" version=\"1.0\"><xs:import namespace=\"http://www.opengis.net/gml\" schemaLocation=\"http://sigma.openplans.org:80/geoserver/schemas/gml/2.1.2.1/feature.xsd\"/><xs:complexType xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"http://www.w3.org/2001/XMLSchema\" name=\"states_Type\"><xs:complexContent><xs:extension base=\"gml:AbstractFeatureType\"><xs:sequence><xs:element name=\"the_geom\" minOccurs=\"0\" nillable=\"true\" type=\"gml:MultiPolygonPropertyType\"/><xs:element name=\"STATE_NAME\" minOccurs=\"0\" nillable=\"true\"><xs:simpleType><xs:restriction base=\"xs:string\"><xs:maxLength value=\"25\"/></xs:restriction></xs:simpleType></xs:element><xs:element name=\"STATE_FIPS\" minOccurs=\"0\" nillable=\"true\"><xs:simpleType><xs:restriction base=\"xs:string\"><xs:maxLength value=\"2\"/></xs:restriction></xs:simpleType></xs:element><xs:element name=\"SUB_REGION\" minOccurs=\"0\" nillable=\"true\"><xs:simpleType><xs:restriction base=\"xs:string\"><xs:maxLength value=\"7\"/></xs:restriction></xs:simpleType></xs:element><xs:element name=\"STATE_ABBR\" minOccurs=\"0\" nillable=\"true\"><xs:simpleType><xs:restriction base=\"xs:string\"><xs:maxLength value=\"2\"/></xs:restriction></xs:simpleType></xs:element><xs:element name=\"LAND_KM\" minOccurs=\"0\" nillable=\"true\" type=\"xs:double\"/><xs:element name=\"WATER_KM\" minOccurs=\"0\" nillable=\"true\" type=\"xs:double\"/><xs:element name=\"PERSONS\" minOccurs=\"0\" nillable=\"true\" type=\"xs:double\"/><xs:element name=\"FAMILIES\" minOccurs=\"0\" nillable=\"true\" type=\"xs:double\"/><xs:element name=\"HOUSHOLD\" minOccurs=\"0\" nillable=\"true\" type=\"xs:double\"/><xs:element name=\"MALE\" minOccurs=\"0\" nillable=\"true\" type=\"xs:double\"/><xs:element name=\"FEMALE\" minOccurs=\"0\" nillable=\"true\" type=\"xs:double\"/><xs:element name=\"WORKERS\" minOccurs=\"0\" nillable=\"true\" type=\"xs:double\"/><xs:element name=\"DRVALONE\" minOccurs=\"0\" nillable=\"true\" type=\"xs:double\"/><xs:element name=\"CARPOOL\" minOccurs=\"0\" nillable=\"true\" type=\"xs:double\"/><xs:element name=\"PUBTRANS\" minOccurs=\"0\" nillable=\"true\" type=\"xs:double\"/><xs:element name=\"EMPLOYED\" minOccurs=\"0\" nillable=\"true\" type=\"xs:double\"/><xs:element name=\"UNEMPLOY\" minOccurs=\"0\" nillable=\"true\" type=\"xs:double\"/><xs:element name=\"SERVICE\" minOccurs=\"0\" nillable=\"true\" type=\"xs:double\"/><xs:element name=\"MANUAL\" minOccurs=\"0\" nillable=\"true\" type=\"xs:double\"/><xs:element name=\"P_MALE\" minOccurs=\"0\" nillable=\"true\" type=\"xs:double\"/><xs:element name=\"P_FEMALE\" minOccurs=\"0\" nillable=\"true\" type=\"xs:double\"/><xs:element name=\"SAMP_POP\" minOccurs=\"0\" nillable=\"true\" type=\"xs:double\"/></xs:sequence></xs:extension></xs:complexContent></xs:complexType><xs:element name=\"states\" type=\"topp:states_Type\" substitutionGroup=\"gml:_Feature\"/></xs:schema>';\n\n        parser = new OpenLayers.Format.WFSDescribeFeatureType();\n        res = parser.read(text);\n\n        t.eq(res.featureTypes[0].properties[1].name, \"STATE_NAME\",\n            \"name of 2nd property of 1st featureType should be 'STATE_NAME'\");\n        \n        t.eq(res.featureTypes[0].properties[1].type, \"xs:string\",\n            \"type of 2nd property of 1st featureType should be 'xs:string'\");\n\n        t.eq(res.featureTypes[0].properties[1].localType, \"string\",\n            \"localType of 2nd property of 1st featureType should be 'string'\");\n        \n        t.eq(res.featureTypes[0].properties[1].restriction.maxLength, \"25\",\n            \"the maxLength restriction should be 25\");\n    }\n    \n    function test_readRestriction(t) {\n        t.plan(2);\n        var text =\n            '<restriction xmlns=\"http://www.w3.org/2001/XMLSchema\" base=\"xs:string\">' +\n            '  <enumeration value=\"One\"/>' +\n            '  <enumeration value=\"Two\"/>' +\n            '</restriction>';\n        var doc = OpenLayers.Format.XML.prototype.read(text).documentElement;\n        var obj = {};\n        new OpenLayers.Format.WFSDescribeFeatureType().readRestriction(doc, obj);\n        \n        t.eq(obj.enumeration.length, 2, \"enumeration has a length of 2\");\n        t.eq(obj.enumeration[1], \"Two\", \"2nd enumeration value is 'Two'\");\n        // other functionality of readRestriction already tested in the last\n        // GeoServer example above\n    }\n\n    function test_read_exception(t) {\n        t.plan(1);\n        var text = \n            '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n            '<ows:ExceptionReport version=\"1.0.0\"' +\n            '  xsi:schemaLocation=\"http://www.opengis.net/ows http://localhost:8080/geoserver/schemas/ows/1.0.0/owsExceptionReport.xsd\"' +\n            '  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ows=\"http://www.opengis.net/ows\">' +\n            '  <ows:Exception exceptionCode=\"NoApplicableCode\">' +\n            '    <ows:ExceptionText>Could not find type: {http://geonode.org/}_map_4_annotations</ows:ExceptionText>' +\n            '  </ows:Exception>' +\n            '</ows:ExceptionReport>';\n        var format = new OpenLayers.Format.WFSDescribeFeatureType();\n        var obj = format.read(text);\n        t.ok(!!obj.error, \"Error reported correctly\");\n    }\n\n    function test_read_annotation(t) {\n        t.plan(2);\n        var text = \n            '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n            '<xsd:schema xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"' +\n            '  xmlns:analytics=\"http://opengeo.org/analytics\" xmlns:cite=\"http://www.opengeospatial.net/cite\"' +\n            '  xmlns:gml=\"http://www.opengis.net/gml\" xmlns:it.geosolutions=\"http://www.geo-solutions.it\"' +\n            '  xmlns:nurc=\"http://www.nurc.nato.int\" xmlns:og=\"http://opengeo.org\"' +\n            '  xmlns:sde=\"http://geoserver.sf.net\" xmlns:sf=\"http://www.openplans.org/spearfish\"' +\n            '  xmlns:tiger=\"http://www.census.gov\" xmlns:tike=\"http://opengeo.org/#tike\"' +\n            '  xmlns:topp=\"http://www.openplans.org/topp\" xmlns:usgs=\"http://www.usgs.gov/\"' +\n            '  xmlns:za=\"http://opengeo.org/za\" elementFormDefault=\"qualified\"' +\n            '  targetNamespace=\"http://www.openplans.org/topp\">' +\n            '  <xsd:import namespace=\"http://www.opengis.net/gml\"' +\n            '    schemaLocation=\"http://demo.opengeo.org/geoserver/schemas/gml/3.1.1/base/gml.xsd\"/>' +\n            '  <xsd:complexType name=\"statesType\">' +\n            '    <xsd:complexContent>' +\n            '      <xsd:extension base=\"gml:AbstractFeatureType\">' +\n            '        <xsd:sequence>' +\n            '          <xsd:element maxOccurs=\"1\" minOccurs=\"0\" name=\"PERSONS\" nillable=\"true\" type=\"xsd:double\">' +\n            '            <xsd:annotation>' +\n            '              <xsd:appinfo>{\"title\":{\"en\":\"Population\"}}</xsd:appinfo>' +\n            '              <xsd:documentation xml:lang=\"en\"> Number of persons living in the state' +\n            '              </xsd:documentation>' +\n            '            </xsd:annotation>' +\n            '          </xsd:element>' +\n            '        </xsd:sequence>' +\n            '      </xsd:extension>' +\n            '    </xsd:complexContent>' +\n            '  </xsd:complexType>' +\n            '  <xsd:element name=\"states\" substitutionGroup=\"gml:_Feature\" type=\"topp:statesType\"/>' +\n            '</xsd:schema>';\n        var format = new OpenLayers.Format.WFSDescribeFeatureType();\n        var res = format.read(text);\n        var property = res.featureTypes[0].properties[0];\n        t.eq(property.annotation.appinfo[0], '{\"title\":{\"en\":\"Population\"}}', \"appinfo read correctly\");\n        t.eq(property.annotation.documentation[0], {lang: \"en\", textContent: 'Number of persons living in the state'}, \"documentation read correctly\");\n    }\n\n    </script> \n</head> \n<body>\n</body> \n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WFST/v1.html",
    "content": "<html>\n<head>\n  <script src=\"../../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_read(t) {\n        t.plan(1);\n\n        var data = readXML(\"FeatureCollection\");\n        var format = new OpenLayers.Format.WFST({\n            featureNS: \"http://www.openplans.org/topp\",\n            featureType: \"states\"\n        });\n        var features = format.read(data);\n\n        t.eq(features.length, 1, \"number of features read from FeatureCollection is correct\");\n    }\n\n    function test_write(t) {\n\n        var format = new OpenLayers.Format.WFST({\n            featureNS: \"http://www.openplans.org/topp\",\n            featureType: \"states\",\n            featurePrefix: \"topp\",\n            geometryName: \"the_geom\"\n        });\n\n        var feature = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(1,2),\n            {foo: \"bar\"}\n        );\n\n        var insertFeature = feature.clone();\n        // null value does not show up in insert\n        insertFeature.attributes.nul = null;\n        insertFeature.state = OpenLayers.State.INSERT;\n        var updateFeature = feature.clone();\n        // undefined value means don't create a Property element\n        updateFeature.attributes.unwritten = undefined;\n        // null value gets Property element with no Value\n        updateFeature.attributes.nul = null;\n        updateFeature.fid = \"fid.42\";\n        updateFeature.state = OpenLayers.State.UPDATE;\n        var deleteFeature = feature.clone();\n        deleteFeature.state = OpenLayers.State.DELETE;\n        deleteFeature.fid = \"fid.37\";\n\n        t.plan(9);\n        var snippets = {\n            \"GetFeature\": {handle: \"handle_g\", viewParams: \"text:Test\", maxFeatures: 1, outputFormat: 'json'},\n            \"Transaction\": {handle: \"handle_t\"},\n            \"Insert\": {feature: insertFeature, options: {handle: \"handle_i\"}},\n            \"Update\": {feature: updateFeature, options: {handle: \"handle_u\"}},\n            \"Delete\": {feature: deleteFeature, options: {handle: \"handle_d\"}}\n        }\n\n        var arg;\n        for(var snippet in snippets) {\n            arg = snippets[snippet]\n            var expected = readXML(snippet);\n            var got = format.writers[\"wfs\"][snippet].apply(format, [arg]);\n            t.xml_eq(got, expected, snippet + \" request created correctly\");\n        }\n        \n        updateFeature.modified = {geometry: updateFeature.geometry.clone()};\n        updateFeature.geometry = new OpenLayers.Geometry.Point(2,3);\n        var expected = readXML(\"UpdateModified\");\n        var got = format.writers[\"wfs\"][\"Update\"].apply(format, [{feature: updateFeature}]);\n        t.xml_eq(got, expected, \"Update request for feature with modified geometry created correctly\");\n        \n        updateFeature.modified.attributes = {foo: \"bar\"};\n        updateFeature.attributes.foo = \"baz\";\n        delete updateFeature.modified.geometry;\n        var expected = readXML(\"UpdateModifiedNoGeometry\");\n        var got = format.writers[\"wfs\"][\"Update\"].apply(format, [{feature: updateFeature}]);\n        t.xml_eq(got, expected, \"Update request for feature with no modified geometry but modified attributes created correctly\");\n\n        // test for a feature that originally had a null geometry and a null value for the attribute\n        updateFeature.modified = {attributes: {foo: null, nul: \"nul\"}, geometry: null};\n        updateFeature.attributes.foo = \"bar\";\n        updateFeature.geometry = new OpenLayers.Geometry.Point(2,3);\n        var expected = readXML(\"UpdateModified\");\n        var got = format.writers[\"wfs\"][\"Update\"].apply(format, [{feature: updateFeature}]);\n        t.xml_eq(got, expected, \"Update request for feature with modified geometry created correctly even if original geometry was null\");\n\n        updateFeature.modified.attributes = {foo: undefined};\n        updateFeature.attributes.foo = \"baz\";\n        delete updateFeature.modified.geometry;\n        var expected = readXML(\"UpdateModifiedNoGeometry\");\n        var got = format.writers[\"wfs\"][\"Update\"].apply(format, [{feature: updateFeature}]);\n        t.xml_eq(got, expected, \"Update request for feature with no modified geometry but modified attributes with undefined created correctly\");\n    }\n\n    function test_writeNative(t) {\n        t.plan(1);\n        var format = new OpenLayers.Format.WFST({\n            featureNS: \"http://www.openplans.org/topp\",\n            featureType: \"states\",\n            version: \"1.1.0\",\n            featurePrefix: \"topp\",\n            geometryName: null\n        });\n        var output = format.write(null, {nativeElements: [\n            {\n                vendorId: \"ORACLE\",\n                safeToIgnore: true,\n                value: \"ALTER SESSION ENABLE PARALLEL DML\"\n            }, {\n                vendorId: \"ORACLE\",\n                safeToIgnore: false,\n                value: \"Another native line goes here\"\n            }]\n        });\n        var expected = '<wfs:Transaction xmlns:wfs=\"http://www.opengis.net/wfs\" service=\"WFS\" version=\"1.1.0\" xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><wfs:Native vendorId=\"ORACLE\" safeToIgnore=\"true\">ALTER SESSION ENABLE PARALLEL DML</wfs:Native><wfs:Native vendorId=\"ORACLE\" safeToIgnore=\"false\">Another native line goes here</wfs:Native></wfs:Transaction>';\n        t.xml_eq(output, expected, \"Native elements written out correctly\");\n    }\n\n    function test_write_no_geometry(t) {\n        var format = new OpenLayers.Format.WFST({\n            featureNS: \"http://www.openplans.org/topp\",\n            featureType: \"states\",\n            featurePrefix: \"topp\",\n            geometryName: null\n        });\n\n        var feature = new OpenLayers.Feature.Vector(null, {foo: \"bar\"});\n        feature.state = OpenLayers.State.UPDATE;\n        feature.fid = \"fid.36\";\n\n        t.plan(1);\n        var snippets = {\n            \"UpdateNoGeometry\": {feature: feature}\n        }\n\n        var arg;\n        for(var snippet in snippets) {\n            arg = snippets[snippet]\n            var expected = readXML(snippet);\n            var got = format.writers[\"wfs\"][\"Update\"].apply(format, [arg]);\n            t.xml_eq(got, expected, snippet + \" request without geometry created correctly\");\n        }\n    }\n    \n    function test_setFilterProperty(t) {\n        t.plan(2);\n        var format = new OpenLayers.Format.WFST({\n            geometryName: \"foo\"\n        });\n        var filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.AND,\n            filters: [new OpenLayers.Filter.Spatial({\n                type: OpenLayers.Filter.Spatial.BBOX,\n                value: new OpenLayers.Bounds(1,2,3,4)\n            }), new OpenLayers.Filter.Spatial({\n                type: OpenLayers.Filter.Spatial.DWITHIN,\n                property: \"bar\",\n                value: new OpenLayers.Geometry.Point(1,2),\n                distance: 10\n            })]\n        });\n        format.setFilterProperty(filter);\n        t.eq(filter.filters[0].property, \"foo\", \"property set if not set on filter\");\n        t.eq(filter.filters[1].property, \"bar\", \"property not set if set on filter\");\n    }\n\n    function test_update_null_geometry(t) {\n        var format = new OpenLayers.Format.WFST({\n            featureNS: \"http://www.openplans.org/topp\",\n            featureType: \"states\",\n            featurePrefix: \"topp\",\n            geometryName: \"the_geom\"\n        });\n\n        var feature = new OpenLayers.Feature.Vector(null, {foo: \"bar\"});\n        feature.state = OpenLayers.State.UPDATE;\n        feature.fid = \"fid.36\";\n\n        t.plan(1);\n        var snippets = {\n            \"UpdateNullGeometry\": {feature: feature}\n        };\n\n        var arg;\n        for (var snippet in snippets) {\n            arg = snippets[snippet]\n            var expected = readXML(snippet);\n            var got = format.writers[\"wfs\"][\"Update\"].apply(format, [arg]);\n            t.xml_eq(got, expected, snippet + \" request with null geometry created correctly\");\n        }\n    }\n\n    function test_write_multiple(t) {\n\n        var format = new OpenLayers.Format.WFST({\n            featureNS: \"http://www.openplans.org/topp\",\n            featureType: [\"states\", \"cities\"],\n            featurePrefix: \"topp\",\n            geometryName: \"the_geom\"\n        });\n\n        t.plan(1);\n        var snippets = {\n            \"GetFeatureMultiple\": {}\n        }\n        \n        var arg;\n        for(var snippet in snippets) {\n            arg = snippets[snippet]\n            var expected = readXML(snippet);\n            var got = format.writers[\"wfs\"][\"GetFeature\"].apply(format, [arg]);\n            t.xml_eq(got, expected, snippet + \" request created correctly with multiple typenames\");\n        }\n    }\n    \n    function test_write_multi(t) {\n        t.plan(2);\n        var format = new OpenLayers.Format.WFST({\n            featureNS: \"http://www.openplans.org/topp\",\n            featureType: \"states\",\n            featurePrefix: \"topp\",\n            geometryName: \"the_geom\"\n        });\n\n        var feature = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(1,2),\n            {foo: \"bar\"}\n        );\n\n        var insertFeature = feature.clone();\n        // null value does not show up in insert\n        insertFeature.attributes.nul = null;\n        insertFeature.state = OpenLayers.State.INSERT;\n        var updateFeature = feature.clone();\n        // undefined value means don't create a Property element\n        updateFeature.attributes.unwritten = undefined;\n        // null value gets Property element with no Value\n        updateFeature.attributes.nul = null;\n        updateFeature.fid = \"fid.42\";\n        updateFeature.state = OpenLayers.State.UPDATE;\n        var features = [insertFeature, updateFeature];\n\n        var expected = readXML(\"TransactionMulti\");\n        var geomTypes = OpenLayers.Util.extend({}, format.geometryTypes);\n        var got = format.writers[\"wfs\"][\"Transaction\"].apply(format, [{\n            features: features,\n            options: {multi: true}}\n        ]);\n        t.xml_eq(got, expected, \"Transaction request with multi option created correctly\");\n        t.eq(format.geometryTypes, geomTypes, \"geometry types unchanged after write with multi option\");\n    }\n\n    function readXML(id) {\n        var xml = document.getElementById(id).firstChild.nodeValue;\n        return new OpenLayers.Format.XML().read(xml).documentElement;\n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:512px; height:256px\"> </div>\n\n<div id=\"FeatureCollection\"><!--\n<wfs:FeatureCollection xmlns:wfs=\"http://www.opengis.net/wfs\" xmlns:topp=\"http://www.openplans.org/topp\" xmlns:gml=\"http://www.opengis.net/gml\">\n    <gml:featureMember>\n        <topp:states fid=\"states.3\">\n            <topp:the_geom>\n                <gml:MultiPolygon srsName=\"http://www.opengis.net/gml/srs/epsg.xml#4326\">\n                    <gml:polygonMember>\n                        <gml:Polygon>\n                            <gml:outerBoundaryIs>\n                                <gml:LinearRing>\n                                    <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">-75.70742,38.557476 -75.71106,38.649551 -75.724937,38.83017 -75.752922,39.141548 -75.761658,39.247753 -75.764664,39.295849 -75.772697,39.383007 -75.791435,39.723755 -75.775269,39.724442 -75.745934,39.774818 -75.695114,39.820347 -75.644341,39.838196 -75.583794,39.840008 -75.470345,39.826435 -75.42083,39.79887 -75.412117,39.789658 -75.428009,39.77813 -75.460754,39.763248 -75.475128,39.741718 -75.476334,39.719971 -75.489639,39.714745 -75.610725,39.612793 -75.562996,39.566723 -75.590187,39.463768 -75.515572,39.36694 -75.402481,39.257637 -75.397728,39.073036 -75.324852,39.012386 -75.307899,38.945911 -75.190941,38.80867 -75.083138,38.799812 -75.045998,38.44949 -75.068298,38.449963 -75.093094,38.450451 -75.350204,38.455208 -75.69915,38.463066 -75.70742,38.557476</gml:coordinates>\n                                </gml:LinearRing>\n                            </gml:outerBoundaryIs>\n                        </gml:Polygon>\n                    </gml:polygonMember>\n                </gml:MultiPolygon>\n            </topp:the_geom>\n            <topp:STATE_NAME>Delaware</topp:STATE_NAME>\n            <topp:STATE_FIPS>10</topp:STATE_FIPS>\n            <topp:SUB_REGION>S Atl</topp:SUB_REGION>\n            <topp:STATE_ABBR>DE</topp:STATE_ABBR>\n            <topp:LAND_KM>5062.456</topp:LAND_KM>\n            <topp:WATER_KM>1385.022</topp:WATER_KM>\n            <topp:PERSONS>666168.0</topp:PERSONS>\n            <topp:FAMILIES>175867.0</topp:FAMILIES>\n            <topp:HOUSHOLD>247497.0</topp:HOUSHOLD>\n            <topp:MALE>322968.0</topp:MALE>\n            <topp:FEMALE>343200.0</topp:FEMALE>\n            <topp:WORKERS>247566.0</topp:WORKERS>\n            <topp:DRVALONE>258087.0</topp:DRVALONE>\n            <topp:CARPOOL>42968.0</topp:CARPOOL>\n            <topp:PUBTRANS>8069.0</topp:PUBTRANS>\n            <topp:EMPLOYED>335147.0</topp:EMPLOYED>\n            <topp:UNEMPLOY>13945.0</topp:UNEMPLOY>\n            <topp:SERVICE>87973.0</topp:SERVICE>\n            <topp:MANUAL>44140.0</topp:MANUAL>\n            <topp:P_MALE>0.485</topp:P_MALE>\n            <topp:P_FEMALE>0.515</topp:P_FEMALE>\n            <topp:SAMP_POP>102776.0</topp:SAMP_POP>\n        </topp:states>\n    </gml:featureMember>\n</wfs:FeatureCollection>\n--></div>\n\n<div id=\"GetFeature\"><!--\n<wfs:GetFeature xmlns:wfs=\"http://www.opengis.net/wfs\" service=\"WFS\" version=\"1.0.0\" viewParams=\"text:Test\" handle=\"handle_g\" outputFormat=\"json\" maxFeatures=\"1\" xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n    <wfs:Query typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\"/>\n</wfs:GetFeature>\n--></div>\n<div id=\"GetFeatureMultiple\"><!--\n<wfs:GetFeature xmlns:wfs=\"http://www.opengis.net/wfs\" service=\"WFS\" version=\"1.0.0\" xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n    <wfs:Query typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\"/>\n    <wfs:Query typeName=\"topp:cities\" xmlns:topp=\"http://www.openplans.org/topp\"/>\n</wfs:GetFeature>\n--></div>\n<div id=\"Transaction\"><!--\n<wfs:Transaction xmlns:wfs=\"http://www.opengis.net/wfs\" service=\"WFS\" version=\"1.0.0\"/>\n--></div>\n<div id=\"TransactionMulti\"><!--\n<wfs:Transaction xmlns:wfs=\"http://www.opengis.net/wfs\" service=\"WFS\" version=\"1.0.0\">\n    <wfs:Insert>\n        <feature:states xmlns:feature=\"http://www.openplans.org/topp\">\n            <feature:the_geom>\n                <gml:MultiPoint xmlns:gml=\"http://www.opengis.net/gml\">\n                    <gml:pointMember>\n                        <gml:Point>\n                            <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2</gml:coordinates>\n                        </gml:Point>\n                    </gml:pointMember>\n                </gml:MultiPoint>\n            </feature:the_geom>\n            <feature:foo>bar</feature:foo>\n        </feature:states>\n    </wfs:Insert>\n    <wfs:Update xmlns:wfs=\"http://www.opengis.net/wfs\" typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\">\n        <wfs:Property>\n            <wfs:Name>the_geom</wfs:Name>\n            <wfs:Value>\n                <gml:MultiPoint xmlns:gml=\"http://www.opengis.net/gml\">\n                    <gml:pointMember>\n                        <gml:Point>\n                            <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2</gml:coordinates>\n                        </gml:Point>\n                    </gml:pointMember>\n                </gml:MultiPoint>\n            </wfs:Value>\n        </wfs:Property>\n        <wfs:Property>\n            <wfs:Name>foo</wfs:Name>\n            <wfs:Value>bar</wfs:Value>\n        </wfs:Property>\n        <wfs:Property>\n            <wfs:Name>nul</wfs:Name>\n        </wfs:Property>\n        <ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n            <ogc:FeatureId fid=\"fid.42\"/>\n        </ogc:Filter>\n    </wfs:Update>\n</wfs:Transaction>\n--></div>\n<div id=\"Insert\"><!--\n<wfs:Insert xmlns:wfs=\"http://www.opengis.net/wfs\" handle=\"handle_i\">\n    <feature:states xmlns:feature=\"http://www.openplans.org/topp\">\n        <feature:the_geom>\n            <gml:Point xmlns:gml=\"http://www.opengis.net/gml\">\n                <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2</gml:coordinates>\n            </gml:Point>\n        </feature:the_geom>\n        <feature:foo>bar</feature:foo>\n    </feature:states>\n</wfs:Insert>\n--></div>\n<div id=\"Update\"><!--\n<wfs:Update xmlns:wfs=\"http://www.opengis.net/wfs\" handle=\"handle_u\" typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\">\n    <wfs:Property>\n        <wfs:Name>the_geom</wfs:Name>\n        <wfs:Value>\n            <gml:Point xmlns:gml=\"http://www.opengis.net/gml\">\n                <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2</gml:coordinates>\n            </gml:Point>\n        </wfs:Value>\n    </wfs:Property>\n    <wfs:Property>\n        <wfs:Name>foo</wfs:Name>\n        <wfs:Value>bar</wfs:Value>\n    </wfs:Property>\n    <wfs:Property>\n        <wfs:Name>nul</wfs:Name>\n    </wfs:Property>\n    <ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n        <ogc:FeatureId fid=\"fid.42\"/>\n    </ogc:Filter>\n</wfs:Update>\n--></div>\n<div id=\"UpdateModified\"><!--\n<wfs:Update xmlns:wfs=\"http://www.opengis.net/wfs\" typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\">\n    <wfs:Property>\n        <wfs:Name>the_geom</wfs:Name>\n        <wfs:Value>\n            <gml:Point xmlns:gml=\"http://www.opengis.net/gml\">\n                <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">2,3</gml:coordinates>\n            </gml:Point>\n        </wfs:Value>\n    </wfs:Property>\n    <wfs:Property>\n        <wfs:Name>foo</wfs:Name>\n        <wfs:Value>bar</wfs:Value>\n    </wfs:Property>\n    <wfs:Property>\n        <wfs:Name>nul</wfs:Name>\n    </wfs:Property>\n    <ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n        <ogc:FeatureId fid=\"fid.42\"/>\n    </ogc:Filter>\n</wfs:Update>\n--></div>\n<div id=\"UpdateModifiedNoGeometry\"><!--\n<wfs:Update xmlns:wfs=\"http://www.opengis.net/wfs\" typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\">\n    <wfs:Property>\n        <wfs:Name>foo</wfs:Name>\n        <wfs:Value>baz</wfs:Value>\n    </wfs:Property>\n    <ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n        <ogc:FeatureId fid=\"fid.42\"/>\n    </ogc:Filter>\n</wfs:Update>\n--></div>\n<div id=\"Delete\"><!--\n<wfs:Delete xmlns:wfs=\"http://www.opengis.net/wfs\" handle=\"handle_d\" typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\">\n    <ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n        <ogc:FeatureId fid=\"fid.37\"/>\n    </ogc:Filter>\n</wfs:Delete>\n--></div>\n<div id=\"UpdateNoGeometry\"><!--\n<wfs:Update xmlns:wfs=\"http://www.opengis.net/wfs\" typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\">\n    <wfs:Property>\n        <wfs:Name>foo</wfs:Name>\n        <wfs:Value>bar</wfs:Value>\n    </wfs:Property>\n    <ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n        <ogc:FeatureId fid=\"fid.36\"/>\n    </ogc:Filter>\n</wfs:Update>\n--></div>\n<div id=\"UpdateNullGeometry\"><!--\n<wfs:Update xmlns:wfs=\"http://www.opengis.net/wfs\" typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\">\n    <wfs:Property>\n        <wfs:Name>the_geom</wfs:Name>\n    </wfs:Property>\n    <wfs:Property>\n        <wfs:Name>foo</wfs:Name>\n        <wfs:Value>bar</wfs:Value>\n    </wfs:Property>\n    <ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n        <ogc:FeatureId fid=\"fid.36\"/>\n    </ogc:Filter>\n</wfs:Update>\n--></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WFST/v1_0_0.html",
    "content": "<html>\n<head>\n  <script src=\"../../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(1);\n\n        var format = new OpenLayers.Format.WFST.v1_0_0({});\n        t.ok(format instanceof OpenLayers.Format.WFST.v1_0_0, \"constructor returns instance\");\n    }\n    \n    function test_read(t) {\n        t.plan(3);\n        \n        var data = readXML(\"Transaction_Response\");        \n        var format = new OpenLayers.Format.WFST.v1_0_0({\n            featureNS: \"http://www.openplans.org/topp\",\n            featureType: \"states\"\n        });\n        var result = format.read(data);\n        t.eq(result.insertIds[0], \"parcelle.40\", \"First InsertId read correctly\");\n        t.eq(result.insertIds[1], \"parcelle.41\", \"Second InsertId read correctly\");\n        t.eq(result.success, true, \"Success read correctly\");\n    }\n    \n    function test_write(t) {\n\n        var format = new OpenLayers.Format.WFST.v1_0_0({\n            featureNS: \"http://www.openplans.org/topp\",\n            featureType: \"states\",\n            featurePrefix: \"topp\",\n            geometryName: \"the_geom\"\n        });\n\n        var cases = [{\n            id: \"query0\",\n            writer: \"wfs:Query\",\n            arg: {\n                filter: new OpenLayers.Filter.Spatial({\n                    type: OpenLayers.Filter.Spatial.BBOX,\n                    value: new OpenLayers.Bounds (1,2,3,4)\n                })\n            }\n        }, {\n            id: \"query1\",\n            writer: \"wfs:Query\",\n            arg: {\n                srsNameInQuery: true,\n                srsName: \"EPSG:900913\"\n            }\n        }, {\n            id: \"getfeature0\",\n            writer: \"wfs:GetFeature\",\n            arg: {\n                propertyNames: [\"STATE_NAME\", \"STATE_FIPS\", \"STATE_ABBR\"]\n            }\n        }];\n        \n        t.plan(cases.length);\n        \n        var test, got, exp;\n        for(var i=0; i<cases.length; ++i) {\n            test = cases[i];\n            exp = readXML(test.id);\n            got = format.writeNode(test.writer, test.arg);\n            t.xml_eq(got, exp, test.id + \": correct request\");\n        }\n\n    }\n    \n    function test_write_poorconfig(t) {\n        t.plan(1);\n        var format = new OpenLayers.Format.WFST.v1_0_0({\n            featureType: \"states\",\n            featurePrefix: \"topp\"\n        });\n        var exp = \"topp:states\";\n        var got = format.writeNode(\"wfs:Query\").getAttribute(\"typeName\");\n        t.eq(got, exp, \"Query without featureNS but with featurePrefix queries for the correct featureType\");\n    }\n\n    var xmlFormat = new OpenLayers.Format.XML();\n    function readXML(id) {\n        var xml = document.getElementById(id).firstChild.nodeValue;\n        return xmlFormat.read(xml).documentElement;        \n    }\n\n  </script>\n</head>\n<body>\n<div id=\"Transaction_Response\"><!--\n<wfs:WFS_TransactionResponse version=\"1.0.0\" xmlns:wfs=\"http://www.opengis.net/wfs\" xmlns:ogc=\"http://www.opengis.net/ogc\">\n    <wfs:InsertResult>\n        <ogc:FeatureId fid=\"parcelle.40\"/>\n        <ogc:FeatureId fid=\"parcelle.41\"/>\n    </wfs:InsertResult>\n    <wfs:TransactionResult>\n        <wfs:Status>\n            <wfs:SUCCESS/>\n        </wfs:Status>\n    </wfs:TransactionResult>\n</wfs:WFS_TransactionResponse>\n--></div>\n<div id=\"query0\"><!--\n<wfs:Query xmlns:wfs=\"http://www.opengis.net/wfs\" typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\">\n    <ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n        <ogc:BBOX>\n            <ogc:PropertyName>the_geom</ogc:PropertyName>\n            <gml:Box xmlns:gml=\"http://www.opengis.net/gml\">\n                <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">1,2 3,4</gml:coordinates>\n            </gml:Box>\n        </ogc:BBOX>\n    </ogc:Filter>\n</wfs:Query>\n--></div>\n<div id=\"query1\"><!--\n<wfs:Query xmlns:wfs=\"http://www.opengis.net/wfs\" typeName=\"topp:states\" srsName=\"EPSG:900913\" xmlns:topp=\"http://www.openplans.org/topp\">\n</wfs:Query>\n--></div>\n<div id=\"getfeature0\"><!--\n<wfs:GetFeature service=\"WFS\" version=\"1.0.0\" xmlns:topp=\"http://www.openplans.org/topp\"\n                xmlns:wfs=\"http://www.opengis.net/wfs\"\n                xmlns:ogc=\"http://www.opengis.net/ogc\"\n                xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n                xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd\">\n    <wfs:Query xmlns:wfs=\"http://www.opengis.net/wfs\" typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\">\n        <ogc:PropertyName>STATE_NAME</ogc:PropertyName>\n        <ogc:PropertyName>STATE_FIPS</ogc:PropertyName>\n        <ogc:PropertyName>STATE_ABBR</ogc:PropertyName>\n    </wfs:Query>\n</wfs:GetFeature>\n--></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WFST/v1_1_0.html",
    "content": "<html>\n<head>\n  <script src=\"../../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(1);\n\n        var format = new OpenLayers.Format.WFST.v1_1_0({});\n        t.ok(format instanceof OpenLayers.Format.WFST.v1_1_0, \"constructor returns instance\");\n    }\n    \n    function test_read(t) {\n        t.plan(3);\n        \n        var data = readXML(\"TransactionResponse\");        \n        var format = new OpenLayers.Format.WFST.v1_1_0({\n            featureNS: \"http://www.openplans.org/topp\",\n            featureType: \"states\"\n        });\n        var result = format.read(data);\n        t.eq(result.insertIds[0], \"parcelle.40\", \"First InsertId read correctly\");\n        t.eq(result.insertIds[1], \"parcelle.41\", \"Second InsertId read correctly\");\n        t.eq(result.success, true, \"Success read correctly\");\n    }\n\n    function test_read_hits(t) {\n        t.plan(1);\n        var data = readXML(\"NumberOfFeatures\");\n        var format = new OpenLayers.Format.WFST.v1_1_0({\n            featureNS: \"http://mapserver.gis.umn.edu/mapserver\",\n            featureType: \"AAA64\"\n        });\n        var result = format.read(data, {output: \"object\"});\n        t.eq(result.numberOfFeatures, 625, \"numberOfFeatures of FeatureCollection correctly read\");\n    }\n\n    function test_read_boundedBy(t) {\n        t.plan(4);\n        var data = readXML(\"boundedBy\");\n        var format = new OpenLayers.Format.WFST.v1_1_0({\n            featureNS: \"http://mapserver.gis.umn.edu/mapserver\",\n            featureType: \"AAA212\"\n        });\n        var result = format.read(data, {output: \"object\"});\n        var bounds = result.bounds;\n        t.eq(bounds.left.toFixed(3), '3197.880', \"Left bounds of the feature collection correctly parsed\");\n        t.eq(bounds.bottom.toFixed(3), '306457.313', \"Bottom bounds of the feature collection correctly parsed\");\n        t.eq(bounds.right.toFixed(3), '280339.156', \"Right bounds of the feature collection correctly parsed\");\n        t.eq(bounds.top.toFixed(3), '613850.438', \"Top bounds of the feature collection corectly parsed\");\n    }\n\n    function test_write(t) {\n\n        var format = new OpenLayers.Format.WFST.v1_1_0({\n            featureNS: \"http://www.openplans.org/topp\",\n            featureType: \"states\",\n            featurePrefix: \"topp\",\n            srsName: \"urn:ogc:def:crs:EPSG::4326\",\n            geometryName: \"the_geom\"\n        });\n\n        var cases = [{\n            id: \"query0\",\n            writer: \"wfs:Query\",\n            arg: {\n                filter: new OpenLayers.Filter.Spatial({\n                    type: OpenLayers.Filter.Spatial.BBOX,\n                    value: new OpenLayers.Bounds (1,2,3,4)\n                })\n            }\n        }, {\n            id: \"getfeature0\",\n            writer: \"wfs:GetFeature\",\n            arg: {\n                resultType: \"hits\",\n                propertyNames: [\"STATE_NAME\", \"STATE_FIPS\", \"STATE_ABBR\"]\n            }\n        }, {\n            id: \"getfeature1\",\n            writer: \"wfs:GetFeature\",\n            arg: {\n                count: 10,\n                startIndex: 20\n            }\n        }];\n        \n        t.plan(cases.length);\n        \n        var test, got, exp;\n        for(var i=0; i<cases.length; ++i) {\n            test = cases[i];\n            exp = readXML(test.id);\n            got = format.writeNode(test.writer, test.arg);\n            t.xml_eq(got, exp, test.id + \": correct request\");\n        }\n    }\n\n    function test_write_poorconfig(t) {\n        t.plan(1);\n        var format = new OpenLayers.Format.WFST.v1_1_0({\n            featureType: \"states\",\n            featurePrefix: \"topp\"\n        });\n        var exp = \"topp:states\";\n        var got = format.writeNode(\"wfs:Query\").getAttribute(\"typeName\");\n        t.eq(got, exp, \"Query without featureNS but with featurePrefix queries for the correct featureType\");\n    }\n\n    function test_write_schemaLocation(t) {\n        t.plan(1);\n        var format = new OpenLayers.Format.WFST.v1_1_0({\n            featureNS: \"http://www.openplans.org/topp\",\n            featureType: \"states\",\n            featurePrefix: \"topp\",\n            srsName: \"urn:ogc:def:crs:EPSG::4326\",\n            geometryName: \"the_geom\",\n            schema: \"http://foo.bar/topp_schema.xsd\"\n        });\n        var exp = readXML(\"schemaLocation\");\n        var got = format.writeNode(\"wfs:GetFeature\");\n        t.xml_eq(got, exp, \"schemaLocation correctly written\");\n    }\n\n    function test_write_schemaLocationDefaultPrefix(t) {\n        t.plan(1);\n        var format = new OpenLayers.Format.WFST.v1_1_0({\n            featureNS: \"http://www.openplans.org/topp\",\n            featureType: \"states\",\n            srsName: \"urn:ogc:def:crs:EPSG::4326\",\n            geometryName: \"the_geom\",\n            schema: \"http://foo.bar/topp_schema.xsd\"\n        });\n        var exp = readXML(\"schemaLocationDefaultPrefix\");\n        var got = format.writeNode(\"wfs:GetFeature\");\n        t.xml_eq(got, exp, \"schemaLocation correctly written\", {prefix:true});\n    }\n\n    var xmlFormat = new OpenLayers.Format.XML();\n    function readXML(id) {\n        var xml = document.getElementById(id).firstChild.nodeValue;\n        return xmlFormat.read(xml).documentElement;        \n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:512px; height:256px\"> </div>\n<div id=\"NumberOfFeatures\"><!--\n<?xml version='1.0' encoding=\"ISO-8859-1\" ?>\n<wfs:FeatureCollection\n   xmlns:rws=\"http://mapserver.gis.umn.edu/mapserver\"\n   xmlns:gml=\"http://www.opengis.net/gml\"\n   xmlns:wfs=\"http://www.opengis.net/wfs\"\n   xmlns:ogc=\"http://www.opengis.net/ogc\"\n   xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n   xsi:schemaLocation=\"http://mapserver.gis.umn.edu/mapserver http://intranet.rijkswaterstaat.nl/services/geoservices/nwb_wegen?SERVICE=WFS&amp;VERSION=1.1.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=feature:AAA64&amp;OUTPUTFORMAT=text/xml; subtype=gml/3.1.1  http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd\" numberOfFeatures=\"625\">\n</wfs:FeatureCollection>\n--></div>\n<div id=\"TransactionResponse\"><!--\n<wfs:TransactionResponse version=\"1.1.0\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:tiger=\"http://www.census.gov\" xmlns:wfs=\"http://www.opengis.net/wfs\" xmlns:topp=\"http://www.openplans.org/topp\" xmlns:sf=\"http://www.openplans.org/spearfish\" xmlns:ows=\"http://www.opengis.net/ows\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n    <wfs:TransactionSummary>\n        <wfs:totalInserted>0</wfs:totalInserted>\n        <wfs:totalUpdated>1</wfs:totalUpdated>\n        <wfs:totalDeleted>0</wfs:totalDeleted>\n    </wfs:TransactionSummary>\n    <wfs:TransactionResults/>\n    <wfs:InsertResults>\n        <wfs:Feature>\n            <ogc:FeatureId fid=\"parcelle.40\"/>\n        </wfs:Feature>\n        <wfs:Feature>\n            <ogc:FeatureId fid=\"parcelle.41\"/>\n        </wfs:Feature>\n    </wfs:InsertResults>\n</wfs:TransactionResponse>\n--></div>\n<div id=\"query0\"><!--\n<wfs:Query xmlns:wfs=\"http://www.opengis.net/wfs\" typeName=\"topp:states\" srsName=\"urn:ogc:def:crs:EPSG::4326\" xmlns:topp=\"http://www.openplans.org/topp\">\n    <ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n        <ogc:BBOX>\n            <ogc:PropertyName>the_geom</ogc:PropertyName>\n            <gml:Envelope xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"urn:ogc:def:crs:EPSG::4326\">\n                <gml:lowerCorner>1 2</gml:lowerCorner>\n                <gml:upperCorner>3 4</gml:upperCorner>\n            </gml:Envelope>\n        </ogc:BBOX>\n    </ogc:Filter>\n</wfs:Query>\n--></div>\n<div id=\"getfeature0\"><!--\n<wfs:GetFeature service=\"WFS\" version=\"1.1.0\" resultType=\"hits\" xmlns:topp=\"http://www.openplans.org/topp\"\n                xmlns:wfs=\"http://www.opengis.net/wfs\"\n                xmlns:ogc=\"http://www.opengis.net/ogc\"\n                xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n                xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd\">\n    <wfs:Query xmlns:wfs=\"http://www.opengis.net/wfs\" typeName=\"topp:states\" srsName=\"urn:ogc:def:crs:EPSG::4326\" xmlns:topp=\"http://www.openplans.org/topp\">\n        <wfs:PropertyName>STATE_NAME</wfs:PropertyName>\n        <wfs:PropertyName>STATE_FIPS</wfs:PropertyName>\n        <wfs:PropertyName>STATE_ABBR</wfs:PropertyName>\n    </wfs:Query>\n</wfs:GetFeature>\n--></div>\n<div id=\"getfeature1\"><!--\n<wfs:GetFeature service=\"WFS\" version=\"1.1.0\" startIndex=\"20\" count=\"10\" xmlns:topp=\"http://www.openplans.org/topp\"\n                xmlns:wfs=\"http://www.opengis.net/wfs\"\n                xmlns:ogc=\"http://www.opengis.net/ogc\"\n                xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n                xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd\">\n    <wfs:Query xmlns:wfs=\"http://www.opengis.net/wfs\" typeName=\"topp:states\" srsName=\"urn:ogc:def:crs:EPSG::4326\" xmlns:topp=\"http://www.openplans.org/topp\">\n    </wfs:Query>\n</wfs:GetFeature>\n--></div>\n<div id=\"boundedBy\"><!--\n<?xml version='1.0' encoding=\"ISO-8859-1\" ?>\n<wfs:FeatureCollection\n   xmlns:rws=\"http://mapserver.gis.umn.edu/mapserver\"\n   xmlns:gml=\"http://www.opengis.net/gml\"\n   xmlns:wfs=\"http://www.opengis.net/wfs\"\n   xmlns:ogc=\"http://www.opengis.net/ogc\"\n   xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n   xsi:schemaLocation=\"http://mapserver.gis.umn.edu/mapserver http://ontwikkel.intranet.rijkswaterstaat.nl/services/geoservices/ov_zonering?SERVICE=WFS&amp;VERSION=1.1.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=AAA212&amp;OUTPUTFORMAT=text/xml; subtype=gml/3.1.1  http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd\">\n      <gml:boundedBy>\n      \t<gml:Envelope srsName=\"EPSG:28992\">\n      \t\t<gml:lowerCorner>3197.880000 306457.313000</gml:lowerCorner>\n      \t\t<gml:upperCorner>280339.156000 613850.438000</gml:upperCorner>\n      \t</gml:Envelope>\n      </gml:boundedBy>\n    <gml:featureMember>\n\n      <rws:AAA212 gml:id=\"AAA212.791\">\n        <gml:boundedBy>\n        \t<gml:Envelope srsName=\"EPSG:28992\">\n        \t\t<gml:lowerCorner>196507.469000 502347.938000</gml:lowerCorner>\n        \t\t<gml:upperCorner>202430.844000 510383.719000</gml:upperCorner>\n        \t</gml:Envelope>\n        </gml:boundedBy>\n        <rws:geometry>\n\n          <gml:MultiSurface srsName=\"EPSG:28992\">\n            <gml:surfaceMembers>\n              <gml:Polygon>\n                <gml:exterior>\n                  <gml:LinearRing>\n                    <gml:posList srsDimension=\"2\">200448.047000 510383.719000 198475.031000 509253.875000 198477.422000 507339.688000 196507.469000 505841.969000 196507.625000 504980.281000 196621.359000 505029.969000 196825.328000 505114.000000 197310.031000 505183.469000 197636.609000 505148.750000 197837.594000 505061.563000 197941.031000 504953.688000 198003.094000 504817.719000 198023.781000 504721.688000 198016.391000 504597.531000 197907.234000 504363.219000 197716.734000 504013.969000 197700.156000 503567.563000 197775.531000 503373.969000 197930.688000 503153.781000 198034.234000 503045.594000 198170.078000 502932.125000 198504.047000 502725.250000 198858.719000 502550.875000 199138.000000 502460.719000 199336.000000 502347.938000 199044.125000 504910.969000 199549.359000 507065.781000 200280.594000 506878.938000 202430.844000 507474.625000 202430.844000 508850.906000 200448.047000 510383.719000 </gml:posList>\n                  </gml:LinearRing>\n                </gml:exterior>\n\n              </gml:Polygon>\n            </gml:surfaceMembers>\n          </gml:MultiSurface>\n        </rws:geometry>\n        <rws:OBJECTID>791</rws:OBJECTID>\n        <rws:HECTARES>1800.89</rws:HECTARES>\n        <rws:ZONENR>4620</rws:ZONENR>\n\n        <rws:NULZONES> </rws:NULZONES>\n        <rws:AREA>0</rws:AREA>\n        <rws:PERIMETER>24305.1</rws:PERIMETER>\n      </rws:AAA212>\n    </gml:featureMember>\n</wfs:FeatureCollection>\n--></div>\n<div id=\"schemaLocation\"><!--\n<wfs:GetFeature service=\"WFS\" version=\"1.1.0\"\n                xmlns:wfs=\"http://www.opengis.net/wfs\"\n                xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n                xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd http://www.openplans.org/topp http://foo.bar/topp_schema.xsd\">\n    <wfs:Query xmlns:wfs=\"http://www.opengis.net/wfs\" typeName=\"topp:states\" srsName=\"urn:ogc:def:crs:EPSG::4326\" xmlns:topp=\"http://www.openplans.org/topp\">\n    </wfs:Query>\n</wfs:GetFeature>\n--></div>\n<div id=\"schemaLocationDefaultPrefix\"><!--\n<wfs:GetFeature service=\"WFS\" version=\"1.1.0\"\n                xmlns:wfs=\"http://www.opengis.net/wfs\"\n                xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n                xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd http://www.openplans.org/topp http://foo.bar/topp_schema.xsd\">\n    <wfs:Query xmlns:wfs=\"http://www.opengis.net/wfs\" typeName=\"feature:states\" srsName=\"urn:ogc:def:crs:EPSG::4326\" xmlns:feature=\"http://www.openplans.org/topp\">\n    </wfs:Query>\n</wfs:GetFeature>\n--></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WFST/v2_0_0.html",
    "content": "<html>\n<head>\n  <script src=\"../../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(1);\n\n        var format = new OpenLayers.Format.WFST.v2_0_0({});\n        t.ok(format instanceof OpenLayers.Format.WFST.v2_0_0, \"constructor returns instance\");\n    }\n    \n\tfunction test_read(t) {\n\t     t.plan(1);\n\t\n\t     var data = readXML(\"FeatureCollection\");\n\t     var format = new OpenLayers.Format.WFST.v2_0_0({\n\t         featureNS: \"http://www.openplans.org/topp\",\n\t         featureType: \"states\"\n\t     });\n\t     var features = format.read(data);\n\t\n\t     t.eq(features.length, 1, \"number of features read from FeatureCollection is correct\");\n\t }\n\t\n    function test_write(t) {\n\n        var format = new OpenLayers.Format.WFST.v2_0_0({\n            featureNS: \"http://www.openplans.org/topp\",\n            featureType: \"states\",\n            featurePrefix: \"topp\",\n            geometryName: \"the_geom\"\n        });\n\n        var feature = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(1,2),\n            {foo: \"bar\"}\n        );\n\n        var insertFeature = feature.clone();\n        // null value does not show up in insert\n        insertFeature.attributes.nul = null;\n        insertFeature.state = OpenLayers.State.INSERT;\n        var updateFeature = feature.clone();\n        // undefined value means don't create a Property element\n        updateFeature.attributes.unwritten = undefined;\n        // null value gets Property element with no Value\n        updateFeature.attributes.nul = null;\n        updateFeature.fid = \"fid.42\";\n        updateFeature.state = OpenLayers.State.UPDATE;\n        var deleteFeature = feature.clone();\n        deleteFeature.state = OpenLayers.State.DELETE;\n        deleteFeature.fid = \"fid.37\";\n\n        t.plan(9);\n        var snippets = {\n            \"GetFeature\": {handle: \"handle_g\", maxFeatures: 1, outputFormat: 'json'},\n            \"Transaction\": {handle: \"handle_t\"},\n            \"Insert\": {feature: insertFeature, options: {handle: \"handle_i\"}},\n            \"Update\": {feature: updateFeature, options: {handle: \"handle_u\"}},\n            \"Delete\": {feature: deleteFeature, options: {handle: \"handle_d\"}}\n        }\n\n        var arg;\n        for(var snippet in snippets) {\n            arg = snippets[snippet]\n            var expected = readXML(snippet);\n            var got = format.writers[\"wfs\"][snippet].apply(format, [arg]);\n            t.xml_eq(got, expected, snippet + \" request created correctly\");\n        }\n        \n        updateFeature.modified = {geometry: updateFeature.geometry.clone()};\n        updateFeature.geometry = new OpenLayers.Geometry.Point(2,3);\n        var expected = readXML(\"UpdateModified\");\n        var got = format.writers[\"wfs\"][\"Update\"].apply(format, [{feature: updateFeature}]);\n        t.xml_eq(got, expected, \"Update request for feature with modified geometry created correctly\");\n        \n        updateFeature.modified.attributes = {foo: \"bar\"};\n        updateFeature.attributes.foo = \"baz\";\n        delete updateFeature.modified.geometry;\n        var expected = readXML(\"UpdateModifiedNoGeometry\");\n        var got = format.writers[\"wfs\"][\"Update\"].apply(format, [{feature: updateFeature}]);\n        t.xml_eq(got, expected, \"Update request for feature with no modified geometry but modified attributes created correctly\");\n\n        // test for a feature that originally had a null geometry and a null value for the attribute\n        updateFeature.modified = {attributes: {foo: null, nul: \"nul\"}, geometry: null};\n        updateFeature.attributes.foo = \"bar\";\n        updateFeature.geometry = new OpenLayers.Geometry.Point(2,3);\n        var expected = readXML(\"UpdateModified\");\n        var got = format.writers[\"wfs\"][\"Update\"].apply(format, [{feature: updateFeature}]);\n        t.xml_eq(got, expected, \"Update request for feature with modified geometry created correctly even if original geometry was null\");\n\n        updateFeature.modified.attributes = {foo: undefined};\n        updateFeature.attributes.foo = \"baz\";\n        delete updateFeature.modified.geometry;\n        var expected = readXML(\"UpdateModifiedNoGeometry\");\n        var got = format.writers[\"wfs\"][\"Update\"].apply(format, [{feature: updateFeature}]);\n        t.xml_eq(got, expected, \"Update request for feature with no modified geometry but modified attributes with undefined created correctly\");\n    }\n    \n    function test_write_query(t) {\n\n        var format = new OpenLayers.Format.WFST.v2_0_0({\n            featureNS: \"http://www.openplans.org/topp\",\n            featureType: \"states\",\n            featurePrefix: \"topp\",\n            srsName: \"urn:ogc:def:crs:EPSG::4326\",\n            geometryName: \"the_geom\"\n        });\n\n        var cases = [{\n            id: \"query0\",\n            writer: \"wfs:Query\",\n            arg: {\n                filter: new OpenLayers.Filter.Spatial({\n                    type: OpenLayers.Filter.Spatial.BBOX,\n                    value: new OpenLayers.Bounds (1,2,3,4)\n                })\n            }\n        }, {\n            id: \"getfeature0\",\n            writer: \"wfs:GetFeature\",\n            arg: {\n                resultType: \"hits\",\n                propertyNames: [\"STATE_NAME\", \"STATE_FIPS\", \"STATE_ABBR\"]\n            }\n        }, {\n            id: \"getfeature1\",\n            writer: \"wfs:GetFeature\",\n            arg: {\n                count: 10,\n                startIndex: 20\n            }\n        }];\n        \n        t.plan(cases.length);\n        \n        var test, got, exp;\n        for(var i=0; i<cases.length; ++i) {\n            test = cases[i];\n            exp = readXML(test.id);\n            got = format.writeNode(test.writer, test.arg);\n            t.xml_eq(got, exp, test.id + \": correct request\");\n        }\n    }\n\n    \n    function test_writeNative(t) {\n        t.plan(1);\n        var format = new OpenLayers.Format.WFST({\n            featureNS: \"http://www.openplans.org/topp\",\n            featureType: \"states\",\n            version: \"2.0.0\",\n            featurePrefix: \"topp\",\n            geometryName: null\n        });\n        var output = format.write(null, {nativeElements: [\n            {\n                vendorId: \"ORACLE\",\n                safeToIgnore: true,\n                value: \"ALTER SESSION ENABLE PARALLEL DML\"\n            }, {\n                vendorId: \"ORACLE\",\n                safeToIgnore: false,\n                value: \"Another native line goes here\"\n            }]\n        });\n        var expected = '<wfs:Transaction xmlns:wfs=\"http://www.opengis.net/wfs/2.0\" service=\"WFS\" version=\"2.0.0\" xsi:schemaLocation=\"http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><wfs:Native vendorId=\"ORACLE\" safeToIgnore=\"true\">ALTER SESSION ENABLE PARALLEL DML</wfs:Native><wfs:Native vendorId=\"ORACLE\" safeToIgnore=\"false\">Another native line goes here</wfs:Native></wfs:Transaction>';\n        t.xml_eq(output, expected, \"Native elements written out correctly\");\n    }\n\n    function test_write_no_geometry(t) {\n        var format = new OpenLayers.Format.WFST({\n            featureNS: \"http://www.openplans.org/topp\",\n            featureType: \"states\",\n            featurePrefix: \"topp\",\n            version: \"2.0.0\",\n            geometryName: null\n        });\n\n        var feature = new OpenLayers.Feature.Vector(null, {foo: \"bar\"});\n        feature.state = OpenLayers.State.UPDATE;\n        feature.fid = \"fid.36\";\n\n        t.plan(1);\n        var snippets = {\n            \"UpdateNoGeometry\": {feature: feature}\n        }\n\n        var arg;\n        for(var snippet in snippets) {\n            arg = snippets[snippet]\n            var expected = readXML(snippet);\n            var got = format.writers[\"wfs\"][\"Update\"].apply(format, [arg]);\n            t.xml_eq(got, expected, snippet + \" request without geometry created correctly\");\n        }\n    }\n    \n    function test_setFilterProperty(t) {\n        t.plan(2);\n        var format = new OpenLayers.Format.WFST({\n            geometryName: \"foo\"\n        });\n        var filter = new OpenLayers.Filter.Logical({\n            type: OpenLayers.Filter.Logical.AND,\n            filters: [new OpenLayers.Filter.Spatial({\n                type: OpenLayers.Filter.Spatial.BBOX,\n                value: new OpenLayers.Bounds(1,2,3,4)\n            }), new OpenLayers.Filter.Spatial({\n                type: OpenLayers.Filter.Spatial.DWITHIN,\n                property: \"bar\",\n                value: new OpenLayers.Geometry.Point(1,2),\n                distance: 10\n            })]\n        });\n        format.setFilterProperty(filter);\n        t.eq(filter.filters[0].property, \"foo\", \"property set if not set on filter\");\n        t.eq(filter.filters[1].property, \"bar\", \"property not set if set on filter\");\n    }\n\n    function test_update_null_geometry(t) {\n        var format = new OpenLayers.Format.WFST({\n            featureNS: \"http://www.openplans.org/topp\",\n            featureType: \"states\",\n            featurePrefix: \"topp\",\n            version: \"2.0.0\",\n            geometryName: \"the_geom\"\n        });\n\n        var feature = new OpenLayers.Feature.Vector(null, {foo: \"bar\"});\n        feature.state = OpenLayers.State.UPDATE;\n        feature.fid = \"fid.36\";\n\n        t.plan(1);\n        var snippets = {\n            \"UpdateNullGeometry\": {feature: feature}\n        };\n\n        var arg;\n        for (var snippet in snippets) {\n            arg = snippets[snippet]\n            var expected = readXML(snippet);\n            var got = format.writers[\"wfs\"][\"Update\"].apply(format, [arg]);\n            t.xml_eq(got, expected, snippet + \" request with null geometry created correctly\");\n        }\n    }\n\n     function test_read_hits(t) {\n        t.plan(2);\n        var data = readXML(\"NumberOfFeatures\");\n        var format = new OpenLayers.Format.WFST.v2_0_0({\n            featureNS: \"http://mapserver.gis.umn.edu/mapserver\",\n            featureType: \"AAA64\"\n        });\n        var result = format.read(data, {output: \"object\"});\n        t.eq(result.numberReturned, 625, \"numberReturned of FeatureCollection correctly read\");\n        t.eq(result.numberMatched, 625, \"numberMatched of FeatureCollection correctly read\");\n    }\n\n    function test_read_boundedBy(t) {\n        t.plan(4);\n        var data = readXML(\"boundedBy\");\n        var format = new OpenLayers.Format.WFST.v2_0_0({\n            featureNS: \"http://www.someserver.com/myns\",\n            featureType: \"Town\"\n        });\n        var result = format.read(data, {output: \"object\"});\n        var bounds = result.bounds;\n        t.eq(bounds.left.toFixed(3), '49.733', \"Left bounds of the feature collection correctly parsed\");\n        t.eq(bounds.bottom.toFixed(3), '-11.521', \"Bottom bounds of the feature collection correctly parsed\");\n        t.eq(bounds.right.toFixed(3), '59.452', \"Right bounds of the feature collection correctly parsed\");\n        t.eq(bounds.top.toFixed(3), '-1.141', \"Top bounds of the feature collection corectly parsed\");\n    }\n\n    function test_write_poorconfig(t) {\n        t.plan(1);\n        var format = new OpenLayers.Format.WFST.v2_0_0({\n            featureType: \"states\",\n            featurePrefix: \"topp\"\n        });\n        var exp = \"topp:states\";\n        var got = format.writeNode(\"wfs:Query\").getAttribute(\"typeNames\");\n        t.eq(got, exp, \"Query without featureNS but with featurePrefix queries for the correct featureType\");\n    }\n    \n    var xmlFormat = new OpenLayers.Format.XML();\n    function readXML(id) {\n        var xml = document.getElementById(id).firstChild.nodeValue;\n        return xmlFormat.read(xml).documentElement;        \n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:512px; height:256px\"> </div>\n\n<div id=\"GetFeature\"><!--\n<wfs:GetFeature xmlns:wfs=\"http://www.opengis.net/wfs/2.0\" service=\"WFS\" version=\"2.0.0\" handle=\"handle_g\" outputFormat=\"json\" maxFeatures=\"1\" xsi:schemaLocation=\"http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n    <wfs:Query typeNames=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\"/>\n</wfs:GetFeature>\n--></div>\n<div id=\"GetFeatureMultiple\"><!--\n<wfs:GetFeature xmlns:wfs=\"http://www.opengis.net/wfs\" service=\"WFS\" version=\"1.0.0\" xsi:schemaLocation=\"http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n    <wfs:Query typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\"/>\n    <wfs:Query typeName=\"topp:cities\" xmlns:topp=\"http://www.openplans.org/topp\"/>\n</wfs:GetFeature>\n--></div>\n<div id=\"Transaction\"><!--\n<wfs:Transaction xmlns:wfs=\"http://www.opengis.net/wfs/2.0\" service=\"WFS\" version=\"2.0.0\"/>\n--></div>\n<div id=\"Insert\"><!--\n<wfs:Insert xmlns:wfs=\"http://www.opengis.net/wfs/2.0\" handle=\"handle_i\">\n    <feature:states xmlns:feature=\"http://www.openplans.org/topp\">\n        <feature:the_geom>\n            <gml:Point xmlns:gml=\"http://www.opengis.net/gml/3.2\">\n                <gml:pos>1 2</gml:pos>\n            </gml:Point>\n        </feature:the_geom>\n        <feature:foo>bar</feature:foo>\n    </feature:states>\n</wfs:Insert>\n--></div>\n<div id=\"Update\"><!--\n<wfs:Update xmlns:wfs=\"http://www.opengis.net/wfs/2.0\" handle=\"handle_u\" typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\">\n    <wfs:Property>\n        <wfs:ValueReference>the_geom</wfs:ValueReference>\n        <wfs:Value>\n            <gml:Point xmlns:gml=\"http://www.opengis.net/gml/3.2\">\n                <gml:pos>1 2</gml:pos>\n            </gml:Point>\n        </wfs:Value>\n    </wfs:Property>\n    <wfs:Property>\n        <wfs:ValueReference>foo</wfs:ValueReference>\n        <wfs:Value>bar</wfs:Value>\n    </wfs:Property>\n    <wfs:Property>\n        <wfs:ValueReference>nul</wfs:ValueReference>\n    </wfs:Property>\n    <fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">\n        <fes:ResourceId rid=\"fid.42\"/>\n    </fes:Filter>\n</wfs:Update>\n--></div>\n<div id=\"UpdateModified\"><!--\n<wfs:Update xmlns:wfs=\"http://www.opengis.net/wfs/2.0\" typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\">\n    <wfs:Property>\n        <wfs:ValueReference>the_geom</wfs:ValueReference>\n        <wfs:Value>\n            <gml:Point xmlns:gml=\"http://www.opengis.net/gml/3.2\">\n                <gml:pos>2 3</gml:pos>\n            </gml:Point>\n        </wfs:Value>\n    </wfs:Property>\n    <wfs:Property>\n        <wfs:ValueReference>foo</wfs:ValueReference>\n        <wfs:Value>bar</wfs:Value>\n    </wfs:Property>\n    <wfs:Property>\n        <wfs:ValueReference>nul</wfs:ValueReference>\n    </wfs:Property>\n    <fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">\n        <fes:ResourceId rid=\"fid.42\"/>\n    </fes:Filter>\n</wfs:Update>\n--></div>\n<div id=\"UpdateModifiedNoGeometry\"><!--\n<wfs:Update xmlns:wfs=\"http://www.opengis.net/wfs/2.0\" typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\">\n    <wfs:Property>\n        <wfs:ValueReference>foo</wfs:ValueReference>\n        <wfs:Value>baz</wfs:Value>\n    </wfs:Property>\n    <fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">\n        <fes:ResourceId rid=\"fid.42\"/>\n    </fes:Filter>\n</wfs:Update>\n--></div>\n<div id=\"Delete\"><!--\n<wfs:Delete xmlns:wfs=\"http://www.opengis.net/wfs/2.0\" handle=\"handle_d\" typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\">\n    <fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">\n        <fes:ResourceId rid=\"fid.37\"/>\n    </fes:Filter>\n</wfs:Delete>\n--></div>\n<div id=\"UpdateNoGeometry\"><!--\n<wfs:Update xmlns:wfs=\"http://www.opengis.net/wfs/2.0\" typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\">\n    <wfs:Property>\n        <wfs:ValueReference>foo</wfs:ValueReference>\n        <wfs:Value>bar</wfs:Value>\n    </wfs:Property>\n    <fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">\n        <fes:ResourceId rid=\"fid.36\"/>\n    </fes:Filter>\n</wfs:Update>\n--></div>\n<div id=\"UpdateNullGeometry\"><!--\n<wfs:Update xmlns:wfs=\"http://www.opengis.net/wfs/2.0\" typeName=\"topp:states\" xmlns:topp=\"http://www.openplans.org/topp\">\n    <wfs:Property>\n        <wfs:ValueReference>the_geom</wfs:ValueReference>\n    </wfs:Property>\n    <wfs:Property>\n        <wfs:ValueReference>foo</wfs:ValueReference>\n        <wfs:Value>bar</wfs:Value>\n    </wfs:Property>\n    <fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">\n        <fes:ResourceId rid=\"fid.36\"/>\n    </fes:Filter>\n</wfs:Update>\n--></div>\n<div id=\"NumberOfFeatures\"><!--\n<?xml version='1.0' encoding=\"ISO-8859-1\" ?>\n<wfs:FeatureCollection\n   xmlns:rws=\"http://mapserver.gis.umn.edu/mapserver\"\n   xmlns:gml=\"http://www.opengis.net/gml/3.2\"\n   xmlns:wfs=\"http://www.opengis.net/wfs/2.0\"\n   xmlns:fes=\"http://www.opengis.net/fes/2.0\"\n   xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n   xsi:schemaLocation=\"http://mapserver.gis.umn.edu/mapserver http://intranet.rijkswaterstaat.nl/services/geoservices/nwb_wegen?SERVICE=WFS&amp;VERSION=1.1.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=feature:AAA64&amp;OUTPUTFORMAT=text/xml; subtype=gml/3.1.1  http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd\" numberReturned=\"625\" numberMatched=\"625\">\n</wfs:FeatureCollection>\n--></div>\n<div id=\"TransactionResponse\"><!--\n<wfs:TransactionResponse xmlns:wfs=\"http://www.opengis.net/wfs/2.0\" xmlns:fes=\"http://www.opengis.net/fes/2.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" version=\"2.0.0\" xsi:schemaLocation=\"http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd\">\n\t<wfs:TransactionSummary>\n\t\t<wfs:totalInserted>3</wfs:totalInserted>\n\t\t<wfs:totalUpdated>3</wfs:totalUpdated>\n\t\t<wfs:totalReplaced>1</wfs:totalReplaced>\n\t\t<wfs:totalDeleted>2</wfs:totalDeleted>\n\t</wfs:TransactionSummary>\n\t<wfs:InsertResults>\n\t\t<wfs:Feature handle=\"Statement 1\">\n\t\t\t<fes:ResourceId rid=\"ElevP_1M.1001\"/>\n\t\t</wfs:Feature>\n\t\t<wfs:Feature handle=\"ComplexInsert\">\n\t\t\t<fes:ResourceId rid=\"RoadL_1M.1553\"/>\n\t\t</wfs:Feature>\n\t\t<wfs:Feature handle=\"Statement 2\">\n\t\t\t<fes:ResourceId rid=\"BuiltUpA_1M.509876\"/>\n\t\t\t<fes:ResourceId rid=\"BuiltUpA_1M.509877\"/>\n\t\t</wfs:Feature>\n\t</wfs:InsertResults>\n</wfs:TransactionResponse>\n--></div>\n<div id=\"query0\"><!--\n<wfs:Query xmlns:wfs=\"http://www.opengis.net/wfs/2.0\" typeNames=\"topp:states\" srsName=\"urn:ogc:def:crs:EPSG::4326\" xmlns:topp=\"http://www.openplans.org/topp\">\n    <fes:Filter xmlns:fes=\"http://www.opengis.net/fes/2.0\">\n        <fes:BBOX>\n            <fes:ValueReference>the_geom</fes:ValueReference>\n            <gml:Envelope xmlns:gml=\"http://www.opengis.net/gml/3.2\" srsName=\"urn:ogc:def:crs:EPSG::4326\">\n                <gml:lowerCorner>1 2</gml:lowerCorner>\n                <gml:upperCorner>3 4</gml:upperCorner>\n            </gml:Envelope>\n        </fes:BBOX>\n    </fes:Filter>\n</wfs:Query>\n--></div>\n<div id=\"getfeature0\"><!--\n<wfs:GetFeature service=\"WFS\" version=\"2.0.0\" resultType=\"hits\" xmlns:topp=\"http://www.openplans.org/topp\"\n                xmlns:wfs=\"http://www.opengis.net/wfs/2.0\"\n                xmlns:fes=\"http://www.opengis.net/fes/2.0\"\n                xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n                xsi:schemaLocation=\"http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd\">\n    <wfs:Query xmlns:wfs=\"http://www.opengis.net/wfs/2.0\" typeNames=\"topp:states\" srsName=\"urn:ogc:def:crs:EPSG::4326\" xmlns:topp=\"http://www.openplans.org/topp\">\n        <wfs:PropertyName>STATE_NAME</wfs:PropertyName>\n        <wfs:PropertyName>STATE_FIPS</wfs:PropertyName>\n        <wfs:PropertyName>STATE_ABBR</wfs:PropertyName>\n    </wfs:Query>\n</wfs:GetFeature>\n--></div>\n<div id=\"getfeature1\"><!--\n<wfs:GetFeature service=\"WFS\" version=\"2.0.0\" startIndex=\"20\" count=\"10\" xmlns:topp=\"http://www.openplans.org/topp\"\n                xmlns:wfs=\"http://www.opengis.net/wfs/2.0\"\n                xmlns:fes=\"http://www.opengis.net/fes/2.0\"\n                xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n                xsi:schemaLocation=\"http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd\">\n    <wfs:Query xmlns:wfs=\"http://www.opengis.net/wfs/2.0\" typeNames=\"topp:states\" srsName=\"urn:ogc:def:crs:EPSG::4326\" xmlns:topp=\"http://www.openplans.org/topp\">\n    </wfs:Query>\n</wfs:GetFeature>\n--></div>\n<div id=\"FeatureCollection\"><!--\n<wfs:FeatureCollection xmlns:wfs=\"http://www.opengis.net/wfs/2.0\" xmlns:tiger=\"http://www.census.gov\" xmlns:gml=\"http://www.opengis.net/gml/3.2\" xmlns:cite=\"http://www.opengeospatial.net/cite\" xmlns:nurc=\"http://www.nurc.nato.int\" xmlns:sde=\"http://geoserver.sf.net\" xmlns:topp=\"http://www.openplans.org/topp\" xmlns:it.geosolutions=\"http://www.geo-solutions.it\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:sf=\"http://www.openplans.org/spearfish\" numberMatched=\"49\" numberReturned=\"49\" timeStamp=\"2013-08-06T11:54:15.559Z\" xsi:schemaLocation=\"http://www.opengis.net/gml/3.2 http://localhost:8082/geoserver/schemas/gml/3.2.1/gml.xsd http://www.openplans.org/topp http://localhost:8082/geoserver/wfs?service=WFS&amp;version=2.0.0&amp;request=DescribeFeatureType&amp;typeName=topp%3Astates http://www.opengis.net/wfs/2.0 http://localhost:8082/geoserver/schemas/wfs/2.0/wfs.xsd\">\n   <wfs:boundedBy>\n      <gml:Envelope>\n         <gml:lowerCorner>-1.3885038382960923E7 2870337.130793682</gml:lowerCorner>\n         <gml:upperCorner>-7455049.489182421 6338174.0557576185</gml:upperCorner>\n      </gml:Envelope>\n   </wfs:boundedBy>\n   <wfs:member>\n      <topp:states gml:id=\"states.1\">\n         <gml:boundedBy>\n            <gml:Envelope srsDimension=\"2\" srsName=\"http://www.opengis.net/gml/srs/epsg.xml#3857\">\n               <gml:lowerCorner>-1.0187528879651537E7 4437262.995631081</gml:lowerCorner>\n               <gml:upperCorner>-9741333.643874306 5237587.2815526575</gml:upperCorner>\n            </gml:Envelope>\n         </gml:boundedBy>\n         <topp:the_geom>\n            <gml:MultiSurface srsDimension=\"2\" srsName=\"http://www.opengis.net/gml/srs/epsg.xml#3857\">\n               <gml:surfaceMember>\n                  <gml:Polygon srsDimension=\"2\">\n                     <gml:exterior>\n                        <gml:LinearRing>\n                           <gml:posList>-9804081.657847203 4510573.570048137 -9805898.28061746 4505702.664324028 -9830814.254324773 4501015.72870541 -9836098.59055273 4496313.788384076 -9842853.011976104 4497853.114945388 -9848173.081760604 4495115.335828296 -9853035.294479474 4480565.297336921 -9851933.788118074 4475099.443555139 -9846286.772989111 4467813.297693937 -9843149.455780085 4461000.643837322 -9846261.28082572 4452869.190793547 -9849192.211698815 4449167.506882168 -9850739.663940333 4448614.465657501 -9853697.756769184 4448138.739395508 -9858373.175382502 4449261.124945198 -9864489.847443119 4454317.452023299 -9872744.187685441 4457998.039407824 -9878392.872606762 4458804.050146454 -9879215.857602198 4460329.801924502 -9892216.081695508 4467327.6217995165 -9899920.948931275 4469593.788107706 -9906674.59111821 4469821.507927165 -9914674.121046105 4465045.034948174 -9920439.134835308 4454748.786355814 -9923725.954120472 4452103.546096644 -9926308.677626366 4448064.2434366895 -9926841.23007032 4442691.175264947 -9924159.988815073 4438889.345599151 -9921890.62967576 4437450.02223913 -9928976.337903734 4437262.995631081 -9930817.562281456 4443146.019612607 -9933892.985853603 4444925.426762354 -9936828.926103784 4451257.716902817 -9939075.353427993 4451832.666853606 -9941196.88028353 4451014.907621134 -9941910.326900024 4447600.12031354 -9936850.188126527 4442973.115106779 -9936600.498508675 4440317.572799773 -9938912.270373981 4438996.253853614 -9942053.03848722 4440456.419127982 -9950064.47960063 4445968.66655027 -9949734.973907884 4452926.693143724 -9954611.658160556 4458248.410033331 -9956473.254005091 4462175.103896018 -9959556.24730261 4470412.84755195 -9959232.641542876 4474532.874986916 -9961936.035376789 4474850.351029055 -9964640.097127648 4477704.009021743 -9964640.097127648 4481700.233926405 -9963158.991302645 4485126.637721484 -9959614.80135477 4486522.210341316 -9955940.812880628 4488805.815899229 -9955032.000557791 4496553.29910406 -9957931.539334483 4502464.737311692 -9962513.449575534 4507870.489861796 -9965874.185002582 4519132.920866387 -9964582.43363142 4525310.639469115 -9965229.5338314 4530152.582520835 -9964583.212867854 4534296.147807098 -9965490.355398327 4536400.271533974 -9972159.840050224 4537990.954535544 -9981624.445796452 4543529.003925382 -9982670.849009909 4548952.808520223 -9984362.571311494 4551886.335211437 -9988525.029711235 4556987.603436236 -1.000224716070234E7 4566023.207236599 -1.0003285882870933E7 4566082.885946576 -1.0003927973693829E7 4564162.757935383 -1.000768355935472E7 4561910.0120879505 -1.0011838336709598E7 4562211.816709335 -1.0016406665972773E7 4566985.444813793 -1.0014104244944697E7 4574289.789724424 -1.0019957646409588E7 4575092.381538184 -1.0023421129726637E7 4578466.092983348 -1.0032038928106397E7 4583985.767760285 -1.0033750242638364E7 4587050.085703865 -1.0041855971360477E7 4591992.731710566 -1.004703588990607E7 4596698.599642423 -1.0050996192110531E7 4603018.336881153 -1.0056237225056568E7 4606119.038391172 -1.0059360070731793E7 4612577.482428579 -1.0059869691360647E7 4625235.222881119 -1.0058683136908278E7 4631164.0181526365 -1.0056559049704453E7 4634787.332401642 -1.0052355069134645E7 4639974.179227037 -1.004834122225511E7 4652960.393995351 -1.0047834161974547E7 4654963.872520132 -1.0045575934784316E7 4659239.223492842 -1.003920445240927E7 4665998.995947451 -1.003918998087547E7 4672910.786842571 -1.0041267425212653E7 4678841.574563614 -1.0040636355019346E7 4682208.703332439 -1.003694366487075E7 4689221.727105073 -1.0033802117521076E7 4690990.411295875 -1.0032304759050416E7 4693136.49220776 -1.0031346743512647E7 4697416.436610844 -1.0033538735605858E7 4700641.335474557 -1.0045908000825351E7 4709433.108080555 -1.004980462828108E7 4710893.658542942 -1.005434746538086E7 4710920.988635183 -1.006473702477609E7 4716277.1038072845 -1.0071056632268423E7 4715826.00020265 -1.0077800923618136E7 4706157.36294659 -1.0082242793939767E7 4703256.850119881 -1.008857520317354E7 4704610.834539867 -1.0093213218437953E7 4712401.359326277 -1.0097353524259027E7 4727086.398941798 -1.0097522507246053E7 4730008.501326762 -1.0095609036518807E7 4735102.1946359705 -1.0098540857947828E7 4742349.662911801 -1.0098703050445916E7 4749767.661822176 -1.0100277664643187E7 4753915.973012006 -1.0100917195117794E7 4757230.647161204 -1.0105510237307921E7 4764275.667575246 -1.0113430730397357E7 4771995.861950482 -1.0124272914842147E7 4779215.456295107 -1.0134118901163831E7 4785531.183069953 -1.013724085628313E7 4789794.92689745 -1.0140494613679526E7 4797721.521708938 -1.0147460542135404E7 4801137.734314944 -1.0152699014733156E7 4807987.527154785 -1.016543596823074E7 4820405.016274203 -1.0170937711424215E7 4826008.027807813 -1.0171642697759409E7 4831311.3798096515 -1.0172565870296558E7 4837467.800663898 -1.0180077041618345E7 4846060.845475296 -1.0180277528021263E7 4849279.946300798 -1.0178392109805696E7 4851686.5757499095 -1.0177984346510923E7 4854590.337890092 -1.0179860525208753E7 4858107.5397222275 -1.018431842553706E7 4866778.325006238 -1.018617924214516E7 4875641.281075712 -1.0187528879651537E7 4885513.152508497 -1.0186462104971264E7 4895115.337766316 -1.0185614518368363E7 4902539.22352504 -1.0184252190440034E7 4911038.536129932 -1.018001080652132E7 4920134.15867877 -1.017669604604397E7 4922322.199239335 -1.0173015934997836E7 4923124.003387151 -1.0171568781617524E7 4924677.374188916 -1.0172976082620133E7 4931149.882711003 -1.017179553942027E7 4939404.117010152 -1.0172609173578478E7 4943041.728874968 -1.0176034362990694E7 4945897.617376829 -1.0175839108603844E7 4949557.568905235 -1.0171886376124755E7 4954023.8038917845 -1.0159246270584162E7 4959319.137172085 -1.0153997556593258E7 4959946.0080705555 -1.014816285680282E7 4961779.025136117 -1.0144451464979773E7 4965571.010330402 -1.0143430553929705E7 4968985.156726282 -1.0140398656278463E7 4977233.268681194 -1.013997052151687E7 4987847.5769731235 -1.0135551694329832E7 4994596.670245673 -1.0128211955023868E7 5001127.380787999 -1.0125699808075137E7 5005043.754075937 -1.012502543459991E7 5022725.588938968 -1.012537453252304E7 5027746.799941758 -1.0128998427226322E7 5033659.731877658 -1.0132106022131307E7 5036831.667628284 -1.0136343175909372E7 5038374.543425472 -1.014137526217119E7 5046551.317376963 -1.0141466989431605E7 5051925.377064774 -1.0138231154473227E7 5061864.950815576 -1.0136283731301289E7 5071726.462726873 -1.0133133723670311E7 5075011.124111179 -1.0130150917914506E7 5076135.905438489 -1.0124469171104416E7 5074673.537160142 -1.0112723295033365E7 5078146.170256631 -1.0105572242264293E7 5078918.283989316 -1.0097592193247288E7 5078954.076874659 -1.0092090450053813E7 5080774.491244318 -1.008562378951414E7 5087798.550118103 -1.0078960204795254E7 5090234.421034555 -1.0069403871788617E7 5090468.763399351 -1.0067174476346498E7 5092853.10512966 -1.006584276127814E7 5096377.68358779 -1.005753409712431E7 5099290.939867389 -1.0056530217956336E7 5101664.96595854 -1.0056728923247404E7 5108558.906123816 -1.005504733101948E7 5119536.701835704 -1.0052693925664619E7 5124568.752455289 -1.0047175150589053E7 5128340.719408752 -1.0040554869152086E7 5131983.797647508 -1.0035955036473017E7 5150615.508548303 -1.0034636123146096E7 5158577.481854369 -1.003551176226068E7 5165988.112312521 -1.0037466755157989E7 5170127.779800905 -1.003730545321583E7 5176532.632466528 -1.0038355975250445E7 5179047.18533362 -1.0040080091523852E7 5179375.265187534 -1.0044461626681477E7 5184934.983299134 -1.0054777269934816E7 5190582.853801676 -1.005968957642454E7 5192519.928347542 -1.006408046241939E7 5197396.072847533 -1.0065283937434357E7 5200596.333346887 -1.006636340253658E7 5212141.977634381 -1.006791252457046E7 5215070.172096852 -1.0073416828112222E7 5219396.338955011 -1.0081491943974365E7 5224379.5326696215 -1.008619452454344E7 5230220.722893911 -1.0090927717972476E7 5232496.903027368 -1.0091309098547934E7 5235373.283363911 -1.0089812630633201E7 5237587.2815526575 -1.0065505574540526E7 5237436.423890345 -1.00102459113938E7 5236794.059994191 -1.0000343931368249E7 5236696.214322979 -9952017.802705582 5235794.813484654 -9947447.803650044 5235857.621875817 -9900652.98590273 5234794.465000342 -9881269.479568353 5234800.8055413775 -9874764.636443337 5234611.949822939 -9829276.932156917 5234961.434001078 -9817789.317304507 5234605.60940872 -9773551.842219185 5234532.996873226 -9777963.990236778 5208163.855569051 -9769425.117375987 5184444.682182559 -9759440.649607757 5169944.7059558295 -9752992.802062029 5138137.880605197 -9743779.555726014 5119664.223398593 -9744089.580507874 5081873.352668125 -9744067.5392487 5056886.0325055 -9743987.723173797 5038004.514775069 -9744020.005826129 5013806.446930743 -9744092.140856162 4974862.059157537 -9744593.189884223 4938080.139428916 -9744426.767245486 4936416.783240098 -9744389.36389658 4890122.75670336 -9744437.787875075 4849578.802714823 -9744415.7466159 4809334.120216452 -9744748.703212861 4790294.49116782 -9744932.15773369 4772006.370827116 -9751327.351160271 4770242.041055282 -9754396.763479913 4765800.702555224 -9752769.495163498 4764399.088851934 -9753346.130125808 4762062.828273016 -9752354.941379784 4758718.961630332 -9749869.06583088 4757366.200756999 -9750317.572059287 4751576.6812662175 -9750942.631000089 4750091.575003462 -9752469.6004553 4749795.671642305 -9756514.060194802 4745837.577368545 -9759416.048000293 4742703.912082091 -9758205.782496387 4740403.810552741 -9758518.367626535 4737937.947208509 -9755112.659125205 4736571.4708002 -9755023.49221308 4734424.359806931 -9752924.00661672 4733797.9121429 -9749953.223365918 4730618.800568355 -9749555.701464297 4721061.812199303 -9750681.030196726 4720824.048536127 -9745788.20461789 4718388.581212782 -9744181.307768287 4716473.671570964 -9743815.289282558 4711924.239963079 -9744819.168450532 4708052.874953907 -9747029.862218197 4703040.378050157 -9746077.857932933 4701336.07176051 -9741333.643874306 4692429.318140128 -9742573.631682253 4689735.907590863 -9741346.334296254 4688739.697550353 -9741381.177296873 4684016.415077351 -9745341.479501337 4676789.343939147 -9750304.770317845 4674820.794170547 -9754391.642783338 4670635.696913094 -9754776.362943519 4667800.7042107945 -9753794.525034722 4664423.224628617 -9756106.296900025 4663564.21674506 -9757471.185176644 4660814.908092914 -9759707.3711077 4657049.728047072 -9757308.10212263 4652488.182239468 -9757546.77111089 4650364.849992316 -9760482.822680563 4650871.530463769 -9761919.845987216 4647675.396447819 -9768963.92072563 4645484.53257022 -9769249.232580533 4644200.916361872 -9767055.570694963 4642549.753153745 -9768110.322870228 4638639.677096441 -9772072.294867052 4632980.627598 -9777692.14804026 4629346.02637084 -9779426.394387327 4619921.075634839 -9780865.198805831 4619816.695535485 -9782093.275428262 4624274.498274765 -9783140.457878156 4624099.134215803 -9783699.281721937 4621986.345767715 -9786553.736104857 4619204.901940741 -9786502.863097565 4622225.50759058 -9787868.530610617 4622569.649362098 -9793890.915062534 4613539.242131068 -9794557.607492894 4612650.468707529 -9793658.146007285 4607818.900338107 -9788577.63576697 4603629.170491141 -9788544.573878204 4601703.199176652 -9790612.556058673 4598785.123374764 -9793165.557260524 4598055.83938258 -9798179.832403816 4594029.216580492 -9797487.647810064 4592479.431662503 -9792204.202138033 4593102.090232319 -9793365.153107516 4589786.815560131 -9799981.204403833 4587069.029371835 -9800912.057985848 4585801.717882557 -9800731.943049742 4584838.1561048785 -9798530.600119308 4584163.7020940315 -9799367.166092617 4580589.348788441 -9798531.490675233 4575902.661285274 -9800847.492681189 4573249.223937362 -9800765.116258 4570176.705064864 -9803308.766622625 4569511.248999743 -9804902.861730786 4571517.908685193 -9805466.02703471 4568647.137191132 -9799503.866427312 4567790.717160487 -9799074.952429285 4566121.120004894 -9801109.872720987 4564745.0647345185 -9807256.267085645 4566179.247330112 -9807409.220065996 4564646.60068051 -9804546.194082284 4560768.451946129 -9799926.880492326 4557375.818290291 -9800805.85919163 4555089.027160649 -9806052.012834245 4555614.307528577 -9805691.894281527 4553692.448811149 -9800075.492012536 4552011.589174394 -9804182.735944845 4542113.987418192 -9810991.481279723 4537236.946740006 -9813856.177055798 4531602.397200321 -9813662.592461308 4527074.485299873 -9811051.037207298 4520764.381898589 -9804081.657847203 4510573.570048137</gml:posList>\n                        </gml:LinearRing>\n                     </gml:exterior>\n                  </gml:Polygon>\n               </gml:surfaceMember>\n            </gml:MultiSurface>\n         </topp:the_geom>\n         <topp:STATE_NAME>Illinois</topp:STATE_NAME>\n         <topp:STATE_FIPS>17</topp:STATE_FIPS>\n         <topp:SUB_REGION>E N Cen</topp:SUB_REGION>\n         <topp:STATE_ABBR>IL</topp:STATE_ABBR>\n         <topp:LAND_KM>143986.61</topp:LAND_KM>\n         <topp:WATER_KM>1993.335</topp:WATER_KM>\n         <topp:PERSONS>1.1430602E7</topp:PERSONS>\n         <topp:FAMILIES>2924880.0</topp:FAMILIES>\n         <topp:HOUSHOLD>4202240.0</topp:HOUSHOLD>\n         <topp:MALE>5552233.0</topp:MALE>\n         <topp:FEMALE>5878369.0</topp:FEMALE>\n         <topp:WORKERS>4199206.0</topp:WORKERS>\n         <topp:DRVALONE>3741715.0</topp:DRVALONE>\n         <topp:CARPOOL>652603.0</topp:CARPOOL>\n         <topp:PUBTRANS>538071.0</topp:PUBTRANS>\n         <topp:EMPLOYED>5417967.0</topp:EMPLOYED>\n         <topp:UNEMPLOY>385040.0</topp:UNEMPLOY>\n         <topp:SERVICE>1360159.0</topp:SERVICE>\n         <topp:MANUAL>828906.0</topp:MANUAL>\n         <topp:P_MALE>0.486</topp:P_MALE>\n         <topp:P_FEMALE>0.514</topp:P_FEMALE>\n         <topp:SAMP_POP>1747776.0</topp:SAMP_POP>\n      </topp:states>\n   </wfs:member>\n</wfs:FeatureCollection>\n--></div>\n<div id=\"boundedBy\"><!--\n\t<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\t<wfs:FeatureCollection timeStamp=\"2009-02-14T01:27:44\"\n\t\tnumberMatched=\"1\" numberReturned=\"1\"\n\t\txmlns:myns=\"http://www.someserver.com/myns\"\n\t\txmlns:wfs=\"http://www.opengis.net/wfs/2.0\"\n\t\txmlns:gml=\"http://www.opengis.net/gml/3.2\"\n\t\txmlns:xlink=\"http://www.w3.org/1999/xlink\"\n\t\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n\t\txsi:schemaLocation=\"http://www.opengis.net/wfs/2.0\n            http://schema.opengis.net/wfs/2.0.0/wfs.xsd\n            http://www.opengis.net/gml/3.2\n            http://schemas.opengis.net/gml/3.2.1/gml.xsd\">\n\t\t<wfs:boundedBy>\n\t\t\t<gml:Envelope srsName=\"urn:ogc:def:crs:EPSG::4326\">\n\t\t\t\t<gml:lowerCorner>49.733 -11.521</gml:lowerCorner>\n\t\t\t\t<gml:upperCorner>59.452 -1.141</gml:upperCorner>\n\t\t\t</gml:Envelope>\n\t\t</wfs:boundedBy>\n\t\t<wfs:member>\n\t\t\t<myns:Town gml:id=\"t1\"> <gml:name>Bedford</gml:name> <gml:directedNode\n\t\t\t\torientation=\"+\" xlink:href=\"#n1\" /> </myns:Town>\n\t\t</wfs:member>\n\t</wfs:FeatureCollection>\n--></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WFST.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(2);\n\n        var format = new OpenLayers.Format.WFST();\n        t.ok(format instanceof OpenLayers.Format.WFST.v1_0_0, \"constructor returns instance with default versioned format\");\n\n        format = new OpenLayers.Format.WFST({\n            version: \"1.1.0\"\n        });\n        t.ok(format instanceof OpenLayers.Format.WFST.v1_1_0, \"constructor returns instance with custom versioned format\");\n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:512px; height:256px\"> </div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WKT.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n     \n    var points = []; \n    for(var i=0; i<12; ++i) { \n        points.push(new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(Math.random() * 100,\n                                          Math.random() * 100))\n        ); \n    } \n    var multipoint = new OpenLayers.Feature.Vector(\n        new OpenLayers.Geometry.MultiPoint([ \n            points[0].geometry, \n            points[1].geometry, \n            points[2].geometry\n        ])\n    ); \n     \n    var linestrings = [ \n        new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.LineString([\n                points[0].geometry, \n                points[1].geometry, \n                points[2].geometry\n            ])\n        ),\n        new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.LineString([\n                points[3].geometry, \n                points[4].geometry, \n                points[5].geometry\n            ])\n        )\n    ]; \n     \n    var multilinestring = new OpenLayers.Feature.Vector(\n        new OpenLayers.Geometry.MultiLineString([ \n            linestrings[0].geometry, \n            linestrings[1].geometry\n        ])\n    ); \n \n    var rings = [ \n        new OpenLayers.Geometry.LinearRing([\n            points[0].geometry, \n            points[1].geometry, \n            points[2].geometry\n        ]), \n        new OpenLayers.Geometry.LinearRing([\n            points[3].geometry, \n            points[4].geometry, \n            points[5].geometry\n        ]), \n        new OpenLayers.Geometry.LinearRing([\n            points[6].geometry, \n            points[7].geometry, \n            points[8].geometry\n        ]), \n        new OpenLayers.Geometry.LinearRing([\n            points[9].geometry, \n            points[10].geometry, \n            points[11].geometry\n        ]) \n    ]; \n \n    var polygons = [ \n        new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Polygon([rings[0], rings[1]])\n        ), \n        new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Polygon([rings[2], rings[3]])\n        )\n    ]; \n     \n    var multipolygon = new OpenLayers.Feature.Vector(\n        new OpenLayers.Geometry.MultiPolygon([ \n            polygons[0].geometry, \n            polygons[1].geometry \n        ])\n    ); \n\n    var collection = new OpenLayers.Feature.Vector(\n        new OpenLayers.Geometry.Collection([ \n            points[0].geometry,\n            linestrings[0].geometry\n        ])\n    ); \n     \n    var geom_array = [points[0], linestrings[0]]; \n     \n    function test_Format_WKT_constructor(t) { \n        t.plan(4); \n         \n        var options = {'foo': 'bar'}; \n        var format = new OpenLayers.Format.WKT(options); \n        t.ok(format instanceof OpenLayers.Format.WKT, \n             \"new OpenLayers.Format.WKT returns object\" ); \n        t.eq(format.foo, \"bar\", \"constructor sets options correctly\"); \n        t.eq(typeof format.read, \"function\", \"format has a read function\"); \n        t.eq(typeof format.write, \"function\", \"format has a write function\"); \n    }\n\n    function test_Format_WKT_write(t) { \n        t.plan(8); \n\n        var format = new OpenLayers.Format.WKT(); \n\n        // test a point \n        \n        t.eq(format.write(points[0]), \n             \"POINT(\" + points[0].geometry.x + \" \" + points[0].geometry.y + \")\", \n             \"format correctly writes Point WKT\"); \n \n        // test a multipoint \n        t.eq(format.write(multipoint), \n             \"MULTIPOINT((\" + points[0].geometry.x + \" \" + points[0].geometry.y + \"),(\" + \n                              points[1].geometry.x + \" \" + points[1].geometry.y + \"),(\" + \n                              points[2].geometry.x + \" \" + points[2].geometry.y + \"))\", \n             \"format correctly writes MultiPoint WKT\"); \n \n        // test a linestring \n        t.eq(format.write(linestrings[0]), \n             \"LINESTRING(\" + points[0].geometry.x + \" \" + points[0].geometry.y + \",\" + \n                             points[1].geometry.x + \" \" + points[1].geometry.y + \",\" + \n                             points[2].geometry.x + \" \" + points[2].geometry.y + \")\", \n             \"format correctly writes LineString WKT\"); \n \n        // test a multilinestring \n        t.eq(format.write(multilinestring), \n             \"MULTILINESTRING((\" + points[0].geometry.x + \" \" + points[0].geometry.y + \",\" + \n                                   points[1].geometry.x + \" \" + points[1].geometry.y + \",\" + \n                                   points[2].geometry.x + \" \" + points[2].geometry.y + \"),\" + \n                             \"(\" + points[3].geometry.x + \" \" + points[3].geometry.y + \",\" + \n                                   points[4].geometry.x + \" \" + points[4].geometry.y + \",\" + \n                                   points[5].geometry.x + \" \" + points[5].geometry.y + \"))\", \n             \"format correctly writes MultiLineString WKT\"); \n \n        // test a polygon \n        t.eq(format.write(polygons[0]), \n             \"POLYGON((\" + points[0].geometry.x + \" \" + points[0].geometry.y + \",\" + \n                           points[1].geometry.x + \" \" + points[1].geometry.y + \",\" + \n                           points[2].geometry.x + \" \" + points[2].geometry.y + \",\" + \n                           points[0].geometry.x + \" \" + points[0].geometry.y + \"),\" + \n                     \"(\" + points[3].geometry.x + \" \" + points[3].geometry.y + \",\" + \n                           points[4].geometry.x + \" \" + points[4].geometry.y + \",\" + \n                           points[5].geometry.x + \" \" + points[5].geometry.y + \",\" + \n                           points[3].geometry.x + \" \" + points[3].geometry.y + \"))\", \n             \"format correctly writes Polygon WKT\"); \n \n        // test a multipolygon \n        t.eq(format.write(multipolygon), \n             \"MULTIPOLYGON(((\" + points[0].geometry.x + \" \" + points[0].geometry.y + \",\" + \n                                 points[1].geometry.x + \" \" + points[1].geometry.y + \",\" + \n                                 points[2].geometry.x + \" \" + points[2].geometry.y + \",\" + \n                                 points[0].geometry.x + \" \" + points[0].geometry.y + \"),\" + \n                           \"(\" + points[3].geometry.x + \" \" + points[3].geometry.y + \",\" + \n                                 points[4].geometry.x + \" \" + points[4].geometry.y + \",\" + \n                                 points[5].geometry.x + \" \" + points[5].geometry.y + \",\" + \n                                 points[3].geometry.x + \" \" + points[3].geometry.y + \")),\" + \n                          \"((\" + points[6].geometry.x + \" \" + points[6].geometry.y + \",\" + \n                                 points[7].geometry.x + \" \" + points[7].geometry.y + \",\" + \n                                 points[8].geometry.x + \" \" + points[8].geometry.y + \",\" + \n                                 points[6].geometry.x + \" \" + points[6].geometry.y + \"),\" + \n                           \"(\" + points[9].geometry.x + \" \" + points[9].geometry.y + \",\" + \n                                 points[10].geometry.x + \" \" + points[10].geometry.y + \",\" + \n                                 points[11].geometry.x + \" \" + points[11].geometry.y + \",\" + \n                                 points[9].geometry.x + \" \" + points[9].geometry.y + \")))\", \n             \"format correctly writes MultiPolygon WKT\"); \n\n        // test geometrycollection\n        t.eq(format.write(collection), \n             \"GEOMETRYCOLLECTION(POINT(\" + points[0].geometry.x + \" \" + points[0].geometry.y + \"),\" + \n                                \"LINESTRING(\" + points[0].geometry.x + \" \" + points[0].geometry.y + \",\" + \n                                                points[1].geometry.x + \" \" + points[1].geometry.y + \",\" + \n                                                points[2].geometry.x + \" \" + points[2].geometry.y + \"))\", \n             \"format correctly writes GeometryCollection WKT\"); \n         \n        // test writing an array of geometries \n        t.eq(format.write(geom_array), \n             \"GEOMETRYCOLLECTION(POINT(\" + points[0].geometry.x + \" \" + points[0].geometry.y + \"),\" + \n                                \"LINESTRING(\" + points[0].geometry.x + \" \" + points[0].geometry.y + \",\" + \n                                                points[1].geometry.x + \" \" + points[1].geometry.y + \",\" + \n                                                points[2].geometry.x + \" \" + points[2].geometry.y + \"))\", \n             \"format correctly writes WKT for an array of Geometries\"); \n \n    }\n\n    function test_Format_WKT_read(t) { \n        t.plan(13); \n\n        var format = new OpenLayers.Format.WKT(); \n         \n        /** \n         * Since we're explicitly testing calls to write, the read tests \n         * just make sure that geometry can make a round trip from read to write. \n         */ \n \n        // test a point \n        t.ok(points[0].geometry.equals(format.read(format.write(points[0])).geometry), \n             \"format correctly reads Point WKT\"); \n\n        // test a multipoint \n        t.ok(multipoint.geometry.equals(format.read(format.write(multipoint)).geometry), \n             \"format correctly reads MultiPoint WKT\"); \n\n        // test a multipoint without separating parens \n        t.ok(multipoint.geometry.equals(format.read( \n \t        \"MULTIPOINT(\" + points[0].geometry.x + \" \" + points[0].geometry.y + \",\" +  \n                            points[1].geometry.x + \" \" + points[1].geometry.y + \",\" +  \n                            points[2].geometry.x + \" \" + points[2].geometry.y + \")\").geometry), \n            \"format correctly reads MultiPoint WKT without parens\");\n\n        // test a linestring \n        t.ok(linestrings[0].geometry.equals(format.read(format.write(linestrings[0])).geometry), \n             \"format correctly reads LineString WKT\"); \n \n        // test a multilinestring \n        t.ok(multilinestring.geometry.equals(format.read(format.write(multilinestring)).geometry), \n             \"format correctly reads MultiLineString WKT\"); \n \n        // test a polygon \n        t.ok(polygons[0].geometry.equals(format.read(format.write(polygons[0])).geometry), \n             \"format correctly reads Polygon WKT\"); \n \n        // test a multipolygon \n        t.ok(multipolygon.geometry.equals(format.read(format.write(multipolygon)).geometry), \n             \"format correctly reads MultiPolygon WKT\"); \n             \n        // test a collection\n        var wkt = format.write(collection);\n        var got = format.read(wkt);\n        t.ok(got instanceof Array, \"by default, reading a collection returns an array\");\n        t.eq(got.length, 2, \"read two items\");\n        t.ok(got[0] instanceof OpenLayers.Feature.Vector, \"first item is a feature\");\n        t.geom_eq(got[0].geometry, points[0].geometry, \"first feature's geometry is the correct point\");\n        t.ok(got[1] instanceof OpenLayers.Feature.Vector, \"second item is a feature\");\n        t.geom_eq(got[1].geometry, linestrings[0].geometry, \"second feature's geometry is the correct linestring\");\n \n    }\n    \n    function test_whitespace(t) {\n        t.plan(3);\n        var wkt = \"LINESTRING(7.120068\\t43.583917,\\n7.120154 43.583652,\\n7.120385\\t43.582716,\\r\\n7.12039 43.582568, 7.120712 43.581511,7.120873\\n43.580718)\";\n        var format = new OpenLayers.Format.WKT();\n        var got = format.read(wkt);\n        t.ok(got instanceof OpenLayers.Feature.Vector, \"read a feature\");\n        t.ok(got.geometry instanceof OpenLayers.Geometry.LineString, \"read a linestring\");\n        t.ok(got.geometry.components.length, 6, \"read a geometry with 6 components\");\n    }\n\n    function test_Format_WKT_read_projection(t) {\n        t.plan(1);\n\n        var projections = {\n                src:  new OpenLayers.Projection(\"EPSG:4326\"),\n                dest: new OpenLayers.Projection(\"EPSG:900913\")\n            },\n            points = {\n                src:  new OpenLayers.Feature.Vector(\n                    new OpenLayers.Geometry.Point(-87.9, 41.9)\n                ),\n                dest: new OpenLayers.Feature.Vector(\n                    new OpenLayers.Geometry.Point(-9784983.2393667, 5146011.6785665)\n                )\n            },\n            format = new OpenLayers.Format.WKT({\n                externalProjection: projections[\"src\"],\n                internalProjection: projections[\"dest\"]\n            }),\n            gc_wkt_parts = [\n                \"GEOMETRYCOLLECTION(\",\n                \"POINT(\",\n                points[\"src\"].geometry.x,\n                \" \",\n                points[\"src\"].geometry.y, \n                \")\",\n                \")\"\n            ],\n            feature = format.read( gc_wkt_parts.join(\"\") )[0],\n            gotGeom = feature.geometry,\n            expectGeom = points[\"dest\"].geometry,\n            // we don't use geometry::toString because we might run into \n            // precision issues\n            precision = 7,\n            got = gotGeom.x.toFixed(precision) + ' ' + gotGeom.y.toFixed(precision),\n            expected = expectGeom.x.toFixed(precision) + ' ' + expectGeom.y.toFixed(precision);\n        \n        t.eq(got, expected, \n            \"Geometry collections aren't transformed twice when reprojection.\");\n    }\n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WMC/v1.html",
    "content": "<html> \n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    \n    function test_write_wmc_StyleList(t) {\n        t.plan(4);\n        \n        var layer, layerContext, got, expected;\n        \n        var format = new OpenLayers.Format.WMC();\n        var parser = format.getParser(\"1\");\n        var name = \"test\";\n        var url = \"http://foo\";\n\n        // test named style\n        layer = new OpenLayers.Layer.WMS(name, url, {\n            styles: \"mystyle\"\n        });\n        layerContext = format.layerToContext(layer);\n        got = parser.write_wmc_StyleList(layerContext);\n        expected = \n            \"<StyleList xmlns='http://www.opengis.net/context'>\" +\n                \"<Style current='1'>\" +\n                    \"<Name>mystyle</Name><Title>Default</Title>\" +\n                \"</Style>\" +\n            \"</StyleList>\";\n        \n        t.xml_eq(got, expected, \"named style correctly written\");\n        layer.destroy();\n        \n        // test linked style\n        layer = new OpenLayers.Layer.WMS(name, url, {\n            sld: \"http://linked.sld\"\n        });\n        layerContext = format.layerToContext(layer);\n        got = parser.write_wmc_StyleList(layerContext);\n        expected = \n            \"<StyleList xmlns='http://www.opengis.net/context'>\" +\n                \"<Style current='1'>\" +\n                    \"<SLD>\" + \n                        \"<Title>Default</Title>\" +\n                        \"<OnlineResource xmlns:xlink='http://www.w3.org/1999/xlink' \"+\n                                        \"xlink:type='simple' \" +\n                                        \"xlink:href='http://linked.sld' />\" +\n                    \"</SLD>\" + \n                \"</Style>\" +\n            \"</StyleList>\";\n            \n        t.xml_eq(got, expected, \"linked style correctly written\");\n        layer.destroy();\n        \n        // test inline style\n        layer = new OpenLayers.Layer.WMS(name, url, {\n            sld_body:\n                \"<sld:StyledLayerDescriptor version='1.0.0' \" +\n                    \"xmlns:ogc='http://www.opengis.net/ogc' \" +\n                    \"xmlns:sld='http://www.opengis.net/sld' \" +\n                    \"xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' \" +\n                    \"xsi:schemaLocation='http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd'>\" +\n                    \"<sld:NamedLayer>\" +\n                        \"<sld:Name>AAA212</sld:Name>\" +\n                        \"<sld:UserStyle>\" +\n                            \"<sld:FeatureTypeStyle>\" +\n                                \"<sld:Rule>\" +\n                                    \"<sld:TextSymbolizer>\" +\n                                        \"<sld:Label>\" +\n                                            \"<ogc:PropertyName>ZONENR</ogc:PropertyName>\" +\n                                        \"</sld:Label>\" +\n                                        \"<sld:Font>\" +\n                                            \"<sld:CssParameter name='font-family'>Arial</sld:CssParameter>\" +\n                                            \"<sld:CssParameter name='font-size'>10</sld:CssParameter>\" +\n                                        \"</sld:Font>\" +\n                                        \"<sld:Fill>\" +\n                                            \"<sld:CssParameter name='fill'>#FF9900</sld:CssParameter>\" +\n                                        \"</sld:Fill>\" +\n                                    \"</sld:TextSymbolizer>\" +\n                                \"</sld:Rule>\" +\n                            \"</sld:FeatureTypeStyle>\" +\n                        \"</sld:UserStyle>\" +\n                    \"</sld:NamedLayer>\" +\n                \"</sld:StyledLayerDescriptor>\"\n        });\n        \n        layerContext = format.layerToContext(layer);\n        got = parser.write_wmc_StyleList(layerContext);\n        expected =\n            \"<StyleList xmlns='http://www.opengis.net/context'>\" +\n                \"<Style current='1'>\" +\n                    \"<SLD>\" + \n                        \"<Title>Default</Title>\" +\n                        \"<sld:StyledLayerDescriptor version='1.0.0' \" +\n                            \"xmlns:sld='http://www.opengis.net/sld' \" +\n                            \"xmlns:ogc='http://www.opengis.net/ogc' \" +\n                            \"xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' \" +\n                            \"xsi:schemaLocation='http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd'>\" +\n                            \"<sld:NamedLayer>\" +\n                                \"<sld:Name>AAA212</sld:Name>\" +\n                                \"<sld:UserStyle>\" +\n                                    \"<sld:FeatureTypeStyle>\" +\n                                        \"<sld:Rule>\" +\n                                            \"<sld:TextSymbolizer>\" +\n                                                \"<sld:Label>\" +\n                                                    \"<ogc:PropertyName>ZONENR</ogc:PropertyName>\" +\n                                                \"</sld:Label>\" +\n                                                \"<sld:Font>\" +\n                                                    \"<sld:CssParameter name='font-family'>Arial</sld:CssParameter>\" +\n                                                    \"<sld:CssParameter name='font-size'>10</sld:CssParameter>\" +\n                                                \"</sld:Font>\" +\n                                                \"<sld:Fill>\" +\n                                                    \"<sld:CssParameter name='fill'>#FF9900</sld:CssParameter>\" +\n                                                \"</sld:Fill>\" +\n                                            \"</sld:TextSymbolizer>\" +\n                                        \"</sld:Rule>\" +\n                                    \"</sld:FeatureTypeStyle>\" +\n                                \"</sld:UserStyle>\" +\n                            \"</sld:NamedLayer>\" +\n                        \"</sld:StyledLayerDescriptor>\" +\n                    \"</SLD>\" +\n                \"</Style>\" + \n            \"</StyleList>\";\n        \n        t.xml_eq(got, expected, \"inline style correctly written\");\n        layer.destroy();\n\n        // test inline FeatureTypeStyle\n        layer = new OpenLayers.Layer.WMS(name, url, {\n            sld_body:\n                \"<sld:FeatureTypeStyle version='1.0.0' \" +\n                            \"xmlns:sld='http://www.opengis.net/sld' \" +\n                            \"xmlns:ogc='http://www.opengis.net/ogc' \" +\n                            \"xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' \" +\n                            \"xsi:schemaLocation='http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd'>\" +\n                    \"<sld:Rule>\" +\n                        \"<sld:TextSymbolizer>\" +\n                            \"<sld:Label>\" +\n                                \"<ogc:PropertyName>ZONENR</ogc:PropertyName>\" +\n                            \"</sld:Label>\" +\n                            \"<sld:Font>\" +\n                                \"<sld:CssParameter name='font-family'>Arial</sld:CssParameter>\" +\n                                \"<sld:CssParameter name='font-size'>10</sld:CssParameter>\" +\n                            \"</sld:Font>\" +\n                            \"<sld:Fill>\" +\n                                \"<sld:CssParameter name='fill'>#FF9900</sld:CssParameter>\" +\n                            \"</sld:Fill>\" +\n                        \"</sld:TextSymbolizer>\" +\n                    \"</sld:Rule>\" +\n                \"</sld:FeatureTypeStyle>\"\n        });\n\n        layerContext = format.layerToContext(layer);\n        got = parser.write_wmc_StyleList(layerContext);\n        expected =\n            \"<StyleList xmlns='http://www.opengis.net/context'>\" +\n                \"<Style current='1'>\" +\n                    \"<SLD>\" +\n                        \"<Title>Default</Title>\" +\n                        \"<sld:FeatureTypeStyle version='1.0.0' \" +\n                            \"xmlns:sld='http://www.opengis.net/sld' \" +\n                            \"xmlns:ogc='http://www.opengis.net/ogc' \" +\n                            \"xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' \" +\n                            \"xsi:schemaLocation='http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd'>\" +\n                            \"<sld:Rule>\" +\n                                \"<sld:TextSymbolizer>\" +\n                                    \"<sld:Label>\" +\n                                        \"<ogc:PropertyName>ZONENR</ogc:PropertyName>\" +\n                                    \"</sld:Label>\" +\n                                    \"<sld:Font>\" +\n                                        \"<sld:CssParameter name='font-family'>Arial</sld:CssParameter>\" +\n                                        \"<sld:CssParameter name='font-size'>10</sld:CssParameter>\" +\n                                    \"</sld:Font>\" +\n                                    \"<sld:Fill>\" +\n                                        \"<sld:CssParameter name='fill'>#FF9900</sld:CssParameter>\" +\n                                    \"</sld:Fill>\" +\n                                    \"</sld:TextSymbolizer>\" +\n                            \"</sld:Rule>\" +\n                        \"</sld:FeatureTypeStyle>\" +\n                    \"</SLD>\" +\n                \"</Style>\" +\n            \"</StyleList>\";\n\n        t.xml_eq(got, expected, \"inline FeatureTypeStyle correctly written\");\n        layer.destroy();\n    }\n    \n    function test_read_wmc_StyleList(t) {\n        t.plan(3);\n        \n        var xml = new OpenLayers.Format.XML();\n        var format = new OpenLayers.Format.WMC();\n        var parser = format.getParser(\"1\");\n        var node, text, layerContext, layer;\n\n        // test named style\n        text = \n            \"<StyleList xmlns='http://www.opengis.net/context'>\" +\n                \"<Style current='1'>\" +\n                    \"<Name>mystyle</Name><Title>Default</Title>\" +\n                \"</Style>\" +\n            \"</StyleList>\";\n        node = xml.read(text).documentElement;\n        layerContext = {\n            styles: []\n        };\n        parser.read_wmc_StyleList(layerContext, node);\n        layer = format.getLayerFromContext(layerContext);\n        t.eq(layer.params.STYLES, \"mystyle\", \"named style correctly read\");\n        \n        // test linked style\n        text = \n            \"<StyleList xmlns='http://www.opengis.net/context'>\" +\n                \"<Style current='1'>\" +\n                    \"<SLD>\" + \n                        \"<OnlineResource xmlns:xlink='http://www.w3.org/1999/xlink' \"+\n                                        \"xlink:type='simple' \" +\n                                        \"xlink:href='http://linked.sld' />\" +\n                    \"</SLD>\" + \n                \"</Style>\" +\n            \"</StyleList>\";\n        node = xml.read(text).documentElement;\n        layerContext = {\n            styles: []\n        };\n        parser.read_wmc_StyleList(layerContext, node);\n        layer = format.getLayerFromContext(layerContext);\n        t.eq(layer.params.SLD, \"http://linked.sld\", \"linked style correctly read\");        \n        \n        // test inline style\n        // any valid xml under the StyledLayerDescriptor node should make the\n        // round trip from string to node and back\n        text = \n            \"<StyleList xmlns='http://www.opengis.net/context'>\" +\n                \"<Style current='1'>\" +\n                    \"<SLD>\" + \n                        \"<sld:StyledLayerDescriptor version='1.0.0' \" +\n                            \"xmlns:sld='http://www.opengis.net/sld' \" +\n                            \"xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' \" +\n                            \"xsi:schemaLocation='http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd'>\" +\n                            \"<foo>bar<more/></foo>\" + \n                        \"</sld:StyledLayerDescriptor>\" + \n                    \"</SLD>\" + \n                \"</Style>\" +\n            \"</StyleList>\";\n        node = xml.read(text).documentElement;\n        layerContext = {\n            styles: []\n        };\n        parser.read_wmc_StyleList(layerContext, node);        \n        layer = format.getLayerFromContext(layerContext);\n        var expected = \n            \"<sld:StyledLayerDescriptor version='1.0.0' \" +\n                \"xmlns:sld='http://www.opengis.net/sld' \" +\n                \"xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' \" +\n                \"xsi:schemaLocation='http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd'>\" +\n                \"<foo xmlns='http://www.opengis.net/context'>bar<more/></foo>\" + \n            \"</sld:StyledLayerDescriptor>\";\n        t.xml_eq(layer.params.SLD_BODY, expected, \"inline style correctly read\");\n\n    }\n    \n\n    </script> \n</head> \n<body>\n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WMC/v1_1_0.html",
    "content": "<html>\n<head>\n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_write_wmc_Layer(t) {\n        if (OpenLayers.BROWSER_NAME == \"safari\") {\n            t.plan(0);\n            t.debug_print(\"Safari has wierd behavior with getElementsByTagNameNS: the result is that we can't run these tests there. Patches welcome.\");\n            return;\n        }\n        t.plan(12);\n\n        // direct construction of a parser for a unit test\n        var format = new OpenLayers.Format.WMC();\n        var parser = format.getParser(\"1_1_0\");\n        var sldNS = parser.namespaces[\"sld\"];\n\n        // test that Min/MaxScaleDenominator is not written out when no\n        // resolution related options are set\n        var layer = new OpenLayers.Layer.WMS(\n            \"test\", \"http://foo\", {},\n            {maxExtent: new OpenLayers.Bounds(1, 2, 3, 4)}\n        );\n        var layerContext = format.layerToContext(layer);\n        var node = parser.write_wmc_Layer(layerContext);\n        var minList = parser.getElementsByTagNameNS(node, sldNS, \"MinScaleDenominator\");\n        t.eq(minList.length, 0, \"(none) node not written with MinScaleDenominator\");\n        var maxList = parser.getElementsByTagNameNS(node, sldNS, \"MaxScaleDenominator\");\n        t.eq(maxList.length, 0, \"(none) node not written with MaxScaleDenominator\");\n\n        // test that Min/MaxScaleDenominator is written out for explicit\n        // resolutions array\n        layer = new OpenLayers.Layer.WMS(\n            \"test\", \"http://foo\", {},\n            {resolutions: [4, 2, 1], maxExtent: new OpenLayers.Bounds(1, 2, 3, 4)}\n        );\n        layer.minScale = Math.random();\n        layer.maxScale = Math.random();\n        sldNS = parser.namespaces[\"sld\"];\n        layerContext = format.layerToContext(layer);\n        node = parser.write_wmc_Layer(layerContext);\n        minList = parser.getElementsByTagNameNS(node, sldNS, \"MinScaleDenominator\");\n        t.eq(minList.length, 1, \"(resolutions) node written with MinScaleDenominator\");\n        t.eq(layer.maxScale.toPrecision(16), parser.getChildValue(minList[0]),\n             \"(resolutions) node written with correct MinScaleDenominator value\");\n        maxList = parser.getElementsByTagNameNS(node, sldNS, \"MaxScaleDenominator\");\n        t.eq(maxList.length, 1, \"(resolutions) node written with MaxScaleDenominator\");\n        t.eq(layer.minScale.toPrecision(16), parser.getChildValue(maxList[0]),\n             \"(resolutions) node written with correct MaxScaleDenominator value\");\n\n        layer = new OpenLayers.Layer.WMS(\n            \"test\", \"http://foo\", {},\n            {scales: [4, 2, 1], maxExtent: new OpenLayers.Bounds(1, 2, 3, 4)}\n        );\n        layer.minScale = Math.random();\n        layer.maxScale = Math.random();\n        layerContext = format.layerToContext(layer);\n        node = parser.write_wmc_Layer(layerContext);\n        minList = parser.getElementsByTagNameNS(node, sldNS, \"MinScaleDenominator\");\n        var f = new OpenLayers.Format.XML();\n        t.eq(minList.length, 1, \"(scales) node written with MinScaleDenominator\");\n        t.eq(layer.maxScale.toPrecision(16), parser.getChildValue(minList[0]),\n             \"(scales) node written with correct MinScaleDenominator value\");\n        maxList = parser.getElementsByTagNameNS(node, sldNS, \"MaxScaleDenominator\");\n        t.eq(maxList.length, 1, \"(scales) node written with MaxScaleDenominator\");\n        t.eq(layer.minScale.toPrecision(16), parser.getChildValue(maxList[0]),\n             \"(scales) node written with correct MaxScaleDenominator value\");\n\n        layer.metadataURL = 'http://foo';\n        layerContext = format.layerToContext(layer);\n        node = parser.write_wmc_Layer(layerContext);\n        t.eq(node.childNodes[3].localName || node.childNodes[3].nodeName.split(\":\").pop(),\n            'MetadataURL', \"MinScaleDenominator is written after MetadataURL, so third node should be MetadataURL\");\n        t.eq(node.childNodes[4].localName || node.childNodes[4].nodeName.split(\":\").pop(),\n            'MinScaleDenominator', \"MinScaleDenominator is written after MetadataURL, so fourth node should be MinScaleDenominator\");\n\n    }\n\n\n    </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 512px; height: 256px;\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WMC.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    var v1_0_0 = '<ViewContext xmlns=\"http://www.opengis.net/context\" version=\"1.0.0\" id=\"OpenLayers_Context_233\" xsi:schemaLocation=\"http://www.opengis.net/context http://schemas.opengis.net/context/1.0.0/context.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><General><Window width=\"512\" height=\"256\"/><BoundingBox minx=\"-109.9709708\" miny=\"27.01451459\" maxx=\"-80.02902918\" maxy=\"41.98548541\" SRS=\"EPSG:4326\"/><Title/><Extension><ol:maxExtent xmlns:ol=\"http://openlayers.org/context\" minx=\"-130.0000000\" miny=\"14.00000000\" maxx=\"-60.00000000\" maxy=\"55.00000000\"/></Extension></General><LayerList><Layer queryable=\"1\" hidden=\"0\"><Server service=\"OGC:WMS\" version=\"1.1.1\"><OnlineResource xlink:type=\"simple\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://t1.hypercube.telascience.org/cgi-bin/landsat7\"/></Server><Name>landsat7</Name><Title>NASA Global Mosaic</Title><FormatList><Format current=\"1\">image/jpeg</Format></FormatList><StyleList><Style current=\"1\"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol=\"http://openlayers.org/context\" minx=\"-130.0000000\" miny=\"14.00000000\" maxx=\"-60.00000000\" maxy=\"55.00000000\"/><ol:numZoomLevels xmlns:ol=\"http://openlayers.org/context\">4</ol:numZoomLevels><ol:units xmlns:ol=\"http://openlayers.org/context\">degrees</ol:units><ol:isBaseLayer xmlns:ol=\"http://openlayers.org/context\">true</ol:isBaseLayer><ol:displayInLayerSwitcher xmlns:ol=\"http://openlayers.org/context\">true</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol=\"http://openlayers.org/context\">false</ol:singleTile><ol:tileSize xmlns:ol=\"http://openlayers.org/context\" width=\"512\" height=\"1024\"/></Extension></Layer><Layer queryable=\"1\" hidden=\"1\"><Server service=\"OGC:WMS\" version=\"1.1.1\"><OnlineResource xlink:type=\"simple\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://labs.metacarta.com/wms/vmap0\"/></Server><Name>basic</Name><Title>OpenLayers WMS</Title><FormatList><Format current=\"1\">image/jpeg</Format></FormatList><StyleList><Style current=\"1\"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol=\"http://openlayers.org/context\" minx=\"-130.0000000\" miny=\"14.00000000\" maxx=\"-60.00000000\" maxy=\"55.00000000\"/><ol:numZoomLevels xmlns:ol=\"http://openlayers.org/context\">4</ol:numZoomLevels><ol:units xmlns:ol=\"http://openlayers.org/context\">degrees</ol:units><ol:isBaseLayer xmlns:ol=\"http://openlayers.org/context\">true</ol:isBaseLayer><ol:displayInLayerSwitcher xmlns:ol=\"http://openlayers.org/context\">true</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol=\"http://openlayers.org/context\">false</ol:singleTile></Extension></Layer><Layer queryable=\"1\" hidden=\"0\"><Server service=\"OGC:WMS\" version=\"1.1.1\"><OnlineResource xlink:type=\"simple\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://lioapp.lrc.gov.on.ca/cubeserv/cubeserv.pl\"/></Server><Name>na_road:CCRS</Name><Title>Transportation Network</Title><FormatList><Format current=\"1\">image/png</Format></FormatList><StyleList><Style current=\"1\"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol=\"http://openlayers.org/context\" minx=\"-166.5320000\" miny=\"4.050460000\" maxx=\"-0.2068180000\" maxy=\"70.28700000\"/><ol:transparent xmlns:ol=\"http://openlayers.org/context\">TRUE</ol:transparent><ol:gutter xmlns:ol=\"http://openlayers.org/context\">10</ol:gutter><ol:numZoomLevels xmlns:ol=\"http://openlayers.org/context\">4</ol:numZoomLevels><ol:units xmlns:ol=\"http://openlayers.org/context\">degrees</ol:units><ol:isBaseLayer xmlns:ol=\"http://openlayers.org/context\">false</ol:isBaseLayer><ol:opacity xmlns:ol=\"http://openlayers.org/context\">0.6</ol:opacity><ol:displayInLayerSwitcher xmlns:ol=\"http://openlayers.org/context\">false</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol=\"http://openlayers.org/context\">false</ol:singleTile></Extension></Layer><Layer queryable=\"1\" hidden=\"0\"><Server service=\"OGC:WMS\" version=\"1.1.1\"><OnlineResource xlink:type=\"simple\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://columbo.nrlssc.navy.mil/ogcwms/servlet/WMSServlet/AccuWeather_Maps.wms\"/></Server><Name>3:1</Name><Title>Radar 3:1</Title><FormatList><Format current=\"1\">image/png</Format></FormatList><StyleList><Style current=\"1\"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol=\"http://openlayers.org/context\" minx=\"-131.0294952\" miny=\"14.56289673\" maxx=\"-61.02950287\" maxy=\"54.56289673\"/><ol:transparent xmlns:ol=\"http://openlayers.org/context\">TRUE</ol:transparent><ol:numZoomLevels xmlns:ol=\"http://openlayers.org/context\">4</ol:numZoomLevels><ol:units xmlns:ol=\"http://openlayers.org/context\">degrees</ol:units><ol:isBaseLayer xmlns:ol=\"http://openlayers.org/context\">false</ol:isBaseLayer><ol:opacity xmlns:ol=\"http://openlayers.org/context\">0.8</ol:opacity><ol:displayInLayerSwitcher xmlns:ol=\"http://openlayers.org/context\">false</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol=\"http://openlayers.org/context\">true</ol:singleTile><ol:attribution xmlns:ol=\"http://openlayers.org/context\"><Title>Agglomération de Saint-Quentin</Title><OnlineResource xlink:type=\"simple\" xlink:href=\"http://www.agglo-saint-quentin.fr\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/><LogoURL width=\"171\" height=\"109\" format=\"image/png\"><OnlineResource xlink:type=\"simple\" xlink:href=\"http://www.geopicardie.fr/files/logos/logo_saint_quentin.png\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></LogoURL></ol:attribution></Extension></Layer></LayerList></ViewContext>';\n    var v1_1_0 = '<ViewContext xmlns=\"http://www.opengis.net/context\" version=\"1.1.0\" id=\"OpenLayers_Context_232\" xsi:schemaLocation=\"http://www.opengis.net/context http://schemas.opengis.net/context/1.1.0/context.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><General><Window width=\"512\" height=\"256\"/><BoundingBox minx=\"-109.9709708\" miny=\"27.01451459\" maxx=\"-80.02902918\" maxy=\"41.98548541\" SRS=\"EPSG:4326\"/><Title/><Extension><ol:maxExtent xmlns:ol=\"http://openlayers.org/context\" minx=\"-130.0000000\" miny=\"14.00000000\" maxx=\"-60.00000000\" maxy=\"55.00000000\"/></Extension></General><LayerList><Layer queryable=\"1\" hidden=\"0\"><Server service=\"OGC:WMS\" version=\"1.1.1\"><OnlineResource xlink:type=\"simple\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://t1.hypercube.telascience.org/cgi-bin/landsat7\"/></Server><Name>landsat7</Name><Title>NASA Global Mosaic</Title><sld:MinScaleDenominator xmlns:sld=\"http://www.opengis.net/sld\">6299645.760</sld:MinScaleDenominator><sld:MaxScaleDenominator xmlns:sld=\"http://www.opengis.net/sld\">31498228.80</sld:MaxScaleDenominator><FormatList><Format current=\"1\">image/jpeg</Format></FormatList><StyleList><Style current=\"1\"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol=\"http://openlayers.org/context\" minx=\"-130.0000000\" miny=\"14.00000000\" maxx=\"-60.00000000\" maxy=\"55.00000000\"/><ol:tileSize xmlns:ol=\"http://openlayers.org/context\" width=\"512\" height=\"1024\"/><ol:numZoomLevels xmlns:ol=\"http://openlayers.org/context\">4</ol:numZoomLevels><ol:units xmlns:ol=\"http://openlayers.org/context\">degrees</ol:units><ol:isBaseLayer xmlns:ol=\"http://openlayers.org/context\">true</ol:isBaseLayer><ol:displayInLayerSwitcher xmlns:ol=\"http://openlayers.org/context\">true</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol=\"http://openlayers.org/context\">false</ol:singleTile></Extension></Layer><Layer queryable=\"1\" hidden=\"1\"><Server service=\"OGC:WMS\" version=\"1.1.1\"><OnlineResource xlink:type=\"simple\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://labs.metacarta.com/wms/vmap0\"/></Server><Name>basic</Name><Title>OpenLayers WMS</Title><sld:MinScaleDenominator xmlns:sld=\"http://www.opengis.net/sld\">6299645.760</sld:MinScaleDenominator><sld:MaxScaleDenominator xmlns:sld=\"http://www.opengis.net/sld\">31498228.80</sld:MaxScaleDenominator><FormatList><Format current=\"1\">image/jpeg</Format></FormatList><StyleList><Style current=\"1\"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol=\"http://openlayers.org/context\" minx=\"-130.0000000\" miny=\"14.00000000\" maxx=\"-60.00000000\" maxy=\"55.00000000\"/><ol:tileSize xmlns:ol=\"http://openlayers.org/context\" width=\"512\" height=\"1024\"/><ol:numZoomLevels xmlns:ol=\"http://openlayers.org/context\">4</ol:numZoomLevels><ol:units xmlns:ol=\"http://openlayers.org/context\">degrees</ol:units><ol:isBaseLayer xmlns:ol=\"http://openlayers.org/context\">true</ol:isBaseLayer><ol:displayInLayerSwitcher xmlns:ol=\"http://openlayers.org/context\">true</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol=\"http://openlayers.org/context\">false</ol:singleTile></Extension></Layer><Layer queryable=\"1\" hidden=\"0\"><Server service=\"OGC:WMS\" version=\"1.1.1\"><OnlineResource xlink:type=\"simple\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://lioapp.lrc.gov.on.ca/cubeserv/cubeserv.pl\"/></Server><Name>na_road:CCRS</Name><Title>Transportation Network</Title><sld:MinScaleDenominator xmlns:sld=\"http://www.opengis.net/sld\">6200000.000</sld:MinScaleDenominator><sld:MaxScaleDenominator xmlns:sld=\"http://www.opengis.net/sld\">32000000.00</sld:MaxScaleDenominator><FormatList><Format current=\"1\">image/png</Format></FormatList><StyleList><Style current=\"1\"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol=\"http://openlayers.org/context\" minx=\"-166.5320000\" miny=\"4.050460000\" maxx=\"-0.2068180000\" maxy=\"70.28700000\"/><ol:tileSize xmlns:ol=\"http://openlayers.org/context\" width=\"512\" height=\"1024\"/><ol:transparent xmlns:ol=\"http://openlayers.org/context\">TRUE</ol:transparent><ol:numZoomLevels xmlns:ol=\"http://openlayers.org/context\">4</ol:numZoomLevels><ol:units xmlns:ol=\"http://openlayers.org/context\">degrees</ol:units><ol:isBaseLayer xmlns:ol=\"http://openlayers.org/context\">false</ol:isBaseLayer><ol:opacity xmlns:ol=\"http://openlayers.org/context\">0.6</ol:opacity><ol:displayInLayerSwitcher xmlns:ol=\"http://openlayers.org/context\">false</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol=\"http://openlayers.org/context\">false</ol:singleTile><ol:gutter xmlns:ol=\"http://openlayers.org/context\">10</ol:gutter></Extension></Layer><Layer queryable=\"1\" hidden=\"0\"><Server service=\"OGC:WMS\" version=\"1.1.1\"><OnlineResource xlink:type=\"simple\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://columbo.nrlssc.navy.mil/ogcwms/servlet/WMSServlet/AccuWeather_Maps.wms\"/></Server><Name>3:1</Name><Title>Radar 3:1</Title><sld:MinScaleDenominator xmlns:sld=\"http://www.opengis.net/sld\">6299645.760</sld:MinScaleDenominator><sld:MaxScaleDenominator xmlns:sld=\"http://www.opengis.net/sld\">31498228.80</sld:MaxScaleDenominator><FormatList><Format current=\"1\">image/png</Format></FormatList><StyleList><Style current=\"1\"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol=\"http://openlayers.org/context\" minx=\"-131.0294952\" miny=\"14.56289673\" maxx=\"-61.02950287\" maxy=\"54.56289673\"/><ol:transparent xmlns:ol=\"http://openlayers.org/context\">TRUE</ol:transparent><ol:numZoomLevels xmlns:ol=\"http://openlayers.org/context\">4</ol:numZoomLevels><ol:units xmlns:ol=\"http://openlayers.org/context\">degrees</ol:units><ol:isBaseLayer xmlns:ol=\"http://openlayers.org/context\">false</ol:isBaseLayer><ol:opacity xmlns:ol=\"http://openlayers.org/context\">0.8</ol:opacity><ol:displayInLayerSwitcher xmlns:ol=\"http://openlayers.org/context\">true</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol=\"http://openlayers.org/context\">true</ol:singleTile><ol:attribution xmlns:ol=\"http://openlayers.org/context\"><Title>Agglomération de Saint-Quentin</Title><OnlineResource xlink:type=\"simple\" xlink:href=\"http://www.agglo-saint-quentin.fr\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/><LogoURL width=\"171\" height=\"109\" format=\"image/png\"><OnlineResource xlink:type=\"simple\" xlink:href=\"http://www.geopicardie.fr/files/logos/logo_saint_quentin.png\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"/></LogoURL></ol:attribution></Extension></Layer></LayerList></ViewContext>';\n    var polar = '<ViewContext xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:default=\"http://www.opengis.net/context\" xmlns:ol=\"http://openlayers.org/context\" xmlns=\"http://www.opengis.net/context\" xmlns:wms=\"http://www.opengis.net/wms\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1.0\" id=\"OpenLayers_Context_466\" xsi:schemaLocation=\"http://www.opengis.net/context http://schemas.opengis.net/context/1.1.0/context.xsd\"><General><BoundingBox minx=\"-3000000\" miny=\"-3000000\" maxx=\"7000000\" maxy=\"7000000\" SRS=\"EPSG:32661\"/><Title>WMS viewer</Title><Extension><ol:maxExtent minx=\"-3000000\" miny=\"-3000000\" maxx=\"7000000\" maxy=\"7000000\"/><ol:units>m</ol:units></Extension></General><LayerList xmlns=\"http://www.opengis.net/context\"><Layer queryable=\"0\" hidden=\"0\"><Server service=\"OGC:WMS\" version=\"1.1.1\" foo=\"bar\"><OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://wms.met.no/maps/northpole.map\"/></Server><Name>world</Name><Title>The World</Title><FormatList><Format>image/jpeg</Format><Format current=\"1\">image/png</Format></FormatList></Layer></LayerList></ViewContext>';\n    var fulldoc = '<ViewContext xmlns=\"http://www.opengis.net/context\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:sld=\"http://www.opengis.net/sld\" version=\"1.1.0\" id=\"eos_data_gateways\" xsi:schemaLocation=\"http://www.opengis.net/context context.xsd\"><General><Window width=\"500\" height=\"300\"/><BoundingBox SRS=\"EPSG:4326\" minx=\"-180.000000\" miny=\"-90.000000\" maxx=\"180.000000\" maxy=\"90.000000\"/><Title>EOS Data Gateways</Title><KeywordList><Keyword>EOS</Keyword><Keyword>EOSDIS</Keyword><Keyword>NASA</Keyword><Keyword>CCRS</Keyword><Keyword>CEOS</Keyword><Keyword>OGC</Keyword></KeywordList><Abstract>Map View of EOSDIS partners locations</Abstract><LogoURL width=\"130\" height=\"74\" format=\"image/gif\"><OnlineResource xlink:type=\"simple\" xlink:href=\"http://redhook.gsfc.nasa.gov/~imswww/pub/icons/logo.gif\"/></LogoURL><DescriptionURL format=\"text/html\"><OnlineResource xlink:type=\"simple\" xlink:href=\"http://eos.nasa.gov/imswelcome\"/></DescriptionURL><ContactInformation><ContactPersonPrimary><ContactPerson>Tom Kralidis</ContactPerson><ContactOrganization>Environment Canada</ContactOrganization></ContactPersonPrimary><ContactPosition>Systems Scientist</ContactPosition><ContactAddress><AddressType>postal</AddressType><Address>867 Lakeshore Road</Address><City>Burlington</City><StateOrProvince>Ontario</StateOrProvince><PostCode>L7R 4A6</PostCode><Country>Canada</Country></ContactAddress><ContactVoiceTelephone>+01-905-336-4409</ContactVoiceTelephone><ContactFacsimileTelephone>+01-905-336-4499</ContactFacsimileTelephone><ContactElectronicMailAddress>tom.kralidis@ec.gc.ca</ContactElectronicMailAddress></ContactInformation></General><LayerList><Layer queryable=\"1\" hidden=\"0\"><Server service=\"OGC:WMS\" version=\"1.1.1\" title=\"ESA CubeSERV\"><OnlineResource xlink:type=\"simple\" xlink:href=\"http://mapserv2.esrin.esa.it/cubestor/cubeserv/cubeserv.cgi\"/></Server><Name>WORLD_MODIS_1KM:MapAdmin</Name><Title>WORLD_MODIS_1KM</Title><Abstract>Global maps derived from various Earth Observation sensors / WORLD_MODIS_1KM:MapAdmin</Abstract><SRS>EPSG:4326</SRS><FormatList><Format current=\"1\">image/png</Format><Format>image/gif</Format><Format>image/jpeg</Format></FormatList><StyleList><Style current=\"1\"><Name>default</Name><Title>default</Title><LegendURL width=\"16\" height=\"16\" format=\"image/gif\"><OnlineResource xlink:type=\"simple\" xlink:href=\"http://mapserv2.esrin.esa.it/cubestor/cubeserv/cubeserv.cgi?version=1.1.1&amp;request=GetLegendGraphic&amp;layer=WORLD_MODIS_1KM:MapAdmin&amp;style=default&amp;format=image/gif\"/></LegendURL></Style></StyleList></Layer><Layer queryable=\"0\" hidden=\"0\"><Server service=\"OGC:WMS\" version=\"1.1.1\" title=\"The GLOBE Program Visualization Server\"><OnlineResource xlink:type=\"simple\" xlink:href=\"http://globe.digitalearth.gov/viz-bin/wmt.cgi\"/></Server><Name>COASTLINES</Name><Title>Coastlines</Title><Abstract>Context layer: Coastlines</Abstract><SRS>EPSG:4326</SRS><SRS>EPSG:900913</SRS><FormatList><Format current=\"1\">image/gif</Format><Format>image/png</Format></FormatList><StyleList><Style current=\"1\"><Name>default</Name><Title>Default</Title><LegendURL width=\"180\" format=\"image/gif\" height=\"50\"><OnlineResource xlink:type=\"simple\" xlink:href=\"http://globe.digitalearth.gov/globe/en/icons/colorbars/COASTLINES.gif\"/></LegendURL></Style></StyleList><DimensionList><Dimension name=\"time\" units=\"ISO8601\" nearestValue=\"1\">2011-03-31,2011-04-01</Dimension></DimensionList></Layer><Layer queryable=\"1\" hidden=\"0\"><Server service=\"OGC:WMS\" version=\"1.1.1\" title=\"The GLOBE Program Visualization Server\"><OnlineResource xlink:type=\"simple\" xlink:href=\"http://globe.digitalearth.gov/viz-bin/wmt.cgi\"/></Server><Name>NATIONAL</Name><Title>National Boundaries</Title><Abstract>Context layer: National Boundaries</Abstract><DataURL><OnlineResource xlink:type=\"simple\" xlink:href=\"http://globe.digitalearth.gov/data/national.gml\"/></DataURL><MetadataURL><OnlineResource xlink:type=\"simple\" xlink:href=\"http://globe.digitalearth.gov/metadata/national.txt\"/></MetadataURL><SRS>EPSG:4326</SRS><FormatList><Format current=\"1\">image/gif</Format><Format>image/png</Format></FormatList><StyleList><Style current=\"1\"><Name>default</Name><Title>Default</Title><LegendURL width=\"180\" format=\"image/gif\" height=\"50\"><OnlineResource xlink:type=\"simple\" xlink:href=\"http://globe.digitalearth.gov/globe/en/icons/colorbars/NATIONAL.gif\"/></LegendURL></Style></StyleList></Layer><Layer queryable=\"1\" hidden=\"0\"><Server service=\"OGC:WMS\" version=\"1.1.1\" title=\"Canada Centre for Remote Sensing Web Map Service\"><OnlineResource xlink:type=\"simple\" xlink:href=\"http://ceoware2.ccrs.nrcan.gc.ca/cubewerx/cubeserv/cubeserv.cgi\"/></Server><Name>EOS_DATA_GATEWAYS:CEOWARE2</Name><Title>EOS Data Gateways</Title><Abstract>Locations of EOS Data Gateway Locations. The same services and data are available through each gateway location.</Abstract><sld:MinScaleDenominator>1000</sld:MinScaleDenominator><sld:MaxScaleDenominator>500000</sld:MaxScaleDenominator><SRS>EPSG:4326</SRS><FormatList><Format current=\"1\">image/gif</Format><Format>image/png</Format><Format>image/jpeg</Format></FormatList><StyleList><Style current=\"1\"><Name>default</Name><Title>default</Title><LegendURL width=\"16\" height=\"16\" format=\"image/gif\"><OnlineResource xlink:type=\"simple\" xlink:href=\"http://ceoware2.ccrs.nrcan.gc.ca/cubewerx/cubeserv/cubeserv.cgi?version=1.1.1&amp;request=GetLegendGraphic&amp;layer=EOS_DATA_GATEWAYS:CEOWARE2&amp;style=default&amp;format=image/gif\"/></LegendURL></Style><Style><SLD><Title>Default</Title><sld:StyledLayerDescriptor xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:sld=\"http://www.opengis.net/sld\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" version=\"1.0.0\" xsi:schemaLocation=\"http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd\"><sld:NamedLayer><sld:Name>AAA212</sld:Name><sld:UserStyle><sld:FeatureTypeStyle><sld:Rule><sld:TextSymbolizer><sld:Label><ogc:PropertyName>ZONENR</ogc:PropertyName></sld:Label><sld:Font><sld:CssParameter name=\"font-family\">Arial</sld:CssParameter><sld:CssParameter name=\"font-size\">10</sld:CssParameter></sld:Font><sld:Fill><sld:CssParameter name=\"fill\">#FF9900</sld:CssParameter></sld:Fill></sld:TextSymbolizer></sld:Rule></sld:FeatureTypeStyle></sld:UserStyle></sld:NamedLayer></sld:StyledLayerDescriptor></SLD></Style><Style><SLD><Title>Default</Title><sld:FeatureTypeStyle xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:sld=\"http://www.opengis.net/sld\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" version=\"1.0.0\" xsi:schemaLocation=\"http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd\"><sld:Rule><sld:TextSymbolizer><sld:Label><PropertyName>ZONENR</PropertyName></sld:Label><sld:Font><sld:CssParameter name=\"font-family\">Arial</sld:CssParameter><sld:CssParameter name=\"font-size\">10</sld:CssParameter></sld:Font><sld:Fill><sld:CssParameter name=\"fill\">#FF9900</sld:CssParameter></sld:Fill></sld:TextSymbolizer></sld:Rule></sld:FeatureTypeStyle></SLD></Style></StyleList></Layer></LayerList></ViewContext>';\n\n    function test_Format_WMC_read(t) {\n        t.plan(68);\n\n        var format = new OpenLayers.Format.WMC();        \n        var map, layer;\n        \n        // test v1.0.0\n        map = format.read(v1_0_0, {map: \"map\"});\n        t.eq(map.center.lon.toPrecision(6), (-95).toPrecision(6), \"(v1.0.0) map center correctly set\");\n        t.eq(map.center.lat.toPrecision(6), (34.5).toPrecision(6), \"(v1.0.0) map center correctly set\");\n        t.eq(map.maxExtent.left.toPrecision(6), (-130).toPrecision(6), \"(v1.0.0) map maxExtent correctly set\");\n        t.eq(map.layers.length, 4, \"(v1.0.0) correct number of layers\");\n        t.eq(map.projection, \"EPSG:4326\", \"(v1.0.0) map projection set correctly\");\n        // check out first base layer\n        layer = map.layers[0];\n        t.eq(layer.queryable, true, \"(1.0.0) Layer is queryable\");    \n        t.ok(layer instanceof OpenLayers.Layer.WMS,\n             \"(v1.0.0) wms layer correctly instantiated\");\n        t.eq(layer.url, \"http://t1.hypercube.telascience.org/cgi-bin/landsat7\",\n             \"(v1.0.0) layer url correctly set\");\n        t.eq(layer.maxExtent.right.toPrecision(6), (-60).toPrecision(6),\n             \"(v1.0.0) layer maxExtent correctly set\");\n        t.eq(layer.numZoomLevels, 4,\n             \"(v1.0.0) layer numZoomLevels correctly set\");\n        t.eq(layer.isBaseLayer, true,\n             \"(v1.0.0) layer isBaseLayer correctly set for base layer\");\n        t.eq(layer.tileSize.w, 512, \n             \"(v1.0.0) layer tileSize width correctly set\");\n        t.eq(layer.tileSize.h, 1024, \n             \"(v1.0.0) layer tileSize height correctly set\");\n        // check out layer not in switcher\n        layer = map.layers[2];\n        t.eq(layer.displayInLayerSwitcher, false, \n             \"(v1.0.0) layer displayInLayerSwitcher correctly set\");\n        t.eq(layer.params[\"TRANSPARENT\"], \"TRUE\", \n             \"(v1.0.0) layer param.transparent correctly set\");\n        t.eq(layer.isBaseLayer, false,\n             \"(v1.0.0) layer isBaseLayer correctly set for overlay\");\n        t.eq(layer.gutter, 10,\n             \"(v1.0.0) layer gutter correctly set for overlay\");\n        // check out single tile overlay\n        layer = map.layers[3];\n        t.eq(layer.singleTile, true, \n             \"(v1.0.0) layer singleTile correctly set\");\n        t.eq(layer.opacity, 0.8, \n             \"(v1.0.0) layer opacity correctly set\");\n        // check attribution\n        t.eq(layer.attribution, {title:\"Agglomération de Saint-Quentin\", href:\"http://www.agglo-saint-quentin.fr\", logo:{format:\"image/png\", width:\"171\", height:\"109\", href:\"http://www.geopicardie.fr/files/logos/logo_saint_quentin.png\"}}, \"(v1.0.0) layer attribution correctly set\");\n        map.destroy();\n\n        // test v1.1.0\n        map = format.read(v1_1_0, {map: \"map\"});\n        t.eq(map.center.lon.toPrecision(6), (-95).toPrecision(6), \"(v1.1.0) map center correctly set\");\n        t.eq(map.center.lat.toPrecision(6), (34.5).toPrecision(6), \"(v1.1.0) map center correctly set\");\n        t.eq(map.maxExtent.left.toPrecision(6), (-130).toPrecision(6), \"(v1.1.0) map maxExtent correctly set\");\n        t.eq(map.layers.length, 4, \"(v1.1.0) correct number of layers\");\n        t.eq(map.projection, \"EPSG:4326\", \"(v1.1.0) map projection set correctly\");\n        // check out first baseLayer\n        layer = map.layers[0];\n        t.ok(layer instanceof OpenLayers.Layer.WMS,\n             \"(v1.1.0) wms layer correctly instantiated\");\n        t.eq(layer.url, \"http://t1.hypercube.telascience.org/cgi-bin/landsat7\",\n             \"(v1.1.0) layer url correctly set\");\n        t.eq(layer.maxExtent.right.toPrecision(6), (-60).toPrecision(6),\n             \"(v1.1.0) layer maxExtent correctly set\");\n        t.eq(layer.numZoomLevels, 4,\n             \"(v1.1.0) layer numZoomLevels correctly set\");\n        t.eq(layer.isBaseLayer, true,\n             \"(v1.1.0) layer isBaseLayer correctly set for overlay\");\n        // check out layer not in switcher\n        layer = map.layers[2];\n        t.eq(layer.displayInLayerSwitcher, false, \n             \"(v1.1.0) layer displayInLayerSwitcher correctly set\");\n        t.eq(layer.params[\"TRANSPARENT\"], \"TRUE\", \n             \"(v1.1.0) layer param.transparent correctly set\");\n        t.eq(layer.isBaseLayer, false,\n             \"(v1.1.0) layer isBaseLayer correctly set for overlay\");\n        t.eq(layer.gutter, 10,\n             \"(v1.1.0) layer gutter correctly set for overlay\");\n        t.eq(layer.minScale.toPrecision(6), (32000000).toPrecision(6), \n             \"(v1.1.0) layer minScale correctly set\");\n        t.eq(layer.maxScale.toPrecision(6), (6200000).toPrecision(6), \n             \"(v1.1.0) layer maxScale correctly set\");\n        // check out single tile overlay\n        layer = map.layers[3];\n        t.eq(layer.singleTile, true, \n             \"(v1.1.0) layer singleTile correctly set\");\n        t.eq(layer.opacity, 0.8, \n             \"(v1.1.0) layer opacity correctly set\");\n        // check attribution\n        t.eq(layer.attribution, {title:\"Agglomération de Saint-Quentin\", href:\"http://www.agglo-saint-quentin.fr\", logo:{format:\"image/png\", width:\"171\", height:\"109\", href:\"http://www.geopicardie.fr/files/logos/logo_saint_quentin.png\"}}, \"(v1.1.0) layer attribution correctly set\");\n        map.destroy();\n\n        // Check if maxResolution is set correctly\n        map = format.read(polar, {map: \"map\"});\n        t.eq(map.maxResolution, 39062.5,\n             \"maxResolution correctly set\");\n        map.destroy();\n\n        // test mapOptions\n        map = format.read(v1_1_0, {map: {foo: 'bar', div: 'map'}});\n        t.eq(map.foo, \"bar\",\n            \"mapOptions correctly passed to the created map object\");\n        map.destroy();\n        \n        map = format.read(fulldoc, {map: \"map\"});\n\n        var meta = map.metadata;\n\n        // Check if ContextInformation is set properly\n        var cinfo = meta.contactInformation;\n\n        t.eq(cinfo.personPrimary.person,       \"Tom Kralidis\",       \"got correct person\");\n        t.eq(cinfo.personPrimary.organization, \"Environment Canada\", \"got correct organization\");\n\n        t.eq(cinfo.contactAddress.address,     \"867 Lakeshore Road\", \"got correct address\");\n        t.eq(cinfo.contactAddress.city,        \"Burlington\",         \"got correct city\");\n        t.eq(cinfo.contactAddress.country,     \"Canada\",             \"got correct country\");\n        t.eq(cinfo.contactAddress.postcode,    \"L7R 4A6\",            \"got correct postcode\");\n        t.eq(cinfo.contactAddress.stateOrProvince, \"Ontario\",        \"got correct stateOrProvince\");\n        t.eq(cinfo.contactAddress.type,        \"postal\",             \"got correct address type\");\n\n        t.eq(cinfo.email,    \"tom.kralidis@ec.gc.ca\", \"got correct email\");\n        t.eq(cinfo.fax,      \"+01-905-336-4499\",      \"got correct fax number\");\n        t.eq(cinfo.phone,    \"+01-905-336-4409\",      \"got correct phone number\");\n        t.eq(cinfo.position, \"Systems Scientist\",     \"got correct position\");\n\n        // Check if LogoURL is read properly\n        var logo = meta.logo;\n        t.eq(logo, {\n                href: \"http://redhook.gsfc.nasa.gov/~imswww/pub/icons/logo.gif\",\n                width: \"130\",\n                height: \"74\",\n                format: \"image/gif\"},\n            \"got currect logo\");\n\n        t.eq(meta.descriptionURL, \"http://eos.nasa.gov/imswelcome\", \"got correct descriptionURL\");\n\n        t.eq(meta.keywords,\n             [\"EOS\", \"EOSDIS\", \"NASA\", \"CCRS\", \"CEOS\", \"OGC\"],\n             \"got correct keywords\");\n\n        layer = map.layers[1];\n\n        t.eq(layer.metadata.servertitle,\n             \"The GLOBE Program Visualization Server\",\n             \"got correct title for server\");\n\n        t.eq(layer.srs,\n             {\"EPSG:4326\": true, \"EPSG:900913\": true},\n             \"SRS read correctly\");\n\n        t.eq(layer.metadata.formats,\n             [{value: \"image/gif\", current: true},\n              {value: \"image/png\"}],\n             \"formats read correctly\");\n\n        var style = layer.metadata.styles[0];\n        t.eq(style.legend, {\n                href: \"http://globe.digitalearth.gov/globe/en/icons/colorbars/COASTLINES.gif\",\n                width: \"180\",\n                height: \"50\",\n                format: \"image/gif\"},\n            \"got currect legend\");\n\n\n        var dim = layer.dimensions[\"time\"];\n        t.eq(dim.name, \"time\", \"got correct name of dimension\");\n        t.eq(dim.units, \"ISO8601\", \"got correct units for dimension\");\n        t.eq(dim.nearestValue, true, \"got correct value for nearestValue\");\n        t.eq(dim.values, [\"2011-03-31\", \"2011-04-01\"], \"got correct values for dimension\");\n\n        layer = map.layers[2];\n        t.eq(layer.metadata.dataURL,\n             \"http://globe.digitalearth.gov/data/national.gml\",\n             \"got correct dataURL\");\n        t.eq(layer.metadataURL,\n             \"http://globe.digitalearth.gov/metadata/national.txt\",\n             \"got correct metadataURL\");\n\n        layer = map.layers[3];\n        var sld_body = '<sld:StyledLayerDescriptor xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:sld=\"http://www.opengis.net/sld\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" version=\"1.0.0\" xsi:schemaLocation=\"http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd\"><sld:NamedLayer><sld:Name>AAA212</sld:Name><sld:UserStyle><sld:FeatureTypeStyle><sld:Rule><sld:TextSymbolizer><sld:Label><ogc:PropertyName>ZONENR</ogc:PropertyName></sld:Label><sld:Font><sld:CssParameter name=\"font-family\">Arial</sld:CssParameter><sld:CssParameter name=\"font-size\">10</sld:CssParameter></sld:Font><sld:Fill><sld:CssParameter name=\"fill\">#FF9900</sld:CssParameter></sld:Fill></sld:TextSymbolizer></sld:Rule></sld:FeatureTypeStyle></sld:UserStyle></sld:NamedLayer></sld:StyledLayerDescriptor>';\n        var styles = layer.metadata.styles;\n        t.xml_eq(styles[1].body, sld_body, \"StyledLayerDescriptor body read correctly\");\n\n        sld_body = '<sld:FeatureTypeStyle xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:sld=\"http://www.opengis.net/sld\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" version=\"1.0.0\" xsi:schemaLocation=\"http://www.opengis.net/sld http://schemas.opengeospatial.net/sld/1.0.0/StyledLayerDescriptor.xsd\"><sld:Rule><sld:TextSymbolizer><sld:Label><PropertyName xmlns=\"http://www.opengis.net/context\">ZONENR</PropertyName></sld:Label><sld:Font><sld:CssParameter name=\"font-family\">Arial</sld:CssParameter><sld:CssParameter name=\"font-size\">10</sld:CssParameter></sld:Font><sld:Fill><sld:CssParameter name=\"fill\">#FF9900</sld:CssParameter></sld:Fill></sld:TextSymbolizer></sld:Rule></sld:FeatureTypeStyle>';\n        t.xml_eq(styles[2].body, sld_body, \"FeatureTypeStyle body read correctly\");\n\n    }\n    \n    function test_Format_WMC_write(t) {\n        \n        var format = new OpenLayers.Format.WMC();        \n        var map = format.read(v1_1_0, {map: \"map\"});\n        var wmc;\n        \n        function sanitize(str) {\n            // id is unique so we don't expect it to be the same\n            str = str.replace(/OpenLayers_Context_\\d+/, \"foo\");\n            // FF and IE differ on ordering of attribute nodes\n            // a better way to compare xml would be nice\n            str = str.replace(/\\s*xsi:schemaLocation=\".*?\"/, \"\");\n            str = str.replace(/\\s*xmlns:xlink=\".*?\"/g, \"\");\n            // and of course floating point precision is an issue\n            str = str.replace(/(-?\\d+\\.\\d+)/g, function(m) {return parseFloat(m).toPrecision(6)});\n            return str;\n        }\n\n        /**\n         * Version 1.0.0 doesn't make the round trip because min/max resolutions\n         * are not stored.  Version 1.1.0 introduced minScaleDenominator and\n         * maxScaleDenominator.  The parser still writes valid WMC v1.0.0, you\n         * just need a validator to prove it.\n         *\n         * The wmc.html example can be used to produce WMC docs for validation.\n         * Prior to validation, the Extension tags need to be removed unless someone\n         * cares to write and maintain some XSD.  Both version 1.0.0 and 1.1.0\n         * validate on http://www.validome.org/xml/.\n         */\n\n        // test v1.1.0\n        if(OpenLayers.BROWSER_NAME== \"opera\") {\n            t.plan(0);\n            t.debug_print(\"WMC writing works but is not tested in Opera\");\n        } else {\n            t.plan(11);\n\n            map = format.read(v1_1_0, {map: \"map\"});\n            wmc = format.write(map);\n            t.eq(sanitize(wmc), sanitize(v1_1_0),\n                 \"(v1.1.0) write gives what read got\");\n            map.destroy();\n\n            var parser = format.getParser(\"1.1.0\");\n            map = format.read(fulldoc, {map: \"map\"});\n            var context = format.toContext(map);\n\n            // KeywordList\n            var expected = '<KeywordList xmlns=\"http://www.opengis.net/context\"><Keyword>EOS</Keyword><Keyword>EOSDIS</Keyword><Keyword>NASA</Keyword><Keyword>CCRS</Keyword><Keyword>CEOS</Keyword><Keyword>OGC</Keyword></KeywordList>';\n            t.xml_eq(parser.write_wmc_KeywordList(context.keywords),\n                     expected,\n                     \"keywordlist written correctly\");\n\n            // ContactInformation\n            expected = '<ContactInformation xmlns=\"http://www.opengis.net/context\"><ContactPersonPrimary><ContactPerson>Tom Kralidis</ContactPerson><ContactOrganization>Environment Canada</ContactOrganization></ContactPersonPrimary><ContactPosition>Systems Scientist</ContactPosition><ContactAddress><AddressType>postal</AddressType><Address>867 Lakeshore Road</Address><City>Burlington</City><StateOrProvince>Ontario</StateOrProvince><PostCode>L7R 4A6</PostCode><Country>Canada</Country></ContactAddress><ContactVoiceTelephone>+01-905-336-4409</ContactVoiceTelephone><ContactFacsimileTelephone>+01-905-336-4499</ContactFacsimileTelephone><ContactElectronicMailAddress>tom.kralidis@ec.gc.ca</ContactElectronicMailAddress></ContactInformation>';\n            t.xml_eq(parser.write_wmc_ContactInformation(context.contactInformation),\n                     expected,\n                     \"contactInformation written correctly\");\n\n            // LogoURL\n            expected = '<LogoURL xmlns=\"http://www.opengis.net/context\" width=\"130\" height=\"74\" format=\"image/gif\"><OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://redhook.gsfc.nasa.gov/~imswww/pub/icons/logo.gif\"/></LogoURL>';\n            t.xml_eq(parser.write_wmc_URLType(\"LogoURL\", context.logo.href, context.logo),\n                     expected,\n                     \"LogoURL written correctly\");\n\n            // DescriptionURL\n            expected = '<DescriptionURL xmlns=\"http://www.opengis.net/context\"><OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://eos.nasa.gov/imswelcome\"/></DescriptionURL>';\n            t.xml_eq(parser.write_wmc_URLType(\"DescriptionURL\", context.descriptionURL),\n                     expected,\n                     \"DescriptionURL written correctly\");\n\n\n            var layerContext = context.layersContext[1];\n\n            // Server\n            expected = '<Server xmlns=\"http://www.opengis.net/context\" service=\"OGC:WMS\" version=\"1.1.1\" title=\"The GLOBE Program Visualization Server\"><OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://globe.digitalearth.gov/viz-bin/wmt.cgi\"/></Server>';\n            t.xml_eq(parser.write_wmc_Server(layerContext),\n                     expected,\n                     \"Server written correctly\");\n\n            // FormatList\n            expected = '<FormatList xmlns=\"http://www.opengis.net/context\"><Format current=\"1\">image/gif</Format><Format>image/png</Format></FormatList>';\n            t.xml_eq(parser.write_wmc_FormatList(layerContext),\n                     expected,\n                     \"FormatList written correctly\");\n\n            // DimensionList\n            expected = '<DimensionList xmlns=\"http://www.opengis.net/context\"><Dimension name=\"time\" units=\"ISO8601\" nearestValue=\"1\" unitSymbol=\"\" userValue=\"\" multipleValues=\"0\" current=\"0\" default=\"\">2011-03-31,2011-04-01</Dimension></DimensionList>';\n            t.xml_eq(parser.write_wmc_DimensionList(layerContext),\n                     expected,\n                     \"DimensionList written correctly\");\n\n            // LegendURL\n            var legend = layerContext.styles[0].legend;\n            expected = '<LegendURL xmlns=\"http://www.opengis.net/context\" width=\"180\" format=\"image/gif\" height=\"50\"><OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://globe.digitalearth.gov/globe/en/icons/colorbars/COASTLINES.gif\"/></LegendURL>';\n            t.xml_eq(parser.write_wmc_URLType(\"LegendURL\", legend.href, legend),\n                     expected,\n                     \"LegendURL written correctly\");\n\n            layerContext = context.layersContext[2];\n\n            // DataURL\n            expected = '<DataURL xmlns=\"http://www.opengis.net/context\"><OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://globe.digitalearth.gov/data/national.gml\" /></DataURL>';\n            t.xml_eq(parser.write_wmc_URLType(\"DataURL\", layerContext.dataURL),\n                     expected,\n                     \"DataURL written correctly\");\n\n            // MetadataURL\n            expected = '<MetadataURL xmlns=\"http://www.opengis.net/context\"><OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://globe.digitalearth.gov/metadata/national.txt\" /></MetadataURL>';\n            t.xml_eq(parser.write_wmc_URLType(\"MetadataURL\", layerContext.metadataURL),\n                     expected,\n                     \"MetadataURL written correctly\");\n\n        }\n\n    }\n\n    </script> \n</head> \n<body>\n    <div id=\"map\" style=\"width: 512px; height: 256px;\"></div>\n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WMSCapabilities/v1_1_1.html",
    "content": "<html> \n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_read_exception(t) {\n        t.plan(1);\n        var xml = document.getElementById(\"exceptionsample\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n        var format = new OpenLayers.Format.WMSCapabilities();\n        var obj = format.read(doc);\n        t.ok(!!obj.error, \"Error reported correctly\");\n    }\n    \n    function test_read(t) {\n        \n        t.plan(24);\n\n        var xml = document.getElementById(\"gssample\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n        var format = new OpenLayers.Format.WMSCapabilities();\n        var obj = format.read(doc);\n        \n        var capability = obj.capability;\n        t.ok(capability, \"object contains capability property\");\n        \n        var getmap = capability.request.getmap;\n        t.eq(getmap.formats.length, 28, \"getmap formats parsed\");\n        t.eq(\n            getmap.href,\n            \"http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&\",\n            \"getmap href parsed\"\n        );\n        t.eq(\n            getmap.get.href,\n            getmap.href,\n            \"getmap.get.href parsed\"\n        );\n        t.eq(\n            getmap.post,\n            undefined,\n            \"getmap.post not available\"\n        );\n\n        var describelayer = capability.request.describelayer;\n        t.eq(\n            describelayer.href,\n            \"http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&\",\n            \"describelayer href parsed\"\n        );\n        t.eq(\n            describelayer.get.href,\n            describelayer.href,\n            \"describelayer.get.href parsed\"\n        );\n        t.eq(\n            describelayer.post,\n            undefined,\n            \"describelayer.post not available\"\n        );\n        \n        var getfeatureinfo = capability.request.getfeatureinfo;\n        t.eq(\n            getfeatureinfo.href,\n            \"http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&\",\n            \"getfeatureinfo href parsed\"\n        );\n        t.eq(\n            getfeatureinfo.get.href,\n            getfeatureinfo.href,\n            \"getmap.get.href parsed\"\n        );\n        t.eq(\n            getfeatureinfo.post.href,\n            \"http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&\",\n            \"getfeatureinfo.post set correctly\"\n        );\n        \n        t.ok(capability.layers, \"layers parsed\");\n        t.eq(capability.layers.length, 22, \"correct number of layers parsed\");\n        \n        var layer = capability.layers[2];\n        t.eq(layer.infoFormats, [\"text/plain\", \"text/html\", \"application/vnd.ogc.gml\"], \"infoFormats set on layer\");\n        t.eq(layer.name, \"tiger:tiger_roads\", \"[2] correct layer name\");\n        t.eq(layer.prefix, \"tiger\", \"[2] correct layer prefix\");\n        t.eq(layer.title, \"Manhattan (NY) roads\", \"[2] correct layer title\");\n        t.eq(\n            layer[\"abstract\"],\n            \"Highly simplified road layout of Manhattan in New York..\",\n            \"[2] correct layer abstract\"\n        );\n        t.eq(\n            layer.llbbox,\n            [-74.08769307536667, 40.660618924633326, -73.84653192463333, 40.90178007536667],\n            \"[2] correct layer bbox\"\n        );\n        t.eq(layer.styles.length, 1, \"[2] correct styles length\");\n        t.eq(layer.styles[0].name, \"tiger_roads\", \"[2] correct style name\");\n        t.eq(\n            layer.styles[0].legend.href,\n            \"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&FORMAT=image/png&WIDTH=20&HEIGHT=20&LAYER=tiger:tiger_roads\",\n            \"[2] correct legend url\"\n        );\n        t.eq(\n            layer.styles[0].legend.format, \"image/png\",\n            \"[2] correct legend format\"\n        );\n        t.eq(layer.queryable, true, \"[2] correct queryable attribute\");\n        \n\n    }\n\n    function test_layers(t) {\n\n        t.plan(24);\n\n        var xml = document.getElementById(\"ogcsample\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n\n        var obj = new OpenLayers.Format.WMSCapabilities().read(doc);\n        var capability = obj.capability;\n\n        var layers = {};\n        for (var i=0, len=capability.layers.length; i<len; i++) {\n            if (\"name\" in capability.layers[i]) {\n                layers[ capability.layers[i].name ] = capability.layers[i];\n            }\n        }\n\n        var rootlayer = capability.layers[ capability.layers.length - 1];\n\n        t.eq(rootlayer.srs, \n             {\"EPSG:4326\": true},\n             \"SRS parsed correctly for root layer\");\n        t.eq(layers[\"ROADS_RIVERS\"].srs,\n             {\"EPSG:4326\": true, \"EPSG:26986\": true},\n             \"Inheritance of SRS handled correctly when adding SRSes\");\n        t.eq(layers[\"Temperature\"].srs,\n             {\"EPSG:4326\": true},\n             \"Inheritance of SRS handled correctly when redeclaring an inherited SRS\");\n\n        var bbox = layers[\"ROADS_RIVERS\"].bbox[\"EPSG:26986\"];\n        t.eq(bbox.bbox,\n             [189000, 834000, 285000, 962000],\n             \"Correct bbox from BoundingBox\");\n        t.eq(bbox.res, {x: 1, y: 1}, \"Correct resolution\");\n        bbox = layers[\"ROADS_RIVERS\"].bbox[\"EPSG:4326\"];\n        t.eq(bbox.bbox,\n             [-71.63, 41.75, -70.78, 42.90],\n             \"Correct bbox from BoundingBox (override)\");\n        t.eq(bbox.res, {x: 0.01, y: 0.01}, \"Correct resolution (override)\");\n        bbox = layers[\"ROADS_1M\"].bbox[\"EPSG:26986\"];\n        t.eq(bbox.bbox,\n             [189000, 834000, 285000, 962000],\n             \"Correctly inherited bbox\");\n        t.eq(bbox.res, {x: 1, y: 1}, \"Correctly inherited resolution\");\n\n\n        var identifiers = layers[\"ROADS_RIVERS\"].identifiers;\n        var authorities = layers[\"ROADS_RIVERS\"].authorityURLs;\n\n        t.ok(identifiers, \"got identifiers from layer ROADS_RIVERS\");\n        t.ok(\"DIF_ID\" in identifiers,\n             \"authority attribute from Identifiers parsed correctly\");\n        t.eq(identifiers[\"DIF_ID\"],\n             \"123456\",\n             \"Identifier value parsed correctly\");\n        t.ok(\"DIF_ID\" in authorities,\n             \"AuthorityURLs parsed and inherited correctly\");\n        t.eq(authorities[\"DIF_ID\"],\n             \"http://gcmd.gsfc.nasa.gov/difguide/whatisadif.html\",\n             \"OnlineResource in AuthorityURLs parsed correctly\");\n\n        var featurelist = layers[\"ROADS_RIVERS\"].featureListURL;\n        t.ok(featurelist, \"layer has FeatureListURL\");\n        t.eq(featurelist.format,\n             \"application/vnd.ogc.se_xml\",\n             \"FeatureListURL format parsed correctly\");\n        t.eq(featurelist.href,\n             \"http://www.university.edu/data/roads_rivers.gml\",\n             \"FeatureListURL OnlineResource parsed correctly\");\n\n        t.eq(layers[\"Pressure\"].queryable,\n             true,\n             \"queryable property inherited correctly\");\n        t.eq(layers[\"ozone_image\"].queryable,\n             false,\n             \"queryable property has correct default value\");\n        t.eq(layers[\"population\"].cascaded,\n             1,\n             \"cascaded property parsed correctly\");\n        t.eq(layers[\"ozone_image\"].fixedWidth,\n             512,\n             \"fixedWidth property correctly parsed\");\n        t.eq(layers[\"ozone_image\"].fixedHeight,\n             256,\n             \"fixedHeight property correctly parsed\");\n        t.eq(layers[\"ozone_image\"].opaque,\n             true,\n             \"opaque property parsed correctly\");\n        t.eq(layers[\"ozone_image\"].noSubsets,\n             true,\n             \"noSubsets property parsed correctly\");\n\n\n    }\n\n    function test_dimensions(t) {\n\n        t.plan(8);\n\n        var xml = document.getElementById(\"ogcsample\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n\n        var obj = new OpenLayers.Format.WMSCapabilities().read(doc);\n        var capability = obj.capability;\n\n        var layers = {};\n        for (var i=0, len=capability.layers.length; i<len; i++) {\n            if (\"name\" in capability.layers[i]) {\n                layers[ capability.layers[i].name ] = capability.layers[i];\n            }\n        }\n\n        var time = layers[\"Clouds\"].dimensions.time;\n        t.eq(time[\"default\"], \"2000-08-22\", \"Default time value parsed correctly\");\n        t.eq(time.values.length, 1, \"Currect number of time extent values/periods\");\n        t.eq(time.values[0], \"1999-01-01/2000-08-22/P1D\", \"Time extent values parsed correctly\");\n\n        var elevation = layers[\"Pressure\"].dimensions.elevation;\n        t.eq(elevation.units, \"EPSG:5030\", \"Dimension units parsed correctly\");\n        t.eq(elevation[\"default\"], \"0\", \"Default elevation value parsed correctly\");\n        t.eq(elevation.nearestVal, true, \"NearestValue parsed correctly\");\n        t.eq(elevation.multipleVal, false, \"Absense of MultipleValues handled correctly\");\n        t.eq(elevation.values,\n             [\"0\",\"1000\",\"3000\",\"5000\",\"10000\"],\n             \"Parsing of comma-separated values done correctly\");\n\n\n    }\n\n    function test_contactinfo(t) {\n        t.plan(15);\n\n        var xml = document.getElementById(\"ogcsample\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n\n        var obj = new OpenLayers.Format.WMSCapabilities().read(doc);\n        var service = obj.service;\n\n        var contactinfo = service.contactInformation;\n        t.ok(contactinfo, \"object contains contactInformation property\");\n\n        var personPrimary = contactinfo.personPrimary;\n        t.ok(personPrimary, \"object contains personPrimary property\");\n\n        t.eq(personPrimary.person, \"Jeff deLaBeaujardiere\", \"ContactPerson parsed correctly\");\n        t.eq(personPrimary.organization, \"NASA\", \"ContactOrganization parsed correctly\");\n\n        t.eq(contactinfo.position,\n             \"Computer Scientist\",\n             \"ContactPosition parsed correctly\");\n\n\n        var addr = contactinfo.contactAddress;\n        t.ok(addr, \"object contains contactAddress property\");\n\n        t.eq(addr.type, \"postal\", \"AddressType parsed correctly\");\n        t.eq(addr.address,\n             \"NASA Goddard Space Flight Center, Code 933\",\n             \"Address parsed correctly\");\n        t.eq(addr.city, \"Greenbelt\", \"City parsed correctly\");\n        t.eq(addr.stateOrProvince, \"MD\", \"StateOrProvince parsed correctly\");\n        t.eq(addr.postcode, \"20771\", \"PostCode parsed correctly\");\n        t.eq(addr.country, \"USA\", \"Country parsed correctly\");\n\n        t.eq(contactinfo.phone,\n             \"+1 301 286-1569\",\n             \"ContactVoiceTelephone parsed correctly\");\n        t.eq(contactinfo.fax,\n             \"+1 301 286-1777\",\n             \"ContactFacsimileTelephone parsed correctly\");\n        t.eq(contactinfo.email,\n             \"delabeau@iniki.gsfc.nasa.gov\",\n             \"ContactElectronicMailAddress parsed correctly\");\n    }\n    \n    function test_feesAndConstraints(t) {\n        t.plan(2);\n\n        var xml = document.getElementById(\"gssample\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n        var obj = new OpenLayers.Format.WMSCapabilities().read(doc);\n        var service = obj.service;\n\n        t.ok(! (\"fees\" in service), \"Fees=none handled correctly\");\n        t.ok(! (\"accessConstraints\" in service), \"AccessConstraints=none handled correctly\");\n    }\n\n    function test_requests(t) {\n        t.plan(13);\n\n        var xml = document.getElementById(\"gssample\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n        var obj = new OpenLayers.Format.WMSCapabilities().read(doc);\n        var request = obj.capability.request;\n\n        t.ok(request, \"request property exists\");\n        t.ok(\"getmap\" in request, \"got GetMap request\");\n\n        t.ok(\"getfeatureinfo\" in request, \"got GetFeatureInfo request\");\n        t.eq(request.getfeatureinfo.formats,\n             [\"text/plain\", \"text/html\", \"application/vnd.ogc.gml\"],\n             \"GetFeatureInfo formats correctly parsed\");\n\n        t.ok(\"describelayer\" in request, \"got DescribeLayer request\");\n\n        t.ok(\"getlegendgraphic\" in request, \"got GetLegendGraphic request\");\n\n        var exception = obj.capability.exception;\n        t.ok(exception, \"exception property exists\");\n        t.eq(exception.formats,\n             [\"application/vnd.ogc.se_xml\"],\n             \"Exception Format parsed\");\n\n        var userSymbols = obj.capability.userSymbols;\n        t.ok(userSymbols, \"userSymbols property exists\");\n        t.eq(userSymbols.supportSLD, true, \"supportSLD parsed\");\n        t.eq(userSymbols.userLayer,  true, \"userLayer parsed\");\n        t.eq(userSymbols.userStyle,  true, \"userStyle parsed\");\n        t.eq(userSymbols.remoteWFS,  true, \"remoteWFS parsed\");\n\n    }\n    function test_ogc(t) {\n        t.plan(16)\n\n        /*\n         * Set up\n         */\n        \n        // needed for the minScale/maxScale test, see below\n        var dpi = OpenLayers.DOTS_PER_INCH;\n        OpenLayers.DOTS_PER_INCH = 90.710230403857;\n\n        var xml = document.getElementById(\"ogcsample\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n\n        var obj = new OpenLayers.Format.WMSCapabilities().read(doc);\n        var capability = obj.capability;\n\n        /*\n         * Test\n         */\n        \n        var attribution = capability.layers[2].attribution;\n        t.eq(attribution.title, \"State College University\", \"attribution title parsed correctly.\");\n        t.eq(attribution.href, \"http://www.university.edu/\", \"attribution href parsed correctly.\")\n        t.eq(attribution.logo.href, \"http://www.university.edu/icons/logo.gif\", \"attribution logo url parsed correctly.\");\n        t.eq(attribution.logo.format, \"image/gif\", \"attribution logo format parsed correctly.\");\n        t.eq(attribution.logo.width, \"100\", \"attribution logo width parsed correctly.\");\n        t.eq(attribution.logo.height, \"100\", \"attribution logo height parsed correctly.\");\n        \n        var keywords = capability.layers[0].keywords;\n        t.eq(keywords.length, 3, \"layer has 3 keywords.\");\n        t.eq(keywords[0], \"road\", \"1st keyword parsed correctly.\");\n        \n        var metadataURLs = capability.layers[0].metadataURLs;\n        t.eq(metadataURLs.length, 2, \"layer has 2 metadata urls.\");\n        t.eq(metadataURLs[0].type, \"FGDC\", \"type parsed correctly.\");\n        t.eq(metadataURLs[0].format, \"text/plain\", \"format parsed correctly.\");\n        t.eq(metadataURLs[0].href, \"http://www.university.edu/metadata/roads.txt\", \"href parsed correctly.\");\n\n        /*\n        Test minScale and maxScale\n\n        For Mapserver\n\n        <ScaleHint min=\"0.395998292216226\" max=\"98.9995730540565\" />\n\n        corresponds to (RESOLUTION keyword in MAP file has value of 90.710230403857):\n\n        MAXSCALE 250000\n        MINSCALE 1000\n\n        */\n        t.eq(capability.layers[0].minScale, 250000, \"layer.minScale is correct\");\n        t.eq(capability.layers[0].maxScale, 1000, \"layer.maxScale is correct\");\n\n        t.eq(capability.layers[1].minScale, undefined, \"layer.minScale for max='Infinity' is correct\");\n        t.eq(capability.layers[1].maxScale, undefined, \"layer.maxScale for min='0' is correct\");\n        /*\n         * Tear down\n         */\n\n        OpenLayers.DOTS_PER_INCH = dpi;\n    }\n    \n    </script> \n</head> \n<body>\n\n<!--\nOGC example below taken from\nhttp://schemas.opengis.net/wms/1.1.1/capabilities_1_1_1.xml\nCopyright © 1994-2008 Open Geospatial Consortium, Inc. All Rights Reserved.\nhttp://www.opengeospatial.org/ogc/document\nChanges:\n* fixed DTD URL\n* removed comments\n-->\n<div id=\"ogcsample\"><!--\n<?xml version='1.0' encoding=\"UTF-8\" standalone=\"no\" ?>\n<!DOCTYPE WMT_MS_Capabilities SYSTEM\n \"http://schemas.opengis.net/wms/1.1.1/capabilities_1_1_1.dtd\"\n [\n <!ELEMENT VendorSpecificCapabilities EMPTY>\n ]>\n\n<WMT_MS_Capabilities version=\"1.1.1\" updateSequence=\"0\">\n<Service>\n\n  <Name>OGC:WMS</Name>\n  <Title>Acme Corp. Map Server</Title>\n  <Abstract>WMT Map Server maintained by Acme Corporation.  Contact: webmaster@wmt.acme.com.  High-quality maps showing roadrunner nests and possible ambush locations.</Abstract>\n  <KeywordList>\n\n    <Keyword>bird</Keyword>\n    <Keyword>roadrunner</Keyword>\n    <Keyword>ambush</Keyword>\n  </KeywordList>\n  <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\"\n   xlink:href=\"http://hostname/\" />\n\n  <ContactInformation>\n    <ContactPersonPrimary>\n      <ContactPerson>Jeff deLaBeaujardiere</ContactPerson>\n      <ContactOrganization>NASA</ContactOrganization>\n    </ContactPersonPrimary>\n    <ContactPosition>Computer Scientist</ContactPosition>\n    <ContactAddress>\n\n      <AddressType>postal</AddressType>\n      <Address>NASA Goddard Space Flight Center, Code 933</Address>\n      <City>Greenbelt</City>\n      <StateOrProvince>MD</StateOrProvince>\n      <PostCode>20771</PostCode>\n      <Country>USA</Country>\n\n    </ContactAddress>\n    <ContactVoiceTelephone>+1 301 286-1569</ContactVoiceTelephone>\n    <ContactFacsimileTelephone>+1 301 286-1777</ContactFacsimileTelephone>\n    <ContactElectronicMailAddress>delabeau@iniki.gsfc.nasa.gov</ContactElectronicMailAddress>\n  </ContactInformation>\n  <Fees>none</Fees>\n\n  <AccessConstraints>none</AccessConstraints>\n</Service>\n<Capability>\n  <Request>\n    <GetCapabilities>\n      <Format>application/vnd.ogc.wms_xml</Format>\n      <DCPType>\n        <HTTP>\n          <Get>\n\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n             xlink:type=\"simple\"\n             xlink:href=\"http://hostname:port/path\" />\n          </Get>\n          <Post>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n             xlink:type=\"simple\"\n             xlink:href=\"http://hostname:port/path\" />\n          </Post>\n        </HTTP>\n      </DCPType>\n\n    </GetCapabilities>\n    <GetMap>\n      <Format>image/gif</Format>\n      <Format>image/png</Format>\n      <Format>image/jpeg</Format>\n      <DCPType>\n        <HTTP>\n          <Get>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n             xlink:type=\"simple\"\n             xlink:href=\"http://hostname:port/path/get\" />\n          </Get>\n          <Post>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n             xlink:type=\"simple\"\n             xlink:href=\"http://hostname:port/path/post\" />\n          </Post>\n        </HTTP>\n      </DCPType>\n    </GetMap>\n    <GetFeatureInfo>\n      <Format>application/vnd.ogc.gml</Format>\n\n      <Format>text/plain</Format>\n      <Format>text/html</Format>\n      <DCPType>\n        <HTTP>\n          <Get>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n             xlink:type=\"simple\"\n             xlink:href=\"http://hostname:port/path\" />\n          </Get>\n        </HTTP>\n\n      </DCPType>\n    </GetFeatureInfo>\n    <DescribeLayer>\n      <Format>application/vnd.ogc.gml</Format>\n      <DCPType>\n        <HTTP>\n          <Get>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n             xlink:type=\"simple\"\n             xlink:href=\"http://hostname:port/path\" />\n\n          </Get>\n        </HTTP>\n      </DCPType>\n    </DescribeLayer>\n  </Request>\n  <Exception>\n    <Format>application/vnd.ogc.se_xml</Format>\n    <Format>application/vnd.ogc.se_inimage</Format>\n\n    <Format>application/vnd.ogc.se_blank</Format>\n  </Exception>\n  <VendorSpecificCapabilities />\n  <UserDefinedSymbolization SupportSLD=\"1\" UserLayer=\"1\" UserStyle=\"1\"\n    RemoteWFS=\"1\" />\n\n  <Layer>\n    <Title>Acme Corp. Map Server</Title>\n    <SRS>EPSG:4326</SRS>\n    <BoundingBox SRS=\"EPSG:4326\"\n     minx=\"-1\" miny=\"-1\" maxx=\"1\" maxy=\"1\" resx=\"0.0\" resy=\"0.0\"/>\n    <AuthorityURL name=\"DIF_ID\">\n      <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\"\n       xlink:href=\"http://gcmd.gsfc.nasa.gov/difguide/whatisadif.html\" />\n    </AuthorityURL>\n    <Layer>\n      <Name>ROADS_RIVERS</Name> \n      <Title>Roads and Rivers</Title>\n      <SRS>EPSG:26986</SRS> \n      <LatLonBoundingBox minx=\"-71.63\" miny=\"41.75\" maxx=\"-70.78\" maxy=\"42.90\"/>\n      <BoundingBox SRS=\"EPSG:4326\"\n       minx=\"-71.63\" miny=\"41.75\" maxx=\"-70.78\" maxy=\"42.90\" resx=\"0.01\" resy=\"0.01\"/>\n\n      <BoundingBox SRS=\"EPSG:26986\"\n       minx=\"189000\" miny=\"834000\" maxx=\"285000\" maxy=\"962000\" resx=\"1\" resy=\"1\" />\n      <Attribution>\n        <Title>State College University</Title>\n        <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\"\n         xlink:href=\"http://www.university.edu/\" />\n        <LogoURL width=\"100\" height=\"100\">\n          <Format>image/gif</Format>\n          <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n           xlink:type=\"simple\"\n           xlink:href=\"http://www.university.edu/icons/logo.gif\" />\n\n        </LogoURL>\n      </Attribution>\n      <Identifier authority=\"DIF_ID\">123456</Identifier>\n      <FeatureListURL>\n        <Format>application/vnd.ogc.se_xml</Format>\n        <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\"\n         xlink:href=\"http://www.university.edu/data/roads_rivers.gml\" />\n      </FeatureListURL>\n\n      <Style>\n        <Name>USGS</Name>\n        <Title>USGS Topo Map Style</Title>\n        <Abstract>Features are shown in a style like that used in USGS topographic maps.</Abstract>\n        <LegendURL width=\"72\" height=\"72\">\n          <Format>image/gif</Format>\n\n          <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n           xlink:type=\"simple\"\n           xlink:href=\"http://www.university.edu/legends/usgs.gif\" />\n        </LegendURL>\n        <StyleSheetURL>\n          <Format>text/xsl</Format>\n          <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n           xlink:type=\"simple\"\n           xlink:href=\"http://www.university.edu/stylesheets/usgs.xsl\" />\n        </StyleSheetURL>\n      </Style>\n\n\n      <Layer queryable=\"1\">\n    <Name>ROADS_1M</Name> \n    <Title>Roads at 1:1M scale</Title>\n    <Abstract>Roads at a scale of 1 to 1 million.</Abstract>\n    <KeywordList>\n          <Keyword>road</Keyword>\n\n          <Keyword>transportation</Keyword>\n          <Keyword>atlas</Keyword>\n    </KeywordList>\n    <Identifier authority=\"DIF_ID\">123456</Identifier>\n    <MetadataURL type=\"FGDC\">\n          <Format>text/plain</Format>\n          <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n           xlink:type=\"simple\"\n           xlink:href=\"http://www.university.edu/metadata/roads.txt\" />\n        </MetadataURL>\n    <MetadataURL type=\"FGDC\">\n           <Format>text/xml</Format>\n           <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n            xlink:type=\"simple\"\n            xlink:href=\"http://www.university.edu/metadata/roads.xml\" />\n        </MetadataURL>\n    <Style>\n\n      <Name>ATLAS</Name>\n      <Title>Road atlas style</Title>\n      <Abstract>Roads are shown in a style like that used in a commercial road atlas.</Abstract>\n        <LegendURL width=\"72\" height=\"72\">\n          <Format>image/gif</Format>\n          <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n           xlink:type=\"simple\"\n           xlink:href=\"http://www.university.edu/legends/atlas.gif\" />\n        </LegendURL>\n\n    </Style>\n      <ScaleHint min=\"0.395998292216226\" max=\"98.9995730540565\" />\n      </Layer>\n      <Layer queryable=\"1\">\n    <Name>RIVERS_1M</Name>\n    <Title>Rivers at 1:1M scale</Title>\n    <Abstract>Rivers at a scale of 1 to 1 million.</Abstract>\n    <KeywordList>\n\n          <Keyword>river</Keyword>\n          <Keyword>canal</Keyword>\n          <Keyword>waterway</Keyword>\n    </KeywordList>\n    <ScaleHint min=\"0\" max=\"Infinity\" />\n      </Layer>\n    </Layer>\n    <Layer queryable=\"1\">\n\n      <Title>Weather Forecast Data</Title>\n      <SRS>EPSG:4326</SRS>\n      <LatLonBoundingBox minx=\"-180\" miny=\"-90\" maxx=\"180\" maxy=\"90\" />\n      <Dimension name=\"time\" units=\"ISO8601\" />\n      <Extent name=\"time\" default=\"2000-08-22\">1999-01-01/2000-08-22/P1D</Extent>\n\n      <Layer>\n    <Name>Clouds</Name> \n    <Title>Forecast cloud cover</Title>\n      </Layer>\n\n      <Layer>\n    <Name>Temperature</Name> \n    <Title>Forecast temperature</Title>\n      </Layer>\n\n      <Layer>\n    <Name>Pressure</Name> \n    <Title>Forecast barometric pressure</Title>\n         <Dimension name=\"time\" units=\"ISO8601\" />\n         <Dimension name=\"elevation\" units=\"EPSG:5030\" />\n         <Extent name=\"time\" default=\"2000-08-22\">1999-01-01/2000-08-22/P1D</Extent>\n         <Extent name=\"elevation\" default=\"0\" nearestValue=\"1\">0,1000,3000,5000,10000</Extent>\n      </Layer>\n\n    </Layer>\n\n    <Layer opaque=\"1\" noSubsets=\"1\" fixedWidth=\"512\" fixedHeight=\"256\">\n      <Name>ozone_image</Name>\n      <Title>Global ozone distribution (1992)</Title>\n      <LatLonBoundingBox minx=\"-180\" miny=\"-90\" maxx=\"180\" maxy=\"90\" />\n      <Extent name=\"time\" default=\"1992\">1992</Extent>\n    </Layer>\n\n    <Layer cascaded=\"1\">\n      <Name>population</Name>\n      <Title>World population, annual</Title>\n      <LatLonBoundingBox minx=\"-180\" miny=\"-90\" maxx=\"180\" maxy=\"90\" />\n      <Extent name=\"time\" default=\"2000\">1990/2000/P1Y</Extent>\n    </Layer>\n\n  </Layer>\n\n\n</Capability>\n</WMT_MS_Capabilities>\n--></div>\n<div id=\"exceptionsample\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n<!DOCTYPE ServiceExceptionReport SYSTEM \"http://schemas.opengis.net/wms/1.1.1/WMS_exception_1_1_1.dtd\">\n<ServiceExceptionReport version=\"1.1.1\"><ServiceException> Plain text message about an error. </ServiceException>\n</ServiceExceptionReport>\n--></div>\n<!--\nGeoServer example below taken from\nhttp://publicus.opengeo.org/geoserver/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetCapabilities\nChanges:\n* fixed DTD URL (publicus is no longer available)\n* removed comments\n-->\n<div id=\"gssample\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE WMT_MS_Capabilities SYSTEM \"http://schemas.opengis.net/wms/1.1.1/capabilities_1_1_1.dtd\">\n<WMT_MS_Capabilities version=\"1.1.1\" updateSequence=\"57\">\n  <Service>\n    <Name>OGC:WMS</Name>\n    <Title>GeoServer Web Map Service</Title>\n    <Abstract>A compliant implementation of WMS 1.1.1 plus most of the SLD 1.0 extension (dynamic styling). Can also generate PDF, SVG, KML, GeoRSS</Abstract>\n    <KeywordList>\n      <Keyword>WFS</Keyword>\n      <Keyword>WMS</Keyword>\n      <Keyword>GEOSERVER</Keyword>\n    </KeywordList>\n    <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms\"/>\n    <ContactInformation>\n      <ContactPersonPrimary>\n        <ContactPerson>Claudius Ptolomaeus</ContactPerson>\n        <ContactOrganization>The ancient geographes INC</ContactOrganization>\n      </ContactPersonPrimary>\n      <ContactPosition>Chief geographer</ContactPosition>\n      <ContactAddress>\n        <AddressType>Work</AddressType>\n        <Address/>\n        <City>Alexandria</City>\n        <StateOrProvince/>\n        <PostCode/>\n        <Country>Egypt</Country>\n      </ContactAddress>\n      <ContactVoiceTelephone/>\n      <ContactFacsimileTelephone/>\n      <ContactElectronicMailAddress>claudius.ptolomaeus@gmail.com</ContactElectronicMailAddress>\n    </ContactInformation>\n    <Fees>NONE</Fees>\n    <AccessConstraints>NONE</AccessConstraints>\n  </Service>\n  <Capability>\n    <Request>\n      <GetCapabilities>\n        <Format>application/vnd.ogc.wms_xml</Format>\n        <DCPType>\n          <HTTP>\n            <Get>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&amp;\"/>\n            </Get>\n            <Post>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&amp;\"/>\n            </Post>\n          </HTTP>\n        </DCPType>\n      </GetCapabilities>\n      <GetMap>\n        <Format>image/png</Format>\n        <Format>application/atom xml</Format>\n        <Format>application/atom+xml</Format>\n        <Format>application/openlayers</Format>\n        <Format>application/pdf</Format>\n        <Format>application/rss xml</Format>\n        <Format>application/rss+xml</Format>\n        <Format>application/vnd.google-earth.kml</Format>\n        <Format>application/vnd.google-earth.kml xml</Format>\n        <Format>application/vnd.google-earth.kml+xml</Format>\n        <Format>application/vnd.google-earth.kmz</Format>\n        <Format>application/vnd.google-earth.kmz xml</Format>\n        <Format>application/vnd.google-earth.kmz+xml</Format>\n        <Format>atom</Format>\n        <Format>image/geotiff</Format>\n        <Format>image/geotiff8</Format>\n        <Format>image/gif</Format>\n        <Format>image/jpeg</Format>\n        <Format>image/png8</Format>\n        <Format>image/svg</Format>\n        <Format>image/svg xml</Format>\n        <Format>image/svg+xml</Format>\n        <Format>image/tiff</Format>\n        <Format>image/tiff8</Format>\n        <Format>kml</Format>\n        <Format>kmz</Format>\n        <Format>openlayers</Format>\n        <Format>rss</Format>\n        <DCPType>\n          <HTTP>\n            <Get>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&amp;\"/>\n            </Get>\n          </HTTP>\n        </DCPType>\n      </GetMap>\n      <GetFeatureInfo>\n        <Format>text/plain</Format>\n        <Format>text/html</Format>\n        <Format>application/vnd.ogc.gml</Format>\n        <DCPType>\n          <HTTP>\n            <Get>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&amp;\"/>\n            </Get>\n            <Post>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&amp;\"/>\n            </Post>\n          </HTTP>\n        </DCPType>\n      </GetFeatureInfo>\n      <DescribeLayer>\n        <Format>application/vnd.ogc.wms_xml</Format>\n        <DCPType>\n          <HTTP>\n            <Get>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&amp;\"/>\n            </Get>\n          </HTTP>\n        </DCPType>\n      </DescribeLayer>\n      <GetLegendGraphic>\n        <Format>image/png</Format>\n        <Format>image/jpeg</Format>\n        <Format>image/gif</Format>\n        <DCPType>\n          <HTTP>\n            <Get>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms?SERVICE=WMS&amp;\"/>\n            </Get>\n          </HTTP>\n        </DCPType>\n      </GetLegendGraphic>\n    </Request>\n    <Exception>\n      <Format>application/vnd.ogc.se_xml</Format>\n    </Exception>\n    <UserDefinedSymbolization SupportSLD=\"1\" UserLayer=\"1\" UserStyle=\"1\" RemoteWFS=\"1\"/>\n    <Layer>\n      <Title>GeoServer Web Map Service</Title>\n      <Abstract>A compliant implementation of WMS 1.1.1 plus most of the SLD 1.0 extension (dynamic styling). Can also generate PDF, SVG, KML, GeoRSS</Abstract>\n      <SRS>EPSG:WGS84(DD)</SRS>\n      <SRS>EPSG:2000</SRS>\n      <SRS>EPSG:2001</SRS>\n      <SRS>EPSG:2002</SRS>\n      <SRS>EPSG:2003</SRS>\n      <SRS>EPSG:2004</SRS>\n      <SRS>EPSG:2005</SRS>\n      <SRS>EPSG:2006</SRS>\n      <SRS>EPSG:2007</SRS>\n      <SRS>EPSG:2008</SRS>\n      <SRS>EPSG:2009</SRS>\n      <SRS>EPSG:2010</SRS>\n      <SRS>EPSG:2011</SRS>\n      <SRS>EPSG:2012</SRS>\n      <SRS>EPSG:2013</SRS>\n      <SRS>EPSG:2014</SRS>\n      <SRS>EPSG:2015</SRS>\n      <SRS>EPSG:2016</SRS>\n      <SRS>EPSG:2017</SRS>\n      <SRS>EPSG:2018</SRS>\n      <SRS>EPSG:2019</SRS>\n      <SRS>EPSG:2020</SRS>\n      <SRS>EPSG:2021</SRS>\n      <SRS>EPSG:2022</SRS>\n      <SRS>EPSG:2023</SRS>\n      <SRS>EPSG:2024</SRS>\n      <SRS>EPSG:2025</SRS>\n      <SRS>EPSG:2026</SRS>\n      <SRS>EPSG:2027</SRS>\n      <SRS>EPSG:2028</SRS>\n      <SRS>EPSG:2029</SRS>\n      <SRS>EPSG:2030</SRS>\n      <SRS>EPSG:2031</SRS>\n      <SRS>EPSG:2032</SRS>\n      <SRS>EPSG:2033</SRS>\n      <SRS>EPSG:2034</SRS>\n      <SRS>EPSG:2035</SRS>\n      <SRS>EPSG:2036</SRS>\n      <SRS>EPSG:2037</SRS>\n      <SRS>EPSG:2038</SRS>\n      <SRS>EPSG:2039</SRS>\n      <SRS>EPSG:2040</SRS>\n      <SRS>EPSG:2041</SRS>\n      <SRS>EPSG:2042</SRS>\n      <SRS>EPSG:2043</SRS>\n      <SRS>EPSG:2044</SRS>\n      <SRS>EPSG:2045</SRS>\n      <SRS>EPSG:2046</SRS>\n      <SRS>EPSG:2047</SRS>\n      <SRS>EPSG:2048</SRS>\n      <SRS>EPSG:2049</SRS>\n      <SRS>EPSG:2050</SRS>\n      <SRS>EPSG:2051</SRS>\n      <SRS>EPSG:2052</SRS>\n      <SRS>EPSG:2053</SRS>\n      <SRS>EPSG:2054</SRS>\n      <SRS>EPSG:2055</SRS>\n      <SRS>EPSG:2056</SRS>\n      <SRS>EPSG:2057</SRS>\n      <SRS>EPSG:2058</SRS>\n      <SRS>EPSG:2059</SRS>\n      <SRS>EPSG:2060</SRS>\n      <SRS>EPSG:2061</SRS>\n      <SRS>EPSG:2062</SRS>\n      <SRS>EPSG:2063</SRS>\n      <SRS>EPSG:2064</SRS>\n      <SRS>EPSG:2065</SRS>\n      <SRS>EPSG:2066</SRS>\n      <SRS>EPSG:2067</SRS>\n      <SRS>EPSG:2068</SRS>\n      <SRS>EPSG:2069</SRS>\n      <SRS>EPSG:2070</SRS>\n      <SRS>EPSG:2071</SRS>\n      <SRS>EPSG:2072</SRS>\n      <SRS>EPSG:2073</SRS>\n      <SRS>EPSG:2074</SRS>\n      <SRS>EPSG:2075</SRS>\n      <SRS>EPSG:2076</SRS>\n      <SRS>EPSG:2077</SRS>\n      <SRS>EPSG:2078</SRS>\n      <SRS>EPSG:2079</SRS>\n      <SRS>EPSG:2080</SRS>\n      <SRS>EPSG:2081</SRS>\n      <SRS>EPSG:2082</SRS>\n      <SRS>EPSG:2083</SRS>\n      <SRS>EPSG:2084</SRS>\n      <SRS>EPSG:2085</SRS>\n      <SRS>EPSG:2086</SRS>\n      <SRS>EPSG:2087</SRS>\n      <SRS>EPSG:2088</SRS>\n      <SRS>EPSG:2089</SRS>\n      <SRS>EPSG:2090</SRS>\n      <SRS>EPSG:2091</SRS>\n      <SRS>EPSG:2092</SRS>\n      <SRS>EPSG:2093</SRS>\n      <SRS>EPSG:2094</SRS>\n      <SRS>EPSG:2095</SRS>\n      <SRS>EPSG:2096</SRS>\n      <SRS>EPSG:2097</SRS>\n      <SRS>EPSG:2098</SRS>\n      <SRS>EPSG:2099</SRS>\n      <SRS>EPSG:2100</SRS>\n      <SRS>EPSG:2101</SRS>\n      <SRS>EPSG:2102</SRS>\n      <SRS>EPSG:2103</SRS>\n      <SRS>EPSG:2104</SRS>\n      <SRS>EPSG:2105</SRS>\n      <SRS>EPSG:2106</SRS>\n      <SRS>EPSG:2107</SRS>\n      <SRS>EPSG:2108</SRS>\n      <SRS>EPSG:2109</SRS>\n      <SRS>EPSG:2110</SRS>\n      <SRS>EPSG:2111</SRS>\n      <SRS>EPSG:2112</SRS>\n      <SRS>EPSG:2113</SRS>\n      <SRS>EPSG:2114</SRS>\n      <SRS>EPSG:2115</SRS>\n      <SRS>EPSG:2116</SRS>\n      <SRS>EPSG:2117</SRS>\n      <SRS>EPSG:2118</SRS>\n      <SRS>EPSG:2119</SRS>\n      <SRS>EPSG:2120</SRS>\n      <SRS>EPSG:2121</SRS>\n      <SRS>EPSG:2122</SRS>\n      <SRS>EPSG:2123</SRS>\n      <SRS>EPSG:2124</SRS>\n      <SRS>EPSG:2125</SRS>\n      <SRS>EPSG:2126</SRS>\n      <SRS>EPSG:2127</SRS>\n      <SRS>EPSG:2128</SRS>\n      <SRS>EPSG:2129</SRS>\n      <SRS>EPSG:2130</SRS>\n      <SRS>EPSG:2131</SRS>\n      <SRS>EPSG:2132</SRS>\n      <SRS>EPSG:2133</SRS>\n      <SRS>EPSG:2134</SRS>\n      <SRS>EPSG:2135</SRS>\n      <SRS>EPSG:2136</SRS>\n      <SRS>EPSG:2137</SRS>\n      <SRS>EPSG:2138</SRS>\n      <SRS>EPSG:2139</SRS>\n      <SRS>EPSG:2140</SRS>\n      <SRS>EPSG:2141</SRS>\n      <SRS>EPSG:2142</SRS>\n      <SRS>EPSG:2143</SRS>\n      <SRS>EPSG:2144</SRS>\n      <SRS>EPSG:2145</SRS>\n      <SRS>EPSG:2146</SRS>\n      <SRS>EPSG:2147</SRS>\n      <SRS>EPSG:2148</SRS>\n      <SRS>EPSG:2149</SRS>\n      <SRS>EPSG:2150</SRS>\n      <SRS>EPSG:2151</SRS>\n      <SRS>EPSG:2152</SRS>\n      <SRS>EPSG:2153</SRS>\n      <SRS>EPSG:2154</SRS>\n      <SRS>EPSG:2155</SRS>\n      <SRS>EPSG:2156</SRS>\n      <SRS>EPSG:2157</SRS>\n      <SRS>EPSG:2158</SRS>\n      <SRS>EPSG:2159</SRS>\n      <SRS>EPSG:2160</SRS>\n      <SRS>EPSG:2161</SRS>\n      <SRS>EPSG:2162</SRS>\n      <SRS>EPSG:2163</SRS>\n      <SRS>EPSG:2164</SRS>\n      <SRS>EPSG:2165</SRS>\n      <SRS>EPSG:2166</SRS>\n      <SRS>EPSG:2167</SRS>\n      <SRS>EPSG:2168</SRS>\n      <SRS>EPSG:2169</SRS>\n      <SRS>EPSG:2170</SRS>\n      <SRS>EPSG:2171</SRS>\n      <SRS>EPSG:2172</SRS>\n      <SRS>EPSG:2173</SRS>\n      <SRS>EPSG:2174</SRS>\n      <SRS>EPSG:2175</SRS>\n      <SRS>EPSG:2176</SRS>\n      <SRS>EPSG:2177</SRS>\n      <SRS>EPSG:2178</SRS>\n      <SRS>EPSG:2179</SRS>\n      <SRS>EPSG:2180</SRS>\n      <SRS>EPSG:2188</SRS>\n      <SRS>EPSG:2189</SRS>\n      <SRS>EPSG:2190</SRS>\n      <SRS>EPSG:2191</SRS>\n      <SRS>EPSG:2192</SRS>\n      <SRS>EPSG:2193</SRS>\n      <SRS>EPSG:2194</SRS>\n      <SRS>EPSG:2195</SRS>\n      <SRS>EPSG:2196</SRS>\n      <SRS>EPSG:2197</SRS>\n      <SRS>EPSG:2198</SRS>\n      <SRS>EPSG:2199</SRS>\n      <SRS>EPSG:2200</SRS>\n      <SRS>EPSG:2201</SRS>\n      <SRS>EPSG:2202</SRS>\n      <SRS>EPSG:2203</SRS>\n      <SRS>EPSG:2204</SRS>\n      <SRS>EPSG:2205</SRS>\n      <SRS>EPSG:2206</SRS>\n      <SRS>EPSG:2207</SRS>\n      <SRS>EPSG:2208</SRS>\n      <SRS>EPSG:2209</SRS>\n      <SRS>EPSG:2210</SRS>\n      <SRS>EPSG:2211</SRS>\n      <SRS>EPSG:2212</SRS>\n      <SRS>EPSG:2213</SRS>\n      <SRS>EPSG:2214</SRS>\n      <SRS>EPSG:2215</SRS>\n      <SRS>EPSG:2216</SRS>\n      <SRS>EPSG:2217</SRS>\n      <SRS>EPSG:2218</SRS>\n      <SRS>EPSG:2219</SRS>\n      <SRS>EPSG:2220</SRS>\n      <SRS>EPSG:2221</SRS>\n      <SRS>EPSG:2222</SRS>\n      <SRS>EPSG:2223</SRS>\n      <SRS>EPSG:2224</SRS>\n      <SRS>EPSG:2225</SRS>\n      <SRS>EPSG:2226</SRS>\n      <SRS>EPSG:2227</SRS>\n      <SRS>EPSG:2228</SRS>\n      <SRS>EPSG:2229</SRS>\n      <SRS>EPSG:2230</SRS>\n      <SRS>EPSG:2231</SRS>\n      <SRS>EPSG:2232</SRS>\n      <SRS>EPSG:2233</SRS>\n      <SRS>EPSG:2234</SRS>\n      <SRS>EPSG:2235</SRS>\n      <SRS>EPSG:2236</SRS>\n      <SRS>EPSG:2237</SRS>\n      <SRS>EPSG:2238</SRS>\n      <SRS>EPSG:2239</SRS>\n      <SRS>EPSG:2240</SRS>\n      <SRS>EPSG:2241</SRS>\n      <SRS>EPSG:2242</SRS>\n      <SRS>EPSG:2243</SRS>\n      <SRS>EPSG:2244</SRS>\n      <SRS>EPSG:2245</SRS>\n      <SRS>EPSG:2246</SRS>\n      <SRS>EPSG:2247</SRS>\n      <SRS>EPSG:2248</SRS>\n      <SRS>EPSG:2249</SRS>\n      <SRS>EPSG:2250</SRS>\n      <SRS>EPSG:2251</SRS>\n      <SRS>EPSG:2252</SRS>\n      <SRS>EPSG:2253</SRS>\n      <SRS>EPSG:2254</SRS>\n      <SRS>EPSG:2255</SRS>\n      <SRS>EPSG:2256</SRS>\n      <SRS>EPSG:2257</SRS>\n      <SRS>EPSG:2258</SRS>\n      <SRS>EPSG:2259</SRS>\n      <SRS>EPSG:2260</SRS>\n      <SRS>EPSG:2261</SRS>\n      <SRS>EPSG:2262</SRS>\n      <SRS>EPSG:2263</SRS>\n      <SRS>EPSG:2264</SRS>\n      <SRS>EPSG:2265</SRS>\n      <SRS>EPSG:2266</SRS>\n      <SRS>EPSG:2267</SRS>\n      <SRS>EPSG:2268</SRS>\n      <SRS>EPSG:2269</SRS>\n      <SRS>EPSG:2270</SRS>\n      <SRS>EPSG:2271</SRS>\n      <SRS>EPSG:2272</SRS>\n      <SRS>EPSG:2273</SRS>\n      <SRS>EPSG:2274</SRS>\n      <SRS>EPSG:2275</SRS>\n      <SRS>EPSG:2276</SRS>\n      <SRS>EPSG:2277</SRS>\n      <SRS>EPSG:2278</SRS>\n      <SRS>EPSG:2279</SRS>\n      <SRS>EPSG:2280</SRS>\n      <SRS>EPSG:2281</SRS>\n      <SRS>EPSG:2282</SRS>\n      <SRS>EPSG:2283</SRS>\n      <SRS>EPSG:2284</SRS>\n      <SRS>EPSG:2285</SRS>\n      <SRS>EPSG:2286</SRS>\n      <SRS>EPSG:2287</SRS>\n      <SRS>EPSG:2288</SRS>\n      <SRS>EPSG:2289</SRS>\n      <SRS>EPSG:2290</SRS>\n      <SRS>EPSG:2291</SRS>\n      <SRS>EPSG:2292</SRS>\n      <SRS>EPSG:2294</SRS>\n      <SRS>EPSG:2295</SRS>\n      <SRS>EPSG:2296</SRS>\n      <SRS>EPSG:2297</SRS>\n      <SRS>EPSG:2298</SRS>\n      <SRS>EPSG:2299</SRS>\n      <SRS>EPSG:2300</SRS>\n      <SRS>EPSG:2301</SRS>\n      <SRS>EPSG:2302</SRS>\n      <SRS>EPSG:2303</SRS>\n      <SRS>EPSG:2304</SRS>\n      <SRS>EPSG:2305</SRS>\n      <SRS>EPSG:2306</SRS>\n      <SRS>EPSG:2307</SRS>\n      <SRS>EPSG:2308</SRS>\n      <SRS>EPSG:2309</SRS>\n      <SRS>EPSG:2310</SRS>\n      <SRS>EPSG:2311</SRS>\n      <SRS>EPSG:2312</SRS>\n      <SRS>EPSG:2313</SRS>\n      <SRS>EPSG:2314</SRS>\n      <SRS>EPSG:2315</SRS>\n      <SRS>EPSG:2316</SRS>\n      <SRS>EPSG:2317</SRS>\n      <SRS>EPSG:2318</SRS>\n      <SRS>EPSG:2319</SRS>\n      <SRS>EPSG:2320</SRS>\n      <SRS>EPSG:2321</SRS>\n      <SRS>EPSG:2322</SRS>\n      <SRS>EPSG:2323</SRS>\n      <SRS>EPSG:2324</SRS>\n      <SRS>EPSG:2325</SRS>\n      <SRS>EPSG:2326</SRS>\n      <SRS>EPSG:2327</SRS>\n      <SRS>EPSG:2328</SRS>\n      <SRS>EPSG:2329</SRS>\n      <SRS>EPSG:2330</SRS>\n      <SRS>EPSG:2331</SRS>\n      <SRS>EPSG:2332</SRS>\n      <SRS>EPSG:2333</SRS>\n      <SRS>EPSG:2334</SRS>\n      <SRS>EPSG:2335</SRS>\n      <SRS>EPSG:2336</SRS>\n      <SRS>EPSG:2337</SRS>\n      <SRS>EPSG:2338</SRS>\n      <SRS>EPSG:2339</SRS>\n      <SRS>EPSG:2340</SRS>\n      <SRS>EPSG:2341</SRS>\n      <SRS>EPSG:2342</SRS>\n      <SRS>EPSG:2343</SRS>\n      <SRS>EPSG:2344</SRS>\n      <SRS>EPSG:2345</SRS>\n      <SRS>EPSG:2346</SRS>\n      <SRS>EPSG:2347</SRS>\n      <SRS>EPSG:2348</SRS>\n      <SRS>EPSG:2349</SRS>\n      <SRS>EPSG:2350</SRS>\n      <SRS>EPSG:2351</SRS>\n      <SRS>EPSG:2352</SRS>\n      <SRS>EPSG:2353</SRS>\n      <SRS>EPSG:2354</SRS>\n      <SRS>EPSG:2355</SRS>\n      <SRS>EPSG:2356</SRS>\n      <SRS>EPSG:2357</SRS>\n      <SRS>EPSG:2358</SRS>\n      <SRS>EPSG:2359</SRS>\n      <SRS>EPSG:2360</SRS>\n      <SRS>EPSG:2361</SRS>\n      <SRS>EPSG:2362</SRS>\n      <SRS>EPSG:2363</SRS>\n      <SRS>EPSG:2364</SRS>\n      <SRS>EPSG:2365</SRS>\n      <SRS>EPSG:2366</SRS>\n      <SRS>EPSG:2367</SRS>\n      <SRS>EPSG:2368</SRS>\n      <SRS>EPSG:2369</SRS>\n      <SRS>EPSG:2370</SRS>\n      <SRS>EPSG:2371</SRS>\n      <SRS>EPSG:2372</SRS>\n      <SRS>EPSG:2373</SRS>\n      <SRS>EPSG:2374</SRS>\n      <SRS>EPSG:2375</SRS>\n      <SRS>EPSG:2376</SRS>\n      <SRS>EPSG:2377</SRS>\n      <SRS>EPSG:2378</SRS>\n      <SRS>EPSG:2379</SRS>\n      <SRS>EPSG:2380</SRS>\n      <SRS>EPSG:2381</SRS>\n      <SRS>EPSG:2382</SRS>\n      <SRS>EPSG:2383</SRS>\n      <SRS>EPSG:2384</SRS>\n      <SRS>EPSG:2385</SRS>\n      <SRS>EPSG:2386</SRS>\n      <SRS>EPSG:2387</SRS>\n      <SRS>EPSG:2388</SRS>\n      <SRS>EPSG:2389</SRS>\n      <SRS>EPSG:2390</SRS>\n      <SRS>EPSG:2391</SRS>\n      <SRS>EPSG:2392</SRS>\n      <SRS>EPSG:2393</SRS>\n      <SRS>EPSG:2394</SRS>\n      <SRS>EPSG:2395</SRS>\n      <SRS>EPSG:2396</SRS>\n      <SRS>EPSG:2397</SRS>\n      <SRS>EPSG:2398</SRS>\n      <SRS>EPSG:2399</SRS>\n      <SRS>EPSG:2400</SRS>\n      <SRS>EPSG:2401</SRS>\n      <SRS>EPSG:2402</SRS>\n      <SRS>EPSG:2403</SRS>\n      <SRS>EPSG:2404</SRS>\n      <SRS>EPSG:2405</SRS>\n      <SRS>EPSG:2406</SRS>\n      <SRS>EPSG:2407</SRS>\n      <SRS>EPSG:2408</SRS>\n      <SRS>EPSG:2409</SRS>\n      <SRS>EPSG:2410</SRS>\n      <SRS>EPSG:2411</SRS>\n      <SRS>EPSG:2412</SRS>\n      <SRS>EPSG:2413</SRS>\n      <SRS>EPSG:2414</SRS>\n      <SRS>EPSG:2415</SRS>\n      <SRS>EPSG:2416</SRS>\n      <SRS>EPSG:2417</SRS>\n      <SRS>EPSG:2418</SRS>\n      <SRS>EPSG:2419</SRS>\n      <SRS>EPSG:2420</SRS>\n      <SRS>EPSG:2421</SRS>\n      <SRS>EPSG:2422</SRS>\n      <SRS>EPSG:2423</SRS>\n      <SRS>EPSG:2424</SRS>\n      <SRS>EPSG:2425</SRS>\n      <SRS>EPSG:2426</SRS>\n      <SRS>EPSG:2427</SRS>\n      <SRS>EPSG:2428</SRS>\n      <SRS>EPSG:2429</SRS>\n      <SRS>EPSG:2430</SRS>\n      <SRS>EPSG:2431</SRS>\n      <SRS>EPSG:2432</SRS>\n      <SRS>EPSG:2433</SRS>\n      <SRS>EPSG:2434</SRS>\n      <SRS>EPSG:2435</SRS>\n      <SRS>EPSG:2436</SRS>\n      <SRS>EPSG:2437</SRS>\n      <SRS>EPSG:2438</SRS>\n      <SRS>EPSG:2439</SRS>\n      <SRS>EPSG:2440</SRS>\n      <SRS>EPSG:2441</SRS>\n      <SRS>EPSG:2442</SRS>\n      <SRS>EPSG:2443</SRS>\n      <SRS>EPSG:2444</SRS>\n      <SRS>EPSG:2445</SRS>\n      <SRS>EPSG:2446</SRS>\n      <SRS>EPSG:2447</SRS>\n      <SRS>EPSG:2448</SRS>\n      <SRS>EPSG:2449</SRS>\n      <SRS>EPSG:2450</SRS>\n      <SRS>EPSG:2451</SRS>\n      <SRS>EPSG:2452</SRS>\n      <SRS>EPSG:2453</SRS>\n      <SRS>EPSG:2454</SRS>\n      <SRS>EPSG:2455</SRS>\n      <SRS>EPSG:2456</SRS>\n      <SRS>EPSG:2457</SRS>\n      <SRS>EPSG:2458</SRS>\n      <SRS>EPSG:2459</SRS>\n      <SRS>EPSG:2460</SRS>\n      <SRS>EPSG:2461</SRS>\n      <SRS>EPSG:2462</SRS>\n      <SRS>EPSG:2463</SRS>\n      <SRS>EPSG:2464</SRS>\n      <SRS>EPSG:2465</SRS>\n      <SRS>EPSG:2466</SRS>\n      <SRS>EPSG:2467</SRS>\n      <SRS>EPSG:2468</SRS>\n      <SRS>EPSG:2469</SRS>\n      <SRS>EPSG:2470</SRS>\n      <SRS>EPSG:2471</SRS>\n      <SRS>EPSG:2472</SRS>\n      <SRS>EPSG:2473</SRS>\n      <SRS>EPSG:2474</SRS>\n      <SRS>EPSG:2475</SRS>\n      <SRS>EPSG:2476</SRS>\n      <SRS>EPSG:2477</SRS>\n      <SRS>EPSG:2478</SRS>\n      <SRS>EPSG:2479</SRS>\n      <SRS>EPSG:2480</SRS>\n      <SRS>EPSG:2481</SRS>\n      <SRS>EPSG:2482</SRS>\n      <SRS>EPSG:2483</SRS>\n      <SRS>EPSG:2484</SRS>\n      <SRS>EPSG:2485</SRS>\n      <SRS>EPSG:2486</SRS>\n      <SRS>EPSG:2487</SRS>\n      <SRS>EPSG:2488</SRS>\n      <SRS>EPSG:2489</SRS>\n      <SRS>EPSG:2490</SRS>\n      <SRS>EPSG:2491</SRS>\n      <SRS>EPSG:2492</SRS>\n      <SRS>EPSG:2493</SRS>\n      <SRS>EPSG:2494</SRS>\n      <SRS>EPSG:2495</SRS>\n      <SRS>EPSG:2496</SRS>\n      <SRS>EPSG:2497</SRS>\n      <SRS>EPSG:2498</SRS>\n      <SRS>EPSG:2499</SRS>\n      <SRS>EPSG:2500</SRS>\n      <SRS>EPSG:2501</SRS>\n      <SRS>EPSG:2502</SRS>\n      <SRS>EPSG:2503</SRS>\n      <SRS>EPSG:2504</SRS>\n      <SRS>EPSG:2505</SRS>\n      <SRS>EPSG:2506</SRS>\n      <SRS>EPSG:2507</SRS>\n      <SRS>EPSG:2508</SRS>\n      <SRS>EPSG:2509</SRS>\n      <SRS>EPSG:2510</SRS>\n      <SRS>EPSG:2511</SRS>\n      <SRS>EPSG:2512</SRS>\n      <SRS>EPSG:2513</SRS>\n      <SRS>EPSG:2514</SRS>\n      <SRS>EPSG:2515</SRS>\n      <SRS>EPSG:2516</SRS>\n      <SRS>EPSG:2517</SRS>\n      <SRS>EPSG:2518</SRS>\n      <SRS>EPSG:2519</SRS>\n      <SRS>EPSG:2520</SRS>\n      <SRS>EPSG:2521</SRS>\n      <SRS>EPSG:2522</SRS>\n      <SRS>EPSG:2523</SRS>\n      <SRS>EPSG:2524</SRS>\n      <SRS>EPSG:2525</SRS>\n      <SRS>EPSG:2526</SRS>\n      <SRS>EPSG:2527</SRS>\n      <SRS>EPSG:2528</SRS>\n      <SRS>EPSG:2529</SRS>\n      <SRS>EPSG:2530</SRS>\n      <SRS>EPSG:2531</SRS>\n      <SRS>EPSG:2532</SRS>\n      <SRS>EPSG:2533</SRS>\n      <SRS>EPSG:2534</SRS>\n      <SRS>EPSG:2535</SRS>\n      <SRS>EPSG:2536</SRS>\n      <SRS>EPSG:2537</SRS>\n      <SRS>EPSG:2538</SRS>\n      <SRS>EPSG:2539</SRS>\n      <SRS>EPSG:2540</SRS>\n      <SRS>EPSG:2541</SRS>\n      <SRS>EPSG:2542</SRS>\n      <SRS>EPSG:2543</SRS>\n      <SRS>EPSG:2544</SRS>\n      <SRS>EPSG:2545</SRS>\n      <SRS>EPSG:2546</SRS>\n      <SRS>EPSG:2547</SRS>\n      <SRS>EPSG:2548</SRS>\n      <SRS>EPSG:2549</SRS>\n      <SRS>EPSG:2550</SRS>\n      <SRS>EPSG:2551</SRS>\n      <SRS>EPSG:2552</SRS>\n      <SRS>EPSG:2553</SRS>\n      <SRS>EPSG:2554</SRS>\n      <SRS>EPSG:2555</SRS>\n      <SRS>EPSG:2556</SRS>\n      <SRS>EPSG:2557</SRS>\n      <SRS>EPSG:2558</SRS>\n      <SRS>EPSG:2559</SRS>\n      <SRS>EPSG:2560</SRS>\n      <SRS>EPSG:2561</SRS>\n      <SRS>EPSG:2562</SRS>\n      <SRS>EPSG:2563</SRS>\n      <SRS>EPSG:2564</SRS>\n      <SRS>EPSG:2565</SRS>\n      <SRS>EPSG:2566</SRS>\n      <SRS>EPSG:2567</SRS>\n      <SRS>EPSG:2568</SRS>\n      <SRS>EPSG:2569</SRS>\n      <SRS>EPSG:2570</SRS>\n      <SRS>EPSG:2571</SRS>\n      <SRS>EPSG:2572</SRS>\n      <SRS>EPSG:2573</SRS>\n      <SRS>EPSG:2574</SRS>\n      <SRS>EPSG:2575</SRS>\n      <SRS>EPSG:2576</SRS>\n      <SRS>EPSG:2577</SRS>\n      <SRS>EPSG:2578</SRS>\n      <SRS>EPSG:2579</SRS>\n      <SRS>EPSG:2580</SRS>\n      <SRS>EPSG:2581</SRS>\n      <SRS>EPSG:2582</SRS>\n      <SRS>EPSG:2583</SRS>\n      <SRS>EPSG:2584</SRS>\n      <SRS>EPSG:2585</SRS>\n      <SRS>EPSG:2586</SRS>\n      <SRS>EPSG:2587</SRS>\n      <SRS>EPSG:2588</SRS>\n      <SRS>EPSG:2589</SRS>\n      <SRS>EPSG:2590</SRS>\n      <SRS>EPSG:2591</SRS>\n      <SRS>EPSG:2592</SRS>\n      <SRS>EPSG:2593</SRS>\n      <SRS>EPSG:2594</SRS>\n      <SRS>EPSG:2595</SRS>\n      <SRS>EPSG:2596</SRS>\n      <SRS>EPSG:2597</SRS>\n      <SRS>EPSG:2598</SRS>\n      <SRS>EPSG:2599</SRS>\n      <SRS>EPSG:2600</SRS>\n      <SRS>EPSG:2601</SRS>\n      <SRS>EPSG:2602</SRS>\n      <SRS>EPSG:2603</SRS>\n      <SRS>EPSG:2604</SRS>\n      <SRS>EPSG:2605</SRS>\n      <SRS>EPSG:2606</SRS>\n      <SRS>EPSG:2607</SRS>\n      <SRS>EPSG:2608</SRS>\n      <SRS>EPSG:2609</SRS>\n      <SRS>EPSG:2610</SRS>\n      <SRS>EPSG:2611</SRS>\n      <SRS>EPSG:2612</SRS>\n      <SRS>EPSG:2613</SRS>\n      <SRS>EPSG:2614</SRS>\n      <SRS>EPSG:2615</SRS>\n      <SRS>EPSG:2616</SRS>\n      <SRS>EPSG:2617</SRS>\n      <SRS>EPSG:2618</SRS>\n      <SRS>EPSG:2619</SRS>\n      <SRS>EPSG:2620</SRS>\n      <SRS>EPSG:2621</SRS>\n      <SRS>EPSG:2622</SRS>\n      <SRS>EPSG:2623</SRS>\n      <SRS>EPSG:2624</SRS>\n      <SRS>EPSG:2625</SRS>\n      <SRS>EPSG:2626</SRS>\n      <SRS>EPSG:2627</SRS>\n      <SRS>EPSG:2628</SRS>\n      <SRS>EPSG:2629</SRS>\n      <SRS>EPSG:2630</SRS>\n      <SRS>EPSG:2631</SRS>\n      <SRS>EPSG:2632</SRS>\n      <SRS>EPSG:2633</SRS>\n      <SRS>EPSG:2634</SRS>\n      <SRS>EPSG:2635</SRS>\n      <SRS>EPSG:2636</SRS>\n      <SRS>EPSG:2637</SRS>\n      <SRS>EPSG:2638</SRS>\n      <SRS>EPSG:2639</SRS>\n      <SRS>EPSG:2640</SRS>\n      <SRS>EPSG:2641</SRS>\n      <SRS>EPSG:2642</SRS>\n      <SRS>EPSG:2643</SRS>\n      <SRS>EPSG:2644</SRS>\n      <SRS>EPSG:2645</SRS>\n      <SRS>EPSG:2646</SRS>\n      <SRS>EPSG:2647</SRS>\n      <SRS>EPSG:2648</SRS>\n      <SRS>EPSG:2649</SRS>\n      <SRS>EPSG:2650</SRS>\n      <SRS>EPSG:2651</SRS>\n      <SRS>EPSG:2652</SRS>\n      <SRS>EPSG:2653</SRS>\n      <SRS>EPSG:2654</SRS>\n      <SRS>EPSG:2655</SRS>\n      <SRS>EPSG:2656</SRS>\n      <SRS>EPSG:2657</SRS>\n      <SRS>EPSG:2658</SRS>\n      <SRS>EPSG:2659</SRS>\n      <SRS>EPSG:2660</SRS>\n      <SRS>EPSG:2661</SRS>\n      <SRS>EPSG:2662</SRS>\n      <SRS>EPSG:2663</SRS>\n      <SRS>EPSG:2664</SRS>\n      <SRS>EPSG:2665</SRS>\n      <SRS>EPSG:2666</SRS>\n      <SRS>EPSG:2667</SRS>\n      <SRS>EPSG:2668</SRS>\n      <SRS>EPSG:2669</SRS>\n      <SRS>EPSG:2670</SRS>\n      <SRS>EPSG:2671</SRS>\n      <SRS>EPSG:2672</SRS>\n      <SRS>EPSG:2673</SRS>\n      <SRS>EPSG:2674</SRS>\n      <SRS>EPSG:2675</SRS>\n      <SRS>EPSG:2676</SRS>\n      <SRS>EPSG:2677</SRS>\n      <SRS>EPSG:2678</SRS>\n      <SRS>EPSG:2679</SRS>\n      <SRS>EPSG:2680</SRS>\n      <SRS>EPSG:2681</SRS>\n      <SRS>EPSG:2682</SRS>\n      <SRS>EPSG:2683</SRS>\n      <SRS>EPSG:2684</SRS>\n      <SRS>EPSG:2685</SRS>\n      <SRS>EPSG:2686</SRS>\n      <SRS>EPSG:2687</SRS>\n      <SRS>EPSG:2688</SRS>\n      <SRS>EPSG:2689</SRS>\n      <SRS>EPSG:2690</SRS>\n      <SRS>EPSG:2691</SRS>\n      <SRS>EPSG:2692</SRS>\n      <SRS>EPSG:2693</SRS>\n      <SRS>EPSG:2694</SRS>\n      <SRS>EPSG:2695</SRS>\n      <SRS>EPSG:2696</SRS>\n      <SRS>EPSG:2697</SRS>\n      <SRS>EPSG:2698</SRS>\n      <SRS>EPSG:2699</SRS>\n      <SRS>EPSG:2700</SRS>\n      <SRS>EPSG:2701</SRS>\n      <SRS>EPSG:2702</SRS>\n      <SRS>EPSG:2703</SRS>\n      <SRS>EPSG:2704</SRS>\n      <SRS>EPSG:2705</SRS>\n      <SRS>EPSG:2706</SRS>\n      <SRS>EPSG:2707</SRS>\n      <SRS>EPSG:2708</SRS>\n      <SRS>EPSG:2709</SRS>\n      <SRS>EPSG:2710</SRS>\n      <SRS>EPSG:2711</SRS>\n      <SRS>EPSG:2712</SRS>\n      <SRS>EPSG:2713</SRS>\n      <SRS>EPSG:2714</SRS>\n      <SRS>EPSG:2715</SRS>\n      <SRS>EPSG:2716</SRS>\n      <SRS>EPSG:2717</SRS>\n      <SRS>EPSG:2718</SRS>\n      <SRS>EPSG:2719</SRS>\n      <SRS>EPSG:2720</SRS>\n      <SRS>EPSG:2721</SRS>\n      <SRS>EPSG:2722</SRS>\n      <SRS>EPSG:2723</SRS>\n      <SRS>EPSG:2724</SRS>\n      <SRS>EPSG:2725</SRS>\n      <SRS>EPSG:2726</SRS>\n      <SRS>EPSG:2727</SRS>\n      <SRS>EPSG:2728</SRS>\n      <SRS>EPSG:2729</SRS>\n      <SRS>EPSG:2730</SRS>\n      <SRS>EPSG:2731</SRS>\n      <SRS>EPSG:2732</SRS>\n      <SRS>EPSG:2733</SRS>\n      <SRS>EPSG:2734</SRS>\n      <SRS>EPSG:2735</SRS>\n      <SRS>EPSG:2736</SRS>\n      <SRS>EPSG:2737</SRS>\n      <SRS>EPSG:2738</SRS>\n      <SRS>EPSG:2739</SRS>\n      <SRS>EPSG:2740</SRS>\n      <SRS>EPSG:2741</SRS>\n      <SRS>EPSG:2742</SRS>\n      <SRS>EPSG:2743</SRS>\n      <SRS>EPSG:2744</SRS>\n      <SRS>EPSG:2745</SRS>\n      <SRS>EPSG:2746</SRS>\n      <SRS>EPSG:2747</SRS>\n      <SRS>EPSG:2748</SRS>\n      <SRS>EPSG:2749</SRS>\n      <SRS>EPSG:2750</SRS>\n      <SRS>EPSG:2751</SRS>\n      <SRS>EPSG:2752</SRS>\n      <SRS>EPSG:2753</SRS>\n      <SRS>EPSG:2754</SRS>\n      <SRS>EPSG:2755</SRS>\n      <SRS>EPSG:2756</SRS>\n      <SRS>EPSG:2757</SRS>\n      <SRS>EPSG:2758</SRS>\n      <SRS>EPSG:2759</SRS>\n      <SRS>EPSG:2760</SRS>\n      <SRS>EPSG:2761</SRS>\n      <SRS>EPSG:2762</SRS>\n      <SRS>EPSG:2763</SRS>\n      <SRS>EPSG:2764</SRS>\n      <SRS>EPSG:2765</SRS>\n      <SRS>EPSG:2766</SRS>\n      <SRS>EPSG:2767</SRS>\n      <SRS>EPSG:2768</SRS>\n      <SRS>EPSG:2769</SRS>\n      <SRS>EPSG:2770</SRS>\n      <SRS>EPSG:2771</SRS>\n      <SRS>EPSG:2772</SRS>\n      <SRS>EPSG:2773</SRS>\n      <SRS>EPSG:2774</SRS>\n      <SRS>EPSG:2775</SRS>\n      <SRS>EPSG:2776</SRS>\n      <SRS>EPSG:2777</SRS>\n      <SRS>EPSG:2778</SRS>\n      <SRS>EPSG:2779</SRS>\n      <SRS>EPSG:2780</SRS>\n      <SRS>EPSG:2781</SRS>\n      <SRS>EPSG:2782</SRS>\n      <SRS>EPSG:2783</SRS>\n      <SRS>EPSG:2784</SRS>\n      <SRS>EPSG:2785</SRS>\n      <SRS>EPSG:2786</SRS>\n      <SRS>EPSG:2787</SRS>\n      <SRS>EPSG:2788</SRS>\n      <SRS>EPSG:2789</SRS>\n      <SRS>EPSG:2790</SRS>\n      <SRS>EPSG:2791</SRS>\n      <SRS>EPSG:2792</SRS>\n      <SRS>EPSG:2793</SRS>\n      <SRS>EPSG:2794</SRS>\n      <SRS>EPSG:2795</SRS>\n      <SRS>EPSG:2796</SRS>\n      <SRS>EPSG:2797</SRS>\n      <SRS>EPSG:2798</SRS>\n      <SRS>EPSG:2799</SRS>\n      <SRS>EPSG:2800</SRS>\n      <SRS>EPSG:2801</SRS>\n      <SRS>EPSG:2802</SRS>\n      <SRS>EPSG:2803</SRS>\n      <SRS>EPSG:2804</SRS>\n      <SRS>EPSG:2805</SRS>\n      <SRS>EPSG:2806</SRS>\n      <SRS>EPSG:2807</SRS>\n      <SRS>EPSG:2808</SRS>\n      <SRS>EPSG:2809</SRS>\n      <SRS>EPSG:2810</SRS>\n      <SRS>EPSG:2811</SRS>\n      <SRS>EPSG:2812</SRS>\n      <SRS>EPSG:2813</SRS>\n      <SRS>EPSG:2814</SRS>\n      <SRS>EPSG:2815</SRS>\n      <SRS>EPSG:2816</SRS>\n      <SRS>EPSG:2817</SRS>\n      <SRS>EPSG:2818</SRS>\n      <SRS>EPSG:2819</SRS>\n      <SRS>EPSG:2820</SRS>\n      <SRS>EPSG:2821</SRS>\n      <SRS>EPSG:2822</SRS>\n      <SRS>EPSG:2823</SRS>\n      <SRS>EPSG:2824</SRS>\n      <SRS>EPSG:2825</SRS>\n      <SRS>EPSG:2826</SRS>\n      <SRS>EPSG:2827</SRS>\n      <SRS>EPSG:2828</SRS>\n      <SRS>EPSG:2829</SRS>\n      <SRS>EPSG:2830</SRS>\n      <SRS>EPSG:2831</SRS>\n      <SRS>EPSG:2832</SRS>\n      <SRS>EPSG:2833</SRS>\n      <SRS>EPSG:2834</SRS>\n      <SRS>EPSG:2835</SRS>\n      <SRS>EPSG:2836</SRS>\n      <SRS>EPSG:2837</SRS>\n      <SRS>EPSG:2838</SRS>\n      <SRS>EPSG:2839</SRS>\n      <SRS>EPSG:2840</SRS>\n      <SRS>EPSG:2841</SRS>\n      <SRS>EPSG:2842</SRS>\n      <SRS>EPSG:2843</SRS>\n      <SRS>EPSG:2844</SRS>\n      <SRS>EPSG:2845</SRS>\n      <SRS>EPSG:2846</SRS>\n      <SRS>EPSG:2847</SRS>\n      <SRS>EPSG:2848</SRS>\n      <SRS>EPSG:2849</SRS>\n      <SRS>EPSG:2850</SRS>\n      <SRS>EPSG:2851</SRS>\n      <SRS>EPSG:2852</SRS>\n      <SRS>EPSG:2853</SRS>\n      <SRS>EPSG:2854</SRS>\n      <SRS>EPSG:2855</SRS>\n      <SRS>EPSG:2856</SRS>\n      <SRS>EPSG:2857</SRS>\n      <SRS>EPSG:2858</SRS>\n      <SRS>EPSG:2859</SRS>\n      <SRS>EPSG:2860</SRS>\n      <SRS>EPSG:2861</SRS>\n      <SRS>EPSG:2862</SRS>\n      <SRS>EPSG:2863</SRS>\n      <SRS>EPSG:2864</SRS>\n      <SRS>EPSG:2865</SRS>\n      <SRS>EPSG:2866</SRS>\n      <SRS>EPSG:2867</SRS>\n      <SRS>EPSG:2868</SRS>\n      <SRS>EPSG:2869</SRS>\n      <SRS>EPSG:2870</SRS>\n      <SRS>EPSG:2871</SRS>\n      <SRS>EPSG:2872</SRS>\n      <SRS>EPSG:2873</SRS>\n      <SRS>EPSG:2874</SRS>\n      <SRS>EPSG:2875</SRS>\n      <SRS>EPSG:2876</SRS>\n      <SRS>EPSG:2877</SRS>\n      <SRS>EPSG:2878</SRS>\n      <SRS>EPSG:2879</SRS>\n      <SRS>EPSG:2880</SRS>\n      <SRS>EPSG:2881</SRS>\n      <SRS>EPSG:2882</SRS>\n      <SRS>EPSG:2883</SRS>\n      <SRS>EPSG:2884</SRS>\n      <SRS>EPSG:2885</SRS>\n      <SRS>EPSG:2886</SRS>\n      <SRS>EPSG:2887</SRS>\n      <SRS>EPSG:2888</SRS>\n      <SRS>EPSG:2889</SRS>\n      <SRS>EPSG:2890</SRS>\n      <SRS>EPSG:2891</SRS>\n      <SRS>EPSG:2892</SRS>\n      <SRS>EPSG:2893</SRS>\n      <SRS>EPSG:2894</SRS>\n      <SRS>EPSG:2895</SRS>\n      <SRS>EPSG:2896</SRS>\n      <SRS>EPSG:2897</SRS>\n      <SRS>EPSG:2898</SRS>\n      <SRS>EPSG:2899</SRS>\n      <SRS>EPSG:2900</SRS>\n      <SRS>EPSG:2901</SRS>\n      <SRS>EPSG:2902</SRS>\n      <SRS>EPSG:2903</SRS>\n      <SRS>EPSG:2904</SRS>\n      <SRS>EPSG:2905</SRS>\n      <SRS>EPSG:2906</SRS>\n      <SRS>EPSG:2907</SRS>\n      <SRS>EPSG:2908</SRS>\n      <SRS>EPSG:2909</SRS>\n      <SRS>EPSG:2910</SRS>\n      <SRS>EPSG:2911</SRS>\n      <SRS>EPSG:2912</SRS>\n      <SRS>EPSG:2913</SRS>\n      <SRS>EPSG:2914</SRS>\n      <SRS>EPSG:2915</SRS>\n      <SRS>EPSG:2916</SRS>\n      <SRS>EPSG:2917</SRS>\n      <SRS>EPSG:2918</SRS>\n      <SRS>EPSG:2919</SRS>\n      <SRS>EPSG:2920</SRS>\n      <SRS>EPSG:2921</SRS>\n      <SRS>EPSG:2922</SRS>\n      <SRS>EPSG:2923</SRS>\n      <SRS>EPSG:2924</SRS>\n      <SRS>EPSG:2925</SRS>\n      <SRS>EPSG:2926</SRS>\n      <SRS>EPSG:2927</SRS>\n      <SRS>EPSG:2928</SRS>\n      <SRS>EPSG:2929</SRS>\n      <SRS>EPSG:2930</SRS>\n      <SRS>EPSG:2931</SRS>\n      <SRS>EPSG:2932</SRS>\n      <SRS>EPSG:2933</SRS>\n      <SRS>EPSG:2934</SRS>\n      <SRS>EPSG:2935</SRS>\n      <SRS>EPSG:2936</SRS>\n      <SRS>EPSG:2937</SRS>\n      <SRS>EPSG:2938</SRS>\n      <SRS>EPSG:2939</SRS>\n      <SRS>EPSG:2940</SRS>\n      <SRS>EPSG:2941</SRS>\n      <SRS>EPSG:2942</SRS>\n      <SRS>EPSG:2943</SRS>\n      <SRS>EPSG:2944</SRS>\n      <SRS>EPSG:2945</SRS>\n      <SRS>EPSG:2946</SRS>\n      <SRS>EPSG:2947</SRS>\n      <SRS>EPSG:2948</SRS>\n      <SRS>EPSG:2949</SRS>\n      <SRS>EPSG:2950</SRS>\n      <SRS>EPSG:2951</SRS>\n      <SRS>EPSG:2952</SRS>\n      <SRS>EPSG:2953</SRS>\n      <SRS>EPSG:2954</SRS>\n      <SRS>EPSG:2955</SRS>\n      <SRS>EPSG:2956</SRS>\n      <SRS>EPSG:2957</SRS>\n      <SRS>EPSG:2958</SRS>\n      <SRS>EPSG:2959</SRS>\n      <SRS>EPSG:2960</SRS>\n      <SRS>EPSG:2961</SRS>\n      <SRS>EPSG:2962</SRS>\n      <SRS>EPSG:2963</SRS>\n      <SRS>EPSG:2964</SRS>\n      <SRS>EPSG:2965</SRS>\n      <SRS>EPSG:2966</SRS>\n      <SRS>EPSG:2967</SRS>\n      <SRS>EPSG:2968</SRS>\n      <SRS>EPSG:2969</SRS>\n      <SRS>EPSG:2970</SRS>\n      <SRS>EPSG:2971</SRS>\n      <SRS>EPSG:2972</SRS>\n      <SRS>EPSG:2973</SRS>\n      <SRS>EPSG:2975</SRS>\n      <SRS>EPSG:2976</SRS>\n      <SRS>EPSG:2977</SRS>\n      <SRS>EPSG:2978</SRS>\n      <SRS>EPSG:2979</SRS>\n      <SRS>EPSG:2980</SRS>\n      <SRS>EPSG:2981</SRS>\n      <SRS>EPSG:2982</SRS>\n      <SRS>EPSG:2983</SRS>\n      <SRS>EPSG:2984</SRS>\n      <SRS>EPSG:2985</SRS>\n      <SRS>EPSG:2986</SRS>\n      <SRS>EPSG:2987</SRS>\n      <SRS>EPSG:2988</SRS>\n      <SRS>EPSG:2989</SRS>\n      <SRS>EPSG:2990</SRS>\n      <SRS>EPSG:2991</SRS>\n      <SRS>EPSG:2992</SRS>\n      <SRS>EPSG:2993</SRS>\n      <SRS>EPSG:2994</SRS>\n      <SRS>EPSG:2995</SRS>\n      <SRS>EPSG:2996</SRS>\n      <SRS>EPSG:2997</SRS>\n      <SRS>EPSG:2998</SRS>\n      <SRS>EPSG:2999</SRS>\n      <SRS>EPSG:3000</SRS>\n      <SRS>EPSG:3001</SRS>\n      <SRS>EPSG:3002</SRS>\n      <SRS>EPSG:3003</SRS>\n      <SRS>EPSG:3004</SRS>\n      <SRS>EPSG:3005</SRS>\n      <SRS>EPSG:3006</SRS>\n      <SRS>EPSG:3007</SRS>\n      <SRS>EPSG:3008</SRS>\n      <SRS>EPSG:3009</SRS>\n      <SRS>EPSG:3010</SRS>\n      <SRS>EPSG:3011</SRS>\n      <SRS>EPSG:3012</SRS>\n      <SRS>EPSG:3013</SRS>\n      <SRS>EPSG:3014</SRS>\n      <SRS>EPSG:3015</SRS>\n      <SRS>EPSG:3016</SRS>\n      <SRS>EPSG:3017</SRS>\n      <SRS>EPSG:3018</SRS>\n      <SRS>EPSG:3019</SRS>\n      <SRS>EPSG:3020</SRS>\n      <SRS>EPSG:3021</SRS>\n      <SRS>EPSG:3022</SRS>\n      <SRS>EPSG:3023</SRS>\n      <SRS>EPSG:3024</SRS>\n      <SRS>EPSG:3025</SRS>\n      <SRS>EPSG:3026</SRS>\n      <SRS>EPSG:3027</SRS>\n      <SRS>EPSG:3028</SRS>\n      <SRS>EPSG:3029</SRS>\n      <SRS>EPSG:3030</SRS>\n      <SRS>EPSG:3031</SRS>\n      <SRS>EPSG:3032</SRS>\n      <SRS>EPSG:3033</SRS>\n      <SRS>EPSG:3034</SRS>\n      <SRS>EPSG:3035</SRS>\n      <SRS>EPSG:3036</SRS>\n      <SRS>EPSG:3037</SRS>\n      <SRS>EPSG:3038</SRS>\n      <SRS>EPSG:3039</SRS>\n      <SRS>EPSG:3040</SRS>\n      <SRS>EPSG:3041</SRS>\n      <SRS>EPSG:3042</SRS>\n      <SRS>EPSG:3043</SRS>\n      <SRS>EPSG:3044</SRS>\n      <SRS>EPSG:3045</SRS>\n      <SRS>EPSG:3046</SRS>\n      <SRS>EPSG:3047</SRS>\n      <SRS>EPSG:3048</SRS>\n      <SRS>EPSG:3049</SRS>\n      <SRS>EPSG:3050</SRS>\n      <SRS>EPSG:3051</SRS>\n      <SRS>EPSG:3052</SRS>\n      <SRS>EPSG:3053</SRS>\n      <SRS>EPSG:3054</SRS>\n      <SRS>EPSG:3055</SRS>\n      <SRS>EPSG:3056</SRS>\n      <SRS>EPSG:3057</SRS>\n      <SRS>EPSG:3058</SRS>\n      <SRS>EPSG:3059</SRS>\n      <SRS>EPSG:3060</SRS>\n      <SRS>EPSG:3061</SRS>\n      <SRS>EPSG:3062</SRS>\n      <SRS>EPSG:3063</SRS>\n      <SRS>EPSG:3064</SRS>\n      <SRS>EPSG:3065</SRS>\n      <SRS>EPSG:3066</SRS>\n      <SRS>EPSG:3067</SRS>\n      <SRS>EPSG:3068</SRS>\n      <SRS>EPSG:3069</SRS>\n      <SRS>EPSG:3070</SRS>\n      <SRS>EPSG:3071</SRS>\n      <SRS>EPSG:3072</SRS>\n      <SRS>EPSG:3073</SRS>\n      <SRS>EPSG:3074</SRS>\n      <SRS>EPSG:3075</SRS>\n      <SRS>EPSG:3076</SRS>\n      <SRS>EPSG:3077</SRS>\n      <SRS>EPSG:3078</SRS>\n      <SRS>EPSG:3079</SRS>\n      <SRS>EPSG:3080</SRS>\n      <SRS>EPSG:3081</SRS>\n      <SRS>EPSG:3082</SRS>\n      <SRS>EPSG:3083</SRS>\n      <SRS>EPSG:3084</SRS>\n      <SRS>EPSG:3085</SRS>\n      <SRS>EPSG:3086</SRS>\n      <SRS>EPSG:3087</SRS>\n      <SRS>EPSG:3088</SRS>\n      <SRS>EPSG:3089</SRS>\n      <SRS>EPSG:3090</SRS>\n      <SRS>EPSG:3091</SRS>\n      <SRS>EPSG:3092</SRS>\n      <SRS>EPSG:3093</SRS>\n      <SRS>EPSG:3094</SRS>\n      <SRS>EPSG:3095</SRS>\n      <SRS>EPSG:3096</SRS>\n      <SRS>EPSG:3097</SRS>\n      <SRS>EPSG:3098</SRS>\n      <SRS>EPSG:3099</SRS>\n      <SRS>EPSG:3100</SRS>\n      <SRS>EPSG:3101</SRS>\n      <SRS>EPSG:3102</SRS>\n      <SRS>EPSG:3103</SRS>\n      <SRS>EPSG:3104</SRS>\n      <SRS>EPSG:3105</SRS>\n      <SRS>EPSG:3106</SRS>\n      <SRS>EPSG:3107</SRS>\n      <SRS>EPSG:3108</SRS>\n      <SRS>EPSG:3109</SRS>\n      <SRS>EPSG:3110</SRS>\n      <SRS>EPSG:3111</SRS>\n      <SRS>EPSG:3112</SRS>\n      <SRS>EPSG:3113</SRS>\n      <SRS>EPSG:3114</SRS>\n      <SRS>EPSG:3115</SRS>\n      <SRS>EPSG:3116</SRS>\n      <SRS>EPSG:3117</SRS>\n      <SRS>EPSG:3118</SRS>\n      <SRS>EPSG:3119</SRS>\n      <SRS>EPSG:3120</SRS>\n      <SRS>EPSG:3121</SRS>\n      <SRS>EPSG:3122</SRS>\n      <SRS>EPSG:3123</SRS>\n      <SRS>EPSG:3124</SRS>\n      <SRS>EPSG:3125</SRS>\n      <SRS>EPSG:3126</SRS>\n      <SRS>EPSG:3127</SRS>\n      <SRS>EPSG:3128</SRS>\n      <SRS>EPSG:3129</SRS>\n      <SRS>EPSG:3130</SRS>\n      <SRS>EPSG:3131</SRS>\n      <SRS>EPSG:3132</SRS>\n      <SRS>EPSG:3133</SRS>\n      <SRS>EPSG:3134</SRS>\n      <SRS>EPSG:3135</SRS>\n      <SRS>EPSG:3136</SRS>\n      <SRS>EPSG:3137</SRS>\n      <SRS>EPSG:3138</SRS>\n      <SRS>EPSG:3139</SRS>\n      <SRS>EPSG:3140</SRS>\n      <SRS>EPSG:3141</SRS>\n      <SRS>EPSG:3142</SRS>\n      <SRS>EPSG:3143</SRS>\n      <SRS>EPSG:3144</SRS>\n      <SRS>EPSG:3145</SRS>\n      <SRS>EPSG:3146</SRS>\n      <SRS>EPSG:3147</SRS>\n      <SRS>EPSG:3148</SRS>\n      <SRS>EPSG:3149</SRS>\n      <SRS>EPSG:3150</SRS>\n      <SRS>EPSG:3151</SRS>\n      <SRS>EPSG:3152</SRS>\n      <SRS>EPSG:3153</SRS>\n      <SRS>EPSG:3154</SRS>\n      <SRS>EPSG:3155</SRS>\n      <SRS>EPSG:3156</SRS>\n      <SRS>EPSG:3157</SRS>\n      <SRS>EPSG:3158</SRS>\n      <SRS>EPSG:3159</SRS>\n      <SRS>EPSG:3160</SRS>\n      <SRS>EPSG:3161</SRS>\n      <SRS>EPSG:3162</SRS>\n      <SRS>EPSG:3163</SRS>\n      <SRS>EPSG:3164</SRS>\n      <SRS>EPSG:3165</SRS>\n      <SRS>EPSG:3166</SRS>\n      <SRS>EPSG:3167</SRS>\n      <SRS>EPSG:3168</SRS>\n      <SRS>EPSG:3169</SRS>\n      <SRS>EPSG:3170</SRS>\n      <SRS>EPSG:3171</SRS>\n      <SRS>EPSG:3172</SRS>\n      <SRS>EPSG:3173</SRS>\n      <SRS>EPSG:3174</SRS>\n      <SRS>EPSG:3175</SRS>\n      <SRS>EPSG:3176</SRS>\n      <SRS>EPSG:3177</SRS>\n      <SRS>EPSG:3178</SRS>\n      <SRS>EPSG:3179</SRS>\n      <SRS>EPSG:3180</SRS>\n      <SRS>EPSG:3181</SRS>\n      <SRS>EPSG:3182</SRS>\n      <SRS>EPSG:3183</SRS>\n      <SRS>EPSG:3184</SRS>\n      <SRS>EPSG:3185</SRS>\n      <SRS>EPSG:3186</SRS>\n      <SRS>EPSG:3187</SRS>\n      <SRS>EPSG:3188</SRS>\n      <SRS>EPSG:3189</SRS>\n      <SRS>EPSG:3190</SRS>\n      <SRS>EPSG:3191</SRS>\n      <SRS>EPSG:3192</SRS>\n      <SRS>EPSG:3193</SRS>\n      <SRS>EPSG:3194</SRS>\n      <SRS>EPSG:3195</SRS>\n      <SRS>EPSG:3196</SRS>\n      <SRS>EPSG:3197</SRS>\n      <SRS>EPSG:3198</SRS>\n      <SRS>EPSG:3199</SRS>\n      <SRS>EPSG:3200</SRS>\n      <SRS>EPSG:3201</SRS>\n      <SRS>EPSG:3202</SRS>\n      <SRS>EPSG:3203</SRS>\n      <SRS>EPSG:3204</SRS>\n      <SRS>EPSG:3205</SRS>\n      <SRS>EPSG:3206</SRS>\n      <SRS>EPSG:3207</SRS>\n      <SRS>EPSG:3208</SRS>\n      <SRS>EPSG:3209</SRS>\n      <SRS>EPSG:3210</SRS>\n      <SRS>EPSG:3211</SRS>\n      <SRS>EPSG:3212</SRS>\n      <SRS>EPSG:3213</SRS>\n      <SRS>EPSG:3214</SRS>\n      <SRS>EPSG:3215</SRS>\n      <SRS>EPSG:3216</SRS>\n      <SRS>EPSG:3217</SRS>\n      <SRS>EPSG:3218</SRS>\n      <SRS>EPSG:3219</SRS>\n      <SRS>EPSG:3220</SRS>\n      <SRS>EPSG:3221</SRS>\n      <SRS>EPSG:3222</SRS>\n      <SRS>EPSG:3223</SRS>\n      <SRS>EPSG:3224</SRS>\n      <SRS>EPSG:3225</SRS>\n      <SRS>EPSG:3226</SRS>\n      <SRS>EPSG:3227</SRS>\n      <SRS>EPSG:3228</SRS>\n      <SRS>EPSG:3229</SRS>\n      <SRS>EPSG:3230</SRS>\n      <SRS>EPSG:3231</SRS>\n      <SRS>EPSG:3232</SRS>\n      <SRS>EPSG:3233</SRS>\n      <SRS>EPSG:3234</SRS>\n      <SRS>EPSG:3235</SRS>\n      <SRS>EPSG:3236</SRS>\n      <SRS>EPSG:3237</SRS>\n      <SRS>EPSG:3238</SRS>\n      <SRS>EPSG:3239</SRS>\n      <SRS>EPSG:3240</SRS>\n      <SRS>EPSG:3241</SRS>\n      <SRS>EPSG:3242</SRS>\n      <SRS>EPSG:3243</SRS>\n      <SRS>EPSG:3244</SRS>\n      <SRS>EPSG:3245</SRS>\n      <SRS>EPSG:3246</SRS>\n      <SRS>EPSG:3247</SRS>\n      <SRS>EPSG:3248</SRS>\n      <SRS>EPSG:3249</SRS>\n      <SRS>EPSG:3250</SRS>\n      <SRS>EPSG:3251</SRS>\n      <SRS>EPSG:3252</SRS>\n      <SRS>EPSG:3253</SRS>\n      <SRS>EPSG:3254</SRS>\n      <SRS>EPSG:3255</SRS>\n      <SRS>EPSG:3256</SRS>\n      <SRS>EPSG:3257</SRS>\n      <SRS>EPSG:3258</SRS>\n      <SRS>EPSG:3259</SRS>\n      <SRS>EPSG:3260</SRS>\n      <SRS>EPSG:3261</SRS>\n      <SRS>EPSG:3262</SRS>\n      <SRS>EPSG:3263</SRS>\n      <SRS>EPSG:3264</SRS>\n      <SRS>EPSG:3265</SRS>\n      <SRS>EPSG:3266</SRS>\n      <SRS>EPSG:3267</SRS>\n      <SRS>EPSG:3268</SRS>\n      <SRS>EPSG:3269</SRS>\n      <SRS>EPSG:3270</SRS>\n      <SRS>EPSG:3271</SRS>\n      <SRS>EPSG:3272</SRS>\n      <SRS>EPSG:3273</SRS>\n      <SRS>EPSG:3274</SRS>\n      <SRS>EPSG:3275</SRS>\n      <SRS>EPSG:3276</SRS>\n      <SRS>EPSG:3277</SRS>\n      <SRS>EPSG:3278</SRS>\n      <SRS>EPSG:3279</SRS>\n      <SRS>EPSG:3280</SRS>\n      <SRS>EPSG:3281</SRS>\n      <SRS>EPSG:3282</SRS>\n      <SRS>EPSG:3283</SRS>\n      <SRS>EPSG:3284</SRS>\n      <SRS>EPSG:3285</SRS>\n      <SRS>EPSG:3286</SRS>\n      <SRS>EPSG:3287</SRS>\n      <SRS>EPSG:3288</SRS>\n      <SRS>EPSG:3289</SRS>\n      <SRS>EPSG:3290</SRS>\n      <SRS>EPSG:3291</SRS>\n      <SRS>EPSG:3292</SRS>\n      <SRS>EPSG:3293</SRS>\n      <SRS>EPSG:3294</SRS>\n      <SRS>EPSG:3295</SRS>\n      <SRS>EPSG:3296</SRS>\n      <SRS>EPSG:3297</SRS>\n      <SRS>EPSG:3298</SRS>\n      <SRS>EPSG:3299</SRS>\n      <SRS>EPSG:3300</SRS>\n      <SRS>EPSG:3301</SRS>\n      <SRS>EPSG:3302</SRS>\n      <SRS>EPSG:3303</SRS>\n      <SRS>EPSG:3304</SRS>\n      <SRS>EPSG:3305</SRS>\n      <SRS>EPSG:3306</SRS>\n      <SRS>EPSG:3307</SRS>\n      <SRS>EPSG:3308</SRS>\n      <SRS>EPSG:3309</SRS>\n      <SRS>EPSG:3310</SRS>\n      <SRS>EPSG:3311</SRS>\n      <SRS>EPSG:3312</SRS>\n      <SRS>EPSG:3313</SRS>\n      <SRS>EPSG:3314</SRS>\n      <SRS>EPSG:3315</SRS>\n      <SRS>EPSG:3316</SRS>\n      <SRS>EPSG:3317</SRS>\n      <SRS>EPSG:3318</SRS>\n      <SRS>EPSG:3319</SRS>\n      <SRS>EPSG:3320</SRS>\n      <SRS>EPSG:3321</SRS>\n      <SRS>EPSG:3322</SRS>\n      <SRS>EPSG:3323</SRS>\n      <SRS>EPSG:3324</SRS>\n      <SRS>EPSG:3325</SRS>\n      <SRS>EPSG:3326</SRS>\n      <SRS>EPSG:3327</SRS>\n      <SRS>EPSG:3328</SRS>\n      <SRS>EPSG:3329</SRS>\n      <SRS>EPSG:3330</SRS>\n      <SRS>EPSG:3331</SRS>\n      <SRS>EPSG:3332</SRS>\n      <SRS>EPSG:3333</SRS>\n      <SRS>EPSG:3334</SRS>\n      <SRS>EPSG:3335</SRS>\n      <SRS>EPSG:3336</SRS>\n      <SRS>EPSG:3337</SRS>\n      <SRS>EPSG:3338</SRS>\n      <SRS>EPSG:3339</SRS>\n      <SRS>EPSG:3340</SRS>\n      <SRS>EPSG:3341</SRS>\n      <SRS>EPSG:3342</SRS>\n      <SRS>EPSG:3343</SRS>\n      <SRS>EPSG:3344</SRS>\n      <SRS>EPSG:3345</SRS>\n      <SRS>EPSG:3346</SRS>\n      <SRS>EPSG:3347</SRS>\n      <SRS>EPSG:3348</SRS>\n      <SRS>EPSG:3349</SRS>\n      <SRS>EPSG:3350</SRS>\n      <SRS>EPSG:3351</SRS>\n      <SRS>EPSG:3352</SRS>\n      <SRS>EPSG:3353</SRS>\n      <SRS>EPSG:3354</SRS>\n      <SRS>EPSG:3355</SRS>\n      <SRS>EPSG:3356</SRS>\n      <SRS>EPSG:3357</SRS>\n      <SRS>EPSG:3358</SRS>\n      <SRS>EPSG:3359</SRS>\n      <SRS>EPSG:3360</SRS>\n      <SRS>EPSG:3361</SRS>\n      <SRS>EPSG:3362</SRS>\n      <SRS>EPSG:3363</SRS>\n      <SRS>EPSG:3364</SRS>\n      <SRS>EPSG:3365</SRS>\n      <SRS>EPSG:3366</SRS>\n      <SRS>EPSG:3367</SRS>\n      <SRS>EPSG:3368</SRS>\n      <SRS>EPSG:3369</SRS>\n      <SRS>EPSG:3370</SRS>\n      <SRS>EPSG:3371</SRS>\n      <SRS>EPSG:3372</SRS>\n      <SRS>EPSG:3373</SRS>\n      <SRS>EPSG:3374</SRS>\n      <SRS>EPSG:3375</SRS>\n      <SRS>EPSG:3376</SRS>\n      <SRS>EPSG:3377</SRS>\n      <SRS>EPSG:3378</SRS>\n      <SRS>EPSG:3379</SRS>\n      <SRS>EPSG:3380</SRS>\n      <SRS>EPSG:3381</SRS>\n      <SRS>EPSG:3382</SRS>\n      <SRS>EPSG:3383</SRS>\n      <SRS>EPSG:3384</SRS>\n      <SRS>EPSG:3385</SRS>\n      <SRS>EPSG:3386</SRS>\n      <SRS>EPSG:3387</SRS>\n      <SRS>EPSG:3388</SRS>\n      <SRS>EPSG:3389</SRS>\n      <SRS>EPSG:3390</SRS>\n      <SRS>EPSG:3391</SRS>\n      <SRS>EPSG:3392</SRS>\n      <SRS>EPSG:3393</SRS>\n      <SRS>EPSG:3394</SRS>\n      <SRS>EPSG:3395</SRS>\n      <SRS>EPSG:3396</SRS>\n      <SRS>EPSG:3397</SRS>\n      <SRS>EPSG:3398</SRS>\n      <SRS>EPSG:3399</SRS>\n      <SRS>EPSG:3400</SRS>\n      <SRS>EPSG:3401</SRS>\n      <SRS>EPSG:3402</SRS>\n      <SRS>EPSG:3403</SRS>\n      <SRS>EPSG:3404</SRS>\n      <SRS>EPSG:3405</SRS>\n      <SRS>EPSG:3406</SRS>\n      <SRS>EPSG:3407</SRS>\n      <SRS>EPSG:3408</SRS>\n      <SRS>EPSG:3409</SRS>\n      <SRS>EPSG:3410</SRS>\n      <SRS>EPSG:3411</SRS>\n      <SRS>EPSG:3412</SRS>\n      <SRS>EPSG:3413</SRS>\n      <SRS>EPSG:3414</SRS>\n      <SRS>EPSG:3415</SRS>\n      <SRS>EPSG:3416</SRS>\n      <SRS>EPSG:3417</SRS>\n      <SRS>EPSG:3418</SRS>\n      <SRS>EPSG:3419</SRS>\n      <SRS>EPSG:3420</SRS>\n      <SRS>EPSG:3421</SRS>\n      <SRS>EPSG:3422</SRS>\n      <SRS>EPSG:3423</SRS>\n      <SRS>EPSG:3424</SRS>\n      <SRS>EPSG:3425</SRS>\n      <SRS>EPSG:3426</SRS>\n      <SRS>EPSG:3427</SRS>\n      <SRS>EPSG:3428</SRS>\n      <SRS>EPSG:3429</SRS>\n      <SRS>EPSG:3430</SRS>\n      <SRS>EPSG:3431</SRS>\n      <SRS>EPSG:3432</SRS>\n      <SRS>EPSG:3433</SRS>\n      <SRS>EPSG:3434</SRS>\n      <SRS>EPSG:3435</SRS>\n      <SRS>EPSG:3436</SRS>\n      <SRS>EPSG:3437</SRS>\n      <SRS>EPSG:3438</SRS>\n      <SRS>EPSG:3439</SRS>\n      <SRS>EPSG:3440</SRS>\n      <SRS>EPSG:3441</SRS>\n      <SRS>EPSG:3442</SRS>\n      <SRS>EPSG:3443</SRS>\n      <SRS>EPSG:3444</SRS>\n      <SRS>EPSG:3445</SRS>\n      <SRS>EPSG:3446</SRS>\n      <SRS>EPSG:3447</SRS>\n      <SRS>EPSG:3448</SRS>\n      <SRS>EPSG:3449</SRS>\n      <SRS>EPSG:3450</SRS>\n      <SRS>EPSG:3451</SRS>\n      <SRS>EPSG:3452</SRS>\n      <SRS>EPSG:3453</SRS>\n      <SRS>EPSG:3454</SRS>\n      <SRS>EPSG:3455</SRS>\n      <SRS>EPSG:3456</SRS>\n      <SRS>EPSG:3457</SRS>\n      <SRS>EPSG:3458</SRS>\n      <SRS>EPSG:3459</SRS>\n      <SRS>EPSG:3460</SRS>\n      <SRS>EPSG:3461</SRS>\n      <SRS>EPSG:3462</SRS>\n      <SRS>EPSG:3463</SRS>\n      <SRS>EPSG:3464</SRS>\n      <SRS>EPSG:3560</SRS>\n      <SRS>EPSG:3561</SRS>\n      <SRS>EPSG:3562</SRS>\n      <SRS>EPSG:3563</SRS>\n      <SRS>EPSG:3564</SRS>\n      <SRS>EPSG:3565</SRS>\n      <SRS>EPSG:3566</SRS>\n      <SRS>EPSG:3567</SRS>\n      <SRS>EPSG:3568</SRS>\n      <SRS>EPSG:3569</SRS>\n      <SRS>EPSG:3570</SRS>\n      <SRS>EPSG:3571</SRS>\n      <SRS>EPSG:3572</SRS>\n      <SRS>EPSG:3573</SRS>\n      <SRS>EPSG:3574</SRS>\n      <SRS>EPSG:3575</SRS>\n      <SRS>EPSG:3576</SRS>\n      <SRS>EPSG:3577</SRS>\n      <SRS>EPSG:3920</SRS>\n      <SRS>EPSG:3991</SRS>\n      <SRS>EPSG:3992</SRS>\n      <SRS>EPSG:3993</SRS>\n      <SRS>EPSG:4001</SRS>\n      <SRS>EPSG:4002</SRS>\n      <SRS>EPSG:4003</SRS>\n      <SRS>EPSG:4004</SRS>\n      <SRS>EPSG:4005</SRS>\n      <SRS>EPSG:4006</SRS>\n      <SRS>EPSG:4007</SRS>\n      <SRS>EPSG:4008</SRS>\n      <SRS>EPSG:4009</SRS>\n      <SRS>EPSG:4010</SRS>\n      <SRS>EPSG:4011</SRS>\n      <SRS>EPSG:4012</SRS>\n      <SRS>EPSG:4013</SRS>\n      <SRS>EPSG:4014</SRS>\n      <SRS>EPSG:4015</SRS>\n      <SRS>EPSG:4016</SRS>\n      <SRS>EPSG:4018</SRS>\n      <SRS>EPSG:4019</SRS>\n      <SRS>EPSG:4020</SRS>\n      <SRS>EPSG:4021</SRS>\n      <SRS>EPSG:4022</SRS>\n      <SRS>EPSG:4024</SRS>\n      <SRS>EPSG:4025</SRS>\n      <SRS>EPSG:4027</SRS>\n      <SRS>EPSG:4028</SRS>\n      <SRS>EPSG:4029</SRS>\n      <SRS>EPSG:4030</SRS>\n      <SRS>EPSG:4031</SRS>\n      <SRS>EPSG:4032</SRS>\n      <SRS>EPSG:4033</SRS>\n      <SRS>EPSG:4034</SRS>\n      <SRS>EPSG:4035</SRS>\n      <SRS>EPSG:4036</SRS>\n      <SRS>EPSG:4041</SRS>\n      <SRS>EPSG:4042</SRS>\n      <SRS>EPSG:4043</SRS>\n      <SRS>EPSG:4044</SRS>\n      <SRS>EPSG:4045</SRS>\n      <SRS>EPSG:4047</SRS>\n      <SRS>EPSG:4052</SRS>\n      <SRS>EPSG:4053</SRS>\n      <SRS>EPSG:4054</SRS>\n      <SRS>EPSG:4120</SRS>\n      <SRS>EPSG:4121</SRS>\n      <SRS>EPSG:4122</SRS>\n      <SRS>EPSG:4123</SRS>\n      <SRS>EPSG:4124</SRS>\n      <SRS>EPSG:4125</SRS>\n      <SRS>EPSG:4126</SRS>\n      <SRS>EPSG:4127</SRS>\n      <SRS>EPSG:4128</SRS>\n      <SRS>EPSG:4129</SRS>\n      <SRS>EPSG:4130</SRS>\n      <SRS>EPSG:4131</SRS>\n      <SRS>EPSG:4132</SRS>\n      <SRS>EPSG:4133</SRS>\n      <SRS>EPSG:4134</SRS>\n      <SRS>EPSG:4135</SRS>\n      <SRS>EPSG:4136</SRS>\n      <SRS>EPSG:4137</SRS>\n      <SRS>EPSG:4138</SRS>\n      <SRS>EPSG:4139</SRS>\n      <SRS>EPSG:4140</SRS>\n      <SRS>EPSG:4141</SRS>\n      <SRS>EPSG:4142</SRS>\n      <SRS>EPSG:4143</SRS>\n      <SRS>EPSG:4144</SRS>\n      <SRS>EPSG:4145</SRS>\n      <SRS>EPSG:4146</SRS>\n      <SRS>EPSG:4147</SRS>\n      <SRS>EPSG:4148</SRS>\n      <SRS>EPSG:4149</SRS>\n      <SRS>EPSG:4150</SRS>\n      <SRS>EPSG:4151</SRS>\n      <SRS>EPSG:4152</SRS>\n      <SRS>EPSG:4153</SRS>\n      <SRS>EPSG:4154</SRS>\n      <SRS>EPSG:4155</SRS>\n      <SRS>EPSG:4156</SRS>\n      <SRS>EPSG:4157</SRS>\n      <SRS>EPSG:4158</SRS>\n      <SRS>EPSG:4159</SRS>\n      <SRS>EPSG:4160</SRS>\n      <SRS>EPSG:4161</SRS>\n      <SRS>EPSG:4162</SRS>\n      <SRS>EPSG:4163</SRS>\n      <SRS>EPSG:4164</SRS>\n      <SRS>EPSG:4165</SRS>\n      <SRS>EPSG:4166</SRS>\n      <SRS>EPSG:4167</SRS>\n      <SRS>EPSG:4168</SRS>\n      <SRS>EPSG:4169</SRS>\n      <SRS>EPSG:4170</SRS>\n      <SRS>EPSG:4171</SRS>\n      <SRS>EPSG:4172</SRS>\n      <SRS>EPSG:4173</SRS>\n      <SRS>EPSG:4174</SRS>\n      <SRS>EPSG:4175</SRS>\n      <SRS>EPSG:4176</SRS>\n      <SRS>EPSG:4178</SRS>\n      <SRS>EPSG:4179</SRS>\n      <SRS>EPSG:4180</SRS>\n      <SRS>EPSG:4181</SRS>\n      <SRS>EPSG:4182</SRS>\n      <SRS>EPSG:4183</SRS>\n      <SRS>EPSG:4184</SRS>\n      <SRS>EPSG:4185</SRS>\n      <SRS>EPSG:4188</SRS>\n      <SRS>EPSG:4189</SRS>\n      <SRS>EPSG:4190</SRS>\n      <SRS>EPSG:4191</SRS>\n      <SRS>EPSG:4192</SRS>\n      <SRS>EPSG:4193</SRS>\n      <SRS>EPSG:4194</SRS>\n      <SRS>EPSG:4195</SRS>\n      <SRS>EPSG:4196</SRS>\n      <SRS>EPSG:4197</SRS>\n      <SRS>EPSG:4198</SRS>\n      <SRS>EPSG:4199</SRS>\n      <SRS>EPSG:4200</SRS>\n      <SRS>EPSG:4201</SRS>\n      <SRS>EPSG:4202</SRS>\n      <SRS>EPSG:4203</SRS>\n      <SRS>EPSG:4204</SRS>\n      <SRS>EPSG:4205</SRS>\n      <SRS>EPSG:4206</SRS>\n      <SRS>EPSG:4207</SRS>\n      <SRS>EPSG:4208</SRS>\n      <SRS>EPSG:4209</SRS>\n      <SRS>EPSG:4210</SRS>\n      <SRS>EPSG:4211</SRS>\n      <SRS>EPSG:4212</SRS>\n      <SRS>EPSG:4213</SRS>\n      <SRS>EPSG:4214</SRS>\n      <SRS>EPSG:4215</SRS>\n      <SRS>EPSG:4216</SRS>\n      <SRS>EPSG:4218</SRS>\n      <SRS>EPSG:4219</SRS>\n      <SRS>EPSG:4220</SRS>\n      <SRS>EPSG:4221</SRS>\n      <SRS>EPSG:4222</SRS>\n      <SRS>EPSG:4223</SRS>\n      <SRS>EPSG:4224</SRS>\n      <SRS>EPSG:4225</SRS>\n      <SRS>EPSG:4226</SRS>\n      <SRS>EPSG:4227</SRS>\n      <SRS>EPSG:4228</SRS>\n      <SRS>EPSG:4229</SRS>\n      <SRS>EPSG:4230</SRS>\n      <SRS>EPSG:4231</SRS>\n      <SRS>EPSG:4232</SRS>\n      <SRS>EPSG:4233</SRS>\n      <SRS>EPSG:4234</SRS>\n      <SRS>EPSG:4235</SRS>\n      <SRS>EPSG:4236</SRS>\n      <SRS>EPSG:4237</SRS>\n      <SRS>EPSG:4238</SRS>\n      <SRS>EPSG:4239</SRS>\n      <SRS>EPSG:4240</SRS>\n      <SRS>EPSG:4241</SRS>\n      <SRS>EPSG:4242</SRS>\n      <SRS>EPSG:4243</SRS>\n      <SRS>EPSG:4244</SRS>\n      <SRS>EPSG:4245</SRS>\n      <SRS>EPSG:4246</SRS>\n      <SRS>EPSG:4247</SRS>\n      <SRS>EPSG:4248</SRS>\n      <SRS>EPSG:4249</SRS>\n      <SRS>EPSG:4250</SRS>\n      <SRS>EPSG:4251</SRS>\n      <SRS>EPSG:4252</SRS>\n      <SRS>EPSG:4253</SRS>\n      <SRS>EPSG:4254</SRS>\n      <SRS>EPSG:4255</SRS>\n      <SRS>EPSG:4256</SRS>\n      <SRS>EPSG:4257</SRS>\n      <SRS>EPSG:4258</SRS>\n      <SRS>EPSG:4259</SRS>\n      <SRS>EPSG:4260</SRS>\n      <SRS>EPSG:4261</SRS>\n      <SRS>EPSG:4262</SRS>\n      <SRS>EPSG:4263</SRS>\n      <SRS>EPSG:4264</SRS>\n      <SRS>EPSG:4265</SRS>\n      <SRS>EPSG:4266</SRS>\n      <SRS>EPSG:4267</SRS>\n      <SRS>EPSG:4268</SRS>\n      <SRS>EPSG:4269</SRS>\n      <SRS>EPSG:4270</SRS>\n      <SRS>EPSG:4271</SRS>\n      <SRS>EPSG:4272</SRS>\n      <SRS>EPSG:4273</SRS>\n      <SRS>EPSG:4274</SRS>\n      <SRS>EPSG:4275</SRS>\n      <SRS>EPSG:4276</SRS>\n      <SRS>EPSG:4277</SRS>\n      <SRS>EPSG:4278</SRS>\n      <SRS>EPSG:4279</SRS>\n      <SRS>EPSG:4280</SRS>\n      <SRS>EPSG:4281</SRS>\n      <SRS>EPSG:4282</SRS>\n      <SRS>EPSG:4283</SRS>\n      <SRS>EPSG:4284</SRS>\n      <SRS>EPSG:4285</SRS>\n      <SRS>EPSG:4286</SRS>\n      <SRS>EPSG:4287</SRS>\n      <SRS>EPSG:4288</SRS>\n      <SRS>EPSG:4289</SRS>\n      <SRS>EPSG:4291</SRS>\n      <SRS>EPSG:4292</SRS>\n      <SRS>EPSG:4293</SRS>\n      <SRS>EPSG:4294</SRS>\n      <SRS>EPSG:4295</SRS>\n      <SRS>EPSG:4296</SRS>\n      <SRS>EPSG:4297</SRS>\n      <SRS>EPSG:4298</SRS>\n      <SRS>EPSG:4299</SRS>\n      <SRS>EPSG:4300</SRS>\n      <SRS>EPSG:4301</SRS>\n      <SRS>EPSG:4302</SRS>\n      <SRS>EPSG:4303</SRS>\n      <SRS>EPSG:4304</SRS>\n      <SRS>EPSG:4306</SRS>\n      <SRS>EPSG:4307</SRS>\n      <SRS>EPSG:4308</SRS>\n      <SRS>EPSG:4309</SRS>\n      <SRS>EPSG:4310</SRS>\n      <SRS>EPSG:4311</SRS>\n      <SRS>EPSG:4312</SRS>\n      <SRS>EPSG:4313</SRS>\n      <SRS>EPSG:4314</SRS>\n      <SRS>EPSG:4315</SRS>\n      <SRS>EPSG:4316</SRS>\n      <SRS>EPSG:4317</SRS>\n      <SRS>EPSG:4318</SRS>\n      <SRS>EPSG:4319</SRS>\n      <SRS>EPSG:4322</SRS>\n      <SRS>EPSG:4324</SRS>\n      <SRS>EPSG:4326</SRS>\n      <SRS>EPSG:4327</SRS>\n      <SRS>EPSG:4328</SRS>\n      <SRS>EPSG:4329</SRS>\n      <SRS>EPSG:4330</SRS>\n      <SRS>EPSG:4331</SRS>\n      <SRS>EPSG:4332</SRS>\n      <SRS>EPSG:4333</SRS>\n      <SRS>EPSG:4334</SRS>\n      <SRS>EPSG:4335</SRS>\n      <SRS>EPSG:4336</SRS>\n      <SRS>EPSG:4337</SRS>\n      <SRS>EPSG:4338</SRS>\n      <SRS>EPSG:4339</SRS>\n      <SRS>EPSG:4340</SRS>\n      <SRS>EPSG:4341</SRS>\n      <SRS>EPSG:4342</SRS>\n      <SRS>EPSG:4343</SRS>\n      <SRS>EPSG:4344</SRS>\n      <SRS>EPSG:4345</SRS>\n      <SRS>EPSG:4346</SRS>\n      <SRS>EPSG:4347</SRS>\n      <SRS>EPSG:4348</SRS>\n      <SRS>EPSG:4349</SRS>\n      <SRS>EPSG:4350</SRS>\n      <SRS>EPSG:4351</SRS>\n      <SRS>EPSG:4352</SRS>\n      <SRS>EPSG:4353</SRS>\n      <SRS>EPSG:4354</SRS>\n      <SRS>EPSG:4355</SRS>\n      <SRS>EPSG:4356</SRS>\n      <SRS>EPSG:4357</SRS>\n      <SRS>EPSG:4358</SRS>\n      <SRS>EPSG:4359</SRS>\n      <SRS>EPSG:4360</SRS>\n      <SRS>EPSG:4361</SRS>\n      <SRS>EPSG:4362</SRS>\n      <SRS>EPSG:4363</SRS>\n      <SRS>EPSG:4364</SRS>\n      <SRS>EPSG:4365</SRS>\n      <SRS>EPSG:4366</SRS>\n      <SRS>EPSG:4367</SRS>\n      <SRS>EPSG:4368</SRS>\n      <SRS>EPSG:4369</SRS>\n      <SRS>EPSG:4370</SRS>\n      <SRS>EPSG:4371</SRS>\n      <SRS>EPSG:4372</SRS>\n      <SRS>EPSG:4373</SRS>\n      <SRS>EPSG:4374</SRS>\n      <SRS>EPSG:4375</SRS>\n      <SRS>EPSG:4376</SRS>\n      <SRS>EPSG:4377</SRS>\n      <SRS>EPSG:4378</SRS>\n      <SRS>EPSG:4379</SRS>\n      <SRS>EPSG:4380</SRS>\n      <SRS>EPSG:4381</SRS>\n      <SRS>EPSG:4382</SRS>\n      <SRS>EPSG:4383</SRS>\n      <SRS>EPSG:4384</SRS>\n      <SRS>EPSG:4385</SRS>\n      <SRS>EPSG:4386</SRS>\n      <SRS>EPSG:4387</SRS>\n      <SRS>EPSG:4388</SRS>\n      <SRS>EPSG:4389</SRS>\n      <SRS>EPSG:4600</SRS>\n      <SRS>EPSG:4601</SRS>\n      <SRS>EPSG:4602</SRS>\n      <SRS>EPSG:4603</SRS>\n      <SRS>EPSG:4604</SRS>\n      <SRS>EPSG:4605</SRS>\n      <SRS>EPSG:4606</SRS>\n      <SRS>EPSG:4607</SRS>\n      <SRS>EPSG:4608</SRS>\n      <SRS>EPSG:4609</SRS>\n      <SRS>EPSG:4610</SRS>\n      <SRS>EPSG:4611</SRS>\n      <SRS>EPSG:4612</SRS>\n      <SRS>EPSG:4613</SRS>\n      <SRS>EPSG:4614</SRS>\n      <SRS>EPSG:4615</SRS>\n      <SRS>EPSG:4616</SRS>\n      <SRS>EPSG:4617</SRS>\n      <SRS>EPSG:4618</SRS>\n      <SRS>EPSG:4619</SRS>\n      <SRS>EPSG:4620</SRS>\n      <SRS>EPSG:4621</SRS>\n      <SRS>EPSG:4622</SRS>\n      <SRS>EPSG:4623</SRS>\n      <SRS>EPSG:4624</SRS>\n      <SRS>EPSG:4625</SRS>\n      <SRS>EPSG:4626</SRS>\n      <SRS>EPSG:4627</SRS>\n      <SRS>EPSG:4628</SRS>\n      <SRS>EPSG:4629</SRS>\n      <SRS>EPSG:4630</SRS>\n      <SRS>EPSG:4631</SRS>\n      <SRS>EPSG:4632</SRS>\n      <SRS>EPSG:4633</SRS>\n      <SRS>EPSG:4634</SRS>\n      <SRS>EPSG:4635</SRS>\n      <SRS>EPSG:4636</SRS>\n      <SRS>EPSG:4637</SRS>\n      <SRS>EPSG:4638</SRS>\n      <SRS>EPSG:4639</SRS>\n      <SRS>EPSG:4640</SRS>\n      <SRS>EPSG:4641</SRS>\n      <SRS>EPSG:4642</SRS>\n      <SRS>EPSG:4643</SRS>\n      <SRS>EPSG:4644</SRS>\n      <SRS>EPSG:4645</SRS>\n      <SRS>EPSG:4646</SRS>\n      <SRS>EPSG:4657</SRS>\n      <SRS>EPSG:4658</SRS>\n      <SRS>EPSG:4659</SRS>\n      <SRS>EPSG:4660</SRS>\n      <SRS>EPSG:4661</SRS>\n      <SRS>EPSG:4662</SRS>\n      <SRS>EPSG:4663</SRS>\n      <SRS>EPSG:4664</SRS>\n      <SRS>EPSG:4665</SRS>\n      <SRS>EPSG:4666</SRS>\n      <SRS>EPSG:4667</SRS>\n      <SRS>EPSG:4668</SRS>\n      <SRS>EPSG:4669</SRS>\n      <SRS>EPSG:4670</SRS>\n      <SRS>EPSG:4671</SRS>\n      <SRS>EPSG:4672</SRS>\n      <SRS>EPSG:4673</SRS>\n      <SRS>EPSG:4674</SRS>\n      <SRS>EPSG:4675</SRS>\n      <SRS>EPSG:4676</SRS>\n      <SRS>EPSG:4677</SRS>\n      <SRS>EPSG:4678</SRS>\n      <SRS>EPSG:4679</SRS>\n      <SRS>EPSG:4680</SRS>\n      <SRS>EPSG:4681</SRS>\n      <SRS>EPSG:4682</SRS>\n      <SRS>EPSG:4683</SRS>\n      <SRS>EPSG:4684</SRS>\n      <SRS>EPSG:4685</SRS>\n      <SRS>EPSG:4686</SRS>\n      <SRS>EPSG:4687</SRS>\n      <SRS>EPSG:4688</SRS>\n      <SRS>EPSG:4689</SRS>\n      <SRS>EPSG:4690</SRS>\n      <SRS>EPSG:4691</SRS>\n      <SRS>EPSG:4692</SRS>\n      <SRS>EPSG:4693</SRS>\n      <SRS>EPSG:4694</SRS>\n      <SRS>EPSG:4695</SRS>\n      <SRS>EPSG:4696</SRS>\n      <SRS>EPSG:4697</SRS>\n      <SRS>EPSG:4698</SRS>\n      <SRS>EPSG:4699</SRS>\n      <SRS>EPSG:4700</SRS>\n      <SRS>EPSG:4701</SRS>\n      <SRS>EPSG:4702</SRS>\n      <SRS>EPSG:4703</SRS>\n      <SRS>EPSG:4704</SRS>\n      <SRS>EPSG:4705</SRS>\n      <SRS>EPSG:4706</SRS>\n      <SRS>EPSG:4707</SRS>\n      <SRS>EPSG:4708</SRS>\n      <SRS>EPSG:4709</SRS>\n      <SRS>EPSG:4710</SRS>\n      <SRS>EPSG:4711</SRS>\n      <SRS>EPSG:4712</SRS>\n      <SRS>EPSG:4713</SRS>\n      <SRS>EPSG:4714</SRS>\n      <SRS>EPSG:4715</SRS>\n      <SRS>EPSG:4716</SRS>\n      <SRS>EPSG:4717</SRS>\n      <SRS>EPSG:4718</SRS>\n      <SRS>EPSG:4719</SRS>\n      <SRS>EPSG:4720</SRS>\n      <SRS>EPSG:4721</SRS>\n      <SRS>EPSG:4722</SRS>\n      <SRS>EPSG:4723</SRS>\n      <SRS>EPSG:4724</SRS>\n      <SRS>EPSG:4725</SRS>\n      <SRS>EPSG:4726</SRS>\n      <SRS>EPSG:4727</SRS>\n      <SRS>EPSG:4728</SRS>\n      <SRS>EPSG:4729</SRS>\n      <SRS>EPSG:4730</SRS>\n      <SRS>EPSG:4731</SRS>\n      <SRS>EPSG:4732</SRS>\n      <SRS>EPSG:4733</SRS>\n      <SRS>EPSG:4734</SRS>\n      <SRS>EPSG:4735</SRS>\n      <SRS>EPSG:4736</SRS>\n      <SRS>EPSG:4737</SRS>\n      <SRS>EPSG:4738</SRS>\n      <SRS>EPSG:4739</SRS>\n      <SRS>EPSG:4740</SRS>\n      <SRS>EPSG:4741</SRS>\n      <SRS>EPSG:4742</SRS>\n      <SRS>EPSG:4743</SRS>\n      <SRS>EPSG:4744</SRS>\n      <SRS>EPSG:4745</SRS>\n      <SRS>EPSG:4746</SRS>\n      <SRS>EPSG:4747</SRS>\n      <SRS>EPSG:4748</SRS>\n      <SRS>EPSG:4749</SRS>\n      <SRS>EPSG:4750</SRS>\n      <SRS>EPSG:4751</SRS>\n      <SRS>EPSG:4752</SRS>\n      <SRS>EPSG:4753</SRS>\n      <SRS>EPSG:4754</SRS>\n      <SRS>EPSG:4755</SRS>\n      <SRS>EPSG:4756</SRS>\n      <SRS>EPSG:4757</SRS>\n      <SRS>EPSG:4758</SRS>\n      <SRS>EPSG:4801</SRS>\n      <SRS>EPSG:4802</SRS>\n      <SRS>EPSG:4803</SRS>\n      <SRS>EPSG:4804</SRS>\n      <SRS>EPSG:4805</SRS>\n      <SRS>EPSG:4806</SRS>\n      <SRS>EPSG:4807</SRS>\n      <SRS>EPSG:4808</SRS>\n      <SRS>EPSG:4809</SRS>\n      <SRS>EPSG:4810</SRS>\n      <SRS>EPSG:4811</SRS>\n      <SRS>EPSG:4813</SRS>\n      <SRS>EPSG:4814</SRS>\n      <SRS>EPSG:4815</SRS>\n      <SRS>EPSG:4816</SRS>\n      <SRS>EPSG:4817</SRS>\n      <SRS>EPSG:4818</SRS>\n      <SRS>EPSG:4819</SRS>\n      <SRS>EPSG:4820</SRS>\n      <SRS>EPSG:4821</SRS>\n      <SRS>EPSG:4894</SRS>\n      <SRS>EPSG:4895</SRS>\n      <SRS>EPSG:4896</SRS>\n      <SRS>EPSG:4897</SRS>\n      <SRS>EPSG:4898</SRS>\n      <SRS>EPSG:4899</SRS>\n      <SRS>EPSG:4900</SRS>\n      <SRS>EPSG:4901</SRS>\n      <SRS>EPSG:4902</SRS>\n      <SRS>EPSG:4903</SRS>\n      <SRS>EPSG:4904</SRS>\n      <SRS>EPSG:4906</SRS>\n      <SRS>EPSG:4907</SRS>\n      <SRS>EPSG:4908</SRS>\n      <SRS>EPSG:4909</SRS>\n      <SRS>EPSG:4910</SRS>\n      <SRS>EPSG:4911</SRS>\n      <SRS>EPSG:4912</SRS>\n      <SRS>EPSG:4913</SRS>\n      <SRS>EPSG:4914</SRS>\n      <SRS>EPSG:4915</SRS>\n      <SRS>EPSG:4916</SRS>\n      <SRS>EPSG:4917</SRS>\n      <SRS>EPSG:4918</SRS>\n      <SRS>EPSG:4919</SRS>\n      <SRS>EPSG:4920</SRS>\n      <SRS>EPSG:4921</SRS>\n      <SRS>EPSG:4922</SRS>\n      <SRS>EPSG:4923</SRS>\n      <SRS>EPSG:4924</SRS>\n      <SRS>EPSG:4925</SRS>\n      <SRS>EPSG:4926</SRS>\n      <SRS>EPSG:4927</SRS>\n      <SRS>EPSG:4928</SRS>\n      <SRS>EPSG:4929</SRS>\n      <SRS>EPSG:4930</SRS>\n      <SRS>EPSG:4931</SRS>\n      <SRS>EPSG:4932</SRS>\n      <SRS>EPSG:4933</SRS>\n      <SRS>EPSG:4934</SRS>\n      <SRS>EPSG:4935</SRS>\n      <SRS>EPSG:4936</SRS>\n      <SRS>EPSG:4937</SRS>\n      <SRS>EPSG:4938</SRS>\n      <SRS>EPSG:4939</SRS>\n      <SRS>EPSG:4940</SRS>\n      <SRS>EPSG:4941</SRS>\n      <SRS>EPSG:4942</SRS>\n      <SRS>EPSG:4943</SRS>\n      <SRS>EPSG:4944</SRS>\n      <SRS>EPSG:4945</SRS>\n      <SRS>EPSG:4946</SRS>\n      <SRS>EPSG:4947</SRS>\n      <SRS>EPSG:4948</SRS>\n      <SRS>EPSG:4949</SRS>\n      <SRS>EPSG:4950</SRS>\n      <SRS>EPSG:4951</SRS>\n      <SRS>EPSG:4952</SRS>\n      <SRS>EPSG:4953</SRS>\n      <SRS>EPSG:4954</SRS>\n      <SRS>EPSG:4955</SRS>\n      <SRS>EPSG:4956</SRS>\n      <SRS>EPSG:4957</SRS>\n      <SRS>EPSG:4958</SRS>\n      <SRS>EPSG:4959</SRS>\n      <SRS>EPSG:4960</SRS>\n      <SRS>EPSG:4961</SRS>\n      <SRS>EPSG:4962</SRS>\n      <SRS>EPSG:4963</SRS>\n      <SRS>EPSG:4964</SRS>\n      <SRS>EPSG:4965</SRS>\n      <SRS>EPSG:4966</SRS>\n      <SRS>EPSG:4967</SRS>\n      <SRS>EPSG:4968</SRS>\n      <SRS>EPSG:4969</SRS>\n      <SRS>EPSG:4970</SRS>\n      <SRS>EPSG:4971</SRS>\n      <SRS>EPSG:4972</SRS>\n      <SRS>EPSG:4973</SRS>\n      <SRS>EPSG:4974</SRS>\n      <SRS>EPSG:4975</SRS>\n      <SRS>EPSG:4976</SRS>\n      <SRS>EPSG:4977</SRS>\n      <SRS>EPSG:4978</SRS>\n      <SRS>EPSG:4979</SRS>\n      <SRS>EPSG:4980</SRS>\n      <SRS>EPSG:4981</SRS>\n      <SRS>EPSG:4982</SRS>\n      <SRS>EPSG:4983</SRS>\n      <SRS>EPSG:4984</SRS>\n      <SRS>EPSG:4985</SRS>\n      <SRS>EPSG:4986</SRS>\n      <SRS>EPSG:4987</SRS>\n      <SRS>EPSG:4988</SRS>\n      <SRS>EPSG:4989</SRS>\n      <SRS>EPSG:4990</SRS>\n      <SRS>EPSG:4991</SRS>\n      <SRS>EPSG:4992</SRS>\n      <SRS>EPSG:4993</SRS>\n      <SRS>EPSG:4994</SRS>\n      <SRS>EPSG:4995</SRS>\n      <SRS>EPSG:4996</SRS>\n      <SRS>EPSG:4997</SRS>\n      <SRS>EPSG:4998</SRS>\n      <SRS>EPSG:4999</SRS>\n      <SRS>EPSG:5600</SRS>\n      <SRS>EPSG:5601</SRS>\n      <SRS>EPSG:5602</SRS>\n      <SRS>EPSG:5603</SRS>\n      <SRS>EPSG:5604</SRS>\n      <SRS>EPSG:5605</SRS>\n      <SRS>EPSG:5606</SRS>\n      <SRS>EPSG:5607</SRS>\n      <SRS>EPSG:5608</SRS>\n      <SRS>EPSG:5609</SRS>\n      <SRS>EPSG:5701</SRS>\n      <SRS>EPSG:5702</SRS>\n      <SRS>EPSG:5703</SRS>\n      <SRS>EPSG:5704</SRS>\n      <SRS>EPSG:5705</SRS>\n      <SRS>EPSG:5706</SRS>\n      <SRS>EPSG:5709</SRS>\n      <SRS>EPSG:5710</SRS>\n      <SRS>EPSG:5711</SRS>\n      <SRS>EPSG:5712</SRS>\n      <SRS>EPSG:5713</SRS>\n      <SRS>EPSG:5714</SRS>\n      <SRS>EPSG:5715</SRS>\n      <SRS>EPSG:5716</SRS>\n      <SRS>EPSG:5717</SRS>\n      <SRS>EPSG:5718</SRS>\n      <SRS>EPSG:5719</SRS>\n      <SRS>EPSG:5720</SRS>\n      <SRS>EPSG:5721</SRS>\n      <SRS>EPSG:5722</SRS>\n      <SRS>EPSG:5723</SRS>\n      <SRS>EPSG:5724</SRS>\n      <SRS>EPSG:5725</SRS>\n      <SRS>EPSG:5726</SRS>\n      <SRS>EPSG:5727</SRS>\n      <SRS>EPSG:5728</SRS>\n      <SRS>EPSG:5729</SRS>\n      <SRS>EPSG:5730</SRS>\n      <SRS>EPSG:5731</SRS>\n      <SRS>EPSG:5732</SRS>\n      <SRS>EPSG:5733</SRS>\n      <SRS>EPSG:5734</SRS>\n      <SRS>EPSG:5735</SRS>\n      <SRS>EPSG:5736</SRS>\n      <SRS>EPSG:5737</SRS>\n      <SRS>EPSG:5738</SRS>\n      <SRS>EPSG:5739</SRS>\n      <SRS>EPSG:5740</SRS>\n      <SRS>EPSG:5741</SRS>\n      <SRS>EPSG:5742</SRS>\n      <SRS>EPSG:5743</SRS>\n      <SRS>EPSG:5744</SRS>\n      <SRS>EPSG:5745</SRS>\n      <SRS>EPSG:5746</SRS>\n      <SRS>EPSG:5747</SRS>\n      <SRS>EPSG:5748</SRS>\n      <SRS>EPSG:5749</SRS>\n      <SRS>EPSG:5750</SRS>\n      <SRS>EPSG:5751</SRS>\n      <SRS>EPSG:5752</SRS>\n      <SRS>EPSG:5753</SRS>\n      <SRS>EPSG:5754</SRS>\n      <SRS>EPSG:5755</SRS>\n      <SRS>EPSG:5756</SRS>\n      <SRS>EPSG:5757</SRS>\n      <SRS>EPSG:5758</SRS>\n      <SRS>EPSG:5759</SRS>\n      <SRS>EPSG:5760</SRS>\n      <SRS>EPSG:5761</SRS>\n      <SRS>EPSG:5762</SRS>\n      <SRS>EPSG:5763</SRS>\n      <SRS>EPSG:5764</SRS>\n      <SRS>EPSG:5765</SRS>\n      <SRS>EPSG:5766</SRS>\n      <SRS>EPSG:5767</SRS>\n      <SRS>EPSG:5768</SRS>\n      <SRS>EPSG:5769</SRS>\n      <SRS>EPSG:5770</SRS>\n      <SRS>EPSG:5771</SRS>\n      <SRS>EPSG:5772</SRS>\n      <SRS>EPSG:5773</SRS>\n      <SRS>EPSG:5774</SRS>\n      <SRS>EPSG:5775</SRS>\n      <SRS>EPSG:5776</SRS>\n      <SRS>EPSG:5777</SRS>\n      <SRS>EPSG:5778</SRS>\n      <SRS>EPSG:5779</SRS>\n      <SRS>EPSG:5780</SRS>\n      <SRS>EPSG:5781</SRS>\n      <SRS>EPSG:5782</SRS>\n      <SRS>EPSG:5783</SRS>\n      <SRS>EPSG:5784</SRS>\n      <SRS>EPSG:5785</SRS>\n      <SRS>EPSG:5786</SRS>\n      <SRS>EPSG:5787</SRS>\n      <SRS>EPSG:5788</SRS>\n      <SRS>EPSG:5789</SRS>\n      <SRS>EPSG:5790</SRS>\n      <SRS>EPSG:5791</SRS>\n      <SRS>EPSG:5792</SRS>\n      <SRS>EPSG:5793</SRS>\n      <SRS>EPSG:5794</SRS>\n      <SRS>EPSG:5795</SRS>\n      <SRS>EPSG:5796</SRS>\n      <SRS>EPSG:5797</SRS>\n      <SRS>EPSG:5798</SRS>\n      <SRS>EPSG:5799</SRS>\n      <SRS>EPSG:5800</SRS>\n      <SRS>EPSG:5801</SRS>\n      <SRS>EPSG:5802</SRS>\n      <SRS>EPSG:5803</SRS>\n      <SRS>EPSG:5804</SRS>\n      <SRS>EPSG:5805</SRS>\n      <SRS>EPSG:5806</SRS>\n      <SRS>EPSG:5807</SRS>\n      <SRS>EPSG:5808</SRS>\n      <SRS>EPSG:5809</SRS>\n      <SRS>EPSG:5810</SRS>\n      <SRS>EPSG:5811</SRS>\n      <SRS>EPSG:5812</SRS>\n      <SRS>EPSG:5813</SRS>\n      <SRS>EPSG:5814</SRS>\n      <SRS>EPSG:5815</SRS>\n      <SRS>EPSG:5816</SRS>\n      <SRS>EPSG:5817</SRS>\n      <SRS>EPSG:5818</SRS>\n      <SRS>EPSG:7400</SRS>\n      <SRS>EPSG:7401</SRS>\n      <SRS>EPSG:7402</SRS>\n      <SRS>EPSG:7403</SRS>\n      <SRS>EPSG:7404</SRS>\n      <SRS>EPSG:7405</SRS>\n      <SRS>EPSG:7406</SRS>\n      <SRS>EPSG:7407</SRS>\n      <SRS>EPSG:7408</SRS>\n      <SRS>EPSG:7409</SRS>\n      <SRS>EPSG:7410</SRS>\n      <SRS>EPSG:7411</SRS>\n      <SRS>EPSG:7412</SRS>\n      <SRS>EPSG:7413</SRS>\n      <SRS>EPSG:7414</SRS>\n      <SRS>EPSG:7415</SRS>\n      <SRS>EPSG:7416</SRS>\n      <SRS>EPSG:7417</SRS>\n      <SRS>EPSG:7418</SRS>\n      <SRS>EPSG:7419</SRS>\n      <SRS>EPSG:7420</SRS>\n      <SRS>EPSG:20004</SRS>\n      <SRS>EPSG:20005</SRS>\n      <SRS>EPSG:20006</SRS>\n      <SRS>EPSG:20007</SRS>\n      <SRS>EPSG:20008</SRS>\n      <SRS>EPSG:20009</SRS>\n      <SRS>EPSG:20010</SRS>\n      <SRS>EPSG:20011</SRS>\n      <SRS>EPSG:20012</SRS>\n      <SRS>EPSG:20013</SRS>\n      <SRS>EPSG:20014</SRS>\n      <SRS>EPSG:20015</SRS>\n      <SRS>EPSG:20016</SRS>\n      <SRS>EPSG:20017</SRS>\n      <SRS>EPSG:20018</SRS>\n      <SRS>EPSG:20019</SRS>\n      <SRS>EPSG:20020</SRS>\n      <SRS>EPSG:20021</SRS>\n      <SRS>EPSG:20022</SRS>\n      <SRS>EPSG:20023</SRS>\n      <SRS>EPSG:20024</SRS>\n      <SRS>EPSG:20025</SRS>\n      <SRS>EPSG:20026</SRS>\n      <SRS>EPSG:20027</SRS>\n      <SRS>EPSG:20028</SRS>\n      <SRS>EPSG:20029</SRS>\n      <SRS>EPSG:20030</SRS>\n      <SRS>EPSG:20031</SRS>\n      <SRS>EPSG:20032</SRS>\n      <SRS>EPSG:20064</SRS>\n      <SRS>EPSG:20065</SRS>\n      <SRS>EPSG:20066</SRS>\n      <SRS>EPSG:20067</SRS>\n      <SRS>EPSG:20068</SRS>\n      <SRS>EPSG:20069</SRS>\n      <SRS>EPSG:20070</SRS>\n      <SRS>EPSG:20071</SRS>\n      <SRS>EPSG:20072</SRS>\n      <SRS>EPSG:20073</SRS>\n      <SRS>EPSG:20074</SRS>\n      <SRS>EPSG:20075</SRS>\n      <SRS>EPSG:20076</SRS>\n      <SRS>EPSG:20077</SRS>\n      <SRS>EPSG:20078</SRS>\n      <SRS>EPSG:20079</SRS>\n      <SRS>EPSG:20080</SRS>\n      <SRS>EPSG:20081</SRS>\n      <SRS>EPSG:20082</SRS>\n      <SRS>EPSG:20083</SRS>\n      <SRS>EPSG:20084</SRS>\n      <SRS>EPSG:20085</SRS>\n      <SRS>EPSG:20086</SRS>\n      <SRS>EPSG:20087</SRS>\n      <SRS>EPSG:20088</SRS>\n      <SRS>EPSG:20089</SRS>\n      <SRS>EPSG:20090</SRS>\n      <SRS>EPSG:20091</SRS>\n      <SRS>EPSG:20092</SRS>\n      <SRS>EPSG:20135</SRS>\n      <SRS>EPSG:20136</SRS>\n      <SRS>EPSG:20137</SRS>\n      <SRS>EPSG:20138</SRS>\n      <SRS>EPSG:20248</SRS>\n      <SRS>EPSG:20249</SRS>\n      <SRS>EPSG:20250</SRS>\n      <SRS>EPSG:20251</SRS>\n      <SRS>EPSG:20252</SRS>\n      <SRS>EPSG:20253</SRS>\n      <SRS>EPSG:20254</SRS>\n      <SRS>EPSG:20255</SRS>\n      <SRS>EPSG:20256</SRS>\n      <SRS>EPSG:20257</SRS>\n      <SRS>EPSG:20258</SRS>\n      <SRS>EPSG:20348</SRS>\n      <SRS>EPSG:20349</SRS>\n      <SRS>EPSG:20350</SRS>\n      <SRS>EPSG:20351</SRS>\n      <SRS>EPSG:20352</SRS>\n      <SRS>EPSG:20353</SRS>\n      <SRS>EPSG:20354</SRS>\n      <SRS>EPSG:20355</SRS>\n      <SRS>EPSG:20356</SRS>\n      <SRS>EPSG:20357</SRS>\n      <SRS>EPSG:20358</SRS>\n      <SRS>EPSG:20436</SRS>\n      <SRS>EPSG:20437</SRS>\n      <SRS>EPSG:20438</SRS>\n      <SRS>EPSG:20439</SRS>\n      <SRS>EPSG:20440</SRS>\n      <SRS>EPSG:20499</SRS>\n      <SRS>EPSG:20538</SRS>\n      <SRS>EPSG:20539</SRS>\n      <SRS>EPSG:20790</SRS>\n      <SRS>EPSG:20791</SRS>\n      <SRS>EPSG:20822</SRS>\n      <SRS>EPSG:20823</SRS>\n      <SRS>EPSG:20824</SRS>\n      <SRS>EPSG:20934</SRS>\n      <SRS>EPSG:20935</SRS>\n      <SRS>EPSG:20936</SRS>\n      <SRS>EPSG:21035</SRS>\n      <SRS>EPSG:21036</SRS>\n      <SRS>EPSG:21037</SRS>\n      <SRS>EPSG:21095</SRS>\n      <SRS>EPSG:21096</SRS>\n      <SRS>EPSG:21097</SRS>\n      <SRS>EPSG:21100</SRS>\n      <SRS>EPSG:21148</SRS>\n      <SRS>EPSG:21149</SRS>\n      <SRS>EPSG:21150</SRS>\n      <SRS>EPSG:21291</SRS>\n      <SRS>EPSG:21292</SRS>\n      <SRS>EPSG:21413</SRS>\n      <SRS>EPSG:21414</SRS>\n      <SRS>EPSG:21415</SRS>\n      <SRS>EPSG:21416</SRS>\n      <SRS>EPSG:21417</SRS>\n      <SRS>EPSG:21418</SRS>\n      <SRS>EPSG:21419</SRS>\n      <SRS>EPSG:21420</SRS>\n      <SRS>EPSG:21421</SRS>\n      <SRS>EPSG:21422</SRS>\n      <SRS>EPSG:21423</SRS>\n      <SRS>EPSG:21453</SRS>\n      <SRS>EPSG:21454</SRS>\n      <SRS>EPSG:21455</SRS>\n      <SRS>EPSG:21456</SRS>\n      <SRS>EPSG:21457</SRS>\n      <SRS>EPSG:21458</SRS>\n      <SRS>EPSG:21459</SRS>\n      <SRS>EPSG:21460</SRS>\n      <SRS>EPSG:21461</SRS>\n      <SRS>EPSG:21462</SRS>\n      <SRS>EPSG:21463</SRS>\n      <SRS>EPSG:21473</SRS>\n      <SRS>EPSG:21474</SRS>\n      <SRS>EPSG:21475</SRS>\n      <SRS>EPSG:21476</SRS>\n      <SRS>EPSG:21477</SRS>\n      <SRS>EPSG:21478</SRS>\n      <SRS>EPSG:21479</SRS>\n      <SRS>EPSG:21480</SRS>\n      <SRS>EPSG:21481</SRS>\n      <SRS>EPSG:21482</SRS>\n      <SRS>EPSG:21483</SRS>\n      <SRS>EPSG:21500</SRS>\n      <SRS>EPSG:21780</SRS>\n      <SRS>EPSG:21781</SRS>\n      <SRS>EPSG:21817</SRS>\n      <SRS>EPSG:21818</SRS>\n      <SRS>EPSG:21891</SRS>\n      <SRS>EPSG:21892</SRS>\n      <SRS>EPSG:21893</SRS>\n      <SRS>EPSG:21894</SRS>\n      <SRS>EPSG:21896</SRS>\n      <SRS>EPSG:21897</SRS>\n      <SRS>EPSG:21898</SRS>\n      <SRS>EPSG:21899</SRS>\n      <SRS>EPSG:22032</SRS>\n      <SRS>EPSG:22033</SRS>\n      <SRS>EPSG:22091</SRS>\n      <SRS>EPSG:22092</SRS>\n      <SRS>EPSG:22171</SRS>\n      <SRS>EPSG:22172</SRS>\n      <SRS>EPSG:22173</SRS>\n      <SRS>EPSG:22174</SRS>\n      <SRS>EPSG:22175</SRS>\n      <SRS>EPSG:22176</SRS>\n      <SRS>EPSG:22177</SRS>\n      <SRS>EPSG:22181</SRS>\n      <SRS>EPSG:22182</SRS>\n      <SRS>EPSG:22183</SRS>\n      <SRS>EPSG:22184</SRS>\n      <SRS>EPSG:22185</SRS>\n      <SRS>EPSG:22186</SRS>\n      <SRS>EPSG:22187</SRS>\n      <SRS>EPSG:22191</SRS>\n      <SRS>EPSG:22192</SRS>\n      <SRS>EPSG:22193</SRS>\n      <SRS>EPSG:22194</SRS>\n      <SRS>EPSG:22195</SRS>\n      <SRS>EPSG:22196</SRS>\n      <SRS>EPSG:22197</SRS>\n      <SRS>EPSG:22234</SRS>\n      <SRS>EPSG:22235</SRS>\n      <SRS>EPSG:22236</SRS>\n      <SRS>EPSG:22275</SRS>\n      <SRS>EPSG:22277</SRS>\n      <SRS>EPSG:22279</SRS>\n      <SRS>EPSG:22281</SRS>\n      <SRS>EPSG:22283</SRS>\n      <SRS>EPSG:22285</SRS>\n      <SRS>EPSG:22287</SRS>\n      <SRS>EPSG:22289</SRS>\n      <SRS>EPSG:22291</SRS>\n      <SRS>EPSG:22293</SRS>\n      <SRS>EPSG:22300</SRS>\n      <SRS>EPSG:22332</SRS>\n      <SRS>EPSG:22391</SRS>\n      <SRS>EPSG:22392</SRS>\n      <SRS>EPSG:22521</SRS>\n      <SRS>EPSG:22522</SRS>\n      <SRS>EPSG:22523</SRS>\n      <SRS>EPSG:22524</SRS>\n      <SRS>EPSG:22525</SRS>\n      <SRS>EPSG:22700</SRS>\n      <SRS>EPSG:22770</SRS>\n      <SRS>EPSG:22780</SRS>\n      <SRS>EPSG:22832</SRS>\n      <SRS>EPSG:22991</SRS>\n      <SRS>EPSG:22992</SRS>\n      <SRS>EPSG:22993</SRS>\n      <SRS>EPSG:22994</SRS>\n      <SRS>EPSG:23028</SRS>\n      <SRS>EPSG:23029</SRS>\n      <SRS>EPSG:23030</SRS>\n      <SRS>EPSG:23031</SRS>\n      <SRS>EPSG:23032</SRS>\n      <SRS>EPSG:23033</SRS>\n      <SRS>EPSG:23034</SRS>\n      <SRS>EPSG:23035</SRS>\n      <SRS>EPSG:23036</SRS>\n      <SRS>EPSG:23037</SRS>\n      <SRS>EPSG:23038</SRS>\n      <SRS>EPSG:23090</SRS>\n      <SRS>EPSG:23095</SRS>\n      <SRS>EPSG:23239</SRS>\n      <SRS>EPSG:23240</SRS>\n      <SRS>EPSG:23433</SRS>\n      <SRS>EPSG:23700</SRS>\n      <SRS>EPSG:23846</SRS>\n      <SRS>EPSG:23847</SRS>\n      <SRS>EPSG:23848</SRS>\n      <SRS>EPSG:23849</SRS>\n      <SRS>EPSG:23850</SRS>\n      <SRS>EPSG:23851</SRS>\n      <SRS>EPSG:23852</SRS>\n      <SRS>EPSG:23853</SRS>\n      <SRS>EPSG:23866</SRS>\n      <SRS>EPSG:23867</SRS>\n      <SRS>EPSG:23868</SRS>\n      <SRS>EPSG:23869</SRS>\n      <SRS>EPSG:23870</SRS>\n      <SRS>EPSG:23871</SRS>\n      <SRS>EPSG:23872</SRS>\n      <SRS>EPSG:23877</SRS>\n      <SRS>EPSG:23878</SRS>\n      <SRS>EPSG:23879</SRS>\n      <SRS>EPSG:23880</SRS>\n      <SRS>EPSG:23881</SRS>\n      <SRS>EPSG:23882</SRS>\n      <SRS>EPSG:23883</SRS>\n      <SRS>EPSG:23884</SRS>\n      <SRS>EPSG:23886</SRS>\n      <SRS>EPSG:23887</SRS>\n      <SRS>EPSG:23888</SRS>\n      <SRS>EPSG:23889</SRS>\n      <SRS>EPSG:23890</SRS>\n      <SRS>EPSG:23891</SRS>\n      <SRS>EPSG:23892</SRS>\n      <SRS>EPSG:23893</SRS>\n      <SRS>EPSG:23894</SRS>\n      <SRS>EPSG:23946</SRS>\n      <SRS>EPSG:23947</SRS>\n      <SRS>EPSG:23948</SRS>\n      <SRS>EPSG:24047</SRS>\n      <SRS>EPSG:24048</SRS>\n      <SRS>EPSG:24100</SRS>\n      <SRS>EPSG:24200</SRS>\n      <SRS>EPSG:24305</SRS>\n      <SRS>EPSG:24306</SRS>\n      <SRS>EPSG:24311</SRS>\n      <SRS>EPSG:24312</SRS>\n      <SRS>EPSG:24313</SRS>\n      <SRS>EPSG:24342</SRS>\n      <SRS>EPSG:24343</SRS>\n      <SRS>EPSG:24344</SRS>\n      <SRS>EPSG:24345</SRS>\n      <SRS>EPSG:24346</SRS>\n      <SRS>EPSG:24347</SRS>\n      <SRS>EPSG:24370</SRS>\n      <SRS>EPSG:24371</SRS>\n      <SRS>EPSG:24372</SRS>\n      <SRS>EPSG:24373</SRS>\n      <SRS>EPSG:24374</SRS>\n      <SRS>EPSG:24375</SRS>\n      <SRS>EPSG:24376</SRS>\n      <SRS>EPSG:24377</SRS>\n      <SRS>EPSG:24378</SRS>\n      <SRS>EPSG:24379</SRS>\n      <SRS>EPSG:24380</SRS>\n      <SRS>EPSG:24381</SRS>\n      <SRS>EPSG:24382</SRS>\n      <SRS>EPSG:24383</SRS>\n      <SRS>EPSG:24500</SRS>\n      <SRS>EPSG:24547</SRS>\n      <SRS>EPSG:24548</SRS>\n      <SRS>EPSG:24571</SRS>\n      <SRS>EPSG:24600</SRS>\n      <SRS>EPSG:24718</SRS>\n      <SRS>EPSG:24719</SRS>\n      <SRS>EPSG:24720</SRS>\n      <SRS>EPSG:24817</SRS>\n      <SRS>EPSG:24818</SRS>\n      <SRS>EPSG:24819</SRS>\n      <SRS>EPSG:24820</SRS>\n      <SRS>EPSG:24821</SRS>\n      <SRS>EPSG:24877</SRS>\n      <SRS>EPSG:24878</SRS>\n      <SRS>EPSG:24879</SRS>\n      <SRS>EPSG:24880</SRS>\n      <SRS>EPSG:24881</SRS>\n      <SRS>EPSG:24882</SRS>\n      <SRS>EPSG:24891</SRS>\n      <SRS>EPSG:24892</SRS>\n      <SRS>EPSG:24893</SRS>\n      <SRS>EPSG:25000</SRS>\n      <SRS>EPSG:25231</SRS>\n      <SRS>EPSG:25391</SRS>\n      <SRS>EPSG:25392</SRS>\n      <SRS>EPSG:25393</SRS>\n      <SRS>EPSG:25394</SRS>\n      <SRS>EPSG:25395</SRS>\n      <SRS>EPSG:25700</SRS>\n      <SRS>EPSG:25828</SRS>\n      <SRS>EPSG:25829</SRS>\n      <SRS>EPSG:25830</SRS>\n      <SRS>EPSG:25831</SRS>\n      <SRS>EPSG:25832</SRS>\n      <SRS>EPSG:25833</SRS>\n      <SRS>EPSG:25834</SRS>\n      <SRS>EPSG:25835</SRS>\n      <SRS>EPSG:25836</SRS>\n      <SRS>EPSG:25837</SRS>\n      <SRS>EPSG:25838</SRS>\n      <SRS>EPSG:25884</SRS>\n      <SRS>EPSG:25932</SRS>\n      <SRS>EPSG:26191</SRS>\n      <SRS>EPSG:26192</SRS>\n      <SRS>EPSG:26193</SRS>\n      <SRS>EPSG:26194</SRS>\n      <SRS>EPSG:26195</SRS>\n      <SRS>EPSG:26237</SRS>\n      <SRS>EPSG:26331</SRS>\n      <SRS>EPSG:26332</SRS>\n      <SRS>EPSG:26391</SRS>\n      <SRS>EPSG:26392</SRS>\n      <SRS>EPSG:26393</SRS>\n      <SRS>EPSG:26432</SRS>\n      <SRS>EPSG:26591</SRS>\n      <SRS>EPSG:26592</SRS>\n      <SRS>EPSG:26632</SRS>\n      <SRS>EPSG:26692</SRS>\n      <SRS>EPSG:26701</SRS>\n      <SRS>EPSG:26702</SRS>\n      <SRS>EPSG:26703</SRS>\n      <SRS>EPSG:26704</SRS>\n      <SRS>EPSG:26705</SRS>\n      <SRS>EPSG:26706</SRS>\n      <SRS>EPSG:26707</SRS>\n      <SRS>EPSG:26708</SRS>\n      <SRS>EPSG:26709</SRS>\n      <SRS>EPSG:26710</SRS>\n      <SRS>EPSG:26711</SRS>\n      <SRS>EPSG:26712</SRS>\n      <SRS>EPSG:26713</SRS>\n      <SRS>EPSG:26714</SRS>\n      <SRS>EPSG:26715</SRS>\n      <SRS>EPSG:26716</SRS>\n      <SRS>EPSG:26717</SRS>\n      <SRS>EPSG:26718</SRS>\n      <SRS>EPSG:26719</SRS>\n      <SRS>EPSG:26720</SRS>\n      <SRS>EPSG:26721</SRS>\n      <SRS>EPSG:26722</SRS>\n      <SRS>EPSG:26729</SRS>\n      <SRS>EPSG:26730</SRS>\n      <SRS>EPSG:26731</SRS>\n      <SRS>EPSG:26732</SRS>\n      <SRS>EPSG:26733</SRS>\n      <SRS>EPSG:26734</SRS>\n      <SRS>EPSG:26735</SRS>\n      <SRS>EPSG:26736</SRS>\n      <SRS>EPSG:26737</SRS>\n      <SRS>EPSG:26738</SRS>\n      <SRS>EPSG:26739</SRS>\n      <SRS>EPSG:26740</SRS>\n      <SRS>EPSG:26741</SRS>\n      <SRS>EPSG:26742</SRS>\n      <SRS>EPSG:26743</SRS>\n      <SRS>EPSG:26744</SRS>\n      <SRS>EPSG:26745</SRS>\n      <SRS>EPSG:26746</SRS>\n      <SRS>EPSG:26747</SRS>\n      <SRS>EPSG:26748</SRS>\n      <SRS>EPSG:26749</SRS>\n      <SRS>EPSG:26750</SRS>\n      <SRS>EPSG:26751</SRS>\n      <SRS>EPSG:26752</SRS>\n      <SRS>EPSG:26753</SRS>\n      <SRS>EPSG:26754</SRS>\n      <SRS>EPSG:26755</SRS>\n      <SRS>EPSG:26756</SRS>\n      <SRS>EPSG:26757</SRS>\n      <SRS>EPSG:26758</SRS>\n      <SRS>EPSG:26759</SRS>\n      <SRS>EPSG:26760</SRS>\n      <SRS>EPSG:26766</SRS>\n      <SRS>EPSG:26767</SRS>\n      <SRS>EPSG:26768</SRS>\n      <SRS>EPSG:26769</SRS>\n      <SRS>EPSG:26770</SRS>\n      <SRS>EPSG:26771</SRS>\n      <SRS>EPSG:26772</SRS>\n      <SRS>EPSG:26773</SRS>\n      <SRS>EPSG:26774</SRS>\n      <SRS>EPSG:26775</SRS>\n      <SRS>EPSG:26776</SRS>\n      <SRS>EPSG:26777</SRS>\n      <SRS>EPSG:26778</SRS>\n      <SRS>EPSG:26779</SRS>\n      <SRS>EPSG:26780</SRS>\n      <SRS>EPSG:26781</SRS>\n      <SRS>EPSG:26782</SRS>\n      <SRS>EPSG:26783</SRS>\n      <SRS>EPSG:26784</SRS>\n      <SRS>EPSG:26785</SRS>\n      <SRS>EPSG:26786</SRS>\n      <SRS>EPSG:26787</SRS>\n      <SRS>EPSG:26791</SRS>\n      <SRS>EPSG:26792</SRS>\n      <SRS>EPSG:26793</SRS>\n      <SRS>EPSG:26794</SRS>\n      <SRS>EPSG:26795</SRS>\n      <SRS>EPSG:26796</SRS>\n      <SRS>EPSG:26797</SRS>\n      <SRS>EPSG:26798</SRS>\n      <SRS>EPSG:26799</SRS>\n      <SRS>EPSG:26801</SRS>\n      <SRS>EPSG:26802</SRS>\n      <SRS>EPSG:26803</SRS>\n      <SRS>EPSG:26811</SRS>\n      <SRS>EPSG:26812</SRS>\n      <SRS>EPSG:26813</SRS>\n      <SRS>EPSG:26901</SRS>\n      <SRS>EPSG:26902</SRS>\n      <SRS>EPSG:26903</SRS>\n      <SRS>EPSG:26904</SRS>\n      <SRS>EPSG:26905</SRS>\n      <SRS>EPSG:26906</SRS>\n      <SRS>EPSG:26907</SRS>\n      <SRS>EPSG:26908</SRS>\n      <SRS>EPSG:26909</SRS>\n      <SRS>EPSG:26910</SRS>\n      <SRS>EPSG:26911</SRS>\n      <SRS>EPSG:26912</SRS>\n      <SRS>EPSG:26913</SRS>\n      <SRS>EPSG:26914</SRS>\n      <SRS>EPSG:26915</SRS>\n      <SRS>EPSG:26916</SRS>\n      <SRS>EPSG:26917</SRS>\n      <SRS>EPSG:26918</SRS>\n      <SRS>EPSG:26919</SRS>\n      <SRS>EPSG:26920</SRS>\n      <SRS>EPSG:26921</SRS>\n      <SRS>EPSG:26922</SRS>\n      <SRS>EPSG:26923</SRS>\n      <SRS>EPSG:26929</SRS>\n      <SRS>EPSG:26930</SRS>\n      <SRS>EPSG:26931</SRS>\n      <SRS>EPSG:26932</SRS>\n      <SRS>EPSG:26933</SRS>\n      <SRS>EPSG:26934</SRS>\n      <SRS>EPSG:26935</SRS>\n      <SRS>EPSG:26936</SRS>\n      <SRS>EPSG:26937</SRS>\n      <SRS>EPSG:26938</SRS>\n      <SRS>EPSG:26939</SRS>\n      <SRS>EPSG:26940</SRS>\n      <SRS>EPSG:26941</SRS>\n      <SRS>EPSG:26942</SRS>\n      <SRS>EPSG:26943</SRS>\n      <SRS>EPSG:26944</SRS>\n      <SRS>EPSG:26945</SRS>\n      <SRS>EPSG:26946</SRS>\n      <SRS>EPSG:26948</SRS>\n      <SRS>EPSG:26949</SRS>\n      <SRS>EPSG:26950</SRS>\n      <SRS>EPSG:26951</SRS>\n      <SRS>EPSG:26952</SRS>\n      <SRS>EPSG:26953</SRS>\n      <SRS>EPSG:26954</SRS>\n      <SRS>EPSG:26955</SRS>\n      <SRS>EPSG:26956</SRS>\n      <SRS>EPSG:26957</SRS>\n      <SRS>EPSG:26958</SRS>\n      <SRS>EPSG:26959</SRS>\n      <SRS>EPSG:26960</SRS>\n      <SRS>EPSG:26961</SRS>\n      <SRS>EPSG:26962</SRS>\n      <SRS>EPSG:26963</SRS>\n      <SRS>EPSG:26964</SRS>\n      <SRS>EPSG:26965</SRS>\n      <SRS>EPSG:26966</SRS>\n      <SRS>EPSG:26967</SRS>\n      <SRS>EPSG:26968</SRS>\n      <SRS>EPSG:26969</SRS>\n      <SRS>EPSG:26970</SRS>\n      <SRS>EPSG:26971</SRS>\n      <SRS>EPSG:26972</SRS>\n      <SRS>EPSG:26973</SRS>\n      <SRS>EPSG:26974</SRS>\n      <SRS>EPSG:26975</SRS>\n      <SRS>EPSG:26976</SRS>\n      <SRS>EPSG:26977</SRS>\n      <SRS>EPSG:26978</SRS>\n      <SRS>EPSG:26979</SRS>\n      <SRS>EPSG:26980</SRS>\n      <SRS>EPSG:26981</SRS>\n      <SRS>EPSG:26982</SRS>\n      <SRS>EPSG:26983</SRS>\n      <SRS>EPSG:26984</SRS>\n      <SRS>EPSG:26985</SRS>\n      <SRS>EPSG:26986</SRS>\n      <SRS>EPSG:26987</SRS>\n      <SRS>EPSG:26988</SRS>\n      <SRS>EPSG:26989</SRS>\n      <SRS>EPSG:26990</SRS>\n      <SRS>EPSG:26991</SRS>\n      <SRS>EPSG:26992</SRS>\n      <SRS>EPSG:26993</SRS>\n      <SRS>EPSG:26994</SRS>\n      <SRS>EPSG:26995</SRS>\n      <SRS>EPSG:26996</SRS>\n      <SRS>EPSG:26997</SRS>\n      <SRS>EPSG:26998</SRS>\n      <SRS>EPSG:27037</SRS>\n      <SRS>EPSG:27038</SRS>\n      <SRS>EPSG:27039</SRS>\n      <SRS>EPSG:27040</SRS>\n      <SRS>EPSG:27120</SRS>\n      <SRS>EPSG:27200</SRS>\n      <SRS>EPSG:27205</SRS>\n      <SRS>EPSG:27206</SRS>\n      <SRS>EPSG:27207</SRS>\n      <SRS>EPSG:27208</SRS>\n      <SRS>EPSG:27209</SRS>\n      <SRS>EPSG:27210</SRS>\n      <SRS>EPSG:27211</SRS>\n      <SRS>EPSG:27212</SRS>\n      <SRS>EPSG:27213</SRS>\n      <SRS>EPSG:27214</SRS>\n      <SRS>EPSG:27215</SRS>\n      <SRS>EPSG:27216</SRS>\n      <SRS>EPSG:27217</SRS>\n      <SRS>EPSG:27218</SRS>\n      <SRS>EPSG:27219</SRS>\n      <SRS>EPSG:27220</SRS>\n      <SRS>EPSG:27221</SRS>\n      <SRS>EPSG:27222</SRS>\n      <SRS>EPSG:27223</SRS>\n      <SRS>EPSG:27224</SRS>\n      <SRS>EPSG:27225</SRS>\n      <SRS>EPSG:27226</SRS>\n      <SRS>EPSG:27227</SRS>\n      <SRS>EPSG:27228</SRS>\n      <SRS>EPSG:27229</SRS>\n      <SRS>EPSG:27230</SRS>\n      <SRS>EPSG:27231</SRS>\n      <SRS>EPSG:27232</SRS>\n      <SRS>EPSG:27258</SRS>\n      <SRS>EPSG:27259</SRS>\n      <SRS>EPSG:27260</SRS>\n      <SRS>EPSG:27291</SRS>\n      <SRS>EPSG:27292</SRS>\n      <SRS>EPSG:27391</SRS>\n      <SRS>EPSG:27392</SRS>\n      <SRS>EPSG:27393</SRS>\n      <SRS>EPSG:27394</SRS>\n      <SRS>EPSG:27395</SRS>\n      <SRS>EPSG:27396</SRS>\n      <SRS>EPSG:27397</SRS>\n      <SRS>EPSG:27398</SRS>\n      <SRS>EPSG:27429</SRS>\n      <SRS>EPSG:27492</SRS>\n      <SRS>EPSG:27500</SRS>\n      <SRS>EPSG:27561</SRS>\n      <SRS>EPSG:27562</SRS>\n      <SRS>EPSG:27563</SRS>\n      <SRS>EPSG:27564</SRS>\n      <SRS>EPSG:27571</SRS>\n      <SRS>EPSG:27572</SRS>\n      <SRS>EPSG:27573</SRS>\n      <SRS>EPSG:27574</SRS>\n      <SRS>EPSG:27581</SRS>\n      <SRS>EPSG:27582</SRS>\n      <SRS>EPSG:27583</SRS>\n      <SRS>EPSG:27584</SRS>\n      <SRS>EPSG:27591</SRS>\n      <SRS>EPSG:27592</SRS>\n      <SRS>EPSG:27593</SRS>\n      <SRS>EPSG:27594</SRS>\n      <SRS>EPSG:27700</SRS>\n      <SRS>EPSG:28191</SRS>\n      <SRS>EPSG:28192</SRS>\n      <SRS>EPSG:28193</SRS>\n      <SRS>EPSG:28232</SRS>\n      <SRS>EPSG:28348</SRS>\n      <SRS>EPSG:28349</SRS>\n      <SRS>EPSG:28350</SRS>\n      <SRS>EPSG:28351</SRS>\n      <SRS>EPSG:28352</SRS>\n      <SRS>EPSG:28353</SRS>\n      <SRS>EPSG:28354</SRS>\n      <SRS>EPSG:28355</SRS>\n      <SRS>EPSG:28356</SRS>\n      <SRS>EPSG:28357</SRS>\n      <SRS>EPSG:28358</SRS>\n      <SRS>EPSG:28402</SRS>\n      <SRS>EPSG:28403</SRS>\n      <SRS>EPSG:28404</SRS>\n      <SRS>EPSG:28405</SRS>\n      <SRS>EPSG:28406</SRS>\n      <SRS>EPSG:28407</SRS>\n      <SRS>EPSG:28408</SRS>\n      <SRS>EPSG:28409</SRS>\n      <SRS>EPSG:28410</SRS>\n      <SRS>EPSG:28411</SRS>\n      <SRS>EPSG:28412</SRS>\n      <SRS>EPSG:28413</SRS>\n      <SRS>EPSG:28414</SRS>\n      <SRS>EPSG:28415</SRS>\n      <SRS>EPSG:28416</SRS>\n      <SRS>EPSG:28417</SRS>\n      <SRS>EPSG:28418</SRS>\n      <SRS>EPSG:28419</SRS>\n      <SRS>EPSG:28420</SRS>\n      <SRS>EPSG:28421</SRS>\n      <SRS>EPSG:28422</SRS>\n      <SRS>EPSG:28423</SRS>\n      <SRS>EPSG:28424</SRS>\n      <SRS>EPSG:28425</SRS>\n      <SRS>EPSG:28426</SRS>\n      <SRS>EPSG:28427</SRS>\n      <SRS>EPSG:28428</SRS>\n      <SRS>EPSG:28429</SRS>\n      <SRS>EPSG:28430</SRS>\n      <SRS>EPSG:28431</SRS>\n      <SRS>EPSG:28432</SRS>\n      <SRS>EPSG:28462</SRS>\n      <SRS>EPSG:28463</SRS>\n      <SRS>EPSG:28464</SRS>\n      <SRS>EPSG:28465</SRS>\n      <SRS>EPSG:28466</SRS>\n      <SRS>EPSG:28467</SRS>\n      <SRS>EPSG:28468</SRS>\n      <SRS>EPSG:28469</SRS>\n      <SRS>EPSG:28470</SRS>\n      <SRS>EPSG:28471</SRS>\n      <SRS>EPSG:28472</SRS>\n      <SRS>EPSG:28473</SRS>\n      <SRS>EPSG:28474</SRS>\n      <SRS>EPSG:28475</SRS>\n      <SRS>EPSG:28476</SRS>\n      <SRS>EPSG:28477</SRS>\n      <SRS>EPSG:28478</SRS>\n      <SRS>EPSG:28479</SRS>\n      <SRS>EPSG:28480</SRS>\n      <SRS>EPSG:28481</SRS>\n      <SRS>EPSG:28482</SRS>\n      <SRS>EPSG:28483</SRS>\n      <SRS>EPSG:28484</SRS>\n      <SRS>EPSG:28485</SRS>\n      <SRS>EPSG:28486</SRS>\n      <SRS>EPSG:28487</SRS>\n      <SRS>EPSG:28488</SRS>\n      <SRS>EPSG:28489</SRS>\n      <SRS>EPSG:28490</SRS>\n      <SRS>EPSG:28491</SRS>\n      <SRS>EPSG:28492</SRS>\n      <SRS>EPSG:28600</SRS>\n      <SRS>EPSG:28991</SRS>\n      <SRS>EPSG:28992</SRS>\n      <SRS>EPSG:29100</SRS>\n      <SRS>EPSG:29101</SRS>\n      <SRS>EPSG:29118</SRS>\n      <SRS>EPSG:29119</SRS>\n      <SRS>EPSG:29120</SRS>\n      <SRS>EPSG:29121</SRS>\n      <SRS>EPSG:29122</SRS>\n      <SRS>EPSG:29168</SRS>\n      <SRS>EPSG:29169</SRS>\n      <SRS>EPSG:29170</SRS>\n      <SRS>EPSG:29171</SRS>\n      <SRS>EPSG:29172</SRS>\n      <SRS>EPSG:29177</SRS>\n      <SRS>EPSG:29178</SRS>\n      <SRS>EPSG:29179</SRS>\n      <SRS>EPSG:29180</SRS>\n      <SRS>EPSG:29181</SRS>\n      <SRS>EPSG:29182</SRS>\n      <SRS>EPSG:29183</SRS>\n      <SRS>EPSG:29184</SRS>\n      <SRS>EPSG:29185</SRS>\n      <SRS>EPSG:29187</SRS>\n      <SRS>EPSG:29188</SRS>\n      <SRS>EPSG:29189</SRS>\n      <SRS>EPSG:29190</SRS>\n      <SRS>EPSG:29191</SRS>\n      <SRS>EPSG:29192</SRS>\n      <SRS>EPSG:29193</SRS>\n      <SRS>EPSG:29194</SRS>\n      <SRS>EPSG:29195</SRS>\n      <SRS>EPSG:29220</SRS>\n      <SRS>EPSG:29221</SRS>\n      <SRS>EPSG:29333</SRS>\n      <SRS>EPSG:29371</SRS>\n      <SRS>EPSG:29373</SRS>\n      <SRS>EPSG:29375</SRS>\n      <SRS>EPSG:29377</SRS>\n      <SRS>EPSG:29379</SRS>\n      <SRS>EPSG:29381</SRS>\n      <SRS>EPSG:29383</SRS>\n      <SRS>EPSG:29385</SRS>\n      <SRS>EPSG:29635</SRS>\n      <SRS>EPSG:29636</SRS>\n      <SRS>EPSG:29700</SRS>\n      <SRS>EPSG:29701</SRS>\n      <SRS>EPSG:29702</SRS>\n      <SRS>EPSG:29738</SRS>\n      <SRS>EPSG:29739</SRS>\n      <SRS>EPSG:29849</SRS>\n      <SRS>EPSG:29850</SRS>\n      <SRS>EPSG:29871</SRS>\n      <SRS>EPSG:29872</SRS>\n      <SRS>EPSG:29873</SRS>\n      <SRS>EPSG:29900</SRS>\n      <SRS>EPSG:29901</SRS>\n      <SRS>EPSG:29902</SRS>\n      <SRS>EPSG:29903</SRS>\n      <SRS>EPSG:30161</SRS>\n      <SRS>EPSG:30162</SRS>\n      <SRS>EPSG:30163</SRS>\n      <SRS>EPSG:30164</SRS>\n      <SRS>EPSG:30165</SRS>\n      <SRS>EPSG:30166</SRS>\n      <SRS>EPSG:30167</SRS>\n      <SRS>EPSG:30168</SRS>\n      <SRS>EPSG:30169</SRS>\n      <SRS>EPSG:30170</SRS>\n      <SRS>EPSG:30171</SRS>\n      <SRS>EPSG:30172</SRS>\n      <SRS>EPSG:30173</SRS>\n      <SRS>EPSG:30174</SRS>\n      <SRS>EPSG:30175</SRS>\n      <SRS>EPSG:30176</SRS>\n      <SRS>EPSG:30177</SRS>\n      <SRS>EPSG:30178</SRS>\n      <SRS>EPSG:30179</SRS>\n      <SRS>EPSG:30200</SRS>\n      <SRS>EPSG:30339</SRS>\n      <SRS>EPSG:30340</SRS>\n      <SRS>EPSG:30491</SRS>\n      <SRS>EPSG:30492</SRS>\n      <SRS>EPSG:30493</SRS>\n      <SRS>EPSG:30494</SRS>\n      <SRS>EPSG:30729</SRS>\n      <SRS>EPSG:30730</SRS>\n      <SRS>EPSG:30731</SRS>\n      <SRS>EPSG:30732</SRS>\n      <SRS>EPSG:30791</SRS>\n      <SRS>EPSG:30792</SRS>\n      <SRS>EPSG:30800</SRS>\n      <SRS>EPSG:31028</SRS>\n      <SRS>EPSG:31121</SRS>\n      <SRS>EPSG:31154</SRS>\n      <SRS>EPSG:31170</SRS>\n      <SRS>EPSG:31171</SRS>\n      <SRS>EPSG:31251</SRS>\n      <SRS>EPSG:31252</SRS>\n      <SRS>EPSG:31253</SRS>\n      <SRS>EPSG:31254</SRS>\n      <SRS>EPSG:31255</SRS>\n      <SRS>EPSG:31256</SRS>\n      <SRS>EPSG:31257</SRS>\n      <SRS>EPSG:31258</SRS>\n      <SRS>EPSG:31259</SRS>\n      <SRS>EPSG:31265</SRS>\n      <SRS>EPSG:31266</SRS>\n      <SRS>EPSG:31267</SRS>\n      <SRS>EPSG:31268</SRS>\n      <SRS>EPSG:31275</SRS>\n      <SRS>EPSG:31276</SRS>\n      <SRS>EPSG:31277</SRS>\n      <SRS>EPSG:31278</SRS>\n      <SRS>EPSG:31279</SRS>\n      <SRS>EPSG:31281</SRS>\n      <SRS>EPSG:31282</SRS>\n      <SRS>EPSG:31283</SRS>\n      <SRS>EPSG:31284</SRS>\n      <SRS>EPSG:31285</SRS>\n      <SRS>EPSG:31286</SRS>\n      <SRS>EPSG:31287</SRS>\n      <SRS>EPSG:31288</SRS>\n      <SRS>EPSG:31289</SRS>\n      <SRS>EPSG:31290</SRS>\n      <SRS>EPSG:31291</SRS>\n      <SRS>EPSG:31292</SRS>\n      <SRS>EPSG:31293</SRS>\n      <SRS>EPSG:31294</SRS>\n      <SRS>EPSG:31295</SRS>\n      <SRS>EPSG:31296</SRS>\n      <SRS>EPSG:31297</SRS>\n      <SRS>EPSG:31300</SRS>\n      <SRS>EPSG:31370</SRS>\n      <SRS>EPSG:31461</SRS>\n      <SRS>EPSG:31462</SRS>\n      <SRS>EPSG:31463</SRS>\n      <SRS>EPSG:31464</SRS>\n      <SRS>EPSG:31465</SRS>\n      <SRS>EPSG:31466</SRS>\n      <SRS>EPSG:31467</SRS>\n      <SRS>EPSG:31468</SRS>\n      <SRS>EPSG:31469</SRS>\n      <SRS>EPSG:31528</SRS>\n      <SRS>EPSG:31529</SRS>\n      <SRS>EPSG:31600</SRS>\n      <SRS>EPSG:31700</SRS>\n      <SRS>EPSG:31838</SRS>\n      <SRS>EPSG:31839</SRS>\n      <SRS>EPSG:31900</SRS>\n      <SRS>EPSG:31901</SRS>\n      <SRS>EPSG:31965</SRS>\n      <SRS>EPSG:31966</SRS>\n      <SRS>EPSG:31967</SRS>\n      <SRS>EPSG:31968</SRS>\n      <SRS>EPSG:31969</SRS>\n      <SRS>EPSG:31970</SRS>\n      <SRS>EPSG:31971</SRS>\n      <SRS>EPSG:31972</SRS>\n      <SRS>EPSG:31973</SRS>\n      <SRS>EPSG:31974</SRS>\n      <SRS>EPSG:31975</SRS>\n      <SRS>EPSG:31976</SRS>\n      <SRS>EPSG:31977</SRS>\n      <SRS>EPSG:31978</SRS>\n      <SRS>EPSG:31979</SRS>\n      <SRS>EPSG:31980</SRS>\n      <SRS>EPSG:31981</SRS>\n      <SRS>EPSG:31982</SRS>\n      <SRS>EPSG:31983</SRS>\n      <SRS>EPSG:31984</SRS>\n      <SRS>EPSG:31985</SRS>\n      <SRS>EPSG:31986</SRS>\n      <SRS>EPSG:31987</SRS>\n      <SRS>EPSG:31988</SRS>\n      <SRS>EPSG:31989</SRS>\n      <SRS>EPSG:31990</SRS>\n      <SRS>EPSG:31991</SRS>\n      <SRS>EPSG:31992</SRS>\n      <SRS>EPSG:31993</SRS>\n      <SRS>EPSG:31994</SRS>\n      <SRS>EPSG:31995</SRS>\n      <SRS>EPSG:31996</SRS>\n      <SRS>EPSG:31997</SRS>\n      <SRS>EPSG:31998</SRS>\n      <SRS>EPSG:31999</SRS>\n      <SRS>EPSG:32000</SRS>\n      <SRS>EPSG:32001</SRS>\n      <SRS>EPSG:32002</SRS>\n      <SRS>EPSG:32003</SRS>\n      <SRS>EPSG:32005</SRS>\n      <SRS>EPSG:32006</SRS>\n      <SRS>EPSG:32007</SRS>\n      <SRS>EPSG:32008</SRS>\n      <SRS>EPSG:32009</SRS>\n      <SRS>EPSG:32010</SRS>\n      <SRS>EPSG:32011</SRS>\n      <SRS>EPSG:32012</SRS>\n      <SRS>EPSG:32013</SRS>\n      <SRS>EPSG:32014</SRS>\n      <SRS>EPSG:32015</SRS>\n      <SRS>EPSG:32016</SRS>\n      <SRS>EPSG:32017</SRS>\n      <SRS>EPSG:32018</SRS>\n      <SRS>EPSG:32019</SRS>\n      <SRS>EPSG:32020</SRS>\n      <SRS>EPSG:32021</SRS>\n      <SRS>EPSG:32022</SRS>\n      <SRS>EPSG:32023</SRS>\n      <SRS>EPSG:32024</SRS>\n      <SRS>EPSG:32025</SRS>\n      <SRS>EPSG:32026</SRS>\n      <SRS>EPSG:32027</SRS>\n      <SRS>EPSG:32028</SRS>\n      <SRS>EPSG:32029</SRS>\n      <SRS>EPSG:32030</SRS>\n      <SRS>EPSG:32031</SRS>\n      <SRS>EPSG:32033</SRS>\n      <SRS>EPSG:32034</SRS>\n      <SRS>EPSG:32035</SRS>\n      <SRS>EPSG:32036</SRS>\n      <SRS>EPSG:32037</SRS>\n      <SRS>EPSG:32038</SRS>\n      <SRS>EPSG:32039</SRS>\n      <SRS>EPSG:32040</SRS>\n      <SRS>EPSG:32041</SRS>\n      <SRS>EPSG:32042</SRS>\n      <SRS>EPSG:32043</SRS>\n      <SRS>EPSG:32044</SRS>\n      <SRS>EPSG:32045</SRS>\n      <SRS>EPSG:32046</SRS>\n      <SRS>EPSG:32047</SRS>\n      <SRS>EPSG:32048</SRS>\n      <SRS>EPSG:32049</SRS>\n      <SRS>EPSG:32050</SRS>\n      <SRS>EPSG:32051</SRS>\n      <SRS>EPSG:32052</SRS>\n      <SRS>EPSG:32053</SRS>\n      <SRS>EPSG:32054</SRS>\n      <SRS>EPSG:32055</SRS>\n      <SRS>EPSG:32056</SRS>\n      <SRS>EPSG:32057</SRS>\n      <SRS>EPSG:32058</SRS>\n      <SRS>EPSG:32061</SRS>\n      <SRS>EPSG:32062</SRS>\n      <SRS>EPSG:32064</SRS>\n      <SRS>EPSG:32065</SRS>\n      <SRS>EPSG:32066</SRS>\n      <SRS>EPSG:32067</SRS>\n      <SRS>EPSG:32074</SRS>\n      <SRS>EPSG:32075</SRS>\n      <SRS>EPSG:32076</SRS>\n      <SRS>EPSG:32077</SRS>\n      <SRS>EPSG:32081</SRS>\n      <SRS>EPSG:32082</SRS>\n      <SRS>EPSG:32083</SRS>\n      <SRS>EPSG:32084</SRS>\n      <SRS>EPSG:32085</SRS>\n      <SRS>EPSG:32086</SRS>\n      <SRS>EPSG:32098</SRS>\n      <SRS>EPSG:32099</SRS>\n      <SRS>EPSG:32100</SRS>\n      <SRS>EPSG:32104</SRS>\n      <SRS>EPSG:32107</SRS>\n      <SRS>EPSG:32108</SRS>\n      <SRS>EPSG:32109</SRS>\n      <SRS>EPSG:32110</SRS>\n      <SRS>EPSG:32111</SRS>\n      <SRS>EPSG:32112</SRS>\n      <SRS>EPSG:32113</SRS>\n      <SRS>EPSG:32114</SRS>\n      <SRS>EPSG:32115</SRS>\n      <SRS>EPSG:32116</SRS>\n      <SRS>EPSG:32117</SRS>\n      <SRS>EPSG:32118</SRS>\n      <SRS>EPSG:32119</SRS>\n      <SRS>EPSG:32120</SRS>\n      <SRS>EPSG:32121</SRS>\n      <SRS>EPSG:32122</SRS>\n      <SRS>EPSG:32123</SRS>\n      <SRS>EPSG:32124</SRS>\n      <SRS>EPSG:32125</SRS>\n      <SRS>EPSG:32126</SRS>\n      <SRS>EPSG:32127</SRS>\n      <SRS>EPSG:32128</SRS>\n      <SRS>EPSG:32129</SRS>\n      <SRS>EPSG:32130</SRS>\n      <SRS>EPSG:32133</SRS>\n      <SRS>EPSG:32134</SRS>\n      <SRS>EPSG:32135</SRS>\n      <SRS>EPSG:32136</SRS>\n      <SRS>EPSG:32137</SRS>\n      <SRS>EPSG:32138</SRS>\n      <SRS>EPSG:32139</SRS>\n      <SRS>EPSG:32140</SRS>\n      <SRS>EPSG:32141</SRS>\n      <SRS>EPSG:32142</SRS>\n      <SRS>EPSG:32143</SRS>\n      <SRS>EPSG:32144</SRS>\n      <SRS>EPSG:32145</SRS>\n      <SRS>EPSG:32146</SRS>\n      <SRS>EPSG:32147</SRS>\n      <SRS>EPSG:32148</SRS>\n      <SRS>EPSG:32149</SRS>\n      <SRS>EPSG:32150</SRS>\n      <SRS>EPSG:32151</SRS>\n      <SRS>EPSG:32152</SRS>\n      <SRS>EPSG:32153</SRS>\n      <SRS>EPSG:32154</SRS>\n      <SRS>EPSG:32155</SRS>\n      <SRS>EPSG:32156</SRS>\n      <SRS>EPSG:32157</SRS>\n      <SRS>EPSG:32158</SRS>\n      <SRS>EPSG:32161</SRS>\n      <SRS>EPSG:32164</SRS>\n      <SRS>EPSG:32165</SRS>\n      <SRS>EPSG:32166</SRS>\n      <SRS>EPSG:32167</SRS>\n      <SRS>EPSG:32180</SRS>\n      <SRS>EPSG:32181</SRS>\n      <SRS>EPSG:32182</SRS>\n      <SRS>EPSG:32183</SRS>\n      <SRS>EPSG:32184</SRS>\n      <SRS>EPSG:32185</SRS>\n      <SRS>EPSG:32186</SRS>\n      <SRS>EPSG:32187</SRS>\n      <SRS>EPSG:32188</SRS>\n      <SRS>EPSG:32189</SRS>\n      <SRS>EPSG:32190</SRS>\n      <SRS>EPSG:32191</SRS>\n      <SRS>EPSG:32192</SRS>\n      <SRS>EPSG:32193</SRS>\n      <SRS>EPSG:32194</SRS>\n      <SRS>EPSG:32195</SRS>\n      <SRS>EPSG:32196</SRS>\n      <SRS>EPSG:32197</SRS>\n      <SRS>EPSG:32198</SRS>\n      <SRS>EPSG:32199</SRS>\n      <SRS>EPSG:32201</SRS>\n      <SRS>EPSG:32202</SRS>\n      <SRS>EPSG:32203</SRS>\n      <SRS>EPSG:32204</SRS>\n      <SRS>EPSG:32205</SRS>\n      <SRS>EPSG:32206</SRS>\n      <SRS>EPSG:32207</SRS>\n      <SRS>EPSG:32208</SRS>\n      <SRS>EPSG:32209</SRS>\n      <SRS>EPSG:32210</SRS>\n      <SRS>EPSG:32211</SRS>\n      <SRS>EPSG:32212</SRS>\n      <SRS>EPSG:32213</SRS>\n      <SRS>EPSG:32214</SRS>\n      <SRS>EPSG:32215</SRS>\n      <SRS>EPSG:32216</SRS>\n      <SRS>EPSG:32217</SRS>\n      <SRS>EPSG:32218</SRS>\n      <SRS>EPSG:32219</SRS>\n      <SRS>EPSG:32220</SRS>\n      <SRS>EPSG:32221</SRS>\n      <SRS>EPSG:32222</SRS>\n      <SRS>EPSG:32223</SRS>\n      <SRS>EPSG:32224</SRS>\n      <SRS>EPSG:32225</SRS>\n      <SRS>EPSG:32226</SRS>\n      <SRS>EPSG:32227</SRS>\n      <SRS>EPSG:32228</SRS>\n      <SRS>EPSG:32229</SRS>\n      <SRS>EPSG:32230</SRS>\n      <SRS>EPSG:32231</SRS>\n      <SRS>EPSG:32232</SRS>\n      <SRS>EPSG:32233</SRS>\n      <SRS>EPSG:32234</SRS>\n      <SRS>EPSG:32235</SRS>\n      <SRS>EPSG:32236</SRS>\n      <SRS>EPSG:32237</SRS>\n      <SRS>EPSG:32238</SRS>\n      <SRS>EPSG:32239</SRS>\n      <SRS>EPSG:32240</SRS>\n      <SRS>EPSG:32241</SRS>\n      <SRS>EPSG:32242</SRS>\n      <SRS>EPSG:32243</SRS>\n      <SRS>EPSG:32244</SRS>\n      <SRS>EPSG:32245</SRS>\n      <SRS>EPSG:32246</SRS>\n      <SRS>EPSG:32247</SRS>\n      <SRS>EPSG:32248</SRS>\n      <SRS>EPSG:32249</SRS>\n      <SRS>EPSG:32250</SRS>\n      <SRS>EPSG:32251</SRS>\n      <SRS>EPSG:32252</SRS>\n      <SRS>EPSG:32253</SRS>\n      <SRS>EPSG:32254</SRS>\n      <SRS>EPSG:32255</SRS>\n      <SRS>EPSG:32256</SRS>\n      <SRS>EPSG:32257</SRS>\n      <SRS>EPSG:32258</SRS>\n      <SRS>EPSG:32259</SRS>\n      <SRS>EPSG:32260</SRS>\n      <SRS>EPSG:32301</SRS>\n      <SRS>EPSG:32302</SRS>\n      <SRS>EPSG:32303</SRS>\n      <SRS>EPSG:32304</SRS>\n      <SRS>EPSG:32305</SRS>\n      <SRS>EPSG:32306</SRS>\n      <SRS>EPSG:32307</SRS>\n      <SRS>EPSG:32308</SRS>\n      <SRS>EPSG:32309</SRS>\n      <SRS>EPSG:32310</SRS>\n      <SRS>EPSG:32311</SRS>\n      <SRS>EPSG:32312</SRS>\n      <SRS>EPSG:32313</SRS>\n      <SRS>EPSG:32314</SRS>\n      <SRS>EPSG:32315</SRS>\n      <SRS>EPSG:32316</SRS>\n      <SRS>EPSG:32317</SRS>\n      <SRS>EPSG:32318</SRS>\n      <SRS>EPSG:32319</SRS>\n      <SRS>EPSG:32320</SRS>\n      <SRS>EPSG:32321</SRS>\n      <SRS>EPSG:32322</SRS>\n      <SRS>EPSG:32323</SRS>\n      <SRS>EPSG:32324</SRS>\n      <SRS>EPSG:32325</SRS>\n      <SRS>EPSG:32326</SRS>\n      <SRS>EPSG:32327</SRS>\n      <SRS>EPSG:32328</SRS>\n      <SRS>EPSG:32329</SRS>\n      <SRS>EPSG:32330</SRS>\n      <SRS>EPSG:32331</SRS>\n      <SRS>EPSG:32332</SRS>\n      <SRS>EPSG:32333</SRS>\n      <SRS>EPSG:32334</SRS>\n      <SRS>EPSG:32335</SRS>\n      <SRS>EPSG:32336</SRS>\n      <SRS>EPSG:32337</SRS>\n      <SRS>EPSG:32338</SRS>\n      <SRS>EPSG:32339</SRS>\n      <SRS>EPSG:32340</SRS>\n      <SRS>EPSG:32341</SRS>\n      <SRS>EPSG:32342</SRS>\n      <SRS>EPSG:32343</SRS>\n      <SRS>EPSG:32344</SRS>\n      <SRS>EPSG:32345</SRS>\n      <SRS>EPSG:32346</SRS>\n      <SRS>EPSG:32347</SRS>\n      <SRS>EPSG:32348</SRS>\n      <SRS>EPSG:32349</SRS>\n      <SRS>EPSG:32350</SRS>\n      <SRS>EPSG:32351</SRS>\n      <SRS>EPSG:32352</SRS>\n      <SRS>EPSG:32353</SRS>\n      <SRS>EPSG:32354</SRS>\n      <SRS>EPSG:32355</SRS>\n      <SRS>EPSG:32356</SRS>\n      <SRS>EPSG:32357</SRS>\n      <SRS>EPSG:32358</SRS>\n      <SRS>EPSG:32359</SRS>\n      <SRS>EPSG:32360</SRS>\n      <SRS>EPSG:32401</SRS>\n      <SRS>EPSG:32402</SRS>\n      <SRS>EPSG:32403</SRS>\n      <SRS>EPSG:32404</SRS>\n      <SRS>EPSG:32405</SRS>\n      <SRS>EPSG:32406</SRS>\n      <SRS>EPSG:32407</SRS>\n      <SRS>EPSG:32408</SRS>\n      <SRS>EPSG:32409</SRS>\n      <SRS>EPSG:32410</SRS>\n      <SRS>EPSG:32411</SRS>\n      <SRS>EPSG:32412</SRS>\n      <SRS>EPSG:32413</SRS>\n      <SRS>EPSG:32414</SRS>\n      <SRS>EPSG:32415</SRS>\n      <SRS>EPSG:32416</SRS>\n      <SRS>EPSG:32417</SRS>\n      <SRS>EPSG:32418</SRS>\n      <SRS>EPSG:32419</SRS>\n      <SRS>EPSG:32420</SRS>\n      <SRS>EPSG:32421</SRS>\n      <SRS>EPSG:32422</SRS>\n      <SRS>EPSG:32423</SRS>\n      <SRS>EPSG:32424</SRS>\n      <SRS>EPSG:32425</SRS>\n      <SRS>EPSG:32426</SRS>\n      <SRS>EPSG:32427</SRS>\n      <SRS>EPSG:32428</SRS>\n      <SRS>EPSG:32429</SRS>\n      <SRS>EPSG:32430</SRS>\n      <SRS>EPSG:32431</SRS>\n      <SRS>EPSG:32432</SRS>\n      <SRS>EPSG:32433</SRS>\n      <SRS>EPSG:32434</SRS>\n      <SRS>EPSG:32435</SRS>\n      <SRS>EPSG:32436</SRS>\n      <SRS>EPSG:32437</SRS>\n      <SRS>EPSG:32438</SRS>\n      <SRS>EPSG:32439</SRS>\n      <SRS>EPSG:32440</SRS>\n      <SRS>EPSG:32441</SRS>\n      <SRS>EPSG:32442</SRS>\n      <SRS>EPSG:32443</SRS>\n      <SRS>EPSG:32444</SRS>\n      <SRS>EPSG:32445</SRS>\n      <SRS>EPSG:32446</SRS>\n      <SRS>EPSG:32447</SRS>\n      <SRS>EPSG:32448</SRS>\n      <SRS>EPSG:32449</SRS>\n      <SRS>EPSG:32450</SRS>\n      <SRS>EPSG:32451</SRS>\n      <SRS>EPSG:32452</SRS>\n      <SRS>EPSG:32453</SRS>\n      <SRS>EPSG:32454</SRS>\n      <SRS>EPSG:32455</SRS>\n      <SRS>EPSG:32456</SRS>\n      <SRS>EPSG:32457</SRS>\n      <SRS>EPSG:32458</SRS>\n      <SRS>EPSG:32459</SRS>\n      <SRS>EPSG:32460</SRS>\n      <SRS>EPSG:32501</SRS>\n      <SRS>EPSG:32502</SRS>\n      <SRS>EPSG:32503</SRS>\n      <SRS>EPSG:32504</SRS>\n      <SRS>EPSG:32505</SRS>\n      <SRS>EPSG:32506</SRS>\n      <SRS>EPSG:32507</SRS>\n      <SRS>EPSG:32508</SRS>\n      <SRS>EPSG:32509</SRS>\n      <SRS>EPSG:32510</SRS>\n      <SRS>EPSG:32511</SRS>\n      <SRS>EPSG:32512</SRS>\n      <SRS>EPSG:32513</SRS>\n      <SRS>EPSG:32514</SRS>\n      <SRS>EPSG:32515</SRS>\n      <SRS>EPSG:32516</SRS>\n      <SRS>EPSG:32517</SRS>\n      <SRS>EPSG:32518</SRS>\n      <SRS>EPSG:32519</SRS>\n      <SRS>EPSG:32520</SRS>\n      <SRS>EPSG:32521</SRS>\n      <SRS>EPSG:32522</SRS>\n      <SRS>EPSG:32523</SRS>\n      <SRS>EPSG:32524</SRS>\n      <SRS>EPSG:32525</SRS>\n      <SRS>EPSG:32526</SRS>\n      <SRS>EPSG:32527</SRS>\n      <SRS>EPSG:32528</SRS>\n      <SRS>EPSG:32529</SRS>\n      <SRS>EPSG:32530</SRS>\n      <SRS>EPSG:32531</SRS>\n      <SRS>EPSG:32532</SRS>\n      <SRS>EPSG:32533</SRS>\n      <SRS>EPSG:32534</SRS>\n      <SRS>EPSG:32535</SRS>\n      <SRS>EPSG:32536</SRS>\n      <SRS>EPSG:32537</SRS>\n      <SRS>EPSG:32538</SRS>\n      <SRS>EPSG:32539</SRS>\n      <SRS>EPSG:32540</SRS>\n      <SRS>EPSG:32541</SRS>\n      <SRS>EPSG:32542</SRS>\n      <SRS>EPSG:32543</SRS>\n      <SRS>EPSG:32544</SRS>\n      <SRS>EPSG:32545</SRS>\n      <SRS>EPSG:32546</SRS>\n      <SRS>EPSG:32547</SRS>\n      <SRS>EPSG:32548</SRS>\n      <SRS>EPSG:32549</SRS>\n      <SRS>EPSG:32550</SRS>\n      <SRS>EPSG:32551</SRS>\n      <SRS>EPSG:32552</SRS>\n      <SRS>EPSG:32553</SRS>\n      <SRS>EPSG:32554</SRS>\n      <SRS>EPSG:32555</SRS>\n      <SRS>EPSG:32556</SRS>\n      <SRS>EPSG:32557</SRS>\n      <SRS>EPSG:32558</SRS>\n      <SRS>EPSG:32559</SRS>\n      <SRS>EPSG:32560</SRS>\n      <SRS>EPSG:32600</SRS>\n      <SRS>EPSG:32601</SRS>\n      <SRS>EPSG:32602</SRS>\n      <SRS>EPSG:32603</SRS>\n      <SRS>EPSG:32604</SRS>\n      <SRS>EPSG:32605</SRS>\n      <SRS>EPSG:32606</SRS>\n      <SRS>EPSG:32607</SRS>\n      <SRS>EPSG:32608</SRS>\n      <SRS>EPSG:32609</SRS>\n      <SRS>EPSG:32610</SRS>\n      <SRS>EPSG:32611</SRS>\n      <SRS>EPSG:32612</SRS>\n      <SRS>EPSG:32613</SRS>\n      <SRS>EPSG:32614</SRS>\n      <SRS>EPSG:32615</SRS>\n      <SRS>EPSG:32616</SRS>\n      <SRS>EPSG:32617</SRS>\n      <SRS>EPSG:32618</SRS>\n      <SRS>EPSG:32619</SRS>\n      <SRS>EPSG:32620</SRS>\n      <SRS>EPSG:32621</SRS>\n      <SRS>EPSG:32622</SRS>\n      <SRS>EPSG:32623</SRS>\n      <SRS>EPSG:32624</SRS>\n      <SRS>EPSG:32625</SRS>\n      <SRS>EPSG:32626</SRS>\n      <SRS>EPSG:32627</SRS>\n      <SRS>EPSG:32628</SRS>\n      <SRS>EPSG:32629</SRS>\n      <SRS>EPSG:32630</SRS>\n      <SRS>EPSG:32631</SRS>\n      <SRS>EPSG:32632</SRS>\n      <SRS>EPSG:32633</SRS>\n      <SRS>EPSG:32634</SRS>\n      <SRS>EPSG:32635</SRS>\n      <SRS>EPSG:32636</SRS>\n      <SRS>EPSG:32637</SRS>\n      <SRS>EPSG:32638</SRS>\n      <SRS>EPSG:32639</SRS>\n      <SRS>EPSG:32640</SRS>\n      <SRS>EPSG:32641</SRS>\n      <SRS>EPSG:32642</SRS>\n      <SRS>EPSG:32643</SRS>\n      <SRS>EPSG:32644</SRS>\n      <SRS>EPSG:32645</SRS>\n      <SRS>EPSG:32646</SRS>\n      <SRS>EPSG:32647</SRS>\n      <SRS>EPSG:32648</SRS>\n      <SRS>EPSG:32649</SRS>\n      <SRS>EPSG:32650</SRS>\n      <SRS>EPSG:32651</SRS>\n      <SRS>EPSG:32652</SRS>\n      <SRS>EPSG:32653</SRS>\n      <SRS>EPSG:32654</SRS>\n      <SRS>EPSG:32655</SRS>\n      <SRS>EPSG:32656</SRS>\n      <SRS>EPSG:32657</SRS>\n      <SRS>EPSG:32658</SRS>\n      <SRS>EPSG:32659</SRS>\n      <SRS>EPSG:32660</SRS>\n      <SRS>EPSG:32661</SRS>\n      <SRS>EPSG:32662</SRS>\n      <SRS>EPSG:32664</SRS>\n      <SRS>EPSG:32665</SRS>\n      <SRS>EPSG:32666</SRS>\n      <SRS>EPSG:32667</SRS>\n      <SRS>EPSG:32700</SRS>\n      <SRS>EPSG:32701</SRS>\n      <SRS>EPSG:32702</SRS>\n      <SRS>EPSG:32703</SRS>\n      <SRS>EPSG:32704</SRS>\n      <SRS>EPSG:32705</SRS>\n      <SRS>EPSG:32706</SRS>\n      <SRS>EPSG:32707</SRS>\n      <SRS>EPSG:32708</SRS>\n      <SRS>EPSG:32709</SRS>\n      <SRS>EPSG:32710</SRS>\n      <SRS>EPSG:32711</SRS>\n      <SRS>EPSG:32712</SRS>\n      <SRS>EPSG:32713</SRS>\n      <SRS>EPSG:32714</SRS>\n      <SRS>EPSG:32715</SRS>\n      <SRS>EPSG:32716</SRS>\n      <SRS>EPSG:32717</SRS>\n      <SRS>EPSG:32718</SRS>\n      <SRS>EPSG:32719</SRS>\n      <SRS>EPSG:32720</SRS>\n      <SRS>EPSG:32721</SRS>\n      <SRS>EPSG:32722</SRS>\n      <SRS>EPSG:32723</SRS>\n      <SRS>EPSG:32724</SRS>\n      <SRS>EPSG:32725</SRS>\n      <SRS>EPSG:32726</SRS>\n      <SRS>EPSG:32727</SRS>\n      <SRS>EPSG:32728</SRS>\n      <SRS>EPSG:32729</SRS>\n      <SRS>EPSG:32730</SRS>\n      <SRS>EPSG:32731</SRS>\n      <SRS>EPSG:32732</SRS>\n      <SRS>EPSG:32733</SRS>\n      <SRS>EPSG:32734</SRS>\n      <SRS>EPSG:32735</SRS>\n      <SRS>EPSG:32736</SRS>\n      <SRS>EPSG:32737</SRS>\n      <SRS>EPSG:32738</SRS>\n      <SRS>EPSG:32739</SRS>\n      <SRS>EPSG:32740</SRS>\n      <SRS>EPSG:32741</SRS>\n      <SRS>EPSG:32742</SRS>\n      <SRS>EPSG:32743</SRS>\n      <SRS>EPSG:32744</SRS>\n      <SRS>EPSG:32745</SRS>\n      <SRS>EPSG:32746</SRS>\n      <SRS>EPSG:32747</SRS>\n      <SRS>EPSG:32748</SRS>\n      <SRS>EPSG:32749</SRS>\n      <SRS>EPSG:32750</SRS>\n      <SRS>EPSG:32751</SRS>\n      <SRS>EPSG:32752</SRS>\n      <SRS>EPSG:32753</SRS>\n      <SRS>EPSG:32754</SRS>\n      <SRS>EPSG:32755</SRS>\n      <SRS>EPSG:32756</SRS>\n      <SRS>EPSG:32757</SRS>\n      <SRS>EPSG:32758</SRS>\n      <SRS>EPSG:32759</SRS>\n      <SRS>EPSG:32760</SRS>\n      <SRS>EPSG:32761</SRS>\n      <SRS>EPSG:32766</SRS>\n      <SRS>EPSG:61206405</SRS>\n      <SRS>EPSG:61216405</SRS>\n      <SRS>EPSG:61226405</SRS>\n      <SRS>EPSG:61236405</SRS>\n      <SRS>EPSG:61246405</SRS>\n      <SRS>EPSG:61266405</SRS>\n      <SRS>EPSG:61266413</SRS>\n      <SRS>EPSG:61276405</SRS>\n      <SRS>EPSG:61286405</SRS>\n      <SRS>EPSG:61296405</SRS>\n      <SRS>EPSG:61306405</SRS>\n      <SRS>EPSG:61306413</SRS>\n      <SRS>EPSG:61316405</SRS>\n      <SRS>EPSG:61326405</SRS>\n      <SRS>EPSG:61336405</SRS>\n      <SRS>EPSG:61346405</SRS>\n      <SRS>EPSG:61356405</SRS>\n      <SRS>EPSG:61366405</SRS>\n      <SRS>EPSG:61376405</SRS>\n      <SRS>EPSG:61386405</SRS>\n      <SRS>EPSG:61396405</SRS>\n      <SRS>EPSG:61406405</SRS>\n      <SRS>EPSG:61406413</SRS>\n      <SRS>EPSG:61416405</SRS>\n      <SRS>EPSG:61426405</SRS>\n      <SRS>EPSG:61436405</SRS>\n      <SRS>EPSG:61446405</SRS>\n      <SRS>EPSG:61456405</SRS>\n      <SRS>EPSG:61466405</SRS>\n      <SRS>EPSG:61476405</SRS>\n      <SRS>EPSG:61486405</SRS>\n      <SRS>EPSG:61486413</SRS>\n      <SRS>EPSG:61496405</SRS>\n      <SRS>EPSG:61506405</SRS>\n      <SRS>EPSG:61516405</SRS>\n      <SRS>EPSG:61516413</SRS>\n      <SRS>EPSG:61526405</SRS>\n      <SRS>EPSG:61526413</SRS>\n      <SRS>EPSG:61536405</SRS>\n      <SRS>EPSG:61546405</SRS>\n      <SRS>EPSG:61556405</SRS>\n      <SRS>EPSG:61566405</SRS>\n      <SRS>EPSG:61576405</SRS>\n      <SRS>EPSG:61586405</SRS>\n      <SRS>EPSG:61596405</SRS>\n      <SRS>EPSG:61606405</SRS>\n      <SRS>EPSG:61616405</SRS>\n      <SRS>EPSG:61626405</SRS>\n      <SRS>EPSG:61636405</SRS>\n      <SRS>EPSG:61636413</SRS>\n      <SRS>EPSG:61646405</SRS>\n      <SRS>EPSG:61656405</SRS>\n      <SRS>EPSG:61666405</SRS>\n      <SRS>EPSG:61676405</SRS>\n      <SRS>EPSG:61676413</SRS>\n      <SRS>EPSG:61686405</SRS>\n      <SRS>EPSG:61696405</SRS>\n      <SRS>EPSG:61706405</SRS>\n      <SRS>EPSG:61706413</SRS>\n      <SRS>EPSG:61716405</SRS>\n      <SRS>EPSG:61716413</SRS>\n      <SRS>EPSG:61736405</SRS>\n      <SRS>EPSG:61736413</SRS>\n      <SRS>EPSG:61746405</SRS>\n      <SRS>EPSG:61756405</SRS>\n      <SRS>EPSG:61766405</SRS>\n      <SRS>EPSG:61766413</SRS>\n      <SRS>EPSG:61786405</SRS>\n      <SRS>EPSG:61796405</SRS>\n      <SRS>EPSG:61806405</SRS>\n      <SRS>EPSG:61806413</SRS>\n      <SRS>EPSG:61816405</SRS>\n      <SRS>EPSG:61826405</SRS>\n      <SRS>EPSG:61836405</SRS>\n      <SRS>EPSG:61846405</SRS>\n      <SRS>EPSG:61886405</SRS>\n      <SRS>EPSG:61896405</SRS>\n      <SRS>EPSG:61896413</SRS>\n      <SRS>EPSG:61906405</SRS>\n      <SRS>EPSG:61906413</SRS>\n      <SRS>EPSG:61916405</SRS>\n      <SRS>EPSG:61926405</SRS>\n      <SRS>EPSG:61936405</SRS>\n      <SRS>EPSG:61946405</SRS>\n      <SRS>EPSG:61956405</SRS>\n      <SRS>EPSG:61966405</SRS>\n      <SRS>EPSG:61976405</SRS>\n      <SRS>EPSG:61986405</SRS>\n      <SRS>EPSG:61996405</SRS>\n      <SRS>EPSG:62006405</SRS>\n      <SRS>EPSG:62016405</SRS>\n      <SRS>EPSG:62026405</SRS>\n      <SRS>EPSG:62036405</SRS>\n      <SRS>EPSG:62046405</SRS>\n      <SRS>EPSG:62056405</SRS>\n      <SRS>EPSG:62066405</SRS>\n      <SRS>EPSG:62076405</SRS>\n      <SRS>EPSG:62086405</SRS>\n      <SRS>EPSG:62096405</SRS>\n      <SRS>EPSG:62106405</SRS>\n      <SRS>EPSG:62116405</SRS>\n      <SRS>EPSG:62126405</SRS>\n      <SRS>EPSG:62136405</SRS>\n      <SRS>EPSG:62146405</SRS>\n      <SRS>EPSG:62156405</SRS>\n      <SRS>EPSG:62166405</SRS>\n      <SRS>EPSG:62186405</SRS>\n      <SRS>EPSG:62196405</SRS>\n      <SRS>EPSG:62206405</SRS>\n      <SRS>EPSG:62216405</SRS>\n      <SRS>EPSG:62226405</SRS>\n      <SRS>EPSG:62236405</SRS>\n      <SRS>EPSG:62246405</SRS>\n      <SRS>EPSG:62256405</SRS>\n      <SRS>EPSG:62276405</SRS>\n      <SRS>EPSG:62296405</SRS>\n      <SRS>EPSG:62306405</SRS>\n      <SRS>EPSG:62316405</SRS>\n      <SRS>EPSG:62326405</SRS>\n      <SRS>EPSG:62336405</SRS>\n      <SRS>EPSG:62366405</SRS>\n      <SRS>EPSG:62376405</SRS>\n      <SRS>EPSG:62386405</SRS>\n      <SRS>EPSG:62396405</SRS>\n      <SRS>EPSG:62406405</SRS>\n      <SRS>EPSG:62416405</SRS>\n      <SRS>EPSG:62426405</SRS>\n      <SRS>EPSG:62436405</SRS>\n      <SRS>EPSG:62446405</SRS>\n      <SRS>EPSG:62456405</SRS>\n      <SRS>EPSG:62466405</SRS>\n      <SRS>EPSG:62476405</SRS>\n      <SRS>EPSG:62486405</SRS>\n      <SRS>EPSG:62496405</SRS>\n      <SRS>EPSG:62506405</SRS>\n      <SRS>EPSG:62516405</SRS>\n      <SRS>EPSG:62526405</SRS>\n      <SRS>EPSG:62536405</SRS>\n      <SRS>EPSG:62546405</SRS>\n      <SRS>EPSG:62556405</SRS>\n      <SRS>EPSG:62566405</SRS>\n      <SRS>EPSG:62576405</SRS>\n      <SRS>EPSG:62586405</SRS>\n      <SRS>EPSG:62586413</SRS>\n      <SRS>EPSG:62596405</SRS>\n      <SRS>EPSG:62616405</SRS>\n      <SRS>EPSG:62626405</SRS>\n      <SRS>EPSG:62636405</SRS>\n      <SRS>EPSG:62646405</SRS>\n      <SRS>EPSG:62656405</SRS>\n      <SRS>EPSG:62666405</SRS>\n      <SRS>EPSG:62676405</SRS>\n      <SRS>EPSG:62686405</SRS>\n      <SRS>EPSG:62696405</SRS>\n      <SRS>EPSG:62706405</SRS>\n      <SRS>EPSG:62716405</SRS>\n      <SRS>EPSG:62726405</SRS>\n      <SRS>EPSG:62736405</SRS>\n      <SRS>EPSG:62746405</SRS>\n      <SRS>EPSG:62756405</SRS>\n      <SRS>EPSG:62766405</SRS>\n      <SRS>EPSG:62776405</SRS>\n      <SRS>EPSG:62786405</SRS>\n      <SRS>EPSG:62796405</SRS>\n      <SRS>EPSG:62806405</SRS>\n      <SRS>EPSG:62816405</SRS>\n      <SRS>EPSG:62826405</SRS>\n      <SRS>EPSG:62836405</SRS>\n      <SRS>EPSG:62836413</SRS>\n      <SRS>EPSG:62846405</SRS>\n      <SRS>EPSG:62856405</SRS>\n      <SRS>EPSG:62866405</SRS>\n      <SRS>EPSG:62886405</SRS>\n      <SRS>EPSG:62896405</SRS>\n      <SRS>EPSG:62926405</SRS>\n      <SRS>EPSG:62936405</SRS>\n      <SRS>EPSG:62956405</SRS>\n      <SRS>EPSG:62976405</SRS>\n      <SRS>EPSG:62986405</SRS>\n      <SRS>EPSG:62996405</SRS>\n      <SRS>EPSG:63006405</SRS>\n      <SRS>EPSG:63016405</SRS>\n      <SRS>EPSG:63026405</SRS>\n      <SRS>EPSG:63036405</SRS>\n      <SRS>EPSG:63046405</SRS>\n      <SRS>EPSG:63066405</SRS>\n      <SRS>EPSG:63076405</SRS>\n      <SRS>EPSG:63086405</SRS>\n      <SRS>EPSG:63096405</SRS>\n      <SRS>EPSG:63106405</SRS>\n      <SRS>EPSG:63116405</SRS>\n      <SRS>EPSG:63126405</SRS>\n      <SRS>EPSG:63136405</SRS>\n      <SRS>EPSG:63146405</SRS>\n      <SRS>EPSG:63156405</SRS>\n      <SRS>EPSG:63166405</SRS>\n      <SRS>EPSG:63176405</SRS>\n      <SRS>EPSG:63186405</SRS>\n      <SRS>EPSG:63196405</SRS>\n      <SRS>EPSG:63226405</SRS>\n      <SRS>EPSG:63246405</SRS>\n      <SRS>EPSG:63266405</SRS>\n      <SRS>EPSG:63266406</SRS>\n      <SRS>EPSG:63266407</SRS>\n      <SRS>EPSG:63266408</SRS>\n      <SRS>EPSG:63266409</SRS>\n      <SRS>EPSG:63266410</SRS>\n      <SRS>EPSG:63266411</SRS>\n      <SRS>EPSG:63266412</SRS>\n      <SRS>EPSG:63266413</SRS>\n      <SRS>EPSG:63266414</SRS>\n      <SRS>EPSG:63266415</SRS>\n      <SRS>EPSG:63266416</SRS>\n      <SRS>EPSG:63266417</SRS>\n      <SRS>EPSG:63266418</SRS>\n      <SRS>EPSG:63266419</SRS>\n      <SRS>EPSG:63266420</SRS>\n      <SRS>EPSG:66006405</SRS>\n      <SRS>EPSG:66016405</SRS>\n      <SRS>EPSG:66026405</SRS>\n      <SRS>EPSG:66036405</SRS>\n      <SRS>EPSG:66046405</SRS>\n      <SRS>EPSG:66056405</SRS>\n      <SRS>EPSG:66066405</SRS>\n      <SRS>EPSG:66076405</SRS>\n      <SRS>EPSG:66086405</SRS>\n      <SRS>EPSG:66096405</SRS>\n      <SRS>EPSG:66106405</SRS>\n      <SRS>EPSG:66116405</SRS>\n      <SRS>EPSG:66126405</SRS>\n      <SRS>EPSG:66126413</SRS>\n      <SRS>EPSG:66136405</SRS>\n      <SRS>EPSG:66146405</SRS>\n      <SRS>EPSG:66156405</SRS>\n      <SRS>EPSG:66166405</SRS>\n      <SRS>EPSG:66186405</SRS>\n      <SRS>EPSG:66196405</SRS>\n      <SRS>EPSG:66196413</SRS>\n      <SRS>EPSG:66206405</SRS>\n      <SRS>EPSG:66216405</SRS>\n      <SRS>EPSG:66226405</SRS>\n      <SRS>EPSG:66236405</SRS>\n      <SRS>EPSG:66246405</SRS>\n      <SRS>EPSG:66246413</SRS>\n      <SRS>EPSG:66256405</SRS>\n      <SRS>EPSG:66266405</SRS>\n      <SRS>EPSG:66276405</SRS>\n      <SRS>EPSG:66276413</SRS>\n      <SRS>EPSG:66286405</SRS>\n      <SRS>EPSG:66296405</SRS>\n      <SRS>EPSG:66306405</SRS>\n      <SRS>EPSG:66316405</SRS>\n      <SRS>EPSG:66326405</SRS>\n      <SRS>EPSG:66336405</SRS>\n      <SRS>EPSG:66346405</SRS>\n      <SRS>EPSG:66356405</SRS>\n      <SRS>EPSG:66366405</SRS>\n      <SRS>EPSG:66376405</SRS>\n      <SRS>EPSG:66386405</SRS>\n      <SRS>EPSG:66396405</SRS>\n      <SRS>EPSG:66406405</SRS>\n      <SRS>EPSG:66406413</SRS>\n      <SRS>EPSG:66416405</SRS>\n      <SRS>EPSG:66426405</SRS>\n      <SRS>EPSG:66436405</SRS>\n      <SRS>EPSG:66446405</SRS>\n      <SRS>EPSG:66456405</SRS>\n      <SRS>EPSG:66456413</SRS>\n      <SRS>EPSG:66466405</SRS>\n      <SRS>EPSG:66576405</SRS>\n      <SRS>EPSG:66586405</SRS>\n      <SRS>EPSG:66596405</SRS>\n      <SRS>EPSG:66596413</SRS>\n      <SRS>EPSG:66606405</SRS>\n      <SRS>EPSG:66616405</SRS>\n      <SRS>EPSG:66616413</SRS>\n      <SRS>EPSG:66636405</SRS>\n      <SRS>EPSG:66646405</SRS>\n      <SRS>EPSG:66656405</SRS>\n      <SRS>EPSG:66666405</SRS>\n      <SRS>EPSG:66676405</SRS>\n      <SRS>EPSG:68016405</SRS>\n      <SRS>EPSG:68026405</SRS>\n      <SRS>EPSG:68036405</SRS>\n      <SRS>EPSG:68046405</SRS>\n      <SRS>EPSG:68056405</SRS>\n      <SRS>EPSG:68066405</SRS>\n      <SRS>EPSG:68086405</SRS>\n      <SRS>EPSG:68096405</SRS>\n      <SRS>EPSG:68136405</SRS>\n      <SRS>EPSG:68146405</SRS>\n      <SRS>EPSG:68156405</SRS>\n      <SRS>EPSG:68186405</SRS>\n      <SRS>EPSG:68206405</SRS>\n      <SRS>EPSG:69036405</SRS>\n      <SRS>EPSG:42302</SRS>\n      <SRS>EPSG:42301</SRS>\n      <SRS>EPSG:900913</SRS>\n      <SRS>EPSG:45556</SRS>\n      <SRS>EPSG:45555</SRS>\n      <SRS>EPSG:54004</SRS>\n      <SRS>EPSG:41001</SRS>\n      <SRS>EPSG:42311</SRS>\n      <SRS>EPSG:42310</SRS>\n      <SRS>EPSG:18001</SRS>\n      <SRS>EPSG:100003</SRS>\n      <SRS>EPSG:42106</SRS>\n      <SRS>EPSG:100002</SRS>\n      <SRS>EPSG:42105</SRS>\n      <SRS>EPSG:100001</SRS>\n      <SRS>EPSG:42309</SRS>\n      <SRS>EPSG:42104</SRS>\n      <SRS>EPSG:42308</SRS>\n      <SRS>EPSG:42103</SRS>\n      <SRS>EPSG:42307</SRS>\n      <SRS>EPSG:42102</SRS>\n      <SRS>EPSG:42306</SRS>\n      <SRS>EPSG:42101</SRS>\n      <SRS>EPSG:42305</SRS>\n      <SRS>EPSG:42304</SRS>\n      <SRS>EPSG:42303</SRS>\n      <LatLonBoundingBox minx=\"-257.0843245637291\" miny=\"-257.0843245637291\" maxx=\"257.0843245637291\" maxy=\"257.0843245637291\"/>\n      <Layer queryable=\"1\">\n        <Name>tiger:poly_landmarks</Name>\n        <Title>Manhattan (NY) landmarks</Title>\n        <Abstract>Manhattan landmarks, identifies water, lakes, parks, interesting buildilngs</Abstract>\n        <KeywordList>\n          <Keyword>DS_poly_landmarks</Keyword>\n          <Keyword>poly_landmarks</Keyword>\n          <Keyword>landmarks</Keyword>\n          <Keyword>manhattan</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <LatLonBoundingBox minx=\"-74.1008830202198\" miny=\"40.65748247978021\" maxx=\"-73.8541219797802\" maxy=\"40.90424352021979\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"-74.047185\" miny=\"40.679648\" maxx=\"-73.90782\" maxy=\"40.882078\"/>\n        <Style>\n          <Name>poly_landmarks</Name>\n          <Title>Default Styler</Title>\n          <Abstract/>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tiger:poly_landmarks\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>tiger:poi</Name>\n        <Title>Manhattan (NY) points of interest</Title>\n        <Abstract>Points of interest in New York, New York (on Manhattan). One of the attributes contains the name of a file with a picture of the point of interest.</Abstract>\n        <KeywordList>\n          <Keyword>poi</Keyword>\n          <Keyword>DS_poi</Keyword>\n          <Keyword>points_of_interest</Keyword>\n          <Keyword>Manhattan</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <LatLonBoundingBox minx=\"-74.01288357289539\" miny=\"40.70706518152972\" maxx=\"-74.00752144792617\" maxy=\"40.71242730649893\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"-74.0118315772888\" miny=\"40.70754683896324\" maxx=\"-74.00153046439813\" maxy=\"40.719885123828675\"/>\n        <Style>\n          <Name>poi</Name>\n          <Title>Points of interest</Title>\n          <Abstract>Manhattan points of interest</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tiger:poi\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>tiger:tiger_roads</Name>\n        <Title>Manhattan (NY) roads</Title>\n        <Abstract>Highly simplified road layout of Manhattan in New York..</Abstract>\n        <KeywordList>\n          <Keyword>DS_tiger_roads</Keyword>\n          <Keyword>tiger_roads</Keyword>\n          <Keyword>roads</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <LatLonBoundingBox minx=\"-74.08769307536667\" miny=\"40.660618924633326\" maxx=\"-73.84653192463333\" maxy=\"40.90178007536667\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"-74.02722\" miny=\"40.684221\" maxx=\"-73.907005\" maxy=\"40.878178\"/>\n        <Style>\n          <Name>tiger_roads</Name>\n          <Title>Default Styler</Title>\n          <Abstract/>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tiger:tiger_roads\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>sf:archsites</Name>\n        <Title>Spearfish archeological sites</Title>\n        <Abstract>Sample data from GRASS, archeological sites location, Spearfish, South Dakota, USA</Abstract>\n        <KeywordList>\n          <Keyword>archsites</Keyword>\n          <Keyword>sfArchsites</Keyword>\n          <Keyword>spearfish</Keyword>\n          <Keyword>archeology</Keyword>\n        </KeywordList>\n        <SRS>EPSG:26713</SRS>\n        <LatLonBoundingBox minx=\"-103.89000625326194\" miny=\"44.29796961116877\" maxx=\"-103.62049935931161\" maxy=\"44.5674765051191\"/>\n        <BoundingBox SRS=\"EPSG:26713\" minx=\"588926.6865343997\" miny=\"4913890.332215005\" maxx=\"609271.2114429093\" maxy=\"4927102.448786693\"/>\n        <Style>\n          <Name>point</Name>\n          <Title>Default point</Title>\n          <Abstract>A sample style that just prints out a 6px wide red square</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=sf:archsites\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>sf:bugsites</Name>\n        <Title>Spearfish bug locations</Title>\n        <Abstract>Sample data from GRASS, bug sites location, Spearfish, South Dakota, USA</Abstract>\n        <KeywordList>\n          <Keyword>sfBugsites</Keyword>\n          <Keyword>bugsites</Keyword>\n          <Keyword>insects</Keyword>\n          <Keyword>spearfish</Keyword>\n          <Keyword>tiger_beetles</Keyword>\n        </KeywordList>\n        <SRS>EPSG:26713</SRS>\n        <LatLonBoundingBox minx=\"-103.89041901614995\" miny=\"44.266492773791775\" maxx=\"-103.61527753322848\" maxy=\"44.54163425671326\"/>\n        <BoundingBox SRS=\"EPSG:26713\" minx=\"589311.4871629482\" miny=\"4913787.082099182\" maxx=\"609374.4115724327\" maxy=\"4920844.691225147\"/>\n        <Style>\n          <Name>capitals</Name>\n          <Title>Capital cities</Title>\n          <Abstract/>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=sf:bugsites\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>sf:restricted</Name>\n        <Title>Spearfish restricted areas</Title>\n        <Abstract>Sample data from GRASS, restricted areas, Spearfish, South Dakota, USA</Abstract>\n        <KeywordList>\n          <Keyword>restricted</Keyword>\n          <Keyword>sfRestricted</Keyword>\n          <Keyword>spearfish</Keyword>\n          <Keyword>areas</Keyword>\n        </KeywordList>\n        <SRS>EPSG:26713</SRS>\n        <LatLonBoundingBox minx=\"-103.86063428986338\" miny=\"44.37661974734028\" maxx=\"-103.73735238788223\" maxy=\"44.49990164932145\"/>\n        <BoundingBox SRS=\"EPSG:26713\" minx=\"591175.6988413236\" miny=\"4915754.888027622\" maxx=\"600052.4121365736\" maxy=\"4926353.920417598\"/>\n        <Style>\n          <Name>restricted</Name>\n          <Title>Red, translucent style</Title>\n          <Abstract>A sample style that just prints out a transparent red interior with a red outline</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=sf:restricted\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>sf:roads</Name>\n        <Title>Spearfish roads</Title>\n        <Abstract>Sample data from GRASS, road layout, Spearfish, South Dakota, USA</Abstract>\n        <KeywordList>\n          <Keyword>sfRoads</Keyword>\n          <Keyword>roads</Keyword>\n          <Keyword>spearfish</Keyword>\n        </KeywordList>\n        <SRS>EPSG:26713</SRS>\n        <LatLonBoundingBox minx=\"-103.90534996703491\" miny=\"44.2800314829381\" maxx=\"-103.5943809967035\" maxy=\"44.5910004532695\"/>\n        <BoundingBox SRS=\"EPSG:26713\" minx=\"588430.2387813567\" miny=\"4913303.484828213\" maxx=\"610531.8279023392\" maxy=\"4928766.251023613\"/>\n        <Style>\n          <Name>simple_roads</Name>\n          <Title>Default Styler for simple road segments</Title>\n          <Abstract>Light red line, 2px wide</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=sf:roads\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>sf:streams</Name>\n        <Title>Spearfish streams</Title>\n        <Abstract>Sample data from GRASS, streams, Spearfish, South Dakota, USA</Abstract>\n        <KeywordList>\n          <Keyword>sfStreams</Keyword>\n          <Keyword>streams</Keyword>\n          <Keyword>spearfish</Keyword>\n        </KeywordList>\n        <SRS>EPSG:26713</SRS>\n        <LatLonBoundingBox minx=\"-103.9089219204826\" miny=\"44.278738996398694\" maxx=\"-103.59184616696963\" maxy=\"44.595814749911675\"/>\n        <BoundingBox SRS=\"EPSG:26713\" minx=\"588430.3113926318\" miny=\"4913241.156915463\" maxx=\"610522.3974737043\" maxy=\"4928777.235349244\"/>\n        <Style>\n          <Name>simple_streams</Name>\n          <Title>Default Styler for streams segments</Title>\n          <Abstract>Blue lines, 2px wide</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=sf:streams\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>topp:tasmania_cities</Name>\n        <Title>Tasmania cities</Title>\n        <Abstract>Cities in Tasmania (actually, just the capital)</Abstract>\n        <KeywordList>\n          <Keyword>cities</Keyword>\n          <Keyword>Tasmania</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <LatLonBoundingBox minx=\"144.93357593664516\" miny=\"-43.93984106335484\" maxx=\"148.53694406335487\" maxy=\"-40.33647293664516\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"147.2910004483\" miny=\"-42.851001816890005\" maxx=\"147.2910004483\" maxy=\"-42.851001816890005\"/>\n        <Style>\n          <Name>capitals</Name>\n          <Title>Capital cities</Title>\n          <Abstract/>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:tasmania_cities\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>topp:tasmania_roads</Name>\n        <Title>Tasmania roads</Title>\n        <Abstract>Main Tasmania roads</Abstract>\n        <KeywordList>\n          <Keyword>Roads</Keyword>\n          <Keyword>Tasmania</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <LatLonBoundingBox minx=\"144.8607879004856\" miny=\"-44.01262909951439\" maxx=\"148.60973209951442\" maxy=\"-40.26368490048561\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"145.19754\" miny=\"-43.423512\" maxx=\"148.27298000000002\" maxy=\"-40.852802\"/>\n        <Style>\n          <Name>simple_roads</Name>\n          <Title>Default Styler for simple road segments</Title>\n          <Abstract>Light red line, 2px wide</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:tasmania_roads\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>topp:tasmania_state_boundaries</Name>\n        <Title>Tasmania state boundaries</Title>\n        <Abstract>Tasmania state boundaries</Abstract>\n        <KeywordList>\n          <Keyword>tasmania_state_boundaries</Keyword>\n          <Keyword>Tasmania</Keyword>\n          <Keyword>boundaries</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <LatLonBoundingBox minx=\"142.70637712387594\" miny=\"-45.06157887612408\" maxx=\"149.60758787612411\" maxy=\"-38.16036812387592\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"143.83482400000003\" miny=\"-43.648056\" maxx=\"148.47914100000003\" maxy=\"-39.573891\"/>\n        <Style>\n          <Name>green</Name>\n          <Title>Green polygon</Title>\n          <Abstract>Green fill with black outline</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:tasmania_state_boundaries\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>topp:tasmania_water_bodies</Name>\n        <Title>Tasmania water bodies</Title>\n        <Abstract>Tasmania water bodies</Abstract>\n        <KeywordList>\n          <Keyword>Lakes</Keyword>\n          <Keyword>Bodies</Keyword>\n          <Keyword>Australia</Keyword>\n          <Keyword>Water</Keyword>\n          <Keyword>Tasmania</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <LatLonBoundingBox minx=\"145.82989373832018\" miny=\"-43.16951476167979\" maxx=\"147.3614212616798\" maxy=\"-41.63798723832021\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"145.97161899999998\" miny=\"-43.031944\" maxx=\"147.219696\" maxy=\"-41.775558\"/>\n        <Style>\n          <Name>cite_lakes</Name>\n          <Title>Blue lake</Title>\n          <Abstract>A blue fill, solid black outline style</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:tasmania_water_bodies\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>topp:states</Name>\n        <Title>USA Population</Title>\n        <Abstract>This is some census data on the states.</Abstract>\n        <KeywordList>\n          <Keyword>census</Keyword>\n          <Keyword>united</Keyword>\n          <Keyword>boundaries</Keyword>\n          <Keyword>state</Keyword>\n          <Keyword>states</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <LatLonBoundingBox minx=\"-131.05615308855994\" miny=\"1.958333411440066\" maxx=\"-60.645117911440046\" maxy=\"72.36936858855995\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"-124.73142200000001\" miny=\"24.955967\" maxx=\"-66.969849\" maxy=\"49.371735\"/>\n        <Style>\n          <Name>population</Name>\n          <Title>Population in the United States</Title>\n          <Abstract>A sample filter that filters the United States into three\n        categories of population, drawn in different colors</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:states\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>tiger:giant_polygon</Name>\n        <Title>World rectangle</Title>\n        <Abstract>A simple rectangular polygon covering most of the world, it\\'s only used for the purpose of providing a background (WMS bgcolor could be used instead)</Abstract>\n        <KeywordList>\n          <Keyword>DS_giant_polygon</Keyword>\n          <Keyword>giant_polygon</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <LatLonBoundingBox minx=\"-257.0843245637291\" miny=\"-257.0843245637291\" maxx=\"257.0843245637291\" maxy=\"257.0843245637291\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"-180.0\" miny=\"-90.0\" maxx=\"180.0\" maxy=\"90.0\"/>\n        <Style>\n          <Name>giant_polygon</Name>\n          <Title>Border-less gray fill</Title>\n          <Abstract>Light gray polygon fill without a border</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tiger:giant_polygon\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>nurc:Arc_Sample</Name>\n        <Title>Global annual rainfall</Title>\n        <Abstract>Global annual rainfall in ArcGrid format</Abstract>\n        <KeywordList>\n          <Keyword>WCS</Keyword>\n          <Keyword>arcGridSample</Keyword>\n          <Keyword>arcGridSample_Coverage</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <LatLonBoundingBox minx=\"-180.0\" miny=\"-90.0\" maxx=\"180.0\" maxy=\"90.0\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"-180.0\" miny=\"-90.0\" maxx=\"180.0\" maxy=\"90.0\"/>\n        <Style>\n          <Name>raster</Name>\n          <Title>Raster</Title>\n          <Abstract>A sample style for rasters, good for displaying imagery</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=nurc:Arc_Sample\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>nurc:Img_Sample</Name>\n        <Title>North America sample imagery</Title>\n        <Abstract>A very rough imagery of North America</Abstract>\n        <KeywordList>\n          <Keyword>WCS</Keyword>\n          <Keyword>worldImageSample</Keyword>\n          <Keyword>worldImageSample_Coverage</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <LatLonBoundingBox minx=\"-130.85168\" miny=\"20.7052\" maxx=\"-62.0054\" maxy=\"54.1141\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"-130.85168\" miny=\"20.7052\" maxx=\"-62.0054\" maxy=\"54.1141\"/>\n        <Style>\n          <Name>raster</Name>\n          <Title>Raster</Title>\n          <Abstract>A sample style for rasters, good for displaying imagery</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=nurc:Img_Sample\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>nurc:mosaic</Name>\n        <Title>Sample PNG mosaic</Title>\n        <Abstract>Subsampled satellite imagery loaded as a mosaic of PNG images</Abstract>\n        <KeywordList>\n          <Keyword>WCS</Keyword>\n          <Keyword>mosaic</Keyword>\n          <Keyword>mosaic</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <LatLonBoundingBox minx=\"6.34617490847439\" miny=\"36.4917718219401\" maxx=\"20.8296831527815\" maxy=\"46.5907669751351\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"6.34617490847439\" miny=\"36.4917718219401\" maxx=\"20.8296831527815\" maxy=\"46.5907669751351\"/>\n        <Style>\n          <Name>raster</Name>\n          <Title>Raster</Title>\n          <Abstract>A sample style for rasters, good for displaying imagery</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=nurc:mosaic\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>nurc:Pk50095</Name>\n        <Title>Sample scanned and georerenced map</Title>\n        <Abstract>This is a sample for the world image format (wld + prj + tiff)</Abstract>\n        <KeywordList>\n          <Keyword>WCS</Keyword>\n          <Keyword>img_sample2</Keyword>\n          <Keyword>Pk50095</Keyword>\n        </KeywordList>\n        <SRS>EPSG:32633</SRS>\n        <LatLonBoundingBox minx=\"12.999446822650462\" miny=\"46.722110379286\" maxx=\"13.308182612644663\" maxy=\"46.91359611878293\"/>\n        <BoundingBox SRS=\"EPSG:32633\" minx=\"347649.93086859107\" miny=\"5176214.082539256\" maxx=\"370725.976428591\" maxy=\"5196961.352859256\"/>\n        <Style>\n          <Name>raster</Name>\n          <Title>Raster</Title>\n          <Abstract>A sample style for rasters, good for displaying imagery</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=nurc:Pk50095\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>sf:sfdem</Name>\n        <Title>sfdem is a Tagged Image File Format with Geographic information</Title>\n        <Abstract>Generated from sfdem</Abstract>\n        <KeywordList>\n          <Keyword>WCS</Keyword>\n          <Keyword>sfdem</Keyword>\n          <Keyword>sfdem</Keyword>\n        </KeywordList>\n        <SRS>EPSG:26713</SRS>\n        <LatLonBoundingBox minx=\"-103.87108701853181\" miny=\"44.370187074132616\" maxx=\"-103.62940739432703\" maxy=\"44.5016011535299\"/>\n        <BoundingBox SRS=\"EPSG:26713\" minx=\"589980.0\" miny=\"4913700.0\" maxx=\"609000.0\" maxy=\"4928010.0\"/>\n        <Style>\n          <Name>dem</Name>\n          <Title>Simple DEM style</Title>\n          <Abstract>Classic elevation color progression</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://publicus.opengeo.org:80/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=sf:sfdem\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"0\">\n        <Name>spearfish</Name>\n        <Title>spearfish</Title>\n        <Abstract>Layer-Group type layer: spearfish</Abstract>\n        <SRS>EPSG:26713</SRS>\n        <LatLonBoundingBox minx=\"-103.87799562257162\" miny=\"44.37244213023845\" maxx=\"-103.62286957414864\" maxy=\"44.5023266635277\"/>\n        <BoundingBox SRS=\"EPSG:26713\" minx=\"589425.9342365642\" miny=\"4913959.224611808\" maxx=\"609518.6719560538\" maxy=\"4928082.949945881\"/>\n      </Layer>\n      <Layer queryable=\"0\">\n        <Name>tasmania</Name>\n        <Title>tasmania</Title>\n        <Abstract>Layer-Group type layer: tasmania</Abstract>\n        <SRS>EPSG:4326</SRS>\n        <LatLonBoundingBox minx=\"143.83482400000003\" miny=\"-43.648056\" maxx=\"148.47914100000003\" maxy=\"-39.573891\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"143.83482400000003\" miny=\"-43.648056\" maxx=\"148.47914100000003\" maxy=\"-39.573891\"/>\n      </Layer>\n      <Layer queryable=\"0\">\n        <Name>tiger-ny</Name>\n        <Title>tiger-ny</Title>\n        <Abstract>Layer-Group type layer: tiger-ny</Abstract>\n        <SRS>EPSG:4326</SRS>\n        <LatLonBoundingBox minx=\"-74.047185\" miny=\"40.679648\" maxx=\"-73.907005\" maxy=\"40.882078\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"-74.047185\" miny=\"40.679648\" maxx=\"-73.907005\" maxy=\"40.882078\"/>\n      </Layer>\n    </Layer>\n  </Capability>\n</WMT_MS_Capabilities>--></div>\n\n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WMSCapabilities/v1_1_1_WMSC.html",
    "content": "<html> \n<head> \n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    \n    function test_read(t) {\n        \n        t.plan(9);\n\n        var xml = document.getElementById(\"wmsc\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n        var format = new OpenLayers.Format.WMSCapabilities({profile: \"WMSC\"});\n        var obj = format.read(doc);\n        var tilesets = obj.capability.vendorSpecific.tileSets;\n        t.eq(tilesets.length, 2, \"We expect 2 tilesets to be parsed\");\n        var tileset = tilesets[0];\n        t.eq(tileset.bbox[\"EPSG:900913\"].bbox, [-13697515.466796875, 5165920.118906248, -13619243.94984375, 5244191.635859374], \"BBOX correctly parsed\");\n        t.eq(tileset.format, \"image/png\", \"Format correctly parsed\");\n        t.eq(tileset.height, 256, \"Height correctly parsed\");\n        t.eq(tileset.width, 256, \"Width correctly parsed\");\n        t.eq(tileset.layers, \"medford:hydro\", \"Layers correctly parsed\");\n        t.eq(tileset.srs[\"EPSG:900913\"], true, \"SRS correctly parsed\");\n        t.eq(tileset.resolutions, [156543.03390625, 78271.516953125, 39135.7584765625, 19567.87923828125, 9783.939619140625, 4891.9698095703125, 2445.9849047851562, 1222.9924523925781, 611.4962261962891, 305.74811309814453, 152.87405654907226, 76.43702827453613, 38.218514137268066, 19.109257068634033, 9.554628534317017, 4.777314267158508, 2.388657133579254, 1.194328566789627, 0.5971642833948135, 0.29858214169740677, 0.14929107084870338, 0.07464553542435169, 0.037322767712175846, 0.018661383856087923, 0.009330691928043961, 0.004665345964021981], \"Resolutions correctly parsed\");\n        t.eq(tileset.styles, \"\", \"Styles correctly parsed\");\n    }\n\n    function test_read_fallback(t) {\n        t.plan(1);\n        var xml = document.getElementById(\"fallback\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n        var format = new OpenLayers.Format.WMSCapabilities({profile: \"WMSC\", allowFallback: true});\n        var obj = format.read(doc);\n        t.eq(obj.capability.layers.length, 2, \"2 layers parsed with allowFallback true\");\n    }\n\n    </script> \n</head> \n<body>\n\n<div id=\"fallback\"><!--\n<?xml version='1.0' encoding=\"ISO-8859-1\" standalone=\"no\" ?>\n<!DOCTYPE WMT_MS_Capabilities SYSTEM \"http://schemas.opengis.net/wms/1.1.0/capabilities_1_1_0.dtd\"\n [\n <!ELEMENT VendorSpecificCapabilities EMPTY>\n ]>  \n<WMT_MS_Capabilities version=\"1.1.0\">\n\n<Service>\n  <Name>OGC:WMS</Name>\n  <Title>i3Geo - i3geo</Title>\n  <Abstract>Web services gerados da base de dados do i3Geo. Para chamar um tema especificamente, veja o sistema de ajuda, digitando no navegador web ogc.php?ajuda=, para uma lista compacta de todos os servicos, digite ogc.php?lista=temas</Abstract>\n        <KeywordList>\n          <Keyword>i3Geo</Keyword>\n        </KeywordList>\n  <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://mapas.mma.gov.br/i3geo/ogc.php?\"/>\n  <ContactInformation>\n    <ContactPersonPrimary>\n      <ContactPerson>Web Master</ContactPerson>\n      <ContactOrganization>Coordena??o Geral de TI</ContactOrganization>\n    </ContactPersonPrimary>\n      <ContactPosition>Administrador do s?tio web</ContactPosition>\n    <ContactAddress>\n        <AddressType>uri</AddressType>\n        <Address>http://www.mma.gov.br</Address>\n        <City>Brasilia</City>\n        <StateOrProvince>DF</StateOrProvince>\n        <PostCode></PostCode>\n        <Country>Brasil</Country>\n    </ContactAddress>\n  <ContactElectronicMailAddress>geoprocessamento@mma.gov.br</ContactElectronicMailAddress>\n  </ContactInformation>\n  <Fees>none</Fees>\n  <AccessConstraints>vedado o uso comercial</AccessConstraints>\n</Service>\n\n<Capability>\n  <Request>\n    <GetCapabilities>\n      <Format>application/vnd.ogc.wms_xml</Format>\n      <DCPType>\n        <HTTP>\n          <Get><OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://mapas.mma.gov.br/i3geo/ogc.php?\"/></Get>\n          <Post><OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://mapas.mma.gov.br/i3geo/ogc.php?\"/></Post>\n        </HTTP>\n      </DCPType>\n    </GetCapabilities>\n    <GetMap>\n      <Format>image/png</Format>\n      <Format>image/jpeg</Format>\n      <Format>image/gif</Format>\n      <Format>image/png; mode=8bit</Format>\n      <Format>application/x-pdf</Format>\n      <Format>image/svg+xml</Format>\n      <Format>image/tiff</Format>\n      <Format>application/vnd.google-earth.kml+xml</Format>\n      <Format>application/vnd.google-earth.kmz</Format>\n      <DCPType>\n        <HTTP>\n          <Get><OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://mapas.mma.gov.br/i3geo/ogc.php?\"/></Get>\n          <Post><OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://mapas.mma.gov.br/i3geo/ogc.php?\"/></Post>\n        </HTTP>\n      </DCPType>\n    </GetMap>\n    <GetFeatureInfo>\n      <Format>text/plain</Format>\n      <Format>application/vnd.ogc.gml</Format>\n      <DCPType>\n        <HTTP>\n          <Get><OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://mapas.mma.gov.br/i3geo/ogc.php?\"/></Get>\n          <Post><OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://mapas.mma.gov.br/i3geo/ogc.php?\"/></Post>\n        </HTTP>\n      </DCPType>\n    </GetFeatureInfo>\n    <DescribeLayer>\n      <Format>text/xml</Format>\n      <DCPType>\n        <HTTP>\n          <Get><OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://mapas.mma.gov.br/i3geo/ogc.php?\"/></Get>\n          <Post><OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://mapas.mma.gov.br/i3geo/ogc.php?\"/></Post>\n        </HTTP>\n      </DCPType>\n    </DescribeLayer>\n  </Request>\n  <Exception>\n    <Format>application/vnd.ogc.se_xml</Format>\n    <Format>application/vnd.ogc.se_inimage</Format>\n    <Format>application/vnd.ogc.se_blank</Format>\n  </Exception>\n  <VendorSpecificCapabilities />\n  <UserDefinedSymbolization SupportSLD=\"1\" UserLayer=\"0\" UserStyle=\"1\" RemoteWFS=\"0\"/>\n  <Layer>\n    <Name>i3geoogc</Name>\n    <Title>i3Geo - i3geo</Title>\n    <Abstract>Web services gerados da base de dados do i3Geo. Para chamar um tema especificamente, veja o sistema de ajuda, digitando no navegador web ogc.php?ajuda=, para uma lista compacta de todos os servicos, digite ogc.php?lista=temas</Abstract>\n    <KeywordList>\n     <Keyword>i3Geo</Keyword>\n    </KeywordList>\n    <SRS></SRS>\n    <LatLonBoundingBox minx=\"-76.5126\" miny=\"-36.9484\" maxx=\"-29.5852\" maxy=\"7.04601\" />\n    <BoundingBox SRS=\"\"\n                minx=\"-76.5126\" miny=\"-36.9484\" maxx=\"-29.5852\" maxy=\"7.04601\" />\n    <Attribution>\n        <Title>i3Geo</Title>\n        <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://mapas.mma.gov.br/i3geo\"/>\n        <LogoURL width=\"85\" height=\"56\">\n             <Format>image/png</Format>\n             <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://mapas.mma.gov.br/i3geo/imagens/i3geo.png\"/>\n          </LogoURL>\n    </Attribution>\n    <Layer queryable=\"1\" opaque=\"0\" cascaded=\"0\">\n        <Name>antigo_caminantes</Name>\n        <Title>Guia de Caminantes - 1817</Title>\n        <SRS> EPSG:4618 EPSG:4291 EPSG:4326 EPSG:22521 EPSG:22522 EPSG:22523 EPSG:22524 EPSG:22525 EPSG:29101 EPSG:29119 EPSG:29120 EPSG:29121 EPSG:29122 EPSG:29177 EPSG:29178 EPSG:29179 EPSG:29180 EPSG:29181 EPSG:29182 EPSG:29183 EPSG:29184 EPSG:29185</SRS>\n        <LatLonBoundingBox minx=\"-75.2336\" miny=\"-33.7516\" maxx=\"-27.593\" maxy=\"5.27216\" />\n        <BoundingBox SRS=\"\"\n                    minx=\"-75.2336\" miny=\"-33.7516\" maxx=\"-27.593\" maxy=\"5.27216\" />\n        <MetadataURL type=\"TC211\">\n          <Format>text/html</Format>\n          <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://consorcio.bn.br\"/>\n        </MetadataURL>\n    </Layer>\n  </Layer>\n</Capability>\n</WMT_MS_Capabilities>\n--></div>\n\n<div id=\"wmsc\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE WMT_MS_Capabilities SYSTEM \"http://schemas.opengis.net/wms/1.1.1/capabilities_1_1_1.dtd\"[\n<!ELEMENT VendorSpecificCapabilities (TileSet*) >\n<!ELEMENT TileSet (SRS, BoundingBox?, Resolutions, Width, Height, Format, Layers*, Styles*) >\n<!ELEMENT Resolutions (#PCDATA) >\n<!ELEMENT Width (#PCDATA) >\n<!ELEMENT Height (#PCDATA) >\n<!ELEMENT Layers (#PCDATA) >\n<!ELEMENT Styles (#PCDATA) >\n]>\n<WMT_MS_Capabilities version=\"1.1.1\" updateSequence=\"57\">\n  <Service>\n    <Name>OGC:WMS</Name>\n    <Title>GeoServer Web Map Service</Title>\n    <Abstract>A compliant implementation of WMS 1.1.1 plus most of the SLD 1.0 extension (dynamic styling). Can also generate PDF, SVG, KML, GeoRSS</Abstract>\n    <KeywordList>\n      <Keyword>WFS</Keyword>\n      <Keyword>WMS</Keyword>\n      <Keyword>GEOSERVER</Keyword>\n    </KeywordList>\n    <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://localhost:8080/geoserver-suite/wms\"/>\n    <ContactInformation>\n      <ContactPersonPrimary>\n        <ContactPerson>OpenGeo</ContactPerson>\n        <ContactOrganization>OpenGeo</ContactOrganization>\n      </ContactPersonPrimary>\n      <ContactPosition>Outreach</ContactPosition>\n      <ContactAddress>\n        <AddressType>Work</AddressType>\n        <Address/>\n        <City>New York</City>\n        <StateOrProvince/>\n        <PostCode/>\n        <Country>USA</Country>\n      </ContactAddress>\n      <ContactVoiceTelephone/>\n      <ContactFacsimileTelephone/>\n      <ContactElectronicMailAddress>inquiry@opengeo.org</ContactElectronicMailAddress>\n    </ContactInformation>\n    <Fees>NONE</Fees>\n    <AccessConstraints>NONE</AccessConstraints>\n  </Service>\n  <Capability>\n    <Request>\n      <GetCapabilities>\n        <Format>application/vnd.ogc.wms_xml</Format>\n        <DCPType>\n          <HTTP>\n            <Get>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://localhost:8080/geoserver-suite/wms?SERVICE=WMS&amp;\"/>\n            </Get>\n            <Post>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://localhost:8080/geoserver-suite/wms?SERVICE=WMS&amp;\"/>\n            </Post>\n          </HTTP>\n        </DCPType>\n      </GetCapabilities>\n      <GetMap>\n        <Format>image/png</Format>\n        <Format>application/atom xml</Format>\n        <Format>application/atom+xml</Format>\n        <Format>application/openlayers</Format>\n        <Format>application/pdf</Format>\n        <Format>application/rss xml</Format>\n        <Format>application/rss+xml</Format>\n        <Format>application/vnd.google-earth.kml</Format>\n        <Format>application/vnd.google-earth.kml xml</Format>\n        <Format>application/vnd.google-earth.kml+xml</Format>\n        <Format>application/vnd.google-earth.kmz</Format>\n        <Format>application/vnd.google-earth.kmz xml</Format>\n        <Format>application/vnd.google-earth.kmz+xml</Format>\n        <Format>atom</Format>\n        <Format>image/geotiff</Format>\n        <Format>image/geotiff8</Format>\n        <Format>image/gif</Format>\n        <Format>image/jpeg</Format>\n        <Format>image/png8</Format>\n        <Format>image/svg</Format>\n        <Format>image/svg xml</Format>\n        <Format>image/svg+xml</Format>\n        <Format>image/tiff</Format>\n        <Format>image/tiff8</Format>\n        <Format>kml</Format>\n        <Format>kmz</Format>\n        <Format>openlayers</Format>\n        <Format>rss</Format>\n        <DCPType>\n          <HTTP>\n            <Get>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://localhost:8080/geoserver-suite/wms?SERVICE=WMS&amp;\"/>\n            </Get>\n          </HTTP>\n        </DCPType>\n      </GetMap>\n      <GetFeatureInfo>\n        <Format>text/plain</Format>\n        <Format>application/vnd.ogc.gml</Format>\n        <Format>text/html</Format>\n        <DCPType>\n          <HTTP>\n            <Get>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://localhost:8080/geoserver-suite/wms?SERVICE=WMS&amp;\"/>\n            </Get>\n            <Post>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://localhost:8080/geoserver-suite/wms?SERVICE=WMS&amp;\"/>\n            </Post>\n          </HTTP>\n        </DCPType>\n      </GetFeatureInfo>\n      <DescribeLayer>\n        <Format>application/vnd.ogc.wms_xml</Format>\n        <DCPType>\n          <HTTP>\n            <Get>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://localhost:8080/geoserver-suite/wms?SERVICE=WMS&amp;\"/>\n            </Get>\n          </HTTP>\n        </DCPType>\n      </DescribeLayer>\n      <GetLegendGraphic>\n        <Format>image/png</Format>\n        <Format>image/jpeg</Format>\n        <Format>image/gif</Format>\n        <DCPType>\n          <HTTP>\n            <Get>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://localhost:8080/geoserver-suite/wms?SERVICE=WMS&amp;\"/>\n            </Get>\n          </HTTP>\n        </DCPType>\n      </GetLegendGraphic>\n      <GetStyles>\n        <Format>application/vnd.ogc.sld+xml</Format>\n        <DCPType>\n          <HTTP>\n            <Get>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://localhost:8080/geoserver-suite/wms?SERVICE=WMS&amp;\"/>\n            </Get>\n          </HTTP>\n        </DCPType>\n      </GetStyles>\n    </Request>\n    <Exception>\n      <Format>application/vnd.ogc.se_xml</Format>\n      <Format>application/vnd.ogc.se_inimage</Format>\n    </Exception>\n    <VendorSpecificCapabilities>\n      <TileSet>\n        <SRS>EPSG:900913</SRS>\n        <BoundingBox SRS=\"EPSG:900913\" minx=\"-1.3697515466796875E7\" miny=\"5165920.118906248\" maxx=\"-1.361924394984375E7\" maxy=\"5244191.635859374\"/>\n        <Resolutions>156543.03390625 78271.516953125 39135.7584765625 19567.87923828125 9783.939619140625 4891.9698095703125 2445.9849047851562 1222.9924523925781 611.4962261962891 305.74811309814453 152.87405654907226 76.43702827453613 38.218514137268066 19.109257068634033 9.554628534317017 4.777314267158508 2.388657133579254 1.194328566789627 0.5971642833948135 0.29858214169740677 0.14929107084870338 0.07464553542435169 0.037322767712175846 0.018661383856087923 0.009330691928043961 0.004665345964021981 </Resolutions>\n        <Width>256</Width>\n        <Height>256</Height>\n        <Format>image/png</Format>\n        <Layers>medford:hydro</Layers>\n        <Styles/>\n      </TileSet>\n      <TileSet>\n        <SRS>EPSG:4326</SRS>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"-123.046875\" miny=\"42.1875\" maxx=\"-122.6953125\" maxy=\"42.5390625\"/>\n        <Resolutions>0.703125 0.3515625 0.17578125 0.087890625 0.0439453125 0.02197265625 0.010986328125 0.0054931640625 0.00274658203125 0.001373291015625 6.866455078125E-4 3.4332275390625E-4 1.71661376953125E-4 8.58306884765625E-5 4.291534423828125E-5 2.1457672119140625E-5 1.0728836059570312E-5 5.364418029785156E-6 2.682209014892578E-6 1.341104507446289E-6 6.705522537231445E-7 3.3527612686157227E-7 1.6763806343078613E-7 8.381903171539307E-8 4.190951585769653E-8 2.0954757928848267E-8 </Resolutions>\n        <Width>256</Width>\n        <Height>256</Height>\n        <Format>image/gif</Format>\n        <Layers>medford</Layers>\n        <Styles/>\n      </TileSet>\n    </VendorSpecificCapabilities>\n    <UserDefinedSymbolization SupportSLD=\"1\" UserLayer=\"1\" UserStyle=\"1\" RemoteWFS=\"1\"/>\n    <Layer queryable=\"0\" opaque=\"0\" noSubsets=\"0\">\n      <Title>GeoServer Web Map Service</Title>\n      <Abstract>A compliant implementation of WMS 1.1.1 plus most of the SLD 1.0 extension (dynamic styling). Can also generate PDF, SVG, KML, GeoRSS</Abstract>\n      <SRS>EPSG:4326</SRS>\n      <SRS>EPSG:900913</SRS>\n      <LatLonBoundingBox minx=\"-180.0\" miny=\"-90.0\" maxx=\"180.0\" maxy=\"83.624\"/>\n    </Layer>\n  </Capability>\n</WMT_MS_Capabilities>\n--></div>\n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WMSCapabilities/v1_3_0.html",
    "content": "<html>\n<head>\n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_read_exception(t) {\n        t.plan(1);\n        var xml = document.getElementById(\"exceptionsample\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n        var format = new OpenLayers.Format.WMSCapabilities();\n        var obj = format.read(doc);\n        t.ok(!!obj.error, \"Error reported correctly\");\n    }\n\n    function test_layers(t) {\n\n        t.plan(25);\n\n        var xml = document.getElementById(\"ogcsample\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n\n        var obj = new OpenLayers.Format.WMSCapabilities().read(doc);\n        var capability = obj.capability;\n\n        var layers = {};\n        for (var i=0, len=capability.layers.length; i<len; i++) {\n            if (\"name\" in capability.layers[i]) {\n                layers[ capability.layers[i].name ] = capability.layers[i];\n            }\n        }\n\n        var rootlayer = capability.layers[ capability.layers.length - 1];\n\n        t.eq(rootlayer.srs,\n             {\"CRS:84\": true},\n             \"SRS parsed correctly for root layer\");\n        t.eq(layers[\"ROADS_RIVERS\"].srs,\n             {\"CRS:84\": true, \"EPSG:26986\": true},\n             \"Inheritance of SRS handled correctly when adding SRSes\");\n        t.eq(layers[\"Temperature\"].srs,\n             {\"CRS:84\": true},\n             \"Inheritance of SRS handled correctly when redeclaring an inherited SRS\");\n        t.eq(layers[\"Temperature\"].infoFormats, [\"text/xml\", \"text/plain\", \"text/html\"], \"infoFormats set correctly on layer\");\n        var bbox = layers[\"ROADS_RIVERS\"].bbox[\"EPSG:26986\"];\n        t.eq(bbox.bbox,\n             [189000, 834000, 285000, 962000],\n             \"Correct bbox from BoundingBox\");\n        t.eq(bbox.res, {x: 1, y: 1}, \"Correct resolution\");\n        bbox = layers[\"ROADS_RIVERS\"].bbox[\"CRS:84\"];\n        t.eq(bbox.bbox,\n             [-71.63, 41.75, -70.78, 42.90],\n             \"Correct bbox from BoundingBox (override)\");\n        t.eq(bbox.res, {x: 0.01, y: 0.01}, \"Correct resolution (override)\");\n\n        bbox = layers[\"ROADS_1M\"].bbox[\"EPSG:26986\"];\n        t.eq(bbox.bbox,\n             [189000, 834000, 285000, 962000],\n             \"Correctly inherited bbox\");\n        t.eq(bbox.res, {x: 1, y: 1}, \"Correctly inherited resolution\");\n\n\n        var identifiers = layers[\"ROADS_RIVERS\"].identifiers;\n        var authorities = layers[\"ROADS_RIVERS\"].authorityURLs;\n\n        t.ok(identifiers, \"got identifiers from layer ROADS_RIVERS\");\n        t.ok(\"DIF_ID\" in identifiers,\n             \"authority attribute from Identifiers parsed correctly\");\n        t.eq(identifiers[\"DIF_ID\"],\n             \"123456\",\n             \"Identifier value parsed correctly\");\n        t.ok(\"DIF_ID\" in authorities,\n             \"AuthorityURLs parsed and inherited correctly\");\n        t.eq(authorities[\"DIF_ID\"],\n             \"http://gcmd.gsfc.nasa.gov/difguide/whatisadif.html\",\n             \"OnlineResource in AuthorityURLs parsed correctly\");\n\n        var featurelist = layers[\"ROADS_RIVERS\"].featureListURL;\n        t.ok(featurelist, \"layer has FeatureListURL\");\n        t.eq(featurelist.format,\n             \"XML\",\n             \"FeatureListURL format parsed correctly\");\n        t.eq(featurelist.href,\n             \"http://www.university.edu/data/roads_rivers.gml\",\n             \"FeatureListURL OnlineResource parsed correctly\");\n\n        t.eq(layers[\"Pressure\"].queryable,\n             true,\n             \"queryable property inherited correctly\");\n        t.eq(layers[\"ozone_image\"].queryable,\n             false,\n             \"queryable property has correct default value\");\n        t.eq(layers[\"population\"].cascaded,\n             1,\n             \"cascaded property parsed correctly\");\n        t.eq(layers[\"ozone_image\"].fixedWidth,\n             512,\n             \"fixedWidth property correctly parsed\");\n        t.eq(layers[\"ozone_image\"].fixedHeight,\n             256,\n             \"fixedHeight property correctly parsed\");\n        t.eq(layers[\"ozone_image\"].opaque,\n             true,\n             \"opaque property parsed correctly\");\n        t.eq(layers[\"ozone_image\"].noSubsets,\n             true,\n             \"noSubsets property parsed correctly\");\n\n\n    }\n\n    function test_dimensions(t) {\n\n        t.plan(8);\n\n        var xml = document.getElementById(\"ogcsample\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n\n        var obj = new OpenLayers.Format.WMSCapabilities().read(doc);\n        var capability = obj.capability;\n\n        var layers = {};\n        for (var i=0, len=capability.layers.length; i<len; i++) {\n            if (\"name\" in capability.layers[i]) {\n                layers[ capability.layers[i].name ] = capability.layers[i];\n            }\n        }\n\n        var time = layers[\"Clouds\"].dimensions.time;\n        t.eq(time[\"default\"], \"2000-08-22\", \"Default time value parsed correctly\");\n        t.eq(time.values.length, 1, \"Currect number of time extent values/periods\");\n        t.eq(time.values[0], \"1999-01-01/2000-08-22/P1D\", \"Time extent values parsed correctly\");\n\n        var elevation = layers[\"Pressure\"].dimensions.elevation;\n        t.eq(elevation.units, \"CRS:88\", \"Dimension units parsed correctly\");\n        t.eq(elevation[\"default\"], \"0\", \"Default elevation value parsed correctly\");\n        t.eq(elevation.nearestVal, true, \"NearestValue parsed correctly\");\n        t.eq(elevation.multipleVal, false, \"Absense of MultipleValues handled correctly\");\n        t.eq(elevation.values,\n             [\"0\",\"1000\",\"3000\",\"5000\",\"10000\"],\n             \"Parsing of comma-separated values done correctly\");\n\n\n    }\n\n    function test_contactinfo(t) {\n        t.plan(14);\n\n        var xml = document.getElementById(\"ogcsample\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n\n        var obj = new OpenLayers.Format.WMSCapabilities().read(doc);\n        var service = obj.service;\n\n        var contactinfo = service.contactInformation;\n        t.ok(contactinfo, \"object contains contactInformation property\");\n\n        var personPrimary = contactinfo.personPrimary;\n        t.ok(personPrimary, \"object contains personPrimary property\");\n\n        t.eq(personPrimary.person, \"Jeff Smith\", \"ContactPerson parsed correctly\");\n        t.eq(personPrimary.organization, \"NASA\", \"ContactOrganization parsed correctly\");\n\n        t.eq(contactinfo.position,\n             \"Computer Scientist\",\n             \"ContactPosition parsed correctly\");\n\n\n        var addr = contactinfo.contactAddress;\n        t.ok(addr, \"object contains contactAddress property\");\n\n        t.eq(addr.type, \"postal\", \"AddressType parsed correctly\");\n        t.eq(addr.address,\n             \"NASA Goddard Space Flight Center\",\n             \"Address parsed correctly\");\n        t.eq(addr.city, \"Greenbelt\", \"City parsed correctly\");\n        t.eq(addr.stateOrProvince, \"MD\", \"StateOrProvince parsed correctly\");\n        t.eq(addr.postcode, \"20771\", \"PostCode parsed correctly\");\n        t.eq(addr.country, \"USA\", \"Country parsed correctly\");\n\n        t.eq(contactinfo.phone,\n             \"+1 301 555-1212\",\n             \"ContactVoiceTelephone parsed correctly\");\n        t.eq(contactinfo.email,\n             \"user@host.com\",\n             \"ContactElectronicMailAddress parsed correctly\");\n    }\n\n    function test_feesAndConstraints(t) {\n        t.plan(2);\n\n        var xml = document.getElementById(\"ogcsample\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n\n        var obj = new OpenLayers.Format.WMSCapabilities().read(doc);\n        var service = obj.service;\n\n        t.ok(! (\"fees\" in service), \"Fees=none handled correctly\");\n        t.ok(! (\"accessConstraints\" in service), \"AccessConstraints=none handled correctly\");\n    }\n\n    function test_requests(t) {\n        t.plan(6);\n\n        var xml = document.getElementById(\"ogcsample\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n\n        var obj = new OpenLayers.Format.WMSCapabilities().read(doc);\n        var request = obj.capability.request;\n\n        t.ok(request, \"request property exists\");\n        t.ok(\"getmap\" in request, \"got GetMap request\");\n\n        t.ok(\"getfeatureinfo\" in request, \"got GetFeatureInfo request\");\n        t.eq(request.getfeatureinfo.formats,\n             [\"text/xml\", \"text/plain\", \"text/html\"],\n             \"GetFeatureInfo formats correctly parsed\");\n\n        var exception = obj.capability.exception;\n        t.ok(exception, \"exception property exists\");\n        t.eq(exception.formats,\n             [\"XML\", \"INIMAGE\", \"BLANK\"],\n             \"Exception Format parsed\");\n    }\n\n    function test_ogc(t) {\n        t.plan(16);\n\n        /*\n         * Set up\n         */\n\n        // needed for the minScale/maxScale test, see below\n        var dpi = OpenLayers.DOTS_PER_INCH;\n        OpenLayers.DOTS_PER_INCH = 90.71;\n\n        var xml = document.getElementById(\"ogcsample\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n\n        var obj = new OpenLayers.Format.WMSCapabilities().read(doc);\n        var capability = obj.capability;\n\n        /*\n         * Test\n         */\n\n        var attribution = capability.layers[2].attribution;\n        t.eq(attribution.title, \"State College University\", \"attribution title parsed correctly.\");\n        t.eq(attribution.href, \"http://www.university.edu/\", \"attribution href parsed correctly.\")\n        t.eq(attribution.logo.href, \"http://www.university.edu/icons/logo.gif\", \"attribution logo url parsed correctly.\");\n        t.eq(attribution.logo.format, \"image/gif\", \"attribution logo format parsed correctly.\");\n        t.eq(attribution.logo.width, \"100\", \"attribution logo width parsed correctly.\");\n        t.eq(attribution.logo.height, \"100\", \"attribution logo height parsed correctly.\");\n\n        var keywords = capability.layers[0].keywords;\n        t.eq(keywords.length, 3, \"layer has 3 keywords.\");\n        t.eq(keywords[0].value, \"road\", \"1st keyword parsed correctly.\");\n\n        var metadataURLs = capability.layers[0].metadataURLs;\n        t.eq(metadataURLs.length, 2, \"layer has 2 metadata urls.\");\n        t.eq(metadataURLs[0].type, \"FGDC:1998\", \"type parsed correctly.\");\n        t.eq(metadataURLs[0].format, \"text/plain\", \"format parsed correctly.\");\n        t.eq(metadataURLs[0].href, \"http://www.university.edu/metadata/roads.txt\", \"href parsed correctly.\");\n\n        /*\n        Test minScale and maxScale\n        */\n        var minScale = 250000;\n        var maxScale = 1000;\n        t.eq(capability.layers[0].minScale, minScale.toPrecision(16), \"layer.minScale is correct\");\n        t.eq(capability.layers[0].maxScale, maxScale.toPrecision(16), \"layer.maxScale is correct\");\n\n        t.eq(capability.layers[3].minScale, undefined, \"layer.minScale for max='Infinity' is correct\");\n        t.eq(capability.layers[3].maxScale, undefined, \"layer.maxScale for min='0' is correct\");\n        /*\n         * Tear down\n         */\n\n        OpenLayers.DOTS_PER_INCH = dpi;\n    }\n\n    function test_WMS13specials(t) {\n        t.plan(3);\n\n        var xml = document.getElementById(\"ogcsample\").firstChild.nodeValue;\n        var doc = new OpenLayers.Format.XML().read(xml);\n\n        var obj = new OpenLayers.Format.WMSCapabilities().read(doc);\n\n        t.eq(obj.service.layerLimit, 16, \"LayerLimit parsed correctly\");\n        t.eq(obj.service.maxHeight, 2048, \"MaxHeight parsed correctly\");\n        t.eq(obj.service.maxWidth, 2048, \"MaxWidth parsed correctly\");\n\n    }\n\n    </script>\n</head>\n<body>\n\n<div id=\"exceptionsample\"><!--\n<?xml version='1.0' encoding=\"UTF-8\"?> \n<ServiceExceptionReport version=\"1.3.0\" xmlns=\"http://www.opengis.net/ogc\"\n    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n    xsi:schemaLocation=\"http://www.opengis.net/ogc\n    http://schemas.opengis.net/wms/1.3.0/exceptions_1_3_0.xsd\">\n    <ServiceException> Plain text message about an error. </ServiceException>\n    <ServiceException code=\"InvalidUpdateSequence\"> Another error message, this one with a service\n        exception code supplied. </ServiceException>\n    <ServiceException>\n        <![CDATA[ Error in module <foo.c>, line 42\nA message that includes angle brackets in text must be enclosed in a Character Data Section as in this example. All XML-like markup is ignored except for this sequence of three closing characters:\n]]>\n    </ServiceException>\n    <ServiceException>\n        <![CDATA[ <Module>foo.c</Module> <Error>An error occurred</Error> <Explanation>Similarly, actual XML can be enclosed in a CDATA section. A generic parser will ignore that XML, but application-specific software may choose to process it.</Explanation> ]]>\n    </ServiceException>\n</ServiceExceptionReport>\n--></div>\n\n<!--\nOGC example below taken from\nhttp://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xml\nChanges:\n-removed comments\n-corrected typo in FeatureListURL Format XML with double quote\n-added MinScaleDenominator and MaxScaleDenominator\n-remove whitespace in Dimension tags\n-->\n<div id=\"ogcsample\"><!--\n<?xml version='1.0' encoding=\"UTF-8\"?>\n<WMS_Capabilities version=\"1.3.0\" xmlns=\"http://www.opengis.net/wms\"\n  xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n  xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n  xsi:schemaLocation=\"http://www.opengis.net/wms http://schemas.opengis.net/wms/1.3.0/capabilities_1_3_0.xsd\">\n<Service>\n  <Name>WMS</Name>\n  <Title>Acme Corp. Map Server</Title>\n  <Abstract>Map Server maintained by Acme Corporation.  Contact: webmaster@wmt.acme.com.  High-quality maps showing roadrunner nests and possible ambush locations.</Abstract>\n\n  <KeywordList>\n    <Keyword>bird</Keyword>\n    <Keyword>roadrunner</Keyword>\n    <Keyword>ambush</Keyword>\n  </KeywordList>\n  <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\"\n   xlink:href=\"http://hostname/\" />\n\n\n  <ContactInformation>\n    <ContactPersonPrimary>\n      <ContactPerson>Jeff Smith</ContactPerson>\n      <ContactOrganization>NASA</ContactOrganization>\n    </ContactPersonPrimary>\n    <ContactPosition>Computer Scientist</ContactPosition>\n\n    <ContactAddress>\n      <AddressType>postal</AddressType>\n      <Address>NASA Goddard Space Flight Center</Address>\n      <City>Greenbelt</City>\n      <StateOrProvince>MD</StateOrProvince>\n      <PostCode>20771</PostCode>\n\n      <Country>USA</Country>\n    </ContactAddress>\n    <ContactVoiceTelephone>+1 301 555-1212</ContactVoiceTelephone>\n    <ContactElectronicMailAddress>user@host.com</ContactElectronicMailAddress>\n  </ContactInformation>\n\n  <Fees>none</Fees>\n\n  <AccessConstraints>none</AccessConstraints>\n  <LayerLimit>16</LayerLimit>\n  <MaxWidth>2048</MaxWidth>\n  <MaxHeight>2048</MaxHeight>\n</Service>\n<Capability>\n  <Request>\n    <GetCapabilities>\n\n      <Format>text/xml</Format>\n      <DCPType>\n        <HTTP>\n          <Get>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n             xlink:type=\"simple\"\n             xlink:href=\"http://hostname/path?\" />\n          </Get>\n          <Post>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n             xlink:type=\"simple\"\n             xlink:href=\"http://hostname/path?\" />\n\n          </Post>\n        </HTTP>\n      </DCPType>\n    </GetCapabilities>\n    <GetMap>\n      <Format>image/gif</Format>\n      <Format>image/png</Format>\n      <Format>image/jpeg</Format>\n\n      <DCPType>\n        <HTTP>\n          <Get>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n             xlink:type=\"simple\"\n             xlink:href=\"http://hostname/path?\" />\n          </Get>\n        </HTTP>\n      </DCPType>\n    </GetMap>\n\n    <GetFeatureInfo>\n      <Format>text/xml</Format>\n      <Format>text/plain</Format>\n      <Format>text/html</Format>\n      <DCPType>\n        <HTTP>\n          <Get>\n\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n             xlink:type=\"simple\"\n             xlink:href=\"http://hostname/path?\" />\n          </Get>\n        </HTTP>\n      </DCPType>\n    </GetFeatureInfo>\n  </Request>\n  <Exception>\n    <Format>XML</Format>\n\n    <Format>INIMAGE</Format>\n    <Format>BLANK</Format>\n  </Exception>\n  <Layer>\n    <Title>Acme Corp. Map Server</Title>\n    <CRS>CRS:84</CRS>\n\n    <AuthorityURL name=\"DIF_ID\">\n      <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\"\n       xlink:href=\"http://gcmd.gsfc.nasa.gov/difguide/whatisadif.html\" />\n    </AuthorityURL>\n    <BoundingBox CRS=\"CRS:84\"\n     minx=\"-1\" miny=\"-1\" maxx=\"1\" maxy=\"1\" resx=\"0.0\" resy=\"0.0\"/>\n    <Layer>\n\n      <Name>ROADS_RIVERS</Name>\n      <Title>Roads and Rivers</Title>\n\n      <CRS>EPSG:26986</CRS>\n      <EX_GeographicBoundingBox>\n        <westBoundLongitude>-71.63</westBoundLongitude>\n        <eastBoundLongitude>-70.78</eastBoundLongitude>\n        <southBoundLatitude>41.75</southBoundLatitude>\n        <northBoundLatitude>42.90</northBoundLatitude>\n\n      </EX_GeographicBoundingBox>\n      <BoundingBox CRS=\"CRS:84\"\n       minx=\"-71.63\" miny=\"41.75\" maxx=\"-70.78\" maxy=\"42.90\" resx=\"0.01\" resy=\"0.01\"/>\n      <BoundingBox CRS=\"EPSG:26986\"\n       minx=\"189000\" miny=\"834000\" maxx=\"285000\" maxy=\"962000\" resx=\"1\" resy=\"1\" />\n      <Attribution>\n        <Title>State College University</Title>\n        <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\"\n         xlink:href=\"http://www.university.edu/\" />\n\n        <LogoURL width=\"100\" height=\"100\">\n          <Format>image/gif</Format>\n          <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n           xlink:type=\"simple\"\n           xlink:href=\"http://www.university.edu/icons/logo.gif\" />\n        </LogoURL>\n      </Attribution>\n      <Identifier authority=\"DIF_ID\">123456</Identifier>\n      <FeatureListURL>\n\n        <Format>XML</Format>\n        <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\"\n         xlink:href=\"http://www.university.edu/data/roads_rivers.gml\" />\n      </FeatureListURL>\n      <Style>\n        <Name>USGS</Name>\n        <Title>USGS Topo Map Style</Title>\n        <Abstract>Features are shown in a style like that used in USGS topographic maps.</Abstract>\n\n        <LegendURL width=\"72\" height=\"72\">\n          <Format>image/gif</Format>\n          <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n           xlink:type=\"simple\"\n           xlink:href=\"http://www.university.edu/legends/usgs.gif\" />\n        </LegendURL>\n        <StyleSheetURL>\n          <Format>text/xsl</Format>\n\n          <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n           xlink:type=\"simple\"\n           xlink:href=\"http://www.university.edu/stylesheets/usgs.xsl\" />\n        </StyleSheetURL>\n      </Style>\n      <MinScaleDenominator>1000</MinScaleDenominator>\n      <MaxScaleDenominator>250000</MaxScaleDenominator>\n      <Layer queryable=\"1\">\n        <Name>ROADS_1M</Name>\n        <Title>Roads at 1:1M scale</Title>\n        <Abstract>Roads at a scale of 1 to 1 million.</Abstract>\n\n        <KeywordList>\n          <Keyword>road</Keyword>\n          <Keyword>transportation</Keyword>\n          <Keyword>atlas</Keyword>\n        </KeywordList>\n        <Identifier authority=\"DIF_ID\">123456</Identifier>\n        <MetadataURL type=\"FGDC:1998\">\n\n                <Format>text/plain</Format>\n                <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n                 xlink:type=\"simple\"\n                 xlink:href=\"http://www.university.edu/metadata/roads.txt\" />\n             </MetadataURL>\n        <MetadataURL type=\"ISO19115:2003\">\n               <Format>text/xml</Format>\n               <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n                xlink:type=\"simple\"\n                xlink:href=\"http://www.university.edu/metadata/roads.xml\" />\n             </MetadataURL>\n\n        <Style>\n          <Name>ATLAS</Name>\n          <Title>Road atlas style</Title>\n          <Abstract>Roads are shown in a style like that used in a commercial road atlas.</Abstract>\n        <LegendURL width=\"72\" height=\"72\">\n          <Format>image/gif</Format>\n          <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\"\n           xlink:type=\"simple\"\n           xlink:href=\"http://www.university.edu/legends/atlas.gif\" />\n\n        </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>RIVERS_1M</Name>\n        <Title>Rivers at 1:1M scale</Title>\n        <Abstract>Rivers at a scale of 1 to 1 million.</Abstract>\n\n        <KeywordList>\n          <Keyword>river</Keyword>\n          <Keyword>canal</Keyword>\n          <Keyword>waterway</Keyword>\n        </KeywordList>\n      </Layer>\n    </Layer>\n\n    <Layer queryable=\"1\">\n      <Title>Weather Forecast Data</Title>\n      <CRS>CRS:84</CRS>\n\n      <EX_GeographicBoundingBox>\n        <westBoundLongitude>-180</westBoundLongitude>\n        <eastBoundLongitude>180</eastBoundLongitude>\n\n        <southBoundLatitude>-90</southBoundLatitude>\n        <northBoundLatitude>90</northBoundLatitude>\n      </EX_GeographicBoundingBox>\n      <Dimension name=\"time\" units=\"ISO8601\" default=\"2000-08-22\">1999-01-01/2000-08-22/P1D</Dimension>\n      <MinScaleDenominator>0.0</MinScaleDenominator>\n      <MaxScaleDenominator>Infinity</MaxScaleDenominator>\n      <Layer>\n\n        <Name>Clouds</Name>\n        <Title>Forecast cloud cover</Title>\n      </Layer>\n      <Layer>\n        <Name>Temperature</Name>\n        <Title>Forecast temperature</Title>\n      </Layer>\n\n      <Layer>\n        <Name>Pressure</Name>\n        <Title>Forecast barometric pressure</Title>\n         <Dimension name=\"elevation\" units=\"EPSG:5030\" />\n         <Dimension name=\"time\" units=\"ISO8601\" default=\"2000-08-22\">\n           1999-01-01/2000-08-22/P1D</Dimension>\n\n         <Dimension name=\"elevation\" units=\"CRS:88\" default=\"0\" nearestValue=\"1\">0,1000,3000,5000,10000</Dimension>\n      </Layer>\n    </Layer>\n    <Layer opaque=\"1\" noSubsets=\"1\" fixedWidth=\"512\" fixedHeight=\"256\">\n      <Name>ozone_image</Name>\n      <Title>Global ozone distribution (1992)</Title>\n\n      <EX_GeographicBoundingBox>\n        <westBoundLongitude>-180</westBoundLongitude>\n        <eastBoundLongitude>180</eastBoundLongitude>\n        <southBoundLatitude>-90</southBoundLatitude>\n        <northBoundLatitude>90</northBoundLatitude>\n      </EX_GeographicBoundingBox>\n      <Dimension name=\"time\" units=\"ISO8601\" default=\"1992\">1992</Dimension>\n\n    </Layer>\n    <Layer cascaded=\"1\">\n      <Name>population</Name>\n      <Title>World population, annual</Title>\n      <EX_GeographicBoundingBox>\n        <westBoundLongitude>-180</westBoundLongitude>\n\n        <eastBoundLongitude>180</eastBoundLongitude>\n        <southBoundLatitude>-90</southBoundLatitude>\n        <northBoundLatitude>90</northBoundLatitude>\n      </EX_GeographicBoundingBox>\n      <Dimension name=\"time\" units=\"ISO8601\" default=\"2000\">1990/2000/P1Y</Dimension>\n    </Layer>\n  </Layer>\n\n</Capability>\n</WMS_Capabilities>\n--></div>\n\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WMSCapabilities.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    \n    function test_initialize(t) {\n        \n        t.plan(1);\n        var format = new OpenLayers.Format.WMSCapabilities({\n            version: \"foo\"\n        });\n        t.eq(format.version, \"foo\", \"version set on format\");\n        \n    }\n    \n    </script> \n</head> \n<body>\n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WMSDescribeLayer.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    \n    function test_read_WMSDescribeLayer(t) {\n        t.plan(10);\n       \n        var parser = new OpenLayers.Format.WMSDescribeLayer();\n\n        var text =\n            '<WMS_DescribeLayerResponse version=\"1.1.1\">' +\n            '  <LayerDescription name=\"topp:states\" wfs=\"http://geo.openplans.org:80/geoserver/wfs/WfsDispatcher?\">' +\n            '    <Query typeName=\"topp:states\"/>' +\n            '  </LayerDescription>' +\n            '</WMS_DescribeLayerResponse>';\n\n        var res = parser.read(text);\n\n        t.eq(res.layerDescriptions.length, 1,\n            \"Only one LayerDescription in data, so only one parsed\");\n\n        t.eq(res.layerDescriptions[0].owsType, \"WFS\",\n            \"Properly parses owsType as WFS\");\n\n        t.eq(res.layerDescriptions[0].owsURL, \"http://geo.openplans.org:80/geoserver/wfs/WfsDispatcher?\",\n            \"Properly parses owsURL\");\n\n        t.eq(res.layerDescriptions[0].typeName, \"topp:states\",\n            \"Properly parses typeName\");\n\n        t.eq(res.layerDescriptions[0].layerName, \"topp:states\",\n            \"Properly parses name\");\n        \n        //TODO remove the 5 tests below when we deprecate the old structure\n        t.eq(res.length, 1,\n            \"Only one LayerDescription in data, so only one parsed\");\n        t.eq(res[0].owsType, \"WFS\",\n            \"Properly parses owsType as WFS\");\n        t.eq(res[0].owsURL, \"http://geo.openplans.org:80/geoserver/wfs/WfsDispatcher?\",\n            \"Properly parses owsURL\");\n        t.eq(res[0].typeName, \"topp:states\",\n            \"Properly parses typeName\");\n        t.eq(res[0].layerName, \"topp:states\",\n            \"Properly parses name\");\n\n    }\n\n    function test_read_exception(t) {\n        t.plan(1);\n        var text = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>' +\n            '<!DOCTYPE ServiceExceptionReport SYSTEM \"http://schemas.opengis.net/wms/1.1.1/WMS_exception_1_1_1.dtd\">' +\n            '<ServiceExceptionReport version=\"1.1.1\" >   <ServiceException code=\"LayerNotDefined\">' +\n            'geonode:_map_107_annotations: no such layer on this server' +\n            '</ServiceException></ServiceExceptionReport>';\n        var format = new OpenLayers.Format.WMSDescribeLayer();\n        var obj = format.read(text);\n        t.ok(!!obj.error, \"Error reported correctly\");\n    }\n\n    </script> \n</head> \n<body>\n</body> \n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WMSGetFeatureInfo.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_read_FeatureInfoResponse(t) {\n        t.plan(7);\n\n        var parser = new OpenLayers.Format.WMSGetFeatureInfo();\n\n        // read empty response\n        var text =\n            '<?xml version=\"1.0\" encoding=\"UTF-8\" ?>' +\n            '<FeatureInfoResponse>' +\n            '</FeatureInfoResponse>';\n\n        var features = parser.read(text);\n        t.eq(features.length, 0,\n             \"Parsing empty FeatureInfoResponse response succesfull\");\n\n        // read 1 feature\n        text =\n            '<?xml version=\"1.0\" encoding=\"UTF-8\" ?>' +\n            '<FeatureInfoResponse>' +\n            '  <FIELDS OBJECTID=\"1188\" HECTARES=\"1819.734\" ZONENR=\"5854\" NULZONES=\" \" AREA=\"18197340.1426\" PERIMETER=\"19177.4073627\" SHAPE=\"NULL\" SE_ANNO_CAD_DATA=\"NULL\" SHAPE.AREA=\"0\" SHAPE.LEN=\"0\"/>' +\n            '</FeatureInfoResponse>';\n\n        features = parser.read(text);\n        t.eq(features.length, 1,\n             \"Parsed 1 feature in total\");\n\n        t.eq(features[0].attributes.OBJECTID, '1188',\n             \"Attribute OBJECTID contains the right value\");\n\n        // read multiple features\n        text =\n            '<?xml version=\"1.0\" encoding=\"UTF-8\" ?>' +\n            '<FeatureInfoResponse>' +\n            '  <FIELDS OBJECTID=\"551\" Shape=\"NULL\" NAME=\"Carbon\" STATE_NAME=\"Wyoming\" AREA=\"7999.91062\" POP2000=\"15639\" POP00_SQMI=\"2\" Shape_Length=\"6.61737274334215\" Shape_Area=\"2.23938983524154\"/>' +\n            '  <FIELDS OBJECTID=\"7\" Shape=\"NULL\" AREA=\"97803.199\" STATE_NAME=\"Wyoming\" SUB_REGION=\"Mtn\" STATE_ABBR=\"WY\" POP2000=\"493782\" POP00_SQMI=\"5\" Shape_Length=\"21.9870297323522\" Shape_Area=\"27.9666881382635\"/>' +\n            '  <FIELDS OBJECTID=\"99\" Shape=\"NULL\" LENGTH=\"378.836\" TYPE=\"Multi-Lane Divided\" ADMN_CLASS=\"Interstate\" TOLL_RD=\"N\" RTE_NUM1=\" 80\" RTE_NUM2=\" \" ROUTE=\"Interstate  80\" Shape_Length=\"7.04294883879398\"/>' +\n            '</FeatureInfoResponse>';\n\n        features = parser.read(text);\n\n        t.eq(features.length, 3,\n             \"Parsed 3 features in total\");\n\n        t.eq(features[1].attributes.STATE_NAME, 'Wyoming',\n             \"Attribute STATE_NAME contains the right value\");\n\n        text = '<FeatureInfoResponse>' +\n            '<FIELDS>' +\n            '<FIELD name=\"ID\" value=\"B31A0154\"/>' +\n            '<FIELD name=\"FID\" value=\"31AL0011\"/>' +\n            '</FIELDS>' +\n            '<FIELDS>' +\n            '<FIELD name=\"ID\" value=\"B31A0153\"/>' +\n            '<FIELD name=\"FID\" value=\"31AL0011\"/>' +\n            '</FIELDS>' +\n            '</FeatureInfoResponse>';\n\n        features = parser.read(text);\n\n        t.eq(features.length, 2,\n             \"Parsed 2 features in total\");\n\n        t.eq(features[1].attributes.FID, '31AL0011',\n             \"Attribute FID contains the right value\");\n\n    }\n\n    function test_read_msGMLOutput(t) {\n        t.plan(14);\n\n        var parser = new OpenLayers.Format.WMSGetFeatureInfo();\n\n        // read empty response\n        var text =\n            '<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>' +\n            '<msGMLOutput ' +\n            '\t xmlns:gml=\"http://www.opengis.net/gml\"' +\n            '\t xmlns:xlink=\"http://www.w3.org/1999/xlink\"' +\n            '\t xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">' +\n            '</msGMLOutput>';\n\n        var features = parser.read(text);\n        t.eq(features.length, 0,\n             \"Parsing empty msGMLOutput response succesfull\");\n\n        // read empty attribute\n        text =\n            '<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>' +\n            '<msGMLOutput ' +\n            '    xmlns:gml=\"http://www.opengis.net/gml\"' +\n            '    xmlns:xlink=\"http://www.w3.org/1999/xlink\"' +\n            '    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">' +\n            '   <AAA64_layer>' +\n            '           <AAA64_feature>' +\n            '                   <gml:boundedBy>' +\n            '                           <gml:Box srsName=\"EPSG:28992\">' +\n            '                                   <gml:coordinates>107397.266000,460681.063000 116568.188000,480609.250000</gml:coordinates>' +\n            '                           </gml:Box>' +\n            '                   </gml:boundedBy>' +\n            '                   <FOO>bar</FOO>' +\n            '                   <EMPTY></EMPTY>' +\n            '           </AAA64_feature>' +\n            '   </AAA64_layer>' +\n            '</msGMLOutput>';\n        features = parser.read(text);\n        t.eq((features[0].attributes.EMPTY === null), true, \"Empty attribute is parsed as null\");\n\n        // read 1 feature from 1 layer\n        text =\n            '<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>' +\n            '<msGMLOutput ' +\n            '\t xmlns:gml=\"http://www.opengis.net/gml\"' +\n            '\t xmlns:xlink=\"http://www.w3.org/1999/xlink\"' +\n            '\t xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">' +\n            '\t<AAA64_layer>' +\n            '\t\t<AAA64_feature>' +\n            '\t\t\t<gml:boundedBy>' +\n            '\t\t\t\t<gml:Box srsName=\"EPSG:28992\">' +\n            '\t\t\t\t\t<gml:coordinates>107397.266000,460681.063000 116568.188000,480609.250000</gml:coordinates>' +\n            '\t\t\t\t</gml:Box>' +\n            '\t\t\t</gml:boundedBy>' +\n            '\t\t\t<OBJECTID>109</OBJECTID>' +\n            '\t\t\t<ROUTE>N231</ROUTE>' +\n            '\t\t\t<ROUTE_CH>#N231</ROUTE_CH>' +\n            '\t\t\t<COUNT>2</COUNT>' +\n            '\t\t\t<BEHEERDER>P</BEHEERDER>' +\n            '\t\t\t<LENGTH>28641.7</LENGTH>' +\n            '\t\t\t<SHAPE>&lt;shape&gt;</SHAPE>' +\n            '\t\t\t<SE_ANNO_CAD_DATA>&lt;null&gt;</SE_ANNO_CAD_DATA>' +\n            '\t\t</AAA64_feature>' +\n            '\t</AAA64_layer>' +\n            '</msGMLOutput>';\n\n        features = parser.read(text);\n\n        t.eq(features.length, 1,\n             \"Parsed 1 feature in total\");\n\n        t.eq(features[0].attributes.OBJECTID, '109',\n             \"Attribute OBJECTID contains the right value\");\n\n        t.eq(features[0].type, 'AAA64',\n             \"Parsed the layer name correctly\");\n\n        var bounds = features[0].bounds;\n        t.ok(bounds instanceof OpenLayers.Bounds, \"feature given a bounds\");\n        t.eq(bounds.left.toFixed(3), \"107397.266\", \"Bounds left parsed correctly\");\n        t.eq(bounds.right.toFixed(3), \"116568.188\", \"Bounds right parsed correctly\");\n        t.eq(bounds.bottom.toFixed(3), \"460681.063\", \"Bounds bottom parsed correctly\");\n        t.eq(bounds.top.toFixed(3), \"480609.250\", \"Bounds top parsed correctly\");\n\n        // read 2 features from 2 layers\n        text =\n            '<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>' +\n            '<msGMLOutput ' +\n            '\t xmlns:gml=\"http://www.opengis.net/gml\"' +\n            '\t xmlns:xlink=\"http://www.w3.org/1999/xlink\"' +\n            '\t xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">'+\n            '\t<AAA64_layer>' +\n            '\t\t<AAA64_feature>' +\n            '\t\t\t<gml:boundedBy>' +\n            '\t\t\t\t<gml:Box srsName=\"EPSG:28992\">' +\n            '\t\t\t\t\t<gml:coordinates>129799.109000,467950.250000 133199.906000,468904.063000</gml:coordinates>' +\n            '\t\t\t\t</gml:Box>' +\n            '\t\t\t</gml:boundedBy>' +\n            '\t\t\t<OBJECTID>287</OBJECTID>' +\n            '\t\t\t<ROUTE>N403</ROUTE>' +\n            '\t\t\t<ROUTE_CH>#N403</ROUTE_CH>' +\n            '\t\t\t<COUNT>1</COUNT>' +\n            '\t\t\t<BEHEERDER>P</BEHEERDER>' +\n            '\t\t\t<LENGTH>4091.25</LENGTH>' +\n            '\t\t\t<SHAPE>&lt;shape&gt;</SHAPE>' +\n            '\t\t\t<SE_ANNO_CAD_DATA>&lt;null&gt;</SE_ANNO_CAD_DATA>' +\n            '\t\t</AAA64_feature>' +\n            '\t</AAA64_layer>' +\n            '\t<AAA62_layer>' +\n            '\t\t<AAA62_feature>' +\n            '\t\t\t<gml:boundedBy>' +\n            '\t\t\t\t<gml:Box srsName=\"EPSG:28992\">' +\n            '\t\t\t\t\t<gml:coordinates>129936.000000,468362.000000 131686.000000,473119.000000</gml:coordinates>' +\n            '\t\t\t\t</gml:Box>' +\n            '\t\t\t</gml:boundedBy>' +\n            '\t\t\t<OBJECTID>1251</OBJECTID>' +\n            '\t\t\t<VWK_ID>1515</VWK_ID>' +\n            '\t\t\t<VWK_BEGDTM>00:00:00 01/01/1998</VWK_BEGDTM>' +\n            '\t\t\t<VWJ_ID_BEG>1472</VWJ_ID_BEG>' +\n            '\t\t\t<VWJ_ID_END>1309</VWJ_ID_END>' +\n            '\t\t\t<VAKTYPE>D</VAKTYPE>' +\n            '\t\t\t<VRT_CODE>227</VRT_CODE>' +\n            '\t\t\t<VRT_NAAM>Vecht</VRT_NAAM>' +\n            '\t\t\t<VWG_NR>2</VWG_NR>' +\n            '\t\t\t<VWG_NAAM>Vecht</VWG_NAAM>' +\n            '\t\t\t<BEGKM>18.25</BEGKM>' +\n            '\t\t\t<ENDKM>23.995</ENDKM>' +\n            '\t\t\t<LENGTH>5745.09</LENGTH>' +\n            '\t\t\t<SHAPE>&lt;shape&gt;</SHAPE>' +\n            '\t\t\t<SE_ANNO_CAD_DATA>&lt;null&gt;</SE_ANNO_CAD_DATA>' +\n            '\t\t</AAA62_feature>' +\n            '\t</AAA62_layer>' +\n            '</msGMLOutput>';\n\n        features = parser.read(text);\n\n        t.eq(features.length, 2,\n             \"Parsed 2 features in total\");\n\n        t.eq((features[0].type == features[1].type), false,\n             \"The layer name differs for the two features\");\n\n        text =\n            '<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>' +\n            '<msGMLOutput ' +\n            '        xmlns:gml=\"http://www.opengis.net/gml\"' +\n            '        xmlns:xlink=\"http://www.w3.org/1999/xlink\"' +\n            '        xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">' +\n            '       <wegbeheerderinfo_layer>' +\n            '               <wegbeheerderinfo_feature>' +\n            '                       <gml:boundedBy>' +\n            '                               <gml:Box srsName=\"EPSG:28992\">' +\n            '                                       <gml:coordinates>105002.943000,490037.863000 105271.523000,490262.208000</gml:coordinates>' +\n            '                               </gml:Box>' +\n            '                       </gml:boundedBy>' +\n            '                       <geometry>' +\n            '                       <gml:MultiLineString srsName=\"EPSG:28992\">' +\n            '                         <gml:lineStringMember>' +\n            '                           <gml:LineString>' +\n            '                             <gml:coordinates>105270.164000,490262.208000 105098.274000,490258.040000 105028.045000,490089.576000 105002.943000,490048.851000 105049.666000,490037.863000 105271.523000,490064.957000 </gml:coordinates>' +\n            '                           </gml:LineString>' +\n            '                         </gml:lineStringMember>' +\n            '                       </gml:MultiLineString>' +\n            '                       </geometry>' +\n            '                       <OGR_FID>203327</OGR_FID>' +\n            '               </wegbeheerderinfo_feature>' +\n            '       </wegbeheerderinfo_layer>' +\n            '</msGMLOutput>';\n\n        features = parser.read(text);\n\n        t.eq((features[0].geometry instanceof OpenLayers.Geometry.MultiLineString), true,\n            \"Parsed geometry is of type multi line string\");\n\n        t.eq(features[0].attributes, {'OGR_FID': '203327'},\n             \"Attributes values are correct, and hasn't additional attribute\");\n\n    }\n\n    function test_read_GMLFeatureInfoResponse(t) {\n        t.plan(4);\n\n        var parser = new OpenLayers.Format.WMSGetFeatureInfo();\n\n        // read Ionic response, see if parser falls back to GML format\n        // url used:\n        /* http://webservices.ionicsoft.com/ionicweb/wfs/BOSTON_ORA?service=WMS&request=GetFeatureInfo&layers=roads&version=1.1.1&bbox=-71.1,42.25,-71.05,42.3&width=500&height=500&format=image/png&SRS=EPSG:4326&styles=&x=174&y=252&query_layers=roads&info_format=application/vnd.ogc.gml */\n        var text =\n            \"<?xml version='1.0' encoding='utf-8' ?>\" +\n            '  <ogcwfs:FeatureCollection xsi:schemaLocation=\"http://www.ionicsoft.com/wfs http://webservices.ionicsoft.com/ionicweb/wfs/BOSTON_ORA?REQUEST=DescribeAllFeatureType&amp;SERVICE=WFS http://www.opengis.net/wfs http://webservices.ionicsoft.com/ionicweb/wfs/BOSTON_ORA/REQUEST/get/DATA/LPR/wfs/1.0.0/WFS-basic.xsd\" xmlns:wfs=\"http://www.ionicsoft.com/wfs\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:ogcwfs=\"http://www.opengis.net/wfs\">' +\n            '    <gml:boundedBy>' +\n            '      <gml:Box srsName=\"EPSG:4326\">' +\n            '        <gml:coordinates>-71.08301710045646,42.27320863544783 -71.08020014900377,42.27480054530114</gml:coordinates>' +\n            '      </gml:Box>' +\n            '    </gml:boundedBy>' +\n            '  <gml:featureMember>' +\n            '    <wfs:roads fid=\"roads.9453.0\">' +\n            '      <wfs:FNODE_>8943.0</wfs:FNODE_>' +\n            '      <wfs:TNODE_>9070.0</wfs:TNODE_>' +\n            '      <wfs:LPOLY_>0.0</wfs:LPOLY_>' +\n            '      <wfs:RPOLY_>0.0</wfs:RPOLY_>' +\n            '      <wfs:LENGTH>306.875</wfs:LENGTH>' +\n            '      <wfs:MRD_>13109.0</wfs:MRD_>' +\n            '      <wfs:MRD_ID>9453.0</wfs:MRD_ID>' +\n            '      <wfs:TILE_NAME>126</wfs:TILE_NAME>' +\n            '      <wfs:COUNTYCODE>M</wfs:COUNTYCODE>' +\n            '      <wfs:SERIAL_NUM>26000.0</wfs:SERIAL_NUM>' +\n            '      <wfs:CLASS>5.0</wfs:CLASS>' +\n            '      <wfs:ADMIN_TYPE>0.0</wfs:ADMIN_TYPE>' +\n            '      <wfs:ALTRT1TYPE>0.0</wfs:ALTRT1TYPE>' +\n            '      <wfs:STREETNAME>DOCTOR MARY MOORE BEATTY CIRCLE</wfs:STREETNAME>' +\n            '      <wfs:CSN>M  26000</wfs:CSN>' +\n            '      <wfs:GEOMETRY>' +\n            '        <gml:LineString srsName=\"EPSG:4326\">' +\n            '          <gml:coordinates>-71.08300668868151,42.27480054530114 -71.08155305289881,42.27452010256956 -71.08021063085208,42.27320863544783</gml:coordinates>' +\n            '        </gml:LineString>' +\n            '      </wfs:GEOMETRY>' +\n            '    </wfs:roads>' +\n            '  </gml:featureMember>' +\n            '  </ogcwfs:FeatureCollection>';\n\n        var features = parser.read(text);\n\n        t.eq(features.length, 1,\n             \"Parsing GML GetFeatureInfo response from Ionic succesfull\");\n\n        t.eq(features[0].attributes.TILE_NAME, '126',\n             \"Attribute TILE_NAME contains the right value\");\n\n        // read Geoserver response\n        // taken from:\n/* http://demo.opengeo.org/geoserver/wms?service=WMS&request=GetFeatureInfo&layers=opengeo:roads&query_layers=opengeo:roads&format=image/png&version=1.1.1&styles=&bbox=-103.9,44.4,-103.7,44.5&srs=EPSG:4326&width=500&height=500&x=158&y=98&info_format=application/vnd.ogc.gml*/\n\n        text = '<?xml version=\"1.0\" encoding=\"UTF-8\"?><wfs:FeatureCollection xmlns=\"http://www.opengis.net/wfs\" xmlns:wfs=\"http://www.opengis.net/wfs\" xmlns:opengeo=\"http://opengeo.org\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://opengeo.org http://demo.opengeo.org:80/geoserver/wfs?service=WFS&amp;version=1.0.0&amp;request=DescribeFeatureType&amp;typeName=opengeo:roads http://www.opengis.net/wfs http://demo.opengeo.org:80/geoserver/schemas/wfs/1.0.0/WFS-basic.xsd\"><gml:boundedBy><gml:Box srsName=\"http://www.opengis.net/gml/srs/epsg.xml#26713\"><gml:coordinates xmlns:gml=\"http://www.opengis.net/gml\" decimal=\".\" cs=\",\" ts=\" \">591943.9375,4925605 593045.625,4925845</gml:coordinates></gml:Box></gml:boundedBy><gml:featureMember><opengeo:roads fid=\"roads.90\"><opengeo:cat>3</opengeo:cat><opengeo:label>secondary highway, hard surface</opengeo:label><opengeo:the_geom><gml:MultiLineString srsName=\"http://www.opengis.net/gml/srs/epsg.xml#26713\"><gml:lineStringMember><gml:LineString><gml:coordinates xmlns:gml=\"http://www.opengis.net/gml\" decimal=\".\" cs=\",\" ts=\" \">593045.60746465,4925605.0059156 593024.32382915,4925606.79305411 592907.54863574,4925624.85647524 592687.35111096,4925670.76834012 592430.76279218,4925678.79393165 592285.97636109,4925715.70811767 592173.39165655,4925761.83511156 592071.1753393,4925793.95523514 591985.96972625,4925831.59842486 591943.98769455,4925844.93220071</gml:coordinates></gml:LineString></gml:lineStringMember></gml:MultiLineString></opengeo:the_geom></opengeo:roads></gml:featureMember></wfs:FeatureCollection>';\n\n        features = parser.read(text);\n\n        t.eq(features.length, 1,\n             \"Parsing GML GetFeatureInfo response from Geoserver succesfull\");\n\n        t.eq(features[0].attributes.cat, '3',\n             \"Attribute cat contains the right value\");\n\n    }\n\n    function test_read_big_msGMLOutput(t) {\n        t.plan(3);\n\n        var parser = new OpenLayers.Format.WMSGetFeatureInfo();\n\n        // read empty attribute\n        var text =\n            '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n            '<msGMLOutput ' +\n            '     xmlns:gml=\"http://www.opengis.net/gml\"' +\n            '     xmlns:xlink=\"http://www.w3.org/1999/xlink\"' +\n            '     xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">' +\n            '    <name_layer>' +\n            '        <name_feature>' +\n            '            <gml:boundedBy>' +\n            '                <gml:Box srsName=\"EPSG:21781\">' +\n            '                    <gml:coordinates>532872.675514,152459.106373 532879.550514,152465.871373</gml:coordinates>' +\n            '                </gml:Box>' +\n            '            </gml:boundedBy>' +\n            '            <html>';\n        for (var i = 0 ; i < 7000 ; i++) {\n            text += 'a';\n        }\n        text +=\n            '</html>' +\n            '        </name_feature>' +\n            '    </name_layer>' +\n            '</msGMLOutput>';\n\n        var features = parser.read(text);\n\n        t.eq(features.length, 1,\n             \"Parsed 1 feature in total\");\n        t.ok(features[0].attributes.html,\n             \"Attribute html exists\");\n        t.eq(features[0].attributes.html.length, 7000,\n             \"Attribute html have the right length\");\n    }\n\n\n    function test_read_QGISOutput(t) {\n        t.plan(4);\n\n        var parser = new OpenLayers.Format.WMSGetFeatureInfo();\n\n        var text =\n            '<wfs:FeatureCollection xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:wfs=\"http://www.opengis.net/wfs\" xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/wfs.xsd http://www.qgis.org/gml\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:ows=\"http://www.opengis.net/ows\" xmlns:qgs=\"http://www.qgis.org/gml\">' +\n            ' <gml:featureMember>' +\n            '  <qgs:camera fid=\"camera.15\">' +\n            '   <qgs:gid>15</qgs:gid>' +\n            '   <qgs:id>i15</qgs:id>' +\n            '  </qgs:camera>' +\n            ' </gml:featureMember>' +\n            '</wfs:FeatureCollection>';\n\n        var features = parser.read(text);\n\n        t.eq(features.length, 1,\n             \"Parsed 1 feature in total\");\n        t.eq(features[0].type, 'camera',\n             \"Attribute type contains the right value\");\n        t.eq(features[0].attributes.gid, '15',\n             \"Attribute gid contains the right value\");\n        t.eq(features[0].attributes.id, 'i15',\n             \"Attribute id contains the right value\");\n    }\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WMTSCapabilities/v1_0_0.html",
    "content": "<html>\n<head>\n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n        function test_ows(t) {\n            t.plan(20);\n            var xml = document.getElementById(\"ogcsample\").firstChild.nodeValue;\n            var doc = new OpenLayers.Format.XML().read(xml);\n            var obj = new OpenLayers.Format.WMTSCapabilities().read(doc);\n            // ows:ServiceIdentification\n            var serviceIdentification = obj.serviceIdentification;\n            t.eq(serviceIdentification.title, \"Web Map Tile Service\", \"ows:ServiceIdentification title is correct\");\n            t.eq(serviceIdentification.serviceTypeVersion, \"1.0.0\", \"ows:ServiceIdentification serviceTypeVersion is correct\");\n            t.eq(serviceIdentification.serviceType.value, \"OGC WMTS\", \"ows:ServiceIdentification serviceType is correct\");\n\n            // ows:ServiceProvider\n            var serviceProvider = obj.serviceProvider;\n            t.eq(serviceProvider.providerName, \"MiraMon\", \"ows:ServiceProvider providerName is correct\");\n            t.eq(serviceProvider.providerSite, \"http://www.creaf.uab.es/miramon\", \"ows:ServiceProvider providerSite is correct\");\n            t.eq(serviceProvider.serviceContact.individualName, \"Joan Maso Pau\", \"ows:ServiceProvider individualName is correct\");\n            t.eq(serviceProvider.serviceContact.positionName, \"Senior Software Engineer\", \"ows:ServiceProvider positionName is correct\");\n            t.eq(serviceProvider.serviceContact.contactInfo.address.administrativeArea, \"Barcelona\", \"ows:ServiceProvider address administrativeArea is correct\");\n            t.eq(serviceProvider.serviceContact.contactInfo.address.city, \"Bellaterra\", \"ows:ServiceProvider address city is correct\");\n            t.eq(serviceProvider.serviceContact.contactInfo.address.country, \"Spain\", \"ows:ServiceProvider address country is correct\");\n            t.eq(serviceProvider.serviceContact.contactInfo.address.deliveryPoint, \"Fac Ciencies UAB\", \"ows:ServiceProvider address deliveryPoint is correct\");\n            t.eq(serviceProvider.serviceContact.contactInfo.address.electronicMailAddress, \"joan.maso@uab.es\", \"ows:ServiceProvider address electronicMailAddress is correct\");\n            t.eq(serviceProvider.serviceContact.contactInfo.address.postalCode, \"08193\", \"ows:ServiceProvider address postalCode is correct\");\n            t.eq(serviceProvider.serviceContact.contactInfo.phone.voice, \"+34 93 581 1312\", \"ows:ServiceProvider phone voice is correct\");\n\n            // ows:OperationsMetadata\n            var operationsMetadata = obj.operationsMetadata;\n            t.eq(operationsMetadata.GetCapabilities.dcp.http.get[0].url, \"http://www.miramon.uab.es/cgi-bin/MiraMon5_0.cgi?\", \"ows:OperationsMetadata GetCapabilities url is correct\");\n            t.eq(operationsMetadata.GetCapabilities.dcp.http.get[0].constraints.GetEncoding.allowedValues,\n                 {'KVP': true},\n                 \"ows:OperationsMetadata GetCapabilities Constraints Get is correct\");\n            t.eq(operationsMetadata.GetFeatureInfo.dcp.http.get[0].url, \"http://www.miramon.uab.es/cgi-bin/MiraMon5_0.cgi?\", \"ows:OperationsMetadata GetFeatureInfo url is correct\");\n            t.eq(operationsMetadata.GetFeatureInfo.dcp.http.get[0].constraints,\n                 undefined,\n                 \"ows:OperationsMetadata GetFeatureInfo Constraints Get is correct\");\n            t.eq(operationsMetadata.GetTile.dcp.http.get[0].url, \"http://www.miramon.uab.es/cgi-bin/MiraMon5_0.cgi?\", \"ows:OperationsMetadata GetTile url is correct\");\n            t.eq(operationsMetadata.GetTile.dcp.http.get[0].constraints,\n                 undefined,\n                 \"ows:OperationsMetadata GetTile Constraints Get is correct\");\n        }\n\n        function test_layers(t) {\n            t.plan(43);\n            var xml = document.getElementById(\"ogcsample\").firstChild.nodeValue;\n            var doc = new OpenLayers.Format.XML().read(xml);\n\n            var obj = new OpenLayers.Format.WMTSCapabilities().read(doc);\n            var contents = obj.contents;\n\n            var numOfLayers = contents.layers.length;\n            t.eq(numOfLayers, 1, \"correct count of layers\");\n\n            var layer = contents.layers[0];\n            t.eq(layer['abstract'], \"Coastline/shorelines (BA010)\", \"layer abstract is correct\");\n            t.eq(layer.identifier, \"coastlines\", \"layer identifier is correct\");\n            t.eq(layer.title, \"Coastlines\", \"layer title is correct\");\n\n            var numOfFormats = layer.formats.length;\n            t.eq(numOfFormats, 2, \"correct count of formats\");\n            t.eq(layer.formats[0], \"image/png\", \"format image/png is correct\");\n            t.eq(layer.formats[1], \"image/gif\", \"format image/gif is correct\");\n\n            var numOfStyles = layer.styles.length;\n            t.eq(numOfStyles, 2, \"correct count of styles\");\n            t.eq(layer.styles[0].identifier, \"DarkBlue\", \"style 0 identifier is correct\");\n            t.eq(layer.styles[0].isDefault, true, \"style 0 isDefault is correct\");\n            t.eq(layer.styles[0].title, \"Dark Blue\", \"style 0 title is correct\");\n            t.eq(layer.styles[0].legends[0].href, \"http://www.miramon.uab.es/wmts/Coastlines/coastlines_darkBlue.png\", \"style 0 legend 0 href is correct\");\n            t.eq(layer.styles[0].legends[0].format, \"image/png\", \"style 0 legend 0 format is correct\");\n            t.eq(layer.styles[1].identifier, \"thickAndRed\", \"style 1 identifier is correct\");\n            t.ok(!layer.styles[1].isDefault, \"style 1 isDefault is correct\");\n            t.eq(layer.styles[1].title, \"Thick And Red\", \"style 1 title is correct\");\n            t.eq(layer.styles[1].legend, undefined, \"style 1 legend is not set\");\n            //t.eq(layer.styles[1].abstract, \"Specify this style if you want your maps to have thick red coastlines. \", \"style 1 abstract is correct\");\n\n            t.eq(layer.tileMatrixSetLinks.length, 1, \"correct count of tileMatrixSetLinks\");\n            t.eq(layer.tileMatrixSetLinks[0].tileMatrixSet, \"BigWorld\", \"tileMatrixSet is correct\");\n\n            var wgs84Bbox = layer.bounds;\n            t.ok(wgs84Bbox instanceof OpenLayers.Bounds, \"wgs84BoudingBox instance of OpenLayers.Bounds\");\n            t.eq(wgs84Bbox.left, -180.0, \"wgs84BoudingBox left is correct\");\n            t.eq(wgs84Bbox.right, 180.0, \"wgs84BoudingBox right is correct\");\n            t.eq(wgs84Bbox.bottom, -90.0, \"wgs84BoudingBox bottom is correct\");\n            t.eq(wgs84Bbox.top, 90.0, \"wgs84BoudingBox top is correct\");\n\n            t.eq(layer.resourceUrl.tile.format, \"image/png\", \"resourceUrl.tile.format is correct\");\n            t.eq(layer.resourceUrl.tile.template, \"http://www.example.com/wmts/coastlines/{TileMatrix}/{TileRow}/{TileCol}.png\",\n                 \"resourceUrl.tile.template is correct\");\n\n            t.eq(layer.resourceUrl.FeatureInfo.format, \"application/gml+xml; version=3.1\", \"resourceUrl.FeatureInfo.format is correct\");\n            t.eq(layer.resourceUrl.FeatureInfo.template, \"http://www.example.com/wmts/coastlines/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}.xml\",\n                 \"resourceUrl.FeatureInfo.template is correct\");\n\n            t.eq(layer.resourceUrls[0].format, \"image/png\", \"resourceUrls[0].format is correct\");\n            t.eq(layer.resourceUrls[0].resourceType, \"tile\", \"resourceUrls[0].resourceType is correct\");\n            t.eq(layer.resourceUrls[0].template, \"http://www.example.com/wmts/coastlines/{TileMatrix}/{TileRow}/{TileCol}.png\",\n                 \"resourceUrls[0].template is correct\");\n\n            t.eq(layer.resourceUrls[1].format, \"application/gml+xml; version=3.1\", \"resourceUrls[0].format is correct\");\n            t.eq(layer.resourceUrls[1].resourceType, \"FeatureInfo\", \"resourceUrls[0].resourceType is correct\");\n            t.eq(layer.resourceUrls[1].template, \"http://www.example.com/wmts/coastlines/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}.xml\",\n                 \"resourceUrls[0].template is correct\");\n\n            var dimensions = layer.dimensions;\n            t.eq(dimensions.length, 1, \"correct count of dimensions\");\n            t.eq(dimensions[0].title, \"Time\", \"first dimension title is correct\");\n            t.eq(dimensions[0]['abstract'], \"Monthly datasets\", \"first dimension abstract is correct\");\n            t.eq(dimensions[0].identifier, \"TIME\", \"first dimension identifier is correct\");\n            t.eq(dimensions[0]['default'], \"default\", \"first dimension default is correct\");\n            t.eq(dimensions[0].values.length, 3, \"first dimension has correct count of values\");\n            t.eq(dimensions[0].values[0], \"2007-05\", \"first value is correct\");\n            t.eq(dimensions[0].values[1], \"2007-06\", \"second value is correct\");\n            t.eq(dimensions[0].values[2], \"2007-07\", \"third value is correct\");\n        }\n\n        function test_tileMatrixSets(t) {\n            t.plan(19);\n            var xml = document.getElementById(\"ogcsample\").firstChild.nodeValue;\n            var doc = new OpenLayers.Format.XML().read(xml);\n\n            var obj = new OpenLayers.Format.WMTSCapabilities().read(doc);\n\n            var tileMatrixSets = obj.contents.tileMatrixSets;\n            t.ok(tileMatrixSets['BigWorld'], \"tileMatrixSets 'BigWorld' found\");\n            var bigWorld = tileMatrixSets['BigWorld'];\n            t.eq(bigWorld.identifier, \"BigWorld\", \"tileMatrixSets identifier is correct\");\n            t.eq(bigWorld.matrixIds.length, 2, \"tileMatrix count is correct\");\n            t.eq(bigWorld.matrixIds[0].identifier, \"1e6\", \"tileMatrix 0 identifier is correct\");\n            t.eq(bigWorld.matrixIds[0].matrixHeight, 50000, \"tileMatrix 0 matrixHeight is correct\");\n            t.eq(bigWorld.matrixIds[0].matrixWidth, 60000, \"tileMatrix 0 matrixWidth is correct\");\n            t.eq(bigWorld.matrixIds[0].scaleDenominator, 1000000, \"tileMatrix 0 scaleDenominator is correct\");\n            t.eq(bigWorld.matrixIds[0].tileWidth, 256, \"tileMatrix 0 tileWidth is correct\");\n            t.eq(bigWorld.matrixIds[0].tileHeight, 256, \"tileMatrix 0 tileHeight is correct\");\n            t.eq(bigWorld.matrixIds[0].topLeftCorner.lon, -180, \"tileMatrix 0 topLeftCorner.lon is correct\");\n            t.eq(bigWorld.matrixIds[0].topLeftCorner.lat, 84, \"tileMatrix 0 topLeftCorner.lat is correct\");\n\n            t.eq(bigWorld.matrixIds[1].identifier, \"2.5e6\", \"tileMatrix 1 identifier is correct\");\n            t.eq(bigWorld.matrixIds[1].matrixHeight, 7000, \"tileMatrix 1 matrixHeight is correct\");\n            t.eq(bigWorld.matrixIds[1].matrixWidth, 9000, \"tileMatrix 1 matrixWidth is correct\");\n            t.eq(bigWorld.matrixIds[1].scaleDenominator, 2500000, \"tileMatrix 1 scaleDenominator is correct\");\n            t.eq(bigWorld.matrixIds[1].tileWidth, 256, \"tileMatrix 1 tileWidth is correct\");\n            t.eq(bigWorld.matrixIds[1].tileHeight, 256, \"tileMatrix 1 tileHeight is correct\");\n            t.eq(bigWorld.matrixIds[1].topLeftCorner.lon, -180, \"tileMatrix 1 topLeftCorner.lon is correct\");\n            t.eq(bigWorld.matrixIds[1].topLeftCorner.lat, 84, \"tileMatrix 1 topLeftCorner.lat is correct\");\n        }\n\n        function test_tileMatrixSetLimits(t) {\n            t.plan(7);\n            var xml = document.getElementById(\"French-IGN-GeoPortal\").firstChild.nodeValue;\n            var doc = new OpenLayers.Format.XML().read(xml);\n\n            var obj = new OpenLayers.Format.WMTSCapabilities().read(doc);\n\n            var tileMatrixSetLink = obj.contents.layers[0].tileMatrixSetLinks[0];\n            t.eq(tileMatrixSetLink.tileMatrixSet, \"PM\", \"tileMatrixSet identifier in TileMatrixSetLink is correct\");\n            t.eq(tileMatrixSetLink.tileMatrixSetLimits.length, 13, \"tileMatrixSetLimits number is correct\");\n            t.eq(tileMatrixSetLink.tileMatrixSetLimits[0].tileMatrix, \"10\", \"tileMatrix identifier in tileMatrixSetLimits is correct\");\n            t.eq(tileMatrixSetLink.tileMatrixSetLimits[0].minTileRow, 336, \"minTileRow is correct\");\n            t.eq(tileMatrixSetLink.tileMatrixSetLimits[0].maxTileRow, 576, \"maxTileRow is correct\");\n            t.eq(tileMatrixSetLink.tileMatrixSetLimits[0].minTileCol, 336, \"minTileCol is correct\");\n            t.eq(tileMatrixSetLink.tileMatrixSetLimits[0].maxTileCol, 671, \"maxTileCol is correct\");\n        }\n\n        function test_legendURL(t) {\n            t.plan(7);\n            var xml = document.getElementById(\"French-IGN-GeoPortal\").firstChild.nodeValue;\n            var doc = new OpenLayers.Format.XML().read(xml);\n\n            var obj = new OpenLayers.Format.WMTSCapabilities().read(doc);\n\n            var style = obj.contents.layers[0].styles[0];\n            t.ok(style['legends'] && style['legends'][0], \"Legend found in style\");\n            var legend = style.legends[0];\n            t.eq(legend.format, \"image/png\", \"Legend format is correct\");\n            t.eq(legend.href, \"http://gpp3-wxs.ign.fr/static/LEGENDES/NOLEGEND.JPG\", \"Legend href is correct\");\n            t.eq(legend.minScaleDenominator, 200, \"Legend minScaleDenominator is correct\");\n            t.eq(legend.maxScaleDenominator, 100000000, \"Legend maxScaleDenominator is correct\");\n            t.eq(legend.width, 1, \"Legend width is correct\");\n            t.eq(legend.height, 1, \"Legend height is correct\");\n        }\n\n        function test_infoFormats(t) {\n            t.plan(2);\n            var xml = document.getElementById(\"French-IGN-GeoPortal\").firstChild.nodeValue;\n            var doc = new OpenLayers.Format.XML().read(xml);\n\n            var obj = new OpenLayers.Format.WMTSCapabilities().read(doc);\n\n            var layer = obj.contents.layers[0];\n            t.ok(layer.infoFormats, \"infoFormats found for layer 0\");\n            t.eq(layer.infoFormats[2], \"application/vnd.ogc.gml\", \"third infoFormat value is correct\");\n        }\n\n        function test_createLayer(t) {\n            t.plan(48);\n\n            var format = new OpenLayers.Format.WMTSCapabilities();\n\n            var xml = document.getElementById(\"ogcsample\").firstChild.nodeValue;\n            var doc = new OpenLayers.Format.XML().read(xml);\n\n            var caps = format.read(doc);\n            var layer;\n\n            var success = true;\n            try {\n                // incomplete config (missing layer)\n                layer = format.createLayer(caps, {\n                });\n            } catch (err) {\n                success = false;\n            }\n            t.ok(!success, \"createLayer throws error if provided incomplete layer config\");\n\n            // bogus layer identifier\n            try {\n                layer = format.createLayer(caps, {\n                    layer: \"foo\",\n                    matrixSet: \"BigWorld\"\n                });\n            } catch (err) {\n                success = false;\n            }\n            t.ok(!success, \"createLayer returns undefined given bad layer identifier\");\n\n            // bogus matrixSet identifier\n            try {\n                layer = format.createLayer(caps, {\n                    layer: \"coastlines\",\n                    matrixSet: \"TheWorld\"\n                });\n            } catch (err) {\n                success = false;\n            }\n            t.ok(!success, \"createLayer returns undefined given bad matrixSet identifier\");\n\n            // bogus projection\n            try {\n                layer = format.createLayer(caps, {\n                    layer: \"coastlines\",\n                    projection: \"EPSG:3857\"\n                });\n            } catch (err) {\n                success = false;\n            }\n            t.ok(!success, \"createLayer returns undefined given unsupported projection\");\n\n            layer = format.createLayer(caps, {\n                layer: \"coastlines\",\n                matrixSet: \"BigWorld\"\n            });\n            t.ok(layer instanceof OpenLayers.Layer.WMTS, \"correct instance\");\n\n            layer = format.createLayer(caps, {\n                layer: \"coastlines\",\n                projection: \"OGC:CRS84\"\n            });\n            t.ok(layer instanceof OpenLayers.Layer.WMTS, \"correct instance with CRS84 tile matrix set\");\n            \n            // autodetect matrixSet\n            layer = format.createLayer(caps, {\n                layer: \"coastlines\"\n            });\n            t.ok(layer instanceof OpenLayers.Layer.WMTS, \"correct instance, with autodetected matrixSet\");\n\n            t.eq(layer.matrixIds.length, 2, \"correct matrixIds length\");\n            t.eq(layer.name, \"Coastlines\", \"correct layer title\");\n            t.eq(layer.style, \"DarkBlue\", \"correct style identifier\");\n            t.eq(layer.requestEncoding, \"KVP\", \"correct requestEncoding\");\n\n            xml = document.getElementById(\"restsample\").firstChild.nodeValue;\n            doc = new OpenLayers.Format.XML().read(xml);\n            caps = format.read(doc);\n            layer = format.createLayer(caps, {\n                layer: \"ch.are.agglomerationen_isolierte_staedte-2000\",\n                matrixSet: \"21781\"\n            });\n            t.ok(layer instanceof OpenLayers.Layer.WMTS, \"correct instance\");\n            t.eq(layer.url[0], \"http://wmts.geo.admin.ch/1.0.0/ch.are.agglomerationen_isolierte_staedte-2000/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png\", \"correct url\");\n            t.eq(layer.url[1], \"http://wmts1.geo.admin.ch/1.0.0/ch.are.agglomerationen_isolierte_staedte-2000/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png\", \"correct url\");\n            t.eq(layer.matrixIds.length, 3, \"correct matrixIds length\");\n            t.eq(layer.requestEncoding, \"REST\", \"correct requestEncoding\");\n            t.eq(layer.name, \"Agglomérations et villes isolées\", \"correct layer title\");\n            t.eq(layer.style, \"ch.are.agglomerationen_isolierte_staedte-2000\", \"correct style identifier\");\n            t.eq(layer.projection.getCode(), \"EPSG:21781\", \"correct projection\");\n            t.eq(layer.units, \"m\", \"correct untis\");\n            t.ok(layer.serverResolutions === layer.resolutions, \"serverResolutions set\");\n            t.eq(layer.resolutions.length, 3, \"correct resolutions length\");\n            t.ok((layer.resolutions[0] - 4000) < 1, \"correct first resolution\");\n            t.eq(layer.dimensions.length, 1, \"correct dimensions length\");\n            t.eq(layer.dimensions[0], \"Time\", \"correct dimensions\");\n            t.eq(layer.params['TIME'], \"20090101\", \"correct params\");\n\n            layer = format.createLayer(caps, {\n                layer: \"ch.are.agglomerationen_isolierte_staedte-2000\",\n                style: \"toto\",\n                params: {\"Time\": \"2012\"}\n            });\n            t.eq(layer.matrixIds.length, 3, \"correct matrixIds length\");\n            t.eq(layer.style, \"toto\", \"correct style identifier\");\n            t.eq(layer.dimensions.length, 1, \"correct dimensions length\");\n            t.eq(layer.dimensions[0], \"Time\", \"correct dimensions\");\n            t.eq(layer.params['TIME'], \"2012\", \"correct params\");\n\n            // test projection and units\n            layer = format.createLayer(caps, {\n                layer: \"ch.are.agglomerationen_isolierte_staedte-2000\",\n                matrixSet: \"21781\",\n                units: 'degrees'\n            });\n            t.eq(layer.units, \"degrees\", \"correct units\");\n            layer = format.createLayer(caps, {\n                layer: \"ch.are.agglomerationen_isolierte_staedte-2000\",\n                matrixSet: \"21781\",\n                projection: \"EPSG:4326\"\n            });\n            t.eq(layer.projection.getCode(), \"EPSG:4326\", \"correct projection\");\n            t.eq(layer.units, \"degrees\", \"correct units\");\n            layer = format.createLayer(caps, {\n                layer: \"ch.are.agglomerationen_isolierte_staedte-2000\",\n                matrixSet: \"21781\",\n                projection: \"EPSG:4326\",\n                units: 'm'\n            });\n            t.eq(layer.projection.getCode(), \"EPSG:4326\", \"correct projection\");\n            t.eq(layer.units, \"m\", \"correct units\");\n            layer = format.createLayer(caps, {\n                layer: \"ch.are.agglomerationen_isolierte_staedte-2000\",\n                matrixSet: \"21781\",\n                projection: \"EPSG:900913\",\n                units: 'degrees'\n            });\n            t.eq(layer.projection.getCode(), \"EPSG:900913\", \"correct projection\");\n            t.eq(layer.units, \"degrees\", \"correct units\");\n\n\n            // test get the right url #608/3\n            xml = document.getElementById(\"multi-getile-1\").firstChild.nodeValue;\n            doc = new OpenLayers.Format.XML().read(xml);\n            caps = format.read(doc);\n            layer = format.createLayer(caps, {\n                layer: \"ch.are.agglomerationen_isolierte_staedte-2000\",\n                matrixSet: \"21781\",\n                requestEncoding: 'REST'\n            });\n            t.eq(layer.url[0], \"http://wmts.geo.admin.ch/rest\", \"correct rest url 1\");\n            t.eq(layer.url[1], \"http://wmts1.geo.admin.ch/rest\", \"correct rest url 1\");\n            layer = format.createLayer(caps, {\n                layer: \"ch.are.agglomerationen_isolierte_staedte-2000\",\n                matrixSet: \"21781\",\n                requestEncoding: 'KVP'\n            });\n            t.eq(layer.url[0], \"http://wmts.geo.admin.ch/kvp\", \"correct kvp url 2\");\n            t.eq(layer.url[1], \"http://wmts1.geo.admin.ch/kvp\", \"correct kvp url 2\");\n            xml = document.getElementById(\"multi-getile-2\").firstChild.nodeValue;\n            doc = new OpenLayers.Format.XML().read(xml);\n            caps = format.read(doc);\n            layer = format.createLayer(caps, {\n                layer: \"ch.are.agglomerationen_isolierte_staedte-2000\",\n                matrixSet: \"21781\",\n                requestEncoding: 'REST'\n            });\n            t.eq(layer.url[0], \"http://wmts.geo.admin.ch/rest\", \"correct rest url 2\");\n            layer = format.createLayer(caps, {\n                layer: \"ch.are.agglomerationen_isolierte_staedte-2000\",\n                matrixSet: \"21781\",\n                requestEncoding: 'KVP'\n            });\n            t.eq(layer.url[0], \"http://wmts.geo.admin.ch/kvp\", \"correct kvp url 2\");\n\n            // test RESTfull\n            xml = document.getElementById(\"arcgis\").firstChild.nodeValue;\n            doc = new OpenLayers.Format.XML().read(xml);\n            caps = format.read(doc);\n            layer = format.createLayer(caps, {\n                layer: \"WorldTimeZones\"\n            });\n            t.eq(layer.requestEncoding, \"REST\", \"correct requestEncoding (in RESTfull)\");\n            \n            // test serverresolutions and min/maxScaleDenominator\n            xml = document.getElementById(\"French-IGN-GeoPortal\").firstChild.nodeValue;\n            doc = new OpenLayers.Format.XML().read(xml);\n            caps = format.read(doc);\n            layer = format.createLayer(caps, {\n                layer: \"ADMINISTRATIVEUNITS.BOUNDARIES\"\n            });\n            t.eq(layer.serverResolutions.length, 13, \"correct number of server resolutions\");\n            t.eq(layer.maxScale, 1/2132, \"correct maxScale\");\n            t.eq(layer.minScale, 1/8735661, \"correct minScale\");\n        }\n\n        function test_parse_projection(t) {\n            t.plan(2);\n\n            var format = new OpenLayers.Format.WMTSCapabilities();\n\n            var xml = document.getElementById(\"restsample-alternate-proj1\").firstChild.nodeValue;\n            var doc = new OpenLayers.Format.XML().read(xml);\n            var caps = format.read(doc);\n            var layer = format.createLayer(caps, {\n                layer: \"ch.are.agglomerationen_isolierte_staedte-2000\",\n                matrixSet: \"21781\"\n            });\n            t.eq(layer.projection.getCode(), \"EPSG:21781\", \"correct projection\");\n\n            xml = document.getElementById(\"restsample-alternate-proj2\").firstChild.nodeValue;\n            doc = new OpenLayers.Format.XML().read(xml);\n            caps = format.read(doc);\n            layer = format.createLayer(caps, {\n                layer: \"ch.are.agglomerationen_isolierte_staedte-2000\",\n                matrixSet: \"21781\"\n            });\n            t.eq(layer.projection.getCode(), \"EPSG:21781\", \"correct projection\");\n        }\n    </script>\n</head>\n<body>\n\n<!--\nOGC example below taken from\nhttp://schemas.opengis.net/wmts/1.0/examples/wmtsGetCapabilities_response.xml\n-->\n<div id=\"ogcsample\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Capabilities xmlns=\"http://www.opengis.net/wmts/1.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:gml=\"http://www.opengis.net/gml\" xsi:schemaLocation=\"http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd\" version=\"1.0.0\">\n    <ows:ServiceIdentification>\n        <ows:Title>Web Map Tile Service</ows:Title>\n        <ows:Abstract>Service that contrains the map access interface to some TileMatrixSets</ows:Abstract>\n        <ows:Keywords>\n            <ows:Keyword>tile</ows:Keyword>\n            <ows:Keyword>tile matrix set</ows:Keyword>\n            <ows:Keyword>map</ows:Keyword>\n        </ows:Keywords>\n        <ows:ServiceType>OGC WMTS</ows:ServiceType>\n        <ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion>\n        <ows:Fees>none</ows:Fees>\n        <ows:AccessConstraints>none</ows:AccessConstraints>\n    </ows:ServiceIdentification>\n    <ows:ServiceProvider>\n        <ows:ProviderName>MiraMon</ows:ProviderName>\n        <ows:ProviderSite xlink:href=\"http://www.creaf.uab.es/miramon\"/>\n        <ows:ServiceContact>\n            <ows:IndividualName>Joan Maso Pau</ows:IndividualName>\n            <ows:PositionName>Senior Software Engineer</ows:PositionName>\n            <ows:ContactInfo>\n                <ows:Phone>\n                    <ows:Voice>+34 93 581 1312</ows:Voice>\n                    <ows:Facsimile>+34 93 581 4151</ows:Facsimile>\n                </ows:Phone>\n                <ows:Address>\n                    <ows:DeliveryPoint>Fac Ciencies UAB</ows:DeliveryPoint>\n                    <ows:City>Bellaterra</ows:City>\n                    <ows:AdministrativeArea>Barcelona</ows:AdministrativeArea>\n                    <ows:PostalCode>08193</ows:PostalCode>\n                    <ows:Country>Spain</ows:Country>\n                    <ows:ElectronicMailAddress>joan.maso@uab.es</ows:ElectronicMailAddress>\n                </ows:Address>\n            </ows:ContactInfo>\n        </ows:ServiceContact>\n    </ows:ServiceProvider>\n    <ows:OperationsMetadata>\n        <ows:Operation name=\"GetCapabilities\">\n            <ows:DCP>\n                <ows:HTTP>\n                    <ows:Get xlink:href=\"http://www.miramon.uab.es/cgi-bin/MiraMon5_0.cgi?\">\n                        <ows:Constraint name=\"GetEncoding\">\n                            <ows:AllowedValues>\n                                <ows:Value>KVP</ows:Value>\n                            </ows:AllowedValues>\n                        </ows:Constraint>\n                    </ows:Get>\n                </ows:HTTP>\n            </ows:DCP>\n        </ows:Operation>\n        <ows:Operation name=\"GetTile\">\n            <ows:DCP>\n                <ows:HTTP>\n                    <ows:Get xlink:href=\"http://www.miramon.uab.es/cgi-bin/MiraMon5_0.cgi?\"/>\n                </ows:HTTP>\n            </ows:DCP>\n        </ows:Operation>\n        <ows:Operation name=\"GetFeatureInfo\">\n            <ows:DCP>\n                <ows:HTTP>\n                    <ows:Get xlink:href=\"http://www.miramon.uab.es/cgi-bin/MiraMon5_0.cgi?\"/>\n                </ows:HTTP>\n            </ows:DCP>\n        </ows:Operation>\n    </ows:OperationsMetadata>\n    <Contents>\n        <Layer>\n            <ows:Title>Coastlines</ows:Title>\n            <ows:Abstract>Coastline/shorelines (BA010)</ows:Abstract>\n            <ows:WGS84BoundingBox>\n                <ows:LowerCorner>-180 -90</ows:LowerCorner>\n                <ows:UpperCorner>180 90</ows:UpperCorner>\n            </ows:WGS84BoundingBox>\n            <ows:Identifier>coastlines</ows:Identifier>\n            <ResourceURL format=\"image/png\" resourceType=\"tile\"\n                         template=\"http://www.example.com/wmts/coastlines/{TileMatrix}/{TileRow}/{TileCol}.png\" />\n            <ResourceURL format=\"application/gml+xml; version=3.1\" resourceType=\"FeatureInfo\"\n                         template=\"http://www.example.com/wmts/coastlines/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}/{J}/{I}.xml\" />\n            <Style isDefault=\"true\">\n                <ows:Title>Dark Blue</ows:Title>\n                <ows:Identifier>DarkBlue</ows:Identifier>\n                <LegendURL format=\"image/png\" xlink:href=\"http://www.miramon.uab.es/wmts/Coastlines/coastlines_darkBlue.png\"/>\n            </Style>\n            <Style>\n                <ows:Title>Thick And Red</ows:Title>\n                <ows:Abstract>Specify this style if you want your maps to have thick red coastlines.\n                </ows:Abstract>\n                <ows:Identifier>thickAndRed</ows:Identifier>\n            </Style>\n            <Format>image/png</Format>\n            <Format>image/gif</Format>\n            <Dimension>\n                <ows:Title>Time</ows:Title>\n                <ows:Abstract>Monthly datasets</ows:Abstract>\n                <ows:Identifier>TIME</ows:Identifier>\n                <Value>2007-05</Value>\n                <Value>2007-06</Value>\n                <Value>2007-07</Value>\n                <Default>default</Default>\n            </Dimension>\n            <TileMatrixSetLink>\n                <TileMatrixSet>BigWorld</TileMatrixSet>\n            </TileMatrixSetLink>\n        </Layer>\n        <TileMatrixSet>\n            <ows:Identifier>BigWorld</ows:Identifier>\n            <ows:SupportedCRS>urn:ogc:def:crs:OGC:1.3:CRS84</ows:SupportedCRS>\n            <TileMatrix>\n                <ows:Identifier>1e6</ows:Identifier>\n                <ScaleDenominator>1e6</ScaleDenominator>\n                <TopLeftCorner>-180 84</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>60000</MatrixWidth>\n                <MatrixHeight>50000</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>2.5e6</ows:Identifier>\n                <ScaleDenominator>2.5e6</ScaleDenominator>\n                <TopLeftCorner>-180 84</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>9000</MatrixWidth>\n                <MatrixHeight>7000</MatrixHeight>\n            </TileMatrix>\n        </TileMatrixSet>\n    </Contents>\n    <Themes>\n        <Theme>\n            <ows:Title>Foundation</ows:Title>\n            <ows:Abstract>\"Digital Chart Of The World\" data</ows:Abstract>\n            <ows:Identifier>Foundation</ows:Identifier>\n            <Theme>\n                <ows:Title>Boundaries</ows:Title>\n                <ows:Identifier>Boundaries</ows:Identifier>\n                <LayerRef>coastlines</LayerRef>\n                <LayerRef>politicalBoundaries</LayerRef>\n                <LayerRef>depthContours</LayerRef>\n            </Theme>\n            <Theme>\n                <ows:Title>Transportation</ows:Title>\n                <ows:Identifier>Transportation</ows:Identifier>\n                <LayerRef>roads</LayerRef>\n                <LayerRef>railroads</LayerRef>\n                <LayerRef>airports</LayerRef>\n            </Theme>\n        </Theme>\n        <Theme>\n            <ows:Title>World Geology</ows:Title>\n            <ows:Identifier>World Geology</ows:Identifier>\n            <LayerRef>worldAgeRockType</LayerRef>\n            <LayerRef>worldFaultLines</LayerRef>\n            <LayerRef>felsicMagmatic</LayerRef>\n            <LayerRef>maficMagmatic</LayerRef>\n        </Theme>\n    </Themes>\n</Capabilities>\n--></div>\n\n<div id=\"restsample\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Capabilities xmlns=\"http://www.opengis.net/wmts/1.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:gml=\"http://www.opengis.net/gml\" xsi:schemaLocation=\"http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd\" version=\"1.0.0\">\n    <ows:ServiceIdentification>\n        <ows:Title>Federal Geodata Infrastructure of Switzerland</ows:Title>\n        <ows:Abstract>Some Geodata are subject to license and fees</ows:Abstract>\n        <ows:Keywords>\n            <ows:Keyword>FGDI</ows:Keyword>\n            <ows:Keyword>Pixelkarte</ows:Keyword>\n            <ows:Keyword>Switzerland</ows:Keyword>\n        </ows:Keywords>\n        <ows:ServiceType>OGC WMTS</ows:ServiceType>\n        <ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion>\n        <ows:Fees>yes</ows:Fees>\n        <ows:AccessConstraints>license</ows:AccessConstraints>\n    </ows:ServiceIdentification>\n    <ows:ServiceProvider>\n        <ows:ProviderName>swisstopo</ows:ProviderName>\n        <ows:ProviderSite xlink:href=\"http://www.swisstopo.admin.ch\"/>\n        <ows:ServiceContact>\n            <ows:IndividualName>David Oesch</ows:IndividualName>\n            <ows:PositionName></ows:PositionName>\n            <ows:ContactInfo>\n                <ows:Phone>\n                    <ows:Voice>+41 (0)31 / 963 21 11</ows:Voice>\n                    <ows:Facsimile>+41 (0)31 / 963 24 59</ows:Facsimile>\n                </ows:Phone>\n                <ows:Address>\n                    <ows:DeliveryPoint>swisstopo</ows:DeliveryPoint>\n                    <ows:City>Bern</ows:City>\n                    <ows:AdministrativeArea>BE</ows:AdministrativeArea>\n                    <ows:PostalCode>3084</ows:PostalCode>\n                    <ows:Country>Switzerland</ows:Country>\n                    <ows:ElectronicMailAddress/>\n                </ows:Address>\n            </ows:ContactInfo>\n        </ows:ServiceContact>\n    </ows:ServiceProvider>\n    <ows:OperationsMetadata>\n        <ows:Operation name=\"GetCapabilities\">\n            <ows:DCP>\n                <ows:HTTP>\n                    <ows:Get xlink:href=\"http://wmts.geo.admin.ch/1.0.0/WMTSCapabilities.xml\">\n                        <ows:Constraint name=\"GetEncoding\">\n                            <ows:AllowedValues>\n                                <ows:Value>REST</ows:Value>\n                            </ows:AllowedValues>\n                        </ows:Constraint>\n                    </ows:Get>\n                </ows:HTTP>\n            </ows:DCP>\n        </ows:Operation>\n        <ows:Operation name=\"GetTile\">\n            <ows:DCP>\n                <ows:HTTP>\n                    <ows:Get xlink:href=\"http://wmts.geo.admin.ch/\">\n                        <ows:Constraint name=\"GetEncoding\">\n                            <ows:AllowedValues>\n                                <ows:Value>REST</ows:Value>\n                            </ows:AllowedValues>\n                        </ows:Constraint>\n                    </ows:Get>\n                </ows:HTTP>\n            </ows:DCP>\n        </ows:Operation>\n    </ows:OperationsMetadata>\n    <Contents>\n        <Layer>\n            <ows:Title>Agglomérations et villes isolées</ows:Title>\n            <ows:Abstract>Les agglomérations et villes isolées (communes non rattachées à une agglomération et comptant au moins 10`000 habitants) font partie des régions d’analyse de la statistique suisse. Ce niveau géographique est défini depuis plus de 100 ans, afin de mesurer l’urbanisation, phénomène fondamental structurant l’organisation du territoire. Sa fonction principale est de permettre une comparaison spatiale entre des espaces urbains inégalement délimités sur le plan institutionnel. Une version ancienne est appliquée pour la première fois en 1930, puis révisée en 1984 et 1990, toujours sur la base des recensements de la population. La version actuelle classe les 2896 communes de Suisse (état 2000) selon leur appartenance ou pas à une agglomération ou ville isolée en fonction de critères statistiques (Etat et évolution de la population, lien de continuité de la zone bâtie, rapport entre population active occupée et population résidante, structure économique et flux de pendulaires). Les agglomérations et les villes isolées forment l`espace urbain, les territoires restant l`espace rural. La définition des agglomérations de l’OFS n’a pas valeur d’obligation légale.</ows:Abstract>\n            <ows:WGS84BoundingBox>\n                <ows:LowerCorner>5.140242 45.398181</ows:LowerCorner>\n                <ows:UpperCorner>11.47757 48.230651</ows:UpperCorner>\n            </ows:WGS84BoundingBox>\n            <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>\n            <ows:Metadata xlink:href=\"http://www.swisstopo.admin.ch/SITiled/world/AdminBoundaries/metadata.htm\"/>\n            <Style>\n                <ows:Title>Agglomérations et villes isolées</ows:Title>\n                <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>\n                <LegendURL format=\"image/png\" xlink:href=\"http://api.geo.admin.ch/legend/ch.are.agglomerationen_isolierte_staedte-2000_fr.png\" />\n            </Style>\n            <Format>image/png</Format>\n            <Dimension>\n                <ows:Identifier>Time</ows:Identifier>\n                <Default>20090101</Default>\n                <Value>20090101</Value>\n            </Dimension>\n            <TileMatrixSetLink>\n                <TileMatrixSet>21781</TileMatrixSet>\n            </TileMatrixSetLink>\n            <ResourceURL format=\"image/png\" resourceType=\"tile\" template=\"http://wmts.geo.admin.ch/1.0.0/ch.are.agglomerationen_isolierte_staedte-2000/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png\"/>\n            <ResourceURL format=\"image/png\" resourceType=\"tile\" template=\"http://wmts1.geo.admin.ch/1.0.0/ch.are.agglomerationen_isolierte_staedte-2000/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png\"/>\n        </Layer>\n        <TileMatrixSet>\n            <ows:Identifier>21781</ows:Identifier>\n            <ows:SupportedCRS>urn:ogc:def:crs:EPSG::21781</ows:SupportedCRS>\n            <TileMatrix>\n                <ows:Identifier>0</ows:Identifier>\n                <ScaleDenominator>14285750.5715</ScaleDenominator>\n                <TopLeftCorner>420000.0 350000.0</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>1</MatrixWidth>\n                <MatrixHeight>1</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>8</ows:Identifier>\n                <ScaleDenominator>7142875.28575</ScaleDenominator>\n                <TopLeftCorner>420000.0 350000.0</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>1</MatrixWidth>\n                <MatrixHeight>1</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>12</ows:Identifier>\n                <ScaleDenominator>3571437.64288</ScaleDenominator>\n                <TopLeftCorner>420000.0 350000.0</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>2</MatrixWidth>\n                <MatrixHeight>2</MatrixHeight>\n            </TileMatrix>\n        </TileMatrixSet>\n    </Contents>\n    <ServiceMetadataURL xlink:href=\"http://www.opengis.uab.es/SITiled/world/1.0.0/WMTSCapabilities.xml\"/>\n</Capabilities>\n--></div>\n\n<div id=\"restsample-alternate-proj1\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Capabilities xmlns=\"http://www.opengis.net/wmts/1.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:gml=\"http://www.opengis.net/gml\" xsi:schemaLocation=\"http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd\" version=\"1.0.0\">\n    <ows:OperationsMetadata>\n        <ows:Operation name=\"GetCapabilities\">\n            <ows:DCP>\n                <ows:HTTP>\n                    <ows:Get xlink:href=\"http://wmts.geo.admin.ch/1.0.0/WMTSCapabilities.xml\">\n                        <ows:Constraint name=\"GetEncoding\">\n                            <ows:AllowedValues>\n                                <ows:Value>REST</ows:Value>\n                            </ows:AllowedValues>\n                        </ows:Constraint>\n                    </ows:Get>\n                </ows:HTTP>\n            </ows:DCP>\n        </ows:Operation>\n        <ows:Operation name=\"GetTile\">\n            <ows:DCP>\n                <ows:HTTP>\n                    <ows:Get xlink:href=\"http://wmts.geo.admin.ch/\">\n                        <ows:Constraint name=\"GetEncoding\">\n                            <ows:AllowedValues>\n                                <ows:Value>REST</ows:Value>\n                            </ows:AllowedValues>\n                        </ows:Constraint>\n                    </ows:Get>\n                </ows:HTTP>\n            </ows:DCP>\n        </ows:Operation>\n    </ows:OperationsMetadata>\n    <Contents>\n        <Layer>\n            <ows:Title>Agglomérations et villes isolées</ows:Title>\n            <ows:Abstract>Les agglomérations et villes isolées (communes non rattachées à une agglomération et comptant au moins 10`000 habitants) font partie des régions d’analyse de la statistique suisse. Ce niveau géographique est défini depuis plus de 100 ans, afin de mesurer l’urbanisation, phénomène fondamental structurant l’organisation du territoire. Sa fonction principale est de permettre une comparaison spatiale entre des espaces urbains inégalement délimités sur le plan institutionnel. Une version ancienne est appliquée pour la première fois en 1930, puis révisée en 1984 et 1990, toujours sur la base des recensements de la population. La version actuelle classe les 2896 communes de Suisse (état 2000) selon leur appartenance ou pas à une agglomération ou ville isolée en fonction de critères statistiques (Etat et évolution de la population, lien de continuité de la zone bâtie, rapport entre population active occupée et population résidante, structure économique et flux de pendulaires). Les agglomérations et les villes isolées forment l`espace urbain, les territoires restant l`espace rural. La définition des agglomérations de l’OFS n’a pas valeur d’obligation légale.</ows:Abstract>\n            <ows:WGS84BoundingBox>\n                <ows:LowerCorner>5.140242 45.398181</ows:LowerCorner>\n                <ows:UpperCorner>11.47757 48.230651</ows:UpperCorner>\n            </ows:WGS84BoundingBox>\n            <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>\n            <ows:Metadata xlink:href=\"http://www.swisstopo.admin.ch/SITiled/world/AdminBoundaries/metadata.htm\"/>\n            <Style>\n                <ows:Title>Agglomérations et villes isolées</ows:Title>\n                <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>\n                <LegendURL format=\"image/png\" xlink:href=\"http://api.geo.admin.ch/legend/ch.are.agglomerationen_isolierte_staedte-2000_fr.png\" />\n            </Style>\n            <Format>image/png</Format>\n            <Dimension>\n                <ows:Identifier>Time</ows:Identifier>\n                <Default>20090101</Default>\n                <Value>20090101</Value>\n            </Dimension>\n            <TileMatrixSetLink>\n                <TileMatrixSet>21781</TileMatrixSet>\n            </TileMatrixSetLink>\n            <ResourceURL format=\"image/png\" resourceType=\"tile\" template=\"http://wmts.geo.admin.ch/1.0.0/ch.are.agglomerationen_isolierte_staedte-2000/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png\"/>\n        </Layer>\n        <TileMatrixSet>\n            <ows:Identifier>21781</ows:Identifier>\n            <ows:SupportedCRS>urn:ogc:def:crs:EPSG:21781</ows:SupportedCRS>\n            <TileMatrix>\n                <ows:Identifier>0</ows:Identifier>\n                <ScaleDenominator>14285750.5715</ScaleDenominator>\n                <TopLeftCorner>420000.0 350000.0</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>1</MatrixWidth>\n                <MatrixHeight>1</MatrixHeight>\n            </TileMatrix>\n        </TileMatrixSet>\n    </Contents>\n    <ServiceMetadataURL xlink:href=\"http://www.opengis.uab.es/SITiled/world/1.0.0/WMTSCapabilities.xml\"/>\n</Capabilities>\n--></div>\n\n<div id=\"restsample-alternate-proj2\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Capabilities xmlns=\"http://www.opengis.net/wmts/1.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:gml=\"http://www.opengis.net/gml\" xsi:schemaLocation=\"http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd\" version=\"1.0.0\">\n    <ows:OperationsMetadata>\n        <ows:Operation name=\"GetCapabilities\">\n            <ows:DCP>\n                <ows:HTTP>\n                    <ows:Get xlink:href=\"http://wmts.geo.admin.ch/1.0.0/WMTSCapabilities.xml\">\n                        <ows:Constraint name=\"GetEncoding\">\n                            <ows:AllowedValues>\n                                <ows:Value>REST</ows:Value>\n                            </ows:AllowedValues>\n                        </ows:Constraint>\n                    </ows:Get>\n                </ows:HTTP>\n            </ows:DCP>\n        </ows:Operation>\n        <ows:Operation name=\"GetTile\">\n            <ows:DCP>\n                <ows:HTTP>\n                    <ows:Get xlink:href=\"http://wmts.geo.admin.ch/\">\n                        <ows:Constraint name=\"GetEncoding\">\n                            <ows:AllowedValues>\n                                <ows:Value>REST</ows:Value>\n                            </ows:AllowedValues>\n                        </ows:Constraint>\n                    </ows:Get>\n                </ows:HTTP>\n            </ows:DCP>\n        </ows:Operation>\n    </ows:OperationsMetadata>\n    <Contents>\n        <Layer>\n            <ows:Title>Agglomérations et villes isolées</ows:Title>\n            <ows:Abstract>Les agglomérations et villes isolées (communes non rattachées à une agglomération et comptant au moins 10`000 habitants) font partie des régions d’analyse de la statistique suisse. Ce niveau géographique est défini depuis plus de 100 ans, afin de mesurer l’urbanisation, phénomène fondamental structurant l’organisation du territoire. Sa fonction principale est de permettre une comparaison spatiale entre des espaces urbains inégalement délimités sur le plan institutionnel. Une version ancienne est appliquée pour la première fois en 1930, puis révisée en 1984 et 1990, toujours sur la base des recensements de la population. La version actuelle classe les 2896 communes de Suisse (état 2000) selon leur appartenance ou pas à une agglomération ou ville isolée en fonction de critères statistiques (Etat et évolution de la population, lien de continuité de la zone bâtie, rapport entre population active occupée et population résidante, structure économique et flux de pendulaires). Les agglomérations et les villes isolées forment l`espace urbain, les territoires restant l`espace rural. La définition des agglomérations de l’OFS n’a pas valeur d’obligation légale.</ows:Abstract>\n            <ows:WGS84BoundingBox>\n                <ows:LowerCorner>5.140242 45.398181</ows:LowerCorner>\n                <ows:UpperCorner>11.47757 48.230651</ows:UpperCorner>\n            </ows:WGS84BoundingBox>\n            <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>\n            <ows:Metadata xlink:href=\"http://www.swisstopo.admin.ch/SITiled/world/AdminBoundaries/metadata.htm\"/>\n            <Style>\n                <ows:Title>Agglomérations et villes isolées</ows:Title>\n                <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>\n                <LegendURL format=\"image/png\" xlink:href=\"http://api.geo.admin.ch/legend/ch.are.agglomerationen_isolierte_staedte-2000_fr.png\" />\n            </Style>\n            <Format>image/png</Format>\n            <Dimension>\n                <ows:Identifier>Time</ows:Identifier>\n                <Default>20090101</Default>\n                <Value>20090101</Value>\n            </Dimension>\n            <TileMatrixSetLink>\n                <TileMatrixSet>21781</TileMatrixSet>\n            </TileMatrixSetLink>\n            <ResourceURL format=\"image/png\" resourceType=\"tile\" template=\"http://wmts.geo.admin.ch/1.0.0/ch.are.agglomerationen_isolierte_staedte-2000/default/{Time}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png\"/>\n        </Layer>\n        <TileMatrixSet>\n            <ows:Identifier>21781</ows:Identifier>\n            <ows:SupportedCRS>urn:ogc:def:crs:EPSG:1.0:21781</ows:SupportedCRS>\n            <TileMatrix>\n                <ows:Identifier>0</ows:Identifier>\n                <ScaleDenominator>14285750.5715</ScaleDenominator>\n                <TopLeftCorner>420000.0 350000.0</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>1</MatrixWidth>\n                <MatrixHeight>1</MatrixHeight>\n            </TileMatrix>\n        </TileMatrixSet>\n    </Contents>\n    <ServiceMetadataURL xlink:href=\"http://www.opengis.uab.es/SITiled/world/1.0.0/WMTSCapabilities.xml\"/>\n</Capabilities>\n--></div>\n\n<div id=\"multi-getile-1\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Capabilities xmlns=\"http://www.opengis.net/wmts/1.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:gml=\"http://www.opengis.net/gml\" xsi:schemaLocation=\"http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd\" version=\"1.0.0\">\n    <ows:OperationsMetadata>\n        <ows:Operation name=\"GetCapabilities\">\n            <ows:DCP>\n                <ows:HTTP>\n                    <ows:Get xlink:href=\"http://wmts.geo.admin.ch/1.0.0/WMTSCapabilities.xml\">\n                        <ows:Constraint name=\"GetEncoding\">\n                            <ows:AllowedValues>\n                                <ows:Value>REST</ows:Value>\n                            </ows:AllowedValues>\n                        </ows:Constraint>\n                    </ows:Get>\n                </ows:HTTP>\n            </ows:DCP>\n        </ows:Operation>\n        <ows:Operation name=\"GetTile\">\n            <ows:DCP>\n                <ows:HTTP>\n                    <ows:Get xlink:href=\"http://wmts.geo.admin.ch/rest\">\n                        <ows:Constraint name=\"GetEncoding\">\n                            <ows:AllowedValues>\n                                <ows:Value>REST</ows:Value>\n                            </ows:AllowedValues>\n                        </ows:Constraint>\n                    </ows:Get>\n                    <ows:Get xlink:href=\"http://wmts1.geo.admin.ch/rest\">\n                        <ows:Constraint name=\"GetEncoding\">\n                            <ows:AllowedValues>\n                                <ows:Value>REST</ows:Value>\n                            </ows:AllowedValues>\n                        </ows:Constraint>\n                    </ows:Get>\n                    <ows:Get xlink:href=\"http://wmts.geo.admin.ch/kvp\">\n                        <ows:Constraint name=\"GetEncoding\">\n                            <ows:AllowedValues>\n                                <ows:Value>KVP</ows:Value>\n                            </ows:AllowedValues>\n                        </ows:Constraint>\n                    </ows:Get>\n                    <ows:Get xlink:href=\"http://wmts1.geo.admin.ch/kvp\">\n                        <ows:Constraint name=\"GetEncoding\">\n                            <ows:AllowedValues>\n                                <ows:Value>KVP</ows:Value>\n                            </ows:AllowedValues>\n                        </ows:Constraint>\n                    </ows:Get>\n                </ows:HTTP>\n            </ows:DCP>\n        </ows:Operation>\n    </ows:OperationsMetadata>\n    <Contents>\n        <Layer>\n            <ows:Title>Agglomérations et villes isolées</ows:Title>\n            <ows:Abstract>Les agglomérations et villes isolées (communes non rattachées à une agglomération et comptant au moins 10`000 habitants) font partie des régions d’analyse de la statistique suisse. Ce niveau géographique est défini depuis plus de 100 ans, afin de mesurer l’urbanisation, phénomène fondamental structurant l’organisation du territoire. Sa fonction principale est de permettre une comparaison spatiale entre des espaces urbains inégalement délimités sur le plan institutionnel. Une version ancienne est appliquée pour la première fois en 1930, puis révisée en 1984 et 1990, toujours sur la base des recensements de la population. La version actuelle classe les 2896 communes de Suisse (état 2000) selon leur appartenance ou pas à une agglomération ou ville isolée en fonction de critères statistiques (Etat et évolution de la population, lien de continuité de la zone bâtie, rapport entre population active occupée et population résidante, structure économique et flux de pendulaires). Les agglomérations et les villes isolées forment l`espace urbain, les territoires restant l`espace rural. La définition des agglomérations de l’OFS n’a pas valeur d’obligation légale.</ows:Abstract>\n            <ows:WGS84BoundingBox>\n                <ows:LowerCorner>5.140242 45.398181</ows:LowerCorner>\n                <ows:UpperCorner>11.47757 48.230651</ows:UpperCorner>\n            </ows:WGS84BoundingBox>\n            <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>\n            <ows:Metadata xlink:href=\"http://www.swisstopo.admin.ch/SITiled/world/AdminBoundaries/metadata.htm\"/>\n            <Style>\n                <ows:Title>Agglomérations et villes isolées</ows:Title>\n                <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>\n                <LegendURL format=\"image/png\" xlink:href=\"http://api.geo.admin.ch/legend/ch.are.agglomerationen_isolierte_staedte-2000_fr.png\" />\n            </Style>\n            <Format>image/png</Format>\n            <Dimension>\n                <ows:Identifier>Time</ows:Identifier>\n                <Default>20090101</Default>\n                <Value>20090101</Value>\n            </Dimension>\n            <TileMatrixSetLink>\n                <TileMatrixSet>21781</TileMatrixSet>\n            </TileMatrixSetLink>\n        </Layer>\n        <TileMatrixSet>\n            <ows:Identifier>21781</ows:Identifier>\n            <ows:SupportedCRS>urn:ogc:def:crs:EPSG:1.0:21781</ows:SupportedCRS>\n            <TileMatrix>\n                <ows:Identifier>0</ows:Identifier>\n                <ScaleDenominator>14285750.5715</ScaleDenominator>\n                <TopLeftCorner>420000.0 350000.0</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>1</MatrixWidth>\n                <MatrixHeight>1</MatrixHeight>\n            </TileMatrix>\n        </TileMatrixSet>\n    </Contents>\n    <ServiceMetadataURL xlink:href=\"http://www.opengis.uab.es/SITiled/world/1.0.0/WMTSCapabilities.xml\"/>\n</Capabilities>\n--></div>\n<div id=\"arcgis\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Capabilities xmlns=\"http://www.opengis.net/wmts/1.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:gml=\"http://www.opengis.net/gml\" xsi:schemaLocation=\"http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd\" version=\"1.0.0\">\n    <ows:ServiceIdentification>\n        <ows:Title>WorldTimeZones</ows:Title>\n        <ows:ServiceType>OGC WMTS</ows:ServiceType>\n        <ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion>\n    </ows:ServiceIdentification>\n    <ows:OperationsMetadata>\n        <ows:Operation name=\"GetTile\">\n            <ows:DCP>\n                <ows:HTTP>\n                    <ows:Get xlink:href=\"http://sampleserver6.arcgisonline.com/arcgis/rest/services/WorldTimeZones/MapServer/WMTS/tile/1.0.0/\">\n                        <ows:Constraint name=\"GetEncoding\">\n                            <ows:AllowedValues>\n                                <ows:Value>RESTful</ows:Value>\n                            </ows:AllowedValues>\n                        </ows:Constraint>\n                    </ows:Get>\n                    <ows:Get xlink:href=\"http://sampleserver6.arcgisonline.com/arcgis/rest/services/WorldTimeZones/MapServer/WMTS?\">\n                        <ows:Constraint name=\"GetEncoding\">\n                            <ows:AllowedValues>\n                                <ows:Value>KVP</ows:Value>\n                            </ows:AllowedValues>\n                        </ows:Constraint>\n                    </ows:Get>\n                </ows:HTTP>\n            </ows:DCP>\n        </ows:Operation>\n    </ows:OperationsMetadata>\n    <Contents>\n        <Layer>\n            <ows:Title>WorldTimeZones</ows:Title>\n            <ows:Identifier>WorldTimeZones</ows:Identifier>\n            <ows:BoundingBox crs=\"urn:ogc:def:crs:EPSG::102100\">\n                <ows:LowerCorner>-2.0037507067161843E7 -3.024097195838617E7</ows:LowerCorner>\n                <ows:UpperCorner>2.0037507067161843E7 3.0240971458386205E7</ows:UpperCorner>\n            </ows:BoundingBox>\n            <ows:WGS84BoundingBox crs=\"urn:ogc:def:crs:OGC:2:84\">\n                <ows:LowerCorner>-179.99999550841463 -88.99999992161119</ows:LowerCorner>\n                <ows:UpperCorner>179.99999550841463 88.99999992161118</ows:UpperCorner>\n            </ows:WGS84BoundingBox>\n            <Style isDefault=\"true\">\n                <ows:Title>Default Style</ows:Title>\n                <ows:Identifier>default</ows:Identifier>\n            </Style>\n            <Format>image/png</Format>\n            <TileMatrixSetLink>\n                <TileMatrixSet>GoogleMapsCompatible</TileMatrixSet>\n            </TileMatrixSetLink>\n            <ResourceURL format=\"image/png\" resourceType=\"tile\" template=\"http://sampleserver6.arcgisonline.com/arcgis/rest/services/WorldTimeZones/MapServer/WMTS/tile/1.0.0/WorldTimeZones/{Style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png\" />\n        </Layer>\n        <TileMatrixSet>\n            <ows:Title>GoogleMapsCompatible</ows:Title>\n            <ows:Abstract>the wellknown 'GoogleMapsCompatible' tile matrix set defined by OGC WMTS specification</ows:Abstract>\n            <ows:Identifier>GoogleMapsCompatible</ows:Identifier>\n            <ows:SupportedCRS>urn:ogc:def:crs:EPSG:6.18:3:3857</ows:SupportedCRS>\n            <WellKnownScaleSet>urn:ogc:def:wkss:OGC:1.0:GoogleMapsCompatible</WellKnownScaleSet>\n            <TileMatrix>\n                <ows:Identifier>5</ows:Identifier>\n                <ScaleDenominator>17471320.75089743</ScaleDenominator>\n                <TopLeftCorner>-20037508.34278925 20037508.34278925</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>32</MatrixWidth>\n                <MatrixHeight>32</MatrixHeight>\n            </TileMatrix>\n        </TileMatrixSet>\n    </Contents>\n    <ServiceMetadataURL xlink:href=\"http://sampleserver6.arcgisonline.com/arcgis/rest/services/WorldTimeZones/MapServer/WMTS/1.0.0/WMTSCapabilities.xml\" />\n</Capabilities>\n--></div>\n\n<div id=\"multi-getile-2\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Capabilities xmlns=\"http://www.opengis.net/wmts/1.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:gml=\"http://www.opengis.net/gml\" xsi:schemaLocation=\"http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd\" version=\"1.0.0\">\n    <ows:OperationsMetadata>\n        <ows:Operation name=\"GetCapabilities\">\n            <ows:DCP>\n                <ows:HTTP>\n                    <ows:Get xlink:href=\"http://wmts.geo.admin.ch/1.0.0/WMTSCapabilities.xml\">\n                        <ows:Constraint name=\"GetEncoding\">\n                            <ows:AllowedValues>\n                                <ows:Value>REST</ows:Value>\n                            </ows:AllowedValues>\n                        </ows:Constraint>\n                    </ows:Get>\n                </ows:HTTP>\n            </ows:DCP>\n        </ows:Operation>\n        <ows:Operation name=\"GetTile\">\n            <ows:DCP>\n                <ows:HTTP>\n                    <ows:Get xlink:href=\"http://wmts.geo.admin.ch/kvp\">\n                        <ows:Constraint name=\"GetEncoding\">\n                            <ows:AllowedValues>\n                                <ows:Value>KVP</ows:Value>\n                            </ows:AllowedValues>\n                        </ows:Constraint>\n                    </ows:Get>\n                    <ows:Get xlink:href=\"http://wmts.geo.admin.ch/rest\">\n                        <ows:Constraint name=\"GetEncoding\">\n                            <ows:AllowedValues>\n                                <ows:Value>REST</ows:Value>\n                            </ows:AllowedValues>\n                        </ows:Constraint>\n                    </ows:Get>\n                </ows:HTTP>\n            </ows:DCP>\n        </ows:Operation>\n    </ows:OperationsMetadata>\n    <Contents>\n        <Layer>\n            <ows:Title>Agglomérations et villes isolées</ows:Title>\n            <ows:Abstract>Les agglomérations et villes isolées (communes non rattachées à une agglomération et comptant au moins 10`000 habitants) font partie des régions d’analyse de la statistique suisse. Ce niveau géographique est défini depuis plus de 100 ans, afin de mesurer l’urbanisation, phénomène fondamental structurant l’organisation du territoire. Sa fonction principale est de permettre une comparaison spatiale entre des espaces urbains inégalement délimités sur le plan institutionnel. Une version ancienne est appliquée pour la première fois en 1930, puis révisée en 1984 et 1990, toujours sur la base des recensements de la population. La version actuelle classe les 2896 communes de Suisse (état 2000) selon leur appartenance ou pas à une agglomération ou ville isolée en fonction de critères statistiques (Etat et évolution de la population, lien de continuité de la zone bâtie, rapport entre population active occupée et population résidante, structure économique et flux de pendulaires). Les agglomérations et les villes isolées forment l`espace urbain, les territoires restant l`espace rural. La définition des agglomérations de l’OFS n’a pas valeur d’obligation légale.</ows:Abstract>\n            <ows:WGS84BoundingBox>\n                <ows:LowerCorner>5.140242 45.398181</ows:LowerCorner>\n                <ows:UpperCorner>11.47757 48.230651</ows:UpperCorner>\n            </ows:WGS84BoundingBox>\n            <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>\n            <ows:Metadata xlink:href=\"http://www.swisstopo.admin.ch/SITiled/world/AdminBoundaries/metadata.htm\"/>\n            <Style>\n                <ows:Title>Agglomérations et villes isolées</ows:Title>\n                <ows:Identifier>ch.are.agglomerationen_isolierte_staedte-2000</ows:Identifier>\n                <LegendURL format=\"image/png\" xlink:href=\"http://api.geo.admin.ch/legend/ch.are.agglomerationen_isolierte_staedte-2000_fr.png\" />\n            </Style>\n            <Format>image/png</Format>\n            <Dimension>\n                <ows:Identifier>Time</ows:Identifier>\n                <Default>20090101</Default>\n                <Value>20090101</Value>\n            </Dimension>\n            <TileMatrixSetLink>\n                <TileMatrixSet>21781</TileMatrixSet>\n            </TileMatrixSetLink>\n        </Layer>\n        <TileMatrixSet>\n            <ows:Identifier>21781</ows:Identifier>\n            <ows:SupportedCRS>urn:ogc:def:crs:EPSG:1.0:21781</ows:SupportedCRS>\n            <TileMatrix>\n                <ows:Identifier>0</ows:Identifier>\n                <ScaleDenominator>14285750.5715</ScaleDenominator>\n                <TopLeftCorner>420000.0 350000.0</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>1</MatrixWidth>\n                <MatrixHeight>1</MatrixHeight>\n            </TileMatrix>\n        </TileMatrixSet>\n    </Contents>\n    <ServiceMetadataURL xlink:href=\"http://www.opengis.uab.es/SITiled/world/1.0.0/WMTSCapabilities.xml\"/>\n</Capabilities>\n--></div>\n\n<div id=\"French-IGN-GeoPortal\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Capabilities xmlns=\"http://www.opengis.net/wmts/1.0\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" version=\"1.0.0\" xsi:schemaLocation=\"http://www.opengis.net/wmts/1.0 http://schemas.opengis.net/wmts/1.0/wmtsGetCapabilities_response.xsd\">\n    <ows:ServiceIdentification>\n        <ows:Title>Service de visualisation WMTS</ows:Title>\n        <ows:Abstract>Ce service permet la visualisation de couches de données raster IGN au travers d'un flux WMTS</ows:Abstract>\n        <ows:Keywords>\n            <ows:Keyword>Unités administratives</ows:Keyword>\n            <ows:Keyword>Limites administratives</ows:Keyword>\n        </ows:Keywords>\n        <ows:ServiceType>OGC WMTS</ows:ServiceType>\n        <ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion>\n        <ows:Fees>licences</ows:Fees>\n        <ows:AccessConstraints>Conditions Générales d'Utilisation disponibles ici : http://professionnels.ign.fr/sites/default/files/CGU_API_Pro.pdf</ows:AccessConstraints>\n    </ows:ServiceIdentification>\n    <ows:ServiceProvider>\n        <ows:ProviderName>IGN</ows:ProviderName>\n        <ows:ProviderSite xlink:href=\"\" />\n        <ows:ServiceContact>\n            <ows:IndividualName>Géoportail SAV</ows:IndividualName>\n            <ows:PositionName>custodian</ows:PositionName>\n            <ows:ContactInfo>\n                <ows:Phone>\n                    <ows:Voice />\n                    <ows:Facsimile />\n                </ows:Phone>\n                <ows:Address>\n                    <ows:DeliveryPoint>73 avenue de Paris</ows:DeliveryPoint>\n                    <ows:City>Saint Mandé</ows:City>\n                    <ows:AdministrativeArea />\n                    <ows:PostalCode>94160</ows:PostalCode>\n                    <ows:Country>France</ows:Country>\n                    <ows:ElectronicMailAddress>geop_services@geoportail.fr</ows:ElectronicMailAddress>\n                </ows:Address>\n            </ows:ContactInfo>\n        </ows:ServiceContact>\n    </ows:ServiceProvider>\n    <ows:OperationsMetadata>\n        <ows:Operation name=\"GetCapabilities\">\n            <ows:DCP>\n                <ows:HTTP>\n                    <ows:Get xlink:href=\"http://wxs.ign.fr/wnmz6nt68k09rw3f5vwaflk4/wmts?\">\n                        <ows:Constraint name=\"GetEncoding\">\n                            <ows:AllowedValues>\n                                <ows:Value>KVP</ows:Value>\n                            </ows:AllowedValues>\n                        </ows:Constraint>\n                    </ows:Get>\n                </ows:HTTP>\n            </ows:DCP>\n        </ows:Operation>\n        <ows:Operation name=\"GetTile\">\n            <ows:DCP>\n                <ows:HTTP>\n                    <ows:Get xlink:href=\"http://wxs.ign.fr/wnmz6nt68k09rw3f5vwaflk4/wmts?\">\n                        <ows:Constraint name=\"GetEncoding\">\n                            <ows:AllowedValues>\n                                <ows:Value>KVP</ows:Value>\n                            </ows:AllowedValues>\n                        </ows:Constraint>\n                    </ows:Get>\n                </ows:HTTP>\n            </ows:DCP>\n        </ows:Operation>\n    </ows:OperationsMetadata>\n    <Contents>\n        <Layer>\n            <ows:Title>Limites administratives</ows:Title>\n            <ows:Abstract>Représentation des limites administratives (régions, départements, cantons, communes)</ows:Abstract>\n            <ows:Keywords>\n                <ows:Keyword>Unités administratives</ows:Keyword>\n            </ows:Keywords>\n            <ows:WGS84BoundingBox>\n                <ows:LowerCorner>-63.3725 -21.4756</ows:LowerCorner>\n                <ows:UpperCorner>55.9259 72.679</ows:UpperCorner>\n            </ows:WGS84BoundingBox>\n            <ows:Identifier>ADMINISTRATIVEUNITS.BOUNDARIES</ows:Identifier>\n            <Style isDefault=\"true\">\n                <ows:Title>Données Brutes</ows:Title>\n                <ows:Abstract>Données brutes sans changement de palette</ows:Abstract>\n                <ows:Keywords>\n                    <ows:Keyword>Défaut</ows:Keyword>\n                </ows:Keywords>\n                <ows:Identifier>normal</ows:Identifier>\n                <LegendURL format=\"image/png\" height=\"1\" maxScaleDenominator=\"100000000\" minScaleDenominator=\"200\" width=\"1\" xlink:href=\"http://gpp3-wxs.ign.fr/static/LEGENDES/NOLEGEND.JPG\" />\n            </Style>\n            <Format>image/png</Format>\n            <InfoFormat>text/plain</InfoFormat>\n            <InfoFormat>text/html</InfoFormat>\n            <InfoFormat>application/vnd.ogc.gml</InfoFormat>\n            <TileMatrixSetLink>\n                <TileMatrixSet>PM</TileMatrixSet>\n                <TileMatrixSetLimits>\n                    <TileMatrixLimits>\n                        <TileMatrix>10</TileMatrix>\n                        <MinTileRow>336</MinTileRow>\n                        <MaxTileRow>576</MaxTileRow>\n                        <MinTileCol>336</MinTileCol>\n                        <MaxTileCol>671</MaxTileCol>\n                    </TileMatrixLimits>\n                    <TileMatrixLimits>\n                        <TileMatrix>11</TileMatrix>\n                        <MinTileRow>680</MinTileRow>\n                        <MaxTileRow>1152</MaxTileRow>\n                        <MinTileCol>672</MinTileCol>\n                        <MaxTileCol>1344</MaxTileCol>\n                    </TileMatrixLimits>\n                    <TileMatrixLimits>\n                        <TileMatrix>12</TileMatrix>\n                        <MinTileRow>1368</MinTileRow>\n                        <MaxTileRow>2304</MaxTileRow>\n                        <MinTileCol>1344</MinTileCol>\n                        <MaxTileCol>2687</MaxTileCol>\n                    </TileMatrixLimits>\n                    <TileMatrixLimits>\n                        <TileMatrix>13</TileMatrix>\n                        <MinTileRow>2736</MinTileRow>\n                        <MaxTileRow>4608</MaxTileRow>\n                        <MinTileCol>2688</MinTileCol>\n                        <MaxTileCol>5376</MaxTileCol>\n                    </TileMatrixLimits>\n                    <TileMatrixLimits>\n                        <TileMatrix>14</TileMatrix>\n                        <MinTileRow>5472</MinTileRow>\n                        <MaxTileRow>9200</MaxTileRow>\n                        <MinTileCol>5376</MinTileCol>\n                        <MaxTileCol>10735</MaxTileCol>\n                    </TileMatrixLimits>\n                    <TileMatrixLimits>\n                        <TileMatrix>15</TileMatrix>\n                        <MinTileRow>10943</MinTileRow>\n                        <MaxTileRow>18384</MaxTileRow>\n                        <MinTileCol>10624</MinTileCol>\n                        <MaxTileCol>21472</MaxTileCol>\n                    </TileMatrixLimits>\n                    <TileMatrixLimits>\n                        <TileMatrix>16</TileMatrix>\n                        <MinTileRow>21904</MinTileRow>\n                        <MaxTileRow>36768</MaxTileRow>\n                        <MinTileCol>21264</MinTileCol>\n                        <MaxTileCol>42943</MaxTileCol>\n                    </TileMatrixLimits>\n                    <TileMatrixLimits>\n                        <TileMatrix>17</TileMatrix>\n                        <MinTileRow>43824</MinTileRow>\n                        <MaxTileRow>73520</MaxTileRow>\n                        <MinTileCol>42528</MinTileCol>\n                        <MaxTileCol>85871</MaxTileCol>\n                    </TileMatrixLimits>\n                    <TileMatrixLimits>\n                        <TileMatrix>18</TileMatrix>\n                        <MinTileRow>87648</MinTileRow>\n                        <MaxTileRow>147024</MaxTileRow>\n                        <MinTileCol>85071</MinTileCol>\n                        <MaxTileCol>171743</MaxTileCol>\n                    </TileMatrixLimits>\n                    <TileMatrixLimits>\n                        <TileMatrix>6</TileMatrix>\n                        <MinTileRow>12</MinTileRow>\n                        <MaxTileRow>29</MaxTileRow>\n                        <MinTileCol>26</MinTileCol>\n                        <MaxTileCol>42</MaxTileCol>\n                    </TileMatrixLimits>\n                    <TileMatrixLimits>\n                        <TileMatrix>7</TileMatrix>\n                        <MinTileRow>24</MinTileRow>\n                        <MaxTileRow>58</MaxTileRow>\n                        <MinTileCol>54</MinTileCol>\n                        <MaxTileCol>84</MaxTileCol>\n                    </TileMatrixLimits>\n                    <TileMatrixLimits>\n                        <TileMatrix>8</TileMatrix>\n                        <MinTileRow>49</MinTileRow>\n                        <MaxTileRow>114</MaxTileRow>\n                        <MinTileCol>108</MinTileCol>\n                        <MaxTileCol>168</MaxTileCol>\n                    </TileMatrixLimits>\n                    <TileMatrixLimits>\n                        <TileMatrix>9</TileMatrix>\n                        <MinTileRow>168</MinTileRow>\n                        <MaxTileRow>288</MaxTileRow>\n                        <MinTileCol>160</MinTileCol>\n                        <MaxTileCol>336</MaxTileCol>\n                    </TileMatrixLimits>\n                </TileMatrixSetLimits>\n            </TileMatrixSetLink>\n        </Layer>\n        <TileMatrixSet>\n            <ows:Identifier>PM</ows:Identifier>\n            <ows:SupportedCRS>EPSG:3857</ows:SupportedCRS>\n            <TileMatrix>\n                <ows:Identifier>0</ows:Identifier>\n                <ScaleDenominator>559082264.0287178958533332</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>1</MatrixWidth>\n                <MatrixHeight>1</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>1</ows:Identifier>\n                <ScaleDenominator>279541132.0143588959472254</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>2</MatrixWidth>\n                <MatrixHeight>2</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>10</ows:Identifier>\n                <ScaleDenominator>545978.7734655447186469</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>1024</MatrixWidth>\n                <MatrixHeight>1024</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>11</ows:Identifier>\n                <ScaleDenominator>272989.3867327723085907</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>2048</MatrixWidth>\n                <MatrixHeight>2048</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>12</ows:Identifier>\n                <ScaleDenominator>136494.6933663861796617</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>4096</MatrixWidth>\n                <MatrixHeight>4096</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>13</ows:Identifier>\n                <ScaleDenominator>68247.3466831930771477</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>8192</MatrixWidth>\n                <MatrixHeight>8192</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>14</ows:Identifier>\n                <ScaleDenominator>34123.6733415965449154</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>16384</MatrixWidth>\n                <MatrixHeight>16384</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>15</ows:Identifier>\n                <ScaleDenominator>17061.8366707982724577</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>32768</MatrixWidth>\n                <MatrixHeight>32768</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>16</ows:Identifier>\n                <ScaleDenominator>8530.9183353991362289</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>65536</MatrixWidth>\n                <MatrixHeight>65536</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>17</ows:Identifier>\n                <ScaleDenominator>4265.4591676995681144</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>131072</MatrixWidth>\n                <MatrixHeight>131072</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>18</ows:Identifier>\n                <ScaleDenominator>2132.7295838497840572</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>262144</MatrixWidth>\n                <MatrixHeight>262144</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>19</ows:Identifier>\n                <ScaleDenominator>1066.3647919248918304</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>524288</MatrixWidth>\n                <MatrixHeight>524288</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>2</ows:Identifier>\n                <ScaleDenominator>139770566.0071793960087234</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>4</MatrixWidth>\n                <MatrixHeight>4</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>20</ows:Identifier>\n                <ScaleDenominator>533.1823959624461134</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>1048576</MatrixWidth>\n                <MatrixHeight>1048576</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>21</ows:Identifier>\n                <ScaleDenominator>266.5911979812228585</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>2097152</MatrixWidth>\n                <MatrixHeight>2097152</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>3</ows:Identifier>\n                <ScaleDenominator>69885283.0035897239868063</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>8</MatrixWidth>\n                <MatrixHeight>8</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>4</ows:Identifier>\n                <ScaleDenominator>34942641.5017948619934032</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>16</MatrixWidth>\n                <MatrixHeight>16</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>5</ows:Identifier>\n                <ScaleDenominator>17471320.7508974309967016</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>32</MatrixWidth>\n                <MatrixHeight>32</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>6</ows:Identifier>\n                <ScaleDenominator>8735660.3754487154983508</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>64</MatrixWidth>\n                <MatrixHeight>64</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>7</ows:Identifier>\n                <ScaleDenominator>4367830.1877243577491754</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>128</MatrixWidth>\n                <MatrixHeight>128</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>8</ows:Identifier>\n                <ScaleDenominator>2183915.0938621788745877</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>256</MatrixWidth>\n                <MatrixHeight>256</MatrixHeight>\n            </TileMatrix>\n            <TileMatrix>\n                <ows:Identifier>9</ows:Identifier>\n                <ScaleDenominator>1091957.5469310886252288</ScaleDenominator>\n                <TopLeftCorner>-20037508 20037508</TopLeftCorner>\n                <TileWidth>256</TileWidth>\n                <TileHeight>256</TileHeight>\n                <MatrixWidth>512</MatrixWidth>\n                <MatrixHeight>512</MatrixHeight>\n            </TileMatrix>\n        </TileMatrixSet>\n    </Contents>\n</Capabilities>\n--></div>\n\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WMTSCapabilities.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    \n    function test_initialize(t) {\n        \n        t.plan(1);\n        var format = new OpenLayers.Format.WMTSCapabilities({\n            version: \"foo\"\n        });\n        t.eq(format.version, \"foo\", \"version set on format\");\n        \n    }\n    \n    </script> \n</head> \n<body>\n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WPSCapabilities/v1_0_0.html",
    "content": "<html>\n<head>\n    <script src=\"../../OLLoader.js\"></script>\n    <script src=\"v1_0_0.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_read(t) {\n\n        t.plan(7);\n\n        var format = new OpenLayers.Format.WPSCapabilities();\n        var obj = format.read(doc);\n\n        t.eq(obj.version, \"1.0.0\", \"Version parsed correctly\");\n\n        t.eq(obj.languages.length, 2, \"2 language entries parsed\");\n        t.eq(obj.languages[0].isDefault, true, \"First language is the default language\");\n        t.eq(obj.languages[0].language, \"en-US\", \"First language is US English\");\n\n        var buffer = obj.processOfferings[\"JTS:buffer\"];\n        t.eq(buffer.processVersion, \"1.0.0\", \"processVersion for buffer is 1.0.0\");\n        t.eq(buffer.abstract, \"Buffers a geometry using a certain distance\", \"Buffer abstract correctly read\");\n        t.eq(buffer.title, \"Buffers a geometry using a certain distance\", \"Buffer title correctly read\");\n    }\n\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WPSCapabilities/v1_0_0.js",
    "content": "var doc = new OpenLayers.Format.XML().read(\n'<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n'<wps:Capabilities xml:lang=\"en\" service=\"WPS\" version=\"1.0.0\"' +\n'    xsi:schemaLocation=\"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd\"' +\n'    xmlns:wps=\"http://www.opengis.net/wps/1.0.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\"' +\n'    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">' +\n'    <ows:ServiceIdentification>' +\n'        <ows:Title>Prototype GeoServer WPS</ows:Title>' +\n'        <ows:Abstract/>' +\n'        <ows:ServiceType>WPS</ows:ServiceType>' +\n'        <ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion>' +\n'    </ows:ServiceIdentification>' +\n'    <ows:ServiceProvider>' +\n'        <ows:ProviderName>The ancient geographes INC</ows:ProviderName>' +\n'        <ows:ProviderSite xlink:href=\"http://geoserver.org\"/>' +\n'        <ows:ServiceContact/>' +\n'    </ows:ServiceProvider>' +\n'    <ows:OperationsMetadata>' +\n'        <ows:Operation name=\"GetCapabilities\">' +\n'            <ows:DCP>' +\n'                <ows:HTTP>' +\n'                    <ows:Get xlink:href=\"http://localhost:8080/geoserver/wps\"/>' +\n'                    <ows:Post xlink:href=\"http://localhost:8080/geoserver/wps\"/>' +\n'                </ows:HTTP>' +\n'            </ows:DCP>' +\n'        </ows:Operation>' +\n'        <ows:Operation name=\"DescribeProcess\">' +\n'            <ows:DCP>' +\n'                <ows:HTTP>' +\n'                    <ows:Get xlink:href=\"http://localhost:8080/geoserver/wps\"/>' +\n'                    <ows:Post xlink:href=\"http://localhost:8080/geoserver/wps\"/>' +\n'                </ows:HTTP>' +\n'            </ows:DCP>' +\n'        </ows:Operation>' +\n'        <ows:Operation name=\"Execute\">' +\n'            <ows:DCP>' +\n'                <ows:HTTP>' +\n'                    <ows:Get xlink:href=\"http://localhost:8080/geoserver/wps\"/>' +\n'                    <ows:Post xlink:href=\"http://localhost:8080/geoserver/wps\"/>' +\n'                </ows:HTTP>' +\n'            </ows:DCP>' +\n'        </ows:Operation>' +\n'    </ows:OperationsMetadata>' +\n'    <wps:ProcessOfferings>' +\n'        <wps:Process wps:processVersion=\"1.0.0\">' +\n'            <ows:Identifier>gt:Intersect</ows:Identifier>' +\n'            <ows:Title>Intersection</ows:Title>' +\n'            <ows:Abstract>Intersection between two literal geometry</ows:Abstract>' +\n'        </wps:Process>' +\n'        <wps:Process wps:processVersion=\"1.0.0\">' +\n'            <ows:Identifier>JTS:length</ows:Identifier>' +\n'            <ows:Title>Returns the geometry perimeters, computed using cartesian geometry' +\n'                expressions in the same unit of measure as the geometry (will not return a valid' +\n'                perimeter for geometries expressed geographic coordinates</ows:Title>' +\n'            <ows:Abstract>Returns the geometry perimeters, computed using cartesian geometry' +\n'                expressions in the same unit of measure as the geometry (will not return a valid' +\n'                perimeter for geometries expressed geographic coordinates</ows:Abstract>' +\n'        </wps:Process>' +\n'        <wps:Process wps:processVersion=\"1.0.0\">' +\n'            <ows:Identifier>JTS:isEmpty</ows:Identifier>' +\n'            <ows:Title>Checks if the provided geometry is empty</ows:Title>' +\n'            <ows:Abstract>Checks if the provided geometry is empty</ows:Abstract>' +\n'        </wps:Process>' +\n'        <wps:Process wps:processVersion=\"1.0.0\">' +\n'            <ows:Identifier>JTS:contains</ows:Identifier>' +\n'            <ows:Title>Checks if a contains b</ows:Title>' +\n'            <ows:Abstract>Checks if a contains b</ows:Abstract>' +\n'        </wps:Process>' +\n'        <wps:Process wps:processVersion=\"1.0.0\">' +\n'            <ows:Identifier>JTS:disjoint</ows:Identifier>' +\n'            <ows:Title>Returns true if the two geometries have no points in common</ows:Title>' +\n'            <ows:Abstract>Returns true if the two geometries have no points in common</ows:Abstract>' +\n'        </wps:Process>' +\n'        <wps:Process wps:processVersion=\"1.0.0\">' +\n'            <ows:Identifier>JTS:intersects</ows:Identifier>' +\n'            <ows:Title>Returns true if the two geometries intersect, false otherwise</ows:Title>' +\n'            <ows:Abstract>Returns true if the two geometries intersect, false' +\n'                otherwise</ows:Abstract>' +\n'        </wps:Process>' +\n'        <wps:Process wps:processVersion=\"1.0.0\">' +\n'            <ows:Identifier>JTS:isClosed</ows:Identifier>' +\n'            <ows:Title>Returns true if the line is closed</ows:Title>' +\n'            <ows:Abstract>Returns true if the line is closed</ows:Abstract>' +\n'        </wps:Process>' +\n'        <wps:Process wps:processVersion=\"1.0.0\">' +\n'            <ows:Identifier>JTS:isValid</ows:Identifier>' +\n'            <ows:Title>Returns true if the geometry is topologically valid, false' +\n'                otherwise</ows:Title>' +\n'            <ows:Abstract>Returns true if the geometry is topologically valid, false' +\n'                otherwise</ows:Abstract>' +\n'        </wps:Process>' +\n'        <wps:Process wps:processVersion=\"1.0.0\">' +\n'            <ows:Identifier>JTS:buffer</ows:Identifier>' +\n'            <ows:Title>Buffers a geometry using a certain distance</ows:Title>' +\n'            <ows:Abstract>Buffers a geometry using a certain distance</ows:Abstract>' +\n'        </wps:Process>' +\n'        <wps:Process wps:processVersion=\"1.0.0\">' +\n'            <ows:Identifier>JTS:getY</ows:Identifier>' +\n'            <ows:Title>Returns the Y ordinate of the point</ows:Title>' +\n'            <ows:Abstract>Returns the Y ordinate of the point</ows:Abstract>' +\n'        </wps:Process>' +\n'    </wps:ProcessOfferings>' +\n'    <wps:Languages>' +\n'        <wps:Default>' +\n'            <ows:Language>en-US</ows:Language>' +\n'        </wps:Default>' +\n'        <wps:Supported>' +\n'            <ows:Language>en-US</ows:Language>' +\n'        </wps:Supported>' +\n'    </wps:Languages>' +\n'</wps:Capabilities>'\n);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WPSDescribeProcess.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_read_WPSDescribeProcess(t) {\n        t.plan(17);\n\n        var parser = new OpenLayers.Format.WPSDescribeProcess();\n        var text =\n'<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n'<wps:ProcessDescriptions xml:lang=\"en\" service=\"WPS\" version=\"1.0.0\" xmlns:wps=\"http://www.opengis.net/wps/1.0.0\"' +\n'    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"' +\n'    xsi:schemaLocation=\"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd\"' +\n'    xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">' +\n'    <ProcessDescription wps:processVersion=\"1.0.0\" statusSupported=\"false\"' +\n'        storeSupported=\"false\">' +\n'        <ows:Identifier>JTS:buffer</ows:Identifier>' +\n'        <ows:Title>Buffers a geometry using a certain distance</ows:Title>' +\n'        <ows:Abstract>Buffers a geometry using a certain distance</ows:Abstract>' +\n'        <DataInputs>' +\n'            <Input maxOccurs=\"1\" minOccurs=\"1\">' +\n'                <ows:Identifier>geom</ows:Identifier>' +\n'                <ows:Title>geom</ows:Title>' +\n'                <ows:Abstract>The geometry to be buffered</ows:Abstract>' +\n'                <ComplexData>' +\n'                    <Default>' +\n'                        <Format>' +\n'                            <MimeType>text/xml; subtype=gml/3.1.1</MimeType>' +\n'                        </Format>' +\n'                    </Default>' +\n'                    <Supported>' +\n'                        <Format>' +\n'                            <MimeType>text/xml; subtype=gml/3.1.1</MimeType>' +\n'                        </Format>' +\n'                        <Format>' +\n'                            <MimeType>text/xml; subtype=gml/2.1.2</MimeType>' +\n'                        </Format>' +\n'                        <Format>' +\n'                            <MimeType>application/wkt</MimeType>' +\n'                        </Format>' +\n'                        <Format>' +\n'                            <MimeType>application/gml-3.1.1</MimeType>' +\n'                        </Format>' +\n'                        <Format>' +\n'                            <MimeType>application/gml-2.1.2</MimeType>' +\n'                        </Format>' +\n'                    </Supported>' +\n'                </ComplexData>' +\n'            </Input>' +\n'            <Input maxOccurs=\"1\" minOccurs=\"1\">' +\n'                <ows:Identifier>distance</ows:Identifier>' +\n'                <ows:Title>distance</ows:Title>' +\n'                <ows:Abstract>The distance (same unit of measure as the geometry)</ows:Abstract>' +\n'                <LiteralData>' +\n'                    <ows:DataType>xs:double</ows:DataType>' +\n'                    <ows:AnyValue/>' +\n'                </LiteralData>' +\n'            </Input>' +\n'            <Input maxOccurs=\"1\" minOccurs=\"0\">' +\n'                <ows:Identifier>quadrantSegments</ows:Identifier>' +\n'                <ows:Title>quadrantSegments</ows:Title>' +\n'                <ows:Abstract>Number of quadrant segments. Use &gt; 0 for round joins, 0 for' +\n'                    flat joins, &lt; 0 for mitred joins</ows:Abstract>' +\n'                <LiteralData>' +\n'                    <ows:DataType>xs:int</ows:DataType>' +\n'                    <ows:AnyValue/>' +\n'                </LiteralData>' +\n'            </Input>' +\n'            <Input maxOccurs=\"1\" minOccurs=\"0\">' +\n'                <ows:Identifier>capStyle</ows:Identifier>' +\n'                <ows:Title>capStyle</ows:Title>' +\n'                <ows:Abstract>The buffer cap style, round, flat, square</ows:Abstract>' +\n'                <LiteralData>' +\n'                    <ows:AllowedValues>' +\n'                        <ows:Value>Round</ows:Value>' +\n'                        <ows:Value>Flat</ows:Value>' +\n'                        <ows:Value>Square</ows:Value>' +\n'                    </ows:AllowedValues>' +\n'                </LiteralData>' +\n'            </Input>' +\n'        </DataInputs>' +\n'        <ProcessOutputs>' +\n'            <Output>' +\n'                <ows:Identifier>result</ows:Identifier>' +\n'                <ows:Title>result</ows:Title>' +\n'                <ComplexOutput>' +\n'                    <Default>' +\n'                        <Format>' +\n'                            <MimeType>text/xml; subtype=gml/3.1.1</MimeType>' +\n'                        </Format>' +\n'                    </Default>' +\n'                    <Supported>' +\n'                        <Format>' +\n'                            <MimeType>text/xml; subtype=gml/3.1.1</MimeType>' +\n'                        </Format>' +\n'                        <Format>' +\n'                            <MimeType>text/xml; subtype=gml/2.1.2</MimeType>' +\n'                        </Format>' +\n'                        <Format>' +\n'                            <MimeType>application/wkt</MimeType>' +\n'                        </Format>' +\n'                        <Format>' +\n'                            <MimeType>application/gml-3.1.1</MimeType>' +\n'                        </Format>' +\n'                        <Format>' +\n'                            <MimeType>application/gml-2.1.2</MimeType>' +\n'                        </Format>' +\n'                    </Supported>' +\n'                </ComplexOutput>' +\n'            </Output>' +\n'            <Output>' +\n'                <ows:Identifier>literal</ows:Identifier>' +\n'                <ows:Title>literal output</ows:Title>' +\n'                <LiteralOutput>' +\n'                   <ows:DataType ows:reference=\"http://www.w3.org/TR/xmlschema-2/#integer\">integer</ows:DataType>'+\n'                </LiteralOutput>' +\n'            </Output>' +\n'        </ProcessOutputs>' +\n'    </ProcessDescription>' +\n'</wps:ProcessDescriptions>';\n\n        var res = parser.read(text);\n        var buffer = res.processDescriptions[\"JTS:buffer\"];\n        t.eq(buffer.statusSupported, false, \"statusSupported read correctly\");\n        t.eq(buffer.storeSupported, false, \"storeSupported read correctly\");\n        t.eq(buffer.processVersion, \"1.0.0\", \"processVersion read correctly\");\n        var capStyle = buffer.dataInputs[3];\n        t.eq(capStyle.abstract, \"The buffer cap style, round, flat, square\", \"capStyle abstract read correctly\");\n        t.eq(capStyle.minOccurs, 0, \"capStyle minOccurs read correctly\");\n        t.eq(capStyle.maxOccurs, 1, \"maxOccurs read correctly\");\n        t.eq(capStyle.literalData.allowedValues[\"Flat\"], true, \"capStyle allowedValues read correctly\");\n        var distance = buffer.dataInputs[1];\n        t.eq(distance.literalData.anyValue, true, \"distance anyValue read correctly\");\n        t.eq(distance.literalData.dataType, \"xs:double\", \"distance dataType read correctly\");\n        var geom = buffer.dataInputs[0];\n        t.eq(geom.complexData[\"default\"].formats[\"text/xml; subtype=gml/3.1.1\"], true, \"geom complexData default read correctly\");\n        t.eq(geom.complexData[\"supported\"].formats[\"application/gml-2.1.2\"], true, \"geom complexData supported read correctly [1/2]\");\n        t.eq(geom.complexData[\"supported\"].formats[\"application/gml-3.1.1\"], true, \"geom complexData supported read correctly [2/2]\");\n        var result = buffer.processOutputs[0];\n        t.eq(result.complexOutput[\"default\"].formats[\"text/xml; subtype=gml/3.1.1\"], true, \"processOutputs default format read correctly\");\n        t.eq(result.complexOutput[\"supported\"].formats[\"text/xml; subtype=gml/3.1.1\"], true, \"processOutputs supported format read correctly [1/2]\");\n        t.eq(result.complexOutput[\"supported\"].formats[\"application/wkt\"], true, \"processOutputs supported format read correctly [1/2]\");\n\n        var literalresult = buffer.processOutputs[1];\n        t.eq(literalresult.literalOutput.dataType, \"integer\", \"processOutputs supported data type read corectly\");\n\n        text = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n'<wps:ProcessDescriptions service=\"WPS\" version=\"1.0.0\" xmlns:wps=\"http://www.opengis.net/wps/1.0.0\"' +\n'    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xml:lang=\"en\"' +\n'    xsi:schemaLocation=\"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd\"' +\n'    xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">' +\n'    <ProcessDescription wps:processVersion=\"1.0.0\" statusSupported=\"false\"' +\n'        storeSupported=\"false\">' +\n'        <ows:Identifier>gt:VectorToRaster</ows:Identifier>' +\n'        <ows:Title>Rasterize features</ows:Title>' +\n'        <ows:Abstract>Rasterize all or selected features in a FeatureCollection</ows:Abstract>' +\n'        <DataInputs>' +\n'            <Input maxOccurs=\"1\" minOccurs=\"0\">' +\n'                <ows:Identifier>bounds</ows:Identifier>' +\n'                <ows:Title>Bounds</ows:Title>' +\n'                <ows:Abstract>Bounds of the area to rasterize</ows:Abstract>' +\n'                <BoundingBoxData>' +\n'                    <Default>' +\n'                        <CRS>EPSG:4326</CRS>' +\n'                    </Default>' +\n'                    <Supported>' +\n'                        <CRS>EPSG:4326</CRS>' +\n'                    </Supported>' +\n'                </BoundingBoxData>' +\n'            </Input>' +\n'        </DataInputs>' +\n'        <ProcessOutputs>' +\n'            <Output>' +\n'                <ows:Identifier>result</ows:Identifier>' +\n'                <ows:Title>Result</ows:Title>' +\n'                <ComplexOutput>' +\n'                    <Default>' +\n'                        <Format>' +\n'                            <MimeType>image/tiff</MimeType>' +\n'                        </Format>' +\n'                    </Default>' +\n'                    <Supported>' +\n'                        <Format>' +\n'                            <MimeType>image/tiff</MimeType>' +\n'                        </Format>' +\n'                        <Format>' +\n'                            <MimeType>application/arcgrid</MimeType>' +\n'                        </Format>' +\n'                    </Supported>' +\n'                </ComplexOutput>' +\n'            </Output>' +\n'        </ProcessOutputs>' +\n'    </ProcessDescription>' +\n'</wps:ProcessDescriptions>';\n\n        res = parser.read(text);\n        var vector2Raster = res.processDescriptions[\"gt:VectorToRaster\"];\n        t.eq(vector2Raster.dataInputs[0].boundingBoxData[\"default\"].CRSs[\"EPSG:4326\"], true, \"BoundingBoxData CRS parsed correctly\");\n    }\n\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/WPSExecute.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    function test_write_WPSExecute_WCS(t) {\n        t.plan(1);\n        var expected = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n'<wps:Execute version=\"1.0.0\" service=\"WPS\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://www.opengis.net/wps/1.0.0\" xmlns:wfs=\"http://www.opengis.net/wfs\" xmlns:wps=\"http://www.opengis.net/wps/1.0.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:wcs=\"http://www.opengis.net/wcs\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xsi:schemaLocation=\"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd\">' +\n'  <ows:Identifier>gs:GeorectifyCoverage</ows:Identifier>' +\n'  <wps:DataInputs>' +\n'    <wps:Input>' +\n'      <ows:Identifier>data</ows:Identifier>' +\n'      <wps:Reference mimeType=\"image/tiff\" xlink:href=\"http://geoserver/wcs\" method=\"POST\">' +\n'        <wps:Body>' +\n'          <wcs:GetCoverage service=\"WCS\" version=\"1.1.2\">' +\n'            <ows:Identifier>topp:asbuilt</ows:Identifier>' +\n'            <wcs:DomainSubset>' +\n'              <ows:BoundingBox crs=\"http://www.opengis.net/gml/srs/epsg.xml#404000\">' +\n'                <ows:LowerCorner>0 -7070</ows:LowerCorner>' +\n'                <ows:UpperCorner>10647 1</ows:UpperCorner>' +\n'              </ows:BoundingBox>' +\n'            </wcs:DomainSubset>' +\n'            <wcs:Output format=\"image/tiff\"/>' +\n'          </wcs:GetCoverage>' +\n'        </wps:Body>' +\n'      </wps:Reference>' +\n'    </wps:Input>' +\n'    <wps:Input>' +\n'      <ows:Identifier>gcp</ows:Identifier>' +\n'      <wps:Data>' +\n'        <wps:LiteralData>[[[2721, 3263], [-122.472109, 37.73106003]], [[4163, 3285], [-122.4693417, 37.729929851]], [[5773, 4046], [-122.466702461, 37.7271906]], [[8885, 4187], [-122.462333, 37.725167]]]</wps:LiteralData>' +\n'      </wps:Data>' +\n'    </wps:Input>' +\n'    <wps:Input>' +\n'      <ows:Identifier>targetCRS</ows:Identifier>' +\n'      <wps:Data>' +\n'        <wps:LiteralData>EPSG:4326</wps:LiteralData>' +\n'      </wps:Data>' +\n'    </wps:Input>' +\n'    <wps:Input>' +\n'      <ows:Identifier>transparent</ows:Identifier>' +\n'      <wps:Data>' +\n'        <wps:LiteralData>true</wps:LiteralData>' +\n'      </wps:Data>' +\n'    </wps:Input>' +\n'  </wps:DataInputs>' +\n'  <wps:ResponseForm>' +\n'    <wps:RawDataOutput mimeType=\"image/tiff\">' +\n'      <ows:Identifier>result</ows:Identifier>' +\n'    </wps:RawDataOutput>' +\n'  </wps:ResponseForm>' +\n'</wps:Execute>';\n\n        var format = new OpenLayers.Format.WPSExecute();\n        var result = format.write({\n            identifier: \"gs:GeorectifyCoverage\", \n            dataInputs: [{\n                identifier: 'data',\n                reference: {\n                    mimeType: \"image/tiff\", \n                    href: \"http://geoserver/wcs\", \n                    method: \"POST\",\n                    body: {\n                        wcs: {\n                            identifier: 'topp:asbuilt',\n                            version: '1.1.2',\n                            domainSubset: {\n                                boundingBox: {\n                                    projection: 'http://www.opengis.net/gml/srs/epsg.xml#404000',\n                                    bounds: new OpenLayers.Bounds(0.0, -7070.0, 10647.0, 1.0)\n                                }\n                            },\n                            output: {format: 'image/tiff'}\n                        }\n                    }\n                }\n            }, {\n                identifier: 'gcp',\n                data: {\n                    literalData: {\n                        value: '[[[2721, 3263], [-122.472109, 37.73106003]], [[4163, 3285], [-122.4693417, 37.729929851]], [[5773, 4046], [-122.466702461, 37.7271906]], [[8885, 4187], [-122.462333, 37.725167]]]'\n                    }\n                }\n            }, {\n                identifier: 'targetCRS',\n                data: {\n                    literalData: {\n                        value: 'EPSG:4326'\n                    }\n                }\n            }, {\n                identifier: 'transparent',\n                data: {\n                    literalData: {\n                        value: 'true'\n                    }\n                }\n            }],\n            responseForm: {\n                rawDataOutput: {\n                    mimeType: \"image/tiff\",\n                    identifier: \"result\"\n                }\n            }\n        });\n        t.xml_eq(result, expected, \"WPS Execute with embedded WCS GetCoverage written out correctly\");\n\n    }\n\n    function test_write_WPSExecute(t) {\n        t.plan(1);\n        var expected = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n'<wps:Execute version=\"1.0.0\" service=\"WPS\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"' +\n'    xmlns=\"http://www.opengis.net/wps/1.0.0\" xmlns:wfs=\"http://www.opengis.net/wfs\"' +\n'    xmlns:wps=\"http://www.opengis.net/wps/1.0.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\"' +\n'    xmlns:gml=\"http://www.opengis.net/gml\" xmlns:ogc=\"http://www.opengis.net/ogc\"' +\n'    xmlns:wcs=\"http://www.opengis.net/wcs/1.1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"' +\n'    xsi:schemaLocation=\"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd\">' +\n'    <ows:Identifier>JTS:area</ows:Identifier>' +\n'    <wps:DataInputs>' +\n'        <wps:Input>' +\n'            <ows:Identifier>geom</ows:Identifier>' +\n'            <wps:Reference mimeType=\"text/xml; subtype=gml/3.1.1\" xlink:href=\"http://geoserver/wps\"' +\n'                method=\"POST\">' +\n'                <wps:Body>' +\n'                    <wps:Execute service=\"WPS\" version=\"1.0.0\">' +\n'                        <ows:Identifier>gs:CollectGeometries</ows:Identifier>' +\n'                        <wps:DataInputs>' +\n'                            <wps:Input>' +\n'                                <ows:Identifier>features</ows:Identifier>' +\n'                                <wps:Reference mimeType=\"text/xml; subtype=wfs-collection/1.0\"' +\n'                                    xlink:href=\"http://geoserver/wfs\" method=\"POST\">' +\n'                                    <wps:Body>' +\n'                                        <wfs:GetFeature service=\"WFS\" version=\"1.0.0\"' +\n'                                            outputFormat=\"GML2\">' +\n'                                            <wfs:Query typeName=\"sf:archsites\"/>' +\n'                                        </wfs:GetFeature>' +\n'                                    </wps:Body>' +\n'                                </wps:Reference>' +\n'                            </wps:Input>' +\n'                        </wps:DataInputs>' +\n'                        <wps:ResponseForm>' +\n'                            <wps:RawDataOutput mimeType=\"text/xml; subtype=gml/3.1.1\">' +\n'                                <ows:Identifier>result</ows:Identifier>' +\n'                            </wps:RawDataOutput>' +\n'                        </wps:ResponseForm>' +\n'                    </wps:Execute>' +\n'                </wps:Body>' +\n'            </wps:Reference>' +\n'        </wps:Input>' +\n'    </wps:DataInputs>' +\n'    <wps:ResponseForm>' +\n'        <wps:RawDataOutput>' +\n'            <ows:Identifier>result</ows:Identifier>' +\n'        </wps:RawDataOutput>' +\n'    </wps:ResponseForm>' +\n'</wps:Execute>';\n\n        var format = new OpenLayers.Format.WPSExecute();\n        var result = format.write({\n            identifier: \"JTS:area\", \n            dataInputs: [{\n                identifier: 'geom',\n                reference: {\n                    mimeType: \"text/xml; subtype=gml/3.1.1\", \n                    href: \"http://geoserver/wps\", \n                    method: \"POST\",\n                    body: {\n                        identifier: \"gs:CollectGeometries\",\n                        dataInputs: [{\n                             identifier: 'features',\n                             reference: {\n                                 mimeType: \"text/xml; subtype=wfs-collection/1.0\",\n                                 href: \"http://geoserver/wfs\",\n                                 method: \"POST\",\n                                 body: {\n                                     wfs: {\n                                         version: \"1.0.0\",\n                                         outputFormat: \"GML2\",\n                                         featureType: \"sf:archsites\"\n                                     }\n                                 }\n                             }\n                         }],\n                         responseForm: {\n                             rawDataOutput: {\n                                 mimeType: \"text/xml; subtype=gml/3.1.1\",\n                                 identifier: \"result\"\n                             }\n                         }\n                    }\n                }\n            }],\n            responseForm: {\n                rawDataOutput: {\n                    identifier: \"result\"\n                }\n            }\n        });\n        t.xml_eq(result, expected, \"WPS Execute written out correctly\");\n    }\n\n    function test_write_raw_data_output(t) {\n        t.plan(1);\n        // example request taken from: http://geoprocessing.info/wpsdoc/1x0ExecutePOST\n        var expected = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>' +\n'<wps:Execute service=\"WPS\" version=\"1.0.0\" xmlns:wps=\"http://www.opengis.net/wps/1.0.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" ' +\n'xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd\">' +\n'\t<ows:Identifier>Buffer</ows:Identifier>' +\n'\t<wps:DataInputs>' +\n'\t\t<wps:Input>' +\n'\t\t\t<ows:Identifier>InputPolygon</ows:Identifier>' +\n'\t\t\t<ows:Title>Playground area</ows:Title>' +\n'\t\t\t<wps:Reference xlink:href=\"http://foo.bar/some_WFS_request.xml\"/>' +\n'\t\t</wps:Input>' +\n'\t\t<wps:Input>' +\n'\t\t\t<ows:Identifier>BufferDistance</ows:Identifier>' +\n'\t\t\t<ows:Title>Distance which people will walk to get to a playground.</ows:Title>' +\n'\t\t\t<wps:Data>' +\n'\t\t\t\t<wps:LiteralData>400</wps:LiteralData>' +\n'\t\t\t</wps:Data>' +\n'\t\t</wps:Input>' +\n'\t</wps:DataInputs>' +\n'\t<wps:ResponseForm>' +\n'\t\t<wps:RawDataOutput>' +\n'\t\t\t<ows:Identifier>BufferedPolygon</ows:Identifier>' +\n'\t\t</wps:RawDataOutput>' +\n'\t</wps:ResponseForm>' +\n'</wps:Execute>';\n\n        var format = new OpenLayers.Format.WPSExecute();\n        var result = format.write({\n            identifier: \"Buffer\", \n            dataInputs: [{\n                identifier: 'InputPolygon',\n                title: 'Playground area',\n                reference: {\n                    href: 'http://foo.bar/some_WFS_request.xml'\n                }\n            }, {\n                identifier: 'BufferDistance',\n                title: 'Distance which people will walk to get to a playground.',\n                data: {\n                    literalData: {\n                        value: 400\n                    }\n                }\n            }],\n            responseForm: {\n                rawDataOutput: {\n                    identifier: \"BufferedPolygon\"\n                }\n            }\n        });\n        t.xml_eq(result, expected, \"WPS Execute written out correctly\");\n    }\n\n    function test_write_request_responseDoc_defaultFormat(t) {\n        t.plan(1);\n        // taken from http://geoprocessing.info/schemas/wps/1.0/examples/51_wpsExecute_request_ResponseDocument.xml\n        var expected = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>' +\n'<wps:Execute service=\"WPS\" version=\"1.0.0\" xmlns:wps=\"http://www.opengis.net/wps/1.0.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" ' +\n'xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd\">' +\n'\t<ows:Identifier>Buffer</ows:Identifier>' +\n'\t<wps:DataInputs>' +\n'\t\t<wps:Input>' +\n'\t\t\t<ows:Identifier>InputPolygon</ows:Identifier>' +\n'\t\t\t<ows:Title>Playground area</ows:Title>' +\n'\t\t\t<wps:Reference xlink:href=\"http://foo.bar/some_WFS_request.xml\"/>' +\n'\t\t</wps:Input>' +\n'\t\t<wps:Input>' +\n'\t\t\t<ows:Identifier>BufferDistance</ows:Identifier>' +\n'\t\t\t<ows:Title>Distance which people will walk to get to a playground.</ows:Title>' +\n'\t\t\t<wps:Data>' +\n'\t\t\t\t<wps:LiteralData>400</wps:LiteralData>' +\n'\t\t\t</wps:Data>' +\n'\t\t</wps:Input>' +\n'\t</wps:DataInputs>' +\n'\t<wps:ResponseForm>' +\n'\t\t<wps:ResponseDocument storeExecuteResponse=\"true\">' +\n'\t\t\t<wps:Output asReference=\"true\">' +\n'\t\t\t\t<ows:Identifier>BufferedPolygon</ows:Identifier>' +\n'\t\t\t\t<ows:Title>Area serviced by playground.</ows:Title>' +\n'\t\t\t\t<ows:Abstract>Area within which most users of this playground will live.</ows:Abstract>' +\n'\t\t\t</wps:Output>' +\n'\t\t</wps:ResponseDocument>' +\n'\t</wps:ResponseForm>' +\n'</wps:Execute>';\n\n        var format = new OpenLayers.Format.WPSExecute();\n        var result = format.write({\n            identifier: \"Buffer\", \n            dataInputs: [{\n                identifier: 'InputPolygon',\n                title: 'Playground area',\n                reference: {\n                    href: 'http://foo.bar/some_WFS_request.xml'\n                }\n            }, {\n                identifier: 'BufferDistance',\n                title: 'Distance which people will walk to get to a playground.',\n                data: {\n                    literalData: {\n                        value: 400\n                    }\n                }                    \n            }],\n            responseForm: {\n                responseDocument: {\n                    storeExecuteResponse: true,\n                    outputs: [{\n                        asReference: true,\n                        identifier: 'BufferedPolygon',\n                        title: 'Area serviced by playground.',\n                        'abstract': 'Area within which most users of this playground will live.'\n                    }]\n                }\n            }\n        });\n        t.xml_eq(result, expected, \"WPS Execute written out correctly\");\n    }\n\n    function test_write_request_responseDoc_specifiedFormat(t) {\n        t.plan(1);\n        // taken from http://geoprocessing.info/schemas/wps/1.0/examples/52_wpsExecute_request_ResponseDocument.xml\n        var expected = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>' +\n'<wps:Execute service=\"WPS\" version=\"1.0.0\" xmlns:wps=\"http://www.opengis.net/wps/1.0.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" ' +\n'xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd\">' +\n'\t<ows:Identifier>Buffer</ows:Identifier>' +\n'\t<wps:DataInputs>' +\n'\t\t<wps:Input>' +\n'\t\t\t<ows:Identifier>InputPolygon</ows:Identifier>' +\n'\t\t\t<ows:Title>Playground area</ows:Title>' +\n'\t\t\t<wps:Reference xlink:href=\"http://foo.bar/some_WFS_request.xml\" method=\"POST\" mimeType=\"text/xml\" encoding=\"UTF-8\" schema=\"http://foo.bar/gml_polygon_schema.xsd\"/>' +\n'\t\t</wps:Input>' +\n'\t\t<wps:Input>' +\n'\t\t\t<ows:Identifier>BufferDistance</ows:Identifier>' +\n'\t\t\t<ows:Title>Distance which people will walk to get to a playground.</ows:Title>' +\n'\t\t\t<wps:Data>' +\n'\t\t\t\t<wps:LiteralData uom=\"feet\">400</wps:LiteralData>' +\n'\t\t\t</wps:Data>' +\n'\t\t</wps:Input>' +\n'\t</wps:DataInputs>' +\n'\t<wps:ResponseForm>' +\n'\t\t<wps:ResponseDocument storeExecuteResponse=\"true\" lineage=\"true\" status=\"true\">' +\n'\t\t\t<wps:Output asReference=\"true\">' +\n'\t\t\t\t<ows:Identifier>BufferedPolygon</ows:Identifier>' +\n'\t\t\t\t<ows:Title>Area serviced by playground.</ows:Title>' +\n'\t\t\t\t<ows:Abstract>Area within which most users of this playground will live.</ows:Abstract>' +\n'\t\t\t</wps:Output>' +\n'\t\t\t<wps:Output>' +\n'\t\t\t\t<ows:Identifier>literal</ows:Identifier>' +\n'                               <ows:Title/>' +\n'                               <ows:Abstract/>' +\n'\t\t\t</wps:Output>' +\n'\t\t</wps:ResponseDocument>' +\n'\t</wps:ResponseForm>' +\n'</wps:Execute>';\n\n        var format = new OpenLayers.Format.WPSExecute();\n        var result = format.write({\n            identifier: \"Buffer\",\n            dataInputs: [{\n                identifier: 'InputPolygon',\n                title: 'Playground area',\n                reference: {\n                    href: 'http://foo.bar/some_WFS_request.xml',\n                    method: \"POST\",\n                    mimeType: \"text/xml\",\n                    encoding: \"UTF-8\",\n                    schema: \"http://foo.bar/gml_polygon_schema.xsd\"\n                }\n            }, {\n                identifier: 'BufferDistance',\n                title: 'Distance which people will walk to get to a playground.',\n                data: {\n                    literalData: {\n                        value: 400,\n                        uom: 'feet'\n                    }\n                }\n            }],\n            responseForm: {\n                responseDocument: {\n                    storeExecuteResponse: true,\n                    lineage: true,\n                    status: true,\n                    outputs: [\n                        {\n                            asReference: true,\n                            identifier: 'BufferedPolygon',\n                            title: 'Area serviced by playground.',\n                            'abstract': 'Area within which most users of this playground will live.'\n                        },\n                        {\n                            identifier: 'literal'\n                        }\n                    ]\n                }\n            }\n        });\n        t.xml_eq(result, expected, \"WPS Execute written out correctly\");\n    }\n\n        function test_write_request_complexData(t) {\n            t.plan(1);\n            // taken from http://geoprocessing.info/schemas/wps/1.0/examples/51_wpsExecute_request_ResponseDocument.xml\n            var expected = '<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>' +\n    '<wps:Execute service=\"WPS\" version=\"1.0.0\" xmlns:wps=\"http://www.opengis.net/wps/1.0.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" ' +\n    'xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd\">' +\n    '\t<ows:Identifier>Buffer</ows:Identifier>' +\n    '\t<wps:DataInputs>' +\n    '\t\t<wps:Input>' +\n    '\t\t\t<ows:Identifier>InputPolygon</ows:Identifier>' +\n    '\t\t\t<ows:Title>Playground area</ows:Title>' +\n    '\t\t\t<wps:Reference xlink:href=\"http://foo.bar/some_WFS_request.xml\"/>' +\n    '\t\t</wps:Input>' +\n    '\t\t<wps:Input>' +\n    '\t\t\t<ows:Identifier>ResultPage</ows:Identifier>' +\n    '\t\t\t<ows:Title>Nicely formatted HTML of the result</ows:Title>' +\n    '\t\t\t<wps:Data>' +\n    '\t\t\t\t<wps:ComplexData><![CDATA[<html><head></head><body></body></head>]]></wps:ComplexData>' +\n    '\t\t\t</wps:Data>' +\n    '\t\t</wps:Input>' +\n    '           <wps:Input>' +\n    '                   <ows:Identifier>GMLPoint</ows:Identifier>' +\n    '                   <ows:Title>Point as GML</ows:Title>' +\n    '                   <wps:Data>' +\n    '                           <wps:ComplexData><feature:geometry xmlns:feature=\"http://www.opengis.net/gml\"><feature:Point><feature:pos>10 10</feature:pos></feature:Point></feature:geometry></wps:ComplexData>' +\n    '                   </wps:Data>' +\n    '           </wps:Input>' +\n    '\t</wps:DataInputs>' +\n    '\t<wps:ResponseForm>' +\n    '\t\t<wps:ResponseDocument storeExecuteResponse=\"true\">' +\n    '\t\t\t<wps:Output asReference=\"true\">' +\n    '\t\t\t\t<ows:Identifier>BufferedPolygon</ows:Identifier>' +\n    '\t\t\t\t<ows:Title>Area serviced by playground.</ows:Title>' +\n    '\t\t\t\t<ows:Abstract>Area within which most users of this playground will live.</ows:Abstract>' +\n    '\t\t\t</wps:Output>' +\n    '\t\t</wps:ResponseDocument>' +\n    '\t</wps:ResponseForm>' +\n    '</wps:Execute>';\n\n            var format = new OpenLayers.Format.WPSExecute();\n            var result = format.write({\n                identifier: \"Buffer\", \n                dataInputs: [{\n                    identifier: 'InputPolygon',\n                    title: 'Playground area',\n                    reference: {\n                        href: 'http://foo.bar/some_WFS_request.xml'\n                    }\n                }, {\n                    identifier: 'ResultPage',\n                    title: 'Nicely formatted HTML of the result',\n                    data: {\n                        complexData: {\n                            value: \"<html><head></head><body></body></head>\"\n                        }\n                    }                    \n                }, {\n                    identifier: \"GMLPoint\",\n                    title: \"Point as GML\",\n                    data: {\n                        complexData: {\n                            value: OpenLayers.Format.GML.v3.prototype.writers.feature[\"_geometry\"].apply(new OpenLayers.Format.GML.v3({curve: true, surface: true}), [new OpenLayers.Geometry.Point(10, 10)])\n                        }\n                    }\n                }],\n                responseForm: {\n                    responseDocument: {\n                        storeExecuteResponse: true,\n                        outputs: [{\n                            asReference: true,\n                            identifier: 'BufferedPolygon',\n                            title: 'Area serviced by playground.',\n                            'abstract': 'Area within which most users of this playground will live.'\n                        }]\n                    }\n                }\n            });\n            t.xml_eq(result, expected, \"WPS Execute written out correctly\");\n        }\n\n        function test_write_WPSExecuteFID(t) {\n            t.plan(1);\n          \n            var result,\n            expected,\n            format = ({geometryName: 'the_geom'});                    \n          \n            expected = '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n                '<wps:Execute xmlns:wps=\"http://www.opengis.net/wps/1.0.0\" version=\"1.0.0\" service=\"WPS\" xsi:schemaLocation=\"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">' +\n                '  <ows:Identifier xmlns:ows=\"http://www.opengis.net/ows/1.1\">gs:Bounds</ows:Identifier>' +\n                '  <wps:DataInputs>' +\n                '    <wps:Input>' +\n                '      <ows:Identifier xmlns:ows=\"http://www.opengis.net/ows/1.1\">features</ows:Identifier>' +\n                '      <wps:Reference mimeType=\"text/xml\" xlink:href=\"http://geoserver/wfs\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" method=\"POST\">' +\n                '        <wps:Body>' +\n                '          <wfs:GetFeature xmlns:wfs=\"http://www.opengis.net/wfs\" service=\"WFS\" version=\"1.0.0\">' +\n                '            <wfs:Query typeName=\"foo:bar\">' +\n                '              <ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">' +\n                '                <ogc:FeatureId fid=\"123\"/>' +\n                '              </ogc:Filter>' +\n                '            </wfs:Query>' +\n                '          </wfs:GetFeature>' +\n                '        </wps:Body>' +\n                '      </wps:Reference>' +\n                '    </wps:Input>' +\n                '  </wps:DataInputs>' +\n                '  <wps:ResponseForm>' +\n                '    <wps:RawDataOutput>' +\n                '      <ows:Identifier xmlns:ows=\"http://www.opengis.net/ows/1.1\">bounds</ows:Identifier>' +\n                '    </wps:RawDataOutput>' +\n                '  </wps:ResponseForm>' +\n                '</wps:Execute>';\n\n            result = new OpenLayers.Format.WPSExecute().write({\n                identifier: 'gs:Bounds',\n                dataInputs: [{\n                    identifier: 'features',\n                    reference: {\n                        mimeType: 'text/xml',\n                        href: 'http://geoserver/wfs',\n                        method: 'POST',\n                        body: {\n                            wfs: {\n                                featureType: 'foo:bar',\n                                version: '1.0.0',                            \n                                filter: new OpenLayers.Filter.FeatureId({fids: [123]})\n                            }\n                        }\n                    }\n                }],\n                responseForm: {\n                    rawDataOutput: {\n                        identifier: 'bounds'\n                    }\n                }\n            });\n            t.xml_eq(result, expected, 'WPS Execute written out correctly with a FID filter');\n        }\n\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/XLS/v1_1_0.html",
    "content": "<html>\n<head>\n    <script src=\"../../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n    function test_read(t) {\n        t.plan(16);\n        var response = '<xls:GeocodeResponse xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/xls http://schemas.opengis.net/ols/1.1.0/LocationUtilityService.xsd\" xmlns:xls=\"http://www.opengis.net/xls\" xmlns:gml=\"http://www.opengis.net/gml\"><xls:GeocodeResponseList numberOfGeocodedAddresses=\"1\"><xls:GeocodedAddress><gml:Point srsName=\"EPSG:28992\"><gml:pos dimension=\"2\">122650 483904</gml:pos></gml:Point><xls:Address countryCode=\"NL\"><xls:StreetAddress><xls:Building number=\"1\"/><xls:Street>president kennedylaan</xls:Street></xls:StreetAddress><xls:Place type=\"MunicipalitySubdivision\">amsterdam</xls:Place><xls:Place type=\"Municipality\">amsterdam</xls:Place><xls:Place type=\"CountrySubdivision\">noord holland</xls:Place><xls:PostalCode>1079MB</xls:PostalCode></xls:Address></xls:GeocodedAddress></xls:GeocodeResponseList></xls:GeocodeResponse>';\n        var format = new OpenLayers.Format.XLS();\n        var output = format.read(response);\n        t.eq(output.responseLists.length, 1, \"Output contains 1 responseList\");\n        var responseList = output.responseLists[0];\n        t.eq(responseList.numberOfGeocodedAddresses, 1, \"Responselist contains 1 geocoded address\");\n        t.eq(responseList.features.length, 1, \"1 feature parsed\");\n        var feature = responseList.features[0];\n        var address = feature.attributes.address;\n        t.eq(address.building[\"number\"], \"1\", \"Building number correctly parsed\");\n        t.eq(address.countryCode, \"NL\", \"Country code correctly parsed\");\n        t.eq(address.place.CountrySubdivision, \"noord holland\", \"CountrySubDivision correctly parsed\");\n        t.eq(address.place.Municipality, \"amsterdam\", \"Municipality correctly parsed\");\n        t.eq(address.place.MunicipalitySubdivision, \"amsterdam\", \"MunicipalitySubdivision correctly parsed\");\n        t.eq(address.postalCode, \"1079MB\", \"Postalcode correctly parsed\");\n        t.eq(address.street[0], \"president kennedylaan\", \"Street correctly parsed\");\n        t.eq(feature.geometry.x, 122650, \"Geometry [x] correctly parsed\");\n        t.eq(feature.geometry.y, 483904, \"Geometry [y] correctly parsed\");\n\n        var responseList = [];\n        responseList.push('<?xml version=\"1.0\" encoding=\"UTF-8\" ?>',\n'<XLS xmlns=\"http://www.opengis.net/xls\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/xls LocationUtilityService.xsd\" version=\"1.1\">',\n'\t<ResponseHeader/>',\n'\t<Response version=\"1.1\" requestID=\"\">',\n'\t\t<GeocodeResponse>',\n'\t\t\t<GeocodeResponseList numberOfGeocodedAddresses=\"2\">',\n'\t\t\t\t<GeocodedAddress>',\n'\t\t\t\t\t<gml:Point>',\n'\t\t\t\t\t\t<gml:pos>-71.4589837781615 41.8317239069808</gml:pos>',\n'\t\t\t\t\t</gml:Point>',\n'\t\t\t\t\t<Address countryCode=\"\">',\n'\t\t\t\t\t\t<StreetAddress>',\n'\t\t\t\t\t\t\t<Street></Street>',\n'\t\t\t\t\t\t\t<Street/>',\n'\t\t\t\t\t\t</StreetAddress>',\n'\t\t\t\t\t\t<Place type=\"Municipality\"></Place>',\n'\t\t\t\t\t\t<Place type=\"CountrySubdivision\"></Place>',\n'\t\t\t\t\t\t<PostalCode></PostalCode>',\n'\t\t\t\t\t</Address>',\n'\t\t\t\t\t<GeocodeMatchCode accuracy=\"100.0\"/>',\n'\t\t\t\t</GeocodedAddress>',\n'\t\t\t\t<GeocodedAddress>',\n'\t\t\t\t\t<gml:Point>',\n'\t\t\t\t\t\t<gml:pos>-71.4087296631643 41.8269575002255</gml:pos>',\n'\t\t\t\t\t</gml:Point>',\n'\t\t\t\t\t<Address countryCode=\"\">',\n'\t\t\t\t\t\t<StreetAddress>',\n'\t\t\t\t\t\t\t<Street></Street>',\n'\t\t\t\t\t\t\t<Street/>',\n'\t\t\t\t\t\t</StreetAddress>',\n'\t\t\t\t\t\t<Place type=\"Municipality\"></Place>',\n'\t\t\t\t\t\t<Place type=\"CountrySubdivision\"></Place>',\n'\t\t\t\t\t\t<PostalCode></PostalCode>',\n'\t\t\t\t\t</Address>',\n'\t\t\t\t\t<GeocodeMatchCode accuracy=\"100.0\"/>',\n'\t\t\t\t</GeocodedAddress>',\n'\t\t\t</GeocodeResponseList>',\n'\t\t</GeocodeResponse>',\n'\t</Response>',\n'</XLS>');\n        response = responseList.join(\"\");\n        output = format.read(response);\n        t.eq(output.version, \"1.1\", \"Version correctly parsed\");\n        var responseList = output.responseLists[0];\n        t.eq(responseList.numberOfGeocodedAddresses, 2, \"2 addresses parsed\");\n        t.eq(responseList.features.length, 2, \"2 features parsed\");\n        t.eq(responseList.features[0].attributes.matchCode.accuracy, 100.0, \"Accuracy correctly parsed\");\n    }\n\n    function test_write(t) {\n        t.plan(1);\n\n        var format = new OpenLayers.Format.XLS();\n        var address = {\n            countryCode: 'US',\n            street: '1 Freedom Rd',\n            municipality: 'Providence',\n            countrySubdivision: 'RI',\n            postalCode: '02909'\n        };\n        var request = format.write({addresses: [address]});\n\n        var expected = '<xls:XLS xmlns:xls=\"http://www.opengis.net/xls\" version=\"1.1\" xsi:schemaLocation=\"http://www.opengis.net/xls http://schemas.opengis.net/ols/1.1.0/LocationUtilityService.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><xls:RequestHeader/><xls:Request methodName=\"GeocodeRequest\" requestID=\"\" version=\"1.1\"><xls:GeocodeRequest><xls:Address countryCode=\"US\"><xls:StreetAddress><xls:Street>1 Freedom Rd</xls:Street></xls:StreetAddress><xls:Place type=\"Municipality\">Providence</xls:Place><xls:Place type=\"CountrySubdivision\">RI</xls:Place><xls:PostalCode>02909</xls:PostalCode></xls:Address></xls:GeocodeRequest></xls:Request></xls:XLS>';\n\n        t.xml_eq(request, expected, \"XLS geocode request correctly written\");\n    }\n\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/XML/VersionedOGC.html",
    "content": "<html> \n<head> \n    <script src=\"../../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    var snippet = '<foo version=\"2.0.0\"></foo>';\n    var snippet2 = '<foo></foo>';\n\n    function test_Format_Versioned_constructor(t) { \n        t.plan(5); \n         \n        var format = new OpenLayers.Format.XML.VersionedOGC({version: \"1.0.0\"}); \n        t.ok(format instanceof OpenLayers.Format.XML.VersionedOGC, \n             \"new OpenLayers.Format.XML.VersionedOGC returns object\" ); \n        t.eq(format.version, \"1.0.0\", \"constructor sets version correctly\");\n        t.eq(format.defaultVersion, null, \"defaultVersion should be null if not specified\");\n        t.eq(typeof format.read, \"function\", \"format has a read function\");\n        t.eq(typeof format.write, \"function\", \"format has a read function\");\n    }\n\n    function test_getVersion(t) {\n        t.plan(6);\n        var format = new OpenLayers.Format.XML.VersionedOGC();\n        // read\n        var data = new OpenLayers.Format.XML().read(snippet);\n        var root = data.documentElement;\n        var version = format.getVersion(root);\n        t.eq(version, \"2.0.0\", \"Version taken from document\");\n        format = new OpenLayers.Format.XML.VersionedOGC({version: \"1.0.0\"});\n        version = format.getVersion(root);\n        t.eq(version, \"1.0.0\", \"Version taken from parser takes preference\");\n        format = new OpenLayers.Format.XML.VersionedOGC({defaultVersion: \"3.0.0\"});\n        data = new OpenLayers.Format.XML().read(snippet2);\n        root = data.documentElement;\n        version = format.getVersion(root);\n        t.eq(version, \"3.0.0\", \"If nothing else is set, defaultVersion should be returned\");\n        // write\n        version = format.getVersion(null, {version: \"1.3.0\"});\n        t.eq(version, \"1.3.0\", \"Version from options returned\");\n        version = format.getVersion(null);\n        t.eq(version, \"3.0.0\", \"defaultVersion returned if no version specified in options and no version on the format\");\n        format.version = \"2.1.3\";\n        version = format.getVersion(null);\n        t.eq(version, \"2.1.3\", \"version returned of the Format if no version specified in options\");\n    }\n\n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format/XML.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    var text =\n        '<?xml version=\"1.0\"?>' + \n        '<ol:root xmlns=\"http://namespace.default.net\" ' +\n                 'xmlns:ol=\"http://namespace.openlayers.org\" ' + \n                 'xmlns:ta=\"http://namespace.testattribute.net\">' +\n            '<ol:child ta:attribute=\"value1\" ' +\n                      'attribute=\"value2\">' +\n                'junk1' +\n            '<' + '/ol:child>' +\n            '<ol:child>junk2<' + '/ol:child>' +\n            '<ol:child>junk3<' + '/ol:child>' +\n            '<element>junk4<' + '/element>' + \n            '<ol:element>junk5<' + '/ol:element>' + \n            '<ol:p>' +\n                '<ol:a>junk' +\n                '<' + '/ol:a>' + \n                '<ol:b>junk' +\n                '<' + '/ol:b>' + \n                '<ol:a>junk' +\n                '<' + '/ol:a>' + \n            '<' + '/ol:p>' + \n        '<' + '/ol:root>';\n\n    function test_Format_XML_constructor(t) { \n        t.plan(13); \n         \n        var options = {'foo': 'bar'}; \n        var format = new OpenLayers.Format.XML(options); \n        t.ok(format instanceof OpenLayers.Format.XML, \n             \"new OpenLayers.Format.XML returns object\" ); \n        t.eq(format.foo, \"bar\", \"constructor sets options correctly\"); \n        t.eq(typeof format.read, \"function\", \"format has a read function\"); \n        t.eq(typeof format.write, \"function\", \"format has a write function\");\n\n        t.ok(!window.ActiveXObject || format.xmldom, \"browsers with activeX must have xmldom\");\n        \n        // test namespaces\n        t.ok(format.namespaces instanceof Object, \"format has namespace object\");\n        var namespaces = {\"foo\": \"bar\"};\n        format = new OpenLayers.Format.XML({namespaces: namespaces});\n        t.eq(format.namespaces, namespaces, \"format.namespaces correctly set in constructor\");\n        \n        // test default prefix\n        t.eq(format.defaultPrefix, null, \"defaultPrefix is null by default\");\n        format = new OpenLayers.Format.XML({defaultPrefix: \"foo\"});\n        t.eq(format.defaultPrefix, \"foo\", \"defaultPrefix correctly set in constructor\");\n\n        // test readers\n        t.ok(format.readers instanceof Object, \"format has readers object\");\n        var readers = {\"foo\": \"bar\"};\n        format = new OpenLayers.Format.XML({readers: readers});\n        t.eq(format.readers, readers, \"format.readers correctly set in constructor\");\n\n        // test readers\n        t.ok(format.writers instanceof Object, \"format has writers object\");\n        var writers = {\"foo\": \"bar\"};\n        format = new OpenLayers.Format.XML({writers: writers});\n        t.eq(format.writers, writers, \"format.writers correctly set in constructor\");\n    }\n    \n    function test_destroy(t) {\n        t.plan(1);\n        var format = new OpenLayers.Format.XML();\n        format.destroy();\n        t.eq(format.xmldom, null, \"xmldom set to null for all browsers\");\n    }\n\n    function test_Format_XML_read(t) {\n        \n        var format = new OpenLayers.Format.XML();\n        t.plan(format.xmldom ? 10 : 9);\n\n        var doc = format.read(text);\n        t.eq(doc.nodeType, 9,\n             \"doc has the correct node type\");\n        t.eq(doc.nodeName, \"#document\",\n             \"doc has the correct node name\");\n        t.ok(doc.documentElement,\n             \"ok to access doc.documentElement\");\n        t.xml_eq(doc.documentElement, text,\n                 \"doc.documentElement correctly read\");\n        \n        // read can also be called on the prototype directly\n        doc = OpenLayers.Format.XML.prototype.read(text);\n        t.eq(doc.nodeType, 9,\n             \"doc has the correct node type\");\n        t.eq(doc.nodeName, \"#document\",\n             \"doc has the correct node name\");\n        t.ok(doc.documentElement,\n             \"ok to access doc.documentElement\");\n        t.xml_eq(doc.documentElement, text,\n                 \"doc.documentElement correctly read\");\n        \n        // where appropriate, make sure doc is loaded into xmldom property\n        if(format.xmldom) {\n            t.xml_eq(format.xmldom.documentElement, text,\n                     \"xmldom.documentElement contains equivalent xml\");\n        }\n        \n        // test equivalence with different namespace alias\n        var pre1 = \n            \"<pre1:parent xmlns:pre1='http://namespace'>\" +\n                \"<pre1:child1>value2</pre1:child1>\" +\n                \"<pre1:child2 pre1:attr1='foo'>value2</pre1:child2>\" +\n                \"<pre1:child3 chicken:attr='hot' xmlns:chicken='http://soup'/>\" +\n            \"</pre1:parent>\";\n        var pre2 = \n            \"<pre2:parent xmlns:pre2='http://namespace'>\" +\n                \"<pre2:child1>value2</pre2:child1>\" +\n                \"<pre2:child2 pre2:attr1='foo'>value2</pre2:child2>\" +\n                \"<pre2:child3 pea:attr='hot' xmlns:pea='http://soup'/>\" +\n            \"</pre2:parent>\";\n        var doc1 = format.read(pre1);\n        t.xml_eq(doc1.documentElement, pre2, \"read correctly sets namespaces\");\n        \n    }\n\n    function test_Format_XML_write(t) {\n        t.plan(2);\n\n        var format = new OpenLayers.Format.XML();\n        var doc = format.read(text);\n        var out = format.write(doc);\n        out = out.replace(/[\\r\\n]/g, '');\n        out = out.replace( /<\\?.*\\?>/, '')\n        var expected = text.replace(/<\\?.*\\?>/, '')\n        t.eq(expected, out,\n             \"correctly writes an XML DOM doc\");\n        var out = format.write(\n          format.getElementsByTagNameNS(doc,\n           \"http://namespace.openlayers.org\",\"root\")[0]);\n        out = out.replace(/[\\r\\n]/g, '');\n        out = out.replace( /<\\?.*\\?>/, '')\n        t.eq(out, expected,\n             \"correctly writes an XML DOM node\");\n    }\n\n    function test_Format_XML_createElementNS(t) {\n        t.plan(5);\n\n        var format = new OpenLayers.Format.XML();\n        var uri = \"http://foo.com\";\n        var prefix = \"foo\";\n        var localName = \"bar\";\n        var qualifiedName = prefix + \":\" + localName;\n        var node = format.createElementNS(uri, qualifiedName);\n        t.eq(node.nodeType, 1,\n             \"node has correct type\");\n        t.eq(node.nodeName, qualifiedName,\n             \"node has correct qualified name\");\n        t.eq(node.prefix, prefix,\n             \"node has correct prefix\");\n        t.eq(node.namespaceURI, uri,\n             \"node has correct namespace uri\");\n        \n        var doc = format.read(text);\n        if (doc.importNode) {\n            node = doc.importNode(node, true);\n        }    \n        t.ok(doc.documentElement.appendChild(node),\n             \"node can be appended to a doc root\");\n    }\n\n    function test_createDocumentFragment(t) {\n        t.plan(3);\n\n        var format = new OpenLayers.Format.XML();\n        var uri = \"http://foo.com\";\n        var prefix = \"foo\";\n        var localName = \"bar\";\n        var qualifiedName = prefix + \":\" + localName;\n        var parent = format.createElementNS(uri, qualifiedName);\n\n        var fragment = format.createDocumentFragment();\n        t.eq(fragment.nodeType, 11, \"fragment type\");\n\n        try {\n            fragment.appendChild(format.createTextNode(\"one\"));\n            fragment.appendChild(format.createTextNode(\"two\"));\n            t.eq(fragment.childNodes.length, 2, \"fragment has two child nodes\");\n        } catch (err) {\n            t.fail(\"trouble appending text nodes to fragment: \" + err.message);\n        }\n\n        try {\n            parent.appendChild(fragment);\n            t.eq(parent.childNodes.length, 2, \"parent has two child nodes\");\n        } catch (err) {\n            t.fail(\"trouble appending fragment to parent: \" + err.message);\n        }\n    }\n\n    function test_Format_XML_createTextNode(t) {\n        t.plan(10);\n\n        var format = new OpenLayers.Format.XML();\n        var value, node;\n\n        value = \"string\";\n        node = format.createTextNode(value);\n        t.eq(node.nodeType, 3,\n             \"[string] node has correct type\");\n        t.eq(node.nodeName, \"#text\",\n             \"[string] node has correct name\");\n        t.eq(node.nodeValue, \"string\",\n             \"[string] node has correct value\");\n        \n        value = 0.42;\n        node = format.createTextNode(value);\n        t.eq(node.nodeType, 3,\n             \"[number] node has correct type\");\n        t.eq(node.nodeName, \"#text\",\n             \"[number] node has correct name\");\n        t.eq(node.nodeValue, \"0.42\",\n             \"[number] node has correct value\");\n\n        value = false;\n        node = format.createTextNode(value);\n        t.eq(node.nodeType, 3,\n             \"[boolean] node has correct type\");\n        t.eq(node.nodeName, \"#text\",\n             \"[boolean] node has correct name\");\n        t.eq(node.nodeValue, \"false\",\n             \"[boolean] node has correct value\");\n\n        var doc = format.read(text);\n        if (doc.importNode) {\n            node = doc.importNode(node, true);\n        }    \n        t.ok(doc.documentElement.appendChild(node),\n             \"node can be appended to a doc root\");\n    }\n\n    function test_Format_XML_getElementsByTagNameNS(t) {\n        t.plan(5);\n\n        var format = new OpenLayers.Format.XML();\n        var olUri = \"http://namespace.openlayers.org\";\n        var name = \"child\";\n        var doc = format.read(text);\n        var nodes = format.getElementsByTagNameNS(doc.documentElement,\n                                                  olUri, name);\n        t.eq(nodes.length, 3,\n             \"gets correct number of nodes\");\n        var qualifiedName = nodes[0].prefix + \":\" + name;\n        t.eq(nodes[0].nodeName, qualifiedName,\n             \"first node has correct qualified name\");\n        \n        var defaultUri = \"http://namespace.default.net\";\n        name = \"element\";\n        nodes = format.getElementsByTagNameNS(doc.documentElement,\n                                                  defaultUri, name);\n        t.eq(nodes.length, 1,\n             \"gets correct number of nodes in default namespace\");\n        \n        var pList = format.getElementsByTagNameNS(doc.documentElement,\n                                                  olUri, \"p\");\n        t.eq(pList.length, 1, \"got one ol:p element\");\n        var p = pList[0];\n        \n        var aList = format.getElementsByTagNameNS(p, olUri, \"a\");\n        t.eq(aList.length, 2, \"got two child ol:a elements\");\n        \n        \n        \n    }\n\n    function test_Format_XML_getAttributeNodeNS(t) {\n        t.plan(5);\n\n        var format = new OpenLayers.Format.XML();\n        var doc = format.read(text);\n        var olUri = \"http://namespace.openlayers.org\";\n        var taUri = \"http://namespace.testattribute.net\";\n        var localNodeName = \"child\";\n        var localAttrName = \"attribute\";\n        var nodes = format.getElementsByTagNameNS(doc.documentElement,\n                                                  olUri, localNodeName);\n        var attributeNode = format.getAttributeNodeNS(nodes[0],\n                                                      taUri, localAttrName);\n        var qualifiedName = attributeNode.prefix + \":\" + localAttrName;\n\n        t.ok(attributeNode,\n             \"returns non-null value\");\n        t.eq(attributeNode.nodeType, 2,\n             \"attribute node has correct type\");\n        t.eq(attributeNode.nodeName, qualifiedName,\n             \"attribute node has correct qualified name\");\n        t.eq(attributeNode.nodeValue, \"value1\",\n             \"attribute node has correct value\");\n        \n        var nullAttribute = format.getAttributeNodeNS(nodes[0],\n                                                      taUri, \"nothing\");\n        t.ok(nullAttribute === null,\n             \"returns null for nonexistent attribute\");\n    }\n\n    function test_Format_XML_getAttributeNS(t) {\n        t.plan(2);\n\n        var format = new OpenLayers.Format.XML();\n        var doc = format.read(text);\n        var olUri = \"http://namespace.openlayers.org\";\n        var taUri = \"http://namespace.testattribute.net\";\n        var localNodeName = \"child\";\n        var localAttrName = \"attribute\";\n        var nodes = format.getElementsByTagNameNS(doc.documentElement,\n                                                  olUri, localNodeName);\n        var attributeValue = format.getAttributeNS(nodes[0],\n                                                   taUri, localAttrName);\n        t.eq(attributeValue, \"value1\",\n             \"got correct attribute value\");\n        \n        var emptyValue = format.getAttributeNS(nodes[0],\n                                              taUri, \"nothing\");\n        t.ok(emptyValue === \"\",\n             \"returns empty string for nonexistent attributes\");\n    }\n\n    function test_Format_XML_hasAttributeNS(t) {\n        t.plan(2);\n\n        var format = new OpenLayers.Format.XML();\n        var doc = format.read(text);\n        var olUri = \"http://namespace.openlayers.org\";\n        var taUri = \"http://namespace.testattribute.net\";\n        var localNodeName = \"child\";\n        var localAttrName = \"attribute\";\n        var nodes = format.getElementsByTagNameNS(doc.documentElement,\n                                                  olUri, localNodeName);\n        var found = format.hasAttributeNS(nodes[0], taUri, localAttrName);\n        t.ok(found === true, \"returns true for good attribute\");\n        \n        found = format.hasAttributeNS(nodes[0], taUri, \"nothing\");\n        t.ok(found === false, \"returns false for bad attribute\");\n    }\n    \n    function test_namespaces(t) {\n        t.plan(2);\n        \n        var format = new OpenLayers.Format.XML({\n            namespaces: {\n                \"def\": \"http://example.com/default\",\n                \"foo\": \"http://example.com/foo\",\n                \"bar\": \"http://example.com/bar\"\n            },\n            defaultPrefix: \"def\"\n        });\n        \n        // test that prototype has not been altered\n        t.eq(OpenLayers.Format.XML.prototype.namespaces, null,\n             \"setting namespaces at construction does not modify prototype\");\n        \n        // test that namespaceAlias has been set\n        t.eq(format.namespaceAlias[\"http://example.com/foo\"], \"foo\",\n             \"namespaceAlias mapping has been set\");\n        \n    }\n    \n    function test_setNamespace(t) {\n        t.plan(3);\n        \n        var format = new OpenLayers.Format.XML();\n        \n        // test that namespaces is an object\n        t.ok(format.namespaces instanceof Object, \"empty namespace object set\");\n        \n        format.setNamespace(\"foo\", \"http://example.com/foo\");\n        t.eq(format.namespaces[\"foo\"], \"http://example.com/foo\", \"alias -> uri mapping set\");\n        t.eq(format.namespaceAlias[\"http://example.com/foo\"], \"foo\", \"uri -> alias mapping set\");\n\n    }\n    \n    function test_readChildNodes(t) {\n        \n        var text = \"<?xml version='1.0' encoding='UTF-8'?>\" +\n        \"<container xmlns='http://example.com/foo'>\" +\n            \"<marker name='my marker 1'>\" +\n                \"<position>\" +\n                    \"<lon>-180</lon>\" +\n                    \"<lat>90</lat>\" +\n                \"</position>\" +\n                \"<detail>some text for first marker</detail>\" +\n                \"<atom:link xmlns:atom='http://www.w3.org/2005/Atom' href='http://host/path/1'/>\" +\n            \"</marker>\" +\n            \"<marker name='my marker 2'>\" +\n                \"<position>\" +\n                    \"<lon>180</lon>\" +\n                    \"<lat>-90</lat>\" +\n                \"</position>\" +\n                \"<detail>some text for second marker</detail>\" +\n                \"<atom:link xmlns:atom='http://www.w3.org/2005/Atom' href='http://host/path/2'/>\" +\n            \"</marker>\" +\n        \"</container>\";\n        \n        var expect = [\n            new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.Point(-180, 90),\n                {\n                    name: 'my marker 1',\n                    link: 'http://host/path/1',\n                    detail: 'some text for first marker'\n                }\n            ),\n            new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.Point(180, -90),\n                {\n                    name: 'my marker 2',\n                    link: 'http://host/path/2',\n                    detail: 'some text for second marker'\n                }\n            )\n        ];\n        \n        var format = new OpenLayers.Format.XML({\n            defaultPrefix: \"foo\",\n            namespaces: {\n                \"foo\": \"http://example.com/foo\",\n                \"atom\": \"http://www.w3.org/2005/Atom\"\n            },\n            readers: {\n                \"foo\": {\n                    \"container\": function(node, obj) {\n                        var list = [];\n                        this.readChildNodes(node, list);\n                        obj.list = list;\n                    },\n                    \"marker\": function(node, list) {\n                        var feature = new OpenLayers.Feature.Vector();\n                        feature.attributes.name = node.getAttribute(\"name\");\n                        this.readChildNodes(node, feature);\n                        list.push(feature);\n                    },\n                    \"position\": function(node, feature) {\n                        var obj = {};\n                        this.readChildNodes(node, obj);\n                        feature.geometry = new OpenLayers.Geometry.Point(obj.x, obj.y);\n                    },\n                    \"lon\": function(node, obj) {\n                        obj.x = this.getChildValue(node);\n                    },\n                    \"lat\": function(node, obj) {\n                        obj.y = this.getChildValue(node);\n                    },\n                    \"detail\": function(node, feature) {\n                        feature.attributes.detail = this.getChildValue(node);\n                    }\n                },\n                \"atom\": {\n                    \"link\": function(node, feature) {\n                        feature.attributes.link = node.getAttribute(\"href\");\n                    }                    \n                }\n            }\n        });\n        \n        // convert text to document node\n        var doc = format.read(text);\n        // read child nodes to get back some object\n        var obj = format.readChildNodes(doc);\n        // start comparing what we got to what we expect\n        var got = obj.list;\n        \n        t.plan(11);\n        t.eq(got.length, expect.length, \"correct number of items parsed\");\n        t.eq(got[0].geometry.x, expect[0].geometry.x, \"correct x coord parsed for marker 1\");\n        t.eq(got[0].geometry.y, expect[0].geometry.y, \"correct y coord parsed for marker 1\");\n        t.eq(got[0].attributes.name, expect[0].attributes.name, \"correct name parsed for marker 1\");\n        t.eq(got[0].attributes.detail, expect[0].attributes.detail, \"correct detail parsed for marker 1\");\n        t.eq(got[0].attributes.link, expect[0].attributes.link, \"correct link parsed for marker 1\");\n        t.eq(got[1].geometry.x, expect[1].geometry.x, \"correct x coord parsed for marker 2\");\n        t.eq(got[1].geometry.y, expect[1].geometry.y, \"correct y coord parsed for marker 2\");\n        t.eq(got[1].attributes.name, expect[1].attributes.name, \"correct name parsed for marker 2\");\n        t.eq(got[1].attributes.detail, expect[1].attributes.detail, \"correct detail parsed for marker 2\");\n        t.eq(got[1].attributes.link, expect[1].attributes.link, \"correct link parsed for marker 2\");\n        \n    }\n    \n    function test_writeNode(t) {\n        \n        var features = [\n            new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.Point(-180, 90),\n                {\n                    name: 'my marker 1',\n                    link: 'http://host/path/1',\n                    detail: 'some text for first marker'\n                }\n            ),\n            new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.Point(180, -90),\n                {\n                    name: 'my marker 2',\n                    link: 'http://host/path/2',\n                    detail: 'some text for second marker'\n                }\n            )\n        ];\n\n        var expect = \"<?xml version='1.0' encoding='UTF-8'?>\" +\n        \"<container xmlns='http://example.com/foo'>\" +\n            \"<marker name='my marker 1'>\" +\n                \"<position>\" +\n                    \"<lon>-180</lon>\" +\n                    \"<lat>90</lat>\" +\n                \"</position>\" +\n                \"<detail>some text for first marker</detail>\" +\n                \"<atom:link xmlns:atom='http://www.w3.org/2005/Atom' href='http://host/path/1'/>\" +\n            \"</marker>\" +\n            \"<marker name='my marker 2'>\" +\n                \"<position>\" +\n                    \"<lon>180</lon>\" +\n                    \"<lat>-90</lat>\" +\n                \"</position>\" +\n                \"<detail>some text for second marker</detail>\" +\n                \"<atom:link xmlns:atom='http://www.w3.org/2005/Atom' href='http://host/path/2'/>\" +\n            \"</marker>\" +\n        \"</container>\";\n        \n        var format = new OpenLayers.Format.XML({\n            defaultPrefix: \"foo\",\n            namespaces: {\n                \"foo\": \"http://example.com/foo\",\n                \"atom\": \"http://www.w3.org/2005/Atom\"\n            },\n            writers: {\n                \"foo\": {\n                    \"container\": function(features) {\n                        var node = this.createElementNSPlus(\"container\");\n                        var feature;\n                        for(var i=0; i<features.length; ++i) {\n                            feature = features[i];\n                            this.writeNode(\"marker\", features[i], node);\n                        }\n                        return node;\n                    },\n                    \"marker\": function(feature) {\n                        var node = this.createElementNSPlus(\"marker\", {\n                            attributes: {name: feature.attributes.name}\n                        });\n                        this.writeNode(\"position\", feature.geometry, node);\n                        this.writeNode(\"detail\", feature.attributes.detail, node);\n                        this.writeNode(\"atom:link\", feature.attributes.link, node);\n                        return node;\n                    },\n                    \"position\": function(geometry) {\n                        var node = this.createElementNSPlus(\"position\");\n                        this.writeNode(\"lon\", geometry.x, node);\n                        this.writeNode(\"lat\", geometry.y, node);\n                        return node;\n                    },\n                    \"lon\": function(x) {\n                        return this.createElementNSPlus(\"lon\", {\n                            value: x\n                        });\n                    },\n                    \"lat\": function(y) {\n                        return this.createElementNSPlus(\"lat\", {\n                            value: y\n                        });\n                    },\n                    \"detail\": function(text) {\n                        return this.createElementNSPlus(\"detail\", {\n                            value: text\n                        });\n                    }\n                },\n                \"atom\": {\n                    \"link\": function(href) {\n                        return this.createElementNSPlus(\"atom:link\", {\n                            attributes: {href: href}\n                        });\n                    }\n                }\n            }\n            \n        });\n        \n        t.plan(1);\n        // test that we get what we expect from writeNode\n        var got = format.writeNode(\"container\", features);\n        t.xml_eq(got, expect, \"features correctly written\");\n    }\n    \n    function test_createElementNSPlus(t) {\n        \n        var format = new OpenLayers.Format.XML({\n            defaultPrefix: \"def\",\n            namespaces: {\n                \"def\": \"http://example.com/default\",\n                \"foo\": \"http://example.com/foo\",\n                \"bar\": \"http://example.com/bar\"\n            }\n        });\n        \n        var cases = [\n            {\n                description: \"unprefixed name with default options\",\n                node: format.createElementNSPlus(\"FooNode\"),\n                expect: \"<def:FooNode xmlns:def='http://example.com/default'/>\"\n            }, {\n                description: \"def prefixed name with default options\",\n                node: format.createElementNSPlus(\"def:FooNode\"),\n                expect: \"<def:FooNode xmlns:def='http://example.com/default'/>\"\n            }, {\n                description: \"foo prefixed name with default options\",\n                node: format.createElementNSPlus(\"foo:FooNode\"),\n                expect: \"<foo:FooNode xmlns:foo='http://example.com/foo'/>\"\n            }, {\n                description: \"unprefixed name with uri option\",\n                node: format.createElementNSPlus(\"FooNode\", {\n                    uri: \"http://example.com/elsewhere\"\n                }),\n                expect: \"<FooNode xmlns='http://example.com/elsewhere'/>\"\n            }, {\n                description: \"foo prefixed name with uri option (overriding format.namespaces)\",\n                node: format.createElementNSPlus(\"foo:FooNode\", {\n                    uri: \"http://example.com/elsewhere\"\n                }),\n                expect: \"<foo:FooNode xmlns:foo='http://example.com/elsewhere'/>\"\n            }, {\n                description: \"foo prefixed name with attributes option\",\n                node: format.createElementNSPlus(\"foo:FooNode\", {\n                    attributes: {\n                        \"id\": \"123\",\n                        \"foo:attr1\": \"namespaced attribute 1\",\n                        \"bar:attr2\": \"namespaced attribute 2\"\n                    }\n                }),\n                expect: \"<foo:FooNode xmlns:foo='http://example.com/foo' xmlns:bar='http://example.com/bar' id='123' foo:attr1='namespaced attribute 1' bar:attr2='namespaced attribute 2'/>\"\n            }, {\n                description: \"foo prefixed name with attributes and value options\",\n                node: format.createElementNSPlus(\"foo:FooNode\", {\n                    attributes: {\"id\": \"123\"},\n                    value: \"text value\"\n                }),\n                expect: \"<foo:FooNode xmlns:foo='http://example.com/foo' id='123'>text value<\" + \"/foo:FooNode>\"\n            }, {\n                description: \"value of 0 gets appended as a text node\",\n                node: format.createElementNSPlus(\"foo:bar\", {value: 0}),\n                expect: \"<foo:bar xmlns:foo='http://example.com/foo'>0</foo:bar>\"\n            }, {\n                description: \"value of 0.42 gets appended as a text node\",\n                node: format.createElementNSPlus(\"foo:bar\", {value: 0.42}),\n                expect: \"<foo:bar xmlns:foo='http://example.com/foo'>0.42</foo:bar>\"\n            }, {\n                description: \"value of true gets appended as a text node\",\n                node: format.createElementNSPlus(\"foo:bar\", {value: true}),\n                expect: \"<foo:bar xmlns:foo='http://example.com/foo'>true</foo:bar>\"\n            }, {\n                description: \"value of false gets appended as a text node\",\n                node: format.createElementNSPlus(\"foo:bar\", {value: false}),\n                expect: \"<foo:bar xmlns:foo='http://example.com/foo'>false</foo:bar>\"\n            }, {\n                description: \"null value does not get appended as a text node\",\n                node: format.createElementNSPlus(\"foo:bar\", {value: null}),\n                expect: \"<foo:bar xmlns:foo='http://example.com/foo'/>\"\n            }, {\n                description: \"undefined value does not get appended as a text node\",\n                node: format.createElementNSPlus(\"foo:bar\"),\n                expect: \"<foo:bar xmlns:foo='http://example.com/foo'/>\"\n            }\n        ];\n        \n        t.plan(cases.length);\n        var test;\n        for(var i=0; i<cases.length; ++i) {\n            test = cases[i];\n            t.xml_eq(test.node, test.expect, test.description);\n        }\n        \n    }\n    \n    function test_setAttributes(t) {\n        \n        var format = new OpenLayers.Format.XML({\n            defaultPrefix: \"def\",\n            namespaces: {\n                \"def\": \"http://example.com/default\",\n                \"foo\": \"http://example.com/foo\",\n                \"bar\": \"http://example.com/bar\"\n            }\n        });\n        \n        var cases = [\n            {\n                description: \"unprefixed attribute\",\n                node: format.createElementNSPlus(\"foo:Node\"),\n                attributes: {\"id\": \"123\"},\n                expect: \"<foo:Node xmlns:foo='http://example.com/foo' id='123'/>\"\n            }, {\n                description: \"foo prefixed attribute\",\n                node: format.createElementNSPlus(\"foo:Node\"),\n                attributes: {\"foo:id\": \"123\"},\n                expect: \"<foo:Node xmlns:foo='http://example.com/foo' foo:id='123'/>\"\n            }, {\n                description: \"foo prefixed attribute with def prefixed node\",\n                node: format.createElementNSPlus(\"def:Node\"),\n                attributes: {\"foo:id\": \"123\"},\n                expect: \"<def:Node xmlns:def='http://example.com/default' xmlns:foo='http://example.com/foo' foo:id='123'/>\"\n            }, {\n                description: \"multiple attributes\",\n                node: format.createElementNSPlus(\"def:Node\"),\n                attributes: {\"id\": \"123\", \"foo\": \"bar\"},\n                expect: \"<def:Node xmlns:def='http://example.com/default' id='123' foo='bar'/>\"\n            }\n        ];\n        \n        t.plan(cases.length);\n        var test;\n        for(var i=0; i<cases.length; ++i) {\n            test = cases[i];\n            format.setAttributes(test.node, test.attributes);\n            t.xml_eq(test.node, test.expect, test.description);\n        }\n        \n    }\n\n    function test_keepData(t) { \n        t.plan(2);\n\n        var options = {'keepData': true};\n        var format = new OpenLayers.Format.XML(options); \n        format.read(text);\n\n        t.ok(format.data != null, 'data property is not null after read with keepData=true');\n        t.eq(format.data.documentElement.tagName,'ol:root','keepData keeps the right data');\n    }\n\n    function test_getChildValue(t) {\n\n        t.plan(1);\n\n        var text =\n            \"<?xml version='1.0' encoding='UTF-8'?>\" +\n            \"<root>\" +\n                \"x<!-- comment -->y<!-- comment 2 --><![CDATA[z]]>z<foo />&#x79;\" +\n            \"</root>\";\n\n        var format = new OpenLayers.Format.XML();\n        var doc = format.read(text).documentElement;\n\n        t.eq(format.getChildValue(doc), \"xyzzy\", \"child value skips comments, concatenates multiple values, reads through entities\");\n\n    }\n    \n    function test_getChildEl(t) {\n\n        t.plan(3);\n\n        var text =\n            \"<?xml version='1.0' encoding='UTF-8'?>\" +\n            \"<root>\" +\n                \"<!-- comment -->\" +\n                \"<a>x</a>\" +\n                \"<b>x</b>\" +\n            \"</root>\";\n\n        var format = new OpenLayers.Format.XML();\n        var doc = format.read(text).documentElement;\n\n        var a = format.getChildEl(doc);\n        t.eq(a.nodeName, \"a\", \"first element found correctly\");\n        \n        a = format.getChildEl(doc, \"a\");\n        t.eq(b, null, \"first child element matches the given name\");\n\n        var b = format.getChildEl(doc, \"b\");\n        t.eq(b, null, \"first child element does not match the given name\");\n\n    }\n    \n    function test_getNextEl(t) {\n        t.plan(5);\n\n        var text =\n            \"<?xml version='1.0' encoding='UTF-8'?>\" +\n            \"<root>\" +\n                \"<!-- comment -->\" +\n                \"<a>x</a>\" +\n                \"<!-- comment -->\" +\n                \"<b xmlns='urn:example'>x</b>\" +\n            \"</root>\";\n\n        var format = new OpenLayers.Format.XML();\n        var doc = format.read(text).documentElement;\n\n        var a = format.getChildEl(doc);\n        \n        var b = format.getNextEl(a);\n        t.eq(b && b.nodeName, \"b\", \"next element correctly found\");\n        \n        b = format.getNextEl(a, \"b\");\n        t.eq(b && b.nodeName, \"b\", \"next element correctly found when name supplied\");\n\n        b = format.getNextEl(a, \"c\");\n        t.eq(b, null, \"null returned when name does not match next element\");\n\n        b = format.getNextEl(a, null, \"urn:example\");\n        t.eq(b && b.nodeName, \"b\", \"next element correctly found when namespace supplied\");\n\n        b = format.getNextEl(a, null, \"foo\");\n        t.eq(b, null, \"null returned when namespace does not match next element\");\n\n    }\n    \n    function test_isSimpleContent(t) {\n        t.plan(2);\n\n        var text =\n            \"<?xml version='1.0' encoding='UTF-8'?>\" +\n            \"<root>\" +\n                \"<!-- comment -->\" +\n                \"<a>x<!-- comment -->y<!-- comment 2 --><![CDATA[z]]>z<foo />&#x79;</a>\" +\n                \"<!-- comment -->\" +\n                \"<b>x<!-- comment -->y<!-- comment 2 --><![CDATA[z]]>z&#x79;</b>\" +\n            \"</root>\";\n\n        var format = new OpenLayers.Format.XML();\n        var doc = format.read(text).documentElement;\n\n        var a = format.getChildEl(doc);\n        var b = format.getNextEl(a);\n        t.ok(!format.isSimpleContent(a), \"<a> content is not simple\");\n        t.ok(format.isSimpleContent(b), \"<b> content is simple\");\n\n    }\n\n    function test_lookupNamespaceURI(t) {\n        \n        t.plan(8);\n\n        var text =\n            \"<?xml version='1.0' encoding='UTF-8'?>\" +\n            \"<root xmlns:baz='urn:baznamespace'>\" +\n                \"<!-- comment -->\" +\n                \"<a><foo /></a>\" +\n                \"<!-- comment -->\" +\n                \"<b xmlns='urn:example'><!-- comment --><bar foo='value'/></b>\" +\n            \"</root>\";\n\n        var format = new OpenLayers.Format.XML();\n        var doc = format.read(text).documentElement;\n\n        var a = format.getChildEl(doc);\n        t.eq(format.lookupNamespaceURI(a, \"baz\"), \"urn:baznamespace\", \"prefix lookup on first child\");\n\n        var foo = format.getChildEl(a);\n        t.eq(format.lookupNamespaceURI(foo, \"baz\"), \"urn:baznamespace\", \"prefix lookup on child of first child\");\n        \n        var b = format.getNextEl(a);\n        t.eq(format.lookupNamespaceURI(b, null), \"urn:example\", \"default namespace lookup on element\");\n        \n        var bar = format.getChildEl(b);\n        t.eq(format.lookupNamespaceURI(bar, null), \"urn:example\", \"default namespace lookup on child\");\n        t.eq(format.lookupNamespaceURI(bar, \"baz\"), \"urn:baznamespace\", \"prefix lookup on child with different default\");\n\n        // test that the alias behaves properly\n        var lookup = OpenLayers.Format.XML.lookupNamespaceURI;\n        t.eq(lookup(bar, \"baz\"), \"urn:baznamespace\", \"(alias) prefix lookup on child with different default\");\n\n        var attr = bar.attributes[0];\n        // Internet Explorer didn't have the ownerElement property until 8.\n        var supportsOwnerElement = !!attr.ownerElement;        \n        if(supportsOwnerElement) {\n            t.eq(format.lookupNamespaceURI(attr, null), \"urn:example\", \"default namespace lookup on attribute\");\n            t.eq(format.lookupNamespaceURI(attr, \"baz\"), \"urn:baznamespace\", \"prefix lookup on attribute with different default\");\n        } else {\n            t.debug_print(\"namespace lookup on attributes not supported in this browser\");\n            t.ok(true, \"namespace lookup on attributes not supported in this browser\");\n            t.ok(true, \"namespace lookup on attributes not supported in this browser\");\n        }\n\n    }\n    \n    function test_getXMLDoc(t) {\n        t.plan(2);\n        var format = new OpenLayers.Format.XML();\n        var doc = format.getXMLDoc();\n        t.ok(doc !== document, \"document returned from getXMLDoc is not the page's html doc\");\n        var root = format.createElementNS(\"http://test\", \"root\");\n        // appending CDATA created from a different document\n        var cdata = doc.createCDATASection(\"<foo></foo>\");\n        root.appendChild(cdata);\n        var result = format.write(root);\n        var expect = '<root xmlns=\"http://test\"><![CDATA[<foo></foo>]]></root>';\n        t.eq(result, expect, \"document with CDATA section serialized correctly\");\n    }\n\n    \n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Format.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_Format_constructor(t) {\n        t.plan(5);\n    \n        var options = {'foo': 'bar'};\n        var format = new OpenLayers.Format(options);\n        t.ok(format instanceof OpenLayers.Format,\n             \"new OpenLayers.Format returns object\" );\n        t.eq(format.foo, \"bar\", \"constructor sets options correctly\");\n        t.eq(typeof format.read, \"function\", \"format has a read function\");\n        t.eq(typeof format.write, \"function\", \"format has a write function\");\n        t.eq(format.options, options, \"format.options correctly set\");\n    }\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Geometry/Collection.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var coll;\n        \n    function test_Collection_constructor (t) {\n        t.plan( 4 );\n        \n      //null param\n        coll = new OpenLayers.Geometry.Collection();\n        t.ok( coll instanceof OpenLayers.Geometry.Collection, \"new OpenLayers.Geometry.Collection returns coll object\" );\n        t.eq( coll.CLASS_NAME, \"OpenLayers.Geometry.Collection\", \"coll.CLASS_NAME is set correctly\");\n        t.eq( coll.components.length, 0, \"coll.components is set correctly\");\n        \n        OpenLayers.Geometry.Collection.prototype._addComponents = \n            OpenLayers.Geometry.Collection.prototype.addComponents;\n        OpenLayers.Geometry.Collection.prototype.addComponents = \n            function(comps) { g_addcomponents = comps; };\n\n      //valid param\n        g_addcomponents = null;\n        var components = {};\n        coll = new OpenLayers.Geometry.Collection(components);\n        t.ok(g_addcomponents, components, \"addcomponents called on non-null param\")\n        \n        OpenLayers.Geometry.Collection.prototype.addComponents = \n            OpenLayers.Geometry.Collection.prototype._addComponents;\n    }\n\n    function test_Collection_addComponents (t) {\n        t.plan( 10 );\n\n        coll = new OpenLayers.Geometry.Collection();\n\n      //null\n        coll.addComponents(null);\n        t.ok(true, \"doesn't break on add null components\");\n\n        OpenLayers.Geometry.Collection.prototype._addComponent = \n            OpenLayers.Geometry.Collection.prototype.addComponent;\n\n        OpenLayers.Geometry.Collection.prototype.addComponent = \n            function(comp) { g_addComp = comp; g_added++};\n            \n\n      //nonarray argument\n        var g_added = 0;\n        var g_addComp = 0;\n        var component = {};\n        coll.addComponents(component);\n        t.eq(g_added, 1, \"added once\");\n        t.eq(g_addComp, component, \"added component\");\n        \n      //array arg\n        var g_added = 0;\n        var g_addComp = 0;\n        var component1 = {};\n        var component2 = {};\n        coll.addComponents([component1, component2]);\n        t.eq(g_added, 2, \"added twice\");\n        t.eq(g_addComp, component2, \"added component\");\n\n        OpenLayers.Geometry.Collection.prototype.addComponent = \n            OpenLayers.Geometry.Collection.prototype._addComponent;\n\n\n\n        coll.addComponents(new OpenLayers.Geometry.Point(0,0));\n        coll.addComponents(new OpenLayers.Geometry.Point(10,10));\n        t.eq( coll.components.length, 2, \"added two components to collection\" );\n        bounds = coll.getBounds();\n        t.eq( bounds.left, 0, \"left bound is 0\" );\n        t.eq( bounds.bottom, 0, \"bottom bound is 0\" );\n        t.eq( bounds.right, 10, \"right bound is 10\" );\n        t.eq( bounds.top, 10, \"top bound is 10\" );\n    }\n\n    function test_Collection_clone (t) {\n        t.plan( 3 );\n        coll = new OpenLayers.Geometry.Collection();\n        coll.addComponents(new OpenLayers.Geometry.Point(0,0));\n        coll.addComponents(new OpenLayers.Geometry.Point(10,10));\n        coll2 = coll.clone(); \n        t.ok( coll2 instanceof OpenLayers.Geometry.Collection, \"coll.clone() returns collection object\" );\n        t.eq( coll2.components.length, 2, \"coll2.components.length is set correctly\");\n        t.ok( coll2.components[0] instanceof OpenLayers.Geometry.Point,\n            \"coll2.components.length is set correctly\");\n    }\n\n    function test_Collection_removeComponents (t) {\n        t.plan( 5 );\n        coll = new OpenLayers.Geometry.Collection();\n        point = new OpenLayers.Geometry.Point(0,0);\n        coll.addComponents(point);\n        coll.addComponents(new OpenLayers.Geometry.Point(10,10));\n        coll.removeComponents(coll.components[0]);\n        t.eq( coll.components.length, 1, \"coll.components.length is smaller after removeComponent\" );\n        t.ok( coll.bounds == null, \"bounds are nullified after call to remove (to trigger recalc on getBounds()\");\n        bounds = coll.getBounds();\n        t.eq( bounds.left, 10, \"left bound is 10 after removeComponent\" );\n        t.eq( bounds.bottom, 10, \"bottom bound is 10 after removeComponent\" );\n        \n        coll = new OpenLayers.Geometry.Collection();\n        for(var i=0; i<5; ++i) {\n            coll.addComponents(\n                new OpenLayers.Geometry.Point(Math.random(), Math.random())\n            );\n        }\n        coll.removeComponents(coll.components);\n        t.eq(coll.components.length, 0,\n             \"remove components even works with multiple components\");\n        \n    }\n    \n    function test_Collection_calculateBounds(t) {\n        t.plan( 9 );\n        \n        var coll = new OpenLayers.Geometry.Collection();\n        coll.calculateBounds();\n        t.eq(coll.bounds, null, \"null components list gives null bounds on calculation()\");\n\n        var p1 = new OpenLayers.Geometry.Point(10,20);\n        var p2 = new OpenLayers.Geometry.Point(30,40);\n        \n        var components = [p1, p2];\n        coll = new OpenLayers.Geometry.Collection(components);\n        \n        coll.calculateBounds();\n        \n        t.eq(coll.bounds.left, 10, \"good left bounds\");\n        t.eq(coll.bounds.bottom, 20, \"good bottom bounds\");\n        t.eq(coll.bounds.right, 30, \"good right bounds\");\n        t.eq(coll.bounds.top, 40, \"good top bounds\");\n\n        var newPoint = new OpenLayers.Geometry.Point(60,70);\n        coll.addComponent(newPoint);\n        coll.calculateBounds();\n        \n        t.eq(coll.bounds.left, 10, \"good left bounds\");\n        t.eq(coll.bounds.bottom, 20, \"good bottom bounds\");\n        t.eq(coll.bounds.right, 60, \"good right bounds\");\n        t.eq(coll.bounds.top, 70, \"good top bounds\");\n    }\n    \n    function test_Collection_equals(t) {\n        t.plan(1);\n        var geom = new OpenLayers.Geometry.Collection();\n        t.ok(!geom.equals(), \"collection.equals() returns false for undefined\");\n    }\n\n    function test_Collection_addComponent(t)   {\n        t.plan(10);\n        \n        var coll = new OpenLayers.Geometry.Collection();\n        \n        //null\n        coll.addComponent(null);\n        t.ok(!coll.addComponent(null),\n             \"addComponent returns false for bad component\")        \n\n        //good component\n        var component = new OpenLayers.Geometry.Point(3,4);\n        t.ok(coll.addComponent(component),\n             \"addComponent returns true for good component\");\n        t.ok(coll.bounds == null, \"bounds cache correctly cleared\");         \n         \n        var foundComponent = false;\n        for(var i=0; i< coll.components.length; i++) {\n            if (coll.components[i].equals(component)) {\n                foundComponent = true;\n            }\n        }\n        t.ok(foundComponent, \"component added to internal array\");\n        \n        // restricted components\n        coll.componentTypes = [\"OpenLayers.Geometry.Point\",\n                               \"OpenLayers.Geometry.LineString\"];\n        var point1 = new OpenLayers.Geometry.Point(0,0);\n        var point2 = new OpenLayers.Geometry.Point(1,1);\n        var line = new OpenLayers.Geometry.LineString([point1, point2]);\n        var multipoint = new OpenLayers.Geometry.MultiPoint([point1, point2]);\n        \n        t.ok(coll.addComponent(point1),\n             \"addComponent returns true for 1st geometry type in componentTypes\");\n        t.ok(OpenLayers.Util.indexOf(coll.components, point1) > -1,\n             \"addComponent adds 1st restricted type to components array\");\n        t.ok(coll.addComponent(line),\n             \"addComponent returns true for 2nd geometry type in componentTypes\");\n        t.ok(OpenLayers.Util.indexOf(coll.components, point1) > -1,\n             \"addComponent adds 2nd restricted type to components array\");\n        t.ok(!coll.addComponent(multipoint),\n             \"addComponent returns false for geometry type not in componentTypes\");\n        t.ok(OpenLayers.Util.indexOf(coll.components, multipoint) == -1,\n             \"addComponent doesn't add restricted type to component array\");\n\n    }\n    \n    function test_collection_getLength(t) {\n        t.plan(2);\n        \n      //null\n        var coll = new OpenLayers.Geometry.Collection();\n        t.eq( coll.getLength(), 0, \"null coll has 0 getlength\");\n            \n      //valid\n        coll.components = [\n            { 'getLength': function() { return 50; } },\n            { 'getLength': function() { return 15; } }\n        ];\n        t.eq( coll.getLength(), 65, \"coll with valid components correctly sums getlength\");\n    }\n    \n    function test_collection_getArea(t) {\n        t.plan(2);\n        \n      //null\n        var coll = new OpenLayers.Geometry.Collection();\n        t.eq( coll.getArea(), 0, \"null coll has 0 getArea\");\n            \n      //valid\n        coll.components = [\n            { 'getArea': function() { return 50; } },\n            { 'getArea': function() { return 15; } }\n        ];\n        t.eq( coll.getArea(), 65, \"coll with valid components correctly sums getArea\");\n    }\n    \n    function test_transform(t) {\n        t.plan(5);\n        var p1 = new OpenLayers.Geometry.Point(0,0);\n        p1.bounds = \"foo\";\n        var p2 = new OpenLayers.Geometry.Point(1,1);\n        p2.bounds = \"foo\";\n        var line = new OpenLayers.Geometry.LineString([p1, p2]);\n        var multipoint = new OpenLayers.Geometry.MultiPoint([p1, p2]);\n        var coll = new OpenLayers.Geometry.Collection([\n            p1, p2, line, multipoint\n        ]);\n        coll.bounds = \"foo\";\n        \n        var wgs84 = new OpenLayers.Projection(\"EPSG:4326\");\n        var sm = new OpenLayers.Projection(\"EPSG:900913\");\n        coll.transform(wgs84, sm);\n        \n        t.eq(coll.bounds, null, \"coll bounds cleared\");\n        t.eq(p1.bounds, null, \"p1 component bounds cleared\");\n        t.eq(p2.bounds, null, \"p2 component bounds cleared\");\n        t.eq(line.bounds, null, \"line component bounds cleared\");\n        t.eq(multipoint.bounds, null, \"multipoint component bounds cleared\");\n\n    }\n\n    function test_getCentroid_pts_only(t) {\n        t.plan(3);\n\n        coll = new OpenLayers.Geometry.Collection();\n        coll.addComponent(new OpenLayers.Geometry.Point(0,0));\n        coll.addComponent(new OpenLayers.Geometry.Point(1,1));\n\n        centroid = coll.getCentroid(true);\n        t.ok(centroid != null, 'The centroid is not null.');\n        t.eq(centroid.x, 0.5, 'The centroid x coordinate is good.');\n        t.eq(centroid.y, 0.5, 'The centroid y coordinate is good.');\n\n        coll.destroy();\n    }\n\n    function test_getCentroid_poly_nonrecursive(t) {\n        t.plan(3);\n\n        coll = new OpenLayers.Geometry.Collection();\n        coll.addComponent(\n            new OpenLayers.Geometry.Polygon([\n                new OpenLayers.Geometry.LinearRing([\n                    new OpenLayers.Geometry.Point(0,0),\n                    new OpenLayers.Geometry.Point(0,1),\n                    new OpenLayers.Geometry.Point(1,1),\n                    new OpenLayers.Geometry.Point(1,0)\n                ])\n            ])\n        );\n        // performing non-recursive getCentroid means this next polygon\n        // is excluded from the centroid computation\n        coll.addComponent(\n            new OpenLayers.Geometry.Polygon([\n                new OpenLayers.Geometry.LinearRing([\n                    new OpenLayers.Geometry.Point(2,2),\n                    new OpenLayers.Geometry.Point(2,3),\n                    new OpenLayers.Geometry.Point(3,3),\n                    new OpenLayers.Geometry.Point(3,2)\n                ])\n            ])\n        );\n\n        centroid = coll.getCentroid();\n        t.ok(centroid != null, 'The centroid is not null.');\n        t.eq(centroid.x, 0.5, 'The centroid x coordinate is good.');\n        t.eq(centroid.y, 0.5, 'The centroid y coordinate is good.');\n\n        coll.destroy();\n    }\n\n    function test_getCentroid_poly_only(t) {\n        t.plan(3);\n\n        coll = new OpenLayers.Geometry.Collection();\n        coll.addComponent(\n            new OpenLayers.Geometry.Polygon([\n                    new OpenLayers.Geometry.LinearRing([\n                    new OpenLayers.Geometry.Point(0,0),\n                    new OpenLayers.Geometry.Point(0,1),\n                    new OpenLayers.Geometry.Point(1,1),\n                    new OpenLayers.Geometry.Point(1,0)\n                ])\n            ])\n        );\n\n        centroid = coll.getCentroid(true);\n        t.ok(centroid != null, 'The centroid is not null.');\n        t.eq(centroid.x, 0.5, 'The centroid x coordinate is good.');\n        t.eq(centroid.y, 0.5, 'The centroid y coordinate is good.');\n\n        coll.destroy();\n    }\n\n    function test_getCentroid_poly_and_pts(t) {\n        t.plan(3);\n\n        coll = new OpenLayers.Geometry.Collection();\n        coll.addComponent(\n            new OpenLayers.Geometry.Polygon([\n                new OpenLayers.Geometry.LinearRing([\n                    new OpenLayers.Geometry.Point(0,0),\n                    new OpenLayers.Geometry.Point(0,1),\n                    new OpenLayers.Geometry.Point(1,1),\n                    new OpenLayers.Geometry.Point(1,0)\n                ])\n            ])\n        );\n\n        // since the polygon above has an area of 1 and these\n        // points have an area of 0, they should not change the centroid\n        coll.addComponent( new OpenLayers.Geometry.Point(2,2) );\n        coll.addComponent( new OpenLayers.Geometry.Point(4,4) );\n\n        centroid = coll.getCentroid(true);\n        t.ok(centroid != null, 'The centroid is not null.');\n        t.eq(centroid.x, 0.5, 'The centroid x coordinate is good.');\n        t.eq(centroid.y, 0.5, 'The centroid y coordinate is good.');\n\n        coll.destroy();\n    }\n\n    function test_getCentroid_poly_big_and_small(t) {\n        t.plan(3);\n\n        coll = new OpenLayers.Geometry.Collection();\n        // polygon w/area=1, centroid=0.5,0.5\n        coll.addComponent(\n            new OpenLayers.Geometry.Polygon([\n                new OpenLayers.Geometry.LinearRing([\n                    new OpenLayers.Geometry.Point(0,0),\n                    new OpenLayers.Geometry.Point(0,1),\n                    new OpenLayers.Geometry.Point(1,1),\n                    new OpenLayers.Geometry.Point(1,0)\n                ])\n            ])\n        );\n\n        // since the polygon above has an area of 1 and this\n        // polygon has an area of 4, the center is weighted 20% toward\n        // the first polygon\n\n        // polygon w/area=4, centroid=5.5,5.5\n        coll.addComponent(\n            new OpenLayers.Geometry.Polygon([\n                new OpenLayers.Geometry.LinearRing([\n                    new OpenLayers.Geometry.Point(4.5,-0.5),\n                    new OpenLayers.Geometry.Point(4.5,1.5),\n                    new OpenLayers.Geometry.Point(6.5,1.5),\n                    new OpenLayers.Geometry.Point(6.5,-0.5)\n                ])\n            ])\n        );\n\n        centroid = coll.getCentroid(true);\n        t.ok(centroid != null, 'The centroid is not null.');\n        t.eq(centroid.x, 4.5, 'The centroid x coordinate is good.');\n        t.eq(centroid.y, 0.5, 'The centroid y coordinate is good.');\n\n        coll.destroy();\n    }\n\n    function test_avoid_infinite_recursion(t) {\n        t.plan(1);\n\n        var g = new OpenLayers.Geometry.Polygon([\n            new OpenLayers.Geometry.LinearRing(),\n            new OpenLayers.Geometry.LinearRing()\n        ]);\n        var bounds;\n        try {\n            bounds = g.getBounds();\n            t.eq(bounds, null, \"Polygon with empty linear ring has null bounds\");\n        } catch (err) {\n            t.fail(\"Failed to get bounds of polygon with empty linear ring: \" + err.message);\n        }\n\n    }\n\n    \n    function test_Collection_destroy(t) {\n        t.plan( 3 );\n        coll = new OpenLayers.Geometry.Collection();\n        coll.addComponents(new OpenLayers.Geometry.Point(0,0));\n        coll.addComponents(new OpenLayers.Geometry.Point(10,10));\n        coll.getBounds();\n        coll.destroy(); \n        \n        t.ok(coll.components == null, \"components array cleared\");\n        t.ok(coll.getBounds() == null, \"bounds is cleared\");\n        t.ok(coll.id == null, \"id is cleared\");\n\n    }\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Geometry/Curve.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var curve;\n    var components = [new OpenLayers.Geometry.Point(10,10), \n                new OpenLayers.Geometry.Point(0,0)];\n        \n    function test_Curve_constructor (t) {\n        t.plan( 3 );\n        curve = new OpenLayers.Geometry.Curve();\n        t.ok( curve instanceof OpenLayers.Geometry.Curve, \"new OpenLayers.Geometry.Curve returns curve object\" );\n        t.eq( curve.CLASS_NAME, \"OpenLayers.Geometry.Curve\", \"curve.CLASS_NAME is set correctly\");\n        t.eq( curve.components, [], \"curve.components is set correctly\");\n    }\n\n    function test_Curve_constructor (t) {\n        t.plan( 2 );\n        curve = new OpenLayers.Geometry.Curve(components);\n        t.ok( curve instanceof OpenLayers.Geometry.Curve, \"new OpenLayers.Geometry.Curve returns curve object\" );\n        t.eq( curve.components.length, 2, \"curve.components.length is set correctly\");\n    }\n\n    function test_Curve_clone (t) {\n        t.plan( 2 );\n        curve = new OpenLayers.Geometry.Curve(components);\n        curve2 = curve.clone(); \n        t.ok( curve2 instanceof OpenLayers.Geometry.Curve, \"curve.clone() returns curve object\" );\n        t.eq( curve2.components.length, 2, \"curve2.components.length is set correctly\");\n    }\n\n    function test_Curve_calculateBounds(t) {\n        t.plan( 17 );\n\n\n        var curve = new OpenLayers.Geometry.Curve();\n        curve.calculateBounds();\n        t.eq(curve.bounds, null, \"bounds null when no components\");\n        \n        var p1 = new OpenLayers.Geometry.Point(10,20);\n        var p2 = new OpenLayers.Geometry.Point(30,40);\n        \n        var components = [p1, p2];\n        var curve = new OpenLayers.Geometry.Curve(components);\n        \n        curve.calculateBounds();\n        \n        t.eq(curve.bounds.left, 10, \"good left bounds\");\n        t.eq(curve.bounds.bottom, 20, \"good bottom bounds\");\n        t.eq(curve.bounds.right, 30, \"good right bounds\");\n        t.eq(curve.bounds.top, 40, \"good top bounds\");\n\n        var newPoint = new OpenLayers.Geometry.Point(60,70);\n        curve.addComponent(newPoint);\n        curve.calculateBounds();\n        \n        t.eq(curve.bounds.left, 10, \"good left bounds\");\n        t.eq(curve.bounds.bottom, 20, \"good bottom bounds\");\n        t.eq(curve.bounds.right, 60, \"good right bounds\");\n        t.eq(curve.bounds.top, 70, \"good top bounds\");\n\n    //nullifying the bounds\n\n      //before calculation\n        curve = new OpenLayers.Geometry.Curve(components);\n        curve.bounds = null;        \n        curve.calculateBounds();\n        \n        t.eq(curve.bounds.left, 10, \"good left bounds\");\n        t.eq(curve.bounds.bottom, 20, \"good bottom bounds\");\n        t.eq(curve.bounds.right, 30, \"good right bounds\");\n        t.eq(curve.bounds.top, 40, \"good top bounds\");\n\n      //before addComponent\n        curve.bounds = null;\n        curve.addComponent(newPoint);\n        curve.calculateBounds();\n        \n        t.eq(curve.bounds.left, 10, \"good left bounds\");\n        t.eq(curve.bounds.bottom, 20, \"good bottom bounds\");\n        t.eq(curve.bounds.right, 60, \"good right bounds\");\n        t.eq(curve.bounds.top, 70, \"good top bounds\");\n\n    }\n\n    function test_Curve_addComponent (t) {\n        t.plan( 8 );\n        curve = new OpenLayers.Geometry.Curve(components);\n        curve.addComponent(new OpenLayers.Geometry.Point(20,30));\n        bounds = curve.getBounds();\n        t.eq( curve.components.length, 3, \"new point added to array\" );\n        t.eq( bounds.top, 30, \"top bound is 30 after addComponent\" );\n        t.eq( bounds.right, 20, \"right bound is 20 after addComponent\" );\n        curve.addComponent(new OpenLayers.Geometry.Point(-20,-30), 1);\n        bounds = curve.getBounds();\n        t.eq( curve.components.length, 4, \"new point added to array\" );\n        t.eq( bounds.bottom, -30, \"bottom bound is -30 after 2nd addComponent\" );\n        t.eq( bounds.left, -20, \"left bound is 20 after 2nd addComponent\" );\n        t.eq( curve.components[1].x, -20,  \"new point.lon is -20 (index worked)\" );\n        t.eq( curve.components[1].y, -30,  \"new point.lat is -30 (index worked)\" );\n    }\n\n    function test_Curve_removeComponent (t) {\n        t.plan( 4 );\n        curve = new OpenLayers.Geometry.Curve(components);\n        curve.removeComponent(curve.components[1]);\n        t.eq( curve.components.length, 1, \"curve.components.length is smaller after removeComponent\" );\n        t.eq( curve.bounds, null, \"curve.bounds nullified after removeComponent (for recalculation)\" );\n        bounds = curve.getBounds();\n        t.eq( bounds.left, 10, \"left bound is 10 after removeComponent\" );\n        t.eq( bounds.bottom, 10, \"bottom bound is 10 after removeComponent\" );\n    }\n\n    function test_Curve_getLength (t) {\n        t.plan( 4 );\n\n      //no components\n        curve = new OpenLayers.Geometry.Curve();\n        curve.components = null;\n        t.eq(curve.getLength(), 0, \"curve with no components has length 0\");\n\n      //empty components\n        curve.components = [];\n        t.eq(curve.getLength(), 0, \"curve with empty components has length 0\");\n\n      //single point curve\n        curve.components = [ new OpenLayers.Geometry.Point(0,0) ];        \n        t.eq(curve.getLength(), 0, \"curve with only one point has length 0\");\n\n      //multipoint\n        var newcomponents = [ new OpenLayers.Geometry.Point(0,0),\n                        new OpenLayers.Geometry.Point(0,10),\n                        new OpenLayers.Geometry.Point(20,10),\n                        new OpenLayers.Geometry.Point(20,-10)\n        ];\n        \n        curve = new OpenLayers.Geometry.Curve(newcomponents);\n        t.eq(curve.getLength(), 50, \"curve.getLength returns a reasonably accurate length\" );\n    }\n    \n    function test_Curve_destroy(t) {\n        t.plan(1);\n        \n        var curve = new OpenLayers.Geometry.Curve();\n        curve.components = {};\n        \n        curve.destroy();\n        \n        t.ok( curve.components == null, \"components is cleared well in destruction\");\n    }\n    \n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Geometry/LineString.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var line;\n    var components = [new OpenLayers.Geometry.Point(10,15), \n                new OpenLayers.Geometry.Point(0,0)];\n        \n    function test_LineString_constructor (t) {\n        t.plan( 3 );\n        line = new OpenLayers.Geometry.LineString();\n        t.ok( line instanceof OpenLayers.Geometry.LineString, \"new OpenLayers.Geometry.LineString returns line object\" );\n        t.eq( line.CLASS_NAME, \"OpenLayers.Geometry.LineString\", \"line.CLASS_NAME is set correctly\");\n        t.eq( line.components, [], \"line.components is set correctly\");\n    }\n\n    function test_LineString_constructor (t) {\n        t.plan( 3 );\n        line = new OpenLayers.Geometry.LineString(components);\n        t.ok( line instanceof OpenLayers.Geometry.LineString, \"new OpenLayers.Geometry.LineString returns line object\" );\n        t.eq( line.CLASS_NAME, \"OpenLayers.Geometry.LineString\", \"line.CLASS_NAME is set correctly\");\n        // TBD FIXME, recursion\n        // t.eq( line.components, components, \"line.components is set correctly\");\n        t.eq( line.components.length, 2, \"line.components.length is set correctly\");\n    }\n    \n    function test_LineString_toString(t) {\n        t.plan(1);\n        \n        line = new OpenLayers.Geometry.LineString(components);\n        t.eq(line.toString(),\n             \"LINESTRING(10 15,0 0)\",\n             \"toString() returns WKT\");\n    }\n    \n    function test_LineString_removeComponent(t) {\n        t.plan(2);\n        \n        OpenLayers.Geometry.Collection.prototype._removeComponent = \n            OpenLayers.Geometry.Collection.prototype.removeComponent;\n        OpenLayers.Geometry.Collection.prototype.removeComponent = \n            function(point) { g_removeComponent = point; };\n        \n        line = new OpenLayers.Geometry.LineString(components);\n\n        g_removeComponent = null;\n        line.removeComponent(components[0]);\n        t.ok(g_removeComponent == null, \"point not removed if only 2 points in components\");\n\n        line.components.push(new OpenLayers.Geometry.Point(4,4));\n        line.removeComponent(components[0]);\n        t.ok(g_removeComponent, components[0], \"point removed if 3 points in components\");\n        \n        OpenLayers.Geometry.Collection.prototype.removeComponent = \n            OpenLayers.Geometry.Collection.prototype._removeComponent;\n    }\n    \n    function test_LineString_move(t) {\n        t.plan(4);\n        \n        var components = [new OpenLayers.Geometry.Point(10,15), \n                new OpenLayers.Geometry.Point(0,0)];\n        var line = new OpenLayers.Geometry.LineString(components);\n        \n        var x0 = components[0].x;\n        var y0 = components[0].y;\n        var x1 = components[1].x;\n        var y1 = components[1].y;\n        \n        var dx = 10 * Math.random();\n        var dy = 10 * Math.random();\n        line.move(dx, dy);\n        \n        t.eq(line.components[0].x, x0 + dx, \"move() correctly modifies first x\");\n        t.eq(line.components[0].y, y0 + dy, \"move() correctly modifies first y\");\n        t.eq(line.components[1].x, x1 + dx, \"move() correctly modifies second x\");\n        t.eq(line.components[1].y, y1 + dy, \"move() correctly modifies second y\");\n    }\n\n    function test_LineString_rotate(t) {\n        t.plan(6);\n        \n        var components = [new OpenLayers.Geometry.Point(10,15), \n                          new OpenLayers.Geometry.Point(0,0)];\n        var geometry = new OpenLayers.Geometry.LineString(components);\n        \n        var originals = [];\n        var comp;\n        var angle = 2 * Math.PI * Math.random();\n        var origin = new OpenLayers.Geometry.Point(10 * Math.random(),\n                                                   10 * Math.random());\n        for(var i=0; i<geometry.components.length; ++i) {\n            comp = geometry.components[i];\n            originals[i] = comp.rotate;\n            comp.rotate = function(a, o) {\n                t.ok(true, \"rotate called for component \" + i);\n                t.ok(a == angle, \"rotate called with correct angle\");\n                t.ok(o == origin, \"rotate called with correct origin\");\n            }\n        }\n        geometry.rotate(angle, origin);\n        \n        // restore the original rotate defs\n        for(var i=0; i<geometry.components.length; ++i) {\n            comp.rotate = originals[i];\n        }\n    }\n\n    function test_LineString_resize(t) {\n        t.plan(8);\n        \n        var tolerance = 1e-10;\n\n        var components = [new OpenLayers.Geometry.Point(10 * Math.random(),\n                                                        10 * Math.random()), \n                          new OpenLayers.Geometry.Point(10 * Math.random(),\n                                                        10 * Math.random())];\n        var geometry = new OpenLayers.Geometry.LineString(components);\n\n        var origin = new OpenLayers.Geometry.Point(10 * Math.random(),\n                                                   10 * Math.random());\n        \n        var scale = 10 * Math.random();\n        \n        var oldLength = geometry.getLength();\n        var ret = geometry.resize(scale, origin);\n        t.ok(ret === geometry, \"resize returns geometry\");\n        var newLength = geometry.getLength();\n        t.ok((((newLength / oldLength) - scale) / scale) < tolerance,\n             \"resize correctly changes the length of a linestring\")\n\n        var originals = [];\n        var comp;\n        for(var i=0; i<geometry.components.length; ++i) {\n            comp = geometry.components[i];\n            originals[i] = comp.resize;\n            comp.resize = function(s, o) {\n                t.ok(true, \"resize called for component \" + i);\n                t.ok(s == scale, \"resize called with correct scale\");\n                t.ok(o == origin, \"resize called with correct origin\");\n            }\n        }\n        geometry.resize(scale, origin);\n        \n        // restore the original resize defs\n        for(var i=0; i<geometry.components.length; ++i) {\n            comp.resize = originals[i];\n        }\n        \n    }\n    \n    function test_split(t) {\n        var wkt = OpenLayers.Geometry.fromWKT;\n        \n        var cases = [{\n            msg: \"no intersection\",\n            g1: \"LINESTRING(0 0, 0 1)\",\n            g2: \"LINESTRING(1 0, 1 1)\",\n            exp: null\n        } , {\n            msg: \"intersection at midpoint\",\n            g1: \"LINESTRING(0 0, 1 1)\",\n            g2: \"LINESTRING(1 0, 0 1)\",\n            exp: [\"LINESTRING(1 0, 0.5 0.5)\", \"LINESTRING(0.5 0.5, 0 1)\"]\n        }, {\n            msg: \"intersection at midpoint (reverse source/target)\",\n            g1: \"LINESTRING(1 0, 0 1)\",\n            g2: \"LINESTRING(0 0, 1 1)\",\n            exp: [\"LINESTRING(0 0, 0.5 0.5)\", \"LINESTRING(0.5 0.5, 1 1)\"]\n        }, {\n            msg: \"intersection at endpoint\",\n            g1: \"LINESTRING(0 0, 1 1)\",\n            g2: \"LINESTRING(1 0, 1 1)\",\n            exp: null\n        }, {\n            msg: \"midpoint intersection, no options\",\n            g1: \"LINESTRING(0 0, 2 2)\",\n            g2: \"LINESTRING(0 2, 2 0)\",\n            exp: [\"LINESTRING(0 2, 1 1)\", \"LINESTRING(1 1, 2 0)\"]\n        }, {\n            msg: \"midpoint intersection, edge false\",\n            opt: {edge: false},\n            g1: \"LINESTRING(0 0, 2 2)\",\n            g2: \"LINESTRING(0 2, 2 0)\",\n            exp: null\n        }, {\n            msg: \"midpoint intersection, mutual\",\n            opt: {mutual: true},\n            g1: \"LINESTRING(0 0, 2 2)\",\n            g2: \"LINESTRING(0 2, 2 0)\",\n            exp: [[\"LINESTRING(0 0, 1 1)\", \"LINESTRING(1 1, 2 2)\"], [\"LINESTRING(0 2, 1 1)\", \"LINESTRING(1 1, 2 0)\"]]\n        }, {\n            msg: \"close intersection, no tolerance\",\n            g1: \"LINESTRING(0 0, 0.9 0.9)\",\n            g2: \"LINESTRING(0 2, 2 0)\",\n            exp: null\n        }, {\n            msg: \"close intersection, within tolerance\",\n            opt: {tolerance: 0.2},\n            g1: \"LINESTRING(0 0, 0.9 0.9)\",\n            g2: \"LINESTRING(0 2, 2 0)\",\n            exp: [\"LINESTRING(0 2, 0.9 0.9)\", \"LINESTRING(0.9 0.9, 2 0)\"]\n        }];\n        \n        t.plan(cases.length);\n        var c, parts, part, midparts;\n        for(var i=0; i<cases.length; ++i) {\n            c = cases[i];\n            var g1 = wkt(c.g1);\n            var g2 = wkt(c.g2);\n            var got = g1.split(g2, c.opt);\n            var exp = c.exp;\n            if(got instanceof Array) {\n                parts = [];\n                for(var j=0; j<got.length; ++j) {\n                    part = got[j];\n                    if(part instanceof Array) {\n                        midparts = [];\n                        for(var k=0; k<part.length; ++k) {\n                            midparts.push(part[k].toString());\n                        }\n                        parts.push(\"[\" + midparts.join(\", \") + \"]\");\n                    } else {\n                        parts.push(got[j].toString());\n                    }\n                }\n                got = parts.join(\", \");\n            }\n            if(exp instanceof Array) {\n                parts = [];\n                for(var j=0; j<exp.length; ++j) {\n                    part = exp[j];\n                    if(part instanceof Array) {\n                        midparts = [];\n                        for(var k=0; k<part.length; ++k) {\n                            midparts.push(wkt(part[k]).toString());\n                        }\n                        parts.push(\"[\" + midparts.join(\", \") + \"]\");\n                    } else {\n                        parts.push(wkt(exp[j]).toString());\n                    }\n                }\n                exp = parts.join(\", \");\n            }\n            t.eq(got, exp, \"case \" + i + \": \" +  c.msg);\n        }\n        \n    }\n    \n\n    function test_distanceTo(t) {\n        var wkt = OpenLayers.Geometry.fromWKT;\n        var geoms = [\n            wkt(\"POINT(0 0)\"),\n            wkt(\"LINESTRING(-2 0, 0 -2, 2 -1, 2 0)\")\n        ];\n\n        var cases = [{\n            got: geoms[1].distanceTo(geoms[0]),\n            expected: Math.sqrt(2)\n        }, {\n            got: geoms[1].distanceTo(geoms[0], {details: true}),\n            expected: {\n                index: 0,\n                indexDistance: 2,\n                distance: Math.sqrt(2),\n                x0: -1, y0: -1,\n                x1: 0, y1: 0\n            }\n        }];\n        \n        t.plan(cases.length);\n        for(var i=0; i<cases.length; ++i) {\n            t.eq(cases[i].got, cases[i].expected, \"case \" + i);\n        }\n        \n    }\n\n    function test_LineString_equals(t) {\n        t.plan(3);\n        \n        var x0 = Math.random() * 100;\n        var y0 = Math.random() * 100;\n        var x1 = Math.random() * 100;\n        var y1 = Math.random() * 100;\n        var point0 = new OpenLayers.Geometry.Point(x0, y0);\n        var point1 = new OpenLayers.Geometry.Point(x1, y1);\n        var geometry = new OpenLayers.Geometry.LineString([point0, point1]);\n        var equal = new OpenLayers.Geometry.LineString([point0, point1]);\n        var offX =  new OpenLayers.Geometry.LineString([\n                            new OpenLayers.Geometry.Point(x0 + 1, y0),\n                            new OpenLayers.Geometry.Point(x1 + 1, y1)]);\n        var offY =  new OpenLayers.Geometry.LineString([\n                            new OpenLayers.Geometry.Point(x0, y0 + 1),\n                            new OpenLayers.Geometry.Point(x1, y1 + 1)]);\n        t.ok(geometry.equals(equal),\n             \"equals() returns true for a geometry with equivalent coordinates\");\n        t.ok(!geometry.equals(offX),\n             \"equals() returns false for a geometry with offset x\");\n        t.ok(!geometry.equals(offY),\n             \"equals() returns false for a geometry with offset y\");\n    }\n\n    \n    function test_getVertices(t) {\n        t.plan(14);\n        \n        var points = [\n            new OpenLayers.Geometry.Point(10, 20),\n            new OpenLayers.Geometry.Point(20, 30),\n            new OpenLayers.Geometry.Point(30, 40),\n            new OpenLayers.Geometry.Point(40, 50)\n        ];\n        var line = new OpenLayers.Geometry.LineString(points);\n        \n        var verts = line.getVertices();\n        t.ok(verts instanceof Array, \"got back an array\");\n        t.eq(verts.length, points.length, \"of correct length length\");\n        t.geom_eq(verts[0], points[0], \"0: correct geometry\");\n        t.geom_eq(verts[1], points[1], \"1: correct geometry\");\n        t.geom_eq(verts[2], points[2], \"2: correct geometry\");\n        t.geom_eq(verts[3], points[3], \"3: correct geometry\");\n        \n        // get nodes only\n        var nodes = line.getVertices(true);\n        t.ok(nodes instanceof Array, \"[nodes only] got back an array\");\n        t.eq(nodes.length, 2, \"[nodes only] of correct length length\");\n        t.geom_eq(nodes[0], points[0], \"[nodes only] first: correct geometry\");\n        t.geom_eq(nodes[1], points[points.length-1], \"[nodes only] last: correct geometry\");\n\n        // no nodes\n        var nodes = line.getVertices(false);\n        t.ok(nodes instanceof Array, \"[no nodes] got back an array\");\n        t.eq(nodes.length, 2, \"[no nodes] of correct length length\");\n        t.geom_eq(nodes[0], points[1], \"[no nodes] first: correct geometry\");\n        t.geom_eq(nodes[1], points[2], \"[no nodes] last: correct geometry\");\n\n    }\n    \n    \n    function test_LineString_clone(t) {\n        t.plan(2);\n        \n        var x0 = Math.random() * 100;\n        var y0 = Math.random() * 100;\n        var x1 = Math.random() * 100;\n        var y1 = Math.random() * 100;\n        var point0 = new OpenLayers.Geometry.Point(x0, y0);\n        var point1 = new OpenLayers.Geometry.Point(x1, y1);\n        var geometry = new OpenLayers.Geometry.LineString([point0, point1]);\n        var clone = geometry.clone();\n        t.ok(clone instanceof OpenLayers.Geometry.LineString,\n             \"clone() creates an OpenLayers.Geometry.LineString\");\n        t.ok(geometry.equals(clone), \"clone has equivalent coordinates\");\n    }\n    \n    function test_getGeodesicLength(t) {\n        \n        // expected values from http://www.movable-type.co.uk/scripts/latlong-vincenty.html\n        var cases = [{\n            wkt: \"LINESTRING(0 0, -10 45)\",\n            exp: 5081689.690\n        }, {\n            wkt: \"LINESTRING(-10 45, 0 0)\",\n            exp: 5081689.690\n        }, {\n            wkt: \"LINESTRING(0 0, -10 45, -20 50)\",\n            exp: 5081689.690 + 935018.062\n        }];\n        t.plan(cases.length);\n        \n        var geom, got;\n        for(var i=0; i<cases.length; ++i) {\n            geom = new OpenLayers.Geometry.fromWKT(cases[i].wkt);\n            got = geom.getGeodesicLength();\n            t.eq(Math.round(got), Math.round(cases[i].exp), \"[case \" + i + \"] length calculated\");\n        }\n        \n    }\n    \n    function test_LineString_simplify(t){\n        t.plan(8);\n        var ls1 = new OpenLayers.Geometry.LineString([\n            new OpenLayers.Geometry.Point(0,0),\n            new OpenLayers.Geometry.Point(1,2.1),\n            new OpenLayers.Geometry.Point(1.8,3.8),\n            new OpenLayers.Geometry.Point(2,4),\n            new OpenLayers.Geometry.Point(3,4),\n            new OpenLayers.Geometry.Point(4,4.5),\n            new OpenLayers.Geometry.Point(5,5)\n            \n        ]);\n        var ls2 = new OpenLayers.Geometry.LineString([\n            new OpenLayers.Geometry.Point(0,0),\n            new OpenLayers.Geometry.Point(1,2.1),\n            new OpenLayers.Geometry.Point(1.8,3.8),\n            new OpenLayers.Geometry.Point(2,4),\n            new OpenLayers.Geometry.Point(3,4),\n            new OpenLayers.Geometry.Point(4,4.5),\n            new OpenLayers.Geometry.Point(5,5),\n            new OpenLayers.Geometry.Point(0,0)\n            \n        ]);\n        var ls3 = new OpenLayers.Geometry.LineString([\n            new OpenLayers.Geometry.Point(0,0),\n            new OpenLayers.Geometry.Point(1,1)\n        ]);\n        var ls5 = new OpenLayers.Geometry.LineString([\n            new OpenLayers.Geometry.Point(0,0),\n            new OpenLayers.Geometry.Point(1,1),\n            new OpenLayers.Geometry.Point(2,2),\n            new OpenLayers.Geometry.Point(3,3),\n            new OpenLayers.Geometry.Point(4,4),\n            new OpenLayers.Geometry.Point(5,5)\n            \n        ]);\n        var ls6 = new OpenLayers.Geometry.LineString([\n            new OpenLayers.Geometry.Point(0,0),\n            new OpenLayers.Geometry.Point(1,1),\n            new OpenLayers.Geometry.Point(1,1),\n            new OpenLayers.Geometry.Point(3,2)\n        ]);\n        \n        t.ok(ls1 instanceof OpenLayers.Geometry.LineString, 'LineString is instance of OpenLayers.Geometry.LineString');\n        var simplified1 = ls1.simplify(0.5);\n        t.ok(simplified1 instanceof OpenLayers.Geometry.LineString, 'Simplified LineString is instance of OpenLayers.Geometry.LineString');\n        t.ok(simplified1.getVertices().length <= ls1.getVertices().length, 'Simplified LineString has less or equal number of vertices');\n        // The simplified version is derived from PostGIS function ST_SIMPLIFY()\n        t.ok(simplified1.toString() === 'LINESTRING(0 0,1.8 3.8,5 5)', 'LineString 1 was simplified correctly');\n        var simplified2 = ls2.simplify(0.5);\n        // The simplified version is derived from PostGIS function ST_SIMPLIFY()\n        t.ok(simplified2.toString() === 'LINESTRING(0 0,1.8 3.8,5 5,0 0)', 'LineString 2 was simplified correctly');\n        var simplified3 = ls3.simplify(0.5);\n        t.ok(simplified3.toString() === ls3.toString(), 'LineString with 2 vertices is left untouched');\n        var simplified5 = ls5.simplify(0.0);\n        t.ok(simplified5.toString() === 'LINESTRING(0 0,5 5)', 'A tolerance of 0 returns the optimized version needless vertices');\n        var simplified6 = ls6.simplify(0.0);\n        t.ok(simplified6.toString() === 'LINESTRING(0 0,1 1,3 2)', 'A tolerance of 0 returns the optimized version without doubled vertices');\n    }\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Geometry/LinearRing.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var line;\n    var components = [new OpenLayers.Geometry.Point(10,10), \n                new OpenLayers.Geometry.Point(0,0)];\n        \n    function test_LinearRing_constructor (t) {\n        t.plan( 6 );\n\n      //null\n        ring = new OpenLayers.Geometry.LinearRing();\n        t.ok( ring instanceof OpenLayers.Geometry.LinearRing, \"new OpenLayers.Geometry.LinearRing returns ring object\" );\n        t.eq( ring.CLASS_NAME, \"OpenLayers.Geometry.LinearRing\", \"ring.CLASS_NAME is set correctly\");\n        t.eq( ring.components, [], \"ring.components is set correctly\");\n\n      //valid components\n        ring = new OpenLayers.Geometry.LinearRing(components);\n        t.ok( ring instanceof OpenLayers.Geometry.LinearRing, \"new OpenLayers.Geometry.LinearRing returns ring object\" );\n        t.eq( ring.CLASS_NAME, \"OpenLayers.Geometry.LinearRing\", \"ring.CLASS_NAME is set correctly\");\n        t.eq( ring.components.length, 3, \"ring.components.length is set correctly\");\n    }\n    \n    function test_LinearRing_addComponent(t) {\n        t.plan(13);\n        \n        var ring = new OpenLayers.Geometry.LinearRing();\n \n        var point = new OpenLayers.Geometry.Point(0,0);\n        t.ok(ring.addComponent(point),\n             \"addComponent returns true for 1st point\");\n        t.eq(ring.components.length, 2, \"add first point, correct length\");\n        t.ok(ring.components[0].equals(point), \"point one correct\");\n        t.ok(ring.components[0] === ring.components[ring.components.length - 1],\n             \"first and last point are the same\");\n        \n        newPoint = new OpenLayers.Geometry.Point(10,10);\n        t.ok(ring.addComponent( newPoint ),\n             \"addComponent returns true for unique point\");\n        t.eq(ring.components.length, 3, \"correctly adds 3rd point\");\n        t.ok(ring.components[0].equals(point), \"point one correct\");\n        t.ok(ring.components[1].equals(newPoint), \"point one correct\");\n        t.ok(ring.components[0] === ring.components[ring.components.length - 1],\n             \"first and last point are the same\");\n        \n        var length = ring.components.length;\n        var clone = ring.components[length - 1].clone();\n        t.ok(!ring.addComponent(clone),\n             \"addComponent returns false for adding a duplicate last point\");\n        t.eq(ring.components.length, length,\n             \"components remains unchanged after trying to add duplicate point\");\n        t.ok(ring.addComponent(clone, length - 1),\n             \"addComponent returns true when adding a duplicate with an index\");\n        t.eq(ring.components.length, length + 1,\n             \"components increase in length after adding a duplicate point with index\");\n        \n    }\n    \n    function test_LinearRing_removeComponent(t) {\n        t.plan(10);\n        \n        var components = [new OpenLayers.Geometry.Point(0,0), \n                    new OpenLayers.Geometry.Point(0,10),\n                    new OpenLayers.Geometry.Point(15,15), \n                    new OpenLayers.Geometry.Point(10,0)\n                    ];\n        var ring = new OpenLayers.Geometry.LinearRing(components);\n \n        ring.removeComponent( ring.components[2] );\n        t.eq(ring.components.length, 4, \"removing from linear ring with 5 points: length ok\");\n        t.ok(ring.components[0].equals(components[0]), \"point one correct\");\n        t.ok(ring.components[1].equals(components[1]), \"point two correct\");\n        t.ok(ring.components[2].equals(components[3]), \"point three correct\");\n        t.ok(ring.components[0] === ring.components[ring.components.length - 1],\n             \"first and last point are the same\");\n \n        var testBounds = new OpenLayers.Bounds(0,0,10,10);\n        var ringBounds = ring.getBounds();\n        t.ok(ringBounds.equals(testBounds), \"bounds correctly recalculated\");\n        \n        ring.removeComponent( ring.components[2] );\n        ring.removeComponent( ring.components[1] );\n        t.eq(ring.components.length, 3, \"cant remove from linear ring with only 3 points. new length ok\");\n        t.ok(ring.components[0].equals(components[0]), \"point one correct\");\n        t.ok(ring.components[1].equals(components[1]), \"point two correct\");\n        t.ok(ring.components[0] === ring.components[ring.components.length - 1],\n             \"first and last point are the same\");\n        \n     }\n    \n    function test_LinearRing_getArea(t) {\n        t.plan(1);\n        var components = [new OpenLayers.Geometry.Point(0,0), \n                    new OpenLayers.Geometry.Point(0,10),\n                    new OpenLayers.Geometry.Point(10,10), \n                    new OpenLayers.Geometry.Point(10,0)\n                    ];\n        var ring = new OpenLayers.Geometry.LinearRing(components);\n        \n        t.eq(ring.getArea(), 100, \"getArea works lovely\");\n    }\n    \n    function test_LinearRing_getLength(t) {\n        t.plan(1);\n        var components = [\n            new OpenLayers.Geometry.Point(0,0), \n            new OpenLayers.Geometry.Point(0,10),\n            new OpenLayers.Geometry.Point(10,10), \n            new OpenLayers.Geometry.Point(10,0)\n        ];\n        var ring = new OpenLayers.Geometry.LinearRing(components);\n        t.eq(ring.getLength(), 40, \"getLength returns the correct perimiter\");\n    }\n\n    function test_LinearRing_getCentroid(t) {\n        t.plan(2);\n        var components = [\n            new OpenLayers.Geometry.Point(0,0), \n            new OpenLayers.Geometry.Point(0,10),\n            new OpenLayers.Geometry.Point(10,10), \n            new OpenLayers.Geometry.Point(10,0)\n        ];\n        var ring = new OpenLayers.Geometry.LinearRing(components);\n        var centroid = ring.getCentroid();\n        t.ok(centroid.x === 5 && centroid.y === 5, \"getCentroid returns the correct centroid\");\n        ring.destroy();\n\n        ring = new OpenLayers.Geometry.LinearRing();\n        t.eq(ring.getCentroid(), null, \"getCentroid returns null if no components\");     \n    }\n\n    function test_LinearRing_move(t) {\n\n        var nvert = 4,\n            x = new Array(nvert),\n            y = new Array(nvert),\n            components = new Array(nvert);\n            \n        t.plan(2 * (nvert + 1));\n\n        for(var i=0; i<nvert; ++i) {\n            x[i] = Math.random();\n            y[i] = Math.random();\n            components[i] = new OpenLayers.Geometry.Point(x[i], y[i]);\n        }\n        x.push(x[0]);\n        y.push(y[0]);\n\n        var ring = new OpenLayers.Geometry.LinearRing(components);\n\n        var dx = Math.random();\n        var dy = Math.random();\n\n        ring.move(dx, dy);\n        \n        for(var j=0; j<nvert + 1; ++j) {\n            t.eq(ring.components[j].x, x[j] + dx,\n                 \"move correctly adjust x coord of \" + j + \" component\");\n            t.eq(ring.components[j].y, y[j] + dy,\n                 \"move correctly adjust y coord of \" + j + \" component\");\n        }\n    }\n    \n    function test_LinearRing_rotate(t) {\n        t.plan(10);\n\n        var components = [\n            new OpenLayers.Geometry.Point(10,10), \n            new OpenLayers.Geometry.Point(11,10),\n            new OpenLayers.Geometry.Point(11,11), \n            new OpenLayers.Geometry.Point(10,11)\n        ];\n        \n        var ring = new OpenLayers.Geometry.LinearRing(components);\n\n        // rotate a quarter turn around the origin\n        var origin = new OpenLayers.Geometry.Point(0, 0);\n        var angle = 90;\n        \n        ring.rotate(angle, origin);\n        \n        function withinTolerance(i, j) {\n            return Math.abs(i - j) < 1e-9;\n        }\n\n        t.ok(withinTolerance(ring.components[0].x , -10),\n             \"rotate correctly adjusts x of component 0\");\n        t.ok(withinTolerance(ring.components[0].y, 10),\n             \"rotate correctly adjusts y of component 0\");\n        t.ok(withinTolerance(ring.components[1].x, -10),\n             \"rotate correctly adjusts x of component 1\");\n        t.ok(withinTolerance(ring.components[1].y, 11),\n             \"rotate correctly adjusts y of component 1\");\n        t.ok(withinTolerance(ring.components[2].x, -11),\n             \"rotate correctly adjusts x of component 2\");\n        t.ok(withinTolerance(ring.components[2].y, 11),\n             \"rotate correctly adjusts y of component 2\");\n        t.ok(withinTolerance(ring.components[3].x, -11),\n             \"rotate correctly adjusts x of component 3\");\n        t.ok(withinTolerance(ring.components[3].y, 10),\n             \"rotate correctly adjusts y of component 3\");\n        t.ok(withinTolerance(ring.components[4].x, -10),\n             \"rotate correctly adjusts x of component 4\");\n        t.ok(withinTolerance(ring.components[4].y, 10),\n             \"rotate correctly adjusts y of component 4\");\n    }\n\n    function test_LinearRing_resize(t) {\n        t.plan(10);\n\n        var components = [\n            new OpenLayers.Geometry.Point(10,10), \n            new OpenLayers.Geometry.Point(11,10),\n            new OpenLayers.Geometry.Point(11,11), \n            new OpenLayers.Geometry.Point(10,11)\n        ];\n        \n        var ring = new OpenLayers.Geometry.LinearRing(components);\n\n        // rotate a quarter turn around the origin\n        var origin = new OpenLayers.Geometry.Point(0, 0);\n        var scale = Math.random();\n        \n        ring.resize(scale, origin);\n        \n        function withinTolerance(i, j) {\n            return Math.abs(i - j) < 1e-9;\n        }\n\n        t.ok(withinTolerance(ring.components[0].x , 10 * scale),\n             \"resize correctly adjusts x of component 0\");\n        t.ok(withinTolerance(ring.components[0].y, 10 * scale),\n             \"resize correctly adjusts y of component 0\");\n        t.ok(withinTolerance(ring.components[1].x, 11 * scale),\n             \"resize correctly adjusts x of component 1\");\n        t.ok(withinTolerance(ring.components[1].y, 10 * scale),\n             \"resize correctly adjusts y of component 1\");\n        t.ok(withinTolerance(ring.components[2].x, 11 * scale),\n             \"resize correctly adjusts x of component 2\");\n        t.ok(withinTolerance(ring.components[2].y, 11 * scale),\n             \"resize correctly adjusts y of component 2\");\n        t.ok(withinTolerance(ring.components[3].x, 10 * scale),\n             \"resize correctly adjusts x of component 3\");\n        t.ok(withinTolerance(ring.components[3].y, 11 * scale),\n             \"resize correctly adjusts y of component 3\");\n        t.ok(withinTolerance(ring.components[4].x, 10 * scale),\n             \"resize correctly adjusts x of component 4\");\n        t.ok(withinTolerance(ring.components[4].y, 10 * scale),\n             \"resize correctly adjusts y of component 4\");\n    }\n\n    function test_containsPoint(t) {\n\n        /**\n         *  The ring:\n         *                      edge 3\n         *          (5, 10)  __________ (15, 10)\n         *                 /         /\n         *        edge 4 /         / edge 2\n         *             /         /\n         *    (0, 0) /_________/ (10, 0)\n         *             edge 1\n         */\n        var components = [\n            new OpenLayers.Geometry.Point(0, 0),\n            new OpenLayers.Geometry.Point(10, 0),\n            new OpenLayers.Geometry.Point(15, 10),\n            new OpenLayers.Geometry.Point(5, 10)\n        ];\n\n        var ring = new OpenLayers.Geometry.LinearRing(components);\n        \n        function p(x, y) {\n            return new OpenLayers.Geometry.Point(x, y);\n        }\n        \n        // contains: 1 (touches), true (within), false (outside)\n        var cases = [{\n            point: p(5, 5), contains: true\n        }, {\n            point: p(20, 20), contains: false\n        }, {\n            point: p(15, 15), contains: false\n        }, {\n            point: p(0, 0), contains: 1 // lower left corner\n        }, {\n            point: p(10, 0), contains: 1 // lower right corner\n        }, {\n            point: p(15, 10), contains: 1 // upper right corner\n        }, {\n            point: p(5, 10), contains: 1 // upper left corner\n        }, {\n            point: p(5, 0), contains: 1 // on edge 1\n        }, {\n            point: p(5, -0.1), contains: false // below edge 1\n        }, {\n            point: p(5, 0.1), contains: true // above edge 1\n        }, {\n            point: p(12.5, 5), contains: 1 // on edge 2\n        }, {\n            point: p(12.4, 5), contains: true // left of edge 2\n        }, {\n            point: p(12.6, 5), contains: false // right of edge 2\n        }, {\n            point: p(10, 10), contains: 1 // on edge 3\n        }, {\n            point: p(10, 9.9), contains: true // below edge 3\n        }, {\n            point: p(10, 10.1), contains: false // above edge 3\n        }, {\n            point: p(2.5, 5), contains: 1 // on edge 4\n        }, {\n            point: p(2.4, 5), contains: false // left of edge 4\n        }, {\n            point: p(2.6, 5), contains: true // right of edge 4\n        }];\n        \n        var len = cases.length;\n        t.plan(len);\n        var c;\n        for (var i=0; i<len; ++i) {\n            c = cases[i];\n            t.eq(ring.containsPoint(c.point), c.contains, \"case \" + i + \": \" + c.point);\n        }\n    }\n    \n    function test_containsPoint_precision(t) {\n\n        /**\n         * The test for linear ring containment was sensitive to failure when\n         * looking for ray crossings on nearly vertical edges.  With a loss\n         * of precision in calculating the x-coordinate for the crossing,\n         * the method would erronously determine that the x-coordinate was\n         * not within the (very narrow) x-range of the nearly vertical edge.\n         * \n         * The test below creates a polygon whose first vertical edge is \n         * nearly horizontal.  The test point lies \"far\" outside the polygon\n         * and we expect the containsPoint method to return false.\n         */\n        \n        t.plan(1);\n\n        var components = [\n            new OpenLayers.Geometry.Point(10000020.000001, 1000000),\n            new OpenLayers.Geometry.Point(10000020.000002, 1000010), // nearly vertical\n            new OpenLayers.Geometry.Point(10000030, 1000010),\n            new OpenLayers.Geometry.Point(10000030, 1000000)\n        ];\n\n        var ring = new OpenLayers.Geometry.LinearRing(components);\n        var point = new OpenLayers.Geometry.Point(10000000, 1000001);\n\n        t.eq(ring.containsPoint(point), false, \"false for point outside polygon with nearly vertical edge\");\n\n    }\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Geometry/MultiLineString.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var line;\n        \n    function test_MultiLineString_constructor (t) {\n        t.plan( 3 );\n        mline = new OpenLayers.Geometry.MultiLineString();\n        t.ok( mline instanceof OpenLayers.Geometry.MultiLineString, \"new OpenLayers.Geometry.MultiLineString returns mline object\" );\n        t.eq( mline.CLASS_NAME, \"OpenLayers.Geometry.MultiLineString\", \"mline.CLASS_NAME is set correctly\");\n        t.eq( mline.components, [], \"line.components is set correctly\");\n    }\n\n    function test_MultiLineString_constructor (t) {\n        t.plan( 3 );\n        line = new OpenLayers.Geometry.LineString();\n        mline = new OpenLayers.Geometry.MultiLineString(line);\n        t.ok( mline instanceof OpenLayers.Geometry.MultiLineString, \"new OpenLayers.Geometry.MultiLineString returns mline object\" );\n        t.eq( mline.CLASS_NAME, \"OpenLayers.Geometry.MultiLineString\", \"mline.CLASS_NAME is set correctly\");\n        t.eq( mline.components.length, 1, \"mline.components.length is set correctly\");\n    }\n\n    function test_split(t) {\n        var wkt = OpenLayers.Geometry.fromWKT;\n        \n        var cases = [{\n            msg: \"no intersection\",\n            g1: \"MULTILINESTRING((0 0, 0 1), (2 2, 3 3))\",\n            g2: \"MULTILINESTRING((1 0, 1 1), (2 2, 3 2))\",\n            exp: null\n        } , {\n            msg: \"intersection at midpoint\",\n            g1: \"MULTILINESTRING((0 0, 1 1))\",\n            g2: \"MULTILINESTRING((1 0, 0 1))\",\n            exp: [\"MULTILINESTRING((1 0, 0.5 0.5))\", \"MULTILINESTRING((0.5 0.5, 0 1))\"]\n        }, {\n            msg: \"intersection at midpoint (reverse source/target)\",\n            g1: \"MULTILINESTRING((1 0, 0 1))\",\n            g2: \"MULTILINESTRING((0 0, 1 1))\",\n            exp: [\"MULTILINESTRING((0 0, 0.5 0.5))\", \"MULTILINESTRING((0.5 0.5, 1 1))\"]\n        }, {\n            msg: \"intersection at endpoint\",\n            g1: \"MULTILINESTRING((0 0, 1 1))\",\n            g2: \"MULTILINESTRING((1 0, 1 1))\",\n            exp: null\n        }, {\n            msg: \"midpoint intersection, no options\",\n            g1: \"MULTILINESTRING((0 0, 2 2))\",\n            g2: \"MULTILINESTRING((0 2, 2 0))\",\n            exp: [\"MULTILINESTRING((0 2, 1 1))\", \"MULTILINESTRING((1 1, 2 0))\"]\n        }, {\n            msg: \"midpoint intersection, edge false\",\n            opt: {edge: false},\n            g1: \"MULTILINESTRING((0 0, 2 2))\",\n            g2: \"MULTILINESTRING((0 2, 2 0))\",\n            exp: null\n        }, {\n            msg: \"midpoint intersection, mutual\",\n            opt: {mutual: true},\n            g1: \"MULTILINESTRING((0 0, 2 2))\",\n            g2: \"MULTILINESTRING((0 2, 2 0))\",\n            exp: [[\"MULTILINESTRING((0 0, 1 1))\", \"MULTILINESTRING((1 1, 2 2))\"], [\"MULTILINESTRING((0 2, 1 1))\", \"MULTILINESTRING((1 1, 2 0))\"]]\n        }, {\n            msg: \"close intersection, no tolerance\",\n            g1: \"MULTILINESTRING((0 0, 0.9 0.9))\",\n            g2: \"MULTILINESTRING((0 2, 2 0))\",\n            exp: null\n        }, {\n            msg: \"close intersection, within tolerance\",\n            opt: {tolerance: 0.2},\n            g1: \"MULTILINESTRING((0 0, 0.9 0.9))\",\n            g2: \"MULTILINESTRING((0 2, 2 0))\",\n            exp: [\"MULTILINESTRING((0 2, 0.9 0.9))\", \"MULTILINESTRING((0.9 0.9, 2 0))\"]\n        }, {\n            msg: \"multi source, single target\",\n            g1: \"MULTILINESTRING((0 0, 2 2))\",\n            g2: \"LINESTRING(0 2, 2 0)\",\n            exp: [\"LINESTRING(0 2, 1 1)\", \"LINESTRING(1 1, 2 0)\"]\n        }, {\n            msg: \"multi source, single target, mutual split\",\n            opt: {mutual: true},\n            g1: \"MULTILINESTRING((0 0, 2 2))\",\n            g2: \"LINESTRING(0 2, 2 0)\",\n            exp: [[\"MULTILINESTRING((0 0, 1 1))\", \"MULTILINESTRING((1 1, 2 2))\"], [\"LINESTRING(0 2, 1 1)\", \"LINESTRING(1 1, 2 0)\"]]\n        }, {\n            msg: \"single source, multi target\",\n            g1: \"LINESTRING(0 2, 2 0)\",\n            g2: \"MULTILINESTRING((0 0, 2 2))\",\n            exp: [\"MULTILINESTRING((0 0, 1 1))\", \"MULTILINESTRING((1 1, 2 2))\"]\n        }, {\n            msg: \"partial target split\",\n            g1: \"MULTILINESTRING((2 0, 0 2))\",\n            g2: \"MULTILINESTRING((0 0, 2 2), (3 3, 4 4))\",\n            exp: [\"MULTILINESTRING((0 0, 1 1))\", \"MULTILINESTRING((1 1, 2 2), (3 3, 4 4))\"]\n        }, {\n            msg: \"partial target split, mutual true\",\n            opt: {mutual: true},\n            g1: \"MULTILINESTRING((2 0, 0 2))\",\n            g2: \"MULTILINESTRING((0 0, 2 2), (3 3, 4 4))\",\n            exp: [[\"MULTILINESTRING((2 0, 1 1))\", \"MULTILINESTRING((1 1, 0 2))\"], [\"MULTILINESTRING((0 0, 1 1))\", \"MULTILINESTRING((1 1, 2 2), (3 3, 4 4))\"]]\n        }, {\n            msg: \"partial source split, mutual true\",\n            opt: {mutual: true},\n            g1: \"MULTILINESTRING((0 0, 2 2), (3 3, 4 4))\",\n            g2: \"MULTILINESTRING((2 0, 0 2))\",\n            exp: [[\"MULTILINESTRING((0 0, 1 1))\", \"MULTILINESTRING((1 1, 2 2), (3 3, 4 4))\"], [\"MULTILINESTRING((2 0, 1 1))\", \"MULTILINESTRING((1 1, 0 2))\"]]\n        }, {\n            msg: \"partial target split with source endpoint\",\n            g1: \"MULTILINESTRING((1 0, 1 1))\",\n            g2: \"MULTILINESTRING((0 0, 2 2), (3 3, 4 4))\",\n            exp: [\"MULTILINESTRING((0 0, 1 1))\", \"MULTILINESTRING((1 1, 2 2), (3 3, 4 4))\"]\n        }, {\n            msg: \"partial target split with source endpoint, mutual true\",\n            opt: {mutual: true},\n            g1: \"MULTILINESTRING((5 5, 6 6), (1 0, 1 1))\",\n            g2: \"MULTILINESTRING((0 0, 2 2), (3 3, 4 4))\",\n            exp: [[], [\"MULTILINESTRING((0 0, 1 1))\", \"MULTILINESTRING((1 1, 2 2), (3 3, 4 4))\"]]\n        }, {\n            msg: \"partial source split with target endpoint\",\n            g1: \"MULTILINESTRING((0 0, 2 2), (3 3, 4 4))\",\n            g2: \"MULTILINESTRING((1 0, 1 1))\",\n            exp: null\n        }, {\n            msg: \"partial source split with target endpoint, mutual true\",\n            opt: {mutual: true},\n            g1: \"MULTILINESTRING((0 0, 2 2), (3 3, 4 4), (5 5, 6 6))\",\n            g2: \"MULTILINESTRING((1 0, 1 1))\",\n            exp: [[\"MULTILINESTRING((0 0, 1 1))\", \"MULTILINESTRING((1 1, 2 2), (3 3, 4 4), (5 5, 6 6))\"], []]\n        }, {\n            msg: \"partial target and source split\",\n            g1: \"MULTILINESTRING((0 5, 2 5), (4 5, 6 5), (8 5, 10 5))\",\n            g2: \"MULTILINESTRING((5 0, 5 2), (5 4, 5 6), (5 8, 5 10))\",\n            exp: [\"MULTILINESTRING((5 0, 5 2), (5 4, 5 5))\", \"MULTILINESTRING((5 5, 5 6), (5 8, 5 10))\"]\n        }, {\n            msg: \"partial target and source split, mutual true\",\n            opt: {mutual: true},\n            g1: \"MULTILINESTRING((0 5, 2 5), (4 5, 6 5), (8 5, 10 5))\",\n            g2: \"MULTILINESTRING((5 0, 5 2), (5 4, 5 6), (5 8, 5 10))\",\n            exp: [[\"MULTILINESTRING((0 5, 2 5), (4 5, 5 5))\", \"MULTILINESTRING((5 5, 6 5), (8 5, 10 5))\"],\n                  [\"MULTILINESTRING((5 0, 5 2), (5 4, 5 5))\", \"MULTILINESTRING((5 5, 5 6), (5 8, 5 10))\"]]\n        }, {\n            msg: \"partial target and source split with source endpoint, mutual true\",\n            opt: {mutual: true},\n            g1: \"MULTILINESTRING((0 5, 2 5), (4 5, 6 5), (8 5, 10 5))\",\n            g2: \"MULTILINESTRING((4 0, 4 2), (4 4, 4 6), (4 8, 4 10))\",\n            exp: [[], [\"MULTILINESTRING((4 0, 4 2), (4 4, 4 5))\", \"MULTILINESTRING((4 5, 4 6), (4 8, 4 10))\"]]\n        }, {\n            msg: \"partial target and source split with target endpoint, mutual true\",\n            opt: {mutual: true},\n            g1: \"MULTILINESTRING((4 0, 4 2), (4 4, 4 6), (4 8, 4 10))\",\n            g2: \"MULTILINESTRING((0 5, 2 5), (4 5, 6 5), (8 5, 10 5))\",\n            exp: [[\"MULTILINESTRING((4 0, 4 2), (4 4, 4 5))\", \"MULTILINESTRING((4 5, 4 6), (4 8, 4 10))\"], []]\n        }, {\n            msg: \"partial target and source split with source vertex, mutual true\",\n            opt: {mutual: true},\n            g1: \"MULTILINESTRING((0 5, 2 5), (4 5, 5 5, 6 5), (8 5, 10 5))\",\n            g2: \"MULTILINESTRING((5 0, 5 2), (5 4, 5 6), (5 8, 5 10))\",\n            exp: [[\"MULTILINESTRING((0 5, 2 5), (4 5, 5 5))\", \"MULTILINESTRING((5 5, 6 5), (8 5, 10 5))\"], [\"MULTILINESTRING((5 0, 5 2), (5 4, 5 5))\", \"MULTILINESTRING((5 5, 5 6), (5 8, 5 10))\"]]\n        }, {\n            msg: \"partial target and source split with target vertex, mutual true\",\n            opt: {mutual: true},\n            g1: \"MULTILINESTRING((5 0, 5 2), (5 4, 5 6), (5 8, 5 10))\",\n            g2: \"MULTILINESTRING((0 5, 2 5), (4 5, 5 5, 6 5), (8 5, 10 5))\",\n            exp: [[\"MULTILINESTRING((5 0, 5 2), (5 4, 5 5))\", \"MULTILINESTRING((5 5, 5 6), (5 8, 5 10))\"], [\"MULTILINESTRING((0 5, 2 5), (4 5, 5 5))\", \"MULTILINESTRING((5 5, 6 5), (8 5, 10 5))\"]]\n        }];\n\n\n        t.plan(cases.length);\n        var c, parts, part, midparts;\n        for(var i=0; i<cases.length; ++i) {\n            c = cases[i];\n            var g1 = wkt(c.g1);\n            var g2 = wkt(c.g2);\n            var got = g1.split(g2, c.opt);\n            var exp = c.exp;\n            if(got instanceof Array) {\n                parts = [];\n                for(var j=0; j<got.length; ++j) {\n                    part = got[j];\n                    if(part instanceof Array) {\n                        midparts = [];\n                        for(var k=0; k<part.length; ++k) {\n                            midparts.push(part[k].toString());\n                        }\n                        parts.push(\"[\" + midparts.join(\", \") + \"]\");\n                    } else {\n                        parts.push(got[j].toString());\n                    }\n                }\n                got = parts.join(\", \");\n            }\n            if(exp instanceof Array) {\n                parts = [];\n                for(var j=0; j<exp.length; ++j) {\n                    part = exp[j];\n                    if(part instanceof Array) {\n                        midparts = [];\n                        for(var k=0; k<part.length; ++k) {\n                            midparts.push(wkt(part[k]).toString());\n                        }\n                        parts.push(\"[\" + midparts.join(\", \") + \"]\");\n                    } else {\n                        parts.push(wkt(exp[j]).toString());\n                    }\n                }\n                exp = parts.join(\", \");\n            }\n            t.eq(got, exp, \"case \" + i + \": \" +  c.msg);\n        }\n        \n    }\n\n    function test_getVertices(t) {\n        t.plan(22);\n        \n        var points = [\n            new OpenLayers.Geometry.Point(10, 20),\n            new OpenLayers.Geometry.Point(20, 30),\n            new OpenLayers.Geometry.Point(30, 40),\n            new OpenLayers.Geometry.Point(40, 50)\n        ];\n        \n        var multi = new OpenLayers.Geometry.MultiLineString([\n            new OpenLayers.Geometry.LineString(points),\n            new OpenLayers.Geometry.LineString(points)\n        ]);\n        \n        var verts = multi.getVertices();\n        t.ok(verts instanceof Array, \"got back an array\");\n        t.eq(verts.length, 2 * points.length, \"of correct length length\");\n        t.geom_eq(verts[0], points[0], \"0: correct geometry\");\n        t.geom_eq(verts[1], points[1], \"1: correct geometry\");\n        t.geom_eq(verts[2], points[2], \"2: correct geometry\");\n        t.geom_eq(verts[3], points[3], \"3: correct geometry\");\n        t.geom_eq(verts[4], points[0], \"4: correct geometry\");\n        t.geom_eq(verts[5], points[1], \"5: correct geometry\");\n        t.geom_eq(verts[6], points[2], \"6: correct geometry\");\n        t.geom_eq(verts[7], points[3], \"7: correct geometry\");\n        \n        // nodes only\n        var nodes = multi.getVertices(true);\n        t.ok(nodes instanceof Array, \"[nodes only] got back an array\");\n        t.eq(nodes.length, 4, \"[nodes only] of correct length length\");\n        t.geom_eq(nodes[0], points[0], \"[nodes only] 0: correct geometry\");\n        t.geom_eq(nodes[1], points[3], \"[nodes only] 1: correct geometry\");\n        t.geom_eq(nodes[2], points[0], \"[nodes only] 2: correct geometry\");\n        t.geom_eq(nodes[3], points[3], \"[nodes only] 3: correct geometry\");\n        \n        // no nodes\n        var nodes = multi.getVertices(false);\n        t.ok(nodes instanceof Array, \"[no nodes] got back an array\");\n        t.eq(nodes.length, 4, \"[no nodes] of correct length length\");\n        t.geom_eq(nodes[0], points[1], \"[no nodes] 0: correct geometry\");\n        t.geom_eq(nodes[1], points[2], \"[no nodes] 1: correct geometry\");\n        t.geom_eq(nodes[2], points[1], \"[no nodes] 2: correct geometry\");\n        t.geom_eq(nodes[3], points[2], \"[no nodes] 3: correct geometry\");\n\n\n    }\n\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Geometry/MultiPoint.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var point = new OpenLayers.Geometry.Point(10, 15);\n     \n        \n    function test_MultiPoint_constructor (t) {\n        t.plan( 2 );\n        var multipoint = new OpenLayers.Geometry.MultiPoint();\n        t.ok( multipoint instanceof OpenLayers.Geometry.MultiPoint, \"new OpenLayers.Geometry.MultiPoint returns multipoint object\" );\n        t.eq( multipoint.CLASS_NAME, \"OpenLayers.Geometry.MultiPoint\", \"multipoint.CLASS_NAME is set correctly\");\n    }\n\n    function test_MultiPoint_constructor (t) {\n        t.plan( 3 );\n        var multipoint = new OpenLayers.Geometry.MultiPoint([point]);\n        t.ok( multipoint instanceof OpenLayers.Geometry.MultiPoint, \"new OpenLayers.Geometry.MultiPoint returns multipoint object\" );\n        t.eq( multipoint.CLASS_NAME, \"OpenLayers.Geometry.MultiPoint\", \"multipoint.CLASS_NAME is set correctly\");\n        t.eq( multipoint.components.length, 1, \"multipolygon.components.length is set correctly\");\n    }\n\n    function test_MultiPoint_move(t) {\n        t.plan(2);\n        \n        var multipoint = new OpenLayers.Geometry.MultiPoint([point]);\n        var x = point.x;\n        var y = point.y;\n        \n        var dx = 10 * Math.random();\n        var dy = 10 * Math.random();\n        multipoint.move(dx, dy);\n        t.eq(multipoint.components[0].x, x + dx, \"move() correctly modifies x\");\n        t.eq(multipoint.components[0].y, y + dy, \"move() correctly modifies y\");\n    }\n    \n    function test_distanceTo(t) {\n        var points = [\n            new OpenLayers.Geometry.Point(0, 0),\n            new OpenLayers.Geometry.Point(10, 0),\n            new OpenLayers.Geometry.Point(0, 9),\n            new OpenLayers.Geometry.Point(-5, 0),\n            new OpenLayers.Geometry.Point(-5, 4)\n        ];\n        \n        var geoms = [\n            new OpenLayers.Geometry.MultiPoint([points[0], points[1]]),\n            new OpenLayers.Geometry.MultiPoint([points[2], points[3]]),\n            points[4]\n        ];\n        \n        var cases = [{\n            got: geoms[0].distanceTo(geoms[0]),\n            expected: 0\n        }, {\n            got: geoms[0].distanceTo(geoms[1]),\n            expected: 5\n        }, {\n            got: geoms[1].distanceTo(geoms[2]),\n            expected: 4\n        }, {\n            got: geoms[0].distanceTo(geoms[1], {details: true}),\n            expected: {\n                distance: 5,\n                x0: 0, y0: 0,\n                x1: -5, y1: 0\n            }\n        }, {\n            got: geoms[1].distanceTo(geoms[0], {details: true}),\n            expected: {\n                distance: 5,\n                x0: -5, y0: 0,\n                x1: 0, y1: 0\n            }\n        }, {\n            got: geoms[1].distanceTo(geoms[2], {details: true}),\n            expected: {\n                distance: 4,\n                x0: -5, y0: 0,\n                x1: -5, y1: 4\n            }\n        }];\n        \n        t.plan(cases.length);\n        for(var i=0; i<cases.length; ++i) {\n            t.eq(cases[i].got, cases[i].expected, \"case \" + i);\n        }\n        \n    }\n\n    function test_MultiPoint_equals(t) {\n        t.plan(3);\n        \n        var x = Math.random() * 100;\n        var y = Math.random() * 100;\n        var geometry = new OpenLayers.Geometry.MultiPoint(\n                                        [new OpenLayers.Geometry.Point(x, y)]);\n        var equal =  new OpenLayers.Geometry.MultiPoint(\n                                        [new OpenLayers.Geometry.Point(x, y)]);        \n        var offX =  new OpenLayers.Geometry.MultiPoint(\n                                        [new OpenLayers.Geometry.Point(x + 1, y)]);        \n        var offY =  new OpenLayers.Geometry.MultiPoint(\n                                        [new OpenLayers.Geometry.Point(x, y + 1)]);        \n        t.ok(geometry.equals(equal),\n             \"equals() returns true for a geometry with equivalent coordinates\");\n        t.ok(!geometry.equals(offX),\n             \"equals() returns false for a geometry with offset x\");\n        t.ok(!geometry.equals(offY),\n             \"equals() returns false for a geometry with offset y\");\n    }\n    \n    function test_MultiPoint_clone(t) {\n        t.plan(2);\n        \n        var x = Math.random() * 100;\n        var y = Math.random() * 100;\n        var geometry = new OpenLayers.Geometry.MultiPoint(\n                                        [new OpenLayers.Geometry.Point(x, y)]);\n        var clone = geometry.clone();\n        t.ok(clone instanceof OpenLayers.Geometry.MultiPoint,\n             \"clone() creates an OpenLayers.Geometry.MultiPoint\");\n        t.ok(geometry.equals(clone), \"clone has equivalent coordinates\");\n    }\n\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Geometry/MultiPolygon.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var polygon;\n    var components = [new OpenLayers.Geometry.Point(10,10), new OpenLayers.Geometry.Point(0,0)];\n    var components2 = [new OpenLayers.Geometry.Point(10,10), new OpenLayers.Geometry.Point(0,0), new OpenLayers.Geometry.Point(10,0), new OpenLayers.Geometry.Point(10,10)];\n    var linearRing = new OpenLayers.Geometry.LinearRing(components);\n    var linearRing2 = new OpenLayers.Geometry.LinearRing(components2);\n    \n    var polygon = new OpenLayers.Geometry.Polygon([linearRing]);\n    var polygon2 = new OpenLayers.Geometry.Polygon([linearRing2]);\n        \n    function test_MultiPolygon_constructor (t) {\n        t.plan( 2 );\n        multipolygon = new OpenLayers.Geometry.MultiPolygon();\n        t.ok( multipolygon instanceof OpenLayers.Geometry.MultiPolygon, \"new OpenLayers.Geometry.MultiPolygon returns multipolygon object\" );\n        t.eq( multipolygon.CLASS_NAME, \"OpenLayers.Geometry.MultiPolygon\", \"multipolygon.CLASS_NAME is set correctly\");\n    }\n\n    function test_MultiPolygon_constructor (t) {\n        t.plan( 3 );\n        multipolygon = new OpenLayers.Geometry.MultiPolygon([polygon, polygon2]);\n        t.ok( multipolygon instanceof OpenLayers.Geometry.MultiPolygon, \"new OpenLayers.Geometry.MultiPolygon returns multipolygon object\" );\n        t.eq( multipolygon.CLASS_NAME, \"OpenLayers.Geometry.MultiPolygon\", \"multipolygon.CLASS_NAME is set correctly\");\n        t.eq( multipolygon.components.length, 2, \"multipolygon.components.length is set correctly\");\n    }\n\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Geometry/Point.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var point; \n        \n    function test_Point_constructor (t) {\n        t.plan( 8 );\n\n      //empty\n        point = new OpenLayers.Geometry.Point();\n        t.ok( point instanceof OpenLayers.Geometry.Point, \"new OpenLayers.Geometry.Point returns point object\" );\n        t.eq( point.CLASS_NAME, \"OpenLayers.Geometry.Point\", \"point.CLASS_NAME is set correctly\");\n\n      //valid\n        var x = 10;\n        var y = 20;\n        point = new OpenLayers.Geometry.Point(x, y);\n        t.ok( point instanceof OpenLayers.Geometry.Point, \"new OpenLayers.Geometry.Point returns point object\" );\n        t.eq( point.CLASS_NAME, \"OpenLayers.Geometry.Point\", \"point.CLASS_NAME is set correctly\");\n        t.eq( point.x, x, \"point.x is set correctly\");\n        t.eq( point.y, y, \"point.y is set correctly\");\n        t.eq( point.lon, null, \"point.lon is not set\");\n        t.eq( point.lat, null, \"point.lat is not set\");\n    }\n\n    function test_Point_calculateBounds (t) {\n        t.plan(4);\n\n        var x = 10;\n        var y = 20;\n        point = new OpenLayers.Geometry.Point(x, y);\n        point.calculateBounds();\n        t.eq( point.bounds.left, x, \"bounds.left is 10\" );\n        t.eq( point.bounds.right, x, \"bounds.right is 10\" );\n        t.eq( point.bounds.top, y, \"bounds.top is 20\" );\n        t.eq( point.bounds.bottom, y, \"bounds.bottom is 20\" );\n    }\n    \n\n    function test_Point_transform_getBounds (t) {\n        t.plan(2);\n\n        var x = 10;\n        var y = 20;\n        point = new OpenLayers.Geometry.Point(x, y);\n        point.calculateBounds();\n        t.ok( point.bounds != null, \"bounds calculated by calcBounds\" );\n        point.transform(new OpenLayers.Projection(\"EPSG:4326\"), \n                        new OpenLayers.Projection(\"EPSG:900913\"));\n        t.eq(point.bounds, null, \"Point bounds cleared after transform\");\n    }\n\n    function test_Point_transform_string(t) {\n        t.plan(4);\n\n        var x = 10;\n        var y = 20;\n        point = new OpenLayers.Geometry.Point(x, y);\n        point.calculateBounds();\n        t.ok( point.bounds != null, \"bounds calculated by calcBounds\" );\n        point.transform(\"EPSG:4326\", \"EPSG:900913\");\n        t.eq(point.bounds, null, \"Point bounds cleared after transform\");\n        t.eq(point.x.toFixed(2), \"1113194.91\", \"transformed x\");\n        t.eq(point.y.toFixed(2), \"2273030.93\", \"transformed y\");\n        \n    }\n    \n    function test_Point_distanceTo(t) {\n        t.plan(7);\n\n        var x1 = 10;\n        var y1 = 20;\n        point1 = new OpenLayers.Geometry.Point(x1, y1);\n\n        var x2 = 100;\n        var y2 = 200;\n        point2 = new OpenLayers.Geometry.Point(x2, y2);\n\n        var dist = point1.distanceTo(point2)\n        t.eq( dist, 201.24611797498107267682563018581, \"distances calculating correctly\");\n        t.eq( dist, Math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)), \"distance calculation correct\");\n        \n        // test that details are returned (though trivial in this case)\n        var result = point1.distanceTo(point2, {details: true});\n        t.eq(result.distance, point1.distanceTo(point2), \"[details] distance property is same as return without details\");\n        t.eq(result.x0, x1, \"[details] x0 property is correct\");\n        t.eq(result.y0, y1, \"[details] y0 property is correct\");\n        t.eq(result.x1, x2, \"[details] x1 property is correct\");\n        t.eq(result.y1, y2, \"[details] y1 property is correct\");\n        \n    }\n    \n    function test_Point_toString(t) {\n        t.plan(1);\n\n        var x = 10;\n        var y = 20;\n        point = new OpenLayers.Geometry.Point(x, y);\n        t.eq(point.toString(), \"POINT(\" + x + \" \" + y + \")\",\n             \"toString() returns WKT\" );\n        \n    }\n\n    function test_Point_toString_no_wkt(t) {\n        t.plan(1);\n        \n        var WKT = OpenLayers.Format.WKT;\n        OpenLayers.Format.WKT = null;\n\n        var x = 10;\n        var y = 20;\n        point = new OpenLayers.Geometry.Point(x, y);\n        t.eq(point.toString(), \"[object Object]\", \"default string representation\");\n        \n        OpenLayers.Format.WKT = WKT;\n        \n    }\n    \n    function test_Point_move(t) {\n        t.plan(3);\n        \n        var x = 10;\n        var y = 20;\n        point = new OpenLayers.Geometry.Point(x, y);\n        \n        var dx = 10 * Math.random();\n        var dy = 10 * Math.random();\n        point.bounds = \"foo\";\n        point.move(dx, dy);\n        t.eq(point.x, x + dx, \"move() correctly modifies x\");\n        t.eq(point.y, y + dy, \"move() correctly modifies y\");\n        \n        t.ok(point.bounds == null, \"bounds is cleared after a move()\");\n    }\n\n    function test_Point_rotate(t) {\n        t.plan(5);\n        \n        var tolerance = 1e-10;\n        var x = 10;\n        var y = 20;\n        var point = new OpenLayers.Geometry.Point(x, y);\n        var origin = new OpenLayers.Geometry.Point(5, 10);\n        \n        // rotate a full revolution\n        point.bounds = \"foo\";\n        point.rotate(360, origin);\n        t.ok(((point.x - x) / x) < tolerance,\n             \"rotate by 360 returns to the same y\");\n        t.ok(((point.y - y) / y) < tolerance,\n             \"rotate by 360 returns to the same y\");\n        \n        t.ok(point.bounds == null, \"bounds is cleared after a rotate()\");\n        \n        // rotate an 1/8 turn\n        point.rotate(45, origin);\n        t.ok(((point.x - 1.4644660940672636) / 1.4644660940672636) < tolerance,\n             \"rotate 1/8 turn correctly\");\n        t.ok(((point.y - 20.606601717798213) / 20.606601717798213) < tolerance,\n             \"rotate 1/8 turn correctly\");\n    }\n\n    function test_Point_resize(t) {\n        t.plan(6);\n        \n        var tolerance = 1e-10;\n        var x = 100 * Math.random();\n        var y = 100 * Math.random();\n        var point = new OpenLayers.Geometry.Point(x, y);\n        point.bounds = \"foo\";\n        \n        var i = 100 * Math.random();\n        var j = 100 * Math.random();\n        var origin = new OpenLayers.Geometry.Point(i, j);\n        \n        var scale = 10 * Math.random();\n        var oldDistance = origin.distanceTo(point);\n        \n        var ret = point.resize(scale, origin);\n        var newDistance = origin.distanceTo(point);\n        \n        t.ok(ret === point, \"resize returns geometry\");\n        t.ok((origin.x == i) && (origin.y == j),\n             \"resize leaves the origin untouched\");\n        t.ok((((newDistance / oldDistance) - scale) / scale) < tolerance,\n             \"resize moves points the correct distance from the origin\");\n        \n        t.ok(point.bounds == null, \"bounds is correctly cleared after a resize()\");\n        \n        // resize with non uniform scaling (ratio != 1)\n        point = new OpenLayers.Geometry.Point(10, 10);\n        origin = new OpenLayers.Geometry.Point(0, 0);\n        point.resize(2, origin, 4);\n        t.eq(point.x, 80, \"non-uniform scaling correctly applied in x dim\");\n        t.eq(point.y, 20, \"non-uniform scaling correctly applied in y dim\");\n        \n    }\n\n    function test_Point_equals(t) {\n        t.plan(3);\n        \n        var x = Math.random() * 100;\n        var y = Math.random() * 100;\n        var geometry = new OpenLayers.Geometry.Point(x, y);\n        var equal = new OpenLayers.Geometry.Point(x, y);\n        var offX = new OpenLayers.Geometry.Point(x + 1, y);\n        var offY = new OpenLayers.Geometry.Point(x, y + 1);\n        t.ok(geometry.equals(equal),\n             \"equals() returns true for a geometry with equivalent coordinates\");\n        t.ok(!geometry.equals(offX),\n             \"equals() returns false for a geometry with offset x\");\n        t.ok(!geometry.equals(offY),\n             \"equals() returns false for a geometry with offset y\");\n    }\n    \n    function test_getVertices(t) {\n        t.plan(3);\n        \n        var point = new OpenLayers.Geometry.Point(10, 20);\n        var verts = point.getVertices();\n        t.ok(verts instanceof Array, \"got back an array\");\n        t.eq(verts.length, 1, \"of length 1\");\n        t.geom_eq(verts[0], point, \"with correct geometry\");\n    }\n    \n    function test_Point_clone(t) {\n        t.plan(2);\n        \n        var x = Math.random() * 100;\n        var y = Math.random() * 100;\n        var geometry = new OpenLayers.Geometry.Point(x, y);\n        var clone = geometry.clone();\n        t.ok(clone instanceof OpenLayers.Geometry.Point,\n             \"clone() creates an OpenLayers.Geometry.Point\");\n        t.ok(geometry.equals(clone), \"clone has equivalent coordinates\");\n    }\n    \n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Geometry/Polygon.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var polygon;\n    var components = [new OpenLayers.Geometry.Point(10,14), new OpenLayers.Geometry.Point(5,3)];\n    var components2 = [new OpenLayers.Geometry.Point(12,15), new OpenLayers.Geometry.Point(2,3), new OpenLayers.Geometry.Point(10,0), new OpenLayers.Geometry.Point(10,10)];\n    var linearRing = new OpenLayers.Geometry.LinearRing(components);\n    var linearRing2 = new OpenLayers.Geometry.LinearRing(components2);\n    \n    function test_Polygon_constructor (t) {\n        t.plan( 3 );\n        polygon = new OpenLayers.Geometry.Polygon();\n        t.ok( polygon instanceof OpenLayers.Geometry.Polygon, \"new OpenLayers.Geometry.Polygon returns polygon object\" );\n        t.eq( polygon.CLASS_NAME, \"OpenLayers.Geometry.Polygon\", \"polygon.CLASS_NAME is set correctly\");\n        t.eq( polygon.components.length, 0, \"polygon.components is set correctly\");\n    }\n\n    function test_Polygon_constructor (t) {\n        t.plan( 3 );\n        polygon = new OpenLayers.Geometry.Polygon([linearRing]);\n        t.ok( polygon instanceof OpenLayers.Geometry.Polygon, \"new OpenLayers.Geometry.Polygon returns polygon object\" );\n        t.eq( polygon.CLASS_NAME, \"OpenLayers.Geometry.Polygon\", \"polygon.CLASS_NAME is set correctly\");\n        t.eq( polygon.components.length, 1, \"polygon.components.length is set correctly\");\n    }\n    \n    function test_Polygon_constructor (t) {\n        t.plan( 3 );\n        polygon = new OpenLayers.Geometry.Polygon([linearRing, linearRing2]);\n        t.ok( polygon instanceof OpenLayers.Geometry.Polygon, \"new OpenLayers.Geometry.Polygon returns polygon object\" );\n        t.eq( polygon.CLASS_NAME, \"OpenLayers.Geometry.Polygon\", \"polygon.CLASS_NAME is set correctly\");\n        t.eq( polygon.components.length, 2, \"polygon.components.length is set correctly\");\n    }\n    \n    function test_Polygon_transform_getBounds (t) {\n        t.plan(3);\n\n        var components = [new OpenLayers.Geometry.Point(10,14), new OpenLayers.Geometry.Point(5,3)];\n        var linearRing = new OpenLayers.Geometry.LinearRing(components);\n        polygon = new OpenLayers.Geometry.Polygon([linearRing.clone()]);\n        polygon.calculateBounds();\n        t.ok( polygon.bounds != null, \"bounds calculated by calcBounds\" );\n        polygon.transform(new OpenLayers.Projection(\"EPSG:4326\"), \n                        new OpenLayers.Projection(\"EPSG:900913\"));\n        t.eq(polygon.bounds, null, \"Point bounds cleared after transform\");\n        t.eq(polygon.getBounds().toBBOX(), \"556597.453889,334111.171355,1113194.907778,1574216.547942\", \"Bounds are correct\")\n    }\n\n    function test_Polygon_transform_string (t) {\n        t.plan(3);\n\n        var components = [new OpenLayers.Geometry.Point(10,14), new OpenLayers.Geometry.Point(5,3)];\n        var linearRing = new OpenLayers.Geometry.LinearRing(components);\n        polygon = new OpenLayers.Geometry.Polygon([linearRing.clone()]);\n        polygon.calculateBounds();\n        t.ok( polygon.bounds != null, \"bounds calculated by calcBounds\" );\n        polygon.transform(\"EPSG:4326\", \"EPSG:900913\");\n        t.eq(polygon.bounds, null, \"Point bounds cleared after transform\");\n        t.eq(polygon.getBounds().toBBOX(), \"556597.453889,334111.171355,1113194.907778,1574216.547942\", \"Bounds are correct\")\n    }\n\n    function test_Polygon_getArea(t) {\n        t.plan( 5 );\n\n      //no components\n        var polygon = new OpenLayers.Geometry.Polygon();\n        t.eq(polygon.getArea(), 0, \"getArea empty polygon is 0\");\n\n        var createSquareRing = function(area) {\n            var points = [\n                new OpenLayers.Geometry.Point(0, 0),\n                new OpenLayers.Geometry.Point(0, area),\n                new OpenLayers.Geometry.Point(area, area),\n                new OpenLayers.Geometry.Point(area, 0)\n            ];\n            var ring = new OpenLayers.Geometry.LinearRing(points);\n            return ring;\n        };\n    \n\n      //simple polygon\n        var comps = [ createSquareRing(2) ];\n        \n        var polygon = new OpenLayers.Geometry.Polygon(comps);\n        t.eq(polygon.getArea(), 4, \"getArea simple polygon works lovely\");\n\n      //polygon with holes\n        comps = [ createSquareRing(10),\n                           createSquareRing(2),\n                           createSquareRing(3),\n                           createSquareRing(4)\n                         ];\n\n        var polygon = new OpenLayers.Geometry.Polygon(comps);\n        t.eq(polygon.getArea(), 71, \"getArea polygon with holes works lovely\");\n        \n      //simple polygon negative\n        comps = [ createSquareRing(-2) ];\n        \n        var polygon = new OpenLayers.Geometry.Polygon(comps);\n        t.eq(polygon.getArea(), 4, \"getArea simple polygon negative works lovely\");\n\n      //polygon with holes negative\n        comps = [ createSquareRing(-10),\n                           createSquareRing(-2),\n                           createSquareRing(-3),\n                           createSquareRing(-4)\n                         ];\n        \n        var polygon = new OpenLayers.Geometry.Polygon(comps);\n        t.eq(polygon.getArea(), 71, \"getArea negative polygon with holes works lovely\");\n        \n    }\n    \n    function test_Polygon_move(t) {\n        t.plan(4);\n        \n        polygon = new OpenLayers.Geometry.Polygon([linearRing, linearRing2]);\n        \n        var x = linearRing.components[0].x;\n        var y = linearRing.components[0].y;\n        var x2 = linearRing2.components[0].x;\n        var y2 = linearRing2.components[0].y;\n        \n        var dx = 10 * Math.random();\n        var dy = 10 * Math.random();\n\n        polygon.move(dx, dy);\n\n        t.eq(polygon.components[0].components[0].x, x + dx, \"move() correctly modifies first x\");\n        t.eq(polygon.components[0].components[0].y, y + dy, \"move() correctly modifies first y\");\n        t.eq(polygon.components[1].components[0].x, x2 + dx, \"move() correctly modifies second x\");\n        t.eq(polygon.components[1].components[0].y, y2 + dy, \"move() correctly modifies second y\");\n    }\n\n    function test_Polygon_rotate(t) {\n        t.plan(6);\n        \n        var geometry = new OpenLayers.Geometry.Polygon([linearRing, linearRing2]);\n        \n        var originals = [];\n        var comp;\n        var angle = 2 * Math.PI * Math.random();\n        var origin = new OpenLayers.Geometry.Point(10 * Math.random(),\n                                                   10 * Math.random());\n        for(var i=0; i<geometry.components.length; ++i) {\n            comp = geometry.components[i];\n            originals[i] = comp.rotate;\n            comp.rotate = function(a, o) {\n                t.ok(true, \"rotate called for component \" + i);\n                t.ok(a == angle, \"rotate called with correct angle\");\n                t.ok(o == origin, \"rotate called with correct origin\");\n            }\n        }\n        geometry.rotate(angle, origin);\n        \n        // restore the original rotate defs\n        for(var i=0; i<geometry.components.length; ++i) {\n            comp.rotate = originals[i];\n        }\n    }\n\n    function test_Polygon_resize(t) {\n        t.plan(8);\n        \n        var tolerance = 1e-10;\n        var geometry = new OpenLayers.Geometry.Polygon([linearRing, linearRing2]);\n        var origin = new OpenLayers.Geometry.Point(10 * Math.random(),\n                                                   10 * Math.random());\n        var scale = 10 * Math.random();\n        \n        var oldArea = geometry.getArea();\n        var oldPerimeter = geometry.getLength();\n        geometry.resize(scale, origin);\n        var newArea = geometry.getArea();\n        var newPerimeter = geometry.getLength();\n        \n        t.ok((((newArea / oldArea) - (scale * scale)) / (scale * scale)) < tolerance,\n             \"resize correctly changes the area of a polygon\")\n        t.ok((((newPerimeter / oldPerimeter) - scale) / scale) < tolerance,\n             \"resize correctly changes the perimeter of a polygon\")\n\n        var originals = [];\n        var comp;\n        for(var i=0; i<geometry.components.length; ++i) {\n            comp = geometry.components[i];\n            originals[i] = comp.resize;\n            comp.resize = function(s, o) {\n                t.ok(true, \"resize called for component \" + i);\n                t.ok(s == scale, \"resize called with correct scale\");\n                t.ok(o == origin, \"resize called with correct origin\");\n            }\n        }\n        geometry.resize(scale, origin);\n        \n        // restore the original resize defs\n        for(var i=0; i<geometry.components.length; ++i) {\n            comp.resize = originals[i];\n        }\n        \n    }\n\n    function test_Polygon_createRegular(t) {\n        t.plan(22);\n        var sides = 40;\n        var poly = OpenLayers.Geometry.Polygon.createRegularPolygon(new OpenLayers.Geometry.Point(5,0), 6, sides);\n        var polyBounds = poly.getBounds();\n        t.eq(polyBounds.toBBOX(), \"-0.981504,-5.981504,10.981504,5.981504\", sides + \" sided figure generates correct bbox.\");\n        t.eq(poly.components.length, 1, \"Poly has one linear ring\");\n        t.eq(poly.components[0].components.length, sides + 1, \"ring has 41 components\");\n        t.eq(poly.components[0].components[0].id, poly.components[0].components[sides].id, \"ring starts and ends with same geom\");\n        t.eq(Math.round(poly.getArea()), Math.round(Math.PI * 36), \"area of \"+sides+\" sided poly rounds to same area as a circle.\");\n        \n        var sides = 3;\n        var poly = OpenLayers.Geometry.Polygon.createRegularPolygon(new OpenLayers.Geometry.Point(5,0), 6, sides);\n        var polyBounds = poly.getBounds();\n        t.eq(polyBounds.toBBOX(), \"-0.196152,-3,10.196152,6\", sides + \" sided figure generates correct bbox.\");\n        t.eq(poly.components.length, 1, \"Poly has one linear ring\");\n        t.eq(poly.components[0].components.length, sides + 1, \"ring has  correct count of  components\");\n        t.eq(poly.components[0].components[0].id, poly.components[0].components[sides].id, \"ring starts and ends with same geom\");\n        t.eq(Math.round(poly.getArea()), 47, \"area of 3 sided poly is correct\");\n        \n        var sides = 3;\n        var poly3 = OpenLayers.Geometry.Polygon.createRegularPolygon(new OpenLayers.Geometry.Point(10,0), 15, sides);\n        var polyBounds = poly3.getBounds();\n        t.eq(polyBounds.toBBOX(), \"-2.990381,-7.5,22.990381,15\", sides + \" sided figure generates correct bbox.\");\n        t.eq(Math.round(polyBounds.getCenterLonLat().lon), 10, \"longitude of center of bounds is same as origin\");\n        t.eq(poly3.components.length, 1, \"Poly has one linear ring\");\n        t.eq(poly3.components[0].components.length, sides + 1, \"ring has  correct count of  components\");\n        t.eq(poly3.components[0].components[0].id, poly3.components[0].components[sides].id, \"ring starts and ends with same geom\");\n        t.ok(poly3.getArea() > poly.getArea(), \"area with radius 15 > poly with radius 6\"); \n        \n        var sides = 4;\n        var poly4 = OpenLayers.Geometry.Polygon.createRegularPolygon(new OpenLayers.Geometry.Point(10,0), 15, sides);\n        var polyBounds = poly4.getBounds();\n        t.eq(polyBounds.toBBOX(), \"-0.606602,-10.606602,20.606602,10.606602\", sides + \" sided figure generates correct bbox.\");\n        t.eq(Math.round(polyBounds.getCenterLonLat().lon), 10, \"longitude of center of bounds is same as origin\");\n        t.eq(poly4.components.length, 1, \"Poly has one linear ring\");\n        t.eq(poly4.components[0].components.length, sides + 1, \"ring has  correct count of  components\");\n        t.eq(poly4.components[0].components[0].id, poly4.components[0].components[sides].id, \"ring starts and ends with same geom\");\n        t.ok(poly4.getArea() > poly3.getArea(), \"square with radius 15 > triangle with radius 15\"); \n    }\n\n    function test_Polygon_equals(t) {\n        t.plan(3);\n        \n        var x0 = Math.random() * 100;\n        var y0 = Math.random() * 100;\n        var x1 = Math.random() * 100;\n        var y1 = Math.random() * 100;\n        var x2 = Math.random() * 100;\n        var y2 = Math.random() * 100;\n        var point0 = new OpenLayers.Geometry.Point(x0, y0);\n        var point1 = new OpenLayers.Geometry.Point(x1, y1);\n        var point2 = new OpenLayers.Geometry.Point(x2, y2);\n        var pointX = new OpenLayers.Geometry.Point(x0 + 1, y0);\n        var pointY = new OpenLayers.Geometry.Point(x0, y0 + 1);\n        var geometry = new OpenLayers.Geometry.Polygon([\n                            new OpenLayers.Geometry.LinearRing([point0, point1, point2])]);\n        var equal = new OpenLayers.Geometry.Polygon([\n                            new OpenLayers.Geometry.LinearRing([point0, point1, point2])]);\n        var offX = new OpenLayers.Geometry.Polygon([\n                            new OpenLayers.Geometry.LinearRing([pointX, point1, point2])]);\n        var offY = new OpenLayers.Geometry.Polygon([\n                            new OpenLayers.Geometry.LinearRing([pointY, point1, point2])]);\n        t.ok(geometry.equals(equal),\n             \"equals() returns true for a geometry with equivalent coordinates\");\n        t.ok(!geometry.equals(offX),\n             \"equals() returns false for a geometry with offset x\");\n        t.ok(!geometry.equals(offY),\n             \"equals() returns false for a geometry with offset y\");\n    }\n    \n    function test_distanceTo(t) {\n        var wkt = OpenLayers.Geometry.fromWKT;\n        var geoms = [\n            wkt(\"POLYGON((0 3, 1 4, 2 3, 1 2, 0 3))\"),\n            wkt(\"POINT(0 0)\"),\n            wkt(\"LINESTRING(-2 0, 0 -2, 2 -1, 2 0)\"),\n            wkt(\"LINESTRING(0 2, 1 3)\"),\n            wkt(\"POINT(1 3)\")\n        ];\n\n        var cases = [{\n            got: geoms[0].distanceTo(geoms[1]),\n            expected: Math.sqrt(5)\n        }, {\n            got: geoms[0].distanceTo(geoms[1], {details: true}),\n            expected: {\n                index: 1,\n                indexDistance: 3,\n                distance: Math.sqrt(5),\n                x0: 1, y0: 2,\n                x1: 0, y1: 0\n            }\n        }, {\n            got: geoms[0].distanceTo(geoms[2], {details: true}),\n            expected: {\n                distance: Math.sqrt(5),\n                x0: 1, y0: 2,\n                x1: 2, y1: 0\n            }\n        }, {\n            got: geoms[0].distanceTo(geoms[3], {details: true}),\n            expected: {\n                distance: 0,\n                x0: 0.5, y0: 2.5,\n                x1: 0.5, y1: 2.5\n            }\n        }, {\n            got: geoms[0].distanceTo(geoms[4]),\n            expected: Math.sqrt(0.5)\n        }, {\n            got: geoms[0].distanceTo(geoms[4], {edge: false}),\n            expected: 0\n        }];\n\n        t.plan(cases.length);\n        for(var i=0; i<cases.length; ++i) {\n            t.eq(cases[i].got, cases[i].expected, \"case \" + i);\n        }\n        \n    }\n\n    function test_getVertices(t) {\n        t.plan(6);\n        \n        var points = [\n            new OpenLayers.Geometry.Point(10, 20),\n            new OpenLayers.Geometry.Point(20, 30),\n            new OpenLayers.Geometry.Point(30, 40),\n            new OpenLayers.Geometry.Point(40, 50)\n        ];\n        var polygon = new OpenLayers.Geometry.Polygon([\n            new OpenLayers.Geometry.LinearRing(points)\n        ]);\n        \n        var verts = polygon.getVertices();\n        t.ok(verts instanceof Array, \"got back an array\");\n        t.eq(verts.length, points.length, \"of correct length length\");\n        t.geom_eq(verts[0], points[0], \"0: correct geometry\");\n        t.geom_eq(verts[1], points[1], \"1: correct geometry\");\n        t.geom_eq(verts[2], points[2], \"2: correct geometry\");\n        t.geom_eq(verts[3], points[3], \"3: correct geometry\");\n        \n    }\n\n    function test_Polygon_clone(t) {\n        t.plan(2);\n        \n        var x0 = Math.random() * 100;\n        var y0 = Math.random() * 100;\n        var x1 = Math.random() * 100;\n        var y1 = Math.random() * 100;\n        var x2 = Math.random() * 100;\n        var y2 = Math.random() * 100;\n        var point0 = new OpenLayers.Geometry.Point(x0, y0);\n        var point1 = new OpenLayers.Geometry.Point(x1, y1);\n        var point2 = new OpenLayers.Geometry.Point(x2, y2);\n        var geometry = new OpenLayers.Geometry.Polygon([\n                            new OpenLayers.Geometry.LinearRing([point0, point1, point2])]);\n        var clone = geometry.clone();\n        t.ok(clone instanceof OpenLayers.Geometry.Polygon,\n             \"clone() creates an OpenLayers.Geometry.Polygon\");\n        t.ok(geometry.equals(clone), \"clone has equivalent coordinates\");\n    }\n    \n    function test_getGeodesicArea(t) {\n        \n        t.plan(1);\n        \n        // from the wfs-states.html example\n        var illinois = OpenLayers.Geometry.fromWKT(\n            \"MULTIPOLYGON(((-88.071564 37.51099,-88.087883 37.476273,-88.311707 37.442852,-88.359177 37.409309,-88.419853 37.420292,-88.467644 37.400757,-88.511322 37.296852,-88.501427 37.257782,-88.450699 37.205669,-88.422516 37.15691,-88.45047 37.098671,-88.476799 37.072144,-88.4907 37.06818,-88.517273 37.06477,-88.559273 37.072815,-88.61422 37.109047,-88.68837 37.13541,-88.739113 37.141182,-88.746506 37.152107,-88.863289 37.202194,-88.932503 37.218407,-88.993172 37.220036,-89.065033 37.18586,-89.116821 37.112137,-89.146347 37.093185,-89.169548 37.064236,-89.174332 37.025711,-89.150246 36.99844,-89.12986 36.988113,-89.193512 36.986771,-89.210052 37.028973,-89.237679 37.041733,-89.264053 37.087124,-89.284233 37.091244,-89.303291 37.085384,-89.3097 37.060909,-89.264244 37.027733,-89.262001 37.008686,-89.282768 36.999207,-89.310982 37.009682,-89.38295 37.049213,-89.37999 37.099083,-89.423798 37.137203,-89.440521 37.165318,-89.468216 37.224266,-89.465309 37.253731,-89.489594 37.256001,-89.513885 37.276402,-89.513885 37.304962,-89.50058 37.329441,-89.468742 37.339409,-89.435738 37.355717,-89.427574 37.411018,-89.453621 37.453186,-89.494781 37.491726,-89.524971 37.571957,-89.513367 37.615929,-89.51918 37.650375,-89.513374 37.67984,-89.521523 37.694798,-89.581436 37.706104,-89.666458 37.745453,-89.675858 37.78397,-89.691055 37.804794,-89.728447 37.840992,-89.851715 37.905064,-89.861046 37.905487,-89.866814 37.891876,-89.900551 37.875904,-89.937874 37.878044,-89.978912 37.911884,-89.958229 37.963634,-90.010811 37.969318,-90.041924 37.993206,-90.119339 38.032272,-90.134712 38.053951,-90.207527 38.088905,-90.254059 38.122169,-90.289635 38.166817,-90.336716 38.188713,-90.364769 38.234299,-90.369347 38.323559,-90.358688 38.36533,-90.339607 38.390846,-90.301842 38.427357,-90.265785 38.518688,-90.26123 38.532768,-90.240944 38.562805,-90.183708 38.610271,-90.183578 38.658772,-90.20224 38.700363,-90.196571 38.723965,-90.163399 38.773098,-90.135178 38.785484,-90.121727 38.80051,-90.113121 38.830467,-90.132812 38.853031,-90.243927 38.914509,-90.278931 38.924717,-90.31974 38.924908,-90.413071 38.96233,-90.469841 38.959179,-90.530426 38.891609,-90.570328 38.871326,-90.627213 38.880795,-90.668877 38.935253,-90.70607 39.037792,-90.707588 39.058178,-90.690399 39.0937,-90.716736 39.144211,-90.718193 39.195873,-90.732338 39.224747,-90.738083 39.24781,-90.779343 39.296803,-90.850494 39.350452,-90.947891 39.400585,-91.036339 39.444412,-91.064384 39.473984,-91.093613 39.528927,-91.156189 39.552593,-91.203247 39.600021,-91.317665 39.685917,-91.367088 39.72464,-91.373421 39.761272,-91.381714 39.803772,-91.449188 39.863049,-91.450989 39.885242,-91.434052 39.901829,-91.430389 39.921837,-91.447243 39.946064,-91.487289 40.005753,-91.504005 40.066711,-91.516129 40.134544,-91.506546 40.200459,-91.498932 40.251377,-91.486694 40.309624,-91.448593 40.371902,-91.418816 40.386875,-91.385757 40.392361,-91.372757 40.402988,-91.385399 40.44725,-91.374794 40.503654,-91.382103 40.528496,-91.412872 40.547993,-91.411118 40.572971,-91.37561 40.603439,-91.262062 40.639545,-91.214912 40.643818,-91.162498 40.656311,-91.129158 40.682148,-91.119987 40.705402,-91.092751 40.761547,-91.088905 40.833729,-91.04921 40.879585,-90.983276 40.923927,-90.960709 40.950504,-90.954651 41.070362,-90.957787 41.104359,-90.990341 41.144371,-91.018257 41.165825,-91.05632 41.176258,-91.101524 41.231522,-91.102348 41.267818,-91.07328 41.334896,-91.055786 41.401379,-91.027489 41.423508,-91.000694 41.431084,-90.949654 41.421234,-90.844139 41.444622,-90.7799 41.449821,-90.708214 41.450062,-90.658791 41.462318,-90.6007 41.509586,-90.54084 41.52597,-90.454994 41.527546,-90.434967 41.543579,-90.423004 41.567272,-90.348366 41.586849,-90.339348 41.602798,-90.341133 41.64909,-90.326027 41.722736,-90.304886 41.756466,-90.25531 41.781738,-90.195839 41.806137,-90.154518 41.930775,-90.14267 41.983963,-90.150536 42.033428,-90.168098 42.061043,-90.166649 42.103745,-90.176086 42.120502,-90.191574 42.122688,-90.230934 42.159721,-90.323601 42.197319,-90.367729 42.210209,-90.407173 42.242645,-90.417984 42.263924,-90.427681 42.340633,-90.441597 42.360073,-90.491043 42.388783,-90.563583 42.421837,-90.605827 42.46056,-90.648346 42.475643,-90.651772 42.494698,-90.638329 42.509361,-90.419975 42.508362,-89.923569 42.504108,-89.834618 42.50346,-89.400497 42.49749,-89.359444 42.497906,-88.939079 42.490864,-88.764954 42.490906,-88.70652 42.489655,-88.297897 42.49197,-88.194702 42.489613,-87.79731 42.489132,-87.836945 42.314213,-87.760239 42.156456,-87.670547 42.059822,-87.612625 41.847332,-87.529861 41.723591,-87.532646 41.469715,-87.532448 41.301304,-87.531731 41.173756,-87.532021 41.00993,-87.532669 40.745411,-87.53717 40.49461,-87.535675 40.483246,-87.535339 40.166195,-87.535774 39.887302,-87.535576 39.609341,-87.538567 39.477448,-87.540215 39.350525,-87.597664 39.338268,-87.625237 39.307404,-87.610619 39.297661,-87.615799 39.281418,-87.606895 39.258163,-87.584564 39.248753,-87.588593 39.208466,-87.594208 39.198128,-87.607925 39.196068,-87.644257 39.168507,-87.670326 39.146679,-87.659454 39.130653,-87.662262 39.113468,-87.631668 39.103943,-87.630867 39.088974,-87.612007 39.084606,-87.58532 39.062435,-87.581749 38.995743,-87.591858 38.994083,-87.547905 38.977077,-87.53347 38.963703,-87.530182 38.931919,-87.5392 38.904861,-87.559059 38.869812,-87.550507 38.857891,-87.507889 38.795559,-87.519028 38.776699,-87.508003 38.769722,-87.508316 38.736633,-87.543892 38.685974,-87.588478 38.672169,-87.625191 38.642811,-87.628647 38.622917,-87.619827 38.599209,-87.640594 38.593178,-87.652855 38.573872,-87.672943 38.547424,-87.65139 38.515369,-87.653534 38.500443,-87.679909 38.504005,-87.692818 38.481533,-87.756096 38.466125,-87.758659 38.457096,-87.738953 38.44548,-87.748428 38.417965,-87.784019 38.378124,-87.834503 38.352524,-87.850082 38.286098,-87.863007 38.285362,-87.874039 38.316788,-87.883446 38.315552,-87.888466 38.300659,-87.914108 38.281048,-87.913651 38.302345,-87.925919 38.304771,-87.980019 38.241085,-87.986008 38.234814,-87.977928 38.200714,-87.932289 38.171131,-87.931992 38.157528,-87.950569 38.136913,-87.973503 38.13176,-88.018547 38.103302,-88.012329 38.092346,-87.964867 38.096748,-87.975296 38.073307,-88.034729 38.054085,-88.043091 38.04512,-88.041473 38.038303,-88.021698 38.033531,-88.029213 38.008236,-88.021706 37.975056,-88.042511 37.956264,-88.041771 37.934498,-88.064621 37.929783,-88.078941 37.944,-88.084 37.92366,-88.030441 37.917591,-88.026588 37.905758,-88.044868 37.896004,-88.100082 37.90617,-88.101456 37.895306,-88.075737 37.867809,-88.034241 37.843746,-88.042137 37.827522,-88.089264 37.831249,-88.086029 37.817612,-88.035576 37.805683,-88.072472 37.735401,-88.133636 37.700745,-88.15937 37.660686,-88.157631 37.628479,-88.134171 37.583572,-88.071564 37.51099)))\"\n        );\n        \n        // two calculations of the area (in square meters)\n        var planar = illinois.getArea() * Math.pow(OpenLayers.INCHES_PER_UNIT['dd'] / OpenLayers.INCHES_PER_UNIT['m'], 2);\n        var geodesic = illinois.getGeodesicArea();\n        \n        // from http://en.wikipedia.org/wiki/Illinois\n        var expected = 1.40998e11; // square meters\n        \n        var planarErr = Math.abs(planar - expected) / expected;\n        var geodesicErr = Math.abs(geodesic - expected) / expected;\n        \n        t.ok(geodesicErr < planarErr, \"geodesic measure is better (\" + geodesicErr.toFixed(3) + \" vs. \" + planarErr.toFixed(3) + \")\");\n        \n    }\n\n    function test_getCentroid(t) {\n        t.plan(5);\n        var bounds = new OpenLayers.Bounds(5, 10, 5, 10);\n        var geometry = bounds.toGeometry();\n        var centroid = geometry.getCentroid();\n        t.eq(geometry.components[0].components.length, 2, \"only two vertices since the box has left=right and bottom=top\");\n        t.ok(centroid && centroid.x === 5 && centroid.y === 10, \"getCentroid returns a point geometry even if the ring of the polygon has only 2 vertices\");\n        bounds = new OpenLayers.Bounds(123456789.0, 123456789.0, 123456789.1, 123456789.1);\n        geometry = bounds.toGeometry();\n        centroid = geometry.getCentroid();\n        t.eq(geometry.components[0].components.length, 5, \"five vertices expected\");\n        var dX = Math.abs(centroid.x - 123456789.05);\n        var dY = Math.abs(centroid.y - 123456789.05);\n        t.ok(centroid && dX < 0.0001 && dY < 0.0001, \" getCentroid returns the correct point geometry dX = \" + dX + \", dY = \" + dY);\n        \n        var components = [\n            new OpenLayers.Geometry.Point(0,0), new OpenLayers.Geometry.Point(1,1),\n            new OpenLayers.Geometry.Point(0,1), new OpenLayers.Geometry.Point(1,0)];\n        var linearRing = new OpenLayers.Geometry.LinearRing(components);\n        polygon = new OpenLayers.Geometry.Polygon([linearRing.clone()]);\n        centroid = polygon.getCentroid();\n        var tX = centroid.x;\n        var tY = centroid.y;\n        t.ok( !isNaN(tX) && !isNaN(tY) && tX !== Infinity && tY !== Infinity, \" getCentroid for wrong polygon works x = \" + tX + \", y = \" + tY);\n    }\n    \n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Geometry.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script src=\"data/geos_wkt_intersects.js\"></script>\n  <script type=\"text/javascript\">\n    var map; \n\n    function test_Geometry_constructor (t) {\n        t.plan( 2 );\n        \n        var g = new OpenLayers.Geometry();\n        \n        t.eq(g.CLASS_NAME, \"OpenLayers.Geometry\", \"correct CLASS_NAME\")\n        t.ok(OpenLayers.String.startsWith(g.id, \"OpenLayers_Geometry_\"),\n             \"id correctly set\");\n    }\n\n\n    function test_Geometry_clone(t) {\n        t.plan(2);\n        var geometry = new OpenLayers.Geometry();\n        var clone = geometry.clone();\n\n        t.eq(clone.CLASS_NAME, \"OpenLayers.Geometry\", \"correct CLASS_NAME\")\n        t.ok(OpenLayers.String.startsWith(clone.id, \"OpenLayers_Geometry_\"),\n             \"id correctly set\");\n    }\n\n    function test_Geometry_setBounds(t) {\n        t.plan( 2 );\n        \n        var g = new OpenLayers.Geometry();\n        \n      //null object\n        g.setBounds(null);\n        t.ok(g.bounds == null, \"setbounds with null value does not crash or set bounds\");\n      \n      //no classname object\n        g_clone = {};\n        var object = {\n            'clone': function() { return g_clone; }\n        };\n        g.setBounds(object);\n        t.ok(g.bounds == g_clone, \"setbounds with valid object sets bounds, calls clone\");\n    }\n\n    function test_Geometry_extendBounds(t) {\n        t.plan(9);\n        \n        OpenLayers.Bounds.prototype._extend = \n            OpenLayers.Bounds.prototype.extend;\n        OpenLayers.Bounds.prototype.extend = function(b) { \n            g_extendBounds = b; \n        };\n        \n        var g = new OpenLayers.Geometry();\n\n      //this.bounds null (calculateBounds(), setBounds() called)\n        g.setBounds = function(b) { g_setBounds = b; };\n        g.calculateBounds = function() { g_calculateBounds = {}; };\n        var object = {};\n        g_setBounds = null;\n        g_calculateBounds = null;\n        g_extendBounds = null;\n        g.extendBounds(object);\n        t.ok(g_calculateBounds != null, \"calculateBounds() called when this.bounds is null\");\n        t.ok(g_setBounds == object, \"setBounds() called when this.bounds is null and calculateBounds() is null too\");        \n        t.ok(g_extendBounds != object, \"this.bounds.extend() not called when this.bounds is null and calculateBounds() is null too\");\n        \n      //this.bounds null (calculateBounds() sets this.bounds:\n      //   -  setBounds() not called\n      //   -  this.bounds.extend() called\n        g_calcBounds = new OpenLayers.Bounds(1,2,3,4);\n        g.calculateBounds = function() { \n            g_calculateBounds = {}; \n            this.bounds = g_calcBounds; \n        };\n        var object = {};\n\n        g_setBounds = null;\n        g_calculateBounds = null;\n        g_extendBounds = null;\n        g.extendBounds(object);\n        t.ok(g_calculateBounds != null, \"calculateBounds() called when this.bounds is null\");\n        t.ok(g_setBounds == null, \"setBounds() not called when this.bounds is null and calculateBounds() sets this.bounds\");        \n        t.ok(g_extendBounds == object, \"this.bounds.extend() called when this.bounds is null and calculateBounds() sets this.bounds\");        \n\n        \n      //this.bounds non-null thus extend()\n      //   -  setBounds() not called\n      //   -  this.bounds.extend() called\n        g_setBounds = null;\n        g_calculateBounds = null;\n        g_extendBounds = null;\n        g.extendBounds(object);\n        t.ok(g_calculateBounds == null, \"calculateBounds() not called when this.bounds is non null\");\n        t.ok(g_setBounds == null, \"setBounds() not called when this.bounds is nonnull\");        \n        t.ok(g_extendBounds == object, \"this.bounds.extend() called when this.bounds is non-null\");        \n\n        OpenLayers.Bounds.prototype.extend = \n            OpenLayers.Bounds.prototype._extend;\n\n\n    }\n\n    function test_Geometry_getBounds(t) {\n        t.plan(1);\n        \n        var g = new OpenLayers.Geometry();\n        \n        var testBounds = new OpenLayers.Bounds(1,2,3,4);\n        g.bounds = testBounds.clone();\n        \n        t.ok(g.getBounds().equals(testBounds), \"getBounds works\");\n    }\n    \n    function test_Geometry_atPoint(t) {\n        t.plan(6);\n            \n        var g = new OpenLayers.Geometry();\n    \n        var lonlat = null;\n        var lon = 5;\n        var lat = 10;\n    \n      //null lonlat\n        g.bounds = new OpenLayers.Bounds();\n\n        var atPoint = g.atPoint(lonlat, lon, lat);\n        t.ok(!atPoint, \"null lonlat\")\n\n      //null this.bounds\n        g.bounds = null;\n        lonlat = new OpenLayers.LonLat(1,2);      \n      \n        atPoint = g.atPoint(lonlat, lon, lat);\n        t.ok(!atPoint, \"null this.bounds\")\n\n    //toleranceLon/toleranceLat\n\n      //default toleranceLon/toleranceLat\n        OpenLayers.Bounds.prototype._containsLonLat = OpenLayers.Bounds.prototype.containsLonLat;\n        g_Return = {};\n        OpenLayers.Bounds.prototype.containsLonLat = function(ll) {\n            g_bounds = this;\n            return g_Return;\n         }\n\n        var testBounds = new OpenLayers.Bounds(10,20,30,40);\n        g.bounds = testBounds.clone();\n        lonlat = new OpenLayers.LonLat(20,30);\n      \n        g_bounds = null;\n        atPoint = g.atPoint(lonlat);\n        t.ok(g_bounds.equals(testBounds), \"default toleranceLon/Lat are 0\");\n        t.ok(atPoint == g_Return, \"default toleranceLon/Lat returns correctly\");\n\n      //real toleranceLon/toleranceLat\n        var testBounds = new OpenLayers.Bounds(10,20,30,40);\n        g.bounds = testBounds.clone();\n        lonlat = new OpenLayers.LonLat(20,30);\n      \n        g_bounds = null;\n        atPoint = g.atPoint(lonlat, lon, lat);\n        testBounds.left -= lon;\n        testBounds.bottom -= lat;\n        testBounds.right += lon;\n        testBounds.top += lat;\n        t.ok(g_bounds.equals(testBounds), \"real toleranceLon/Lat are 0\");\n        t.ok(atPoint == g_Return, \"real toleranceLon/Lat returns correctly\");\n\n        OpenLayers.Bounds.prototype.containsLonLat = OpenLayers.Bounds.prototype._containsLonLat;\n    \n    }\n    \n    function test_Geometry_getLength(t) {\n        t.plan(1);\n        \n        var g = new OpenLayers.Geometry();\n        \n        t.eq(g.getLength(), 0, \"getLength is 0\");\n    }    \n\n    function test_Geometry_getArea(t) {\n        t.plan(1);\n        \n        var g = new OpenLayers.Geometry();\n        \n        t.eq(g.getArea(), 0, \"getArea is 0\");\n    }\n    \n    function test_Geometry_clearBounds(t) {\n        t.plan(2);\n        \n        var g = new OpenLayers.Geometry();\n        g.parent = new OpenLayers.Geometry();\n\n        g.bounds = \"foo\";\n        g.parent.bounds = \"bar\";\n        \n        g.clearBounds();\n        t.ok(g.bounds == null, \"bounds is correctly cleared\");\n        t.ok(g.parent.bounds == null, \"parent geometry bounds is correctly cleared\");\n    }\n\n    function test_Geometry_destroy(t) {\n        t.plan( 2 );\n\n        var g = new OpenLayers.Geometry();\n        g.bounds = new OpenLayers.Bounds();\n\n        g_style_destroy = null;\n        g.destroy();\n        \n        t.eq(g.id, null, \"id nullified\");\n\n        t.eq(g.bounds, null, \"bounds nullified\");\n\n    }\n\n    function test_Geometry_intersects_geos_wkt(t) {\n        var wkt = new OpenLayers.Format.WKT();\n        var failures = [];\n        var intersect12, intersect21, msg;\n        for (var i = 0; i < geos_test_data.length; i++) {\n            var testcase = geos_test_data[i];\n            f1 = wkt.read(testcase['wkt1']);\n            f2 = wkt.read(testcase['wkt2']);\n            intersect12 = f1.geometry.intersects(f2.geometry);\n            intersect21 = f2.geometry.intersects(f1.geometry);\n            if(intersect12 != testcase.result) {\n                msg = \"f1 should \" + (testcase.result ? \"\" : \"not \") +\n                      \"intersect f2: f1 = '\" + testcase['wkt1'] + \"' \" +\n                      \"f2 = '\" + testcase['wkt2'] + \"'\";\n                failures.push(msg);\n            }\n            if(intersect21 != testcase.result) {\n                msg = \"f2 should \" + (testcase.result ? \"\" : \"not \") +\n                      \"intersect f1: f1 = '\" + testcase['wkt1'] + \"' \" +\n                      \"f2 = '\" + testcase['wkt2'] + \"'\";\n                failures.push(msg);\n            }\n        }\n        if(failures.length == 0) {\n            t.plan(1);\n            t.ok(true, \"all \" + geos_test_data.length + \" geos tests pass\");\n        } else {\n            t.plan(failures.length);\n            for(var f=0; f<failures.length; ++f) {\n                t.fail(failures[f]);\n            }\n        }\n    }\n    \n    function test_distanceToSegment(t) {\n        var dist = OpenLayers.Geometry.distanceToSegment;\n\n        var cases = [{\n            got: dist({x: 0, y: 0}, {x1: 0, y1: 1, x2: 1, y2: 1}),\n            expected: {distance: 1, x: 0, y: 1, along: 0}\n        }, {\n            got: dist({x: 0, y: 0}, {x1: -1, y1: -1, x2: 0, y2: -1}),\n            expected: {distance: 1, x: 0, y: -1, along: 1}\n        }, {\n            got: dist({x: 0, y: 0}, {x1: -1, y1: -1, x2: 1, y2: 1}),\n            expected: {distance: 0, x: 0, y: 0, along: 0.5}\n        }, {\n            got: dist({x: 1, y: 1}, {x1: 2, y1: 0, x2: 2, y2: 3}),\n            expected: {distance: 1, x: 2, y: 1, along: 1/3.}\n        }, {\n            got: dist({x: -1, y: -1}, {x1: -2, y1: -2, x2: -1, y2: -3}),\n            expected: {distance: Math.sqrt(2), x: -2, y: -2, along: 0}\n        }, {\n            got: dist({x: -1, y: 1}, {x1: -3, y1: 1, x2: -1, y2: 3}),\n            expected: {distance: Math.sqrt(2), x: -2, y: 2, along: 0.5}\n        }, {\n            got: dist({x: -89.188002586365, y: 14.656255960464}, {x1: -89.187315940857, x2: -89.187315940857, y1: 14.656255960464, y2: 14.656255960464}),\n            expected: {distance: 0.0006866455079972411, x: -89.187315940857, y: 14.656255960464, along: 0}\n        }];\n        t.plan(cases.length);\n        for(var i=0; i<cases.length; ++i) {\n            t.eq(cases[i].got, cases[i].expected, \"case \" + i);\n        }\n        \n    }\n\n    function test_fromWKT(t) {\n        \n        var cases = [{\n            wkt: \"POINT(1 2)\",\n            geom: new OpenLayers.Geometry.Point(1, 2)\n        }, {\n            wkt: \"MULTIPOINT((3.5 5.6),(4.8 10.5))\",\n            geom: new OpenLayers.Geometry.MultiPoint([\n                new OpenLayers.Geometry.Point(3.5, 5.6),\n                new OpenLayers.Geometry.Point(4.8, 10.5)\n            ])\n        }, {\n            wkt: \"LINESTRING(1 2, 3 4)\",\n            geom: new OpenLayers.Geometry.LineString([\n                new OpenLayers.Geometry.Point(1, 2),\n                new OpenLayers.Geometry.Point(3, 4)\n            ])\n        }, {\n            wkt: \"POLYGON((0 0, 0 4, 4 4, 4 0, 0 0),(1 1, 1 3, 3 3, 3 1, 1 1))\",\n            geom: new OpenLayers.Geometry.Polygon([\n                new OpenLayers.Geometry.LinearRing([\n                    new OpenLayers.Geometry.Point(0, 0),\n                    new OpenLayers.Geometry.Point(0, 4),\n                    new OpenLayers.Geometry.Point(4, 4),\n                    new OpenLayers.Geometry.Point(4, 0),\n                    new OpenLayers.Geometry.Point(0, 0)\n                ]),\n                new OpenLayers.Geometry.LinearRing([\n                    new OpenLayers.Geometry.Point(1, 1),\n                    new OpenLayers.Geometry.Point(1, 3),\n                    new OpenLayers.Geometry.Point(3, 3),\n                    new OpenLayers.Geometry.Point(3, 1),\n                    new OpenLayers.Geometry.Point(1, 1)\n                ])\n            ])\n        }, {\n            wkt: \"GEOMETRYCOLLECTION(POINT(4 6),LINESTRING(4 6,7 10))\",\n            geom: new OpenLayers.Geometry.Collection([\n                new OpenLayers.Geometry.Point(4, 6),\n                new OpenLayers.Geometry.LineString([\n                    new OpenLayers.Geometry.Point(4, 6),\n                    new OpenLayers.Geometry.Point(7, 10)\n                ])\n            ])\n        }];\n        \n        t.plan(cases.length);\n        var wkt = OpenLayers.Geometry.fromWKT;\n        for(var i=0; i<cases.length; ++i) {\n            t.geom_eq(wkt(cases[i].wkt), cases[i].geom, \"case \" + i);\n        }\n    }\n    \n    function test_fromWKT_undefined(t) {\n        t.plan(1);\n        \n        var WKT = OpenLayers.Format.WKT;\n        OpenLayers.Format.WKT = null;\n        delete OpenLayers.Geometry.fromWKT.format;\n        \n        var geom = OpenLayers.Geometry.fromWKT(\"POINT(1 1)\");\n        t.eq(geom, undefined, \"undefined when OpenLayers.Format.WKT is not available\");\n        \n        OpenLayers.Format.WKT = WKT;\n    }\n\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Handler/Box.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    function test_Handler_Box_constructor(t) {\n        t.plan(5);\n        var control = new OpenLayers.Control();\n        control.id = Math.random();\n        var callbacks = {start: \"foo\", done: \"bar\"};\n        var options = {bar: \"foo\"};\n        \n        var handler = new OpenLayers.Handler.Box(control, callbacks, options);\n\n        t.eq(handler.control.id, control.id, \"handler created with the correct control\");\n        t.eq(handler.callbacks.start, \"foo\", \"handler created with the correct start callback\");\n        t.eq(handler.callbacks.done, \"bar\", \"handler created with the correct done callback\");\n        t.eq(handler.bar, \"foo\", \"handler created with the correct options\");\n        t.ok(handler.dragHandler instanceof OpenLayers.Handler.Drag, \"drag handler created\");\n    }\n\n    function test_Handler_Box_draw(t) {\n\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Box(control, {\n            start: function(e) {\n                t.ok(true, \"start callback called\");\n            },\n            done: function(e) {\n                t.ok(e.equals(new OpenLayers.Bounds(5, 11, 11, 5)), \"box result correct\");\n            }\n        });\n        handler.activate();\n\n        // determine whether we can test the box position, the hidden frame\n        // our tests run in causes us problem here in FF and IE:\n        // IE8: left is NaN\n        // FF3: left is NaN\n        // FF4; left is NaN\n        // Chromium 10: left is 0\n        var testdiv = OpenLayers.Util.createDiv('testdiv', new OpenLayers.Pixel(5, 5));\n        map.div.appendChild(testdiv);\n        var left = parseInt(OpenLayers.Element.getStyle(testdiv, 'border-left-width'));\n        map.div.removeChild(testdiv);\n        var testAll = !isNaN(left);\n\n        t.plan(testAll ? 11 : 3);\n\n        // we change NaN values to 0 values in the handler's\n        // boxOffsets object, this is to prevent \"invalid\n        // \"argument\" errors in IE\n        if(!testAll) {\n            var offset = handler.getBoxOffsets();\n            offset.left = 0;\n            offset.right = 0;\n            offset.top = 0;\n            offset.bottom = 0;\n            offset.width = 0;\n            offset.height = 0;\n        }\n\n\n        handler.dragHandler.start = {x: 5, y: 5};\n        handler.startBox();\n        offset = handler.getBoxOffsets();\n        handler.moveBox({x: 10, y: 10});\n        if (testAll) {\n            t.eq(parseInt(handler.zoomBox.style.left), 5 - offset.left, \"x position of box correct\");\n            t.eq(parseInt(handler.zoomBox.style.top), 5 - offset.top, \"y position of box correct\");\n            t.eq(parseInt(handler.zoomBox.style.width), 5 + offset.width + 1, \"x dimension of box correct\");\n            t.eq(parseInt(handler.zoomBox.style.height), 5 + offset.height + 1, \"y dimension of box correct\");\n        }\n        handler.moveBox({x: 0, y: 0});\n        if (testAll) {\n            t.eq(parseInt(handler.zoomBox.style.left), 0 - offset.left, \"new x position of box correct\");\n            t.eq(parseInt(handler.zoomBox.style.top), 0 - offset.top, \"new y position of box correct\");\n            t.eq(parseInt(handler.zoomBox.style.width), 5 + offset.width + 1, \"x dimension of box still correct\");\n            t.eq(parseInt(handler.zoomBox.style.height), 5 + offset.height + 1, \"y dimension of box still correct\");\n        }\n        handler.endBox({x: 11, y: 11});\n        t.eq(handler.zoomBox, null, \"box removed after endBox\");\n    }\n    \n    function test_Handler_Box_destroy(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Box(control);\n        handler.activate();\n        try {\n            handler.destroy();\n            t.ok(true, \"destroying the box handler should not raise any error\");\n        } catch(err) {\n            t.fail(\"destroying the box handler causes trouble: \" + err);\n        }\n        map.destroy();\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 300px; height: 150px;\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Handler/Click.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n  \n    function px(x, y) {\n        return new OpenLayers.Pixel(x, y);\n    }\n  \n    function test_Handler_Click_constructor(t) {\n        t.plan(3);\n        var control = new OpenLayers.Control();\n        control.id = Math.random();\n        var callbacks = {foo: \"bar\"};\n        var options = {bar: \"foo\"};\n        \n        var oldInit = OpenLayers.Handler.prototype.initialize;\n        \n        OpenLayers.Handler.prototype.initialize = function(con, call, opt) {\n            t.eq(con.id, control.id,\n                 \"constructor calls parent with the correct control\");\n            t.eq(call, callbacks,\n                 \"constructor calls parent with the correct callbacks\");\n            t.eq(opt, options,\n                 \"constructor calls parent with the correct options\");\n        }\n        var handler = new OpenLayers.Handler.Click(control, callbacks, options);\n\n        OpenLayers.Handler.prototype.initialize = oldInit;\n    }\n\n    function test_Handler_Click_activate(t) {\n        t.plan(2);\n        var control = {\n            map: new OpenLayers.Map('map')\n        };\n        var handler = new OpenLayers.Handler.Click(control);\n        handler.active = true;\n        var activated = handler.activate();\n        t.ok(!activated,\n             \"activate returns false if the handler was already active\");\n        handler.active = false;\n        handler.dragging = true;\n        activated = handler.activate();\n        t.ok(activated,\n             \"activate returns true if the handler was not already active\");\n        \n    }\n    \n    function test_Handler_Click_events(t) {\n        t.plan(80);\n        \n        var map = new OpenLayers.Map('map');\n        var control = {\n            map: map\n        };\n        map.events.registerPriority = function(type, obj, func) {\n            var f = OpenLayers.Function.bind(func, obj)\n            var r = f({xy:null});\n            if(typeof r == \"string\") {\n                // this is one of the mock handler methods\n                t.eq(OpenLayers.Util.indexOf(nonevents, type), -1,\n                     \"registered method is not one of the events \" +\n                     \"that should not be handled\");\n                t.ok(OpenLayers.Util.indexOf(events, type) > -1,\n                     \"activate calls registerPriority with browser event: \" + type);\n                t.eq(typeof func, \"function\",\n                     \"activate calls registerPriority with a function\");\n                t.eq(func(), type,\n                     \"activate calls registerPriority with the correct method\");\n                t.eq(obj[\"CLASS_NAME\"], \"OpenLayers.Handler.Click\",\n                     \"activate calls registerPriority with the handler\");\n            }\n        }\n        function setMethod(key) {\n            handler[key] = function() {return key};\n        }\n\n        // list below events that should be handled (events) and those\n        // that should not be handled (nonevents) by the handler\n        var events = [\"click\", \"dblclick\", \"mousedown\", \"mouseup\", \"rightclick\", \"touchstart\", \"touchmove\", \"touchend\"];\n        var nonevents = [\"mousemove\", \"resize\", \"focus\", \"blur\"];\n        var handler = new OpenLayers.Handler.Click(control);\n        // set browser event like properties on the handler\n        for(var i=0; i<events.length; ++i) {\n            setMethod(events[i]);\n        }\n        handler.activate();\n\n        // different listeners registered for pixelTolerance option\n        var events = [\"click\", \"dblclick\", \"mousedown\", \"mouseup\", \"rightclick\", \"touchstart\", \"touchmove\", \"touchend\"];\n        var nonevents = [\"mousemove\", \"resize\", \"focus\", \"blur\"];\n        var handler = new OpenLayers.Handler.Click(control, {}, {\n            pixelTolerance: 2\n        });\n        for(var i=0; i<events.length; ++i) {\n            setMethod(events[i]);\n        }\n        handler.activate();\n\n    }\n    \n    var callbackMap;\n    function callbackSetup(log, options) {\n        callbackMap = new OpenLayers.Map({\n            div: \"map\",\n            controls: [], // no controls here because these tests use a custom setTimeout and we only want setTimeout calls from a single handler \n            layers: [new OpenLayers.Layer(null, {isBaseLayer: true})],\n            center: new OpenLayers.LonLat(0, 0),\n            zoom: 1\n        });\n        var control = new OpenLayers.Control();\n        callbackMap.addControl(control);\n\n        var callbacks = {\n            \"click\": function(evt) {\n                log.push({callback: \"click\", evt: evt});\n            },\n            \"dblclick\": function(evt) {\n                log.push({callback: \"dblclick\", evt: evt});\n            }\n        };\n        var handler = new OpenLayers.Handler.Click(control, callbacks, options);\n        handler.activate();\n        \n        \n        var timers = {};\n        window._setTimeout = window.setTimeout;\n        window.setTimeout = function(func, delay) {\n            log.push({method: \"setTimeout\", func: func, delay: delay});\n            var key = (new Date).getTime() + \"-\" + Math.random();\n            timers[key] = true;\n            // execute function that is supposed to be delayed\n            func();\n            return key;\n        }\n        window._clearTimeout = window.clearTimeout;\n        window.clearTimeout = function(key) {\n            log.push({\n                method: \"clearTimeout\",\n                keyExists: (key in timers)\n            });\n            delete timers[key];\n        }\n        return handler;    \n    }\n    \n    function callbackTeardown() {\n        window.setTimeout = window._setTimeout;\n        window.clearTimeout = window._clearTimeout;\n        callbackMap.destroy();\n        callbackMap = null;\n    }\n\n    function test_callbacks_click_default(t) {\n        t.plan(6);\n\n        var log = [];\n        var handler = callbackSetup(log);\n        \n        // set up for single click - three tests here\n        var testEvt = {id: Math.random()};\n        handler.map.events.triggerEvent(\"click\", testEvt);\n        t.eq(log.length, 2, \"(click w/ single true) two items logged\");\n\n        // first item logged is setTimeout call\n        t.eq(log[0].method, \"setTimeout\", \"setTimeout called\");\n        t.eq(typeof log[0].func, \"function\", \"setTimeout called with a function\");\n        t.eq(log[0].delay, handler.delay, \"setTimeout called with proper delay\");\n        \n        // second item logged is from click callback\n        t.eq(log[1].callback, \"click\", \"click callback called\");\n        t.eq(log[1].evt.id, testEvt.id, \"got correct event\");\n        \n        callbackTeardown();\n    }\n    \n    function test_callbacks_dblclick_default(t) {\n        t.plan(1);\n\n        var log = [];\n        var handler = callbackSetup(log);\n        var testEvt = {id: Math.random()};\n        handler.map.events.triggerEvent(\"dblclick\", testEvt);\n        \n        t.eq(log.length, 0, \"nothing happens by default with dblclick (double is false)\");\n        \n        callbackTeardown();\n        \n    }\n\n    function test_callbacks_dblclick_double(t) {\n        t.plan(3);\n\n        var log = [];\n        var handler = callbackSetup(log, {\"double\": true});\n        var testEvt = {id: Math.random()};\n        handler.map.events.triggerEvent(\"dblclick\", testEvt);\n        \n        t.eq(log.length, 1, \"one item logged\");\n        t.eq(log[0].callback, \"dblclick\", \"dblclick callback called\")\n        t.eq(log[0].evt.id, testEvt.id, \"dblclick callback called with event\");\n        \n        callbackTeardown();\n        \n    }\n\n    function test_callbacks_dblclick_sequence(t) {\n        t.plan(8);\n\n        var log = [];\n        var handler = callbackSetup(log, {\"double\": true});\n        var testEvt = {id: Math.random()};\n\n        // first click - set timer for next\n        handler.map.events.triggerEvent(\"click\", testEvt);\n        t.ok(handler.timerId != null, \"timer is set\");\n        log.pop(); // because the test setTimeout is synchronous we get the click callback immediately\n        t.eq(log.length, 1, \"one item logged (after pop due to synchronous setTimeout call in our tests\");\n        t.eq(log[0].method, \"setTimeout\", \"setTimeout called first\");\n\n        // second click - timer cleared\n        handler.map.events.triggerEvent(\"click\", testEvt);\n        t.ok(handler.timerId == null, \"timer is cleared\");\n        t.eq(log.length, 2, \"two items logged after second click\");\n        t.eq(log[1].method, \"clearTimeout\", \"clearTimeout called second\");\n\n        // dblclick event - callback called\n        handler.map.events.triggerEvent(\"dblclick\", testEvt);        \n        t.eq(log.length, 3, \"three items logged\");\n        t.eq(log[2].callback, \"dblclick\", \"dblclick callback called third\");\n        \n        callbackTeardown();\n        \n    }\n\n    function test_callbacks_within_pixelTolerance(t) {\n        t.plan(1);\n\n        var log = [];\n        var handler = callbackSetup(log, {\"double\": true, pixelTolerance: 2});\n\n        var down = {\n            xy: px(0, 0)\n        };\n        var up = {\n            xy: px(0, 1)\n        };\n\n        handler.map.events.triggerEvent(\"mousedown\", down);\n        handler.map.events.triggerEvent(\"mouseup\", up);\n        handler.map.events.triggerEvent(\"click\", up);\n        \n        t.eq(log[log.length-1].callback, \"click\", \"click callback called\");\n        \n        callbackTeardown();\n        \n    }\n\n    function test_callbacks_outside_pixelTolerance(t) {\n        t.plan(2);\n\n        var log = [];\n        var handler = callbackSetup(log, {pixelTolerance: 2});\n\n        var down = {\n            xy: px(0, 0)\n        };\n        var up = {\n            xy: px(2, 3)\n        };\n\n        handler.map.events.triggerEvent(\"mousedown\", down);\n        t.ok(handler.down && handler.down.xy.equals(down.xy), \"down position set\");\n\n        handler.map.events.triggerEvent(\"mouseup\", up);\n        handler.map.events.triggerEvent(\"click\", up);\n        t.eq(log.length, 0, \"nothing logged - event outside tolerance\");\n        \n        callbackTeardown();\n        \n    }\n\n    function test_callbacks_within_dblclickTolerance(t) {\n        t.plan(6);\n\n        var log = [];\n        var handler = callbackSetup(log, {single: false, \"double\": true, dblclickTolerance: 8});\n\n        var first = {\n            xy: px(0, 0)\n        };\n        var second = {\n            xy: px(0, 5)\n        };\n\n        handler.map.events.triggerEvent(\"mousedown\", first);\n        handler.map.events.triggerEvent(\"mouseup\", first);\n        handler.map.events.triggerEvent(\"click\", first);\n        t.eq(log.length, 1, \"one item logged\");\n        t.eq(log[0] && log[0].method, \"setTimeout\", \"setTimeout called\");\n        \n        handler.map.events.triggerEvent(\"mousedown\", second);\n        handler.map.events.triggerEvent(\"mouseup\", second);\n        handler.map.events.triggerEvent(\"click\", second);\n        t.eq(log.length, 2, \"two events logged\");\n        t.eq(log[1] && log[1].method, \"clearTimeout\", \"clearTimeout called\");\n        \n        handler.map.events.triggerEvent(\"dblclick\", second);\n        t.eq(log.length, 3, \"three items logged\");\n        t.eq(log[2] && log[2].callback, \"dblclick\", \"dblclick callback called\");\n        \n        callbackTeardown();        \n    }\n\n    function test_callbacks_outside_dblclickTolerance(t) {\n        t.plan(5);\n\n        var log = [];\n        // default dblclickTolerance is 13\n        var handler = callbackSetup(log, {single: false, \"double\": true});\n\n        var first = {\n            xy: px(0, 0)\n        };\n        var second = {\n            xy: px(13.5, 0)\n        };\n\n        handler.map.events.triggerEvent(\"mousedown\", first);\n        handler.map.events.triggerEvent(\"mouseup\", first);\n        handler.map.events.triggerEvent(\"click\", first);\n        t.eq(log.length, 1, \"one item logged\");\n        t.eq(log[0] && log[0].method, \"setTimeout\", \"setTimeout called\");\n\n        handler.map.events.triggerEvent(\"mousedown\", second);\n        handler.map.events.triggerEvent(\"mouseup\", second);\n        handler.map.events.triggerEvent(\"click\", second);\n        t.eq(log.length, 2, \"two items logged\");\n        t.eq(log[1] && log[1].method, \"clearTimeout\", \"clearTimeout called\");\n\n        handler.map.events.triggerEvent(\"dblclick\", second);\n        t.eq(log.length, 2, \"still two items logged - dblclick callback is not called\");\n        \n        callbackTeardown();\n    }\n\n    function test_callbacks_multitouch_single(t) {\n\n        t.plan(2);\n\n        var log = [];\n\n        var callbacks = {\n            click: function(evt) {\n                log.push({callback: \"click\", type: evt.type});\n            },\n            dblclick: function(evt) {\n                log.push({callback: \"dblclick\", type: evt.type});\n            }\n        };\n\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer(null, {isBaseLayer: true});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 1);\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Click(\n            control, callbacks,\n            {\"double\": true, single: true, pixelTolerance: 2}\n        );\n\n        // we override here so we don't have to wait for the timeout\n        handler.queuePotentialClick = function(evt) {\n            log.push({potential: true, evt: evt});\n            OpenLayers.Handler.Click.prototype.queuePotentialClick.call(this, evt);\n        }\n        \n        handler.activate();\n        \n        function handle(o) {\n            var touches = [];\n            if ((\"x0\" in o) && (\"y0\" in o)) {\n                touches.push({\n                    clientX: o.x0, clientY: o.y0\n                });\n            }\n            if ((\"x1\" in o) && (\"y1\" in o)) {\n                touches.push({\n                    clientX: o.x1, clientY: o.y1\n                });\n            }\n            handler.map.events.handleBrowserEvent({\n                type: o.type, touches: touches\n            });\n        }\n\n        // a typical multitouch sequence goes like this:\n        // touchstart, touchstart, touchend, touchend\n        handle({type: \"touchstart\", x0: 10, y0: 10});\n        handle({type: \"touchstart\", x0: 10, y0: 10, x1: 30, y1: 15});\n        handle({type: \"touchend\"});\n        handle({type: \"touchend\"});\n        \n        t.eq(log.length, 1, \"one item logged\");\n        t.eq(log[0] && log[0].potential, true, \"click in queue - no dblclick called\");\n        \n        map.destroy();\n    }\n\n    function test_Handler_Click_deactivate(t) {\n        t.plan(6);\n        var control = {\n            map: new OpenLayers.Map('map')\n        };\n        var handler = new OpenLayers.Handler.Click(control);\n        handler.active = false;\n        var deactivated = handler.deactivate();\n        t.ok(!deactivated,\n             \"deactivate returns false if the handler was not already active\");\n        handler.active = true;\n        handler.down = true;\n        handler.timerId = true;\n        handler.touch = true;\n        handler.last = true;\n        deactivated = handler.deactivate();\n        t.ok(deactivated,\n             \"deactivate returns true if the handler was active already\");\n        t.eq(handler.down, null,\n             \"deactivate sets down to null\");\n        t.eq(handler.timerId, null,\n             \"deactivate sets timerId to null\");\n        t.eq(handler.touch, false,\n             \"deactivate sets touch to false\");\n        t.eq(handler.last, null,\n            \"deactivate sets last to null\");\n\n    }\n\n    function test_Handler_Click_mouseup(t) {\n        t.plan(11);\n\n        var map = new OpenLayers.Map(\"map\");\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Click(control);\n\n        var testEvent = {id: Math.random()};\n        var propagate = true;\n        var log, got, modMatch, rightClick;\n\n        // override methods to log what is called\n        var temp = OpenLayers.Event.isRightClick;\n        OpenLayers.Event.isRightClick = function(e) { \n            log.push({method: \"isRightClick\", evt: e});\n            return rightClick; \n        };\n        handler.checkModifiers = function(e) {\n            log.push({method: \"checkModifiers\", evt: e});\n            return modMatch;\n        };\n        handler.rightclick = function(e) {\n            log.push({method: \"rightclick\", evt: e});\n            return propagate;\n        };\n\n        \n        // simulate an event with non-matching modifiers\n        log = [];\n        modMatch = false;\n        rightClick = false;\n        got = handler.mouseup(testEvent);\n        t.eq(log.length, 1, \"one item logged\");\n        t.eq(log[0] && log[0].method, \"checkModifiers\", \"a) checkModifiers called first\");\n        t.eq(log[0] && log[0].evt, testEvent, \"a) first method called with correct event\");\n\n\n        // modifiers, handlerightclicks, and isrightclick\n        log = [];\n        rightClick = true;\n        modMatch = true;\n        handler.control.handleRightClicks = true;\n        got = handler.mouseup(testEvent);\n        t.eq(log.length, 3, \"three items logged\");\n        t.eq(log[0] && log[0].method, \"checkModifiers\", \"b) checkModifiers called first\");\n        t.eq(log[0] && log[0].evt, testEvent, \"b) first method called with correct event\");\n        t.eq(log[1] && log[1].method, \"isRightClick\", \"b) isRightClick called second\");\n        t.eq(log[1] && log[1].evt, testEvent, \"b) second method called with correct event\");\n        t.eq(log[2] && log[2].method, \"rightclick\", \"b) rightclick called third\");\n        t.eq(log[2] && log[2].evt, testEvent, \"b) third method called with correct event\");\n        t.eq(got, propagate, \"b) return from handler's rightclick returned from mouseup\");\n\n        OpenLayers.Event.isRightClick = temp;\n        map.destroy();\n    }\n\n    function test_touch_click(t) {\n        t.plan(5);\n\n        // set up\n\n        var log;\n\n        var map = new OpenLayers.Map('map');\n        var control = {map: map};\n\n        var callbacks = {\n            'click': function(e) {\n                log = {x: e.xy.x, y: e.xy.y,\n                       lastTouches: e.lastTouches};\n            }\n        };\n\n        var handler = new OpenLayers.Handler.Click(\n                control, callbacks,\n                {'single': true, pixelTolerance: null});\n\n        // test\n\n        // the common case: a touchstart followed by a touchend\n        log = null;\n        handler.touchstart({xy: px(1, 1), touches: [\"foo\"]});\n        handler.touchend({touches: [\"foo\"]});\n\n        t.delay_call(1, function() {\n            t.ok(log != null, \"click callback called\");\n            if(log != null) {\n                t.eq(log.x, 1, \"evt.xy.x as expected\");\n                t.eq(log.y, 1, \"evt.xy.y as expected\");\n                t.ok(log.lastTouches, \"evt.lastTouches as expected\");\n            }\n\n            // now emulate a touch where touchstart doesn't propagate\n            // to the click handler, i.e. the click handler gets a\n            // touchend only\n            log = null;\n            handler.touchend({touches: [\"foo\"]});\n\n            t.delay_call(1, function() {\n                t.ok(log == null, \"click callback not called\");\n\n                // tear down\n                map.destroy();\n            });\n        });\n    }\n\n    function test_touch_within_dblclickTolerance(t) {\n        t.plan(4);\n\n        var log;\n\n        var callbacks = {\n            click: function(evt) {\n                log.push({callback: \"click\", type: evt.type});\n            },\n            dblclick: function(evt) {\n                log.push({callback: \"dblclick\", type: evt.type});\n            }\n        };\n\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer(null, {isBaseLayer: true});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 1);\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Click(\n            control, callbacks,\n            {\"double\": true, single: true, pixelTolerance: 2}\n        );\n        handler.activate();\n        \n        function handle(type, x, y) {\n            map.events.handleBrowserEvent({\n                type: type,\n                touches: [\n                    {clientX: x, clientY: y}\n                ]\n            });\n        }\n\n        // test\n        log = [];\n        // sequence of two clicks on a touch device\n        // click 1\n        handle(\"touchstart\", 10, 10);\n        handle(\"touchend\", 11, 10);\n        handle(\"mousemove\", 11, 10);\n        handle(\"mousedown\", 10, 10);\n        handle(\"mouseup\", 11, 10);\n        handle(\"click\", 11, 10);\n        // click 2\n        handle(\"touchstart\", 12, 10);\n        handle(\"touchend\", 12, 10);\n        handle(\"mousedown\", 12, 10);\n        handle(\"mouseup\", 12, 10);\n        handle(\"click\", 12, 10);\n\n        t.eq(log.length, 1, \"one callback called\");\n        t.eq(log[0] && log[0].callback, \"dblclick\", \"click callback called\");\n        t.eq(log[0] && log[0].type, \"touchend\", \"click callback called with touchend event\");\n        t.ok(!handler.timerId, \"handler doesn't have a timerId waiting for click\")\n\n        // tear down\n        map.destroy();\n    }\n\n    function test_touch_outside_dblclickTolerance(t) {\n        t.plan(2);\n\n        var log;\n\n        var callbacks = {\n            click: function(evt) {\n                log.push({callback: \"click\", type: evt.type});\n            },\n            dblclick: function(evt) {\n                log.push({callback: \"dblclick\", type: evt.type});\n            }\n        };\n\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer(null, {isBaseLayer: true});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 1);\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Click(\n            control, callbacks,\n            {\"double\": true, single: true, pixelTolerance: 2, dblclickTolerance: 8}\n        );\n        handler.activate();\n        \n        function handle(type, x, y) {\n            var touches = [];\n            if (x !== undefined && y !== undefined) {\n                touches.push({\n                    clientX: x, clientY: y\n                });\n            }\n            map.events.handleBrowserEvent({\n                type: type, touches: touches\n            });\n        }\n\n        // test\n        log = [];\n        // sequence of two clicks on a touch device\n        // click 1\n        handle(\"touchstart\", 10, 10);\n        handle(\"touchend\");\n        handle(\"mousemove\", 11, 10);\n        handle(\"mousedown\", 10, 10);\n        handle(\"mouseup\", 11, 10);\n        handle(\"click\", 11, 10);\n        // click 2\n        handle(\"touchstart\", 20, 10);\n        handle(\"touchend\");\n        handle(\"mousedown\", 20, 10);\n        handle(\"mouseup\", 20, 10);\n        handle(\"click\", 20, 10);\n\n        t.eq(log.length, 0, \"no callbacks called\");\n        t.ok(!handler.timerId, \"handler doesn't have a timerId waiting for click\")\n\n        // tear down\n        map.destroy();\n    }\n\n    function test_touchstart(t) {\n        // a test to verify that the touchstart function does\n        // unregister the mouse listeners when it's called the\n        // first time\n\n        t.plan(7);\n\n        // set up\n\n        var map = new OpenLayers.Map(\"map\", {\n            controls: []\n        });\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Click(control, {});\n        control.handler = handler;\n        map.addControl(control);\n        handler.activate();\n\n        function allRegistered() {\n            var eventTypes = ['mousedown', 'mouseup', 'click', 'dblclick'],\n                eventType,\n                listeners,\n                listener,\n                flag;\n            for(var i=0, ilen=eventTypes.length; i<ilen; i++) {\n                flag =  false;\n                eventType = eventTypes[i];\n                listeners = map.events.listeners[eventType];\n                for(var j=0, jlen=listeners.length; j<jlen; j++) {\n                    listener = listeners[j];\n                    if(listener.func === handler[eventType] && listener.obj === handler) {\n                        flag = true;\n                        break;\n                    }\n                }\n                if(!flag) {\n                    return false;\n                }\n            }\n            return true;\n        }\n\n        // test\n\n        t.ok(allRegistered(), 'mouse listeners are registered');\n        handler.touchstart({xy: new OpenLayers.Pixel(0, 0)});\n        t.eq(map.events.listeners.mousedown.length, 0,\"mousedown is not registered\");\n        t.eq(map.events.listeners.mouseup.length, 0,\"mouseup is not registered\");\n        t.eq(map.events.listeners.click.length, 0,\"click is not registered\");\n        t.eq(map.events.listeners.dblclick.length, 0,\"dblclick is not registered\");\n\n        t.ok(handler.touch, 'handler.touch is set');\n\n        handler.deactivate();\n        t.ok(!handler.touch, 'handler.touch is not set');\n\n        map.destroy();\n    }\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 300px; height: 150px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Handler/Drag.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    function test_Handler_Drag_constructor(t) {\n        t.plan(3);\n        var control = new OpenLayers.Control();\n        control.id = Math.random();\n        var callbacks = {foo: \"bar\"};\n        var options = {bar: \"foo\"};\n        \n        var oldInit = OpenLayers.Handler.prototype.initialize;\n        \n        OpenLayers.Handler.prototype.initialize = function(con, call, opt) {\n            t.eq(con.id, control.id,\n                 \"constructor calls parent with the correct control\");\n            t.eq(call, callbacks,\n                 \"constructor calls parent with the correct callbacks\");\n            t.eq(opt, options,\n                 \"constructor calls parent with the correct options\");\n        }\n        var handler = new OpenLayers.Handler.Drag(control, callbacks, options);\n\n        OpenLayers.Handler.prototype.initialize = oldInit;\n    }\n\n    function test_Handler_Drag_activate(t) {\n        t.plan(3);\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Drag(control);\n        handler.active = true;\n        var activated = handler.activate();\n        t.ok(!activated,\n             \"activate returns false if the handler was already active\");\n        handler.active = false;\n        handler.dragging = true;\n        activated = handler.activate();\n        t.ok(activated,\n             \"activate returns true if the handler was not already active\");\n        t.ok(!handler.dragging,\n             \"activate sets dragging to false\");\n        \n    }\n    \n    function test_Handler_Drag_events(t) {\n        t.plan(40);\n        \n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Drag(control);\n\n        // list below events that should be handled (events) and those\n        // that should not be handled (nonevents) by the handler\n        var events = [\"mousedown\", \"mouseup\", \"mousemove\", \"mouseout\", \"click\",\n                      \"touchstart\", \"touchmove\", \"touchend\"];\n        var nonevents = [\"dblclick\", \"resize\", \"focus\", \"blur\"];\n        map.events.registerPriority = function(type, obj, func) {\n            var r = func();\n            if(typeof r == \"string\") {\n                // this is one of the mock handler methods\n                t.eq(OpenLayers.Util.indexOf(nonevents, type), -1,\n                     \"registered method is not one of the events \" +\n                     \"that should not be handled\");\n                t.ok(OpenLayers.Util.indexOf(events, type) > -1,\n                     \"activate calls registerPriority with browser event: \" + type);\n                t.eq(typeof func, \"function\",\n                     \"activate calls registerPriority with a function\");\n                t.eq(func(), type,\n                     \"activate calls registerPriority with the correct method\");\n                t.eq(obj[\"CLASS_NAME\"], \"OpenLayers.Handler.Drag\",\n                     \"activate calls registerPriority with the handler\");\n            }\n        }\n        \n        // set browser event like properties on the handler\n        for(var i=0; i<events.length; ++i) {\n            setMethod(events[i]);\n        }\n        function setMethod(key) {\n            handler[key] = function() {return key};\n        }\n\n        var activated = handler.activate();\n\n    }\n\n    function test_Handler_Drag_callbacks(t) {\n        t.plan(33);\n        \n        var map = new OpenLayers.Map('map', {controls: []});\n\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        \n        // set callback methods (out doesn't get an xy)\n        var events = [\"down\", \"move\", \"up\", \"done\"];\n        var testEvents = {};\n        var xys = {};\n        var callbacks = {};\n        for(var i=0; i<events.length; ++i) {\n            var px = new OpenLayers.Pixel(Math.random(), Math.random());\n            testEvents[events[i]] = {xy: px};\n            setCallback(events[i]);\n        }\n        function setCallback(key) {\n            callbacks[key] = function(evtxy) {\n                t.ok(evtxy.x == testEvents[key].xy.x &&\n                     evtxy.y == testEvents[key].xy.y,\n                     key + \" callback called with the proper evt.xy\");\n            }\n        }\n\n        var handler = new OpenLayers.Handler.Drag(control, callbacks);\n        handler.activate();\n        \n        var oldIsLeftClick = OpenLayers.Event.isLeftClick;\n        var oldPreventDefault = OpenLayers.Event.preventDefault;\n        var oldCheckModifiers = handler.checkModifiers;\n\n        // test mousedown with right click\n        OpenLayers.Event.isLeftClick = function() {\n            return false;\n        }\n        handler.checkModifiers = function() {\n            return true;\n        }\n        handler.started = true;\n        handler.start = {x: \"foo\", y: \"bar\"};\n        handler.last = {x: \"foo\", y: \"bar\"};\n        map.events.triggerEvent(\"mousedown\", testEvents.down);\n        t.ok(!handler.started, \"right-click sets started to false\");\n        t.eq(handler.start, null, \"right-click sets start to null\");\n        t.eq(handler.last, null, \"right-click sets last to null\");\n\n        // test mousedown with improper modifier\n        OpenLayers.Event.isLeftClick = function() {\n            return true;\n        }\n        handler.checkModifiers = function() {\n            return false;\n        }\n        handler.started = true;\n        handler.start = {x: \"foo\", y: \"bar\"};\n        handler.last = {x: \"foo\", y: \"bar\"};\n        map.events.triggerEvent(\"mousedown\", testEvents.down);\n        t.ok(!handler.started, \"bad modifier sets started to false\");\n        t.eq(handler.start, null, \"bad modifier sets start to null\");\n        t.eq(handler.last, null, \"bad modifier sets last to null\");\n\n        // test mousedown\n        handler.checkModifiers = function(evt) {\n            t.ok(evt.xy.x == testEvents.down.xy.x &&\n                 evt.xy.y == testEvents.down.xy.y,\n                 \"mousedown calls checkModifiers with the proper event\");\n            return true;\n        }\n        OpenLayers.Event.isLeftClick = function(evt) {\n            t.ok(evt.xy.x == testEvents.down.xy.x &&\n                 evt.xy.y == testEvents.down.xy.y,\n                 \"mousedown calls isLeftClick with the proper event\");\n            return true;\n        }\n        OpenLayers.Event.preventDefault = function(evt) {\n            t.ok(evt.xy.x == testEvents.down.xy.x && evt.xy.y == testEvents.down.xy.y,\n                 \"mousedown default action is disabled\");\n        }\n        map.events.triggerEvent(\"mousedown\", testEvents.down);\n        t.ok(handler.started, \"mousedown sets the started flag to true\");\n        t.ok(!handler.dragging, \"mouse down sets the dragging flag to false\");\n        t.ok(handler.start.x == testEvents.down.xy.x &&\n             handler.start.y == testEvents.down.xy.y,\n             \"mouse down sets handler.start correctly\");\n        t.ok(handler.last.x == testEvents.down.xy.x &&\n             handler.last.y == testEvents.down.xy.y,\n             \"mouse down sets handler.last correctly\");\n        \n        OpenLayers.Event.preventDefault = oldPreventDefault;\n        OpenLayers.Event.isLeftClick = oldIsLeftClick;\n        handler.checkModifiers = oldCheckModifiers;\n\n        // test mouseup before mousemove\n        var realUp = testEvents.up;\n        testEvents.up = testEvents.down;\n        // this will fail with notice about the done callback being called\n        // if done is called when it shouldn't be\n        map.events.triggerEvent(\"mouseup\", testEvents.up);\n        testEvents.up = realUp;\n\n        // test mousemove\n        handler.started = false;\n        map.events.triggerEvent(\"mousemove\", {xy: {x: null, y: null}});\n        // if the handler triggers the move callback, it will be with the\n        // incorrect evt.xy\n        t.ok(true,\n             \"mousemove before the handler has started doesn't call move\");\n        \n        handler.started = true;\n        map.events.triggerEvent(\"mousemove\", testEvents.move);\n        t.ok(handler.dragging, \"mousemove sets the dragging flag to true\");\n        t.ok(handler.start.x == testEvents.down.xy.x &&\n             handler.start.y == testEvents.down.xy.y,\n             \"mouse move leaves handler.start alone\");\n        t.ok(handler.last.x == testEvents.move.xy.x &&\n             handler.last.y == testEvents.move.xy.y,\n             \"mouse move sets handler.last correctly\");\n        \n        // a second move with the same evt.xy should not trigger move callback\n        // if it does, the test page will complain about a bad plan number\n        var oldMove = handler.callbacks.move;\n        handler.callbacks.move = function() {\n            t.ok(false,\n                 \"a second move with the same evt.xy should not trigger a move callback\");\n        }\n        map.events.triggerEvent(\"mousemove\", testEvents.move);\n        handler.callbacks.move = oldMove;\n        \n        // test mouseup\n        handler.started = false;\n        map.events.triggerEvent(\"mouseup\", {xy: {x: null, y: null}});\n        // if the handler triggers the up callback, it will be with the\n        // incorrect evt.xy\n        t.ok(true,\n             \"mouseup before the handler has started doesn't call up\");\n        \n        handler.started = true;\n        // mouseup triggers the up and done callbacks\n        testEvents.done = testEvents.up;\n        map.events.triggerEvent(\"mouseup\", testEvents.up);\n        t.ok(!this.started, \"mouseup sets the started flag to false\");\n        t.ok(!this.dragging, \"mouseup sets the dragging flag to false\");\n        \n        // test mouseout\n        handler.started = false;\n        map.events.triggerEvent(\"mouseout\", {xy: {x: null, y: null}});\n        // if the handler triggers the out or done callback, it will be with the\n        // incorrect evt.xy\n        t.ok(true,\n             \"mouseout before the handler has started doesn't call out or done\");\n        \n        handler.started = true;\n        var oldMouseLeft = OpenLayers.Util.mouseLeft;\n        OpenLayers.Util.mouseLeft = function(evt, element) {\n            t.ok(evt.xy.x == testEvents.done.xy.x &&\n                 evt.xy.y == testEvents.done.xy.y,\n                 \"mouseout calls Util.mouseLeft with the correct event\");\n            t.eq(element.id, map.viewPortDiv.id,\n                 \"mouseout calls Util.mouseLeft with the correct element\");\n            return true;\n        }\n        // mouseup triggers the out and done callbacks\n        // out callback gets no arguments\n        handler.callbacks.out = function() {\n            t.eq(arguments.length, 0,\n                 \"mouseout calls out callback with no arguments\");\n        }\n        map.events.triggerEvent(\"mouseout\", testEvents.done);\n        t.ok(!handler.started, \"mouseout sets started flag to false\");\n        t.ok(!handler.dragging, \"mouseout sets dragging flag to false\");\n        OpenLayers.Util.mouseLeft = oldMouseLeft;\n        \n        // test click with the click.html example - the click method on the\n        // drag handler returns (handler.start == handler.last), stopping\n        // propagation of the click event if the mouse moved during a drag.\n        \n        // regression tests will assure that the drag handler doesn't mess\n        // with anything else on a click\n        function getProperties(obj) {\n            var props = {};\n            for(key in obj) {\n                if(typeof obj[key] != \"function\" && typeof obj[key] != \"object\") {\n                    props[key] = obj[key];\n                }\n            }\n            return props;\n        }\n        var before = getProperties(handler);\n        map.events.triggerEvent(\"click\", null);\n        var after = getProperties(handler);\n        t.eq(before, after, \"click doesn't mess with handler\");\n        \n    }\n\n    function test_Handler_Drag_touch(t) {\n        // In this test we verify that \"touchstart\", \"touchmove\", and\n        // \"touchend\" events set expected states in the drag handler.\n        // We also verify that we prevent the default as appropriate.\n\n        t.plan(19);\n\n        // set up\n\n        var m = new OpenLayers.Map('map', {controls: []});\n        var c = new OpenLayers.Control();\n        m.addControl(c);\n        var h = new OpenLayers.Handler.Drag(c, {\n            done: function(px) { \n                log.push(px); \n            }\n        });\n        h.activate();\n\n        var _preventDefault = OpenLayers.Event.preventDefault;\n        OpenLayers.Event.preventDefault = function(e) {\n            log.push(e);\n        };\n\n        var Px = OpenLayers.Pixel, e;\n        var log = [];\n\n        // test\n        e = {touches: [{}], xy: new Px(0, 0)};\n        m.events.triggerEvent('touchstart', e);\n        t.eq(h.started, true, '[touchstart] started is set');\n        t.eq(h.start.x, 0, '[touchstart] start.x is correct');\n        t.eq(h.start.y, 0, '[touchstart] start.y is correct');\n        t.eq(log.length, 1, '[touchstart] one item in log');\n        t.ok(log[0] === e, \"touchstart\", '[touchstart] event is stopped');\n        t.eq(m.events.listeners.mousedown.length, 0,\"mousedown is not registered\");\n        t.eq(m.events.listeners.mouseup.length, 0,\"mouseup is not registered\");\n        t.eq(m.events.listeners.mousemove.length, 0,\"mousemove is not registered\");\n        t.eq(m.events.listeners.click.length, 0,\"click is not registered\");\n        t.eq(m.events.listeners.mouseout.length, 0,\"mouseout is not registered\");\n\n        e = {xy: new Px(1, 1)};\n        m.events.triggerEvent('touchmove', e);\n        t.eq(h.dragging, true, '[touchmove] dragging is set');\n        t.eq(h.last.x, 1, '[touchmove] last.x is correct');\n        t.eq(h.last.y, 1, '[touchmove] last.y is correct');\n        t.eq(log.length, 1, '[touchmove] one item in log (event is not stopped)');\n\n        e = {xy: new Px(2, 2)};\n        m.events.triggerEvent('touchend', e);\n        t.eq(h.started, false, '[touchend] started is reset');\n        t.eq(h.started, false, '[touchend] started is reset');\n        // the \"done\" callback gets the position of the last touchmove\n        t.eq(log.length, 2, '[touchend] two items in log');\n        t.ok(log[1] instanceof Px, '[touchend] got');\n        t.ok(log[1].equals(e.xy), '[touchend] done callback got correct position');\n\n        // tear down\n\n        OpenLayers.Event.preventDefault = _preventDefault;\n        m.destroy();\n    }\n\n    function test_Handler_Drag_submethods(t) {\n        t.plan(8);\n        \n        var map = new OpenLayers.Map('map', {controls: []});\n\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        \n\n        var handler = new OpenLayers.Handler.Drag(control, {});\n        // set test events\n        var events = [\"down\", \"move\", \"up\", \"out\"];\n        var onselect = {\n            \"move\": OpenLayers.Function.False,\n            \"up\": OpenLayers.Function.False,\n            \"out\": OpenLayers.Function.True\n        }\n        var testEvents = {};\n        var type, px;\n        for(var i=0; i<events.length; ++i) {\n            type = events[i];\n            px = new OpenLayers.Pixel(Math.random(), Math.random());\n            testEvents[type] = {xy: px};\n            setMethod(type);\n        }\n        function setMethod(type) {\n            handler[type] = function(evt) {\n                t.ok(evt.xy.x == testEvents[type].xy.x &&\n                     evt.xy.y == testEvents[type].xy.y,\n                     \"handler.\" + type + \" called with the right event\");\n                onselect[type] && t.ok(document.onselectstart === onselect[type], \"document.onselectstart listener is correct after \" + type);\n            }\n        }\n        handler.activate();\n        \n        // pretend that we have gone through a down-move-up-out cycle before\n        handler.oldOnselectstart = OpenLayers.Function.True;\n        \n        // test mousedown\n        handler.checkModifiers = function(evt) {\n            return true;\n        }\n        var oldIsLeftClick = OpenLayers.Event.isLeftClick;\n        OpenLayers.Event.isLeftClick = function(evt) {\n            return true;\n        }\n        map.events.triggerEvent(\"mousedown\", testEvents.down);\n        OpenLayers.Event.isLeftClick = oldIsLeftClick;\n\n        // test mousemove\n        map.events.triggerEvent(\"mousemove\", testEvents.move);\n        \n        // test mouseup\n        map.events.triggerEvent(\"mouseup\", testEvents.up);\n        \n        // test mouseout\n        var oldMouseLeft = OpenLayers.Util.mouseLeft;\n        OpenLayers.Util.mouseLeft = function() {\n            return true;\n        };\n        handler.started = true;\n        map.events.triggerEvent(\"mouseout\", testEvents.out);\n        OpenLayers.Util.mouseLeft = oldMouseLeft;\n        \n        t.ok(document.onselectstart === OpenLayers.Function.True, \"document.onselectstart listener correct after down-move-up-out cycle\");\n        \n    }\n\n    function test_Handler_Drag_deactivate(t) {\n        t.plan(7);\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Drag(control);\n        handler.active = false;\n        var deactivated = handler.deactivate();\n        t.ok(!deactivated,\n             \"deactivate returns false if the handler was not already active\");\n        handler.active = true;\n        handler.dragging = true;\n        handler.touch = true;\n        deactivated = handler.deactivate();\n        t.ok(deactivated,\n             \"deactivate returns true if the handler was active already\");\n        t.ok(!handler.started,\n             \"deactivate sets started to false\");\n        t.ok(!handler.dragging,\n             \"deactivate sets dragging to false\");\n        t.ok(handler.start == null,\n             \"deactivate sets start to null\");\n        t.ok(handler.last == null,\n             \"deactivate sets last to null\");\n        t.ok(!handler.touch,\n             \"deactivate sets touch to false\");\n    }\n\n    function test_interval_timer_after_mouseup(t) {\n        t.plan(5);\n\n        // set up\n\n        var map = new OpenLayers.Map('map');\n\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n\n        var moveCnt;\n\n        var handler = new OpenLayers.Handler.Drag(control, {}, {\n            interval: 1,\n            move: function() {\n                moveCnt++;\n            }\n        });\n        handler.activate();\n\n        handler.checkModifiers = function() { return true; };\n\n        var ilc = OpenLayers.Event.isLeftClick;\n        OpenLayers.Event.isLeftClick = function() { return true; };\n\n        // test\n\n        moveCnt = 0;\n\n        var xy1 = new OpenLayers.Pixel(1, 2);\n        handler.mousedown({xy: xy1});\n        t.ok(handler.last == xy1, \"[mousedown] last is as expected\");\n        var xy2 = new OpenLayers.Pixel(2, 3);\n        handler.mousemove({xy: xy2});\n        t.ok(handler.last == xy2, \"[mousemove 1] last is as expected\");\n        t.ok(handler.timeoutId != null, \"[mousemove 1] timeoutId is set\");\n        var xy3 = new OpenLayers.Pixel(3, 4);\n        handler.mousemove({xy: xy3});\n        t.ok(handler.last == xy2, \"[mousemove 2] last is as expected\");\n        var xy4 = new OpenLayers.Pixel(4, 5);\n        handler.mouseup({xy: xy4});\n\n        t.delay_call(3, function() {\n            // the timer should not cause a move\n            t.eq(moveCnt, 1, \"move called once\");\n            // tear down\n            OpenLayers.Event.isLeftClick = ilc;\n        });\n    }\n\n    function test_interval_timer_after_mousedown(t) {\n        t.plan(5);\n\n        // set up\n\n        var map = new OpenLayers.Map('map');\n\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n\n        var moveCnt;\n\n        var handler = new OpenLayers.Handler.Drag(control, {}, {\n            interval: 1,\n            move: function() {\n                moveCnt++;\n            }\n        });\n        handler.activate();\n\n        handler.checkModifiers = function() { return true; };\n\n        var ilc = OpenLayers.Event.isLeftClick;\n        OpenLayers.Event.isLeftClick = function() { return true; };\n\n        // test\n\n        moveCnt = 0;\n\n        var xy1 = new OpenLayers.Pixel(1, 2);\n        handler.mousedown({xy: xy1});\n        t.ok(handler.last == xy1, \"[mousedown] last is as expected\");\n        var xy2 = new OpenLayers.Pixel(2, 3);\n        handler.mousemove({xy: xy2});\n        t.ok(handler.last == xy2, \"[mousemove 1] last is as expected\");\n        t.ok(handler.timeoutId != null, \"[mousemove 1] timeoutId is set\");\n        var xy3 = new OpenLayers.Pixel(3, 4);\n        handler.mousemove({xy: xy3});\n        t.ok(handler.last == xy2, \"[mousemove 2] last is as expected\");\n        var xy4 = new OpenLayers.Pixel(4, 5);\n        handler.mouseup({xy: xy4});\n        var xy5 = new OpenLayers.Pixel(5, 6);\n        handler.mousedown({xy: xy4});\n\n        t.delay_call(3, function() {\n            // the timer should not cause a move\n            t.eq(moveCnt, 1, \"move called once\");\n            // tear down\n            OpenLayers.Event.isLeftClick = ilc;\n        });\n    }\n\n    function test_interval_timer_before_mouseup(t) {\n        t.plan(5);\n\n        // set up\n\n        var map = new OpenLayers.Map('map');\n\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n\n        var moveCnt;\n\n        var handler = new OpenLayers.Handler.Drag(control, {}, {\n            interval: 1,\n            move: function() {\n                moveCnt++;\n            }\n        });\n        handler.activate();\n\n        handler.checkModifiers = function() { return true; };\n\n        var ilc = OpenLayers.Event.isLeftClick;\n        OpenLayers.Event.isLeftClick = function() { return true; };\n\n        // test\n\n        moveCnt = 0;\n\n        var xy1 = new OpenLayers.Pixel(1, 2);\n        handler.mousedown({xy: xy1});\n        t.ok(handler.last == xy1, \"[mousedown] last is as expected\");\n        var xy2 = new OpenLayers.Pixel(2, 3);\n        handler.mousemove({xy: xy2});\n        t.ok(handler.last == xy2, \"[mousemove 1] last is as expected\");\n        t.ok(handler.timeoutId != null, \"[mousemove 1] timeoutId is set\");\n        var xy3 = new OpenLayers.Pixel(3, 4);\n        handler.mousemove({xy: xy3});\n        t.ok(handler.last == xy2, \"[mousemove 2] last is as expected\");\n\n        t.delay_call(3, function() {\n            // the timer should cause a move\n            t.eq(moveCnt, 2, \"move called twice\");\n            var xy4 = new OpenLayers.Pixel(4, 5);\n            handler.mouseup({xy: xy4});\n            // tear down\n            OpenLayers.Event.isLeftClick = ilc;\n        });\n    }\n\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 300px; height: 150px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Handler/Feature.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    function test_initialize(t) {\n        t.plan(4);\n        var control = new OpenLayers.Control();\n        control.id = Math.random();\n        var layer = \"boo\";\n        var callbacks = {foo: \"bar\"};\n        var options = {bar: \"foo\"};\n        \n        var oldInit = OpenLayers.Handler.prototype.initialize;\n        \n        OpenLayers.Handler.prototype.initialize = function(con, call, opt) {\n            t.eq(con.id, control.id,\n                 \"constructor calls parent with the correct control\");\n            t.eq(call, callbacks,\n                 \"constructor calls parent with the correct callbacks\");\n            t.eq(opt, options,\n                 \"constructor calls parent with the correct options\");\n        }\n        var handler = new OpenLayers.Handler.Feature(control, layer,\n                                                     callbacks, options);\n        \n        t.eq(handler.layer, \"boo\",\n             \"layer property properly set\");\n\n        OpenLayers.Handler.prototype.initialize = oldInit;\n    }\n\n    function test_activate(t) {\n        t.plan(3);\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var layer = new OpenLayers.Layer();\n        map.addLayer(layer);\n        var handler = new OpenLayers.Handler.Feature(control, layer);\n        handler.active = true;\n        var activated = handler.activate();\n        t.ok(!activated,\n             \"activate returns false if the handler was already active\");\n        handler.active = false;\n        \n        var zIndex = layer.div.style.zIndex;\n        activated = handler.activate();\n        t.ok(activated,\n             \"activate returns true if the handler was not already active\");\n        t.eq(parseInt(layer.div.style.zIndex),\n             map.Z_INDEX_BASE['Feature'],\n             \"layer z-index properly adjusted\");\n        \n    }\n    function test_events(t) {\n        t.plan(35);\n        \n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var layer = new OpenLayers.Layer();\n        map.addLayer(layer);\n        var handler = new OpenLayers.Handler.Feature(control, layer);\n \n        // list below events that should be handled (events) and those\n        // that should not be handled (nonevents) by the handler\n        var events = [\"mousedown\", \"mouseup\", \"mousemove\", \"click\", \"dblclick\", \"touchstart\", \"touchmove\"];\n        var nonevents = [\"mouseout\", \"resize\", \"focus\", \"blur\", \"touchend\"];\n        map.events.registerPriority = function(type, obj, func) {\n            var output = func();\n            // Don't listen for setEvent handlers (#902)\n            if (typeof output == \"string\") {\n                t.eq(OpenLayers.Util.indexOf(nonevents, type), -1,\n                     \"registered method is not one of the events \" +\n                     \"that should not be handled\");\n                t.ok(OpenLayers.Util.indexOf(events, type) > -1,\n                     \"activate calls registerPriority with browser event: \" + type);\n                t.eq(typeof func, \"function\",\n                     \"activate calls registerPriority with a function\");\n                t.eq(func(), type,\n                     \"activate calls registerPriority with the correct method:\"+type);\n                t.eq(obj[\"CLASS_NAME\"], \"OpenLayers.Handler.Feature\",\n                     \"activate calls registerPriority with the handler\");\n            }     \n        }\n        \n        // set browser event like properties on the handler\n        for(var i=0; i<events.length; ++i) {\n            setMethod(events[i]);\n        }\n        function setMethod(key) {\n            handler[key] = function() {return key};\n        }\n \n        var activated = handler.activate();\n \n    }\n \n    function test_geometrytype_limit(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var layer = new OpenLayers.Layer();\n        var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0));\n        feature.layer = layer;\n        layer.getFeatureFromEvent = function(evt) { return feature };\n        map.addLayer(layer);\n        var handler = new OpenLayers.Handler.Feature(control, layer, {}, {'geometryTypes':['OpenLayers.Geometry.Point']});\n        handler.activate();\n        handler.callback = function(type,featurelist) {\n            t.eq(featurelist[0].id, feature.id, \"Correct feature called back on\");\n        }\n        handler.handle({type: \"click\"});\n        handler.feature = null;\n        handler.lastFeature = null;\n        handler.callback = function(type,featurelist) {\n            t.fail(\"Shouldn't have called back on \" + featurelist[0].geometry);\n        }    \n        feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(0,0));\n        feature.layer = layer;\n        handler.handle(\"click\", {}); \n    }\n\n    function test_callbacks(t) {\n        t.plan(14);\n        \n        var map = new OpenLayers.Map('map', {controls: []});\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var layer = new OpenLayers.Layer();\n        map.addLayer(layer);\n \n        var callbacks = {};\n        var newFeature, lastFeature;\n        var evtPx = {xy: new OpenLayers.Pixel(Math.random(), Math.random())};\n \n        // define a callback factory function\n        function getCallback(evt, feature) {\n            return function(f) {\n                t.ok(f == feature, evt + \" callback called with proper feature\");\n            };\n        }\n \n        // override the layer's getFeatureFromEvent func so that it always\n        // returns newFeature\n        layer.getFeatureFromEvent = function(evt) { return newFeature; };\n \n        var handler = new OpenLayers.Handler.Feature(control, layer, callbacks);\n        handler.activate();\n\n        // test click in new feature\n        // only 'click' callback should be called\n        handler.feature = null;\n        lastFeature = null;\n        newFeature = new OpenLayers.Feature.Vector();\n        newFeature.layer = layer;\n        callbacks['click'] = getCallback('click', newFeature);\n        callbacks['clickout'] = getCallback('clickout', lastFeature);\n        evtPx.type = \"click\";\n        map.events.triggerEvent('click', evtPx);\n\n        // test click in new feature and out of last feature\n        // both 'click' and 'clickout' callbacks should be called\n        lastFeature = newFeature;\n        newFeature = new OpenLayers.Feature.Vector();\n        newFeature.layer = layer;\n        callbacks['click'] = getCallback('click', newFeature);\n        callbacks['clickout'] = getCallback('clickout', lastFeature);\n        evtPx.type = \"click\";\n        map.events.triggerEvent('click', evtPx);\n\n        // test click out of last feature\n        // only 'clickout' callback should be called\n        lastFeature = newFeature;\n        newFeature = null;\n        callbacks['click'] = getCallback('click', newFeature);\n        callbacks['clickout'] = getCallback('clickout', lastFeature);\n        evtPx.type = \"click\";\n        map.events.triggerEvent('click', evtPx);\n\n        layer.getFeatureFromEvent = function(evt) { t.fail(\"mousemove called getFeatureFromEvent without any mousemove callbacks\"); };\n        evtPx.type = \"mousemove\";\n        map.events.triggerEvent('mousemove', evtPx);\n        layer.getFeatureFromEvent = function(evt) { return newFeature; };\n        \n        // test over a new feature\n        // only 'over' callback should be called\n        handler.feature = null;\n        lastFeature = null;\n        newFeature = new OpenLayers.Feature.Vector();\n        newFeature.layer = layer;\n        callbacks['over'] = getCallback('over', newFeature);\n        callbacks['out'] = getCallback('out', lastFeature);\n        evtPx.type = \"mousemove\";\n        map.events.triggerEvent('mousemove', evtPx);\n\n        // test over a new feature and out of last feature\n        // both 'over' and 'out' callbacks should be called\n        lastFeature = newFeature;\n        newFeature = new OpenLayers.Feature.Vector();\n        newFeature.layer = layer;\n        callbacks['over'] = getCallback('over', newFeature);\n        callbacks['out'] = getCallback('out', lastFeature);\n        evtPx.type = \"mousemove\";\n        map.events.triggerEvent('mousemove', evtPx);\n\n        // test out of last feature\n        // only 'out' callback should be called\n        lastFeature = newFeature;\n        newFeature = null;\n        callbacks['over'] = getCallback('over', newFeature);\n        callbacks['out'] = getCallback('out', lastFeature);\n        evtPx.type = \"mousemove\";\n        map.events.triggerEvent('mousemove', evtPx);\n\n        // test dblclick on a feature\n        // 'dblclick' callback should be called\n        handler.feature = null;\n        lastFeature = null;\n        newFeature = new OpenLayers.Feature.Vector();\n        newFeature.layer = layer;\n        callbacks['dblclick'] = getCallback('dblclick', newFeature);\n        evtPx.type = \"dblclick\";\n        map.events.triggerEvent('dblclick', evtPx);\n\n        // test touchstart on a feature\n        // 'click' callback should be called\n        handler.feature = null;\n        lastFeature = null;\n        newFeature = new OpenLayers.Feature.Vector();\n        newFeature.layer = layer;\n        callbacks['click'] = getCallback('click (touch)', newFeature);\n        callbacks['clickout'] = getCallback('clickout (touch)', lastFeature);\n        evtPx.type = \"touchstart\";\n        map.events.triggerEvent('touchstart', evtPx);\n\n        // test touchstart on the same feature\n        // 'click' callback should be called\n        callbacks['click'] = getCallback('click (touch)', newFeature);\n        evtPx.type = \"touchstart\";\n        map.events.triggerEvent('touchstart', evtPx);\n\n        // test touchstart in new feature and out of last feature\n        // both 'click' and 'clickout' callbacks should be called\n        lastFeature = newFeature;\n        newFeature = new OpenLayers.Feature.Vector();\n        newFeature.layer = layer;\n        callbacks['click'] = getCallback('click (touch)', newFeature);\n        callbacks['clickout'] = getCallback('clickout (touch)', lastFeature);\n        evtPx.type = \"touchstart\";\n        map.events.triggerEvent('touchstart', evtPx);\n\n        // test touchstart out of last feature\n        // only 'clickout' callback should be called\n        lastFeature = newFeature;\n        newFeature = null;\n        callbacks['click'] = getCallback('click (touch)', newFeature);\n        callbacks['clickout'] = getCallback('clickout (touch)', lastFeature);\n        evtPx.type = \"touchstart\";\n        map.events.triggerEvent('touchstart', evtPx);\n    }\n\n    function test_touchstart(t) {\n        // a test to verify that the touchstart function does\n        // unregister the mouse listeners when it's called the\n        // first time\n\n        t.plan(4);\n\n        // set up\n\n        var map = new OpenLayers.Map('map', {controls: []});\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var layer = new OpenLayers.Layer();\n        map.addLayer(layer);\n\n        var handler = new OpenLayers.Handler.Feature(control, layer, {});\n        handler.mousedown = function() {}; // mock mousedown\n        handler.activate();\n\n        var eventTypes = ['mousedown', 'mouseup', 'mousemove', 'click', 'dblclick'];\n\n        function allRegistered() {\n            var eventType,\n                listeners,\n                listener,\n                flag;\n            for(var i=0, ilen=eventTypes.length; i<ilen; i++) {\n                flag =  false;\n                eventType = eventTypes[i];\n                listeners = map.events.listeners[eventType];\n                for(var j=0, jlen=listeners.length; j<jlen; j++) {\n                    listener = listeners[j];\n                    if(listener.func === handler[eventType] && listener.obj === handler) {\n                        flag = true;\n                        break;\n                    }\n                }\n                if(!flag) {\n                    return false;\n                }\n            }\n            return true;\n        }\n\n        function noneRegistered() {\n            var eventType,\n                times,\n                flag = false;\n            for(var i=0, ilen=eventTypes.length; i<ilen; i++) {\n                eventType = eventTypes[i];\n                times = map.events.listeners[eventType].length;\n                if (times != 0) {\n                    t.fail(eventType + \" is registered \" + times + \" times\");\n                    flag = true;\n                }\n            }\n            return !flag;\n        }\n\n        // test\n\n        t.ok(allRegistered(), 'mouse listeners are registered');\n        handler.touchstart({xy: new OpenLayers.Pixel(0, 0)});\n        t.ok(noneRegistered(), 'mouse listeners are unregistered');\n        t.ok(handler.touch, 'handler.touch is set');\n\n        handler.deactivate();\n        t.ok(!handler.touch, 'handler.touch is not set');\n\n        // tear down\n\n        map.destroy();\n    }\n\n    function test_deactivate(t) {\n        t.plan(3);\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var layer = new OpenLayers.Layer();\n        map.addLayer(layer);\n        var layerIndex = parseInt(layer.div.style.zIndex);\n        \n        var handler = new OpenLayers.Handler.Feature(control, layer);\n        handler.active = false;\n        var deactivated = handler.deactivate();\n        t.ok(!deactivated,\n             \"deactivate returns false if the handler was not already active\");\n        \n        handler.active = true;\n\n        deactivated = handler.deactivate();\n        t.ok(deactivated,\n             \"deactivate returns true if the handler was active already\");\n        t.eq(parseInt(layer.div.style.zIndex),\n             layerIndex,\n             \"deactivate sets the layer z-index back\");\n    }\n\n    function test_stopHandled(t) {\n        t.plan(3);\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var layer = new OpenLayers.Layer();\n        map.addLayer(layer);\n        var handler = new OpenLayers.Handler.Feature(control, layer);\n        handler.activate();\n        handler.handle = function(evt) { return /* handled */ true; };\n        var  evtPx = {xy: new OpenLayers.Pixel(Math.random(), Math.random())};\n        map.events.register(\"click\", map, function(e) {\n            t.ok(!handler.stopClick, \"clicks propagate with stopClick set to false\" );\n        });\n        map.events.register(\"mousedown\", map, function(e) {\n            t.ok(!handler.stopDown, \"mousedown propagate with stopDown set to false\" );\n        });\n        map.events.register(\"mouseup\", map, function(e) {\n            t.ok(!handler.stopUp, \"mouseup propagate with stopUp set to false\" );\n        });\n\n        // 0 test\n        map.events.triggerEvent('click', evtPx);\n        // 0 test\n        map.events.triggerEvent('mousedown', evtPx);\n        // 0 test\n        map.events.triggerEvent('mousedown', evtPx);\n\n        // 1 test\n        handler.stopClick = false;\n        map.events.triggerEvent('click', evtPx);\n        // 1 test\n        handler.stopDown = false;\n        map.events.triggerEvent('mousedown', evtPx);\n        // 1 test\n        handler.stopUp = false;\n        map.events.triggerEvent('mouseup', evtPx);\n        \n        // 3 tests total\n    }\n\n    function test_destroyed_feature(t) {\n        t.plan(18);\n        \n        // setup\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var layer = new OpenLayers.Layer();\n        layer.removeFeatures = function() {};\n        map.addLayer(layer);\n        var handler = new OpenLayers.Handler.Feature(control, layer);\n        var feature, count, lastType, lastHandled;\n        handler.callback = function(type, features) {\n            ++count;\n            lastType = type;\n            lastHandled = features;\n        }\n\n        /**\n         * Test that a destroyed feature doesn't get sent to the \"click\" callback\n         */\n        count = 0;\n        handler.activate();\n        feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0));\n        feature.layer = layer;\n        // mock click on a feature\n        layer.getFeatureFromEvent = function(evt) {return feature};\n        handler.handle({type: \"click\"});\n        // confirm that feature was handled\n        t.eq(count, 1, \"[click] callback called once\");\n        t.eq(lastType, \"click\", \"[click] correct callback type\");\n        t.eq(lastHandled[0].id, feature.id, \"[click] correct feature sent to callback\");\n        \n        // now destroy the feature and confirm that the callback is not called again\n        feature.destroy();\n        handler.handle({type: \"click\"});\n        if(count === 1) {\n            t.ok(true, \"[click] callback not called after destroy\");\n        } else {\n            t.fail(\"[click] callback called after destroy: \" + lastType);\n        }\n        \n        /**\n         * Test that a destroyed feature doesn't get sent to the \"clickout\" callback\n         */\n        count = 0;\n        handler.deactivate();\n        handler.activate();\n        feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0));\n        feature.layer = layer;\n\n        // mock a click on a feature\n        layer.getFeatureFromEvent = function(evt) {return feature};\n        handler.handle({type: \"click\"});\n        // confirm that callback got feature\n        t.eq(count, 1, \"[clickout] callback called once on in\");\n        t.eq(lastType, \"click\", \"[clickout] click callback called on in\");\n        t.eq(lastHandled.length, 1, \"[clickout] callback called with one feature\");\n        t.eq(lastHandled[0].id, feature.id, \"[clickout] callback called with correct feature\");\n\n        // now mock a click off a destroyed feature\n        feature.destroy();\n        layer.getFeatureFromEvent = function(evt) {return null};\n        handler.handle({type: \"click\"});\n        // confirm that callback does not get called\n        if(count === 1) {\n            t.ok(true, \"[clickout] callback not called when clicking out of a destroyed feature\");\n        } else {\n            t.fail(\"[clickout] callback called when clicking out of a destroyed feature: \" + lastType);\n        }\n        \n        /**\n         * Test that a destroyed feature doesn't get sent to the \"over\" callback\n         */\n        count = 0;\n        handler.deactivate();\n        handler.activate();\n        feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0));\n        feature.layer = layer;\n        // mock mousemove over a feature\n        layer.getFeatureFromEvent = function(evt) {return feature};\n        handler.handle({type: \"mousemove\"});\n        // confirm that feature was handled\n        t.eq(count, 1, \"[over] callback called once\");\n        t.eq(lastType, \"over\", \"[over] correct callback type\");\n        t.eq(lastHandled[0].id, feature.id, \"[over] correct feature sent to callback\");\n        \n        // now destroy the feature and confirm that the callback is not called again\n        feature.destroy();\n        handler.handle({type: \"mousemove\"});\n        if(count === 1) {\n            t.ok(true, \"[over] callback not called after destroy\");\n        } else {\n            t.fail(\"[over] callback called after destroy: \" + lastType);\n        }\n\n        /**\n         * Test that a destroyed feature doesn't get sent to the \"out\" callback\n         */\n        count = 0;\n        handler.deactivate();\n        handler.activate();\n        feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,0));\n        feature.layer = layer;\n\n        // mock a mousemove over a feature\n        layer.getFeatureFromEvent = function(evt) {return feature};\n        handler.handle({type: \"mousemove\"});\n        // confirm that callback got feature\n        t.eq(count, 1, \"[out] callback called once on over\");\n        t.eq(lastType, \"over\", \"[out] click callback called on over\");\n        t.eq(lastHandled.length, 1, \"[out] callback called with one feature\");\n        t.eq(lastHandled[0].id, feature.id, \"[out] callback called with correct feature\");\n\n        // now mock a click off a destroyed feature\n        feature.destroy();\n        layer.getFeatureFromEvent = function(evt) {return null};\n        handler.handle({type: \"mousemove\"});\n        // confirm that callback does not get called\n        if(count === 1) {\n            t.ok(true, \"[out] callback not called when moving out of a destroyed feature\");\n        } else {\n            t.fail(\"[out] callback called when moving out of a destroyed feature: \" + lastType);\n        }\n        \n        handler.destroy();\n    }\n\n    function test_click_tolerance(t) {\n        t.plan(3);\n\n        var map, control, layer, feature, evtPx;\n        var clicks, callbacks, handler;\n\n        map = new OpenLayers.Map('map', {controls: []});\n        control = new OpenLayers.Control();\n        map.addControl(control);\n        layer = new OpenLayers.Layer();\n        map.addLayer(layer);\n \n        feature = new OpenLayers.Feature.Vector();\n        feature.layer = layer;\n\n        evtPx = {\n            xy: new OpenLayers.Pixel(Math.random(), Math.random()),\n            type: \"click\"\n        };\n \n        // override the layer's getFeatureFromEvent func so that it always\n        // returns newFeature\n        layer.getFeatureFromEvent = function(evt) { return feature; };\n\n        callbacks = {\n            click: function() {\n                clicks++;\n            }\n        };\n \n        handler = new OpenLayers.Handler.Feature(\n            control, layer, callbacks, {clickTolerance: 4});\n        handler.activate();\n\n        // distance between down and up is 1, which is\n        // lower than clickTolerance so \"click\" should trigger\n        handler.down = {x: 0, y: 0};\n        handler.up = {x: 1, y: 0};\n        clicks = 0;\n        map.events.triggerEvent(\"click\", evtPx);\n        t.eq(clicks, 1, \"click callback triggers when tolerance is not reached (lower than)\");\n\n        // distance between down and up is 4, which is\n        // equal to clickTolerance so \"click\" should trigger\n        handler.down = {x: 0, y: 0}; // cached handler.down cleared (#857)\n        handler.up = {x: 0, y: 4};\n        clicks = 0;\n        map.events.triggerEvent(\"click\", evtPx);\n        t.eq(clicks, 1, \"click callback triggers when tolerance is not reached (equal to)\");\n\n        // distance between down and up is 5, which is\n        // greater than clickTolerance so \"click\" should not trigger\n        handler.down = {x: 0, y: 0}; // cached handler.down cleared (#857)\n        handler.up = {x: 5, y: 0};\n        clicks = 0;\n        map.events.triggerEvent(\"click\", evtPx);\n        t.eq(clicks, 0, \"click callback does not trigger when tolerance is reached\");\n    }\n\n    function test_multitouch_canvas(t) {\n        var supported = OpenLayers.Renderer.Canvas.prototype.supported();\n        if (!supported) { t.plan(0); return; }\n\n        t.plan(1);\n\n        // set up\n\n        var log;\n\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.Vector('vectors', {\n            renderers: ['Canvas'],\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n\n        var control = new OpenLayers.Control();\n        var handler = new OpenLayers.Handler.Feature(control, layer,\n                {click: function() { log++; }});\n        control.handler = handler;\n        map.addControl(control);\n        control.activate();\n\n        var feature = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(0, 0));\n        layer.addFeatures(feature);\n\n        map.zoomToMaxExtent();\n\n        // test\n\n        // mock getMousePosition on the events object to make\n        // sure scrolls, offsets and leftop do not interfere\n        map.events.getMousePosition = function(evt) {\n            return new OpenLayers.Pixel(evt.clientX,\n                                        evt.clientY);\n        };\n\n        log = 0;\n        var evt = {\n            type: 'touchstart',\n            touches: [{\n                clientX: 100,\n                clientY: 75\n            }, {\n                clientX: 200,\n                clientY: 75\n            }]\n        };\n        map.events.handleBrowserEvent(evt);\n        t.eq(log, 0, \"no feature selection when multi-touching\");\n\n        // tear down\n\n        map.destroy();\n    }\n    \n    function test_layerorder(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var base = new OpenLayers.Layer(null, {isBaseLayer: true});\n        var vector = new OpenLayers.Layer.Vector();\n        map.addLayers([base, vector]);\n        map.addControl(new OpenLayers.Control.SelectFeature(vector, {autoActivate: true}));\n        map.zoomToMaxExtent();\n        t.eq(parseInt(vector.getZIndex(), 10), 725, \"vector layer's zIndex correct\");\n        map.events.triggerEvent(\"changelayer\");\n        t.eq(parseInt(vector.getZIndex(), 10), 725, \"vector layer's zIndex still correct after changelayer event\");\n        \n    }\n\n    function test_clear_event_position_cache(t) {\n        t.plan(2);\n\n        var map, control, layer, feature, evtPx;\n\n        map = new OpenLayers.Map('map', {controls: []});\n        control = new OpenLayers.Control();\n        map.addControl(control);\n        layer = new OpenLayers.Layer();\n        layer.getFeatureFromEvent = function(evt) { return feature; };\n        map.addLayer(layer);\n        feature = new OpenLayers.Feature.Vector();\n        feature.layer = layer;\n\n        evtPx = {\n            xy: new OpenLayers.Pixel(Math.random(), Math.random()),\n            type: \"click\"\n        };\n \n        handler = new OpenLayers.Handler.Feature(\n            control, layer, {}, {});\n        handler.activate();\n\n        handler.down = {x: 0, y: 0};\n        handler.up = {x: 1, y: 0};\n        map.events.triggerEvent(\"click\", evtPx);\n        t.eq(handler.down, null, \"cached mousedown position is cleared after handling click\");\n        t.eq(handler.up, null, \"cached mouseup position is cleared after handling click\")\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 300px; height: 150px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Handler/Hover.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    function test_Handler_Hover_events(t) {\n        t.plan(10);\n        \n        var map = new OpenLayers.Map('map');\n        var control = {\n            map: map\n        };\n        map.events.registerPriority = function(type, obj, func) {\n            var r = func();\n            if(typeof r == \"string\") {\n                // this is one of the mock handler methods\n                t.eq(OpenLayers.Util.indexOf(nonevents, type), -1,\n                     \"registered method is not one of the events \" +\n                     \"that should not be handled\");\n                t.ok(OpenLayers.Util.indexOf(events, type) > -1,\n                     \"activate calls registerPriority with browser event: \" + type);\n                t.eq(typeof func, \"function\",\n                     \"activate calls registerPriority with a function\");\n                t.eq(func(), type,\n                     \"activate calls registerPriority with the correct method\");\n                t.eq(obj[\"CLASS_NAME\"], \"OpenLayers.Handler.Hover\",\n                     \"activate calls registerPriority with the handler\");\n            }\n        }\n        function setMethod(key) {\n            handler[key] = function() {return key};\n        }\n\n        // list below events that should be handled (events) and those\n        // that should not be handled (nonevents) by the handler\n        var events = [\"mousemove\", \"mouseout\"];\n        var nonevents = [\"mousedown\", \"mouseup\", \"click\", \"dblclick\", \"resize\", \"focus\", \"blur\"];\n        var handler = new OpenLayers.Handler.Hover(control);\n        // set browser event like properties on the handler\n        for(var i=0; i<events.length; ++i) {\n            setMethod(events[i]);\n        }\n        handler.activate();\n    }\n\n    function test_Handler_Hover_callbacks(t) {\n        t.plan(8);\n        \n        var map = new OpenLayers.Map('map', {controls: []});\n\n        var control = {\n            map: map\n        };\n        \n        var timers = {};\n        var sto = window.setTimeout;\n        window.setTimeout = function(func, delay) {\n            var key = Math.random();\n            timers[key] = true;\n            t.ok(typeof func == \"function\",\n                 \"setTimeout called with a function\");\n            t.eq(delay, handler.delay,\n                 \"setTimeout called with proper delay\");\n            // execute function that is supposed to be delayed\n            func();\n            return key;\n        }\n        var cto = window.clearTimeout;\n        window.clearTimeout = function(key) {\n            if(timers[key] === true) {\n                delete timers[key];\n            } else {\n                t.fail(\"clearTimeout called with non-existent timerId\");\n            }\n        }\n\n        var handler = new OpenLayers.Handler.Hover(control, {});\n        handler.activate();\n        var testEvt;\n\n        // test pause and move callbacks - four tests here (2 from setTimeout above)\n        testEvt = {id: Math.random()};\n        handler.callbacks = {\n            \"pause\": function(evt) {\n                t.eq(evt.id, testEvt.id,\n                     \"pause callback called with correct evt\");\n            },\n            \"move\": function(evt) {\n               t.eq(evt.id, testEvt.id,\n                   \"move callback called with correct evt\");\n            }\n        };\n        map.events.triggerEvent(\"mousemove\", testEvt);\n        handler.clearTimer();\n\n        // test pixelTolerance - four tests here (2 from setTimeout above)\n        handler.pixelTolerance = 2;\n        handler.px = new OpenLayers.Pixel(0, 0);\n        testEvt = {\n            xy: new OpenLayers.Pixel(0, 1)\n        };\n        // mouse moves one pixel, callbacks shouldn't be called\n        handler.callbacks = {\n            \"pause\": function(evt) {\n                t.fail(\"(pixelTolerance met) pause callback shouldn't be called\");\n            },\n            \"move\": function(evt) {\n                t.fail(\"(pixelTolerance met) move callback shoudln't be called\");\n            }\n        };\n        map.events.triggerEvent(\"mousemove\", testEvt);\n        handler.clearTimer();\n        handler.px = new OpenLayers.Pixel(0, 0);\n        testEvt = {\n            xy: new OpenLayers.Pixel(3, 3)\n        };\n        // mouse moves 3x3 pixels, callbacks should be called\n        handler.callbacks =  {\n            \"pause\": function(evt) {\n                t.ok(evt.xy == testEvt.xy, \"(pixelTolerance unmet) pause callback called\");\n            },\n            \"move\": function(evt) {\n                t.ok(evt == testEvt, \"(pixelTolerance unmet) move callback called\");\n            }\n        };\n        map.events.triggerEvent(\"mousemove\", testEvt);\n        handler.clearTimer();\n\n        window.setTimeout = sto;\n        window.clearTimeout = cto;\n   }\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 300px; height: 150px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Handler/Keyboard.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    function test_Handler_Keyboard_initialize(t) {\n        t.plan(3);\n        var control = new OpenLayers.Control();\n        control.id = Math.random();\n        var callbacks = {foo: \"bar\"};\n        var options = {bar: \"foo\"};\n        \n        var oldInit = OpenLayers.Handler.prototype.initialize;\n        \n        OpenLayers.Handler.prototype.initialize = function(con, call, opt) {\n            t.eq(con.id, control.id,\n                 \"constructor calls parent with the correct control\");\n            t.eq(call, callbacks,\n                 \"constructor calls parent with the correct callbacks\");\n            t.eq(opt, options,\n                 \"constructor calls parent with the correct options\");\n        }\n        var handler = new OpenLayers.Handler.Keyboard(control, callbacks,\n                                                      options);\n\n        OpenLayers.Handler.prototype.initialize = oldInit;\n    }\n\n    function test_Handler_Keyboard_destroy(t) {\n        t.plan(3);\n        var control = new OpenLayers.Control();        \n        var handler = new OpenLayers.Handler.Keyboard(control);\n        var old = OpenLayers.Handler.prototype.destroy;\n        t.ok(handler.eventListener != null,\n             \"eventListener is not null before destroy\");\n        OpenLayers.Handler.prototype.destroy = function() {\n            t.ok(true, \"destroy calls destroy on correct parent\");\n        };\n        handler.destroy();\n        t.ok(handler.eventListener == null,\n             \"eventListeners is null after destroy\");\n        OpenLayers.Handler.prototype.destroy = old;\n    }\n\n    function test_Handler_Keyboard_activate(t) {\n        t.plan(15);\n\n        var log;\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Keyboard(control);\n\n        // mock OpenLayers.Event.observe\n        var old = OpenLayers.Event.stopObserving;\n        OpenLayers.Event.observe = function(obj, type, method) {\n            log[type] = obj;\n            var validType = OpenLayers.Util.indexOf([\"keydown\", \"keyup\"], type) != -1;\n            t.ok(validType, \"activate calls observe for \" + type);\n            t.ok(method == handler.eventListener,\n                 \"activate calls observing with correct method\");\n        };\n\n        handler.active = true;\n        var activated = handler.activate();\n        t.ok(!activated,\n             \"activate returns false if the handler was already active\");\n\n        log = {};\n        handler.active = false;\n        handler.observeElement = map.div;\n        activated = handler.activate();\n        t.ok(log['keydown'] == map.div,\n             \"activate calls observing for keydown with correct object\");\n        t.ok(log['keyup'] == map.div,\n             \"activate calls observing for keyup with correct object\");\n        t.ok(activated,\n             \"activate returns true if the handler was not already active\");\n\n        log = {};\n        handler.active = false;\n        handler.observeElement = null;\n        activated = handler.activate();\n        t.ok(log['keydown'] == document,\n             \"activate calls observing for keydown with correct object\");\n        t.ok(log['keyup'] == document,\n             \"activate calls observing for keyup with correct object\");\n        t.ok(activated,\n             \"activate returns true if the handler was not already active\");\n\n        OpenLayers.Event.observe = old;\n        map.destroy();\n    }\n\n    function test_Handler_Keyboard_deactivate(t) {\n        t.plan(15);\n\n        var log;\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Keyboard(control);\n\n        // mock OpenLayers.Event.stopObserving\n        var old = OpenLayers.Event.stopObserving;\n        OpenLayers.Event.stopObserving = function(obj, type, method) {\n            log[type] = obj;\n            var validType = OpenLayers.Util.indexOf([\"keydown\", \"keyup\"], type) != -1;\n            t.ok(validType, \"deactivate calls stopObserving for \" + type);\n            t.ok(method == handler.eventListener,\n                 \"deactivate calls stopObserving with correct method\");\n        };\n\n        handler.active = false;\n        var deactivated = handler.deactivate();\n        t.ok(!deactivated,\n             \"deactivate returns false if the handler was not already active\");\n\n        log = {};\n        handler.active = true;\n        handler.observeElement = map.div;\n        deactivated = handler.deactivate();\n        t.ok(log['keydown'] == map.div,\n             \"deactivate calls stopObserving for keydown with correct object\");\n        t.ok(log['keyup'] == map.div,\n             \"deactivate calls stopObserving for keyup with correct object\");\n        t.ok(deactivated,\n             \"deactivate returns true if the handler was active already\");\n\n        log = {};\n        handler.active = true;\n        handler.observeElement = document;\n        deactivated = handler.deactivate();\n        t.ok(log['keydown'] == document,\n             \"deactivate calls stopObserving for keydown with correct object\");\n        t.ok(log['keyup'] == document,\n             \"deactivate calls stopObserving for keyup with correct object\");\n        t.ok(deactivated,\n             \"deactivate returns true if the handler was active already\");\n\n        OpenLayers.Event.stopObserving = old;\n        map.destroy();\n    }\n\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 300px; height: 150px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Handler/MouseWheel.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    function test_Handler_MouseWheel_constructor(t) {\n        t.plan(3);\n        var control = new OpenLayers.Control();\n        control.id = Math.random();\n        var callbacks = {foo: \"bar\"};\n        var options = {bar: \"foo\"};\n        \n        var oldInit = OpenLayers.Handler.prototype.initialize;\n        \n        OpenLayers.Handler.prototype.initialize = function(con, call, opt) {\n            t.eq(con.id, control.id,\n                 \"constructor calls parent with the correct control\");\n            t.eq(call, callbacks,\n                 \"constructor calls parent with the correct callbacks\");\n            t.eq(opt, options,\n                 \"constructor calls parent with the correct options\");\n        }\n        var handler = new OpenLayers.Handler.MouseWheel(control, callbacks, options);\n\n        OpenLayers.Handler.prototype.initialize = oldInit;\n    }\n\n    function test_Handler_MouseWheel_activate(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.MouseWheel(control);\n        handler.active = true;\n        var activated = handler.activate();\n        t.ok(!activated,\n             \"activate returns false if the handler was already active\");\n        handler.active = false;\n        activated = handler.activate();\n        t.ok(activated,\n             \"activate returns true if the handler was not already active\");\n    }\n    \n    function test_Handler_MouseWheel_mousePosition(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map('map');\n        map.addLayer(new OpenLayers.Layer.WMS(\"\",\"\",{}));\n        map.zoomToMaxExtent();\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var pass = false;\n        var handler = new OpenLayers.Handler.MouseWheel(control, {'up': \n          function (evt) { \n                if (evt.xy) { pass = true; }\n          }\n        });\n        handler.setMap(map);\n        handler.activate();\n        var delta = 120;\n        handler.onWheelEvent({'target':map.layers[0].div, wheelDelta: delta});\n        t.ok(pass, \"evt.xy was set even without a mouse move\");\n    }    \n    \n    function test_Handler_MouseWheel_events(t) {\n        t.plan(6);\n        \n        var map = new OpenLayers.Map('map');\n        map.addLayer(new OpenLayers.Layer.WMS(\"\",\"\",{}));\n        map.zoomToMaxExtent();\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var deltaZ;\n        var handler = new OpenLayers.Handler.MouseWheel(control, {\n            'up': function(evt, delta){\n                deltaZ = delta;\n            }\n        }, {interval: 200});\n\n        // list below events that should be handled (events) and those\n        // that should not be handled (nonevents) by the handler\n        var events = [\"mousemove\"];\n        var nonevents = [\"dblclick\", \"resize\", \"focus\", \"blur\"];\n        map.events.registerPriority = function(type, obj, func) {\n            var r = func();\n            if(typeof r == \"string\") {\n                t.eq(OpenLayers.Util.indexOf(nonevents, type), -1,\n                     \"registered method is not one of the events \" +\n                     \"that should not be handled\");\n                t.ok(OpenLayers.Util.indexOf(events, type) > -1,\n                     \"activate calls registerPriority with browser event: \" + type);\n                t.eq(typeof func, \"function\",\n                     \"activate calls registerPriority with a function\");\n                t.eq(func(), type,\n                     \"activate calls registerPriority with the correct method\");\n                t.eq(obj[\"CLASS_NAME\"], \"OpenLayers.Handler.MouseWheel\",\n                     \"activate calls registerPriority with the handler\");\n            }\n        }\n        \n        // set browser event like properties on the handler\n        for(var i=0; i<events.length; ++i) {\n            setMethod(events[i]);\n        }\n        function setMethod(key) {\n            handler[key] = function() {return key};\n        }\n\n        var activated = handler.activate();\n        \n        var delta = 120;\n        handler.onWheelEvent({'target':map.layers[0].div, wheelDelta: delta});\n        handler.onWheelEvent({'target':map.layers[0].div, wheelDelta: delta});\n        t.delay_call(1, function() {\n            t.eq(deltaZ, 2, \"Multiple scroll actions triggered one event when interval is set\");\n        });\n    }\n\n    function test_Handler_MouseWheel_cumulative(t) {\n        t.plan(2);\n\n        var deltaUp = 0, ticks = 0;\n        var callbacks = {\n            up: function(evt, delta) {\n                deltaUp += delta;\n                ticks++;\n            }\n        };\n\n        var map = new OpenLayers.Map('map');\n        map.addLayer(new OpenLayers.Layer.WMS(\"\",\"\",{}));\n        map.zoomToMaxExtent();\n        var control = new OpenLayers.Control({});\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.MouseWheel(control, callbacks, {\n            interval: 150,\n            cumulative: false,\n            maxDelta: 6\n        });\n\n        var delta = 120;\n        // generate 20 scroll up in non cumulative mode\n        for (var i=0; i < 20; i++) {\n            handler.onWheelEvent({'target':map.layers[0].div, wheelDelta: delta});\n        }\n        \n        t.delay_call(2, function() {\n            t.eq(deltaUp / ticks, 1, \"Cumulative mode works\");\n            t.eq(ticks, 4, \"up called 4x with maxDelta of 6\");\n        });\n    }\n\n    function test_Handler_MouseWheel_deactivate(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.MouseWheel(control);\n        handler.active = false;\n        var deactivated = handler.deactivate();\n        t.ok(!deactivated,\n             \"deactivate returns false if the handler was not already active\");\n        handler.active = true;\n        deactivated = handler.deactivate();\n        t.ok(deactivated,\n             \"deactivate returns true if the handler was active already\");\n    }\n    function test_handler_MouseWheel_destroy(t) {\n        t.plan(1);\n        var control = new OpenLayers.Control();\n        var handler = new OpenLayers.Handler.MouseWheel(control);\n        handler.deactivate = function() { \n            t.ok(true, \"Deactivate called one time.\");\n        }    \n        handler.destroy();\n    }\n\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 300px; height: 150px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Handler/Path.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    function test_Handler_Path_constructor(t) {\n        t.plan(3);\n        var control = new OpenLayers.Control();\n        control.id = Math.random();\n        var callbacks = {foo: \"bar\"};\n        var options = {bar: \"foo\"};\n        \n        var oldInit = OpenLayers.Handler.prototype.initialize;\n        \n        OpenLayers.Handler.prototype.initialize = function(con, call, opt) {\n            t.eq(con.id, control.id,\n                 \"constructor calls parent with the correct control\");\n            t.eq(call, callbacks,\n                 \"constructor calls parent with the correct callbacks\");\n            t.eq(opt, options,\n                 \"constructor calls parent with the correct options\");\n        }\n        var handler = new OpenLayers.Handler.Path(control, callbacks, options);\n\n        OpenLayers.Handler.prototype.initialize = oldInit;\n    }\n\n    function test_Handler_Path_activation(t) {\n        t.plan(5);\n        var log = [];\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control();\n        var handler = new OpenLayers.Handler.Path(control, {});\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n        handler.active = true;\n\n        var activated = handler.activate();\n        t.ok(!activated,\n             \"activate returns false if the handler was already active\");\n        handler.active = false;\n        activated = handler.activate();\n        t.ok(activated,\n             \"activate returns true if the handler was not already active\");\n        t.ok(handler.layer instanceof OpenLayers.Layer.Vector,\n             \"activate creates a vector layer\");\n        t.ok(handler.layer.map == map,\n             \"activate adds the vector layer to the map\");\n        activated = handler.deactivate();\n        t.ok(activated,\n             \"deactivate returns true if the handler was active already\");\n\n        map.destroy();\n    }\n\n    // See: http://trac.osgeo.org/openlayers/ticket/3179\n    function test_activate_before_map_is_centered(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map('map', {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control();\n        var handler = new OpenLayers.Handler.Path(control, {});\n        control.handler = handler;\n        map.addControl(control);\n\n        var error;\n        try {\n            handler.activate();\n            error = false;\n        } catch(err) {\n            error = true;\n        }\n        t.ok(!error, \"no error on activate\");\n    }\n\n    function test_bounds(t) {\n        t.plan(4);\n        var geometry;\n        var map = new OpenLayers.Map('map');\n        map.addLayer(new OpenLayers.Layer.WMS(\"\", \"\", {}));\n        map.zoomToMaxExtent();\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Path(control, {},\n            {stopDown: true, stopUp: true});\n        var activated = handler.activate();\n        // click on (150, 75)\n        var evt = {xy: new OpenLayers.Pixel(150, 75), which: 1};\n        handler.mousemove(evt);\n        handler.mousedown(evt);\n        handler.mouseup(evt);\n        t.eq(handler.layer.features.length, 2,\n            \"There are two features in the layer after first click.\");\n        // click on (175, 100)\n        evt = {xy: new OpenLayers.Pixel(175, 100), which: 1};\n        handler.mousemove(evt);\n        handler.mousedown(evt);\n        handler.mouseup(evt);\n        t.eq(handler.layer.features.length, 2,\n            \"There are two features in the layer after second click.\");\n        t.ok(handler.line.geometry.getBounds().equals(\n                    new OpenLayers.Bounds(0,-35.15625,35.15625,0)),\n             \"Correct bounds\");\n        // mousedown on (175, 100)\n        evt = {xy: new OpenLayers.Pixel(175, 100), which: 1};\n        handler.mousedown(evt);\n        // mousemove to (125, 100)\n        evt = {xy: new OpenLayers.Pixel(125, 100), which: 1};\n        handler.mousemove(evt);\n        // test that the bounds have changed\n        t.ok(!handler.line.geometry.getBounds().equals(\n                 new OpenLayers.Bounds(0,-35.15625,35.15625,0)),\n             \"Correct bounds after dragging without letting go. \" +\n             \"(Came out as \" + handler.line.geometry.getBounds().toBBOX() +\n             \".)\");\n        map.destroy();     \n    }     \n\n    function test_callbacks(t) {\n        t.plan(39);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var logs = [], log;\n        var handler = new OpenLayers.Handler.Path(control, {\n            create: function() {\n                logs.push({type: \"create\", args: arguments});\n            },\n            point: function() {\n                logs.push({type: \"point\", args: arguments});\n            },\n            modify: function() {\n                logs.push({type: \"modify\", args: arguments});\n            },\n            done: function() {\n                logs.push({type: \"done\", args: arguments});\n            },\n            cancel: function() {\n                logs.push({type: \"cancel\", args: arguments});\n            }\n        },\n        {\n            pixelTolerance: 0\n        });\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n        \n        handler.activate();\n\n        // mouse move\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        t.eq(logs.length, 2, \"[mousemove] called back twice\");\n        log = logs.shift();\n        t.eq(log.type, \"create\", \"[mousemove] create called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-150, 75),\n                  \"[mousemove] correct point\");\n        t.ok(log.args[1] === handler.line,\n             \"[mousemove] correct feature\");\n        log = logs.shift();\n        t.eq(log.type, \"modify\", \"[mousemove] modify called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-150, 75),\n                  \"[mousemove] correct point\");\n        t.ok(log.args[1] === handler.line,\n             \"[mousemove] correct feature\");\n        // mouse down\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0)});\n        t.eq(logs.length, 1, \"[mousedown] called back\");\n        log = logs.shift();\n        t.eq(log.type, \"modify\", \"[mousedown] modify called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-150, 75),\n                  \"[mousedown] correct point\");\n        t.ok(log.args[1] === handler.line,\n             \"[mousedown] correct feature\");\n        // mouse up\n        handler.mouseup({type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0)});\n        t.eq(logs.length, 2, \"[mouseup] called back twice\");\n        log = logs.shift();\n        t.eq(log.type, \"point\", \"[mouseup] point called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-150, 75),\n                  \"[mouseup] correct point\");\n        t.geom_eq(log.args[1],\n                  new OpenLayers.Geometry.LineString([\n                      new OpenLayers.Geometry.Point(-150, 75),\n                      new OpenLayers.Geometry.Point(-150, 75)\n                  ]), \"[mouseup] correct line\");\n        log = logs.shift();\n        t.eq(log.type, \"modify\", \"[mouseup] modify called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-150, 75),\n                  \"[mouseup] correct point\");\n        t.ok(log.args[1] == handler.line,\n             \"[mouseup] correct feature\");\n        // mouse move\n        handler.mousemove({type: \"mousemove\",\n                           xy: new OpenLayers.Pixel(1, 1)});\n        t.eq(logs.length, 1, \"[mousemove] called back\");\n        log = logs.shift();\n        t.eq(log.type, \"modify\", \"[mousemove] modify called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-149, 74),\n                  \"[mousemove] correct point\");\n        t.ok(log.args[1] === handler.line,\n             \"[mousemove] correct feature\");\n        // mouse move\n        handler.mousemove({type: \"mousemove\",\n                           xy: new OpenLayers.Pixel(10, 10)});\n        t.eq(logs.length, 1, \"[mousemove] called back\");\n        log = logs.shift();\n        t.eq(log.type, \"modify\", \"[mousemove] modify called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-140, 65),\n                  \"[mousemove] correct point\");\n        t.ok(log.args[1] === handler.line,\n             \"[mousemove] correct feature\");\n        // mouse down\n        handler.mousedown({type: \"mousedown\",\n                           xy: new OpenLayers.Pixel(10, 10)});\n        t.eq(logs.length, 1, \"[mousedown] called back\");\n        log = logs.shift();\n        t.eq(log.type, \"modify\", \"[mousedown] modify called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-140, 65),\n                  \"[mousedown] correct point\");\n        t.ok(log.args[1] === handler.line,\n             \"[mousedown] correct feature\");\n        // mouse up (\"point\", \"modify\")\n        handler.mouseup({type: \"mouseup\",\n                         xy: new OpenLayers.Pixel(10, 10)});\n        t.eq(logs.length, 2, \"[mouseup] called back twice\");\n        log = logs.shift();\n        log = logs.shift();\n        // mouse down\n        handler.mousedown({type: \"mousedown\",\n                           xy: new OpenLayers.Pixel(10, 10)});\n        t.eq(logs.length, 0, \"[mousedown] called back\");\n        // mouse up\n        handler.mouseup({type: \"mouseup\",\n                         xy: new OpenLayers.Pixel(10, 10)});\n        t.eq(logs.length, 0, \"[mouseup] not called back\");\n        // double click\n        handler.dblclick({type: \"dblclick\",\n                          xy: new OpenLayers.Pixel(10, 10)});\n        t.eq(logs.length, 1, \"[dblclick] called back\");\n        log = logs.shift();\n        t.eq(log.type, \"done\", \"[dblclick] done called\");\n        t.geom_eq(log.args[0],\n            new OpenLayers.Geometry.LineString([\n                new OpenLayers.Geometry.Point(-150, 75),\n                new OpenLayers.Geometry.Point(-140, 65)\n            ]),\n            \"[dblclick] correct linestring\"\n        );\n        // cancel\n        handler.cancel();\n        t.eq(logs.length, 1, \"[cancel] called back\");\n        log = logs.shift();\n        t.eq(log.type, \"cancel\", \"[cancel] canced called\");\n        t.eq(log.args[0], null, \"[cancel] got null\"\n        );\n \n        map.destroy();\n    }\n\n    function test_toggle_freehand(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Path(control, {\n            done: function(g) {\n                log++;\n            }\n        }, {persist: true});\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        handler.activate();\n\n        log = 0;\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 2), shiftKey: true});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0), shiftKey: true});\n        t.eq(log, 1, \"feature drawn when shift pressed on mousedown\");\n\n        log = 0;\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0), shiftKey: false});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 2), shiftKey: true});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0), shiftKey: true});\n        t.eq(log, 0, \"feature not drawn when shift not pressed on mousedown\");\n    }\n\n    function test_persist(t) {\n        t.plan(4);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Path(control, {});\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        handler.activate();\n\n        handler.persist = false;\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        var feature1 = handler.line;\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.dblclick(\n            {type: \"dblclick\", xy: new OpenLayers.Pixel(1, 1)});\n        t.ok(feature1.layer == null, \"a) feature1 destroyed\");\n\n        handler.persist = true;\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        var feature2 = handler.line;\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.dblclick(\n            {type: \"dblclick\", xy: new OpenLayers.Pixel(1, 1)});\n        t.ok(feature2.layer != null, \"b) feature2 not destroyed\");\n\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        var feature3 = handler.line;\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.dblclick(\n            {type: \"dblclick\", xy: new OpenLayers.Pixel(1, 1)});\n        t.ok(feature3.layer != null, \"c) feature3 not destroyed\");\n        t.ok(feature2.layer == null, \"c) feature2 destroyed\");\n\n        map.destroy();\n    }\n\n    function test_persist_freehand(t) {\n        t.plan(6);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Path(control, {});\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        handler.activate();\n\n        handler.persist = false;\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        var feature1 = handler.line;\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 2), shiftKey: true});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0), shiftKey: true});\n        t.ok(feature1.layer == null, \"a) feature1 destroyed\");\n\n        handler.persist = true;\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        feature2 = handler.line;\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 2), shiftKey: true});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0), shiftKey: true});\n        t.ok(feature2.layer != null, \"b) feature2 not destroyed\");\n\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        feature3 = handler.line;\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 2), shiftKey: true});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0), shiftKey: true});\n        t.ok(feature3.layer != null, \"c) feature3 not destroyed\");\n        t.ok(feature2.layer == null, \"c) feature2 destroyed\");\n\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        feature4 = handler.line;\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0), shiftKey: false});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 2), shiftKey: true});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0), shiftKey: true});\n        t.ok(feature4.layer != null, \"d) feature4 not destroyed\");\n        t.ok(feature3.layer == null, \"c) feature3 destroyed\");\n\n        map.destroy();\n    }\n\n    function test_Handler_Path_destroy(t) {\n        t.plan(6);\n        var map = new OpenLayers.Map('map');\n        map.addLayer(new OpenLayers.Layer.WMS(\"\", \"\", {}));\n        map.zoomToMaxExtent();\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Path(control, {foo: 'bar'});\n\n        handler.activate();\n        var evt = {xy: new OpenLayers.Pixel(150, 75), which: 1};\n        handler.mousedown(evt);\n\n        t.ok(handler.layer,\n             \"handler has a layer prior to destroy\");\n        t.ok(handler.point,\n             \"handler has a point prior to destroy\");\n        t.ok(handler.line,\n             \"handler has a line prior to destroy\");\n        handler.destroy();\n        t.eq(handler.layer, null,\n             \"handler.layer is null after destroy\");\n        t.eq(handler.point, null,\n             \"handler.point is null after destroy\");\n        t.eq(handler.line, null,\n             \"handler.line is null after destroy\");\n        map.destroy();     \n    }\n\n    function test_maxVertices(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var log = {};\n        var doneCallback = function(evt) {\n            t.ok(evt, 'When maxVertices is reached, the geometry is finalized automatically');\n        };\n        var handler = new OpenLayers.Handler.Path(control, {'done': doneCallback}, {maxVertices: 2});\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        // mock up feature drawing\n        handler.activate();\n        var evt = {xy: new OpenLayers.Pixel(0, 0)};\n        handler.mousemove(evt);\n        handler.mousedown(evt);\n        handler.mouseup(evt);\n        evt = {xy: new OpenLayers.Pixel(20, 20)};\n        handler.mousemove(evt);\n        handler.mousedown(evt);\n        handler.mouseup(evt);\n        evt = {xy: new OpenLayers.Pixel(40, 40)};\n        handler.mousemove(evt);\n        handler.mousedown(evt);\n        handler.mouseup(evt);\n        map.destroy();\n    }\n\n    function test_freehand_maxVertices(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var log = {};\n        var MAX_VERTICES = 2;\n        var doneCallback = function(geo) {\n            t.eq(geo.components.length, MAX_VERTICES,\n                'When maxVertices is reached, the geometry is finalized automatically');\n        };\n        var handler = new OpenLayers.Handler.Path(control, \n            {'done': doneCallback}, \n            {freehand: true, \n             maxVertices: MAX_VERTICES});\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        // mock up feature freehand drawing\n        handler.activate();\n        var evt = {xy: new OpenLayers.Pixel(0, 0)};\n        handler.mousemove(evt);\n        handler.mousedown(evt);\n        evt = {xy: new OpenLayers.Pixel(20, 20)};\n        handler.mousemove(evt);\n        evt = {xy: new OpenLayers.Pixel(40, 40)};\n        handler.mousemove(evt);\n        map.destroy();\n    }\n    \n    /**\n     * Helper functions for editing method tests\n     */ \n    function editingMethodsSetup() {\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.DrawFeature(\n            layer, OpenLayers.Handler.Path\n        );\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        control.activate();\n        return {\n            handler: control.handler,\n            map: map\n        }\n    }\n    function userClick(handler, x, y) {\n        var px = new OpenLayers.Pixel(x, y);\n        handler.mousemove({type: \"mousemove\", xy: px});\n        handler.mousedown({type: \"mousedown\", xy: px});\n        handler.mouseup({type: \"mouseup\", xy: px});\n    }\n    function userTap(handler, x, y) {\n        var px = new OpenLayers.Pixel(x, y);\n        handler.touchstart({xy: px});\n        handler.touchmove({xy: px});\n        handler.touchend({});\n    }\n\n    /**\n     * Editing method tests: insertXY, insertDeltaXY, insertDirectionXY,\n     * insertDeflectionXY, undo, and redo\n     */\n    function test_insertXY(t) {\n        t.plan(3);\n        var obj = editingMethodsSetup();\n        var map = obj.map;\n        var handler = obj.handler;\n\n        // add points at px(0, 0) and px(10, 10)\n        userClick(handler, 0, 0);\n        userClick(handler, 10, 10);\n        handler.mousemove({type: \"mousemove\", xy: new OpenLayers.Pixel(50, 50)});\n\n        t.eq(handler.line.geometry.components.length, 3, \"line has three points after two clicks\");\n        \n        // programmatically add a point\n        handler.insertXY(5, 6);\n        t.eq(handler.line.geometry.components.length, 4, \"line has four points after insertXY\");\n        t.geom_eq(\n            handler.line.geometry.components[2],\n            new OpenLayers.Geometry.Point(5, 6),\n            \"third point comes from insertXY\"\n        );\n        \n        map.destroy();\n        \n    }\n\n    function test_insertDeltaXY(t) {\n        t.plan(3);\n        var obj = editingMethodsSetup();\n        var map = obj.map;\n        var handler = obj.handler;\n        \n        // add points at px(0, 0) and px(10, 10)\n        userClick(handler, 0, 0);\n        userClick(handler, 10, 10);\n        handler.mousemove({type: \"mousemove\", xy: new OpenLayers.Pixel(50, 50)});\n\n        t.eq(handler.line.geometry.components.length, 3, \"line has three points after two clicks\");\n        \n        // programmatically add a point\n        handler.insertDeltaXY(1, 2);\n        t.eq(handler.line.geometry.components.length, 4, \"line has four points after insert\");\n        // expect a point that is offset from previous point\n        var exp = handler.line.geometry.components[1].clone();\n        exp.move(1, 2);\n        t.geom_eq(\n            handler.line.geometry.components[2], exp,\n            \"third point is offset by dx,dy from second point\"\n        );\n        \n        map.destroy();\n    }\n\n    function test_insertDirectionLength(t) {\n        t.plan(4);\n        var obj = editingMethodsSetup();\n        var map = obj.map;\n        var handler = obj.handler;\n        \n        // add points at px(0, 0) and px(10, 10)\n        userClick(handler, 0, 0);\n        userClick(handler, 10, 10);\n        handler.mousemove({type: \"mousemove\", xy: new OpenLayers.Pixel(50, 50)});\n\n        t.eq(handler.line.geometry.components.length, 3, \"line has three points after two clicks\");\n        \n        // programmatically add a point\n        handler.insertDirectionLength(45, 2);\n        t.eq(handler.line.geometry.components.length, 4, \"line has four points after insert\");\n        var p1 = handler.line.geometry.components[1];\n        var p2 = handler.line.geometry.components[2];\n        \n        var direction = Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI;\n        t.eq(direction.toFixed(4), (45).toFixed(4), \"inserted point offset with correct direction\");\n        var length = Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));\n        t.eq(length.toFixed(4), (2).toFixed(4), \"inserted point offset with correct length\");\n        \n        map.destroy();\n    }\n\n    function test_insertDeflectionLength(t) {\n        t.plan(4);\n        var obj = editingMethodsSetup();\n        var map = obj.map;\n        var handler = obj.handler;\n\n        // add points at px(0, 0) and px(10, 10)\n        userClick(handler, 0, 0);\n        userClick(handler, 10, 10);\n        handler.mousemove({type: \"mousemove\", xy: new OpenLayers.Pixel(50, 50)});\n\n        t.eq(handler.line.geometry.components.length, 3, \"line has three points after two clicks\");\n        var p0 = handler.line.geometry.components[0];\n        var p1 = handler.line.geometry.components[1];\n        // angle of first segment\n        var dir0 = Math.atan2(p1.y - p0.y, p1.x - p0.x) * 180 / Math.PI;\n        \n        // programmatically add a point\n        handler.insertDeflectionLength(-30, 5);\n        t.eq(handler.line.geometry.components.length, 4, \"line has four points after insert\");\n        var p2 = handler.line.geometry.components[2];\n        // angle of second segment\n        var dir1 = Math.atan2(p2.y - p1.y, p2.x - p1.x) * 180 / Math.PI;\n        \n        var deflection = dir1 - dir0;\n        t.eq(deflection.toFixed(4), (-30).toFixed(4), \"inserted point offset with correct deflection\");\n\n        var length = Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2));\n        t.eq(length.toFixed(4), (5).toFixed(4), \"inserted point offset with correct length\");\n        \n        map.destroy();\n    }\n\n    function test_undoredo1(t) {\n        t.plan(5);\n        var obj = editingMethodsSetup();\n        var map = obj.map;\n        var handler = obj.handler;\n        \n        // add points and move mouse\n        userClick(handler, 0, 0);\n        userClick(handler, 10, 10);\n        userClick(handler, 50, 10);\n        handler.mousemove({type: \"mousemove\", xy: new OpenLayers.Pixel(50, 50)});\n        var original = handler.line.geometry.clone();\n        var len = original.components.length;\n        t.eq(len, 4, \"original has four points after three clicks\");\n        \n        // one undo\n        handler.undo();\n        var currentLen = handler.line.geometry.components.length;\n        t.eq(currentLen, len-1, \"one point removed on undo\");\n        t.geom_eq(\n            handler.line.geometry.components[currentLen-1],\n            original.components[len-1],\n            \"current point (mouse position) remains the same after undo\"\n        );\n        // one redo\n        handler.redo();\n        t.geom_eq(original, handler.line.geometry, \"one redo undoes one undo\");\n        \n        // add point via touch\n        userTap(handler, 10, 50);\n        handler.undo();\n        currentLen = handler.line.geometry.components.length;\n        t.geom_eq(\n            handler.line.geometry.components[currentLen-1],\n            handler.line.geometry.components[currentLen-2],\n            \"current point (mouse position) is set to the last digitized \" + \n            \"point after undo on touch devices\"\n        );\n        \n        // cleanup\n        map.destroy();\n    }\n\n    function test_undoredo2(t) {\n        t.plan(8);\n        var obj = editingMethodsSetup();\n        var map = obj.map;\n        var handler = obj.handler;\n        \n        // add points and move mouse\n        userClick(handler, 0, 0);\n        userClick(handler, 10, 10);\n        userClick(handler, 50, 10);\n        handler.mousemove({type: \"mousemove\", xy: new OpenLayers.Pixel(50, 50)});\n        var original = handler.line.geometry.clone();\n        var len = original.components.length;\n        t.eq(len, 4, \"original has four points after three clicks\");\n\n        // two undos\n        handler.undo();\n        handler.undo();\n        var currentLen = handler.line.geometry.components.length;\n        t.eq(currentLen, len-2, \"two points removed on two undos\");\n        t.geom_eq(\n            handler.line.geometry.components[currentLen-1],\n            original.components[len-1],\n            \"current point (mouse position) remains the same after two undos\"\n        );\n        // first redo\n        handler.redo();\n        currentLen = handler.line.geometry.components.length;\n        t.eq(currentLen, len-1, \"point added in first redo\");\n        t.geom_eq(\n            handler.line.geometry.components[currentLen-2],\n            original.components[len-3],\n            \"correct point restored in first redo\"\n        );\n\n        // second redo\n        handler.redo();\n        currentLen = handler.line.geometry.components.length;\n        t.eq(currentLen, len, \"point added in second redo\");\n        t.geom_eq(\n            handler.line.geometry.components[currentLen-2],\n            original.components[len-2],\n            \"correct point restored in second redo\"\n        );\n        t.geom_eq(handler.line.geometry, original, \"correct geometry\");\n\n        // cleanup\n        map.destroy();\n    }\n\n    function test_undoredo3(t) {\n        t.plan(3);\n        var obj = editingMethodsSetup();\n        var map = obj.map;\n        var handler = obj.handler;\n        \n        // add points and move mouse\n        userClick(handler, 0, 0);\n        userClick(handler, 10, 10);\n        userClick(handler, 50, 10);\n        handler.mousemove({type: \"mousemove\", xy: new OpenLayers.Pixel(50, 50)});\n        var original = handler.line.geometry.clone();\n        var len = original.components.length;\n        t.eq(len, 4, \"original has four points after three clicks\");\n\n        // gratuitous redos \n        var trouble = false;\n        try {\n            handler.undo();\n            handler.undo();\n            handler.redo();\n            handler.redo();\n            handler.redo();\n            handler.redo();\n            handler.redo();\n        } catch (err) {\n            trouble = true;\n        }\n        t.ok(!trouble, \"extra redos cause no ill effects\");\n        t.geom_eq(handler.line.geometry, original, \"correct geometry\");\n        \n        // cleanup\n        map.destroy();\n    }\n        \n    function test_undoredo4(t) {\n        t.plan(3);\n        var obj = editingMethodsSetup();\n        var map = obj.map;\n        var handler = obj.handler;\n        \n        // add points and move mouse\n        userClick(handler, 0, 0);\n        userClick(handler, 10, 10);\n        userClick(handler, 50, 10);\n        handler.mousemove({type: \"mousemove\", xy: new OpenLayers.Pixel(50, 50)});\n        var original = handler.line.geometry.clone();\n        var len = original.components.length;\n        t.eq(len, 4, \"original has four points after three clicks\");\n\n        // gratuitous undos\n        var trouble = false;\n        try {\n            handler.undo();\n            handler.undo();\n            handler.undo();\n            handler.undo();\n            handler.undo();\n            handler.undo();\n            handler.undo();\n        } catch (err) {\n            trouble = true;\n        }\n        t.ok(!trouble, \"extra undos cause no ill effects\");\n        t.eq(handler.line.geometry.components.length, 2, \"still left with two points after many undos\")\n\n        // cleanup\n        map.destroy();\n    }\n\n    //\n    // Sequence tests\n    // \n    // Sequence tests basically involve executing a sequence of events\n    // and testing the resulting geometry.\n    //\n    // Below are tests for various drawing sequences. Tests can be\n    // added here each a non-working sequence is found.\n    //\n\n    // stopDown:true, stopUp:true, pixelTolerance:1\n    // a) click on (0, 0)\n    // b) mousedown on (1, 1)\n    // c) mouseup on (2, 2)\n    // d) dblclick on (10, 10)\n    function test_sequence1(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Path(control,\n            {done: function(g) { log.geometry = g; }},\n            {stopDown: true, stopUp: true, pixelTolerance: 1}\n        );\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        handler.activate();\n        log = {};\n\n        // a) click on (0, 0)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0)});\n        // b) mousedown on (1, 1)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(1, 1)});\n        // c) mouseup on (2, 2)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 2)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(2, 2)});\n        // d) dblclick on (10, 10)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(10, 10)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(10, 10)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(10, 10)});\n        handler.dblclick(\n            {type: \"dblclick\", xy: new OpenLayers.Pixel(10, 10)});\n        t.geom_eq(log.geometry,\n            new OpenLayers.Geometry.LineString([\n                new OpenLayers.Geometry.Point(-150, 75), // (0, 0)\n                new OpenLayers.Geometry.Point(-140, 65)  // (10, 10)\n            ]), \"geometry is correct\");\n    }\n\n    // stopDown:false, stopUp:false, pixelTolerance:1\n    // a) click on (0, 0)\n    // b) mousedown on (1, 1)\n    // c) mouseup on (2, 2)\n    // d) dblclick on (10, 10)\n    function test_sequence2(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Path(control,\n            {done: function(g) { log.geometry = g; }},\n            {stopDown: false, stopUp: false, pixelTolerance: 1}\n        );\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        handler.activate();\n        log = {};\n\n        // a) click on (0, 0)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0)});\n        // b) mousedown on (1, 1)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(1, 1)});\n        // c) mouseup on (2, 2)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 2)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(2, 2)});\n        // d) dblclick on (10, 10)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(10, 10)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(10, 10)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(10, 10)});\n        handler.dblclick(\n            {type: \"dblclick\", xy: new OpenLayers.Pixel(10, 10)});\n        t.geom_eq(log.geometry,\n            new OpenLayers.Geometry.LineString([\n                new OpenLayers.Geometry.Point(-150, 75), // (0, 0)\n                new OpenLayers.Geometry.Point(-140, 65)  // (10, 10)\n            ]), \"geometry is correct\");\n    }\n\n    // a) click\n    // b) dblclick\n    // c) mousedown holding shift key\n    // d) mousemove holding shift key\n    function test_sequence3(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Path(control, {},\n        {\n            pixelTolerance: 0\n        });\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        handler.activate();\n\n        // a) click on (0, 0)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0)});\n        // b) click on (1, 1)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(1, 1)});\n        // c) click on (1, 1)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(1, 1)});\n        // d) mousemove to (10, 10)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(10, 10), shiftKey: true});\n        t.geom_eq(handler.line.geometry,\n            new OpenLayers.Geometry.LineString([\n                new OpenLayers.Geometry.Point(-150, 75), // (0, 0)\n                new OpenLayers.Geometry.Point(-149, 74), // (1, 1)\n                new OpenLayers.Geometry.Point(-140, 65)  // (10, 10)\n            ]), \"geometry is correct after mousemove\");\n    }\n\n    // a) click\n    // b) dblclick\n    // c) mousedown holding shift key\n    // d) mousemove holding shift key\n    function test_sequence4(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Path(control,\n            {done: function(g) { log.geometry = g; }},\n            {stopDown: false, stopUp: false}\n        );\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        handler.activate();\n        log = {};\n\n        // a) click on (0, 0)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0)});\n        // b) dblclick on (1, 1)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.dblclick(\n            {type: \"dblclick\", xy: new OpenLayers.Pixel(1, 1)});\n        t.geom_eq(log.geometry,\n            new OpenLayers.Geometry.LineString([\n                new OpenLayers.Geometry.Point(-150, 75), // (0, 0)\n                new OpenLayers.Geometry.Point(-149, 74)  // (1, 1)\n            ]), \"geometry is correct after dblclick\");\n        // c) mousedown holding shift key on (1, 1)\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(1, 1), shiftKey: true});\n        // d) mousemove holding shift key to (10, 10)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(10, 10), shiftKey: true});\n        t.geom_eq(handler.line.geometry,\n            new OpenLayers.Geometry.LineString([\n                new OpenLayers.Geometry.Point(-149, 74),  // (1, 1)\n                new OpenLayers.Geometry.Point(-140, 65)   // (10, 10)\n            ]), \"geometry is correct after mousemove\");\n    }\n\n \n    // a) tap\n    // c) doubletap\n    function test_touch_sequence1(t) {\n        t.plan(19);\n\n        // set up\n\n        var log;\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Path(control, {\n            done: function(g, f) {\n                log = {type: 'done', geometry: g, feature: f};\n            },\n            modify: function(g, f) {\n                log = {type: 'modify', geometry: g, feature: f};\n            }\n        }, {\n            doubleTouchTolerance: 2\n        });\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n        handler.activate();\n\n        // test\n\n        var ret;\n\n        // tap on (1, 0)\n        log = null;\n        ret = handler.touchstart({xy: new OpenLayers.Pixel(0, 0)});\n        t.ok(ret, '[touchstart] event propagates');\n        t.eq(log, null, '[touchstart] feature not finalized or modified');\n        ret = handler.touchmove({xy: new OpenLayers.Pixel(1, 0)});\n        t.ok(ret, '[touchmove] event propagates');\n        t.eq(log, null, '[touchmove] feature not finalized or modified');\n        ret = handler.touchend({});\n        t.ok(ret, '[touchend] event propagates');\n        t.eq(log.type, 'modify', '[touchend] feature modified');\n        t.geom_eq(log.geometry, new OpenLayers.Geometry.Point(-149, 75),\n                  \"[touchend] correct point\");\n\n        // doubletap on (10, 10)\n        log = null;\n        ret = handler.touchstart({xy: new OpenLayers.Pixel(9, 10)});\n        t.ok(ret, '[touchstart] event propagates');\n        t.eq(log, null, '[touchstart] feature not finalized or modified');\n        ret = handler.touchmove({xy: new OpenLayers.Pixel(10, 10)});\n        t.ok(ret, '[touchmove] event propagates');\n        t.eq(log, null, '[touchmove] feature not finalized or modified');\n        ret = handler.touchend({});\n        t.ok(ret, '[touchend] event propagates');\n        t.eq(log.type, 'modify', '[touchend] feature modified');\n        t.geom_eq(log.geometry, new OpenLayers.Geometry.Point(-140, 65),\n                  \"[touchend] correct point\");\n        log = null;\n        ret = handler.touchstart({xy: new OpenLayers.Pixel(11, 10)});\n        t.ok(!ret, '[touchstart] event does not propagate');\n        t.eq(log.type, 'done', '[touchend] feature finalized');\n        t.geom_eq(log.geometry,\n            new OpenLayers.Geometry.LineString([\n                new OpenLayers.Geometry.Point(-149, 75),  // (1, 0)\n                new OpenLayers.Geometry.Point(-140, 65)   // (10, 10)\n            ]), \"[touchstart] final geometry is correct\");\n        log = null;\n        ret = handler.touchend({});\n        t.ok(ret, '[touchend] event propagates');\n        t.eq(log, null, '[touchend] feature not finalized or modified');\n\n        // tear down\n\n        map.destroy();\n    }\n\n    // a) tap\n    // b) tap-move\n    // c) doubletap\n    function test_touch_sequence2(t) {\n        t.plan(25);\n\n        // set up\n\n        var log;\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Path(control, {\n            done: function(g, f) {\n                log = {type: 'done', geometry: g, feature: f};\n            },\n            modify: function(g, f) {\n                log = {type: 'modify', geometry: g, feature: f};\n            }\n        }, {\n            doubleTouchTolerance: 2\n        });\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n        handler.activate();\n\n        // test\n\n        var ret;\n\n        // tap on (1, 0)\n        log = null;\n        ret = handler.touchstart({xy: new OpenLayers.Pixel(0, 0)});\n        t.ok(ret, '[touchstart] event propagates');\n        t.eq(log, null, '[touchstart] feature not finalized or modified');\n        ret = handler.touchmove({xy: new OpenLayers.Pixel(1, 0)});\n        t.ok(ret, '[touchmove] event propagates');\n        t.eq(log, null, '[touchmove] feature not finalized or modified');\n        ret = handler.touchend({});\n        t.ok(ret, '[touchend] event propagates');\n        t.eq(log.type, 'modify', '[touchend] feature modified');\n        t.geom_eq(log.geometry, new OpenLayers.Geometry.Point(-149, 75),\n                  \"[touchend] correct point\");\n\n        // tap-move\n        log = null;\n        ret = handler.touchstart({xy: new OpenLayers.Pixel(9, 10)});\n        t.ok(ret, '[touchstart] event propagates');\n        t.eq(log, null, '[touchstart] feature not finalized or modified');\n        ret = handler.touchmove({xy: new OpenLayers.Pixel(20, 20)});\n        t.ok(ret, '[touchmove] event propagates');\n        t.eq(log, null, '[touchmove] feature not finalized or modified');\n        ret = handler.touchend({});\n        t.ok(ret, '[touchend] event propagates');\n        t.eq(log, null, '[touchend] feature not finalized or modified');\n\n        // doubletap on (10, 10)\n        log = null;\n        ret = handler.touchstart({xy: new OpenLayers.Pixel(9, 10)});\n        t.ok(ret, '[touchstart] event propagates');\n        t.eq(log, null, '[touchstart] feature not finalized or modified');\n        ret = handler.touchmove({xy: new OpenLayers.Pixel(10, 10)});\n        t.ok(ret, '[touchmove] event propagates');\n        t.eq(log, null, '[touchmove] feature not finalized or modified');\n        ret = handler.touchend({});\n        t.ok(ret, '[touchend] event propagates');\n        t.eq(log.type, 'modify', '[touchend] feature modified');\n        t.geom_eq(log.geometry, new OpenLayers.Geometry.Point(-140, 65),\n                  \"[touchend] correct point\");\n        log = null;\n        ret = handler.touchstart({xy: new OpenLayers.Pixel(11, 10)});\n        t.ok(!ret, '[touchstart] event does not propagate');\n        t.eq(log.type, 'done', '[touchend] feature finalized');\n        t.geom_eq(log.geometry,\n            new OpenLayers.Geometry.LineString([\n                new OpenLayers.Geometry.Point(-149, 75),  // (1, 0)\n                new OpenLayers.Geometry.Point(-140, 65)   // (10, 10)\n            ]), \"[touchstart] final geometry is correct\");\n        log = null;\n        ret = handler.touchend({});\n        t.ok(ret, '[touchend] event propagates');\n        t.eq(log, null, '[touchend] feature not finalized or modified');\n\n        // tear down\n\n        map.destroy();\n    }\n\n    function test_persist_one_click_freehand(t) {\n        t.plan(3);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Path(control, {}, {persist: true});\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        handler.activate();\n\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0), shiftKey: true});\n        var feature1 = handler.line;\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1), shiftKey: true});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(1, 1), shiftKey: true});\n        t.ok(feature1.layer != null, \"a) feature1 not destroyed\");\n\n        // one click freehand\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 2)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(2, 2), shiftKey: true});\n        var feature2 = handler.line;\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(2, 2), shiftKey: true});\n        t.ok(feature2.layer != null, \"b) feature2 not destroyed\");\n        t.ok(feature1.layer == null, \"b) feature1 destroyed\");\n        \n        map.destroy();\n    }\n\n    function test_set_freehand(t) {\n        t.plan(5);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n\n        var geo, pointsCount;        \n        var handler = new OpenLayers.Handler.Path(control, {\n                done: function(g) {\n                    geo = g;\n                },\n                point: function() {\n                    pointsCount++;\n                }\n            },\n            {freehand: true}\n        );\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        handler.activate();\n\n        geo = null;\n        pointsCount = 0;\n        // Using mouse events\n        handler.mousemove(\n                {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mousedown(\n                {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mousemove(\n                {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mousemove(\n                {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 2)});\n        handler.mouseup(\n                {type: \"mouseup\", xy: new OpenLayers.Pixel(2, 2)});\n        t.ok(geo != null, \"feature drawn when mouseup\");\n        t.eq(pointsCount, 2, \"two points have been added\");\n\n        handler.deactivate();\n        var geoMouse = geo;\n        \n        handler.activate();\n        \n        geo = null;\n        pointsCount = 0;\n        // Using touch events\n        handler.touchstart(\n                {type: \"touchstart\", xy: new OpenLayers.Pixel(0, 0)});\n        try {\n            handler.touchmove(\n                    {type: \"touchmove\", xy: new OpenLayers.Pixel(1, 1)});\n            handler.touchmove(\n                    {type: \"touchmove\", xy: new OpenLayers.Pixel(2, 2)});\n            handler.touchend(\n                    {type: \"touchend\"});\n        } catch(err) {\n            t.fail(\"occurred errors using touch events\");\n        }\n        t.ok(geo != null, \"feature drawn when touchend\");\n        t.eq(pointsCount, 2, \"two points have been added\");\n        \n        t.geom_eq(geo, geoMouse, \n            \"geometry obtained using the mouse and touch events are the same\");\n\n        map.destroy();\n    }\n\n    function test_citeComplaint(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map('map');\n        map.addLayer(new OpenLayers.Layer.OSM());\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Path(control, {});\n        control.handler = handler;\n        map.addControl(control);\n        map.zoomToExtent(new OpenLayers.Bounds(-24225034.496992, -11368938.517442, -14206280.326992, -1350184.3474418));\n        handler.activate();\n        handler.createFeature(new OpenLayers.Pixel(100, 50));\n        t.ok(handler.point.geometry.x < 0, \"Geometry started correctly when wrapping the dateline using citeCompliant false\");\n        control.deactivate();\n\n        handler = new OpenLayers.Handler.Path(control, {}, {citeCompliant: true});\n        control.handler = handler;\n        control.activate();\n        handler.createFeature(new OpenLayers.Pixel(100, 50));\n        t.ok(handler.point.geometry.x > 0, \"Geometry started correctly when wrapping the dateline using citeCompliant true\");\n        \n        map.destroy();\n    }\n\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 300px; height: 150px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Handler/Pinch.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    function test_constructor(t) {\n        t.plan(3);\n        var control = new OpenLayers.Control();\n        control.id = Math.random();\n        var callbacks = {foo: \"bar\"};\n        var options = {bar: \"foo\"};\n\n        var oldInit = OpenLayers.Handler.prototype.initialize;\n\n        OpenLayers.Handler.prototype.initialize = function(con, call, opt) {\n            t.eq(con.id, control.id,\n                 \"constructor calls parent with the correct control\");\n            t.eq(call, callbacks,\n                 \"constructor calls parent with the correct callbacks\");\n            t.eq(opt, options,\n                 \"constructor calls parent with the correct options\");\n        };\n        var handler = new OpenLayers.Handler.Pinch(control, callbacks, options);\n\n        OpenLayers.Handler.prototype.initialize = oldInit;\n    }\n\n    function test_activate(t) {\n        t.plan(3);\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Pinch(control);\n        handler.active = true;\n        var activated = handler.activate();\n        t.ok(!activated,\n             \"activate returns false if the handler was already active\");\n        handler.active = false;\n        handler.pinching = true;\n        activated = handler.activate();\n        t.ok(activated,\n             \"activate returns true if the handler was not already active\");\n        t.ok(!handler.pinching,\n             \"activate sets pinching to false\");\n\n    }\n\n    function test_events(t) {\n        // each handled event should be activated twice when handler is\n        // activated, so:\n        // 27 = 4tests * 2*3events + 1tests * 3events\n        t.plan(27);\n\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Pinch(control);\n\n        // list below events that should be handled (events) and those\n        // that should not be handled (nonevents) by the handler\n        var events = [\"touchend\", \"touchmove\", \"touchstart\"];\n        var nonevents = [\"mousedown\", \"mouseup\", \"mousemove\", \"mouseout\",\n        \"click\", \"dblclick\", \"resize\", \"focus\", \"blur\"];\n        map.events.registerPriority = function(type, obj, func) {\n                // this is one of the mock handler methods\n                t.eq(OpenLayers.Util.indexOf(nonevents, type), -1,\n                     \"registered method is not one of the events \" +\n                     \"that should not be handled: \" + type);\n                t.ok(OpenLayers.Util.indexOf(events, type) > -1,\n                     \"activate calls registerPriority with browser event: \" + type);\n                t.eq(typeof func, \"function\",\n                     \"activate calls registerPriority with a function\");\n                t.eq(obj[\"CLASS_NAME\"], \"OpenLayers.Handler.Pinch\",\n                     \"activate calls registerPriority with the handler\");\n        };\n        handler.activate();\n        handler.deactivate();\n\n        // set browser event like properties on the handler\n        for(var i=0; i<events.length; ++i) {\n            setMethod(events[i]);\n        }\n        function setMethod(key) {\n            handler[key] = function() {return key;};\n        }\n\n        map.events.registerPriority = function(type, obj, func) {\n            var r = func();\n            if(typeof r == \"string\") {\n                t.eq(r, type,\n                     \"activate calls registerPriority with the correct method\");\n            }\n        }\n        handler.activate();\n\n    }\n\n    function test_callbacks(t) {\n        t.plan(32);\n\n        var map = new OpenLayers.Map('map', {controls: [], fallThrough: true});\n\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n\n        // set fake values for touches\n        var testEvents = {\n            start: {\n                type: 'touchstart',\n                touches: [{\n                    clientX: 100,\n                    clientY: 0\n                }, {\n                    clientX: 0,\n                    clientY: 0\n                }]\n            },\n            move: {\n                type: 'touchmove',\n                touches: [{\n                    clientX: 100,\n                    clientY: 0\n                }, {\n                    clientX: 20,\n                    clientY: 0\n                }]\n            },\n            done: {\n                type: 'touchend',\n                touches: []\n            }\n        };\n        \n        // set callback methods\n        var customCb = OpenLayers.Function.False;\n        var cb = function(evt) {\n            var callback = evt.type.replace(\"touch\", \"\").replace(\"end\", \"done\");;\n            var tch = testEvents[callback].touches;\n            t.ok(evt.touches[0].clientX == tch[0].clientX &&\n                evt.touches[0].clientY == tch[0].clientY,\n                \"touchstart sets first touch position correctly in evt\");\n            t.ok(evt.touches[1].clientX == tch[1].clientX &&\n                evt.touches[1].clientY == tch[1].clientY,\n                \"touchstart sets second touch position correctly in evt\");\n            t.eq(handler.start.distance, 100, \"start distance is \" +\n                \"always the same\");\n            customCb.apply(this, arguments);\n        }\n        var callbacks = {\n            start: cb,\n            move: cb,\n            done: function () {\n                customCb.apply(this, arguments);\n            }\n        };\n\n        var handler = new OpenLayers.Handler.Pinch(control, callbacks);\n        handler.activate();\n\n        var old_isMultiTouch = OpenLayers.Event.isMultiTouch;\n        var old_stop = OpenLayers.Event.stop;\n        \n        // test single touch\n        OpenLayers.Event.isMultiTouch = function() {\n            return false;\n        }\n        \n        // no callbacks with tests expected (pinch not started)\n        map.events.handleBrowserEvent(testEvents.start);\n        // test 1, 2, 3\n        t.ok(!handler.started, \"1) touchstart (singletouch) sets started to false\");\n        t.eq(handler.start, null, \"1) touchstart (singletouch) sets start to null\");\n        t.eq(handler.last, null, \"1) touchstart (singletouch) sets last to null\");\n        \n        handler.started = true;\n        handler.start = {\n            distance: 100,\n            delta: 0,\n            scale: 1\n        };\n        handler.last = {\n            distance: 150,\n            delta: 10,\n            scale: 1.5\n        };\n        \n        // no callbacks with tests expected (multitouch pinch started, so ignores singletouch)\n        map.events.handleBrowserEvent(testEvents.start);\n        // test 4, 5, 6\n        t.ok(handler.started, \"1) touchstart (singletouch) after pinch started is ignored\");\n        t.ok(!!handler.start, \"1) touchstart (singletouch) after pinch started is ignored\");\n        t.ok(!!handler.last, \"1) touchstart (singletouch) after pinch started is ignored\");\n\n        OpenLayers.Event.stop = function(evt, allowDefault) {\n            if(allowDefault) {\n                t.fail(\n                    \"touchstart is prevented from falling to other elements\");\n            }\n        }\n        OpenLayers.Event.isMultiTouch = function(evt) {\n            var res = old_isMultiTouch(evt);\n            t.ok(res, \"fake event is a mutitouch touch event\");\n            return res;\n        }\n        customCb = function(evt, pinchdata) {\n            t.eq(pinchdata.distance, 100, \"2) calculated distance is correct\");\n            t.eq(pinchdata.delta, 0, \"2) calculated delta is correct\");\n            t.eq(pinchdata.scale, 1, \"2) calculated scale is correct\");\n        }\n        // test 7, 8, 9, 10, 11, 12, 13\n        map.events.handleBrowserEvent(testEvents.start);\n        // test 14, 15\n        t.ok(handler.started, \"2) touchstart sets the started flag to true\");\n        t.ok(!handler.pinching, \"2) touchstart sets the pinching flag to false\");\n\n        customCb = function(evt, pinchdata) {\n            t.eq(pinchdata.distance, 80, \"3) calculated distance is correct\");\n            t.eq(pinchdata.delta, 20, \"3) calculated delta is correct\");\n            t.eq(pinchdata.scale, 0.8, \"3) calculated scale is correct\");\n        }\n        // test 16, 17, 18, 19, 20, 21, 22\n        map.events.handleBrowserEvent(testEvents.move);\n        // test 23, 24\n        t.ok(handler.started, \"3) started flag still set to true\");\n        t.ok(handler.pinching, \"3) touchmove sets the pinching flag to true\");\n\n        OpenLayers.Event.isMultiTouch = old_isMultiTouch;\n        \n        customCb = function(evt, first, last) {\n            t.eq(first.distance, 100, \"4) calculated distance is correct\");\n            t.eq(first.delta, 0, \"4) calculated delta is correct\");\n            t.eq(first.scale, 1, \"4) calculated scale is correct\");\n            t.eq(last.distance, 80, \"4) calculated distance is correct\");\n            t.eq(last.delta, 20, \"4) calculated delta is correct\");\n            t.eq(last.scale, 0.8, \"4) calculated scale is correct\");\n        }\n        // test 25, 26, 27, 28, 29, 30\n        map.events.handleBrowserEvent(testEvents.done);\n        // test 31, 32\n        t.ok(!handler.started, \"4) started flag is set to false\");\n        t.ok(!handler.pinching, \"4) touchdone sets the pinching flag to false\");\n\n        OpenLayers.Event.stop = old_stop;\n\n        // test move or done before start\n        customCb = function(evt) {\n            t.fail(\"should not pass here\")\n        }\n        // no callbacks with tests expected\n        map.events.handleBrowserEvent(testEvents.move);\n        map.events.handleBrowserEvent(testEvents.done);\n\n    }\n\n    function test_deactivate(t) {\n        t.plan(6);\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Pinch(control);\n        handler.active = false;\n        var deactivated = handler.deactivate();\n        t.ok(!deactivated,\n             \"deactivate returns false if the handler was not already active\");\n        handler.active = true;\n        handler.pinching = true;\n        deactivated = handler.deactivate();\n        t.ok(deactivated,\n             \"deactivate returns true if the handler was active already\");\n        t.ok(!handler.started,\n             \"deactivate sets started to false\");\n        t.ok(!handler.pinching,\n             \"deactivate sets pinching to false\");\n        t.ok(handler.start == null,\n             \"deactivate sets start to null\");\n        t.ok(handler.last == null,\n             \"deactivate sets start to null\");\n    }\n\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 300px; height: 150px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Handler/Point.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    function test_Handler_Point_constructor(t) {\n        t.plan(3);\n        var control = new OpenLayers.Control();\n        control.id = Math.random();\n        var callbacks = {foo: \"bar\"};\n        var options = {bar: \"foo\"};\n        \n        var oldInit = OpenLayers.Handler.prototype.initialize;\n        \n        OpenLayers.Handler.prototype.initialize = function(con, call, opt) {\n            t.eq(con.id, control.id,\n                 \"constructor calls parent with the correct control\");\n            t.eq(call, callbacks,\n                 \"constructor calls parent with the correct callbacks\");\n            t.eq(opt, options,\n                 \"constructor calls parent with the correct options\");\n        }\n        var handler = new OpenLayers.Handler.Point(control, callbacks, options);\n\n        OpenLayers.Handler.prototype.initialize = oldInit;\n    }\n\n    function test_Handler_Point_activation(t) {\n        t.plan(6);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control();\n        var handler = new OpenLayers.Handler.Point(control, {});\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        handler.active = true;\n        var activated = handler.activate();\n        t.ok(!activated,\n             \"activate returns false if the handler was already active\");\n        handler.active = false;\n        activated = handler.activate();\n        t.ok(activated,\n             \"activate returns true if the handler was not already active\");\n        t.ok(handler.layer instanceof OpenLayers.Layer.Vector,\n             \"activate creates a vector layer\");\n        t.ok(handler.layer.map == map,\n             \"activate adds the vector layer to the map\");\n        activated = handler.deactivate();\n        t.ok(activated,\n             \"deactivate returns true if the handler was active already\");\n        var failed = false;\n        try {\n            handler.finalize();\n            msg = \"finalizing after deactivation does not throw an error\";\n        } catch (err) {\n            failed = true;\n            msg = \"finalizing after deactivation throws an error\";\n        }\n        t.ok(!failed, msg);\n        map.destroy();\n    }\n\n    // http://trac.osgeo.org/openlayers/ticket/3179\n    function test_activate_before_map_is_centered(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map('map', {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control();\n        var handler = new OpenLayers.Handler.Point(control, {});\n        control.handler = handler;\n        map.addControl(control);\n\n        var error;\n        try {\n            handler.activate();\n            error = false;\n        } catch(err) {\n            error = true;\n        }\n        t.ok(!error, \"no error on activate\");\n    }\n\n    function test_Handler_Point_events(t) {\n        t.plan(49);\n        var log = [];\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control();\n        var handler = new OpenLayers.Handler.Point(control, {\n            \"create\": function(g, f) {\n                log.push({geometry: g, feature: f});\n            }\n        });\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        // list below events that should be handled (events) and those\n        // that should not be handled (nonevents) by the handler\n        var events = [\"click\", \"dblclick\", \"mousedown\", \"mouseup\", \"mousemove\", \"mouseout\", \"touchstart\", \"touchmove\", \"touchend\"];\n        var nonevents = [\"resize\", \"focus\", \"blur\"];\n        map.events.registerPriority = function(type, obj, func) {\n            var r = func();\n            if(typeof r == \"string\") {\n                // this is one of the mock handler methods\n                t.eq(OpenLayers.Util.indexOf(nonevents, type), -1,\n                     \"registered method is not one of the events \" +\n                     \"that should not be handled\");\n                t.ok(OpenLayers.Util.indexOf(events, type) > -1,\n                     \"activate calls registerPriority with browser event: \" + type);\n                t.eq(typeof func, \"function\",\n                     \"activate calls registerPriority with a function\");\n                t.eq(func(), type,\n                     \"activate calls registerPriority with the correct method\");\n                t.eq(obj[\"CLASS_NAME\"], \"OpenLayers.Handler.Point\",\n                     \"activate calls registerPriority with the handler\");\n            }\n        }\n        \n        // set browser event like properties on the handler\n        for(var i=0; i<events.length; ++i) {\n            setMethod(events[i]);\n        }\n        function setMethod(key) {\n            handler[key] = function() {return key};\n        }\n\n        var activated = handler.activate();\n        handler.destroy();\n\n        // test that click and dblclick are stopped\n        var handler = new OpenLayers.Handler.Point(control);\n        var oldStop = OpenLayers.Event.stop;\n        OpenLayers.Event.stop = function(evt) {\n            t.ok(evt.type == \"click\" || evt.type == \"dblclick\",\n                 evt.type + \" stopped\");\n        }\n        t.eq(handler.click({type: \"click\"}), false, \"click returns false\");\n        t.eq(handler.dblclick({type: \"dblclick\"}), false, \"dblclick returns false\");\n        OpenLayers.Event.stop = oldStop;\n\n    }\n    \n    function test_callbacks(t) {\n        t.plan(24);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var logs = [], log;\n        var handler = new OpenLayers.Handler.Point(control, {\n            create: function() {\n                logs.push({type: \"create\", args: arguments});\n            },\n            modify: function() {\n                logs.push({type: \"modify\", args: arguments});\n            },\n            done: function() {\n                logs.push({type: \"done\", args: arguments});\n            },\n            cancel: function() {\n                logs.push({type: \"cancel\", args: arguments});\n            }\n        },\n        {\n            pixelTolerance: 0,\n            dblclickTolerance: 0\n        });\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n        \n        handler.activate();\n\n        // mouse down\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0)});\n        t.eq(logs.length, 2, \"[mousedown] called back twice\");\n        log = logs.shift();\n        t.eq(log.type, \"create\", \"[mousedown] create called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-150, 75),\n                  \"[mousedown] correct point\");\n        t.geom_eq(log.args[1].geometry,\n                  new OpenLayers.Geometry.Point(-150, 75),\n                  \"[mousedown] correct feature\");\n        log = logs.shift();\n        t.eq(log.type, \"modify\", \"[mousedown] modify called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-150, 75),\n                  \"[mousedown] correct point\");\n        t.geom_eq(log.args[1].geometry,\n                  new OpenLayers.Geometry.Point(-150, 75),\n                  \"[mousedown] correct feature\");\n        // mouse move\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 0)});\n        t.eq(logs.length, 0, \"[mousemove] not called back\");\n        // mouse up (no finalize - we moved)\n        handler.mouseup({type: \"mouseup\", xy: new OpenLayers.Pixel(1, 0)});\n        t.eq(logs.length, 0, \"[mouseup] not called back\");\n        // mouse move\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 0)});\n        t.eq(logs.length, 1, \"[mousemove] called back\");\n        log = logs.shift();\n        t.eq(log.type, \"modify\", \"[mousemove] modify called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-148, 75),\n                  \"[mousemove] correct point\");\n        t.geom_eq(log.args[1].geometry,\n                  new OpenLayers.Geometry.Point(-148, 75),\n                  \"[mousemove] correct feature\");\n        // mouse down\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(2, 0)});\n        t.eq(logs.length, 1, \"[mousedown] called back\");\n        log = logs.shift();\n        t.eq(log.type, \"modify\", \"[mousedown] modify called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-148, 75),\n                  \"[mousedown] correct point\");\n        t.geom_eq(log.args[1].geometry,\n                  new OpenLayers.Geometry.Point(-148, 75),\n                  \"[mousedown] correct feature\");\n        // mouse up\n        handler.mouseup({type: \"mouseup\", xy: new OpenLayers.Pixel(2, 0)});\n        t.eq(logs.length, 1, \"[mouseup] called back\");\n        log = logs.shift();\n        t.eq(log.type, \"done\", \"[mouseup] done called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-148, 75),\n                  \"[mouseup] correct point\");\n        // mouse up on same pixel\n        handler.mouseup({type: \"mouseup\", xy: new OpenLayers.Pixel(2, 0)});\n        t.eq(logs.length, 0, \"[mouseup] not called back\");\n        // cancel\n        handler.cancel();\n        t.eq(logs.length, 1, \"[cancel] called back\");\n        log = logs.shift();\n        t.eq(log.type, \"cancel\", \"[cancel] cancel called\");\n        t.eq(log.args[0], null, \"[cancel] got null\");\n\n        map.destroy();\n    }\n\n    function test_persist(t) {\n        t.plan(3);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Point(control, {});\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n        \n        handler.activate();\n\n        handler.persist = false;\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0)});\n        t.eq(handler.layer.features.length, 0,\n             \"feature destroyed on mouseup when persist is false\");\n\n        handler.persist = true;\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(1, 0)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(1, 0)});\n        t.eq(handler.layer.features.length, 1,\n             \"feature not destroyed on mouseup when persist is true\");\n        var feature = handler.layer.features[0];\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(2, 0)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(2, 0)});\n        t.ok(handler.layer.features[0] !== feature,\n             \"persisted feature destroyed on next mouseup\");\n\n        map.destroy();\n    }\n\n\n    function test_Handler_Point_deactivation(t) {\n        t.plan(5);\n        var log = [];\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control();\n        var handler = new OpenLayers.Handler.Point(control, {\n            \"cancel\": function(g) {\n                log.push({geometry: g});\n            }\n        });\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        handler.activate();\n        handler.mousemove({xy: new OpenLayers.Pixel(0, 0)});\n        var _layer = handler.layer;\n        var _geometry = handler.point.geometry;\n        handler.deactivate();\n        t.eq(_layer.map, null,\n             \"deactivates removes the layer from the map\");\n        t.eq(handler.layer, null,\n             \"deactivates sets its \\\"layer\\\" property to null\");\n        t.eq(log.length, 1,\n             \"deactivates calls \\\"cancel\\\" once\");\n        t.ok(log[0].geometry.equals(_geometry),\n             \"\\\"cancel\\\" called with expected geometry\");\n\n        handler.activate();\n        handler.layer.destroy();\n        handler.deactivate();\n        t.eq(handler.layer, null,\n             \"deactivate doesn't throw an error if layer was\" +\n             \" previously destroyed\");\n\n        map.destroy();\n    }\n\n    function test_Handler_Point_bounds(t) {\n        t.plan(4);\n        var map = new OpenLayers.Map('map');\n        map.addLayer(new OpenLayers.Layer.WMS(\"\", \"\", {}));\n        map.zoomToMaxExtent();\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Point(control, {});\n        var activated = handler.activate();\n        var px = new OpenLayers.Pixel(150, 75);\n        var evt = {xy: px, which: 1};\n        handler.mousemove(evt);\n        var lonlat = map.getLonLatFromPixel(px);\n        t.eq(handler.point.geometry.x, lonlat.lon, \"X is correct\"); \n        t.eq(handler.point.geometry.y, lonlat.lat, \"Y is correct\"); \n        t.ok(handler.point.geometry.getBounds().equals(new OpenLayers.Bounds(lonlat.lon,lonlat.lat,lonlat.lon,lonlat.lat)), \"Correct bounds\"); \n        var evt = {xy: new OpenLayers.Pixel(175, 100), which: 1};\n        handler.mousemove(evt);\n        t.ok(!handler.point.geometry.getBounds().equals(new OpenLayers.Bounds(0,0,0,0)), \"Bounds changed after moving mouse\"); \n    }     \n        \n    function test_Handler_Point_destroy(t) {\n        t.plan(4);\n        var map = new OpenLayers.Map('map');\n        map.addLayer(new OpenLayers.Layer.WMS(\"\", \"\", {}));\n        map.zoomToMaxExtent();\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Point(control, {foo: 'bar'});\n\n        handler.activate();\n        handler.mousemove({xy: new OpenLayers.Pixel(150, 75)});\n\n        t.ok(handler.layer,\n             \"handler has a layer prior to destroy\");\n        t.ok(handler.point,\n             \"handler has a point prior to destroy\");\n        handler.destroy();\n        t.eq(handler.layer, null,\n             \"handler.layer is null after destroy\");\n        t.eq(handler.point, null,\n             \"handler.point is null after destroy\");\n    }\n\n    function test_touchstart(t) {\n        // a test to verify that the touchstart function does\n        // unregister the mouse listeners when it's called the\n        // first time\n\n        t.plan(4);\n\n        // set up\n\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1],\n            controls: []\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Point(control, {});\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n        handler.activate();\n\n        var eventTypes = ['mousedown', 'mouseup', 'mousemove', 'click', 'dblclick',\n                'mouseout'];\n\n        function allRegistered() {\n            var eventType,\n                listeners,\n                listener,\n                flag;\n            for(var i=0, ilen=eventTypes.length; i<ilen; i++) {\n                flag =  false;\n                eventType = eventTypes[i];\n                listeners = map.events.listeners[eventType];\n                for(var j=0, jlen=listeners.length; j<jlen; j++) {\n                    listener = listeners[j];\n                    if(listener.func === handler[eventType] && listener.obj === handler) {\n                        flag = true;\n                        break;\n                    }\n                }\n                if(!flag) {\n                    return false;\n                }\n            }\n            return true;\n        }\n\n        function noneRegistered() {\n            var eventType,\n                times,\n                flag = false;\n            for(var i=0, ilen=eventTypes.length; i<ilen; i++) {\n                eventType = eventTypes[i];\n                times = map.events.listeners[eventType].length;\n                if (times != 0) {\n                    t.fail(eventType + \" is registered \" + times + \" times\");\n                    flag = true;\n                }\n            }\n            return !flag;\n        }\n\n\n        // test\n\n        t.ok(allRegistered(), 'mouse listeners are registered');\n        handler.touchstart({xy: new OpenLayers.Pixel(0, 0)});\n        t.ok(noneRegistered(), 'mouse listeners are unregistered');\n        t.ok(handler.touch, 'handler.touch is set');\n\n        handler.deactivate();\n        t.ok(!handler.touch, 'handler.touch is not set');\n\n        // tear down\n\n        map.destroy();\n    }\n\n\n    //\n    // Sequence tests\n    // \n    // Sequence tests basically involve executing a sequence of events\n    // and testing the resulting geometry.\n    //\n    // Below are tests for various drawing sequences. Tests can be\n    // added here each a non-working sequence is found.\n    //\n\n    // tap\n    function test_touch_sequence1(t) {\n        t.plan(8);\n\n        // set up\n\n        var log;\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Point(control, {\n            done: function(g, f) {\n                log = {geometry: g, feature: f};\n            }\n        });\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n        handler.activate();\n\n        // test\n\n        var ret;\n\n        // tap on (1, 0)\n        log = null;\n        ret = handler.touchstart({xy: new OpenLayers.Pixel(0, 0)});\n        t.ok(ret, '[touchstart] event propagates');\n        t.eq(log, null, '[touchstart] no finalization');\n        t.eq(handler.point, null, '[touchstart] feature not modified');\n        ret = handler.touchmove({xy: new OpenLayers.Pixel(1, 0)});\n        t.ok(ret, '[touchmove] event propagates');\n        t.eq(log, null, '[touchmove] no finalization');\n        t.eq(handler.point, null, '[touchmove] feature not modified');\n        ret = handler.touchend({});\n        t.ok(ret, '[touchend] event propagates');\n        t.geom_eq(log.geometry, new OpenLayers.Geometry.Point(-149, 75),\n                  \"[touchend] correct point\");\n        // tear down\n\n        map.destroy();\n    }\n\n    // tap-move\n    function test_touch_sequence2(t) {\n        t.plan(9);\n\n        // set up\n\n        var log;\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Point(control, {\n            done: function(g, f) {\n                log = {geometry: g, feature: f};\n            }\n        });\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n        handler.activate();\n\n        // test\n\n        var ret;\n\n        // tap-move (0, 0) -> (9, 0)\n        log = null;\n        ret = handler.touchstart({xy: new OpenLayers.Pixel(0, 0)});\n        t.ok(ret, '[touchstart] event propagates');\n        t.eq(log, null, '[touchstart] no finalization');\n        t.eq(handler.point, null, null,\n             '[touchstart] feature not modified');\n        ret = handler.touchmove({xy: new OpenLayers.Pixel(9, 0)});\n        t.ok(ret, '[touchmove] event propagates');\n        t.eq(log, null, '[touchmove] no finalization');\n        t.eq(handler.point, null,\n             '[touchmove] feature not modified');\n        ret = handler.touchend({});\n        t.ok(ret, '[touchend] event propagates');\n        t.eq(log, null, '[touchend] no finalization');\n        t.eq(handler.point, null,\n             '[touchend] feature not modified');\n\n        // tear down\n\n        map.destroy();\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 300px; height: 150px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Handler/Polygon.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    function test_Handler_Polygon_constructor(t) {\n        t.plan(3);\n        var control = new OpenLayers.Control();\n        control.id = Math.random();\n        var callbacks = {foo: \"bar\"};\n        var options = {bar: \"foo\"};\n\n        var oldInit = OpenLayers.Handler.prototype.initialize;\n\n        OpenLayers.Handler.prototype.initialize = function(con, call, opt) {\n            t.eq(con.id, control.id,\n                 \"constructor calls parent with the correct control\");\n            t.eq(call, callbacks,\n                 \"constructor calls parent with the correct callbacks\");\n            t.eq(opt, options,\n                 \"constructor calls parent with the correct options\");\n        }\n        var handler = new OpenLayers.Handler.Polygon(control, callbacks, options);\n\n        OpenLayers.Handler.prototype.initialize = oldInit;\n    }\n\n    function test_Handler_Polygon_activation(t) {\n        t.plan(5);\n        var log = [];\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control();\n        var handler = new OpenLayers.Handler.Polygon(control, {});\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n        handler.active = true;\n\n        var activated = handler.activate();\n        t.ok(!activated,\n             \"activate returns false if the handler was already active\");\n        handler.active = false;\n        activated = handler.activate();\n        t.ok(activated,\n             \"activate returns true if the handler was not already active\");\n        t.ok(handler.layer instanceof OpenLayers.Layer.Vector,\n             \"activate creates a vector layer\");\n        t.ok(handler.layer.map == map,\n             \"activate adds the vector layer to the map\");\n        activated = handler.deactivate();\n        t.ok(activated,\n             \"deactivate returns true if the handler was active already\");\n\n        map.destroy();\n    }\n\n    // See: http://trac.osgeo.org/openlayers/ticket/3179\n    function test_activate_before_map_is_centered(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map('map', {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control();\n        var handler = new OpenLayers.Handler.Polygon(control, {});\n        control.handler = handler;\n        map.addControl(control);\n\n        var error;\n        try {\n            handler.activate();\n            error = false;\n        } catch(err) {\n            error = true;\n        }\n        t.ok(!error, \"no error on activate\");\n    }\n\n    function test_bounds_stopDown_true(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map('map');\n        map.addLayer(new OpenLayers.Layer.WMS(\"\", \"\", {}));\n        map.zoomToMaxExtent();\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Polygon(control, {},\n                {stopDown: true, stopUp: true});\n        var activated = handler.activate();\n        // click on (150, 75)\n        var evt = {xy: new OpenLayers.Pixel(150, 75), which: 1};\n        handler.mousemove(evt);\n        handler.mousedown(evt);\n        handler.mouseup(evt);\n        // click on (175, 100)\n        evt = {xy: new OpenLayers.Pixel(175, 100), which: 1};\n        handler.mousemove(evt);\n        handler.mousedown(evt);\n        handler.mouseup(evt);\n        t.ok(handler.line.geometry.getBounds().equals(new OpenLayers.Bounds(0,-35.15625,35.15625,0)), \"Correct bounds\");\n        // mousedown on (175, 100)\n        evt = {xy: new OpenLayers.Pixel(175, 100), which: 1};\n        handler.mousedown(evt);\n        // mousemove to (125, 100)\n        evt = {xy: new OpenLayers.Pixel(125, 100), which: 1};\n        handler.mousemove(evt);\n        // test that the bounds have changed\n        t.ok(!handler.polygon.geometry.getBounds().equals(new OpenLayers.Bounds(0,-35.15625,35.15625,0)),\n             \"Correct bounds after dragging without letting go. (Came out as \"+handler.line.geometry.getBounds().toBBOX() + \".)\");\n        map.destroy();     \n    }\n\n    function test_callbacks(t) {\n        t.plan(39);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({\n        });\n        var logs = [], log;\n        var handler = new OpenLayers.Handler.Polygon(control, {\n            create: function() {\n                logs.push({type: \"create\", args: arguments});\n            },\n            point: function() {\n                logs.push({type: \"point\", args: arguments});\n            },\n            modify: function() {\n                logs.push({type: \"modify\", args: arguments});\n            },\n            done: function() {\n                logs.push({type: \"done\", args: arguments});\n            },\n            cancel: function() {\n                logs.push({type: \"cancel\", args: arguments});\n            }\n        },\n        {\n            pixelTolerance: 0\n        });\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n        \n        // create polygon\n        handler.activate();\n\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        t.eq(logs.length, 2, \"[mousemove] called back\");\n        log = logs.shift();\n        t.eq(log.type, \"create\", \"[activate] create called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-150, 75),\n                  \"[mousemove] correct point\");\n        t.ok(log.args[1] == handler.polygon,\n             \"[mousemove] correct feature\");\n        log = logs.shift();\n        t.eq(log.type, \"modify\", \"[mousemove] modify called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-150, 75),\n                  \"[mousemove] correct point\");\n        t.ok(log.args[1] === handler.polygon,\n             \"[mousemove] correct feature\");\n        // mouse down\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0)});\n        t.eq(logs.length, 1, \"[mousedown] called back\");\n        log = logs.shift();\n        t.eq(log.type, \"modify\", \"[mousedown] modify called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-150, 75),\n                  \"[mousedown] correct point\");\n        t.ok(log.args[1] === handler.polygon,\n             \"[mousedown] correct feature\");\n        // mouse up\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0)});\n        t.eq(logs.length, 2, \"[mouseup] called back twice\");\n        log = logs.shift();\n        t.eq(log.type, \"point\", \"[mouseup] point called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-150, 75),\n                  \"[mouseup] correct point\");\n        var geom = new OpenLayers.Geometry.Polygon([\n            new OpenLayers.Geometry.LinearRing([\n                new OpenLayers.Geometry.Point(-150, 75)\n            ])\n        ]);\n        geom.components[0].addComponent(\n            new OpenLayers.Geometry.Point(-150, 75),\n            geom.components[0].components.length\n        );\n        t.geom_eq(log.args[1], geom, \"[mouseup] correct polygon\");\n        log = logs.shift();\n        t.eq(log.type, \"modify\", \"[mouseup] modify called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-150, 75),\n                  \"[mouseup] correct point\");\n        t.ok(log.args[1] == handler.polygon,\n             \"[mouseup] correct feature\");\n        // mouse move\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(10, 10)});\n        t.eq(logs.length, 1, \"[mousemove] called back\");\n        log = logs.shift();\n        t.eq(log.type, \"modify\", \"[mousemove] modify called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-140, 65),\n                  \"[mousemove] correct point\");\n        t.ok(log.args[1] === handler.polygon,\n             \"[mousemove] correct feature\");\n        // mouse down\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(10, 10)});\n        t.eq(logs.length, 1, \"[mousedown] called back\");\n        log = logs.shift();\n        t.eq(log.type, \"modify\", \"[mousedown] modify called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-140, 65),\n                  \"[mousedown] correct point\");\n        t.ok(log.args[1] === handler.polygon,\n             \"[mousedown] correct feature\");\n        // mouse up\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(10, 10)});\n        log = logs.shift();\n        log = logs.shift();\n        // move to 0, 10 and double click\n        // mouse move\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 10)});\n        t.eq(logs.length, 1, \"[mousemove] called back\");\n        log = logs.shift();\n        t.eq(log.type, \"modify\", \"[mousemove] modify called\");\n        t.geom_eq(log.args[0], new OpenLayers.Geometry.Point(-150, 65),\n                  \"[mousemove] correct point\");\n        t.ok(log.args[1] === handler.polygon,\n             \"[mousemove] correct feature\");\n        // mouse down\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 10)});\n        t.eq(logs.length, 1, \"[mousedown] not called back\");\n        log = logs.shift();\n        // mouse up\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 10)});\n        t.eq(logs.length, 2, \"[mouseup] called back\");\n        log = logs.shift();\n        log = logs.shift();\n        // mouse down\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 10)});\n        t.eq(logs.length, 0, \"[mousedown] not called back\");\n        // mouse up\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 10)});\n        t.eq(logs.length, 0, \"[mouseup] not called back\");\n        // dblclick\n        handler.dblclick(\n            {type: \"dblclick\", xy: new OpenLayers.Pixel(0, 10)});\n        t.eq(logs.length, 1, \"[dblclick] called back\");\n        log = logs.shift();\n        t.eq(log.type, \"done\", \"[dblclick] done called\");\n        t.geom_eq(\n            log.args[0],\n            new OpenLayers.Geometry.Polygon([\n                new OpenLayers.Geometry.LinearRing([\n                    new OpenLayers.Geometry.Point(-150, 75),\n                    new OpenLayers.Geometry.Point(-140, 65),\n                    new OpenLayers.Geometry.Point(-150, 65),\n                    new OpenLayers.Geometry.Point(-150, 75)\n                ])\n            ]),\n            \"[dblclick] correct polygon\"\n        );\n        // cancel\n        handler.cancel();\n        t.eq(logs.length, 1, \"[cancel] called back\");\n        log = logs.shift();\n        t.eq(log.type, \"cancel\", \"[cancel] canced called\");\n\n        map.destroy();\n    }        \n\n    function test_toggle_freehand(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Polygon(control, {\n            done: function(g) {\n                log++;\n            }\n        }, {persist: true});\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        handler.activate();\n\n        log = 0;\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 2), shiftKey: true});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0), shiftKey: true});\n        t.eq(log, 1, \"feature drawn when shift pressed on mousedown\");\n\n        log = 0;\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0), shiftKey: false});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 2), shiftKey: true});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0), shiftKey: true});\n        t.eq(log, 0, \"feature not drawn when shift not pressed on mousedown\");\n    }\n\n    function test_persist(t) {\n        t.plan(4);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Polygon(control, {});\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        handler.activate();\n\n        handler.persist = false;\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        var feature1 = handler.polygon;\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 2)});\n        handler.dblclick(\n            {type: \"dblclick\", xy: new OpenLayers.Pixel(2, 2)});\n        t.ok(feature1.layer == null, \"a) feature1 destroyed\");\n\n        handler.persist = true;\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        var feature2 = handler.polygon;\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 2)});\n        handler.dblclick(\n            {type: \"dblclick\", xy: new OpenLayers.Pixel(2, 2)});\n        t.ok(feature2.layer != null, \"b) feature2 not destroyed\");\n\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        var feature3 = handler.polygon;\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 2)});\n        handler.dblclick(\n            {type: \"dblclick\", xy: new OpenLayers.Pixel(2, 2)});\n        t.ok(feature3.layer != null, \"c) feature3 not destroyed\");\n        t.ok(feature2.layer == null, \"c) feature2 destroyed\");\n\n        map.destroy();\n    }\n\n    function test_persist_freehand(t) {\n        t.plan(6);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Polygon(control, {});\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        handler.activate();\n\n        handler.persist = false;\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        var feature1 = handler.polygon;\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 2), shiftKey: true});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(2, 2), shiftKey: true});\n        t.ok(feature1.layer == null, \"a) feature1 destroyed\");\n\n        handler.persist = true;\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        var feature2 = handler.polygon;\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 2), shiftKey: true});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(2, 2), shiftKey: true});\n        t.ok(feature2.layer != null, \"b) feature2 not destroyed\");\n\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        var feature3 = handler.polygon;\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 2), shiftKey: true});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(2, 2), shiftKey: true});\n        t.ok(feature3.layer != null, \"c) feature3 not destroyed\");\n        t.ok(feature2.layer == null, \"c) feature2 destroyed\");\n\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        feature4 = handler.polygon;\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0), shiftKey: false});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1), shiftKey: true});\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(2, 2), shiftKey: true});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0), shiftKey: true});\n        t.ok(feature4.layer != null, \"d) feature4 not destroyed\");\n        t.ok(feature3.layer == null, \"c) feature3 destroyed\");\n\n        map.destroy();\n    }\n\n    function test_rings(t) {\n        t.plan(12);\n\n        var log = [];\n        var map = new OpenLayers.Map({\n            div: \"map\",\n            resolutions: [1],\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            layers: [\n                new OpenLayers.Layer.Vector(null, {\n                    isBaseLayer: true,\n                    eventListeners: {\n                        featureadded: function(event) {\n                            log.push(event);\n                        },\n                        sketchmodified: function(event) {\n                            log.push(event);\n                        },\n                        sketchcomplete: function(event) {\n                            log.push(event);\n                        }\n                    }\n                })\n            ],\n            center: new OpenLayers.LonLat(0, 0),\n            zoom: 0\n        });\n        \n        // create control for drawing polygons with holes\n        var draw = new OpenLayers.Control.DrawFeature(\n            map.layers[0],\n            OpenLayers.Handler.Polygon,\n            {handlerOptions: {\n                holeModifier: \"altKey\",\n                pixelTolerance: 0\n            }}\n        );\n        map.addControl(draw);\n        draw.activate();\n        \n        var event;\n        function trigger(type, event) {\n            map.events.triggerEvent(type, OpenLayers.Util.extend({}, event));\n        }\n        \n        // a) draw a polygon\n        log = [];\n        // start at -9, 9\n        event = {xy: new OpenLayers.Pixel(-9, 9)};\n        trigger(\"mousemove\", event);\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        // draw to -1, 9\n        event = {xy: new OpenLayers.Pixel(-1, 9)};\n        trigger(\"mousemove\", event);\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        // draw to -1, 1\n        event = {xy: new OpenLayers.Pixel(-1, 1)};\n        trigger(\"mousemove\", event);\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        // draw to -9, 1\n        event = {xy: new OpenLayers.Pixel(-9, 1)};\n        trigger(\"mousemove\", event);\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        // finish\n        event = {xy: new OpenLayers.Pixel(-9, 1)};\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        trigger(\"dblclick\", event);\n        \n        // make assertions\n        t.eq(log.length, 14, \"a) correct number of events\");\n        t.eq(log[log.length-1].type, \"featureadded\", \"a) featureadded event last\");\n        t.eq(log[log.length-1].feature.geometry.getArea(), 64, \"a) correct polygon area\");\n\n        // b) draw a hole\n        log = [];\n        // start at -6, 6\n        event = {xy: new OpenLayers.Pixel(-6, 6), altKey: true};\n        trigger(\"mousemove\", event);\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        // draw to -3, 6\n        event = {xy: new OpenLayers.Pixel(-3, 6), altKey: true};\n        trigger(\"mousemove\", event);\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        // draw to -3, 3\n        event = {xy: new OpenLayers.Pixel(-3, 3), altKey: true};\n        trigger(\"mousemove\", event);\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        // draw to -6, 3\n        event = {xy: new OpenLayers.Pixel(-6, 3), altKey: true};\n        trigger(\"mousemove\", event);\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        // finish\n        event = {xy: new OpenLayers.Pixel(-6, 3), altKey: true};\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        trigger(\"dblclick\", event);\n        \n        // make assertions\n        t.eq(log.length, 13, \"b) correct number of events\");\n        t.eq(log[log.length-1].type, \"sketchcomplete\", \"b) sketchcomplete event last\");\n        t.eq(log[log.length-1].feature.geometry.getArea(), 55, \"b) correct polygon area\");\n        \n\n        // c) draw a polygon that overlaps the first\n        log = [];\n        // start at -2, 2\n        event = {xy: new OpenLayers.Pixel(-2, 2)};\n        trigger(\"mousemove\", event);\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        // draw to 2, 2\n        event = {xy: new OpenLayers.Pixel(2, 2)};\n        trigger(\"mousemove\", event);\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        // draw to 2, -2\n        event = {xy: new OpenLayers.Pixel(2, -2)};\n        trigger(\"mousemove\", event);\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        // draw to -2, -2\n        event = {xy: new OpenLayers.Pixel(-2, -2)};\n        trigger(\"mousemove\", event);\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        // finish\n        event = {xy: new OpenLayers.Pixel(-2, -2)};\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        trigger(\"dblclick\", event);\n        \n        // make assertions\n        t.eq(log.length, 14, \"c) correct number of events\");\n        t.eq(log[log.length-1].type, \"featureadded\", \"c) featureadded event last\");\n        t.eq(log[log.length-1].feature.geometry.getArea(), 16, \"c) correct polygon area\");\n\n        // d) draw a hole that tries to go outside the exterior ring\n        log = [];\n        // start at -1, 1\n        event = {xy: new OpenLayers.Pixel(-1, 1), altKey: true};\n        trigger(\"mousemove\", event);\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        // draw to 1, 1\n        event = {xy: new OpenLayers.Pixel(1, 1), altKey: true};\n        trigger(\"mousemove\", event);\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        // try to draw to -8, 8 (ouside active polygon)\n        event = {xy: new OpenLayers.Pixel(-8, 8), altKey: true};\n        trigger(\"mousemove\", event);\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        // draw to 1, -1\n        event = {xy: new OpenLayers.Pixel(1, -1), altKey: true};\n        trigger(\"mousemove\", event);\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        // draw to -1, -1\n        event = {xy: new OpenLayers.Pixel(-1, -1), altKey: true};\n        trigger(\"mousemove\", event);\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        // finish\n        event = {xy: new OpenLayers.Pixel(-1, 1), altKey: true};\n        trigger(\"mousedown\", event);\n        trigger(\"mouseup\", event);\n        trigger(\"dblclick\", event);\n        \n        // make assertions\n        t.eq(log.length, 18, \"d) correct number of events\");\n        t.eq(log[log.length-1].type, \"sketchcomplete\", \"d) sketchcomplete event last\");\n        t.eq(log[log.length-1].feature.geometry.getArea(), 12, \"d) correct polygon area\");\n        \n        \n        map.destroy();\n    }        \n\n    function test_Handler_Polygon_destroy(t) {\n        t.plan(8);\n        var map = new OpenLayers.Map('map');\n        map.addLayer(new OpenLayers.Layer.WMS(\"\", \"\", {}));\n        map.zoomToMaxExtent();\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.Polygon(control, {foo: 'bar'});\n\n        handler.activate();\n        var evt = {xy: new OpenLayers.Pixel(150, 75), which: 1};\n        handler.mousedown(evt);\n\n        t.ok(handler.layer,\n             \"handler has a layer prior to destroy\");\n        t.ok(handler.point,\n             \"handler has a point prior to destroy\");\n        t.ok(handler.line,\n             \"handler has a line prior to destroy\");\n        t.ok(handler.polygon,\n             \"handler has a polygon prior to destroy\");\n        handler.destroy();\n        t.eq(handler.layer, null,\n             \"handler.layer is null after destroy\");\n        t.eq(handler.point, null,\n             \"handler.point is null after destroy\");\n        t.eq(handler.line, null,\n             \"handler.line is null after destroy\");\n        t.eq(handler.polygon, null,\n             \"handler.polygon is null after destroy\");\n        map.destroy();     \n    }\n\n    function test_insertXY(t) {\n        t.plan(3);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control.DrawFeature(\n            layer, OpenLayers.Handler.Polygon\n        );\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        control.activate();\n        var handler = control.handler;\n        \n        function userClick(x, y) {\n            var px = new OpenLayers.Pixel(x, y);\n            handler.mousemove({type: \"mousemove\", xy: px});\n            handler.mousedown({type: \"mousedown\", xy: px});\n            handler.mouseup({type: \"mouseup\", xy: px});\n        }\n\n        // add points at px(0, 0) and px(10, 10)\n        userClick(0, 0);\n        userClick(10, 10);\n        t.eq(handler.line.geometry.components.length, 4, \"ring has four points after two clicks\");\n        \n        // programmatically add a point\n        handler.insertXY(5, 6);\n        t.eq(handler.line.geometry.components.length, 5, \"ring has five points after insertXY\");\n        t.geom_eq(\n            handler.line.geometry.components[2],\n            new OpenLayers.Geometry.Point(5, 6),\n            \"third point comes from insertXY\"\n        );\n        \n        map.destroy();\n        \n    }\n\n    //\n    // Sequence tests\n    // \n    // Sequence tests basically involve executing a sequence of events\n    // and testing the resulting geometry.\n    //\n    // Below are tests for various drawing sequences. Tests can be\n    // added here each a non-working sequence is found.\n    //\n\n    // stopDown:true, stopUp:true\n    // a) click on (0, 0)\n    // b) mousedown on (0.5, 0.5)\n    // c) mouseup on (1, 1)\n    // d) click on (0, 10)\n    // e) dblclick on (10, 10)\n    function test_sequence1(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Polygon(control,\n            {done: function(g) { log.geometry = g; }},\n            {stopDown: true, stopUp: true,\n            pixelTolerance: 0}\n        );\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        handler.activate();\n        log = {};\n\n        // a) click on (0, 0)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0)});\n        // b) mousedown on (0.5, 0.5)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0.5, 0.5)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0.5, 0.5)});\n        // c) mouseup on (1, 1)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(1, 1)});\n        // d) click on (0, 10)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 10)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 10)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 10)});\n        // e) dblclick on (10, 10)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(10, 10)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(10, 10)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(10, 10)});\n        handler.dblclick(\n            {type: \"dblclick\", xy: new OpenLayers.Pixel(10, 10)});\n        t.geom_eq(log.geometry,\n            new OpenLayers.Geometry.Polygon([\n                new OpenLayers.Geometry.LinearRing([\n                    new OpenLayers.Geometry.Point(-150, 75), // (0, 0)\n                    new OpenLayers.Geometry.Point(-150, 65), // (0, 10)\n                    new OpenLayers.Geometry.Point(-140, 65)  // (10, 10)\n                ])\n            ]), \"geometry is correct\");\n    }\n\n    // stopDown:false, stopUp:false\n    // a) click on (0, 0)\n    // b) mousedown on (0.5, 0.5)\n    // c) mouseup on (1, 1)\n    // d) click on (0, 10)\n    // e) dblclick on (10, 10)\n    function test_sequence2(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Polygon(control,\n            {done: function(g) { log.geometry = g; }},\n            {stopDown: false, stopUp: false,\n            pixelTolerance: 0}\n        );\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        handler.activate();\n        log = {};\n\n        // a) click on (0, 0)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 0)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 0)});\n        // b) mousedown on (0.5, 0.5)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0.5, 0.5)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0.5, 0.5)});\n        // c) mouseup on (1, 1)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(1, 1)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(1, 1)});\n        // d) click on (0, 10)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(0, 10)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(0, 10)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(0, 10)});\n        // e) dblclick on (10, 10)\n        handler.mousemove(\n            {type: \"mousemove\", xy: new OpenLayers.Pixel(10, 10)});\n        handler.mousedown(\n            {type: \"mousedown\", xy: new OpenLayers.Pixel(10, 10)});\n        handler.mouseup(\n            {type: \"mouseup\", xy: new OpenLayers.Pixel(10, 10)});\n        handler.dblclick(\n            {type: \"dblclick\", xy: new OpenLayers.Pixel(10, 10)});\n        t.geom_eq(log.geometry,\n            new OpenLayers.Geometry.Polygon([\n                new OpenLayers.Geometry.LinearRing([\n                    new OpenLayers.Geometry.Point(-150, 75), // (0, 0)\n                    new OpenLayers.Geometry.Point(-150, 65), // (0, 10)\n                    new OpenLayers.Geometry.Point(-140, 65)  // (10, 10)\n                ])\n            ]), \"geometry is correct\");\n    }\n\n    // a) tap\n    // b) tap\n    // c) doubletap\n    function test_touch_sequence1(t) {\n        t.plan(26);\n\n        // set up\n\n        var log;\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Polygon(control, {\n            done: function(g, f) {\n                log = {type: 'done', geometry: g, feature: f};\n            },\n            modify: function(g, f) {\n                log = {type: 'modify', geometry: g, feature: f};\n            }\n        }, {\n            doubleTouchTolerance: 2\n        });\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n        handler.activate();\n\n        // test\n\n        var ret;\n\n        // tap on (0, 0)\n        log = null;\n        ret = handler.touchstart({xy: new OpenLayers.Pixel(1, 0)});\n        t.ok(ret, '[touchstart] event propagates');\n        t.eq(log, null, '[touchstart] feature not finalized or modified');\n        ret = handler.touchmove({xy: new OpenLayers.Pixel(0, 0)});\n        t.ok(ret, '[touchmove] event propagates');\n        t.eq(log, null, '[touchmove] feature not finalized or modified');\n        ret = handler.touchend({});\n        t.ok(ret, '[touchend] event propagates');\n        t.eq(log.type, 'modify', '[touchend] feature modified');\n        t.geom_eq(log.geometry, new OpenLayers.Geometry.Point(-150, 75),\n                  \"[touchend] correct point\");\n\n        // tap on (0, 10)\n        log = null;\n        ret = handler.touchstart({xy: new OpenLayers.Pixel(1, 10)});\n        t.ok(ret, '[touchstart] event propagates');\n        t.eq(log, null, '[touchstart] feature not finalized or modified');\n        ret = handler.touchmove({xy: new OpenLayers.Pixel(0, 10)});\n        t.ok(ret, '[touchmove] event propagates');\n        t.eq(log, null, '[touchmove] feature not finalized or modified');\n        ret = handler.touchend({});\n        t.ok(ret, '[touchend] event propagates');\n        t.eq(log.type, 'modify', '[touchend] feature modified');\n        t.geom_eq(log.geometry, new OpenLayers.Geometry.Point(-150, 65),\n                  \"[touchend] correct point\");\n\n        // doubletap on (10, 10)\n        log = null;\n        ret = handler.touchstart({xy: new OpenLayers.Pixel(9, 10)});\n        t.ok(ret, '[touchstart] event propagates');\n        t.eq(log, null, '[touchstart] feature not finalized or modified');\n        ret = handler.touchmove({xy: new OpenLayers.Pixel(10, 10)});\n        t.ok(ret, '[touchmove] event propagates');\n        t.eq(log, null, '[touchmove] feature not finalized or modified');\n        ret = handler.touchend({});\n        t.ok(ret, '[touchend] event propagates');\n        t.eq(log.type, 'modify', '[touchend] feature modified');\n        t.geom_eq(log.geometry, new OpenLayers.Geometry.Point(-140, 65),\n                  \"[touchend] correct point\");\n        log = null;\n        ret = handler.touchstart({xy: new OpenLayers.Pixel(11, 10)});\n        t.ok(!ret, '[touchstart] event does not propagate');\n        t.eq(log.type, 'done', '[touchend] feature finalized');\n        t.geom_eq(log.geometry,\n            new OpenLayers.Geometry.Polygon([\n                new OpenLayers.Geometry.LinearRing([\n                    new OpenLayers.Geometry.Point(-150, 75), // (0, 0)\n                    new OpenLayers.Geometry.Point(-150, 65), // (0, 10)\n                    new OpenLayers.Geometry.Point(-140, 65)  // (10, 10)\n                ])\n            ]), \"[touchstart] geometry is correct\");\n        log = null;\n        ret = handler.touchend({});\n        t.ok(ret, '[touchend] event propagates');\n        t.eq(log, null, '[touchend] feature not finalized or modified');\n\n        // tear down\n\n        map.destroy();\n    }\n\n    // a) tap\n    // b) tap-move\n    // c) tap\n    // d) doubletap\n    function test_touch_sequence2(t) {\n        t.plan(32);\n\n        // set up\n\n        var log;\n        var map = new OpenLayers.Map(\"map\", {\n            resolutions: [1]\n        });\n        var layer = new OpenLayers.Layer.Vector(\"foo\", {\n            maxExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Polygon(control, {\n            done: function(g, f) {\n                log = {type: 'done', geometry: g, feature: f};\n            },\n            modify: function(g, f) {\n                log = {type: 'modify', geometry: g, feature: f};\n            }\n        }, {\n            doubleTouchTolerance: 2\n        });\n        control.handler = handler;\n        map.addControl(control);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n        handler.activate();\n\n        // test\n\n        var ret;\n\n        // tap on (0, 0)\n        log = null;\n        ret = handler.touchstart({xy: new OpenLayers.Pixel(1, 0)});\n        t.ok(ret, '[touchstart] event propagates');\n        t.eq(log, null, '[touchstart] feature not finalized or modified');\n        ret = handler.touchmove({xy: new OpenLayers.Pixel(0, 0)});\n        t.ok(ret, '[touchmove] event propagates');\n        t.eq(log, null, '[touchmove] feature not finalized or modified');\n        ret = handler.touchend({});\n        t.ok(ret, '[touchend] event propagates');\n        t.eq(log.type, 'modify', '[touchend] feature modified');\n        t.geom_eq(log.geometry, new OpenLayers.Geometry.Point(-150, 75),\n                  \"[touchend] correct point\");\n\n        // tap-move\n        log = null;\n        ret = handler.touchstart({xy: new OpenLayers.Pixel(1, 10)});\n        t.ok(ret, '[touchstart] event propagates');\n        t.eq(log, null, '[touchstart] feature not finalized or modified');\n        ret = handler.touchmove({xy: new OpenLayers.Pixel(20, 20)});\n        t.ok(ret, '[touchmove] event propagates');\n        t.eq(log, null, '[touchmove] feature not finalized or modified');\n        ret = handler.touchend({});\n        t.ok(ret, '[touchend] event propagates');\n        t.eq(log, null, '[touchend] feature not finalized or modified');\n\n        // tap on (0, 10)\n        log = null;\n        ret = handler.touchstart({xy: new OpenLayers.Pixel(1, 10)});\n        t.ok(ret, '[touchstart] event propagates');\n        t.eq(log, null, '[touchstart] feature not finalized or modified');\n        ret = handler.touchmove({xy: new OpenLayers.Pixel(0, 10)});\n        t.ok(ret, '[touchmove] event propagates');\n        t.eq(log, null, '[touchmove] feature not finalized or modified');\n        ret = handler.touchend({});\n        t.ok(ret, '[touchend] event propagates');\n        t.eq(log.type, 'modify', '[touchend] feature modified');\n        t.geom_eq(log.geometry, new OpenLayers.Geometry.Point(-150, 65),\n                  \"[touchend] correct point\");\n\n        // doubletap on (10, 10)\n        log = null;\n        ret = handler.touchstart({xy: new OpenLayers.Pixel(9, 10)});\n        t.ok(ret, '[touchstart] event propagates');\n        t.eq(log, null, '[touchstart] feature not finalized or modified');\n        ret = handler.touchmove({xy: new OpenLayers.Pixel(10, 10)});\n        t.ok(ret, '[touchmove] event propagates');\n        t.eq(log, null, '[touchmove] feature not finalized or modified');\n        ret = handler.touchend({});\n        t.ok(ret, '[touchend] event propagates');\n        t.eq(log.type, 'modify', '[touchend] feature modified');\n        t.geom_eq(log.geometry, new OpenLayers.Geometry.Point(-140, 65),\n                  \"[touchend] correct point\");\n        log = null;\n        ret = handler.touchstart({xy: new OpenLayers.Pixel(11, 10)});\n        t.ok(!ret, '[touchstart] event does not propagate');\n        t.eq(log.type, 'done', '[touchend] feature finalized');\n        t.geom_eq(log.geometry,\n            new OpenLayers.Geometry.Polygon([\n                new OpenLayers.Geometry.LinearRing([\n                    new OpenLayers.Geometry.Point(-150, 75), // (0, 0)\n                    new OpenLayers.Geometry.Point(-150, 65), // (0, 10)\n                    new OpenLayers.Geometry.Point(-140, 65)  // (10, 10)\n                ])\n            ]), \"[touchstart] geometry is correct\");\n        log = null;\n        ret = handler.touchend({});\n        t.ok(ret, '[touchend] event propagates');\n        t.eq(log, null, '[touchend] feature not finalized or modified');\n\n        // tear down\n\n        map.destroy();\n    }\n\n    function test_citeComplaint(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map('map');\n        map.addLayer(new OpenLayers.Layer.OSM());\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var control = new OpenLayers.Control({});\n        var handler = new OpenLayers.Handler.Polygon(control, {});\n        control.handler = handler;\n        map.addControl(control);\n        map.zoomToExtent(new OpenLayers.Bounds(-24225034.496992, -11368938.517442, -14206280.326992, -1350184.3474418));        \n        control.activate();\n        handler.createFeature(new OpenLayers.Pixel(100, 50));\n        t.ok(handler.point.geometry.x < 0, \"Geometry started correctly when wrapping the dateline using citeCompliant false\");\n        control.deactivate();\n\n        var handler = new OpenLayers.Handler.Polygon(control, {}, {citeCompliant: true});\n        control.handler = handler;\n        control.activate();\n        handler.createFeature(new OpenLayers.Pixel(100, 50));\n        t.ok(handler.point.geometry.x > 0, \"Geometry started correctly when wrapping the dateline using citeCompliant true\");\n\n        map.destroy();\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 300px; height: 150px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Handler/RegularPolygon.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    function test_Handler_RegularPolygon_constructor(t) {\n        t.plan(3);\n        var control = new OpenLayers.Control();\n        control.id = Math.random();\n        var callbacks = {foo: \"bar\"};\n        var options = {bar: \"foo\"};\n        \n        var oldInit = OpenLayers.Handler.prototype.initialize;\n        \n        OpenLayers.Handler.prototype.initialize = function(con, call, opt) {\n            t.eq(con.id, control.id,\n                 \"constructor calls parent with the correct control\");\n            t.eq(call, callbacks,\n                 \"constructor calls parent with the correct callbacks\");\n            t.eq(opt, options,\n                 \"regular polygon constructor calls parent with the correct options\");\n        }\n        var handler = new OpenLayers.Handler.RegularPolygon(control, callbacks, options);\n\n        OpenLayers.Handler.prototype.initialize = oldInit;\n    }\n\n    function test_Handler_RegularPolygon_activation(t) {\n        t.plan(3);\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.RegularPolygon(control);\n        handler.active = true;\n        var activated = handler.activate();\n        t.ok(!activated,\n             \"activate returns false if the handler was already active\");\n        handler.active = false;\n        activated = handler.activate();\n        t.ok(activated,\n             \"activate returns true if the handler was not already active\");\n        activated = handler.deactivate();\n        t.ok(activated,\n             \"deactivate returns true if the handler was active already\");\n        map.destroy();     \n    }\n\n    function test_Handler_RegularPolygon_deactivation(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n             \n        var handler = new OpenLayers.Handler.RegularPolygon(control, {foo: 'bar'});\n        handler.activate();\n        handler.layer.destroy();\n        handler.deactivate();\n        t.eq(handler.layer, null,\n             \"deactivate doesn't throw an error if layer was\" +\n             \" previously destroyed\");\n        map.destroy();     \n    }\n\n    function test_Handler_RegularPolygon_four_corners(t) {\n        t.plan(7);\n        var map = new OpenLayers.Map('map');\n        map.addLayer(new OpenLayers.Layer.WMS(\"\", \"\", {}));\n        map.zoomToMaxExtent();\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.RegularPolygon(control, {});\n        var activated = handler.activate();\n        var evt = {xy: new OpenLayers.Pixel(150, 75), which: 1};\n        handler.down(evt);\n        var evt = {xy: new OpenLayers.Pixel(175, 75), which: 1};\n        handler.move(evt);\n        t.eq(handler.feature.geometry.getBounds().toBBOX(),\n             \"-35.15625,-35.15625,35.15625,35.15625\",\n             \"correct bounds after move\");\n        t.eq(handler.feature.geometry.components[0].components.length, 5,\n             \"geometry has 5 components\");\n        t.eq(handler.feature.geometry.CLASS_NAME,\n             \"OpenLayers.Geometry.Polygon\",\n             \"geometry is a polygon\");\n        t.eq(handler.radius, 25*1.40625, \"feature radius as set on handler\");\n        var evt = {xy: new OpenLayers.Pixel(175, 80), which: 1};\n        handler.move(evt);\n        t.eq(handler.feature.geometry.getBounds().toBBOX(),\n             \"-35.15625,-35.15625,35.15625,35.15625\",\n             \"correct bounds after move with a fixed radius\");\n        handler.cancel();\n        handler.setOptions({radius:2 / Math.sqrt(2)});\n        var evt = {xy: new OpenLayers.Pixel(150, 75), which: 1};\n        handler.down(evt);\n        \n        t.eq(handler.feature.geometry.getBounds().toBBOX(),\n             \"-1,-1,1,1\",\n             \"bounds with manual radius setting\");\n        var evt = {xy: new OpenLayers.Pixel(175, 90), which: 1};\n        handler.move(evt);\n        t.eq(handler.feature.geometry.getBounds().toBBOX(),\n             \"34.15625,-22.09375,36.15625,-20.09375\",\n             \"bounds with manual radius setting and mousemove\");\n        map.destroy();     \n    }\n\n    function test_Handler_RegularPolygon_circle(t) {\n        t.plan(7);\n        var map = new OpenLayers.Map('map');\n        map.addLayer(new OpenLayers.Layer.WMS(\"\", \"\", {}));\n        map.zoomToMaxExtent();\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler.RegularPolygon(control, {}, {'sides':40});\n        var activated = handler.activate();\n        var evt = {xy: new OpenLayers.Pixel(150, 75), which: 1};\n        handler.down(evt);\n        var evt = {xy: new OpenLayers.Pixel(175, 75), which: 1};\n        handler.move(evt);\n        t.eq(handler.feature.geometry.getBounds().toBBOX(),\n             \"-35.15625,-35.15625,35.15625,35.15625\",\n             \"correct bounds after move\");\n        t.eq(handler.feature.geometry.components[0].components.length, 41,\n             \"geometry has correct numbre of components\");\n        t.eq(handler.feature.geometry.CLASS_NAME,\n             \"OpenLayers.Geometry.Polygon\",\n             \"geometry is a polygon\");\n        t.eq(handler.radius, 25*1.40625, \"feature radius as set on handler\");\n        var evt = {xy: new OpenLayers.Pixel(175, 80), which: 1};\n        handler.move(evt);\n        t.eq(handler.feature.geometry.getBounds().toBBOX(),\n             \"-35.823348,-35.823348,35.823348,35.823348\",\n             \"correct bounds after move with fixed radius\");\n        handler.cancel();\n        handler.setOptions({radius:1});\n        var evt = {xy: new OpenLayers.Pixel(150, 75), which: 1};\n        handler.down(evt);\n        \n        t.eq(handler.feature.geometry.getBounds().toBBOX(),\n             \"-0.996917,-0.996917,0.996917,0.996917\",\n             \"bounds with manual radius setting\");\n        var evt = {xy: new OpenLayers.Pixel(175, 80), which: 1};\n        handler.move(evt);\n        t.eq(handler.feature.geometry.getBounds().toBBOX(),\n             \"34.159333,-8.028167,36.153167,-6.034333\",\n             \"bounds with manual radius setting and mousemove\");\n        map.destroy();     \n    }\n\n    function test_Handler_RegularPolygon_irregular(t) {\n        t.plan(4);\n        var map = {\n            getResolution: function() {\n                return 1;\n            }\n        };\n        var layer = {\n            addFeatures: function() {},\n            drawFeature: function(feature, style) {\n                var ring = feature.geometry.components[0];\n                t.eq(ring.components[0].x, 20, \"correct right\");\n                t.eq(ring.components[0].y, 10, \"correct bottom\");\n                t.eq(ring.components[2].x, 10, \"correct left\");\n                t.eq(ring.components[2].y, 15, \"correct top\");\n            },\n            getLonLatFromViewPortPx: function(px) {\n                return {lon: px.x, lat: px.y};\n            }\n        };\n        var control = {};\n        var options = {\n            sides: 4,\n            irregular: true,\n            layer: layer,\n            map: map\n        };\n        var handler = new OpenLayers.Handler.RegularPolygon(\n            control, null, options\n        );\n        handler.origin = new OpenLayers.Geometry.Point(10, 10);\n        handler.feature = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Polygon(\n                [new OpenLayers.Geometry.LinearRing()]\n            )\n        );\n        // should result in a 10 x 5 rectangle\n        handler.move({xy: {x: 20, y: 15}});\n    }\n\n    function test_callbacks(t) {\n        t.plan(1);\n\n        // setup\n        var map = new OpenLayers.Map(\"map\");\n\n        var control = {\"map\": map};\n\n        var done = function(geom) {\n            t.ok(true,\n                 \"done callback called even if no move between down and up\");\n        };\n\n        var handler = new OpenLayers.Handler.RegularPolygon(\n            control, {\"done\": done});\n        handler.activate();\n        \n        var xy = new OpenLayers.Pixel(Math.random(), Math.random());\n\n        var isLeftClick = OpenLayers.Event.isLeftClick;\n        OpenLayers.Event.isLeftClick = function() { return true; };\n        handler.layer = {\n            renderer: {\n                clear: OpenLayers.Function.Void\n            },\n            addFeatures: OpenLayers.Function.Void,\n            drawFeature: OpenLayers.Function.Void,\n            destroyFeatures: OpenLayers.Function.Void,\n            getLonLatFromViewPortPx: function() {\n                return xy;\n            }\n        };\n\n        // test\n        map.events.triggerEvent(\"mousedown\", {\"xy\": xy});\n        map.events.triggerEvent(\"mouseup\", {\"xy\": xy});\n\n        // tear down\n        OpenLayers.Event.isLeftClick = isLeftClick;\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 300px; height: 150px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Handler.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    function test_Handler_constructor(t) {\n        t.plan(4);\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n    \n        var callbacks = {foo: \"bar\"};\n        var options = {bar: \"foo\"};\n        var handler = new OpenLayers.Handler(control, callbacks, options);\n        t.ok(handler instanceof OpenLayers.Handler,\n             \"new OpenLayers.Handler returns object\");\n        t.eq(handler.map.id, map.id,\n             \"constructing a handler with a map sets the map on the handler\");\n        t.eq(handler.callbacks.foo, callbacks.foo,\n             \"constructor correctly sets callbacks\");\n        t.eq(handler.bar, options.bar,\n             \"constructor correctly extends handler with options\");\n    }\n    \n    function test_Handler_activate(t) {\n        t.plan(52);\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n    \n        var events = [\"mouseover\", \"mouseout\", \"mousedown\",\n                      \"mouseup\", \"mousemove\", \"click\",\n                      \"dblclick\", \"resize\", \"focus\", \"blur\"];\n\n        var handler = new OpenLayers.Handler(control);\n        handler.active = true;\n        var activated = handler.activate();\n        t.ok(!activated,\n             \"activate returns false if the handler is already active\");\n\n        handler.active = false;\n        map.events.registerPriority = function(type, obj, func) {\n            var r = func();\n            if(typeof r == \"string\") {\n                // this is one of the mock handler methods\n                t.ok(OpenLayers.Util.indexOf(events, type) > -1,\n                     \"activate calls registerPriority with browser event: \" + type);\n                t.eq(typeof func, \"function\",\n                     \"activate calls registerPriority with a function\");\n                t.eq(r, type,\n                     \"activate calls registerPriority with the correct method\");\n                t.eq(obj[\"CLASS_NAME\"], \"OpenLayers.Handler\",\n                     \"activate calls registerPriority with the handler\");\n            } else {\n                // this is the call with handler.setEvent as the func\n                t.ok(r, \"activate calls registerPriority with handler.setEvent\");\n            }\n        }\n        \n        // set browser event like properties on the handler\n        for(var i=0; i<events.length; ++i) {\n            setMethod(events[i]);\n        }\n        function setMethod(key) {\n            handler[key] = function() {return key};\n        }\n        activated = handler.activate();\n        t.ok(activated,\n             \"activated returns true if the handler is not already active\");\n        \n    }\n    \n    function test_Handler_deactivate(t) {\n        t.plan(52);\n        var map = new OpenLayers.Map('map', { controls: []});\n        // No controls so that we don't get more thingies than we expect\n        // when we actually clean up after ourselves: r5891 caused this\n        // because we actually destroy things now on the navigation control. \n        var control = new OpenLayers.Control();\n        map.addControl(control);\n    \n        var events = [\"mouseover\", \"mouseout\", \"mousedown\",\n                      \"mouseup\", \"mousemove\", \"click\",\n                      \"dblclick\", \"resize\", \"focus\", \"blur\"];\n\n        var handler = new OpenLayers.Handler(control);\n        handler.active = false;\n        var deactivated = handler.deactivate();\n        t.ok(!deactivated,\n             \"deactivate returns false if the handler is already deactive\");\n\n        handler.activate();\n        map.events.unregister = function(type, obj, func) {\n            var r = func();\n            if(typeof r == \"string\") {\n                // this is one of the mock handler methods\n                t.ok(OpenLayers.Util.indexOf(events, type) > -1,\n                     \"deactivate calls unregister with browser event: \" + type);\n                t.eq(typeof func, \"function\",\n                     \"activate calls unregister with a function\");\n                t.eq(func(), type,\n                     \"activate calls unregister with the correct method\");\n                t.eq(obj[\"CLASS_NAME\"], \"OpenLayers.Handler\",\n                     \"activate calls unregister with the handler\");\n            } else {\n                // this is the call with handler.setEvent as the func\n                t.ok(r, \"activate calls registerPriority with handler.setEvent\");\n            }\n        }\n        \n        // set browser event like properties on the handler\n        for(var i=0; i<events.length; ++i) {\n            // add in a closure for key\n            (function(key) {\n                handler[key] = function() {return key};\n            })(events[i]);\n        }\n        deactivated = handler.deactivate();\n        t.ok(deactivated,\n             \"deactivated returns true if the handler is already active\");\n        map.events.unregister = OpenLayers.Events.prototype.unregister;\n        map.destroy();\n        \n    }\n    \n    function test_Handler_setEvent(t) {\n        t.plan(5);\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler(control);\n        handler.click = function(evt) {\n        }\n        handler.activate();\n        var testEvent = {\n            xy: new OpenLayers.Pixel(Math.random(), Math.random()),\n            altKey: (Math.random() > 0.5),\n            shiftKey: (Math.random() > 0.5),\n            ctrlKey: (Math.random() > 0.5),\n            metaKey: (Math.random() > 0.5)\n        }\n        map.events.triggerEvent(\"click\", testEvent);\n        t.ok(handler.evt.xy.x == testEvent.xy.x &&\n             handler.evt.xy.y == testEvent.xy.y,\n             \"handler.evt has proper xy object\");\n        t.eq(handler.evt.altKey, testEvent.altKey,\n             \"handler.evt.altKey correct\");\n        t.eq(handler.evt.shiftKey, testEvent.shiftKey,\n             \"handler.evt.shiftKey correct\");\n        t.eq(handler.evt.ctrlKey, testEvent.ctrlKey,\n             \"handler.evt.ctrlKey correct\");\n        t.eq(handler.evt.metaKey, testEvent.metaKey,\n             \"handler.evt.metaKey correct\");\n    }\n    \n    function test_Handler_destroy(t) {\n        t.plan(5);\n        var map = new OpenLayers.Map('map');\n        var control = new OpenLayers.Control();\n        map.addControl(control);\n        var handler = new OpenLayers.Handler(control);\n        var deactivated = false;\n        handler.deactivate = function() {\n            deactivated = true;\n        };\n        t.ok(handler.control,\n             \"handler has a control prior to destroy\");\n        t.ok(handler.map,\n             \"handler has a map prior to destroy\");\n        handler.destroy();\n        t.eq(handler.control, null,\n             \"hanlder.control is null after destroy\");\n        t.eq(handler.map, null,\n             \"handler.map is null after destroy\");\n        t.ok(deactivated,\n             \"handler.deactivate is called by destroy\");\n    }\n    \n    function test_Handler_checkModifiers(t) {\n        t.plan(62);\n        var handler = new OpenLayers.Handler({});\n        handler.keyMask = null;\n        var proceed = handler.checkModifiers({});\n        t.ok(proceed,\n             \"checkModifiers returns true if no keyMask on the handler\");\n        \n        \n        /**\n         * Test checkModifiers for single keyMask values.  The method should\n         *     return true if the corresponding key is associated with the\n         *     event.  For example, if evt.shiftKey is true and handler.keyMask\n         *     is OpenLayers.Handler.MOD_SHIFT, checkModifiers should return\n         *     true.\n         */\n        var constants = {\n            MOD_NONE: null,\n            MOD_SHIFT: \"shiftKey\",\n            MOD_CTRL: \"ctrlKey\",\n            MOD_ALT: \"altKey\",\n            MOD_META: \"metaKey\"\n        }\n        var proceed, evt, value, c, k;\n        for(c in constants) {\n            handler.keyMask = OpenLayers.Handler[c];\n            // for this key mask, test all single key possibilities\n            for(k in constants) {\n                value = constants[k];\n                evt = {};\n                if(value) {\n                    // mimic a key down on an event\n                    evt[value] = true;\n                }\n                proceed = handler.checkModifiers(evt);\n                // if k == c, proceed should be true - false otherwise\n                t.eq(k == c, proceed,\n                     \"returns \" + proceed + \" if keyMask is \" + c +\n                     \" and \" + ((value) ? value : \"no key\") + \" is down\");\n            }\n        }\n\n        /**\n         * Test checkModifiers for double keyMask values.  The method should\n         *     return true if the corresponding key combo is associated with the\n         *     event.  For example, if evt.shiftKey is true and handler.keyMask\n         *     is OpenLayers.Handler.MOD_SHIFT, checkModifiers should return\n         *     true.\n         */\n        var constants = [\"MOD_SHIFT\", \"MOD_CTRL\", \"MOD_ALT\", \"MOD_META\"];\n        var keys = [\"shiftKey\", \"ctrlKey\", \"altKey\", \"metaKey\"];\n        var proceed, evt, c1, c2, k1, k2;\n        for(var i=0; i<constants.length-1; ++i) {\n            c1 = constants[i];\n            for(var j=i+1; j<constants.length; ++j) {\n                c2 = constants[j];\n                handler.keyMask = OpenLayers.Handler[c1] |\n                                  OpenLayers.Handler[c2];\n                // for this key mask, test all double key possibilities\n                for(var x=0; x<keys.length-1; ++x) {\n                    k1 = keys[x];\n                    for(var y=x+1; y<keys.length; ++y) {\n                        k2 = keys[y];\n                        evt = {};\n                        evt[k1] = true;\n                        evt[k2] = true;\n                        proceed = handler.checkModifiers(evt);\n                        // if the combo matches, proceed should be true\n                        // at this point we know that i != j and x != y\n                        t.eq(((i == x) || (i == y)) &&\n                             ((j == x) || (j == y)),\n                             proceed,\n                             \"returns \" + proceed + \" if \" + c1 + \" | \" + c2 +\n                             \" and \" + k1 + \" + \" + k2 + \" is down\");\n                    }\n                }\n            }\n        }\n            \n    }\n\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Icon.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var icon; \n    \n    function test_Icon_constructor (t) {\n        t.plan( 4 );\n        var size = new OpenLayers.Size(5,6);\n        icon = new OpenLayers.Icon(\"\", size);\n        t.ok( icon instanceof OpenLayers.Icon, \"new OpenLayers.Icon returns Icon object\" );\n        t.ok( icon.size instanceof OpenLayers.Size, \"icon.size returns Size object\" );\n        t.ok( icon.size.equals(size), \"icon.size returns correct value\" );\n        t.eq( icon.url, \"\", \"icon.url returns str object\" );\n    }\n    function test_Icon_clone (t) {\n        t.plan( 4 );\n        icon = new OpenLayers.Icon(\"a\",new OpenLayers.Size(5,6));\n        t.ok( icon instanceof OpenLayers.Icon, \"new OpenLayers.Icon returns Icon object\" );\n        var cloned = icon.clone();\n        t.ok( cloned instanceof OpenLayers.Icon, \"clone is an OpenLayers.Icon\" );\n        cloned.url = \"b\"\n        t.eq( icon.url, \"a\", \"icon.url doesn't change with clone's url\" );\n        t.eq( cloned.url, \"b\", \"cloned.url does change when edited\" );\n    }\n\n    function test_Icon_setOpacity(t) {\n        t.plan( 2 );\n        \n        icon = new OpenLayers.Icon(\"a\",new OpenLayers.Size(5,6));\n        t.ok(!icon.imageDiv.style.opacity, \"default icon has no opacity\");\n        \n        icon.setOpacity(0.5);\n        t.eq(parseFloat(icon.imageDiv.style.opacity), 0.5, \"icon.setOpacity() works\");\n    }\n    \n    function test_Icon_isDrawn(t) {\n        t.plan(4);\n\n        var icon = {};\n\n        //no imageDiv\n        var drawn = OpenLayers.Icon.prototype.isDrawn.apply(icon, []);\n        t.ok(!drawn, \"icon with no imageDiv not drawn\");\n\n        //imageDiv no parentNode\n        icon.imageDiv = {};\n        drawn = OpenLayers.Icon.prototype.isDrawn.apply(icon, []);\n        t.ok(!drawn, \"icon with imageDiv with no parentNode not drawn\");\n\n        //imageDiv with parent\n        icon.imageDiv.parentNode = {};\n        drawn = OpenLayers.Icon.prototype.isDrawn.apply(icon, []);\n        t.ok(drawn, \"icon with imageDiv with parentNode drawn\");\n\n        //imageDiv with parent but nodetype 11\n        icon.imageDiv.parentNode = {'nodeType': 11};\n        drawn = OpenLayers.Icon.prototype.isDrawn.apply(icon, []);\n        t.ok(!drawn, \"imageDiv with parent but nodetype 11 not drawn\");\n    }\n\n\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Kinetic.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_Kinetic (t) {\n        t.plan(17);\n        var finish = false;\n        var results = {\n            110: {x: -2.7, y: -3.6, end: false},\n            120: {x: -2.1, y: -2.8, end: false},\n            130: {x: -1.5, y: -2.0, end: false},\n            140: {x: -0.9, y: -1.2, end: false},\n            150: {x: -0.3, y: -0.4, end: true}\n        };\n\n        var originalGetTime = Date.prototype.getTime;\n        Date.prototype.getTime = function() { return 0 };\n        \n        var interval = 10; // arbitrary value for tests \n\n        var originalLoopAnimation = OpenLayers.Animation.start;\n        OpenLayers.Animation.start = function(callback) {\n            while (!finish) {\n                var time = new Date().getTime();\n                Date.prototype.getTime = function() { return time+interval };\n                callback();\n            }\n        };\n\n        var kinetic = new OpenLayers.Kinetic({\n            deceleration: 0.01\n        });\n        kinetic.begin();\n        kinetic.update({x:0, y:0});\n        \n        Date.prototype.getTime = function() { return 100 };\n        var measure = kinetic.end({x:30, y:40});\n\n        t.eq(measure.speed, 0.5, \"correct speed\");\n        t.eq(measure.theta, Math.PI - Math.atan(40/30), \"correct angle\");\n\n        // fake timer id    \n        kinetic.timerId = 0;\n        kinetic.move(measure, function(x, y, end) {\n            var result = results[new Date().getTime()];\n            t.eq(Math.round(x * 1000) / 1000, result.x, \"correct x\");\n            t.eq(Math.round(y * 1000) / 1000, result.y, \"correct y\");\n            t.eq(end, result.end, \"correct end\");\n            finish = end;\n        });\n        \n        Date.prototype.getTime = originalGetTime;\n        OpenLayers.Animation.start = originalLoopAnimation;\n    }\n\n    function test_Angle (t) {\n        t.plan(8);\n        var results = [\n            {speed: 0.5, theta: Math.round((Math.PI - Math.atan(40/30)) * 1000000) / 1000000},\n            {speed: 0.5, theta: Math.round((Math.PI + Math.atan(40/30)) * 1000000) / 1000000},\n            {speed: 0.5, theta: Math.round((- Math.atan(40/30)) * 1000000) / 1000000},\n            {speed: 0.5, theta: Math.round((Math.atan(40/30)) * 1000000) / 1000000}\n        ];\n\n        var originalGetTime = Date.prototype.getTime;\n        Date.prototype.getTime = function() { return 0 };\n\n        var kinetic = new OpenLayers.Kinetic();\n        kinetic.begin();\n        kinetic.update({x:0, y:0});\n        \n        Date.prototype.getTime = function() { return 100 };\n        var measure = kinetic.end({x:30, y:40});\n\n        t.eq(measure.speed, results[0].speed, \"correct speed\");\n        t.eq(Math.round(measure.theta * 1000000) / 1000000,\n                results[0].theta, \"correct angle\");\n\n\n        var originalGetTime = Date.prototype.getTime;\n        Date.prototype.getTime = function() { return 0 };\n\n        var kinetic = new OpenLayers.Kinetic();\n        kinetic.begin();\n        kinetic.update({x:0, y:0});\n        \n        Date.prototype.getTime = function() { return 100 };\n        var measure = kinetic.end({x:30, y:-40});\n\n        t.eq(measure.speed, results[1].speed, \"correct speed\");\n        t.eq(Math.round(measure.theta * 1000000) / 1000000,\n                results[1].theta, \"correct angle\");\n\n\n        var originalGetTime = Date.prototype.getTime;\n        Date.prototype.getTime = function() { return 0 };\n\n        var kinetic = new OpenLayers.Kinetic();\n        kinetic.begin();\n        kinetic.update({x:0, y:0});\n        \n        Date.prototype.getTime = function() { return 100 };\n        var measure = kinetic.end({x:-30, y:-40});\n\n        t.eq(measure.speed, results[2].speed, \"correct speed\");\n        t.eq(Math.round(measure.theta * 1000000) / 1000000,\n                results[2].theta, \"correct angle\");\n\n        var originalGetTime = Date.prototype.getTime;\n        Date.prototype.getTime = function() { return 0 };\n\n        var kinetic = new OpenLayers.Kinetic();\n        kinetic.begin();\n        kinetic.update({x:0, y:0});\n        \n        Date.prototype.getTime = function() { return 100 };\n        var measure = kinetic.end({x:-30, y:40});\n\n        t.eq(measure.speed, results[3].speed, \"correct speed\");\n        t.eq(Math.round(measure.theta * 1000000) / 1000000,\n                results[3].theta, \"correct angle\");\n\n        Date.prototype.getTime = originalGetTime;\n    }\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 600px; height: 300px;\"/>\n    <div style=\"display: none;\"><div id=\"invisimap\"></div></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Lang.html",
    "content": "<html>\n<head>\n    <script src=\"OLLoader.js\"></script>\n    <script src=\"../lib/OpenLayers/Lang/en-CA.js\" type=\"text/javascript\"></script>\n    <script src=\"../lib/OpenLayers/Lang/fr.js\" type=\"text/javascript\"></script>\n    <script type=\"text/javascript\">\n    \n    function test_setCode(t) {\n        t.plan(4);\n        OpenLayers.Lang.code = null;\n        \n        // test with no argument - this could result in the default or the\n        // browser language if a dictionary exists\n        OpenLayers.Lang.setCode();\n        t.ok(OpenLayers.Lang.code != null,\n             \"code set when no argument is sent\");\n        \n        var primary = \"xx\";\n        var subtag = \"XX\";\n        var code = primary + \"-\" + subtag;\n        OpenLayers.Lang[code] = {};\n        \n        // test code for dictionary that exists\n        OpenLayers.Lang.setCode(code);\n        t.eq(OpenLayers.Lang.code, code,\n             \"code properly set for existing dictionary\");\n        \n        // test code for dictionary that doesn't exist\n        OpenLayers.Lang.setCode(primary + \"-YY\");\n        t.eq(OpenLayers.Lang.code, OpenLayers.Lang.defaultCode,\n             \"code set to default for non-existing dictionary\");\n        \n        // test code for existing primary but missing subtag\n        OpenLayers.Lang[primary] = {};\n        OpenLayers.Lang.setCode(primary + \"-YY\");\n        t.eq(OpenLayers.Lang.code, primary,\n             \"code set to primary when subtag dictionary is missing\");\n        \n        // clean up\n        delete OpenLayers.Lang[code];\n        delete OpenLayers.Lang[primary];\n        OpenLayers.Lang.code = null;\n    }\n    \n    function test_getCode(t) {\n        t.plan(3);\n        OpenLayers.Lang.code = null;\n        \n        // test that a non-null value is retrieved - could be browser language\n        // or defaultCode\n        var code = OpenLayers.Lang.getCode();\n        t.ok(code != null, \"returns a non-null code\");\n        t.ok(OpenLayers.Lang.code != null, \"sets the code to a non-null value\");\n        \n        // test that the code is returned if non-null\n        OpenLayers.Lang.code = \"foo\";\n        t.eq(OpenLayers.Lang.getCode(), \"foo\", \"returns the code if non-null\");\n        \n        // clean up\n        OpenLayers.Lang.code = null;        \n    }\n    \n    function test_i18n(t) {\n        t.plan(1);        \n        t.ok(OpenLayers.i18n === OpenLayers.Lang.translate,\n             \"i18n is an alias for OpenLayers.Lang.translate\");\n    }\n    \n    function test_translate(t) {\n        var keys = ['test1', 'test3', 'noKey'];\n        var codes = ['en', 'en-CA', 'fr', 'fr-CA', 'sw'];\n        var result = {\n            'en': {'Overlays':'Overlays', \n                   'unhandledRequest':'Unhandled request return foo', \n                   'noKey':'noKey'},\n            'en-CA': {'Overlays':'Overlays',\n                   'unhandledRequest':'Unhandled request return foo', \n                      'noKey':'noKey'},\n            'fr': {'Overlays':'Calques', \n                   'unhandledRequest':'Requête non gérée, retournant foo',\n                  'noKey':'noKey'},\n            'fr-CA': {'Overlays':'Calques', //this should result in 'fr'\n                   'unhandledRequest':'Requête non gérée, retournant foo',\n                  'noKey':'noKey'},\n            'sw': {'Overlays':'Overlays', //this should result in 'en'\n                   'unhandledRequest':'Unhandled request return foo', \n                  'noKey':'noKey'}\n        };\n        \n        t.plan(keys.length*codes.length);\n\n        for (var i=0; i<codes.length; ++i) {\n            var code = codes[i];\n            OpenLayers.Lang.setCode(code);\n            t.eq(OpenLayers.Lang.translate('Overlays'), result[code]['Overlays'], \"simple key lookup in \"+code);\n            t.eq(OpenLayers.Lang.translate('unhandledRequest',{'statusText':'foo'}), \n                        result[code]['unhandledRequest'], \"lookup with argument substitution in \"+code);\n            t.eq(OpenLayers.Lang.translate('noKey'), result[code]['noKey'], \"invalid key returns the key in \"+code);\n        }\n    }\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/ArcGIS93Rest.html",
    "content": "<html>\n<head>\n    <script type=\"text/javascript\">var oldAlert = window.alert, gMess; window.alert = function(message) {gMess = message; return true;};</script>\n    <script type=\"text/javascript\">window.alert = oldAlert;</script>\n<script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var layer; \n\n    var name = 'Test Layer';\n    var url = \"http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/Specialty/ESRI_StateCityHighway_USA/MapServer/export\";\n    var params = {layers: \"show:0,2\"};\n\n    function test_Layer_AGS93_constructor (t) {\n        var params = {layers: \"show:0,2\"};\n        t.plan( 14 );\n\n        var trans_format = \"png\";\n        if (OpenLayers.Util.alphaHack()) { trans_format = \"gif\"; } \n        \n        layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params);\n        t.ok( layer instanceof OpenLayers.Layer.ArcGIS93Rest, \"new OpenLayers.Layer.ArcGIS93Rest returns object\" );\n        t.eq( layer.url, url, \"layer.url is correct (HTTPRequest inited)\" );\n        t.eq( layer.params.LAYERS, \"show:0,2\", \"params passed in correctly uppercased\" );\n\n        t.eq( layer.params.FORMAT, \"png\", \"default params correclty uppercased and copied\");\n\n        t.eq(layer.isBaseLayer, true, \"no transparency setting, wms is baselayer\");\n\n        params.format = 'jpg';\n        layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params);\n        t.eq( layer.params.FORMAT, \"jpg\", \"default params correclty uppercased and overridden\");\n\n        params.TRANSPARENT = \"true\";\n        var layer2 = new OpenLayers.Layer.ArcGIS93Rest(name, url, params);\n        t.eq(layer2.isBaseLayer, false, \"transparency == 'true', wms is not baselayer\");\n\n        params.TRANSPARENT = \"TRUE\";\n        var layer3 = new OpenLayers.Layer.ArcGIS93Rest(name, url, params);\n        t.eq(layer3.isBaseLayer, false, \"transparency == 'TRUE', wms is not baselayer\");\n        t.eq(layer3.params.FORMAT, trans_format, \"transparent = TRUE causes non-image/jpeg format\");\n\n        params.TRANSPARENT = \"TRuE\";\n        var layer4 = new OpenLayers.Layer.ArcGIS93Rest(name, url, params);\n        t.eq(layer4.isBaseLayer, false, \"transparency == 'TRuE', wms is not baselayer\");\n        t.eq(layer4.params.FORMAT, trans_format, \"transparent = TRuE causes non-image/jpeg format\");\n\n        params.TRANSPARENT = true;\n        var layer5 = new OpenLayers.Layer.ArcGIS93Rest(name, url, params);\n        t.eq(layer5.isBaseLayer, false, \"transparency == true, wms is not baselayer\");\n        t.eq(layer5.params.FORMAT, trans_format, \"transparent = true causes non-image/jpeg format\");\n\n        params.TRANSPARENT = false;\n        var layer6 = new OpenLayers.Layer.ArcGIS93Rest(name, url, params);\n        t.eq(layer6.isBaseLayer, true, \"transparency == false, wms is baselayer\");\n    }\n    \n    function test_Layer_AGS93_addtile (t) {\n        var params = {layers: \"show:0,2\"};\n        t.plan( 6 );\n    \n        layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params);\n        var map = new OpenLayers.Map('map', {tileManager: null});\n        map.addLayer(layer);\n        var pixel = new OpenLayers.Pixel(5,6);\n        var tile = layer.addTile(new OpenLayers.Bounds(1,2,3,4), pixel);\n        tile.draw();\n\n        var img = tile.imgDiv;\n        var tParams = OpenLayers.Util.extend({},\n                        OpenLayers.Util.upperCaseObject(params));\n        tParams = OpenLayers.Util.extend(tParams, {\n            FORMAT: \"png\", BBOX: \"1,2,3,4\", SIZE: \"256,256\", F: \"image\", BBOXSR: \"4326\", IMAGESR: \"4326\"\n        });\n        t.eq( tile.url,\n             url + \"?\" + OpenLayers.Util.getParameterString(tParams),\n             \"image src is created correctly via addtile\" );\n        t.eq( tile.getTile().style.top, \"6px\", \"image top is set correctly via addtile\" );\n        t.eq( tile.getTile().style.left, \"5px\", \"image top is set correctly via addtile\" );\n\n        var firstChild = layer.div.firstChild;\n        t.eq( firstChild.nodeName.toLowerCase(), \"img\", \"div first child is an image object\" );\n        t.ok( firstChild == img, \"div first child is correct image object\" );\n        t.eq( tile.position.toString(), \"x=5,y=6\", \"Position of tile is set correctly.\" );\n        map.destroy();\n    }\n    \n    function test_Layer_AGS93_inittiles (t) {\n        var params = {layers: \"show:0,2\"};\n        t.plan( 2 );\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params, {buffer: 2});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0),5);\n        t.eq( layer.grid.length, 8, \"Grid rows is correct.\" );\n        t.eq( layer.grid[0].length, 7, \"Grid cols is correct.\" );\n        map.destroy();\n    }\n\n\n    function test_Layer_AGS93_clone (t) {\n        var params = {layers: \"show:0,2\"};\n        t.plan(4);\n        \n        var options = {tileSize: new OpenLayers.Size(500,50)};\n        var map = new OpenLayers.Map('map', options);\n        layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params);\n        map.addLayer(layer);\n\n        layer.grid = [ [6, 7], \n                       [8, 9]];\n\n        var clone = layer.clone();\n\n        t.ok( clone.grid != layer.grid, \"clone does not copy grid\");\n\n        t.ok( clone.tileSize.equals(layer.tileSize), \"tileSize correctly cloned\");\n\n        layer.tileSize.w += 40;\n\n        t.eq( clone.tileSize.w, 500, \"changing layer.tileSize does not change clone.tileSize -- a fresh copy was made, not just copied reference\");\n\n        t.eq( clone.alpha, layer.alpha, \"alpha copied correctly\");\n\n        layer.grid = null;\n        map.destroy();\n    }\n\n    function test_Layer_AGS93_isBaseLayer(t) {\n        var params = {layers: \"show:0,2\"};\n        t.plan(3);\n        \n        layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params);\n        t.ok( layer.isBaseLayer, \"baselayer is true by default\");\n\n        var newParams = OpenLayers.Util.extend({}, params);\n        newParams.transparent = \"true\";\n        layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, newParams);\n        t.ok( !layer.isBaseLayer, \"baselayer is false when transparent is set to true\");\n\n        layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params, {isBaseLayer: false});\n        t.ok( !layer.isBaseLayer, \"baselayer is false when option is set to false\" );\n    }\n\n    function test_Layer_AGS93_mergeNewParams (t) {\n        var params = {layers: \"show:0,2\"};\n        t.plan( 4 );\n\n        var map = new OpenLayers.Map(\"map\");\n        layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params);\n        \n        var newParams = { layers: 'sooper', \n                          chickpeas: 'png'};\n\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n\n        layer.redraw = function() {\n            t.ok(true, \"layer is redrawn after new params merged\");\n        }\n\n        layer.mergeNewParams(newParams);\n        \n        t.eq( layer.params.LAYERS, \"sooper\", \"mergeNewParams() overwrites well\");\n        t.eq( layer.params.CHICKPEAS, \"png\", \"mergeNewParams() adds well\");\n    \n        newParams.CHICKPEAS = 151;\n\n        t.eq( layer.params.CHICKPEAS, \"png\", \"mergeNewParams() makes clean copy of hashtable\");\n        map.destroy();\n    }\n\n    function test_Layer_AGS93_getFullRequestString (t) {\n        var params = {layers: \"show:0,2\"};\n        t.plan( 1 );\n        var map = new OpenLayers.Map('map');\n        map.projection = \"xx\";\n        tParams = { layers: 'show:0,2', \n                   format: 'png'};\n        var tLayer = new OpenLayers.Layer.ArcGIS93Rest(name, url, tParams);\n        map.addLayer(tLayer);\n        str = tLayer.getFullRequestString();\n        var tParams = {\n            LAYERS: \"show:0,2\", FORMAT: \"png\"\n        };\n        t.eq(str,\n             url + \"?\" + OpenLayers.Util.getParameterString(tParams),\n             \"getFullRequestString() adds SRS value\");\n        map.destroy();\n \n    }\n\n    function test_Layer_AGS93_noGutters (t) { \n        t.plan(2);\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.ArcGIS93Rest(\"no gutter layer\", url, params, {gutter: 0});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 5);\n        var tile = layer.grid[0][0];\n        var request = layer.getURL(tile.bounds);\n        var args = OpenLayers.Util.getParameters(request);\n        t.eq(parseInt(args['SIZE'][0]),\n             tile.size.w,\n             \"layer without gutter requests images that are as wide as the tile\");\n        t.eq(parseInt(args['SIZE'][1]),\n             tile.size.h,\n             \"layer without gutter requests images that are as tall as the tile\");\n        \n        layer.destroy();\n        map.destroy();\n    }\n\n    function test_Layer_AGS93_gutters (t) { \n        var params = {layers: \"show:0,2\"};\n        t.plan(2);\n        var gutter = 15;\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.ArcGIS93Rest(\"gutter layer\", url, params, {gutter: gutter});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 5);\n        var tile = layer.grid[0][0];\n        var request = layer.getURL(tile.bounds);\n        var args = OpenLayers.Util.getParameters(request);\n        t.eq(parseInt(args['SIZE'][0]),\n             tile.size.w + (2 * gutter),\n             \"layer with gutter requests images that are wider by twice the gutter\");\n        t.eq(parseInt(args['SIZE'][1]),\n             tile.size.h + (2 * gutter),\n             \"layer with gutter requests images that are taller by twice the gutter\");\n\n        layer.destroy();\n        map.destroy();\n\n    }\n\n    function test_Layer_AGS93_destroy (t) {\n\n        t.plan( 1 );\n\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params);\n        map.addLayer(layer);\n\n        map.setCenter(new OpenLayers.LonLat(0,0), 5);\n\n        //grab a reference to one of the tiles\n        var tile = layer.grid[0][0];        \n\n        layer.destroy();\n        \n    // checks to make sure superclass (grid) destroy() was called    \n        \n        t.ok( layer.grid == null, \"grid set to null\");\n    }\n    \n    function test_Layer_ADG93_Filter(t) {\n        var params = {layers: \"show:0,2\"};\n        t.plan( 9 );\n    \n        layer = new OpenLayers.Layer.ArcGIS93Rest(name, url, params);\n        var map = new OpenLayers.Map('map', {tileManager: null});\n        map.addLayer(layer);\n        var pixel = new OpenLayers.Pixel(5,6);\n        var tile = layer.addTile(new OpenLayers.Bounds(1,2,3,4), pixel);\n        // Set up basic params.\n        var tParams = OpenLayers.Util.extend({}, OpenLayers.Util.upperCaseObject(params));\n        tParams = OpenLayers.Util.extend(tParams, {\n            FORMAT: \"png\", BBOX: \"1,2,3,4\", SIZE: \"256,256\", F: \"image\", BBOXSR: \"4326\", IMAGESR: \"4326\"\n        });\n        \n        // We need to actually set the \"correct\" url on a dom element, because doing so encodes things not encoded by getParameterString.\n        var encodingHack = document.createElement(\"img\");\n        \n        tile.draw();\n        t.eq( tile.url, url + \"?\" + OpenLayers.Util.getParameterString(tParams), \"image src no filter\" );\n        \n        layer.setLayerFilter('1', \"MR_TOAD = 'FLYING'\");\n        tParams[\"LAYERDEFS\"] = \"1:MR_TOAD = 'FLYING';\";\n        tile.draw();\n        t.eq( tile.url, url + \"?\" + OpenLayers.Util.getParameterString(tParams), \"image src one filter\" );\n\n        layer.setLayerFilter('1', \"MR_TOAD = 'NOT FLYING'\");\n        tParams[\"LAYERDEFS\"] = \"1:MR_TOAD = 'NOT FLYING';\";\n        tile.draw();\n        t.eq( tile.url, url + \"?\" + OpenLayers.Util.getParameterString(tParams), \"image src change one filter\" );\n\n        layer.setLayerFilter('2', \"true = false\");\n        tParams[\"LAYERDEFS\"] = \"1:MR_TOAD = 'NOT FLYING';2:true = false;\";\n        tile.draw();\n        t.eq( tile.url, url + \"?\" + OpenLayers.Util.getParameterString(tParams), \"image src two filters\" );\n\n        layer.setLayerFilter('99', \"some_col > 5\");\n        tParams[\"LAYERDEFS\"] = \"1:MR_TOAD = 'NOT FLYING';2:true = false;99:some_col > 5;\";\n        tile.draw();\n        t.eq( tile.url, url + \"?\" + OpenLayers.Util.getParameterString(tParams), \"image src three filters\" );\n        \n        layer.clearLayerFilter('2');\n        tParams[\"LAYERDEFS\"] = \"1:MR_TOAD = 'NOT FLYING';99:some_col > 5;\";\n        tile.draw();\n        t.eq( tile.url, url + \"?\" + OpenLayers.Util.getParameterString(tParams), \"image src removed middle filter\" );\n        \n        layer.clearLayerFilter('2');\n        tParams[\"LAYERDEFS\"] = \"1:MR_TOAD = 'NOT FLYING';99:some_col > 5;\";\n        tile.draw();\n        t.eq( tile.url, url + \"?\" + OpenLayers.Util.getParameterString(tParams), \"image src removed missing filter (no change)\" );\n        \n        layer.clearLayerFilter();\n        delete tParams[\"LAYERDEFS\"];\n        tile.draw();\n        t.eq( tile.url, url + \"?\" + OpenLayers.Util.getParameterString(tParams), \"image src removed all filters\" );\n        \n        layer.clearLayerFilter();\n        tile.draw();\n        t.eq( tile.url, url + \"?\" + OpenLayers.Util.getParameterString(tParams), \"image src removed all (no) filters\" );\n    }\n    \n    \n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/ArcGISCache.html",
    "content": "<html>\n<head>\n  <script src=\"../../lib/OpenLayers.js\"></script>\n  <script src=\"../../lib/OpenLayers/Layer/ArcGISCache.js\" type=\"text/javascript\"></script>\n  <script src=\"ArcGISCache.json\" type=\"text/javascript\"></script>\n  <script type=\"text/javascript\">\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var layer; \n\n    var name = 'Test Layer';\n    var url = \"http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer\";\n    var options = { }; \n\n    function test_Layer_ARCGISCACHE_constructor (t) {\n        t.plan( 1 );\n                       \n        var layer = new OpenLayers.Layer.ArcGISCache(name, url, options);\n        t.ok( layer instanceof OpenLayers.Layer.ArcGISCache, \"returns OpenLayers.Layer.ArcGISCache object\" );\n    }\n    \n    function test_Layer_ARCGISCACHE_autoConfigure (t) {\n        t.plan( 5 );\n        var layerInfo = capabilitiesObject;\n        \n        //initialize the layer using the JSON object from an arcgis server\n        //SEE: ArcGISCache.json\n        var layer = new OpenLayers.Layer.ArcGISCache(name, url, {\n            layerInfo: layerInfo\n        });\n        t.ok( layer instanceof OpenLayers.Layer.ArcGISCache, \"returns OpenLayers.Layer.ArcGISCache object\" );        \n        t.ok( layer.projection = 'EPSG:' + layerInfo.spatialReference.wkid, \"projection is set correctly\");\n        t.ok( layer.units = 'm', \"map units are set correctly\");\n        t.ok( layer.resolutions && layer.resolutions.length == 20, \"resolutions are initialized from LOD objects properly\");\n        \n        if (layerInfo.tileInfo) {\n            if (layerInfo.tileInfo.width && layerInfo.tileInfo.height) {\n                var tileSize = new OpenLayers.Size(layerInfo.tileInfo.width, layerInfo.tileInfo.height);\n                t.ok((layer.tileSize.width == tileSize.width) && (layer.tileSize.height == tileSize.height), \"tile size is set properly\");\n            }\n            else {\n                var tileSize = new OpenLayers.Size(layerInfo.tileInfo.cols, layerInfo.tileInfo.rows);\n                t.ok((layer.tileSize.width == tileSize.width) && (layer.tileSize.height == tileSize.height), \"tile size is set properly\");\n            }\n        }        \n    }\n    \n    /**\n     * lets make sure we're getting the correct urls back with a basic auto-configure setup \n     */\n    function test_Layer_ARCGISCACHE_autoConfigure_URLS(t) {\n        var layerInfo = capabilitiesObject;\n        \n        //initialize the layer using the JSON object from an arcgis server\n        //SEE: ArcGISCache.json\n        var layer = new OpenLayers.Layer.ArcGISCache(name, url, {\n            layerInfo: layerInfo,\n            params: {foo: \"bar\"}\n        });\n        var layer2 = new OpenLayers.Layer.ArcGISCache(name, url, {\n            layerInfo: layerInfo,\n            hexZoom: true,\n            useArcGISServer: false,\n            params: {foo: \"bar\"}\n        });\n        var map = new OpenLayers.Map('map', { \n            maxExtent: layer.maxExtent,\n            units: layer.units,\n            resolutions: layer.resolutions,\n            numZoomLevels: layer.numZoomLevels,\n            tileSize: layer.tileSize,\n            projection: layer.displayProjection,\n            StartBounds: layer.initialExtent    \n        });\n        map.addLayers([layer, layer2]);\n    \n        //this set represents a few edge cases, and some more specific cases, it is by no means exhaustive,\n        var urlSets = [\n            { \n                bounds: new OpenLayers.Bounds(-36787612.973083,-22463925.368666, 43362420.398053,17611091.316902),\n                url: \"http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/0/0/0\",\n                url2: \"http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/L00/R00000000/C00000000.png\"\n            },            \n            { \n                bounds: new OpenLayers.Bounds(-31793889.951914,4589319.785415, 8281126.733654,24626828.128199),\n                url: \"http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/1/0/0\",\n                url2: \"http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/L01/R00000000/C00000000.png\"\n            },            \n            { \n                bounds: new OpenLayers.Bounds(-24639873.181971,12676071.933457, -4602364.839187,22694826.104849),\n                url: \"http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/2/0/0\",\n                url2: \"http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/L02/R00000000/C00000000.png\" \n            },\n            { \n                bounds: new OpenLayers.Bounds(-15521241.455665,11580270.695961, 4516266.887119,21599024.867353),\n                url: \"http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/2/0/1\",\n                url2: \"http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/L02/R00000000/C00000001.png\"\n            },                    \n            { \n                bounds: new OpenLayers.Bounds(-9265879.5435993,2870892.9335638, -8639707.4078873,3183979.0014198) ,\n                url: \"http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/7/54/35\",\n                url2: \"http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/L07/R00000036/C00000023.png\"\n            },\n            { \n                bounds: new OpenLayers.Bounds(-10741909.131798,4684560.1640365, -10585366.09787,4762831.6810005),\n                url: \"http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/9/195/119\",\n                url2: \"http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/L09/R000000c3/C00000077.png\"\n            },\n            { \n                bounds: new OpenLayers.Bounds(-13668958.106938,4456961.2611504, -13512415.07301,4535232.7781144),\n                url: \"http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/9/198/82\",\n                url2: \"http://services.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/L09/R000000c6/C00000052.png\"\n            }\n        ];\n        \n        t.plan( urlSets.length * 2 );\n        for(var i=0;i<urlSets.length;i++) \n        {\n            var o = urlSets[i];            \n            map.zoomToExtent(o.bounds, true);\n            \n            var resultUrl = layer.getURL(o.bounds);            \n            t.ok( resultUrl == o.url + \"?foo=bar\", \"correct tile returned for \" + o.bounds);        \n            t.ok(layer2.getURL(o.bounds) == o.url2 + \"?foo=bar\", \"correct tile url returned if hexZoom is true for \" + o.bounds);\n        }\n    }    \n    \n    /**\n     * Test the formatting for the 'direct' urls, especially when not auto-configuring the layer\n     */\n    function test_Layer_ARCGISCACHE_direct(t) {\n        var roadsUrl = 'http://serverx.esri.com/arcgiscache/DG_County_roads_yesA_backgroundDark/Layers/_alllayers';\n        var urlSets = [\n            { \n                bounds: new OpenLayers.Bounds(289244.67443386,4317153.7421985, 306178.04163392,4325620.4257985),\n                url: roadsUrl + \"/L00/R0000029e/C0000027f.png\" \n            },            \n            { \n                bounds: new OpenLayers.Bounds(308658.51534463,4303230.0164352, 325591.88254469,4311696.7000352),\n                url: roadsUrl + \"/L00/R000002a0/C00000282.png\"\n            },            \n            { \n                bounds: new OpenLayers.Bounds(311136.39626998,4318933.8711555, 311678.26402038,4319204.8050307) ,\n                url: roadsUrl + \"/L05/R000051e0/C00004e52.png\" \n            }\n        ];\n        t.plan( urlSets.length );\n    \n    \n        //perform the exact setup from the arcgiscache_direct example\n            \n        // First 4 variables extracted from conf.xml file        \n        // Tile layers & map MUST have same projection \n        var proj='EPSG:26915';\n            \n        // Layer can also accept serverResolutions array\n        // to deal with situation in which layer resolution array & map resolution\n        // array are out of sync\n        var mapResolutions = [33.0729828126323,16.9333672000677,8.46668360003387,4.23334180001693,2.11667090000847,1.05833545000423];\n\n        // For this example this next line is not really needed, 256x256 is default.\n        // However, you would need to change this if your layer had different tile sizes \n        var tileSize = new OpenLayers.Size(256,256);\n        \n        // Tile Origin is required unless it is the same as the implicit map origin\n        // which can be effected by several variables including maxExtent for map or base layer \n        var agsTileOrigin = new OpenLayers.LonLat(-5120900,9998100);\n        \n        // This can really be any valid bounds that the map would reasonably be within \n        var mapExtent = new OpenLayers.Bounds(289310.8204,4300021.937,314710.8712,4325421.988);\n        \n\n        var map = new OpenLayers.Map('map', {\n            maxExtent:mapExtent,\n            controls: [\n                new OpenLayers.Control.Navigation(),\n                new OpenLayers.Control.LayerSwitcher(), \n                new OpenLayers.Control.PanZoomBar(),\n                new OpenLayers.Control.MousePosition()]\n        });\n\n        var layer = new OpenLayers.Layer.ArcGISCache('Roads', roadsUrl, {\n            tileOrigin: agsTileOrigin,\n            resolutions: mapResolutions,\n            sphericalMercator: true,\n            maxExtent: mapExtent,\n            useArcGISServer: false,\n            isBaseLayer: true,\n            projection: proj\n        });\n        \n        map.addLayers([layer]);\n        map.zoomToExtent(new OpenLayers.Bounds(-8341644, 4711236, -8339198, 4712459));\n\n        for(var i=0;i<urlSets.length;i++) \n        {\n            var o = urlSets[i];            \n            map.zoomToExtent(o.bounds, true);\n            var resultUrl = layer.getURL(o.bounds);\n            t.ok( resultUrl == o.url, \"correct tile returned for \" + o.bounds);        \n        }\n    }\n        \n    /**\n     * Check the utility function for generating tile indexes against a file cache\n     * This is already tested in BaseTypes test, but these are specific,\n     * common conversions that this class will rely on, so the tests are retained\n     */\n    function test_Layer_ARCGISCACHE_zeroPad(t) {\n        t.plan(4);\n    \n        var layer = new OpenLayers.Layer.ArcGISCache('test', null, { });\n\n        //some tile examples\n        t.ok('00000001' == OpenLayers.Number.zeroPad(1, 8, 16), 'zeroPad should generate tile indexes properly ');\n        t.ok('00000020' == OpenLayers.Number.zeroPad(32, 8, 16), 'zeroPad should generate tile indexes properly ');\n        t.ok('00000100' == OpenLayers.Number.zeroPad(256, 8, 16), 'zeroPad should generate tile indexes properly ');\n        t.ok('00001000' == OpenLayers.Number.zeroPad(4096, 8, 16), 'zeroPad should generate tile indexes properly ');        \n    }\n    \n    /**\n     * Check to ensure our LOD calculation will correctly avoid returning tile indexes less than zero\n     * (see http://trac.osgeo.org/openlayers/ticket/3169)\n     */\n    function test_Layer_ARCGISCACHE_tileBounds(t) {\n        t.plan(1);\n    \n        var layer = new OpenLayers.Layer.ArcGISCache('test', null, { });\n        var res = 264.583862501058;\n        layer.tileOrigin = new OpenLayers.LonLat(0.0, 650000.0);\n        layer.tileSize = new OpenLayers.Size(512, 512);\n        \n        // pick a point off the left of our tile origin  (would be a negative tile index)\n        var point = new OpenLayers.Geometry.Point(-123308.94829, 393128.85817);\n        \n        var tile = layer.getContainingTileCoords(point, res);\n        t.ok((tile.x >= 0 && tile.y >= 0), 'layer should not generate negative tile ranges for level of detail');\n    }\n\n   /*  \n    * Test that messing up the Array.prototype does not mess up the lods of the layer. \n    * This messes up zooming when resolutions are very small/scales are very large/zoomed way in. \n    */ \n    function test_Layer_ARCGISCACHE_lods (t) { \n        t.plan( 2 ); \n        var layerInfo = capabilitiesObject; \n\n        lods = layerInfo.tileInfo.lods.length; \n\n        // mess up the Array prototype\n        Array.prototype.foo = function() { };\n\n        t.ok( lods == layerInfo.tileInfo.lods.length, 'proper number of \"Levels of Detail\" before initialization' ); \n\n        // initialize the layer using the JSON object from an arcgis server \n        // see: ArcGISCache.json \n        var layer = new OpenLayers.Layer.ArcGISCache(name, url, { \n            layerInfo: layerInfo \n        }); \n\n        t.ok( lods == layer.lods.length, 'proper number of \"Levels of Detail\" after initialization.' );         \n        // restore the Array prototype\n        delete Array.prototype.foo;\n    } \n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px;\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/ArcGISCache.json",
    "content": "var capabilitiesObject = {\n  \"currentVersion\" : 10.01, \n  \"serviceDescription\" : \"This map is designed to be used as a base map by GIS professionals and as a reference map by anyone.  The base map includes administrative boundaries, cities, water features, physiographic features, parks, landmarks, highways, roads, railways, airports, and buildings overlaid on land cover and shaded relief imagery for added context. The map was compiled from a variety of best available sources from several data providers, including the U.S. Geological Survey, Food and Agriculture Organization of the United Nations, National Park Service, Tele Atlas, AND, and ESRI. The base map currently provides coverage for the world down to a scale of ~1:1m and coverage for the continental United States and Hawaii to a scale of ~1:20k.  The base map also includes detailed maps for selected cities in the United States including Portland, Oregon and Philadephia, Pennsylvania. The base map was designed and developed by ESRI based on the topographic map templates that are available through the ArcGIS Resource Centers. For more information on this map, visit us \\u003ca href=\\\"http://goto.arcgisonline.com/maps/World_Topo_Map \\\" target=\\\"_new\\\"\\u003eonline\\u003c/a\\u003e.\", \n  \"mapName\" : \"Layers\", \n  \"description\" : \"This map is designed to be used as a base map by GIS professionals and as a reference map by anyone.  The base map includes administrative boundaries, cities, water features, physiographic features, parks, landmarks, highways, roads, railways, airports, and buildings overlaid on land cover and shaded relief imagery for added context. The map was compiled from a variety of best available sources from several data providers, including the U.S. Geological Survey, Food and Agriculture Organization of the United Nations, National Park Service, Tele Atlas, AND, and ESRI. The base map currently provides coverage for the world down to a scale of ~1:1m and coverage for the continental United States and Hawaii to a scale of ~1:20k.  The base map also includes detailed maps for selected cities in the United States including Portland, Oregon and Philadephia, Pennsylvania. The base map was designed and developed by ESRI based on the topographic map templates that are available through the ArcGIS Resource Centers. For more information on this map, visit us online at http://goto.arcgisonline.com/maps/World_Topo_Map\", \n  \"copyrightText\" : \"Sources: USGS, FAO, NPS, EPA, ESRI, DeLorme, TANA, other suppliers\", \n  \"layers\" : [\n    {\n      \"id\" : 0, \n      \"name\" : \"Topographic Info\", \n      \"parentLayerId\" : -1, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : [1, 2, 3, 4], \n      \"minScale\" : 0, \n      \"maxScale\" : 0\n    }, \n    {\n      \"id\" : 1, \n      \"name\" : \"Elevation (m)\", \n      \"parentLayerId\" : 0, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 0, \n      \"maxScale\" : 0\n    }, \n    {\n      \"id\" : 2, \n      \"name\" : \"Elevation (ft)\", \n      \"parentLayerId\" : 0, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 0, \n      \"maxScale\" : 0\n    }, \n    {\n      \"id\" : 3, \n      \"name\" : \"Slope\", \n      \"parentLayerId\" : 0, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 0, \n      \"maxScale\" : 0\n    }, \n    {\n      \"id\" : 4, \n      \"name\" : \"Aspect\", \n      \"parentLayerId\" : 0, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 0, \n      \"maxScale\" : 0\n    }, \n    {\n      \"id\" : 5, \n      \"name\" : \"Places Info\", \n      \"parentLayerId\" : -1, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : [6, 7, 8, 9], \n      \"minScale\" : 0, \n      \"maxScale\" : 0\n    }, \n    {\n      \"id\" : 6, \n      \"name\" : \"Place Names (Country Level)\", \n      \"parentLayerId\" : 5, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 0, \n      \"maxScale\" : 80000000\n    }, \n    {\n      \"id\" : 7, \n      \"name\" : \"Place Names (State Level)\", \n      \"parentLayerId\" : 5, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 80000001, \n      \"maxScale\" : 1500000\n    }, \n    {\n      \"id\" : 8, \n      \"name\" : \"Place Names (County Level)\", \n      \"parentLayerId\" : 5, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 1500001, \n      \"maxScale\" : 400000\n    }, \n    {\n      \"id\" : 9, \n      \"name\" : \"Place Names (City Level)\", \n      \"parentLayerId\" : 5, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 399999, \n      \"maxScale\" : 0\n    }, \n    {\n      \"id\" : 10, \n      \"name\" : \"Scale Descriptions\", \n      \"parentLayerId\" : -1, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : [11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26], \n      \"minScale\" : 0, \n      \"maxScale\" : 0\n    }, \n    {\n      \"id\" : 11, \n      \"name\" : \"Level 15  ~1:18K\", \n      \"parentLayerId\" : 10, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 25000, \n      \"maxScale\" : 15001\n    }, \n    {\n      \"id\" : 12, \n      \"name\" : \"Level 14  ~1:36K\", \n      \"parentLayerId\" : 10, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 50000, \n      \"maxScale\" : 25001\n    }, \n    {\n      \"id\" : 13, \n      \"name\" : \"Level 13  ~1:72K\", \n      \"parentLayerId\" : 10, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 100000, \n      \"maxScale\" : 50001\n    }, \n    {\n      \"id\" : 14, \n      \"name\" : \"Level 12  ~1:144K\", \n      \"parentLayerId\" : 10, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 288000, \n      \"maxScale\" : 100000\n    }, \n    {\n      \"id\" : 15, \n      \"name\" : \"Level 11  ~1:288K\", \n      \"parentLayerId\" : 10, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 575000, \n      \"maxScale\" : 288000\n    }, \n    {\n      \"id\" : 16, \n      \"name\" : \"Level 10  ~1:577K\", \n      \"parentLayerId\" : 10, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 1150000, \n      \"maxScale\" : 575000\n    }, \n    {\n      \"id\" : 17, \n      \"name\" : \"Level 9    ~1:1.15M\", \n      \"parentLayerId\" : 10, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 2200000, \n      \"maxScale\" : 1150000\n    }, \n    {\n      \"id\" : 18, \n      \"name\" : \"Level 8    ~1:2.3M\", \n      \"parentLayerId\" : 10, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 4500000, \n      \"maxScale\" : 2200000\n    }, \n    {\n      \"id\" : 19, \n      \"name\" : \"Level 7    ~1:4.5M\", \n      \"parentLayerId\" : 10, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 9000000, \n      \"maxScale\" : 4500000\n    }, \n    {\n      \"id\" : 20, \n      \"name\" : \"Level 6    ~1:9.2M\", \n      \"parentLayerId\" : 10, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 18000000, \n      \"maxScale\" : 9000000\n    }, \n    {\n      \"id\" : 21, \n      \"name\" : \"Level 5    ~1:18M \", \n      \"parentLayerId\" : 10, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 36000000, \n      \"maxScale\" : 18000000\n    }, \n    {\n      \"id\" : 22, \n      \"name\" : \"Level 4    ~1:36M\", \n      \"parentLayerId\" : 10, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 72000000, \n      \"maxScale\" : 36000000\n    }, \n    {\n      \"id\" : 23, \n      \"name\" : \"Level 3    ~1:72M\", \n      \"parentLayerId\" : 10, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 75500000, \n      \"maxScale\" : 70000000\n    }, \n    {\n      \"id\" : 24, \n      \"name\" : \"Level 2    ~1:147M\", \n      \"parentLayerId\" : 10, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 290000000, \n      \"maxScale\" : 147000000\n    }, \n    {\n      \"id\" : 25, \n      \"name\" : \"Level 1    ~1:292M\", \n      \"parentLayerId\" : 10, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 295000000, \n      \"maxScale\" : 150000000\n    }, \n    {\n      \"id\" : 26, \n      \"name\" : \"Level 0     ~1:584M\", \n      \"parentLayerId\" : 10, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 0, \n      \"maxScale\" : 295000000\n    }, \n    {\n      \"id\" : 27, \n      \"name\" : \"Citations\", \n      \"parentLayerId\" : -1, \n      \"defaultVisibility\" : true, \n      \"subLayerIds\" : null, \n      \"minScale\" : 0, \n      \"maxScale\" : 0\n    }\n  ], \n  \"tables\" : [\n    \n  ], \n  \"spatialReference\" : {\n    \"wkid\" : 102100\n  }, \n  \"singleFusedMapCache\" : true, \n  \"tileInfo\" : {\n    \"rows\" : 256, \n    \"cols\" : 256, \n    \"dpi\" : 96, \n    \"format\" : \"JPEG\", \n    \"compressionQuality\" : 90, \n    \"origin\" : {\n      \"x\" : -20037508.342787, \n      \"y\" : 20037508.342787\n    }, \n    \"spatialReference\" : {\n      \"wkid\" : 102100\n    }, \n    \"lods\" : [\n      {\"level\" : 0, \"resolution\" : 156543.033928, \"scale\" : 591657527.591555}, \n      {\"level\" : 1, \"resolution\" : 78271.5169639999, \"scale\" : 295828763.795777}, \n      {\"level\" : 2, \"resolution\" : 39135.7584820001, \"scale\" : 147914381.897889}, \n      {\"level\" : 3, \"resolution\" : 19567.8792409999, \"scale\" : 73957190.948944}, \n      {\"level\" : 4, \"resolution\" : 9783.93962049996, \"scale\" : 36978595.474472}, \n      {\"level\" : 5, \"resolution\" : 4891.96981024998, \"scale\" : 18489297.737236}, \n      {\"level\" : 6, \"resolution\" : 2445.98490512499, \"scale\" : 9244648.868618}, \n      {\"level\" : 7, \"resolution\" : 1222.99245256249, \"scale\" : 4622324.434309}, \n      {\"level\" : 8, \"resolution\" : 611.49622628138, \"scale\" : 2311162.217155}, \n      {\"level\" : 9, \"resolution\" : 305.748113140558, \"scale\" : 1155581.108577}, \n      {\"level\" : 10, \"resolution\" : 152.874056570411, \"scale\" : 577790.554289}, \n      {\"level\" : 11, \"resolution\" : 76.4370282850732, \"scale\" : 288895.277144}, \n      {\"level\" : 12, \"resolution\" : 38.2185141425366, \"scale\" : 144447.638572}, \n      {\"level\" : 13, \"resolution\" : 19.1092570712683, \"scale\" : 72223.819286}, \n      {\"level\" : 14, \"resolution\" : 9.55462853563415, \"scale\" : 36111.909643}, \n      {\"level\" : 15, \"resolution\" : 4.77731426794937, \"scale\" : 18055.954822}, \n      {\"level\" : 16, \"resolution\" : 2.38865713397468, \"scale\" : 9027.977411}, \n      {\"level\" : 17, \"resolution\" : 1.19432856685505, \"scale\" : 4513.988705}, \n      {\"level\" : 18, \"resolution\" : 0.597164283559817, \"scale\" : 2256.994353}, \n      {\"level\" : 19, \"resolution\" : 0.298582141647617, \"scale\" : 1128.497176}\n    ]\n  }, \n  \"initialExtent\" : {\n    \"xmin\" : -45223792.233066, \n    \"ymin\" : -22882589.2065154, \n    \"xmax\" : 45223792.233066, \n    \"ymax\" : 22882589.2065155, \n    \"spatialReference\" : {\n      \"wkid\" : 102100\n    }\n  }, \n  \"fullExtent\" : {\n    \"xmin\" : -20037507.0671618, \n    \"ymin\" : -19971868.8804086, \n    \"xmax\" : 20037507.0671618, \n    \"ymax\" : 19971868.8804086, \n    \"spatialReference\" : {\n      \"wkid\" : 102100\n    }\n  }, \n  \"units\" : \"esriMeters\", \n  \"supportedImageFormatTypes\" : \"PNG24,PNG,JPG,DIB,TIFF,EMF,PS,PDF,GIF,SVG,SVGZ,AI,BMP\", \n  \"documentInfo\" : {\n    \"Title\" : \"World Topo Map\", \n    \"Author\" : \"ESRI\", \n    \"Comments\" : \"\", \n    \"Subject\" : \"\", \n    \"Category\" : \"\", \n    \"Keywords\" : \"\", \n    \"Credits\" : \"\"\n  }, \n  \"capabilities\" : \"Map,Query,Data\"\n};"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/ArcIMS.html",
    "content": "<html>\n  <head>\n    <script type=\"text/javascript\" src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    \n      // use an arcims map service against Avencia Inc.'s global sample map services\n      var serviceName = \"OpenLayers_Sample\";\n      var layerName = \"Global Sample Map\";\n      var imsUrl = \"http://sample.avencia.com/servlet/com.esri.esrimap.Esrimap\";\n      \n      //\n      // create an arcims layer\n      //\n      function test_Layer_ArcIMS_constructor( t ) {\n        t.plan(11);\n        \n        var options = {\n          serviceName: serviceName,\n          async: false,\n          displayOutsideMaxExtent: true\n        };\n            \n        var layer = new OpenLayers.Layer.ArcIMS( layerName, imsUrl, options );\n          \n        // check layer & properties\n        t.ok( layer instanceof OpenLayers.Layer.ArcIMS, \"new OpenLayers.Layer.ArcIMS returns object\" );\n        t.eq( layer.url, imsUrl, \"layer.url is correct (HTTPRequest inited)\" );\n        t.eq( layer.name, layerName, \"layer.name is correct\" );\n        t.eq( layer.displayOutsideMaxExtent, options.displayOutsideMaxExtent, \n          \"displayOutsideMaxExtent property set correctly from options\" );\n         \n        // check request parameters\n        t.eq( layer.params.ServiceName, serviceName, \"ServiceName set properly\" );\n        t.eq( layer.params.ClientVersion, \"9.2\", \"ClientVersion set properly\" );\n        \n        // check request options\n        t.eq( layer.options.async, options.async, \"async property set correctly from options\" );\n        t.eq( layer.options.serviceName, serviceName, \"serviceName property set correctly from options\" );\n        t.eq( layer.options.layers.length, 0, \"layers option is the correct length\" );\n        t.eq( layer.options.tileSize.w, 512, \"default tile width set correctly\" );\n        t.eq( layer.options.tileSize.h, 512, \"default tile height set correctly\" );\n      } \n      \n      \n      \n      /*\n       * how to test getURL, getURLasync, and getFeatureInfo without a proxy?\n       *\n       */\n      \n      \n      //\n      // Create an arcims layer, and verify that the query changes properly\n      //\n      function test_Layer_ArcIMS_setLayerQuery(t) {\n        t.plan(9);\n        \n        var options = { serviceName: serviceName };\n        var layer = new OpenLayers.Layer.ArcIMS( layerName, imsUrl, options );\n        var querydef = {\n          where: \"FIPS_CNTRY = 'US'\"\n        };\n        \n        t.eq( layer.options.layers.length, 0, \"layer definitions are empty\" );\n        \n        layer.setLayerQuery( \"layerID\", querydef );\n        \n        t.eq( layer.options.layers.length, 1, \"layers definitions contain one layerdef\" );\n        t.ok( layer.options.layers[0].query !== null, \"layer query exists\" );\n        t.eq( typeof layer.options.layers[0].query.where, \"string\", \"where query is a string\" );\n        t.eq( layer.options.layers[0].query.where, querydef.where, \"where query matches\" );\n        \n        // change the definition\n        querydef = {\n          where: \"FIPS_CNTRY = 'UV'\",\n          spatialfilter:true\n        }\n        \n        layer.setLayerQuery( \"layerID\", querydef );\n        \n        t.eq( layer.options.layers.length, 1, \"layers definitions contain one layerdef\" );\n        t.ok( layer.options.layers[0].query !== null, \"layer query exists\" );\n        t.eq( typeof layer.options.layers[0].query.where, \"string\", \"where query is a string\" );\n        t.eq( layer.options.layers[0].query.where, querydef.where, \"where query matches\" );\n      }\n      function test_Layer_ArcIMS_clone (t) {\n          t.plan(5);\n  \n          var url = imsUrl;\n          var options = {\n            serviceName: serviceName,\n            async: false,\n            displayOutsideMaxExtent: true\n          };\n          var map = new OpenLayers.Map('map', {controls: []});\n          var layer = new OpenLayers.Layer.ArcIMS(name, url, options);\n          map.addLayer(layer);\n  \n          layer.grid = [ [6, 7],\n                         [8, 9]];\n  \n          var clone = layer.clone();\n  \n          t.ok( clone.grid != layer.grid, \"clone does not copy grid\");\n  \n          t.ok( clone.tileSize.equals(layer.tileSize), \"tileSize correctly cloned\");\n  \n          t.eq( clone.params.serviceName, layer.params.serviceName, \"serviceName copied correctly\");\n  \n          t.eq( clone.async, layer.async, \"async copied correctly\");\n  \n          t.eq( clone.url, layer.url, \"url copied correctly\");\n  \n          layer.grid = null;\n          map.destroy();\n      }\n      \n    </script>\n  </head>\n  <body>\n    <div id=\"map\" style=\"width:500px;height:550px\"></div> \n  </body>  \n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/Bing.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var map, layer; \n\n    var layerType = 'Aerial';\n    var key = \"AqTGBsziZHIJYYxgivLBf0hVdrAk9mWO5cQcb8Yux8sW5M8c8opEC2lZqKR1ZZXf\";\n    \n    var options = {\n        type: layerType,\n        key: key\n    };\n\n    function test_constructor(t) {\n        t.plan(3);\n                       \n        var origProcessMetadata = OpenLayers.Layer.Bing.processMetadata;\n        var log = [];\n        OpenLayers.Layer.Bing.processMetadata = function(metadata) {\n            var script = document.getElementById(this._callbackId);\n            log.push(script.src);\n            origProcessMetadata.apply(this, arguments);\n        };\n        layer = new OpenLayers.Layer.Bing(OpenLayers.Util.extend({\n            metadataParams: {foo: \"bar\"}\n        }, options));\n        t.ok(layer instanceof OpenLayers.Layer.Bing, \"returns OpenLayers.Layer.Bing object\" );\n        t.delay_call(5, function() {\n            t.eq(log.length, 1, \"processMetadata called\");\n            t.eq(OpenLayers.Util.getParameters(log[0]).foo, \"bar\", \"metadataParams passed to url correctly.\");\n            OpenLayers.Layer.Bing.processMetadata = origProcessMetadata;\n            layer.destroy();\n        });\n    }\n    \n    function test_initLayer(t) {\n        t.plan(2);\n\n        var meta = [];\n        var origProcessMetadata = OpenLayers.Layer.Bing.processMetadata;\n        OpenLayers.Layer.Bing.processMetadata = function(metadata) {\n            meta.push(metadata);\n        };\n        map = new OpenLayers.Map(\"map\");\n        layer = new OpenLayers.Layer.Bing(options);\n        var extent;\n        map.addLayers([layer, new OpenLayers.Layer(null, {\n            moveTo: function(bounds, changed) {\n                extent = bounds;\n            }\n        })]);\n        map.zoomToMaxExtent();\n        \n        var map2 = new OpenLayers.Map(\"map\");\n        var layer2 = new OpenLayers.Layer.Bing(OpenLayers.Util.extend({\n            initLayer: function() {\n                // pretend we have a zoomMin of 2\n                this.metadata.resourceSets[0].resources[0].zoomMin = 2;\n                OpenLayers.Layer.Bing.prototype.initLayer.apply(this, arguments);\n            }\n        }, options));\n        var extent2;\n        map2.addLayers([layer2, new OpenLayers.Layer(null, {\n            moveTo: function(bounds, changed) {\n                extent2 = bounds;\n            }\n        })]);\n        map2.zoomToMaxExtent();\n        \n        t.delay_call(5, function() {\n            origProcessMetadata.call(layer, meta[0]);\n            t.eq(extent.toBBOX(), map.getExtent().toBBOX(), \"layer extent correct for base layer with zoomMin == 1.\");\n            map.destroy();\n        });\n\n        t.delay_call(6, function() {\n            origProcessMetadata.call(layer2, meta[1]);\n            t.eq(extent2.toBBOX(), map2.getExtent().toBBOX(), \"layer extent correct for base layer with zoomMin == 2.\");\n            map2.destroy();\n            OpenLayers.Layer.Bing.processMetadata = origProcessMetadata;\n        });\n    }\n    \n    function test_initLayer_notempty(t) {\n        t.plan(1);\n        \n        map = new OpenLayers.Map(\"map\", {\n            projection: \"EPSG:3857\",\n            layers: [new OpenLayers.Layer(\"dummy\", {isBaseLayer: true})]\n        });\n        map.zoomToExtent([-14768652, 4492113, -12263964, 5744457]);\n        var layer = new OpenLayers.Layer.Bing(OpenLayers.Util.extend({\n            isBaseLayer: false\n        }, options));\n        map.addLayer(layer);\n        \n        t.delay_call(5, function() {\n            t.ok(layer.grid[0][0].url, \"Tile not empty\");\n            map.destroy();\n        });\n    }\n    \n    function test_attribution(t) {\n        t.plan(3);\n        \n        var log = [];\n        var map = new OpenLayers.Map(\"map\");\n        layer = new OpenLayers.Layer.Bing(options);\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        \n        t.delay_call(2, function() {\n            t.ok(OpenLayers.Util.indexOf(layer.attribution, 'olBingAttribution aerial') !== -1, \"Attribution has the correct css class\");\n            t.ok(OpenLayers.Util.indexOf(layer.attribution, '<img src=\"\">') == -1, \"Attribution contains a logo\");\n            t.ok(OpenLayers.Util.indexOf(layer.attribution, '</img></div></a><a style=') == -1 , \"Attribution contains a copyright\");\n            map.destroy();\n        });\n    }\n\n    function test_attribution_notempty(t) {\n        t.plan(1);\n        \n        var log = [];\n        var map = new OpenLayers.Map(\"map\");\n        layer = new OpenLayers.Layer.Bing(OpenLayers.Util.applyDefaults({type: 'Road'}, options));\n        map.addLayer(layer);\n        var format = OpenLayers.String.format;\n        OpenLayers.String.format = function(tpl, options) {\n            log.push(options.copyrights);\n        }\n        map.zoomToExtent(new OpenLayers.Bounds(-14768652, 4492113, -12263964, 5744457));\n        t.delay_call(2, function() {\n            t.ok(log.join(\"\") !== \"\", \"Copyright not empty\");\n            OpenLayers.String.format = format;\n            map.destroy();\n        });\n    }\n    \n    function test_getXYZ(t) {\n        t.plan(1);\n        \n        var map = new OpenLayers.Map(\"map\", {allOverlays: true});\n        var osm = new OpenLayers.Layer.OSM();\n        map.addLayer(osm);\n        map.zoomToExtent(new OpenLayers.Bounds(11373579,-2445208,13628777,680760));\n        layer = new OpenLayers.Layer.Bing(options);\n        map.addLayer(layer);\n        \n        t.delay_call(2, function() {\n            var xyz = layer.getXYZ(layer.getTileBounds(new OpenLayers.Pixel(1,1)));\n            t.eq(xyz.z, OpenLayers.Util.indexOf(layer.serverResolutions, map.getResolution()), \"zoom level correct\");\n        });\n    }\n\n    function test_clone(t) {\n        t.plan(1);\n        \n        var clone;\n        \n        layer = new OpenLayers.Layer.Bing(options);\n        clone = layer.clone();\n        t.ok(clone instanceof OpenLayers.Layer.Bing, \"clone is a Layer.Bing instance\");\n    }\n\n    function test_protocol(t)\n    {\n        t.plan(5);\n\n        var map = new OpenLayers.Map(\"map\");\n        layer = new OpenLayers.Layer.Bing(options);\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        \n        t.delay_call(5, function() {\n            t.ok(OpenLayers.Util.indexOf(layer.attribution, '<img src=\"//') != -1, \"Attribution contains a logo with protocol //\");\n            t.ok(OpenLayers.Util.indexOf(layer.attribution, '<img src=\"http://') == -1, \"Attribution logo does not have http:// protocol\");\n            t.ok(layer.grid[1][1].url.indexOf('http:') == -1, \"Tile url does not contain http:\");\n\n            map.destroy();\n        });\n\n        var map2 = new OpenLayers.Map(\"map\");\n        layer_https = new OpenLayers.Layer.Bing(OpenLayers.Util.applyDefaults({protocol: 'https:'}, options));\n        map2.addLayer(layer_https);\n        map2.zoomToMaxExtent();\n\n        t.delay_call(5, function() {\n            t.ok(OpenLayers.Util.indexOf(layer_https.attribution, '<img src=\"https://') != -1, \"Attribution logo has https:// protocol\");\n            t.ok(layer_https.grid[1][1].url.indexOf('https:') == 0, \"Tile url contains https:\");\n            map2.destroy();\n        });\n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/EventPane.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var isOpera = (navigator.userAgent.indexOf(\"Opera\") != -1);\n    var layer; \n\n    function test_Layer_EventPane_constructor (t) {\n        t.plan( 5 );\n        \n        var layer = new OpenLayers.Layer.EventPane('Test Layer');\n        \n        t.ok( layer instanceof OpenLayers.Layer.EventPane, \"new OpenLayers.Layer.EventPane returns object\" );\n        t.eq( layer.CLASS_NAME, \"OpenLayers.Layer.EventPane\", \"CLASS_NAME variable set correctly\");\n        t.eq( layer.name, \"Test Layer\", \"layer.name is correct\" );\n        t.eq( layer.isBaseLayer, true, \"EventPane layer is always base layer\" );\n        if (!isMozilla) {\n            t.ok( true, \"skipping element test outside of Mozilla\");\n        } else {\n            t.ok( layer.pane instanceof HTMLDivElement, \"layer.pane is an HTMLDivElement\" );\n        }\n    }\n\n    function test_Layer_EventPane_clone (t) {\n        t.plan( 1 );\n        t.ok( true, \"need to actually write some tests here\" );\n        return;\n        \n        /// FIX ME FIX ME: fix this later\n\n        var map = new OpenLayers.Map('map'); \n        var options = { chicken: 151, foo: \"bar\" };\n        var layer = new OpenLayers.Layer('Test Layer', options);\n        map.addLayer(layer);\n\n        // randomly assigned property\n        layer.chocolate = 5;\n\n        var clone = layer.clone();\n\n        t.ok( clone instanceof OpenLayers.Layer, \"new OpenLayers.Layer returns object\" );\n        t.eq( clone.name, \"Test Layer\", \"default clone.name is correct\" );\n        t.ok( ((clone.options[\"chicken\"] == 151) && (clone.options[\"foo\"] == \"bar\")), \"clone.options correctly set\" );\n        t.eq(clone.chocolate, 5, \"correctly copied randomly assigned property\");\n\n        layer.addOptions({chicken:152});\n        t.eq(clone.options[\"chicken\"], 151, \"made a clean copy of options\");        \n\n        \n        t.ok( clone.map == null, \"cloned layer has map property set to null\")\n        \n    }\n\n    function test_Layer_EventPane_setMap (t) {\n\n// MOUSEMOVE test does not seem to work... \n//         t.plan( 2 );    \n\n        if (OpenLayers.BROWSER_NAME != \"firefox\" && OpenLayers.BROWSER_NAME != \"mozilla\") {\n            t.plan(4);\n        } else {\n            t.plan(0);\n            t.debug_print(\"Firefox gives different results for different browsers on setMap on EventPane, so just don't run it for now.\") \n            return;\n        }\n        var map = new OpenLayers.Map('map');\n        \n        layer = new OpenLayers.Layer.EventPane('Test Layer');\n\n        //give dummy function so test wont bomb on layer.setMap()\n        layer.loadMapObject = function() { };\n        layer.getWarningHTML = function() { this.warning = true; return \"\"; };\n        map.addLayer(layer);\n        t.eq( parseInt(layer.pane.style.zIndex) - parseInt(layer.div.style.zIndex),\n            1, \"layer pane is 1 z-level above its div\" );\n\n        t.ok( layer.warning, \"warning correctly registered on no mapObject load\" );\n\n        layer2 = new OpenLayers.Layer.EventPane('Test Layer');\n\n        //give dummy function so test wont bomb on layer.setMap()\n        layer2.loadMapObject = function() { this.mapObject = {}; };\n        layer2.getWarningHTML = function() { this.warning = true; return \"\"; }\n\n        map.addLayer(layer2);\n        t.ok(!layer2.warning, \"warning not registered on mapObject load\");\n\n        var log = [];\n        map.events.register(\"mousemove\", map, function(event) {\n            log.push(event);\n        });\n        \n        if (document.createEvent) { // Mozilla\n            var evObj = document.createEvent('MouseEvents');\n            evObj.initEvent('mousemove', true, false);\n            map.viewPortDiv.dispatchEvent(evObj);\n        } else if(document.createEventObject) { // IE\n            map.viewPortDiv.fireEvent('onmousemove');\n        }\n        \n        t.eq(log.length, 1, \"got one event\");\n        \n    }\n\n    function test_Layer_EventPane_setVisibility (t) {\n        t.plan( 2 );    \n        layer = new OpenLayers.Layer.EventPane('Test Layer');\n        layer.setVisibility(false);\n        t.eq(layer.visibility, false, \"layer pane is now invisible\");\n        layer.setVisibility(true);\n        t.eq(layer.visibility, true, \"layer pane is now visible\");\n    }\n\n    \n    function test_Layer_EventPane_removeLayer(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map('map');\n        \n        layer = new OpenLayers.Layer.EventPane('Test Layer');\n        layer.loadMapObject = function() { };\n        layer.getWarningHTML = function() { this.warning = true; return \"\"; };\n        map.addLayer(layer);\n        map.removeLayer(layer);\n        var parent = layer.pane.parentNode;\n        // IE creates a DOCUMENT_FRAGMENT_NODE for the parent\n        t.ok(!parent || parent.nodeType == 11, \"Layer.pane removed from dom.\");\n    }\n   \n    function test_repeat_add(t) {\n\n        t.plan(1);\n        var map = new OpenLayers.Map(\"map\");\n        \n        layer = new OpenLayers.Layer.EventPane();\n        layer.loadMapObject = function() {};\n        layer.getWarningHTML = function() {this.warning = true; return \"\";};\n\n        map.addLayer(layer);\n        map.removeLayer(layer);\n        \n        // try adding the layer a second time\n        var msg = \"layer successfully added after being removed\";\n        var pass = true;\n        try {\n            map.addLayer(layer);\n        } catch (err) {\n            msg = \"couldn't add layer after removing: \" + err;\n            pass = false;\n        }\n        t.ok(pass, msg);\n\n    }\n    \n    function test_destroy(t) {\n        \n        t.plan(2);\n        layer = new OpenLayers.Layer.EventPane();\n        t.ok(layer.pane, \"pane created on initialize\");\n        \n        layer.destroy();\n        t.ok(!layer.pane, \"pane deleted on destroy\");\n        \n    }\n\n\n  </script>\n</head>\n<body>\n  <div id=\"map\" style=\"height:500px;width:500px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/FixedZoomLevels.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var layer; \n\n    function test_Layer_FixedZoomLevels (t) {\n        t.plan( 39 );\n        \n        var layer = { 'MIN_ZOOM_LEVEL': 5,\n                      'MAX_ZOOM_LEVEL': 10 };        \n\n\n    //defaults \n\n        layer = p_createLayer(layer);\n        p_minMaxNum(t, layer, layer.MIN_ZOOM_LEVEL, layer.MAX_ZOOM_LEVEL, \"nothing specified\");\n\n    \n    //layer.options\n\n        // min,num\n        layer = p_createLayer(layer, {}, { minZoomLevel: 3, numZoomLevels: 12});\n        p_minMaxNum(t, layer, layer.MIN_ZOOM_LEVEL, layer.MAX_ZOOM_LEVEL, \"min too low num too high(layer.options)\");\n\n        layer = p_createLayer(layer, {}, { minZoomLevel: 6, numZoomLevels: 3 });\n        p_minMaxNum(t, layer, 6, 8, \"valid min,num(layer.options)\");\n\n\n        // max\n        layer = p_createLayer(layer, {}, { maxZoomLevel: 9 });\n        p_minMaxNum(t, layer, layer.MIN_ZOOM_LEVEL, 9, \"valid max(layer.options)\");\n\n        layer = p_createLayer(layer, {}, { maxZoomLevel: 12 });\n        p_minMaxNum(t, layer, layer.MIN_ZOOM_LEVEL, layer.MAX_ZOOM_LEVEL, \"invalid max(layer.options)\");\n\n\n\n    //map\n\n        // min,num\n        layer = p_createLayer(layer, { minZoomLevel: 3, numZoomLevels: 12});\n        p_minMaxNum(t, layer, layer.MIN_ZOOM_LEVEL, layer.MAX_ZOOM_LEVEL, \"min too low num too high(map)\");\n\n        layer = p_createLayer(layer, { minZoomLevel: 6, numZoomLevels: 3 });\n        p_minMaxNum(t, layer, 6, 8, \"valid min,num(map)\");\n\n\n        // max\n        layer = p_createLayer(layer, { maxZoomLevel: 9 });\n        p_minMaxNum(t, layer, layer.MIN_ZOOM_LEVEL, 9, \"valid max(map)\");\n\n        layer = p_createLayer(layer, { maxZoomLevel: 12 });\n        p_minMaxNum(t, layer, layer.MIN_ZOOM_LEVEL, layer.MAX_ZOOM_LEVEL, \"invalid max(map)\");\n\n    //map vs. options\n\n        layer = p_createLayer(layer, {minZoomLevel: 6, numZoomLevels: 2}, { minZoomLevel: 7, numZoomLevels: 3});\n        p_minMaxNum(t, layer, 7, 9, \"min,num(layer.options) wins over (map)\");\n\n        layer = p_createLayer(layer, {minZoomLevel: 6, maxZoomLevel: 8}, { minZoomLevel: 7, maxZoomLevel: 9});\n        p_minMaxNum(t, layer, 7, 9, \"min,max(layer.options) wins over (map)\");\n\n\n    // numZoomLevels vs. maxZoomLevel\n    \n        layer = p_createLayer(layer, {maxZoomLevel: 8, numZoomLevels: 6});\n        p_minMaxNum(t, layer, layer.MIN_ZOOM_LEVEL, 10, \"min,max(layer.options) wins over (map)\");\n\n    // resolutions array\n\n        var resolutions = Array(20);\n        for (var i = 0; i < 20; i++) {\n            resolutions[i] = Math.random();\n        }\n        OpenLayers.Util.extend(layer, {RESOLUTIONS:resolutions});\n        var minZoomLevel = 6;\n        var numZoomLevels = 2;\n        layer = p_createLayer(layer, {}, {minZoomLevel: minZoomLevel, numZoomLevels: numZoomLevels});\n        t.eq( layer.resolutions.length, numZoomLevels, \"length of resolutions array ok\");\n        for (var i = 0; i < numZoomLevels; i++) {\n            t.eq( layer.resolutions[i], resolutions[i + minZoomLevel], \"resolutions array at index \" + i + \" ok\");\n        }\n    }\n    \n    function test_getMapObjectZoomFromOLZoom(t) {\n        t.plan(4);\n        \n        var map = new OpenLayers.Map(\"map\", {allOverlays: true});\n        var xyz = new OpenLayers.Layer.XYZ(\"xyz\", \"${x}${y}${z}\", {\n            sphericalMercator: true,\n            resolutions: [39135.7584765625, 19567.87923828125, 9783.939619140625]\n        });\n        var fixed = new (OpenLayers.Class(OpenLayers.Layer, OpenLayers.Layer.FixedZoomLevels, {\n             initialize: function() {\n                OpenLayers.Layer.prototype.initialize.apply(this, arguments);\n            }\n        }))(\"fixed\", {\n            resolutions: [156543.03390625, 78271.516953125, 39135.7584765625, 19567.87923828125, 9783.939619140625],\n            minZoomLevel: 1\n        });\n        map.addLayers([xyz, fixed]);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 2);\n        // map.getZoom() returns 2\n        t.eq(fixed.getMapObjectZoomFromOLZoom(map.getZoom()), 4, \"correct return value from getMapObjectZoomFromOLZoom\");\n        t.eq(fixed.getOLZoomFromMapObjectZoom(4), map.getZoom() - fixed.minZoomLevel, \"correct return value from getOLZoomFromMapObjectZoom\");\n\n        map.setBaseLayer(fixed);\n        // map.getZoom() returns 4 now\n        t.eq(fixed.getMapObjectZoomFromOLZoom(map.getZoom()), 5, \"correct return value from getMapObjectZoomFromOLZoom\");\n        t.eq(fixed.getOLZoomFromMapObjectZoom(5), map.getZoom(), \"correct return value from getOLZoomFromMapObjectZoom\");\n    }\n\n    function p_createLayer(layer, mapOptions, layerOptions) {\n\n        layer.map = mapOptions || {};\n        layer.options = layerOptions || {};\n        OpenLayers.Layer.FixedZoomLevels.prototype.initResolutions.apply(layer);\n\n        return layer;\n    }\n\n    function p_minMaxNum(t, layer, min, max, msg) {\n\n        t.eq( layer.minZoomLevel, min, \"min zoom level inherited from layer constant: \" + msg);\n        t.eq( layer.maxZoomLevel, max, \"max zoom level inherited from layer constant: \" + msg);\n        t.eq( layer.numZoomLevels, max - min + 1, \"num zoom levels correctly calcuated: \" + msg);\n        \n    }\n\n\n  </script>\n</head>\n<body>\n  <div id=\"map\" style=\"width:256px;height:256px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/GeoRSS.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var isMSIE    = (navigator.userAgent.indexOf(\"MSIE\") > -1);\n    var layer; \n\n    var georss_txt = \"./georss.txt\";\n    var atom_xml   = \"./atom-1.0.xml\";\n\n    // if this test is running online, different rules apply\n    if (isMSIE) {\n        georss_txt = \".\" + georss_txt;\n        atom_xml = \".\" + atom_xml;\n    }\n\n    function test_Layer_GeoRSS_constructor (t) {\n        t.plan( 7 );\n        layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt );\n        t.ok( layer instanceof OpenLayers.Layer.GeoRSS, \"new OpenLayers.Layer.GeoRSS returns object\" );\n        t.eq( layer.location, georss_txt, \"layer.location is correct\" );\n        var markers;\n        layer.loadRSS();\n        t.delay_call( 1, function() {  \n            t.eq( layer.markers.length, 40, \"marker length is correct\" );\n            var ll = new OpenLayers.LonLat(-71.142197, 42.405696);\n            var theTitle = \"Knitting Room\";\n            var theDescription = 'This little shop is jammed full. Yarn, yarn everywhere. They make the most of every possible nook and cranny. I like this place also because they have a lot of different kinds of knitting needles in all different sizes. Also, the people who work here are younger and hipper than in the other stores I go to. I reccomend buying supplies here and then knitting your way through a good documentary at the Capitol Theater across the street.<br/>Address: 2 lake St, Arlington, MA <br/>Tags: knitting, yarn, pins and needles, handspun, hand dyed, novelty yarn, fancy, simple, young, hip, friendly, needles, addy, cute hats<br /><br /><a href=\"http://platial.com/place/90306\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/90306\">Grab this on Platial</a> ';\n            t.ok( layer.markers[0].lonlat.equals(ll), \"lonlat on first marker is correct\" );\n            t.eq( layer.name, \"Crschmidt's Places At Platial\", \"Layer name is correct.\" );\n            t.eq( layer.features[0].data.title, theTitle);\n            t.eq( layer.features[0].data.description, theDescription);\n        } );\n    }\n    \n    function test_Layer_GeoRSS_dontUseFeedTitle (t) {\n        t.plan( 1 );\n        layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt, {'useFeedTitle': false} );\n        t.delay_call( 1, function() {  \n            t.eq( layer.name, \"Test Layer\", \"Layer name is correct when not used from feed.\" );\n        } );\n    }\n    \n    function test_Layer_GeoRSS_AtomParsing (t) {\n        t.plan( 6 );\n        layer = new OpenLayers.Layer.GeoRSS('Test Layer', atom_xml );\n        t.ok( layer instanceof OpenLayers.Layer.GeoRSS, \"new OpenLayers.Layer.GeoRSS returns object\" );\n        t.eq( layer.location, atom_xml, \"layer.location is correct\" );\n        var markers;\n        layer.loadRSS();\n        t.delay_call( 1, function() {  \n            t.eq( layer.markers.length, 2, \"marker length is correct\" );\n            var ll = new OpenLayers.LonLat(29.9805, 36.7702);\n            t.ok( layer.markers[0].lonlat.equals(ll), \"lonlat on first marker is correct\" );\n            t.like( layer.features[0].data['popupContentHTML'], '<a class=\"link\" href=\"http://pleiades.stoa.org/places/638896\" target=\"_blank\">Unnamed Tumulus</a>', \"Link is correct.\");\n            t.eq( layer.name, \"tumulus\", \"Layer name is correct.\" );\n        } );\n    }\n\n    function test_Layer_GeoRSS_draw (t) { \n//        t.plan(5);\n        t.plan( 2 );\n        layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt);\n        t.ok( layer instanceof OpenLayers.Layer.GeoRSS, \"new OpenLayers.Layer.GeoRSS returns object\" );\n        var map = new OpenLayers.Map('map');\n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(baseLayer);\n        map.addLayer(layer);\n        t.delay_call( 1, function() { \n          map.setCenter(new OpenLayers.LonLat(0,0),0);\n          t.eq( map.layers[1].name, layer.name, \"Layer name is correct\" );\n\n        });;\n    }\n    function test_Layer_GeoRSS_load_events (t) {\n        t.plan( 1 );    \n        layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt);\n        var map = new OpenLayers.Map('map');\n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(baseLayer);\n        map.addLayer(layer);\n        layer.events.register(\"loadstart\", t, function() { this.ok(true, \"loadstart event triggered once (#1580)\") });\n        map.setCenter(new OpenLayers.LonLat(0,0),0);\n    }\n    function test_Layer_GeoRSS_events (t) {\n        t.plan( 4 );    \n        layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt);\n        var map = new OpenLayers.Map('map');\n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(baseLayer);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0),0);\n        var event = {};\n        t.delay_call( 2, function() {  \n          t.ok(layer.markers[0].events, \"First marker has an events object\");\n          t.eq(layer.markers[0].events.listeners['click'].length, 1, \"Marker events has one object\");\n          layer.markers[0].events.triggerEvent('click', event);\n          t.eq(map.popups.length, 1, \"Popup opened correctly\");\n          layer.markers[1].events.triggerEvent('click', event);\n          t.eq(map.popups.length, 1, \"1st popup gone, 2nd Popup opened correctly\");\n        });\n    }\n    function test_Layer_GeoRSS_popups (t) {\n        t.plan( 4 );    \n        layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt);\n        var map = new OpenLayers.Map('map');\n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(baseLayer);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0),0);\n        var event = {};\n        t.delay_call( 1, function() {  \n          t.ok(layer.markers[0].events, \"First marker has an events object\");\n          t.eq(layer.markers[0].events.listeners['click'].length, 1, \"Marker events has one object\");\n          layer.markers[0].events.triggerEvent('click', event);\n          t.eq(map.popups.length, 1, \"Popup opened correctly\");\n          layer.markers[1].events.triggerEvent('click', event);\n          t.eq(map.popups.length, 1, \"1st popup gone, 2nd Popup opened correctly\");\n        });\n        \n    }\n    function test_Layer_GeoRSS_resizedPopups(t) {\n        layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt, {'popupSize': new OpenLayers.Size(200,100)});\n        t.plan( 4 );    \n        var map = new OpenLayers.Map('map');\n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(baseLayer);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0),0);\n        var event = {};\n        t.delay_call( 1, function() {  \n          t.ok(layer.markers[0].events, \"First marker has an events object\");\n          t.eq(layer.markers[0].events.listeners['click'].length, 1, \"Marker events has one object\");\n          layer.markers[0].events.triggerEvent('click', event);\n          t.eq(map.popups.length, 1, \"Popup opened correctly\");\n          map.popups[0].size.w=300;\n          layer.markers[1].events.triggerEvent('click', event);\n          t.eq(map.popups.length, 1, \"1st popup gone, 2nd Popup opened correctly\");\n        });\n    }    \n\n    function test_Layer_GeoRSS_icon(t) {\n        t.plan( 3 );\n        layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt);\n        var the_icon = new OpenLayers.Icon('http://boston.openguides.org/markers/AQUA.png');\n        var otherLayer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt,{icon:the_icon});\n        var map = new OpenLayers.Map('map');\n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(baseLayer);\n        map.addLayers([layer,otherLayer]);\n        map.setCenter(new OpenLayers.LonLat(0,0),0);\n        var defaultIcon = OpenLayers.Marker.defaultIcon();\n        layer.loadRSS();\n        otherLayer.loadRSS();\n        t.delay_call( 2, function() {\n            t.ok(layer.markers[0].icon, \"The layer has a icon\");\n            t.eq(layer.markers[0].icon.url, defaultIcon.url, \"The layer without icon has the default icon.\");\n            t.eq(otherLayer.markers[0].icon.url, the_icon.url,\"The layer with an icon has that icon.\");\n        });\n    }\n    function test_Layer_GeoRSS_loadend_Event(t) {\n        var browserCode = OpenLayers.BROWSER_NAME;\n        if (browserCode == \"msie\") {\n            t.plan(1);\n            t.ok(true, \"IE fails the GeoRSS test. This could probably be fixed by someone with enough energy to fix it.\");\n        } else {\n            t.plan(2);\n            layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt);\n            t.delay_call(2, function() { \n                layer.events.register('loadend', layer, function() { \n                    t.ok(true, \"Loadend event fired\"); \n                });\n                layer.parseData({\n                    'responseText': '<xml xmlns=\"http://example.com\"><title> </title></xml>'\n                });\n                t.ok(true, \"Parsing data didn't fail\"); \n            });\n        } \n    }\n\n    function test_Layer_GeoRSS_destroy (t) {\n        t.plan( 1 );    \n        layer = new OpenLayers.Layer.GeoRSS('Test Layer', georss_txt);\n        var map = new OpenLayers.Map('map');\n        map.addLayer(layer);\n        t.delay_call( 1, function() {  \n        layer.destroy();\n        t.eq( layer.map, null, \"layer.map is null after destroy\" );\n        });\n    }\n\n  </script>\n</head>\n<body>\n  <div id=\"map\" style=\"width:500px; height:500px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/Google/v3.html",
    "content": "<html>\n<head>\n    <script src=\"http://maps.google.com/maps/api/js?sensor=false&amp;v=3.6\"></script>\n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    var layer; \n                   \n    function test_Layer_Google_constructor (t) {\n        t.plan( 5 );\n        \n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.Google('Goog Layer');\n        map.addLayer(layer);\n        \n        \n        t.ok( layer instanceof OpenLayers.Layer.Google, \"new OpenLayers.Layer.Google returns object\" );\n        t.eq( layer.CLASS_NAME, \"OpenLayers.Layer.Google\", \"CLASS_NAME variable set correctly\");\n    \n        t.eq( layer.name, \"Goog Layer\", \"layer.name is correct\" );\n    \n        t.ok ( layer.mapObject != null, \"GMap Object correctly loaded\");\n        \n        t.eq(layer.version, \"3\", \"API version 3 detected.\");\n    }\n    \n    function test_clone(t) {\n        t.plan(2);\n        var layer, clone;\n        \n        // test default layer\n        layer = new OpenLayers.Layer.Google();\n        clone = layer.clone();\n        t.ok(clone instanceof OpenLayers.Layer.Google, \"[default] good instance\");\n        \n        layer.destroy();\n        clone.destroy();\n        \n        // test with alt type\n        layer = new OpenLayers.Layer.Google(null, {type: google.maps.MapTypeId.SATELLITE});\n        clone = layer.clone();\n        t.ok(clone.type === google.maps.MapTypeId.SATELLITE, \"[sat] correct type\");\n        \n        layer.destroy();\n        clone.destroy();   \n    }\n    \n    function test_Layer_Google_isBaseLayer (t) {\n        t.plan(1);\n        \n        var layer = new OpenLayers.Layer.Google('Goog Layer');\n    \n        t.ok(layer.isBaseLayer, \"a default load of google layer responds as a base layer\");\n    }    \n    \n    function test_Layer_Google_Translation_lonlat (t) {\n        t.plan( 4 );\n        \n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.Google('Goog Layer');\n        map.addLayer(layer);\n    \n    // these two lines specify an appropriate translation. \n    //  the code afterwards works by itself to test that translation\n    //  works correctly both ways.\n       var gLatLng = new google.maps.LatLng(50,100);\n       // v3 uses sphericalMercator by default\n       var correspondingOLLonLat = layer.forwardMercator(100, 50);\n    \n       olLonLat = layer.getOLLonLatFromMapObjectLonLat(gLatLng);\n       t.ok(olLonLat.equals(correspondingOLLonLat), \"Translation from GLatLng to OpenLayers.LonLat works\");\n    \n       var transGLatLng = layer.getMapObjectLonLatFromOLLonLat(olLonLat);\n       t.ok( transGLatLng.equals(gLatLng), \"Translation from OpenLayers.LonLat to GLatLng works\");\n    \n       t.ok( layer.getMapObjectLonLatFromOLLonLat(null) == null, \"getGLatLngFromOLLonLat(null) returns null\");\n       t.ok( layer.getOLLonLatFromMapObjectLonLat(null) == null, \"getOLLonLatFromGLatLng(null) returns null\");\n    }\n    \n    function test_Layer_Google_Translation_pixel (t) {\n        t.plan( 4 );\n        \n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.Google('Goog Layer');\n        map.addLayer(layer);\n    \n     // these two lines specify an appropriate translation. \n     //  the code afterwards works by itself to test that translation\n     //  works correctly both ways.\n        var gPoint = new google.maps.Point(50,100);\n        var correspondingOLPixel = new OpenLayers.Pixel(50, 100);\n    \n    \n        olPixel = layer.getOLPixelFromMapObjectPixel(gPoint);\n        t.ok( olPixel.equals(correspondingOLPixel), \"Translation from GPoint to OpenLayers.Pixel works\");\n    \n        var transGPoint = layer.getMapObjectPixelFromOLPixel(olPixel);\n        t.ok( transGPoint.equals(gPoint), \"Translation from OpenLayers.Pixel to GPoint works\");\n    \n        t.ok( layer.getMapObjectPixelFromOLPixel(null) == null, \"getGPointFromOLPixel(null) returns null\");\n        t.ok( layer.getOLPixelFromMapObjectPixel(null) == null, \"getOLPixelFromGPoint(null) returns null\");\n    }\n    \n    function test_Layer_destroy (t) {\n        t.plan( 5 );    \n    \n        var map = new OpenLayers.Map('map');\n        \n        layer = new OpenLayers.Layer.Google('Test Layer');\n        map.addLayer(layer);\n    \n        layer.destroy();\n    \n        t.eq( layer.name, null, \"layer.name is null after destroy\" );\n        t.eq( layer.div, null, \"layer.div is null after destroy\" );\n        t.eq( layer.map, null, \"layer.map is null after destroy\" );\n        t.eq( layer.options, null, \"layer.options is null after destroy\" );\n        t.eq( layer.gmap, null, \"layer.gmap is null after destroy\" );\n    }\n    \n    function test_Layer_Goole_forwardMercator(t){\n        t.plan(2);\n        //Just test that the fowardMercator function still exists.\n        var layer = new OpenLayers.Layer.Google('Test Layer', {'sphericalMercator': true});\n        layer.forwardMercator = function(evt) {\n            t.ok(true,\n                 \"GoogleMercator.forwardMercator was called and executed.\" );\n            return;\n        }\n        layer.forwardMercator();\n        //Now test the fowardMercator returns the expected LonLat object\n        var layer = new OpenLayers.Layer.Google('Test Layer', {'sphericalMercator': true});\n        var lonlat2 = new OpenLayers.LonLat(Math.random(),Math.random());\n        var result = layer.forwardMercator(lonlat2.lon, lonlat2.lat);\n        t.ok(result instanceof OpenLayers.LonLat, \"OpenLayers.Google.fowardMercator returns LonLat object\" );\n    }\n    \n    function test_Layer_Google_overlay(t) {\n        // Test for #849.\n        t.plan(1);\n        var map = new OpenLayers.Map( 'map' , \n        { controls: [] , 'numZoomLevels':20});\n    \n        var satellite = new OpenLayers.Layer.Google( \"Google Satellite\" , {type: google.maps.MapTypeId.SATELLITE, 'maxZoomLevel':18} );\n        var layer = new OpenLayers.Layer.WMS( \"OpenLayers WMS\", \n                \"http://labs.metacarta.com/wms/vmap0\", {layers: 'basic', 'transparent':true}, \n                  {isBaseLayer: false, singleTile: true, displayOutsideMaxExtent: true} );\n    \n        map.addLayers([satellite, layer]);\n        map.setCenter(new OpenLayers.LonLat(10.205188,48.857593), 5);\n        map.zoomIn();\n        var size = map.getSize();\n        var px = new OpenLayers.Pixel(size.w, size.h);\n        var br = map.getLonLatFromPixel(px);\n        t.ok(layer.grid[0][0].bounds.containsLonLat(br), \"Bottom right pixel is covered by untiled WMS layer\");\n    }    \n    function test_Layer_Google_isBaseLayer (t) {\n        t.plan(3);\n        var map = new OpenLayers.Map( 'map' , \n        { controls: [] , 'numZoomLevels':20});\n    \n        var satellite = new OpenLayers.Layer.Google( \"Google Satellite\" , {type: google.maps.MapTypeId.SATELLITE, 'maxZoomLevel':18} );\n        map.addLayers([satellite]);\n        map.zoomToMaxExtent();\n        \n        t.eq(satellite.div.style.display, \"\", \"Satellite layer is visible.\");\n        satellite.setVisibility(false);\n        t.eq(satellite.div.style.display, \"none\", \"Satellite layer is not visible.\");\n        satellite.setVisibility(true);\n        t.eq(satellite.div.style.display, \"block\", \"Satellite layer is visible.\");\n    }    \n    \n     function test_allOverlays_invisible(t) {\n\n         t.plan(1);\n\n         var map = new OpenLayers.Map('map', {allOverlays: true});\n\n         var osm = new OpenLayers.Layer.OSM();\n         var gmap = new OpenLayers.Layer.Google(\"Google Streets\", {visibility: false});\n\n         // keep track of last argument to setGMapVisibility\n         var visible;\n         var original = gmap.setGMapVisibility;\n         gmap.setGMapVisibility = function(vis) {\n             visible = vis;\n             original.apply(gmap, arguments);\n         }\n\n         map.addLayers([osm, gmap]);\n         map.zoomToMaxExtent();\n\n         t.ok(visible === false, \"setGMapVisibility last called with false\");\n\n         map.destroy();\n\n     }\n     \n     function test_allOverlays_pan(t) {\n\n         t.plan(8);\n\n         var origPrecision = OpenLayers.Util.DEFAULT_PRECISION;\n         // GMaps v3 seems to use a default precision of 13, which is lower\n         // than what we use in OpenLayers.\n         // See http://trac.osgeo.org/openlayers/ticket/3059\n         OpenLayers.Util.DEFAULT_PRECISION = 13;\n\n         var map = new OpenLayers.Map('map', {allOverlays: true});\n\n         var gmap = new OpenLayers.Layer.Google(\"Google Streets\");\n         var osm = new OpenLayers.Layer.OSM();\n         map.addLayers([gmap, osm]);\n\n         var origin = new OpenLayers.LonLat(1000000, 6000000);\n         map.setCenter(origin, 4);\n         var resolution = map.getResolution();\n         \n         var dx, dy, center, expected;\n\n         // confirm that panning works with Google visible\n         dx = 100, dy = -100;\n         map.pan(dx, dy, {animate: false});\n         center = map.getCenter();\n         expected = new OpenLayers.LonLat(\n             origin.lon + (resolution * dx),\n             origin.lat - (resolution * dy)\n         );\n         t.eq(center.lon, expected.lon, \"x panning with Google visible \" + dx + \", \" + dy);\n         t.eq(center.lat, expected.lat, \"y panning with Google visible \" + dx + \", \" + dy);\n         map.pan(-dx, -dy, {animate: false});\n         center = map.getCenter();\n         t.eq(center.lon, origin.lon, \"x panning with Google visible \" + (-dx) + \", \" + (-dy));\n         t.eq(center.lat, origin.lat, \"y panning with Google visible \" + (-dx) + \", \" + (-dy));\n\n         // confirm that panning works with Google invisible\n         gmap.setVisibility(false);\n         dx = 100, dy = -100;\n         map.pan(dx, dy, {animate: false});\n         center = map.getCenter();\n         expected = new OpenLayers.LonLat(\n             origin.lon + (resolution * dx),\n             origin.lat - (resolution * dy)\n         );\n         t.eq(center.lon, expected.lon, \"x panning with Google invisible \" + dx + \", \" + dy);\n         t.eq(center.lat, expected.lat, \"y panning with Google invisible \" + dx + \", \" + dy);\n         map.pan(-dx, -dy, {animate: false});\n         center = map.getCenter();\n         t.eq(center.lon, origin.lon, \"x panning with Google invisible \" + (-dx) + \", \" + (-dy));\n         t.eq(center.lat, origin.lat, \"y panning with Google invisible \" + (-dx) + \", \" + (-dy));\n\n         map.destroy();\n         OpenLayers.Util.DEFAULT_PRECISION = origPrecision;\n     }\n     \n     function test_wrapDateLine(t) {\n         t.plan(2);\n\n         var origPrecision = OpenLayers.Util.DEFAULT_PRECISION;\n         // Our default precision is very high - millimeters should be enough.\n         // See http://trac.osgeo.org/openlayers/ticket/3059\n         OpenLayers.Util.DEFAULT_PRECISION = 12;\n\n         var map = new OpenLayers.Map(\"map\");\n\n         var gmap = new OpenLayers.Layer.Google(\"Google Streets\");\n         map.addLayer(gmap);\n         map.setCenter(new OpenLayers.LonLat(0, 0), 1);\n         \n         var center;\n         \n         // pan to the edge of the world\n         map.pan(256, 0, {animate: false});\n         center = map.getCenter();\n         t.eq(center.lon, 20037508.34, \"edge of the world\");\n         // pan off the edge of the world\n         map.pan(100, 0, {animate: false});\n         center = map.getCenter();\n         var expect = OpenLayers.Util.toFloat(100 * map.getResolution() - 20037508.34);\n         t.eq(center.lon, expect, \"magically back in the western hemisphere\");\n         \n         map.destroy();\n         OpenLayers.Util.DEFAULT_PRECISION = origPrecision;         \n     }\n\n     function test_respectDateLine(t) {\n         t.plan(2);\n\n         var map = new OpenLayers.Map(\"map\");\n\n         var gmap = new OpenLayers.Layer.Google(\"Google Streets\", {wrapDateLine: false});\n         map.addLayer(gmap);\n         map.setCenter(new OpenLayers.LonLat(0, 0), 1);\n         \n         var center;\n         \n         // pan to the edge of the world\n         map.pan(256, 0, {animate: false});\n         center = map.getCenter();\n         t.eq(center.lon, 20037508.34, \"edge of the world\");\n         // pan off the edge of the world\n         map.pan(100, 0, {animate: false});\n         center = map.getCenter();\n         t.eq(center.lon, 20037508.34, \"whew, still on the edge\");\n         \n         map.destroy();\n         \n     }\n     \n     function test_moveViewportDiv(t) {\n         t.plan(2);\n         \n         var map = new OpenLayers.Map('map', {\n             projection: 'EPSG:3857',\n             center: [0, 0],\n             zoom: 1\n         });\n         var gmap = new OpenLayers.Layer.Google();\n         map.addLayer(gmap);\n         \n         t.delay_call(4, function() {\n             t.ok(map.viewPortDiv.parentNode !== map.div, 'viewport moved inside GMaps');\n\n             var osm = new OpenLayers.Layer.OSM();\n             map.addLayer(osm);\n             map.setBaseLayer(osm);\n\n             t.ok(map.viewPortDiv.parentNode === map.div, 'viewport moved back');\n         });\n     }\n     \n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width:500px; height: 500px\"></div>\n</body>\n</html>"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/Grid.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var layer; \n\n    var name = 'Test Layer';\n    var url = \"http://vmap0.tiles.osgeo.org/wms/vmap0\";\n    var params = {layers: 'basic', format: 'image/png'};\n\n    /**\n     *  NOTE TO READER:\n     * \n     *    Some of the tests on the Grid class actually use the WMS class. \n     *    This is because WMS is a subclass of Grid and it implements the \n     *    core functions which are necessary to test the tile-generation \n     *    mechanism. \n     * \n     */\n\n\n    function test_constructor (t) {\n        t.plan( 7 );\n                       \n        layer = new OpenLayers.Layer.Grid(name, url, params, null);\n        t.ok( layer instanceof OpenLayers.Layer.Grid, \"returns OpenLayers.Layer.Grid object\" );\n        t.eq( layer.buffer, 0, \"buffer default is 0\");\n        t.eq( layer.ratio, 1.5, \"ratio default is 1.5\");\n        t.eq( layer.numLoadingTiles, 0, \"numLoadingTiles starts at 0\");\n        t.ok( layer.tileClass === OpenLayers.Tile.Image, \"tileClass default is OpenLayers.Tile.Image\");\n        t.eq( layer.className, 'olLayerGrid', \"className default is olLayerGrid\");\n\n        var obj = {};\n        var func = function() {};\n        layer.events.register('tileloaded', obj, func);        \n\n        t.ok( layer.events.listeners['tileloaded'].length == 1, \"one listener for tileloaded after register\");        \n    }\n\n    function test_constructor_singleTile(t) {\n        t.plan(2);\n        layer = new OpenLayers.Layer.Grid(name, url, params, {singleTile: true});\n        t.eq( layer.className, 'olLayerGridSingleTile', \"className default is olLayerGridSingleTile\");\n        t.eq( layer.removeBackBufferDelay, 0, \"removeBackBufferDelay default is 0\");\n    }\n\n    function test_setMap(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map('map', {tileManager: null});\n        layer = new OpenLayers.Layer.Grid(name, url, params, null);\n        map.addLayer(layer);\n        t.ok(OpenLayers.Element.hasClass(layer.div, \"olLayerGrid\"),\n             \"olLayerGrid class assigned to layer div\");\n        map.destroy();\n    }\n\n    function test_setMap_singleTile(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.Grid(name, url, params, {singleTile: true});\n        map.addLayer(layer);\n        t.ok(OpenLayers.Element.hasClass(layer.div, \"olLayerGridSingleTile\"),\n             \"olLayerGridSingleTile class assigned to layer div\");\n        map.destroy();\n    }\n\n    function test_Layer_Grid_inittiles (t) {\n        t.plan( 2 );\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS(name, url, params, {buffer:2});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0),5);\n        t.eq( layer.grid.length, 8, \"Grid rows is correct.\" );\n        t.eq( layer.grid[0].length, 7, \"Grid cols is correct.\" );\n        \n    }\n\n    function test_Layer_Grid_tileClass(t) {\n        t.plan(2);\n\n        var myTileClass = OpenLayers.Class(OpenLayers.Tile, {});\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS(name, url, params, {\n            tileClass: myTileClass\n        });\n        map.addLayer(layer);\n\n        t.ok(layer.tileClass === myTileClass, \"tileClass is set\");\n        var instance = layer.addTile(new OpenLayers.Bounds(-10, 10, 50, 100),\n                                     new OpenLayers.Pixel(10, 12));\n\n        t.ok(instance instanceof myTileClass, \"addTile returns type is correct\");\n\n        map.destroy();\n    }\n    \n    function test_Layer_Grid_clearTiles (t) {\n        t.plan(4);\n\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS(name, url, params);\n        map.addLayer(layer);\n\n        map.setCenter(new OpenLayers.LonLat(0,0));\n\n        var numTiles = layer.grid.length * layer.grid[0].length;\n\n        //our count of how many times tile.destroy() is called\n        tilesDeleted = 0;\n        \n        //this will get set to false if we try to destroy a tile that has \n        // not been unhookedv\n        allTilesUnhooked = true;\n        \n        OpenLayers.Tile.Image.prototype._destroy =\n            OpenLayers.Tile.Image.prototype.destroy;\n\n        OpenLayers.Tile.Image.prototype.destroy = function() {\n            if (!this.unhooked) {\n                allTilesUnhooked = false;\n            }\n            tilesDeleted++;\n        }\n\n        layer.removeTileMonitoringHooks = function(tile) {\n            tile.unhooked = true;            \n        }\n\n        layer.clearGrid();\n\n        t.ok( layer.grid != null, \"layer.grid does not get nullified\" );\n        t.eq(tilesDeleted, numTiles, \"all tiles destroy()ed properly\");\n        t.ok(allTilesUnhooked, \"all tiles unhooked before being destroyed\");\n        t.eq(layer.gridResolution, null, \"gridResolution set to null\");\n\n        OpenLayers.Tile.Image.prototype.destroy =\n            OpenLayers.Tile.Image.prototype._destroy;\n        \n    }\n\n\n    function test_Layer_Grid_getTilesBounds(t) {\n        t.plan(4);\n\n        layer = new OpenLayers.Layer.WMS(name, url, params);\n\n\n    //normal grid\n        var bl = { bounds: new OpenLayers.Bounds(1,2,2,3)};\n        var tr = { bounds: new OpenLayers.Bounds(2,3,3,4)};\n        layer.grid = [ [6, tr], \n                       [bl, 7]];\n\n        var bounds = layer.getTilesBounds();\n        var testBounds = new OpenLayers.Bounds(1,2,3,4);\n        \n        t.ok( bounds.equals(testBounds), \"getTilesBounds() returns correct bounds\");\n        \n    //no tiles\n        layer.grid = [];\n        bounds = layer.getTilesBounds();\n        \n        t.ok(bounds == null, \"getTilesBounds() on a tile-less grid returns null\");\n        \n\n    //singleTile\n        var singleTile = { bounds: new OpenLayers.Bounds(1,2,3,4)};\n        layer.grid = [ [ singleTile ] ];\n        bounds = layer.getTilesBounds();\n        \n        t.ok( bounds.equals(testBounds), \"getTilesBounds() returns correct bounds\");\n    \n    //world wrapped around the dateline\n        var bl = { bounds: new OpenLayers.Bounds(0,-90,180,90)};\n        var tr = { bounds: new OpenLayers.Bounds(-180,-90,0,90)};\n        layer.grid = [[bl, tr]];\n\n        var bounds = layer.getTilesBounds();\n        var testBounds = new OpenLayers.Bounds(0,-90,360,90);\n    \n        t.ok( bounds.equals(testBounds), \"getTilesBounds() returns correct bounds\");\n        \n    }\n\n    function test_Layer_Grid_getResolution(t) {\n        t.plan( 1 );\n\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS(name, url, params);\n        map.addLayer(layer);\n\n        map.zoom = 5;\n\n        t.eq( layer.getResolution(), 0.0439453125, \"getResolution() returns correct value\");\n    }\n\n    function test_Layer_Grid_getZoomForExtent(t) {\n        t.plan( 2 );\n        var bounds, zoom;\n\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS(name, url, params);\n        map.addLayer(layer);\n\n        bounds = new OpenLayers.Bounds(10,10,12,12);\n        zoom = layer.getZoomForExtent(bounds);\n\n        t.eq( zoom, 8, \"getZoomForExtent() returns correct value\");\n\n        bounds = new OpenLayers.Bounds(10,10,100,100);\n        zoom = layer.getZoomForExtent(bounds);\n\n        t.eq( zoom, 2, \"getZoomForExtent() returns correct value\");\n    }   \n    \n    function test_moveGriddedTiles(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS(name, url, params, {buffer: 2});\n        map.addLayer(layer);\n        map.setCenter([0, 0], 5);\n        var count = 0;\n        layer.shiftColumn = function(prepend) {\n            ++count;\n            OpenLayers.Layer.WMS.prototype.shiftColumn.apply(this, arguments);\n        }\n        map.moveTo([15, 0]);\n        t.delay_call(.5, function() {\n            t.eq(count, 1, \"column shifted once\");\n        });\n    }\n    \n    function test_Layer_Grid_moveTo(t) {\n\n        t.plan(13);\n\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS(name, url, params);\n        layer.destroy = function() {}; //we're going to do funky things with the grid\n        layer.applyBackBuffer = function() {}; // backbuffering isn't under test here\n        map.addLayer(layer);\n        map.setCenter([-10, 0], 5);\n        \n        var log = [];\n\n    //make sure null bounds doesnt cause script error. \n    // no test necessary, just action\n        map.getExtent = function() { return null; }\n        layer.singleTile = false;\n        layer.moveTo(); //checks to make sure null bounds doesnt break us\n  \n\n      //observing globals\n        layer.initSingleTile = function(bounds) {\n            g_WhichFunc = \"InitSingle\";\n            g_Bounds = bounds;\n        };\n        layer.initGriddedTiles = function(bounds) {\n            g_WhichFunc = \"InitGridded\";\n            g_Bounds = bounds;\n        };\n        layer.moveGriddedTiles = function() {\n            g_WhichFunc = \"MoveGridded\";\n            g_Bounds = layer.map.getExtent();\n        };\n        var clearTestBounds = function() {\n            g_WhichFunc = null;\n            g_Bounds = null;\n        };\n\n      //default map extent (tested every time below)\n        b = new OpenLayers.Bounds(0,0,100,100);        \n        map.getExtent = function() {\n            return b;\n        };\n        var tilesBounds = null;\n        layer.getTilesBounds = function() {\n            return tilesBounds;\n        }\n\n\n//FORCE\n\n    //empty grid\n        layer.grid = [];\n       //grid\n        clearTestBounds();\n        layer.singleTile = false;\n        layer.moveTo()        \n        t.ok(g_Bounds.equals(b), \"if grid is empty, initGridded called\");\n        \n       //singletile\n        clearTestBounds();\n        layer.singleTile = true;\n        layer.moveTo()        \n        t.ok(g_Bounds.equals(b), \"if grid is empty, initSingleTile called\");\n\n    //zoomChanged\n        zoomChanged = true;\n        layer.grid = [ [ {} ] ];\n\n       //grid\n        clearTestBounds();\n        layer.singleTile = false;\n        layer.moveTo(null, zoomChanged);        \n        t.ok(g_Bounds.equals(b), \"if layer has grid but zoomChanged is called, initGridded called\");\n        \n       //singletile\n        clearTestBounds();\n        layer.singleTile = true;\n        layer.moveTo(null, zoomChanged);\n        t.ok(g_Bounds.equals(b), \"if layer has grid but zoomChanged is called, initSingleTile called\");        \n        \n\n//NO FORCE\n        zoomChanged = false;\n        layer.grid = [ [ {} ] ];\n \n   //single tile\n        layer.singleTile = true; \n        \n      //DRAGGING   \n        var dragging = true;\n            \n        //in bounds\n        clearTestBounds();\n        tilesBounds = new OpenLayers.Bounds(-10,-10,110,110);\n        layer.moveTo(null, zoomChanged, dragging);\n        t.ok(g_Bounds == null, \"if dragging and tile in bounds, no init()\");\n        \n        //out bounds\n        clearTestBounds();\n        tilesBounds = new OpenLayers.Bounds(10,10,120,120);\n        layer.moveTo(null, zoomChanged, dragging);\n        t.ok(g_Bounds == null, \"if dragging and tile out of bounds, no init()\");\n\n      //NOT DRAGGING\n        dragging = false;\n\n        //in bounds\n        clearTestBounds();\n        tilesBounds = new OpenLayers.Bounds(-10,-10,110,110);\n        layer.moveTo(null, zoomChanged, dragging);\n        t.ok(g_Bounds == null, \"if dragging and tile in bounds, no init()\");\n        \n        //out bounds\n        clearTestBounds();\n        tilesBounds = new OpenLayers.Bounds(10,10,120,120);\n        layer.moveTo(null, zoomChanged, dragging);\n        t.ok(g_WhichFunc == \"InitSingle\", \"if not dragging and tile out of bounds, we call initSingleTile()\");\n        t.ok(g_Bounds.equals(b), \"if not dragging and tile out of bounds, we call initSingleTile() with correct bounds\");\n\n  \n   //gridded\n        layer.grid = [ [ {position: new OpenLayers.Pixel(0,0)} ] ];\n        layer.singleTile = false;\n        \n        //regular move \n        clearTestBounds();\n        tilesBounds = new OpenLayers.Bounds(10,10,120,120);\n        g_WhichFunc = null;\n        layer.moveTo(null, zoomChanged);\n        t.eq(g_WhichFunc, \"MoveGridded\", \"if tiles not drastically out of bounds, we call moveGriddedTile()\");\n        t.ok(g_Bounds.equals(b), \"if tiles not drastically out of bounds, we call moveGriddedTile() with correct bounds\");\n\n        // drastic pan\n        clearTestBounds();\n        tilesBounds = new OpenLayers.Bounds(-150,-150,-120,-120);\n        layer.moveTo(null, zoomChanged);\n        t.ok(g_WhichFunc == \"InitGridded\", \"if tiles drastically out of bounds, we call initGriddedTile()\");\n        t.ok(g_Bounds.equals(b), \"if tiles drastically out of bounds, we call initGriddedTile() with correct bounds\");\n    }\n\n    /** THIS WOULD BE WHERE THE TESTS WOULD GO FOR \n     *     \n     *    -insertColumn\n     *    -insertRow\n     * \n\n    function 08_Layer_Grid_insertColumn(t) {\n    }\n\n    function 09_Layer_Grid_insertRow(t) {\n    }\n\n     * \n     */\n\n    function test_Layer_Grid_clone(t) {\n        t.plan(7);\n        \n        var options = {tileSize: new OpenLayers.Size(500,50)};\n        var map = new OpenLayers.Map('map', options);\n        layer = new OpenLayers.Layer.Grid(name, url, params);\n        map.addLayer(layer);\n\n        layer.grid = [ [6, 7], \n                       [8, 9]];\n\n        // if we clone when tiles are still loading, this should not influence the clone\n        layer.numLoadingTiles = 1;\n        var clone = layer.clone();\n        t.eq( clone.numLoadingTiles, 0, \"numLoadingTiles should be reset\");\n        t.ok( clone.grid != layer.grid, \"clone does not copy grid\");\n        t.ok( clone.grid.length == 0, \"clone creates a new array instead\");\n        \n        t.eq(clone.backBuffer, null, \"no backbuffer from original\");\n\n        t.ok( clone.tileSize.equals(layer.tileSize), \"tileSize correctly cloned\");\n\n        layer.tileSize.w += 40;\n\n        t.eq( clone.tileSize.w, 500, \"changing layer.tileSize does not change clone.tileSize -- a fresh copy was made, not just copied reference\");\n\n        t.eq( clone.alpha, layer.alpha, \"alpha copied correctly\");\n\n        layer.grid = null;\n    }\n\n    function test_Layer_Grid_setTileSize(t) {\n        t.plan(1);\n\n        OpenLayers.Layer.HTTPRequest.prototype._setTileSize = \n            OpenLayers.Layer.HTTPRequest.prototype.setTileSize;\n\n        OpenLayers.Layer.HTTPRequest.prototype.setTileSize = function(size) {\n            g_Size = size;\n        };\n\n\n        layer = new OpenLayers.Layer.Grid(name, url, params, {\n            singleTile: true\n        });\n        mapSize = new OpenLayers.Size(100,1000);\n        layer.map = {\n            getSize: function() { return mapSize; }\n        }\n        \n        g_Size = null;\n        layer.setTileSize();\n        \n        var idealSize = new OpenLayers.Size(150,1500);\n        t.ok( g_Size && g_Size.equals(idealSize), \"correctly calculated tile size passed to superclass setTileSize() function\");\n \n        OpenLayers.Layer.HTTPRequest.prototype.setTileSize = \n            OpenLayers.Layer.HTTPRequest.prototype._setTileSize;\n    }\n    \n    function test_Layer_Grid_initSingleTile(t) {\n      t.plan( 11 );\n      \n        layer = new OpenLayers.Layer.Grid(name, url, params, {\n            singleTile: true,\n            ratio: 2\n        });\n        \n        var bounds = new OpenLayers.Bounds(-10,10,50,100);\n        \n        var desiredTileBounds = new OpenLayers.Bounds(-40,-35,80,145);\n        var desiredUL = new OpenLayers.LonLat(-40,145);\n        \n        translatedPX = {};\n        layer.map = {\n            getLayerPxFromLonLat: function(ul) {\n                t.ok(ul.lon === desiredUL.lon && ul.lat === desiredUL.lat, \"correct ul passed to translation\");\n                return translatedPX;        \n            },\n            getResolution: function() {\n            }\n        }\n\n        var newTile = {\n            draw: function() {\n                t.ok(true, \"newly created tile has been drawn\");\n            }\n        };\n        layer.addTile = function(tileBounds, px) {\n            t.ok(tileBounds.equals(desiredTileBounds), \"correct tile bounds passed to addTile to create new tile\");\n            t.ok(px == translatedPX, \"correct tile px passed to addTile to create new tile\");\n            return newTile;\n        };\n        layer.addTileMonitoringHooks = function(tile) {\n            t.ok(tile == newTile, \"adding monitoring hooks to the newly added tile\");\n        };\n        layer.removeExcessTiles = function(x,y) {\n            t.ok(x == 1 && y == 1, \"removeExcessTiles called\")  \n        };\n\n\n        layer.grid = [];\n        layer.initSingleTile(bounds);       \n      \n        t.ok(layer.grid[0][0] == newTile, \"grid's 0,0 is set to the newly created tile\");        \n        \n        var tile = { \n            moveTo: function(tileBounds, px) {\n                t.ok(tileBounds.equals(desiredTileBounds), \"correct tile bounds passed to tile.moveTo()\");\n                t.ok(px == translatedPX, \"correct tile px passed to tile.moveTo()\");\n            }\n        }; \n        layer.grid = [[ tile ]];\n        layer.initSingleTile(bounds);       \n      \n    }  \n     \n    function test_Layer_Grid_addTileMonitoringHooks(t) {\n        t.plan(18);\n        \n        layer = new OpenLayers.Layer.Grid();\n        layer.events = {\n            'triggerEvent': function(str, evt) {\n                g_events.push([str, evt]);\n            }\n        }\n                \n        var tile = {\n            events: {\n                register: function(name, obj, func) {\n                    g_registered[name] = [obj, func];\n                },\n                on: function(obj) {\n                    for (var o in obj) {\n                        if (obj.hasOwnProperty(o)) {\n                            tile.events.register(o, obj.scope, obj[o]);\n                        }\n                    }\n                }\n            },\n            imgDiv: {className: ''}\n        }\n\n        g_registered = {};\n        g_events = [];\n        \n        layer.addTileMonitoringHooks(tile);\n        \n    //loadstart\n        t.ok(tile.onLoadStart != null, \"onLoadStart function created and added to tile\");\n        entry =  g_registered[\"loadstart\"];\n        t.ok( entry && entry[0] == layer && entry[1] == tile.onLoadStart, \"loadstart correctly registered\");\n\n        layer.numLoadingTiles = 0; \n        g_events = [];\n        tile.onLoadStart.apply(layer);\n\n        t.eq(g_events[0][0], \"loadstart\", \"loadstart event triggered when numLoadingTiles is 0\");\n        t.eq(layer.numLoadingTiles, 1, \"numLoadingTiles incremented\");\n        t.eq(g_events[1][0], \"tileloadstart\", \"tileloadstart event triggered\");\n\n        g_events = [];\n        tile.onLoadStart.apply(layer);\n        t.eq(g_events.length, 1, \"tileloadstart, but not loadstart triggered when numLoadingTiles is not 0\");\n        t.eq(layer.numLoadingTiles, 2, \"numLoadingTiles incremented\");\n\n\n    //loadend\n        t.ok(tile.onLoadEnd != null, \"onLoadEnd function created and added to tile\");\n        entry = g_registered[\"loadend\"];\n        t.ok( entry && entry[0] == layer && entry[1] == tile.onLoadEnd, \"loadend correctly registered\");\n        \n        g_events = [];\n        tile.onLoadError.apply(layer);\n        t.eq(g_events[0][0], \"tileerror\", \"tileerror triggered\");\n        t.ok(g_events[0][1].tile === tile, \"tile passed as tile property to event object\");\n        \n        layer.numLoadingTiles = 2; \n        g_events = [];\n        tile.onLoadEnd.apply(layer, [{}]);\n        t.eq(g_events[0][0], \"tileloaded\", \"tileloaded triggered when numLoadingTiles is > 0\");\n        t.ok(g_events[0][1].tile === tile, \"tile passed as tile property to event object\");\n        t.eq(g_events.length, 1, \"loadend event not triggered when numLoadingTiles is > 0\");\n        t.eq(layer.numLoadingTiles, 1, \"numLoadingTiles decremented\");\n\n\n        g_events = [];\n        layer.grid = [[{}]]; // to prevent error in updateBackBuffer\n        tile.onLoadEnd.apply(layer, [{}]);\n        t.eq(g_events[0][0], \"tileloaded\", \"tileloaded triggered when numLoadingTiles is 0\");\n        t.eq(g_events[1][0], \"loadend\", \"loadend event triggered when numLoadingTiles is 0\");\n        t.eq(layer.numLoadingTiles, 0, \"numLoadingTiles decremented\");\n    }\n    \n    function test_Layer_Grid_removeTileMonitoringHooks(t) {\n        t.plan(2);\n        \n        layer = new OpenLayers.Layer.Grid();\n                \n        var tile = {\n            onLoadStart: {},\n            onLoadEnd: {},\n            unload: function() {},\n            events: {\n                unregister: function(name, obj, func) {\n                    g_unregistered[name] = [obj, func];\n                },\n                un: OpenLayers.Events.prototype.un\n            }\n        }\n\n        g_unregistered = {};\n        \n        layer.removeTileMonitoringHooks(tile);\n        \n        entry =  g_unregistered[\"loadstart\"];\n        t.ok( entry && entry[0] == layer && entry[1] == tile.onLoadStart, \"loadstart correctly unregistered\");\n\n        entry =  g_unregistered[\"loadend\"];\n        t.ok( entry && entry[0] == layer && entry[1] == tile.onLoadEnd, \"loadend correctly unregistered\");\n    }\n    \n    function test_Layer_Grid_tileSizeIsInteger(t) {\n            t.plan(1);\n            \n        var map = new OpenLayers.Map('map');\n            var layer = new OpenLayers.Layer.Grid(name, url, params, {\n            singleTile: true,\n            ratio: 1.5\n        });\n        map.addLayers([layer]);\n        \n        width = layer.tileSize.w;\n        height = layer.tileSize.h;\n        t.ok(width == parseInt(width) && height == parseInt(height), \"calculated tileSize width/height are integer values\");\n    }\n    function test_Layer_Grid_getTileBounds(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map2\", {zoomMethod: null});\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.WMS(name, url, params);\n        \n        var newParams = { layers: 'sooper', \n                          chickpeas: 'image/png'};\n\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        map.zoomIn();\n        var bounds = layer.getTileBounds(new OpenLayers.Pixel(200,200));\n        t.eq(bounds.toBBOX(), \"-180,-90,0,90\", \"get tile bounds returns correct bounds\"); \n        map.pan(200,0, {animate:false});\n        var bounds = layer.getTileBounds(new OpenLayers.Pixel(200,200));\n        t.eq(bounds.toBBOX(), \"0,-90,180,90\", \"get tile bounds returns correct bounds after pan\"); \n    }\n\n    function test_Layer_Grid_moveTo_buffer_calculation (t) {\n        t.plan(6);\n\n        var map = new OpenLayers.Map( 'map3' ); // odd map size\n        var layer0 = new OpenLayers.Layer.WMS( \"0 buffer: OpenLayers WMS\", \n                    \"http://labs.metacarta.com/wms/vmap0\",\n                    {layers: 'basic'}, {'buffer':0} );\n        map.addLayer(layer0);\n\n        var layer1 = new OpenLayers.Layer.WMS( \"1 buffer: OpenLayers WMS\", \n                \"http://labs.metacarta.com/wms/vmap0\",\n                {layers: 'basic'}, {'buffer':1} );\n        map.addLayer(layer1);\n\n        var layer2 = new OpenLayers.Layer.WMS( \"2 buffer: OpenLayers WMS\", \n                \"http://labs.metacarta.com/wms/vmap0\",\n                {layers: 'basic'}, {'buffer':2} );\n        map.addLayer(layer2);\n\n        map.setCenter(new OpenLayers.LonLat(0, 0), 4); \n        t.eq( layer0.grid.length, 3, \"Grid rows with buffer:0\" );\n        map.setBaseLayer(layer1);\n        t.eq( layer1.grid.length, 5, \"Grid rows with buffer:1\" );\n        map.setBaseLayer(layer2);\n        t.eq( layer2.grid.length, 7, \"Grid rows with buffer:2\" );\n\n        // zooming in on Greenland exercises the bug from pre-r4313\n        map.setCenter(new OpenLayers.LonLat(0, 90), 4); \n        t.eq( layer0.grid.length, 3, \"Grid rows with buffer:0\" );\n        map.setBaseLayer(layer1);\n        t.eq( layer1.grid.length, 5, \"Grid rows with buffer:1\" );\n        map.setBaseLayer(layer2);\n        t.eq( layer2.grid.length, 7, \"Grid rows with buffer:2\" );\n    }\n\n    function test_Layer_Grid_destroy (t) {\n\n        t.plan( 9 );\n\n        var map = new OpenLayers.Map('map', {tileManager: null});\n        layer = new OpenLayers.Layer.Grid(name, url, params);\n        map.addLayer(layer);\n        layer.destroy();\n        t.eq( layer.grid, null, \"layer.grid is null after destroy\" );\n        t.eq( layer.tileSize, null, \"layer.tileSize is null after destroy\" );\n\n\n    //test with tile creation\n        layer = new OpenLayers.Layer.WMS(name, url, params);\n        map.addLayer(layer);\n\n        map.setCenter(new OpenLayers.LonLat(0,0), 10);\n        map.setCenter(new OpenLayers.LonLat(1,1));\n\n        //grab a reference to one of the tiles\n        var tile = layer.grid[1][1];        \n        t.eq( tile.imgDiv.className, \"olTileImage\", \"Tile has an image\" ); \n\n        var removeBackBufferCalled = false;\n        layer.removeBackBuffer = function() {\n            removeBackBufferCalled = true;\n        };\n\n        layer.destroy();\n        t.eq( tile.imgDiv, null, \"Tile destroyed\" ); \n        t.eq( layer.timerId, null, \"Tile loading timeout cleared\");\n        t.ok( layer.grid == null, \"tiles appropriately destroyed\")\n        t.ok( removeBackBufferCalled, \"destroy calls removeBackBuffer\");\n\n        // destroy after remove from map\n        layer = new OpenLayers.Layer.WMS(name, url, params);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 10);\n        map.removeLayer(layer);\n        layer.destroy();\n        t.eq( layer.grid, null, \"layer.grid is null after destroy\" );\n        t.eq( layer.tileSize, null, \"layer.tileSize is null after destroy\" );\n    }\n\n    function test_setOpacity(t) {\n        t.plan(5);\n\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS('', '', {}, {\n            isBaseLayer: true,\n            opacity: '0.6'\n        });\n        map.addLayer(layer);\n        // setCenter adds tiles to the layer's grid\n        map.setCenter(new OpenLayers.LonLat(0, 0), 5);\n\n        var tile = layer.grid[0][0], tileImg = tile.imgDiv;\n\n        tile.onImageLoad(); // simulate an image load event\n        t.eq(layer.opacity, '0.6', 'layer opacity value is correct');\n        t.eq(parseFloat(tileImg.style.opacity), 0.6, 'tile opacity is correct');\n\n        layer.setOpacity('0.2');\n        t.eq(layer.opacity, '0.2', 'layer opacity value is correct');\n        t.eq(parseFloat(tileImg.style.opacity), 0.2, 'tile opacity is correct');\n\n        tile = layer.addTile(new OpenLayers.Bounds(1, 2, 3, 4),\n                             new OpenLayers.Pixel(5, 6));\n        tile.draw(); // add tile to the grid\n        tile.onImageLoad(); // simulate an image load event\n        t.eq(parseFloat(tile.imgDiv.style.opacity), 0.2, \"tile opacity is correc\");\n\n        map.destroy();\n    }\n    \n    function test_getServerResolution(t) {\n\n        t.plan(4);\n\n        var layer = new OpenLayers.Layer.Grid('', '', {}, {});\n        var res;\n\n        res = layer.getServerResolution(1);\n        t.eq(res, 1, '[1] getServerResolution return value is correct');\n\n        layer.serverResolutions = [2, 1];\n        res = layer.getServerResolution(1);\n        t.eq(res, 1, '[2] getServerResolution return value is correct');\n\n        layer.serverResolutions = [2];\n        res = layer.getServerResolution(1);\n        t.eq(res, 2, '[3] getServerResolution return value is correct');\n\n        var exc;\n        layer.serverResolutions = [0.5];\n        res = layer.getServerResolution(1);\n        t.eq(res, 0.5, '[4] getServerResolution return value is correct');\n    }\n\n    function test_getServerZoom(t) {\n\n        t.plan(5);\n\n        var resolution, zoom;\n        var map = new OpenLayers.Map('map', {\n            resolutions: [8, 4, 2, 1, 0.5],\n            getResolution: function() {\n                return resolution;\n            }\n        });\n        var layer = new OpenLayers.Layer.WMS('', '', {}, {isBaseLayer: true});\n        map.addLayer(layer);\n\n        resolution = 8;\n        zoom = layer.getServerZoom();\n        t.eq(zoom, 0, '[1] getServerZoom return value is correct');\n\n        resolution = 4;\n        zoom = layer.getServerZoom();\n        t.eq(zoom, 1, '[2] getServerZoom return value is correct');\n\n        layer.serverResolutions = [2, 1];\n        resolution = 1;\n        zoom = layer.getServerZoom();\n        t.eq(zoom, 1, '[3] getServerZoom return value is correct');\n\n        layer.serverResolutions = [2];\n        resolution = 0.5;\n        zoom = layer.getServerZoom();\n        t.eq(zoom, 0, '[4] getServerZoom return value is correct');\n\n        var exc;\n        layer.serverResolutions = [0.5];\n        resolution = 1;\n        zoom = layer.getServerZoom();\n        t.eq(zoom, 0, '[4] getServerZoom return value is correct');\n\n        map.destroy();\n    }\n\n    function test_moveTo_scale(t) {\n\n        t.plan(11);\n\n        var map = new OpenLayers.Map('map', {\n            resolutions: [32, 16, 8, 4, 2, 1],\n            zoomMethod: null\n        });\n        var layer = new OpenLayers.Layer.WMS('', '', {}, {\n            isBaseLayer: true,\n            serverResolutions: [32, 16, 8]\n        });\n        map.addLayer(layer);\n\n        // initial resolution is 8\n        map.setCenter(new OpenLayers.LonLat(0, 0), 2);\n\n        // test initial conditions\n        t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 1, 'layer div scale is 1');\n\n        // change from resolution 8 to 4\n        map.zoomTo(3);\n        t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 2, '[8->4] layer div scale is 2');\n\n        // change from resolution 8 to 2\n        map.zoomTo(2); map.zoomTo(4);\n        t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 4, '[8->2] layer div scale is 4');\n\n        // change from resolution 8 to 1\n        map.zoomTo(2); map.zoomTo(5);\n        t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 8, '[8->1] layer div scale is 8');\n\n        // change from resolution 4 to 2\n        map.zoomTo(3); map.zoomTo(4);\n        t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 4, '[4->2] layer div scale is 4');\n\n        // change from resolution 4 to 1\n        map.zoomTo(3); map.zoomTo(5);\n        t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 8, '[4->1] layer div scale is 8');\n\n        // change from resolution 2 to 1\n        map.zoomTo(4); map.zoomTo(5);\n        t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 8, '[2->1] layer div scale is 8');\n\n        // change from resolution 1 to 2\n        map.zoomTo(5); map.zoomTo(4);\n        t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 4, '[1->2] layer div scale is 4');\n\n        // change from resolution 1 to 4\n        map.zoomTo(5); map.zoomTo(3);\n        t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 2, '[1->4] layer div scale is 2');\n\n        // change from resolution 1 to 8\n        map.zoomTo(5); map.zoomTo(2);\n        t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 1, '[1->8] layer div scale is 1');\n\n        // change from resolution 1 to 16\n        map.zoomTo(5); map.zoomTo(1);\n        t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 1, '[1->16] layer div scale is 1');\n\n        map.destroy();\n    }\n\n    function test_moveTo_backbuffer_singletile(t) {\n        t.plan(4);\n\n        var map = new OpenLayers.Map('map', {\n            resolutions: [1, 0.5, 0.025],\n            zoomMethod: null\n        });\n        var resolution;\n        var layer = new OpenLayers.Layer.WMS('', '', {}, {\n            singleTile: true,\n            isBaseLayer: true,\n            transitionEffect: 'resize',\n            applyBackBuffer: function(res) {\n                resolution = res;\n            }\n        });\n        map.addLayer(layer);\n\n        // initial resolution is 0.025\n        resolution = undefined;\n        map.setCenter(new OpenLayers.LonLat(0, 0), 2);\n        t.eq(resolution, 0.025,\n             'applyBackBuffer not called on first moveTo');\n\n        // move to (-90, 45)\n        resolution = undefined;\n        map.setCenter(new OpenLayers.LonLat(-90, 45));\n        t.eq(resolution, 0.025,\n             'applyBackBuffer called when map is moved');\n\n        // change to resolution 1\n        resolution = undefined;\n        map.zoomTo(0);\n        t.eq(resolution, 1,\n             'applyBackBuffer called when map is zoomed out');\n\n        // change to resolution 0.5\n        resolution = undefined;\n        map.zoomTo(1);\n        t.eq(resolution, 0.5,\n             'applyBackBuffer called when map is zoomed out');\n\n        map.destroy();\n    }\n\n    function test_moveTo_backbuffer(t) {\n        t.plan(4);\n\n        var map = new OpenLayers.Map('map', {\n            resolutions: [1, 0.5, 0.025],\n            zoomMethod: null\n        });\n        var resolution;\n        var layer = new OpenLayers.Layer.WMS('', '', {}, {\n            isBaseLayer: true,\n            transitionEffect: 'resize',\n            applyBackBuffer: function(res) {\n                resolution = res;\n            }\n        });\n        map.addLayer(layer);\n\n        // initial resolution is 0.025\n        resolution = undefined;\n        map.setCenter(new OpenLayers.LonLat(0, 0), 2);\n        t.eq(resolution, 0.025,\n             'applyBackBuffer not called on first moveTo');\n\n        // move to (-90, 45)\n        resolution = undefined;\n        map.setCenter(new OpenLayers.LonLat(-90, 45));\n        t.eq(resolution, undefined,\n             'applyBackBuffer not called when map is moved');\n\n        // change to resolution 1\n        resolution = undefined;\n        map.zoomTo(0);\n        t.eq(resolution, 1,\n             'applyBackBuffer called when map is zoomed out');\n\n        // change to resolution 0.5\n        map.zoomTo(1);\n        t.eq(resolution, 0.5,\n             'applyBackBuffer called when map is zoomed out');\n\n        map.destroy();\n    }\n\n    function test_applyBackBuffer(t) {\n        t.plan(12);\n\n        var map = new OpenLayers.Map('map2');\n        var layer = new OpenLayers.Layer.WMS('', '', {}, {\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n\n        var backBuffer;\n\n        // test #1\n        layer.createBackBuffer = function() {\n            return;\n        };\n        layer.applyBackBuffer(2);\n        t.eq(layer.backBuffer, undefined,\n             'back buffer not created if createBackBuffer returns undefined');\n\n        // test #2\n        layer.createBackBuffer = function() {\n            backBuffer = document.createElement('div');\n            return backBuffer;\n        };\n        layer.gridResolution = 32;\n        layer.backBufferResolution = 2;\n        layer.grid[0][0].bounds = new OpenLayers.Bounds(0, 1, 1, 0);\n        layer.applyBackBuffer(2);\n        t.ok(layer.backBuffer === backBuffer,\n             'back buffer set in layer');\n        t.ok(map.layerContainerDiv.firstChild === backBuffer,\n             'back buffer inserted as first child');\n        t.eq(layer.backBuffer.style.left, '250px',\n             'back buffer has correct left');\n        t.eq(layer.backBuffer.style.top, '275px',\n             'back buffer has correct top');\n\n        // test #3\n        layer.createBackBuffer = function() {\n            backBuffer = document.createElement('div');\n            return backBuffer;\n        };\n        layer.gridResolution = 32;\n        layer.backBufferResolution = 2;\n        layer.grid[0][0].bounds = new OpenLayers.Bounds(0, 1, 1, 0);\n        map.layerContainerOriginPx.x = 20;\n        map.layerContainerOriginPx.y = -20;\n        layer.applyBackBuffer(2);\n        t.ok(layer.backBuffer === backBuffer,\n             'back buffer set in layer');\n        t.ok(map.layerContainerDiv.firstChild === backBuffer,\n             'back buffer inserted as first child');\n        t.eq(layer.backBuffer.style.left, '230px',\n             'back buffer has correct left');\n        t.eq(layer.backBuffer.style.top, '295px',\n             'back buffer has correct top');\n\n         // test #4\n         // and a back buffer in the layer and do as if back buffer removal\n         // has been scheduled, and test that applyBackBuffer removes the\n         // back buffer and clears the timer\n         layer.createBackBuffer = function() {\n             return;\n         };\n         backBuffer = document.createElement('div');\n         map.layerContainerDiv.insertBefore(backBuffer, map.baseLayer.div);\n         layer.backBuffer = backBuffer;\n         layer.backBufferTimerId = 'fake';\n         layer.applyBackBuffer(2);\n         t.ok(backBuffer !== map.layerContainerDiv.firstChild,\n              'back buffer is not first child of layer container div');\n         t.eq(layer.backBuffer, null,\n              'back buffer not set in layer');\n         t.eq(layer.backBufferTimerId, null,\n              'back buffer timer cleared');\n         map.destroy();\n    }\n\n    function test_createBackBuffer(t) {\n        t.plan(9);\n\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS('', '', {}, {\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n\n        var createBackBuffer = OpenLayers.Tile.Image.prototype.createBackBuffer;\n\n        var backBuffer;\n\n        OpenLayers.Tile.Image.prototype.createBackBuffer = function() {\n            return;\n        };\n        backBuffer = layer.createBackBuffer();\n        t.ok(backBuffer != undefined,\n             'createBackBuffer returns a back buffer');\n        t.eq(backBuffer.childNodes.length, 0,\n             'returned back buffer has no child nodes');\n\n        OpenLayers.Tile.Image.prototype.createBackBuffer = function() {\n            return document.createElement('div');\n        };\n        \n        layer.transitionEffect = 'map-resize';\n        backBuffer = layer.createBackBuffer();\n        t.ok(backBuffer.style.zIndex == 99, 'z-index of backbuffer correct for \"map-resize\".');\n        layer.removeBackBuffer();\n        \n        layer.transitionEffect = 'resize';\n        backBuffer = layer.createBackBuffer();\n        t.ok(backBuffer.style.zIndex == layer.getZIndex() - 1, 'z-index of backbuffer correct for \"resize\",');\n\n        layer.backBufferResolution = 1;\n        layer.gridResolution = 1;\n        layer.backBuffer = backBuffer;\n        layer.div.appendChild(backBuffer);\n        layer.backBufferLonLat = {lon: 0, lat: 0};\n        layer.applyBackBuffer(1);\n        t.ok(backBuffer != undefined,\n             'createBackBuffer returns a back buffer');\n        t.eq(backBuffer.childNodes[0].style.left, '0px',\n             'first tile has correct left');\n        t.eq(backBuffer.childNodes[0].style.top, '0px',\n             'first tile has correct top');\n        t.eq(backBuffer.childNodes[1].style.left, '256px',\n             'second tile has correct left');\n        t.eq(backBuffer.childNodes[1].style.top, '0px',\n             'second tile has correct top');\n\n        map.destroy();\n        OpenLayers.Tile.Image.prototype.createBackBuffer = createBackBuffer;\n    }\n\n    function test_removeBackBuffer(t) {\n        t.plan(3);\n\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS('', '', {}, {isBaseLayer: true});\n        map.addLayer(layer);\n\n        // add a fake back buffer\n        var backBuffer = document.createElement('div');\n        layer.backBuffer = backBuffer;\n        layer.div.appendChild(backBuffer);\n        layer.backBufferResolution = 32;\n\n        layer.removeBackBuffer();\n        t.eq(layer.backBuffer, null, 'backBuffer set to null in layer');\n        t.eq(layer.backBufferResolution, null,\n             'backBufferResolution set to null in layer');\n        t.ok(backBuffer.parentNode !== layer.div,\n             'back buffer removed from layer');\n\n        map.destroy();\n    }\n    \n    function test_backbuffer_replace(t) {\n        t.plan(6);\n        var map = new OpenLayers.Map('map', {tileManager: null});\n        var layer = new OpenLayers.Layer.WMS('', '../../img/blank.gif');\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        \n        layer.grid[1][1].onImageLoad();\n        layer.mergeNewParams({foo: 'bar'});\n        var tile = layer.grid[1][1];\n        t.ok(OpenLayers.Element.hasClass(tile.imgDiv, 'olTileReplacing'), 'tile is marked for being replaced');\n        t.ok(document.getElementById(tile.id + '_bb'), 'backbuffer created for tile');\n        // simulate a css declaration where '.olTileReplacing' sets display\n        // to none.\n        tile.imgDiv.style.display = 'none';\n        tile.onImageLoad();\n        t.ok(!OpenLayers.Element.hasClass(tile.imgDiv, 'olTileReplacing'), 'tile replaced, no longer marked');\n        t.ok(!document.getElementById(tile.id + '_bb'), 'backbuffer removed for tile');\n        \n        layer.mergeNewParams({foo: 'baz'});\n        tile = layer.grid[1][1];\n        // simulate a css declaration where '.olTileReplacing' does not set\n        // display to none.\n        tile.imgDiv.style.display = 'block';\n        tile.onImageLoad();\n        t.ok(!OpenLayers.Element.hasClass(tile.imgDiv, 'olTileReplacing'), 'tile replaced, no longer marked');\n        t.ok(document.getElementById(tile.id + '_bb'), 'backbuffer not removed for visible tile');\n    }\n\n    function test_backbuffer_replace_singleTile(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS('', '../../img/blank.gif', null, {\n            singleTile: true,\n            transitionEffect: 'resize'\n        });\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        \n        t.delay_call(1, function() {\n            map.zoomIn();\n            var tile = layer.grid[0][0];\n            t.ok(!OpenLayers.Element.hasClass(tile.imgDiv, 'olTileReplacing'), 'tile is not marked for being replaced for singleTile layers');\n        });\n    }\n\n    function test_singleTile_move_and_zoom(t) {\n\n        //\n        // In single tile mode with no transition effect, we insert a non-scaled\n        // backbuffer when the layer is moved. But if a zoom occurs right after\n        // a move, i.e. before the new image is received, we need to remove the\n        // backbuffer, or an ill-positioned image will be visible during the\n        // zoom transition.\n        //\n\n        t.plan(5);\n\n        var map = new OpenLayers.Map('map', {zoomMethod: null});\n        var layer = new OpenLayers.Layer.WMS('', '', {}, {\n            isBaseLayer: true,\n            transitionEffect: null,\n            singleTile: true,\n            displayOutsideMaxExtent: true,\n            ratio: 1.1\n        });\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        // move\n        map.setCenter(new OpenLayers.LonLat(50, 50));\n        t.ok(layer.backBuffer && layer.backBuffer.parentNode === layer.div,\n                'backbuffer inserted after map move');\n        t.eq(layer.backBuffer.style.left, '-25px');\n        t.eq(layer.backBuffer.style.top, '-28px');\n        // zoom\n        map.zoomTo(1);\n        t.eq(layer.backBuffer, null,\n             'back buffer removed when zooming');\n\n        // now the single tile image will be clipped to maxExtent\n        layer.displayOutsideMaxExtent = false;\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n        // move again\n        map.setCenter(new OpenLayers.LonLat(50, 50));\n        t.eq(layer.backBuffer.style.left, '122px', 'proper offset for single tile smaller than the map viewport');\n\n        map.destroy();\n    }\n\n    function test_backbuffer_scaled_layer(t) {\n        t.plan(12);\n\n        //\n        // set up\n        //\n\n        var map = new OpenLayers.Map('map', {\n            resolutions: [32, 16, 8, 4, 2, 1],\n            zoomMethod: null,\n            tileManager: null\n        });\n        var layer = new OpenLayers.Layer.WMS(\n            \"WMS\",\n            window.location.href + \"#\",\n            null,\n            {transitionEffect: \"resize\"}\n        );\n        \n        layer.serverResolutions = [32, 16, 8];\n\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 2);\n\n        var origCreateBackBuffer = OpenLayers.Tile.Image.prototype.createBackBuffer;\n        OpenLayers.Tile.Image.prototype.createBackBuffer = function() {\n            return document.createElement('div');\n        };\n\n        // we want to control when the back buffer is removed\n        var removeBackBuffer = OpenLayers.Function.bind(\n                layer.removeBackBuffer, layer);\n        layer.removeBackBuffer = function() {};\n\n        //\n        // test\n        //\n\n        // change resolution from 8 to 4\n        map.zoomTo(3);\n        t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1,\n            '[8->4] back buffer not scaled');\n        removeBackBuffer();\n\n        // change resolution from 8 to 2\n        map.zoomTo(2); removeBackBuffer(); map.zoomTo(4);\n        t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1,\n            '[8->2] back buffer not scaled');\n        removeBackBuffer();\n\n        // change resolution from 16 to 4\n        map.zoomTo(1); removeBackBuffer(); map.zoomTo(3);\n        t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 2,\n             '[16->4] back buffer width is as expected');\n        t.eq(parseInt(layer.backBuffer.firstChild.style.height) / parseInt(layer.div.lastChild.style.height), 2,\n             '[16->4] back buffer height is as expected');\n        removeBackBuffer();\n\n        // change resolution from 32 to 1\n        map.zoomTo(0); removeBackBuffer(); map.zoomTo(5);\n        t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 4,\n             '[32->1] back buffer width is as expected');\n        t.eq(parseInt(layer.backBuffer.firstChild.style.height) / parseInt(layer.div.lastChild.style.height), 4,\n             '[32->1] back buffer height is as expected');\n        removeBackBuffer();\n\n        // change resolution from 4 to 2\n        map.zoomTo(3); removeBackBuffer(); map.zoomTo(4);\n        t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1,\n            '[4->2] back buffer not scaled');\n        removeBackBuffer();\n\n        // change resolution from 4 to 1\n        map.zoomTo(3); removeBackBuffer(); map.zoomTo(5);\n        t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1,\n            '[4->1] back buffer not scaled');\n        removeBackBuffer();\n\n        // change resolution from 1 to 4\n        map.zoomTo(5); removeBackBuffer(); map.zoomTo(3);\n        t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1,\n            '[1->4] back buffer not scaled');\n        removeBackBuffer();\n\n        // change resolution from 4 to 8\n        map.zoomTo(3); removeBackBuffer(); map.zoomTo(2);\n        t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1,\n            '[4->8] back buffer not scaled');\n        removeBackBuffer();\n\n        // change resolution from 4 to 16\n        map.zoomTo(3); removeBackBuffer(); map.zoomTo(1);\n        t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 0.5,\n             '[4->16] back buffer width is as expected');\n        t.eq(parseInt(layer.backBuffer.firstChild.style.height) / parseInt(layer.div.lastChild.style.height), 0.5,\n             '[4->16] back buffer height is as expected');\n        removeBackBuffer();\n\n        //\n        // tear down\n        //\n\n        map.destroy();\n        OpenLayers.Tile.Image.prototype.createBackBuffer = origCreateBackBuffer\n    }\n\n\n    function test_delayed_back_buffer_removal(t) {\n        //\n        // Test that the delaying of the back buffer removal behaves\n        // as expected.\n        //\n\n        t.plan(5);\n\n        // set up\n        \n        var map = new OpenLayers.Map('map', {\n            resolutions: [32, 16, 8, 4, 2, 1],\n            zoomMethod: null\n        });\n        var layer = new OpenLayers.Layer.WMS('', '', {}, {\n            isBaseLayer: true,\n            transitionEffect: 'resize'\n        });\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        map.zoomTo(1);\n\n        t.ok(layer.backBuffer === map.layerContainerDiv.firstChild,\n             '[a] back buffer is first child of layer container div');\n\n        // Mark one tile loaded and add an element to the backbuffer, to see if\n        // backbuffer removal gets scheduled.\n        layer.backBuffer.appendChild(document.createElement('img'));\n        layer.grid[1][1].onImageLoad();\n\n        t.ok(layer.backBufferTimerId !== null,\n             '[a] back buffer scheduled for removal');\n\n        var backBuffer = layer.backBuffer;\n\n        map.zoomTo(2);\n\n        t.ok(layer.backBuffer !== backBuffer,\n             '[b] a new back buffer was created');\n        t.ok(layer.backBuffer === map.layerContainerDiv.firstChild,\n             '[b] back buffer is first child of layer container div');\n        t.ok(layer.backBufferTimerId === null,\n             '[b] back buffer no longer scheduled for removal');\n\n        // tear down\n\n        map.destroy();\n    }\n\n    function test_getGridData(t) {\n        t.plan(12);\n        \n        var layer = new OpenLayers.Layer.Grid(null, null, null, {\n            isBaseLayer: true, getURL: function() {\n                return \"/bogus/path/to/tile\";\n            }\n        });\n        var map = new OpenLayers.Map({\n            div: \"map\",\n            layers: [layer],\n            controls: [],\n            center: [0, 0],\n            zoom: 1\n        });\n        \n        // get tile data for [0, 0]\n        var data = layer.getTileData({lon: 0, lat: 0});\n        t.ok(data && data.tile, \"[0, 0]: got tile data\");\n        t.eq(data.i, 0, \"[0, 0]: i\");\n        t.eq(data.j, 128, \"[0, 0]: j\");\n        t.ok(\n            data.tile.bounds.equals({left: 0, bottom: -90, right: 180, top: 90}),\n            \"[0, 0]: tile bounds \" + data.tile.bounds.toString()\n        );\n        \n        // get tile data for [-110, 45]\n        data = layer.getTileData({lon: -110, lat: 45});\n        t.ok(data && data.tile, \"[-110, 45]: got tile data\");\n        t.eq(data.i, 99, \"[-110, 45]: i\");\n        t.eq(data.j, 64, \"[-110, 45]: j\");\n        t.ok(\n            data.tile.bounds.equals({left: -180, bottom: -90, right: 0, top: 90}),\n            \"[-110, 45]: tile bounds \" + data.tile.bounds.toString()\n        );\n        \n        // get tile data for [0, 300] (north of grid)\n        data = layer.getTileData({lon: 0, lat: 300})\n        t.eq(data, null, \"[0, 300]: north of grid\");\n\n        // get tile data for [400, 0] (east of grid)\n        data = layer.getTileData({lon: 400, lat: 0})\n        t.eq(data, null, \"[400, 0]: east of grid\");\n\n        // get tile data for [0, -500] (south of grid)\n        data = layer.getTileData({lon: 0, lat: -500})\n        t.eq(data, null, \"[0, -500]: south of grid\");\n\n        // get tile data for [-200, 0] (west of grid)\n        data = layer.getTileData({lon: -200, lat: 0})\n        t.eq(data, null, \"[-200, 0]: west of grid\");\n        \n        map.destroy();\n        \n    }\n\n    function test_getGridData_wrapped(t) {\n        t.plan(18);\n        \n        var layer = new OpenLayers.Layer.Grid(null, null, null, {\n            isBaseLayer: true, getURL: function() {\n                return \"/bogus/path/to/tile\";\n            },\n            wrapDateLine: true\n        });\n        var map = new OpenLayers.Map({\n            div: \"map\",\n            layers: [layer],\n            controls: [],\n            center: [-50, 0],\n            zoom: 1\n        });\n        \n        // get tile data for [0, 0]\n        var data = layer.getTileData({lon: 0, lat: 0});\n        t.ok(data && data.tile, \"[0, 0]: got tile data\");\n        t.eq(data.i, 0, \"[0, 0]: i\");\n        t.eq(data.j, 128, \"[0, 0]: j\");\n        t.ok(\n            data.tile.bounds.equals({left: 0, bottom: -90, right: 180, top: 90}),\n            \"[0, 0]: tile bounds \" + data.tile.bounds.toString()\n        );\n        \n        // get tile data for [-110, 45]\n        data = layer.getTileData({lon: -110, lat: 45});\n        t.ok(data && data.tile, \"[-110, 45]: got tile data\");\n        t.eq(data.i, 99, \"[-110, 45]: i\");\n        t.eq(data.j, 64, \"[-110, 45]: j\");\n        t.ok(\n            data.tile.bounds.equals({left: -180, bottom: -90, right: 0, top: 90}),\n            \"[-110, 45]: tile bounds \" + data.tile.bounds.toString()\n        );\n        \n        // get tile data for [0, 300] (north of grid)\n        data = layer.getTileData({lon: 0, lat: 300})\n        t.eq(data, null, \"[0, 300]: north of grid\");\n\n        // get tile data for [400, 0] (equivalent to [40, 0] and visible on map)\n        data = layer.getTileData({lon: 400, lat: 0})\n        t.ok(data && data.tile, \"[400, 0]: got tile data\");\n        t.eq(data.i, 56, \"[400, 0]: i\");\n        t.eq(data.j, 128, \"[400, 0]: j\");\n        t.ok(\n            data.tile.bounds.equals({left: 0, bottom: -90, right: 180, top: 90}),\n            \"[400, 0]: tile bounds \" + data.tile.bounds.toString()\n        );\n\n        // get tile data for [0, -500] (south of grid)\n        data = layer.getTileData({lon: 0, lat: -500})\n        t.eq(data, null, \"[0, -500]: south of grid\");\n\n        // get tile data for [-200, 0] (equivalent to [160, 0] and wrapped to west side map)\n        data = layer.getTileData({lon: -200, lat: 0})\n        t.ok(data && data.tile, \"[-200, 0]: got tile data\");\n        t.eq(data.i, 227, \"[-200, 0]: i\");\n        t.eq(data.j, 128, \"[-200, 0]: j\");\n        t.ok(\n            data.tile.bounds.equals({left: 0, bottom: -90, right: 180, top: 90}),\n            \"[-200, 0]: tile bounds \" + data.tile.bounds.toString()\n        );\n        \n        map.destroy();\n        \n    }\n\n    function test_removeExcessTiles(t) {\n        t.plan(15);\n\n        /*\n         * Set up\n         */\n\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.Grid('name', '/url',\n                                              {}, {isBaseLayer: true});\n        map.addLayer(layer);\n\n        function newTile(id) {\n            var t = new OpenLayers.Tile(layer,\n                        new OpenLayers.Pixel(1, 1),\n                        new OpenLayers.Bounds(1, 1, 1, 1));\n            t._id = id;\n            return t;\n        }\n\n        layer.grid = [\n            [newTile(1), newTile(2), newTile(3)],\n            [newTile(4), newTile(5)],\n            [newTile(6), newTile(7), newTile(8)]\n        ];\n\n        // create a clone to be able to test whether\n        // tiles have been destroyed or not\n        var grid = [\n            layer.grid[0].slice(),\n            layer.grid[1].slice(),\n            layer.grid[2].slice()\n        ];\n\n        /*\n         * Test\n         */\n\n        layer.removeExcessTiles(2, 2);\n\n        t.eq(layer.grid.length, 2, 'grid has two rows');\n        t.eq(layer.grid[0].length, 2, 'row #1 has two columns');\n        t.eq(layer.grid[0][0]._id, 1, 'row #1 col #1 includes expected tile');\n        t.eq(layer.grid[0][1]._id, 2, 'row #1 col #2 includes expected tile');\n        t.eq(layer.grid[1].length, 2, 'row #2 has two columns');\n        t.eq(layer.grid[1][0]._id, 4, 'row #2 col #1 includes expected tile');\n        t.eq(layer.grid[1][1]._id, 5, 'row #2 col #2 includes expected tile');\n\n        t.ok(grid[0][0].events != null, 'tile 0,0 not destroyed');\n        t.ok(grid[0][1].events != null, 'tile 0,1 not destroyed');\n        t.ok(grid[0][2].events == null, 'tile 0,2 destroyed');\n        t.ok(grid[1][0].events != null, 'tile 1,0 not destroyed');\n        t.ok(grid[1][1].events != null, 'tile 1,1 not destroyed');\n        t.ok(grid[2][0].events == null, 'tile 2,0 destroyed');\n        t.ok(grid[2][1].events == null, 'tile 2,1 destroyed');\n        t.ok(grid[2][2].events == null, 'tile 2,2 destroyed');\n\n        /*\n         * Tear down\n         */\n\n        map.destroy();\n    }\n\n    function test_addOptions(t) {\n        t.plan(15);\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS(name, url, params, {buffer:2});\n        map.addLayer(layer);\n        t.eq(layer.tileSize, map.getTileSize(), \"layer's tile size is equal to the map's tile size\");\n        t.ok(layer.removeBackBufferDelay !== 0, \"removeBackBufferDelay should not be 0 since we are not singleTile\");\n        t.eq(layer.className, \"olLayerGrid\", \"className correct for gridded mode\");\n        map.setCenter(new OpenLayers.LonLat(0,0),5);\n        t.eq(layer.grid.length, 8, \"Grid rows is correct.\");\n        t.eq(layer.grid[0].length, 7, \"Grid cols is correct.\");\n        t.eq(layer.singleTile, false, \"singleTile is false by default\");\n        layer.addOptions({singleTile: true});\n        t.eq(layer.removeBackBufferDelay, 0, \"removeBackBufferDelay set to 0 since singleTile is true\");\n        t.eq(layer.singleTile, true, \"singleTile set to true\");\n        t.eq(layer.className, \"olLayerGridSingleTile\", \"className correct for singleTile mode\");\n        t.eq(layer.grid.length, 1, \"Grid rows is correct.\");\n        t.eq(layer.grid[0].length, 1, \"Grid cols is correct.\");\n        t.eq(layer.tileSize, new OpenLayers.Size(748, 823), \"tile size changed\");\n        layer.addOptions({singleTile: false});\n        t.eq(layer.grid.length, 8, \"Grid rows is correct.\");\n        t.eq(layer.grid[0].length, 7, \"Grid cols is correct.\");\n        t.eq(layer.tileSize, map.getTileSize(), \"layer's tile size is equal to the map's tile size\");\n        map.destroy();\n    }\n    \n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:499px;height:549px;display:none\"></div>\n<div id=\"map2\" style=\"width:500px;height:550px;display:none\"></div>\n<div id=\"map3\" style=\"width:594px;height:464px;display:none\"></div>\n<div id=\"map4\" style=\"width:768px;height:512px;display:none\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/HTTPRequest.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var layer; \n\n    var name = \"Test Layer\";\n    var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n    var params = { map: '/mapdata/vmap_wms.map', \n                   layers: 'basic', \n                   format: 'image/png'};\n    var options = { chicken: 151, foo: \"bar\" };\n\n    function test_Layer_HTTPRequest_constructor (t) {\n        t.plan( 6 );\n\n        layer = new OpenLayers.Layer.HTTPRequest(name, url, params, options);\n        \n        t.ok( layer instanceof OpenLayers.Layer.HTTPRequest, \"new OpenLayers.Layer.HTTPRequest returns correctly typed object\" );\n\n        // correct bubbling up to Layer.initialize()\n        t.eq( layer.name, name, \"layer.name is correct\" );\n        t.ok( ((layer.options[\"chicken\"] == 151) && (layer.options[\"foo\"] == \"bar\")), \"layer.options correctly set\" );\n\n        // HTTPRequest-specific properties\n        t.eq( layer.url, url, \"layer.name is correct\" );\n        t.ok( ((layer.params[\"map\"] == '/mapdata/vmap_wms.map') && \n               (layer.params[\"layers\"] == \"basic\") &&\n               (layer.params[\"format\"] == \"image/png\")), \"layer.params correctly set\" );\n        \n        layer = new OpenLayers.Layer.HTTPRequest(name, url, null, {params: params});\n        t.ok( ((layer.params[\"map\"] == '/mapdata/vmap_wms.map') && \n               (layer.params[\"layers\"] == \"basic\") &&\n               (layer.params[\"format\"] == \"image/png\")), \"layer.params correctly set from options\" );\n    }\n\n    function test_Layer_HTTPRequest_clone (t) {\n        t.plan( 6 );\n        \n        var toClone = new OpenLayers.Layer.HTTPRequest(name, url, params, options);\n        toClone.chocolate = 5;\n\n        var layer = toClone.clone();\n\n        t.eq(layer.chocolate, 5, \"correctly copied randomly assigned property\");\n\n        t.ok( layer instanceof OpenLayers.Layer.HTTPRequest, \"new OpenLayers.Layer.HTTPRequest returns correctly typed object\" );\n\n        // correct bubbling up to Layer.initialize()\n        t.eq( layer.name, name, \"layer.name is correct\" );\n        t.eq( layer.options, options, \"layer.options correctly set\" );\n\n        // HTTPRequest-specific properties\n        t.eq( layer.url, url, \"layer.name is correct\" );\n        t.ok( ((layer.params[\"map\"] == '/mapdata/vmap_wms.map') && \n               (layer.params[\"layers\"] == \"basic\") &&\n               (layer.params[\"format\"] == \"image/png\")), \"layer.params correctly set\" );\n\n    }\n\n    function test_Layer_HTTPRequest_setUrl (t) {\n        t.plan( 1 );\n\n        layer = new OpenLayers.Layer.HTTPRequest(name, url, params, options);\n        \n        layer.setUrl(\"foo\");\n        t.eq( layer.url, \"foo\", \"setUrl() works\");\n    }\n\n    function test_Layer_HTTPRequest_mergeNewParams (t) {\n        t.plan( 8 );\n\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.HTTPRequest(name, url, params, options);\n        map.addLayer(layer);\n\n        var scope = {some: \"scope\"}, log = [];\n        map.events.on({\n            changelayer: function(e) {\n                log.push({layer: e.layer, property: e.property, scope: this});\n            },\n            scope: scope\n        });\n        \n        var newParams = { layers: 'sooper', \n                          chickpeas: 'image/png'};\n\n        layer.mergeNewParams(newParams);\n        \n        t.eq( layer.params.layers, \"sooper\", \"mergeNewParams() overwrites well\");\n        t.eq( layer.params.chickpeas, \"image/png\", \"mergeNewParams() adds well\");\n        t.eq( log.length, 1, \"mergeNewParams() triggers changelayer once\");\n        t.ok( log[0].layer == layer, \"mergeNewParams() passes changelayer listener the expected layer\");\n        t.ok( log[0].property == \"params\", \"mergeNewParams() passes changelayer listener the property \\\"params\\\"\");\n        t.eq( log[0].scope, scope, \"mergeNewParams() executes changelayer listener with expected scope\");\n\n        newParams.chickpeas = 151;\n\n        t.eq( layer.params.chickpeas, \"image/png\", \"mergeNewParams() makes clean copy of hash\");\n        \n        layer.redraw = function() {\n            t.ok(true, \"layer.mergeNewParams calls layer.redraw\");\n        }\n        layer.mergeNewParams();\n    }\n\n    function test_Layer_HTTPRequest_getFullRequestString (t) {\n\n        tParams = { layers: 'basic', \n                   format: 'image/png'};\n        \n        t.plan( 12 );\n\n  // without ?        \n        tUrl = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, tParams, null);\n        str = layer.getFullRequestString();\n        t.eq(str, tUrl + '?' + OpenLayers.Util.getParameterString(tParams), \"getFullRequestString() works for url sans ?\");\n\n\n  // with ?        \n        tUrl = \"http://octo.metacarta.com/cgi-bin/mapserv?\";\n        layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, tParams, null);\n        str = layer.getFullRequestString();\n        t.eq(str, tUrl + OpenLayers.Util.getParameterString(tParams), \"getFullRequestString() works for url with ?\");\n\n  // with ?param1=5\n        tUrl = \"http://octo.metacarta.com/cgi-bin/mapserv?param1=5\";\n        layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, tParams, null);\n        str = layer.getFullRequestString();\n        t.eq(str, tUrl + '&' + OpenLayers.Util.getParameterString(tParams), \"getFullRequestString() works for url with ?param1=5\");\n  \n  // with ?param1=5&\n        tUrl = \"http://octo.metacarta.com/cgi-bin/mapserv?param1=5&format=image/jpeg\";\n        layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, tParams, null);\n        str = layer.getFullRequestString();\n        t.eq(str, tUrl + '&' + OpenLayers.Util.getParameterString({'layers':'basic'}), \"getFullRequestString() doesn't override already-existing params in URL\");\n\n \n  // with ?param1=5&\n        tUrl = \"http://octo.metacarta.com/cgi-bin/mapserv?param1=5&\";\n        layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, tParams, null);\n        str = layer.getFullRequestString();\n        t.eq(str, tUrl + OpenLayers.Util.getParameterString(tParams), \"getFullRequestString() works for url with ?param1=5&\");\n  \n\n\n  // passing in new params\n        layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, tParams, null);\n        str = layer.getFullRequestString( { chicken: 6, \n                                            layers:\"road\" } );\n        t.eq(str, tUrl + OpenLayers.Util.getParameterString({layers: 'road', format: \"image/png\", chicken: 6}), \"getFullRequestString() works for passing in new params\");\n\n  // layer with null params\n        layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, null, null);\n        str = layer.getFullRequestString();\n        t.eq(str, tUrl + OpenLayers.Util.getParameterString({}), \"getFullRequestString() works for layer with null params\");\n\n  // layer with null params passing in new params\n        layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, null, null);\n        str = layer.getFullRequestString( { chicken: 6, \n                                            layers:\"road\" } );\n        t.eq(str, tUrl + OpenLayers.Util.getParameterString({chicken: 6, layers: \"road\"}), \"getFullRequestString() works for layer with null params passing in new params\");\n\n  // with specified altUrl parameter\n        tUrl = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.HTTPRequest(name, \"chicken\", tParams, null);\n        str = layer.getFullRequestString(null, tUrl);\n        t.eq(str, tUrl + '?' + OpenLayers.Util.getParameterString(tParams), \"getFullRequestString() works with specified altUrl parameter\");\n  \n  // single url object        \n        tUrl = [\"http://octo.metacarta.com/cgi-bin/mapserv\"];\n        layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, tParams, null);\n        str = layer.getFullRequestString();\n        t.eq(str, tUrl[0] + '?' + OpenLayers.Util.getParameterString(tParams), \"getFullRequestString() works for list of one url\");\n  \n  // two url object        \n        tUrl = [\"http://octo.metacarta.com/cgi-bin/mapserv\",\"http://labs.metacarta.com/cgi-bin/mapserv\"];\n        layer = new OpenLayers.Layer.HTTPRequest(name, tUrl, tParams, null);\n        str = layer.getFullRequestString();\n        t.eq(str, tUrl[1] + '?' + OpenLayers.Util.getParameterString(tParams), \"getFullRequestString() works for list of two urls\");\n        str = layer.getFullRequestString({'a':'b'});\n        t.eq(str, tUrl[0] + '?' + OpenLayers.Util.getParameterString(OpenLayers.Util.extend(tParams,{'a':'b'})), \"getFullRequestString() works for list of two urls and is deterministic\");\n\n    }\n\n    function test_Layer_HTTPRequest_selectUrl (t) { \n        t.plan( 4 ); \n\n        layer = new OpenLayers.Layer.HTTPRequest(name, url, params, options); \n\n        urls = [\"wms1\", \"wms2\", \"wms3\", \"wms4\"]; \n        t.eq( layer.selectUrl(\"bbox=-180,0,0,90\",  urls), \"wms3\", \"selectUrl(-90,-180) returns 4\" ); \n        t.eq( layer.selectUrl(\"bbox=-180,-90,0,0\", urls), \"wms1\", \"selectUrl(90,-180) returns 3\" ); \n        t.eq( layer.selectUrl(\"bbox=0,90,180,0\",   urls), \"wms1\", \"selectUrl(-90,180) returns 1\" ); \n        t.eq( layer.selectUrl(\"bbox=0,0,180,90\",   urls), \"wms4\", \"selectUrl(90,180) returns 2\" ); \n    }\n\n    function test_Layer_HTTPRequest_destroy (t) {\n        t.plan( 6 );    \n\n        var map = new OpenLayers.Map('map');\n\n        layer = new OpenLayers.Layer.HTTPRequest(\"Test Layer\",\n                                                 \"http://www.openlayers.org\", \n                                                 { foo: 2, bar: 3}, \n                                                 { opt1: 8, opt2: 9});\n\n        map.addLayer(layer);\n        layer.destroy();\n \n        // Ensure Layer.destroy() is called\n        t.eq( layer.name, null, \"layer.name is null after destroy\" );\n        t.eq( layer.div, null, \"layer.div is null after destroy\" );\n        t.eq( layer.map, null, \"layer.map is null after destroy\" );\n        t.eq( layer.options, null, \"layer.options is null after destroy\" );\n \n \n        // Specific to HTTPRequest \n        t.eq( layer.url, null, \"layer.url is null after destroy\" );\n        t.eq( layer.params, null, \"layer.params is null after destroy\" );\n    }\n\n  </script>\n</head>\n<body>\n  <div id=\"map\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/Image.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var layer; \n\n    function test_Layer_Image_constructor (t) {\n        t.plan( 13 );\n        \n        var options = { chicken: 151, foo: \"bar\", projection: \"EPSG:4326\" };\n        var layer = new OpenLayers.Layer.Image('Test Layer',\n                                        'http://earthtrends.wri.org/images/maps/4_m_citylights_lg.gif',\n                                                                        new OpenLayers.Bounds(-180, -88.759, 180, 88.759),\n                                                                                                        new OpenLayers.Size(580, 288), options);\n        \n        t.ok( layer instanceof OpenLayers.Layer.Image, \"new OpenLayers.Layer.Image returns object\" );\n        t.eq( layer.CLASS_NAME, \"OpenLayers.Layer.Image\", \"CLASS_NAME variable set correctly\");\n\n        t.eq( layer.name, \"Test Layer\", \"layer.name is correct\" );\n        t.ok( layer.id != null, \"Layer is given an id\");\n        t.eq( layer.projection.getCode(), \"EPSG:4326\", \"default layer projection correctly set\");\n        t.ok( ((layer.chicken == 151) && (layer.foo == \"bar\")), \"layer.options correctly set to Layer Object\" );\n        t.ok( ((layer.options[\"chicken\"] == 151) && (layer.options[\"foo\"] == \"bar\")), \"layer.options correctly backed up\" );\n\n        options.chicken = 552;\n        \n        t.eq( layer.options[\"chicken\"], 151 , \"layer.options correctly made fresh copy\" );\n        \n        t.eq( layer.isBaseLayer, true, \"Default img layer is base layer\" );\n\n        layer = new OpenLayers.Layer.Image('Test Layer',\n                                        'http://earthtrends.wri.org/images/maps/4_m_citylights_lg.gif',\n                                                                        new OpenLayers.Bounds(-180, -88.759, 180, 88.759),\n                                                                                                        new OpenLayers.Size(580, 288));\n        t.ok( layer instanceof OpenLayers.Layer.Image, \"new OpenLayers.Layer.Image returns object\" );\n        t.eq( layer.name, \"Test Layer\", \"layer.name is correct\" );\n        t.ok( layer.projection == null, \"default layer projection correctly set\");\n        t.ok( layer.options instanceof Object, \"layer.options correctly initialized as a non-null Object\" );\n    }\n    \n    function test_maxExtent(t) {\n        t.plan(2);\n        var layer;\n        \n        // test that the image extent is set as the default maxExtent\n        var extent = new OpenLayers.Bounds(1, 2, 3, 4);\n        var size = new OpenLayers.Size(2, 2);\n        layer = new OpenLayers.Layer.Image(\"Test\", \"foo\", extent, size);\n        t.eq(layer.maxExtent.toString(), extent.toString(), \"extent set as default maxExtent\");\n        \n        // test that the maxExtent can be set explicitly\n        var maxExtent = new OpenLayers.Bounds(10, 20, 30, 40);\n        layer = new OpenLayers.Layer.Image(\"Test\", \"foo\", extent, size, {maxExtent: maxExtent});\n        t.eq(layer.maxExtent.toString(), maxExtent.toString(), \"maxExtent can be set explicitly\");\n        \n    }\n\n    function test_Layer_Image_tileTests (t) {\n        t.plan(7);\n        var map = new OpenLayers.Map('map');\n        \n        layer = new OpenLayers.Layer.Image('Test Layer', \n                                        'http://earthtrends.wri.org/images/maps/4_m_citylights_lg.gif',\n                                                                        new OpenLayers.Bounds(-180, -88.759, 180, 88.759),\n                                                                                                        new OpenLayers.Size(580, 288));\n\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n\n        // no resolution info was sent, so maxResolution should be calculated\n        // by aspectRatio*extent/size (this is the pixel aspect ratio)\n        var aspectRatio =  (layer.extent.getHeight() / layer.size.h) /\n                           (layer.extent.getWidth() / layer.size.w);\n        t.eq(aspectRatio, layer.aspectRatio, \"aspectRatio is properly set\");\n        var maxExtent = aspectRatio * layer.extent.getWidth() / layer.size.w;\n        t.eq(maxExtent, layer.maxResolution, \"maxResolution is properly set\");\n\n        t.eq(layer.tile.position.x,-42, \"Tile x positioned correctly at maxextent\");\n        t.eq(layer.tile.position.y,106, \"Tile y positioned correctly at maxextent\");\n        t.eq(layer.tile.url, \"http://earthtrends.wri.org/images/maps/4_m_citylights_lg.gif\", \"URL is correct\");\n        map.zoomIn();\n        t.eq(layer.tile.url, \"http://earthtrends.wri.org/images/maps/4_m_citylights_lg.gif\", \"URL is correct\");\n        layer.setUrl('http://labs.metacarta.com/wms/vmap0?LAYERS=basic&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&FORMAT=image%2Fjpeg&SRS=EPSG%3A4326&BBOX=-180,-90,0,90&WIDTH=256&HEIGHT=256');\n        t.eq(layer.tile.url, \"http://labs.metacarta.com/wms/vmap0?LAYERS=basic&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&EXCEPTIONS=application%2Fvnd.ogc.se_inimage&FORMAT=image%2Fjpeg&SRS=EPSG%3A4326&BBOX=-180,-90,0,90&WIDTH=256&HEIGHT=256\", \"URL is correct after setURL\");\n    }\n/******\n * \n * \n * HERE IS WHERE SOME TESTS SHOULD BE PUT TO CHECK ON THE LONLAT-PX TRANSLATION\n * FUNCTIONS AND RESOLUTION AND GETEXTENT GETZOOMLEVEL, ETC\n * \n * \n */\n\n\n    function test_Layer_Image_destroy_before_use (t) {\n        t.plan(1);\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.Image('Test', 'http://earthtrends.wri.org/images/maps/4_m_citylights_lg.gif', new OpenLayers.Bounds(-180, -88.759, 180, 88.759), new OpenLayers.Size(580, 288));\n        map.addLayer(layer);\n        map.removeLayer(layer);\n        layer.destroy();\n        t.ok(true, \"destroy() didn't throw an error\");\n    }\n\n    function test_Layer_Image_destroy (t) {\n        t.plan( 4 );    \n\n        var map = new OpenLayers.Map('map');\n        \n        layer = new OpenLayers.Layer.Image('Test Layer', \n                                        'http://earthtrends.wri.org/images/maps/4_m_citylights_lg.gif',\n                                                                        new OpenLayers.Bounds(-180, -88.759, 180, 88.759),\n                                                                                                        new OpenLayers.Size(580, 288));\n\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n    \n        layer.destroy();\n\n        t.eq( layer.name, null, \"layer.name is null after destroy\" );\n        t.eq( layer.div, null, \"layer.div is null after destroy\" );\n        t.eq( layer.map, null, \"layer.map is null after destroy\" );\n        t.eq( layer.options, null, \"layer.options is null after destroy\" );\n\n    }\n\n    function test_loadEvents(t) {\n        t.plan(3);\n\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.Image(\n            'Test', '../../img/blank.gif',\n            new OpenLayers.Bounds(-180, -88.759, 180, 88.759),\n            new OpenLayers.Size(580, 288)\n        );\n    \n        map.addLayer(layer);\n\n        layer.events.register('loadstart', null, function(obj) {\n            t.ok(obj.object.tile.isLoading, \"loadstart triggered while tile is loading\");\n        });\n\n        var delay = false;\n        layer.events.register('loadend', null, function(obj) {\n            delay = true;\n        });\n\n        t.delay_call(5, function() {\n            t.eq(delay, true, \"registered for loadend\");\n            t.eq(layer.tile.isLoading, false, \"loadend triggered after tile is loaded\");\n            map.destroy(); //tear down\n            return delay;\n        });\n        map.zoomToMaxExtent();\n    }\n\n  </script>\n</head>\n<body>\n  <div id=\"map\" style=\"width:500px;height:500px\"></div>\n  <div id=\"map2\" style=\"width:100px;height:100px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/KaMap.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var layer; \n\n    var name = 'Test Layer';\n    var url = \"http://boston.freemap.in/tile.php?\";\n    var params = {\n                  'map':'boston-new', \n                  'g':'border,water,roads,openspace', \n                  'i':'JPEG'\n                 };\n    var units = \"meters\";\n\n\n\n    function test_Layer_KaMap_constructor (t) {\n        t.plan( 1 );\n                       \n        layer = new OpenLayers.Layer.KaMap(name, url, params, units);\n        t.ok( layer instanceof OpenLayers.Layer.KaMap, \"returns OpenLayers.Layer.KaMap object\" );\n    }\n\n    function test_Layer_Grid_moveTo_buffer_calculation (t) {\n        t.plan(6);\n\n        var map = new OpenLayers.Map( 'map3' ); // odd map size\n        var layer0 = new OpenLayers.Layer.KaMap( \"0 buffer: OpenLayers WMS\", \n                    \"http://labs.metacarta.com/wms/vmap0\",\n                    {layers: 'basic'}, {'buffer':0} );\n        map.addLayer(layer0);\n\n        var layer1 = new OpenLayers.Layer.KaMap( \"1 buffer: OpenLayers WMS\", \n                \"http://labs.metacarta.com/wms/vmap0\",\n                {layers: 'basic'}, {'buffer':1} );\n        map.addLayer(layer1);\n\n        var layer2 = new OpenLayers.Layer.KaMap( \"2 buffer: OpenLayers WMS\", \n                \"http://labs.metacarta.com/wms/vmap0\",\n                {layers: 'basic'}, {'buffer':2} );\n        map.addLayer(layer2);\n\n        map.setCenter(new OpenLayers.LonLat(0, 0), 4); \n        t.eq( layer0.grid.length, 3, \"Grid rows with buffer:0\" );\n        map.setBaseLayer(layer1);\n        t.eq( layer1.grid.length, 5, \"Grid rows with buffer:1\" );\n        map.setBaseLayer(layer2);\n        t.eq( layer2.grid.length, 7, \"Grid rows with buffer:2\" );\n\n        // zooming in on Greenland exercises the bug from pre-r4313\n        map.setCenter(new OpenLayers.LonLat(0, 90), 4); \n        t.eq( layer0.grid.length, 3, \"Grid rows with buffer:0\" );\n        map.setBaseLayer(layer1);\n        t.eq( layer1.grid.length, 5, \"Grid rows with buffer:1\" );\n        map.setBaseLayer(layer2);\n        t.eq( layer2.grid.length, 7, \"Grid rows with buffer:2\" );\n        map.destroy();\n    }\n\n    function test_Layer_KaMap_inittiles (t) {\n        t.plan( 2 );\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.KaMap(name, url, params, units);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0),5);\n        t.eq( layer.grid.length, 4, \"KaMap rows is correct.\" );\n        t.eq( layer.grid[0].length, 3, \"KaMap cols is correct.\" );\n        map.destroy();\n        \n    }\n\n    function test_Layer_KaMap_clearTiles (t) {\n        t.plan( 1 );\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.KaMap(name, url, params, units);\n        map.addLayer(layer);\n\n        map.setCenter(new OpenLayers.LonLat(0,0));\n\n        //grab a reference to one of the tiles\n        var tile = layer.grid[0][0];        \n\n        layer.clearGrid();\n\n        t.ok( layer.grid != null, \"layer.grid does not get nullified\" );\n        map.destroy();\n    }\n\n\n    function test_Layer_KaMap_getKaMapBounds(t) {\n        t.plan( 1 );\n\n        layer = new OpenLayers.Layer.KaMap(name, url, params, units);\n\n        var bl = { bounds: new OpenLayers.Bounds(1,2,2,3)};\n        var tr = { bounds: new OpenLayers.Bounds(2,3,3,4)};\n        layer.grid = [ [6, tr], \n                       [bl, 7]];\n\n        var bounds = layer.getTilesBounds();\n    \n        var testBounds = new OpenLayers.Bounds(1,2,3,4);\n        \n        t.ok( bounds.equals(testBounds), \"getKaMapBounds() returns correct bounds\")\n        \n        layer.grid = null;\n    }\n\n    function test_Layer_KaMap_getResolution(t) {\n        t.plan( 1 );\n\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.KaMap(name, url, params, units);\n        map.addLayer(layer);\n\n        map.zoom = 5;\n\n        t.eq( layer.getResolution(), 0.0439453125, \"getResolution() returns correct value\");\n        map.destroy();\n    }\n\n    function test_Layer_KaMap_getZoomForExtent(t) {\n        t.plan( 2 );\n        var bounds, zoom;\n\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.KaMap(name, url, params, units);\n        map.addLayer(layer);\n\n        bounds = new OpenLayers.Bounds(10,10,12,12);\n        zoom = layer.getZoomForExtent(bounds);\n\n        t.eq( zoom, 8, \"getZoomForExtent() returns correct value\");\n\n        bounds = new OpenLayers.Bounds(10,10,100,100);\n        zoom = layer.getZoomForExtent(bounds);\n\n        t.eq( zoom, 2, \"getZoomForExtent() returns correct value\");\n        map.destroy();\n    }   \n    \n    function test_Layer_kaMap_mergeNewParams (t) {\n        t.plan( 4 );\n\n        var map = new OpenLayers.Map(\"map\");\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.KaMap(name, url, params);\n        \n        var newParams = { layers: 'sooper', \n                          chickpeas: 'image/png'};\n\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        layer.redraw = function() {\n            t.ok(true, \"layer is redrawn after new params merged\");\n        }\n        \n        layer.mergeNewParams(newParams);\n        \n        t.eq( layer.params.layers, \"sooper\", \"mergeNewParams() overwrites well\");\n        t.eq( layer.params.chickpeas, \"image/png\", \"mergeNewParams() adds well\");\n\n        newParams.chickpeas = 151;\n\n        t.eq( layer.params.chickpeas, \"image/png\", \"mergeNewParams() makes clean copy of hashtable\");\n        map.destroy();\n    }\n\n\n    /** THIS WOULD BE WHERE THE TESTS WOULD GO FOR \n     *     \n     *    -moveTo\n     *    -insertColumn\n     *    -insertRow\n    \n    function 07_Layer_KaMap_moveTo(t) {\n    }\n\n    function 08_Layer_KaMap_insertColumn(t) {\n    }\n\n    function 09_Layer_KaMap_insertRow(t) {\n    }\n\n     * \n     */\n\n    function test_Layer_KaMap_clone(t) {\n        t.plan(5);\n        \n        var options = {tileSize: new OpenLayers.Size(500,50)};\n        var map = new OpenLayers.Map('map', options);\n        layer = new OpenLayers.Layer.KaMap(name, url, params, units);\n        map.addLayer(layer);\n\n        layer.grid = [ [6, 7], \n                       [8, 9]];\n\n        var clone = layer.clone();\n\n        t.ok( clone.grid != layer.grid, \"clone does not copy grid\");\n\n        t.ok( clone.tileSize.equals(layer.tileSize), \"tileSize correctly cloned\");\n\n        layer.tileSize.w += 40;\n\n        t.eq( clone.tileSize.w, 500, \"changing layer.tileSize does not change clone.tileSize -- a fresh copy was made, not just copied reference\");\n\n        t.eq( clone.alpha, layer.alpha, \"alpha copied correctly\");\n        \n        t.eq( clone.CLASS_NAME, \"OpenLayers.Layer.KaMap\", \"Clone is a ka-map layer\");\n\n        layer.grid = null;\n        map.destroy();\n    }\n\n    function test_Layer_KaMap_setMap(t) {\n\n        t.plan(2);\n        \n        var options = {tileSize: new OpenLayers.Size(500,50)};\n        var map = new OpenLayers.Map('map', options);\n        layer = new OpenLayers.Layer.KaMap(name, url, params, units);\n\n\n        layer.setMap(map);\n        \n        t.ok( layer.tileSize != null, \"tileSize has been set\");\n        t.ok( (layer.tileSize.h == 50) && (layer.tileSize.w == 500), \"tileSize has been set correctly\");\n        map.destroy();\n    }\n    function test_Layer_KaMap_getTileBounds(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\", {zoomMethod: null});\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.KaMap(name, url, params);\n        \n        var newParams = { layers: 'sooper', \n                          chickpeas: 'image/png'};\n\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        map.zoomIn();\n        var bounds = layer.getTileBounds(new OpenLayers.Pixel(200,200));\n        t.eq(bounds.toBBOX(), \"-180,0,0,180\", \"get tile bounds returns correct bounds\"); \n        map.pan(200,0,{animate:false});\n        var bounds = layer.getTileBounds(new OpenLayers.Pixel(200,200));\n        t.eq(bounds.toBBOX(), \"0,0,180,180\", \"get tile bounds returns correct bounds after pan\"); \n        map.destroy();\n    }\n\n    function test_Layer_KaMap_destroy (t) {\n\n        t.plan( 3 );\n\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.KaMap(name, url, params, units);\n        map.addLayer(layer);\n        layer.destroy();\n        t.eq( layer.grid, null, \"layer.grid is null after destroy\" );\n        t.eq( layer.tileSize, null, \"layer.tileSize is null after destroy\" );\n\n\n    //test with tile creation\n        layer = new OpenLayers.Layer.KaMap(name, url, params, units);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 5);\n        //grab a reference to one of the tiles\n        var tile = layer.grid[0][0];        \n\n        layer.destroy();\n\n        t.ok( layer.grid == null, \"tiles appropriately destroyed\");\n        map.destroy();\n    }\n    \n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px;display:none\"></div>\n<div id=\"map2\" style=\"width:500px;height:550px;display:none\"></div>\n<div id=\"map3\" style=\"width:594px;height:464px;display:none\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/MapGuide.html",
    "content": "<html>\n<head>\n    <script type=\"text/javascript\">var oldAlert = window.alert, gMess; window.alert = function(message) {gMess = message; return true;};</script>\n    <script src=\"http://maps.google.com/maps/api/js?v=3&amp;sensor=false\"></script>\n    <script type=\"text/javascript\">window.alert = oldAlert;</script>\n<script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var layer; \n\n    var name = 'MapGuide Test Layer';\n    var url = \"http://data.mapguide.com/mapguide/mapagent/mapagent.fcgi?USERNAME=Anonymous&\";\n    var paramsTiled = {\n      mapdefinition: 'Library://Samples/Sheboygan/MapsTiled/Sheboygan.MapDefinition',\n      basemaplayergroupname: \"Base Layer Group\"\n    }\n    var paramsUntiled = {\n      mapdefinition: 'Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition'\n    };\n\n    function test_Layer_MapGuide_untiled_constructor (t) {\n        t.plan( 8 );\n\n        var trans_format = \"image/png\";\n        var options = {singleTile:true};\n        if (OpenLayers.Util.alphaHack()) { trans_format = \"image/gif\"; } \n        \n        layer = new OpenLayers.Layer.MapGuide(name, url, paramsUntiled, options);\n        t.ok( layer instanceof OpenLayers.Layer.MapGuide, \"new OpenLayers.Layer.MapGuide returns object\" );\n        t.eq( layer.url, \"http://data.mapguide.com/mapguide/mapagent/mapagent.fcgi?USERNAME=Anonymous&\", \"layer.url is correct (HTTPRequest inited)\" );\n        t.eq( layer.params.mapdefinition, \"Library://Samples/Sheboygan/Maps/Sheboygan.MapDefinition\", \"params passed in correctly\" );\n\n        t.eq( layer.params.operation, \"GETMAPIMAGE\", \"default params set correctly and copied\");\n\n        t.eq(layer.isBaseLayer, true, \"no transparency setting, layer is baselayer\");\n\n        options.transparent = \"true\";\n        var layer2 = new OpenLayers.Layer.MapGuide(name, url, paramsUntiled, options);\n        t.eq(layer2.isBaseLayer, false, \"transparency == 'true', layer is not baselayer\");\n\n        options.transparent = true;\n        var layer5 = new OpenLayers.Layer.MapGuide(name, url, paramsUntiled, options);\n        t.eq(layer5.isBaseLayer, false, \"transparency == true, layer is not baselayer\");\n\n        options.transparent = false;\n        var layer6 = new OpenLayers.Layer.MapGuide(name, url, paramsUntiled, options);\n        t.eq(layer6.isBaseLayer, true, \"transparency == false, layer is baselayer\");\n    }\n    \n    function test_Layer_MapGuide_tiled_constructor (t) {\n        t.plan( 5 );\n\n        var trans_format = \"image/png\";\n        var options = {singleTile:false};\n        if (OpenLayers.Util.alphaHack()) { trans_format = \"image/gif\"; } \n        \n        layer = new OpenLayers.Layer.MapGuide(name, url, paramsTiled, options);\n        t.ok( layer instanceof OpenLayers.Layer.MapGuide, \"new OpenLayers.Layer.MapGuide returns object\" );\n        t.eq( layer.url, \"http://data.mapguide.com/mapguide/mapagent/mapagent.fcgi?USERNAME=Anonymous&\", \"layer.url is correct (HTTPRequest inited)\" );\n        t.eq( layer.params.basemaplayergroupname, \"Base Layer Group\", \"params passed in correctly\" );\n\n        t.eq( layer.params.operation, \"GETTILEIMAGE\", \"default params correctly uppercased and copied\");\n        t.eq( layer.params.version, \"1.2.0\", \"version params set correctly set\");\n    }\n    \n    function test_Layer_MapGuide_inittiles (t) {\n        t.plan( 1 );\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.MapGuide(name, url, paramsTiled);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,400000),5);\n        t.eq( layer.grid.length, 3, \"Grid rows is correct.\" );\n        // t.eq( layer.grid[0].length, 6, \"Grid cols is correct.\" );\n        map.destroy();\n    }\n\n\n    function test_Layer_MapGuide_clone (t) {\n        t.plan(4);\n        \n        var options = {tileSize: new OpenLayers.Size(500,50)};\n        var map = new OpenLayers.Map('map', options);\n        layer = new OpenLayers.Layer.MapGuide(name, url, paramsTiled);\n        map.addLayer(layer);\n\n        layer.grid = [ [6, 7], \n                       [8, 9]];\n\n        var clone = layer.clone();\n\n        t.eq( layer.tileSize.w, 300, \"layer.tileSize fixed to 300x300\");\n        t.ok( clone.grid != layer.grid, \"clone does not copy grid\");\n\n        t.ok( clone.tileSize.equals(layer.tileSize), \"tileSize correctly cloned\");\n\n        layer.tileSize.w += 40;\n\n        t.eq( clone.alpha, layer.alpha, \"alpha copied correctly\");\n\n        layer.grid = null;\n        map.destroy();\n    }\n\n    function test_Layer_MapGuide_isBaseLayer(t) {\n        t.plan(3);\n        \n        var options = {singleTile:true};\n        layer = new OpenLayers.Layer.MapGuide(name, url, paramsUntiled, options);\n        t.ok( layer.isBaseLayer, \"baselayer is true by default\");\n\n        var newParams = OpenLayers.Util.extend({}, paramsUntiled);\n        options.transparent = \"true\";\n        layer = new OpenLayers.Layer.MapGuide(name, url, newParams, options);\n        t.ok( !layer.isBaseLayer, \"baselayer is false when transparent is set to true\");\n\n        newParams = OpenLayers.Util.extend({}, paramsUntiled);\n        options.isBaseLayer = false;\n        layer = new OpenLayers.Layer.MapGuide(name, url, newParams, options);\n        t.ok( !layer.isBaseLayer, \"baselayer is false when option is set to false\" );\n    }\n\n    function test_Layer_MapGuide_mergeNewParams (t) {\n        t.plan( 4 );\n\n        var options = {singleTile:true};\n        var map = new OpenLayers.Map(\"map\");\n        layer = new OpenLayers.Layer.MapGuide(name, url, paramsUntiled, options);\n        \n        var newParams = { mapDefinition: 'Library://Samples/Gmap/Maps/gmap.MapDefinition',\n                          chickpeas: 'image/png'};\n\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n\n        layer.redraw = function() {\n            t.ok(true, \"layer is redrawn after new params merged\");\n        }\n\n        layer.mergeNewParams(newParams);\n        \n        t.eq( layer.params.mapDefinition, \"Library://Samples/Gmap/Maps/gmap.MapDefinition\", \"mergeNewParams() overwrites well\");\n        t.eq( layer.params.chickpeas, \"image/png\", \"mergeNewParams() adds well\");\n    \n        newParams.chickpeas = 151;\n\n        t.eq( layer.params.chickpeas, \"image/png\", \"mergeNewParams() makes clean copy of hashtable\");\n        map.destroy();\n    }\n\n    function test_Layer_MapGuide_destroy (t) {\n\n        t.plan( 1 );\n\n        var options = {singleTile:true};\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.MapGuide(name, url, paramsUntiled, options);\n        map.addLayer(layer);\n\n        map.setCenter(new OpenLayers.LonLat(0,0), 5);\n\n        //grab a reference to one of the tiles\n        var tile = layer.grid[0][0];        \n\n        layer.destroy();\n        \n    // checks to make sure superclass (grid) destroy() was called    \n        \n        t.ok( layer.grid == null, \"grid set to null\");\n    }\n    \n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/MapServer.html",
    "content": "<html>\n<head>\n    <script type=\"text/javascript\">var oldAlert = window.alert, gMess; window.alert = function(message) {gMess = message; return true;};</script>\n    <script type=\"text/javascript\">window.alert = oldAlert;</script>\n    \n\n<script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    // turn off animation frame handling, so we can check img urls in tests\n    delete OpenLayers.Layer.Grid.prototype.queueTileDraw;\n    \n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var layer; \n\n    var name = 'Test Layer';\n    var url = \"http://labs.metacarta.com/cgi-bin/mapserv\";\n    var params = { map: '/mapdata/vmap_wms.map', \n                   layers: 'basic'};\n\n    function test_Layer_MapServer_constructor (t) {\n        t.plan( 4 );\n\n        var url = \"http://labs.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.MapServer(name, url, params);\n        t.ok( layer instanceof OpenLayers.Layer.MapServer, \"new OpenLayers.Layer.MapServer returns object\" );\n        t.eq( layer.url, \"http://labs.metacarta.com/cgi-bin/mapserv\", \"layer.url is correct (HTTPRequest inited)\" );\n\n        t.eq( layer.params.mode, \"map\", \"default mode param correctly copied\");\n        t.eq( layer.params.map_imagetype, \"png\", \"default imagetype correctly copied\");\n\n\n    }\n    \n    function test_Layer_MapServer_addtile (t) {\n        t.plan( 6 );\n    \n        var url = \"http://labs.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.MapServer(name, url, params);\n        var map = new OpenLayers.Map('map', {tileManager: null});\n        map.addLayer(layer);\n        var pixel = new OpenLayers.Pixel(5,6);\n        var tile = layer.addTile(new OpenLayers.Bounds(1,2,3,4), pixel);\n        tile.draw();\n\n        var img = tile.imgDiv;\n        var tParams = OpenLayers.Util.extend({},params);\n        tParams = OpenLayers.Util.extend(tParams, {\n                 layers: 'basic', \n                 mode: 'map',\n                 map_imagetype: 'png',\n                 mapext:[1,2,3,4],\n                 imgext:[1,2,3,4],\n                 map_size:[256, 256],\n                 imgx:128,\n                 imgy:128,\n                 imgxy:[256,256]\n        });\n        t.eq( tile.url,\n             url + \"?\" + OpenLayers.Util.getParameterString(tParams).replace(/,/g, \"+\"),\n             \"image src is created correctly via addtile\" );\n        t.eq( tile.getTile().style.top, \"6px\", \"image top is set correctly via addtile\" );\n        t.eq( tile.getTile().style.left, \"5px\", \"image top is set correctly via addtile\" );\n\n        var firstChild = layer.div.firstChild;\n        t.eq( firstChild.nodeName.toLowerCase(), \"img\", \"div first child is an image object\" );\n        t.ok( firstChild == img, \"div first child is correct image object\" );\n        t.eq( tile.position.toString(), \"x=5,y=6\", \"Position of tile is set correctly.\" );\n        map.destroy();\n    }\n    \n    function test_Layer_MapServer_inittiles (t) {\n        t.plan( 2 );\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.MapServer(name, url, params, {buffer: 0});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0),5);\n        t.eq( layer.grid.length, 4, \"Grid rows is correct.\" );\n        t.eq( layer.grid[0].length, 3, \"Grid cols is correct.\" );\n        map.destroy();\n        \n    }\n\n\n    function test_Layer_MapServer_clone (t) {\n        t.plan(4);\n        \n        var url = \"http://labs.metacarta.com/cgi-bin/mapserv\";\n        var options = {tileSize: new OpenLayers.Size(500,50)};\n        var map = new OpenLayers.Map('map', options);\n        layer = new OpenLayers.Layer.MapServer(name, url, params);\n        map.addLayer(layer);\n\n        layer.grid = [ [6, 7], \n                       [8, 9]];\n\n        var clone = layer.clone();\n\n        t.ok( clone.grid != layer.grid, \"clone does not copy grid\");\n\n        t.ok( clone.tileSize.equals(layer.tileSize), \"tileSize correctly cloned\");\n\n        layer.tileSize.w += 40;\n\n        t.eq( clone.tileSize.w, 500, \"changing layer.tileSize does not change clone.tileSize -- a fresh copy was made, not just copied reference\");\n\n        t.eq( clone.alpha, layer.alpha, \"alpha copied correctly\");\n\n        layer.grid = null;\n        map.destroy();\n    }\n\n    function test_Layer_MapServer_isBaseLayer(t) {\n        t.plan(3);\n        \n        var url = \"http://labs.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.MapServer(name, url, params);\n        t.ok( layer.isBaseLayer, \"baselayer is true by default\");\n\n        var newParams = OpenLayers.Util.extend({}, params);\n        newParams.transparent = \"true\";\n        layer = new OpenLayers.Layer.MapServer(name, url, newParams);\n        t.ok( !layer.isBaseLayer, \"baselayer is false when transparent is set to true\");\n\n        layer = new OpenLayers.Layer.MapServer(name, url, params, {isBaseLayer: false});\n        t.ok( !layer.isBaseLayer, \"baselayer is false when option is set to false\" );\n    }\n\n    function test_Layer_MapServer_mergeNewParams (t) {\n        t.plan( 4 );\n\n        var map = new OpenLayers.Map(\"map\");\n        var url = \"http://labs.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.MapServer(name, url, params);\n        \n        var newParams = { layers: 'sooper', \n                          chickpeas: 'image/png'};\n\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        \n        layer.redraw = function() {\n            t.ok(true, \"layer is redrawn after new params merged\");\n        }\n        layer.mergeNewParams(newParams);\n        \n        t.eq( layer.params.layers, \"sooper\", \"mergeNewParams() overwrites well\");\n        t.eq( layer.params.chickpeas, \"image/png\", \"mergeNewParams() adds well\");\n        \n        newParams.chickpeas = 151;\n\n        t.eq( layer.params.chickpeas, \"image/png\", \"mergeNewParams() makes clean copy of hashtable\");\n        map.destroy();\n    }\n\n    function test_Layer_MapServer_getFullRequestString (t) {\n        t.plan( 3 );\n        var map = new OpenLayers.Map('map');\n        tUrl = \"http://labs.metacarta.com/cgi-bin/mapserv\";\n        tParams = { layers: 'basic', \n                    format: 'png'};\n        var tLayer = new OpenLayers.Layer.MapServer(name, tUrl, tParams);\n        map.addLayer(tLayer);\n        str = tLayer.getFullRequestString();\n        var tParams = {\n                 layers: 'basic', \n                 format: 'png',\n                 mode: 'map',\n                 map_imagetype: 'png'\n        };\n\n            var sStr = tUrl + \"?\" + OpenLayers.Util.getParameterString(tParams);\n            sStr = sStr.replace(/,/g, \"+\");\n        \n        t.eq(str, sStr , \"getFullRequestString() works\");\n        map.destroy();\n        \n        tUrl = [\"http://octo.metacarta.com/cgi-bin/mapserv\",\"http://labs.metacarta.com/cgi-bin/mapserv\"];\n        layer = new OpenLayers.Layer.MapServer(name, tUrl, tParams, null);\n        str = layer.getFullRequestString({'c':'d'});\n        t.eq(str, tUrl[1] + '?' + OpenLayers.Util.getParameterString(OpenLayers.Util.extend(tParams,{'c':'d'})), \"getFullRequestString() works for list of two urls and is deterministic\");\n        layer.destroy();\n        var tParams = {\n                 layers: 'basic', \n                 format: 'png',\n                 mode: 'map',\n                 map_imagetype: 'png'\n        };\n        tUrl = [\"http://octo.metacarta.com/cgi-bin/mapserv\",\"http://labs.metacarta.com/cgi-bin/mapserv\"];\n        layer = new OpenLayers.Layer.MapServer(name, tUrl, tParams, null);\n        str = layer.getFullRequestString({'a':'b'});\n        t.eq(str, tUrl[0] + '?' + OpenLayers.Util.getParameterString(OpenLayers.Util.extend(tParams,{'a':'b'})), \"getFullRequestString() works for list of two urls and is deterministic\");\n        layer.destroy();\n\n    }\n\n    function test_Layer_MapServer_singleTile (t) {\n        t.plan( 5 );\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.MapServer(name, url, params, {singleTile: true});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0),5);\n        t.eq( layer.singleTile, true, \"layer has singleTile property, great!\" );\n        t.eq( layer.grid.length, 1, \"Grid has only a single row, good enough!\" );\n        t.eq( layer.grid[0].length, 1, \"Grid has only a single column, good enough!\" );\n        t.eq( layer.tileSize.w, 750, \"Image width is correct\" );\n        t.eq( layer.tileSize.h, 825, \"Image height is correct\" );\n        map.destroy();\n    }\n\n    \n    \n    function test_Layer_MapServer_destroy (t) {\n\n        t.plan( 1 );\n\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.MapServer(name, url, params);\n        map.addLayer(layer);\n\n        map.setCenter(new OpenLayers.LonLat(0,0), 5);\n\n        //grab a reference to one of the tiles\n        var tile = layer.grid[0][0];        \n\n        layer.destroy();\n        \n    // checks to make sure superclass (grid) destroy() was called    \n        \n        t.ok( layer.grid == null, \"grid set to null\");\n        map.destroy();\n    }\n    \n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/Markers.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var layer; \n\n    function test_initialize(t) {\n        t.plan( 2 );\n        \n        layer = new OpenLayers.Layer.Markers('Test Layer');\n        t.ok( layer instanceof OpenLayers.Layer.Markers, \"new OpenLayers.Layer.Markers returns object\" );\n        t.eq( layer.name, \"Test Layer\", \"layer.name is correct\" );\n    }\n    function test_addlayer (t) {\n        t.plan( 3 );\n        \n        layer = new OpenLayers.Layer.Markers('Test Layer');\n        t.ok( layer instanceof OpenLayers.Layer.Markers, \"new OpenLayers.Layer.Markers returns object\" );\n        t.eq( layer.name, \"Test Layer\", \"layer.name is correct\" );\n        layer.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0,0), \n                                              new OpenLayers.Icon())\n                       );\n        t.eq( layer.markers.length, 1, \"addLayer adds marker to layer.\" );\n    }\n    function test_addMarker_removeMarker (t) {\n        t.plan( 6 );\n\n        var map = new OpenLayers.Map('map');\n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(baseLayer);\n        map.zoomToMaxExtent();\n        layer = new OpenLayers.Layer.Markers('Test Layer');\n        map.addLayer(layer);\n        var marker = new OpenLayers.Marker(new OpenLayers.LonLat(5,40));\n        layer.addMarker(marker);\n        t.ok(  marker.icon.imageDiv.parentNode == layer.div, \"addMarker adds marker image node into layer node.\" ); \n        layer.removeMarker(marker);\n        t.ok(  marker.icon.imageDiv.parentNode != layer.div, \"removeMarker removes marker image node from layer node.\" ); \n        layer.removeMarker(marker);\n        t.ok(true, \"Removing marker twice does not fail.\");\n        layer.addMarker(marker);\n        t.ok(  marker.icon.imageDiv.parentNode == layer.div, \"addMarker adds marker image node into layer node.\" ); \n\n        layer.markers = null;\n        layer.removeMarker(marker);\n        t.ok(true, \"removing marker when no markers present does not script error\");\n\n        var l = new OpenLayers.Layer.Markers();\n        var marker = new OpenLayers.Marker(new OpenLayers.LonLat(5,40));\n        l.addMarker(marker);\n        l.removeMarker(marker);\n        t.ok(true, \"Removing marker when layer not added to map does not fail.\");\n\n    }\n    \n    function test_markerMovement(t) {\n        \n        t.plan(6);\n        \n        var map = new OpenLayers.Map(\"map\", {zoomMethod: null});\n        var layer = new OpenLayers.Layer.Markers(\"Base\", {isBaseLayer: true});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 1);\n        \n        var size = new OpenLayers.Size(10, 10);\n        var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);\n        var icon = new OpenLayers.Icon(\"foo\", size, offset);\n        var marker = new OpenLayers.Marker(new OpenLayers.LonLat(10, -10), icon)\n        layer.addMarker(marker);\n        \n        t.eq(marker.icon.px.x, 554, \"marker icon is placed at 554 px on x-axis\");\n        t.eq(marker.icon.px.y, 314, \"marker icon is placed at 314 px on y-axis\");\n        \n        map.zoomTo(2);\n        \n        t.eq(marker.icon.px.x, 568, \"marker icon moved to 568 px on x-axis\");\n        t.eq(marker.icon.px.y, 328, \"marker icon moved to 328 px on y-axis\");\n        \n        map.zoomTo(1);\n\n        t.eq(marker.icon.px.x, 554, \"marker icon moved back to 554 px on x-axis\");\n        t.eq(marker.icon.px.y, 314, \"marker icon moved back to 314 px on y-axis\");\n        \n    }\n    \n    function test_destroy (t) {\n        t.plan( 1 );    \n        layer = new OpenLayers.Layer.Markers('Test Layer');\n        var map = new OpenLayers.Map('map');\n        map.addLayer(layer);\n        layer.destroy();\n        t.eq( layer.map, null, \"layer.map is null after destroy\" );\n    }\n\n    function test_getDataExtent(t) {\n        t.plan( 4 );\n\n        var layer = {};\n        var ret = OpenLayers.Layer.Markers.prototype.getDataExtent.apply(layer, []);\n        t.eq(ret, null, \"does not crash, returns null on layer with null 'this.markers'\");\n\n        layer.markers = [];\n        ret = OpenLayers.Layer.Markers.prototype.getDataExtent.apply(layer, []);\n        t.eq(ret, null, \"returns null on layer with empty 'this.markers'\");\n        \n        layer.markers.push({\n            'lonlat': new OpenLayers.LonLat(4,5)\n        });\n        var expectedBounds = new OpenLayers.Bounds(4,5,4,5);\n        ret = OpenLayers.Layer.Markers.prototype.getDataExtent.apply(layer, []);\n        t.ok(ret.equals(expectedBounds), \"returns expected bounds with only one marker\");\n\n        layer.markers.push({\n            'lonlat': new OpenLayers.LonLat(1,2)\n        });\n        var expectedBounds = new OpenLayers.Bounds(1,2,4,5);\n        ret = OpenLayers.Layer.Markers.prototype.getDataExtent.apply(layer, []);\n        t.ok(ret.equals(expectedBounds), \"returns expected bounds with multiple markers\");\n\n    }\n\n    function test_setOpacity(t) {\n        t.plan(1);\n\n        layer = new OpenLayers.Layer.Markers('Test Layer');\n\n        var opacity = 0.1234;\n        \n        for (var i = 0; i < 12; i++) {\n            layer.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0,0), new OpenLayers.Icon()));\n        }\n\n        layer.setOpacity(opacity);\n\n        for (var i = 0; i < 4; i++) {\n            layer.addMarker(new OpenLayers.Marker(new OpenLayers.LonLat(0,0), new OpenLayers.Icon()));\n        }\n        \n        var itWorks = false;\n        for (var i = 0; i < layer.markers.length; i++) {\n            itWorks = parseFloat(layer.markers[i].icon.imageDiv.style.opacity) == opacity;\n            if (!itWorks) {\n                break;\n            }\n        }\n        t.ok(itWorks, \"setOpacity change markers opacity\");\n    }\n\n  </script>\n</head>\n<body>\n  <div id=\"map\" style=\"width: 1080px; height: 600px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/OSM.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    function test_clone(t) {\n        t.plan(1);\n        var layer = new OpenLayers.Layer.OSM();\n        var clone = layer.clone();\n        t.ok(clone instanceof OpenLayers.Layer.OSM, \"clone is a Layer.OSM instance\");\n    }\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/PointGrid.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<script src=\"../OLLoader.js\"></script>\n<script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(1);\n        var layer = new OpenLayers.Layer.PointGrid();\n        t.ok(layer instanceof OpenLayers.Layer.PointGrid, \"instance created\");\n        layer.destroy();\n    }\n    \n    function test_name(t) {\n        t.plan(1);\n        var layer = new OpenLayers.Layer.PointGrid({name: \"foo\"});\n        t.eq(layer.name, \"foo\", \"name set like every other property\");\n        layer.destroy();\n    }\n    \n    function test_spacing(t) {\n        t.plan(7);\n        \n        var layer = new OpenLayers.Layer.PointGrid({\n            isBaseLayer: true,\n            resolutions: [1],\n            maxExtent: new OpenLayers.Bounds(-100, -50, 100, 50),\n            dx: 10,\n            dy: 10,\n            ratio: 1\n        });\n        \n        var map = new OpenLayers.Map({\n            div: \"map\",\n            layers: [layer],\n            center: new OpenLayers.LonLat(0, 0),\n            zoom: 0\n        });\n        \n        t.eq(layer.features.length, 200, \"200 features\");\n        \n        // set dx/dy together\n        layer.setSpacing(20);\n        t.eq(layer.dx, 20, \"dx 20\");\n        t.eq(layer.dy, 20, \"dy 20\");\n        t.eq(layer.features.length, 50, \"50 features\");\n        \n        // set dx/dy independently\n        layer.setSpacing(50, 25);\n        t.eq(layer.dx, 50, \"dx 50\");\n        t.eq(layer.dy, 25, \"dy 25\");\n        t.eq(layer.features.length, 16, \"16 features\");\n        \n        map.destroy();\n    }\n    \n    function test_ratio(t) {\n        t.plan(3);\n        \n        var layer = new OpenLayers.Layer.PointGrid({\n            isBaseLayer: true,\n            resolutions: [1],\n            maxExtent: new OpenLayers.Bounds(-100, -50, 100, 50),\n            dx: 25,\n            dy: 25,\n            ratio: 1\n        });\n        \n        var map = new OpenLayers.Map({\n            div: \"map\",\n            layers: [layer],\n            center: new OpenLayers.LonLat(0, 0),\n            zoom: 0\n        });\n        \n        t.eq(layer.features.length, 32, \"32 features\");\n        \n        // increase ratio (1.5 -> 300 x 150)\n        layer.setRatio(1.5);\n        t.eq(layer.ratio, 1.5, \"ratio 1.5\");\n        t.eq(layer.features.length, 72, \"72 features\");\n        \n        map.destroy();\n    }\n\n    function test_maxFeatures(t) {\n        t.plan(3);\n        \n        var layer = new OpenLayers.Layer.PointGrid({\n            isBaseLayer: true,\n            resolutions: [1],\n            maxExtent: new OpenLayers.Bounds(-100, -50, 100, 50),\n            dx: 10,\n            dy: 10,\n            ratio: 1\n        });\n        \n        var map = new OpenLayers.Map({\n            div: \"map\",\n            layers: [layer],\n            center: new OpenLayers.LonLat(0, 0),\n            zoom: 0\n        });\n        \n        t.eq(layer.features.length, 200, \"200 features\");\n        \n        // limit maxFeatures\n        layer.setMaxFeatures(150);\n        t.eq(layer.maxFeatures, 150, \"maxFeatures 150\");\n        t.ok(layer.features.length <= 150, \"<= 150 features\");\n        \n        map.destroy();\n    }\n\n    function test_rotation(t) {\n        t.plan(6);\n        \n        var layer = new OpenLayers.Layer.PointGrid({\n            isBaseLayer: true,\n            resolutions: [1],\n            maxExtent: new OpenLayers.Bounds(-100, -50, 100, 50),\n            dx: 10,\n            dy: 10,\n            ratio: 1\n        });\n        \n        var map = new OpenLayers.Map({\n            div: \"map\",\n            layers: [layer],\n            center: new OpenLayers.LonLat(0, 0),\n            zoom: 0\n        });\n\n        function getRotation(layer) {\n            // grid starts at bottom left and goes up\n            var g0 = layer.features[0].geometry;\n            var g1 = layer.features[1].geometry;\n            // subtract 90 to get rotation of grid\n            return Math.atan2(g1.y - g0.y, g1.x - g0.x) * (180 / Math.PI) - 90;\n        }\n        \n        t.eq(layer.rotation, 0, \"0 rotation\");\n        t.eq(getRotation(layer).toFixed(3), (0).toFixed(3), \"0 grid\")\n        \n        // rotate grid 25 degrees counter-clockwise\n        layer.setRotation(25);\n        t.eq(layer.rotation, 25, \"25 rotation\");\n        t.eq(getRotation(layer).toFixed(3), (25).toFixed(3), \"25 grid\");\n\n        // rotate grid 45 degrees clockwise\n        layer.setRotation(-45);\n        t.eq(layer.rotation, -45, \"-45 rotation\");\n        t.eq(getRotation(layer).toFixed(3), (-45).toFixed(3), \"-45 grid\");\n        \n        map.destroy();\n    }\n\n    function test_origin(t) {\n        t.plan(7);\n        \n        var layer = new OpenLayers.Layer.PointGrid({\n            isBaseLayer: true,\n            resolutions: [1],\n            maxExtent: new OpenLayers.Bounds(-100, -50, 100, 50),\n            dx: 10,\n            dy: 10,\n            ratio: 1\n        });\n        \n        var map = new OpenLayers.Map({\n            div: \"map\",\n            layers: [layer],\n            center: new OpenLayers.LonLat(0, 0),\n            zoom: 0\n        });\n\n        var origin = layer.getOrigin();\n        t.ok(map.getExtent().getCenterLonLat().equals(origin), \"default is center of map extent\");\n        \n        var g0 = layer.features[0].geometry;\n        \n        t.eq((g0.x - origin.lon) % layer.dx, 0, \"a) lattice aligned with origin x\");\n        t.eq((g0.y - origin.lat) % layer.dy, 0, \"a) lattice aligned with origin y\");\n        \n        // set origin\n        layer.setOrigin(new OpenLayers.LonLat(-5, 12));\n        origin = layer.getOrigin();\n        t.eq(origin.lon, -5, \"-5 origin x\");\n        t.eq(origin.lat, 12, \"12 origin y\");\n\n        g0 = layer.features[0].geometry;        \n        t.eq((g0.x - origin.lon) % layer.dx, 0, \"b) lattice aligned with origin x\");\n        t.eq((g0.y - origin.lat) % layer.dy, 0, \"b) lattice aligned with origin y\");\n\n        map.destroy();\n    }\n\n    function test_zoom(t) {\n        t.plan(2);\n        \n        var layer = new OpenLayers.Layer.PointGrid({\n            isBaseLayer: true,\n            resolutions: [2, 1],\n            maxExtent: new OpenLayers.Bounds(-200, -100, 200, 100),\n            dx: 20,\n            dy: 20,\n            ratio: 1\n        });\n        \n        var map = new OpenLayers.Map({\n            div: \"map\",\n            layers: [layer],\n            center: new OpenLayers.LonLat(0, 0),\n            zoom: 1,\n            zoomMethod: null\n        });\n        \n        t.eq(layer.features.length, 50, \"50 features at zoom 1\");\n        \n        map.zoomTo(0);\n        t.eq(layer.features.length, 200, \"200 features at zoom 0\")\n\n        map.destroy();\n    }\n\n\n</script>\n</head>\n<body>\n<div id=\"map\" style=\"width:200px;height:100px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/PointTrack.html",
    "content": "<html>\n<head>\n<script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n  \n    var name = \"PointTrack Layer\";\n\n    function test_Layer_PointTrack_constructor(t) {\n        t.plan(2);\n\n        var layer = new OpenLayers.Layer.PointTrack(name);\n        t.ok(layer instanceof OpenLayers.Layer.PointTrack, \"new OpenLayers.Layer.PointTrack returns correct object\" );\n        t.ok(layer.addNodes, \"layer has an addNodes method\");\n\n    }\n    \n    function test_Layer_PointTrack_addNodes(t) {\n        t.plan(11);\n    \n        var layer = new OpenLayers.Layer.PointTrack(name,\n                {dataFrom: OpenLayers.Layer.PointTrack.dataFrom.TARGET_NODE});\n\n        var point1 = new OpenLayers.Geometry.Point(-111.04, 45.68);\n        var sourceNode = new OpenLayers.Feature.Vector(point1);\n        var point2 = new OpenLayers.Geometry.Point(-112.34, 45.67);\n        var targetNode = new OpenLayers.Feature.Vector(point2, {foo: \"bar\"});\n        layer.addNodes([sourceNode, targetNode]);\n        \n        t.eq(layer.features.length, 1, \"OpenLayers.Layer.PointTrack.addNodes creates one feature from two vector point features\");\n        t.eq(layer.features[0].geometry.CLASS_NAME, \"OpenLayers.Geometry.LineString\", \"The created feature has a LineString geometry\");\n        var geometry = layer.features[0].geometry;\n        t.eq(geometry.components[0].x, -111.04, \"The x of the first point of the line equals the x of the first point added to the layer\");\n        t.eq(geometry.components[1].y, 45.67, \"The y of the second point of the line equals the y of the second point added to the layer\");\n        t.eq(layer.features[0].attributes.foo, \"bar\", \"OpenLayers.Layer.PointTrack.addNodes assigns the attributes of the target node correctly\");\n        \n        layer.dataFrom = OpenLayers.Layer.PointTrack.dataFrom.SOURCE_NODE;\n\n        point1 = new OpenLayers.Geometry.Point(-123.54, 45.67);\n        sourceNode = new OpenLayers.Feature.Vector(point1, {foo: \"bar\"});\n        point2 = new OpenLayers.Geometry.Point(-123.21, 45.32);\n        targetNode = new OpenLayers.Feature.Vector(point2);\n        layer.addNodes([sourceNode, targetNode]);\n\n        t.eq(layer.features.length, 2, \"added another two points, so the layer now has two features\");\n        t.eq(layer.features[1].attributes.foo, \"bar\", \"OpenLayers.Layer.PointTrack.addNodes assigns the attributes of the source node correctly\");\n\n        point1 = new OpenLayers.LonLat(-123.58, 45.69);\n        sourceNode = new OpenLayers.Feature(null, point1);\n        point2 = new OpenLayers.LonLat(-123.25, 45.37);\n        targetNode = new OpenLayers.Feature(null, point2);\n        sourceNode.data = {foo: \"bar\"};\n        layer.addNodes([sourceNode, targetNode]);\n\n        t.eq(layer.features.length, 3, \"added another two points, this time from features, so the layer now has two features\");\n        t.eq(layer.features[2].geometry.components[0].x, -123.58, \"The x of the first point of the line equals the x of the first point added to the layer\");\n        t.eq(layer.features[2].geometry.components[1].y, 45.37, \"The y of the second point of the line equals the x of the second point added to the layer\");\n        t.eq(layer.features[2].data, sourceNode.data, \"OpenLayers.Layer.PointTrack.addNodes assigns the data of the source node correctly\");\n\n    }\n\n    function test_Layer_PointTrack_destroy (t) {\n        t.plan(3);    \n        layer = new OpenLayers.Layer.PointTrack(name);\n        var map = new OpenLayers.Map('map');\n        map.addLayer(layer);\n        t.eq(layer.map.layers.length, 1, \"layer added to the map successfully\");\n        layer.destroy();\n        t.eq(layer.map, null, \"layer.map is null after destroy\");\n        t.ok(!layer.renderer, \"layer.renderer is falsey after destroy\");\n    }\n\n\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/SphericalMercator.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    function test_SphericalMercator_forwardMercator(t) {\n        t.plan(12);\n        var arctic = OpenLayers.Layer.SphericalMercator.forwardMercator(0, 85);\n        var antarctic = OpenLayers.Layer.SphericalMercator.forwardMercator(0, -85);\n        var hawaii = OpenLayers.Layer.SphericalMercator.forwardMercator(-180, 0);\n        var phillipines = OpenLayers.Layer.SphericalMercator.forwardMercator(180, 0);\n        var ne = OpenLayers.Layer.SphericalMercator.forwardMercator(180, 90);\n        var sw = OpenLayers.Layer.SphericalMercator.forwardMercator(-180, -90);\n        \n        t.eq(arctic.lon, 0, \"Arctic longitude is correct\");\n        t.eq(Math.round(arctic.lat), 19971869, \"Arctic latitude is correct\");\n        \n        t.eq(antarctic.lon, 0, \"Antarctic longitude is correct\");\n        t.eq(Math.round(antarctic.lat), -19971869, \"Antarctic latitude is correct\");\n        \n        t.eq(Math.round(hawaii.lat), 0, \"Hawaiian lat is correct\");\n        t.eq(hawaii.lon, -20037508.34, \"Hawaiian lon is correct\");\n        \n        t.eq(Math.round(phillipines.lat), 0, \"Phillipines lat is correct\");\n        t.eq(phillipines.lon, 20037508.340, \"Phillipines lon is correct\");\n       \n        // be kind and stay within the world instead of having +/- infinity lat\n        t.ok(ne.lat, 20037508.34, \"NE lat is correct\");\n        t.eq(ne.lon, 20037508.34, \"NE lon is correct\");\n        \n        t.eq(sw.lat, -20037508.34, \"SW lat is correct\");\n        t.eq(sw.lon, -20037508.34, \"SW lon is correct\");\n    } \n    \n    function test_sphericalMercator_inverseMercator(t) {\n        t.plan(4);\n        var sw =  OpenLayers.Layer.SphericalMercator.inverseMercator(-20037508.34,  -20037508.34);\n        var ne =  OpenLayers.Layer.SphericalMercator.inverseMercator(20037508.34,  20037508.34);\n        t.eq(sw.lon, -180, \"Southwest lon correct\");\n        t.eq(ne.lon, 180, \"Northeast lon correct\");\n        \n        t.eq(sw.lat.toFixed(10), \"-85.0511287798\", \"Southwest lat correct\");\n        t.eq(ne.lat.toFixed(10), \"85.0511287798\", \"Northeast lat correct\");\n    }\n\n    function strToFixed(str, dig) { \n        if(dig == undefined) { \n            dig = 5; \n        } \n        return str.replace(/(\\d+\\.\\d+)/g, function(match) { \n            return parseFloat(match).toFixed(dig); \n        }); \n    } \n \n    function test_SphericalMercator_to4326(t) { \n        t.plan(1);\n        var point = new OpenLayers.Geometry.Point(1113195, 2273031);\n        point.transform(\"EPSG:900913\", \"EPSG:4326\");\n\n        t.eq(strToFixed(point.toString()), \n             strToFixed(\"POINT(10.000000828446318 20.000000618997227)\"), \n             \"point transforms from Spherical Mercator to EPSG:4326\"); \n    }\n    \n    function test_SphericalMercator_addTransform(t) {\n        // this class should add two methods to the\n        // OpenLayers.Projection.transforms object\n        t.plan(4);\n        var wgs84 = OpenLayers.Projection.transforms[\"EPSG:4326\"];\n        t.ok(wgs84 instanceof Object, \"EPSG:4326 exists in table\");\n        \n        var smerc = OpenLayers.Projection.transforms[\"EPSG:900913\"];\n        t.ok(smerc instanceof Object, \"EPSG:900913 exists in table\");\n        \n        t.ok(typeof(wgs84[\"EPSG:900913\"]) === \"function\",\n             \"from EPSG:4326 to EPSG:900913 correctly defined\");\n        t.ok(typeof(smerc[\"EPSG:4326\"]) === \"function\",\n             \"from EPSG:900913 to EPSG:4326 correctly defined\");\n    }\n    \n    function test_equivalence(t) {\n\n        // list of equivalent codes for web mercator\n        var codes = [\"EPSG:900913\", \"EPSG:3857\", \"EPSG:102113\", \"EPSG:102100\"];\n        var len = codes.length;\n        \n        t.plan(len + (len * len));\n\n        var ggPoint = new OpenLayers.Geometry.Point(10, 20);\n        var smPoint = new OpenLayers.Geometry.Point(1113195, 2273031);\n        \n        var gg = new OpenLayers.Projection(\"EPSG:4326\");\n        \n        var i, proj, forward, inverse, other, j, equiv;\n        for (i=0, len=codes.length; i<len; ++i) {\n            proj = new OpenLayers.Projection(codes[i]);\n            \n            // confirm that forward/inverse work\n            forward = ggPoint.clone().transform(gg, proj);\n            t.eq(\n                strToFixed(forward.toString()), \n                strToFixed(\"POINT(1113194.9077777779 2273030.9266712805)\"), \n                \"transforms from EPSG:4326 to \" + proj\n            );\n            inverse = smPoint.clone().transform(proj, gg);\n            t.eq(\n                strToFixed(inverse.toString()), \n                strToFixed(\"POINT(10.000000828446318 20.000000618997227)\"), \n                \"transforms from \" + proj + \" to EPSG:4326\"\n            ); \n            \n            // confirm that null transform works\n            for (j=i+1; j<len; ++j) {\n                other = new OpenLayers.Projection(codes[j]);\n                equiv = ggPoint.clone().transform(proj, other);\n                t.ok(proj.equals(other),  proj + \" and \" + other + \" are equivalent\");\n                t.ok(ggPoint.equals(equiv), \"transform from \" + proj + \" to \" + other + \" preserves geometry\");                \n            }\n        }\n\n    }\n    \n  </script> \n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/TMS.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var layer; \n\n    var name = 'Test Layer';\n    var url = \"http://labs.metacarta.com/wms-c/Basic.py/\";\n    var options = {'layername':'basic', 'type':'png'}; \n\n\n    function test_Layer_TMS_constructor (t) {\n        t.plan( 1 );\n                       \n        layer = new OpenLayers.Layer.TMS(name, url, options);\n        t.ok( layer instanceof OpenLayers.Layer.TMS, \"returns OpenLayers.Layer.TMS object\" );\n    }\n\n\n\n    function test_Layer_TMS_clearTiles (t) {\n        t.plan( 1 );\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.TMS(name, url, options);\n        map.addLayer(layer);\n\n        map.setCenter(new OpenLayers.LonLat(0,0));\n\n        //grab a reference to one of the tiles\n        var tile = layer.grid[0][0];        \n\n        layer.clearGrid();\n\n        t.ok( layer.grid != null, \"layer.grid does not get nullified\" );\n        map.destroy();\n    }\n\n\n    function test_Layer_TMS_getTMSBounds(t) {\n        t.plan( 1 );\n\n        layer = new OpenLayers.Layer.TMS(name, url, options);\n\n        var bl = { bounds: new OpenLayers.Bounds(1,2,2,3)};\n        var tr = { bounds: new OpenLayers.Bounds(2,3,3,4)};\n        layer.grid = [ [6, tr], \n                       [bl, 7]];\n\n        var bounds = layer.getTilesBounds();\n    \n        var testBounds = new OpenLayers.Bounds(1,2,3,4);\n        \n        t.ok( bounds.equals(testBounds), \"getTMSBounds() returns correct bounds\");\n        \n        layer.grid = null;\n    }\n\n    function test_Layer_TMS_getResolution(t) {\n        t.plan( 1 );\n\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.TMS(name, url, options);\n        map.addLayer(layer);\n\n        map.zoom = 5;\n\n        t.eq( layer.getResolution(), 0.0439453125, \"getResolution() returns correct value\");\n        map.destroy();\n    }\n\n    function test_Layer_TMS_getZoomForExtent(t) {\n        t.plan( 2 );\n        var bounds, zoom;\n\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.TMS(name, url, options);\n        map.addLayer(layer);\n\n        bounds = new OpenLayers.Bounds(10,10,12,12);\n        zoom = layer.getZoomForExtent(bounds);\n\n        t.eq( zoom, 8, \"getZoomForExtent() returns correct value\");\n\n        bounds = new OpenLayers.Bounds(10,10,100,100);\n        zoom = layer.getZoomForExtent(bounds);\n\n        t.eq( zoom, 2, \"getZoomForExtent() returns correct value\");\n        map.destroy();\n    }   \n\n\n    /** THIS WOULD BE WHERE THE TESTS WOULD GO FOR \n     *     \n     *    -moveTo\n     *    -insertColumn\n     *    -insertRow\n    \n    function 07_Layer_TMS_moveTo(t) {\n    }\n\n    function 08_Layer_TMS_insertColumn(t) {\n    }\n\n    function 09_Layer_TMS_insertRow(t) {\n    }\n\n     * \n     */\n    function test_Layer_TMS_getURL(t) {\n\n        t.plan(3);\n        \n        var map = new OpenLayers.Map('map', options);\n        var options = {'layername':'basic', 'type':'png'}; \n        layer = new OpenLayers.Layer.TMS(name, url, options);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 9);\n        var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125));\n        t.eq(tileurl, \"http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/261/192.png\", \"Tile URL is correct\");\n    \n        var layer2 = layer.clone();\n        layer2.serviceVersion = \"1.2.3\";\n        map.addLayer(layer2);\n        tileurl = layer2.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125));\n        t.eq(tileurl, \"http://labs.metacarta.com/wms-c/Basic.py/1.2.3/basic/9/261/192.png\", \"TMS serviceVersion is correct\");\n\n        layer.url = [\"http://tilecache1/\", \"http://tilecache2/\", \"http://tilecache3/\"];\n        tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125));\n        t.eq(tileurl, \"http://tilecache1/1.0.0/basic/9/261/192.png\", \"Tile URL is deterministic\");\n        map.destroy();\n    }\n    function test_Layer_TMS_Rounding(t) {\n        t.plan(1);\n            m = new OpenLayers.Map(\"map\", {'maxExtent':new OpenLayers.Bounds(-122.6579,37.4901,-122.0738,37.8795)});\n            layer = new OpenLayers.Layer.TMS( \"TMS\", \n                    \"http://labs.metacarta.com/wms-c/Basic.py/\", {layername: 'basic', type:'png', resolutions:[0.000634956337608418], buffer: 2} );\n            m.addLayer(layer);\n            m.zoomToMaxExtent();\n            t.eq(layer.getURL(layer.grid[3][3].bounds), \"http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/0/1/1.png\", \"TMS tiles around rounded properly.\");\n        m.destroy();\n    }        \n            \n    function test_Layer_TMS_serverResolutions(t) {\n        t.plan(2);\n        \n        var map = new OpenLayers.Map('map', {\n            resolutions: [13,11]\n        });\n\n        var layer = new OpenLayers.Layer.TMS('tc layer', '', options);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 1);\n\n        var tileurl = layer.getURL(new OpenLayers.Bounds(0,0,0,0));\n        var level = parseInt(tileurl.split('/')[2]);\n        t.eq(map.getZoom(), level, \"Tile zoom level is correct without serverResolutions\");\n\n        layer.serverResolutions = [14,13,12,11,10];\n        tileurl = layer.getURL(new OpenLayers.Bounds(0,0,0,0));\n        level = parseInt(tileurl.split('/')[2]);\n        var res = map.getResolution();\n        var gotLevel = OpenLayers.Util.indexOf(layer.serverResolutions, res);\n        t.eq(gotLevel, level, \"Tile zoom level is correct with serverResolutions\");\n        \n        map.destroy();\n    }\n\n    function test_zoomOffset(t) {\n\n        t.plan(2);\n        \n        var offset, zoom;\n        \n        // test offset of 2\n        offset = 2;\n        zoom = 3;\n\n        var map = new OpenLayers.Map({\n            div: \"map\"\n        });\n        var layer = new OpenLayers.Layer.TMS(\"TMS\", \"\", {\n            layername: \"basic\",\n            type: \"png\",\n            zoomOffset: offset\n        });\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0, 0), zoom);\n\n        var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125));\n        t.eq(parseInt(tileurl.split(\"/\")[2]), zoom + offset, \"correct level for offset 2\");\n\n        map.destroy();\n\n        // test offset of -1\n        offset = -1;\n        zoom = 3;\n        \n        var map = new OpenLayers.Map({\n            div: \"map\"\n        });\n        var layer = new OpenLayers.Layer.TMS(\"TMS\", \"\", {\n            layername: \"basic\",\n            type: \"png\",\n            zoomOffset: offset\n        });\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0, 0), zoom);\n\n        var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125));\n        t.eq(parseInt(tileurl.split(\"/\")[2]), zoom + offset, \"correct level for offset -1\");\n\n        map.destroy();\n    }\n\n    function test_Layer_TMS_setMap(t) {\n\n        t.plan(3);\n        \n        var map = new OpenLayers.Map('map', options);\n        layer = new OpenLayers.Layer.TMS(name, url, options);\n\n        t.eq(layer.tileOrigin, null, \"Tile origin starts out null\");\n        layer.setMap(map);\n        \n        t.eq(layer.tileOrigin.lat, -90, \"lat is -90\");\n        t.eq(layer.tileOrigin.lon, -180, \"lon is -180\");\n        map.destroy();\n    }\n\n    function test_Layer_TMS_destroy (t) {\n\n        t.plan( 3 );\n\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.TMS(name, url, options);\n        map.addLayer(layer);\n        layer.destroy();\n        t.eq( layer.grid, null, \"layer.grid is null after destroy\" );\n        t.eq( layer.tileSize, null, \"layer.tileSize is null after destroy\" );\n\n\n    //test with tile creation\n        layer = new OpenLayers.Layer.TMS(name, url, options);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 5);\n        //grab a reference to one of the tiles\n        var tile = layer.grid[0][0];        \n\n        layer.destroy();\n\n        t.ok( layer.grid == null, \"tiles appropriately destroyed\");\n        map.destroy();\n    }\n    \n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px;\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/Text.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var isMSIE = (navigator.userAgent.indexOf(\"MSIE\") > -1);\n    var layer; \n\n    var datafile  = \"./data_Layer_Text_textfile.txt\";\n    var datafile2 = \"./data_Layer_Text_textfile_2.txt\";\n    var datafile_overflow = \"./data_Layer_Text_textfile_overflow.txt\";\n\n    // if this test is running in IE, different rules apply\n    if (isMSIE) {\n        datafile = \".\" + datafile;\n        datafile2 = \".\" + datafile2;\n        datafile_overflow = \".\" + datafile_overflow;\n    }\n\n    function test_Layer_Text_constructor (t) {\n        t.plan( 5 );\n        \n        layer = new OpenLayers.Layer.Text('Test Layer', { location: datafile });\n        layer.loadText();\n        t.ok( layer instanceof OpenLayers.Layer.Text, \"new OpenLayers.Layer.Text returns object\" );\n        t.eq( layer.location, datafile, \"layer.location is correct\" );\n        var markers;\n        t.delay_call( 1, function() {  \n            t.eq( layer.markers.length, 2, \"marker length is correct\" );\n            var ll = new OpenLayers.LonLat(20, 10);\n            t.ok( layer.markers[0].lonlat.equals(ll), \"first marker is correct\" );\n            t.eq( layer.markers[0].icon.url, 'http://boston.openguides.org/markers/ORANGE.png', \"icon\" );\n        } );\n    }\n    function test_Layer_Text_draw (t) { \n//        t.plan(5);\n        t.plan( 2 );\n        layer = new OpenLayers.Layer.Text('Test Layer', { location: datafile });\n        t.ok( layer instanceof OpenLayers.Layer.Text, \"new OpenLayers.Layer.Text returns object\" );\n        var map = new OpenLayers.Map('map');\n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(baseLayer);\n        map.addLayer(layer);\n        t.eq( map.layers[1].name, layer.name, \"Layer added to map okay\" );\n        t.delay_call( 1, function() { \n          map.setCenter(new OpenLayers.LonLat(0,0),0);\n\n/*\n            if (!isMozilla)\n                t.ok( true, \"skipping element test outside of Mozilla\");\n            else\n              t.ok( map.layers[0].div.firstChild instanceof HTMLImageElement, \"Marker added to div\" )\n\n          t.eq( map.layers[0].div.firstChild.style.top, \"219px\", \"Marker top set correctly\" )\n          t.eq( map.layers[0].div.firstChild.style.left, \"273px\", \"Marker left set correctly\" )\n*/\n        });;\n    }\n\n    function test_Layer_Text_moveTo(t) {\n        t.plan(16);\n        \n        temp = OpenLayers.Layer.Markers.prototype.moveTo;\n\n        g_Bounds = {};\n        g_ZoomChanged = {};\n        g_Minor = {};\n        var args = [g_Bounds, g_ZoomChanged, g_Minor];\n\n        OpenLayers.Layer.Markers.prototype.moveTo = \n            function(bounds, zoomChanged, minor) {\n                t.ok(bounds == g_Bounds, \"correct bounds passed to Markers superclass\");\n                t.ok(zoomChanged == g_ZoomChanged, \"correct zoomChanged passed to Markers superclass\");\n                t.ok(minor == g_Minor, \"correct minor passed to Markers superclass\");\n            }\n\n        var layer = {\n            'loadText': function() { g_TextLoaded = true; }\n        };\n\n        //visibility true, loaded true\n        layer.visibility = true;\n        layer.loaded = true;\n        g_TextLoaded = false;\n        OpenLayers.Layer.Text.prototype.moveTo.apply(layer, args);\n        t.ok(g_TextLoaded == false, \"text not loaded when visibility true, loaded true\");\n\n        //visibility true, loaded false\n        layer.visibility = true;\n        layer.loaded = false;\n        g_TextLoaded = false;\n        OpenLayers.Layer.Text.prototype.moveTo.apply(layer, args);\n        t.ok(g_TextLoaded == true, \"text is loaded when visibility true, loaded false\");\n\n        //visibility false, loaded true\n        layer.visibility = false;\n        layer.loaded = true;\n        g_TextLoaded = false;\n        OpenLayers.Layer.Text.prototype.moveTo.apply(layer, args);\n        t.ok(g_TextLoaded == false, \"text not loaded when visibility false, loaded true\");\n\n        //visibility false, loaded false\n        layer.visibility = false;\n        layer.loaded = false;\n        g_TextLoaded = false;\n        OpenLayers.Layer.Text.prototype.moveTo.apply(layer, args);\n        t.ok(g_TextLoaded == false, \"text not loaded when visibility false, loaded false\");\n\n        OpenLayers.Layer.Markers.prototype.moveTo = temp;\n    }\n\n\n\n    function test_Layer_Text_events (t) {\n        t.plan( 5 );    \n        layer = new OpenLayers.Layer.Text('Test Layer', { location: datafile2 });\n        var map = new OpenLayers.Map('map');\n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(baseLayer);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0),0);\n        var event = {};\n        t.delay_call( 1, function() {  \n          t.ok(layer.markers[0].events, \"First marker has an events object\");\n          t.eq(layer.markers[0].events.listeners['click'].length, 1, \"Marker events has one object\");\n          layer.markers[0].events.triggerEvent('click', event);\n          t.eq(map.popups.length, 1, \"Popup opened correctly\");\n          layer.markers[1].events.triggerEvent('click', event);\n          t.eq(map.popups.length, 1, \"1st popup gone, 2nd Popup opened correctly\");\n          //Safari 3 separates style overflow into overflow-x and overflow-y\n          var prop = (OpenLayers.BROWSER_NAME == 'safari') ? 'overflowX' : 'overflow';\n          t.eq(map.popups[0].contentDiv.style[prop],\"auto\", \"default Popup overflow correct\");\n        });\n    }\n    function test_Layer_Text_overflow (t) {\n        t.plan( 4 );    \n        layer = new OpenLayers.Layer.Text('Test Layer', { location: datafile_overflow });\n        var map = new OpenLayers.Map('map');\n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(baseLayer);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0),0);\n        var event = {};\n        t.delay_call( 1, function() {  \n          layer.markers[0].events.triggerEvent('click', event);\n          t.eq(map.popups.length, 1, \"Popup opened correctly\");\n          //Safari 3 separates style overflow into overflow-x and overflow-y\n          var prop = (OpenLayers.BROWSER_NAME == 'safari') ? 'overflowX' : 'overflow';\n          t.eq(map.popups[0].contentDiv.style[prop],\"auto\", \"Popup overflow read from file\");\n          layer.markers[1].events.triggerEvent('click', event);\n          t.eq(map.popups.length, 1, \"1st popup gone, 2nd Popup opened correctly\");\n          //Safari 3 separates style overflow into overflow-x and overflow-y\n          var prop = (OpenLayers.BROWSER_NAME == 'safari') ? 'overflowX' : 'overflow';\n          t.eq(map.popups[0].contentDiv.style[prop],\"hidden\", \"Popup overflow read from file\");\n        });\n    }\n    function test_Layer_Text_events_nopopups (t) {\n        t.plan( 4 );    \n        layer = new OpenLayers.Layer.Text('Test Layer', { location: datafile });\n        var map = new OpenLayers.Map('map');\n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(baseLayer);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0),0);\n        var event = {};\n        t.delay_call( 1, function() {  \n          t.ok(layer.markers[0].events, \"First marker has an events object\");\n          t.eq(layer.markers[0].events.listeners['click'], undefined, \"Marker events has no object\");\n          layer.markers[0].events.triggerEvent('click', event);\n          t.eq(map.popups.length, 0, \"no popup on first marker\");\n          layer.markers[1].events.triggerEvent('click', event);\n          t.eq(map.popups.length, 0, \"no popup on second marker\");\n        });\n    }\n    function test_Layer_Text_loadend_Event(t) {\n        t.plan(2);\n        layer = new OpenLayers.Layer.Text('Test Layer', {location:datafile});\n        t.delay_call(2, function() { \n            layer.events.register('loadend', layer, function() { \n                t.ok(true, \"Loadend event fired\"); \n            });\n            layer.parseData({\n                'responseText':''\n            });\n            t.ok(true, \"Parsing data didn't fail\"); \n        });\n    }\n\n    function test_Layer_Text_destroy (t) {\n        t.plan( 1 );    \n        layer = new OpenLayers.Layer.Text('Test Layer');\n        var map = new OpenLayers.Map('map');\n        map.addLayer(layer);\n        layer.destroy();\n        t.eq( layer.map, null, \"layer.map is null after destroy\" );\n    }\n\n  </script>\n</head>\n<body>\n  <div id=\"map\" style=\"width:500px; height:500px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/TileCache.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n\n\n    function test_Layer_TileCache_constructor (t) {\n        t.plan( 1 );\n\n        var name = 'Test Layer';\n        var url = \"http://labs.metacarta.com/wms-c/Basic.py/\";\n        var layername = \"basic\";\n        var options = {'type':'png'}; \n\n        var layer = new OpenLayers.Layer.TileCache(name, url, layername, options);\n        t.ok( layer instanceof OpenLayers.Layer.TileCache, \"returns OpenLayers.Layer.TileCache object\" );\n        layer.destroy();\n    }\n\n    function test_Layer_TileCache_clone(t) {\n        t.plan(3);\n\n        var name = 'Test Layer';\n        var url = \"http://labs.metacarta.com/wms-c/Basic.py/\";\n        var layername = \"basic\";\n        var options = {'type':'png'}; \n        var layer = new OpenLayers.Layer.TileCache(name, url, layername, options);\n\n        var clone = layer.clone();\n        t.eq(layer.name, clone.name, \"clone() correctly copy the 'name' property\");\n        t.eq(layer.url, clone.url, \"clone() correctly copy the 'url' property\");\n        t.eq(layer.layername, clone.layername, \"clone() correctly copy the 'layername' property\");\n        clone.destroy();\n        layer.destroy();\n    }\n\n    function test_Layer_TileCache_clearTiles (t) {\n        t.plan( 1 );\n        var name = 'Test Layer';\n        var url = \"http://labs.metacarta.com/wms-c/Basic.py/\";\n        var layername = \"basic\";\n        var options = {'type':'png'}; \n        var layer = new OpenLayers.Layer.TileCache(name, url, layername, options);\n        var map = new OpenLayers.Map('map');\n        map.addLayer(layer);\n\n        map.setCenter(new OpenLayers.LonLat(0,0));\n\n        //grab a reference to one of the tiles\n        var tile = layer.grid[0][0];        \n\n        layer.clearGrid();\n\n        t.ok( layer.grid != null, \"layer.grid does not get nullified\" );\n        map.destroy();\n    }\n\n\n    function test_Layer_TileCache_getTileCacheBounds(t) {\n        t.plan( 1 );\n\n        var name = 'Test Layer';\n        var url = \"http://labs.metacarta.com/wms-c/Basic.py/\";\n        var layername = \"basic\";\n        var options = {'type':'png'}; \n        var layer = new OpenLayers.Layer.TileCache(name, url, layername, options);\n\n        var bl = { bounds: new OpenLayers.Bounds(1,2,2,3)};\n        var tr = { bounds: new OpenLayers.Bounds(2,3,3,4)};\n        layer.grid = [ [6, tr], \n                       [bl, 7]];\n\n        var bounds = layer.getTilesBounds();\n    \n        var testBounds = new OpenLayers.Bounds(1,2,3,4);\n        \n        t.ok( bounds.equals(testBounds), \"getTileCacheBounds() returns correct bounds\")\n\n    }\n\n    function test_Layer_TileCache_getResolution(t) {\n        t.plan( 1 );\n\n        var name = 'Test Layer';\n        var url = \"http://labs.metacarta.com/wms-c/Basic.py/\";\n        var layername = \"basic\";\n        var options = {'type':'png', maxResolution: 180/256}; \n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.TileCache(name, url, layername, options);\n        map.addLayer(layer);\n\n        map.zoom = 5;\n\n        t.eq( layer.getResolution(), 0.02197265625, \"getResolution() returns correct value\");\n        map.destroy();\n    }\n\n    function test_Layer_TileCache_getZoomForExtent(t) {\n        t.plan( 2 );\n        var bounds, zoom;\n\n        var name = 'Test Layer';\n        var url = \"http://labs.metacarta.com/wms-c/Basic.py/\";\n        var layername = \"basic\";\n        var options = {'type':'png', maxResolution: 180/256}; \n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.TileCache(name, url, layername, options);\n        map.addLayer(layer);\n\n        bounds = new OpenLayers.Bounds(10,10,12,12);\n        zoom = layer.getZoomForExtent(bounds);\n\n        t.eq( zoom, 7, \"getZoomForExtent() returns correct value\");\n\n        bounds = new OpenLayers.Bounds(10,10,100,100);\n        zoom = layer.getZoomForExtent(bounds);\n\n        t.eq( zoom, 1, \"getZoomForExtent() returns correct value\");\n        map.destroy();\n    }   \n\n    function test_Layer_TileCache_getURL(t) {\n\n        t.plan(2);\n        \n        var map = new OpenLayers.Map('map');\n        var name = 'Test Layer';\n        var url = \"http://labs.metacarta.com/wms-c/Basic.py/\";\n        var layername = \"basic\";\n        var options = {'layername':'basic', 'format':'image/jpg', maxResolution: 180/256}; \n        var layer = new OpenLayers.Layer.TileCache(name, url, layername, options);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 9);\n        var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125));\n        t.eq(tileurl, \"http://labs.metacarta.com/wms-c/Basic.py/basic/09/000/000/522/000/000/384.jpeg\", \"Tile URL is correct\");\n\n        layer.url = [\"http://tilecache1/\", \"http://tilecache2/\", \"http://tilecache3/\"];\n        tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125));\n        t.eq(tileurl, \"http://tilecache2/basic/09/000/000/522/000/000/384.jpeg\", \"Tile URL is deterministic\");\n        map.destroy();\n    }\n\n    function test_Layer_TileCache_serverResolutions(t) {\n        t.plan(2);\n        \n        var map = new OpenLayers.Map('map', {\n            resolutions: [13,11]\n        });\n\n        var layer = new OpenLayers.Layer.TileCache('tc layer', '', 'basic');\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 1);\n\n        var tileurl = layer.getURL(new OpenLayers.Bounds(0,0,0,0));\n        var level = parseInt(tileurl.split('/')[2]);\n        t.eq(map.getZoom(), level, \"Tile zoom level is correct without serverResolutions\");\n\n        layer.serverResolutions = [14,13,12,11,10];\n        tileurl = layer.getURL(new OpenLayers.Bounds(0,0,0,0));\n        level = parseInt(tileurl.split('/')[2]);\n        var gotLevel = OpenLayers.Util.indexOf(layer.serverResolutions, map.getResolution());\n        t.eq(gotLevel, level, \"Tile zoom level is correct with serverResolutions\");\n        \n        map.destroy();\n    }\n\n    function test_Layer_TileCache_destroy (t) {\n\n        t.plan( 3 );\n\n        var name = 'Test Layer';\n        var url = \"http://labs.metacarta.com/wms-c/Basic.py/\";\n        var layername = \"basic\";\n        var options = {'layername':'basic', 'format':'image/jpg', maxResolution: 180/256}; \n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.TileCache(name, url, layername, options);\n        map.addLayer(layer);\n        layer.destroy();\n        t.eq( layer.grid, null, \"layer.grid is null after destroy\" );\n        t.eq( layer.tileSize, null, \"layer.tileSize is null after destroy\" );\n\n\n    //test with tile creation\n        layer = new OpenLayers.Layer.TileCache(name, url, options);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 5);\n        //grab a reference to one of the tiles\n        var tile = layer.grid[0][0];        \n\n        layer.destroy();\n\n        t.ok( layer.grid == null, \"tiles appropriately destroyed\");\n        map.destroy();\n    }\n    \n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/UTFGrid.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n  <script>\n      /**\n      * Because browsers that implement requestAnimationFrame may not execute\n      * animation functions while a window is not displayed (e.g. in a hidden\n      * iframe as in these tests), we mask the native implementations here.  The\n      * native requestAnimationFrame functionality is tested in Util.html and\n      * in PanZoom.html (where a popup is opened before panning).  The panTo tests\n      * here will test the fallback setTimeout implementation for animation.\n      */\n      window.requestAnimationFrame = \n          window.webkitRequestAnimationFrame =\n          window.mozRequestAnimationFrame =\n          window.oRequestAnimationFrame =\n          window.msRequestAnimationFrame = null;\n  </script>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    var map, layer;\n    function setUp() {\n        layer = new OpenLayers.Layer.UTFGrid({\n            url: \"../data/utfgrid/world_utfgrid/${z}/${x}/${y}.json\",\n            isBaseLayer: true, \n            utfgridResolution: 4\n        });\n        map = new OpenLayers.Map({\n            div: \"map\",\n            projection: \"EPSG:900913\",\n            layers: [layer],\n            center: [0, 0],\n            zoom: 1,\n            tileManager: null\n        });\n    }\n    \n    function tearDown() {\n        map.destroy();\n        map = null;\n        layer = null;\n    }\n\n    function test_constructor(t) {\n        t.plan(4);\n        \n        var layer = new OpenLayers.Layer.UTFGrid({\n            name: \"foo\",\n            url: \"path/to/tiles/${z}/${x}/${y}\",\n            utfgridResolution: 8\n        });\n        t.ok(layer instanceof OpenLayers.Layer.UTFGrid, \"utfgrid instance\");\n        t.eq(layer.name, \"foo\", \"layer name\");\n        t.eq(layer.url, \"path/to/tiles/${z}/${x}/${y}\", \"layer url\");\n        t.eq(layer.utfgridResolution, 8, \"layer utfgridResolution\");\n\n        layer.destroy();\n\n    }\n\n    function test_createBackBuffer(t) {\n      t.plan(1);\n      setUp();\n\n      var got;\n      try {\n        got = layer.createBackBuffer();\n      } catch (e) {\n        got = e;\n      } finally {\n        tearDown();\n      }\n      t.eq(got, undefined, \"createBackBuffer returns undefined\");\n    }\n    \n    function test_clone(t) {\n        t.plan(3);\n        setUp();\n        \n        var clone = layer.clone();\n        t.ok(layer instanceof OpenLayers.Layer.UTFGrid, \"utfgrid instance\");\n        t.eq(layer.url, \"../data/utfgrid/world_utfgrid/${z}/${x}/${y}.json\", \"layer url\");\n        t.eq(layer.utfgridResolution, 4, \"layer utfgridResolution\");\n        clone.destroy();\n        \n        tearDown();\n    }\n    \n    function test_getFeatureInfo(t) {\n        t.plan(2);\n        setUp();\n                \n        // wait for tile loading to finish\n        t.delay_call(0.5, function() {\n            var loc = new OpenLayers.LonLat(-110, 45).transform(\"EPSG:4326\", \"EPSG:900913\");\n            var info = layer.getFeatureInfo(loc);\n            \n            t.eq(info.id, \"207\", \"feature id\");\n            t.eq(info.data, {POP2005: 299846449, NAME: \"United States\"}, \"feature data\");\n            \n            tearDown();\n        });\n        \n    }\n\n    function test_getFeatureId(t) {\n        t.plan(2);\n        setUp();\n\n        // wait for tile loading to finish\n        t.delay_call(0.5, function() {\n            var ca = new OpenLayers.LonLat(-110, 55).transform(\"EPSG:4326\", \"EPSG:900913\");\n            var ru = new OpenLayers.LonLat(90, 75).transform(\"EPSG:4326\", \"EPSG:900913\");\n            \n            t.eq(layer.getFeatureId(ca), \"24\", \"feature id for ca\");\n            t.eq(layer.getFeatureId(ru), \"245\", \"feature id for ru\");\n            \n            tearDown();\n        });\n        \n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"height: 256px; width: 512px\"></div>\n</body>\n</html>\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/Vector/RootContainer.html",
    "content": "<html>\n<head>\n  <script src=\"../../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var layer, map; \n\n    function test_RootContainer_collectResetRoots(t) {\n        \n        map = new OpenLayers.Map(\"map\");\n        var layer1 = new OpenLayers.Layer.Vector(\"layer1\");\n        var layer2 = new OpenLayers.Layer.Vector(\"layer2\");\n        layer = new OpenLayers.Layer.Vector.RootContainer(\"layer_1_2\", {\n            layers: [layer1, layer2]\n        });\n        \n        // we cannot test this with a renderer that does not hava a rendererRoot\n        var plan = layer.renderer.rendererRoot ? 4 : 0;\n        t.plan(plan);\n        if(plan == 0) {\n            return;\n        }\n\n        var numRoots = layer.renderer.rendererRoot.childNodes.length;\n\n        // addLayers will call setMap() for layer, which will call collectRoots()\n        map.addLayers([layer1, layer2, layer]);\n        t.eq(layer.renderer.rendererRoot.childNodes.length, numRoots * 3, \"layer has correct number of renderer roots\");        \n        t.eq(layer1.renderer.rendererRoot.childNodes.length, 0, \"layer1 has no own renderer root\");\n        \n        layer.resetRoots();\n        t.eq(layer.renderer.rendererRoot.childNodes.length, numRoots, \"roots removed from container\");\n        t.eq(layer1.renderer.rendererRoot.childNodes.length, numRoots, \"root re-added to original layer\");\n    }\n    \n    function test_RootContainer_getFeatureFromEvent(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var layer1 = new OpenLayers.Layer.Vector(\"layer1\");\n        var layer2 = new OpenLayers.Layer.Vector(\"layer2\");\n        layer = new OpenLayers.Layer.Vector.RootContainer(\"layer_1_2\", {\n            layers: [layer1, layer2]\n        });\n        map.addLayers([layer1, layer2, layer]);\n        var feature1 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0,1));\n        var feature2 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,0));\n        layer1.addFeatures(feature1);\n        layer2.addFeatures(feature2);\n        t.eq(layer.getFeatureFromEvent({\n            srcElement: {\n                _featureId: feature1.id\n            }\n        }).id, feature1.id, \"feature from layer1 found\");\n        t.eq(layer.getFeatureFromEvent({srcElement: {\n            _featureId: feature2.id\n        }}).id, feature2.id, \"feature from layer2 found\");\n    }\n\n  </script>\n</head>\n<body>\n  <div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/Vector.html",
    "content": "<html>\n<head>\n<script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    var name = \"Vector Layer\";\n    \n    function test_Layer_Vector_constructor(t) {\n        t.plan(5);\n\n        var options = {protocol: new OpenLayers.Protocol(), \n                       strategies: [new OpenLayers.Strategy(), new OpenLayers.Strategy()]}\n        var layer = new OpenLayers.Layer.Vector(name, options);\n\n        t.ok(layer instanceof OpenLayers.Layer.Vector, \"new OpenLayers.Layer.Vector returns correct object\" );\n        t.eq(layer.name, name, \"layer name is correctly set\");\n        t.ok(layer.renderer.CLASS_NAME, \"layer has a renderer\");\n        \n        t.ok((layer.name == layer.strategies[0].layer.name) &&\n             (layer.strategies[0].layer.name == layer.strategies[1].layer.name), \n             \"setLayer was called on strategies\");\n\n       options.renderers = [OpenLayers.Renderer.SVG, OpenLayers.Renderer.VML, OpenLayers.Renderer.Canvas]; \n       layer.destroy(); \n       layer = new OpenLayers.Layer.Vector(name, options); \n       t.ok(layer.renderer.CLASS_NAME, \"layer has a renderer when providing a function\"); \n       layer.destroy(); \n    }\n\n    function test_Layer_Vector_assignRenderer(t) { \n        t.plan(2);\n \n        // create a dummy class in the global name space \n        My = { \n            Custom: { \n                Renderer: { \n                    Supported: OpenLayers.Class(OpenLayers.Renderer, { \n                        supported: OpenLayers.Function.True, \n                        CLASS_NAME: 'My.Custom.Renderer.Supported' \n                    }), \n                    NotSupported: OpenLayers.Class(OpenLayers.Renderer, { \n                        supported: OpenLayers.Function.False, \n                        CLASS_NAME: 'My.Custom.Renderer.NotSupported' \n                    }) \n                } \n            } \n        }; \n        var layer = new OpenLayers.Layer.Vector('vector', { \n            renderers: [My.Custom.Renderer.NotSupported, \n                My.Custom.Renderer.Supported, \n                OpenLayers.Renderer.Canvas] \n        }); \n        t.eq(layer.renderer.CLASS_NAME, 'My.Custom.Renderer.Supported',  \n            'layer has a valid renderer'); \n \n        var layer = new OpenLayers.Layer.Vector('vector', { \n            renderers: ['SVG', 'VML', 'Canvas', My.Custom.Renderer.Supported] \n        }); \n        t.ok(layer.renderer.CLASS_NAME != 'My.Custom.Renderer.Supported',  \n            'renderers can be strings as well'); \n    }\n\n    function test_Layer_Vector_refresh(t) {\n        t.plan(4);\n\n        var obj = {\"an\": \"object\"};\n\n        var log;\n        var layer = new OpenLayers.Layer.Vector(name, {\n            eventListeners: {\n                refresh: function(o) {\n                    log.obj = o;\n                }\n            }\n        });\n        inRange = false;\n        layer.calculateInRange = function() {\n            return inRange;\n        };\n\n        log = {};\n        inRange = false;\n        layer.visibility = false;\n        layer.refresh(obj);\n        t.eq(log.obj, undefined, \"[false, false] refresh not triggered\");\n\n        log = {};\n        inRange = true;\n        layer.visibility = false;\n        layer.refresh(obj);\n        t.eq(log.obj, undefined, \"[true, false] refresh not triggered\");\n\n        log = {};\n        inRange = false;\n        layer.visibility = true;\n        layer.refresh(obj);\n        t.eq(log.obj, undefined, \"[false, true] refresh not triggered\");\n\n        log = {};\n        inRange = true;\n        layer.visibility = true;\n        layer.refresh(obj);\n        t.ok(log.obj === obj, \"[true, true] refresh triggered with correct arg\");\n    }\n    \n    function test_Layer_Vector_addFeatures(t) {\n        t.plan(8);\n    \n        var layer = new OpenLayers.Layer.Vector(name);\n\n        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);\n        var pointFeature = new OpenLayers.Feature.Vector(point);\n\n        layer.preFeatureInsert = function(feature) {\n            t.ok(feature == pointFeature, \"OpenLayers.Layer.Vector.addFeatures calls preFeatureInsert with the right arg\");\n        };\n        layer.onFeatureInsert = function(feature) {\n            t.ok(feature == pointFeature, \"OpenLayers.Layer.Vector.addFeatures calls onFeatureInsert with the right arg\");\n        };\n        layer.events.register('beforefeatureadded', null, function(obj) {\n            t.ok(pointFeature == obj.feature, \"OpenLayers.Layer.Vector.addFeatures triggers beforefeatureadded with correct feature passed to callback\");\n        });\n        layer.events.register('featureadded', null, function(obj) {\n            t.ok(pointFeature == obj.feature, \"OpenLayers.Layer.Vector.addFeatures triggers featureadded with correct feature passed to callback\");\n        });\n        layer.events.register('featuresadded', null, function(obj) {\n            t.ok(pointFeature == obj.features[0], \"OpenLayers.Layer.Vector.addFeatures triggers featuresadded with correct features passed to callback\");\n        });\n\n        layer.addFeatures([pointFeature]);\n        \n        t.eq(layer.features.length, 1, \"OpenLayers.Layer.Vector.addFeatures adds something to the array\");\n        t.ok(layer.features[0] == pointFeature, \"OpenLayers.Layer.Vector.addFeatures returns an array of features\");\n\n        layer.preFeatureInsert = function(feature) {\n            t.fail(\"OpenLayers.Layer.Vector.addFeatures calls preFeatureInsert while it must not\");\n        };\n        layer.onFeatureInsert = function(feature) {\n            t.fail(\"OpenLayers.Layer.Vector.addFeatures calls onFeatureInsert while it must not\");\n        };\n        layer.events.register('beforefeatureadded', null, function(obj) {\n            t.fail(\"OpenLayers.Layer.Vector.addFeatures triggers beforefeatureadded while it must not\");\n        });\n        layer.events.register('featureadded', null, function(obj) {\n            t.fail(\"OpenLayers.Layer.Vector.addFeatures triggers featureadded while it must not\");\n        });\n        layer.events.register('featuresadded', null, function(obj) {\n            t.fail(\"OpenLayers.Layer.Vector.addFeatures triggers featuresadded while it must not\");\n        });\n\n        layer.addFeatures([pointFeature], {silent: true});\n\n        var extent = layer.getDataExtent();\n        t.eq(extent.toBBOX(), \"-111.04,45.68,-111.04,45.68\", \"extent from getDataExtent is correct\");\n    }\n\n    function test_Layer_Vector_getFeature(t) {\n        t.plan(13);\n\n        var layer = new OpenLayers.Layer.Vector(name);\n        var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(-111.04, 45.68));\n\n        t.ok(layer.getFeatureById(feature.id) == null,\n             \"OpenLayers.Layer.Vector.getFeatureById returns null while the layer is empty\");\n        t.ok(layer.getFeatureByFid('my_fid') == null,\n             \"OpenLayers.Layer.Vector.getFeatureByFid returns null while the layer is empty\");\n\n        layer.addFeatures([feature]);\n\n        t.ok(layer.getFeatureByFid('my_fid') == null,\n             \"OpenLayers.Layer.Vector.getFeatureByFid returns null on unset feature fid\");\n\n        feature.fid = 'my_fid';\n\n        t.ok(layer.getFeatureById(feature.id) == feature,\n             \"OpenLayers.Layer.Vector.getFeatureById returns the correct feature\");\n        t.ok(layer.getFeatureByFid(feature.fid) == feature,\n             \"OpenLayers.Layer.Vector.getFeatureByFid returns the correct feature\");\n        t.ok(layer.getFeatureById('some_id_that_does_not_exist') == null,\n             \"OpenLayers.Layer.Vector.getFeatureById returns null on non-existing feature id\");\n        t.ok(layer.getFeatureByFid('some_fid_that_does_not_exist') == null,\n             \"OpenLayers.Layer.Vector.getFeatureByFid returns null on non-existing feature fid\");\n        t.ok(layer.getFeatureById(feature.fid) == null,\n             \"OpenLayers.Layer.Vector.getFeatureById ignores the feature fid\");\n        t.ok(layer.getFeatureByFid(feature.id) == null,\n             \"OpenLayers.Layer.Vector.getFeatureByFid ignores the feature id\");\n\n        t.ok(layer.getFeatureBy('id', feature.id) == feature,\n             \"OpenLayers.Layer.Vector.getFeatureBy('id', ...) works like getFeatureById on existing feature id\");\n        t.ok(layer.getFeatureBy('id', 'some_id_that_does_not_exist') == null,\n             \"OpenLayers.Layer.Vector.getFeatureBy('id', ...) works like getFeatureById on non-existing feature id\");\n        t.ok(layer.getFeatureBy('fid', feature.fid) == feature,\n             \"OpenLayers.Layer.Vector.getFeatureBy('fid', ...) works like getFeatureByFid on existing feature fid\");\n        t.ok(layer.getFeatureBy('fid', 'some_fid_that_does_not_exist') == null,\n             \"OpenLayers.Layer.Vector.getFeatureBy('fid', ...) works like getFeatureByFid on non-existing feature fid\");\n    }\n    \n    function test_Layer_Vector_getFeaturesByAttribute(t) {\n        t.plan( 9 );\n        // setup layer\n        var layer = new OpenLayers.Layer.Vector(name);\n        \n        // feature_1\n        var geometry_1 = new OpenLayers.Geometry.Point(-28.63, 153.64);\n        var attributes_1 = {\n            humpty: 'dumpty',\n            clazz: 1\n        };\n        var feature_1 = new OpenLayers.Feature.Vector(geometry_1, attributes_1);\n        feature_1.fid = 'f_01'; // to identify later\n        \n        // feature_2\n        var geometry_2 = new OpenLayers.Geometry.Point(-27.48, 153.05);\n        var attributes_2 = {\n            // this feature has attribute humpty === undefined\n            clazz: '1'\n        };\n        var feature_2 = new OpenLayers.Feature.Vector(geometry_2, attributes_2);\n        feature_2.fid = 'f_02'; // to identify later\n        \n        // feature_3\n        var geometry_3 = new OpenLayers.Geometry.Point(-33.74, 150.3);\n        var attributes_3 = {\n            humpty: 'foobar',\n            clazz: 1\n        };\n        var feature_3 = new OpenLayers.Feature.Vector(geometry_3, attributes_3);\n        feature_3.fid = 'f_03'; // to identify later\n        \n        // Tests\n        \n        // don't find anything... no features added\n        // 1 test\n        t.ok(layer.getFeaturesByAttribute('humpty', 'dumpty').length === 0,\n             \"OpenLayers.Layer.Vector.getFeaturesByAttribute returns an empty array while the layer is empty\");\n        \n        layer.addFeatures([feature_1, feature_2, feature_3]);\n        \n        // simple use case: find 1 feature with an attribute and matching value\n        // 2 tests\n        var dumptyResults = layer.getFeaturesByAttribute('humpty', 'dumpty');\n        t.ok(dumptyResults.length === 1,\n             \"OpenLayers.Layer.Vector.getFeaturesByAttribute returns an array with one feature for attribute 'humpty' with value 'dumpty'\");\n        t.ok(dumptyResults[0].fid === 'f_01',\n             \"OpenLayers.Layer.Vector.getFeaturesByAttribute returns the correct feature with attribute 'humpty' set to 'dumpty'\");\n        \n        // simple use case: find 1 feature with an attribute and matching value\n        //                  and respect data types\n        // 2 tests\n        var strOneResults = layer.getFeaturesByAttribute('clazz', '1');\n        t.ok(strOneResults.length === 1,\n             \"OpenLayers.Layer.Vector.getFeaturesByAttribute returns an array with one feature for attribute 'clazz' with value '1' (a string)\");\n        t.ok(strOneResults[0].fid === 'f_02',\n             \"OpenLayers.Layer.Vector.getFeaturesByAttribute returns the correct feature with attribute 'clazz' set to the string '1'\");\n        \n        // simple use case: find 2 features with an attribute and matching value\n        //                  and respect data types\n        // 2 tests    \n        var numOneResults = layer.getFeaturesByAttribute('clazz', 1);\n        t.ok(numOneResults.length === 2,\n             \"OpenLayers.Layer.Vector.getFeaturesByAttribute returns an array with two features for attribute 'clazz' with value 1 (a number)\");\n        var bothFound = !!((numOneResults[0].fid === 'f_01' && numOneResults[1].fid === 'f_03') || (numOneResults[0].fid === 'f_03' && numOneResults[1].fid === 'f_01')); \n        t.ok(bothFound,\n             \"OpenLayers.Layer.Vector.getFeaturesByAttribute returns the correct features with attribute 'clazz' set to the number 1\");\n        \n        // advanced use case: find the 1 feature, that has an attribute not set\n        var undefined;\n        var humptyNotSet = layer.getFeaturesByAttribute('humpty', undefined);\n        t.ok(humptyNotSet.length === 1,\n             \"OpenLayers.Layer.Vector.getFeaturesByAttribute can be used to find features that have certain attributes not set\");\n        t.ok(humptyNotSet[0].fid === 'f_02',\n             \"OpenLayers.Layer.Vector.getFeaturesByAttribute found the correct featuren that has a certain attribute not set\");\n    }\n\n    function test_Layer_Vector_getDataExtent(t) {\n        t.plan(1);\n        var layer = new OpenLayers.Layer.Vector(name);\n\n        var point = new OpenLayers.Geometry.Point(-111.04, 45.68);\n        var pointFeature = new OpenLayers.Feature.Vector(point);\n        layer.addFeatures([pointFeature]);\n        var point = new OpenLayers.Geometry.Point(-111.04, 5.68);\n        var pointFeature = new OpenLayers.Feature.Vector(point);\n        layer.addFeatures([pointFeature]);\n        var extent = layer.getDataExtent();\n        t.ok(extent.toBBOX() != layer.features[0].geometry.getBounds().toBBOX(), \"extent from getDataExtent doesn't clobber first feature\");\n    }\n\n    function test_Layer_Vector_getDataExtentEmpty(t) {\n        t.plan(1);\n        var layer = new OpenLayers.Layer.Vector(name);\n        layer.addFeatures([new OpenLayers.Feature.Vector(null), new OpenLayers.Feature.Vector(null)]);\n        var extent = layer.getDataExtent();\n        t.eq(extent, null, \"We expect null to be returned if there are no features with a geometry\");\n    }\n\n    function test_Layer_Vector_removeFeatures(t) {\n        t.plan(17);\n    \n        var layer = new OpenLayers.Layer.Vector(name);\n        var features, log;\n\n        var point1 = new OpenLayers.Geometry.Point(-111.04, 45.68);\n        var pointFeature1 = new OpenLayers.Feature.Vector(point1);\n        var point2 = new OpenLayers.Geometry.Point(-111.14, 45.78);\n        var pointFeature2 = new OpenLayers.Feature.Vector(point2);\n\n        // 1 test\n        layer.addFeatures([pointFeature1, pointFeature2]);\n        features = layer.removeFeatures([pointFeature1]);\n        t.ok(layer.features.length == 1, \"OpenLayers.Layer.Vector.removeFeatures removes a feature from the features array\");\n\n        // 1 test\n        layer.addFeatures([pointFeature1.clone(), pointFeature2.clone()]);\n        layer.selectedFeatures.push(layer.features[0]); \n        layer.removeFeatures(layer.features[0]);\n        t.eq(layer.selectedFeatures, [], \"Remove features removes selected features\");\n\n        // 1 test\n        features = layer.removeFeatures(layer.features);\n        t.ok(layer.features.length == 0,\n             \"OpenLayers.Layer.Vector.removeFeatures(layer.features) removes all feature from the features array\");\n\n        // 4 tests\n        log = [];\n        layer.addFeatures([pointFeature1, pointFeature2]);\n        layer.events.register(\"featuresremoved\", null, function(obj) {\n            log.push(obj);\n        });\n        layer.removeFeatures(layer.features);\n        t.eq(log.length, 1,\n             \"\\\"featuresremoved\\\" triggered once [0]\");\n        t.eq(log[0].features.length, 2,\n             \"\\\"featuresremoved\\\" listener is passed two features [0]\");\n        t.ok(log[0].features[0] == pointFeature1,\n             \"\\\"featuresremoved\\\" listener is passed the correct feature at index 0 [0]\");\n        t.ok(log[0].features[1] == pointFeature2,\n             \"\\\"featuresremoved\\\" listener is passed the correct feature at index 1 [0]\");\n        layer.events.remove(\"featuresremoved\");\n\n        // 4 tests\n        log = [];\n        layer.addFeatures([\n            pointFeature1, pointFeature2,\n            pointFeature1.clone(), pointFeature2.clone()\n        ]);\n        layer.selectedFeatures.push(pointFeature1);\n        layer.selectedFeatures.push(pointFeature2);\n        layer.events.register(\"featuresremoved\", null, function(obj) {\n            log.push(obj);\n        });\n        layer.removeFeatures(layer.selectedFeatures);\n        t.eq(log.length, 1,\n             \"\\\"featuresremoved\\\" triggered once [1]\");\n        t.eq(log[0].features.length, 2,\n             \"\\\"featuresremoved\\\" listener is passed two features [1]\");\n        t.ok(log[0].features[0] == pointFeature1,\n             \"\\\"featuresremoved\\\" listener is passed the correct feature at index 0 [1]\");\n        t.ok(log[0].features[1] == pointFeature2,\n             \"\\\"featuresremoved\\\" listener is passed the correct feature at index 1 [1]\");\n        layer.events.remove(\"featuresremoved\");\n        layer.removeFeatures(layer.features);\n\n        // 6 tests\n        layer.events.register('beforefeatureremoved', null, function(obj) {\n            t.ok(pointFeature1 == obj.feature,\n                 \"OpenLayers.Layer.Vector.removeFeatures triggers beforefeatureremoved with correct feature passed to callback\");\n        });\n        layer.events.register('featureremoved', null, function(obj) {\n            t.ok(pointFeature1 == obj.feature,\n                 \"OpenLayers.Layer.Vector.removeFeatures triggers featureremoved with correct feature passed to callback\");\n        });\n        layer.events.register('featuresremoved', null, function(obj) {\n            t.ok(pointFeature1 == obj.features[0],\n                 \"OpenLayers.Layer.Vector.removeFeatures triggers featuresremoved with correct features passed to callback\");\n        });\n        layer.addFeatures([pointFeature1]);\n        layer.removeFeatures([pointFeature1]);\n        layer.addFeatures([pointFeature1]);\n        layer.removeFeatures(layer.features);\n\n        // 0 test\n        layer.events.register('beforefeatureremoved', null, function(obj) {\n            t.fail(\"OpenLayers.Layer.Vector.removeFeatures triggers beforefeatureremoved while it must not\");\n        });\n        layer.events.register('featureremoved', null, function(obj) {\n            t.fail(\"OpenLayers.Layer.Vector.removeFeatures triggers featureremoved while it must not\");\n        });\n        layer.events.register('featuresremoved', null, function(obj) {\n            t.fail(\"OpenLayers.Layer.Vector.removeFeatures triggers featuresremoved while it must not\");\n        });\n        layer.addFeatures([pointFeature1]);\n        layer.removeFeatures([pointFeature1], {silent: true});\n     }\n    \n    function test_Layer_Vector_drawFeature(t) {\n        t.plan(7);\n        var layer = new OpenLayers.Layer.Vector(\"Test Layer\", {isBaseLayer: true});\n        var map = new OpenLayers.Map('map', {\n            maxExtent: new OpenLayers.Bounds(-100, -100, 100, 100)\n        });\n        map.addLayer(layer);\n        var geometry = new OpenLayers.Geometry.Point(10, 10);\n        var feature = new OpenLayers.Feature.Vector(geometry);\n        \n        var f, s;\n        \n        // Bogus layer renderer needs some methods\n        // for functional tests.\n        layer.drawn = true;\n        layer.renderer = {\n            drawFeature: function(feature, style) {\n                f = feature;\n                s = style;\n            },\n            root: document.createElement(\"div\"),\n            destroy: function() { },\n            eraseFeatures: function() {},\n            setExtent: function() {}\n        };\n        \n\n        layer.drawFeature(feature);\n        t.ok(geometry.equals(f.geometry),\n             \"calls layer.renderer.drawFeature() with feature.geometry\");\n        \n        feature.style = {foo: \"bar\"};\n        layer.drawFeature(feature);\n        t.eq(feature.style, s,\n             \"calls layer.renderer.drawFeature() with feature.style\");\n        \n        feature.style = null;\n        layer.style = {foo: \"bar\"};\n        layer.drawFeature(feature);\n        t.eq(layer.style.foo, s.foo,\n             \"given null feature style, uses layer style\");\n\n        feature.style = {foo1: \"bar1\"};\n        layer.style = {foo2: \"bar2\"};\n        var customStyle = {foo: \"bar\"};\n        layer.drawFeature(feature, customStyle);\n        t.eq(customStyle.foo, s.foo,\n             \"given a custom style, renders with that\");\n        \n        // the real renderer's drawFeature method is tested in Renderer.html\n        layer.renderer.drawFeature = function(feature) {\n            return(feature.geometry.getBounds().intersectsBounds(map.getExtent()));\n        }\n        // reset the drawn to null as if the layer had never been rendered\n        layer.drawn = null;\n        \n        layer.drawFeature(feature);\n        t.ok(true, \"Trying to draw a feature on an not drawn layer doesn't throw any error.\");\n        \n        layer.addFeatures([feature]);\n        \n        map.setCenter(new OpenLayers.Bounds(0, 0, 0, 0), 6);\n        t.ok(layer.unrenderedFeatures[feature.id], \"Did not render feature outside the viewport.\");\n        map.panTo(new OpenLayers.LonLat(10, 10));\n        t.ok(!layer.unrenderedFeatures[feature.id], \"Rendered feature inside the viewport.\");\n        \n        layer.features = [];\n    }\n    \n    function test_deleted_state(t) {\n        t.plan(9);\n        \n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector();\n        map.addLayer(layer);\n        var feature = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(10, 10)\n        );\n        var log;\n        layer.renderer = {\n            drawFeature: function(f, s) {\n                log = {\n                    feature: f,\n                    style: s\n                };\n            },\n            destroy: function() {}\n        };\n        \n        // draw feature with no state\n        layer.drawn = true;\n        layer.drawFeature(feature);\n        t.ok(log.feature === feature, \"[no state] drawFeature called with correct feature\");\n        t.ok(log.style.display !== \"none\", \"[no state] drawFeature called with style display not none\");\n\n        // draw feature with delete style\n        feature.state = OpenLayers.State.DELETE;\n        layer.drawFeature(feature);\n        t.ok(log.feature === feature, \"[delete] drawFeature called with correct feature\");\n        t.eq(log.style.display, \"none\", \"[delete] drawFeature called with style display none\");\n\n        // undelete the feature and redraw\n        delete feature.state;\n        delete feature.renderIntent;\n        layer.drawFeature(feature);\n        t.ok(log.feature === feature, \"[undelete] drawFeature called with correct feature\");\n        t.ok(log.style.display !== \"none\", \"[undelete] drawFeature called with style display not none\");\n        \n        // change deleted style\n        layer.styleMap.styles[\"delete\"] = new OpenLayers.Style({fillOpacity: 0.1});\n\n        // draw feature with delete style\n        feature.state = OpenLayers.State.DELETE;\n        layer.drawFeature(feature);\n        t.ok(log.feature === feature, \"[draw deleted] drawFeature called with correct feature\");\n        t.ok(log.style.display !== \"none\", \"[draw deleted] drawFeature called with style display not none\");\n        t.eq(log.style.fillOpacity, 0.1,\"[draw deleted] drawFeature called with correct fill opacity\");\n\n        \n    }\n    \n    function test_Layer_Vector_eraseFeatures(t) {\n        t.plan(2);\n        var layer = new OpenLayers.Layer.Vector(\"Test Layer\");\n        var map = new OpenLayers.Map('map');\n        map.addLayer(layer);\n        var geometry = new OpenLayers.Geometry.Point(10, 10);\n        var feature = new OpenLayers.Feature.Vector(geometry);\n        \n        var f;\n        layer.renderer = {\n            eraseFeatures: function(features) {\n                f = features[0];\n            },\n            destroy: function() { }\n        };\n\n        layer.eraseFeatures([feature]);\n        t.ok(f, \"calls layer.renderer.eraseFeatures\");\n        t.ok(geometry.equals(f.geometry),\n             \"calls layer.renderer.eraseFeatures() given an array of features\");\n    }\n\n    function test_Layer_Vector_destroyFeatures (t) {\n        t.plan(8);\n        var layer = new OpenLayers.Layer.Vector(name);\n        var map = new OpenLayers.Map('map');\n        map.addLayer(layer);\n        var features = [], i;\n        for (i = 0; i < 5; i++) {\n            features.push(new OpenLayers.Feature.Vector(\n                          new OpenLayers.Geometry.Point(0,0)));\n        }\n        layer.addFeatures(features);\n        t.eq(layer.features.length, 5, \"addFeatures adds 5 features\");\n        layer.selectedFeatures.push(features[0]); \n        layer.destroyFeatures();\n        t.eq(layer.features.length, 0, \"destroyFeatures triggers removal\");\n        t.eq(layer.selectedFeatures, [], \"Destroy features removes selected features\");\n        var allDestroyed = true;\n        for (i = 0; i < 5; i++) {\n            if(features[i].geometry) {\n                allDestroyed = false;\n            }\n        }\n        t.ok(allDestroyed, \"destroyFeatures actually destroys features\");\n        features = [];\n        for (i = 0; i < 5; i++) {\n            features.push(new OpenLayers.Feature.Vector(\n                          new OpenLayers.Geometry.Point(0,0)));\n        }\n        layer.addFeatures(features);\n        layer.selectedFeatures.push(features[0]);\n        layer.selectedFeatures.push(features[1]);\n        layer.destroyFeatures([features[0], features[1]]);\n        t.eq(layer.features.length, 3, \"destroyFeatures removes appropriate features\");\n        t.eq(layer.selectedFeatures, [], \"destroyFeatures removes appropriate selected features\");\n        t.eq(features[0].geometry, null, \"destroyFeatures destroys feature 0\");\n        t.eq(features[1].geometry, null, \"destroyFeatures destroys feature 1\");\n    }\n\n    function test_Layer_Vector_destroy (t) {\n        t.plan(6);    \n\n        var options = {protocol: new OpenLayers.Protocol(), \n                       strategies: [new OpenLayers.Strategy(), new OpenLayers.Strategy()]}\n        var layer = new OpenLayers.Layer.Vector(name, options);\n        var map = new OpenLayers.Map('map');\n        map.addLayer(layer);\n        layer.destroy();\n        t.eq(layer.map, null, \"layer.map is null after destroy\");\n        t.ok(!layer.renderer, \"layer.renderer is falsey\");\n        var err;\n        try {\n            layer.getFeatureFromEvent({target: \"map\"});\n        } catch (ex) {\n            err = ex;\n        }\n        t.ok(err, \"Error thrown when calling getFeatureFromEvent on destroyed layer\");\n\n        t.eq(layer.protocol, null, \"layer.protocol is null after destroy\");\n        t.eq(layer.strategies, null, \"layer.strategies is null after destroy\");\n        \n        // test that we can call layer.destroy a second time without trouble\n        try {\n            layer.destroy();\n            layer.destroy();\n            t.ok(true, \"layer.destroy called twice without any issues\");\n        } catch(err) {\n            t.fail(\"calling layer.destroy twice triggers exception: \" + err + \" in \" + err.fileName + \" line \" + err.lineNumber);\n        }\n        \n    }\n    \n    function test_Layer_Vector_clone(t) {\n        t.plan(5);\n        var original = new OpenLayers.Layer.Vector(name, {dummyOption: \"foo\"});\n        original.addFeatures([new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1,2), {foo: \"bar\"})]);\n        var clone = original.clone();\n        t.ok(clone instanceof OpenLayers.Layer.Vector, \"clone is an instance of OpenLayers.Layer.Vector\");\n        t.ok(clone.name, original.name, \"clone has the same name as the original\");\n        t.ok(clone.features[0] != original.features[0], \"clone's feature does not equal the original's feature\");\n        t.eq(clone.features[0].attributes.foo, original.features[0].attributes.foo, \"clone's feature has the same attributes as the original's feature\");\n        t.eq(clone.dummyOption, original.dummyOption, \"clone's dummyOption equals the original's dummy option\");\n    }\n\n    function test_Layer_Vector_externalGraphic(t) {\n        t.plan(11);\n        var layer = new OpenLayers.Layer.Vector(\"Test Layer\", {isBaseLayer: true});\n        var renderer = layer.renderer;\n        var map = new OpenLayers.Map('map');\n        map.addLayers([layer]);\n\n        var geometryX = 10;\n        var geometryY = 10;\n        var geometry = new OpenLayers.Geometry.Point(geometryX, geometryY);\n        var feature = new OpenLayers.Feature.Vector(geometry);\n\n        map.zoomToMaxExtent();\n\n        var customStyle1 = new Object({\n                externalGraphic: 'test.png',\n                pointRadius: 10\n        });\n        var customStyle2 = new Object({\n                externalGraphic: 'test.png',\n                graphicWidth: 12\n        });\n        var customStyle3 = new Object({\n                externalGraphic: 'test.png',\n                graphicHeight: 14\n        });\n        var customStyle4 = new Object({\n                externalGraphic: 'test.png',\n                graphicWidth: 24,\n                graphicHeight: 16\n        });\n        var customStyle5 = new Object({\n                externalGraphic: 'test.png',\n                graphicWidth: 24,\n                graphicOpacity: 1\n        });\n        var customStyle6 = new Object({\n                externalGraphic: 'test.png',\n                graphicWidth: 24,\n                graphicHeight: 16,\n                graphicXOffset: -24,\n                graphicYOffset: -16\n        });\n               \n        var root = renderer.vectorRoot;\n        if (layer.renderer.CLASS_NAME == 'OpenLayers.Renderer.SVG') {\n                feature.style = customStyle1;\n                layer.drawFeature(feature);\n                t.eq(root.firstChild.getAttributeNS(null, 'width'),\n                             (2*customStyle1.pointRadius).toString(),\n                             \"given a pointRadius, width equals 2*pointRadius\");\n                t.eq(root.firstChild.getAttributeNS(null, 'height'),\n                             (2*customStyle1.pointRadius).toString(),\n                             \"given a pointRadius, height equals 2*pointRadius\");\n                feature.style = customStyle2;\n                layer.drawFeature(feature);\n                t.eq(root.firstChild.getAttributeNS(null, 'width'),\n                             root.firstChild.getAttributeNS(null, 'height'),\n                             \"given a graphicWidth, width equals height\");\n                t.eq(root.firstChild.getAttributeNS(null, 'width'),\n                             customStyle2.graphicWidth.toString(),\n                             \"width is set correctly\");\n                feature.style = customStyle3;\n                layer.drawFeature(feature);\n                t.eq(root.firstChild.getAttributeNS(null, 'height'),\n                             root.firstChild.getAttributeNS(null, 'width'),\n                             \"given a graphicHeight, height equals width\");\n                t.eq(root.firstChild.getAttributeNS(null, 'height'),\n                             customStyle3.graphicHeight.toString(),\n                             \"height is set correctly\");\n                feature.style = customStyle4;\n                layer.drawFeature(feature);\n                t.eq(root.firstChild.getAttributeNS(null, 'height'),\n                             customStyle4.graphicHeight.toString(),\n                             \"given graphicHeight and graphicWidth, both are set: height\");\n                t.eq(root.firstChild.getAttributeNS(null, 'width'),\n                             customStyle4.graphicWidth.toString(),\n                             \"given graphicHeight and graphicWidth, both are set: width\");\n                feature.style = customStyle5;\n                layer.drawFeature(feature);\n                // we use startsWith here as some browsers (at least Safari 3 and FireFox 4)\n                // do not append a semi-colon to the opacity string\n                t.ok(OpenLayers.String.startsWith(\n                            root.firstChild.getAttributeNS(null, 'style'),\n                            \"opacity: \" + customStyle5.graphicOpacity.toString()),\n                     \"graphicOpacity correctly set\");\n                feature.style = customStyle6;\n                layer.drawFeature(feature);\n                var x = geometryX / renderer.getResolution() + renderer.left;\n                var y = geometryY / renderer.getResolution() - renderer.top;\n                // SVG setStyle() gets x and y using getAttributeNS(), which returns\n                // a value with only 3 decimal digits. To mimic this we use toFixed(3) here\n                x = x.toFixed(3);\n                y = y.toFixed(3);\n                // toFixed() returns a string\n                x = parseFloat(x);\n                y = parseFloat(y);\n                t.eq(root.firstChild.getAttributeNS(null, 'x'),\n                        (x + customStyle6.graphicXOffset).toFixed().toString(),\n                        \"graphicXOffset correctly set\");\n                t.eq(root.firstChild.getAttributeNS(null, 'y'),\n                        (-y + customStyle6.graphicYOffset).toFixed().toString(),\n                        \"graphicYOffset correctly set\");\n        }\n        if (layer.renderer.CLASS_NAME == 'OpenLayers.Renderer.VML') {\n                feature.style = customStyle1;\n                layer.drawFeature(feature);\n                t.eq(root.firstChild.style.width,\n                             (2*customStyle1.pointRadius).toString()+'px',\n                             \"given a pointRadius, width equals 2*pointRadius\");\n                t.eq(root.firstChild.style.height,\n                             (2*customStyle1.pointRadius).toString()+'px',\n                             \"given a pointRadius, height equals 2*pointRadius\");\n                feature.style = customStyle2;\n                layer.drawFeature(feature);\n                t.eq(root.firstChild.style.width,\n                             root.firstChild.style.height,\n                             \"given a graphicWidth, width equals height\");\n                t.eq(root.firstChild.style.width,\n                             customStyle2.graphicWidth.toString()+'px',\n                             \"width is set correctly\");\n                feature.style = customStyle3;\n                layer.drawFeature(feature);\n                t.eq(root.firstChild.style.height,\n                             root.firstChild.style.width,\n                             \"given a graphicHeight, height equals width\");\n                t.eq(root.firstChild.style.height,\n                             customStyle3.graphicHeight.toString()+'px',\n                             \"height is set correctly\");\n                feature.style = customStyle4;\n                layer.drawFeature(feature);\n                var left = parseInt(root.firstChild.style.left);\n                var top = parseInt(root.firstChild.style.top);\n                t.eq(root.firstChild.style.height,\n                             customStyle4.graphicHeight.toString()+'px',\n                             \"given graphicHeight and graphicWidth, both are set: height\");\n                t.eq(root.firstChild.style.width,\n                             customStyle4.graphicWidth.toString()+'px',\n                             \"given graphicHeight and graphicWidth, both are set: width\");\n                feature.style = customStyle5;\n                layer.renderer.clear();\n                layer.drawFeature(feature);\n                var fill = root.firstChild.getElementsByTagName(\"v:fill\")[0];\n                var opacity;\n                if(fill) {\n                    opacity = fill.getAttribute('opacity');\n                }\n                if(opacity === undefined) {\n                    fill = root.firstChild.getElementsByTagName(\"fill\")[0];\n                    opacity = fill.getAttribute('opacity');\n                }\n                t.eq(opacity,\n                             customStyle5.graphicOpacity,\n                             \"graphicOpacity correctly set\"); \n                feature.style = customStyle6;\n                layer.drawFeature(feature);\n                var offsetLeft = parseInt(root.firstChild.style.left);\n                var offsetTop = parseInt(root.firstChild.style.top);\n                t.eq((offsetLeft-left)*2, customStyle6.graphicXOffset, \"graphicXOffset correctly set\");\n                t.eq((top-offsetTop)*2, customStyle6.graphicYOffset, \"graphicYOffset correctly set\");\n\n        }\n    }\n\n    function test_removeLayer_drawFeature(t) {\n        // test behaviour when features are redrawn while\n        // the layer has been removed from the map\n\n        t.plan(1);\n\n        // set up\n\n        var map, layer, feature;\n\n        map = new OpenLayers.Map(\"map\");\n        map.addLayer(new OpenLayers.Layer(\"base\", {isBaseLayer: true}));\n\n        layer = new OpenLayers.Layer.Vector(\"vector\");\n        map.addLayer(layer);\n\n        map.zoomToMaxExtent();\n\n        feature = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(1.0, 1.0));\n        layer.addFeatures(feature);\n\n        // test\n\n        map.removeLayer(layer);\n        layer.drawFeature(feature);\n        layer.drawFeature(feature);\n        map.addLayer(layer);\n\n        var count = 0, node;\n        while(node = document.getElementById(feature.geometry.id)) {\n            node.parentNode.removeChild(node);\n            count++;\n        }\n\n        t.eq(count, 1, \"one geometry added, one geometry removed\");\n\n        // tear down\n\n        map.destroy();\n    }\n\n    function test_vectorBeforeFeatureAddedVeto(t) {\n        t.plan( 4 );\n\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.Vector(\"\");\n        map.addLayer(layer);\n        var feature = new OpenLayers.Feature.Vector(new OpenLayers.Geometry(1.0, 1.0));\n        layer.addFeatures([feature]);\n\n        var addedFeatures = [];\n        var beforefeatureadded_veto = function(evt) { return false; };\n        layer.events.register(\"beforefeatureadded\", layer, beforefeatureadded_veto);\n        layer.events.register(\"featuresadded\", layer, function(evt) {\n            if (evt.features) {\n                for (var i = 0; i < evt.features.length; i++) {\n                    addedFeatures.push(evt.features[i]);\n                }\n            }\n        });\n\n        var blankFeatures = [\n            new OpenLayers.Feature.Vector(new OpenLayers.Geometry(1.0, 1.0)),\n            new OpenLayers.Feature.Vector(new OpenLayers.Geometry(1.0, 1.0))];\n        layer.addFeatures(blankFeatures);\n\n        t.eq(layer.features.length, 1,\n            \"features not added to layer after beforefeatureadded veto\");\n        t.eq(addedFeatures.length, 0,\n            \"no features sent to featuresadded on feature veto\");\n\n        addedFeatures = [];\n\n        layer.events.unregister(\"beforefeatureadded\", layer, beforefeatureadded_veto);\n        beforefeatureadded_veto = function(evt) { return true; };\n        layer.events.register(\"beforefeatureadded\", layer, beforefeatureadded_veto);\n\n        layer.addFeatures(blankFeatures);\n\n        t.eq(layer.features.length, 3,\n            \"features added to layer as expected\");\n        t.eq(addedFeatures.length, 2,\n            \"featuresadded event received expected number of features\");\n    }\n\n\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/WMS.html",
    "content": "<html>\n<head>\n    <script type=\"text/javascript\">var oldAlert = window.alert, gMess; window.alert = function(message) {gMess = message; return true;};</script>\n    <script src=\"http://maps.google.com/maps/api/js?v=3&amp;sensor=false\"></script>\n    <script type=\"text/javascript\">window.alert = oldAlert;</script>\n<script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    // turn off animation frame handling, so we can check img urls in tests\n    delete OpenLayers.Layer.Grid.prototype.queueTileDraw;\n\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var layer;\n\n    var name = 'Test Layer';\n    var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n    var params = { map: '/mapdata/vmap_wms.map',\n                   layers: 'basic',\n                   format: 'image/jpeg'};\n\n    function test_Layer_WMS_constructor (t) {\n        t.plan( 15 );\n\n        var trans_format = \"image/png\";\n        if (OpenLayers.Util.alphaHack()) { trans_format = \"image/gif\"; }\n\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.WMS(name, url, params);\n        t.ok( layer instanceof OpenLayers.Layer.WMS, \"new OpenLayers.Layer.WMS returns object\" );\n        t.eq( layer.url, \"http://octo.metacarta.com/cgi-bin/mapserv\", \"layer.url is correct (HTTPRequest inited)\" );\n        t.eq( layer.params.MAP, \"/mapdata/vmap_wms.map\", \"params passed in correctly uppercased\" );\n\n        t.eq( layer.params.SERVICE, \"WMS\", \"default params correclty uppercased and copied\");\n\n        t.eq(layer.isBaseLayer, true, \"no transparency setting, wms is baselayer\");\n\n        params.TRANSPARENT = \"true\";\n        var layer2 = new OpenLayers.Layer.WMS(name, url, params);\n        t.eq(layer2.isBaseLayer, false, \"transparency == 'true', wms is not baselayer\");\n\n        params.TRANSPARENT = \"TRUE\";\n        var layer3 = new OpenLayers.Layer.WMS(name, url, params);\n        t.eq(layer3.isBaseLayer, false, \"transparency == 'TRUE', wms is not baselayer\");\n        t.eq(layer3.params.FORMAT, trans_format, \"transparent = TRUE causes non-image/jpeg format\");\n\n        params.TRANSPARENT = \"TRuE\";\n        var layer4 = new OpenLayers.Layer.WMS(name, url, params);\n        t.eq(layer4.isBaseLayer, false, \"transparency == 'TRuE', wms is not baselayer\");\n        t.eq(layer4.params.FORMAT, trans_format, \"transparent = TRuE causes non-image/jpeg format\");\n\n        params.TRANSPARENT = true;\n        var layer5 = new OpenLayers.Layer.WMS(name, url, params);\n        t.eq(layer5.isBaseLayer, false, \"transparency == true, wms is not baselayer\");\n        t.eq(layer5.params.FORMAT, trans_format, \"transparent = true causes non-image/jpeg format\");\n\n        params.TRANSPARENT = false;\n        var layer6 = new OpenLayers.Layer.WMS(name, url, params);\n        t.eq(layer6.isBaseLayer, true, \"transparency == false, wms is baselayer\");\n\n        params.TRANSPARENT = true;\n        var layer7 = new OpenLayers.Layer.WMS(name, url, params, {noMagic: true});\n        t.eq(layer7.params.FORMAT, \"image/jpeg\", \"When using noMagic true image/jpeg will not be automagically switched to image/png or image/gif if transparent\");\n\n        params.TRANSPARENT = true;\n        var layer8 = new OpenLayers.Layer.WMS(name, url, params, {noMagic: true});\n        t.eq(layer8.isBaseLayer, true, \"When using noMagic then transparent means the wms layer is not automagically changed to not being a baselayer\");\n\n        params.TRANSPARENT = false;\n\n    }\n\n    function test_Layer_WMS_addtile (t) {\n        t.plan( 6 );\n\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.WMS(name, url, params);\n        var map = new OpenLayers.Map('map', {tileManager: null});\n        map.addLayer(layer);\n        var pixel = new OpenLayers.Pixel(5,6);\n        var tile = layer.addTile(new OpenLayers.Bounds(1,2,3,4), pixel);\n        tile.draw();\n\n        var img = tile.imgDiv;\n        var tParams = OpenLayers.Util.extend({},\n                        OpenLayers.Util.upperCaseObject(params));\n        tParams = OpenLayers.Util.extend(tParams, {\n            BBOX: [1,2,3,4],\n            WIDTH: \"256\", HEIGHT: \"256\"\n        });\n        t.eq( tile.url,\n             layer.getFullRequestString(tParams),\n             \"image src is created correctly via addtile\" );\n        t.eq( tile.getTile().style.top, \"6px\", \"image top is set correctly via addtile\" );\n        t.eq( tile.getTile().style.left, \"5px\", \"image top is set correctly via addtile\" );\n\n        var firstChild = layer.div.firstChild;\n        t.eq( firstChild.nodeName.toLowerCase(), \"img\", \"div first child is an image object\" );\n        t.ok( firstChild == img, \"div first child is correct image object\" );\n        t.eq( tile.position.toString(), \"x=5,y=6\", \"Position of tile is set correctly.\" );\n        map.destroy();\n    }\n\n    function test_Layer_WMS_bboxEncoding (t) {\n        t.plan( 6 );\n\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.WMS(name, url, params, {encodeBBOX:true});\n        var map = new OpenLayers.Map('map', {tileManager: null});\n        map.addLayer(layer);\n        var pixel = new OpenLayers.Pixel(5,6);\n        var tile = layer.addTile(new OpenLayers.Bounds(1,2,3,4), pixel);\n        tile.draw();\n\n        var img = tile.imgDiv;\n        var tParams = OpenLayers.Util.extend({},\n                        OpenLayers.Util.upperCaseObject(params));\n        tParams = OpenLayers.Util.extend(tParams, {\n            BBOX: \"1,2,3,4\",\n            WIDTH: \"256\", HEIGHT: \"256\"\n        });\n        t.eq( tile.url,\n             layer.getFullRequestString(tParams),\n             \"image src is created correctly via addtile\" );\n        t.eq( tile.getTile().style.top, \"6px\", \"image top is set correctly via addtile\" );\n        t.eq( tile.getTile().style.left, \"5px\", \"image top is set correctly via addtile\" );\n\n        var firstChild = layer.div.firstChild;\n        t.eq( firstChild.nodeName.toLowerCase(), \"img\", \"div first child is an image object\" );\n        t.ok( firstChild, img, \"div first child is correct image object\" );\n        t.eq( tile.position.toString(), \"x=5,y=6\", \"Position of tile is set correctly.\" );\n        map.destroy();\n    }\n\n    function test_Layer_WMS_inittiles (t) {\n        t.plan( 2 );\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS(name, url, params, {buffer:2});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0),5);\n        t.eq( layer.grid.length, 8, \"Grid rows is correct.\" );\n        t.eq( layer.grid[0].length, 7, \"Grid cols is correct.\" );\n        map.destroy();\n    }\n\n    function test_Layer_WMS_clone (t) {\n        t.plan(4);\n\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        var options = {tileSize: new OpenLayers.Size(500,50)};\n        var map = new OpenLayers.Map('map', options);\n        layer = new OpenLayers.Layer.WMS(name, url, params);\n        map.addLayer(layer);\n\n        layer.grid = [ [6, 7],\n                       [8, 9]];\n\n        var clone = layer.clone();\n\n        t.ok( clone.grid != layer.grid, \"clone does not copy grid\");\n\n        t.ok( clone.tileSize.equals(layer.tileSize), \"tileSize correctly cloned\");\n\n        layer.tileSize.w += 40;\n\n        t.eq( clone.tileSize.w, 500, \"changing layer.tileSize does not change clone.tileSize -- a fresh copy was made, not just copied reference\");\n\n        t.eq( clone.alpha, layer.alpha, \"alpha copied correctly\");\n\n        layer.grid = null;\n        map.destroy();\n    }\n\n    function test_Layer_WMS_isBaseLayer(t) {\n        t.plan(3);\n\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.WMS(name, url, params);\n        t.ok( layer.isBaseLayer, \"baselayer is true by default\");\n\n        var newParams = OpenLayers.Util.extend({}, params);\n        newParams.transparent = \"true\";\n        layer = new OpenLayers.Layer.WMS(name, url, newParams);\n        t.ok( !layer.isBaseLayer, \"baselayer is false when transparent is set to true\");\n\n        layer = new OpenLayers.Layer.WMS(name, url, params, {isBaseLayer: false});\n        t.ok( !layer.isBaseLayer, \"baselayer is false when option is set to false\" );\n    }\n\n    function test_Layer_WMS_mergeNewParams (t) {\n        t.plan( 4 );\n\n        var map = new OpenLayers.Map(\"map\");\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.WMS(name, url, params);\n\n        var newParams = { layers: 'sooper',\n                          chickpeas: 'image/png'};\n\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n\n        layer.redraw = function() {\n            t.ok(true, \"layer is redrawn after new params merged\");\n        }\n\n        layer.mergeNewParams(newParams);\n\n        t.eq( layer.params.LAYERS, \"sooper\", \"mergeNewParams() overwrites well\");\n        t.eq( layer.params.CHICKPEAS, \"image/png\", \"mergeNewParams() adds well\");\n\n        newParams.CHICKPEAS = 151;\n\n        t.eq( layer.params.CHICKPEAS, \"image/png\", \"mergeNewParams() makes clean copy of hashtable\");\n        map.destroy();\n    }\n\n    function test_Layer_WMS_getFullRequestString (t) {\n\n\n        t.plan( 4 );\n        var map = new OpenLayers.Map('map');\n        map.projection = \"xx\";\n        var tUrl = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        var tParams = { layers: 'basic',\n                   format: 'image/png'};\n        var tLayer = new OpenLayers.Layer.WMS(name, tUrl, tParams);\n        map.addLayer(tLayer);\n        var str = tLayer.getFullRequestString();\n        var tParams = {\n            LAYERS: \"basic\", FORMAT: \"image/png\", SERVICE: \"WMS\",\n            VERSION: \"1.1.1\", REQUEST: \"GetMap\", STYLES: \"\",\n            SRS: \"xx\"\n        };\n        t.eq(str,\n             tUrl + \"?\" + OpenLayers.Util.getParameterString(tParams),\n             \"getFullRequestString() adds SRS value\");\n\n        map.removeLayer(tLayer);\n        tLayer.projection = \"none\";\n        map.addLayer(tLayer);\n        str = tLayer.getFullRequestString();\n        delete tParams['SRS'];\n        t.eq(str,\n             tUrl + \"?\" + OpenLayers.Util.getParameterString(tParams),\n             \"getFullRequestString() by default does *not* add SRS value if projection is 'none'\");\n        map.destroy();\n        \n        map = new OpenLayers.Map(\"map\", {projection: \"EPSG:4326\"});\n        var layerProj = new OpenLayers.Projection(\"FOO\", {\n            equals: function() {return true},\n            getCode: function() {return \"FOO\"}\n        });\n        tLayer = new OpenLayers.Layer.WMS(name, tUrl, tParams, {projection: layerProj});\n        map.addLayer(tLayer);\n        str = tLayer.getFullRequestString();\n        tParams.SRS = \"FOO\";\n        t.eq(str,\n             tUrl + \"?\" + OpenLayers.Util.getParameterString(tParams),\n             \"getFullRequestString() uses the layer projection if it equals the map projection\");\n        map.destroy();\n\n        map = new OpenLayers.Map(\"map\", {projection: \"EPSG:4326\"});\n        map.addLayer(new OpenLayers.Layer(null, {isBaseLayer: true}));\n        tLayer = new OpenLayers.Layer.WMS(name, tUrl);\n        tLayer.map = map;\n        var error;\n        try {\n            tLayer.getFullRequestString();\n            error = false;\n        } catch(err) {\n            error = true;\n    }\n        t.ok(!error, \"no error on getFullRequestString if layer has no projection\");\n        map.destroy();\n\n    }\n\n    function test_setOpacity(t) {\n        t.plan(1);\n\n        var layer = new OpenLayers.Layer.WMS(\n            null, \"/bogus/wms\", {layers: \"mylayer\"}\n        );\n        var map = new OpenLayers.Map(\"map\");\n        map.addLayer(layer);\n        \n        map.zoomToMaxExtent();\n        \n        layer.setOpacity(0.5);\n        t.delay_call(1, function() {\n            t.eq(parseFloat(layer.div.firstChild.style.opacity), 0.5, \"opacity set\");\n            map.destroy();\n        });\n    }\n\n\n    function test_Layer_WMS_noGutters (t) {\n        t.plan(2);\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS(\"no gutter layer\", url, params, {gutter: 0});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 5);\n        var tile = layer.grid[0][0];\n        var request = layer.getURL(tile.bounds);\n        var args = OpenLayers.Util.getParameters(request);\n        t.eq(parseInt(args['WIDTH']),\n             tile.size.w,\n             \"layer without gutter requests images that are as wide as the tile\");\n        t.eq(parseInt(args['HEIGHT']),\n             tile.size.h,\n             \"layer without gutter requests images that are as tall as the tile\");\n\n        layer.destroy();\n        map.destroy();\n    }\n\n    function test_Layer_WMS_gutters (t) {\n        t.plan(2);\n        var gutter = 15;\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS(\"gutter layer\", url, params, {gutter: gutter});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 5);\n        var tile = layer.grid[0][0];\n        var request = layer.getURL(tile.bounds);\n        var args = OpenLayers.Util.getParameters(request);\n        t.eq(parseInt(args['WIDTH']),\n             tile.size.w + (2 * gutter),\n             \"layer with gutter requests images that are wider by twice the gutter\");\n        t.eq(parseInt(args['HEIGHT']),\n             tile.size.h + (2 * gutter),\n             \"layer with gutter requests images that are taller by twice the gutter\");\n\n        layer.destroy();\n        map.destroy();\n\n    }\n\n    function test_maxExtent(t) {\n        t.plan(5);\n        \n        var layer = new OpenLayers.Layer.WMS(\n            null, \"http://example.com/wms\", \n            {layers: \"foo\"}, \n            {maxExtent: [-180, 0, 0, 90]}\n        );\n        \n        t.ok(layer.maxExtent instanceof OpenLayers.Bounds, \"(array) bounds instance\");\n        t.eq(layer.maxExtent.left, -180, \"(array) bounds left\");\n        t.eq(layer.maxExtent.bottom, 0, \"(array) bounds left\");\n        t.eq(layer.maxExtent.right, 0, \"(array) bounds right\");\n        t.eq(layer.maxExtent.top, 90, \"(array) bounds top\");\n        \n        layer.destroy();\n    }\n\n    function test_minExtent(t) {\n        t.plan(5);\n        \n        var layer = new OpenLayers.Layer.WMS(\n            null, \"http://example.com/wms\", \n            {layers: \"foo\"}, \n            {minExtent: [-180, 0, 0, 90]}\n        );\n        \n        t.ok(layer.minExtent instanceof OpenLayers.Bounds, \"(array) bounds instance\");\n        t.eq(layer.minExtent.left, -180, \"(array) bounds left\");\n        t.eq(layer.minExtent.bottom, 0, \"(array) bounds left\");\n        t.eq(layer.minExtent.right, 0, \"(array) bounds right\");\n        t.eq(layer.minExtent.top, 90, \"(array) bounds top\");\n        \n        layer.destroy();\n    }\n\n    function test_tileOrigin(t) {\n        t.plan(4);\n        \n        var dummy = new OpenLayers.Layer(null, {isBaseLayer: true});\n        var unconstrained = new OpenLayers.Layer.WMS(\n            null, \"http://example.com/wms\", \n            {layers: \"unconstrained\"}, \n            {isBaseLayer: false, buffer: 0}\n        );\n        var constrained = new OpenLayers.Layer.WMS(\n            null, \"http://example.com/wms-c\", \n            {layers: \"constrained\"}, \n            {buffer: 0, isBaseLayer: false, tileOrigin: new OpenLayers.LonLat(-180, -90)}\n        );\n        var map = new OpenLayers.Map({\n            div: \"map\",\n            maxExtent: new OpenLayers.Bounds(-185, -95, 185, 95),\n            maxResolution: 1.40625,\n            layers: [dummy, unconstrained, constrained],\n            center: new OpenLayers.LonLat(0, 0),\n            zoom: 1\n        });\n        \n        t.eq(unconstrained.grid[1][0].bounds.bottom, -95, \"unconstrained bottom correct\");\n        t.eq(unconstrained.grid[1][0].bounds.left, -185, \"unconstrained left correct\");\n        t.eq(constrained.grid[1][0].bounds.bottom, -90, \"constrained bottom correct\");\n        t.eq(constrained.grid[1][0].bounds.left, -180, \"constrained left correct\");\n        \n        map.destroy();\n        \n    }\n\n    function test_Layer_WMS_destroy (t) {\n\n        t.plan( 1 );\n\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS(name, url, params);\n        map.addLayer(layer);\n\n        map.setCenter(new OpenLayers.LonLat(0,0), 5);\n\n        //grab a reference to one of the tiles\n        var tile = layer.grid[0][0];\n\n        layer.destroy();\n\n    // checks to make sure superclass (grid) destroy() was called\n\n        t.ok( layer.grid == null, \"grid set to null\");\n    }\n\n    function test_customProjection(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map('map', {\n            units: 'm', \n            projection: new OpenLayers.Projection('EPSG:28992'),\n            maxExtent: new OpenLayers.Bounds(0, 300000, 300000, 6250000)\n        });\n        var layer = new OpenLayers.Layer.WMS(null, url, {layers: 'mylayer', version: '1.3.0'});\n        map.addLayer(layer);\n        var error = false;\n        try {\n            map.setCenter(new OpenLayers.LonLat(100000,300000), 5);\n        } catch(err) {\n            error = true;\n        }\n        t.ok(!error, \"no error on getURL if layer has a custom projection and no defaults defined\");\n        layer.destroy();\n        map.destroy();\n    }\n\n    function test_Layer_WMS_v13(t) {\n\n        t.plan(6);\n\n        var lon = 5;\n        var lat = 40;\n        var zoom = 5;\n        var map = new OpenLayers.Map( 'map' );\n        var layer = new OpenLayers.Layer.WMS(\n            \"OpenLayers WMS\",\n            \"http://myserver.org/wms?\",\n            {layers: 'mylayer', version: '1.3.0'},\n            {singleTile: true}\n        );\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);\n\n        var url = layer.getURL(map.getExtent());\n        var params = url.split(\"&\");\n        var bbox;\n        for (var i=0, len=params.length; i<len; i++) {\n            var param = params[i];\n            var a = param.split('=');\n            if (a[0] === 'BBOX') {\n                bbox = a[1];\n                break;\n            }\n        }\n\n        t.eq(layer.params.CRS, \"EPSG:4326\", \"In WMS 1.3 SRS is now CRS\");\n        t.eq(bbox, \"27.9150390625,-5.986328125,52.0849609375,15.986328125\", \"Axis sequence is lat lon for EPSG:4326 in WMS 1.3.0\");\n\n        var layer2 = new OpenLayers.Layer.WMS(\n            \"OpenLayers WMS\",\n            \"http://myserver.org/wms?\",\n            {layers: 'mylayer', version: '1.1.1'},\n            {singleTile: true}\n        );\n        map.addLayer(layer2);\n\n        var url = layer2.getURL(map.getExtent());\n        var params = url.split(\"&\");\n        var bbox;\n        for (var i=0, len=params.length; i<len; i++) {\n            var param = params[i];\n            var a = param.split('=');\n            if (a[0] === 'BBOX') {\n                bbox = a[1];\n                break;\n            }\n        }\n\n        t.eq(layer2.params.SRS, \"EPSG:4326\", \"In WMS 1.1.1 parameter is called SRS\");\n        t.eq(bbox, \"-5.986328125,27.9150390625,15.986328125,52.0849609375\", \"Axis sequence is lon lat for EPSG:4326 in WMS 1.1.1\");\n\n        map.destroy();\n\n        // CRS:84 has normal axis sequence (lon lat)\n        var map = new OpenLayers.Map( 'map', {projection: 'CRS:84'} );\n        var layer = new OpenLayers.Layer.WMS(\n            \"OpenLayers WMS\",\n            \"http://myserver.org/wms?\",\n            {layers: 'mylayer', version: '1.3.0'},\n            {singleTile: true}\n        );\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);\n\n        var url = layer.getURL(map.getExtent());\n        var params = url.split(\"&\");\n        var bbox, exceptions;\n        for (var i=0, len=params.length; i<len; i++) {\n            var param = params[i];\n            var a = param.split('=');\n            if (a[0] === 'EXCEPTIONS') {\n                exceptions = a[1];\n            }\n            if (a[0] === 'BBOX') {\n                bbox = a[1];\n            }\n        }\n\n        t.eq(exceptions, \"INIMAGE\", \"If not set, EXCEPTIONS should be INIMAGE for WMS 1.3\");\n        t.eq(bbox, \"-5.986328125,27.9150390625,15.986328125,52.0849609375\", \"Axis sequence for CRS:84 is lon lat\");\n\n        map.destroy();\n\n    }\n    \n    function test_transparent(t) {\n        t.plan(5);\n        var map = new OpenLayers.Map(\"map\", {allOverlays: true});\n        var layer = new OpenLayers.Layer.WMS(\n            \"OpenLayers WMS\",\n            \"http://myserver.org/wms?\",\n            {layers: 'mylayer', transparent: true}\n        );\n        map.addLayer(layer);\n\n        t.eq(typeof layer.params.TRANSPARENT, \"boolean\", \"transparent param is boolean\");\n        t.ok(layer.getFullRequestString({}).indexOf(\"TRANSPARENT=TRUE\") != -1, \"Boolean transparent param value is uppercase TRUE\");\n        layer.mergeNewParams({transparent: false});\n        t.ok(layer.getFullRequestString({}).indexOf(\"TRANSPARENT=FALSE\") != -1, \"Boolean transparent param value is uppercase FALSE\");\n\n        layer.mergeNewParams({transparent: \"true\"});\n        t.eq(typeof layer.params.TRANSPARENT, \"string\", \"transparent param is string\");\n        t.ok(layer.getFullRequestString({}).indexOf(\"TRANSPARENT=true\") != -1, \"transparent param value passed as provided if String\");\n        \n        map.destroy();\n    }\n    \n    function test_tileBounds(t) {\n        t.plan(3);\n        \n        var map = new OpenLayers.Map(\"map\", {projection: \"EPSG:3857\", zoomMethod: null});\n        var layer = new OpenLayers.Layer.WMS(\"wms\", \"../../img/blank.gif\");\n        map.addLayer(layer);\n        map.setCenter([0, 0], 1);\n        map.pan(2, -100);\n        map.zoomIn();\n        t.eq(layer.grid[1][0].bounds, new OpenLayers.Bounds(-10018754.17, 0, 0, 10018754.17), \"no floating point errors after zooming\");\n        map.setCenter([0, 0], 14);\n        var bounds = layer.grid[0][0].bounds.clone();\n        map.pan(260, 520);\n        map.pan(-260, -520);\n        t.eq(layer.grid[0][0].bounds, bounds, \"no floating point errors after dragging back and forth\");\n        t.eq(bounds.right, 0, \"0 is 0, and not some super small number\");\n        \n        map.destroy();\n    }\n\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/WMTS.html",
    "content": "<html>\n    <head>\n        <script src=\"../OLLoader.js\"></script>\n        <script type=\"text/javascript\">    \n\n            function test_constructor(t) {\n                t.plan(6);        \n                var xml = document.getElementById(\"capabilities\").firstChild.nodeValue;\n                var doc = new OpenLayers.Format.XML().read(xml);\n                var obj = new OpenLayers.Format.WMTSCapabilities().read(doc);\n            \n                var layer0 = new OpenLayers.Layer.WMTS({\n                    name: \"GeoWebCache USA WMTS\", \n                    url: \"http://example.com/geowebcache-1.2.2/service/wmts/\",\n                    layer: \"arcgis-online-wms\",\n                    style: \"\",\n                    matrixSet: \"arcgis-online-wgs84\",                \n                    format: \"image/png\",\n                    isBaseLayer: false,\n                    requestEncoding: \"KVP\",\n                    maxResolution: 0.3521969032857032,\n                    numZoomLevels: 7,\n                    matrixIds: obj.contents.tileMatrixSets[\"arcgis-online-wgs84\"].matrixIds\n                });\n\n                t.ok(layer0 instanceof OpenLayers.Layer.WMTS, \"constructor returns instance of OpenLayers.Layer.WMTS\");\n                t.eq(layer0.formatSuffix, \"png\", \"formatSuffix is set correct based on 'format' parameter\");\n                \n                var layer1 = new OpenLayers.Layer.WMTS({\n                    name: \"Blue Marble WMTS\",  \n                    url: \"http://example.com/wmts/\",\n                    layer: \"world\",\n                    style: \"blue_marble\",\n                    matrixSet: \"arcgis_online\",\n                    tileSize: new OpenLayers.Size(512, 512),            \n                    requestEncoding: \"REST\"            \n                });\n\n                t.ok(layer1 instanceof OpenLayers.Layer.WMTS, \"constructor returns instance of OpenLayers.Layer.WMTS\");\n                t.eq(layer1.formatSuffix, \"jpg\", \"formatSuffix is set correct based on default format\");\n                t.eq(layer1.tileSize.w, 512.0, \"tileSize w is set correctly\");\n                t.eq(layer1.tileSize.h, 512.0, \"tileSize h is set correctly\");\n            }\n\n            function test_moveTo(t) {\n                t.plan(9);        \n                var xml = document.getElementById(\"capabilities\").firstChild.nodeValue;\n                var doc = new OpenLayers.Format.XML().read(xml);\n                var obj = new OpenLayers.Format.WMTSCapabilities().read(doc);\n            \n                var layer0 = new OpenLayers.Layer.WMTS({\n                    name: \"GeoWebCache USA WMTS\", \n                    url: \"http://example.com/geowebcache-1.2.2/service/wmts/\",\n                    layer: \"arcgis-online-wms\",\n                    style: \"foo\",\n                    matrixSet: \"arcgis-online-wgs84\",    \n                    format: \"image/png\",\n                    requestEncoding: \"KVP\",\n                    maxResolution: 0.3521969032857032,\n                    numZoomLevels: 7,\n                    matrixIds: obj.contents.tileMatrixSets[\"arcgis-online-wgs84\"].matrixIds\n                });   \n\n                var map = new OpenLayers.Map('map');\n                map.addLayer(layer0);\n                \n                map.setCenter(new OpenLayers.LonLat(-97, 38), 1);\n                \n                t.ok((layer0.tileOrigin instanceof OpenLayers.LonLat), \"tileOrigin is an instance of OpenLayers.LonLat\");\n                t.ok((layer0.tileOrigin.lon == -180 && layer0.tileOrigin.lat == 90), \"tileOrigin is set correctly\");\n                t.ok((layer0.tileSize instanceof OpenLayers.Size), \"tileSize is an instance of OpenLayers.Size\");\n                t.eq(layer0.tileSize.w, 256.0, \"tileSize w is set correctly\");\n                t.eq(layer0.tileSize.h, 256.0, \"tileSize h is set correctly\");\n\n                map.setCenter(new OpenLayers.LonLat(-97.0, 38.0), 6);\n                \n                t.eq(layer0.tileOrigin.lon, -175, \"tileOrigin.lat updated correctly when zoom changed\"); \n                t.eq(layer0.tileOrigin.lat, 85, \"tileOrigin.lat updated correctly when zoom changed\");                \n                t.eq(layer0.tileSize.w, 512.0, \"tileSize w updated correctly when zoom changed\");\n                t.eq(layer0.tileSize.h, 512.0, \"tileSize h updated correctly when zoom changed\");                    \n\n                map.destroy();\n            }\n\n            function test_clearTiles (t) {\n                t.plan(1);\n                var map = new OpenLayers.Map('map');\n\n                var layer1 = new OpenLayers.Layer.WMTS({\n                    name: \"Blue Marble WMTS\",\n                    url: \"http://example.com/wmts/\",\n                    layer: \"world\",\n                    style: \"blue_marble\",\n                    matrixSet: \"arcgis_online\",\n                    tileSize: new OpenLayers.Size(512, 512),            \n                    requestEncoding: \"REST\"            \n                });\n                \n                map.addLayer(layer1);\n                map.setCenter(new OpenLayers.LonLat(0,0));\n\n                //grab a reference to one of the tiles\n                var tile = layer1.grid[0][0];        \n\n                layer1.clearGrid();\n\n                t.ok( layer1.grid != null, \"layer.grid does not get nullified\" );\n                map.destroy();\n            }\n\n            function test_getTilesBounds(t) {\n                t.plan(1);\n                var layer1 = new OpenLayers.Layer.WMTS({ \n                    name: \"Blue Marble WMTS\",  \n                    url: \"http://example.com/wmts/\",\n                    layer: \"world\",\n                    style: \"blue_marble\",\n                    matrixSet: \"arcgis_online\",\n                    tileSize: new OpenLayers.Size(512, 512),            \n                    requestEncoding: \"REST\"            \n                });\n                var bl = {bounds: new OpenLayers.Bounds(1,2,2,3)};\n                var tr = {bounds: new OpenLayers.Bounds(2,3,3,4)};\n                layer1.grid = [[6, tr],[bl, 7]];\n                var bounds = layer1.getTilesBounds();            \n                var testBounds = new OpenLayers.Bounds(1,2,3,4);                \n                t.ok(bounds.equals(testBounds), \"correct bounds\");                \n            }\n\n            function test_getResolution(t) {\n                t.plan(1);\n                var map = new OpenLayers.Map('map');\n                var layer1 = new OpenLayers.Layer.WMTS({\n                    name: \"Blue Marble WMTS\",  \n                    url: \"http://example.com/wmts/\",\n                    layer: \"world\",\n                    style: \"blue_marble\",\n                    matrixSet: \"arcgis_online\",\n                    tileSize: new OpenLayers.Size(512, 512),  \n                    maxResolution: 1.40625,          \n                    requestEncoding: \"REST\"            \n                });\n                map.addLayer(layer1);\n                map.zoom = 5;\n                t.eq(layer1.getResolution(), 0.0439453125, \"getResolution() returns correct value\");\n                map.destroy();\n            }\n\n            function test_getZoomForExtent(t) {\n                t.plan(2);\n                var bounds, zoom;\n\n                var map = new OpenLayers.Map('map');\n                var layer1 = new OpenLayers.Layer.WMTS({\n                    name: \"Blue Marble WMTS\",  \n                    url: \"http://example.com/wmts/\",\n                    layer: \"world\",\n                    style: \"blue_marble\",\n                    matrixSet: \"arcgis_online\",\n                    tileSize: new OpenLayers.Size(512, 512),       \n                    maxResolution: 1.40625,     \n                    requestEncoding: \"REST\"            \n                });                                \n                map.addLayer(layer1);\n                bounds = new OpenLayers.Bounds(10,10,12,12);\n                zoom = layer1.getZoomForExtent(bounds);\n                t.eq(zoom, 8, \"correct value for (10,10,12,12)\");\n                bounds = new OpenLayers.Bounds(10,10,100,100);\n                zoom = layer1.getZoomForExtent(bounds);\n                t.eq(zoom, 3, \"correct value (10,10,100,100)\");\n                map.destroy();\n            }   \n\n            function test_getURL(t) {\n                t.plan(2);\n                var xml = document.getElementById(\"capabilities\").firstChild.nodeValue;\n                var doc = new OpenLayers.Format.XML().read(xml);\n                var obj = new OpenLayers.Format.WMTSCapabilities().read(doc);\n            \n                var layer0 = new OpenLayers.Layer.WMTS({\n                    name: \"GeoWebCache USA WMTS\", \n                    url: \"http://example.com/geowebcache-1.2.2/service/wmts/\",\n                    layer: \"arcgis-online-wms\",\n                    style: \"foo\",\n                    matrixSet: \"arcgis-online-wgs84\",                \n                    format: \"image/png\",\n                    requestEncoding: \"KVP\",\n                    maxResolution: 0.3521969032857032,\n                    numZoomLevels: 7,\n                    matrixIds: obj.contents.tileMatrixSets[\"arcgis-online-wgs84\"].matrixIds\n                }); \n                 \n                var layer1 = new OpenLayers.Layer.WMTS({\n                    name: \"Blue Marble WMTS\",  \n                    url: \"http://example.com/wmts/\",\n                    layer: \"world\",\n                    style: \"blue_marble\",\n                    matrixSet: \"arcgis_online\",\n                    format: \"image/jpeg\",\n                    tileSize: new OpenLayers.Size(512, 512),            \n                    requestEncoding: \"REST\",\n                    isBaseLayer: false            \n                });     \n\n                var options = {\n                    controls: [            \n                        new OpenLayers.Control.LayerSwitcher(),\n                        new OpenLayers.Control.Navigation(),   \n                        new OpenLayers.Control.PanZoom()\n                    ],\n                    projection: \"EPSG:4326\",                                    \n                    maxResolution: 0.3515625,\n                    maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90)\n                };    \n                var map = new OpenLayers.Map('map', options);\n                map.addLayers([layer0,layer1]);\n                map.setCenter(new OpenLayers.LonLat(-97.0, 38.0), 1);\n                var tileurl0 = layer0.getURL(new OpenLayers.Bounds(-135.0, 0.0, -90.0, 45.0));\n                t.ok(OpenLayers.Util.isEquivalentUrl(tileurl0, \"http://example.com/geowebcache-1.2.2/service/wmts/?LAYER=arcgis-online-wms&STYLE=foo&TILEMATRIXSET=arcgis-online-wgs84&FORMAT=image%2Fpng&SERVICE=WMTS&VERSION=1.0.0&REQUEST=GetTile&TILEMATRIX=arcgis-online-wgs84%3A1&TILEROW=1&TILECOL=1\"), \"layer0 getURL returns correct url\");\n\n                var tileurl1 = layer1.getURL(new OpenLayers.Bounds(-180.0, 0.0, -90.0, 90.0));\n                t.eq(tileurl1, \"http://example.com/wmts/1.0.0/world/blue_marble/arcgis_online/1/0/0.jpg\", \"layer1 getURL returns correct url\");                                        \n                map.destroy();\n            }\n\n            function test_getURL_resourceUrl(t) {\n                t.plan(2);\n            \n                var xml = document.getElementById(\"capabilities\").firstChild.nodeValue;\n                var doc = new OpenLayers.Format.XML().read(xml);\n                var obj = new OpenLayers.Format.WMTSCapabilities().read(doc);\n\n                var template = \"http://www.example.com/{style}/{Time}/{style}/{TileMatrixSet}/{TileMatrix}/{TileRow}/{TileCol}.png\";\n                var layer = new OpenLayers.Layer.WMTS({\n                    requestEncoding: \"REST\",\n                    url: template,\n                    layer: \"GeoWebCache_USA_WMTS\",\n                    style: \"foo\",\n                    matrixSet: \"arcgis-online\",\n                    params: {Time: \"2011\"},\n                    dimensions: [\"Time\"]\n                });   \n\n                var map = new OpenLayers.Map(\"map\", {\n                    layers: [layer],\n                    projection: \"EPSG:4326\",                                    \n                    maxResolution: 0.3515625,\n                    maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90),\n                    zoomMethod: null\n                });\n                map.setCenter(new OpenLayers.LonLat(-97.0, 38.0), 1);\n                t.eq(layer.getURL(new OpenLayers.Bounds(-135.0, 0.0, -90.0, 45.0)), \n                     \"http://www.example.com/foo/2011/foo/arcgis-online/1/1/1.png\", \"getURL returns correct url\");\n                map.zoomIn();\n                t.eq(layer.getURL(new OpenLayers.Bounds(-180.0, 0.0, -90.0, 90.0)), \n                     \"http://www.example.com/foo/2011/foo/arcgis-online/2/2/2.png\", \"getURL returns correct url\");\n                map.destroy();\n            }\n            \n            function test_destroy (t) {\n                t.plan(3);\n                var map = new OpenLayers.Map('map');\n                var layer1 = new OpenLayers.Layer.WMTS({\n                    name: \"Blue Marble WMTS\",  \n                    url: \"http://example.com/wmts/\",\n                    layer: \"world\",\n                    style: \"blue_marble\",\n                    matrixSet: \"arcgis_online\",\n                    tileSize: new OpenLayers.Size(512, 512),            \n                    requestEncoding: \"REST\"            \n                });    \n                map.addLayer(layer1);\n                layer1.destroy();\n                t.eq( layer1.grid, null, \"layer.grid is null after destroy\" );\n                t.eq( layer1.tileSize, null, \"layer.tileSize is null after destroy\" );\n\n                //test with tile creation\n                var layer2 = new OpenLayers.Layer.WMTS({\n                    name: \"Blue Marble WMTS\",  \n                    url: \"http://example.com/wmts/\",\n                    layer: \"world\",\n                    style: \"blue_marble\",\n                    matrixSet: \"arcgis_online\",\n                    tileSize: new OpenLayers.Size(512, 512),            \n                    requestEncoding: \"REST\"            \n                });    \n                map.addLayer(layer2);\n                map.setCenter(new OpenLayers.LonLat(0,0), 5);\n                //grab a reference to one of the tiles\n                var tile = layer2.grid[0][0];        \n\n                layer2.destroy();\n\n                t.ok( layer2.grid == null, \"tiles appropriately destroyed\");\n                map.destroy();\n            }    \n\n            function test_getIdentifier(t) {\n                t.plan(2);\n\n                var map = new OpenLayers.Map('map');\n                var layer, identifier;\n\n                layer = new OpenLayers.Layer.WMTS({\n                    name: \"Blue Marble WMTS\",\n                    url: \"http://example.com/wmts/\",\n                    layer: \"world\",\n                    style: \"blue_marble\",\n                    matrixSet: \"arcgis_online\",\n                    tileSize: new OpenLayers.Size(512, 512),\n                    requestEncoding: \"REST\"\n                });\n                map.addLayer(layer);\n                map.setCenter(new OpenLayers.LonLat(0,0), 5);\n\n                layer.zoomOffset = 2;\n                identifier = layer.getIdentifier();\n                t.eq(identifier, 7, '[zoomOffset] getIdentifier return value is correct');\n\n                layer.serverResolutions = ['offset', 1.40625, 0.703125, 0.3515625, 0.17578125,\n                                           0.087890625, 0.0439453125];\n                identifier = layer.getIdentifier();\n                t.eq(identifier, 6, '[serverResolutions] getIdentifier return value is correct');\n\n                map.destroy();\n            }\n\n        </script>\n    </head>\n    <body>\n        <div id=\"map\" style=\"width:1024px;height:512px;\"></div>\n        <div id=\"capabilities\"><!--\n<Capabilities xmlns=\"http://www.opengis.net/wmts/1.0\"\nxmlns:ows=\"http://www.opengis.net/ows/1.1\"\nxmlns:xlink=\"http://www.w3.org/1999/xlink\"\nxmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\nxmlns:gml=\"http://www.opengis.net/gml\" xsi:schemaLocation=\"http://www.opengis.net/wmts/1.0 http://geowebcache.org/schema/opengis/wmts/1.0.0/wmtsGetCapabilities_response.xsd\"\nversion=\"1.0.0\">\n<ows:ServiceIdentification>\n  <ows:Title>Web Map Tile Service - GeoWebCache</ows:Title>\n  <ows:ServiceType>OGC WMTS</ows:ServiceType>\n  <ows:ServiceTypeVersion>1.0.0</ows:ServiceTypeVersion>\n</ows:ServiceIdentification>\n<ows:ServiceProvider>\n  <ows:ProviderName>http://example.com/geowebcache-1.2.2/service/wmts</ows:ProviderName>\n  <ows:ProviderSite xlink:href=\"http://example.com/geowebcache-1.2.2/service/wmts\" />\n  <ows:ServiceContact>\n    <ows:IndividualName>GeoWebCache User</ows:IndividualName>\n  </ows:ServiceContact>\n</ows:ServiceProvider>\n<ows:OperationsMetadata>\n  <ows:Operation name=\"GetCapabilities\">\n    <ows:DCP>\n      <ows:HTTP>\n        <ows:Get xlink:href=\"http://example.com/geowebcache-1.2.2/service/wmts?\">\n          <ows:Constraint name=\"GetEncoding\">\n            <ows:AllowedValues>\n              <ows:Value>KVP</ows:Value>\n            </ows:AllowedValues>\n          </ows:Constraint>\n        </ows:Get>\n      </ows:HTTP>\n    </ows:DCP>\n  </ows:Operation>\n  <ows:Operation name=\"GetTile\">\n    <ows:DCP>\n      <ows:HTTP>\n        <ows:Get xlink:href=\"http://example.com/geowebcache-1.2.2/service/wmts?\">\n          <ows:Constraint name=\"GetEncoding\">\n            <ows:AllowedValues>\n              <ows:Value>KVP</ows:Value>\n            </ows:AllowedValues>\n          </ows:Constraint>\n        </ows:Get>\n      </ows:HTTP>\n    </ows:DCP>\n  </ows:Operation>\n  <ows:Operation name=\"GetFeatureInfo\">\n    <ows:DCP>\n      <ows:HTTP>\n        <ows:Get xlink:href=\"http://example.com/geowebcache-1.2.2/service/wmts?\">\n          <ows:Constraint name=\"GetEncoding\">\n            <ows:AllowedValues>\n              <ows:Value>KVP</ows:Value>\n            </ows:AllowedValues>\n          </ows:Constraint>\n        </ows:Get>\n      </ows:HTTP>\n    </ows:DCP>\n  </ows:Operation>\n</ows:OperationsMetadata>\n<Contents>\n  <Layer>\n    <ows:Title>arcgis-online-wms</ows:Title>\n    <ows:Abstract>arcgis-online-wms</ows:Abstract>\n    <ows:WGS84BoundingBox>\n      <ows:LowerCorner>-180.0 -90.0</ows:LowerCorner>\n      <ows:UpperCorner>180.0 90.0</ows:UpperCorner>\n    </ows:WGS84BoundingBox>\n    <ows:Identifier>arcgis-online-wms</ows:Identifier>\n    <Style isDefault=\"true\">\n      <ows:Identifier>_null</ows:Identifier>\n    </Style>\n    <Format>image/png</Format>\n    <Format>image/jpeg</Format>\n    <TileMatrixSetLink>      <TileMatrixSet>arcgis-online-wgs84</TileMatrixSet>\n    </TileMatrixSetLink>  </Layer>\n  <TileMatrixSet>\n    <ows:Identifier>EPSG:4326</ows:Identifier>\n    <ows:SupportedCRS>urn:ogc:def:crs:EPSG::4326</ows:SupportedCRS>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:0</ows:Identifier>\n      <ScaleDenominator>2.795411320143589E8</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>2</MatrixWidth>\n      <MatrixHeight>1</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:1</ows:Identifier>\n      <ScaleDenominator>1.3977056600717944E8</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>4</MatrixWidth>\n      <MatrixHeight>2</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:2</ows:Identifier>\n      <ScaleDenominator>6.988528300358972E7</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>8</MatrixWidth>\n      <MatrixHeight>4</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:3</ows:Identifier>\n      <ScaleDenominator>3.494264150179486E7</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>16</MatrixWidth>\n      <MatrixHeight>8</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:4</ows:Identifier>\n      <ScaleDenominator>1.747132075089743E7</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>32</MatrixWidth>\n      <MatrixHeight>16</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:5</ows:Identifier>\n      <ScaleDenominator>8735660.375448715</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>64</MatrixWidth>\n      <MatrixHeight>32</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:6</ows:Identifier>\n      <ScaleDenominator>4367830.1877243575</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>128</MatrixWidth>\n      <MatrixHeight>64</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:7</ows:Identifier>\n      <ScaleDenominator>2183915.0938621787</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>256</MatrixWidth>\n      <MatrixHeight>128</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:8</ows:Identifier>\n      <ScaleDenominator>1091957.5469310894</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>512</MatrixWidth>\n      <MatrixHeight>256</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:9</ows:Identifier>\n      <ScaleDenominator>545978.7734655447</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>1024</MatrixWidth>\n      <MatrixHeight>512</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:10</ows:Identifier>\n      <ScaleDenominator>272989.38673277234</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>2048</MatrixWidth>\n      <MatrixHeight>1024</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:11</ows:Identifier>\n      <ScaleDenominator>136494.69336638617</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>4096</MatrixWidth>\n      <MatrixHeight>2048</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:12</ows:Identifier>\n      <ScaleDenominator>68247.34668319309</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>8192</MatrixWidth>\n      <MatrixHeight>4096</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:13</ows:Identifier>\n      <ScaleDenominator>34123.67334159654</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>16384</MatrixWidth>\n      <MatrixHeight>8192</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:14</ows:Identifier>\n      <ScaleDenominator>17061.83667079827</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>32768</MatrixWidth>\n      <MatrixHeight>16384</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:15</ows:Identifier>\n      <ScaleDenominator>8530.918335399136</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>65536</MatrixWidth>\n      <MatrixHeight>32768</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:16</ows:Identifier>\n      <ScaleDenominator>4265.459167699568</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>131072</MatrixWidth>\n      <MatrixHeight>65536</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:17</ows:Identifier>\n      <ScaleDenominator>2132.729583849784</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>262144</MatrixWidth>\n      <MatrixHeight>131072</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:18</ows:Identifier>\n      <ScaleDenominator>1066.364791924892</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>524288</MatrixWidth>\n      <MatrixHeight>262144</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:19</ows:Identifier>\n      <ScaleDenominator>533.182395962446</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>1048576</MatrixWidth>\n      <MatrixHeight>524288</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:20</ows:Identifier>\n      <ScaleDenominator>266.591197981223</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>2097152</MatrixWidth>\n      <MatrixHeight>1048576</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:21</ows:Identifier>\n      <ScaleDenominator>133.2955989906115</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>4194304</MatrixWidth>\n      <MatrixHeight>2097152</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:22</ows:Identifier>\n      <ScaleDenominator>66.64779949530575</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>8388608</MatrixWidth>\n      <MatrixHeight>4194304</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:23</ows:Identifier>\n      <ScaleDenominator>33.323899747652874</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>16777216</MatrixWidth>\n      <MatrixHeight>8388608</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:24</ows:Identifier>\n      <ScaleDenominator>16.661949873826437</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>33554432</MatrixWidth>\n      <MatrixHeight>16777216</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:25</ows:Identifier>\n      <ScaleDenominator>8.330974936913218</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>67108864</MatrixWidth>\n      <MatrixHeight>33554432</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:26</ows:Identifier>\n      <ScaleDenominator>4.165487468456609</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>134217728</MatrixWidth>\n      <MatrixHeight>67108864</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:27</ows:Identifier>\n      <ScaleDenominator>2.0827437342283046</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>268435456</MatrixWidth>\n      <MatrixHeight>134217728</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:28</ows:Identifier>\n      <ScaleDenominator>1.0413718671141523</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>536870912</MatrixWidth>\n      <MatrixHeight>268435456</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:29</ows:Identifier>\n      <ScaleDenominator>0.5206859335570762</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>1073741824</MatrixWidth>\n      <MatrixHeight>536870912</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:4326:30</ows:Identifier>\n      <ScaleDenominator>0.2603429667785381</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>2147483648</MatrixWidth>\n      <MatrixHeight>1073741824</MatrixHeight>\n    </TileMatrix>\n  </TileMatrixSet>\n  <TileMatrixSet>\n    <ows:Identifier>arcgis-online-epsg102113</ows:Identifier>\n    <ows:SupportedCRS>urn:ogc:def:crs:EPSG::102113</ows:SupportedCRS>\n    <TileMatrix>\n      <ows:Abstract>The grid was not well-defined, the scale therefore assumes 1m per map unit.</ows:Abstract>      <ows:Identifier>arcgis-online-epsg102113:0</ows:Identifier>\n      <ScaleDenominator>5.590822639285715E8</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.00375083392E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>1</MatrixWidth>\n      <MatrixHeight>1</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Abstract>The grid was not well-defined, the scale therefore assumes 1m per map unit.</ows:Abstract>      <ows:Identifier>arcgis-online-epsg102113:1</ows:Identifier>\n      <ScaleDenominator>2.7954113196428573E8</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.00375083392E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>2</MatrixWidth>\n      <MatrixHeight>2</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Abstract>The grid was not well-defined, the scale therefore assumes 1m per map unit.</ows:Abstract>      <ows:Identifier>arcgis-online-epsg102113:2</ows:Identifier>\n      <ScaleDenominator>1.3977056598214287E8</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.00375083392E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>4</MatrixWidth>\n      <MatrixHeight>4</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Abstract>The grid was not well-defined, the scale therefore assumes 1m per map unit.</ows:Abstract>      <ows:Identifier>arcgis-online-epsg102113:3</ows:Identifier>\n      <ScaleDenominator>6.988528299107143E7</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.00375083392E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>8</MatrixWidth>\n      <MatrixHeight>8</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Abstract>The grid was not well-defined, the scale therefore assumes 1m per map unit.</ows:Abstract>      <ows:Identifier>arcgis-online-epsg102113:4</ows:Identifier>\n      <ScaleDenominator>3.494264149553572E7</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.00375083392E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>16</MatrixWidth>\n      <MatrixHeight>16</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Abstract>The grid was not well-defined, the scale therefore assumes 1m per map unit.</ows:Abstract>      <ows:Identifier>arcgis-online-epsg102113:5</ows:Identifier>\n      <ScaleDenominator>1.747132074776786E7</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.00375083392E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>32</MatrixWidth>\n      <MatrixHeight>32</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Abstract>The grid was not well-defined, the scale therefore assumes 1m per map unit.</ows:Abstract>      <ows:Identifier>arcgis-online-epsg102113:6</ows:Identifier>\n      <ScaleDenominator>8735660.37388393</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.00375083392E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>64</MatrixWidth>\n      <MatrixHeight>64</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Abstract>The grid was not well-defined, the scale therefore assumes 1m per map unit.</ows:Abstract>      <ows:Identifier>arcgis-online-epsg102113:7</ows:Identifier>\n      <ScaleDenominator>4367830.186941965</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.00375083392E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>128</MatrixWidth>\n      <MatrixHeight>128</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Abstract>The grid was not well-defined, the scale therefore assumes 1m per map unit.</ows:Abstract>      <ows:Identifier>arcgis-online-epsg102113:8</ows:Identifier>\n      <ScaleDenominator>2183915.0934709823</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.00375083392E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>256</MatrixWidth>\n      <MatrixHeight>256</MatrixHeight>\n    </TileMatrix>\n  </TileMatrixSet>\n  <TileMatrixSet>\n    <ows:Identifier>GlobalCRS84Scale</ows:Identifier>\n    <ows:SupportedCRS>urn:ogc:def:crs:EPSG::4326</ows:SupportedCRS>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:0</ows:Identifier>\n      <ScaleDenominator>5.0000000000000006E8</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>2</MatrixWidth>\n      <MatrixHeight>1</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:1</ows:Identifier>\n      <ScaleDenominator>2.5000000000000003E8</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>3</MatrixWidth>\n      <MatrixHeight>2</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:2</ows:Identifier>\n      <ScaleDenominator>1.0000000000000001E8</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>6</MatrixWidth>\n      <MatrixHeight>3</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:3</ows:Identifier>\n      <ScaleDenominator>5.000000000000001E7</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>12</MatrixWidth>\n      <MatrixHeight>6</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:4</ows:Identifier>\n      <ScaleDenominator>2.5000000000000004E7</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>23</MatrixWidth>\n      <MatrixHeight>12</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:5</ows:Identifier>\n      <ScaleDenominator>1.0E7</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>56</MatrixWidth>\n      <MatrixHeight>28</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:6</ows:Identifier>\n      <ScaleDenominator>5000000.0</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>112</MatrixWidth>\n      <MatrixHeight>56</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:7</ows:Identifier>\n      <ScaleDenominator>2500000.0</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>224</MatrixWidth>\n      <MatrixHeight>112</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:8</ows:Identifier>\n      <ScaleDenominator>1000000.0000000001</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>560</MatrixWidth>\n      <MatrixHeight>280</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:9</ows:Identifier>\n      <ScaleDenominator>500000.00000000006</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>1119</MatrixWidth>\n      <MatrixHeight>560</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:10</ows:Identifier>\n      <ScaleDenominator>250000.00000000003</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>2237</MatrixWidth>\n      <MatrixHeight>1119</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:11</ows:Identifier>\n      <ScaleDenominator>100000.00000000001</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>5591</MatrixWidth>\n      <MatrixHeight>2796</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:12</ows:Identifier>\n      <ScaleDenominator>50000.00000000001</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>11182</MatrixWidth>\n      <MatrixHeight>5591</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:13</ows:Identifier>\n      <ScaleDenominator>25000.000000000004</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>22364</MatrixWidth>\n      <MatrixHeight>11182</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:14</ows:Identifier>\n      <ScaleDenominator>10000.000000000002</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>55909</MatrixWidth>\n      <MatrixHeight>27955</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:15</ows:Identifier>\n      <ScaleDenominator>5000.000000000001</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>111817</MatrixWidth>\n      <MatrixHeight>55909</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:16</ows:Identifier>\n      <ScaleDenominator>2500.0000000000005</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>223633</MatrixWidth>\n      <MatrixHeight>111817</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:17</ows:Identifier>\n      <ScaleDenominator>1000.0000000000002</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>559083</MatrixWidth>\n      <MatrixHeight>279542</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:18</ows:Identifier>\n      <ScaleDenominator>500.0000000000001</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>1118165</MatrixWidth>\n      <MatrixHeight>559083</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:19</ows:Identifier>\n      <ScaleDenominator>250.00000000000006</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>2236330</MatrixWidth>\n      <MatrixHeight>1118165</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Scale:20</ows:Identifier>\n      <ScaleDenominator>100.00000000000003</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>5590823</MatrixWidth>\n      <MatrixHeight>2795412</MatrixHeight>\n    </TileMatrix>\n  </TileMatrixSet>\n  <TileMatrixSet>\n    <ows:Identifier>EPSG:900913</ows:Identifier>\n    <ows:SupportedCRS>urn:ogc:def:crs:EPSG::900913</ows:SupportedCRS>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:0</ows:Identifier>\n      <ScaleDenominator>5.590822639508929E8</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>1</MatrixWidth>\n      <MatrixHeight>1</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:1</ows:Identifier>\n      <ScaleDenominator>2.7954113197544646E8</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>2</MatrixWidth>\n      <MatrixHeight>2</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:2</ows:Identifier>\n      <ScaleDenominator>1.3977056598772323E8</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>4</MatrixWidth>\n      <MatrixHeight>4</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:3</ows:Identifier>\n      <ScaleDenominator>6.988528299386162E7</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>8</MatrixWidth>\n      <MatrixHeight>8</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:4</ows:Identifier>\n      <ScaleDenominator>3.494264149693081E7</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>16</MatrixWidth>\n      <MatrixHeight>16</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:5</ows:Identifier>\n      <ScaleDenominator>1.7471320748465404E7</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>32</MatrixWidth>\n      <MatrixHeight>32</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:6</ows:Identifier>\n      <ScaleDenominator>8735660.374232702</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>64</MatrixWidth>\n      <MatrixHeight>64</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:7</ows:Identifier>\n      <ScaleDenominator>4367830.187116351</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>128</MatrixWidth>\n      <MatrixHeight>128</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:8</ows:Identifier>\n      <ScaleDenominator>2183915.0935581755</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>256</MatrixWidth>\n      <MatrixHeight>256</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:9</ows:Identifier>\n      <ScaleDenominator>1091957.5467790877</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>512</MatrixWidth>\n      <MatrixHeight>512</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:10</ows:Identifier>\n      <ScaleDenominator>545978.7733895439</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>1024</MatrixWidth>\n      <MatrixHeight>1024</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:11</ows:Identifier>\n      <ScaleDenominator>272989.38669477194</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>2048</MatrixWidth>\n      <MatrixHeight>2048</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:12</ows:Identifier>\n      <ScaleDenominator>136494.69334738597</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>4096</MatrixWidth>\n      <MatrixHeight>4096</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:13</ows:Identifier>\n      <ScaleDenominator>68247.34667369298</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>8192</MatrixWidth>\n      <MatrixHeight>8192</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:14</ows:Identifier>\n      <ScaleDenominator>34123.67333684649</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>16384</MatrixWidth>\n      <MatrixHeight>16384</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:15</ows:Identifier>\n      <ScaleDenominator>17061.836668423246</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>32768</MatrixWidth>\n      <MatrixHeight>32768</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:16</ows:Identifier>\n      <ScaleDenominator>8530.918334211623</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>65536</MatrixWidth>\n      <MatrixHeight>65536</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:17</ows:Identifier>\n      <ScaleDenominator>4265.4591671058115</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>131072</MatrixWidth>\n      <MatrixHeight>131072</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:18</ows:Identifier>\n      <ScaleDenominator>2132.7295835529058</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>262144</MatrixWidth>\n      <MatrixHeight>262144</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:19</ows:Identifier>\n      <ScaleDenominator>1066.3647917764529</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>524288</MatrixWidth>\n      <MatrixHeight>524288</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:20</ows:Identifier>\n      <ScaleDenominator>533.1823958882264</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>1048576</MatrixWidth>\n      <MatrixHeight>1048576</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:21</ows:Identifier>\n      <ScaleDenominator>266.5911979441132</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>2097152</MatrixWidth>\n      <MatrixHeight>2097152</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:22</ows:Identifier>\n      <ScaleDenominator>133.2955989720566</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>4194304</MatrixWidth>\n      <MatrixHeight>4194304</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:23</ows:Identifier>\n      <ScaleDenominator>66.6477994860283</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>8388608</MatrixWidth>\n      <MatrixHeight>8388608</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:24</ows:Identifier>\n      <ScaleDenominator>33.32389974301415</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>16777216</MatrixWidth>\n      <MatrixHeight>16777216</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:25</ows:Identifier>\n      <ScaleDenominator>16.661949871507076</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>33554432</MatrixWidth>\n      <MatrixHeight>33554432</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:26</ows:Identifier>\n      <ScaleDenominator>8.330974935753538</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>67108864</MatrixWidth>\n      <MatrixHeight>67108864</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:27</ows:Identifier>\n      <ScaleDenominator>4.165487467876769</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>134217728</MatrixWidth>\n      <MatrixHeight>134217728</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:28</ows:Identifier>\n      <ScaleDenominator>2.0827437339383845</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>268435456</MatrixWidth>\n      <MatrixHeight>268435456</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:29</ows:Identifier>\n      <ScaleDenominator>1.0413718669691923</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>536870912</MatrixWidth>\n      <MatrixHeight>536870912</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>EPSG:900913:30</ows:Identifier>\n      <ScaleDenominator>0.5206859334845961</ScaleDenominator>\n      <TopLeftCorner>2.0037508E7 -2.003750834E7</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>1073741824</MatrixWidth>\n      <MatrixHeight>1073741824</MatrixHeight>\n    </TileMatrix>\n  </TileMatrixSet>\n  <TileMatrixSet>\n    <ows:Identifier>arcgis-online-wgs84</ows:Identifier>\n    <ows:SupportedCRS>urn:ogc:def:crs:EPSG::4326</ows:SupportedCRS>\n    <TileMatrix>\n      <ows:Identifier>arcgis-online-wgs84:0</ows:Identifier>\n      <ScaleDenominator>1.3977056600717944E8</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>4</MatrixWidth>\n      <MatrixHeight>2</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>arcgis-online-wgs84:1</ows:Identifier>\n      <ScaleDenominator>6.988528300358972E7</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>8</MatrixWidth>\n      <MatrixHeight>4</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>arcgis-online-wgs84:2</ows:Identifier>\n      <ScaleDenominator>3.494264150179486E7</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>16</MatrixWidth>\n      <MatrixHeight>8</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>arcgis-online-wgs84:3</ows:Identifier>\n      <ScaleDenominator>1.747132075089743E7</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>32</MatrixWidth>\n      <MatrixHeight>16</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>arcgis-online-wgs84:4</ows:Identifier>\n      <ScaleDenominator>8735660.375448715</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>64</MatrixWidth>\n      <MatrixHeight>32</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>arcgis-online-wgs84:5</ows:Identifier>\n      <ScaleDenominator>4367830.1877243575</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>128</MatrixWidth>\n      <MatrixHeight>64</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>arcgis-online-wgs84:6</ows:Identifier>\n      <ScaleDenominator>2183915.0938621787</ScaleDenominator>\n      <TopLeftCorner>85 -175</TopLeftCorner>\n      <TileWidth>512</TileWidth>\n      <TileHeight>512</TileHeight>\n      <MatrixWidth>256</MatrixWidth>\n      <MatrixHeight>128</MatrixHeight>\n    </TileMatrix>\n  </TileMatrixSet>\n  <TileMatrixSet>\n    <ows:Identifier>GlobalCRS84Pixel</ows:Identifier>\n    <ows:SupportedCRS>urn:ogc:def:crs:EPSG::4326</ows:SupportedCRS>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Pixel:0</ows:Identifier>\n      <ScaleDenominator>7.951392199519542E8</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>1</MatrixWidth>\n      <MatrixHeight>1</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Pixel:1</ows:Identifier>\n      <ScaleDenominator>3.975696099759771E8</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>2</MatrixWidth>\n      <MatrixHeight>1</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Pixel:2</ows:Identifier>\n      <ScaleDenominator>1.9878480498798856E8</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>3</MatrixWidth>\n      <MatrixHeight>2</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Pixel:3</ows:Identifier>\n      <ScaleDenominator>1.325232033253257E8</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>5</MatrixWidth>\n      <MatrixHeight>3</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Pixel:4</ows:Identifier>\n      <ScaleDenominator>6.626160166266285E7</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>9</MatrixWidth>\n      <MatrixHeight>5</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Pixel:5</ows:Identifier>\n      <ScaleDenominator>3.3130800831331424E7</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>17</MatrixWidth>\n      <MatrixHeight>9</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Pixel:6</ows:Identifier>\n      <ScaleDenominator>1.325232033253257E7</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>43</MatrixWidth>\n      <MatrixHeight>22</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Pixel:7</ows:Identifier>\n      <ScaleDenominator>6626160.166266285</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>85</MatrixWidth>\n      <MatrixHeight>43</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Pixel:8</ows:Identifier>\n      <ScaleDenominator>3313080.0831331424</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>169</MatrixWidth>\n      <MatrixHeight>85</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Pixel:9</ows:Identifier>\n      <ScaleDenominator>1656540.0415665712</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>338</MatrixWidth>\n      <MatrixHeight>169</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Pixel:10</ows:Identifier>\n      <ScaleDenominator>552180.0138555238</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>1013</MatrixWidth>\n      <MatrixHeight>507</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Pixel:11</ows:Identifier>\n      <ScaleDenominator>331308.00831331423</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>1688</MatrixWidth>\n      <MatrixHeight>844</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Pixel:12</ows:Identifier>\n      <ScaleDenominator>110436.00277110476</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>5063</MatrixWidth>\n      <MatrixHeight>2532</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Pixel:13</ows:Identifier>\n      <ScaleDenominator>55218.00138555238</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>10125</MatrixWidth>\n      <MatrixHeight>5063</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Pixel:14</ows:Identifier>\n      <ScaleDenominator>33130.80083133143</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>16875</MatrixWidth>\n      <MatrixHeight>8438</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Pixel:15</ows:Identifier>\n      <ScaleDenominator>11043.600277110474</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>50625</MatrixWidth>\n      <MatrixHeight>25313</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Pixel:16</ows:Identifier>\n      <ScaleDenominator>3313.080083133142</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>168750</MatrixWidth>\n      <MatrixHeight>84375</MatrixHeight>\n    </TileMatrix>\n    <TileMatrix>\n      <ows:Identifier>GlobalCRS84Pixel:17</ows:Identifier>\n      <ScaleDenominator>1104.3600277110472</ScaleDenominator>\n      <TopLeftCorner>90.0 -180.0</TopLeftCorner>\n      <TileWidth>256</TileWidth>\n      <TileHeight>256</TileHeight>\n      <MatrixWidth>506250</MatrixWidth>\n      <MatrixHeight>253125</MatrixHeight>\n    </TileMatrix>\n  </TileMatrixSet>\n</Contents>\n<ServiceMetadataURL xlink:href=\"http://example.com/geowebcache-1.2.2/service/wmts?REQUEST=getcapabilities&amp;VERSION=1.0.0\"/>\n</Capabilities>\n        -->\n        </div>\n    </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/WrapDateLine.html",
    "content": "<html>\n<head>\n<script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    // turn off animation frame handling, so we can check img urls in tests\n    delete OpenLayers.Layer.Grid.prototype.queueTileDraw;\n\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var layer; \n\n    var name = 'Test Layer';\n    var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n    var params = { map: '/mapdata/vmap_wms.map', \n                   layers: 'basic', \n                   format: 'image/png'};\n\n    \n    function test_Layer_WrapDateLine_adjustBounds(t) {\n        t.plan(10);\n        \n        \n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS(name, url, params, {'wrapDateLine':true});\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        var bounds = layer.adjustBounds(new OpenLayers.Bounds(-270,-90,-180,0));\n        t.ok( bounds.equals(new OpenLayers.Bounds(90,-90,180,0)), \"-270,-90,-180,0 wraps to 90,-90,180,0\");\n        bounds = layer.adjustBounds(new OpenLayers.Bounds(180,-90,270,0));\n        t.ok( bounds.equals(new OpenLayers.Bounds(-180,-90,-90,0)), \"180,-90,270,0 wraps to -180,-90,-90,0\");\n        bounds = layer.adjustBounds(new OpenLayers.Bounds(-180,-90,0,0));\n        t.ok( bounds.equals(new OpenLayers.Bounds(-180,-90,0,0)), \"-180,-90,0,0 doesn't wrap\");\n        bounds = layer.adjustBounds(new OpenLayers.Bounds(-181,-90,-179,0));\n        t.ok( bounds.equals(new OpenLayers.Bounds(-181,-90,-179,0)), \"-181,-90,-179,0 doesn't wrap, because it straddles the dateline\");\n        bounds = layer.adjustBounds(new OpenLayers.Bounds(-180,-180,-90,-90));\n        t.ok( bounds.equals(new OpenLayers.Bounds(-180,-180,-90,-90)), \"-180,-180,-90,-90 doesn't wrap, because we don't wrap lats.\");\n        layer = new OpenLayers.Layer.WMS(name, url, params);\n        map.addLayer(layer);\n        var testBounds = null;\n        var outBounds = null;\n        var testList = [\n          new OpenLayers.Bounds(-270,-90,-180,0),\n          new OpenLayers.Bounds(180,-90,270,0),\n          new OpenLayers.Bounds(-180,-90,0,0),\n          new OpenLayers.Bounds(-181,-90,-179,0),\n          new OpenLayers.Bounds(-180,-180,-90,-90)\n        ];          \n        for (var i = 0; i < testList.length; i++) {\n            outBounds = layer.adjustBounds(testList[i]);\n            t.ok( outBounds.equals(testList[i]), testList[i]+\" doesn't wrap in non-wrapping layer.\");\n        }\n        map.destroy();\n    }\n    function test_Layer_WrapDateLine_getLonLat(t) {\n        t.plan(12);\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS(name, url, params, {'wrapDateLine':true});\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        var testLonLats = [\n            new OpenLayers.LonLat(-185,5),\n            new OpenLayers.LonLat(-180,-95),\n            new OpenLayers.LonLat(-180,95),\n            new OpenLayers.LonLat(180,-95),\n            new OpenLayers.LonLat(180,95),\n            new OpenLayers.LonLat(185,5)\n        ];\n        var outLonLats = [\n            new OpenLayers.LonLat(175,5),\n            new OpenLayers.LonLat(-180,-95),\n            new OpenLayers.LonLat(-180,95),\n            new OpenLayers.LonLat(180,-95),\n            new OpenLayers.LonLat(180,95),\n            new OpenLayers.LonLat(-175,5)\n        ];    \n            \n        for (var i = 0; i < testLonLats.length; i++) {\n            var pixel = layer.getViewPortPxFromLonLat(testLonLats[i]);\n            var lonlat = layer.getLonLatFromViewPortPx(pixel);\n            lonlat.lon = Math.round(lonlat.lon);\n            lonlat.lat = Math.round(lonlat.lat);\n            t.ok(outLonLats[i].equals(lonlat), testLonLats[i] + \" wraps to \" + outLonLats[i]+ \" (what happened: \" + lonlat + \")\");   \n        }\n        \n        layer = new OpenLayers.Layer.WMS(name, url, params);\n        map.addLayer(layer);\n        var outLonLats = [\n            new OpenLayers.LonLat(-185,5),\n            new OpenLayers.LonLat(-180,-95),\n            new OpenLayers.LonLat(-180,95),\n            new OpenLayers.LonLat(180,-95),\n            new OpenLayers.LonLat(180,95),\n            new OpenLayers.LonLat(185,5)\n        ];    \n        for (var i = 0; i < testLonLats.length; i++) {\n            var pixel = layer.getViewPortPxFromLonLat(testLonLats[i]);\n            var lonlat = layer.getLonLatFromViewPortPx(pixel);\n            lonlat.lon = Math.round(lonlat.lon);\n            lonlat.lat = Math.round(lonlat.lat);\n            t.ok(outLonLats[i].equals(lonlat), testLonLats[i] + \" wraps to \" + outLonLats[i]+ \" (what happened: \" + lonlat + \")\");   \n        }\n        map.destroy();\n        \n    }\n    function test_Layer_WrapDateLine_ZoomToExtent (t) {\n        t.plan( 4 );\n\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.WMS(name, url, params, {'wrapDateLine':true});\n        var m = new OpenLayers.Map('map');\n        m.addLayer(layer);\n        m.setCenter = function(myCenter) { this.center = myCenter; }\n        var testBounds = [\n            new OpenLayers.Bounds(-185,-90,-175,-85),\n            new OpenLayers.Bounds(0,-90,-170,-85),\n            new OpenLayers.Bounds(-270,-90,-180,-85),\n            new OpenLayers.Bounds(0,0,45,45)\n        ];\n        var outCenters = [\n            new OpenLayers.LonLat(-180,-87.5),\n            new OpenLayers.LonLat(95,-87.5),\n            new OpenLayers.LonLat(135,-87.5),\n            new OpenLayers.LonLat(22.5,22.5)\n        ];\n        for (var i = 0; i < testBounds.length; i++) {\n            m.zoomToExtent(testBounds[i]);\n            t.ok(m.center.equals(outCenters[i]), \"Map center from bounds \" + testBounds[i] + \" should be \" + outCenters[i] + \", got \" + m.center);  \n        }\n        m.destroy();\n        \n    \n    }\n    function test_Layer_WrapDateLine_WMS (t) {\n        t.plan( 4 );\n\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.WMS(name, url, params, {'wrapDateLine':true,encodeBBOX:true, buffer: 2});\n        var m = new OpenLayers.Map('map', {tileManager: null, adjustZoom: function(z) {return z;}});\n        m.addLayer(layer);\n        m.zoomToMaxExtent();\n        t.eq(layer.grid[3][0].url, \"http://octo.metacarta.com/cgi-bin/mapserv?MAP=%2Fmapdata%2Fvmap_wms.map&LAYERS=basic&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=0%2C-90%2C180%2C90&WIDTH=256&HEIGHT=256\", \"cell [3][0] is wrapped around the world.\");\n        t.eq(layer.grid[3][1].url, \"http://octo.metacarta.com/cgi-bin/mapserv?MAP=%2Fmapdata%2Fvmap_wms.map&LAYERS=basic&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=-180%2C-90%2C0%2C90&WIDTH=256&HEIGHT=256\", \"cell [3][1] is wrapped around the world.\");\n        t.eq(layer.grid[3][2].url, \"http://octo.metacarta.com/cgi-bin/mapserv?MAP=%2Fmapdata%2Fvmap_wms.map&LAYERS=basic&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=0%2C-90%2C180%2C90&WIDTH=256&HEIGHT=256\", \"cell [3][2] is not wrapped at all.\");\n        t.ok(layer.grid[0][2].url == null, \"no latitudinal wrapping - tile not loaded if outside maxExtent\");\n        m.destroy();\n\n    }\n    function test_Layer_WrapDateLine_KaMap (t) {\n        t.plan( 4 );\n\n        var layer = new OpenLayers.Layer.KaMap( \"Blue Marble NG\",\n             \"http://www.openlayers.org/world/index.php\",\n             {g: \"satellite\", map: \"world\"},\n             {wrapDateLine: true, buffer: 2} ); \n        var m = new OpenLayers.Map('map', {tileManager: null, adjustZoom: function(z) {return z;}});\n        m.addLayer(layer);\n        m.zoomToMaxExtent();\n        t.eq(layer.grid[4][7].url, \"http://www.openlayers.org/world/index.php?g=satellite&map=world&i=jpeg&t=0&l=-256&s=221471921.25\", \"grid[5][7] kamap is okay\");\n        t.eq(layer.grid[4][6].url, \"http://www.openlayers.org/world/index.php?g=satellite&map=world&i=jpeg&t=0&l=0&s=221471921.25\", \"grid[5][6] kamap is okay\");\n        t.eq(layer.grid[4][5].url, \"http://www.openlayers.org/world/index.php?g=satellite&map=world&i=jpeg&t=0&l=-256&s=221471921.25\", \"grid[5][5] is okay\");\n        t.ok(layer.grid[7][6].url == null, \"no latitudinal wrapping - tile not loaded if outside maxExtent\");\n        m.destroy();\n    }\n    function test_Layer_WrapDateLine_WMS_Overlay (t) {\n        t.plan( 4 );\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        baselayer = new OpenLayers.Layer.WMS(name, url, params, {'wrapDateLine':true, buffer: 2});\n        var layer = new OpenLayers.Layer.WMS( \"DM Solutions Demo\",\n            \"http://www2.dmsolutions.ca/cgi-bin/mswms_gmap\",\n            {layers: \"bathymetry,land_fn,park,drain_fn,drainage,\" +\n                     \"prov_bound,fedlimit,rail,road,popplace\",\n             transparent: \"true\", format: \"image/png\"},\n            {wrapDateLine: true, encodeBBOX:true, buffer:2});\n        var m = new OpenLayers.Map('map', {tileManager: null, adjustZoom: function(z) {return z;}});\n        m.addLayers([baselayer,layer]);\n        m.zoomToMaxExtent();\n        t.eq(layer.grid[3][0].url, \"http://www2.dmsolutions.ca/cgi-bin/mswms_gmap?LAYERS=bathymetry%2Cland_fn%2Cpark%2Cdrain_fn%2Cdrainage%2Cprov_bound%2Cfedlimit%2Crail%2Croad%2Cpopplace&TRANSPARENT=true&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=0%2C-90%2C180%2C90&WIDTH=256&HEIGHT=256\", \"grid[0][0] wms overlay is okay\");\n        t.eq(layer.grid[3][1].url, \"http://www2.dmsolutions.ca/cgi-bin/mswms_gmap?LAYERS=bathymetry%2Cland_fn%2Cpark%2Cdrain_fn%2Cdrainage%2Cprov_bound%2Cfedlimit%2Crail%2Croad%2Cpopplace&TRANSPARENT=true&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=-180%2C-90%2C0%2C90&WIDTH=256&HEIGHT=256\", \"grid[0][3] wms overlay is okay\");\n        t.eq(layer.grid[3][2].url, \"http://www2.dmsolutions.ca/cgi-bin/mswms_gmap?LAYERS=bathymetry%2Cland_fn%2Cpark%2Cdrain_fn%2Cdrainage%2Cprov_bound%2Cfedlimit%2Crail%2Croad%2Cpopplace&TRANSPARENT=true&FORMAT=image%2Fpng&SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&STYLES=&SRS=EPSG%3A4326&BBOX=0%2C-90%2C180%2C90&WIDTH=256&HEIGHT=256\", \"grid[3][0] wms overlay okay\");\n        t.ok(layer.grid[0][2].url == null, \"no latitudinal wrapping - tile not loaded if outside maxExtent\");\n        m.destroy();\n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:1000px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/XYZ.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var layer; \n\n    var name = 'Test Layer';\n    var url = \"http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/${z}/${x}/${y}.png\";\n    var options = {'layername':'basic', 'type':'png'}; \n\n\n    function test_Layer_XYZ_constructor (t) {\n        t.plan( 1 );\n                       \n        layer = new OpenLayers.Layer.XYZ(name, url, options);\n        t.ok( layer instanceof OpenLayers.Layer.XYZ, \"returns OpenLayers.Layer.XYZ object\" );\n    }\n\n\n\n    function test_Layer_XYZ_clearTiles (t) {\n        t.plan( 1 );\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.XYZ(name, url, options);\n        map.addLayer(layer);\n\n        map.setCenter(new OpenLayers.LonLat(0,0));\n\n        //grab a reference to one of the tiles\n        var tile = layer.grid[0][0];        \n\n        layer.clearGrid();\n\n        t.ok( layer.grid != null, \"layer.grid does not get nullified\" );\n        map.destroy();\n    }\n\n\n    function test_Layer_XYZ_getXYZBounds(t) {\n        t.plan( 1 );\n\n        layer = new OpenLayers.Layer.XYZ(name, url, options);\n\n        var bl = { bounds: new OpenLayers.Bounds(1,2,2,3)};\n        var tr = { bounds: new OpenLayers.Bounds(2,3,3,4)};\n        layer.grid = [ [6, tr], \n                       [bl, 7]];\n\n        var bounds = layer.getTilesBounds();\n    \n        var testBounds = new OpenLayers.Bounds(1,2,3,4);\n        \n        t.ok( bounds.equals(testBounds), \"getXYZBounds() returns correct bounds\")\n        \n        layer.grid = null;\n    }\n\n    function test_Layer_XYZ_getResolution(t) {\n        t.plan( 1 );\n\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.XYZ(name, url, options);\n        map.addLayer(layer);\n\n        map.zoom = 5;\n\n        t.eq( layer.getResolution(), 0.0439453125, \"getResolution() returns correct value\");\n        map.destroy();\n    }\n\n    function test_Layer_XYZ_getZoomForExtent(t) {\n        t.plan( 2 );\n        var bounds, zoom;\n\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.XYZ(name, url, options);\n        map.addLayer(layer);\n\n        bounds = new OpenLayers.Bounds(10,10,12,12);\n        zoom = layer.getZoomForExtent(bounds);\n\n        t.eq( zoom, 8, \"getZoomForExtent() returns correct value\");\n\n        bounds = new OpenLayers.Bounds(10,10,100,100);\n        zoom = layer.getZoomForExtent(bounds);\n\n        t.eq( zoom, 2, \"getZoomForExtent() returns correct value\");\n        map.destroy();\n    }   \n\n\n    /** THIS WOULD BE WHERE THE TESTS WOULD GO FOR \n     *     \n     *    -moveTo\n     *    -insertColumn\n     *    -insertRow\n    \n    function 07_Layer_XYZ_moveTo(t) {\n    }\n\n    function 08_Layer_XYZ_insertColumn(t) {\n    }\n\n    function 09_Layer_XYZ_insertRow(t) {\n    }\n\n     * \n     */\n    function test_Layer_XYZ_getURL(t) {\n\n        t.plan(6);\n        \n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.XYZ(name, url);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 9);\n        var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125));\n        t.eq(tileurl, \"http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/261/63.png\", \"Tile URL is correct\");\n    \n        layer.url = [\"http://tilecache1/\", \"http://tilecache2/\", \"http://tilecache3/\"];\n        tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125));\n        t.eq(tileurl, \"http://tilecache1/\", \"Tile URL is deterministic\");\n\n        layer.url = url;\n        tileurl = layer.getURL(new OpenLayers.Bounds(180.515625,45,181.21875,45.703125));\n        t.eq(tileurl, \"http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/513/63.png\", \"Tile URL is correct\");\n        tileurl = layer.getURL(new OpenLayers.Bounds(-181.515625,45,-180.21875,45.703125));\n        t.eq(tileurl, \"http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/-2/63.png\", \"Tile URL is correct\");\n        layer.wrapDateLine = true;\n        tileurl = layer.getURL(new OpenLayers.Bounds(180.515625,45,181.21875,45.703125));\n        t.eq(tileurl, \"http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/1/63.png\", \"Tile URL is correct\");\n        tileurl = layer.getURL(new OpenLayers.Bounds(-181.515625,45,-180.21875,45.703125));\n        t.eq(tileurl, \"http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/510/63.png\", \"Tile URL is correct\");\n        map.destroy();\n    }\n    function test_Layer_XYZ_Rounding(t) {\n        t.plan(1);\n            m = new OpenLayers.Map(\"map\", {'maxExtent':new OpenLayers.Bounds(-122.6579,37.4901,-122.0738,37.8795)});\n            layer = new OpenLayers.Layer.XYZ( \"XYZ\", \n                    url, {layername: 'basic', type:'png', resolutions:[0.000634956337608418], buffer: 2} );\n            m.addLayer(layer);\n            m.zoomToMaxExtent()\n            t.eq(layer.getURL(layer.grid[3][3].bounds), \"http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/0/1/1.png\", \"XYZ tiles around rounded properly.\");\n        m.destroy();\n    }        \n            \n    function test_Layer_XYZ_setMap(t) {\n\n        t.plan(3);\n        \n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.XYZ(name, url);\n\n        t.eq(layer.tileOrigin, null, \"Tile origin starts out null\");\n        layer.setMap(map);\n        \n        t.eq(layer.tileOrigin.lat, 90, \"lat is 90\");\n        t.eq(layer.tileOrigin.lon, -180, \"lon is -180\");\n        map.destroy();\n    }\n\n    function test_Layer_XYZ_serverResolutions(t) {\n        t.plan(2);\n\n        var map = new OpenLayers.Map('map', {\n            resolutions: [13,11]\n        });\n\n        var layer = new OpenLayers.Layer.XYZ(name, url, options);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 1);\n\n        var tileurl = layer.getURL(new OpenLayers.Bounds(0,0,0,0));\n        var level = parseInt(tileurl.split('/')[7]);\n        t.eq(map.getZoom(), level, \"Tile zoom level is correct without serverResolutions\");\n\n        layer.serverResolutions = [14,13,12,11,10];\n        tileurl = layer.getURL(new OpenLayers.Bounds(0,0,0,0));\n        level = parseInt(tileurl.split('/')[7]);\n        var res = map.getResolution();\n        var gotLevel = OpenLayers.Util.indexOf(layer.serverResolutions, res);\n        t.eq(gotLevel, level, \"Tile zoom level is correct with serverResolutions\");\n\n        map.destroy();\n    }\n\n    function test_zoomOffset(t) {\n\n        t.plan(2);\n        \n        var offset;\n        \n        // test offset of 2\n        offset = 2;\n        \n        var map = new OpenLayers.Map({\n            div: \"map\",\n            maxResolution: 1.40625 / Math.pow(2, offset)\n        });\n        var layer = new OpenLayers.Layer.XYZ(name, url, {zoomOffset: offset});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 7);\n\n        var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125));\n        t.eq(tileurl, \"http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/261/63.png\", \"correct URL for offset of 2\");\n\n        map.destroy();\n\n        // test offset of -1\n        offset = -1;\n        \n        var map = new OpenLayers.Map({\n            div: \"map\",\n            maxResolution: 1.40625 / Math.pow(2, offset)\n        });\n        var layer = new OpenLayers.Layer.XYZ(name, url, {zoomOffset: offset});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 10);\n\n        var tileurl = layer.getURL(new OpenLayers.Bounds(3.515625,45,4.21875,45.703125));\n        t.eq(tileurl, \"http://labs.metacarta.com/wms-c/Basic.py/1.0.0/basic/9/261/63.png\", \"correct URL for offset of -1\");\n\n        map.destroy();\n\n\n    }\n\n    function test_Layer_XYZ_destroy (t) {\n\n        t.plan( 3 );\n\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.XYZ(name, url, options);\n        map.addLayer(layer);\n        layer.destroy();\n        t.eq( layer.grid, null, \"layer.grid is null after destroy\" );\n        t.eq( layer.tileSize, null, \"layer.tileSize is null after destroy\" );\n\n\n    //test with tile creation\n        layer = new OpenLayers.Layer.XYZ(name, url, options);\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 5);\n        //grab a reference to one of the tiles\n        var tile = layer.grid[0][0];        \n\n        layer.destroy();\n\n        t.ok( layer.grid == null, \"tiles appropriately destroyed\");\n        map.destroy();\n    }\n    \n    function test_clone(t) {\n        t.plan(1);\n        \n        layer = new OpenLayers.Layer.XYZ(name, url, options);\n        var clone = layer.clone();\n        t.ok(clone instanceof OpenLayers.Layer.XYZ, \"clone is a Layer.XYZ instance\");\n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/atom-1.0.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<feed xmlns=\"http://www.w3.org/2005/Atom\"\n      xmlns:georss=\"http://www.georss.org/georss\">\n\n  <title>tumulus</title>\n  <link rel=\"self\"\n        href=\"http://pleiades.stoa.org/places/tumulus\"/>\n  <updated/>\n  <author/>\n  <id>http://pleiades.stoa.org/places/tumulus</id>\n    \n  <entry>\n    <title>Unnamed Tumulus</title>\n    <link rel=\"alternate\"\n          href=\"http://pleiades.stoa.org/places/638896\"\n    />\n    <id>http://pleiades.stoa.org/places/638896</id>\n    <updated/>\n    <summary>An ancient tumulus, attested during the Classical period (modern location: Karaburun). Its ancient name is not known.</summary>\n    <georss:point>36.7702 29.9805</georss:point>\n  </entry>\n  <entry>\n    <title>Unnamed Tumulus</title>\n    <link rel=\"alternate\"\n          href=\"http://pleiades.stoa.org/places/638924\"\n    />\n    <id>http://pleiades.stoa.org/places/638924</id>\n    <updated/>\n    <summary>An ancient tumulus, attested during the Classical period (modern location: Kızılbel). Its ancient name is not known.</summary>\n    <georss:point>36.7263 29.8619</georss:point>\n  </entry>\n  \n</feed>\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/data_Layer_Text_textfile.txt",
    "content": "point\timage\n10,20\thttp://boston.openguides.org/markers/ORANGE.png\n15,25\thttp://boston.openguides.org/markers/ORANGE.png\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/data_Layer_Text_textfile_2.txt",
    "content": "point\ttitle\tdescription\timage\n10,20\ta\tb\thttp://boston.openguides.org/markers/ORANGE.png\n15,25\tc\td\thttp://boston.openguides.org/markers/ORANGE.png\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/data_Layer_Text_textfile_overflow.txt",
    "content": "overflow\tpoint\ttitle\tdescription\timage\nauto\t10,20\ta\tb\thttp://boston.openguides.org/markers/ORANGE.png\nhidden\t15,25\tc\td\thttp://boston.openguides.org/markers/ORANGE.png\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer/georss.txt",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><?xml-stylesheet type=\"text/css\" href=\"/css/rss.css\" ?>\n\n<rdf:RDF  xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n  xmlns=\"http://purl.org/rss/1.0/\"\n  xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n  xmlns:georss=\"http://www.georss.org/georss\">\n<docs>This is an RSS file.  Copy the URL into your aggregator of choice.  If you don't know what this means and want to learn more, please see: <span>http://platial.typepad.com/news/2006/04/really_simple_t.html</span> for more info.</docs><channel rdf:about=\"http://platial.com\">\n<link>http://platial.com</link>\n<title>Crschmidt's Places At Platial</title>\n<description></description>\n<items>\n<rdf:Seq>\n<rdf:li resource=\"http://platial.com/place/90306\"/>\n<rdf:li resource=\"http://platial.com/place/67230\"/>\n<rdf:li resource=\"http://platial.com/place/65645\"/>\n<rdf:li resource=\"http://platial.com/place/62200\"/>\n<rdf:li resource=\"http://platial.com/place/28232\"/>\n<rdf:li resource=\"http://platial.com/place/43666\"/>\n<rdf:li resource=\"http://platial.com/place/28394\"/>\n<rdf:li resource=\"http://platial.com/place/28251\"/>\n<rdf:li resource=\"http://platial.com/place/28392\"/>\n<rdf:li resource=\"http://platial.com/place/28391\"/>\n<rdf:li resource=\"http://platial.com/place/28231\"/>\n<rdf:li resource=\"http://platial.com/place/28393\"/>\n<rdf:li resource=\"http://platial.com/place/31685\"/>\n<rdf:li resource=\"http://platial.com/place/28596\"/>\n<rdf:li resource=\"http://platial.com/place/28595\"/>\n<rdf:li resource=\"http://platial.com/place/28594\"/>\n<rdf:li resource=\"http://platial.com/place/28593\"/>\n<rdf:li resource=\"http://platial.com/place/28592\"/>\n<rdf:li resource=\"http://platial.com/place/28591\"/>\n<rdf:li resource=\"http://platial.com/place/28590\"/>\n<rdf:li resource=\"http://platial.com/place/28589\"/>\n<rdf:li resource=\"http://platial.com/place/28588\"/>\n<rdf:li resource=\"http://platial.com/place/28587\"/>\n<rdf:li resource=\"http://platial.com/place/28586\"/>\n<rdf:li resource=\"http://platial.com/place/28585\"/>\n<rdf:li resource=\"http://platial.com/place/28584\"/>\n<rdf:li resource=\"http://platial.com/place/28583\"/>\n<rdf:li resource=\"http://platial.com/place/28582\"/>\n<rdf:li resource=\"http://platial.com/place/28581\"/>\n<rdf:li resource=\"http://platial.com/place/28580\"/>\n<rdf:li resource=\"http://platial.com/place/28579\"/>\n<rdf:li resource=\"http://platial.com/place/28578\"/>\n<rdf:li resource=\"http://platial.com/place/28577\"/>\n<rdf:li resource=\"http://platial.com/place/28576\"/>\n<rdf:li resource=\"http://platial.com/place/28575\"/>\n<rdf:li resource=\"http://platial.com/place/28574\"/>\n<rdf:li resource=\"http://platial.com/place/28573\"/>\n<rdf:li resource=\"http://platial.com/place/28572\"/>\n<rdf:li resource=\"http://platial.com/place/28571\"/>\n<rdf:li resource=\"http://platial.com/place/28570\"/>\n</rdf:Seq>\n</items>\n</channel>\n<item rdf:about=\"http://platial.com/place/90306\">\n<link>http://platial.com/place/90306</link>\n<title>Knitting Room</title>\n<description><![CDATA[This little shop is jammed full. Yarn, yarn everywhere. They make the most of every possible nook and cranny. I like this place also because they have a lot of different kinds of knitting needles in all different sizes. Also, the people who work here are younger and hipper than in the other stores I go to. I reccomend buying supplies here and then knitting your way through a good documentary at the Capitol Theater across the street.<br/>Address: 2 lake St, Arlington, MA <br/>Tags: knitting, yarn, pins and needles, handspun, hand dyed, novelty yarn, fancy, simple, young, hip, friendly, needles, addy, cute hats<br /><br /><a href=\"http://platial.com/place/90306\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/90306\">Grab this on Platial</a> ]]></description>\n<georss:point>42.405696 -71.142197</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-06-08T17:35:01.942452+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/67230\">\n<link>http://platial.com/place/67230</link>\n<title>Knitting Room</title>\n<description><![CDATA[This little shop is jammed full. Yarn, yarn everywhere. They make the most of every possible nook and cranny. I like this place also because they have a lot of different kinds of knitting needles in all different sizes. Also, the people who work here are younger and hipper than in the other stores I go to. I reccomend buying supplies here and then knitting your way through a good documentary at the Capitol Theater across the street.<br/>Address: 2 lake St, Arlington, MA <br/>Tags: knitting, yarn, pins and needles, handspun, hand dyed, novelty yarn, fancy, simple, young, hip, friendly, needles, addy, cute hats<br /><br /><a href=\"http://platial.com/place/67230\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/67230\">Grab this on Platial</a> ]]></description>\n<georss:point>42.405524 -71.142273</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-04-24T11:35:26.733857+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/65645\">\n<link>http://platial.com/place/65645</link>\n<title>â Â¢Â¢â¢Â£ËÃ¸Å</title>\n<description><![CDATA[ijeÂªÂ£âÂµËËÃ®<br/>Address: 151 Erie St., Cambridge, MA<br/>Tags: platial graffiti<br /><br /><a href=\"http://platial.com/place/65645\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/65645\">Grab this on Platial</a> ]]></description>\n<georss:point>42.352455 -71.110210</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-04-20T08:56:12.696224+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/62200\">\n<link>http://platial.com/place/62200</link>\n<title>Allen Hall</title>\n<description><![CDATA[My dorm at UIUC.<br/>Address: 1301 W Gregory Dr, Urbana, IL<br/>Tags: dorm, uiuc, college<br/><a href=\"http://platial.com/place/62200\"><img src=\"http://platial.comhttp://static.flickr.com/4/8576450_0d59cc2531_s.jpg\"/></a><br/><br /><br /><a href=\"http://platial.com/place/62200\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/62200\">Grab this on Platial</a> ]]></description>\n<georss:point>40.104172 -88.220623</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-04-14T08:01:01.872873+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28232\">\n<link>http://platial.com/place/28232</link>\n<title>Bagby Hot Springs, OR</title>\n<description><![CDATA[Hot spring, temperature: 136  degress F, 58  degress C. However, the area around the springs are not exactly well looked upon by people who know the place.\n\n<br/>Tags: 20s, rosalie, romance, childhood, hike, camping, soak, relax, beautiful, hot springs, bathhouse, favorite, popular, crowded, organized, honeymoon tub, plumbing made from hollowed out trees, hot springs, mt hood, notorious car break in spot, rash, bacteria<br /><br /><a href=\"http://platial.com/place/28232\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28232\">Grab this on Platial</a> ]]></description>\n<georss:point>44.936000 -122.173000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:10:18.553063+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/43666\">\n<link>http://platial.com/place/43666</link>\n<title>Shooting Location for \"The Field of Dreams\" Film</title>\n<description><![CDATA[1989's Field of Dreams was a Best Picture Academy Award nominee, and the baseball field in the cornfield still stands today, and has become quite a tourist destination.  Games are occasionally played at the field, re-enacting professional baseball at the turn of the 20th Century.<br/>Address: Dyersville, Iowa<br/>Tags: iowa, baseball, movie locations, field of dreams, kevin costner, costner, dyersville, kinsella, james earl jones, chicago black sox, shoeless joe, joe jackson, famous farms, film, movie, cinema, shooting location<br /><br /><a href=\"http://platial.com/place/43666\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/43666\">Grab this on Platial</a> ]]></description>\n<georss:point>42.481213 -91.111679</georss:point>\n<dc:creator>echinodermata</dc:creator>\n<dc:date>2006-03-23T11:40:17.654061+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28394\">\n<link>http://platial.com/place/28394</link>\n<title>Moffetts (Bonneville) Hot Springs, WA</title>\n<description><![CDATA[Hot spring, temperature: 97  degress F, 36  degress C<br/>Tags: soak, hot springs, relax, nature<br /><br /><a href=\"http://platial.com/place/28394\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28394\">Grab this on Platial</a> ]]></description>\n<georss:point>45.658000 -121.962000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:16:27.329816+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28251\">\n<link>http://platial.com/place/28251</link>\n<title>Austin Hot Springs, OR</title>\n<description><![CDATA[Hot spring, temperature: 186  degress F, 86  degress C<br/>Tags: soak, hot springs, relax, nature, popular, crowded<br /><br /><a href=\"http://platial.com/place/28251\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28251\">Grab this on Platial</a> ]]></description>\n<georss:point>45.021000 -122.009000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:11:04.489886+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28392\">\n<link>http://platial.com/place/28392</link>\n<title>Rock Creek Hot Springs, WA</title>\n<description><![CDATA[Hot spring, temperature: Hot  degress F, Hot  degress C<br/>Tags: soak, hot springs, relax, nature<br /><br /><a href=\"http://platial.com/place/28392\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28392\">Grab this on Platial</a> ]]></description>\n<georss:point>45.723000 -121.927000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:16:22.636855+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28391\">\n<link>http://platial.com/place/28391</link>\n<title>St. Martins (Wind River) Hot Springs, WA</title>\n<description><![CDATA[Hot spring, temperature: 120  degress F, 49  degress C<br/>Tags: hot springs, soak, relax, nature, wonderful<br /><br /><a href=\"http://platial.com/place/28391\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28391\">Grab this on Platial</a> ]]></description>\n<georss:point>45.728000 -121.800000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:16:20.383244+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28231\">\n<link>http://platial.com/place/28231</link>\n<title>Breitenbush Hot Springs, OR</title>\n<description><![CDATA[Hot spring, temperature: 198  degress F, 92  degress C<br/>Tags: hot springs, resort, relax, nature, beautiful, http:www.breitenbush.com, soaking<br /><br /><a href=\"http://platial.com/place/28231\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28231\">Grab this on Platial</a> ]]></description>\n<georss:point>44.782000 -121.975000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:10:16.529195+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28393\">\n<link>http://platial.com/place/28393</link>\n<title>Collins Hot Springs, WA</title>\n<description><![CDATA[Hot spring, temperature: 122  degress F, 50  degress C<br/>Tags: portland, nice, hot springs, soak<br /><br /><a href=\"http://platial.com/place/28393\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28393\">Grab this on Platial</a> ]]></description>\n<georss:point>45.701000 -121.728000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:16:24.648745+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/31685\">\n<link>http://platial.com/place/31685</link>\n<title>Darwin's Ltd.</title>\n<description><![CDATA[Nice little coffee shop/cafe, free Wifi, close enough to walk from Harvard Square.<br/>Address: 148 Mount Auburn St, Cambridge, MA<br/>Tags: coffee, beer, sandwiches, freewifi<br/><a href=\"http://platial.com/place/31685\"><img src=\"http://platial.comhttp://static.flickr.com/38/84885937_74fd3d1025_s.jpg\"/></a><br/><br /><br /><a href=\"http://platial.com/place/31685\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/31685\">Grab this on Platial</a> ]]></description>\n<georss:point>42.373974 -71.125053</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-10T09:24:08.152985+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28596\">\n<link>http://platial.com/place/28596</link>\n<title>Huckleberry Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: Boiling  degress F, Boiling  degress C<br /><br /><a href=\"http://platial.com/place/28596\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28596\">Grab this on Platial</a> ]]></description>\n<georss:point>44.115000 -110.684000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:32.283094+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28595\">\n<link>http://platial.com/place/28595</link>\n<title>South Entrance Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: 156  degress F, 69  degress C<br/><a href=\"http://platial.com/place/28595\"><img src=\"http://platial.comhttp://static.flickr.com/52/130989872_f1457f68b5_s.jpg\"/></a><br/><br /><br /><a href=\"http://platial.com/place/28595\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28595\">Grab this on Platial</a> ]]></description>\n<georss:point>44.142000 -110.656000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:30.279497+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28594\">\n<link>http://platial.com/place/28594</link>\n<title>Crawfish Creek Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: 136  degress F, 58  degress C<br/><a href=\"http://platial.com/place/28594\"><img src=\"http://platial.comhttp://static.flickr.com/52/128312256_d6a879924c_s.jpg\"/></a><br/><br /><br /><a href=\"http://platial.com/place/28594\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28594\">Grab this on Platial</a> ]]></description>\n<georss:point>44.157000 -110.699000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:28.280271+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28593\">\n<link>http://platial.com/place/28593</link>\n<title>Crawfish Creek Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: 138  degress F, 59  degress C<br /><br /><a href=\"http://platial.com/place/28593\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28593\">Grab this on Platial</a> ]]></description>\n<georss:point>44.165000 -110.723000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:20.364077+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28592\">\n<link>http://platial.com/place/28592</link>\n<title>Snake Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: 136  degress F, 58  degress C<br /><br /><a href=\"http://platial.com/place/28592\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28592\">Grab this on Platial</a> ]]></description>\n<georss:point>44.169000 -110.583000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:12.234974+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28591\">\n<link>http://platial.com/place/28591</link>\n<title>Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: 142  degress F, 61  degress C<br /><br /><a href=\"http://platial.com/place/28591\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28591\">Grab this on Platial</a> ]]></description>\n<georss:point>44.187000 -110.726000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:10.027857+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28590\">\n<link>http://platial.com/place/28590</link>\n<title>Hot Springs on Upper Snake River, WY</title>\n<description><![CDATA[Hot spring, temperature: 167  degress F, 75  degress C<br /><br /><a href=\"http://platial.com/place/28590\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28590\">Grab this on Platial</a> ]]></description>\n<georss:point>44.204000 -110.486000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:07.79658+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28589\">\n<link>http://platial.com/place/28589</link>\n<title>Hot Springs on lewis Lake, WY</title>\n<description><![CDATA[Hot spring, temperature: 154  degress F, 68  degress C<br /><br /><a href=\"http://platial.com/place/28589\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28589\">Grab this on Platial</a> ]]></description>\n<georss:point>44.276000 -110.636000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:05.683418+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28588\">\n<link>http://platial.com/place/28588</link>\n<title>Rustic Geyser, WY</title>\n<description><![CDATA[Hot spring, temperature: 199  degress F, 93  degress C<br /><br /><a href=\"http://platial.com/place/28588\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28588\">Grab this on Platial</a> ]]></description>\n<georss:point>44.282000 -110.506000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:03.66329+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28587\">\n<link>http://platial.com/place/28587</link>\n<title>Bechler River Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: 194  degress F, 90  degress C<br /><br /><a href=\"http://platial.com/place/28587\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28587\">Grab this on Platial</a> ]]></description>\n<georss:point>44.285000 -110.900000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:01.611442+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28586\">\n<link>http://platial.com/place/28586</link>\n<title>Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: Boiling  degress F, 201  degress C<br /><br /><a href=\"http://platial.com/place/28586\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28586\">Grab this on Platial</a> ]]></description>\n<georss:point>44.290000 -110.504000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:59.658699+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28585\">\n<link>http://platial.com/place/28585</link>\n<title>Heart Lake Geyser Basin, WY</title>\n<description><![CDATA[Hot spring, temperature:  Middle Group  degress F, 174  degress C<br /><br /><a href=\"http://platial.com/place/28585\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28585\">Grab this on Platial</a> ]]></description>\n<georss:point>44.299000 -110.517000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:57.181801+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28584\">\n<link>http://platial.com/place/28584</link>\n<title>Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: Boiling  degress F, 201  degress C<br /><br /><a href=\"http://platial.com/place/28584\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28584\">Grab this on Platial</a> ]]></description>\n<georss:point>44.307000 -110.526000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:55.240485+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28583\">\n<link>http://platial.com/place/28583</link>\n<title>Hot Springs on lewis Lake, WY</title>\n<description><![CDATA[Hot spring, temperature: 199  degress F, 93  degress C<br /><br /><a href=\"http://platial.com/place/28583\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28583\">Grab this on Platial</a> ]]></description>\n<georss:point>44.309000 -110.654000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:53.22295+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28582\">\n<link>http://platial.com/place/28582</link>\n<title>Shoshone Geyser Basin, WY</title>\n<description><![CDATA[Hot spring, temperature: 203  degress F, 95  degress C<br /><br /><a href=\"http://platial.com/place/28582\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28582\">Grab this on Platial</a> ]]></description>\n<georss:point>44.354000 -110.800000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:51.179049+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28581\">\n<link>http://platial.com/place/28581</link>\n<title>Hot Springs on Continental Divide, WY</title>\n<description><![CDATA[Hot spring, temperature: 189  degress F, 87  degress C<br /><br /><a href=\"http://platial.com/place/28581\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28581\">Grab this on Platial</a> ]]></description>\n<georss:point>44.401000 -110.936000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:49.077176+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28580\">\n<link>http://platial.com/place/28580</link>\n<title>Hot Springs on Upper Firehole River, WY</title>\n<description><![CDATA[Hot spring, temperature: Hot  degress F, Hot  degress C<br /><br /><a href=\"http://platial.com/place/28580\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28580\">Grab this on Platial</a> ]]></description>\n<georss:point>44.404000 -110.824000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:47.054664+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28579\">\n<link>http://platial.com/place/28579</link>\n<title>Summit Lake Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: 162  degress F, 72  degress C<br /><br /><a href=\"http://platial.com/place/28579\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28579\">Grab this on Platial</a> ]]></description>\n<georss:point>44.410000 -110.953000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:45.039394+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28578\">\n<link>http://platial.com/place/28578</link>\n<title>Lone Star Geyser Basin, WY</title>\n<description><![CDATA[Hot spring, temperature:  Footbridge  degress F, 183  degress C<br /><br /><a href=\"http://platial.com/place/28578\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28578\">Grab this on Platial</a> ]]></description>\n<georss:point>44.414000 -110.817000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:42.938808+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28577\">\n<link>http://platial.com/place/28577</link>\n<title>West. Thumb Geyser Basin, WY</title>\n<description><![CDATA[Hot spring, temperature: 203  degress F, 95  degress C<br /><br /><a href=\"http://platial.com/place/28577\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28577\">Grab this on Platial</a> ]]></description>\n<georss:point>44.417000 -110.570000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:40.90238+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28576\">\n<link>http://platial.com/place/28576</link>\n<title>Lone Star Geyser, WY</title>\n<description><![CDATA[Hot spring, temperature: 199  degress F, 93  degress C<br /><br /><a href=\"http://platial.com/place/28576\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28576\">Grab this on Platial</a> ]]></description>\n<georss:point>44.418000 -110.805000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:38.844625+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28575\">\n<link>http://platial.com/place/28575</link>\n<title>Smoke Jumper Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: 198  degress F, 92  degress C<br /><br /><a href=\"http://platial.com/place/28575\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28575\">Grab this on Platial</a> ]]></description>\n<georss:point>44.421000 -110.952000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:36.818513+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28574\">\n<link>http://platial.com/place/28574</link>\n<title>West. Thumb Geyser Basin, WY</title>\n<description><![CDATA[Hot spring, temperature: 196  degress F, 91  degress C<br /><br /><a href=\"http://platial.com/place/28574\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28574\">Grab this on Platial</a> ]]></description>\n<georss:point>44.422000 -110.574000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:34.767729+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28573\">\n<link>http://platial.com/place/28573</link>\n<title>Potts Hot Spring Basin, WY</title>\n<description><![CDATA[Hot spring, temperature: 203  degress F, 95  degress C<br /><br /><a href=\"http://platial.com/place/28573\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28573\">Grab this on Platial</a> ]]></description>\n<georss:point>44.433000 -110.581000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:32.749915+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28572\">\n<link>http://platial.com/place/28572</link>\n<title>Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: Hot  degress F, Hot  degress C<br /><br /><a href=\"http://platial.com/place/28572\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28572\">Grab this on Platial</a> ]]></description>\n<georss:point>44.433000 -110.813000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:30.829745+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28571\">\n<link>http://platial.com/place/28571</link>\n<title>Hot Springs on Continental Divide, WY</title>\n<description><![CDATA[Hot spring, temperature: Hot  degress F, Hot  degress C<br /><br /><a href=\"http://platial.com/place/28571\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28571\">Grab this on Platial</a> ]]></description>\n<georss:point>44.438000 -110.977000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:28.730401+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28570\">\n<link>http://platial.com/place/28570</link>\n<title>SouthEastern Group, WY</title>\n<description><![CDATA[Hot spring, temperature: 198  degress F, 92  degress C<br /><br /><a href=\"http://platial.com/place/28570\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28570\">Grab this on Platial</a> ]]></description>\n<georss:point>44.459000 -110.817000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:26.706763+00:00</dc:date>\n</item>\n</rdf:RDF>"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Layer.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var layer; \n\n    function test_Layer_constructor (t) {\n        t.plan( 15 );\n        \n        var options = { chicken: 151, foo: \"bar\", projection: \"none\" };\n        var layer = new OpenLayers.Layer('Test Layer', options);\n        \n        t.ok( layer instanceof OpenLayers.Layer, \"new OpenLayers.Layer returns object\" );\n        t.eq( layer.CLASS_NAME, \"OpenLayers.Layer\", \"CLASS_NAME variable set correctly\");\n\n        t.eq( layer.name, \"Test Layer\", \"layer.name is correct\" );\n        t.ok( layer.id != null, \"Layer is given an id\");\n        t.ok( layer.projection, \"none\", \"default layer projection correctly set\");\n        t.ok( ((layer.chicken == 151) && (layer.foo == \"bar\")), \"layer.options correctly set to Layer Object\" );\n        t.ok( ((layer.options[\"chicken\"] == 151) && (layer.options[\"foo\"] == \"bar\")), \"layer.options correctly backed up\" );\n\n        t.ok( typeof layer.div == \"object\" , \"layer.div is created\" );\n        t.eq( layer.div.id, layer.id, \"layer.div.id is correct\" );\n\n        options.chicken = 552;\n        \n        t.eq( layer.options[\"chicken\"], 151 , \"layer.options correctly made fresh copy\" );\n        \n        t.eq( layer.isBaseLayer, false, \"Default layer is not base layer\" );\n\n        layer = new OpenLayers.Layer('Test Layer');\n        t.ok( layer instanceof OpenLayers.Layer, \"new OpenLayers.Layer returns object\" );\n        t.eq( layer.name, \"Test Layer\", \"layer.name is correct\" );\n        t.ok( layer.projection == null, \"default layer projection correctly set\");\n        t.ok( layer.options instanceof Object, \"layer.options correctly initialized as a non-null Object\" );\n    }\n\n\n    function test_Layer_clone (t) {\n        t.plan( 7 );\n        \n        var mapone = new OpenLayers.Map('map'); \n        var options = { chicken: 151, foo: \"bar\", maxResolution: \"auto\", visibility: false };\n        var layer = new OpenLayers.Layer('Test Layer', options);\n        mapone.addLayer(layer);\n        layer.setVisibility(true);\n\n        // randomly assigned property\n        layer.chocolate = 5;\n\n        var clone = layer.clone();\n\n        t.ok( clone.map == null, \"cloned layer has map property set to null\")\n\n        var maptwo = new OpenLayers.Map('map2'); \n        maptwo.addLayer(clone);\n\n        t.ok( clone instanceof OpenLayers.Layer, \"new OpenLayers.Layer returns object\" );\n        t.eq( clone.name, \"Test Layer\", \"default clone.name is correct\" );\n        t.ok( ((clone.options[\"chicken\"] == 151) && (clone.options[\"foo\"] == \"bar\")), \"clone.options correctly set\" );\n        t.eq(clone.chocolate, 5, \"correctly copied randomly assigned property\");\n\n        t.eq(clone.visibility, true, \"visibility correctly cloned\");\n        \n        layer.addOptions({chicken:152});\n        t.eq(clone.options[\"chicken\"], 151, \"made a clean copy of options\");        \n\n        mapone.destroy();\n        maptwo.destroy();\n    }\n\n    function test_Layer_setName (t) {\n        \n        t.plan( 1 );\n\n        layer = new OpenLayers.Layer('Test Layer');\n        layer.setName(\"chicken\");\n        \n        t.eq(layer.name, \"chicken\", \"setName() works\")\n        \n    }\n\n    function test_Layer_addOptions (t) {\n        \n        t.plan( 20 );\n\n        var map = new OpenLayers.Map(\"map\", {allOverlays: true});\n        var options = { chicken: 151, foo: \"bar\" };\n        var layer = new OpenLayers.Layer('Test Layer', options);\n        map.addLayer(layer);\n\n        layer.addOptions({bark:55, chicken: 171});\n        t.eq(layer.bark, 55, \"addOptions() assigns new option correctly to Layer\");\n        t.eq(layer.options.bark, 55, \"addOptions() adds new option correctly to backup\");\n\n        t.eq(layer.chicken, 171, \"addOptions() overwrites option correctly to Layer\");\n        t.eq(layer.options.chicken, 171, \"addOptions() overwrites option correctly to backup\");\n\n        var log;\n        layer.initResolutions = function() {\n            log++;\n        };\n        log = 0;\n        layer.addOptions({bark: 56});\n        t.eq(log, 0, \"addOptions doesn't call initResolutions when not given a resolution option\");\n\n        log = 0;\n        layer.addOptions({scales: [1, 2]});\n        t.eq(log, 1, \"addOptions calls initResolutions when given scales\");\n\n        log = 0;\n        layer.addOptions({resolutions: [1, 2]});\n        t.eq(log, 1, \"addOptions calls initResolutions when given resolutions\");\n\n        log = 0;\n        layer.addOptions({minScale: 4});\n        t.eq(log, 1, \"addOptions calls initResolutions when given minScale\");\n\n        log = 0;\n        layer.addOptions({maxScale: 4});\n        t.eq(log, 1, \"addOptions calls initResolutions when given maxScale\");\n\n        log = 0;\n        layer.addOptions({minResolution: 4});\n        t.eq(log, 1, \"addOptions calls initResolutions when given minResolution\");\n\n        log = 0;\n        layer.addOptions({maxResolution: 4});\n        t.eq(log, 1, \"addOptions calls initResolutions when given maxResolution\");\n\n        log = 0;\n        layer.addOptions({numZoomLevels: 4});\n        t.eq(log, 1, \"addOptions calls initResolutions when given numZoomLevels\");\n\n        log = 0;\n        layer.addOptions({maxZoomLevel: 4});\n        t.eq(log, 1, \"addOptions calls initResolutions when given maxZoomLevel\");\n\n        log = 0;\n        layer.addOptions({projection: new OpenLayers.Projection(\"EPSG:900913\")});\n        t.eq(log, 1, \"addOptions calls initResolutions when given projection\");\n\n        log = 0;\n        layer.addOptions({units: \"m\"});\n        t.eq(log, 1, \"addOptions calls initResolutions when given units\");\n\n        log = 0;\n        layer.addOptions({minExtent: new OpenLayers.Bounds(0, 0, 0, 0)});\n        t.eq(log, 1, \"addOptions calls initResolutions when given minExtent\");\n\n        log = 0;\n        layer.addOptions({maxExtent: new OpenLayers.Bounds(0, 0, 0, 0)});\n        t.eq(log, 1, \"addOptions calls initResolutions when given maxExtent\");\n\n        layer.projection = null;\n        layer.addOptions({projection: \"EPSG:900913\"});\n        t.ok(layer.projection instanceof OpenLayers.Projection,\n             \"addOptions creates a Projection object when given a projection string\");\n        \n        log = null;\n        // adding a 2nd layer to see if it gets reinitialized properly\n        var layer2 = new OpenLayers.Layer(null, {\n            moveTo: function(bounds) {\n                log = bounds;\n            }\n        });\n        map.addLayer(layer2);\n        layer.addOptions({maxResolution: 0.00034332275390625}, true);\n        t.eq(log.toBBOX(), map.getExtent().toBBOX(), \"when reinitialize is set to true, changing base layer's resolution property reinitializes all layers.\");\n\n        map.removeLayer(layer);\n        log = 0;\n        layer.addOptions({minExtent: new OpenLayers.Bounds(0, 0, 0, 0)});\n        t.eq(log, 0, \"addOptions doesn't call initResolutions when layer is not in map\");\n    }\n    \n    function test_addOptionsScale(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.WMS();\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        layer.addOptions({maxResolution: 0.5, numZoomLevels: 15});\n        t.eq(layer.alwaysInRange, false, \"alwaysInRange should not be true anymore\");\n    }\n    \n    function test_Layer_StandardOptionsAccessors (t) {\n\n        t.plan( 4 );\n\n        var projection = \"EPSG:4326\";\n        var maxExtent = new OpenLayers.Bounds(50,50,100,100);\n        var maxResolution = 1.5726;\n        var numZoomLevels = 11;\n\n        var options = { projection: projection, \n                        maxExtent: maxExtent,\n                        maxResolution: maxResolution,\n                        numZoomLevels: numZoomLevels\n                        };\n\n        var layer = new OpenLayers.Layer('Test Layer', options);\n\n        t.eq(layer.projection.getCode(), projection, \"projection set correctly\");\n        t.ok(layer.maxExtent.equals(maxExtent), \"maxExtent set correctly\");\n        t.eq(layer.maxResolution, maxResolution, \"maxResolution set correctly\");\n        t.eq(layer.numZoomLevels, numZoomLevels, \"numZoomLevels set correctly\");\n    }\n    \n    function test_maxExtent(t) {\n        t.plan(5);\n        \n        var layer = new OpenLayers.Layer(\n            null, {maxExtent: [-180, 0, 0, 90]}\n        );\n        \n        t.ok(layer.maxExtent instanceof OpenLayers.Bounds, \"(array) bounds instance\");\n        t.eq(layer.maxExtent.left, -180, \"(array) bounds left\");\n        t.eq(layer.maxExtent.bottom, 0, \"(array) bounds left\");\n        t.eq(layer.maxExtent.right, 0, \"(array) bounds right\");\n        t.eq(layer.maxExtent.top, 90, \"(array) bounds top\");\n        \n        layer.destroy();\n    }\n\n    function test_minExtent(t) {\n        t.plan(5);\n        \n        var layer = new OpenLayers.Layer(\n            null, {minExtent: [-180, 0, 0, 90]}\n        );\n        \n        t.ok(layer.minExtent instanceof OpenLayers.Bounds, \"(array) bounds instance\");\n        t.eq(layer.minExtent.left, -180, \"(array) bounds left\");\n        t.eq(layer.minExtent.bottom, 0, \"(array) bounds left\");\n        t.eq(layer.minExtent.right, 0, \"(array) bounds right\");\n        t.eq(layer.minExtent.top, 90, \"(array) bounds top\");\n        \n        layer.destroy();\n    }\n\n\n    function test_eventListeners(t) {\n        t.plan(1);\n        \n        var method = OpenLayers.Events.prototype.on;\n        // test that events.on is called at layer construction\n        var options = {\n            eventListeners: {foo: \"bar\"}\n        };\n        OpenLayers.Events.prototype.on = function(obj) {\n            t.eq(obj, options.eventListeners, \"events.on called with eventListeners\");\n        }\n        var layer = new OpenLayers.Layer(\"test\", options);\n        OpenLayers.Events.prototype.on = method;\n        layer.destroy();\n        \n        // if events.on is called again, this will fail due to an extra test\n        // test layer without eventListeners\n        OpenLayers.Events.prototype.on = function(obj) {\n            t.fail(\"events.on called without eventListeners\");\n        }\n        var layer2 = new OpenLayers.Layer(\"test\");\n        OpenLayers.Events.prototype.on = method;\n        layer2.destroy();\n    }\n\n    function test_initResolutions_alwaysInRange(t) {\n        t.plan(3);\n\n        var map, layer;\n\n        map = new OpenLayers.Map(\"map\");\n        layer = new OpenLayers.Layer(\"test\", {maxResolution: 80, minResolution: 10});\n        map.addLayer(layer);\n        t.eq(layer.alwaysInRange, false,\n             \"alwaysInRange set to false due to passed options\");\n        map.destroy();\n\n        map = new OpenLayers.Map(\"map\");\n        layer = new OpenLayers.Layer(\"test\", {projection: \"unknown\"});\n        map.addLayer(layer);\n        t.eq(layer.alwaysInRange, true,\n             \"alwaysInRange true if unknown projection is set.\");\n        map.destroy();\n\n        map = new OpenLayers.Map(\"map\");\n        OpenLayers.Layer.prototype.alwaysInRange = false;\n        layer = new OpenLayers.Layer(\"test\", {'projection': 'EPSG:4326'});\n        map.addLayer(layer);\n        t.eq(layer.alwaysInRange, false,\n             \"alwaysInRange true if overridden on prototype.\");\n        OpenLayers.Layer.prototype.alwaysInRange = null;\n        map.destroy();\n    }\n\n    function test_initResolutions_resolutions(t) {\n\n        function initResolutionsTest(\n            id, mapOptions, layerOptions,\n            expectedResolutions, expectedMinResolution, expectedMaxResolution) {\n\n            // setup\n            var map = new OpenLayers.Map(\"map\", mapOptions);\n            var layer = new OpenLayers.Layer(null, layerOptions);\n            map.addLayer(layer);\n\n            // make resolution assertions\n            t.eq(\n                layer.resolutions.length, expectedResolutions.length,\n                id + \": correct resolutions length\"\n            );\n            // allow for floating point imprecision\n            var got, exp, same = true;\n            for (var i=0; i<expectedResolutions.length; ++i) {\n                got = layer.resolutions[i];\n                exp = expectedResolutions[i];\n                if (got.toFixed(10) !== exp.toFixed(10)) {\n                    t.fail(id + \": bad resolutions - index \" + i + \" got \" + got + \" but expected \" + exp);\n                    same = false;\n                    break;\n                }\n            }\n            if (same) {\n                t.ok(true, id + \": correct resolutions\");\n            }\n            t.eq(\n                layer.maxResolution, expectedMaxResolution,\n                id + \": maxResolution set\"\n            );\n            t.eq(\n                layer.minResolution, expectedMinResolution,\n                id + \": minResolution set\"\n            );\n\n            // teardown\n            map.destroy();\n        }\n\n        // each case is an array of id, map options, layer options, expected resolutions,\n        // expected min resolution, and expected max resolution\n        var cases = [[\n\n        /*\n         * Batch 1: map defaults and sensible layer options\n         */\n\n            \"1.0\",  null, {resolutions: [400, 200, 100]},\n            [400, 200, 100], 100, 400\n        ], [\n            \"1.1\",  null, {resolutions: [400, 200, 100], minResolution: 150, maxResolution: 300},\n            [400, 200, 100], 150, 300\n        ], [\n            \"1.2\",  null, {maxResolution: 4000, numZoomLevels: 3},\n            [4000, 2000, 1000], 1000, 4000\n        ], [\n            \"1.3\",  null, {maxResolution: 4000, maxZoomLevel: 2},\n            [4000, 2000, 1000], 1000, 4000\n        ], [\n            \"1.4\",  null, {minResolution: 40, numZoomLevels: 3},\n            [160, 80, 40], 40, 160\n        ], [\n            \"1.5\",  null, {minResolution: 40, maxZoomLevel: 2},\n            [160, 80, 40], 40, 160\n        ], [\n            \"1.6\", null, {minResolution: 10, maxResolution: 40},\n            [40, 20, 10], 10, 40\n        ], [\n            \"1.7\", null, {minResolution: 10, maxResolution: 40, numZoomLevels: 3},\n            [40, 20, 10], 10, 40\n        ], [\n            \"1.8\", null, {minResolution: 10, maxResolution: 40, maxZoomLevel: 2},\n            [40, 20, 10], 10, 40\n        ], [\n            \"1.9\",  null, {scales: [400000, 200000, 100000]},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362\n        ], [\n            \"1.10\",  null, {scales: [400000, 200000, 100000], minScale: 400000, maxScale: 100000},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362\n        ], [\n            \"1.11\",  null, {minScale: 400000, numZoomLevels: 3},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362\n        ], [\n            \"1.12\",  null, {minScale: 400000, maxZoomLevel: 2},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362\n        ], [\n            \"1.13\",  null, {maxScale: 100000, numZoomLevels: 3},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362\n        ], [\n            \"1.14\",  null, {maxScale: 100000, maxZoomLevel: 2},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362\n        ], [\n            \"1.15\",  null, {maxScale: 100000, minScale: 400000},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362\n        ], [\n            \"1.16\",  null, {maxScale: 100000, minScale: 400000, numZoomLevels: 3},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362\n        ], [\n            \"1.17\",  null, {maxScale: 100000, minScale: 400000, maxZoomLevel: 2},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362\n        ], [\n            \"1.18\",  null, {scales: [400000, 200000, 100000], units: \"m\"},\n            [141.11139333389778, 70.55569666694889, 35.277848333474445], 35.277848333474445, 141.11139333389778\n        ], [\n            \"1.19\",  null, {minScale: 400000, numZoomLevels: 3, units: \"m\"},\n            [141.11139333389778, 70.55569666694889, 35.277848333474445], 35.277848333474445, 141.11139333389778\n        ], [\n            \"1.20\",  null, {maxScale: 100000, numZoomLevels: 3, units: \"m\"},\n            [141.11139333389778, 70.55569666694889, 35.277848333474445], 35.277848333474445, 141.11139333389778\n        ], [\n            \"1.21\", null, {numZoomLevels: 2},  // maxResolution calculated based on the projection's maxExtent here\n           [1.40625, 0.703125], 0.703125, 1.40625\n        ], [\n\n        /*\n         * Batch 2: custom map options map and sensible layer options\n         */\n\n        /*\n         * Batch 2.1: resolutions set in the layer options\n         */\n            \"2.1.0\",  {resolutions: [300, 150]}, {resolutions: [400, 200, 100]},\n            [400, 200, 100], 100, 400\n        ], [\n            \"2.1.1\",  {numZoomLevels: 4}, {resolutions: [400, 200, 100]},\n            [400, 200, 100], 100, 400\n        ], [\n            \"2.1.2\",  {maxResolution: 300}, {resolutions: [400, 200, 100]},\n            [400, 200, 100], 100, 400\n        ], [\n            \"2.1.3\",  {minResolution: 300}, {resolutions: [400, 200, 100]},\n            [400, 200, 100], 100, 400\n        ], [\n            \"2.1.4\",  {scales: [4, 2, 1]}, {resolutions: [400, 200, 100]},\n            [400, 200, 100], 100, 400\n        ], [\n            \"2.1.5\",  {minScale: 4}, {resolutions: [400, 200, 100]},\n            [400, 200, 100], 100, 400\n        ], [\n            \"2.1.6\",  {maxScale: 4}, {resolutions: [400, 200, 100]},\n            [400, 200, 100], 100, 400\n        ], [\n        /*\n         * Batch 2.2: minResolution and maxResolution set in the layer options\n         */\n            \"2.2.0\",  {resolutions: [80, 40, 20, 10]}, {minResolution: 12, maxResolution: 48, numZoomLevels: 0},\n            [80, 40, 20, 10], 12, 48\n        ], [\n            \"2.2.1\",  {resolutions: [80, 40, 20, 10]}, {minResolution: 12, maxResolution: 48, numZoomLevels: -1},\n            [80, 40, 20, 10], 12, 48\n        ], [\n            \"2.2.2\",  {resolutions: [80, 40, 20, 10]}, {minResolution: 12, maxResolution: 48, numZoomLevels: null},\n            [80, 40, 20, 10], 12, 48\n        ], [\n            \"2.2.3\",  {resolutions: [80, 40, 20, 10]}, {minResolution: 12, maxResolution: 48, numZoomLevels: undefined},\n            [48, 24, 12], 12, 48\n        ], [\n            \"2.2.4\",  {resolutions: [80, 40, 20, 10]}, {minResolution: 12, maxResolution: 48, numZoomLevels: 3},\n            [48, 24, 12], 12, 48\n        ], [\n            \"2.2.5\",  {resolutions: [80, 40, 20, 10]}, {minResolution: 12, maxResolution: 48},\n            [48, 24, 12], 12, 48\n        ], [\n        /*\n         * Batch 2.3: maxResolution set in the layer options\n         */\n            \"2.3.0\",  {resolutions: [300, 150]}, {maxResolution: 4000, numZoomLevels: 3},\n            [4000, 2000, 1000], 1000, 4000\n        ], [\n            \"2.3.1\",  {numZoomLevels: 2}, {maxResolution: 4000, numZoomLevels: 3},\n            [4000, 2000, 1000], 1000, 4000\n        ], [\n            \"2.3.2\",  {maxResolution: 50}, {maxResolution: 4000, numZoomLevels: 3},\n            [4000, 2000, 1000], 1000, 4000\n        ], [\n            \"2.3.3\",  {scales: [4, 2, 1]}, {maxResolution: 4000, numZoomLevels: 3},\n            [4000, 2000, 1000], 1000, 4000\n        ], [\n            \"2.3.4\",  {minScale: 4}, {maxResolution: 4000, numZoomLevels: 3},\n            [4000, 2000, 1000], 1000, 4000\n        ], [\n            \"2.3.5\",  {resolutions: [300, 150]}, {maxResolution: 250},\n            [300, 150], 150, 250\n        ], [\n        /*\n         * Batch 2.4: minResolution set in the layer options\n         */\n            \"2.4.0\",  {resolutions: [300, 150]}, {minResolution: 40, numZoomLevels: 3},\n            [160, 80, 40], 40, 160\n        ], [\n            \"2.4.1\",  {numZoomLevels: 2}, {minResolution: 40, numZoomLevels: 3},\n            [160, 80, 40], 40, 160\n        ], [\n            \"2.4.2\",  {minResolution: 50}, {minResolution: 40, numZoomLevels: 3},\n            [160, 80, 40], 40, 160\n        ], [\n            \"2.4.3\",  {scales: [4, 2, 1]}, {minResolution: 40, numZoomLevels: 3},\n            [160, 80, 40], 40, 160\n        ], [\n            \"2.4.4\",  {maxScale: 1}, {minResolution: 40, numZoomLevels: 3},\n            [160, 80, 40], 40, 160\n        ], [\n            \"2.4.5\",  {resolutions: [300, 150]}, {minResolution: 250},\n            [300, 150], 250, 300\n        ], [\n        /*\n         * Batch 2.5: scales set in the layer options\n         */\n            \"2.5.0\",  {resolutions: [4, 2, 1]}, {scales: [400000, 200000, 100000]},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362\n        ], [\n            \"2.5.1\",  {numZoomLevels: 2}, {scales: [400000, 200000, 100000]},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362\n        ], [\n            \"2.5.2\",  {maxResolution: 4}, {scales: [400000, 200000, 100000]},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362\n        ], [\n            \"2.5.3\",  {minResolution: 1}, {scales: [400000, 200000, 100000]},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362\n        ], [\n            \"2.5.4\",  {units: \"m\"}, {scales: [400000, 200000, 100000]},\n            [141.11139333389778, 70.55569666694889, 35.277848333474445], 35.277848333474445, 141.11139333389778\n        ], [\n        /*\n         * Batch 2.6: minScale set in the layer options\n         */\n            \"2.6.0\",  {resolutions: [4, 2, 1]}, {minScale: 400000, numZoomLevels: 3},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362\n        ], [\n            \"2.6.1\",  {numZoomLevels: 2}, {minScale: 400000, numZoomLevels: 3},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362\n        ], [\n            \"2.6.2\",  {maxResolution: 4}, {minScale: 400000, numZoomLevels: 3},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362\n        ], [\n            \"2.6.3\", {scales: [400000, 200000, 100000]}, {minScale: 200000},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0006349563376084181\n        ], [\n        /*\n         * Batch 2.7: maxScale set in the layer options\n         */\n            \"2.7.0\",  {resolutions: [4, 2, 1]}, {maxScale: 100000, numZoomLevels: 3},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362\n        ], [\n            \"2.7.1\",  {numZoomLevels: 2}, {maxScale: 100000, numZoomLevels: 3},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362\n        ], [\n            \"2.7.2\",  {minResolution: 1}, {maxScale: 100000, numZoomLevels: 3},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.00031747816880420905, 0.0012699126752168362\n        ], [\n            \"2.7.3\", {scales: [400000, 200000, 100000]}, {maxScale: 200000},\n            [0.0012699126752168362, 0.0006349563376084181, 0.00031747816880420905], 0.0006349563376084181, 0.0012699126752168362\n        ], [\n        /*\n         * Batch 2.8: numZoomLevels set in the layer options\n         */\n            \"2.8.0\",  {maxResolution: 80}, {numZoomLevels: 4},  // maxResolution calculated based on the projection's maxExtent here\n            [1.40625, 0.703125, 0.3515625, 0.17578125], 0.17578125, 1.40625\n        ], [\n            \"2.8.1\", {maxResolution: 80, numZoomLevels: 4}, {numZoomLevels: null},\n            [80, 40, 20, 10], 10, 80\n        ], [\n            \"2.8.2\", {maxResolution: 80, numZoomLevels: 4}, {numZoomLevels: undefined},\n            [80, 40, 20, 10], 10, 80\n        ]];\n\n        // run all cases (4 tests each)\n        var i, num = cases.length, c;\n        t.plan(num * 4);\n        for (i=0; i<num; ++i) {\n            c = cases[i];\n            initResolutionsTest(c[0], c[1], c[2], c[3], c[4], c[5]);\n        }\n\n    }\n\n    function test_Layer_visibility(t) {\n\n        t.plan(7);\n\n        var layer = new OpenLayers.Layer('Test Layer');\n    \n        t.eq(layer.getVisibility(), true, \"default for layer creation is visible\");\n        \n        layer.setVisibility(false);\n        t.eq(layer.getVisibility(), false, \"setVisibility false works\");\n\n        layer.setVisibility(true);\n        t.eq(layer.getVisibility(), true, \"setVisibility true works\");\n       \n        // Need a map in order to have moveTo called.\n        // Tests added for #654.\n        var layer = new OpenLayers.Layer.WMS('Test Layer','http://example.com');\n        var m = new OpenLayers.Map('map');\n        m.addLayer(layer);\n        m.zoomToMaxExtent();\n        \n        layermoved = false; \n        layer.moveTo = function() { layermoved = true; }\n        \n        layer.events.register('visibilitychanged', t, function() {\n            this.ok(true, \"Visibility changed calls layer event.\");\n        });    \n        \n        layer.setVisibility(false);\n        t.eq(layermoved, false, \"Layer didn't move when calling setvis false\");\n        \n        layer.setVisibility(true);\n        t.eq(layermoved, true, \"Layer moved when calling setvis true.\");\n    \n    }\n\n\n    function test_Layer_getZoomForResolution(t) {\n\n        t.plan(12);\n\n        var layer = new OpenLayers.Layer('Test Layer');\n        layer.map = {};\n        \n        //make some dummy resolutions\n        layer.resolutions = [128, 64, 32, 16, 8, 4, 2];\n        \n        t.eq(layer.getZoomForResolution(200), 0, \"zoom all the way out\");\n        t.eq(layer.getZoomForResolution(25), 2, \"zoom in middle\");\n        t.eq(layer.getZoomForResolution(3), 5, \"zoom allmost all the way in\");\n        t.eq(layer.getZoomForResolution(1), 6, \"zoom  all the way in\");\n\n        t.eq(layer.getZoomForResolution(65), 0, \"smallest containing res\");\n        t.eq(layer.getZoomForResolution(63), 1, \"smallest containing res\");\n\n        t.eq(layer.getZoomForResolution(65, true), 1, \"closest res\");\n        t.eq(layer.getZoomForResolution(63, true), 1, \"closest res\");\n        \n        layer.map.fractionalZoom = true;\n        t.eq(layer.getZoomForResolution(64), 1,\n             \"(fractionalZoom) correct zoom for res in array\");\n        t.eq(layer.getZoomForResolution(48).toPrecision(6), (1.5).toPrecision(6),\n             \"(fractionalZoom) linear scaling for res between entries\");\n        t.eq(layer.getZoomForResolution(200).toPrecision(6), (0).toPrecision(6),\n             \"(fractionalZoom) doesn't return zoom below zero\");\n        t.eq(layer.getZoomForResolution(1).toPrecision(6), (layer.resolutions.length - 1).toPrecision(6),\n             \"(fractionalZoom) doesn't return zoom above highest index\");\n    }\n    \n    function test_Layer_redraw(t) {\n        t.plan(11)\n\n        var name = 'Test Layer';\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        var params = { map: '/mapdata/vmap_wms.map', \n                       layers: 'basic', \n                       format: 'image/jpeg'};\n\n        var layer = new OpenLayers.Layer.WMS(name, url, params);\n        \n        t.ok(!layer.redraw(),\n             \"redraw on an orphan layer returns false\");\n        \n        var map = new OpenLayers.Map('map');\n        map.addLayer(layer);\n\n        t.ok(!layer.redraw(),\n             \"redraw returns false if map does not yet have a center\");\n        map.zoomToMaxExtent();\n        \n        t.ok(layer.redraw(),\n             \"redraw returns true after map has a center\");\n        \n        layer.setVisibility(false);\n        t.ok(!layer.redraw(),\n             \"redraw returns false if a layer is not visible\");\n        \n        layer.setVisibility(true);\n        t.ok(layer.redraw(),\n                \"redraw returns true even if extent has not changed\");\n        \n        var log = {};\n        var onMoveend = function(e) {\n            log.event = e;\n        };\n        layer.events.on({\"moveend\": onMoveend});\n        layer.redraw();\n        layer.events.un({\"moveend\": onMoveend});\n        // test that the moveend event was triggered\n        t.ok(log.event, \"an event was logged\");\n        t.eq(log.event.type, \"moveend\", \"moveend was triggered\");\n        t.eq(log.event.zoomChanged, true, \"event says zoomChanged true - poor name\");\n\n        layer.moveTo = function(bounds, zoomChanged, dragging) {\n            var extent = layer.map.getExtent();\n            t.ok(bounds.equals(extent),\n                 \"redraw calls moveTo with the map extent\");\n            t.ok(zoomChanged,\n                 \"redraw calls moveTo with zoomChanged true\");\n            t.ok(!dragging,\n                 \"redraw calls moveTo with dragging false\");\n        }\n        layer.redraw();\n    }\n      \n    function test_layer_setIsBaseLayer(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer();\n\n        map.events.register(\"changebaselayer\", t, function() {\n          this.ok(true, \"setIsBaseLayer() trig changebaselayer event.\")\n        });\n\n        map.addLayer(layer);\n        layer.setIsBaseLayer(true);\n        t.ok(layer.isBaseLayer, \"setIsBaseLayer() change isBaseLayer property.\");\n    }\n      \n    function test_layer_setTileSize(t) {\n        t.plan(4);\n\n        layer = new OpenLayers.Layer();\n        \n        g_MapTileSize = new OpenLayers.Size(25,67);        \n        layer.map = {\n            getTileSize: function() {\n                return g_MapTileSize;\n            }\n        };\n\n        var layerTileSize = new OpenLayers.Size(1,1);\n\n    //TILE SIZE\n        layer.tileSize = layerTileSize;\n      \n      //parameter\n        var size = new OpenLayers.Size(2,2);\n        layer.setTileSize(size);\n        t.ok(layer.tileSize.equals(size), \"size paramater set correctly to layer's tile size\");\n      \n      //set on layer\n        layer.tileSize = layerTileSize;\n        layer.setTileSize();\n        t.ok(layer.tileSize.equals(layerTileSize), \"layer's tileSize property preserved if no parameter sent in\");\n      \n      //take it from map\n        layer.tileSize = null;\n        layer.setTileSize();\n        t.ok(layer.tileSize.equals(g_MapTileSize), \"layer's tileSize property is null and so correctly taken from the map\");\n        \n        \n\n    //GUTTERS\n        layer.gutter = 15;\n        size = new OpenLayers.Size(10,100);\n        layer.setTileSize(size);\n\n        var desiredImageSize = new OpenLayers.Size(40, 130); \n\n        t.ok(layer.imageSize.equals(desiredImageSize), \"image size correctly calculated\");\n    }\n    \n    function test_Layer_getResolution(t) {\n        t.plan(1);\n        var layer = new OpenLayers.Layer(\"test\");\n        layer.map = {\n            getZoom: function() {return \"foo\";}\n        };\n        layer.getResolutionForZoom = function(zoom) {\n            t.eq(zoom, \"foo\", \"getResolution calls getResolutionForZoom\");\n        }\n        layer.getResolution();\n        layer.map = null;\n        layer.destroy();\n    }\n    \n    function test_Layer_getResolutionForZoom(t) {\n        t.plan(8);\n        var layer = new OpenLayers.Layer(\"test\");\n        layer.map = {fractionalZoom: false};\n        layer.resolutions = [\"zero\", \"one\", \"two\"];\n        t.eq(layer.getResolutionForZoom(0), \"zero\",\n             \"(fractionalZoom false) returns resolution for given index\");\n        t.eq(layer.getResolutionForZoom(0.9), \"one\",\n             \"(fractionalZoom false) returns resolution for float index\");\n        \n        layer.resolutions = [2, 4, 6, 8];\n        layer.map.fractionalZoom = true;\n        t.eq(layer.getResolutionForZoom(1).toPrecision(6), (4).toPrecision(6),\n             \"(fractionalZoom true) returns resolution for integer zoom\");\n\n        t.eq(layer.getResolutionForZoom(1.3).toPrecision(6), (4.6).toPrecision(6),\n             \"(fractionalZoom true) for zoom 1.3 should be 4.6\");\n\n        t.eq(layer.getResolutionForZoom(1.6).toPrecision(6), (5.2).toPrecision(6),\n             \"(fractionalZoom true) for zoom 1.6 should be 5.2\");\n\n        t.eq(layer.getResolutionForZoom(1.8).toPrecision(6), (5.6).toPrecision(6),\n             \"(fractionalZoom true) for zoom 1.8 should be 5.6\");\n\n        t.eq(layer.getResolutionForZoom(1.5).toPrecision(6), (5).toPrecision(6),\n             \"(fractionalZoom true) returns resolution for float zoom\");             \n        t.eq(layer.getResolutionForZoom(3.5).toPrecision(6), (8).toPrecision(6),\n             \"(fractionalZoom true) returns resolution for zoom beyond res length - 1\");\n        \n    }\n    \n    function test_afterAdd(t) {\n        \n        t.plan(4);\n        \n        var log = [];\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer(null, {\n            isBaseLayer: true,\n            eventListeners: {\n                \"added\": function(evt) {\n                    log.push(evt);\n                }\n            }\n        });\n        var hasBase = false;\n        layer.afterAdd = function() {\n            hasBase = !!(layer.map && layer.map.baseLayer);\n        }\n        map.addLayer(layer);\n        t.eq(hasBase, true, \"when afterAdd is called, map has a base layer\");\n        t.eq(log.length, 1, \"added event triggered\");\n        t.eq(log[0].map.id, map.id, \"added listener argument with correct map\");\n        t.eq(log[0].layer.id, layer.id, \"added listener argument with correct layer\");\n        \n    }\n    \n    function test_setOpacity(t) {\n        t.plan(5);\n\n        var map, layer, log;\n        \n        map = new OpenLayers.Map(\"map\");\n        layer = new OpenLayers.Layer(\"\");\n        map.addLayer(layer);\n\n        log = [];\n        map.events.register('changelayer', t, function(event) {\n            log.push({layer: event.layer, property: event.property});\n        });\n        layer.setOpacity(0.42);\n        t.eq(layer.opacity, 0.42,\n             \"setOpacity() set layer.opacity to correct value\");\n        t.eq(log.length, 1,\n             \"setOpacity() triggers changelayer once\");\n        t.ok(log[0].layer == layer,\n             \"changelayer listener called with expected layer\");\n        t.eq(log[0].property, \"opacity\",\n             \"changelayer listener called with expected property\");\n\n        // This call must not trig the event because the opacity value is the same.\n        log = [];\n        layer.setOpacity(0.42);\n        t.eq(log.length, 0,\n             \"setOpacity() does not trigger changelayer if the opacity value is the same\");\n    }\n\n\n/******\n * \n * \n * HERE IS WHERE SOME TESTS SHOULD BE PUT TO CHECK ON THE LONLAT-PX TRANSLATION\n * FUNCTIONS AND RESOLUTION AND GETEXTENT GETZOOMLEVEL, ETC\n * \n * \n */\n\n\n    function test_Layer_destroy (t) {\n        t.plan( 8 );    \n\n        var log = [];\n        var map = new OpenLayers.Map('map');\n        \n        layer = new OpenLayers.Layer('Test Layer', {\n            eventListeners: {\n                \"removed\": function(evt) {\n                    log.push(evt);\n                }\n            }\n        });\n\n        map.addLayer(layer);\n\n        layer.destroy();\n\n        t.eq( layer.name, null, \"layer.name is null after destroy\" );\n        t.eq( layer.div, null, \"layer.div is null after destroy\" );\n        t.eq( layer.map, null, \"layer.map is null after destroy\" );\n        t.eq( layer.options, null, \"layer.options is null after destroy\" );\n\n        t.eq(map.layers.length, 0, \"layer removed from map\");\n        t.eq(log.length, 1, \"removed event triggered\");\n        t.eq(log[0].map.id, map.id, \"removed listener argument with correct map\");\n        t.eq(log[0].layer.id, layer.id, \"removed listener argument with correct layer\");\n        \n        map.destroy();\n\n    }\n\n  </script>\n</head>\n<body>\n  <div id=\"map\" style=\"width:500px;height:500px\"></div>\n  <div id=\"map2\" style=\"width:100px;height:100px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Map.html",
    "content": "<html>\n<head>\n    <script>\n    /**\n    * Because browsers that implement requestAnimationFrame may not execute\n    * animation functions while a window is not displayed (e.g. in a hidden\n    * iframe as in these tests), we mask the native implementations here.  The\n    * native requestAnimationFrame functionality is tested in Util.html and\n    * in PanZoom.html (where a popup is opened before panning).  The panTo tests\n    * here will test the fallback setTimeout implementation for animation.\n    */\n    window.requestAnimationFrame = \n        window.webkitRequestAnimationFrame =\n        window.mozRequestAnimationFrame =\n        window.oRequestAnimationFrame =\n        window.msRequestAnimationFrame = null;\n    </script>\n    <script src=\"OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var map;\n\n    function test_Map_constructor (t) {\n        t.plan( 11 );\n        \n        map = new OpenLayers.Map('map'); \n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(baseLayer);\n\n        t.ok( OpenLayers.Element.hasClass(map.div, \"olMap\"), \"Map div has olMap class\");\n\n        t.ok( map instanceof OpenLayers.Map, \"new OpenLayers.Map returns object\" );\n        if (!isMozilla) {\n            t.ok( true, \"skipping element test outside of Mozilla\");\n            t.ok( true, \"skipping element test outside of Mozilla\");\n            t.ok( true, \"skipping element test outside of Mozilla\");\n        } else {\n            t.ok( map.div instanceof HTMLDivElement, \"map.div is an HTMLDivElement\" );\n            t.ok( map.viewPortDiv instanceof HTMLDivElement, \"map.viewPortDiv is an HTMLDivElement\" );\n            t.ok( map.layerContainerDiv instanceof HTMLDivElement, \"map.layerContainerDiv is an HTMLDivElement\" );\n        }\n        t.ok( map.layers instanceof Array, \"map.layers is an Array\" );\n        t.ok( map.controls instanceof Array, \"map.controls is an Array\" );\n        t.eq( map.controls.length, 4, \"Default map has 4 controls.\" );\n        t.ok( map.events instanceof OpenLayers.Events, \"map.events is an OpenLayers.Events\" );\n        t.ok( map.getMaxExtent() instanceof OpenLayers.Bounds, \"map.maxExtent is an OpenLayers.Bounds\" );\n        t.ok( map.getNumZoomLevels() > 0, \"map has a default numZoomLevels\" );\n\n        map.destroy();\n    }\n    \n    function test_Map_constructor_convenience(t) {\n        t.plan(13);\n        var map = new OpenLayers.Map({\n            maxExtent: [-170, -80, 170, 80],\n            restrictedExtent: [-120, -65, 120, 65],\n            layers: [\n                new OpenLayers.Layer(null, {isBaseLayer: true})\n            ],\n            center: [-111, 45],\n            zoom: 3\n        });\n        \n        // maxExtent from array\n        t.ok(map.maxExtent instanceof OpenLayers.Bounds, \"maxExtent bounds\");\n        t.eq(map.maxExtent.left, -170, \"maxExtent left\");\n        t.eq(map.maxExtent.bottom, -80, \"maxExtent bottom\");\n        t.eq(map.maxExtent.right, 170, \"maxExtent right\");\n        t.eq(map.maxExtent.top, 80, \"maxExtent top\");\n\n        // restrictedExtent from array\n        t.ok(map.restrictedExtent instanceof OpenLayers.Bounds, \"restrictedExtent bounds\");\n        t.eq(map.restrictedExtent.left, -120, \"restrictedExtent left\");\n        t.eq(map.restrictedExtent.bottom, -65, \"restrictedExtent bottom\");\n        t.eq(map.restrictedExtent.right, 120, \"restrictedExtent right\");\n        t.eq(map.restrictedExtent.top, 65, \"restrictedExtent top\");\n        \n        var center = map.getCenter();\n        t.eq(center.lon, -111, \"center lon\");\n        t.eq(center.lat, 45, \"center lat\");\n        \n        t.eq(map.getZoom(), 3, \"zoom\");\n        \n        map.destroy();\n    }\n    \n    function test_Map_constructor_late_rendering(t) {\n        t.plan( 4 );\n        \n        map = new OpenLayers.Map(); \n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(baseLayer);\n        \n        t.ok(map.div != null, \"Map has a div even though none was specified.\");\n        t.ok(map.viewPortDiv.parentNode == map.div, \"Map is attached to a temporary div that holds the viewPortDiv.\");\n        \n        var mapDiv = document.getElementById(\"map\");\n        // clean up the effects of other tests\n        while(OpenLayers.Element.hasClass(mapDiv, \"olMap\")) {\n            OpenLayers.Element.removeClass(mapDiv, \"olMap\");\n        }\n        map.render(mapDiv); // Can also take a string.\n        \n        t.ok(map.div == mapDiv, \"Map is now rendered to the 'map' div.\")\n        t.ok( OpenLayers.Element.hasClass(map.div, \"olMap\"), \"Map div has olMap class\");\n        \n        map.destroy();\n        \n    }\n    \n    function test_Map_constructor_renderTo(t) {\n        t.plan( 1 );\n        \n        map = new OpenLayers.Map({\n            div: \"map\"\n        }); \n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(baseLayer);\n        \n        var mapDiv = document.getElementById(\"map\");\n        t.ok(map.div == mapDiv, \"Map is rendered to the 'map' div.\")\n        \n        map.destroy();\n    }\n\n    function test_Map_constructor_renderTo_DOM_element_ref(t) {\n        t.plan( 1 );\n\n        var map_div = document.getElementById('map');\n        map = new OpenLayers.Map(map_div); \n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(baseLayer);\n        \n        var mapDiv = document.getElementById(\"map\");\n        t.ok(map.div == mapDiv, \"Map is rendered to the 'map' div.\")\n        \n        map.destroy();\n    }\n\n    function test_Map_setOptions(t) {\n        t.plan(2);\n        map = new OpenLayers.Map('map', {maxExtent: new OpenLayers.Bounds(100, 200, 300, 400)});\n        map.setOptions({theme: 'foo'});\n        \n        t.eq(map.theme, 'foo', \"theme is correctly set by setOptions\");\n        t.ok(map.maxExtent.equals(new OpenLayers.Bounds(100, 200, 300, 400)), \n             \"maxExtent is correct after calling setOptions\");\n        \n        map.destroy();\n    }\n\n    function test_Map_add_layers(t) {\n        t.plan(8);\n        map = new OpenLayers.Map('map');\n        var layer1 = new OpenLayers.Layer.WMS(\"Layer 1\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        var layer2 = new OpenLayers.Layer.WMS(\"Layer 2\",\n            \"http://wms.jpl.nasa.gov/wms.cgi\", {layers: \"modis,global_mosaic\"});\n        // this uses map.addLayer internally\n        map.addLayers([layer1, layer2])\n        t.eq( map.layers.length, 2, \"map has exactly two layers\" );\n        t.ok( map.layers[0] === layer1, \"1st layer is layer1\" );\n        t.ok( map.layers[1] === layer2, \"2nd layer is layer2\" );\n        t.ok( layer1.map === map, \"layer.map is map\" ); \n        t.eq( parseInt(layer1.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'], \n                \"layer1 zIndex is set\" );\n        t.eq( parseInt(layer2.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'] + 5, \n                \"layer2 zIndex is set\" );\n\n        map.events.register('preaddlayer', this, function(evt) {\n            return !(evt.layer.name === 'donotadd');\n        });\n        var layer3 = new OpenLayers.Layer.WMS(\"donotadd\",\n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayers([layer3]);\n        t.eq(map.layers.length, 2, \"layer is not added since preaddlayer returns false\");\n        layer3.name = 'pleaseadd';\n        map.addLayers([layer3]);\n        t.eq(map.layers.length, 3, \"layer is added since preaddlayer returns true\");\n        \n        map.destroy();\n    }\n\n    function test_Map_options(t) {\n        t.plan(3);\n        map = new OpenLayers.Map('map', {numZoomLevels: 6, maxResolution: 3.14159, theme: 'foo'});\n        t.eq( map.numZoomLevels, 6, \"map.numZoomLevels set correctly via options hashtable\" );\n        t.eq( map.maxResolution, 3.14159, \"map.maxResolution set correctly via options hashtable\" );\n        t.eq( map.theme, 'foo', \"map theme set correctly.\" );\n\n        map.destroy();\n    }\n    \n    function test_eventListeners(t) {\n        t.plan(1);\n        \n        var method = OpenLayers.Events.prototype.on;\n        // test that events.on is called at map construction\n        var options = {\n            eventListeners: {foo: \"bar\"},\n            tileManager: null,\n            controls: []\n        };\n        OpenLayers.Events.prototype.on = function(obj) {\n            t.eq(obj, options.eventListeners, \"events.on called with eventListeners\");\n        }\n        var map = new OpenLayers.Map('map', options);\n        OpenLayers.Events.prototype.on = method;\n        map.destroy();\n\n        // if events.on is called again, this will fail due to an extra test\n        // test map without eventListeners\n        OpenLayers.Events.prototype.on = function(obj) {\n            t.fail(\"events.on called without eventListeners\");\n        }\n        var map2 = new OpenLayers.Map(\"map\", {tileManager: null, controls: []});\n        OpenLayers.Events.prototype.on = method;\n        map2.destroy();\n    }\n\n    function test_Map_center(t) {\n        t.plan(14);\n        var log = [];\n        map = new OpenLayers.Map('map', {\n            zoomMethod: null,\n            eventListeners: {\n                \"movestart\": function() {log.push(\"movestart\");},\n                \"move\": function() {log.push(\"move\");},\n                \"moveend\": function() {log.push(\"moveend\");}\n            }            \n        });\n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"} );\n        map.addLayer(baseLayer);\n        var ll = new OpenLayers.LonLat(2,1);\n        map.setCenter(ll, 0);\n        t.ok( map.getCenter() instanceof OpenLayers.LonLat, \"map.getCenter returns a LonLat\");\n        t.eq( map.getZoom(), 0, \"map.zoom is correct after calling setCenter\");\n        t.ok( map.getCenter().equals(ll), \"map center is correct after calling setCenter\");\n        map.zoomIn();\n        t.eq( map.getZoom(), 1, \"map.zoom is correct after calling setCenter,zoom in\");\n        t.ok( map.getCenter().equals(ll), \"map center is correct after calling setCenter, zoom in\");\n        map.zoomOut();\n        t.eq( map.getZoom(), 0, \"map.zoom is correct after calling setCenter,zoom in, zoom out\");\n        \n        log = [];\n        map.zoomTo(5);\n        t.eq(log[0], \"movestart\", \"zoomTo fires movestart event\");\n        t.eq(log[1], \"move\", \"zoomTo fires move event\");\n        t.eq(log[2], \"moveend\", \"zoomTo fires moveend event\");\n        t.eq( map.getZoom(), 5, \"map.zoom is correct after calling zoomTo\" );\n\n    /**\n        map.zoomToMaxExtent();\n        t.eq( map.getZoom(), 2, \"map.zoom is correct after calling zoomToMaxExtent\" );\n        var lonlat = map.getCenter();\n        var zero = new OpenLayers.LonLat(0, 0);\n        t.ok( lonlat.equals(zero), \"map center is correct after calling zoomToFullExtent\" );\n    */\n\n        map.getCenter().lon = 10;\n        t.ok( map.getCenter().equals(ll), \"map.getCenter returns a clone of map.center\");\n\n        // allow calling setCenter with an array\n        map.setCenter([4, 2]);\n        var center = map.getCenter();\n        t.ok(center instanceof OpenLayers.LonLat, \"(array) center is lonlat\");\n        t.eq(center.lon, 4, \"(array) center lon\");\n        t.eq(center.lat, 2, \"(array) center lat\");\n\n        map.destroy();\n    }\n\n    function test_Map_zoomstart_zoomend_event (t) {\n        t.plan(4);\n\n        map = new OpenLayers.Map('map', {zoomMethod: null});\n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(baseLayer);\n        map.events.register(\"zoomstart\", {count: 0}, function() { \n            this.count++; \n            t.ok(true, \"zoomstart event was triggered \" + this.count + \" times\");\n            });\n        map.events.register(\"zoomend\", {count: 0}, function() { \n            this.count++; \n            t.ok(true, \"zoomend event was triggered \" + this.count + \" times\");\n            });\n        map.setCenter(new OpenLayers.LonLat(2, 1), 0);\n        map.zoomIn();\n        map.zoomOut();\n\n        map.destroy();\n    }\n\n    function test_Map_add_remove_popup (t) {\n        t.plan(4);\n\n        map = new OpenLayers.Map('map');\n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(baseLayer);\n        \n        var popup = new OpenLayers.Popup(\"chicken\", \n                                         new OpenLayers.LonLat(0,0),\n                                         new OpenLayers.Size(200,200));\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        map.addPopup(popup);\n        var pIndex = OpenLayers.Util.indexOf(map.popups, popup);\n        t.eq(pIndex, 0, \"popup successfully added to Map's internal popups array\");\n\n        var nodes = map.layerContainerDiv.childNodes;\n        \n        var found = false;\n        for (var i=0; i < nodes.length; i++) {\n            if (nodes.item(i) == popup.div) {\n                found = true;\n                break;\n            }\n        }\n        t.ok(found, \"popup.div successfully added to the map's viewPort\");\n\n        \n        map.removePopup(popup);\n        var pIndex = OpenLayers.Util.indexOf(map.popups, popup);\n        t.eq(pIndex, -1, \"popup successfully removed from Map's internal popups array\");\n\n        var found = false;\n        for (var i=0; i < nodes.length; i++) {\n            if (nodes.item(i) == popup.div) {\n                found = true;\n                break;\n            }\n        }\n        t.ok(!found, \"popup.div successfully removed from the map's viewPort\");\n\n        map.destroy();\n    }\n\n    function test_Map_add_popup_exclusive(t) {\n        t.plan(2);\n\n        map = new OpenLayers.Map('map');\n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(baseLayer);\n        \n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n\n        for (var i = 0; i < 10; i++) {\n            var popup = new OpenLayers.Popup(\"chicken\", \n                                             new OpenLayers.LonLat(0,0),\n                                             new OpenLayers.Size(200,200));\n            map.addPopup(popup);\n        }\n        t.eq(map.popups.length, 10, \"addPopup non exclusive mode works\");\n\n        var popup = new OpenLayers.Popup(\"chicken\", \n                                         new OpenLayers.LonLat(0,0),\n                                         new OpenLayers.Size(200,200));\n        map.addPopup(popup, true);\n        t.eq(map.popups.length, 1, \"addPopup exclusive mode works\");\n\n        map.destroy();\n    }   \n    \n\n/***  THIS IS A GOOD TEST, BUT IT SHOULD BE MOVED TO WMS. \n *     Also, it won't work until we figure out the viewSize bug\n\n    function 08_Map_px_lonlat_translation (t) {\n        t.plan( 6 );    \n        map = new OpenLayers.Map('map');\n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n        map.addLayer(baseLayer);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n \n        var pixel = new OpenLayers.Pixel(50,150);\n        var lonlat = map.getLonLatFromViewPortPx(pixel);\n        t.ok( lonlat instanceof OpenLayers.LonLat, \"getLonLatFromViewPortPx returns valid OpenLayers.LonLat\" );\n\n        var newPixel = map.getViewPortPxFromLonLat(lonlat);\n        t.ok( newPixel instanceof OpenLayers.Pixel, \"getViewPortPxFromLonLat returns valid OpenLayers.Pixel\" );\n\n        // WARNING!!!  I'm faily sure that the following test's validity \n        //             depends highly on rounding and the resolution. For now,\n        //             in the default case, it seems to work. This may not \n        //             always be so.\n        t.ok( newPixel.equals(pixel), \"Translation to pixel and back to lonlat is consistent\");\n\n        lonlat = map.getLonLatFromPixel(pixel);\n        t.ok( lonlat instanceof OpenLayers.LonLat, \"getLonLatFromPixel returns valid OpenLayers.LonLat\" );\n\n        newPixel = map.getPixelFromLonLat(lonlat);\n        t.ok( newPixel instanceof OpenLayers.Pixel, \"getPixelFromLonLat returns valid OpenLayers.Pixel\" );\n\n        t.ok( newPixel.equals(pixel), \"2nd translation to pixel and back to lonlat is consistent\");\n    }\n */\n\n    function test_Map_isValidZoomLevel(t) {\n        t.plan(5);\n        var map = new OpenLayers.Map(\"map\");\n        map.addLayer(new OpenLayers.Layer(null, {\n            isBaseLayer: true, wrapDateLine: true, numZoomLevels: 19\n        }));\n        map.zoomToMaxExtent();\n        \n        var valid;\n\n        valid = OpenLayers.Map.prototype.isValidZoomLevel.apply(map, [-1]);\n        t.eq(valid, false, \"-1 is not a valid zoomLevel\");\n\n        valid = OpenLayers.Map.prototype.isValidZoomLevel.apply(map, [0]);\n        t.eq(valid, true, \"0 is a valid zoomLevel\");\n\n        valid = OpenLayers.Map.prototype.isValidZoomLevel.apply(map, [18]);\n        t.eq(valid, true, \"18 is a valid zoomLevel\");\n\n        valid = OpenLayers.Map.prototype.isValidZoomLevel.apply(map, [19]);\n        t.eq(valid, false, \"19 is not a valid zoomLevel\");\n        \n        map.moveTo([16, 48], 0);\n        t.eq(map.getCenter().toShortString(), \"0, 0\", \"no panning when moveTo is called with invalid zoom\");\n\n        map.destroy();\n    }\n    \n    function test_Map_isValidLonLat(t) {\n        t.plan( 3 );    \n\n        map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS('Test Layer', \n                    \"http://octo.metacarta.com/cgi-bin/mapserv\", \n                    {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, \n                    {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:\"EPSG:2805\" } );\n        map.addLayer(layer);\n        \n        t.ok( !map.isValidLonLat(null), \"null lonlat is not valid\" );\n        t.ok( map.isValidLonLat(new OpenLayers.LonLat(33862, 717606)), \"lonlat outside max extent is valid\" );\n        t.ok( !map.isValidLonLat(new OpenLayers.LonLat(10, 10)), \"lonlat outside max extent is not valid\" );\n\n        map.destroy();\n    }\n\n    function test_Map_getLayer(t) {\n        var numLayers = 3;\n        t.plan( numLayers + 1 );    \n\n        var m = {\n            layers: []\n        };\n        \n        for(var i = 0; i < numLayers; i++) {\n            m.layers.push( { 'id': i } );\n        }\n\n        for(var i = 0; i < numLayers; i++) {\n            var layer = OpenLayers.Map.prototype.getLayer.apply(m, [i]);\n            t.ok( layer == m.layers[i], \"getLayer correctly returns layer \" + i);\n        }\n\n        var gotLayer = OpenLayers.Map.prototype.getLayer.apply(m, [\"chicken\"]);\n        t.ok( gotLayer == null, \"getLayer correctly returns null when layer not found\");\n\n        map.destroy();\n    }\n\n    function test_Map_getLayersBy(t) {\n        \n        var map = {\n            getBy: OpenLayers.Map.prototype.getBy,\n            getLayersBy: OpenLayers.Map.prototype.getLayersBy,\n            layers: [\n                {foo: \"foo\", id: Math.random()},\n                {foo: \"bar\", id: Math.random()},\n                {foo: \"foobar\", id: Math.random()},\n                {foo: \"foo bar\", id: Math.random()},\n                {foo: \"foo\", id: Math.random()}\n            ]\n        };\n\n        var cases = [\n            {\n                got: map.getLayersBy(\"foo\", \"foo\"),\n                expected: [map.layers[0], map.layers[4]],\n                message: \"(string literal) got two layers matching foo\"\n            }, {\n                got: map.getLayersBy(\"foo\", \"bar\"),\n                expected: [map.layers[1]],\n                message: \"(string literal) got one layer matching foo\"\n            }, {\n                got: map.getLayersBy(\"foo\", \"barfoo\"),\n                expected: [],\n                message: \"(string literal) got empty array for no foo match\"\n            }, {\n                got: map.getLayersBy(\"foo\", /foo/),\n                expected: [map.layers[0], map.layers[2], map.layers[3], map.layers[4]],\n                message: \"(regexp literal) got three layers containing string\"\n            }, {\n                got: map.getLayersBy(\"foo\", /foo$/),\n                expected: [map.layers[0], map.layers[4]],\n                message: \"(regexp literal) got three layers ending with string\"\n            }, {\n                got: map.getLayersBy(\"foo\", /\\s/),\n                expected: [map.layers[3]],\n                message: \"(regexp literal) got layer containing space\"\n            }, {\n                got: map.getLayersBy(\"foo\", new RegExp(\"BAR\", \"i\")),\n                expected: [map.layers[1], map.layers[2], map.layers[3]],\n                message: \"(regexp object) got layers ignoring case\"\n            }, {\n                got: map.getLayersBy(\"foo\", {test: function(str) {return str.length > 3;}}),\n                expected: [map.layers[2], map.layers[3]],\n                message: \"(custom object) got layers with foo length greater than 3\"\n            }\n        ];\n        t.plan(cases.length);\n        for(var i=0; i<cases.length; ++i) {\n            t.eq(cases[i].got, cases[i].expected, cases[i].message);\n        }\n        \n    }\n\n    function test_Map_getLayersByName(t) {\n        \n        var map = {\n            getBy: OpenLayers.Map.prototype.getBy,\n            getLayersBy: OpenLayers.Map.prototype.getLayersBy,\n            getLayersByName: OpenLayers.Map.prototype.getLayersByName,\n            layers: [\n                {name: \"foo\", id: Math.random()},\n                {name: \"bar\", id: Math.random()},\n                {name: \"foobar\", id: Math.random()},\n                {name: \"foo bar\", id: Math.random()},\n                {name: \"foo\", id: Math.random()}\n            ]\n        };\n\n        var cases = [\n            {\n                got: map.getLayersByName(\"foo\"),\n                expected: [map.layers[0], map.layers[4]],\n                message: \"(string literal) got two layers matching name\"\n            }, {\n                got: map.getLayersByName(\"bar\"),\n                expected: [map.layers[1]],\n                message: \"(string literal) got one layer matching name\"\n            }, {\n                got: map.getLayersByName(\"barfoo\"),\n                expected: [],\n                message: \"(string literal) got empty array for no match\"\n            }, {\n                got: map.getLayersByName(/foo/),\n                expected: [map.layers[0], map.layers[2], map.layers[3], map.layers[4]],\n                message: \"(regexp literal) got three layers containing string\"\n            }, {\n                got: map.getLayersByName(/foo$/),\n                expected: [map.layers[0], map.layers[4]],\n                message: \"(regexp literal) got three layers ending with string\"\n            }, {\n                got: map.getLayersByName(/\\s/),\n                expected: [map.layers[3]],\n                message: \"(regexp literal) got layer containing space\"\n            }, {\n                got: map.getLayersByName(new RegExp(\"BAR\", \"i\")),\n                expected: [map.layers[1], map.layers[2], map.layers[3]],\n                message: \"(regexp object) got layers ignoring case\"\n            }, {\n                got: map.getLayersByName({test: function(str) {return str.length > 3;}}),\n                expected: [map.layers[2], map.layers[3]],\n                message: \"(custom object) got layers with name length greater than 3\"\n            }\n        ];\n        t.plan(cases.length);\n        for(var i=0; i<cases.length; ++i) {\n            t.eq(cases[i].got, cases[i].expected, cases[i].message);\n        }\n        \n    }\n\n    function test_Map_getLayersByClass(t) {\n        \n        var map = {\n            getBy: OpenLayers.Map.prototype.getBy,\n            getLayersBy: OpenLayers.Map.prototype.getLayersBy,\n            getLayersByClass: OpenLayers.Map.prototype.getLayersByClass,\n            layers: [\n                {CLASS_NAME: \"foo\", id: Math.random()},\n                {CLASS_NAME: \"bar\", id: Math.random()},\n                {CLASS_NAME: \"foobar\", id: Math.random()},\n                {CLASS_NAME: \"foo bar\", id: Math.random()},\n                {CLASS_NAME: \"foo\", id: Math.random()}\n            ]\n        };\n\n        var cases = [\n            {\n                got: map.getLayersByClass(\"foo\"),\n                expected: [map.layers[0], map.layers[4]],\n                message: \"(string literal) got two layers matching type\"\n            }, {\n                got: map.getLayersByClass(\"bar\"),\n                expected: [map.layers[1]],\n                message: \"(string literal) got one layer matching type\"\n            }, {\n                got: map.getLayersByClass(\"barfoo\"),\n                expected: [],\n                message: \"(string literal) got empty array for no match\"\n            }, {\n                got: map.getLayersByClass(/foo/),\n                expected: [map.layers[0], map.layers[2], map.layers[3], map.layers[4]],\n                message: \"(regexp literal) got three layers containing string\"\n            }, {\n                got: map.getLayersByClass(/foo$/),\n                expected: [map.layers[0], map.layers[4]],\n                message: \"(regexp literal) got three layers ending with string\"\n            }, {\n                got: map.getLayersByClass(/\\s/),\n                expected: [map.layers[3]],\n                message: \"(regexp literal) got layer containing space\"\n            }, {\n                got: map.getLayersByClass(new RegExp(\"BAR\", \"i\")),\n                expected: [map.layers[1], map.layers[2], map.layers[3]],\n                message: \"(regexp object) got layers ignoring case\"\n            }, {\n                got: map.getLayersByClass({test: function(str) {return str.length > 3;}}),\n                expected: [map.layers[2], map.layers[3]],\n                message: \"(custom object) got layers with type length greater than 3\"\n            }\n        ];\n        t.plan(cases.length);\n        for(var i=0; i<cases.length; ++i) {\n            t.eq(cases[i].got, cases[i].expected, cases[i].message);\n        }\n        \n    }\n\n    function test_Map_getControlsBy(t) {\n        \n        var map = {\n            getBy: OpenLayers.Map.prototype.getBy,\n            getControlsBy: OpenLayers.Map.prototype.getControlsBy,\n            controls: [\n                {foo: \"foo\", id: Math.random()},\n                {foo: \"bar\", id: Math.random()},\n                {foo: \"foobar\", id: Math.random()},\n                {foo: \"foo bar\", id: Math.random()},\n                {foo: \"foo\", id: Math.random()}\n            ]\n        };\n\n        var cases = [\n            {\n                got: map.getControlsBy(\"foo\", \"foo\"),\n                expected: [map.controls[0], map.controls[4]],\n                message: \"(string literal) got two controls matching foo\"\n            }, {\n                got: map.getControlsBy(\"foo\", \"bar\"),\n                expected: [map.controls[1]],\n                message: \"(string literal) got one control matching foo\"\n            }, {\n                got: map.getControlsBy(\"foo\", \"barfoo\"),\n                expected: [],\n                message: \"(string literal) got empty array for no foo match\"\n            }, {\n                got: map.getControlsBy(\"foo\", /foo/),\n                expected: [map.controls[0], map.controls[2], map.controls[3], map.controls[4]],\n                message: \"(regexp literal) got three controls containing string\"\n            }, {\n                got: map.getControlsBy(\"foo\", /foo$/),\n                expected: [map.controls[0], map.controls[4]],\n                message: \"(regexp literal) got three controls ending with string\"\n            }, {\n                got: map.getControlsBy(\"foo\", /\\s/),\n                expected: [map.controls[3]],\n                message: \"(regexp literal) got control containing space\"\n            }, {\n                got: map.getControlsBy(\"foo\", new RegExp(\"BAR\", \"i\")),\n                expected: [map.controls[1], map.controls[2], map.controls[3]],\n                message: \"(regexp object) got layers ignoring case\"\n            }, {\n                got: map.getControlsBy(\"foo\", {test: function(str) {return str.length > 3;}}),\n                expected: [map.controls[2], map.controls[3]],\n                message: \"(custom object) got controls with foo length greater than 3\"\n            }\n        ];\n        t.plan(cases.length);\n        for(var i=0; i<cases.length; ++i) {\n            t.eq(cases[i].got, cases[i].expected, cases[i].message);\n        }\n        \n    }\n\n    function test_Map_getControlsByClass(t) {\n        \n        var map = {\n            getBy: OpenLayers.Map.prototype.getBy,\n            getControlsBy: OpenLayers.Map.prototype.getControlsBy,\n            getControlsByClass: OpenLayers.Map.prototype.getControlsByClass,\n            controls: [\n                {CLASS_NAME: \"foo\", id: Math.random()},\n                {CLASS_NAME: \"bar\", id: Math.random()},\n                {CLASS_NAME: \"foobar\", id: Math.random()},\n                {CLASS_NAME: \"foo bar\", id: Math.random()},\n                {CLASS_NAME: \"foo\", id: Math.random()}\n            ]\n        };\n\n        var cases = [\n            {\n                got: map.getControlsByClass(\"foo\"),\n                expected: [map.controls[0], map.controls[4]],\n                message: \"(string literal) got two controls matching type\"\n            }, {\n                got: map.getControlsByClass(\"bar\"),\n                expected: [map.controls[1]],\n                message: \"(string literal) got one control matching type\"\n            }, {\n                got: map.getControlsByClass(\"barfoo\"),\n                expected: [],\n                message: \"(string literal) got empty array for no match\"\n            }, {\n                got: map.getControlsByClass(/foo/),\n                expected: [map.controls[0], map.controls[2], map.controls[3], map.controls[4]],\n                message: \"(regexp literal) got three controls containing string\"\n            }, {\n                got: map.getControlsByClass(/foo$/),\n                expected: [map.controls[0], map.controls[4]],\n                message: \"(regexp literal) got three controls ending with string\"\n            }, {\n                got: map.getControlsByClass(/\\s/),\n                expected: [map.controls[3]],\n                message: \"(regexp literal) got control containing space\"\n            }, {\n                got: map.getControlsByClass(new RegExp(\"BAR\", \"i\")),\n                expected: [map.controls[1], map.controls[2], map.controls[3]],\n                message: \"(regexp object) got controls ignoring case\"\n            }, {\n                got: map.getControlsByClass({test: function(str) {return str.length > 3;}}),\n                expected: [map.controls[2], map.controls[3]],\n                message: \"(custom object) got controls with type length greater than 3\"\n            }\n        ];\n        t.plan(cases.length);\n        for(var i=0; i<cases.length; ++i) {\n            t.eq(cases[i].got, cases[i].expected, cases[i].message);\n        }\n        \n    }\n\n    function test_Map_double_addLayer(t) {\n        t.plan(2);\n\n        map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS('Test Layer', \n                    \"http://octo.metacarta.com/cgi-bin/mapserv\", \n                    {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'} \n                    );\n\n        var added = map.addLayer(layer);\n        t.ok(added === true, \"Map.addLayer returns true if the layer is added to the map.\");\n        var added = map.addLayer(layer);\n        t.ok(added === false, \"Map.addLayer returns false if the layer is already present.\");\n    \n        map.destroy();\n    }\n\n    function test_Map_setBaseLayer(t) {\n        t.plan( 6 );\n        \n        map = new OpenLayers.Map('map');\n\n        var wmslayer = new OpenLayers.Layer.WMS('Test Layer', \n                    \"http://octo.metacarta.com/cgi-bin/mapserv\", \n                    {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, \n                    {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:\"EPSG:2805\" } );\n\n        var wmslayer2 = new OpenLayers.Layer.WMS('Test Layer2', \n                    \"http://octo.metacarta.com/cgi-bin/mapserv\", \n                    {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, \n                    {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:\"EPSG:2805\" } );\n\n        map.addLayers([wmslayer, wmslayer2]);\n\n        t.ok(map.baseLayer == wmslayer, \"default base layer is first one added\");\n        \n        map.setBaseLayer(null);\n        t.ok(map.baseLayer == wmslayer, \"setBaseLayer on null object does nothing (and does not break)\");\n        \n        map.setBaseLayer(\"chicken\");\n        t.ok(map.baseLayer == wmslayer, \"setBaseLayer on non-layer object does nothing (and does not break)\");\n        \n        map.setBaseLayer(wmslayer2);\n        t.ok(map.baseLayer == wmslayer2, \"setbaselayer correctly sets 'baseLayer' property\");\n\n        map.destroy();\n\n        var l1 = new OpenLayers.Layer(),\n            l2 = new OpenLayers.Layer(null, {maxResolution: 1.4});\n        map = new OpenLayers.Map({\n            div: 'map',\n            allOverlays: true,\n            layers: [l1, l2],\n            zoom: 0,\n            center: [0, 0]\n        });\n        t.eq(l2.div.style.display, \"none\", \"Layer invisible because not in range\");\n        map.raiseLayer(l1, 1);\n        t.eq(l2.div.style.display, \"block\", \"Layer visible after base layer change because in range now\");\n        map.destroy();\n    }\n    \n    function test_Map_removeLayer(t) {\n        t.plan(1);\n        var f = function() {};\n        var events = {triggerEvent: f};\n        var layers = [\n            {name: \"fee\", removeMap: f, events: events},\n            {name: \"fi\", removeMap: f, events: events},\n            {name: \"fo\", removeMap: f, events: events},\n            {name: \"fum\", removeMap: f, events: events}\n        ];\n        var map = {\n            layers: layers,\n            baseLayer: layers[0],\n            layerContainerDiv: {removeChild: f},\n            events: {triggerEvent: f},\n            resetLayersZIndex: function() {}\n        };\n        OpenLayers.Map.prototype.removeLayer.apply(map, [map.baseLayer, false]);\n        t.eq(map.baseLayer, null,\n             \"removing the baselayer sets baseLayer to null\");        \n    }\n\n    function test_Map_removeLayer_res(t) {\n        t.plan(2);\n        \n        map = new OpenLayers.Map('map');\n\n        var layer0 = new OpenLayers.Layer.WMS(\n            'Test Layer 0', \n            \"http://octo.metacarta.com/cgi-bin/mapserv\", \n            {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, \n            {resolutions: [4, 2, 1]}\n        );\n\n        var layer1 = new OpenLayers.Layer.WMS(\n            'Test Layer 1', \n            \"http://octo.metacarta.com/cgi-bin/mapserv\", \n            {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, \n            {resolutions: [4, 2]}\n        );\n\n        map.addLayers([layer0, layer1]);\n        map.zoomToMaxExtent();\n        map.zoomTo(2);\n        t.eq(map.getResolution(), layer0.resolutions[2],\n             \"correct resolution before removal\");\n        map.removeLayer(layer0);\n        t.eq(map.getResolution(), layer0.resolutions[1],\n             \"correct resolution after removal\");\n\n        map.destroy();\n    }\n\n    function test_Map_removeLayer_zindex(t) {\n        t.plan(2);\n        \n        map = new OpenLayers.Map('map');\n\n        var layer0 = new OpenLayers.Layer('Test Layer 0', {isBaseLayer:true});\n        var layer1 = new OpenLayers.Layer('Test Layer 1', {isBaseLayer:true});\n        var layer2 = new OpenLayers.Layer('Test Layer 2', {isBaseLayer:false});\n\n        map.addLayers([layer0, layer1, layer2]);\n        map.removeLayer(layer0);\n\n        t.eq(parseInt(layer1.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'],\n             \"correct z-index after removeLayer\");\n        t.eq(parseInt(layer2.div.style.zIndex), map.Z_INDEX_BASE['Overlay'] + 5,\n             \"correct z-index after removeLayer\");\n\n        map.destroy();\n    }\n    \n\tfunction test_Map_removeLayer_preremovelayer(t) {\n        t.plan(4);\n        map = new OpenLayers.Map('map');\n\t\t\n        map.addLayer(new OpenLayers.Layer());\n        map.removeLayer(map.layers[0]);\n        \n        // one test: standard behaviour without listener\n        t.eq(map.layers.length, 0, \"without registered preremovelayer-listener layers can be removed as usual\");\n        \n        var callCnt = 0;\n        \n        map.events.register('preremovelayer', this, function(evt) {\n            callCnt++;\n            return !(evt.layer.name === 'donotremove');\n        });\n        var layer1 = new OpenLayers.Layer('donotremove');\n        var layer2 = new OpenLayers.Layer('doremove');\n\t\t\n        map.addLayers([layer1,layer2]);\n\t\t\n        // two tests: remove action can be canceled\n        map.removeLayer(layer1);\n        t.eq(map.layers.length, 2, \"layer is not removed since preremovelayer returns false\");\n        map.removeLayer(layer2);\n        t.eq(map.layers.length, 1, \"layer is removed since preremovelayer returns true\");\n        \n        // one test: listener was called twice\n        t.eq(callCnt, 2, \"preremovelayer-listener was called exactly twice\");\n        \n        map.destroy();\n\t}\n    \n    function test_Map_setBaseLayer_after_pan (t) {\n        t.plan(1);\n\n        map = new OpenLayers.Map('map');\n        var wmsLayer = new OpenLayers.Layer.WMS( \"OpenLayers WMS\", \n            \"http://labs.metacarta.com/wms/vmap0\", {layers: 'basic'} );\n        var tmsLayer = new OpenLayers.Layer.TMS(\"TMS\",\n                                    \"http://labs.metacarta.com/wms-c/Basic.py/\",\n                                    {'layername':'basic', 'type':'png'});\n        map.addLayers([wmsLayer,tmsLayer]);\n        map.setBaseLayer(wmsLayer);\n        map.zoomToMaxExtent();\n        map.setBaseLayer(tmsLayer);\n        map.zoomIn();\n        map.pan(0, -200, {animate:false});\n        var log = [];\n        map.applyTransform = function(x, y, scale) {\n            log.push([x || map.layerContainerOriginPx.x, y || map.layerContainerOriginPx.y, scale]);\n            OpenLayers.Map.prototype.applyTransform.apply(this, arguments);\n        };\n        map.setBaseLayer(wmsLayer);\n        t.eq(log[0][0], 0, \"layerContainer is recentered after setBaseLayer\");\n        \n        map.destroy();\n    }\n\n    function test_Map_moveLayer (t) {\n        t.plan(10);\n\n        var ct  = 0;\n        map = new OpenLayers.Map('map');\n        var wmslayer = new OpenLayers.Layer.WMS('Test Layer', \n                    \"http://octo.metacarta.com/cgi-bin/mapserv\", \n                    {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, \n                    {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:\"EPSG:2805\" } );\n\n        var wmslayer2 = new OpenLayers.Layer.WMS('Test Layer2', \n                    \"http://octo.metacarta.com/cgi-bin/mapserv\", \n                    {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, \n                    {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:\"EPSG:2805\" } );\n\n        var wmslayer3 = new OpenLayers.Layer.WMS('Test Layer2', \n                    \"http://octo.metacarta.com/cgi-bin/mapserv\", \n                    {map: '/mapdata/vmap_wms.map', layers: 'basic', format: 'image/jpeg'}, \n                    {maxExtent: new OpenLayers.Bounds(33861, 717605, 330846, 1019656), maxResolution: 296985/1024, projection:\"EPSG:2805\" } );\n\n        map.addLayers([wmslayer, wmslayer2, wmslayer3]);\n        map.events.register(\"changelayer\", map, function (e) { ct++; });\n        t.eq( map.getNumLayers(), 3, \"getNumLayers returns the number of layers\" );\n        t.eq( map.getLayerIndex(wmslayer3), 2, \"getLayerIndex returns the right index\" );\n        map.raiseLayer(wmslayer3, 1);\n        t.eq( map.getLayerIndex(wmslayer3), 2, \"can't moveLayer up past the top of the stack\" );\n        map.raiseLayer(wmslayer, -1);\n        t.eq( map.getLayerIndex(wmslayer), 0, \"can't moveLayer down past the bottom of the stack\" );\n        map.raiseLayer(wmslayer3, -1);\n        t.eq( map.getLayerIndex(wmslayer3), 1, \"can moveLayer down from the top\" );\n        t.eq( parseInt(wmslayer3.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'] + 5,\n            \"layer div has the right zIndex after moving down\" );\n        map.raiseLayer(wmslayer, 2);\n        t.eq( map.getLayerIndex(wmslayer), 2, \"can moveLayer up from the bottom\" );\n        t.eq( parseInt(wmslayer.div.style.zIndex), map.Z_INDEX_BASE['BaseLayer'] + 2 * 5,\n            \"layer div has the right zIndex after moving up\" );\n        t.eq( map.getLayerIndex(wmslayer3), 0, \"top layer is now on the bottom\" );\n        t.eq( ct, 3, \"raiseLayer triggered changelayer the right # of times\" );\n\n        map.destroy();\n    }\n\n    function test_Map_moveTo(t) {\n        t.plan(2);\n\n        map = new OpenLayers.Map('map');\n        var baseLayer = new OpenLayers.Layer.WMS(\"Test Layer\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"},\n            {maxResolution: 'auto', maxExtent: new OpenLayers.Bounds(-10,-10,10,10)});\n        baseLayer.events.on({\n            move: function() {\n                t.ok(true, \"move listener called\");\n            },\n            movestart: function(e) {\n                t.eq(e.zoomChanged, true, \"movestart listener called with expected value\");\n            }\n        });\n        baseLayer.events.on({\n            moveend: function(e) {\n                t.eq(e.zoomChanged, true, \"moveend listener called with expected value\");\n            }\n        });\n        map.addLayer(baseLayer);\n        var ll = new OpenLayers.LonLat(-100,-150);\n        map.moveTo(ll, 2);\n        t.ok(map.getCenter().equals(new OpenLayers.LonLat(0,0)), \"safely sets out-of-bounds lonlat\");\n\n        map.destroy();\n    }\n\n    function test_Map_defaultTheme(t) {\n        t.plan(5);\n        \n        var links = document.getElementsByTagName('link');\n        map = new OpenLayers.Map('map');\n        var gotNodes = 0;\n        var themeNode = null;\n        for(var i=0; i<links.length; ++i) {\n            if(OpenLayers.Util.isEquivalentUrl(map.theme, links.item(i).href)) {\n                gotNodes += 1;\n                themeNode = links.item(i);\n            }\n        }\n        t.eq(gotNodes, 1, \"by default, a single link node is added to document\");\n        t.ok(themeNode != null, \"a link node with the theme href was added\");\n        t.eq(themeNode.rel, \"stylesheet\", \"node added has rel set to stylesheet\");\n        t.eq(themeNode.type, \"text/css\", \"node added has type set to text/css\");\n        \n        // reconstruct the map to prove that another link is not added\n        map = new OpenLayers.Map('map');\n        t.eq(links.length, document.getElementsByTagName('link').length,\n             \"calling the map constructor twice with the same theme doesn't add duplicate link nodes\");\n\n        map.destroy();\n    }\n\n    function test_Map_customTheme(t) {\n        t.plan(5);\n        \n        var customTheme = 'foo';\n        var options = {theme: customTheme};\n        map = new OpenLayers.Map('map', options);\n\n        var links = document.getElementsByTagName('link');\n        var gotNodes = 0;\n        var themeNode = null;\n        for(var i=0; i<links.length; ++i) {\n            if(OpenLayers.Util.isEquivalentUrl(map.theme, links.item(i).href)) {\n                gotNodes += 1;\n                themeNode = links.item(i);\n            }\n        }\n        \n        t.eq(map.theme, customTheme, \"map theme is properly set\");\n        t.eq(gotNodes, 1, \"with custom theme, a single link node is added to document\");\n        t.ok(themeNode != null, \"a link node with the theme href was added\");\n        t.eq(themeNode.rel, \"stylesheet\", \"node added has rel set to stylesheet\");\n        t.eq(themeNode.type, \"text/css\", \"node added has type set to text/css\");\n        \n        map.destroy();\n    }\n\n    function test_Map_noTheme(t) {\n        t.plan(1);\n        \n        var head = document.getElementsByTagName('head')[0];\n        var nodeCount = head.childNodes.length;\n        \n        var options = {theme: null};\n        map = new OpenLayers.Map('map', options);\n\n        t.eq(nodeCount, head.childNodes.length, \"with no theme, a node is not added to document head\" );\n\n        map.destroy();\n    }\n\n    function test_Map_addControls(t) {\n        t.plan(5);\n        var map = new OpenLayers.Map('map', {\n            controls: []\n        });\n        var controls = [\n          new OpenLayers.Control({id:'firstctrl'}),\n          new OpenLayers.Control({id:'secondctrl'})\n        ];\n        map.addControls(controls);\n        t.eq(map.controls.length, 2, \"two controls were added by map.addControls without a px-array\");\n        t.eq(map.controls[0].id, 'firstctrl', \"control with index 0 has id 'firstctrl'\");\n        t.eq(map.controls[1].id, 'secondctrl', \"control with index 1 has id 'secondctrl'\");\n        \n        var controls2 = [\n          new OpenLayers.Control({id:'thirdctrl'}),\n          new OpenLayers.Control({id:'fourthctrl'}),\n          new OpenLayers.Control({id:'fifthctrl'})\n        ];\n        // this array is intentionally one element shorter than the above       \n        var pixels2 = [\n          null,\n          new OpenLayers.Pixel(27,11)\n        ];\n        map.addControls(controls2, pixels2);\n        t.eq(map.controls.length, 5, \"three additional controls were added by map.addControls with a px-array\");\n        t.eq(map.controls[3].position.toString(), pixels2[1].toString(), \"control 'fourthctrl' has position set to given px\");\n\n        map.destroy();\n    }\n\n    function test_Map_getControl(t) {\n        t.plan(2);\n        \n        var map1 = new OpenLayers.Map('map');\n        \n        var control = new OpenLayers.Control();\n        map1.addControl(control);\n\n        var gotControl = map1.getControl(control.id);\n        t.ok(gotControl == control, \"got right control\");\n        \n        gotControl = map1.getControl(\"bogus id\");\n        t.ok(gotControl == null, \"getControl() for bad id returns null\");\n\n        map1.destroy();\n    }\n\n    function test_Map_removeControl(t) {\n        t.plan(6);\n        \n        var oldNumControls, newNumControls;\n        \n        var map1 = new OpenLayers.Map('map');\n        oldNumControls = map1.controls.length;\n        \n        var control = new OpenLayers.Control();\n        map1.addControl(control);\n\n    //add control        \n        newNumControls = map1.controls.length;\n        t.ok( newNumControls = oldNumControls + 1, \"adding a control increases control count\")\n\n        var foundDiv = false;\n        for(var i=0; i < map1.viewPortDiv.childNodes.length; i++) {\n            var childNode = map1.viewPortDiv.childNodes[i];\n            if (childNode == control.div) {\n                foundDiv = true;\n            }\n        }\n        t.ok(foundDiv, \"new control's div correctly added to viewPort\");\n\n    //remove control        \n        map1.removeControl(control)\n        newNumControls = map1.controls.length;\n        t.ok( newNumControls == oldNumControls, \"removing the control decreases control count\")\n\n        var gotControl = map1.getControl(control.id);\n        t.ok( gotControl == null, \"control no longer in map's controls array\");\n\n        var foundDiv = false;\n        for(var i=0; i < map1.viewPortDiv.childNodes.length; i++) {\n            var childNode = map1.viewPortDiv.childNodes[i];\n            if (childNode == control.div) {\n                foundDiv = true;\n            }\n        }\n        t.ok(!foundDiv, \"control no longer child of viewPort\");\n\n    //remove bogus\n        control = { id: \"bogus id\" };\n        map1.removeControl(control);\n        newNumControls = map1.controls.length;\n        t.ok( newNumControls == oldNumControls, \"removing bad controlid doesnt crash or decrease control count\")\n\n        map1.destroy();\n\n    }\n\n    function test_Map_restrictedExtent(t) {\n        t.plan(25);\n        var extent = new OpenLayers.Bounds(-180, -90, 180, 90);\n        var options = {\n            maxResolution: \"auto\"\n        };\n        var map = new OpenLayers.Map(\"map\", options);\n        var layer = new OpenLayers.Layer.WMS(\n            \"test\", \n            \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n            {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"}\n        );\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        var nw = new OpenLayers.LonLat(extent.left, extent.top);\n        var ne = new OpenLayers.LonLat(extent.right, extent.top);\n        var sw = new OpenLayers.LonLat(extent.left, extent.bottom);\n        var se = new OpenLayers.LonLat(extent.right, extent.bottom);\n        \n        // try panning to northwest corner\n        map.setOptions({restrictedExtent: extent});\n        map.setCenter(nw, 0);\n        t.eq(map.getExtent().getCenterLonLat().toString(),\n             extent.getCenterLonLat().toString(),\n             \"map extent properly restricted to northwest at zoom 0\");\n        t.eq(map.zoom, 0, \"zoom not restricted for nw, 0\");\n        map.setCenter(nw, 5);\n        t.eq(map.getExtent().top, extent.top,\n             \"map extent top properly restricted to northwest at zoom 5\");\n        t.eq(map.getExtent().left, extent.left,\n             \"map extent left properly restricted to northwest at zoom 5\");\n        t.eq(map.zoom, 5, \"zoom not restricted for nw, 5\");\n        map.setOptions({restrictedExtent: null});\n        map.setCenter(nw, 0);\n        t.eq(map.getExtent().getCenterLonLat().toString(),\n             nw.toString(),\n             \"map extent not restricted with null restrictedExtent for nw\");\n\n        // try panning to northeast corner\n        map.setOptions({restrictedExtent: extent});\n        map.setCenter(ne, 0);\n        t.eq(map.getExtent().getCenterLonLat().toString(),\n             extent.getCenterLonLat().toString(),\n             \"map extent properly restricted to northeast at zoom 0\");\n        t.eq(map.zoom, 0, \"zoom not restricted for ne, 0\");\n        map.setCenter(ne, 5);\n        t.eq(map.getExtent().top, extent.top,\n             \"map extent top properly restricted to northeast at zoom 5\");\n        t.eq(map.getExtent().right, extent.right,\n             \"map extent right properly restricted to northeast at zoom 5\");\n        t.eq(map.zoom, 5, \"zoom not restricted for ne, 5\");\n        map.setOptions({restrictedExtent: null});\n        map.setCenter(ne, 0);\n        t.eq(map.getExtent().getCenterLonLat().toString(),\n             ne.toString(),\n             \"map extent not restricted with null restrictedExtent for ne\");\n        \n        // try panning to southwest corner\n        map.setOptions({restrictedExtent: extent});\n        map.setCenter(sw, 0);\n        t.eq(map.getExtent().getCenterLonLat().toString(),\n             extent.getCenterLonLat().toString(),\n             \"map extent properly restricted to southwest at zoom 0\");\n        t.eq(map.zoom, 0, \"zoom not restricted for sw, 0\");\n        map.setCenter(sw, 5);\n        t.eq(map.getExtent().bottom, extent.bottom,\n             \"map extent bottom properly restricted to southwest at zoom 5\");\n        t.eq(map.getExtent().left, extent.left,\n             \"map extent left properly restricted to southwest at zoom 5\");\n        t.eq(map.zoom, 5, \"zoom not restricted for sw, 5\");\n        map.setOptions({restrictedExtent: null});\n        map.setCenter(sw, 0);\n        t.eq(map.getExtent().getCenterLonLat().toString(),\n             sw.toString(),\n             \"map extent not restricted with null restrictedExtent for sw\");\n\n        // try panning to southeast corner\n        map.setOptions({restrictedExtent: extent});\n        map.setCenter(se, 0);\n        t.eq(map.getExtent().getCenterLonLat().toString(),\n             extent.getCenterLonLat().toString(),\n             \"map extent properly restricted to southeast at zoom 0\");\n        t.eq(map.zoom, 0, \"zoom not restricted for se, 0\");\n        map.setCenter(se, 5);\n        t.eq(map.getExtent().bottom, extent.bottom,\n             \"map extent bottom properly restricted to southeast at zoom 5\");\n        t.eq(map.getExtent().right, extent.right,\n             \"map extent right properly restricted to southeast at zoom 5\");\n        t.eq(map.zoom, 5, \"zoom not restricted for se, 5\");\n        map.setOptions({restrictedExtent: null});\n        map.setCenter(se, 0);\n        t.eq(map.getExtent().getCenterLonLat().toString(),\n             se.toString(),\n             \"map extent not restricted with null restrictedExtent for se\");\n\n        map.destroy();\n\n        extent = new OpenLayers.Bounds(8, 44.5, 19, 50);\n        var options = {\n            restrictedExtent: extent,\n            zoomMethod: null\n        };\n        map = new OpenLayers.Map('map', options);\n\n        var wms = new OpenLayers.Layer.WMS(\n            \"OpenLayers WMS\", \n            \"http://vmap0.tiles.osgeo.org/wms/vmap0?\",\n            {layers: 'basic'}\n        ); \n\n        map.addLayers([wms]);\n        map.zoomToExtent(extent);\n        map.zoomIn();\n        map.setOptions({restrictedExtent: null});\n        map.pan(-250, -250);\n        t.ok((map.getExtent().bottom == 48.3486328125 && map.getExtent().left == 7.45751953125), \"Expected extent when toggling restrictedExtent\");\n        map.destroy();\n    }\n\n    function test_Map_getResolutionForZoom(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var res = map.getResolutionForZoom();\n        t.eq(res, null, \"getResolutionForZoom returns null for no base layer\");\n        map.fractionalZoom = true;\n        var layer = new OpenLayers.Layer(\"test\", {isBaseLayer: true});\n        map.addLayer(layer);\n        layer.getResolutionForZoom = function() {\n            t.ok(true, \"getResolutionForZoom calls base layer getResolutionForZoom\");\n        }\n        var res = map.getResolutionForZoom();\n        layer.destroy();\n        map.destroy();\n    }\n    \n    function test_zoomTo(t) {\n        t.plan(8);\n        \n        var map = new OpenLayers.Map(\"map\", {zoomMethod: null});\n        map.addLayer(new OpenLayers.Layer(null, {\n            isBaseLayer: true\n        }));\n        \n        map.zoomToMaxExtent();\n        \n        map.zoomTo(2);\n        t.eq(map.getZoom(), 2, 'zoomTo(2)');\n\n        map.zoomTo(3.6);\n        t.eq(map.getZoom(), 4, 'zoomTo(3.6)');\n        \n        map.zoomTo(\"4.6\");\n        t.eq(map.getZoom(), 5, 'zoomTo(\"4.6\")');\n        \n        map.zoomTo(\"1.2\");\n        t.eq(map.getZoom(), 1, 'zoomTo(\"1.2\")');\n        \n        // now allow fractional zoom\n        map.fractionalZoom = true;\n        \n        map.zoomTo(2);\n        t.eq(map.getZoom(), 2, '[fractionalZoom] zoomTo(2)');\n\n        map.zoomTo(3.6);\n        t.eq(map.getZoom(), 3.6, '[fractionalZoom] zoomTo(3.6)');\n        \n        map.zoomTo(\"4.6\");\n        t.eq(map.getZoom(), 4.6, '[fractionalZoom] zoomTo(\"4.6\")');\n        \n        map.zoomTo(\"1.2\");\n        t.eq(map.getZoom(), 1.2, '[fractionalZoom] zoomTo(\"1.2\")');\n        \n        map.destroy();\n    }\n    \n    function test_zoomTo_animated(t) {\n        t.plan(2);\n        \n        var map = new OpenLayers.Map(\"map\");\n        map.addLayer(new OpenLayers.Layer(null, {\n            isBaseLayer: true\n        }));\n        \n        map.zoomToMaxExtent();\n        \n        map.zoomTo(2);\n        map.zoomIn();\n        map.zoomOut();\n        map.zoomIn();\n        t.delay_call(2, function() {\n            t.eq(map.getZoom(), 3, '[fractionalZoom: false] zoomTo(2) - zoomIn() - zoomOut() - zoomIn()');\n\n            // now allow fractional zoom\n            map.fractionalZoom = true;\n\n            map.zoomTo(2.6);\n            map.zoomIn();\n            map.zoomOut();\n            map.zoomIn();\n        });\n        t.delay_call(4, function() {\n            t.eq(map.getZoom(), 3.6, '[fractionalZoom: true] zoomTo(2) - zoomIn() - zoomOut() - zoomIn()');\n            map.destroy();\n        });\n        \n    }\n    \n    function test_Map_getUnits(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map(\"map\");\n        var units = map.getUnits();\n        t.eq(units, null, \"getUnits returns null for no base layer\");\n        \n        var layer = new OpenLayers.Layer(\"test\", {\n            isBaseLayer: true,\n            units: 'foo'\n        });\n        map.addLayer(layer);\n        var units = map.getUnits();\n        t.eq(units, 'foo', \"getUnits returns the base layer units property\");\n        layer.destroy();\n        map.destroy();\n    }\n\n    function test_Map_destroy (t) {\n        t.plan( 3 );    \n        map = new OpenLayers.Map('map');\n        map.destroy();\n        t.eq( map.layers, null, \"map.layers is null after destroy\" );\n        t.eq( map.controls, null, \"map.controls is null after destroy\" );\n        t.eq( map.viewPortDiv, null, \"map's viewportDiv nullified\");\n    }\n\n    function test_Map_getMaxExtent(t){\n        t.plan(5);\n\n        var options = null;\n        var map = {};\n\n      //null options, no baseLayer\n        var maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);\n        t.eq(maxExtent, null, \"null options, no baseLayer returns null\");     \n\n      //null options.restricted, no baseLayer\n        maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);\n        t.eq(maxExtent, null, \"null options.restricted, no baseLayer returns null\");     \n\n      //true options.restricted, null map.restrictedExtent no baseLayer\n        maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);\n        t.eq(maxExtent, null, \"true options.restricted, null map.restrictedExtent no baseLayer returns null\");     \n\n      //true options.restricted, valid map.restrictedExtent no baseLayer\n        options = {\n            'restricted': true\n        };\n        map.restrictedExtent = {};\n        maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);\n        t.ok(maxExtent == map.restrictedExtent, \"true options.restricted, valid map.restrictedExtent no baseLayer returns map.restrictedExtent\");     \n\n      //null options, valid baseLayer\n        options = null;\n        map.baseLayer = {\n            'maxExtent': {}\n        };\n        var maxExtent = OpenLayers.Map.prototype.getMaxExtent.apply(map, [options]);\n        t.ok(maxExtent == map.baseLayer.maxExtent, \"null options, valid baseLayer returns map.baseLayer.maxExtent\");     \n    }\n    \n    function test_Map_zoomToMaxExtent(t){\n        t.plan(4)\n\n        gMaxExtent = {};\n\n        var map = {\n            'getMaxExtent': function(options) {\n                gRestricted = options.restricted; \n                return gMaxExtent;\n            }, \n            'zoomToExtent': function(extent) {\n                t.ok(extent == gMaxExtent, \"zoomToExtent() always called on return from map.getMaxExtent()\");\n            } \n        };\n\n      //options is null\n        var options = null;\n        gRestricted = null;\n        OpenLayers.Map.prototype.zoomToMaxExtent.apply(map, [options]);\n        t.eq(gRestricted, true, \"default 'restricted' passed to map.getMaxExtent() is true\");\n        \n      //valid options\n        options = {\n            'restricted': {}\n        };\n        gRestricted = null;\n        OpenLayers.Map.prototype.zoomToMaxExtent.apply(map, [options]);\n        t.ok(gRestricted == options.restricted, \"when valid options argument, 'options.restricted' passed to map.getMaxExtent()\");\n    }\n\n    function test_Map_zoomToScale(t) {\n        t.plan(4);\n        \n        var m = {\n            'baseLayer': { 'units': {} },\n            'size': {'w': 10, 'h': 15},\n            'getSize': function() { return {'w': 10, 'h': 15}; },\n            'getCachedCenter': function() { return {'lon': -5, 'lat': -25}; },\n            'zoomToExtent': function(extent, closest) {\n                t.ok(extent.equals(g_ExpectedExtent), \"extent correctly calculated for zoomToExtent()\");\n                t.ok(closest == g_Closest, \"closest correctly passed on to zoomToExtent()\");\n            }            \n        }\n\n        var temp = OpenLayers.Util.getResolutionFromScale;\n        OpenLayers.Util.getResolutionFromScale = function(scale, units) {\n            t.ok(scale == g_Scale, \"scale parameter correctly passed to getResolutionFromScale\");\n            t.ok(units == m.baseLayer.units, \"map's baselayer's units parameter correctly passed to getResolutionFromScale\");\n            return 1000;\n        };\n \n        g_ExpectedExtent = new OpenLayers.Bounds(-5005,-7525,4995,7475);\n        g_Scale = {};\n        g_Closest = {};\n        var args = [g_Scale, g_Closest];\n        OpenLayers.Map.prototype.zoomToScale.apply(m, args);    \n\n        OpenLayers.Util.getResolutionFromScale = temp;\n    }\n    \n    function test_Map_zoomToExtent(t) {\n        t.plan(12);\n        \n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer(null, {isBaseLayer: true});\n        map.addLayer(layer);\n        \n        var bounds = new OpenLayers.Bounds(-160, 15, -50, 69);\n        var center;\n        \n        // default for closest\n        map.zoomToExtent(bounds);\n        center = map.getCenter();\n        t.eq(center.lon, -105, \"a) correct x\");\n        t.eq(center.lat, 42, \"a) correct y\");\n        t.eq(map.getZoom(), 2, \"a) correct zoom\");\n\n        // false for closest\n        map.zoomToExtent(bounds, false);\n        center = map.getCenter();\n        t.eq(center.lon, -105, \"b) correct x\");\n        t.eq(center.lat, 42, \"b) correct y\");\n        t.eq(map.getZoom(), 2, \"b) correct zoom\");\n\n        // true for closest\n        map.zoomToExtent(bounds, true);\n        center = map.getCenter();\n        t.eq(center.lon, -105, \"c) correct x\");\n        t.eq(center.lat, 42, \"c) correct y\");\n        t.eq(map.getZoom(), 3, \"c) correct zoom\");\n\n        // accept array\n        map.zoomToExtent([-160, 15, -50, 69]);\n        center = map.getCenter();\n        t.eq(center.lon, -105, \"(array) correct x\");\n        t.eq(center.lat, 42, \"(array) correct y\");\n        t.eq(map.getZoom(), 2, \"(array) correct zoom\");\n        \n        map.destroy();\n    }\n\n    function test_Map_zoomToExtent_wrapped(t) {\n        t.plan(9);\n        \n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer(null, {isBaseLayer: true, wrapDateLine: true});\n        map.addLayer(layer);\n        \n        var bounds, center;\n        \n        var cases = [{\n            // real world\n            bbox: [120, -20, 140, 0],\n            center: [130, -10]\n        }, {\n            // one world to the right\n            bbox: [220, -45, 240, 45],\n            center: [-130, 0]\n        }, {\n            // two worlds to the right\n            bbox: [550, -15, 560, 5],\n            center: [-165, -5]\n        }, {\n            // one world to the left\n            bbox: [-240, -15, -220, 5],\n            center: [130, -5]\n        }, {\n            // two worlds to the left\n            bbox: [-600, -15, -580, 5],\n            center: [130, -5]\n        }];\n        \n        var num = cases.length;\n        t.plan(num * 2);\n        \n        var c, bounds, center;\n        for (var i=0; i<num; ++i) {\n            c = cases[i];\n            bounds = OpenLayers.Bounds.fromArray(c.bbox);\n            map.zoomToExtent(bounds);\n            center = map.getCenter();\n            t.eq(center.lon, c.center[0], \"y: \" + bounds);\n            t.eq(center.lat, c.center[1], \"x: \" + bounds);\n        }\n        \n        map.destroy();\n    }\n\n    \n    function test_allOverlays(t) {\n        \n        t.plan(18);\n\n        var map = new OpenLayers.Map({\n            div: \"map\", allOverlays: true\n        });\n        \n        var a = new OpenLayers.Layer.Vector(\"a\", {visibility: true});\n\n        var b = new OpenLayers.Layer.Image(\n            \"b\",\n            \"http://earthtrends.wri.org/images/maps/4_m_citylights_lg.gif\",\n            new OpenLayers.Bounds(-180, -88.759, 180, 88.759),\n            new OpenLayers.Size(580, 288)\n        );\n\n        var c = new OpenLayers.Layer.WMS(\n            \"c\",\n            \"http://labs.metacarta.com/wms/vmap0\",\n            {layers: 'basic'}\n        );\n\n        var d = new OpenLayers.Layer.Vector(\"d\");\n        \n        map.addLayers([a, b, c, d]);\n\n        var moveCount = 0;\n        a.moveTo = function() {\n            moveCount++;\n            OpenLayers.Layer.Vector.prototype.moveTo.apply(this, arguments);\n        };\n\n        map.zoomToMaxExtent();\n        t.eq(moveCount, 1, \"map.moveTo moves the base layer only once\");\n        t.eq(map.getCenter().toString(), \"lon=0,lat=0\", \"a map with all overlays can have a center\");\n\n        a.setVisibility(false);\n        var moveend = 0;\n        a.events.on({\"moveend\": function() { moveend++; }}); \n        map.zoomToMaxExtent();\n        t.eq(moveCount, 1, \"map.moveTo does not move the base layer if it is invisible\");\n        t.eq(moveend, 0, \"map.moveTo does not trigger \\\"moveend\\\" in the layer if the layer is invisible\");\n        a.setVisibility(true);\n        \n        // a, b, c, d\n        t.eq(map.baseLayer.name, \"a\", \"base layer set to first layer added\");\n        \n        map.removeLayer(a);\n        // b, c, d\n        t.eq(map.baseLayer.name, \"b\", \"if base layer is removed, lowest layer becomes base\");\n        \n        map.addLayer(a);\n        // b, c, d, a\n        t.eq(map.baseLayer.name, \"b\", \"adding a new layer doesn't change base layer\");\n        \n        map.setLayerIndex(c, 1);\n        // b, d, c, a\n        t.eq(map.baseLayer.name, \"b\", \"changing layer order above base doesn't mess with base\");\n        \n        map.setLayerIndex(d, 0);\n        // d, b, c, a\n        t.eq(map.baseLayer.name, \"d\", \"changing layer order to 0 sets base layer\");\n        \n        map.raiseLayer(d, 1);\n        // b, d, c, a\n        t.eq(map.baseLayer.name, \"b\", \"raising the base layer sets a new base layer\");\n        \n        map.raiseLayer(d, -1);\n        // d, b, c, a\n        t.eq(map.baseLayer.name, \"d\", \"lowering a layer to lowest index sets as base\");\n        \n        // all this switching of base layer didn't muck with layer visibility\n        t.eq(a.visibility, true, \"a is visible\");\n        t.eq(b.visibility, true, \"b is visible\");\n        t.eq(c.visibility, true, \"c is visible\");\n        t.eq(d.visibility, true, \"d is visible\");\n        \n        // test that map can have an invisible base layer\n        b.setVisibility(false);\n        map.setLayerIndex(b, 0);\n        t.eq(b.visibility, false, \"changing layer order doesn't change visibility\");\n\n       \n        map.destroy();\n        \n        // make sure setVisibility is called when adding a single layer to the map\n        map = new OpenLayers.Map({\n            div: \"map\", allOverlays: true\n        });\n        var count = 0;\n        var layer = new OpenLayers.Layer(null, {\n            visibility: true,\n            maxExtent: new OpenLayers.Bounds(-180, -90, 180, 90),\n            setVisibility: function() {\n                ++count;\n                OpenLayers.Layer.prototype.setVisibility.apply(this, arguments);\n            }\n        });\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        \n        t.eq(count, 1, \"setVisibility called when visibility is true in layer config\");\n        t.eq(layer.div.style.display, \"\", \"layer is visible.\");\n\n        map.destroy();\n        \n    }\n    \n    function test_panTo(t) {\n        \n        t.plan(6);\n        \n        var log = [];\n        var map = new OpenLayers.Map(\"map\", {\n            eventListeners: {\n                \"movestart\": function() {log.push(\"movestart\");},\n                \"move\": function() {log.push(\"move\");},\n                \"moveend\": function() {log.push(\"moveend\");}\n            }            \n        });\n        map.addLayer(\n            new OpenLayers.Layer(null, {isBaseLayer: true})\n        );\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n        t.eq(log[log.length-1], \"moveend\", \"moveend fired when map center is set\");\n        log = [];\n        \n        map.panTo(new OpenLayers.LonLat(1, 0));\n        t.eq(map.panTween.playing, true, \"the map pan tween is playing before destroy\");\n        \n        t.delay_call(2, function() {\n            t.eq(log[0], \"movestart\", \"panTo starts with movestart event\");\n            t.eq(log[1], \"move\", \"move events fired while panning\");\n            t.eq(log[log.length-1], \"moveend\", \"panTo finishes with moveend event\");\n            map.destroy();\n            t.ok(!map.panTween || !map.panTween.playing, \"the map pan tween is not playing after destroy\");\n        });\n    }\n    \n    function test_pan(t) {\n        t.plan(4);\n        \n        var map = new OpenLayers.Map(\"map\");\n        map.addLayer(\n            new OpenLayers.Layer(null, {isBaseLayer: true})\n        );\n        map.setCenter(new OpenLayers.LonLat(0, 0), 5);\n        var log = [];\n        map.events.on({\n            \"movestart\": function() {log.push(\"movestart\");},\n            \"move\": function() {log.push(\"move\");},\n            \"moveend\": function() {log.push(\"moveend\");}\n        });\n        \n        // simulate the drag sequence of the DragPan control;\n        map.pan(5,5, {animate: false, dragging: true});\n        map.pan(1,1, {animate: false, dragging: false});\n        \n        t.eq(log[0], \"movestart\", \"pan sequence starts with movestart\");\n        t.eq(log[1], \"move\", \"followed by move,\");\n        t.eq(log[log.length-2], \"move\", \"move again before we stop panning,\");\n        t.eq(log[log.length-1], \"moveend\", \"and moveend when we're done.\");\n    }\n\n    function test_pan_no_anim_event_sequence(t) {\n        t.plan(4);\n\n        var log = [];\n        var map = new OpenLayers.Map(\"map\");\n        map.addLayer(\n            new OpenLayers.Layer(null, {isBaseLayer: true})\n        );\n        map.setCenter(new OpenLayers.LonLat(0, 0), 5);\n        map.events.on({\n            \"movestart\": function() {\n                log.push(\"movestart\");\n            },\n            \"move\": function() {\n                log.push(\"move\");\n            },\n            \"moveend\": function() {\n                log.push(\"moveend\");\n            }\n        });\n\n        map.pan(5,5, {animate: false});\n        t.eq(log.length, 3, \"no more than 3 events happen.\");\n        t.eq(log[0], \"movestart\", \"pan sequence starts with movestart\");\n        t.eq(log[1], \"move\", \"followed by move,\");\n        t.eq(log[2], \"moveend\", \"and moveend when we're done.\");\n\n        map.destroy();\n    }\n\n    // test if we can call updateSize before document.body is ready. updateOk\n    // is tested in the test_updateSize function below\n    var earlyMap = new OpenLayers.Map();\n    var updateOk;\n    try {\n      earlyMap.updateSize();\n      updateOk = true;\n    } catch(e) {}\n    earlyMap.destroy();\n    function test_updateSize(t) {\n        t.plan(3);\n\n        // checking updateSize from outside this test function (see above)\n        t.ok(updateOk, \"updateSize works before document.body is ready\");\n\n        var map, moveToCnt, size;\n\n        map = new OpenLayers.Map({div: \"map\"});\n        map.addLayer(new OpenLayers.Layer(\"layer\", {isBaseLayer: true}));\n\n        map.moveTo = function() {\n            moveToCnt++;\n            OpenLayers.Map.prototype.moveTo.apply(this, arguments);\n        };\n\n        map.getCurrentSize = function() {\n            return size;\n        };\n\n        // map has no center\n        // 1 test\n        moveToCnt = 0;\n        size = new OpenLayers.Size(650, 350);\n        map.updateSize();\n        t.eq(moveToCnt, 0, \"updateSize doesn't move the map if it doesn't have a center\");\n\n        // map has a center\n        // 1 test\n        map.zoomToMaxExtent();\n        moveToCnt = 0;\n        size = new OpenLayers.Size(600, 300);\n        map.updateSize();\n        t.eq(moveToCnt, 1, \"updateSize move the map if it has a center\");\n\n        map.destroy();        \n    }\n    \n    function test_invisible_map(t) {\n        /** \n         * This test confirms that initializing a map using an element that is \n         * not currently displayed doesn't cause any trouble.\n         */\n        t.plan(1);\n        \n        var map, msg = \"initializing a map on an undisplayed element\";\n        try {\n            map = new OpenLayers.Map(\"invisimap\");\n        } catch (err) {\n            msg += \": \" + err;\n        }\n        t.ok(!!map, msg);\n        \n        if (map) {\n            map.destroy();\n        }        \n    }\n    \n    function test_layers_option(t) {\n        \n        t.plan(3);\n\n        var map = new OpenLayers.Map({\n            div: \"map\",\n            layers: [\n                new OpenLayers.Layer()\n            ]\n        });\n        \n        t.eq(map.layers.length, 1, \"single layer from options added\");\n\n        map.destroy();\n        \n        map = new OpenLayers.Map({\n            div: \"map\",\n            layers: [\n                new OpenLayers.Layer(null, {isBaseLayer: true}),\n                new OpenLayers.Layer(null, {isBaseLayer: false})\n            ]\n        });\n        \n        t.eq(map.layers.length, 2, \"multiple layers added from options\");\n        t.ok(map.baseLayer, \"map has a base layer\");\n\n        map.destroy();\n        \n    }\n    \n    function test_center_option(t) {\n        t.plan(7);\n        \n        var map, msg;\n        \n        \n        // try setting center without layers, this has no effect\n        var failed = false;\n        try {\n            map = new OpenLayers.Map({\n                div: \"map\",\n                center: new OpenLayers.LonLat(1, 2)\n            });\n            msg = \"center option without layers has no effect\";\n        } catch (err) {\n            failed = true;\n            msg = \"center option without layers throws error\";\n        }\n        t.ok(!failed, msg);\n        \n        if (map) {\n            map.destroy();\n        }\n        \n        var log = [];\n        var meth = OpenLayers.Layer.prototype.moveTo;\n        OpenLayers.Layer.prototype.moveTo = function() {\n            log.push(arguments);\n            meth.apply(this, arguments);\n        };\n        \n        // set center without zoom\n        var center = new OpenLayers.LonLat(1, 2);\n        map = new OpenLayers.Map({\n            div: \"map\",\n            layers: [new OpenLayers.Layer(null, {isBaseLayer: true})],\n            center: center\n        });\n        \n        t.ok(center.equals(map.getCenter()), \"map center set without zoom\");\n        t.eq(log.length, 1, \"moveTo called once\");\n        \n        map.destroy();\n        OpenLayers.Layer.prototype.moveTo = meth;\n        \n        // set center and zoom\n        var zoom = 3;\n        map = new OpenLayers.Map({\n            div: \"map\",\n            layers: [new OpenLayers.Layer(null, {isBaseLayer: true})],\n            center: center,\n            zoom: zoom\n        });\n\n        t.ok(center.equals(map.getCenter()), \"map center set with center and zoom\");\n        t.eq(zoom, map.getZoom(), \"map zoom set with center and zoom\");\n        \n        map.destroy();\n        \n        // set center and zoom with all overlays\n        map = new OpenLayers.Map({\n            div: \"map\",\n            allOverlays: true,\n            layers: [new OpenLayers.Layer()],\n            center: center,\n            zoom: zoom\n        });\n        \n        t.ok(center.equals(map.getCenter()), \"map center set with all overlays\");\n        t.eq(zoom, map.getZoom(), \"map zoom set with all overlays\");        \n        \n        map.destroy();\n        \n    }\n    function test_pixel_lonlat(t) {\n        \n        t.plan(4);\n\n        var map = new OpenLayers.Map({\n            div: \"map\",\n            layers: [\n                new OpenLayers.Layer(\"name\", {isBaseLayer:true})\n            ]\n        });\n        map.zoomToMaxExtent();\n        var px = map.getPixelFromLonLat(map.getLonLatFromPixel(new OpenLayers.Pixel(100, 100)));\n        t.eq(px.x, 100, \"x is the same in and ot\");\n        t.eq(px.y, 100, \"y is the same in and out\");\n        var ll = map.getLonLatFromPixel(map.getPixelFromLonLat(new OpenLayers.LonLat(100, 100)));\n        t.ok((ll.lon > (100 -map.getResolution()) && (ll.lon < (100 + map.getResolution()))), \"lon is the same in and ot\");\n        t.ok((ll.lat > (100 -map.getResolution()) && (ll.lat < (100 + map.getResolution()))), \"lat is the same in and ot\");\n        map.destroy();\n    }    \n\n    function test_moveByPx(t) {\n        t.plan(14);\n\n        var moved;\n        var Layer = OpenLayers.Class(OpenLayers.Layer, {\n            moveByPx: function(dx, dy) {\n                moved[this.name] = true;\n            }\n        });\n\n        var map = new OpenLayers.Map({\n            div: 'map',\n            maxExtent: new OpenLayers.Bounds(-50, -50, 50, 50),\n            restrictedExtent: new OpenLayers.Bounds(-10, -10, 10, 10),\n            layers: [\n                new Layer('base',\n                    {isBaseLayer: true}),\n                new Layer('outofrange',\n                    {isBaseLayer: false, minResolution:2})\n            ]\n        });\n        var log = [];\n        map.applyTransform = function(x, y, scale) {\n            log.push([x || map.layerContainerOriginPx.x, y || map.layerContainerOriginPx.y, scale]);\n            OpenLayers.Map.prototype.applyTransform.apply(this, arguments);\n        };\n\n        moved = {};\n        map.zoomToExtent(new OpenLayers.Bounds(-1, -1, 1, 1));\n\n        // check initial state\n        t.eq(log[0][0], 0,\n             '[initial state] layer container left correct');\n        t.eq(log[0][1], 0,\n             '[initial state] layer container top correct');\n        t.eq(moved['base'], undefined,\n             '[initial state] base layer not moved');\n        t.eq(moved['outofrange'], undefined,\n             '[initial state] out-of-range layer not moved');\n\n        // move to a valid position\n        moved = {};\n        map.moveByPx(-455, 455);\n        t.eq(log[1][0], 455,\n             '[valid position] layer container left correct');\n        t.eq(log[1][1], -455,\n             '[valid position] layer container top correct');\n        t.eq(moved['base'], true,\n             '[valid position] base layer moved');\n        t.eq(moved['outofrange'], undefined,\n             '[valid position] out-of-range layer not moved');\n\n        // move outside the max extent\n        moved = {};\n        map.moveByPx(-4500, 4500);\n        t.eq(log.length, 2,\n             '[outside max extent] layer container offset unchanged');\n        t.eq(moved['base'], undefined,\n             '[outside max extent] base layer not moved');\n        t.eq(moved['outofrange'], undefined,\n             '[outside max extent] out-of-range layer not moved');\n\n        // move outside the restricted extent\n        moved = {};\n        map.moveByPx(-500, 500);\n        t.eq(log.length, 2,\n             '[outside restricted extent] layer container offset unchanged');\n        t.eq(moved['base'], undefined,\n             '[outside restricted extent] base layer not moved');\n        t.eq(moved['outofrange'], undefined,\n             '[outside restricted extent] out-of-range layer not moved');\n\n\n        map.destroy();\n    }\n\n    // test for http://trac.osgeo.org/openlayers/ticket/3388\n    function test_moveByPx_restrictedExtent(t) {\n        t.plan(2);\n\n        var map = new OpenLayers.Map({\n            div: 'map',\n            restrictedExtent: new OpenLayers.Bounds(-22.5,-11.25,22.5,11.25),\n            layers: [\n                new OpenLayers.Layer('name', {isBaseLayer: true})\n            ]\n        });\n\n        map.zoomToExtent(new OpenLayers.Bounds(-11.25, 0, 11.25, 11.25));\n\n        var log = [];\n        map.applyTransform = function(x, y, scale) {\n            log.push([x || map.layerContainerOriginPx.x, y || map.layerContainerOriginPx.y, scale]);\n            OpenLayers.Map.prototype.applyTransform.apply(this, arguments);\n        };\n\n        map.moveByPx(-10, -10);\n        t.eq(log[0][0], 10, 'layer container left correct');\n        t.eq(log[0][1], 0, 'layer container top correct');\n    }\n    \n    function test_applyTransform(t) {\n        t.plan(10);\n        var origStylePrefix = OpenLayers.Util.vendorPrefix.style;\n        OpenLayers.Util.vendorPrefix.style =\n                OpenLayers.Util.vendorPrefix.css =\n                function(key) { return 'transform'; };\n        \n        var map = new OpenLayers.Map('map');\n        map.layerContainerDiv = {style: {}};\n        delete map.applyTransform.transform;\n        delete map.applyTransform.template;\n        var origGetStyle = OpenLayers.Element.getStyle;\n        OpenLayers.Element.getStyle = function() { return 'foo'; }\n        map.applyTransform(1, 2, 3);\n        OpenLayers.Element.getStyle = origGetStyle;\n        t.eq(map.layerContainerDiv.style.transform, 'translate3d(1px,2px,0) scale3d(3,3,1)', '3d transform and scale used when available');\n        \n        delete map.applyTransform.transform;\n        delete map.applyTransform.template;\n        var origIndexOf = String.prototype.indexOf;\n        String.prototype.indexOf = function() { return -1; };\n        map.layerContainerOriginPx = {x: -3, y: 2};\n        map.applyTransform(1, 2, 3);\n        String.prototype.indexOf = origIndexOf;\n        t.eq(map.layerContainerDiv.style.transform, 'translate(4px,0px) scale(3,3)', '2d translate and scale correct');\n        t.eq(map.layerContainerDiv.style.left, '-3px', 'container origin x set as style.left');\n        t.eq(map.layerContainerDiv.style.top, '2px', 'container origin y set as style.top');\n        map.applyTransform(1, 2);\n        t.ok(!map.layerContainerDiv.style.transform, 'no transform set when no transform needed');\n        t.eq(map.layerContainerDiv.style.left, '1px', 'style.left correct when no transform needed');\n        t.eq(map.layerContainerDiv.style.top, '2px', 'style.top correct when no transform needed');\n        \n        map.applyTransform.transform = null;\n        map.applyTransform(4, 5, 6);\n        t.eq(map.layerContainerDiv.style.left, '4px', 'style.left set when transform not available')\n        t.eq(map.layerContainerDiv.style.top, '5px', 'style.top set when transform not available')\n        t.ok(!map.layerContainerDiv.style.transform, 'no transform set, because not supported');\n\n        map.destroy();\n        delete map.applyTransform.transform;\n        delete map.applyTransform.template;\n        OpenLayers.Util.vendorPrefix.style = origStylePrefix;\n    }\n\n    function test_options(t) {\n        t.plan(2);\n\n        var map = new OpenLayers.Map('map');\n        t.eq(map.options, {}, 'map.options is empty with no options');\n        map.destroy();\n\n        var options = {\n            resolutions: [1,2,3,5],\n            projection: \"EPSG:4326\",\n            units: 'm'\n        };\n        var map = new OpenLayers.Map('map', options);\n        t.eq(map.options, options, 'map.options is a copy of the constructor option');\n        map.destroy();\n    }\n\n    function test_adjustZoom(t) {\n        t.plan(5);\n        var map = new OpenLayers.Map({\n            div: 'map',\n            layers: [\n                new OpenLayers.Layer('name', {\n                    isBaseLayer: true,\n                    wrapDateLine: true\n                })\n            ]\n        });\n        map.zoomToMaxExtent();\n        t.ok(map.getResolution() <= map.getMaxExtent().getWidth() / map.getSize().w, \"wrapDateLine map not wider than world\");\n        \n        t.eq(map.adjustZoom(9), 9, \"valid zoom maintained\");\n        t.eq(map.adjustZoom(1), 2, \"zoom adjusted to not exceed world width\");\n        \n        map.fractionalZoom = true;\n        t.eq(map.adjustZoom(1).toPrecision(3), \"1.29\", \"zoom adjusted to match world width\");\n\n        map.moveTo([16, 48], 0);\n        t.eq(map.getCenter().toShortString(), \"0, 0\", \"no panning when moveTo is called with invalid zoom\");\n    }\n\n    function test_correctCenterAtZoomLevel0(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map({\n            div: 'map',\n            maxExtent: new OpenLayers.Bounds(-30, 48.00, 3.50, 64.00),\n            restrictedExtent: new OpenLayers.Bounds(-30, 48.00, 3.50, 64.00),\n            projection: \"EPSG:4258\",\n            units: \"degrees\",\n            layers: [\n                new OpenLayers.Layer('name', {\n                    isBaseLayer: true\n                })\n            ]\n        });\n        map.setCenter(new OpenLayers.LonLat(-1.3, 50.8), 4);\n        map.moveTo(null, 0);\n        var center  = map.getCenter();\n        t.ok(center.equals(new OpenLayers.LonLat(-13.25, 56)), \"Center is correct and not equal to maxExtent's center\");\n    }\n    \n    function test_getZoomTargetCenter(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map({\n            div: 'map',\n            layers: [\n                new OpenLayers.Layer('', {isBaseLayer: true})\n            ],\n            center: [0, 0],\n            zoom: 1\n        });\n        \n        var ll = map.getZoomTargetCenter({x: 44, y: 22}, map.getMaxResolution());\n\n        t.eq(ll.toShortString(), \"180, -90\", \"getZoomTargetCenter works.\");\n        \n        map.destroy();\n    }\n\n    function test_autoUpdateSize(t) {\n        t.plan(1);\n        OpenLayers.Event.unloadCache();\n        var resizeListener = false;\n        var map = new OpenLayers.Map({\n            autoUpdateSize: false,\n            div: 'map',\n            layers: [\n                new OpenLayers.Layer('name', {\n                    isBaseLayer: true,\n                    wrapDateLine: true\n                })\n            ]\n        });\n        map.setCenter(new OpenLayers.LonLat(-1.3, 50.8), 4);\n        for (var key in OpenLayers.Event.observers) {\n            var obj = OpenLayers.Event.observers[key];\n            for (var i=0, ii=obj.length; i<ii; ++i) {\n                var listener = obj[i];\n                if (listener.name === 'resize' && listener.element === window) {\n                    resizeListener = true;\n                }\n            }\n        }\n        t.eq(resizeListener, map.autoUpdateSize, \"resize listener not registered when autoUpdateSize is false\");\n        map.destroy();\n    }\n\n    function test_tileManager(t) {\n        t.plan(3);\n        var map = new OpenLayers.Map('map');\n        t.ok(map.tileManager instanceof OpenLayers.TileManager, \"Default tileManager created\");\n        map.destroy();\n        map = new OpenLayers.Map('map', {tileManager: null});\n        t.ok(map.tileManager === null, \"No tileManager created\");\n        map.destroy();\n        var options = {cacheSize: 512};\n        map = new OpenLayers.Map('map', {tileManager: options});\n        t.eq(map.tileManager.cacheSize, 512, \"cacheSize taken from options\");\n        map.destroy();\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 600px; height: 300px;\"/>\n    <div style=\"display: none;\"><div id=\"invisimap\"></div></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Marker/Box.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var box; \n    \n    function test_Box_constructor (t) {\n        t.plan( 7 );\n\n        OpenLayers.Marker.Box.prototype._setBorder = \n            OpenLayers.Marker.Box.prototype.setBorder;\n        OpenLayers.Marker.Box.prototype.setBorder = function (x,y) {\n            g_Color = x;\n            g_Width = y;\n        };\n\n        var bounds = new OpenLayers.Bounds(1,2,3,4);\n        var borderColor = \"blue\";\n        var borderWidth = 55;\n\n\n        g_Color = g_Width = null;\n        box = new OpenLayers.Marker.Box(bounds, borderColor, borderWidth);\n\n        t.ok( box instanceof OpenLayers.Marker.Box, \"new OpenLayers.Marker.Box returns Box object\" );\n        t.ok( box.bounds.equals(bounds), \"bounds object correctly set\");\n        t.ok( box.div != null, \"div created\");\n        //Safari 3 separates style overflow into overflow-x and overflow-y\n        var prop = (OpenLayers.BROWSER_NAME == 'safari') ? 'overflowX' : 'overflow';\n        t.eq( box.div.style[prop], \"hidden\", \"div style overflow hidden\");\n        t.ok( box.events != null, \"events object created\");\n        t.eq( g_Color, borderColor, \"setBorder called with correct border color\");        \n        t.eq( g_Width, borderWidth, \"setBorder called with correct border width\");        \n        \n\n        OpenLayers.Marker.Box.prototype.setBorder = \n            OpenLayers.Marker.Box.prototype._setBorder;\n    }\n\n\n    function test_Box_setBorder(t) {\n        t.plan( 2 );\n\n        var box = {\n            div: {\n                style: {}\n            }\n        };\n\n      //defaults\n        var args = [];\n        OpenLayers.Marker.Box.prototype.setBorder.apply(box, args);\n        t.eq(box.div.style.border, \"2px solid red\", \"style correctly set with no good values (defaults work)\");\n\n      //good vals\n        var borderColor = \"blue\";\n        var borderWidth = 55;\n\n        args = [borderColor, borderWidth];\n        OpenLayers.Marker.Box.prototype.setBorder.apply(box, args);\n        t.eq(box.div.style.border, borderWidth + \"px solid \" + borderColor, \"style correctly set with both good values\");\n\n    }\n    function test_Box_draw(t) {\n        t.plan( 5 );\n\n        OpenLayers.Util._modifyDOMElement = \n            OpenLayers.Util.modifyDOMElement;\n        OpenLayers.Util.modifyDOMElement = \n            function (element, id, px, sz) {\n                g_Element = element;\n                g_Id = id;\n                g_Px = px;\n                g_Sz = sz;\n            };\n\n        var box = {\n            div: {}\n        };\n\n        \n        var px = {};\n        var sz = {};\n        var args = [px, sz];\n\n        g_Element = g_Id = g_Px = g_Sz = null;\n        var retVal = OpenLayers.Marker.Box.prototype.draw.apply(box, args);\n\n        t.eq(g_Element, box.div, \"modifyDOMElement passes box's div for element\");\n        t.eq(g_Id, null, \"modifyDOMElement passes null for id\");\n        t.eq(g_Px, px, \"modifyDOMElement passes new px value for px\");\n        t.eq(g_Sz, sz, \"modifyDOMElement passes new sz value for sz\");\n        t.ok(retVal == box.div, \"draw returns box's div\");\n\n        OpenLayers.Util.modifyDOMElement = \n            OpenLayers.Util._modifyDOMElement;\n\n    }\n\n    function test_Box_onScreen(t) {\n        t.plan( 2 );\n\n        var map = new OpenLayers.Map(\"map\");\n\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.WMS(\"WMS Layer\", url);\n\n        map.addLayer(layer);\n        \n        mlayer = new OpenLayers.Layer.Boxes('Test Layer');\n        map.addLayer(mlayer);\n               \n        map.zoomToExtent(new OpenLayers.Bounds(-50,-50,50,50));\n\n        //onscreen box\n        var bounds = new OpenLayers.Bounds(-1,-1,1,1);\n        var box = new OpenLayers.Marker.Box(bounds);\n        mlayer.addMarker(box);\n        \n        t.ok( box.onScreen(), \"box knows it's onscreen\" );\n\n        //offscreen box\n        var bounds = new OpenLayers.Bounds(100,100,150,150);\n        var box2 = new OpenLayers.Marker.Box(bounds);\n        mlayer.addMarker(box2);\n\n        t.ok( !box2.onScreen(), \"box knows it's offscreen\" );\n        map.destroy();\n    }\n\n    function test_Box_display(t) {\n        t.plan( 2 );\n\n        var box = {\n            div: {\n                style: {}\n            }\n        };\n\n      //display(true)\n        var args = [true];\n        OpenLayers.Marker.Box.prototype.display.apply(box, args);\n        t.eq(box.div.style.display, \"\", \"style.display correctly set to '' when display(true)\");\n\n      //display(false)\n        var args = [false];\n        OpenLayers.Marker.Box.prototype.display.apply(box, args);\n        t.eq(box.div.style.display, \"none\", \"style.display correctly set to 'none' when display(false)\");\n    }\n\n    function test_Box_destroy(t) {\n        t.plan(3);\n        \n        OpenLayers.Marker.prototype._destroy = \n            OpenLayers.Marker.prototype.destroy;\n        OpenLayers.Marker.prototype.destroy = function() {\n            g_Destroy = true;\n        }\n                \n        var bounds = new OpenLayers.Bounds(1,2,3,4);\n        var borderColor = \"blue\";\n        var borderWidth = 55;\n\n        g_Destroy = null;\n        box = new OpenLayers.Marker.Box(bounds, borderColor, borderWidth);\n        box.destroy();\n\n        t.eq(box.bounds, null, \"bounds nullified\");\n        t.eq(box.div, null, \"div nullified\");\n        t.ok(g_Destroy == true, \"OpenLayers.Marker.destroy() called\");\n\n\n        OpenLayers.Marker.prototype.destroy = \n            OpenLayers.Marker.prototype._destroy;\n    }\n    \n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Marker.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    var marker;\n\n    function test_Marker_constructor (t) {\n        t.plan( 4 );\n        var ll = new OpenLayers.LonLat(2,1);\n        marker = new OpenLayers.Marker(ll,new OpenLayers.Icon());\n        t.ok( marker instanceof OpenLayers.Marker, \"new OpenLayers.Marker returns Marker object\" );\n        t.ok( marker.icon instanceof OpenLayers.Icon, \"new marker.Icon returns Icon object\" );\n        t.ok( marker.lonlat instanceof OpenLayers.LonLat, \"new marker.lonlat returns LonLat object\" );\n        t.ok( marker.lonlat.equals(ll), \"marker.lonlat returns correct\" );\n    }\n\n    function test_Marker_onScreen(t) {\n        t.plan( 2 );\n\n        var map = new OpenLayers.Map(\"map\");\n\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.WMS(name, url);\n\n        map.addLayer(layer);\n        \n        mlayer = new OpenLayers.Layer.Markers('Test Layer');\n        map.addLayer(mlayer);\n               \n        map.zoomToExtent(new OpenLayers.Bounds(-50,-50,50,50));\n\n        //onscreen marker\n        var ll = new OpenLayers.LonLat(0,0);\n        var marker = new OpenLayers.Marker(ll);\n        mlayer.addMarker(marker);\n        \n        t.ok( marker.onScreen(), \"marker knows it's onscreen\" );\n\n        //offscreen marker\n        var ll = new OpenLayers.LonLat(100,100);\n        var marker2 = new OpenLayers.Marker(ll);\n        mlayer.addMarker(marker2);\n\n        t.ok( !marker2.onScreen(), \"marker knows it's offscreen\" );\n        map.destroy();\n    }\n\n    function test_Marker_setOpacity(t) {\n        t.plan( 2 );\n        \n        var map = new OpenLayers.Map(\"map\");\n\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.WMS(name, url);\n\n        map.addLayer(layer);\n        \n        mlayer = new OpenLayers.Layer.Markers('Test Layer');\n        map.addLayer(mlayer);\n               \n        map.zoomToExtent(new OpenLayers.Bounds(-50,-50,50,50));\n\n        //onscreen marker\n        var ll = new OpenLayers.LonLat(0,0);\n        var marker = new OpenLayers.Marker(ll);\n        mlayer.addMarker(marker);\n\n        t.ok(!marker.icon.imageDiv.style.opacity, \"default marker has no opacity\");\n        \n        marker.setOpacity(0.5);\n\n        t.eq(parseFloat(marker.icon.imageDiv.style.opacity), 0.5, \"marker.setOpacity() works\");\n        map.destroy();\n    }\n    \n    function test_Marker_setUrl(t) {\n        t.plan( 2 );\n        \n        var map = new OpenLayers.Map(\"map\");\n\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.WMS(name, url);\n\n        map.addLayer(layer);\n        \n        mlayer = new OpenLayers.Layer.Markers('Test Layer');\n        map.addLayer(mlayer);\n               \n        map.zoomToExtent(new OpenLayers.Bounds(-50,-50,50,50));\n\n        //onscreen marker\n        var ll = new OpenLayers.LonLat(0,0);\n        var marker = new OpenLayers.Marker(ll);\n        mlayer.addMarker(marker);\n\n        t.ok(OpenLayers.String.contains(marker.icon.imageDiv.firstChild.src, \"img/marker.png\"), \"Marker.png is default URL\");\n\n        marker.setUrl(\"http://example.com/broken.png\");\n        t.eq(marker.icon.imageDiv.firstChild.src, \"http://example.com/broken.png\", \"image source changes correctly.\");\n\n        map.destroy();\n    }\n\n    function test_Marker_moveTo(t) {\n        t.plan( 6 );\n        \n        var map = new OpenLayers.Map(\"map\");\n\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.WMS(name, url);\n\n        map.addLayer(layer);\n        \n        mlayer = new OpenLayers.Layer.Markers('Test Layer');\n        map.addLayer(mlayer);\n               \n        map.zoomToExtent(new OpenLayers.Bounds(-50,-50,50,50));\n\n        //onscreen marker\n        var ll = new OpenLayers.LonLat(0,0);\n        var marker = new OpenLayers.Marker(ll);\n        mlayer.addMarker(marker);\n        \n        t.eq(marker.lonlat.lon, 0, \"marker lon okay\"); \n        t.eq(marker.lonlat.lat, 0, \"marker lat okay\");\n\n        marker.moveTo(new OpenLayers.Pixel(250,275));\n        t.eq(marker.lonlat.lon, 0, \"marker lon no change\"); \n        t.eq(marker.lonlat.lat, 0, \"marker lat no change\"); \n        \n        marker.moveTo(new OpenLayers.Pixel(0,0));\n        t.eq(marker.lonlat.lon, map.getExtent().left, \"on left edge of map\"); \n        t.eq(marker.lonlat.lat, map.getExtent().top, \"on top edge of map\"); \n        map.destroy();\n    }\n    \n    function test_Marker_isDrawn(t) {\n        t.plan(3);\n\n        var marker = {};\n\n        //no icon\n        var drawn = OpenLayers.Marker.prototype.isDrawn.apply(marker, []);\n        t.ok(!drawn, \"marker with no icon not drawn\");\n\n        //not drawn icon\n        marker.icon = { isDrawn: function() { return false; } };\n        drawn = OpenLayers.Marker.prototype.isDrawn.apply(marker, []);\n        t.ok(!drawn, \"marker with not drawn icon not drawn\");\n\n        //drawn icon\n        marker.icon.isDrawn = function() { return true; };\n        drawn = OpenLayers.Marker.prototype.isDrawn.apply(marker, []);\n        t.ok(drawn, \"marker with drawn icon drawn\");\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/OLLoader.js",
    "content": "(function() {\n    var r = new RegExp(\"(^|(.*?\\\\/))(\" + \"OLLoader.js\" + \")(\\\\?|$)\"),\n        s = document.getElementsByTagName('script'),\n        src, m, l = \"\";\n    for(var i=0, len=s.length; i<len; i++) {\n        src = s[i].getAttribute('src');\n        if(src) {\n            var m = src.match(r);\n            if(m) {\n                l = m[1];\n                break;\n            }\n        }\n    }\n\n    var regex = new RegExp( \"[\\\\?&]mode=([^&#]*)\" );\n    var href = window.parent.location.href;\n    var results = regex.exec( href );\n    l += (results && results[1] == 'build') ? \n        \"../build/OpenLayers.js\" : \"../lib/OpenLayers.js\"; \n    scriptTag = \"<script src='\" + l + \"'></script>\"; \n    document.write(scriptTag);\n})();\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/OpenLayers1.html",
    "content": "<html>\n<head>\n    <script src=\"../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        function test_OpenLayers(t) {\n            t.plan(3);\n\n            t.eq(OpenLayers._getScriptLocation(), \"../\", \"Script location correctly detected.\");\n            \n            t.ok(OpenLayers.ImgPath !== undefined, \"An ImgPath property exists.\");\n            \n            t.eq(OpenLayers.ImgPath, '', \"The default for OpenLayers.ImgPath is the empty string.\");\n        }\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/OpenLayers2.html",
    "content": "<html>\n<head>\n    <script src=\"bogus/1/OpenLayers.js-foo\"></script>\n    <script src=\"bogus/2/foo-OpenLayers.js\"></script>\n    <script src=\"../lib/OpenLayers.js?foo\"></script>\n    <script src=\"bogus/3/after-OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        function test_OpenLayers(t) {\n            t.plan(1);\n\n            var script = document.getElementById(\"script\");\n\n            t.eq(OpenLayers._getScriptLocation(), \"../\", \"Script location with search string correctly detected, and not fooled by other scripts.\");\n        }\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/OpenLayers3.html",
    "content": "<html>\n<head>\n    <script>\n    var OpenLayers = {singleFile: true};\n    </script>\n    <script src=\"../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        function test_OpenLayers(t) {\n            t.plan(1);\n\n            var script = document.getElementById(\"script\");\n\n            t.eq(OpenLayers._getScriptLocation(), \"../lib/\", \"Script location for single file build correctly detected.\");\n        }\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/OpenLayers4.html",
    "content": "<html>\n<head>\n    <script type=\"text/javascript\">\n        OpenLayers = {singleFile: true}; // just to make the test run faster\n        document.write('<scr'+'ipt src=\"../lib/OpenLayers.js\"></scr'+'ipt>');\n        document.write('<scr'+'ipt src=\"bogus/foo-/OpenLayers.js\"></scr'+'ipt>');\n    </script>\n    <script type=\"text/javascript\">\n        function test_OpenLayers(t) {\n            t.plan(1);\n            t.eq(OpenLayers._getScriptLocation(), \"../lib/\",\n                 \"Script location correctly detected, and not fooled by other scripts.\");\n        }\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/OpenLayersJsFiles.html",
    "content": "<html>\n<head>\n    <script type=\"text/javascript\">\n        window.OpenLayers = new Array(\n            \"OpenLayers/Util.js\",\n            \"OpenLayers/BaseTypes.js\"\n        );\n    </script>\n    <script src=\"../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        function test_OpenLayers(t) {\n            t.plan(1);\n            var s = document.getElementsByTagName(\"script\");\n            var src, count = 0;\n            for(var i=0, len=s.length; i<len; i++) {\n                src = s[i].getAttribute('src');\n                if(src) {\n                    count++;\n                }\n            }\n            t.eq(count, 3, \"Three OpenLayers scripts loaded.\");\n        }\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Popup/Anchored.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    var popup;\n\n    function test_Popup_Anchored_default_constructor(t) {\n        t.plan( 4 );\n\n        popup = new OpenLayers.Popup.Anchored();\n\n        t.ok( popup instanceof OpenLayers.Popup.Anchored, \"new OpenLayers.Popup.Anchored returns Popup.Anchored object\" );\n        t.ok(OpenLayers.String.startsWith(popup.id, \"OpenLayers_Popup_Anchored\"), \"valid default popupid\");\n        var firstID = popup.id;\n        t.eq(popup.contentHTML, null, \"good default popup.contentHTML\");\n\n        \n        popup = new OpenLayers.Popup.Anchored();\n        var newID = popup.id;\n        t.ok(newID != firstID, \"default id generator creating unique ids\");\n    }\n    function test_Popup_Anchored_updateRelPos(t) { \n        t.plan(1);\n        var popup = new OpenLayers.Popup.Anchored();\n        popup.calculateNewPx = function () {}\n        popup.calculateRelativePosition = function() {\n            t.ok(true, \"update relative position is called on moveTo\");\n        }\n        popup.moveTo(new OpenLayers.Pixel(0,0));\n   } \n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Popup/FramedCloud.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n   function test_Popup_FramedCloud_setHTML(t) { \n        t.plan(1);\n        popup = new OpenLayers.Popup.FramedCloud();\n        popup.setContentHTML(\"<p></p>\");\n        t.ok(\"setHTML on popup not yet added to map doesn't fail\");\n   }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:512px; height:256px\"> </div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Popup.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    var popup;\n\n    function test_Popup_default_constructor(t) {\n        t.plan( 8 );\n\n        var size = new OpenLayers.Size(OpenLayers.Popup.WIDTH,\n                                       OpenLayers.Popup.HEIGHT);\n        popup = new OpenLayers.Popup();\n\n        t.ok( popup instanceof OpenLayers.Popup, \"new OpenLayers.Popup returns Popup object\" );\n        t.ok(OpenLayers.String.startsWith(popup.id, \"OpenLayers_Popup\"),\n             \"valid default popupid\");\n        var firstID = popup.id;\n        t.ok(popup.contentSize.equals(size), \"good default popup.size\");\n        t.eq(popup.contentHTML, null, \"good default popup.contentHTML\");\n        t.eq(popup.backgroundColor, OpenLayers.Popup.COLOR, \"good default popup.backgroundColor\");\n        t.eq(popup.opacity, OpenLayers.Popup.OPACITY, \"good default popup.opacity\");\n        t.eq(popup.border, OpenLayers.Popup.BORDER, \"good default popup.border\");\n\n        \n        popup = new OpenLayers.Popup();\n        var newID = popup.id;\n        t.ok(newID != firstID, \"default id generator creating unique ids\");\n    }\n    \n    function test_Popup_constructor (t) {\n        t.plan(9);\n\n        var id = \"chicken\";\n        var w = 500;\n        var h = 400;\n        var sz = new OpenLayers.Size(w,h);\n        var lon = 5;\n        var lat = 40;\n        var ll = new OpenLayers.LonLat(lon, lat);\n        var content = \"foo\";\n        var closePopupCallback = function(e) {\n            //this should get triggered by the \"observer.observer();\" call below\n            t.ok(true, \"closePopupCallback called\")\n        };\n\n        popup = new OpenLayers.Popup(id,\n                                     ll,\n                                     sz,\n                                     content,\n                                     true,\n                                     closePopupCallback);\n\n        t.ok( popup instanceof OpenLayers.Popup, \"new OpenLayers.Popup returns Popup object\" );\n        t.eq(popup.id, id, \"popup.id set correctly\");\n        t.ok(popup.lonlat.equals(ll), \"popup.lonlat set correctly\");\n        t.ok(popup.contentSize.equals(sz), \"popup.size set correctly\");\n        t.eq(popup.contentHTML, content, \"contentHTML porpoerty of set correctly\");\n\n        // test that a browser event is registered on click on popup closebox\n        var closeImgDiv = popup.groupDiv.childNodes[1];\n        var cacheID = closeImgDiv._eventCacheID;\n        for (var i = 0; i < OpenLayers.Event.observers[cacheID].length; i++) {\n            var observer = OpenLayers.Event.observers[cacheID][i];\n            if (observer.element == closeImgDiv) {\n                if (observer.name == \"click\") {\n                    t.ok(true, \"A click event was registered for the close box element\");\n                    //call the registered observer to make sure it's the right one\n                    observer.observer();\n                } else if (observer.name == \"touchend\") {\n                    t.ok(true, \"A touchend event was registered for the close box element\");\n                    //call the registered observer to make sure it's the right one\n                    observer.observer();\n                } else {\n                    t.fail(\"A \" + observer.name + \" event was registered for the close box element\");\n                }\n            }\n        }\n    }\n\n    function test_Popup_updatePosition(t) {\n        t.plan(1)\n        var map = new OpenLayers.Map('map');\n        map.addLayer(new OpenLayers.Layer('name', {'isBaseLayer':true}));\n        map.zoomToMaxExtent();\n        var popup = new OpenLayers.Popup('id');\n        map.addPopup(popup);\n        map.getLayerPxFromLonLat = function () { return null; }\n        popup.moveTo=function() { t.fail(\"Shouldnt' call moveTo if layerpx is null\"); }\n        popup.lonlat = true;\n        popup.updatePosition();\n        t.ok(true, \"update position doesn't fail when getLayerPxFromLonLat fails.\");\n        map.destroy();\n    }\n    function test_Popup_keepInMap(t) {\n        \n        var bn = OpenLayers.BROWSER_NAME;\n        OpenLayers.BROWSER_NAME = \"mock\";\n        t.plan(3);\n        var map = new OpenLayers.Map(\"map\");\n        map.addLayer(new OpenLayers.Layer(\"\", {isBaseLayer: true}));\n        map.zoomToMaxExtent();\n        var longString = \"<div style='width: 200px; height: 200px'>Abc def</div>\"; \n        popup = new OpenLayers.Popup(\"chicken\", \n                                 new OpenLayers.LonLat(90, 60),\n                                 new OpenLayers.Size(100,100),\n                                 longString,\n                                 null, true);\n        popup.panMapIfOutOfView = false;\n        popup.keepInMap = true;\n        map.addPopup(popup);\n        var safeSize = popup.getSafeContentSize(new OpenLayers.Size(1000,1000));\n        popup = new OpenLayers.Popup(\"chicken\", \n                                 new OpenLayers.LonLat(90, 60),\n                                 new OpenLayers.Size(100,100),\n                                 longString,\n                                 null, true);\n        popup.panMapIfOutOfView = true;\n        popup.keepInMap = true;\n        map.addPopup(popup);\n        var safeSizePanKeep = popup.getSafeContentSize(new OpenLayers.Size(1000,1000));\n        popup.keepInMap = false;\n        map.addPopup(popup);\n        map.setCenter(-180, -90);\n        var safeSizePan = popup.getSafeContentSize(new OpenLayers.Size(1000,1000));\n        t.ok(safeSizePan.equals(safeSizePanKeep), \"Panning means that all sizes are equal\");\n        t.ok(safeSize.w < safeSizePan.w, \"Width of non-panning is less\");    \n        t.ok(safeSize.h < safeSizePan.h, \"Height of non-panning is less\");    \n        OpenLayers.BROWSER_NAME = bn;\n    }    \n    function test_Popup_draw(t) {\n        t.plan( 15 );\n        \n        var id = \"chicken\";\n        var x = 50;\n        var y = 100;\n        var w = 500;\n        var h = 400;\n        var content = \"charlie\";\n        var color = \"red\";\n        var hexColor = \"#ff0000\";\n        var opacity = 0.5;\n        var border = \"1px solid\";\n        map1 = new OpenLayers.Map(\"map\");\n        popup = new OpenLayers.Popup(id);\n        popup.setSize(new OpenLayers.Size(w, h));\n        popup.setContentHTML(content);\n        popup.setBackgroundColor(color);\n        popup.setOpacity(opacity);\n        popup.setBorder(border);\n        map1.addPopup(popup);\n        popup.moveTo(new OpenLayers.Pixel(x, y));\n                                     \n        t.eq(popup.div.id, id, \"popup.div.id set correctly\");\n        t.eq(popup.div.style.left, x + \"px\", \"left position of popup.div set correctly\");\n        t.eq(popup.div.style.top, y + \"px\", \"top position of popup.div set correctly\");\n\n        var contentDiv = popup.div.childNodes[0].childNodes[0];\n        \n        t.eq(contentDiv.className, \"olPopupContent\", \"correct content div className\");\n        t.eq(contentDiv.id, \"chicken_contentDiv\", \"correct content div id\");\n        t.eq(contentDiv.style.position, \"relative\", \"correct content div position\");\n        //Safari 3 separates style overflow into overflow-x and overflow-y\n        var prop = (OpenLayers.BROWSER_NAME == 'safari') ? 'overflowX' : 'overflow';\n        t.eq(contentDiv.style[prop], \"\", \"correct content div overflow\");\n        t.eq(contentDiv.innerHTML, content, \"correct content div content\");\n\n        var bColor = popup.div.style.backgroundColor;\n        var goodColor = ( (bColor == color) || (bColor == hexColor));\n        t.ok(goodColor, \"good default popup.backgroundColor\");\n        if (navigator.appName.indexOf(\"Microsoft\") == -1 || new RegExp(/msie 10/).test(navigator.userAgent.toLowerCase())) {\n            t.eq(parseFloat(popup.div.style.opacity), opacity, \"good default popup.opacity\");\n        } else {\n            t.eq(popup.div.style.filter, \"alpha(opacity=\" + opacity*100 + \")\", \"good default popup.opacity\");\n        }\n        //Safari 3 separates the border style into separate entities when reading it\n        if (OpenLayers.BROWSER_NAME == 'safari') {\n          var s = border.split(' ');\n          t.ok(popup.div.style.borderTopWidth == s[0] && popup.div.style.borderTopStyle == s[1], \"good default popup.border\")\n        } else {\n          t.ok(popup.div.style.border.indexOf(border) != -1, \"good default popup.border\");\n        }\n\n        x += 50;\n        popup.moveTo(new OpenLayers.Pixel(x, y));\n        t.eq(popup.div.style.left, x + \"px\", \"moveTo updates left position of popup.div correctly\");\n        t.eq(popup.div.style.top, y + \"px\", \"moveTo updates top position of popup.div correctly\");\n\n\n    //closeOnMove\n        var checkMapEvent = function(map, popup) {\n            var startListeners = map.events.listeners['movestart'];\n            if (startListeners) {\n                for (var i = 0; i < startListeners.length; i++) {\n                    var listener = startListeners[i];\n                    if ((listener.obj == popup) && (listener.func == popup.hide)) {\n                        return true;\n                    }\n                }\n            }\n            return false;\n        };\n        var registered = checkMapEvent(map1, popup);\n        t.ok(!registered, \"when not 'closeOnMove', correctly not registered hide() on map's movestart.\")    \n        \n        var popup2 = new OpenLayers.Popup('test');\n        popup2.closeOnMove = true;\n        map1.addPopup(popup2);\n        \n        registered = checkMapEvent(map1, popup2);\n        t.ok(registered, \"when 'closeOnMove', correctly registered hide() on map's movestart.\")    \n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:512px; height:256px\"> </div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Projection.html",
    "content": "<html> \n  <head> \n    <script src=\"OLLoader.js\"></script> \n    <script type=\"text/javascript\"> \n     function test_Projection_constructor(t) { \n         t.plan(9); \n      \n         var options = {'foo': 'bar'}; \n         var projection = new OpenLayers.Projection(\"code\", options); \n         t.ok(projection instanceof OpenLayers.Projection, \n              \"new OpenLayers.Projection returns object\" ); \n         t.eq(projection.projCode, \"code\", \"The proj code is maintained\");  \n         t.eq(projection.getCode(), \"code\", \"The proj code is maintained.\");  \n         t.eq(projection.getUnits(), null, \"Null units with no proj4js library.\");  \n         t.eq(projection.foo, \"bar\", \"constructor sets options correctly\"); \n  \n         var projection2 = new OpenLayers.Projection(\"epsg:4325\", options); \n         out = OpenLayers.Projection.transform({'x':10,'y':12}, projection, projection2); \n         t.eq(out.x, 10, \"Null transform has no effect\"); \n         t.eq(out.y, 12, \"Null transform has no effect\"); \n\n         t.eq(projection.equals(null), false, \"equals on null projection returns false\");\n         t.eq(projection.equals({}), false, \"equals on null projection object returns false (doesn't call getCode)\");\n     }\n     \n     function test_Projection_equals(t) {\n         t.plan(8);\n         var origTransforms = OpenLayers.Util.extend({}, OpenLayers.Projection.transforms);\n         OpenLayers.Projection.addTransform(\"EPSG:4326\", \"FOO\", OpenLayers.Projection.nullTransform);\n         OpenLayers.Projection.addTransform(\"FOO\", \"EPSG:4326\", OpenLayers.Projection.nullTransform);\n         var projection = new OpenLayers.Projection(\"FOO\");\n         t.eq(projection.equals(new OpenLayers.Projection(\"EPSG:4326\")), true, \"EPSG:4326 and FOO are equal without proj4js\");\n         t.eq(projection.equals(new OpenLayers.Projection(\"EPSG:900913\")), false, \"EPSG:900913 and FOO are not equal without proj4js\");\n         t.eq(new OpenLayers.Projection(\"EPSG:4326\").equals(new OpenLayers.Projection(\"EPSG:4326\")), true, \"EPSG:4326 and EPSG:4326 are equal without proj4js\");\n         t.eq(new OpenLayers.Projection(\"BAR\").equals(new OpenLayers.Projection(\"EPSG:4326\")), false, \"Projection.equals() returns false for unknown projections withoug proj4js\");\n         OpenLayers.Projection.transforms = origTransforms;\n         \n         var proj1 = new OpenLayers.Projection(\"EPSG:4326\");\n         var proj2 = new OpenLayers.Projection(\"FOO\");\n         var proj3 = new OpenLayers.Projection(\"EPSG:900913\");\n         var proj4 = new OpenLayers.Projection(\"EPSG:4326\");\n         var proj5 = new OpenLayers.Projection(\"BAR\");\n\n         // conditionally mock up proj4js\n         var hasProj = !!window.Proj4js;\n         if (!hasProj) {\n             window.Proj4js = {};\n         }\n         proj1.proj = {defData: \"+title= WGS84 +foo=bar +x=0\"};\n         proj2.proj = {defData: \"+title=FOO +foo=bar +x=0\", srsCode: \"FOO\"};\n         proj3.proj = {defData: \"+title=Web Mercator +foo=bar +x=0 +I=am-different\"};\n         proj4.proj = proj1.proj;\n         proj5.proj = {srsCode: \"BAR\"};\n\n         t.eq(proj2.equals(proj1), true, \"EPSG:4326 and FOO are equal with proj4js\");\n         t.eq(proj2.equals(proj3), false, \"EPSG:900913 and FOO are not equal with proj4js\");\n         t.eq(proj1.equals(proj4), true, \"EPSG:4326 and EPSG:4326 are equal with proj4js\");\n         t.eq(proj2.equals(proj5), false, \"Projection.equals() returns false for unknown projections with proj4js\");\n         \n         if (!hasProj) {\n             window.Proj4js = undefined;\n         }\n\n    }\n    \n    function test_equals_string(t) {\n\n        t.plan(7);\n        var gg = new OpenLayers.Projection(\"EPSG:4326\");\n        var sm = new OpenLayers.Projection(\"EPSG:900913\");\n\n        // allow comparison with identifier\n        t.eq(gg.equals(\"EPSG:4326\"), true, \"EPSG:4326 equality with string\");\n        t.eq(gg.equals(\"EPSG:4327\"), false, \"EPSG:4326 inequality with string\");\n        t.eq(sm.equals(\"EPSG:900913\"), true, \"EPSG:900913 equality with string\");\n        t.eq(sm.equals(\"EPSG:900914\"), false, \"EPSG:900913 inequality with string\");\n        t.eq(sm.equals(\"EPSG:3857\"), true, \"EPSG:900913 equality with EPSG:3857\");\n        t.eq(sm.equals(\"EPSG:102113\"), true, \"EPSG:900913 equality with EPSG:102113\");\n        t.eq(sm.equals(\"EPSG:102100\"), true, \"EPSG:900913 equality with EPSG:102100\");\n\n     }\n       \n    </script> \n  </head> \n  <body> \n  </body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Protocol/CSW.html",
    "content": "<html>\n<head>\n  <script src=\"../../lib/OpenLayers.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(3);\n\n        var protocol = new OpenLayers.Protocol.CSW({formatOptions: {foo: \"bar\"}});\n        t.ok(protocol instanceof OpenLayers.Protocol.CSW.v2_0_2,\n             \"initialize returns instance of default versioned protocol\");\n        var format = protocol.format;\n        t.ok(format instanceof OpenLayers.Format.CSWGetRecords.v2_0_2, \"Default format created\");\n        t.ok(format.foo, \"bar\", \"formatOptions set correctly\");\n        protocol.destroy();\n    }\n\n    function test_read(t) {\n        t.plan(6);\n\n        var protocol = new OpenLayers.Protocol.CSW({\n            url: \"http://some.url.org\",\n            parseData: function(request) {\n                t.eq(request.responseText, \"foo\", \"parseData called properly\");\n                return \"foo\";\n            }\n        });\n\n        var _POST = OpenLayers.Request.POST;\n\n        var expected, status;\n        OpenLayers.Request.POST = function(obj) {\n            t.xml_eq(new OpenLayers.Format.XML().read(obj.data).documentElement, expected, \"GetRecords request is correct\");\n            obj.status = status;\n            obj.responseText = \"foo\";\n            obj.options = {};\n            t.delay_call(0.1, function() {obj.callback.call(this)});\n            return obj;\n        };\n\n        expected = readXML(\"GetRecords\");\n        status = 200;\n        var data = {\n            \"resultType\": \"results\",\n            \"maxRecords\": 100,\n            \"Query\": {\n                \"typeNames\": \"gmd:MD_Metadata\",\n                \"ElementSetName\": {\n                    \"value\": \"full\"\n                }\n            }\n        };\n        var response = protocol.read({\n            params: data,\n            callback: function(response) {\n                t.eq(response.data, \"foo\", \"user callback properly called with data\");\n                t.eq(response.code, OpenLayers.Protocol.Response.SUCCESS, \"success reported properly to user callback\");\n            }\n        });\n\n        var options = {\n            params: data,\n            callback: function(response) {\n                t.eq(response.code, OpenLayers.Protocol.Response.FAILURE, \"failure reported properly to user callback\");\n            }\n        };\n        status = 400;\n        var response = protocol.read(options);\n\n        OpenLayers.Request.POST = _POST;\n    }\n\n    function readXML(id) {\n        var xml = document.getElementById(id).firstChild.nodeValue;\n        return new OpenLayers.Format.XML().read(xml).documentElement;\n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:512px; height:256px\"> </div>\n<div id=\"GetRecords\"><!--\n<csw:GetRecords xmlns:csw=\"http://www.opengis.net/cat/csw/2.0.2\" service=\"CSW\" version=\"2.0.2\" resultType=\"results\" maxRecords=\"100\">\n  <csw:Query typeNames=\"gmd:MD_Metadata\">\n    <csw:ElementSetName>full</csw:ElementSetName>\n  </csw:Query>\n</csw:GetRecords>\n--></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Protocol/HTTP.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_constructor(t) {\n        t.plan(8);\n        var a = new OpenLayers.Protocol.HTTP({\n            url: \"foo\"\n        });\n\n        // 4 tests\n        t.eq(a.url, \"foo\", \"constructor sets url\");\n        t.eq(a.options.url, a.url, \"constructor copies url to options.url\");\n        t.eq(a.params, {}, \"constructor sets params\");\n        t.eq(a.options.params, undefined, \"constructor do not copy params to options.params\");\n\n        var params = {hello: \"world\"};\n        var b = new OpenLayers.Protocol.HTTP({\n            url: \"bar\",\n            params: params\n        });\n\n        // 4 tests\n        t.eq(b.url, \"bar\", \"constructor sets url\");\n        t.eq(b.options.url, b.url, \"constructor copies url to options.url\");\n        t.eq(b.params, params, \"constructor sets params\");\n        t.eq(b.options.params, b.params, \"constructor copies params to options.params\");\n    }\n\n    function test_destroy(t) {\n        t.plan(3);\n        var protocol = new OpenLayers.Protocol.HTTP({\n            url: \"bar\",\n            params: {hello: \"world\"}\n        });\n        protocol.destroy();\n        t.eq(protocol.options, null, \"destroy nullifies options\");\n        t.eq(protocol.params, null, \"destroy nullifies params\");\n        t.eq(protocol.headers, null, \"destroy nullifies headers\");\n    }\n\n    function test_read(t) {\n        t.plan(10);\n        var protocol = new OpenLayers.Protocol.HTTP({\n            'url': 'foo_url',\n            'params': {'k': 'foo_param'}\n        });\n\n        // fake XHR request object\n        var request = {'status': 200};\n\n        // options to pass to read\n        var readOptions = {\n            'url': 'bar_url',\n            'params': {'k': 'bar_param'},\n            'headers': {'k': 'bar_header'},\n            'scope': {'hello': 'world'},\n            'callback': function() {}\n        };\n\n        var response;\n\n        protocol.handleResponse = function(resp, opt) {\n            // 4 tests\n            var req = resp.priv;\n            t.ok(this == protocol,\n                'handleResponse called with correct scope');\n            t.ok(opt == readOptions,\n                'handleResponse called with correct options');\n            t.eq(resp.CLASS_NAME, 'OpenLayers.Protocol.Response',\n                'handleResponse called with a Response object');\n            t.eq(req, request,\n                'handleResponse called with correct request');\n\n            response = resp;\n        };\n\n        var _get = OpenLayers.Request.GET;\n\n        OpenLayers.Request.GET = function(options) {\n            // 5 tests\n            t.eq(options.url, readOptions.url,\n                'GET called with correct url in options');\n            t.eq(options.params['k'], readOptions.params['k'],\n                'GET called with correct params in options');\n            t.eq(options.headers['k'], readOptions.headers['k'],\n                'GET called with correct headers in options');\n            t.eq(options.scope, undefined,\n                'GET called with correct scope in options');\n            t.ok(typeof options.callback == 'function',\n                'GET called with a callback in options');\n            t.delay_call(0.1, function() {\n                options.callback(request);\n                t.ok(resp == response,\n                    'read returns the expected response object');        \n                // cleanup\n                protocol.destroy();\n                OpenLayers.Request.GET = _get;\n            });\n            return request;\n        };\n\n        var resp = protocol.read(readOptions);\n\n        OpenLayers.Request.GET = _get;\n    }\n\n    function test_readWithPOST(t) {\n        t.plan(10);\n        var protocol = new OpenLayers.Protocol.HTTP({\n            'url': 'foo_url',\n            'params': {'k': 'foo_param'}\n        });\n\n        // fake XHR request object\n        var request = {'status': 200};\n\n        // options to pass to read\n        var readOptions = {\n            'url': 'bar_url',\n            'params': {'k': 'bar_param'},\n            'scope': {'hello': 'world'},\n            'callback': function() {},\n            'readWithPOST': true\n        };\n\n        var response;\n\n        protocol.handleResponse = function(resp, opt) {\n            // 4 tests\n            var req = resp.priv;\n            t.ok(this == protocol,\n                'handleResponse called with correct scope');\n            t.ok(opt == readOptions,\n                'handleResponse called with correct options');\n            t.eq(resp.CLASS_NAME, 'OpenLayers.Protocol.Response',\n                'handleResponse called with a Response object');\n            t.eq(req, request,\n                'handleResponse called with correct request');\n\n            response = resp;\n        };\n\n        var _post = OpenLayers.Request.POST;\n\n        OpenLayers.Request.POST = function(options) {\n            // 5 tests\n            t.eq(options.url, readOptions.url,\n                'GET with POST called with correct url in options');\n            t.eq(options.data, OpenLayers.Util.getParameterString(readOptions.params),\n                'GET with POST called with correct params encoded in options');\n            t.eq(options.headers, {\"Content-Type\": \"application/x-www-form-urlencoded\"},\n                'GET with POST called with correct headers (application/x-www-form-urlencoded)');\n            t.eq(options.scope, undefined,\n                'GET with POST called with correct scope in options');\n            t.ok(typeof options.callback == 'function',\n                'GET with POST called with a callback in options');\n            t.delay_call(0.1, function() {\n                options.callback(request);\n                t.ok(resp == response,\n                    'read returns the expected response object');        \n                // cleanup\n                protocol.destroy();\n                OpenLayers.Request.POST = _post;\n            });\n            return request;\n        };\n\n        var resp = protocol.read(readOptions);\n\n        OpenLayers.Request.POST = _post;\n    }\n\n    function test_read_method(t) {\n        t.plan(4);\n\n        var _post = OpenLayers.Request.POST;\n        OpenLayers.Request.POST = function(options) { return 'post'; }\n        var _get = OpenLayers.Request.GET;\n        OpenLayers.Request.GET = function(options) { return 'get'; }\n\n        var protocol = new OpenLayers.Protocol.HTTP({});\n\n        t.eq(protocol.read({}).priv, 'get',\n            'readWithPOST is false by default');\n        t.eq(protocol.read({readWithPOST: true}).priv, 'post',\n            'readWithPOST can be set in read options');\n\n        var protocol = new OpenLayers.Protocol.HTTP({readWithPOST: true});\n\n        t.eq(protocol.read({}).priv, 'post',\n            'readWithPOST can be set in constructor');\n        t.eq(protocol.read({readWithPOST: false}).priv, 'get',\n            'readWithPOST can be overridden in read options');\n\n        OpenLayers.Request.POST = _post;\n        OpenLayers.Request.GET = _get;\n    }\n\n    function test_read_bbox(t) {\n        t.plan(6);\n\n        var _get = OpenLayers.Request.GET;\n\n        var bounds = new OpenLayers.Bounds(1, 2, 3, 4);\n        var filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.BBOX,\n            value: bounds,\n            projection: new OpenLayers.Projection(\"foo\")\n        });\n        \n        // log requests\n        var log, exp;\n        OpenLayers.Request.GET = function(options) {\n            log.push(options.params.bbox);\n            return {status: 200};\n        };\n\n        // 1) issue request with default protocol\n        log = [];\n        new OpenLayers.Protocol.HTTP().read({filter: filter});\n\n        t.eq(log.length, 1, \"1) GET called once\");\n        t.ok(log[0] instanceof Array, \"1) bbox param is array\");\n        exp = bounds.toArray();\n        t.eq(log[0], exp, \"1) bbox param doesn't include SRS id by default\");\n        \n        // 2) issue request with default protocol\n        log = [];\n        new OpenLayers.Protocol.HTTP({srsInBBOX: true}).read({filter: filter});\n\n        t.eq(log.length, 1, \"2) GET called once\");\n        t.ok(log[0] instanceof Array, \"2) bbox param is array\");\n        exp = bounds.toArray();\n        exp.push(\"foo\");\n        t.eq(log[0], exp, \"2) bbox param includes SRS id if srsInBBOX is true\");\n\n        OpenLayers.Request.GET = _get;        \n    }\n\n    function test_parseFeatures(t) {\n        t.plan(5);\n\n        var protocol = new OpenLayers.Protocol.HTTP();\n\n        // test responseXML - 2 tests\n        var request = {\n            'responseXML': {\n                'documentElement': 'xml'\n            }\n        };\n        protocol.format = {\n            'read': function(doc) {\n                t.eq(doc.documentElement, 'xml',\n                    'format.read called with correct doc');\n                return doc.documentElement;\n            }\n        };\n        var ret = protocol.parseFeatures(request);\n        t.eq(ret, 'xml', 'parseFeatures returns expected value');\n\n        // test responseText - 2 tests\n        var request = {\n            'responseText': 'text'\n        };\n        protocol.format = {\n            'read': function(doc) {\n                t.eq(doc, 'text',\n                    'format.read called with correct doc');\n                return doc;\n            }\n        };\n        var ret = protocol.parseFeatures(request);\n        t.eq(ret, 'text', 'parseFeatures returns expected value');\n\n        // test empty responseText - 1 test\n        var request = {\n            'responseText': ''\n        };\n        protocol.format = {\n            'read': function(doc) {\n                t.fail('format.read should not be called');\n            }\n        };\n        var ret = protocol.parseFeatures(request);\n        t.eq(ret, null, 'parseFeatures returns expected value');\n    }\n\n    function test_create(t) {\n        t.plan(10);\n        var protocol = new OpenLayers.Protocol.HTTP({\n            'url': 'foo_url',\n            'format': {'write': function() {}}\n        });\n\n        // fake XHR request object\n        var request = {'status': 200};\n\n        // features to pass to create\n        var features = ['feature'];\n\n        // options to pass to create\n        var createOptions = {\n            'url': 'bar_url',\n            'headers': {'k': 'bar_header'},\n            'scope': {'hello': 'world'},\n            'callback': function() {}\n        };\n\n        var response;\n\n        protocol.handleCreate = function(resp, opt) {\n            // 5 tests\n            var req = resp.priv;\n            t.ok(this == protocol,\n                'handleCreate called with correct scope');\n            t.ok(opt == createOptions,\n                'handleCreate called with correct options');\n            t.eq(resp.CLASS_NAME, 'OpenLayers.Protocol.Response',\n                'handleCreate called with a Response object');\n            t.ok(resp.reqFeatures == features,\n                'handleCreate called with correct requested features in response');\n            t.eq(req, request,\n                'handleCreate called with correct request');\n\n            response = resp;\n        };\n\n        var _post = OpenLayers.Request.POST;\n\n        OpenLayers.Request.POST = function(options) {\n            // 4 tests\n            t.eq(options.url, createOptions.url,\n                'POST called with correct url in options');\n            t.eq(options.headers['k'], createOptions.headers['k'],\n                'POST called with correct headers in options');\n            t.eq(options.scope, undefined,\n                'POST called with correct scope in options');\n            t.ok(typeof options.callback == 'function',\n                'POST called with a callback in options');\n            // call callback - delayed because this function has to return first\n            t.delay_call(0.1, function() {\n                options.callback(request);\n                t.ok(resp == response,\n                    'create returns the expected response object');\n                // cleanup\n                protocol.destroy();\n                OpenLayers.Request.POST = _post;\n            });\n            return request;\n        };\n\n        var resp = protocol.create(features, createOptions);\n        \n        OpenLayers.Request.POST = _post;\n    }\n\n    function test_update(t) {\n        t.plan(10);\n        var protocol = new OpenLayers.Protocol.HTTP({\n            'url': 'foo_url',\n            'format': {'write': function() {}}\n        });\n\n        // fake XHR request object\n        var request = {'status': 200};\n\n        // feature to pass to update\n        var feature = {'feature':'feature'};\n\n        // options to pass to update\n        var updateOptions = {\n            'url': 'bar_url',\n            'headers': {'k': 'bar_header'},\n            'scope': {'hello': 'world'},\n            'callback': function() {}\n        };\n\n        var response;\n\n        protocol.handleUpdate = function(resp, opt) {\n            var req = resp.priv;\n            // 5 tests\n            t.ok(this == protocol,\n                'handleUpdate called with correct scope');\n            t.ok(opt == updateOptions,\n                'handleUpdate called with correct options');\n            t.eq(resp.CLASS_NAME, 'OpenLayers.Protocol.Response',\n                'handleUpdate called with a Response object');\n            t.ok(resp.reqFeatures == feature,\n                'handleUpdate called with correct requested feature in response');\n            t.eq(req, request,\n                'handleUpdate called with correct request');\n\n            response = resp;\n        };\n\n        var _put = OpenLayers.Request.PUT;\n\n        OpenLayers.Request.PUT = function(options) {\n            // 4 tests\n            t.eq(options.url, updateOptions.url,\n                'PUT called with correct url in options');\n            t.eq(options.headers['k'], updateOptions.headers['k'],\n                'PUT called with correct headers in options');\n            t.eq(options.scope, undefined,\n                'PUT called with correct scope in options');\n            t.ok(typeof options.callback == 'function',\n                'PUT called with a callback in options');\n            // call callback - delayed because this function has to return first\n            t.delay_call(0.1, function() {\n                options.callback(request);\n                t.ok(resp == response,\n                    'update returns the expected response object');\n                // cleanup\n                protocol.destroy();\n                OpenLayers.Request.PUT = _put;\n            });\n            return request;\n        };\n\n        var resp = protocol.update(feature, updateOptions);\n        \n        OpenLayers.Request.PUT = _put;\n    }\n\n    function test_update_featureurl(t) {\n\n        // test that OpenLayers.Request.PUT receives the URL\n        // set in the feature\n        // http://trac.openlayers.org/ticket/2393#comment:11\n\n        t.plan(1);\n\n        var protocol = new OpenLayers.Protocol.HTTP({\n            'url': 'foo_url',\n            'format': {'write': function() {}}\n        });\n\n        // feature to pass to update\n        var feature = {'feature':'feature', 'url': 'bar_url'};\n\n        var _put = OpenLayers.Request.PUT;\n\n        OpenLayers.Request.PUT = function(options) {\n            t.eq(options.url, feature.url,\n                'PUT called with correct url in options');\n        };\n\n        protocol.update(feature);\n\n        OpenLayers.Request.PUT = _put;\n    }\n\n    function test_handleResponse(t) {\n        t.plan(6);\n\n        var protocol = new OpenLayers.Protocol.HTTP();\n\n        var options, response, request, features;\n\n        // test options - 2 tests\n        var scope = {'fake': 'scope'};\n        options = {\n            'scope': scope,\n            'callback': function(resp) {\n                t.ok(this == scope,\n                    '[no status] callback called with correct scope');\n                t.ok(resp == response,\n                    '[no status] callback called with correct response');\n            }\n        };\n        response = {priv: {}};\n        protocol.handleResponse(response, options);\n        \n        // test failure condition - 1 test\n        options = {\n            'callback': function(resp) {\n                t.eq(resp.code, OpenLayers.Protocol.Response.FAILURE,\n                    '[status 400] callback called with correct response code');\n            }\n        };\n        response = {priv: {status: 400}};\n        protocol.handleResponse(response, options);\n\n        // test success condition - 3 tests\n        features = {'fake': 'features'};\n        options = {\n            'callback': function(resp) {\n                t.eq(resp.code, OpenLayers.Protocol.Response.SUCCESS,\n                    '[status 200] callback called with correct response code');\n                t.eq(resp.features, features,\n                    '[status 200] callback called with correct features in response');\n            }\n        };\n        response = {priv: {status: 200}};\n        protocol.parseFeatures = function(request) {\n            t.ok(request == response.priv,\n                '[status 200] parseFeatures called with correct request');\n            return features;\n        }\n        protocol.handleResponse(response, options);\n\n        // cleanup\n        protocol.destroy();\n    }\n\n    function test_delete(t) {\n        t.plan(10);\n        var protocol = new OpenLayers.Protocol.HTTP({\n            'url': 'foo_url'\n        });\n\n        // fake XHR request object\n        var request = {'status': 200};\n\n        // feature to pass to delete\n        var feature = {'url': 'bar_url'};\n\n        // options to pass to delete\n        var deleteOptions = {\n            'url': 'bar_url',\n            'headers': {'k': 'bar_header'},\n            'scope': {'hello': 'world'},\n            'callback': function() {}\n        };\n\n        var response;\n\n        protocol.handleDelete = function(resp, opt) {\n            // 5 tests\n            var req = resp.priv;\n            t.ok(this == protocol,\n                'handleDelete called with correct scope');\n            t.ok(opt == deleteOptions,\n                'handleDelete called with correct options');\n            t.eq(resp.CLASS_NAME, 'OpenLayers.Protocol.Response',\n                'handleDelete called with a Response object');\n            t.ok(resp.reqFeatures == feature,\n                'handleDelete called with correct requested feature in response');\n            t.eq(req, request,\n                'handleDelete called with correct request');\n\n            response = resp;\n        };\n\n        var _delete = OpenLayers.Request.DELETE;\n\n        OpenLayers.Request.DELETE = function(options) {\n            // 4 tests\n            t.eq(options.url, deleteOptions.url,\n                'DELETE called with correct url in options');\n            t.eq(options.headers['k'], deleteOptions.headers['k'],\n                'DELETE called with correct headers in options');\n            t.eq(options.scope, undefined,\n                'DELETE called with correct scope in options');\n            t.ok(typeof options.callback == 'function',\n                'DELETE called with a callback in options');\n            // call callback - delayed because this function has to return first\n            t.delay_call(0.1, function() {\n                options.callback(request);\n                t.ok(resp == response,\n                    'read returns the expected response object');\n                // cleanup\n                protocol.destroy();\n                OpenLayers.Request.DELETE = _delete;\n            });\n            return request;\n        };\n\n        var resp = protocol['delete'](feature, deleteOptions);\n\n        OpenLayers.Request.DELETE = _delete;\n    }\n\n    function test_delete_featureurl(t) {\n\n        // test that OpenLayers.Request.DELETE receives the URL\n        // set in the feature\n        // http://trac.openlayers.org/ticket/2393#comment:11\n\n        t.plan(1);\n\n        var protocol = new OpenLayers.Protocol.HTTP({\n            'url': 'foo_url',\n            'format': {'write': function() {}}\n        });\n\n        // feature to pass to update\n        var feature = {'feature':'feature', 'url': 'bar_url'};\n\n        var _delete = OpenLayers.Request.DELETE;\n\n        OpenLayers.Request.DELETE = function(options) {\n            t.eq(options.url, feature.url,\n                'DELETE called with correct url in options');\n        };\n\n        protocol['delete'](feature);\n\n        OpenLayers.Request.DELETE = _delete;\n    }\n\n    function test_handleDelete(t) {\n        t.plan(4);\n\n        var protocol = new OpenLayers.Protocol.HTTP();\n\n        var options, response, request, features;\n\n        // test options - 2 tests\n        var scope = {'fake': 'scope'};\n        options = {\n            'scope': scope,\n            'callback': function(resp) {\n                t.ok(this == scope,\n                    'callback called with correct scope');\n                t.ok(resp == response,\n                    'callback called with correct response');\n            }\n        };\n        response = {priv: {}};\n        protocol.handleDelete(response, options);\n        \n        // test failure condition - 1 test\n        options = {\n            'callback': function(resp) {\n                t.eq(resp.code, OpenLayers.Protocol.Response.FAILURE,\n                    'callback called with correct response code');\n            }\n        };\n        response = {priv: {status: 400}};\n        protocol.handleDelete(response, options);\n\n        // test success condition - 1 test\n        options = {\n            'callback': function(resp) {\n                t.eq(resp.code, OpenLayers.Protocol.Response.SUCCESS,\n                    'callback called with correct response code');\n            }\n        };\n        response = {priv: {status: 200}};\n        protocol.handleDelete(response, options);\n\n        // cleanup\n        protocol.destroy();\n    }\n\n    function test_commit(t) {\n        t.plan(17);\n\n        var protocol = new OpenLayers.Protocol.HTTP();\n\n        // 6 features\n        var features = [\n            {'state': OpenLayers.State.INSERT},\n            {'state': OpenLayers.State.INSERT},\n            {'state': OpenLayers.State.UPDATE},\n            {'state': OpenLayers.State.UPDATE},\n            {'state': OpenLayers.State.DELETE},\n            {'state': OpenLayers.State.DELETE}\n        ];\n\n        var options = {\n            'create': {\n                'callback': function(resp) {\n                }\n            },\n            'update': {\n                'callback': function(resp) {\n                }\n            },\n            'delete': {\n                'callback': function(resp) {\n                }\n            }\n        };\n\n        var respCreate = new OpenLayers.Protocol.Response();\n        var respUpdate = new OpenLayers.Protocol.Response();\n        var respDelete = new OpenLayers.Protocol.Response();\n\n        // 2 tests\n        protocol['create'] = function(feature, options) {\n            t.ok(options.scope == protocol,\n                'create called with correct scope');\n            t.ok(typeof options.callback == 'function',\n                'create called with a callback in options');\n            options.callback.call(options.scope, respCreate);\n            return respCreate;\n        };\n        // 4 tests\n        protocol['update'] = function(feature, options) {\n            t.ok(options.scope == protocol,\n                'update called with correct scope');\n            t.ok(typeof options.callback == 'function',\n                'update called with a callback in options');\n            options.callback.call(options.scope, respUpdate);\n            return respUpdate;\n        };\n        // 4 tests\n        protocol['delete'] = function(feature, options) {\n            t.ok(options.scope == protocol,\n                'delete called with correct scope');\n            t.ok(typeof options.callback == 'function',\n                'delete called with a callback in options');\n            options.callback.call(options.scope, respDelete);\n            return respDelete;\n        };\n\n        var count = 0;\n\n        // 5 tests\n        protocol.callUserCallback = function(resp, opt) {\n            t.ok(opt == options,\n                'callUserCallback called with correction options map');\n            count++;\n        };\n\n        var resp = protocol.commit(features, options);\n\n        // 2 tests\n        t.eq(count, 5, 'callUserCallback called for each request');\n        t.eq(resp.length, 5, 'commit returns array with correct length');\n\n        // cleanup\n        protocol.destroy();\n    }\n\n    function test_callUserCallback(t) {\n        t.plan(1);\n\n        var protocol = new OpenLayers.Protocol.HTTP();\n\n        var scope = {'fake': 'scope'};\n\n        // test commit callback\n        var log = {};\n        var options = {\n            foo: {\n                callback: function() {\n                    log.scope = this;\n                },\n                scope: scope\n            }\n        };\n        var resp = {requestType: 'foo'};\n        protocol.callUserCallback(resp, options);\n        t.ok(log.scope, scope, 'correct callback called with correct scope');\n\n    }\n\n    function test_options(t) {\n        t.plan(6);\n        \n        var log1 = {};\n\n        // test that read with no options uses protocol options - 5 tests\n        var url = \".\";\n        var headers = {};\n        var params = {};\n        var scope = {};\n        var protocol = new OpenLayers.Protocol.HTTP({\n            format: new OpenLayers.Format({\n                read: function() {},\n                write: function() {}\n            }),\n            url: url,\n            headers: headers,\n            params: params,\n            callback: function(resp) {\n                log1.callbackCalled = true;\n                log1.callbackScope = this;\n                log1.request = resp && resp.priv;\n                log1.requestType = resp && resp.requestType;\n            },\n            scope: scope\n        });        \n        protocol.read();\n        \n        t.delay_call(2, function() {\n            t.eq(log1.callbackCalled, true, \"[read] callback called\");\n            t.eq(log1.callbackScope, scope, \"[read] correct scope\");\n            t.ok(log1.request instanceof OpenLayers.Request.XMLHttpRequest, \"[read] correct priv type\");\n            t.eq(log1.requestType, \"read\", \"[read] correct request type\");\n        });\n        \n\n        // test that commit with no options uses protocol options - 2 tests\n        var log2 = {called: 0};\n        protocol.options.callback = function() {\n            log2.called++;\n            log2.scope = this;\n        };\n        protocol.commit([\n            {state: OpenLayers.State.INSERT},\n            {state: OpenLayers.State.INSERT},\n            {state: OpenLayers.State.UPDATE, url: \"./1\"},\n            {state: OpenLayers.State.UPDATE, url: \"./2\"},\n            {state: OpenLayers.State.DELETE, url: \"./3\"},\n            {state: OpenLayers.State.DELETE, url: \"./4\"}\n        ]);\n        t.delay_call(2, function() {\n            t.eq(log2.called, 1, \"[commit] Callback called once.\");\n            t.eq(log2.scope, scope, \"[commit] Correct scope.\");\n        });\n    }\n\n    function test_read_global_options(t) {\n\n        // test that calling read doesn't write params into the protocol's\n        // options object, see ticket #3237\n\n        t.plan(2);\n\n        var protocol = new OpenLayers.Protocol.HTTP({\n            url: '.',\n            callback: function() {},\n            params: {'a': 'a'}\n        });\n\n        // check initial state first\n        t.eq(protocol.options.params, {'a': 'a'},\n             'protocol params are ok at initial state');\n\n        var filter = new OpenLayers.Filter.Comparison({\n            type: OpenLayers.Filter.Comparison.EQUAL_TO,\n            property: 'b',\n            value: 'b'\n        });\n        protocol.read({filter: filter});\n        t.eq(protocol.options.params, {'a': 'a'},\n             \"protocol params are ok after read\");\n    }\n\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Protocol/SOS.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_constructor(t) {\n        t.plan(4);\n        var a = new OpenLayers.Protocol.SOS({\n            url: \"foo\",\n            fois: [\"a\", \"b\", \"c\"]\n        });\n\n        t.eq(a.url, \"foo\", \"constructor sets url\");\n        t.eq(a.options.url, a.url, \"constructor copies url to options.url\");\n        t.eq(a.fois[0], \"a\", \"constructor sets the fois correctly\");\n        t.eq((a.format instanceof OpenLayers.Format.SOSGetFeatureOfInterest), true, \"Constructor sets format correctly\"); \n    }\n\n    function test_read(t) {\n        t.plan(4);\n\n        var protocol = new OpenLayers.Protocol.SOS({\n            url: \"http://some.url.org/sos?\",\n            fois: [\"foi1\", \"foi2\"],\n            parseFeatures: function(request) {\n                t.eq(request.responseText, \"foo\", \"parseFeatures called properly\");\n                return \"foo\";\n            }\n        });\n\n        var _POST = OpenLayers.Request.POST;\n\n        var expected, status;\n        OpenLayers.Request.POST = function(obj) {\n            t.xml_eq(new OpenLayers.Format.XML().read(obj.data).documentElement, expected, \"GetFeatureOfInterest request is correct\");\n            obj.status = status;\n            obj.responseText = \"foo\";\n            obj.options = {};\n            t.delay_call(0.1, function() {obj.callback.call(this)});\n            return obj;\n        };\n\n        var xml = '<GetFeatureOfInterest xmlns=\"http://www.opengis.net/sos/1.0\" version=\"1.0.0\" service=\"SOS\" xsi:schemaLocation=\"http://www.opengis.net/sos/1.0 http://schemas.opengis.net/sos/1.0.0/sosAll.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><FeatureOfInterestId>foi1</FeatureOfInterestId><FeatureOfInterestId>foi2</FeatureOfInterestId></GetFeatureOfInterest>';\n        expected = new OpenLayers.Format.XML().read(xml).documentElement;\n        status = 200;\n        var response = protocol.read({callback: function(response) {\n            t.eq(response.features, \"foo\", \"user callback properly called with features\");\n            t.eq(response.code, OpenLayers.Protocol.Response.SUCCESS, \"success reported properly\");\n        }});\n\n    }\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Protocol/Script.html",
    "content": "<html>\n<head>\n  <script src=\"../../lib/OpenLayers.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_constructor(t) {\n        t.plan(11);\n        var a = new OpenLayers.Protocol.Script({\n            url: \"foo\"\n        });\n\n        // 7 tests\n        t.eq(a.url, \"foo\", \"constructor sets url\");\n        t.eq(a.options.url, a.url, \"constructor copies url to options.url\");\n        t.eq(a.params, {}, \"constructor sets params\");\n        t.eq(a.options.params, undefined, \"constructor does not copy params to options.params\");\n        t.ok(a.format instanceof OpenLayers.Format.GeoJSON,\n                \"constructor sets a GeoJSON format by default\");\n        t.eq(a.callbackKey, 'callback',\n                \"callbackKey is set to 'callback' by default\");\n        t.eq(a.callbackPrefix, '',\n                \"callbackPrefix is set to '' by default\");\n\n        var params = {hello: \"world\"};\n        var b = new OpenLayers.Protocol.Script({\n            url: \"bar\",\n            params: params,\n            callbackKey: 'cb_key',\n            callbackPrefix: 'cb_prefix'\n        });\n\n        // 6 tests\n        t.eq(b.params, params, \"constructor sets params\");\n        t.eq(b.options.params, b.params, \"constructor copies params to options.params\");\n        t.eq(b.callbackKey, 'cb_key',\n                \"callbackKey is set to 'cb_key'\");\n        t.eq(b.callbackPrefix, 'cb_prefix',\n                \"callbackPrefix is set to 'cb_prefix'\");\n    }\n\n    function test_destroy(t) {\n        t.plan(3);\n        var aborted = false;\n        var protocol = new OpenLayers.Protocol.Script({\n            url: \"bar\",\n            params: {hello: \"world\"},\n            abort: function() {\n                aborted = true;\n            }\n        });\n        protocol.destroy();\n        t.ok(aborted, \"destroy aborts request\");\n        t.eq(protocol.params, null, \"destroy nullifies params\");\n        t.eq(protocol.format, null, \"destroy nullifies format\");\n    }\n\n    function test_read(t) {\n        t.plan(5);\n        var protocol = new OpenLayers.Protocol.Script({\n            'url': 'foo_url',\n            'params': {'k': 'foo_param'}\n        });\n\n        // fake XHR request object\n        var request = {'status': 200};\n\n        // options to pass to read\n        var readOptions = {\n            'url': 'bar_url',\n            'params': {'k': 'bar_param'}\n        };\n\n        var response;\n\n        protocol.createRequest = function(url, params, callback) {\n            // 4 tests\n            t.ok(this == protocol,\n                'createRequest called with correct scope');\n            t.ok(url == readOptions.url,\n                'createRequest called with correct url');\n            t.ok(params == readOptions.params,\n                'createRequest called with correct params');\n            t.ok(callback instanceof Function,\n                'createRequest called with a function as callback');\n\n            return 'foo_request';\n       };\n\n        var resp = protocol.read(readOptions);\n\n        t.eq(resp.priv, 'foo_request',\n            'response priv property set to what the createRequest method returns');\n    }\n\n    function test_read_bbox(t) {\n        t.plan(6);\n\n        var _createRequest = OpenLayers.Protocol.Script.prototype.createRequest;\n\n        var bounds = new OpenLayers.Bounds(1, 2, 3, 4);\n        var filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.BBOX,\n            value: bounds,\n            projection: new OpenLayers.Projection(\"foo\")\n        });\n\n        // log requests\n        var log, exp;\n        OpenLayers.Protocol.Script.prototype.createRequest = function(url, params,\n                                                               callback) {\n            log.push(params.bbox);\n            return null;\n        };\n\n        // 1) issue request with default protocol\n        log = [];\n        new OpenLayers.Protocol.Script().read({filter: filter});\n\n        t.eq(log.length, 1, \"1) createRequest called once\");\n        t.ok(log[0] instanceof Array, \"1) bbox param is array\");\n        exp = bounds.toArray();\n        t.eq(log[0], exp, \"1) bbox param doesn't include SRS id by default\");\n\n        // 2) issue request with default protocol\n        log = [];\n        new OpenLayers.Protocol.Script({srsInBBOX: true}).read({filter: filter});\n\n        t.eq(log.length, 1, \"2) createRequest called once\");\n        t.ok(log[0] instanceof Array, \"2) bbox param is array\");\n        exp = bounds.toArray();\n        exp.push(\"foo\");\n        t.eq(log[0], exp, \"2) bbox param includes SRS id if srsInBBOX is true\");\n\n        OpenLayers.Protocol.Script.prototype.createRequest = _createRequest;\n    }\n\n    function test_createRequest(t) {\n        t.plan(6);\n        var protocol = new OpenLayers.Protocol.Script({\n            callbackKey: 'cb_key',\n            callbackPrefix: 'cb_prefix:'\n        });\n\n        var _register = OpenLayers.Protocol.Script.register;\n        OpenLayers.Protocol.Script.register = function() {\n            return 'bar';\n        };\n\n        var script = protocol.createRequest('http://bar_url/', {'k': 'bar_param'}, 'bar_callback');\n\n        t.eq(script.type, 'text/javascript',\n            'created script has a correct type');\n\n        var params = OpenLayers.Util.getParameters(script.src);        \n        t.eq(params.k, \"bar_param\", \"custom query string param\");\n        t.eq(params.cb_key, \"cb_prefix:OpenLayers.Protocol.Script.registry.bar\", \"callback with prefix\");\n\n        t.eq(script.id, 'OpenLayers_Protocol_Script_bar',\n            'created script has a correct id');\n\n        protocol.callbackTemplate = \"customCallback(${id})\";\n        script = protocol.createRequest('http://bar_url/', {'k': 'bar_param2'}, 'bar_callback');\n\n        params = OpenLayers.Util.getParameters(script.src);        \n        t.eq(params.k, \"bar_param2\", \"custom query string param\");\n        t.eq(params.cb_key, \"cb_prefix:customCallback(bar)\", \"custom callback with prefix\");\n\n        OpenLayers.Protocol.Script.register = _register;\n\n    }\n\n    function test_destroyRequest(t) {\n        t.plan(2);\n\n        var protocol = new OpenLayers.Protocol.Script({});\n\n        var _unregister = OpenLayers.Protocol.Script.unregister;\n        OpenLayers.Protocol.Script.unregister = function(id) {\n            t.eq(id, 'foo', \"destroyRequest calls unregister with correct id\");\n        };\n        var script = {\n            id: 'script_foo'\n        };\n        protocol.destroyRequest(script);\n        t.eq(protocol.pendingRequests[script.id], null, \n            \"destroyRequest nullifies the pending request\");\n\n        OpenLayers.Protocol.Script.unregister = _unregister;\n    }\n\n    function test_handleResponse(t) {\n        t.plan(8);\n\n        var protocol = new OpenLayers.Protocol.Script();\n\n        // 2 tests (should be called only twive)\n        protocol.destroyRequest = function(priv) {\n            t.eq(priv, 'foo_priv', 'destroyRequest called with correct argument');\n        }\n\n        // 1 test (should be called only once)\n        protocol.parseFeatures = function(data) {\n            t.eq(data, 'foo_data', 'parseFeatures called with correct argument');\n            return 'foo_features';\n        }\n\n        var response = {\n            priv: 'foo_priv',\n            data: 'foo_data'\n        }\n        var options = {\n            // 2 tests (should be called twice)\n            scope: 'foo_scope',\n            callback: function(resp) {\n                t.eq(this, 'foo_scope', 'callback called with correct scope');\n            }\n        }\n        protocol.handleResponse(response, options);\n        // 2 tests\n        t.eq(response.code, OpenLayers.Protocol.Response.SUCCESS,\n                'response code correctly set');\n        t.eq(response.features, 'foo_features', \n                'response features takes a correct value');\n\n        response = {\n            priv: 'foo_priv'\n        }\n        protocol.handleResponse(response, options);\n        // 1 test\n        t.eq(response.code, OpenLayers.Protocol.Response.FAILURE,\n                'response code correctly set');\n    }\n\n    function test_parseFeatures(t) {\n        t.plan(1);\n\n        var protocol = new OpenLayers.Protocol.Script();\n\n        protocol.format = {\n            'read': function(data) {\n                t.ok(true, 'format.read called');\n            }\n        };\n\n        var ret = protocol.parseFeatures({foo: 'bar'});\n    }\n\n    function test_abort(t) {\n        t.plan(2);\n\n        var protocol = new OpenLayers.Protocol.Script();\n\n        // 1 test\n        protocol.destroyRequest = function(priv) {\n            t.eq(priv, 'foo_priv', 'destroyRequest called with correct argument');\n        }\n\n        var response = {\n            priv: 'foo_priv'\n        }\n\n        protocol.abort(response);\n\n        var calls = [];\n        protocol.pendingRequests = {\n            'foo': 'foo_request',\n            'bar': 'bar_request'\n        }\n        protocol.destroyRequest = function(priv) {\n            calls.push(priv);\n        }\n        protocol.abort();\n        // 1 test\n        t.eq(calls, ['foo_request', 'bar_request'],\n                'destroyRequest called for each pending requests');\n    }\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Protocol/WFS.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(3);\n\n        var protocol = new OpenLayers.Protocol.WFS({\n            url: \"http://some.url.org\",\n            featureNS: \"http://namespace.org\",\n            featureType: \"type\"\n        });\n        t.ok(protocol instanceof OpenLayers.Protocol.WFS.v1_0_0,\n             \"initialize returns instance of default versioned protocol\");\n\n        var protocol = new OpenLayers.Protocol.WFS({\n            url: \"http://some.url.org\",\n            featureNS: \"http://namespace.org\",\n            featureType: \"type\",\n            version: \"1.1.0\"\n        });\n        t.ok(protocol instanceof OpenLayers.Protocol.WFS.v1_1_0,\n             \"initialize returns instance of custom versioned protocol\");\n        \n        var protocol = new OpenLayers.Protocol.WFS({\n            url: \"http://some.url.org\",\n            featureNS: \"http://namespace.org\",\n            featureType: \"type\",\n            version: \"2.0.0\"\n        });\n        t.ok(protocol instanceof OpenLayers.Protocol.WFS.v2_0_0,\n             \"initialize returns instance of custom versioned protocol\");\n    }\n\n    function test_setGeometryName(t) {\n        t.plan(4);\n        var protocol = new OpenLayers.Protocol.WFS({\n            url: \"http://some.url.org\",\n            featureNS: \"http://namespace.org\",\n            featureType: \"type\",\n            geometryName: \"geom\"\n        });\n        t.eq(protocol.geometryName, \"geom\", \"geometryName set correctly by constructor\");\n        t.eq(protocol.format.geometryName, \"geom\", \"geometryName correctly set on format by constructor\");\n        // change the geometryName on the fly\n        protocol.setGeometryName(\"SHAPE\");\n        t.eq(protocol.geometryName, \"SHAPE\", \"geometryName changed correctly by setGeometryName\");\n        t.eq(protocol.format.geometryName, \"SHAPE\", \"geometryName correctly changed on format by setGeometryName\");\n        protocol.destroy();\n    }\n\n    function test_setFeatureType(t) {\n        t.plan(4);\n        var protocol = new OpenLayers.Protocol.WFS({\n            url: \"http://some.url.org\",\n            featureNS: \"http://namespace.org\",\n            featureType: \"type\"\n        });\n        t.eq(protocol.featureType, \"type\", \"featureType set correctly by constructor\");\n        t.eq(protocol.format.featureType, \"type\", \"featureType correctly set on format by constructor\");\n        // change the feature type on the fly\n        protocol.setFeatureType(\"foo\");\n        t.eq(protocol.featureType, \"foo\", \"featureType changed correctly by setFeatureType\");\n        t.eq(protocol.format.featureType, \"foo\", \"featureType correctly changed on format by setFeatureType\");\n        protocol.destroy();\n    }\n\n    function test_read(t) {\n        t.plan(7);\n\n        var protocol = new OpenLayers.Protocol.WFS({\n            url: \"http://some.url.org\",\n            featureNS: \"http://namespace.org\",\n            featureType: \"type\",\n            parseResponse: function(request, options) {\n                t.eq(request.responseText, \"foo\", \"parseResponse called properly\");\n                t.eq(options, {foo: \"bar\"}, \"parseResponse receives readOptions\");\n                return \"foo\";\n            }\n        });\n\n        var _POST = OpenLayers.Request.POST;\n\n        var expected, status;\n        OpenLayers.Request.POST = function(obj) {\n            t.xml_eq(new OpenLayers.Format.XML().read(obj.data).documentElement, expected, \"GetFeature request is correct\");\n            obj.status = status;\n            obj.responseText = \"foo\";\n            t.delay_call(0.1, function() {obj.callback.call(this)});\n            return obj;\n        };\n\n        expected = readXML(\"GetFeature_1\");\n        status = 200;\n        var response = protocol.read({readOptions: {foo: \"bar\"}, callback: function(response) {\n            t.eq(response.features, \"foo\", \"user callback properly called with features\");\n            t.eq(response.code, OpenLayers.Protocol.Response.SUCCESS, \"success reported properly\");\n        }});\n\n        options = {\n            maxFeatures: 10,\n            featureType: 'type2',\n            srsName: 'EPSG:900913',\n            featureNS: 'htttp://alternative.namespace.org',\n            callback: function(response) {\n                t.eq(response.code, OpenLayers.Protocol.Response.FAILURE, \"failure reported properly to user callback\");\n            }\n        };\n        expected = readXML(\"GetFeature_2\");\n        status = 400;\n        var response = protocol.read(options);\n\n        OpenLayers.Request.POST = _POST;\n    }\n    \n    function test_parseResponse_poorconfig(t) {\n        t.plan(2);\n\n        var protocol = new OpenLayers.Protocol.WFS({\n            url: \"http://some.url.org\",\n            featurePrefix: \"topp\",\n            featureType: \"tasmania_roads\",\n            geometryName: null\n        });\n\n        protocol.parseResponse({responseText: document.getElementById(\"query_response\").firstChild.nodeValue});\n        t.eq(protocol.geometryName, \"geom\", \"geometryName configured correctly\");\n        t.eq(protocol.featureNS, \"http://www.openplans.org/topp\", \"featureNS configured correctly\");\n    }\n\n    function test_exception(t) {\n        t.plan(8);\n        var url = \"http://some.url.org\";\n        var protocol = new OpenLayers.Protocol.WFS({\n            url: url,\n            version: \"1.1.0\",\n            featureNS: \"http://namespace.org\",\n            featureType: \"type\"\n        });\n        // mock up a response\n        var response = {\n            priv: {\n                status: 200,\n                responseText: '<?xml version=\"1.0\" encoding=\"UTF-8\"?><ows:ExceptionReport language=\"en\" version=\"1.0.0\" xsi:schemaLocation=\"http://www.opengis.net/ows http://schemas.opengis.net/ows/1.0.0/owsExceptionReport.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ows=\"http://www.opengis.net/ows\"><ows:Exception locator=\"foo\" exceptionCode=\"InvalidParameterValue\"><ows:ExceptionText>Update error: Error occurred updating features</ows:ExceptionText><ows:ExceptionText>Second exception line</ows:ExceptionText></ows:Exception></ows:ExceptionReport>'\n            }\n        };\n        var log, entry, expected;\n        \n        // test GetFeature\n        log = [];\n        protocol.handleRead(OpenLayers.Util.extend({}, response), {\n            callback: function(resp) {\n                log.push(resp);\n            }\n        });\n        expected = {\n            exceptionReport: {\n                version: \"1.0.0\",\n                language: \"en\",\n                exceptions: [{\n                    code: \"InvalidParameterValue\",\n                    locator: \"foo\",\n                    texts: [\n                        \"Update error: Error occurred updating features\",\n                        \"Second exception line\"\n                    ]\n                }]\n            },\n            success: false\n        };\n\n        t.eq(log.length, 1, \"GetFeature handled\");\n        entry = log[0];\n        t.eq(entry.code, OpenLayers.Protocol.Response.FAILURE, \"GetFeature failure reported\");\n        t.ok(!!entry.error, \"GetFeature got error\");\n        t.eq(entry.error, expected, \"GetFeature error matches expected\");\n\n        // test a commit\n        log = [];\n        protocol.handleCommit(response, {\n            callback: function(resp) {\n                log.push(resp);\n            }\n        });\n        t.eq(log.length, 1, \"commit handled\");\n        entry = log[0];\n        t.eq(entry.code, OpenLayers.Protocol.Response.FAILURE, \"commit failure reported\");\n        t.ok(!!entry.error, \"commit got error\");\n        t.eq(entry.error, expected, \"GetFeature error matches expected\");\n\n    }\n\n    function test_commit(t){\n        t.plan(5);\n\n        var url = \"http://some.url.org\";\n        var protocol = new OpenLayers.Protocol.WFS({\n            url: url,\n            featureNS: \"http://namespace.org\",\n            featureType: \"type\"\n        });\n        protocol.format.read = function(data) {\n            t.eq(data, \"foo\", \"callback called with correct argument\");\n            return {\n                insertIds: new Array(3),\n                success: true\n            }\n        };\n\n        var _POST = OpenLayers.Request.POST;\n\n        var expected;\n        OpenLayers.Request.POST = function(obj) {\n            t.xml_eq(new OpenLayers.Format.XML().read(obj.data).documentElement, expected, \"Transaction XML with Insert, Update and Delete created correctly\");\n            t.eq(obj.headers, {foo: 'bar'}, \"HTTP headers passed from commit to Request.POST\");\n            obj.responseText = \"foo\";\n            t.delay_call(0.1, function() {obj.callback.call(this)});\n            return obj;\n        };\n\n        var featureDelete = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(42, 7), {has : \"cheeseburger\"});\n        featureDelete.fid = \"fid.37\";\n        featureDelete.state = OpenLayers.State.DELETE;\n        featureDelete.layer = {\n            projection: {\n                getCode : function(){\n                    return \"EPSG:4326\";\n                }\n            }\n        }\n        var featureInsert = featureDelete.clone();\n        featureInsert.state = OpenLayers.State.INSERT;\n        var featureModify = featureDelete.clone();\n        featureModify.fid = \"fid.37\";\n        featureModify.state = OpenLayers.State.UPDATE;\n\n        options = {\n            featureNS: \"http://some.namespace.org\",\n            featureType: \"type\",\n            headers: {foo: 'bar'},\n            callback: function(response) {\n                t.eq(response.insertIds.length, 3, \"correct response passed to user callback\");\n                t.eq(response.code, OpenLayers.Protocol.Response.SUCCESS, \"success properly reported to user callback\");\n            }\n        }\n\n        expected = readXML(\"commit\");\n        var response = protocol.commit([featureInsert, featureModify, featureDelete], options);\n\n        OpenLayers.Request.POST = _POST;\n\n    }\n\n    function test_filterDelete(t) {\n        t.plan(2)\n\n        var url = \"http://some.url.org\";\n        var protocol = new OpenLayers.Protocol.WFS({\n            url: url,\n            featureNS: \"http://namespace.org\",\n            featureType: \"type\"\n        });\n\n        var filter = new OpenLayers.Filter.Spatial({\n            type: OpenLayers.Filter.Spatial.BBOX,\n            value: new OpenLayers.Bounds(-5, -5, 5, 5)\n        });\n\n        var _POST = OpenLayers.Request.POST;\n\n        var expected = readXML(\"filter_delete\");\n        OpenLayers.Request.POST = function(obj) {\n            t.xml_eq(new OpenLayers.Format.XML().read(obj.data).documentElement, expected, \"request data correct\");\n            t.delay_call(0.1, function() {obj.callback.call(this)});\n            return obj;\n        };\n\n        var response = protocol.filterDelete(filter, {\n            callback: function() {\n                t.ok(\"user callback function called\");\n            }\n        });\n\n        OpenLayers.Request.POST = _POST;\n    }\n\n    function test_abort(t) {\n        t.plan(1);\n        var protocol = new OpenLayers.Protocol.WFS({\n            url: \"http://example.com\",\n            featureNS: \"http://example.com#namespace\",\n            featureType: \"type\"\n        });\n\n        var response = {\n            priv: {\n                abort: function() {\n                    aborted = true;\n                }\n            }\n        };\n\n        // call abort with mocked response\n        var aborted = false;\n        protocol.abort(response);\n        t.eq(aborted, true, \"abort called on response.priv\");\n\n    }\n\n    function test_fromWMSLayer(t) {\n        t.plan(9);\n        var map = new OpenLayers.Map(\"map\", {\n            projection: \"CRS:84\"\n        });\n        var layer = new OpenLayers.Layer.WMS(\"foo\", \"htttp://foo/ows\",\n            {layers: \"topp:states\"}\n        );\n        map.addLayer(layer);\n        var protocol = OpenLayers.Protocol.WFS.fromWMSLayer(layer);\n        t.eq(protocol.url, \"htttp://foo/ows\", \"url taken from wms layer\");\n        t.eq(protocol.featurePrefix, \"topp\", \"feature prefix correctly extracted\");\n        t.eq(protocol.featureType, \"states\", \"typeName correctly extracted\");\n        t.eq(protocol.srsName, \"CRS:84\", \"srsName set correctly\");\n        t.eq(protocol.version, \"1.1.0\", \"version set correctly\");\n        t.eq(protocol.format.geometryName, null, \"format's geometryName set to null\");\n\n        layer.params[\"LAYERS\"] = [\"topp:street_centerline\", \"topp:states\"];\n        layer.projection = new OpenLayers.Projection(\"EPSG:900913\");\n        protocol = OpenLayers.Protocol.WFS.fromWMSLayer(layer);\n        t.eq(protocol.featurePrefix, \"topp\", \"featurePrefix from layer param array\");\n        t.eq(protocol.featureType, \"street_centerline\", \"first layer from layer param array as featureType\");\n        t.eq(protocol.srsName, \"EPSG:900913\", \"projection from layer preferred\");\n    }\n\n    function test_readFormat(t) {\n        t.plan(1);\n\n        var protocol = new OpenLayers.Protocol.WFS({\n            url: \"http://some.url.org\",\n            featureNS: \"http://namespace.org\",\n            featureType: \"type\",\n            formatOptions: {outputFormat: 'json'},\n            readFormat: new OpenLayers.Format.GeoJSON()\n        });\n\n        var request = {};\n        request.responseText = '{\"type\":\"FeatureCollection\",\"features\":[{\"type\":\"Feature\",\"id\":\"V_HECTOPUNTEN.108411\",\"geometry\":{\"type\":\"MultiPoint\",\"coordinates\":[[190659.467,349576.19]]},\"geometry_name\":\"ORA_GEOMETRY\",\"properties\":{\"WEGNUMMER\":\"002\",\"HECTOMTRNG_ORG\":2200,\"HECTOMTRNG\":\"220.00\",\"bbox\":[190659.467,349576.19,190659.467,349576.19]}}]}';\n        var features = protocol.parseResponse(request);\n        t.eq(features.length, 1, \"the right format is used to read the request (GeoJSON)\");\n \t}\n\n    function test_outputFormat(t) {\n        t.plan(2);\n\n        var protocol = new OpenLayers.Protocol.WFS({\n            version: \"1.1.0\",\n            url: \"http://some.url.org\",\n            featureNS: \"http://namespace.org\",\n            featureType: \"type\",\n            outputFormat: 'json'\n        });\n\n        t.ok(protocol.readFormat instanceof OpenLayers.Format.GeoJSON, \"the correct readFormat is used for outputFormat JSON\");\n\n        protocol = new OpenLayers.Protocol.WFS({\n            version: \"1.1.0\",\n            url: \"http://some.url.org\",\n            featureNS: \"http://namespace.org\",\n            featureType: \"type\",\n            outputFormat: 'GML2'\n        });\n\n        t.ok(protocol.readFormat instanceof OpenLayers.Format.GML.v2, \"the correct readFormat is used for outputFormat GML2\");\n \t}\n\n    function test_readOptions(t) {\n        t.plan(1);\n\n        var protocol = new OpenLayers.Protocol.WFS({\n            url: \"http://some.url.org\",\n            version: \"1.1.0\",\n            featureNS: \"http://namespace.org\",\n            featureType: \"type\",\n            readOptions: {'output': 'object'},\n            parseResponse: function(request, options) {\n                t.eq(options.output, \"object\", \"Options object correctly set to pass on to Format's read\");\n            }\n        });\n\n        var _POST = OpenLayers.Request.POST;\n\n        OpenLayers.Request.POST = function(obj) {\n            obj.status = 200;\n            obj.responseText = \"foo\";\n            t.delay_call(0.1, function() {obj.callback.call(this)});\n            return obj;\n        };\n\n        protocol.read({\n            callback: function() {}\n        });\n\n        OpenLayers.Request.POST = _POST;\n    }\n\n    function readXML(id) {\n        var xml = document.getElementById(id).firstChild.nodeValue;\n        return new OpenLayers.Format.XML().read(xml).documentElement;\n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:512px; height:256px\"> </div>\n<div id=\"GetFeature_1\"><!--\n<wfs:GetFeature xmlns:wfs=\"http://www.opengis.net/wfs\" service=\"WFS\" version=\"1.0.0\" xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n    <wfs:Query typeName=\"feature:type\" xmlns:feature=\"http://namespace.org\"/>\n</wfs:GetFeature>\n--></div>\n<div id=\"GetFeature_2\"><!--\n<wfs:GetFeature xmlns:wfs=\"http://www.opengis.net/wfs\" service=\"WFS\" version=\"1.0.0\" maxFeatures=\"10\" xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n    <wfs:Query typeName=\"feature:type2\" xmlns:feature=\"htttp://alternative.namespace.org\"/>\n</wfs:GetFeature>\n--></div>\n<div id=\"commit\"><!--\n<wfs:Transaction xmlns:wfs=\"http://www.opengis.net/wfs\" service=\"WFS\" version=\"1.0.0\" xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n    <wfs:Insert>\n        <feature:type xmlns:feature=\"http://namespace.org\">\n            <feature:the_geom>\n                <gml:Point xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"EPSG:4326\">\n                    <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">42,7</gml:coordinates>\n                </gml:Point>\n            </feature:the_geom>\n            <feature:has>cheeseburger</feature:has>\n        </feature:type>\n    </wfs:Insert>\n    <wfs:Update typeName=\"feature:type\" xmlns:feature=\"http://namespace.org\">\n        <wfs:Property>\n            <wfs:Name>the_geom</wfs:Name>\n            <wfs:Value>\n                <gml:Point xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"EPSG:4326\">\n                    <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">42,7</gml:coordinates>\n                </gml:Point>\n            </wfs:Value>\n        </wfs:Property>\n        <wfs:Property>\n            <wfs:Name>has</wfs:Name>\n            <wfs:Value>cheeseburger</wfs:Value>\n        </wfs:Property>\n        <ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n            <ogc:FeatureId fid=\"fid.37\"/>\n        </ogc:Filter>\n    </wfs:Update>\n    <wfs:Delete typeName=\"feature:type\" xmlns:feature=\"http://namespace.org\">\n        <ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n            <ogc:FeatureId fid=\"fid.37\"/>\n        </ogc:Filter>\n    </wfs:Delete>\n</wfs:Transaction>\n--></div>\n<div id=\"filter_delete\"><!--\n<wfs:Transaction xmlns:wfs=\"http://www.opengis.net/wfs\" service=\"WFS\" version=\"1.0.0\">\n    <wfs:Delete typeName=\"feature:type\" xmlns:feature=\"http://namespace.org\">\n        <ogc:Filter xmlns:ogc=\"http://www.opengis.net/ogc\">\n            <ogc:BBOX>\n                <gml:Box xmlns:gml=\"http://www.opengis.net/gml\" srsName=\"EPSG:4326\">\n                    <gml:coordinates decimal=\".\" cs=\",\" ts=\" \">-5,-5 5,5</gml:coordinates>\n                </gml:Box>\n            </ogc:BBOX>\n        </ogc:Filter>\n    </wfs:Delete>\n</wfs:Transaction>\n--></div>\n<div id=\"query_response\"><!--\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<wfs:FeatureCollection xmlns:ogc=\"http://www.opengis.net/ogc\" xmlns:wfs=\"http://www.opengis.net/wfs\" xmlns:topp=\"http://www.openplans.org/topp\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:ows=\"http://www.opengis.net/ows\" xmlns:gml=\"http://www.opengis.net/gml\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><gml:boundedBy><gml:Envelope srsDimension=\"2\" srsName=\"urn:x-ogc:def:crs:EPSG:4326\"><gml:lowerCorner>5450000.0 500000.0</gml:lowerCorner><gml:upperCorner>5450000.0 540000.0</gml:upperCorner></gml:Envelope></gml:boundedBy><gml:featureMembers><topp:tasmania_roads gml:id=\"tasmania_roads.1\"><gml:boundedBy><gml:Envelope srsDimension=\"2\" srsName=\"urn:x-ogc:def:crs:EPSG:4326\"><gml:lowerCorner>5450000.0 500000.0</gml:lowerCorner><gml:upperCorner>5450000.0 540000.0</gml:upperCorner></gml:Envelope></gml:boundedBy><topp:geom><gml:MultiLineString srsDimension=\"2\" srsName=\"urn:x-ogc:def:crs:EPSG:4326\"><gml:lineStringMember><gml:LineString><gml:posList>5450000.0 500000.0 5450000.0 540000.0</gml:posList></gml:LineString></gml:lineStringMember></gml:MultiLineString></topp:geom><topp:TYPE>street</topp:TYPE></topp:tasmania_roads></gml:featureMembers></wfs:FeatureCollection>\n--></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Protocol.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(4);\n        var options = {};\n        var protocol = new OpenLayers.Protocol(options);\n\n        t.ok(protocol instanceof OpenLayers.Protocol,\n             \"new OpenLayers.Protocol returns object\" );\n        t.eq(protocol.options, options, \"constructor sets this.options\");\n        t.eq(protocol.options.filter, null, \"constructor sets defaultFilter to null\");\n        t.eq(protocol.autoDestroy, true, \"constructor does not modify this.autoDestroy\");\n    }\n    \n    function test_read_defaultFilter(t) {\n        t.plan(4);\n\n        var protocol = new OpenLayers.Protocol({filter: \"a\"});\n        var options = {};\n        protocol.read(options);\n        // the line below is what happens in Protocol.WFS.v1::read\n        OpenLayers.Util.applyDefaults(options, protocol.options);\n        t.eq(options.filter, \"a\", \"filter from protocol.options applied to options\");\n        protocol.destroy();\n\n        var defaultFilter = 'a';\n        var options = {\n            defaultFilter: defaultFilter\n        };\n\n        protocol = new OpenLayers.Protocol(options);\n        var readFilter = 'b';\n        var options = { filter: readFilter };\n\n        protocol.read(options);\n\n        var filter = options.filter;\n        t.ok(filter instanceof OpenLayers.Filter.Logical, \"read method merge default filter & options filter to a logical one\");\n        t.eq(filter.type, OpenLayers.Filter.Logical.AND, \"logical filter type is OpenLayers.Filter.Logical.AND\");\n        t.eq(filter.filters, [defaultFilter, readFilter], \"read method has merged filters\");\n        protocol.destroy();\n    }\n\n    function test_destroy(t) {\n        t.plan(2);\n        var protocol = new OpenLayers.Protocol({\n            options: {foo: 'bar'},\n            format: 'foo'\n        });\n        protocol.destroy();\n\n        t.eq(protocol.format, null, \"destroy nullify protocol.format\");\n        t.eq(protocol.options, null, \"destroy nullify protocol.options\");\n    }\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/README.txt",
    "content": "This directory contains unit tests for the OpenLayers library.\n\nTests use the Test.AnotherWay library from <http://openjsan.org>. The test\nrunner is 'run-tests.html' and new test files need to be added to\n'list-tests.html'.\n\nThe following file naming conventions are used:\n\n  * A filename that starts with `test_` and has an `.html` extension\n    contains tests. These should contain tests for a specific class.\n\n  * A filename starting with `page_` and has an `.html` extension is a\n    supporting HTML file used in one or more tests.\n\n  * A filename starting with 'data_` is a supporting data file used in one\n    or more tests.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Renderer/Canvas.html",
    "content": "<html>\n<head>\n<script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var supported = OpenLayers.Renderer.Canvas.prototype.supported();\n    \n    var map, layer;\n    function setUp() {\n        map = new OpenLayers.Map(\"map\");\n        layer = new OpenLayers.Layer.Vector(null, {\n            isBaseLayer: true,\n            renderers: [\"Canvas\"]\n        });\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0, 0));\n    }\n    \n    function tearDown() {\n        map.destroy();\n        map = null;\n        layer = null;\n    }\n    \n    function test_Renderer_Canvas_constructor(t) {\n        if (!supported) { t.plan(0); return; }\n        t.plan(2);\n        var el = document.body;\n        el.id = \"foo\";\n        var r = new OpenLayers.Renderer.Canvas(el.id);\n        \n        t.ok(r instanceof OpenLayers.Renderer.Canvas, \"new OpenLayers.Renderer.Canvas returns Renderer.Canvas object\" );\n        t.ok(r.container == el, \"renderer container is correctly set\");\n        r.destroy();\n    }\n    \n    function test_Renderer_Canvas_setextent(t) {\n        if (!supported) { t.plan(0); return; }\n        t.plan(2);\n        \n        setUp();\n        \n        var r = layer.renderer;        \n        var extent = new OpenLayers.Bounds(1,2,3,4);\n        r.resolution = 1;\n        r.setExtent(extent, true);\n        t.ok(r.extent.equals(extent), \"extent is correctly set\");\n        t.eq(r.resolution, null, \"resolution nullified\");\n        \n        tearDown();\n    }\n    \n    function test_Renderer_Canvas_setsize(t) {\n        if (!supported) { t.plan(0); return; }\n        t.plan(2);\n        \n        var el = document.body;\n        el.id = \"foo\";\n        var r = new OpenLayers.Renderer.Canvas(el.id);\n        var size = new OpenLayers.Size(1,2);\n        r.resolution = 1;\n        r.setSize(size);\n        t.ok(r.size.equals(size), \"size is correctly set\");\n        t.eq(r.resolution, null, \"resolution nullified\");\n        r.destroy();\n    }\n    \n    function test_Renderer_Canvas_getresolution(t) {\n        if (!supported) { t.plan(0); return; }\n        t.plan(2);\n        \n        var el = document.body;\n        el.id = \"foo\";\n        var r = new OpenLayers.Renderer.Canvas(el.id);\n        var map = new OpenLayers.Map(\"map\");\n        r.map = map;\n        var resolution = r.getResolution();\n        t.eq(resolution, map.getResolution(), \"resolution matches the map resolution\");\n        t.eq(r.resolution, resolution, \"resolution is correctly set\");\n        map.destroy();\n    }\n\n    function test_featureIdToHex(t) {\n        if (!supported) {\n            t.plan(0); \n            return;\n        }\n        t.plan(2);\n        var el = document.body;\n        el.id = \"foo\";\n        var renderer = new OpenLayers.Renderer.Canvas(el.id);\n        \n        var cases = [{\n            id: \"foo_0\", hex: \"#000001\"\n        }, {\n            id: \"foo_10\", hex: \"#00000b\"\n        }, {\n            id: \"foo_100\", hex: \"#000065\"\n        }, {\n            id: \"foo_1000000\", hex: \"#0f4241\"\n        }, {\n            id: \"foo_16777214\", hex: \"#ffffff\"\n        }, {\n            id: \"foo_16777215\", hex: \"#000001\"\n        }];\n        t.plan(cases.length);\n        \n        var c;\n        for (var i=0; i<cases.length; ++i) {\n            c = cases[i];\n            t.eq(renderer.featureIdToHex(c.id), c.hex, c.id);\n        }\n        \n        renderer.destroy();\n    }\n\n\n    function test_Renderer_Canvas_destroy(t) {\n        if (!supported) { t.plan(0); return; }\n        t.plan(5);\n\n        var el = document.body;\n        el.id = \"foo\";\n        var r = new OpenLayers.Renderer.Canvas(el.id);\n        r.container = document.createElement(\"div\");\n        r.extent = new OpenLayers.Bounds(1,2,3,4);\n        r.size = new OpenLayers.Size(1,2);\n        r.resolution = 1;\n        r.map = {};\n\n        r.destroy();\n\n        t.eq(r.container, null, \"container nullified\");\n        t.eq(r.extent, null, \"extent nullified\");\n        t.eq(r.size, null, \"size nullified\");\n        t.eq(r.resolution, null, \"resolution nullified\");\n        t.eq(r.map, null, \"map nullified\");\n    }\n\n    function test_drawFeature(t) {\n        if (!supported) {\n            t.plan(0); \n            return; \n        }\n        \n        t.plan(10);\n        \n        setUp();\n        \n        var renderer = layer.renderer;\n        var count = 0;\n        var redraw = layer.renderer.redraw;\n        renderer.redraw = function() {\n            ++count;\n            redraw.apply(this, arguments);\n        }\n        var exp;\n        \n        // a) draw a point feature\n        count = 0;\n        exp = renderer.drawFeature(\n            new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0, 0)), {}\n        );\n        t.eq(exp, true, \"a) drawFeature returns true\");\n        t.eq(count, 1, \"a) redraw called once after drawing a point feature\");\n        renderer.clear();\n        \n        // b) draw one feature with no geometry\n        count = 0;\n        exp = renderer.drawFeature(\n            new OpenLayers.Feature.Vector(), {}\n        );\n        t.eq(exp, undefined, \"b) drawFeature returns undefined\");\n        t.eq(count, 0, \"b) redraw is not called when drawing a feature with no geometry\");\n        renderer.clear();\n        \n        // c) draw a point feature with display \"none\"\n        count = 0;\n        exp = renderer.drawFeature(\n            new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1, 0)),\n            {display: \"none\"}\n        );\n        t.eq(exp, false, \"c) drawFeature returns false\");\n        t.eq(count, 1, \"c) redraw is called when drawing a feature with display 'none'\");\n        renderer.clear();\n\n        // d) draw a point feature outside renderer extent\n        count = 0;\n        exp = renderer.drawFeature(\n            new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(-1000, 0)), {}\n        );\n        t.eq(exp, false, \"d) drawFeature returns false\");\n        t.eq(count, 1, \"d) redraw is called when drawing a feature outside renderer extent\");\n        renderer.clear();\n        \n        // e) draw a polygon feature without bounds\n        count = 0;\n        exp = renderer.drawFeature(\n            new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Polygon()), {}\n        );\n        t.eq(exp, false, \"d) drawFeature returns false\");\n        t.eq(count, 1, \"d) redraw is called when drawing a feature without bounds\");\n        renderer.clear();\n\n        tearDown();\n    }\n\n\n    function test_pendingRedraw(t) {\n        if (!supported) {\n            t.plan(0); \n            return; \n        }\n        \n        t.plan(4);\n        var layer = new OpenLayers.Layer.Vector(null, {\n            isBaseLayer: true,\n            renderers: [\"Canvas\"]\n        });\n        \n        var map = new OpenLayers.Map({\n            div: \"map\",\n            controls: [],\n            layers: [layer],\n            center: new OpenLayers.LonLat(0, 0),\n            zoom: 0\n        });\n        \n        var count = 0;\n        var redraw = layer.renderer.redraw;\n        layer.renderer.redraw = function() {\n            ++count;\n            redraw.apply(this, arguments);\n        }\n        \n        // add one point feature and confirm redraw is called once\n        count = 0;\n        layer.addFeatures([\n            new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0, 0))\n        ]);\n        t.eq(count, 1, \"redraw called once after adding one point feature\");\n        \n        // add one feature with no geometry and confirm redraw is not called\n        count = 0;\n        layer.addFeatures([\n            new OpenLayers.Feature.Vector()\n        ]);\n        t.eq(count, 0, \"redraw is not called when adding a feature with no geometry\");\n        \n        // add one point feature, one feature with no geom, and one point feature and confirm redraw is called once\n        count = 0;\n        layer.addFeatures([\n            new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1, 0)),\n            new OpenLayers.Feature.Vector(),\n            new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0, 1))\n        ]);\n        t.eq(count, 1, \"redraw called once after adding three features where middle one has no geometry\");\n\n        // add two point features and one feature with no geom, and confirm redraw is called once\n        count = 0;\n        layer.addFeatures([\n            new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(1, 0)),\n            new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0, 1)),\n            new OpenLayers.Feature.Vector()\n        ]);\n        t.eq(count, 1, \"redraw called once after adding three features where last one has no geometry\");\n        \n        map.destroy();\n    }\n    \n    function test_hitDetection(t) {\n        if (!supported) {\n            t.plan(0); \n            return; \n        }\n        \n        var layer = new OpenLayers.Layer.Vector(null, {\n            isBaseLayer: true,\n            resolutions: [1],\n            styleMap: new OpenLayers.StyleMap({\n                pointRadius: 5,\n                strokeWidth: 3,\n                fillColor: \"red\",\n                fillOpacity: 0.5,\n                strokeColor: \"blue\",\n                strokeOpacity: 0.75\n            }),\n            renderers: [\"Canvas\"]\n        });\n        \n        var map = new OpenLayers.Map({\n            div: \"map\",\n            controls: [],\n            layers: [layer],\n            center: new OpenLayers.LonLat(0, 0),\n            zoom: 0\n        });\n        \n        layer.addFeatures([\n            new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.Point(-100, 0)\n            ),\n            new OpenLayers.Feature.Vector(\n                OpenLayers.Geometry.fromWKT(\"LINESTRING(-50 0, 50 0)\")\n            ),\n            new OpenLayers.Feature.Vector(\n                OpenLayers.Geometry.fromWKT(\"POLYGON((100 -25, 150 -25, 150 25, 100 25, 100 -25), (120 -5, 130 -5, 130 5, 120 5, 120 -5))\")\n            ),\n            new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.Point(80, 0), {}, {\n                    graphicName: \"square\",\n                    pointRadius: 8,\n                    strokeWidth: 4,\n                    fillColor: \"red\",\n                    fillOpacity: 0.5,\n                    strokeColor: \"blue\",\n                    strokeOpacity: 0.75\n                } \n            )\n        ]);\n        \n        var cases = [{\n            msg: \"center of point\", x: -100, y: 0, id: layer.features[0].id\n        }, {\n            msg: \"edge of point\", x: -106, y: 0, id: layer.features[0].id\n        }, {\n            msg: \"outside point\", x: -110, y: 0, id: null\n        }, {\n            msg: \"center of line\", x: 0, y: 0, id: layer.features[1].id\n        }, {\n            msg: \"edge of line\", x: 0, y: 1, id: layer.features[1].id\n        }, {\n            msg: \"outside line\", x: 0, y: 5, id: null\n        }, {\n            msg: \"inside polygon\", x: 110, y: 0, id: layer.features[2].id\n        }, {\n            msg: \"edge of polygon\", x: 99, y: 0, id: layer.features[2].id\n        }, {\n            msg: \"inside polygon hole\", x: 125, y: 0, id: null\n        }, {\n            msg: \"outside polygon\", x: 155, y: 0, id: null\n        }, {\n            msg: \"inside symbol\", x: 80, y: 0, id: layer.features[3].id\n        }, {\n            msg: \"outside symbol interior, inside symbol edge\", x: 90, y: 8, id: layer.features[3].id\n        }, {\n            msg: \"outside symbol\", x: 94, y: 0, id: null\n        }];\n\n        function px(x, y) {\n            return map.getPixelFromLonLat(\n                new OpenLayers.LonLat(x, y)\n            );\n        }        \n        \n        var num = cases.length;\n        t.plan(2 * num);\n        var c, feature;\n        for (var i=0; i<num; ++i) {\n            c = cases[i];\n            feature = layer.renderer.getFeatureIdFromEvent({xy: px(c.x, c.y)});\n            t.eq(feature && feature.id, c.id, c.msg);\n            \n            // Extra test: hit detection on an invisible canvas should return undefined\n            layer.setVisibility(false);\n            feature = layer.renderer.getFeatureIdFromEvent({xy: px(c.x, c.y)});\n            t.eq(feature, undefined, c.msg + ' (invisible)');\n            layer.setVisibility(true);\n        }\n        \n        map.destroy();\n        \n    }\n\n    // see http://trac.osgeo.org/openlayers/ticket/3264\n    function test_externalGraphic_destroyFeatures(t) {\n        if (!supported) {\n            t.plan(0);\n            return;\n        }\n\n        t.plan(1);\n\n        // set up\n\n        var layer = new OpenLayers.Layer.Vector(null, {\n            isBaseLayer: true,\n            renderers: [\"Canvas\"]\n        });\n\n        var map = new OpenLayers.Map({\n            div: \"map\",\n            controls: [],\n            layers: [layer],\n            center: new OpenLayers.LonLat(0, 0),\n            zoom: 0\n        });\n\n        layer.addFeatures([\n            new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.Point(0, 0),\n                null,\n                {\n                    externalGraphic: '../../img/marker.png',\n                    graphicHeight: 20,\n                    graphicWidth: 20\n                }\n            )\n        ]);\n\n        var called = false;\n        layer.renderer.canvas.drawImage = function(img, x, y, w, h) {\n            called = true;\n        };\n\n        // test\n\n        // schedule a canvas.drawImage\n        layer.renderer.redraw();\n\n        // destroy the feature before drawImage gets called\n        layer.destroyFeatures();\n\n        t.delay_call(0.1, function() {\n            t.ok(!called,\n                 'canvas.drawImage not called if feature is destroyed');\n\n            // tear down\n            map.destroy();\n        });\n    }\n\n    // see http://trac.osgeo.org/openlayers/ticket/3264\n    function test_externalGraphic_moveTo(t) {\n        if (!supported) {\n            t.plan(0);\n            return;\n        }\n\n        t.plan(2);\n\n        // set up\n\n        var layer = new OpenLayers.Layer.Vector(null, {\n            isBaseLayer: true,\n            renderers: [\"Canvas\"]\n        });\n\n        var map = new OpenLayers.Map({\n            div: \"map\",\n            controls: [],\n            layers: [layer],\n            center: new OpenLayers.LonLat(0, 0),\n            zoom: 0\n        });\n\n        var feature = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(0, 0),\n            null,\n            {\n                externalGraphic: '../../img/marker.png',\n                graphicHeight: 20,\n                graphicWidth: 20,\n                graphicXOffset: 0,\n                graphicYOffset: 0\n            }\n        );\n\n        layer.addFeatures([feature]);\n\n        // test\n\n        // delay_call to let the first drawImage (the one\n        // resulting from addFeatures) run\n        t.delay_call(0.1, function() {\n\n            var log = [];\n            layer.renderer.canvas.drawImage = function(img, x, y, w, h) {\n                log.push({x: x, y: y});\n            };\n\n            layer.renderer.redraw();\n            t.delay_call(0.1, function() {\n\n                map.setCenter(new OpenLayers.LonLat(45, 0), 0);\n                t.delay_call(0.1, function() {\n\n                t.eq(log.length, 2,\n                         \"canvas.drawImage called twice\");\n                    t.ok(log[0].x > log[1].x && log[0].y == log[1].y,\n                         \"second image drawn at a location with smaller x and same y\");\n\n                    // tear down\n                    map.destroy();\n                });\n            });\n        });\n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Renderer/Elements.html",
    "content": "<html>\n<head>\n<script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function setUp() {\n        // Stub out functions that are meant to be overridden by\n        // subclasses.\n        OpenLayers.Renderer.Elements.prototype._createRenderRoot =\n            OpenLayers.Renderer.Elements.prototype.createRenderRoot;\n        \n        var rendererRoot = document.createElement(\"div\");\n        OpenLayers.Renderer.Elements.prototype.createRenderRoot = function() {\n            return rendererRoot;\n        };\n        \n        OpenLayers.Renderer.Elements.prototype._createRoot =\n            OpenLayers.Renderer.Elements.prototype.createRoot;\n        \n        OpenLayers.Renderer.Elements.prototype.createRoot = function() {\n            return document.createElement(\"div\");\n        };\n        \n        OpenLayers.Renderer.Elements.prototype._createNode =\n            OpenLayers.Renderer.Elements.prototype.createNode;\n        \n        OpenLayers.Renderer.Elements.prototype.createNode = function() {\n            return document.createElement(\"div\");\n        };\n    }\n    \n    // Create a new Elements renderer based on an id and an ordering\n    // type. For these tests, both of these parameters are optional.\n    function create_renderer(id, options) {\n        \n        rendererRoot = null;\n        \n        if (id == null) {\n            var el = document.createElement('div');\n            document.body.appendChild(el);\n            el.id = OpenLayers.Util.createUniqueID();\n            id = el.id;\n        }\n        \n        return new OpenLayers.Renderer.Elements(id, options);\n    }\n    \n    // Cleanup stubs made in the function above.\n    function tearDown() {\n        OpenLayers.Renderer.Elements.prototype.createRenderRoot =\n            OpenLayers.Renderer.Elements.prototype._createRenderRoot;\n        OpenLayers.Renderer.Elements.prototype.createRoot =\n            OpenLayers.Renderer.Elements.prototype._createRoot;\n        OpenLayers.Renderer.Elements.prototype.createNode =\n            OpenLayers.Renderer.Elements.prototype._createNode;\n    }\n\n    function test_Elements_constructor(t) {\n        t.plan(6);\n        \n        setUp();\n        \n        var r = create_renderer();\n        \n        t.ok(r instanceof OpenLayers.Renderer.Elements, \"new OpenLayers.Renderer.Elements returns Elements object\" );\n        t.ok(r.rendererRoot != null, \"elements rendererRoot is not null\");\n        t.ok(r.root != null, \"elements root is not null\");\n        t.ok(r.indexer == null, \"indexer is null if unused.\");\n        \n        t.ok(r.root.parentNode == r.rendererRoot, \"elements root is correctly appended to rendererRoot\");\n        t.ok(r.rendererRoot.parentNode == r.container, \"elements rendererRoot is correctly appended to container\");\n        \n        tearDown();\n    }\n    \n    function test_Elements_destroy(t) {\n        t.plan(5);\n        \n        var elems = {\n            'clear': function() {\n                t.ok(true, \"clear called\");\n            },\n            'rendererRoot': {},\n            'root': {},\n            'xmlns': {}\n        };\n\n        OpenLayers.Renderer.prototype._destroy = \n            OpenLayers.Renderer.prototype.destroy;\n\n        var args = [{}, {}, {}];\n        OpenLayers.Renderer.prototype.destroy = function() {\n            t.ok((arguments[0] == args[0]) &&\n                 (arguments[1] == args[1]) &&\n                 (arguments[2] == args[2]), \"correct arguments passed to OpenLayers.Renderer.destroy()\");\n        };\n\n        OpenLayers.Renderer.Elements.prototype.destroy.apply(elems, args);\n\n        t.ok(elems.rendererRoot == null, \"rendererRoot nullified\");\n        t.ok(elems.root == null, \"root nullified\");\n        t.ok(elems.xmlns == null, \"xmlns nullified\");\n\n        OpenLayers.Renderer.prototype.destroy = \n            OpenLayers.Renderer.prototype._destroy;\n\n    }\n    \n    function test_Elements_clear(t) {\n        t.plan(2);\n        \n        setUp();\n        \n        var r = create_renderer();\n        var element = document.createElement(\"div\");\n        r.root = element;\n        \n        var node = document.createElement(\"div\");\n        element.appendChild(node);\n        \n        r.clear();\n        \n        t.ok(r.vectorRoot.childNodes.length == 0, \"vector root is correctly cleared\");\n        t.ok(r.textRoot.childNodes.length == 0, \"text root is correctly cleared\");\n        \n        tearDown();\n    }\n    \n    function test_Elements_drawGeometry(t) {\n        t.plan(7);\n\n        setUp();\n\n        var r = create_renderer();\n        \n        var element = document.createElement(\"div\");\n        r.vectorRoot = element;\n\n        r.nodeFactory = function(id, type) {\n            var element = document.createElement(\"div\");\n            return element;\n        };\n        var g_Node = null;\n        var b_Node = null;\n        r.drawGeometryNode = function(node, geometry, style) {\n            g_Node = node;\n            return {node: node, complete: true};\n        };\n        r.redrawBackgroundNode = function(id, geometry, style, featureId) {\n            b_Node = r.nodeFactory();\n            b_Node.id = \"foo_background\";\n            element.appendChild(b_Node);\n        };\n\n        r.getNodeType = function(geometry, style) {\n            return \"div\";\n        };\n        var geometry = {\n            id: 'foo',\n            CLASS_NAME: 'bar',\n            getBounds: function() {return {bottom: 0}}\n        };\n        var style = {'backgroundGraphic': 'foo'};\n        var featureId = 'dude';\n        r.drawGeometry(geometry, style, featureId);\n        t.ok(g_Node.parentNode == element, \"node is correctly appended to root\");\n        t.ok(b_Node.parentNode == element, \"redrawBackgroundNode appended background node\");\n        t.eq(g_Node._featureId, 'dude', \"_featureId is correct\");\n        t.eq(g_Node._style.backgroundGraphic, \"foo\", \"_style is correct\");\n        t.eq(g_Node._geometryClass, 'bar', \"_geometryClass is correct\");\n\n        var returnNode = function(id) {\n        \treturn id == \"foo_background\" ? b_Node : g_Node;\n        }\n       \t\n        var _getElement = document.getElementById;\n        document.getElementById = returnNode;\n        OpenLayers.Util.getElement = returnNode;\n        \n        style = {'display':'none'};\n        r.drawGeometry(geometry, style, featureId);\n        t.ok(g_Node.parentNode != element, \"node is correctly removed\");\n        t.ok(b_Node.parentNode != element, \"background node correctly removed\")\n        \n        document.getElementById = _getElement;\n            \n        tearDown();\n    }\n\n    function test_Elements_drawGeometry_2(t) {\n        t.plan(8);\n        \n        setUp();\n        \n        var geometry = {\n            getBounds: function() {return {bottom: 0}}\n        }\n        \n        var r = create_renderer();\n        \n        var element = document.createElement(\"div\");\n        r.root = element;\n        \n        r.nodeFactory = function(id, type) {\n            var element = document.createElement(\"div\");\n            return element;\n        };\n        r.setStyle = function(node, style, options, geometry) {\n            return node;\n        };\n        \n        // point\n        var properDraw = false;\n        r.drawPoint = function(node, geometry) {\n            properDraw = true;\n            return {};\n        };\n        var point = OpenLayers.Util.applyDefaults({CLASS_NAME: 'OpenLayers.Geometry.Point'}, geometry);\n        style = true;\n        r.drawGeometry(point, style);\n        t.ok(properDraw, \"drawGeometry called drawPoint when passed a point\");\n\n        // line string\n        var properDraw = false;\n        r.drawLineString = function(g) {\n            properDraw = true;\n            return {};\n        };\n        var linestring = OpenLayers.Util.applyDefaults({id: \"foo\", CLASS_NAME: 'OpenLayers.Geometry.LineString'}, geometry);\n        style = true;\n        r.drawGeometry(linestring, style);\n        t.ok(properDraw, \"drawGeometry called drawLineString when passed a line string\");\n\n        // linear ring\n        var properDraw = false;\n        r.drawLinearRing = function(g) {\n            properDraw = true;\n            return {};\n        };\n        var linearring = OpenLayers.Util.applyDefaults({CLASS_NAME: 'OpenLayers.Geometry.LinearRing'}, geometry);\n        style = true;\n        r.drawGeometry(linearring, style);\n        t.ok(properDraw, \"drawGeometry called drawLinearRing when passed a linear ring\");\n\n        // polygon\n        var properDraw = false;\n        r.drawPolygon = function(g) {\n            properDraw = true;\n            return {};\n        };\n        var polygon = OpenLayers.Util.applyDefaults({CLASS_NAME: 'OpenLayers.Geometry.Polygon'}, geometry);\n        style = true;\n        r.drawGeometry(polygon, style);\n        t.ok(properDraw, \"drawGeometry called drawPolygon when passed a polygon\");\n\n        // rectangle\n        var properDraw = false;\n        r.drawRectangle = function(g) {\n            properDraw = true;\n            return {};\n        };\n        var rectangle = OpenLayers.Util.applyDefaults({CLASS_NAME: 'OpenLayers.Geometry.Rectangle'}, geometry);\n        style = true;\n        r.drawGeometry(rectangle, style);\n        t.ok(properDraw, \"drawGeometry called drawRectangle when passed a rectangle\");\n\n        // multi-point\n        var properDraw = false;\n        r.drawPoint = function(g) {\n            properDraw = true;\n            return {};\n        };\n        var multipoint = OpenLayers.Util.applyDefaults({\n            CLASS_NAME: 'OpenLayers.Geometry.MultiPoint',\n            components: [point]\n        }, geometry);\n        style = true;\n        r.drawGeometry(multipoint, style);\n        t.ok(properDraw, \"drawGeometry called drawPoint when passed a multi-point\");\n\n        // multi-linestring\n        var properDraw = false;\n        r.drawLineString = function(g) {\n            properDraw = true;\n            return {};\n        };\n        var multilinestring = OpenLayers.Util.applyDefaults({\n            CLASS_NAME: 'OpenLayers.Geometry.MultiLineString',\n            components: [linestring]\n        }, geometry);\n        style = true;\n        r.drawGeometry(multilinestring, style);\n        t.ok(properDraw, \"drawGeometry called drawLineString when passed a multi-linestring\");\n\n        // multi-polygon\n        var properDraw = false;\n        r.drawPolygon = function(g) {\n            properDraw = true;\n            return {};\n        };\n        var multipolygon = OpenLayers.Util.applyDefaults({\n            CLASS_NAME: 'OpenLayers.Geometry.MultiPolygon',\n            components: [polygon]\n        }, geometry);\n        style = true;\n        r.drawGeometry(multipolygon, style);\n        t.ok(properDraw, \"drawGeometry called drawPolygon when passed a multi-polygon\");\n      \n        tearDown();\n    }\n    \n    function test_Elements_getfeatureidfromevent(t) {\n        t.plan(2);\n        \n        var node = {\n            _featureId: 'foo'\n        };\n        var event = {\n            target: node\n        };\n        \n        var id = OpenLayers.Renderer.Elements.prototype.getFeatureIdFromEvent(event);\n        t.eq(id, 'foo', \"returned id is correct when event with target is passed\");\n        \n        var event = {\n            srcElement: node\n        };\n        \n        var id = OpenLayers.Renderer.Elements.prototype.getFeatureIdFromEvent(event);\n        t.eq(id, 'foo', \"returned id is correct when event with srcElement is passed\");\n    }\n    \n    function test_Elements_erasegeometry(t) {\n        t.plan(15);\n\n        var elements = {\n            'eraseGeometry': function(geometry) {\n                gErased.push(geometry);\n            }\n        };\n        \n        var geometry = {\n            'components': [{}, {}, {}]\n        };\n        \n      //multipoint\n        geometry.CLASS_NAME = \"OpenLayers.Geometry.MultiPoint\";\n        gErased = [];\n        OpenLayers.Renderer.Elements.prototype.eraseGeometry.apply(elements, [geometry]);\n        t.ok( (gErased[0] == geometry.components[0]) &&\n              (gErased[1] == geometry.components[1]) &&\n              (gErased[2] == geometry.components[2]), \"multipoint all components of geometry correctly erased.\");\n\n      //multilinestring\n        geometry.CLASS_NAME = \"OpenLayers.Geometry.MultiLineString\";\n        gErased = [];\n        OpenLayers.Renderer.Elements.prototype.eraseGeometry.apply(elements, [geometry]);\n        t.ok( (gErased[0] == geometry.components[0]) &&\n              (gErased[1] == geometry.components[1]) &&\n              (gErased[2] == geometry.components[2]), \"multilinestring all components of geometry correctly erased.\");\n      \n      //multipolygon\n        geometry.CLASS_NAME = \"OpenLayers.Geometry.MultiPolygon\";\n        gErased = [];\n        OpenLayers.Renderer.Elements.prototype.eraseGeometry.apply(elements, [geometry]);\n        t.ok( (gErased[0] == geometry.components[0]) &&\n              (gErased[1] == geometry.components[1]) &&\n              (gErased[2] == geometry.components[2]), \"multipolygon all components of geometry correctly erased.\");\n      \n      //collection\n        geometry.CLASS_NAME = \"OpenLayers.Geometry.Collection\";\n        gErased = [];\n        OpenLayers.Renderer.Elements.prototype.eraseGeometry.apply(elements, [geometry]);\n        t.ok( (gErased[0] == geometry.components[0]) &&\n              (gErased[1] == geometry.components[1]) &&\n              (gErased[2] == geometry.components[2]), \"collection all components of geometry correctly erased.\");\n        \n\n    // OTHERS\n    //\n        geometry.CLASS_NAME = {};\n\n        gElement = null;\n        gBackElement = null;\n\n        OpenLayers.Util._getElement = OpenLayers.Util.getElement;\n        OpenLayers.Util.getElement = function(id) {\n            var retVal = null;\n            if (id != null) {\n                var hasBack = (id.indexOf(elements.BACKGROUND_ID_SUFFIX) != -1);\n                retVal = hasBack ? gBackElement : gElement;\n            }\n            return retVal;\n        };\n\n      //element null\n        geometry.id = null;\n        OpenLayers.Renderer.Elements.prototype.eraseGeometry.apply(elements, [geometry]);\n        // (no tests here, just make sure it doesn't bomb)      \n      \n      //element.parentNode null\n        elements.BACKGROUND_ID_SUFFIX = 'BLAHBLAHBLAH';\n        geometry.id = \"foo\";        \n        gElement = {};\n        OpenLayers.Renderer.Elements.prototype.eraseGeometry.apply(elements, [geometry]);\n        // (no tests here, just make sure it doesn't bomb)      \n      \n      //valid element.parentNode, element.geometry\n        elements.indexer = {\n            'remove': function(elem) {\n                gIndexerRemoved = elem;\n            }\n        };\n\n        gElement = {\n            'geometry': {\n                'destroy': function() { \n                    t.ok(true, \"geometry destroyed\");\n                }\n            },\n            'parentNode': {\n                'removeChild': function(elem) {\n                    gElemRemoved = elem;\n                }\n            },\n            '_style' : {backgroundGraphic: \"foo\"}\n        };\n        gBackElement = {\n            'parentNode': {\n                'removeChild': function(elem) {\n                    gBackRemoved = elem;\n                }\n            }\n        };\n\n        gElemRemoved = gBackRemoved =  gIndexerRemoved = null;\n        OpenLayers.Renderer.Elements.prototype.eraseGeometry.apply(elements, [geometry]);\n        t.ok( (gElement.geometry == null), \"all normal: element's 'geometry' property nullified\");\n        t.ok( (gElemRemoved == gElement), \"all normal: main element properly removed from parent node\");\n        t.ok( (gBackRemoved == gBackElement), \"all normal: back element properly removed from parent node\");\n        t.ok( (gIndexerRemoved == gElement), \"all normal: main element properly removed from the indexer\");\n\n      //valid element.parentNode, no element.geometry, no bElem\n        gBackElement = null;\n        gElement.geometry = null;\n        gElemRemoved = gBackRemoved =  gIndexerRemoved = null;\n        OpenLayers.Renderer.Elements.prototype.eraseGeometry.apply(elements, [geometry]);\n        t.ok( (gElemRemoved == gElement), \"no bElem: main element properly removed from parent node\");\n        t.ok( (gBackRemoved == null), \"no bElem: back element not tried to remove from parent node when it doesn't exist\");\n        t.ok( (gIndexerRemoved == gElement), \"no bElem: main element properly removed from the indexer\");\n\n      //valid element.parentNode, no element.geometry, valid bElem, no bElem.parentNode \n        gBackElement = {};\n        gElemRemoved = gBackRemoved =  gIndexerRemoved = null;\n        OpenLayers.Renderer.Elements.prototype.eraseGeometry.apply(elements, [geometry]);\n        t.ok( (gElemRemoved == gElement), \"no bElem.parentNode: main element properly removed from parent node\");\n        t.ok( (gBackRemoved == null), \"no bElem.parentNode: back element not tried to remove from parent node when it has no parent node\");\n        t.ok( (gIndexerRemoved == gElement), \"no bElem.parentNode: main element properly removed from the indexer\");\n\n\n        OpenLayers.Util.getElement = OpenLayers.Util._getElement;\n    }\n    \n    function test_Elements_drawAndErase(t) {\n        t.plan(20);\n\n        setUp();\n\n        var r = create_renderer(null, {zIndexing: true});\n        var element = document.createElement(\"div\");\n        r.vectorRoot = element;\n        document.body.appendChild(element);\n\n        r.createNode = function(type, id) {\n            var element = document.createElement(\"div\");\n            element.id = id;\n            return element;\n        };\n        r.nodeTypeCompare = function() {return true};\n        r.setStyle = function(node, style, options, geometry) {\n            return node;\n        };\n        \n        var geometry = {\n            id: 'foo',\n            CLASS_NAME: 'bar',\n            getBounds: function() {return {bottom: 0}}\n        };\n        var style = {\n            graphicZIndex: 10\n        };\n        var featureId = 'foo';\n        r.drawGeometry(geometry, style, featureId);\n\n        function count(obj) {\n            var result = 0;\n            for (var i in obj) {\n                result++;\n            }\n            return result;\n        }\n\n        t.eq(element.childNodes.length, 1, \"root is correctly filled\");\n        t.eq(r.indexer.maxZIndex, 10, \"indexer.maxZIndex is correctly filled\");\n        t.eq(r.indexer.order.length, 1, \"indexer.order is correctly filled\");\n        t.eq(count(r.indexer.indices), 1, \"indexer.indices is correctly filled\");\n\n        r.eraseGeometry(geometry);\n\n        t.eq(element.childNodes.length, 0, \"root is correctly cleared\");\n        t.eq(r.indexer.maxZIndex, 0, \"indexer.maxZIndex is correctly reset\");\n        t.eq(r.indexer.order.length, 0, \"indexer.order is correctly reset\");\n        t.eq(count(r.indexer.indices), 0, \"indexer.indices is correctly reset\");\n\n        delete(style.graphicZIndex);\n        r.drawGeometry(geometry, style, featureId);\n\n        t.eq(element.childNodes.length, 1, \"root is correctly filled\");\n        t.eq(r.indexer.maxZIndex, 0, \"indexer.maxZIndex is correctly filled\");\n        t.eq(r.indexer.order.length, 1, \"indexer.order is correctly filled\");\n        t.eq(count(r.indexer.indices), 1, \"indexer.indices is correctly filled\");\n\n        r.clear();\n\n        t.eq(element.childNodes.length, 0, \"root is correctly cleared\");\n        t.eq(r.indexer.maxZIndex, 0, \"indexer.maxZIndex is correctly reset\");\n        t.eq(r.indexer.order.length, 0, \"indexer.order is correctly reset\");\n        t.eq(count(r.indexer.indices), 0, \"indexer.indices is correctly reset\");\n\n        style.graphicZIndex = 12;\n        r.drawGeometry(geometry, style, featureId);\n\n        t.eq(element.childNodes.length, 1, \"root is correctly filled\");\n        t.eq(r.indexer.maxZIndex, 12, \"indexer.maxZIndex is correctly filled\");\n        t.eq(r.indexer.order.length, 1, \"indexer.order is correctly filled\");\n        t.eq(count(r.indexer.indices), 1, \"indexer.indices is correctly filled\");\n\n        tearDown();\n    }\n\n    function test_Elements_moveRoot(t) {\n        t.plan(2);\n        setUp();\n        var r1 = create_renderer();\n        var r2 = create_renderer();\n        r1.moveRoot(r2);\n        t.xml_eq(r1.root.parentNode, r2.root.parentNode, \"root moved successfully\");\n        r1.moveRoot(r1);\n        t.xml_eq(r1.root.parentNode, r1.rendererRoot, \"root moved back successfully\");\n        tearDown();        \n    }\n\n    function test_Elements_drawGeometry_3(t) {\n        t.plan(2);\n\n        setUp();\n\n        var r = create_renderer();\n        \n        var element = document.createElement(\"div\");\n        r.vectorRoot = element;\n\n        r.nodeFactory = function(id, type) {\n            return document.createElement(\"div\");\n        };\n        var g_Node = null;\n        var b_Node = null;\n        r.drawGeometryNode = function(node, geometry, style) {\n            g_Node = node;\n            return {node: node, complete: true};\n        };\n        r.redrawBackgroundNode = function(id, geometry, style, featureId) {\n            b_Node = r.nodeFactory();\n            b_Node.id = \"foo_background\";\n            element.appendChild(b_Node);\n        };\n\n        r.getNodeType = function(geometry, style) {\n            return \"div\";\n        };\n        var geometry = {\n            id: 'foo',\n            CLASS_NAME: 'bar',\n            getBounds: function() {return {bottom: 0}}\n        };\n        var style = {'backgroundGraphic': 'foo'};\n        var featureId = 'dude';\n        r.drawGeometry(geometry, style, featureId);\n        t.ok(b_Node.parentNode == element, \"redrawBackgroundNode appended background node\");\n\n        var returnNode = function(id) {\n        \treturn id == \"foo_background\" ? b_Node : g_Node;\n        }\n       \t\n        var _getElement = document.getElementById;\n        document.getElementById = returnNode;\n        OpenLayers.Util.getElement = returnNode;\n\n        style = {};\n        r.drawGeometry(geometry, style, featureId);\n        t.ok(b_Node.parentNode != element, \"background node correctly removed\")\n            \n        document.getElementById = _getElement;\n\n        tearDown();\n    }\n\n    function test_setExtent(t) {\n        t.plan(10);\n        setUp();\n        var resolution = 1;\n        var r = create_renderer();\n        r.map = {\n            getMaxExtent: function() {\n                return new OpenLayers.Bounds(-180,-90,180,90);\n            },\n            getExtent: function() {\n                return r.extent;\n            },\n            getResolution: function() {\n                return resolution;\n            },\n            baseLayer: {wrapDateLine: true}\n        }\n        \n        r.setExtent(new OpenLayers.Bounds(179, -1, 182, 1), true);\n        t.eq(r.rightOfDateLine, true, \"on the right side of the dateline\");\n        t.eq(r.xOffset, r.map.getMaxExtent().getWidth(), \"correct xOffset\");\n        r.setExtent(new OpenLayers.Bounds(179.5, -1, 182.5, 1), false);\n        t.eq(r.rightOfDateLine, true, \"still on the right side of the dateline\");\n        t.eq(r.xOffset, r.map.getMaxExtent().getWidth(), \"still correct xOffset\");\n        resolution = 2;\n        r.setExtent(new OpenLayers.Bounds(178, -2, 184, 2), true);\n        t.eq(r.rightOfDateLine, true, \"still on the right side of the dateline\");\n        t.eq(r.xOffset, r.map.getMaxExtent().getWidth() / resolution, \"xOffset adjusted for new resolution\");\n        r.setExtent(new OpenLayers.Bounds(-184, -2, 178, 2), false);\n        t.eq(r.rightOfDateLine, false, \"on the left side of the dateline\");\n        t.eq(r.xOffset, 0, \"no xOffset\");\n        r.setExtent(new OpenLayers.Bounds(178, -2, 184, 2), true);\n        t.eq(r.rightOfDateLine, true, \"back on the right side of the dateline\");\n        t.eq(r.xOffset, r.map.getMaxExtent().getWidth() / resolution, \"correct xOffset\");\n        \n        tearDown();\n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Renderer/SVG.html",
    "content": "<html>\n<head>\n<script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    var geometry = null, node = null;\n    \n    function test_SVG_constructor(t) {\n        if (!OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(1);\n        var r = new OpenLayers.Renderer.SVG(document.body);\n        t.ok(r instanceof OpenLayers.Renderer.SVG, \"new OpenLayers.Renderer.SVG returns SVG object\" );\n    }\n    \n    function test_SVG_destroy(t) {\n        if (!OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(1);\n        \n        var g_Destroy = false;\n        \n        OpenLayers.Renderer.Elements.prototype._destroy = \n            OpenLayers.Renderer.Elements.prototype.destroy;\n            \n        OpenLayers.Renderer.prototype.destroy = function() {\n            g_Destroy = true;\n        }\n        \n        var r = new OpenLayers.Renderer.SVG(document.body);\n        r.destroy();\n        \n        t.eq(g_Destroy, true, \"OpenLayers.Renderer.Elements.destroy() called\");\n        \n        OpenLayers.Renderer.prototype.destroy = \n            OpenLayers.Renderer.prototype._destroy;\n    }\n    \n    function test_SVG_setextent(t) {\n        if (!OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(5);\n        \n        OpenLayers.Renderer.Elements.prototype._setExtent =\n            OpenLayers.Renderer.Elements.prototype.setExtent;\n        \n        var g_SetExtent = false;\n        OpenLayers.Renderer.Elements.prototype.setExtent = function() {\n            g_SetExtent = true;\n        }\n                \n        var r = new OpenLayers.Renderer.SVG(document.body);\n        r.setSize(new OpenLayers.Size(4,4));\n        r.map = {\n            getResolution: function() {\n                return 0.5;\n            }\n        }\n        \n        var extent = new OpenLayers.Bounds(1,2,3,4);\n        r.setExtent(extent);\n        \n        t.eq(g_SetExtent, true, \"Elements.setExtent() called\");\n        \n        t.eq(r.left, -2, \"left is correct\");\n        t.eq(r.top, 8, \"top is correct\");\n        \n        t.eq(r.rendererRoot.getAttributeNS(null, \"viewBox\"), \"0 0 4 4\", \"rendererRoot viewBox is correct\");\n        \n        // test extent changes\n        var extent = new OpenLayers.Bounds(4,3,2,1);\n        r.setExtent(extent);\n        var el = r.createNode(\"g\");\n        el.setAttributeNS(null, \"transform\", \"translate(-6,-6)\");\n        t.eq(r.root.getAttributeNS(null, \"transform\"), el.getAttributeNS(null, \"transform\"), \"rendererRoot viewBox is correct after a new setExtent\");\n\n        OpenLayers.Renderer.Elements.prototype.setExtent =\n            OpenLayers.Renderer.Elements.prototype._setExtent;\n    }\n    \n    function test_SVG_setsize(t) {\n        if (!OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(2);\n                \n        var r = new OpenLayers.Renderer.SVG(document.body);\n        \n        var size = new OpenLayers.Size(1,2);\n        r.setSize(size);\n        t.eq(r.rendererRoot.getAttributeNS(null, \"width\"), size.w.toString(), \"width is correct\");\n        t.eq(r.rendererRoot.getAttributeNS(null, \"height\"), size.h.toString(), \"height is correct\");\n    }\n    \n    function test_SVG_drawpoint(t) {\n        if (!OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n    \n        t.plan(1);\n\n        var r = new OpenLayers.Renderer.SVG(document.body);\n        \n        var properDraw = false;\n        var g_Radius = null;\n        r.drawCircle = function(n, g, r) {\n            properDraw = true;\n            g_Radius = 1;\n        }\n        r.drawPoint();\n        \n        t.ok(properDraw && g_Radius == 1, \"drawPoint called drawCircle with radius set to 1\");\n    }\n    \n    function test_SVG_drawcircle(t) {\n        if (!OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(5);\n        \n        var r = new OpenLayers.Renderer.SVG(document.body);\n        r.resolution = 0.5;\n        r.left = 0;\n        r.top = 0;\n        \n        var node = document.createElement('div');\n        \n        var geometry = {\n            x: 1,\n            y: 2\n        }\n        \n        r.drawCircle(node, geometry, 3);\n        \n        t.eq(node.getAttributeNS(null, 'cx'), '2', \"cx is correct\");\n        t.eq(node.getAttributeNS(null, 'cy'), '-4', \"cy is correct\");\n        t.eq(node.getAttributeNS(null, 'r'), '3', \"r is correct\");\n       \n        // #1274: out of bound node fails when first added\n        var geometry = {\n            x: 10000000,\n            y: 200000000,\n            CLASS_NAME: \"OpenLayers.Geometry.Point\",\n            id: \"foo\",\n            getBounds: function() {return {bottom: 0}}\n        }\n        node.id = geometry.id;\n        r.root.appendChild(node);\n\n        var drawCircleCalled = false;\n        r.drawCircle = function() {\n            drawCircleCalled = true;\n            return OpenLayers.Renderer.SVG.prototype.drawCircle.apply(r, arguments);\n        }\n        \n        r.drawGeometry(geometry, {pointRadius: 3}, \"blah_4000\");\n        t.eq(drawCircleCalled, true, \"drawCircle called on drawGeometry for a point geometry.\")\n        t.ok(node.parentNode != r.root, \"circle will not be drawn when coordinates are outside the valid range\");\n    }\n    \n    function test_SVG_drawlinestring(t) {\n        if (!OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(2);\n        \n        var r = new OpenLayers.Renderer.SVG(document.body);\n        \n        var node = document.createElement('div');\n        \n        var geometry = {\n            components: \"foo\"\n        }\n        g_GetString = false;\n        g_Components = null;\n        r.getComponentsString = function(c) {\n            g_GetString = true;\n            g_Components = c;\n            return {path: \"bar\", complete: true};\n        }\n        \n        r.drawLineString(node, geometry);\n        \n        t.ok(g_GetString && g_Components == \"foo\", \"getComponentString is called with valid arguments\");\n        t.eq(node.getAttributeNS(null, \"points\"), \"bar\", \"points attribute is correct\");\n    }\n    \n    function test_SVG_drawlinearring(t) {\n        if (!OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(2);\n        \n        var r = new OpenLayers.Renderer.SVG(document.body);\n        \n        var node = document.createElement('div');\n        \n        var geometry = {\n            components: \"foo\"\n        }\n        g_GetString = false;\n        g_Components = null;\n        r.getComponentsString = function(c) {\n            g_GetString = true;\n            g_Components = c;\n            return {path: \"bar\", complete: true};\n        }\n        \n        r.drawLinearRing(node, geometry);\n        \n        t.ok(g_GetString, \"getComponentString is called with valid arguments\");\n        t.eq(node.getAttributeNS(null, \"points\"), \"bar\", \"points attribute is correct\");\n    }\n\n    function test_SVG_drawpolygon(t) {\n        if (!OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(4);\n        \n        var r = new OpenLayers.Renderer.SVG(document.body);\n        \n        var node = document.createElement('div');\n        \n        var linearRings = [{\n            components: [\"foo\"]\n        },{\n            components: [\"bar\"]\n        }]\n        \n        var geometry = {\n            components: linearRings\n        }\n        g_GetString = false;\n        r.getShortString = function(c) {\n            g_GetString = true;\n            return c;\n        }\n        \n        r.drawPolygon(node, geometry);\n        \n        t.ok(g_GetString, \"getShortString is called\");\n        t.eq(node.getAttributeNS(null, \"d\"), \" M foo M bar z\", \"d attribute is correctly set\");\n        t.eq(node.getAttributeNS(null, \"fill-rule\"), \"evenodd\", \"fill-rule attribute is correctly set\");\n        \n        r.getShortString = function(c) {\n            return false;\n        }\n        t.eq(r.drawPolygon(node, geometry), false, \"drawPolygon returns false if one linearRing cannot be drawn\");\n    }\n\n    function test_SVG_drawrectangle(t) {\n        if (!OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(4);\n        \n        var r = new OpenLayers.Renderer.SVG(document.body);\n        r.resolution = 0.5;\n        r.left = 0;\n        r.top = 0;\n        \n        var node = document.createElement('div');\n        \n        var geometry = {\n            x: 1,\n            y: 2,\n            width: 3,\n            height: 4\n        }\n        \n        r.drawRectangle(node, geometry);\n        \n        t.eq(node.getAttributeNS(null, \"x\"), \"2\", \"x attribute is correctly set\");\n        t.eq(node.getAttributeNS(null, \"y\"), \"-4\", \"y attribute is correctly set\");\n        t.eq(node.getAttributeNS(null, \"width\"), \"6\", \"width attribute is correctly set\");\n        t.eq(node.getAttributeNS(null, \"height\"), \"8\", \"height attribute is correctly set\");\n    }\n    \n    function test_SVG_getcomponentsstring(t) {\n        if (!OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(1);\n        \n        var components = ['foo', 'bar'];\n        \n        OpenLayers.Renderer.SVG.prototype._getShortString = \n            OpenLayers.Renderer.SVG.prototype.getShortString;\n            \n        OpenLayers.Renderer.SVG.prototype.getShortString = function(p) {\n            return p;\n        };\n        \n        var string = OpenLayers.Renderer.SVG.prototype.getComponentsString(components).path;\n        t.eq(string, \"foo,bar\", \"returned string is correct\");\n        \n        OpenLayers.Renderer.SVG.prototype.getShortString = \n            OpenLayers.Renderer.SVG.prototype._getShortString;\n    }\n    \n    \n    \n    function test_SVG_getshortstring(t) {\n        if (!OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(1);\n        \n        var r = new OpenLayers.Renderer.SVG(document.body);\n        r.resolution = 0.5;\n        r.left = 0;\n        r.top = 0;\n        \n        var point = {\n            x: 1,\n            y: 2\n        };\n        \n        var string = r.getShortString(point);\n        t.eq(string, \"2,-4\", \"returned string is correct\");\n    }\n        \n    function test_svg_importsymbol(t) {\n        if (!OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n\n        t.plan(2);\n        \n        var r = new OpenLayers.Renderer.SVG(document.body);\n\n        r.importSymbol(\"square\");\n\n        var polygon = document.getElementById(r.container.id + \"_defs\").firstChild.firstChild;\n        \n        var pass = false;\n        for (var i = 0; i < polygon.points.numberOfItems; i++) {\n            var p = polygon.points.getItem(i);\n            pass = p.x === OpenLayers.Renderer.symbol.square[2*i] && \n                   p.y === OpenLayers.Renderer.symbol.square[2*i+1];\n            if (!pass) {\n                break;\n            }\n        }\n        t.ok(pass, \"Square symbol rendered correctly\");\n        t.ok(r.symbolMetrics[\"-square\"], \"Symbol metrics cached correctly.\");\n    }\n        \n    function test_svg_dashstyle(t) {\n        if (!OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n\n        t.plan(5);\n        \n        var r = new OpenLayers.Renderer.SVG(document.body);\n\n        t.eq(r.dashStyle({strokeWidth: 1, strokeDashstyle: \"dot\"}, 1), \"1,4\", \"dot dasharray created correctly\");\n        t.eq(r.dashStyle({strokeWidth: 1, strokeDashstyle: \"dash\"}, 1), \"4,4\", \"dash dasharray created correctly\");\n        t.eq(r.dashStyle({strokeWidth: 1, strokeDashstyle: \"longdash\"}, 1), \"8,4\", \"longdash dasharray created correctly\");\n        t.eq(r.dashStyle({strokeWidth: 1, strokeDashstyle: \"dashdot\"}, 1), \"4,4,1,4\", \"dashdot dasharray created correctly\");\n        t.eq(r.dashStyle({strokeWidth: 1, strokeDashstyle: \"longdashdot\"}, 1), \"8,4,1,4\", \"dashdot dasharray created correctly\");\n    }\n    \n    function test_svg_clipline(t) {\n        if (!OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(3);\n        \n        var r = new OpenLayers.Renderer.SVG(document.body);\n        r.setSize(new OpenLayers.Size(0, 0));\n        r.map = {\n            getResolution: function() {\n                return 0.5;\n            }\n        }\n        r.setExtent(new OpenLayers.Bounds(0, 0, 0, 0));\n\n        var node = document.createElement('div');\n\n        var geometry = new OpenLayers.Geometry.LineString([\n            new OpenLayers.Geometry.Point(0, -5000),\n            new OpenLayers.Geometry.Point(10000, 0),\n            new OpenLayers.Geometry.Point(0, 5000)\n        ]);\n        r.drawLineString(node, geometry);\n        t.eq(node.getAttribute(\"points\"), \"0,10000,15000,2500,15000,-2500,0,-10000\", \"Line with 3 points correctly clipped at inValidRange bounds\");\n        \n        geometry = new OpenLayers.Geometry.LineString([\n            new OpenLayers.Geometry.Point(0, -5000),\n            new OpenLayers.Geometry.Point(10000, 0)\n        ]);\n        r.drawLineString(node, geometry);\n        t.eq(node.getAttribute(\"points\"), \"0,10000,15000,2500\", \"2-point line with 2nd point outside range correctly clipped at inValidRange bounds\");\n\n        var geometry = new OpenLayers.Geometry.LineString([\n            new OpenLayers.Geometry.Point(10000, 0),\n            new OpenLayers.Geometry.Point(0, 5000)\n        ]);\n        r.drawLineString(node, geometry);\n        t.eq(node.getAttribute(\"points\"), \"15000,-2500,0,-10000\", \"2-point line with 1st point outside range correctly clipped at inValidRange bounds\");\n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Renderer/VML.html",
    "content": "<html>\n<head>\n<script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    var geometry = null, node = null;\n\n    function test_VML_constructor(t) {\n        if (!OpenLayers.Renderer.VML.prototype.supported() || OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(1);\n        var r = new OpenLayers.Renderer.VML(document.body);\n        t.ok(r instanceof OpenLayers.Renderer.VML, \"new OpenLayers.Renderer.VML returns VML object\" );\n    }\n    \n    function test_VML_destroy(t) {\n        if (!OpenLayers.Renderer.VML.prototype.supported() || OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(1);\n        \n        var g_Destroy = false;\n        \n        OpenLayers.Renderer.Elements.prototype._destroy = \n            OpenLayers.Renderer.Elements.prototype.destroy;\n            \n        OpenLayers.Renderer.prototype.destroy = function() {\n            g_Destroy = true;\n        }\n        \n        var r = new OpenLayers.Renderer.VML(document.body);\n        r.destroy();\n        \n        t.eq(g_Destroy, true, \"OpenLayers.Renderer.Elements.destroy() called\");\n        \n        OpenLayers.Renderer.prototype.destroy = \n            OpenLayers.Renderer.prototype._destroy;\n    }\n    \n    function test_VML_setextent(t) {\n        if (!OpenLayers.Renderer.VML.prototype.supported() || OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(4);\n        \n        OpenLayers.Renderer.Elements.prototype._setExtent =\n            OpenLayers.Renderer.Elements.prototype.setExtent;\n        \n        var g_SetExtent = false;\n        OpenLayers.Renderer.Elements.prototype.setExtent = function() {\n            g_SetExtent = true;\n        }\n                \n        var r = new OpenLayers.Renderer.VML(document.body);\n        r.setSize(new OpenLayers.Size(4,4));\n        r.map = {\n            getResolution: function() {\n                return 0.5;\n            }\n        }\n        \n        var extent = new OpenLayers.Bounds(1,2,3,4);\n        r.setExtent(extent);\n        \n        t.eq(g_SetExtent, true, \"Elements.setExtent() called\");\n        \n        t.ok(r.root.coordorigin == \"0,0\", \"coordorigin is correct\");\n        t.ok(r.root.coordsize == \"4,4\", \"coordsize is correct\");\n        t.eq(r.offset, {x:2, y:4}, \"offset is correct\");\n        \n        OpenLayers.Renderer.Elements.prototype.setExtent =\n            OpenLayers.Renderer.Elements.prototype._setExtent;\n    }\n\n    function test_VML_setsize(t) {\n        if (!OpenLayers.Renderer.VML.prototype.supported() || OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(4);\n                \n        var r = new OpenLayers.Renderer.VML(document.body);\n        \n        var size = new OpenLayers.Size(1,2);\n        r.setSize(size);\n        t.eq(r.rendererRoot.style.width, \"1px\", \"rendererRoot width is correct\");\n        t.eq(r.rendererRoot.style.height, \"2px\", \"rendererRoot height is correct\");\n        \n        t.eq(r.root.style.width, \"1px\", \"root width is correct\");\n        t.eq(r.root.style.height, \"2px\", \"root height is correct\");\n    }\n    \n    function test_VML_drawText(t) {\n        if (!OpenLayers.Renderer.VML.prototype.supported() || OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(2);\n\n        var r = new OpenLayers.Renderer.VML(document.body);\n        r.offset = {x: 0, y: 0};\n        \n        r.LABEL_ID_SUFFIX = \"\";\n        r.getResolution = function() {\n            return 1;\n        };\n\n        var style = {\n            label: \"myText\",\n            fontColor: \"blue\"\n        }\n        \n        r.drawText(\"feature1\", style, new OpenLayers.Geometry.Point(1,1));\n        \n        var textbox = document.getElementById(\"feature1_textbox\");\n        \n        t.eq(textbox.innerText, style.label, \"label set correctly\");\n        t.eq(textbox.style.color, style.fontColor, \"font color of label set correctly\");\n    }\n\n    function test_VML_drawpoint(t) {\n        if (!OpenLayers.Renderer.VML.prototype.supported() || OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n    \n        t.plan(1);\n\n        var r = new OpenLayers.Renderer.VML(document.body);\n        \n        var properDraw = false;\n        var g_Radius = null;\n        r.drawCircle = function(n, g, r) {\n            properDraw = true;\n            g_Radius = 1;\n        }\n        r.drawPoint();\n        \n        t.ok(properDraw && g_Radius == 1, \"drawPoint called drawCircle with radius set to 1\");\n    }\n\n    function test_VML_drawcircle(t) {\n        if (!OpenLayers.Renderer.VML.prototype.supported() || OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(4);\n        \n        var r = new OpenLayers.Renderer.VML(document.body);\n        r.offset = {x: 0, y: 0};\n        r.resolution = 0.5;\n        \n        var node = document.createElement('div');\n        \n        var geometry = {\n            x: 1,\n            y: 2\n        }\n        \n        var radius = 3;\n        r.drawCircle(node, geometry, radius);\n        \n        t.eq(node.style.left, '-1px', \"left is correct\");\n        t.eq(node.style.top, '1px', \"top is correct\");\n        t.eq(node.style.width, (2 * radius) + \"px\", \"width is correct\");\n        t.eq(node.style.height, (2 * radius) + \"px\", \"height is correct\");\n    }\n    \n    function test_VML_drawGraphic(t) {\n        if (!OpenLayers.Renderer.VML.prototype.supported() || OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(6);\n        \n        var r = new OpenLayers.Renderer.VML(document.body);\n        r.offset = {x: 0, y: 0};\n        r.resolution = 1;\n        \n        var node = document.createElement('div');\n        node.id = \"test\"\n        node._geometryClass = \"OpenLayers.Geometry.Point\";\n        \n        var geometry = {\n            x: 1,\n            y: 2\n        }\n        \n        var style = {\n            externalGraphic: \"foo.png\",\n            graphicWidth: 7,\n            graphicHeight: 10\n        }\n        \n        r.drawGeometryNode(node, geometry, style);\n\n        t.eq(node.childNodes[0].id, \"test_fill\", \"fill child node correctly created\");\n        t.eq(node.style.left, \"-2px\", \"x of insertion point with calculated xOffset correct\");\n        t.eq(node.style.top, \"-3px\", \"y of insertion point with calculated yOffset correct\");\n        \n        style.rotation = 90;\n        \n        r.drawGeometryNode(node, geometry, style);\n        \n        t.eq(node.childNodes[1].id, \"test_image\", \"image child node correctly created\");\n        t.eq(node.style.left, \"-3px\", \"x of insertion point of rotated image correct\");\n        t.eq(node.style.top, \"-4px\", \"y of insertion point of rotated image correct\");\n    }\n\n    function test_VML_drawlinestring(t) {\n        if (!OpenLayers.Renderer.VML.prototype.supported() || OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(1);\n        \n        var r = new OpenLayers.Renderer.VML(document.body);\n        \n        g_DrawLine = false;\n        r.drawLine = function(c) {\n            g_DrawLine = true;\n        }\n        \n        r.drawLineString(node, geometry);\n        \n        t.ok(g_DrawLine, \"drawLine is called\");\n    }\n    \n    function test_VML_drawlinearring(t) {\n        if (!OpenLayers.Renderer.VML.prototype.supported() || OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(1);\n        \n        var r = new OpenLayers.Renderer.VML(document.body);\n        \n        g_DrawLine = false;\n        r.drawLine = function(c) {\n            g_DrawLine = true;\n        }\n        \n        r.drawLinearRing(node, geometry);\n        \n        t.ok(g_DrawLine, \"drawLine is called\");\n    }\n\n    function test_VML_drawline(t) {\n        if (!OpenLayers.Renderer.VML.prototype.supported() || OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(8);\n        \n        var r = new OpenLayers.Renderer.VML(document.body);\n        r.offset = {x: 0, y: 0};\n        r.resolution = 0.5;\n        \n        var node = document.createElement('div');\n        \n        var geometry = {\n            components: [{\n                x: 1,\n                y: 2\n            },{\n                x: 3,\n                y: 4\n            }],\n            getBounds: function() {\n                return new OpenLayers.Bounds(5,6,7,8);\n            }\n        };\n        \n        r.drawLine(node, geometry, true);\n        t.ok(node.path.indexOf(\"x\") != -1, \"path attribute is correct when passed closeLine = true\");\n        \n        \n        r.drawLine(node, geometry, false);\n        t.eq(node.path, \"m 2,4 l  6,8 l  e\", \"path attribute is correct\");\n        t.eq(node.style.left, \"10px\", \"node.style.left is correct\");\n        t.eq(node.style.top, \"16px\", \"node.style.top is correct\");\n        t.eq(node.style.width, \"4px\", \"node.style.width is correct\");\n        t.eq(node.style.height, \"4px\", \"node.style.height is correct\");\n        t.eq(node.coordorigin, \"10 16\", \"node.coordorigin is correct\");\n        t.eq(node.coordsize, \"4 4\", \"node.coordsize is correct\");\n    }\n    \n    function test_VML_drawpolygon(t) {\n        if (!OpenLayers.Renderer.VML.prototype.supported() || OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(3);\n        \n        var r = new OpenLayers.Renderer.VML(document.body);\n        r.offset = {x: 0, y: 0};\n        r.resolution = 0.5;\n        \n        g_SetNodeDimension = false;\n        r.setNodeDimension = function(){\n            g_SetNodeDimension = true;\n        };\n        \n        var node = document.createElement('div');\n        \n        var geometry = OpenLayers.Geometry.fromWKT(\n            \"POLYGON((1 2, 3 4), (5 6, 7 8))\"\n        );\n        r.drawPolygon(node, geometry, true);\n        t.ok(g_SetNodeDimension, \"setNodeDimension is called\");\n        t.eq(node.path, \"m 2,4 l 6,8 2,4 x m 10,12 l 14,16 10,12 e\", \"path attribute is correct - inner ring has no area and is not closed\");\n\n        geometry.components[1].addComponent(new OpenLayers.Geometry.Point(8, 7));\n        r.drawPolygon(node, geometry, true);\n        t.eq(node.path, \"m 2,4 l 6,8 2,4 x m 10,12 l 14,16 16,14 10,12 x e\", \"path attribute is correct - inner ring has an area and is closed\");        \n    }\n    \n    function test_VML_drawrectangle(t) {\n        if (!OpenLayers.Renderer.VML.prototype.supported() || OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(4);\n        \n        var r = new OpenLayers.Renderer.VML(document.body);\n        r.offset = {x: 0, y: 0};\n        r.resolution = 0.5;\n        \n        var node = document.createElement('div');\n        \n        var geometry = {\n            x: 1,\n            y: 2,\n            width: 3,\n            height: 4\n        }\n        \n        r.drawRectangle(node, geometry);\n        \n        t.eq(node.style.left, \"2px\", \"node.style.left is correct\");\n        t.eq(node.style.top, \"4px\", \"node.style.top is correct\");\n        t.eq(node.style.width, \"6px\", \"node.style.width is correct\");\n        t.eq(node.style.height, \"8px\", \"node.style.height is correct\");\n    }\n    \n    function test_vml_getnodetype(t) {\n        if (!OpenLayers.Renderer.VML.prototype.supported() || OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n\n        t.plan(1);\n        \n        var r = new OpenLayers.Renderer.VML(document.body);\n\n        var g = {CLASS_NAME: \"OpenLayers.Geometry.Point\"}\n        var s = {graphicName: \"square\"};\n        \n        t.eq(r.getNodeType(g, s), \"olv:shape\", \"Correct node type for well known symbols\");\n    }\n\n    function test_vml_importsymbol(t) {\n        if (!OpenLayers.Renderer.VML.prototype.supported() || OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n\n        t.plan(4);\n        \n        OpenLayers.Renderer.symbol.rect1 = [0,0, 10,0, 10,4, 0,4, 0,0];\n        OpenLayers.Renderer.symbol.rect2 = [0,0, 4,0, 4,10, 0,10, 0,0];\n\n        var r = new OpenLayers.Renderer.VML(document.body);\n\n        var cache = r.importSymbol(\"square\");\n\n        t.eq(cache.path, \"m 0 0 l 0 1 1 1 1 0 0 0 x e\", \"Square symbol rendered correctly\");\n        t.ok(r.symbolCache[\"-square\"], \"Symbol has been cached correctly.\");\n        \n        cache = r.importSymbol(\"rect1\");\n        t.eq(cache.bottom, -3, \"coordorigin bottom of landscape symbol set to -3 to move topmost part to the bottom (we are flipping y!)\");\n        \n        cache = r.importSymbol(\"rect2\");\n        t.eq(cache.left, -3, \"coordorigin left of portrait symbol set to -3 to move leftmost part to the right\");\n        \n        delete OpenLayers.Renderer.symbol.rect1;\n        delete OpenLayers.Renderer.symbol.rect2;\n        \n    }\n    \n    function test_vml_dashstyle(t) {\n        if (!OpenLayers.Renderer.VML.prototype.supported() || OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(5);\n        \n        var r = new OpenLayers.Renderer.VML(document.body);\n        \n        t.eq(r.dashStyle({strokeDashstyle: \"1 4\"}), \"dot\", \"dot pattern recognized correctly.\");\n        t.eq(r.dashStyle({strokeDashstyle: \"4 4\"}), \"dash\", \"dash pattern recognized correctly.\");\n        t.eq(r.dashStyle({strokeDashstyle: \"8 4\"}), \"longdash\", \"longdash pattern recognized correctly.\");\n        t.eq(r.dashStyle({strokeDashstyle: \"4 4 1 4\"}), \"dashdot\", \"dashdot pattern recognized correctly.\");\n        t.eq(r.dashStyle({strokeDashstyle: \"8 4 1 4\"}), \"longdashdot\", \"longdashdot pattern recognized correctly.\");\n    }\n    \n    function test_vml_moveRoot(t) {\n        if (!OpenLayers.Renderer.VML.prototype.supported() || OpenLayers.Renderer.SVG.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        t.plan(2);\n        \n        var map = new OpenLayers.Map(\"map\");\n        var l1 = new OpenLayers.Layer.Vector(\"vector\");\n        map.addLayer(l1);\n        var l2 = new OpenLayers.Layer.Vector.RootContainer(\"rootcontainer\", {layers: [l1]});\n        \n        var clear = l1.renderer.clear;\n        l1.renderer.clear = function() {\n            // this should be called twice, once when l2 is added to the map,\n            // and once when removed from the map.\n            t.ok(true, \"Clearing original layer\");\n        };\n        map.addLayer(l2);\n        map.removeLayer(l2);\n        l1.renderer.clear = clear;\n        \n        map.removeLayer(l1);\n    }\n        \n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Renderer.html",
    "content": "<html>\n<head>\n<script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_Renderer_constructor(t) {\n        t.plan(2);\n        var el = document.body;\n        el.id = \"foo\";\n        var r = new OpenLayers.Renderer(el.id);\n        \n        t.ok(r instanceof OpenLayers.Renderer, \"new OpenLayers.Renderer returns Renderer object\" );\n        t.ok(r.container == el, \"renderer container is correctly set\");\n    }\n    \n    function test_Renderer_supported(t) {\n        t.plan(1);\n        \n        var r = new OpenLayers.Renderer();\n        t.eq(r.supported(), false, \"supported returns false by default\");\n    }\n    \n    function test_Renderer_setextent(t) {\n        t.plan(2);\n        \n        var r = new OpenLayers.Renderer();\n        r.map = {};\n        var extent = new OpenLayers.Bounds(1,2,3,4);\n        r.resolution = 1;\n        r.setExtent(extent, true);\n        t.ok(r.extent.equals(extent), \"extent is correctly set\");\n        t.eq(r.resolution, null, \"resolution nullified\");\n    }\n    \n    function test_Renderer_setsize(t) {\n        t.plan(2);\n        \n        var r = new OpenLayers.Renderer();\n        var size = new OpenLayers.Size(1,2);\n        r.resolution = 1;\n        r.setSize(size);\n        t.ok(r.size.equals(size), \"size is correctly set\");\n        t.eq(r.resolution, null, \"resolution nullified\");\n    }\n    \n    function test_Renderer_getresolution(t) {\n        t.plan(2);\n        \n        var r = new OpenLayers.Renderer();\n        var map = new OpenLayers.Map(\"map\");\n        r.map = map;\n        var resolution = r.getResolution();\n        t.eq(resolution, map.getResolution(), \"resolution matches the map resolution\");\n        t.eq(r.resolution, resolution, \"resolution is correctly set\");\n    }\n    \n    function test_calculateFeatureDx(t) {\n        t.plan(4);\n        var r = new OpenLayers.Renderer();\n        r.extent = new OpenLayers.Bounds(177, -2, 183, 2);\n        var worldBounds = new OpenLayers.Bounds(-180,-90,180,90);\n        r.calculateFeatureDx(new OpenLayers.Bounds(179,-1,181,1), worldBounds);\n        t.eq(r.featureDx, 0, \"no offset for feature inside extent\");\n        r.calculateFeatureDx(new OpenLayers.Bounds(-181,-1,-179,1), worldBounds);\n        t.eq(r.featureDx, -360, \"negative offset for feature on other end of world\");\n        r.calculateFeatureDx(new OpenLayers.Bounds(359,-1,361,1), worldBounds);\n        t.eq(r.featureDx, 360, \"positive offset for feature that is one world away\");\n        r.calculateFeatureDx(new OpenLayers.Bounds(719,-1,721,1), worldBounds);\n        t.eq(r.featureDx, 720, \"correct offset for feature that is two worlds away\");\n    }\n\n    function test_Renderer_destroy(t) {\n        t.plan(5);\n\n        var r = new OpenLayers.Renderer();\n        r.container = document.createElement(\"div\");\n        r.extent = new OpenLayers.Bounds(1,2,3,4);\n        r.size = new OpenLayers.Size(1,2);\n        r.resolution = 1;\n        r.map = {};\n\n        r.destroy();\n\n        t.eq(r.container, null, \"container nullified\");\n        t.eq(r.extent, null, \"extent nullified\");\n        t.eq(r.size, null, \"size nullified\");\n        t.eq(r.resolution, null, \"resolution nullified\");\n        t.eq(r.map, null, \"map nullified\");\n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Request/XMLHttpRequest.html",
    "content": "<html>\n<head>\n    <script src=\"../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n        function test_constructor(t) {\n            t.plan(1);\n            t.ok(new OpenLayers.Request.XMLHttpRequest(),\n                 \"constructor didn't fail and we trust the code is well tested in OpenLayers.Request methods\");\n        }\n        function test_readyState(t) {\n        // Verify compliance of the standard (a part) See: http://www.w3.org/TR/XMLHttpRequest/\n        t.plan(9);\n        // Case 1: Request-A: open & abort\n            var requestA = new OpenLayers.Request.XMLHttpRequest();\n            //requestA.onreadystatechange = function() {};\n            t.eq(requestA.readyState, 0, \"Request-A: readyState after new is 0-UNSENT\");\n            requestA.open(\"GET\", \".\", true);\n            t.eq(requestA.readyState, 1, \"Request-A: readyState after open is 1-OPENED\");\n            requestA.abort();\n            t.eq(requestA.readyState, 0, \"Request-A: readyState after abort is 0-UNSENT\");\n\n        // Case 2: Request-B: open & send\n            var requestB = new OpenLayers.Request.XMLHttpRequest();\n            requestB.onreadystatechange = function() {\n                if (requestB.readyState == 4) {\n                    t.ok(true, \"Request-B: triggered the event onreadystatechange when 4-DONE\");\n                }\n            };\n            t.eq(requestB.readyState, 0, \"Request-B: readyState after new is 0-UNSENT\");\n            requestB.open(\"GET\", \".\", true);\n            t.eq(requestB.readyState, 1, \"Request-B: readyState after open is 1-OPENED\");\n            requestB.send();\n\n        // Case 3: Request-C: open, send & abort\n            var requestC = new OpenLayers.Request.XMLHttpRequest();\n            requestC.onreadystatechange = function() {\n                if (requestC.readyState == 4) {\n                    t.fail(\"Request-C: triggered the event onreadystatechange when 4-DONE after abort\");\n                }\n            };\n            t.eq(requestC.readyState, 0, \"Request-C: readyState after new is 0-UNSENT\");\n            requestC.open(\"GET\", \".\", true);\n            t.eq(requestC.readyState, 1, \"Request-C: readyState after open is 1-OPENED\");\n            requestC.send();\n            requestC.abort();\n            t.eq(requestC.readyState, 0, \"Request-C: readyState after abort is 0-UNSENT\");\n\n        // delay destroy\n            t.delay_call( \n                2, function() {\n                    // to await the end of requestB and requestC\n                }\n            );\n        }\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Request.html",
    "content": "<html>\n<head>\n    <script src=\"OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    function setup() {\n        window._xhr = OpenLayers.Request.XMLHttpRequest;\n        var anon = new Function();\n        OpenLayers.Request.XMLHttpRequest = function() {};\n        OpenLayers.Request.XMLHttpRequest.prototype = {\n            open: anon,\n            setRequestHeader: anon,\n            send: anon\n        };\n        OpenLayers.Request.XMLHttpRequest.DONE = 4;\n    }\n    function teardown() {\n        OpenLayers.Request.XMLHttpRequest = window._xhr;\n    }\n\n    function test_defaultHeaders(t) {\n        setup();\n        t.plan(2);\n        var config = {\n            headers: {\n                x: 'y'\n            }\n        };\n        OpenLayers.Request.DEFAULT_CONFIG.headers = {\n            foo: 'bar'\n        };\n        var proto = OpenLayers.Request.XMLHttpRequest.prototype;\n        var issue = OpenLayers.Function.bind(OpenLayers.Request.issue,\n                                             OpenLayers.Request);\n\n        var headers = {};\n        var _setRequestHeader = proto.setRequestHeader;\n        proto.setRequestHeader = function(key, value) {\n            headers[key] = value;\n        };\n        request = issue(config);\n        t.eq(headers.foo, 'bar', \"Header from DEFAULT_CONFIG set correctly\");\n        t.eq(headers.x, 'y', \"Header from config set correctly\");\n        proto.setRequestHeader = _setRequestHeader;\n        OpenLayers.Request.DEFAULT_CONFIG.headers = {};\n        teardown();\n    }\n \n    function test_issue(t) {\n        setup();\n\n        t.plan(25);\n        var request, config;\n        var proto = OpenLayers.Request.XMLHttpRequest.prototype;\n        var issue = OpenLayers.Function.bind(OpenLayers.Request.issue,\n                                             OpenLayers.Request);\n\n        // test that issue returns a new XMLHttpRequest - 1 test\n        request = issue();\n        t.ok(request instanceof OpenLayers.Request.XMLHttpRequest,\n             \"returns an XMLHttpRequest instance\");\n        \n        // test that issue calls xhr.open with correct args from config - 5 tests\n        var _open = proto.open;\n        config = {\n            method: \"foo\",\n            url: \"http://nowhere\",\n            async: \"bar\",\n            user: \"uncle\",\n            password: \"sam\"\n        };\n        proto.open = function(method, url, async, user, password) {\n            t.eq(method, config.method, \"open called with correct method\");\n            t.eq(url, config.url, \"open called with correct url\");\n            t.eq(async, config.async, \"open called with correct async\");\n            t.eq(user, config.user, \"open called with correct user\");\n            t.eq(password, config.password, \"open called with correct password\");\n        };\n        request = issue(config);\n        \n        // test that params are serialized as query string - 1 test\n        config = {\n            method: \"GET\",\n            url: \"http://example.com/\",\n            params: {\"foo\": \"bar\"}\n        };\n        proto.open = function(method, url, async, user, password) {\n            t.eq(url, config.url + \"?foo=bar\", \"params serialized as query string\");\n        };\n        request = issue(config);\n        \n        // test that empty params object doesn't produce query string - 1 test\n        config = {\n            method: \"GET\",\n            url: \"http://example.com/\",\n            params: {}\n        };\n        proto.open = function(method, url, async, user, password) {\n            t.eq(url, config.url, \"empty params doesn't produce query string\");\n        }\n        request = issue(config);\n        \n        // test that query string doesn't get two ? separators\n        config = {\n            method: \"GET\",\n            url: \"http://example.com/?existing=query\",\n            params: {\"foo\": \"bar\"}\n        };\n        proto.open = function(method, url, async, user, password) {\n            t.eq(url, config.url + \"&foo=bar\", \"existing query string gets extended with &\");\n        }\n        request = issue(config);\n        \n        // test that query string doesn't get ? followed by &\n        config = {\n            method: \"GET\",\n            url: \"http://example.com/service?\",\n            params: {\"foo\": \"bar\"}\n        };\n        proto.open = function(method, url, async, user, password) {\n            t.eq(url, config.url + \"foo=bar\", \"existing query string ending with ? gets extended without &\");\n        }\n        request = issue(config);\n        \n        // reset open method\n        proto.open = _open;\n        \n        // test that headers are correctly set - 6 tests\n        var _setRequestHeader = proto.setRequestHeader;\n        config = {\n            headers: {\n                foo: \"bar\",\n                chicken: \"soup\",\n                // This checks whether the autoadded 'X-Requested-With'-header\n                // can be overridden, even though the given key here is spelled\n                // in lowercase. \n                'x-requested-with': 'humpty'\n            }\n        };\n        // we also track how often setRequestHeader is being called, it should\n        // be called once for every header, even with the above defined\n        // custom 'x-requested-with' header which we usually autoadd.\n        // If the numbers match, we make sure to not send duplicate headers like\n        //   x-requested-with: humpty         AND\n        //   X-Requested-With: XMLHttpRequest\n        var actualSetHeaderCnt = 0;\n        var expectedSetHeaderCnt = 3; // and not four!\n        proto.setRequestHeader = function(key, value) {\n            actualSetHeaderCnt++;\n            t.ok(key in config.headers, \"setRequestHeader called with key: \" + key);\n            t.eq(value, config.headers[key], \"setRequestHeader called with correct value: \" + value);\n        };\n        request = issue(config);\n        \n        t.eq(actualSetHeaderCnt, expectedSetHeaderCnt, 'A custom \"x-requested-with\" header overrides the default \"X-Requested-With\" header.');\n\n        proto.setRequestHeader = _setRequestHeader;\n        \n        // test that callback is called (no scope) - 1 test\n        var unbound = function(request) {\n            t.ok(request instanceof OpenLayers.Request.XMLHttpRequest,\n                 \"unbound callback called with xhr instance\");\n        }\n        config = {\n            callback: unbound\n        };\n        request = issue(config);\n        request.readyState = OpenLayers.Request.XMLHttpRequest.DONE;\n        request.onreadystatechange();\n\n        // test that callback is called (with scope) - 2 tests\n        var obj = {};\n        var bound = function(request) {\n            t.ok(this === obj, \"bound callback has correct scope\");\n            t.ok(request instanceof OpenLayers.Request.XMLHttpRequest,\n                 \"bound callback called with xhr instance\");\n        }\n        config = {\n            callback: bound,\n            scope: obj\n        };\n        request = issue(config);\n        request.readyState = 4;\n        request.onreadystatechange();\n        \n        // test that optional success callback is only called with 200s and\n        // failure is only called with non-200s\n        var _send = proto.send;\n        proto.send = function() {};\n        \n        config = {\n            success: function(req) {\n                t.ok(!req.status || (req.status >= 200 && req.status < 300),\n                     \"success callback called with \" + req.status + \" status\");\n            },\n            failure: function(req) {\n                t.ok(req.status && (req.status < 200 || req.status >= 300),\n                     \"failure callback called with \" + req.status + \" status\");\n            }\n        };\n        request = issue(config);\n        request.readyState = 4;\n        \n        // mock up status 200 (1 test)\n        request.status = 200;\n        request.onreadystatechange();\n        \n        // mock up status 299 (1 test)\n        request.status = 299;\n        request.onreadystatechange();\n        \n        // mock up status 100 (1 test)\n        request.status = 100;\n        request.onreadystatechange();\n\n        // mock up status 300 (1 test)\n        request.status = 300;\n        request.onreadystatechange();\n        \n        // mock up a status null (1 test)\n        request.status = null;\n        request.onreadystatechange();\n\n        proto.send = _send;\n\n        teardown();\n    }\n    \n    function test_delayed_send(t) {\n        t.plan(1);\n        var proto = OpenLayers.Request.XMLHttpRequest.prototype;\n        var _send = proto.send;\n        \n        // test that send is called with data - 1 test\n        var config = {\n            method: \"PUT\",\n            data: \"bling\"\n        };\n        var got = {};\n        proto.send = function(data) {\n            got.data = data;\n        }\n        OpenLayers.Request.issue(config);\n        \n        t.delay_call(1, function() {\n            t.eq(got.data, config.data, \"proper data sent\");\n            proto.send = _send;\n        });        \n        \n    }\n    \n    function test_GET(t) {\n        t.plan(1);\n        var _issue = OpenLayers.Request.issue;\n        OpenLayers.Request.issue = function(config) {\n            t.eq(config.method, \"GET\", \"calls issue with correct method\");\n        }\n        OpenLayers.Request.GET();\n        OpenLayers.Request.issue = _issue;\n    }\n    function test_POST(t) {\n        t.plan(1);\n        var _issue = OpenLayers.Request.issue;\n        OpenLayers.Request.issue = function(config) {\n            t.eq(config.method, \"POST\", \"calls issue with correct method\");\n        }\n        OpenLayers.Request.POST();\n        OpenLayers.Request.issue = _issue;\n    }\n    function test_PUT(t) {\n        t.plan(1);\n        var _issue = OpenLayers.Request.issue;\n        OpenLayers.Request.issue = function(config) {\n            t.eq(config.method, \"PUT\", \"calls issue with correct method\");\n        }\n        OpenLayers.Request.PUT();\n        OpenLayers.Request.issue = _issue;\n    }\n    function test_DELETE(t) {\n        t.plan(1);\n        var _issue = OpenLayers.Request.issue;\n        OpenLayers.Request.issue = function(config) {\n            t.eq(config.method, \"DELETE\", \"calls issue with correct method\");\n        }\n        OpenLayers.Request.DELETE();\n        OpenLayers.Request.issue = _issue;\n    }\n    function test_HEAD(t) {\n        t.plan(1);\n        var _issue = OpenLayers.Request.issue;\n        OpenLayers.Request.issue = function(config) {\n            t.eq(config.method, \"HEAD\", \"calls issue with correct method\");\n        }\n        OpenLayers.Request.HEAD();\n        OpenLayers.Request.issue = _issue;\n    }\n    function test_OPTIONS(t) {\n        t.plan(1);\n        var _issue = OpenLayers.Request.issue;\n        OpenLayers.Request.issue = function(config) {\n            t.eq(config.method, \"OPTIONS\", \"calls issue with correct method\");\n        }\n        OpenLayers.Request.OPTIONS();\n        OpenLayers.Request.issue = _issue;\n    }\n    \n    function test_events_success(t) {\n        \n        t.plan(5);\n\n        var events = [];\n        function listener(event) {\n            events.push(event);\n        }\n        \n        // set up event listeners\n        OpenLayers.Request.events.on({\n            complete: listener,\n            success: listener,\n            failure: listener\n        });\n\n        // issue a request that succeeds\n        OpenLayers.Request.GET({\n            url: \".\", params: {bar: \"baz\"}, async: false\n        });\n        t.eq(events.length, 2, \"two events logged\");\n        t.eq(events[0].type, \"complete\", \"first event is complete\");\n        t.eq(events[1].type, \"success\", \"second event is success\");\n        t.ok(events[1].config, \"success listener sent config\");\n        t.eq(events[1].requestUrl, \".?bar=baz\", \"success listener sent config.url\");\n\n        // remove event listeners\n        OpenLayers.Request.events.un({\n            complete: listener,\n            success: listener,\n            failure: listener\n        });\n        \n    }\n\n    function test_events_failure(t) {\n        \n        t.plan(5);\n\n        var events = [];\n        function listener(event) {\n            events.push(event);\n        }\n        \n        // set up event listeners\n        OpenLayers.Request.events.on({\n            complete: listener,\n            success: listener,\n            failure: listener\n        });\n\n        // issue a request that succeeds\n        OpenLayers.Request.GET({\n            url: \"foo\", params: {bar: \"baz\"}, async: false\n        });\n        t.eq(events.length, 2, \"two events logged\");\n        t.eq(events[0].type, \"complete\", \"first event is complete\");\n        t.eq(events[1].type, \"failure\", \"second event is failure\");\n        t.ok(events[1].config, \"failure listener sent config\");\n        t.eq(events[1].requestUrl, \"foo?bar=baz\", \"failure listener sent requestUrl\");\n\n        // remove event listeners\n        OpenLayers.Request.events.un({\n            complete: listener,\n            success: listener,\n            failure: listener\n        });\n        \n    }\n\n    function test_ProxyHost(t) {\n        t.plan(5);\n\n        /*\n         * Setup\n         */\n\n        setup();\n\n        var expectedURL;\n\n        var _ProxyHost = OpenLayers.ProxyHost;\n\n        var proto = OpenLayers.Request.XMLHttpRequest.prototype;\n        var _open = proto.open;\n        var log = [];\n        var port;\n        proto.open = function(method, url, async, user, password) {\n            log.push(url);\n        };\n\n        /*\n         * Test\n         */\n\n        // 2 tests\n        log = [];\n        OpenLayers.ProxyHost = \"http://fooproxy/?url=\";\n        expectedURL = \"http://fooproxy/?url=http%3A%2F%2Fbar%3Fk1%3Dv1%26k2%3Dv2\";        \n        OpenLayers.Request.GET({url: \"http://bar?k1=v1&k2=v2\"});\n        t.eq(log.length, 1, \"[1] XHR.open called once\");\n        t.eq(log[0], expectedURL, \"[1] the URL used for XHR is correct (\" + log[0] + \")\");\n        \n        // 1 test\n        log = [];\n        OpenLayers.ProxyHost = \"http://fooproxy/?url=\";\n        port = window.location.port ? ':'+window.location.port : '';\n        expectedURL = window.location.protocol+\"//\"+window.location.hostname+port+\"/service\";\n        OpenLayers.Request.GET({url: expectedURL});\n        t.eq(log[0], expectedURL, \"[2] proxy is not used when requesting the same server\");\n        \n        // 2 tests\n        log = [];\n        OpenLayers.ProxyHost = function(url) {\n            var p = OpenLayers.Util.getParameters(url);\n            var p = OpenLayers.Util.getParameterString(p);\n            return \"http://barproxy/?\" + p;\n        };\n        expectedURL = \"http://barproxy/?k1=v1&k2=v2\";\n        OpenLayers.Request.GET({url: \"http://bar?k1=v1&k2=v2\"});\n        t.eq(log.length, 1, \"[3] XHR.open called once\");\n        t.eq(log[0], expectedURL, \"[3] the URL used for XHR is correct (\" + log[0] + \")\");\n\n        /*\n         * Teardown\n         */\n\n        OpenLayers.Request.XMLHttpRequest.prototype.open = _open;\n        OpenLayers.ProxyHost = _ProxyHost;\n        teardown();\n    }\n\n    function test_abort(t) {\n\n        t.plan(0);\n\n        var sendCalled;\n\n        // set up\n\n        var _open = OpenLayers.Request.XMLHttpRequest.prototype.open;\n        OpenLayers.Request.XMLHttpRequest.prototype.open = function() {\n            this.readyState = OpenLayers.Request.XMLHttpRequest.OPENED;\n        };\n\n        var _setRequestHeader = OpenLayers.Request.XMLHttpRequest.prototype.setRequestHeader;\n        OpenLayers.Request.XMLHttpRequest.prototype.setRequestHeader = function() {};\n\n        var _send = OpenLayers.Request.XMLHttpRequest.prototype.send;\n        OpenLayers.Request.XMLHttpRequest.prototype.send = function() {\n            sendCalled = true;\n        };\n\n        // test\n\n        sendCalled = false;\n        OpenLayers.Request.issue().abort();\n\n        t.delay_call(0.5, function() {\n            if (sendCalled) {\n                t.fail(\"Send should not be called because request is aborted\");\n            }\n\n            // tear down\n            OpenLayers.Request.XMLHttpRequest.prototype.open = _open;\n            OpenLayers.Request.XMLHttpRequest.prototype.setRequestHeader = _setRequestHeader;\n            OpenLayers.Request.XMLHttpRequest.prototype.send = _send;\n        });\n    }\n\n    function test_abort2(t) {\n        t.plan(0);\n        var fail = false;\n        OpenLayers.Request.XMLHttpRequest.onsend = function(args) {\n            fail = true;\n        }\n        t.delay_call(0.5, function() {\n            if (fail === true) {\n                t.fail(\"Send should not be called because request is aborted\");\n            }\n            OpenLayers.Request.XMLHttpRequest.onsend = null;\n        });\n        var req = OpenLayers.Request.GET();\n        req.abort();\n    }\n    \n    function test_XRequestedWithHeaderAutoadded(t) {\n        t.plan( 2 );\n        \n        var headerSet = false;\n        var headerGot = '';\n        var headerExpected = 'XMLHttpRequest';\n        \n        // save to be able to restore later\n        var _setRequestHeader = OpenLayers.Request.XMLHttpRequest.prototype.setRequestHeader;\n        \n        OpenLayers.Request.XMLHttpRequest.prototype.setRequestHeader = function(field, value) {\n            if (field === 'X-Requested-With') {\n                headerSet = true;\n                headerGot = value;\n            }\n        };\n        \n        var req = OpenLayers.Request.issue({\n            url: location.href,\n            async: false\n        });\n                \n        t.ok( headerSet, 'We call the method \"setRequestHeader\" to set a \"X-Requested-With\"-header' );\n        t.eq( headerGot, headerExpected,  'The \"X-Requested-With\"-header is set to \"' + headerExpected + '\" as expected.' );\n        \n        // restore old setRequestHeader\n        OpenLayers.Request.XMLHttpRequest.prototype.setRequestHeader = _setRequestHeader;\n    }\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Rule.html",
    "content": "<html> \n<head> \n    <script src=\"OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_Rule_constructor(t) { \n        t.plan(3); \n         \n        var options = {'foo': 'bar'}; \n        var rule = new OpenLayers.Rule(options); \n        t.ok(rule instanceof OpenLayers.Rule, \n             \"new OpenLayers.Rule returns object\" ); \n        t.eq(rule.foo, \"bar\", \"constructor sets options correctly\"); \n        t.eq(typeof rule.evaluate, \"function\", \"rule has an evaluate function\"); \n    }\n    \n    function test_Rule_getContext(t) { \n        t.plan(2);\n        var rule, options;\n        \n        var feature = {\n            attributes: {\n                'dude': 'hello'\n            },\n            'foobar': 'world'\n        }\n        \n        rule = new OpenLayers.Rule();\n        var context = rule.getContext(feature);\n        t.eq(context.dude, \"hello\", \"value returned by getContext is correct\"\n            + \" if no context is specified\"); \n        \n        var options = {\n            context: function(feature){\n                return feature;\n            }\n        };\n        rule = new OpenLayers.Rule(options);\n        var context = rule.getContext(feature);\n        t.eq(context.foobar, \"world\", \"value returned by getContext is correct\"\n            + \" if a context is given in constructor options\"); \n    }\n    \n    function test_clone(t) {\n        \n        t.plan(9);\n        \n        var rule = new OpenLayers.Rule({\n            name: \"test rule\",\n            minScaleDenominator: 10,\n            maxScaleDenominator: 20,\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                property: \"prop\",\n                value: \"value\"\n            }),\n            symbolizer: {\n                fillColor: \"black\"\n            },\n            context: {\n                foo: \"bar\"\n            }\n        });\n        var clone = rule.clone();\n        t.eq(clone.name, \"test rule\", \"name copied\");\n        t.eq(clone.minScaleDenominator, 10, \"minScaleDenominator copied\");\n        t.eq(clone.filter.type, OpenLayers.Filter.Comparison.EQUAL_TO, \"clone has correct filter type\");\n        \n        // modify original\n        rule.filter.property = \"new\";\n        rule.symbolizer.fillColor = \"white\";\n        rule.context.foo = \"baz\";\n        \n        // confirm that clone didn't change\n        t.eq(clone.filter.property, \"prop\", \"clone has clone of filter\");\n        t.eq(clone.symbolizer.fillColor, \"black\", \"clone has clone of symbolizer\");\n        t.eq(clone.context.foo, \"bar\", \"clone has clone of context\");\n        \n        // confirm that ids are different\n        t.ok(clone.id !== rule.id, \"clone has different id\");\n        \n        rule.destroy();\n        clone.destroy();\n\n        // test multiple symbolizers\n        rule = new OpenLayers.Rule({\n            name: \"test rule\",\n            minScaleDenominator: 10,\n            maxScaleDenominator: 20,\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                property: \"prop\",\n                value: \"value\"\n            }),\n            symbolizers: [\n                new OpenLayers.Symbolizer.Line({\n                    strokeColor: \"black\"\n                })\n            ]\n        });\n        clone = rule.clone();\n\n        t.eq(clone.symbolizers.length, 1, \"clone has one symbolizer\");\n        t.ok(clone.symbolizers[0] !== rule.symbolizers[0], \"clone has different symbolizers than original\");\n        \n        clone.destroy();\n        rule.destroy();\n        \n    }\n\n    function test_Rule_destroy(t) {\n        t.plan(1);\n        \n        var rule = new OpenLayers.Rule();\n        rule.destroy();\n        t.eq(rule.symbolizer, null, \"symbolizer hash nulled properly\");\n    }\n\n    </script> \n</head> \n<body> \n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/SingleFile1.html",
    "content": "<html>\n<head>\n    <script src=\"some/OpenLayers/path/OpenLayers.js\"></script>\n    <script src=\"../lib/OpenLayers/SingleFile.js\"></script>\n    <script type=\"text/javascript\">\n        function test_OpenLayers(t) {\n            t.plan(1);\n            t.eq(OpenLayers._getScriptLocation(), \"some/OpenLayers/path/\",\n                 \"Script location correctly detected (OpenLayers.js).\");\n        }\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/SingleFile2.html",
    "content": "<html>\n<head>\n    <script src=\"some/OpenLayers/path/OpenLayers.light.js\"></script>\n    <script src=\"../lib/OpenLayers/SingleFile.js\"></script>\n    <script type=\"text/javascript\">\n        function test_OpenLayers(t) {\n            t.plan(1);\n            t.eq(OpenLayers._getScriptLocation(), \"some/OpenLayers/path/\",\n                 \"Script location correctly detected (OpenLayers.light.js).\");\n        }\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/SingleFile3.html",
    "content": "<html>\n<head>\n    <script src=\"some/OpenLayers/path/OpenLayers.light.debug.js\"></script>\n    <script src=\"../lib/OpenLayers/SingleFile.js\"></script>\n    <script type=\"text/javascript\">\n        function test_OpenLayers(t) {\n            t.plan(1);\n            t.eq(OpenLayers._getScriptLocation(), \"some/OpenLayers/path/\",\n                 \"Script location correctly detected (OpenLayers.light.debug.js).\");\n        }\n    </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Strategy/BBOX.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(1);\n\n        var ratio = 4;\n\n        var s = new OpenLayers.Strategy.BBOX({ratio: ratio});\n        t.eq(s.ratio, ratio, \"ctor sets ratio\");\n    }\n\n    function test_activate(t) {\n        t.plan(5);\n\n        var l = new OpenLayers.Layer.Vector();\n        var s = new OpenLayers.Strategy.BBOX();\n        s.setLayer(l);\n\n        t.eq(s.active, false, \"not active after construction\");\n\n        var activated = s.activate();\n        t.eq(activated, true, \"activate returns true\");\n        t.eq(s.active, true, \"activated after activate\");\n        t.ok(l.events.listeners[\"moveend\"][0].obj == s &&\n             l.events.listeners[\"moveend\"][0].func == s.update,\n             \"activates registers moveend listener\");\n        t.ok(l.events.listeners[\"refresh\"][0].obj == s &&\n             l.events.listeners[\"refresh\"][0].func == s.update,\n             \"activates registers refresh listener\");\n    }\n\n    function test_update(t) {\n        t.plan(7);\n\n        // Create a dummy layer that can act as the map base layer.\n        // This will be unnecessary if #1921 is addressed (allowing\n        // map to have different projection than base layer).\n        var dummy = new OpenLayers.Layer(null, {isBaseLayer: true});\n\n        var strategy = new OpenLayers.Strategy.BBOX({\n            ratio: 1 // makes for easier comparison to map bounds\n        });\n        var log = [];\n        var layer = new OpenLayers.Layer.Vector(null, {\n            isBaseLayer: true,\n            protocol: new OpenLayers.Protocol({abort: function(response) { log.push(response); }}),\n            strategies: [strategy]\n        });\n\n        // create a map with the layers and a center\n        var map = new OpenLayers.Map(\"map\", {zoomMethod: null});\n        map.addLayers([dummy, layer]);\n        map.zoomToMaxExtent();\n        \n        /**\n         * The setCenter call above should set strategy bounds.  I *think* this\n         * issue is captured in http://trac.openlayers.org/ticket/1835.\n         * For now, I'm going to force an update on the strategy.  This line\n         * should be removed when the issue(s) described in #1835 are addressed.\n         */\n        strategy.update({force: true});\n        strategy.response = {};\n        strategy.update({force: true});\n        t.eq(log.length, 1, \"Response aborted\");\n        log = [];\n        strategy.update({force: true});\n        strategy.update({force: true, noAbort: true}); \n        t.eq(log.length, 0, \"Response not aborted when noAbort is true\");\n\n        // test that the strategy bounds were set\n        t.ok(map.getExtent().equals(strategy.bounds), \"[set center] bounds set to map extent\");\n        \n        // zoom and test that bounds are not reset\n        var old = strategy.bounds.clone();\n        map.zoomIn();\n        t.ok(strategy.bounds.equals(old), \"[zoom in] bounds not reset\");\n        \n        // force update and check that bounds change\n        strategy.update({force: true});\n        t.ok(!strategy.bounds.equals(old), \"[force update] bounds changed\");\n        t.ok(strategy.bounds.equals(map.getExtent()), \"[force update] bounds set to map extent\");\n        \n        // change the layer projection to confirm strategy uses same\n        layer.projection = new OpenLayers.Projection(\"EPSG:900913\");\n        strategy.update({force: true});\n        var from = map.getProjectionObject();\n        var to = layer.projection;\n        \n        var strategyBounds = strategy.bounds,\n            mapExtent = map.getExtent().transform(from, to),\n            // we don't use bounds::toString because we might run into \n            // precision issues\n            precision = 7,\n            strategyBoundsGot = [\n                strategyBounds.left.toFixed( precision ),\n                strategyBounds.bottom.toFixed( precision ),\n                strategyBounds.right.toFixed( precision ),\n                strategyBounds.top.toFixed( precision )\n            ].join(','),\n            mapExtentExpected = [\n                mapExtent.left.toFixed( precision ),\n                mapExtent.bottom.toFixed( precision ),\n                mapExtent.right.toFixed( precision ),\n                mapExtent.top.toFixed( precision )\n            ].join(',');\n        t.eq(strategyBoundsGot, mapExtentExpected, \n            \"[force update different proj] bounds transformed\");\n    }\n    \n    function test_events(t) {\n        \n        t.plan(7);\n\n        var log = [];\n\n        var response = new OpenLayers.Protocol.Response();\n\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector(null, {\n            strategies: [new OpenLayers.Strategy.BBOX()],\n            protocol: new OpenLayers.Protocol({\n                read: function(config) {\n                    config.callback.call(config.scope, response);\n                }\n            }),\n            isBaseLayer: true,\n            eventListeners: {\n                loadstart: function(event) {\n                    log.push(event);\n                },\n                loadend: function(event) {\n                    log.push(event);\n                }\n            }            \n        });\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n\n        t.eq(log.length, 2, \"2 events logged\");\n        t.eq(log[0].type, \"loadstart\", \"loadstart first\");\n        t.ok(log[0].filter.type === OpenLayers.Filter.Spatial.BBOX, \"loadstart includes filter used\");\n        t.eq(log[1].type, \"loadend\", \"loadend second\");\n        t.ok(log[1].response == response, \"loadend includes response\");\n        \n        var calls = [];\n        layer.protocol.read = function(obj) {\n            calls.push(obj);\n        }\n        layer.refresh({force: true, whee: 'chicken'});\n\n        t.eq(calls.length, 1, \"1 call to read\");\n        t.eq(calls[0].whee, \"chicken\", \"properties passed to read\");\n\n        map.destroy();\n        \n    }\n\n    function test_triggerRead(t) {\n        t.plan(4);\n\n        var s = new OpenLayers.Strategy.BBOX();\n\n        var filter = {\"fake\": \"filter\"};\n\n        s.createFilter = function() {\n            return filter;\n        };\n        s.response = {\"fake\": \"response\"};\n        \n        var log = {};\n\n        var protocol = new OpenLayers.Protocol({\n            read: function(options) {\n                log.options = options;\n            },\n            abort: function(response) {\n                log.abort = response.fake;\n            }\n        });\n        \n        var layer = new OpenLayers.Layer.Vector(null, {\n            strategies: [s],\n            protocol: protocol,\n            isBaseLayer: true\n        });\n        var map = new OpenLayers.Map(\"map\");\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        \n        t.ok(log.options.filter == filter,\n                \"protocol read called with correct filter\");\n        t.ok(log.options.callback == s.merge,\n                \"protocol read called with correct callback\");\n        t.ok(log.options.scope == s,\n                \"protocol read called with correct scope\");\n        t.eq(log.abort, \"response\",\n                \"protocol abort called with correct response\");\n\n        map.destroy();\n\n    }\n    \n    function test_resFactor(t) {\n        t.plan(2);\n        \n        var map = new OpenLayers.Map(\"map\", {zoomMethod: null});\n        var bbox = new OpenLayers.Strategy.BBOX();\n        var fakeProtocol = new OpenLayers.Protocol({\n            'read': function() { \n                t.ok(true, \"read called once without resfactor\"); \n            }\n        });\n        var layer = new OpenLayers.Layer.Vector(\"test\", {\n            strategies: [bbox],\n            protocol: fakeProtocol,\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n        map.zoomIn();\n        \n        fakeProtocol.read = function() { \n            t.ok(\"read called again on zooming with resFactor: 1\");\n        }\n        bbox.resFactor = 1;\n        map.zoomIn();\n        \n    }\n\n    function test_createFilter(t) {\n        t.plan(3);\n\n        var s = new OpenLayers.Strategy.BBOX();\n\n        var f;\n\n        // 2 test\n        s.setLayer({});\n        f = s.createFilter();\n        t.ok(f.CLASS_NAME.search(/^OpenLayers.Filter.Spatial/) != -1,\n             \"createFilter returns a spatial filter object\");\n        t.eq(f.type, OpenLayers.Filter.Spatial.BBOX,\n             \"createFilter returns a BBOX-typed filter\");\n\n        // 1 test\n        s.setLayer({filter: {fake: \"filter\"}});\n        f = s.createFilter();\n        t.ok(f.CLASS_NAME.search(/^OpenLayers.Filter.Logical/) != -1,\n             \"createFilter returns a logical filter object\");\n    }\n\n    function test_merge(t) {\n        t.plan(4);\n        \n        var strategy = new OpenLayers.Strategy.BBOX();\n                \n        // create map with default projection\n        var map = new OpenLayers.Map(\"map\");\n        \n        // create layer with custom projection\n        var layer = new OpenLayers.Layer.Vector(null, {\n            isBaseLayer: true,\n            strategies: [strategy],\n            protocol: new OpenLayers.Protocol(),\n            projection: new OpenLayers.Projection(\"EPSG:900913\")\n        });\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        \n        // create some features\n        var geometries = [\n            new OpenLayers.Geometry.Point(100, 200),\n            new OpenLayers.Geometry.Point(1000, 2000)\n        ];\n        var features = [\n            new OpenLayers.Feature.Vector(geometries[0].clone()),\n            new OpenLayers.Feature.Vector(geometries[1].clone())\n        ];\n\n        // call merge with a mocked up response\n        strategy.merge({features: features, success: OpenLayers.Function.True});\n        \n        // test that feature geometries have been transformed to map projection\n        var from = layer.projection;\n        var to = map.getProjectionObject();\n        t.geom_eq(layer.features[0].geometry, features[0].geometry.transform(from, to), \"[different proj] feature 0 geometry transformed\");\n        t.geom_eq(layer.features[1].geometry, features[1].geometry.transform(from, to), \"[different proj] feature 1 geometry transformed\");\n        \n        // same as above but with same map/layer projection\n        layer.destroyFeatures();\n        layer.projection = map.getProjectionObject();\n        \n        features = [\n            new OpenLayers.Feature.Vector(geometries[0].clone()),\n            new OpenLayers.Feature.Vector(geometries[1].clone())\n        ];\n        \n        // call merge again with mocked up response\n        strategy.merge({features: features, success: OpenLayers.Function.True});\n\n        // test that feature geometries have not been transformed\n        t.geom_eq(layer.features[0].geometry, features[0].geometry, \"[same proj] feature 0 geometry not transformed\");\n        t.geom_eq(layer.features[1].geometry, features[1].geometry, \"[same proj] feature 1 geometry not transformed\");\n        \n    }\n\n    // Test fix for Ticket #3142\n    function test_layerLoadedAfterBeingAdded(t) {\n        t.plan(3);\n\n        var dummy = new OpenLayers.Layer(null, {isBaseLayer: true});\n\n        var strategy = new OpenLayers.Strategy.BBOX({\n            ratio: 1 // makes for easier comparison to map bounds\n        });\n        var layer = new OpenLayers.Layer.Vector(null, {\n            protocol: new OpenLayers.Protocol(),\n            strategies: [strategy]\n        });\n\n        // Make sure to test the case of a vector layer needing to be \n        // reprojected while the map is not yet centered\n        var layerReproject = new OpenLayers.Layer.Vector(null, {\n            protocol: new OpenLayers.Protocol(),\n            strategies: [new OpenLayers.Strategy.BBOX()],\n            projection: 'EPSG:900913'\n        });\n\n        // Make sure that layers that are not in range don't request data\n        var layerOutOfRange = new OpenLayers.Layer.Vector(null, {\n            maxResolution: 1,\n            protocol: new OpenLayers.Protocol(),\n            strategies: [new OpenLayers.Strategy.BBOX()]\n        });\n\n        var map = new OpenLayers.Map(\"map\");\n        map.addLayer(dummy);\n        map.addLayer(layerReproject);\n        map.setCenter(new OpenLayers.LonLat(0, 0));\n        map.addLayer(layer);\n        map.addLayer(layerOutOfRange);\n        // test that the strategy bounds were set\n        t.ok(map.getExtent().equals(strategy.bounds), \"[set center] bounds set to map extent\");\n        t.eq(layerOutOfRange.strategies[0].bounds, null, \"Data not requested if layer is out of range\");\n\n        layerOutOfRange.setVisibility(false);\n        layerOutOfRange.setVisibility(true);\n        t.eq(layerOutOfRange.strategies[0].bounds, null, \"Data not requested if layer is out of range when switching visibility\");\n\n        map.destroy();\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 400px; height: 200px\" />\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Strategy/Cluster.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_activate(t) {\n        t.plan(2);\n\n        var strategy = new OpenLayers.Strategy.Cluster();\n        t.eq(strategy.active, false, \"not active after construction\");\n\n        var layer = new OpenLayers.Layer.Vector(\"Vector Layer\", {\n            strategies: [strategy]\n        });\n        var map = new OpenLayers.Map('map');\n        map.addLayer(layer);\n        \n        t.eq(strategy.active, true, \"active after adding to map\");\n    }\n\n    function test_clusters(t) {\n        t.plan(22);\n\n        function featuresEq(got, exp) {\n            var eq = false;\n            if(got instanceof Array && exp instanceof Array) {\n                if(got.length === exp.length) {\n                    for(var i=0; i<got.length; ++i) {\n                        if(got[i] !== exp[i]) {\n                            console.log(got[i], exp[i]);\n                            break;\n                        }\n                    }\n                    eq = (i == got.length);\n                }\n            }\n            return eq;\n        }\n\n        var strategy = new OpenLayers.Strategy.Cluster();\n        var layer = new OpenLayers.Layer.Vector(\"Vector Layer\", {\n            strategies: [strategy],\n            isBaseLayer: true\n        });\n        var map = new OpenLayers.Map('map', {\n            resolutions: [4, 2, 1],\n            maxExtent: new OpenLayers.Bounds(-40, -40, 40, 40),\n            zoomMethod: null\n        });\n        map.addLayer(layer);\n        \n        // create features in a line, 1 unit apart\n        var features = new Array(80);\n        for(var i=0; i<80; ++i) {\n            features[i] = new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.Point(-40 + i, 0)\n            );\n        }\n        \n        // add one additional feature, with no geometry - just to confirm it doesn't break things\n        features.push(new OpenLayers.Feature.Vector());\n        \n        layer.addFeatures(features);\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n        \n        // resolution 4\n        // threshold: 4 * 20 = 80 units\n        // one cluster\n        t.eq(layer.features.length, 1, \"[4] layer has one cluster\");\n        t.ok(featuresEq(layer.features[0].cluster, features.slice(0, 80)), \"[4] cluster includes all features with geometries\");\n        \n        // resolution 2\n        // threshold: 2 * 20 = 40 units\n        // two clusters (41 and 39) - first cluster includes all features within 40 units of the first (0-40 or 41 features)\n        map.zoomIn();\n        t.eq(layer.features.length, 2, \"[2] layer has two clusters\");\n        t.ok(featuresEq(layer.features[0].cluster, features.slice(0, 41)), \"[2] first cluster includes first 41 features\");\n        t.ok(featuresEq(layer.features[1].cluster, features.slice(41, 80)), \"[2] second cluster includes last 39 features\");\n        \n        // resolution 1\n        // threshold: 1 * 20 = 20 units\n        // four clusters (21, 21, 21, and 17)\n        map.zoomIn();\n        t.eq(layer.features.length, 4, \"[1] layer has four clusters\");\n        t.ok(featuresEq(layer.features[0].cluster, features.slice(0, 21)), \"[1] first cluster includes first 21 features\");\n        t.ok(featuresEq(layer.features[1].cluster, features.slice(21, 42)), \"[1] second cluster includes second 21 features\");\n        t.ok(featuresEq(layer.features[2].cluster, features.slice(42, 63)), \"[1] third cluster includes third 21 features\");\n        t.ok(featuresEq(layer.features[3].cluster, features.slice(63, 80)), \"[1] fourth cluster includes last 17 features\");\n        \n        // zoom out and back in to test threshold property (21)\n        map.zoomOut();\n        strategy.threshold = 21;\n        map.zoomIn();\n        t.eq(layer.features.length, 20, \"[1-threshold 21] layer has 20 clusters\");\n        t.ok(featuresEq(layer.features[0].cluster, features.slice(0, 21)), \"[1-threshold 21] first cluster includes first 21 features\");\n        t.ok(featuresEq(layer.features[1].cluster, features.slice(21, 42)), \"[1-threshold 21] second cluster includes second 21 features\");\n        t.ok(featuresEq(layer.features[2].cluster, features.slice(42, 63)), \"[1-threshold 21] third cluster includes third 21 features\");\n        t.ok(featuresEq(layer.features.slice(3, 20), features.slice(63, 80)), \"[1-threshold 21] last 17 features are not clustered\");\n        \n        // zoom out and back in to test high threshold\n        map.zoomOut();\n        strategy.threshold = 100; // clusters must contain 100 features or more\n        map.zoomIn();\n        // the one feature with no geometry is not added to the layer\n        t.eq(layer.features.length, features.length-1, \"[1-threshold 100] layer has \" + (features.length-1) + \" clusters\");\n        t.ok(featuresEq(layer.features, features.slice(0, 80)), \"[1-threshold 100] layer has all features with geometry\");\n\n        // remove features and zoom\n        strategy.threshold = 1;\n        map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n        t.eq(strategy.features.length, 81,\n                    \"[remove features] cluster has cache\");\n        layer.removeAllFeatures();\n        t.eq(layer.features.length, 0,\n                    \"[remove features] layer has no features after remove\");\n        t.ok(!strategy.features,\n                    \"[remove features] cluster has no cache after remove\");\n        map.zoomIn();\n        t.eq(layer.features.length, 0,\n                    \"[remove features] layer has no features after zoom\");\n        t.ok(!strategy.features,\n                    \"[remove features] cluster has no cache after zoom\");\n\n        map.destroy();\n    }\n\n    function test_deactivate(t) {\n        t.plan(2);\n\n        var strategy = new OpenLayers.Strategy.Cluster();\n        var layer = new OpenLayers.Layer.Vector(\"Vector Layer\", {\n            strategies: [strategy]\n        });\n        var map = new OpenLayers.Map('map');\n        map.addLayer(layer);\n        \n        t.eq(strategy.active, true, \"active after adding to map\");\n        \n        map.removeLayer(layer);\n        t.eq(strategy.active, false, \"not active after removing from map\");\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 400px; height: 200px\" />\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Strategy/Filter.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<script src=\"../OLLoader.js\"></script>\n<script>\n\nvar features = [];\nfor (var i=0; i<20; ++i) {\n    features.push(\n        new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(0, 0), {index: i}\n        )\n    );\n}\n\nvar filter = new OpenLayers.Filter.Comparison({\n    type: OpenLayers.Filter.Comparison.LESS_THAN,\n    property: \"index\",\n    value: 10\n});\n\nfunction test_initialize(t) {\n    \n    t.plan(4);\n    \n    var strategy = new OpenLayers.Strategy.Filter({filter: filter});\n\n    t.ok(strategy instanceof OpenLayers.Strategy, \"is strategy\");\n    t.ok(strategy instanceof OpenLayers.Strategy.Filter, \"is filter strategy\");\n    \n    t.ok(strategy.filter === filter, \"has filter\");\n    \n    strategy.destroy();\n    \n    try {\n        strategy = new OpenLayers.Strategy.Filter();\n        t.ok(true, \"strategy without filter works\");\n    } catch (err) {\n        t.fail(\"strategy without filter should not throw\");\n    }\n    \n\n}\n\nfunction test_autoActivate(t) {\n\n    t.plan(2);\n\n    var strategy = new OpenLayers.Strategy.Filter({filter: filter});\n    \n    var layer = new OpenLayers.Layer.Vector(null, {\n        strategies: [strategy]\n    });\n    \n    t.ok(!strategy.active, \"strategy not active before adding to map\");\n\n    var map = new OpenLayers.Map({\n        div: \"map\",\n        allOverlays: true,\n        layers: [layer],\n        center: new OpenLayers.LonLat(0, 0),\n        zoom: 1\n    });\n\n    t.ok(strategy.active, \"strategy active after adding to map\");\n    \n    map.destroy();\n    \n}\n\nfunction test_setFilter(t) {\n    \n    t.plan(13);\n\n    var strategy = new OpenLayers.Strategy.Filter({filter: filter});\n    var layer = new OpenLayers.Layer.Vector(null, {\n        strategies: [strategy]\n    });\n\n    var map = new OpenLayers.Map({\n        div: \"map\",\n        allOverlays: true,\n        layers: [layer],\n        center: new OpenLayers.LonLat(0, 0),\n        zoom: 1\n    });\n    \n    var log = [];\n    layer.events.on({\n        beforefeaturesadded:  function(event) {\n            log.push(event.type);\n        },\n        beforefeaturesremoved: function(event) {\n            log.push(event.type);\n        }\n    })\n\n    // a) add all features\n    log = [];\n    layer.addFeatures(features);\n    t.eq(features.length, 20, \"a) collection of 20 features\")\n    t.eq(layer.features.length, 10, \"a) layer got 10 with filter 'index < 10'\");\n    t.eq(strategy.cache.length, 10, \"a) strategy cached 10 with filter 'index < 10'\");\n    t.eq(log.length, 1, \"a) one event logged\");\n    t.eq(log[0], \"beforefeaturesadded\", \"a) beforefeaturesadded fired\");\n\n    // b) update filter\n    log = [];\n    filter.value = 5;\n    strategy.setFilter(filter);\n    t.eq(layer.features.length, 5, \"b) layer got 5 with filter 'index < 5'\");\n    t.eq(strategy.cache.length, 15, \"b) strategy cached 15 with filter 'index < 5'\");\n    t.eq(log.length, 1, \"b) one event logged\");\n    t.eq(log[0], \"beforefeaturesremoved\", \"b) beforefeaturesremoved fired\");\n\n    // c) update filter\n    log = [];\n    filter.value = 15;\n    strategy.setFilter(filter);\n    t.eq(layer.features.length, 15, \"c) layer got 15 with filter 'index < 15'\");\n    t.eq(strategy.cache.length, 5, \"c) strategy cached 5 with filter 'index < 15'\");\n    t.eq(log.length, 1, \"c) one event logged\");\n    t.eq(log[0], \"beforefeaturesadded\", \"c) beforefeaturesadded fired\");\n    \n    map.destroy();\n    \n}\n\n\n\n</script></head>\n<body>\n    <div id=\"map\" style=\"width: 512px; height: 256px\" />\n</body>\n</html>"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Strategy/Fixed.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_activate(t) {\n        t.plan(5);\n\n        var featureList = ['foo', 'bar'];\n        // a fake protocol\n        var protocol = {\n            read: function(options) {\n                options.callback.call(options.scope, {\n                    features: featureList, \n                    success: OpenLayers.Function.True\n                });\n            }\n        };\n        \n        // Create a dummy layer that can act as the map base layer.\n        // This will be unnecessary if #1920 is addressed or if base layer\n        // handling is changed.\n        var dummy = new OpenLayers.Layer(null, {isBaseLayer: true});\n\n        var layer = new OpenLayers.Layer.Vector(\"Vector Layer\", {\n            strategies: [new OpenLayers.Strategy.Fixed()],\n            protocol: protocol,\n            addFeatures: function(features) {\n                t.eq(features, featureList, \"Features added to the layer\");\n            }\n        });\n        \n        var layerp = new OpenLayers.Layer.Vector(\"Hidden preload Layer\", {\n            strategies: [new OpenLayers.Strategy.Fixed({preload:true})],\n            protocol: protocol,\n            visibility: false,\n            addFeatures: function(features) {\n                t.ok(!this.visibility, \"Features preloaded before visible\");\n            }\n        });\n\n        var s = new OpenLayers.Strategy.Fixed();\n        var layer2 = new OpenLayers.Layer.Vector(\"Hidden lazyload Layer\", {\n            strategies: [s],\n            protocol: protocol,\n            visibility: false,\n            addFeatures: function(features) {\n                t.ok(this.visibility, \"Layer visible when features added\");\n            }\n        });\n\n        var map = new OpenLayers.Map('map');\n        map.addLayers([dummy, layer, layerp, layer2]);\n\n        t.ok(layer2.events.listeners[\"visibilitychanged\"][0].obj == s &&\n                layer2.events.listeners[\"visibilitychanged\"][0].func == s.load,\n                \"activate registers visibilitychanged listener if layer hidden\"+\n                \" and is lazyloading\");\n\n        layer2.setVisibility(true);\n        \n        t.ok(layer2.events.listeners[\"visibilitychanged\"] == false,\n                \"visibilitychanged listener unregistered\");\n    }\n    \n    function test_events(t) {\n        \n        t.plan(7);\n        \n        var log = [];\n\n        var response = new OpenLayers.Protocol.Response();\n        \n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector(null, {\n            filter: new OpenLayers.Filter.Comparison({\n                type: '==',\n                property: 'foo',\n                value: 'bar'\n            }),\n            strategies: [new OpenLayers.Strategy.Fixed()],\n            protocol: new OpenLayers.Protocol({\n                read: function(config) {\n                    config.callback.call(config.scope, response);\n                }\n            }),\n            isBaseLayer: true,\n            eventListeners: {\n                loadstart: function(event) {\n                    log.push(event);\n                },\n                loadend: function(event) {\n                    log.push(event);\n                }\n            }\n        });\n\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n\n        t.eq(log.length, 2, \"2 events logged\");\n        t.eq(log[0].type, \"loadstart\", \"loadstart first\");\n        t.eq(log[0].filter, layer.filter, \"filter passed on as argument to loadstart\");\n        t.eq(log[1].type, \"loadend\", \"loadend second\");\n        t.ok(log[1].response == response, \"loadend includes response\");\n        \n        var calls = [];\n        layer.protocol.read = function(obj) {\n            calls.push(obj);\n        }\n        layer.refresh({whee: 'chicken'});\n\n        t.eq(calls.length, 1, \"1 call to read\");\n        t.eq(calls[0].whee, \"chicken\", \"properties passed to read\");\n        \n        map.destroy();\n        \n    }\n    \n    \n    function test_merge(t) {\n        \n        t.plan(6);\n        \n        var strategy = new OpenLayers.Strategy.Fixed();\n        \n        // create map with default projection\n        var map = new OpenLayers.Map(\"map\");\n        \n        var log = {\n            loadend: 0\n        };\n        \n        // create layer with custom projection\n        var layer = new OpenLayers.Layer.Vector(null, {\n            isBaseLayer: true,\n            strategies: [strategy],\n            protocol: new OpenLayers.Protocol(),\n            projection: new OpenLayers.Projection(\"EPSG:900913\"),\n            eventListeners: {\n                loadend: function() {\n                    ++log.loadend;\n                }\n            }\n        });\n        \n        // give the layer some existing features (one)\n        layer.addFeatures([\n            new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.Point(0, 0)\n            )\n        ]);\n        \n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        \n        // create some features\n        var geometries = [\n            new OpenLayers.Geometry.Point(100, 200),\n            new OpenLayers.Geometry.Point(1000, 2000)\n        ];\n        var features = [\n            new OpenLayers.Feature.Vector(geometries[0].clone()),\n            new OpenLayers.Feature.Vector(geometries[1].clone())\n        ];\n\n        // call merge with a mocked up response\n        strategy.merge({features: features, success: OpenLayers.Function.True});\n        \n        // confirm that the original features were destroyed\n        t.eq(layer.features.length, 2, \"old features destroyed\");\n        \n        // confirm that loadend was called\n        t.eq(log.loadend, 1, \"merge triggers loadend\");\n        \n        // test that feature geometries have been transformed to map projection\n        var from = layer.projection;\n        var to = map.getProjectionObject();\n        t.geom_eq(layer.features[0].geometry, features[0].geometry.transform(from, to), \"[different proj] feature 0 geometry transformed\");\n        t.geom_eq(layer.features[1].geometry, features[1].geometry.transform(from, to), \"[different proj] feature 1 geometry transformed\");\n        \n        // same as above but with same map/layer projection\n        layer.destroyFeatures();\n        layer.projection = map.getProjectionObject();\n        \n        features = [\n            new OpenLayers.Feature.Vector(geometries[0].clone()),\n            new OpenLayers.Feature.Vector(geometries[1].clone())\n        ];\n        \n        // call merge again with mocked up response\n        strategy.merge({features: features, success: OpenLayers.Function.True});\n\n        // test that feature geometries have not been transformed\n        t.geom_eq(layer.features[0].geometry, features[0].geometry, \"[same proj] feature 0 geometry not transformed\");\n        t.geom_eq(layer.features[1].geometry, features[1].geometry, \"[same proj] feature 1 geometry not transformed\");\n        \n    }\n\n    function test_load(t) {\n        t.plan(3);\n\n        // set up\n\n        var log;\n\n        var map = new OpenLayers.Map({\n            div: \"map\",\n            projection: new OpenLayers.Projection(\"EPSG:900913\"),\n            layers: [new OpenLayers.Layer(\"\", {isBaseLayer: true})]\n        });\n\n        var response = new OpenLayers.Protocol.Response();\n\n        var strategy = new OpenLayers.Strategy.Fixed({\n            merge: function(r) {\n                log = {scope: this, response: r};\n            }\n        });\n\n        var layer = new OpenLayers.Layer.Vector(\"vector\", {\n            strategies: [strategy],\n            protocol: {\n                read: function(o) {\n                    o.callback.call(o.scope, response);\n                }\n            }\n        });\n\n        map.addLayer(layer);\n\n        // test\n\n        strategy.load();\n\n        // verify that the callback is correctly bound\n        t.ok(log !== undefined,\n             \"merge was called\");\n        t.ok(log.scope == strategy,\n             \"merge called with expected scope\");\n        t.ok(log.response == response,\n             \"merge called with response as the first arg\");\n\n        // tear down\n\n        map.destroy();\n    }\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 400px; height: 200px\" />\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Strategy/Paging.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_activate(t) {\n        t.plan(2);\n\n        var strategy = new OpenLayers.Strategy.Paging();\n        t.eq(strategy.active, false, \"not active after construction\");\n\n        var layer = new OpenLayers.Layer.Vector(\"Vector Layer\", {\n            strategies: [strategy]\n        });\n        var map = new OpenLayers.Map('map');\n        map.addLayer(layer);\n        \n        t.eq(strategy.active, true, \"active after adding to map\");\n    }\n    \n    function test_paging(t) {\n        t.plan(18);\n\n        var strategy = new OpenLayers.Strategy.Paging();\n        var layer = new OpenLayers.Layer.Vector(\"Vector Layer\", {\n            strategies: [strategy],\n            drawFeature: function() {}\n        });\n        var map = new OpenLayers.Map('map');\n        map.addLayer(layer);\n        \n        var features = new Array(25);\n        for(var i=0; i<features.length; ++i) {\n            features[i] = {destroy: function() {}};\n        }\n        \n        function featuresEq(got, exp) {\n            var eq = false;\n            if(got instanceof Array && exp instanceof Array) {\n                if(got.length === exp.length) {\n                    for(var i=0; i<got.length; ++i) {\n                        if(got[i] !== exp[i]) {\n                            console.log(got[i], exp[i]);\n                            break;\n                        }\n                    }\n                    eq = (i == got.length);\n                }\n            }\n            return eq;\n        }\n        \n        var len = strategy.pageLength();\n        t.eq(len, 10, \"page length defaults to 10\");\n        \n        // add 25 features to the layer\n        layer.addFeatures(features);\n        t.eq(strategy.features.length, features.length, \"strategy caches all features\");\n        t.eq(layer.features.length, len, \"layer gets one page of features\");\n        t.ok(featuresEq(layer.features, features.slice(0, len)), \"layer gets first page initially\");\n        t.eq(strategy.pageNum(), 0, \"strategy reports 0 based page number\");\n        t.eq(strategy.pageCount(), Math.ceil(features.length / len), \"strategy reports correct number of pages\");\n        \n        // load next page of features\n        var changed = strategy.pageNext();\n        t.eq(changed, true, \"(1) strategy reports change\");\n        t.eq(strategy.pageNum(), 1, \"second page\");\n        t.ok(featuresEq(layer.features, features.slice(len, 2*len)), \"layer has second page of features\");\n        \n        // load next page of features (half page)\n        changed = strategy.pageNext();\n        t.eq(changed, true, \"(2) strategy reports change\");\n        t.eq(strategy.pageNum(), 2, \"third page\");\n        \n        // try to change forward again\n        changed = strategy.pageNext();\n        t.eq(changed, false, \"strategy reports no change\");\n        t.eq(layer.features.length, features.length % len, \"layer has partial page\");\n        t.ok(featuresEq(layer.features, features.slice(2*len, 3*len)), \"layer has third page of features\");\n        t.eq(strategy.pageNum(), 2, \"still on third page\");\n        \n        // change back a page\n        changed = strategy.pagePrevious();\n        t.eq(changed, true, \"(3) strategy reports change\");\n        t.eq(strategy.pageNum(), 1, \"back on second page\");\n        t.ok(featuresEq(layer.features, features.slice(len, 2*len)), \"layer has second page of features again\");\n        \n        layer.destroy();\n        \n    }\n\n    function test_deactivate(t) {\n        t.plan(2);\n\n        var strategy = new OpenLayers.Strategy.Paging();\n        var layer = new OpenLayers.Layer.Vector(\"Vector Layer\", {\n            strategies: [strategy]\n        });\n        var map = new OpenLayers.Map('map');\n        map.addLayer(layer);\n        \n        t.eq(strategy.active, true, \"active after adding to map\");\n        \n        map.removeLayer(layer);\n        t.eq(strategy.active, false, \"not active after removing from map\");\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 400px; height: 200px\" />\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Strategy/Refresh.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    var interval = 5000;\n    \n    function test_initialize(t) {\n        t.plan(2);\n\n        var s = new OpenLayers.Strategy.Refresh({interval: interval});\n        t.ok(typeof s.interval === \"number\", \"interval must be a number\");\n        t.eq(s.interval, interval, \"ctor sets interval\");\n    }\n\n    function test_activate(t) {\n        t.plan(4);\n\n        var l = new OpenLayers.Layer.Vector();\n        l.setVisibility(false);\n        var s = new OpenLayers.Strategy.Refresh();\n        s.setLayer(l);\n\n        t.eq(s.active, false, \"not active after construction\");\n\n        var activated = s.activate();\n        t.eq(activated, true, \"activate returns true\");\n        t.eq(s.active, true, \"activated after activate\");\n        t.ok(l.events.listeners.visibilitychanged[0].obj == s &&\n            l.events.listeners.visibilitychanged[0].func == s.reset,\n            \"activates registers visibilitychanged listener\");\n    }\n\n    function test_deactivate(t) {\n        t.plan(3);\n\n        var l = new OpenLayers.Layer.Vector();\n        l.setVisibility(false);\n        var s = new OpenLayers.Strategy.Refresh();\n        s.setLayer(l);\n        s.activate();\n        var deactivated = s.deactivate();\n        t.eq(deactivated, true, \"deactivate returns true\");\n        t.eq(s.active, false, \"deactivated after activate\");\n        t.ok(l.events.listeners.visibilitychanged.length == 0,\n            \"deactivate unregisters visibilitychanged listener\");\n    }\n\t\n    function test_activateWithVisibleLayer(t) {\n        t.plan(5);\n\n        var l = new OpenLayers.Layer.Vector();\n        l.setVisibility(true);\n        var s = new OpenLayers.Strategy.Refresh({interval: interval});\n        s.setLayer(l);\n\n        t.eq(s.active, false, \"not active after construction\");\n\n        var activated = s.activate();\n        t.eq(activated, true, \"activate returns true\");\n        t.eq(s.active, true, \"activated after activate\");\n        t.ok(l.events.listeners.visibilitychanged[0].obj == s &&\n            l.events.listeners.visibilitychanged[0].func == s.reset,\n            \"activates registers visibilitychanged listener\");\n        t.ok(s.timer !== null, \"timer should be set on activate if layer is visible\");\n\n        // reset the timer!!\n        s.stop();\n    }\n\n    function test_events(t) {\n        \n        t.plan(1);\n        var log = {\n            visibilitychanged: 0\n        };\n\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector(null, {\n            strategies: [new OpenLayers.Strategy.Refresh({interval: interval})],\n            protocol: new OpenLayers.Protocol({\n                read: function(config) {\n                    config.callback.call(config.scope, {});\n                }\n            }),\n            isBaseLayer: true,\n            eventListeners: {\n                visibilitychanged: function() {\n                    ++log.visibilitychanged;\n                }\n            }            \n        });\n        map.addLayer(layer);\n\n        layer.setVisibility(false);\n        t.eq(log.visibilitychanged, 1, \"visibilitychanged triggered\");\n        \n        map.destroy();\n        \n    }\n\n    function test_refreshWithNormalProgress(t) {\n        \n        t.plan(1);\n        var log = {\n            refreshcalled: 0\n        };\n\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector(null, {\n            strategies: [new OpenLayers.Strategy.Refresh({\n                interval: interval,\n                refresh: function() {\n                    if (this.layer && this.layer.refresh) {\n                        ++log.refreshcalled;\n                    }\n                }\n            })],\n            protocol: new OpenLayers.Protocol({\n                read: function(config) {\n                    config.callback.call(config.scope, {});\n                }\n            }),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n\n        t.delay_call((5 * (interval / 1000)) + 0.5, function() { \n            t.eq(log.refreshcalled, 5, \"number of refreshes\");\n            map.destroy();\n        });\n        \n    }\n\n    function test_refreshWithSwitchingVisibility(t) {\n        \n        t.plan(1);\n        var log = {\n            refreshcalled: 0\n        };\n\n        var map = new OpenLayers.Map(\"map\");\n        var layer = new OpenLayers.Layer.Vector(null, {\n            strategies: [new OpenLayers.Strategy.Refresh({\n                interval: interval,\n                refresh: function() {\n                    if (this.layer && this.layer.refresh) {\n                        ++log.refreshcalled;\n                    }\n                }\n            })],\n            protocol: new OpenLayers.Protocol({\n                read: function(config) {\n                    config.callback.call(config.scope, {});\n                }\n            }),\n            isBaseLayer: true\n        });\n        map.addLayer(layer);\n\n        window.setTimeout(function() {\n            layer.setVisibility(false);\n        }, 2.5 * interval);\n        \n        t.delay_call((5 * (interval / 1000)) + 0.5, function() { \n            t.eq(log.refreshcalled, 2, \"number of refreshes\");\n            map.destroy();\n        });\n        \n    }\n\n    </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 400px; height: 200px;\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Strategy/Save.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n  \n    function test_initialize(t) {\n        t.plan(1);\n        var strategy = new OpenLayers.Strategy.Save();\n        t.eq(strategy.auto, false, \"auto is false by default\");\n    }\n\n    function test_activate(t) {\n        \n        t.plan(3);\n        \n        var strategy = new OpenLayers.Strategy.Save();\n        var layer = new OpenLayers.Layer.Vector(null, {\n            isBaseLayer: true,\n            protocol: new OpenLayers.Protocol(),\n            strategies: [strategy]\n        });\n        var map = new OpenLayers.Map(\"map\");\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        \n        // check that auto true registers listeners\n        strategy.deactivate();\n        strategy.auto = true;\n        strategy.activate();\n        t.ok(layer.events.listeners[\"featureadded\"][0].func === strategy.triggerSave,\n             \"[auto true] triggerSave registered as listener for featureadded\");\n        t.ok(layer.events.listeners[\"afterfeaturemodified\"][0].func === strategy.triggerSave,\n             \"[auto true] triggerSave registered as listener for afterfeaturemodified\");\n\n        // check that auto can be set to interval\n        strategy.deactivate();\n        strategy.auto = 1;\n        strategy.activate();\n        t.ok(strategy.timer != null, \"[auto number] timer set\")\n        \n        map.destroy();\n        \n    }\n    \n    function test_save(t) {\n        t.plan(9);\n\n        var strategy = new OpenLayers.Strategy.Save();\n        \n        // mock up a protocol for synchronous and successful commits\n        var protocol = new OpenLayers.Protocol({\n            commit: function(features, options) {\n                var response = new OpenLayers.Protocol.Response();\n                response.reqFeatures = features;\n                response.insertIds = [];\n                for(var i=0; i<features.length; ++i) {\n                    // test feature.url first\n                    t.eq(features[i].url, \"url\" + i,\n                         \"feature.url correctly set (url\" + i + \")\");\n                    if(features[i].state == OpenLayers.State.INSERT) {\n                        response.insertIds.push(\"new_\" + i);\n                    }\n                }\n                response.code = OpenLayers.Protocol.Response.SUCCESS;\n                options.callback.call(options.scope, response);\n            }\n        });\n\n        var layer = new OpenLayers.Layer.Vector(null, {\n            isBaseLayer: true,\n            protocol: protocol,\n            strategies: [strategy],\n            projection: \"EPSG:4326\"\n        });\n        var map = new OpenLayers.Map(\"map\", {\n            getProjectionObject: function() {\n                return new OpenLayers.Projection(\"EPSG:900913\");\n            }\n        })\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        \n        // give the layer some features\n        var features = [\n            new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.Point(5, 45)\n            ), // insert\n            new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.Point(6, 46)\n            ), // delete\n            new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.Point(7, 47)\n            ), // update\n            new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.Point(8, 48)\n            )  // nothing\n        ];\n        features[0].state = OpenLayers.State.INSERT;\n        features[0].url = \"url0\";\n        features[1].state = OpenLayers.State.DELETE;\n        features[1].url = \"url1\";\n        features[2].state = OpenLayers.State.UPDATE;\n        features[2].url = \"url2\";\n        features[3].url = \"url3\";\n        layer.addFeatures(features);\n        \n        // save feature modifications\n        strategy.save(features);\n        \n        // confirm that newly created feature has an id and no longer has insert state\n        t.eq(features[0].fid, \"new_0\", \"newly created feature gets fid\");\n        t.ok(features[0].state == null, \"newly created feature no longer insert state\");\n        \n        // confirm that deleted features are not on layer\n        t.eq(layer.features.length, 3, \"layer only has three features\");\n        t.ok(features[1].layer == null, \"deleted feature has no layer\");\n        \n        // confirm that updated feature no longer has update state\n        t.ok(features[2].state == null, \"updated feature no longer update state\");\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 400px; height: 200px\" />\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Strategy.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(5);\n        var options = {};\n        var strategy = new OpenLayers.Strategy(options);\n\n        t.ok(strategy instanceof OpenLayers.Strategy,\n             \"new OpenLayers.Strategy returns object\" );\n        t.eq(strategy.options, options, \"constructor sets this.options\");\n        t.eq(strategy.active, false, \"constructor sets this.active to false\");\n        t.eq(strategy.autoActivate, true, \"constructor does not modify this.autoActivate\");\n        t.eq(strategy.autoDestroy, true, \"constructor does not modify this.autoDestroy\");\n    }\n\n    function test_activate(t) {\n        t.plan(1);\n        var options = {\n            activate: function() {\n                t.ok(true, \"OpenLayer.Map.addLayer calls activate\");\n            }\n        };\n        \n        var layer = new OpenLayers.Layer.Vector(\"Vector Layer\", {\n            strategies: [new OpenLayers.Strategy(options)]\n        });\n\n        var map = new OpenLayers.Map('map');\n        map.addLayer(layer);\n    }\n    \n    function test_destroy(t) {\n        t.plan(3);\n\n        var strategy = new OpenLayers.Strategy({\n            deactivate: function() {\n                t.ok(true, \"destroy calls deactivate\");\n            },\n            \n            options: {foo: 'bar'},\n            layer: 'foo'\n        });\n        strategy.destroy();\n\n        t.eq(strategy.layer, null, \"destroy nullify protocol.layer\");\n        t.eq(strategy.options, null, \"destroy nullify protocol.options\");\n    }\n\n    function test_activate(t) {\n        t.plan(4);\n        var strategy = new OpenLayers.Strategy({\n            layer: 'foo'\n        });\n\n        var ret;\n        ret = strategy.activate();\n\n        t.eq(strategy.active, true, \"activate sets this.active to true on first call\");\n        t.eq(ret, true, \"activate returns true on first call\");\n\n        ret = strategy.activate();\n\n        t.eq(strategy.active, true, \"activate does not modify this.active on second call\");\n        t.eq(ret, false, \"activate returns false on second call\");\n    }\n\n    function test_deactivate(t) {\n        t.plan(4);\n        var strategy = new OpenLayers.Strategy({\n            layer: 'foo'\n        });\n        strategy.activate();\n\n        var ret;\n        ret = strategy.deactivate();\n\n        t.eq(strategy.active, false, \"deactivate sets this.active to false on first call\");\n        t.eq(ret, true, \"deactivate returns true on first call\");\n\n        ret = strategy.deactivate();\n\n        t.eq(strategy.active, false, \"deactivate does not modify this.active on second call\");\n        t.eq(ret, false, \"deactivate returns false on second call\");\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Style.html",
    "content": "<html> \n<head> \n    <script src=\"OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_Style_constructor(t) { \n        t.plan(6); \n         \n        var rules = [\n            new OpenLayers.Rule({\n                symbolizer: {fillColor: \"red\"},\n                filter: new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                    property: \"type\",\n                    value: \"fire engine\"\n                })\n            }),\n            new OpenLayers.Rule({\n                symbolizer: {fillColor: \"yellow\"},\n                filter: new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                    property: \"type\",\n                    value: \"sports car\"\n                })\n            })\n        ];\n        var style = new OpenLayers.Style(null, {\n            foo: \"bar\",\n            rules: rules\n        }); \n        t.ok(style instanceof OpenLayers.Style, \n             \"new OpenLayers.Style returns object\" ); \n        t.eq(style.foo, \"bar\", \"constructor sets options correctly\");\n        t.eq(style.rules.length, 2, \"correct number of rules added\");\n        t.ok(style.rules[0] === rules[0], \"correct first rule added\");\n        t.ok(style.rules[1] === rules[1], \"correct second rule added\");\n        t.eq(typeof style.createSymbolizer, \"function\", \"style has a createSymbolizer function\"); \n    }\n    \n    function test_Style_create(t) {\n        t.plan(10);\n        \n        var map = new OpenLayers.Map(\"map\");\n        \n        var layer = new OpenLayers.Layer.Vector(\"layer\");\n         \n        var baseStyle = OpenLayers.Util.extend(\n            OpenLayers.Feature.Vector.style[\"default\"],\n            {externalGraphic: \"bar${foo}.png\"}\n        );\n        \n        var style = new OpenLayers.Style(baseStyle);\n        \n        var rule1 = new OpenLayers.Rule({\n            symbolizer: {\"Point\": {fillColor: \"green\"}},\n            maxScaleDenominator: 500000,\n            filter: new OpenLayers.Filter.FeatureId({\n                fids: [\"1\"]\n            })\n        });\n        var rule2 = new OpenLayers.Rule({\n            symbolizer: {\"Point\": {fillColor: \"yellow\"}},\n            minScaleDenominator: 500000,\n            maxScaleDenominator: 1000000,\n            filter: new OpenLayers.Filter.FeatureId({\n                fids: [\"1\"]\n            })\n        });\n        var rule3 = new OpenLayers.Rule({\n            symbolizer: {\"Point\": {fillColor: \"red\"}},\n            minScaleDenominator: 1000000,\n            maxScaleDenominator: 2500000,\n            filter: new OpenLayers.Filter.FeatureId({\n                fids: [\"1\"]\n            })\n        });\n        \n        var feature = new OpenLayers.Feature.Vector(\n            new OpenLayers.Geometry.Point(3,5),\n            {\"foo\": \"bar\"}\n        );\n\n        feature.fid = \"1\";\n        // for this fid, the above rule should apply\n        \n        layer.styleMap = new OpenLayers.StyleMap(style);\n                \n        layer.addFeatures([feature]);\n        map.addLayer(layer);\n        map.setBaseLayer(layer);\n\n        map.setCenter(new OpenLayers.LonLat(3,5), 10);\n\n        var createdStyle = style.createSymbolizer(feature);\n        t.eq(createdStyle.externalGraphic, \"barbar.png\", \"Calculated property style for default symbolizer correctly.\");\n        \n        style.addRules([rule1, rule2, rule3]);\n        createdStyle = style.createSymbolizer(feature);\n        \n        // at this scale, the feature should be green\n        t.eq(createdStyle.display, undefined, \"Feature is visible at scale \"+map.getScale());\n        t.eq(createdStyle.fillColor, \"green\", \"Point symbolizer from rule applied correctly.\");\n\n        map.setCenter(new OpenLayers.LonLat(3,5), 9);\n        // at this scale, the feature should be red\n        createdStyle = style.createSymbolizer(feature);\n        t.eq(createdStyle.display, undefined, \"Feature is visible at scale \"+map.getScale());\n        t.eq(createdStyle.fillColor, \"yellow\", \"Point symbolizer from rule applied correctly.\");\n\n        map.setCenter(new OpenLayers.LonLat(3,5), 8);\n        // at this scale, the feature should be yellow\n        createdStyle = style.createSymbolizer(feature);\n        t.eq(createdStyle.display, undefined, \"Feature is visible at scale \"+map.getScale());\n        t.eq(createdStyle.fillColor, \"red\", \"Point symbolizer from rule applied correctly.\");\n\n        map.setCenter(new OpenLayers.LonLat(3,5), 7);\n        // at this scale, the feature should be invisible\n        createdStyle = style.createSymbolizer(feature);\n        t.eq(createdStyle.display, \"none\", \"Feature is invisible at scale \"+map.getScale());\n        t.eq(createdStyle.fillColor, baseStyle.fillColor, \"Point symbolizer from base style applied correctly.\");\n        \n        feature.fid = \"2\";\n        // now the rule should not apply\n        \n        createdStyle = style.createSymbolizer(feature);\n        t.eq(createdStyle.fillColor, baseStyle.fillColor, \"Correct style for rule that does not apply to fid=\\\"2\\\".\");\n    }\n    \n    function test_Style_createSymbolizer(t) {\n        t.plan(5);\n        var style = new OpenLayers.Style();\n\n        // override applySymbolizer to log arguments\n        var log = [];\n        style.applySymbolizer = function(r) {\n            log.push(r);\n            OpenLayers.Style.prototype.applySymbolizer.apply(this, arguments);\n        };\n\n        // rules for the style\n        var rule = new OpenLayers.Rule({\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                property: \"foo\",\n                value: \"bar\"\n            }),\n            symbolizer: {\n                label: \"${labelValue}\"\n            }\n        });\n        rule.id = \"foo=bar rule\";\n        var elseRule = new OpenLayers.Rule({\n            elseFilter: true,\n            symbolizer: {\n                label: \"${labelValue}\"\n            }\n        });\n        elseRule.id = \"else rule\";\n        style.addRules([rule, elseRule]);\n        \n        // a) test that applySymbolizer is only called with rule\n        log = [];\n        style.createSymbolizer(\n            new OpenLayers.Feature.Vector(null, {foo: \"bar\"})\n        );\n        t.eq(log.length, 1, \"a) applySymbolizer called once\");\n        t.eq(log[0] && log[0].id, rule.id, \"a) applySymbolizer called with correct rule\");\n\n        // b) test that applySymbolizer is only called with elseRule\n        log = [];\n        style.createSymbolizer(\n            new OpenLayers.Feature.Vector(null, {foo: \"baz\"})\n        );\n        t.eq(log.length, 1, \"b) applySymbolizer called once\");\n        t.eq(log[0] && log[0].id, elseRule.id, \"b) applySymbolizer called with correct rule\");\n        \n        // c) test that label in returned symbolizer is a string even if property value is a number\n        var symbolizer = style.createSymbolizer(\n            new OpenLayers.Feature.Vector(null, {foo: \"bar\", labelValue: 0})\n        );\n        t.eq(symbolizer.label, \"0\", \"c) feature property cast to string when used as symbolizer label\");\n\n    }\n    \n    function test_Style_applySymbolizer(t) {\n        t.plan(15);\n\n        var feature = new OpenLayers.Feature.Vector();\n        var defaults = OpenLayers.Feature.Vector.style[\"default\"];\n        var style, symbolizer;\n\n        style = new OpenLayers.Style();\n        symbolizer = style.createSymbolizer(feature);\n        t.eq(symbolizer.pointRadius, defaults.pointRadius, \"symbolizer has the correct pointRadius\");\n        t.eq(symbolizer.strokeWidth, defaults.strokeWidth, \"symbolizer has the correct strokeWidth\");\n        t.eq(symbolizer.fillColor, defaults.fillColor, \"symbolizer has the correct fillColor\");\n        t.eq(symbolizer.graphicName, defaults.graphicName, \"symbolizer has the correct graphicName\");\n\n        style = new OpenLayers.Style(null, {\n            defaultsPerSymbolizer: true,\n            rules: [\n                new OpenLayers.Rule({\n                    symbolizer: {\n                        stroke: true\n                    }\n                })\n            ]\n        });\n        symbolizer = style.createSymbolizer(feature);\n        t.eq(symbolizer.strokeWidth, defaults.strokeWidth, \"symbolizer has the correct strokeWidth\");\n        t.ok(symbolizer.fillColor == undefined, \"fillColor is undefined\");\n\n        style = new OpenLayers.Style(null, {\n            defaultsPerSymbolizer: true,\n            rules: [\n                new OpenLayers.Rule({\n                    symbolizer: {\n                    }\n                })\n            ]\n        });\n        symbolizer = style.createSymbolizer(feature);\n        t.eq(symbolizer.pointRadius, defaults.pointRadius, \"symbolizer has the correct pointRadius\");\n        t.ok(symbolizer.strokeWidth == undefined, \"strokeWidth is undefined\");\n        t.ok(symbolizer.fillColor == undefined, \"fillColor is undefined\");\n        t.ok(symbolizer.graphicName == undefined, \"graphicName is undefined\");\n\n        style = new OpenLayers.Style(null, {\n            defaultsPerSymbolizer: true,\n            rules: [\n                new OpenLayers.Rule({\n                    symbolizer: {\n                        stroke: true\n                    }\n                })\n            ]\n        });\n        symbolizer = style.createSymbolizer(feature);\n        t.eq(symbolizer.strokeWidth, defaults.strokeWidth, \"symbolizer has the correct strokeWidth\");\n        t.ok(symbolizer.fillColor == undefined, \"fillColor is undefined\");\n\n        style = new OpenLayers.Style(null, {\n            defaultsPerSymbolizer: true,\n            rules: [\n                new OpenLayers.Rule({\n                    symbolizer: {\n                        fill: true\n                    }\n                })\n            ]\n        });\n        symbolizer = style.createSymbolizer(feature);\n        t.eq(symbolizer.fillColor, defaults.fillColor, \"symbolizer has the correct fillColor\");\n        t.ok(symbolizer.strokeWidth == undefined, \"strokeWidth is undefined\");\n\n        style = new OpenLayers.Style(null, {\n            defaultsPerSymbolizer: true,\n            rules: [\n                new OpenLayers.Rule({\n                    symbolizer: {\n                        graphic: true\n                    }\n                })\n            ]\n        });\n        symbolizer = style.createSymbolizer(feature);\n        t.eq(symbolizer.graphicName, defaults.graphicName, \"symbolizer has the correct graphicName\");\n    }\n    \n    function test_Style_context(t) {\n        t.plan(4);\n        var rule = new OpenLayers.Rule({\n            symbolizer: {\"Point\": {externalGraphic: \"${img1}\"}},\n            filter: new OpenLayers.Filter.Comparison({\n                type: OpenLayers.Filter.Comparison.LESS_THAN,\n                property: \"size\",\n                value: 11\n            })\n        });\n        var style = new OpenLayers.Style();\n        style.context = {\n            \"img1\": \"myImage.png\"\n        };\n        style.addRules([rule]);\n        var feature = new OpenLayers.Feature.Vector();\n        feature.attributes = {size: 10};\n        var styleHash = style.createSymbolizer(feature);\n        t.eq(styleHash.externalGraphic, \"myImage.png\", \"correctly evaluated rule and calculated property styles from a custom context\");\n        \n        // same as above, but without rule (#1526)\n        style = new OpenLayers.Style(\n            {externalGraphic: \"${getExternalGraphic}\"},\n            {context: {\n                getExternalGraphic: function(feature) {\n                    return \"foo\" + feature.attributes.size + \".png\";\n                }\n            }});\n        t.eq(style.createSymbolizer(feature).externalGraphic, \"foo10.png\", \"correctly evaluated symbolizer without rule\");\n        \n        style = new OpenLayers.Style(\n            {externalGraphic: \"${getExternalGraphic}\",\n             pointRadius: \"${size}\"},\n            {context: {\n                getExternalGraphic: function(feature) {\n                    return \"foo\" + feature.attributes.size + \".png\";\n                }\n            }});\n        t.eq(style.createSymbolizer(feature).externalGraphic, \"foo10.png\", \"correctly evaluated symbolizer from context\");\n        t.eq(style.createSymbolizer(feature).pointRadius, 10, \"correctly evaluated symbolizer from attributes\");\n        \n    };\n        \n    function test_Style_findPropertyStyles(t) {\n        t.plan(4);\n        var rule1 = new OpenLayers.Rule({symbolizer: {\n            pointRadius: 3,\n            externalGraphic: \"${foo}.bar\"\n        }});\n        var rule2 = new OpenLayers.Rule({symbolizer: {\"Point\": {\n            strokeWidth: \"${foo}\"\n        }}});\n        var style = new OpenLayers.Style({\n            strokeOpacity: 1,\n            strokeColor: \"${foo}\"\n        });\n        style.addRules([rule1, rule2]);\n        var propertyStyles = style.findPropertyStyles();\n        t.ok(propertyStyles.externalGraphic, \"detected externalGraphic from rule correctly\");\n        t.ok(propertyStyles.strokeWidth, \"detected strokeWidth from Point symbolizer correctly\");\n        t.ok(propertyStyles.strokeColor, \"detected strokeColor from style correctly\");\n        t.eq(typeof propertyStyles.pointRadius, \"undefined\", \"correctly detected pointRadius as non-property style\");\n    }\n    \n    function test_createLiteral(t) {\n        t.plan(6);\n        \n        var value, context, feature, result, expected;\n        var func = OpenLayers.Style.createLiteral;\n\n        // without templates\n        value = \"foo\";\n        expected = value;\n        result = func(value);\n        t.eq(result, expected, \"(no template) preserves literal\");\n        \n        // with templates\n        value = \"${foo}\"\n        expected = \"bar\";\n        context = {foo: expected};\n        result = func(value, context);\n        t.eq(result, expected, \"(template) preserves literal\");\n        \n        expected = \"\";\n        context = {foo: expected};\n        result = func(value, context);\n        t.eq(result, expected, \"(template) preserves empty string\");\n        \n        expected = \"16/03/2008\";\n        context = {foo: expected};\n        result = func(value, context);\n        t.eq(result, expected, \"(template) preserves string with numbers\");\n        \n        expected = 16;\n        context = {foo: expected + \"\"};\n        result = func(value, context);\n        t.eq(result, expected, \"(template) casts integer in a string\");\n\n        expected = 16;\n        context = {foo: \" \" + expected + \" \"};\n        result = func(value, context);\n        t.eq(result, expected, \"(template) casts integer in a space padded string\");\n\n    }\n\n    function test_clone(t) {\n        \n        t.plan(7);\n        \n        var style = new OpenLayers.Style({bar: \"baz\"}, {\n            name: \"test style\",\n            rules: [new OpenLayers.Rule({\n                name: \"test rule\"\n            })],\n            context: {\n                foo: \"bar\"\n            }\n        });\n        var clone = style.clone();\n        t.eq(clone.name, \"test style\", \"name copied\");\n        t.eq(clone.rules[0].name, \"test rule\", \"clone has correct rule\");\n        \n        // modify original\n        style.name = \"new\";\n        style.addRules([new OpenLayers.Rule({\n\t\t\tname: \"new rule\"\n\t\t})]);\n        style.context.foo = \"baz\";\n        \n        // confirm that clone didn't change\n        t.eq(clone.defaultStyle.bar, \"baz\", \"clone has clone of defaultStyle\");\n        t.eq(clone.name, \"test style\", \"clone has clone of name\");\n        t.eq(clone.rules.length, 1, \"clone has clone of rules\");\n        t.eq(clone.context.foo, \"bar\", \"clone has clone of context\");\n        \n        // confirm that ids are different\n        t.ok(clone.id !== style.id, \"clone has different id\");\n\n        style.destroy();\n        clone.destroy();\n        \n    }\n\n    function test_Style_destroy(t) {\n        t.plan(1);\n        \n        var style = new OpenLayers.Style();\n        style.destroy();\n        t.eq(style.rules, null, \"rules array nulled properly\");\n    }\n\n    </script> \n</head> \n<body> \n  <div id=\"map\" style=\"width:500px;height:500px\"></div>\n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Style2.html",
    "content": "<html> \n<head> \n    <script src=\"OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_constructor(t) { \n        t.plan(4); \n\n        var rules = [\n            new OpenLayers.Rule({\n                symbolizer: {fillColor: \"red\"},\n                filter: new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                    property: \"type\",\n                    value: \"fire engine\"\n                })\n            }),\n            new OpenLayers.Rule({\n                symbolizer: {fillColor: \"yellow\"},\n                filter: new OpenLayers.Filter.Comparison({\n                    type: OpenLayers.Filter.Comparison.EQUAL_TO,\n                    property: \"type\",\n                    value: \"sports car\"\n                })\n            })\n        ];\n        var style = new OpenLayers.Style2({rules: rules}); \n        t.ok(style instanceof OpenLayers.Style2, \"correct type\"); \n        t.eq(style.rules.length, 2, \"correct number of rules added\");\n        t.ok(style.rules[0] === rules[0], \"correct first rule added\");\n        t.ok(style.rules[1] === rules[1], \"correct second rule added\");\n    }\n    \n    function test_destroy(t) {\n        t.plan(1);\n        \n        var style = new OpenLayers.Style2({\n            rules: [\n                new OpenLayers.Rule({\n                    symbolizers: [\n                        new OpenLayers.Symbolizer.Point({\n                            fillColor: \"fuchsia\"\n                        })\n                    ]\n                })\n            ]\n        });\n        style.destroy();\n        t.ok(!style.rules, \"rules array gone\");\n    }\n\n\n    </script> \n</head>\n<body></body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/StyleMap.html",
    "content": "<html> \n<head> \n    <script src=\"OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_StyleMap_constructor(t) { \n        t.plan(6);\n         \n        var options = {'foo': 'bar'}; \n        var styleMap = new OpenLayers.StyleMap(null, options); \n        t.ok(styleMap instanceof OpenLayers.StyleMap, \n             \"new OpenLayers.StyleMap returns object\" ); \n        t.eq(styleMap.foo, \"bar\", \"constructor sets options correctly\"); \n\n        var style = new OpenLayers.Style();\n        var styleMap = new OpenLayers.StyleMap(style);\n        t.eq(styleMap.styles[\"default\"].defaultStyle.strokeColor, style.defaultStyle.strokeColor, \"default style set correctly from style object\");\n\n        var style = {strokeColor: \"blue\"};\n        var styleMap = new OpenLayers.StyleMap(style);\n        t.eq(styleMap.styles[\"default\"].defaultStyle.strokeColor, \"blue\", \"default style set correctly from style hash\");\n        \n        var style = {\n            \"default\": new OpenLayers.Style({strokeColor: \"yellow\"}),\n            \"select\": {strokeColor: \"blue\"}};\n        var styleMap = new OpenLayers.StyleMap(style);\n        t.eq(styleMap.styles[\"default\"].defaultStyle.strokeColor, \"yellow\", \"default style set correctly from a mixed hash of renderIntents\");\n        t.eq(styleMap.styles[\"select\"].defaultStyle.strokeColor, \"blue\", \"select style set correctly from a mixed hash of renderIntents\");\n    }\n    \n    function test_StyleMap_destroy(t) {\n        t.plan(2);\n        var styleMap = new OpenLayers.StyleMap();\n        t.ok(styleMap.styles[\"default\"], \"Got a default style after initialisation\");\n        styleMap.destroy();\n        t.ok(!styleMap.styles, \"StyleMap styles successfully destroyed\");\n    }\n    \n    </script> \n</head> \n<body> \n  <div id=\"map\" style=\"width:500px;height:500px\"></div>\n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Symbolizer/Line.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_constructor(t) { \n        t.plan(3); \n        \n        var symbolizer = new OpenLayers.Symbolizer.Line({foo: \"bar\"});\n        \n        t.ok(symbolizer instanceof OpenLayers.Symbolizer, \"instance of OpenLayers.Symbolizer\");\n        t.ok(symbolizer instanceof OpenLayers.Symbolizer.Line, \"instance of OpenLayers.Symbolizer.Line\");\n        t.eq(symbolizer.foo, \"bar\", \"constructor applies config properties\");\n\n    }\n    \n    function test_clone(t) {\n        t.plan(2);\n        \n        var symbolizer = new OpenLayers.Symbolizer.Line({foo: \"bar\"});\n        var clone = symbolizer.clone();\n        \n        t.ok(clone instanceof OpenLayers.Symbolizer.Line, \"correct type\");\n        t.eq(clone.foo, \"bar\", \"clone copies properties\");\n        \n    }\n    \n    function test_defaults(t) {\n        t.plan(5);\n        var symbolizer = new OpenLayers.Symbolizer.Line();\n        t.ok(symbolizer.strokeColor === undefined, \"no default strokeColor\");\n        t.ok(symbolizer.strokeOpacity === undefined, \"no default strokeOpacity\");\n        t.ok(symbolizer.strokeWidth === undefined, \"no default strokeWidth\");\n        t.ok(symbolizer.strokeLinecap === undefined, \"no default strokeLinecap\");\n        t.ok(symbolizer.strokeDashstyle === undefined, \"no default strokeDashstyle\");\n    }\n\n\n    </script> \n</head>\n<body></body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Symbolizer/Point.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_constructor(t) { \n        t.plan(3); \n        \n        var symbolizer = new OpenLayers.Symbolizer.Point({foo: \"bar\"});\n        \n        t.ok(symbolizer instanceof OpenLayers.Symbolizer, \"instance of OpenLayers.Symbolizer\");\n        t.ok(symbolizer instanceof OpenLayers.Symbolizer.Point, \"instance of OpenLayers.Symbolizer.Point\");\n        t.eq(symbolizer.foo, \"bar\", \"constructor applies config properties\");\n\n    }\n    \n    function test_clone(t) {\n        t.plan(2);\n        \n        var symbolizer = new OpenLayers.Symbolizer.Point({foo: \"bar\"});\n        var clone = symbolizer.clone();\n        \n        t.ok(clone instanceof OpenLayers.Symbolizer.Point, \"correct type\");\n        t.eq(clone.foo, \"bar\", \"clone copies properties\");\n        \n    }\n\n    function test_defaults(t) {\n        t.plan(16);\n        var symbolizer = new OpenLayers.Symbolizer.Point();\n        t.ok(symbolizer.strokeColor === undefined, \"no default strokeColor\");\n        t.ok(symbolizer.strokeOpacity === undefined, \"no default strokeOpacity\");\n        t.ok(symbolizer.strokeWidth === undefined, \"no default strokeWidth\");\n        t.ok(symbolizer.strokeLinecap === undefined, \"no default strokeLinecap\");\n        t.ok(symbolizer.strokeDashstyle === undefined, \"no default strokeDashstyle\");\n        t.ok(symbolizer.fillColor === undefined, \"no default fillColor\");\n        t.ok(symbolizer.fillOpacity === undefined, \"no default fillOpacity\");\n        t.ok(symbolizer.pointRadius === undefined, \"no default pointRadius\");\n        t.ok(symbolizer.externalGraphic === undefined, \"no default externalGraphic\");\n        t.ok(symbolizer.graphicWidth === undefined, \"no default graphicWidth\");\n        t.ok(symbolizer.graphicHeight === undefined, \"no default graphicHeight\");\n        t.ok(symbolizer.graphicOpacity === undefined, \"no default graphicOpacity\");\n        t.ok(symbolizer.graphicXOffset === undefined, \"no default graphicXOffset\");\n        t.ok(symbolizer.graphicYOffset === undefined, \"no default graphicYOffset\");\n        t.ok(symbolizer.rotation === undefined, \"no default rotation\");\n        t.ok(symbolizer.graphicName === undefined, \"no default graphicName\");\n    }\n\n    </script> \n</head>\n<body></body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Symbolizer/Polygon.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_constructor(t) { \n        t.plan(3); \n        \n        var symbolizer = new OpenLayers.Symbolizer.Polygon({foo: \"bar\"});\n        \n        t.ok(symbolizer instanceof OpenLayers.Symbolizer, \"instance of OpenLayers.Symbolizer\");\n        t.ok(symbolizer instanceof OpenLayers.Symbolizer.Polygon, \"instance of OpenLayers.Symbolizer.Polygon\");\n        t.eq(symbolizer.foo, \"bar\", \"constructor applies config properties\");\n\n    }\n    \n    function test_clone(t) {\n        t.plan(2);\n        \n        var symbolizer = new OpenLayers.Symbolizer.Polygon({foo: \"bar\"});\n        var clone = symbolizer.clone();\n        \n        t.ok(clone instanceof OpenLayers.Symbolizer.Polygon, \"correct type\");\n        t.eq(clone.foo, \"bar\", \"clone copies properties\");\n        \n    }\n\n    function test_defaults(t) {\n        t.plan(7);\n        var symbolizer = new OpenLayers.Symbolizer.Polygon();\n        t.ok(symbolizer.strokeColor === undefined, \"no default strokeColor\");\n        t.ok(symbolizer.strokeOpacity === undefined, \"no default strokeOpacity\");\n        t.ok(symbolizer.strokeWidth === undefined, \"no default strokeWidth\");\n        t.ok(symbolizer.strokeLinecap === undefined, \"no default strokeLinecap\");\n        t.ok(symbolizer.strokeDashstyle === undefined, \"no default strokeDashstyle\");\n        t.ok(symbolizer.fillColor === undefined, \"no default fillColor\");\n        t.ok(symbolizer.fillOpacity === undefined, \"no default fillOpacity\");\n    }\n\n\n    </script> \n</head>\n<body></body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Symbolizer/Raster.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_constructor(t) { \n        t.plan(3); \n        \n        var symbolizer = new OpenLayers.Symbolizer.Raster({foo: \"bar\"});\n        \n        t.ok(symbolizer instanceof OpenLayers.Symbolizer, \"instance of OpenLayers.Symbolizer\");\n        t.ok(symbolizer instanceof OpenLayers.Symbolizer.Raster, \"instance of OpenLayers.Symbolizer.Raster\");\n        t.eq(symbolizer.foo, \"bar\", \"constructor applies config properties\");\n\n    }\n    \n    function test_clone(t) {\n        t.plan(2);\n        \n        var symbolizer = new OpenLayers.Symbolizer.Raster({foo: \"bar\"});\n        var clone = symbolizer.clone();\n        \n        t.ok(clone instanceof OpenLayers.Symbolizer.Raster, \"correct type\");\n        t.eq(clone.foo, \"bar\", \"clone copies properties\");\n        \n    }\n\n\n    </script> \n</head>\n<body></body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Symbolizer/Text.html",
    "content": "<html> \n<head> \n    <script src=\"../OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_constructor(t) { \n        t.plan(3); \n        \n        var symbolizer = new OpenLayers.Symbolizer.Text({foo: \"bar\"});\n        \n        t.ok(symbolizer instanceof OpenLayers.Symbolizer, \"instance of OpenLayers.Symbolizer\");\n        t.ok(symbolizer instanceof OpenLayers.Symbolizer.Text, \"instance of OpenLayers.Symbolizer.Text\");\n        t.eq(symbolizer.foo, \"bar\", \"constructor applies config properties\");\n\n    }\n    \n    function test_clone(t) {\n        t.plan(2);\n        \n        var symbolizer = new OpenLayers.Symbolizer.Text({foo: \"bar\"});\n        var clone = symbolizer.clone();\n        \n        t.ok(clone instanceof OpenLayers.Symbolizer.Text, \"correct type\");\n        t.eq(clone.foo, \"bar\", \"clone copies properties\");\n        \n    }\n\n    function test_defaults(t) {\n        t.plan(5);\n        var symbolizer = new OpenLayers.Symbolizer.Point();\n        t.ok(symbolizer.label === undefined, \"no default label\");\n        t.ok(symbolizer.fontFamily === undefined, \"no default fontFamily\");\n        t.ok(symbolizer.fontSize === undefined, \"no default fontSize\");\n        t.ok(symbolizer.fontWeight === undefined, \"no default fontWeight\");\n        t.ok(symbolizer.fontStyle === undefined, \"no default fontStyle\");\n    }\n\n\n    </script> \n</head>\n<body></body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Symbolizer.html",
    "content": "<html> \n<head> \n    <script src=\"OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_constructor(t) { \n        t.plan(2); \n        \n        var symbolizer = new OpenLayers.Symbolizer({foo: \"bar\"});\n        \n        t.ok(symbolizer instanceof OpenLayers.Symbolizer, \"correct type\");\n        t.eq(symbolizer.foo, \"bar\", \"constructor applies config properties\");\n\n    }\n    \n    function test_clone(t) {\n        t.plan(2);\n        \n        var symbolizer = new OpenLayers.Symbolizer({foo: \"bar\"});\n        var clone = symbolizer.clone();\n        \n        t.ok(clone instanceof OpenLayers.Symbolizer, \"correct type\");\n        t.eq(clone.foo, \"bar\", \"clone copies properties\");\n        \n    }\n\n\n    </script> \n</head>\n<body></body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Test.AnotherWay.baseadditions.js",
    "content": "Test.AnotherWay._openlayers_sum_total_detail_ok=0;\nTest.AnotherWay._openlayers_sum_total_detail_fail=0;\nTest.AnotherWay._startTime = null;\nTest.AnotherWay._old_run_all_onclick = Test.AnotherWay._run_all_onclick;\nTest.AnotherWay._run_all_onclick = function(){\n    Test.AnotherWay._startTime = (new Date()).getTime();\n    Test.AnotherWay.reset_running_time();\n    Test.AnotherWay._old_run_all_onclick.apply(this, arguments);\n};\n\nTest.AnotherWay._old_run_selected_onclick = Test.AnotherWay._run_selected_onclick;\nTest.AnotherWay._run_selected_onclick = function(){\n    Test.AnotherWay._startTime = (new Date()).getTime();\n    Test.AnotherWay.reset_running_time();\n    Test.AnotherWay._old_run_selected_onclick.apply(this, arguments);\n};\n\nTest.AnotherWay._old_run_one_onclick = Test.AnotherWay._run_one_onclick;\nTest.AnotherWay._run_one_onclick = function(){\n    Test.AnotherWay._startTime = (new Date()).getTime();\n    Test.AnotherWay.reset_running_time();\n    Test.AnotherWay._old_run_one_onclick.apply(this, arguments);\n};\nTest.AnotherWay.old_load_next_page = Test.AnotherWay._load_next_page;\nTest.AnotherWay._load_next_page = function(){\n    document.getElementById(\"test_iframe_el\").style.display = \"none\";\n    Test.AnotherWay.update_running_time();    \n    Test.AnotherWay.old_load_next_page.apply(this, arguments);\n};\n\n\nTest.AnotherWay._add_test_page_url = function(test_url, convention){\n    var table = document.getElementById(\"testtable\");\n    var record_select = document.getElementById(\"record_select\");\n    var index = Test.AnotherWay._g_test_page_urls.length;\n    if (test_url.match(\"^(\\\\s*)(.*\\\\S)(\\\\s*)$\")) {\n        test_url = RegExp.$2;\n    }\n    \n    Test.AnotherWay._g_test_page_urls[index] = {\n        url: test_url,\n        convention: convention\n    };\n    var row = table.insertRow(-1);\n    \n    var cell;\n    var cell_child;\n    var link;\n    \n    cell = row.insertCell(-1);\n    cell_child = document.createElement(\"input\");\n    cell_child.type = \"checkbox\";\n    cell_child.id = \"checkbox\" + index;\n    cell_child.checked = 'checked';\n    cell_child.defaultChecked = 'checked';\n    cell.appendChild(cell_child);\n    \n    cell = row.insertCell(-1);\n    cell.setAttribute(\"width\", \"75%\");\n    link = document.createElement(\"a\");\n    link.href=test_url;\n    link.target='_blank';\n    link.title='Opens testfile in a new window.';\n    link.appendChild(document.createTextNode(test_url));    \n    cell.appendChild(link);\n    \n    cell = row.insertCell(-1);\n    cell_child = document.createElement(\"input\");\n    cell_child.type = \"button\";\n    cell_child.id = \"test\" + index;\n    cell_child.value = \" run \";\n    cell_child.onclick = Test.AnotherWay._run_one_onclick;\n    cell.appendChild(cell_child);\n    \n    cell = row.insertCell(-1);\n    cell.setAttribute(\"width\", \"8em\");\n    cell_child = document.createElement(\"span\");\n    cell.appendChild(cell_child);\n    \n    var option = document.createElement(\"option\");\n    option.appendChild(document.createTextNode(test_url));\n    record_select.appendChild(option);\n};\n\nTest.AnotherWay.old_set_iframe_location = Test.AnotherWay._set_iframe_location;\nTest.AnotherWay._set_iframe_location = function(iframe, loc, outside_path_correction){\n    var optionPos = loc.indexOf( \"?\" ),\n        option;\n    if (optionPos != -1) {\n        option = loc.substring(optionPos+1);\n        loc = loc.substring(0, optionPos);\n    }\n    if (option === \"visible\") {\n        document.getElementById(\"test_iframe_el\").style.display = \"\";\n    }\n    return Test.AnotherWay.old_set_iframe_location.call(this, iframe, loc, outside_path_correction);\n};\nTest.AnotherWay.update_running_time = function() {\n    var now = (new Date()).getTime();\n    var floor = Math.floor;\n    var elapsed = now - Test.AnotherWay._startTime;\n    var zeroPad = function(num, length){\n        var len = -1 * (length || 2);\n        return ('00000' + num).slice(len);  \n    };\n    var ms = zeroPad(elapsed%1000, 3);\n    var seconds=zeroPad(floor((elapsed/1000)%60));\n    var minutes=zeroPad(floor((elapsed/60000)%60));\n    \n    document.getElementById('running-time').innerHTML = 'Elapsed time ' + minutes + ':' + seconds + ':' + ms +' (m:s:ms).';\n};\n\nTest.AnotherWay.reset_running_time = function(){\n    document.getElementById('running-time').innerHTML = '';\n};\nTest.AnotherWay.bindQuicksearchListener = function(){\n    var input = document.getElementById('quickfilter');\n    if (input.addEventListener) {\n        input.addEventListener('keyup', Test.AnotherWay.quicksearch);\n    } else if (input.attachEvent) {\n        input.attachEvent('onkeyup', Test.AnotherWay.quicksearch);\n    } else {\n        input.parentNode.removeChild(input);\n    }\n};\nTest.AnotherWay.quicksearchThrottleTimeOut = null;\nTest.AnotherWay.quicksearch = function(){\n    if (Test.AnotherWay.quicksearchThrottleTimeOut) {\n        window.clearTimeout(Test.AnotherWay.quicksearchThrottleTimeOut);\n    }\n    Test.AnotherWay.quicksearchThrottleTimeOut = window.setTimeout(function(){\n        var input = document.getElementById('quickfilter');\n        Test.AnotherWay.filterTestList(input.value);\n    }, 300);\n};\n\nTest.AnotherWay.filterTestList = function(str){\n    Test.AnotherWay.unfilterTestList();\n    var re = new RegExp(str, 'i');\n    var candidates  = document.querySelectorAll('#testtable tr a');\n    for (var idx = 0, len = candidates.length; idx<len; idx++) {\n        var tr = candidates[idx].parentNode.parentNode;\n        var html = candidates[idx].innerHTML;\n        if (re.test(html)) {\n            tr.className = 'isShown';\n        } else {\n            tr.className = 'isHidden';\n        }\n    }\n    \n};\n\nTest.AnotherWay.unfilterTestList = function() {\n    if ( document.querySelectorAll ) {\n        var hidden = document.querySelectorAll('.isHidden');\n        for (var idx = 0, len = hidden.length; idx < len; idx++) {\n            hidden[idx].className = 'isShown';\n        }\n    }\n};\n(function(win) {\n    if (win.addEventListener) {\n        win.addEventListener('load', Test.AnotherWay.bindQuicksearchListener);\n    } else if (win.attachEvent) {\n        win.attachEvent('onload', Test.AnotherWay.bindQuicksearchListener);\n    } else {\n        win.onload = function(){\n            Test.AnotherWay.bindQuicksearchListener();\n        };\n    }\n})(window);\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Test.AnotherWay.css",
    "content": "/**\n *  Test.AnotherWay version 0.5\n *  \n *  Copyright (c) 2005 Artem Khodush, http://straytree.org\n *  \n *  Permission is hereby granted, free of charge, to any person obtaining\n *  a copy of this software and associated documentation files (the\n *  \"Software\"), to deal in the Software without restriction, including\n *  without limitation the rights to use, copy, modify, merge, publish,\n *  distribute, sublicense, and/or sell copies of the Software, and to\n *  permit persons to whom the Software is furnished to do so, subject to\n *  the following conditions:\n *  \n *  The above copyright notice and this permission notice shall be\n *  included in all copies or substantial portions of the Software.\n *  \n *  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n *  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n *  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n *  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n *  LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n *  OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n *  WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *  \n */\n\n* {\n    padding: 0;\n    margin: 0;\n}\n\nhtml {\n    height: 99%;\n}\n\nbody {\n    height: 98%;\n    font: normal normal 10pt sans-serif\n}\n\n#col1 {\n    float: left;\n    width: 27em;\n    margin: 0 0 0 1em;\n    overflow: visible;\n}\n\n#col2 {\n    position: relative;\n    height: 98%;\n    margin: 0 0.5em 0 28em;\n}\n\n#col1_header {\n    margin-top: 0.5em;\n}\n\n#scroller {\n    height: 400px;\n    overflow: auto;\n}\n\n#testtable {\n    margin: 0 0 2em 0;\n    width: 97%;\n    font-size: 1em;\n    border-collapse: collapse;\n}\n#testtable input {\n    cursor: pointer;\n}\n#testtable td {\n    line-height: 2em;\n    padding: 0;\n    margin: 0;\n    border-top: 1px solid #ccc;\n    border-bottom: 1px solid #ccc;\n}\n#testtable tr:hover td {\n    background-color: #ededed;\n}\n#testtable tr.isHidden {\n    display: none;\n}\n#testtable tr.isShown {\n    display: table-row;\n}\n\n#run_buttons, #running-time {\n    margin-bottom: 1em;\n}\n\n#right_header {\n    padding-top: 0.8em;\n}\n\n#results_count {\n    float: left;\n}\n\n#results > p:hover {\n    background-color: #ededed;\n}\n\n.active_tab {\n    float: right;\n    padding: 0 1em 0.2em 1em;\n    background: #0af;\n    border: 1px solid #048;\n    border-bottom: none;\n    cursor: pointer;\n    cursor: hand;\n    position: relative;\n    top: -0.2em;\n}\n\n.inactive_tab {\n    float: right;\n    padding: 0 1em 0 1em;\n    background: #9bb;\n    color: #444;\n    border: 1px solid #9bb;\n    border-bottom: none;\n    cursor: pointer;\n    cursor: hand;\n}\n\n.inactive_mouseover_tab {\n    float: right;\n    padding: 0 1em 0 1em;\n    background: #9bb;\n    color: #062;\n    border: 1px solid #062;\n    border-bottom: none;\n    cursor: pointer;\n    cursor: hand;\n}\n\n#right_frame {\n    overflow: auto;\n    position: relative;\n    top: -0.2em;\n    clear: right;\n    height: 95%;\n    border: 1px solid #048;\n}\n\n#debug {\n    display: none;\n}\n\n#debug p {\n    margin: 2px 0 0 5em;\n    text-indent: -4.8em;\n}\n\n#error {\n    display: none;\n    color: #c22;\n}\n\n#results p {\n    margin: 0 0 2px 0;\n}\n\n/* cursor indicating that detailed results may be expanded/contracted */\n#results p.badtest {\n    cursor: text;\n}\n\n#results p.ok, #results p.fail {\n    cursor: pointer;\n    cursor: hand;\n}\n\n/* colored squares in the results window at the left of test page names */\n#results p.ok .bullet {\n    background: #6d6;\n}\n\n#results p.fail .bullet {\n    background: #d46;\n}\n\n#results p.badtest .bullet {\n    background: #ea3;\n}\n\n#results p.loading .bullet {\n    background: #48f;\n}\n\n#results p.running .bullet {\n    background: #26e;\n}\n\n#results p.waiting .bullet {\n    background: #04d;\n}\n\n/* highlight in the results line */\n#results p .warning {\n    background: #ffc;\n}\n\n/* layout of the detailed results */\n.result_detail {\n    padding-left: 3em;\n}\n\n.result_exception_detail {\n    padding-left: 4em;\n}\n\n.result_exception_stack_detail {\n    padding-left: 5em;\n}\n\n.result_micro_detail {\n    padding-left: 6em;\n}\n\n/* colouring in the detailed results */\n.result_detail .fail, .result_exception_detail .fail, .result_micro_detail .fail {\n    background: #ffd8d8;\n}\n\n/* \"start recording\" controls*/\n#record_div {\n    margin-top: 3em;\n}\n\n#record_div p {\n    margin-bottom: 0.5em;\n}\n\n#record_select {\n    width: 88%;\n}\n\n#record_input {\n    width: 53%;\n}"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Test.AnotherWay.geom_eq.js",
    "content": "\n(function() {\n    \n        function assertEqual(got, expected, msg) {\n        if(got === undefined) {\n            got = \"undefined\";\n        } else if (got === null) {\n            got = \"null\";\n        }\n        if(expected === undefined) {\n            expected = \"undefined\";\n        } else if (expected === null) {\n            expected = \"null\";\n        }\n        if(got != expected) {\n            throw msg + \": got '\" + got + \"' but expected '\" + expected + \"'\";\n        }\n    }\n    \n        function assertFloatEqual(got, expected, msg) {\n        var OpenLayers = Test.AnotherWay._g_test_iframe.OpenLayers;\n        if(got === undefined) {\n            got = \"undefined\";\n        } else if (got === null) {\n            got = \"null\";\n        }\n        if(expected === undefined) {\n            expected = \"undefined\";\n        } else if (expected === null) {\n            expected = \"null\";\n        }\n        if(Math.abs(got - expected) > Math.pow(10, -OpenLayers.Util.DEFAULT_PRECISION)) {\n            throw msg + \": got '\" + got + \"' but expected '\" + expected + \"'\";\n        }\n    }\n    \n        function assertGeometryEqual(got, expected, options) {\n        \n        var OpenLayers = Test.AnotherWay._g_test_iframe.OpenLayers;\n        assertEqual(typeof got, typeof expected, \"Object types mismatch\");\n        assertEqual(got.CLASS_NAME, expected.CLASS_NAME, \"Object class mismatch\");\n        \n        if(got instanceof OpenLayers.Geometry.Point) {\n            assertFloatEqual(got.x, expected.x, \"x mismatch\");\n            assertFloatEqual(got.y, expected.y, \"y mismatch\");\n            assertFloatEqual(got.z, expected.z, \"z mismatch\");\n        } else {\n            assertEqual(\n                got.components.length, expected.components.length,\n                \"Component length mismatch for \" + got.CLASS_NAME\n            );\n            for(var i=0; i<got.components.length; ++i) {\n                try {\n                    assertGeometryEqual(\n                        got.components[i], expected.components[i], options\n                    );\n                } catch(err) {\n                    throw \"Bad component \" + i + \" for \" + got.CLASS_NAME + \": \" + err;\n                }\n            }\n        }\n        return true;\n    }\n    \n        var proto = Test.AnotherWay._test_object_t.prototype;\n    proto.geom_eq = function(got, expected, msg, options) {        \n        try {\n            assertGeometryEqual(got, expected, options);\n            this.ok(true, msg);\n        } catch(err) {\n            this.fail(msg + \": \" + err);\n        }\n    }\n    \n})();\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Test.AnotherWay.js",
    "content": "\nif (typeof(Test) == \"undefined\") {\n    Test = {};\n}\nTest.AnotherWay = {};\n\nTest.AnotherWay._g_test_iframe = null; // frame where to load test pages\nTest.AnotherWay._g_test_frame_no_clear = false; // true - leave last page displayed after tests end\nTest.AnotherWay._g_test_page_urls = []; // array of: { url: url, convention: \"anotherway\" or \"jsan\" }\nTest.AnotherWay._g_test_object_for_jsan = null; // test object for filling by tests that adhere to jsan Test.Simple calling convention\nTest.AnotherWay._g_pages_to_run = null; // list of pages to run automatically after loading\nTest.AnotherWay._g_run_on_main_load = false; // special handling for run_pages_to_run when it might be called before onload or before list of test pages is known.\nTest.AnotherWay._g_run_on_list_load = false;\nTest.AnotherWay._g_main_loaded = false;\n\nTest.AnotherWay._run_pages_to_run = function(called_from_outside){\n    if (!Test.AnotherWay._g_main_loaded) {\n        Test.AnotherWay._g_run_on_main_load = true;\n    }\n    else {\n        var a_pages = Test.AnotherWay._g_pages_to_run;\n        if (a_pages == \"all\") {\n            for (var i = 0; i < Test.AnotherWay._g_test_page_urls.length; ++i) {\n                Test.AnotherWay._run_test_page(\"test\" + i);\n            }\n        }\n        else \n            if (a_pages != null) {\n                for (var run_i = 0; run_i < a_pages.length; ++run_i) {\n                    var run_page = a_pages[run_i];\n                    var found = false;\n                    for (var all_i = 0; all_i < Test.AnotherWay._g_test_page_urls.length; ++all_i) {\n                        if (run_page == Test.AnotherWay._g_test_page_urls[all_i].url) {\n                            Test.AnotherWay._run_test_page(\"test\" + all_i, called_from_outside);\n                            found = true;\n                            break;\n                        }\n                    }\n                    if (!found) {\n                        Test.AnotherWay._show_error(\"page specified to run is not found in the page list: \" + run_page);\n                        break;\n                    }\n                }\n            }\n    }\n};\n\nTest.AnotherWay._add_test_page_url = function(test_url, convention){\n    var table = document.getElementById(\"testtable\");\n    var record_select = document.getElementById(\"record_select\");\n    var index = Test.AnotherWay._g_test_page_urls.length;\n    if (test_url.match(\"^(\\\\s*)(.*\\\\S)(\\\\s*)$\")) {\n        test_url = RegExp.$2;\n    }\n    \n    Test.AnotherWay._g_test_page_urls[index] = {\n        url: test_url,\n        convention: convention\n    };\n    var row = table.insertRow(-1);\n    \n    var cell;\n    var cell_child;\n    var link;\n    \n    cell = row.insertCell(-1);\n    cell_child = document.createElement(\"input\");\n    cell_child.type = \"checkbox\";\n    cell_child.id = \"checkbox\" + index;\n    cell_child.checked = 'checked';\n    cell_child.defaultChecked = 'checked';\n    cell.appendChild(cell_child);\n    \n    cell = row.insertCell(-1);\n    cell.setAttribute(\"width\", \"75%\");\n    \n    cell.appendChild(document.createTextNode(test_url));    \n    \n    cell = row.insertCell(-1);\n    cell_child = document.createElement(\"input\");\n    cell_child.type = \"button\";\n    cell_child.id = \"test\" + index;\n    cell_child.value = \" run \";\n    cell_child.onclick = Test.AnotherWay._run_one_onclick;\n    cell.appendChild(cell_child);\n    \n    cell = row.insertCell(-1);\n    cell.setAttribute(\"width\", \"8em\");\n    cell_child = document.createElement(\"span\");\n    cell.appendChild(cell_child);\n    \n    var option = document.createElement(\"option\");\n    option.appendChild(document.createTextNode(test_url));\n    record_select.appendChild(option);\n};\nTest.AnotherWay._show_error = function(msg){\n    var error_div = document.getElementById(\"error\");\n    error_div.innerHTML = \"\";\n    error_div.appendChild(document.createTextNode(msg));\n    error_div.style.display = \"block\";\n};\nTest.AnotherWay._list_iframe_onload = function(){\n    if (window.frames.list_iframe != null && window.frames.list_iframe.location != \"\" && window.frames.list_iframe.location != \"about:blank\") {\n        var list_doc = window.frames.list_iframe.document;\n        var list = list_doc.getElementById(\"testlist\");\n        if (list != null) {\n            for (var i = 0; i < list.childNodes.length; ++i) {\n                var item = list.childNodes[i];\n                if (item.nodeName == \"LI\" || item.nodeName == \"li\") {\n                    var convention = \"anotherway\";\n                    if (Test.AnotherWay._get_css_class(item) == \"jsan\") {\n                        convention = \"jsan\";\n                    }\n                    Test.AnotherWay._add_test_page_url(item.innerHTML, convention);\n                }\n            }\n            if (Test.AnotherWay._g_run_on_list_load) {\n                Test.AnotherWay._g_run_on_list_load = false;\n                Test.AnotherWay._run_pages_to_run();\n            }\n        }\n        else {\n            Test.AnotherWay._show_error(\"no list with id 'testlist' in a list file \" + window.frames.list_iframe.location);\n        }\n    }\n};\n\nTest.AnotherWay._map_checkboxes = function(f){\n    var table = document.getElementById(\"testtable\");\n    var checks = table.getElementsByTagName(\"INPUT\");\n    for (var i = 0; i < checks.length; ++i) {\n        if (checks[i].type == \"checkbox\" && checks[i].id.match(/^checkbox(\\d+)$/)) {\n            f(checks[i], RegExp.$1);\n        }\n    }\n};\n\nTest.AnotherWay._run_all_onclick = function(){\n    Test.AnotherWay._map_checkboxes(function(c, id){\n        Test.AnotherWay._run_test_page(\"test\" + id);\n    });\n};\nTest.AnotherWay._run_selected_onclick = function(){\n    Test.AnotherWay._map_checkboxes(function(c, id){\n        if (c.checked) {\n            Test.AnotherWay._run_test_page(\"test\" + id);\n        }\n    });\n};\n\nTest.AnotherWay._unselect_all_onclick = function(){\n    Test.AnotherWay._map_checkboxes(function(c, id){\n        c.checked = false;\n    });\n};\n\nTest.AnotherWay._run_one_onclick = function(){\n    Test.AnotherWay._run_test_page(this.id);\n};\nTest.AnotherWay._test_object_t = function(fun_name){\n    this.name = fun_name; // name of the test function\n    this.n_plan = null; // planned number of assertions\n    this.n_ok = 0; // # of ok assertions\n    this.n_fail = 0; // # of failed assertions\n    this.exception = \"\"; // if the function throwed an exception, it's its message\n    this.exception_stack = []; // strings: function call stack from the exception\n    this.assertions = []; // assertion results: array of { ok: 1 or 0, name: string }\n    this.wait_result_milliseconds = 0; // how long to wait before collecting results from the test\n    this.second_wait_msg = null; // <p> status message (in addition to the page wait_msg)\n    this.delay_actions = []; // array of actions to be perfomed after the test function returns\n    this.delay_action_i = null; // index of delay action currently being performed\n    this.delay_prev_timer_time = 0; // for counting time while performing delay_actions\n    this.delay_current_milliseconds_left = 0; // time left before the next action, runs down\n    this.delay_total_milliseconds_left = 0; // for indication: total estimated time for all actions, runs up and down\n};\n\nTest.AnotherWay._test_object_t.prototype.ok = function(cond, name){\n    if (cond) {\n        ++this.n_ok;\n        cond = 1;\n    }\n    else {\n        ++this.n_fail;\n        cond = 0;\n    }\n    this.assertions.push({\n        ok: cond,\n        name: name\n    });\n};\nTest.AnotherWay._test_object_t.prototype.fail = function(name){\n    this.ok(false, name);\n};\nTest.AnotherWay._test_object_t.prototype.plan = function(n){\n    this.n_plan = n;\n};\nTest.AnotherWay._test_object_t.prototype.wait_result = function(seconds){\n    this.wait_result_milliseconds = 1000 * seconds;\n};\nTest.AnotherWay._eq_fail_msg = function(path, what, expected, got){\n    return \"eq: \" + path + \" \" + what + \" differ: got \" + got + \", but expected \" + expected;\n};\nTest.AnotherWay._array_eq = function(expected, got, path, msg){\n    if (expected.length != got.length) {\n        msg.msg = Test.AnotherWay._eq_fail_msg(path, \"array length\", expected.length, got.length);\n        return false;\n    }\n    for (var i = 0; i < expected.length; ++i) {\n        if (!Test.AnotherWay._thing_eq(expected[i], got[i], path + \"[\" + i + \"]\", msg)) {\n            return false;\n        }\n    }\n    return true;\n};\nTest.AnotherWay._object_eq = function(expected, got, path, msg){\n    var v;\n    for (v in expected) {\n        if (!(v in got)) {\n            msg.msg = Test.AnotherWay._eq_fail_msg(path + \".\" + v, \"properties\", expected[v], \"undefined\");\n            return false;\n        }\n        if (!Test.AnotherWay._thing_eq(expected[v], got[v], path + \".\" + v, msg)) {\n            return false;\n        }\n    }\n    for (v in got) {\n        if (!(v in expected)) {\n            msg.msg = Test.AnotherWay._eq_fail_msg(path + \".\" + v, \"properties\", \"undefined\", got[v]);\n            return false;\n        }\n    }\n    return true;\n};\n\nTest.AnotherWay._constructor_name = function(x){\n    if (x == null) {\n        return \"\";\n    }\n    var s = \"unknown\";\n    try {\n        s = typeof(x.constructor);\n        if (s != \"unknown\") {\n            s = x.constructor.toString();\n        }\n    } \n    catch (e) {\n        s = \"unknown\";\n    }\n    if (s == \"unknown\") {\n        var is_array = true;\n        var index = 0;\n        for (i in x) {\n            if (i != index) {\n                is_array = false;\n            }\n            ++index;\n        }\n        return is_array ? \"Array\" : \"Object\"; // for empty arrays/objects, this will be wrong half the time\n    }\n    else \n        if (s.match(/^\\s*function\\s+(\\w+)\\s*\\(/)) {\n            return RegExp.$1;\n        }\n        else {\n            var c = '';\n            switch (typeof x) {\n                case 'string':\n                    c = 'String';\n                    break;\n                case 'object':\n                    c = 'Object';\n                    break;\n                default:\n                    c = '';\n            }\n            return c;\n        }\n};\nTest.AnotherWay._is_array = function(x){\n    return Test.AnotherWay._constructor_name(x) == \"Array\";\n};\n\nTest.AnotherWay._is_value_type = function(x){\n    cn = Test.AnotherWay._constructor_name(x);\n    return cn == \"Number\" || cn == \"String\" || cn == \"Boolean\" || cn == \"Date\";\n};\n\nTest.AnotherWay._thing_eq = function(expected, got, path, msg){\n    if (expected == null && got == null) {\n        return true;\n    }\n    else \n        if ((expected == null && got != null) || (expected != null && got == null)) {\n            msg.msg = Test.AnotherWay._eq_fail_msg(path, \"values\", expected, got);\n            return false;\n        }\n        else {\n            var expected_cn = Test.AnotherWay._constructor_name(expected);\n            var got_cn = Test.AnotherWay._constructor_name(got);\n            if (expected_cn != got_cn) {\n                msg.msg = Test.AnotherWay._eq_fail_msg(path, \"types\", expected_cn, got_cn);\n                return false;\n            }\n            else {\n                if (Test.AnotherWay._is_array(expected)) {\n                    return Test.AnotherWay._array_eq(expected, got, path, msg);\n                }\n                else \n                    if (Test.AnotherWay._is_value_type(expected)) {\n                        if (expected != got) {\n                            msg.msg = Test.AnotherWay._eq_fail_msg(path, \"values\", expected, got);\n                            return false;\n                        }\n                        else {\n                            return true;\n                        }\n                    }\n                    else { // just a plain object\n                        return Test.AnotherWay._object_eq(expected, got, path, msg);\n                    }\n            }\n        }\n};\n\nTest.AnotherWay._test_object_t.prototype.eq = function(got, expected, name){\n    var msg = {};\n    if (Test.AnotherWay._thing_eq(expected, got, \"\", msg)) {\n        this.ok(1, name);\n    }\n    else {\n        this.fail(name + \". \" + msg.msg);\n    }\n};\n\nTest.AnotherWay._test_object_t.prototype.like = function(got, expected, name){\n    if (got.match(expected) != null) {\n        this.ok(1, name);\n    }\n    else {\n        this.fail(name + \": got \" + got + \", but expected it to match: \" + expected);\n    }\n};\n\nTest.AnotherWay._g_html_eq_span = null;\nTest.AnotherWay._html_eq_string_to_node = function(string_or_node, what, msg){\n    if (string_or_node.nodeType != null) {\n        string_or_node = Test.AnotherWay._html_eq_node_to_string(string_or_node); // double trip - to make properties assigned in scripts available as html node attributes\n    }\n    if (Test.AnotherWay._g_html_eq_span == null) {\n        Test.AnotherWay._g_html_eq_span = document.createElement(\"span\");\n    }\n    Test.AnotherWay._g_html_eq_span.innerHTML = string_or_node;\n    if (Test.AnotherWay._g_html_eq_span.childNodes.length != 1) {\n        msg.msg = \"bad \" + what + \" html string given (should contain exactly one outermost element): \" + string_or_node;\n    }\n    return Test.AnotherWay._g_html_eq_span.childNodes[0].cloneNode(true);\n};\n\nTest.AnotherWay._html_eq_node_to_string = function(node){\n    if (Test.AnotherWay._g_html_eq_span == null) {\n        Test.AnotherWay._g_html_eq_span = document.createElement(\"span\");\n    }\n    Test.AnotherWay._g_html_eq_span.innerHTML = \"\";\n    if (node.outerHTML != null) {\n        Test.AnotherWay._g_html_eq_span.innerHTML = node.outerHTML;\n    }\n    else {\n        var clone = node.cloneNode(true);\n        var node = Test.AnotherWay._g_html_eq_span;\n        if (node.ownerDocument && node.ownerDocument.importNode) {\n            if (node.ownerDocument != clone.ownerDocument) {\n                clone = node.ownerDocument.importNode(clone, true);\n            }\n        }\n        node.appendChild(clone);\n    }\n    return Test.AnotherWay._g_html_eq_span.innerHTML;\n};\n\nTest.AnotherWay._html_eq_path_msg = function(path){\n    var msg = \"\";\n    for (var i = 0; i < path.length; ++i) {\n        msg += \" [node \" + path[i].node;\n        if (path[i].id != null && path[i].id != \"\") {\n            msg += \" id \" + path[i].id;\n        }\n        else \n            if (path[i].index != null) {\n                msg += \" at index \" + path[i].index;\n            }\n        msg += \"] \";\n    }\n    return msg;\n};\n\nTest.AnotherWay._html_eq_fail_msg = function(path, what, expected, got){\n    return Test.AnotherWay._html_eq_path_msg(path) + \": \" + what + \" differ: got \" + got + \", but expected \" + expected;\n};\n\nTest.AnotherWay._html_eq_remove_blank = function(text){\n    if (text == null) {\n        return \"\";\n    }\n    else \n        if (text.match(\"^(\\\\s*)(.*\\\\S)(\\\\s*)$\")) {\n            return RegExp.$2;\n        }\n        else \n            if (text.match(\"\\s*\")) {\n                return \"\";\n            }\n    return text;\n};\n\nTest.AnotherWay._html_eq_remove_blank_nodes = function(node){\n    var to_remove = [];\n    for (var child = node.firstChild; child != null; child = child.nextSibling) {\n        if (child.nodeType == 3) {\n            var value = Test.AnotherWay._html_eq_remove_blank(child.nodeValue);\n            if (value == \"\") {\n                to_remove.push(child);\n            }\n            else {\n                child.nodeValue = value;\n            }\n        }\n    }\n    for (var i = 0; i < to_remove.length; ++i) {\n        node.removeChild(to_remove[i]);\n    }\n};\n\nTest.AnotherWay._html_node_type_text = function(node_type){\n    if (node_type == 1) {\n        return \"1 (html element)\";\n    }\n    else \n        if (node_type == 3) {\n            return \"3 (text)\";\n        }\n        else {\n            return node_type;\n        }\n};\n\nTest.AnotherWay._html_eq_node = function(expected, got, path, msg, expected_loc_base, got_loc_base){\n    if (expected.nodeType != got.nodeType) {\n        msg.msg = Test.AnotherWay._html_eq_fail_msg(path, \"node types\", Test.AnotherWay._html_node_type_text(expected.nodeType), Test.AnotherWay._html_node_type_text(got.nodeType));\n        return false;\n    }\n    else \n        if (expected.nodeType == 3) {\n            if (expected.nodeValue != got.nodeValue) {\n                msg.msg = Test.AnotherWay._html_eq_fail_msg(path, \"text\", expected.nodeValue, got.nodeValue);\n                return false;\n            }\n        }\n        else \n            if (expected.nodeType == 1) {\n                if (expected.nodeName != got.nodeName) {\n                    msg.msg = Test.AnotherWay._html_eq_fail_msg(path, \"node names\", expected.nodeName, got.nodeName);\n                    return false;\n                }\n                var expected_attrs = {};\n                var got_attrs = {};\n                var i;\n                var a;\n                for (i = 0; i < expected.attributes.length; ++i) {\n                    a = expected.attributes[i];\n                    if (a.specified) {\n                        expected_attrs[a.name] = 1;\n                    }\n                }\n                for (i = 0; i < got.attributes.length; ++i) {\n                    a = got.attributes[i];\n                    if (a.specified) {\n                        got_attrs[a.name] = 1;\n                    }\n                }\n                for (a in expected_attrs) {\n                    if (!(a in got_attrs)) {\n                        msg.msg = Test.AnotherWay._html_eq_path_msg(path) + \": attribute sets differ: expected attribute \" + a + \" is missing\";\n                        return false;\n                    }\n                }\n                for (a in got_attrs) {\n                    if (!(a in expected_attrs)) {\n                        msg.msg = Test.AnotherWay._html_eq_path_msg(path) + \": attribute sets differ: got extra attribute \" + a;\n                        return false;\n                    }\n                }\n                for (a in expected_attrs) {\n                    var expected_value = expected.getAttribute(a);\n                    var got_value = got.getAttribute(a);\n                    if (typeof(expected_value) == \"string\" && typeof(got_value) == \"string\") {\n                        expected_value = Test.AnotherWay._html_eq_remove_blank(expected_value);\n                        got_value = Test.AnotherWay._html_eq_remove_blank(got_value);\n                        var ok = expected_value == got_value;\n                        if (!ok && (a == \"href\" || a == \"HREF\")) { // try relative hrefs\n                            var expected_relative_value = expected_value;\n                            if (expected_loc_base != null && expected_value.substring(0, expected_loc_base.length) == expected_loc_base) {\n                                expected_relative_value = expected_value.substring(expected_loc_base.length);\n                            }\n                            var got_relative_value = got_value;\n                            if (got_loc_base != null && got_value.substring(0, got_loc_base.length) == got_loc_base) {\n                                got_relative_value = got_value.substring(got_loc_base.length);\n                            }\n                            ok = expected_relative_value == got_relative_value;\n                        }\n                        if (!ok) {\n                            msg.msg = Test.AnotherWay._html_eq_fail_msg(path, \"attribute \" + a + \" values\", expected_value, got_value);\n                            return false;\n                        }\n                    }\n                    else \n                        if (typeof(expected_value) == \"function\" && typeof(got_value) == \"function\") {\n                            expected_value = expected_value.toString();\n                            got_value = got_value.toString();\n                            if (expected_value != got_value) {\n                                msg.msg = Test.AnotherWay._html_eq_fail_msg(path, \"attribute \" + a + \" values\", expected_value, got_value);\n                                return false;\n                            }\n                        }\n                        else {\n                            var value_msg = {};\n                            if (!Test.AnotherWay._thing_eq(expected_value, got_value, \"\", value_msg)) {\n                                msg.msg = Test.AnotherWay._html_eq_path_msg(path) + \": attribute \" + a + \" values differ: \" + value_msg.msg;\n                                return false;\n                            }\n                        }\n                }\n                Test.AnotherWay._html_eq_remove_blank_nodes(expected);\n                Test.AnotherWay._html_eq_remove_blank_nodes(got);\n                var expected_length = expected.childNodes.length;\n                var got_length = got.childNodes.length;\n                if (expected_length < got_length) {\n                    msg.msg = Test.AnotherWay._html_eq_path_msg(path) + \": got \" + (got_length - expected_length) + \" extra child nodes\";\n                    return false;\n                }\n                else \n                    if (expected_length > got_length) {\n                        msg.msg = Test.AnotherWay._html_eq_path_msg(path) + \": expected \" + (expected_length - got_length) + \" more child nodes\";\n                        return false;\n                    }\n                    else {\n                        for (i = 0; i < expected_length; ++i) {\n                            var expected_node = expected.childNodes[i];\n                            path.push({\n                                node: expected_node.nodeName,\n                                id: expected_node.id,\n                                index: i\n                            });\n                            var eq = Test.AnotherWay._html_eq_node(expected_node, got.childNodes[i], path, msg, expected_loc_base, got_loc_base);\n                            path.pop();\n                            if (!eq) {\n                                return false;\n                            }\n                        }\n                    }\n            }\n    return true;\n};\n\nTest.AnotherWay._html_eq_get_loc_base = function(node){\n    var loc_base = document.location;\n    if (node.ownerDocument != null) {\n        loc_base = node.ownerDocument.location;\n    }\n    if (loc_base != null) {\n        loc_base = loc_base.href;\n        var slash_pos = loc_base.lastIndexOf(\"/\");\n        if (slash_pos != -1) {\n            loc_base = loc_base.substring(0, slash_pos + 1);\n        }\n    }\n    return loc_base;\n};\n\nTest.AnotherWay._test_object_t.prototype.html_eq = function(got, expected, name){\n    var msg = {};\n    var expected_node = Test.AnotherWay._html_eq_string_to_node(expected, \"expected\", msg);\n    if (msg.msg != null) {\n        this.fail(name + \" html_eq: \" + msg.msg);\n    }\n    else {\n        var got_node = Test.AnotherWay._html_eq_string_to_node(got, \"got\", msg);\n        if (msg.msg != null) {\n            this.fail(name + \" html_eq: \" + msg.msg);\n        }\n        else {\n            var expected_loc_base = Test.AnotherWay._html_eq_get_loc_base(expected);\n            var got_loc_base = Test.AnotherWay._html_eq_get_loc_base(got);\n            if (Test.AnotherWay._html_eq_node(expected_node, got_node, [], msg, expected_loc_base, got_loc_base)) {\n                this.ok(1, name);\n            }\n            else {\n                var msg = name + \" html_eq \" + msg.msg;\n                var expected_str = Test.AnotherWay._html_eq_node_to_string(expected_node);\n                var got_str = Test.AnotherWay._html_eq_node_to_string(got_node);\n                msg += \".\\n got html: \" + got_str;\n                msg += \".\\n expected html: \" + expected_str;\n                this.fail(msg);\n            }\n        }\n    }\n};\n\nTest.AnotherWay._debug_pane_print = function(msg){\n    var d = new Date();\n    var p = document.createElement(\"p\");\n    p.appendChild(document.createTextNode(d.toLocaleTimeString() + \" \" + msg));\n    var debug_pane = document.getElementById(\"debug\");\n    debug_pane.appendChild(p);\n    var debug_tab = document.getElementById(\"debug_tab\");\n    var results_tab = document.getElementById(\"results_tab\");\n    debug_tab.style.visibility = \"visible\";\n    results_tab.style.visibility = \"visible\";\n};\n\nTest.AnotherWay._test_object_t.prototype.debug_print = function(msg){\n    Test.AnotherWay._debug_pane_print(this.name + \": \" + msg);\n};\n\nTest.AnotherWay._test_object_t.prototype.delay_call = function(){\n    var timeout_ms = 200;\n    for (var i = 0; i < arguments.length; ++i) {\n        if (typeof(arguments[i]) != \"function\") {\n            timeout_ms = 1000 * arguments[i];\n        }\n        else {\n            var action = {\n                action_kind: \"call\",\n                call_delay_milliseconds: timeout_ms,\n                call_fn: arguments[i]\n            };\n            this.delay_total_milliseconds_left += Test.AnotherWay._action_estimate_milliseconds(action);\n            this.delay_actions.push(action);\n        }\n    }\n};\n\nTest.AnotherWay._test_object_t.prototype.open_window = function(url, fn, timeout_seconds){\n    if (timeout_seconds == null) {\n        timeout_seconds = 4;\n    }\n    var no_close = document.getElementById(\"dont_close_test_windows\");\n    var action = {\n        action_kind: \"window\",\n        wnd_url: url.toString() + (window.location.search || \"\"),\n        wnd_wnd: null,\n        wnd_fn: fn,\n        wnd_timeout_milliseconds: timeout_seconds * 1000,\n        wnd_no_close: no_close.checked\n    };\n    this.delay_total_milliseconds_left += Test.AnotherWay._action_estimate_milliseconds(action);\n    this.delay_actions.push(action);\n};\n\nTest.AnotherWay._test_object_t.prototype.replay_events = function(wnd, events){\n    if (Test.AnotherWay._g_no_record_msg != null) {\n        this.fail(\"replay_events: \" + Test.AnotherWay._g_no_record_msg);\n    }\n    else {\n        var action = {\n            action_kind: \"replay\",\n            replay_wnd: wnd,\n            replay_events: events.events,\n            replay_event_i: null,\n            replay_checkpoints: events.checkpoints\n        };\n        this.delay_total_milliseconds_left += Test.AnotherWay._action_estimate_milliseconds(action);\n        this.delay_actions.push(action);\n    }\n};\n\nTest.AnotherWay._action_estimate_milliseconds = function(action){\n    var ms = 0;\n    if (action.action_kind == \"call\") {\n        ms = action.call_delay_milliseconds;\n    }\n    else \n        if (action.action_kind == \"window\") {\n            ms = 0;\n        }\n        else \n            if (action.action_kind == \"replay\") {\n                ms = 0;\n                for (var i = 0; i < action.replay_events.length; ++i) {\n                    ms += action.replay_events[i][\"time\"] - 0;\n                }\n            }\n    return ms;\n};\n\nTest.AnotherWay._g_timeout_granularity = 200;\nTest.AnotherWay._g_tests_queue = []; // vector of { url: string, test_objects : array of test_object_t, test_object_i: int, wait_msg: <p> object, loading_timeout_milliseconds: int, timeout_id: id }\nTest.AnotherWay._run_test_page = function(id, called_from_outside){\n    if (id.match(/^test(\\d+)/)) {\n        id = RegExp.$1;\n        Test.AnotherWay._g_tests_queue.push({\n            url: Test.AnotherWay._g_test_page_urls[id].url,\n            convention: Test.AnotherWay._g_test_page_urls[id].convention,\n            test_objects: []\n        });\n        if (Test.AnotherWay._g_tests_queue.length == 1) {\n            if (!called_from_outside) {\n                Test.AnotherWay._g_tests_queue[0].suppress_outside_path_correction = true;\n            }\n            Test.AnotherWay._start_loading_page();\n        }\n    }\n};\n\nTest.AnotherWay._load_next_page = function(){\n    Test.AnotherWay._g_tests_queue.splice(0, 1);\n    if (Test.AnotherWay._g_tests_queue.length > 0) {\n        Test.AnotherWay._start_loading_page();\n    }\n    else {\n        if (!Test.AnotherWay._g_test_frame_no_clear) {\n            Test.AnotherWay._g_test_iframe.location.replace(\"about:blank\");\n        }\n    }\n};\n\nTest.AnotherWay._g_opera_path_correction = null; // ugly wart to support opera\nTest.AnotherWay._g_outside_path_correction = null; // ugly wart to accomodate Opera and Mozilla, where relative url relates to the directory where the page that calls this function is located\nTest.AnotherWay._set_iframe_location = function(iframe, loc, outside_path_correction){\n    var proto_end = loc.indexOf(\"://\");\n    if (proto_end != -1) { // otherwise, it's safe to assume (for Opera, Mozilla and IE ) that loc will be treated as relative\n        var main_loc = window.location.href;\n        var host_end = loc.substring(proto_end + 3).indexOf(\"/\");\n        var ok = false;\n        if (host_end != -1) {\n            var loc_origin = loc.substring(0, proto_end + 3 + host_end + 1);\n            if (main_loc.length >= loc_origin.length && main_loc.substring(0, loc_origin.length) == loc_origin) {\n                ok = true;\n            }\n        }\n        if (!ok) {\n            return {\n                msg: \"test pages may have only urls with the same origin as \" + main_loc\n            };\n        }\n    }\n    if (window.opera != null && window.location.protocol == \"file:\" && loc.indexOf(\":\") == -1) {\n        var base = window.location.href;\n        var q_pos = base.indexOf(\"?\");\n        if (q_pos != -1) {\n            base = base.substring(0, q_pos);\n        }\n        var slash_pos = base.lastIndexOf(\"/\");\n        if (slash_pos != -1) {\n            base = base.substring(0, slash_pos + 1);\n            Test.AnotherWay._g_opera_path_correction = base;\n            loc = base + loc;\n        }\n    }\n    if (outside_path_correction != null) {\n        var pos = loc.indexOf(outside_path_correction);\n        if (pos == 0) {\n            loc = loc.substring(outside_path_correction.length + 1);\n        }\n    }\n    if (iframe.location != null) {\n        iframe.location.replace(loc);\n    }\n    else {\n        iframe.src = loc;\n    }\n    return {};\n};\n\nTest.AnotherWay._start_loading_page = function(){\n    var test_page = Test.AnotherWay._g_tests_queue[0];\n    test_page.loading_timeout_milliseconds = 12000;\n    test_page.timeout_id = setTimeout(Test.AnotherWay._loading_timeout, Test.AnotherWay._g_timeout_granularity);\n    test_page.wait_msg = Test.AnotherWay._print_counter_result(test_page.url, \"loading...\", test_page.loading_timeout_milliseconds, \"loading\");\n    if (test_page.convention == \"jsan\") {\n        Test.AnotherWay._g_test_object_for_jsan = new Test.AnotherWay._test_object_t(test_page.url);\n    }\n    var outside_path_correction = null;\n    if (Test.AnotherWay._g_outside_path_correction != null && !test_page.suppress_outside_path_correction) {\n        outside_path_correction = Test.AnotherWay._g_outside_path_correction;\n    }\n    var result = Test.AnotherWay._set_iframe_location(Test.AnotherWay._g_test_iframe, test_page.url, outside_path_correction);\n    if (result.msg != null) {\n        Test.AnotherWay._unprint_result(test_page.wait_msg);\n        Test.AnotherWay._print_result(test_page.url, result.msg, \"badtest\", null);\n        Test.AnotherWay._load_next_page();\n    }\n};\n\nTest.AnotherWay._loading_timeout = function(){\n    var test_page = Test.AnotherWay._g_tests_queue[0];\n    test_page.loading_timeout_milliseconds -= Test.AnotherWay._g_timeout_granularity;\n    if (test_page.loading_timeout_milliseconds > 0) {\n        Test.AnotherWay._update_msg_counter(test_page.wait_msg, (test_page.loading_timeout_milliseconds / 1000).toFixed());\n        test_page.timeout_id = setTimeout(Test.AnotherWay._loading_timeout, Test.AnotherWay._g_timeout_granularity);\n    }\n    else {\n        Test.AnotherWay._unprint_result(test_page.wait_msg);\n        Test.AnotherWay._print_result(test_page.url, \"Unable to load test page. Timeout expired\", \"badtest\", null);\n        Test.AnotherWay._load_next_page();\n    }\n};\n\nTest.AnotherWay._strip_query_and_hash = function(s){\n    var i = s.lastIndexOf(\"#\");\n    if (i != -1) {\n        s = s.substring(0, i);\n    }\n    i = s.lastIndexOf(\"?\");\n    if (i != -1) {\n        s = s.substring(0, i);\n    }\n    return s;\n};\n\nTest.AnotherWay._is_url_loaded = function(url, wnd){\n    var loaded = false;\n    if (wnd != null && wnd.location != null) {\n        var location_s = \"\";\n        location_s += wnd.location;\n        if (location_s != \"\") {\n            var pathname = wnd.location.pathname;\n            var expected_url = url;\n            var i = expected_url.lastIndexOf(\"#\");\n            if (i != -1) {\n                expected_url = expected_url.substring(0, i);\n            }\n            i = expected_url.lastIndexOf(\"?\");\n            if (i != -1) {\n                expected_url = expected_url.substring(0, i);\n            }\n            i = expected_url.lastIndexOf(\"/\");\n            if (i != -1 && i != expected_url.length - 1) {\n                expected_url = expected_url.substring(i + 1);\n            }\n            i = pathname.indexOf(expected_url);\n            if (wnd.location.href == url || (i != -1 && i == pathname.length - expected_url.length)) {\n                if ( /*window.opera==null*/wnd.document.readyState == null || wnd.document.readyState == \"complete\") { // for opera (and IE?), getElementById does not work until..\n                    loaded = true;\n                }\n            }\n        }\n    }\n    return loaded;\n};\nTest.AnotherWay._test_page_onload = function(){\n    if (Test.AnotherWay._g_tests_queue.length == 0) {\n        return;\n    }\n    var test_page = Test.AnotherWay._g_tests_queue[0];\n    if (!Test.AnotherWay._is_url_loaded(test_page.url, Test.AnotherWay._g_test_iframe)) {\n        return;\n    }\n    clearTimeout(test_page.timeout_id);\n    Test.AnotherWay._unprint_result(test_page.wait_msg);\n    \n    if (test_page.convention == \"anotherway\") {\n        if (typeof(Test.AnotherWay._g_test_iframe.document.scripts) != 'undefined') { // IE\n            for (var i = 0; i < Test.AnotherWay._g_test_iframe.document.scripts.length; ++i) {\n                var script_text = Test.AnotherWay._g_test_iframe.document.scripts[i].text;\n                var fun_sig = \"function test\";\n                var fun_start = script_text.indexOf(fun_sig);\n                \n                while (fun_start != -1) {\n                    script_text = script_text.substring(fun_start, script_text.length);\n                    var fun_end = script_text.indexOf('(');\n                    var fun_name = script_text.substring(\"function \".length, fun_end);\n                    var whitespace = fun_name.indexOf(' ');\n                    if (whitespace >= 0) {\n                        fun_name = fun_name.substring(0, whitespace);\n                    }\n                    test_page.test_objects.push(new Test.AnotherWay._test_object_t(fun_name));\n                    script_text = script_text.substring(fun_end, script_text.length);\n                    fun_start = script_text.indexOf(fun_sig);\n                }\n            }\n        }\n        else { // otherwise (not IE) it ought to work like this\n            for (var i in Test.AnotherWay._g_test_iframe) {\n                if (i == \"innerWidth\" || i == \"innerHeight\" || i == \"sessionStorage\") {\n                    continue;\n                }\n                if (typeof(Test.AnotherWay._g_test_iframe[i]) == 'function') {\n                    if (i.substring(0, 4) == \"test\") {\n                        test_page.test_objects.push(new Test.AnotherWay._test_object_t(i));\n                    }\n                }\n            }\n        }\n    }\n    else \n        if (test_page.convention == \"jsan\") {\n            test_page.test_objects.push(Test.AnotherWay._g_test_object_for_jsan);\n        }\n    \n    if (test_page.test_objects.length == 0) {\n        Test.AnotherWay._print_result(test_page.url, \"No test functions defined in the page\", \"badtest\", null);\n        Test.AnotherWay._load_next_page();\n        return;\n    }\n    \n    test_page.wait_msg = Test.AnotherWay._print_result(test_page.url, \"running tests..<span class=\\\"counter\\\">\" + test_page.test_objects.length + \"</span>\", \"running\", null);\n    \n    test_page.test_object_i = 0;\n    Test.AnotherWay._run_more_tests();\n};\n\nTest.AnotherWay._handle_exception = function(o, e, title){\n    var s = title + \": \" + typeof(e) + \": \";\n    if (e.message != null) {\n        s += e.message;\n    }\n    else \n        if (e.description != null) {\n            s += e.description;\n        }\n        else {\n            s += e.toString();\n        }\n    o.exception = s;\n    s = [];\n    if (e.stack) {\n        var lines = e.stack.split(\"\\n\");\n        for (var i = 0; i < lines.length; ++i) {\n            if (lines[i].match(/(\\w*)\\(([^\\)]*)\\)@(.*):([^:]*)$/)) {\n                var func_name = RegExp.$1;\n                if (func_name.length == 0) {\n                    func_name = \"<anonymous>\";\n                }\n                s.push(\"in \" + func_name + \"( \" + RegExp.$2 + \") at \" + RegExp.$3 + \" line \" + RegExp.$4 + \"\\n\");\n            }\n        }\n    }\n    o.exception_stack = s;\n};\n\nTest.AnotherWay._run_more_tests = function(){\n    var test_page = Test.AnotherWay._g_tests_queue[0];\n    while (test_page.test_object_i < test_page.test_objects.length) {\n        Test.AnotherWay._update_msg_counter(test_page.wait_msg, (1 + test_page.test_object_i) + \"/\" + test_page.test_objects.length);\n        var o = test_page.test_objects[test_page.test_object_i];\n        if (test_page.convention == \"anotherway\") {\n            try {\n                Test.AnotherWay._g_test_iframe[o.name](o);\n            } \n            catch (e) {\n                Test.AnotherWay._handle_exception(o, e, \"\");\n            }\n        } // for \"jsan\" convention, test has run already\n        if (o.delay_actions.length > 0 || o.wait_result_milliseconds > 0) {\n            o.delay_total_milliseconds_left += o.wait_result_milliseconds;\n            Test.AnotherWay._delay_actions_timeout();\n            return;\n        }\n        ++test_page.test_object_i;\n    }\n    Test.AnotherWay._unprint_result(test_page.wait_msg);\n    Test.AnotherWay._print_result(test_page.url, null, null, test_page.test_objects);\n    Test.AnotherWay._load_next_page();\n};\n\nTest.AnotherWay._delay_actions_timeout = function(){\n    var test_page = Test.AnotherWay._g_tests_queue[0];\n    var test_object = test_page.test_objects[test_page.test_object_i];\n    var finished = true;\n    if (test_object.delay_action_i == null) {\n        test_object.delay_action_i = -1;\n    }\n    else {\n        var milliseconds_passed = (new Date()).getTime() - test_object.delay_prev_timer_time;\n        test_object.delay_current_milliseconds_left -= milliseconds_passed;\n        test_object.delay_total_milliseconds_left -= milliseconds_passed;\n        finished = Test.AnotherWay._delay_continue_action(test_object, milliseconds_passed);\n    }\n    while (finished && test_object.delay_action_i < test_object.delay_actions.length) {\n        ++test_object.delay_action_i; // start next action\n        finished = Test.AnotherWay._delay_start_action(test_object);\n    }\n    if (test_object.delay_action_i <= test_object.delay_actions.length) { // any more actions left ?\n        test_object.delay_prev_timer_time = (new Date()).getTime();\n        var next_timeout = Test.AnotherWay._g_timeout_granularity;\n        if (test_object.delay_current_milliseconds_left < next_timeout) {\n            next_timeout = test_object.delay_current_milliseconds_left;\n        }\n        if (test_object.second_wait_msg != null) {\n            Test.AnotherWay._update_msg_counter(test_object.second_wait_msg, (test_object.delay_total_milliseconds_left / 1000).toFixed());\n        }\n        setTimeout(Test.AnotherWay._delay_actions_timeout, next_timeout);\n    }\n    else { // no more actions left. run the next test.\n        if (test_object.second_wait_msg != null) {\n            Test.AnotherWay._unprint_result(test_object.second_wait_msg);\n            test_object.second_wait_msg = null;\n        }\n        ++test_page.test_object_i;\n        Test.AnotherWay._run_more_tests();\n    }\n};\n\nTest.AnotherWay._delay_start_action = function(test_object){\n    var finished = false;\n    var wait_msg = \"\";\n    if (test_object.delay_action_i == test_object.delay_actions.length) {\n        if (test_object.wait_result_milliseconds > 0) {\n            test_object.delay_current_milliseconds_left = test_object.wait_result_milliseconds; // wait for result\n            wait_msg = \"waiting for results..\";\n        }\n        else {\n            ++test_object.delay_action_i; // dont wait for result\n        }\n    }\n    else {\n        var action = test_object.delay_actions[test_object.delay_action_i];\n        if (action.action_kind == \"call\") {\n            test_object.delay_current_milliseconds_left = action.call_delay_milliseconds;\n            wait_msg = \"performing delayed calls..\";\n        }\n        else \n            if (action.action_kind == \"window\") {\n                if (Test.AnotherWay._g_opera_path_correction != null && action.wnd_url.indexOf(\":\") == -1) {\n                    action.wnd_url = Test.AnotherWay._g_opera_path_correction + action.wnd_url;\n                }\n                action.wnd_wnd = window.open(action.wnd_url, \"_blank\");\n                if (action.wnd_wnd == null) {\n                    finished = true;\n                    test_object.fail(\"unable to open window for \" + action.wnd_url);\n                }\n                else {\n                    test_object.delay_current_milliseconds_left = action.wnd_timeout_milliseconds;\n                    wait_msg = \"opening window..\";\n                }\n            }\n            else \n                if (action.action_kind == \"replay\") {\n                    if (action.replay_events.length == 0) {\n                        finished = true;\n                    }\n                    else {\n                        action.replay_event_i = 0;\n                        test_object.delay_current_milliseconds_left = action.replay_events[0][\"time\"];\n                        wait_msg = \"replaying events..\";\n                    }\n                }\n    }\n    if (test_object.second_wait_msg != null) {\n        Test.AnotherWay._unprint_result(test_object.second_wait_msg);\n    }\n    if (wait_msg != \"\") {\n        var test_page = Test.AnotherWay._g_tests_queue[0];\n        test_object.second_wait_msg = Test.AnotherWay._print_counter_result(test_page.url, wait_msg, test_object.delay_total_milliseconds_left, \"waiting\");\n    }\n    else {\n        test_object.second_wait_msg = null;\n    }\n    return finished;\n};\nTest.AnotherWay._delay_continue_action = function(test_object, milliseconds_passed){\n    var finished = test_object.delay_current_milliseconds_left <= 0;\n    if (test_object.delay_action_i == test_object.delay_actions.length) { // action is \"waiting for results\"\n        if (test_object.n_plan != null && test_object.n_plan == test_object.n_ok + test_object.n_fail) {\n            finished = true; // if all assertions results are recorded, don't wait any more\n        }\n        if (finished) {\n            ++test_object.delay_action_i; // move on to the next test\n        }\n    }\n    else {\n        var action = test_object.delay_actions[test_object.delay_action_i];\n        if (action.action_kind == \"call\") {\n            if (finished) {\n                try {\n                    action.call_fn();\n                } \n                catch (e) {\n                    Test.AnotherWay._handle_exception(test_object, e, \"in delay_call\");\n                }\n            }\n        }\n        else \n            if (action.action_kind == \"window\") {\n                test_object.delay_total_milliseconds_left += milliseconds_passed; // for \"window\", the countdown is suspended since it's unknown how long it will take\n                if (Test.AnotherWay._is_url_loaded(action.wnd_url, action.wnd_wnd)) {\n                    try {\n                        action.wnd_fn(action.wnd_wnd);\n                    } \n                    catch (e) {\n                        Test.AnotherWay._handle_exception(test_object, e, \"in open_window function call\");\n                    }\n                    finished = true;\n                }\n                else \n                    if (finished) {\n                        test_object.fail(\"unable to open window for url '\" + action.wnd_url + \"'. timeout expired\");\n                    }\n            }\n            else \n                if (action.action_kind == \"replay\") {\n                    if (finished) {\n                        Test.AnotherWay._delay_replay_event(test_object, action.replay_wnd, action.replay_events[action.replay_event_i], action.replay_checkpoints);\n                        ++action.replay_event_i;\n                        finished = action.replay_event_i == action.replay_events.length;\n                        if (!finished) {\n                            test_object.delay_current_milliseconds_left = action.replay_events[action.replay_event_i][\"time\"];\n                        }\n                    }\n                }\n    }\n    return finished;\n};\n\nTest.AnotherWay._delay_replay_event = function(test_object, wnd, event, checkpoints){\n    if (event.type == \"_checkpoint\") {\n        var checkpoint_n = event.which;\n        var prev_n_fail = test_object.n_fail;\n        checkpoints[checkpoint_n](test_object, wnd);\n        var flash_color = prev_n_fail == test_object.n_fail ? \"#2f2\" : \"#f22\";\n        Test.AnotherWay._record_flash_border(flash_color);\n    }\n    else \n        if (event.type == \"click\" || event.type == \"mouseover\" || event.type == \"mouseout\" || event.type == \"mousemove\" || event.type == \"mousedown\" || event.type == \"mouseup\") {\n            var target = Test.AnotherWay._record_node_path_to_node(event[\"target\"], wnd.document);\n            if (target != null) {\n                Test.AnotherWay._record_control_update_highlight(target, \"ball\", event);\n                var e = wnd.document.createEvent(\"MouseEvents\");\n                var related_target = Test.AnotherWay._record_node_path_to_node(event[\"relatedTarget\"], wnd.document);\n                e.initMouseEvent(event[\"type\"], event[\"cancelable\"], event[\"bubbles\"], wnd.document.defaultView, event[\"detail\"], event[\"screenX\"], event[\"screenY\"], event[\"clientX\"], event[\"clientY\"], event[\"ctrlKey\"], event[\"altKey\"], event[\"shiftKey\"], event[\"metaKey\"], event[\"button\"], Test.AnotherWay._record_node_path_to_node(event[\"relatedTarget\"], wnd.document));\n                e.passThroughRelatedTarget = related_target;\n                target.dispatchEvent(e);\n            }\n        }\n        else \n            if (event.type == \"keyup\" || event.type == \"keydown\" || event.type == \"keypress\") {\n                var e = wnd.document.createEvent(\"KeyboardEvents\"); // forget it. Apparently it's not supported neither by mozilla nor by opera.\n                e.initKeyboardEvent(event[\"type\"], event[\"cancelable\"], event[\"bubbles\"], wnd.document.defaultView, event[\"which\"], event[\"which\"], event[\"ctrlKey\"], event[\"altKey\"], event[\"shiftKey\"], event[\"metaKey\"], false);\n                wnd.document.dispatchEvent(e);\n            }\n};\n\nTest.AnotherWay._print_counter_result = function(url, msg, milliseconds, style){\n    return Test.AnotherWay._print_result(url, msg + \"<span class=\\\"counter\\\">\" + (milliseconds / 1000).toFixed() + \"</span>\", style, null);\n};\n\nTest.AnotherWay._g_result_count = 0; // for assigning unique ids to result paragraphs\nTest.AnotherWay._g_ok_pages = 0;\nTest.AnotherWay._g_fail_pages = 0;\n\nTest.AnotherWay._print_result = function(url, msg, style, test_objects){\n    var results = document.getElementById(\"results\");\n    var r = results.appendChild(document.createElement(\"p\"));\n    r.id = \"result\" + Test.AnotherWay._g_result_count;\n    ++Test.AnotherWay._g_result_count;\n    r.onclick = Test.AnotherWay._toggle_detail;\n    var text = \"<span class=\\\"bullet\\\">&nbsp;&nbsp;&nbsp;</span>&nbsp;\";\n    if (url != \"\") {\n        text += url + \":  \";\n    }\n    if (msg != null) {\n        text += msg;\n    }\n    if (test_objects != null) {\n        var total_ok = 0;\n        var total_detail_ok = 0;\n        var total_fail = 0;\n        var total_detail_fail = 0;\n        var no_plan = 0;\n        \n        var detail = results.appendChild(document.createElement(\"div\"));\n        \n        if (r.id.match(/^result(\\d+)$/)) {\n            detail.id = \"result_detail\" + RegExp.$1;\n        }\n        \n        for (var i = 0; i < test_objects.length; ++i) {\n            var o = test_objects[i];\n            var p;\n            var p_text;\n            p = document.createElement(\"P\");\n            Test.AnotherWay._set_css_class(p, \"result_detail\");\n            p_text = o.name;\n            if (o.n_fail > 0 || o.exception || (o.n_plan != null && o.n_plan != o.n_ok + o.n_fail) || (o.n_plan == null && o.n_ok == 0 && o.n_fail == 0)) {\n                ++total_fail;\n                p_text += \" <span class=\\\"fail\\\">\";\n                if (o.n_plan != null && o.n_plan != o.n_ok + o.n_fail) {\n                    p_text += \"planned \" + o.n_plan + \" assertions but got \" + (o.n_ok + o.n_fail) + \"; \";\n                }\n                if (o.n_plan == null && o.n_ok == 0 && o.n_fail == 0) {\n                    p_text += \"test did not output anything\";\n                }\n                else {\n                    p_text += \" fail \" + o.n_fail;\n                }\n                p_text += \"</span>\";\n            }\n            else {\n                ++total_ok;\n            }\n            p_text += \" ok \" + o.n_ok;\n            if (o.n_plan == null) {\n                no_plan = 1;\n                p_text += \" <span class=\\\"warning\\\">no plan</span>\";\n            }\n            p.innerHTML = p_text;\n            detail.appendChild(p);\n            if (o.exception) {\n                p = document.createElement(\"P\");\n                Test.AnotherWay._set_css_class(p, \"result_exception_detail\");\n                p.innerHTML = \"<span class=\\\"fail\\\">exception:</span> \" + o.exception;\n                detail.appendChild(p);\n                p = document.createElement(\"P\");\n                Test.AnotherWay._set_css_class(p, \"result_exception_stack_detail\");\n                p.innerHTML = o.exception_stack.join(\"<br/>\");\n                detail.appendChild(p);\n            }\n            for (var ii = 0; ii < o.assertions.length; ++ii) {\n                var oo = o.assertions[ii];\n                var status = oo.ok ? \"ok\" : \"<span class=\\\"fail\\\">fail</span>\";\n                p = document.createElement(\"P\");\n                Test.AnotherWay._set_css_class(p, \"result_micro_detail\");\n                p.innerHTML = status;\n                p.appendChild(document.createTextNode(\" \" + oo.name));\n                detail.appendChild(p);\n            }\n            total_detail_ok += o.n_ok;\n            total_detail_fail += o.n_fail;\n        }\n        if (total_fail || total_detail_fail) {\n            text += \" fail \" + total_fail;\n        }\n        text += \" ok \" + total_ok + \" (detailed:\";\n        if (total_fail || total_detail_fail) {\n            text += \" fail \" + total_detail_fail;\n        }\n        text += \" ok \" + total_detail_ok + \")\";\n        if (no_plan) {\n            text += \" <span class=\\\"warning\\\">no plan</span>\";\n        }\n        style = total_fail == 0 ? \"ok\" : \"fail\";\n        detail.style.display = style == \"fail\" ? \"block\" : \"none\";\n        detail.style.cursor = \"text\";\n    }\n    if (style != null) {\n        Test.AnotherWay._set_css_class(r, style);\n        if (style == \"ok\") {\n            ++Test.AnotherWay._g_ok_pages;\n        }\n        else \n            if (style == \"fail\" || style == \"badtest\") {\n                ++Test.AnotherWay._g_fail_pages;\n            }\n        var pages_total = \"\";\n        if (Test.AnotherWay._g_fail_pages > 0) {\n            pages_total += \" fail \" + Test.AnotherWay._g_fail_pages;\n        }\n        pages_total += \" ok \" + Test.AnotherWay._g_ok_pages;\n        Test.AnotherWay._openlayers_sum_total_detail_ok  = Test.AnotherWay._openlayers_sum_total_detail_ok || 0;\n        Test.AnotherWay._openlayers_sum_total_detail_ok += (total_detail_ok||0);\n        \n        Test.AnotherWay._openlayers_sum_total_detail_fail  = Test.AnotherWay._openlayers_sum_total_detail_fail || 0;\n        Test.AnotherWay._openlayers_sum_total_detail_fail += (total_detail_fail||0);\n        \n        pages_total+=\" (detailed: fail \" + Test.AnotherWay._openlayers_sum_total_detail_fail + \" | ok \" + Test.AnotherWay._openlayers_sum_total_detail_ok + \")\";\n        \n        Test.AnotherWay._update_results_total(pages_total);\n    }\n    r.innerHTML = text;\n    if (results.scrollHeight != null && results.scrollTop != null && results.offsetHeight != null) {\n        results.scrollTop = results.scrollHeight - results.offsetHeight;\n    }\n    if (test_objects != null) {\n        for (var i = 0; i < test_objects.length; ++i) {\n            var actions = test_objects[i].delay_actions;\n            for (var action_i = 0; action_i < actions.length; ++action_i) {\n                var action = actions[action_i];\n                if (action.action_kind == \"window\" && action.wnd_wnd != null && !action.wnd_no_close) {\n                    action.wnd_wnd.close();\n                    action.wnd_wnd = null;\n                }\n            }\n        }\n    }\n    return r;\n};\n\nTest.AnotherWay._unprint_result = function(child){\n    var results = document.getElementById(\"results\");\n    results.removeChild(child);\n};\n\nTest.AnotherWay._toggle_detail = function(){\n    if (this.id.match(/^result(\\d+)$/)) {\n        var detail = document.getElementById(\"result_detail\" + RegExp.$1);\n        if (detail != null) {\n            if (detail.style.display == \"none\") {\n                detail.style.display = \"block\";\n            }\n            else \n                if (detail.style.display == \"block\") {\n                    detail.style.display = \"none\";\n                }\n        }\n    }\n};\n\nTest.AnotherWay._update_msg_counter = function(msg, text){\n    for (var i = 0; i < msg.childNodes.length; ++i) {\n        var item = msg.childNodes[i];\n        if (item.nodeName == \"SPAN\" && Test.AnotherWay._get_css_class(item) == \"counter\") {\n            item.innerHTML = text;\n        }\n    }\n};\n\nTest.AnotherWay._update_results_total = function(msg){\n    var total = document.getElementById(\"total\");\n    if (total) {\n        total.innerHTML = msg;\n    }\n};\n\nTest.AnotherWay._results_clear_onclick = function(){\n    var results = document.getElementById(\"results\");\n    results.innerHTML = \"\";\n    Test.AnotherWay._update_results_total(\"\");\n    Test.AnotherWay._g_ok_pages = 0;\n    Test.AnotherWay._g_fail_pages = 0;\n    Test.AnotherWay._openlayers_sum_total_detail_ok=0;\n    Test.AnotherWay._openlayers_sum_total_detail_fail=0;\n    var debug = document.getElementById(\"debug\");\n    debug.innerHTML = \"\";\n    Test.AnotherWay.reset_running_time();\n};\n\nTest.AnotherWay._get_css_class = function(o){\n    var c = o.getAttribute(\"className\");\n    if (c == null || c == \"\") {\n        c = o.getAttribute(\"class\");\n    }\n    return c;\n};\n\nTest.AnotherWay._set_css_class = function(o, css_class){\n    o.setAttribute(\"className\", css_class);\n    o.setAttribute(\"class\", css_class);\n};\n\nTest.AnotherWay._tab_onclick = function(){\n    var tab = this;\n    var tabs = [document.getElementById(\"debug_tab\"), document.getElementById(\"results_tab\")];\n    var panes = [document.getElementById(\"debug\"), document.getElementById(\"results\")];\n    for (var i = 0; i < tabs.length; ++i) {\n        if (tab == tabs[i]) {\n            Test.AnotherWay._set_css_class(tabs[i], \"active_tab\");\n            panes[i].style.display = \"block\";\n        }\n        else {\n            Test.AnotherWay._set_css_class(tabs[i], \"inactive_tab\");\n            panes[i].style.display = \"none\";\n        }\n    }\n};\nTest.AnotherWay._tab_mouseover = function(){\n    if (Test.AnotherWay._get_css_class(this) == \"inactive_tab\") {\n        Test.AnotherWay._set_css_class(this, \"inactive_mouseover_tab\");\n    }\n};\nTest.AnotherWay._tab_mouseout = function(){\n    if (Test.AnotherWay._get_css_class(this) == \"inactive_mouseover_tab\") {\n        Test.AnotherWay._set_css_class(this, \"inactive_tab\");\n    }\n};\nTest.AnotherWay._record_check_onfocus = function(){\n    var o = this;\n    var check_select = o.type != \"text\";\n    var div = document.getElementById(\"record_div\");\n    var inputs = div.getElementsByTagName(\"input\");\n    for (var i = 0; i < inputs.length; ++i) {\n        var input = inputs[i];\n        if (input.type == \"radio\") {\n            if (input.value == \"select\") {\n                input.checked = check_select;\n            }\n            else \n                if (input.value == \"input\") {\n                    input.checked = !check_select;\n                }\n        }\n    }\n};\n\nTest.AnotherWay._g_no_record_msg = null; // not null - recording is unavailable\nTest.AnotherWay._g_record_timeout_cnt = 0; // opening window for a page for recording\nTest.AnotherWay._g_record_url = null;\nTest.AnotherWay._g_record_wnd = null;\nTest.AnotherWay._g_record_random_id = null; // added to element ids of record_control div so that they do not clash with ids already in the page for which input is recorded\nTest.AnotherWay._g_record_keydown = null; // recording control - which key is down\nTest.AnotherWay._g_record_ctrl_keydown = false;\nTest.AnotherWay._g_record_shift_keydown = false;\nTest.AnotherWay._g_record_control_visible = true; // recording control ui state\nTest.AnotherWay._g_record_started;\nTest.AnotherWay._g_record_paused;\nTest.AnotherWay._g_record_include_mousemove = false;\nTest.AnotherWay._g_record_start_time; // for time references\nTest.AnotherWay._g_record_pause_start_time;\nTest.AnotherWay._g_record_update_time_interval; // showing time in the control ui\nTest.AnotherWay._g_record_waiting_for_results = false; // waiting for results window to open\nTest.AnotherWay._g_record_events; // recorded events\nTest.AnotherWay._g_record_under_cursor; // track element under cursor\nTest.AnotherWay._g_record_checkpoint_count; // for checkpoint numbering\nTest.AnotherWay._g_record_mouse_over_record_control; // for avoiding record control highlight on mouseover\nTest.AnotherWay._g_record_highlighted_element = {\n    element: null,\n    x: null,\n    y: null\n};\n\nTest.AnotherWay._record_control_get_element = function(id){\n    if (Test.AnotherWay._g_record_wnd != null && Test.AnotherWay._g_record_wnd.document != null) {\n        return Test.AnotherWay._g_record_wnd.document.getElementById(id + Test.AnotherWay._g_record_random_id);\n    }\n    else {\n        return null;\n    }\n};\nTest.AnotherWay._record_start_onclick = function() // \"record\" button on the run_tests.html: open a window for a page for which input is recorded\n{\n    if (Test.AnotherWay._g_no_record_msg != null) {\n        alert(Test.AnotherWay._g_no_record_msg);\n        return;\n    }\n    if (Test.AnotherWay._g_record_timeout_cnt > 0 ||\n    (Test.AnotherWay._g_record_wnd != null && (Test.AnotherWay._g_record_wnd.closed != null && !Test.AnotherWay._g_record_wnd.closed))) { // in opera, closed is null.\n        alert(\"there is already window opened for recording input for a page \" + Test.AnotherWay._g_record_url);\n        return;\n    }\n    var div = document.getElementById(\"record_div\");\n    var inputs = div.getElementsByTagName(\"input\");\n    var url = null;\n    for (var i = 0; i < inputs.length; ++i) {\n        var input = inputs[i];\n        if (input.type == \"radio\") {\n            if (input.value == \"select\" && input.checked) {\n                var index = document.getElementById(\"record_select\").selectedIndex;\n                if (index > 0) {\n                    url = Test.AnotherWay._g_test_page_urls[index - 1].url;\n                }\n            }\n            else \n                if (input.value == \"input\" && input.checked) {\n                    url = document.getElementById(\"record_input\").value;\n                }\n        }\n    }\n    if (url != null) {\n        Test.AnotherWay._g_record_url = url;\n        Test.AnotherWay._g_record_wnd = window.open(url, \"_blank\");\n        if (Test.AnotherWay._g_record_wnd == null) {\n            alert(\"unable to open new window for a page: \" + url);\n        }\n        else {\n            Test.AnotherWay._g_record_timeout_cnt = 50;\n            setTimeout(Test.AnotherWay._record_window_timeout, 100);\n        }\n    }\n};\nTest.AnotherWay._record_window_timeout = function(){\n    if (Test.AnotherWay._is_url_loaded(Test.AnotherWay._g_record_url, Test.AnotherWay._g_record_wnd)) {\n        Test.AnotherWay._record_window_setup(Test.AnotherWay._g_record_wnd);\n    }\n    else {\n        if (--Test.AnotherWay._g_record_timeout_cnt > 0) {\n            setTimeout(Test.AnotherWay._record_window_timeout, 100);\n        }\n        else {\n            alert(\"timeout expired while opening new window for a page: \" + Test.AnotherWay._g_record_url);\n            Test.AnotherWay._g_record_wnd = null;\n            Test.AnotherWay._g_record_url = null;\n            Test.AnotherWay._g_record_timeout_cnt = 0;\n        }\n    }\n};\nTest.AnotherWay._record_control_randomize_id = function(e, r){\n    if (e.id != \"\") {\n        e.id = e.id + r;\n    }\n    for (var c = e.firstChild; c != null; c = c.nextSibling) {\n        Test.AnotherWay._record_control_randomize_id(c, r);\n    }\n};\nTest.AnotherWay._record_window_setup = function(wnd) // insert recording control into the page for which input is recorded\n{\n    Test.AnotherWay._g_record_timeout_cnt = 0;\n    var this_div = document.getElementById(\"record_control\");\n    var record_control = wnd.document.importNode(this_div, true);\n    Test.AnotherWay._g_record_random_id = (1000 * Math.random()).toFixed();\n    Test.AnotherWay._record_control_randomize_id(record_control, Test.AnotherWay._g_record_random_id);\n    Test.AnotherWay._g_record_control_visible = true;\n    Test.AnotherWay._g_record_started = false;\n    Test.AnotherWay._g_record_paused = false;\n    Test.AnotherWay._g_record_checkpoint_count = 0;\n    Test.AnotherWay._g_record_mouse_over_record_control = false;\n    var doc = wnd.document;\n    doc.body.appendChild(record_control);\n    if (window.opera) {\n        cursor_over_indicator = Test.AnotherWay._record_control_get_element(\"record_cursor_over\");\n        cursor_over_indicator.style.width = \"18em\";\n        cursor_over_indicator.style.height = \"2em\";\n        cursor_over_indicator.style.fontSize = \"7pt\";\n    }\n    doc.addEventListener(\"keydown\", Test.AnotherWay._record_control_keydown, true);\n    doc.addEventListener(\"keyup\", Test.AnotherWay._record_control_keyup, true);\n    \n    doc.body.addEventListener(\"mousemove\", Test.AnotherWay._record_on_mousemove, true);\n    doc.body.addEventListener(\"click\", Test.AnotherWay._record_event, true);\n    doc.body.addEventListener(\"mouseover\", Test.AnotherWay._record_event, true);\n    doc.body.addEventListener(\"mouseout\", Test.AnotherWay._record_event, true);\n    doc.body.addEventListener(\"mousedown\", Test.AnotherWay._record_event, true);\n    doc.body.addEventListener(\"mouseup\", Test.AnotherWay._record_event, true);\n};\nTest.AnotherWay._record_control_key_disabled = function(k){\n    if (k == \"c\") {\n        return !Test.AnotherWay._g_record_started;\n    }\n    else \n        if (k == \"p\") {\n            return !Test.AnotherWay._g_record_started;\n        }\n        else \n            if (k == \"s\") {\n                return Test.AnotherWay._g_record_waiting_for_results;\n            }\n            else {\n                return false;\n            }\n};\n\nTest.AnotherWay._record_control_update_ui = function(){\n    var keydown_color = \"#fff\";\n    var disabled_color = \"#aaa\";\n    var button_color = \"#adf\";\n    var active_color = \"#fdf\";\n    \n    var display = {};\n    display[false] = \"none\";\n    display[true] = \"inline\";\n    \n    var s_button = Test.AnotherWay._record_control_get_element(\"record_s\");\n    var record_on = Test.AnotherWay._record_control_get_element(\"record_on\");\n    var record_off = Test.AnotherWay._record_control_get_element(\"record_off\");\n    \n    s_button.style.backgroundColor = Test.AnotherWay._record_control_key_disabled(\"s\") ? disabled_color : Test.AnotherWay._g_record_keydown == \"s\" ? keydown_color : Test.AnotherWay._g_record_started ? active_color : button_color;\n    record_on.style.display = display[!Test.AnotherWay._g_record_started];\n    record_off.style.display = display[Test.AnotherWay._g_record_started];\n    \n    var h_button = Test.AnotherWay._record_control_get_element(\"record_h\");\n    h_button.style.backgroundColor = Test.AnotherWay._g_record_keydown == \"h\" ? keydown_color : button_color;\n    \n    var p_button = Test.AnotherWay._record_control_get_element(\"record_p\");\n    var record_pause_on = Test.AnotherWay._record_control_get_element(\"record_pause_on\");\n    var record_pause_off = Test.AnotherWay._record_control_get_element(\"record_pause_off\");\n    p_button.style.backgroundColor = Test.AnotherWay._record_control_key_disabled(\"p\") ? disabled_color : Test.AnotherWay._g_record_keydown == \"p\" ? keydown_color : Test.AnotherWay._g_record_paused ? active_color : button_color;\n    record_pause_on.style.display = display[!Test.AnotherWay._g_record_paused];\n    record_pause_off.style.display = display[Test.AnotherWay._g_record_paused];\n    \n    var m_button = Test.AnotherWay._record_control_get_element(\"record_m\");\n    var record_include_mousemove = Test.AnotherWay._record_control_get_element(\"record_include_mousemove\");\n    var record_omit_mousemove = Test.AnotherWay._record_control_get_element(\"record_omit_mousemove\");\n    m_button.style.backgroundColor = Test.AnotherWay._g_record_keydown == \"m\" ? keydown_color : Test.AnotherWay._g_record_include_mousemove ? active_color : button_color;\n    record_include_mousemove.style.display = display[!Test.AnotherWay._g_record_include_mousemove];\n    record_omit_mousemove.style.display = display[Test.AnotherWay._g_record_include_mousemove];\n    \n    var c_button = Test.AnotherWay._record_control_get_element(\"record_c\");\n    c_button.style.backgroundColor = Test.AnotherWay._record_control_key_disabled(\"c\") ? disabled_color : Test.AnotherWay._g_record_keydown == \"c\" ? keydown_color : button_color;\n    \n    var record_indicator = Test.AnotherWay._record_control_get_element(\"record_indicator\");\n    record_indicator.style.display = display[Test.AnotherWay._g_record_started];\n    \n    var pause_indicator = Test.AnotherWay._record_control_get_element(\"record_pause_indicator\");\n    pause_indicator.style.display = display[Test.AnotherWay._g_record_paused];\n    \n    var record_control = Test.AnotherWay._record_control_get_element(\"record_control\");\n    record_control.style.display = Test.AnotherWay._g_record_control_visible ? \"block\" : \"none\";\n    \n    var shift_button = Test.AnotherWay._record_control_get_element(\"record_shift_key\");\n    shift_button.style.backgroundColor = Test.AnotherWay._g_record_shift_keydown ? keydown_color : button_color;\n    \n    var ctrl_button = Test.AnotherWay._record_control_get_element(\"record_ctrl_key\");\n    ctrl_button.style.backgroundColor = Test.AnotherWay._g_record_ctrl_keydown ? keydown_color : button_color;\n};\nTest.AnotherWay._record_format_time = function(t){\n    t = new Date(t);\n    var m = t.getMinutes();\n    var s = t.getSeconds();\n    var str = m == 0 ? \"\" : m + \"m \";\n    str += s + \"s.\";\n    return str;\n};\nTest.AnotherWay._record_control_update_time = function(){\n    var time_display = Test.AnotherWay._record_control_get_element(\"record_time\");\n    if (time_display != null) {\n        time_display.innerHTML = Test.AnotherWay._record_format_time((new Date()).getTime() - Test.AnotherWay._g_record_start_time);\n    }\n};\nTest.AnotherWay._record_control_update_highlight = function(elem, style, event){\n    if (elem == null) {\n        Test.AnotherWay._record_highlight_border(null);\n    }\n    else {\n        var pos = Test.AnotherWay._get_page_coords(elem);\n        if (style == \"ball\" || elem != Test.AnotherWay._g_record_highlighted_element.element || pos.x != Test.AnotherWay._g_record_highlighted_element.x || pos.y != Test.AnotherWay._g_record_highlighted_element.y) {\n            Test.AnotherWay._g_record_highlighted_element = {\n                element: elem,\n                x: pos.x,\n                y: pos.y\n            };\n            Test.AnotherWay._record_highlight_border(elem, style, event);\n        }\n    }\n};\nTest.AnotherWay._record_decode_key = function(event){\n    var k = null;\n    if (event == null) {\n        k = Test.AnotherWay._g_record_wnd.event.keyCode;\n    }\n    else {\n        k = event.which;\n    }\n    if (k == 83) {\n        return \"s\";\n    }\n    else \n        if (k == 72) {\n            return \"h\";\n        }\n        else \n            if (k == 73) {\n                return \"i\";\n            }\n            else \n                if (k == 80) {\n                    return \"p\";\n                }\n                else \n                    if (k == 67) {\n                        return \"c\";\n                    }\n                    else \n                        if (k == 77) {\n                            return \"m\";\n                        }\n                        else \n                            if (k == 16) {\n                                return \"shift\";\n                            }\n                            else \n                                if (k == 17) {\n                                    return \"ctrl\";\n                                }\n                                else \n                                    if (k == 18) {\n                                        return \"alt\";\n                                    }\n                                    else \n                                        if (k == 19) {\n                                            return \"pause\";\n                                        }\n                                        else \n                                            if (k == 123) {\n                                                return \"f12\";\n                                            }\n    return \"\";\n};\nTest.AnotherWay._record_control_keydown = function(event){\n    var handled = false;\n    var k = Test.AnotherWay._record_decode_key(event);\n    if (k == \"shift\") {\n        Test.AnotherWay._g_record_shift_keydown = true;\n    }\n    else \n        if (k == \"ctrl\") {\n            Test.AnotherWay._g_record_ctrl_keydown = true;\n        }\n        else \n            if (k != \"\" && (Test.AnotherWay._g_record_keydown == null || Test.AnotherWay._g_record_keydown == k)) {\n                if (Test.AnotherWay._g_record_ctrl_keydown && Test.AnotherWay._g_record_shift_keydown && !Test.AnotherWay._record_control_key_disabled(k)) {\n                    Test.AnotherWay._g_record_keydown = k;\n                    handled = true;\n                }\n            }\n            else {\n                Test.AnotherWay._g_record_keydown = \"\";\n            }\n    Test.AnotherWay._record_control_update_ui();\n    if (!handled) {\n    }\n    return;\n};\nTest.AnotherWay._record_control_keyup = function(event){\n    var handled = false;\n    var k = Test.AnotherWay._record_decode_key(event);\n    if (k == \"shift\") {\n        Test.AnotherWay._g_record_shift_keydown = false;\n    }\n    else \n        if (k == \"ctrl\") {\n            Test.AnotherWay._g_record_ctrl_keydown = false;\n        }\n        else \n            if (k != \"\" && k == Test.AnotherWay._g_record_keydown && Test.AnotherWay._g_record_ctrl_keydown && Test.AnotherWay._g_record_shift_keydown) {\n                if (k == \"s\") {\n                    Test.AnotherWay._g_record_started = !Test.AnotherWay._g_record_started;\n                    if (Test.AnotherWay._g_record_started) {\n                        Test.AnotherWay._g_record_events = [];\n                        Test.AnotherWay._g_record_start_time = (new Date()).getTime();\n                        Test.AnotherWay._record_control_update_time();\n                        Test.AnotherWay._g_record_update_time_interval = window.setInterval(Test.AnotherWay._record_control_update_time, 200);\n                    }\n                    else {\n                        Test.AnotherWay._record_control_update_highlight(null);\n                        if (!Test.AnotherWay._g_record_paused) {\n                            window.clearInterval(Test.AnotherWay._g_record_update_time_interval);\n                        }\n                        Test.AnotherWay._g_record_waiting_for_results = true;\n                        Test.AnotherWay._g_record_paused = false;\n                        var loc = window.location;\n                        loc = loc.protocol + \"//\" + loc.host + loc.pathname + \"?recording_results=\" + Test.AnotherWay._g_record_random_id;\n                        if (window.open(loc, \"_blank\") == null) {\n                            alert(\"unable to open new window for results\");\n                        }\n                    }\n                    handled = true;\n                }\n                else \n                    if (k == \"h\") {\n                        Test.AnotherWay._g_record_control_visible = !Test.AnotherWay._g_record_control_visible;\n                        handled = true;\n                    }\n                    else \n                        if (k == \"p\") {\n                            Test.AnotherWay._g_record_paused = !Test.AnotherWay._g_record_paused;\n                            if (Test.AnotherWay._g_record_paused) {\n                                Test.AnotherWay._g_record_pause_start_time = (new Date()).getTime();\n                                if (Test.AnotherWay._g_record_started) {\n                                    window.clearInterval(Test.AnotherWay._g_record_update_time_interval);\n                                }\n                                Test.AnotherWay._record_control_update_highlight(null);\n                            }\n                            else {\n                                var pause_duration = (new Date()).getTime() - Test.AnotherWay._g_record_pause_start_time;\n                                Test.AnotherWay._g_record_start_time += pause_duration;\n                                Test.AnotherWay._g_record_update_time_interval = window.setInterval(Test.AnotherWay._record_control_update_time, 200);\n                            }\n                            handled = true;\n                        }\n                        else \n                            if (k == \"m\") {\n                                Test.AnotherWay._g_record_include_mousemove = !Test.AnotherWay._g_record_include_mousemove;\n                                handled = true;\n                            }\n                            else \n                                if (k == \"c\") {\n                                    var o = Test.AnotherWay._record_checkpoint();\n                                    Test.AnotherWay._record_display_checkpoint(o);\n                                    Test.AnotherWay._record_flash_border(\"#24d\");\n                                    handled = true;\n                                }\n            }\n    Test.AnotherWay._g_record_keydown = null;\n    Test.AnotherWay._record_control_update_ui();\n    if (!handled) {\n    }\n    return;\n};\nTest.AnotherWay._record_html_node_path = function(node){\n    if (node == null) {\n        return null;\n    }\n    var path = [];\n    while (true) {\n        if (node.id != null && node.id != \"\") {\n            path.unshift(\"#\" + node.id + \" \" + node.nodeName);\n            break;\n        }\n        else {\n            var parent_node = node.parentNode;\n            if (parent_node == null) {\n                return []; // no BODY up the path - this node is screwed (browsers differ in what's above the body), discard\n            }\n            else {\n                var i = 0;\n                var found = false;\n                for (var child = parent_node.firstChild; child != null; child = child.nextSibling) {\n                    if (child == node) {\n                        found = true;\n                        break;\n                    }\n                    if (child.nodeType == 1) { // count only HTML element nodes\n                        ++i;\n                    }\n                }\n                if (!found) {\n                    i = -1;\n                }\n                path.unshift(i + \" \" + node.nodeName);\n                if (parent_node.nodeName == \"BODY\" || parent_node.nodeName == \"body\") {\n                    break;\n                }\n                node = parent_node;\n            }\n        }\n    }\n    return path;\n};\nTest.AnotherWay._record_node_path_to_string = function(path){\n    var s = \"\";\n    if (path != null) {\n        for (var i = 0; i < path.length; ++i) {\n            s += i == 0 ? \"\" : \", \";\n            var elem = path[i].split(\" \");\n            if (elem[0].charAt(0) == \"#\") {\n                s += elem[1] + \" \" + elem[0];\n            }\n            else {\n                s += elem[1] + \" [\" + elem[0] + \"]\";\n            }\n        }\n    }\n    return s;\n};\nTest.AnotherWay._record_node_path_to_node = function(path_str, doc){\n    if (path_str == null) {\n        return null;\n    }\n    var path = path_str.split(\",\");\n    var node = doc.body;\n    for (var i = 0; i < path.length; ++i) {\n        var node_i = path[i].split(\" \")[0];\n        if (node_i.charAt(0) == \"#\") {\n            node = doc.getElementById(node_i.substring(1));\n        }\n        else {\n            if (node_i < 0 || node_i >= node.childNodes.length) {\n                node = null;\n            }\n            else {\n                node = node.firstChild;\n                while (node != null) {\n                    if (node.nodeType == 1) { // count only HTML element nodes\n                        if (node_i == 0) {\n                            break;\n                        }\n                        --node_i;\n                    }\n                    node = node.nextSibling;\n                }\n            }\n        }\n        if (node == null) {\n            return null;\n        }\n    }\n    return node;\n};\nTest.AnotherWay._record_control_contains_id = function(s){\n    return s.match(/^#record_[\\w_]+/) && s.match(Test.AnotherWay._g_record_random_id);\n};\nTest.AnotherWay._record_checkpoint = function(){\n    var o = {\n        type: \"_checkpoint\",\n        time: (new Date()).getTime() - Test.AnotherWay._g_record_start_time,\n        which: Test.AnotherWay._g_record_checkpoint_count++,\n        target: Test.AnotherWay._record_html_node_path(Test.AnotherWay._g_record_under_cursor)\n    };\n    Test.AnotherWay._g_record_events.push(o);\n    return o;\n};\nTest.AnotherWay._record_event = function(event){\n    var unneeded = [\"rangeOffset\", \"eventPhase\", \"timeStamp\", \"isTrusted\", \"popupWindowFeatures\", \"rangeOffset\"];\n    if (Test.AnotherWay._g_record_started && !Test.AnotherWay._g_record_paused) {\n        var o = {};\n        for (var n in event) {\n            var needed = !n.match(/^[A-Z0-9_]+$/);\n            if (needed) {\n                for (var ui = 0; ui < unneeded.length; ++ui) {\n                    if (unneeded[ui] == n) {\n                        needed = false;\n                        break;\n                    }\n                }\n                if (needed) {\n                    var value = event[n];\n                    if (typeof(value) != \"object\" && typeof(value) != \"function\") {\n                        o[n] = value;\n                    }\n                    else \n                        if (n == \"target\" || n == \"relatedTarget\") {\n                            o[n] = Test.AnotherWay._record_html_node_path(value);\n                        }\n                }\n            }\n        }\n        o[\"time\"] = (new Date()).getTime() - Test.AnotherWay._g_record_start_time;\n        var over_record_control = o[\"target\"] != null && o[\"target\"][0] != null && Test.AnotherWay._record_control_contains_id(o[\"target\"][0]);\n        if (!over_record_control) {\n            Test.AnotherWay._g_record_events.push(o);\n        }\n    }\n    return true;\n};\nTest.AnotherWay._record_on_mousemove = function(event){\n    var path = Test.AnotherWay._record_html_node_path(event.target);\n    var new_mouse_over_record_control = path != null && path[0] != null && Test.AnotherWay._record_control_contains_id(path[0]);\n    if (new_mouse_over_record_control != Test.AnotherWay._g_record_mouse_over_record_control) {\n        Test.AnotherWay._g_record_mouse_over_record_control = new_mouse_over_record_control;\n        Test.AnotherWay._record_control_update_ui();\n    }\n    if (event.target != null && event.target != Test.AnotherWay._g_record_under_cursor) {\n        Test.AnotherWay._g_record_under_cursor = event.target;\n        var s = \"\";\n        if (path == null || path[0] == null || !Test.AnotherWay._record_control_contains_id(path[0])) {\n            s = Test.AnotherWay._record_node_path_to_string(path);\n        }\n        if (s == \"\") {\n            s = \"&nbsp;\";\n        }\n        var cursor_over_indicator = Test.AnotherWay._record_control_get_element(\"record_cursor_over\");\n        cursor_over_indicator.innerHTML = s;\n    }\n    \n    var highlight_element = null;\n    if (!Test.AnotherWay._g_record_mouse_over_record_control && Test.AnotherWay._g_record_started && !Test.AnotherWay._g_record_paused) {\n        highlight_element = event.target;\n    }\n    \n    if (Test.AnotherWay._g_record_include_mousemove) {\n        Test.AnotherWay._record_event(event);\n    }\n    return true;\n};\nTest.AnotherWay._record_display_checkpoint = function(o){\n    var checkpoints_div = Test.AnotherWay._record_control_get_element(\"record_checkpoints\");\n    var p = checkpoints_div.appendChild(checkpoints_div.ownerDocument.createElement(\"div\"));\n    p.style.marginTop = \"3px\";\n    p.style.font = \"normal normal 8pt sans-serif\";\n    p.style.color = \"#000\";\n    p.style.textAligh = \"left\";\n    p.style.position = \"relative\";\n    p.style.width = \"100%\";\n    var checkpoint_text = \"\";\n    checkpoint_text += \"#\" + (o.which + 1);\n    checkpoint_text += \"  \" + Test.AnotherWay._record_format_time(o.time);\n    if (o.target != null) {\n        checkpoint_text += Test.AnotherWay._record_node_path_to_string(o.target);\n    }\n    p.appendChild(p.ownerDocument.createTextNode(checkpoint_text));\n};\nTest.AnotherWay._record_save_results = function(doc){\n    var append = function(s){\n        doc.write(\"<div>\" + s + \"</div>\");\n    };\n    append(\"/* paste this data into your javascript and pass it as an argument to replay_events method */\");\n    append(\"{ checkpoints: [\");\n    var first_checkpoint = true;\n    for (var i = 0; i < Test.AnotherWay._g_record_events.length; ++i) {\n        var o = Test.AnotherWay._g_record_events[i];\n        if (o.type == \"_checkpoint\") {\n            var str = first_checkpoint ? \"\" : \"}, \";\n            str += \"function( tst, wnd ) { // #\" + o.which + \" time \" + Test.AnotherWay._record_format_time(o.time) + \" cursor was over \" + Test.AnotherWay._record_node_path_to_string(o.target);\n            append(str);\n            first_checkpoint = false;\n        }\n    }\n    if (!first_checkpoint) {\n        append(\"}\");\n    }\n    append(\"], events: [ \");\n    var prev_time = 0;\n    for (var i = 0; i < Test.AnotherWay._g_record_events.length; ++i) {\n        var o = Test.AnotherWay._g_record_events[i];\n        var s = \"\";\n        s += \"{\";\n        var n_first = true;\n        for (var n in o) {\n            if (n == \"time\") { // convert to relative time\n                var cur_time = o[n] - 0;\n                o[n] = cur_time - prev_time;\n                prev_time = cur_time;\n            }\n            s += n_first ? n : \", \" + n;\n            s += \":\";\n            if (o[n] == null) {\n                s += \"null\";\n            }\n            else {\n                s += \"\\\"\" + o[n] + \"\\\"\";\n            }\n            n_first = false;\n        }\n        s += i == Test.AnotherWay._g_record_events.length - 1 ? \"}\" : \"},\";\n        append(s);\n    }\n    append(\"] }\");\n    append(\";\");\n};\n\nTest.AnotherWay._g_record_border; // border highlighting element under cursor\nTest.AnotherWay._g_record_border_flashes = []; // array of { color: color, timeout: milliseconds }\nTest.AnotherWay._g_record_border_flashing = false;\nTest.AnotherWay._g_record_border_normal_color = \"#d4b\";\nTest.AnotherWay._record_flash_border_timeout = function(){\n    var color = Test.AnotherWay._g_record_border_normal_color;\n    var timeout = null;\n    if (Test.AnotherWay._g_record_border_flashes.length != 0) {\n        color = Test.AnotherWay._g_record_border_flashes[0].color;\n        timeout = Test.AnotherWay._g_record_border_flashes[0].timeout;\n        Test.AnotherWay._g_record_border_flashes.splice(0, 1);\n    }\n    if (Test.AnotherWay._g_record_border != null) {\n        for (var i = 0; i < Test.AnotherWay._g_record_border.length; ++i) {\n            Test.AnotherWay._g_record_border[i].style.backgroundColor = color;\n        }\n    }\n    if (timeout != null) {\n        setTimeout(Test.AnotherWay._record_flash_border_timeout, timeout);\n    }\n    else {\n        Test.AnotherWay._g_record_border_flashing = false;\n    }\n};\nTest.AnotherWay._get_page_coords = function(elm){\n    var point = {\n        x: 0,\n        y: 0\n    };\n    while (elm) {\n        point.x += elm.offsetLeft;\n        point.y += elm.offsetTop;\n        elm = elm.offsetParent;\n    }\n    return point;\n};\nTest.AnotherWay._set_page_coords = function(elm, x, y){\n    var parent_coords = {\n        x: 0,\n        y: 0\n    };\n    if (elm.offsetParent) {\n        parent_coords = Test.AnotherWay._get_page_coords(elm.offsetParent);\n    }\n    var new_x = x - parent_coords.x;\n    if (new_x < 0) {\n        new_x = 0;\n    }\n    elm.style.left = new_x + 'px';\n    var new_y = y - parent_coords.y;\n    if (new_y < 0) {\n        new_y = 0;\n    }\n    elm.style.top = new_y + 'px';\n};\nTest.AnotherWay._record_setup_highlight_positions = function(element, style, coords, positions){\n    if (style == \"border\") {\n        var width = element.clientWidth;\n        var height = element.clientHeight;\n        var step = 0;\n        var thickness = 2;\n        var fudge_expand = 4;\n        positions.push({\n            x: coords.x - step - thickness,\n            y: coords.y - step - thickness,\n            width: width + 2 * step + 2 * thickness + fudge_expand,\n            height: thickness\n        });\n        positions.push({\n            x: coords.x + width + step + fudge_expand,\n            y: coords.y - step - thickness,\n            width: thickness,\n            height: height + 2 * step + 2 * thickness + fudge_expand\n        });\n        positions.push({\n            x: positions[0].x,\n            y: positions[0].y,\n            width: positions[0].width,\n            height: positions[0].height\n        });\n        positions.push({\n            x: positions[1].x,\n            y: positions[1].y,\n            width: positions[1].width,\n            height: positions[1].height\n        });\n        positions[2].y += height + thickness + 2 * step + fudge_expand;\n        positions[3].x -= width + thickness + 2 * step + fudge_expand;\n    }\n    else \n        if (style == \"ball\") {\n            positions.push({\n                x: coords.x + 2,\n                y: coords.y,\n                width: 2,\n                height: 6\n            });\n            positions.push({\n                x: coords.x,\n                y: coords.y + 2,\n                width: 6,\n                height: 2\n            });\n            positions.push({\n                x: coords.x + 1,\n                y: coords.y + 1,\n                width: 4,\n                height: 4\n            });\n        }\n};\nTest.AnotherWay._record_highlight_border = function(element, style, event) // null - hide border\n{\n    if (element != null) {\n        if (Test.AnotherWay._g_record_border == null || Test.AnotherWay._g_record_border[0].ownerDocument != element.ownerDocument) {\n            Test.AnotherWay._g_record_border = [];\n            var n = style == \"border\" ? 4 : style == \"ball\" ? 3 : 0;\n            for (var i = 0; i < 4; ++i) {\n                var b = element.ownerDocument.createElement(\"div\");\n                b.style.position = \"absolute\";\n                b.style.zIndex = \"1\";\n                b.style.backgroundColor = Test.AnotherWay._g_record_border_normal_color;\n                element.ownerDocument.body.appendChild(b);\n                Test.AnotherWay._g_record_border.push(b);\n            }\n        }\n        var coords = null;\n        if (style == \"border\") {\n            coords = Test.AnotherWay._get_page_coords(element);\n        }\n        else \n            if (style == \"ball\") {\n                if (event != null) {\n                    if (event.pageX != null && event.pageY != null) {\n                        coords = {\n                            x: event.pageX - 0,\n                            y: event.pageY - 0\n                        };\n                    }\n                    else \n                        if (event.clientX != null && event.clientY != null) {\n                            var doc = element.ownerDocument;\n                            if (doc != null) {\n                                coords = {\n                                    x: (event.clientX - 0) + doc.body.scrollLeft,\n                                    y: (event.clientY - 0) + doc.body.scrollTop\n                                };\n                            }\n                        }\n                }\n            }\n        if (coords != null && element.clientWidth != null && element.clientHeight != null) {\n            var positions = [];\n            Test.AnotherWay._record_setup_highlight_positions(element, style, coords, positions);\n            for (var i = 0; i < positions.length; ++i) {\n                var b = Test.AnotherWay._g_record_border[i];\n                var p = positions[i];\n                Test.AnotherWay._set_page_coords(b, p.x, p.y);\n                b.style.width = p.width + \"px\";\n                b.style.height = p.height + \"px\";\n                b.style.display = \"block\";\n            }\n        }\n    }\n    else {\n        if (Test.AnotherWay._g_record_border != null) {\n            for (var i = 0; i < Test.AnotherWay._g_record_border.length; ++i) {\n                Test.AnotherWay._g_record_border[i].style.display = \"none\";\n            }\n        }\n    }\n};\nTest.AnotherWay._record_flash_border = function(color){\n    if (Test.AnotherWay._g_record_border_flashing) { //already\n        Test.AnotherWay._g_record_border_flashes.push({\n            color: Test.AnotherWay._g_record_border_normal_color,\n            timeout: 300\n        });\n        Test.AnotherWay._g_record_border_flashes.push({\n            color: color,\n            timeout: 600\n        });\n    }\n    else {\n        Test.AnotherWay._g_record_border_flashing = true;\n        Test.AnotherWay._g_record_border_flashes.push({\n            color: color,\n            timeout: 600\n        });\n        Test.AnotherWay._record_flash_border_timeout();\n    }\n};\nTest.AnotherWay._record_prepare_doc_for_results = function(){\n    document.open();\n    document.write(\"<!DOCTYPE HTML PUBLIC \\\"-//W3C//DTD HTML 4.01//EN\\\" \\\"http://www.w3.org/TR/html4/strict.dtd\\\">\");\n    document.write(\"<html><head><title> Input recording results</title>\");\n    document.write(\"<style type=\\\"text/css\\\">\");\n    document.write(\"body { font: normal normal smaller sans-serif; }\");\n    document.write(\"div { margin-top: 3px; }\");\n    document.write(\"</style></head><body>\");\n    if (typeof(window.opener.Test) != \"undefined\" && typeof(window.opener.Test.AnotherWay) != \"undefined\") {\n        window.opener.Test.AnotherWay._record_save_results(document);\n        window.opener.Test.AnotherWay._g_record_waiting_for_results = false;\n        window.opener.Test.AnotherWay._record_control_update_ui();\n    }\n    else \n        if (typeof(window.opener.opener.Test) != \"undefined\" && typeof(window.opener.opener.Test.AnotherWay) != \"undefined\") {\n            window.opener.opener.Test.AnotherWay._record_save_results(document);\n            window.opener.opener.Test.AnotherWay._g_record_waiting_for_results = false;\n            window.opener.opener.Test.AnotherWay._record_control_update_ui();\n        }\n    document.write(\"</body>\");\n    document.close();\n};\nonload = function(){\n    if (window.opera) {\n        var good_opera = typeof(window.opera.version) == \"function\";\n        good_opera = good_opera && window.opera.version().match(/^\\s*(\\d+)/);\n        good_opera = good_opera && RegExp.$1 >= 8;\n    }\n    var span = document.createElement(\"SPAN\");\n    span.innerHTML = \"<!--[if IE]><br /><![endif]-\" + \"->\";\n    var is_ie = span.getElementsByTagName(\"BR\").length > 0;\n    \n    Test.AnotherWay._g_test_iframe = window.frames.test_iframe;\n    \n    var query_str = window.location.search;\n    if (query_str.charAt(0) == \"?\") {\n        query_str = query_str.substring(1);\n    }\n    var testlist_page = \"list-tests.html\";\n    var auto_run = false;\n    if (query_str != \"\") {\n        var params = [query_str];\n        if (query_str.indexOf(\";\") != -1) {\n            params = query_str.split(\";\");\n        }\n        else \n            if (query_str.indexOf(\"&\") != -1) {\n                params = query_str.split(\"&\");\n            }\n        for (var param_i = 0; param_i < params.length; ++param_i) {\n            var param = params[param_i].split(\"=\");\n            if (param[0] == \"recording_results\") {\n                if (window.opener != null) {\n                    Test.AnotherWay._record_prepare_doc_for_results();\n                    return;\n                }\n            }\n            else \n                if (param[0] == \"testpage\") {\n                    Test.AnotherWay._add_test_page_url(decodeURIComponent(param[1]), \"anotherway\");\n                }\n                else \n                    if (param[0] == \"jsantestpage\") {\n                        Test.AnotherWay._add_test_page_url(decodeURIComponent(param[1]), \"jsan\");\n                    }\n                    else \n                        if (param[0] == \"testlist\") {\n                            testlist_page = decodeURIComponent(param[1]);\n                        }\n                        else \n                            if (param[0] == \"testframe\") {\n                                if (window.opera && !good_opera) {\n                                    Test.AnotherWay._show_error(\"testframe parameter does not work in versions of Opera prior to 8.0. Sorry (pathches are welcome).\");\n                                }\n                                else {\n                                    var frame_path = param[1].split(\".\");\n                                    var frame = top;\n                                    for (var frame_path_i = 0; frame_path_i < frame_path.length; ++frame_path_i) {\n                                        frame = frame[frame_path[frame_path_i]];\n                                    }\n                                    if (frame == null) {\n                                        Test.AnotherWay._show_error(\"unable to find frame specified for loading test pages: \" + param[1]);\n                                    }\n                                    else {\n                                        if (frame.frameElement != null) { // for the following assignement to onload to work, frameElement is required\n                                            frame = frame.frameElement;\n                                        }\n                                        Test.AnotherWay._g_test_iframe = frame;\n                                    }\n                                }\n                            }\n                            else \n                                if (param[0] == \"testframe_no_clear\") {\n                                    Test.AnotherWay._g_test_frame_no_clear = true;\n                                }\n                                else \n                                    if (param[0] == \"windows\") {\n                                        if (param[1] == \"none\") {\n                                            Test.AnotherWay._test_object_t.prototype.open_window = null;\n                                        }\n                                    }\n                                    else \n                                        if (param[0] == \"run\") {\n                                            auto_run = true;\n                                            if (param[1] == \"all\") {\n                                                Test.AnotherWay._g_pages_to_run = \"all\";\n                                            }\n                                            else {\n                                                if (Test.AnotherWay._g_pages_to_run == null || Test.AnotherWay._g_pages_to_run == \"all\") {\n                                                    Test.AnotherWay._g_pages_to_run = [];\n                                                }\n                                                var pages = param[1].split(\",\");\n                                                for (var i = 0; i < pages.length; ++i) {\n                                                    Test.AnotherWay._g_pages_to_run.push(pages[i]);\n                                                }\n                                            }\n                                        }\n        }\n    }\n    if (Test.AnotherWay._g_test_page_urls.length == 0) { // if no individual pages were given on the command line, load the list\n        var result = Test.AnotherWay._set_iframe_location(window.frames[\"list_iframe\"], testlist_page);\n        if (result.msg != null) {\n            Test.AnotherWay._show_error(result.msg);\n        }\n        Test.AnotherWay._g_run_on_list_load = auto_run;\n    }\n    else {\n        Test.AnotherWay._g_run_on_main_load = auto_run;\n    }\n    \n    var f = Test.AnotherWay._g_test_iframe;\n    try {\n        if (f.attachEvent != null) {\n            f.attachEvent(\"onload\", Test.AnotherWay._test_page_onload);\n        }\n        else {\n            f.onload = Test.AnotherWay._test_page_onload;\n        }\n        if (Test.AnotherWay._g_test_iframe.nodeType != null && Test.AnotherWay._g_test_iframe.contentWindow != null) { // it's iframe element, not the iframe. we need iframe.\n            Test.AnotherWay._g_test_iframe = Test.AnotherWay._g_test_iframe.contentWindow;\n        }\n    } \n    catch (e) {\n    }\n    var handlers = {\n        \"run_all\": {\n            \"onclick\": Test.AnotherWay._run_all_onclick\n        },\n        \"run_selected\": {\n            \"onclick\": Test.AnotherWay._run_selected_onclick\n        },\n        \"unselect_all\": {\n            \"onclick\": Test.AnotherWay._unselect_all_onclick\n        },\n        \"record_select\": {\n            \"onfocus\": Test.AnotherWay._record_check_onfocus\n        },\n        \"record_input\": {\n            \"onfocus\": Test.AnotherWay._record_check_onfocus\n        },\n        \"record_start\": {\n            \"onclick\": Test.AnotherWay._record_start_onclick\n        },\n        \"clear_btn\": {\n            \"onclick\": Test.AnotherWay._results_clear_onclick\n        },\n        \"results_tab\": {\n            \"onclick\": Test.AnotherWay._tab_onclick,\n            \"onmouseover\": Test.AnotherWay._tab_mouseover,\n            \"onmouseout\": Test.AnotherWay._tab_mouseout\n        },\n        \"debug_tab\": {\n            \"onclick\": Test.AnotherWay._tab_onclick,\n            \"onmouseover\": Test.AnotherWay._tab_mouseover,\n            \"onmouseout\": Test.AnotherWay._tab_mouseout\n        }\n    };\n    for (var hs in handlers) {\n        var o = document.getElementById(hs);\n        if (o != null) {\n            for (var h in handlers[hs]) {\n                o[h] = handlers[hs][h];\n            }\n        }\n        else {\n            Test.AnotherWay._show_error(\"unable to set \" + h + \" handler: id \" + hs + \" not found\");\n        }\n    }\n    \n    if (window.opera && !good_opera) {\n        Test.AnotherWay._g_no_record_msg = \"Input events recording and replaying is not available in opera versions prior to 8.0.\";\n    }\n    if (is_ie) {\n        Test.AnotherWay._g_no_record_msg = \"Input events recording and replaying is not available in internet explorer.\";\n    }\n    if (Test.AnotherWay._g_no_record_msg != null) {\n        var no_record_p = document.getElementById(\"record_not_supported\");\n        no_record_p.style.display = \"block\";\n        no_record_p.appendChild(document.createTextNode(Test.AnotherWay._g_no_record_msg));\n    }\n    \n    Test.AnotherWay._g_main_loaded = true;\n    if (Test.AnotherWay._g_run_on_main_load) {\n        Test.AnotherWay._g_run_on_main_load = false;\n        Test.AnotherWay._run_pages_to_run();\n    }\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Test.AnotherWay.xml_eq.js",
    "content": "\n(function() {\n\n        function createNode(text) {\n        \n        var index = text.indexOf('<');\n        if(index > 0) {\n            text = text.substring(index);\n        }\n        \n        var doc;\n        if(window.ActiveXObject && !this.xmldom) {\n            doc = new ActiveXObject(\"Microsoft.XMLDOM\");\n            try {\n                doc.loadXML(text);\n            } catch(err) {\n                throw \"ActiveXObject loadXML failed: \" + err;\n            }\n        } else if(window.DOMParser) {\n            try {\n                doc = new DOMParser().parseFromString(text, 'text/xml');\n            } catch(err) {\n                throw \"DOMParser.parseFromString failed\";\n            }\n            if(doc.documentElement && doc.documentElement.nodeName == \"parsererror\") {\n                throw \"DOMParser.parseFromString returned parsererror\";\n            }\n        } else {\n            var req = new XMLHttpRequest();\n            req.open(\"GET\", \"data:text/xml;charset=utf-8,\" +\n                     encodeURIComponent(text), false);\n            if(req.overrideMimeType) {\n                req.overrideMimeType(\"text/xml\");\n            }\n            req.send(null);\n            doc = req.responseXML;\n        }\n        \n        var root = doc.documentElement;\n        if(!root) {\n            throw \"no documentElement\";\n        }\n        return root;\n    }\n    \n        function assertEqual(got, expected, msg) {\n        if(got === undefined) {\n            got = \"undefined\";\n        } else if (got === null) {\n            got = \"null\";\n        }\n        if(expected === undefined) {\n            expected = \"undefined\";\n        } else if (expected === null) {\n            expected = \"null\";\n        }\n        if(got != expected) {\n            throw msg + \": got '\" + got + \"' but expected '\" + expected + \"'\";\n        }\n    }\n    \n        function assertElementNodesEqual(got, expected, options) {\n        var testPrefix = (options && options.prefix === true);\n        assertEqual(got.nodeType, expected.nodeType, \"Node type mismatch\");\n        var gotName = testPrefix ?\n            got.nodeName : got.nodeName.split(\":\").pop();\n        var expName = testPrefix ?\n            expected.nodeName : expected.nodeName.split(\":\").pop();\n        assertEqual(gotName, expName, \"Node name mismatch\");\n        if(got.nodeType == 3) {\n            assertEqual(\n                got.nodeValue, expected.nodeValue, \"Node value mismatch\"\n            );\n        }\n        else if(got.nodeType == 1) {\n            if(got.prefix || expected.prefix) {\n                if(testPrefix) {\n                    assertEqual(\n                        got.prefix, expected.prefix,\n                        \"Bad prefix for \" + got.nodeName\n                    );\n                }\n            }\n            if(got.namespaceURI || expected.namespaceURI) {\n                assertEqual(\n                    got.namespaceURI, expected.namespaceURI,\n                    \"Bad namespaceURI for \" + got.nodeName\n                );\n            }\n            var gotAttrLen = 0;\n            var gotAttr = {};\n            var expAttrLen = 0;\n            var expAttr = {};\n            var ga, ea, gn, en;\n            for(var i=0; i<got.attributes.length; ++i) {\n                ga = got.attributes[i];\n                if(ga.specified === undefined || ga.specified === true) {\n                    if(ga.name.split(\":\").shift() != \"xmlns\") {\n                        gn = testPrefix ? ga.name : ga.name.split(\":\").pop();\n                        gotAttr[gn] = ga;\n                        ++gotAttrLen;\n                    }\n                }\n            }\n            for(var i=0; i<expected.attributes.length; ++i) {\n                ea = expected.attributes[i];\n                if(ea.specified === undefined || ea.specified === true) {\n                    if(ea.name.split(\":\").shift() != \"xmlns\") {\n                        en = testPrefix ? ea.name : ea.name.split(\":\").pop();\n                        expAttr[en] = ea;\n                        ++expAttrLen;\n                    }\n                }\n            }\n            assertEqual(\n                gotAttrLen, expAttrLen,\n                \"Attributes length mismatch for \" + got.nodeName\n            );\n            var gv, ev;\n            for(var name in gotAttr) {\n                if(expAttr[name] == undefined) {\n                    throw \"Attribute name \" + gotAttr[name].name + \" expected for element \" + got.nodeName;\n                }\n                assertEqual(\n                    gotAttr[name].namespaceURI, expAttr[name].namespaceURI,\n                    \"Attribute namespace mismatch for element \" +\n                    got.nodeName + \" attribute name \" + gotAttr[name].name\n                );\n                assertEqual(\n                    gotAttr[name].value, expAttr[name].value,\n                    \"Attribute value mismatch for element \" + got.nodeName +\n                    \" attribute name \" + gotAttr[name].name\n                );\n            }\n            var gotChildNodes = getChildNodes(got, options);\n            var expChildNodes = getChildNodes(expected, options);\n\n            assertEqual(\n                gotChildNodes.length, expChildNodes.length,\n                \"Children length mismatch for \" + got.nodeName\n            );\n            for(var j=0; j<gotChildNodes.length; ++j) {\n                try {\n                    assertElementNodesEqual(\n                        gotChildNodes[j], expChildNodes[j], options\n                    );\n                } catch(err) {\n                    throw \"Bad child \" + j + \" for element \" + got.nodeName + \": \" + err;\n                }\n            }\n        }\n        return true;\n    }\n\n        function getChildNodes(node, options) {\n        if (options && options.includeWhiteSpace) {\n            return node.childNodes;\n        }\n        else {\n           nodes = [];\n           for (var i = 0; i < node.childNodes.length; i++ ) {\n              var child = node.childNodes[i];\n              if (child.nodeType == 1) {\n                 nodes.push(child);\n              }\n              else if (child.nodeType == 3) {\n                 if (child.nodeValue && \n                       child.nodeValue.replace(/^\\s*(.*?)\\s*$/, \"$1\") != \"\" ) { \n\n                    nodes.push(child);\n                 }\n              }\n           }\n  \n           return nodes;\n        }\n    } \n    \n        var proto = Test.AnotherWay._test_object_t.prototype;\n    proto.xml_eq = function(got, expected, msg, options) {\n        if(typeof got == \"string\") {\n            try {\n                got = createNode(got);\n            } catch(err) {\n                this.fail(msg + \": got argument could not be converted to an XML node: \" + err);\n                return;\n            }\n        }\n        if(typeof expected == \"string\") {\n            try {\n                expected = createNode(expected);\n            } catch(err) {\n                this.fail(msg + \": expected argument could not be converted to an XML node: \" + err);\n                return;\n            }\n        }\n        try {\n            assertElementNodesEqual(got, expected, options);\n            this.ok(true, msg);\n        } catch(err) {\n            this.fail(msg + \": \" + err);\n        }\n    }\n    \n})();\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Tile/Image/IFrame.html",
    "content": "<html>\n<head>\n    <script src=\"../../OLLoader.js\"></script>\n    <script type=\"text/javascript\">\n    // turn off animation frame handling, so we can check img urls in tests\n    delete OpenLayers.Layer.Grid.prototype.queueTileDraw;\n\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var isOpera   = (navigator.userAgent.indexOf(\"Opera\") != -1);\n    var isIElt9      = (parseFloat(navigator.appVersion.split(\"MSIE\")[1]) < 9);\n\n    var map, layer;\n    var position = new OpenLayers.Pixel(20,30);\n    var bounds   = new OpenLayers.Bounds(1,2,3,4);\n    var url      = \"http://www.openlayers.org/dev/tests/tileimage\";\n    var size     = new OpenLayers.Size(5,6);\n    var name     = \"OpenaLayers WMS\";\n    var wmsUrl   = \"http://labs.metacarta.com/wms/vmap0?\";\n    \n    function test_Tile_Image_IFrame_create (t) {\n        t.plan( 3 );\n        map   = new OpenLayers.Map('map', {tileManager: null});\n        var bar = new Array(205).join(\"1234567890\");\n        layer = new OpenLayers.Layer.WMS(name, wmsUrl,\n                                         {layers: 'basic', foo: bar},\n                                         {tileOptions: {maxGetUrlLength: 2048},\n                                          transitionEffect: 'resize'});\n        map.addLayer(layer);\n\n        var tile = layer.addTile(bounds, position);\n\n        tile.draw();\n        t.eq(tile.imgDiv.nodeName.toLowerCase(), \"iframe\", \"IFrame used for long URL\");\n        \n        layer.mergeNewParams({foo: null});\n        tile.draw();\n        t.eq(tile.imgDiv.nodeName.toLowerCase(), \"img\", \"IMG used for short URL\");\n        \n        tile.maxGetUrlLength = 0;\n        tile.draw();\n        t.eq(tile.imgDiv.nodeName.toLowerCase(), \"iframe\", \"IFrame used when maxGetUrlLength is 0\");\n        \n        tile.destroy();\n        layer.destroy();\n        map.destroy();\n    }\n\n    function test_Tile_Image_IFrame_clear (t) {\n        t.plan( 1 );\n        \n        map   = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS(name, wmsUrl, {layers: 'basic'}, {tileOptions: {maxGetUrlLength: 0}}); \n        map.addLayer(layer);  \n        tile = layer.addTile(bounds, position);\n        tile.draw();\n        tile.clear();\n\n        t.eq(\n            tile.frame.getElementsByTagName(\"iframe\").length, 0,\n            \"IFrame removed on clear()\");\n        tile.destroy();\n        layer.destroy();\n        map.destroy();\n    }\n\n    function test_Tile_Image_IFrame_initImage (t) {\n        t.plan( 2 );\n\n        map   = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS(name, wmsUrl, {layers: 'basic'}, {tileOptions: {maxGetUrlLength: 0}}); \n        map.addLayer(layer);  \n        tile = layer.addTile(bounds, position);\n        tile.url = layer.getURL(bounds);\n        tile.initImage();\n\n        if(isMozilla) {\n            t.ok( tile.imgDiv instanceof HTMLElement, \"tile.iFrame successfully created.\");\n        }\n        else {\n            t.ok( tile.imgDiv != null, \"tile.iFrame successfully created.\");\n        }\n        t.eq( tile.imgDiv.className, \"olTileImage\", \"iFrame's className correctly set.\");\n\n        map.destroy();\n    }\n\n    function test_Tile_Image_IFrame_createImage (t) {\n        t.plan( 9 );\n\n        map   = new OpenLayers.Map('map', {tileManager: null});\n        layer = new OpenLayers.Layer.WMS(name, wmsUrl, {layers: 'basic'}, {tileOptions: {maxGetUrlLength: 0}}); \n        map.addLayer(layer);  \n        var tile = layer.addTile(bounds, position);\n        tile.draw();\n        var iFrame    = tile.imgDiv;\n        var eventPane = tile.frame.childNodes[0];\n\n        t.ok(OpenLayers.String.contains(eventPane.style.backgroundImage,\n                    tile.blankImageUrl),\n             \"backgroundImage of eventPane is set.\");\n        t.eq(parseInt(eventPane.style.zIndex, 10), 1, \"zIndex of eventPane is set.\");\n        if(isIElt9) {\n            t.ok(iFrame != null, \"IFrame successfully created.\");\n            t.eq(iFrame.style.backgroundColor, '#ffffff', \"backgroundColor correctly set.\");\n            t.eq(iFrame.style.filter, 'chroma(color=#FFFFFF)', \"filter correctly set.\");\n        } else {\n            t.ok(iFrame instanceof HTMLElement, \"IFrame successfully created.\");\n            t.ok(true, 'Skip IFrame backgroundColor test outside IE < 9');\n            t.ok(true, 'Skip IFrame filter test outside IE < 9');\n        }\n        t.eq( iFrame.scrolling, 'no', \"no scrolling\");\n        t.eq( parseFloat(iFrame.marginWidth), 0, \"no margin width\");\n        t.eq( parseFloat(iFrame.marginHeight), 0, \"no margin height\");\n        t.eq( parseFloat(iFrame.frameBorder), 0, \"no iframe border\");\n\n        map.destroy();\n    }\n\n    function test_Tile_Image_IFrame_createRequestForm (t) {\n        t.plan( 6 );\n\n        var tParams = {\n            SERVICE: \"WMS\", VERSION: \"1.1.1\",\n            REQUEST: \"GetMap\", STYLES: \"\",\n            FORMAT: \"image/jpeg\",\n            SRS: \"EPSG:4326\", BBOX: [1,2,3,4],\n            WIDTH: String(size.w), HEIGHT: String(size.h)\n        };\n        var newLayer = new OpenLayers.Layer.WMS(\"Name\",\n                     \"http://labs.metacarta.com/TESTURL\",\n                     tParams,\n                     {tileSize: size, tileOptions: {maxGetUrlLength: 0}});  \n        map = new OpenLayers.Map('map'); \n        map.addLayer(newLayer);  \n        tile = newLayer.addTile(bounds, position);\n        tile.url = newLayer.getURL(bounds);\n        tile.initImage();\n\n        tile.url = newLayer.getURL(bounds);\n        var form = tile.createRequestForm();\n        if(isMozilla) {\n            t.ok( form instanceof HTMLElement, \"created html form successfully.\");\n        }\n        else {\n            t.ok( form != null, \"created html form successfully.\");\n        }\n\n        \n        var cacheId = newLayer.params[\"_OLSALT\"];\n        cacheId     = (cacheId ? cacheId + \"_\" : \"\") + tile.bounds.toBBOX();\n        var url = OpenLayers.Util.urlAppend(newLayer.url, cacheId);\n\n        t.eq( form.method.toLowerCase(), 'post', \"form method correctly set.\");\n        t.eq( form.target, tile.id+'_iFrame', \"form target correctly set.\");\n        t.eq( form.action, url, \"form action correctly set.\");\n\n        var formParams = {};\n        var children = form.childNodes;\n        for(var i=0; i<form.childNodes.length; i++) {\n            formParams[children[i].name] = children[i].value\n        }\n        newLayer.params.BBOX = newLayer.params.BBOX.join(\",\");\n        t.eq(newLayer.params, formParams, \"html form elements equal layer's parameters.\");\n\n        tile.draw();\n        tile.clear();\n        tile.initImage();\n        tile.createRequestForm();\n        t.ok(\n            tile.imgDiv.nodeName == \"IFRAME\",\n            \"Iframe has been reinserted properly\"\n        );\n        \n        tile.destroy();\n        newLayer.destroy();\n        map.destroy();\n    }\n</script>\n</head>\n<body>\n<div id=\"map\" style=\"height:550px;width:500px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Tile/Image.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    // turn off tile queue, so we can check img urls in tests\n    delete OpenLayers.Layer.Grid.prototype.queueTileDraw;\n\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var tile; \n    \n    var map, layer;\n    function setUp() {\n        map = new OpenLayers.Map(\"map\");\n        layer = new OpenLayers.Layer(null, {\n            isBaseLayer: true\n        });\n        map.addLayer(layer)\n        map.setCenter(new OpenLayers.LonLat(0, 0));\n    }\n    \n    function tearDown() {\n        map.destroy();\n        map = null;\n        layer = null;\n    }\n\n    function test_Tile_Image_constructor (t) {\n        t.plan( 6 );\n        \n        setUp();\n        \n        var position = new OpenLayers.Pixel(20,30);\n        var bounds = new OpenLayers.Bounds(1,2,3,4);\n        var url = \"http://www.openlayers.org/dev/tests/tileimage\";\n        var size = new OpenLayers.Size(5,6);\n        tile = new OpenLayers.Tile.Image(layer, position, bounds, url, size);\n        \n        t.ok( tile instanceof OpenLayers.Tile.Image, \"new OpenLayers.Tile returns Tile object\" );\n        t.ok( tile.layer == layer, \"tile.layer is set correctly\");\n        t.ok( tile.position.equals(position), \"tile.position is set correctly\");\n        t.ok( tile.bounds.equals(bounds), \"tile.bounds is set correctly\");\n        t.eq( tile.url, url, \"tile.url is set correctly\");\n        t.ok( tile.size.equals(size), \"tile.size is set correctly\");\n        \n        tearDown();\n    }\n\n    function test_destroy_observers(t) {\n        t.plan(2);\n\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS( \"OpenLayers WMS\", \n            \"../../img/blank.gif\", {layers: 'basic'}); \n        map.addLayer(layer);\n\n        var position = new OpenLayers.Pixel(20,30);\n        var bounds = new OpenLayers.Bounds(1,2,3,4);\n        var size = new OpenLayers.Size(5,6);\n\n        // with alpha hack\n        var withAlpha = new OpenLayers.Tile.Image(layer, position, bounds, null, size);\n        withAlpha.layerAlphaHack = true;\n\n        withAlpha.draw();\n        var cacheID = withAlpha.imgDiv._eventCacheID;\n        withAlpha.destroy();\n        \n        t.eq(OpenLayers.Event.observers[cacheID], undefined, \n             \"With alpha hack: imgDiv observers are cleared in destroy\");\n\n        // without alpha hack\n        var withoutAlpha = new OpenLayers.Tile.Image(layer, position, bounds, null, size);\n        withoutAlpha.layerAlphaHack = false;\n\n        withoutAlpha.draw();\n        var cacheID = withoutAlpha.imgDiv._eventCacheID;\n        withoutAlpha.destroy();\n\n        t.eq(OpenLayers.Event.observers[cacheID], undefined, \n             \"Without alpha hack: imgDiv observers are cleared in destroy\");\n\n        map.destroy();\n    }\n\n    function test_Tile_Image_async (t) {\n        t.plan( 3 );\n        var map   = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS(\n            \"Name\",\n            \"../../img/blank.gif\",\n            {layers: 'basic'}, {async: true, getURLasync: function(bounds, callback, scope) {\n                callback.call(scope, this.getURL(bounds));\n            }}\n        ); \n        map.addLayer(layer);\n\n        var position = new OpenLayers.Pixel(20,30);\n        var bounds = new OpenLayers.Bounds(1,2,3,4);\n        tile = layer.addTile(bounds, position);\n        tile.renderTile();\n        t.delay_call(0.1, function() {\n            var expected = new Image();\n            expected.src = layer.getURL(bounds);\n            t.eq(tile.imgDiv.src, expected.src, \"image src correct for async request\");\n            t.eq(tile.asyncRequestId, 1, \"asyncRequestId correct after renderTile\");\n            tile.renderTile();\n        });\n        t.delay_call(0.2, function() {\n            t.eq(tile.asyncRequestId, 2, \"asyncRequestId correct after subsequent renderTile\");\n            tile.destroy();\n            layer.destroy();\n            map.destroy();\n        });\n    }\n\n    function test_Tile_Image_draw (t) {\n        t.plan(7);\n\n        var map = new OpenLayers.Map('map');\n        \n        var size = new OpenLayers.Size(5,6);\n        layer = new OpenLayers.Layer.WMS(\"Name\",\n                                         \"../../img/blank.gif\",\n                                         null,\n                                         {tileSize: size});  \n        map.addLayer(layer);  \n        var position = new OpenLayers.Pixel(20,30);\n        var bounds = new OpenLayers.Bounds(1,2,3,4);\n        var url = \"http://www.openlayers.org/dev/tests/tileimage\";\n        tile = new OpenLayers.Tile.Image(layer, position, bounds, url, size);\n        \n        tile.events.register(\"loadstart\", this, function() { \n            t.ok(true, \"loadstart triggered\");\n        });\n        tile.events.register(\"reload\", this, function() { \n            t.ok(true, \"reload triggered\");\n        });\n                \n        //this should trigger a \"loadstart\" event\n        tile.draw();\n        \n        if (!isMozilla)\n            t.ok( true, \"skipping element test outside of Mozilla\");\n        else\n            t.ok( tile.imgDiv instanceof HTMLElement, \"tile.draw creates an image\");\n        var tParams = {\n            SERVICE: \"WMS\", VERSION: \"1.1.1\",\n            REQUEST: \"GetMap\", STYLES: \"\",\n            FORMAT: \"image/jpeg\",\n            SRS: \"EPSG:4326\", BBOX: [1,2,3,4],\n            WIDTH: String(size.w), HEIGHT: String(size.h)\n        };\n        var expected = new Image();\n        expected.src =  \"../../img/blank.gif?\" + OpenLayers.Util.getParameterString(tParams)\n        t.delay_call(0.1, function() {\n            t.eq( tile.imgDiv.src, expected.src, \"tile.draw creates an image\");\n        });\n        t.eq( tile.imgDiv.style.width, \"5px\", \"Image width is correct\" );\n        t.eq( tile.imgDiv.style.height, \"6px\", \"Image height is correct\" );\n        t.ok( tile.imgDiv.parentNode === layer.div, \"Image is directly appended to the layer div\" ); \n\n        // this should trigger a \"reload\" event (since the image never actually\n        // loads in tests)\n        tile.draw();\n        \n    }\n    function test_Tile_Image_OutsideMaxExtent(t) {\n        t.plan( 11 );\n        var position = new OpenLayers.Pixel(20,30);\n        var bounds = new OpenLayers.Bounds(1,2,3,4);\n        var url = \"http://www.openlayers.org/dev/tests/tileimage\";\n        var size = new OpenLayers.Size(5,6);\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS( \"OpenLayers WMS\", \n            \"../../img/blank.gif\", {layers: 'basic'}, {encodeBBOX: true});\n        map.addLayer(layer);\n        tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-185,-90,-180,90), url, size);\n        tile.draw()\n        t.eq(tile.imgDiv, null, \"Images against side of maxextent don't load\");\n        tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-181,-91,180,90), url, size);\n        tile.draw()\n        var tParams = {\n            LAYERS: \"basic\", SERVICE: \"WMS\", VERSION: \"1.1.1\",\n            REQUEST: \"GetMap\", STYLES: \"\",\n            FORMAT: \"image/jpeg\",\n            SRS: \"EPSG:4326\", BBOX: \"-181,-91,180,90\",\n            WIDTH: \"256\", HEIGHT: \"256\"\n        };\n        t.eq(tile.url,\n             \"../../img/blank.gif?\" + OpenLayers.Util.getParameterString(tParams),\n             \"Images over edges of maxextent do load\");\n        tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-181,-90,180,90), url, size);\n        tile.draw()\n        tParams = OpenLayers.Util.extend(tParams, {BBOX: \"-181,-90,180,90\"});\n        t.eq(tile.url,\n             \"../../img/blank.gif?\" + OpenLayers.Util.getParameterString(tParams),\n             \"Images over edges of maxextent do load\");\n        tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-180,-90,180,90), url, size);\n        tile.draw()\n        tParams = OpenLayers.Util.extend(tParams, {BBOX: \"-180,-90,180,90\"});\n        t.eq(tile.url,\n             \"../../img/blank.gif?\" + OpenLayers.Util.getParameterString(tParams),\n             \"Image covering all of extent loads\");\n        tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-80,-45,80,45), url, size);\n        tile.draw()\n        tParams = OpenLayers.Util.extend(tParams, {BBOX: \"-80,-45,80,45\"});\n        t.eq(tile.url,\n             \"../../img/blank.gif?\" + OpenLayers.Util.getParameterString(tParams),\n             \"Image covering small part of extent loads\");\n        tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-185,-95,185,95), url, size);\n        tile.draw()\n        tParams = OpenLayers.Util.extend(tParams, {BBOX: \"-185,-95,185,95\"});\n        t.eq(tile.url,\n             \"../../img/blank.gif?\" + OpenLayers.Util.getParameterString(tParams),\n             \"Image covering more than all of extent loads\");\n\n        layer.displayOutsideMaxExtent=1;\n        tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-185,-90,-180,90), url, size);\n        tile.draw()\n        tParams = OpenLayers.Util.extend(tParams, {BBOX: \"-185,-90,-180,90\"});\n        t.eq(tile.url,\n             \"../../img/blank.gif?\" + OpenLayers.Util.getParameterString(tParams),\n             \"Images against side of maxextent do load with displayOutsideMaxExtent\");\n        tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-181,-90,180,90), url, size);\n        tile.draw()\n        tParams = OpenLayers.Util.extend(tParams, {BBOX: \"-181,-90,180,90\"});\n        t.eq(tile.url,\n             \"../../img/blank.gif?\" + OpenLayers.Util.getParameterString(tParams),\n             \"Images over edges of maxextent do load with displayOutsideMaxExtent set\");\n        tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-180,-90,180,90), url, size);\n        tile.draw()\n        tParams = OpenLayers.Util.extend(tParams, {BBOX: \"-180,-90,180,90\"});\n        t.eq(tile.url,\n             \"../../img/blank.gif?\" + OpenLayers.Util.getParameterString(tParams),\n             \"Image covering all of extent loads with display outside max extent\");\n        tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-80,-45,80,45), url, size);\n        tile.draw()\n        tParams = OpenLayers.Util.extend(tParams, {BBOX: \"-80,-45,80,45\"});\n        t.eq(tile.url,\n             \"../../img/blank.gif?\" + OpenLayers.Util.getParameterString(tParams),\n             \"Image covering small part of extent loads with display outside max extent\");\n        tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-185,-95,185,95), url, size);\n        tile.draw()\n        tParams = OpenLayers.Util.extend(tParams, {BBOX: \"-185,-95,185,95\"});\n        t.eq(tile.url,\n             \"../../img/blank.gif?\" + OpenLayers.Util.getParameterString(tParams),\n             \"Image covering more than all of extent loads\");\n    } \n    function test_Tile_Image_Display_After_Move(t) {\n        t.plan(2);\n        var position = new OpenLayers.Pixel(20,30);\n        var bounds = new OpenLayers.Bounds(1,2,3,4);\n        var url = \"http://www.openlayers.org/dev/tests/tileimage\";\n        var size = new OpenLayers.Size(5,6);\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS( \"OpenLayers WMS\", \n            \"../../img/blank.gif\", {layers: 'basic'}); \n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-90,-85,-90,85), url, size);\n        tile.draw();\n        tile.moveTo(new OpenLayers.Bounds(-185,-90,-180,-80), new OpenLayers.Pixel(-180,-85), true);\n        t.delay_call( 1, function() { t.ok(!tile.imgDiv, \"Reference to tile image removed.\") } );\n        var layer = new OpenLayers.Layer.WMS( \"OpenLayers WMS\", \n            \"../../img/blank.gif\", {layers: 'basic'}, {'alpha':true});\n        map.addLayer(layer);\n        tile = new OpenLayers.Tile.Image(layer, position, new OpenLayers.Bounds(-90,-85,-90,85), url, size);\n        tile.draw();\n        tile.moveTo(new OpenLayers.Bounds(-185,-90,-180,-80), new OpenLayers.Pixel(-180,-85), true)\n        t.delay_call( 1, function() { t.ok(!tile.imgDiv, \"Reference to alpha tile image removed.\") } );\n        \n    }\n\n    function test_Tile_Image_gutters(t) {\n        t.plan(5);\n        \n        var gutter = 0;\n        var name = 'Test Layer';\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        var params = { map: '/mapdata/vmap_wms.map', \n                       layers: 'basic', \n                       format: 'image/png'};\n\n\n        var map = new OpenLayers.Map('map', {tileManager: null});\n        var layer = new OpenLayers.Layer.WMS(name, url, params, {gutter: gutter});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 5);\n        \n        var tile = layer.grid[0][0];\n        t.ok(tile.layer.imageSize == null,\n             \"zero size gutter doesn't set image size\"); \n\n        var zero_gutter_bounds = tile.bounds;\n        \n        map.destroy();\n        \n        var gutter = 15;\n        var map = new OpenLayers.Map('map', {tileManager: null});\n        var layer = new OpenLayers.Layer.WMS(name, url, params, {gutter: gutter});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 5);\n        var tile = layer.grid[0][0];\n        t.ok(tile.layer.imageSize.equals(new OpenLayers.Size(tile.size.w + (2 * gutter),\n                                                             tile.size.h + (2 * gutter))),\n             \"gutter properly changes image size\"); \n\n        var offsetLeft = -(gutter / layer.tileSize.w * 100) | 0;\n        var offsetTop = -(gutter / layer.tileSize.h * 100) | 0;\n        t.eq(parseInt(tile.imgDiv.style.left, 10), offsetLeft,\n             \"gutter properly sets image left style\");\n        t.eq(parseInt(tile.imgDiv.style.top, 10), offsetTop,\n             \"gutter properly sets image top style\");\n        t.ok(tile.bounds.equals(zero_gutter_bounds),\n             \"gutter doesn't affect tile bounds\");\n\n        map.destroy();\n    }\n    \n    function test_createBackBuffer(t) {\n        t.plan(3);\n\n        var map = new OpenLayers.Map('map', {tileManager: null});\n        var layer = new OpenLayers.Layer.WMS( \"OpenLayers WMS\", \n            \"../../img/blank.gif\", {layers: 'basic'});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 5);\n        var tile = layer.grid[0][0];\n\n        // we're going to create a back buffer while the image\n        // is actually loading, so we call stopObservingElement\n        // to avoid any unexpected behavior\n        tile.isLoading = false;\n        OpenLayers.Event.stopObservingElement(tile.imgDiv);\n\n        var img = tile.imgDiv;\n        var left = img.style.left;\n        var bb = tile.createBackBuffer();\n        t.eq(bb.style.left, left, \"backbuffer has same left style as frame\");\n        t.ok(bb === img, \"image appended to bb\");\n        t.ok(tile.imgDiv == null, \"image reference removed from tile\");\n        map.destroy();\n    }\n\n    function test_onImageLoad(t) {\n        t.plan(3);\n\n        var map = new OpenLayers.Map('map', {tileManager: null});\n        var layer = new OpenLayers.Layer.WMS( \"OpenLayers WMS\",\n            \"../../img/blank.gif\", {layers: 'basic'}, {opacity: 0.5});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 5);\n\n        var tile = layer.grid[0][0];\n\n        var log;\n        tile.events.on({loadend: function() { log++; }});\n\n        log = 0;\n        tile.onImageLoad();\n        t.eq(tile.imgDiv.style.visibility, 'inherit',\n             'onImageLoad makes the image visible');\n        t.eq(parseFloat(tile.imgDiv.style.opacity), 0.5,\n             'onImageLoad sets the expected opacity for the image');\n        t.eq(log, 1,\n             'onImageLoad does trigger loadend');\n\n        map.destroy();\n    }\n\n    function test_getCanvasContext(t) {\n        if (!OpenLayers.CANVAS_SUPPORTED) {\n            t.plan(0);\n        } else {\n            t.plan(1);\n\n            var map = new OpenLayers.Map('map');\n            var layer = new OpenLayers.Layer.WMS(\"blank\",\n                \"../../img/blank.gif\", {layers: 'fake'});\n            map.addLayer(layer);\n            map.setCenter(new OpenLayers.LonLat(0, 0), 5);\n\n            t.delay_call(5, function() {\n                var tile = layer.grid[0][0];\n                tile.onImageLoad();\n                t.ok(tile.getCanvasContext() instanceof CanvasRenderingContext2D,\n                     \"getCanvasContext() returns CanvasRenderingContext2D instance\");\n                map.destroy();\n            });\n        }\n    }\n\n    /*\n     * A series of tests to verify the dimensions and positions\n     * of the tile frame and img after draw.\n\n     * Written for https://github.com/openlayers/openlayers/issues/441\n     */\n    function test_draw_without_gutter_without_frame(t) {\n        t.plan(5);\n\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS('blank',\n                        '../../img/blank.gif',\n                        {layers: 'fake'},\n                        {isBaseLayer: true});\n        map.addLayer(layer);\n        var tile = new OpenLayers.Tile.Image(\n                            layer,\n                            new OpenLayers.Pixel(6, 6),\n                            new OpenLayers.Bounds(5, 45, 6, 46),\n                            null,\n                            new OpenLayers.Size(256, 256));\n\n        tile.draw();\n        t.eq(tile.frame, null, 'no frame');\n        t.eq(parseInt(tile.imgDiv.style.left, 10), 6, 'correct tile img left');\n        t.eq(parseInt(tile.imgDiv.style.top, 10), 6, 'correct tile img top');\n        t.eq(parseInt(tile.imgDiv.style.width, 10), 256, 'correct tile img width');\n        t.eq(parseInt(tile.imgDiv.style.height, 10), 256, 'correct tile img height');\n\n        map.destroy();\n    }\n    function test_draw_without_gutter_with_frame(t) {\n        t.plan(8);\n\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS('blank',\n                        '../../img/blank.gif',\n                        {layers: 'fake'},\n                        {isBaseLayer: true});\n        map.addLayer(layer);\n        layer.gutter = 1; // this is just for a frame to be created for\n                          // the tile\n        var tile = new OpenLayers.Tile.Image(\n                            layer,\n                            new OpenLayers.Pixel(6, 6),\n                            new OpenLayers.Bounds(5, 45, 6, 46),\n                            null,\n                            new OpenLayers.Size(256, 256));\n        layer.gutter = null;\n\n        tile.draw();\n        t.eq(parseInt(tile.frame.style.left, 10), 6, 'correct tile frame left');\n        t.eq(parseInt(tile.frame.style.top, 10), 6, 'correct tile frame top');\n        t.eq(parseInt(tile.frame.style.width, 10), 256, 'correct tile frame width');\n        t.eq(parseInt(tile.frame.style.height, 10), 256, 'correct tile frame height');\n        t.eq(parseInt(tile.imgDiv.style.left, 10), 0, 'correct tile img left');\n        t.eq(parseInt(tile.imgDiv.style.top, 10), 0, 'correct tile img top');\n        t.eq(parseInt(tile.imgDiv.style.width, 10), 100, 'correct tile img width');\n        t.eq(parseInt(tile.imgDiv.style.height, 10), 100, 'correct tile img height');\n\n        map.destroy();\n    }\n    function test_draw_with_gutter(t) {\n        t.plan(8);\n\n        var map = new OpenLayers.Map('map');\n        var layer = new OpenLayers.Layer.WMS('blank',\n                        '../../img/blank.gif',\n                        {layers: 'fake'},\n                        {isBaseLayer: true, gutter: 15});\n        map.addLayer(layer);\n        var tile = new OpenLayers.Tile.Image(\n                            layer,\n                            new OpenLayers.Pixel(6, 6),\n                            new OpenLayers.Bounds(5, 45, 6, 46),\n                            null,\n                            new OpenLayers.Size(256, 256));\n\n        tile.draw();\n        t.eq(parseInt(tile.frame.style.left, 10), 6, 'correct tile frame left');\n        t.eq(parseInt(tile.frame.style.top, 10), 6, 'correct tile frame top');\n        t.eq(parseInt(tile.frame.style.width, 10), 256, 'correct tile frame width');\n        t.eq(parseInt(tile.frame.style.height, 10), 256, 'correct tile frame height');\n        t.eq(parseInt(tile.imgDiv.style.left, 10), -5, 'correct tile img left');\n        t.eq(parseInt(tile.imgDiv.style.top, 10), -5, 'correct tile img top');\n        t.eq(parseInt(tile.imgDiv.style.width, 10), 111, 'correct tile img width');\n        t.eq(parseInt(tile.imgDiv.style.height, 10), 111, 'correct tile img height');\n\n        map.destroy();\n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"height:550px;width:500px\"></div>\n</body>\n</html>\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Tile/UTFGrid.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">\n  <script>\n      /**\n      * Because browsers that implement requestAnimationFrame may not execute\n      * animation functions while a window is not displayed (e.g. in a hidden\n      * iframe as in these tests), we mask the native implementations here.  The\n      * native requestAnimationFrame functionality is tested in Util.html and\n      * in PanZoom.html (where a popup is opened before panning).  The panTo tests\n      * here will test the fallback setTimeout implementation for animation.\n      */\n      window.requestAnimationFrame = \n          window.webkitRequestAnimationFrame =\n          window.mozRequestAnimationFrame =\n          window.oRequestAnimationFrame =\n          window.msRequestAnimationFrame = null;\n  </script>\n  <script src=\"../OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n    var map, layer;\n    function setUp() {\n        layer = new OpenLayers.Layer.UTFGrid({\n            url: \"../data/utfgrid/world_utfgrid/${z}/${x}/${y}.json\",\n            isBaseLayer: true, \n            utfgridResolution: 4\n        });\n        map = new OpenLayers.Map({\n            div: \"map\",\n            projection: \"EPSG:900913\",\n            layers: [layer],\n            center: [0, 0],\n            zoom: 1,\n            tileManager: null\n        });\n    }\n    \n    function tearDown() {\n        map.destroy();\n        map = null;\n        layer = null;\n    }\n\n    function test_constructor(t) {\n        t.plan(7);\n\n        setUp();\n        \n        var position = new OpenLayers.Pixel(20, 30);\n        var bounds = new OpenLayers.Bounds(1, 2, 3, 4);\n        var url = \"http://example.com/\";\n        var size = new OpenLayers.Size(5, 6);\n        var tile = new OpenLayers.Tile.UTFGrid(layer, position, bounds, url, size);\n        \n        t.ok(tile instanceof OpenLayers.Tile, \"tile instance\");\n        t.ok(tile instanceof OpenLayers.Tile.UTFGrid, \"UTFGrid tile instance\");\n        t.ok(tile.layer === layer, \"layer set\");\n        t.ok(tile.position.equals(position), \"position set\");\n        t.ok(tile.bounds.equals(bounds), \"bounds set\");\n        t.eq(tile.url, url, \"url set\");\n        t.ok(tile.size.equals(size), \"size set\");\n        \n        tearDown();\n    }\n    \n    function test_parseData(t) {\n        t.plan(2);\n        setUp();\n\n        var tile = layer.grid[0][0];\n        \n        tile.parseData('{\"foo\": \"bar\"}');\n        t.eq(tile.json, {foo: \"bar\"}, \"valid json parsed\");\n        \n        var err, obj;\n        try {\n            obj = tile.parseData('foo bar');\n        } catch (e) {\n            err = e;\n        }\n        // The JSON format doesn't actually throw on IE6, so we also check\n        // for undefined here.\n        t.ok(err instanceof Error || obj === undefined, \"throws on invalid json\");\n        \n        tearDown();\n    }\n    \n    function test_draw(t) {\n        t.plan(7);\n        setUp();\n        \n        var position = new OpenLayers.Pixel(20, 30);\n        var bounds = new OpenLayers.Bounds(1, 2, 3, 4);\n        var url = \"../data/utfgrid/world_utfgrid/${z}/${x}/${y}.json\";\n        var size = new OpenLayers.Size(256, 256);\n        var tile = new OpenLayers.Tile.UTFGrid(layer, position, bounds, url, size);\n        \n        var log = [];\n        function logger(event) {\n            log.push(event);\n        }\n        tile.events.on({\n            loadstart: logger,\n            reload: logger,\n            loadend: logger\n        });\n        \n        t.eq(log.length, 0, \"no events logged\");\n        \n        // start tile loading\n        tile.draw();\n        t.eq(log.length, 1, \"[first draw] one event\");\n        t.eq(log[0].type, \"loadstart\", \"[first draw] loadstart\");\n        \n        // restart tile loading\n        log.length = 0;\n        tile.draw();\n        t.eq(log.length, 1, \"[second draw] first event\");\n        t.eq(log[0].type, \"reload\", \"[second draw] reload\");\n        \n        // wait for tile loading to finish\n        t.delay_call(1, function() {\n            t.eq(log.length, 2, \"[second draw] second event\");\n            t.eq(log[1].type, \"loadend\", \"[second draw] loadend\");\n            tearDown();\n        });\n        \n    }\n\n    function test_abortLoading(t) {\n        t.plan(7);\n        setUp();\n        \n        var position = new OpenLayers.Pixel(20, 30);\n        var bounds = new OpenLayers.Bounds(1, 2, 3, 4);\n        var url = \"../data/utfgrid/world_utfgrid/${z}/${x}/${y}.json\";\n        var size = new OpenLayers.Size(256, 256);\n        var tile = new OpenLayers.Tile.UTFGrid(layer, position, bounds, url, size);\n        \n        var log = [];\n        function logger(event) {\n            log.push(event);\n        }\n        tile.events.on({\n            loadstart: logger,\n            reload: logger,\n            loadend: logger\n        });\n        \n        t.eq(log.length, 0, \"no events logged\");\n        \n        // start tile loading\n        tile.draw();\n        t.eq(log.length, 1, \"[first draw] one event\");\n        t.eq(log[0].type, \"loadstart\", \"[first draw] loadstart\");\n        \n        // abort tile loading\n        log.length = 0;\n        tile.abortLoading();\n        t.eq(log.length, 0, \"[first abort] no events logged\"); // TODO: does anybody need an abort event?\n        \n        // abort again for the heck of it\n        var err;\n        try {\n            tile.abortLoading();\n        } catch (e) {\n            err = e;\n        }\n        t.ok(!err, \"[second abort] no trouble\");\n        t.eq(log.length, 0, \"[second abort] no events\");\n        \n        // wait to confirm tile loading doesn't happen after abort\n        t.delay_call(1, function() {\n            t.eq(log.length, 0, \"[wait] no events\");\n            tearDown();\n        });\n        \n    }\n    \n    function test_getFeatureId(t) {\n        t.plan(3);\n        setUp();\n        \n        var tile = layer.grid[1][1];\n        t.delay_call(0.5, function() {\n            var id = tile.getFeatureId(16, 60);\n            t.eq(id, \"238\", \"feature 238 at 16, 60\");\n            t.eq(tile.getFeatureId(18, 63), id, \"same feature at 18, 63\");\n            \n            t.eq(tile.getFeatureId(300, 10), null, \"null id outside tile\");\n            \n            tearDown();\n        });\n    }\n\n    function test_getFeatureInfo(t) {\n        t.plan(3);\n        setUp();\n        \n        var tile = layer.grid[1][1];\n        t.delay_call(0.5, function() {\n            var info = tile.getFeatureInfo(16, 60);\n            var exp = {\n                id: \"238\",\n                data: {\n                    NAME: \"Svalbard\",\n                    POP2005: 0\n                }\n            };\n            t.eq(info, exp, \"feature info at 16, 60\");\n            t.eq(tile.getFeatureInfo(17, 62), exp, \"same feature at 17, 62\");\n\n            t.eq(tile.getFeatureInfo(300, 10), null, \"undefined outside tile\");\n\n            tearDown();\n        });\n    }\n    \n    // While I dislike committing tests that aren't run, I'd like to make an \n    // exception here.  This test (or something like it) should pass.  When\n    // https://github.com/mapbox/utfgrid-spec/issues/1 is resolved, we should\n    // either modify this or update demo.json and enable the test.\n    function xtest_getFeatureId_demo(t) {\n        /**\n         * The UTFGrid 1.2 spec (https://github.com/mapbox/utfgrid-spec/blob/master/1.2/utfgrid.md)\n         * links to a demo.json to be used for testing implementations.  This\n         * file is constructed with 256x256 data points.  Each data point maps\n         * to a \"feature id\" using this heuristic:\n         *\n         *     // x and y are pixel offsets from top left of 256x256 tile\n         *     if (y < 255 || x < 222) {\n         *         id = (y * 256) + x\n         *     } else {\n         *         id = 65501; // max number of ids that can be encoded\n         *     }\n         */\n        t.plan(1);\n        setUp();\n        \n        // look at this beauty of a constructor\n        var tile = new OpenLayers.Tile.UTFGrid(\n            layer, // layer\n            new OpenLayers.Pixel(0, 0), // position\n            new OpenLayers.Bounds(0, 0, 256, 256), // bounds\n            \"../data/utfgrid/demo-1.1.json\", // url\n            new OpenLayers.Size(256, 256), // size\n            {utfgridResolution: 1} // options\n        );\n        \n        var err;        \n        var request = new OpenLayers.Request.GET({\n            url: tile.url,\n            success: function(req) {\n                try {\n                    tile.parseData(req.responseText);\n                } catch (e) {\n                    err = e;\n                }\n            },\n            failure: function(req) {\n                err = new Error(\"Failed to fetch json.  Status: \" + req.status);\n            }\n        });\n        \n        // wait for response and parsing, then make assertions\n        t.delay_call(1, function() {\n            if (err) {\n                t.fail(err);\n            } else {\n                var got, exp, failure;\n                outer: for (var y=0; y<256; ++y) {\n                    for (var x=0; x<256; ++x) {\n                        if (y<255 || x<222) {\n                            exp = String((y * 256) + x);\n                        } else {\n                            exp = \"65501\";\n                        }\n                        got = tile.getFeatureId(x, y);\n                        if (got !== exp) {\n                            failure = \"Failed to get id for (\" + x + \", \" + y + \"): \" +\n                                \"got \" + got + \" but expected \" + exp;\n                            \n                            break outer;\n                        }\n                    }\n                }\n                if (!failure) {\n                    t.ok(true, \"resolved feature ids for all data points\");\n                } else {\n                    t.fail(failure);\n                }\n            }\n            tearDown();\n        });\n        \n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"height:550px;width:500px\"></div>\n</body>\n</html>\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Tile.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n    var tile; \n\n    var map, layer;\n    function setUp() {\n        map = new OpenLayers.Map(\"map\");\n        layer = new OpenLayers.Layer(null, {\n            isBaseLayer: true\n        });\n        map.addLayer(layer)\n        map.setCenter(new OpenLayers.LonLat(0, 0));\n    }\n    \n    function tearDown() {\n        map.destroy();\n        map = null;\n        layer = null;\n    }\n\n    \n    function test_Tile_constructor (t) {\n        t.plan( 13 );\n     \n        setUp();\n        \n        var dummy = {};\n\n        var position = new OpenLayers.Pixel(10,20);\n        var bounds = new OpenLayers.Bounds(1,2,3,4);\n        var url = \"bobob\";\n        var size = new OpenLayers.Size(5,6);\n        \n        tile = new OpenLayers.Tile(layer, position, bounds, url, size, {\n            eventListeners: {\n                loadstart: OpenLayers.Function.False\n            }\n        });\n\n        t.ok(tile instanceof OpenLayers.Tile, \"new OpenLayers.Tile returns Tile object\");\n        t.ok(tile.layer === layer, \"tile.layer set correctly\");\n        t.ok(tile.position.equals(position), \"tile.position set correctly\");\n        t.ok(tile.position != position, \"tile.position set not by reference\");\n        t.ok(tile.bounds.equals(bounds), \"tile.bounds set correctly\");\n        t.ok(tile.bounds != bounds, \"tile.bounds set not by reference\");\n        t.eq(tile.url, url, \"tile.url set correctly\");        \n        t.ok(tile.size.equals(size), \"tile.size is set correctly\");\n        t.ok(tile.size != size, \"tile.size set not by reference\");\n\n        t.ok(tile.id != null, \"tile is given an id\");\n        t.ok(OpenLayers.String.startsWith(tile.id, \"Tile_\"),\n             \"tile's id starts correctly\");\n        t.ok(tile.events != null, \"tile's events initialized\");\n        t.ok(tile.events.listeners.loadstart.length == 1, \n             \"tile's events initialized from eventListeners option\");\n        \n        tearDown();\n        \n    }\n    \n    function test_Tile_draw(t) {\n        t.plan(6);\n        setUp();\n\n        var position = new OpenLayers.Pixel(10,20);\n        var bounds = new OpenLayers.Bounds(1,2,3,4);\n        var url = \"bobob\";\n        var size = new OpenLayers.Size(5,6);\n        \n        tile = new OpenLayers.Tile(layer, position, bounds, url, size);\n        var log = [];\n        tile.clear = function() {\n            log.push(\"clear\");\n        }\n        tile.draw();\n        t.eq(log.length, 1, \"Tile cleared before drawing\");\n        \n        log = [];\n        tile.events.register(\"beforedraw\", this, function() {\n            log.push(\"beforedraw\");\n            return false;\n        });\n        var drawn = tile.draw();\n        t.eq(log[0], \"clear\", \"tile cleared\");\n        t.eq(log[1], \"beforedraw\", \"beforedraw event fired\");\n        t.eq(drawn, null, \"tile not drawn when beforedraw listener returns false\");\n        drawn = tile.draw(true);\n        t.eq(log.length, 2, \"no beforedraw event fired and tile not cleared when draw called with 'deferred' argument set to true\");\n        t.eq(drawn, true, \"tile drawn when draw called with 'deferred' argument set to true\");\n\n        tearDown();\n    }\n\n    function test_Tile_destroy(t) {\n        t.plan( 6 );\n        \n        setUp();\n\n        var position = new OpenLayers.Pixel(10,20);\n        var bounds = new OpenLayers.Bounds(1,2,3,4);\n        var url = \"bobob\";\n        var size = new OpenLayers.Size(5,6);\n        \n        tile = new OpenLayers.Tile(layer, position, bounds, url, size);\n        tile.events.destroy = function() {\n            t.ok(true, \"tile events destroy() called\");\n        };\n\n \n        tile.destroy();\n\n        t.ok(tile.layer == null, \"tile.layer set to null\");\n        t.ok(tile.bounds == null, \"tile.bounds set to null\");\n        t.ok(tile.size == null, \"tile.size set to null\");\n        t.ok(tile.position == null, \"tile.position set to null\");\n        \n        t.ok(tile.events == null, \"tile.events set to null\");\n        \n        tearDown();\n        \n    }\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/TileManager.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n  \n    function test_initialize(t) {\n        t.plan(4);\n        \n        var tileManager = new OpenLayers.TileManager();\n        var map = new OpenLayers.Map('map', {\n            zoomMethod: null,\n            tileManager: tileManager\n        });\n        var layer = new OpenLayers.Layer.WMS('WMS1', '../img/blank.gif');\n        map.addLayer(layer);\n        map.setCenter([16, 48], 9);\n        t.ok(tileManager.tileQueue[map.id].length, \"Tiles queued from layer\");\n        map.removeLayer(layer);\n        t.eq(tileManager.tileQueue[map.id].length, 0, \"Tiles unqueued when layer is removed\");\n        map.addLayer(new OpenLayers.Layer.WMS('WMS2', '../img/blank.gif'));\n        map.zoomIn();\n        t.ok(tileManager.tileQueue[map.id].length, \"Tiles queued from added layer\");\n        map.destroy();\n        t.eq(tileManager.tileQueue[map.id], undefined, \"Tile queue removed when map was destroyed\");\n    }\n    \n    function test_destroy(t) {\n        t.plan(3);\n        \n        var tileManager = new OpenLayers.TileManager();\n        var map = new OpenLayers.Map('map', {tileManager: tileManager});\n        var layer = new OpenLayers.Layer.WMS('WMS', '../img/blank.gif');\n        map.addLayer(layer);\n        map.setCenter([16, 48], 9);\n        var numTileListeners = layer.grid[0][0].events.listeners.beforeload.length;\n        var numLayerListeners = layer.events.listeners.retile.length;\n        var numMapListeners = map.events.listeners.preremovelayer.length;\n        tileManager.destroy();\n        t.eq(layer.grid[0][0].events.listeners.beforeload.length, numTileListeners - 1, \"no listener on tile after destroy\");\n        t.eq(layer.events.listeners.retile.length, numLayerListeners - 1, \"no listeners on layer after destroy\");\n        t.eq(map.events.listeners.preremovelayer.length, numMapListeners - 1, \"no listeners on map after destroy\");\n        map.destroy();\n    }\n\n    function test_manageTileCache(t) {\n        t.plan(10);\n        \n        var tileManager = new OpenLayers.TileManager({\n            cacheSize: 12\n        });\n        var map = new OpenLayers.Map('map', {tileManager: tileManager});\n        layer = new OpenLayers.Layer.WMS('WMS', '../img/blank.gif');\n        map.addLayer(layer);\n        map.setCenter([16, 48], 9);\n        var gridSize;\n        \n        var firstInCache, sharedTile;\n        t.delay_call(2, function() {\n            t.eq(tileManager.tileCacheIndex.length, 12, \"tiles cached\");\n            t.ok(~OpenLayers.Util.indexOf(tileManager.tileCacheIndex, layer.grid[1][2].url), \"tile found in cache\");\n            t.ok(tileManager.tileCache[layer.grid[1][2].url] === layer.grid[1][2].imgDiv, \"correct object cached\");\n            firstInCache = tileManager.tileCache[tileManager.tileCacheIndex[0]];\n            sharedTile = tileManager.tileCache[tileManager.tileCacheIndex[11]];\n            gridSize = layer.div.childNodes.length;\n            map.setCenter([17, 47]);\n        });\n\n        function inCache(img) {\n            var search = img.src.split('?')[1];\n            for (var s in tileManager.tileCache) {\n                if (s.split('?')[1] == search) {\n                    return true;\n                }\n            }\n            return false;\n        }\n\n        t.delay_call(4, function() {\n            t.eq(tileManager.tileCacheIndex.length, 12, \"tiles cached\");\n            t.ok(tileManager.tileCache[layer.grid[1][2].url] === layer.grid[1][2].imgDiv, \"correct object cached\");\n            t.ok(!inCache(firstInCache), \"old tile discarded\");\n            t.ok(inCache(sharedTile), \"shared tile still in cache\");\n            firstInCache = tileManager.tileCache[tileManager.tileCacheIndex[0]];\n            map.setCenter([16, 48]);\n        });\n        t.delay_call(6, function() {\n            t.ok(!inCache(firstInCache), \"old tile discarded\");\n            t.ok(inCache(sharedTile), \"shared tile still in cache\");\n            t.eq(layer.div.childNodes.length, gridSize, 'no unused images left in dom');\n            map.destroy();\n        });\n    }\n    \n    function test_queueTileDraw(t) {\n        t.plan(3);\n\n        var tileManager = new OpenLayers.TileManager();\n        var map = new OpenLayers.Map('map', {tileManager: tileManager});\n        layer = new OpenLayers.Layer.WMS('WMS', '../img/blank.gif');\n        map.addLayer(layer);\n        map.setCenter([0, 0], 3);\n        var queued = tileManager.tileQueue[map.id].length;\n        t.ok(tileManager.tileQueue[map.id].length, \"Tiles queued for drawing\");\n        map.zoomIn();\n        t.eq(tileManager.tileQueue[map.id].length, queued, \"Tile queue has same length after immediate zoom change\");\n        t.delay_call(1, function() {\n            t.eq(tileManager.tileQueue[map.id].length, 0, \"Tiles from queue processed\");        \n            map.destroy();\n        });\n    }\n    \n    function test_deferTileDraw(t) {\n\n        t.plan(3);\n\n        var tileManager = new OpenLayers.TileManager();\n        var map = new OpenLayers.Map('map', {tileManager: tileManager});\n        layer = new OpenLayers.Layer.WMS('WMS', '../img/blank.gif');\n        layer.destroy = function() {}; //we're going to do funky things with the grid\n        layer.applyBackBuffer = function() {}; // backbuffering isn't under test here\n        map.addLayer(layer);\n        map.setCenter([-10, 0], 5);\n        \n        map.moveTo([5, 0]);\n        t.ok(tileManager.tileQueue[map.id].length, \"tile loading deferred after moveTo\");\n        map.moveTo([0, 0]);\n        t.ok(tileManager.tileQueue[map.id].length, \"deferred again after another moveTo\");\n        t.delay_call(1, function() {\n            t.eq(tileManager.tileQueue[map.id].length, 0, \"tiles loaded after moveDelay\");\n        });\n    }\n\n    function test_handleLayerRefresh(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map( 'map', {maxResolution: 1.40625/2} );\n        var layer = new OpenLayers.Layer.TMS( \"TMS\",\n                \"../img/blank.gif/\", {layername: 'basic', type:'png'} );\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(5, 40), 5);\n        var log = 0;\n        t.delay_call(1, function() {\n            var origSetImgSrc = OpenLayers.Tile.Image.prototype.setImgSrc;\n            OpenLayers.Tile.Image.prototype.setImgSrc = function() {\n                ++log;\n                OpenLayers.Tile.Image.prototype.setImgSrc = origSetImgSrc;\n            };\n            layer.redraw(true);\n        });\n        t.delay_call(1.5, function() {\n            t.ok(log > 0, 'setImgSrc called to refresh tile.');\n        });\n    }\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:499px;height:549px;display:none\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Tween.html",
    "content": "<html> \n<head> \n    <script>\n    /**\n    * Because browsers that implement requestAnimationFrame may not execute\n    * animation functions while a window is not displayed (e.g. in a hidden\n    * iframe as in these tests), we mask the native implementations here.  The\n    * native requestAnimationFrame functionality is tested in Util.html and\n    * in PanZoom.html (where a popup is opened before panning).  The panTo tests\n    * here will test the fallback setTimeout implementation for animation.\n    */\n    window.requestAnimationFrame = \n        window.webkitRequestAnimationFrame =\n        window.mozRequestAnimationFrame =\n        window.oRequestAnimationFrame =\n        window.msRequestAnimationFrame = null;\n    </script>\n    <script src=\"OLLoader.js\"></script> \n    <script type=\"text/javascript\">\n\n    function test_Tween_constructor(t) { \n        t.plan(3);\n        \n        var tween = new OpenLayers.Tween();\n        t.ok(tween instanceof OpenLayers.Tween, \n             \"new OpenLayers.Tween returns object\" );\n        t.eq(typeof tween.easing, \"function\", \n            \"constructor sets easing correctly\"); \n        t.eq(typeof tween.start, \"function\", \"tween has a start function\"); \n    }\n    \n    function test_Tween_start(t) {\n        t.plan(5);\n        \n        var tween = new OpenLayers.Tween();\n\n        var start = {foo: 0, bar: 10};\n        var finish = {foo: 10, bar: 0};\n        var _start = false;\n        var _done = false;\n        var _eachStep = false;\n        var callbacks = {\n            start: function() {\n                _start = true;\n            },\n            done: function() {\n                _done = true;\n            },\n            eachStep: function() {\n                _eachStep = true;\n            }\n        }\n        tween.start(start, finish, 10, {callbacks: callbacks});\n        t.ok(tween.animationId != null, \"animationId correctly set\");\n        t.delay_call(0.8, function() {\n            t.eq(_start, true, \"start callback called\");\n            t.eq(_done, true, \"finish callback called\");\n            t.eq(_eachStep, true, \"eachStep callback called\");\n            t.eq(tween.time, 11, \"Number of steps reached is correct\");\n        });\n    }\n\n    function test_Tween_stop(t) {\n        t.plan(2);\n        \n        var tween = new OpenLayers.Tween();\n        tween.animationId = OpenLayers.Animation.start(function() {});\n        tween.playing = true;\n        tween.stop();\n        t.eq(tween.animationId, null, \"tween correctly stopped\");\n        \n        tween.animationId = OpenLayers.Animation.start(function() {});\n        tween.playing = false;\n        tween.stop();\n        t.ok(tween.animationId != null, \"stop method doesn't do anything if tween isn't running\");\n    }\n    \n    function test_Tween_skip(t) {\n        t.plan(2);\n        \n        var tween = new OpenLayers.Tween();\n        var log = 0;\n        tween.start({count: 0}, {count: 10}, 10, {\n            callbacks: {\n                eachStep: function() {\n                    log++;\n                }\n            },\n            minFrameRate: 10000\n        });\n        \n        t.delay_call(0.8, function() {\n            t.eq(log, 0, 'all frames skipped at a frame rate of 10000');\n            \n            log = 0;\n            tween.start({count: 0}, {count: 10}, 10, {\n                callbacks: {\n                    eachStep: function() {\n                        log++;\n                    }\n                },\n                minFrameRate: 1\n            });\n        });\n        \n        t.delay_call(1.6, function() {\n            t.eq(log, 11, 'no frames skipped at a frame rate of 1');            \n        });\n    }\n\n    </script> \n</head> \n<body> \n  <div id=\"map\" style=\"width:500px;height:500px\"></div>\n</body> \n</html> \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Util/vendorPrefix.html",
    "content": "<!DOCTYPE html>\n<html>\n    <head>\n        <title>vendorPrefix.js Tests</title>\n        <script>\n        var div = document.createElement(\"div\");\n        var style = div.style,\n            orgCreateElement = document.createElement;\n            \n        // wrap document.createElement to control property values\n        document.createElement = function(type) {\n            return div;\n        };\n\n        // dependencies for tests\n        var OpenLayers = [\n            \"OpenLayers/Util/vendorPrefix.js\"\n        ];\n\n        </script>\n        <script src=\"../OLLoader.js\"></script>\n\n        <script>\n        \n        /**\n         * Test vendor prefixing\n         */\n        function test_vendor_prefixes(t) {\n            t.plan(20);\n            var err;\n            \n            function clearCache(type) {\n                var cache = OpenLayers.Util.vendorPrefix[type.replace(\"style\", \"js\") + \"Cache\"];\n                for (var key in cache) {\n                    delete cache[key];\n                }\n            }\n            \n            function setStyleMockProp(prop, value) {\n                if (prop && value === undefined) {\n                    delete style[prop];\n                } else if (prop) {\n                    style[prop] = value;\n                }\n            }\n            \n            function curryTestPrefix(type) {\n                return function(standardProp, expectedPrefix, msg) {\n                        var prefixedProp, err;\n                        try {\n                            clearCache(type);\n                            setStyleMockProp(expectedPrefix, \"\");\n                            prefixedProp = OpenLayers.Util.vendorPrefix[type](standardProp);\n                        } catch(e) {\n                            err = e;\n                        } finally {\n                            setStyleMockProp(expectedPrefix, undefined);\n                        }\n                        \n                        if(!err) {\n                            t.eq(prefixedProp, expectedPrefix, msg);\n                        } else {\n                            t.fail(\"Error when testing \" + type.toUpperCase() + \" vendor prefix: \" + err.message);\n                        }\n                };\n            }\n            var testDomPrefix = curryTestPrefix(\"style\"),\n                testCssPrefix = curryTestPrefix(\"css\");\n\n            testDomPrefix(\"unsupported\", null, \"DOM vendor prefix - unsupported\");\n            testCssPrefix(\"unsupported\", null, \"CSS vendor prefix - unsupported\");\n\n            testDomPrefix(\"test\", \"test\", \"DOM vendor prefix - single word\");\n            testCssPrefix(\"test\", \"test\", \"CSS vendor prefix - single word\");\n\n            testDomPrefix(\"testMultiWord\", \"testMultiWord\", \"DOM vendor prefix - multiple words\");\n            testCssPrefix(\"test-multi-word\", \"test-multi-word\", \"CSS vendor prefix - multiple words\");\n\n            testDomPrefix(\"multiWord\", \"WebkitMultiWord\", \"DOM vendor prefix - multiple words for WebKit\");\n            testCssPrefix(\"multi-word\", \"-webkit-multi-word\", \"CSS vendor prefix - multiple words for WebKit\");\n\n            testDomPrefix(\"multiWord\", \"MozMultiWord\", \"DOM vendor prefix - multiple words for Mozilla\");\n            testCssPrefix(\"multi-word\", \"-moz-multi-word\", \"CSS vendor prefix - multiple words for Mozilla\");\n\n            testDomPrefix(\"multiWord\", \"OMultiWord\", \"DOM vendor prefix - multiple words for Opera\");\n            testCssPrefix(\"multi-word\", \"-o-multi-word\", \"CSS vendor prefix - multiple words for Opera\");\n\n            testDomPrefix(\"multiWord\", \"msMultiWord\", \"DOM vendor prefix - multiple words for Internet Explorer\");\n            testCssPrefix(\"multi-word\", \"-ms-multi-word\", \"CSS vendor prefix - multiple words for Internet Explorer\");\n\n            // test vendor prefix on object\n            clearCache(\"js\");\n            t.eq( OpenLayers.Util.vendorPrefix.js( {}, \"unsupported\" ), null, \"Standard object property - unsupported\");\n\n            clearCache(\"js\");\n            t.eq( OpenLayers.Util.vendorPrefix.js( { \"test\": true }, \"test\" ), \"test\", \"Standard object property\");\n\n            clearCache(\"js\");\n            t.eq( OpenLayers.Util.vendorPrefix.js( { \"oTest\": true }, \"test\" ), \"oTest\", \"Standard object property\");\n\n            clearCache(\"js\");\n            t.eq( OpenLayers.Util.vendorPrefix.js( { \"msTest\": true }, \"test\" ), \"msTest\", \"Standard object property\");\n\n            clearCache(\"js\");\n            t.eq( OpenLayers.Util.vendorPrefix.js( { \"mozTest\": true }, \"test\" ), \"mozTest\", \"Standard object property\");\n\n            clearCache(\"js\");\n            t.eq( OpenLayers.Util.vendorPrefix.js( { \"webkitTest\": true }, \"test\" ), \"webkitTest\", \"Standard object property\");\n\n            // unwrap document.createElement\n            document.createElement = orgCreateElement;\n        }\n        \n        </script>\n    </head>\n    <body></body>\n</html>"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Util.html",
    "content": "<html>\n<head>\n  <meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n  <style>\n    body {\n        margin: 0;\n        padding: 0;\n    }\n    #map {\n        position: absolute;\n        top:  1234px;\n        left: 123px;\n    }\n    .test_getRenderedDimensions p{\n        padding: 20px; \n    }\n  </style>\n  <script>\n    var OpenLayers = [\n        \"OpenLayers/BaseTypes/Class.js\",\n        \"OpenLayers/Util.js\",\n        \"OpenLayers/BaseTypes.js\",\n        \"OpenLayers/BaseTypes/Element.js\",\n        \"OpenLayers/BaseTypes/LonLat.js\",\n        \"OpenLayers/BaseTypes/Pixel.js\",\n        \"OpenLayers/BaseTypes/Size.js\",\n        \"OpenLayers/Lang.js\",\n        \"OpenLayers/Console.js\"\n    ];\n  </script>\n  <script src=\"OLLoader.js\"></script>\n  <script src=\"Util_common.js\"></script>\n  <script type=\"text/javascript\">\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var map; \n\n    function test_isElement(t) {\n        t.plan(3);\n\n        // set up\n        var o;\n\n        // tests\n        o = {};\n        t.eq(OpenLayers.Util.isElement(o), false,\n             \"isElement reports that {} isn't an Element\");\n        o = document.createElement(\"div\");\n        t.eq(OpenLayers.Util.isElement(o), true,\n             \"isElement reports that object returned by createElement is an Element\");\n        o = OpenLayers.Util.getElement(\"map\");\n        t.eq(OpenLayers.Util.isElement(o), true,\n             \"isElement reports that object returned by getElement is an Element\");\n    }\n    \n    function test_isArray(t) {\n        t.plan(5);\n        \n        var a;\n        \n        a = null;\n        t.eq(OpenLayers.Util.isArray(a), false, \n             \"isArray reports 'null' isn't an Array\");\n        a = \"Array\";   \n        t.eq(OpenLayers.Util.isArray(a), false, \n             \"isArray reports \\\"Array\\\" isn't an Array\");\n        a = {};\n        t.eq(OpenLayers.Util.isArray(a), false, \n             \"isArray reports {} isn't an Array\");\n        a = [];\n        t.eq(OpenLayers.Util.isArray(a), true, \n             \"isArray reports [] is an Array\");\n        a = new Array();\n        t.eq(OpenLayers.Util.isArray(a), true, \n             \"isArray reports new Array() is an Array\");\n    }\n    \n    function test_iframe_isArray(t) {\n        t.plan(3);\n        // create an array in an iframe\n        var iframe = document.createElement(\"iframe\");\n        document.body.appendChild(iframe);\n        frames[frames.length-1].document.write(\n            \"<script>parent.testArray = [];<\\/script>\"\n        );\n        \n        t.ok(!!testArray, \"testArray created\");\n        t.ok(!(testArray instanceof Array), \"instanceof check doesn't work\");\n        t.eq(OpenLayers.Util.isArray(testArray), true, \"isArray works\");\n    }\n    \n    function test_Util_getImagesLocation (t) {\n        t.plan( 1 );\n        t.ok( OpenLayers.Util.getImagesLocation(), \"../img/\",\n                    \"getImagesLocation()\" );\n    }\n\n    function test_Util_IndexOf(t) {\n        t.plan( 3 );\n        var array = new Array(1, \"bar\");\n        t.eq(OpenLayers.Util.indexOf(array, 1), 0);\n        t.eq(OpenLayers.Util.indexOf(array, \"bar\"), 1);\n        t.eq(OpenLayers.Util.indexOf(array, \"foo\"), -1);\n    }\n\n    function test_Util_Array(t) {\n        t.plan( 2 );\n\n        var array = new Array(1,2,3,4,4,5);\n\n        OpenLayers.Util.removeItem(array, 3);\n        t.eq( array.toString(), \"1,2,4,4,5\", \"Util.removeItem works on one element\");    \n        OpenLayers.Util.removeItem(array, 4);\n        t.eq( array.toString(), \"1,2,5\", \"Util.removeItem works on more than one element \");    \n    }\n    \n    function test_Util_pagePosition(t) {\n        t.plan( 2 );\n\n        // making sure that the test iframe is visible\n        var origDisplay;\n        var parents = window.parent.document.getElementsByTagName('iframe');\n        if (parents.length) {\n            origDisplay = parents[1].parentNode.style.display;\n            // span containing the test iframe is the invisible element\n            parents[1].parentNode.style.display = \"\";\n        }\n\n        var pp = OpenLayers.Util.pagePosition(window);\n        t.eq( pp.toString(), \"0,0\", \"Page position doesn't bail if passed 'window'\");\n        \n        var mapDiv = document.getElementById(\"map\");\n        var beforeScrollPp = OpenLayers.Util.pagePosition(mapDiv);\n        window.scrollTo(100, 1200);\n        pp = OpenLayers.Util.pagePosition(mapDiv);\n        t.eq(pp, beforeScrollPp, \"Page position should work after page has been scrolled\");\n        \n        // reset test iframe visibility\n        if (parents.length) {\n            parents[1].parentNode.style.display = origDisplay;\n        }\n    }\n\n    function test_Util_createDiv(t) {\n        t.plan( 24 );\n\n        var id = \"boo\";\n        var px = new OpenLayers.Pixel(5,5);\n        var sz = new OpenLayers.Size(10,10);\n        var img = \"http://www.openlayers.org/images/OpenLayers.trac.png\";\n        var position = \"absolute\";\n        var border = \"13px solid\";\n        var overflow = \"hidden\";\n        var opacity = 0.5;\n\n        var div = OpenLayers.Util.createDiv(id, px, sz, img, position, border, overflow, opacity);\n\n        if (!isMozilla)\n            t.ok( true, \"skipping element test outside of Mozilla\");\n        else\n            t.ok( div instanceof HTMLDivElement, \"createDiv creates a valid HTMLDivElement\" );\n        t.eq( div.id, id, \"div.id set correctly\");    \n        t.eq( div.style.left, px.x + \"px\", \"div.style.left set correctly\");    \n        t.eq( div.style.top, px.y + \"px\", \"div.style.top set correctly\");    \n\n        t.eq( div.style.width, sz.w + \"px\", \"div.style.width set correctly\");    \n        t.eq( div.style.height, sz.h + \"px\", \"div.style.height set correctly\");    \n\n        bImg = div.style.backgroundImage;\n        imgCorrect = ( (bImg == \"url(\" + img + \")\") ||  \n                       (bImg == \"url(\\\"\" + img + \"\\\")\") );\n        t.ok(imgCorrect, \"div.style.backgroundImage correctly\");    \n\n        t.eq( div.style.position, position, \"div.style.positionset correctly\");    \n        //Safari 3 separates the border style into separate entities when reading it\n        if (OpenLayers.BROWSER_NAME == 'safari') {\n          var s = border.split(' ');\n          t.ok(div.style.borderTopWidth == s[0] && div.style.borderTopStyle == s[1], \"good default popup.border\")\n        } else {\n          t.ok( (div.style.border.indexOf(border) != -1), \"div.style.border set correctly\");\n        }\n            \n        //Safari 3 separates style overflow into overflow-x and overflow-y\n        var prop = (OpenLayers.BROWSER_NAME == 'safari') ? 'overflowX' : 'overflow';\n        t.eq( div.style[prop], overflow, \"div.style.overflow set correctly\");    \n        t.eq( parseFloat(div.style.opacity), opacity, \"element.style.opacity set correctly\");    \n        //Some non-IE browsers don't return the alpha string for this value, which is okay\n        var filterString = div.style.filter.match(/^alpha/) != null ? \n                               'alpha(opacity=' + (opacity * 100) + ')' : div.style.filter;\n        t.eq( div.style.filter, filterString, \"element.style.filter set correctly\");\n\n        //test defaults\n        var div = OpenLayers.Util.createDiv();\n\n        if (!isMozilla)\n            t.ok( true, \"skipping element test outside of Mozilla\");\n        else\n            t.ok( div instanceof HTMLDivElement, \"createDiv creates a valid HTMLDivElement\" );\n        t.ok( (div.id != \"\"), \"div.id set correctly\");    \n        t.eq(div.style.left, \"\", \"div.style.left set correctly\");    \n        t.eq(div.style.top, \"\", \"div.style.top set correctly\");    \n\n        t.eq( div.style.width, \"\", \"div.style.width set correctly\");    \n        t.eq( div.style.height, \"\", \"div.style.height set correctly\");    \n\n        t.eq(div.style.backgroundImage, \"\", \"div.style.backgroundImage correctly\");    \n\n        t.eq( div.style.position, \"absolute\", \"div.style.positionset correctly\");    \n        //Safari 3 separates the border style into separate entities when reading it\n        if (OpenLayers.BROWSER_NAME == 'safari') {\n          t.ok(div.style.borderTopWidth == '' && div.style.borderTopStyle == '', \"good default popup.border\")\n        } else {\n          t.eq( div.style.border, \"\", \"div.style.border set correctly\");    \n        }\n        //Safari 3 separates style overflow into overflow-x and overflow-y\n        var prop = (OpenLayers.BROWSER_NAME == 'safari') ? 'overflowX' : 'overflow';\n        t.eq(div.style[prop], \"\", \"div.style.overflow set correctly\");    \n        t.ok( !div.style.opacity, \"element.style.opacity set correctly\");    \n        t.ok( !div.style.filter, \"element.style.filter set correctly\");\n\n    }\n\n    function test_Util_createImage(t) {\n        t.plan( 22 );\n\n        var img = \"http://www.openlayers.org/images/OpenLayers.trac.png\";\n        var sz = new OpenLayers.Size(10,10);\n        var xy = new OpenLayers.Pixel(5,5);\n        var position = \"absolute\";\n        var id = \"boo\";\n        var border = \"1px solid\";\n        var opacity = 0.5;\n\n        var image = OpenLayers.Util.createImage(id, xy, sz, img, position, border, opacity);\n\n        if (!isMozilla)\n            t.ok( true, \"skipping element test outside of Mozilla\");\n        else\n            t.ok( image.nodeName == \"IMG\", \"createImage creates a valid HTMLImageElement\" );\n        t.eq( image.id, id, \"image.id set correctly\");    \n        t.eq( image.style.left, xy.x + \"px\", \"image.style.left set correctly\");    \n        t.eq( image.style.top, xy.y + \"px\", \"image.style.top set correctly\");    \n\n        t.eq( image.style.width, sz.w + \"px\", \"image.style.width set correctly\");    \n        t.eq( image.style.height, sz.h + \"px\", \"image.style.height set correctly\");    \n\n        //Safari 3 separates the border style into separate entities when reading it\n        if (OpenLayers.BROWSER_NAME == 'safari') {\n          var s = border.split(' ');\n          t.ok(image.style.borderTopWidth == s[0] && image.style.borderTopStyle == s[1], \"good default popup.border\")\n        } else {\n          t.ok( (image.style.border.indexOf(border) != -1), \"image.style.border set correctly\");\n        }\n        t.eq( image.src, img, \"image.style.backgroundImage correctly\");    \n        t.eq( image.style.position, position, \"image.style.position set correctly\");    \n        t.eq( parseFloat(image.style.opacity), opacity, \"image.style.opacity set correctly\");    \n        //Some non-IE browsers don't return the alpha string for this value, which is okay\n        var filterString = image.style.filter.match(/^alpha/) != null ? \n                               'alpha(opacity=' + (opacity * 100) + ')' : image.style.filter;\n        t.eq( image.style.filter, filterString, \"element.style.filter set correctly\");\n\n        //test defaults\n        var image = OpenLayers.Util.createImage();\n\n        if (!isMozilla)\n            t.ok( true, \"skipping element test outside of Mozilla\");\n        else\n            t.ok( image.nodeName == \"IMG\", \"createDiv creates a valid HTMLDivElement\" );\n        t.ok( (image.id != \"\"), \"image.id set to something\");    \n        t.eq( image.style.left, \"\", \"image.style.left set correctly\");    \n        t.eq( image.style.top, \"\", \"image.style.top set correctly\");    \n\n        t.eq( image.style.width, \"\", \"image.style.width set correctly\");    \n        t.eq( image.style.height, \"\", \"image.style.height set correctly\");    \n\n        t.ok((image.style.border == \"\"), \"image.style.border set correctly\");    \n        t.eq(image.src, \"\", \"image.style.backgroundImage correctly\");    \n        t.eq( image.style.position, \"relative\", \"image.style.positionset correctly\");    \n        t.ok( !image.style.opacity, \"element.style.opacity default unset\");    \n        t.ok( !image.style.filter, \"element.style.filter default unset\");\n\n    }\n\n    function test_Util_applyDefaults(t) {\n    \n        t.plan(12);\n        \n        var to = { \n            'a': \"abra\",\n            'b': \"blorg\",\n            'n': null\n        };\n\n        var from = { \n            'b': \"zoink\",\n            'c': \"press\",\n            'toString': function() {return 'works'},\n            'n': \"broken\"\n        };\n\n        OpenLayers.Util.applyDefaults(to, from);\n\n        t.ok( to instanceof Object, \" applyDefaults returns an object\");\n        t.eq( to[\"a\"], \"abra\", \"key present in to but not from maintained\");\n        t.eq( to[\"b\"], \"blorg\", \"key present in to and from, maintained in to\");\n        t.eq( to[\"c\"], \"press\", \"key present in from and not to successfully copied to to\");\n\n        var ret = OpenLayers.Util.applyDefaults({'a': \"abra\",'b': \"blorg\"}, from);\n        t.ok( ret instanceof Object, \" applyDefaults returns an object\");\n        t.eq( ret[\"a\"], \"abra\", \"key present in ret but not from maintained\");\n        t.eq( ret[\"b\"], \"blorg\", \"key present in ret and from, maintained in ret\");\n        t.eq( ret[\"c\"], \"press\", \"key present in from and not ret successfully copied to ret\");\n        t.eq(to.toString(), \"works\", \"correctly applies custom toString\");\n        t.eq(to.n, null, \"correctly preserves null\");\n        \n        var to;\n        var from = {rand: Math.random()};\n        \n        var ret = OpenLayers.Util.applyDefaults(to, from);\n        t.eq(ret.rand, from.rand, \"works with undefined to\");\n\n        //regression test for #1716 -- allow undefined from\n        try {\n            OpenLayers.Util.applyDefaults({}, undefined);\n            t.ok(true, \"no exception thrown when from is undefined\");\n        } catch(err) {\n            t.fail(\"exception thrown when from is undefined:\" + err);\n        }\n\n    }\n\n    function test_Util_getParameterString(t) {\n        t.plan(6);\n\n        var params = { \n            'foo': \"bar\",\n            'chicken': 1.5\n        };\n\n        t.eq( OpenLayers.Util.getParameterString(params), \"foo=bar&chicken=1.5\", \"getParameterString returns correctly\");    \n        t.eq( OpenLayers.Util.getParameterString({'a:':'b='}), \"a%3A=b%3D\", \"getParameterString returns correctly with non-ascii keys/values\");    \n        \n        t.eq(OpenLayers.Util.getParameterString({chars: \"~!*()'\"}), \"chars=~!*()'\", \"~!*()' are unreserved or have no reserved purpose in a URI component\");\n        \n\n        // Parameters which are a list should end up being a comma-seperated\n        // list of the URL encoded strings\n        var params = { foo: [\"bar,baz\"] };\n        t.eq( OpenLayers.Util.getParameterString(params), \"foo=bar%2Cbaz\", \"getParameterString encodes , correctly in arrays\");    \n        \n        var params = { foo: [\"bar\",\"baz,\"] };\n        t.eq( OpenLayers.Util.getParameterString(params), \"foo=bar,baz%2C\", \"getParameterString returns with list of CSVs when given a list. \");\n        \n        var params = { foo: [null, undefined, 0, \"\", \"bar\"] }\n        t.eq( OpenLayers.Util.getParameterString(params), \"foo=,,0,,bar\", \"getParameterString works fine with null values in array.\");\n    }\n    \n    function test_Util_urlAppend(t) {\n\n        var params = \"foo=bar\";\n        \n        t.plan( 7 );\n\n  // without ?        \n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        var str = OpenLayers.Util.urlAppend(url, params);\n        t.eq(str, url + '?' + params, \"urlAppend() works for url sans ?\");\n\n\n  // with ?        \n        url = \"http://octo.metacarta.com/cgi-bin/mapserv?\";\n        str = OpenLayers.Util.urlAppend(url, params);\n        t.eq(str, url + params, \"urlAppend() works for url with ?\");\n\n  // with ?param1=5\n        url = \"http://octo.metacarta.com/cgi-bin/mapserv?param1=5\";\n        str = OpenLayers.Util.urlAppend(url, params);\n        t.eq(str, url + '&' + params, \"urlAppend() works for url with ?param1=5\");\n  \n  // with ?param1=5&\n        url = \"http://octo.metacarta.com/cgi-bin/mapserv?param1=5&\";\n        str = OpenLayers.Util.urlAppend(url, params);\n        t.eq(str, url + params, \"urlAppend() works for url with ?param1=5&\");\n \n  // with ?param1=5&param2=6\n        url = \"http://octo.metacarta.com/cgi-bin/mapserv?param1=5&param2=6\";\n        str = OpenLayers.Util.urlAppend(url, params);\n        t.eq(str, url + \"&\" + params, \"urlAppend() works for url with ?param1=5&param2=6\");\n        \n  // with empty paramStr\n        url = \"http://octo.metacarta.com/cgi-bin/mapserv?param1=5\"\n        str = OpenLayers.Util.urlAppend(url, \"\");\n        t.eq(str, url, \"urlAppend() works with empty paramStr\")\n\n  // with null paramStr\n        url = \"http://octo.metacarta.com/cgi-bin/mapserv?param1=5\"\n        str = OpenLayers.Util.urlAppend(url, null);\n        t.eq(str, url, \"urlAppend() works with null paramStr\")\n    }\n\n    function test_Util_createAlphaImageDiv(t) {\n        t.plan( 19 );\n\n        var img = \"http://www.openlayers.org/images/OpenLayers.trac.png\";\n        var sz = new OpenLayers.Size(10,10);\n        var xy = new OpenLayers.Pixel(5,5);\n        var position = \"absolute\";\n        var id = \"boo\";\n        var border = \"1px solid\";\n        var sizing = \"crop\";\n        var opacity = 0.5;\n\n        var imageDiv = OpenLayers.Util.createAlphaImageDiv(id, xy, sz, img, position, border, sizing, opacity);\n\n        if (!isMozilla)\n            t.ok( true, \"skipping element test outside of Mozilla\");\n        else\n            t.ok( imageDiv instanceof HTMLDivElement, \"createDiv creates a valid HTMLDivElement\" );\n\n        t.eq( imageDiv.id, id, \"image.id set correctly\");    \n        t.eq( imageDiv.style.left, xy.x + \"px\", \"image.style.left set correctly\");    \n        t.eq( imageDiv.style.top, xy.y + \"px\", \"image.style.top set correctly\");    \n\n        t.eq( imageDiv.style.width, sz.w + \"px\", \"image.style.width set correctly\");    \n        t.eq( imageDiv.style.height, sz.h + \"px\", \"image.style.height set correctly\");    \n\n        t.eq( imageDiv.style.position, position, \"image.style.positionset correctly\");    \n        t.eq( parseFloat(imageDiv.style.opacity), opacity, \"element.style.opacity set correctly\");    \n        \n        var filterString;\n        if (OpenLayers.Util.alphaHack()) {\n            filterString = \"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://www.openlayers.org/images/OpenLayers.trac.png', sizingMethod='crop') alpha(opacity=50)\";\n        } else {\n            //Some non-IE browsers don't return the alpha string for this value, which is okay\n            var filterString = imageDiv.style.filter.match(/^alpha/) != null ? \n                                   'alpha(opacity=' + (opacity * 100) + ')' : imageDiv.style.filter;\n        }        \n        t.eq( imageDiv.style.filter, filterString, \"element.style.filter set correctly\");\n\n\n        image = imageDiv.firstChild;\n        if (!isMozilla)\n            t.ok( true, \"skipping element test outside of Mozilla\");\n        else\n            t.ok( image.nodeName == \"IMG\", \"createImage creates a valid HTMLImageElement\" );\n        t.eq( image.id, id + \"_innerImage\", \"image.id set correctly\");    \n\n        t.eq( image.style.width, sz.w + \"px\", \"image.style.width set correctly\");    \n        t.eq( image.style.height, sz.h + \"px\", \"image.style.height set correctly\");    \n\n        //Safari 3 separates the border style into separate entities when reading it\n        if (OpenLayers.BROWSER_NAME == 'safari') {\n          var s = border.split(' ');\n          t.ok(image.style.borderTopWidth == s[0] && image.style.borderTopStyle == s[1], \"good default popup.border\")\n        } else {\n          t.ok( (image.style.border.indexOf(border) != -1), \"image.style.border set correctly\");\n        }\n        \n        t.eq( image.style.position, \"relative\", \"image.style.positionset correctly\");    \n\n        if (OpenLayers.Util.alphaHack()) {\n        \n            t.eq(imageDiv.style.display, \"inline-block\", \"imageDiv.style.display set correctly\");\n\n            var filter = \"progid:DXImageTransform.Microsoft\" +\n                         \".AlphaImageLoader(src='\" + img + \"', \" +\n                         \"sizingMethod='\" + sizing + \"') alpha(opacity=50)\";\n            t.eq(imageDiv.style.filter, filter, \"div filter value correctly set\");\n\n            filter = \"alpha(opacity=0)\";\n            t.eq(image.style.filter, filter, \"image filter set correctly\");\n\n        } else {\n            t.eq( image.src, img, \"image.style.backgroundImage correctly\");    \n            t.ok(true, \"div filter value not set (not in IE)\");\n            t.ok(true, \"image filter value not set (not in IE)\");\n        }\n\n        var imageDiv = OpenLayers.Util.createAlphaImageDiv(id, xy, sz, img, position, border);\n        if (OpenLayers.Util.alphaHack()) {\n            var filter = \"progid:DXImageTransform.Microsoft\" +\n                         \".AlphaImageLoader(src='\" + img + \"', \" +\n                         \"sizingMethod='scale')\";\n            t.eq(imageDiv.style.filter, filter, \"sizingMethod default correctly set to scale\");\n        } else {\n            t.ok(true);\n        }        \n\n    }\n\n    function test_Util_modifyDOMElement_opacity(t) {\n        t.plan(8);\n\n        var opacity = 0.2;\n\n        var element = document.createElement(\"div\");\n\n        OpenLayers.Util.modifyDOMElement(element, null, null, null, null, \n                                         null, null, opacity);\n\n        t.eq(parseFloat(element.style.opacity), opacity, \n             \"element.style.opacity set correctly when opacity = \" + opacity);\n        //Some non-IE browsers don't return the alpha string for this value, which is okay\n        var filterString = element.style.filter.match(/^alpha/) != null ? \n                               'alpha(opacity=' + (opacity * 100) + ')' : element.style.filter;\n        t.eq(element.style.filter, filterString, \n             \"element.style.filter set correctly when opacity = \" + opacity);\n\n        OpenLayers.Util.modifyDOMElement(element, null, null, null, null, \n                                         null, null, \"5\");\n    \n        t.eq(parseFloat(element.style.opacity), opacity, \n             \"element.style.opacity not changed if the value is incorrect\");\n        //Some non-IE browsers don't return the alpha string for this value, which is okay\n        var filterString = element.style.filter.match(/^alpha/) != null ? \n                               'alpha(opacity=' + (opacity * 100) + ')' : element.style.filter;\n        t.eq(element.style.filter, filterString, \n             \"element.style.filter not changed if the value is incorrect\");\n\n        OpenLayers.Util.modifyDOMElement(element, null, null, null, null, \n                                         null, null, \"hello\");\n    \n        t.eq(parseFloat(element.style.opacity), opacity, \n             \"element.style.opacity not changed if the value is incorrect\");\n        //Some non-IE browsers don't return the alpha string for this value, which is okay\n        var filterString = element.style.filter.match(/^alpha/) != null ? \n                               'alpha(opacity=' + (opacity * 100) + ')' : element.style.filter;\n        t.eq(element.style.filter, filterString, \n             \"element.style.filter not changed if the value is incorrect\");\n\n        opacity = 1.00;\n        OpenLayers.Util.modifyDOMElement(element, null, null, null, null, \n                                         null, null, opacity);\n\n        t.eq(element.style.opacity, '', \n             \"element.style.opacity is removed when opacity = \" + opacity);\n        // Some browser returns null instead of '', which is okay\n        t.ok(element.style.filter == '' || element.style.filter == null,\n             \"element.style.filter is removed when opacity = \" + opacity);\n    }\n\n    function test_Util_modifyDOMElement(t) {\n        t.plan( 10 );\n\n        var id = \"boo\";\n        var px = new OpenLayers.Pixel(5,5);\n        var sz = new OpenLayers.Size(10,10);\n        var position = \"absolute\";\n        var border = \"1px solid\";\n        var overflow = \"hidden\";\n        var opacity = 1/2;\n\n        var element = document.createElement(\"div\");\n\n        OpenLayers.Util.modifyDOMElement(element, id, px, sz, position, \n                                         border, overflow, opacity);\n\n        t.eq( element.id, id, \"element.id set correctly\");    \n        t.eq( element.style.left, px.x + \"px\", \"element.style.left set correctly\");    \n        t.eq( element.style.top, px.y + \"px\", \"element.style.top set correctly\");    \n\n        t.eq( element.style.width, sz.w + \"px\", \"element.style.width set correctly\");    \n        t.eq( element.style.height, sz.h + \"px\", \"element.style.height set correctly\");    \n\n        t.eq( element.style.position, position, \"element.style.position set correctly\");    \n        //Safari 3 separates the border style into separate entities when reading it\n        if (OpenLayers.BROWSER_NAME == 'safari') {\n          var s = border.split(' ');\n          t.ok(element.style.borderTopWidth == s[0] && element.style.borderTopStyle == s[1], \"good default popup.border\")\n        } else {\n          t.ok( (element.style.border.indexOf(border) != -1), \"element.style.border set correctly\");\n        }\n        //Safari 3 separates style overflow into overflow-x and overflow-y\n        var prop = (OpenLayers.BROWSER_NAME == 'safari') ? 'overflowX' : 'overflow';\n        t.eq( element.style[prop], overflow, \"element.style.overflow set correctly\");    \n        t.eq( parseFloat(element.style.opacity), opacity, \"element.style.opacity set correctly\");    \n        //Some non-IE browsers don't return the alpha string for this value, which is okay\n        var filterString = element.style.filter.match(/^alpha/) != null ? \n                               'alpha(opacity=' + (opacity * 100) + ')' : element.style.filter;\n        t.eq( element.style.filter, filterString, \"element.style.filter set correctly\");\n    }\n\n    function test_Util_modifyAlphaImageDiv(t) {\n        t.plan( 21 );\n\n        var imageDiv = OpenLayers.Util.createAlphaImageDiv();\n\n        var img = \"http://www.openlayers.org/images/OpenLayers.trac.png\";\n        var sz = new OpenLayers.Size(10,10);\n        var xy = new OpenLayers.Pixel(5,5);\n        var position = \"absolute\";\n        var id = \"boo\";\n        var border = \"1px solid\";\n        var sizing = \"crop\";\n        var opacity = 0.5;\n\n        OpenLayers.Util.modifyAlphaImageDiv(imageDiv, id, xy, sz, img, position, border, sizing, opacity);\n        if (OpenLayers.Util.alphaHack())\n            t.ok( true, \"skipping element test outside of Mozilla\");\n        else\n            t.ok( imageDiv.nodeName == \"DIV\", \"createDiv creates a valid HTMLDivElement\" );\n\n        t.eq( imageDiv.id, id, \"image.id set correctly\");    \n        t.eq( imageDiv.style.left, xy.x + \"px\", \"image.style.left set correctly\");    \n        t.eq( imageDiv.style.top, xy.y + \"px\", \"image.style.top set correctly\");    \n\n        t.eq( imageDiv.style.width, sz.w + \"px\", \"image.style.width set correctly\");    \n        t.eq( imageDiv.style.height, sz.h + \"px\", \"image.style.height set correctly\");    \n\n        t.eq( imageDiv.style.position, position, \"image.style.position set correctly\");    \n        t.eq( parseFloat(imageDiv.style.opacity), opacity, \"element.style.opacity set correctly\");    \n\n        \n\n        image = imageDiv.firstChild;\n\n        var filterString;\n        if (OpenLayers.Util.alphaHack()) {\n            filterString = \"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://www.openlayers.org/images/OpenLayers.trac.png', sizingMethod='crop') alpha(opacity=50)\";\n            t.ok( true, \"skipping element test outside of Mozilla\");\n        } else {\n            //Some non-IE browsers don't return the alpha string for this value, which is okay\n            var filterString = imageDiv.style.filter.match(/^alpha/) != null ? \n                                   'alpha(opacity=' + (opacity * 100) + ')' : imageDiv.style.filter;\n            t.ok( image.nodeName == \"IMG\", \"createImage creates a valid HTMLImageElement\" );\n        }\n        t.eq( imageDiv.style.filter, filterString, \"element.style.filter set correctly\");\n        t.eq( image.id, id + \"_innerImage\", \"image.id set correctly\");    \n\n        t.eq( image.style.width, sz.w + \"px\", \"image.style.width set correctly\");    \n        t.eq( image.style.height, sz.h + \"px\", \"image.style.height set correctly\");    \n\n        //Safari 3 separates the border style into separate entities when reading it\n        if (OpenLayers.BROWSER_NAME == 'safari') {\n          var s = border.split(' ');\n          t.ok(image.style.borderTopWidth == s[0] && image.style.borderTopStyle == s[1], \"good default popup.border\")\n        } else {\n          t.ok( (image.style.border.indexOf(border) != -1), \"image.style.border set correctly\");\n        }\n\n        t.eq( image.style.position, \"relative\", \"image.style.positionset correctly\");    \n        t.eq( image.src, img, \"image.style.backgroundImage correctly\");\n        \n        if (OpenLayers.Util.alphaHack()) {\n        \n            var filter = \"progid:DXImageTransform.Microsoft\" +\n                         \".AlphaImageLoader(src='\" + img + \"', \" +\n                         \"sizingMethod='\" + sizing + \"') alpha(opacity=\" + opacity *100 + \")\";\n            t.eq(imageDiv.style.filter, filter, \"div filter value correctly set\");\n\n            filter = \"alpha(opacity=0)\";\n            t.eq(image.style.filter, filter, \"image filter set correctly\");\n\n        } else {  \n            t.ok(true, \"div filter value not set (not in IE)\");\n            t.ok(true, \"image filter value not set (not in IE)\");\n        }\n\n        var imageDiv = OpenLayers.Util.createAlphaImageDiv();\n        var display = \"none\";\n        imageDiv.style.display = display;\n        OpenLayers.Util.modifyAlphaImageDiv(imageDiv, id, xy, sz, img, position, border, sizing, opacity);\n        t.eq(imageDiv.style.display, display, \"imageDiv.style.display set correctly, if 'none'\");\n\n        var imageDiv = OpenLayers.Util.createAlphaImageDiv();\n        var display = \"block\";\n        imageDiv.style.display = display;\n        OpenLayers.Util.modifyAlphaImageDiv(imageDiv, id, xy, sz, img, position, border, sizing, opacity);\n        if(OpenLayers.Util.alphaHack()) {\n            t.eq(imageDiv.style.display, \"inline-block\", \"imageDiv.style.display set correctly, if not 'none'\");\n        } else {\n            t.ok(true, \"inline-block is not part of CSS2 and is not supported by Firefox 2\");\n        }\n\n        \n\n        var imageDiv = OpenLayers.Util.createAlphaImageDiv(id, xy, sz, img, position, border, \"scale\", opacity);\n        if (OpenLayers.Util.alphaHack()) {\n            var filter = \"progid:DXImageTransform.Microsoft\" +\n                         \".AlphaImageLoader(src='\" + img + \"', \" +\n                         \"sizingMethod='scale') alpha(opacity=\" + opacity *100 + \")\";\n            t.eq(imageDiv.style.filter, filter, \"sizingMethod default correctly set to scale\");\n        } else {\n            t.ok(true);\n        }        \n   \n    }\n       \n    function test_Util_upperCaseObject(t) {\n        t.plan(8);\n        \n        var aKey = \"chicken\";\n        var aValue = \"pot pie\";\n\n        var bKey = \"blorg\";\n        var bValue = \"us maximus\";\n        \n        var obj = {};\n        obj[aKey] = aValue;        \n        obj[bKey] = bValue;        \n             \n        var uObj = OpenLayers.Util.upperCaseObject(obj);          \n\n        //make sure old object not modified\n        t.eq(obj[aKey], aValue, \"old lowercase value still present in old obj\");\n        t.eq(obj[bKey], bValue, \"old lowercase value still present in old obj\");\n\n        t.eq(obj[aKey.toUpperCase()], null, \"new uppercase value not present in old obj\");\n        t.eq(obj[bKey.toUpperCase()], null, \"new uppercase value not present in old obj\");\n\n        //make sure new object modified\n        t.eq(uObj[aKey], null, \"old lowercase value not present\");\n        t.eq(uObj[bKey], null, \"old lowercase value not present\");\n\n        t.eq(uObj[aKey.toUpperCase()], aValue, \"new uppercase value present\");\n        t.eq(uObj[bKey.toUpperCase()], bValue, \"new uppercase value present\");\n    }\n    \n    function test_Util_createUniqueID(t) {\n        t.plan(2);\n        \n        var id = OpenLayers.Util.createUniqueID();\n        t.ok(OpenLayers.String.startsWith(id, \"id_\"),\n             \"default OpenLayers.Util.createUniqueID starts id correctly\");\n\n        var id = OpenLayers.Util.createUniqueID(\"chicken\");\n        t.ok(OpenLayers.String.startsWith(id, \"chicken\"),\n             \"OpenLayers.Util.createUniqueID starts id correctly\");\n    }\n    \n    function test_units(t) {\n        t.plan(2);\n        t.eq(OpenLayers.INCHES_PER_UNIT.m, OpenLayers.INCHES_PER_UNIT.Meter, 'Same inches per m and Meters');\n        t.eq(OpenLayers.INCHES_PER_UNIT.km, OpenLayers.INCHES_PER_UNIT.Kilometer, 'Same inches per km and Kilometers');\n    }\n        \n    function test_Util_normalizeScale(t) {\n        t.plan(2); \n        \n        //normal scale\n        var scale = 1/5;\n        t.eq( OpenLayers.Util.normalizeScale(scale), scale, \"normalizing a normal scale does nothing\");\n\n        //funky scale\n        var scale = 5;\n        t.eq( OpenLayers.Util.normalizeScale(scale), 1/5, \"normalizing a wrong scale works!\");\n    }\n    \n    function test_Util_getScaleResolutionTranslation(t) {\n        t.plan(5); \n        \n        var scale = 1/150000000; \n        var resolution = OpenLayers.Util.getResolutionFromScale(scale);\n        t.eq(resolution.toFixed(6), \"0.476217\", \"Calculated correct resolution for \" + scale);\n\n        var scale = 1/150000000; \n        var resolution = OpenLayers.Util.getResolutionFromScale(scale, 'm');\n        t.eq(resolution.toFixed(6), \"52916.772500\", \"Calculated correct resolution for \" + scale);\n\n        scale = 150000000; \n        resolution = OpenLayers.Util.getResolutionFromScale(scale);\n        t.eq(resolution.toFixed(6), \"0.476217\", \"Calculated correct resolution for \" + scale);\n\n        scale = 150000000; \n        resolution = OpenLayers.Util.getResolutionFromScale(scale);\n        t.eq(OpenLayers.Util.getScaleFromResolution(resolution), scale, \"scale->resolution->scale works\");\n        \n        scale = null;\n        resolution = OpenLayers.Util.getResolutionFromScale(scale);\n        t.eq(resolution, undefined, \"falsey scale results in undefined resolution\");\n        \n    }\n    \n    function test_Util_getImgLocation(t) {\n        t.plan(3);\n\n        OpenLayers.ImgPath = \"foo/\";\n        t.eq(OpenLayers.Util.getImagesLocation(), \"foo/\", \"ImgPath works as expected.\"); \n        OpenLayers.ImgPath = null;\n        t.eq(OpenLayers.Util.getImagesLocation().substr(OpenLayers.Util.getImagesLocation().length-4,4), \"img/\", \"ImgPath works as expected when not set.\"); \n\n        OpenLayers.ImgPath = '';\n        t.eq(OpenLayers.Util.getImagesLocation().substr(OpenLayers.Util.getImagesLocation().length-4,4), \"img/\", \"ImgPath works as expected when set to ''.\"); \n    }\n\n    function test_Util_isEquivalentUrl(t) {\n        t.plan(10);\n        \n        var url1, url2, options;\n\n  //CASE\n\n        url1 = \"http://www.openlayers.org\";\n        url2 = \"HTTP://WWW.OPENLAYERS.ORG\";\n\n        t.ok(OpenLayers.Util.isEquivalentUrl(url1, url2), \"default ignoreCase works\"); \n\n  //ARGS\n\n        url1 = \"http://www.openlayers.org?foo=5;bar=6\";\n        url2 = \"http://www.openlayers.org?bar=6;foo=5\";\n\n        t.ok(OpenLayers.Util.isEquivalentUrl(url1, url2), \"shuffled arguments works\"); \n\n  //PORT\n\n        url1 = \"http://www.openlayers.org:80\";\n        url2 = \"http://www.openlayers.org\";\n\n        t.ok(OpenLayers.Util.isEquivalentUrl(url1, url2), \"default ignorePort80 works\"); \n\n        options = {\n            'ignorePort80': false\n        }        \n        url1 = \"http://www.openlayers.org:80\";\n        url2 = \"http://www.openlayers.org:50\";\n\n        t.ok(!OpenLayers.Util.isEquivalentUrl(url1, url2, options), \"port check works\"); \n\n\n  //HASH\n\n        url1 = \"http://www.openlayers.org#barf\";\n        url2 = \"http://www.openlayers.org\";\n\n        t.ok(OpenLayers.Util.isEquivalentUrl(url1, url2), \"default ignoreHash works\"); \n        options = {\n            'ignoreHash': false\n        }        \n        t.ok(!OpenLayers.Util.isEquivalentUrl(url1, url2, options), \"ignoreHash FALSE works\"); \n\n  //PROTOCOL\n\n        url1 = \"http://www.openlayers.org\";\n        url2 = \"ftp://www.openlayers.org\";\n\n        t.ok(!OpenLayers.Util.isEquivalentUrl(url1, url2), \"default ignoreHash works\"); \n\n\n  //PATHNAME\n        url1 = \"foo.html?bar=now#go\";\n        url2 = \"../tests/../tests/foo.html?bar=now#go\";\n\n        t.ok(OpenLayers.Util.isEquivalentUrl(url1, url2), \"relative vs. absolute paths works\");\n        \n        url1 = \"/foo/bar\";\n        url2 = new Array(window.location.pathname.split(\"/\").length-1).join(\"../\")+\"foo/bar\";\n        \n        t.ok(OpenLayers.Util.isEquivalentUrl(url1, url2), \"absolute and relative path without host works for \"+url2) \n\n  //ARGS\n        url1 = \"foo.html?bbox=1,2,3,4\",\n        url2 = url1;\n        t.ok(OpenLayers.Util.isEquivalentUrl(url1, url2), \"equal urls with comma delimited params are equal\");\n    }\n    \n    function test_createUrlObject(t) {\n        \n        var cases = [{\n            url: \"http://example.com/\",\n            exp: {\n                protocol: \"http:\",\n                host: \"example.com\",\n                port: \"80\",\n                pathname: \"/\",\n                args: {},\n                hash: \"\"\n            }\n        }, {\n            url: \"http://example.com:80/\",\n            opt: {ignorePort80: true},\n            exp: {\n                protocol: \"http:\",\n                host: \"example.com\",\n                port: \"\",\n                pathname: \"/\",\n                args: {},\n                hash: \"\"\n            }\n        }, {\n            url: \"http://example.com/\",\n            opt: {ignorePort80: true},\n            exp: {\n                protocol: \"http:\",\n                host: \"example.com\",\n                port: \"\",\n                pathname: \"/\",\n                args: {},\n                hash: \"\"\n            }\n        }, {\n            url: \"http://example.com:88/\",\n            exp: {\n                protocol: \"http:\",\n                host: \"example.com\",\n                port: \"88\",\n                pathname: \"/\",\n                args: {},\n                hash: \"\"\n            }\n        }, {\n            url: \"http://example.com:88/foo#bar\",\n            exp: {\n                protocol: \"http:\",\n                host: \"example.com\",\n                port: \"88\",\n                pathname: \"/foo\",\n                args: {},\n                hash: \"#bar\"\n            }\n        }, {\n            url: \"http://example.com:88/?foo=bar\",\n            exp: {\n                protocol: \"http:\",\n                host: \"example.com\",\n                port: \"88\",\n                pathname: \"/\",\n                args: {foo: \"bar\"},\n                hash: \"\"\n            }\n        }, {\n            url: \"http://example.com/bogus/../bogus/../path\",\n            exp: {\n                protocol: \"http:\",\n                host: \"example.com\",\n                port: \"80\",\n                pathname: \"/path\",\n                args: {},\n                hash: \"\"\n            }\n        }, {\n            url: \"/relative#foo\",\n            exp: {\n                protocol: window.location.protocol,\n                host: window.location.hostname,\n                port: window.location.port || \"80\",\n                pathname: \"/relative\",\n                args: {},\n                hash: \"#foo\"\n            }\n        }, {\n            url: \"../foo\",\n            exp: {\n                protocol: window.location.protocol,\n                host: window.location.hostname,\n                port: window.location.port || \"80\",\n                pathname: (function() {\n                    var parts = window.location.pathname.split(\"/\");\n                    return parts.slice(0, parts.length -2).join(\"/\") + \"/foo\";\n                })(),\n                args: {},\n                hash: \"\"\n            }\n        }];\n        \n        t.plan(cases.length);\n\n        var c, obj;\n        for(var i=0; i<cases.length; ++i) {\n            c = cases[i];\n            obj = OpenLayers.Util.createUrlObject(c.url, c.opt);\n            t.eq(obj, c.exp, i + \": '\" + c.url + \"'\");\n        }\n        \n    }\n    \n    function test_Util_createUniqueIDSeq(t) {\n        t.plan(1);\n\n        OpenLayers.Util.lastSeqID = 0;\n        OpenLayers.Util.createDiv();\n        OpenLayers.Util.createDiv();\n        t.eq(OpenLayers.Util.createDiv().id, \"OpenLayersDiv3\", \"Div created is sequential, starting at lastSeqID in Util.\");\n    }\n\n    function test_Util_getParameters(t) {\n        t.plan(20);\n\n        t.eq(OpenLayers.Util.getParameters(''), {},\n                \"getParameters works when the given argument is empty string\");\n\n        t.eq(OpenLayers.Util.getParameters(), {},\n                \"getParameters works with optional argument\");\n\n        t.eq(OpenLayers.Util.getParameters(null), {},\n                \"getParameters works with optional argument\");\n\n        t.eq(OpenLayers.Util.getParameters('http://www.example.com'), {},\n             \"getParameters works when args = ''\");\n        t.eq(OpenLayers.Util.getParameters('http://www.example.com?'), {},\n             \"getParameters works when args = '?'\");\n        t.eq(OpenLayers.Util.getParameters('http://www.example.com?hello=world&foo=bar'),\n             {'hello' : 'world', 'foo': 'bar'},\n             \"getParameters works when args = '?hello=world&foo=bar'\");\n        t.eq(OpenLayers.Util.getParameters('http://www.example.com?hello=&foo=bar'),\n             {'hello' : '', 'foo': 'bar'},\n             \"getParameters works when args = '?hello=&foo=bar'\");\n        t.eq(OpenLayers.Util.getParameters('http://www.example.com?foo=bar#bugssucks'),\n             {'foo': 'bar'},\n             \"getParameters works when using a fragment identifier\");\n        t.eq(OpenLayers.Util.getParameters('http://www.example.com?foo=bar%3Aone'),\n             {'foo': 'bar:one'},\n             \"getParameters works with percent encoded values\");\n        t.eq(OpenLayers.Util.getParameters('http://www.example.com?foo=bar:one,pub,disco'),\n             {'foo': ['bar:one', 'pub', 'disco']},\n             \"getParameters works with a comma-separated value (parses into array)\");\n        t.eq(OpenLayers.Util.getParameters('http://www.example.com?foo=bar%3Aone%2Cpub%2Cdisco'),\n             {'foo': ['bar:one', 'pub', 'disco']},\n             \"getParameters works with a URL encoded comma-separated values (parses into array)\");\n        \n        var value = \"%20\";  // say you wanted to have a query string parameter value be literal \"%20\"\n        var encoded = encodeURIComponent(value); // this is the proper URI component encoding\n        var url = \"http://example.com/path?key=\" + encoded; // this is a properly encoded URL\n        var params = OpenLayers.Util.getParameters(url);\n        t.eq(params.key, value, \"a properly encoded value of '%20' is properly decoded\");\n\n        /**\n         * IETF RFC 2396 (http://www.ietf.org/rfc/rfc2396.txt) says spaces\n         * should be encoded as \"%20\".  However, the \"+\" is used widely to\n         * indicate a space in a URL.\n         */\n        t.eq(OpenLayers.Util.getParameters('http://www.example.com?foo=bar+one'),\n             {'foo': 'bar one'},\n             \"getParameters works with + instead of %20 in values\");\n        t.eq(OpenLayers.Util.getParameters('http://www.example.com?foo=bar%20one'),\n             {'foo': 'bar one'},\n             \"getParameters works with properly encoded space character\");\n        t.eq(OpenLayers.Util.getParameters('http://www.example.com?foo=bar%2Bone'),\n             {'foo': 'bar+one'},\n             \"getParameters works with properly encoded + character\");\n             \n        // Let's do some round tripping to make it harder to introduce regressions\n        var obj = {\n            \"a key\": \"a value with spaces  (and +)\",\n            \"see%2B%2B\": \"C++\",\n            \"C++\": \"see%2B%2B\",\n            \"~%257E\": \"+%252B\",\n            \"who?\": \"me?\",\n            \"#yes\": \"#you\",\n            \"url\": \"http://example.com:80/?question=%3F&hash=%23&amp=&26#id\"\n        };\n        var str = OpenLayers.Util.getParameterString(obj);\n        t.eq(OpenLayers.Util.getParameters(\"?\" + str), obj, \"round tripped parameters\");\n        \n        // try some oddly encoded strings\n        var url = \"http://example.com/?C%E9sar=C%E9sar+Ch%E1vez\";\n        var obj = OpenLayers.Util.getParameters(url);\n        t.ok(\"César\" in obj, \"got proper key from C%E9sar\");\n        t.eq(obj[\"César\"], \"César Chávez\", \"got proper value from C%E9sar+Ch%E1vez\");\n        \n        // try some properly encoded strings\n        var url = \"http://example.com/?C%C3%A9sar=C%C3%A9sar+Ch%C3%A1vez\";\n        var obj = OpenLayers.Util.getParameters(url);\n        t.ok(\"César\" in obj, \"got proper key from C%C3%A9sar\");\n        t.eq(obj[\"César\"], \"César Chávez\", \"got proper value from C%E9sar+Ch%E1vez\");\n\n    }\n\n    function tests_Util_extend(t) {\n        t.plan(7);\n\n        var source = {\n            num: Math.random(),\n            obj: {\n                foo: \"bar\"\n            },\n            method: function() {\n                return \"method\";\n            },\n            toString: function() {\n                return \"source\";\n            },\n            nada: undefined\n        };\n        var destination = OpenLayers.Util.extend({nada: \"untouched\"}, source);\n        t.eq(destination.num, source.num,\n             \"extend properly sets primitive property on destination\");\n        t.eq(destination.obj, source.obj,\n             \"extend properly sets object property on destination\");\n        t.eq(destination.method(), \"method\",\n             \"extend properly sets function property on destination\");\n        t.eq(destination.toString(), \"source\",\n             \"extend properly sets custom toString method\");\n        t.eq(destination.nada, \"untouched\",\n             \"undefined source properties don't clobber existing properties\");\n        t.eq(window.property, undefined, \"Property variable not clobbered.\");\n        \n        var destination;\n        var source = {rand: Math.random()};\n        var ret = OpenLayers.Util.extend(destination, source);\n        t.eq(destination.rand, source.rand, \"works with undefined destination\");\n        \n    }\n    \n    function test_XX_Util_Try(t) {\n        t.plan(7);\n\n        var func1 = function() {\n            t.ok(true, \"func1 executed\");\n            throw \"error\";\n        };\n        \n        var func2 = function() {\n            t.ok(true, \"func2 executed\");\n            throw \"error\";\n        };\n\n        g_TestVal3 = {};\n        var func3 = function() {\n            t.ok(true, \"func3 executed\");\n            return g_TestVal3;            \n        };\n\n        g_TestVal4 = {};\n        var func4 = function() {\n            t.fail(\"func4 should *not* be executed\");\n            return g_TestVal4;            \n        };\n\n        var ret = OpenLayers.Util.Try(func1, func2);\n        t.ok(ret == null, \"if all functions throw exceptions, null returned\");\n\n        var ret = OpenLayers.Util.Try(func1, func2, func3, func4);\n        t.ok(ret == g_TestVal3, \"try returns first sucessfully executed function's return\");\n\n    }\n    \n    function test_getRenderedDimensions(t) {\n        // from <script src=\"Util_common.js\"> and shared by Util_w3c.html\n        com_test_getRenderedDimensions(t); \n    }\n\n    function test_toFloat(t) {\n        t.plan(2);\n        // actual possible computed Mercator tile coordinates, more or less\n        var a1=40075016.67999999, b1=-20037508.33999999,\n            a2=40075016.68, b2=-20037508.34;\n        t.eq(OpenLayers.Util.toFloat(a1), OpenLayers.Util.toFloat(a2),\n            \"toFloat rounds large floats correctly #1\");\n        t.eq(OpenLayers.Util.toFloat(b1), OpenLayers.Util.toFloat(b2),\n            \"toFloat rounds large floats correctly #2\");\n    }\n    function test_getFormattedLonLat(t) {\n        t.plan(3);\n        var z = 2 + (4/60) - 0.000002 ;\n        t.eq(OpenLayers.Util.getFormattedLonLat(z,\"lon\"), \"02°04'00\\\"E\",\n            \"LonLat does not show 60 seconds.\");\n        t.eq(OpenLayers.Util.getFormattedLonLat(-181, \"lon\"), \"179°00'00\\\"E\", \"crossing dateline from the west results in correct east coordinate\");\n        t.eq(OpenLayers.Util.getFormattedLonLat(181, \"lon\"), \"179°00'00\\\"W\", \"crossing dateline from the east results in correct west coordinate\");\n    }\n\n    function test_getConstructor(t) {\n        t.plan(3);\n\n        var Constructor,\n            get = OpenLayers.Util.getConstructor;\n\n        t.eq(get(\"OpenLayers.Size\"), OpenLayers.Size, \"got OpenLayers.Size\");\n        t.eq(get(\"OpenLayers.LonLat\"), OpenLayers.LonLat, \"got OpenLayers.LonLat\");\n\n        var err;\n        try {\n            Constructor = get(\"Foo.Bar\");\n        } catch (e) {\n            err = e;\n        }\n        t.ok(err instanceof Error, \"throws\");\n    }\n\n    /**\n     * To test that we can safely call OpenLayers.Util.extend with an Event\n     * instance, we need to capture a real event.\n     */\n    var loadEvent;\n    window.onload = function(evt) {\n        loadEvent = evt || window.event;\n    }\n    function test_extend_event(t) {\n        t.plan(2);\n        t.ok(loadEvent, \"loadEvent recorded\");\n        var extended, err;\n        try {\n            extended = OpenLayers.Util.extend({foo: \"bar\"}, loadEvent);\n        } catch (e) {\n            err = e;\n        }\n        if (err) {\n            t.fail(\"Failed to extend with an event: \" + err.message);\n        } else {\n            t.eq(extended && extended.foo, \"bar\", \"extended with event\");\n        }\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Util_common.js",
    "content": "function com_test_getRenderedDimensions(t) {\r\n    t.plan(17);\r\n    var content = (new Array(100)).join(\"foo \");\r\n    var fw = OpenLayers.Util.getRenderedDimensions(content, {w: 20});\r\n    t.eq(fw.w, 20, \"got the fixed width\");\r\n    var fh = OpenLayers.Util.getRenderedDimensions(content, {h: 15});\r\n    t.eq(fh.h, 15, \"got the fixed height\");        \r\n    \r\n    var size = OpenLayers.Util.getRenderedDimensions(\"<p>Content</p>\");\r\n    var bigger = OpenLayers.Util.getRenderedDimensions(\"<p>Content</p>\", null, {displayClass: 'test_getRenderedDimensions'});\r\n    var overflow = OpenLayers.Util.getRenderedDimensions(\"<p style='overflow:auto'>Content</p>\");\r\n    var width = OpenLayers.Util.getRenderedDimensions(\"<p>Content</p>\", new OpenLayers.Size(250, null));\r\n    var height = OpenLayers.Util.getRenderedDimensions(\"<p>Content</p>\", new OpenLayers.Size(null, 40));\r\n    t.ok((size.w + 40) == bigger.w && (size.h + 40) == bigger.h, \"bigger Pass:  \" + size + \", \" + bigger);\r\n    t.ok(size.w == overflow.w && size.h == overflow.h, \"overflow Pass:  \" + size + \", \" + overflow);\r\n    t.ok(width.w == 250 && width.h == size.h, \"width Pass:  \" + size + \", \" + width);\r\n    t.ok(height.h == 40 && height.w == size.w, \"height Pass:  \" + size + \", \" + height);\r\n    \r\n    content = (new Array(10)).join(\"foo foo foo <br>\");\r\n    var testName,\r\n        finalSize,\r\n        initialSize = OpenLayers.Util.getRenderedDimensions(content, null);\r\n    testName = \"Absolute with w&h: \";\r\n    var optionAbsDiv ={\r\n        containerElement: document.getElementById(\"absoluteDiv\")\r\n    };\r\n    finalSize = OpenLayers.Util.getRenderedDimensions(content, null, optionAbsDiv);\r\n    t.ok(initialSize.w > 0 && initialSize.h > 0, \"Has initial size (requires visible test_iframe)\");\r\n    t.eq(finalSize.w, initialSize.w, \r\n                testName + \"initial width \" + initialSize.w + \"px is maintained\");\r\n     t.eq(finalSize.h, initialSize.h, \r\n                testName + \"initial height \" + initialSize.h + \"px is maintained\");\r\n    testName = \"Absolute with w&h (set height): \";\r\n    finalSize = OpenLayers.Util.getRenderedDimensions(content, {h: 15}, optionAbsDiv);\r\n    t.eq(finalSize.h, 15, testName + \"got the fixed height to 15px\");\r\n    t.eq(finalSize.w, initialSize.w, \r\n                testName + \"initial width \" + initialSize.w + \"px is maintained\");\r\n    testName = \"Absolute with w&h (set width): \";\r\n    finalSize = OpenLayers.Util.getRenderedDimensions(content, {w: 20}, optionAbsDiv);\r\n    t.eq(finalSize.w, 20, testName + \"got the fixed width to 20px\");\r\n    testName = \"Absolute without w&h: \";\r\n    var optionAbsDiv00 ={\r\n        containerElement: document.getElementById(\"absoluteDiv00\")\r\n    };\r\n    finalSize = OpenLayers.Util.getRenderedDimensions(content, null, optionAbsDiv00);\r\n    t.eq(finalSize.w, initialSize.w, \r\n                testName + \"initial width \" + initialSize.w + \"px is maintained\");\r\n    t.eq(finalSize.h, initialSize.h, \r\n                testName + \"initial height \" + initialSize.h + \"px is maintained\");\r\n    testName = \"Absolute without w&h (set height): \";\r\n    finalSize = OpenLayers.Util.getRenderedDimensions(content, {h: 15}, optionAbsDiv00);\r\n    t.eq(finalSize.h, 15, testName + \"got the fixed height to 15px\");\r\n    t.eq(finalSize.w, initialSize.w, \r\n                testName + \"initial width \" + initialSize.w + \"px is maintained\");\r\n    testName = \"Absolute without w&h (set width): \";\r\n    finalSize = OpenLayers.Util.getRenderedDimensions(content, {w: 20}, optionAbsDiv00);\r\n    t.eq(finalSize.w, 20, testName + \"got the fixed width to 20px\");\r\n}\r\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/Util_w3c.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n  <meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\" />\n  <style type=\"text/css\">\n        .test_getRenderedDimensions p{\n            padding: 20px; \n        }     \n  </style>\n  <script>\n    var OpenLayers = [\n        \"OpenLayers/BaseTypes/Class.js\",\n        \"OpenLayers/Util.js\",\n        \"OpenLayers/BaseTypes.js\",\n        \"OpenLayers/BaseTypes/Element.js\",\n        \"OpenLayers/BaseTypes/LonLat.js\",\n        \"OpenLayers/BaseTypes/Pixel.js\",\n        \"OpenLayers/BaseTypes/Size.js\",\n        \"OpenLayers/Lang.js\",\n        \"OpenLayers/Console.js\"\n    ];\n  </script>\n  <script src=\"OLLoader.js\"></script>\n  <script src=\"Util_common.js\"></script>\n  <script type=\"text/javascript\">\n    function test_getRenderedDimensions(t) {\n        // from <script src=\"Util_common.js\"> and shared by Util.html\n        com_test_getRenderedDimensions(t);\n    }\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/WPSClient.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n  \n  var client;\n  \n  function test_initialize(t) {\n      t.plan(3);\n      \n      client = new OpenLayers.WPSClient({\n          servers: {\n              local: \"/geoserver/wps\"\n          }\n      });\n      \n      t.ok(client instanceof OpenLayers.WPSClient, 'creates an instance');\n      t.ok(client.events, 'has an events instance');\n      t.eq(client.servers.local.url, '/geoserver/wps', 'servers stored on instance');\n  }\n  \n  function test_getProcess(t) {\n      t.plan(4);\n\n      client = new OpenLayers.WPSClient({\n          servers: {\n              local: \"/geoserver/wps\"\n          },\n          lazy: true\n      });\n\n      var process = client.getProcess('local', 'gs:splitPolygon');\n      t.ok(process instanceof OpenLayers.WPSProcess, 'creates a process');\n      t.ok(process.client === client, 'process knows about client');\n      t.eq(process.server, 'local', 'process created with correct server');\n      t.eq(process.identifier, 'gs:splitPolygon', 'process created with correct identifier');\n      \n  }\n  \n  function test_describeProcess(t) {\n      t.plan(8);\n      var log = {request: [], event: [], callbacks: []};\n      var originalGET = OpenLayers.Request.GET;\n      OpenLayers.Request.GET = function(cfg) {\n          log.request.push(cfg);\n      }      \n      function describe(evt) {\n          log.event.push(evt);\n      }\n      client.events.register('describeprocess', this, describe);\n      client.lazy = false;\n      process = client.getProcess('local', 'gs:splitPolygon', {callback: function(evt) {\n        log.callbacks.push(evt);\n        client.lazy = true;\n      }});\n      t.eq(client.servers.local.processDescription['gs:splitPolyon'], null, 'describeProcess pending'); \n      process.describe();\n      t.eq(log.request.length, 1, 'describeProcess request only sent once');\n      log.request[0].success.call(client, {\n          responseText: '<?xml version=\"1.0\" encoding=\"UTF-8\"?><wps:ProcessDescriptions xmlns:wps=\"http://www.opengis.net/wps/1.0.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xml:lang=\"en\" service=\"WPS\" version=\"1.0.0\" xsi:schemaLocation=\"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd\"><ProcessDescription wps:processVersion=\"1.0.0\" statusSupported=\"true\" storeSupported=\"true\"><ows:Identifier>gs:splitPolygon</ows:Identifier><ows:Title>Split Polygon</ows:Title><ows:Abstract>Splits a polygon by a linestring</ows:Abstract><DataInputs><Input maxOccurs=\"1\" minOccurs=\"1\"><ows:Identifier>polygon</ows:Identifier><ows:Title>polygon</ows:Title><ows:Abstract>Polygon to split</ows:Abstract><ComplexData><Default><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format></Default><Supported><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format><Format><MimeType>text/xml; subtype=gml/2.1.2</MimeType></Format><Format><MimeType>application/wkt</MimeType></Format><Format><MimeType>application/gml-3.1.1</MimeType></Format><Format><MimeType>application/gml-2.1.2</MimeType></Format></Supported></ComplexData></Input><Input maxOccurs=\"1\" minOccurs=\"1\"><ows:Identifier>line</ows:Identifier><ows:Title>line</ows:Title><ows:Abstract>Linestring to split by</ows:Abstract><ComplexData><Default><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format></Default><Supported><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format><Format><MimeType>text/xml; subtype=gml/2.1.2</MimeType></Format><Format><MimeType>application/wkt</MimeType></Format><Format><MimeType>application/gml-3.1.1</MimeType></Format><Format><MimeType>application/gml-2.1.2</MimeType></Format></Supported></ComplexData></Input></DataInputs><ProcessOutputs><Output><ows:Identifier>result</ows:Identifier><ows:Title>result</ows:Title><ComplexOutput><Default><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format></Default><Supported><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format><Format><MimeType>text/xml; subtype=gml/2.1.2</MimeType></Format><Format><MimeType>application/wkt</MimeType></Format><Format><MimeType>application/gml-3.1.1</MimeType></Format><Format><MimeType>application/gml-2.1.2</MimeType></Format></Supported></ComplexOutput></Output></ProcessOutputs></ProcessDescription></wps:ProcessDescriptions>'\n      });\n      t.eq(log.event[0].type, 'describeprocess', 'describeprocess event triggered');\n      t.ok(client.servers.local.processDescription['gs:splitPolygon'], 'We have a process description!');\n      process.describe();\n      t.eq(log.request.length, 1, 'describeProcess request only sent once');\n      t.eq(log.event.length, 1, 'describeprocess event only triggered once');\n      t.eq(log.callbacks.length, 1, 'describeProcess callback called once');\n      t.eq(log.callbacks[0].title, 'Split Polygon', 'Correct callback argument');\n      OpenLayers.Request.GET = originalGET;\n      client.events.unregister('describeprocess', this, describe);\n  }\n  \n  function test_execute(t) {\n      t.plan(1);\n\n      client = new OpenLayers.WPSClient({\n          servers: {\n              local: \"/geoserver/wps\"\n          },\n          lazy: true\n      });\n      var log = [];\n      client.getProcess = function() {\n          return {\n              execute: function(options) {\n                  log.push(options);\n              }\n          }\n      }\n      \n      client.execute({inputs: 'a', success: 'b', scope: 'c'});\n      t.eq(log[0], {inputs: 'a', success: 'b', scope: 'c'}, \"process executed with correct options\");   \n  }\n  \n  function test_destroy(t) {\n      t.plan(2);\n      client = new OpenLayers.WPSClient({\n          servers: {\n              local: \"/geoserver/wps\"\n          },\n          lazy: true\n      });\n      client.destroy();\n      t.eq(client.events, null, \"Events nullified\");\n      t.eq(client.servers, null, \"Servers nullified\");\n  }\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/WPSProcess.html",
    "content": "<html>\n<head>\n  <script src=\"OLLoader.js\"></script>\n  <script type=\"text/javascript\">\n\n  var wkt = new OpenLayers.Format.WKT();\n  var process;\n  var client = new OpenLayers.WPSClient({\n      servers: {\n          local: 'geoserver/wps'\n      }\n  });\n  client.servers.local.processDescription = {\n      'JTS:contains': '<?xml version=\"1.0\" encoding=\"UTF-8\"?><wps:ProcessDescriptions xmlns:wps=\"http://www.opengis.net/wps/1.0.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xml:lang=\"en\" service=\"WPS\" version=\"1.0.0\" xsi:schemaLocation=\"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd\"><ProcessDescription wps:processVersion=\"1.0.0\" statusSupported=\"true\" storeSupported=\"true\"><ows:Identifier>JTS:contains</ows:Identifier><ows:Title>Contains Test</ows:Title><ows:Abstract>Tests if no points of the second geometry lie in the exterior of the first geometry and at least one point of the interior of second geometry lies in the interior of first geometry.</ows:Abstract><DataInputs><Input maxOccurs=\"1\" minOccurs=\"1\"><ows:Identifier>a</ows:Identifier><ows:Title>a</ows:Title><ows:Abstract>First input geometry</ows:Abstract><ComplexData><Default><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format></Default><Supported><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format><Format><MimeType>text/xml; subtype=gml/2.1.2</MimeType></Format><Format><MimeType>application/wkt</MimeType></Format><Format><MimeType>application/gml-3.1.1</MimeType></Format><Format><MimeType>application/gml-2.1.2</MimeType></Format></Supported></ComplexData></Input><Input maxOccurs=\"1\" minOccurs=\"1\"><ows:Identifier>b</ows:Identifier><ows:Title>b</ows:Title><ows:Abstract>Second input geometry, tested to be contained in first geometry</ows:Abstract><ComplexData><Default><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format></Default><Supported><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format><Format><MimeType>text/xml; subtype=gml/2.1.2</MimeType></Format><Format><MimeType>application/wkt</MimeType></Format><Format><MimeType>application/gml-3.1.1</MimeType></Format><Format><MimeType>application/gml-2.1.2</MimeType></Format></Supported></ComplexData></Input></DataInputs><ProcessOutputs><Output><ows:Identifier>result</ows:Identifier><ows:Title>result</ows:Title><LiteralOutput><ows:DataType>boolean</ows:DataType></LiteralOutput></Output></ProcessOutputs></ProcessDescription></wps:ProcessDescriptions>',\n      'JTS:intersection': '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n          '<wps:ProcessDescriptions xml:lang=\"en\" service=\"WPS\" version=\"1.0.0\" xsi:schemaLocation=\"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd\" xmlns:wps=\"http://www.opengis.net/wps/1.0.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><ProcessDescription wps:processVersion=\"1.0.0\" statusSupported=\"true\" storeSupported=\"true\"><ows:Identifier>JTS:intersection</ows:Identifier><ows:Title>Returns the intersectoin between a and b (eventually an empty collection if there is no intersection)</ows:Title><ows:Abstract>Returns the intersectoin between a and b (eventually an empty collection if there is no intersection)</ows:Abstract><DataInputs><Input maxOccurs=\"1\" minOccurs=\"1\"><ows:Identifier>a</ows:Identifier><ows:Title>a</ows:Title><ows:Abstract>[undescribed]</ows:Abstract><ComplexData><Default><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format></Default><Supported><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format><Format><MimeType>text/xml; subtype=gml/2.1.2</MimeType></Format><Format><MimeType>application/wkt</MimeType></Format><Format><MimeType>application/gml-3.1.1</MimeType></Format><Format><MimeType>application/gml-2.1.2</MimeType></Format></Supported></ComplexData></Input><Input maxOccurs=\"1\" minOccurs=\"1\"><ows:Identifier>b</ows:Identifier><ows:Title>b</ows:Title><ows:Abstract>[undescribed]</ows:Abstract><ComplexData><Default><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format></Default><Supported><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format><Format><MimeType>text/xml; subtype=gml/2.1.2</MimeType></Format><Format><MimeType>application/wkt</MimeType></Format><Format><MimeType>application/gml-3.1.1</MimeType></Format><Format><MimeType>application/gml-2.1.2</MimeType></Format></Supported></ComplexData></Input></DataInputs><ProcessOutputs><Output><ows:Identifier>result</ows:Identifier><ows:Title>Process result</ows:Title><ComplexOutput><Default><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format></Default><Supported><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format><Format><MimeType>text/xml; subtype=gml/2.1.2</MimeType></Format><Format><MimeType>application/wkt</MimeType></Format><Format><MimeType>application/gml-3.1.1</MimeType></Format><Format><MimeType>application/gml-2.1.2</MimeType></Format></Supported></ComplexOutput></Output></ProcessOutputs></ProcessDescription></wps:ProcessDescriptions>' \n  };\n  \n  function test_initialize(t) {\n      t.plan(1);\n      process = new OpenLayers.WPSProcess();\n      t.ok(process instanceof OpenLayers.WPSProcess, 'creates an instance');\n  }\n\n  function test_describe(t) {\n      t.plan(2);\n      process = client.getProcess('local', 'JTS:intersection');\n      var log = [];\n      process.describe({\n          callback: function(description) { log.push(description); }\n      });\n      t.delay_call(0.1, function() {\n          t.eq(log.length, 1, 'callback called');\n          t.eq(log[0].identifier, 'JTS:intersection', 'callback called with correct description');\n      });\n  }\n\n  function test_boolean_output(t) {\n      t.plan(2);\n      var log = [];\n      var originalPOST = OpenLayers.Request.POST;\n      OpenLayers.Request.POST = function(cfg) {\n          cfg.success.call(cfg.scope, {responseText: 'true'});\n      }\n      process = client.getProcess('local', 'JTS:contains');\n      process.describe();\n      var features = [\n          new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(\n              'LINESTRING(117 22,112 18,118 13, 115 8)'\n          )), new OpenLayers.Feature.Vector(OpenLayers.Geometry.fromWKT(\n              'POLYGON((110 20,120 20,120 10,110 10,110 20),(112 17,118 18,118 16,112 15,112 17))'\n          ))\n      ];\n      process.execute({\n          inputs: {\n              a: features[0].geometry,\n              b: features[1].geometry\n          },\n          success: function (output) {\n              log.push(output);\n          }\n      });\n      t.delay_call(0.1, function() {\n          t.eq(log.length, 1, 'One execute requests sent');\n          t.eq(log[0].result, true, 'process output is a boolean with value true');\n          OpenLayers.Request.POST = originalPOST;\n      });\n  }\n  \n  function test_execute(t) {\n      t.plan(7);\n      \n      var log = [];\n      var originalPOST = OpenLayers.Request.POST;\n      OpenLayers.Request.POST = function(cfg) {\n          log.push(cfg);\n          cfg.success.call(cfg.scope, {responseText: ''});\n      }\n      \n      process = new OpenLayers.WPSProcess({\n          client: client,\n          server: 'local',\n          identifier: 'gs:splitPolygon'\n      });\n      process.description = {\n          dataInputs: [{\n              identifier: 'line',\n              complexData: {\n                  supported: {\n                      formats: {'application/wkt': true}\n                  }\n              }\n          }, {\n              identifier: 'polygon',\n              complexData: {\n                  supported: {\n                      formats: {'application/wkt': true}\n                  }\n              }\n          }],\n          processOutputs: [{\n              identifier: 'foo',\n              complexOutput: {\n                  supported: {\n                      formats: {'application/wkt': true}\n                  }\n              }\n          }]\n      };\n      var line = 'LINESTRING(117 22,112 18,118 13,115 8)';\n      var polygon = 'POLYGON((110 20,120 20,120 10,110 10,110 20),(112 17,118 18,118 16,112 15,112 17))';\n      var output = [];\n      function success(result) {\n          output.push(result);\n      }\n      // configured with output identifier\n      process.execute({\n          inputs: {\n              line: wkt.read(line),\n              polygon: wkt.read(polygon)\n          },\n          output: 'foo',\n          success: success\n      });\n      // configured without output identifier\n      process.execute({\n          inputs: {\n              line: wkt.read(line),\n              polygon: wkt.read(polygon)\n          },\n          success: success\n      });\n      \n      t.delay_call(0.1, function() {\n          t.eq(log.length, 2, 'Two execute requests sent');\n          t.eq(process.description.dataInputs[0].data.complexData.value, line, 'data for first input correct');\n          t.eq(process.description.dataInputs[0].data.complexData.mimeType, 'application/wkt', 'format for first input correct');\n          t.eq(process.description.responseForm.rawDataOutput.identifier, 'foo', 'correct identifier for responseForm');\n          t.eq(process.description.responseForm.rawDataOutput.mimeType, 'application/wkt', 'correct format for responseForm');\n          t.ok('foo' in output[0], 'process result contains output with correct identifier when configured with output');\n          t.ok('result' in output[1], 'process result contains output with correct identifier when configured without output');\n\n          OpenLayers.Request.POST = originalPOST;\n      });      \n  }\n  \n  function test_chainProcess(t) {\n      t.plan(5);\n      \n      var originalGET = OpenLayers.Request.GET;\n      OpenLayers.Request.GET = function(cfg) {\n          window.setTimeout(function() {\n              cfg.success.call(cfg.scope, {\n                  responseText: '<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n                      '<wps:ProcessDescriptions xml:lang=\"en\" service=\"WPS\" version=\"1.0.0\" xsi:schemaLocation=\"http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsAll.xsd\" xmlns:wps=\"http://www.opengis.net/wps/1.0.0\" xmlns:ows=\"http://www.opengis.net/ows/1.1\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xlink=\"http://www.w3.org/1999/xlink\"><ProcessDescription wps:processVersion=\"1.0.0\" statusSupported=\"true\" storeSupported=\"true\"><ows:Identifier>JTS:buffer</ows:Identifier><ows:Title>Buffers a geometry using a certain distance</ows:Title><ows:Abstract>Buffers a geometry using a certain distance</ows:Abstract><DataInputs><Input maxOccurs=\"1\" minOccurs=\"1\"><ows:Identifier>geom</ows:Identifier><ows:Title>geom</ows:Title><ows:Abstract>The geometry to be buffered</ows:Abstract><ComplexData><Default><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format></Default><Supported><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format><Format><MimeType>text/xml; subtype=gml/2.1.2</MimeType></Format><Format><MimeType>application/wkt</MimeType></Format><Format><MimeType>application/gml-3.1.1</MimeType></Format><Format><MimeType>application/gml-2.1.2</MimeType></Format></Supported></ComplexData></Input><Input maxOccurs=\"1\" minOccurs=\"1\"><ows:Identifier>distance</ows:Identifier><ows:Title>distance</ows:Title><ows:Abstract>The distance (same unit of measure as the geometry)</ows:Abstract><LiteralData><ows:DataType>xs:double</ows:DataType><ows:AnyValue/></LiteralData></Input><Input maxOccurs=\"1\" minOccurs=\"0\"><ows:Identifier>quadrantSegments</ows:Identifier><ows:Title>quadrantSegments</ows:Title><ows:Abstract>Number of quadrant segments. Use &gt; 0 for round joins, 0 for flat joins, &lt; 0 for mitred joins</ows:Abstract><LiteralData><ows:DataType>xs:int</ows:DataType><ows:AnyValue/></LiteralData></Input><Input maxOccurs=\"1\" minOccurs=\"0\"><ows:Identifier>capStyle</ows:Identifier><ows:Title>capStyle</ows:Title><ows:Abstract>The buffer cap style, round, flat, square</ows:Abstract><LiteralData><ows:AllowedValues><ows:Value>Round</ows:Value><ows:Value>Flat</ows:Value><ows:Value>Square</ows:Value></ows:AllowedValues></LiteralData></Input></DataInputs><ProcessOutputs><Output><ows:Identifier>result</ows:Identifier><ows:Title>result</ows:Title><ComplexOutput><Default><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format></Default><Supported><Format><MimeType>text/xml; subtype=gml/3.1.1</MimeType></Format><Format><MimeType>text/xml; subtype=gml/2.1.2</MimeType></Format><Format><MimeType>application/wkt</MimeType></Format><Format><MimeType>application/gml-3.1.1</MimeType></Format><Format><MimeType>application/gml-2.1.2</MimeType></Format></Supported></ComplexOutput></Output></ProcessOutputs></ProcessDescription></wps:ProcessDescriptions>'\n              });\n          }, 100);\n      }\n      var originalPOST = OpenLayers.Request.POST;\n      OpenLayers.Request.POST = function(cfg) {\n          cfg.success.call(cfg.scope, {responseText: ''});\n      };\n\n      var intersect = client.getProcess('local', 'JTS:intersection');    \n      intersect.configure({\n          inputs: {\n              a: wkt.read(\n                     'LINESTRING(117 22,112 18,118 13,115 8)'\n                 ),\n              b: wkt.read(\n                     'POLYGON((110 20,120 20,120 10,110 10,110 20),(112 17,118 18,118 16,112 15,112 17))'\n                 )\n          }\n      });\n\n      // one buffer process to make sure chaining works\n      var buffer1 = client.getProcess('local', 'JTS:buffer');\n      // another buffer process to make sure that things work asynchronously\n      var buffer2 = client.getProcess('local', 'JTS:buffer');\n      var log = [];\n      buffer1.chainProcess = buffer2.chainProcess = function() {\n          log.push(this.executeCallbacks.length);\n          OpenLayers.WPSProcess.prototype.chainProcess.apply(this, arguments);\n      };\n      var done1 = done2 = false;\n      buffer1.execute({\n          inputs: {\n              geom: intersect.output(),\n              distance: 1\n          },\n          success: function(outputs) {\n              done1 = true;\n          }\n      });\n      buffer2.execute({\n          inputs: {\n              geom: intersect.output(),\n              distance: 2\n          },\n          success: function(outputs) {\n              done2 = true;\n          }\n      });\n      \n      t.delay_call(0.5, function() {\n          t.eq(log.length, 2, 'chainProcess called once for each process');\n          t.eq(log[0], 1, 'executeCallback queued to wait for 1 chained process');\n          t.eq(log[1], 1, 'executeCallback queued to wait for 1 chained process');\n          t.eq(done1, true, 'execute for buffer1 process successfully completed');\n          t.eq(done2, true, 'execute for buffer2 process successfully completed');\n\n          OpenLayers.Request.GET = originalGET;\n          OpenLayers.Request.POST = originalPOST;\n      });\n  }\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/atom-1.0.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<feed xmlns=\"http://www.w3.org/2005/Atom\"\n      xmlns:georss=\"http://www.georss.org/georss\">\n\n  <title>tumulus</title>\n  <link rel=\"self\"\n        href=\"http://pleiades.stoa.org/places/tumulus\"/>\n  <updated/>\n  <author/>\n  <id>http://pleiades.stoa.org/places/tumulus</id>\n    \n  <entry>\n    <title>Unnamed Tumulus</title>\n    <link rel=\"alternate\"\n          href=\"http://pleiades.stoa.org/places/638896\"\n    />\n    <id>http://pleiades.stoa.org/places/638896</id>\n    <updated/>\n    <summary>An ancient tumulus, attested during the Classical period (modern location: Karaburun). Its ancient name is not known.</summary>\n    <georss:point>36.7702 29.9805</georss:point>\n  </entry>\n  <entry>\n    <title>Unnamed Tumulus</title>\n    <link rel=\"alternate\"\n          href=\"http://pleiades.stoa.org/places/638924\"\n    />\n    <id>http://pleiades.stoa.org/places/638924</id>\n    <updated/>\n    <summary>An ancient tumulus, attested during the Classical period (modern location: Kızılbel). Its ancient name is not known.</summary>\n    <georss:point>36.7263 29.8619</georss:point>\n  </entry>\n  \n</feed>\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/auto-tests.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n<html><head>\n<meta http-equiv=\"refresh\" content=\"1200\" />\n<title> Run the testsuite</title>\n<noscript>Javascript is disabled in your browser. This page cannot be displayed correctly without Javascript. Sorry. <br/> If you want to view this page, please change your browser settings so that Javascript is enabled.</noscript>\n<!--\nTest.AnotherWay version 0.5\n\nCopyright (c) 2005 Artem Khodush, http://straytree.org\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n-->\n<style type=\"text/css\">\n* { padding: 0; margin: 0; }\nhtml { height: 99%; }\nbody { height: 98%; font: normal normal 10pt sans-serif }\n#col1 {  float: left; width: 27em; margin: 0 0 0 1em; overflow: visible; }\n#col2 {  position: relative; height: 98%; margin: 0 0.5em 0 28em; }\n#col1_header { margin-top: 0.5em; }\n#scroller { height: 400px; overflow: auto;}\n#testtable { margin: 0 0 2em 0; width: 97%; }\n#run_buttons { margin-bottom: 4em; }\n\n#right_header { padding-top: 0.8em; }\n#results_count { float: left; }\n.active_tab \t\t\t{ float: right; padding: 0 1em 0.2em 1em; background: #0af; border: 1px solid #048; border-bottom: none; cursor: pointer; cursor: hand;\n\t\t\t\t\t position: relative; top: -0.2em; }\n.inactive_tab \t\t\t{ float: right; padding: 0 1em 0 1em; background: #9bb; color: #444; border: 1px solid #9bb; border-bottom: none; cursor: pointer; cursor: hand; }\n.inactive_mouseover_tab \t{ float: right; padding: 0 1em 0 1em; background: #9bb; color: #062; border: 1px solid #062; border-bottom: none; cursor: pointer; cursor: hand; }\n\n#right_frame { overflow: auto; position: relative; top: -0.2em; clear: right; height: 95%; border: 1px solid #048; }\n\n#debug { display: none; }\n#debug p { margin: 2px 0 0 5em; text-indent: -4.8em; }\n\n#error { display: none; color: #c22; }\n\n#results p { margin: 0 0 2px 0; }\n/* cursor indicating that detailed results may be expanded/contracted */\n#results p.badtest { cursor: text; }\n#results p.ok, #results p.fail { cursor: pointer; cursor: hand; }\n\n/* colored squares in the results window at the left of test page names */\n#results p.ok .bullet { background: #6d6; }\n#results p.fail .bullet { background:  #d46; }\n#results p.badtest .bullet { background: #ea3; }\n#results p.loading .bullet { background: #48f; }\n#results p.running .bullet { background: #26e; }\n#results p.waiting .bullet { background: #04d; }\n/* highlight in the results line */\n#results p .warning { background: #ffc; }\n\n/* layout of the detailed results */\n.result_detail { padding-left: 3em; }\n.result_exception_detail { padding-left: 4em; }\n.result_exception_stack_detail { padding-left: 5em;  }\n.result_micro_detail { padding-left: 6em; }\n/* colouring in the detailed results */\n.result_detail .fail, .result_exception_detail .fail,  .result_micro_detail .fail { background: #ffd8d8; }\n\n/* \"start recording\" controls*/\n#record_div { margin-top: 3em; }\n#record_div p { margin-bottom: 0.5em; }\n#record_select { width: 88%; }\n#record_input { width: 53%; }\n</style>\n<script type=\"text/javascript\">\n<!--\n\nfunction report_results() {\n    req = false;\n    // branch for native XMLHttpRequest object\n    if(window.XMLHttpRequest && !(window.ActiveXObject)) {\n        try {\n            req = new XMLHttpRequest();\n        } catch(e) {\n            req = false;\n        }\n    // branch for IE/Windows ActiveX version\n    } else if(window.ActiveXObject) {\n        try {\n            req = new ActiveXObject(\"Msxml2.XMLHTTP\");\n        } catch(e) {\n            try {\n                req = new ActiveXObject(\"Microsoft.XMLHTTP\");\n            } catch(e) {\n                req = false;\n            }\n        }\n    } \n    req.open(\"POST\", \"/test/results.cgi\");\n    req.setRequestHeader(\"Content-Type\", 'application/x-www-form-urlencoded');\n    var results = document.getElementById('total').innerHTML;\n    var test_text = \"\";\n    if (results.match(\"fail\")) {\n        test_text = document.getElementById(\"results\").innerHTML;\n    }    \n    req.send(\"results=\"+escape(results)+\"&test_text=\"+escape(test_text));\n}\n\nif( typeof( Test )==\"undefined\" ) {\n\tTest={};\n}\nTest.AnotherWay={};\n\nTest.AnotherWay._g_test_iframe=null; // frame where to load test pages\nTest.AnotherWay._g_test_frame_no_clear=false; // true - leave last page displayed after tests end\nTest.AnotherWay._g_test_page_urls=[]; // array of: { url: url, convention: \"anotherway\" or \"jsan\" }\nTest.AnotherWay._g_test_object_for_jsan=null; // test object for filling by tests that adhere to jsan Test.Simple calling convention\nTest.AnotherWay._g_pages_to_run=null; // list of pages to run automatically after loading\nTest.AnotherWay._g_run_on_main_load=false; // special handling for run_pages_to_run when it might be called before onload or before list of test pages is known.\nTest.AnotherWay._g_run_on_list_load=false;\nTest.AnotherWay._g_main_loaded=false;\n\nTest.AnotherWay._run_pages_to_run=function( called_from_outside )\n{\n\tif( !Test.AnotherWay._g_main_loaded ) {\n\t\tTest.AnotherWay._g_run_on_main_load=true;\n\t}else {\n\t\tvar a_pages=Test.AnotherWay._g_pages_to_run;\n\t\tif( a_pages==\"all\" ) {\n\t\t\tfor( var i=0; i<Test.AnotherWay._g_test_page_urls.length; ++i ) {\n\t\t\t\tTest.AnotherWay._run_test_page( \"test\"+i );\n\t\t\t}\n\t\t}else if( a_pages!=null ) {\n\t\t\tfor( var run_i=0; run_i<a_pages.length; ++run_i ) {\n\t\t\t\tvar run_page=a_pages[run_i];\n\t\t\t\tvar found=false;\n\t\t\t\tfor( var all_i=0; all_i<Test.AnotherWay._g_test_page_urls.length; ++all_i ) {\n\t\t\t\t\tif( run_page==Test.AnotherWay._g_test_page_urls[all_i].url ) {\n\t\t\t\t\t\tTest.AnotherWay._run_test_page( \"test\"+all_i, called_from_outside );\n\t\t\t\t\t\tfound=true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif( !found ) {\n\t\t\t\t\tTest.AnotherWay._show_error( \"page specified to run is not found in the page list: \"+run_page );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nTest.AnotherWay._add_test_page_url=function( test_url, convention )\n{\n\tvar table=document.getElementById( \"testtable\" );\n\tvar record_select=document.getElementById( \"record_select\" );\n\tvar index=Test.AnotherWay._g_test_page_urls.length;\n\n\t// trim spaces.\n\tif( test_url.match( \"^(\\\\s*)(.*\\\\S)(\\\\s*)$\" ) ) {\n\t\ttest_url=RegExp.$2;\n\t}\n\n\tTest.AnotherWay._g_test_page_urls[index]={ url: test_url, convention: convention };\n\tvar row=table.insertRow( -1 );\n\n\tvar cell;\n\tvar cell_child;\n\tcell=row.insertCell( -1 );\n\tcell_child=document.createElement( \"input\" );\n\tcell_child.type=\"checkbox\";\n\tcell_child.id=\"checkbox\"+index;\n    cell_child.checked='checked';\n    cell_child.defaultChecked='checked';\n\tcell.appendChild( cell_child );\n\n\tcell=row.insertCell( -1 );\n\tcell.setAttribute( \"width\", \"75%\" );\n\tcell.appendChild( document.createTextNode( test_url ) );\n\n\tcell=row.insertCell( -1 );\n\tcell_child=document.createElement( \"input\" );\n\tcell_child.type=\"button\";\n\tcell_child.id=\"test\"+index;\n\tcell_child.value=\" run \";\n\tcell_child.onclick=Test.AnotherWay._run_one_onclick;\n\tcell.appendChild( cell_child );\n\n\tcell=row.insertCell( -1 );\n\tcell.setAttribute( \"width\", \"8em\" );\n\tcell_child=document.createElement( \"span\" );\n\tcell.appendChild( cell_child );\n\n\tvar option=document.createElement( \"option\" );\n\toption.appendChild( document.createTextNode( test_url ) );\n\trecord_select.appendChild( option );\n}\nTest.AnotherWay._show_error=function( msg )\n{\n\tvar error_div=document.getElementById( \"error\" );\n\terror_div.innerHTML=\"\";\n\terror_div.appendChild( document.createTextNode( msg ) );\n\terror_div.style.display=\"block\";\n}\n\n// read urls from the list in the html file inside the list_iframe\n// fill on-screen list with urls and \"run\" buttons, and fill the g_test_page_urls object.\nTest.AnotherWay._list_iframe_onload=function()\n{\n\tif( window.frames.list_iframe!=null && window.frames.list_iframe.location!=\"\" && window.frames.list_iframe.location!=\"about:blank\" ) {\n\t\tvar list_doc=window.frames.list_iframe.document;\n\t\tvar list=list_doc.getElementById( \"testlist\" );\n\t\tif( list!=null ) {\n\t\t\tfor( var i=0; i<list.childNodes.length; ++i ) {\n\t\t\t\tvar item=list.childNodes[i];\n\t\t\t\tif( item.nodeName==\"LI\" || item.nodeName==\"li\" ) {\n\t\t\t\t\tvar convention=\"anotherway\";\n\t\t\t\t\tif( Test.AnotherWay._get_css_class( item )==\"jsan\" ) {\n\t\t\t\t\t\tconvention=\"jsan\";\n\t\t\t\t\t}\n\t\t\t\t\tTest.AnotherWay._add_test_page_url( item.innerHTML, convention );\n\t\t\t\t}\n\t\t\t}\n\t\t\tif( Test.AnotherWay._g_run_on_list_load ) {\n\t\t\t\tTest.AnotherWay._g_run_on_list_load=false;\n\t\t\t\tTest.AnotherWay._run_pages_to_run();\n\t\t\t}\n\t\t}else {\n\t\t\tTest.AnotherWay._show_error( \"no list with id 'testlist' in a list file \"+window.frames.list_iframe.location );\n\t\t}\n\t}\n}\n\nTest.AnotherWay._map_checkboxes=function( f )\n{\n\tvar table=document.getElementById( \"testtable\" );\n\tvar checks=table.getElementsByTagName( \"INPUT\" );\n\tfor( var i=0; i<checks.length; ++i ) {\n\t\tif( checks[i].type==\"checkbox\" && checks[i].id.match( /^checkbox(\\d+)$/ ) ) {\n\t\t\tf( checks[i], RegExp.$1 );\n\t\t}\n\t}\n}\nTest.AnotherWay._run_all_onclick=function()\n{\n\tTest.AnotherWay._map_checkboxes( function( c, id ) { Test.AnotherWay._run_test_page( \"test\"+id ); } );\n}\nTest.AnotherWay._run_selected_onclick=function()\n{\n\tTest.AnotherWay._map_checkboxes( function( c, id ) { if( c.checked ) Test.AnotherWay._run_test_page( \"test\"+id ); } );\n}\nTest.AnotherWay._unselect_all_onclick=function()\n{\n\tTest.AnotherWay._map_checkboxes( function( c, id ) { c.checked=false; } );\n}\nTest.AnotherWay._run_one_onclick=function()\n{\n\tTest.AnotherWay._run_test_page( this.id );\n}\n\n// construct an object that will gather results of running one test function\nTest.AnotherWay._test_object_t=function( fun_name )\n{\n\tthis.name=fun_name; // name of the test function\n\tthis.n_plan=null; // planned number of assertions\n\tthis.n_ok=0; // # of ok assertions\n\tthis.n_fail=0; // # of failed assertions\n\tthis.exception=\"\"; // if the function throwed an exception, it's its message\n\tthis.exception_stack=[]; // strings: function call stack from the exception\n\tthis.assertions=[]; // assertion results: array of { ok: 1 or 0, name: string }\n\tthis.wait_result_milliseconds=0; // how long to wait before collecting results from the test\n\tthis.second_wait_msg=null; // <p> status message (in addition to the page wait_msg)\n\tthis.delay_actions=[]; // array of actions to be perfomed after the test function returns\n\t\t\t\t//\taction : { acton_kind: \"call\" | \"window\" | \"replay\"\n\t\t\t\t//\t\t\t\twhen \"call\": \t\t{ call_fn call_delay_milliseconds } call_fn takes nothing\n\t\t\t\t//\t\t\t\twhen \"window\" : \t{ wnd_url wnd_wnd wnd_fn wnd_timeout_milliseconds wnd_dont_close } wnd_fn takes wnd\n\t\t\t\t//\t\t\t\twnen \"replay\" : \t{ replay_wnd replay_events replay_event_i replay_checkpoints } checkpoint_fn takes this, wnd\n\t\t\t\t//\t}\n\tthis.delay_action_i=null; // index of delay action currently being performed\n\tthis.delay_prev_timer_time=0;\t// for counting time while performing delay_actions\n\tthis.delay_current_milliseconds_left=0; // time left before the next action, runs down\n\tthis.delay_total_milliseconds_left=0; \t// for indication: total estimated time for all actions, runs up and down\n}\n\nTest.AnotherWay._test_object_t.prototype.ok=function( cond, name )\n{\n\tif( cond ) {\n\t\t++this.n_ok;\n\t\tcond=1;\n\t}else {\n\t\t++this.n_fail;\n\t\tcond=0;\n\t}\n\tthis.assertions.push( { ok: cond, name: name } );\n}\nTest.AnotherWay._test_object_t.prototype.fail=function( name )\n{\n\tthis.ok( false, name );\n}\nTest.AnotherWay._test_object_t.prototype.plan=function( n )\n{\n\tthis.n_plan=n;\n}\nTest.AnotherWay._test_object_t.prototype.wait_result=function( seconds )\n{\n\tthis.wait_result_milliseconds=1000*seconds;\n}\nTest.AnotherWay._eq_fail_msg=function( path, what, expected, got )\n{\n\treturn \"eq: \"+path+\" \"+what+\" differ: got \"+got+\", but expected \"+expected;\n}\nTest.AnotherWay._array_eq=function( expected, got, path, msg )\n{\n\tif( expected.length!=got.length ) {\n\t\tmsg.msg=Test.AnotherWay._eq_fail_msg( path, \"array length\", expected.length, got.length );\n\t\treturn false;\n\t}\n\tfor( var i=0; i<expected.length; ++i ) {\n\t\tif( !Test.AnotherWay._thing_eq( expected[i], got[i], path+\"[\"+i+\"]\", msg ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\nTest.AnotherWay._object_eq=function( expected, got, path, msg )\n{\n\tvar v;\n\tfor( v in expected ) {\n\t\tif( ! (v in got) ) {\n\t\t\tmsg.msg=Test.AnotherWay._eq_fail_msg( path+\".\"+v, \"properties\", expected[v], \"undefined\" );\n\t\t\treturn false;\n\t\t}\n\t\tif( !Test.AnotherWay._thing_eq( expected[v], got[v], path+\".\"+v, msg ) ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\tfor( v in got ) {\n\t\tif( ! (v in expected) ) {\n\t\t\tmsg.msg=Test.AnotherWay._eq_fail_msg( path+\".\"+v, \"properties\", \"undefined\", got[v] );\n\t\t\treturn false;\n\t\t}\n\t}\n\treturn true;\n}\nTest.AnotherWay._constructor_name=function( x )\n{\n\tif( x==null ) {\n\t\treturn \"\";\n\t}\n\tvar s=\"unknown\";\n\ttry {\n\t\ts=typeof( x.constructor );\n\t\tif( s!=\"unknown\" ) {\n\t\t\ts=x.constructor.toString();\n\t\t}\n\t}catch( e ) {\n\t\ts=\"unknown\";\n\t}\n\tif( s==\"unknown\" ) {\n\t\t// hackish attempt to guess a type\n\t\tvar is_array=true;\n\t\tvar index=0;\n\t\tfor( i in x ) {\n\t\t\tif( i!=index ) {\n\t\t\t\tis_array=false;\n\t\t\t}\n\t\t\t++index;\n\t\t}\n\t\treturn is_array ? \"Array\" : \"Object\"; // for empty arrays/objects, this will be wrong half the time\n\t}else if( s.match( /^\\s*function\\s+(\\w+)\\s*\\(/ ) ) {\n\t\treturn RegExp.$1;\n\t}else {\n\t  var c = '';\n\t  switch(typeof x) {\n\t    case 'string':\n\t      c = 'String';\n\t      break;\n\t    case 'object':\n\t      c = 'Object';\n\t      break;\n\t    default:\n\t      c = '';\n\t  }\n\t\treturn c;\t}\n}\nTest.AnotherWay._is_array=function( x )\n{\n\treturn Test.AnotherWay._constructor_name( x )==\"Array\";\n}\nTest.AnotherWay._is_value_type=function( x )\n{\n\tcn=Test.AnotherWay._constructor_name( x );\n\treturn cn==\"Number\" || cn==\"String\" || cn==\"Boolean\" || cn==\"Date\";\n}\nTest.AnotherWay._thing_eq=function( expected, got, path, msg )\n{\n\tif( expected==null && got==null ) {\n\t\treturn true;\n\t}else if( (expected==null && got!=null) || (expected!=null && got==null) ) {\n\t\tmsg.msg=Test.AnotherWay._eq_fail_msg( path, \"values\", expected, got );\n\t\treturn false;\n\t}else {\n\t\tvar expected_cn=Test.AnotherWay._constructor_name( expected );\n\t\tvar got_cn=Test.AnotherWay._constructor_name( got );\n\t\tif( expected_cn!=got_cn ) {\n\t\t\tmsg.msg=Test.AnotherWay._eq_fail_msg( path, \"types\", expected_cn, got_cn );\n\t\t\treturn false;\n\t\t}else {\n\t\t\tif( Test.AnotherWay._is_array( expected ) ) {\n\t\t\t\treturn Test.AnotherWay._array_eq( expected, got, path, msg );\n\t\t\t}else if( Test.AnotherWay._is_value_type( expected ) ) {\n\t\t\t\tif( expected!=got ) {\n\t\t\t\t\tmsg.msg=Test.AnotherWay._eq_fail_msg( path, \"values\", expected, got );\n\t\t\t\t\treturn false;\n\t\t\t\t}else {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}else { // just a plain object\n\t\t\t\treturn Test.AnotherWay._object_eq( expected, got, path, msg );\n\t\t\t}\n\t\t}\n\t}\n}\nTest.AnotherWay._test_object_t.prototype.eq=function( got, expected, name )\n{\n\tvar msg={};\n\tif( Test.AnotherWay._thing_eq( expected, got, \"\", msg ) ) {\n\t\tthis.ok( 1, name );\n\t}else {\n\t\tthis.fail( name+\". \"+msg.msg );\n\t}\n}\nTest.AnotherWay._test_object_t.prototype.like=function( got, expected, name )\n{\n\tif( got.match( expected )!=null ) {\n\t\tthis.ok( 1, name );\n\t}else {\n\t\tthis.fail( name+\": got \"+got+\", but expected it to match: \"+expected );\n\t}\n}\nTest.AnotherWay._g_html_eq_span=null;\nTest.AnotherWay._html_eq_string_to_node=function( string_or_node, what, msg )\n{\n\tif( string_or_node.nodeType!=null ) {\n\t\tstring_or_node=Test.AnotherWay._html_eq_node_to_string( string_or_node ); // double trip - to make properties assigned in scripts available as html node attributes\n\t}\n\tif( Test.AnotherWay._g_html_eq_span==null ) {\n\t\tTest.AnotherWay._g_html_eq_span=document.createElement( \"span\" );\n\t}\n\tTest.AnotherWay._g_html_eq_span.innerHTML=string_or_node;\n\tif( Test.AnotherWay._g_html_eq_span.childNodes.length!=1 ) {\n\t\tmsg.msg=\"bad \"+what+\" html string given (should contain exactly one outermost element): \"+string_or_node;\n\t}\n\treturn Test.AnotherWay._g_html_eq_span.childNodes[0].cloneNode( true );\n}\nTest.AnotherWay._html_eq_node_to_string=function( node ) {\n\tif( Test.AnotherWay._g_html_eq_span==null ) {\n\t\tTest.AnotherWay._g_html_eq_span=document.createElement( \"span\" );\n\t}\n\tTest.AnotherWay._g_html_eq_span.innerHTML=\"\";\n\tif( node.outerHTML!=null ) {\n\t\tTest.AnotherWay._g_html_eq_span.innerHTML=node.outerHTML;\n\t}else {\n            var clone = node.cloneNode(true);\n            var node = Test.AnotherWay._g_html_eq_span;\n            if(node.ownerDocument && node.ownerDocument.importNode) {\n                if(node.ownerDocument != clone.ownerDocument) {\n                    clone = node.ownerDocument.importNode(clone, true);\n                }\n            }\n            node.appendChild(clone);\n\t}\n\treturn Test.AnotherWay._g_html_eq_span.innerHTML;\n}\nTest.AnotherWay._html_eq_path_msg=function( path )\n{\n\tvar msg=\"\";\n\tfor( var i=0; i<path.length; ++i ) {\n\t\tmsg+=\" [node \"+path[i].node;\n\t\tif( path[i].id!=null && path[i].id!=\"\" ) {\n\t\t\tmsg+=\" id \"+path[i].id;\n\t\t}else if( path[i].index!=null ) {\n\t\t\tmsg+=\" at index \"+path[i].index;\n\t\t}\n\t\tmsg+=\"] \"\n\t}\n\treturn msg;\n}\nTest.AnotherWay._html_eq_fail_msg=function( path, what, expected, got )\n{\n\treturn Test.AnotherWay._html_eq_path_msg( path )+\": \"+what+\" differ: got \"+got+\", but expected \"+expected;\n}\nTest.AnotherWay._html_eq_remove_blank=function( text )\n{\n\tif( text==null ) {\n\t\treturn \"\";\n\t}else if( text.match( \"^(\\\\s*)(.*\\\\S)(\\\\s*)$\" ) ) {\n\t\treturn RegExp.$2;\n\t}else if( text.match( \"\\s*\" ) ) {\n\t\treturn \"\";\n\t}\n\treturn text;\n}\nTest.AnotherWay._html_eq_remove_blank_nodes=function( node )\n{\n\tvar to_remove=[];\n\tfor( var child=node.firstChild; child!=null; child=child.nextSibling ) {\n\t\tif( child.nodeType==3 ) {\n\t\t\tvar value=Test.AnotherWay._html_eq_remove_blank( child.nodeValue );\n\t\t\tif( value==\"\" ) {\n\t\t\t\tto_remove.push( child );\n\t\t\t}else {\n\t\t\t\tchild.nodeValue=value;\n\t\t\t}\n\t\t}\n\t}\n\tfor( var i=0; i<to_remove.length; ++i ) {\n\t\tnode.removeChild( to_remove[i] );\n\t}\n}\nTest.AnotherWay._html_node_type_text=function( node_type )\n{\n\tif( node_type==1 ) {\n\t\treturn \"1 (html element)\";\n\t}else if( node_type==3 ) {\n\t\treturn \"3 (text)\";\n\t}else {\n\t\treturn node_type;\n\t}\n}\nTest.AnotherWay._html_eq_node=function( expected, got, path, msg, expected_loc_base, got_loc_base )\n{\n\tif( expected.nodeType!=got.nodeType ) {\n\t\tmsg.msg=Test.AnotherWay._html_eq_fail_msg( path, \"node types\", Test.AnotherWay._html_node_type_text( expected.nodeType ), Test.AnotherWay._html_node_type_text( got.nodeType ) );\n\t\treturn false;\n\t}else if( expected.nodeType==3 ) {\n\t\tif( expected.nodeValue!=got.nodeValue ) {\n\t\t\tmsg.msg=Test.AnotherWay._html_eq_fail_msg( path, \"text\", expected.nodeValue, got.nodeValue );\n\t\t\treturn false;\n\t\t}\n\t}else if( expected.nodeType==1 ) {\n\t\tif( expected.nodeName!=got.nodeName ) {\n\t\t\tmsg.msg=Test.AnotherWay._html_eq_fail_msg( path, \"node names\", expected.nodeName, got.nodeName );\n\t\t\treturn false;\n\t\t}\n\t\t// compare attributes\n\t\tvar expected_attrs={};\n\t\tvar got_attrs={};\n\t\tvar i;\n\t\tvar a;\n\t\tfor( i=0; i<expected.attributes.length; ++i ) {\n\t\t\ta=expected.attributes[i];\n\t\t\tif( a.specified ) {\n\t\t\t\texpected_attrs[a.name]=1;\n\t\t\t}\n\t\t}\n\t\tfor( i=0; i<got.attributes.length; ++i ) {\n\t\t\ta=got.attributes[i];\n\t\t\tif( a.specified ) {\n\t\t\t\tgot_attrs[a.name]=1;\n\t\t\t}\n\t\t}\n\t\tfor( a in expected_attrs ) {\n\t\t\tif( ! (a in got_attrs) ) {\n\t\t\t\tmsg.msg=Test.AnotherWay._html_eq_path_msg( path )+\": attribute sets differ: expected attribute \"+a+\" is missing\";\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\tfor( a in got_attrs ) {\n\t\t\tif( ! (a in expected_attrs) ) {\n\t\t\t\tmsg.msg=Test.AnotherWay._html_eq_path_msg( path )+\": attribute sets differ: got extra attribute \"+a;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\tfor( a in expected_attrs ) {\n\t\t\tvar expected_value=expected.getAttribute( a );\n\t\t\tvar got_value=got.getAttribute( a );\n\t\t\tif( typeof( expected_value )==\"string\" && typeof( got_value )==\"string\" ) {\n\t\t\t\texpected_value=Test.AnotherWay._html_eq_remove_blank( expected_value );\n\t\t\t\tgot_value=Test.AnotherWay._html_eq_remove_blank( got_value );\n\t\t\t\tvar ok=expected_value==got_value;\n\t\t\t\tif( !ok && (a==\"href\" || a==\"HREF\" )  ) { // try relative hrefs\n\t\t\t\t\tvar expected_relative_value=expected_value;\n\t\t\t\t\tif( expected_loc_base!=null && expected_value.substring( 0, expected_loc_base.length )==expected_loc_base ) {\n\t\t\t\t\t\texpected_relative_value=expected_value.substring( expected_loc_base.length );\n\t\t\t\t\t}\n\t\t\t\t\tvar got_relative_value=got_value;\n\t\t\t\t\tif( got_loc_base!=null && got_value.substring( 0, got_loc_base.length )==got_loc_base ) {\n\t\t\t\t\t\tgot_relative_value=got_value.substring( got_loc_base.length );\n\t\t\t\t\t}\n\t\t\t\t\tok=expected_relative_value==got_relative_value;\n\t\t\t\t}\n\t\t\t\tif( !ok ) {\n\t\t\t\t\tmsg.msg=Test.AnotherWay._html_eq_fail_msg( path, \"attribute \"+a+\" values\", expected_value, got_value );\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}else if( typeof( expected_value )==\"function\" && typeof( got_value )==\"function\" ) {\n\t\t\t\texpected_value=expected_value.toString();\n\t\t\t\tgot_value=got_value.toString();\n\t\t\t\tif( expected_value!=got_value ) {\n\t\t\t\t\tmsg.msg=Test.AnotherWay._html_eq_fail_msg( path, \"attribute \"+a+\" values\", expected_value, got_value );\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}else {\n\t\t\t\tvar value_msg={};\n\t\t\t\tif( !Test.AnotherWay._thing_eq( expected_value, got_value, \"\", value_msg ) ) {\n\t\t\t\t\tmsg.msg=Test.AnotherWay._html_eq_path_msg( path )+\": attribute \"+a+\" values differ: \"+value_msg.msg;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// compare child nodes\n\t\tTest.AnotherWay._html_eq_remove_blank_nodes( expected );\n\t\tTest.AnotherWay._html_eq_remove_blank_nodes( got );\n\t\tvar expected_length=expected.childNodes.length;\n\t\tvar got_length=got.childNodes.length;\n\t\tif( expected_length<got_length ) {\n\t\t\tmsg.msg=Test.AnotherWay._html_eq_path_msg( path )+\": got \"+(got_length-expected_length)+\" extra child nodes\";\n\t\t\treturn false;\n\t\t}else if( expected_length>got_length ) {\n\t\t\tmsg.msg=Test.AnotherWay._html_eq_path_msg( path )+\": expected \"+(expected_length-got_length)+\" more child nodes\";\n\t\t\treturn false;\n\t\t}else {\n\t\t\tfor( i=0; i<expected_length; ++i ) {\n\t\t\t\tvar expected_node=expected.childNodes[i];\n\t\t\t\tpath.push( { node: expected_node.nodeName, id: expected_node.id, index: i } );\n\t\t\t\tvar eq=Test.AnotherWay._html_eq_node( expected_node, got.childNodes[i], path, msg, expected_loc_base, got_loc_base );\n\t\t\t\tpath.pop();\n\t\t\t\tif( !eq ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn true;\n}\nTest.AnotherWay._html_eq_get_loc_base=function( node )\n{\n\tvar loc_base=document.location;\n\tif( node.ownerDocument!=null ) {\n\t\tloc_base=node.ownerDocument.location;\n\t}\n\tif( loc_base!=null ) {\n\t\tloc_base=loc_base.href;\n\t\tvar slash_pos=loc_base.lastIndexOf( \"/\" );\n\t\tif( slash_pos!=-1 ) {\n\t\t\tloc_base=loc_base.substring( 0, slash_pos+1 );\n\t\t}\n\t}\n\treturn loc_base;\n}\nTest.AnotherWay._test_object_t.prototype.html_eq=function( got, expected, name )\n{\n\tvar msg={};\n\tvar expected_node=Test.AnotherWay._html_eq_string_to_node( expected, \"expected\", msg );\n\tif( msg.msg!=null ) {\n\t\tthis.fail( name+\" html_eq: \"+msg.msg );\n\t}else {\n\t\tvar got_node=Test.AnotherWay._html_eq_string_to_node( got, \"got\", msg );\n\t\tif( msg.msg!=null ) {\n\t\t\tthis.fail( name+\" html_eq: \"+msg.msg );\n\t\t}else {\n\t\t\tvar expected_loc_base=Test.AnotherWay._html_eq_get_loc_base( expected );\n\t\t\tvar got_loc_base=Test.AnotherWay._html_eq_get_loc_base( got );\n\t\t\tif( Test.AnotherWay._html_eq_node( expected_node, got_node, [], msg, expected_loc_base, got_loc_base ) ) {\n\t\t\t\tthis.ok( 1, name );\n\t\t\t}else {\n\t\t\t\tvar msg=name+\" html_eq \"+msg.msg;\n\t\t\t\tvar expected_str=Test.AnotherWay._html_eq_node_to_string( expected_node );\n\t\t\t\tvar got_str=Test.AnotherWay._html_eq_node_to_string( got_node );\n\t\t\t\tmsg+=\".\\n got html: \"+got_str;\n\t\t\t\tmsg+=\".\\n expected html: \"+expected_str;\n\t\t\t\tthis.fail( msg );\n\t\t\t}\n\t\t}\n\t}\n}\nTest.AnotherWay._debug_pane_print=function( msg )\n{\n\tvar d=new Date();\n\tvar p=document.createElement( \"p\" );\n\tp.appendChild( document.createTextNode( d.toLocaleTimeString()+\" \"+msg ) );\n\tvar debug_pane=document.getElementById( \"debug\" );\n\tdebug_pane.appendChild( p );\n\tvar debug_tab=document.getElementById( \"debug_tab\" );\n\tvar results_tab=document.getElementById( \"results_tab\" );\n\tdebug_tab.style.visibility=\"visible\";\n\tresults_tab.style.visibility=\"visible\";\n}\nTest.AnotherWay._test_object_t.prototype.debug_print=function( msg )\n{\n\tTest.AnotherWay._debug_pane_print( this.name+\": \"+msg );\n}\nTest.AnotherWay._test_object_t.prototype.delay_call=function()\n{\n\tvar timeout_ms=200;\n\tfor( var i=0; i<arguments.length; ++i ) {\n\t\tif( typeof( arguments[i] )!=\"function\" ) {\n\t\t\ttimeout_ms=3000*arguments[i];\n\t\t}else {\n\t\t\tvar action={ action_kind: \"call\", call_delay_milliseconds: timeout_ms, call_fn: arguments[i] };\n\t\t\tthis.delay_total_milliseconds_left+=Test.AnotherWay._action_estimate_milliseconds( action );\n\t\t\tthis.delay_actions.push( action );\n\t\t}\n\t}\n}\nTest.AnotherWay._test_object_t.prototype.open_window=function( url, fn, timeout_seconds )\n{\n\tif( timeout_seconds==null ) {\n\t\ttimeout_seconds=4;\n\t}\n\tvar no_close=document.getElementById( \"dont_close_test_windows\" );\n\tvar action={ action_kind: \"window\", wnd_url: url.toString(), wnd_wnd: null, wnd_fn: fn, wnd_timeout_milliseconds: timeout_seconds*1000, wnd_no_close: no_close.checked };\n\tthis.delay_total_milliseconds_left+=Test.AnotherWay._action_estimate_milliseconds( action );\n\tthis.delay_actions.push( action );\n}\nTest.AnotherWay._test_object_t.prototype.replay_events=function( wnd, events )\n{\n\tif( Test.AnotherWay._g_no_record_msg!=null ) {\n\t\tthis.fail( \"replay_events: \"+Test.AnotherWay._g_no_record_msg );\n\t}else {\n\t\tvar action={ action_kind: \"replay\", replay_wnd: wnd, replay_events: events.events, replay_event_i: null, replay_checkpoints: events.checkpoints };\n\t\tthis.delay_total_milliseconds_left+=Test.AnotherWay._action_estimate_milliseconds( action );\n\t\tthis.delay_actions.push( action );\n\t}\n}\nTest.AnotherWay._action_estimate_milliseconds=function( action )\n{\n\tvar ms=0;\n\tif( action.action_kind==\"call\" ) {\n\t\tms=action.call_delay_milliseconds;\n\t}else if( action.action_kind==\"window\" ) {\n\t\tms=0;\n\t}else if( action.action_kind==\"replay\" ) {\n\t\tms=0;\n\t\tfor( var i=0; i<action.replay_events.length; ++i ) {\n\t\t\tms+=action.replay_events[i][\"time\"]-0;\n\t\t}\n\t}\n\treturn ms;\n}\n\nTest.AnotherWay._g_timeout_granularity=200;\nTest.AnotherWay._g_tests_queue=[]; // vector of { url: string, test_objects : array of test_object_t, test_object_i: int, wait_msg: <p> object, loading_timeout_milliseconds: int, timeout_id: id }\n\n// load one html page, schedule further processing\nTest.AnotherWay._run_test_page=function( id, called_from_outside )\n{\n\tif( id.match( /^test(\\d+)/ ) ) {\n\t\tid=RegExp.$1;\n\t\tTest.AnotherWay._g_tests_queue.push( {\n\t\t\turl: Test.AnotherWay._g_test_page_urls[id].url,\n\t\t\tconvention: Test.AnotherWay._g_test_page_urls[id].convention,\n\t\t\ttest_objects: []\n\t\t\t} );\n\t\tif( Test.AnotherWay._g_tests_queue.length==1 ) {\n\t\t\tif( !called_from_outside ) {\n\t\t\t\t// Crap. Be careful stepping around.\n\t\t\t\t// For Mozilla and Opera, when this file is included into the frameset page that is in another directory (and _g_outside_path_correction!=null)\n\t\t\t\t// but the test pages are started from within it (by \"run\" buttons), then:\n\t\t\t\t// depending on whether the page is the first one loaded into the test frame or not,\n\t\t\t\t// the base url for relative test pages differs.\n\t\t\t\t// Crap, like I said.\n\t\t\t\tTest.AnotherWay._g_tests_queue[0].suppress_outside_path_correction=true;\n\t\t\t}\n\t\t\tTest.AnotherWay._start_loading_page();\n\t\t}\n\t}\n}\nTest.AnotherWay._load_next_page=function()\n{\n\tTest.AnotherWay._g_tests_queue.splice( 0, 1 );\n\tif( Test.AnotherWay._g_tests_queue.length>0 ) {\n\t\tTest.AnotherWay._start_loading_page();\n\t}else {\n\t\tif( !Test.AnotherWay._g_test_frame_no_clear ) {\n\t\t\tTest.AnotherWay._g_test_iframe.location.replace( \"about:blank\" );\n\t\t}\n        report_results();\n    }\n}\nTest.AnotherWay._g_opera_path_correction=null; // ugly wart to support opera\nTest.AnotherWay._g_outside_path_correction=null; // ugly wart to accomodate Opera and Mozilla, where relative url relates to the directory where the page that calls this function is located\nTest.AnotherWay._set_iframe_location=function( iframe, loc, outside_path_correction )\n{\n\t// allow to load only locations with the same origin\n\tvar proto_end=loc.indexOf( \"://\" );\n\tif( proto_end!=-1 ) { // otherwise, it's safe to assume (for Opera, Mozilla and IE ) that loc will be treated as relative\n\t\tvar main_loc=window.location.href;\n\t\tvar host_end=loc.substring( proto_end+3 ).indexOf( \"/\" );\n\t\tvar ok=false;\n\t\tif( host_end!=-1 ) {\n\t\t\tvar loc_origin=loc.substring( 0, proto_end+3+host_end+1 );\n\t\t\tif( main_loc.length>=loc_origin.length && main_loc.substring( 0, loc_origin.length )==loc_origin ) {\n\t\t\t\tok=true;\n\t\t\t}\n\t\t}\n\t\tif( !ok ) {\n\t\t\treturn { msg: \"test pages may have only urls with the same origin as \"+main_loc };\n\t\t}\n\t}\n\t// opera cannot handle urls relative to file:// without assistance\n\tif( window.opera!=null && window.location.protocol==\"file:\" && loc.indexOf( \":\" )==-1 ) {\n\t\tvar base=window.location.href;\n\t\tvar q_pos=base.indexOf( \"?\" );\n\t\tif( q_pos!=-1 ) {\n\t\t\tbase=base.substring( 0, q_pos );\n\t\t}\n\t\tvar slash_pos=base.lastIndexOf( \"/\" );\n\t\tif( slash_pos!=-1 ) {\n\t\t\tbase=base.substring( 0, slash_pos+1 );\n\t\t\tTest.AnotherWay._g_opera_path_correction=base;\n\t\t\tloc=base+loc;\n\t\t}\n\t}\n\t// if this function is called from another page, and if that page is in another directory, correction is needed\n\tif( outside_path_correction!=null ) {\n\t\tvar pos=loc.indexOf( outside_path_correction );\n\t\tif( pos==0 ) {\n\t\t\tloc=loc.substring( outside_path_correction.length+1 );\n\t\t}\n\t}\n\tif( iframe.location!=null ) {\n\t\tiframe.location.replace( loc );\n\t}else {\n\t\tiframe.src=loc;\n\t}\n\treturn {};\n}\nTest.AnotherWay._start_loading_page=function()\n{\n\tvar test_page=Test.AnotherWay._g_tests_queue[0];\n\ttest_page.loading_timeout_milliseconds=20000;\n\ttest_page.timeout_id=setTimeout( Test.AnotherWay._loading_timeout, Test.AnotherWay._g_timeout_granularity );\n\ttest_page.wait_msg=Test.AnotherWay._print_counter_result( test_page.url, \"loading...\", test_page.loading_timeout_milliseconds, \"loading\" );\n\tif( test_page.convention==\"jsan\" ) {\n\t\t// the tests in that page will run when it's loading, so the test object must be ready\n\t\tTest.AnotherWay._g_test_object_for_jsan=new Test.AnotherWay._test_object_t( test_page.url );\n\t}\n\tvar outside_path_correction=null;\n\tif( Test.AnotherWay._g_outside_path_correction!=null && !test_page.suppress_outside_path_correction ) {\n\t\toutside_path_correction=Test.AnotherWay._g_outside_path_correction;\n\t}\n\tvar result=Test.AnotherWay._set_iframe_location( Test.AnotherWay._g_test_iframe, test_page.url, outside_path_correction );\n\tif( result.msg!=null ) {\n\t\tTest.AnotherWay._unprint_result( test_page.wait_msg );\n\t\tTest.AnotherWay._print_result( test_page.url, result.msg, \"badtest\", null );\n\t\tTest.AnotherWay._load_next_page();\n\t}\n}\n\nTest.AnotherWay._loading_timeout=function()\n{\n\tvar test_page=Test.AnotherWay._g_tests_queue[0];\n\ttest_page.loading_timeout_milliseconds-=Test.AnotherWay._g_timeout_granularity;\n\tif( test_page.loading_timeout_milliseconds>0 ) {\n\t\tTest.AnotherWay._update_msg_counter( test_page.wait_msg, (test_page.loading_timeout_milliseconds/1000).toFixed() );\n\t\ttest_page.timeout_id=setTimeout( Test.AnotherWay._loading_timeout, Test.AnotherWay._g_timeout_granularity );\n\t}else {\n\t\tTest.AnotherWay._unprint_result( test_page.wait_msg );\n\t\tTest.AnotherWay._print_result( test_page.url, \"Unable to load test page. Timeout expired\", \"badtest\", null );\n\t\tTest.AnotherWay._load_next_page();\n\t}\n}\n\nTest.AnotherWay._strip_query_and_hash=function( s )\n{\n\tvar i=s.lastIndexOf( \"#\" );\n\tif( i!=-1 ) {\n\t\ts=s.substring( 0, i );\n\t}\n\ti=s.lastIndexOf( \"?\" );\n\tif( i!=-1 ) {\n\t\ts=s.substring( 0, i );\n\t}\n\treturn s;\n}\nTest.AnotherWay._is_url_loaded=function( url, wnd )\n{\n\tvar loaded=false;\n\tif( wnd!=null && wnd.location!=null ) {\n\t\t// after some popup blocker interference, location may behave strange..\n\t\tvar location_s=\"\";\n\t\tlocation_s+=wnd.location;\n\t\tif( location_s!=\"\" ) {\n\t\t\tvar pathname=wnd.location.pathname;\n\t\t\tvar expected_url=url;\n\t\t\tvar i=expected_url.lastIndexOf( \"#\" );\n\t\t\tif( i!=-1 ) {\n\t\t\t\texpected_url=expected_url.substring( 0, i );\n\t\t\t}\n\t\t\ti=expected_url.lastIndexOf( \"?\" );\n\t\t\tif( i!=-1 ) {\n\t\t\t\texpected_url=expected_url.substring( 0, i );\n\t\t\t}\n\t\t\ti=expected_url.lastIndexOf( \"/\" );\n\t\t\tif( i!=-1 && i!=expected_url.length-1 ) {\n\t\t\t\texpected_url=expected_url.substring( i+1 );\n\t\t\t}\n\t\t\ti=pathname.indexOf( expected_url )\n\t\t\tif( wnd.location.href==url || (i!=-1 && i==pathname.length-expected_url.length) ) {\n\t\t\t\tif( /*window.opera==null*/wnd.document.readyState==null || wnd.document.readyState==\"complete\" ) { // for opera (and IE?), getElementById does not work until..\n\t\t\t\t\tloaded=true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn loaded;\n}\n// find and run all test functions in the g_cur_page html page.\nTest.AnotherWay._test_page_onload=function()\n{\n\tif( Test.AnotherWay._g_tests_queue.length==0 ) {\n\t\treturn;\n\t}\n\tvar test_page=Test.AnotherWay._g_tests_queue[0];\n\tif( !Test.AnotherWay._is_url_loaded( test_page.url, Test.AnotherWay._g_test_iframe ) ) {\n\t\treturn;\n\t}\n\tclearTimeout( test_page.timeout_id );\n\tTest.AnotherWay._unprint_result( test_page.wait_msg );\n\n\tif( test_page.convention==\"anotherway\" ) {\n\t\t// get test function names (those beginning with \"test\")\n\t\tif( typeof( Test.AnotherWay._g_test_iframe.document.scripts )!='undefined' ) { // IE\n\t\t\tfor( var i=0; i<Test.AnotherWay._g_test_iframe.document.scripts.length; ++i ) {\n\t\t\t\tvar script_text=Test.AnotherWay._g_test_iframe.document.scripts[i].text;\n\t\t\t\tvar fun_sig=\"function test\";\n\t\t\t\tvar fun_start=script_text.indexOf( fun_sig );\n\n\t\t\t\twhile( fun_start!=-1 ) {\n\t\t\t\t\tscript_text=script_text.substring( fun_start, script_text.length );\n\t\t\t\t\tvar fun_end=script_text.indexOf( '(' );\n\t\t\t\t\tvar fun_name=script_text.substring( \"function \".length,  fun_end );\n                                        var whitespace = fun_name.indexOf( ' ' );\n                                        if (whitespace >= 0)\n                                            fun_name = fun_name.substring( 0, whitespace );\n\t\t\t\t\ttest_page.test_objects.push( new Test.AnotherWay._test_object_t( fun_name ) );\n\t\t\t\t\tscript_text=script_text.substring( fun_end, script_text.length );\n\t\t\t\t\tfun_start=script_text.indexOf( fun_sig  );\n\t\t\t\t}\n\t\t\t}\n\t\t}else { // otherwise (not IE) it ought to work like this\n\t\t\tfor( var i in Test.AnotherWay._g_test_iframe) {\n\t\t\t\t// Hack to prevent failure in FF3.0b1 \n                if (i == \"innerWidth\" || i == \"innerHeight\") { continue; }\n\t\t\t\tif( typeof( Test.AnotherWay._g_test_iframe[i] )=='function' ) {\n\t\t\t\t\tif( i.substring( 0, 4 )==\"test\" ) {\n\t\t\t\t\t\ttest_page.test_objects.push( new Test.AnotherWay._test_object_t( i ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}else if( test_page.convention==\"jsan\" ) {\n\t\t// the test object is already filled with results\n\t\ttest_page.test_objects.push( Test.AnotherWay._g_test_object_for_jsan );\n\t}\n\n\tif( test_page.test_objects.length==0 ) {\n\t\tTest.AnotherWay._print_result( test_page.url,  \"No test functions defined in the page\", \"badtest\", null );\n\t\tTest.AnotherWay._load_next_page();\n\t\treturn;\n\t}\n\n\ttest_page.wait_msg=Test.AnotherWay._print_result( test_page.url, \"running tests..<span class=\\\"counter\\\">\"+test_page.test_objects.length+\"</span>\", \"running\", null );\n\n\ttest_page.test_object_i=0;\n\tTest.AnotherWay._run_more_tests();\n}\n\nTest.AnotherWay._handle_exception=function( o, e, title )\n{\n\tvar s=title+\": \"+typeof( e )+\": \";\n\tif( e.message!=null ) {\n\t\ts+=e.message;\n\t}else if( e.description!=null ) {\n\t\ts+=e.description;\n\t}else {\n\t\ts+=e.toString();\n\t}\n//\tif( e.location!=null ) {  // XXX figure out how to display exception location if it's present (like in mozilla)\n//\t\ts+=\" location: \"+e.location.toString();\n//\t}\n\to.exception=s;\n\ts=[];\n\tif( e.stack ) {\n\t\tvar lines=e.stack.split( \"\\n\" );\n\t\tfor( var i=0; i<lines.length; ++i ) {\n\t\t\t// format of the line: func_name(args)@file_name:line_no\n\t\t\tif( lines[i].match( /(\\w*)\\(([^\\)]*)\\)@(.*):([^:]*)$/ ) ) {\n\t\t\t\tvar func_name=RegExp.$1;\n\t\t\t\tif( func_name.length==0 ) {\n\t\t\t\t\tfunc_name=\"<anonymous>\";\n\t\t\t\t}\n\t\t\t\ts.push( \"in \"+func_name+\"( \"+RegExp.$2+\") at \"+RegExp.$3+\" line \"+RegExp.$4+\"\\n\" );\n\t\t\t}\n\t\t}\n\t}\n\to.exception_stack=s;\n}\n\nTest.AnotherWay._run_more_tests=function()\n{\n\tvar test_page=Test.AnotherWay._g_tests_queue[0];\n\twhile( test_page.test_object_i<test_page.test_objects.length ) {\n\t\tTest.AnotherWay._update_msg_counter( test_page.wait_msg, (1+test_page.test_object_i)+\"/\"+test_page.test_objects.length );\n\t\tvar o=test_page.test_objects[test_page.test_object_i];\n\t\tif( test_page.convention==\"anotherway\" ) {\n\t\t\ttry {\n\t\t\t\tTest.AnotherWay._g_test_iframe[o.name]( o );\n\t\t\t}catch( e ) {\n\t\t\t\tTest.AnotherWay._handle_exception( o, e, \"\" );\n\t\t\t}\n\t\t} // for \"jsan\" convention, test has run already\n\t\tif( o.delay_actions.length>0 || o.wait_result_milliseconds>0 ) {\n\t\t\to.delay_total_milliseconds_left+=o.wait_result_milliseconds;\n\t\t\tTest.AnotherWay._delay_actions_timeout();\n\t\t\treturn;\n\t\t}\n\t\t++test_page.test_object_i;\n\t}\n\tTest.AnotherWay._unprint_result( test_page.wait_msg );\n\tTest.AnotherWay._print_result( test_page.url, null, null, test_page.test_objects );\n\tTest.AnotherWay._load_next_page();\n}\n\nTest.AnotherWay._delay_actions_timeout=function()\n{\n\tvar test_page=Test.AnotherWay._g_tests_queue[0];\n\tvar test_object=test_page.test_objects[test_page.test_object_i];\n\tvar finished=true;\n\tif( test_object.delay_action_i==null ) {\n\t\t// set up to start first action\n\t\ttest_object.delay_action_i=-1;\n\t}else {\n\t\t// perform current action\n\t\tvar milliseconds_passed=(new Date()).getTime()-test_object.delay_prev_timer_time;\n\t\ttest_object.delay_current_milliseconds_left-=milliseconds_passed;\n\t\ttest_object.delay_total_milliseconds_left-=milliseconds_passed;\n\t\tfinished=Test.AnotherWay._delay_continue_action( test_object, milliseconds_passed );\n\t}\n\twhile( finished && test_object.delay_action_i<test_object.delay_actions.length ) {\n\t\t++test_object.delay_action_i; // start next action\n\t\tfinished=Test.AnotherWay._delay_start_action( test_object );\n\t}\n\tif( test_object.delay_action_i<=test_object.delay_actions.length ) { // any more actions left ?\n\t\ttest_object.delay_prev_timer_time=(new Date()).getTime();\n\t\tvar next_timeout=Test.AnotherWay._g_timeout_granularity;\n\t\tif( test_object.delay_current_milliseconds_left<next_timeout ) {\n\t\t\tnext_timeout=test_object.delay_current_milliseconds_left;\n\t\t}\n\t\tif( test_object.second_wait_msg!=null ) {\n\t\t\tTest.AnotherWay._update_msg_counter( test_object.second_wait_msg, (test_object.delay_total_milliseconds_left/1000).toFixed() );\n\t\t}\n\t\tsetTimeout( Test.AnotherWay._delay_actions_timeout, next_timeout );\n\t}else { // no more actions left. run the next test.\n\t\tif( test_object.second_wait_msg!=null ) {\n\t\t\tTest.AnotherWay._unprint_result( test_object.second_wait_msg );\n\t\t\ttest_object.second_wait_msg=null;\n\t\t}\n\t\t++test_page.test_object_i;\n\t\tTest.AnotherWay._run_more_tests();\n\t}\n}\nTest.AnotherWay._delay_start_action=function( test_object )\n{\n\tvar finished=false;\n\tvar wait_msg=\"\";\n\tif( test_object.delay_action_i==test_object.delay_actions.length ) {\n\t\tif( test_object.wait_result_milliseconds>0 ) {\n\t\t\ttest_object.delay_current_milliseconds_left=test_object.wait_result_milliseconds; // wait for result\n\t\t\twait_msg=\"waiting for results..\";\n\t\t}else {\n\t\t\t++test_object.delay_action_i; // dont wait for result\n\t\t}\n\t}else {\n\t\tvar action=test_object.delay_actions[test_object.delay_action_i];\n\t\tif( action.action_kind==\"call\" ) {\n\t\t\ttest_object.delay_current_milliseconds_left=action.call_delay_milliseconds;\n\t\t\twait_msg=\"performing delayed calls..\";\n\t\t}else if( action.action_kind==\"window\" ) {\n\t\t\tif( Test.AnotherWay._g_opera_path_correction!=null && action.wnd_url.indexOf( \":\" )==-1 ) {\n\t\t\t\taction.wnd_url=Test.AnotherWay._g_opera_path_correction+action.wnd_url;\n\t\t\t}\n\t\t\taction.wnd_wnd=window.open( action.wnd_url, \"_blank\" );\n\t\t\tif( action.wnd_wnd==null ) {\n\t\t\t\tfinished=true;\n\t\t\t\ttest_object.fail( \"unable to open window for \"+action.wnd_url );\n\t\t\t}else {\n\t\t\t\ttest_object.delay_current_milliseconds_left=action.wnd_timeout_milliseconds;\n\t\t\t\twait_msg=\"opening window..\";\n\t\t\t}\n\t\t}else if( action.action_kind==\"replay\" ) {\n\t\t\tif( action.replay_events.length==0 ) {\n\t\t\t\tfinished=true;\n\t\t\t}else {\n\t\t\t\taction.replay_event_i=0;\n\t\t\t\ttest_object.delay_current_milliseconds_left=action.replay_events[0][\"time\"];\n\t\t\t\twait_msg=\"replaying events..\";\n\t\t\t}\n\t\t}\n\t}\n\tif( test_object.second_wait_msg!=null ) {\n\t\tTest.AnotherWay._unprint_result( test_object.second_wait_msg );\n\t}\n\tif( wait_msg!=\"\" ) {\n\t\tvar test_page=Test.AnotherWay._g_tests_queue[0];\n\t\ttest_object.second_wait_msg=Test.AnotherWay._print_counter_result( test_page.url, wait_msg, test_object.delay_total_milliseconds_left, \"waiting\" );\n\t}else {\n\t\ttest_object.second_wait_msg=null;\n\t}\n\treturn finished;\n}\nTest.AnotherWay._delay_continue_action=function( test_object, milliseconds_passed )\n{\n\tvar finished=test_object.delay_current_milliseconds_left<=0;\n\tif( test_object.delay_action_i==test_object.delay_actions.length ) { // action is \"waiting for results\"\n\t\tif( test_object.n_plan!=null && test_object.n_plan==test_object.n_ok+test_object.n_fail ) {\n\t\t\tfinished=true; // if all assertions results are recorded, don't wait any more\n\t\t}\n\t\tif( finished ) {\n\t\t\t++test_object.delay_action_i; // move on to the next test\n\t\t}\n\t}else {\n\t\tvar action=test_object.delay_actions[test_object.delay_action_i];\n\t\tif( action.action_kind==\"call\" ) {\n\t\t\tif( finished ) {\n\t\t\t\ttry {\n\t\t\t\t\taction.call_fn();\n\t\t\t\t}catch( e ) {\n\t\t\t\t\tTest.AnotherWay._handle_exception( test_object, e, \"in delay_call\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}else if( action.action_kind==\"window\" ) {\n\t\t\ttest_object.delay_total_milliseconds_left+=milliseconds_passed; // for \"window\", the countdown is suspended since it's unknown how long it will take\n\t\t\tif( Test.AnotherWay._is_url_loaded( action.wnd_url, action.wnd_wnd ) ) {\n\t\t\t\ttry {\n\t\t\t\t\taction.wnd_fn( action.wnd_wnd );\n\t\t\t\t}catch( e ) {\n\t\t\t\t\tTest.AnotherWay._handle_exception( test_object, e, \"in open_window function call\" );\n\t\t\t\t}\n\t\t\t\tfinished=true;\n\t\t\t}else if( finished ) {\n\t\t\t\ttest_object.fail(  \"unable to open window for url '\"+action.wnd_url+\"'. timeout expired\" );\n\t\t\t}\n\t\t}else if( action.action_kind==\"replay\" ) {\n\t\t\tif( finished ) {\n//\t\t\t\ttry {\n\t\t\t\t\tTest.AnotherWay._delay_replay_event( test_object, action.replay_wnd, action.replay_events[action.replay_event_i], action.replay_checkpoints );\n//\t\t\t\t}catch( e ) { // disabled, until I know how to gel location info from an exception\n//\t\t\t\t\tTest.AnotherWay._handle_exception( test_object, e, \"while replaying event\" );\n//\t\t\t\t}\n\t\t\t\t++action.replay_event_i;\n\t\t\t\tfinished=action.replay_event_i==action.replay_events.length;\n\t\t\t\tif( !finished ) {\n\t\t\t\t\ttest_object.delay_current_milliseconds_left=action.replay_events[action.replay_event_i][\"time\"];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn finished;\n}\nTest.AnotherWay._delay_replay_event=function( test_object, wnd, event, checkpoints )\n{\n\tif( event.type==\"_checkpoint\" ) {\n\t\tvar checkpoint_n=event.which;\n\t\tvar prev_n_fail=test_object.n_fail;\n\t\tcheckpoints[checkpoint_n]( test_object, wnd );\n\t\tvar flash_color= prev_n_fail==test_object.n_fail ? \"#2f2\" : \"#f22\" ;\n\t\tTest.AnotherWay._record_flash_border( flash_color );\n\t}else if( event.type==\"click\" || event.type==\"mouseover\" || event.type==\"mouseout\" || event.type==\"mousemove\" || event.type==\"mousedown\" || event.type==\"mouseup\" ) {\n\t\tvar target=Test.AnotherWay._record_node_path_to_node( event[\"target\"], wnd.document );\n\t\tif( target!=null ) {\n\t\t\tTest.AnotherWay._record_control_update_highlight( target, \"ball\", event );\n\t\t\tvar e=wnd.document.createEvent( \"MouseEvents\" );\n\t\t\tvar related_target=Test.AnotherWay._record_node_path_to_node( event[\"relatedTarget\"], wnd.document );\n\t\t\te.initMouseEvent(\n\t\t\t\tevent[\"type\"],\n\t\t\t\tevent[\"cancelable\"],\n\t\t\t\tevent[\"bubbles\"],\n\t\t\t\twnd.document.defaultView,\n\t\t\t\tevent[\"detail\"],\n\t\t\t\tevent[\"screenX\"],\n\t\t\t\tevent[\"screenY\"],\n\t\t\t\tevent[\"clientX\"],\n\t\t\t\tevent[\"clientY\"],\n\t\t\t\tevent[\"ctrlKey\"],\n\t\t\t\tevent[\"altKey\"],\n\t\t\t\tevent[\"shiftKey\"],\n\t\t\t\tevent[\"metaKey\"],\n\t\t\t\tevent[\"button\"],\n\t\t\t\tTest.AnotherWay._record_node_path_to_node( event[\"relatedTarget\"], wnd.document )\n\t\t\t);\n\t\t\t// Firefox 1.0.6 somehow loses relatedTarget somewhere on the way. Pass through our own, for those who choose to care.\n\t\t\te.passThroughRelatedTarget=related_target;\n\t\t\ttarget.dispatchEvent( e );\n\t\t}\n\t}else if( event.type==\"keyup\" || event.type==\"keydown\" || event.type==\"keypress\" ) {\n\t\tvar e=wnd.document.createEvent( \"KeyboardEvents\" ); // forget it. Apparently it's not supported neither by mozilla nor by opera.\n\t\te.initKeyboardEvent(\n\t\t\t\tevent[\"type\"],\n\t\t\t\tevent[\"cancelable\"],\n\t\t\t\tevent[\"bubbles\"],\n\t\t\t\twnd.document.defaultView,\n\t\t\t\tevent[\"which\"],\n\t\t\t\tevent[\"which\"],\n\t\t\t\tevent[\"ctrlKey\"],\n\t\t\t\tevent[\"altKey\"],\n\t\t\t\tevent[\"shiftKey\"],\n\t\t\t\tevent[\"metaKey\"],\n\t\t\t\tfalse\n\t\t);\n\t\twnd.document.dispatchEvent( e );\n\t}\n}\n\nTest.AnotherWay._print_counter_result=function( url, msg, milliseconds, style )\n{\n\treturn Test.AnotherWay._print_result( url, msg+\"<span class=\\\"counter\\\">\"+(milliseconds/1000).toFixed()+\"</span>\", style, null );\n}\n\nTest.AnotherWay._g_result_count=0; // for assigning unique ids to result paragraphs\n\n// number of pages tested\nTest.AnotherWay._g_ok_pages=0;\nTest.AnotherWay._g_fail_pages=0;\n\nTest.AnotherWay._print_result=function( url, msg, style, test_objects )\n{\n\tvar results=document.getElementById( \"results\" );\n\tvar r=results.appendChild( document.createElement( \"p\" ) );\n\tr.id=\"result\"+Test.AnotherWay._g_result_count;\n\t++Test.AnotherWay._g_result_count;\n\tr.onclick=Test.AnotherWay._toggle_detail;\n\tvar text=\"<span class=\\\"bullet\\\">&nbsp;&nbsp;&nbsp;</span>&nbsp;\";\n\tif( url!=\"\" ) {\n\t\ttext+=url+\":  \";\n\t}\n\tif( msg!=null ) {\n\t\ttext+=msg;\n\t}\n\tif( test_objects!=null ) {\n\t\t// compose summary and detail texts\n\t\tvar total_ok=0;\n\t\tvar total_detail_ok=0;\n\t\tvar total_fail=0;\n\t\tvar total_detail_fail=0;\n\t\tvar no_plan=0;\n\n\t\tvar detail=results.appendChild( document.createElement( \"div\" ) );\n\n\t\tif( r.id.match( /^result(\\d+)$/ ) ) {\n\t\t\tdetail.id=\"result_detail\"+RegExp.$1;\n\t\t}\n\n\t\tfor( var i=0; i<test_objects.length; ++i ) {\n\t\t\tvar o=test_objects[i];\n\t\t\tvar p;\n\t\t\tvar p_text;\n\t\t\tp=document.createElement( \"P\" );\n\t\t\tTest.AnotherWay._set_css_class( p, \"result_detail\" );\n\t\t\tp_text=o.name;\n\t\t\tif( o.n_fail>0 || o.exception || (o.n_plan!=null && o.n_plan!=o.n_ok+o.n_fail) || (o.n_plan==null && o.n_ok==0 && o.n_fail==0)) {\n\t\t\t\t++total_fail;\n\t\t\t\tp_text+=\" <span class=\\\"fail\\\">\";\n\t\t\t\tif( o.n_plan!=null && o.n_plan!=o.n_ok+o.n_fail) {\n\t\t\t\t\tp_text+=\"planned \"+o.n_plan+\" assertions but got \"+(o.n_ok+o.n_fail)+\"; \";\n\t\t\t\t}\n\t\t\t\tif(o.n_plan==null && o.n_ok==0 && o.n_fail==0) {\n\t\t\t\t\tp_text+=\"test did not output anything\";\n\t\t\t\t}else {\n\t\t\t\t\tp_text+=\" fail \"+o.n_fail;\n\t\t\t\t}\n\t\t\t\tp_text+=\"</span>\";\n\t\t\t}else {\n\t\t\t\t++total_ok;\n\t\t\t}\n\t\t\tp_text+=\" ok \"+o.n_ok;\n\t\t\tif( o.n_plan==null ) {\n\t\t\t\tno_plan=1;\n\t\t\t\tp_text+=\" <span class=\\\"warning\\\">no plan</span>\";\n\t\t\t}\n\t\t\tp.innerHTML=p_text;\n\t\t\tdetail.appendChild( p );\n\t\t\tif( o.exception ) {\n\t\t\t\tp=document.createElement( \"P\" );\n\t\t\t\tTest.AnotherWay._set_css_class( p, \"result_exception_detail\" );\n\t\t\t\tp.innerHTML=\"<span class=\\\"fail\\\">exception:</span> \"+o.exception;\n\t\t\t\tdetail.appendChild( p );\n\t\t\t\tp=document.createElement( \"P\" );\n\t\t\t\tTest.AnotherWay._set_css_class( p, \"result_exception_stack_detail\" );\n\t\t\t\tp.innerHTML=o.exception_stack.join( \"<br/>\" );\n\t\t\t\tdetail.appendChild( p );\n\t\t\t}\n\t\t\tfor( var ii=0; ii<o.assertions.length; ++ii ) {\n\t\t\t\tvar oo=o.assertions[ii];\n\t\t\t\tvar status=oo.ok ? \"ok\" : \"<span class=\\\"fail\\\">fail</span>\";\n\t\t\t\tp=document.createElement( \"P\" );\n\t\t\t\tTest.AnotherWay._set_css_class( p, \"result_micro_detail\" );\n\t\t\t\tp.innerHTML=status;\n\t\t\t\tp.appendChild( document.createTextNode( \" \"+oo.name ) );\n\t\t\t\tdetail.appendChild( p );\n\t\t\t}\n\t\t\ttotal_detail_ok+=o.n_ok;\n\t\t\ttotal_detail_fail+=o.n_fail;\n\t\t}\n\t\tif( total_fail || total_detail_fail ) {\n\t\t\ttext+=\" fail \"+total_fail;\n\t\t}\n\t\ttext+=\" ok \"+total_ok+\" (detailed:\";\n\t\tif( total_fail || total_detail_fail ) {\n\t\t\ttext+=\" fail \"+total_detail_fail;\n\t\t}\n\t\ttext+=\" ok \"+total_detail_ok+\")\";\n\t\tif( no_plan ) {\n\t\t\ttext+=\" <span class=\\\"warning\\\">no plan</span>\";\n\t\t}\n\t\tstyle= total_fail==0 ? \"ok\" : \"fail\";\n\t\tdetail.style.display= style==\"fail\" ? \"block\" : \"none\";\n\t\tdetail.style.cursor=\"text\";\n\t}\n\tif( style!=null ) {\n\t\tTest.AnotherWay._set_css_class( r, style );\n\t\tif( style==\"ok\" ) {\n\t\t\t++Test.AnotherWay._g_ok_pages;\n\t\t}else if( style==\"fail\" || style==\"badtest\" ) {\n\t\t\t++Test.AnotherWay._g_fail_pages;\n\t\t}\n\t\tvar pages_total=\"\";\n\t\tif( Test.AnotherWay._g_fail_pages>0 ) {\n\t\t\tpages_total+=\" fail \"+Test.AnotherWay._g_fail_pages;\n\t\t}\n\t\tpages_total+=\" ok \"+Test.AnotherWay._g_ok_pages;\n\t\tTest.AnotherWay._update_results_total( pages_total );\n\t}\n\tr.innerHTML=text;\n\tif( results.scrollHeight!=null && results.scrollTop!=null && results.offsetHeight!=null ) {\n\t\tresults.scrollTop=results.scrollHeight-results.offsetHeight;\n\t}\n\t// when test_objects is not null, the results are final - good time to clean up\n\tif( test_objects!=null ) {\n\t\tfor( var i=0; i<test_objects.length; ++i ) {\n\t\t\tvar actions=test_objects[i].delay_actions;\n\t\t\tfor( var action_i=0; action_i<actions.length; ++action_i ) {\n\t\t\t\tvar action=actions[action_i];\n\t\t\t\tif( action.action_kind==\"window\" && action.wnd_wnd!=null && !action.wnd_no_close ) {\n\t\t\t\t\taction.wnd_wnd.close();\n\t\t\t\t\taction.wnd_wnd=null;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn r;\n}\nTest.AnotherWay._unprint_result=function( child )\n{\n\tvar results=document.getElementById( \"results\" );\n\tresults.removeChild( child );\n}\nTest.AnotherWay._toggle_detail=function()\n{\n\tif( this.id.match( /^result(\\d+)$/ ) ) {\n\t\tvar detail=document.getElementById( \"result_detail\"+RegExp.$1 );\n\t\tif( detail!=null ) {\n\t\t\tif( detail.style.display==\"none\" ) {\n\t\t\t\tdetail.style.display=\"block\";\n\t\t\t}else if( detail.style.display==\"block\" ) {\n\t\t\t\tdetail.style.display=\"none\";\n\t\t\t}\n\t\t}\n\t}\n}\nTest.AnotherWay._update_msg_counter=function( msg, text )\n{\n\tfor( var i=0; i<msg.childNodes.length; ++i ) {\n\t\tvar item=msg.childNodes[i];\n\t\tif( item.nodeName==\"SPAN\" && Test.AnotherWay._get_css_class( item )==\"counter\" ) {\n\t\t\titem.innerHTML=text;\n\t\t}\n\t}\n}\nTest.AnotherWay._update_results_total=function( msg )\n{\n\tvar total=document.getElementById( \"total\" );\n\tif( total ) {\n\t\ttotal.innerHTML=msg;\n\t}\n}\nTest.AnotherWay._results_clear_onclick=function()\n{\n\tvar results=document.getElementById( \"results\" );\n\tresults.innerHTML=\"\";\n\tTest.AnotherWay._update_results_total( \"\" );\n\tTest.AnotherWay._g_ok_pages=0;\n\tTest.AnotherWay._g_fail_pages=0;\n\tvar debug=document.getElementById( \"debug\" );\n\tdebug.innerHTML=\"\";\n}\n\nTest.AnotherWay._get_css_class=function( o )\n{\n\tvar c=o.getAttribute( \"className\" );\n\tif( c==null || c==\"\" ) {\n\t\tc=o.getAttribute( \"class\" );\n\t}\n\treturn c;\n}\nTest.AnotherWay._set_css_class=function( o, css_class )\n{\n\to.setAttribute( \"className\", css_class );\n\to.setAttribute( \"class\", css_class );\n}\n\nTest.AnotherWay._tab_onclick=function()\n{\n\tvar tab=this;\n\tvar tabs=[ document.getElementById( \"debug_tab\" ), document.getElementById( \"results_tab\" ) ];\n\tvar panes=[ document.getElementById( \"debug\" ), document.getElementById( \"results\" ) ];\n\tfor( var i=0; i<tabs.length; ++i ) {\n\t\tif( tab==tabs[i] ) {\n\t\t\tTest.AnotherWay._set_css_class( tabs[i], \"active_tab\" );\n\t\t\tpanes[i].style.display=\"block\";\n\t\t}else {\n\t\t\tTest.AnotherWay._set_css_class( tabs[i], \"inactive_tab\" );\n\t\t\tpanes[i].style.display=\"none\";\n\t\t}\n\t}\n}\nTest.AnotherWay._tab_mouseover=function()\n{\n\tif( Test.AnotherWay._get_css_class( this )==\"inactive_tab\" ) {\n\t\tTest.AnotherWay._set_css_class( this, \"inactive_mouseover_tab\" );\n\t}\n}\nTest.AnotherWay._tab_mouseout=function()\n{\n\tif( Test.AnotherWay._get_css_class( this )==\"inactive_mouseover_tab\" ) {\n\t\tTest.AnotherWay._set_css_class( this, \"inactive_tab\" );\n\t}\n}\n\n// recording mouse input\nTest.AnotherWay._record_check_onfocus=function()\n{\n\tvar o=this;\n\tvar check_select=o.type!=\"text\";\n\tvar div=document.getElementById( \"record_div\" );\n\tvar inputs=div.getElementsByTagName( \"input\" );\n\tfor( var i=0; i<inputs.length; ++i ) {\n\t\tvar input=inputs[i];\n\t\tif( input.type==\"radio\" ) {\n\t\t\tif( input.value==\"select\" ) {\n\t\t\t\tinput.checked=check_select;\n\t\t\t}else if( input.value==\"input\" ) {\n\t\t\t\tinput.checked=!check_select;\n\t\t\t}\n\t\t}\n\t}\n}\n\nTest.AnotherWay._g_no_record_msg=null; // not null - recording is unavailable\nTest.AnotherWay._g_record_timeout_cnt=0; // opening window for a page for recording\nTest.AnotherWay._g_record_url=null;\nTest.AnotherWay._g_record_wnd=null;\nTest.AnotherWay._g_record_random_id=null; // added to element ids of record_control div so that they do not clash with ids already in the page for which input is recorded\nTest.AnotherWay._g_record_keydown=null; // recording control - which key is down\nTest.AnotherWay._g_record_ctrl_keydown=false;\nTest.AnotherWay._g_record_shift_keydown=false;\nTest.AnotherWay._g_record_control_visible=true; // recording control ui state\nTest.AnotherWay._g_record_started;\nTest.AnotherWay._g_record_paused;\nTest.AnotherWay._g_record_include_mousemove=false;\nTest.AnotherWay._g_record_start_time; // for time references\nTest.AnotherWay._g_record_pause_start_time;\nTest.AnotherWay._g_record_update_time_interval; // showing time in the control ui\nTest.AnotherWay._g_record_waiting_for_results=false; // waiting for results window to open\nTest.AnotherWay._g_record_events; // recorded events\nTest.AnotherWay._g_record_under_cursor; // track element under cursor\nTest.AnotherWay._g_record_checkpoint_count; // for checkpoint numbering\nTest.AnotherWay._g_record_mouse_over_record_control; // for avoiding record control highlight on mouseover\nTest.AnotherWay._g_record_highlighted_element={ element: null, x: null, y: null };\n\nTest.AnotherWay._record_control_get_element=function( id )\n{\n\tif( Test.AnotherWay._g_record_wnd!=null && Test.AnotherWay._g_record_wnd.document!=null ) {\n\t\treturn Test.AnotherWay._g_record_wnd.document.getElementById( id+Test.AnotherWay._g_record_random_id );\n\t}else {\n\t\treturn null;\n\t}\n}\nTest.AnotherWay._record_start_onclick=function() // \"record\" button on the run_tests.html: open a window for a page for which input is recorded\n{\n\tif( Test.AnotherWay._g_no_record_msg!=null ) {\n\t\talert( Test.AnotherWay._g_no_record_msg );\n\t\treturn;\n\t}\n\tif( Test.AnotherWay._g_record_timeout_cnt>0\n\t    || (Test.AnotherWay._g_record_wnd!=null && (Test.AnotherWay._g_record_wnd.closed!=null && !Test.AnotherWay._g_record_wnd.closed)) ) { // in opera, closed is null.\n\t\talert( \"there is already window opened for recording input for a page \"+Test.AnotherWay._g_record_url );\n\t\treturn;\n\t}\n\tvar div=document.getElementById( \"record_div\" );\n\tvar inputs=div.getElementsByTagName( \"input\" );\n\tvar url=null;\n\tfor( var i=0; i<inputs.length; ++i ) {\n\t\tvar input=inputs[i];\n\t\tif( input.type==\"radio\" ) {\n\t\t\tif( input.value==\"select\" && input.checked ) {\n\t\t\t\tvar index=document.getElementById( \"record_select\" ).selectedIndex;\n\t\t\t\tif( index>0 ) {\n\t\t\t\t\turl=Test.AnotherWay._g_test_page_urls[index-1].url;\n\t\t\t\t}\n\t\t\t}else if( input.value==\"input\" && input.checked ) {\n\t\t\t\turl=document.getElementById( \"record_input\" ).value;\n\t\t\t}\n\t\t}\n\t}\n\tif( url!=null ) {\n\t\tTest.AnotherWay._g_record_url=url;\n\t\tTest.AnotherWay._g_record_wnd=window.open( url, \"_blank\" );\n\t\tif( Test.AnotherWay._g_record_wnd==null ) {\n\t\t\talert( \"unable to open new window for a page: \"+url );\n\t\t}else {\n\t\t\tTest.AnotherWay._g_record_timeout_cnt=50;\n\t\t\tsetTimeout( Test.AnotherWay._record_window_timeout, 100 );\n\t\t}\n\t}\n}\nTest.AnotherWay._record_window_timeout=function()\n{\n\tif( Test.AnotherWay._is_url_loaded( Test.AnotherWay._g_record_url, Test.AnotherWay._g_record_wnd ) ) {\n\t\tTest.AnotherWay._record_window_setup( Test.AnotherWay._g_record_wnd );\n\t}else {\n\t\tif( --Test.AnotherWay._g_record_timeout_cnt>0 ) {\n\t\t\tsetTimeout( Test.AnotherWay._record_window_timeout, 100 );\n\t\t}else {\n\t\t\talert( \"timeout expired while opening new window for a page: \"+Test.AnotherWay._g_record_url );\n\t\t\tTest.AnotherWay._g_record_wnd=null;\n\t\t\tTest.AnotherWay._g_record_url=null;\n\t\t\tTest.AnotherWay._g_record_timeout_cnt=0;\n\t\t}\n\t}\n}\nTest.AnotherWay._record_control_randomize_id=function( e, r )\n{\n\tif( e.id!=\"\" ) {\n\t\te.id=e.id+r;\n\t}\n\tfor( var c=e.firstChild; c!=null; c=c.nextSibling ) {\n\t\tTest.AnotherWay._record_control_randomize_id( c, r );\n\t}\n}\nTest.AnotherWay._record_window_setup=function( wnd ) // insert recording control into the page for which input is recorded\n{\n\tTest.AnotherWay._g_record_timeout_cnt=0;\n\tvar this_div=document.getElementById( \"record_control\" );\n\tvar record_control=wnd.document.importNode( this_div, true );\n\tTest.AnotherWay._g_record_random_id=(1000*Math.random()).toFixed();\n\tTest.AnotherWay._record_control_randomize_id( record_control, Test.AnotherWay._g_record_random_id );\n\tTest.AnotherWay._g_record_control_visible=true;\n\tTest.AnotherWay._g_record_started=false;\n\tTest.AnotherWay._g_record_paused=false;\n\tTest.AnotherWay._g_record_checkpoint_count=0;\n\tTest.AnotherWay._g_record_mouse_over_record_control=false;\n\tvar doc=wnd.document;\n\tdoc.body.appendChild( record_control );\n\t// opera sans-serif font is different\n\tif( window.opera ) {\n\t\tcursor_over_indicator=Test.AnotherWay._record_control_get_element( \"record_cursor_over\" );\n\t\tcursor_over_indicator.style.width=\"18em\";\n\t\tcursor_over_indicator.style.height=\"2em\";\n\t\tcursor_over_indicator.style.fontSize=\"7pt\";\n\t}\n\tdoc.addEventListener( \"keydown\", Test.AnotherWay._record_control_keydown, true );\n\tdoc.addEventListener( \"keyup\", Test.AnotherWay._record_control_keyup, true );\n//\tdoc.addEventListener( \"keypress\", Test.AnotherWay._record_event, true ); // replaying is not supported by any known browser\n\n\tdoc.body.addEventListener( \"mousemove\", Test.AnotherWay._record_on_mousemove, true );\n\tdoc.body.addEventListener( \"click\", Test.AnotherWay._record_event, true );\n\tdoc.body.addEventListener( \"mouseover\", Test.AnotherWay._record_event, true );\n\tdoc.body.addEventListener( \"mouseout\", Test.AnotherWay._record_event, true );\n\tdoc.body.addEventListener( \"mousedown\", Test.AnotherWay._record_event, true );\n\tdoc.body.addEventListener( \"mouseup\", Test.AnotherWay._record_event, true );\n}\nTest.AnotherWay._record_control_key_disabled=function( k )\n{\n\tif( k==\"c\" ) {\n\t\treturn !Test.AnotherWay._g_record_started;\n\t}else if( k==\"p\" ) {\n\t\treturn !Test.AnotherWay._g_record_started;\n\t}else if( k==\"s\" ) {\n\t\treturn Test.AnotherWay._g_record_waiting_for_results;\n\t}else {\n\t\treturn false;\n\t}\n}\n\nTest.AnotherWay._record_control_update_ui=function()\n{\n\tvar keydown_color=\"#fff\";\n\tvar disabled_color=\"#aaa\";\n\tvar button_color=\"#adf\";\n\tvar active_color=\"#fdf\";\n\n\tvar display={};\n\tdisplay[false]=\"none\";\n\tdisplay[true]=\"inline\";\n\n\tvar s_button=Test.AnotherWay._record_control_get_element( \"record_s\" );\n\tvar record_on=Test.AnotherWay._record_control_get_element( \"record_on\" );\n\tvar record_off=Test.AnotherWay._record_control_get_element( \"record_off\" );\n\n\ts_button.style.backgroundColor= Test.AnotherWay._record_control_key_disabled( \"s\" ) ? disabled_color\n\t\t: Test.AnotherWay._g_record_keydown==\"s\" ? keydown_color : Test.AnotherWay._g_record_started ? active_color : button_color;\n\trecord_on.style.display=display[!Test.AnotherWay._g_record_started];\n\trecord_off.style.display=display[Test.AnotherWay._g_record_started];\n\n\tvar h_button=Test.AnotherWay._record_control_get_element( \"record_h\" );\n\th_button.style.backgroundColor= Test.AnotherWay._g_record_keydown==\"h\" ? keydown_color : button_color;\n\n\tvar p_button=Test.AnotherWay._record_control_get_element( \"record_p\" );\n\tvar record_pause_on=Test.AnotherWay._record_control_get_element( \"record_pause_on\" );\n\tvar record_pause_off=Test.AnotherWay._record_control_get_element( \"record_pause_off\" );\n\tp_button.style.backgroundColor= Test.AnotherWay._record_control_key_disabled( \"p\" ) ? disabled_color\n\t\t: Test.AnotherWay._g_record_keydown==\"p\" ? keydown_color : Test.AnotherWay._g_record_paused ? active_color : button_color;\n\trecord_pause_on.style.display=display[!Test.AnotherWay._g_record_paused];\n\trecord_pause_off.style.display=display[Test.AnotherWay._g_record_paused];\n\n\tvar m_button=Test.AnotherWay._record_control_get_element( \"record_m\" );\n\tvar record_include_mousemove=Test.AnotherWay._record_control_get_element( \"record_include_mousemove\" );\n\tvar record_omit_mousemove=Test.AnotherWay._record_control_get_element( \"record_omit_mousemove\" );\n\tm_button.style.backgroundColor= Test.AnotherWay._g_record_keydown==\"m\" ? keydown_color : Test.AnotherWay._g_record_include_mousemove ? active_color : button_color;\n\trecord_include_mousemove.style.display=display[!Test.AnotherWay._g_record_include_mousemove];\n\trecord_omit_mousemove.style.display=display[Test.AnotherWay._g_record_include_mousemove];\n\n\tvar c_button=Test.AnotherWay._record_control_get_element( \"record_c\" );\n\tc_button.style.backgroundColor= Test.AnotherWay._record_control_key_disabled( \"c\" ) ? disabled_color\n\t\t: Test.AnotherWay._g_record_keydown==\"c\" ? keydown_color : button_color;\n\n\tvar record_indicator=Test.AnotherWay._record_control_get_element( \"record_indicator\" );\n\trecord_indicator.style.display=display[Test.AnotherWay._g_record_started];\n\n\tvar pause_indicator=Test.AnotherWay._record_control_get_element( \"record_pause_indicator\" );\n\tpause_indicator.style.display=display[Test.AnotherWay._g_record_paused];\n\n\tvar record_control=Test.AnotherWay._record_control_get_element( \"record_control\" );\n\trecord_control.style.display= Test.AnotherWay._g_record_control_visible ? \"block\" : \"none\";\n\n\tvar shift_button=Test.AnotherWay._record_control_get_element( \"record_shift_key\" );\n\tshift_button.style.backgroundColor= Test.AnotherWay._g_record_shift_keydown ? keydown_color : button_color;\n\n\tvar ctrl_button=Test.AnotherWay._record_control_get_element( \"record_ctrl_key\" );\n\tctrl_button.style.backgroundColor= Test.AnotherWay._g_record_ctrl_keydown ? keydown_color : button_color;\n}\nTest.AnotherWay._record_format_time=function( t )\n{\n\tt=new Date( t );\n\tvar m=t.getMinutes();\n\tvar s=t.getSeconds();\n\tvar str= m==0 ? \"\" : m+\"m \";\n\tstr+=s+\"s.\";\n\treturn str;\n}\nTest.AnotherWay._record_control_update_time=function()\n{\n\tvar time_display=Test.AnotherWay._record_control_get_element( \"record_time\" );\n\tif( time_display!=null ) {\n\t\ttime_display.innerHTML=Test.AnotherWay._record_format_time( (new Date()).getTime()-Test.AnotherWay._g_record_start_time );\n\t}\n}\nTest.AnotherWay._record_control_update_highlight=function( elem, style, event )\n{\n\tif( elem==null ) {\n\t\tTest.AnotherWay._record_highlight_border( null );\n\t}else {\n\t\tvar pos=Test.AnotherWay._get_page_coords( elem );\n\t\tif( style==\"ball\" || elem!=Test.AnotherWay._g_record_highlighted_element.element || pos.x!=Test.AnotherWay._g_record_highlighted_element.x || pos.y!=Test.AnotherWay._g_record_highlighted_element.y ) {\n\t\t\tTest.AnotherWay._g_record_highlighted_element={ element: elem, x: pos.x, y: pos.y };\n\t\t\tTest.AnotherWay._record_highlight_border( elem, style, event );\n\t\t}\n\t}\n}\nTest.AnotherWay._record_decode_key=function( event )\n{\n\tvar k=null;\n\tif( event==null ) {\n\t\tk=Test.AnotherWay._g_record_wnd.event.keyCode;\n\t}else {\n\t\tk=event.which;\n\t}\n\tif( k==83 ) {\n\t\treturn \"s\";\n\t}else if( k==72 ) {\n\t\treturn \"h\";\n\t}else if( k==73 ) {\n\t\treturn \"i\";\n\t}else if( k==80 ) {\n\t\treturn \"p\";\n\t}else if( k==67 ) {\n\t\treturn \"c\";\n\t}else if( k==77 ) {\n\t\treturn \"m\";\n\t}else if( k==16 ) {\n\t\treturn \"shift\";\n\t}else if( k==17 ) {\n\t\treturn \"ctrl\";\n\t}else if( k==18 ) {\n\t\treturn \"alt\";\n\t}else if( k==19 ) {\n\t\treturn \"pause\";\n\t}else if( k==123 ) {\n\t\treturn \"f12\";\n\t}\n\treturn \"\";\n}\nTest.AnotherWay._record_control_keydown=function( event )\n{\n\tvar handled=false;\n\tvar k=Test.AnotherWay._record_decode_key( event );\n\tif( k==\"shift\" ) {\n\t\tTest.AnotherWay._g_record_shift_keydown=true;\n\t}else if( k==\"ctrl\" ) {\n\t\tTest.AnotherWay._g_record_ctrl_keydown=true;\n\t}else if( k!=\"\" && (Test.AnotherWay._g_record_keydown==null || Test.AnotherWay._g_record_keydown==k) ) {\n\t\tif( Test.AnotherWay._g_record_ctrl_keydown && Test.AnotherWay._g_record_shift_keydown && !Test.AnotherWay._record_control_key_disabled( k ) ) {\n\t\t\tTest.AnotherWay._g_record_keydown=k;\n\t\t\thandled=true;\n\t\t}\n\t}else {\n\t\tTest.AnotherWay._g_record_keydown=\"\";\n\t}\n\tTest.AnotherWay._record_control_update_ui();\n\tif( !handled ) {\n//\t\tTest.AnotherWay._record_event( event ); // replaying is not supported in any known browser\n\t}\n\treturn;\n}\nTest.AnotherWay._record_control_keyup=function( event )\n{\n\tvar handled=false;\n\tvar k=Test.AnotherWay._record_decode_key( event );\n\tif( k==\"shift\" ) {\n\t\tTest.AnotherWay._g_record_shift_keydown=false;\n\t}else if( k==\"ctrl\" ) {\n\t\tTest.AnotherWay._g_record_ctrl_keydown=false;\n\t}else if( k!=\"\" && k==Test.AnotherWay._g_record_keydown && Test.AnotherWay._g_record_ctrl_keydown && Test.AnotherWay._g_record_shift_keydown  ) {\n\t\tif( k==\"s\" ) {\n\t\t\tTest.AnotherWay._g_record_started=!Test.AnotherWay._g_record_started;\n\t\t\tif( Test.AnotherWay._g_record_started ) {\n\t\t\t\tTest.AnotherWay._g_record_events=[];\n\t\t\t\tTest.AnotherWay._g_record_start_time=(new Date()).getTime();\n\t\t\t\tTest.AnotherWay._record_control_update_time();\n\t\t\t\tTest.AnotherWay._g_record_update_time_interval=window.setInterval( Test.AnotherWay._record_control_update_time, 200 );\n\t\t\t}else {\n\t\t\t\tTest.AnotherWay._record_control_update_highlight( null );\n\t\t\t\tif( !Test.AnotherWay._g_record_paused ) {\n\t\t\t\t\twindow.clearInterval( Test.AnotherWay._g_record_update_time_interval );\n\t\t\t\t}\n\t\t\t\tTest.AnotherWay._g_record_waiting_for_results=true;\n\t\t\t\t// open a new window for self, pass a parameter to dump recorded events as javascript code there\n\t\t\t\t// (the easiest way to obtain a document from the same origin, so it's writable, is to open this same page again)\n\t\t\t\tTest.AnotherWay._g_record_paused=false;\n\t\t\t\tvar loc=window.location;\n\t\t\t\tloc=loc.protocol+\"//\"+loc.host+loc.pathname+\"?recording_results=\"+Test.AnotherWay._g_record_random_id;\n\t\t\t\tif( window.open( loc, \"_blank\" )==null ) {\n\t\t\t\t\talert( \"unable to open new window for results\" );\n\t\t\t\t}\n\t\t\t}\n\t\t\thandled=true;\n\t\t}else if( k==\"h\" ) {\n\t\t\tTest.AnotherWay._g_record_control_visible=!Test.AnotherWay._g_record_control_visible;\n\t\t\thandled=true;\n\t\t}else if( k==\"p\" ) {\n\t\t\tTest.AnotherWay._g_record_paused=!Test.AnotherWay._g_record_paused;\n\t\t\tif( Test.AnotherWay._g_record_paused ) {\n\t\t\t\tTest.AnotherWay._g_record_pause_start_time=(new Date()).getTime();\n\t\t\t\tif( Test.AnotherWay._g_record_started ) {\n\t\t\t\t\twindow.clearInterval( Test.AnotherWay._g_record_update_time_interval );\n\t\t\t\t}\n\t\t\t\tTest.AnotherWay._record_control_update_highlight( null );\n\t\t\t}else {\n\t\t\t\tvar pause_duration=(new Date()).getTime()-Test.AnotherWay._g_record_pause_start_time;\n\t\t\t\tTest.AnotherWay._g_record_start_time+=pause_duration;\n\t\t\t\tTest.AnotherWay._g_record_update_time_interval=window.setInterval( Test.AnotherWay._record_control_update_time, 200 );\n\t\t\t}\n\t\t\thandled=true;\n\t\t}else if( k==\"m\" ) {\n\t\t\tTest.AnotherWay._g_record_include_mousemove=!Test.AnotherWay._g_record_include_mousemove;\n\t\t\thandled=true;\n\t\t}else if( k==\"c\" ) {\n\t\t\tvar o=Test.AnotherWay._record_checkpoint();\n\t\t\tTest.AnotherWay._record_display_checkpoint( o );\n\t\t\tTest.AnotherWay._record_flash_border( \"#24d\" );\n\t\t\thandled=true;\n\t\t}\n\t}\n\tTest.AnotherWay._g_record_keydown=null;\n\tTest.AnotherWay._record_control_update_ui();\n\tif( !handled ) {\n//\t\tTest.AnotherWay._record_event( event ); // replaying is not supported in any known browser\n\t}\n\treturn;\n}\nTest.AnotherWay._record_html_node_path=function( node )\n{\n\tif( node==null ) {\n\t\treturn null;\n\t}\n\tvar path=[];\n\twhile( true ) {\n\t\tif( node.id!=null && node.id!=\"\" ) {\n\t\t\tpath.unshift( \"#\"+node.id+\" \"+node.nodeName );\n\t\t\tbreak;\n\t\t}else {\n\t\t\tvar parent_node=node.parentNode;\n\t\t\tif( parent_node==null ) {\n\t\t\t\treturn []; // no BODY up the path - this node is screwed (browsers differ in what's above the body), discard\n\t\t\t}else {\n\t\t\t\tvar i=0;\n\t\t\t\tvar found=false;\n\t\t\t\tfor( var child=parent_node.firstChild; child!=null; child=child.nextSibling ) {\n\t\t\t\t\tif( child==node ) {\n\t\t\t\t\t\tfound=true;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif( child.nodeType==1 ) { // count only HTML element nodes\n\t\t\t\t\t\t++i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif( !found ) {\n\t\t\t\t\ti=-1;\n\t\t\t\t}\n\t\t\t\tpath.unshift( i+\" \"+node.nodeName );\n\t\t\t\tif( parent_node.nodeName==\"BODY\" || parent_node.nodeName==\"body\" ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tnode=parent_node;\n\t\t\t}\n\t\t}\n\t}\n\treturn path;\n}\nTest.AnotherWay._record_node_path_to_string=function( path )\n{\n\tvar s=\"\";\n\tif( path!=null ) {\n\t\tfor( var i=0; i<path.length; ++i ) {\n\t\t\ts+= i==0 ? \"\" : \", \";\n\t\t\tvar elem=path[i].split( \" \" );\n\t\t\tif( elem[0].charAt( 0 )==\"#\" ) {\n\t\t\t\ts+=elem[1]+\" \"+elem[0];\n\t\t\t}else {\n\t\t\t\ts+=elem[1]+\" [\"+elem[0]+\"]\";\n\t\t\t}\n\t\t}\n\t}\n\treturn s;\n}\nTest.AnotherWay._record_node_path_to_node=function( path_str, doc )\n{\n\tif( path_str==null ) {\n\t\treturn null;\n\t}\n\tvar path=path_str.split( \",\" );\n\tvar node=doc.body;\n\tfor( var i=0; i<path.length; ++i ) {\n\t\tvar node_i=path[i].split( \" \" )[0];\n\t\tif( node_i.charAt( 0 )==\"#\" ) {\n\t\t\tnode=doc.getElementById( node_i.substring( 1 ) );\n\t\t}else {\n\t\t\tif( node_i<0 || node_i>=node.childNodes.length ) {\n\t\t\t\tnode=null;\n\t\t\t}else {\n\t\t\t\tnode=node.firstChild;\n\t\t\t\twhile( node!=null ) {\n\t\t\t\t\tif( node.nodeType==1 ) {  // count only HTML element nodes\n\t\t\t\t\t\tif( node_i==0 ) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t--node_i;\n\t\t\t\t\t}\n\t\t\t\t\tnode=node.nextSibling;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif( node==null ) {\n\t\t\treturn null;\n\t\t}\n\t}\n\treturn node;\n}\nTest.AnotherWay._record_control_contains_id=function( s )\n{\n\treturn s.match( /^#record_[\\w_]+/ ) && s.match( Test.AnotherWay._g_record_random_id );\n}\nTest.AnotherWay._record_checkpoint=function()\n{\n\tvar o={ type: \"_checkpoint\", time: (new Date()).getTime()-Test.AnotherWay._g_record_start_time, which: Test.AnotherWay._g_record_checkpoint_count++,\n\t\t\ttarget: Test.AnotherWay._record_html_node_path( Test.AnotherWay._g_record_under_cursor ) };\n\tTest.AnotherWay._g_record_events.push( o );\n\treturn o;\n}\nTest.AnotherWay._record_event=function( event )\n{\n\tvar unneeded=[\"rangeOffset\",\"eventPhase\",\"timeStamp\",\"isTrusted\",\"popupWindowFeatures\",\"rangeOffset\"];\n\tif( Test.AnotherWay._g_record_started && !Test.AnotherWay._g_record_paused ) {\n\t\tvar o={};\n\t\tfor( var n in event ) {\n\t\t\tvar needed=!n.match( /^[A-Z0-9_]+$/ );\n\t\t\tif( needed ) {\n\t\t\t\tfor( var ui=0; ui<unneeded.length; ++ui ) {\n\t\t\t\t\tif( unneeded[ui]==n ) {\n\t\t\t\t\t\tneeded=false;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif( needed ) {\n\t\t\t\t\tvar value=event[n];\n\t\t\t\t\tif( typeof( value )!=\"object\" && typeof( value )!=\"function\" ) {\n\t\t\t\t\t\to[n]=value;\n\t\t\t\t\t}else if( n==\"target\" || n==\"relatedTarget\" ) {\n\t\t\t\t\t\to[n]=Test.AnotherWay._record_html_node_path( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\to[\"time\"]=(new Date()).getTime()-Test.AnotherWay._g_record_start_time;\n\t\tvar over_record_control= o[\"target\"]!=null && o[\"target\"][0]!=null && Test.AnotherWay._record_control_contains_id( o[\"target\"][0] );\n\t\tif( !over_record_control ) {\n\t\t\tTest.AnotherWay._g_record_events.push( o );\n\t\t}\n\t}\n\treturn true;\n}\nTest.AnotherWay._record_on_mousemove=function( event )\n{\n\tvar path=Test.AnotherWay._record_html_node_path( event.target );\n\tvar new_mouse_over_record_control= path!=null && path[0]!=null && Test.AnotherWay._record_control_contains_id( path[0] );\n\tif( new_mouse_over_record_control!=Test.AnotherWay._g_record_mouse_over_record_control ) {\n\t\tTest.AnotherWay._g_record_mouse_over_record_control=new_mouse_over_record_control;\n\t\tTest.AnotherWay._record_control_update_ui();\n\t}\n\tif( event.target!=null && event.target!=Test.AnotherWay._g_record_under_cursor ) {\n\t\tTest.AnotherWay._g_record_under_cursor=event.target;\n\t\tvar s=\"\";\n\t\tif( path==null || path[0]==null || !Test.AnotherWay._record_control_contains_id( path[0] ) ) {\n\t\t\ts=Test.AnotherWay._record_node_path_to_string( path );\n\t\t}\n\t\tif( s==\"\" ) {\n\t\t\ts=\"&nbsp;\";\n\t\t}\n\t\tvar cursor_over_indicator=Test.AnotherWay._record_control_get_element( \"record_cursor_over\" );\n\t\tcursor_over_indicator.innerHTML=s;\n\t}\n\n\tvar highlight_element=null;\n\tif( !Test.AnotherWay._g_record_mouse_over_record_control && Test.AnotherWay._g_record_started && !Test.AnotherWay._g_record_paused ) {\n\t\thighlight_element=event.target;\n\t}\n\t// highlight border disabled on recording - it causes page to scroll, issuing spurious mouseover/mouseout event\n\t//Test.AnotherWay._record_control_update_highlight( highlight_element, \"border\" );\n\n\tif( Test.AnotherWay._g_record_include_mousemove ) {\n\t\tTest.AnotherWay._record_event( event );\n\t}\n\treturn true;\n}\nTest.AnotherWay._record_display_checkpoint=function( o )\n{\n\tvar checkpoints_div=Test.AnotherWay._record_control_get_element( \"record_checkpoints\" );\n\tvar p=checkpoints_div.appendChild( checkpoints_div.ownerDocument.createElement( \"div\" ) );\n\tp.style.marginTop=\"3px\";\n\tp.style.font=\"normal normal 8pt sans-serif\";\n\tp.style.color=\"#000\";\n\tp.style.textAligh=\"left\";\n\tp.style.position=\"relative\";\n\tp.style.width=\"100%\";\n\tvar checkpoint_text=\"\";\n\tcheckpoint_text+=\"#\"+(o.which+1);\n\tcheckpoint_text+=\"  \"+Test.AnotherWay._record_format_time( o.time );\n\tif( o.target!=null ) {\n\t\tcheckpoint_text+=Test.AnotherWay._record_node_path_to_string( o.target );\n\t}\n\tp.appendChild( p.ownerDocument.createTextNode( checkpoint_text ) );\n}\nTest.AnotherWay._record_save_results=function( doc )\n{\n\t// strange, but DOM-style append does not work here in opera 8.\n\tvar append=function( s ) { doc.write( \"<div>\"+s+\"</div>\" ); };\n\tappend( \"/* paste this data into your javascript and pass it as an argument to replay_events method */\" );\n\tappend( \"{ checkpoints: [\" );\n\tvar first_checkpoint=true;\n\tfor( var i=0; i<Test.AnotherWay._g_record_events.length; ++i ) {\n\t\tvar o=Test.AnotherWay._g_record_events[i];\n\t\tif( o.type==\"_checkpoint\" ) {\n\t\t\tvar str= first_checkpoint ? \"\" : \"}, \";\n\t\t\tstr+=\"function( tst, wnd ) { // #\"+o.which+\" time \"+Test.AnotherWay._record_format_time( o.time )+\" cursor was over \"+Test.AnotherWay._record_node_path_to_string( o.target );\n\t\t\tappend( str );\n\t\t\tfirst_checkpoint=false;\n\t\t}\n\t}\n\tif( !first_checkpoint ) {\n\t\tappend( \"}\" );\n\t}\n\tappend( \"], events: [ \" );\n\tvar prev_time=0;\n\tfor( var i=0; i<Test.AnotherWay._g_record_events.length; ++i ) {\n\t\tvar o=Test.AnotherWay._g_record_events[i];\n\t\tvar s=\"\";\n\t\ts+= \"{\";\n\t\tvar n_first=true;\n\t\tfor( var n in o ) {\n\t\t\tif( n==\"time\" ) { // convert to relative time\n\t\t\t\tvar cur_time=o[n]-0;\n\t\t\t\to[n]=cur_time-prev_time;\n\t\t\t\tprev_time=cur_time;\n\t\t\t}\n\t\t\ts+=n_first ? n : \", \"+n;\n\t\t\ts+=\":\";\n\t\t\tif( o[n]==null ) {\n\t\t\t\ts+=\"null\";\n\t\t\t}else {\n\t\t\t\ts+=\"\\\"\"+o[n]+\"\\\"\";\n\t\t\t}\n\t\t\tn_first=false;\n\t\t}\n\t\ts+= i==Test.AnotherWay._g_record_events.length-1 ? \"}\" : \"},\";\n\t\tappend( s );\n\t}\n\tappend( \"] }\" );\n\tappend( \";\" );\n}\n\nTest.AnotherWay._g_record_border; // border highlighting element under cursor\nTest.AnotherWay._g_record_border_flashes=[]; // array of { color: color, timeout: milliseconds }\nTest.AnotherWay._g_record_border_flashing=false;\nTest.AnotherWay._g_record_border_normal_color=\"#d4b\";\nTest.AnotherWay._record_flash_border_timeout=function()\n{\n\tvar color=Test.AnotherWay._g_record_border_normal_color;\n\tvar timeout=null;\n\tif( Test.AnotherWay._g_record_border_flashes.length!=0 ) {\n\t\tcolor=Test.AnotherWay._g_record_border_flashes[0].color;\n\t\ttimeout=Test.AnotherWay._g_record_border_flashes[0].timeout;\n\t\tTest.AnotherWay._g_record_border_flashes.splice( 0, 1 );\n\t}\n\tif( Test.AnotherWay._g_record_border!=null ) {\n\t\tfor( var i=0; i<Test.AnotherWay._g_record_border.length; ++i ) {\n\t\t\tTest.AnotherWay._g_record_border[i].style.backgroundColor=color;\n\t\t}\n\t}\n\tif( timeout!=null ) {\n\t\tsetTimeout( Test.AnotherWay._record_flash_border_timeout, timeout );\n\t}else {\n\t\tTest.AnotherWay._g_record_border_flashing=false;\n\t}\n}\nTest.AnotherWay._get_page_coords=function( elm )\n{\n\tvar point = { x: 0, y: 0 };\n\twhile( elm )  {\n\t\tpoint.x+=elm.offsetLeft;\n\t\tpoint.y+=elm.offsetTop;\n\t\telm=elm.offsetParent;\n\t }\n\treturn point;\n}\nTest.AnotherWay._set_page_coords=function( elm, x, y )\n{\n\tvar parent_coords={ x: 0, y: 0 };\n\tif( elm.offsetParent )  {\n\t\tparent_coords=Test.AnotherWay._get_page_coords( elm.offsetParent );\n\t}\n\tvar new_x=x-parent_coords.x;\n\tif( new_x<0 ) {\n\t\tnew_x=0;\n\t}\n\telm.style.left=new_x+'px';\n\tvar new_y=y-parent_coords.y;\n\tif( new_y<0 ) {\n\t\tnew_y=0;\n\t}\n\telm.style.top=new_y+'px';\n}\nTest.AnotherWay._record_setup_highlight_positions=function( element, style, coords, positions )\n{\n\tif( style==\"border\" ) {\n\t\tvar width=element.clientWidth;\n\t\tvar height=element.clientHeight;\n\t\tvar step=0;\n\t\tvar thickness=2;\n\t\tvar fudge_expand=4;\n\t\tpositions.push( { x: coords.x-step-thickness, y: coords.y-step-thickness, width: width+2*step+2*thickness+fudge_expand, height: thickness } );\n\t\tpositions.push( { x: coords.x+width+step+fudge_expand, y: coords.y-step-thickness, width: thickness, height: height+2*step+2*thickness+fudge_expand } );\n\t\tpositions.push( { x:positions[0].x, y:positions[0].y, width:positions[0].width, height:positions[0].height } );\n\t\tpositions.push( { x:positions[1].x, y:positions[1].y, width:positions[1].width, height:positions[1].height } );\n\t\tpositions[2].y+=height+thickness+2*step+fudge_expand;\n\t\tpositions[3].x-=width+thickness+2*step+fudge_expand;\n\t}else if( style==\"ball\" ) {\n\t\tpositions.push( { x: coords.x+2, y: coords.y, width: 2, height: 6 } );\n\t\tpositions.push( { x: coords.x, y: coords.y+2, width: 6, height: 2 } );\n\t\tpositions.push( { x: coords.x+1, y: coords.y+1, width: 4, height: 4 } );\n\t}\n}\nTest.AnotherWay._record_highlight_border=function( element, style, event ) // null - hide border\n{\n\tif( element!=null ) {\n\t\tif( Test.AnotherWay._g_record_border==null || Test.AnotherWay._g_record_border[0].ownerDocument!=element.ownerDocument ) {\n\t\t\tTest.AnotherWay._g_record_border=[];\n\t\t\tvar n= style==\"border\" ? 4 : style==\"ball\" ? 3 : 0;\n\t\t\tfor( var i=0; i<4; ++i ) {\n\t\t\t\tvar b=element.ownerDocument.createElement( \"div\" );\n\t\t\t\tb.style.position=\"absolute\";\n\t\t\t\tb.style.zIndex=\"1\";\n\t\t\t\tb.style.backgroundColor=Test.AnotherWay._g_record_border_normal_color;\n\t\t\t\telement.ownerDocument.body.appendChild( b );\n\t\t\t\tTest.AnotherWay._g_record_border.push( b );\n\t\t\t}\n\t\t}\n\t\tvar coords=null;\n\t\tif( style==\"border\" ) {\n\t\t\tcoords=Test.AnotherWay._get_page_coords( element );\n\t\t}else if( style==\"ball\" ) {\n\t\t\tif( event!=null ) {\n\t\t\t\tif( event.pageX!=null && event.pageY!=null ) {\n\t\t\t\t\tcoords={ x: event.pageX-0, y: event.pageY-0 };\n\t\t\t\t}else if( event.clientX!=null && event.clientY!=null ) {\n\t\t\t\t\tvar doc=element.ownerDocument;\n\t\t\t\t\tif( doc!=null ) {\n\t\t\t\t\t\tcoords={ x: (event.clientX-0)+doc.body.scrollLeft, y: (event.clientY-0)+doc.body.scrollTop };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif( coords!=null && element.clientWidth!=null && element.clientHeight!=null ) {\n\t\t\tvar positions=[];\n\t\t\tTest.AnotherWay._record_setup_highlight_positions( element, style, coords, positions );\n\t\t\tfor( var i=0; i<positions.length; ++i ) {\n\t\t\t\tvar b=Test.AnotherWay._g_record_border[i];\n\t\t\t\tvar p=positions[i];\n\t\t\t\tTest.AnotherWay._set_page_coords( b, p.x, p.y );\n\t\t\t\tb.style.width=p.width+\"px\";\n\t\t\t\tb.style.height=p.height+\"px\";\n\t\t\t\tb.style.display=\"block\";\n\t\t\t}\n\t\t}\n\t}else {\n\t\tif( Test.AnotherWay._g_record_border!=null ) {\n\t\t\tfor( var i=0; i<Test.AnotherWay._g_record_border.length; ++i ) {\n\t\t\t\tTest.AnotherWay._g_record_border[i].style.display=\"none\";\n\t\t\t}\n\t\t}\n\t}\n}\nTest.AnotherWay._record_flash_border=function( color )\n{\n\tif( Test.AnotherWay._g_record_border_flashing ) { //already\n\t\tTest.AnotherWay._g_record_border_flashes.push( { color: Test.AnotherWay._g_record_border_normal_color, timeout:300 } );\n\t\tTest.AnotherWay._g_record_border_flashes.push( { color: color, timeout:600 } );\n\t}else {\n\t\tTest.AnotherWay._g_record_border_flashing=true;\n\t\tTest.AnotherWay._g_record_border_flashes.push( { color: color, timeout:600 } );\n\t\tTest.AnotherWay._record_flash_border_timeout();\n\t}\n}\nTest.AnotherWay._record_prepare_doc_for_results=function()\n{\n\tdocument.open();\n\tdocument.write( \"<!DOCTYPE HTML PUBLIC \\\"-//W3C//DTD HTML 4.01//EN\\\" \\\"http://www.w3.org/TR/html4/strict.dtd\\\">\" );\n\tdocument.write( \"<html><head><title> Input recording results</title>\" );\n\tdocument.write( \"<style type=\\\"text/css\\\">\" );\n\tdocument.write( \"body { font: normal normal smaller sans-serif; }\" );\n\tdocument.write( \"div { margin-top: 3px; }\" );\n\tdocument.write( \"</style></head><body>\" );\n\t// opera and mozilla disagree over who the opener is.\n\tif( typeof( window.opener.Test )!=\"undefined\" && typeof( window.opener.Test.AnotherWay )!=\"undefined\" ) {\n\t\twindow.opener.Test.AnotherWay._record_save_results( document );\n\t\twindow.opener.Test.AnotherWay._g_record_waiting_for_results=false;\n\t\twindow.opener.Test.AnotherWay._record_control_update_ui();\n\t}else if( typeof( window.opener.opener.Test  )!=\"undefined\" && typeof( window.opener.opener.Test.AnotherWay )!=\"undefined\" ) {\n\t\twindow.opener.opener.Test.AnotherWay._record_save_results( document );\n\t\twindow.opener.opener.Test.AnotherWay._g_record_waiting_for_results=false;\n\t\twindow.opener.opener.Test.AnotherWay._record_control_update_ui();\n\t}\n\tdocument.write( \"</body>\" );\n\tdocument.close();\n}\n\n// global initialization\nonload=function()\n{\n\tif( window.opera ) {\n\t\tvar good_opera=typeof( window.opera.version )==\"function\";\n\t\tgood_opera=good_opera && window.opera.version().match( /^\\s*(\\d+)/ );\n\t\tgood_opera=good_opera && RegExp.$1>=8;\n\t}\n\tvar span=document.createElement( \"SPAN\" );\n\tspan.innerHTML=\"<!--[if IE]><br /><![endif]-\"+\"->\";\n\tvar is_ie=span.getElementsByTagName( \"BR\" ).length>0;\n\n\tTest.AnotherWay._g_test_iframe=window.frames.test_iframe;\n\n\tvar query_str=window.location.search;\n\tif( query_str.charAt( 0 )==\"?\" ) {\n\t\tquery_str=query_str.substring( 1 );\n\t}\n\tvar testlist_page=\"list-tests.html\";\n\tvar auto_run=false;\n\tif( query_str!=\"\" ) {\n\t\tvar params=[query_str];\n\t\tif( query_str.indexOf( \";\" )!=-1 ) {\n\t\t\tparams=query_str.split( \";\" );\n\t\t}else if( query_str.indexOf( \"&\" )!=-1 ) {\n\t\t\tparams=query_str.split( \"&\" );\n\t\t}\n\t\tfor( var param_i=0; param_i<params.length; ++param_i ) {\n\t\t\tvar param=params[param_i].split( \"=\" );\n\t\t\tif( param[0]==\"recording_results\" ) {\n\t\t\t\tif( window.opener!=null ) {\n\t\t\t\t\t// we were told to show recording results - replace everything in the document with the results\n\t\t\t\t\tTest.AnotherWay._record_prepare_doc_for_results();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}else if( param[0]==\"testpage\" ) {\n\t\t\t\tTest.AnotherWay._add_test_page_url( decodeURIComponent( param[1] ), \"anotherway\" );\n\t\t\t}else if( param[0]==\"jsantestpage\" ) {\n\t\t\t\tTest.AnotherWay._add_test_page_url( decodeURIComponent( param[1] ), \"jsan\" );\n\t\t\t}else if( param[0]==\"testlist\" ) {\n\t\t\t\ttestlist_page=decodeURIComponent( param[1] );\n\t\t\t}else if( param[0]==\"testframe\" ) {\n\t\t\t\tif( window.opera && !good_opera ) {\n\t\t\t\t\tTest.AnotherWay._show_error( \"testframe parameter does not work in versions of Opera prior to 8.0. Sorry (pathches are welcome).\" );\n\t\t\t\t\t// Opera 7 barfs on attempt to access frame.frameElement.\n\t\t\t\t\t// if someone knows a way to assign onload handler to that iframe in Opera 7\n\t\t\t\t\t// without disrupting code that works in other browsers, patches are welcome.\n\t\t\t\t}else {\n\t\t\t\t\tvar frame_path=param[1].split( \".\" );\n\t\t\t\t\tvar frame=top;\n\t\t\t\t\tfor( var frame_path_i=0; frame_path_i<frame_path.length; ++frame_path_i ) {\n\t\t\t\t\t\tframe=frame[frame_path[frame_path_i]];\n\t\t\t\t\t}\n\t\t\t\t\tif( frame==null ) {\n\t\t\t\t\t\tTest.AnotherWay._show_error( \"unable to find frame specified for loading test pages: \"+param[1] );\n\t\t\t\t\t}else {\n\t\t\t\t\t\tif( frame.frameElement!=null ) { // for the following assignement to onload to work, frameElement is required\n\t\t\t\t\t\t\tframe=frame.frameElement;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tTest.AnotherWay._g_test_iframe=frame;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}else if( param[0]==\"testframe_no_clear\" ) {\n\t\t\t\tTest.AnotherWay._g_test_frame_no_clear=true;\n\t\t\t}else if( param[0]==\"windows\" ) {\n                if (param[1] == \"none\") {\n                }\n\t\t\t}else if( param[0]==\"run\" ) {\n\t\t\t\tauto_run=true;\n\t\t\t\tif( param[1]==\"all\" ) {\n\t\t\t\t\tTest.AnotherWay._g_pages_to_run=\"all\";\n\t\t\t\t}else {\n\t\t\t\t\tif( Test.AnotherWay._g_pages_to_run==null || Test.AnotherWay._g_pages_to_run==\"all\" ) {\n\t\t\t\t\t\tTest.AnotherWay._g_pages_to_run=[];\n\t\t\t\t\t}\n\t\t\t\t\tvar pages=param[1].split( \",\" );\n\t\t\t\t\tfor( var i=0; i<pages.length; ++i ) {\n\t\t\t\t\t\tTest.AnotherWay._g_pages_to_run.push( pages[i] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\tif( Test.AnotherWay._g_test_page_urls.length==0 ) {  // if no individual pages were given on the command line, load the list\n\t\tvar result=Test.AnotherWay._set_iframe_location( window.frames[\"list_iframe\"], testlist_page );\n\t\tif( result.msg!=null ) {\n\t\t\tTest.AnotherWay._show_error( result.msg );\n\t\t}\n\t\tTest.AnotherWay._g_run_on_list_load=auto_run;\n\t}else {\n\t\tTest.AnotherWay._g_run_on_main_load=auto_run;\n\t}\n\n\tvar f=Test.AnotherWay._g_test_iframe;\n\ttry {\n\t\tif( f.attachEvent!=null ) {\n\t\t\tf.attachEvent( \"onload\", Test.AnotherWay._test_page_onload );\n\t\t}else {\n\t\t\tf.onload=Test.AnotherWay._test_page_onload;\n\t\t}\n\t\tif( Test.AnotherWay._g_test_iframe.nodeType!=null && Test.AnotherWay._g_test_iframe.contentWindow!=null ) { // it's iframe element, not the iframe. we need iframe.\n\t\t\tTest.AnotherWay._g_test_iframe=Test.AnotherWay._g_test_iframe.contentWindow;\n\t\t}\n\t}catch(e) {\n\t\t// ignore stupid opera error if the frame has onload handler assigned in the inline html\n\t}\n\tvar handlers={\n\t\t\"run_all\": { \"onclick\": Test.AnotherWay._run_all_onclick },\n\t\t\"run_selected\": { \"onclick\": Test.AnotherWay._run_selected_onclick },\n\t\t\"unselect_all\": { \"onclick\": Test.AnotherWay._unselect_all_onclick },\n\t\t\"record_select\": { \"onfocus\": Test.AnotherWay._record_check_onfocus },\n\t\t\"record_input\": { \"onfocus\": Test.AnotherWay._record_check_onfocus },\n\t\t\"record_start\": { \"onclick\": Test.AnotherWay._record_start_onclick },\n\t\t\"clear_btn\": { \"onclick\": Test.AnotherWay._results_clear_onclick },\n\t\t\"results_tab\": { \"onclick\": Test.AnotherWay._tab_onclick, \"onmouseover\": Test.AnotherWay._tab_mouseover, \"onmouseout\": Test.AnotherWay._tab_mouseout },\n\t\t\"debug_tab\": { \"onclick\": Test.AnotherWay._tab_onclick, \"onmouseover\": Test.AnotherWay._tab_mouseover, \"onmouseout\": Test.AnotherWay._tab_mouseout }\n\t};\n\tfor( var hs in handlers ) {\n\t\tvar o=document.getElementById( hs );\n\t\tif( o!=null ) {\n\t\t\tfor( var h in handlers[hs] ) {\n\t\t\t\to[h]=handlers[hs][h];\n\t\t\t}\n\t\t}else {\n\t\t\tTest.AnotherWay._show_error( \"unable to set \"+h+\" handler: id \"+hs+\" not found\" );\n\t\t}\n\t}\n\n\tif( window.opera && !good_opera ) {\n\t\tTest.AnotherWay._g_no_record_msg=\"Input events recording and replaying is not available in opera versions prior to 8.0.\";\n\t}\n\tif( is_ie ) {\n\t\tTest.AnotherWay._g_no_record_msg=\"Input events recording and replaying is not available in internet explorer.\";\n\t}\n \tif( Test.AnotherWay._g_no_record_msg!=null ) {\n\t\tvar no_record_p=document.getElementById( \"record_not_supported\" );\n\t\tno_record_p.style.display=\"block\";\n\t\tno_record_p.appendChild( document.createTextNode( Test.AnotherWay._g_no_record_msg ) );\n\t}\n\n\tTest.AnotherWay._g_main_loaded=true;\n\tif( Test.AnotherWay._g_run_on_main_load ) {\n\t\tTest.AnotherWay._g_run_on_main_load=false;\n\t\tTest.AnotherWay._run_pages_to_run();\n\t}\n}\nTest.AnotherWay._test_object_t.prototype.open_window=null;\n// -->\n</script>\n<script type=\"text/javascript\" src=\"xml_eq.js\"></script>\n<script type=\"text/javascript\" src=\"geom_eq.js\"></script>\n</head><body>\n\n<div id=\"col1\">\n<div id=\"col1_header\">Test pages:</div>\n<div id=\"scroller\">\n<table id=\"testtable\">\n</table>\n</div>\n<div id=\"run_buttons\">\n<input type=\"button\" value=\" clear \" id=\"clear_btn\" />\n<input type=\"button\" value=\" run all \" id=\"run_all\" />\n<input type=\"button\" value=\" run selected \" id=\"run_selected\" />\n<input type=\"button\" value=\" unselect all \" id=\"unselect_all\" />\n</div>\n<input type=\"checkbox\" id=\"dont_close_test_windows\" /> do not close windows opened by tests\n<div id=\"error\"></div>\n<div id=\"record_div\">\n<p id=\"record_not_supported\" style=\"display:none\"></p>\n<p>Record mouse input for the page:</p>\n<p><input type=\"radio\" name=\"record_choose\" value=\"select\" checked=\"checked\" /> <select id=\"record_select\"><option selected=\"selected\">-- select a page: --</option></select></p>\n<p><input type=\"radio\" name=\"record_choose\" value=\"input\" /> or enter page url: <input type=\"text\" id=\"record_input\" /></p>\n<p><input type=\"button\" value=\" record \" id=\"record_start\" /></p>\n</div>\n</div>\n\n<div id=\"col2\">\n<div id=\"right_header\">\n<span id=\"results_count\">Results: <span id=\"total\"></span></span>\n<span id=\"results_tab\" class=\"active_tab\" style=\"visibility:hidden\">Results</span>\n<span id=\"debug_tab\" class=\"inactive_tab\" style=\"visibility:hidden\">Debug</span>\n</div>\n<div id=\"right_frame\">\n<div id=\"results\"></div>\n<div id=\"debug\"></div>\n</div>\n</div>\n\n<span style=\"display:none\">\n<iframe name=\"list_iframe\" onload=\"Test.AnotherWay._list_iframe_onload();\"></iframe>\n<iframe name=\"test_iframe\" onload=\"Test.AnotherWay._test_page_onload();\"></iframe>\n\n<!-- record_control div is to be imported into other documents, so all its styles are inline -->\n-<div id=\"record_control\" style=\"position:absolute;bottom:0;left:0;margin:0;padding:0.5em;width:22em;height:22em;border:1px solid;background:#ffd;font: normal normal 8pt sans-serif; color:#000; text-align: left\">\n\n<p style=\"margin:0 0 0 0; padding:0\">\n&nbsp;\n<span style=\"display:none;font-weight:bold;color:#408\" id=\"record_indicator\">\nrecording. <span style=\"font-weight:normal\">time: <span id=\"record_time\"></span></span><span id=\"record_pause_indicator\"> paused</span>\n</span>\n</p>\n\n<div id=\"record_cursor_over\" style=\"margin:0;padding:2px;width:14em;height:1.1em;overflow:hidden;float:right;border:1px solid #777;background:#fff;font: normal normal 8pt sans-serif;position:relative;top:3px;color:#000;text-align:left;\">&nbsp;</div>\n<p style=\"margin:2px 0 0 0; padding:0\">\ncursor is over\n</p>\n\n<p style=\"margin:8px 0 0 0; padding:0;\">\n keyboard control: press\n <span id=\"record_ctrl_key\" style=\"border:1px solid #226;background:#adf;padding:0 0.5em\">ctrl</span> -\n <span id=\"record_shift_key\" style=\"border:1px solid #226;background:#adf;padding:0 0.5em\">shift</span> -\n</p>\n\n<p style=\"margin:4px 0 0 0; padding:0\">\n<span id=\"record_s\" style=\"border:1px solid #226;background:#adf;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em\">s</span>\n<span id=\"record_on\">to <b>start</b> recording</span>\n<span id=\"record_off\" style=\"display:none\">to <b>stop</b> recording</span>\n</p>\n\n<p style=\"margin:4px 0 0 0; padding:0\">\n<span id=\"record_h\" style=\"border:1px solid #226;background:#adf;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em\">h</span>\n<span>to <b>hide/show</b> this window</span>\n</p>\n\n<p style=\"margin:4px 0 0 0; padding:0\">\n<span id=\"record_m\" style=\"border:1px solid #226;background:#adf;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em\">m</span>\n<span id=\"record_include_mousemove\">to <b> record</b> mousemove</span>\n<span id=\"record_omit_mousemove\" style=\"display:none\">to <b>omit</b> mousemove</span>\n</p>\n\n<p style=\"margin:4px 0 0 0; padding:0\">\n<span id=\"record_p\" style=\"border:1px solid #226;background:#aaa;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em\">p</span>\n<span id=\"record_pause_on\">to <b> pause</b> recording</span>\n<span id=\"record_pause_off\" style=\"display:none\">to <b>continue</b> recording</span>\n</p>\n\n<p style=\"margin:4px 0 0 0; padding:0\">\n<span id=\"record_c\" style=\"border:1px solid #226;background:#aaa;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em\">c</span>\n<span>to add checkpoint</span>\n</p>\n\n<p style=\"margin:6px 0 0 0; padding:0\">\ncheckpoints:\n</p>\n<div id=\"record_checkpoints\" style=\"position:relative;width:100%;height:6em;overflow:auto;font: normal normal 8pt sans-serif; color:#000; text-align: left\">\n</div>\n</div>\n\n</span>\n</body></html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/data_Layer_Text_textfile.txt",
    "content": "point\timage\n10,20\thttp://boston.openguides.org/markers/ORANGE.png\n15,25\thttp://boston.openguides.org/markers/ORANGE.png\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/data_Layer_Text_textfile_2.txt",
    "content": "point\ttitle\tdescription\timage\n10,20\ta\tb\thttp://boston.openguides.org/markers/ORANGE.png\n15,25\tc\td\thttp://boston.openguides.org/markers/ORANGE.png\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/data_Layer_Text_textfile_overflow.txt",
    "content": "overflow\tpoint\ttitle\tdescription\timage\nauto\t10,20\ta\tb\thttp://boston.openguides.org/markers/ORANGE.png\nhidden\t15,25\tc\td\thttp://boston.openguides.org/markers/ORANGE.png\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/Ajax.html",
    "content": "<html>\n<head>\n  <script src=\"../OLLoader.js\"></script>\n  <script src=\"../../lib/deprecated.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_Ajax_loadUrl(t) {\n        t.plan(5);\n        var _get = OpenLayers.Request.GET;\n        var caller = {};\n        var onComplete = function() {};\n        var onFailure = function() {};\n        var params = {};\n        OpenLayers.Request.GET = function(config) {\n            t.eq(config.url, \"http://example.com/?format=image+kml\", \"correct url\")\n            t.eq(config.params, params, \"correct params\");\n            t.eq(config.scope, caller, \"correct scope\");\n            t.ok(config.success === onComplete, \"correct success callback\");\n            t.ok(config.failure === onFailure, \"correct failure callback\");\n        };\n        OpenLayers.loadURL(\"http://example.com/?format=image+kml\", params, caller, onComplete, onFailure);\n        OpenLayers.Request.GET = _get;\n    }\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/BaseTypes/Class.html",
    "content": "<html>\n<head>\n  <script src=\"../../OLLoader.js\"></script>\n  <script src=\"../../../lib/deprecated.js\"></script>\n  <script type=\"text/javascript\">\n    // remove this next line at 3.0\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    \n    // Remove this at 3.0\n    function test_Class_backwards(t) {\n        t.plan(4);\n        // test that a new style class supports old style inheritance\n        var NewClass = OpenLayers.Class({\n            newProp: \"new\",\n            initialize: function() {\n                t.ok(false, \"the base class is never instantiated\");\n            },\n            toString: function() {\n                return \"new style\";\n            }\n        });\n        \n        var OldClass = OpenLayers.Class.create();\n        OldClass.prototype = OpenLayers.Class.inherit(NewClass, {\n            oldProp: \"old\",\n            initialize: function() {\n                t.ok(true, \"only the child class constructor is called\");\n            }\n        });\n        \n        var oldObj = new OldClass();\n        t.eq(oldObj.oldProp, \"old\",\n             \"old style classes can still be instantiated\");\n        t.eq(oldObj.newProp, \"new\",\n             \"old style inheritance of properties works with new style base\");\n        t.eq(oldObj.toString(), \"new style\",\n             \"toString inheritance works with backwards style\");\n        \n    }\n\n    // Remove this at 3.0\n    function test_Class_create (t) {\n        t.plan( 3 );\n        var cls = OpenLayers.Class.create();\n        cls.prototype = {\n            initialize: function () {\n                if (isMozilla)\n                    t.ok(this instanceof cls,\n                                \"initialize is called on the right class\");\n                else\n                    t.ok(true, \"initialize is called\");\n            }\n        };\n        var obj = new cls();\n        t.eq(typeof obj, \"object\", \"obj is an object\");\n        if (isMozilla)\n            t.ok(obj instanceof cls,\n                        \"object is of the right class\");\n        else\n            t.ok(true, \"this test doesn't work in IE\");\n    }\n\n    // Remove this at 3.0\n    function test_Class_inherit (t) {\n        t.plan( 20 );\n        var A = OpenLayers.Class.create();\n        var initA = 0;\n        A.prototype = {\n            count: 0,\n            mixed: false,\n            initialize: function () {\n                initA++;\n                this.count++;\n            }\n        };\n\n        var B = OpenLayers.Class.create();\n        var initB = 0;\n        B.prototype = OpenLayers.Class.inherit( A, {\n            initialize: function () {\n                A.prototype.initialize.apply(this, arguments);\n                initB++;\n                this.count++;\n            }\n        });\n\n        var mixin = OpenLayers.Class.create()\n        mixin.prototype = {\n            mixed: true\n        };\n\n        t.eq( initA, 0, \"class A not inited\" );\n        t.eq( initB, 0, \"class B not inited\" );\n\n        var objA = new A();\n        t.eq( objA.count, 1, \"object A init\" );\n        t.eq( initA, 1, \"class A init\" );\n        if (isMozilla) \n            t.ok( objA instanceof A, \"obj A isa A\" );\n        else\n            t.ok( true, \"IE sucks\" );\n\n        var objB = new B();\n        t.eq( initA, 2, \"class A init\" );\n        t.eq( initB, 1, \"class B init\" );\n        t.eq( objB.count, 2, \"object B init twice\" );\n        if (isMozilla) {\n            t.ok( objB instanceof A, \"obj B isa A\" );\n            t.ok( objB instanceof B, \"obj B isa B\" );\n        } else {\n            t.ok( true, \"IE sucks\" );\n            t.ok( true, \"IE sucks\" );\n        }\n\n        var C = OpenLayers.Class.create();\n        C.prototype = OpenLayers.Class.inherit( B, mixin, {count: 0} );\n        t.eq( initA, 2, \"class A init unchanged\" );\n        t.eq( initB, 1, \"class B init unchanged\" );\n        \n        var objC = new C();\n        t.eq( initA, 3, \"class A init changed\" );\n        t.eq( initB, 2, \"class B init changed\" );\n        t.eq( objC.count, 2, \"object C init changed\" );\n        if (isMozilla) {\n            t.ok( objC instanceof A, \"obj C isa A\" );\n            t.ok( objC instanceof B, \"obj C isa B\" );\n            t.ok( objC instanceof C, \"obj C isa C\" );\n            t.ok( !(objC instanceof mixin), \"obj C isn'ta mixin\" );\n        } else {\n            t.ok( true, \"IE sucks\" );\n            t.ok( true, \"IE sucks\" );\n            t.ok( true, \"IE sucks\" );\n            t.ok( true, \"IE sucks\" );\n        }\n        t.eq( objC.mixed, true, \"class C has mixin properties\" );\n    }\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/BaseTypes/Element.html",
    "content": "<html>\n<head>\n    <script src=\"../../OLLoader.js\"></script>\n    <script src=\"../../../lib/deprecated.js\"></script>\n\n    <script type=\"text/javascript\">\n\n        function test_Element_hide(t) {\n            t.plan(2);\n\n            var elem1 = {\n                style: {\n                    'display': \"none\"\n                }\n            };\n        \n            var elem2 = {\n                style: {\n                    'display': \"\"\n                }\n            };\n\n            OpenLayers.Element.hide(elem1, elem2, \"do-not-exists\");\n        \n            t.eq(elem1.style.display, \"none\", \"hidden element stays hidden\");\n            t.eq(elem2.style.display, \"none\", \"shown element hidden\");\n        }\n    \n        function test_Element_show(t) {\n            t.plan(2);\n\n            var elem1 = {\n                style: {\n                    'display': \"none\"\n                }\n            };\n        \n            var elem2 = {\n                style: {\n                    'display': \"\"\n                }\n            };\n\n            OpenLayers.Element.show(elem1, \"do-not-exists\", elem2);\n        \n            t.eq(elem1.style.display, \"\", \"hidden element shown\");\n            t.eq(elem2.style.display, \"\", \"shown element stays shown\");\n        }\n\n    </script>\n</head>\n<body>\n    <div id=\"elemID\" style=\"width:50px; height:100px; background-color:red\">test</div>\n</body>\n</html>\n        "
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/Control/MouseToolbar.html",
    "content": "<html>\n<head>\n  <script src=\"../../OLLoader.js\"></script>\n  <script src=\"../../../lib/deprecated.js\"></script>\n  <script type=\"text/javascript\">\n    var map; \n    function test_Control_MouseToolbar_constructor (t) {\n        t.plan( 1 );\n    \n        control = new OpenLayers.Control.MouseToolbar();\n        t.ok( control instanceof OpenLayers.Control.MouseToolbar, \"new OpenLayers.Control.MouseToolbar returns object\" );\n    }\n    function test_Control_MouseToolbar_addControl (t) {\n        t.plan( 8 );\n        map = new OpenLayers.Map('map');\n        control = new OpenLayers.Control.MouseToolbar();\n        t.ok( control instanceof OpenLayers.Control.MouseToolbar, \"new OpenLayers.Control.MouseToolbar returns object\" );\n        t.ok( map instanceof OpenLayers.Map, \"new OpenLayers.Map creates map\" );\n        map.addControl(control);\n        t.ok( control.map === map, \"Control.map is set to the map object\" );\n        t.ok( map.controls[4] === control, \"map.controls contains control\" );\n        t.eq( parseInt(control.div.style.zIndex), map.Z_INDEX_BASE['Control'] + 5, \"Control div zIndexed properly\" );\n        t.eq( parseInt(map.viewPortDiv.lastChild.style.zIndex), map.Z_INDEX_BASE['Control'] + 5, \"Viewport div contains control div\" );\n        t.eq( control.div.style.left, \"6px\", \"Control div left located correctly by default\");\n        t.eq( control.div.style.top, \"300px\", \"Control div top located correctly by default\");\n\n    }\n    function test_Control_MouseToolbar_control_events (t) {\n        t.plan( 1 );\n        if ((navigator.userAgent.indexOf(\"compatible\") == -1)) { \n            var evt = {which: 1}; // control expects left-click\n            map = new OpenLayers.Map('map');\n            var layer = new OpenLayers.Layer.WMS(\"Test Layer\", \n                \"http://octo.metacarta.com/cgi-bin/mapserv?\",\n                {map: \"/mapdata/vmap_wms.map\", layers: \"basic\"});\n            map.addLayer(layer);\n\n            control = new OpenLayers.Control.MouseToolbar();\n            map.addControl(control);\n\n            var centerLL = new OpenLayers.LonLat(0,0); \n            map.setCenter(centerLL, 5);\n\n            evt.shiftKey = true;\n            evt.xy = new OpenLayers.Size(5,5);\n            control.defaultMouseDown(evt);\n            evt.xy = new OpenLayers.Size(15,15);\n            control.defaultMouseUp(evt);\n            t.eq(map.getZoom(), 6, \"Map zoom set correctly after zoombox\");\n        } else {\n            t.ok(true, \"IE does not run this test.\") \n        }\n    }\n\n  </script>\n</head>\n<body>\n    <div id=\"map\" style=\"width: 1024px; height: 512px;\"/>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/Geometry/Rectangle.html",
    "content": "<html>\n<head>\n  <script src=\"../../OLLoader.js\"></script>\n  <script src=\"../../../lib/deprecated.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_Rectangle_constructor (t) {\n        t.plan( 8 );\n\n      //empty\n        var rect = new OpenLayers.Geometry.Rectangle();\n        t.ok( rect instanceof OpenLayers.Geometry.Rectangle, \"new OpenLayers.Geometry.Rectangle returns Rectangle object\" );\n        t.eq( rect.CLASS_NAME, \"OpenLayers.Geometry.Rectangle\", \"Rectangle.CLASS_NAME is set correctly\");\n        t.ok( rect.id != null, \"rect.id is set\");\n        t.ok( ! (rect.x || rect.y || rect.width || rect.height), \"empty construct leaves properties empty\");\n        \n      //good\n        var x = {};\n        var y = {};\n        var w = {};\n        var h = {};\n        var rect = new OpenLayers.Geometry.Rectangle(x, y, w, h);\n        t.eq( rect.x, x, \"good init correctly sets x property\"); \n        t.eq( rect.y, y, \"good init correctly sets y property\"); \n        t.eq( rect.width, w, \"good init correctly sets width property\"); \n        t.eq( rect.height, h, \"good init correctly sets height property\"); \n    }\n\n    function test_Rectangle_calculateBounds(t) {\n        t.plan(1);\n        \n        var x = 1;\n        var y = 2;\n        var w = 10;\n        var h = 20;\n        var rect = new OpenLayers.Geometry.Rectangle(x, y, w, h);\n        rect.calculateBounds();\n\n        var testBounds = new OpenLayers.Bounds(x, y, x + w, y + h)\n        \n        t.ok( rect.bounds.equals(testBounds), \"calculateBounds works correctly\"); \n    }\n\n    function test_Rectangle_getLength(t) {\n        t.plan(1);\n\n        var x = 1;\n        var y = 2;\n        var w = 10;\n        var h = 20;\n        var rect = new OpenLayers.Geometry.Rectangle(x, y, w, h);\n\n        var testLength = (2 * w) + (2 * h);\n\n        t.eq(rect.getLength(), testLength, \"getLength() works\");\n    }\n\n    function test_Rectangle_getArea(t) {\n        t.plan(1);\n\n        var x = 1;\n        var y = 2;\n        var w = 10;\n        var h = 20;\n        var rect = new OpenLayers.Geometry.Rectangle(x, y, w, h);\n\n        var testArea = w * h;\n        t.eq(rect.getArea(), testArea, \"testArea() works\");\n    }\n\n\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/Layer/GML.html",
    "content": "<html>\n<head>\n  <script src=\"../../OLLoader.js\"></script>\n  <script src=\"../../../lib/deprecated.js\"></script>\n  <script type=\"text/javascript\">\n\n    var name = \"GML Layer\";\n    \n    var gml = \"./owls.xml\";\n    var gml2 = \"./mice.xml\";\n\n    // if this test is running online, different rules apply\n    var isMSIE = (navigator.userAgent.indexOf(\"MSIE\") > -1);\n    if (isMSIE) {\n        gml = \".\" + gml;\n        gml2 = \".\" + gml2;\n    }\n    \n    function test_Layer_GML_constructor(t) {\n        t.plan(3);\n\n        var layer = new OpenLayers.Layer.GML(name);\n        t.ok(layer instanceof OpenLayers.Layer.GML, \"new OpenLayers.Layer.GML returns correct object\" );\n        t.eq(layer.name, name, \"layer name is correctly set\");\n        t.ok(layer.renderer.CLASS_NAME, \"layer has a renderer\");\n\n    }\n    function test_Layer_GML_events(t) {\n        t.plan(3);\n\n        var layer = new OpenLayers.Layer.GML(name, gml, {isBaseLayer: true});\n        layer.events.register(\"loadstart\", layer, function() { \n            t.ok(true, \"loadstart called.\")\n        });\n        layer.events.register(\"loadend\", layer, function() { \n            t.ok(true, \"loadend called.\")\n        });\n        var map = new OpenLayers.Map(\"map\");\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        t.delay_call(3, function() { \n            t.ok(true, \"waited for 3s\"); \n        });\n\n    }\n    function test_GML_setUrl(t) {\n        t.plan(2);\n        var layer = new OpenLayers.Layer.GML(name, gml);\n        var map = new OpenLayers.Map(\"map\");\n        map.addLayer(layer);\n        t.eq(layer.url, gml, \"layer has correct original url\");\n        layer.setUrl(gml2);\n        t.eq(layer.url, gml2, \"layer has correctly changed url\");\n    }\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/Layer/MapServer/Untiled.html",
    "content": "<html>\n<head>    \n\n    <script src=\"../../../OLLoader.js\"></script>\n    <script src=\"../../../../lib/deprecated.js\"></script>\n    <script type=\"text/javascript\">\n\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var layer; \n\n    var name = 'Test Layer';\n    var url = \"http://labs.metacarta.com/cgi-bin/mapserv\";\n    var params = { map: '/mapdata/vmap_wms.map', \n                   layers: 'basic'};\n    \n    function test_Layer_MapServer_Untiled_constructor (t) {\n        t.plan( 4 );\n\n        var url = \"http://labs.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.MapServer.Untiled(name, url, params);\n        t.ok( layer instanceof OpenLayers.Layer.MapServer.Untiled, \"new OpenLayers.Layer.MapServer returns object\" );\n        t.eq( layer.url, \"http://labs.metacarta.com/cgi-bin/mapserv\", \"layer.url is correct (HTTPRequest inited)\" );\n\n        t.eq( layer.params.mode, \"map\", \"default mode param correctly copied\");\n        t.eq( layer.params.map_imagetype, \"png\", \"default imagetype correctly copied\");\n\n\n    }\n    \n    function test_Layer_MapServer_Untiled_clone (t) {\n        t.plan(3);\n        \n        var url = \"http://labs.metacarta.com/cgi-bin/mapserv\";\n        var map = new OpenLayers.Map('map', {});\n        layer = new OpenLayers.Layer.MapServer.Untiled(name, url, params);\n        map.addLayer(layer);\n\n        var clone = layer.clone();\n        layer.tile = [[1,2],[3,4]];\n        \n        t.ok( clone.tile != layer.tile, \"clone does not copy tile\");\n\n        layer.ratio += 1;\n\n        t.eq( clone.ratio, 1.5, \"changing layer.ratio does not change clone.ratio -- a fresh copy was made, not just copied reference\");\n\n        t.eq( clone.alpha, layer.alpha, \"alpha copied correctly\");\n\n        layer.tile = null;\n        map.destroy();\n    }\n\n    function test_Layer_MapServer_Untiled_isBaseLayer(t) {\n        t.plan(3);\n        \n        var url = \"http://labs.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.MapServer.Untiled(name, url, params);\n        t.ok( layer.isBaseLayer, \"baselayer is true by default\");\n\n        var newParams = OpenLayers.Util.extend({}, params);\n        newParams.transparent = \"true\";\n        layer = new OpenLayers.Layer.MapServer.Untiled(name, url, newParams);\n        t.ok( !layer.isBaseLayer, \"baselayer is false when transparent is set to true\");\n\n        layer = new OpenLayers.Layer.MapServer.Untiled(name, url, params, {isBaseLayer: false});\n        t.ok( !layer.isBaseLayer, \"baselayer is false when option is set to false\" );\n    }\n\n    function test_Layer_MapServer_Untiled_mergeNewParams (t) {\n        t.plan( 5 );\n\n        var map = new OpenLayers.Map(\"map\", {tileManager: null});\n        var url = \"http://labs.metacarta.com/cgi-bin/mapserv\";\n        layer = new OpenLayers.Layer.MapServer.Untiled(name, url, params);\n        \n        var newParams = { layers: 'sooper', \n                          chickpeas: 'image/png'};\n\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        t.ok( !layer.grid[0][0].url.match(\"chickpeas\"), \"chickpeas is not in URL of first tile in grid\" );\n\n        layer.mergeNewParams(newParams);\n        \n        t.eq( layer.params.layers, \"sooper\", \"mergeNewParams() overwrites well\");\n        t.eq( layer.params.chickpeas, \"image/png\", \"mergeNewParams() adds well\");\n        t.ok( layer.grid[0][0].url.match(\"chickpeas\"), \"chickpeas is in URL of first tile in grid\" );\n\n        newParams.chickpeas = 151;\n\n        t.eq( layer.params.chickpeas, \"image/png\", \"mergeNewParams() makes clean copy of hashtable\");\n        map.destroy();\n    }\n\n    function test_Layer_MapServer_Untiled_getFullRequestString (t) {\n\n        \n        t.plan( 1 );\n        var map = new OpenLayers.Map('map');\n        tUrl = \"http://labs.metacarta.com/cgi-bin/mapserv\";\n        tParams = { layers: 'basic', \n                    format: 'png'};\n        var tLayer = new OpenLayers.Layer.MapServer.Untiled(name, tUrl, tParams);\n        map.addLayer(tLayer);\n        str = tLayer.getFullRequestString();\n        var tParams = {\n             layers: 'basic', \n             format: 'png',\n             mode: 'map',\n             map_imagetype: 'png'\n        };\n\n        var sStr = tUrl + \"?\" + OpenLayers.Util.getParameterString(tParams);\n        sStr = sStr.replace(/,/g, \"+\");\n        \n        t.eq(str, sStr , \"getFullRequestString() works\");\n        map.destroy();\n\n    }\n\n    // DEPRECATED -- REMOVE IN 3.0\n    function test_Layer_Untiled_MapServer(t) { \n        t.plan(1);\n        \n        var layer = new OpenLayers.Layer.MapServer.Untiled();\n        \n        var clone = layer.clone();\n        \n        t.ok(clone.singleTile, \"regression test: clone works. this is for #1013\");\n    }\n    \n    function test_Layer_MapServer_Untiled_destroy (t) {\n\n        t.plan( 1 );\n\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.MapServer.Untiled(name, url, params);\n        map.addLayer(layer);\n\n        map.setCenter(new OpenLayers.LonLat(0,0), 5);\n\n        //grab a reference to one of the tiles\n        var tile = layer.tile;        \n\n        layer.destroy();\n        \n    // checks to make sure superclass (grid) destroy() was called    \n        \n        t.ok( layer.tile == null, \"tile set to null\");\n        map.destroy();\n    }\n    \n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/Layer/MapServer.html",
    "content": "<html>\n<head>\n<script src=\"http://maps.google.com/maps/api/js?v=3&amp;sensor=false\"></script>\n\n<script src=\"../../OLLoader.js\"></script>\n<script src=\"../../../lib/deprecated.js\"></script>\n<script type=\"text/javascript\">\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var layer; \n\n    var name = 'Test Layer';\n    var url = \"http://labs.metacarta.com/cgi-bin/mapserv\";\n    var params = { map: '/mapdata/vmap_wms.map', \n                   layers: 'basic'};\n\n    function test_Layer_MapServer_Reproject (t) { \n        var validkey = (window.location.protocol == \"file:\") ||\n                       (window.location.host == \"localhost\") ||\n                       (window.location.host == \"openlayers.org\");\n\n        if (OpenLayers.BROWSER_NAME == \"opera\" || OpenLayers.BROWSER_NAME == \"safari\") {\n            t.plan(1);\n            t.debug_print(\"Can't test google reprojection in Opera or Safari.\");\n        } else if(validkey) {\n            t.plan(5);\n            var map = new OpenLayers.Map('map', {tileManager: null});\n            var layer = new OpenLayers.Layer.Google(\"Google\");\n            map.addLayer(layer);\n            layer = new OpenLayers.Layer.MapServer(name, url, params, {reproject: true, isBaseLayer: false, buffer: 2});\n            layer.isBaseLayer=false;\n            map.addLayer(layer);\n            map.setCenter(new OpenLayers.LonLat(0,0), 5);\n            var tile = layer.grid[0][0];\n            t.eq( tile.bounds.left, -22.5, \"left side matches\" );\n            t.eq( tile.bounds.right, -11.25, \"right side matches\" );\n            t.eq( tile.bounds.bottom.toFixed(6), '11.781325', \"bottom side matches\" );\n            t.eq( tile.bounds.top.toFixed(6), '22.512557', \"top side matches\" );\n            map.destroy();\n        } else {\n            t.plan(1);\n            t.debug_print(\"can't test google layer from \" +\n                          window.location.host);\n        }\n\n        var map = new OpenLayers.Map('map', {tileManager: null});\n        layer = new OpenLayers.Layer.MapServer(name, url, params, {buffer:2});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 5);\n        var tile = layer.grid[0][0];\n        t.ok( tile.bounds.equals(new OpenLayers.Bounds(-33.75, 33.75, -22.5, 45)), \"okay\");\n        map.destroy();\n    }\n    \n</script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/Layer/WFS.html",
    "content": "<html>\n<head>\n  <script src=\"../../OLLoader.js\"></script>\n  <script src=\"../../../lib/deprecated.js\"></script>\n  <script type=\"text/javascript\">\n\n    var name = \"Vector Layer\";\n    \n    function test_Layer_WFS_constructor(t) {\n        t.plan(3);\n\n        var layer = new OpenLayers.Layer.WFS(name, \"url\", {});\n        t.ok(layer instanceof OpenLayers.Layer.WFS, \"new OpenLayers.Layer.Vector returns correct object\" );\n        t.eq(layer.name, name, \"layer name is correctly set\");\n        t.ok(layer.renderer.CLASS_NAME, \"layer has a renderer\");\n\n    }\n    \n    function test_Layer_WFS_getDataExtent(t) {\n        t.plan(1);\n\n        var layer = new OpenLayers.Layer.WFS(name, \"url\", {});\n        layer.addFeatures(new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0, 0)));\n        layer.addFeatures(new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(0, 1)));\n        t.eq(layer.getDataExtent().toBBOX(), \"0,0,0,1\", \"bbox is correctly pulled from vectors.\");\n\n    }\n    \n    function test_Layer_WFS_setOpacity(t) {\n        t.plan(3);\n\n        var layer = new OpenLayers.Layer.WFS(name, \"url\", {});\n        layer.setOpacity(.5);\n        t.eq(layer.opacity, 0.5, \"vector setOpacity didn't fail\");\n        var layer = new OpenLayers.Layer.WFS(name, \"url\", {}, {'featureClass': OpenLayers.Feature.WFS});\n        var marker = new OpenLayers.Marker(new OpenLayers.LonLat(0,0));\n        marker.setOpacity = function() {\n            t.ok(true, \"Marker setOpacity was called\");\n        }    \n        layer.addMarker(marker);\n        layer.setOpacity(.6);\n        t.eq(layer.opacity, 0.6, \"setOpacity didn't fail on markers\");\n    }\n    \n    function test_Layer_WFS_destroy(t) {\n        t.plan(13);\n        \n        var tVectorDestroy = OpenLayers.Layer.Vector.prototype.destroy;\n        OpenLayers.Layer.Vector.prototype.destroy = function() {\n            g_VectorDestroyed = true;\n        }\n\n        var tMarkersDestroy = OpenLayers.Layer.Markers.prototype.destroy;\n        OpenLayers.Layer.Markers.prototype.destroy = function() {\n            g_MarkersDestroyed = true;\n        }\n\n        var layer = {\n            'vectorMode': true,\n            'tile': {\n                'destroy': function() {\n                    t.ok(true, \"wfs layer's tile is destroyed\");\n                }\n            },\n            'ratio': {},\n            'featureClass': {},\n            'format': {},\n            'formatObject': {\n                'destroy': function() {\n                    t.ok(true, \"wfs layer's format object is destroyed\");\n                }\n            },\n            'formatOptions': {},\n            'encodeBBOX': {},\n            'extractAttributes': {}\n        };\n        \n        //this call should set off two tests (destroys for tile and format object)\n        g_VectorDestroyed = null;\n        g_MarkersDestroyed = null;        \n        OpenLayers.Layer.WFS.prototype.destroy.apply(layer, []);        \n\n        t.ok(g_VectorDestroyed && !g_MarkersDestroyed, \"when vector mode is set to true, the default vector layer's destroy() method is called\");\n        t.eq(layer.vectorMode, null, \"'vectorMode' property nullified\");\n        t.eq(layer.tile, null, \"'tile' property nullified\");\n        t.eq(layer.ratio, null, \"'ratio' property nullified\");\n        t.eq(layer.featureClass, null, \"'featureClass' property nullified\");\n        t.eq(layer.format, null, \"'format' property nullified\");\n        t.eq(layer.formatObject, null, \"'formatObject' property nullified\");\n        t.eq(layer.formatOptions, null, \"'formatOptions' property nullified\");\n        t.eq(layer.encodeBBOX, null, \"'encodeBBOX' property nullified\");\n        t.eq(layer.extractAttributes, null, \"'extractAttributes' property nullified\");\n\n        layer.vectorMode = false;\n\n        //this call will *not* set off two tests (tile and format object are null)\n        g_VectorDestroyed = null;\n        g_MarkersDestroyed = null;        \n        OpenLayers.Layer.WFS.prototype.destroy.apply(layer, []);        \n        t.ok(!g_VectorDestroyed && g_MarkersDestroyed, \"when vector mode is set to false, the default markers layer's destroy() method is called\");\n        \n        OpenLayers.Layer.Vector.prototype.destroy = tVectorDestroy;\n        OpenLayers.Layer.Markers.prototype.destroy = tMarkersDestroy;\n    }\n    \n    function test_Layer_WFS_mapresizevector(t) {\n        t.plan(2);\n\n        var map = new OpenLayers.Map(\"map\");\n        map.addLayer(new OpenLayers.Layer.WMS(\"WMS\", \"url\", {}));\n        var layer = new OpenLayers.Layer.WFS(name, \"url\", {});\n        t.ok(layer.renderer.CLASS_NAME, \"layer has a renderer\");\n        map.addLayer(layer);\n        setSize = false;\n        layer.renderer.setSize = function() { setSize = true; }\n        layer.onMapResize();\n        t.eq(setSize, true, \"Renderer resize called on map size change.\");\n        map.destroy();     \n\n    }\n    function test_Layer_WFS_drawmap(t) {\n        t.plan(2);\n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS( \"OpenLayers WMS\", \n            \"http://labs.metacarta.com/wms/vmap0\", {layers: 'basic'} );\n        map.addLayer(layer);\n\n        layer = new OpenLayers.Layer.WFS( \"Owl Survey\",\n            \"http://www.bsc-eoc.org/cgi-bin/bsc_ows.asp?\",\n            {typename: \"OWLS\", maxfeatures: 10},\n            { featureClass: OpenLayers.Feature.WFS});\n        map.addLayer(layer);\n        map.addControl(new OpenLayers.Control.LayerSwitcher());\n        try { \n            map.setCenter(new OpenLayers.LonLat(-100, 60), 3);\n        } catch (Exception) {\n        }    \n        t.eq(layer.tile.url, \"http://www.bsc-eoc.org/cgi-bin/bsc_ows.asp?TYPENAME=OWLS&MAXFEATURES=10&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&SRS=EPSG%3A4326&BBOX=-187.890625,-36.6796875,-12.109375,156.6796875\", \"Tile URL is set correctly when not encoded\");\n        map.destroy();     \n        var map = new OpenLayers.Map('map');\n        layer = new OpenLayers.Layer.WMS( \"OpenLayers WMS\", \n            \"http://labs.metacarta.com/wms/vmap0\", {layers: 'basic'}\n            );\n        map.addLayer(layer);\n\n        layer = new OpenLayers.Layer.WFS( \"Owl Survey\",\n            \"http://www.bsc-eoc.org/cgi-bin/bsc_ows.asp?\",\n            {typename: \"OWLS\", maxfeatures: 10},\n            { featureClass: OpenLayers.Feature.WFS, 'encodeBBOX': true});\n        map.addLayer(layer);\n        map.addControl(new OpenLayers.Control.LayerSwitcher());\n        try { \n            map.setCenter(new OpenLayers.LonLat(-100, 60), 3);\n        } catch (Exception) {\n        }  \n        t.eq(layer.tile.url, \"http://www.bsc-eoc.org/cgi-bin/bsc_ows.asp?TYPENAME=OWLS&MAXFEATURES=10&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&SRS=EPSG%3A4326&BBOX=-187.890625%2C-36.679687%2C-12.109375%2C156.679688\", \"Tile URL is set correctly when not encoded\");\n        map.destroy();     \n    }\n    function test_projection_srs(t) {\n        t.plan(1);\n        var map = new OpenLayers.Map('map');\n        map.addLayer(new OpenLayers.Layer(\"\",{isBaseLayer: true} ));\n        // we use an empty moveTo function because we don't want to request tiles\n        var layer = new OpenLayers.Layer.WFS(\"\",\"/wfs\",{},{'projection': new OpenLayers.Projection(\"EPSG:900913\"),\n            moveTo: function() {}});\n        map.addLayer(layer);\n        map.zoomToMaxExtent();\n        var params = OpenLayers.Util.getParameters(layer.getFullRequestString());\n        t.eq(params.SRS, \"EPSG:900913\", \"SRS represents projection of WFS layer, instead of map (#1537)\");   \n    }\n\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/Layer/WMS/Post.html",
    "content": "<html>\n<head>\n    <script src=\"../../../OLLoader.js\"></script>\n    <script src=\"../../../../lib/deprecated.js\"></script>\n    <script type=\"text/javascript\">\n    var isMozilla = (navigator.userAgent.indexOf(\"compatible\") == -1);\n    var isOpera   = (navigator.userAgent.indexOf(\"Opera\") != -1);\n    var layer;\n\n    var name = 'Test Layer';\n    var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n    var params = { map: '/mapdata/vmap_wms.map', \n                   layers: 'basic', \n                   format: 'image/jpeg'};\n\n    function test_Layer_WMS_Post_constructor (t) {\n        t.plan( 2 );\n\n        var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n        var options = {unsupportedBrowsers: []};\n        layer = new OpenLayers.Layer.WMS.Post(name, url, params, options);\n\n        t.eq(\n            layer.usePost, true,\n            \"Supported browsers use IFrame tiles.\");\n\n        layer.destroy();\n\n        var options = { unsupportedBrowsers: [OpenLayers.BROWSER_NAME]};\n        layer = new OpenLayers.Layer.WMS.Post(name, url, params, options);\n        t.eq(\n            layer.usePost, false,\n            \"unsupported browsers use Image tiles.\");\n        layer.destroy();\n    }\n\n    function test_Layer_WMS_Post_addtile (t) {\n        t.plan( 3 );\n    \n        layer = new OpenLayers.Layer.WMS.Post(name, url, params);\n        var map = new OpenLayers.Map('map');\n        map.addLayer(layer);\n        var bounds = new OpenLayers.Bounds(1,2,3,4);\n        var pixel  = new OpenLayers.Pixel(5,6);\n        var tile   = layer.addTile(bounds, pixel);\n        \n        if(isMozilla || isOpera) {\n            t.ok(\n                tile instanceof OpenLayers.Tile.Image,\n                \"tile is an instance of OpenLayers.Tile.Image\");\n        }\n        else {\n            t.ok(\n                tile.useIFrame !== undefined,\n                \"tile is created with the OpenLayers.Tile.Image.IFrame mixin\");\n        }\n        map.destroy();\n\n        // test the unsupported browser\n        layer = new OpenLayers.Layer.WMS.Post(name, url, params, {\n            unsupportedBrowsers: [OpenLayers.BROWSER_NAME]\n        });\n        map   = new OpenLayers.Map('map');\n        map.addLayer(layer);\n        tile  = layer.addTile(bounds, pixel);\n        t.ok(\n            tile instanceof OpenLayers.Tile.Image,\n            \"unsupported browser: tile is an instance of Tile.Image\");\n        layer.destroy();\n\n        // test a supported browser\n        layer = new OpenLayers.Layer.WMS.Post(name, url, params, {\n            unsupportedBrowsers: []\n        });\n        map.addLayer(layer);\n        var tile2 = layer.addTile(bounds, pixel);\n        tile2.draw();\n        t.eq(\n            tile2.useIFrame, true,\n            \"supported browser: tile is created with the Tile.Image.IFrame mixin\");\n        map.destroy();\n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/Layer/WMS.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <script src=\"http://maps.google.com/maps/api/js?v=3&amp;sensor=false\"></script>\n    <script src=\"../../OLLoader.js\"></script>\n    <script src=\"../../../lib/deprecated.js\"></script>\n    <script type=\"text/javascript\">\n    \n    var name = 'Test Layer';\n    var url = \"http://octo.metacarta.com/cgi-bin/mapserv\";\n    var params = { map: '/mapdata/vmap_wms.map',\n                   layers: 'basic',\n                   format: 'image/jpeg'};\n\n    function test_Layer_WMS_Reproject (t) {\n        var validkey = (window.location.protocol == \"file:\") ||\n                       (window.location.host == \"localhost\") ||\n                       (window.location.host == \"openlayers.org\");\n        if (OpenLayers.BROWSER_NAME == \"opera\" || OpenLayers.BROWSER_NAME == \"safari\") {\n            t.plan(1);\n            t.debug_print(\"Can't test google reprojection in Opera or Safari.\");\n        } else if(validkey) {\n            t.plan(5);\n\n            var map = new OpenLayers.Map('map', {tileManager: null});\n            var layer = new OpenLayers.Layer.Google(\"Google\");\n            map.addLayer(layer);\n            var wmslayer = new OpenLayers.Layer.WMS(name, url, params,\n                                                    {isBaseLayer: false, reproject:true, buffer: 2});\n            wmslayer.isBaseLayer=false;\n            map.addLayer(wmslayer);\n            map.setCenter(new OpenLayers.LonLat(0,0), 5);\n            var tile = wmslayer.grid[0][0];\n            t.eq( tile.bounds.left, -22.5, \"left side matches\" );\n            t.eq( tile.bounds.right, -11.25, \"right side matches\" );\n            t.eq( tile.bounds.bottom.toFixed(6), '11.781325', \"bottom side matches\" );\n            t.eq( tile.bounds.top.toFixed(6), '22.512557', \"top side matches\" );\n            map.destroy();\n        } else {\n            t.plan(1);\n            t.debug_print(\"can't test google layer from \" +\n                          window.location.host);\n        }\n\n        var map = new OpenLayers.Map('map', {tileManager: null});\n        layer = new OpenLayers.Layer.WMS(name, url, params, {buffer: 2});\n        map.addLayer(layer);\n        map.setCenter(new OpenLayers.LonLat(0,0), 5);\n        var tile = layer.grid[0][0];\n        t.ok( tile.bounds.equals(new OpenLayers.Bounds(-33.75, 33.75, -22.5, 45)), \"okay\");\n\n        map.destroy();\n    }\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/Layer/Yahoo.html",
    "content": "<html>\n<head>\n  <script src=\"http://api.maps.yahoo.com/ajaxymap?v=3.0&appid=euzuro-openlayers\"></script>\n  <script src=\"../../OLLoader.js\"></script>\n  <script src=\"../../../lib/deprecated.js\"></script>\n  <script type=\"text/javascript\">\n    var layer; \n\n    function test_Layer_Yahoo_constructor (t) {\n        t.plan( 4 );\n\n        var tempEventPane = OpenLayers.Layer.EventPane.prototype.initialize;\n        OpenLayers.Layer.EventPane.prototype.initialize = function(name, options) {\n            t.ok(name == g_Name, \"EventPane initialize() called with correct name\");\n            t.ok(options == g_Options, \"EventPane initialize() called with correct options\");\n        }\n\n        var tempFixedZoomLevels = OpenLayers.Layer.FixedZoomLevels.prototype.initialize;\n        OpenLayers.Layer.FixedZoomLevels.prototype.initialize = function(name, options) {\n            t.ok(name == g_Name, \"FixedZoomLevels initialize() called with correct name\");\n            t.ok(options == g_Options, \"FixedZoomLevels initialize() called with correct options\");\n        }\n\n\n        g_Name = {};\n        g_Options = {};        \n        var l = new OpenLayers.Layer.Yahoo(g_Name, g_Options);\n\n        OpenLayers.Layer.EventPane.prototype.initialize = tempEventPane;\n        OpenLayers.Layer.FixedZoomLevels.prototype.initialize = tempFixedZoomLevels;\n    }\n\n    function test_Layer_Yahoo_loadMapObject(t) {\n        t.plan(5);\n        \n        var temp = YMap;\n        YMap = OpenLayers.Class({\n            initialize: function(div, type, size) {\n                t.ok(div == g_Div, \"correct div passed to YMap constructor\");\n                t.ok(type == g_Type, \"correct type passed to YMap constructor\");\n                t.ok(size == g_YMapSize, \"correct size passed to YMap constructor\");\n            },\n            disableKeyControls: function() {\n                t.ok(true, \"disableKeyControls called on map object\");\n            }\n        });\n        \n        g_Div = {};\n        g_Type = {};\n        g_MapSize = {};\n        g_YMapSize = {};\n        \n        var l = new OpenLayers.Layer.Yahoo();\n        l.div = g_Div;\n        l.type = g_Type;\n        l.map = {\n            'getSize': function() {\n                return g_MapSize;\n            }\n        };\n        l.getMapObjectSizeFromOLSize = function(mapSize) {\n            t.ok(mapSize == g_MapSize, \"correctly translating map size from ol to YSize\");\n            return g_YMapSize;\n        };\n\n        l.loadMapObject();\n\n        YMap = temp;\n    }    \n\n    function test_Layer_Yahoo_onMapResize(t) {\n        t.plan(2);\n        \n        g_MapSize = {};\n        g_YMapSize = {};\n        \n        var l = new OpenLayers.Layer.Yahoo();\n        l.mapObject = {\n            'resizeTo': function(size) {\n                t.ok(size == g_YMapSize, \"correct YSize passed to reiszeTo on map object\");\n            }\n        }\n        l.map = {\n            'getSize': function() {\n                return g_MapSize;\n            }\n        };\n        l.getMapObjectSizeFromOLSize = function(mapSize) {\n            t.ok(mapSize == g_MapSize, \"correctly translating map size from ol to YSize\");\n            return g_YMapSize;\n        };\n\n        l.onMapResize();\n    }\n    \n    function test_Layer_Yahoo_getMapObjectSizeFromOLSize(t) {\n        t.plan(2);\n        \n        var temp = YSize;\n        YSize = function(w, h) {\n            t.ok(w == g_Size.w, \"correct width passed to YSize constructor\");\n            t.ok(h == g_Size.h, \"correct height passed to YSize constructor\");\n        }\n        \n        g_Size = {\n            'w': {},\n            'h': {}\n        };\n        \n        OpenLayers.Layer.Yahoo.prototype.getMapObjectSizeFromOLSize(g_Size);\n\n        YSize = temp;\n    }\n\n\n  </script>\n</head>\n<body>\n  <div id=\"map\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/Layer/mice.xml",
    "content": "<?xml version='1.0' encoding=\"ISO-8859-1\" ?>\n<wfs:FeatureCollection\n   xmlns:bsc=\"http://www.bsc-eoc.org/bsc\"\n   xmlns:wfs=\"http://www.opengis.net/wfs\"\n   xmlns:gml=\"http://www.opengis.net/gml\"\n   xmlns:ogc=\"http://www.opengis.net/ogc\"\n   xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n   xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengeospatial.net//wfs/1.0.0/WFS-basic.xsd \n                       http://www.bsc-eoc.org/bsc http://www.bsc-eoc.org/cgi-bin/bsc_ows.asp?SERVICE=WFS&amp;VERSION=1.0.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=OWLS&amp;OUTPUTFORMAT=XMLSCHEMA\">\n      <gml:boundedBy>\n      \t<gml:Box srsName=\"EPSG:4326\">\n      \t\t<gml:coordinates>-89.817223,45.005555 -74.755001,51.701388</gml:coordinates>\n      \t</gml:Box>\n      </gml:boundedBy>\n    <gml:featureMember><bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-79.771668,45.891110 -79.771668,45.891110</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-79.771668,45.891110</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.755834,46.365277 -83.755834,46.365277</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:owlname>owl</bsc:owlname>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.755834,46.365277</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.808612,46.175277 -83.808612,46.175277</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.808612,46.175277</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-84.111112,46.309166 -84.111112,46.309166</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-84.111112,46.309166</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.678612,46.821110 -83.678612,46.821110</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.678612,46.821110</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.664445,46.518888 -83.664445,46.518888</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.664445,46.518888</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-80.613334,46.730277 -80.613334,46.730277</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-80.613334,46.730277</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-79.676946,45.428054 -79.676946,45.428054</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-79.676946,45.428054</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.853056,46.236944 -83.853056,46.236944</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.853056,46.236944</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-82.289167,45.896388 -82.289167,45.896388</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-82.289167,45.896388</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n</wfs:FeatureCollection>\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/Layer/owls.xml",
    "content": "<?xml version='1.0' encoding=\"ISO-8859-1\" ?>\n<wfs:FeatureCollection\n   xmlns:bsc=\"http://www.bsc-eoc.org/bsc\"\n   xmlns:wfs=\"http://www.opengis.net/wfs\"\n   xmlns:gml=\"http://www.opengis.net/gml\"\n   xmlns:ogc=\"http://www.opengis.net/ogc\"\n   xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n   xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengeospatial.net//wfs/1.0.0/WFS-basic.xsd \n                       http://www.bsc-eoc.org/bsc http://www.bsc-eoc.org/cgi-bin/bsc_ows.asp?SERVICE=WFS&amp;VERSION=1.0.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=OWLS&amp;OUTPUTFORMAT=XMLSCHEMA\">\n      <gml:boundedBy>\n      \t<gml:Box srsName=\"EPSG:4326\">\n      \t\t<gml:coordinates>-89.817223,45.005555 -74.755001,51.701388</gml:coordinates>\n      \t</gml:Box>\n      </gml:boundedBy>\n    <gml:featureMember><bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-79.771668,45.891110 -79.771668,45.891110</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-79.771668,45.891110</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.755834,46.365277 -83.755834,46.365277</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:owlname>owl</bsc:owlname>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.755834,46.365277</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.808612,46.175277 -83.808612,46.175277</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.808612,46.175277</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-84.111112,46.309166 -84.111112,46.309166</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-84.111112,46.309166</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.678612,46.821110 -83.678612,46.821110</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.678612,46.821110</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.664445,46.518888 -83.664445,46.518888</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.664445,46.518888</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-80.613334,46.730277 -80.613334,46.730277</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-80.613334,46.730277</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-79.676946,45.428054 -79.676946,45.428054</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-79.676946,45.428054</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.853056,46.236944 -83.853056,46.236944</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.853056,46.236944</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-82.289167,45.896388 -82.289167,45.896388</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-82.289167,45.896388</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n</wfs:FeatureCollection>\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/Popup/AnchoredBubble.html",
    "content": "<html>\n<head>\n  <script src=\"../../OLLoader.js\"></script>\n  <script src=\"../../../lib/Rico/Corner.js\"></script>\n  <script src=\"../../../lib/deprecated.js\"></script>\n  <script type=\"text/javascript\">\n\n   function test_Popup_Anchored_setOpacity(t) {\n        t.plan(5);\n        var opacity = 0.5;\n        var id = \"chicken\";\n        var w = 500;\n        var h = 400;\n        var sz = new OpenLayers.Size(w,h);\n        var lon = 5;\n        var lat = 40;\n        var ll = new OpenLayers.LonLat(lon, lat);\n        var content = \"foo\";\n        var x = 50;\n        var y = 100;\n\n        var map = new OpenLayers.Map('map');\n        map.addLayer(new OpenLayers.Layer('name', {'isBaseLayer':true}));\n        map.zoomToMaxExtent();\n\n        var popup = new OpenLayers.Popup.AnchoredBubble(id,\n                                     ll,\n                                     sz,\n                                     content,\n                                     null,\n                                     false);\n        map.addPopup(popup);\n\n        popup.setOpacity(opacity);\n        popup.draw(new OpenLayers.Pixel(x, y));\n\n        if (navigator.appName.indexOf(\"Microsoft\") == -1 || new RegExp(/msie 10/).test(navigator.userAgent.toLowerCase())) {\n            t.eq(parseFloat(popup.div.style.opacity), opacity, \"good default popup.opacity\");\n        } else {\n            t.eq(popup.div.style.filter, \"alpha(opacity=\" + opacity*100 + \")\", \"good default popup.opacity\");\n        }\n\n        t.ok(popup.groupDiv!=null, \"popup.groupDiv exists\");\n        t.ok(popup.groupDiv.parentNode!=null, \"popup.groupDiv.parentNode exists\");\n        t.ok(popup.groupDiv.parentNode.getElementsByTagName(\"span\").length > 0, \"popup.groupDiv.parentNode has SPAN children\");\n\n        var ricoCornerDiv = popup.groupDiv.parentNode.getElementsByTagName(\"span\")[0];\n        if (navigator.appName.indexOf(\"Microsoft\") == -1 || new RegExp(/msie 10/).test(navigator.userAgent.toLowerCase())) {\n            t.eq(parseFloat(ricoCornerDiv.style.opacity), opacity, \"good default ricoCornerDiv.opacity\");\n        } else {\n            t.eq(ricoCornerDiv.style.filter, \"alpha(opacity=\" + opacity*100 + \")\", \"good default ricoCornerDiv.opacity\");\n        }\n\n   }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:512px; height:256px\"> </div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/Protocol/SQL/Gears.html",
    "content": "<html>\n<head>\n  <script src=\"../../../OLLoader.js\"></script>\n  <script src=\"../../../../lib/deprecated.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        var protocol = new OpenLayers.Protocol.SQL.Gears();\n        if (!protocol.supported()) {\n            t.plan(0);\n            return;\n        }\n\n        t.plan(5);\n\n        t.eq(protocol.CLASS_NAME, \"OpenLayers.Protocol.SQL.Gears\",\n             \"ctor returns correct value\");\n\n        t.eq(protocol.jsonParser.CLASS_NAME,\n             \"OpenLayers.Format.JSON\",\n             \"ctor creates a JSON parser\");\n\n        t.eq(protocol.wktParser.CLASS_NAME,\n             \"OpenLayers.Format.WKT\",\n             \"ctor creates a WKT parser\");\n\n        var str = protocol.FID_PREFIX + \"foo_bar\";\n        t.ok(str.match(protocol.fidRegExp),\n             \"ctor creates correct regexp\");\n\n        t.ok(typeof protocol.db == \"object\",\n             \"ctor creates a db object\");\n\n        protocol.clear();\n        protocol.destroy();\n    }\n\n    function test_destroy(t) {\n        var protocol = new OpenLayers.Protocol.SQL.Gears();\n        if (!protocol.supported()) {\n            t.plan(0);\n            return;\n        }\n\n        t.plan(3);\n\n        protocol.destroy();\n\n        t.eq(protocol.db, null,\n             \"destroy nullifies db\");\n        t.eq(protocol.jsonParser, null,\n             \"destroy nullifies jsonParser\");\n        t.eq(protocol.wktParser, null,\n             \"destroy nullifies wktParser\");\n     }\n\n    function test_read(t) {\n        var protocolCallback, readCallback;\n        var protocolOptions = {callback: protocolCallback};\n        var readOptions = {callback: readCallback};\n\n        var protocol = new OpenLayers.Protocol.SQL.Gears(protocolOptions);\n        if (!protocol.supported()) {\n            t.plan(0);\n            return;\n        }\n\n        function okCallback(resp) {\n            t.eq(resp.CLASS_NAME, \"OpenLayers.Protocol.Response\",\n                 \"read calls correct callback with a response object\");\n        }\n\n        function failCallback(resp) {\n            t.fail(\"read calls incorrect callback\");\n        }\n\n        t.plan(4);\n\n        var resp;\n\n        // 2 tests\n        protocolOptions.callback = okCallback;\n        readOptions.callback = failCallback;\n        resp = protocol.read();\n        t.eq(resp.CLASS_NAME, \"OpenLayers.Protocol.Response\",\n             \"read returns a response object\");\n\n        // 2 test\n        protocolOptions.callback = failCallback;\n        readOptions.callback = okCallback;\n        resp = protocol.read(readOptions);\n        t.eq(resp.CLASS_NAME, \"OpenLayers.Protocol.Response\",\n             \"read returns a response object\");\n\n        protocol.clear();\n        protocol.destroy();\n    }\n\n    function test_unfreezeFeature(t) {\n        var protocol = new OpenLayers.Protocol.SQL.Gears();\n        if (!protocol.supported()) {\n            t.plan(0);\n            return;\n        }\n\n        t.plan(10);\n\n        var feature;\n        var wkt, json, fid, state;\n\n        json = \"{\\\"fake\\\":\\\"properties\\\"}\";\n        fid = \"1000\";\n        state = OpenLayers.State.INSERT;\n\n        var row = {\n            fieldByName: function(str) {\n                if (str == \"geometry\") {\n                    return wkt;\n                }\n                if (str == \"properties\") {\n                    return json;\n                }\n                if (str == \"fid\") {\n                    return fid;\n                }\n                if (str == \"state\") {\n                    return state;\n                }\n            }\n        };\n\n        // 5 tests\n        wkt = \"POINT(1 2)\";\n        feature = protocol.unfreezeFeature(row);\n        t.eq(feature.CLASS_NAME, \"OpenLayers.Feature.Vector\",\n             \"unfreezeFeature returns an OpenLayers.Feature.Vector\");\n        t.ok(feature.geometry.x == 1 && feature.geometry.y == 2,\n             \"unfreezeFeature returns a feature with correct geometry\");\n        t.eq(feature.attributes.fake, \"properties\",\n             \"unfreezeFeature returns a feature with correct attributes\");\n        t.eq(feature.fid, fid,\n             \"unfreezeFeature returns a feature with fid\");\n        t.eq(feature.state, state,\n             \"unfreezeFeature returns a feature with state\");\n\n        // 5 tests\n        wkt = protocol.NULL_GEOMETRY;\n        state = protocol.NULL_FEATURE_STATE;\n        feature = protocol.unfreezeFeature(row);\n        t.eq(feature.CLASS_NAME, \"OpenLayers.Feature.Vector\",\n             \"unfreezeFeature returns an OpenLayers.Feature.Vector\");\n        t.eq(feature.geometry, null,\n             \"unfreezeFeature returns a feature with correct geometry\");\n        t.eq(feature.attributes.fake, \"properties\",\n             \"unfreezeFeature returns a feature with correct attributes\");\n        t.eq(feature.fid, fid,\n             \"unfreezeFeature returns a feature with fid\");\n        t.eq(feature.state, null,\n             \"unfreezeFeature returns a feature with state\");\n\n        protocol.clear();\n        protocol.destroy();\n    }\n\n    function test_extractFidFromField(t) {\n        var protocol = new OpenLayers.Protocol.SQL.Gears();\n        if (!protocol.supported()) {\n            t.plan(0);\n            return;\n        }\n\n        t.plan(4);\n\n        var field, fid;\n\n        // fid is a string, field is not prefixed with FID_PREFIX\n        // 1 test\n        field = \"10\";\n        res = protocol.extractFidFromField(field);\n        t.eq(res, \"10\",\n             \"extractFidFromField returns expected string\");\n\n        // fid is a string, field is prefixed with FID_PREFIX\n        // 1 test\n        field = protocol.FIX_PREFIX + \"10\";\n        res = protocol.extractFidFromField(field);\n        t.eq(res, protocol.FIX_PREFIX + \"10\",\n             \"extractFidFromField returns expected prefixed string\");\n\n        // fid is a number, field is not prefixed with FIX_PREFIX\n        // 1 test\n        protocol.typeOfFid = \"number\";\n        field = \"10\";\n        res = protocol.extractFidFromField(field);\n        t.eq(res, 10,\n             \"extractFidFromField returns expected number\");\n\n        // fid is a number, field is prefixed with FIX_PREFIX\n        // 1 test\n        protocol.typeOfFid = \"number\";\n        field = protocol.FID_PREFIX + \"10\";\n        res = protocol.extractFidFromField(field);\n        t.eq(res, protocol.FID_PREFIX + \"10\",\n             \"extractFidFromField returns expected prefixed string\");\n    }\n\n    function test_freezeFeature(t) {\n        var protocol = new OpenLayers.Protocol.SQL.Gears();\n        if (!protocol.supported()) {\n            t.plan(0);\n            return;\n        }\n\n        t.plan(8);\n\n        var feature, res;\n\n        // 4 tests\n        feature = new OpenLayers.Feature.Vector();\n        feature.geometry = new OpenLayers.Geometry.Point(1, 2);\n        feature.attributes.fake = \"properties\";\n        feature.fid = \"1000\";\n        feature.state = OpenLayers.State.INSERT;\n        res = protocol.freezeFeature(feature);\n        t.eq(res[0], feature.fid,\n             \"freezeFeature returns correct fid\");\n        t.eq(res[1], \"POINT(1 2)\",\n             \"freezeFeature returns correct WKT\");\n        t.eq(res[2], \"{\\\"fake\\\":\\\"properties\\\"}\",\n             \"freezeFeature returns correct JSON\");\n        t.eq(res[3], feature.state,\n             \"freezeFeature returns correct feature state\");\n\n        // 4 tests\n        protocol.saveFeatureState = false;\n        feature = new OpenLayers.Feature.Vector();\n        feature.attributes.fake = \"properties\";\n        feature.fid = \"1000\";\n        feature.state = OpenLayers.State.INSERT;\n        res = protocol.freezeFeature(feature);\n        t.eq(res[0], feature.fid,\n             \"freezeFeature returns correct fid\");\n        t.eq(res[1], protocol.NULL_GEOMETRY,\n             \"freezeFeature returns expected null geom string\");\n        t.eq(res[2], \"{\\\"fake\\\":\\\"properties\\\"}\",\n             \"freezeFeature returns correct JSON\");\n        t.eq(res[3], protocol.NULL_FEATURE_STATE,\n             \"freezeFeature returns expected null feature state string\");\n\n        protocol.clear();\n        protocol.destroy();\n     }\n\n     function test_create(t) {\n        var protocol = new OpenLayers.Protocol.SQL.Gears();\n        if (!protocol.supported()) {\n            t.plan(0);\n            return;\n        }\n\n        t.plan(8);\n\n        var resp;\n        var scope = {\"fake\": \"scope\"};\n\n        var options = {\n            callback: function(resp) {\n                t.eq(resp.CLASS_NAME, \"OpenLayers.Protocol.Response\",\n                     \"user callback is passed a response\");\n                t.eq(resp.requestType, \"create\",\n                     \"user callback is passed correct request type in resp\");\n                t.ok(this == scope,\n                     \"user callback called with correct scope\");\n            },\n            scope: scope\n        };\n\n        // 4 tests\n        var feature = new OpenLayers.Feature.Vector();\n        feature.fid = \"1000\";\n        feature.attributes.fake = \"properties\";\n        feature.state = OpenLayers.State.INSERT;\n        resp = protocol.create([feature], options);\n        t.eq(resp.CLASS_NAME, \"OpenLayers.Protocol.Response\",\n             \"create returns a response\");\n\n        // check what we have in the DB\n        // 4 tests\n        resp = protocol.read({\"noFeatureStateReset\": true});\n        t.eq(resp.features.length, 1,\n             \"create inserts feature in the DB\");\n        t.eq(resp.features[0].fid, feature.fid,\n             \"create inserts feature with correct fid\");\n        t.eq(resp.features[0].attributes.fake, feature.attributes.fake,\n             \"create inserts feature with correct attributes\");\n        t.eq(resp.features[0].state, feature.state,\n             \"create inserts feature with correct state\");\n\n        protocol.clear();\n        protocol.destroy();\n    }\n\n     function test_createOrUpdate(t) {\n        var protocol = new OpenLayers.Protocol.SQL.Gears();\n        if (!protocol.supported()) {\n            t.plan(0);\n            return;\n        }\n\n        t.plan(5);\n\n        // 1 test\n        var feature = new OpenLayers.Feature.Vector();\n        feature.fid = \"1000\";\n        feature.attributes.fake = \"properties\";\n        feature.state = OpenLayers.State.INSERT;\n        resp = protocol.createOrUpdate([feature]);\n        t.eq(resp.CLASS_NAME, \"OpenLayers.Protocol.Response\",\n             \"createOrUpdate returns a response\");\n\n        // check what we have in the DB\n        // 4 tests\n        resp = protocol.read({\"noFeatureStateReset\": true});\n        t.eq(resp.features.length, 1,\n             \"createOrUpdate inserts feature in the DB\");\n        t.eq(resp.features[0].fid, feature.fid,\n             \"createOrUpdate inserts feature with correct fid\");\n        t.eq(resp.features[0].attributes.fake, feature.attributes.fake,\n             \"createOrUpdate inserts feature with correct attributes\");\n        t.eq(resp.features[0].state, feature.state,\n             \"createOrUpdate inserts feature with correct state\");\n\n        protocol.clear();\n        protocol.destroy();\n    }\n\n    function test_delete(t) {\n        var protocol = new OpenLayers.Protocol.SQL.Gears();\n        if (!protocol.supported()) {\n            t.plan(0);\n            return;\n        }\n\n        t.plan(4);\n\n        function createOneAndDeleteOne(fid, deleteOptions) {\n            var feature = new OpenLayers.Feature.Vector();\n            feature.fid = fid;\n            feature.attributes.fake = \"properties\";\n            feature.state = OpenLayers.State.INSERT;\n            var r = protocol.create([feature]);\n            protocol[\"delete\"](r.reqFeatures, deleteOptions);\n        }\n\n        var resp, fid;\n\n        // 1 test\n        fid = 1000;\n        protocol.saveFeatureState = false;\n        createOneAndDeleteOne(fid)\n        resp = protocol.read();\n        t.eq(resp.features.length, 0,\n             \"delete deletes feature if saveFeatureState is false\");\n        protocol.clear();\n\n        // 1 test\n        fid = 1000;\n        protocol.saveFeatureState = true;\n        createOneAndDeleteOne(fid);\n        resp = protocol.read();\n        t.eq(resp.features.length, 1,\n             \"delete does not delete feature if saveFeatureState is true\");\n        protocol.clear();\n\n        // 1 test\n        fid = \"1000\";\n        protocol.saveFeatureState = true;\n        createOneAndDeleteOne(fid);\n        resp = protocol.read();\n        t.eq(resp.features.length, 1,\n             \"delete does not delete feature if saveFeatureState is true\");\n        protocol.clear();\n\n        // 1 test\n        fid = protocol.FID_PREFIX + \"1000\";\n        protocol.saveFeatureState = true;\n        createOneAndDeleteOne(fid, {dontDelete: true});\n        resp = protocol.read();\n        t.eq(resp.features.length, 0,\n             \"delete deletes feature if saveFeatureState is true and fid is prefixed\");\n        protocol.clear();\n\n        protocol.destroy();\n    }\n\n    function test_callUserCallback(t) {\n        var protocol = new OpenLayers.Protocol.SQL.Gears();\n        if (!protocol.supported()) {\n            t.plan(0);\n            return;\n        }\n\n        t.plan(6);\n\n        var options, resp;\n        var scope = {'fake': 'scope'};\n\n        // test commit callback\n        // 1 tests\n        options = {\n            'callback': function() {\n                t.ok(this == scope, 'callback called with correct scope');\n            },\n            'scope': scope\n        };\n        resp = {'requestType': 'create', 'last': true};\n        protocol.callUserCallback(options, resp);\n        // 0 test\n        resp = {'requestType': 'create', 'last': false};\n        protocol.callUserCallback(options, resp);\n\n        // test create callback\n        // 2 tests\n        options = {\n            'create': {\n                'callback': function(r) {\n                    t.ok(this == scope, 'callback called with correct scope');\n                    t.ok(r == resp, 'callback called with correct response');\n                },\n                'scope': scope\n            }\n        };\n        resp = {'requestType': 'create'};\n        protocol.callUserCallback(options, resp);\n\n        // test with both callbacks set\n        // 3 tests\n        options = {\n            'create': {\n                'callback': function(r) {\n                    t.ok(this == scope, 'callback called with correct scope');\n                    t.ok(r == resp, 'callback called with correct response');\n                },\n                'scope': scope\n            },\n            'callback': function() {\n                t.ok(this == scope, 'callback called with correct scope');\n            },\n            'scope': scope\n        };\n        resp = {'requestType': 'create', 'last': true};\n        protocol.callUserCallback(options, resp);\n\n        // no callback set\n        // 0 test\n        options = {\n            'delete': {\n                'callback': function(resp) {\n                    t.fail('callback should not get called');\n                }\n            }\n        };\n        resp = {'requestType': 'create'};\n        protocol.callUserCallback(options, resp);\n\n        // cleanup\n        protocol.destroy();\n    }\n\n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/Protocol/SQL.html",
    "content": "<html>\n<head>\n  <script src=\"../../OLLoader.js\"></script>\n  <script src=\"../../../lib/deprecated.js\"></script>\n  <script type=\"text/javascript\">\n\n    function test_initialize(t) {\n        t.plan(3);\n        var options = {tableName: 'my_features', \n                       databaseName: 'my_database_name'}\n        var protocol = new OpenLayers.Protocol.SQL(options);\n\n        t.ok(protocol instanceof OpenLayers.Protocol.SQL,\n             \"new OpenLayers.Protocol.SQL returns object\");\n\n        t.eq(protocol.tableName, options.tableName, \"tableName property is set\");\n        t.eq(protocol.databaseName, options.databaseName, \"databaseName property is set\");\n    }\n    \n  </script>\n</head>\n<body>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/Renderer/SVG2.html",
    "content": "<html>\n<head>\n  <script src=\"../../OLLoader.js\"></script>\n  <script src=\"../../../lib/deprecated.js\"></script>\n  <script type=\"text/javascript\">\n\n    var geometry = null, node = null;\n    \n    function test_SVG_constructor(t) {\n        if (!OpenLayers.Renderer.SVG2.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(1);\n        var r = new OpenLayers.Renderer.SVG2(document.body);\n        t.ok(r instanceof OpenLayers.Renderer.SVG2, \"new OpenLayers.Renderer.SVG2 returns SVG object\" );\n    }\n    \n    function test_SVG_destroy(t) {\n        if (!OpenLayers.Renderer.SVG2.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(1);\n        \n        var g_Destroy = false;\n        \n        OpenLayers.Renderer.Elements.prototype._destroy = \n            OpenLayers.Renderer.Elements.prototype.destroy;\n            \n        OpenLayers.Renderer.prototype.destroy = function() {\n            g_Destroy = true;\n        }\n        \n        var r = new OpenLayers.Renderer.SVG2(document.body);\n        r.destroy();\n        \n        t.eq(g_Destroy, true, \"OpenLayers.Renderer.Elements.destroy() called\");\n        \n        OpenLayers.Renderer.prototype.destroy = \n            OpenLayers.Renderer.prototype._destroy;\n    }\n    \n    function test_SVG_updateDimensions(t) {\n        if (!OpenLayers.Renderer.SVG2.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(7);\n        \n        OpenLayers.Renderer.SVG2.prototype._setExtent =\n            OpenLayers.Renderer.SVG2.prototype.setExtent;\n        \n        var g_SetExtent = false;\n        OpenLayers.Renderer.SVG2.prototype.setExtent = function() {\n            g_SetExtent = true;\n            OpenLayers.Renderer.SVG2.prototype._setExtent.apply(this, arguments);\n        }\n                \n        var r = new OpenLayers.Renderer.SVG2(document.body);\n        var extent = new OpenLayers.Bounds(1,2,3,4);\n        r.map = {\n            getResolution: function() {\n                return 0.5;\n            },\n            getExtent: function() {\n                return extent;\n            },\n            getMaxExtent: function() {\n                return extent;\n            }\n        }\n        r.updateDimensions();\n        \n        t.eq(g_SetExtent, true, \"Elements.setExtent() called\");\n        \n        t.eq(r.extent.toString(), extent.scale(3).toString(), \"renderer's extent is correct\");\n        t.eq(r.rendererRoot.getAttributeNS(null, \"width\"), \"12\", \"width is correct\");\n        t.eq(r.rendererRoot.getAttributeNS(null, \"height\"), \"12\", \"height is correct\");\n        t.eq(r.rendererRoot.getAttributeNS(null, \"viewBox\"), \"-1 -6 6 6\", \"rendererRoot viewBox is correct\");\n        \n        // test extent changes\n        extent = new OpenLayers.Bounds(2,3,5,6);\n        r.updateDimensions();\n        t.eq(r.extent.toString(), extent.scale(3).toString(), \"renderer's extent changed after updateDimensions\");\n        t.eq(r.rendererRoot.getAttributeNS(null, \"viewBox\"), \"-1 -9 9 9\", \"rendererRoot viewBox is correct after a new setExtent\");\n\n        OpenLayers.Renderer.SVG2.prototype.setExtent =\n            OpenLayers.Renderer.SVG2.prototype._setExtent;\n    }\n    \n    function test_SVG_drawpoint(t) {\n        if (!OpenLayers.Renderer.SVG2.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n    \n        t.plan(1);\n\n        var r = new OpenLayers.Renderer.SVG2(document.body);\n        \n        var properDraw = false;\n        var g_Radius = null;\n        r.drawCircle = function(n, g, r) {\n            properDraw = true;\n            g_Radius = 1;\n        }\n        r.drawPoint();\n        \n        t.ok(properDraw && g_Radius == 1, \"drawPoint called drawCircle with radius set to 1\");\n    }\n    \n    function test_SVG_drawcircle(t) {\n        if (!OpenLayers.Renderer.SVG2.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(5);\n        \n        var r = new OpenLayers.Renderer.SVG2(document.body);\n        r.resolution = 0.5;\n        r.left = 0;\n        r.top = 0;\n        \n        var node = document.createElement('div');\n        \n        var geometry = {\n            x: 1,\n            y: 2\n        }\n        \n        r.drawCircle(node, geometry, 3);\n        \n        t.eq(node.getAttributeNS(null, 'cx'), '1', \"cx is correct\");\n        t.eq(node.getAttributeNS(null, 'cy'), '-2', \"cy is correct\");\n        t.eq(node._radius, 3, \"radius preset is correct\");\n       \n        // #1274: out of bound node fails when first added\n        var geometry = {\n            x: 10000000,\n            y: 200000000,\n            CLASS_NAME: \"OpenLayers.Geometry.Point\",\n            id: \"foo\",\n            getBounds: function() {return {bottom: 0}}\n        }\n        node.id = geometry.id;\n        r.root.appendChild(node);\n\n        var drawCircleCalled = false;\n        r.drawCircle = function() {\n            drawCircleCalled = true;\n            return OpenLayers.Renderer.SVG2.prototype.drawCircle.apply(r, arguments);\n        }\n        \n        r.drawGeometry(geometry, {pointRadius: 3}, \"blah_4000\");\n        t.eq(drawCircleCalled, true, \"drawCircle called on drawGeometry for a point geometry.\")\n        t.ok(node.parentNode != r.root, \"circle will not be drawn when coordinates are outside the valid range\");\n    }\n    \n    function test_SVG_drawlinestring(t) {\n        if (!OpenLayers.Renderer.SVG2.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(2);\n        \n        var r = new OpenLayers.Renderer.SVG2(document.body);\n        \n        var node = document.createElement('div');\n        \n        var geometry = {\n            components: \"foo\"\n        }\n        g_GetString = false;\n        g_Components = null;\n        r.getComponentsString = function(c) {\n            g_GetString = true;\n            g_Components = c;\n            return \"bar\";\n        }\n        \n        r.drawLineString(node, geometry);\n        \n        t.ok(g_GetString && g_Components == \"foo\", \"getComponentString is called with valid arguments\");\n        t.eq(node.getAttributeNS(null, \"points\"), \"bar\", \"points attribute is correct\");\n    }\n    \n    function test_SVG_drawlinearring(t) {\n        if (!OpenLayers.Renderer.SVG2.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(2);\n        \n        var r = new OpenLayers.Renderer.SVG2(document.body);\n        \n        var node = document.createElement('div');\n        \n        var geometry = {\n            components: \"foo\"\n        }\n        g_GetString = false;\n        g_Components = null;\n        r.getComponentsString = function(c) {\n            g_GetString = true;\n            g_Components = c;\n            return \"bar\";\n        }\n        \n        r.drawLinearRing(node, geometry);\n        \n        t.ok(g_GetString, \"getComponentString is called with valid arguments\");\n        t.eq(node.getAttributeNS(null, \"points\"), \"bar\", \"points attribute is correct\");\n    }\n\n    function test_SVG_drawpolygon(t) {\n        if (!OpenLayers.Renderer.SVG2.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(3);\n        \n        var r = new OpenLayers.Renderer.SVG2(document.body);\n        \n        var node = document.createElement('div');\n        \n        var linearRings = [{\n            components: [\"foo\"]\n        },{\n            components: [\"bar\"]\n        }]\n        \n        var geometry = {\n            components: linearRings\n        }\n        g_GetString = false;\n        r.getShortString = function(c) {\n            g_GetString = true;\n            return c;\n        }\n        \n        r.drawPolygon(node, geometry);\n        \n        t.ok(g_GetString, \"getShortString is called\");\n        t.eq(node.getAttributeNS(null, \"d\"), \"M foo M bar z\", \"d attribute is correctly set\");\n        t.eq(node.getAttributeNS(null, \"fill-rule\"), \"evenodd\", \"fill-rule attribute is correctly set\");\n    }\n\n    function test_SVG_drawrectangle(t) {\n        if (!OpenLayers.Renderer.SVG2.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(4);\n        \n        var r = new OpenLayers.Renderer.SVG2(document.body);\n        r.resolution = 0.5;\n        r.left = 0;\n        r.top = 0;\n        \n        var node = document.createElement('div');\n        \n        var geometry = {\n            x: 1,\n            y: 2,\n            width: 3,\n            height: 4\n        }\n        \n        r.drawRectangle(node, geometry);\n        \n        t.eq(node.getAttributeNS(null, \"x\"), \"1\", \"x attribute is correctly set\");\n        t.eq(node.getAttributeNS(null, \"y\"), \"-2\", \"y attribute is correctly set\");\n        t.eq(node.getAttributeNS(null, \"width\"), \"3\", \"width attribute is correctly set\");\n        t.eq(node.getAttributeNS(null, \"height\"), \"4\", \"height attribute is correctly set\");\n    }\n    \n    function test_SVG_getcomponentsstring(t) {\n        if (!OpenLayers.Renderer.SVG2.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(1);\n        \n        var components = ['foo', 'bar'];\n        \n        OpenLayers.Renderer.SVG2.prototype._getShortString = \n            OpenLayers.Renderer.SVG2.prototype.getShortString;\n            \n        OpenLayers.Renderer.SVG2.prototype.getShortString = function(p) {\n            return p;\n        };\n        \n        var string = OpenLayers.Renderer.SVG2.prototype.getComponentsString(components);\n        t.eq(string, \"foo,bar\", \"returned string is correct\");\n        \n        OpenLayers.Renderer.SVG2.prototype.getShortString = \n            OpenLayers.Renderer.SVG2.prototype._getShortString;\n    }\n    \n    \n    \n    function test_SVG_getshortstring(t) {\n        if (!OpenLayers.Renderer.SVG2.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n        \n        t.plan(1);\n        \n        var r = new OpenLayers.Renderer.SVG2(document.body);\n        r.resolution = 0.5;\n        r.left = 0;\n        r.top = 0;\n        \n        var point = {\n            x: 1,\n            y: 2\n        };\n        \n        var string = r.getShortString(point);\n        t.eq(string, \"1,-2\", \"returned string is correct\");\n    }\n    \n    function test_svg_getnodetype(t) {\n        if (!OpenLayers.Renderer.SVG2.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n\n        t.plan(1);\n         \n        var r = new OpenLayers.Renderer.SVG2(document.body);\n\n        var g = {CLASS_NAME: \"OpenLayers.Geometry.Point\"}\n        var s = {graphicName: \"square\"};\n        \n        t.eq(r.getNodeType(g, s), \"svg\", \"Correct node type for well known symbols\");\n    }\n        \n    function test_svg_importsymbol(t) {\n        if (!OpenLayers.Renderer.SVG2.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n\n        t.plan(2);\n        \n        var r = new OpenLayers.Renderer.SVG2(document.body);\n\n        r.importSymbol(\"square\");\n\n        var polygon = document.getElementById(r.container.id + \"_defs\").firstChild.firstChild;\n        \n        var pass = false;\n        for (var i = 0; i < polygon.points.numberOfItems; i++) {\n            var p = polygon.points.getItem(i);\n            pass = p.x === OpenLayers.Renderer.symbol.square[2*i] && \n                   p.y === OpenLayers.Renderer.symbol.square[2*i+1];\n            if (!pass) {\n                break;\n            }\n        }\n        t.ok(pass, \"Square symbol rendered correctly\");\n        t.ok(r.symbolMetrics[\"-square\"], \"Symbol metrics cached correctly.\");\n    }\n        \n    function test_svg_dashstyle(t) {\n        if (!OpenLayers.Renderer.SVG2.prototype.supported()) {\n            t.plan(0);\n            return;\n        }\n\n        t.plan(5);\n        \n        var r = new OpenLayers.Renderer.SVG2(document.body);\n\n        t.eq(r.dashStyle({strokeWidth: 1, strokeDashstyle: \"dot\"}, 1), \"1,4\", \"dot dasharray created correctly\");\n        t.eq(r.dashStyle({strokeWidth: 1, strokeDashstyle: \"dash\"}, 1), \"4,4\", \"dash dasharray created correctly\");\n        t.eq(r.dashStyle({strokeWidth: 1, strokeDashstyle: \"longdash\"}, 1), \"8,4\", \"longdash dasharray created correctly\");\n        t.eq(r.dashStyle({strokeWidth: 1, strokeDashstyle: \"dashdot\"}, 1), \"4,4,1,4\", \"dashdot dasharray created correctly\");\n        t.eq(r.dashStyle({strokeWidth: 1, strokeDashstyle: \"longdashdot\"}, 1), \"8,4,1,4\", \"dashdot dasharray created correctly\");\n    }\n\n  </script>\n</head>\n<body>\n<div id=\"map\" style=\"width:500px;height:550px\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/Tile/WFS.html",
    "content": "<html>\n<head>\n  <script src=\"../../OLLoader.js\"></script>\n  <script src=\"../../../lib/deprecated.js\"></script>\n  <script type=\"text/javascript\">\n    var tile; \n\n    var map, layer;\n    function setUp() {\n        map = new OpenLayers.Map(\"map\");\n        layer = new OpenLayers.Layer(null, {\n            isBaseLayer: true\n        });\n        map.addLayer(layer)\n        map.setCenter(new OpenLayers.LonLat(0, 0));\n    }\n    \n    function tearDown() {\n        map.destroy();\n        map = null;\n        layer = null;\n    }\n    \n    function test_Tile_WFS_constructor (t) {\n        t.plan( 8 );\n        setUp();\n     \n        var position = new OpenLayers.Pixel(10,20);\n        var bounds = new OpenLayers.Bounds(1,2,3,4);\n        var url = \"bobob\";\n        var size = new OpenLayers.Size(5,6);\n        \n        tile = new OpenLayers.Tile.WFS(layer, position, bounds, url, size);\n\n        t.ok( tile instanceof OpenLayers.Tile.WFS, \"new OpenLayers.Tile.WFS returns Tile.WFS object\" );\n        t.ok( tile.layer === layer, \"tile.layer set correctly\");\n        t.ok( tile.position.equals(position), \"tile.position set correctly\");\n        t.ok( tile.bounds.equals(bounds), \"tile.bounds set correctly\");\n        t.eq( tile.url, url, \"tile.url set correctly\");        \n        t.ok( tile.size.equals(size), \"tile.size is set correctly\" );\n\n        t.ok( tile.id != null, \"tile is given an id\");\n        t.ok( tile.events != null, \"tile's events intitialized\");\n        \n        tearDown();\n    }\n\n    function test_Tile_WFS_requestSuccess(t) {\n        t.plan(2);\n        setUp();\n\n        var tile = {\n            'request': {}\n        };\n            \n        OpenLayers.Tile.WFS.prototype.requestSuccess.apply(tile, []);\n        \n        t.ok(tile.request == null, \"request property on tile set to null\");\n\n        var position = new OpenLayers.Pixel(10,20);\n        var bounds = new OpenLayers.Bounds(1,2,3,4);\n        var url = \"bobob\";\n        var size = new OpenLayers.Size(5,6);\n        \n        tile = new OpenLayers.Tile.WFS(layer, position, bounds, url, size);\n        tile.destroy();\n        tile.requestSuccess({'requestText': '<xml><foo /></xml>'});\n        t.ok(true, \"Didn't fail after calling requestSuccess on destroyed tile.\");\n        \n        tearDown();\n    }\n    \n    function test_Tile_WFS_loadFeaturesForRegion(t) {\n        t.plan(9);\n        \n        var tile = {\n            'url': {}\n        };\n\n        var g_Success = {};        \n\n        var _get = OpenLayers.Request.GET;\n        OpenLayers.Request.GET = function(config) {\n            t.ok(config.url == tile.url, \"tile's url correctly passed\");\n            t.ok(config.params == null, \"null params\");\n            t.ok(config.scope == tile, \"tile passed as scope\");\n            t.ok(config.success == g_Success, \"success passed\");\n        };\n        \n      //no running request -- 4 tests\n        OpenLayers.Tile.WFS.prototype.loadFeaturesForRegion.apply(tile, [g_Success]);\n\n      //running request (cancelled) -- 4 tests + 1 test (for request abort)\n        tile.request = {\n            'abort': function() {\n                    t.ok(true, \"request aborted\");\n            }\n        };\n        OpenLayers.Tile.WFS.prototype.loadFeaturesForRegion.apply(tile, [g_Success]);\n\n        OpenLayers.Request.GET = _get;\n    }\n    \n    function test_Tile_WFS_destroy(t) {\n        t.plan(9);\n        setUp();\n\n        var position = new OpenLayers.Pixel(10,20);\n        var bounds = new OpenLayers.Bounds(1,2,3,4);\n        var url = \"bobob\";\n        var size = new OpenLayers.Size(5,6);\n        \n        tile = new OpenLayers.Tile.WFS(layer, position, bounds, url, size);\n        tile.events.destroy = function() {\n            t.ok(true, \"tile events destroy() called\");\n        };\n\n \n        var _gAbort = false; \n        tile.request = { \n            abort: function() { \n                _gAbort = true; \n            } \n        } \n\n        \n        tile.destroy();\n\n        t.ok(tile.layer == null, \"tile.layer set to null\");\n        t.ok(tile.bounds == null, \"tile.bounds set to null\");\n        t.ok(tile.size == null, \"tile.size set to null\");\n        t.ok(tile.position == null, \"tile.position set to null\");\n        t.ok(_gAbort, \"request transport is aborted\");\n        t.ok(tile.request == null, \"tile.request set to null\");\n        \n        t.ok(tile.events == null, \"tile.events set to null\");\n        \n        tile.requestSuccess({'requestText': '<xml><foo /></xml>'});\n        t.ok(true, \"Didn't fail after calling requestSuccess on destroyed tile.\");\n        \n        tearDown();\n    }\n    function test_nonxml_format(t) {\n        t.plan(2);\n        \n        setUp();\n        \n        var data = '{\"type\":\"Feature\", \"id\":\"OpenLayers.Feature.Vector_135\", \"properties\":{}, \"geometry\":{\"type\":\"Point\", \"coordinates\":[118.125, -18.6328125]}, \"crs\":{\"type\":\"OGC\", \"properties\":{\"urn\":\"urn:ogc:def:crs:OGC:1.3:CRS84\"}}}'\n        var position = new OpenLayers.Pixel(10,20);\n        var bounds = new OpenLayers.Bounds(1,2,3,4);\n        var url = \"bobob\";\n        var size = new OpenLayers.Size(5,6);\n        \n        var log = [];\n        \n        var l = new OpenLayers.Layer(null, {\n            vectorMode: true,\n            formatObject: new OpenLayers.Format.GeoJSON(), \n            addFeatures: function(features) { \n                log.push(features);\n            }\n        })\n        map.addLayer(l);\n\n        var tile = new OpenLayers.Tile.WFS(l, position, bounds, url, size);\n\n        tile.requestSuccess({responseText: data});\n\n        t.eq(log.length, 1, \"one call logged\")\n        t.eq(log[0] && log[0].length, 1, \"GeoJSON format returned a single feature which was added.\");\n        \n        tearDown();\n    }  \n     \n    function test_xml_string_and_dom(t) {\n        t.plan(4);\n        setUp();\n        \n        var data = '<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?><wfs:FeatureCollection   xmlns:bsc=\"http://www.bsc-eoc.org/bsc\"   xmlns:wfs=\"http://www.opengis.net/wfs\"   xmlns:gml=\"http://www.opengis.net/gml\"   xmlns:ogc=\"http://www.opengis.net/ogc\"   xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"   xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengeospatial.net//wfs/1.0.0/WFS-basic.xsd                        http://www.bsc-eoc.org/bsc http://www.bsc-eoc.org/cgi-bin/bsc_ows.asp?SERVICE=WFS&amp;VERSION=1.0.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=OWLS&amp;OUTPUTFORMAT=XMLSCHEMA\">      <gml:boundedBy>        <gml:Box srsName=\"EPSG:4326\">            <gml:coordinates>-94.989723,43.285833 -74.755001,51.709520</gml:coordinates>        </gml:Box>      </gml:boundedBy>    <gml:featureMember>      <bsc:OWLS>        <gml:boundedBy>            <gml:Box srsName=\"EPSG:4326\">                <gml:coordinates>-94.142500,50.992777 -94.142500,50.992777</gml:coordinates>            </gml:Box>        </gml:boundedBy>        <bsc:msGeometry>        <gml:Point srsName=\"EPSG:4326\">          <gml:coordinates>-94.142500,50.992777</gml:coordinates>        </gml:Point>        </bsc:msGeometry>        <bsc:ROUTEID>ON_2</bsc:ROUTEID>        <bsc:ROUTE_NAME>Suffel Road</bsc:ROUTE_NAME>        <bsc:LATITUDE>50.9927770</bsc:LATITUDE>        <bsc:LONGITUDE>-94.1425000</bsc:LONGITUDE>      </bsc:OWLS>    </gml:featureMember></wfs:FeatureCollection>';\n        var position = new OpenLayers.Pixel(10,20);\n        var bounds = new OpenLayers.Bounds(1,2,3,4);\n        var url = \"bobob\";\n        var size = new OpenLayers.Size(5,6);\n        \n        var l = new OpenLayers.Layer();\n        map.addLayer(l);\n\n        var tile = new OpenLayers.Tile.WFS(l, position, bounds, url, size);\n        \n        var log = [];\n        tile.addResults = function(results) {\n            log.push(results);\n        } \n        tile.requestSuccess({responseText: data});\n        \n        t.eq(log.length, 1, \"first call logged\");\n        t.eq(log[0] && log[0].length, 1, \"results count is correct when passing in XML as a string into non-vectormode\");\n        \n        log.length = 0;\n        tile.addResults = function(results) {\n            log.push(results);\n        } \n        tile.requestSuccess({responseXML: OpenLayers.Format.XML.prototype.read(data)}); \n\n        t.eq(log.length, 1, \"second call logged\");\n        t.eq(log[0] && log[0].length, 1, \"results count is correct when passing in XML as DOM into non-vectormode\");\n\n        tearDown();\n    }         \n  </script>\n</head>\n<body>\n</body>\n</html>\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/deprecated/Util.html",
    "content": "<html>\n    <head>\n        <script>\nvar custom$ = function() {};\nwindow.$ = custom$;\n        </script>\n        <script src=\"../OLLoader.js\"></script>\n        <script src=\"../../lib/deprecated.js\"></script>\n        <script>\n        \nfunction test_$(t) {\n    t.plan(1);\n    t.ok($ === custom$, \"OpenLayers doesn't clobber existing definition of $.\");\n}\n            \n        </script>\n    </head>\n    <body>\n    </body>\n</html>"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/georss.txt",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><?xml-stylesheet type=\"text/css\" href=\"/css/rss.css\" ?>\n\n<rdf:RDF  xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\"\n  xmlns=\"http://purl.org/rss/1.0/\"\n  xmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n  xmlns:georss=\"http://www.georss.org/georss\">\n<docs>This is an RSS file.  Copy the URL into your aggregator of choice.  If you don't know what this means and want to learn more, please see: <span>http://platial.typepad.com/news/2006/04/really_simple_t.html</span> for more info.</docs><channel rdf:about=\"http://platial.com\">\n<link>http://platial.com</link>\n<title>Crschmidt's Places At Platial</title>\n<description></description>\n<items>\n<rdf:Seq>\n<rdf:li resource=\"http://platial.com/place/90306\"/>\n<rdf:li resource=\"http://platial.com/place/67230\"/>\n<rdf:li resource=\"http://platial.com/place/65645\"/>\n<rdf:li resource=\"http://platial.com/place/62200\"/>\n<rdf:li resource=\"http://platial.com/place/28232\"/>\n<rdf:li resource=\"http://platial.com/place/43666\"/>\n<rdf:li resource=\"http://platial.com/place/28394\"/>\n<rdf:li resource=\"http://platial.com/place/28251\"/>\n<rdf:li resource=\"http://platial.com/place/28392\"/>\n<rdf:li resource=\"http://platial.com/place/28391\"/>\n<rdf:li resource=\"http://platial.com/place/28231\"/>\n<rdf:li resource=\"http://platial.com/place/28393\"/>\n<rdf:li resource=\"http://platial.com/place/31685\"/>\n<rdf:li resource=\"http://platial.com/place/28596\"/>\n<rdf:li resource=\"http://platial.com/place/28595\"/>\n<rdf:li resource=\"http://platial.com/place/28594\"/>\n<rdf:li resource=\"http://platial.com/place/28593\"/>\n<rdf:li resource=\"http://platial.com/place/28592\"/>\n<rdf:li resource=\"http://platial.com/place/28591\"/>\n<rdf:li resource=\"http://platial.com/place/28590\"/>\n<rdf:li resource=\"http://platial.com/place/28589\"/>\n<rdf:li resource=\"http://platial.com/place/28588\"/>\n<rdf:li resource=\"http://platial.com/place/28587\"/>\n<rdf:li resource=\"http://platial.com/place/28586\"/>\n<rdf:li resource=\"http://platial.com/place/28585\"/>\n<rdf:li resource=\"http://platial.com/place/28584\"/>\n<rdf:li resource=\"http://platial.com/place/28583\"/>\n<rdf:li resource=\"http://platial.com/place/28582\"/>\n<rdf:li resource=\"http://platial.com/place/28581\"/>\n<rdf:li resource=\"http://platial.com/place/28580\"/>\n<rdf:li resource=\"http://platial.com/place/28579\"/>\n<rdf:li resource=\"http://platial.com/place/28578\"/>\n<rdf:li resource=\"http://platial.com/place/28577\"/>\n<rdf:li resource=\"http://platial.com/place/28576\"/>\n<rdf:li resource=\"http://platial.com/place/28575\"/>\n<rdf:li resource=\"http://platial.com/place/28574\"/>\n<rdf:li resource=\"http://platial.com/place/28573\"/>\n<rdf:li resource=\"http://platial.com/place/28572\"/>\n<rdf:li resource=\"http://platial.com/place/28571\"/>\n<rdf:li resource=\"http://platial.com/place/28570\"/>\n</rdf:Seq>\n</items>\n</channel>\n<item rdf:about=\"http://platial.com/place/90306\">\n<link>http://platial.com/place/90306</link>\n<title>Knitting Room</title>\n<description><![CDATA[This little shop is jammed full. Yarn, yarn everywhere. They make the most of every possible nook and cranny. I like this place also because they have a lot of different kinds of knitting needles in all different sizes. Also, the people who work here are younger and hipper than in the other stores I go to. I reccomend buying supplies here and then knitting your way through a good documentary at the Capitol Theater across the street.<br/>Address: 2 lake St, Arlington, MA <br/>Tags: knitting, yarn, pins and needles, handspun, hand dyed, novelty yarn, fancy, simple, young, hip, friendly, needles, addy, cute hats<br /><br /><a href=\"http://platial.com/place/90306\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/90306\">Grab this on Platial</a> ]]></description>\n<georss:point>42.405696 -71.142197</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-06-08T17:35:01.942452+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/67230\">\n<link>http://platial.com/place/67230</link>\n<title>Knitting Room</title>\n<description><![CDATA[This little shop is jammed full. Yarn, yarn everywhere. They make the most of every possible nook and cranny. I like this place also because they have a lot of different kinds of knitting needles in all different sizes. Also, the people who work here are younger and hipper than in the other stores I go to. I reccomend buying supplies here and then knitting your way through a good documentary at the Capitol Theater across the street.<br/>Address: 2 lake St, Arlington, MA <br/>Tags: knitting, yarn, pins and needles, handspun, hand dyed, novelty yarn, fancy, simple, young, hip, friendly, needles, addy, cute hats<br /><br /><a href=\"http://platial.com/place/67230\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/67230\">Grab this on Platial</a> ]]></description>\n<georss:point>42.405524 -71.142273</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-04-24T11:35:26.733857+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/65645\">\n<link>http://platial.com/place/65645</link>\n<title>â Â¢Â¢â¢Â£ËÃ¸Å</title>\n<description><![CDATA[ijeÂªÂ£âÂµËËÃ®<br/>Address: 151 Erie St., Cambridge, MA<br/>Tags: platial graffiti<br /><br /><a href=\"http://platial.com/place/65645\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/65645\">Grab this on Platial</a> ]]></description>\n<georss:point>42.352455 -71.110210</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-04-20T08:56:12.696224+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/62200\">\n<link>http://platial.com/place/62200</link>\n<title>Allen Hall</title>\n<description><![CDATA[My dorm at UIUC.<br/>Address: 1301 W Gregory Dr, Urbana, IL<br/>Tags: dorm, uiuc, college<br/><a href=\"http://platial.com/place/62200\"><img src=\"http://platial.comhttp://static.flickr.com/4/8576450_0d59cc2531_s.jpg\"/></a><br/><br /><br /><a href=\"http://platial.com/place/62200\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/62200\">Grab this on Platial</a> ]]></description>\n<georss:point>40.104172 -88.220623</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-04-14T08:01:01.872873+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28232\">\n<link>http://platial.com/place/28232</link>\n<title>Bagby Hot Springs, OR</title>\n<description><![CDATA[Hot spring, temperature: 136  degress F, 58  degress C. However, the area around the springs are not exactly well looked upon by people who know the place.\n\n<br/>Tags: 20s, rosalie, romance, childhood, hike, camping, soak, relax, beautiful, hot springs, bathhouse, favorite, popular, crowded, organized, honeymoon tub, plumbing made from hollowed out trees, hot springs, mt hood, notorious car break in spot, rash, bacteria<br /><br /><a href=\"http://platial.com/place/28232\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28232\">Grab this on Platial</a> ]]></description>\n<georss:point>44.936000 -122.173000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:10:18.553063+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/43666\">\n<link>http://platial.com/place/43666</link>\n<title>Shooting Location for \"The Field of Dreams\" Film</title>\n<description><![CDATA[1989's Field of Dreams was a Best Picture Academy Award nominee, and the baseball field in the cornfield still stands today, and has become quite a tourist destination.  Games are occasionally played at the field, re-enacting professional baseball at the turn of the 20th Century.<br/>Address: Dyersville, Iowa<br/>Tags: iowa, baseball, movie locations, field of dreams, kevin costner, costner, dyersville, kinsella, james earl jones, chicago black sox, shoeless joe, joe jackson, famous farms, film, movie, cinema, shooting location<br /><br /><a href=\"http://platial.com/place/43666\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/43666\">Grab this on Platial</a> ]]></description>\n<georss:point>42.481213 -91.111679</georss:point>\n<dc:creator>echinodermata</dc:creator>\n<dc:date>2006-03-23T11:40:17.654061+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28394\">\n<link>http://platial.com/place/28394</link>\n<title>Moffetts (Bonneville) Hot Springs, WA</title>\n<description><![CDATA[Hot spring, temperature: 97  degress F, 36  degress C<br/>Tags: soak, hot springs, relax, nature<br /><br /><a href=\"http://platial.com/place/28394\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28394\">Grab this on Platial</a> ]]></description>\n<georss:point>45.658000 -121.962000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:16:27.329816+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28251\">\n<link>http://platial.com/place/28251</link>\n<title>Austin Hot Springs, OR</title>\n<description><![CDATA[Hot spring, temperature: 186  degress F, 86  degress C<br/>Tags: soak, hot springs, relax, nature, popular, crowded<br /><br /><a href=\"http://platial.com/place/28251\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28251\">Grab this on Platial</a> ]]></description>\n<georss:point>45.021000 -122.009000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:11:04.489886+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28392\">\n<link>http://platial.com/place/28392</link>\n<title>Rock Creek Hot Springs, WA</title>\n<description><![CDATA[Hot spring, temperature: Hot  degress F, Hot  degress C<br/>Tags: soak, hot springs, relax, nature<br /><br /><a href=\"http://platial.com/place/28392\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28392\">Grab this on Platial</a> ]]></description>\n<georss:point>45.723000 -121.927000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:16:22.636855+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28391\">\n<link>http://platial.com/place/28391</link>\n<title>St. Martins (Wind River) Hot Springs, WA</title>\n<description><![CDATA[Hot spring, temperature: 120  degress F, 49  degress C<br/>Tags: hot springs, soak, relax, nature, wonderful<br /><br /><a href=\"http://platial.com/place/28391\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28391\">Grab this on Platial</a> ]]></description>\n<georss:point>45.728000 -121.800000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:16:20.383244+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28231\">\n<link>http://platial.com/place/28231</link>\n<title>Breitenbush Hot Springs, OR</title>\n<description><![CDATA[Hot spring, temperature: 198  degress F, 92  degress C<br/>Tags: hot springs, resort, relax, nature, beautiful, http:www.breitenbush.com, soaking<br /><br /><a href=\"http://platial.com/place/28231\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28231\">Grab this on Platial</a> ]]></description>\n<georss:point>44.782000 -121.975000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:10:16.529195+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28393\">\n<link>http://platial.com/place/28393</link>\n<title>Collins Hot Springs, WA</title>\n<description><![CDATA[Hot spring, temperature: 122  degress F, 50  degress C<br/>Tags: portland, nice, hot springs, soak<br /><br /><a href=\"http://platial.com/place/28393\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28393\">Grab this on Platial</a> ]]></description>\n<georss:point>45.701000 -121.728000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:16:24.648745+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/31685\">\n<link>http://platial.com/place/31685</link>\n<title>Darwin's Ltd.</title>\n<description><![CDATA[Nice little coffee shop/cafe, free Wifi, close enough to walk from Harvard Square.<br/>Address: 148 Mount Auburn St, Cambridge, MA<br/>Tags: coffee, beer, sandwiches, freewifi<br/><a href=\"http://platial.com/place/31685\"><img src=\"http://platial.comhttp://static.flickr.com/38/84885937_74fd3d1025_s.jpg\"/></a><br/><br /><br /><a href=\"http://platial.com/place/31685\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/31685\">Grab this on Platial</a> ]]></description>\n<georss:point>42.373974 -71.125053</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-10T09:24:08.152985+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28596\">\n<link>http://platial.com/place/28596</link>\n<title>Huckleberry Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: Boiling  degress F, Boiling  degress C<br /><br /><a href=\"http://platial.com/place/28596\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28596\">Grab this on Platial</a> ]]></description>\n<georss:point>44.115000 -110.684000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:32.283094+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28595\">\n<link>http://platial.com/place/28595</link>\n<title>South Entrance Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: 156  degress F, 69  degress C<br/><a href=\"http://platial.com/place/28595\"><img src=\"http://platial.comhttp://static.flickr.com/52/130989872_f1457f68b5_s.jpg\"/></a><br/><br /><br /><a href=\"http://platial.com/place/28595\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28595\">Grab this on Platial</a> ]]></description>\n<georss:point>44.142000 -110.656000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:30.279497+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28594\">\n<link>http://platial.com/place/28594</link>\n<title>Crawfish Creek Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: 136  degress F, 58  degress C<br/><a href=\"http://platial.com/place/28594\"><img src=\"http://platial.comhttp://static.flickr.com/52/128312256_d6a879924c_s.jpg\"/></a><br/><br /><br /><a href=\"http://platial.com/place/28594\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28594\">Grab this on Platial</a> ]]></description>\n<georss:point>44.157000 -110.699000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:28.280271+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28593\">\n<link>http://platial.com/place/28593</link>\n<title>Crawfish Creek Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: 138  degress F, 59  degress C<br /><br /><a href=\"http://platial.com/place/28593\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28593\">Grab this on Platial</a> ]]></description>\n<georss:point>44.165000 -110.723000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:20.364077+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28592\">\n<link>http://platial.com/place/28592</link>\n<title>Snake Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: 136  degress F, 58  degress C<br /><br /><a href=\"http://platial.com/place/28592\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28592\">Grab this on Platial</a> ]]></description>\n<georss:point>44.169000 -110.583000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:12.234974+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28591\">\n<link>http://platial.com/place/28591</link>\n<title>Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: 142  degress F, 61  degress C<br /><br /><a href=\"http://platial.com/place/28591\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28591\">Grab this on Platial</a> ]]></description>\n<georss:point>44.187000 -110.726000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:10.027857+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28590\">\n<link>http://platial.com/place/28590</link>\n<title>Hot Springs on Upper Snake River, WY</title>\n<description><![CDATA[Hot spring, temperature: 167  degress F, 75  degress C<br /><br /><a href=\"http://platial.com/place/28590\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28590\">Grab this on Platial</a> ]]></description>\n<georss:point>44.204000 -110.486000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:07.79658+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28589\">\n<link>http://platial.com/place/28589</link>\n<title>Hot Springs on lewis Lake, WY</title>\n<description><![CDATA[Hot spring, temperature: 154  degress F, 68  degress C<br /><br /><a href=\"http://platial.com/place/28589\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28589\">Grab this on Platial</a> ]]></description>\n<georss:point>44.276000 -110.636000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:05.683418+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28588\">\n<link>http://platial.com/place/28588</link>\n<title>Rustic Geyser, WY</title>\n<description><![CDATA[Hot spring, temperature: 199  degress F, 93  degress C<br /><br /><a href=\"http://platial.com/place/28588\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28588\">Grab this on Platial</a> ]]></description>\n<georss:point>44.282000 -110.506000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:03.66329+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28587\">\n<link>http://platial.com/place/28587</link>\n<title>Bechler River Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: 194  degress F, 90  degress C<br /><br /><a href=\"http://platial.com/place/28587\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28587\">Grab this on Platial</a> ]]></description>\n<georss:point>44.285000 -110.900000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:24:01.611442+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28586\">\n<link>http://platial.com/place/28586</link>\n<title>Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: Boiling  degress F, 201  degress C<br /><br /><a href=\"http://platial.com/place/28586\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28586\">Grab this on Platial</a> ]]></description>\n<georss:point>44.290000 -110.504000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:59.658699+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28585\">\n<link>http://platial.com/place/28585</link>\n<title>Heart Lake Geyser Basin, WY</title>\n<description><![CDATA[Hot spring, temperature:  Middle Group  degress F, 174  degress C<br /><br /><a href=\"http://platial.com/place/28585\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28585\">Grab this on Platial</a> ]]></description>\n<georss:point>44.299000 -110.517000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:57.181801+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28584\">\n<link>http://platial.com/place/28584</link>\n<title>Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: Boiling  degress F, 201  degress C<br /><br /><a href=\"http://platial.com/place/28584\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28584\">Grab this on Platial</a> ]]></description>\n<georss:point>44.307000 -110.526000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:55.240485+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28583\">\n<link>http://platial.com/place/28583</link>\n<title>Hot Springs on lewis Lake, WY</title>\n<description><![CDATA[Hot spring, temperature: 199  degress F, 93  degress C<br /><br /><a href=\"http://platial.com/place/28583\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28583\">Grab this on Platial</a> ]]></description>\n<georss:point>44.309000 -110.654000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:53.22295+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28582\">\n<link>http://platial.com/place/28582</link>\n<title>Shoshone Geyser Basin, WY</title>\n<description><![CDATA[Hot spring, temperature: 203  degress F, 95  degress C<br /><br /><a href=\"http://platial.com/place/28582\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28582\">Grab this on Platial</a> ]]></description>\n<georss:point>44.354000 -110.800000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:51.179049+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28581\">\n<link>http://platial.com/place/28581</link>\n<title>Hot Springs on Continental Divide, WY</title>\n<description><![CDATA[Hot spring, temperature: 189  degress F, 87  degress C<br /><br /><a href=\"http://platial.com/place/28581\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28581\">Grab this on Platial</a> ]]></description>\n<georss:point>44.401000 -110.936000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:49.077176+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28580\">\n<link>http://platial.com/place/28580</link>\n<title>Hot Springs on Upper Firehole River, WY</title>\n<description><![CDATA[Hot spring, temperature: Hot  degress F, Hot  degress C<br /><br /><a href=\"http://platial.com/place/28580\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28580\">Grab this on Platial</a> ]]></description>\n<georss:point>44.404000 -110.824000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:47.054664+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28579\">\n<link>http://platial.com/place/28579</link>\n<title>Summit Lake Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: 162  degress F, 72  degress C<br /><br /><a href=\"http://platial.com/place/28579\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28579\">Grab this on Platial</a> ]]></description>\n<georss:point>44.410000 -110.953000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:45.039394+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28578\">\n<link>http://platial.com/place/28578</link>\n<title>Lone Star Geyser Basin, WY</title>\n<description><![CDATA[Hot spring, temperature:  Footbridge  degress F, 183  degress C<br /><br /><a href=\"http://platial.com/place/28578\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28578\">Grab this on Platial</a> ]]></description>\n<georss:point>44.414000 -110.817000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:42.938808+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28577\">\n<link>http://platial.com/place/28577</link>\n<title>West. Thumb Geyser Basin, WY</title>\n<description><![CDATA[Hot spring, temperature: 203  degress F, 95  degress C<br /><br /><a href=\"http://platial.com/place/28577\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28577\">Grab this on Platial</a> ]]></description>\n<georss:point>44.417000 -110.570000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:40.90238+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28576\">\n<link>http://platial.com/place/28576</link>\n<title>Lone Star Geyser, WY</title>\n<description><![CDATA[Hot spring, temperature: 199  degress F, 93  degress C<br /><br /><a href=\"http://platial.com/place/28576\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28576\">Grab this on Platial</a> ]]></description>\n<georss:point>44.418000 -110.805000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:38.844625+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28575\">\n<link>http://platial.com/place/28575</link>\n<title>Smoke Jumper Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: 198  degress F, 92  degress C<br /><br /><a href=\"http://platial.com/place/28575\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28575\">Grab this on Platial</a> ]]></description>\n<georss:point>44.421000 -110.952000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:36.818513+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28574\">\n<link>http://platial.com/place/28574</link>\n<title>West. Thumb Geyser Basin, WY</title>\n<description><![CDATA[Hot spring, temperature: 196  degress F, 91  degress C<br /><br /><a href=\"http://platial.com/place/28574\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28574\">Grab this on Platial</a> ]]></description>\n<georss:point>44.422000 -110.574000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:34.767729+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28573\">\n<link>http://platial.com/place/28573</link>\n<title>Potts Hot Spring Basin, WY</title>\n<description><![CDATA[Hot spring, temperature: 203  degress F, 95  degress C<br /><br /><a href=\"http://platial.com/place/28573\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28573\">Grab this on Platial</a> ]]></description>\n<georss:point>44.433000 -110.581000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:32.749915+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28572\">\n<link>http://platial.com/place/28572</link>\n<title>Hot Springs, WY</title>\n<description><![CDATA[Hot spring, temperature: Hot  degress F, Hot  degress C<br /><br /><a href=\"http://platial.com/place/28572\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28572\">Grab this on Platial</a> ]]></description>\n<georss:point>44.433000 -110.813000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:30.829745+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28571\">\n<link>http://platial.com/place/28571</link>\n<title>Hot Springs on Continental Divide, WY</title>\n<description><![CDATA[Hot spring, temperature: Hot  degress F, Hot  degress C<br /><br /><a href=\"http://platial.com/place/28571\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28571\">Grab this on Platial</a> ]]></description>\n<georss:point>44.438000 -110.977000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:28.730401+00:00</dc:date>\n</item>\n<item rdf:about=\"http://platial.com/place/28570\">\n<link>http://platial.com/place/28570</link>\n<title>SouthEastern Group, WY</title>\n<description><![CDATA[Hot spring, temperature: 198  degress F, 92  degress C<br /><br /><a href=\"http://platial.com/place/28570\">Map this on Platial</a><br /> <a href=\"http://platial.com/place_grab/28570\">Grab this on Platial</a> ]]></description>\n<georss:point>44.459000 -110.817000</georss:point>\n<dc:creator>crschmidt</dc:creator>\n<dc:date>2006-01-03T23:23:26.706763+00:00</dc:date>\n</item>\n</rdf:RDF>"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/grid_inittiles.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <style type=\"text/css\">\n        #map {\n            width: 800px;\n            height: 475px;\n            border: 1px solid black;\n        }\n    </style>\n    <script src=\"../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        function init(){\n            var map = new OpenLayers.Map('map', {'maxResolution': 1.40625/2, tileSize: new OpenLayers.Size(256,256)});\n            ww = new OpenLayers.Layer.WMS( \"Basic\", \n            \"http://labs.metacarta.com/wms-c/Basic.py?\", \n            {layers:\"basic\"});\n            map.addLayers([ww]);\n            map.zoomToMaxExtent();\n            map.zoomIn();\n            map.zoomOut();\n            map.zoomOut();\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h1>Grid Test</h1>\n    <p>Map should display with two centered tiles. If there appear to be a combination of two zoom levels, then this test is failed, and something is broken in OpenLayers.</p>\n    <div id=\"map\"></div>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/index.html",
    "content": "<html>\n    <head>\n        <meta http-equiv=\"refresh\" content=\"0;url=run-tests.html\">\n    </head>\n    <body></body>\n</html>"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/list-tests.html",
    "content": "<ul id=\"testlist\">\n    <li>Animation.html</li>\n    <li>BaseTypes.html</li>\n    <li>BaseTypes/Bounds.html</li>\n    <li>BaseTypes/Class.html</li>\n    <li>BaseTypes/Date.html</li>\n    <li>BaseTypes/Element.html</li>\n    <li>BaseTypes/LonLat.html</li>\n    <li>BaseTypes/Pixel.html</li>\n    <li>BaseTypes/Size.html</li>\n    <li>Console.html</li>\n    <li>Control.html</li>\n    <li>Control/Attribution.html</li>\n    <li>Control/ArgParser.html</li>\n    <li>Control/Button.html</li>\n    <li>Control/CacheRead.html</li>\n    <li>Control/CacheWrite.html</li>\n    <li>Control/DragFeature.html</li>\n    <li>Control/DragPan.html</li>\n    <li>Control/DrawFeature.html</li>\n    <li>Control/EditingToolbar.html</li>\n    <li>Control/Geolocate.html</li>\n    <li>Control/GetFeature.html</li>\n    <li>Control/Graticule.html</li>\n    <li>Control/KeyboardDefaults.html</li>\n    <li>Control/LayerSwitcher.html</li>\n    <li>Control/Measure.html</li>\n    <li>Control/ModifyFeature.html</li>\n    <li>Control/ModifyFeature/BySegment.html</li>\n    <li>Control/MousePosition.html</li>\n    <li>Control/Navigation.html</li>\n    <li>Control/NavigationHistory.html</li>\n    <li>Control/NavToolbar.html</li>\n    <li>Control/OverviewMap.html</li>\n    <li>Control/Panel.html</li>\n    <li>Control/PanZoom.html</li>\n    <li>Control/PanZoomBar.html</li>\n    <li>Control/Permalink.html</li>\n    <li>Control/PinchZoom.html</li>\n    <li>Control/Scale.html</li>\n    <li>Control/ScaleLine.html</li>\n    <li>Control/SelectFeature.html</li>\n    <li>Control/Snapping.html</li>\n    <li>Control/Split.html</li>\n    <li>Control/TextButtonPanel.html</li>\n    <li>Control/TouchNavigation.html</li>\n    <li>Control/TransformFeature.html</li>\n    <li>Control/UTFGrid.html</li>\n    <li>Control/WMSGetFeatureInfo.html</li>\n    <li>Control/WMTSGetFeatureInfo.html</li>\n    <li>Control/PanPanel.html</li>\n    <li>Control/SLDSelect.html</li>\n    <li>Control/Zoom.html</li>\n    <li>Control/ZoomBox.html</li>\n    <li>Events.html</li>\n    <li>Events/buttonclick.html</li>\n    <li>Events/featureclick.html?visible</li>\n    <li>Extras.html</li>\n    <li>Feature.html</li>\n    <li>Feature/Vector.html</li>\n    <li>Filter.html</li>\n    <li>Filter/Comparison.html</li>\n    <li>Filter/FeatureId.html</li>\n    <li>Filter/Logical.html</li>\n    <li>Filter/Spatial.html</li>\n    <li>Format.html</li>\n    <li>Format/Atom.html</li>\n    <li>Format/ArcXML.html</li>\n    <li>Format/XML/VersionedOGC.html</li>\n    <li>Format/ArcXML/Features.html</li>\n    <li>Format/CQL.html</li>\n    <li>Format/EncodedPolyline.html</li>\n    <li>Format/GeoJSON.html</li>\n    <li>Format/GeoRSS.html</li>\n    <li>Format/GML.html</li>\n    <li>Format/GML/v2.html</li>\n    <li>Format/GML/v3.html</li>\n    <li>Format/GPX.html</li>\n    <li>Format/JSON.html</li>\n    <li>Format/KML.html</li>\n    <li>Format/OSM.html</li>\n    <li>Format/Text.html</li>\n    <li>Format/SLD.html</li>\n    <li>Format/SLD/v1_0_0.html</li>\n    <li>Format/SLD/v1_0_0_GeoServer.html</li>\n    <li>Format/Filter.html</li>\n    <li>Format/Filter/v1.html</li>\n    <li>Format/Filter/v1_0_0.html</li>\n    <li>Format/Filter/v1_1_0.html</li>\n    <li>Format/Filter/v2_0_0.html</li>\n    <li>Format/QueryStringFilter.html</li>\n    <li>Format/WCSCapabilities.html</li>\n    <li>Format/WCSCapabilities/v1.html</li>\n    <li>Format/WCSDescribeCoverage.html</li>\n    <li>Format/WCSDescribeCoverage/v1.html</li>\n    <li>Format/WFS.html</li>\n    <li>Format/WFSCapabilities.html</li>\n    <li>Format/WFSCapabilities/v1.html</li>\n    <li>Format/WFSCapabilities/v2.html</li>\n    <li>Format/WFSDescribeFeatureType.html</li>\n    <li>Format/WFST.html</li>\n    <li>Format/WFST/v1.html</li>\n    <li>Format/WFST/v1_0_0.html</li>\n    <li>Format/WFST/v1_1_0.html</li>\n    <li>Format/WFST/v2_0_0.html</li>\n    <li>Format/WKT.html</li>\n    <li>Format/WMC.html</li>\n    <li>Format/WMC/v1_1_0.html</li>\n    <li>Format/WMC/v1.html</li>\n    <li>Format/WMSCapabilities.html</li>\n    <li>Format/WMSCapabilities/v1_1_1.html</li>\n    <li>Format/WMSCapabilities/v1_1_1_WMSC.html</li>\n    <li>Format/WMSCapabilities/v1_3_0.html</li>\n    <li>Format/WMSDescribeLayer.html</li>\n    <li>Format/WMSGetFeatureInfo.html</li>\n    <li>Format/WMTSCapabilities.html</li>\n    <li>Format/WMTSCapabilities/v1_0_0.html</li>\n    <li>Format/WPSCapabilities/v1_0_0.html</li>\n    <li>Format/WPSDescribeProcess.html</li>\n    <li>Format/WPSExecute.html</li>\n    <li>Format/CSWGetDomain.html</li>\n    <li>Format/CSWGetDomain/v2_0_2.html</li>\n    <li>Format/CSWGetRecords.html</li>\n    <li>Format/CSWGetRecords/v2_0_2.html</li>\n    <li>Format/SOSCapabilities/v1_0_0.html</li>\n    <li>Format/SOSGetObservation.html</li>\n    <li>Format/SOSGetFeatureOfInterest.html</li>\n    <li>Format/OWSContext/v0_3_1.html</li>\n    <li>Format/OWSCommon/v1_0_0.html</li>\n    <li>Format/OWSCommon/v1_1_0.html</li>\n    <li>Format/OGCExceptionReport.html</li>\n    <li>Format/XLS/v1_1_0.html</li>\n    <li>Format/WCSGetCoverage.html</li>\n    <li>Format/TMSCapabilities.html</li>\n    <li>Format/XML.html</li>\n    <li>Geometry.html</li>\n    <li>Geometry/Collection.html</li>\n    <li>Geometry/Curve.html</li>\n    <li>Geometry/LinearRing.html</li>\n    <li>Geometry/LineString.html</li>\n    <li>Geometry/MultiLineString.html</li>\n    <li>Geometry/MultiPoint.html</li>\n    <li>Geometry/MultiPolygon.html</li>\n    <li>Geometry/Point.html</li>\n    <li>Geometry/Polygon.html</li>\n    <li>Handler.html</li>\n    <li>Handler/Box.html</li>\n    <li>Handler/Click.html</li>\n    <li>Handler/Drag.html</li>\n    <li>Handler/Pinch.html</li>\n    <li>Handler/Feature.html</li>\n    <li>Handler/Hover.html</li>\n    <li>Handler/Keyboard.html</li>\n    <li>Handler/MouseWheel.html</li>\n    <li>Handler/Path.html</li>\n    <li>Handler/Point.html</li>\n    <li>Handler/Polygon.html</li>\n    <li>Handler/RegularPolygon.html</li>\n    <li>Icon.html</li>\n    <li>Lang.html</li>\n    <li>Layer.html</li>\n    <li>Layer/ArcIMS.html</li> \n    <li>Layer/ArcGIS93Rest.html</li>\n    <li>Layer/ArcGISCache.html</li>\n    <li>Layer/Bing.html</li>\n    <li>Layer/EventPane.html</li>\n    <li>Layer/FixedZoomLevels.html</li>\n    <li>Layer/GeoRSS.html</li>\n    <li>Layer/Google/v3.html</li>\n    <li>Layer/Grid.html</li>\n    <li>Layer/HTTPRequest.html</li>\n    <li>Layer/Image.html</li>\n    <li>Layer/KaMap.html</li>\n    <li>Layer/MapGuide.html</li>\n    <li>Layer/MapServer.html</li>\n    <li>Layer/Markers.html</li>\n    <li>Layer/PointGrid.html</li>\n    <li>Layer/PointTrack.html</li>\n    <li>Layer/SphericalMercator.html</li>\n    <li>Layer/Text.html</li>\n    <li>Layer/TileCache.html</li>\n    <li>Layer/TMS.html</li>\n    <li>Layer/UTFGrid.html</li>\n    <li>Layer/Vector.html</li>\n    <li>Layer/Vector/RootContainer.html</li>\n    <li>Layer/WMS.html</li>\n    <li>Layer/WMTS.html</li>\n    <li>Layer/WrapDateLine.html</li>\n    <li>Layer/XYZ.html</li>\n    <li>Layer/OSM.html</li>\n    <li>Map.html</li>\n    <li>Marker.html</li>\n    <li>Marker/Box.html</li>\n    <li>OpenLayers1.html</li>\n    <li>OpenLayers2.html</li>\n    <li>OpenLayers3.html</li>\n    <li>OpenLayers4.html</li>\n    <li>OpenLayersJsFiles.html</li>\n    <li>SingleFile1.html</html>\n    <li>SingleFile2.html</html>\n    <li>SingleFile3.html</html>\n    <li>Popup.html?visible</li>\n    <li>Popup/Anchored.html</li>\n    <li>Popup/FramedCloud.html</li>\n    <li>Projection.html</li>\n    <li>Protocol.html</li>\n    <li>Protocol/HTTP.html</li>\n    <li>Protocol/Script.html</li>\n    <li>Protocol/WFS.html</li>\n    <li>Protocol/CSW.html</li>\n    <li>Protocol/SOS.html</li>\n    <li>Renderer.html</li>\n    <li>Renderer/Canvas.html</li>\n    <li>Renderer/Elements.html</li>\n    <li>Renderer/SVG.html</li>\n    <li>Renderer/VML.html</li>\n    <li>Request.html</li>\n    <li>Request/XMLHttpRequest.html</li>\n    <li>Rule.html</li>\n    <li>Strategy.html</li>\n    <li>Strategy/BBOX.html</li>\n    <li>Strategy/Cluster.html</li>\n    <li>Strategy/Filter.html</li>\n    <li>Strategy/Fixed.html</li>\n    <li>Strategy/Paging.html</li>\n    <li>Strategy/Save.html</li>\n    <li>Strategy/Refresh.html</li>\n    <li>Style.html</li>\n    <li>Style2.html</li>\n    <li>StyleMap.html</li>\n    <li>Symbolizer.html</li>\n    <li>Symbolizer/Line.html</li>\n    <li>Symbolizer/Point.html</li>\n    <li>Symbolizer/Polygon.html</li>\n    <li>Symbolizer/Raster.html</li>\n    <li>Symbolizer/Text.html</li>\n    <li>Tile.html</li>\n    <li>Tile/Image.html</li>\n    <li>Tile/Image/IFrame.html</li>\n    <li>Tile/UTFGrid.html</li>\n    <li>TileManager.html</li>\n    <li>Tween.html</li>\n    <li>Kinetic.html</li>\n    <li>Util.html?visible</li>\n    <li>Util_w3c.html?visible</li>\n    <li>Util/vendorPrefix.html</li>\n    <li>WPSClient.html</li>\n    <li>WPSProcess.html</li>\n    <li>deprecated/Ajax.html</li>\n    <li>deprecated/Util.html</li>\n    <li>deprecated/BaseTypes/Class.html</li>\n    <li>deprecated/BaseTypes/Element.html</li>\n    <li>deprecated/Control/MouseToolbar.html</li>\n    <li>deprecated/Geometry/Rectangle.html</li>\n    <li>deprecated/Layer/GML.html</li>\n    <li>deprecated/Layer/MapServer.html</li>\n    <li>deprecated/Layer/MapServer/Untiled.html</li>\n    <li>deprecated/Layer/WFS.html</li>\n    <li>deprecated/Layer/WMS.html</li>\n    <li>deprecated/Layer/WMS/Post.html</li>\n    <li>deprecated/Popup/AnchoredBubble.html</li>\n    <li>deprecated/Protocol/SQL.html</li>\n    <li>deprecated/Protocol/SQL/Gears.html</li>\n    <li>deprecated/Renderer/SVG2.html</li>\n    <li>deprecated/Layer/Yahoo.html</li>\n    <li>deprecated/Tile/WFS.html</li>\n</ul>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/ajax.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <title>XHR Acceptance Test</title>\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var url = \"ajax.txt\";\n        function sendSynchronous(){\n            var request = OpenLayers.Request.GET({\n                url: url,\n                async: false,\n                callback: function() {\n                    document.getElementById('send_sync').value += 'request completed\\n';\n                }\n            });\n            document.getElementById('send_sync').value += 'other processing\\n';\n        }\n        function sendAsynchronous(){\n            var request = OpenLayers.Request.GET({\n                url: url,\n                callback: function() {\n                    document.getElementById('send_sync').value += 'request completed\\n';\n                }\n            });\n            document.getElementById('send_sync').value += 'other processing\\n';\n        }\n        function sendAndAbort(){\n            var request = OpenLayers.Request.GET({\n                url: url,\n                callback: function() {\n                    document.getElementById('send_sync').value += 'never called\\n';\n                }\n            });\n            request.abort();\n            document.getElementById('send_sync').value += 'other processing\\n';\n        }\n\n        </script>\n    </head>\n    <body >\n        <button onclick=\"sendSynchronous()\">synchronous</button>\n        expected output: \"request completed\" then \"other processing\"<br />\n        <button onclick=\"sendAsynchronous()\">asynchronous</button>\n        expected output: \"other processing\" then \"request completed\"<br />\n        <button onclick=\"sendAndAbort()\">send and abort</button>\n        expected output: \"other processing\" (and not \"never called\")<br />\n        <textarea id=\"send_sync\" rows=\"6\"></textarea><br />\n        <button onclick=\"document.getElementById('send_sync').value = ''\">Clear</button>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/ajax.txt",
    "content": "one fake text file"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/alloverlays-mixed.html",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <title>OpenLayers Mixed allOverlays Test</title>\n    <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\">\n    <link rel=\"stylesheet\" href=\"../../theme/default/google.css\" type=\"text/css\">\n    <link rel=\"stylesheet\" href=\"../../examples/style.css\" type=\"text/css\">\n    <script src=\"http://maps.google.com/maps/api/js?sensor=false&amp;v=3.6\"></script>\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var map;\n\n        function init() {\n            map = new OpenLayers.Map('map', {allOverlays: true});\n            map.addControl(new OpenLayers.Control.LayerSwitcher());\n            \n            var osm = new OpenLayers.Layer.OSM(\"OSM\", null, {\n                visibility: false,\n                maxResolution: 78271.516953125,\n                serverResolutions: [156543.03390625, 78271.516953125, 39135.7584765625, 19567.87923828125, 9783.939619140625, 4891.9698095703125, 2445.9849047851562, 1222.9924523925781, 611.4962261962891, 305.74811309814453, 152.87405654907226, 76.43702827453613, 38.218514137268066, 19.109257068634033, 9.554628534317017, 4.777314267158508, 2.388657133579254, 1.194328566789627, 0.5971642833948135]\n            });\n            var google = new OpenLayers.Layer.Google(\"Google\");\n            var wms = new OpenLayers.Layer.WMS(\"WMS\",\n                \"http://vmap0.tiles.osgeo.org/wms/vmap0\",\n                {layers: 'basic'}, {\n                    opacity: .5,\n                    maxExtent: new OpenLayers.Bounds(\n                        -20037508.34, -20037508.34, 20037508.34, 20037508.34\n                    ),\n                    wrapDateLine: true\n                }\n            );\n\n            map.addLayers([osm, google, wms]);\n\n            map.setCenter(new OpenLayers.LonLat(0, 0), 3);\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h1 id=\"title\">Mixed allOverlays Test</h1>\n\n    <div id=\"map\" class=\"smallmap\"></div>\n\n    <div id=\"docs\">\n     <p>\n        The map image aboved should show a Google layer and an opaque WMS\n        layer. They both should align (look at the border of West Africa)\n    </p>\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/arcims-2117.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <title>ArcIMS Test Ticket #2117</title>\n    <link rel=\"stylesheet\" href=\"../theme/default/style.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../examples/style.css\" type=\"text/css\" />\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var lon = 0;\n        var lat = 0;\n        var zoom = 1;\n        var map, layer;\n\n        function init(){\n            OpenLayers.ProxyHost = \"../../examples/proxy.cgi?url=\";\n            \n            map = new OpenLayers.Map( 'map' );\n            \n            var options = {\n              serviceName: \"OpenLayers_Sample\",\n              async: true,\n\t\t\t\t\t\t\tlayers: [{\n\t\t\t\t\t\t\t\tid:1,\n\t\t\t\t\t\t\t\tvisible:'true',\n\t\t\t\t\t\t\t\t/*query:{\n\t\t\t\t\t\t\t\t\twhere: '1=1',\n\t\t\t\t\t\t\t\t\tspatialfilter: true\n\t\t\t\t\t\t\t\t},*/\n\t\t\t\t\t\t\t\trenderer:{\n\t\t\t\t\t\t\t\t\ttype: 'valuemaplabel',\n\t\t\t\t\t\t\t\t\tlookupfield: 'FIPS_ID',\n\t\t\t\t\t\t\t\t\tlabelfield: 'FIPS_CNTRY',\n\t\t\t\t\t\t\t\t\texacts:[{\n\t\t\t\t\t\t\t\t\t\tvalue: '227',\n\t\t\t\t\t\t\t\t\t\tsymbol: {\n\t\t\t\t\t\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\t\t\t\t\t\tantialiasing: 'true',\n\t\t\t\t\t\t\t\t\t\t\tinterval: 6,\n\t\t\t\t\t\t\t\t\t\t\tblockout: '255,255,255',\n\t\t\t\t\t\t\t\t\t\t\tfont: 'Arial',\n\t\t\t\t\t\t\t\t\t\t\tfontcolor: '0,0,0',\n\t\t\t\t\t\t\t\t\t\t\tfontsize: 11,\n\t\t\t\t\t\t\t\t\t\t\ttransparency: 0.7\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},{\n\t\t\t\t\t\t\t\t\t\tvalue: '150',\n\t\t\t\t\t\t\t\t\t\tsymbol: {\n\t\t\t\t\t\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\t\t\t\t\t\tantialiasing: 'true',\n\t\t\t\t\t\t\t\t\t\t\tinterval: 6,\n\t\t\t\t\t\t\t\t\t\t\tblockout: '255,255,255',\n\t\t\t\t\t\t\t\t\t\t\tfont: 'Arial',\n\t\t\t\t\t\t\t\t\t\t\tfontcolor: '0,0,0',\n\t\t\t\t\t\t\t\t\t\t\tfontsize: 11,\n\t\t\t\t\t\t\t\t\t\t\ttransparency: 0.7\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t},{\n\t\t\t\t\t\t\t\t\t\tvalue: '75',\n\t\t\t\t\t\t\t\t\t\tsymbol: {\n\t\t\t\t\t\t\t\t\t\t\ttype: 'text',\n\t\t\t\t\t\t\t\t\t\t\tantialiasing: 'true',\n\t\t\t\t\t\t\t\t\t\t\tinterval: 6,\n\t\t\t\t\t\t\t\t\t\t\tblockout: '255,255,255',\n\t\t\t\t\t\t\t\t\t\t\tfont: 'Arial',\n\t\t\t\t\t\t\t\t\t\t\tfontcolor: '0,0,0',\n\t\t\t\t\t\t\t\t\t\t\tfontsize: 11,\n\t\t\t\t\t\t\t\t\t\t\ttransparency: 0.7\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}]\n            };\n            \n            layer = new OpenLayers.Layer.ArcIMS( \"Global Sample Map\",\n                    \"http://sample.avencia.com/servlet/com.esri.esrimap.Esrimap\", options );\n            map.addLayer(layer);\n\n            map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);\n            map.addControl( new OpenLayers.Control.LayerSwitcher() );\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h1 id=\"title\">ArcIMS Test Ticket #2117</h1>\n\n    <div id=\"tags\">\n    </div>\n    <p id=\"shortdesc\">\n        <a href=\"http://trac.openlayers.org/ticket/2117\">Testing ticket #2117</a>\n    </p>\n\n    <div id=\"map\" class=\"smallmap\"></div>\n\n    <div id=\"docs\">\n        This is an example of a bug in the ArcXML format writer.\n         If you don't see a map, it's broken.\n    </div>\n\n  </body>\n</html>\n\n\n\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/arkansas.rss",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><rss xmlns:atom=\"http://www.w3.org/2005/Atom\" xmlns:georss=\"http://www.georss.org/georss\" version=\"2.0\"><channel><title>topp:states</title><description>Feed auto-generated by GeoServer</description><link><![CDATA[http://localhost:8080/geoserver/wms?format_options=ENCODING:simple;&width=512&featureid=states.21&transparent=false&version=1.1.1&service=wms&srs=EPSG:4326&styles=population&height=216&bbox=-124.731422,24.955967,-66.969849,49.371735&request=GetMap&layers=topp:states&format=application/rss+xml]]></link><atom:link href=\"http://localhost:8080/geoserver/wms?format_options=ENCODING:simple;&amp;width=512&amp;featureid=states.21&amp;transparent=false&amp;version=1.1.1&amp;service=wms&amp;srs=EPSG:4326&amp;styles=population&amp;height=216&amp;bbox=-124.731422,24.955967,-66.969849,49.371735&amp;request=GetMap&amp;layers=topp:states&amp;format=application/rss+xml\" rel=\"self\"/><item><title>Arkansas\n</title><link><![CDATA[http://localhost:8080/geoserver/wfs?request=getfeature&service=wfs&version=1.0.0&featureid=states.21]]></link><guid><![CDATA[http://localhost:8080/geoserver/wfs?request=getfeature&service=wfs&version=1.0.0&featureid=states.21]]></guid><description><![CDATA[This is the state of Arkansas.  \n2350725.0 people live in an area of 134875.075 square \nkilometers, and only 5096.0 take public transportation.\n<br>\n<br>\n\nMap by:<br> <a href=\"http://topp.openplans.org/geoserver\"><img alt=\"TOPP\" src=\"http://topp.openplans.org/images/logo.jpg\"></a>\n]]></description><georss:polygon>34.19665500000001 -94.461479 34.508326999999994 -94.452408 34.735504000000006 -94.44574 34.929050000000004 -94.439102 35.400454999999994 -94.428337 35.641003 -94.468269 35.760227 -94.485718 36.106753999999995 -94.542198 36.164444 -94.552895 36.478714 -94.607231 36.489338000000004 -94.617035 36.49095199999999 -94.080849 36.489716 -93.857323 36.489891 -93.59626 36.490196 -93.328163 36.490616 -93.297142 36.489819 -92.852104 36.489918 -92.777466 36.490855999999994 -92.522888 36.491596 -92.146164 36.491371 -92.127487 36.490955 -91.688416 36.490376 -91.45285 36.491039 -91.411659 36.487953000000005 -91.133827 36.489204 -90.804314 36.490962999999994 -90.581619 36.492751999999996 -90.224373 36.491814000000005 -90.150162 36.45741700000001 -90.137276 36.453896 -90.117226 36.422565000000006 -90.123833 36.404915 -90.116829 36.39738800000001 -90.080177 36.382553 -90.052063 36.362606 -90.050201 36.325333 -90.067635 36.300472 -90.049751 36.272273999999996 -90.066093 36.257996000000006 -90.109917 36.21207 -90.131218 36.196940999999995 -90.161308 36.172565000000006 -90.219223 36.161148 -90.232224 36.137089 -90.23484 36.118763 -90.263702 36.115905999999995 -90.284752 36.091656 -90.315239 35.989586 -90.37896 35.991158 -90.283455 35.996838 -89.963203 35.999877999999995 -89.721756 35.966324 -89.713135 35.93782 -89.664192 35.913799 -89.645401 35.894287000000006 -89.649338 35.885647000000006 -89.66465 35.911427 -89.714684 35.915012000000004 -89.737976 35.896812 -89.762909 35.884102 -89.766273 35.871418000000006 -89.757713 35.842037000000005 -89.701439 35.827515000000005 -89.700829 35.807036999999994 -89.735939 35.817420999999996 -89.759796 35.805553 -89.790382 35.774223000000006 -89.799904 35.758269999999996 -89.827042 35.748192 -89.859871 35.754836999999995 -89.909782 35.734268 -89.951035 35.712486 -89.952034 35.676266 -89.929741 35.655972000000006 -89.893402 35.673306 -89.865181 35.671062000000006 -89.857246 35.645222000000004 -89.849197 35.629745 -89.863838 35.633335 -89.877441 35.603104 -89.957047 35.578593999999995 -89.958031 35.546059 -89.921661 35.52923199999999 -89.931175 35.526900999999995 -89.947548 35.532291 -89.962273 35.561676000000006 -89.989586 35.552414 -90.033051 35.542846999999995 -90.040901 35.51244 -90.041817 35.445454 -89.999565 35.417103 -90.046783 35.41341 -90.060295 35.426506 -90.073936 35.472342999999995 -90.074844 35.478207 -90.08223 35.473568 -90.101959 35.442524000000006 -90.137276 35.423716999999996 -90.172676 35.384254 -90.167816 35.383044999999996 -90.140167 35.4076 -90.132469 35.41768999999999 -90.112244 35.418282000000005 -90.085159 35.406527999999994 -90.075478 35.381508 -90.087135 35.365982 -90.105621 35.345591999999996 -90.098701 35.314685999999995 -90.106346 35.30624400000001 -90.15699 35.282566 -90.169746 35.264056999999994 -90.152122 35.263847 -90.105942 35.254397999999995 -90.090103 35.212738 -90.068962 35.191833 -90.073303 35.166916 -90.062431 35.147385 -90.064537 35.12505 -90.082924 35.13653600000001 -90.14373 35.129611999999995 -90.164474 35.10864599999999 -90.178345 35.077827 -90.169083 35.040897 -90.195709 35.048458 -90.291809 35.000693999999996 -90.305351 34.978481 -90.299507 34.94976 -90.248169 34.938903999999994 -90.241898 34.920731 -90.242844 34.896511000000004 -90.266708 34.88269 -90.296272 34.864959999999996 -90.299446 34.851776 -90.301552 34.850266000000005 -90.322823 34.860577000000006 -90.341423 34.841038 -90.403931 34.832268 -90.42231 34.835353999999995 -90.433548 34.872643 -90.427841 34.88618099999999 -90.438087 34.88092399999999 -90.470528 34.857727 -90.474716 34.82521800000001 -90.451904 34.79966400000001 -90.466705 34.76075 -90.448868 34.741198999999995 -90.451431 34.726833 -90.485924 34.729855 -90.504417 34.748371000000006 -90.516968 34.765784999999994 -90.498734 34.789833 -90.501282 34.805603000000005 -90.516045 34.807323 -90.52726 34.790336999999994 -90.547745 34.713252999999995 -90.533279 34.702068 -90.513565 34.704254000000006 -90.469978 34.672039 -90.466225 34.638065 -90.508812 34.636894 -90.538963 34.65180599999999 -90.547546 34.685947 -90.539062 34.700287 -90.561058 34.645611 -90.5793 34.627815 -90.58799 34.604744 -90.577614 34.555649 -90.530617 34.543327000000005 -90.537148 34.532509000000005 -90.565681 34.520222000000004 -90.580345 34.496506 -90.59005 34.453945000000004 -90.574402 34.432998999999995 -90.579124 34.40459799999999 -90.60379 34.36591 -90.657242 34.330006 -90.657814 34.31797400000001 -90.679337 34.320145 -90.689377 34.3634 -90.681137 34.377871999999996 -90.687485 34.37216600000001 -90.75531 34.363913999999994 -90.761856 34.317719 -90.747757 34.278976 -90.758255 34.299957000000006 -90.792526 34.299347 -90.806419 34.277339999999995 -90.823837 34.229534 -90.83136 34.219162 -90.863411 34.250195000000005 -90.928436 34.23467599999999 -90.933708 34.20483 -90.921486 34.190544 -90.822922 34.166172 -90.80751 34.148658999999995 -90.828865 34.147544999999994 -90.846611 34.185649999999995 -90.928917 34.155804 -90.953346 34.125941999999995 -90.942245 34.102749 -90.906311 34.10095200000001 -90.866333 34.040710000000004 -90.886345 34.031288 -90.95047 34.010998 -90.973366 33.994606000000005 -90.975273 33.978874000000005 -90.961128 33.967461 -90.96479 33.960815 -90.986816 33.968372 -91.000259 33.990528 -91.009544 33.985699 -91.031059 34.006096 -91.069695 33.994468999999995 -91.088852 33.974644 -91.075706 33.936306 -91.018463 33.867081 -91.061371 33.843525 -91.054817 33.816586 -91.028854 33.798897 -90.990372 33.78533899999999 -90.984039 33.77154899999999 -90.995377 33.76397299999999 -91.018433 33.769554 -91.043404 33.786525999999995 -91.066391 33.776439999999994 -91.105415 33.780086999999995 -91.136986 33.771820000000005 -91.142891 33.723225 -91.138 33.71244 -91.128944 33.70823300000001 -91.104568 33.719357 -91.056213 33.70549 -91.038826 33.683216 -91.037834 33.662586000000005 -91.083771 33.677527999999995 -91.121048 33.718315000000004 -91.1633 33.708965000000006 -91.211678 33.690723000000006 -91.215141 33.669945 -91.205307 33.637032000000005 -91.154404 33.616161000000005 -91.15065 33.57724399999999 -91.168022 33.57468 -91.187805 33.590481 -91.22673 33.55635100000001 -91.227631 33.539276 -91.213486 33.538506 -91.204102 33.52334999999999 -91.182846 33.512012 -91.180405 33.473395999999994 -91.207642 33.459453999999994 -91.22715 33.443443 -91.232849 33.447388000000004 -91.18177 33.466644 -91.17173 33.504368 -91.174179 33.51178 -91.164978 33.493190999999996 -91.128799 33.469673 -91.118958 33.452831 -91.119713 33.443123 -91.130516 33.422112 -91.19883 33.414299 -91.204163 33.39183 -91.184982 33.388878000000005 -91.137634 33.414897999999994 -91.099129 33.462856 -91.0858 33.466206 -91.073761 33.460010999999994 -91.060982 33.431797 -91.061516 33.410179 -91.07869 33.393406 -91.106941 33.359402 -91.130424 33.322384 -91.141747 33.268505000000005 -91.122505 33.249210000000005 -91.102905 33.29235799999999 -91.076324 33.293575000000004 -91.053833 33.281921 -91.040428 33.245780999999994 -91.054543 33.225697 -91.092003 33.161602 -91.086319 33.145084 -91.095856 33.131069 -91.12133 33.150288 -91.177628 33.140465000000006 -91.195503 33.113224 -91.190536 33.090652000000006 -91.14679 33.065571000000006 -91.11779 33.04727200000001 -91.123985 33.040431999999996 -91.156685 33.021709 -91.160675 33.013039000000006 -91.162132 33.013476999999995 -91.254616 33.013419999999996 -91.427528 33.013874 -91.454353 33.010025 -92.063309 33.016701 -92.717079 33.018135 -92.978828 33.019238 -93.232376 33.021393 -93.478897 33.021152 -93.511742 33.022594 -93.809753 33.023289000000005 -94.03875 33.270325 -94.036507 33.555912000000006 -94.035927 33.577213 -94.061432 33.583954000000006 -94.086655 33.572998 -94.098701 33.567085000000006 -94.155167 33.593773 -94.159515 33.58507899999999 -94.205345 33.557987 -94.210884 33.561535000000006 -94.235367 33.585719999999995 -94.223038 33.592422 -94.237236 33.561736999999994 -94.274544 33.584605999999994 -94.272079 33.589332999999996 -94.278984 33.579853 -94.29882 33.556934 -94.302383 33.57313499999999 -94.328751 33.547684000000004 -94.370758 33.560303000000005 -94.395264 33.572661999999994 -94.372307 33.590042 -94.370628 33.593327 -94.379112 33.57495900000001 -94.393417 33.573486 -94.40657 33.59714099999999 -94.428467 33.596503999999996 -94.443329 33.604347000000004 -94.451553 33.616844 -94.436333 33.636444 -94.435913 33.631966000000006 -94.476486 33.939198000000005 -94.468376 34.19665500000001 -94.461479</georss:polygon></item></channel></rss>"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/big-georss.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n      <title>OpenLayers GML Layer Example</title>\n    <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../examples/style.css\" type=\"text/css\" />\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var lon = 5;\n        var lat = 40;\n        var zoom = 5;\n        var map, layer;\n\n        function init(){\n            map = new OpenLayers.Map('map');\n            layer = new OpenLayers.Layer.WMS( \"OpenLayers WMS\",\n                    \"http://labs.metacarta.com/wms/vmap0\", {layers: 'basic'} );\n            map.addLayer(layer);\n            map.zoomToExtent(new OpenLayers.Bounds(-94.617035,33.010025,-89.645401,36.492752));\n            map.addLayer(new OpenLayers.Layer.Vector(\"arkansas\", {\n                protocol: new OpenLayers.Protocol.HTTP({\n                    url: \"arkansas.rss\",\n                    format: new OpenLayers.Format.GeoRSS()\n                }),\n                strategies: [new OpenLayers.Strategy.Fixed()]\n            }));\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <p>Does this map look like arkansas?</p>\n    <div id=\"map\" class=\"smallmap\"></div>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/box-quirks.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <title>Box Handler Quirks Mode Test</title>\n    <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../examples/style.css\" type=\"text/css\" />\n    <style type=\"text/css\">\n    /* simulate quirks mode (traditional box model) in browsers other than IE */\n    div {\n        box-sizing: border-box;\n        -moz-box-sizing: border-box;\n        -ms-box-sizing: border-box;\n        -webkit-box-sizing: border-box;\n    }\n    \n    .olHandlerBoxZoomBox {\n        border: 20px solid red;\n        border-left-width: 10px;\n        border-bottom-width: 30px;\n    }\n    </style>\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var map, layer;\n        function init(){\n            map = new OpenLayers.Map( 'map' );\n            layer = new OpenLayers.Layer.WMS( \"OpenLayers WMS\",\n                    \"http://vmap0.tiles.osgeo.org/wms/vmap0\",\n                    {layers: 'basic'} );\n            map.addLayer(layer);\n            map.zoomToMaxExtent();\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h1 id=\"title\">Box handler Quirks Mode Test</h1>\n\n    <div id=\"shortdesc\">Test the correct appearance of the ZoomBox in quirks mode</div>\n\n    <div id=\"map\" class=\"smallmap\"></div>\n\n    <div id=\"docs\">\n        <p>For the box to be positioned correctly, we need to know the\n            width of the borders.</p>\n        <p>Shift-click on the map. A red box should be visible around the mouse\n            cursor position, with 20 pixels to the top and right, 10 pixels to\n            the left and 30 pixels to the bottom edge of the box.</p>\n        <p>Drag the box both to the top-left and the bottom-right. The cursor\n            should always be at the top-left or bottom-right inner corner of\n            the box.</p>\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/box-strict.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" \n    \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n  <head>\n    <title>Box Handler Strict Mode Test</title>\n    <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../examples/style.css\" type=\"text/css\" />\n    <style type=\"text/css\">\n    .olHandlerBoxZoomBox {\n        border: 20px solid red;\n        border-left-width: 10px;\n        border-bottom-width: 30px;\n    }\n    </style>\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var map, layer;\n        function init(){\n            map = new OpenLayers.Map( 'map' );\n            layer = new OpenLayers.Layer.WMS( \"OpenLayers WMS\",\n                    \"http://vmap0.tiles.osgeo.org/wms/vmap0\",\n                    {layers: 'basic'} );\n            map.addLayer(layer);\n            map.zoomToMaxExtent();\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h1 id=\"title\">Box Handler Strict Mode Test</h1>\n\n    <div id=\"shortdesc\">Test the correct appearance of the ZoomBox in strict mode</div>\n\n    <div id=\"map\" class=\"smallmap\"></div>\n\n    <div id=\"docs\">\n        <p>For the box to be positioned correctly, we need to know the\n            width of the borders.</p>\n        <p>Shift-click on the map. A red box should be visible around the mouse\n            cursor position, with 20 pixels to the top and right, 10 pixels to\n            the left and 30 pixels to the bottom edge of the box.</p>\n        <p>Drag the box both to the top-left and the bottom-right. The cursor\n            should always be at the top-left or bottom-right inner corner of\n            the box.</p>\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/clip-features-svg.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n<title>SVG inValidRange Test Case</title><link\nhref=\"../../theme/default/style.css\"\nrel=\"stylesheet\" type=\"text/css\">\n<style>\n        #map {\n            width: 512px;\n            height: 512px;\n            border: 1px solid #4B3624;\n            background: White;\n        }\n\n        /* avoid pink tiles */\n        .olImageLoadError {\n            background-color: transparent !important;\n        }\n\n       .olControlAttribution { bottom: 0px!important }\n</style>\n<script src=\"../../lib/OpenLayers.js\"\ntype=\"text/javascript\"></script>\n<script type=\"text/javascript\">var map;\n\n      // increase reload attempts \n      OpenLayers.IMAGE_RELOAD_ATTEMPTS = 3;\n\n      var vectorLayer;\n      var markerLayer, boxes, newPoint;\n\n      function init(){\n              var options = {\n                  projection: new OpenLayers.Projection(\"EPSG:900913\"),\n                  units: \"m\",\n                  numZoomLevels: 19,\n                  maxResolution: 156543.0339,\n                  maxExtent: new OpenLayers.Bounds(-20037508, -20037508,\n                                                   20037508, 20037508.34)\n              };\n              map = new OpenLayers.Map('map', options);\n\n              map.addControl(new OpenLayers.Control.MousePosition());\n\n              vectorLayer = new OpenLayers.Layer.Vector(\"Trails\", {isBaseLayer: true});\n              markerLayer = new OpenLayers.Layer.Markers(\"WayPoints\");\n\n              map.addLayers([vectorLayer,markerLayer]);\n\n              var style_trail = OpenLayers.Util.extend({},\n                  OpenLayers.Feature.Vector.style['default']);\n              style_trail.strokeColor = \"green\";\n              style_trail.strokeWidth = 5;\n\n              var pointList = [];\n\n              newPoint = new OpenLayers.Geometry.Point(-13653735.8487833,5726045.3578081);\n              pointList.push(newPoint);\n              newPoint = new OpenLayers.Geometry.Point(-13653731.3960036,5726056.5070679);\n              pointList.push(newPoint);\n              newPoint = new OpenLayers.Geometry.Point(-13653730.8394062,5726044.7207079);\n              pointList.push(newPoint);\n              newPoint = new OpenLayers.Geometry.Point(-13653743.1958697,5726043.9243328);\n              pointList.push(newPoint);\n              newPoint = new OpenLayers.Geometry.Point(-13653754.1051798,5726046.9505586);\n              pointList.push(newPoint);\n              newPoint = new OpenLayers.Geometry.Point(-13653760.4503907,5726056.5070679);\n              pointList.push(newPoint);\n              newPoint = new OpenLayers.Geometry.Point(-13653767.4635187,5726065.5857612);\n              pointList.push(newPoint);\n              newPoint = new OpenLayers.Geometry.Point(-13653830.136392,5726052.2066375);\n              pointList.push(newPoint);\n              newPoint = new OpenLayers.Geometry.Point(-13653846.5003571,5726042.3315828);\n              pointList.push(newPoint);\n\n              var lineFeature = new OpenLayers.Feature.Vector(\n                      new OpenLayers.Geometry.LineString(pointList));\n              lineFeature.fid = 52730;\n              vectorLayer.addFeatures(lineFeature);\n\n              pointList = [];\n              \n              newPoint = new OpenLayers.Geometry.Point(-12250153.3626406,4852001.6114048);\n              pointList.push(newPoint);\n              newPoint = new OpenLayers.Geometry.Point(-12194315.5060664,4800503.5113048);\n              pointList.push(newPoint);\n              newPoint = new OpenLayers.Geometry.Point(-12180445.0975155,4873109.008858);\n              pointList.push(newPoint);\n\n              lineFeature = new OpenLayers.Feature.Vector(\n                  new OpenLayers.Geometry.LineString(pointList),null,style_trail);\n              lineFeature.fid = 52751;\n              vectorLayer.addFeatures([lineFeature]);\n\n              var size = new OpenLayers.Size(15, 15);\n              var offset = new OpenLayers.Pixel(-(size.w/2), -size.h);\n              var icon = new OpenLayers.Icon('../../img/marker.png', size, offset);\n              markerLayer.addMarker(new OpenLayers.Marker(\n                  new OpenLayers.LonLat((newPoint.x + 400), (newPoint.y - 400)), icon));\n\n              map.setCenter(new OpenLayers.LonLat(newPoint.x, newPoint.y), 13)\n      }\n\n      function zoomToScale(zoom) {\n         if (zoom == 8) map.zoomToScale(3385.5001275);\n         else if(zoom == 7) map.zoomToScale(6771.000255);\n         else if (zoom == 6) map.zoomToScale(13542);\n         else if (zoom == 5) map.zoomToScale(27084.001020);\n         else if (zoom == 4) map.zoomToScale(54168.001020);\n         else if (zoom == 3) map.zoomToScale(108337);\n         else if (zoom == 2) map.zoomToScale(3466752.1306573446);\n         else if (zoom == 1) map.zoomToScale(13867008.522629378);\n         else if (zoom == 0) map.zoomToScale(55468034.09051751);\n      }\n\n</script>\n</head>\n<body onLoad=\"init()\">\n<h1 id=\"title\">SVG inValidRange Clipping Test Case</h1>\n<p>Behavior before fixing #1631: Push Zoom 5.  You see lines.  Push\nZoom 6.  No lines.</p>\n    <div id=\"map\">\n    </div>\n    <button onClick=\"zoomToScale(5);\">Zoom 5</button>\n    <button onClick=\"zoomToScale(6);\">Zoom 6</button>\n    <button onClick=\"zoomToScale(7);\">Zoom 7</button>\n    <button onClick=\"zoomToScale(8);\">Zoom 8</button>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/dateline-sketch.html",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <title>OpenLayers: Sketch handlers crossing the dateline</title>\n    <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\">\n    <link rel=\"stylesheet\" href=\"../../examples/style.css\" type=\"text/css\">\n    <style type=\"text/css\">\n        #map {\n            height: 512px;\n        }\n    </style>\n\n    <script src=\"../../lib/OpenLayers.js\"></script>\n  </head>\n  <body>\n    <h1 id=\"title\">OpenLayers sketch handlers crossing the dateline example</h1>\n\n    <div id=\"tags\">\n        international date line, dateline, sketch\n    </div>\n    <p id=\"shortdesc\">\n        Start digitizing a polygon or line\n        on one side of the international dateline, and then cross the dateline\n        whilst digitizing. The feature should behave like digitizing on any\n        other location.\n    </p>\n    <div id=\"map\" class=\"smallmap\"></div>\n\n    <div id=\"docs\">\n    </div>\n        <script type=\"text/javascript\">\n\n        var map = new OpenLayers.Map('map');\n\n        var base = new OpenLayers.Layer.WMS(\"marble\", \n            \"http://demo.boundlessgeo.com/geoserver/wms\",\n            {layers: \"topp:naturalearth\"},\n            {wrapDateLine: true}\n        );\n        \n        // allow testing of specific renderers via \"?renderer=Canvas\", etc\n        var renderer = OpenLayers.Util.getParameters(window.location.href).renderer;\n        renderer = (renderer) ? [renderer] : OpenLayers.Layer.Vector.prototype.renderers;\n\n        var vector = new OpenLayers.Layer.Vector(\"Editable Vectors\", {renderers: renderer});\n\n        map.addLayers([base, vector]);\n        \n        var wkt = new OpenLayers.Format.WKT();\n        var f = wkt.read(\"POLYGON((210.8828125 39.7265625,151.8203125 36.2109375,152.171875 -9.4921875,219.3203125 -10.546875,210.8828125 39.7265625))\");\n        \n        var f2 = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(-190, 0));\n        \n        vector.addFeatures([f, f2]);\n        \n        map.addControl(new OpenLayers.Control.EditingToolbar(vector));\n\n        map.setCenter(new OpenLayers.LonLat(-179, 0), 2);\n\n        </script>\n\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/dateline-smallextent.html",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <title>OpenLayers: Overlay layer extents crossing the dateline</title>\n    <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\">\n    <link rel=\"stylesheet\" href=\"../../examples/style.css\" type=\"text/css\">\n    <style type=\"text/css\">\n        #map {\n            height: 512px;\n        }\n    </style>\n\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n\n// make map available for easy debugging\nvar map;\n\nfunction init(){\n    map = new OpenLayers.Map('map');\n\n    var base = new OpenLayers.Layer.WMS(\"marble\", \n        \"http://demo.boundlessgeo.com/geoserver/wms\",\n        {layers: \"topp:naturalearth\"},\n        {wrapDateLine: true}\n    );\n    var extent = new OpenLayers.Bounds(142.3828125,-70.902270266175,233.6171875,-12.039326531729);\n    var wms = new OpenLayers.Layer.WMS( \"world\",\n        \"http://demo.boundlessgeo.com/geoserver/wms\",\n        {layers: 'world', transparent: true},\n        {maxExtent: extent}\n    );\n    \n    var vector = new OpenLayers.Layer.Vector();\n    vector.addFeatures([\n        new OpenLayers.Feature.Vector(extent.toGeometry())\n    ]);\n\n    map.addLayers([base, wms, vector]);\n\n    map.addControl(new OpenLayers.Control.LayerSwitcher());\n    map.zoomToExtent(extent);\n}\n\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h1 id=\"title\">OpenLayers overlays crossing the dateline test</h1>\n\n    <p id=\"shortdesc\">\n        The overlay has an extent smaller than the world extent, but exceeds\n        the world extent. The base layer is configured with wrapDateLine set to\n        true. The area inside the orange rectangle should always contain tiles\n        from the world layer, regardless of the zoom level.\n    </p>\n    <div id=\"map\" class=\"smallmap\"></div>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/draw-feature.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <title>Draw Feature Acceptance Test</title>\n    <style type=\"text/css\">\n    \n        body {\n            font-size: 0.8em;\n        }\n        p {\n            padding-top: 1em;\n        }\n        \n        .map {\n            margin: 1em;\n            float: left;\n            width: 256px;\n            height: 256px;\n        }\n\n    </style>\n\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n \n        var map1, map2;\n\n        function init(){\n            var wms, vector, ctrl;\n            var goodMaxRes = OpenLayers.Map.prototype.maxResolution;\n            var badMaxRes = 0.00000001;\n\n            map1 = new OpenLayers.Map('map1');\n            wms = new OpenLayers.Layer.WMS( \"OpenLayers WMS\",\n                \"http://labs.metacarta.com/wms/vmap0?\", {layers: 'basic'});\n            vector = new OpenLayers.Layer.Vector(\"vector1\");\n            map1.addLayers([wms, vector]);\n            ctrl = new OpenLayers.Control.DrawFeature(vector,\n                OpenLayers.Handler.Path);\n            map1.addControl(ctrl);\n            ctrl.activate();\n \n            map2 = new OpenLayers.Map('map2',\n                {maxResolution: badMaxRes});\n            wms = new OpenLayers.Layer.WMS( \"OpenLayers WMS\",\n                \"http://labs.metacarta.com/wms/vmap0?\", {layers: 'basic'},\n                {maxResolution: goodMaxRes});\n            vector = new OpenLayers.Layer.Vector(\"vector2\",\n                {maxResolution: goodMaxRes});\n            map2.addLayers([wms, vector]);\n            ctrl = new OpenLayers.Control.DrawFeature(vector,\n                OpenLayers.Handler.Path);\n            map2.addControl(ctrl);\n            ctrl.activate();\n\n            map1.setCenter(new OpenLayers.LonLat(0, 0), 3);\n            map2.setCenter(new OpenLayers.LonLat(0, 0), 3);\n        }\n\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <div id=\"map1\" class=\"map\"></div>\n    <p><b>Resolution properties set at the map level.</b></p>\n    <p>Points should draw as you draw lines. Click to start\n    drawing and double-click to draw the last point.</p>\n    <br style=\"clear: both;\" />\n\n    <div id=\"map2\" class=\"map\"></div>\n    <p><b>Resolution properties set at the layer level.</b></p>\n    <p>Points should draw as you draw lines. Click to start\n    drawing and double-click to draw the last point.</p>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/feature-handler.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <title>Feature Handler Acceptance Test</title>\n    <style type=\"text/css\">\n    \n        body {\n            font-size: 0.8em;\n        }\n        p {\n            padding-top: 1em;\n        }\n        li {\n            list-style: none;\n        }\n        #output {\n            width: 300px;\n            height: 300px;\n        }\n        #west {\n            width: 425px;\n        }\n\n        #east {\n            position: absolute;\n            left: 450px;\n            top: 5px;\n        }\n        #map {\n            width: 400px;\n            height: 400px;\n            border: 1px solid gray;\n        }\n\n    </style>\n\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\"> \n\n        var map, draw, handler, controls;\n        OpenLayers.Feature.Vector.style['default']['strokeWidth'] = '2';\n\n        function init(){\n            map = new OpenLayers.Map('map');\n\n            var vectors = new OpenLayers.Layer.Vector(\n                \"Vector Layer\",\n                {isBaseLayer: true}\n            );\n            map.addLayer(vectors);\n            \n            \n            draw = new OpenLayers.Control.DrawFeature(\n                vectors, OpenLayers.Handler.Polygon\n            );\n            map.addControl(draw);\n            \n            var callbacks = {\n                \"over\": function(feature) {\n                    log(\"over \" + feature.id);\n                },\n                \"out\": function(feature) {\n                    log(\"out \" + feature.id);\n                },\n                \"click\": function(feature) {\n                    log(\"click \" + feature.id);\n                },\n                \"dblclick\": function(feature) {\n                    log(\"dblclick \" + feature.id);\n                },\n                \"clickout\": function(feature) {\n                    log(\"clickout \" + feature.id);\n                }\n            };\n            \n            handler = new OpenLayers.Handler.Feature(\n                {map: map}, vectors, callbacks\n            );\n            \n            map.setCenter(new OpenLayers.LonLat(0, 0), 3);\n\n        }\n        \n        function log(msg) {\n            document.getElementById('output').value += msg + \"\\n\";\n        }\n        \n        function clearLog() {\n            document.getElementById('output').value = \"\";\n        }\n\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <div id=\"west\">\n        <div id=\"map\"></div>\n        <p>\n            Draw a few polygons on the map.  Some overlapping.  Activate the\n            feature handler and ensure that \"over\" and \"out\" are called only\n            when mousing over/out of a feature for the first time.  The\n            \"click\" callback should be called for every click on a feature.\n            The \"clickout\" callback should be called when?\n        </p>\n    </div>\n    <div id=\"east\">\n        <ul>\n            <li>\n                <input type=\"radio\" name=\"type\" value=\"none\" id=\"noneToggle\"\n                       onclick=\"draw.deactivate();handler.deactivate();\" checked=\"checked\" />\n                <label for=\"noneToggle\">navigate</label>\n            </li>\n            <li>\n                <input type=\"radio\" name=\"type\" value=\"polygon\" id=\"polygonToggle\"\n                       onclick=\"draw.activate();handler.deactivate();\" />\n                <label for=\"polygonToggle\">draw polygon</label>\n            </li>\n            <li>\n                <input type=\"radio\" name=\"type\" value=\"feature\" id=\"featureToggle\"\n                       onclick=\"draw.deactivate();handler.activate();\" />\n                <label for=\"featureToggle\">activate feature handler</label>\n            </li>\n        </ul>\n        <button onclick=\"clearLog();\">clear log</button><br />\n        <textarea id=\"output\"></textarea>\n    </div>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/geodesic.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\" />\n    <style type=\"text/css\">\n        #controlToggle li {\n            list-style: none;\n        }\n        #options {\n            position: relative;\n            width: 512px;\n        }\n        #output {\n            float: right;\n        }\n\n        /* avoid pink tiles */\n        .olImageLoadError {\n            background-color: transparent !important;\n        }\n    </style>\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var map, measureControls;\n        function init(){\n            map = new OpenLayers.Map('map');\n            \n            var wmsLayer = new OpenLayers.Layer.OSM(); \n\n            map.addLayers([wmsLayer]);\n            map.setCenter(new OpenLayers.LonLat(0,0), 5);\n            map.addControl(new OpenLayers.Control.LayerSwitcher());\n            map.addControl(new OpenLayers.Control.MousePosition());\n            map.addControl(new OpenLayers.Control.ScaleLine({geodesic: true}))\n            \n            // style the sketch fancy\n            var sketchSymbolizers = {\n                \"Point\": {\n                    pointRadius: 4,\n                    graphicName: \"square\",\n                    fillColor: \"white\",\n                    fillOpacity: 1,\n                    strokeWidth: 1,\n                    strokeOpacity: 1,\n                    strokeColor: \"#333333\"\n                },\n                \"Line\": {\n                    strokeWidth: 3,\n                    strokeOpacity: 1,\n                    strokeColor: \"#666666\",\n                    strokeDashstyle: \"dash\"\n                },\n                \"Polygon\": {\n                    strokeWidth: 2,\n                    strokeOpacity: 1,\n                    strokeColor: \"#666666\",\n                    fillColor: \"white\",\n                    fillOpacity: 0.3\n                }\n            };\n            var style = new OpenLayers.Style();\n            style.addRules([\n                new OpenLayers.Rule({symbolizer: sketchSymbolizers})\n            ]);\n            var styleMap = new OpenLayers.StyleMap({\"default\": style});\n            \n            measureControls = {\n                line: new OpenLayers.Control.Measure(\n                    OpenLayers.Handler.Path, {\n                        geodesic: true,\n                        persist: true,\n                        handlerOptions: {\n                            layerOptions: {styleMap: styleMap}\n                        }\n                    }\n                ),\n                polygon: new OpenLayers.Control.Measure(\n                    OpenLayers.Handler.Polygon, {\n                        geodesic: true,\n                        persist: true,\n                        handlerOptions: {\n                            layerOptions: {styleMap: styleMap}\n                        }\n                    }\n                )\n            };\n            \n            var control;\n            for(var key in measureControls) {\n                control = measureControls[key];\n                control.events.on({\n                    \"measure\": handleMeasurements,\n                    \"measurepartial\": handleMeasurements\n                });\n                map.addControl(control);\n            }\n            \n            map.setCenter(new OpenLayers.LonLat(0, 0), 3);\n            \n            document.getElementById('noneToggle').checked = true;\n        }\n        \n        function handleMeasurements(event) {\n            var geometry = event.geometry;\n            var units = event.units;\n            var order = event.order;\n            var measure = event.measure;\n            var element = document.getElementById('output');\n            var out = \"\";\n            if(order == 1) {\n                out += \"measure: \" + measure.toFixed(3) + \" \" + units;\n            } else {\n                out += \"measure: \" + measure.toFixed(3) + \" \" + units + \"<sup>2</\" + \"sup>\";\n            }\n            element.innerHTML = out;\n        }\n\n        function toggleControl(element) {\n            for(key in measureControls) {\n                var control = measureControls[key];\n                if(element.value == key && element.checked) {\n                    control.activate();\n                } else {\n                    control.deactivate();\n                }\n            }\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h1 id=\"title\">OpenLayers Geodesic Measurement & ScaleLine</h1>\n    <p id=\"shortdesc\">\n        Tests geodesic measurement of distances and areas against a geodesic ScaleLine.\n    </p>\n    <div id=\"map\" style=\"width: 512px; height: 300px;\"></div>\n    <div id=\"options\">\n        <div id=\"output\">\n        </div>\n        <ul id=\"controlToggle\">\n            <li>\n                <input type=\"radio\" name=\"type\" value=\"none\" id=\"noneToggle\"\n                       onclick=\"toggleControl(this);\" checked=\"checked\" />\n                <label for=\"noneToggle\">navigate</label>\n            </li>\n            <li>\n                <input type=\"radio\" name=\"type\" value=\"line\" id=\"lineToggle\" onclick=\"toggleControl(this);\" />\n                <label for=\"lineToggle\">measure distance</label>\n            </li>\n            <li>\n                <input type=\"radio\" name=\"type\" value=\"polygon\" id=\"polygonToggle\" onclick=\"toggleControl(this);\" />\n                <label for=\"polygonToggle\">measure area</label>\n            </li>\n        </ul>\n    </div>\n    <p>Zoom in so the ScaleLine shows units in the range of 10-100 km. Measure\n    the length of the ScaleLine. The result should be approximately the same\n    as the distance printed on the ScaleLine.</p>\n    <p>Zoom out so the ScaleLine shows units in the range of 100-500 km. Drag\n    the map to the South or North and see how the ScaleLine length changes.</p>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/geojson-geomcoll-reprojection.html",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\"\n    \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\">\n    <head>\n        <style type=\"text/css\" media=\"screen\">\n            #map { height: 500px; }\n        </style>\n        <script src=\"../../lib/OpenLayers.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\n        <script src=\"http://www.openstreetmap.org/openlayers/OpenStreetMap.js\" type=\"text/javascript\" charset=\"utf-8\"></script>\n        <script type=\"text/javascript\" charset=\"utf-8\">\n            function init(){\n                var map = new OpenLayers.Map (\"map\", {\n                    controls: [\n                        new OpenLayers.Control.Navigation(),\n                        new OpenLayers.Control.Attribution()\n                    ],\n                    maxExtent: new OpenLayers.Bounds(-20037508.34,-20037508.34,20037508.34,20037508.34),\n                    maxResolution: 156543.0399,\n                    numZoomLevels: 19,\n                    units: 'm',\n                    projection: new OpenLayers.Projection(\"EPSG:900913\"),\n                    displayProjection: new OpenLayers.Projection(\"EPSG:4326\")\n                });\n                \n                var osm = new OpenLayers.Layer.OSM.Mapnik('OSM');\n                map.addLayer(osm);\n                var lonLat = new OpenLayers.LonLat(5, 40).transform(new OpenLayers.Projection(\"EPSG:4326\"), map.getProjectionObject());\n                map.setCenter (lonLat, 5);\n                \n                var featurecollection = {\n                    \"type\": \"FeatureCollection\", \n                    \"features\": [{\n                        \"geometry\": {\n                            \"type\": \"GeometryCollection\", \n                            \"geometries\": [\n                                {\n                                    \"type\": \"LineString\", \n                                    \"coordinates\": \n                                        [[11.0878902207, 45.1602390564], \n                                        [15.01953125, 48.1298828125]]\n                                },\n                                {\n                                    \"type\": \"Polygon\", \n                                    \"coordinates\": \n                                        [[[11.0878902207, 45.1602390564], \n                                          [14.931640625, 40.9228515625], \n                                          [0.8251953125, 41.0986328125], \n                                          [7.63671875, 48.96484375], \n                                          [11.0878902207, 45.1602390564]]]\n                                },\n                                {\n                                    \"type\":\"Point\", \n                                    \"coordinates\":[15.87646484375, 44.1748046875]                                    \n                                }\n                            ]\n                        }, \n                        \"type\": \"Feature\", \n                        \"properties\": {}    \n                    }]\n                };\n                var geojson_format = new OpenLayers.Format.GeoJSON({\n                    'internalProjection': new OpenLayers.Projection(\"EPSG:900913\"),\n                    'externalProjection': new OpenLayers.Projection(\"EPSG:4326\")\n                });\n                var vector_layer = new OpenLayers.Layer.Vector(); \n                map.addLayer(vector_layer);\n                vector_layer.addFeatures(geojson_format.read(featurecollection));\n            };\n        </script>\n    </head>\n    <body onload=\"init()\">\n        <div id=\"map\"></div>\n    </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/google-fullscreen-overlay.html",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Google v3 with Overlay Test</title>\n    <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../examples/style.css\" type=\"text/css\">\n    <style type=\"text/css\">\n        html, body, #map {\n            width: 100%;\n            height: 100%;\n            margin: 0;\n        }\n        #text {\n            position: absolute;\n            top: 1em;\n            right: 1em;\n            width: 512px;\n            z-index: 20000;\n            background-color: white;\n            padding: 0 0.5em 0.5em 0.5em;\n        }\n    </style>\n    <script src=\"http://maps.google.com/maps/api/js?v=3.6&amp;sensor=false\"></script>\n    <script src=\"../../lib/OpenLayers.js\"></script>\n  </head>\n  <body>\n    <div id=\"map\"></div>\n      <div id=\"text\">\n          <h1 id=\"title\">Google v3 with Overlay Test</h1>\n\n        <div id=\"docs\">\n            <p>This test shows that the Google layer and overlays are not in sync while dragging or zooming.</p>\n        </div>\n    </div>\n    <script type=\"text/javascript\">\n        var options = {\n            projection: new OpenLayers.Projection(\"EPSG:900913\"),\n            units: \"m\",\n            maxResolution: 156543.0339,\n            maxExtent: new OpenLayers.Bounds(-20037508, -20037508, 20037508, 20037508)\n        };\n        var map = new OpenLayers.Map('map', options);\n        var gmap = new OpenLayers.Layer.Google(\n            \"Google Streets\", {sphericalMercator: true}\n        );\n        var states = new OpenLayers.Layer.WMS(\n            \"USA States\", \"http://demo.boundlessgeo.com/geoserver/wms\",\n            {layers: \"topp:states\", transparent: true}\n        );\n        map.addLayers([gmap, states]);\n        map.setCenter(new OpenLayers.LonLat(-10028537.429619, 4598451.0222853), 5);\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/google-panning.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <title>Google Panning Acceptance Test</title>\n    <style type=\"text/css\">\n    \n        body {\n            font-size: 0.8em;\n        }\n        p {\n            padding-top: 1em;\n        }\n        \n        #evenmap {\n            margin: 1em;\n            float: left;\n            width: 256px;\n            height: 256px;\n        }\n\n        #oddmap {\n            margin: 1em;\n            float: left;\n            width: 255px;\n            height: 255px;\n        }\n\n        /* avoid pink tiles */\n        .olImageLoadError {\n            background-color: transparent !important;\n        }\n\n    </style>\n\n    <script src=\"http://maps.google.com/maps/api/js?v=3&amp;sensor=false\"></script>\n\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n \n        var evenmap, oddmap;\n\n        // increase reload attempts \n        OpenLayers.IMAGE_RELOAD_ATTEMPTS = 3;\n\n        function init(){\n            evenmap = new OpenLayers.Map('evenmap');\n            var evenlayer = new OpenLayers.Layer.Google(\n                \"Imagery\",\n                {type: google.maps.MapTypeId.SATELLITE}\n            );\n            evenmap.addLayer(evenlayer);\n            var epc = document.getElementById(\"epc\");\n            var emc = document.getElementById(\"emc\");\n            var ee = document.getElementById(\"ee\");\n            evenmap.events.register(\"moveend\", null, function() {\n                var px = new OpenLayers.Pixel(evenmap.size.w / 2,\n                                              evenmap.size.h / 2);\n                var pc = evenmap.getLonLatFromViewPortPx(px);\n                pc.lon = parseFloat(pc.lon.toPrecision(6));\n                pc.lat = parseFloat(pc.lat.toPrecision(6));\n                var mc = evenmap.baseLayer.getOLLonLatFromMapObjectLonLat(\n                    evenmap.baseLayer.mapObject.getCenter()\n                );\n                mc.lon = parseFloat(mc.lon.toPrecision(6));\n                mc.lat = parseFloat(mc.lat.toPrecision(6));\n                epc.innerHTML = \"(\" + pc.lon + \", \" + pc.lat + \")\";\n                emc.innerHTML = \"(\" + mc.lon + \", \" + mc.lat + \")\";\n                ee.innerHTML = pc.equals(mc);\n            });\n            evenmap.zoomToMaxExtent();\n\n            oddmap = new OpenLayers.Map('oddmap');\n            var oddlayer = new OpenLayers.Layer.Google(\n                \"Imagery\",\n                {type: google.maps.MapTypeId.SATELLITE}\n            );\n            oddmap.addLayer(oddlayer);\n            var opc = document.getElementById(\"opc\");\n            var omc = document.getElementById(\"omc\");\n            var oe = document.getElementById(\"oe\");\n            oddmap.events.register(\"moveend\", null, function() {\n                var px = new OpenLayers.Pixel(oddmap.size.w / 2,\n                                              oddmap.size.h / 2);\n                var pc = oddmap.getLonLatFromViewPortPx(px);\n                pc.lon = parseFloat(pc.lon.toPrecision(6));\n                pc.lat = parseFloat(pc.lat.toPrecision(6));\n                var mc = oddmap.baseLayer.getOLLonLatFromMapObjectLonLat(\n                    oddmap.baseLayer.mapObject.getCenter()\n                );\n                mc.lon = parseFloat(mc.lon.toPrecision(6));\n                mc.lat = parseFloat(mc.lat.toPrecision(6));\n                opc.innerHTML = \"(\" + pc.lon + \", \" + pc.lat + \")\";\n                omc.innerHTML = \"(\" + mc.lon + \", \" + mc.lat + \")\";\n                oe.innerHTML = pc.equals(mc);\n            });\n            oddmap.zoomToMaxExtent();\n\n        }\n\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <div id=\"evenmap\"></div>\n    <p><b>Even sized map.</b> The map on the left should pan regularly, and the\n    two centers below should be equivalent.  Both dragging and panning with\n    buttons should maintain the same center.</p>\n    <p><b>pixel center:</b> <span id=\"epc\"></span>\n    <br /><b>map center:</b> <span id=\"emc\"></span>\n    <br /><b>equvalent:</b> <span id=\"ee\"></span>\n    </p>\n    <br style=\"clear: both;\" />\n\n    <div id=\"oddmap\"></div>\n    <p><b>Odd sized map.</b> The map on the left should pan regularly, and the\n    two centers below should be equivalent.  Both dragging and panning with\n    buttons should maintain the same center.</p>\n    <p><b>pixel center:</b> <span id=\"opc\"></span>\n    <br /><b>map center:</b> <span id=\"omc\"></span>\n    <br /><b>equvalent:</b> <span id=\"oe\"></span>\n    </p>\n    </ul>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/google-resize.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <title>OpenLayers Google Layer Example</title>\n    <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../examples/style.css\" type=\"text/css\" />\n    <script src=\"http://maps.google.com/maps/api/js?v=3&amp;sensor=false\"></script>\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var map;\n\n        function init() {\n            var mapOptions = {\n                projection: \"EPSG:900913\",\n                displayProjection: new OpenLayers.Projection(\"EPSG:4326\"), //Pour afficher les coord lat long\n                units: \"m\",\n                maxResolution: 156543.0339,\n                maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),\n                controls: [new OpenLayers.Control.LayerSwitcher()],\n                numZoomLevels: 20\n            };\n            map = new OpenLayers.Map('map', mapOptions);\n\n            var dummy = new OpenLayers.Layer(\n                \"Dummy\",\n                {isBaseLayer: true}\n            );\n            var gmap = new OpenLayers.Layer.Google(\n                \"Google Streets\", {sphericalMercator: true}\n            );\n\n            map.addLayers([dummy, gmap]);\n\n            map.setCenter(new OpenLayers.LonLat(-7712190.388467473, 6567469.498697457), 6);\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h1 id=\"title\">Google Layer Resize Issue</h1>\n\n    <div id=\"tags\"></div>\n\n    <p id=\"shortdesc\">\n        <ol>\n            <li>Click\n                <button onclick=\"var m = document.getElementById('map').style; m.height = '400px'; m.width = '800px'; map.updateSize(); return false;\">Resize</button></li>\n            <li>Open the LayerSwitcher and switch to Google Streets</li>\n            <li>Confirm that the whole map area is populated with tiles</li>\n        </ol>\n    </p>\n\n    <div id=\"map\" style=\"width: 200px; height: 200px\"></div>\n\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/google-tilt.html",
    "content": "<!DOCTYPE html>\n<html>\n    <head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n        <title>OpenLayers Google (v3) Layer Example</title>\n        <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\">\n        <link rel=\"stylesheet\" href=\"../../examples/style.css\" type=\"text/css\">\n        <script src=\"http://maps.google.com/maps/api/js?v=3.6&amp;sensor=false\"></script>\n        <script src=\"../../lib/OpenLayers.js\"></script>\n    </head>\n    <body onload=\"init()\">\n        <h1 id=\"title\">Google (v3) Unexpected Tilt Test</h1>\n        <div id=\"map\" class=\"smallmap\"></div>\n        <div id=\"docs\">\n            <p>\n                OpenLayers uses the disableDefaultUI option of the GMaps API.\n                Despite that, the tilt feature is active. To see it, zoom in\n                once and see the buildings from a 45° angle instead of from the\n                top as you would expect from aerial imagery.\n            </p>\n        </div>\n        <script>\n            var map = new OpenLayers.Map('map');\n\n            var ghyb = new OpenLayers.Layer.Google(\n                \"Google Hybrid\",\n                {type: google.maps.MapTypeId.HYBRID, numZoomLevels: 20}\n            );\n\n            map.addLayers([ghyb]);\n\n            map.setCenter(new OpenLayers.LonLat(-13635213, 4544641), 17);\n        </script>\n    </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/google-v3-resize.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <title>Google v3 Resize Test</title>\n    <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../examples/style.css\" type=\"text/css\" />\n    <script src=\"http://maps.google.com/maps/api/js?sensor=false&amp;v=3.6\"></script>\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var map;\n\n        function init() {\n            var mapOptions = {\n                projection: \"EPSG:900913\",\n                displayProjection: new OpenLayers.Projection(\"EPSG:4326\"), //Pour afficher les coord lat long\n                units: \"m\",\n                maxResolution: 156543.0339,\n                maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),\n                controls: [new OpenLayers.Control.Navigation(), new OpenLayers.Control.LayerSwitcher()],\n                numZoomLevels: 20\n            };\n            map = new OpenLayers.Map('map', mapOptions);\n\n            var dummy = new OpenLayers.Layer(\n                \"Dummy\",\n                {isBaseLayer: true}\n            );\n            var gmap = new OpenLayers.Layer.Google(\n                \"Google Streets\", {sphericalMercator: true}\n            );\n\n            map.addLayers([dummy, gmap]);\n\n            map.setCenter(new OpenLayers.LonLat(-7712190.388467473, 6567469.498697457), 6);\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h1 id=\"title\">Google Layer Resize Issue</h1>\n\n    <div id=\"tags\"></div>\n\n    <p id=\"shortdesc\">\n        <ol>\n            <li>Click\n                <button onclick=\"var m = document.getElementById('map').style; m.height = '400px'; m.width = '800px';map.updateSize(); return false;\">Resize</button></li>\n            <li>Open the LayerSwitcher and switch to Google Streets</li>\n            <li>Confirm that the whole map area is populated with tiles</li>\n        </ol>\n    </p>\n\n    <div id=\"map\" style=\"width: 350px; height: 200px\"></div>\n\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/loadend.html",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\">\n    <link rel=\"stylesheet\" href=\"../../examples/style.css\" type=\"text/css\">\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var lon = 5;\n        var lat = 40;\n        var zoom = 5;\n        var map, layer;\n\n        var numLoadingLayers = 0;\n\n        function init(){\n            map = new OpenLayers.Map( 'map' );\n            layer = new OpenLayers.Layer.WMS( \"OpenLayers WMS\",\n                    \"http://vmap0.tiles.osgeo.org/wms/vmap0\", {layers: 'basic'});\n\n            layer.events.register('loadstart', this, onloadstart);\n            layer.events.register('loadend', this, onloadend);\n\n            map.addLayer(layer);\n\n            map.setCenter(new OpenLayers.LonLat(lon, lat), zoom);\n        }\n\n        function log(msg) {\n            document.getElementById(\"output\").innerHTML += msg + \"<br />\";\n        }\n\n        function onloadstart(evt) {\n            numLoadingLayers++;\n            var msg = ['loadstart', '# layers loading:', numLoadingLayers].join(' ');\n            log (msg);\n        };\n\n        function onloadend(evt) {\n            numLoadingLayers--;\n            var msg = ['loadend  ', '# layers loading:', numLoadingLayers].join(' ');\n            log (msg);\n        };\n\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h1 id=\"title\">WMS loadstart/loadend events</h1>\n\n    <div id=\"tags\">\n        wms, layer, singletile\n    </div>\n    <p id=\"shortdesc\">\n        Shows the loadstart and loadend events of a WMS layer\n    </p>\n\n    <div id=\"map\" class=\"smallmap\"></div>\n   \n    <div id=\"docs\">\n        <p>\n          This example is helpful in testing whether all loadstart events are followed\n          by a loadend event.\n          Test by using scroll-wheel up and down.\n        </p>\n    </div>\n\n    <h1>loadstart and loadend events</h1>\n    <pre id=\"output\"></pre>\n\n  </body>\n</html>"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/map-events.html",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <title>map.div Events Acceptance Test</title>\n    <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\">\n    <link rel=\"stylesheet\" href=\"../../examples/style.css\" type=\"text/css\">\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var map, layer;\n        function init() {\n            map = new OpenLayers.Map('map');\n            layer = new OpenLayers.Layer.OSM( \"Simple OSM Map\");\n            map.addLayer(layer);\n            map.setCenter(\n                new OpenLayers.LonLat(-71.147, 42.472).transform(\n                    new OpenLayers.Projection(\"EPSG:4326\"),\n                    map.getProjectionObject()\n                ), 12\n            );\n\n            var element = document.getElementById('map');\n            element.addEventListener('mousedown', function(evt) {\n                alert('mousedown on map div');\n            });\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h1 id=\"title\">map.div Events Acceptance Test</h1>\n\n    <div id=\"map\" class=\"smallmap\"></div>\n\n    <p><b>Test 1</b> : mousedown the map; an alert must be displayed.</p>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/memory/Marker-2258.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <title>Memory Test - Layer.Markers / Marker</title>\n    <style type=\"text/css\">\n        body {\n            font-size: 0.8em;\n        }\n        p {\n            padding-top: 1em;\n        }\n        #map {\n            width: 256px;\n            height: 256px;\n            border: 1px solid black;\n        }\n    </style>\n\n    <script src=\"../../../lib/Firebug/firebug.js\"></script>\n    <script src=\"../../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var map, layer, marker;\n        \n        function init(){\n            map = new OpenLayers.Map('map');\n            map.addLayer(new OpenLayers.Layer.WMS( \"OpenLayers WMS\", \n                \"http://labs.metacarta.com/wms/vmap0\", {layers: 'basic'} ));\n            map.setCenter(new OpenLayers.LonLat(0, 0), 0);\n            \n            layer = new OpenLayers.Layer.Markers( \"Markers\" );\n            map.addLayer(layer);\n            \n            marker = new OpenLayers.Marker(new OpenLayers.LonLat(0,0));\n            layer.addMarker(marker);\n            \n            window.setTimeout(function() {\n                layer.removeMarker(marker);\n                layer.addMarker(marker);\n                \n                // people SHOULD call marker.destroy(). But if they don't\n                // we leak memory.\n                //marker.destroy();\n                \n                window.alert(\"Setup - hit STOP in the leak detector now\");\n            }, 100);\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h1 id=\"title\">Memory Test - Layer.Markers / Marker</h1>\n    <pre id=\"status\"></pre>\n    <div id=\"map\"></div>\n    <p>\n    This test is a memory leak test for usage of Layer.Markers / Marker.\n    </p>\n    <p>\n    Run this test in IE6/7 with <a href=\"http://blogs.msdn.com/gpde/pages/javascript-memory-leak-detector-v2.aspx\">JavaScript Memory Leak Detector v2</a>\n    and watch it identify a leak unless this is fixed.\n    </p>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/memory/PanZoom-2323.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <title>Memory Test - PanZoom.getSlideFactor</title>\n    <style type=\"text/css\">\n        body {\n            font-size: 0.8em;\n        }\n        p {\n            padding-top: 1em;\n        }\n        #map {\n            width: 256px;\n            height: 256px;\n            border: 1px solid black;\n        }\n    </style>\n\n    <script src=\"../../../lib/Firebug/firebug.js\"></script>\n    <script src=\"../../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var map;\n        var layer;\n        \n        function init(){\n            map = new OpenLayers.Map('map');\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h1 id=\"title\">Memory Test - PanZoom.getSlideFactor</h1>\n    <pre id=\"status\"></pre>\n    <div id=\"map\"></div>\n    <p>\n    This test is a memory leak test for: PanZoom.getSlideFactor.\n    </p>\n    <p>\n    Run this test in IE6/7 with <a href=\"http://blogs.msdn.com/gpde/pages/javascript-memory-leak-detector-v2.aspx\">JavaScript Memory Leak Detector v2</a>\n    and watch it identify a leak unless this is fixed.\n    </p>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/memory/RemoveChild-2170.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <title>Memory Test - DOMNode.removeChild</title>\n    <style type=\"text/css\">\n        body {\n            font-size: 0.8em;\n        }\n        p {\n            padding-top: 1em;\n        }\n        #map {\n            width: 512px;\n            height: 512px;\n            border: 1px solid black;\n        }\n    </style>\n\n    <script src=\"../../../lib/Firebug/firebug.js\"></script>\n    <script src=\"../../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var map, layer;\n        \n        function tearDown() {\n            layer.events.unregister(\"loadend\", layer, tearDown);\n            window.setTimeout(function() {\n                map.removeLayer(layer);\n                //map.addLayer(layer);\n                layer.destroy();\n                window.alert(\"Setup - hit STOP in the leak detector now\");\n            }, 100);\n        }\n        \n        function init(){\n            map = new OpenLayers.Map( 'map', {maxResolution:1.40625/2} );\n            layer = new OpenLayers.Layer.TMS( \"TMS\",\n                    \"http://labs.metacarta.com/wms-c/Basic.py/\", {layername: 'basic', type:'png'} );\n            map.addLayer(layer);\n            map.setCenter(new OpenLayers.LonLat(5, 40), 5);\n            \n            layer.events.register(\"loadend\", layer, tearDown);\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h1 id=\"title\">Memory Test - DOMNode.removeChild</h1>\n    <pre id=\"status\"></pre>\n    <div id=\"map\"></div>\n    <p>\n    This test is a memory leak test for usage of DOMNode.removeChild\n    </p>\n    <p>\n    Run this test in IE6/7 with <a href=\"http://blogs.msdn.com/gpde/pages/javascript-memory-leak-detector-v2.aspx\">JavaScript Memory Leak Detector v2</a>\n    and watch it identify a leak unless this is fixed.\n    </p>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/memory/VML-2170.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <title>Memory Test - Renderer.VML - onselectstart</title>\n    <style type=\"text/css\">\n        body {\n            font-size: 0.8em;\n        }\n        p {\n            padding-top: 1em;\n        }\n        #map {\n            width: 256px;\n            height: 256px;\n            border: 1px solid black;\n        }\n    </style>\n\n    <script src=\"../../../lib/Firebug/firebug.js\"></script>\n    <script src=\"../../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var map;\n        var layer;\n        \n        function init(){\n            map = new OpenLayers.Map('map');\n            \n            layer = new OpenLayers.Layer.Vector(\"Test-VML\", {renderers:['VML']});\n            map.addLayers([layer]);\n            \n            window.setTimeout(function() {\n                layer.redraw();\n                window.alert(\"Setup - hit STOP in the leak detector now\");\n            }, 100);\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h1 id=\"title\">Memory Test - Renderer.VML - onselectstart</h1>\n    <pre id=\"status\"></pre>\n    <div id=\"map\"></div>\n    <p>\n    This test is a memory leak test for usage of \"onselectstart\" event handler in Renderer.VML\n    </p>\n    <p>\n    Run this test in IE6/7 with <a href=\"http://blogs.msdn.com/gpde/pages/javascript-memory-leak-detector-v2.aspx\">JavaScript Memory Leak Detector v2</a>\n    and watch it identify a leak unless this is fixed.\n    </p>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/multiple-google-layers.html",
    "content": "<html>\n    <head>\n        <title>Multiple Google Layers Acceptance Test</title>\n        <script src=\"http://maps.google.com/maps/api/js?v=3&amp;sensor=false\"></script>\n        <script src=\"../../lib/OpenLayers.js\"></script>\n        <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\" />\n        <link rel=\"stylesheet\" href=\"../../theme/default/google.css\" type=\"text/css\" />\n        <style>\n            .col {\n                position: relative;\n                width: 50%;\n            }\n            #col1 {\n                float: left;\n            }\n            #col2 {\n                float: right;\n            }\n            .map {\n                position: relative;\n                height: 300px;\n            }\n            .wrap {\n                position: relative;\n                padding: 10px;\n            }\n            ul {\n                padding: 0;\n            }\n            ul li {\n                list-style: none;\n            }\n            p.clear {\n                clear: both;\n            }\n        </style>\n    </head>\n    <body>\n        <div id=\"col1\" class=\"col\">\n            <div class=\"wrap\">\n                <div id=\"map1\" class=\"map\"></div>\n                layers for map1\n                <ul>\n                    <li><input type=\"checkbox\" checked=\"checked\" name=\"streets1\" id=\"streets1\"><label for=\"streets1\">streets</label></li>\n                    <li><input type=\"checkbox\" checked=\"checked\" name=\"sat1\" id=\"sat1\"><label for=\"sat1\">imagery</label></li>\n                    <li><input type=\"checkbox\" checked=\"checked\" name=\"topo1\" id=\"topo1\"><label for=\"topo1\">topography</label></li>\n                </ul>\n            </div>\n        </div>\n        <div id=\"col2\" class=\"col\">\n            <div class=\"wrap\">\n                <div id=\"map2\" class=\"map\"></div>\n                layers for map2\n                <ul>\n                    <li><input type=\"checkbox\" name=\"streets2\" id=\"streets2\"><label for=\"streets2\">streets</label></li>\n                    <li><input type=\"checkbox\" name=\"sat2\" id=\"sat2\"><label for=\"sat2\">imagery</label></li>\n                    <li><input type=\"checkbox\" name=\"topo2\" id=\"topo2\"><label for=\"topo2\">topography</label></li>\n                </ul>\n            </div>\n        </div>\n        <p class=\"clear\">\n            This example is used to confirm that resizable maps with multiple\n            Google layers work properly.  Click the checkboxes to add/remove\n            layers from the maps.  Use the layer switcher to change the map's\n            base layer.  You should be able to confirm the following:\n            <ol>\n                <li>Adding and removing layers doesn't raise any errors\n                (regardless of how many times the same layer is added/removed).</li>\n                <li>The Google \"Powered By\" link is always visible and clickable\n                when a Google layer is displayed.</li>\n                <li>The Google \"Terms of Use\" link is always visible and clickable\n                when a Google layer is displayed.</li>\n                <li>Resizing a map (by resizing the browser window) and then\n                changing base layer works well.  That is, the center & scale are\n                preserved and all tiles are well aligned.</li>\n                <li>Setting the base layer to the \"Dummy Layer\" hides all other\n                Google base layers, \"Powered By\" link, and \"Terms of Use\" link.</li>\n            </ol>\n        </p>\n        <script>\n        \n            var map1 = new OpenLayers.Map(\"map1\");\n            var streets1 = new OpenLayers.Layer.Google(\"Streets\", {\n                type: google.maps.MapTypeId.ROADMAP\n            });\n            var sat1 = new OpenLayers.Layer.Google(\"Imagery\", {\n                type: google.maps.MapTypeId.SATELLITE\n            });\n            var topo1 = new OpenLayers.Layer.Google(\"Topography\", {\n                type: google.maps.MapTypeId.TERRAIN\n            });\n            var dummy1 = new OpenLayers.Layer(\"Dummy Layer\", {\n                isBaseLayer: true\n            });\n            map1.addLayers([streets1, sat1, topo1, dummy1]);\n            map1.addControl(new OpenLayers.Control.LayerSwitcher);\n            map1.zoomToMaxExtent();\n        \n            var map2 = new OpenLayers.Map(\"map2\");\n            var streets2 = new OpenLayers.Layer.Google(\"Streets\", {\n                type: google.maps.MapTypeId.ROADMAP\n            });\n            var sat2 = new OpenLayers.Layer.Google(\"Imagery\", {\n                type: google.maps.MapTypeId.SATELLITE\n            });\n            var topo2 = new OpenLayers.Layer.Google(\"Topography\", {\n                type: google.maps.MapTypeId.TERRAIN\n            });\n            var dummy2 = new OpenLayers.Layer(\"Dummy Layer\", {\n                isBaseLayer: true\n            });\n            map2.addLayer(dummy2);\n            map2.addControl(new OpenLayers.Control.LayerSwitcher);\n            map2.zoomToMaxExtent();\n            \n            // add behavior to checkboxes\n            var check, inputs = document.getElementsByTagName(\"input\");\n            for (var i=0, len=inputs.length; i<len; ++i) {\n                check = inputs[i];\n                check.onclick = function() {\n                    var name = this.name;\n                    var num = name.match(/\\d$/)[0];\n                    var layer = window[name];\n                    var map = window[\"map\" + num];\n                    if (this.checked) {\n                        map.addLayer(layer);\n                    } else {\n                        map.removeLayer(layer);\n                    }\n                }\n            }\n\n        </script>\n    </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/overviewmap-projection.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../examples/style.css\" type=\"text/css\" />\n    <style type=\"text/css\">\n        .olControlAttribution { bottom: 0px!important }\n        #map {\n            height: 512px;\n        }\n    </style>\n\n    <script src=\"http://maps.google.com/maps/api/js?v=3&amp;sensor=false\"></script>\n\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n\n        // make map available for easy debugging\n        var map;\n\n        function init(){\n            var options = {\n                projection: new OpenLayers.Projection(\"EPSG:900913\"),\n                displayProjection: new OpenLayers.Projection(\"EPSG:4326\"),\n                units: \"m\",\n                maxResolution: 156543.0339,\n                maxExtent: new OpenLayers.Bounds(-20037508, -20037508,\n                                                 20037508, 20037508.34)\n            };\n            map = new OpenLayers.Map('map', options);\n\n            // create Google Mercator layers\n            var gmap = new OpenLayers.Layer.Google(\n                \"Google Streets\",\n                {'sphericalMercator': true}\n            );\n            map.addLayers([gmap]);\n            map.addControl(new OpenLayers.Control.LayerSwitcher());\n            map.addControl(new OpenLayers.Control.Permalink());\n            map.addControl(new OpenLayers.Control.MousePosition());\n            var ovmap = new OpenLayers.Control.OverviewMap({\n                maxRatio: 16,\n                layers: [new OpenLayers.Layer.WMS(\"OpenLayers WMS\", \n                    \"http://labs.metacarta.com/wms/vmap0\",\n                    {layers: 'basic'})]\n            });\n            map.addControl(ovmap);\n            ovmap.maximizeControl();\n            if (!map.getCenter()) {map.zoomToMaxExtent()};\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h1 id=\"title\">OpenLayers Overview Map Projection Test</h1>\n\n    <div id=\"tags\">\n    </div>\n    <p id=\"shortdesc\">\n        Acceptance test for different projections in map and overview map.\n        The map uses EPSG:900913, the overview map EPSG:4326. Zoom the map and\n        drag both the map and the overview map to see it in action.\n    </p>\n    <div id=\"map\" class=\"smallmap\"></div>\n\n    <div id=\"docs\">\n    </div>\n  </body>\n</html>\n\n\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/page-position.html",
    "content": "<!DOCTYPE HTML>\n<html>\n    <head>\n        <title>Page Position Test</title>\n        \n        <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\" />\n        <link rel=\"stylesheet\" href=\"../../examples/style.css\" type=\"text/css\" />\n        <style type=\"text/css\">\n            #mapwrap {\n                border: 10px solid red;\n                width: 532px;\n                height: 276px;\n            }\n            #map {\n                position: absolute;\n                border: 10px solid #ccc;\n                width: 512px;\n                height: 256px;\n            }\n            #controlToggle li {\n                list-style: none;\n            }\n            p {\n                width: 512px;\n            }\n            #scrollspace {\n                height: 500px;\n            }\n        </style>\n        <script src=\"../../lib/OpenLayers.js\"></script>\n        <script type=\"text/javascript\">\n            var map, drawControls;\n            function init(){\n                map = new OpenLayers.Map('map');\n\n                var wmsLayer = new OpenLayers.Layer.WMS( \"OpenLayers WMS\",\n                    \"http://vmap0.tiles.osgeo.org/wms/vmap0?\", {layers: 'basic'});\n\n                var lineLayer = new OpenLayers.Layer.Vector(\"Line Layer\");\n\n                map.addLayers([wmsLayer, lineLayer]);\n                map.addControl(new OpenLayers.Control.LayerSwitcher());\n                map.addControl(new OpenLayers.Control.MousePosition());\n\n                drawControl = new OpenLayers.Control.DrawFeature(lineLayer,\n                                OpenLayers.Handler.Path);\n\n                map.addControl(drawControl);\n\n                map.setCenter(new OpenLayers.LonLat(0, 0), 3);\n\n                document.getElementById('noneToggle').checked = true;\n            }\n\n            function toggleControl(element) {\n                var control = drawControl;\n                if(element.value == \"draw\" && element.checked) {\n                    control.activate();\n                } else {\n                    control.deactivate();\n                }\n            }\n        </script>\n    </head>\n    <body onload=\"init()\">\n        <h1 id=\"title\">OpenLayers Page Position Test</h1>\n\n        <p id=\"shortdesc\">\n            Test if borders and scroll position cause unwanted offsets on the\n            mouse positions reported by map events.\n        </p>\n        <div id=\"mapwrap\">\n            <div id=\"map\"></div>\n        </div>\n\n        <ul id=\"controlToggle\">\n            <li>\n                <input type=\"radio\" name=\"type\" value=\"none\" id=\"noneToggle\"\n                       onclick=\"toggleControl(this);\" checked=\"checked\" />\n                <label for=\"noneToggle\">navigate</label>\n            </li>\n            <li>\n                <input type=\"radio\" name=\"type\" value=\"draw\" id=\"lineToggle\" onclick=\"toggleControl(this);\" />\n                <label for=\"lineToggle\">draw line</label>\n            </li>\n        </ul>\n\n        <div id=\"docs\">\n            <p>This map's div has a border and absolute positioning, wrapped\n                by a container which also has a border. The page is also\n                scrollable. Neither the borders nor scrolling the page should\n                result in unwanted offsets on pixel positions reported by map\n                events.</p>\n            <p>With the line drawing control active, click on the map to add a\n                point.  The point should be drawn at the exact mouse location.</p>\n            <p>With the navigation control active, shift-drag a zoom rectangle.\n                The rectangle's corner should align exactly with the mouse\n                cursor.</p>\n            <p>Scroll the page and repeat the above tests.</p>\n            <div id=\"scrollspace\"><div>\n        </div>\n    </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/pan-redraw-svg.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\" />\n    <style type=\"text/css\">\n        #map {\n            width: 512px;\n            height: 512px;\n            border: 1px solid gray;\n        }\n    </style>\n\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var map, point;\n\n        function init(){\n            var options = {\n                projection: new OpenLayers.Projection(\"EPSG:900913\"),\n                displayProjection: new OpenLayers.Projection(\"EPSG:4326\"),\n                units: \"m\",\n                maxResolution: 20, //0.07464553542137146,\n                maxExtent: new OpenLayers.Bounds(-20037508, -20037508,\n                                                 20037508, 20037508.34)\n            };\n            map = new OpenLayers.Map('map', options);\n            var vector = new OpenLayers.Layer.Vector(\n                    \"Vectors\",\n                    {isBaseLayer: true}\n            );\n            map.addLayer(vector);\n\n            var x =  -20000;//4.33791754;\n            var y = 20000;\n            point = new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.Point(x, y)\n            );\n            \n            map.addLayer(vector);\n            vector.addFeatures([point]);\n            map.setCenter(new OpenLayers.LonLat(0, 0), 5);\n        }\n        \n        function pan(){\n            map.panTo(point.geometry.getBounds().getCenterLonLat());\n        }\n\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h3 id=\"title\">SVG inValidRange Redraw Test Case</h3>\n    <p>Before fixing #1631, after klicking Go! no point would have appeared. The Go! button\n    pans the map over a long distance. Before dragging, the point would have been\n    outside the valid range, and the pan operation would not have triggered the SVG\n    coordinate system to be recreated. The new vector rendering takes care of all this. </p>\n    <div id=\"map\"></div>\n    <input type=\"button\" value=\"Go!\" onclick=\"pan();\"></input>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/popup-keepInMap.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\" debug=\"true\">\n  <head>\n    <title>OpenLayers: Popup Mayhem</title>\n    <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\" />\n    <style type=\"text/css\">\n        #map {\n            width: 900px;\n            height: 500px;\n            border: 1px solid black;\n        }\n    </style>\n\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var map;\n        var layer, markers;\n        \n        var currentPopup;\n        \n        \n        AutoSizeFramedCloud = OpenLayers.Class(OpenLayers.Popup.FramedCloud, {\n            'autoSize': true,\n            'panMapIfOutOfView': false\n        });\n\n        function init(){\n            map = new OpenLayers.Map('map');\n\n            markers = new OpenLayers.Layer.Markers(\"zibo\", {isBaseLayer: true});\n            map.addLayer(markers);\n\n            addMarkers();\n            map.zoomToMaxExtent();\n        }\n        \n        function addMarkers() {\n\n            var ll, popupClass, popupContentHTML;\n\n            //anchored bubble popup small contents autosize closebox\n            ll = new OpenLayers.LonLat(-35,-15);\n            popupClass = AutoSizeFramedCloud;\n            popupContentHTML = \"<div>This popup can't be panned to fit in view, so its popup text should fit inside the map. If it doens't, instead of expaning outside, it will simply make the content scroll. Scroll scroll scroll your boat, gently down the stream! Chicken chicken says the popup text is really boring to write. Did you ever see a popup a popup a popup did you ever see a popup a popup right now. With this way and that way and this way and that way did you ever see a popup a popup right now. I wonder if this is long enough. it might be, but maybe i should throw in some other content. <ul><li>one</li><li>two</li><li>three</li><li>four</li></ul>(get your booty on the floor) </div>\";\n            addMarker(ll, popupClass, popupContentHTML, true, true);\n \n\n        }\n\n        /**\n         * Function: addMarker\n         * Add a new marker to the markers layer given the following lonlat, \n         *     popupClass, and popup contents HTML. Also allow specifying \n         *     whether or not to give the popup a close box.\n         * \n         * Parameters:\n         * ll - {<OpenLayers.LonLat>} Where to place the marker\n         * popupClass - {<OpenLayers.Class>} Which class of popup to bring up \n         *     when the marker is clicked.\n         * popupContentHTML - {String} What to put in the popup\n         * closeBox - {Boolean} Should popup have a close box?\n         * overflow - {Boolean} Let the popup overflow scrollbars?\n         */\n        function addMarker(ll, popupClass, popupContentHTML, closeBox, overflow) {\n\n            var feature = new OpenLayers.Feature(markers, ll); \n            feature.closeBox = closeBox;\n            feature.popupClass = popupClass;\n            feature.data.popupContentHTML = popupContentHTML;\n            feature.data.overflow = (overflow) ? \"auto\" : \"hidden\";\n                    \n            var marker = feature.createMarker();\n\n            var markerClick = function (evt) {\n                if (this.popup == null) {\n                    this.popup = this.createPopup(this.closeBox);\n                    map.addPopup(this.popup);\n                    this.popup.show();\n                } else {\n                    this.popup.toggle();\n                    this.popup.updateSize();\n                }\n                currentPopup = this.popup;\n                OpenLayers.Event.stop(evt);\n            };\n            marker.events.register(\"mousedown\", feature, markerClick);\n\n            markers.addMarker(marker);\n        }\n\n    </script>\n  </head>\n  <body onload=\"init()\">\n  <h1 id=\"title\">Popup KeepInMap</h1>\n\n           <div id=\"map\" class=\"smallmap\"></div>\n      </div>\n      Click on popup, and the content should scroll rather than expanding outside the map.  \n   </div>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/reflow.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <style type=\"text/css\">\n        #map {\n            width: 800px;\n            height: 475px;\n            border: 1px solid black;\n        }\n    </style>\n    <script src=\"../../lib/OpenLayers.js\" type=\"text/javascript\"></script>\n    <script type=\"text/javascript\">\n        \n        var map;\n        var vectors;\n        \n        function init(){\n            map = new OpenLayers.Map('map');\n            var wms = new OpenLayers.Layer.WMS(\n                \"OpenLayers WMS\", \n                \"http://labs.metacarta.com/wms/vmap0\",\n                {layers: 'basic'}\n            );\n\n            vectors = new OpenLayers.Layer.Vector(\n                \"Simple Geometry\",\n                {\n                    styleMap: new OpenLayers.StyleMap({\n                        externalGraphic: \"../../img/marker-gold.png\",\n                        pointRadius: 10\n                    })\n                }\n            );\n            \n            map.addLayers([wms, vectors]);\n            \n            var features = [];\n            var x = -111.04;\n            var y = 45.68;\n            for(var i = 0; i < 10; i++){\n                x += i * .5;\n                y += i * .1;\n                features.push(\n                    new OpenLayers.Feature.Vector(\n                        new OpenLayers.Geometry.Point(x, y)\n                    )\n                );\n            }\n            \n            map.setCenter(new OpenLayers.LonLat(x, y), 5);\n            vectors.addFeatures(features);\n        };\n        \n    </script>\n  </head>\n  <body onload=\"init()\">\n    <div id=\"map\"></div>\n    <p>Use the pan buttons.  See flicker at end of animated pan.</p>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/renderedDimensions.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\" debug=\"true\">\n  <head>\n    <title>OpenLayers: Popup Mayhem</title>\n    <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\" />\n    <style type=\"text/css\">\n        #map {\n            width: 900px;\n            height: 500px;\n            border: 1px solid black;\n        }\n    </style>\n\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var map;\n        var layer, markers;\n        \n        var currentPopup;\n        \n        \n// different popup types\n\n\n        //disable the autosize for the purpose of our matrix\n        OpenLayers.Popup.FramedCloud.prototype.autoSize = false;\n\n        AutoSizeFramedCloud = OpenLayers.Class(OpenLayers.Popup.FramedCloud, {\n            'autoSize': true\n        });\n\n        function init(){\n            map = new OpenLayers.Map('map');\n\n            layer = new OpenLayers.Layer(\n                \"popupMatrix\", \n                {isBaseLayer: true}\n            );\n            map.addLayer(layer);\n\n            markers = new OpenLayers.Layer.Markers(\"zibo\");\n            map.addLayer(markers);\n\n            addMarkers();\n            map.zoomToMaxExtent();\n        }\n        \n        function addMarkers() {\n\n            var ll, popupClass, popupContentHTML;\n\n            //anchored bubble popup small contents autosize closebox\n            ll = new OpenLayers.LonLat(-35,-15);\n            popupClass = AutoSizeFramedCloud;\n            popupContentHTML = \"<div>This text's line-height is affected<br/>by it's parents. Thus we have to<br/>place the content inside<br/>the correct container to get<br/>the rendered size.</div>\";\n            addMarker(ll, popupClass, popupContentHTML, true);\n \n\n        }\n\n        /**\n         * Function: addMarker\n         * Add a new marker to the markers layer given the following lonlat, \n         *     popupClass, and popup contents HTML. Also allow specifying \n         *     whether or not to give the popup a close box.\n         * \n         * Parameters:\n         * ll - {<OpenLayers.LonLat>} Where to place the marker\n         * popupClass - {<OpenLayers.Class>} Which class of popup to bring up \n         *     when the marker is clicked.\n         * popupContentHTML - {String} What to put in the popup\n         * closeBox - {Boolean} Should popup have a close box?\n         * overflow - {Boolean} Let the popup overflow scrollbars?\n         */\n        function addMarker(ll, popupClass, popupContentHTML, closeBox, overflow) {\n\n            var feature = new OpenLayers.Feature(markers, ll); \n            feature.closeBox = closeBox;\n            feature.popupClass = popupClass;\n            feature.data.popupContentHTML = popupContentHTML;\n            feature.data.overflow = (overflow) ? \"auto\" : \"hidden\";\n                    \n            var marker = feature.createMarker();\n\n            var markerClick = function (evt) {\n                if (this.popup == null) {\n                    this.popup = this.createPopup(this.closeBox);\n                    map.addPopup(this.popup);\n                    this.popup.show();\n                } else {\n                    this.popup.toggle();\n                }\n                currentPopup = this.popup;\n                OpenLayers.Event.stop(evt);\n            };\n            marker.events.register(\"mousedown\", feature, markerClick);\n\n            markers.addMarker(marker);\n        }\n\n    </script>\n  </head>\n  <body onload=\"init()\">\n  <h1 id=\"title\">Popup Matrix</h1>\n\n  <div id=\"tags\">\n  </div>\n      <div style=\"line-height: 40px;\">\n           <div id=\"map\" class=\"smallmap\"></div>\n      </div>\n      Click on popup, should be able to read a full sentence, not just two lines.  \n   </div>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/select-feature-right-click.html",
    "content": "<html>\n    <head>\n        <title>OpenLayers Ticket 3404</title>\n        <script src=\"../../lib/OpenLayers.js\"></script>\n    </head>\n    <body>\n        <table cellpadding=\"10px\">\n            <tr>\n                <td width=\"600\">\n                    <p><a href=\"http://trac.osgeo.org/openlayers/ticket/3404\">Ticket 3404</a> Test Page</p>\n                    <p>This bug is only triggered by physical right mouse clicks so it is not possible to write\n                       an automated js unit test</p>\n                    <p>When a SelectFeature control and a Navigation control are added to a map the left-click\n                       mousedown events are stopped by a Drag handler before reaching the Feature handler. However,\n                       right-click mousedown events so pass through and reach the Feature handler.</p>\n                    <p>The Feature handler records the xy of\n                       each mousedown and mouseup events so they can be compared in the click event. Because only right-click\n                       mousedown event are received the location of future left-click mouseup events are compared\n                       to the location of the 'stale' right-click mousedown event resulting in the feature not being selected.</p>\n                    <p>Steps to recreate the bug:\n                        <ol>\n                            <li>Left-click a point to select it.</li>\n                            <li>Left-click the map to deselect the point.</li>\n                            <li>Left-click a different point to select it.</li>\n                            <li>Left-click the map to deselect the second point.</li>\n                            <li>Right-click the map then left-click to close the browser context menu.</li>\n                            <li>Left-click a point.</li>\n                        </ol>\n                    </p>\n                    <p>Expected: The point is selected.</p>\n                </td>\n                <td>\n                  <div style=\"width:300; height:400\" id=\"map\"></div>\n                </td>\n            </tr>\n        </table>\n\n        <script defer=\"defer\" type=\"text/javascript\">\n        var map = new OpenLayers.Map('map');\n\n        var wmsLayer = new OpenLayers.Layer.WMS( \"OpenLayers WMS\",\n            \"http://vmap0.tiles.osgeo.org/wms/vmap0\", {layers: 'basic'} );\n\n        // allow testing of specific renderers via \"?renderer=Canvas\", etc\n        var renderer = OpenLayers.Util.getParameters(window.location.href).renderer;\n        renderer = (renderer) ? [renderer] : OpenLayers.Layer.Vector.prototype.renderers;\n\n        var vectorLayer = new OpenLayers.Layer.Vector(\"Vector Layer\", {\n            renderers: renderer\n        });\n\n        map.addLayers([wmsLayer, vectorLayer]);\n        map.addControl(new OpenLayers.Control.LayerSwitcher());\n\n        var selectControl = new OpenLayers.Control.SelectFeature(\n            vectorLayer,\n            {\n                clickout: true, toggle: false,\n                multiple: false, hover: false,\n                toggleKey: \"ctrlKey\", // ctrl key removes from selection\n                multipleKey: \"shiftKey\", // shift key adds to selection\n            }\n        );\n\n        map.addControl(selectControl);\n        selectControl.activate();\n\n        map.addControl(new OpenLayers.Control.Navigation());\n        map.setCenter(new OpenLayers.LonLat(-75.1641667, 39.9522222), 10);\n\n        var createRandomFeatures = function() {\n            var extent = map.getExtent();\n            var features = [];\n            for(var i=0; i<10; ++i) {\n                features.push(new OpenLayers.Feature.Vector(\n                    new OpenLayers.Geometry.Point(extent.left + (extent.right - extent.left) * Math.random(),\n                    extent.bottom + (extent.top - extent.bottom) * Math.random()\n                )));\n            }\n            return features;\n        }\n\n        vectorLayer.addFeatures(createRandomFeatures());\n        </script>\n    </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/select-feature.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <title>Select Feature Test</title>\n    <style type=\"text/css\">\n        body {\n            font-size: 0.8em;\n        }\n        p {\n            padding-top: 1em;\n        }\n        #map {\n            margin: 1em;\n            width: 512px;\n            height: 512px;\n        }\n    </style>\n\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var map, selectControl1, selectControl2;\n\n        function init() {\n            map = new OpenLayers.Map('map');\n            var wmsLayer = new OpenLayers.Layer.WMS(\n                \"OpenLayers WMS\", \n                \"http://labs.metacarta.com/wms/vmap0\",\n                {layers: 'basic'}\n            ); \n            var vectorLayer = new OpenLayers.Layer.Vector(\"Vector Layer\");\n            var pointFeature = new OpenLayers.Feature.Vector(\n                 new OpenLayers.Geometry.Point(-50, -45)\n            );\n            var polygonFeature = new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.Polygon([\n                    new OpenLayers.Geometry.LinearRing([\n                        new OpenLayers.Geometry.Point(-50,-50),\n                        new OpenLayers.Geometry.Point(-40,-50),\n                        new OpenLayers.Geometry.Point(-40,-40),\n                        new OpenLayers.Geometry.Point(-50,-50)\n                    ])\n                ])\n            );\n            vectorLayer.addFeatures([pointFeature, polygonFeature]);\n            map.addLayers([wmsLayer, vectorLayer]);\n            selectControl1 = new OpenLayers.Control.SelectFeature(\n                vectorLayer, {geometryTypes: ['OpenLayers.Geometry.Point']}\n            );\n            selectControl2 = new OpenLayers.Control.SelectFeature(\n                vectorLayer, {\n                    geometryTypes: ['OpenLayers.Geometry.Polygon'],\n                    hover: true\n            });\n            map.addControl(new OpenLayers.Control.MousePosition());\n            map.addControl(selectControl1);\n            map.addControl(selectControl2);\n            selectControl1.activate();\n            selectControl2.activate();\n            map.setCenter(new OpenLayers.LonLat(-45, -45), 4);\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h1 id=\"title\">Select Feature Test</h1>\n    <div id=\"map\"></div>\n    <p>\n    \n    The map includes two select feature controls. The first one operates on\n    geometries of type OpenLayers.Geometry.Point only and works on clicks. The\n    second one operates on geometries of type OpenLayers.Geometry.Polygon and\n    works on mouseover's. If you select the point geometry by clicking on it,\n    it shouldn't be unselected when the mouse moves out if it.\n    \n    </p>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/tiles-loading.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <title>Tiles Loading Acceptance Test</title>\n    <style type=\"text/css\">\n        body {\n            font-size: 0.8em;\n        }\n        p {\n            padding-top: 1em;\n        }\n        #map {\n            margin: 1em;\n            float: left;\n            width: 512px;\n            height: 512px;\n        }\n\n    </style>\n\n    <script src=\"http://maps.google.com/maps/api/js?v=3&amp;sensor=false\"></script>\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        // make map available for easy debugging\n        var map;\n\n        // increase reload attempts \n        OpenLayers.IMAGE_RELOAD_ATTEMPTS = 3;\n\n        function init(){\n            var options = {\n                controls: [],\n                projection: \"EPSG:900913\",\n                units: \"m\",\n                maxResolution: 156543.0339,\n                maxExtent: new OpenLayers.Bounds(-20037508, -20037508,\n                                                 20037508, 20037508.34)\n            };\n            map = new OpenLayers.Map('map', options);\n            // create Google Mercator layers\n            var gmap = new OpenLayers.Layer.Google(\n                \"Google Streets\",\n                {'sphericalMercator': true}\n            );\n            // create WMS layer\n            var wmsMaxResolution = 78271.51695;\n            var wms = new OpenLayers.Layer.WMS(\n                \"World Map\",\n                \"http://world.freemap.in/tiles/\",\n                {'layers': 'factbook-overlay', 'format':'png'},\n                {\n                    'opacity': 0.4,\n                    'isBaseLayer': false,\n                    'wrapDateLine': true,\n                    'buffer': 0,\n                    'maxResolution' : wmsMaxResolution\n                }\n            );\n            map.addLayers([gmap, wms]);\n            map.addControl(new OpenLayers.Control.Navigation());\n            map.addControl(new OpenLayers.Control.LayerSwitcher());\n            map.addControl(new OpenLayers.Control.PanZoomBar());\n\n            function onLayerChanged() {\n                var html = '<p>WMS Layer state - in range: '\n                    + this.inRange\n                    + ', visibility: '\n                    + this.visibility;\n                    + '</p>';\n                document.getElementById('layerstate').innerHTML = html;\n            }\n            map.events.register('changelayer', wms, onLayerChanged);\n\n            function onTileLoaded() {\n                var html = '<p>Message: ';\n                if (this.numLoadingTiles > 0) {\n                    html += 'Loading tiles...';\n                } else {\n                    html += 'Done loading tiles';\n                }\n                html += '</p>';\n                document.getElementById('tilesloading').innerHTML = html;\n            }\n            wms.events.register('tileloaded', wms, onTileLoaded);\n\n            map.zoomToMaxExtent()\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <div id=\"map\"></div>\n    <p>\n\n      <b>Test 0</b> : at the initial zoom the WMS layer is in range, you should\n      therefore see the 'Loading tiles...' message when loading the page for\n      the first time.\n\n    </p>\n    <p>\n\n      <b>Test 1</b> : If you zoom out by one level (using the zoombar), the WMS\n      layer becomes out of range. No tile should be loaded so you shouldn't see\n      the 'Loading tiles...' message.\n\n    </p>\n    <p>\n\n      <b>Test 2</b> : Zoom in by one level to go back to initial state (the WMS\n      is back). Open the layer switcher and turn off the WMS layer. No tile\n      should be loaded so you shouldn't see the 'Loading tiles...' message.\n\n    </p>\n    <p>\n\n      <b>Test 3</b> : Keep the WMS layer turned off in the layer switcher. Zoom\n      out by one level again. The layer is both invisible and out of range, so\n      you shouldn't see the 'Loading tiles...' message.\n\n    </p>\n    <div id=\"layerstate\"><p>WMS Layer state - in range: true, visibility: true</p></div>\n    <div id=\"tilesloading\"><p>Message:</p></div>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/tween.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <title>Tween Example</title>\n    <style type=\"text/css\">\n        #viewport {\n            width: 500px;\n            height: 300px;\n            border: 1px solid black;\n        }\n        #block {\n            width: 10px;\n            height: 10px;\n            background-color: red;\n            position: absolute;\n        }\n    </style>\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var tween, events;\n\n        function init(){\n            tween = new OpenLayers.Tween(OpenLayers.Easing.Linear.easeIn);\n            \n            events = new OpenLayers.Events(null, OpenLayers.Util.getElement('viewport'), null, true);\n            events.register(\"mousedown\", null, moveBlock);\n            \n            changeTween();\n        }\n        function moveBlock(e) {\n            var block = OpenLayers.Util.getElement('block');\n            var viewport = OpenLayers.Util.getElement('viewport');\n            var blockPosition = OpenLayers.Util.pagePosition(block);\n            var viewportPosition = OpenLayers.Util.pagePosition(viewport);\n            e.xy = events.getMousePosition(e);\n            var from = {\n                x: blockPosition[0] - viewportPosition[0],\n                y: blockPosition[1] - viewportPosition[1]\n            };\n            var to = {\n                x: e.xy.x,\n                y: e.xy.y\n            }\n            var duration = OpenLayers.Util.getElement('duration').value;\n            var callbacks = {\n                eachStep: function(value) {\n                    block.style.left = (value.x + viewportPosition[0]) + 'px';\n                    block.style.top = (value.y + viewportPosition[1]) + 'px';\n                }\n            }\n            tween.start(from, to, duration, {callbacks: callbacks});\n            \n        }\n        function changeTween() {\n            var transition = OpenLayers.Util.getElement('transition').value;\n            var easing = OpenLayers.Util.getElement('easing').value;\n            tween.stop();\n            tween.easing = OpenLayers.Easing[transition][easing];\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <div id=\"title\">Tween Example</div>\n    <div id=\"tags\"></div>\n    <div id=\"shortdesc\">Show transition effects</div>\n    <select name=\"transition\" id=\"transition\" onchange=\"changeTween()\">\n        <option value=\"Linear\">Linear</option>\n        <option value=\"Expo\">Expo</option>\n        <option value=\"Quad\">Quad</option>\n    </select>\n    <select name=\"easing\" id=\"easing\" onchange=\"changeTween()\">\n        <option value=\"easeIn\">EaseIn</option>\n        <option value=\"easeOut\">EaseOut</option>\n    </select>\n    <input type=\"text\" name=\"duration\" id=\"duration\" value=\"100\"></input>\n    <div id=\"viewport\">\n        <div id=\"block\"></div>\n    </div>\n    <div id=\"docs\">\n        This is an example of transition effects.\n    </div>\n  </body>\n</html>"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/vector-features-performance.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <title>Vector Features Performance Test</title>\n    <style type=\"text/css\">\n        body {\n            font-size: 0.8em;\n        }\n        p {\n            padding-top: 1em;\n        }\n        #map {\n            width: 512px;\n            height: 512px;\n            border: 1px solid black;\n        }\n    </style>\n\n    <script src=\"../../lib/Firebug/firebug.js\"></script>\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var map, vectorLayer, drawFeature, features\n        \n        var run = 0;\n        \n        function nextRun() {\n            window.setTimeout(function() {\n                if (run < 5) {\n                    vectorLayer.removeFeatures(features);\n                }\n            }, 900);\n            \n            window.setTimeout(function(){\n                run++;\n                \n                switch(run) {\n                    case 1:\n                        console.log(\"First run - feature bboxes will be cached\");\n                        map.setCenter(new OpenLayers.LonLat(-22.5, -22.5), 3);\n                        vectorTestNew()\n                        break;\n                    case 2:\n                        console.log(\"Test with all features inside extent\");\n                        vectorTestOld();\n                        break;\n                    case 3:\n                        vectorTestNew();\n                        break;\n                    case 4:\n                        console.log(\"Test with some features outside extent\");\n                        map.setCenter(new OpenLayers.LonLat(-22.5, -22.5), 5);\n                        vectorTestOld();\n                        break;\n                    case 5:\n                        vectorTestNew();\n                        break;\n                }\n            }, 1000);\n        }\n        \n        function vectorTestOld(){            \n            vectorLayer.renderer.drawFeature = function(feature, style) {\n                if(style == null) {\n                    style = feature.style;\n                }\n                if (feature.geometry) {\n                    this.drawGeometry(feature.geometry, style, feature.id);\n                }\n            };\n\n            console.time(\"addFeaturesOld\");\n            vectorLayer.addFeatures(features);\n            console.timeEnd(\"addFeaturesOld\");\n        }\n        \n        function vectorTestNew() {\n            vectorLayer.renderer.drawFeature = OpenLayers.Renderer[vectorLayer.renderer.CLASS_NAME.split(\".\")[2]].prototype.drawFeature;\n            \n            console.time(\"addFeatures\");\n            vectorLayer.addFeatures(features);\n            console.timeEnd(\"addFeatures\");\n        }\n\n        function init(){\n            // allow testing of specific renderers via \"?renderer=Canvas\", etc\n            var renderer = OpenLayers.Util.getParameters(window.location.href).renderer;\n            renderer = (renderer) ? [renderer] : OpenLayers.Layer.Vector.prototype.renderers;\n\n            map = new OpenLayers.Map('map');\n            \n            vectorLayer = new OpenLayers.Layer.Vector(\"Vector Layer\", {\n                isBaseLayer: true,\n                renderers: renderer\n            });\n\n            map.addLayers([vectorLayer]);\n            map.addControl(new OpenLayers.Control.MousePosition());\n            map.setCenter(new OpenLayers.LonLat(-22.5, -22.5), 3);\n\n            vectorLayer.events.register(\"featuresadded\", this, nextRun);\n            \n            features = new Array(200);\n            var x, y\n            for (var i = 0; i < 200; i++) {\n                x = -Math.random()*45;\n                y = -Math.random()*45;\n                features[i] = new OpenLayers.Feature.Vector(\n                    new OpenLayers.Geometry.LinearRing([\n                        new OpenLayers.Geometry.Point(\n                            -Math.random()*5+x, -Math.random()*5+y),\n                        new OpenLayers.Geometry.Point(\n                            -Math.random()*5+x, -Math.random()*5+y),\n                        new OpenLayers.Geometry.Point(\n                            -Math.random()*5+x, -Math.random()*5+y),\n                        new OpenLayers.Geometry.Point(\n                            -Math.random()*5+x, -Math.random()*5+y),\n                        new OpenLayers.Geometry.Point(\n                            -Math.random()*5+x, -Math.random()*5+y),\n                        new OpenLayers.Geometry.Point(\n                            -Math.random()*5+x, -Math.random()*5+y),\n                        new OpenLayers.Geometry.Point(\n                            -Math.random()*5+x, -Math.random()*5+y),\n                        new OpenLayers.Geometry.Point(\n                            -Math.random()*5+x, -Math.random()*5+y),\n                        new OpenLayers.Geometry.Point(\n                            -Math.random()*5+x, -Math.random()*5+y),\n                        new OpenLayers.Geometry.Point(\n                            -Math.random()*5+x, -Math.random()*5+y)\n                    ]));\n                    \n            }\n            \n            nextRun();\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h1 id=\"title\">New Rendering - Vector Features Performance Test</h1>\n    <div id=\"map\"></div>\n    <p>\n    This test examines if checking for a feature being inside the visible\n    extent before rendering it has an impact on performance. Open the Firebug\n    console after running this test (hit F12) to see the results.\n    <br/>\n    After the performance test, you can drag around the map to see how the new\n    vector rendering feels where features get rendered only when they are visible\n    inside the map extent. \n    </p>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/manual/vector-layer-zindex.html",
    "content": "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n  <head>\n    <title>Vector Layer ZIndex Test</title>\n    <style type=\"text/css\">\n        body {\n            font-size: 0.8em;\n        }\n        p {\n            padding-top: 1em;\n        }\n        #map {\n            margin: 1em;\n            width: 512px;\n            height: 512px;\n        }\n    </style>\n\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script type=\"text/javascript\">\n        var map, layerA, layerB, layerV, selectControl1, selectControl2;\n\n        function init() {\n            map = new OpenLayers.Map('map');\n            var wmsLayer = new OpenLayers.Layer.WMS(\n                \"OpenLayers WMS\", \n                \"http://labs.metacarta.com/wms/vmap0\",\n                {layers: 'basic'}\n            );\n\n            layerV = new OpenLayers.Layer.Vector('v');\n            var feature = new OpenLayers.Feature.Vector(\n                new OpenLayers.Geometry.Polygon([\n                    new OpenLayers.Geometry.LinearRing([\n                        new OpenLayers.Geometry.Point(-110, 60),\n                        new OpenLayers.Geometry.Point(-110, 30),\n                        new OpenLayers.Geometry.Point(-80, 30),\n                        new OpenLayers.Geometry.Point(-110, 60)\n                    ])\n                ])\n            );\n            layerV.addFeatures([feature]);\n            selectControl1 = new OpenLayers.Control.SelectFeature(layerV);\n            selectControl2 = new OpenLayers.Control.SelectFeature(layerV, {\n                hover: true,\n                selectStyle: OpenLayers.Util.applyDefaults({fillColor: \"red\"}, OpenLayers.Feature.Vector.style[\"select\"]),\n                onSelect: function(feature) {\n                    selectControl2.unselect(feature);\n                    layerV.drawFeature(feature, selectControl2.selectStyle);\n                }\n            });\n            selectControl2.events.register(\"beforefeatureselected\", null, function(feature) {\n                layerV.drawFeature(feature, selectControl2.selectStyle);\n                return false;\n            })\n\n            layerA = new OpenLayers.Layer('a', {'isBaseLayer': false});\n            layerB = new OpenLayers.Layer.WMS(\n                'b', 'http://www2.dmsolutions.ca/cgi-bin/mswms_gmap', {\n                    'layers': [\n                        'bathymetry', 'land_fn', 'park', 'drain_fn', 'drainage',\n                        'prov_bound', 'fedlimit', 'rail', 'road', 'popplace'\n                    ],\n                    'transparent': 'true',\n                    'format': 'image/png'\n                }, {\n                    'reproject': false\n            });\n\n            map.addLayers([wmsLayer, layerV, layerA, layerB]);\n            map.addControl(selectControl2);\n            map.addControl(selectControl1);\n            map.addControl(new OpenLayers.Control.MousePosition());\n            selectControl2.activate();\n            selectControl1.activate();\n\n            map.setCenter(new OpenLayers.LonLat(-90, 20), 2);\n        }\n\n        function removeLayerA() {\n            if (OpenLayers.Util.indexOf(map.layers, layerA) > -1) {\n                map.removeLayer(layerA);\n            }\n        }\n        \n        function toggleSelectControl1() {\n            if (selectControl1.active) {\n                selectControl1.deactivate();\n                alert(\"SelectFeature control for clicks deactivated.\");\n            } else {\n                selectControl1.activate();\n                alert(\"SelectFeature control for clicks activated.\");\n            }\n        }\n\n        function toggleSelectControl2() {\n            if (selectControl2.active) {\n                selectControl2.deactivate();\n                alert(\"SelectFeature control for hover deactivated.\");\n            } else {\n                selectControl2.activate();\n                alert(\"SelectFeature control for hover activated.\");\n            }\n        }\n    </script>\n  </head>\n  <body onload=\"init()\">\n    <h1 id=\"title\">Vector Layer ZIndex Test</h1>\n    <div id=\"map\"></div>\n    <p>\n\n    The map includes one base layer (vmap0) and three overlays, namely a vector\n    layer, a fake layer with no images, and a dmsolutions layer. The overlays are\n    added to the map in this order: the vector layer, the fake layer, and the\n    dmsolutions layer. The map also includes a select feature control, which\n    when activated bumped the vector layer z-index to some high value. This\n    makes feature selection work, even though other overlays were added after\n    the vector layer.\n       \n    </p>\n    <p>\n\n    If the fake layer is removed from the map (first link below), the vector layer's\n    z-index must not be reset, so the vector layer must not go under the\n    dmsolutions layer and feature selection must continue to function as\n    expected.\n       \n    </p>\n    <p>\n\n    If one of the SelectFeature controls is deactivated or activated (second\n    and third link below), the vector layer should change it's position in the\n    layer stack: on top if at least one of the controls is activated, covered\n    by other layers if both are deactivated.\n\n    </p>\n\n    <p>\n      <a href=\"javascript:removeLayerA()\">Remove the fake layer</a>\n      <br/><a href=\"javascript:toggleSelectControl1()\">Toggle the click SelectFeature control's active status</a>\n      <br/><a href=\"javascript:toggleSelectControl2()\">Toggle the hover SelectFeature control's active status</a>\n    </p>\n  </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/mice.xml",
    "content": "<?xml version='1.0' encoding=\"ISO-8859-1\" ?>\n<wfs:FeatureCollection\n   xmlns:bsc=\"http://www.bsc-eoc.org/bsc\"\n   xmlns:wfs=\"http://www.opengis.net/wfs\"\n   xmlns:gml=\"http://www.opengis.net/gml\"\n   xmlns:ogc=\"http://www.opengis.net/ogc\"\n   xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n   xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengeospatial.net//wfs/1.0.0/WFS-basic.xsd \n                       http://www.bsc-eoc.org/bsc http://www.bsc-eoc.org/cgi-bin/bsc_ows.asp?SERVICE=WFS&amp;VERSION=1.0.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=OWLS&amp;OUTPUTFORMAT=XMLSCHEMA\">\n      <gml:boundedBy>\n      \t<gml:Box srsName=\"EPSG:4326\">\n      \t\t<gml:coordinates>-89.817223,45.005555 -74.755001,51.701388</gml:coordinates>\n      \t</gml:Box>\n      </gml:boundedBy>\n    <gml:featureMember><bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-79.771668,45.891110 -79.771668,45.891110</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-79.771668,45.891110</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.755834,46.365277 -83.755834,46.365277</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:owlname>owl</bsc:owlname>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.755834,46.365277</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.808612,46.175277 -83.808612,46.175277</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.808612,46.175277</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-84.111112,46.309166 -84.111112,46.309166</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-84.111112,46.309166</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.678612,46.821110 -83.678612,46.821110</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.678612,46.821110</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.664445,46.518888 -83.664445,46.518888</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.664445,46.518888</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-80.613334,46.730277 -80.613334,46.730277</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-80.613334,46.730277</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-79.676946,45.428054 -79.676946,45.428054</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-79.676946,45.428054</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.853056,46.236944 -83.853056,46.236944</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.853056,46.236944</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-82.289167,45.896388 -82.289167,45.896388</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-82.289167,45.896388</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n</wfs:FeatureCollection>\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/node.js/mockdom.js",
    "content": "XMLHttpRequest = function() { \n    return { \n    'open': function() {  },\n    'send': function() {  }\n    }\n};\n\nnavigator = {\n  'appName': 'mockdom',\n  'userAgent': 'mockdom',\n  'appVersion': '0.1',\n  'language': 'en',\n  'userLanguage': 'en'\n}  \n\nelement = function(type) {\n    type = type || \"\";\n\n    return {\n        'childNodes': [],\n        'className': '',\n        'tagName': type.toUpperCase(),\n        'style': {},\n        'setAttribute': function(attr, value) {\n            this[attr] = value;\n        },    \n        'appendChild': function(element) {\n            if (this.childNodes.length) {\n                this.childNodes[this.childNodes.length - 1].nextSibling = element;\n            }  else {\n                this.firstChild = element;\n            }    \n            element.parentNode = this;\n            this.childNodes.push(element);\n\n        }, \n        'removeChild': function(element) {\n            var i = this.childNodes.indexOf(element);\n            this.childNodes.splice(i, 1);\n        },    \n        'addEventListener': function() {\n        },\n        'removeEventListener': function() {\n        },\n        'getElementsByTagName': function(name, externalList) {\n            var uc = name.toUpperCase();\n            var list = externalList || [];\n            for(var i = 0; i < this.childNodes.length; i++) {\n                if (this.childNodes[i].tagName == uc) {\n                    list.push(this.childNodes[i]);\n                }\n                this.childNodes[i].getElementsByTagName(name, list);\n            }\n            return list;\n        },\n        'getElementById': function(id) {\n            for(var i = 0; i < this.childNodes.length; i++) {\n                if (this.childNodes[i].id == id) {\n                    return this.childNodes[i];\n                } else {\n                    var elem = this.childNodes[i].getElementById(id);\n                    if (elem) { \n                        return elem\n                    }\n                }\n            }\n        }\n    }\n};\n\ndocument = element();\ndocument.createElement = function(type) {\n     return element(type);\n};\ndocument.createTextNode = function(text) {\n    var e = element(\"Text\");\n    e.innerHTML = text;\n}\n\ndocument.appendChild(element(\"head\"));\ndocument.body = element(\"body\");\ndocument.appendChild(document.body);\n\nwindow = {\n    'addEventListener': function() {\n    },\n    'getSelection': function() {\n        return {\n            collapseToStart: function() {}\n        }\n    },\n    document: document,\n    navigator: navigator,\n    location: {\n        href: '#',\n        port: '',\n        hostname: 'openlayers.org',\n        host: 'openlayers.org',\n        proto: 'https'\n    }    \n};\ndocument.location = window.location;\n\nwindow.Function = Function;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/node.js/node-tests.cfg",
    "content": "# This build config is supposed to be used for the units tests with \"mode=build\"\n\n[first]\nmockdom.js\n[last]\nnode.js\n\n[include]\n\n[exclude]\nOpenLayers.js\nFirebug/firebug.js\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/node.js/node.js",
    "content": "exports.OpenLayers = OpenLayers;\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/node.js/run-test.js",
    "content": "// Requires:\n/// 0. nodejs\n//  1. jsdom installed (npm install jsdom)\n//  2. A build profile with mockdom.js included in [first], and node.js \n//     inclded in [last], at ../../build/OpenLayers.js , like node-tests.js.\n//  3. Run with node run-tests.js\n//\n//  Missing: integration with a solid node.js testrunner.\nvar jsdom = require('jsdom'); \njsdom.env('<html><body></body></html>', function(errors, window) { \n    for (var i in window) { \n        if (i == \"console\") {\n            continue;\n        }    \n        eval(i+\"=window['\"+i+\"'];\"); \n    }\n    OpenLayers = require(\"../../build/OpenLayers.js\")['OpenLayers'];\n    var map = new OpenLayers.Map(document.createElement(\"map\"));\n    map.addLayer(new OpenLayers.Layer(\"\", {isBaseLayer:true}));\n    map.setCenter(new OpenLayers.LonLat(-71,42), 10);\n    var px = map.getPixelFromLonLat(map.getLonLatFromPixel(new OpenLayers.Pixel(100,100)));\n    console.log(px);\n    var px = map.getLonLatFromPixel(map.getPixelFromLonLat(new OpenLayers.LonLat(10,10)));\n    console.log(px);\n    \n});\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/node.js/run.sh",
    "content": "#!/bin/sh\ncp mockdom.js node.js ../../lib\ncp node-tests.cfg ../../build\ncd ../../build\npython build.py -c none node-tests\ncd ../tests/node.js/\n\nnode run-test.js\nrm ../../lib/mockdom.js\nrm ../../lib/node.js\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/owls.xml",
    "content": "<?xml version='1.0' encoding=\"ISO-8859-1\" ?>\n<wfs:FeatureCollection\n   xmlns:bsc=\"http://www.bsc-eoc.org/bsc\"\n   xmlns:wfs=\"http://www.opengis.net/wfs\"\n   xmlns:gml=\"http://www.opengis.net/gml\"\n   xmlns:ogc=\"http://www.opengis.net/ogc\"\n   xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n   xsi:schemaLocation=\"http://www.opengis.net/wfs http://schemas.opengeospatial.net//wfs/1.0.0/WFS-basic.xsd \n                       http://www.bsc-eoc.org/bsc http://www.bsc-eoc.org/cgi-bin/bsc_ows.asp?SERVICE=WFS&amp;VERSION=1.0.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=OWLS&amp;OUTPUTFORMAT=XMLSCHEMA\">\n      <gml:boundedBy>\n      \t<gml:Box srsName=\"EPSG:4326\">\n      \t\t<gml:coordinates>-89.817223,45.005555 -74.755001,51.701388</gml:coordinates>\n      \t</gml:Box>\n      </gml:boundedBy>\n    <gml:featureMember><bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-79.771668,45.891110 -79.771668,45.891110</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-79.771668,45.891110</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.755834,46.365277 -83.755834,46.365277</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:owlname>owl</bsc:owlname>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.755834,46.365277</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.808612,46.175277 -83.808612,46.175277</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.808612,46.175277</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-84.111112,46.309166 -84.111112,46.309166</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-84.111112,46.309166</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.678612,46.821110 -83.678612,46.821110</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.678612,46.821110</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.664445,46.518888 -83.664445,46.518888</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.664445,46.518888</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-80.613334,46.730277 -80.613334,46.730277</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-80.613334,46.730277</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-79.676946,45.428054 -79.676946,45.428054</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-79.676946,45.428054</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-83.853056,46.236944 -83.853056,46.236944</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-83.853056,46.236944</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n    <gml:featureMember>\n      <bsc:OWLS>\n        <gml:boundedBy>\n        \t<gml:Box srsName=\"EPSG:4326\">\n        \t\t<gml:coordinates>-82.289167,45.896388 -82.289167,45.896388</gml:coordinates>\n        \t</gml:Box>\n        </gml:boundedBy>\n        <bsc:msGeometry>\n        <gml:Point srsName=\"EPSG:4326\">\n          <gml:coordinates>-82.289167,45.896388</gml:coordinates>\n        </gml:Point>\n        </bsc:msGeometry>\n      </bsc:OWLS>\n    </gml:featureMember>\n</wfs:FeatureCollection>\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/run-tests.html",
    "content": "<!DOCTYPE html>\n<html>\n    <head>\n        <title>Run the testsuite</title>\n        <noscript>\n            Javascript is disabled in your browser. This page cannot be \n            displayed correctly without Javascript. Sorry. \n            <br/>\n            If you want to view this page, please change your browser settings\n            so that Javascript is enabled.\n        </noscript>\n        <!--\n        \n        Test.AnotherWay version 0.5\n        \n        Copyright (c) 2005 Artem Khodush, http://straytree.org\n        \n        Permission is hereby granted, free of charge, to any person obtaining\n        a copy of this software and associated documentation files (the\n        \"Software\"), to deal in the Software without restriction, including\n        without limitation the rights to use, copy, modify, merge, publish,\n        distribute, sublicense, and/or sell copies of the Software, and to\n        permit persons to whom the Software is furnished to do so, subject to\n        the following conditions:\n        \n        The above copyright notice and this permission notice shall be\n        included in all copies or substantial portions of the Software.\n        \n        THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n        EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n        MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n        NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\n        LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\n        OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\n        WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n        \n        -->\n        <link rel=\"stylesheet\" href=\"Test.AnotherWay.css\" />\n        <script type=\"text/javascript\" src=\"Test.AnotherWay.js\"></script>\n        <script type=\"text/javascript\" src=\"Test.AnotherWay.baseadditions.js\"></script>\n        <script type=\"text/javascript\" src=\"Test.AnotherWay.xml_eq.js\"></script>\n        <script type=\"text/javascript\" src=\"Test.AnotherWay.geom_eq.js\"></script>\n    </head>\n    <body>\n        <div id=\"col1\">\n            <div id=\"col1_header\">\n                Test pages:\n                <input id=\"quickfilter\" placeholder=\"quick filter\">\n            </div>\n            <div id=\"scroller\">\n                <table id=\"testtable\">\n                </table>\n            </div>\n            <div id=\"run_buttons\">\n                <input type=\"button\" value=\" clear \" id=\"clear_btn\" /><input type=\"button\" value=\" run all \" id=\"run_all\" /><input type=\"button\" value=\" run selected \" id=\"run_selected\" /><input type=\"button\" value=\" unselect all \" id=\"unselect_all\" />\n            </div>\n            <div id=\"running-time\">\n            </div>\n            <input type=\"checkbox\" id=\"dont_close_test_windows\" /> do not close windows opened by tests\n            <div id=\"error\">\n            </div>\n            <div id=\"record_div\">\n                <p id=\"record_not_supported\" style=\"display:none\">\n                </p>\n                <p>\n                    Record mouse input for the page:\n                </p>\n                <p>\n                    <input type=\"radio\" name=\"record_choose\" value=\"select\" checked=\"checked\" />\n                    <select id=\"record_select\">\n                        <option selected=\"selected\">-- select a page: --</option>\n                    </select>\n                </p>\n                <p>\n                    <input type=\"radio\" name=\"record_choose\" value=\"input\" /> or enter page url: <input type=\"text\" id=\"record_input\" />\n                </p>\n                <p>\n                    <input type=\"button\" value=\" record \" id=\"record_start\" />\n                </p>\n            </div>\n        </div>\n        <div id=\"col2\">\n            <div id=\"right_header\">\n                <span id=\"results_count\">Results: <span id=\"total\"></span></span>\n                <span id=\"results_tab\" class=\"active_tab\" style=\"visibility:hidden\">Results</span>\n                <span id=\"debug_tab\" class=\"inactive_tab\" style=\"visibility:hidden\">Debug</span>\n            </div>\n            <div id=\"right_frame\">\n                <div id=\"results\">\n                </div>\n                <div id=\"debug\">\n                </div>\n            </div>\n        </div>\n        <span>\n            <iframe id=\"test_iframe_el\" style=\"display:none\" name=\"test_iframe\" onload=\"Test.AnotherWay._test_page_onload();\">\n            </iframe>\n        </span>\n        <span style=\"display:none\">\n            <iframe name=\"list_iframe\" onload=\"Test.AnotherWay._list_iframe_onload();\">\n            </iframe>\n            <!-- record_control div is to be imported into other documents, so all its styles are inline -->-\n            <div id=\"record_control\" style=\"position:absolute;bottom:0;left:0;margin:0;padding:0.5em;width:22em;height:22em;border:1px solid;background:#ffd;font: normal normal 8pt sans-serif; color:#000; text-align: left\">\n                <p style=\"margin:0 0 0 0; padding:0\">\n                    &nbsp;<span style=\"display:none;font-weight:bold;color:#408\" id=\"record_indicator\">recording. <span style=\"font-weight:normal\">time: <span id=\"record_time\"></span></span><span id=\"record_pause_indicator\">paused</span></span>\n                </p>\n                <div id=\"record_cursor_over\" style=\"margin:0;padding:2px;width:14em;height:1.1em;overflow:hidden;float:right;border:1px solid #777;background:#fff;font: normal normal 8pt sans-serif;position:relative;top:3px;color:#000;text-align:left;\">\n                    &nbsp;\n                </div>\n                <p style=\"margin:2px 0 0 0; padding:0\">\n                    cursor is over\n                </p>\n                <p style=\"margin:8px 0 0 0; padding:0;\">\n                    keyboard control: press<span id=\"record_ctrl_key\" style=\"border:1px solid #226;background:#adf;padding:0 0.5em\">ctrl</span>\n                    -<span id=\"record_shift_key\" style=\"border:1px solid #226;background:#adf;padding:0 0.5em\">shift</span>\n                    -\n                </p>\n                <p style=\"margin:4px 0 0 0; padding:0\">\n                    <span id=\"record_s\" style=\"border:1px solid #226;background:#adf;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em\">s</span>\n                    <span id=\"record_on\">to <b>start</b> recording</span>\n                    <span id=\"record_off\" style=\"display:none\">to <b>stop</b> recording</span>\n                </p>\n                <p style=\"margin:4px 0 0 0; padding:0\">\n                    <span id=\"record_h\" style=\"border:1px solid #226;background:#adf;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em\">h</span>\n                    <span>to <b>hide/show</b> this window</span>\n                </p>\n                <p style=\"margin:4px 0 0 0; padding:0\">\n                    <span id=\"record_m\" style=\"border:1px solid #226;background:#adf;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em\">m</span>\n                    <span id=\"record_include_mousemove\">to <b>record</b> mousemove</span>\n                    <span id=\"record_omit_mousemove\" style=\"display:none\">to <b>omit</b> mousemove</span>\n                </p>\n                <p style=\"margin:4px 0 0 0; padding:0\">\n                    <span id=\"record_p\" style=\"border:1px solid #226;background:#aaa;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em\">p</span>\n                    <span id=\"record_pause_on\">to <b>pause</b> recording</span>\n                    <span id=\"record_pause_off\" style=\"display:none\">to <b>continue</b> recording</span>\n                </p>\n                <p style=\"margin:4px 0 0 0; padding:0\">\n                    <span id=\"record_c\" style=\"border:1px solid #226;background:#aaa;width:1.2em;float:left;font-weight:bold;text-align:center;margin-right:0.5em\">c</span>\n                    <span>to add checkpoint</span>\n                </p>\n                <p style=\"margin:6px 0 0 0; padding:0\">\n                    checkpoints:\n                </p>\n                <div id=\"record_checkpoints\" style=\"position:relative;width:100%;height:6em;overflow:auto;font: normal normal 8pt sans-serif; color:#000; text-align: left\">\n                </div>\n            </div>\n        </span>\n        <script>\n            if (/noscroll/.test(location.href)) {\n                document.getElementById('scroller').style.height = 'auto';\n                document.getElementById('right_frame').style.height = 'auto';\n            }\n        </script>\n    </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/selenium/remotecontrol/config.cfg",
    "content": "[config]\nserver=http://openlayers.org/\nurl=/dev/tests/run-tests.html?run=all&windows=none\n\n[local_ff]\nhost=localhost\nbrowserCmd=firefox\ncomment=Firefox on localhost\n\n[local_safari]\nhost=localhost\nbrowserCmd=safari\ncomment=Safari  on localhost\n\n#[ie6-winxp]\n#host=208.80.142.184\n#browserCmd=iexploreproxy C:\\Program Files\\MultipleIEs\\IE6\\iexplore.exe\n#comment=IE6 on WinXP\n\n[ie7-winxp]\nhost=208.80.142.184\nbrowserCmd=iexploreproxy\ncomment=IE7 on WinXP\n\n# Running on alta: debian etch\n[opera-winxp]\nhost=208.80.142.184\nbrowserCmd=opera C:\\Program Files\\Opera 9\\Opera.exe\ncomment=Opera on WinXP \n\n# Running on alta: debian etch\n[opera]\nhost=208.80.142.140\nbrowserCmd=opera\ncomment=Opera on Debian Etch\n\n# Running on alta: Debian Etch\n[firefox2]\nhost=208.80.142.140\nbrowserCmd=firefox /usr/lib/iceweasel/firefox-bin\ncomment=Iceweasel 2 on Debian Etch\n\n# Running on alta: Debian Etch\n[firefox3]\nhost=208.80.142.105\nbrowserCmd=firefox /usr/lib/firefox-3.0.1/firefox-bin\ncomment=FF3 on Ubuntu \n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/selenium/remotecontrol/selenium.py",
    "content": "\n\"\"\"\nCopyright 2006 ThoughtWorks, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\"\"\"\n__docformat__ = \"restructuredtext en\"\n\n# This file has been automatically generated via XSL\n\nimport httplib\nimport urllib\nimport re\n\nclass selenium:\n    \"\"\"\n    Defines an object that runs Selenium commands.\n    \n    Element Locators\n    ~~~~~~~~~~~~~~~~\n    \n    Element Locators tell Selenium which HTML element a command refers to.\n    The format of a locator is:\n    \n    \\ *locatorType*\\ **=**\\ \\ *argument*\n    \n    \n    We support the following strategies for locating elements:\n    \n    \n    *   \\ **identifier**\\ =\\ *id*: \n        Select the element with the specified @id attribute. If no match is\n        found, select the first element whose @name attribute is \\ *id*.\n        (This is normally the default; see below.)\n    *   \\ **id**\\ =\\ *id*:\n        Select the element with the specified @id attribute.\n    *   \\ **name**\\ =\\ *name*:\n        Select the first element with the specified @name attribute.\n        \n        *   username\n        *   name=username\n        \n        \n        The name may optionally be followed by one or more \\ *element-filters*, separated from the name by whitespace.  If the \\ *filterType* is not specified, \\ **value**\\  is assumed.\n        \n        *   name=flavour value=chocolate\n        \n        \n    *   \\ **dom**\\ =\\ *javascriptExpression*: \n        \n        Find an element by evaluating the specified string.  This allows you to traverse the HTML Document Object\n        Model using JavaScript.  Note that you must not return a value in this string; simply make it the last expression in the block.\n        \n        *   dom=document.forms['myForm'].myDropdown\n        *   dom=document.images[56]\n        *   dom=function foo() { return document.links[1]; }; foo();\n        \n        \n    *   \\ **xpath**\\ =\\ *xpathExpression*: \n        Locate an element using an XPath expression.\n        \n        *   xpath=//img[@alt='The image alt text']\n        *   xpath=//table[@id='table1']//tr[4]/td[2]\n        *   xpath=//a[contains(@href,'#id1')]\n        *   xpath=//a[contains(@href,'#id1')]/@class\n        *   xpath=(//table[@class='stylee'])//th[text()='theHeaderText']/../td\n        *   xpath=//input[@name='name2' and @value='yes']\n        *   xpath=//\\*[text()=\"right\"]\n        \n        \n    *   \\ **link**\\ =\\ *textPattern*:\n        Select the link (anchor) element which contains text matching the\n        specified \\ *pattern*.\n        \n        *   link=The link text\n        \n        \n    *   \\ **css**\\ =\\ *cssSelectorSyntax*:\n        Select the element using css selectors. Please refer to CSS2 selectors, CSS3 selectors for more information. You can also check the TestCssLocators test in the selenium test suite for an example of usage, which is included in the downloaded selenium core package.\n        \n        *   css=a[href=\"#id3\"]\n        *   css=span#firstChild + span\n        \n        \n        Currently the css selector locator supports all css1, css2 and css3 selectors except namespace in css3, some pseudo classes(:nth-of-type, :nth-last-of-type, :first-of-type, :last-of-type, :only-of-type, :visited, :hover, :active, :focus, :indeterminate) and pseudo elements(::first-line, ::first-letter, ::selection, ::before, ::after). \n        \n    \n    \n    \n    Without an explicit locator prefix, Selenium uses the following default\n    strategies:\n    \n    \n    *   \\ **dom**\\ , for locators starting with \"document.\"\n    *   \\ **xpath**\\ , for locators starting with \"//\"\n    *   \\ **identifier**\\ , otherwise\n    \n    Element Filters\n    ~~~~~~~~~~~~~~~\n    \n    Element filters can be used with a locator to refine a list of candidate elements.  They are currently used only in the 'name' element-locator.\n    \n    Filters look much like locators, ie.\n    \n    \\ *filterType*\\ **=**\\ \\ *argument*\n    \n    Supported element-filters are:\n    \n    \\ **value=**\\ \\ *valuePattern*\n    \n    \n    Matches elements based on their values.  This is particularly useful for refining a list of similarly-named toggle-buttons.\n    \n    \\ **index=**\\ \\ *index*\n    \n    \n    Selects a single element based on its position in the list (offset from zero).\n    \n    String-match Patterns\n    ~~~~~~~~~~~~~~~~~~~~~\n    \n    Various Pattern syntaxes are available for matching string values:\n    \n    \n    *   \\ **glob:**\\ \\ *pattern*:\n        Match a string against a \"glob\" (aka \"wildmat\") pattern. \"Glob\" is a\n        kind of limited regular-expression syntax typically used in command-line\n        shells. In a glob pattern, \"\\*\" represents any sequence of characters, and \"?\"\n        represents any single character. Glob patterns match against the entire\n        string.\n    *   \\ **regexp:**\\ \\ *regexp*:\n        Match a string using a regular-expression. The full power of JavaScript\n        regular-expressions is available.\n    *   \\ **regexpi:**\\ \\ *regexpi*:\n        Match a string using a case-insensitive regular-expression.\n    *   \\ **exact:**\\ \\ *string*:\n        \n        Match a string exactly, verbatim, without any of that fancy wildcard\n        stuff.\n    \n    \n    \n    If no pattern prefix is specified, Selenium assumes that it's a \"glob\"\n    pattern.\n    \n    \n    \n    For commands that return multiple values (such as verifySelectOptions),\n    the string being matched is a comma-separated list of the return values,\n    where both commas and backslashes in the values are backslash-escaped.\n    When providing a pattern, the optional matching syntax (i.e. glob,\n    regexp, etc.) is specified once, as usual, at the beginning of the\n    pattern.\n    \n    \n    \"\"\"\n\n### This part is hard-coded in the XSL\n    def __init__(self, host, port, browserStartCommand, browserURL):\n        self.host = host\n        self.port = port\n        self.browserStartCommand = browserStartCommand\n        self.browserURL = browserURL\n        self.sessionId = None\n\n    def start(self):\n        result = self.get_string(\"getNewBrowserSession\", [self.browserStartCommand, self.browserURL])\n        try:\n            self.sessionId = result\n        except ValueError:\n            raise Exception, result\n        \n    def stop(self):\n        self.do_command(\"testComplete\", [])\n        self.sessionId = None\n\n    def do_command(self, verb, args):\n        conn = httplib.HTTPConnection(self.host, self.port)\n        commandString = u'/selenium-server/driver/?cmd=' + urllib.quote_plus(unicode(verb).encode('utf-8'))\n        for i in range(len(args)):\n            commandString = commandString + '&' + unicode(i+1) + '=' + urllib.quote_plus(unicode(args[i]).encode('utf-8'))\n        if (None != self.sessionId):\n            commandString = commandString + \"&sessionId=\" + unicode(self.sessionId)\n        conn.request(\"GET\", commandString)\n    \n        response = conn.getresponse()\n        #print response.status, response.reason\n        data = unicode(response.read(), \"UTF-8\")\n        result = response.reason\n        #print \"Selenium Result: \" + repr(data) + \"\\n\\n\"\n        if (not data.startswith('OK')):\n            raise Exception, data\n        return data\n    \n    def get_string(self, verb, args):\n        result = self.do_command(verb, args)\n        return result[3:]\n    \n    def get_string_array(self, verb, args):\n        csv = self.get_string(verb, args)\n        token = \"\"\n        tokens = []\n        escape = False\n        for i in range(len(csv)):\n            letter = csv[i]\n            if (escape):\n                token = token + letter\n                escape = False\n                continue\n            if (letter == '\\\\'):\n                escape = True\n            elif (letter == ','):\n                tokens.append(token)\n                token = \"\"\n            else:\n                token = token + letter\n        tokens.append(token)\n        return tokens\n\n    def get_number(self, verb, args):\n        # Is there something I need to do here?\n        return self.get_string(verb, args)\n    \n    def get_number_array(self, verb, args):\n        # Is there something I need to do here?\n        return self.get_string_array(verb, args)\n\n    def get_boolean(self, verb, args):\n        boolstr = self.get_string(verb, args)\n        if (\"true\" == boolstr):\n            return True\n        if (\"false\" == boolstr):\n            return False\n        raise ValueError, \"result is neither 'true' nor 'false': \" + boolstr\n    \n    def get_boolean_array(self, verb, args):\n        boolarr = self.get_string_array(verb, args)\n        for i in range(len(boolarr)):\n            if (\"true\" == boolstr):\n                boolarr[i] = True\n                continue\n            if (\"false\" == boolstr):\n                boolarr[i] = False\n                continue\n            raise ValueError, \"result is neither 'true' nor 'false': \" + boolarr[i]\n        return boolarr\n    \n    \n\n### From here on, everything's auto-generated from XML\n\n\n    def click(self,locator):\n        \"\"\"\n        Clicks on a link, button, checkbox or radio button. If the click action\n        causes a new page to load (like a link usually does), call\n        waitForPageToLoad.\n        \n        'locator' is an element locator\n        \"\"\"\n        self.do_command(\"click\", [locator,])\n\n\n    def double_click(self,locator):\n        \"\"\"\n        Double clicks on a link, button, checkbox or radio button. If the double click action\n        causes a new page to load (like a link usually does), call\n        waitForPageToLoad.\n        \n        'locator' is an element locator\n        \"\"\"\n        self.do_command(\"doubleClick\", [locator,])\n\n\n    def context_menu(self,locator):\n        \"\"\"\n        Simulates opening the context menu for the specified element (as might happen if the user \"right-clicked\" on the element).\n        \n        'locator' is an element locator\n        \"\"\"\n        self.do_command(\"contextMenu\", [locator,])\n\n\n    def click_at(self,locator,coordString):\n        \"\"\"\n        Clicks on a link, button, checkbox or radio button. If the click action\n        causes a new page to load (like a link usually does), call\n        waitForPageToLoad.\n        \n        'locator' is an element locator\n        'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse      event relative to the element returned by the locator.\n        \"\"\"\n        self.do_command(\"clickAt\", [locator,coordString,])\n\n\n    def double_click_at(self,locator,coordString):\n        \"\"\"\n        Doubleclicks on a link, button, checkbox or radio button. If the action\n        causes a new page to load (like a link usually does), call\n        waitForPageToLoad.\n        \n        'locator' is an element locator\n        'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse      event relative to the element returned by the locator.\n        \"\"\"\n        self.do_command(\"doubleClickAt\", [locator,coordString,])\n\n\n    def context_menu_at(self,locator,coordString):\n        \"\"\"\n        Simulates opening the context menu for the specified element (as might happen if the user \"right-clicked\" on the element).\n        \n        'locator' is an element locator\n        'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse      event relative to the element returned by the locator.\n        \"\"\"\n        self.do_command(\"contextMenuAt\", [locator,coordString,])\n\n\n    def fire_event(self,locator,eventName):\n        \"\"\"\n        Explicitly simulate an event, to trigger the corresponding \"on\\ *event*\"\n        handler.\n        \n        'locator' is an element locator\n        'eventName' is the event name, e.g. \"focus\" or \"blur\"\n        \"\"\"\n        self.do_command(\"fireEvent\", [locator,eventName,])\n\n\n    def focus(self,locator):\n        \"\"\"\n        Move the focus to the specified element; for example, if the element is an input field, move the cursor to that field.\n        \n        'locator' is an element locator\n        \"\"\"\n        self.do_command(\"focus\", [locator,])\n\n\n    def key_press(self,locator,keySequence):\n        \"\"\"\n        Simulates a user pressing and releasing a key.\n        \n        'locator' is an element locator\n        'keySequence' is Either be a string(\"\\\" followed by the numeric keycode  of the key to be pressed, normally the ASCII value of that key), or a single  character. For example: \"w\", \"\\119\".\n        \"\"\"\n        self.do_command(\"keyPress\", [locator,keySequence,])\n\n\n    def shift_key_down(self):\n        \"\"\"\n        Press the shift key and hold it down until doShiftUp() is called or a new page is loaded.\n        \n        \"\"\"\n        self.do_command(\"shiftKeyDown\", [])\n\n\n    def shift_key_up(self):\n        \"\"\"\n        Release the shift key.\n        \n        \"\"\"\n        self.do_command(\"shiftKeyUp\", [])\n\n\n    def meta_key_down(self):\n        \"\"\"\n        Press the meta key and hold it down until doMetaUp() is called or a new page is loaded.\n        \n        \"\"\"\n        self.do_command(\"metaKeyDown\", [])\n\n\n    def meta_key_up(self):\n        \"\"\"\n        Release the meta key.\n        \n        \"\"\"\n        self.do_command(\"metaKeyUp\", [])\n\n\n    def alt_key_down(self):\n        \"\"\"\n        Press the alt key and hold it down until doAltUp() is called or a new page is loaded.\n        \n        \"\"\"\n        self.do_command(\"altKeyDown\", [])\n\n\n    def alt_key_up(self):\n        \"\"\"\n        Release the alt key.\n        \n        \"\"\"\n        self.do_command(\"altKeyUp\", [])\n\n\n    def control_key_down(self):\n        \"\"\"\n        Press the control key and hold it down until doControlUp() is called or a new page is loaded.\n        \n        \"\"\"\n        self.do_command(\"controlKeyDown\", [])\n\n\n    def control_key_up(self):\n        \"\"\"\n        Release the control key.\n        \n        \"\"\"\n        self.do_command(\"controlKeyUp\", [])\n\n\n    def key_down(self,locator,keySequence):\n        \"\"\"\n        Simulates a user pressing a key (without releasing it yet).\n        \n        'locator' is an element locator\n        'keySequence' is Either be a string(\"\\\" followed by the numeric keycode  of the key to be pressed, normally the ASCII value of that key), or a single  character. For example: \"w\", \"\\119\".\n        \"\"\"\n        self.do_command(\"keyDown\", [locator,keySequence,])\n\n\n    def key_up(self,locator,keySequence):\n        \"\"\"\n        Simulates a user releasing a key.\n        \n        'locator' is an element locator\n        'keySequence' is Either be a string(\"\\\" followed by the numeric keycode  of the key to be pressed, normally the ASCII value of that key), or a single  character. For example: \"w\", \"\\119\".\n        \"\"\"\n        self.do_command(\"keyUp\", [locator,keySequence,])\n\n\n    def mouse_over(self,locator):\n        \"\"\"\n        Simulates a user hovering a mouse over the specified element.\n        \n        'locator' is an element locator\n        \"\"\"\n        self.do_command(\"mouseOver\", [locator,])\n\n\n    def mouse_out(self,locator):\n        \"\"\"\n        Simulates a user moving the mouse pointer away from the specified element.\n        \n        'locator' is an element locator\n        \"\"\"\n        self.do_command(\"mouseOut\", [locator,])\n\n\n    def mouse_down(self,locator):\n        \"\"\"\n        Simulates a user pressing the mouse button (without releasing it yet) on\n        the specified element.\n        \n        'locator' is an element locator\n        \"\"\"\n        self.do_command(\"mouseDown\", [locator,])\n\n\n    def mouse_down_at(self,locator,coordString):\n        \"\"\"\n        Simulates a user pressing the mouse button (without releasing it yet) at\n        the specified location.\n        \n        'locator' is an element locator\n        'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse      event relative to the element returned by the locator.\n        \"\"\"\n        self.do_command(\"mouseDownAt\", [locator,coordString,])\n\n\n    def mouse_up(self,locator):\n        \"\"\"\n        Simulates the event that occurs when the user releases the mouse button (i.e., stops\n        holding the button down) on the specified element.\n        \n        'locator' is an element locator\n        \"\"\"\n        self.do_command(\"mouseUp\", [locator,])\n\n\n    def mouse_up_at(self,locator,coordString):\n        \"\"\"\n        Simulates the event that occurs when the user releases the mouse button (i.e., stops\n        holding the button down) at the specified location.\n        \n        'locator' is an element locator\n        'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse      event relative to the element returned by the locator.\n        \"\"\"\n        self.do_command(\"mouseUpAt\", [locator,coordString,])\n\n\n    def mouse_move(self,locator):\n        \"\"\"\n        Simulates a user pressing the mouse button (without releasing it yet) on\n        the specified element.\n        \n        'locator' is an element locator\n        \"\"\"\n        self.do_command(\"mouseMove\", [locator,])\n\n\n    def mouse_move_at(self,locator,coordString):\n        \"\"\"\n        Simulates a user pressing the mouse button (without releasing it yet) on\n        the specified element.\n        \n        'locator' is an element locator\n        'coordString' is specifies the x,y position (i.e. - 10,20) of the mouse      event relative to the element returned by the locator.\n        \"\"\"\n        self.do_command(\"mouseMoveAt\", [locator,coordString,])\n\n\n    def type(self,locator,value):\n        \"\"\"\n        Sets the value of an input field, as though you typed it in.\n        \n        \n        Can also be used to set the value of combo boxes, check boxes, etc. In these cases,\n        value should be the value of the option selected, not the visible text.\n        \n        \n        'locator' is an element locator\n        'value' is the value to type\n        \"\"\"\n        self.do_command(\"type\", [locator,value,])\n\n\n    def type_keys(self,locator,value):\n        \"\"\"\n        Simulates keystroke events on the specified element, as though you typed the value key-by-key.\n        \n        \n        This is a convenience method for calling keyDown, keyUp, keyPress for every character in the specified string;\n        this is useful for dynamic UI widgets (like auto-completing combo boxes) that require explicit key events.\n        \n        Unlike the simple \"type\" command, which forces the specified value into the page directly, this command\n        may or may not have any visible effect, even in cases where typing keys would normally have a visible effect.\n        For example, if you use \"typeKeys\" on a form element, you may or may not see the results of what you typed in\n        the field.\n        \n        In some cases, you may need to use the simple \"type\" command to set the value of the field and then the \"typeKeys\" command to\n        send the keystroke events corresponding to what you just typed.\n        \n        \n        'locator' is an element locator\n        'value' is the value to type\n        \"\"\"\n        self.do_command(\"typeKeys\", [locator,value,])\n\n\n    def set_speed(self,value):\n        \"\"\"\n        Set execution speed (i.e., set the millisecond length of a delay which will follow each selenium operation).  By default, there is no such delay, i.e.,\n        the delay is 0 milliseconds.\n        \n        'value' is the number of milliseconds to pause after operation\n        \"\"\"\n        self.do_command(\"setSpeed\", [value,])\n\n\n    def get_speed(self):\n        \"\"\"\n        Get execution speed (i.e., get the millisecond length of the delay following each selenium operation).  By default, there is no such delay, i.e.,\n        the delay is 0 milliseconds.\n        \n        See also setSpeed.\n        \n        \"\"\"\n        return self.get_string(\"getSpeed\", [])\n\n\n    def check(self,locator):\n        \"\"\"\n        Check a toggle-button (checkbox/radio)\n        \n        'locator' is an element locator\n        \"\"\"\n        self.do_command(\"check\", [locator,])\n\n\n    def uncheck(self,locator):\n        \"\"\"\n        Uncheck a toggle-button (checkbox/radio)\n        \n        'locator' is an element locator\n        \"\"\"\n        self.do_command(\"uncheck\", [locator,])\n\n\n    def select(self,selectLocator,optionLocator):\n        \"\"\"\n        Select an option from a drop-down using an option locator.\n        \n        \n        \n        Option locators provide different ways of specifying options of an HTML\n        Select element (e.g. for selecting a specific option, or for asserting\n        that the selected option satisfies a specification). There are several\n        forms of Select Option Locator.\n        \n        \n        *   \\ **label**\\ =\\ *labelPattern*:\n            matches options based on their labels, i.e. the visible text. (This\n            is the default.)\n            \n            *   label=regexp:^[Oo]ther\n            \n            \n        *   \\ **value**\\ =\\ *valuePattern*:\n            matches options based on their values.\n            \n            *   value=other\n            \n            \n        *   \\ **id**\\ =\\ *id*:\n            \n            matches options based on their ids.\n            \n            *   id=option1\n            \n            \n        *   \\ **index**\\ =\\ *index*:\n            matches an option based on its index (offset from zero).\n            \n            *   index=2\n            \n            \n        \n        \n        \n        If no option locator prefix is provided, the default behaviour is to match on \\ **label**\\ .\n        \n        \n        \n        'selectLocator' is an element locator identifying a drop-down menu\n        'optionLocator' is an option locator (a label by default)\n        \"\"\"\n        self.do_command(\"select\", [selectLocator,optionLocator,])\n\n\n    def add_selection(self,locator,optionLocator):\n        \"\"\"\n        Add a selection to the set of selected options in a multi-select element using an option locator.\n        \n        @see #doSelect for details of option locators\n        \n        'locator' is an element locator identifying a multi-select box\n        'optionLocator' is an option locator (a label by default)\n        \"\"\"\n        self.do_command(\"addSelection\", [locator,optionLocator,])\n\n\n    def remove_selection(self,locator,optionLocator):\n        \"\"\"\n        Remove a selection from the set of selected options in a multi-select element using an option locator.\n        \n        @see #doSelect for details of option locators\n        \n        'locator' is an element locator identifying a multi-select box\n        'optionLocator' is an option locator (a label by default)\n        \"\"\"\n        self.do_command(\"removeSelection\", [locator,optionLocator,])\n\n\n    def remove_all_selections(self,locator):\n        \"\"\"\n        Unselects all of the selected options in a multi-select element.\n        \n        'locator' is an element locator identifying a multi-select box\n        \"\"\"\n        self.do_command(\"removeAllSelections\", [locator,])\n\n\n    def submit(self,formLocator):\n        \"\"\"\n        Submit the specified form. This is particularly useful for forms without\n        submit buttons, e.g. single-input \"Search\" forms.\n        \n        'formLocator' is an element locator for the form you want to submit\n        \"\"\"\n        self.do_command(\"submit\", [formLocator,])\n\n\n    def open(self,url):\n        \"\"\"\n        Opens an URL in the test frame. This accepts both relative and absolute\n        URLs.\n        \n        The \"open\" command waits for the page to load before proceeding,\n        ie. the \"AndWait\" suffix is implicit.\n        \n        \\ *Note*: The URL must be on the same domain as the runner HTML\n        due to security restrictions in the browser (Same Origin Policy). If you\n        need to open an URL on another domain, use the Selenium Server to start a\n        new browser session on that domain.\n        \n        'url' is the URL to open; may be relative or absolute\n        \"\"\"\n        self.do_command(\"open\", [url,])\n\n\n    def open_window(self,url,windowID):\n        \"\"\"\n        Opens a popup window (if a window with that ID isn't already open).\n        After opening the window, you'll need to select it using the selectWindow\n        command.\n        \n        \n        This command can also be a useful workaround for bug SEL-339.  In some cases, Selenium will be unable to intercept a call to window.open (if the call occurs during or before the \"onLoad\" event, for example).\n        In those cases, you can force Selenium to notice the open window's name by using the Selenium openWindow command, using\n        an empty (blank) url, like this: openWindow(\"\", \"myFunnyWindow\").\n        \n        \n        'url' is the URL to open, which can be blank\n        'windowID' is the JavaScript window ID of the window to select\n        \"\"\"\n        self.do_command(\"openWindow\", [url,windowID,])\n\n\n    def select_window(self,windowID):\n        \"\"\"\n        Selects a popup window using a window locator; once a popup window has been selected, all\n        commands go to that window. To select the main window again, use null\n        as the target.\n        \n        \n        \n        \n        Window locators provide different ways of specifying the window object:\n        by title, by internal JavaScript \"name,\" or by JavaScript variable.\n        \n        \n        *   \\ **title**\\ =\\ *My Special Window*:\n            Finds the window using the text that appears in the title bar.  Be careful;\n            two windows can share the same title.  If that happens, this locator will\n            just pick one.\n            \n        *   \\ **name**\\ =\\ *myWindow*:\n            Finds the window using its internal JavaScript \"name\" property.  This is the second \n            parameter \"windowName\" passed to the JavaScript method window.open(url, windowName, windowFeatures, replaceFlag)\n            (which Selenium intercepts).\n            \n        *   \\ **var**\\ =\\ *variableName*:\n            Some pop-up windows are unnamed (anonymous), but are associated with a JavaScript variable name in the current\n            application window, e.g. \"window.foo = window.open(url);\".  In those cases, you can open the window using\n            \"var=foo\".\n            \n        \n        \n        \n        If no window locator prefix is provided, we'll try to guess what you mean like this:\n        \n        1.) if windowID is null, (or the string \"null\") then it is assumed the user is referring to the original window instantiated by the browser).\n        \n        2.) if the value of the \"windowID\" parameter is a JavaScript variable name in the current application window, then it is assumed\n        that this variable contains the return value from a call to the JavaScript window.open() method.\n        \n        3.) Otherwise, selenium looks in a hash it maintains that maps string names to window \"names\".\n        \n        4.) If \\ *that* fails, we'll try looping over all of the known windows to try to find the appropriate \"title\".\n        Since \"title\" is not necessarily unique, this may have unexpected behavior.\n        \n        If you're having trouble figuring out the name of a window that you want to manipulate, look at the Selenium log messages\n        which identify the names of windows created via window.open (and therefore intercepted by Selenium).  You will see messages\n        like the following for each window as it is opened:\n        \n        ``debug: window.open call intercepted; window ID (which you can use with selectWindow()) is \"myNewWindow\"``\n        \n        In some cases, Selenium will be unable to intercept a call to window.open (if the call occurs during or before the \"onLoad\" event, for example).\n        (This is bug SEL-339.)  In those cases, you can force Selenium to notice the open window's name by using the Selenium openWindow command, using\n        an empty (blank) url, like this: openWindow(\"\", \"myFunnyWindow\").\n        \n        \n        'windowID' is the JavaScript window ID of the window to select\n        \"\"\"\n        self.do_command(\"selectWindow\", [windowID,])\n\n\n    def select_frame(self,locator):\n        \"\"\"\n        Selects a frame within the current window.  (You may invoke this command\n        multiple times to select nested frames.)  To select the parent frame, use\n        \"relative=parent\" as a locator; to select the top frame, use \"relative=top\".\n        You can also select a frame by its 0-based index number; select the first frame with\n        \"index=0\", or the third frame with \"index=2\".\n        \n        \n        You may also use a DOM expression to identify the frame you want directly,\n        like this: ``dom=frames[\"main\"].frames[\"subframe\"]``\n        \n        \n        'locator' is an element locator identifying a frame or iframe\n        \"\"\"\n        self.do_command(\"selectFrame\", [locator,])\n\n\n    def get_whether_this_frame_match_frame_expression(self,currentFrameString,target):\n        \"\"\"\n        Determine whether current/locator identify the frame containing this running code.\n        \n        \n        This is useful in proxy injection mode, where this code runs in every\n        browser frame and window, and sometimes the selenium server needs to identify\n        the \"current\" frame.  In this case, when the test calls selectFrame, this\n        routine is called for each frame to figure out which one has been selected.\n        The selected frame will return true, while all others will return false.\n        \n        \n        'currentFrameString' is starting frame\n        'target' is new frame (which might be relative to the current one)\n        \"\"\"\n        return self.get_boolean(\"getWhetherThisFrameMatchFrameExpression\", [currentFrameString,target,])\n\n\n    def get_whether_this_window_match_window_expression(self,currentWindowString,target):\n        \"\"\"\n        Determine whether currentWindowString plus target identify the window containing this running code.\n        \n        \n        This is useful in proxy injection mode, where this code runs in every\n        browser frame and window, and sometimes the selenium server needs to identify\n        the \"current\" window.  In this case, when the test calls selectWindow, this\n        routine is called for each window to figure out which one has been selected.\n        The selected window will return true, while all others will return false.\n        \n        \n        'currentWindowString' is starting window\n        'target' is new window (which might be relative to the current one, e.g., \"_parent\")\n        \"\"\"\n        return self.get_boolean(\"getWhetherThisWindowMatchWindowExpression\", [currentWindowString,target,])\n\n\n    def wait_for_pop_up(self,windowID,timeout):\n        \"\"\"\n        Waits for a popup window to appear and load up.\n        \n        'windowID' is the JavaScript window \"name\" of the window that will appear (not the text of the title bar)\n        'timeout' is a timeout in milliseconds, after which the action will return with an error\n        \"\"\"\n        self.do_command(\"waitForPopUp\", [windowID,timeout,])\n\n\n    def choose_cancel_on_next_confirmation(self):\n        \"\"\"\n        By default, Selenium's overridden window.confirm() function will\n        return true, as if the user had manually clicked OK; after running\n        this command, the next call to confirm() will return false, as if\n        the user had clicked Cancel.  Selenium will then resume using the\n        default behavior for future confirmations, automatically returning \n        true (OK) unless/until you explicitly call this command for each\n        confirmation.\n        \n        \"\"\"\n        self.do_command(\"chooseCancelOnNextConfirmation\", [])\n\n\n    def choose_ok_on_next_confirmation(self):\n        \"\"\"\n        Undo the effect of calling chooseCancelOnNextConfirmation.  Note\n        that Selenium's overridden window.confirm() function will normally automatically\n        return true, as if the user had manually clicked OK, so you shouldn't\n        need to use this command unless for some reason you need to change\n        your mind prior to the next confirmation.  After any confirmation, Selenium will resume using the\n        default behavior for future confirmations, automatically returning \n        true (OK) unless/until you explicitly call chooseCancelOnNextConfirmation for each\n        confirmation.\n        \n        \"\"\"\n        self.do_command(\"chooseOkOnNextConfirmation\", [])\n\n\n    def answer_on_next_prompt(self,answer):\n        \"\"\"\n        Instructs Selenium to return the specified answer string in response to\n        the next JavaScript prompt [window.prompt()].\n        \n        'answer' is the answer to give in response to the prompt pop-up\n        \"\"\"\n        self.do_command(\"answerOnNextPrompt\", [answer,])\n\n\n    def go_back(self):\n        \"\"\"\n        Simulates the user clicking the \"back\" button on their browser.\n        \n        \"\"\"\n        self.do_command(\"goBack\", [])\n\n\n    def refresh(self):\n        \"\"\"\n        Simulates the user clicking the \"Refresh\" button on their browser.\n        \n        \"\"\"\n        self.do_command(\"refresh\", [])\n\n\n    def close(self):\n        \"\"\"\n        Simulates the user clicking the \"close\" button in the titlebar of a popup\n        window or tab.\n        \n        \"\"\"\n        self.do_command(\"close\", [])\n\n\n    def is_alert_present(self):\n        \"\"\"\n        Has an alert occurred?\n        \n        \n        \n        This function never throws an exception\n        \n        \n        \n        \"\"\"\n        return self.get_boolean(\"isAlertPresent\", [])\n\n\n    def is_prompt_present(self):\n        \"\"\"\n        Has a prompt occurred?\n        \n        \n        \n        This function never throws an exception\n        \n        \n        \n        \"\"\"\n        return self.get_boolean(\"isPromptPresent\", [])\n\n\n    def is_confirmation_present(self):\n        \"\"\"\n        Has confirm() been called?\n        \n        \n        \n        This function never throws an exception\n        \n        \n        \n        \"\"\"\n        return self.get_boolean(\"isConfirmationPresent\", [])\n\n\n    def get_alert(self):\n        \"\"\"\n        Retrieves the message of a JavaScript alert generated during the previous action, or fail if there were no alerts.\n        \n        \n        Getting an alert has the same effect as manually clicking OK. If an\n        alert is generated but you do not get/verify it, the next Selenium action\n        will fail.\n        \n        NOTE: under Selenium, JavaScript alerts will NOT pop up a visible alert\n        dialog.\n        \n        NOTE: Selenium does NOT support JavaScript alerts that are generated in a\n        page's onload() event handler. In this case a visible dialog WILL be\n        generated and Selenium will hang until someone manually clicks OK.\n        \n        \n        \"\"\"\n        return self.get_string(\"getAlert\", [])\n\n\n    def get_confirmation(self):\n        \"\"\"\n        Retrieves the message of a JavaScript confirmation dialog generated during\n        the previous action.\n        \n        \n        \n        By default, the confirm function will return true, having the same effect\n        as manually clicking OK. This can be changed by prior execution of the\n        chooseCancelOnNextConfirmation command. If an confirmation is generated\n        but you do not get/verify it, the next Selenium action will fail.\n        \n        \n        \n        NOTE: under Selenium, JavaScript confirmations will NOT pop up a visible\n        dialog.\n        \n        \n        \n        NOTE: Selenium does NOT support JavaScript confirmations that are\n        generated in a page's onload() event handler. In this case a visible\n        dialog WILL be generated and Selenium will hang until you manually click\n        OK.\n        \n        \n        \n        \"\"\"\n        return self.get_string(\"getConfirmation\", [])\n\n\n    def get_prompt(self):\n        \"\"\"\n        Retrieves the message of a JavaScript question prompt dialog generated during\n        the previous action.\n        \n        \n        Successful handling of the prompt requires prior execution of the\n        answerOnNextPrompt command. If a prompt is generated but you\n        do not get/verify it, the next Selenium action will fail.\n        \n        NOTE: under Selenium, JavaScript prompts will NOT pop up a visible\n        dialog.\n        \n        NOTE: Selenium does NOT support JavaScript prompts that are generated in a\n        page's onload() event handler. In this case a visible dialog WILL be\n        generated and Selenium will hang until someone manually clicks OK.\n        \n        \n        \"\"\"\n        return self.get_string(\"getPrompt\", [])\n\n\n    def get_location(self):\n        \"\"\"\n        Gets the absolute URL of the current page.\n        \n        \"\"\"\n        return self.get_string(\"getLocation\", [])\n\n\n    def get_title(self):\n        \"\"\"\n        Gets the title of the current page.\n        \n        \"\"\"\n        return self.get_string(\"getTitle\", [])\n\n\n    def get_body_text(self):\n        \"\"\"\n        Gets the entire text of the page.\n        \n        \"\"\"\n        return self.get_string(\"getBodyText\", [])\n\n\n    def get_value(self,locator):\n        \"\"\"\n        Gets the (whitespace-trimmed) value of an input field (or anything else with a value parameter).\n        For checkbox/radio elements, the value will be \"on\" or \"off\" depending on\n        whether the element is checked or not.\n        \n        'locator' is an element locator\n        \"\"\"\n        return self.get_string(\"getValue\", [locator,])\n\n\n    def get_text(self,locator):\n        \"\"\"\n        Gets the text of an element. This works for any element that contains\n        text. This command uses either the textContent (Mozilla-like browsers) or\n        the innerText (IE-like browsers) of the element, which is the rendered\n        text shown to the user.\n        \n        'locator' is an element locator\n        \"\"\"\n        return self.get_string(\"getText\", [locator,])\n\n\n    def highlight(self,locator):\n        \"\"\"\n        Briefly changes the backgroundColor of the specified element yellow.  Useful for debugging.\n        \n        'locator' is an element locator\n        \"\"\"\n        self.do_command(\"highlight\", [locator,])\n\n\n    def get_eval(self,script):\n        \"\"\"\n        Gets the result of evaluating the specified JavaScript snippet.  The snippet may\n        have multiple lines, but only the result of the last line will be returned.\n        \n        \n        Note that, by default, the snippet will run in the context of the \"selenium\"\n        object itself, so ``this`` will refer to the Selenium object.  Use ``window`` to\n        refer to the window of your application, e.g. ``window.document.getElementById('foo')``\n        \n        If you need to use\n        a locator to refer to a single element in your application page, you can\n        use ``this.browserbot.findElement(\"id=foo\")`` where \"id=foo\" is your locator.\n        \n        \n        'script' is the JavaScript snippet to run\n        \"\"\"\n        return self.get_string(\"getEval\", [script,])\n\n\n    def is_checked(self,locator):\n        \"\"\"\n        Gets whether a toggle-button (checkbox/radio) is checked.  Fails if the specified element doesn't exist or isn't a toggle-button.\n        \n        'locator' is an element locator pointing to a checkbox or radio button\n        \"\"\"\n        return self.get_boolean(\"isChecked\", [locator,])\n\n\n    def get_table(self,tableCellAddress):\n        \"\"\"\n        Gets the text from a cell of a table. The cellAddress syntax\n        tableLocator.row.column, where row and column start at 0.\n        \n        'tableCellAddress' is a cell address, e.g. \"foo.1.4\"\n        \"\"\"\n        return self.get_string(\"getTable\", [tableCellAddress,])\n\n\n    def get_selected_labels(self,selectLocator):\n        \"\"\"\n        Gets all option labels (visible text) for selected options in the specified select or multi-select element.\n        \n        'selectLocator' is an element locator identifying a drop-down menu\n        \"\"\"\n        return self.get_string_array(\"getSelectedLabels\", [selectLocator,])\n\n\n    def get_selected_label(self,selectLocator):\n        \"\"\"\n        Gets option label (visible text) for selected option in the specified select element.\n        \n        'selectLocator' is an element locator identifying a drop-down menu\n        \"\"\"\n        return self.get_string(\"getSelectedLabel\", [selectLocator,])\n\n\n    def get_selected_values(self,selectLocator):\n        \"\"\"\n        Gets all option values (value attributes) for selected options in the specified select or multi-select element.\n        \n        'selectLocator' is an element locator identifying a drop-down menu\n        \"\"\"\n        return self.get_string_array(\"getSelectedValues\", [selectLocator,])\n\n\n    def get_selected_value(self,selectLocator):\n        \"\"\"\n        Gets option value (value attribute) for selected option in the specified select element.\n        \n        'selectLocator' is an element locator identifying a drop-down menu\n        \"\"\"\n        return self.get_string(\"getSelectedValue\", [selectLocator,])\n\n\n    def get_selected_indexes(self,selectLocator):\n        \"\"\"\n        Gets all option indexes (option number, starting at 0) for selected options in the specified select or multi-select element.\n        \n        'selectLocator' is an element locator identifying a drop-down menu\n        \"\"\"\n        return self.get_string_array(\"getSelectedIndexes\", [selectLocator,])\n\n\n    def get_selected_index(self,selectLocator):\n        \"\"\"\n        Gets option index (option number, starting at 0) for selected option in the specified select element.\n        \n        'selectLocator' is an element locator identifying a drop-down menu\n        \"\"\"\n        return self.get_string(\"getSelectedIndex\", [selectLocator,])\n\n\n    def get_selected_ids(self,selectLocator):\n        \"\"\"\n        Gets all option element IDs for selected options in the specified select or multi-select element.\n        \n        'selectLocator' is an element locator identifying a drop-down menu\n        \"\"\"\n        return self.get_string_array(\"getSelectedIds\", [selectLocator,])\n\n\n    def get_selected_id(self,selectLocator):\n        \"\"\"\n        Gets option element ID for selected option in the specified select element.\n        \n        'selectLocator' is an element locator identifying a drop-down menu\n        \"\"\"\n        return self.get_string(\"getSelectedId\", [selectLocator,])\n\n\n    def is_something_selected(self,selectLocator):\n        \"\"\"\n        Determines whether some option in a drop-down menu is selected.\n        \n        'selectLocator' is an element locator identifying a drop-down menu\n        \"\"\"\n        return self.get_boolean(\"isSomethingSelected\", [selectLocator,])\n\n\n    def get_select_options(self,selectLocator):\n        \"\"\"\n        Gets all option labels in the specified select drop-down.\n        \n        'selectLocator' is an element locator identifying a drop-down menu\n        \"\"\"\n        return self.get_string_array(\"getSelectOptions\", [selectLocator,])\n\n\n    def get_attribute(self,attributeLocator):\n        \"\"\"\n        Gets the value of an element attribute. The value of the attribute may\n        differ across browsers (this is the case for the \"style\" attribute, for\n        example).\n        \n        'attributeLocator' is an element locator followed by an @ sign and then the name of the attribute, e.g. \"foo@bar\"\n        \"\"\"\n        return self.get_string(\"getAttribute\", [attributeLocator,])\n\n\n    def is_text_present(self,pattern):\n        \"\"\"\n        Verifies that the specified text pattern appears somewhere on the rendered page shown to the user.\n        \n        'pattern' is a pattern to match with the text of the page\n        \"\"\"\n        return self.get_boolean(\"isTextPresent\", [pattern,])\n\n\n    def is_element_present(self,locator):\n        \"\"\"\n        Verifies that the specified element is somewhere on the page.\n        \n        'locator' is an element locator\n        \"\"\"\n        return self.get_boolean(\"isElementPresent\", [locator,])\n\n\n    def is_visible(self,locator):\n        \"\"\"\n        Determines if the specified element is visible. An\n        element can be rendered invisible by setting the CSS \"visibility\"\n        property to \"hidden\", or the \"display\" property to \"none\", either for the\n        element itself or one if its ancestors.  This method will fail if\n        the element is not present.\n        \n        'locator' is an element locator\n        \"\"\"\n        return self.get_boolean(\"isVisible\", [locator,])\n\n\n    def is_editable(self,locator):\n        \"\"\"\n        Determines whether the specified input element is editable, ie hasn't been disabled.\n        This method will fail if the specified element isn't an input element.\n        \n        'locator' is an element locator\n        \"\"\"\n        return self.get_boolean(\"isEditable\", [locator,])\n\n\n    def get_all_buttons(self):\n        \"\"\"\n        Returns the IDs of all buttons on the page.\n        \n        \n        If a given button has no ID, it will appear as \"\" in this array.\n        \n        \n        \"\"\"\n        return self.get_string_array(\"getAllButtons\", [])\n\n\n    def get_all_links(self):\n        \"\"\"\n        Returns the IDs of all links on the page.\n        \n        \n        If a given link has no ID, it will appear as \"\" in this array.\n        \n        \n        \"\"\"\n        return self.get_string_array(\"getAllLinks\", [])\n\n\n    def get_all_fields(self):\n        \"\"\"\n        Returns the IDs of all input fields on the page.\n        \n        \n        If a given field has no ID, it will appear as \"\" in this array.\n        \n        \n        \"\"\"\n        return self.get_string_array(\"getAllFields\", [])\n\n\n    def get_attribute_from_all_windows(self,attributeName):\n        \"\"\"\n        Returns every instance of some attribute from all known windows.\n        \n        'attributeName' is name of an attribute on the windows\n        \"\"\"\n        return self.get_string_array(\"getAttributeFromAllWindows\", [attributeName,])\n\n\n    def dragdrop(self,locator,movementsString):\n        \"\"\"\n        deprecated - use dragAndDrop instead\n        \n        'locator' is an element locator\n        'movementsString' is offset in pixels from the current location to which the element should be moved, e.g., \"+70,-300\"\n        \"\"\"\n        self.do_command(\"dragdrop\", [locator,movementsString,])\n\n\n    def set_mouse_speed(self,pixels):\n        \"\"\"\n        Configure the number of pixels between \"mousemove\" events during dragAndDrop commands (default=10).\n        \n        Setting this value to 0 means that we'll send a \"mousemove\" event to every single pixel\n        in between the start location and the end location; that can be very slow, and may\n        cause some browsers to force the JavaScript to timeout.\n        \n        If the mouse speed is greater than the distance between the two dragged objects, we'll\n        just send one \"mousemove\" at the start location and then one final one at the end location.\n        \n        \n        'pixels' is the number of pixels between \"mousemove\" events\n        \"\"\"\n        self.do_command(\"setMouseSpeed\", [pixels,])\n\n\n    def get_mouse_speed(self):\n        \"\"\"\n        Returns the number of pixels between \"mousemove\" events during dragAndDrop commands (default=10).\n        \n        \"\"\"\n        return self.get_number(\"getMouseSpeed\", [])\n\n\n    def drag_and_drop(self,locator,movementsString):\n        \"\"\"\n        Drags an element a certain distance and then drops it\n        \n        'locator' is an element locator\n        'movementsString' is offset in pixels from the current location to which the element should be moved, e.g., \"+70,-300\"\n        \"\"\"\n        self.do_command(\"dragAndDrop\", [locator,movementsString,])\n\n\n    def drag_and_drop_to_object(self,locatorOfObjectToBeDragged,locatorOfDragDestinationObject):\n        \"\"\"\n        Drags an element and drops it on another element\n        \n        'locatorOfObjectToBeDragged' is an element to be dragged\n        'locatorOfDragDestinationObject' is an element whose location (i.e., whose center-most pixel) will be the point where locatorOfObjectToBeDragged  is dropped\n        \"\"\"\n        self.do_command(\"dragAndDropToObject\", [locatorOfObjectToBeDragged,locatorOfDragDestinationObject,])\n\n\n    def window_focus(self):\n        \"\"\"\n        Gives focus to the currently selected window\n        \n        \"\"\"\n        self.do_command(\"windowFocus\", [])\n\n\n    def window_maximize(self):\n        \"\"\"\n        Resize currently selected window to take up the entire screen\n        \n        \"\"\"\n        self.do_command(\"windowMaximize\", [])\n\n\n    def get_all_window_ids(self):\n        \"\"\"\n        Returns the IDs of all windows that the browser knows about.\n        \n        \"\"\"\n        return self.get_string_array(\"getAllWindowIds\", [])\n\n\n    def get_all_window_names(self):\n        \"\"\"\n        Returns the names of all windows that the browser knows about.\n        \n        \"\"\"\n        return self.get_string_array(\"getAllWindowNames\", [])\n\n\n    def get_all_window_titles(self):\n        \"\"\"\n        Returns the titles of all windows that the browser knows about.\n        \n        \"\"\"\n        return self.get_string_array(\"getAllWindowTitles\", [])\n\n\n    def get_html_source(self):\n        \"\"\"\n        Returns the entire HTML source between the opening and\n        closing \"html\" tags.\n        \n        \"\"\"\n        return self.get_string(\"getHtmlSource\", [])\n\n\n    def set_cursor_position(self,locator,position):\n        \"\"\"\n        Moves the text cursor to the specified position in the given input element or textarea.\n        This method will fail if the specified element isn't an input element or textarea.\n        \n        'locator' is an element locator pointing to an input element or textarea\n        'position' is the numerical position of the cursor in the field; position should be 0 to move the position to the beginning of the field.  You can also set the cursor to -1 to move it to the end of the field.\n        \"\"\"\n        self.do_command(\"setCursorPosition\", [locator,position,])\n\n\n    def get_element_index(self,locator):\n        \"\"\"\n        Get the relative index of an element to its parent (starting from 0). The comment node and empty text node\n        will be ignored.\n        \n        'locator' is an element locator pointing to an element\n        \"\"\"\n        return self.get_number(\"getElementIndex\", [locator,])\n\n\n    def is_ordered(self,locator1,locator2):\n        \"\"\"\n        Check if these two elements have same parent and are ordered siblings in the DOM. Two same elements will\n        not be considered ordered.\n        \n        'locator1' is an element locator pointing to the first element\n        'locator2' is an element locator pointing to the second element\n        \"\"\"\n        return self.get_boolean(\"isOrdered\", [locator1,locator2,])\n\n\n    def get_element_position_left(self,locator):\n        \"\"\"\n        Retrieves the horizontal position of an element\n        \n        'locator' is an element locator pointing to an element OR an element itself\n        \"\"\"\n        return self.get_number(\"getElementPositionLeft\", [locator,])\n\n\n    def get_element_position_top(self,locator):\n        \"\"\"\n        Retrieves the vertical position of an element\n        \n        'locator' is an element locator pointing to an element OR an element itself\n        \"\"\"\n        return self.get_number(\"getElementPositionTop\", [locator,])\n\n\n    def get_element_width(self,locator):\n        \"\"\"\n        Retrieves the width of an element\n        \n        'locator' is an element locator pointing to an element\n        \"\"\"\n        return self.get_number(\"getElementWidth\", [locator,])\n\n\n    def get_element_height(self,locator):\n        \"\"\"\n        Retrieves the height of an element\n        \n        'locator' is an element locator pointing to an element\n        \"\"\"\n        return self.get_number(\"getElementHeight\", [locator,])\n\n\n    def get_cursor_position(self,locator):\n        \"\"\"\n        Retrieves the text cursor position in the given input element or textarea; beware, this may not work perfectly on all browsers.\n        \n        \n        Specifically, if the cursor/selection has been cleared by JavaScript, this command will tend to\n        return the position of the last location of the cursor, even though the cursor is now gone from the page.  This is filed as SEL-243.\n        \n        This method will fail if the specified element isn't an input element or textarea, or there is no cursor in the element.\n        \n        'locator' is an element locator pointing to an input element or textarea\n        \"\"\"\n        return self.get_number(\"getCursorPosition\", [locator,])\n\n\n    def get_expression(self,expression):\n        \"\"\"\n        Returns the specified expression.\n        \n        \n        This is useful because of JavaScript preprocessing.\n        It is used to generate commands like assertExpression and waitForExpression.\n        \n        \n        'expression' is the value to return\n        \"\"\"\n        return self.get_string(\"getExpression\", [expression,])\n\n\n    def get_xpath_count(self,xpath):\n        \"\"\"\n        Returns the number of nodes that match the specified xpath, eg. \"//table\" would give\n        the number of tables.\n        \n        'xpath' is the xpath expression to evaluate. do NOT wrap this expression in a 'count()' function; we will do that for you.\n        \"\"\"\n        return self.get_number(\"getXpathCount\", [xpath,])\n\n\n    def assign_id(self,locator,identifier):\n        \"\"\"\n        Temporarily sets the \"id\" attribute of the specified element, so you can locate it in the future\n        using its ID rather than a slow/complicated XPath.  This ID will disappear once the page is\n        reloaded.\n        \n        'locator' is an element locator pointing to an element\n        'identifier' is a string to be used as the ID of the specified element\n        \"\"\"\n        self.do_command(\"assignId\", [locator,identifier,])\n\n\n    def allow_native_xpath(self,allow):\n        \"\"\"\n        Specifies whether Selenium should use the native in-browser implementation\n        of XPath (if any native version is available); if you pass \"false\" to\n        this function, we will always use our pure-JavaScript xpath library.\n        Using the pure-JS xpath library can improve the consistency of xpath\n        element locators between different browser vendors, but the pure-JS\n        version is much slower than the native implementations.\n        \n        'allow' is boolean, true means we'll prefer to use native XPath; false means we'll only use JS XPath\n        \"\"\"\n        self.do_command(\"allowNativeXpath\", [allow,])\n\n\n    def ignore_attributes_without_value(self,ignore):\n        \"\"\"\n        Specifies whether Selenium will ignore xpath attributes that have no\n        value, i.e. are the empty string, when using the non-native xpath\n        evaluation engine. You'd want to do this for performance reasons in IE.\n        However, this could break certain xpaths, for example an xpath that looks\n        for an attribute whose value is NOT the empty string.\n        \n        The hope is that such xpaths are relatively rare, but the user should\n        have the option of using them. Note that this only influences xpath\n        evaluation when using the ajaxslt engine (i.e. not \"javascript-xpath\").\n        \n        'ignore' is boolean, true means we'll ignore attributes without value                        at the expense of xpath \"correctness\"; false means                        we'll sacrifice speed for correctness.\n        \"\"\"\n        self.do_command(\"ignoreAttributesWithoutValue\", [ignore,])\n\n\n    def wait_for_condition(self,script,timeout):\n        \"\"\"\n        Runs the specified JavaScript snippet repeatedly until it evaluates to \"true\".\n        The snippet may have multiple lines, but only the result of the last line\n        will be considered.\n        \n        \n        Note that, by default, the snippet will be run in the runner's test window, not in the window\n        of your application.  To get the window of your application, you can use\n        the JavaScript snippet ``selenium.browserbot.getCurrentWindow()``, and then\n        run your JavaScript in there\n        \n        \n        'script' is the JavaScript snippet to run\n        'timeout' is a timeout in milliseconds, after which this command will return with an error\n        \"\"\"\n        self.do_command(\"waitForCondition\", [script,timeout,])\n\n\n    def set_timeout(self,timeout):\n        \"\"\"\n        Specifies the amount of time that Selenium will wait for actions to complete.\n        \n        \n        Actions that require waiting include \"open\" and the \"waitFor\\*\" actions.\n        \n        The default timeout is 30 seconds.\n        \n        'timeout' is a timeout in milliseconds, after which the action will return with an error\n        \"\"\"\n        self.do_command(\"setTimeout\", [timeout,])\n\n\n    def wait_for_page_to_load(self,timeout):\n        \"\"\"\n        Waits for a new page to load.\n        \n        \n        You can use this command instead of the \"AndWait\" suffixes, \"clickAndWait\", \"selectAndWait\", \"typeAndWait\" etc.\n        (which are only available in the JS API).\n        \n        Selenium constantly keeps track of new pages loading, and sets a \"newPageLoaded\"\n        flag when it first notices a page load.  Running any other Selenium command after\n        turns the flag to false.  Hence, if you want to wait for a page to load, you must\n        wait immediately after a Selenium command that caused a page-load.\n        \n        \n        'timeout' is a timeout in milliseconds, after which this command will return with an error\n        \"\"\"\n        self.do_command(\"waitForPageToLoad\", [timeout,])\n\n\n    def wait_for_frame_to_load(self,frameAddress,timeout):\n        \"\"\"\n        Waits for a new frame to load.\n        \n        \n        Selenium constantly keeps track of new pages and frames loading, \n        and sets a \"newPageLoaded\" flag when it first notices a page load.\n        \n        \n        See waitForPageToLoad for more information.\n        \n        'frameAddress' is FrameAddress from the server side\n        'timeout' is a timeout in milliseconds, after which this command will return with an error\n        \"\"\"\n        self.do_command(\"waitForFrameToLoad\", [frameAddress,timeout,])\n\n\n    def get_cookie(self):\n        \"\"\"\n        Return all cookies of the current page under test.\n        \n        \"\"\"\n        return self.get_string(\"getCookie\", [])\n\n\n    def get_cookie_by_name(self,name):\n        \"\"\"\n        Returns the value of the cookie with the specified name, or throws an error if the cookie is not present.\n        \n        'name' is the name of the cookie\n        \"\"\"\n        return self.get_string(\"getCookieByName\", [name,])\n\n\n    def is_cookie_present(self,name):\n        \"\"\"\n        Returns true if a cookie with the specified name is present, or false otherwise.\n        \n        'name' is the name of the cookie\n        \"\"\"\n        return self.get_boolean(\"isCookiePresent\", [name,])\n\n\n    def create_cookie(self,nameValuePair,optionsString):\n        \"\"\"\n        Create a new cookie whose path and domain are same with those of current page\n        under test, unless you specified a path for this cookie explicitly.\n        \n        'nameValuePair' is name and value of the cookie in a format \"name=value\"\n        'optionsString' is options for the cookie. Currently supported options include 'path', 'max_age' and 'domain'.      the optionsString's format is \"path=/path/, max_age=60, domain=.foo.com\". The order of options are irrelevant, the unit      of the value of 'max_age' is second.  Note that specifying a domain that isn't a subset of the current domain will      usually fail.\n        \"\"\"\n        self.do_command(\"createCookie\", [nameValuePair,optionsString,])\n\n\n    def delete_cookie(self,name,optionsString):\n        \"\"\"\n        Delete a named cookie with specified path and domain.  Be careful; to delete a cookie, you\n        need to delete it using the exact same path and domain that were used to create the cookie.\n        If the path is wrong, or the domain is wrong, the cookie simply won't be deleted.  Also\n        note that specifying a domain that isn't a subset of the current domain will usually fail.\n        \n        Since there's no way to discover at runtime the original path and domain of a given cookie,\n        we've added an option called 'recurse' to try all sub-domains of the current domain with\n        all paths that are a subset of the current path.  Beware; this option can be slow.  In\n        big-O notation, it operates in O(n\\*m) time, where n is the number of dots in the domain\n        name and m is the number of slashes in the path.\n        \n        'name' is the name of the cookie to be deleted\n        'optionsString' is options for the cookie. Currently supported options include 'path', 'domain'      and 'recurse.' The optionsString's format is \"path=/path/, domain=.foo.com, recurse=true\".      The order of options are irrelevant. Note that specifying a domain that isn't a subset of      the current domain will usually fail.\n        \"\"\"\n        self.do_command(\"deleteCookie\", [name,optionsString,])\n\n\n    def delete_all_visible_cookies(self):\n        \"\"\"\n        Calls deleteCookie with recurse=true on all cookies visible to the current page.\n        As noted on the documentation for deleteCookie, recurse=true can be much slower\n        than simply deleting the cookies using a known domain/path.\n        \n        \"\"\"\n        self.do_command(\"deleteAllVisibleCookies\", [])\n\n\n    def set_browser_log_level(self,logLevel):\n        \"\"\"\n        Sets the threshold for browser-side logging messages; log messages beneath this threshold will be discarded.\n        Valid logLevel strings are: \"debug\", \"info\", \"warn\", \"error\" or \"off\".\n        To see the browser logs, you need to\n        either show the log window in GUI mode, or enable browser-side logging in Selenium RC.\n        \n        'logLevel' is one of the following: \"debug\", \"info\", \"warn\", \"error\" or \"off\"\n        \"\"\"\n        self.do_command(\"setBrowserLogLevel\", [logLevel,])\n\n\n    def run_script(self,script):\n        \"\"\"\n        Creates a new \"script\" tag in the body of the current test window, and \n        adds the specified text into the body of the command.  Scripts run in\n        this way can often be debugged more easily than scripts executed using\n        Selenium's \"getEval\" command.  Beware that JS exceptions thrown in these script\n        tags aren't managed by Selenium, so you should probably wrap your script\n        in try/catch blocks if there is any chance that the script will throw\n        an exception.\n        \n        'script' is the JavaScript snippet to run\n        \"\"\"\n        self.do_command(\"runScript\", [script,])\n\n\n    def add_location_strategy(self,strategyName,functionDefinition):\n        \"\"\"\n        Defines a new function for Selenium to locate elements on the page.\n        For example,\n        if you define the strategy \"foo\", and someone runs click(\"foo=blah\"), we'll\n        run your function, passing you the string \"blah\", and click on the element \n        that your function\n        returns, or throw an \"Element not found\" error if your function returns null.\n        \n        We'll pass three arguments to your function:\n        \n        *   locator: the string the user passed in\n        *   inWindow: the currently selected window\n        *   inDocument: the currently selected document\n        \n        \n        The function must return null if the element can't be found.\n        \n        'strategyName' is the name of the strategy to define; this should use only   letters [a-zA-Z] with no spaces or other punctuation.\n        'functionDefinition' is a string defining the body of a function in JavaScript.   For example: ``return inDocument.getElementById(locator);``\n        \"\"\"\n        self.do_command(\"addLocationStrategy\", [strategyName,functionDefinition,])\n\n\n    def capture_entire_page_screenshot(self,filename):\n        \"\"\"\n        Saves the entire contents of the current window canvas to a PNG file.\n        Currently this only works in Mozilla and when running in chrome mode.\n        Contrast this with the captureScreenshot command, which captures the\n        contents of the OS viewport (i.e. whatever is currently being displayed\n        on the monitor), and is implemented in the RC only. Implementation\n        mostly borrowed from the Screengrab! Firefox extension. Please see\n        http://www.screengrab.org for details.\n        \n        'filename' is the path to the file to persist the screenshot as. No                  filename extension will be appended by default.                  Directories will not be created if they do not exist,                    and an exception will be thrown, possibly by native                  code.\n        \"\"\"\n        self.do_command(\"captureEntirePageScreenshot\", [filename,])\n\n\n    def set_context(self,context):\n        \"\"\"\n        Writes a message to the status bar and adds a note to the browser-side\n        log.\n        \n        'context' is the message to be sent to the browser\n        \"\"\"\n        self.do_command(\"setContext\", [context,])\n\n\n    def attach_file(self,fieldLocator,fileLocator):\n        \"\"\"\n        Sets a file input (upload) field to the file listed in fileLocator\n        \n        'fieldLocator' is an element locator\n        'fileLocator' is a URL pointing to the specified file. Before the file  can be set in the input field (fieldLocator), Selenium RC may need to transfer the file    to the local machine before attaching the file in a web page form. This is common in selenium  grid configurations where the RC server driving the browser is not the same  machine that started the test.   Supported Browsers: Firefox (\"\\*chrome\") only.\n        \"\"\"\n        self.do_command(\"attachFile\", [fieldLocator,fileLocator,])\n\n\n    def capture_screenshot(self,filename):\n        \"\"\"\n        Captures a PNG screenshot to the specified file.\n        \n        'filename' is the absolute path to the file to be written, e.g. \"c:\\blah\\screenshot.png\"\n        \"\"\"\n        self.do_command(\"captureScreenshot\", [filename,])\n\n\n    def shut_down_selenium_server(self):\n        \"\"\"\n        Kills the running Selenium Server and all browser sessions.  After you run this command, you will no longer be able to send\n        commands to the server; you can't remotely start the server once it has been stopped.  Normally\n        you should prefer to run the \"stop\" command, which terminates the current browser session, rather than \n        shutting down the entire server.\n        \n        \"\"\"\n        self.do_command(\"shutDownSeleniumServer\", [])\n\n\n    def key_down_native(self,keycode):\n        \"\"\"\n        Simulates a user pressing a key (without releasing it yet) by sending a native operating system keystroke.\n        This function uses the java.awt.Robot class to send a keystroke; this more accurately simulates typing\n        a key on the keyboard.  It does not honor settings from the shiftKeyDown, controlKeyDown, altKeyDown and\n        metaKeyDown commands, and does not target any particular HTML element.  To send a keystroke to a particular\n        element, focus on the element first before running this command.\n        \n        'keycode' is an integer keycode number corresponding to a java.awt.event.KeyEvent; note that Java keycodes are NOT the same thing as JavaScript keycodes!\n        \"\"\"\n        self.do_command(\"keyDownNative\", [keycode,])\n\n\n    def key_up_native(self,keycode):\n        \"\"\"\n        Simulates a user releasing a key by sending a native operating system keystroke.\n        This function uses the java.awt.Robot class to send a keystroke; this more accurately simulates typing\n        a key on the keyboard.  It does not honor settings from the shiftKeyDown, controlKeyDown, altKeyDown and\n        metaKeyDown commands, and does not target any particular HTML element.  To send a keystroke to a particular\n        element, focus on the element first before running this command.\n        \n        'keycode' is an integer keycode number corresponding to a java.awt.event.KeyEvent; note that Java keycodes are NOT the same thing as JavaScript keycodes!\n        \"\"\"\n        self.do_command(\"keyUpNative\", [keycode,])\n\n\n    def key_press_native(self,keycode):\n        \"\"\"\n        Simulates a user pressing and releasing a key by sending a native operating system keystroke.\n        This function uses the java.awt.Robot class to send a keystroke; this more accurately simulates typing\n        a key on the keyboard.  It does not honor settings from the shiftKeyDown, controlKeyDown, altKeyDown and\n        metaKeyDown commands, and does not target any particular HTML element.  To send a keystroke to a particular\n        element, focus on the element first before running this command.\n        \n        'keycode' is an integer keycode number corresponding to a java.awt.event.KeyEvent; note that Java keycodes are NOT the same thing as JavaScript keycodes!\n        \"\"\"\n        self.do_command(\"keyPressNative\", [keycode,])\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/selenium/remotecontrol/setup.txt",
    "content": " * Install selenium remote control from the latest snapshot:\n\n   http://nexus.openqa.org/content/repositories/snapshots/org/seleniumhq/selenium/selenium-remote-control/1.0-SNAPSHOT/\n\n * Run the server with java -jar selenium-server.jar\n * Run the python script\n\n \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/selenium/remotecontrol/test_ol.py",
    "content": "from selenium import selenium\nimport time\nimport sys\nfrom ConfigParser import ConfigParser\n\nMAX_TEST_LENGTH = 300\nif len(sys.argv) > 2: \n    filename = sys.argv[2]\nelse:\n    filename = \"config.cfg\"\n\nc = ConfigParser()\nc.read(filename)\n\ntargets = {}\n\nserver = c.get('config', 'server') \nurl= c.get('config', 'url')\nif c.has_option('config', 'timeout'):\n    MAX_TEST_LENGTH = int(c.get('config', 'timeout'))\n\n\nsections = c.sections()\nfor s in sections:\n    if s == 'config':\n       continue\n    targets[s] = dict(c.items(s))\n    targets[s]['name'] = s\n\nif sys.argv[1] == \"all\":\n    browsers = list(targets.values())\nelif sys.argv[1] not in targets:\n    print \"Invalid target\"\n    sys.exit()\nelse:    \n    browsers = [targets[sys.argv[1]]]\n\nkeep_going = True\n\nif 1:\n    for b in browsers:\n        if not keep_going: \n            continue\n\n        print \"Running %s on %s\" % (b['name'], b['host']) \n        s = selenium(b['host'], 4444, \"*%s\" % b['browsercmd'], server)\n        s.start()\n        try:\n            s.open_window(url, \"test_running\")\n            time.sleep(2)\n            s.select_window(\"test_running\")\n            time.sleep(2)\n            s.refresh()\n            \n            count = 0\n            while count == 0: \n                count = int(s.get_eval(\"window.document.getElementById('testtable').getElementsByTagName('tr').length\"))\n                time.sleep(5)\n                \n            ok = 0 \n            fail = 0\n            last_change = time.time()\n            while True:\n                new_ok = int(s.get_eval('window.Test.AnotherWay._g_ok_pages'))\n                new_fail = int(s.get_eval('window.Test.AnotherWay._g_fail_pages'))\n                if new_ok != ok or new_fail != fail:\n                    ok = new_ok\n                    fail = new_fail\n                    last_change = time.time()\n                    \n                if (ok + fail) >= count:\n                    break \n                if time.time() - last_change > MAX_TEST_LENGTH:\n                    raise Exception(\"Failed: with %s okay and %s failed, ran out of time: %s is more than %s\" % (ok, fail, (time.time() - last_change), MAX_TEST_LENGTH))      \n                time.sleep(10)\n            \n            if fail:\n                print \"Failed: %s\" % fail\n                html = s.get_eval(\"window.document.getElementById('results').innerHTML\").encode(\"utf-8\")\n                all_html = \"\"\"<html>\n  <head>    \n    <meta content=\"text/html; charset=utf-8\" http-equiv=\"content-type\" />\n  </head>\n  <body>%s</body></html>\"\"\" % html\n\n                f = open(\"fail.%s.%s.html\" % (time.time(), b['name']), \"w\")\n                f.write(all_html)\n                f.close()\n        except KeyboardInterrupt, E:\n            keep_going = False\n            print \"Stopped by keyboard interrupt\"\n        except Exception, E:\n            print \"Error: \", E\n        s.stop()\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/speed/geometry.html",
    "content": "<html>\n<script src=\"../../lib/OpenLayers.js\"></script>\n<script>\n\nvar test_data = {};\n\nfunction setup_test() {\n    if (test_data['polygon']) { return; }\n    var f = new OpenLayers.Format.WKT();\n    var list = f.read(\"POLYGON((-78.046875 5.9765625, -78.75 5.9765625, -79.453125 5.2734375, -79.453125 4.5703125, -80.15625 3.8671875, -80.15625 2.4609375, -80.15625 1.0546875, -80.15625 -1.0546875, -80.15625 -2.4609375, -80.15625 -3.8671875, -80.15625 -4.5703125, -80.15625 -5.2734375, -80.15625 -5.9765625, -80.15625 -6.6796875, -80.15625 -8.0859375, -80.15625 -8.7890625, -80.15625 -9.4921875, -80.15625 -10.8984375, -79.453125 -13.0078125, -78.046875 -13.7109375, -78.046875 -15.1171875, -76.640625 -15.1171875, -76.640625 -16.5234375, -75.9375 -16.5234375, -75.9375 -17.2265625, -75.234375 -17.9296875, -75.234375 -18.6328125, -74.53125 -19.3359375, -74.53125 -20.0390625, -74.53125 -20.7421875, -73.828125 -20.7421875, -73.828125 -22.8515625, -73.828125 -24.2578125, -72.421875 -25.6640625, -71.015625 -25.6640625, -71.015625 -26.3671875, -69.609375 -27.7734375, -69.609375 -28.4765625, -68.90625 -29.1796875, -68.203125 -29.8828125, -67.5 -30.5859375, -67.5 -31.9921875, -67.5 -32.6953125, -67.5 -33.3984375, -67.5 -34.8046875, -67.5 -36.9140625, -68.203125 -39.0234375, -68.203125 -39.7265625, -70.3125 -41.1328125, -71.015625 -41.8359375, -71.015625 -43.2421875, -71.015625 -43.9453125, -71.015625 -44.6484375, -71.71875 -48.8671875, -71.71875 -50.2734375, -71.71875 -50.9765625, -72.421875 -52.3828125, -72.421875 -53.0859375, -73.828125 -53.7890625, -73.828125 -55.1953125, -73.828125 -55.8984375, -73.828125 -56.6015625, -73.828125 -57.3046875, -73.828125 -58.0078125, -72.421875 -59.4140625, -71.71875 -60.1171875, -71.015625 -60.1171875, -70.3125 -60.1171875, -68.90625 -60.8203125, -68.203125 -60.8203125, -67.5 -60.8203125, -66.796875 -60.8203125, -66.796875 -59.4140625, -65.390625 -58.0078125, -65.390625 -57.3046875, -65.390625 -55.8984375, -65.390625 -55.1953125, -65.390625 -54.4921875, -65.390625 -53.7890625, -65.390625 -53.0859375, -64.6875 -52.3828125, -60.46875 -50.2734375, -57.65625 -48.8671875, -55.546875 -47.4609375, -54.84375 -47.4609375, -54.84375 -46.7578125, -54.140625 -46.7578125, -54.140625 -46.0546875, -54.140625 -45.3515625, -54.140625 -43.2421875, -54.140625 -41.1328125, -54.140625 -39.0234375, -53.4375 -37.6171875, -52.734375 -36.2109375, -51.328125 -36.2109375, -49.921875 -35.5078125, -48.515625 -34.8046875, -45 -33.3984375, -41.484375 -31.9921875, -35.15625 -28.4765625, -33.046875 -27.0703125, -33.046875 -24.9609375, -33.046875 -23.5546875, -33.046875 -22.1484375, -33.046875 -19.3359375, -32.34375 -13.0078125, -31.640625 -11.6015625, -31.640625 -10.8984375, -31.640625 -10.1953125, -31.640625 -8.0859375, -31.640625 -7.3828125, -31.640625 -5.9765625, -31.640625 -4.5703125, -31.640625 -2.4609375, -32.34375 -2.4609375, -34.453125 0.3515625, -37.265625 3.1640625, -41.484375 6.6796875, -45.703125 8.7890625, -53.4375 12.3046875, -55.546875 14.4140625, -56.953125 14.4140625, -59.0625 15.1171875, -61.875 13.7109375, -65.390625 13.0078125, -71.015625 12.3046875, -75.234375 11.6015625, -78.75 11.6015625, -80.859375 11.6015625, -81.5625 11.6015625, -81.5625 10.8984375, -81.5625 10.1953125, -81.5625 9.4921875, -81.5625 8.7890625, -80.15625 8.7890625, -80.15625 6.6796875, -80.15625 5.2734375, -80.15625 4.5703125, -80.15625 3.8671875, -79.453125 3.8671875, -78.046875 5.9765625))\");\n    test_data['polygon'] = list.geometry;\n    var list = f.read(\"POLYGON((-125.15625 48.1640625, -125.859375 48.1640625, -125.859375 46.7578125, -125.15625 46.7578125, -124.453125 46.0546875, -123.75 46.0546875, -123.046875 46.0546875, -122.34375 46.0546875, -120.9375 46.0546875, -116.71875 46.7578125, -113.90625 46.7578125, -113.203125 46.7578125, -112.5 46.7578125, -111.796875 46.7578125, -111.09375 46.7578125, -110.390625 46.7578125, -109.6875 46.7578125, -106.875 46.7578125, -102.65625 46.7578125, -95.625 47.4609375, -91.40625 48.1640625, -87.890625 48.1640625, -87.1875 48.1640625, -86.484375 48.1640625, -85.78125 48.1640625, -84.375 48.1640625, -82.96875 48.1640625, -81.5625 48.1640625, -80.15625 48.1640625, -79.453125 47.4609375, -79.453125 46.7578125, -78.75 46.7578125, -78.75 45.3515625, -78.046875 45.3515625, -77.34375 45.3515625, -76.640625 45.3515625, -75.234375 45.3515625, -71.015625 46.7578125, -69.609375 47.4609375, -68.90625 47.4609375, -68.203125 48.1640625, -67.5 48.1640625, -66.09375 48.1640625, -65.390625 49.5703125, -63.984375 49.5703125, -63.28125 49.5703125, -62.578125 49.5703125, -61.875 48.8671875, -61.875 48.1640625, -61.875 46.7578125, -61.171875 46.0546875, -61.171875 43.2421875, -61.171875 41.8359375, -61.171875 40.4296875, -61.171875 39.7265625, -61.875 39.7265625, -62.578125 39.7265625, -63.28125 39.7265625, -63.984375 39.7265625, -66.796875 39.7265625, -67.5 39.7265625, -68.203125 39.7265625, -68.90625 39.7265625, -68.90625 39.0234375, -69.609375 38.3203125, -69.609375 36.9140625, -71.015625 34.8046875, -71.015625 32.6953125, -72.421875 31.2890625, -73.125 30.5859375, -73.828125 29.8828125, -74.53125 29.1796875, -75.234375 28.4765625, -76.640625 26.3671875, -76.640625 25.6640625, -76.640625 24.9609375, -77.34375 24.2578125, -77.34375 23.5546875, -78.046875 23.5546875, -79.453125 23.5546875, -80.15625 23.5546875, -80.859375 23.5546875, -81.5625 23.5546875, -82.265625 23.5546875, -82.96875 23.5546875, -83.671875 23.5546875, -83.671875 24.2578125, -85.078125 24.2578125, -85.78125 24.9609375, -85.78125 25.6640625, -86.484375 25.6640625, -87.1875 26.3671875, -87.1875 27.7734375, -87.1875 28.4765625, -87.890625 28.4765625, -88.59375 28.4765625, -89.296875 28.4765625, -90 28.4765625, -90.703125 28.4765625, -91.40625 28.4765625, -91.40625 27.7734375, -92.8125 27.7734375, -92.8125 27.0703125, -92.8125 26.3671875, -92.8125 25.6640625, -92.8125 24.9609375, -92.8125 24.2578125, -93.515625 24.2578125, -94.921875 23.5546875, -95.625 23.5546875, -97.03125 23.5546875, -97.734375 23.5546875, -98.4375 23.5546875, -99.140625 23.5546875, -99.84375 24.2578125, -101.25 24.2578125, -104.0625 24.9609375, -106.171875 25.6640625, -106.875 26.3671875, -107.578125 26.3671875, -108.28125 26.3671875, -108.984375 26.3671875, -110.390625 26.3671875, -113.90625 26.3671875, -116.015625 26.3671875, -116.71875 27.0703125, -118.125 27.0703125, -118.828125 27.7734375, -120.234375 27.7734375, -120.234375 28.4765625, -120.9375 28.4765625, -120.9375 29.1796875, -121.640625 29.8828125, -121.640625 30.5859375, -121.640625 31.2890625, -123.046875 31.2890625, -123.75 32.6953125, -124.453125 33.3984375, -125.15625 34.1015625, -126.5625 34.8046875, -127.265625 34.8046875, -127.96875 35.5078125, -125.15625 48.1640625))\");\n    test_data['miss_polygon'] = list.geometry;\n    var list = f.read(\"POLYGON((-32.34375 13.0078125, -33.046875 13.0078125, -33.75 13.0078125, -34.453125 13.0078125, -35.15625 13.0078125, -35.859375 13.0078125, -36.5625 13.0078125, -37.265625 13.0078125, -37.96875 13.0078125, -37.96875 12.3046875, -38.671875 12.3046875, -39.375 12.3046875, -40.078125 12.3046875, -40.078125 11.6015625, -41.484375 11.6015625, -42.890625 10.8984375, -43.59375 10.8984375, -44.296875 10.1953125, -44.296875 9.4921875, -44.296875 8.7890625, -44.296875 8.0859375, -44.296875 6.6796875, -44.296875 5.9765625, -44.296875 5.2734375, -43.59375 5.2734375, -43.59375 4.5703125, -43.59375 3.8671875, -42.890625 3.1640625, -42.890625 2.4609375, -42.890625 1.7578125, -42.890625 1.0546875, -42.1875 -0.3515625, -41.484375 -1.0546875, -41.484375 -2.4609375, -41.484375 -3.1640625, -42.890625 -3.1640625, -44.296875 -3.8671875, -44.296875 -4.5703125, -45.703125 -5.2734375, -46.40625 -5.2734375, -47.109375 -5.2734375, -47.109375 -5.9765625, -47.109375 -6.6796875, -47.109375 -7.3828125, -47.109375 -8.0859375, -47.109375 -9.4921875, -47.109375 -10.1953125, -47.109375 -10.8984375, -47.109375 -11.6015625, -47.109375 -12.3046875, -47.109375 -13.7109375, -47.109375 -15.1171875, -47.109375 -15.8203125, -47.8125 -15.8203125, -47.8125 -16.5234375, -46.40625 -16.5234375, -45.703125 -16.5234375, -44.296875 -17.2265625, -43.59375 -17.9296875, -42.890625 -18.6328125, -42.1875 -18.6328125, -41.484375 -18.6328125, -40.78125 -18.6328125, -39.375 -18.6328125, -37.265625 -18.6328125, -35.859375 -18.6328125, -34.453125 -17.9296875, -33.75 -17.9296875, -33.046875 -17.9296875, -32.34375 -17.9296875, -32.34375 -18.6328125, -32.34375 -19.3359375, -32.34375 -20.0390625, -32.34375 -21.4453125, -31.640625 -22.1484375, -30.9375 -22.8515625, -28.828125 -22.8515625, -26.71875 -22.8515625, -23.90625 -20.0390625, -23.203125 -19.3359375, -22.5 -19.3359375, -21.796875 -17.2265625, -21.09375 -16.5234375, -21.09375 -15.8203125, -21.09375 -15.1171875, -21.09375 -14.4140625, -19.6875 -10.8984375, -19.6875 -8.0859375, -19.6875 -7.3828125, -19.6875 -5.9765625, -19.6875 -5.2734375, -19.6875 -3.1640625, -19.6875 -1.7578125, -19.6875 -0.3515625, -19.6875 0.3515625, -19.6875 1.0546875, -19.6875 1.7578125, -19.6875 2.4609375, -19.6875 3.1640625, -20.390625 4.5703125, -20.390625 5.9765625, -20.390625 6.6796875, -21.09375 6.6796875, -22.5 8.0859375, -23.90625 8.7890625, -25.3125 8.7890625, -26.015625 9.4921875, -26.71875 9.4921875, -27.421875 9.4921875, -28.125 9.4921875, -32.34375 13.0078125))\");\n    test_data['hit_polygon'] = list.geometry; \n\n}\n\nfunction run_test() { \n    test_data['polygon'].intersects(test_data['hit_polygon']);\n    test_data['polygon'].intersects(test_data['miss_polygon']);\n}\n\nfunction run_many(x) {\n    var elapsed = 0;  \n    for (var i = 0; i < x; i++) {\n        var time = new Date();\n        run_test();\n        elapsed += (new Date() - time);\n    }\n    return elapsed;\n}\n\nfunction print_results(x) {\n    var t = run_many(x);\n    document.getElementById(\"out\").innerHTML += (t +\"ms to run \" + x + \" times<br />\");  \n}\n    setup_test()\n</script>\n<body>   \n<input type=\"submit\" value=\"Run\" onclick=\"print_results(5)\" /> \n<div id=\"out\"></div> \n</body>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/speed/string_format.html",
    "content": "<html>\n<head>\n<script src=\"../../lib/OpenLayers.js\"></script>\n<script>\n\nfunction stringformat() {\n  var string = OpenLayers.String.format(\"${abc} 123 ${def}\", {'abc': 456, 'def': 789}) \n}    \nfunction run(x) {\n    var date = new Date();\n    for (var i = 0; i < x; i++) {\n        stringformat();\n    }\n    var elapsed = (new Date() - date);\n    return elapsed;\n}\n\nfunction show_time(x) \n{\n    var t = run(x);\n    document.getElementById(\"out\").innerHTML = t + \"ms  for \" + x + \" runs\";\n}\n</script>\n</head>\n<body>\n<a onclick=\"javascript:show_time(100000); return false\" href=\"#\">Run</a>\n<div id=\"out\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/speed/vector-renderers.html",
    "content": "<!DOCTYPE html>\n<html>\n  <head>\n    <title>Vector Features Performance Test</title>\n    <script type=\"text/javascript\" src=\"https://getfirebug.com/firebug-lite.js#startOpened=true\"></script>\n    <link rel=\"stylesheet\" href=\"../../theme/default/style.css\" type=\"text/css\" />\n    <link rel=\"stylesheet\" href=\"../../examples/style.css\" type=\"text/css\" />\n  </head>\n  <body>\n    <h1 id=\"title\">Vector Rendering Performance</h1>\n    <div id=\"map\" class=\"smallmap\"></div>\n    <p>\n    This is a benchmark for vector rendering performance. Test results are\n    written to the debug console.\n    Select a renderer here:\n    <br/>\n    <select id=\"renderers\"></select>\n    </p><p>\n    The benchmark shows the time needed to render the features, and how long a\n    move (drag or zoom) takes. Drag and zoom around to produce move results.\n    </p>\n    <script src=\"../../lib/OpenLayers.js\"></script>\n    <script src=\"vector-renderers.js\"></script>\n  </body>\n</html>"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/speed/vector-renderers.js",
    "content": "var map, vectorLayer, drawFeature, features\n\nmap = new OpenLayers.Map('map', {\n    eventListeners: {\n        movestart: function() {\n            console.time(\"move\");\n        },\n        moveend: function() {\n            console.timeEnd(\"move\");\n        }\n    }\n});\n\n// allow testing of specific renderers via \"?renderer=Canvas\", etc\nvar renderer = OpenLayers.Util.getParameters(window.location.href).renderer;\nrenderer = (renderer) ? [renderer] : OpenLayers.Layer.Vector.prototype.renderers;\n\nvectorLayer = new OpenLayers.Layer.Vector(\"Vector Layer\", {\n    isBaseLayer: true,\n    renderers: renderer,\n    eventListeners: {\n        beforefeaturesadded: function() {\n            console.time(\"addFeatures\");\n        },\n        featuresadded: function() {\n            console.timeEnd(\"addFeatures\");\n        }\n    }\n});\n\nmap.addLayers([vectorLayer]);\nmap.addControl(new OpenLayers.Control.MousePosition());\nmap.setCenter(new OpenLayers.LonLat(0, 0), 2);\n\nfeatures = new Array(500);\nvar x, y, points\nfor (var i = 0; i < 500; i++) {\n    x = 90-Math.random()*180;\n    y = 45-Math.random()*90;\n    var pointList = [];\n    for(var p=0; p<19; ++p) {\n        var a = p * (2 * Math.PI) / 20;\n        var r = Math.random() * 3 + 1;\n        var newPoint = new OpenLayers.Geometry.Point(x + (r * Math.cos(a)),\n                                                     y + (r * Math.sin(a)));\n        pointList.push(newPoint);\n    }\n    pointList.push(pointList[0]);\n    features[i] = new OpenLayers.Feature.Vector(\n        new OpenLayers.Geometry.LinearRing(pointList));\n        \n}\nvectorLayer.addFeatures(features);\n\nvar select = document.getElementById(\"renderers\");\nvar renderers = OpenLayers.Layer.Vector.prototype.renderers;\nvar option;\nfor (var i=0, len=renderers.length; i<len; i++) {\n    if (OpenLayers.Renderer[renderers[i]].prototype.supported()) {\n        option = document.createElement(\"option\");\n        option.textContent = renderers[i];\n        option.value = renderers[i];\n        option.selected = renderers[i] == vectorLayer.renderer.CLASS_NAME.split(\".\").pop();\n        select.appendChild(option);\n    }\n}\nselect.onchange = function() {\n    window.location.href = window.location.href.split(\"?\")[0] +\n        \"?renderer=\" + select.options[select.selectedIndex].value;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/speed/wmc_speed.html",
    "content": "<html>\n<head>\n<script src=\"../../lib/OpenLayers.js\"></script>\n<script>\nvar context = '<ViewContext xmlns=\"http://www.opengis.net/context\" version=\"1.1.0\" id=\"OpenLayers_Context_232\" xsi:schemaLocation=\"http://www.opengis.net/context http://schemas.opengis.net/context/1.1.0/context.xsd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><General><Window width=\"512\" height=\"256\"/><BoundingBox minx=\"-109.9709708\" miny=\"27.01451459\" maxx=\"-80.02902918\" maxy=\"41.98548541\" SRS=\"EPSG:4326\"/><Title/><Extension><ol:maxExtent xmlns:ol=\"http://openlayers.org/context\" minx=\"-130.0000000\" miny=\"14.00000000\" maxx=\"-60.00000000\" maxy=\"55.00000000\"/></Extension></General><LayerList><Layer queryable=\"1\" hidden=\"0\"><Server service=\"OGC:WMS\" version=\"1.1.1\"><OnlineResource xlink:type=\"simple\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://t1.hypercube.telascience.org/cgi-bin/landsat7\"/></Server><Name>landsat7</Name><Title>NASA Global Mosaic</Title><sld:MinScaleDenominator xmlns:sld=\"http://www.opengis.net/sld\">6299645.760</sld:MinScaleDenominator><sld:MaxScaleDenominator xmlns:sld=\"http://www.opengis.net/sld\">31498228.80</sld:MaxScaleDenominator><FormatList><Format current=\"1\">image/jpeg</Format></FormatList><StyleList><Style current=\"1\"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol=\"http://openlayers.org/context\" minx=\"-130.0000000\" miny=\"14.00000000\" maxx=\"-60.00000000\" maxy=\"55.00000000\"/><ol:numZoomLevels xmlns:ol=\"http://openlayers.org/context\">4</ol:numZoomLevels><ol:units xmlns:ol=\"http://openlayers.org/context\">degrees</ol:units><ol:isBaseLayer xmlns:ol=\"http://openlayers.org/context\">true</ol:isBaseLayer><ol:displayInLayerSwitcher xmlns:ol=\"http://openlayers.org/context\">true</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol=\"http://openlayers.org/context\">false</ol:singleTile></Extension></Layer><Layer queryable=\"1\" hidden=\"1\"><Server service=\"OGC:WMS\" version=\"1.1.1\"><OnlineResource xlink:type=\"simple\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://labs.metacarta.com/wms/vmap0\"/></Server><Name>basic</Name><Title>OpenLayers WMS</Title><sld:MinScaleDenominator xmlns:sld=\"http://www.opengis.net/sld\">6299645.760</sld:MinScaleDenominator><sld:MaxScaleDenominator xmlns:sld=\"http://www.opengis.net/sld\">31498228.80</sld:MaxScaleDenominator><FormatList><Format current=\"1\">image/jpeg</Format></FormatList><StyleList><Style current=\"1\"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol=\"http://openlayers.org/context\" minx=\"-130.0000000\" miny=\"14.00000000\" maxx=\"-60.00000000\" maxy=\"55.00000000\"/><ol:numZoomLevels xmlns:ol=\"http://openlayers.org/context\">4</ol:numZoomLevels><ol:units xmlns:ol=\"http://openlayers.org/context\">degrees</ol:units><ol:isBaseLayer xmlns:ol=\"http://openlayers.org/context\">true</ol:isBaseLayer><ol:displayInLayerSwitcher xmlns:ol=\"http://openlayers.org/context\">true</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol=\"http://openlayers.org/context\">false</ol:singleTile></Extension></Layer><Layer queryable=\"1\" hidden=\"0\"><Server service=\"OGC:WMS\" version=\"1.1.1\"><OnlineResource xlink:type=\"simple\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://lioapp.lrc.gov.on.ca/cubeserv/cubeserv.pl\"/></Server><Name>na_road:CCRS</Name><Title>Transportation Network</Title><sld:MinScaleDenominator xmlns:sld=\"http://www.opengis.net/sld\">6200000.000</sld:MinScaleDenominator><sld:MaxScaleDenominator xmlns:sld=\"http://www.opengis.net/sld\">32000000.00</sld:MaxScaleDenominator><FormatList><Format current=\"1\">image/png</Format></FormatList><StyleList><Style current=\"1\"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol=\"http://openlayers.org/context\" minx=\"-166.5320000\" miny=\"4.050460000\" maxx=\"-0.2068180000\" maxy=\"70.28700000\"/><ol:transparent xmlns:ol=\"http://openlayers.org/context\">TRUE</ol:transparent><ol:numZoomLevels xmlns:ol=\"http://openlayers.org/context\">4</ol:numZoomLevels><ol:units xmlns:ol=\"http://openlayers.org/context\">degrees</ol:units><ol:isBaseLayer xmlns:ol=\"http://openlayers.org/context\">false</ol:isBaseLayer><ol:opacity xmlns:ol=\"http://openlayers.org/context\">0.6</ol:opacity><ol:displayInLayerSwitcher xmlns:ol=\"http://openlayers.org/context\">false</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol=\"http://openlayers.org/context\">false</ol:singleTile></Extension></Layer><Layer queryable=\"1\" hidden=\"0\"><Server service=\"OGC:WMS\" version=\"1.1.1\"><OnlineResource xlink:type=\"simple\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:href=\"http://columbo.nrlssc.navy.mil/ogcwms/servlet/WMSServlet/AccuWeather_Maps.wms\"/></Server><Name>3:1</Name><Title>Radar 3:1</Title><sld:MinScaleDenominator xmlns:sld=\"http://www.opengis.net/sld\">6299645.760</sld:MinScaleDenominator><sld:MaxScaleDenominator xmlns:sld=\"http://www.opengis.net/sld\">31498228.80</sld:MaxScaleDenominator><FormatList><Format current=\"1\">image/png</Format></FormatList><StyleList><Style current=\"1\"><Name/><Title>Default</Title></Style></StyleList><Extension><ol:maxExtent xmlns:ol=\"http://openlayers.org/context\" minx=\"-131.0294952\" miny=\"14.56289673\" maxx=\"-61.02950287\" maxy=\"54.56289673\"/><ol:transparent xmlns:ol=\"http://openlayers.org/context\">TRUE</ol:transparent><ol:numZoomLevels xmlns:ol=\"http://openlayers.org/context\">4</ol:numZoomLevels><ol:units xmlns:ol=\"http://openlayers.org/context\">degrees</ol:units><ol:isBaseLayer xmlns:ol=\"http://openlayers.org/context\">false</ol:isBaseLayer><ol:opacity xmlns:ol=\"http://openlayers.org/context\">0.8</ol:opacity><ol:displayInLayerSwitcher xmlns:ol=\"http://openlayers.org/context\">true</ol:displayInLayerSwitcher><ol:singleTile xmlns:ol=\"http://openlayers.org/context\">true</ol:singleTile></Extension></Layer></LayerList></ViewContext>';\nfunction parse_wmc() {\n  var format = new OpenLayers.Format.WMC.v1()\n  var data = format.read(context);\n}    \nfunction run(x) {\n    var date = new Date();\n    for (var i = 0; i < x; i++) {\n        parse_wmc();\n    }\n    var elapsed = (new Date() - date);\n    return elapsed;\n}\n\nfunction show_time(x) \n{\n    var t = run(x);\n    document.getElementById(\"out\").innerHTML = t + \"ms  for \" + x + \" runs\";\n}\n</script>\n</head>\n<body>\n<a onclick=\"javascript:show_time(100); return false\" href=\"#\">Run</a>\n<div id=\"out\"></div>\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/speed/wmscaps.html",
    "content": "<html>\n    <head>\n        <title>WMS Capabilities Speed Test</title>\n        <script src=\"../../lib/OpenLayers.js\"></script>\n        <script src=\"wmscaps.js\"></script>\n        <script>\n            var data;\n            var stats = [];\n\n            function parseCaps(id, done) {\n                var format = new OpenLayers.Format.WMSCapabilities();\n                data = format.read(caps);\n                done(id);\n            }\n\n            function run(func, x) {\n                document.getElementById(\"out\").innerHTML = \"running ...\";\n                var starts = {};\n                var elapsed = 0;\n                completed = 0;\n                function callback(id) {\n                    elapsed += new Date() - starts[id];\n                    ++completed;\n                    if (completed === x) {\n                        report(x, elapsed);\n                    }\n                }\n                var runner;\n                for (var i=0; i<x; i++) {\n                    runner = createRunner(i, starts, func, callback);\n                    window.setTimeout(runner, 0);\n                }\n            }\n            \n            function createRunner(id, starts, func, done) {\n                return function() {\n                    starts[id] = new Date();\n                    func(id, done);\n                }\n            }\n\n            function report(x, elapsed) {\n                document.getElementById(\"out\").innerHTML = elapsed + \" ms for \" + x + \" runs (\" + elapsed/x + \" ms average)\";\n            }\n\n        </script>\n    </head>\n    <body>\n        <a onclick=\"javascript:run(parseCaps, 5); return false\" href=\"#\">Run</a>\n        <div id=\"out\"></div>\n    </body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/speed/wmscaps.js",
    "content": "var caps = \n'<?xml version=\"1.0\" encoding=\"UTF-8\"?>' +\n'<!DOCTYPE WMT_MS_Capabilities SYSTEM \"http://demo.boundlessgeo.com/geoserver/schemas/wms/1.1.1/WMS_MS_Capabilities.dtd\">' +\n'<WMT_MS_Capabilities version=\"1.1.1\" updateSequence=\"145\">' +\n'  <Service>' +\n'    <Name>OGC:WMS</Name>' +\n'    <Title>GeoServer Web Map Service</Title>' +\n'    <Abstract>A compliant implementation of WMS 1.1.1 plus most of the SLD 1.0 extension (dynamic styling). Can also generate PDF, SVG, KML, GeoRSS</Abstract>' +\n'    <KeywordList>' +\n'      <Keyword>WFS</Keyword>' +\n'      <Keyword>WMS</Keyword>' +\n'      <Keyword>GEOSERVER</Keyword>' +\n'    </KeywordList>' +\n'    <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms\"/>' +\n'    <ContactInformation>' +\n'      <ContactPersonPrimary>' +\n'        <ContactPerson>Claudius Ptolomaeus</ContactPerson>' +\n'        <ContactOrganization>The ancient geographes INC</ContactOrganization>' +\n'      </ContactPersonPrimary>' +\n'      <ContactPosition>Chief geographer</ContactPosition>' +\n'      <ContactAddress>' +\n'        <AddressType>Work</AddressType>' +\n'        <Address/>' +\n'        <City>Alexandria</City>' +\n'        <StateOrProvince/>' +\n'        <PostCode/>' +\n'        <Country>Egypt</Country>' +\n'      </ContactAddress>' +\n'      <ContactVoiceTelephone/>' +\n'      <ContactFacsimileTelephone/>' +\n'      <ContactElectronicMailAddress>claudius.ptolomaeus@gmail.com</ContactElectronicMailAddress>' +\n'    </ContactInformation>' +\n'    <Fees>NONE</Fees>' +\n'    <AccessConstraints>NONE</AccessConstraints>' +\n'  </Service>' +\n'  <Capability>' +\n'    <Request>' +\n'      <GetCapabilities>' +\n'        <Format>application/vnd.ogc.wms_xml</Format>' +\n'        <DCPType>' +\n'          <HTTP>' +\n'            <Get>' +\n'              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms?SERVICE=WMS&amp;\"/>' +\n'            </Get>' +\n'            <Post>' +\n'              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms?SERVICE=WMS&amp;\"/>' +\n'            </Post>' +\n'          </HTTP>' +\n'        </DCPType>' +\n'      </GetCapabilities>' +\n'      <GetMap>' +\n'        <Format>image/png</Format>' +\n'        <Format>application/atom xml</Format>' +\n'        <Format>application/atom+xml</Format>' +\n'        <Format>application/openlayers</Format>' +\n'        <Format>application/pdf</Format>' +\n'        <Format>application/rss xml</Format>' +\n'        <Format>application/rss+xml</Format>' +\n'        <Format>application/vnd.google-earth.kml</Format>' +\n'        <Format>application/vnd.google-earth.kml xml</Format>' +\n'        <Format>application/vnd.google-earth.kml+xml</Format>' +\n'        <Format>application/vnd.google-earth.kmz</Format>' +\n'        <Format>application/vnd.google-earth.kmz xml</Format>' +\n'        <Format>application/vnd.google-earth.kmz+xml</Format>' +\n'        <Format>atom</Format>' +\n'        <Format>image/geotiff</Format>' +\n'        <Format>image/geotiff8</Format>' +\n'        <Format>image/gif</Format>' +\n'        <Format>image/jpeg</Format>' +\n'        <Format>image/png8</Format>' +\n'        <Format>image/svg</Format>' +\n'        <Format>image/svg xml</Format>' +\n'        <Format>image/svg+xml</Format>' +\n'        <Format>image/tiff</Format>' +\n'        <Format>image/tiff8</Format>' +\n'        <Format>kml</Format>' +\n'        <Format>kmz</Format>' +\n'        <Format>openlayers</Format>' +\n'        <Format>rss</Format>' +\n'        <DCPType>' +\n'          <HTTP>' +\n'            <Get>' +\n'              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms?SERVICE=WMS&amp;\"/>' +\n'            </Get>' +\n'          </HTTP>' +\n'        </DCPType>' +\n'      </GetMap>' +\n'      <GetFeatureInfo>' +\n'        <Format>text/plain</Format>' +\n'        <Format>text/html</Format>' +\n'        <Format>application/vnd.ogc.gml</Format>' +\n'        <DCPType>' +\n'          <HTTP>' +\n'            <Get>' +\n'              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms?SERVICE=WMS&amp;\"/>' +\n'            </Get>' +\n'            <Post>' +\n'              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms?SERVICE=WMS&amp;\"/>' +\n'            </Post>' +\n'          </HTTP>' +\n'        </DCPType>' +\n'      </GetFeatureInfo>' +\n'      <DescribeLayer>' +\n'        <Format>application/vnd.ogc.wms_xml</Format>' +\n'        <DCPType>' +\n'          <HTTP>' +\n'            <Get>' +\n'              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms?SERVICE=WMS&amp;\"/>' +\n'            </Get>' +\n'          </HTTP>' +\n'        </DCPType>' +\n'      </DescribeLayer>' +\n'      <GetLegendGraphic>' +\n'        <Format>image/png</Format>' +\n'        <Format>image/jpeg</Format>' +\n'        <Format>image/gif</Format>' +\n'        <DCPType>' +\n'          <HTTP>' +\n'            <Get>' +\n'              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms?SERVICE=WMS&amp;\"/>' +\n'            </Get>' +\n'          </HTTP>' +\n'        </DCPType>' +\n'      </GetLegendGraphic>' +\n'    </Request>' +\n'    <Exception>' +\n'      <Format>application/vnd.ogc.se_xml</Format>' +\n'    </Exception>' +\n'    <UserDefinedSymbolization SupportSLD=\"1\" UserLayer=\"1\" UserStyle=\"1\" RemoteWFS=\"1\"/>' +\n'    <Layer>' +\n'      <Title>GeoServer Web Map Service</Title>' +\n'      <Abstract>A compliant implementation of WMS 1.1.1 plus most of the SLD 1.0 extension (dynamic styling). Can also generate PDF, SVG, KML, GeoRSS</Abstract>' +\n'      <!--All supported EPSG projections:-->' +\n'      <SRS>EPSG:WGS84(DD)</SRS>' +\n'      <SRS>EPSG:2000</SRS>' +\n'      <SRS>EPSG:2001</SRS>' +\n'      <SRS>EPSG:2002</SRS>' +\n'      <SRS>EPSG:2003</SRS>' +\n'      <SRS>EPSG:2004</SRS>' +\n'      <SRS>EPSG:2005</SRS>' +\n'      <SRS>EPSG:2006</SRS>' +\n'      <SRS>EPSG:2007</SRS>' +\n'      <SRS>EPSG:2008</SRS>' +\n'      <SRS>EPSG:2009</SRS>' +\n'      <SRS>EPSG:2010</SRS>' +\n'      <SRS>EPSG:2011</SRS>' +\n'      <SRS>EPSG:2012</SRS>' +\n'      <SRS>EPSG:2013</SRS>' +\n'      <SRS>EPSG:2014</SRS>' +\n'      <SRS>EPSG:2015</SRS>' +\n'      <SRS>EPSG:2016</SRS>' +\n'      <SRS>EPSG:2017</SRS>' +\n'      <SRS>EPSG:2018</SRS>' +\n'      <SRS>EPSG:2019</SRS>' +\n'      <SRS>EPSG:2020</SRS>' +\n'      <SRS>EPSG:2021</SRS>' +\n'      <SRS>EPSG:2022</SRS>' +\n'      <SRS>EPSG:2023</SRS>' +\n'      <SRS>EPSG:2024</SRS>' +\n'      <SRS>EPSG:2025</SRS>' +\n'      <SRS>EPSG:2026</SRS>' +\n'      <SRS>EPSG:2027</SRS>' +\n'      <SRS>EPSG:2028</SRS>' +\n'      <SRS>EPSG:2029</SRS>' +\n'      <SRS>EPSG:2030</SRS>' +\n'      <SRS>EPSG:2031</SRS>' +\n'      <SRS>EPSG:2032</SRS>' +\n'      <SRS>EPSG:2033</SRS>' +\n'      <SRS>EPSG:2034</SRS>' +\n'      <SRS>EPSG:2035</SRS>' +\n'      <SRS>EPSG:2036</SRS>' +\n'      <SRS>EPSG:2037</SRS>' +\n'      <SRS>EPSG:2038</SRS>' +\n'      <SRS>EPSG:2039</SRS>' +\n'      <SRS>EPSG:2040</SRS>' +\n'      <SRS>EPSG:2041</SRS>' +\n'      <SRS>EPSG:2042</SRS>' +\n'      <SRS>EPSG:2043</SRS>' +\n'      <SRS>EPSG:2044</SRS>' +\n'      <SRS>EPSG:2045</SRS>' +\n'      <SRS>EPSG:2046</SRS>' +\n'      <SRS>EPSG:2047</SRS>' +\n'      <SRS>EPSG:2048</SRS>' +\n'      <SRS>EPSG:2049</SRS>' +\n'      <SRS>EPSG:2050</SRS>' +\n'      <SRS>EPSG:2051</SRS>' +\n'      <SRS>EPSG:2052</SRS>' +\n'      <SRS>EPSG:2053</SRS>' +\n'      <SRS>EPSG:2054</SRS>' +\n'      <SRS>EPSG:2055</SRS>' +\n'      <SRS>EPSG:2056</SRS>' +\n'      <SRS>EPSG:2057</SRS>' +\n'      <SRS>EPSG:2058</SRS>' +\n'      <SRS>EPSG:2059</SRS>' +\n'      <SRS>EPSG:2060</SRS>' +\n'      <SRS>EPSG:2061</SRS>' +\n'      <SRS>EPSG:2062</SRS>' +\n'      <SRS>EPSG:2063</SRS>' +\n'      <SRS>EPSG:2064</SRS>' +\n'      <SRS>EPSG:2065</SRS>' +\n'      <SRS>EPSG:2066</SRS>' +\n'      <SRS>EPSG:2067</SRS>' +\n'      <SRS>EPSG:2068</SRS>' +\n'      <SRS>EPSG:2069</SRS>' +\n'      <SRS>EPSG:2070</SRS>' +\n'      <SRS>EPSG:2071</SRS>' +\n'      <SRS>EPSG:2072</SRS>' +\n'      <SRS>EPSG:2073</SRS>' +\n'      <SRS>EPSG:2074</SRS>' +\n'      <SRS>EPSG:2075</SRS>' +\n'      <SRS>EPSG:2076</SRS>' +\n'      <SRS>EPSG:2077</SRS>' +\n'      <SRS>EPSG:2078</SRS>' +\n'      <SRS>EPSG:2079</SRS>' +\n'      <SRS>EPSG:2080</SRS>' +\n'      <SRS>EPSG:2081</SRS>' +\n'      <SRS>EPSG:2082</SRS>' +\n'      <SRS>EPSG:2083</SRS>' +\n'      <SRS>EPSG:2084</SRS>' +\n'      <SRS>EPSG:2085</SRS>' +\n'      <SRS>EPSG:2086</SRS>' +\n'      <SRS>EPSG:2087</SRS>' +\n'      <SRS>EPSG:2088</SRS>' +\n'      <SRS>EPSG:2089</SRS>' +\n'      <SRS>EPSG:2090</SRS>' +\n'      <SRS>EPSG:2091</SRS>' +\n'      <SRS>EPSG:2092</SRS>' +\n'      <SRS>EPSG:2093</SRS>' +\n'      <SRS>EPSG:2094</SRS>' +\n'      <SRS>EPSG:2095</SRS>' +\n'      <SRS>EPSG:2096</SRS>' +\n'      <SRS>EPSG:2097</SRS>' +\n'      <SRS>EPSG:2098</SRS>' +\n'      <SRS>EPSG:2099</SRS>' +\n'      <SRS>EPSG:2100</SRS>' +\n'      <SRS>EPSG:2101</SRS>' +\n'      <SRS>EPSG:2102</SRS>' +\n'      <SRS>EPSG:2103</SRS>' +\n'      <SRS>EPSG:2104</SRS>' +\n'      <SRS>EPSG:2105</SRS>' +\n'      <SRS>EPSG:2106</SRS>' +\n'      <SRS>EPSG:2107</SRS>' +\n'      <SRS>EPSG:2108</SRS>' +\n'      <SRS>EPSG:2109</SRS>' +\n'      <SRS>EPSG:2110</SRS>' +\n'      <SRS>EPSG:2111</SRS>' +\n'      <SRS>EPSG:2112</SRS>' +\n'      <SRS>EPSG:2113</SRS>' +\n'      <SRS>EPSG:2114</SRS>' +\n'      <SRS>EPSG:2115</SRS>' +\n'      <SRS>EPSG:2116</SRS>' +\n'      <SRS>EPSG:2117</SRS>' +\n'      <SRS>EPSG:2118</SRS>' +\n'      <SRS>EPSG:2119</SRS>' +\n'      <SRS>EPSG:2120</SRS>' +\n'      <SRS>EPSG:2121</SRS>' +\n'      <SRS>EPSG:2122</SRS>' +\n'      <SRS>EPSG:2123</SRS>' +\n'      <SRS>EPSG:2124</SRS>' +\n'      <SRS>EPSG:2125</SRS>' +\n'      <SRS>EPSG:2126</SRS>' +\n'      <SRS>EPSG:2127</SRS>' +\n'      <SRS>EPSG:2128</SRS>' +\n'      <SRS>EPSG:2129</SRS>' +\n'      <SRS>EPSG:2130</SRS>' +\n'      <SRS>EPSG:2131</SRS>' +\n'      <SRS>EPSG:2132</SRS>' +\n'      <SRS>EPSG:2133</SRS>' +\n'      <SRS>EPSG:2134</SRS>' +\n'      <SRS>EPSG:2135</SRS>' +\n'      <SRS>EPSG:2136</SRS>' +\n'      <SRS>EPSG:2137</SRS>' +\n'      <SRS>EPSG:2138</SRS>' +\n'      <SRS>EPSG:2139</SRS>' +\n'      <SRS>EPSG:2140</SRS>' +\n'      <SRS>EPSG:2141</SRS>' +\n'      <SRS>EPSG:2142</SRS>' +\n'      <SRS>EPSG:2143</SRS>' +\n'      <SRS>EPSG:2144</SRS>' +\n'      <SRS>EPSG:2145</SRS>' +\n'      <SRS>EPSG:2146</SRS>' +\n'      <SRS>EPSG:2147</SRS>' +\n'      <SRS>EPSG:2148</SRS>' +\n'      <SRS>EPSG:2149</SRS>' +\n'      <SRS>EPSG:2150</SRS>' +\n'      <SRS>EPSG:2151</SRS>' +\n'      <SRS>EPSG:2152</SRS>' +\n'      <SRS>EPSG:2153</SRS>' +\n'      <SRS>EPSG:2154</SRS>' +\n'      <SRS>EPSG:2155</SRS>' +\n'      <SRS>EPSG:2156</SRS>' +\n'      <SRS>EPSG:2157</SRS>' +\n'      <SRS>EPSG:2158</SRS>' +\n'      <SRS>EPSG:2159</SRS>' +\n'      <SRS>EPSG:2160</SRS>' +\n'      <SRS>EPSG:2161</SRS>' +\n'      <SRS>EPSG:2162</SRS>' +\n'      <SRS>EPSG:2163</SRS>' +\n'      <SRS>EPSG:2164</SRS>' +\n'      <SRS>EPSG:2165</SRS>' +\n'      <SRS>EPSG:2166</SRS>' +\n'      <SRS>EPSG:2167</SRS>' +\n'      <SRS>EPSG:2168</SRS>' +\n'      <SRS>EPSG:2169</SRS>' +\n'      <SRS>EPSG:2170</SRS>' +\n'      <SRS>EPSG:2171</SRS>' +\n'      <SRS>EPSG:2172</SRS>' +\n'      <SRS>EPSG:2173</SRS>' +\n'      <SRS>EPSG:2174</SRS>' +\n'      <SRS>EPSG:2175</SRS>' +\n'      <SRS>EPSG:2176</SRS>' +\n'      <SRS>EPSG:2177</SRS>' +\n'      <SRS>EPSG:2178</SRS>' +\n'      <SRS>EPSG:2179</SRS>' +\n'      <SRS>EPSG:2180</SRS>' +\n'      <SRS>EPSG:2188</SRS>' +\n'      <SRS>EPSG:2189</SRS>' +\n'      <SRS>EPSG:2190</SRS>' +\n'      <SRS>EPSG:2191</SRS>' +\n'      <SRS>EPSG:2192</SRS>' +\n'      <SRS>EPSG:2193</SRS>' +\n'      <SRS>EPSG:2194</SRS>' +\n'      <SRS>EPSG:2195</SRS>' +\n'      <SRS>EPSG:2196</SRS>' +\n'      <SRS>EPSG:2197</SRS>' +\n'      <SRS>EPSG:2198</SRS>' +\n'      <SRS>EPSG:2199</SRS>' +\n'      <SRS>EPSG:2200</SRS>' +\n'      <SRS>EPSG:2201</SRS>' +\n'      <SRS>EPSG:2202</SRS>' +\n'      <SRS>EPSG:2203</SRS>' +\n'      <SRS>EPSG:2204</SRS>' +\n'      <SRS>EPSG:2205</SRS>' +\n'      <SRS>EPSG:2206</SRS>' +\n'      <SRS>EPSG:2207</SRS>' +\n'      <SRS>EPSG:2208</SRS>' +\n'      <SRS>EPSG:2209</SRS>' +\n'      <SRS>EPSG:2210</SRS>' +\n'      <SRS>EPSG:2211</SRS>' +\n'      <SRS>EPSG:2212</SRS>' +\n'      <SRS>EPSG:2213</SRS>' +\n'      <SRS>EPSG:2214</SRS>' +\n'      <SRS>EPSG:2215</SRS>' +\n'      <SRS>EPSG:2216</SRS>' +\n'      <SRS>EPSG:2217</SRS>' +\n'      <SRS>EPSG:2218</SRS>' +\n'      <SRS>EPSG:2219</SRS>' +\n'      <SRS>EPSG:2220</SRS>' +\n'      <SRS>EPSG:2221</SRS>' +\n'      <SRS>EPSG:2222</SRS>' +\n'      <SRS>EPSG:2223</SRS>' +\n'      <SRS>EPSG:2224</SRS>' +\n'      <SRS>EPSG:2225</SRS>' +\n'      <SRS>EPSG:2226</SRS>' +\n'      <SRS>EPSG:2227</SRS>' +\n'      <SRS>EPSG:2228</SRS>' +\n'      <SRS>EPSG:2229</SRS>' +\n'      <SRS>EPSG:2230</SRS>' +\n'      <SRS>EPSG:2231</SRS>' +\n'      <SRS>EPSG:2232</SRS>' +\n'      <SRS>EPSG:2233</SRS>' +\n'      <SRS>EPSG:2234</SRS>' +\n'      <SRS>EPSG:2235</SRS>' +\n'      <SRS>EPSG:2236</SRS>' +\n'      <SRS>EPSG:2237</SRS>' +\n'      <SRS>EPSG:2238</SRS>' +\n'      <SRS>EPSG:2239</SRS>' +\n'      <SRS>EPSG:2240</SRS>' +\n'      <SRS>EPSG:2241</SRS>' +\n'      <SRS>EPSG:2242</SRS>' +\n'      <SRS>EPSG:2243</SRS>' +\n'      <SRS>EPSG:2244</SRS>' +\n'      <SRS>EPSG:2245</SRS>' +\n'      <SRS>EPSG:2246</SRS>' +\n'      <SRS>EPSG:2247</SRS>' +\n'      <SRS>EPSG:2248</SRS>' +\n'      <SRS>EPSG:2249</SRS>' +\n'      <SRS>EPSG:2250</SRS>' +\n'      <SRS>EPSG:2251</SRS>' +\n'      <SRS>EPSG:2252</SRS>' +\n'      <SRS>EPSG:2253</SRS>' +\n'      <SRS>EPSG:2254</SRS>' +\n'      <SRS>EPSG:2255</SRS>' +\n'      <SRS>EPSG:2256</SRS>' +\n'      <SRS>EPSG:2257</SRS>' +\n'      <SRS>EPSG:2258</SRS>' +\n'      <SRS>EPSG:2259</SRS>' +\n'      <SRS>EPSG:2260</SRS>' +\n'      <SRS>EPSG:2261</SRS>' +\n'      <SRS>EPSG:2262</SRS>' +\n'      <SRS>EPSG:2263</SRS>' +\n'      <SRS>EPSG:2264</SRS>' +\n'      <SRS>EPSG:2265</SRS>' +\n'      <SRS>EPSG:2266</SRS>' +\n'      <SRS>EPSG:2267</SRS>' +\n'      <SRS>EPSG:2268</SRS>' +\n'      <SRS>EPSG:2269</SRS>' +\n'      <SRS>EPSG:2270</SRS>' +\n'      <SRS>EPSG:2271</SRS>' +\n'      <SRS>EPSG:2272</SRS>' +\n'      <SRS>EPSG:2273</SRS>' +\n'      <SRS>EPSG:2274</SRS>' +\n'      <SRS>EPSG:2275</SRS>' +\n'      <SRS>EPSG:2276</SRS>' +\n'      <SRS>EPSG:2277</SRS>' +\n'      <SRS>EPSG:2278</SRS>' +\n'      <SRS>EPSG:2279</SRS>' +\n'      <SRS>EPSG:2280</SRS>' +\n'      <SRS>EPSG:2281</SRS>' +\n'      <SRS>EPSG:2282</SRS>' +\n'      <SRS>EPSG:2283</SRS>' +\n'      <SRS>EPSG:2284</SRS>' +\n'      <SRS>EPSG:2285</SRS>' +\n'      <SRS>EPSG:2286</SRS>' +\n'      <SRS>EPSG:2287</SRS>' +\n'      <SRS>EPSG:2288</SRS>' +\n'      <SRS>EPSG:2289</SRS>' +\n'      <SRS>EPSG:2290</SRS>' +\n'      <SRS>EPSG:2291</SRS>' +\n'      <SRS>EPSG:2292</SRS>' +\n'      <SRS>EPSG:2294</SRS>' +\n'      <SRS>EPSG:2295</SRS>' +\n'      <SRS>EPSG:2296</SRS>' +\n'      <SRS>EPSG:2297</SRS>' +\n'      <SRS>EPSG:2298</SRS>' +\n'      <SRS>EPSG:2299</SRS>' +\n'      <SRS>EPSG:2300</SRS>' +\n'      <SRS>EPSG:2301</SRS>' +\n'      <SRS>EPSG:2302</SRS>' +\n'      <SRS>EPSG:2303</SRS>' +\n'      <SRS>EPSG:2304</SRS>' +\n'      <SRS>EPSG:2305</SRS>' +\n'      <SRS>EPSG:2306</SRS>' +\n'      <SRS>EPSG:2307</SRS>' +\n'      <SRS>EPSG:2308</SRS>' +\n'      <SRS>EPSG:2309</SRS>' +\n'      <SRS>EPSG:2310</SRS>' +\n'      <SRS>EPSG:2311</SRS>' +\n'      <SRS>EPSG:2312</SRS>' +\n'      <SRS>EPSG:2313</SRS>' +\n'      <SRS>EPSG:2314</SRS>' +\n'      <SRS>EPSG:2315</SRS>' +\n'      <SRS>EPSG:2316</SRS>' +\n'      <SRS>EPSG:2317</SRS>' +\n'      <SRS>EPSG:2318</SRS>' +\n'      <SRS>EPSG:2319</SRS>' +\n'      <SRS>EPSG:2320</SRS>' +\n'      <SRS>EPSG:2321</SRS>' +\n'      <SRS>EPSG:2322</SRS>' +\n'      <SRS>EPSG:2323</SRS>' +\n'      <SRS>EPSG:2324</SRS>' +\n'      <SRS>EPSG:2325</SRS>' +\n'      <SRS>EPSG:2326</SRS>' +\n'      <SRS>EPSG:2327</SRS>' +\n'      <SRS>EPSG:2328</SRS>' +\n'      <SRS>EPSG:2329</SRS>' +\n'      <SRS>EPSG:2330</SRS>' +\n'      <SRS>EPSG:2331</SRS>' +\n'      <SRS>EPSG:2332</SRS>' +\n'      <SRS>EPSG:2333</SRS>' +\n'      <SRS>EPSG:2334</SRS>' +\n'      <SRS>EPSG:2335</SRS>' +\n'      <SRS>EPSG:2336</SRS>' +\n'      <SRS>EPSG:2337</SRS>' +\n'      <SRS>EPSG:2338</SRS>' +\n'      <SRS>EPSG:2339</SRS>' +\n'      <SRS>EPSG:2340</SRS>' +\n'      <SRS>EPSG:2341</SRS>' +\n'      <SRS>EPSG:2342</SRS>' +\n'      <SRS>EPSG:2343</SRS>' +\n'      <SRS>EPSG:2344</SRS>' +\n'      <SRS>EPSG:2345</SRS>' +\n'      <SRS>EPSG:2346</SRS>' +\n'      <SRS>EPSG:2347</SRS>' +\n'      <SRS>EPSG:2348</SRS>' +\n'      <SRS>EPSG:2349</SRS>' +\n'      <SRS>EPSG:2350</SRS>' +\n'      <SRS>EPSG:2351</SRS>' +\n'      <SRS>EPSG:2352</SRS>' +\n'      <SRS>EPSG:2353</SRS>' +\n'      <SRS>EPSG:2354</SRS>' +\n'      <SRS>EPSG:2355</SRS>' +\n'      <SRS>EPSG:2356</SRS>' +\n'      <SRS>EPSG:2357</SRS>' +\n'      <SRS>EPSG:2358</SRS>' +\n'      <SRS>EPSG:2359</SRS>' +\n'      <SRS>EPSG:2360</SRS>' +\n'      <SRS>EPSG:2361</SRS>' +\n'      <SRS>EPSG:2362</SRS>' +\n'      <SRS>EPSG:2363</SRS>' +\n'      <SRS>EPSG:2364</SRS>' +\n'      <SRS>EPSG:2365</SRS>' +\n'      <SRS>EPSG:2366</SRS>' +\n'      <SRS>EPSG:2367</SRS>' +\n'      <SRS>EPSG:2368</SRS>' +\n'      <SRS>EPSG:2369</SRS>' +\n'      <SRS>EPSG:2370</SRS>' +\n'      <SRS>EPSG:2371</SRS>' +\n'      <SRS>EPSG:2372</SRS>' +\n'      <SRS>EPSG:2373</SRS>' +\n'      <SRS>EPSG:2374</SRS>' +\n'      <SRS>EPSG:2375</SRS>' +\n'      <SRS>EPSG:2376</SRS>' +\n'      <SRS>EPSG:2377</SRS>' +\n'      <SRS>EPSG:2378</SRS>' +\n'      <SRS>EPSG:2379</SRS>' +\n'      <SRS>EPSG:2380</SRS>' +\n'      <SRS>EPSG:2381</SRS>' +\n'      <SRS>EPSG:2382</SRS>' +\n'      <SRS>EPSG:2383</SRS>' +\n'      <SRS>EPSG:2384</SRS>' +\n'      <SRS>EPSG:2385</SRS>' +\n'      <SRS>EPSG:2386</SRS>' +\n'      <SRS>EPSG:2387</SRS>' +\n'      <SRS>EPSG:2388</SRS>' +\n'      <SRS>EPSG:2389</SRS>' +\n'      <SRS>EPSG:2390</SRS>' +\n'      <SRS>EPSG:2391</SRS>' +\n'      <SRS>EPSG:2392</SRS>' +\n'      <SRS>EPSG:2393</SRS>' +\n'      <SRS>EPSG:2394</SRS>' +\n'      <SRS>EPSG:2395</SRS>' +\n'      <SRS>EPSG:2396</SRS>' +\n'      <SRS>EPSG:2397</SRS>' +\n'      <SRS>EPSG:2398</SRS>' +\n'      <SRS>EPSG:2399</SRS>' +\n'      <SRS>EPSG:2400</SRS>' +\n'      <SRS>EPSG:2401</SRS>' +\n'      <SRS>EPSG:2402</SRS>' +\n'      <SRS>EPSG:2403</SRS>' +\n'      <SRS>EPSG:2404</SRS>' +\n'      <SRS>EPSG:2405</SRS>' +\n'      <SRS>EPSG:2406</SRS>' +\n'      <SRS>EPSG:2407</SRS>' +\n'      <SRS>EPSG:2408</SRS>' +\n'      <SRS>EPSG:2409</SRS>' +\n'      <SRS>EPSG:2410</SRS>' +\n'      <SRS>EPSG:2411</SRS>' +\n'      <SRS>EPSG:2412</SRS>' +\n'      <SRS>EPSG:2413</SRS>' +\n'      <SRS>EPSG:2414</SRS>' +\n'      <SRS>EPSG:2415</SRS>' +\n'      <SRS>EPSG:2416</SRS>' +\n'      <SRS>EPSG:2417</SRS>' +\n'      <SRS>EPSG:2418</SRS>' +\n'      <SRS>EPSG:2419</SRS>' +\n'      <SRS>EPSG:2420</SRS>' +\n'      <SRS>EPSG:2421</SRS>' +\n'      <SRS>EPSG:2422</SRS>' +\n'      <SRS>EPSG:2423</SRS>' +\n'      <SRS>EPSG:2424</SRS>' +\n'      <SRS>EPSG:2425</SRS>' +\n'      <SRS>EPSG:2426</SRS>' +\n'      <SRS>EPSG:2427</SRS>' +\n'      <SRS>EPSG:2428</SRS>' +\n'      <SRS>EPSG:2429</SRS>' +\n'      <SRS>EPSG:2430</SRS>' +\n'      <SRS>EPSG:2431</SRS>' +\n'      <SRS>EPSG:2432</SRS>' +\n'      <SRS>EPSG:2433</SRS>' +\n'      <SRS>EPSG:2434</SRS>' +\n'      <SRS>EPSG:2435</SRS>' +\n'      <SRS>EPSG:2436</SRS>' +\n'      <SRS>EPSG:2437</SRS>' +\n'      <SRS>EPSG:2438</SRS>' +\n'      <SRS>EPSG:2439</SRS>' +\n'      <SRS>EPSG:2440</SRS>' +\n'      <SRS>EPSG:2441</SRS>' +\n'      <SRS>EPSG:2442</SRS>' +\n'      <SRS>EPSG:2443</SRS>' +\n'      <SRS>EPSG:2444</SRS>' +\n'      <SRS>EPSG:2445</SRS>' +\n'      <SRS>EPSG:2446</SRS>' +\n'      <SRS>EPSG:2447</SRS>' +\n'      <SRS>EPSG:2448</SRS>' +\n'      <SRS>EPSG:2449</SRS>' +\n'      <SRS>EPSG:2450</SRS>' +\n'      <SRS>EPSG:2451</SRS>' +\n'      <SRS>EPSG:2452</SRS>' +\n'      <SRS>EPSG:2453</SRS>' +\n'      <SRS>EPSG:2454</SRS>' +\n'      <SRS>EPSG:2455</SRS>' +\n'      <SRS>EPSG:2456</SRS>' +\n'      <SRS>EPSG:2457</SRS>' +\n'      <SRS>EPSG:2458</SRS>' +\n'      <SRS>EPSG:2459</SRS>' +\n'      <SRS>EPSG:2460</SRS>' +\n'      <SRS>EPSG:2461</SRS>' +\n'      <SRS>EPSG:2462</SRS>' +\n'      <SRS>EPSG:2463</SRS>' +\n'      <SRS>EPSG:2464</SRS>' +\n'      <SRS>EPSG:2465</SRS>' +\n'      <SRS>EPSG:2466</SRS>' +\n'      <SRS>EPSG:2467</SRS>' +\n'      <SRS>EPSG:2468</SRS>' +\n'      <SRS>EPSG:2469</SRS>' +\n'      <SRS>EPSG:2470</SRS>' +\n'      <SRS>EPSG:2471</SRS>' +\n'      <SRS>EPSG:2472</SRS>' +\n'      <SRS>EPSG:2473</SRS>' +\n'      <SRS>EPSG:2474</SRS>' +\n'      <SRS>EPSG:2475</SRS>' +\n'      <SRS>EPSG:2476</SRS>' +\n'      <SRS>EPSG:2477</SRS>' +\n'      <SRS>EPSG:2478</SRS>' +\n'      <SRS>EPSG:2479</SRS>' +\n'      <SRS>EPSG:2480</SRS>' +\n'      <SRS>EPSG:2481</SRS>' +\n'      <SRS>EPSG:2482</SRS>' +\n'      <SRS>EPSG:2483</SRS>' +\n'      <SRS>EPSG:2484</SRS>' +\n'      <SRS>EPSG:2485</SRS>' +\n'      <SRS>EPSG:2486</SRS>' +\n'      <SRS>EPSG:2487</SRS>' +\n'      <SRS>EPSG:2488</SRS>' +\n'      <SRS>EPSG:2489</SRS>' +\n'      <SRS>EPSG:2490</SRS>' +\n'      <SRS>EPSG:2491</SRS>' +\n'      <SRS>EPSG:2492</SRS>' +\n'      <SRS>EPSG:2493</SRS>' +\n'      <SRS>EPSG:2494</SRS>' +\n'      <SRS>EPSG:2495</SRS>' +\n'      <SRS>EPSG:2496</SRS>' +\n'      <SRS>EPSG:2497</SRS>' +\n'      <SRS>EPSG:2498</SRS>' +\n'      <SRS>EPSG:2499</SRS>' +\n'      <SRS>EPSG:2500</SRS>' +\n'      <SRS>EPSG:2501</SRS>' +\n'      <SRS>EPSG:2502</SRS>' +\n'      <SRS>EPSG:2503</SRS>' +\n'      <SRS>EPSG:2504</SRS>' +\n'      <SRS>EPSG:2505</SRS>' +\n'      <SRS>EPSG:2506</SRS>' +\n'      <SRS>EPSG:2507</SRS>' +\n'      <SRS>EPSG:2508</SRS>' +\n'      <SRS>EPSG:2509</SRS>' +\n'      <SRS>EPSG:2510</SRS>' +\n'      <SRS>EPSG:2511</SRS>' +\n'      <SRS>EPSG:2512</SRS>' +\n'      <SRS>EPSG:2513</SRS>' +\n'      <SRS>EPSG:2514</SRS>' +\n'      <SRS>EPSG:2515</SRS>' +\n'      <SRS>EPSG:2516</SRS>' +\n'      <SRS>EPSG:2517</SRS>' +\n'      <SRS>EPSG:2518</SRS>' +\n'      <SRS>EPSG:2519</SRS>' +\n'      <SRS>EPSG:2520</SRS>' +\n'      <SRS>EPSG:2521</SRS>' +\n'      <SRS>EPSG:2522</SRS>' +\n'      <SRS>EPSG:2523</SRS>' +\n'      <SRS>EPSG:2524</SRS>' +\n'      <SRS>EPSG:2525</SRS>' +\n'      <SRS>EPSG:2526</SRS>' +\n'      <SRS>EPSG:2527</SRS>' +\n'      <SRS>EPSG:2528</SRS>' +\n'      <SRS>EPSG:2529</SRS>' +\n'      <SRS>EPSG:2530</SRS>' +\n'      <SRS>EPSG:2531</SRS>' +\n'      <SRS>EPSG:2532</SRS>' +\n'      <SRS>EPSG:2533</SRS>' +\n'      <SRS>EPSG:2534</SRS>' +\n'      <SRS>EPSG:2535</SRS>' +\n'      <SRS>EPSG:2536</SRS>' +\n'      <SRS>EPSG:2537</SRS>' +\n'      <SRS>EPSG:2538</SRS>' +\n'      <SRS>EPSG:2539</SRS>' +\n'      <SRS>EPSG:2540</SRS>' +\n'      <SRS>EPSG:2541</SRS>' +\n'      <SRS>EPSG:2542</SRS>' +\n'      <SRS>EPSG:2543</SRS>' +\n'      <SRS>EPSG:2544</SRS>' +\n'      <SRS>EPSG:2545</SRS>' +\n'      <SRS>EPSG:2546</SRS>' +\n'      <SRS>EPSG:2547</SRS>' +\n'      <SRS>EPSG:2548</SRS>' +\n'      <SRS>EPSG:2549</SRS>' +\n'      <SRS>EPSG:2550</SRS>' +\n'      <SRS>EPSG:2551</SRS>' +\n'      <SRS>EPSG:2552</SRS>' +\n'      <SRS>EPSG:2553</SRS>' +\n'      <SRS>EPSG:2554</SRS>' +\n'      <SRS>EPSG:2555</SRS>' +\n'      <SRS>EPSG:2556</SRS>' +\n'      <SRS>EPSG:2557</SRS>' +\n'      <SRS>EPSG:2558</SRS>' +\n'      <SRS>EPSG:2559</SRS>' +\n'      <SRS>EPSG:2560</SRS>' +\n'      <SRS>EPSG:2561</SRS>' +\n'      <SRS>EPSG:2562</SRS>' +\n'      <SRS>EPSG:2563</SRS>' +\n'      <SRS>EPSG:2564</SRS>' +\n'      <SRS>EPSG:2565</SRS>' +\n'      <SRS>EPSG:2566</SRS>' +\n'      <SRS>EPSG:2567</SRS>' +\n'      <SRS>EPSG:2568</SRS>' +\n'      <SRS>EPSG:2569</SRS>' +\n'      <SRS>EPSG:2570</SRS>' +\n'      <SRS>EPSG:2571</SRS>' +\n'      <SRS>EPSG:2572</SRS>' +\n'      <SRS>EPSG:2573</SRS>' +\n'      <SRS>EPSG:2574</SRS>' +\n'      <SRS>EPSG:2575</SRS>' +\n'      <SRS>EPSG:2576</SRS>' +\n'      <SRS>EPSG:2577</SRS>' +\n'      <SRS>EPSG:2578</SRS>' +\n'      <SRS>EPSG:2579</SRS>' +\n'      <SRS>EPSG:2580</SRS>' +\n'      <SRS>EPSG:2581</SRS>' +\n'      <SRS>EPSG:2582</SRS>' +\n'      <SRS>EPSG:2583</SRS>' +\n'      <SRS>EPSG:2584</SRS>' +\n'      <SRS>EPSG:2585</SRS>' +\n'      <SRS>EPSG:2586</SRS>' +\n'      <SRS>EPSG:2587</SRS>' +\n'      <SRS>EPSG:2588</SRS>' +\n'      <SRS>EPSG:2589</SRS>' +\n'      <SRS>EPSG:2590</SRS>' +\n'      <SRS>EPSG:2591</SRS>' +\n'      <SRS>EPSG:2592</SRS>' +\n'      <SRS>EPSG:2593</SRS>' +\n'      <SRS>EPSG:2594</SRS>' +\n'      <SRS>EPSG:2595</SRS>' +\n'      <SRS>EPSG:2596</SRS>' +\n'      <SRS>EPSG:2597</SRS>' +\n'      <SRS>EPSG:2598</SRS>' +\n'      <SRS>EPSG:2599</SRS>' +\n'      <SRS>EPSG:2600</SRS>' +\n'      <SRS>EPSG:2601</SRS>' +\n'      <SRS>EPSG:2602</SRS>' +\n'      <SRS>EPSG:2603</SRS>' +\n'      <SRS>EPSG:2604</SRS>' +\n'      <SRS>EPSG:2605</SRS>' +\n'      <SRS>EPSG:2606</SRS>' +\n'      <SRS>EPSG:2607</SRS>' +\n'      <SRS>EPSG:2608</SRS>' +\n'      <SRS>EPSG:2609</SRS>' +\n'      <SRS>EPSG:2610</SRS>' +\n'      <SRS>EPSG:2611</SRS>' +\n'      <SRS>EPSG:2612</SRS>' +\n'      <SRS>EPSG:2613</SRS>' +\n'      <SRS>EPSG:2614</SRS>' +\n'      <SRS>EPSG:2615</SRS>' +\n'      <SRS>EPSG:2616</SRS>' +\n'      <SRS>EPSG:2617</SRS>' +\n'      <SRS>EPSG:2618</SRS>' +\n'      <SRS>EPSG:2619</SRS>' +\n'      <SRS>EPSG:2620</SRS>' +\n'      <SRS>EPSG:2621</SRS>' +\n'      <SRS>EPSG:2622</SRS>' +\n'      <SRS>EPSG:2623</SRS>' +\n'      <SRS>EPSG:2624</SRS>' +\n'      <SRS>EPSG:2625</SRS>' +\n'      <SRS>EPSG:2626</SRS>' +\n'      <SRS>EPSG:2627</SRS>' +\n'      <SRS>EPSG:2628</SRS>' +\n'      <SRS>EPSG:2629</SRS>' +\n'      <SRS>EPSG:2630</SRS>' +\n'      <SRS>EPSG:2631</SRS>' +\n'      <SRS>EPSG:2632</SRS>' +\n'      <SRS>EPSG:2633</SRS>' +\n'      <SRS>EPSG:2634</SRS>' +\n'      <SRS>EPSG:2635</SRS>' +\n'      <SRS>EPSG:2636</SRS>' +\n'      <SRS>EPSG:2637</SRS>' +\n'      <SRS>EPSG:2638</SRS>' +\n'      <SRS>EPSG:2639</SRS>' +\n'      <SRS>EPSG:2640</SRS>' +\n'      <SRS>EPSG:2641</SRS>' +\n'      <SRS>EPSG:2642</SRS>' +\n'      <SRS>EPSG:2643</SRS>' +\n'      <SRS>EPSG:2644</SRS>' +\n'      <SRS>EPSG:2645</SRS>' +\n'      <SRS>EPSG:2646</SRS>' +\n'      <SRS>EPSG:2647</SRS>' +\n'      <SRS>EPSG:2648</SRS>' +\n'      <SRS>EPSG:2649</SRS>' +\n'      <SRS>EPSG:2650</SRS>' +\n'      <SRS>EPSG:2651</SRS>' +\n'      <SRS>EPSG:2652</SRS>' +\n'      <SRS>EPSG:2653</SRS>' +\n'      <SRS>EPSG:2654</SRS>' +\n'      <SRS>EPSG:2655</SRS>' +\n'      <SRS>EPSG:2656</SRS>' +\n'      <SRS>EPSG:2657</SRS>' +\n'      <SRS>EPSG:2658</SRS>' +\n'      <SRS>EPSG:2659</SRS>' +\n'      <SRS>EPSG:2660</SRS>' +\n'      <SRS>EPSG:2661</SRS>' +\n'      <SRS>EPSG:2662</SRS>' +\n'      <SRS>EPSG:2663</SRS>' +\n'      <SRS>EPSG:2664</SRS>' +\n'      <SRS>EPSG:2665</SRS>' +\n'      <SRS>EPSG:2666</SRS>' +\n'      <SRS>EPSG:2667</SRS>' +\n'      <SRS>EPSG:2668</SRS>' +\n'      <SRS>EPSG:2669</SRS>' +\n'      <SRS>EPSG:2670</SRS>' +\n'      <SRS>EPSG:2671</SRS>' +\n'      <SRS>EPSG:2672</SRS>' +\n'      <SRS>EPSG:2673</SRS>' +\n'      <SRS>EPSG:2674</SRS>' +\n'      <SRS>EPSG:2675</SRS>' +\n'      <SRS>EPSG:2676</SRS>' +\n'      <SRS>EPSG:2677</SRS>' +\n'      <SRS>EPSG:2678</SRS>' +\n'      <SRS>EPSG:2679</SRS>' +\n'      <SRS>EPSG:2680</SRS>' +\n'      <SRS>EPSG:2681</SRS>' +\n'      <SRS>EPSG:2682</SRS>' +\n'      <SRS>EPSG:2683</SRS>' +\n'      <SRS>EPSG:2684</SRS>' +\n'      <SRS>EPSG:2685</SRS>' +\n'      <SRS>EPSG:2686</SRS>' +\n'      <SRS>EPSG:2687</SRS>' +\n'      <SRS>EPSG:2688</SRS>' +\n'      <SRS>EPSG:2689</SRS>' +\n'      <SRS>EPSG:2690</SRS>' +\n'      <SRS>EPSG:2691</SRS>' +\n'      <SRS>EPSG:2692</SRS>' +\n'      <SRS>EPSG:2693</SRS>' +\n'      <SRS>EPSG:2694</SRS>' +\n'      <SRS>EPSG:2695</SRS>' +\n'      <SRS>EPSG:2696</SRS>' +\n'      <SRS>EPSG:2697</SRS>' +\n'      <SRS>EPSG:2698</SRS>' +\n'      <SRS>EPSG:2699</SRS>' +\n'      <SRS>EPSG:2700</SRS>' +\n'      <SRS>EPSG:2701</SRS>' +\n'      <SRS>EPSG:2702</SRS>' +\n'      <SRS>EPSG:2703</SRS>' +\n'      <SRS>EPSG:2704</SRS>' +\n'      <SRS>EPSG:2705</SRS>' +\n'      <SRS>EPSG:2706</SRS>' +\n'      <SRS>EPSG:2707</SRS>' +\n'      <SRS>EPSG:2708</SRS>' +\n'      <SRS>EPSG:2709</SRS>' +\n'      <SRS>EPSG:2710</SRS>' +\n'      <SRS>EPSG:2711</SRS>' +\n'      <SRS>EPSG:2712</SRS>' +\n'      <SRS>EPSG:2713</SRS>' +\n'      <SRS>EPSG:2714</SRS>' +\n'      <SRS>EPSG:2715</SRS>' +\n'      <SRS>EPSG:2716</SRS>' +\n'      <SRS>EPSG:2717</SRS>' +\n'      <SRS>EPSG:2718</SRS>' +\n'      <SRS>EPSG:2719</SRS>' +\n'      <SRS>EPSG:2720</SRS>' +\n'      <SRS>EPSG:2721</SRS>' +\n'      <SRS>EPSG:2722</SRS>' +\n'      <SRS>EPSG:2723</SRS>' +\n'      <SRS>EPSG:2724</SRS>' +\n'      <SRS>EPSG:2725</SRS>' +\n'      <SRS>EPSG:2726</SRS>' +\n'      <SRS>EPSG:2727</SRS>' +\n'      <SRS>EPSG:2728</SRS>' +\n'      <SRS>EPSG:2729</SRS>' +\n'      <SRS>EPSG:2730</SRS>' +\n'      <SRS>EPSG:2731</SRS>' +\n'      <SRS>EPSG:2732</SRS>' +\n'      <SRS>EPSG:2733</SRS>' +\n'      <SRS>EPSG:2734</SRS>' +\n'      <SRS>EPSG:2735</SRS>' +\n'      <SRS>EPSG:2736</SRS>' +\n'      <SRS>EPSG:2737</SRS>' +\n'      <SRS>EPSG:2738</SRS>' +\n'      <SRS>EPSG:2739</SRS>' +\n'      <SRS>EPSG:2740</SRS>' +\n'      <SRS>EPSG:2741</SRS>' +\n'      <SRS>EPSG:2742</SRS>' +\n'      <SRS>EPSG:2743</SRS>' +\n'      <SRS>EPSG:2744</SRS>' +\n'      <SRS>EPSG:2745</SRS>' +\n'      <SRS>EPSG:2746</SRS>' +\n'      <SRS>EPSG:2747</SRS>' +\n'      <SRS>EPSG:2748</SRS>' +\n'      <SRS>EPSG:2749</SRS>' +\n'      <SRS>EPSG:2750</SRS>' +\n'      <SRS>EPSG:2751</SRS>' +\n'      <SRS>EPSG:2752</SRS>' +\n'      <SRS>EPSG:2753</SRS>' +\n'      <SRS>EPSG:2754</SRS>' +\n'      <SRS>EPSG:2755</SRS>' +\n'      <SRS>EPSG:2756</SRS>' +\n'      <SRS>EPSG:2757</SRS>' +\n'      <SRS>EPSG:2758</SRS>' +\n'      <SRS>EPSG:2759</SRS>' +\n'      <SRS>EPSG:2760</SRS>' +\n'      <SRS>EPSG:2761</SRS>' +\n'      <SRS>EPSG:2762</SRS>' +\n'      <SRS>EPSG:2763</SRS>' +\n'      <SRS>EPSG:2764</SRS>' +\n'      <SRS>EPSG:2765</SRS>' +\n'      <SRS>EPSG:2766</SRS>' +\n'      <SRS>EPSG:2767</SRS>' +\n'      <SRS>EPSG:2768</SRS>' +\n'      <SRS>EPSG:2769</SRS>' +\n'      <SRS>EPSG:2770</SRS>' +\n'      <SRS>EPSG:2771</SRS>' +\n'      <SRS>EPSG:2772</SRS>' +\n'      <SRS>EPSG:2773</SRS>' +\n'      <SRS>EPSG:2774</SRS>' +\n'      <SRS>EPSG:2775</SRS>' +\n'      <SRS>EPSG:2776</SRS>' +\n'      <SRS>EPSG:2777</SRS>' +\n'      <SRS>EPSG:2778</SRS>' +\n'      <SRS>EPSG:2779</SRS>' +\n'      <SRS>EPSG:2780</SRS>' +\n'      <SRS>EPSG:2781</SRS>' +\n'      <SRS>EPSG:2782</SRS>' +\n'      <SRS>EPSG:2783</SRS>' +\n'      <SRS>EPSG:2784</SRS>' +\n'      <SRS>EPSG:2785</SRS>' +\n'      <SRS>EPSG:2786</SRS>' +\n'      <SRS>EPSG:2787</SRS>' +\n'      <SRS>EPSG:2788</SRS>' +\n'      <SRS>EPSG:2789</SRS>' +\n'      <SRS>EPSG:2790</SRS>' +\n'      <SRS>EPSG:2791</SRS>' +\n'      <SRS>EPSG:2792</SRS>' +\n'      <SRS>EPSG:2793</SRS>' +\n'      <SRS>EPSG:2794</SRS>' +\n'      <SRS>EPSG:2795</SRS>' +\n'      <SRS>EPSG:2796</SRS>' +\n'      <SRS>EPSG:2797</SRS>' +\n'      <SRS>EPSG:2798</SRS>' +\n'      <SRS>EPSG:2799</SRS>' +\n'      <SRS>EPSG:2800</SRS>' +\n'      <SRS>EPSG:2801</SRS>' +\n'      <SRS>EPSG:2802</SRS>' +\n'      <SRS>EPSG:2803</SRS>' +\n'      <SRS>EPSG:2804</SRS>' +\n'      <SRS>EPSG:2805</SRS>' +\n'      <SRS>EPSG:2806</SRS>' +\n'      <SRS>EPSG:2807</SRS>' +\n'      <SRS>EPSG:2808</SRS>' +\n'      <SRS>EPSG:2809</SRS>' +\n'      <SRS>EPSG:2810</SRS>' +\n'      <SRS>EPSG:2811</SRS>' +\n'      <SRS>EPSG:2812</SRS>' +\n'      <SRS>EPSG:2813</SRS>' +\n'      <SRS>EPSG:2814</SRS>' +\n'      <SRS>EPSG:2815</SRS>' +\n'      <SRS>EPSG:2816</SRS>' +\n'      <SRS>EPSG:2817</SRS>' +\n'      <SRS>EPSG:2818</SRS>' +\n'      <SRS>EPSG:2819</SRS>' +\n'      <SRS>EPSG:2820</SRS>' +\n'      <SRS>EPSG:2821</SRS>' +\n'      <SRS>EPSG:2822</SRS>' +\n'      <SRS>EPSG:2823</SRS>' +\n'      <SRS>EPSG:2824</SRS>' +\n'      <SRS>EPSG:2825</SRS>' +\n'      <SRS>EPSG:2826</SRS>' +\n'      <SRS>EPSG:2827</SRS>' +\n'      <SRS>EPSG:2828</SRS>' +\n'      <SRS>EPSG:2829</SRS>' +\n'      <SRS>EPSG:2830</SRS>' +\n'      <SRS>EPSG:2831</SRS>' +\n'      <SRS>EPSG:2832</SRS>' +\n'      <SRS>EPSG:2833</SRS>' +\n'      <SRS>EPSG:2834</SRS>' +\n'      <SRS>EPSG:2835</SRS>' +\n'      <SRS>EPSG:2836</SRS>' +\n'      <SRS>EPSG:2837</SRS>' +\n'      <SRS>EPSG:2838</SRS>' +\n'      <SRS>EPSG:2839</SRS>' +\n'      <SRS>EPSG:2840</SRS>' +\n'      <SRS>EPSG:2841</SRS>' +\n'      <SRS>EPSG:2842</SRS>' +\n'      <SRS>EPSG:2843</SRS>' +\n'      <SRS>EPSG:2844</SRS>' +\n'      <SRS>EPSG:2845</SRS>' +\n'      <SRS>EPSG:2846</SRS>' +\n'      <SRS>EPSG:2847</SRS>' +\n'      <SRS>EPSG:2848</SRS>' +\n'      <SRS>EPSG:2849</SRS>' +\n'      <SRS>EPSG:2850</SRS>' +\n'      <SRS>EPSG:2851</SRS>' +\n'      <SRS>EPSG:2852</SRS>' +\n'      <SRS>EPSG:2853</SRS>' +\n'      <SRS>EPSG:2854</SRS>' +\n'      <SRS>EPSG:2855</SRS>' +\n'      <SRS>EPSG:2856</SRS>' +\n'      <SRS>EPSG:2857</SRS>' +\n'      <SRS>EPSG:2858</SRS>' +\n'      <SRS>EPSG:2859</SRS>' +\n'      <SRS>EPSG:2860</SRS>' +\n'      <SRS>EPSG:2861</SRS>' +\n'      <SRS>EPSG:2862</SRS>' +\n'      <SRS>EPSG:2863</SRS>' +\n'      <SRS>EPSG:2864</SRS>' +\n'      <SRS>EPSG:2865</SRS>' +\n'      <SRS>EPSG:2866</SRS>' +\n'      <SRS>EPSG:2867</SRS>' +\n'      <SRS>EPSG:2868</SRS>' +\n'      <SRS>EPSG:2869</SRS>' +\n'      <SRS>EPSG:2870</SRS>' +\n'      <SRS>EPSG:2871</SRS>' +\n'      <SRS>EPSG:2872</SRS>' +\n'      <SRS>EPSG:2873</SRS>' +\n'      <SRS>EPSG:2874</SRS>' +\n'      <SRS>EPSG:2875</SRS>' +\n'      <SRS>EPSG:2876</SRS>' +\n'      <SRS>EPSG:2877</SRS>' +\n'      <SRS>EPSG:2878</SRS>' +\n'      <SRS>EPSG:2879</SRS>' +\n'      <SRS>EPSG:2880</SRS>' +\n'      <SRS>EPSG:2881</SRS>' +\n'      <SRS>EPSG:2882</SRS>' +\n'      <SRS>EPSG:2883</SRS>' +\n'      <SRS>EPSG:2884</SRS>' +\n'      <SRS>EPSG:2885</SRS>' +\n'      <SRS>EPSG:2886</SRS>' +\n'      <SRS>EPSG:2887</SRS>' +\n'      <SRS>EPSG:2888</SRS>' +\n'      <SRS>EPSG:2889</SRS>' +\n'      <SRS>EPSG:2890</SRS>' +\n'      <SRS>EPSG:2891</SRS>' +\n'      <SRS>EPSG:2892</SRS>' +\n'      <SRS>EPSG:2893</SRS>' +\n'      <SRS>EPSG:2894</SRS>' +\n'      <SRS>EPSG:2895</SRS>' +\n'      <SRS>EPSG:2896</SRS>' +\n'      <SRS>EPSG:2897</SRS>' +\n'      <SRS>EPSG:2898</SRS>' +\n'      <SRS>EPSG:2899</SRS>' +\n'      <SRS>EPSG:2900</SRS>' +\n'      <SRS>EPSG:2901</SRS>' +\n'      <SRS>EPSG:2902</SRS>' +\n'      <SRS>EPSG:2903</SRS>' +\n'      <SRS>EPSG:2904</SRS>' +\n'      <SRS>EPSG:2905</SRS>' +\n'      <SRS>EPSG:2906</SRS>' +\n'      <SRS>EPSG:2907</SRS>' +\n'      <SRS>EPSG:2908</SRS>' +\n'      <SRS>EPSG:2909</SRS>' +\n'      <SRS>EPSG:2910</SRS>' +\n'      <SRS>EPSG:2911</SRS>' +\n'      <SRS>EPSG:2912</SRS>' +\n'      <SRS>EPSG:2913</SRS>' +\n'      <SRS>EPSG:2914</SRS>' +\n'      <SRS>EPSG:2915</SRS>' +\n'      <SRS>EPSG:2916</SRS>' +\n'      <SRS>EPSG:2917</SRS>' +\n'      <SRS>EPSG:2918</SRS>' +\n'      <SRS>EPSG:2919</SRS>' +\n'      <SRS>EPSG:2920</SRS>' +\n'      <SRS>EPSG:2921</SRS>' +\n'      <SRS>EPSG:2922</SRS>' +\n'      <SRS>EPSG:2923</SRS>' +\n'      <SRS>EPSG:2924</SRS>' +\n'      <SRS>EPSG:2925</SRS>' +\n'      <SRS>EPSG:2926</SRS>' +\n'      <SRS>EPSG:2927</SRS>' +\n'      <SRS>EPSG:2928</SRS>' +\n'      <SRS>EPSG:2929</SRS>' +\n'      <SRS>EPSG:2930</SRS>' +\n'      <SRS>EPSG:2931</SRS>' +\n'      <SRS>EPSG:2932</SRS>' +\n'      <SRS>EPSG:2933</SRS>' +\n'      <SRS>EPSG:2934</SRS>' +\n'      <SRS>EPSG:2935</SRS>' +\n'      <SRS>EPSG:2936</SRS>' +\n'      <SRS>EPSG:2937</SRS>' +\n'      <SRS>EPSG:2938</SRS>' +\n'      <SRS>EPSG:2939</SRS>' +\n'      <SRS>EPSG:2940</SRS>' +\n'      <SRS>EPSG:2941</SRS>' +\n'      <SRS>EPSG:2942</SRS>' +\n'      <SRS>EPSG:2943</SRS>' +\n'      <SRS>EPSG:2944</SRS>' +\n'      <SRS>EPSG:2945</SRS>' +\n'      <SRS>EPSG:2946</SRS>' +\n'      <SRS>EPSG:2947</SRS>' +\n'      <SRS>EPSG:2948</SRS>' +\n'      <SRS>EPSG:2949</SRS>' +\n'      <SRS>EPSG:2950</SRS>' +\n'      <SRS>EPSG:2951</SRS>' +\n'      <SRS>EPSG:2952</SRS>' +\n'      <SRS>EPSG:2953</SRS>' +\n'      <SRS>EPSG:2954</SRS>' +\n'      <SRS>EPSG:2955</SRS>' +\n'      <SRS>EPSG:2956</SRS>' +\n'      <SRS>EPSG:2957</SRS>' +\n'      <SRS>EPSG:2958</SRS>' +\n'      <SRS>EPSG:2959</SRS>' +\n'      <SRS>EPSG:2960</SRS>' +\n'      <SRS>EPSG:2961</SRS>' +\n'      <SRS>EPSG:2962</SRS>' +\n'      <SRS>EPSG:2963</SRS>' +\n'      <SRS>EPSG:2964</SRS>' +\n'      <SRS>EPSG:2965</SRS>' +\n'      <SRS>EPSG:2966</SRS>' +\n'      <SRS>EPSG:2967</SRS>' +\n'      <SRS>EPSG:2968</SRS>' +\n'      <SRS>EPSG:2969</SRS>' +\n'      <SRS>EPSG:2970</SRS>' +\n'      <SRS>EPSG:2971</SRS>' +\n'      <SRS>EPSG:2972</SRS>' +\n'      <SRS>EPSG:2973</SRS>' +\n'      <SRS>EPSG:2975</SRS>' +\n'      <SRS>EPSG:2976</SRS>' +\n'      <SRS>EPSG:2977</SRS>' +\n'      <SRS>EPSG:2978</SRS>' +\n'      <SRS>EPSG:2979</SRS>' +\n'      <SRS>EPSG:2980</SRS>' +\n'      <SRS>EPSG:2981</SRS>' +\n'      <SRS>EPSG:2982</SRS>' +\n'      <SRS>EPSG:2983</SRS>' +\n'      <SRS>EPSG:2984</SRS>' +\n'      <SRS>EPSG:2985</SRS>' +\n'      <SRS>EPSG:2986</SRS>' +\n'      <SRS>EPSG:2987</SRS>' +\n'      <SRS>EPSG:2988</SRS>' +\n'      <SRS>EPSG:2989</SRS>' +\n'      <SRS>EPSG:2990</SRS>' +\n'      <SRS>EPSG:2991</SRS>' +\n'      <SRS>EPSG:2992</SRS>' +\n'      <SRS>EPSG:2993</SRS>' +\n'      <SRS>EPSG:2994</SRS>' +\n'      <SRS>EPSG:2995</SRS>' +\n'      <SRS>EPSG:2996</SRS>' +\n'      <SRS>EPSG:2997</SRS>' +\n'      <SRS>EPSG:2998</SRS>' +\n'      <SRS>EPSG:2999</SRS>' +\n'      <SRS>EPSG:3000</SRS>' +\n'      <SRS>EPSG:3001</SRS>' +\n'      <SRS>EPSG:3002</SRS>' +\n'      <SRS>EPSG:3003</SRS>' +\n'      <SRS>EPSG:3004</SRS>' +\n'      <SRS>EPSG:3005</SRS>' +\n'      <SRS>EPSG:3006</SRS>' +\n'      <SRS>EPSG:3007</SRS>' +\n'      <SRS>EPSG:3008</SRS>' +\n'      <SRS>EPSG:3009</SRS>' +\n'      <SRS>EPSG:3010</SRS>' +\n'      <SRS>EPSG:3011</SRS>' +\n'      <SRS>EPSG:3012</SRS>' +\n'      <SRS>EPSG:3013</SRS>' +\n'      <SRS>EPSG:3014</SRS>' +\n'      <SRS>EPSG:3015</SRS>' +\n'      <SRS>EPSG:3016</SRS>' +\n'      <SRS>EPSG:3017</SRS>' +\n'      <SRS>EPSG:3018</SRS>' +\n'      <SRS>EPSG:3019</SRS>' +\n'      <SRS>EPSG:3020</SRS>' +\n'      <SRS>EPSG:3021</SRS>' +\n'      <SRS>EPSG:3022</SRS>' +\n'      <SRS>EPSG:3023</SRS>' +\n'      <SRS>EPSG:3024</SRS>' +\n'      <SRS>EPSG:3025</SRS>' +\n'      <SRS>EPSG:3026</SRS>' +\n'      <SRS>EPSG:3027</SRS>' +\n'      <SRS>EPSG:3028</SRS>' +\n'      <SRS>EPSG:3029</SRS>' +\n'      <SRS>EPSG:3030</SRS>' +\n'      <SRS>EPSG:3031</SRS>' +\n'      <SRS>EPSG:3032</SRS>' +\n'      <SRS>EPSG:3033</SRS>' +\n'      <SRS>EPSG:3034</SRS>' +\n'      <SRS>EPSG:3035</SRS>' +\n'      <SRS>EPSG:3036</SRS>' +\n'      <SRS>EPSG:3037</SRS>' +\n'      <SRS>EPSG:3038</SRS>' +\n'      <SRS>EPSG:3039</SRS>' +\n'      <SRS>EPSG:3040</SRS>' +\n'      <SRS>EPSG:3041</SRS>' +\n'      <SRS>EPSG:3042</SRS>' +\n'      <SRS>EPSG:3043</SRS>' +\n'      <SRS>EPSG:3044</SRS>' +\n'      <SRS>EPSG:3045</SRS>' +\n'      <SRS>EPSG:3046</SRS>' +\n'      <SRS>EPSG:3047</SRS>' +\n'      <SRS>EPSG:3048</SRS>' +\n'      <SRS>EPSG:3049</SRS>' +\n'      <SRS>EPSG:3050</SRS>' +\n'      <SRS>EPSG:3051</SRS>' +\n'      <SRS>EPSG:3052</SRS>' +\n'      <SRS>EPSG:3053</SRS>' +\n'      <SRS>EPSG:3054</SRS>' +\n'      <SRS>EPSG:3055</SRS>' +\n'      <SRS>EPSG:3056</SRS>' +\n'      <SRS>EPSG:3057</SRS>' +\n'      <SRS>EPSG:3058</SRS>' +\n'      <SRS>EPSG:3059</SRS>' +\n'      <SRS>EPSG:3060</SRS>' +\n'      <SRS>EPSG:3061</SRS>' +\n'      <SRS>EPSG:3062</SRS>' +\n'      <SRS>EPSG:3063</SRS>' +\n'      <SRS>EPSG:3064</SRS>' +\n'      <SRS>EPSG:3065</SRS>' +\n'      <SRS>EPSG:3066</SRS>' +\n'      <SRS>EPSG:3067</SRS>' +\n'      <SRS>EPSG:3068</SRS>' +\n'      <SRS>EPSG:3069</SRS>' +\n'      <SRS>EPSG:3070</SRS>' +\n'      <SRS>EPSG:3071</SRS>' +\n'      <SRS>EPSG:3072</SRS>' +\n'      <SRS>EPSG:3073</SRS>' +\n'      <SRS>EPSG:3074</SRS>' +\n'      <SRS>EPSG:3075</SRS>' +\n'      <SRS>EPSG:3076</SRS>' +\n'      <SRS>EPSG:3077</SRS>' +\n'      <SRS>EPSG:3078</SRS>' +\n'      <SRS>EPSG:3079</SRS>' +\n'      <SRS>EPSG:3080</SRS>' +\n'      <SRS>EPSG:3081</SRS>' +\n'      <SRS>EPSG:3082</SRS>' +\n'      <SRS>EPSG:3083</SRS>' +\n'      <SRS>EPSG:3084</SRS>' +\n'      <SRS>EPSG:3085</SRS>' +\n'      <SRS>EPSG:3086</SRS>' +\n'      <SRS>EPSG:3087</SRS>' +\n'      <SRS>EPSG:3088</SRS>' +\n'      <SRS>EPSG:3089</SRS>' +\n'      <SRS>EPSG:3090</SRS>' +\n'      <SRS>EPSG:3091</SRS>' +\n'      <SRS>EPSG:3092</SRS>' +\n'      <SRS>EPSG:3093</SRS>' +\n'      <SRS>EPSG:3094</SRS>' +\n'      <SRS>EPSG:3095</SRS>' +\n'      <SRS>EPSG:3096</SRS>' +\n'      <SRS>EPSG:3097</SRS>' +\n'      <SRS>EPSG:3098</SRS>' +\n'      <SRS>EPSG:3099</SRS>' +\n'      <SRS>EPSG:3100</SRS>' +\n'      <SRS>EPSG:3101</SRS>' +\n'      <SRS>EPSG:3102</SRS>' +\n'      <SRS>EPSG:3103</SRS>' +\n'      <SRS>EPSG:3104</SRS>' +\n'      <SRS>EPSG:3105</SRS>' +\n'      <SRS>EPSG:3106</SRS>' +\n'      <SRS>EPSG:3107</SRS>' +\n'      <SRS>EPSG:3108</SRS>' +\n'      <SRS>EPSG:3109</SRS>' +\n'      <SRS>EPSG:3110</SRS>' +\n'      <SRS>EPSG:3111</SRS>' +\n'      <SRS>EPSG:3112</SRS>' +\n'      <SRS>EPSG:3113</SRS>' +\n'      <SRS>EPSG:3114</SRS>' +\n'      <SRS>EPSG:3115</SRS>' +\n'      <SRS>EPSG:3116</SRS>' +\n'      <SRS>EPSG:3117</SRS>' +\n'      <SRS>EPSG:3118</SRS>' +\n'      <SRS>EPSG:3119</SRS>' +\n'      <SRS>EPSG:3120</SRS>' +\n'      <SRS>EPSG:3121</SRS>' +\n'      <SRS>EPSG:3122</SRS>' +\n'      <SRS>EPSG:3123</SRS>' +\n'      <SRS>EPSG:3124</SRS>' +\n'      <SRS>EPSG:3125</SRS>' +\n'      <SRS>EPSG:3126</SRS>' +\n'      <SRS>EPSG:3127</SRS>' +\n'      <SRS>EPSG:3128</SRS>' +\n'      <SRS>EPSG:3129</SRS>' +\n'      <SRS>EPSG:3130</SRS>' +\n'      <SRS>EPSG:3131</SRS>' +\n'      <SRS>EPSG:3132</SRS>' +\n'      <SRS>EPSG:3133</SRS>' +\n'      <SRS>EPSG:3134</SRS>' +\n'      <SRS>EPSG:3135</SRS>' +\n'      <SRS>EPSG:3136</SRS>' +\n'      <SRS>EPSG:3137</SRS>' +\n'      <SRS>EPSG:3138</SRS>' +\n'      <SRS>EPSG:3139</SRS>' +\n'      <SRS>EPSG:3140</SRS>' +\n'      <SRS>EPSG:3141</SRS>' +\n'      <SRS>EPSG:3142</SRS>' +\n'      <SRS>EPSG:3143</SRS>' +\n'      <SRS>EPSG:3144</SRS>' +\n'      <SRS>EPSG:3145</SRS>' +\n'      <SRS>EPSG:3146</SRS>' +\n'      <SRS>EPSG:3147</SRS>' +\n'      <SRS>EPSG:3148</SRS>' +\n'      <SRS>EPSG:3149</SRS>' +\n'      <SRS>EPSG:3150</SRS>' +\n'      <SRS>EPSG:3151</SRS>' +\n'      <SRS>EPSG:3152</SRS>' +\n'      <SRS>EPSG:3153</SRS>' +\n'      <SRS>EPSG:3154</SRS>' +\n'      <SRS>EPSG:3155</SRS>' +\n'      <SRS>EPSG:3156</SRS>' +\n'      <SRS>EPSG:3157</SRS>' +\n'      <SRS>EPSG:3158</SRS>' +\n'      <SRS>EPSG:3159</SRS>' +\n'      <SRS>EPSG:3160</SRS>' +\n'      <SRS>EPSG:3161</SRS>' +\n'      <SRS>EPSG:3162</SRS>' +\n'      <SRS>EPSG:3163</SRS>' +\n'      <SRS>EPSG:3164</SRS>' +\n'      <SRS>EPSG:3165</SRS>' +\n'      <SRS>EPSG:3166</SRS>' +\n'      <SRS>EPSG:3167</SRS>' +\n'      <SRS>EPSG:3168</SRS>' +\n'      <SRS>EPSG:3169</SRS>' +\n'      <SRS>EPSG:3170</SRS>' +\n'      <SRS>EPSG:3171</SRS>' +\n'      <SRS>EPSG:3172</SRS>' +\n'      <SRS>EPSG:3173</SRS>' +\n'      <SRS>EPSG:3174</SRS>' +\n'      <SRS>EPSG:3175</SRS>' +\n'      <SRS>EPSG:3176</SRS>' +\n'      <SRS>EPSG:3177</SRS>' +\n'      <SRS>EPSG:3178</SRS>' +\n'      <SRS>EPSG:3179</SRS>' +\n'      <SRS>EPSG:3180</SRS>' +\n'      <SRS>EPSG:3181</SRS>' +\n'      <SRS>EPSG:3182</SRS>' +\n'      <SRS>EPSG:3183</SRS>' +\n'      <SRS>EPSG:3184</SRS>' +\n'      <SRS>EPSG:3185</SRS>' +\n'      <SRS>EPSG:3186</SRS>' +\n'      <SRS>EPSG:3187</SRS>' +\n'      <SRS>EPSG:3188</SRS>' +\n'      <SRS>EPSG:3189</SRS>' +\n'      <SRS>EPSG:3190</SRS>' +\n'      <SRS>EPSG:3191</SRS>' +\n'      <SRS>EPSG:3192</SRS>' +\n'      <SRS>EPSG:3193</SRS>' +\n'      <SRS>EPSG:3194</SRS>' +\n'      <SRS>EPSG:3195</SRS>' +\n'      <SRS>EPSG:3196</SRS>' +\n'      <SRS>EPSG:3197</SRS>' +\n'      <SRS>EPSG:3198</SRS>' +\n'      <SRS>EPSG:3199</SRS>' +\n'      <SRS>EPSG:3200</SRS>' +\n'      <SRS>EPSG:3201</SRS>' +\n'      <SRS>EPSG:3202</SRS>' +\n'      <SRS>EPSG:3203</SRS>' +\n'      <SRS>EPSG:3204</SRS>' +\n'      <SRS>EPSG:3205</SRS>' +\n'      <SRS>EPSG:3206</SRS>' +\n'      <SRS>EPSG:3207</SRS>' +\n'      <SRS>EPSG:3208</SRS>' +\n'      <SRS>EPSG:3209</SRS>' +\n'      <SRS>EPSG:3210</SRS>' +\n'      <SRS>EPSG:3211</SRS>' +\n'      <SRS>EPSG:3212</SRS>' +\n'      <SRS>EPSG:3213</SRS>' +\n'      <SRS>EPSG:3214</SRS>' +\n'      <SRS>EPSG:3215</SRS>' +\n'      <SRS>EPSG:3216</SRS>' +\n'      <SRS>EPSG:3217</SRS>' +\n'      <SRS>EPSG:3218</SRS>' +\n'      <SRS>EPSG:3219</SRS>' +\n'      <SRS>EPSG:3220</SRS>' +\n'      <SRS>EPSG:3221</SRS>' +\n'      <SRS>EPSG:3222</SRS>' +\n'      <SRS>EPSG:3223</SRS>' +\n'      <SRS>EPSG:3224</SRS>' +\n'      <SRS>EPSG:3225</SRS>' +\n'      <SRS>EPSG:3226</SRS>' +\n'      <SRS>EPSG:3227</SRS>' +\n'      <SRS>EPSG:3228</SRS>' +\n'      <SRS>EPSG:3229</SRS>' +\n'      <SRS>EPSG:3230</SRS>' +\n'      <SRS>EPSG:3231</SRS>' +\n'      <SRS>EPSG:3232</SRS>' +\n'      <SRS>EPSG:3233</SRS>' +\n'      <SRS>EPSG:3234</SRS>' +\n'      <SRS>EPSG:3235</SRS>' +\n'      <SRS>EPSG:3236</SRS>' +\n'      <SRS>EPSG:3237</SRS>' +\n'      <SRS>EPSG:3238</SRS>' +\n'      <SRS>EPSG:3239</SRS>' +\n'      <SRS>EPSG:3240</SRS>' +\n'      <SRS>EPSG:3241</SRS>' +\n'      <SRS>EPSG:3242</SRS>' +\n'      <SRS>EPSG:3243</SRS>' +\n'      <SRS>EPSG:3244</SRS>' +\n'      <SRS>EPSG:3245</SRS>' +\n'      <SRS>EPSG:3246</SRS>' +\n'      <SRS>EPSG:3247</SRS>' +\n'      <SRS>EPSG:3248</SRS>' +\n'      <SRS>EPSG:3249</SRS>' +\n'      <SRS>EPSG:3250</SRS>' +\n'      <SRS>EPSG:3251</SRS>' +\n'      <SRS>EPSG:3252</SRS>' +\n'      <SRS>EPSG:3253</SRS>' +\n'      <SRS>EPSG:3254</SRS>' +\n'      <SRS>EPSG:3255</SRS>' +\n'      <SRS>EPSG:3256</SRS>' +\n'      <SRS>EPSG:3257</SRS>' +\n'      <SRS>EPSG:3258</SRS>' +\n'      <SRS>EPSG:3259</SRS>' +\n'      <SRS>EPSG:3260</SRS>' +\n'      <SRS>EPSG:3261</SRS>' +\n'      <SRS>EPSG:3262</SRS>' +\n'      <SRS>EPSG:3263</SRS>' +\n'      <SRS>EPSG:3264</SRS>' +\n'      <SRS>EPSG:3265</SRS>' +\n'      <SRS>EPSG:3266</SRS>' +\n'      <SRS>EPSG:3267</SRS>' +\n'      <SRS>EPSG:3268</SRS>' +\n'      <SRS>EPSG:3269</SRS>' +\n'      <SRS>EPSG:3270</SRS>' +\n'      <SRS>EPSG:3271</SRS>' +\n'      <SRS>EPSG:3272</SRS>' +\n'      <SRS>EPSG:3273</SRS>' +\n'      <SRS>EPSG:3274</SRS>' +\n'      <SRS>EPSG:3275</SRS>' +\n'      <SRS>EPSG:3276</SRS>' +\n'      <SRS>EPSG:3277</SRS>' +\n'      <SRS>EPSG:3278</SRS>' +\n'      <SRS>EPSG:3279</SRS>' +\n'      <SRS>EPSG:3280</SRS>' +\n'      <SRS>EPSG:3281</SRS>' +\n'      <SRS>EPSG:3282</SRS>' +\n'      <SRS>EPSG:3283</SRS>' +\n'      <SRS>EPSG:3284</SRS>' +\n'      <SRS>EPSG:3285</SRS>' +\n'      <SRS>EPSG:3286</SRS>' +\n'      <SRS>EPSG:3287</SRS>' +\n'      <SRS>EPSG:3288</SRS>' +\n'      <SRS>EPSG:3289</SRS>' +\n'      <SRS>EPSG:3290</SRS>' +\n'      <SRS>EPSG:3291</SRS>' +\n'      <SRS>EPSG:3292</SRS>' +\n'      <SRS>EPSG:3293</SRS>' +\n'      <SRS>EPSG:3294</SRS>' +\n'      <SRS>EPSG:3295</SRS>' +\n'      <SRS>EPSG:3296</SRS>' +\n'      <SRS>EPSG:3297</SRS>' +\n'      <SRS>EPSG:3298</SRS>' +\n'      <SRS>EPSG:3299</SRS>' +\n'      <SRS>EPSG:3300</SRS>' +\n'      <SRS>EPSG:3301</SRS>' +\n'      <SRS>EPSG:3302</SRS>' +\n'      <SRS>EPSG:3303</SRS>' +\n'      <SRS>EPSG:3304</SRS>' +\n'      <SRS>EPSG:3305</SRS>' +\n'      <SRS>EPSG:3306</SRS>' +\n'      <SRS>EPSG:3307</SRS>' +\n'      <SRS>EPSG:3308</SRS>' +\n'      <SRS>EPSG:3309</SRS>' +\n'      <SRS>EPSG:3310</SRS>' +\n'      <SRS>EPSG:3311</SRS>' +\n'      <SRS>EPSG:3312</SRS>' +\n'      <SRS>EPSG:3313</SRS>' +\n'      <SRS>EPSG:3314</SRS>' +\n'      <SRS>EPSG:3315</SRS>' +\n'      <SRS>EPSG:3316</SRS>' +\n'      <SRS>EPSG:3317</SRS>' +\n'      <SRS>EPSG:3318</SRS>' +\n'      <SRS>EPSG:3319</SRS>' +\n'      <SRS>EPSG:3320</SRS>' +\n'      <SRS>EPSG:3321</SRS>' +\n'      <SRS>EPSG:3322</SRS>' +\n'      <SRS>EPSG:3323</SRS>' +\n'      <SRS>EPSG:3324</SRS>' +\n'      <SRS>EPSG:3325</SRS>' +\n'      <SRS>EPSG:3326</SRS>' +\n'      <SRS>EPSG:3327</SRS>' +\n'      <SRS>EPSG:3328</SRS>' +\n'      <SRS>EPSG:3329</SRS>' +\n'      <SRS>EPSG:3330</SRS>' +\n'      <SRS>EPSG:3331</SRS>' +\n'      <SRS>EPSG:3332</SRS>' +\n'      <SRS>EPSG:3333</SRS>' +\n'      <SRS>EPSG:3334</SRS>' +\n'      <SRS>EPSG:3335</SRS>' +\n'      <SRS>EPSG:3336</SRS>' +\n'      <SRS>EPSG:3337</SRS>' +\n'      <SRS>EPSG:3338</SRS>' +\n'      <SRS>EPSG:3339</SRS>' +\n'      <SRS>EPSG:3340</SRS>' +\n'      <SRS>EPSG:3341</SRS>' +\n'      <SRS>EPSG:3342</SRS>' +\n'      <SRS>EPSG:3343</SRS>' +\n'      <SRS>EPSG:3344</SRS>' +\n'      <SRS>EPSG:3345</SRS>' +\n'      <SRS>EPSG:3346</SRS>' +\n'      <SRS>EPSG:3347</SRS>' +\n'      <SRS>EPSG:3348</SRS>' +\n'      <SRS>EPSG:3349</SRS>' +\n'      <SRS>EPSG:3350</SRS>' +\n'      <SRS>EPSG:3351</SRS>' +\n'      <SRS>EPSG:3352</SRS>' +\n'      <SRS>EPSG:3353</SRS>' +\n'      <SRS>EPSG:3354</SRS>' +\n'      <SRS>EPSG:3355</SRS>' +\n'      <SRS>EPSG:3356</SRS>' +\n'      <SRS>EPSG:3357</SRS>' +\n'      <SRS>EPSG:3358</SRS>' +\n'      <SRS>EPSG:3359</SRS>' +\n'      <SRS>EPSG:3360</SRS>' +\n'      <SRS>EPSG:3361</SRS>' +\n'      <SRS>EPSG:3362</SRS>' +\n'      <SRS>EPSG:3363</SRS>' +\n'      <SRS>EPSG:3364</SRS>' +\n'      <SRS>EPSG:3365</SRS>' +\n'      <SRS>EPSG:3366</SRS>' +\n'      <SRS>EPSG:3367</SRS>' +\n'      <SRS>EPSG:3368</SRS>' +\n'      <SRS>EPSG:3369</SRS>' +\n'      <SRS>EPSG:3370</SRS>' +\n'      <SRS>EPSG:3371</SRS>' +\n'      <SRS>EPSG:3372</SRS>' +\n'      <SRS>EPSG:3373</SRS>' +\n'      <SRS>EPSG:3374</SRS>' +\n'      <SRS>EPSG:3375</SRS>' +\n'      <SRS>EPSG:3376</SRS>' +\n'      <SRS>EPSG:3377</SRS>' +\n'      <SRS>EPSG:3378</SRS>' +\n'      <SRS>EPSG:3379</SRS>' +\n'      <SRS>EPSG:3380</SRS>' +\n'      <SRS>EPSG:3381</SRS>' +\n'      <SRS>EPSG:3382</SRS>' +\n'      <SRS>EPSG:3383</SRS>' +\n'      <SRS>EPSG:3384</SRS>' +\n'      <SRS>EPSG:3385</SRS>' +\n'      <SRS>EPSG:3386</SRS>' +\n'      <SRS>EPSG:3387</SRS>' +\n'      <SRS>EPSG:3388</SRS>' +\n'      <SRS>EPSG:3389</SRS>' +\n'      <SRS>EPSG:3390</SRS>' +\n'      <SRS>EPSG:3391</SRS>' +\n'      <SRS>EPSG:3392</SRS>' +\n'      <SRS>EPSG:3393</SRS>' +\n'      <SRS>EPSG:3394</SRS>' +\n'      <SRS>EPSG:3395</SRS>' +\n'      <SRS>EPSG:3396</SRS>' +\n'      <SRS>EPSG:3397</SRS>' +\n'      <SRS>EPSG:3398</SRS>' +\n'      <SRS>EPSG:3399</SRS>' +\n'      <SRS>EPSG:3400</SRS>' +\n'      <SRS>EPSG:3401</SRS>' +\n'      <SRS>EPSG:3402</SRS>' +\n'      <SRS>EPSG:3403</SRS>' +\n'      <SRS>EPSG:3404</SRS>' +\n'      <SRS>EPSG:3405</SRS>' +\n'      <SRS>EPSG:3406</SRS>' +\n'      <SRS>EPSG:3407</SRS>' +\n'      <SRS>EPSG:3408</SRS>' +\n'      <SRS>EPSG:3409</SRS>' +\n'      <SRS>EPSG:3410</SRS>' +\n'      <SRS>EPSG:3411</SRS>' +\n'      <SRS>EPSG:3412</SRS>' +\n'      <SRS>EPSG:3413</SRS>' +\n'      <SRS>EPSG:3414</SRS>' +\n'      <SRS>EPSG:3415</SRS>' +\n'      <SRS>EPSG:3416</SRS>' +\n'      <SRS>EPSG:3417</SRS>' +\n'      <SRS>EPSG:3418</SRS>' +\n'      <SRS>EPSG:3419</SRS>' +\n'      <SRS>EPSG:3420</SRS>' +\n'      <SRS>EPSG:3421</SRS>' +\n'      <SRS>EPSG:3422</SRS>' +\n'      <SRS>EPSG:3423</SRS>' +\n'      <SRS>EPSG:3424</SRS>' +\n'      <SRS>EPSG:3425</SRS>' +\n'      <SRS>EPSG:3426</SRS>' +\n'      <SRS>EPSG:3427</SRS>' +\n'      <SRS>EPSG:3428</SRS>' +\n'      <SRS>EPSG:3429</SRS>' +\n'      <SRS>EPSG:3430</SRS>' +\n'      <SRS>EPSG:3431</SRS>' +\n'      <SRS>EPSG:3432</SRS>' +\n'      <SRS>EPSG:3433</SRS>' +\n'      <SRS>EPSG:3434</SRS>' +\n'      <SRS>EPSG:3435</SRS>' +\n'      <SRS>EPSG:3436</SRS>' +\n'      <SRS>EPSG:3437</SRS>' +\n'      <SRS>EPSG:3438</SRS>' +\n'      <SRS>EPSG:3439</SRS>' +\n'      <SRS>EPSG:3440</SRS>' +\n'      <SRS>EPSG:3441</SRS>' +\n'      <SRS>EPSG:3442</SRS>' +\n'      <SRS>EPSG:3443</SRS>' +\n'      <SRS>EPSG:3444</SRS>' +\n'      <SRS>EPSG:3445</SRS>' +\n'      <SRS>EPSG:3446</SRS>' +\n'      <SRS>EPSG:3447</SRS>' +\n'      <SRS>EPSG:3448</SRS>' +\n'      <SRS>EPSG:3449</SRS>' +\n'      <SRS>EPSG:3450</SRS>' +\n'      <SRS>EPSG:3451</SRS>' +\n'      <SRS>EPSG:3452</SRS>' +\n'      <SRS>EPSG:3453</SRS>' +\n'      <SRS>EPSG:3454</SRS>' +\n'      <SRS>EPSG:3455</SRS>' +\n'      <SRS>EPSG:3456</SRS>' +\n'      <SRS>EPSG:3457</SRS>' +\n'      <SRS>EPSG:3458</SRS>' +\n'      <SRS>EPSG:3459</SRS>' +\n'      <SRS>EPSG:3460</SRS>' +\n'      <SRS>EPSG:3461</SRS>' +\n'      <SRS>EPSG:3462</SRS>' +\n'      <SRS>EPSG:3463</SRS>' +\n'      <SRS>EPSG:3464</SRS>' +\n'      <SRS>EPSG:3560</SRS>' +\n'      <SRS>EPSG:3561</SRS>' +\n'      <SRS>EPSG:3562</SRS>' +\n'      <SRS>EPSG:3563</SRS>' +\n'      <SRS>EPSG:3564</SRS>' +\n'      <SRS>EPSG:3565</SRS>' +\n'      <SRS>EPSG:3566</SRS>' +\n'      <SRS>EPSG:3567</SRS>' +\n'      <SRS>EPSG:3568</SRS>' +\n'      <SRS>EPSG:3569</SRS>' +\n'      <SRS>EPSG:3570</SRS>' +\n'      <SRS>EPSG:3571</SRS>' +\n'      <SRS>EPSG:3572</SRS>' +\n'      <SRS>EPSG:3573</SRS>' +\n'      <SRS>EPSG:3574</SRS>' +\n'      <SRS>EPSG:3575</SRS>' +\n'      <SRS>EPSG:3576</SRS>' +\n'      <SRS>EPSG:3577</SRS>' +\n'      <SRS>EPSG:3920</SRS>' +\n'      <SRS>EPSG:3991</SRS>' +\n'      <SRS>EPSG:3992</SRS>' +\n'      <SRS>EPSG:3993</SRS>' +\n'      <SRS>EPSG:4001</SRS>' +\n'      <SRS>EPSG:4002</SRS>' +\n'      <SRS>EPSG:4003</SRS>' +\n'      <SRS>EPSG:4004</SRS>' +\n'      <SRS>EPSG:4005</SRS>' +\n'      <SRS>EPSG:4006</SRS>' +\n'      <SRS>EPSG:4007</SRS>' +\n'      <SRS>EPSG:4008</SRS>' +\n'      <SRS>EPSG:4009</SRS>' +\n'      <SRS>EPSG:4010</SRS>' +\n'      <SRS>EPSG:4011</SRS>' +\n'      <SRS>EPSG:4012</SRS>' +\n'      <SRS>EPSG:4013</SRS>' +\n'      <SRS>EPSG:4014</SRS>' +\n'      <SRS>EPSG:4015</SRS>' +\n'      <SRS>EPSG:4016</SRS>' +\n'      <SRS>EPSG:4018</SRS>' +\n'      <SRS>EPSG:4019</SRS>' +\n'      <SRS>EPSG:4020</SRS>' +\n'      <SRS>EPSG:4021</SRS>' +\n'      <SRS>EPSG:4022</SRS>' +\n'      <SRS>EPSG:4024</SRS>' +\n'      <SRS>EPSG:4025</SRS>' +\n'      <SRS>EPSG:4027</SRS>' +\n'      <SRS>EPSG:4028</SRS>' +\n'      <SRS>EPSG:4029</SRS>' +\n'      <SRS>EPSG:4030</SRS>' +\n'      <SRS>EPSG:4031</SRS>' +\n'      <SRS>EPSG:4032</SRS>' +\n'      <SRS>EPSG:4033</SRS>' +\n'      <SRS>EPSG:4034</SRS>' +\n'      <SRS>EPSG:4035</SRS>' +\n'      <SRS>EPSG:4036</SRS>' +\n'      <SRS>EPSG:4041</SRS>' +\n'      <SRS>EPSG:4042</SRS>' +\n'      <SRS>EPSG:4043</SRS>' +\n'      <SRS>EPSG:4044</SRS>' +\n'      <SRS>EPSG:4045</SRS>' +\n'      <SRS>EPSG:4047</SRS>' +\n'      <SRS>EPSG:4052</SRS>' +\n'      <SRS>EPSG:4053</SRS>' +\n'      <SRS>EPSG:4054</SRS>' +\n'      <SRS>EPSG:4120</SRS>' +\n'      <SRS>EPSG:4121</SRS>' +\n'      <SRS>EPSG:4122</SRS>' +\n'      <SRS>EPSG:4123</SRS>' +\n'      <SRS>EPSG:4124</SRS>' +\n'      <SRS>EPSG:4125</SRS>' +\n'      <SRS>EPSG:4126</SRS>' +\n'      <SRS>EPSG:4127</SRS>' +\n'      <SRS>EPSG:4128</SRS>' +\n'      <SRS>EPSG:4129</SRS>' +\n'      <SRS>EPSG:4130</SRS>' +\n'      <SRS>EPSG:4131</SRS>' +\n'      <SRS>EPSG:4132</SRS>' +\n'      <SRS>EPSG:4133</SRS>' +\n'      <SRS>EPSG:4134</SRS>' +\n'      <SRS>EPSG:4135</SRS>' +\n'      <SRS>EPSG:4136</SRS>' +\n'      <SRS>EPSG:4137</SRS>' +\n'      <SRS>EPSG:4138</SRS>' +\n'      <SRS>EPSG:4139</SRS>' +\n'      <SRS>EPSG:4140</SRS>' +\n'      <SRS>EPSG:4141</SRS>' +\n'      <SRS>EPSG:4142</SRS>' +\n'      <SRS>EPSG:4143</SRS>' +\n'      <SRS>EPSG:4144</SRS>' +\n'      <SRS>EPSG:4145</SRS>' +\n'      <SRS>EPSG:4146</SRS>' +\n'      <SRS>EPSG:4147</SRS>' +\n'      <SRS>EPSG:4148</SRS>' +\n'      <SRS>EPSG:4149</SRS>' +\n'      <SRS>EPSG:4150</SRS>' +\n'      <SRS>EPSG:4151</SRS>' +\n'      <SRS>EPSG:4152</SRS>' +\n'      <SRS>EPSG:4153</SRS>' +\n'      <SRS>EPSG:4154</SRS>' +\n'      <SRS>EPSG:4155</SRS>' +\n'      <SRS>EPSG:4156</SRS>' +\n'      <SRS>EPSG:4157</SRS>' +\n'      <SRS>EPSG:4158</SRS>' +\n'      <SRS>EPSG:4159</SRS>' +\n'      <SRS>EPSG:4160</SRS>' +\n'      <SRS>EPSG:4161</SRS>' +\n'      <SRS>EPSG:4162</SRS>' +\n'      <SRS>EPSG:4163</SRS>' +\n'      <SRS>EPSG:4164</SRS>' +\n'      <SRS>EPSG:4165</SRS>' +\n'      <SRS>EPSG:4166</SRS>' +\n'      <SRS>EPSG:4167</SRS>' +\n'      <SRS>EPSG:4168</SRS>' +\n'      <SRS>EPSG:4169</SRS>' +\n'      <SRS>EPSG:4170</SRS>' +\n'      <SRS>EPSG:4171</SRS>' +\n'      <SRS>EPSG:4172</SRS>' +\n'      <SRS>EPSG:4173</SRS>' +\n'      <SRS>EPSG:4174</SRS>' +\n'      <SRS>EPSG:4175</SRS>' +\n'      <SRS>EPSG:4176</SRS>' +\n'      <SRS>EPSG:4178</SRS>' +\n'      <SRS>EPSG:4179</SRS>' +\n'      <SRS>EPSG:4180</SRS>' +\n'      <SRS>EPSG:4181</SRS>' +\n'      <SRS>EPSG:4182</SRS>' +\n'      <SRS>EPSG:4183</SRS>' +\n'      <SRS>EPSG:4184</SRS>' +\n'      <SRS>EPSG:4185</SRS>' +\n'      <SRS>EPSG:4188</SRS>' +\n'      <SRS>EPSG:4189</SRS>' +\n'      <SRS>EPSG:4190</SRS>' +\n'      <SRS>EPSG:4191</SRS>' +\n'      <SRS>EPSG:4192</SRS>' +\n'      <SRS>EPSG:4193</SRS>' +\n'      <SRS>EPSG:4194</SRS>' +\n'      <SRS>EPSG:4195</SRS>' +\n'      <SRS>EPSG:4196</SRS>' +\n'      <SRS>EPSG:4197</SRS>' +\n'      <SRS>EPSG:4198</SRS>' +\n'      <SRS>EPSG:4199</SRS>' +\n'      <SRS>EPSG:4200</SRS>' +\n'      <SRS>EPSG:4201</SRS>' +\n'      <SRS>EPSG:4202</SRS>' +\n'      <SRS>EPSG:4203</SRS>' +\n'      <SRS>EPSG:4204</SRS>' +\n'      <SRS>EPSG:4205</SRS>' +\n'      <SRS>EPSG:4206</SRS>' +\n'      <SRS>EPSG:4207</SRS>' +\n'      <SRS>EPSG:4208</SRS>' +\n'      <SRS>EPSG:4209</SRS>' +\n'      <SRS>EPSG:4210</SRS>' +\n'      <SRS>EPSG:4211</SRS>' +\n'      <SRS>EPSG:4212</SRS>' +\n'      <SRS>EPSG:4213</SRS>' +\n'      <SRS>EPSG:4214</SRS>' +\n'      <SRS>EPSG:4215</SRS>' +\n'      <SRS>EPSG:4216</SRS>' +\n'      <SRS>EPSG:4218</SRS>' +\n'      <SRS>EPSG:4219</SRS>' +\n'      <SRS>EPSG:4220</SRS>' +\n'      <SRS>EPSG:4221</SRS>' +\n'      <SRS>EPSG:4222</SRS>' +\n'      <SRS>EPSG:4223</SRS>' +\n'      <SRS>EPSG:4224</SRS>' +\n'      <SRS>EPSG:4225</SRS>' +\n'      <SRS>EPSG:4226</SRS>' +\n'      <SRS>EPSG:4227</SRS>' +\n'      <SRS>EPSG:4228</SRS>' +\n'      <SRS>EPSG:4229</SRS>' +\n'      <SRS>EPSG:4230</SRS>' +\n'      <SRS>EPSG:4231</SRS>' +\n'      <SRS>EPSG:4232</SRS>' +\n'      <SRS>EPSG:4233</SRS>' +\n'      <SRS>EPSG:4234</SRS>' +\n'      <SRS>EPSG:4235</SRS>' +\n'      <SRS>EPSG:4236</SRS>' +\n'      <SRS>EPSG:4237</SRS>' +\n'      <SRS>EPSG:4238</SRS>' +\n'      <SRS>EPSG:4239</SRS>' +\n'      <SRS>EPSG:4240</SRS>' +\n'      <SRS>EPSG:4241</SRS>' +\n'      <SRS>EPSG:4242</SRS>' +\n'      <SRS>EPSG:4243</SRS>' +\n'      <SRS>EPSG:4244</SRS>' +\n'      <SRS>EPSG:4245</SRS>' +\n'      <SRS>EPSG:4246</SRS>' +\n'      <SRS>EPSG:4247</SRS>' +\n'      <SRS>EPSG:4248</SRS>' +\n'      <SRS>EPSG:4249</SRS>' +\n'      <SRS>EPSG:4250</SRS>' +\n'      <SRS>EPSG:4251</SRS>' +\n'      <SRS>EPSG:4252</SRS>' +\n'      <SRS>EPSG:4253</SRS>' +\n'      <SRS>EPSG:4254</SRS>' +\n'      <SRS>EPSG:4255</SRS>' +\n'      <SRS>EPSG:4256</SRS>' +\n'      <SRS>EPSG:4257</SRS>' +\n'      <SRS>EPSG:4258</SRS>' +\n'      <SRS>EPSG:4259</SRS>' +\n'      <SRS>EPSG:4260</SRS>' +\n'      <SRS>EPSG:4261</SRS>' +\n'      <SRS>EPSG:4262</SRS>' +\n'      <SRS>EPSG:4263</SRS>' +\n'      <SRS>EPSG:4264</SRS>' +\n'      <SRS>EPSG:4265</SRS>' +\n'      <SRS>EPSG:4266</SRS>' +\n'      <SRS>EPSG:4267</SRS>' +\n'      <SRS>EPSG:4268</SRS>' +\n'      <SRS>EPSG:4269</SRS>' +\n'      <SRS>EPSG:4270</SRS>' +\n'      <SRS>EPSG:4271</SRS>' +\n'      <SRS>EPSG:4272</SRS>' +\n'      <SRS>EPSG:4273</SRS>' +\n'      <SRS>EPSG:4274</SRS>' +\n'      <SRS>EPSG:4275</SRS>' +\n'      <SRS>EPSG:4276</SRS>' +\n'      <SRS>EPSG:4277</SRS>' +\n'      <SRS>EPSG:4278</SRS>' +\n'      <SRS>EPSG:4279</SRS>' +\n'      <SRS>EPSG:4280</SRS>' +\n'      <SRS>EPSG:4281</SRS>' +\n'      <SRS>EPSG:4282</SRS>' +\n'      <SRS>EPSG:4283</SRS>' +\n'      <SRS>EPSG:4284</SRS>' +\n'      <SRS>EPSG:4285</SRS>' +\n'      <SRS>EPSG:4286</SRS>' +\n'      <SRS>EPSG:4287</SRS>' +\n'      <SRS>EPSG:4288</SRS>' +\n'      <SRS>EPSG:4289</SRS>' +\n'      <SRS>EPSG:4291</SRS>' +\n'      <SRS>EPSG:4292</SRS>' +\n'      <SRS>EPSG:4293</SRS>' +\n'      <SRS>EPSG:4294</SRS>' +\n'      <SRS>EPSG:4295</SRS>' +\n'      <SRS>EPSG:4296</SRS>' +\n'      <SRS>EPSG:4297</SRS>' +\n'      <SRS>EPSG:4298</SRS>' +\n'      <SRS>EPSG:4299</SRS>' +\n'      <SRS>EPSG:4300</SRS>' +\n'      <SRS>EPSG:4301</SRS>' +\n'      <SRS>EPSG:4302</SRS>' +\n'      <SRS>EPSG:4303</SRS>' +\n'      <SRS>EPSG:4304</SRS>' +\n'      <SRS>EPSG:4306</SRS>' +\n'      <SRS>EPSG:4307</SRS>' +\n'      <SRS>EPSG:4308</SRS>' +\n'      <SRS>EPSG:4309</SRS>' +\n'      <SRS>EPSG:4310</SRS>' +\n'      <SRS>EPSG:4311</SRS>' +\n'      <SRS>EPSG:4312</SRS>' +\n'      <SRS>EPSG:4313</SRS>' +\n'      <SRS>EPSG:4314</SRS>' +\n'      <SRS>EPSG:4315</SRS>' +\n'      <SRS>EPSG:4316</SRS>' +\n'      <SRS>EPSG:4317</SRS>' +\n'      <SRS>EPSG:4318</SRS>' +\n'      <SRS>EPSG:4319</SRS>' +\n'      <SRS>EPSG:4322</SRS>' +\n'      <SRS>EPSG:4324</SRS>' +\n'      <SRS>EPSG:4326</SRS>' +\n'      <SRS>EPSG:4327</SRS>' +\n'      <SRS>EPSG:4328</SRS>' +\n'      <SRS>EPSG:4329</SRS>' +\n'      <SRS>EPSG:4330</SRS>' +\n'      <SRS>EPSG:4331</SRS>' +\n'      <SRS>EPSG:4332</SRS>' +\n'      <SRS>EPSG:4333</SRS>' +\n'      <SRS>EPSG:4334</SRS>' +\n'      <SRS>EPSG:4335</SRS>' +\n'      <SRS>EPSG:4336</SRS>' +\n'      <SRS>EPSG:4337</SRS>' +\n'      <SRS>EPSG:4338</SRS>' +\n'      <SRS>EPSG:4339</SRS>' +\n'      <SRS>EPSG:4340</SRS>' +\n'      <SRS>EPSG:4341</SRS>' +\n'      <SRS>EPSG:4342</SRS>' +\n'      <SRS>EPSG:4343</SRS>' +\n'      <SRS>EPSG:4344</SRS>' +\n'      <SRS>EPSG:4345</SRS>' +\n'      <SRS>EPSG:4346</SRS>' +\n'      <SRS>EPSG:4347</SRS>' +\n'      <SRS>EPSG:4348</SRS>' +\n'      <SRS>EPSG:4349</SRS>' +\n'      <SRS>EPSG:4350</SRS>' +\n'      <SRS>EPSG:4351</SRS>' +\n'      <SRS>EPSG:4352</SRS>' +\n'      <SRS>EPSG:4353</SRS>' +\n'      <SRS>EPSG:4354</SRS>' +\n'      <SRS>EPSG:4355</SRS>' +\n'      <SRS>EPSG:4356</SRS>' +\n'      <SRS>EPSG:4357</SRS>' +\n'      <SRS>EPSG:4358</SRS>' +\n'      <SRS>EPSG:4359</SRS>' +\n'      <SRS>EPSG:4360</SRS>' +\n'      <SRS>EPSG:4361</SRS>' +\n'      <SRS>EPSG:4362</SRS>' +\n'      <SRS>EPSG:4363</SRS>' +\n'      <SRS>EPSG:4364</SRS>' +\n'      <SRS>EPSG:4365</SRS>' +\n'      <SRS>EPSG:4366</SRS>' +\n'      <SRS>EPSG:4367</SRS>' +\n'      <SRS>EPSG:4368</SRS>' +\n'      <SRS>EPSG:4369</SRS>' +\n'      <SRS>EPSG:4370</SRS>' +\n'      <SRS>EPSG:4371</SRS>' +\n'      <SRS>EPSG:4372</SRS>' +\n'      <SRS>EPSG:4373</SRS>' +\n'      <SRS>EPSG:4374</SRS>' +\n'      <SRS>EPSG:4375</SRS>' +\n'      <SRS>EPSG:4376</SRS>' +\n'      <SRS>EPSG:4377</SRS>' +\n'      <SRS>EPSG:4378</SRS>' +\n'      <SRS>EPSG:4379</SRS>' +\n'      <SRS>EPSG:4380</SRS>' +\n'      <SRS>EPSG:4381</SRS>' +\n'      <SRS>EPSG:4382</SRS>' +\n'      <SRS>EPSG:4383</SRS>' +\n'      <SRS>EPSG:4384</SRS>' +\n'      <SRS>EPSG:4385</SRS>' +\n'      <SRS>EPSG:4386</SRS>' +\n'      <SRS>EPSG:4387</SRS>' +\n'      <SRS>EPSG:4388</SRS>' +\n'      <SRS>EPSG:4389</SRS>' +\n'      <SRS>EPSG:4600</SRS>' +\n'      <SRS>EPSG:4601</SRS>' +\n'      <SRS>EPSG:4602</SRS>' +\n'      <SRS>EPSG:4603</SRS>' +\n'      <SRS>EPSG:4604</SRS>' +\n'      <SRS>EPSG:4605</SRS>' +\n'      <SRS>EPSG:4606</SRS>' +\n'      <SRS>EPSG:4607</SRS>' +\n'      <SRS>EPSG:4608</SRS>' +\n'      <SRS>EPSG:4609</SRS>' +\n'      <SRS>EPSG:4610</SRS>' +\n'      <SRS>EPSG:4611</SRS>' +\n'      <SRS>EPSG:4612</SRS>' +\n'      <SRS>EPSG:4613</SRS>' +\n'      <SRS>EPSG:4614</SRS>' +\n'      <SRS>EPSG:4615</SRS>' +\n'      <SRS>EPSG:4616</SRS>' +\n'      <SRS>EPSG:4617</SRS>' +\n'      <SRS>EPSG:4618</SRS>' +\n'      <SRS>EPSG:4619</SRS>' +\n'      <SRS>EPSG:4620</SRS>' +\n'      <SRS>EPSG:4621</SRS>' +\n'      <SRS>EPSG:4622</SRS>' +\n'      <SRS>EPSG:4623</SRS>' +\n'      <SRS>EPSG:4624</SRS>' +\n'      <SRS>EPSG:4625</SRS>' +\n'      <SRS>EPSG:4626</SRS>' +\n'      <SRS>EPSG:4627</SRS>' +\n'      <SRS>EPSG:4628</SRS>' +\n'      <SRS>EPSG:4629</SRS>' +\n'      <SRS>EPSG:4630</SRS>' +\n'      <SRS>EPSG:4631</SRS>' +\n'      <SRS>EPSG:4632</SRS>' +\n'      <SRS>EPSG:4633</SRS>' +\n'      <SRS>EPSG:4634</SRS>' +\n'      <SRS>EPSG:4635</SRS>' +\n'      <SRS>EPSG:4636</SRS>' +\n'      <SRS>EPSG:4637</SRS>' +\n'      <SRS>EPSG:4638</SRS>' +\n'      <SRS>EPSG:4639</SRS>' +\n'      <SRS>EPSG:4640</SRS>' +\n'      <SRS>EPSG:4641</SRS>' +\n'      <SRS>EPSG:4642</SRS>' +\n'      <SRS>EPSG:4643</SRS>' +\n'      <SRS>EPSG:4644</SRS>' +\n'      <SRS>EPSG:4645</SRS>' +\n'      <SRS>EPSG:4646</SRS>' +\n'      <SRS>EPSG:4657</SRS>' +\n'      <SRS>EPSG:4658</SRS>' +\n'      <SRS>EPSG:4659</SRS>' +\n'      <SRS>EPSG:4660</SRS>' +\n'      <SRS>EPSG:4661</SRS>' +\n'      <SRS>EPSG:4662</SRS>' +\n'      <SRS>EPSG:4663</SRS>' +\n'      <SRS>EPSG:4664</SRS>' +\n'      <SRS>EPSG:4665</SRS>' +\n'      <SRS>EPSG:4666</SRS>' +\n'      <SRS>EPSG:4667</SRS>' +\n'      <SRS>EPSG:4668</SRS>' +\n'      <SRS>EPSG:4669</SRS>' +\n'      <SRS>EPSG:4670</SRS>' +\n'      <SRS>EPSG:4671</SRS>' +\n'      <SRS>EPSG:4672</SRS>' +\n'      <SRS>EPSG:4673</SRS>' +\n'      <SRS>EPSG:4674</SRS>' +\n'      <SRS>EPSG:4675</SRS>' +\n'      <SRS>EPSG:4676</SRS>' +\n'      <SRS>EPSG:4677</SRS>' +\n'      <SRS>EPSG:4678</SRS>' +\n'      <SRS>EPSG:4679</SRS>' +\n'      <SRS>EPSG:4680</SRS>' +\n'      <SRS>EPSG:4681</SRS>' +\n'      <SRS>EPSG:4682</SRS>' +\n'      <SRS>EPSG:4683</SRS>' +\n'      <SRS>EPSG:4684</SRS>' +\n'      <SRS>EPSG:4685</SRS>' +\n'      <SRS>EPSG:4686</SRS>' +\n'      <SRS>EPSG:4687</SRS>' +\n'      <SRS>EPSG:4688</SRS>' +\n'      <SRS>EPSG:4689</SRS>' +\n'      <SRS>EPSG:4690</SRS>' +\n'      <SRS>EPSG:4691</SRS>' +\n'      <SRS>EPSG:4692</SRS>' +\n'      <SRS>EPSG:4693</SRS>' +\n'      <SRS>EPSG:4694</SRS>' +\n'      <SRS>EPSG:4695</SRS>' +\n'      <SRS>EPSG:4696</SRS>' +\n'      <SRS>EPSG:4697</SRS>' +\n'      <SRS>EPSG:4698</SRS>' +\n'      <SRS>EPSG:4699</SRS>' +\n'      <SRS>EPSG:4700</SRS>' +\n'      <SRS>EPSG:4701</SRS>' +\n'      <SRS>EPSG:4702</SRS>' +\n'      <SRS>EPSG:4703</SRS>' +\n'      <SRS>EPSG:4704</SRS>' +\n'      <SRS>EPSG:4705</SRS>' +\n'      <SRS>EPSG:4706</SRS>' +\n'      <SRS>EPSG:4707</SRS>' +\n'      <SRS>EPSG:4708</SRS>' +\n'      <SRS>EPSG:4709</SRS>' +\n'      <SRS>EPSG:4710</SRS>' +\n'      <SRS>EPSG:4711</SRS>' +\n'      <SRS>EPSG:4712</SRS>' +\n'      <SRS>EPSG:4713</SRS>' +\n'      <SRS>EPSG:4714</SRS>' +\n'      <SRS>EPSG:4715</SRS>' +\n'      <SRS>EPSG:4716</SRS>' +\n'      <SRS>EPSG:4717</SRS>' +\n'      <SRS>EPSG:4718</SRS>' +\n'      <SRS>EPSG:4719</SRS>' +\n'      <SRS>EPSG:4720</SRS>' +\n'      <SRS>EPSG:4721</SRS>' +\n'      <SRS>EPSG:4722</SRS>' +\n'      <SRS>EPSG:4723</SRS>' +\n'      <SRS>EPSG:4724</SRS>' +\n'      <SRS>EPSG:4725</SRS>' +\n'      <SRS>EPSG:4726</SRS>' +\n'      <SRS>EPSG:4727</SRS>' +\n'      <SRS>EPSG:4728</SRS>' +\n'      <SRS>EPSG:4729</SRS>' +\n'      <SRS>EPSG:4730</SRS>' +\n'      <SRS>EPSG:4731</SRS>' +\n'      <SRS>EPSG:4732</SRS>' +\n'      <SRS>EPSG:4733</SRS>' +\n'      <SRS>EPSG:4734</SRS>' +\n'      <SRS>EPSG:4735</SRS>' +\n'      <SRS>EPSG:4736</SRS>' +\n'      <SRS>EPSG:4737</SRS>' +\n'      <SRS>EPSG:4738</SRS>' +\n'      <SRS>EPSG:4739</SRS>' +\n'      <SRS>EPSG:4740</SRS>' +\n'      <SRS>EPSG:4741</SRS>' +\n'      <SRS>EPSG:4742</SRS>' +\n'      <SRS>EPSG:4743</SRS>' +\n'      <SRS>EPSG:4744</SRS>' +\n'      <SRS>EPSG:4745</SRS>' +\n'      <SRS>EPSG:4746</SRS>' +\n'      <SRS>EPSG:4747</SRS>' +\n'      <SRS>EPSG:4748</SRS>' +\n'      <SRS>EPSG:4749</SRS>' +\n'      <SRS>EPSG:4750</SRS>' +\n'      <SRS>EPSG:4751</SRS>' +\n'      <SRS>EPSG:4752</SRS>' +\n'      <SRS>EPSG:4753</SRS>' +\n'      <SRS>EPSG:4754</SRS>' +\n'      <SRS>EPSG:4755</SRS>' +\n'      <SRS>EPSG:4756</SRS>' +\n'      <SRS>EPSG:4757</SRS>' +\n'      <SRS>EPSG:4758</SRS>' +\n'      <SRS>EPSG:4801</SRS>' +\n'      <SRS>EPSG:4802</SRS>' +\n'      <SRS>EPSG:4803</SRS>' +\n'      <SRS>EPSG:4804</SRS>' +\n'      <SRS>EPSG:4805</SRS>' +\n'      <SRS>EPSG:4806</SRS>' +\n'      <SRS>EPSG:4807</SRS>' +\n'      <SRS>EPSG:4808</SRS>' +\n'      <SRS>EPSG:4809</SRS>' +\n'      <SRS>EPSG:4810</SRS>' +\n'      <SRS>EPSG:4811</SRS>' +\n'      <SRS>EPSG:4813</SRS>' +\n'      <SRS>EPSG:4814</SRS>' +\n'      <SRS>EPSG:4815</SRS>' +\n'      <SRS>EPSG:4816</SRS>' +\n'      <SRS>EPSG:4817</SRS>' +\n'      <SRS>EPSG:4818</SRS>' +\n'      <SRS>EPSG:4819</SRS>' +\n'      <SRS>EPSG:4820</SRS>' +\n'      <SRS>EPSG:4821</SRS>' +\n'      <SRS>EPSG:4894</SRS>' +\n'      <SRS>EPSG:4895</SRS>' +\n'      <SRS>EPSG:4896</SRS>' +\n'      <SRS>EPSG:4897</SRS>' +\n'      <SRS>EPSG:4898</SRS>' +\n'      <SRS>EPSG:4899</SRS>' +\n'      <SRS>EPSG:4900</SRS>' +\n'      <SRS>EPSG:4901</SRS>' +\n'      <SRS>EPSG:4902</SRS>' +\n'      <SRS>EPSG:4903</SRS>' +\n'      <SRS>EPSG:4904</SRS>' +\n'      <SRS>EPSG:4906</SRS>' +\n'      <SRS>EPSG:4907</SRS>' +\n'      <SRS>EPSG:4908</SRS>' +\n'      <SRS>EPSG:4909</SRS>' +\n'      <SRS>EPSG:4910</SRS>' +\n'      <SRS>EPSG:4911</SRS>' +\n'      <SRS>EPSG:4912</SRS>' +\n'      <SRS>EPSG:4913</SRS>' +\n'      <SRS>EPSG:4914</SRS>' +\n'      <SRS>EPSG:4915</SRS>' +\n'      <SRS>EPSG:4916</SRS>' +\n'      <SRS>EPSG:4917</SRS>' +\n'      <SRS>EPSG:4918</SRS>' +\n'      <SRS>EPSG:4919</SRS>' +\n'      <SRS>EPSG:4920</SRS>' +\n'      <SRS>EPSG:4921</SRS>' +\n'      <SRS>EPSG:4922</SRS>' +\n'      <SRS>EPSG:4923</SRS>' +\n'      <SRS>EPSG:4924</SRS>' +\n'      <SRS>EPSG:4925</SRS>' +\n'      <SRS>EPSG:4926</SRS>' +\n'      <SRS>EPSG:4927</SRS>' +\n'      <SRS>EPSG:4928</SRS>' +\n'      <SRS>EPSG:4929</SRS>' +\n'      <SRS>EPSG:4930</SRS>' +\n'      <SRS>EPSG:4931</SRS>' +\n'      <SRS>EPSG:4932</SRS>' +\n'      <SRS>EPSG:4933</SRS>' +\n'      <SRS>EPSG:4934</SRS>' +\n'      <SRS>EPSG:4935</SRS>' +\n'      <SRS>EPSG:4936</SRS>' +\n'      <SRS>EPSG:4937</SRS>' +\n'      <SRS>EPSG:4938</SRS>' +\n'      <SRS>EPSG:4939</SRS>' +\n'      <SRS>EPSG:4940</SRS>' +\n'      <SRS>EPSG:4941</SRS>' +\n'      <SRS>EPSG:4942</SRS>' +\n'      <SRS>EPSG:4943</SRS>' +\n'      <SRS>EPSG:4944</SRS>' +\n'      <SRS>EPSG:4945</SRS>' +\n'      <SRS>EPSG:4946</SRS>' +\n'      <SRS>EPSG:4947</SRS>' +\n'      <SRS>EPSG:4948</SRS>' +\n'      <SRS>EPSG:4949</SRS>' +\n'      <SRS>EPSG:4950</SRS>' +\n'      <SRS>EPSG:4951</SRS>' +\n'      <SRS>EPSG:4952</SRS>' +\n'      <SRS>EPSG:4953</SRS>' +\n'      <SRS>EPSG:4954</SRS>' +\n'      <SRS>EPSG:4955</SRS>' +\n'      <SRS>EPSG:4956</SRS>' +\n'      <SRS>EPSG:4957</SRS>' +\n'      <SRS>EPSG:4958</SRS>' +\n'      <SRS>EPSG:4959</SRS>' +\n'      <SRS>EPSG:4960</SRS>' +\n'      <SRS>EPSG:4961</SRS>' +\n'      <SRS>EPSG:4962</SRS>' +\n'      <SRS>EPSG:4963</SRS>' +\n'      <SRS>EPSG:4964</SRS>' +\n'      <SRS>EPSG:4965</SRS>' +\n'      <SRS>EPSG:4966</SRS>' +\n'      <SRS>EPSG:4967</SRS>' +\n'      <SRS>EPSG:4968</SRS>' +\n'      <SRS>EPSG:4969</SRS>' +\n'      <SRS>EPSG:4970</SRS>' +\n'      <SRS>EPSG:4971</SRS>' +\n'      <SRS>EPSG:4972</SRS>' +\n'      <SRS>EPSG:4973</SRS>' +\n'      <SRS>EPSG:4974</SRS>' +\n'      <SRS>EPSG:4975</SRS>' +\n'      <SRS>EPSG:4976</SRS>' +\n'      <SRS>EPSG:4977</SRS>' +\n'      <SRS>EPSG:4978</SRS>' +\n'      <SRS>EPSG:4979</SRS>' +\n'      <SRS>EPSG:4980</SRS>' +\n'      <SRS>EPSG:4981</SRS>' +\n'      <SRS>EPSG:4982</SRS>' +\n'      <SRS>EPSG:4983</SRS>' +\n'      <SRS>EPSG:4984</SRS>' +\n'      <SRS>EPSG:4985</SRS>' +\n'      <SRS>EPSG:4986</SRS>' +\n'      <SRS>EPSG:4987</SRS>' +\n'      <SRS>EPSG:4988</SRS>' +\n'      <SRS>EPSG:4989</SRS>' +\n'      <SRS>EPSG:4990</SRS>' +\n'      <SRS>EPSG:4991</SRS>' +\n'      <SRS>EPSG:4992</SRS>' +\n'      <SRS>EPSG:4993</SRS>' +\n'      <SRS>EPSG:4994</SRS>' +\n'      <SRS>EPSG:4995</SRS>' +\n'      <SRS>EPSG:4996</SRS>' +\n'      <SRS>EPSG:4997</SRS>' +\n'      <SRS>EPSG:4998</SRS>' +\n'      <SRS>EPSG:4999</SRS>' +\n'      <SRS>EPSG:5600</SRS>' +\n'      <SRS>EPSG:5601</SRS>' +\n'      <SRS>EPSG:5602</SRS>' +\n'      <SRS>EPSG:5603</SRS>' +\n'      <SRS>EPSG:5604</SRS>' +\n'      <SRS>EPSG:5605</SRS>' +\n'      <SRS>EPSG:5606</SRS>' +\n'      <SRS>EPSG:5607</SRS>' +\n'      <SRS>EPSG:5608</SRS>' +\n'      <SRS>EPSG:5609</SRS>' +\n'      <SRS>EPSG:5701</SRS>' +\n'      <SRS>EPSG:5702</SRS>' +\n'      <SRS>EPSG:5703</SRS>' +\n'      <SRS>EPSG:5704</SRS>' +\n'      <SRS>EPSG:5705</SRS>' +\n'      <SRS>EPSG:5706</SRS>' +\n'      <SRS>EPSG:5709</SRS>' +\n'      <SRS>EPSG:5710</SRS>' +\n'      <SRS>EPSG:5711</SRS>' +\n'      <SRS>EPSG:5712</SRS>' +\n'      <SRS>EPSG:5713</SRS>' +\n'      <SRS>EPSG:5714</SRS>' +\n'      <SRS>EPSG:5715</SRS>' +\n'      <SRS>EPSG:5716</SRS>' +\n'      <SRS>EPSG:5717</SRS>' +\n'      <SRS>EPSG:5718</SRS>' +\n'      <SRS>EPSG:5719</SRS>' +\n'      <SRS>EPSG:5720</SRS>' +\n'      <SRS>EPSG:5721</SRS>' +\n'      <SRS>EPSG:5722</SRS>' +\n'      <SRS>EPSG:5723</SRS>' +\n'      <SRS>EPSG:5724</SRS>' +\n'      <SRS>EPSG:5725</SRS>' +\n'      <SRS>EPSG:5726</SRS>' +\n'      <SRS>EPSG:5727</SRS>' +\n'      <SRS>EPSG:5728</SRS>' +\n'      <SRS>EPSG:5729</SRS>' +\n'      <SRS>EPSG:5730</SRS>' +\n'      <SRS>EPSG:5731</SRS>' +\n'      <SRS>EPSG:5732</SRS>' +\n'      <SRS>EPSG:5733</SRS>' +\n'      <SRS>EPSG:5734</SRS>' +\n'      <SRS>EPSG:5735</SRS>' +\n'      <SRS>EPSG:5736</SRS>' +\n'      <SRS>EPSG:5737</SRS>' +\n'      <SRS>EPSG:5738</SRS>' +\n'      <SRS>EPSG:5739</SRS>' +\n'      <SRS>EPSG:5740</SRS>' +\n'      <SRS>EPSG:5741</SRS>' +\n'      <SRS>EPSG:5742</SRS>' +\n'      <SRS>EPSG:5743</SRS>' +\n'      <SRS>EPSG:5744</SRS>' +\n'      <SRS>EPSG:5745</SRS>' +\n'      <SRS>EPSG:5746</SRS>' +\n'      <SRS>EPSG:5747</SRS>' +\n'      <SRS>EPSG:5748</SRS>' +\n'      <SRS>EPSG:5749</SRS>' +\n'      <SRS>EPSG:5750</SRS>' +\n'      <SRS>EPSG:5751</SRS>' +\n'      <SRS>EPSG:5752</SRS>' +\n'      <SRS>EPSG:5753</SRS>' +\n'      <SRS>EPSG:5754</SRS>' +\n'      <SRS>EPSG:5755</SRS>' +\n'      <SRS>EPSG:5756</SRS>' +\n'      <SRS>EPSG:5757</SRS>' +\n'      <SRS>EPSG:5758</SRS>' +\n'      <SRS>EPSG:5759</SRS>' +\n'      <SRS>EPSG:5760</SRS>' +\n'      <SRS>EPSG:5761</SRS>' +\n'      <SRS>EPSG:5762</SRS>' +\n'      <SRS>EPSG:5763</SRS>' +\n'      <SRS>EPSG:5764</SRS>' +\n'      <SRS>EPSG:5765</SRS>' +\n'      <SRS>EPSG:5766</SRS>' +\n'      <SRS>EPSG:5767</SRS>' +\n'      <SRS>EPSG:5768</SRS>' +\n'      <SRS>EPSG:5769</SRS>' +\n'      <SRS>EPSG:5770</SRS>' +\n'      <SRS>EPSG:5771</SRS>' +\n'      <SRS>EPSG:5772</SRS>' +\n'      <SRS>EPSG:5773</SRS>' +\n'      <SRS>EPSG:5774</SRS>' +\n'      <SRS>EPSG:5775</SRS>' +\n'      <SRS>EPSG:5776</SRS>' +\n'      <SRS>EPSG:5777</SRS>' +\n'      <SRS>EPSG:5778</SRS>' +\n'      <SRS>EPSG:5779</SRS>' +\n'      <SRS>EPSG:5780</SRS>' +\n'      <SRS>EPSG:5781</SRS>' +\n'      <SRS>EPSG:5782</SRS>' +\n'      <SRS>EPSG:5783</SRS>' +\n'      <SRS>EPSG:5784</SRS>' +\n'      <SRS>EPSG:5785</SRS>' +\n'      <SRS>EPSG:5786</SRS>' +\n'      <SRS>EPSG:5787</SRS>' +\n'      <SRS>EPSG:5788</SRS>' +\n'      <SRS>EPSG:5789</SRS>' +\n'      <SRS>EPSG:5790</SRS>' +\n'      <SRS>EPSG:5791</SRS>' +\n'      <SRS>EPSG:5792</SRS>' +\n'      <SRS>EPSG:5793</SRS>' +\n'      <SRS>EPSG:5794</SRS>' +\n'      <SRS>EPSG:5795</SRS>' +\n'      <SRS>EPSG:5796</SRS>' +\n'      <SRS>EPSG:5797</SRS>' +\n'      <SRS>EPSG:5798</SRS>' +\n'      <SRS>EPSG:5799</SRS>' +\n'      <SRS>EPSG:5800</SRS>' +\n'      <SRS>EPSG:5801</SRS>' +\n'      <SRS>EPSG:5802</SRS>' +\n'      <SRS>EPSG:5803</SRS>' +\n'      <SRS>EPSG:5804</SRS>' +\n'      <SRS>EPSG:5805</SRS>' +\n'      <SRS>EPSG:5806</SRS>' +\n'      <SRS>EPSG:5807</SRS>' +\n'      <SRS>EPSG:5808</SRS>' +\n'      <SRS>EPSG:5809</SRS>' +\n'      <SRS>EPSG:5810</SRS>' +\n'      <SRS>EPSG:5811</SRS>' +\n'      <SRS>EPSG:5812</SRS>' +\n'      <SRS>EPSG:5813</SRS>' +\n'      <SRS>EPSG:5814</SRS>' +\n'      <SRS>EPSG:5815</SRS>' +\n'      <SRS>EPSG:5816</SRS>' +\n'      <SRS>EPSG:5817</SRS>' +\n'      <SRS>EPSG:5818</SRS>' +\n'      <SRS>EPSG:7400</SRS>' +\n'      <SRS>EPSG:7401</SRS>' +\n'      <SRS>EPSG:7402</SRS>' +\n'      <SRS>EPSG:7403</SRS>' +\n'      <SRS>EPSG:7404</SRS>' +\n'      <SRS>EPSG:7405</SRS>' +\n'      <SRS>EPSG:7406</SRS>' +\n'      <SRS>EPSG:7407</SRS>' +\n'      <SRS>EPSG:7408</SRS>' +\n'      <SRS>EPSG:7409</SRS>' +\n'      <SRS>EPSG:7410</SRS>' +\n'      <SRS>EPSG:7411</SRS>' +\n'      <SRS>EPSG:7412</SRS>' +\n'      <SRS>EPSG:7413</SRS>' +\n'      <SRS>EPSG:7414</SRS>' +\n'      <SRS>EPSG:7415</SRS>' +\n'      <SRS>EPSG:7416</SRS>' +\n'      <SRS>EPSG:7417</SRS>' +\n'      <SRS>EPSG:7418</SRS>' +\n'      <SRS>EPSG:7419</SRS>' +\n'      <SRS>EPSG:7420</SRS>' +\n'      <SRS>EPSG:20004</SRS>' +\n'      <SRS>EPSG:20005</SRS>' +\n'      <SRS>EPSG:20006</SRS>' +\n'      <SRS>EPSG:20007</SRS>' +\n'      <SRS>EPSG:20008</SRS>' +\n'      <SRS>EPSG:20009</SRS>' +\n'      <SRS>EPSG:20010</SRS>' +\n'      <SRS>EPSG:20011</SRS>' +\n'      <SRS>EPSG:20012</SRS>' +\n'      <SRS>EPSG:20013</SRS>' +\n'      <SRS>EPSG:20014</SRS>' +\n'      <SRS>EPSG:20015</SRS>' +\n'      <SRS>EPSG:20016</SRS>' +\n'      <SRS>EPSG:20017</SRS>' +\n'      <SRS>EPSG:20018</SRS>' +\n'      <SRS>EPSG:20019</SRS>' +\n'      <SRS>EPSG:20020</SRS>' +\n'      <SRS>EPSG:20021</SRS>' +\n'      <SRS>EPSG:20022</SRS>' +\n'      <SRS>EPSG:20023</SRS>' +\n'      <SRS>EPSG:20024</SRS>' +\n'      <SRS>EPSG:20025</SRS>' +\n'      <SRS>EPSG:20026</SRS>' +\n'      <SRS>EPSG:20027</SRS>' +\n'      <SRS>EPSG:20028</SRS>' +\n'      <SRS>EPSG:20029</SRS>' +\n'      <SRS>EPSG:20030</SRS>' +\n'      <SRS>EPSG:20031</SRS>' +\n'      <SRS>EPSG:20032</SRS>' +\n'      <SRS>EPSG:20064</SRS>' +\n'      <SRS>EPSG:20065</SRS>' +\n'      <SRS>EPSG:20066</SRS>' +\n'      <SRS>EPSG:20067</SRS>' +\n'      <SRS>EPSG:20068</SRS>' +\n'      <SRS>EPSG:20069</SRS>' +\n'      <SRS>EPSG:20070</SRS>' +\n'      <SRS>EPSG:20071</SRS>' +\n'      <SRS>EPSG:20072</SRS>' +\n'      <SRS>EPSG:20073</SRS>' +\n'      <SRS>EPSG:20074</SRS>' +\n'      <SRS>EPSG:20075</SRS>' +\n'      <SRS>EPSG:20076</SRS>' +\n'      <SRS>EPSG:20077</SRS>' +\n'      <SRS>EPSG:20078</SRS>' +\n'      <SRS>EPSG:20079</SRS>' +\n'      <SRS>EPSG:20080</SRS>' +\n'      <SRS>EPSG:20081</SRS>' +\n'      <SRS>EPSG:20082</SRS>' +\n'      <SRS>EPSG:20083</SRS>' +\n'      <SRS>EPSG:20084</SRS>' +\n'      <SRS>EPSG:20085</SRS>' +\n'      <SRS>EPSG:20086</SRS>' +\n'      <SRS>EPSG:20087</SRS>' +\n'      <SRS>EPSG:20088</SRS>' +\n'      <SRS>EPSG:20089</SRS>' +\n'      <SRS>EPSG:20090</SRS>' +\n'      <SRS>EPSG:20091</SRS>' +\n'      <SRS>EPSG:20092</SRS>' +\n'      <SRS>EPSG:20135</SRS>' +\n'      <SRS>EPSG:20136</SRS>' +\n'      <SRS>EPSG:20137</SRS>' +\n'      <SRS>EPSG:20138</SRS>' +\n'      <SRS>EPSG:20248</SRS>' +\n'      <SRS>EPSG:20249</SRS>' +\n'      <SRS>EPSG:20250</SRS>' +\n'      <SRS>EPSG:20251</SRS>' +\n'      <SRS>EPSG:20252</SRS>' +\n'      <SRS>EPSG:20253</SRS>' +\n'      <SRS>EPSG:20254</SRS>' +\n'      <SRS>EPSG:20255</SRS>' +\n'      <SRS>EPSG:20256</SRS>' +\n'      <SRS>EPSG:20257</SRS>' +\n'      <SRS>EPSG:20258</SRS>' +\n'      <SRS>EPSG:20348</SRS>' +\n'      <SRS>EPSG:20349</SRS>' +\n'      <SRS>EPSG:20350</SRS>' +\n'      <SRS>EPSG:20351</SRS>' +\n'      <SRS>EPSG:20352</SRS>' +\n'      <SRS>EPSG:20353</SRS>' +\n'      <SRS>EPSG:20354</SRS>' +\n'      <SRS>EPSG:20355</SRS>' +\n'      <SRS>EPSG:20356</SRS>' +\n'      <SRS>EPSG:20357</SRS>' +\n'      <SRS>EPSG:20358</SRS>' +\n'      <SRS>EPSG:20436</SRS>' +\n'      <SRS>EPSG:20437</SRS>' +\n'      <SRS>EPSG:20438</SRS>' +\n'      <SRS>EPSG:20439</SRS>' +\n'      <SRS>EPSG:20440</SRS>' +\n'      <SRS>EPSG:20499</SRS>' +\n'      <SRS>EPSG:20538</SRS>' +\n'      <SRS>EPSG:20539</SRS>' +\n'      <SRS>EPSG:20790</SRS>' +\n'      <SRS>EPSG:20791</SRS>' +\n'      <SRS>EPSG:20822</SRS>' +\n'      <SRS>EPSG:20823</SRS>' +\n'      <SRS>EPSG:20824</SRS>' +\n'      <SRS>EPSG:20934</SRS>' +\n'      <SRS>EPSG:20935</SRS>' +\n'      <SRS>EPSG:20936</SRS>' +\n'      <SRS>EPSG:21035</SRS>' +\n'      <SRS>EPSG:21036</SRS>' +\n'      <SRS>EPSG:21037</SRS>' +\n'      <SRS>EPSG:21095</SRS>' +\n'      <SRS>EPSG:21096</SRS>' +\n'      <SRS>EPSG:21097</SRS>' +\n'      <SRS>EPSG:21100</SRS>' +\n'      <SRS>EPSG:21148</SRS>' +\n'      <SRS>EPSG:21149</SRS>' +\n'      <SRS>EPSG:21150</SRS>' +\n'      <SRS>EPSG:21291</SRS>' +\n'      <SRS>EPSG:21292</SRS>' +\n'      <SRS>EPSG:21413</SRS>' +\n'      <SRS>EPSG:21414</SRS>' +\n'      <SRS>EPSG:21415</SRS>' +\n'      <SRS>EPSG:21416</SRS>' +\n'      <SRS>EPSG:21417</SRS>' +\n'      <SRS>EPSG:21418</SRS>' +\n'      <SRS>EPSG:21419</SRS>' +\n'      <SRS>EPSG:21420</SRS>' +\n'      <SRS>EPSG:21421</SRS>' +\n'      <SRS>EPSG:21422</SRS>' +\n'      <SRS>EPSG:21423</SRS>' +\n'      <SRS>EPSG:21453</SRS>' +\n'      <SRS>EPSG:21454</SRS>' +\n'      <SRS>EPSG:21455</SRS>' +\n'      <SRS>EPSG:21456</SRS>' +\n'      <SRS>EPSG:21457</SRS>' +\n'      <SRS>EPSG:21458</SRS>' +\n'      <SRS>EPSG:21459</SRS>' +\n'      <SRS>EPSG:21460</SRS>' +\n'      <SRS>EPSG:21461</SRS>' +\n'      <SRS>EPSG:21462</SRS>' +\n'      <SRS>EPSG:21463</SRS>' +\n'      <SRS>EPSG:21473</SRS>' +\n'      <SRS>EPSG:21474</SRS>' +\n'      <SRS>EPSG:21475</SRS>' +\n'      <SRS>EPSG:21476</SRS>' +\n'      <SRS>EPSG:21477</SRS>' +\n'      <SRS>EPSG:21478</SRS>' +\n'      <SRS>EPSG:21479</SRS>' +\n'      <SRS>EPSG:21480</SRS>' +\n'      <SRS>EPSG:21481</SRS>' +\n'      <SRS>EPSG:21482</SRS>' +\n'      <SRS>EPSG:21483</SRS>' +\n'      <SRS>EPSG:21500</SRS>' +\n'      <SRS>EPSG:21780</SRS>' +\n'      <SRS>EPSG:21781</SRS>' +\n'      <SRS>EPSG:21817</SRS>' +\n'      <SRS>EPSG:21818</SRS>' +\n'      <SRS>EPSG:21891</SRS>' +\n'      <SRS>EPSG:21892</SRS>' +\n'      <SRS>EPSG:21893</SRS>' +\n'      <SRS>EPSG:21894</SRS>' +\n'      <SRS>EPSG:21896</SRS>' +\n'      <SRS>EPSG:21897</SRS>' +\n'      <SRS>EPSG:21898</SRS>' +\n'      <SRS>EPSG:21899</SRS>' +\n'      <SRS>EPSG:22032</SRS>' +\n'      <SRS>EPSG:22033</SRS>' +\n'      <SRS>EPSG:22091</SRS>' +\n'      <SRS>EPSG:22092</SRS>' +\n'      <SRS>EPSG:22171</SRS>' +\n'      <SRS>EPSG:22172</SRS>' +\n'      <SRS>EPSG:22173</SRS>' +\n'      <SRS>EPSG:22174</SRS>' +\n'      <SRS>EPSG:22175</SRS>' +\n'      <SRS>EPSG:22176</SRS>' +\n'      <SRS>EPSG:22177</SRS>' +\n'      <SRS>EPSG:22181</SRS>' +\n'      <SRS>EPSG:22182</SRS>' +\n'      <SRS>EPSG:22183</SRS>' +\n'      <SRS>EPSG:22184</SRS>' +\n'      <SRS>EPSG:22185</SRS>' +\n'      <SRS>EPSG:22186</SRS>' +\n'      <SRS>EPSG:22187</SRS>' +\n'      <SRS>EPSG:22191</SRS>' +\n'      <SRS>EPSG:22192</SRS>' +\n'      <SRS>EPSG:22193</SRS>' +\n'      <SRS>EPSG:22194</SRS>' +\n'      <SRS>EPSG:22195</SRS>' +\n'      <SRS>EPSG:22196</SRS>' +\n'      <SRS>EPSG:22197</SRS>' +\n'      <SRS>EPSG:22234</SRS>' +\n'      <SRS>EPSG:22235</SRS>' +\n'      <SRS>EPSG:22236</SRS>' +\n'      <SRS>EPSG:22275</SRS>' +\n'      <SRS>EPSG:22277</SRS>' +\n'      <SRS>EPSG:22279</SRS>' +\n'      <SRS>EPSG:22281</SRS>' +\n'      <SRS>EPSG:22283</SRS>' +\n'      <SRS>EPSG:22285</SRS>' +\n'      <SRS>EPSG:22287</SRS>' +\n'      <SRS>EPSG:22289</SRS>' +\n'      <SRS>EPSG:22291</SRS>' +\n'      <SRS>EPSG:22293</SRS>' +\n'      <SRS>EPSG:22300</SRS>' +\n'      <SRS>EPSG:22332</SRS>' +\n'      <SRS>EPSG:22391</SRS>' +\n'      <SRS>EPSG:22392</SRS>' +\n'      <SRS>EPSG:22521</SRS>' +\n'      <SRS>EPSG:22522</SRS>' +\n'      <SRS>EPSG:22523</SRS>' +\n'      <SRS>EPSG:22524</SRS>' +\n'      <SRS>EPSG:22525</SRS>' +\n'      <SRS>EPSG:22700</SRS>' +\n'      <SRS>EPSG:22770</SRS>' +\n'      <SRS>EPSG:22780</SRS>' +\n'      <SRS>EPSG:22832</SRS>' +\n'      <SRS>EPSG:22991</SRS>' +\n'      <SRS>EPSG:22992</SRS>' +\n'      <SRS>EPSG:22993</SRS>' +\n'      <SRS>EPSG:22994</SRS>' +\n'      <SRS>EPSG:23028</SRS>' +\n'      <SRS>EPSG:23029</SRS>' +\n'      <SRS>EPSG:23030</SRS>' +\n'      <SRS>EPSG:23031</SRS>' +\n'      <SRS>EPSG:23032</SRS>' +\n'      <SRS>EPSG:23033</SRS>' +\n'      <SRS>EPSG:23034</SRS>' +\n'      <SRS>EPSG:23035</SRS>' +\n'      <SRS>EPSG:23036</SRS>' +\n'      <SRS>EPSG:23037</SRS>' +\n'      <SRS>EPSG:23038</SRS>' +\n'      <SRS>EPSG:23090</SRS>' +\n'      <SRS>EPSG:23095</SRS>' +\n'      <SRS>EPSG:23239</SRS>' +\n'      <SRS>EPSG:23240</SRS>' +\n'      <SRS>EPSG:23433</SRS>' +\n'      <SRS>EPSG:23700</SRS>' +\n'      <SRS>EPSG:23846</SRS>' +\n'      <SRS>EPSG:23847</SRS>' +\n'      <SRS>EPSG:23848</SRS>' +\n'      <SRS>EPSG:23849</SRS>' +\n'      <SRS>EPSG:23850</SRS>' +\n'      <SRS>EPSG:23851</SRS>' +\n'      <SRS>EPSG:23852</SRS>' +\n'      <SRS>EPSG:23853</SRS>' +\n'      <SRS>EPSG:23866</SRS>' +\n'      <SRS>EPSG:23867</SRS>' +\n'      <SRS>EPSG:23868</SRS>' +\n'      <SRS>EPSG:23869</SRS>' +\n'      <SRS>EPSG:23870</SRS>' +\n'      <SRS>EPSG:23871</SRS>' +\n'      <SRS>EPSG:23872</SRS>' +\n'      <SRS>EPSG:23877</SRS>' +\n'      <SRS>EPSG:23878</SRS>' +\n'      <SRS>EPSG:23879</SRS>' +\n'      <SRS>EPSG:23880</SRS>' +\n'      <SRS>EPSG:23881</SRS>' +\n'      <SRS>EPSG:23882</SRS>' +\n'      <SRS>EPSG:23883</SRS>' +\n'      <SRS>EPSG:23884</SRS>' +\n'      <SRS>EPSG:23886</SRS>' +\n'      <SRS>EPSG:23887</SRS>' +\n'      <SRS>EPSG:23888</SRS>' +\n'      <SRS>EPSG:23889</SRS>' +\n'      <SRS>EPSG:23890</SRS>' +\n'      <SRS>EPSG:23891</SRS>' +\n'      <SRS>EPSG:23892</SRS>' +\n'      <SRS>EPSG:23893</SRS>' +\n'      <SRS>EPSG:23894</SRS>' +\n'      <SRS>EPSG:23946</SRS>' +\n'      <SRS>EPSG:23947</SRS>' +\n'      <SRS>EPSG:23948</SRS>' +\n'      <SRS>EPSG:24047</SRS>' +\n'      <SRS>EPSG:24048</SRS>' +\n'      <SRS>EPSG:24100</SRS>' +\n'      <SRS>EPSG:24200</SRS>' +\n'      <SRS>EPSG:24305</SRS>' +\n'      <SRS>EPSG:24306</SRS>' +\n'      <SRS>EPSG:24311</SRS>' +\n'      <SRS>EPSG:24312</SRS>' +\n'      <SRS>EPSG:24313</SRS>' +\n'      <SRS>EPSG:24342</SRS>' +\n'      <SRS>EPSG:24343</SRS>' +\n'      <SRS>EPSG:24344</SRS>' +\n'      <SRS>EPSG:24345</SRS>' +\n'      <SRS>EPSG:24346</SRS>' +\n'      <SRS>EPSG:24347</SRS>' +\n'      <SRS>EPSG:24370</SRS>' +\n'      <SRS>EPSG:24371</SRS>' +\n'      <SRS>EPSG:24372</SRS>' +\n'      <SRS>EPSG:24373</SRS>' +\n'      <SRS>EPSG:24374</SRS>' +\n'      <SRS>EPSG:24375</SRS>' +\n'      <SRS>EPSG:24376</SRS>' +\n'      <SRS>EPSG:24377</SRS>' +\n'      <SRS>EPSG:24378</SRS>' +\n'      <SRS>EPSG:24379</SRS>' +\n'      <SRS>EPSG:24380</SRS>' +\n'      <SRS>EPSG:24381</SRS>' +\n'      <SRS>EPSG:24382</SRS>' +\n'      <SRS>EPSG:24383</SRS>' +\n'      <SRS>EPSG:24500</SRS>' +\n'      <SRS>EPSG:24547</SRS>' +\n'      <SRS>EPSG:24548</SRS>' +\n'      <SRS>EPSG:24571</SRS>' +\n'      <SRS>EPSG:24600</SRS>' +\n'      <SRS>EPSG:24718</SRS>' +\n'      <SRS>EPSG:24719</SRS>' +\n'      <SRS>EPSG:24720</SRS>' +\n'      <SRS>EPSG:24817</SRS>' +\n'      <SRS>EPSG:24818</SRS>' +\n'      <SRS>EPSG:24819</SRS>' +\n'      <SRS>EPSG:24820</SRS>' +\n'      <SRS>EPSG:24821</SRS>' +\n'      <SRS>EPSG:24877</SRS>' +\n'      <SRS>EPSG:24878</SRS>' +\n'      <SRS>EPSG:24879</SRS>' +\n'      <SRS>EPSG:24880</SRS>' +\n'      <SRS>EPSG:24881</SRS>' +\n'      <SRS>EPSG:24882</SRS>' +\n'      <SRS>EPSG:24891</SRS>' +\n'      <SRS>EPSG:24892</SRS>' +\n'      <SRS>EPSG:24893</SRS>' +\n'      <SRS>EPSG:25000</SRS>' +\n'      <SRS>EPSG:25231</SRS>' +\n'      <SRS>EPSG:25391</SRS>' +\n'      <SRS>EPSG:25392</SRS>' +\n'      <SRS>EPSG:25393</SRS>' +\n'      <SRS>EPSG:25394</SRS>' +\n'      <SRS>EPSG:25395</SRS>' +\n'      <SRS>EPSG:25700</SRS>' +\n'      <SRS>EPSG:25828</SRS>' +\n'      <SRS>EPSG:25829</SRS>' +\n'      <SRS>EPSG:25830</SRS>' +\n'      <SRS>EPSG:25831</SRS>' +\n'      <SRS>EPSG:25832</SRS>' +\n'      <SRS>EPSG:25833</SRS>' +\n'      <SRS>EPSG:25834</SRS>' +\n'      <SRS>EPSG:25835</SRS>' +\n'      <SRS>EPSG:25836</SRS>' +\n'      <SRS>EPSG:25837</SRS>' +\n'      <SRS>EPSG:25838</SRS>' +\n'      <SRS>EPSG:25884</SRS>' +\n'      <SRS>EPSG:25932</SRS>' +\n'      <SRS>EPSG:26191</SRS>' +\n'      <SRS>EPSG:26192</SRS>' +\n'      <SRS>EPSG:26193</SRS>' +\n'      <SRS>EPSG:26194</SRS>' +\n'      <SRS>EPSG:26195</SRS>' +\n'      <SRS>EPSG:26237</SRS>' +\n'      <SRS>EPSG:26331</SRS>' +\n'      <SRS>EPSG:26332</SRS>' +\n'      <SRS>EPSG:26391</SRS>' +\n'      <SRS>EPSG:26392</SRS>' +\n'      <SRS>EPSG:26393</SRS>' +\n'      <SRS>EPSG:26432</SRS>' +\n'      <SRS>EPSG:26591</SRS>' +\n'      <SRS>EPSG:26592</SRS>' +\n'      <SRS>EPSG:26632</SRS>' +\n'      <SRS>EPSG:26692</SRS>' +\n'      <SRS>EPSG:26701</SRS>' +\n'      <SRS>EPSG:26702</SRS>' +\n'      <SRS>EPSG:26703</SRS>' +\n'      <SRS>EPSG:26704</SRS>' +\n'      <SRS>EPSG:26705</SRS>' +\n'      <SRS>EPSG:26706</SRS>' +\n'      <SRS>EPSG:26707</SRS>' +\n'      <SRS>EPSG:26708</SRS>' +\n'      <SRS>EPSG:26709</SRS>' +\n'      <SRS>EPSG:26710</SRS>' +\n'      <SRS>EPSG:26711</SRS>' +\n'      <SRS>EPSG:26712</SRS>' +\n'      <SRS>EPSG:26713</SRS>' +\n'      <SRS>EPSG:26714</SRS>' +\n'      <SRS>EPSG:26715</SRS>' +\n'      <SRS>EPSG:26716</SRS>' +\n'      <SRS>EPSG:26717</SRS>' +\n'      <SRS>EPSG:26718</SRS>' +\n'      <SRS>EPSG:26719</SRS>' +\n'      <SRS>EPSG:26720</SRS>' +\n'      <SRS>EPSG:26721</SRS>' +\n'      <SRS>EPSG:26722</SRS>' +\n'      <SRS>EPSG:26729</SRS>' +\n'      <SRS>EPSG:26730</SRS>' +\n'      <SRS>EPSG:26731</SRS>' +\n'      <SRS>EPSG:26732</SRS>' +\n'      <SRS>EPSG:26733</SRS>' +\n'      <SRS>EPSG:26734</SRS>' +\n'      <SRS>EPSG:26735</SRS>' +\n'      <SRS>EPSG:26736</SRS>' +\n'      <SRS>EPSG:26737</SRS>' +\n'      <SRS>EPSG:26738</SRS>' +\n'      <SRS>EPSG:26739</SRS>' +\n'      <SRS>EPSG:26740</SRS>' +\n'      <SRS>EPSG:26741</SRS>' +\n'      <SRS>EPSG:26742</SRS>' +\n'      <SRS>EPSG:26743</SRS>' +\n'      <SRS>EPSG:26744</SRS>' +\n'      <SRS>EPSG:26745</SRS>' +\n'      <SRS>EPSG:26746</SRS>' +\n'      <SRS>EPSG:26747</SRS>' +\n'      <SRS>EPSG:26748</SRS>' +\n'      <SRS>EPSG:26749</SRS>' +\n'      <SRS>EPSG:26750</SRS>' +\n'      <SRS>EPSG:26751</SRS>' +\n'      <SRS>EPSG:26752</SRS>' +\n'      <SRS>EPSG:26753</SRS>' +\n'      <SRS>EPSG:26754</SRS>' +\n'      <SRS>EPSG:26755</SRS>' +\n'      <SRS>EPSG:26756</SRS>' +\n'      <SRS>EPSG:26757</SRS>' +\n'      <SRS>EPSG:26758</SRS>' +\n'      <SRS>EPSG:26759</SRS>' +\n'      <SRS>EPSG:26760</SRS>' +\n'      <SRS>EPSG:26766</SRS>' +\n'      <SRS>EPSG:26767</SRS>' +\n'      <SRS>EPSG:26768</SRS>' +\n'      <SRS>EPSG:26769</SRS>' +\n'      <SRS>EPSG:26770</SRS>' +\n'      <SRS>EPSG:26771</SRS>' +\n'      <SRS>EPSG:26772</SRS>' +\n'      <SRS>EPSG:26773</SRS>' +\n'      <SRS>EPSG:26774</SRS>' +\n'      <SRS>EPSG:26775</SRS>' +\n'      <SRS>EPSG:26776</SRS>' +\n'      <SRS>EPSG:26777</SRS>' +\n'      <SRS>EPSG:26778</SRS>' +\n'      <SRS>EPSG:26779</SRS>' +\n'      <SRS>EPSG:26780</SRS>' +\n'      <SRS>EPSG:26781</SRS>' +\n'      <SRS>EPSG:26782</SRS>' +\n'      <SRS>EPSG:26783</SRS>' +\n'      <SRS>EPSG:26784</SRS>' +\n'      <SRS>EPSG:26785</SRS>' +\n'      <SRS>EPSG:26786</SRS>' +\n'      <SRS>EPSG:26787</SRS>' +\n'      <SRS>EPSG:26791</SRS>' +\n'      <SRS>EPSG:26792</SRS>' +\n'      <SRS>EPSG:26793</SRS>' +\n'      <SRS>EPSG:26794</SRS>' +\n'      <SRS>EPSG:26795</SRS>' +\n'      <SRS>EPSG:26796</SRS>' +\n'      <SRS>EPSG:26797</SRS>' +\n'      <SRS>EPSG:26798</SRS>' +\n'      <SRS>EPSG:26799</SRS>' +\n'      <SRS>EPSG:26801</SRS>' +\n'      <SRS>EPSG:26802</SRS>' +\n'      <SRS>EPSG:26803</SRS>' +\n'      <SRS>EPSG:26811</SRS>' +\n'      <SRS>EPSG:26812</SRS>' +\n'      <SRS>EPSG:26813</SRS>' +\n'      <SRS>EPSG:26901</SRS>' +\n'      <SRS>EPSG:26902</SRS>' +\n'      <SRS>EPSG:26903</SRS>' +\n'      <SRS>EPSG:26904</SRS>' +\n'      <SRS>EPSG:26905</SRS>' +\n'      <SRS>EPSG:26906</SRS>' +\n'      <SRS>EPSG:26907</SRS>' +\n'      <SRS>EPSG:26908</SRS>' +\n'      <SRS>EPSG:26909</SRS>' +\n'      <SRS>EPSG:26910</SRS>' +\n'      <SRS>EPSG:26911</SRS>' +\n'      <SRS>EPSG:26912</SRS>' +\n'      <SRS>EPSG:26913</SRS>' +\n'      <SRS>EPSG:26914</SRS>' +\n'      <SRS>EPSG:26915</SRS>' +\n'      <SRS>EPSG:26916</SRS>' +\n'      <SRS>EPSG:26917</SRS>' +\n'      <SRS>EPSG:26918</SRS>' +\n'      <SRS>EPSG:26919</SRS>' +\n'      <SRS>EPSG:26920</SRS>' +\n'      <SRS>EPSG:26921</SRS>' +\n'      <SRS>EPSG:26922</SRS>' +\n'      <SRS>EPSG:26923</SRS>' +\n'      <SRS>EPSG:26929</SRS>' +\n'      <SRS>EPSG:26930</SRS>' +\n'      <SRS>EPSG:26931</SRS>' +\n'      <SRS>EPSG:26932</SRS>' +\n'      <SRS>EPSG:26933</SRS>' +\n'      <SRS>EPSG:26934</SRS>' +\n'      <SRS>EPSG:26935</SRS>' +\n'      <SRS>EPSG:26936</SRS>' +\n'      <SRS>EPSG:26937</SRS>' +\n'      <SRS>EPSG:26938</SRS>' +\n'      <SRS>EPSG:26939</SRS>' +\n'      <SRS>EPSG:26940</SRS>' +\n'      <SRS>EPSG:26941</SRS>' +\n'      <SRS>EPSG:26942</SRS>' +\n'      <SRS>EPSG:26943</SRS>' +\n'      <SRS>EPSG:26944</SRS>' +\n'      <SRS>EPSG:26945</SRS>' +\n'      <SRS>EPSG:26946</SRS>' +\n'      <SRS>EPSG:26948</SRS>' +\n'      <SRS>EPSG:26949</SRS>' +\n'      <SRS>EPSG:26950</SRS>' +\n'      <SRS>EPSG:26951</SRS>' +\n'      <SRS>EPSG:26952</SRS>' +\n'      <SRS>EPSG:26953</SRS>' +\n'      <SRS>EPSG:26954</SRS>' +\n'      <SRS>EPSG:26955</SRS>' +\n'      <SRS>EPSG:26956</SRS>' +\n'      <SRS>EPSG:26957</SRS>' +\n'      <SRS>EPSG:26958</SRS>' +\n'      <SRS>EPSG:26959</SRS>' +\n'      <SRS>EPSG:26960</SRS>' +\n'      <SRS>EPSG:26961</SRS>' +\n'      <SRS>EPSG:26962</SRS>' +\n'      <SRS>EPSG:26963</SRS>' +\n'      <SRS>EPSG:26964</SRS>' +\n'      <SRS>EPSG:26965</SRS>' +\n'      <SRS>EPSG:26966</SRS>' +\n'      <SRS>EPSG:26967</SRS>' +\n'      <SRS>EPSG:26968</SRS>' +\n'      <SRS>EPSG:26969</SRS>' +\n'      <SRS>EPSG:26970</SRS>' +\n'      <SRS>EPSG:26971</SRS>' +\n'      <SRS>EPSG:26972</SRS>' +\n'      <SRS>EPSG:26973</SRS>' +\n'      <SRS>EPSG:26974</SRS>' +\n'      <SRS>EPSG:26975</SRS>' +\n'      <SRS>EPSG:26976</SRS>' +\n'      <SRS>EPSG:26977</SRS>' +\n'      <SRS>EPSG:26978</SRS>' +\n'      <SRS>EPSG:26979</SRS>' +\n'      <SRS>EPSG:26980</SRS>' +\n'      <SRS>EPSG:26981</SRS>' +\n'      <SRS>EPSG:26982</SRS>' +\n'      <SRS>EPSG:26983</SRS>' +\n'      <SRS>EPSG:26984</SRS>' +\n'      <SRS>EPSG:26985</SRS>' +\n'      <SRS>EPSG:26986</SRS>' +\n'      <SRS>EPSG:26987</SRS>' +\n'      <SRS>EPSG:26988</SRS>' +\n'      <SRS>EPSG:26989</SRS>' +\n'      <SRS>EPSG:26990</SRS>' +\n'      <SRS>EPSG:26991</SRS>' +\n'      <SRS>EPSG:26992</SRS>' +\n'      <SRS>EPSG:26993</SRS>' +\n'      <SRS>EPSG:26994</SRS>' +\n'      <SRS>EPSG:26995</SRS>' +\n'      <SRS>EPSG:26996</SRS>' +\n'      <SRS>EPSG:26997</SRS>' +\n'      <SRS>EPSG:26998</SRS>' +\n'      <SRS>EPSG:27037</SRS>' +\n'      <SRS>EPSG:27038</SRS>' +\n'      <SRS>EPSG:27039</SRS>' +\n'      <SRS>EPSG:27040</SRS>' +\n'      <SRS>EPSG:27120</SRS>' +\n'      <SRS>EPSG:27200</SRS>' +\n'      <SRS>EPSG:27205</SRS>' +\n'      <SRS>EPSG:27206</SRS>' +\n'      <SRS>EPSG:27207</SRS>' +\n'      <SRS>EPSG:27208</SRS>' +\n'      <SRS>EPSG:27209</SRS>' +\n'      <SRS>EPSG:27210</SRS>' +\n'      <SRS>EPSG:27211</SRS>' +\n'      <SRS>EPSG:27212</SRS>' +\n'      <SRS>EPSG:27213</SRS>' +\n'      <SRS>EPSG:27214</SRS>' +\n'      <SRS>EPSG:27215</SRS>' +\n'      <SRS>EPSG:27216</SRS>' +\n'      <SRS>EPSG:27217</SRS>' +\n'      <SRS>EPSG:27218</SRS>' +\n'      <SRS>EPSG:27219</SRS>' +\n'      <SRS>EPSG:27220</SRS>' +\n'      <SRS>EPSG:27221</SRS>' +\n'      <SRS>EPSG:27222</SRS>' +\n'      <SRS>EPSG:27223</SRS>' +\n'      <SRS>EPSG:27224</SRS>' +\n'      <SRS>EPSG:27225</SRS>' +\n'      <SRS>EPSG:27226</SRS>' +\n'      <SRS>EPSG:27227</SRS>' +\n'      <SRS>EPSG:27228</SRS>' +\n'      <SRS>EPSG:27229</SRS>' +\n'      <SRS>EPSG:27230</SRS>' +\n'      <SRS>EPSG:27231</SRS>' +\n'      <SRS>EPSG:27232</SRS>' +\n'      <SRS>EPSG:27258</SRS>' +\n'      <SRS>EPSG:27259</SRS>' +\n'      <SRS>EPSG:27260</SRS>' +\n'      <SRS>EPSG:27291</SRS>' +\n'      <SRS>EPSG:27292</SRS>' +\n'      <SRS>EPSG:27391</SRS>' +\n'      <SRS>EPSG:27392</SRS>' +\n'      <SRS>EPSG:27393</SRS>' +\n'      <SRS>EPSG:27394</SRS>' +\n'      <SRS>EPSG:27395</SRS>' +\n'      <SRS>EPSG:27396</SRS>' +\n'      <SRS>EPSG:27397</SRS>' +\n'      <SRS>EPSG:27398</SRS>' +\n'      <SRS>EPSG:27429</SRS>' +\n'      <SRS>EPSG:27492</SRS>' +\n'      <SRS>EPSG:27500</SRS>' +\n'      <SRS>EPSG:27561</SRS>' +\n'      <SRS>EPSG:27562</SRS>' +\n'      <SRS>EPSG:27563</SRS>' +\n'      <SRS>EPSG:27564</SRS>' +\n'      <SRS>EPSG:27571</SRS>' +\n'      <SRS>EPSG:27572</SRS>' +\n'      <SRS>EPSG:27573</SRS>' +\n'      <SRS>EPSG:27574</SRS>' +\n'      <SRS>EPSG:27581</SRS>' +\n'      <SRS>EPSG:27582</SRS>' +\n'      <SRS>EPSG:27583</SRS>' +\n'      <SRS>EPSG:27584</SRS>' +\n'      <SRS>EPSG:27591</SRS>' +\n'      <SRS>EPSG:27592</SRS>' +\n'      <SRS>EPSG:27593</SRS>' +\n'      <SRS>EPSG:27594</SRS>' +\n'      <SRS>EPSG:27700</SRS>' +\n'      <SRS>EPSG:28191</SRS>' +\n'      <SRS>EPSG:28192</SRS>' +\n'      <SRS>EPSG:28193</SRS>' +\n'      <SRS>EPSG:28232</SRS>' +\n'      <SRS>EPSG:28348</SRS>' +\n'      <SRS>EPSG:28349</SRS>' +\n'      <SRS>EPSG:28350</SRS>' +\n'      <SRS>EPSG:28351</SRS>' +\n'      <SRS>EPSG:28352</SRS>' +\n'      <SRS>EPSG:28353</SRS>' +\n'      <SRS>EPSG:28354</SRS>' +\n'      <SRS>EPSG:28355</SRS>' +\n'      <SRS>EPSG:28356</SRS>' +\n'      <SRS>EPSG:28357</SRS>' +\n'      <SRS>EPSG:28358</SRS>' +\n'      <SRS>EPSG:28402</SRS>' +\n'      <SRS>EPSG:28403</SRS>' +\n'      <SRS>EPSG:28404</SRS>' +\n'      <SRS>EPSG:28405</SRS>' +\n'      <SRS>EPSG:28406</SRS>' +\n'      <SRS>EPSG:28407</SRS>' +\n'      <SRS>EPSG:28408</SRS>' +\n'      <SRS>EPSG:28409</SRS>' +\n'      <SRS>EPSG:28410</SRS>' +\n'      <SRS>EPSG:28411</SRS>' +\n'      <SRS>EPSG:28412</SRS>' +\n'      <SRS>EPSG:28413</SRS>' +\n'      <SRS>EPSG:28414</SRS>' +\n'      <SRS>EPSG:28415</SRS>' +\n'      <SRS>EPSG:28416</SRS>' +\n'      <SRS>EPSG:28417</SRS>' +\n'      <SRS>EPSG:28418</SRS>' +\n'      <SRS>EPSG:28419</SRS>' +\n'      <SRS>EPSG:28420</SRS>' +\n'      <SRS>EPSG:28421</SRS>' +\n'      <SRS>EPSG:28422</SRS>' +\n'      <SRS>EPSG:28423</SRS>' +\n'      <SRS>EPSG:28424</SRS>' +\n'      <SRS>EPSG:28425</SRS>' +\n'      <SRS>EPSG:28426</SRS>' +\n'      <SRS>EPSG:28427</SRS>' +\n'      <SRS>EPSG:28428</SRS>' +\n'      <SRS>EPSG:28429</SRS>' +\n'      <SRS>EPSG:28430</SRS>' +\n'      <SRS>EPSG:28431</SRS>' +\n'      <SRS>EPSG:28432</SRS>' +\n'      <SRS>EPSG:28462</SRS>' +\n'      <SRS>EPSG:28463</SRS>' +\n'      <SRS>EPSG:28464</SRS>' +\n'      <SRS>EPSG:28465</SRS>' +\n'      <SRS>EPSG:28466</SRS>' +\n'      <SRS>EPSG:28467</SRS>' +\n'      <SRS>EPSG:28468</SRS>' +\n'      <SRS>EPSG:28469</SRS>' +\n'      <SRS>EPSG:28470</SRS>' +\n'      <SRS>EPSG:28471</SRS>' +\n'      <SRS>EPSG:28472</SRS>' +\n'      <SRS>EPSG:28473</SRS>' +\n'      <SRS>EPSG:28474</SRS>' +\n'      <SRS>EPSG:28475</SRS>' +\n'      <SRS>EPSG:28476</SRS>' +\n'      <SRS>EPSG:28477</SRS>' +\n'      <SRS>EPSG:28478</SRS>' +\n'      <SRS>EPSG:28479</SRS>' +\n'      <SRS>EPSG:28480</SRS>' +\n'      <SRS>EPSG:28481</SRS>' +\n'      <SRS>EPSG:28482</SRS>' +\n'      <SRS>EPSG:28483</SRS>' +\n'      <SRS>EPSG:28484</SRS>' +\n'      <SRS>EPSG:28485</SRS>' +\n'      <SRS>EPSG:28486</SRS>' +\n'      <SRS>EPSG:28487</SRS>' +\n'      <SRS>EPSG:28488</SRS>' +\n'      <SRS>EPSG:28489</SRS>' +\n'      <SRS>EPSG:28490</SRS>' +\n'      <SRS>EPSG:28491</SRS>' +\n'      <SRS>EPSG:28492</SRS>' +\n'      <SRS>EPSG:28600</SRS>' +\n'      <SRS>EPSG:28991</SRS>' +\n'      <SRS>EPSG:28992</SRS>' +\n'      <SRS>EPSG:29100</SRS>' +\n'      <SRS>EPSG:29101</SRS>' +\n'      <SRS>EPSG:29118</SRS>' +\n'      <SRS>EPSG:29119</SRS>' +\n'      <SRS>EPSG:29120</SRS>' +\n'      <SRS>EPSG:29121</SRS>' +\n'      <SRS>EPSG:29122</SRS>' +\n'      <SRS>EPSG:29168</SRS>' +\n'      <SRS>EPSG:29169</SRS>' +\n'      <SRS>EPSG:29170</SRS>' +\n'      <SRS>EPSG:29171</SRS>' +\n'      <SRS>EPSG:29172</SRS>' +\n'      <SRS>EPSG:29177</SRS>' +\n'      <SRS>EPSG:29178</SRS>' +\n'      <SRS>EPSG:29179</SRS>' +\n'      <SRS>EPSG:29180</SRS>' +\n'      <SRS>EPSG:29181</SRS>' +\n'      <SRS>EPSG:29182</SRS>' +\n'      <SRS>EPSG:29183</SRS>' +\n'      <SRS>EPSG:29184</SRS>' +\n'      <SRS>EPSG:29185</SRS>' +\n'      <SRS>EPSG:29187</SRS>' +\n'      <SRS>EPSG:29188</SRS>' +\n'      <SRS>EPSG:29189</SRS>' +\n'      <SRS>EPSG:29190</SRS>' +\n'      <SRS>EPSG:29191</SRS>' +\n'      <SRS>EPSG:29192</SRS>' +\n'      <SRS>EPSG:29193</SRS>' +\n'      <SRS>EPSG:29194</SRS>' +\n'      <SRS>EPSG:29195</SRS>' +\n'      <SRS>EPSG:29220</SRS>' +\n'      <SRS>EPSG:29221</SRS>' +\n'      <SRS>EPSG:29333</SRS>' +\n'      <SRS>EPSG:29371</SRS>' +\n'      <SRS>EPSG:29373</SRS>' +\n'      <SRS>EPSG:29375</SRS>' +\n'      <SRS>EPSG:29377</SRS>' +\n'      <SRS>EPSG:29379</SRS>' +\n'      <SRS>EPSG:29381</SRS>' +\n'      <SRS>EPSG:29383</SRS>' +\n'      <SRS>EPSG:29385</SRS>' +\n'      <SRS>EPSG:29635</SRS>' +\n'      <SRS>EPSG:29636</SRS>' +\n'      <SRS>EPSG:29700</SRS>' +\n'      <SRS>EPSG:29701</SRS>' +\n'      <SRS>EPSG:29702</SRS>' +\n'      <SRS>EPSG:29738</SRS>' +\n'      <SRS>EPSG:29739</SRS>' +\n'      <SRS>EPSG:29849</SRS>' +\n'      <SRS>EPSG:29850</SRS>' +\n'      <SRS>EPSG:29871</SRS>' +\n'      <SRS>EPSG:29872</SRS>' +\n'      <SRS>EPSG:29873</SRS>' +\n'      <SRS>EPSG:29900</SRS>' +\n'      <SRS>EPSG:29901</SRS>' +\n'      <SRS>EPSG:29902</SRS>' +\n'      <SRS>EPSG:29903</SRS>' +\n'      <SRS>EPSG:30161</SRS>' +\n'      <SRS>EPSG:30162</SRS>' +\n'      <SRS>EPSG:30163</SRS>' +\n'      <SRS>EPSG:30164</SRS>' +\n'      <SRS>EPSG:30165</SRS>' +\n'      <SRS>EPSG:30166</SRS>' +\n'      <SRS>EPSG:30167</SRS>' +\n'      <SRS>EPSG:30168</SRS>' +\n'      <SRS>EPSG:30169</SRS>' +\n'      <SRS>EPSG:30170</SRS>' +\n'      <SRS>EPSG:30171</SRS>' +\n'      <SRS>EPSG:30172</SRS>' +\n'      <SRS>EPSG:30173</SRS>' +\n'      <SRS>EPSG:30174</SRS>' +\n'      <SRS>EPSG:30175</SRS>' +\n'      <SRS>EPSG:30176</SRS>' +\n'      <SRS>EPSG:30177</SRS>' +\n'      <SRS>EPSG:30178</SRS>' +\n'      <SRS>EPSG:30179</SRS>' +\n'      <SRS>EPSG:30200</SRS>' +\n'      <SRS>EPSG:30339</SRS>' +\n'      <SRS>EPSG:30340</SRS>' +\n'      <SRS>EPSG:30491</SRS>' +\n'      <SRS>EPSG:30492</SRS>' +\n'      <SRS>EPSG:30493</SRS>' +\n'      <SRS>EPSG:30494</SRS>' +\n'      <SRS>EPSG:30729</SRS>' +\n'      <SRS>EPSG:30730</SRS>' +\n'      <SRS>EPSG:30731</SRS>' +\n'      <SRS>EPSG:30732</SRS>' +\n'      <SRS>EPSG:30791</SRS>' +\n'      <SRS>EPSG:30792</SRS>' +\n'      <SRS>EPSG:30800</SRS>' +\n'      <SRS>EPSG:31028</SRS>' +\n'      <SRS>EPSG:31121</SRS>' +\n'      <SRS>EPSG:31154</SRS>' +\n'      <SRS>EPSG:31170</SRS>' +\n'      <SRS>EPSG:31171</SRS>' +\n'      <SRS>EPSG:31251</SRS>' +\n'      <SRS>EPSG:31252</SRS>' +\n'      <SRS>EPSG:31253</SRS>' +\n'      <SRS>EPSG:31254</SRS>' +\n'      <SRS>EPSG:31255</SRS>' +\n'      <SRS>EPSG:31256</SRS>' +\n'      <SRS>EPSG:31257</SRS>' +\n'      <SRS>EPSG:31258</SRS>' +\n'      <SRS>EPSG:31259</SRS>' +\n'      <SRS>EPSG:31265</SRS>' +\n'      <SRS>EPSG:31266</SRS>' +\n'      <SRS>EPSG:31267</SRS>' +\n'      <SRS>EPSG:31268</SRS>' +\n'      <SRS>EPSG:31275</SRS>' +\n'      <SRS>EPSG:31276</SRS>' +\n'      <SRS>EPSG:31277</SRS>' +\n'      <SRS>EPSG:31278</SRS>' +\n'      <SRS>EPSG:31279</SRS>' +\n'      <SRS>EPSG:31281</SRS>' +\n'      <SRS>EPSG:31282</SRS>' +\n'      <SRS>EPSG:31283</SRS>' +\n'      <SRS>EPSG:31284</SRS>' +\n'      <SRS>EPSG:31285</SRS>' +\n'      <SRS>EPSG:31286</SRS>' +\n'      <SRS>EPSG:31287</SRS>' +\n'      <SRS>EPSG:31288</SRS>' +\n'      <SRS>EPSG:31289</SRS>' +\n'      <SRS>EPSG:31290</SRS>' +\n'      <SRS>EPSG:31291</SRS>' +\n'      <SRS>EPSG:31292</SRS>' +\n'      <SRS>EPSG:31293</SRS>' +\n'      <SRS>EPSG:31294</SRS>' +\n'      <SRS>EPSG:31295</SRS>' +\n'      <SRS>EPSG:31296</SRS>' +\n'      <SRS>EPSG:31297</SRS>' +\n'      <SRS>EPSG:31300</SRS>' +\n'      <SRS>EPSG:31370</SRS>' +\n'      <SRS>EPSG:31461</SRS>' +\n'      <SRS>EPSG:31462</SRS>' +\n'      <SRS>EPSG:31463</SRS>' +\n'      <SRS>EPSG:31464</SRS>' +\n'      <SRS>EPSG:31465</SRS>' +\n'      <SRS>EPSG:31466</SRS>' +\n'      <SRS>EPSG:31467</SRS>' +\n'      <SRS>EPSG:31468</SRS>' +\n'      <SRS>EPSG:31469</SRS>' +\n'      <SRS>EPSG:31528</SRS>' +\n'      <SRS>EPSG:31529</SRS>' +\n'      <SRS>EPSG:31600</SRS>' +\n'      <SRS>EPSG:31700</SRS>' +\n'      <SRS>EPSG:31838</SRS>' +\n'      <SRS>EPSG:31839</SRS>' +\n'      <SRS>EPSG:31900</SRS>' +\n'      <SRS>EPSG:31901</SRS>' +\n'      <SRS>EPSG:31965</SRS>' +\n'      <SRS>EPSG:31966</SRS>' +\n'      <SRS>EPSG:31967</SRS>' +\n'      <SRS>EPSG:31968</SRS>' +\n'      <SRS>EPSG:31969</SRS>' +\n'      <SRS>EPSG:31970</SRS>' +\n'      <SRS>EPSG:31971</SRS>' +\n'      <SRS>EPSG:31972</SRS>' +\n'      <SRS>EPSG:31973</SRS>' +\n'      <SRS>EPSG:31974</SRS>' +\n'      <SRS>EPSG:31975</SRS>' +\n'      <SRS>EPSG:31976</SRS>' +\n'      <SRS>EPSG:31977</SRS>' +\n'      <SRS>EPSG:31978</SRS>' +\n'      <SRS>EPSG:31979</SRS>' +\n'      <SRS>EPSG:31980</SRS>' +\n'      <SRS>EPSG:31981</SRS>' +\n'      <SRS>EPSG:31982</SRS>' +\n'      <SRS>EPSG:31983</SRS>' +\n'      <SRS>EPSG:31984</SRS>' +\n'      <SRS>EPSG:31985</SRS>' +\n'      <SRS>EPSG:31986</SRS>' +\n'      <SRS>EPSG:31987</SRS>' +\n'      <SRS>EPSG:31988</SRS>' +\n'      <SRS>EPSG:31989</SRS>' +\n'      <SRS>EPSG:31990</SRS>' +\n'      <SRS>EPSG:31991</SRS>' +\n'      <SRS>EPSG:31992</SRS>' +\n'      <SRS>EPSG:31993</SRS>' +\n'      <SRS>EPSG:31994</SRS>' +\n'      <SRS>EPSG:31995</SRS>' +\n'      <SRS>EPSG:31996</SRS>' +\n'      <SRS>EPSG:31997</SRS>' +\n'      <SRS>EPSG:31998</SRS>' +\n'      <SRS>EPSG:31999</SRS>' +\n'      <SRS>EPSG:32000</SRS>' +\n'      <SRS>EPSG:32001</SRS>' +\n'      <SRS>EPSG:32002</SRS>' +\n'      <SRS>EPSG:32003</SRS>' +\n'      <SRS>EPSG:32005</SRS>' +\n'      <SRS>EPSG:32006</SRS>' +\n'      <SRS>EPSG:32007</SRS>' +\n'      <SRS>EPSG:32008</SRS>' +\n'      <SRS>EPSG:32009</SRS>' +\n'      <SRS>EPSG:32010</SRS>' +\n'      <SRS>EPSG:32011</SRS>' +\n'      <SRS>EPSG:32012</SRS>' +\n'      <SRS>EPSG:32013</SRS>' +\n'      <SRS>EPSG:32014</SRS>' +\n'      <SRS>EPSG:32015</SRS>' +\n'      <SRS>EPSG:32016</SRS>' +\n'      <SRS>EPSG:32017</SRS>' +\n'      <SRS>EPSG:32018</SRS>' +\n'      <SRS>EPSG:32019</SRS>' +\n'      <SRS>EPSG:32020</SRS>' +\n'      <SRS>EPSG:32021</SRS>' +\n'      <SRS>EPSG:32022</SRS>' +\n'      <SRS>EPSG:32023</SRS>' +\n'      <SRS>EPSG:32024</SRS>' +\n'      <SRS>EPSG:32025</SRS>' +\n'      <SRS>EPSG:32026</SRS>' +\n'      <SRS>EPSG:32027</SRS>' +\n'      <SRS>EPSG:32028</SRS>' +\n'      <SRS>EPSG:32029</SRS>' +\n'      <SRS>EPSG:32030</SRS>' +\n'      <SRS>EPSG:32031</SRS>' +\n'      <SRS>EPSG:32033</SRS>' +\n'      <SRS>EPSG:32034</SRS>' +\n'      <SRS>EPSG:32035</SRS>' +\n'      <SRS>EPSG:32036</SRS>' +\n'      <SRS>EPSG:32037</SRS>' +\n'      <SRS>EPSG:32038</SRS>' +\n'      <SRS>EPSG:32039</SRS>' +\n'      <SRS>EPSG:32040</SRS>' +\n'      <SRS>EPSG:32041</SRS>' +\n'      <SRS>EPSG:32042</SRS>' +\n'      <SRS>EPSG:32043</SRS>' +\n'      <SRS>EPSG:32044</SRS>' +\n'      <SRS>EPSG:32045</SRS>' +\n'      <SRS>EPSG:32046</SRS>' +\n'      <SRS>EPSG:32047</SRS>' +\n'      <SRS>EPSG:32048</SRS>' +\n'      <SRS>EPSG:32049</SRS>' +\n'      <SRS>EPSG:32050</SRS>' +\n'      <SRS>EPSG:32051</SRS>' +\n'      <SRS>EPSG:32052</SRS>' +\n'      <SRS>EPSG:32053</SRS>' +\n'      <SRS>EPSG:32054</SRS>' +\n'      <SRS>EPSG:32055</SRS>' +\n'      <SRS>EPSG:32056</SRS>' +\n'      <SRS>EPSG:32057</SRS>' +\n'      <SRS>EPSG:32058</SRS>' +\n'      <SRS>EPSG:32061</SRS>' +\n'      <SRS>EPSG:32062</SRS>' +\n'      <SRS>EPSG:32064</SRS>' +\n'      <SRS>EPSG:32065</SRS>' +\n'      <SRS>EPSG:32066</SRS>' +\n'      <SRS>EPSG:32067</SRS>' +\n'      <SRS>EPSG:32074</SRS>' +\n'      <SRS>EPSG:32075</SRS>' +\n'      <SRS>EPSG:32076</SRS>' +\n'      <SRS>EPSG:32077</SRS>' +\n'      <SRS>EPSG:32081</SRS>' +\n'      <SRS>EPSG:32082</SRS>' +\n'      <SRS>EPSG:32083</SRS>' +\n'      <SRS>EPSG:32084</SRS>' +\n'      <SRS>EPSG:32085</SRS>' +\n'      <SRS>EPSG:32086</SRS>' +\n'      <SRS>EPSG:32098</SRS>' +\n'      <SRS>EPSG:32099</SRS>' +\n'      <SRS>EPSG:32100</SRS>' +\n'      <SRS>EPSG:32104</SRS>' +\n'      <SRS>EPSG:32107</SRS>' +\n'      <SRS>EPSG:32108</SRS>' +\n'      <SRS>EPSG:32109</SRS>' +\n'      <SRS>EPSG:32110</SRS>' +\n'      <SRS>EPSG:32111</SRS>' +\n'      <SRS>EPSG:32112</SRS>' +\n'      <SRS>EPSG:32113</SRS>' +\n'      <SRS>EPSG:32114</SRS>' +\n'      <SRS>EPSG:32115</SRS>' +\n'      <SRS>EPSG:32116</SRS>' +\n'      <SRS>EPSG:32117</SRS>' +\n'      <SRS>EPSG:32118</SRS>' +\n'      <SRS>EPSG:32119</SRS>' +\n'      <SRS>EPSG:32120</SRS>' +\n'      <SRS>EPSG:32121</SRS>' +\n'      <SRS>EPSG:32122</SRS>' +\n'      <SRS>EPSG:32123</SRS>' +\n'      <SRS>EPSG:32124</SRS>' +\n'      <SRS>EPSG:32125</SRS>' +\n'      <SRS>EPSG:32126</SRS>' +\n'      <SRS>EPSG:32127</SRS>' +\n'      <SRS>EPSG:32128</SRS>' +\n'      <SRS>EPSG:32129</SRS>' +\n'      <SRS>EPSG:32130</SRS>' +\n'      <SRS>EPSG:32133</SRS>' +\n'      <SRS>EPSG:32134</SRS>' +\n'      <SRS>EPSG:32135</SRS>' +\n'      <SRS>EPSG:32136</SRS>' +\n'      <SRS>EPSG:32137</SRS>' +\n'      <SRS>EPSG:32138</SRS>' +\n'      <SRS>EPSG:32139</SRS>' +\n'      <SRS>EPSG:32140</SRS>' +\n'      <SRS>EPSG:32141</SRS>' +\n'      <SRS>EPSG:32142</SRS>' +\n'      <SRS>EPSG:32143</SRS>' +\n'      <SRS>EPSG:32144</SRS>' +\n'      <SRS>EPSG:32145</SRS>' +\n'      <SRS>EPSG:32146</SRS>' +\n'      <SRS>EPSG:32147</SRS>' +\n'      <SRS>EPSG:32148</SRS>' +\n'      <SRS>EPSG:32149</SRS>' +\n'      <SRS>EPSG:32150</SRS>' +\n'      <SRS>EPSG:32151</SRS>' +\n'      <SRS>EPSG:32152</SRS>' +\n'      <SRS>EPSG:32153</SRS>' +\n'      <SRS>EPSG:32154</SRS>' +\n'      <SRS>EPSG:32155</SRS>' +\n'      <SRS>EPSG:32156</SRS>' +\n'      <SRS>EPSG:32157</SRS>' +\n'      <SRS>EPSG:32158</SRS>' +\n'      <SRS>EPSG:32161</SRS>' +\n'      <SRS>EPSG:32164</SRS>' +\n'      <SRS>EPSG:32165</SRS>' +\n'      <SRS>EPSG:32166</SRS>' +\n'      <SRS>EPSG:32167</SRS>' +\n'      <SRS>EPSG:32180</SRS>' +\n'      <SRS>EPSG:32181</SRS>' +\n'      <SRS>EPSG:32182</SRS>' +\n'      <SRS>EPSG:32183</SRS>' +\n'      <SRS>EPSG:32184</SRS>' +\n'      <SRS>EPSG:32185</SRS>' +\n'      <SRS>EPSG:32186</SRS>' +\n'      <SRS>EPSG:32187</SRS>' +\n'      <SRS>EPSG:32188</SRS>' +\n'      <SRS>EPSG:32189</SRS>' +\n'      <SRS>EPSG:32190</SRS>' +\n'      <SRS>EPSG:32191</SRS>' +\n'      <SRS>EPSG:32192</SRS>' +\n'      <SRS>EPSG:32193</SRS>' +\n'      <SRS>EPSG:32194</SRS>' +\n'      <SRS>EPSG:32195</SRS>' +\n'      <SRS>EPSG:32196</SRS>' +\n'      <SRS>EPSG:32197</SRS>' +\n'      <SRS>EPSG:32198</SRS>' +\n'      <SRS>EPSG:32199</SRS>' +\n'      <SRS>EPSG:32201</SRS>' +\n'      <SRS>EPSG:32202</SRS>' +\n'      <SRS>EPSG:32203</SRS>' +\n'      <SRS>EPSG:32204</SRS>' +\n'      <SRS>EPSG:32205</SRS>' +\n'      <SRS>EPSG:32206</SRS>' +\n'      <SRS>EPSG:32207</SRS>' +\n'      <SRS>EPSG:32208</SRS>' +\n'      <SRS>EPSG:32209</SRS>' +\n'      <SRS>EPSG:32210</SRS>' +\n'      <SRS>EPSG:32211</SRS>' +\n'      <SRS>EPSG:32212</SRS>' +\n'      <SRS>EPSG:32213</SRS>' +\n'      <SRS>EPSG:32214</SRS>' +\n'      <SRS>EPSG:32215</SRS>' +\n'      <SRS>EPSG:32216</SRS>' +\n'      <SRS>EPSG:32217</SRS>' +\n'      <SRS>EPSG:32218</SRS>' +\n'      <SRS>EPSG:32219</SRS>' +\n'      <SRS>EPSG:32220</SRS>' +\n'      <SRS>EPSG:32221</SRS>' +\n'      <SRS>EPSG:32222</SRS>' +\n'      <SRS>EPSG:32223</SRS>' +\n'      <SRS>EPSG:32224</SRS>' +\n'      <SRS>EPSG:32225</SRS>' +\n'      <SRS>EPSG:32226</SRS>' +\n'      <SRS>EPSG:32227</SRS>' +\n'      <SRS>EPSG:32228</SRS>' +\n'      <SRS>EPSG:32229</SRS>' +\n'      <SRS>EPSG:32230</SRS>' +\n'      <SRS>EPSG:32231</SRS>' +\n'      <SRS>EPSG:32232</SRS>' +\n'      <SRS>EPSG:32233</SRS>' +\n'      <SRS>EPSG:32234</SRS>' +\n'      <SRS>EPSG:32235</SRS>' +\n'      <SRS>EPSG:32236</SRS>' +\n'      <SRS>EPSG:32237</SRS>' +\n'      <SRS>EPSG:32238</SRS>' +\n'      <SRS>EPSG:32239</SRS>' +\n'      <SRS>EPSG:32240</SRS>' +\n'      <SRS>EPSG:32241</SRS>' +\n'      <SRS>EPSG:32242</SRS>' +\n'      <SRS>EPSG:32243</SRS>' +\n'      <SRS>EPSG:32244</SRS>' +\n'      <SRS>EPSG:32245</SRS>' +\n'      <SRS>EPSG:32246</SRS>' +\n'      <SRS>EPSG:32247</SRS>' +\n'      <SRS>EPSG:32248</SRS>' +\n'      <SRS>EPSG:32249</SRS>' +\n'      <SRS>EPSG:32250</SRS>' +\n'      <SRS>EPSG:32251</SRS>' +\n'      <SRS>EPSG:32252</SRS>' +\n'      <SRS>EPSG:32253</SRS>' +\n'      <SRS>EPSG:32254</SRS>' +\n'      <SRS>EPSG:32255</SRS>' +\n'      <SRS>EPSG:32256</SRS>' +\n'      <SRS>EPSG:32257</SRS>' +\n'      <SRS>EPSG:32258</SRS>' +\n'      <SRS>EPSG:32259</SRS>' +\n'      <SRS>EPSG:32260</SRS>' +\n'      <SRS>EPSG:32301</SRS>' +\n'      <SRS>EPSG:32302</SRS>' +\n'      <SRS>EPSG:32303</SRS>' +\n'      <SRS>EPSG:32304</SRS>' +\n'      <SRS>EPSG:32305</SRS>' +\n'      <SRS>EPSG:32306</SRS>' +\n'      <SRS>EPSG:32307</SRS>' +\n'      <SRS>EPSG:32308</SRS>' +\n'      <SRS>EPSG:32309</SRS>' +\n'      <SRS>EPSG:32310</SRS>' +\n'      <SRS>EPSG:32311</SRS>' +\n'      <SRS>EPSG:32312</SRS>' +\n'      <SRS>EPSG:32313</SRS>' +\n'      <SRS>EPSG:32314</SRS>' +\n'      <SRS>EPSG:32315</SRS>' +\n'      <SRS>EPSG:32316</SRS>' +\n'      <SRS>EPSG:32317</SRS>' +\n'      <SRS>EPSG:32318</SRS>' +\n'      <SRS>EPSG:32319</SRS>' +\n'      <SRS>EPSG:32320</SRS>' +\n'      <SRS>EPSG:32321</SRS>' +\n'      <SRS>EPSG:32322</SRS>' +\n'      <SRS>EPSG:32323</SRS>' +\n'      <SRS>EPSG:32324</SRS>' +\n'      <SRS>EPSG:32325</SRS>' +\n'      <SRS>EPSG:32326</SRS>' +\n'      <SRS>EPSG:32327</SRS>' +\n'      <SRS>EPSG:32328</SRS>' +\n'      <SRS>EPSG:32329</SRS>' +\n'      <SRS>EPSG:32330</SRS>' +\n'      <SRS>EPSG:32331</SRS>' +\n'      <SRS>EPSG:32332</SRS>' +\n'      <SRS>EPSG:32333</SRS>' +\n'      <SRS>EPSG:32334</SRS>' +\n'      <SRS>EPSG:32335</SRS>' +\n'      <SRS>EPSG:32336</SRS>' +\n'      <SRS>EPSG:32337</SRS>' +\n'      <SRS>EPSG:32338</SRS>' +\n'      <SRS>EPSG:32339</SRS>' +\n'      <SRS>EPSG:32340</SRS>' +\n'      <SRS>EPSG:32341</SRS>' +\n'      <SRS>EPSG:32342</SRS>' +\n'      <SRS>EPSG:32343</SRS>' +\n'      <SRS>EPSG:32344</SRS>' +\n'      <SRS>EPSG:32345</SRS>' +\n'      <SRS>EPSG:32346</SRS>' +\n'      <SRS>EPSG:32347</SRS>' +\n'      <SRS>EPSG:32348</SRS>' +\n'      <SRS>EPSG:32349</SRS>' +\n'      <SRS>EPSG:32350</SRS>' +\n'      <SRS>EPSG:32351</SRS>' +\n'      <SRS>EPSG:32352</SRS>' +\n'      <SRS>EPSG:32353</SRS>' +\n'      <SRS>EPSG:32354</SRS>' +\n'      <SRS>EPSG:32355</SRS>' +\n'      <SRS>EPSG:32356</SRS>' +\n'      <SRS>EPSG:32357</SRS>' +\n'      <SRS>EPSG:32358</SRS>' +\n'      <SRS>EPSG:32359</SRS>' +\n'      <SRS>EPSG:32360</SRS>' +\n'      <SRS>EPSG:32401</SRS>' +\n'      <SRS>EPSG:32402</SRS>' +\n'      <SRS>EPSG:32403</SRS>' +\n'      <SRS>EPSG:32404</SRS>' +\n'      <SRS>EPSG:32405</SRS>' +\n'      <SRS>EPSG:32406</SRS>' +\n'      <SRS>EPSG:32407</SRS>' +\n'      <SRS>EPSG:32408</SRS>' +\n'      <SRS>EPSG:32409</SRS>' +\n'      <SRS>EPSG:32410</SRS>' +\n'      <SRS>EPSG:32411</SRS>' +\n'      <SRS>EPSG:32412</SRS>' +\n'      <SRS>EPSG:32413</SRS>' +\n'      <SRS>EPSG:32414</SRS>' +\n'      <SRS>EPSG:32415</SRS>' +\n'      <SRS>EPSG:32416</SRS>' +\n'      <SRS>EPSG:32417</SRS>' +\n'      <SRS>EPSG:32418</SRS>' +\n'      <SRS>EPSG:32419</SRS>' +\n'      <SRS>EPSG:32420</SRS>' +\n'      <SRS>EPSG:32421</SRS>' +\n'      <SRS>EPSG:32422</SRS>' +\n'      <SRS>EPSG:32423</SRS>' +\n'      <SRS>EPSG:32424</SRS>' +\n'      <SRS>EPSG:32425</SRS>' +\n'      <SRS>EPSG:32426</SRS>' +\n'      <SRS>EPSG:32427</SRS>' +\n'      <SRS>EPSG:32428</SRS>' +\n'      <SRS>EPSG:32429</SRS>' +\n'      <SRS>EPSG:32430</SRS>' +\n'      <SRS>EPSG:32431</SRS>' +\n'      <SRS>EPSG:32432</SRS>' +\n'      <SRS>EPSG:32433</SRS>' +\n'      <SRS>EPSG:32434</SRS>' +\n'      <SRS>EPSG:32435</SRS>' +\n'      <SRS>EPSG:32436</SRS>' +\n'      <SRS>EPSG:32437</SRS>' +\n'      <SRS>EPSG:32438</SRS>' +\n'      <SRS>EPSG:32439</SRS>' +\n'      <SRS>EPSG:32440</SRS>' +\n'      <SRS>EPSG:32441</SRS>' +\n'      <SRS>EPSG:32442</SRS>' +\n'      <SRS>EPSG:32443</SRS>' +\n'      <SRS>EPSG:32444</SRS>' +\n'      <SRS>EPSG:32445</SRS>' +\n'      <SRS>EPSG:32446</SRS>' +\n'      <SRS>EPSG:32447</SRS>' +\n'      <SRS>EPSG:32448</SRS>' +\n'      <SRS>EPSG:32449</SRS>' +\n'      <SRS>EPSG:32450</SRS>' +\n'      <SRS>EPSG:32451</SRS>' +\n'      <SRS>EPSG:32452</SRS>' +\n'      <SRS>EPSG:32453</SRS>' +\n'      <SRS>EPSG:32454</SRS>' +\n'      <SRS>EPSG:32455</SRS>' +\n'      <SRS>EPSG:32456</SRS>' +\n'      <SRS>EPSG:32457</SRS>' +\n'      <SRS>EPSG:32458</SRS>' +\n'      <SRS>EPSG:32459</SRS>' +\n'      <SRS>EPSG:32460</SRS>' +\n'      <SRS>EPSG:32501</SRS>' +\n'      <SRS>EPSG:32502</SRS>' +\n'      <SRS>EPSG:32503</SRS>' +\n'      <SRS>EPSG:32504</SRS>' +\n'      <SRS>EPSG:32505</SRS>' +\n'      <SRS>EPSG:32506</SRS>' +\n'      <SRS>EPSG:32507</SRS>' +\n'      <SRS>EPSG:32508</SRS>' +\n'      <SRS>EPSG:32509</SRS>' +\n'      <SRS>EPSG:32510</SRS>' +\n'      <SRS>EPSG:32511</SRS>' +\n'      <SRS>EPSG:32512</SRS>' +\n'      <SRS>EPSG:32513</SRS>' +\n'      <SRS>EPSG:32514</SRS>' +\n'      <SRS>EPSG:32515</SRS>' +\n'      <SRS>EPSG:32516</SRS>' +\n'      <SRS>EPSG:32517</SRS>' +\n'      <SRS>EPSG:32518</SRS>' +\n'      <SRS>EPSG:32519</SRS>' +\n'      <SRS>EPSG:32520</SRS>' +\n'      <SRS>EPSG:32521</SRS>' +\n'      <SRS>EPSG:32522</SRS>' +\n'      <SRS>EPSG:32523</SRS>' +\n'      <SRS>EPSG:32524</SRS>' +\n'      <SRS>EPSG:32525</SRS>' +\n'      <SRS>EPSG:32526</SRS>' +\n'      <SRS>EPSG:32527</SRS>' +\n'      <SRS>EPSG:32528</SRS>' +\n'      <SRS>EPSG:32529</SRS>' +\n'      <SRS>EPSG:32530</SRS>' +\n'      <SRS>EPSG:32531</SRS>' +\n'      <SRS>EPSG:32532</SRS>' +\n'      <SRS>EPSG:32533</SRS>' +\n'      <SRS>EPSG:32534</SRS>' +\n'      <SRS>EPSG:32535</SRS>' +\n'      <SRS>EPSG:32536</SRS>' +\n'      <SRS>EPSG:32537</SRS>' +\n'      <SRS>EPSG:32538</SRS>' +\n'      <SRS>EPSG:32539</SRS>' +\n'      <SRS>EPSG:32540</SRS>' +\n'      <SRS>EPSG:32541</SRS>' +\n'      <SRS>EPSG:32542</SRS>' +\n'      <SRS>EPSG:32543</SRS>' +\n'      <SRS>EPSG:32544</SRS>' +\n'      <SRS>EPSG:32545</SRS>' +\n'      <SRS>EPSG:32546</SRS>' +\n'      <SRS>EPSG:32547</SRS>' +\n'      <SRS>EPSG:32548</SRS>' +\n'      <SRS>EPSG:32549</SRS>' +\n'      <SRS>EPSG:32550</SRS>' +\n'      <SRS>EPSG:32551</SRS>' +\n'      <SRS>EPSG:32552</SRS>' +\n'      <SRS>EPSG:32553</SRS>' +\n'      <SRS>EPSG:32554</SRS>' +\n'      <SRS>EPSG:32555</SRS>' +\n'      <SRS>EPSG:32556</SRS>' +\n'      <SRS>EPSG:32557</SRS>' +\n'      <SRS>EPSG:32558</SRS>' +\n'      <SRS>EPSG:32559</SRS>' +\n'      <SRS>EPSG:32560</SRS>' +\n'      <SRS>EPSG:32600</SRS>' +\n'      <SRS>EPSG:32601</SRS>' +\n'      <SRS>EPSG:32602</SRS>' +\n'      <SRS>EPSG:32603</SRS>' +\n'      <SRS>EPSG:32604</SRS>' +\n'      <SRS>EPSG:32605</SRS>' +\n'      <SRS>EPSG:32606</SRS>' +\n'      <SRS>EPSG:32607</SRS>' +\n'      <SRS>EPSG:32608</SRS>' +\n'      <SRS>EPSG:32609</SRS>' +\n'      <SRS>EPSG:32610</SRS>' +\n'      <SRS>EPSG:32611</SRS>' +\n'      <SRS>EPSG:32612</SRS>' +\n'      <SRS>EPSG:32613</SRS>' +\n'      <SRS>EPSG:32614</SRS>' +\n'      <SRS>EPSG:32615</SRS>' +\n'      <SRS>EPSG:32616</SRS>' +\n'      <SRS>EPSG:32617</SRS>' +\n'      <SRS>EPSG:32618</SRS>' +\n'      <SRS>EPSG:32619</SRS>' +\n'      <SRS>EPSG:32620</SRS>' +\n'      <SRS>EPSG:32621</SRS>' +\n'      <SRS>EPSG:32622</SRS>' +\n'      <SRS>EPSG:32623</SRS>' +\n'      <SRS>EPSG:32624</SRS>' +\n'      <SRS>EPSG:32625</SRS>' +\n'      <SRS>EPSG:32626</SRS>' +\n'      <SRS>EPSG:32627</SRS>' +\n'      <SRS>EPSG:32628</SRS>' +\n'      <SRS>EPSG:32629</SRS>' +\n'      <SRS>EPSG:32630</SRS>' +\n'      <SRS>EPSG:32631</SRS>' +\n'      <SRS>EPSG:32632</SRS>' +\n'      <SRS>EPSG:32633</SRS>' +\n'      <SRS>EPSG:32634</SRS>' +\n'      <SRS>EPSG:32635</SRS>' +\n'      <SRS>EPSG:32636</SRS>' +\n'      <SRS>EPSG:32637</SRS>' +\n'      <SRS>EPSG:32638</SRS>' +\n'      <SRS>EPSG:32639</SRS>' +\n'      <SRS>EPSG:32640</SRS>' +\n'      <SRS>EPSG:32641</SRS>' +\n'      <SRS>EPSG:32642</SRS>' +\n'      <SRS>EPSG:32643</SRS>' +\n'      <SRS>EPSG:32644</SRS>' +\n'      <SRS>EPSG:32645</SRS>' +\n'      <SRS>EPSG:32646</SRS>' +\n'      <SRS>EPSG:32647</SRS>' +\n'      <SRS>EPSG:32648</SRS>' +\n'      <SRS>EPSG:32649</SRS>' +\n'      <SRS>EPSG:32650</SRS>' +\n'      <SRS>EPSG:32651</SRS>' +\n'      <SRS>EPSG:32652</SRS>' +\n'      <SRS>EPSG:32653</SRS>' +\n'      <SRS>EPSG:32654</SRS>' +\n'      <SRS>EPSG:32655</SRS>' +\n'      <SRS>EPSG:32656</SRS>' +\n'      <SRS>EPSG:32657</SRS>' +\n'      <SRS>EPSG:32658</SRS>' +\n'      <SRS>EPSG:32659</SRS>' +\n'      <SRS>EPSG:32660</SRS>' +\n'      <SRS>EPSG:32661</SRS>' +\n'      <SRS>EPSG:32662</SRS>' +\n'      <SRS>EPSG:32664</SRS>' +\n'      <SRS>EPSG:32665</SRS>' +\n'      <SRS>EPSG:32666</SRS>' +\n'      <SRS>EPSG:32667</SRS>' +\n'      <SRS>EPSG:32700</SRS>' +\n'      <SRS>EPSG:32701</SRS>' +\n'      <SRS>EPSG:32702</SRS>' +\n'      <SRS>EPSG:32703</SRS>' +\n'      <SRS>EPSG:32704</SRS>' +\n'      <SRS>EPSG:32705</SRS>' +\n'      <SRS>EPSG:32706</SRS>' +\n'      <SRS>EPSG:32707</SRS>' +\n'      <SRS>EPSG:32708</SRS>' +\n'      <SRS>EPSG:32709</SRS>' +\n'      <SRS>EPSG:32710</SRS>' +\n'      <SRS>EPSG:32711</SRS>' +\n'      <SRS>EPSG:32712</SRS>' +\n'      <SRS>EPSG:32713</SRS>' +\n'      <SRS>EPSG:32714</SRS>' +\n'      <SRS>EPSG:32715</SRS>' +\n'      <SRS>EPSG:32716</SRS>' +\n'      <SRS>EPSG:32717</SRS>' +\n'      <SRS>EPSG:32718</SRS>' +\n'      <SRS>EPSG:32719</SRS>' +\n'      <SRS>EPSG:32720</SRS>' +\n'      <SRS>EPSG:32721</SRS>' +\n'      <SRS>EPSG:32722</SRS>' +\n'      <SRS>EPSG:32723</SRS>' +\n'      <SRS>EPSG:32724</SRS>' +\n'      <SRS>EPSG:32725</SRS>' +\n'      <SRS>EPSG:32726</SRS>' +\n'      <SRS>EPSG:32727</SRS>' +\n'      <SRS>EPSG:32728</SRS>' +\n'      <SRS>EPSG:32729</SRS>' +\n'      <SRS>EPSG:32730</SRS>' +\n'      <SRS>EPSG:32731</SRS>' +\n'      <SRS>EPSG:32732</SRS>' +\n'      <SRS>EPSG:32733</SRS>' +\n'      <SRS>EPSG:32734</SRS>' +\n'      <SRS>EPSG:32735</SRS>' +\n'      <SRS>EPSG:32736</SRS>' +\n'      <SRS>EPSG:32737</SRS>' +\n'      <SRS>EPSG:32738</SRS>' +\n'      <SRS>EPSG:32739</SRS>' +\n'      <SRS>EPSG:32740</SRS>' +\n'      <SRS>EPSG:32741</SRS>' +\n'      <SRS>EPSG:32742</SRS>' +\n'      <SRS>EPSG:32743</SRS>' +\n'      <SRS>EPSG:32744</SRS>' +\n'      <SRS>EPSG:32745</SRS>' +\n'      <SRS>EPSG:32746</SRS>' +\n'      <SRS>EPSG:32747</SRS>' +\n'      <SRS>EPSG:32748</SRS>' +\n'      <SRS>EPSG:32749</SRS>' +\n'      <SRS>EPSG:32750</SRS>' +\n'      <SRS>EPSG:32751</SRS>' +\n'      <SRS>EPSG:32752</SRS>' +\n'      <SRS>EPSG:32753</SRS>' +\n'      <SRS>EPSG:32754</SRS>' +\n'      <SRS>EPSG:32755</SRS>' +\n'      <SRS>EPSG:32756</SRS>' +\n'      <SRS>EPSG:32757</SRS>' +\n'      <SRS>EPSG:32758</SRS>' +\n'      <SRS>EPSG:32759</SRS>' +\n'      <SRS>EPSG:32760</SRS>' +\n'      <SRS>EPSG:32761</SRS>' +\n'      <SRS>EPSG:32766</SRS>' +\n'      <SRS>EPSG:61206405</SRS>' +\n'      <SRS>EPSG:61216405</SRS>' +\n'      <SRS>EPSG:61226405</SRS>' +\n'      <SRS>EPSG:61236405</SRS>' +\n'      <SRS>EPSG:61246405</SRS>' +\n'      <SRS>EPSG:61266405</SRS>' +\n'      <SRS>EPSG:61266413</SRS>' +\n'      <SRS>EPSG:61276405</SRS>' +\n'      <SRS>EPSG:61286405</SRS>' +\n'      <SRS>EPSG:61296405</SRS>' +\n'      <SRS>EPSG:61306405</SRS>' +\n'      <SRS>EPSG:61306413</SRS>' +\n'      <SRS>EPSG:61316405</SRS>' +\n'      <SRS>EPSG:61326405</SRS>' +\n'      <SRS>EPSG:61336405</SRS>' +\n'      <SRS>EPSG:61346405</SRS>' +\n'      <SRS>EPSG:61356405</SRS>' +\n'      <SRS>EPSG:61366405</SRS>' +\n'      <SRS>EPSG:61376405</SRS>' +\n'      <SRS>EPSG:61386405</SRS>' +\n'      <SRS>EPSG:61396405</SRS>' +\n'      <SRS>EPSG:61406405</SRS>' +\n'      <SRS>EPSG:61406413</SRS>' +\n'      <SRS>EPSG:61416405</SRS>' +\n'      <SRS>EPSG:61426405</SRS>' +\n'      <SRS>EPSG:61436405</SRS>' +\n'      <SRS>EPSG:61446405</SRS>' +\n'      <SRS>EPSG:61456405</SRS>' +\n'      <SRS>EPSG:61466405</SRS>' +\n'      <SRS>EPSG:61476405</SRS>' +\n'      <SRS>EPSG:61486405</SRS>' +\n'      <SRS>EPSG:61486413</SRS>' +\n'      <SRS>EPSG:61496405</SRS>' +\n'      <SRS>EPSG:61506405</SRS>' +\n'      <SRS>EPSG:61516405</SRS>' +\n'      <SRS>EPSG:61516413</SRS>' +\n'      <SRS>EPSG:61526405</SRS>' +\n'      <SRS>EPSG:61526413</SRS>' +\n'      <SRS>EPSG:61536405</SRS>' +\n'      <SRS>EPSG:61546405</SRS>' +\n'      <SRS>EPSG:61556405</SRS>' +\n'      <SRS>EPSG:61566405</SRS>' +\n'      <SRS>EPSG:61576405</SRS>' +\n'      <SRS>EPSG:61586405</SRS>' +\n'      <SRS>EPSG:61596405</SRS>' +\n'      <SRS>EPSG:61606405</SRS>' +\n'      <SRS>EPSG:61616405</SRS>' +\n'      <SRS>EPSG:61626405</SRS>' +\n'      <SRS>EPSG:61636405</SRS>' +\n'      <SRS>EPSG:61636413</SRS>' +\n'      <SRS>EPSG:61646405</SRS>' +\n'      <SRS>EPSG:61656405</SRS>' +\n'      <SRS>EPSG:61666405</SRS>' +\n'      <SRS>EPSG:61676405</SRS>' +\n'      <SRS>EPSG:61676413</SRS>' +\n'      <SRS>EPSG:61686405</SRS>' +\n'      <SRS>EPSG:61696405</SRS>' +\n'      <SRS>EPSG:61706405</SRS>' +\n'      <SRS>EPSG:61706413</SRS>' +\n'      <SRS>EPSG:61716405</SRS>' +\n'      <SRS>EPSG:61716413</SRS>' +\n'      <SRS>EPSG:61736405</SRS>' +\n'      <SRS>EPSG:61736413</SRS>' +\n'      <SRS>EPSG:61746405</SRS>' +\n'      <SRS>EPSG:61756405</SRS>' +\n'      <SRS>EPSG:61766405</SRS>' +\n'      <SRS>EPSG:61766413</SRS>' +\n'      <SRS>EPSG:61786405</SRS>' +\n'      <SRS>EPSG:61796405</SRS>' +\n'      <SRS>EPSG:61806405</SRS>' +\n'      <SRS>EPSG:61806413</SRS>' +\n'      <SRS>EPSG:61816405</SRS>' +\n'      <SRS>EPSG:61826405</SRS>' +\n'      <SRS>EPSG:61836405</SRS>' +\n'      <SRS>EPSG:61846405</SRS>' +\n'      <SRS>EPSG:61886405</SRS>' +\n'      <SRS>EPSG:61896405</SRS>' +\n'      <SRS>EPSG:61896413</SRS>' +\n'      <SRS>EPSG:61906405</SRS>' +\n'      <SRS>EPSG:61906413</SRS>' +\n'      <SRS>EPSG:61916405</SRS>' +\n'      <SRS>EPSG:61926405</SRS>' +\n'      <SRS>EPSG:61936405</SRS>' +\n'      <SRS>EPSG:61946405</SRS>' +\n'      <SRS>EPSG:61956405</SRS>' +\n'      <SRS>EPSG:61966405</SRS>' +\n'      <SRS>EPSG:61976405</SRS>' +\n'      <SRS>EPSG:61986405</SRS>' +\n'      <SRS>EPSG:61996405</SRS>' +\n'      <SRS>EPSG:62006405</SRS>' +\n'      <SRS>EPSG:62016405</SRS>' +\n'      <SRS>EPSG:62026405</SRS>' +\n'      <SRS>EPSG:62036405</SRS>' +\n'      <SRS>EPSG:62046405</SRS>' +\n'      <SRS>EPSG:62056405</SRS>' +\n'      <SRS>EPSG:62066405</SRS>' +\n'      <SRS>EPSG:62076405</SRS>' +\n'      <SRS>EPSG:62086405</SRS>' +\n'      <SRS>EPSG:62096405</SRS>' +\n'      <SRS>EPSG:62106405</SRS>' +\n'      <SRS>EPSG:62116405</SRS>' +\n'      <SRS>EPSG:62126405</SRS>' +\n'      <SRS>EPSG:62136405</SRS>' +\n'      <SRS>EPSG:62146405</SRS>' +\n'      <SRS>EPSG:62156405</SRS>' +\n'      <SRS>EPSG:62166405</SRS>' +\n'      <SRS>EPSG:62186405</SRS>' +\n'      <SRS>EPSG:62196405</SRS>' +\n'      <SRS>EPSG:62206405</SRS>' +\n'      <SRS>EPSG:62216405</SRS>' +\n'      <SRS>EPSG:62226405</SRS>' +\n'      <SRS>EPSG:62236405</SRS>' +\n'      <SRS>EPSG:62246405</SRS>' +\n'      <SRS>EPSG:62256405</SRS>' +\n'      <SRS>EPSG:62276405</SRS>' +\n'      <SRS>EPSG:62296405</SRS>' +\n'      <SRS>EPSG:62306405</SRS>' +\n'      <SRS>EPSG:62316405</SRS>' +\n'      <SRS>EPSG:62326405</SRS>' +\n'      <SRS>EPSG:62336405</SRS>' +\n'      <SRS>EPSG:62366405</SRS>' +\n'      <SRS>EPSG:62376405</SRS>' +\n'      <SRS>EPSG:62386405</SRS>' +\n'      <SRS>EPSG:62396405</SRS>' +\n'      <SRS>EPSG:62406405</SRS>' +\n'      <SRS>EPSG:62416405</SRS>' +\n'      <SRS>EPSG:62426405</SRS>' +\n'      <SRS>EPSG:62436405</SRS>' +\n'      <SRS>EPSG:62446405</SRS>' +\n'      <SRS>EPSG:62456405</SRS>' +\n'      <SRS>EPSG:62466405</SRS>' +\n'      <SRS>EPSG:62476405</SRS>' +\n'      <SRS>EPSG:62486405</SRS>' +\n'      <SRS>EPSG:62496405</SRS>' +\n'      <SRS>EPSG:62506405</SRS>' +\n'      <SRS>EPSG:62516405</SRS>' +\n'      <SRS>EPSG:62526405</SRS>' +\n'      <SRS>EPSG:62536405</SRS>' +\n'      <SRS>EPSG:62546405</SRS>' +\n'      <SRS>EPSG:62556405</SRS>' +\n'      <SRS>EPSG:62566405</SRS>' +\n'      <SRS>EPSG:62576405</SRS>' +\n'      <SRS>EPSG:62586405</SRS>' +\n'      <SRS>EPSG:62586413</SRS>' +\n'      <SRS>EPSG:62596405</SRS>' +\n'      <SRS>EPSG:62616405</SRS>' +\n'      <SRS>EPSG:62626405</SRS>' +\n'      <SRS>EPSG:62636405</SRS>' +\n'      <SRS>EPSG:62646405</SRS>' +\n'      <SRS>EPSG:62656405</SRS>' +\n'      <SRS>EPSG:62666405</SRS>' +\n'      <SRS>EPSG:62676405</SRS>' +\n'      <SRS>EPSG:62686405</SRS>' +\n'      <SRS>EPSG:62696405</SRS>' +\n'      <SRS>EPSG:62706405</SRS>' +\n'      <SRS>EPSG:62716405</SRS>' +\n'      <SRS>EPSG:62726405</SRS>' +\n'      <SRS>EPSG:62736405</SRS>' +\n'      <SRS>EPSG:62746405</SRS>' +\n'      <SRS>EPSG:62756405</SRS>' +\n'      <SRS>EPSG:62766405</SRS>' +\n'      <SRS>EPSG:62776405</SRS>' +\n'      <SRS>EPSG:62786405</SRS>' +\n'      <SRS>EPSG:62796405</SRS>' +\n'      <SRS>EPSG:62806405</SRS>' +\n'      <SRS>EPSG:62816405</SRS>' +\n'      <SRS>EPSG:62826405</SRS>' +\n'      <SRS>EPSG:62836405</SRS>' +\n'      <SRS>EPSG:62836413</SRS>' +\n'      <SRS>EPSG:62846405</SRS>' +\n'      <SRS>EPSG:62856405</SRS>' +\n'      <SRS>EPSG:62866405</SRS>' +\n'      <SRS>EPSG:62886405</SRS>' +\n'      <SRS>EPSG:62896405</SRS>' +\n'      <SRS>EPSG:62926405</SRS>' +\n'      <SRS>EPSG:62936405</SRS>' +\n'      <SRS>EPSG:62956405</SRS>' +\n'      <SRS>EPSG:62976405</SRS>' +\n'      <SRS>EPSG:62986405</SRS>' +\n'      <SRS>EPSG:62996405</SRS>' +\n'      <SRS>EPSG:63006405</SRS>' +\n'      <SRS>EPSG:63016405</SRS>' +\n'      <SRS>EPSG:63026405</SRS>' +\n'      <SRS>EPSG:63036405</SRS>' +\n'      <SRS>EPSG:63046405</SRS>' +\n'      <SRS>EPSG:63066405</SRS>' +\n'      <SRS>EPSG:63076405</SRS>' +\n'      <SRS>EPSG:63086405</SRS>' +\n'      <SRS>EPSG:63096405</SRS>' +\n'      <SRS>EPSG:63106405</SRS>' +\n'      <SRS>EPSG:63116405</SRS>' +\n'      <SRS>EPSG:63126405</SRS>' +\n'      <SRS>EPSG:63136405</SRS>' +\n'      <SRS>EPSG:63146405</SRS>' +\n'      <SRS>EPSG:63156405</SRS>' +\n'      <SRS>EPSG:63166405</SRS>' +\n'      <SRS>EPSG:63176405</SRS>' +\n'      <SRS>EPSG:63186405</SRS>' +\n'      <SRS>EPSG:63196405</SRS>' +\n'      <SRS>EPSG:63226405</SRS>' +\n'      <SRS>EPSG:63246405</SRS>' +\n'      <SRS>EPSG:63266405</SRS>' +\n'      <SRS>EPSG:63266406</SRS>' +\n'      <SRS>EPSG:63266407</SRS>' +\n'      <SRS>EPSG:63266408</SRS>' +\n'      <SRS>EPSG:63266409</SRS>' +\n'      <SRS>EPSG:63266410</SRS>' +\n'      <SRS>EPSG:63266411</SRS>' +\n'      <SRS>EPSG:63266412</SRS>' +\n'      <SRS>EPSG:63266413</SRS>' +\n'      <SRS>EPSG:63266414</SRS>' +\n'      <SRS>EPSG:63266415</SRS>' +\n'      <SRS>EPSG:63266416</SRS>' +\n'      <SRS>EPSG:63266417</SRS>' +\n'      <SRS>EPSG:63266418</SRS>' +\n'      <SRS>EPSG:63266419</SRS>' +\n'      <SRS>EPSG:63266420</SRS>' +\n'      <SRS>EPSG:66006405</SRS>' +\n'      <SRS>EPSG:66016405</SRS>' +\n'      <SRS>EPSG:66026405</SRS>' +\n'      <SRS>EPSG:66036405</SRS>' +\n'      <SRS>EPSG:66046405</SRS>' +\n'      <SRS>EPSG:66056405</SRS>' +\n'      <SRS>EPSG:66066405</SRS>' +\n'      <SRS>EPSG:66076405</SRS>' +\n'      <SRS>EPSG:66086405</SRS>' +\n'      <SRS>EPSG:66096405</SRS>' +\n'      <SRS>EPSG:66106405</SRS>' +\n'      <SRS>EPSG:66116405</SRS>' +\n'      <SRS>EPSG:66126405</SRS>' +\n'      <SRS>EPSG:66126413</SRS>' +\n'      <SRS>EPSG:66136405</SRS>' +\n'      <SRS>EPSG:66146405</SRS>' +\n'      <SRS>EPSG:66156405</SRS>' +\n'      <SRS>EPSG:66166405</SRS>' +\n'      <SRS>EPSG:66186405</SRS>' +\n'      <SRS>EPSG:66196405</SRS>' +\n'      <SRS>EPSG:66196413</SRS>' +\n'      <SRS>EPSG:66206405</SRS>' +\n'      <SRS>EPSG:66216405</SRS>' +\n'      <SRS>EPSG:66226405</SRS>' +\n'      <SRS>EPSG:66236405</SRS>' +\n'      <SRS>EPSG:66246405</SRS>' +\n'      <SRS>EPSG:66246413</SRS>' +\n'      <SRS>EPSG:66256405</SRS>' +\n'      <SRS>EPSG:66266405</SRS>' +\n'      <SRS>EPSG:66276405</SRS>' +\n'      <SRS>EPSG:66276413</SRS>' +\n'      <SRS>EPSG:66286405</SRS>' +\n'      <SRS>EPSG:66296405</SRS>' +\n'      <SRS>EPSG:66306405</SRS>' +\n'      <SRS>EPSG:66316405</SRS>' +\n'      <SRS>EPSG:66326405</SRS>' +\n'      <SRS>EPSG:66336405</SRS>' +\n'      <SRS>EPSG:66346405</SRS>' +\n'      <SRS>EPSG:66356405</SRS>' +\n'      <SRS>EPSG:66366405</SRS>' +\n'      <SRS>EPSG:66376405</SRS>' +\n'      <SRS>EPSG:66386405</SRS>' +\n'      <SRS>EPSG:66396405</SRS>' +\n'      <SRS>EPSG:66406405</SRS>' +\n'      <SRS>EPSG:66406413</SRS>' +\n'      <SRS>EPSG:66416405</SRS>' +\n'      <SRS>EPSG:66426405</SRS>' +\n'      <SRS>EPSG:66436405</SRS>' +\n'      <SRS>EPSG:66446405</SRS>' +\n'      <SRS>EPSG:66456405</SRS>' +\n'      <SRS>EPSG:66456413</SRS>' +\n'      <SRS>EPSG:66466405</SRS>' +\n'      <SRS>EPSG:66576405</SRS>' +\n'      <SRS>EPSG:66586405</SRS>' +\n'      <SRS>EPSG:66596405</SRS>' +\n'      <SRS>EPSG:66596413</SRS>' +\n'      <SRS>EPSG:66606405</SRS>' +\n'      <SRS>EPSG:66616405</SRS>' +\n'      <SRS>EPSG:66616413</SRS>' +\n'      <SRS>EPSG:66636405</SRS>' +\n'      <SRS>EPSG:66646405</SRS>' +\n'      <SRS>EPSG:66656405</SRS>' +\n'      <SRS>EPSG:66666405</SRS>' +\n'      <SRS>EPSG:66676405</SRS>' +\n'      <SRS>EPSG:68016405</SRS>' +\n'      <SRS>EPSG:68026405</SRS>' +\n'      <SRS>EPSG:68036405</SRS>' +\n'      <SRS>EPSG:68046405</SRS>' +\n'      <SRS>EPSG:68056405</SRS>' +\n'      <SRS>EPSG:68066405</SRS>' +\n'      <SRS>EPSG:68086405</SRS>' +\n'      <SRS>EPSG:68096405</SRS>' +\n'      <SRS>EPSG:68136405</SRS>' +\n'      <SRS>EPSG:68146405</SRS>' +\n'      <SRS>EPSG:68156405</SRS>' +\n'      <SRS>EPSG:68186405</SRS>' +\n'      <SRS>EPSG:68206405</SRS>' +\n'      <SRS>EPSG:69036405</SRS>' +\n'      <SRS>EPSG:42302</SRS>' +\n'      <SRS>EPSG:42301</SRS>' +\n'      <SRS>EPSG:900913</SRS>' +\n'      <SRS>EPSG:45556</SRS>' +\n'      <SRS>EPSG:45555</SRS>' +\n'      <SRS>EPSG:54004</SRS>' +\n'      <SRS>EPSG:41001</SRS>' +\n'      <SRS>EPSG:42311</SRS>' +\n'      <SRS>EPSG:42310</SRS>' +\n'      <SRS>EPSG:18001</SRS>' +\n'      <SRS>EPSG:100003</SRS>' +\n'      <SRS>EPSG:42106</SRS>' +\n'      <SRS>EPSG:100002</SRS>' +\n'      <SRS>EPSG:42105</SRS>' +\n'      <SRS>EPSG:100001</SRS>' +\n'      <SRS>EPSG:42309</SRS>' +\n'      <SRS>EPSG:42104</SRS>' +\n'      <SRS>EPSG:42308</SRS>' +\n'      <SRS>EPSG:42103</SRS>' +\n'      <SRS>EPSG:42307</SRS>' +\n'      <SRS>EPSG:42102</SRS>' +\n'      <SRS>EPSG:42306</SRS>' +\n'      <SRS>EPSG:42101</SRS>' +\n'      <SRS>EPSG:42305</SRS>' +\n'      <SRS>EPSG:42304</SRS>' +\n'      <SRS>EPSG:42303</SRS>' +\n'      <LatLonBoundingBox minx=\"-297176.16529836657\" miny=\"-1.2694600326676274E7\" maxx=\"3.0016785704606913E7\" maxy=\"1.7619361543229006E7\"/>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>og:bugsites</Name>' +\n'        <Title/>' +\n'        <Abstract>Sample data from GRASS, bug sites location, Spearfish, South Dakota, USA</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>spearfish</Keyword>' +\n'          <Keyword>sfBugsites</Keyword>' +\n'          <Keyword>insects</Keyword>' +\n'          <Keyword>bugsites</Keyword>' +\n'          <Keyword>tiger_beetles</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:26713</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'PROJCS[\"NAD27 / UTM zone 13N\", ' +\n'  GEOGCS[\"NAD27\", ' +\n'    DATUM[\"North American Datum 1927\", ' +\n'      SPHEROID[\"Clarke 1866\", 6378206.4, 294.9786982138982, AUTHORITY[\"EPSG\",\"7008\"]], ' +\n'      TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], ' +\n'      AUTHORITY[\"EPSG\",\"6267\"]], ' +\n'    PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'    UNIT[\"degree\", 0.017453292519943295], ' +\n'    AXIS[\"Geodetic longitude\", EAST], ' +\n'    AXIS[\"Geodetic latitude\", NORTH], ' +\n'    AUTHORITY[\"EPSG\",\"4267\"]], ' +\n'  PROJECTION[\"Transverse Mercator\", AUTHORITY[\"EPSG\",\"9807\"]], ' +\n'  PARAMETER[\"central_meridian\", -105.0], ' +\n'  PARAMETER[\"latitude_of_origin\", 0.0], ' +\n'  PARAMETER[\"scale_factor\", 0.9996], ' +\n'  PARAMETER[\"false_easting\", 500000.0], ' +\n'  PARAMETER[\"false_northing\", 0.0], ' +\n'  UNIT[\"m\", 1.0], ' +\n'  AXIS[\"Easting\", EAST], ' +\n'  AXIS[\"Northing\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"26713\"]]-->' +\n'        <LatLonBoundingBox minx=\"-103.8701581843142\" miny=\"44.286540361238224\" maxx=\"-103.63532819794625\" maxy=\"44.52137034760618\"/>' +\n'        <BoundingBox SRS=\"EPSG:26713\" minx=\"590232.0\" miny=\"4914096.0\" maxx=\"608471.0\" maxy=\"4920512.0\"/>' +\n'        <Style>' +\n'          <Name>capitals</Name>' +\n'          <Title>Capital cities</Title>' +\n'          <Abstract/>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=og:bugsites\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>og:restricted</Name>' +\n'        <Title/>' +\n'        <Abstract>Sample data from GRASS, restricted areas, Spearfish, South Dakota, USA</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>spearfish</Keyword>' +\n'          <Keyword>restricted</Keyword>' +\n'          <Keyword>sfRestricted</Keyword>' +\n'          <Keyword>areas</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:26713</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'PROJCS[\"NAD27 / UTM zone 13N\", ' +\n'  GEOGCS[\"NAD27\", ' +\n'    DATUM[\"North American Datum 1927\", ' +\n'      SPHEROID[\"Clarke 1866\", 6378206.4, 294.9786982138982, AUTHORITY[\"EPSG\",\"7008\"]], ' +\n'      TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], ' +\n'      AUTHORITY[\"EPSG\",\"6267\"]], ' +\n'    PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'    UNIT[\"degree\", 0.017453292519943295], ' +\n'    AXIS[\"Geodetic longitude\", EAST], ' +\n'    AXIS[\"Geodetic latitude\", NORTH], ' +\n'    AUTHORITY[\"EPSG\",\"4267\"]], ' +\n'  PROJECTION[\"Transverse Mercator\", AUTHORITY[\"EPSG\",\"9807\"]], ' +\n'  PARAMETER[\"central_meridian\", -105.0], ' +\n'  PARAMETER[\"latitude_of_origin\", 0.0], ' +\n'  PARAMETER[\"scale_factor\", 0.9996], ' +\n'  PARAMETER[\"false_easting\", 500000.0], ' +\n'  PARAMETER[\"false_northing\", 0.0], ' +\n'  UNIT[\"m\", 1.0], ' +\n'  AXIS[\"Easting\", EAST], ' +\n'  AXIS[\"Northing\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"26713\"]]-->' +\n'        <LatLonBoundingBox minx=\"-104.36424600670885\" miny=\"43.78798270975212\" maxx=\"-103.06226503558304\" maxy=\"45.089963680877936\"/>' +\n'        <BoundingBox SRS=\"EPSG:26713\" minx=\"551796.8125\" miny=\"4901896.0\" maxx=\"652788.5625\" maxy=\"4940954.0\"/>' +\n'        <Style>' +\n'          <Name>restricted</Name>' +\n'          <Title>Red, translucent style</Title>' +\n'          <Abstract>A sample style that just prints out a transparent red interior with a red outline</Abstract>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=og:restricted\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>og:archsites</Name>' +\n'        <Title/>' +\n'        <Abstract>Sample data from GRASS, archeological sites location, Spearfish, South Dakota, USA</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>archsites</Keyword>' +\n'          <Keyword>spearfish</Keyword>' +\n'          <Keyword>sfArchsites</Keyword>' +\n'          <Keyword>archeology</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:26713</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'PROJCS[\"NAD27 / UTM zone 13N\", ' +\n'  GEOGCS[\"NAD27\", ' +\n'    DATUM[\"North American Datum 1927\", ' +\n'      SPHEROID[\"Clarke 1866\", 6378206.4, 294.9786982138982, AUTHORITY[\"EPSG\",\"7008\"]], ' +\n'      TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], ' +\n'      AUTHORITY[\"EPSG\",\"6267\"]], ' +\n'    PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'    UNIT[\"degree\", 0.017453292519943295], ' +\n'    AXIS[\"Geodetic longitude\", EAST], ' +\n'    AXIS[\"Geodetic latitude\", NORTH], ' +\n'    AUTHORITY[\"EPSG\",\"4267\"]], ' +\n'  PROJECTION[\"Transverse Mercator\", AUTHORITY[\"EPSG\",\"9807\"]], ' +\n'  PARAMETER[\"central_meridian\", -105.0], ' +\n'  PARAMETER[\"latitude_of_origin\", 0.0], ' +\n'  PARAMETER[\"scale_factor\", 0.9996], ' +\n'  PARAMETER[\"false_easting\", 500000.0], ' +\n'  PARAMETER[\"false_northing\", 0.0], ' +\n'  UNIT[\"m\", 1.0], ' +\n'  AXIS[\"Easting\", EAST], ' +\n'  AXIS[\"Northing\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"26713\"]]-->' +\n'        <LatLonBoundingBox minx=\"-103.87480459767542\" miny=\"44.31295793136913\" maxx=\"-103.63549073047534\" maxy=\"44.55227179856921\"/>' +\n'        <BoundingBox SRS=\"EPSG:26713\" minx=\"589860.0\" miny=\"4914479.0\" maxx=\"608355.0\" maxy=\"4926490.0\"/>' +\n'        <Style>' +\n'          <Name>point</Name>' +\n'          <Title>Default point</Title>' +\n'          <Abstract>A sample style that just prints out a 6px wide red square</Abstract>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=og:archsites\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>og:streams</Name>' +\n'        <Title/>' +\n'        <Abstract>Sample data from GRASS, streams, Spearfish, South Dakota, USA</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>spearfish</Keyword>' +\n'          <Keyword>sfStreams</Keyword>' +\n'          <Keyword>streams</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:26713</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'PROJCS[\"NAD27 / UTM zone 13N\", ' +\n'  GEOGCS[\"NAD27\", ' +\n'    DATUM[\"North American Datum 1927\", ' +\n'      SPHEROID[\"Clarke 1866\", 6378206.4, 294.9786982138982, AUTHORITY[\"EPSG\",\"7008\"]], ' +\n'      TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], ' +\n'      AUTHORITY[\"EPSG\",\"6267\"]], ' +\n'    PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'    UNIT[\"degree\", 0.017453292519943295], ' +\n'    AXIS[\"Geodetic longitude\", EAST], ' +\n'    AXIS[\"Geodetic latitude\", NORTH], ' +\n'    AUTHORITY[\"EPSG\",\"4267\"]], ' +\n'  PROJECTION[\"Transverse Mercator\", AUTHORITY[\"EPSG\",\"9807\"]], ' +\n'  PARAMETER[\"central_meridian\", -105.0], ' +\n'  PARAMETER[\"latitude_of_origin\", 0.0], ' +\n'  PARAMETER[\"scale_factor\", 0.9996], ' +\n'  PARAMETER[\"false_easting\", 500000.0], ' +\n'  PARAMETER[\"false_northing\", 0.0], ' +\n'  UNIT[\"m\", 1.0], ' +\n'  AXIS[\"Easting\", EAST], ' +\n'  AXIS[\"Northing\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"26713\"]]-->' +\n'        <LatLonBoundingBox minx=\"-103.88033574142051\" miny=\"44.30711172484593\" maxx=\"-103.62022283326024\" maxy=\"44.5672246330062\"/>' +\n'        <BoundingBox SRS=\"EPSG:26713\" minx=\"589443.0\" miny=\"4913935.0\" maxx=\"609526.75\" maxy=\"4928059.5\"/>' +\n'        <Style>' +\n'          <Name>simple_streams</Name>' +\n'          <Title>Default Styler for streams segments</Title>' +\n'          <Abstract>Blue lines, 2px wide</Abstract>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=og:streams\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>tiger:poly_landmarks</Name>' +\n'        <Title>Manhattan (NY) landmarks</Title>' +\n'        <Abstract>Manhattan landmarks, identifies water, lakes, parks, interesting buildilngs</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>DS_poly_landmarks</Keyword>' +\n'          <Keyword>landmarks</Keyword>' +\n'          <Keyword>manhattan</Keyword>' +\n'          <Keyword>poly_landmarks</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'GEOGCS[\"WGS 84\", ' +\n'  DATUM[\"World Geodetic System 1984\", ' +\n'    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], ' +\n'    AUTHORITY[\"EPSG\",\"6326\"]], ' +\n'  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'  UNIT[\"degree\", 0.017453292519943295], ' +\n'  AXIS[\"Geodetic longitude\", EAST], ' +\n'  AXIS[\"Geodetic latitude\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"4326\"]]-->' +\n'        <LatLonBoundingBox minx=\"-74.0828672737\" miny=\"40.67246384130001\" maxx=\"-73.8660689563\" maxy=\"40.8892621587\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"-74.047185\" miny=\"40.679648\" maxx=\"-73.90782\" maxy=\"40.882078\"/>' +\n'        <Style>' +\n'          <Name>poly_landmarks</Name>' +\n'          <Title>Default Styler</Title>' +\n'          <Abstract/>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tiger:poly_landmarks\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>tiger:poi</Name>' +\n'        <Title>Manhattan (NY) points of interest</Title>' +\n'        <Abstract>Points of interest in New York, New York (on Manhattan). One of the attributes contains the name of a file with a picture of the point of interest.</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>poi</Keyword>' +\n'          <Keyword>Manhattan</Keyword>' +\n'          <Keyword>DS_poi</Keyword>' +\n'          <Keyword>points_of_interest</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'GEOGCS[\"WGS 84\", ' +\n'  DATUM[\"World Geodetic System 1984\", ' +\n'    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], ' +\n'    AUTHORITY[\"EPSG\",\"6326\"]], ' +\n'  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'  UNIT[\"degree\", 0.017453292519943295], ' +\n'  AXIS[\"Geodetic longitude\", EAST], ' +\n'  AXIS[\"Geodetic latitude\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"4326\"]]-->' +\n'        <LatLonBoundingBox minx=\"-74.01244590356289\" miny=\"40.70750285086222\" maxx=\"-74.00795911725866\" maxy=\"40.711989637166425\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"-74.0118315772888\" miny=\"40.70754683896324\" maxx=\"-74.00153046439813\" maxy=\"40.719885123828675\"/>' +\n'        <Style>' +\n'          <Name>poi</Name>' +\n'          <Title>Points of interest</Title>' +\n'          <Abstract>Manhattan points of interest</Abstract>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tiger:poi\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>tiger:tiger_roads</Name>' +\n'        <Title>Manhattan (NY) roads</Title>' +\n'        <Abstract>Highly simplified road layout of Manhattan in New York..</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>DS_tiger_roads</Keyword>' +\n'          <Keyword>tiger_roads</Keyword>' +\n'          <Keyword>roads</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'GEOGCS[\"WGS 84\", ' +\n'  DATUM[\"World Geodetic System 1984\", ' +\n'    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], ' +\n'    AUTHORITY[\"EPSG\",\"6326\"]], ' +\n'  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'  UNIT[\"degree\", 0.017453292519943295], ' +\n'  AXIS[\"Geodetic longitude\", EAST], ' +\n'  AXIS[\"Geodetic latitude\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"4326\"]]-->' +\n'        <LatLonBoundingBox minx=\"-74.06603057\" miny=\"40.68228143\" maxx=\"-73.86819443\" maxy=\"40.880117569999996\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"-74.02722\" miny=\"40.684221\" maxx=\"-73.907005\" maxy=\"40.878178\"/>' +\n'        <Style>' +\n'          <Name>tiger_roads</Name>' +\n'          <Title>Default Styler</Title>' +\n'          <Abstract/>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tiger:tiger_roads\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>za:za_natural</Name>' +\n'        <Title>Natural Landmarks in South Africa</Title>' +\n'        <Abstract>This layer describes natural features of South Africa such as forests and lakes.</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>water</Keyword>' +\n'          <Keyword>forests</Keyword>' +\n'          <Keyword>landmarks</Keyword>' +\n'          <Keyword>Africa</Keyword>' +\n'          <Keyword>South</Keyword>' +\n'          <Keyword>natural</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'GEOGCS[\"WGS 84\", ' +\n'  DATUM[\"World Geodetic System 1984\", ' +\n'    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], ' +\n'    AUTHORITY[\"EPSG\",\"6326\"]], ' +\n'  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'  UNIT[\"degree\", 0.017453292519943295], ' +\n'  AXIS[\"Geodetic longitude\", EAST], ' +\n'  AXIS[\"Geodetic latitude\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"4326\"]]-->' +\n'        <LatLonBoundingBox minx=\"16.779241142272962\" miny=\"-36.53577846527099\" maxx=\"32.70336002349853\" maxy=\"-20.611659584045416\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"16.935359954834\" miny=\"-34.3737831115723\" maxx=\"32.5472412109375\" maxy=\"-22.7736549377441\"/>' +\n'        <Style>' +\n'          <Name>za_natural</Name>' +\n'          <Title>Default Styler</Title>' +\n'          <Abstract/>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=za:za_natural\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>za:za_points</Name>' +\n'        <Title>Points of Interest in South Africa</Title>' +\n'        <Abstract>Noteworthy locations such as hotels and tourist attractions in South Africa.</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>of</Keyword>' +\n'          <Keyword>tourist</Keyword>' +\n'          <Keyword>landmarks</Keyword>' +\n'          <Keyword>zoo</Keyword>' +\n'          <Keyword>cities</Keyword>' +\n'          <Keyword>interest</Keyword>' +\n'          <Keyword>attractions</Keyword>' +\n'          <Keyword>points</Keyword>' +\n'          <Keyword>hotel</Keyword>' +\n'          <Keyword>museum</Keyword>' +\n'          <Keyword>picnic</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'GEOGCS[\"WGS 84\", ' +\n'  DATUM[\"World Geodetic System 1984\", ' +\n'    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], ' +\n'    AUTHORITY[\"EPSG\",\"6326\"]], ' +\n'  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'  UNIT[\"degree\", 0.017453292519943295], ' +\n'  AXIS[\"Geodetic longitude\", EAST], ' +\n'  AXIS[\"Geodetic latitude\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"4326\"]]-->' +\n'        <LatLonBoundingBox minx=\"14.629095230102537\" miny=\"-47.151258316040014\" maxx=\"39.792314376831065\" maxy=\"-21.988039169311488\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"16.4827766418457\" miny=\"-46.9045600891113\" maxx=\"37.9386329650879\" maxy=\"-22.2347373962402\"/>' +\n'        <Style>' +\n'          <Name>za_points</Name>' +\n'          <Title>Default Styler</Title>' +\n'          <Abstract/>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=za:za_points\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>za:za_roads</Name>' +\n'        <Title>South African Roads</Title>' +\n'        <Abstract>This layer describes roads in South Africa.</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>south</Keyword>' +\n'          <Keyword>africa</Keyword>' +\n'          <Keyword>roads</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'GEOGCS[\"WGS 84\", ' +\n'  DATUM[\"World Geodetic System 1984\", ' +\n'    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], ' +\n'    AUTHORITY[\"EPSG\",\"6326\"]], ' +\n'  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'  UNIT[\"degree\", 0.017453292519943295], ' +\n'  AXIS[\"Geodetic longitude\", EAST], ' +\n'  AXIS[\"Geodetic latitude\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"4326\"]]-->' +\n'        <LatLonBoundingBox minx=\"16.29388177871706\" miny=\"-36.85438787460323\" maxx=\"33.04232465744013\" maxy=\"-20.10594499588016\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"16.4580821990967\" miny=\"-34.8331336975098\" maxx=\"32.8781242370605\" maxy=\"-22.1271991729736\"/>' +\n'        <Style>' +\n'          <Name>za_roads</Name>' +\n'          <Title>Default Styler</Title>' +\n'          <Abstract/>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=za:za_roads\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>za:za_vegetation</Name>' +\n'        <Title>South African Vegetation</Title>' +\n'        <Abstract>This layer describes vegetated areas in South Africa, categorized by biome.</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>south</Keyword>' +\n'          <Keyword>vegetation</Keyword>' +\n'          <Keyword>africa</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'GEOGCS[\"WGS 84\", ' +\n'  DATUM[\"World Geodetic System 1984\", ' +\n'    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], ' +\n'    AUTHORITY[\"EPSG\",\"6326\"]], ' +\n'  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'  UNIT[\"degree\", 0.017453292519943295], ' +\n'  AXIS[\"Geodetic longitude\", EAST], ' +\n'  AXIS[\"Geodetic latitude\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"4326\"]]-->' +\n'        <LatLonBoundingBox minx=\"16.30492322921758\" miny=\"-36.855452365875216\" maxx=\"33.05824930191042\" maxy=\"-20.102126293182376\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"16.4691715240479\" miny=\"-34.8336486816406\" maxx=\"32.8940010070801\" maxy=\"-22.123929977417\"/>' +\n'        <Style>' +\n'          <Name>za_vegetation</Name>' +\n'          <Title>Default Styler</Title>' +\n'          <Abstract/>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=za:za_vegetation\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>topp:tasmania_cities</Name>' +\n'        <Title>Tasmania cities</Title>' +\n'        <Abstract>Cities in Tasmania (actually, just the capital)</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>cities</Keyword>' +\n'          <Keyword>Tasmania</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'GEOGCS[\"WGS 84\", ' +\n'  DATUM[\"World Geodetic System 1984\", ' +\n'    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], ' +\n'    AUTHORITY[\"EPSG\",\"6326\"]], ' +\n'  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'  UNIT[\"degree\", 0.017453292519943295], ' +\n'  AXIS[\"Geodetic longitude\", EAST], ' +\n'  AXIS[\"Geodetic latitude\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"4326\"]]-->' +\n'        <LatLonBoundingBox minx=\"145.1667856\" miny=\"-43.706631400000006\" maxx=\"148.30373440000002\" maxy=\"-40.56968259999999\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"147.2910004483\" miny=\"-42.851001816890005\" maxx=\"147.2910004483\" maxy=\"-42.851001816890005\"/>' +\n'        <Style>' +\n'          <Name>capitals</Name>' +\n'          <Title>Capital cities</Title>' +\n'          <Abstract/>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:tasmania_cities\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>topp:tasmania_roads</Name>' +\n'        <Title>Tasmania roads</Title>' +\n'        <Abstract>Main Tasmania roads</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>Roads</Keyword>' +\n'          <Keyword>Tasmania</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'GEOGCS[\"WGS 84\", ' +\n'  DATUM[\"World Geodetic System 1984\", ' +\n'    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], ' +\n'    AUTHORITY[\"EPSG\",\"6326\"]], ' +\n'  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'  UNIT[\"degree\", 0.017453292519943295], ' +\n'  AXIS[\"Geodetic longitude\", EAST], ' +\n'  AXIS[\"Geodetic latitude\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"4326\"]]-->' +\n'        <LatLonBoundingBox minx=\"145.1667856\" miny=\"-43.706631400000006\" maxx=\"148.30373440000002\" maxy=\"-40.56968259999999\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"145.19754\" miny=\"-43.423512\" maxx=\"148.27298000000002\" maxy=\"-40.852802\"/>' +\n'        <Style>' +\n'          <Name>simple_roads</Name>' +\n'          <Title>Default Styler for simple road segments</Title>' +\n'          <Abstract>Light red line, 2px wide</Abstract>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:tasmania_roads\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>topp:tasmania_state_boundaries</Name>' +\n'        <Title>Tasmania state boundaries</Title>' +\n'        <Abstract>Tasmania state boundaries</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>boundaries</Keyword>' +\n'          <Keyword>tasmania_state_boundaries</Keyword>' +\n'          <Keyword>Tasmania</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'GEOGCS[\"WGS 84\", ' +\n'  DATUM[\"World Geodetic System 1984\", ' +\n'    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], ' +\n'    AUTHORITY[\"EPSG\",\"6326\"]], ' +\n'  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'  UNIT[\"degree\", 0.017453292519943295], ' +\n'  AXIS[\"Geodetic longitude\", EAST], ' +\n'  AXIS[\"Geodetic latitude\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"4326\"]]-->' +\n'        <LatLonBoundingBox minx=\"143.74100879660003\" miny=\"-44.026947203400006\" maxx=\"148.57295620340003\" maxy=\"-39.194999796599994\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"143.83482400000003\" miny=\"-43.648056\" maxx=\"148.47914100000003\" maxy=\"-39.573891\"/>' +\n'        <Style>' +\n'          <Name>green</Name>' +\n'          <Title>Green polygon</Title>' +\n'          <Abstract>Green fill with black outline</Abstract>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:tasmania_state_boundaries\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>topp:tasmania_water_bodies</Name>' +\n'        <Title>Tasmania water bodies</Title>' +\n'        <Abstract>Tasmania water bodies</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>Lakes</Keyword>' +\n'          <Keyword>Bodies</Keyword>' +\n'          <Keyword>Australia</Keyword>' +\n'          <Keyword>Water</Keyword>' +\n'          <Keyword>Tasmania</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'GEOGCS[\"WGS 84\", ' +\n'  DATUM[\"World Geodetic System 1984\", ' +\n'    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], ' +\n'    AUTHORITY[\"EPSG\",\"6326\"]], ' +\n'  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'  UNIT[\"degree\", 0.017453292519943295], ' +\n'  AXIS[\"Geodetic longitude\", EAST], ' +\n'  AXIS[\"Geodetic latitude\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"4326\"]]-->' +\n'        <LatLonBoundingBox minx=\"145.95490063999998\" miny=\"-43.04450786\" maxx=\"147.23641436\" maxy=\"-41.762994139999996\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"145.97161899999998\" miny=\"-43.031944\" maxx=\"147.219696\" maxy=\"-41.775558\"/>' +\n'        <Style>' +\n'          <Name>cite_lakes</Name>' +\n'          <Title>Blue lake</Title>' +\n'          <Abstract>A blue fill, solid black outline style</Abstract>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:tasmania_water_bodies\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>topp:states</Name>' +\n'        <Title>USA Population</Title>' +\n'        <Abstract>This is some census data on the states.</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>census</Keyword>' +\n'          <Keyword>united</Keyword>' +\n'          <Keyword>boundaries</Keyword>' +\n'          <Keyword>state</Keyword>' +\n'          <Keyword>states</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'GEOGCS[\"WGS 84\", ' +\n'  DATUM[\"World Geodetic System 1984\", ' +\n'    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], ' +\n'    AUTHORITY[\"EPSG\",\"6326\"]], ' +\n'  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'  UNIT[\"degree\", 0.017453292519943295], ' +\n'  AXIS[\"Geodetic longitude\", EAST], ' +\n'  AXIS[\"Geodetic latitude\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"4326\"]]-->' +\n'        <LatLonBoundingBox minx=\"-125.30903773\" miny=\"7.705448770000002\" maxx=\"-66.39223326999999\" maxy=\"66.62225323\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"-124.73142200000001\" miny=\"24.955967\" maxx=\"-66.969849\" maxy=\"49.371735\"/>' +\n'        <Style>' +\n'          <Name>population</Name>' +\n'          <Title>Population in the United States</Title>' +\n'          <Abstract>A sample filter that filters the United States into three' +\n'        categories of population, drawn in different colors</Abstract>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:states\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>tike:waterways</Name>' +\n'        <Title>Waterways</Title>' +\n'        <Abstract>Waterways in Finland.</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>Finland</Keyword>' +\n'          <Keyword>waterways</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'GEOGCS[\"WGS 84\", ' +\n'  DATUM[\"World Geodetic System 1984\", ' +\n'    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], ' +\n'    AUTHORITY[\"EPSG\",\"6326\"]], ' +\n'  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'  UNIT[\"degree\", 0.017453292519943295], ' +\n'  AXIS[\"Geodetic longitude\", EAST], ' +\n'  AXIS[\"Geodetic latitude\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"4326\"]]-->' +\n'        <LatLonBoundingBox minx=\"19.530168895721403\" miny=\"58.860618000030506\" maxx=\"31.6566005897522\" maxy=\"70.9870496940613\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"19.649055480957\" miny=\"59.9357719421387\" maxx=\"31.5377140045166\" maxy=\"69.9118957519531\"/>' +\n'        <Style>' +\n'          <Name>line</Name>' +\n'          <Title>1 px blue line</Title>' +\n'          <Abstract>Default line style, 1 pixel wide blue</Abstract>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tike:waterways\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>tike:railways</Name>' +\n'        <Title>roads_Type</Title>' +\n'        <Abstract>Generated from tike</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>tike</Keyword>' +\n'          <Keyword>roads</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'GEOGCS[\"WGS 84\", ' +\n'  DATUM[\"World Geodetic System 1984\", ' +\n'    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], ' +\n'    AUTHORITY[\"EPSG\",\"6326\"]], ' +\n'  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'  UNIT[\"degree\", 0.017453292519943295], ' +\n'  AXIS[\"Geodetic longitude\", EAST], ' +\n'  AXIS[\"Geodetic latitude\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"4326\"]]-->' +\n'        <LatLonBoundingBox minx=\"-297176.16529836657\" miny=\"-1.2694600326676274E7\" maxx=\"3.0016785704606913E7\" maxy=\"1.7619361543229006E7\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"19.5393085479736\" miny=\"-2277.78344726562\" maxx=\"2.971959E7\" maxy=\"4927039.0\"/>' +\n'        <Style>' +\n'          <Name>line</Name>' +\n'          <Title>1 px blue line</Title>' +\n'          <Abstract>Default line style, 1 pixel wide blue</Abstract>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tike:railways\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>tike:roads</Name>' +\n'        <Title>roads_Type</Title>' +\n'        <Abstract>Generated from tike</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>tike</Keyword>' +\n'          <Keyword>roads</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'GEOGCS[\"WGS 84\", ' +\n'  DATUM[\"World Geodetic System 1984\", ' +\n'    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], ' +\n'    AUTHORITY[\"EPSG\",\"6326\"]], ' +\n'  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'  UNIT[\"degree\", 0.017453292519943295], ' +\n'  AXIS[\"Geodetic longitude\", EAST], ' +\n'  AXIS[\"Geodetic latitude\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"4326\"]]-->' +\n'        <LatLonBoundingBox minx=\"-297176.16529836657\" miny=\"-1.2694600326676274E7\" maxx=\"3.0016785704606913E7\" maxy=\"1.7619361543229006E7\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"19.5393085479736\" miny=\"-2277.78344726562\" maxx=\"2.971959E7\" maxy=\"4927039.0\"/>' +\n'        <Style>' +\n'          <Name>line</Name>' +\n'          <Title>1 px blue line</Title>' +\n'          <Abstract>Default line style, 1 pixel wide blue</Abstract>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tike:roads\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>og:roads</Name>' +\n'        <Title>roads_Type</Title>' +\n'        <Abstract>Generated from sf_reset</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>roads</Keyword>' +\n'          <Keyword>sf_reset</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:26713</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'PROJCS[\"NAD27 / UTM zone 13N\", ' +\n'  GEOGCS[\"NAD27\", ' +\n'    DATUM[\"North American Datum 1927\", ' +\n'      SPHEROID[\"Clarke 1866\", 6378206.4, 294.9786982138982, AUTHORITY[\"EPSG\",\"7008\"]], ' +\n'      TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], ' +\n'      AUTHORITY[\"EPSG\",\"6267\"]], ' +\n'    PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'    UNIT[\"degree\", 0.017453292519943295], ' +\n'    AXIS[\"Geodetic longitude\", EAST], ' +\n'    AXIS[\"Geodetic latitude\", NORTH], ' +\n'    AUTHORITY[\"EPSG\",\"4267\"]], ' +\n'  PROJECTION[\"Transverse Mercator\", AUTHORITY[\"EPSG\",\"9807\"]], ' +\n'  PARAMETER[\"central_meridian\", -105.0], ' +\n'  PARAMETER[\"latitude_of_origin\", 0.0], ' +\n'  PARAMETER[\"scale_factor\", 0.9996], ' +\n'  PARAMETER[\"false_easting\", 500000.0], ' +\n'  PARAMETER[\"false_northing\", 0.0], ' +\n'  UNIT[\"m\", 1.0], ' +\n'  AXIS[\"Easting\", EAST], ' +\n'  AXIS[\"Northing\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"26713\"]]-->' +\n'        <LatLonBoundingBox minx=\"-103.88042792817339\" miny=\"44.308776913708805\" maxx=\"-103.62014761945467\" maxy=\"44.56905722242751\"/>' +\n'        <BoundingBox SRS=\"EPSG:26713\" minx=\"589434.8125\" miny=\"4914006.0\" maxx=\"609527.25\" maxy=\"4928377.0\"/>' +\n'        <Style>' +\n'          <Name>simple_roads</Name>' +\n'          <Title>Default Styler for simple road segments</Title>' +\n'          <Abstract>Light red line, 2px wide</Abstract>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=og:roads\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>tike:points</Name>' +\n'        <Title>roads_Type</Title>' +\n'        <Abstract>Generated from tike</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>tike</Keyword>' +\n'          <Keyword>roads</Keyword>' +\n'        </KeywordList>' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <!--WKT definition of this CRS:' +\n'GEOGCS[\"WGS 84\", ' +\n'  DATUM[\"World Geodetic System 1984\", ' +\n'    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], ' +\n'    AUTHORITY[\"EPSG\",\"6326\"]], ' +\n'  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'  UNIT[\"degree\", 0.017453292519943295], ' +\n'  AXIS[\"Geodetic longitude\", EAST], ' +\n'  AXIS[\"Geodetic latitude\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"4326\"]]-->' +\n'        <LatLonBoundingBox minx=\"19.73377216339108\" miny=\"59.107116584777835\" maxx=\"31.40053188323972\" maxy=\"70.77387630462647\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"19.8481521606445\" miny=\"59.8213005065918\" maxx=\"31.2861518859863\" maxy=\"70.0596923828125\"/>' +\n'        <Style>' +\n'          <Name>line</Name>' +\n'          <Title>1 px blue line</Title>' +\n'          <Abstract>Default line style, 1 pixel wide blue</Abstract>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tike:points\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>topp:bluemarble</Name>' +\n'        <Title>Blue Marble Imagery</Title>' +\n'        <Abstract>Blue Marble NG global bathymetry and topography data from NASA.  More information about the Blue Marble NG project is available from http://earthobservatory.nasa.gov/Features/BlueMarble .</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>WCS</Keyword>' +\n'          <Keyword>bluemarble</Keyword>' +\n'          <Keyword>bluemarble</Keyword>' +\n'        </KeywordList>' +\n'        <!--WKT definition of this CRS:' +\n'GEOGCS[\"WGS 84\", ' +\n'  DATUM[\"World Geodetic System 1984\", ' +\n'    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], ' +\n'    AUTHORITY[\"EPSG\",\"6326\"]], ' +\n'  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'  UNIT[\"degree\", 0.017453292519943295], ' +\n'  AXIS[\"Geodetic longitude\", EAST], ' +\n'  AXIS[\"Geodetic latitude\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"4326\"]]-->' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <LatLonBoundingBox minx=\"-180.00000003333\" miny=\"-89.99999996486703\" maxx=\"179.99999993067\" maxy=\"90.000000033333\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"-180.00000003333\" miny=\"-89.99999996486703\" maxx=\"179.99999993067\" maxy=\"90.000000033333\"/>' +\n'        <Style>' +\n'          <Name>raster</Name>' +\n'          <Title>Raster</Title>' +\n'          <Abstract>A sample style for rasters, good for displaying imagery</Abstract>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:bluemarble\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>nurc:Arc_Sample</Name>' +\n'        <Title>Global annual rainfall</Title>' +\n'        <Abstract>Global annual rainfall in ArcGrid format</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>WCS</Keyword>' +\n'          <Keyword>arcGridSample</Keyword>' +\n'          <Keyword>arcGridSample_Coverage</Keyword>' +\n'        </KeywordList>' +\n'        <!--WKT definition of this CRS:' +\n'GEOGCS[\"WGS 84\", ' +\n'  DATUM[\"World Geodetic System 1984\", ' +\n'    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], ' +\n'    AUTHORITY[\"EPSG\",\"6326\"]], ' +\n'  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'  UNIT[\"degree\", 0.017453292519943295], ' +\n'  AXIS[\"Geodetic longitude\", EAST], ' +\n'  AXIS[\"Geodetic latitude\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"4326\"]]-->' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <LatLonBoundingBox minx=\"-180.0\" miny=\"-90.0\" maxx=\"180.0\" maxy=\"90.0\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"-180.0\" miny=\"-90.0\" maxx=\"180.0\" maxy=\"90.0\"/>' +\n'        <Style>' +\n'          <Name>raster</Name>' +\n'          <Title>Raster</Title>' +\n'          <Abstract>A sample style for rasters, good for displaying imagery</Abstract>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=nurc:Arc_Sample\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>nurc:Img_Sample</Name>' +\n'        <Title>North America sample imagery</Title>' +\n'        <Abstract>A very rough imagery of North America</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>WCS</Keyword>' +\n'          <Keyword>worldImageSample</Keyword>' +\n'          <Keyword>worldImageSample_Coverage</Keyword>' +\n'        </KeywordList>' +\n'        <!--WKT definition of this CRS:' +\n'GEOGCS[\"WGS 84\", ' +\n'  DATUM[\"World Geodetic System 1984\", ' +\n'    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], ' +\n'    AUTHORITY[\"EPSG\",\"6326\"]], ' +\n'  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'  UNIT[\"degree\", 0.017453292519943295], ' +\n'  AXIS[\"Geodetic longitude\", EAST], ' +\n'  AXIS[\"Geodetic latitude\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"4326\"]]-->' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <LatLonBoundingBox minx=\"-130.85168\" miny=\"20.7052\" maxx=\"-62.0054\" maxy=\"54.1141\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"-130.85168\" miny=\"20.7052\" maxx=\"-62.0054\" maxy=\"54.1141\"/>' +\n'        <Style>' +\n'          <Name>raster</Name>' +\n'          <Title>Raster</Title>' +\n'          <Abstract>A sample style for rasters, good for displaying imagery</Abstract>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=nurc:Img_Sample\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"1\">' +\n'        <Name>sf:sfdem</Name>' +\n'        <Title>Spearfish DEM</Title>' +\n'        <Abstract>Digital Elevation Model data for Spearfish, South Dakota</Abstract>' +\n'        <KeywordList>' +\n'          <Keyword>WCS</Keyword>' +\n'          <Keyword>sf</Keyword>' +\n'          <Keyword>dem</Keyword>' +\n'          <Keyword>digital</Keyword>' +\n'          <Keyword>elevation</Keyword>' +\n'          <Keyword>model</Keyword>' +\n'        </KeywordList>' +\n'        <!--WKT definition of this CRS:' +\n'PROJCS[\"NAD27 / UTM zone 13N\", ' +\n'  GEOGCS[\"NAD27\", ' +\n'    DATUM[\"North American Datum 1927\", ' +\n'      SPHEROID[\"Clarke 1866\", 6378206.4, 294.9786982138982, AUTHORITY[\"EPSG\",\"7008\"]], ' +\n'      TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], ' +\n'      AUTHORITY[\"EPSG\",\"6267\"]], ' +\n'    PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], ' +\n'    UNIT[\"degree\", 0.017453292519943295], ' +\n'    AXIS[\"Geodetic longitude\", EAST], ' +\n'    AXIS[\"Geodetic latitude\", NORTH], ' +\n'    AUTHORITY[\"EPSG\",\"4267\"]], ' +\n'  PROJECTION[\"Transverse Mercator\", AUTHORITY[\"EPSG\",\"9807\"]], ' +\n'  PARAMETER[\"central_meridian\", -105.0], ' +\n'  PARAMETER[\"latitude_of_origin\", 0.0], ' +\n'  PARAMETER[\"scale_factor\", 0.9996], ' +\n'  PARAMETER[\"false_easting\", 500000.0], ' +\n'  PARAMETER[\"false_northing\", 0.0], ' +\n'  UNIT[\"m\", 1.0], ' +\n'  AXIS[\"Easting\", EAST], ' +\n'  AXIS[\"Northing\", NORTH], ' +\n'  AUTHORITY[\"EPSG\",\"26713\"]]-->' +\n'        <SRS>EPSG:26713</SRS>' +\n'        <LatLonBoundingBox minx=\"-103.87108701853181\" miny=\"44.370187074132616\" maxx=\"-103.62940739432703\" maxy=\"44.5016011535299\"/>' +\n'        <BoundingBox SRS=\"EPSG:26713\" minx=\"589980.0\" miny=\"4913700.0\" maxx=\"609000.0\" maxy=\"4928010.0\"/>' +\n'        <Style>' +\n'          <Name>dem</Name>' +\n'          <Title>Simple DEM style</Title>' +\n'          <Abstract>Classic elevation color progression</Abstract>' +\n'          <LegendURL width=\"20\" height=\"20\">' +\n'            <Format>image/png</Format>' +\n'            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=sf:sfdem\"/>' +\n'          </LegendURL>' +\n'        </Style>' +\n'      </Layer>' +\n'      <Layer queryable=\"0\">' +\n'        <Name>tasmania</Name>' +\n'        <Title>tasmania</Title>' +\n'        <Abstract>Layer-Group type layer: tasmania</Abstract>' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <LatLonBoundingBox minx=\"143.83482400000003\" miny=\"-43.648056\" maxx=\"148.47914100000003\" maxy=\"-39.573891\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"143.83482400000003\" miny=\"-43.648056\" maxx=\"148.47914100000003\" maxy=\"-39.573891\"/>' +\n'      </Layer>' +\n'      <Layer queryable=\"0\">' +\n'        <Name>tiger-ny</Name>' +\n'        <Title>tiger-ny</Title>' +\n'        <Abstract>Layer-Group type layer: tiger-ny</Abstract>' +\n'        <SRS>EPSG:4326</SRS>' +\n'        <LatLonBoundingBox minx=\"-74.047185\" miny=\"40.679648\" maxx=\"-73.907005\" maxy=\"40.882078\"/>' +\n'        <BoundingBox SRS=\"EPSG:4326\" minx=\"-74.047185\" miny=\"40.679648\" maxx=\"-73.907005\" maxy=\"40.882078\"/>' +\n'      </Layer>' +\n'    </Layer>' +\n'  </Capability>' +\n'</WMT_MS_Capabilities>';\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/speed/wmscaps.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE WMT_MS_Capabilities SYSTEM \"http://demo.boundlessgeo.com/geoserver/schemas/wms/1.1.1/WMS_MS_Capabilities.dtd\">\n<WMT_MS_Capabilities version=\"1.1.1\" updateSequence=\"145\">\n  <Service>\n    <Name>OGC:WMS</Name>\n    <Title>GeoServer Web Map Service</Title>\n    <Abstract>A compliant implementation of WMS 1.1.1 plus most of the SLD 1.0 extension (dynamic styling). Can also generate PDF, SVG, KML, GeoRSS</Abstract>\n    <KeywordList>\n      <Keyword>WFS</Keyword>\n      <Keyword>WMS</Keyword>\n      <Keyword>GEOSERVER</Keyword>\n    </KeywordList>\n    <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms\"/>\n    <ContactInformation>\n      <ContactPersonPrimary>\n        <ContactPerson>Claudius Ptolomaeus</ContactPerson>\n        <ContactOrganization>The ancient geographes INC</ContactOrganization>\n      </ContactPersonPrimary>\n      <ContactPosition>Chief geographer</ContactPosition>\n      <ContactAddress>\n        <AddressType>Work</AddressType>\n        <Address/>\n        <City>Alexandria</City>\n        <StateOrProvince/>\n        <PostCode/>\n        <Country>Egypt</Country>\n      </ContactAddress>\n      <ContactVoiceTelephone/>\n      <ContactFacsimileTelephone/>\n      <ContactElectronicMailAddress>claudius.ptolomaeus@gmail.com</ContactElectronicMailAddress>\n    </ContactInformation>\n    <Fees>NONE</Fees>\n    <AccessConstraints>NONE</AccessConstraints>\n  </Service>\n  <Capability>\n    <Request>\n      <GetCapabilities>\n        <Format>application/vnd.ogc.wms_xml</Format>\n        <DCPType>\n          <HTTP>\n            <Get>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms?SERVICE=WMS&amp;\"/>\n            </Get>\n            <Post>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms?SERVICE=WMS&amp;\"/>\n            </Post>\n          </HTTP>\n        </DCPType>\n      </GetCapabilities>\n      <GetMap>\n        <Format>image/png</Format>\n        <Format>application/atom xml</Format>\n        <Format>application/atom+xml</Format>\n        <Format>application/openlayers</Format>\n        <Format>application/pdf</Format>\n        <Format>application/rss xml</Format>\n        <Format>application/rss+xml</Format>\n        <Format>application/vnd.google-earth.kml</Format>\n        <Format>application/vnd.google-earth.kml xml</Format>\n        <Format>application/vnd.google-earth.kml+xml</Format>\n        <Format>application/vnd.google-earth.kmz</Format>\n        <Format>application/vnd.google-earth.kmz xml</Format>\n        <Format>application/vnd.google-earth.kmz+xml</Format>\n        <Format>atom</Format>\n        <Format>image/geotiff</Format>\n        <Format>image/geotiff8</Format>\n        <Format>image/gif</Format>\n        <Format>image/jpeg</Format>\n        <Format>image/png8</Format>\n        <Format>image/svg</Format>\n        <Format>image/svg xml</Format>\n        <Format>image/svg+xml</Format>\n        <Format>image/tiff</Format>\n        <Format>image/tiff8</Format>\n        <Format>kml</Format>\n        <Format>kmz</Format>\n        <Format>openlayers</Format>\n        <Format>rss</Format>\n        <DCPType>\n          <HTTP>\n            <Get>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms?SERVICE=WMS&amp;\"/>\n            </Get>\n          </HTTP>\n        </DCPType>\n      </GetMap>\n      <GetFeatureInfo>\n        <Format>text/plain</Format>\n        <Format>text/html</Format>\n        <Format>application/vnd.ogc.gml</Format>\n        <DCPType>\n          <HTTP>\n            <Get>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms?SERVICE=WMS&amp;\"/>\n            </Get>\n            <Post>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms?SERVICE=WMS&amp;\"/>\n            </Post>\n          </HTTP>\n        </DCPType>\n      </GetFeatureInfo>\n      <DescribeLayer>\n        <Format>application/vnd.ogc.wms_xml</Format>\n        <DCPType>\n          <HTTP>\n            <Get>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms?SERVICE=WMS&amp;\"/>\n            </Get>\n          </HTTP>\n        </DCPType>\n      </DescribeLayer>\n      <GetLegendGraphic>\n        <Format>image/png</Format>\n        <Format>image/jpeg</Format>\n        <Format>image/gif</Format>\n        <DCPType>\n          <HTTP>\n            <Get>\n              <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms?SERVICE=WMS&amp;\"/>\n            </Get>\n          </HTTP>\n        </DCPType>\n      </GetLegendGraphic>\n    </Request>\n    <Exception>\n      <Format>application/vnd.ogc.se_xml</Format>\n    </Exception>\n    <UserDefinedSymbolization SupportSLD=\"1\" UserLayer=\"1\" UserStyle=\"1\" RemoteWFS=\"1\"/>\n    <Layer>\n      <Title>GeoServer Web Map Service</Title>\n      <Abstract>A compliant implementation of WMS 1.1.1 plus most of the SLD 1.0 extension (dynamic styling). Can also generate PDF, SVG, KML, GeoRSS</Abstract>\n      <!--All supported EPSG projections:-->\n      <SRS>EPSG:WGS84(DD)</SRS>\n      <SRS>EPSG:2000</SRS>\n      <SRS>EPSG:2001</SRS>\n      <SRS>EPSG:2002</SRS>\n      <SRS>EPSG:2003</SRS>\n      <SRS>EPSG:2004</SRS>\n      <SRS>EPSG:2005</SRS>\n      <SRS>EPSG:2006</SRS>\n      <SRS>EPSG:2007</SRS>\n      <SRS>EPSG:2008</SRS>\n      <SRS>EPSG:2009</SRS>\n      <SRS>EPSG:2010</SRS>\n      <SRS>EPSG:2011</SRS>\n      <SRS>EPSG:2012</SRS>\n      <SRS>EPSG:2013</SRS>\n      <SRS>EPSG:2014</SRS>\n      <SRS>EPSG:2015</SRS>\n      <SRS>EPSG:2016</SRS>\n      <SRS>EPSG:2017</SRS>\n      <SRS>EPSG:2018</SRS>\n      <SRS>EPSG:2019</SRS>\n      <SRS>EPSG:2020</SRS>\n      <SRS>EPSG:2021</SRS>\n      <SRS>EPSG:2022</SRS>\n      <SRS>EPSG:2023</SRS>\n      <SRS>EPSG:2024</SRS>\n      <SRS>EPSG:2025</SRS>\n      <SRS>EPSG:2026</SRS>\n      <SRS>EPSG:2027</SRS>\n      <SRS>EPSG:2028</SRS>\n      <SRS>EPSG:2029</SRS>\n      <SRS>EPSG:2030</SRS>\n      <SRS>EPSG:2031</SRS>\n      <SRS>EPSG:2032</SRS>\n      <SRS>EPSG:2033</SRS>\n      <SRS>EPSG:2034</SRS>\n      <SRS>EPSG:2035</SRS>\n      <SRS>EPSG:2036</SRS>\n      <SRS>EPSG:2037</SRS>\n      <SRS>EPSG:2038</SRS>\n      <SRS>EPSG:2039</SRS>\n      <SRS>EPSG:2040</SRS>\n      <SRS>EPSG:2041</SRS>\n      <SRS>EPSG:2042</SRS>\n      <SRS>EPSG:2043</SRS>\n      <SRS>EPSG:2044</SRS>\n      <SRS>EPSG:2045</SRS>\n      <SRS>EPSG:2046</SRS>\n      <SRS>EPSG:2047</SRS>\n      <SRS>EPSG:2048</SRS>\n      <SRS>EPSG:2049</SRS>\n      <SRS>EPSG:2050</SRS>\n      <SRS>EPSG:2051</SRS>\n      <SRS>EPSG:2052</SRS>\n      <SRS>EPSG:2053</SRS>\n      <SRS>EPSG:2054</SRS>\n      <SRS>EPSG:2055</SRS>\n      <SRS>EPSG:2056</SRS>\n      <SRS>EPSG:2057</SRS>\n      <SRS>EPSG:2058</SRS>\n      <SRS>EPSG:2059</SRS>\n      <SRS>EPSG:2060</SRS>\n      <SRS>EPSG:2061</SRS>\n      <SRS>EPSG:2062</SRS>\n      <SRS>EPSG:2063</SRS>\n      <SRS>EPSG:2064</SRS>\n      <SRS>EPSG:2065</SRS>\n      <SRS>EPSG:2066</SRS>\n      <SRS>EPSG:2067</SRS>\n      <SRS>EPSG:2068</SRS>\n      <SRS>EPSG:2069</SRS>\n      <SRS>EPSG:2070</SRS>\n      <SRS>EPSG:2071</SRS>\n      <SRS>EPSG:2072</SRS>\n      <SRS>EPSG:2073</SRS>\n      <SRS>EPSG:2074</SRS>\n      <SRS>EPSG:2075</SRS>\n      <SRS>EPSG:2076</SRS>\n      <SRS>EPSG:2077</SRS>\n      <SRS>EPSG:2078</SRS>\n      <SRS>EPSG:2079</SRS>\n      <SRS>EPSG:2080</SRS>\n      <SRS>EPSG:2081</SRS>\n      <SRS>EPSG:2082</SRS>\n      <SRS>EPSG:2083</SRS>\n      <SRS>EPSG:2084</SRS>\n      <SRS>EPSG:2085</SRS>\n      <SRS>EPSG:2086</SRS>\n      <SRS>EPSG:2087</SRS>\n      <SRS>EPSG:2088</SRS>\n      <SRS>EPSG:2089</SRS>\n      <SRS>EPSG:2090</SRS>\n      <SRS>EPSG:2091</SRS>\n      <SRS>EPSG:2092</SRS>\n      <SRS>EPSG:2093</SRS>\n      <SRS>EPSG:2094</SRS>\n      <SRS>EPSG:2095</SRS>\n      <SRS>EPSG:2096</SRS>\n      <SRS>EPSG:2097</SRS>\n      <SRS>EPSG:2098</SRS>\n      <SRS>EPSG:2099</SRS>\n      <SRS>EPSG:2100</SRS>\n      <SRS>EPSG:2101</SRS>\n      <SRS>EPSG:2102</SRS>\n      <SRS>EPSG:2103</SRS>\n      <SRS>EPSG:2104</SRS>\n      <SRS>EPSG:2105</SRS>\n      <SRS>EPSG:2106</SRS>\n      <SRS>EPSG:2107</SRS>\n      <SRS>EPSG:2108</SRS>\n      <SRS>EPSG:2109</SRS>\n      <SRS>EPSG:2110</SRS>\n      <SRS>EPSG:2111</SRS>\n      <SRS>EPSG:2112</SRS>\n      <SRS>EPSG:2113</SRS>\n      <SRS>EPSG:2114</SRS>\n      <SRS>EPSG:2115</SRS>\n      <SRS>EPSG:2116</SRS>\n      <SRS>EPSG:2117</SRS>\n      <SRS>EPSG:2118</SRS>\n      <SRS>EPSG:2119</SRS>\n      <SRS>EPSG:2120</SRS>\n      <SRS>EPSG:2121</SRS>\n      <SRS>EPSG:2122</SRS>\n      <SRS>EPSG:2123</SRS>\n      <SRS>EPSG:2124</SRS>\n      <SRS>EPSG:2125</SRS>\n      <SRS>EPSG:2126</SRS>\n      <SRS>EPSG:2127</SRS>\n      <SRS>EPSG:2128</SRS>\n      <SRS>EPSG:2129</SRS>\n      <SRS>EPSG:2130</SRS>\n      <SRS>EPSG:2131</SRS>\n      <SRS>EPSG:2132</SRS>\n      <SRS>EPSG:2133</SRS>\n      <SRS>EPSG:2134</SRS>\n      <SRS>EPSG:2135</SRS>\n      <SRS>EPSG:2136</SRS>\n      <SRS>EPSG:2137</SRS>\n      <SRS>EPSG:2138</SRS>\n      <SRS>EPSG:2139</SRS>\n      <SRS>EPSG:2140</SRS>\n      <SRS>EPSG:2141</SRS>\n      <SRS>EPSG:2142</SRS>\n      <SRS>EPSG:2143</SRS>\n      <SRS>EPSG:2144</SRS>\n      <SRS>EPSG:2145</SRS>\n      <SRS>EPSG:2146</SRS>\n      <SRS>EPSG:2147</SRS>\n      <SRS>EPSG:2148</SRS>\n      <SRS>EPSG:2149</SRS>\n      <SRS>EPSG:2150</SRS>\n      <SRS>EPSG:2151</SRS>\n      <SRS>EPSG:2152</SRS>\n      <SRS>EPSG:2153</SRS>\n      <SRS>EPSG:2154</SRS>\n      <SRS>EPSG:2155</SRS>\n      <SRS>EPSG:2156</SRS>\n      <SRS>EPSG:2157</SRS>\n      <SRS>EPSG:2158</SRS>\n      <SRS>EPSG:2159</SRS>\n      <SRS>EPSG:2160</SRS>\n      <SRS>EPSG:2161</SRS>\n      <SRS>EPSG:2162</SRS>\n      <SRS>EPSG:2163</SRS>\n      <SRS>EPSG:2164</SRS>\n      <SRS>EPSG:2165</SRS>\n      <SRS>EPSG:2166</SRS>\n      <SRS>EPSG:2167</SRS>\n      <SRS>EPSG:2168</SRS>\n      <SRS>EPSG:2169</SRS>\n      <SRS>EPSG:2170</SRS>\n      <SRS>EPSG:2171</SRS>\n      <SRS>EPSG:2172</SRS>\n      <SRS>EPSG:2173</SRS>\n      <SRS>EPSG:2174</SRS>\n      <SRS>EPSG:2175</SRS>\n      <SRS>EPSG:2176</SRS>\n      <SRS>EPSG:2177</SRS>\n      <SRS>EPSG:2178</SRS>\n      <SRS>EPSG:2179</SRS>\n      <SRS>EPSG:2180</SRS>\n      <SRS>EPSG:2188</SRS>\n      <SRS>EPSG:2189</SRS>\n      <SRS>EPSG:2190</SRS>\n      <SRS>EPSG:2191</SRS>\n      <SRS>EPSG:2192</SRS>\n      <SRS>EPSG:2193</SRS>\n      <SRS>EPSG:2194</SRS>\n      <SRS>EPSG:2195</SRS>\n      <SRS>EPSG:2196</SRS>\n      <SRS>EPSG:2197</SRS>\n      <SRS>EPSG:2198</SRS>\n      <SRS>EPSG:2199</SRS>\n      <SRS>EPSG:2200</SRS>\n      <SRS>EPSG:2201</SRS>\n      <SRS>EPSG:2202</SRS>\n      <SRS>EPSG:2203</SRS>\n      <SRS>EPSG:2204</SRS>\n      <SRS>EPSG:2205</SRS>\n      <SRS>EPSG:2206</SRS>\n      <SRS>EPSG:2207</SRS>\n      <SRS>EPSG:2208</SRS>\n      <SRS>EPSG:2209</SRS>\n      <SRS>EPSG:2210</SRS>\n      <SRS>EPSG:2211</SRS>\n      <SRS>EPSG:2212</SRS>\n      <SRS>EPSG:2213</SRS>\n      <SRS>EPSG:2214</SRS>\n      <SRS>EPSG:2215</SRS>\n      <SRS>EPSG:2216</SRS>\n      <SRS>EPSG:2217</SRS>\n      <SRS>EPSG:2218</SRS>\n      <SRS>EPSG:2219</SRS>\n      <SRS>EPSG:2220</SRS>\n      <SRS>EPSG:2221</SRS>\n      <SRS>EPSG:2222</SRS>\n      <SRS>EPSG:2223</SRS>\n      <SRS>EPSG:2224</SRS>\n      <SRS>EPSG:2225</SRS>\n      <SRS>EPSG:2226</SRS>\n      <SRS>EPSG:2227</SRS>\n      <SRS>EPSG:2228</SRS>\n      <SRS>EPSG:2229</SRS>\n      <SRS>EPSG:2230</SRS>\n      <SRS>EPSG:2231</SRS>\n      <SRS>EPSG:2232</SRS>\n      <SRS>EPSG:2233</SRS>\n      <SRS>EPSG:2234</SRS>\n      <SRS>EPSG:2235</SRS>\n      <SRS>EPSG:2236</SRS>\n      <SRS>EPSG:2237</SRS>\n      <SRS>EPSG:2238</SRS>\n      <SRS>EPSG:2239</SRS>\n      <SRS>EPSG:2240</SRS>\n      <SRS>EPSG:2241</SRS>\n      <SRS>EPSG:2242</SRS>\n      <SRS>EPSG:2243</SRS>\n      <SRS>EPSG:2244</SRS>\n      <SRS>EPSG:2245</SRS>\n      <SRS>EPSG:2246</SRS>\n      <SRS>EPSG:2247</SRS>\n      <SRS>EPSG:2248</SRS>\n      <SRS>EPSG:2249</SRS>\n      <SRS>EPSG:2250</SRS>\n      <SRS>EPSG:2251</SRS>\n      <SRS>EPSG:2252</SRS>\n      <SRS>EPSG:2253</SRS>\n      <SRS>EPSG:2254</SRS>\n      <SRS>EPSG:2255</SRS>\n      <SRS>EPSG:2256</SRS>\n      <SRS>EPSG:2257</SRS>\n      <SRS>EPSG:2258</SRS>\n      <SRS>EPSG:2259</SRS>\n      <SRS>EPSG:2260</SRS>\n      <SRS>EPSG:2261</SRS>\n      <SRS>EPSG:2262</SRS>\n      <SRS>EPSG:2263</SRS>\n      <SRS>EPSG:2264</SRS>\n      <SRS>EPSG:2265</SRS>\n      <SRS>EPSG:2266</SRS>\n      <SRS>EPSG:2267</SRS>\n      <SRS>EPSG:2268</SRS>\n      <SRS>EPSG:2269</SRS>\n      <SRS>EPSG:2270</SRS>\n      <SRS>EPSG:2271</SRS>\n      <SRS>EPSG:2272</SRS>\n      <SRS>EPSG:2273</SRS>\n      <SRS>EPSG:2274</SRS>\n      <SRS>EPSG:2275</SRS>\n      <SRS>EPSG:2276</SRS>\n      <SRS>EPSG:2277</SRS>\n      <SRS>EPSG:2278</SRS>\n      <SRS>EPSG:2279</SRS>\n      <SRS>EPSG:2280</SRS>\n      <SRS>EPSG:2281</SRS>\n      <SRS>EPSG:2282</SRS>\n      <SRS>EPSG:2283</SRS>\n      <SRS>EPSG:2284</SRS>\n      <SRS>EPSG:2285</SRS>\n      <SRS>EPSG:2286</SRS>\n      <SRS>EPSG:2287</SRS>\n      <SRS>EPSG:2288</SRS>\n      <SRS>EPSG:2289</SRS>\n      <SRS>EPSG:2290</SRS>\n      <SRS>EPSG:2291</SRS>\n      <SRS>EPSG:2292</SRS>\n      <SRS>EPSG:2294</SRS>\n      <SRS>EPSG:2295</SRS>\n      <SRS>EPSG:2296</SRS>\n      <SRS>EPSG:2297</SRS>\n      <SRS>EPSG:2298</SRS>\n      <SRS>EPSG:2299</SRS>\n      <SRS>EPSG:2300</SRS>\n      <SRS>EPSG:2301</SRS>\n      <SRS>EPSG:2302</SRS>\n      <SRS>EPSG:2303</SRS>\n      <SRS>EPSG:2304</SRS>\n      <SRS>EPSG:2305</SRS>\n      <SRS>EPSG:2306</SRS>\n      <SRS>EPSG:2307</SRS>\n      <SRS>EPSG:2308</SRS>\n      <SRS>EPSG:2309</SRS>\n      <SRS>EPSG:2310</SRS>\n      <SRS>EPSG:2311</SRS>\n      <SRS>EPSG:2312</SRS>\n      <SRS>EPSG:2313</SRS>\n      <SRS>EPSG:2314</SRS>\n      <SRS>EPSG:2315</SRS>\n      <SRS>EPSG:2316</SRS>\n      <SRS>EPSG:2317</SRS>\n      <SRS>EPSG:2318</SRS>\n      <SRS>EPSG:2319</SRS>\n      <SRS>EPSG:2320</SRS>\n      <SRS>EPSG:2321</SRS>\n      <SRS>EPSG:2322</SRS>\n      <SRS>EPSG:2323</SRS>\n      <SRS>EPSG:2324</SRS>\n      <SRS>EPSG:2325</SRS>\n      <SRS>EPSG:2326</SRS>\n      <SRS>EPSG:2327</SRS>\n      <SRS>EPSG:2328</SRS>\n      <SRS>EPSG:2329</SRS>\n      <SRS>EPSG:2330</SRS>\n      <SRS>EPSG:2331</SRS>\n      <SRS>EPSG:2332</SRS>\n      <SRS>EPSG:2333</SRS>\n      <SRS>EPSG:2334</SRS>\n      <SRS>EPSG:2335</SRS>\n      <SRS>EPSG:2336</SRS>\n      <SRS>EPSG:2337</SRS>\n      <SRS>EPSG:2338</SRS>\n      <SRS>EPSG:2339</SRS>\n      <SRS>EPSG:2340</SRS>\n      <SRS>EPSG:2341</SRS>\n      <SRS>EPSG:2342</SRS>\n      <SRS>EPSG:2343</SRS>\n      <SRS>EPSG:2344</SRS>\n      <SRS>EPSG:2345</SRS>\n      <SRS>EPSG:2346</SRS>\n      <SRS>EPSG:2347</SRS>\n      <SRS>EPSG:2348</SRS>\n      <SRS>EPSG:2349</SRS>\n      <SRS>EPSG:2350</SRS>\n      <SRS>EPSG:2351</SRS>\n      <SRS>EPSG:2352</SRS>\n      <SRS>EPSG:2353</SRS>\n      <SRS>EPSG:2354</SRS>\n      <SRS>EPSG:2355</SRS>\n      <SRS>EPSG:2356</SRS>\n      <SRS>EPSG:2357</SRS>\n      <SRS>EPSG:2358</SRS>\n      <SRS>EPSG:2359</SRS>\n      <SRS>EPSG:2360</SRS>\n      <SRS>EPSG:2361</SRS>\n      <SRS>EPSG:2362</SRS>\n      <SRS>EPSG:2363</SRS>\n      <SRS>EPSG:2364</SRS>\n      <SRS>EPSG:2365</SRS>\n      <SRS>EPSG:2366</SRS>\n      <SRS>EPSG:2367</SRS>\n      <SRS>EPSG:2368</SRS>\n      <SRS>EPSG:2369</SRS>\n      <SRS>EPSG:2370</SRS>\n      <SRS>EPSG:2371</SRS>\n      <SRS>EPSG:2372</SRS>\n      <SRS>EPSG:2373</SRS>\n      <SRS>EPSG:2374</SRS>\n      <SRS>EPSG:2375</SRS>\n      <SRS>EPSG:2376</SRS>\n      <SRS>EPSG:2377</SRS>\n      <SRS>EPSG:2378</SRS>\n      <SRS>EPSG:2379</SRS>\n      <SRS>EPSG:2380</SRS>\n      <SRS>EPSG:2381</SRS>\n      <SRS>EPSG:2382</SRS>\n      <SRS>EPSG:2383</SRS>\n      <SRS>EPSG:2384</SRS>\n      <SRS>EPSG:2385</SRS>\n      <SRS>EPSG:2386</SRS>\n      <SRS>EPSG:2387</SRS>\n      <SRS>EPSG:2388</SRS>\n      <SRS>EPSG:2389</SRS>\n      <SRS>EPSG:2390</SRS>\n      <SRS>EPSG:2391</SRS>\n      <SRS>EPSG:2392</SRS>\n      <SRS>EPSG:2393</SRS>\n      <SRS>EPSG:2394</SRS>\n      <SRS>EPSG:2395</SRS>\n      <SRS>EPSG:2396</SRS>\n      <SRS>EPSG:2397</SRS>\n      <SRS>EPSG:2398</SRS>\n      <SRS>EPSG:2399</SRS>\n      <SRS>EPSG:2400</SRS>\n      <SRS>EPSG:2401</SRS>\n      <SRS>EPSG:2402</SRS>\n      <SRS>EPSG:2403</SRS>\n      <SRS>EPSG:2404</SRS>\n      <SRS>EPSG:2405</SRS>\n      <SRS>EPSG:2406</SRS>\n      <SRS>EPSG:2407</SRS>\n      <SRS>EPSG:2408</SRS>\n      <SRS>EPSG:2409</SRS>\n      <SRS>EPSG:2410</SRS>\n      <SRS>EPSG:2411</SRS>\n      <SRS>EPSG:2412</SRS>\n      <SRS>EPSG:2413</SRS>\n      <SRS>EPSG:2414</SRS>\n      <SRS>EPSG:2415</SRS>\n      <SRS>EPSG:2416</SRS>\n      <SRS>EPSG:2417</SRS>\n      <SRS>EPSG:2418</SRS>\n      <SRS>EPSG:2419</SRS>\n      <SRS>EPSG:2420</SRS>\n      <SRS>EPSG:2421</SRS>\n      <SRS>EPSG:2422</SRS>\n      <SRS>EPSG:2423</SRS>\n      <SRS>EPSG:2424</SRS>\n      <SRS>EPSG:2425</SRS>\n      <SRS>EPSG:2426</SRS>\n      <SRS>EPSG:2427</SRS>\n      <SRS>EPSG:2428</SRS>\n      <SRS>EPSG:2429</SRS>\n      <SRS>EPSG:2430</SRS>\n      <SRS>EPSG:2431</SRS>\n      <SRS>EPSG:2432</SRS>\n      <SRS>EPSG:2433</SRS>\n      <SRS>EPSG:2434</SRS>\n      <SRS>EPSG:2435</SRS>\n      <SRS>EPSG:2436</SRS>\n      <SRS>EPSG:2437</SRS>\n      <SRS>EPSG:2438</SRS>\n      <SRS>EPSG:2439</SRS>\n      <SRS>EPSG:2440</SRS>\n      <SRS>EPSG:2441</SRS>\n      <SRS>EPSG:2442</SRS>\n      <SRS>EPSG:2443</SRS>\n      <SRS>EPSG:2444</SRS>\n      <SRS>EPSG:2445</SRS>\n      <SRS>EPSG:2446</SRS>\n      <SRS>EPSG:2447</SRS>\n      <SRS>EPSG:2448</SRS>\n      <SRS>EPSG:2449</SRS>\n      <SRS>EPSG:2450</SRS>\n      <SRS>EPSG:2451</SRS>\n      <SRS>EPSG:2452</SRS>\n      <SRS>EPSG:2453</SRS>\n      <SRS>EPSG:2454</SRS>\n      <SRS>EPSG:2455</SRS>\n      <SRS>EPSG:2456</SRS>\n      <SRS>EPSG:2457</SRS>\n      <SRS>EPSG:2458</SRS>\n      <SRS>EPSG:2459</SRS>\n      <SRS>EPSG:2460</SRS>\n      <SRS>EPSG:2461</SRS>\n      <SRS>EPSG:2462</SRS>\n      <SRS>EPSG:2463</SRS>\n      <SRS>EPSG:2464</SRS>\n      <SRS>EPSG:2465</SRS>\n      <SRS>EPSG:2466</SRS>\n      <SRS>EPSG:2467</SRS>\n      <SRS>EPSG:2468</SRS>\n      <SRS>EPSG:2469</SRS>\n      <SRS>EPSG:2470</SRS>\n      <SRS>EPSG:2471</SRS>\n      <SRS>EPSG:2472</SRS>\n      <SRS>EPSG:2473</SRS>\n      <SRS>EPSG:2474</SRS>\n      <SRS>EPSG:2475</SRS>\n      <SRS>EPSG:2476</SRS>\n      <SRS>EPSG:2477</SRS>\n      <SRS>EPSG:2478</SRS>\n      <SRS>EPSG:2479</SRS>\n      <SRS>EPSG:2480</SRS>\n      <SRS>EPSG:2481</SRS>\n      <SRS>EPSG:2482</SRS>\n      <SRS>EPSG:2483</SRS>\n      <SRS>EPSG:2484</SRS>\n      <SRS>EPSG:2485</SRS>\n      <SRS>EPSG:2486</SRS>\n      <SRS>EPSG:2487</SRS>\n      <SRS>EPSG:2488</SRS>\n      <SRS>EPSG:2489</SRS>\n      <SRS>EPSG:2490</SRS>\n      <SRS>EPSG:2491</SRS>\n      <SRS>EPSG:2492</SRS>\n      <SRS>EPSG:2493</SRS>\n      <SRS>EPSG:2494</SRS>\n      <SRS>EPSG:2495</SRS>\n      <SRS>EPSG:2496</SRS>\n      <SRS>EPSG:2497</SRS>\n      <SRS>EPSG:2498</SRS>\n      <SRS>EPSG:2499</SRS>\n      <SRS>EPSG:2500</SRS>\n      <SRS>EPSG:2501</SRS>\n      <SRS>EPSG:2502</SRS>\n      <SRS>EPSG:2503</SRS>\n      <SRS>EPSG:2504</SRS>\n      <SRS>EPSG:2505</SRS>\n      <SRS>EPSG:2506</SRS>\n      <SRS>EPSG:2507</SRS>\n      <SRS>EPSG:2508</SRS>\n      <SRS>EPSG:2509</SRS>\n      <SRS>EPSG:2510</SRS>\n      <SRS>EPSG:2511</SRS>\n      <SRS>EPSG:2512</SRS>\n      <SRS>EPSG:2513</SRS>\n      <SRS>EPSG:2514</SRS>\n      <SRS>EPSG:2515</SRS>\n      <SRS>EPSG:2516</SRS>\n      <SRS>EPSG:2517</SRS>\n      <SRS>EPSG:2518</SRS>\n      <SRS>EPSG:2519</SRS>\n      <SRS>EPSG:2520</SRS>\n      <SRS>EPSG:2521</SRS>\n      <SRS>EPSG:2522</SRS>\n      <SRS>EPSG:2523</SRS>\n      <SRS>EPSG:2524</SRS>\n      <SRS>EPSG:2525</SRS>\n      <SRS>EPSG:2526</SRS>\n      <SRS>EPSG:2527</SRS>\n      <SRS>EPSG:2528</SRS>\n      <SRS>EPSG:2529</SRS>\n      <SRS>EPSG:2530</SRS>\n      <SRS>EPSG:2531</SRS>\n      <SRS>EPSG:2532</SRS>\n      <SRS>EPSG:2533</SRS>\n      <SRS>EPSG:2534</SRS>\n      <SRS>EPSG:2535</SRS>\n      <SRS>EPSG:2536</SRS>\n      <SRS>EPSG:2537</SRS>\n      <SRS>EPSG:2538</SRS>\n      <SRS>EPSG:2539</SRS>\n      <SRS>EPSG:2540</SRS>\n      <SRS>EPSG:2541</SRS>\n      <SRS>EPSG:2542</SRS>\n      <SRS>EPSG:2543</SRS>\n      <SRS>EPSG:2544</SRS>\n      <SRS>EPSG:2545</SRS>\n      <SRS>EPSG:2546</SRS>\n      <SRS>EPSG:2547</SRS>\n      <SRS>EPSG:2548</SRS>\n      <SRS>EPSG:2549</SRS>\n      <SRS>EPSG:2550</SRS>\n      <SRS>EPSG:2551</SRS>\n      <SRS>EPSG:2552</SRS>\n      <SRS>EPSG:2553</SRS>\n      <SRS>EPSG:2554</SRS>\n      <SRS>EPSG:2555</SRS>\n      <SRS>EPSG:2556</SRS>\n      <SRS>EPSG:2557</SRS>\n      <SRS>EPSG:2558</SRS>\n      <SRS>EPSG:2559</SRS>\n      <SRS>EPSG:2560</SRS>\n      <SRS>EPSG:2561</SRS>\n      <SRS>EPSG:2562</SRS>\n      <SRS>EPSG:2563</SRS>\n      <SRS>EPSG:2564</SRS>\n      <SRS>EPSG:2565</SRS>\n      <SRS>EPSG:2566</SRS>\n      <SRS>EPSG:2567</SRS>\n      <SRS>EPSG:2568</SRS>\n      <SRS>EPSG:2569</SRS>\n      <SRS>EPSG:2570</SRS>\n      <SRS>EPSG:2571</SRS>\n      <SRS>EPSG:2572</SRS>\n      <SRS>EPSG:2573</SRS>\n      <SRS>EPSG:2574</SRS>\n      <SRS>EPSG:2575</SRS>\n      <SRS>EPSG:2576</SRS>\n      <SRS>EPSG:2577</SRS>\n      <SRS>EPSG:2578</SRS>\n      <SRS>EPSG:2579</SRS>\n      <SRS>EPSG:2580</SRS>\n      <SRS>EPSG:2581</SRS>\n      <SRS>EPSG:2582</SRS>\n      <SRS>EPSG:2583</SRS>\n      <SRS>EPSG:2584</SRS>\n      <SRS>EPSG:2585</SRS>\n      <SRS>EPSG:2586</SRS>\n      <SRS>EPSG:2587</SRS>\n      <SRS>EPSG:2588</SRS>\n      <SRS>EPSG:2589</SRS>\n      <SRS>EPSG:2590</SRS>\n      <SRS>EPSG:2591</SRS>\n      <SRS>EPSG:2592</SRS>\n      <SRS>EPSG:2593</SRS>\n      <SRS>EPSG:2594</SRS>\n      <SRS>EPSG:2595</SRS>\n      <SRS>EPSG:2596</SRS>\n      <SRS>EPSG:2597</SRS>\n      <SRS>EPSG:2598</SRS>\n      <SRS>EPSG:2599</SRS>\n      <SRS>EPSG:2600</SRS>\n      <SRS>EPSG:2601</SRS>\n      <SRS>EPSG:2602</SRS>\n      <SRS>EPSG:2603</SRS>\n      <SRS>EPSG:2604</SRS>\n      <SRS>EPSG:2605</SRS>\n      <SRS>EPSG:2606</SRS>\n      <SRS>EPSG:2607</SRS>\n      <SRS>EPSG:2608</SRS>\n      <SRS>EPSG:2609</SRS>\n      <SRS>EPSG:2610</SRS>\n      <SRS>EPSG:2611</SRS>\n      <SRS>EPSG:2612</SRS>\n      <SRS>EPSG:2613</SRS>\n      <SRS>EPSG:2614</SRS>\n      <SRS>EPSG:2615</SRS>\n      <SRS>EPSG:2616</SRS>\n      <SRS>EPSG:2617</SRS>\n      <SRS>EPSG:2618</SRS>\n      <SRS>EPSG:2619</SRS>\n      <SRS>EPSG:2620</SRS>\n      <SRS>EPSG:2621</SRS>\n      <SRS>EPSG:2622</SRS>\n      <SRS>EPSG:2623</SRS>\n      <SRS>EPSG:2624</SRS>\n      <SRS>EPSG:2625</SRS>\n      <SRS>EPSG:2626</SRS>\n      <SRS>EPSG:2627</SRS>\n      <SRS>EPSG:2628</SRS>\n      <SRS>EPSG:2629</SRS>\n      <SRS>EPSG:2630</SRS>\n      <SRS>EPSG:2631</SRS>\n      <SRS>EPSG:2632</SRS>\n      <SRS>EPSG:2633</SRS>\n      <SRS>EPSG:2634</SRS>\n      <SRS>EPSG:2635</SRS>\n      <SRS>EPSG:2636</SRS>\n      <SRS>EPSG:2637</SRS>\n      <SRS>EPSG:2638</SRS>\n      <SRS>EPSG:2639</SRS>\n      <SRS>EPSG:2640</SRS>\n      <SRS>EPSG:2641</SRS>\n      <SRS>EPSG:2642</SRS>\n      <SRS>EPSG:2643</SRS>\n      <SRS>EPSG:2644</SRS>\n      <SRS>EPSG:2645</SRS>\n      <SRS>EPSG:2646</SRS>\n      <SRS>EPSG:2647</SRS>\n      <SRS>EPSG:2648</SRS>\n      <SRS>EPSG:2649</SRS>\n      <SRS>EPSG:2650</SRS>\n      <SRS>EPSG:2651</SRS>\n      <SRS>EPSG:2652</SRS>\n      <SRS>EPSG:2653</SRS>\n      <SRS>EPSG:2654</SRS>\n      <SRS>EPSG:2655</SRS>\n      <SRS>EPSG:2656</SRS>\n      <SRS>EPSG:2657</SRS>\n      <SRS>EPSG:2658</SRS>\n      <SRS>EPSG:2659</SRS>\n      <SRS>EPSG:2660</SRS>\n      <SRS>EPSG:2661</SRS>\n      <SRS>EPSG:2662</SRS>\n      <SRS>EPSG:2663</SRS>\n      <SRS>EPSG:2664</SRS>\n      <SRS>EPSG:2665</SRS>\n      <SRS>EPSG:2666</SRS>\n      <SRS>EPSG:2667</SRS>\n      <SRS>EPSG:2668</SRS>\n      <SRS>EPSG:2669</SRS>\n      <SRS>EPSG:2670</SRS>\n      <SRS>EPSG:2671</SRS>\n      <SRS>EPSG:2672</SRS>\n      <SRS>EPSG:2673</SRS>\n      <SRS>EPSG:2674</SRS>\n      <SRS>EPSG:2675</SRS>\n      <SRS>EPSG:2676</SRS>\n      <SRS>EPSG:2677</SRS>\n      <SRS>EPSG:2678</SRS>\n      <SRS>EPSG:2679</SRS>\n      <SRS>EPSG:2680</SRS>\n      <SRS>EPSG:2681</SRS>\n      <SRS>EPSG:2682</SRS>\n      <SRS>EPSG:2683</SRS>\n      <SRS>EPSG:2684</SRS>\n      <SRS>EPSG:2685</SRS>\n      <SRS>EPSG:2686</SRS>\n      <SRS>EPSG:2687</SRS>\n      <SRS>EPSG:2688</SRS>\n      <SRS>EPSG:2689</SRS>\n      <SRS>EPSG:2690</SRS>\n      <SRS>EPSG:2691</SRS>\n      <SRS>EPSG:2692</SRS>\n      <SRS>EPSG:2693</SRS>\n      <SRS>EPSG:2694</SRS>\n      <SRS>EPSG:2695</SRS>\n      <SRS>EPSG:2696</SRS>\n      <SRS>EPSG:2697</SRS>\n      <SRS>EPSG:2698</SRS>\n      <SRS>EPSG:2699</SRS>\n      <SRS>EPSG:2700</SRS>\n      <SRS>EPSG:2701</SRS>\n      <SRS>EPSG:2702</SRS>\n      <SRS>EPSG:2703</SRS>\n      <SRS>EPSG:2704</SRS>\n      <SRS>EPSG:2705</SRS>\n      <SRS>EPSG:2706</SRS>\n      <SRS>EPSG:2707</SRS>\n      <SRS>EPSG:2708</SRS>\n      <SRS>EPSG:2709</SRS>\n      <SRS>EPSG:2710</SRS>\n      <SRS>EPSG:2711</SRS>\n      <SRS>EPSG:2712</SRS>\n      <SRS>EPSG:2713</SRS>\n      <SRS>EPSG:2714</SRS>\n      <SRS>EPSG:2715</SRS>\n      <SRS>EPSG:2716</SRS>\n      <SRS>EPSG:2717</SRS>\n      <SRS>EPSG:2718</SRS>\n      <SRS>EPSG:2719</SRS>\n      <SRS>EPSG:2720</SRS>\n      <SRS>EPSG:2721</SRS>\n      <SRS>EPSG:2722</SRS>\n      <SRS>EPSG:2723</SRS>\n      <SRS>EPSG:2724</SRS>\n      <SRS>EPSG:2725</SRS>\n      <SRS>EPSG:2726</SRS>\n      <SRS>EPSG:2727</SRS>\n      <SRS>EPSG:2728</SRS>\n      <SRS>EPSG:2729</SRS>\n      <SRS>EPSG:2730</SRS>\n      <SRS>EPSG:2731</SRS>\n      <SRS>EPSG:2732</SRS>\n      <SRS>EPSG:2733</SRS>\n      <SRS>EPSG:2734</SRS>\n      <SRS>EPSG:2735</SRS>\n      <SRS>EPSG:2736</SRS>\n      <SRS>EPSG:2737</SRS>\n      <SRS>EPSG:2738</SRS>\n      <SRS>EPSG:2739</SRS>\n      <SRS>EPSG:2740</SRS>\n      <SRS>EPSG:2741</SRS>\n      <SRS>EPSG:2742</SRS>\n      <SRS>EPSG:2743</SRS>\n      <SRS>EPSG:2744</SRS>\n      <SRS>EPSG:2745</SRS>\n      <SRS>EPSG:2746</SRS>\n      <SRS>EPSG:2747</SRS>\n      <SRS>EPSG:2748</SRS>\n      <SRS>EPSG:2749</SRS>\n      <SRS>EPSG:2750</SRS>\n      <SRS>EPSG:2751</SRS>\n      <SRS>EPSG:2752</SRS>\n      <SRS>EPSG:2753</SRS>\n      <SRS>EPSG:2754</SRS>\n      <SRS>EPSG:2755</SRS>\n      <SRS>EPSG:2756</SRS>\n      <SRS>EPSG:2757</SRS>\n      <SRS>EPSG:2758</SRS>\n      <SRS>EPSG:2759</SRS>\n      <SRS>EPSG:2760</SRS>\n      <SRS>EPSG:2761</SRS>\n      <SRS>EPSG:2762</SRS>\n      <SRS>EPSG:2763</SRS>\n      <SRS>EPSG:2764</SRS>\n      <SRS>EPSG:2765</SRS>\n      <SRS>EPSG:2766</SRS>\n      <SRS>EPSG:2767</SRS>\n      <SRS>EPSG:2768</SRS>\n      <SRS>EPSG:2769</SRS>\n      <SRS>EPSG:2770</SRS>\n      <SRS>EPSG:2771</SRS>\n      <SRS>EPSG:2772</SRS>\n      <SRS>EPSG:2773</SRS>\n      <SRS>EPSG:2774</SRS>\n      <SRS>EPSG:2775</SRS>\n      <SRS>EPSG:2776</SRS>\n      <SRS>EPSG:2777</SRS>\n      <SRS>EPSG:2778</SRS>\n      <SRS>EPSG:2779</SRS>\n      <SRS>EPSG:2780</SRS>\n      <SRS>EPSG:2781</SRS>\n      <SRS>EPSG:2782</SRS>\n      <SRS>EPSG:2783</SRS>\n      <SRS>EPSG:2784</SRS>\n      <SRS>EPSG:2785</SRS>\n      <SRS>EPSG:2786</SRS>\n      <SRS>EPSG:2787</SRS>\n      <SRS>EPSG:2788</SRS>\n      <SRS>EPSG:2789</SRS>\n      <SRS>EPSG:2790</SRS>\n      <SRS>EPSG:2791</SRS>\n      <SRS>EPSG:2792</SRS>\n      <SRS>EPSG:2793</SRS>\n      <SRS>EPSG:2794</SRS>\n      <SRS>EPSG:2795</SRS>\n      <SRS>EPSG:2796</SRS>\n      <SRS>EPSG:2797</SRS>\n      <SRS>EPSG:2798</SRS>\n      <SRS>EPSG:2799</SRS>\n      <SRS>EPSG:2800</SRS>\n      <SRS>EPSG:2801</SRS>\n      <SRS>EPSG:2802</SRS>\n      <SRS>EPSG:2803</SRS>\n      <SRS>EPSG:2804</SRS>\n      <SRS>EPSG:2805</SRS>\n      <SRS>EPSG:2806</SRS>\n      <SRS>EPSG:2807</SRS>\n      <SRS>EPSG:2808</SRS>\n      <SRS>EPSG:2809</SRS>\n      <SRS>EPSG:2810</SRS>\n      <SRS>EPSG:2811</SRS>\n      <SRS>EPSG:2812</SRS>\n      <SRS>EPSG:2813</SRS>\n      <SRS>EPSG:2814</SRS>\n      <SRS>EPSG:2815</SRS>\n      <SRS>EPSG:2816</SRS>\n      <SRS>EPSG:2817</SRS>\n      <SRS>EPSG:2818</SRS>\n      <SRS>EPSG:2819</SRS>\n      <SRS>EPSG:2820</SRS>\n      <SRS>EPSG:2821</SRS>\n      <SRS>EPSG:2822</SRS>\n      <SRS>EPSG:2823</SRS>\n      <SRS>EPSG:2824</SRS>\n      <SRS>EPSG:2825</SRS>\n      <SRS>EPSG:2826</SRS>\n      <SRS>EPSG:2827</SRS>\n      <SRS>EPSG:2828</SRS>\n      <SRS>EPSG:2829</SRS>\n      <SRS>EPSG:2830</SRS>\n      <SRS>EPSG:2831</SRS>\n      <SRS>EPSG:2832</SRS>\n      <SRS>EPSG:2833</SRS>\n      <SRS>EPSG:2834</SRS>\n      <SRS>EPSG:2835</SRS>\n      <SRS>EPSG:2836</SRS>\n      <SRS>EPSG:2837</SRS>\n      <SRS>EPSG:2838</SRS>\n      <SRS>EPSG:2839</SRS>\n      <SRS>EPSG:2840</SRS>\n      <SRS>EPSG:2841</SRS>\n      <SRS>EPSG:2842</SRS>\n      <SRS>EPSG:2843</SRS>\n      <SRS>EPSG:2844</SRS>\n      <SRS>EPSG:2845</SRS>\n      <SRS>EPSG:2846</SRS>\n      <SRS>EPSG:2847</SRS>\n      <SRS>EPSG:2848</SRS>\n      <SRS>EPSG:2849</SRS>\n      <SRS>EPSG:2850</SRS>\n      <SRS>EPSG:2851</SRS>\n      <SRS>EPSG:2852</SRS>\n      <SRS>EPSG:2853</SRS>\n      <SRS>EPSG:2854</SRS>\n      <SRS>EPSG:2855</SRS>\n      <SRS>EPSG:2856</SRS>\n      <SRS>EPSG:2857</SRS>\n      <SRS>EPSG:2858</SRS>\n      <SRS>EPSG:2859</SRS>\n      <SRS>EPSG:2860</SRS>\n      <SRS>EPSG:2861</SRS>\n      <SRS>EPSG:2862</SRS>\n      <SRS>EPSG:2863</SRS>\n      <SRS>EPSG:2864</SRS>\n      <SRS>EPSG:2865</SRS>\n      <SRS>EPSG:2866</SRS>\n      <SRS>EPSG:2867</SRS>\n      <SRS>EPSG:2868</SRS>\n      <SRS>EPSG:2869</SRS>\n      <SRS>EPSG:2870</SRS>\n      <SRS>EPSG:2871</SRS>\n      <SRS>EPSG:2872</SRS>\n      <SRS>EPSG:2873</SRS>\n      <SRS>EPSG:2874</SRS>\n      <SRS>EPSG:2875</SRS>\n      <SRS>EPSG:2876</SRS>\n      <SRS>EPSG:2877</SRS>\n      <SRS>EPSG:2878</SRS>\n      <SRS>EPSG:2879</SRS>\n      <SRS>EPSG:2880</SRS>\n      <SRS>EPSG:2881</SRS>\n      <SRS>EPSG:2882</SRS>\n      <SRS>EPSG:2883</SRS>\n      <SRS>EPSG:2884</SRS>\n      <SRS>EPSG:2885</SRS>\n      <SRS>EPSG:2886</SRS>\n      <SRS>EPSG:2887</SRS>\n      <SRS>EPSG:2888</SRS>\n      <SRS>EPSG:2889</SRS>\n      <SRS>EPSG:2890</SRS>\n      <SRS>EPSG:2891</SRS>\n      <SRS>EPSG:2892</SRS>\n      <SRS>EPSG:2893</SRS>\n      <SRS>EPSG:2894</SRS>\n      <SRS>EPSG:2895</SRS>\n      <SRS>EPSG:2896</SRS>\n      <SRS>EPSG:2897</SRS>\n      <SRS>EPSG:2898</SRS>\n      <SRS>EPSG:2899</SRS>\n      <SRS>EPSG:2900</SRS>\n      <SRS>EPSG:2901</SRS>\n      <SRS>EPSG:2902</SRS>\n      <SRS>EPSG:2903</SRS>\n      <SRS>EPSG:2904</SRS>\n      <SRS>EPSG:2905</SRS>\n      <SRS>EPSG:2906</SRS>\n      <SRS>EPSG:2907</SRS>\n      <SRS>EPSG:2908</SRS>\n      <SRS>EPSG:2909</SRS>\n      <SRS>EPSG:2910</SRS>\n      <SRS>EPSG:2911</SRS>\n      <SRS>EPSG:2912</SRS>\n      <SRS>EPSG:2913</SRS>\n      <SRS>EPSG:2914</SRS>\n      <SRS>EPSG:2915</SRS>\n      <SRS>EPSG:2916</SRS>\n      <SRS>EPSG:2917</SRS>\n      <SRS>EPSG:2918</SRS>\n      <SRS>EPSG:2919</SRS>\n      <SRS>EPSG:2920</SRS>\n      <SRS>EPSG:2921</SRS>\n      <SRS>EPSG:2922</SRS>\n      <SRS>EPSG:2923</SRS>\n      <SRS>EPSG:2924</SRS>\n      <SRS>EPSG:2925</SRS>\n      <SRS>EPSG:2926</SRS>\n      <SRS>EPSG:2927</SRS>\n      <SRS>EPSG:2928</SRS>\n      <SRS>EPSG:2929</SRS>\n      <SRS>EPSG:2930</SRS>\n      <SRS>EPSG:2931</SRS>\n      <SRS>EPSG:2932</SRS>\n      <SRS>EPSG:2933</SRS>\n      <SRS>EPSG:2934</SRS>\n      <SRS>EPSG:2935</SRS>\n      <SRS>EPSG:2936</SRS>\n      <SRS>EPSG:2937</SRS>\n      <SRS>EPSG:2938</SRS>\n      <SRS>EPSG:2939</SRS>\n      <SRS>EPSG:2940</SRS>\n      <SRS>EPSG:2941</SRS>\n      <SRS>EPSG:2942</SRS>\n      <SRS>EPSG:2943</SRS>\n      <SRS>EPSG:2944</SRS>\n      <SRS>EPSG:2945</SRS>\n      <SRS>EPSG:2946</SRS>\n      <SRS>EPSG:2947</SRS>\n      <SRS>EPSG:2948</SRS>\n      <SRS>EPSG:2949</SRS>\n      <SRS>EPSG:2950</SRS>\n      <SRS>EPSG:2951</SRS>\n      <SRS>EPSG:2952</SRS>\n      <SRS>EPSG:2953</SRS>\n      <SRS>EPSG:2954</SRS>\n      <SRS>EPSG:2955</SRS>\n      <SRS>EPSG:2956</SRS>\n      <SRS>EPSG:2957</SRS>\n      <SRS>EPSG:2958</SRS>\n      <SRS>EPSG:2959</SRS>\n      <SRS>EPSG:2960</SRS>\n      <SRS>EPSG:2961</SRS>\n      <SRS>EPSG:2962</SRS>\n      <SRS>EPSG:2963</SRS>\n      <SRS>EPSG:2964</SRS>\n      <SRS>EPSG:2965</SRS>\n      <SRS>EPSG:2966</SRS>\n      <SRS>EPSG:2967</SRS>\n      <SRS>EPSG:2968</SRS>\n      <SRS>EPSG:2969</SRS>\n      <SRS>EPSG:2970</SRS>\n      <SRS>EPSG:2971</SRS>\n      <SRS>EPSG:2972</SRS>\n      <SRS>EPSG:2973</SRS>\n      <SRS>EPSG:2975</SRS>\n      <SRS>EPSG:2976</SRS>\n      <SRS>EPSG:2977</SRS>\n      <SRS>EPSG:2978</SRS>\n      <SRS>EPSG:2979</SRS>\n      <SRS>EPSG:2980</SRS>\n      <SRS>EPSG:2981</SRS>\n      <SRS>EPSG:2982</SRS>\n      <SRS>EPSG:2983</SRS>\n      <SRS>EPSG:2984</SRS>\n      <SRS>EPSG:2985</SRS>\n      <SRS>EPSG:2986</SRS>\n      <SRS>EPSG:2987</SRS>\n      <SRS>EPSG:2988</SRS>\n      <SRS>EPSG:2989</SRS>\n      <SRS>EPSG:2990</SRS>\n      <SRS>EPSG:2991</SRS>\n      <SRS>EPSG:2992</SRS>\n      <SRS>EPSG:2993</SRS>\n      <SRS>EPSG:2994</SRS>\n      <SRS>EPSG:2995</SRS>\n      <SRS>EPSG:2996</SRS>\n      <SRS>EPSG:2997</SRS>\n      <SRS>EPSG:2998</SRS>\n      <SRS>EPSG:2999</SRS>\n      <SRS>EPSG:3000</SRS>\n      <SRS>EPSG:3001</SRS>\n      <SRS>EPSG:3002</SRS>\n      <SRS>EPSG:3003</SRS>\n      <SRS>EPSG:3004</SRS>\n      <SRS>EPSG:3005</SRS>\n      <SRS>EPSG:3006</SRS>\n      <SRS>EPSG:3007</SRS>\n      <SRS>EPSG:3008</SRS>\n      <SRS>EPSG:3009</SRS>\n      <SRS>EPSG:3010</SRS>\n      <SRS>EPSG:3011</SRS>\n      <SRS>EPSG:3012</SRS>\n      <SRS>EPSG:3013</SRS>\n      <SRS>EPSG:3014</SRS>\n      <SRS>EPSG:3015</SRS>\n      <SRS>EPSG:3016</SRS>\n      <SRS>EPSG:3017</SRS>\n      <SRS>EPSG:3018</SRS>\n      <SRS>EPSG:3019</SRS>\n      <SRS>EPSG:3020</SRS>\n      <SRS>EPSG:3021</SRS>\n      <SRS>EPSG:3022</SRS>\n      <SRS>EPSG:3023</SRS>\n      <SRS>EPSG:3024</SRS>\n      <SRS>EPSG:3025</SRS>\n      <SRS>EPSG:3026</SRS>\n      <SRS>EPSG:3027</SRS>\n      <SRS>EPSG:3028</SRS>\n      <SRS>EPSG:3029</SRS>\n      <SRS>EPSG:3030</SRS>\n      <SRS>EPSG:3031</SRS>\n      <SRS>EPSG:3032</SRS>\n      <SRS>EPSG:3033</SRS>\n      <SRS>EPSG:3034</SRS>\n      <SRS>EPSG:3035</SRS>\n      <SRS>EPSG:3036</SRS>\n      <SRS>EPSG:3037</SRS>\n      <SRS>EPSG:3038</SRS>\n      <SRS>EPSG:3039</SRS>\n      <SRS>EPSG:3040</SRS>\n      <SRS>EPSG:3041</SRS>\n      <SRS>EPSG:3042</SRS>\n      <SRS>EPSG:3043</SRS>\n      <SRS>EPSG:3044</SRS>\n      <SRS>EPSG:3045</SRS>\n      <SRS>EPSG:3046</SRS>\n      <SRS>EPSG:3047</SRS>\n      <SRS>EPSG:3048</SRS>\n      <SRS>EPSG:3049</SRS>\n      <SRS>EPSG:3050</SRS>\n      <SRS>EPSG:3051</SRS>\n      <SRS>EPSG:3052</SRS>\n      <SRS>EPSG:3053</SRS>\n      <SRS>EPSG:3054</SRS>\n      <SRS>EPSG:3055</SRS>\n      <SRS>EPSG:3056</SRS>\n      <SRS>EPSG:3057</SRS>\n      <SRS>EPSG:3058</SRS>\n      <SRS>EPSG:3059</SRS>\n      <SRS>EPSG:3060</SRS>\n      <SRS>EPSG:3061</SRS>\n      <SRS>EPSG:3062</SRS>\n      <SRS>EPSG:3063</SRS>\n      <SRS>EPSG:3064</SRS>\n      <SRS>EPSG:3065</SRS>\n      <SRS>EPSG:3066</SRS>\n      <SRS>EPSG:3067</SRS>\n      <SRS>EPSG:3068</SRS>\n      <SRS>EPSG:3069</SRS>\n      <SRS>EPSG:3070</SRS>\n      <SRS>EPSG:3071</SRS>\n      <SRS>EPSG:3072</SRS>\n      <SRS>EPSG:3073</SRS>\n      <SRS>EPSG:3074</SRS>\n      <SRS>EPSG:3075</SRS>\n      <SRS>EPSG:3076</SRS>\n      <SRS>EPSG:3077</SRS>\n      <SRS>EPSG:3078</SRS>\n      <SRS>EPSG:3079</SRS>\n      <SRS>EPSG:3080</SRS>\n      <SRS>EPSG:3081</SRS>\n      <SRS>EPSG:3082</SRS>\n      <SRS>EPSG:3083</SRS>\n      <SRS>EPSG:3084</SRS>\n      <SRS>EPSG:3085</SRS>\n      <SRS>EPSG:3086</SRS>\n      <SRS>EPSG:3087</SRS>\n      <SRS>EPSG:3088</SRS>\n      <SRS>EPSG:3089</SRS>\n      <SRS>EPSG:3090</SRS>\n      <SRS>EPSG:3091</SRS>\n      <SRS>EPSG:3092</SRS>\n      <SRS>EPSG:3093</SRS>\n      <SRS>EPSG:3094</SRS>\n      <SRS>EPSG:3095</SRS>\n      <SRS>EPSG:3096</SRS>\n      <SRS>EPSG:3097</SRS>\n      <SRS>EPSG:3098</SRS>\n      <SRS>EPSG:3099</SRS>\n      <SRS>EPSG:3100</SRS>\n      <SRS>EPSG:3101</SRS>\n      <SRS>EPSG:3102</SRS>\n      <SRS>EPSG:3103</SRS>\n      <SRS>EPSG:3104</SRS>\n      <SRS>EPSG:3105</SRS>\n      <SRS>EPSG:3106</SRS>\n      <SRS>EPSG:3107</SRS>\n      <SRS>EPSG:3108</SRS>\n      <SRS>EPSG:3109</SRS>\n      <SRS>EPSG:3110</SRS>\n      <SRS>EPSG:3111</SRS>\n      <SRS>EPSG:3112</SRS>\n      <SRS>EPSG:3113</SRS>\n      <SRS>EPSG:3114</SRS>\n      <SRS>EPSG:3115</SRS>\n      <SRS>EPSG:3116</SRS>\n      <SRS>EPSG:3117</SRS>\n      <SRS>EPSG:3118</SRS>\n      <SRS>EPSG:3119</SRS>\n      <SRS>EPSG:3120</SRS>\n      <SRS>EPSG:3121</SRS>\n      <SRS>EPSG:3122</SRS>\n      <SRS>EPSG:3123</SRS>\n      <SRS>EPSG:3124</SRS>\n      <SRS>EPSG:3125</SRS>\n      <SRS>EPSG:3126</SRS>\n      <SRS>EPSG:3127</SRS>\n      <SRS>EPSG:3128</SRS>\n      <SRS>EPSG:3129</SRS>\n      <SRS>EPSG:3130</SRS>\n      <SRS>EPSG:3131</SRS>\n      <SRS>EPSG:3132</SRS>\n      <SRS>EPSG:3133</SRS>\n      <SRS>EPSG:3134</SRS>\n      <SRS>EPSG:3135</SRS>\n      <SRS>EPSG:3136</SRS>\n      <SRS>EPSG:3137</SRS>\n      <SRS>EPSG:3138</SRS>\n      <SRS>EPSG:3139</SRS>\n      <SRS>EPSG:3140</SRS>\n      <SRS>EPSG:3141</SRS>\n      <SRS>EPSG:3142</SRS>\n      <SRS>EPSG:3143</SRS>\n      <SRS>EPSG:3144</SRS>\n      <SRS>EPSG:3145</SRS>\n      <SRS>EPSG:3146</SRS>\n      <SRS>EPSG:3147</SRS>\n      <SRS>EPSG:3148</SRS>\n      <SRS>EPSG:3149</SRS>\n      <SRS>EPSG:3150</SRS>\n      <SRS>EPSG:3151</SRS>\n      <SRS>EPSG:3152</SRS>\n      <SRS>EPSG:3153</SRS>\n      <SRS>EPSG:3154</SRS>\n      <SRS>EPSG:3155</SRS>\n      <SRS>EPSG:3156</SRS>\n      <SRS>EPSG:3157</SRS>\n      <SRS>EPSG:3158</SRS>\n      <SRS>EPSG:3159</SRS>\n      <SRS>EPSG:3160</SRS>\n      <SRS>EPSG:3161</SRS>\n      <SRS>EPSG:3162</SRS>\n      <SRS>EPSG:3163</SRS>\n      <SRS>EPSG:3164</SRS>\n      <SRS>EPSG:3165</SRS>\n      <SRS>EPSG:3166</SRS>\n      <SRS>EPSG:3167</SRS>\n      <SRS>EPSG:3168</SRS>\n      <SRS>EPSG:3169</SRS>\n      <SRS>EPSG:3170</SRS>\n      <SRS>EPSG:3171</SRS>\n      <SRS>EPSG:3172</SRS>\n      <SRS>EPSG:3173</SRS>\n      <SRS>EPSG:3174</SRS>\n      <SRS>EPSG:3175</SRS>\n      <SRS>EPSG:3176</SRS>\n      <SRS>EPSG:3177</SRS>\n      <SRS>EPSG:3178</SRS>\n      <SRS>EPSG:3179</SRS>\n      <SRS>EPSG:3180</SRS>\n      <SRS>EPSG:3181</SRS>\n      <SRS>EPSG:3182</SRS>\n      <SRS>EPSG:3183</SRS>\n      <SRS>EPSG:3184</SRS>\n      <SRS>EPSG:3185</SRS>\n      <SRS>EPSG:3186</SRS>\n      <SRS>EPSG:3187</SRS>\n      <SRS>EPSG:3188</SRS>\n      <SRS>EPSG:3189</SRS>\n      <SRS>EPSG:3190</SRS>\n      <SRS>EPSG:3191</SRS>\n      <SRS>EPSG:3192</SRS>\n      <SRS>EPSG:3193</SRS>\n      <SRS>EPSG:3194</SRS>\n      <SRS>EPSG:3195</SRS>\n      <SRS>EPSG:3196</SRS>\n      <SRS>EPSG:3197</SRS>\n      <SRS>EPSG:3198</SRS>\n      <SRS>EPSG:3199</SRS>\n      <SRS>EPSG:3200</SRS>\n      <SRS>EPSG:3201</SRS>\n      <SRS>EPSG:3202</SRS>\n      <SRS>EPSG:3203</SRS>\n      <SRS>EPSG:3204</SRS>\n      <SRS>EPSG:3205</SRS>\n      <SRS>EPSG:3206</SRS>\n      <SRS>EPSG:3207</SRS>\n      <SRS>EPSG:3208</SRS>\n      <SRS>EPSG:3209</SRS>\n      <SRS>EPSG:3210</SRS>\n      <SRS>EPSG:3211</SRS>\n      <SRS>EPSG:3212</SRS>\n      <SRS>EPSG:3213</SRS>\n      <SRS>EPSG:3214</SRS>\n      <SRS>EPSG:3215</SRS>\n      <SRS>EPSG:3216</SRS>\n      <SRS>EPSG:3217</SRS>\n      <SRS>EPSG:3218</SRS>\n      <SRS>EPSG:3219</SRS>\n      <SRS>EPSG:3220</SRS>\n      <SRS>EPSG:3221</SRS>\n      <SRS>EPSG:3222</SRS>\n      <SRS>EPSG:3223</SRS>\n      <SRS>EPSG:3224</SRS>\n      <SRS>EPSG:3225</SRS>\n      <SRS>EPSG:3226</SRS>\n      <SRS>EPSG:3227</SRS>\n      <SRS>EPSG:3228</SRS>\n      <SRS>EPSG:3229</SRS>\n      <SRS>EPSG:3230</SRS>\n      <SRS>EPSG:3231</SRS>\n      <SRS>EPSG:3232</SRS>\n      <SRS>EPSG:3233</SRS>\n      <SRS>EPSG:3234</SRS>\n      <SRS>EPSG:3235</SRS>\n      <SRS>EPSG:3236</SRS>\n      <SRS>EPSG:3237</SRS>\n      <SRS>EPSG:3238</SRS>\n      <SRS>EPSG:3239</SRS>\n      <SRS>EPSG:3240</SRS>\n      <SRS>EPSG:3241</SRS>\n      <SRS>EPSG:3242</SRS>\n      <SRS>EPSG:3243</SRS>\n      <SRS>EPSG:3244</SRS>\n      <SRS>EPSG:3245</SRS>\n      <SRS>EPSG:3246</SRS>\n      <SRS>EPSG:3247</SRS>\n      <SRS>EPSG:3248</SRS>\n      <SRS>EPSG:3249</SRS>\n      <SRS>EPSG:3250</SRS>\n      <SRS>EPSG:3251</SRS>\n      <SRS>EPSG:3252</SRS>\n      <SRS>EPSG:3253</SRS>\n      <SRS>EPSG:3254</SRS>\n      <SRS>EPSG:3255</SRS>\n      <SRS>EPSG:3256</SRS>\n      <SRS>EPSG:3257</SRS>\n      <SRS>EPSG:3258</SRS>\n      <SRS>EPSG:3259</SRS>\n      <SRS>EPSG:3260</SRS>\n      <SRS>EPSG:3261</SRS>\n      <SRS>EPSG:3262</SRS>\n      <SRS>EPSG:3263</SRS>\n      <SRS>EPSG:3264</SRS>\n      <SRS>EPSG:3265</SRS>\n      <SRS>EPSG:3266</SRS>\n      <SRS>EPSG:3267</SRS>\n      <SRS>EPSG:3268</SRS>\n      <SRS>EPSG:3269</SRS>\n      <SRS>EPSG:3270</SRS>\n      <SRS>EPSG:3271</SRS>\n      <SRS>EPSG:3272</SRS>\n      <SRS>EPSG:3273</SRS>\n      <SRS>EPSG:3274</SRS>\n      <SRS>EPSG:3275</SRS>\n      <SRS>EPSG:3276</SRS>\n      <SRS>EPSG:3277</SRS>\n      <SRS>EPSG:3278</SRS>\n      <SRS>EPSG:3279</SRS>\n      <SRS>EPSG:3280</SRS>\n      <SRS>EPSG:3281</SRS>\n      <SRS>EPSG:3282</SRS>\n      <SRS>EPSG:3283</SRS>\n      <SRS>EPSG:3284</SRS>\n      <SRS>EPSG:3285</SRS>\n      <SRS>EPSG:3286</SRS>\n      <SRS>EPSG:3287</SRS>\n      <SRS>EPSG:3288</SRS>\n      <SRS>EPSG:3289</SRS>\n      <SRS>EPSG:3290</SRS>\n      <SRS>EPSG:3291</SRS>\n      <SRS>EPSG:3292</SRS>\n      <SRS>EPSG:3293</SRS>\n      <SRS>EPSG:3294</SRS>\n      <SRS>EPSG:3295</SRS>\n      <SRS>EPSG:3296</SRS>\n      <SRS>EPSG:3297</SRS>\n      <SRS>EPSG:3298</SRS>\n      <SRS>EPSG:3299</SRS>\n      <SRS>EPSG:3300</SRS>\n      <SRS>EPSG:3301</SRS>\n      <SRS>EPSG:3302</SRS>\n      <SRS>EPSG:3303</SRS>\n      <SRS>EPSG:3304</SRS>\n      <SRS>EPSG:3305</SRS>\n      <SRS>EPSG:3306</SRS>\n      <SRS>EPSG:3307</SRS>\n      <SRS>EPSG:3308</SRS>\n      <SRS>EPSG:3309</SRS>\n      <SRS>EPSG:3310</SRS>\n      <SRS>EPSG:3311</SRS>\n      <SRS>EPSG:3312</SRS>\n      <SRS>EPSG:3313</SRS>\n      <SRS>EPSG:3314</SRS>\n      <SRS>EPSG:3315</SRS>\n      <SRS>EPSG:3316</SRS>\n      <SRS>EPSG:3317</SRS>\n      <SRS>EPSG:3318</SRS>\n      <SRS>EPSG:3319</SRS>\n      <SRS>EPSG:3320</SRS>\n      <SRS>EPSG:3321</SRS>\n      <SRS>EPSG:3322</SRS>\n      <SRS>EPSG:3323</SRS>\n      <SRS>EPSG:3324</SRS>\n      <SRS>EPSG:3325</SRS>\n      <SRS>EPSG:3326</SRS>\n      <SRS>EPSG:3327</SRS>\n      <SRS>EPSG:3328</SRS>\n      <SRS>EPSG:3329</SRS>\n      <SRS>EPSG:3330</SRS>\n      <SRS>EPSG:3331</SRS>\n      <SRS>EPSG:3332</SRS>\n      <SRS>EPSG:3333</SRS>\n      <SRS>EPSG:3334</SRS>\n      <SRS>EPSG:3335</SRS>\n      <SRS>EPSG:3336</SRS>\n      <SRS>EPSG:3337</SRS>\n      <SRS>EPSG:3338</SRS>\n      <SRS>EPSG:3339</SRS>\n      <SRS>EPSG:3340</SRS>\n      <SRS>EPSG:3341</SRS>\n      <SRS>EPSG:3342</SRS>\n      <SRS>EPSG:3343</SRS>\n      <SRS>EPSG:3344</SRS>\n      <SRS>EPSG:3345</SRS>\n      <SRS>EPSG:3346</SRS>\n      <SRS>EPSG:3347</SRS>\n      <SRS>EPSG:3348</SRS>\n      <SRS>EPSG:3349</SRS>\n      <SRS>EPSG:3350</SRS>\n      <SRS>EPSG:3351</SRS>\n      <SRS>EPSG:3352</SRS>\n      <SRS>EPSG:3353</SRS>\n      <SRS>EPSG:3354</SRS>\n      <SRS>EPSG:3355</SRS>\n      <SRS>EPSG:3356</SRS>\n      <SRS>EPSG:3357</SRS>\n      <SRS>EPSG:3358</SRS>\n      <SRS>EPSG:3359</SRS>\n      <SRS>EPSG:3360</SRS>\n      <SRS>EPSG:3361</SRS>\n      <SRS>EPSG:3362</SRS>\n      <SRS>EPSG:3363</SRS>\n      <SRS>EPSG:3364</SRS>\n      <SRS>EPSG:3365</SRS>\n      <SRS>EPSG:3366</SRS>\n      <SRS>EPSG:3367</SRS>\n      <SRS>EPSG:3368</SRS>\n      <SRS>EPSG:3369</SRS>\n      <SRS>EPSG:3370</SRS>\n      <SRS>EPSG:3371</SRS>\n      <SRS>EPSG:3372</SRS>\n      <SRS>EPSG:3373</SRS>\n      <SRS>EPSG:3374</SRS>\n      <SRS>EPSG:3375</SRS>\n      <SRS>EPSG:3376</SRS>\n      <SRS>EPSG:3377</SRS>\n      <SRS>EPSG:3378</SRS>\n      <SRS>EPSG:3379</SRS>\n      <SRS>EPSG:3380</SRS>\n      <SRS>EPSG:3381</SRS>\n      <SRS>EPSG:3382</SRS>\n      <SRS>EPSG:3383</SRS>\n      <SRS>EPSG:3384</SRS>\n      <SRS>EPSG:3385</SRS>\n      <SRS>EPSG:3386</SRS>\n      <SRS>EPSG:3387</SRS>\n      <SRS>EPSG:3388</SRS>\n      <SRS>EPSG:3389</SRS>\n      <SRS>EPSG:3390</SRS>\n      <SRS>EPSG:3391</SRS>\n      <SRS>EPSG:3392</SRS>\n      <SRS>EPSG:3393</SRS>\n      <SRS>EPSG:3394</SRS>\n      <SRS>EPSG:3395</SRS>\n      <SRS>EPSG:3396</SRS>\n      <SRS>EPSG:3397</SRS>\n      <SRS>EPSG:3398</SRS>\n      <SRS>EPSG:3399</SRS>\n      <SRS>EPSG:3400</SRS>\n      <SRS>EPSG:3401</SRS>\n      <SRS>EPSG:3402</SRS>\n      <SRS>EPSG:3403</SRS>\n      <SRS>EPSG:3404</SRS>\n      <SRS>EPSG:3405</SRS>\n      <SRS>EPSG:3406</SRS>\n      <SRS>EPSG:3407</SRS>\n      <SRS>EPSG:3408</SRS>\n      <SRS>EPSG:3409</SRS>\n      <SRS>EPSG:3410</SRS>\n      <SRS>EPSG:3411</SRS>\n      <SRS>EPSG:3412</SRS>\n      <SRS>EPSG:3413</SRS>\n      <SRS>EPSG:3414</SRS>\n      <SRS>EPSG:3415</SRS>\n      <SRS>EPSG:3416</SRS>\n      <SRS>EPSG:3417</SRS>\n      <SRS>EPSG:3418</SRS>\n      <SRS>EPSG:3419</SRS>\n      <SRS>EPSG:3420</SRS>\n      <SRS>EPSG:3421</SRS>\n      <SRS>EPSG:3422</SRS>\n      <SRS>EPSG:3423</SRS>\n      <SRS>EPSG:3424</SRS>\n      <SRS>EPSG:3425</SRS>\n      <SRS>EPSG:3426</SRS>\n      <SRS>EPSG:3427</SRS>\n      <SRS>EPSG:3428</SRS>\n      <SRS>EPSG:3429</SRS>\n      <SRS>EPSG:3430</SRS>\n      <SRS>EPSG:3431</SRS>\n      <SRS>EPSG:3432</SRS>\n      <SRS>EPSG:3433</SRS>\n      <SRS>EPSG:3434</SRS>\n      <SRS>EPSG:3435</SRS>\n      <SRS>EPSG:3436</SRS>\n      <SRS>EPSG:3437</SRS>\n      <SRS>EPSG:3438</SRS>\n      <SRS>EPSG:3439</SRS>\n      <SRS>EPSG:3440</SRS>\n      <SRS>EPSG:3441</SRS>\n      <SRS>EPSG:3442</SRS>\n      <SRS>EPSG:3443</SRS>\n      <SRS>EPSG:3444</SRS>\n      <SRS>EPSG:3445</SRS>\n      <SRS>EPSG:3446</SRS>\n      <SRS>EPSG:3447</SRS>\n      <SRS>EPSG:3448</SRS>\n      <SRS>EPSG:3449</SRS>\n      <SRS>EPSG:3450</SRS>\n      <SRS>EPSG:3451</SRS>\n      <SRS>EPSG:3452</SRS>\n      <SRS>EPSG:3453</SRS>\n      <SRS>EPSG:3454</SRS>\n      <SRS>EPSG:3455</SRS>\n      <SRS>EPSG:3456</SRS>\n      <SRS>EPSG:3457</SRS>\n      <SRS>EPSG:3458</SRS>\n      <SRS>EPSG:3459</SRS>\n      <SRS>EPSG:3460</SRS>\n      <SRS>EPSG:3461</SRS>\n      <SRS>EPSG:3462</SRS>\n      <SRS>EPSG:3463</SRS>\n      <SRS>EPSG:3464</SRS>\n      <SRS>EPSG:3560</SRS>\n      <SRS>EPSG:3561</SRS>\n      <SRS>EPSG:3562</SRS>\n      <SRS>EPSG:3563</SRS>\n      <SRS>EPSG:3564</SRS>\n      <SRS>EPSG:3565</SRS>\n      <SRS>EPSG:3566</SRS>\n      <SRS>EPSG:3567</SRS>\n      <SRS>EPSG:3568</SRS>\n      <SRS>EPSG:3569</SRS>\n      <SRS>EPSG:3570</SRS>\n      <SRS>EPSG:3571</SRS>\n      <SRS>EPSG:3572</SRS>\n      <SRS>EPSG:3573</SRS>\n      <SRS>EPSG:3574</SRS>\n      <SRS>EPSG:3575</SRS>\n      <SRS>EPSG:3576</SRS>\n      <SRS>EPSG:3577</SRS>\n      <SRS>EPSG:3920</SRS>\n      <SRS>EPSG:3991</SRS>\n      <SRS>EPSG:3992</SRS>\n      <SRS>EPSG:3993</SRS>\n      <SRS>EPSG:4001</SRS>\n      <SRS>EPSG:4002</SRS>\n      <SRS>EPSG:4003</SRS>\n      <SRS>EPSG:4004</SRS>\n      <SRS>EPSG:4005</SRS>\n      <SRS>EPSG:4006</SRS>\n      <SRS>EPSG:4007</SRS>\n      <SRS>EPSG:4008</SRS>\n      <SRS>EPSG:4009</SRS>\n      <SRS>EPSG:4010</SRS>\n      <SRS>EPSG:4011</SRS>\n      <SRS>EPSG:4012</SRS>\n      <SRS>EPSG:4013</SRS>\n      <SRS>EPSG:4014</SRS>\n      <SRS>EPSG:4015</SRS>\n      <SRS>EPSG:4016</SRS>\n      <SRS>EPSG:4018</SRS>\n      <SRS>EPSG:4019</SRS>\n      <SRS>EPSG:4020</SRS>\n      <SRS>EPSG:4021</SRS>\n      <SRS>EPSG:4022</SRS>\n      <SRS>EPSG:4024</SRS>\n      <SRS>EPSG:4025</SRS>\n      <SRS>EPSG:4027</SRS>\n      <SRS>EPSG:4028</SRS>\n      <SRS>EPSG:4029</SRS>\n      <SRS>EPSG:4030</SRS>\n      <SRS>EPSG:4031</SRS>\n      <SRS>EPSG:4032</SRS>\n      <SRS>EPSG:4033</SRS>\n      <SRS>EPSG:4034</SRS>\n      <SRS>EPSG:4035</SRS>\n      <SRS>EPSG:4036</SRS>\n      <SRS>EPSG:4041</SRS>\n      <SRS>EPSG:4042</SRS>\n      <SRS>EPSG:4043</SRS>\n      <SRS>EPSG:4044</SRS>\n      <SRS>EPSG:4045</SRS>\n      <SRS>EPSG:4047</SRS>\n      <SRS>EPSG:4052</SRS>\n      <SRS>EPSG:4053</SRS>\n      <SRS>EPSG:4054</SRS>\n      <SRS>EPSG:4120</SRS>\n      <SRS>EPSG:4121</SRS>\n      <SRS>EPSG:4122</SRS>\n      <SRS>EPSG:4123</SRS>\n      <SRS>EPSG:4124</SRS>\n      <SRS>EPSG:4125</SRS>\n      <SRS>EPSG:4126</SRS>\n      <SRS>EPSG:4127</SRS>\n      <SRS>EPSG:4128</SRS>\n      <SRS>EPSG:4129</SRS>\n      <SRS>EPSG:4130</SRS>\n      <SRS>EPSG:4131</SRS>\n      <SRS>EPSG:4132</SRS>\n      <SRS>EPSG:4133</SRS>\n      <SRS>EPSG:4134</SRS>\n      <SRS>EPSG:4135</SRS>\n      <SRS>EPSG:4136</SRS>\n      <SRS>EPSG:4137</SRS>\n      <SRS>EPSG:4138</SRS>\n      <SRS>EPSG:4139</SRS>\n      <SRS>EPSG:4140</SRS>\n      <SRS>EPSG:4141</SRS>\n      <SRS>EPSG:4142</SRS>\n      <SRS>EPSG:4143</SRS>\n      <SRS>EPSG:4144</SRS>\n      <SRS>EPSG:4145</SRS>\n      <SRS>EPSG:4146</SRS>\n      <SRS>EPSG:4147</SRS>\n      <SRS>EPSG:4148</SRS>\n      <SRS>EPSG:4149</SRS>\n      <SRS>EPSG:4150</SRS>\n      <SRS>EPSG:4151</SRS>\n      <SRS>EPSG:4152</SRS>\n      <SRS>EPSG:4153</SRS>\n      <SRS>EPSG:4154</SRS>\n      <SRS>EPSG:4155</SRS>\n      <SRS>EPSG:4156</SRS>\n      <SRS>EPSG:4157</SRS>\n      <SRS>EPSG:4158</SRS>\n      <SRS>EPSG:4159</SRS>\n      <SRS>EPSG:4160</SRS>\n      <SRS>EPSG:4161</SRS>\n      <SRS>EPSG:4162</SRS>\n      <SRS>EPSG:4163</SRS>\n      <SRS>EPSG:4164</SRS>\n      <SRS>EPSG:4165</SRS>\n      <SRS>EPSG:4166</SRS>\n      <SRS>EPSG:4167</SRS>\n      <SRS>EPSG:4168</SRS>\n      <SRS>EPSG:4169</SRS>\n      <SRS>EPSG:4170</SRS>\n      <SRS>EPSG:4171</SRS>\n      <SRS>EPSG:4172</SRS>\n      <SRS>EPSG:4173</SRS>\n      <SRS>EPSG:4174</SRS>\n      <SRS>EPSG:4175</SRS>\n      <SRS>EPSG:4176</SRS>\n      <SRS>EPSG:4178</SRS>\n      <SRS>EPSG:4179</SRS>\n      <SRS>EPSG:4180</SRS>\n      <SRS>EPSG:4181</SRS>\n      <SRS>EPSG:4182</SRS>\n      <SRS>EPSG:4183</SRS>\n      <SRS>EPSG:4184</SRS>\n      <SRS>EPSG:4185</SRS>\n      <SRS>EPSG:4188</SRS>\n      <SRS>EPSG:4189</SRS>\n      <SRS>EPSG:4190</SRS>\n      <SRS>EPSG:4191</SRS>\n      <SRS>EPSG:4192</SRS>\n      <SRS>EPSG:4193</SRS>\n      <SRS>EPSG:4194</SRS>\n      <SRS>EPSG:4195</SRS>\n      <SRS>EPSG:4196</SRS>\n      <SRS>EPSG:4197</SRS>\n      <SRS>EPSG:4198</SRS>\n      <SRS>EPSG:4199</SRS>\n      <SRS>EPSG:4200</SRS>\n      <SRS>EPSG:4201</SRS>\n      <SRS>EPSG:4202</SRS>\n      <SRS>EPSG:4203</SRS>\n      <SRS>EPSG:4204</SRS>\n      <SRS>EPSG:4205</SRS>\n      <SRS>EPSG:4206</SRS>\n      <SRS>EPSG:4207</SRS>\n      <SRS>EPSG:4208</SRS>\n      <SRS>EPSG:4209</SRS>\n      <SRS>EPSG:4210</SRS>\n      <SRS>EPSG:4211</SRS>\n      <SRS>EPSG:4212</SRS>\n      <SRS>EPSG:4213</SRS>\n      <SRS>EPSG:4214</SRS>\n      <SRS>EPSG:4215</SRS>\n      <SRS>EPSG:4216</SRS>\n      <SRS>EPSG:4218</SRS>\n      <SRS>EPSG:4219</SRS>\n      <SRS>EPSG:4220</SRS>\n      <SRS>EPSG:4221</SRS>\n      <SRS>EPSG:4222</SRS>\n      <SRS>EPSG:4223</SRS>\n      <SRS>EPSG:4224</SRS>\n      <SRS>EPSG:4225</SRS>\n      <SRS>EPSG:4226</SRS>\n      <SRS>EPSG:4227</SRS>\n      <SRS>EPSG:4228</SRS>\n      <SRS>EPSG:4229</SRS>\n      <SRS>EPSG:4230</SRS>\n      <SRS>EPSG:4231</SRS>\n      <SRS>EPSG:4232</SRS>\n      <SRS>EPSG:4233</SRS>\n      <SRS>EPSG:4234</SRS>\n      <SRS>EPSG:4235</SRS>\n      <SRS>EPSG:4236</SRS>\n      <SRS>EPSG:4237</SRS>\n      <SRS>EPSG:4238</SRS>\n      <SRS>EPSG:4239</SRS>\n      <SRS>EPSG:4240</SRS>\n      <SRS>EPSG:4241</SRS>\n      <SRS>EPSG:4242</SRS>\n      <SRS>EPSG:4243</SRS>\n      <SRS>EPSG:4244</SRS>\n      <SRS>EPSG:4245</SRS>\n      <SRS>EPSG:4246</SRS>\n      <SRS>EPSG:4247</SRS>\n      <SRS>EPSG:4248</SRS>\n      <SRS>EPSG:4249</SRS>\n      <SRS>EPSG:4250</SRS>\n      <SRS>EPSG:4251</SRS>\n      <SRS>EPSG:4252</SRS>\n      <SRS>EPSG:4253</SRS>\n      <SRS>EPSG:4254</SRS>\n      <SRS>EPSG:4255</SRS>\n      <SRS>EPSG:4256</SRS>\n      <SRS>EPSG:4257</SRS>\n      <SRS>EPSG:4258</SRS>\n      <SRS>EPSG:4259</SRS>\n      <SRS>EPSG:4260</SRS>\n      <SRS>EPSG:4261</SRS>\n      <SRS>EPSG:4262</SRS>\n      <SRS>EPSG:4263</SRS>\n      <SRS>EPSG:4264</SRS>\n      <SRS>EPSG:4265</SRS>\n      <SRS>EPSG:4266</SRS>\n      <SRS>EPSG:4267</SRS>\n      <SRS>EPSG:4268</SRS>\n      <SRS>EPSG:4269</SRS>\n      <SRS>EPSG:4270</SRS>\n      <SRS>EPSG:4271</SRS>\n      <SRS>EPSG:4272</SRS>\n      <SRS>EPSG:4273</SRS>\n      <SRS>EPSG:4274</SRS>\n      <SRS>EPSG:4275</SRS>\n      <SRS>EPSG:4276</SRS>\n      <SRS>EPSG:4277</SRS>\n      <SRS>EPSG:4278</SRS>\n      <SRS>EPSG:4279</SRS>\n      <SRS>EPSG:4280</SRS>\n      <SRS>EPSG:4281</SRS>\n      <SRS>EPSG:4282</SRS>\n      <SRS>EPSG:4283</SRS>\n      <SRS>EPSG:4284</SRS>\n      <SRS>EPSG:4285</SRS>\n      <SRS>EPSG:4286</SRS>\n      <SRS>EPSG:4287</SRS>\n      <SRS>EPSG:4288</SRS>\n      <SRS>EPSG:4289</SRS>\n      <SRS>EPSG:4291</SRS>\n      <SRS>EPSG:4292</SRS>\n      <SRS>EPSG:4293</SRS>\n      <SRS>EPSG:4294</SRS>\n      <SRS>EPSG:4295</SRS>\n      <SRS>EPSG:4296</SRS>\n      <SRS>EPSG:4297</SRS>\n      <SRS>EPSG:4298</SRS>\n      <SRS>EPSG:4299</SRS>\n      <SRS>EPSG:4300</SRS>\n      <SRS>EPSG:4301</SRS>\n      <SRS>EPSG:4302</SRS>\n      <SRS>EPSG:4303</SRS>\n      <SRS>EPSG:4304</SRS>\n      <SRS>EPSG:4306</SRS>\n      <SRS>EPSG:4307</SRS>\n      <SRS>EPSG:4308</SRS>\n      <SRS>EPSG:4309</SRS>\n      <SRS>EPSG:4310</SRS>\n      <SRS>EPSG:4311</SRS>\n      <SRS>EPSG:4312</SRS>\n      <SRS>EPSG:4313</SRS>\n      <SRS>EPSG:4314</SRS>\n      <SRS>EPSG:4315</SRS>\n      <SRS>EPSG:4316</SRS>\n      <SRS>EPSG:4317</SRS>\n      <SRS>EPSG:4318</SRS>\n      <SRS>EPSG:4319</SRS>\n      <SRS>EPSG:4322</SRS>\n      <SRS>EPSG:4324</SRS>\n      <SRS>EPSG:4326</SRS>\n      <SRS>EPSG:4327</SRS>\n      <SRS>EPSG:4328</SRS>\n      <SRS>EPSG:4329</SRS>\n      <SRS>EPSG:4330</SRS>\n      <SRS>EPSG:4331</SRS>\n      <SRS>EPSG:4332</SRS>\n      <SRS>EPSG:4333</SRS>\n      <SRS>EPSG:4334</SRS>\n      <SRS>EPSG:4335</SRS>\n      <SRS>EPSG:4336</SRS>\n      <SRS>EPSG:4337</SRS>\n      <SRS>EPSG:4338</SRS>\n      <SRS>EPSG:4339</SRS>\n      <SRS>EPSG:4340</SRS>\n      <SRS>EPSG:4341</SRS>\n      <SRS>EPSG:4342</SRS>\n      <SRS>EPSG:4343</SRS>\n      <SRS>EPSG:4344</SRS>\n      <SRS>EPSG:4345</SRS>\n      <SRS>EPSG:4346</SRS>\n      <SRS>EPSG:4347</SRS>\n      <SRS>EPSG:4348</SRS>\n      <SRS>EPSG:4349</SRS>\n      <SRS>EPSG:4350</SRS>\n      <SRS>EPSG:4351</SRS>\n      <SRS>EPSG:4352</SRS>\n      <SRS>EPSG:4353</SRS>\n      <SRS>EPSG:4354</SRS>\n      <SRS>EPSG:4355</SRS>\n      <SRS>EPSG:4356</SRS>\n      <SRS>EPSG:4357</SRS>\n      <SRS>EPSG:4358</SRS>\n      <SRS>EPSG:4359</SRS>\n      <SRS>EPSG:4360</SRS>\n      <SRS>EPSG:4361</SRS>\n      <SRS>EPSG:4362</SRS>\n      <SRS>EPSG:4363</SRS>\n      <SRS>EPSG:4364</SRS>\n      <SRS>EPSG:4365</SRS>\n      <SRS>EPSG:4366</SRS>\n      <SRS>EPSG:4367</SRS>\n      <SRS>EPSG:4368</SRS>\n      <SRS>EPSG:4369</SRS>\n      <SRS>EPSG:4370</SRS>\n      <SRS>EPSG:4371</SRS>\n      <SRS>EPSG:4372</SRS>\n      <SRS>EPSG:4373</SRS>\n      <SRS>EPSG:4374</SRS>\n      <SRS>EPSG:4375</SRS>\n      <SRS>EPSG:4376</SRS>\n      <SRS>EPSG:4377</SRS>\n      <SRS>EPSG:4378</SRS>\n      <SRS>EPSG:4379</SRS>\n      <SRS>EPSG:4380</SRS>\n      <SRS>EPSG:4381</SRS>\n      <SRS>EPSG:4382</SRS>\n      <SRS>EPSG:4383</SRS>\n      <SRS>EPSG:4384</SRS>\n      <SRS>EPSG:4385</SRS>\n      <SRS>EPSG:4386</SRS>\n      <SRS>EPSG:4387</SRS>\n      <SRS>EPSG:4388</SRS>\n      <SRS>EPSG:4389</SRS>\n      <SRS>EPSG:4600</SRS>\n      <SRS>EPSG:4601</SRS>\n      <SRS>EPSG:4602</SRS>\n      <SRS>EPSG:4603</SRS>\n      <SRS>EPSG:4604</SRS>\n      <SRS>EPSG:4605</SRS>\n      <SRS>EPSG:4606</SRS>\n      <SRS>EPSG:4607</SRS>\n      <SRS>EPSG:4608</SRS>\n      <SRS>EPSG:4609</SRS>\n      <SRS>EPSG:4610</SRS>\n      <SRS>EPSG:4611</SRS>\n      <SRS>EPSG:4612</SRS>\n      <SRS>EPSG:4613</SRS>\n      <SRS>EPSG:4614</SRS>\n      <SRS>EPSG:4615</SRS>\n      <SRS>EPSG:4616</SRS>\n      <SRS>EPSG:4617</SRS>\n      <SRS>EPSG:4618</SRS>\n      <SRS>EPSG:4619</SRS>\n      <SRS>EPSG:4620</SRS>\n      <SRS>EPSG:4621</SRS>\n      <SRS>EPSG:4622</SRS>\n      <SRS>EPSG:4623</SRS>\n      <SRS>EPSG:4624</SRS>\n      <SRS>EPSG:4625</SRS>\n      <SRS>EPSG:4626</SRS>\n      <SRS>EPSG:4627</SRS>\n      <SRS>EPSG:4628</SRS>\n      <SRS>EPSG:4629</SRS>\n      <SRS>EPSG:4630</SRS>\n      <SRS>EPSG:4631</SRS>\n      <SRS>EPSG:4632</SRS>\n      <SRS>EPSG:4633</SRS>\n      <SRS>EPSG:4634</SRS>\n      <SRS>EPSG:4635</SRS>\n      <SRS>EPSG:4636</SRS>\n      <SRS>EPSG:4637</SRS>\n      <SRS>EPSG:4638</SRS>\n      <SRS>EPSG:4639</SRS>\n      <SRS>EPSG:4640</SRS>\n      <SRS>EPSG:4641</SRS>\n      <SRS>EPSG:4642</SRS>\n      <SRS>EPSG:4643</SRS>\n      <SRS>EPSG:4644</SRS>\n      <SRS>EPSG:4645</SRS>\n      <SRS>EPSG:4646</SRS>\n      <SRS>EPSG:4657</SRS>\n      <SRS>EPSG:4658</SRS>\n      <SRS>EPSG:4659</SRS>\n      <SRS>EPSG:4660</SRS>\n      <SRS>EPSG:4661</SRS>\n      <SRS>EPSG:4662</SRS>\n      <SRS>EPSG:4663</SRS>\n      <SRS>EPSG:4664</SRS>\n      <SRS>EPSG:4665</SRS>\n      <SRS>EPSG:4666</SRS>\n      <SRS>EPSG:4667</SRS>\n      <SRS>EPSG:4668</SRS>\n      <SRS>EPSG:4669</SRS>\n      <SRS>EPSG:4670</SRS>\n      <SRS>EPSG:4671</SRS>\n      <SRS>EPSG:4672</SRS>\n      <SRS>EPSG:4673</SRS>\n      <SRS>EPSG:4674</SRS>\n      <SRS>EPSG:4675</SRS>\n      <SRS>EPSG:4676</SRS>\n      <SRS>EPSG:4677</SRS>\n      <SRS>EPSG:4678</SRS>\n      <SRS>EPSG:4679</SRS>\n      <SRS>EPSG:4680</SRS>\n      <SRS>EPSG:4681</SRS>\n      <SRS>EPSG:4682</SRS>\n      <SRS>EPSG:4683</SRS>\n      <SRS>EPSG:4684</SRS>\n      <SRS>EPSG:4685</SRS>\n      <SRS>EPSG:4686</SRS>\n      <SRS>EPSG:4687</SRS>\n      <SRS>EPSG:4688</SRS>\n      <SRS>EPSG:4689</SRS>\n      <SRS>EPSG:4690</SRS>\n      <SRS>EPSG:4691</SRS>\n      <SRS>EPSG:4692</SRS>\n      <SRS>EPSG:4693</SRS>\n      <SRS>EPSG:4694</SRS>\n      <SRS>EPSG:4695</SRS>\n      <SRS>EPSG:4696</SRS>\n      <SRS>EPSG:4697</SRS>\n      <SRS>EPSG:4698</SRS>\n      <SRS>EPSG:4699</SRS>\n      <SRS>EPSG:4700</SRS>\n      <SRS>EPSG:4701</SRS>\n      <SRS>EPSG:4702</SRS>\n      <SRS>EPSG:4703</SRS>\n      <SRS>EPSG:4704</SRS>\n      <SRS>EPSG:4705</SRS>\n      <SRS>EPSG:4706</SRS>\n      <SRS>EPSG:4707</SRS>\n      <SRS>EPSG:4708</SRS>\n      <SRS>EPSG:4709</SRS>\n      <SRS>EPSG:4710</SRS>\n      <SRS>EPSG:4711</SRS>\n      <SRS>EPSG:4712</SRS>\n      <SRS>EPSG:4713</SRS>\n      <SRS>EPSG:4714</SRS>\n      <SRS>EPSG:4715</SRS>\n      <SRS>EPSG:4716</SRS>\n      <SRS>EPSG:4717</SRS>\n      <SRS>EPSG:4718</SRS>\n      <SRS>EPSG:4719</SRS>\n      <SRS>EPSG:4720</SRS>\n      <SRS>EPSG:4721</SRS>\n      <SRS>EPSG:4722</SRS>\n      <SRS>EPSG:4723</SRS>\n      <SRS>EPSG:4724</SRS>\n      <SRS>EPSG:4725</SRS>\n      <SRS>EPSG:4726</SRS>\n      <SRS>EPSG:4727</SRS>\n      <SRS>EPSG:4728</SRS>\n      <SRS>EPSG:4729</SRS>\n      <SRS>EPSG:4730</SRS>\n      <SRS>EPSG:4731</SRS>\n      <SRS>EPSG:4732</SRS>\n      <SRS>EPSG:4733</SRS>\n      <SRS>EPSG:4734</SRS>\n      <SRS>EPSG:4735</SRS>\n      <SRS>EPSG:4736</SRS>\n      <SRS>EPSG:4737</SRS>\n      <SRS>EPSG:4738</SRS>\n      <SRS>EPSG:4739</SRS>\n      <SRS>EPSG:4740</SRS>\n      <SRS>EPSG:4741</SRS>\n      <SRS>EPSG:4742</SRS>\n      <SRS>EPSG:4743</SRS>\n      <SRS>EPSG:4744</SRS>\n      <SRS>EPSG:4745</SRS>\n      <SRS>EPSG:4746</SRS>\n      <SRS>EPSG:4747</SRS>\n      <SRS>EPSG:4748</SRS>\n      <SRS>EPSG:4749</SRS>\n      <SRS>EPSG:4750</SRS>\n      <SRS>EPSG:4751</SRS>\n      <SRS>EPSG:4752</SRS>\n      <SRS>EPSG:4753</SRS>\n      <SRS>EPSG:4754</SRS>\n      <SRS>EPSG:4755</SRS>\n      <SRS>EPSG:4756</SRS>\n      <SRS>EPSG:4757</SRS>\n      <SRS>EPSG:4758</SRS>\n      <SRS>EPSG:4801</SRS>\n      <SRS>EPSG:4802</SRS>\n      <SRS>EPSG:4803</SRS>\n      <SRS>EPSG:4804</SRS>\n      <SRS>EPSG:4805</SRS>\n      <SRS>EPSG:4806</SRS>\n      <SRS>EPSG:4807</SRS>\n      <SRS>EPSG:4808</SRS>\n      <SRS>EPSG:4809</SRS>\n      <SRS>EPSG:4810</SRS>\n      <SRS>EPSG:4811</SRS>\n      <SRS>EPSG:4813</SRS>\n      <SRS>EPSG:4814</SRS>\n      <SRS>EPSG:4815</SRS>\n      <SRS>EPSG:4816</SRS>\n      <SRS>EPSG:4817</SRS>\n      <SRS>EPSG:4818</SRS>\n      <SRS>EPSG:4819</SRS>\n      <SRS>EPSG:4820</SRS>\n      <SRS>EPSG:4821</SRS>\n      <SRS>EPSG:4894</SRS>\n      <SRS>EPSG:4895</SRS>\n      <SRS>EPSG:4896</SRS>\n      <SRS>EPSG:4897</SRS>\n      <SRS>EPSG:4898</SRS>\n      <SRS>EPSG:4899</SRS>\n      <SRS>EPSG:4900</SRS>\n      <SRS>EPSG:4901</SRS>\n      <SRS>EPSG:4902</SRS>\n      <SRS>EPSG:4903</SRS>\n      <SRS>EPSG:4904</SRS>\n      <SRS>EPSG:4906</SRS>\n      <SRS>EPSG:4907</SRS>\n      <SRS>EPSG:4908</SRS>\n      <SRS>EPSG:4909</SRS>\n      <SRS>EPSG:4910</SRS>\n      <SRS>EPSG:4911</SRS>\n      <SRS>EPSG:4912</SRS>\n      <SRS>EPSG:4913</SRS>\n      <SRS>EPSG:4914</SRS>\n      <SRS>EPSG:4915</SRS>\n      <SRS>EPSG:4916</SRS>\n      <SRS>EPSG:4917</SRS>\n      <SRS>EPSG:4918</SRS>\n      <SRS>EPSG:4919</SRS>\n      <SRS>EPSG:4920</SRS>\n      <SRS>EPSG:4921</SRS>\n      <SRS>EPSG:4922</SRS>\n      <SRS>EPSG:4923</SRS>\n      <SRS>EPSG:4924</SRS>\n      <SRS>EPSG:4925</SRS>\n      <SRS>EPSG:4926</SRS>\n      <SRS>EPSG:4927</SRS>\n      <SRS>EPSG:4928</SRS>\n      <SRS>EPSG:4929</SRS>\n      <SRS>EPSG:4930</SRS>\n      <SRS>EPSG:4931</SRS>\n      <SRS>EPSG:4932</SRS>\n      <SRS>EPSG:4933</SRS>\n      <SRS>EPSG:4934</SRS>\n      <SRS>EPSG:4935</SRS>\n      <SRS>EPSG:4936</SRS>\n      <SRS>EPSG:4937</SRS>\n      <SRS>EPSG:4938</SRS>\n      <SRS>EPSG:4939</SRS>\n      <SRS>EPSG:4940</SRS>\n      <SRS>EPSG:4941</SRS>\n      <SRS>EPSG:4942</SRS>\n      <SRS>EPSG:4943</SRS>\n      <SRS>EPSG:4944</SRS>\n      <SRS>EPSG:4945</SRS>\n      <SRS>EPSG:4946</SRS>\n      <SRS>EPSG:4947</SRS>\n      <SRS>EPSG:4948</SRS>\n      <SRS>EPSG:4949</SRS>\n      <SRS>EPSG:4950</SRS>\n      <SRS>EPSG:4951</SRS>\n      <SRS>EPSG:4952</SRS>\n      <SRS>EPSG:4953</SRS>\n      <SRS>EPSG:4954</SRS>\n      <SRS>EPSG:4955</SRS>\n      <SRS>EPSG:4956</SRS>\n      <SRS>EPSG:4957</SRS>\n      <SRS>EPSG:4958</SRS>\n      <SRS>EPSG:4959</SRS>\n      <SRS>EPSG:4960</SRS>\n      <SRS>EPSG:4961</SRS>\n      <SRS>EPSG:4962</SRS>\n      <SRS>EPSG:4963</SRS>\n      <SRS>EPSG:4964</SRS>\n      <SRS>EPSG:4965</SRS>\n      <SRS>EPSG:4966</SRS>\n      <SRS>EPSG:4967</SRS>\n      <SRS>EPSG:4968</SRS>\n      <SRS>EPSG:4969</SRS>\n      <SRS>EPSG:4970</SRS>\n      <SRS>EPSG:4971</SRS>\n      <SRS>EPSG:4972</SRS>\n      <SRS>EPSG:4973</SRS>\n      <SRS>EPSG:4974</SRS>\n      <SRS>EPSG:4975</SRS>\n      <SRS>EPSG:4976</SRS>\n      <SRS>EPSG:4977</SRS>\n      <SRS>EPSG:4978</SRS>\n      <SRS>EPSG:4979</SRS>\n      <SRS>EPSG:4980</SRS>\n      <SRS>EPSG:4981</SRS>\n      <SRS>EPSG:4982</SRS>\n      <SRS>EPSG:4983</SRS>\n      <SRS>EPSG:4984</SRS>\n      <SRS>EPSG:4985</SRS>\n      <SRS>EPSG:4986</SRS>\n      <SRS>EPSG:4987</SRS>\n      <SRS>EPSG:4988</SRS>\n      <SRS>EPSG:4989</SRS>\n      <SRS>EPSG:4990</SRS>\n      <SRS>EPSG:4991</SRS>\n      <SRS>EPSG:4992</SRS>\n      <SRS>EPSG:4993</SRS>\n      <SRS>EPSG:4994</SRS>\n      <SRS>EPSG:4995</SRS>\n      <SRS>EPSG:4996</SRS>\n      <SRS>EPSG:4997</SRS>\n      <SRS>EPSG:4998</SRS>\n      <SRS>EPSG:4999</SRS>\n      <SRS>EPSG:5600</SRS>\n      <SRS>EPSG:5601</SRS>\n      <SRS>EPSG:5602</SRS>\n      <SRS>EPSG:5603</SRS>\n      <SRS>EPSG:5604</SRS>\n      <SRS>EPSG:5605</SRS>\n      <SRS>EPSG:5606</SRS>\n      <SRS>EPSG:5607</SRS>\n      <SRS>EPSG:5608</SRS>\n      <SRS>EPSG:5609</SRS>\n      <SRS>EPSG:5701</SRS>\n      <SRS>EPSG:5702</SRS>\n      <SRS>EPSG:5703</SRS>\n      <SRS>EPSG:5704</SRS>\n      <SRS>EPSG:5705</SRS>\n      <SRS>EPSG:5706</SRS>\n      <SRS>EPSG:5709</SRS>\n      <SRS>EPSG:5710</SRS>\n      <SRS>EPSG:5711</SRS>\n      <SRS>EPSG:5712</SRS>\n      <SRS>EPSG:5713</SRS>\n      <SRS>EPSG:5714</SRS>\n      <SRS>EPSG:5715</SRS>\n      <SRS>EPSG:5716</SRS>\n      <SRS>EPSG:5717</SRS>\n      <SRS>EPSG:5718</SRS>\n      <SRS>EPSG:5719</SRS>\n      <SRS>EPSG:5720</SRS>\n      <SRS>EPSG:5721</SRS>\n      <SRS>EPSG:5722</SRS>\n      <SRS>EPSG:5723</SRS>\n      <SRS>EPSG:5724</SRS>\n      <SRS>EPSG:5725</SRS>\n      <SRS>EPSG:5726</SRS>\n      <SRS>EPSG:5727</SRS>\n      <SRS>EPSG:5728</SRS>\n      <SRS>EPSG:5729</SRS>\n      <SRS>EPSG:5730</SRS>\n      <SRS>EPSG:5731</SRS>\n      <SRS>EPSG:5732</SRS>\n      <SRS>EPSG:5733</SRS>\n      <SRS>EPSG:5734</SRS>\n      <SRS>EPSG:5735</SRS>\n      <SRS>EPSG:5736</SRS>\n      <SRS>EPSG:5737</SRS>\n      <SRS>EPSG:5738</SRS>\n      <SRS>EPSG:5739</SRS>\n      <SRS>EPSG:5740</SRS>\n      <SRS>EPSG:5741</SRS>\n      <SRS>EPSG:5742</SRS>\n      <SRS>EPSG:5743</SRS>\n      <SRS>EPSG:5744</SRS>\n      <SRS>EPSG:5745</SRS>\n      <SRS>EPSG:5746</SRS>\n      <SRS>EPSG:5747</SRS>\n      <SRS>EPSG:5748</SRS>\n      <SRS>EPSG:5749</SRS>\n      <SRS>EPSG:5750</SRS>\n      <SRS>EPSG:5751</SRS>\n      <SRS>EPSG:5752</SRS>\n      <SRS>EPSG:5753</SRS>\n      <SRS>EPSG:5754</SRS>\n      <SRS>EPSG:5755</SRS>\n      <SRS>EPSG:5756</SRS>\n      <SRS>EPSG:5757</SRS>\n      <SRS>EPSG:5758</SRS>\n      <SRS>EPSG:5759</SRS>\n      <SRS>EPSG:5760</SRS>\n      <SRS>EPSG:5761</SRS>\n      <SRS>EPSG:5762</SRS>\n      <SRS>EPSG:5763</SRS>\n      <SRS>EPSG:5764</SRS>\n      <SRS>EPSG:5765</SRS>\n      <SRS>EPSG:5766</SRS>\n      <SRS>EPSG:5767</SRS>\n      <SRS>EPSG:5768</SRS>\n      <SRS>EPSG:5769</SRS>\n      <SRS>EPSG:5770</SRS>\n      <SRS>EPSG:5771</SRS>\n      <SRS>EPSG:5772</SRS>\n      <SRS>EPSG:5773</SRS>\n      <SRS>EPSG:5774</SRS>\n      <SRS>EPSG:5775</SRS>\n      <SRS>EPSG:5776</SRS>\n      <SRS>EPSG:5777</SRS>\n      <SRS>EPSG:5778</SRS>\n      <SRS>EPSG:5779</SRS>\n      <SRS>EPSG:5780</SRS>\n      <SRS>EPSG:5781</SRS>\n      <SRS>EPSG:5782</SRS>\n      <SRS>EPSG:5783</SRS>\n      <SRS>EPSG:5784</SRS>\n      <SRS>EPSG:5785</SRS>\n      <SRS>EPSG:5786</SRS>\n      <SRS>EPSG:5787</SRS>\n      <SRS>EPSG:5788</SRS>\n      <SRS>EPSG:5789</SRS>\n      <SRS>EPSG:5790</SRS>\n      <SRS>EPSG:5791</SRS>\n      <SRS>EPSG:5792</SRS>\n      <SRS>EPSG:5793</SRS>\n      <SRS>EPSG:5794</SRS>\n      <SRS>EPSG:5795</SRS>\n      <SRS>EPSG:5796</SRS>\n      <SRS>EPSG:5797</SRS>\n      <SRS>EPSG:5798</SRS>\n      <SRS>EPSG:5799</SRS>\n      <SRS>EPSG:5800</SRS>\n      <SRS>EPSG:5801</SRS>\n      <SRS>EPSG:5802</SRS>\n      <SRS>EPSG:5803</SRS>\n      <SRS>EPSG:5804</SRS>\n      <SRS>EPSG:5805</SRS>\n      <SRS>EPSG:5806</SRS>\n      <SRS>EPSG:5807</SRS>\n      <SRS>EPSG:5808</SRS>\n      <SRS>EPSG:5809</SRS>\n      <SRS>EPSG:5810</SRS>\n      <SRS>EPSG:5811</SRS>\n      <SRS>EPSG:5812</SRS>\n      <SRS>EPSG:5813</SRS>\n      <SRS>EPSG:5814</SRS>\n      <SRS>EPSG:5815</SRS>\n      <SRS>EPSG:5816</SRS>\n      <SRS>EPSG:5817</SRS>\n      <SRS>EPSG:5818</SRS>\n      <SRS>EPSG:7400</SRS>\n      <SRS>EPSG:7401</SRS>\n      <SRS>EPSG:7402</SRS>\n      <SRS>EPSG:7403</SRS>\n      <SRS>EPSG:7404</SRS>\n      <SRS>EPSG:7405</SRS>\n      <SRS>EPSG:7406</SRS>\n      <SRS>EPSG:7407</SRS>\n      <SRS>EPSG:7408</SRS>\n      <SRS>EPSG:7409</SRS>\n      <SRS>EPSG:7410</SRS>\n      <SRS>EPSG:7411</SRS>\n      <SRS>EPSG:7412</SRS>\n      <SRS>EPSG:7413</SRS>\n      <SRS>EPSG:7414</SRS>\n      <SRS>EPSG:7415</SRS>\n      <SRS>EPSG:7416</SRS>\n      <SRS>EPSG:7417</SRS>\n      <SRS>EPSG:7418</SRS>\n      <SRS>EPSG:7419</SRS>\n      <SRS>EPSG:7420</SRS>\n      <SRS>EPSG:20004</SRS>\n      <SRS>EPSG:20005</SRS>\n      <SRS>EPSG:20006</SRS>\n      <SRS>EPSG:20007</SRS>\n      <SRS>EPSG:20008</SRS>\n      <SRS>EPSG:20009</SRS>\n      <SRS>EPSG:20010</SRS>\n      <SRS>EPSG:20011</SRS>\n      <SRS>EPSG:20012</SRS>\n      <SRS>EPSG:20013</SRS>\n      <SRS>EPSG:20014</SRS>\n      <SRS>EPSG:20015</SRS>\n      <SRS>EPSG:20016</SRS>\n      <SRS>EPSG:20017</SRS>\n      <SRS>EPSG:20018</SRS>\n      <SRS>EPSG:20019</SRS>\n      <SRS>EPSG:20020</SRS>\n      <SRS>EPSG:20021</SRS>\n      <SRS>EPSG:20022</SRS>\n      <SRS>EPSG:20023</SRS>\n      <SRS>EPSG:20024</SRS>\n      <SRS>EPSG:20025</SRS>\n      <SRS>EPSG:20026</SRS>\n      <SRS>EPSG:20027</SRS>\n      <SRS>EPSG:20028</SRS>\n      <SRS>EPSG:20029</SRS>\n      <SRS>EPSG:20030</SRS>\n      <SRS>EPSG:20031</SRS>\n      <SRS>EPSG:20032</SRS>\n      <SRS>EPSG:20064</SRS>\n      <SRS>EPSG:20065</SRS>\n      <SRS>EPSG:20066</SRS>\n      <SRS>EPSG:20067</SRS>\n      <SRS>EPSG:20068</SRS>\n      <SRS>EPSG:20069</SRS>\n      <SRS>EPSG:20070</SRS>\n      <SRS>EPSG:20071</SRS>\n      <SRS>EPSG:20072</SRS>\n      <SRS>EPSG:20073</SRS>\n      <SRS>EPSG:20074</SRS>\n      <SRS>EPSG:20075</SRS>\n      <SRS>EPSG:20076</SRS>\n      <SRS>EPSG:20077</SRS>\n      <SRS>EPSG:20078</SRS>\n      <SRS>EPSG:20079</SRS>\n      <SRS>EPSG:20080</SRS>\n      <SRS>EPSG:20081</SRS>\n      <SRS>EPSG:20082</SRS>\n      <SRS>EPSG:20083</SRS>\n      <SRS>EPSG:20084</SRS>\n      <SRS>EPSG:20085</SRS>\n      <SRS>EPSG:20086</SRS>\n      <SRS>EPSG:20087</SRS>\n      <SRS>EPSG:20088</SRS>\n      <SRS>EPSG:20089</SRS>\n      <SRS>EPSG:20090</SRS>\n      <SRS>EPSG:20091</SRS>\n      <SRS>EPSG:20092</SRS>\n      <SRS>EPSG:20135</SRS>\n      <SRS>EPSG:20136</SRS>\n      <SRS>EPSG:20137</SRS>\n      <SRS>EPSG:20138</SRS>\n      <SRS>EPSG:20248</SRS>\n      <SRS>EPSG:20249</SRS>\n      <SRS>EPSG:20250</SRS>\n      <SRS>EPSG:20251</SRS>\n      <SRS>EPSG:20252</SRS>\n      <SRS>EPSG:20253</SRS>\n      <SRS>EPSG:20254</SRS>\n      <SRS>EPSG:20255</SRS>\n      <SRS>EPSG:20256</SRS>\n      <SRS>EPSG:20257</SRS>\n      <SRS>EPSG:20258</SRS>\n      <SRS>EPSG:20348</SRS>\n      <SRS>EPSG:20349</SRS>\n      <SRS>EPSG:20350</SRS>\n      <SRS>EPSG:20351</SRS>\n      <SRS>EPSG:20352</SRS>\n      <SRS>EPSG:20353</SRS>\n      <SRS>EPSG:20354</SRS>\n      <SRS>EPSG:20355</SRS>\n      <SRS>EPSG:20356</SRS>\n      <SRS>EPSG:20357</SRS>\n      <SRS>EPSG:20358</SRS>\n      <SRS>EPSG:20436</SRS>\n      <SRS>EPSG:20437</SRS>\n      <SRS>EPSG:20438</SRS>\n      <SRS>EPSG:20439</SRS>\n      <SRS>EPSG:20440</SRS>\n      <SRS>EPSG:20499</SRS>\n      <SRS>EPSG:20538</SRS>\n      <SRS>EPSG:20539</SRS>\n      <SRS>EPSG:20790</SRS>\n      <SRS>EPSG:20791</SRS>\n      <SRS>EPSG:20822</SRS>\n      <SRS>EPSG:20823</SRS>\n      <SRS>EPSG:20824</SRS>\n      <SRS>EPSG:20934</SRS>\n      <SRS>EPSG:20935</SRS>\n      <SRS>EPSG:20936</SRS>\n      <SRS>EPSG:21035</SRS>\n      <SRS>EPSG:21036</SRS>\n      <SRS>EPSG:21037</SRS>\n      <SRS>EPSG:21095</SRS>\n      <SRS>EPSG:21096</SRS>\n      <SRS>EPSG:21097</SRS>\n      <SRS>EPSG:21100</SRS>\n      <SRS>EPSG:21148</SRS>\n      <SRS>EPSG:21149</SRS>\n      <SRS>EPSG:21150</SRS>\n      <SRS>EPSG:21291</SRS>\n      <SRS>EPSG:21292</SRS>\n      <SRS>EPSG:21413</SRS>\n      <SRS>EPSG:21414</SRS>\n      <SRS>EPSG:21415</SRS>\n      <SRS>EPSG:21416</SRS>\n      <SRS>EPSG:21417</SRS>\n      <SRS>EPSG:21418</SRS>\n      <SRS>EPSG:21419</SRS>\n      <SRS>EPSG:21420</SRS>\n      <SRS>EPSG:21421</SRS>\n      <SRS>EPSG:21422</SRS>\n      <SRS>EPSG:21423</SRS>\n      <SRS>EPSG:21453</SRS>\n      <SRS>EPSG:21454</SRS>\n      <SRS>EPSG:21455</SRS>\n      <SRS>EPSG:21456</SRS>\n      <SRS>EPSG:21457</SRS>\n      <SRS>EPSG:21458</SRS>\n      <SRS>EPSG:21459</SRS>\n      <SRS>EPSG:21460</SRS>\n      <SRS>EPSG:21461</SRS>\n      <SRS>EPSG:21462</SRS>\n      <SRS>EPSG:21463</SRS>\n      <SRS>EPSG:21473</SRS>\n      <SRS>EPSG:21474</SRS>\n      <SRS>EPSG:21475</SRS>\n      <SRS>EPSG:21476</SRS>\n      <SRS>EPSG:21477</SRS>\n      <SRS>EPSG:21478</SRS>\n      <SRS>EPSG:21479</SRS>\n      <SRS>EPSG:21480</SRS>\n      <SRS>EPSG:21481</SRS>\n      <SRS>EPSG:21482</SRS>\n      <SRS>EPSG:21483</SRS>\n      <SRS>EPSG:21500</SRS>\n      <SRS>EPSG:21780</SRS>\n      <SRS>EPSG:21781</SRS>\n      <SRS>EPSG:21817</SRS>\n      <SRS>EPSG:21818</SRS>\n      <SRS>EPSG:21891</SRS>\n      <SRS>EPSG:21892</SRS>\n      <SRS>EPSG:21893</SRS>\n      <SRS>EPSG:21894</SRS>\n      <SRS>EPSG:21896</SRS>\n      <SRS>EPSG:21897</SRS>\n      <SRS>EPSG:21898</SRS>\n      <SRS>EPSG:21899</SRS>\n      <SRS>EPSG:22032</SRS>\n      <SRS>EPSG:22033</SRS>\n      <SRS>EPSG:22091</SRS>\n      <SRS>EPSG:22092</SRS>\n      <SRS>EPSG:22171</SRS>\n      <SRS>EPSG:22172</SRS>\n      <SRS>EPSG:22173</SRS>\n      <SRS>EPSG:22174</SRS>\n      <SRS>EPSG:22175</SRS>\n      <SRS>EPSG:22176</SRS>\n      <SRS>EPSG:22177</SRS>\n      <SRS>EPSG:22181</SRS>\n      <SRS>EPSG:22182</SRS>\n      <SRS>EPSG:22183</SRS>\n      <SRS>EPSG:22184</SRS>\n      <SRS>EPSG:22185</SRS>\n      <SRS>EPSG:22186</SRS>\n      <SRS>EPSG:22187</SRS>\n      <SRS>EPSG:22191</SRS>\n      <SRS>EPSG:22192</SRS>\n      <SRS>EPSG:22193</SRS>\n      <SRS>EPSG:22194</SRS>\n      <SRS>EPSG:22195</SRS>\n      <SRS>EPSG:22196</SRS>\n      <SRS>EPSG:22197</SRS>\n      <SRS>EPSG:22234</SRS>\n      <SRS>EPSG:22235</SRS>\n      <SRS>EPSG:22236</SRS>\n      <SRS>EPSG:22275</SRS>\n      <SRS>EPSG:22277</SRS>\n      <SRS>EPSG:22279</SRS>\n      <SRS>EPSG:22281</SRS>\n      <SRS>EPSG:22283</SRS>\n      <SRS>EPSG:22285</SRS>\n      <SRS>EPSG:22287</SRS>\n      <SRS>EPSG:22289</SRS>\n      <SRS>EPSG:22291</SRS>\n      <SRS>EPSG:22293</SRS>\n      <SRS>EPSG:22300</SRS>\n      <SRS>EPSG:22332</SRS>\n      <SRS>EPSG:22391</SRS>\n      <SRS>EPSG:22392</SRS>\n      <SRS>EPSG:22521</SRS>\n      <SRS>EPSG:22522</SRS>\n      <SRS>EPSG:22523</SRS>\n      <SRS>EPSG:22524</SRS>\n      <SRS>EPSG:22525</SRS>\n      <SRS>EPSG:22700</SRS>\n      <SRS>EPSG:22770</SRS>\n      <SRS>EPSG:22780</SRS>\n      <SRS>EPSG:22832</SRS>\n      <SRS>EPSG:22991</SRS>\n      <SRS>EPSG:22992</SRS>\n      <SRS>EPSG:22993</SRS>\n      <SRS>EPSG:22994</SRS>\n      <SRS>EPSG:23028</SRS>\n      <SRS>EPSG:23029</SRS>\n      <SRS>EPSG:23030</SRS>\n      <SRS>EPSG:23031</SRS>\n      <SRS>EPSG:23032</SRS>\n      <SRS>EPSG:23033</SRS>\n      <SRS>EPSG:23034</SRS>\n      <SRS>EPSG:23035</SRS>\n      <SRS>EPSG:23036</SRS>\n      <SRS>EPSG:23037</SRS>\n      <SRS>EPSG:23038</SRS>\n      <SRS>EPSG:23090</SRS>\n      <SRS>EPSG:23095</SRS>\n      <SRS>EPSG:23239</SRS>\n      <SRS>EPSG:23240</SRS>\n      <SRS>EPSG:23433</SRS>\n      <SRS>EPSG:23700</SRS>\n      <SRS>EPSG:23846</SRS>\n      <SRS>EPSG:23847</SRS>\n      <SRS>EPSG:23848</SRS>\n      <SRS>EPSG:23849</SRS>\n      <SRS>EPSG:23850</SRS>\n      <SRS>EPSG:23851</SRS>\n      <SRS>EPSG:23852</SRS>\n      <SRS>EPSG:23853</SRS>\n      <SRS>EPSG:23866</SRS>\n      <SRS>EPSG:23867</SRS>\n      <SRS>EPSG:23868</SRS>\n      <SRS>EPSG:23869</SRS>\n      <SRS>EPSG:23870</SRS>\n      <SRS>EPSG:23871</SRS>\n      <SRS>EPSG:23872</SRS>\n      <SRS>EPSG:23877</SRS>\n      <SRS>EPSG:23878</SRS>\n      <SRS>EPSG:23879</SRS>\n      <SRS>EPSG:23880</SRS>\n      <SRS>EPSG:23881</SRS>\n      <SRS>EPSG:23882</SRS>\n      <SRS>EPSG:23883</SRS>\n      <SRS>EPSG:23884</SRS>\n      <SRS>EPSG:23886</SRS>\n      <SRS>EPSG:23887</SRS>\n      <SRS>EPSG:23888</SRS>\n      <SRS>EPSG:23889</SRS>\n      <SRS>EPSG:23890</SRS>\n      <SRS>EPSG:23891</SRS>\n      <SRS>EPSG:23892</SRS>\n      <SRS>EPSG:23893</SRS>\n      <SRS>EPSG:23894</SRS>\n      <SRS>EPSG:23946</SRS>\n      <SRS>EPSG:23947</SRS>\n      <SRS>EPSG:23948</SRS>\n      <SRS>EPSG:24047</SRS>\n      <SRS>EPSG:24048</SRS>\n      <SRS>EPSG:24100</SRS>\n      <SRS>EPSG:24200</SRS>\n      <SRS>EPSG:24305</SRS>\n      <SRS>EPSG:24306</SRS>\n      <SRS>EPSG:24311</SRS>\n      <SRS>EPSG:24312</SRS>\n      <SRS>EPSG:24313</SRS>\n      <SRS>EPSG:24342</SRS>\n      <SRS>EPSG:24343</SRS>\n      <SRS>EPSG:24344</SRS>\n      <SRS>EPSG:24345</SRS>\n      <SRS>EPSG:24346</SRS>\n      <SRS>EPSG:24347</SRS>\n      <SRS>EPSG:24370</SRS>\n      <SRS>EPSG:24371</SRS>\n      <SRS>EPSG:24372</SRS>\n      <SRS>EPSG:24373</SRS>\n      <SRS>EPSG:24374</SRS>\n      <SRS>EPSG:24375</SRS>\n      <SRS>EPSG:24376</SRS>\n      <SRS>EPSG:24377</SRS>\n      <SRS>EPSG:24378</SRS>\n      <SRS>EPSG:24379</SRS>\n      <SRS>EPSG:24380</SRS>\n      <SRS>EPSG:24381</SRS>\n      <SRS>EPSG:24382</SRS>\n      <SRS>EPSG:24383</SRS>\n      <SRS>EPSG:24500</SRS>\n      <SRS>EPSG:24547</SRS>\n      <SRS>EPSG:24548</SRS>\n      <SRS>EPSG:24571</SRS>\n      <SRS>EPSG:24600</SRS>\n      <SRS>EPSG:24718</SRS>\n      <SRS>EPSG:24719</SRS>\n      <SRS>EPSG:24720</SRS>\n      <SRS>EPSG:24817</SRS>\n      <SRS>EPSG:24818</SRS>\n      <SRS>EPSG:24819</SRS>\n      <SRS>EPSG:24820</SRS>\n      <SRS>EPSG:24821</SRS>\n      <SRS>EPSG:24877</SRS>\n      <SRS>EPSG:24878</SRS>\n      <SRS>EPSG:24879</SRS>\n      <SRS>EPSG:24880</SRS>\n      <SRS>EPSG:24881</SRS>\n      <SRS>EPSG:24882</SRS>\n      <SRS>EPSG:24891</SRS>\n      <SRS>EPSG:24892</SRS>\n      <SRS>EPSG:24893</SRS>\n      <SRS>EPSG:25000</SRS>\n      <SRS>EPSG:25231</SRS>\n      <SRS>EPSG:25391</SRS>\n      <SRS>EPSG:25392</SRS>\n      <SRS>EPSG:25393</SRS>\n      <SRS>EPSG:25394</SRS>\n      <SRS>EPSG:25395</SRS>\n      <SRS>EPSG:25700</SRS>\n      <SRS>EPSG:25828</SRS>\n      <SRS>EPSG:25829</SRS>\n      <SRS>EPSG:25830</SRS>\n      <SRS>EPSG:25831</SRS>\n      <SRS>EPSG:25832</SRS>\n      <SRS>EPSG:25833</SRS>\n      <SRS>EPSG:25834</SRS>\n      <SRS>EPSG:25835</SRS>\n      <SRS>EPSG:25836</SRS>\n      <SRS>EPSG:25837</SRS>\n      <SRS>EPSG:25838</SRS>\n      <SRS>EPSG:25884</SRS>\n      <SRS>EPSG:25932</SRS>\n      <SRS>EPSG:26191</SRS>\n      <SRS>EPSG:26192</SRS>\n      <SRS>EPSG:26193</SRS>\n      <SRS>EPSG:26194</SRS>\n      <SRS>EPSG:26195</SRS>\n      <SRS>EPSG:26237</SRS>\n      <SRS>EPSG:26331</SRS>\n      <SRS>EPSG:26332</SRS>\n      <SRS>EPSG:26391</SRS>\n      <SRS>EPSG:26392</SRS>\n      <SRS>EPSG:26393</SRS>\n      <SRS>EPSG:26432</SRS>\n      <SRS>EPSG:26591</SRS>\n      <SRS>EPSG:26592</SRS>\n      <SRS>EPSG:26632</SRS>\n      <SRS>EPSG:26692</SRS>\n      <SRS>EPSG:26701</SRS>\n      <SRS>EPSG:26702</SRS>\n      <SRS>EPSG:26703</SRS>\n      <SRS>EPSG:26704</SRS>\n      <SRS>EPSG:26705</SRS>\n      <SRS>EPSG:26706</SRS>\n      <SRS>EPSG:26707</SRS>\n      <SRS>EPSG:26708</SRS>\n      <SRS>EPSG:26709</SRS>\n      <SRS>EPSG:26710</SRS>\n      <SRS>EPSG:26711</SRS>\n      <SRS>EPSG:26712</SRS>\n      <SRS>EPSG:26713</SRS>\n      <SRS>EPSG:26714</SRS>\n      <SRS>EPSG:26715</SRS>\n      <SRS>EPSG:26716</SRS>\n      <SRS>EPSG:26717</SRS>\n      <SRS>EPSG:26718</SRS>\n      <SRS>EPSG:26719</SRS>\n      <SRS>EPSG:26720</SRS>\n      <SRS>EPSG:26721</SRS>\n      <SRS>EPSG:26722</SRS>\n      <SRS>EPSG:26729</SRS>\n      <SRS>EPSG:26730</SRS>\n      <SRS>EPSG:26731</SRS>\n      <SRS>EPSG:26732</SRS>\n      <SRS>EPSG:26733</SRS>\n      <SRS>EPSG:26734</SRS>\n      <SRS>EPSG:26735</SRS>\n      <SRS>EPSG:26736</SRS>\n      <SRS>EPSG:26737</SRS>\n      <SRS>EPSG:26738</SRS>\n      <SRS>EPSG:26739</SRS>\n      <SRS>EPSG:26740</SRS>\n      <SRS>EPSG:26741</SRS>\n      <SRS>EPSG:26742</SRS>\n      <SRS>EPSG:26743</SRS>\n      <SRS>EPSG:26744</SRS>\n      <SRS>EPSG:26745</SRS>\n      <SRS>EPSG:26746</SRS>\n      <SRS>EPSG:26747</SRS>\n      <SRS>EPSG:26748</SRS>\n      <SRS>EPSG:26749</SRS>\n      <SRS>EPSG:26750</SRS>\n      <SRS>EPSG:26751</SRS>\n      <SRS>EPSG:26752</SRS>\n      <SRS>EPSG:26753</SRS>\n      <SRS>EPSG:26754</SRS>\n      <SRS>EPSG:26755</SRS>\n      <SRS>EPSG:26756</SRS>\n      <SRS>EPSG:26757</SRS>\n      <SRS>EPSG:26758</SRS>\n      <SRS>EPSG:26759</SRS>\n      <SRS>EPSG:26760</SRS>\n      <SRS>EPSG:26766</SRS>\n      <SRS>EPSG:26767</SRS>\n      <SRS>EPSG:26768</SRS>\n      <SRS>EPSG:26769</SRS>\n      <SRS>EPSG:26770</SRS>\n      <SRS>EPSG:26771</SRS>\n      <SRS>EPSG:26772</SRS>\n      <SRS>EPSG:26773</SRS>\n      <SRS>EPSG:26774</SRS>\n      <SRS>EPSG:26775</SRS>\n      <SRS>EPSG:26776</SRS>\n      <SRS>EPSG:26777</SRS>\n      <SRS>EPSG:26778</SRS>\n      <SRS>EPSG:26779</SRS>\n      <SRS>EPSG:26780</SRS>\n      <SRS>EPSG:26781</SRS>\n      <SRS>EPSG:26782</SRS>\n      <SRS>EPSG:26783</SRS>\n      <SRS>EPSG:26784</SRS>\n      <SRS>EPSG:26785</SRS>\n      <SRS>EPSG:26786</SRS>\n      <SRS>EPSG:26787</SRS>\n      <SRS>EPSG:26791</SRS>\n      <SRS>EPSG:26792</SRS>\n      <SRS>EPSG:26793</SRS>\n      <SRS>EPSG:26794</SRS>\n      <SRS>EPSG:26795</SRS>\n      <SRS>EPSG:26796</SRS>\n      <SRS>EPSG:26797</SRS>\n      <SRS>EPSG:26798</SRS>\n      <SRS>EPSG:26799</SRS>\n      <SRS>EPSG:26801</SRS>\n      <SRS>EPSG:26802</SRS>\n      <SRS>EPSG:26803</SRS>\n      <SRS>EPSG:26811</SRS>\n      <SRS>EPSG:26812</SRS>\n      <SRS>EPSG:26813</SRS>\n      <SRS>EPSG:26901</SRS>\n      <SRS>EPSG:26902</SRS>\n      <SRS>EPSG:26903</SRS>\n      <SRS>EPSG:26904</SRS>\n      <SRS>EPSG:26905</SRS>\n      <SRS>EPSG:26906</SRS>\n      <SRS>EPSG:26907</SRS>\n      <SRS>EPSG:26908</SRS>\n      <SRS>EPSG:26909</SRS>\n      <SRS>EPSG:26910</SRS>\n      <SRS>EPSG:26911</SRS>\n      <SRS>EPSG:26912</SRS>\n      <SRS>EPSG:26913</SRS>\n      <SRS>EPSG:26914</SRS>\n      <SRS>EPSG:26915</SRS>\n      <SRS>EPSG:26916</SRS>\n      <SRS>EPSG:26917</SRS>\n      <SRS>EPSG:26918</SRS>\n      <SRS>EPSG:26919</SRS>\n      <SRS>EPSG:26920</SRS>\n      <SRS>EPSG:26921</SRS>\n      <SRS>EPSG:26922</SRS>\n      <SRS>EPSG:26923</SRS>\n      <SRS>EPSG:26929</SRS>\n      <SRS>EPSG:26930</SRS>\n      <SRS>EPSG:26931</SRS>\n      <SRS>EPSG:26932</SRS>\n      <SRS>EPSG:26933</SRS>\n      <SRS>EPSG:26934</SRS>\n      <SRS>EPSG:26935</SRS>\n      <SRS>EPSG:26936</SRS>\n      <SRS>EPSG:26937</SRS>\n      <SRS>EPSG:26938</SRS>\n      <SRS>EPSG:26939</SRS>\n      <SRS>EPSG:26940</SRS>\n      <SRS>EPSG:26941</SRS>\n      <SRS>EPSG:26942</SRS>\n      <SRS>EPSG:26943</SRS>\n      <SRS>EPSG:26944</SRS>\n      <SRS>EPSG:26945</SRS>\n      <SRS>EPSG:26946</SRS>\n      <SRS>EPSG:26948</SRS>\n      <SRS>EPSG:26949</SRS>\n      <SRS>EPSG:26950</SRS>\n      <SRS>EPSG:26951</SRS>\n      <SRS>EPSG:26952</SRS>\n      <SRS>EPSG:26953</SRS>\n      <SRS>EPSG:26954</SRS>\n      <SRS>EPSG:26955</SRS>\n      <SRS>EPSG:26956</SRS>\n      <SRS>EPSG:26957</SRS>\n      <SRS>EPSG:26958</SRS>\n      <SRS>EPSG:26959</SRS>\n      <SRS>EPSG:26960</SRS>\n      <SRS>EPSG:26961</SRS>\n      <SRS>EPSG:26962</SRS>\n      <SRS>EPSG:26963</SRS>\n      <SRS>EPSG:26964</SRS>\n      <SRS>EPSG:26965</SRS>\n      <SRS>EPSG:26966</SRS>\n      <SRS>EPSG:26967</SRS>\n      <SRS>EPSG:26968</SRS>\n      <SRS>EPSG:26969</SRS>\n      <SRS>EPSG:26970</SRS>\n      <SRS>EPSG:26971</SRS>\n      <SRS>EPSG:26972</SRS>\n      <SRS>EPSG:26973</SRS>\n      <SRS>EPSG:26974</SRS>\n      <SRS>EPSG:26975</SRS>\n      <SRS>EPSG:26976</SRS>\n      <SRS>EPSG:26977</SRS>\n      <SRS>EPSG:26978</SRS>\n      <SRS>EPSG:26979</SRS>\n      <SRS>EPSG:26980</SRS>\n      <SRS>EPSG:26981</SRS>\n      <SRS>EPSG:26982</SRS>\n      <SRS>EPSG:26983</SRS>\n      <SRS>EPSG:26984</SRS>\n      <SRS>EPSG:26985</SRS>\n      <SRS>EPSG:26986</SRS>\n      <SRS>EPSG:26987</SRS>\n      <SRS>EPSG:26988</SRS>\n      <SRS>EPSG:26989</SRS>\n      <SRS>EPSG:26990</SRS>\n      <SRS>EPSG:26991</SRS>\n      <SRS>EPSG:26992</SRS>\n      <SRS>EPSG:26993</SRS>\n      <SRS>EPSG:26994</SRS>\n      <SRS>EPSG:26995</SRS>\n      <SRS>EPSG:26996</SRS>\n      <SRS>EPSG:26997</SRS>\n      <SRS>EPSG:26998</SRS>\n      <SRS>EPSG:27037</SRS>\n      <SRS>EPSG:27038</SRS>\n      <SRS>EPSG:27039</SRS>\n      <SRS>EPSG:27040</SRS>\n      <SRS>EPSG:27120</SRS>\n      <SRS>EPSG:27200</SRS>\n      <SRS>EPSG:27205</SRS>\n      <SRS>EPSG:27206</SRS>\n      <SRS>EPSG:27207</SRS>\n      <SRS>EPSG:27208</SRS>\n      <SRS>EPSG:27209</SRS>\n      <SRS>EPSG:27210</SRS>\n      <SRS>EPSG:27211</SRS>\n      <SRS>EPSG:27212</SRS>\n      <SRS>EPSG:27213</SRS>\n      <SRS>EPSG:27214</SRS>\n      <SRS>EPSG:27215</SRS>\n      <SRS>EPSG:27216</SRS>\n      <SRS>EPSG:27217</SRS>\n      <SRS>EPSG:27218</SRS>\n      <SRS>EPSG:27219</SRS>\n      <SRS>EPSG:27220</SRS>\n      <SRS>EPSG:27221</SRS>\n      <SRS>EPSG:27222</SRS>\n      <SRS>EPSG:27223</SRS>\n      <SRS>EPSG:27224</SRS>\n      <SRS>EPSG:27225</SRS>\n      <SRS>EPSG:27226</SRS>\n      <SRS>EPSG:27227</SRS>\n      <SRS>EPSG:27228</SRS>\n      <SRS>EPSG:27229</SRS>\n      <SRS>EPSG:27230</SRS>\n      <SRS>EPSG:27231</SRS>\n      <SRS>EPSG:27232</SRS>\n      <SRS>EPSG:27258</SRS>\n      <SRS>EPSG:27259</SRS>\n      <SRS>EPSG:27260</SRS>\n      <SRS>EPSG:27291</SRS>\n      <SRS>EPSG:27292</SRS>\n      <SRS>EPSG:27391</SRS>\n      <SRS>EPSG:27392</SRS>\n      <SRS>EPSG:27393</SRS>\n      <SRS>EPSG:27394</SRS>\n      <SRS>EPSG:27395</SRS>\n      <SRS>EPSG:27396</SRS>\n      <SRS>EPSG:27397</SRS>\n      <SRS>EPSG:27398</SRS>\n      <SRS>EPSG:27429</SRS>\n      <SRS>EPSG:27492</SRS>\n      <SRS>EPSG:27500</SRS>\n      <SRS>EPSG:27561</SRS>\n      <SRS>EPSG:27562</SRS>\n      <SRS>EPSG:27563</SRS>\n      <SRS>EPSG:27564</SRS>\n      <SRS>EPSG:27571</SRS>\n      <SRS>EPSG:27572</SRS>\n      <SRS>EPSG:27573</SRS>\n      <SRS>EPSG:27574</SRS>\n      <SRS>EPSG:27581</SRS>\n      <SRS>EPSG:27582</SRS>\n      <SRS>EPSG:27583</SRS>\n      <SRS>EPSG:27584</SRS>\n      <SRS>EPSG:27591</SRS>\n      <SRS>EPSG:27592</SRS>\n      <SRS>EPSG:27593</SRS>\n      <SRS>EPSG:27594</SRS>\n      <SRS>EPSG:27700</SRS>\n      <SRS>EPSG:28191</SRS>\n      <SRS>EPSG:28192</SRS>\n      <SRS>EPSG:28193</SRS>\n      <SRS>EPSG:28232</SRS>\n      <SRS>EPSG:28348</SRS>\n      <SRS>EPSG:28349</SRS>\n      <SRS>EPSG:28350</SRS>\n      <SRS>EPSG:28351</SRS>\n      <SRS>EPSG:28352</SRS>\n      <SRS>EPSG:28353</SRS>\n      <SRS>EPSG:28354</SRS>\n      <SRS>EPSG:28355</SRS>\n      <SRS>EPSG:28356</SRS>\n      <SRS>EPSG:28357</SRS>\n      <SRS>EPSG:28358</SRS>\n      <SRS>EPSG:28402</SRS>\n      <SRS>EPSG:28403</SRS>\n      <SRS>EPSG:28404</SRS>\n      <SRS>EPSG:28405</SRS>\n      <SRS>EPSG:28406</SRS>\n      <SRS>EPSG:28407</SRS>\n      <SRS>EPSG:28408</SRS>\n      <SRS>EPSG:28409</SRS>\n      <SRS>EPSG:28410</SRS>\n      <SRS>EPSG:28411</SRS>\n      <SRS>EPSG:28412</SRS>\n      <SRS>EPSG:28413</SRS>\n      <SRS>EPSG:28414</SRS>\n      <SRS>EPSG:28415</SRS>\n      <SRS>EPSG:28416</SRS>\n      <SRS>EPSG:28417</SRS>\n      <SRS>EPSG:28418</SRS>\n      <SRS>EPSG:28419</SRS>\n      <SRS>EPSG:28420</SRS>\n      <SRS>EPSG:28421</SRS>\n      <SRS>EPSG:28422</SRS>\n      <SRS>EPSG:28423</SRS>\n      <SRS>EPSG:28424</SRS>\n      <SRS>EPSG:28425</SRS>\n      <SRS>EPSG:28426</SRS>\n      <SRS>EPSG:28427</SRS>\n      <SRS>EPSG:28428</SRS>\n      <SRS>EPSG:28429</SRS>\n      <SRS>EPSG:28430</SRS>\n      <SRS>EPSG:28431</SRS>\n      <SRS>EPSG:28432</SRS>\n      <SRS>EPSG:28462</SRS>\n      <SRS>EPSG:28463</SRS>\n      <SRS>EPSG:28464</SRS>\n      <SRS>EPSG:28465</SRS>\n      <SRS>EPSG:28466</SRS>\n      <SRS>EPSG:28467</SRS>\n      <SRS>EPSG:28468</SRS>\n      <SRS>EPSG:28469</SRS>\n      <SRS>EPSG:28470</SRS>\n      <SRS>EPSG:28471</SRS>\n      <SRS>EPSG:28472</SRS>\n      <SRS>EPSG:28473</SRS>\n      <SRS>EPSG:28474</SRS>\n      <SRS>EPSG:28475</SRS>\n      <SRS>EPSG:28476</SRS>\n      <SRS>EPSG:28477</SRS>\n      <SRS>EPSG:28478</SRS>\n      <SRS>EPSG:28479</SRS>\n      <SRS>EPSG:28480</SRS>\n      <SRS>EPSG:28481</SRS>\n      <SRS>EPSG:28482</SRS>\n      <SRS>EPSG:28483</SRS>\n      <SRS>EPSG:28484</SRS>\n      <SRS>EPSG:28485</SRS>\n      <SRS>EPSG:28486</SRS>\n      <SRS>EPSG:28487</SRS>\n      <SRS>EPSG:28488</SRS>\n      <SRS>EPSG:28489</SRS>\n      <SRS>EPSG:28490</SRS>\n      <SRS>EPSG:28491</SRS>\n      <SRS>EPSG:28492</SRS>\n      <SRS>EPSG:28600</SRS>\n      <SRS>EPSG:28991</SRS>\n      <SRS>EPSG:28992</SRS>\n      <SRS>EPSG:29100</SRS>\n      <SRS>EPSG:29101</SRS>\n      <SRS>EPSG:29118</SRS>\n      <SRS>EPSG:29119</SRS>\n      <SRS>EPSG:29120</SRS>\n      <SRS>EPSG:29121</SRS>\n      <SRS>EPSG:29122</SRS>\n      <SRS>EPSG:29168</SRS>\n      <SRS>EPSG:29169</SRS>\n      <SRS>EPSG:29170</SRS>\n      <SRS>EPSG:29171</SRS>\n      <SRS>EPSG:29172</SRS>\n      <SRS>EPSG:29177</SRS>\n      <SRS>EPSG:29178</SRS>\n      <SRS>EPSG:29179</SRS>\n      <SRS>EPSG:29180</SRS>\n      <SRS>EPSG:29181</SRS>\n      <SRS>EPSG:29182</SRS>\n      <SRS>EPSG:29183</SRS>\n      <SRS>EPSG:29184</SRS>\n      <SRS>EPSG:29185</SRS>\n      <SRS>EPSG:29187</SRS>\n      <SRS>EPSG:29188</SRS>\n      <SRS>EPSG:29189</SRS>\n      <SRS>EPSG:29190</SRS>\n      <SRS>EPSG:29191</SRS>\n      <SRS>EPSG:29192</SRS>\n      <SRS>EPSG:29193</SRS>\n      <SRS>EPSG:29194</SRS>\n      <SRS>EPSG:29195</SRS>\n      <SRS>EPSG:29220</SRS>\n      <SRS>EPSG:29221</SRS>\n      <SRS>EPSG:29333</SRS>\n      <SRS>EPSG:29371</SRS>\n      <SRS>EPSG:29373</SRS>\n      <SRS>EPSG:29375</SRS>\n      <SRS>EPSG:29377</SRS>\n      <SRS>EPSG:29379</SRS>\n      <SRS>EPSG:29381</SRS>\n      <SRS>EPSG:29383</SRS>\n      <SRS>EPSG:29385</SRS>\n      <SRS>EPSG:29635</SRS>\n      <SRS>EPSG:29636</SRS>\n      <SRS>EPSG:29700</SRS>\n      <SRS>EPSG:29701</SRS>\n      <SRS>EPSG:29702</SRS>\n      <SRS>EPSG:29738</SRS>\n      <SRS>EPSG:29739</SRS>\n      <SRS>EPSG:29849</SRS>\n      <SRS>EPSG:29850</SRS>\n      <SRS>EPSG:29871</SRS>\n      <SRS>EPSG:29872</SRS>\n      <SRS>EPSG:29873</SRS>\n      <SRS>EPSG:29900</SRS>\n      <SRS>EPSG:29901</SRS>\n      <SRS>EPSG:29902</SRS>\n      <SRS>EPSG:29903</SRS>\n      <SRS>EPSG:30161</SRS>\n      <SRS>EPSG:30162</SRS>\n      <SRS>EPSG:30163</SRS>\n      <SRS>EPSG:30164</SRS>\n      <SRS>EPSG:30165</SRS>\n      <SRS>EPSG:30166</SRS>\n      <SRS>EPSG:30167</SRS>\n      <SRS>EPSG:30168</SRS>\n      <SRS>EPSG:30169</SRS>\n      <SRS>EPSG:30170</SRS>\n      <SRS>EPSG:30171</SRS>\n      <SRS>EPSG:30172</SRS>\n      <SRS>EPSG:30173</SRS>\n      <SRS>EPSG:30174</SRS>\n      <SRS>EPSG:30175</SRS>\n      <SRS>EPSG:30176</SRS>\n      <SRS>EPSG:30177</SRS>\n      <SRS>EPSG:30178</SRS>\n      <SRS>EPSG:30179</SRS>\n      <SRS>EPSG:30200</SRS>\n      <SRS>EPSG:30339</SRS>\n      <SRS>EPSG:30340</SRS>\n      <SRS>EPSG:30491</SRS>\n      <SRS>EPSG:30492</SRS>\n      <SRS>EPSG:30493</SRS>\n      <SRS>EPSG:30494</SRS>\n      <SRS>EPSG:30729</SRS>\n      <SRS>EPSG:30730</SRS>\n      <SRS>EPSG:30731</SRS>\n      <SRS>EPSG:30732</SRS>\n      <SRS>EPSG:30791</SRS>\n      <SRS>EPSG:30792</SRS>\n      <SRS>EPSG:30800</SRS>\n      <SRS>EPSG:31028</SRS>\n      <SRS>EPSG:31121</SRS>\n      <SRS>EPSG:31154</SRS>\n      <SRS>EPSG:31170</SRS>\n      <SRS>EPSG:31171</SRS>\n      <SRS>EPSG:31251</SRS>\n      <SRS>EPSG:31252</SRS>\n      <SRS>EPSG:31253</SRS>\n      <SRS>EPSG:31254</SRS>\n      <SRS>EPSG:31255</SRS>\n      <SRS>EPSG:31256</SRS>\n      <SRS>EPSG:31257</SRS>\n      <SRS>EPSG:31258</SRS>\n      <SRS>EPSG:31259</SRS>\n      <SRS>EPSG:31265</SRS>\n      <SRS>EPSG:31266</SRS>\n      <SRS>EPSG:31267</SRS>\n      <SRS>EPSG:31268</SRS>\n      <SRS>EPSG:31275</SRS>\n      <SRS>EPSG:31276</SRS>\n      <SRS>EPSG:31277</SRS>\n      <SRS>EPSG:31278</SRS>\n      <SRS>EPSG:31279</SRS>\n      <SRS>EPSG:31281</SRS>\n      <SRS>EPSG:31282</SRS>\n      <SRS>EPSG:31283</SRS>\n      <SRS>EPSG:31284</SRS>\n      <SRS>EPSG:31285</SRS>\n      <SRS>EPSG:31286</SRS>\n      <SRS>EPSG:31287</SRS>\n      <SRS>EPSG:31288</SRS>\n      <SRS>EPSG:31289</SRS>\n      <SRS>EPSG:31290</SRS>\n      <SRS>EPSG:31291</SRS>\n      <SRS>EPSG:31292</SRS>\n      <SRS>EPSG:31293</SRS>\n      <SRS>EPSG:31294</SRS>\n      <SRS>EPSG:31295</SRS>\n      <SRS>EPSG:31296</SRS>\n      <SRS>EPSG:31297</SRS>\n      <SRS>EPSG:31300</SRS>\n      <SRS>EPSG:31370</SRS>\n      <SRS>EPSG:31461</SRS>\n      <SRS>EPSG:31462</SRS>\n      <SRS>EPSG:31463</SRS>\n      <SRS>EPSG:31464</SRS>\n      <SRS>EPSG:31465</SRS>\n      <SRS>EPSG:31466</SRS>\n      <SRS>EPSG:31467</SRS>\n      <SRS>EPSG:31468</SRS>\n      <SRS>EPSG:31469</SRS>\n      <SRS>EPSG:31528</SRS>\n      <SRS>EPSG:31529</SRS>\n      <SRS>EPSG:31600</SRS>\n      <SRS>EPSG:31700</SRS>\n      <SRS>EPSG:31838</SRS>\n      <SRS>EPSG:31839</SRS>\n      <SRS>EPSG:31900</SRS>\n      <SRS>EPSG:31901</SRS>\n      <SRS>EPSG:31965</SRS>\n      <SRS>EPSG:31966</SRS>\n      <SRS>EPSG:31967</SRS>\n      <SRS>EPSG:31968</SRS>\n      <SRS>EPSG:31969</SRS>\n      <SRS>EPSG:31970</SRS>\n      <SRS>EPSG:31971</SRS>\n      <SRS>EPSG:31972</SRS>\n      <SRS>EPSG:31973</SRS>\n      <SRS>EPSG:31974</SRS>\n      <SRS>EPSG:31975</SRS>\n      <SRS>EPSG:31976</SRS>\n      <SRS>EPSG:31977</SRS>\n      <SRS>EPSG:31978</SRS>\n      <SRS>EPSG:31979</SRS>\n      <SRS>EPSG:31980</SRS>\n      <SRS>EPSG:31981</SRS>\n      <SRS>EPSG:31982</SRS>\n      <SRS>EPSG:31983</SRS>\n      <SRS>EPSG:31984</SRS>\n      <SRS>EPSG:31985</SRS>\n      <SRS>EPSG:31986</SRS>\n      <SRS>EPSG:31987</SRS>\n      <SRS>EPSG:31988</SRS>\n      <SRS>EPSG:31989</SRS>\n      <SRS>EPSG:31990</SRS>\n      <SRS>EPSG:31991</SRS>\n      <SRS>EPSG:31992</SRS>\n      <SRS>EPSG:31993</SRS>\n      <SRS>EPSG:31994</SRS>\n      <SRS>EPSG:31995</SRS>\n      <SRS>EPSG:31996</SRS>\n      <SRS>EPSG:31997</SRS>\n      <SRS>EPSG:31998</SRS>\n      <SRS>EPSG:31999</SRS>\n      <SRS>EPSG:32000</SRS>\n      <SRS>EPSG:32001</SRS>\n      <SRS>EPSG:32002</SRS>\n      <SRS>EPSG:32003</SRS>\n      <SRS>EPSG:32005</SRS>\n      <SRS>EPSG:32006</SRS>\n      <SRS>EPSG:32007</SRS>\n      <SRS>EPSG:32008</SRS>\n      <SRS>EPSG:32009</SRS>\n      <SRS>EPSG:32010</SRS>\n      <SRS>EPSG:32011</SRS>\n      <SRS>EPSG:32012</SRS>\n      <SRS>EPSG:32013</SRS>\n      <SRS>EPSG:32014</SRS>\n      <SRS>EPSG:32015</SRS>\n      <SRS>EPSG:32016</SRS>\n      <SRS>EPSG:32017</SRS>\n      <SRS>EPSG:32018</SRS>\n      <SRS>EPSG:32019</SRS>\n      <SRS>EPSG:32020</SRS>\n      <SRS>EPSG:32021</SRS>\n      <SRS>EPSG:32022</SRS>\n      <SRS>EPSG:32023</SRS>\n      <SRS>EPSG:32024</SRS>\n      <SRS>EPSG:32025</SRS>\n      <SRS>EPSG:32026</SRS>\n      <SRS>EPSG:32027</SRS>\n      <SRS>EPSG:32028</SRS>\n      <SRS>EPSG:32029</SRS>\n      <SRS>EPSG:32030</SRS>\n      <SRS>EPSG:32031</SRS>\n      <SRS>EPSG:32033</SRS>\n      <SRS>EPSG:32034</SRS>\n      <SRS>EPSG:32035</SRS>\n      <SRS>EPSG:32036</SRS>\n      <SRS>EPSG:32037</SRS>\n      <SRS>EPSG:32038</SRS>\n      <SRS>EPSG:32039</SRS>\n      <SRS>EPSG:32040</SRS>\n      <SRS>EPSG:32041</SRS>\n      <SRS>EPSG:32042</SRS>\n      <SRS>EPSG:32043</SRS>\n      <SRS>EPSG:32044</SRS>\n      <SRS>EPSG:32045</SRS>\n      <SRS>EPSG:32046</SRS>\n      <SRS>EPSG:32047</SRS>\n      <SRS>EPSG:32048</SRS>\n      <SRS>EPSG:32049</SRS>\n      <SRS>EPSG:32050</SRS>\n      <SRS>EPSG:32051</SRS>\n      <SRS>EPSG:32052</SRS>\n      <SRS>EPSG:32053</SRS>\n      <SRS>EPSG:32054</SRS>\n      <SRS>EPSG:32055</SRS>\n      <SRS>EPSG:32056</SRS>\n      <SRS>EPSG:32057</SRS>\n      <SRS>EPSG:32058</SRS>\n      <SRS>EPSG:32061</SRS>\n      <SRS>EPSG:32062</SRS>\n      <SRS>EPSG:32064</SRS>\n      <SRS>EPSG:32065</SRS>\n      <SRS>EPSG:32066</SRS>\n      <SRS>EPSG:32067</SRS>\n      <SRS>EPSG:32074</SRS>\n      <SRS>EPSG:32075</SRS>\n      <SRS>EPSG:32076</SRS>\n      <SRS>EPSG:32077</SRS>\n      <SRS>EPSG:32081</SRS>\n      <SRS>EPSG:32082</SRS>\n      <SRS>EPSG:32083</SRS>\n      <SRS>EPSG:32084</SRS>\n      <SRS>EPSG:32085</SRS>\n      <SRS>EPSG:32086</SRS>\n      <SRS>EPSG:32098</SRS>\n      <SRS>EPSG:32099</SRS>\n      <SRS>EPSG:32100</SRS>\n      <SRS>EPSG:32104</SRS>\n      <SRS>EPSG:32107</SRS>\n      <SRS>EPSG:32108</SRS>\n      <SRS>EPSG:32109</SRS>\n      <SRS>EPSG:32110</SRS>\n      <SRS>EPSG:32111</SRS>\n      <SRS>EPSG:32112</SRS>\n      <SRS>EPSG:32113</SRS>\n      <SRS>EPSG:32114</SRS>\n      <SRS>EPSG:32115</SRS>\n      <SRS>EPSG:32116</SRS>\n      <SRS>EPSG:32117</SRS>\n      <SRS>EPSG:32118</SRS>\n      <SRS>EPSG:32119</SRS>\n      <SRS>EPSG:32120</SRS>\n      <SRS>EPSG:32121</SRS>\n      <SRS>EPSG:32122</SRS>\n      <SRS>EPSG:32123</SRS>\n      <SRS>EPSG:32124</SRS>\n      <SRS>EPSG:32125</SRS>\n      <SRS>EPSG:32126</SRS>\n      <SRS>EPSG:32127</SRS>\n      <SRS>EPSG:32128</SRS>\n      <SRS>EPSG:32129</SRS>\n      <SRS>EPSG:32130</SRS>\n      <SRS>EPSG:32133</SRS>\n      <SRS>EPSG:32134</SRS>\n      <SRS>EPSG:32135</SRS>\n      <SRS>EPSG:32136</SRS>\n      <SRS>EPSG:32137</SRS>\n      <SRS>EPSG:32138</SRS>\n      <SRS>EPSG:32139</SRS>\n      <SRS>EPSG:32140</SRS>\n      <SRS>EPSG:32141</SRS>\n      <SRS>EPSG:32142</SRS>\n      <SRS>EPSG:32143</SRS>\n      <SRS>EPSG:32144</SRS>\n      <SRS>EPSG:32145</SRS>\n      <SRS>EPSG:32146</SRS>\n      <SRS>EPSG:32147</SRS>\n      <SRS>EPSG:32148</SRS>\n      <SRS>EPSG:32149</SRS>\n      <SRS>EPSG:32150</SRS>\n      <SRS>EPSG:32151</SRS>\n      <SRS>EPSG:32152</SRS>\n      <SRS>EPSG:32153</SRS>\n      <SRS>EPSG:32154</SRS>\n      <SRS>EPSG:32155</SRS>\n      <SRS>EPSG:32156</SRS>\n      <SRS>EPSG:32157</SRS>\n      <SRS>EPSG:32158</SRS>\n      <SRS>EPSG:32161</SRS>\n      <SRS>EPSG:32164</SRS>\n      <SRS>EPSG:32165</SRS>\n      <SRS>EPSG:32166</SRS>\n      <SRS>EPSG:32167</SRS>\n      <SRS>EPSG:32180</SRS>\n      <SRS>EPSG:32181</SRS>\n      <SRS>EPSG:32182</SRS>\n      <SRS>EPSG:32183</SRS>\n      <SRS>EPSG:32184</SRS>\n      <SRS>EPSG:32185</SRS>\n      <SRS>EPSG:32186</SRS>\n      <SRS>EPSG:32187</SRS>\n      <SRS>EPSG:32188</SRS>\n      <SRS>EPSG:32189</SRS>\n      <SRS>EPSG:32190</SRS>\n      <SRS>EPSG:32191</SRS>\n      <SRS>EPSG:32192</SRS>\n      <SRS>EPSG:32193</SRS>\n      <SRS>EPSG:32194</SRS>\n      <SRS>EPSG:32195</SRS>\n      <SRS>EPSG:32196</SRS>\n      <SRS>EPSG:32197</SRS>\n      <SRS>EPSG:32198</SRS>\n      <SRS>EPSG:32199</SRS>\n      <SRS>EPSG:32201</SRS>\n      <SRS>EPSG:32202</SRS>\n      <SRS>EPSG:32203</SRS>\n      <SRS>EPSG:32204</SRS>\n      <SRS>EPSG:32205</SRS>\n      <SRS>EPSG:32206</SRS>\n      <SRS>EPSG:32207</SRS>\n      <SRS>EPSG:32208</SRS>\n      <SRS>EPSG:32209</SRS>\n      <SRS>EPSG:32210</SRS>\n      <SRS>EPSG:32211</SRS>\n      <SRS>EPSG:32212</SRS>\n      <SRS>EPSG:32213</SRS>\n      <SRS>EPSG:32214</SRS>\n      <SRS>EPSG:32215</SRS>\n      <SRS>EPSG:32216</SRS>\n      <SRS>EPSG:32217</SRS>\n      <SRS>EPSG:32218</SRS>\n      <SRS>EPSG:32219</SRS>\n      <SRS>EPSG:32220</SRS>\n      <SRS>EPSG:32221</SRS>\n      <SRS>EPSG:32222</SRS>\n      <SRS>EPSG:32223</SRS>\n      <SRS>EPSG:32224</SRS>\n      <SRS>EPSG:32225</SRS>\n      <SRS>EPSG:32226</SRS>\n      <SRS>EPSG:32227</SRS>\n      <SRS>EPSG:32228</SRS>\n      <SRS>EPSG:32229</SRS>\n      <SRS>EPSG:32230</SRS>\n      <SRS>EPSG:32231</SRS>\n      <SRS>EPSG:32232</SRS>\n      <SRS>EPSG:32233</SRS>\n      <SRS>EPSG:32234</SRS>\n      <SRS>EPSG:32235</SRS>\n      <SRS>EPSG:32236</SRS>\n      <SRS>EPSG:32237</SRS>\n      <SRS>EPSG:32238</SRS>\n      <SRS>EPSG:32239</SRS>\n      <SRS>EPSG:32240</SRS>\n      <SRS>EPSG:32241</SRS>\n      <SRS>EPSG:32242</SRS>\n      <SRS>EPSG:32243</SRS>\n      <SRS>EPSG:32244</SRS>\n      <SRS>EPSG:32245</SRS>\n      <SRS>EPSG:32246</SRS>\n      <SRS>EPSG:32247</SRS>\n      <SRS>EPSG:32248</SRS>\n      <SRS>EPSG:32249</SRS>\n      <SRS>EPSG:32250</SRS>\n      <SRS>EPSG:32251</SRS>\n      <SRS>EPSG:32252</SRS>\n      <SRS>EPSG:32253</SRS>\n      <SRS>EPSG:32254</SRS>\n      <SRS>EPSG:32255</SRS>\n      <SRS>EPSG:32256</SRS>\n      <SRS>EPSG:32257</SRS>\n      <SRS>EPSG:32258</SRS>\n      <SRS>EPSG:32259</SRS>\n      <SRS>EPSG:32260</SRS>\n      <SRS>EPSG:32301</SRS>\n      <SRS>EPSG:32302</SRS>\n      <SRS>EPSG:32303</SRS>\n      <SRS>EPSG:32304</SRS>\n      <SRS>EPSG:32305</SRS>\n      <SRS>EPSG:32306</SRS>\n      <SRS>EPSG:32307</SRS>\n      <SRS>EPSG:32308</SRS>\n      <SRS>EPSG:32309</SRS>\n      <SRS>EPSG:32310</SRS>\n      <SRS>EPSG:32311</SRS>\n      <SRS>EPSG:32312</SRS>\n      <SRS>EPSG:32313</SRS>\n      <SRS>EPSG:32314</SRS>\n      <SRS>EPSG:32315</SRS>\n      <SRS>EPSG:32316</SRS>\n      <SRS>EPSG:32317</SRS>\n      <SRS>EPSG:32318</SRS>\n      <SRS>EPSG:32319</SRS>\n      <SRS>EPSG:32320</SRS>\n      <SRS>EPSG:32321</SRS>\n      <SRS>EPSG:32322</SRS>\n      <SRS>EPSG:32323</SRS>\n      <SRS>EPSG:32324</SRS>\n      <SRS>EPSG:32325</SRS>\n      <SRS>EPSG:32326</SRS>\n      <SRS>EPSG:32327</SRS>\n      <SRS>EPSG:32328</SRS>\n      <SRS>EPSG:32329</SRS>\n      <SRS>EPSG:32330</SRS>\n      <SRS>EPSG:32331</SRS>\n      <SRS>EPSG:32332</SRS>\n      <SRS>EPSG:32333</SRS>\n      <SRS>EPSG:32334</SRS>\n      <SRS>EPSG:32335</SRS>\n      <SRS>EPSG:32336</SRS>\n      <SRS>EPSG:32337</SRS>\n      <SRS>EPSG:32338</SRS>\n      <SRS>EPSG:32339</SRS>\n      <SRS>EPSG:32340</SRS>\n      <SRS>EPSG:32341</SRS>\n      <SRS>EPSG:32342</SRS>\n      <SRS>EPSG:32343</SRS>\n      <SRS>EPSG:32344</SRS>\n      <SRS>EPSG:32345</SRS>\n      <SRS>EPSG:32346</SRS>\n      <SRS>EPSG:32347</SRS>\n      <SRS>EPSG:32348</SRS>\n      <SRS>EPSG:32349</SRS>\n      <SRS>EPSG:32350</SRS>\n      <SRS>EPSG:32351</SRS>\n      <SRS>EPSG:32352</SRS>\n      <SRS>EPSG:32353</SRS>\n      <SRS>EPSG:32354</SRS>\n      <SRS>EPSG:32355</SRS>\n      <SRS>EPSG:32356</SRS>\n      <SRS>EPSG:32357</SRS>\n      <SRS>EPSG:32358</SRS>\n      <SRS>EPSG:32359</SRS>\n      <SRS>EPSG:32360</SRS>\n      <SRS>EPSG:32401</SRS>\n      <SRS>EPSG:32402</SRS>\n      <SRS>EPSG:32403</SRS>\n      <SRS>EPSG:32404</SRS>\n      <SRS>EPSG:32405</SRS>\n      <SRS>EPSG:32406</SRS>\n      <SRS>EPSG:32407</SRS>\n      <SRS>EPSG:32408</SRS>\n      <SRS>EPSG:32409</SRS>\n      <SRS>EPSG:32410</SRS>\n      <SRS>EPSG:32411</SRS>\n      <SRS>EPSG:32412</SRS>\n      <SRS>EPSG:32413</SRS>\n      <SRS>EPSG:32414</SRS>\n      <SRS>EPSG:32415</SRS>\n      <SRS>EPSG:32416</SRS>\n      <SRS>EPSG:32417</SRS>\n      <SRS>EPSG:32418</SRS>\n      <SRS>EPSG:32419</SRS>\n      <SRS>EPSG:32420</SRS>\n      <SRS>EPSG:32421</SRS>\n      <SRS>EPSG:32422</SRS>\n      <SRS>EPSG:32423</SRS>\n      <SRS>EPSG:32424</SRS>\n      <SRS>EPSG:32425</SRS>\n      <SRS>EPSG:32426</SRS>\n      <SRS>EPSG:32427</SRS>\n      <SRS>EPSG:32428</SRS>\n      <SRS>EPSG:32429</SRS>\n      <SRS>EPSG:32430</SRS>\n      <SRS>EPSG:32431</SRS>\n      <SRS>EPSG:32432</SRS>\n      <SRS>EPSG:32433</SRS>\n      <SRS>EPSG:32434</SRS>\n      <SRS>EPSG:32435</SRS>\n      <SRS>EPSG:32436</SRS>\n      <SRS>EPSG:32437</SRS>\n      <SRS>EPSG:32438</SRS>\n      <SRS>EPSG:32439</SRS>\n      <SRS>EPSG:32440</SRS>\n      <SRS>EPSG:32441</SRS>\n      <SRS>EPSG:32442</SRS>\n      <SRS>EPSG:32443</SRS>\n      <SRS>EPSG:32444</SRS>\n      <SRS>EPSG:32445</SRS>\n      <SRS>EPSG:32446</SRS>\n      <SRS>EPSG:32447</SRS>\n      <SRS>EPSG:32448</SRS>\n      <SRS>EPSG:32449</SRS>\n      <SRS>EPSG:32450</SRS>\n      <SRS>EPSG:32451</SRS>\n      <SRS>EPSG:32452</SRS>\n      <SRS>EPSG:32453</SRS>\n      <SRS>EPSG:32454</SRS>\n      <SRS>EPSG:32455</SRS>\n      <SRS>EPSG:32456</SRS>\n      <SRS>EPSG:32457</SRS>\n      <SRS>EPSG:32458</SRS>\n      <SRS>EPSG:32459</SRS>\n      <SRS>EPSG:32460</SRS>\n      <SRS>EPSG:32501</SRS>\n      <SRS>EPSG:32502</SRS>\n      <SRS>EPSG:32503</SRS>\n      <SRS>EPSG:32504</SRS>\n      <SRS>EPSG:32505</SRS>\n      <SRS>EPSG:32506</SRS>\n      <SRS>EPSG:32507</SRS>\n      <SRS>EPSG:32508</SRS>\n      <SRS>EPSG:32509</SRS>\n      <SRS>EPSG:32510</SRS>\n      <SRS>EPSG:32511</SRS>\n      <SRS>EPSG:32512</SRS>\n      <SRS>EPSG:32513</SRS>\n      <SRS>EPSG:32514</SRS>\n      <SRS>EPSG:32515</SRS>\n      <SRS>EPSG:32516</SRS>\n      <SRS>EPSG:32517</SRS>\n      <SRS>EPSG:32518</SRS>\n      <SRS>EPSG:32519</SRS>\n      <SRS>EPSG:32520</SRS>\n      <SRS>EPSG:32521</SRS>\n      <SRS>EPSG:32522</SRS>\n      <SRS>EPSG:32523</SRS>\n      <SRS>EPSG:32524</SRS>\n      <SRS>EPSG:32525</SRS>\n      <SRS>EPSG:32526</SRS>\n      <SRS>EPSG:32527</SRS>\n      <SRS>EPSG:32528</SRS>\n      <SRS>EPSG:32529</SRS>\n      <SRS>EPSG:32530</SRS>\n      <SRS>EPSG:32531</SRS>\n      <SRS>EPSG:32532</SRS>\n      <SRS>EPSG:32533</SRS>\n      <SRS>EPSG:32534</SRS>\n      <SRS>EPSG:32535</SRS>\n      <SRS>EPSG:32536</SRS>\n      <SRS>EPSG:32537</SRS>\n      <SRS>EPSG:32538</SRS>\n      <SRS>EPSG:32539</SRS>\n      <SRS>EPSG:32540</SRS>\n      <SRS>EPSG:32541</SRS>\n      <SRS>EPSG:32542</SRS>\n      <SRS>EPSG:32543</SRS>\n      <SRS>EPSG:32544</SRS>\n      <SRS>EPSG:32545</SRS>\n      <SRS>EPSG:32546</SRS>\n      <SRS>EPSG:32547</SRS>\n      <SRS>EPSG:32548</SRS>\n      <SRS>EPSG:32549</SRS>\n      <SRS>EPSG:32550</SRS>\n      <SRS>EPSG:32551</SRS>\n      <SRS>EPSG:32552</SRS>\n      <SRS>EPSG:32553</SRS>\n      <SRS>EPSG:32554</SRS>\n      <SRS>EPSG:32555</SRS>\n      <SRS>EPSG:32556</SRS>\n      <SRS>EPSG:32557</SRS>\n      <SRS>EPSG:32558</SRS>\n      <SRS>EPSG:32559</SRS>\n      <SRS>EPSG:32560</SRS>\n      <SRS>EPSG:32600</SRS>\n      <SRS>EPSG:32601</SRS>\n      <SRS>EPSG:32602</SRS>\n      <SRS>EPSG:32603</SRS>\n      <SRS>EPSG:32604</SRS>\n      <SRS>EPSG:32605</SRS>\n      <SRS>EPSG:32606</SRS>\n      <SRS>EPSG:32607</SRS>\n      <SRS>EPSG:32608</SRS>\n      <SRS>EPSG:32609</SRS>\n      <SRS>EPSG:32610</SRS>\n      <SRS>EPSG:32611</SRS>\n      <SRS>EPSG:32612</SRS>\n      <SRS>EPSG:32613</SRS>\n      <SRS>EPSG:32614</SRS>\n      <SRS>EPSG:32615</SRS>\n      <SRS>EPSG:32616</SRS>\n      <SRS>EPSG:32617</SRS>\n      <SRS>EPSG:32618</SRS>\n      <SRS>EPSG:32619</SRS>\n      <SRS>EPSG:32620</SRS>\n      <SRS>EPSG:32621</SRS>\n      <SRS>EPSG:32622</SRS>\n      <SRS>EPSG:32623</SRS>\n      <SRS>EPSG:32624</SRS>\n      <SRS>EPSG:32625</SRS>\n      <SRS>EPSG:32626</SRS>\n      <SRS>EPSG:32627</SRS>\n      <SRS>EPSG:32628</SRS>\n      <SRS>EPSG:32629</SRS>\n      <SRS>EPSG:32630</SRS>\n      <SRS>EPSG:32631</SRS>\n      <SRS>EPSG:32632</SRS>\n      <SRS>EPSG:32633</SRS>\n      <SRS>EPSG:32634</SRS>\n      <SRS>EPSG:32635</SRS>\n      <SRS>EPSG:32636</SRS>\n      <SRS>EPSG:32637</SRS>\n      <SRS>EPSG:32638</SRS>\n      <SRS>EPSG:32639</SRS>\n      <SRS>EPSG:32640</SRS>\n      <SRS>EPSG:32641</SRS>\n      <SRS>EPSG:32642</SRS>\n      <SRS>EPSG:32643</SRS>\n      <SRS>EPSG:32644</SRS>\n      <SRS>EPSG:32645</SRS>\n      <SRS>EPSG:32646</SRS>\n      <SRS>EPSG:32647</SRS>\n      <SRS>EPSG:32648</SRS>\n      <SRS>EPSG:32649</SRS>\n      <SRS>EPSG:32650</SRS>\n      <SRS>EPSG:32651</SRS>\n      <SRS>EPSG:32652</SRS>\n      <SRS>EPSG:32653</SRS>\n      <SRS>EPSG:32654</SRS>\n      <SRS>EPSG:32655</SRS>\n      <SRS>EPSG:32656</SRS>\n      <SRS>EPSG:32657</SRS>\n      <SRS>EPSG:32658</SRS>\n      <SRS>EPSG:32659</SRS>\n      <SRS>EPSG:32660</SRS>\n      <SRS>EPSG:32661</SRS>\n      <SRS>EPSG:32662</SRS>\n      <SRS>EPSG:32664</SRS>\n      <SRS>EPSG:32665</SRS>\n      <SRS>EPSG:32666</SRS>\n      <SRS>EPSG:32667</SRS>\n      <SRS>EPSG:32700</SRS>\n      <SRS>EPSG:32701</SRS>\n      <SRS>EPSG:32702</SRS>\n      <SRS>EPSG:32703</SRS>\n      <SRS>EPSG:32704</SRS>\n      <SRS>EPSG:32705</SRS>\n      <SRS>EPSG:32706</SRS>\n      <SRS>EPSG:32707</SRS>\n      <SRS>EPSG:32708</SRS>\n      <SRS>EPSG:32709</SRS>\n      <SRS>EPSG:32710</SRS>\n      <SRS>EPSG:32711</SRS>\n      <SRS>EPSG:32712</SRS>\n      <SRS>EPSG:32713</SRS>\n      <SRS>EPSG:32714</SRS>\n      <SRS>EPSG:32715</SRS>\n      <SRS>EPSG:32716</SRS>\n      <SRS>EPSG:32717</SRS>\n      <SRS>EPSG:32718</SRS>\n      <SRS>EPSG:32719</SRS>\n      <SRS>EPSG:32720</SRS>\n      <SRS>EPSG:32721</SRS>\n      <SRS>EPSG:32722</SRS>\n      <SRS>EPSG:32723</SRS>\n      <SRS>EPSG:32724</SRS>\n      <SRS>EPSG:32725</SRS>\n      <SRS>EPSG:32726</SRS>\n      <SRS>EPSG:32727</SRS>\n      <SRS>EPSG:32728</SRS>\n      <SRS>EPSG:32729</SRS>\n      <SRS>EPSG:32730</SRS>\n      <SRS>EPSG:32731</SRS>\n      <SRS>EPSG:32732</SRS>\n      <SRS>EPSG:32733</SRS>\n      <SRS>EPSG:32734</SRS>\n      <SRS>EPSG:32735</SRS>\n      <SRS>EPSG:32736</SRS>\n      <SRS>EPSG:32737</SRS>\n      <SRS>EPSG:32738</SRS>\n      <SRS>EPSG:32739</SRS>\n      <SRS>EPSG:32740</SRS>\n      <SRS>EPSG:32741</SRS>\n      <SRS>EPSG:32742</SRS>\n      <SRS>EPSG:32743</SRS>\n      <SRS>EPSG:32744</SRS>\n      <SRS>EPSG:32745</SRS>\n      <SRS>EPSG:32746</SRS>\n      <SRS>EPSG:32747</SRS>\n      <SRS>EPSG:32748</SRS>\n      <SRS>EPSG:32749</SRS>\n      <SRS>EPSG:32750</SRS>\n      <SRS>EPSG:32751</SRS>\n      <SRS>EPSG:32752</SRS>\n      <SRS>EPSG:32753</SRS>\n      <SRS>EPSG:32754</SRS>\n      <SRS>EPSG:32755</SRS>\n      <SRS>EPSG:32756</SRS>\n      <SRS>EPSG:32757</SRS>\n      <SRS>EPSG:32758</SRS>\n      <SRS>EPSG:32759</SRS>\n      <SRS>EPSG:32760</SRS>\n      <SRS>EPSG:32761</SRS>\n      <SRS>EPSG:32766</SRS>\n      <SRS>EPSG:61206405</SRS>\n      <SRS>EPSG:61216405</SRS>\n      <SRS>EPSG:61226405</SRS>\n      <SRS>EPSG:61236405</SRS>\n      <SRS>EPSG:61246405</SRS>\n      <SRS>EPSG:61266405</SRS>\n      <SRS>EPSG:61266413</SRS>\n      <SRS>EPSG:61276405</SRS>\n      <SRS>EPSG:61286405</SRS>\n      <SRS>EPSG:61296405</SRS>\n      <SRS>EPSG:61306405</SRS>\n      <SRS>EPSG:61306413</SRS>\n      <SRS>EPSG:61316405</SRS>\n      <SRS>EPSG:61326405</SRS>\n      <SRS>EPSG:61336405</SRS>\n      <SRS>EPSG:61346405</SRS>\n      <SRS>EPSG:61356405</SRS>\n      <SRS>EPSG:61366405</SRS>\n      <SRS>EPSG:61376405</SRS>\n      <SRS>EPSG:61386405</SRS>\n      <SRS>EPSG:61396405</SRS>\n      <SRS>EPSG:61406405</SRS>\n      <SRS>EPSG:61406413</SRS>\n      <SRS>EPSG:61416405</SRS>\n      <SRS>EPSG:61426405</SRS>\n      <SRS>EPSG:61436405</SRS>\n      <SRS>EPSG:61446405</SRS>\n      <SRS>EPSG:61456405</SRS>\n      <SRS>EPSG:61466405</SRS>\n      <SRS>EPSG:61476405</SRS>\n      <SRS>EPSG:61486405</SRS>\n      <SRS>EPSG:61486413</SRS>\n      <SRS>EPSG:61496405</SRS>\n      <SRS>EPSG:61506405</SRS>\n      <SRS>EPSG:61516405</SRS>\n      <SRS>EPSG:61516413</SRS>\n      <SRS>EPSG:61526405</SRS>\n      <SRS>EPSG:61526413</SRS>\n      <SRS>EPSG:61536405</SRS>\n      <SRS>EPSG:61546405</SRS>\n      <SRS>EPSG:61556405</SRS>\n      <SRS>EPSG:61566405</SRS>\n      <SRS>EPSG:61576405</SRS>\n      <SRS>EPSG:61586405</SRS>\n      <SRS>EPSG:61596405</SRS>\n      <SRS>EPSG:61606405</SRS>\n      <SRS>EPSG:61616405</SRS>\n      <SRS>EPSG:61626405</SRS>\n      <SRS>EPSG:61636405</SRS>\n      <SRS>EPSG:61636413</SRS>\n      <SRS>EPSG:61646405</SRS>\n      <SRS>EPSG:61656405</SRS>\n      <SRS>EPSG:61666405</SRS>\n      <SRS>EPSG:61676405</SRS>\n      <SRS>EPSG:61676413</SRS>\n      <SRS>EPSG:61686405</SRS>\n      <SRS>EPSG:61696405</SRS>\n      <SRS>EPSG:61706405</SRS>\n      <SRS>EPSG:61706413</SRS>\n      <SRS>EPSG:61716405</SRS>\n      <SRS>EPSG:61716413</SRS>\n      <SRS>EPSG:61736405</SRS>\n      <SRS>EPSG:61736413</SRS>\n      <SRS>EPSG:61746405</SRS>\n      <SRS>EPSG:61756405</SRS>\n      <SRS>EPSG:61766405</SRS>\n      <SRS>EPSG:61766413</SRS>\n      <SRS>EPSG:61786405</SRS>\n      <SRS>EPSG:61796405</SRS>\n      <SRS>EPSG:61806405</SRS>\n      <SRS>EPSG:61806413</SRS>\n      <SRS>EPSG:61816405</SRS>\n      <SRS>EPSG:61826405</SRS>\n      <SRS>EPSG:61836405</SRS>\n      <SRS>EPSG:61846405</SRS>\n      <SRS>EPSG:61886405</SRS>\n      <SRS>EPSG:61896405</SRS>\n      <SRS>EPSG:61896413</SRS>\n      <SRS>EPSG:61906405</SRS>\n      <SRS>EPSG:61906413</SRS>\n      <SRS>EPSG:61916405</SRS>\n      <SRS>EPSG:61926405</SRS>\n      <SRS>EPSG:61936405</SRS>\n      <SRS>EPSG:61946405</SRS>\n      <SRS>EPSG:61956405</SRS>\n      <SRS>EPSG:61966405</SRS>\n      <SRS>EPSG:61976405</SRS>\n      <SRS>EPSG:61986405</SRS>\n      <SRS>EPSG:61996405</SRS>\n      <SRS>EPSG:62006405</SRS>\n      <SRS>EPSG:62016405</SRS>\n      <SRS>EPSG:62026405</SRS>\n      <SRS>EPSG:62036405</SRS>\n      <SRS>EPSG:62046405</SRS>\n      <SRS>EPSG:62056405</SRS>\n      <SRS>EPSG:62066405</SRS>\n      <SRS>EPSG:62076405</SRS>\n      <SRS>EPSG:62086405</SRS>\n      <SRS>EPSG:62096405</SRS>\n      <SRS>EPSG:62106405</SRS>\n      <SRS>EPSG:62116405</SRS>\n      <SRS>EPSG:62126405</SRS>\n      <SRS>EPSG:62136405</SRS>\n      <SRS>EPSG:62146405</SRS>\n      <SRS>EPSG:62156405</SRS>\n      <SRS>EPSG:62166405</SRS>\n      <SRS>EPSG:62186405</SRS>\n      <SRS>EPSG:62196405</SRS>\n      <SRS>EPSG:62206405</SRS>\n      <SRS>EPSG:62216405</SRS>\n      <SRS>EPSG:62226405</SRS>\n      <SRS>EPSG:62236405</SRS>\n      <SRS>EPSG:62246405</SRS>\n      <SRS>EPSG:62256405</SRS>\n      <SRS>EPSG:62276405</SRS>\n      <SRS>EPSG:62296405</SRS>\n      <SRS>EPSG:62306405</SRS>\n      <SRS>EPSG:62316405</SRS>\n      <SRS>EPSG:62326405</SRS>\n      <SRS>EPSG:62336405</SRS>\n      <SRS>EPSG:62366405</SRS>\n      <SRS>EPSG:62376405</SRS>\n      <SRS>EPSG:62386405</SRS>\n      <SRS>EPSG:62396405</SRS>\n      <SRS>EPSG:62406405</SRS>\n      <SRS>EPSG:62416405</SRS>\n      <SRS>EPSG:62426405</SRS>\n      <SRS>EPSG:62436405</SRS>\n      <SRS>EPSG:62446405</SRS>\n      <SRS>EPSG:62456405</SRS>\n      <SRS>EPSG:62466405</SRS>\n      <SRS>EPSG:62476405</SRS>\n      <SRS>EPSG:62486405</SRS>\n      <SRS>EPSG:62496405</SRS>\n      <SRS>EPSG:62506405</SRS>\n      <SRS>EPSG:62516405</SRS>\n      <SRS>EPSG:62526405</SRS>\n      <SRS>EPSG:62536405</SRS>\n      <SRS>EPSG:62546405</SRS>\n      <SRS>EPSG:62556405</SRS>\n      <SRS>EPSG:62566405</SRS>\n      <SRS>EPSG:62576405</SRS>\n      <SRS>EPSG:62586405</SRS>\n      <SRS>EPSG:62586413</SRS>\n      <SRS>EPSG:62596405</SRS>\n      <SRS>EPSG:62616405</SRS>\n      <SRS>EPSG:62626405</SRS>\n      <SRS>EPSG:62636405</SRS>\n      <SRS>EPSG:62646405</SRS>\n      <SRS>EPSG:62656405</SRS>\n      <SRS>EPSG:62666405</SRS>\n      <SRS>EPSG:62676405</SRS>\n      <SRS>EPSG:62686405</SRS>\n      <SRS>EPSG:62696405</SRS>\n      <SRS>EPSG:62706405</SRS>\n      <SRS>EPSG:62716405</SRS>\n      <SRS>EPSG:62726405</SRS>\n      <SRS>EPSG:62736405</SRS>\n      <SRS>EPSG:62746405</SRS>\n      <SRS>EPSG:62756405</SRS>\n      <SRS>EPSG:62766405</SRS>\n      <SRS>EPSG:62776405</SRS>\n      <SRS>EPSG:62786405</SRS>\n      <SRS>EPSG:62796405</SRS>\n      <SRS>EPSG:62806405</SRS>\n      <SRS>EPSG:62816405</SRS>\n      <SRS>EPSG:62826405</SRS>\n      <SRS>EPSG:62836405</SRS>\n      <SRS>EPSG:62836413</SRS>\n      <SRS>EPSG:62846405</SRS>\n      <SRS>EPSG:62856405</SRS>\n      <SRS>EPSG:62866405</SRS>\n      <SRS>EPSG:62886405</SRS>\n      <SRS>EPSG:62896405</SRS>\n      <SRS>EPSG:62926405</SRS>\n      <SRS>EPSG:62936405</SRS>\n      <SRS>EPSG:62956405</SRS>\n      <SRS>EPSG:62976405</SRS>\n      <SRS>EPSG:62986405</SRS>\n      <SRS>EPSG:62996405</SRS>\n      <SRS>EPSG:63006405</SRS>\n      <SRS>EPSG:63016405</SRS>\n      <SRS>EPSG:63026405</SRS>\n      <SRS>EPSG:63036405</SRS>\n      <SRS>EPSG:63046405</SRS>\n      <SRS>EPSG:63066405</SRS>\n      <SRS>EPSG:63076405</SRS>\n      <SRS>EPSG:63086405</SRS>\n      <SRS>EPSG:63096405</SRS>\n      <SRS>EPSG:63106405</SRS>\n      <SRS>EPSG:63116405</SRS>\n      <SRS>EPSG:63126405</SRS>\n      <SRS>EPSG:63136405</SRS>\n      <SRS>EPSG:63146405</SRS>\n      <SRS>EPSG:63156405</SRS>\n      <SRS>EPSG:63166405</SRS>\n      <SRS>EPSG:63176405</SRS>\n      <SRS>EPSG:63186405</SRS>\n      <SRS>EPSG:63196405</SRS>\n      <SRS>EPSG:63226405</SRS>\n      <SRS>EPSG:63246405</SRS>\n      <SRS>EPSG:63266405</SRS>\n      <SRS>EPSG:63266406</SRS>\n      <SRS>EPSG:63266407</SRS>\n      <SRS>EPSG:63266408</SRS>\n      <SRS>EPSG:63266409</SRS>\n      <SRS>EPSG:63266410</SRS>\n      <SRS>EPSG:63266411</SRS>\n      <SRS>EPSG:63266412</SRS>\n      <SRS>EPSG:63266413</SRS>\n      <SRS>EPSG:63266414</SRS>\n      <SRS>EPSG:63266415</SRS>\n      <SRS>EPSG:63266416</SRS>\n      <SRS>EPSG:63266417</SRS>\n      <SRS>EPSG:63266418</SRS>\n      <SRS>EPSG:63266419</SRS>\n      <SRS>EPSG:63266420</SRS>\n      <SRS>EPSG:66006405</SRS>\n      <SRS>EPSG:66016405</SRS>\n      <SRS>EPSG:66026405</SRS>\n      <SRS>EPSG:66036405</SRS>\n      <SRS>EPSG:66046405</SRS>\n      <SRS>EPSG:66056405</SRS>\n      <SRS>EPSG:66066405</SRS>\n      <SRS>EPSG:66076405</SRS>\n      <SRS>EPSG:66086405</SRS>\n      <SRS>EPSG:66096405</SRS>\n      <SRS>EPSG:66106405</SRS>\n      <SRS>EPSG:66116405</SRS>\n      <SRS>EPSG:66126405</SRS>\n      <SRS>EPSG:66126413</SRS>\n      <SRS>EPSG:66136405</SRS>\n      <SRS>EPSG:66146405</SRS>\n      <SRS>EPSG:66156405</SRS>\n      <SRS>EPSG:66166405</SRS>\n      <SRS>EPSG:66186405</SRS>\n      <SRS>EPSG:66196405</SRS>\n      <SRS>EPSG:66196413</SRS>\n      <SRS>EPSG:66206405</SRS>\n      <SRS>EPSG:66216405</SRS>\n      <SRS>EPSG:66226405</SRS>\n      <SRS>EPSG:66236405</SRS>\n      <SRS>EPSG:66246405</SRS>\n      <SRS>EPSG:66246413</SRS>\n      <SRS>EPSG:66256405</SRS>\n      <SRS>EPSG:66266405</SRS>\n      <SRS>EPSG:66276405</SRS>\n      <SRS>EPSG:66276413</SRS>\n      <SRS>EPSG:66286405</SRS>\n      <SRS>EPSG:66296405</SRS>\n      <SRS>EPSG:66306405</SRS>\n      <SRS>EPSG:66316405</SRS>\n      <SRS>EPSG:66326405</SRS>\n      <SRS>EPSG:66336405</SRS>\n      <SRS>EPSG:66346405</SRS>\n      <SRS>EPSG:66356405</SRS>\n      <SRS>EPSG:66366405</SRS>\n      <SRS>EPSG:66376405</SRS>\n      <SRS>EPSG:66386405</SRS>\n      <SRS>EPSG:66396405</SRS>\n      <SRS>EPSG:66406405</SRS>\n      <SRS>EPSG:66406413</SRS>\n      <SRS>EPSG:66416405</SRS>\n      <SRS>EPSG:66426405</SRS>\n      <SRS>EPSG:66436405</SRS>\n      <SRS>EPSG:66446405</SRS>\n      <SRS>EPSG:66456405</SRS>\n      <SRS>EPSG:66456413</SRS>\n      <SRS>EPSG:66466405</SRS>\n      <SRS>EPSG:66576405</SRS>\n      <SRS>EPSG:66586405</SRS>\n      <SRS>EPSG:66596405</SRS>\n      <SRS>EPSG:66596413</SRS>\n      <SRS>EPSG:66606405</SRS>\n      <SRS>EPSG:66616405</SRS>\n      <SRS>EPSG:66616413</SRS>\n      <SRS>EPSG:66636405</SRS>\n      <SRS>EPSG:66646405</SRS>\n      <SRS>EPSG:66656405</SRS>\n      <SRS>EPSG:66666405</SRS>\n      <SRS>EPSG:66676405</SRS>\n      <SRS>EPSG:68016405</SRS>\n      <SRS>EPSG:68026405</SRS>\n      <SRS>EPSG:68036405</SRS>\n      <SRS>EPSG:68046405</SRS>\n      <SRS>EPSG:68056405</SRS>\n      <SRS>EPSG:68066405</SRS>\n      <SRS>EPSG:68086405</SRS>\n      <SRS>EPSG:68096405</SRS>\n      <SRS>EPSG:68136405</SRS>\n      <SRS>EPSG:68146405</SRS>\n      <SRS>EPSG:68156405</SRS>\n      <SRS>EPSG:68186405</SRS>\n      <SRS>EPSG:68206405</SRS>\n      <SRS>EPSG:69036405</SRS>\n      <SRS>EPSG:42302</SRS>\n      <SRS>EPSG:42301</SRS>\n      <SRS>EPSG:900913</SRS>\n      <SRS>EPSG:45556</SRS>\n      <SRS>EPSG:45555</SRS>\n      <SRS>EPSG:54004</SRS>\n      <SRS>EPSG:41001</SRS>\n      <SRS>EPSG:42311</SRS>\n      <SRS>EPSG:42310</SRS>\n      <SRS>EPSG:18001</SRS>\n      <SRS>EPSG:100003</SRS>\n      <SRS>EPSG:42106</SRS>\n      <SRS>EPSG:100002</SRS>\n      <SRS>EPSG:42105</SRS>\n      <SRS>EPSG:100001</SRS>\n      <SRS>EPSG:42309</SRS>\n      <SRS>EPSG:42104</SRS>\n      <SRS>EPSG:42308</SRS>\n      <SRS>EPSG:42103</SRS>\n      <SRS>EPSG:42307</SRS>\n      <SRS>EPSG:42102</SRS>\n      <SRS>EPSG:42306</SRS>\n      <SRS>EPSG:42101</SRS>\n      <SRS>EPSG:42305</SRS>\n      <SRS>EPSG:42304</SRS>\n      <SRS>EPSG:42303</SRS>\n      <LatLonBoundingBox minx=\"-297176.16529836657\" miny=\"-1.2694600326676274E7\" maxx=\"3.0016785704606913E7\" maxy=\"1.7619361543229006E7\"/>\n      <Layer queryable=\"1\">\n        <Name>og:bugsites</Name>\n        <Title/>\n        <Abstract>Sample data from GRASS, bug sites location, Spearfish, South Dakota, USA</Abstract>\n        <KeywordList>\n          <Keyword>spearfish</Keyword>\n          <Keyword>sfBugsites</Keyword>\n          <Keyword>insects</Keyword>\n          <Keyword>bugsites</Keyword>\n          <Keyword>tiger_beetles</Keyword>\n        </KeywordList>\n        <SRS>EPSG:26713</SRS>\n        <!--WKT definition of this CRS:\nPROJCS[\"NAD27 / UTM zone 13N\", \n  GEOGCS[\"NAD27\", \n    DATUM[\"North American Datum 1927\", \n      SPHEROID[\"Clarke 1866\", 6378206.4, 294.9786982138982, AUTHORITY[\"EPSG\",\"7008\"]], \n      TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], \n      AUTHORITY[\"EPSG\",\"6267\"]], \n    PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n    UNIT[\"degree\", 0.017453292519943295], \n    AXIS[\"Geodetic longitude\", EAST], \n    AXIS[\"Geodetic latitude\", NORTH], \n    AUTHORITY[\"EPSG\",\"4267\"]], \n  PROJECTION[\"Transverse Mercator\", AUTHORITY[\"EPSG\",\"9807\"]], \n  PARAMETER[\"central_meridian\", -105.0], \n  PARAMETER[\"latitude_of_origin\", 0.0], \n  PARAMETER[\"scale_factor\", 0.9996], \n  PARAMETER[\"false_easting\", 500000.0], \n  PARAMETER[\"false_northing\", 0.0], \n  UNIT[\"m\", 1.0], \n  AXIS[\"Easting\", EAST], \n  AXIS[\"Northing\", NORTH], \n  AUTHORITY[\"EPSG\",\"26713\"]]-->\n        <LatLonBoundingBox minx=\"-103.8701581843142\" miny=\"44.286540361238224\" maxx=\"-103.63532819794625\" maxy=\"44.52137034760618\"/>\n        <BoundingBox SRS=\"EPSG:26713\" minx=\"590232.0\" miny=\"4914096.0\" maxx=\"608471.0\" maxy=\"4920512.0\"/>\n        <Style>\n          <Name>capitals</Name>\n          <Title>Capital cities</Title>\n          <Abstract/>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=og:bugsites\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>og:restricted</Name>\n        <Title/>\n        <Abstract>Sample data from GRASS, restricted areas, Spearfish, South Dakota, USA</Abstract>\n        <KeywordList>\n          <Keyword>spearfish</Keyword>\n          <Keyword>restricted</Keyword>\n          <Keyword>sfRestricted</Keyword>\n          <Keyword>areas</Keyword>\n        </KeywordList>\n        <SRS>EPSG:26713</SRS>\n        <!--WKT definition of this CRS:\nPROJCS[\"NAD27 / UTM zone 13N\", \n  GEOGCS[\"NAD27\", \n    DATUM[\"North American Datum 1927\", \n      SPHEROID[\"Clarke 1866\", 6378206.4, 294.9786982138982, AUTHORITY[\"EPSG\",\"7008\"]], \n      TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], \n      AUTHORITY[\"EPSG\",\"6267\"]], \n    PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n    UNIT[\"degree\", 0.017453292519943295], \n    AXIS[\"Geodetic longitude\", EAST], \n    AXIS[\"Geodetic latitude\", NORTH], \n    AUTHORITY[\"EPSG\",\"4267\"]], \n  PROJECTION[\"Transverse Mercator\", AUTHORITY[\"EPSG\",\"9807\"]], \n  PARAMETER[\"central_meridian\", -105.0], \n  PARAMETER[\"latitude_of_origin\", 0.0], \n  PARAMETER[\"scale_factor\", 0.9996], \n  PARAMETER[\"false_easting\", 500000.0], \n  PARAMETER[\"false_northing\", 0.0], \n  UNIT[\"m\", 1.0], \n  AXIS[\"Easting\", EAST], \n  AXIS[\"Northing\", NORTH], \n  AUTHORITY[\"EPSG\",\"26713\"]]-->\n        <LatLonBoundingBox minx=\"-104.36424600670885\" miny=\"43.78798270975212\" maxx=\"-103.06226503558304\" maxy=\"45.089963680877936\"/>\n        <BoundingBox SRS=\"EPSG:26713\" minx=\"551796.8125\" miny=\"4901896.0\" maxx=\"652788.5625\" maxy=\"4940954.0\"/>\n        <Style>\n          <Name>restricted</Name>\n          <Title>Red, translucent style</Title>\n          <Abstract>A sample style that just prints out a transparent red interior with a red outline</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=og:restricted\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>og:archsites</Name>\n        <Title/>\n        <Abstract>Sample data from GRASS, archeological sites location, Spearfish, South Dakota, USA</Abstract>\n        <KeywordList>\n          <Keyword>archsites</Keyword>\n          <Keyword>spearfish</Keyword>\n          <Keyword>sfArchsites</Keyword>\n          <Keyword>archeology</Keyword>\n        </KeywordList>\n        <SRS>EPSG:26713</SRS>\n        <!--WKT definition of this CRS:\nPROJCS[\"NAD27 / UTM zone 13N\", \n  GEOGCS[\"NAD27\", \n    DATUM[\"North American Datum 1927\", \n      SPHEROID[\"Clarke 1866\", 6378206.4, 294.9786982138982, AUTHORITY[\"EPSG\",\"7008\"]], \n      TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], \n      AUTHORITY[\"EPSG\",\"6267\"]], \n    PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n    UNIT[\"degree\", 0.017453292519943295], \n    AXIS[\"Geodetic longitude\", EAST], \n    AXIS[\"Geodetic latitude\", NORTH], \n    AUTHORITY[\"EPSG\",\"4267\"]], \n  PROJECTION[\"Transverse Mercator\", AUTHORITY[\"EPSG\",\"9807\"]], \n  PARAMETER[\"central_meridian\", -105.0], \n  PARAMETER[\"latitude_of_origin\", 0.0], \n  PARAMETER[\"scale_factor\", 0.9996], \n  PARAMETER[\"false_easting\", 500000.0], \n  PARAMETER[\"false_northing\", 0.0], \n  UNIT[\"m\", 1.0], \n  AXIS[\"Easting\", EAST], \n  AXIS[\"Northing\", NORTH], \n  AUTHORITY[\"EPSG\",\"26713\"]]-->\n        <LatLonBoundingBox minx=\"-103.87480459767542\" miny=\"44.31295793136913\" maxx=\"-103.63549073047534\" maxy=\"44.55227179856921\"/>\n        <BoundingBox SRS=\"EPSG:26713\" minx=\"589860.0\" miny=\"4914479.0\" maxx=\"608355.0\" maxy=\"4926490.0\"/>\n        <Style>\n          <Name>point</Name>\n          <Title>Default point</Title>\n          <Abstract>A sample style that just prints out a 6px wide red square</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=og:archsites\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>og:streams</Name>\n        <Title/>\n        <Abstract>Sample data from GRASS, streams, Spearfish, South Dakota, USA</Abstract>\n        <KeywordList>\n          <Keyword>spearfish</Keyword>\n          <Keyword>sfStreams</Keyword>\n          <Keyword>streams</Keyword>\n        </KeywordList>\n        <SRS>EPSG:26713</SRS>\n        <!--WKT definition of this CRS:\nPROJCS[\"NAD27 / UTM zone 13N\", \n  GEOGCS[\"NAD27\", \n    DATUM[\"North American Datum 1927\", \n      SPHEROID[\"Clarke 1866\", 6378206.4, 294.9786982138982, AUTHORITY[\"EPSG\",\"7008\"]], \n      TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], \n      AUTHORITY[\"EPSG\",\"6267\"]], \n    PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n    UNIT[\"degree\", 0.017453292519943295], \n    AXIS[\"Geodetic longitude\", EAST], \n    AXIS[\"Geodetic latitude\", NORTH], \n    AUTHORITY[\"EPSG\",\"4267\"]], \n  PROJECTION[\"Transverse Mercator\", AUTHORITY[\"EPSG\",\"9807\"]], \n  PARAMETER[\"central_meridian\", -105.0], \n  PARAMETER[\"latitude_of_origin\", 0.0], \n  PARAMETER[\"scale_factor\", 0.9996], \n  PARAMETER[\"false_easting\", 500000.0], \n  PARAMETER[\"false_northing\", 0.0], \n  UNIT[\"m\", 1.0], \n  AXIS[\"Easting\", EAST], \n  AXIS[\"Northing\", NORTH], \n  AUTHORITY[\"EPSG\",\"26713\"]]-->\n        <LatLonBoundingBox minx=\"-103.88033574142051\" miny=\"44.30711172484593\" maxx=\"-103.62022283326024\" maxy=\"44.5672246330062\"/>\n        <BoundingBox SRS=\"EPSG:26713\" minx=\"589443.0\" miny=\"4913935.0\" maxx=\"609526.75\" maxy=\"4928059.5\"/>\n        <Style>\n          <Name>simple_streams</Name>\n          <Title>Default Styler for streams segments</Title>\n          <Abstract>Blue lines, 2px wide</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=og:streams\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>tiger:poly_landmarks</Name>\n        <Title>Manhattan (NY) landmarks</Title>\n        <Abstract>Manhattan landmarks, identifies water, lakes, parks, interesting buildilngs</Abstract>\n        <KeywordList>\n          <Keyword>DS_poly_landmarks</Keyword>\n          <Keyword>landmarks</Keyword>\n          <Keyword>manhattan</Keyword>\n          <Keyword>poly_landmarks</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <!--WKT definition of this CRS:\nGEOGCS[\"WGS 84\", \n  DATUM[\"World Geodetic System 1984\", \n    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], \n    AUTHORITY[\"EPSG\",\"6326\"]], \n  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n  UNIT[\"degree\", 0.017453292519943295], \n  AXIS[\"Geodetic longitude\", EAST], \n  AXIS[\"Geodetic latitude\", NORTH], \n  AUTHORITY[\"EPSG\",\"4326\"]]-->\n        <LatLonBoundingBox minx=\"-74.0828672737\" miny=\"40.67246384130001\" maxx=\"-73.8660689563\" maxy=\"40.8892621587\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"-74.047185\" miny=\"40.679648\" maxx=\"-73.90782\" maxy=\"40.882078\"/>\n        <Style>\n          <Name>poly_landmarks</Name>\n          <Title>Default Styler</Title>\n          <Abstract/>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tiger:poly_landmarks\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>tiger:poi</Name>\n        <Title>Manhattan (NY) points of interest</Title>\n        <Abstract>Points of interest in New York, New York (on Manhattan). One of the attributes contains the name of a file with a picture of the point of interest.</Abstract>\n        <KeywordList>\n          <Keyword>poi</Keyword>\n          <Keyword>Manhattan</Keyword>\n          <Keyword>DS_poi</Keyword>\n          <Keyword>points_of_interest</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <!--WKT definition of this CRS:\nGEOGCS[\"WGS 84\", \n  DATUM[\"World Geodetic System 1984\", \n    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], \n    AUTHORITY[\"EPSG\",\"6326\"]], \n  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n  UNIT[\"degree\", 0.017453292519943295], \n  AXIS[\"Geodetic longitude\", EAST], \n  AXIS[\"Geodetic latitude\", NORTH], \n  AUTHORITY[\"EPSG\",\"4326\"]]-->\n        <LatLonBoundingBox minx=\"-74.01244590356289\" miny=\"40.70750285086222\" maxx=\"-74.00795911725866\" maxy=\"40.711989637166425\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"-74.0118315772888\" miny=\"40.70754683896324\" maxx=\"-74.00153046439813\" maxy=\"40.719885123828675\"/>\n        <Style>\n          <Name>poi</Name>\n          <Title>Points of interest</Title>\n          <Abstract>Manhattan points of interest</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tiger:poi\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>tiger:tiger_roads</Name>\n        <Title>Manhattan (NY) roads</Title>\n        <Abstract>Highly simplified road layout of Manhattan in New York..</Abstract>\n        <KeywordList>\n          <Keyword>DS_tiger_roads</Keyword>\n          <Keyword>tiger_roads</Keyword>\n          <Keyword>roads</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <!--WKT definition of this CRS:\nGEOGCS[\"WGS 84\", \n  DATUM[\"World Geodetic System 1984\", \n    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], \n    AUTHORITY[\"EPSG\",\"6326\"]], \n  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n  UNIT[\"degree\", 0.017453292519943295], \n  AXIS[\"Geodetic longitude\", EAST], \n  AXIS[\"Geodetic latitude\", NORTH], \n  AUTHORITY[\"EPSG\",\"4326\"]]-->\n        <LatLonBoundingBox minx=\"-74.06603057\" miny=\"40.68228143\" maxx=\"-73.86819443\" maxy=\"40.880117569999996\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"-74.02722\" miny=\"40.684221\" maxx=\"-73.907005\" maxy=\"40.878178\"/>\n        <Style>\n          <Name>tiger_roads</Name>\n          <Title>Default Styler</Title>\n          <Abstract/>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tiger:tiger_roads\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>za:za_natural</Name>\n        <Title>Natural Landmarks in South Africa</Title>\n        <Abstract>This layer describes natural features of South Africa such as forests and lakes.</Abstract>\n        <KeywordList>\n          <Keyword>water</Keyword>\n          <Keyword>forests</Keyword>\n          <Keyword>landmarks</Keyword>\n          <Keyword>Africa</Keyword>\n          <Keyword>South</Keyword>\n          <Keyword>natural</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <!--WKT definition of this CRS:\nGEOGCS[\"WGS 84\", \n  DATUM[\"World Geodetic System 1984\", \n    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], \n    AUTHORITY[\"EPSG\",\"6326\"]], \n  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n  UNIT[\"degree\", 0.017453292519943295], \n  AXIS[\"Geodetic longitude\", EAST], \n  AXIS[\"Geodetic latitude\", NORTH], \n  AUTHORITY[\"EPSG\",\"4326\"]]-->\n        <LatLonBoundingBox minx=\"16.779241142272962\" miny=\"-36.53577846527099\" maxx=\"32.70336002349853\" maxy=\"-20.611659584045416\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"16.935359954834\" miny=\"-34.3737831115723\" maxx=\"32.5472412109375\" maxy=\"-22.7736549377441\"/>\n        <Style>\n          <Name>za_natural</Name>\n          <Title>Default Styler</Title>\n          <Abstract/>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=za:za_natural\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>za:za_points</Name>\n        <Title>Points of Interest in South Africa</Title>\n        <Abstract>Noteworthy locations such as hotels and tourist attractions in South Africa.</Abstract>\n        <KeywordList>\n          <Keyword>of</Keyword>\n          <Keyword>tourist</Keyword>\n          <Keyword>landmarks</Keyword>\n          <Keyword>zoo</Keyword>\n          <Keyword>cities</Keyword>\n          <Keyword>interest</Keyword>\n          <Keyword>attractions</Keyword>\n          <Keyword>points</Keyword>\n          <Keyword>hotel</Keyword>\n          <Keyword>museum</Keyword>\n          <Keyword>picnic</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <!--WKT definition of this CRS:\nGEOGCS[\"WGS 84\", \n  DATUM[\"World Geodetic System 1984\", \n    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], \n    AUTHORITY[\"EPSG\",\"6326\"]], \n  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n  UNIT[\"degree\", 0.017453292519943295], \n  AXIS[\"Geodetic longitude\", EAST], \n  AXIS[\"Geodetic latitude\", NORTH], \n  AUTHORITY[\"EPSG\",\"4326\"]]-->\n        <LatLonBoundingBox minx=\"14.629095230102537\" miny=\"-47.151258316040014\" maxx=\"39.792314376831065\" maxy=\"-21.988039169311488\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"16.4827766418457\" miny=\"-46.9045600891113\" maxx=\"37.9386329650879\" maxy=\"-22.2347373962402\"/>\n        <Style>\n          <Name>za_points</Name>\n          <Title>Default Styler</Title>\n          <Abstract/>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=za:za_points\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>za:za_roads</Name>\n        <Title>South African Roads</Title>\n        <Abstract>This layer describes roads in South Africa.</Abstract>\n        <KeywordList>\n          <Keyword>south</Keyword>\n          <Keyword>africa</Keyword>\n          <Keyword>roads</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <!--WKT definition of this CRS:\nGEOGCS[\"WGS 84\", \n  DATUM[\"World Geodetic System 1984\", \n    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], \n    AUTHORITY[\"EPSG\",\"6326\"]], \n  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n  UNIT[\"degree\", 0.017453292519943295], \n  AXIS[\"Geodetic longitude\", EAST], \n  AXIS[\"Geodetic latitude\", NORTH], \n  AUTHORITY[\"EPSG\",\"4326\"]]-->\n        <LatLonBoundingBox minx=\"16.29388177871706\" miny=\"-36.85438787460323\" maxx=\"33.04232465744013\" maxy=\"-20.10594499588016\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"16.4580821990967\" miny=\"-34.8331336975098\" maxx=\"32.8781242370605\" maxy=\"-22.1271991729736\"/>\n        <Style>\n          <Name>za_roads</Name>\n          <Title>Default Styler</Title>\n          <Abstract/>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=za:za_roads\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>za:za_vegetation</Name>\n        <Title>South African Vegetation</Title>\n        <Abstract>This layer describes vegetated areas in South Africa, categorized by biome.</Abstract>\n        <KeywordList>\n          <Keyword>south</Keyword>\n          <Keyword>vegetation</Keyword>\n          <Keyword>africa</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <!--WKT definition of this CRS:\nGEOGCS[\"WGS 84\", \n  DATUM[\"World Geodetic System 1984\", \n    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], \n    AUTHORITY[\"EPSG\",\"6326\"]], \n  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n  UNIT[\"degree\", 0.017453292519943295], \n  AXIS[\"Geodetic longitude\", EAST], \n  AXIS[\"Geodetic latitude\", NORTH], \n  AUTHORITY[\"EPSG\",\"4326\"]]-->\n        <LatLonBoundingBox minx=\"16.30492322921758\" miny=\"-36.855452365875216\" maxx=\"33.05824930191042\" maxy=\"-20.102126293182376\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"16.4691715240479\" miny=\"-34.8336486816406\" maxx=\"32.8940010070801\" maxy=\"-22.123929977417\"/>\n        <Style>\n          <Name>za_vegetation</Name>\n          <Title>Default Styler</Title>\n          <Abstract/>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=za:za_vegetation\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>topp:tasmania_cities</Name>\n        <Title>Tasmania cities</Title>\n        <Abstract>Cities in Tasmania (actually, just the capital)</Abstract>\n        <KeywordList>\n          <Keyword>cities</Keyword>\n          <Keyword>Tasmania</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <!--WKT definition of this CRS:\nGEOGCS[\"WGS 84\", \n  DATUM[\"World Geodetic System 1984\", \n    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], \n    AUTHORITY[\"EPSG\",\"6326\"]], \n  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n  UNIT[\"degree\", 0.017453292519943295], \n  AXIS[\"Geodetic longitude\", EAST], \n  AXIS[\"Geodetic latitude\", NORTH], \n  AUTHORITY[\"EPSG\",\"4326\"]]-->\n        <LatLonBoundingBox minx=\"145.1667856\" miny=\"-43.706631400000006\" maxx=\"148.30373440000002\" maxy=\"-40.56968259999999\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"147.2910004483\" miny=\"-42.851001816890005\" maxx=\"147.2910004483\" maxy=\"-42.851001816890005\"/>\n        <Style>\n          <Name>capitals</Name>\n          <Title>Capital cities</Title>\n          <Abstract/>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:tasmania_cities\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>topp:tasmania_roads</Name>\n        <Title>Tasmania roads</Title>\n        <Abstract>Main Tasmania roads</Abstract>\n        <KeywordList>\n          <Keyword>Roads</Keyword>\n          <Keyword>Tasmania</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <!--WKT definition of this CRS:\nGEOGCS[\"WGS 84\", \n  DATUM[\"World Geodetic System 1984\", \n    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], \n    AUTHORITY[\"EPSG\",\"6326\"]], \n  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n  UNIT[\"degree\", 0.017453292519943295], \n  AXIS[\"Geodetic longitude\", EAST], \n  AXIS[\"Geodetic latitude\", NORTH], \n  AUTHORITY[\"EPSG\",\"4326\"]]-->\n        <LatLonBoundingBox minx=\"145.1667856\" miny=\"-43.706631400000006\" maxx=\"148.30373440000002\" maxy=\"-40.56968259999999\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"145.19754\" miny=\"-43.423512\" maxx=\"148.27298000000002\" maxy=\"-40.852802\"/>\n        <Style>\n          <Name>simple_roads</Name>\n          <Title>Default Styler for simple road segments</Title>\n          <Abstract>Light red line, 2px wide</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:tasmania_roads\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>topp:tasmania_state_boundaries</Name>\n        <Title>Tasmania state boundaries</Title>\n        <Abstract>Tasmania state boundaries</Abstract>\n        <KeywordList>\n          <Keyword>boundaries</Keyword>\n          <Keyword>tasmania_state_boundaries</Keyword>\n          <Keyword>Tasmania</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <!--WKT definition of this CRS:\nGEOGCS[\"WGS 84\", \n  DATUM[\"World Geodetic System 1984\", \n    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], \n    AUTHORITY[\"EPSG\",\"6326\"]], \n  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n  UNIT[\"degree\", 0.017453292519943295], \n  AXIS[\"Geodetic longitude\", EAST], \n  AXIS[\"Geodetic latitude\", NORTH], \n  AUTHORITY[\"EPSG\",\"4326\"]]-->\n        <LatLonBoundingBox minx=\"143.74100879660003\" miny=\"-44.026947203400006\" maxx=\"148.57295620340003\" maxy=\"-39.194999796599994\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"143.83482400000003\" miny=\"-43.648056\" maxx=\"148.47914100000003\" maxy=\"-39.573891\"/>\n        <Style>\n          <Name>green</Name>\n          <Title>Green polygon</Title>\n          <Abstract>Green fill with black outline</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:tasmania_state_boundaries\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>topp:tasmania_water_bodies</Name>\n        <Title>Tasmania water bodies</Title>\n        <Abstract>Tasmania water bodies</Abstract>\n        <KeywordList>\n          <Keyword>Lakes</Keyword>\n          <Keyword>Bodies</Keyword>\n          <Keyword>Australia</Keyword>\n          <Keyword>Water</Keyword>\n          <Keyword>Tasmania</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <!--WKT definition of this CRS:\nGEOGCS[\"WGS 84\", \n  DATUM[\"World Geodetic System 1984\", \n    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], \n    AUTHORITY[\"EPSG\",\"6326\"]], \n  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n  UNIT[\"degree\", 0.017453292519943295], \n  AXIS[\"Geodetic longitude\", EAST], \n  AXIS[\"Geodetic latitude\", NORTH], \n  AUTHORITY[\"EPSG\",\"4326\"]]-->\n        <LatLonBoundingBox minx=\"145.95490063999998\" miny=\"-43.04450786\" maxx=\"147.23641436\" maxy=\"-41.762994139999996\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"145.97161899999998\" miny=\"-43.031944\" maxx=\"147.219696\" maxy=\"-41.775558\"/>\n        <Style>\n          <Name>cite_lakes</Name>\n          <Title>Blue lake</Title>\n          <Abstract>A blue fill, solid black outline style</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:tasmania_water_bodies\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>topp:states</Name>\n        <Title>USA Population</Title>\n        <Abstract>This is some census data on the states.</Abstract>\n        <KeywordList>\n          <Keyword>census</Keyword>\n          <Keyword>united</Keyword>\n          <Keyword>boundaries</Keyword>\n          <Keyword>state</Keyword>\n          <Keyword>states</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <!--WKT definition of this CRS:\nGEOGCS[\"WGS 84\", \n  DATUM[\"World Geodetic System 1984\", \n    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], \n    AUTHORITY[\"EPSG\",\"6326\"]], \n  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n  UNIT[\"degree\", 0.017453292519943295], \n  AXIS[\"Geodetic longitude\", EAST], \n  AXIS[\"Geodetic latitude\", NORTH], \n  AUTHORITY[\"EPSG\",\"4326\"]]-->\n        <LatLonBoundingBox minx=\"-125.30903773\" miny=\"7.705448770000002\" maxx=\"-66.39223326999999\" maxy=\"66.62225323\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"-124.73142200000001\" miny=\"24.955967\" maxx=\"-66.969849\" maxy=\"49.371735\"/>\n        <Style>\n          <Name>population</Name>\n          <Title>Population in the United States</Title>\n          <Abstract>A sample filter that filters the United States into three\n        categories of population, drawn in different colors</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:states\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>tike:waterways</Name>\n        <Title>Waterways</Title>\n        <Abstract>Waterways in Finland.</Abstract>\n        <KeywordList>\n          <Keyword>Finland</Keyword>\n          <Keyword>waterways</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <!--WKT definition of this CRS:\nGEOGCS[\"WGS 84\", \n  DATUM[\"World Geodetic System 1984\", \n    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], \n    AUTHORITY[\"EPSG\",\"6326\"]], \n  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n  UNIT[\"degree\", 0.017453292519943295], \n  AXIS[\"Geodetic longitude\", EAST], \n  AXIS[\"Geodetic latitude\", NORTH], \n  AUTHORITY[\"EPSG\",\"4326\"]]-->\n        <LatLonBoundingBox minx=\"19.530168895721403\" miny=\"58.860618000030506\" maxx=\"31.6566005897522\" maxy=\"70.9870496940613\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"19.649055480957\" miny=\"59.9357719421387\" maxx=\"31.5377140045166\" maxy=\"69.9118957519531\"/>\n        <Style>\n          <Name>line</Name>\n          <Title>1 px blue line</Title>\n          <Abstract>Default line style, 1 pixel wide blue</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tike:waterways\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>tike:railways</Name>\n        <Title>roads_Type</Title>\n        <Abstract>Generated from tike</Abstract>\n        <KeywordList>\n          <Keyword>tike</Keyword>\n          <Keyword>roads</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <!--WKT definition of this CRS:\nGEOGCS[\"WGS 84\", \n  DATUM[\"World Geodetic System 1984\", \n    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], \n    AUTHORITY[\"EPSG\",\"6326\"]], \n  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n  UNIT[\"degree\", 0.017453292519943295], \n  AXIS[\"Geodetic longitude\", EAST], \n  AXIS[\"Geodetic latitude\", NORTH], \n  AUTHORITY[\"EPSG\",\"4326\"]]-->\n        <LatLonBoundingBox minx=\"-297176.16529836657\" miny=\"-1.2694600326676274E7\" maxx=\"3.0016785704606913E7\" maxy=\"1.7619361543229006E7\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"19.5393085479736\" miny=\"-2277.78344726562\" maxx=\"2.971959E7\" maxy=\"4927039.0\"/>\n        <Style>\n          <Name>line</Name>\n          <Title>1 px blue line</Title>\n          <Abstract>Default line style, 1 pixel wide blue</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tike:railways\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>tike:roads</Name>\n        <Title>roads_Type</Title>\n        <Abstract>Generated from tike</Abstract>\n        <KeywordList>\n          <Keyword>tike</Keyword>\n          <Keyword>roads</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <!--WKT definition of this CRS:\nGEOGCS[\"WGS 84\", \n  DATUM[\"World Geodetic System 1984\", \n    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], \n    AUTHORITY[\"EPSG\",\"6326\"]], \n  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n  UNIT[\"degree\", 0.017453292519943295], \n  AXIS[\"Geodetic longitude\", EAST], \n  AXIS[\"Geodetic latitude\", NORTH], \n  AUTHORITY[\"EPSG\",\"4326\"]]-->\n        <LatLonBoundingBox minx=\"-297176.16529836657\" miny=\"-1.2694600326676274E7\" maxx=\"3.0016785704606913E7\" maxy=\"1.7619361543229006E7\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"19.5393085479736\" miny=\"-2277.78344726562\" maxx=\"2.971959E7\" maxy=\"4927039.0\"/>\n        <Style>\n          <Name>line</Name>\n          <Title>1 px blue line</Title>\n          <Abstract>Default line style, 1 pixel wide blue</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tike:roads\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>og:roads</Name>\n        <Title>roads_Type</Title>\n        <Abstract>Generated from sf_reset</Abstract>\n        <KeywordList>\n          <Keyword>roads</Keyword>\n          <Keyword>sf_reset</Keyword>\n        </KeywordList>\n        <SRS>EPSG:26713</SRS>\n        <!--WKT definition of this CRS:\nPROJCS[\"NAD27 / UTM zone 13N\", \n  GEOGCS[\"NAD27\", \n    DATUM[\"North American Datum 1927\", \n      SPHEROID[\"Clarke 1866\", 6378206.4, 294.9786982138982, AUTHORITY[\"EPSG\",\"7008\"]], \n      TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], \n      AUTHORITY[\"EPSG\",\"6267\"]], \n    PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n    UNIT[\"degree\", 0.017453292519943295], \n    AXIS[\"Geodetic longitude\", EAST], \n    AXIS[\"Geodetic latitude\", NORTH], \n    AUTHORITY[\"EPSG\",\"4267\"]], \n  PROJECTION[\"Transverse Mercator\", AUTHORITY[\"EPSG\",\"9807\"]], \n  PARAMETER[\"central_meridian\", -105.0], \n  PARAMETER[\"latitude_of_origin\", 0.0], \n  PARAMETER[\"scale_factor\", 0.9996], \n  PARAMETER[\"false_easting\", 500000.0], \n  PARAMETER[\"false_northing\", 0.0], \n  UNIT[\"m\", 1.0], \n  AXIS[\"Easting\", EAST], \n  AXIS[\"Northing\", NORTH], \n  AUTHORITY[\"EPSG\",\"26713\"]]-->\n        <LatLonBoundingBox minx=\"-103.88042792817339\" miny=\"44.308776913708805\" maxx=\"-103.62014761945467\" maxy=\"44.56905722242751\"/>\n        <BoundingBox SRS=\"EPSG:26713\" minx=\"589434.8125\" miny=\"4914006.0\" maxx=\"609527.25\" maxy=\"4928377.0\"/>\n        <Style>\n          <Name>simple_roads</Name>\n          <Title>Default Styler for simple road segments</Title>\n          <Abstract>Light red line, 2px wide</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=og:roads\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>tike:points</Name>\n        <Title>roads_Type</Title>\n        <Abstract>Generated from tike</Abstract>\n        <KeywordList>\n          <Keyword>tike</Keyword>\n          <Keyword>roads</Keyword>\n        </KeywordList>\n        <SRS>EPSG:4326</SRS>\n        <!--WKT definition of this CRS:\nGEOGCS[\"WGS 84\", \n  DATUM[\"World Geodetic System 1984\", \n    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], \n    AUTHORITY[\"EPSG\",\"6326\"]], \n  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n  UNIT[\"degree\", 0.017453292519943295], \n  AXIS[\"Geodetic longitude\", EAST], \n  AXIS[\"Geodetic latitude\", NORTH], \n  AUTHORITY[\"EPSG\",\"4326\"]]-->\n        <LatLonBoundingBox minx=\"19.73377216339108\" miny=\"59.107116584777835\" maxx=\"31.40053188323972\" maxy=\"70.77387630462647\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"19.8481521606445\" miny=\"59.8213005065918\" maxx=\"31.2861518859863\" maxy=\"70.0596923828125\"/>\n        <Style>\n          <Name>line</Name>\n          <Title>1 px blue line</Title>\n          <Abstract>Default line style, 1 pixel wide blue</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=tike:points\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>topp:bluemarble</Name>\n        <Title>Blue Marble Imagery</Title>\n        <Abstract>Blue Marble NG global bathymetry and topography data from NASA.  More information about the Blue Marble NG project is available from http://earthobservatory.nasa.gov/Features/BlueMarble .</Abstract>\n        <KeywordList>\n          <Keyword>WCS</Keyword>\n          <Keyword>bluemarble</Keyword>\n          <Keyword>bluemarble</Keyword>\n        </KeywordList>\n        <!--WKT definition of this CRS:\nGEOGCS[\"WGS 84\", \n  DATUM[\"World Geodetic System 1984\", \n    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], \n    AUTHORITY[\"EPSG\",\"6326\"]], \n  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n  UNIT[\"degree\", 0.017453292519943295], \n  AXIS[\"Geodetic longitude\", EAST], \n  AXIS[\"Geodetic latitude\", NORTH], \n  AUTHORITY[\"EPSG\",\"4326\"]]-->\n        <SRS>EPSG:4326</SRS>\n        <LatLonBoundingBox minx=\"-180.00000003333\" miny=\"-89.99999996486703\" maxx=\"179.99999993067\" maxy=\"90.000000033333\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"-180.00000003333\" miny=\"-89.99999996486703\" maxx=\"179.99999993067\" maxy=\"90.000000033333\"/>\n        <Style>\n          <Name>raster</Name>\n          <Title>Raster</Title>\n          <Abstract>A sample style for rasters, good for displaying imagery</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=topp:bluemarble\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>nurc:Arc_Sample</Name>\n        <Title>Global annual rainfall</Title>\n        <Abstract>Global annual rainfall in ArcGrid format</Abstract>\n        <KeywordList>\n          <Keyword>WCS</Keyword>\n          <Keyword>arcGridSample</Keyword>\n          <Keyword>arcGridSample_Coverage</Keyword>\n        </KeywordList>\n        <!--WKT definition of this CRS:\nGEOGCS[\"WGS 84\", \n  DATUM[\"World Geodetic System 1984\", \n    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], \n    AUTHORITY[\"EPSG\",\"6326\"]], \n  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n  UNIT[\"degree\", 0.017453292519943295], \n  AXIS[\"Geodetic longitude\", EAST], \n  AXIS[\"Geodetic latitude\", NORTH], \n  AUTHORITY[\"EPSG\",\"4326\"]]-->\n        <SRS>EPSG:4326</SRS>\n        <LatLonBoundingBox minx=\"-180.0\" miny=\"-90.0\" maxx=\"180.0\" maxy=\"90.0\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"-180.0\" miny=\"-90.0\" maxx=\"180.0\" maxy=\"90.0\"/>\n        <Style>\n          <Name>raster</Name>\n          <Title>Raster</Title>\n          <Abstract>A sample style for rasters, good for displaying imagery</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=nurc:Arc_Sample\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>nurc:Img_Sample</Name>\n        <Title>North America sample imagery</Title>\n        <Abstract>A very rough imagery of North America</Abstract>\n        <KeywordList>\n          <Keyword>WCS</Keyword>\n          <Keyword>worldImageSample</Keyword>\n          <Keyword>worldImageSample_Coverage</Keyword>\n        </KeywordList>\n        <!--WKT definition of this CRS:\nGEOGCS[\"WGS 84\", \n  DATUM[\"World Geodetic System 1984\", \n    SPHEROID[\"WGS 84\", 6378137.0, 298.257223563, AUTHORITY[\"EPSG\",\"7030\"]], \n    AUTHORITY[\"EPSG\",\"6326\"]], \n  PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n  UNIT[\"degree\", 0.017453292519943295], \n  AXIS[\"Geodetic longitude\", EAST], \n  AXIS[\"Geodetic latitude\", NORTH], \n  AUTHORITY[\"EPSG\",\"4326\"]]-->\n        <SRS>EPSG:4326</SRS>\n        <LatLonBoundingBox minx=\"-130.85168\" miny=\"20.7052\" maxx=\"-62.0054\" maxy=\"54.1141\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"-130.85168\" miny=\"20.7052\" maxx=\"-62.0054\" maxy=\"54.1141\"/>\n        <Style>\n          <Name>raster</Name>\n          <Title>Raster</Title>\n          <Abstract>A sample style for rasters, good for displaying imagery</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=nurc:Img_Sample\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"1\">\n        <Name>sf:sfdem</Name>\n        <Title>Spearfish DEM</Title>\n        <Abstract>Digital Elevation Model data for Spearfish, South Dakota</Abstract>\n        <KeywordList>\n          <Keyword>WCS</Keyword>\n          <Keyword>sf</Keyword>\n          <Keyword>dem</Keyword>\n          <Keyword>digital</Keyword>\n          <Keyword>elevation</Keyword>\n          <Keyword>model</Keyword>\n        </KeywordList>\n        <!--WKT definition of this CRS:\nPROJCS[\"NAD27 / UTM zone 13N\", \n  GEOGCS[\"NAD27\", \n    DATUM[\"North American Datum 1927\", \n      SPHEROID[\"Clarke 1866\", 6378206.4, 294.9786982138982, AUTHORITY[\"EPSG\",\"7008\"]], \n      TOWGS84[-4.2, 135.4, 181.9, 0.0, 0.0, 0.0, 0.0], \n      AUTHORITY[\"EPSG\",\"6267\"]], \n    PRIMEM[\"Greenwich\", 0.0, AUTHORITY[\"EPSG\",\"8901\"]], \n    UNIT[\"degree\", 0.017453292519943295], \n    AXIS[\"Geodetic longitude\", EAST], \n    AXIS[\"Geodetic latitude\", NORTH], \n    AUTHORITY[\"EPSG\",\"4267\"]], \n  PROJECTION[\"Transverse Mercator\", AUTHORITY[\"EPSG\",\"9807\"]], \n  PARAMETER[\"central_meridian\", -105.0], \n  PARAMETER[\"latitude_of_origin\", 0.0], \n  PARAMETER[\"scale_factor\", 0.9996], \n  PARAMETER[\"false_easting\", 500000.0], \n  PARAMETER[\"false_northing\", 0.0], \n  UNIT[\"m\", 1.0], \n  AXIS[\"Easting\", EAST], \n  AXIS[\"Northing\", NORTH], \n  AUTHORITY[\"EPSG\",\"26713\"]]-->\n        <SRS>EPSG:26713</SRS>\n        <LatLonBoundingBox minx=\"-103.87108701853181\" miny=\"44.370187074132616\" maxx=\"-103.62940739432703\" maxy=\"44.5016011535299\"/>\n        <BoundingBox SRS=\"EPSG:26713\" minx=\"589980.0\" miny=\"4913700.0\" maxx=\"609000.0\" maxy=\"4928010.0\"/>\n        <Style>\n          <Name>dem</Name>\n          <Title>Simple DEM style</Title>\n          <Abstract>Classic elevation color progression</Abstract>\n          <LegendURL width=\"20\" height=\"20\">\n            <Format>image/png</Format>\n            <OnlineResource xmlns:xlink=\"http://www.w3.org/1999/xlink\" xlink:type=\"simple\" xlink:href=\"http://demo.boundlessgeo.com/geoserver/wms/GetLegendGraphic?VERSION=1.0.0&amp;FORMAT=image/png&amp;WIDTH=20&amp;HEIGHT=20&amp;LAYER=sf:sfdem\"/>\n          </LegendURL>\n        </Style>\n      </Layer>\n      <Layer queryable=\"0\">\n        <Name>tasmania</Name>\n        <Title>tasmania</Title>\n        <Abstract>Layer-Group type layer: tasmania</Abstract>\n        <SRS>EPSG:4326</SRS>\n        <LatLonBoundingBox minx=\"143.83482400000003\" miny=\"-43.648056\" maxx=\"148.47914100000003\" maxy=\"-39.573891\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"143.83482400000003\" miny=\"-43.648056\" maxx=\"148.47914100000003\" maxy=\"-39.573891\"/>\n      </Layer>\n      <Layer queryable=\"0\">\n        <Name>tiger-ny</Name>\n        <Title>tiger-ny</Title>\n        <Abstract>Layer-Group type layer: tiger-ny</Abstract>\n        <SRS>EPSG:4326</SRS>\n        <LatLonBoundingBox minx=\"-74.047185\" miny=\"40.679648\" maxx=\"-73.907005\" maxy=\"40.882078\"/>\n        <BoundingBox SRS=\"EPSG:4326\" minx=\"-74.047185\" miny=\"40.679648\" maxx=\"-73.907005\" maxy=\"40.882078\"/>\n      </Layer>\n    </Layer>\n  </Capability>\n</WMT_MS_Capabilities>\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tests/throws.js",
    "content": "/*\n\n  throws.js -- Adds a `throws_` method to AnotherWay test objects.\n\n  Copyright 2005 OpenLayers Contributors. released under the BSD License.\n\n\n  A reference to this file needs to be added to `run-tests.html` in the\n  head element after the AnotherWay classes are created:\n\n    <script type=\"text/javascript\" src=\"throws.js\"></script>\n\n  Then, it can be used just like the `ok`, `fail` and other such methods\n  in your unit tests.\n\n  e.g. \n\n   t.throws_(function () {new OpenLayers.View.Map.Dynamic();},\n             ReferenceError(\"No container supplied.\"),\n             \"OpenLayers.View.Map.Dynamic instantiation with no container \"\n             + \"must throw.\");\n\n  This was inspired by the `assertRaises` method of Python's unittest\n  library.\n\n  Possible future enhancements:\n\n    * Contribute to official AnotherWay distribution.\n    * Use `apply` rather than require a inner function (or as an option).\n    * Preserve the stack fields.\n\n */\n\nTest.AnotherWay._test_object_t.prototype.throws_ = \nfunction (fn, expectedException, doc) {\n    /*\n      \n       Executes the supplied function object catching any exception(s)\n       thrown, then verifies the supplied expected exception occurred.\n      \n       If no exception is thrown the test fails.\n\n       If an exception is thrown and it does not match the supplied\n       expected exception the test fails.\n\n       If the exception thrown matches the supplied expected exception\n       the test passes.\n\n       Two exceptions \"match\" if Test.AnotherWay's `eq` method considers\n       the two equal when their respective stacks are ignored.\n\n                      fn - The function object to be executed\n       expectedException - The exception object expected to result\n                     doc - Description of the test\n\n       Note: The name of this method is `throws_` (with a trailing\n             underscore) as `throws` is a reserved identifier and can\n             not be used as a method name.\n\n       Note: This function does not preserve the stack field associated\n             with either exception.\n\n     */\n    var theCaughtException = null;\n\n    try {\n        fn();\n    } catch (innerCaughtException) {\n        // As `innerCaughtException` is not visible outside the scope\n        // of this `catch` block we need to make it visible explicitly. \n        theCaughtException = innerCaughtException;\n    }\n\n    if (theCaughtException) {\n        // We delete the stacks before comparison as they will never match.\n        delete theCaughtException.stack;\n        delete expectedException.stack;\n        this.eq(theCaughtException, expectedException, doc);\n    } else {\n        this.fail(doc);\n    }\n};\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/theme/default/google.css",
    "content": ".olLayerGoogleCopyright {\n    right: 3px;\n    bottom: 2px;\n    left: auto;  \n}\n.olLayerGooglePoweredBy {\n    left: 2px;\n    bottom: 2px;   \n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/theme/default/ie6-style.css",
    "content": ".olControlZoomPanel div {\n    background-image: url(img/zoom-panel-NOALPHA.png);\n}\n.olControlPanPanel div {\n    background-image: url(img/pan-panel-NOALPHA.png);\n}\n.olControlEditingToolbar {\n    width: 200px;\n}\n\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/theme/default/style.css",
    "content": "div.olMap {\n    z-index: 0;\n    padding: 0 !important;\n    margin: 0 !important;\n    cursor: default;\n}\n\ndiv.olMapViewport {\n    text-align: left;\n    -ms-touch-action: none;\n}\n\ndiv.olLayerDiv {\n   -moz-user-select: none;\n   -khtml-user-select: none;\n}\n\n.olLayerGoogleCopyright {\n    left: 2px;\n    bottom: 2px;\n}\n.olLayerGoogleV3.olLayerGoogleCopyright {\n    right: auto !important;\n}\n.olLayerGooglePoweredBy {\n    left: 2px;\n    bottom: 15px;\n}\n.olLayerGoogleV3.olLayerGooglePoweredBy {\n    bottom: 15px !important;\n}\n/* GMaps should not set styles on its container */\n.olForeignContainer {\n    opacity: 1 !important;\n}\n.olControlAttribution {\n    font-size: smaller;\n    right: 3px;\n    bottom: 4.5em;\n    position: absolute;\n    display: block;\n}\n.olControlScale {\n    right: 3px;\n    bottom: 3em;\n    display: block;\n    position: absolute;\n    font-size: smaller;\n}\n.olControlScaleLine {\n   display: block;\n   position: absolute;\n   left: 10px;\n   bottom: 15px;\n   font-size: xx-small;\n}\n.olControlScaleLineBottom {\n   border: solid 2px black;\n   border-bottom: none;\n   margin-top:-2px;\n   text-align: center;\n}\n.olControlScaleLineTop {\n   border: solid 2px black;\n   border-top: none;\n   text-align: center;\n}\n\n.olControlPermalink {\n    right: 3px;\n    bottom: 1.5em;\n    display: block;\n    position: absolute;\n    font-size: smaller;\n}\n\ndiv.olControlMousePosition {\n    bottom: 0;\n    right: 3px;\n    display: block;\n    position: absolute;\n    font-family: Arial;\n    font-size: smaller;\n}\n\n.olControlOverviewMapContainer {\n    position: absolute;\n    bottom: 0;\n    right: 0;\n}\n\n.olControlOverviewMapElement {\n    padding: 10px 18px 10px 10px;\n    background-color: #00008B;\n    -moz-border-radius: 1em 0 0 0;\n}\n\n.olControlOverviewMapMinimizeButton,\n.olControlOverviewMapMaximizeButton {\n    height: 18px;\n    width: 18px;\n    right: 0;\n    bottom: 80px;\n    cursor: pointer;\n}\n\n.olControlOverviewMapExtentRectangle {\n    overflow: hidden;\n    background-image: url(\"img/blank.gif\");\n    cursor: move;\n    border: 2px dotted red;\n}\n.olControlOverviewMapRectReplacement {\n    overflow: hidden;\n    cursor: move;\n    background-image: url(\"img/overview_replacement.gif\");\n    background-repeat: no-repeat;\n    background-position: center;\n}\n\n.olLayerGeoRSSDescription {\n    float:left;\n    width:100%;\n    overflow:auto;\n    font-size:1.0em;\n}\n.olLayerGeoRSSClose {\n    float:right;\n    color:gray;\n    font-size:1.2em;\n    margin-right:6px;\n    font-family:sans-serif;\n}\n.olLayerGeoRSSTitle {\n    float:left;font-size:1.2em;\n}\n\n.olPopupContent {\n    padding:5px;\n    overflow: auto;\n}\n\n.olControlNavigationHistory {\n   background-image: url(\"img/navigation_history.png\");\n   background-repeat: no-repeat;\n   width:  24px;\n   height: 24px;\n\n}\n.olControlNavigationHistoryPreviousItemActive {\n  background-position: 0 0;\n}\n.olControlNavigationHistoryPreviousItemInactive {\n   background-position: 0 -24px;\n}\n.olControlNavigationHistoryNextItemActive {\n   background-position: -24px 0;\n}\n.olControlNavigationHistoryNextItemInactive {\n   background-position: -24px -24px;\n}\n\ndiv.olControlSaveFeaturesItemActive {\n    background-image: url(img/save_features_on.png);\n    background-repeat: no-repeat;\n    background-position: 0 1px;\n}\ndiv.olControlSaveFeaturesItemInactive {\n    background-image: url(img/save_features_off.png);\n    background-repeat: no-repeat;\n    background-position: 0 1px;\n}\n\n.olHandlerBoxZoomBox {\n    border: 2px solid red;\n    position: absolute;\n    background-color: white;\n    opacity: 0.50;\n    font-size: 1px;\n    filter: alpha(opacity=50);\n}\n.olHandlerBoxSelectFeature {\n    border: 2px solid blue;\n    position: absolute;\n    background-color: white;\n    opacity: 0.50;\n    font-size: 1px;\n    filter: alpha(opacity=50);\n}\n\n.olControlPanPanel {\n    top: 10px;\n    left: 5px;\n}\n\n.olControlPanPanel div {\n    background-image: url(img/pan-panel.png);\n    height: 18px;\n    width: 18px;\n    cursor: pointer;\n    position: absolute;\n}\n\n.olControlPanPanel .olControlPanNorthItemInactive {\n    top: 0;\n    left: 9px;\n    background-position: 0 0;\n}\n.olControlPanPanel .olControlPanSouthItemInactive {\n    top: 36px;\n    left: 9px;\n    background-position: 18px 0;\n}\n.olControlPanPanel .olControlPanWestItemInactive {\n    position: absolute;\n    top: 18px;\n    left: 0;\n    background-position: 0 18px;\n}\n.olControlPanPanel .olControlPanEastItemInactive {\n    top: 18px;\n    left: 18px;\n    background-position: 18px 18px;\n}\n\n.olControlZoomPanel {\n    top: 71px;\n    left: 14px;\n}\n\n.olControlZoomPanel div {\n    background-image: url(img/zoom-panel.png);\n    position: absolute;\n    height: 18px;\n    width: 18px;\n    cursor: pointer;\n}\n\n.olControlZoomPanel .olControlZoomInItemInactive {\n    top: 0;\n    left: 0;\n    background-position: 0 0;\n}\n\n.olControlZoomPanel .olControlZoomToMaxExtentItemInactive {\n    top: 18px;\n    left: 0;\n    background-position: 0 -18px;\n}\n\n.olControlZoomPanel .olControlZoomOutItemInactive {\n    top: 36px;\n    left: 0;\n    background-position: 0 18px;\n}\n\n/*\n * When a potential text is bigger than the image it move the image\n * with some headers (closes #3154)\n */\n.olControlPanZoomBar div {\n    font-size: 1px;\n}\n\n.olPopupCloseBox {\n  background: url(\"img/close.gif\") no-repeat;\n  cursor: pointer;\n}\n\n.olFramedCloudPopupContent {\n    padding: 5px;\n    overflow: auto;\n}\n\n.olControlNoSelect {\n -moz-user-select: none;\n -khtml-user-select: none;\n}\n\n.olImageLoadError {\n    background-color: pink;\n    opacity: 0.5;\n    filter: alpha(opacity=50); /* IE */\n}\n\n/**\n * Cursor styles\n */\n\n.olCursorWait {\n    cursor: wait;\n}\n.olDragDown {\n    cursor: move;\n}\n.olDrawBox {\n    cursor: crosshair;\n}\n.olControlDragFeatureOver {\n    cursor: move;\n}\n.olControlDragFeatureActive.olControlDragFeatureOver.olDragDown {\n    cursor: -moz-grabbing;\n}\n\n/**\n * Layer switcher\n */\n.olControlLayerSwitcher {\n    position: absolute;\n    top: 25px;\n    right: 0;\n    width: 20em;\n    font-family: sans-serif;\n    font-weight: bold;\n    margin-top: 3px;\n    margin-left: 3px;\n    margin-bottom: 3px;\n    font-size: smaller;\n    color: white;\n    background-color: transparent;\n}\n\n.olControlLayerSwitcher .layersDiv {\n    padding-top: 5px;\n    padding-left: 10px;\n    padding-bottom: 5px;\n    padding-right: 10px;\n    background-color: darkblue;\n}\n\n.olControlLayerSwitcher .layersDiv .baseLbl,\n.olControlLayerSwitcher .layersDiv .dataLbl {\n    margin-top: 3px;\n    margin-left: 3px;\n    margin-bottom: 3px;\n}\n\n.olControlLayerSwitcher .layersDiv .baseLayersDiv,\n.olControlLayerSwitcher .layersDiv .dataLayersDiv {\n    padding-left: 10px;\n}\n\n.olControlLayerSwitcher .maximizeDiv,\n.olControlLayerSwitcher .minimizeDiv {\n    width: 18px;\n    height: 18px;\n    top: 5px;\n    right: 0;\n    cursor: pointer;\n}\n\n.olBingAttribution {\n    color: #DDD;\n}\n.olBingAttribution.road {\n    color: #333;\n}\n\n.olGoogleAttribution.hybrid, .olGoogleAttribution.satellite {\n    color: #EEE;\n}\n.olGoogleAttribution {\n    color: #333;\n}\nspan.olGoogleAttribution a {\n    color: #77C;\n}\nspan.olGoogleAttribution.hybrid a, span.olGoogleAttribution.satellite a {\n    color: #EEE;\n}\n\n/**\n * Editing and navigation icons.\n * (using the editing_tool_bar.png sprint image)\n */\n.olControlNavToolbar ,\n.olControlEditingToolbar {\n    margin: 5px 5px 0 0;\n}\n.olControlNavToolbar div,\n.olControlEditingToolbar div {\n    background-image: url(\"img/editing_tool_bar.png\");\n    background-repeat: no-repeat;\n    margin: 0 0 5px 5px;\n    width: 24px;\n    height: 22px;\n    cursor: pointer\n}\n/* positions */\n.olControlEditingToolbar {\n    right: 0;\n    top: 0;\n}\n.olControlNavToolbar {\n    top: 295px;\n    left: 9px;\n}\n/* layouts */\n.olControlEditingToolbar div {\n    float: right;\n}\n/* individual controls */\n.olControlNavToolbar .olControlNavigationItemInactive,\n.olControlEditingToolbar .olControlNavigationItemInactive {\n    background-position: -103px -1px;\n}\n.olControlNavToolbar .olControlNavigationItemActive ,\n.olControlEditingToolbar .olControlNavigationItemActive  {\n    background-position: -103px -24px;\n}\n.olControlNavToolbar .olControlZoomBoxItemInactive,\n.olControlEditingToolbar .olControlZoomBoxItemInactive  {\n    background-position: -128px -1px;\n}\n.olControlNavToolbar .olControlZoomBoxItemActive,  \n.olControlEditingToolbar .olControlZoomBoxItemActive  {\n    background-position: -128px -24px;\n}\n.olControlEditingToolbar .olControlDrawFeaturePointItemInactive {\n    background-position: -77px -1px;\n}\n.olControlEditingToolbar .olControlDrawFeaturePointItemActive {\n    background-position: -77px -24px;\n}\n.olControlEditingToolbar .olControlDrawFeaturePathItemInactive {\n    background-position: -51px -1px;\n}\n.olControlEditingToolbar .olControlDrawFeaturePathItemActive {\n    background-position: -51px -24px;\n}\n.olControlEditingToolbar .olControlDrawFeaturePolygonItemInactive{\n    background-position: -26px -1px;\n}\n.olControlEditingToolbar .olControlDrawFeaturePolygonItemActive {\n    background-position: -26px -24px;\n}\n\ndiv.olControlZoom, div.olControlTextButtonPanel {\n    position: absolute;\n    top: 8px;\n    left: 8px;\n    background: rgba(255,255,255,0.4);\n    border-radius: 4px;\n    padding: 2px;\n}\ndiv.olControlZoom a {\n    font-size: 18px;\n    line-height: 19px;\n    height: 22px;\n    width:22px;\n    padding: 0;\n}\ndiv.olControlZoom a, div.olControlTextButtonPanel .olButton {\n    display: block;\n    margin: 1px;\n    color: white;\n    font-family: 'Lucida Grande', Verdana, Geneva, Lucida, Arial, Helvetica, sans-serif;\n    font-weight: bold;\n    text-decoration: none;\n    text-align: center;\n    background: #130085; /* fallback for IE - IE6 requires background shorthand*/\n    background: rgba(0, 60, 136, 0.5);\n    filter: alpha(opacity=80);\n}\ndiv.olControlZoom a:hover, div.olControlTextButtonPanel .olButton:hover {\n    background: #130085; /* fallback for IE */\n    background: rgba(0, 60, 136, 0.7);\n    filter: alpha(opacity=100);\n}\n@media only screen and (max-width: 600px) {\n    div.olControlZoom a:hover, div.olControlTextButtonPanel .olButton:hover {\n        background: rgba(0, 60, 136, 0.5);\n    }\n}\na.olControlZoomIn {\n    border-radius: 4px 4px 0 0;\n}\na.olControlZoomOut {\n    border-radius: 0 0 4px 4px;\n}\n\n/**\n * TextButtonPanel\n */\n\ndiv.olControlTextButtonPanel .olButton {\n    float: left;\n    padding: 4px;\n}\n\ndiv.olControlTextButtonPanel.vertical .olButton {\n    float: none;\n}\ndiv.olControlTextButtonPanel .olButton:first-child {\n    border-radius: 4px 0 0 4px;\n}\ndiv.olControlTextButtonPanel .olButton:last-child {\n    border-radius: 0 4px 4px 0;\n}\ndiv.olControlTextButtonPanel.vertical .olButton:first-child {\n    border-radius: 4px 4px 0 0\n}\ndiv.olControlTextButtonPanel.vertical .olButton:last-child {\n    border-radius: 0 0 4px 4px;\n}\n\n\n/**\n * Animations\n */\n\n.olLayerGrid .olTileImage {\n    -webkit-transition: opacity 0.2s linear;\n    -moz-transition: opacity 0.2s linear;\n    -o-transition: opacity 0.2s linear;\n    transition: opacity 0.2s linear;\n}\n\n/* Turn on GPU support where available */\n.olTileImage {\n    -webkit-transform: translateZ(0);\n    -moz-transform: translateZ(0);\n    -o-transform: translateZ(0);\n    -ms-transform: translateZ(0);\n    transform: translateZ(0);\n    -webkit-backface-visibility: hidden;\n    -moz-backface-visibility: hidden;\n    -ms-backface-visibility: hidden;\n    backface-visibility: hidden;\n    -webkit-perspective: 1000;\n    -moz-perspective: 1000;\n    -ms-perspective: 1000;\n    perspective: 1000;\n}\n\n/* when replacing tiles, do not show tile and backbuffer at the same time */\n.olTileReplacing {\n    display: none;\n}\n\n/* override any max-width image settings (e.g. bootstrap.css) */\nimg.olTileImage {\n    max-width: none;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/theme/default/style.mobile.css",
    "content": "div.olControlZoom {\n    position: absolute;\n    top: 8px;\n    left: 8px;\n    background: rgba(255,255,255,0.4);\n    border-radius: 4px;\n    padding: 2px;\n}\n* {\n    -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\ndiv.olControlZoom a {\n    display: block;\n    margin: 1px;\n    padding: 0;\n    color: white;\n    font-size: 28px;\n    font-family: sans-serif;\n    font-weight: bold;\n    text-decoration: none;\n    text-align: center;\n    height: 32px;\n    width: 32px;\n    line-height: 28px;\n    text-shadow: 0 0 3px rgba(0,0,0,0.8);\n    background: #130085; /* fallback for IE - IE6 requires background shorthand*/\n    background: rgba(0, 60, 136, 0.5);\n    filter: alpha(opacity=80);\n}\na.olControlZoomIn {\n    border-radius: 4px 4px 0 0;\n}\na.olControlZoomOut {\n    border-radius: 0 0 4px 4px;\n}\ndiv.olControlZoom a:hover {\n    background: #130085; /* fallback for IE */\n    background: rgba(0, 60, 136, 0.7);\n    filter: alpha(opacity=100);\n}\n@media only screen and (max-width: 600px) {\n    div.olControlZoom a:hover {\n        background: rgba(0, 60, 136, 0.5);\n    }\n}\ndiv.olMapViewport {\n    -ms-touch-action: none;\n}\n.olLayerGrid .olTileImage {\n    -webkit-transition: opacity 0.2s linear;\n    -moz-transition: opacity 0.2s linear;\n    -o-transition: opacity 0.2s linear;\n    transition: opacity 0.2s linear;\n}\n/* Turn on GPU support where available */\n.olTileImage {\n    -webkit-transform: translateZ(0);\n    -moz-transform: translateZ(0);\n    -o-transform: translateZ(0);\n    -ms-transform: translateZ(0);\n    transform: translateZ(0);\n    -webkit-backface-visibility: hidden;\n    -moz-backface-visibility: hidden;\n    -ms-backface-visibility: hidden;\n    backface-visibility: hidden;\n    -webkit-perspective: 1000;\n    -moz-perspective: 1000;\n    -ms-perspective: 1000;\n    perspective: 1000;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tools/BeautifulSoup.py",
    "content": "\"\"\"Beautiful Soup\nElixir and Tonic\n\"The Screen-Scraper's Friend\"\nhttp://www.crummy.com/software/BeautifulSoup/\n\nBeautiful Soup parses a (possibly invalid) XML or HTML document into a\ntree representation. It provides methods and Pythonic idioms that make\nit easy to navigate, search, and modify the tree.\n\nA well-formed XML/HTML document yields a well-formed data\nstructure. An ill-formed XML/HTML document yields a correspondingly\nill-formed data structure. If your document is only locally\nwell-formed, you can use this library to find and process the\nwell-formed part of it. The BeautifulSoup class \n\nBeautiful Soup works with Python 2.2 and up. It has no external\ndependencies, but you'll have more success at converting data to UTF-8\nif you also install these three packages:\n\n* chardet, for auto-detecting character encodings\n  http://chardet.feedparser.org/\n* cjkcodecs and iconv_codec, which add more encodings to the ones supported\n  by stock Python.\n  http://cjkpython.i18n.org/\n\nBeautiful Soup defines classes for two main parsing strategies:\n    \n * BeautifulStoneSoup, for parsing XML, SGML, or your domain-specific\n   language that kind of looks like XML.\n\n * BeautifulSoup, for parsing run-of-the-mill HTML code, be it valid\n   or invalid. This class has web browser-like heuristics for\n   obtaining a sensible parse tree in the face of common HTML errors.\n\nBeautiful Soup also defines a class (UnicodeDammit) for autodetecting\nthe encoding of an HTML or XML document, and converting it to\nUnicode. Much of this code is taken from Mark Pilgrim's Universal Feed Parser.\n\nFor more than you ever wanted to know about Beautiful Soup, see the\ndocumentation:\nhttp://www.crummy.com/software/BeautifulSoup/documentation.html\n\n\"\"\"\nfrom __future__ import generators\n\n__author__ = \"Leonard Richardson (leonardr@segfault.org)\"\n__version__ = \"3.0.4\"\n__copyright__ = \"Copyright (c) 2004-2007 Leonard Richardson\"\n__license__ = \"PSF\"\n\nfrom sgmllib import SGMLParser, SGMLParseError\nimport codecs\nimport types\nimport re\nimport sgmllib\ntry:\n  from htmlentitydefs import name2codepoint\nexcept ImportError:\n  name2codepoint = {}\n\n#This hack makes Beautiful Soup able to parse XML with namespaces\nsgmllib.tagfind = re.compile('[a-zA-Z][-_.:a-zA-Z0-9]*')\n\nDEFAULT_OUTPUT_ENCODING = \"utf-8\"\n\n# First, the classes that represent markup elements.\n\nclass PageElement:\n    \"\"\"Contains the navigational information for some part of the page\n    (either a tag or a piece of text)\"\"\"\n\n    def setup(self, parent=None, previous=None):\n        \"\"\"Sets up the initial relations between this element and\n        other elements.\"\"\"        \n        self.parent = parent\n        self.previous = previous\n        self.next = None\n        self.previousSibling = None\n        self.nextSibling = None\n        if self.parent and self.parent.contents:\n            self.previousSibling = self.parent.contents[-1]\n            self.previousSibling.nextSibling = self\n\n    def replaceWith(self, replaceWith):        \n        oldParent = self.parent\n        myIndex = self.parent.contents.index(self)\n        if hasattr(replaceWith, 'parent') and replaceWith.parent == self.parent:\n            # We're replacing this element with one of its siblings.\n            index = self.parent.contents.index(replaceWith)\n            if index and index < myIndex:\n                # Furthermore, it comes before this element. That\n                # means that when we extract it, the index of this\n                # element will change.\n                myIndex = myIndex - 1\n        self.extract()        \n        oldParent.insert(myIndex, replaceWith)\n        \n    def extract(self):\n        \"\"\"Destructively rips this element out of the tree.\"\"\"        \n        if self.parent:\n            try:\n                self.parent.contents.remove(self)\n            except ValueError:\n                pass\n\n        #Find the two elements that would be next to each other if\n        #this element (and any children) hadn't been parsed. Connect\n        #the two.        \n        lastChild = self._lastRecursiveChild()\n        nextElement = lastChild.next\n\n        if self.previous:\n            self.previous.next = nextElement\n        if nextElement:\n            nextElement.previous = self.previous\n        self.previous = None\n        lastChild.next = None\n\n        self.parent = None        \n        if self.previousSibling:\n            self.previousSibling.nextSibling = self.nextSibling\n        if self.nextSibling:\n            self.nextSibling.previousSibling = self.previousSibling\n        self.previousSibling = self.nextSibling = None       \n\n    def _lastRecursiveChild(self):\n        \"Finds the last element beneath this object to be parsed.\"\n        lastChild = self\n        while hasattr(lastChild, 'contents') and lastChild.contents:\n            lastChild = lastChild.contents[-1]\n        return lastChild\n\n    def insert(self, position, newChild):\n        if (isinstance(newChild, basestring)\n            or isinstance(newChild, unicode)) \\\n            and not isinstance(newChild, NavigableString):\n            newChild = NavigableString(newChild)        \n\n        position =  min(position, len(self.contents))\n        if hasattr(newChild, 'parent') and newChild.parent != None:\n            # We're 'inserting' an element that's already one\n            # of this object's children. \n            if newChild.parent == self:\n                index = self.find(newChild)\n                if index and index < position:\n                    # Furthermore we're moving it further down the\n                    # list of this object's children. That means that\n                    # when we extract this element, our target index\n                    # will jump down one.\n                    position = position - 1\n            newChild.extract()\n            \n        newChild.parent = self\n        previousChild = None\n        if position == 0:\n            newChild.previousSibling = None\n            newChild.previous = self\n        else:\n            previousChild = self.contents[position-1]\n            newChild.previousSibling = previousChild\n            newChild.previousSibling.nextSibling = newChild\n            newChild.previous = previousChild._lastRecursiveChild()\n        if newChild.previous:\n            newChild.previous.next = newChild        \n\n        newChildsLastElement = newChild._lastRecursiveChild()\n\n        if position >= len(self.contents):\n            newChild.nextSibling = None\n            \n            parent = self\n            parentsNextSibling = None\n            while not parentsNextSibling:\n                parentsNextSibling = parent.nextSibling\n                parent = parent.parent\n                if not parent: # This is the last element in the document.\n                    break\n            if parentsNextSibling:\n                newChildsLastElement.next = parentsNextSibling\n            else:\n                newChildsLastElement.next = None\n        else:\n            nextChild = self.contents[position]            \n            newChild.nextSibling = nextChild            \n            if newChild.nextSibling:\n                newChild.nextSibling.previousSibling = newChild\n            newChildsLastElement.next = nextChild\n\n        if newChildsLastElement.next:\n            newChildsLastElement.next.previous = newChildsLastElement\n        self.contents.insert(position, newChild)\n\n    def findNext(self, name=None, attrs={}, text=None, **kwargs):\n        \"\"\"Returns the first item that matches the given criteria and\n        appears after this Tag in the document.\"\"\"\n        return self._findOne(self.findAllNext, name, attrs, text, **kwargs)\n\n    def findAllNext(self, name=None, attrs={}, text=None, limit=None,\n                    **kwargs):\n        \"\"\"Returns all items that match the given criteria and appear\n        before after Tag in the document.\"\"\"\n        return self._findAll(name, attrs, text, limit, self.nextGenerator)\n\n    def findNextSibling(self, name=None, attrs={}, text=None, **kwargs):\n        \"\"\"Returns the closest sibling to this Tag that matches the\n        given criteria and appears after this Tag in the document.\"\"\"\n        return self._findOne(self.findNextSiblings, name, attrs, text,\n                             **kwargs)\n\n    def findNextSiblings(self, name=None, attrs={}, text=None, limit=None,\n                         **kwargs):\n        \"\"\"Returns the siblings of this Tag that match the given\n        criteria and appear after this Tag in the document.\"\"\"\n        return self._findAll(name, attrs, text, limit,\n                             self.nextSiblingGenerator, **kwargs)\n    fetchNextSiblings = findNextSiblings # Compatibility with pre-3.x\n\n    def findPrevious(self, name=None, attrs={}, text=None, **kwargs):\n        \"\"\"Returns the first item that matches the given criteria and\n        appears before this Tag in the document.\"\"\"\n        return self._findOne(self.findAllPrevious, name, attrs, text, **kwargs)\n\n    def findAllPrevious(self, name=None, attrs={}, text=None, limit=None,\n                        **kwargs):\n        \"\"\"Returns all items that match the given criteria and appear\n        before this Tag in the document.\"\"\"\n        return self._findAll(name, attrs, text, limit, self.previousGenerator,\n                           **kwargs)\n    fetchPrevious = findAllPrevious # Compatibility with pre-3.x\n\n    def findPreviousSibling(self, name=None, attrs={}, text=None, **kwargs):\n        \"\"\"Returns the closest sibling to this Tag that matches the\n        given criteria and appears before this Tag in the document.\"\"\"\n        return self._findOne(self.findPreviousSiblings, name, attrs, text,\n                             **kwargs)\n\n    def findPreviousSiblings(self, name=None, attrs={}, text=None,\n                             limit=None, **kwargs):\n        \"\"\"Returns the siblings of this Tag that match the given\n        criteria and appear before this Tag in the document.\"\"\"\n        return self._findAll(name, attrs, text, limit,\n                             self.previousSiblingGenerator, **kwargs)\n    fetchPreviousSiblings = findPreviousSiblings # Compatibility with pre-3.x\n\n    def findParent(self, name=None, attrs={}, **kwargs):\n        \"\"\"Returns the closest parent of this Tag that matches the given\n        criteria.\"\"\"\n        # NOTE: We can't use _findOne because findParents takes a different\n        # set of arguments.\n        r = None\n        l = self.findParents(name, attrs, 1)\n        if l:\n            r = l[0]\n        return r\n\n    def findParents(self, name=None, attrs={}, limit=None, **kwargs):\n        \"\"\"Returns the parents of this Tag that match the given\n        criteria.\"\"\"\n\n        return self._findAll(name, attrs, None, limit, self.parentGenerator,\n                             **kwargs)\n    fetchParents = findParents # Compatibility with pre-3.x\n\n    #These methods do the real heavy lifting.\n\n    def _findOne(self, method, name, attrs, text, **kwargs):\n        r = None\n        l = method(name, attrs, text, 1, **kwargs)\n        if l:\n            r = l[0]\n        return r\n    \n    def _findAll(self, name, attrs, text, limit, generator, **kwargs):\n        \"Iterates over a generator looking for things that match.\"\n\n        if isinstance(name, SoupStrainer):\n            strainer = name\n        else:\n            # Build a SoupStrainer\n            strainer = SoupStrainer(name, attrs, text, **kwargs)\n        results = ResultSet(strainer)\n        g = generator()\n        while True:\n            try:\n                i = g.next()\n            except StopIteration:\n                break\n            if i:\n                found = strainer.search(i)\n                if found:\n                    results.append(found)\n                    if limit and len(results) >= limit:\n                        break\n        return results\n\n    #These Generators can be used to navigate starting from both\n    #NavigableStrings and Tags.                \n    def nextGenerator(self):\n        i = self\n        while i:\n            i = i.next\n            yield i\n\n    def nextSiblingGenerator(self):\n        i = self\n        while i:\n            i = i.nextSibling\n            yield i\n\n    def previousGenerator(self):\n        i = self\n        while i:\n            i = i.previous\n            yield i\n\n    def previousSiblingGenerator(self):\n        i = self\n        while i:\n            i = i.previousSibling\n            yield i\n\n    def parentGenerator(self):\n        i = self\n        while i:\n            i = i.parent\n            yield i\n\n    # Utility methods\n    def substituteEncoding(self, str, encoding=None):\n        encoding = encoding or \"utf-8\"\n        return str.replace(\"%SOUP-ENCODING%\", encoding)    \n\n    def toEncoding(self, s, encoding=None):\n        \"\"\"Encodes an object to a string in some encoding, or to Unicode.\n        .\"\"\"\n        if isinstance(s, unicode):\n            if encoding:\n                s = s.encode(encoding)\n        elif isinstance(s, str):\n            if encoding:\n                s = s.encode(encoding)\n            else:\n                s = unicode(s)\n        else:\n            if encoding:\n                s  = self.toEncoding(str(s), encoding)\n            else:\n                s = unicode(s)\n        return s\n\nclass NavigableString(unicode, PageElement):\n\n    def __getattr__(self, attr):\n        \"\"\"text.string gives you text. This is for backwards\n        compatibility for Navigable*String, but for CData* it lets you\n        get the string without the CData wrapper.\"\"\"\n        if attr == 'string':\n            return self\n        else:\n            raise AttributeError, \"'%s' object has no attribute '%s'\" % (self.__class__.__name__, attr)\n\n    def __unicode__(self):\n        return self.__str__(None)\n\n    def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING):\n        if encoding:\n            return self.encode(encoding)\n        else:\n            return self\n        \nclass CData(NavigableString):\n\n    def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING):\n        return \"<![CDATA[%s]]>\" % NavigableString.__str__(self, encoding)\n\nclass ProcessingInstruction(NavigableString):\n    def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING):\n        output = self\n        if \"%SOUP-ENCODING%\" in output:\n            output = self.substituteEncoding(output, encoding)\n        return \"<?%s?>\" % self.toEncoding(output, encoding)\n\nclass Comment(NavigableString):\n    def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING):\n        return \"<!--%s-->\" % NavigableString.__str__(self, encoding)    \n\nclass Declaration(NavigableString):\n    def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING):\n        return \"<!%s>\" % NavigableString.__str__(self, encoding)        \n\nclass Tag(PageElement):\n\n    \"\"\"Represents a found HTML tag with its attributes and contents.\"\"\"\n\n    XML_SPECIAL_CHARS_TO_ENTITIES = { \"'\" : \"squot\",\n                                      '\"' : \"quote\",\n                                      \"&\" : \"amp\",\n                                      \"<\" : \"lt\",\n                                      \">\" : \"gt\" }\n\n    def __init__(self, parser, name, attrs=None, parent=None,\n                 previous=None):\n        \"Basic constructor.\"\n\n        # We don't actually store the parser object: that lets extracted\n        # chunks be garbage-collected\n        self.parserClass = parser.__class__\n        self.isSelfClosing = parser.isSelfClosingTag(name)\n        self.name = name\n        if attrs == None:\n            attrs = []\n        self.attrs = attrs\n        self.contents = []\n        self.setup(parent, previous)\n        self.hidden = False\n        self.containsSubstitutions = False\n\n    def get(self, key, default=None):\n        \"\"\"Returns the value of the 'key' attribute for the tag, or\n        the value given for 'default' if it doesn't have that\n        attribute.\"\"\"\n        return self._getAttrMap().get(key, default)    \n\n    def has_key(self, key):\n        return self._getAttrMap().has_key(key)\n\n    def __getitem__(self, key):\n        \"\"\"tag[key] returns the value of the 'key' attribute for the tag,\n        and throws an exception if it's not there.\"\"\"\n        return self._getAttrMap()[key]\n\n    def __iter__(self):\n        \"Iterating over a tag iterates over its contents.\"\n        return iter(self.contents)\n\n    def __len__(self):\n        \"The length of a tag is the length of its list of contents.\"\n        return len(self.contents)\n\n    def __contains__(self, x):\n        return x in self.contents\n\n    def __nonzero__(self):\n        \"A tag is non-None even if it has no contents.\"\n        return True\n\n    def __setitem__(self, key, value):        \n        \"\"\"Setting tag[key] sets the value of the 'key' attribute for the\n        tag.\"\"\"\n        self._getAttrMap()\n        self.attrMap[key] = value\n        found = False\n        for i in range(0, len(self.attrs)):\n            if self.attrs[i][0] == key:\n                self.attrs[i] = (key, value)\n                found = True\n        if not found:\n            self.attrs.append((key, value))\n        self._getAttrMap()[key] = value\n\n    def __delitem__(self, key):\n        \"Deleting tag[key] deletes all 'key' attributes for the tag.\"\n        for item in self.attrs:\n            if item[0] == key:\n                self.attrs.remove(item)\n                #We don't break because bad HTML can define the same\n                #attribute multiple times.\n            self._getAttrMap()\n            if self.attrMap.has_key(key):\n                del self.attrMap[key]\n\n    def __call__(self, *args, **kwargs):\n        \"\"\"Calling a tag like a function is the same as calling its\n        findAll() method. Eg. tag('a') returns a list of all the A tags\n        found within this tag.\"\"\"\n        return apply(self.findAll, args, kwargs)\n\n    def __getattr__(self, tag):\n        #print \"Getattr %s.%s\" % (self.__class__, tag)\n        if len(tag) > 3 and tag.rfind('Tag') == len(tag)-3:\n            return self.find(tag[:-3])\n        elif tag.find('__') != 0:\n            return self.find(tag)\n\n    def __eq__(self, other):\n        \"\"\"Returns true iff this tag has the same name, the same attributes,\n        and the same contents (recursively) as the given tag.\n\n        NOTE: right now this will return false if two tags have the\n        same attributes in a different order. Should this be fixed?\"\"\"\n        if not hasattr(other, 'name') or not hasattr(other, 'attrs') or not hasattr(other, 'contents') or self.name != other.name or self.attrs != other.attrs or len(self) != len(other):\n            return False\n        for i in range(0, len(self.contents)):\n            if self.contents[i] != other.contents[i]:\n                return False\n        return True\n\n    def __ne__(self, other):\n        \"\"\"Returns true iff this tag is not identical to the other tag,\n        as defined in __eq__.\"\"\"\n        return not self == other\n\n    def __repr__(self, encoding=DEFAULT_OUTPUT_ENCODING):\n        \"\"\"Renders this tag as a string.\"\"\"\n        return self.__str__(encoding)\n\n    def __unicode__(self):\n        return self.__str__(None)\n\n    def __str__(self, encoding=DEFAULT_OUTPUT_ENCODING,\n                prettyPrint=False, indentLevel=0):\n        \"\"\"Returns a string or Unicode representation of this tag and\n        its contents. To get Unicode, pass None for encoding.\n\n        NOTE: since Python's HTML parser consumes whitespace, this\n        method is not certain to reproduce the whitespace present in\n        the original string.\"\"\"\n\n        encodedName = self.toEncoding(self.name, encoding)\n\n        attrs = []\n        if self.attrs:\n            for key, val in self.attrs:\n                fmt = '%s=\"%s\"'\n                if isString(val):                    \n                    if self.containsSubstitutions and '%SOUP-ENCODING%' in val:\n                        val = self.substituteEncoding(val, encoding)\n\n                    # The attribute value either:\n                    #\n                    # * Contains no embedded double quotes or single quotes.\n                    #   No problem: we enclose it in double quotes.\n                    # * Contains embedded single quotes. No problem:\n                    #   double quotes work here too.\n                    # * Contains embedded double quotes. No problem:\n                    #   we enclose it in single quotes.\n                    # * Embeds both single _and_ double quotes. This\n                    #   can't happen naturally, but it can happen if\n                    #   you modify an attribute value after parsing\n                    #   the document. Now we have a bit of a\n                    #   problem. We solve it by enclosing the\n                    #   attribute in single quotes, and escaping any\n                    #   embedded single quotes to XML entities.\n                    if '\"' in val:\n                        fmt = \"%s='%s'\"\n                        # This can't happen naturally, but it can happen\n                        # if you modify an attribute value after parsing.\n                        if \"'\" in val:\n                            val = val.replace(\"'\", \"&squot;\")\n\n                    # Now we're okay w/r/t quotes. But the attribute\n                    # value might also contain angle brackets, or\n                    # ampersands that aren't part of entities. We need\n                    # to escape those to XML entities too.\n                    val = re.sub(\"([<>]|&(?![^\\s]+;))\",\n                                 lambda x: \"&\" + self.XML_SPECIAL_CHARS_TO_ENTITIES[x.group(0)[0]] + \";\",\n                                 val)\n                                      \n                attrs.append(fmt % (self.toEncoding(key, encoding),\n                                    self.toEncoding(val, encoding)))\n        close = ''\n        closeTag = ''\n        if self.isSelfClosing:\n            close = ' /'\n        else:\n            closeTag = '</%s>' % encodedName\n\n        indentTag, indentContents = 0, 0\n        if prettyPrint:\n            indentTag = indentLevel\n            space = (' ' * (indentTag-1))\n            indentContents = indentTag + 1\n        contents = self.renderContents(encoding, prettyPrint, indentContents)\n        if self.hidden:\n            s = contents\n        else:\n            s = []\n            attributeString = ''\n            if attrs:\n                attributeString = ' ' + ' '.join(attrs)            \n            if prettyPrint:\n                s.append(space)\n            s.append('<%s%s%s>' % (encodedName, attributeString, close))\n            if prettyPrint:\n                s.append(\"\\n\")\n            s.append(contents)\n            if prettyPrint and contents and contents[-1] != \"\\n\":\n                s.append(\"\\n\")\n            if prettyPrint and closeTag:\n                s.append(space)\n            s.append(closeTag)\n            if prettyPrint and closeTag and self.nextSibling:\n                s.append(\"\\n\")\n            s = ''.join(s)\n        return s\n\n    def prettify(self, encoding=DEFAULT_OUTPUT_ENCODING):\n        return self.__str__(encoding, True)\n\n    def renderContents(self, encoding=DEFAULT_OUTPUT_ENCODING,\n                       prettyPrint=False, indentLevel=0):\n        \"\"\"Renders the contents of this tag as a string in the given\n        encoding. If encoding is None, returns a Unicode string..\"\"\"\n        s=[]\n        for c in self:\n            text = None\n            if isinstance(c, NavigableString):\n                text = c.__str__(encoding)\n            elif isinstance(c, Tag):\n                s.append(c.__str__(encoding, prettyPrint, indentLevel))\n            if text and prettyPrint:\n                text = text.strip()              \n            if text:\n                if prettyPrint:\n                    s.append(\" \" * (indentLevel-1))\n                s.append(text)\n                if prettyPrint:\n                    s.append(\"\\n\")\n        return ''.join(s)    \n\n    #Soup methods\n\n    def find(self, name=None, attrs={}, recursive=True, text=None,\n             **kwargs):\n        \"\"\"Return only the first child of this Tag matching the given\n        criteria.\"\"\"\n        r = None\n        l = self.findAll(name, attrs, recursive, text, 1, **kwargs)\n        if l:\n            r = l[0]\n        return r\n    findChild = find\n\n    def findAll(self, name=None, attrs={}, recursive=True, text=None,\n                limit=None, **kwargs):\n        \"\"\"Extracts a list of Tag objects that match the given\n        criteria.  You can specify the name of the Tag and any\n        attributes you want the Tag to have.\n\n        The value of a key-value pair in the 'attrs' map can be a\n        string, a list of strings, a regular expression object, or a\n        callable that takes a string and returns whether or not the\n        string matches for some custom definition of 'matches'. The\n        same is true of the tag name.\"\"\"\n        generator = self.recursiveChildGenerator\n        if not recursive:\n            generator = self.childGenerator\n        return self._findAll(name, attrs, text, limit, generator, **kwargs)\n    findChildren = findAll\n\n    # Pre-3.x compatibility methods\n    first = find\n    fetch = findAll\n    \n    def fetchText(self, text=None, recursive=True, limit=None):\n        return self.findAll(text=text, recursive=recursive, limit=limit)\n\n    def firstText(self, text=None, recursive=True):\n        return self.find(text=text, recursive=recursive)\n    \n    #Utility methods\n\n    def append(self, tag):\n        \"\"\"Appends the given tag to the contents of this tag.\"\"\"\n        self.contents.append(tag)\n\n    #Private methods\n\n    def _getAttrMap(self):\n        \"\"\"Initializes a map representation of this tag's attributes,\n        if not already initialized.\"\"\"\n        if not getattr(self, 'attrMap'):\n            self.attrMap = {}\n            for (key, value) in self.attrs:\n                self.attrMap[key] = value \n        return self.attrMap\n\n    #Generator methods\n    def childGenerator(self):\n        for i in range(0, len(self.contents)):\n            yield self.contents[i]\n        raise StopIteration\n    \n    def recursiveChildGenerator(self):\n        stack = [(self, 0)]\n        while stack:\n            tag, start = stack.pop()\n            if isinstance(tag, Tag):            \n                for i in range(start, len(tag.contents)):\n                    a = tag.contents[i]\n                    yield a\n                    if isinstance(a, Tag) and tag.contents:\n                        if i < len(tag.contents) - 1:\n                            stack.append((tag, i+1))\n                        stack.append((a, 0))\n                        break\n        raise StopIteration\n\n# Next, a couple classes to represent queries and their results.\nclass SoupStrainer:\n    \"\"\"Encapsulates a number of ways of matching a markup element (tag or\n    text).\"\"\"\n\n    def __init__(self, name=None, attrs={}, text=None, **kwargs):\n        self.name = name\n        if isString(attrs):\n            kwargs['class'] = attrs\n            attrs = None\n        if kwargs:\n            if attrs:\n                attrs = attrs.copy()\n                attrs.update(kwargs)\n            else:\n                attrs = kwargs\n        self.attrs = attrs\n        self.text = text\n\n    def __str__(self):\n        if self.text:\n            return self.text\n        else:\n            return \"%s|%s\" % (self.name, self.attrs)\n    \n    def searchTag(self, markupName=None, markupAttrs={}):\n        found = None\n        markup = None\n        if isinstance(markupName, Tag):\n            markup = markupName\n            markupAttrs = markup\n        callFunctionWithTagData = callable(self.name) \\\n                                and not isinstance(markupName, Tag)\n\n        if (not self.name) \\\n               or callFunctionWithTagData \\\n               or (markup and self._matches(markup, self.name)) \\\n               or (not markup and self._matches(markupName, self.name)):\n            if callFunctionWithTagData:\n                match = self.name(markupName, markupAttrs)\n            else:\n                match = True            \n                markupAttrMap = None\n                for attr, matchAgainst in self.attrs.items():\n                    if not markupAttrMap:\n                         if hasattr(markupAttrs, 'get'):\n                            markupAttrMap = markupAttrs\n                         else:\n                            markupAttrMap = {}\n                            for k,v in markupAttrs:\n                                markupAttrMap[k] = v\n                    attrValue = markupAttrMap.get(attr)\n                    if not self._matches(attrValue, matchAgainst):\n                        match = False\n                        break\n            if match:\n                if markup:\n                    found = markup\n                else:\n                    found = markupName\n        return found\n\n    def search(self, markup):\n        #print 'looking for %s in %s' % (self, markup)\n        found = None\n        # If given a list of items, scan it for a text element that\n        # matches.        \n        if isList(markup) and not isinstance(markup, Tag):\n            for element in markup:\n                if isinstance(element, NavigableString) \\\n                       and self.search(element):\n                    found = element\n                    break\n        # If it's a Tag, make sure its name or attributes match.\n        # Don't bother with Tags if we're searching for text.\n        elif isinstance(markup, Tag):\n            if not self.text:\n                found = self.searchTag(markup)\n        # If it's text, make sure the text matches.\n        elif isinstance(markup, NavigableString) or \\\n                 isString(markup):\n            if self._matches(markup, self.text):\n                found = markup\n        else:\n            raise Exception, \"I don't know how to match against a %s\" \\\n                  % markup.__class__\n        return found\n        \n    def _matches(self, markup, matchAgainst):    \n        #print \"Matching %s against %s\" % (markup, matchAgainst)\n        result = False\n        if matchAgainst == True and type(matchAgainst) == types.BooleanType:\n            result = markup != None\n        elif callable(matchAgainst):\n            result = matchAgainst(markup)\n        else:\n            #Custom match methods take the tag as an argument, but all\n            #other ways of matching match the tag name as a string.\n            if isinstance(markup, Tag):\n                markup = markup.name\n            if markup and not isString(markup):\n                markup = unicode(markup)\n            #Now we know that chunk is either a string, or None.\n            if hasattr(matchAgainst, 'match'):\n                # It's a regexp object.\n                result = markup and matchAgainst.search(markup)\n            elif isList(matchAgainst):\n                result = markup in matchAgainst\n            elif hasattr(matchAgainst, 'items'):\n                result = markup.has_key(matchAgainst)\n            elif matchAgainst and isString(markup):\n                if isinstance(markup, unicode):\n                    matchAgainst = unicode(matchAgainst)\n                else:\n                    matchAgainst = str(matchAgainst)\n\n            if not result:\n                result = matchAgainst == markup\n        return result\n\nclass ResultSet(list):\n    \"\"\"A ResultSet is just a list that keeps track of the SoupStrainer\n    that created it.\"\"\"\n    def __init__(self, source):\n        list.__init__([])\n        self.source = source\n\n# Now, some helper functions.\n\ndef isList(l):\n    \"\"\"Convenience method that works with all 2.x versions of Python\n    to determine whether or not something is listlike.\"\"\"\n    return hasattr(l, '__iter__') \\\n           or (type(l) in (types.ListType, types.TupleType))\n\ndef isString(s):\n    \"\"\"Convenience method that works with all 2.x versions of Python\n    to determine whether or not something is stringlike.\"\"\"\n    try:\n        return isinstance(s, unicode) or isintance(s, basestring) \n    except NameError:\n        return isinstance(s, str)\n\ndef buildTagMap(default, *args):\n    \"\"\"Turns a list of maps, lists, or scalars into a single map.\n    Used to build the SELF_CLOSING_TAGS, NESTABLE_TAGS, and\n    NESTING_RESET_TAGS maps out of lists and partial maps.\"\"\"\n    built = {}\n    for portion in args:\n        if hasattr(portion, 'items'):\n            #It's a map. Merge it.\n            for k,v in portion.items():\n                built[k] = v\n        elif isList(portion):\n            #It's a list. Map each item to the default.\n            for k in portion:\n                built[k] = default\n        else:\n            #It's a scalar. Map it to the default.\n            built[portion] = default\n    return built\n\n# Now, the parser classes.\n\nclass BeautifulStoneSoup(Tag, SGMLParser):\n\n    \"\"\"This class contains the basic parser and search code. It defines\n    a parser that knows nothing about tag behavior except for the\n    following:\n   \n      You can't close a tag without closing all the tags it encloses.\n      That is, \"<foo><bar></foo>\" actually means\n      \"<foo><bar></bar></foo>\".\n\n    [Another possible explanation is \"<foo><bar /></foo>\", but since\n    this class defines no SELF_CLOSING_TAGS, it will never use that\n    explanation.]\n\n    This class is useful for parsing XML or made-up markup languages,\n    or when BeautifulSoup makes an assumption counter to what you were\n    expecting.\"\"\"\n\n    XML_ENTITY_LIST = {}\n    for i in Tag.XML_SPECIAL_CHARS_TO_ENTITIES.values():\n        XML_ENTITY_LIST[i] = True \n\n    SELF_CLOSING_TAGS = {}\n    NESTABLE_TAGS = {}\n    RESET_NESTING_TAGS = {}\n    QUOTE_TAGS = {}\n\n    MARKUP_MASSAGE = [(re.compile('(<[^<>]*)/>'),\n                       lambda x: x.group(1) + ' />'),\n                      (re.compile('<!\\s+([^<>]*)>'),\n                       lambda x: '<!' + x.group(1) + '>')\n                      ]\n\n    ROOT_TAG_NAME = u'[document]'\n\n    HTML_ENTITIES = \"html\"\n    XML_ENTITIES = \"xml\"\n\n    def __init__(self, markup=\"\", parseOnlyThese=None, fromEncoding=None,\n                 markupMassage=True, smartQuotesTo=XML_ENTITIES,\n                 convertEntities=None, selfClosingTags=None):\n        \"\"\"The Soup object is initialized as the 'root tag', and the\n        provided markup (which can be a string or a file-like object)\n        is fed into the underlying parser. \n\n        sgmllib will process most bad HTML, and the BeautifulSoup\n        class has some tricks for dealing with some HTML that kills\n        sgmllib, but Beautiful Soup can nonetheless choke or lose data\n        if your data uses self-closing tags or declarations\n        incorrectly.\n\n        By default, Beautiful Soup uses regexes to sanitize input,\n        avoiding the vast majority of these problems. If the problems\n        don't apply to you, pass in False for markupMassage, and\n        you'll get better performance.\n\n        The default parser massage techniques fix the two most common\n        instances of invalid HTML that choke sgmllib:\n\n         <br/> (No space between name of closing tag and tag close)\n         <! --Comment--> (Extraneous whitespace in declaration)\n\n        You can pass in a custom list of (RE object, replace method)\n        tuples to get Beautiful Soup to scrub your input the way you\n        want.\"\"\"\n\n        self.parseOnlyThese = parseOnlyThese\n        self.fromEncoding = fromEncoding\n        self.smartQuotesTo = smartQuotesTo\n        self.convertEntities = convertEntities\n        if self.convertEntities:\n            # It doesn't make sense to convert encoded characters to\n            # entities even while you're converting entities to Unicode.\n            # Just convert it all to Unicode.\n            self.smartQuotesTo = None\n        self.instanceSelfClosingTags = buildTagMap(None, selfClosingTags)\n        SGMLParser.__init__(self)\n            \n        if hasattr(markup, 'read'):        # It's a file-type object.\n            markup = markup.read()\n        self.markup = markup\n        self.markupMassage = markupMassage\n        try:\n            self._feed()\n        except StopParsing:\n            pass\n        self.markup = None                 # The markup can now be GCed\n        \n    def _feed(self, inDocumentEncoding=None):\n        # Convert the document to Unicode.\n        markup = self.markup\n        if isinstance(markup, unicode):\n            if not hasattr(self, 'originalEncoding'):\n                self.originalEncoding = None\n        else:\n            dammit = UnicodeDammit\\\n                     (markup, [self.fromEncoding, inDocumentEncoding],\n                      smartQuotesTo=self.smartQuotesTo)\n            markup = dammit.unicode\n            self.originalEncoding = dammit.originalEncoding\n        if markup:\n            if self.markupMassage:\n                if not isList(self.markupMassage):\n                    self.markupMassage = self.MARKUP_MASSAGE            \n                for fix, m in self.markupMassage:\n                    markup = fix.sub(m, markup)\n        self.reset()\n\n        SGMLParser.feed(self, markup)\n        # Close out any unfinished strings and close all the open tags.\n        self.endData()\n        while self.currentTag.name != self.ROOT_TAG_NAME:\n            self.popTag()\n\n    def __getattr__(self, methodName):\n        \"\"\"This method routes method call requests to either the SGMLParser\n        superclass or the Tag superclass, depending on the method name.\"\"\"\n        #print \"__getattr__ called on %s.%s\" % (self.__class__, methodName)\n\n        if methodName.find('start_') == 0 or methodName.find('end_') == 0 \\\n               or methodName.find('do_') == 0:\n            return SGMLParser.__getattr__(self, methodName)\n        elif methodName.find('__') != 0:\n            return Tag.__getattr__(self, methodName)\n        else:\n            raise AttributeError\n\n    def isSelfClosingTag(self, name):\n        \"\"\"Returns true iff the given string is the name of a\n        self-closing tag according to this parser.\"\"\"\n        return self.SELF_CLOSING_TAGS.has_key(name) \\\n               or self.instanceSelfClosingTags.has_key(name)\n            \n    def reset(self):\n        Tag.__init__(self, self, self.ROOT_TAG_NAME)\n        self.hidden = 1\n        SGMLParser.reset(self)\n        self.currentData = []\n        self.currentTag = None\n        self.tagStack = []\n        self.quoteStack = []\n        self.pushTag(self)\n    \n    def popTag(self):\n        tag = self.tagStack.pop()\n        # Tags with just one string-owning child get the child as a\n        # 'string' property, so that soup.tag.string is shorthand for\n        # soup.tag.contents[0]\n        if len(self.currentTag.contents) == 1 and \\\n           isinstance(self.currentTag.contents[0], NavigableString):\n            self.currentTag.string = self.currentTag.contents[0]\n\n        #print \"Pop\", tag.name\n        if self.tagStack:\n            self.currentTag = self.tagStack[-1]\n        return self.currentTag\n\n    def pushTag(self, tag):\n        #print \"Push\", tag.name\n        if self.currentTag:\n            self.currentTag.append(tag)\n        self.tagStack.append(tag)\n        self.currentTag = self.tagStack[-1]\n\n    def endData(self, containerClass=NavigableString):\n        if self.currentData:\n            currentData = ''.join(self.currentData)\n            if not currentData.strip():\n                if '\\n' in currentData:\n                    currentData = '\\n'\n                else:\n                    currentData = ' '\n            self.currentData = []\n            if self.parseOnlyThese and len(self.tagStack) <= 1 and \\\n                   (not self.parseOnlyThese.text or \\\n                    not self.parseOnlyThese.search(currentData)):\n                return\n            o = containerClass(currentData)\n            o.setup(self.currentTag, self.previous)\n            if self.previous:\n                self.previous.next = o\n            self.previous = o\n            self.currentTag.contents.append(o)\n\n\n    def _popToTag(self, name, inclusivePop=True):\n        \"\"\"Pops the tag stack up to and including the most recent\n        instance of the given tag. If inclusivePop is false, pops the tag\n        stack up to but *not* including the most recent instqance of\n        the given tag.\"\"\"\n        #print \"Popping to %s\" % name\n        if name == self.ROOT_TAG_NAME:\n            return            \n\n        numPops = 0\n        mostRecentTag = None\n        for i in range(len(self.tagStack)-1, 0, -1):\n            if name == self.tagStack[i].name:\n                numPops = len(self.tagStack)-i\n                break\n        if not inclusivePop:\n            numPops = numPops - 1\n\n        for i in range(0, numPops):\n            mostRecentTag = self.popTag()\n        return mostRecentTag    \n\n    def _smartPop(self, name):\n\n        \"\"\"We need to pop up to the previous tag of this type, unless\n        one of this tag's nesting reset triggers comes between this\n        tag and the previous tag of this type, OR unless this tag is a\n        generic nesting trigger and another generic nesting trigger\n        comes between this tag and the previous tag of this type.\n\n        Examples:\n         <p>Foo<b>Bar<p> should pop to 'p', not 'b'.\n         <p>Foo<table>Bar<p> should pop to 'table', not 'p'.\n         <p>Foo<table><tr>Bar<p> should pop to 'tr', not 'p'.\n         <p>Foo<b>Bar<p> should pop to 'p', not 'b'.\n\n         <li><ul><li> *<li>* should pop to 'ul', not the first 'li'.\n         <tr><table><tr> *<tr>* should pop to 'table', not the first 'tr'\n         <td><tr><td> *<td>* should pop to 'tr', not the first 'td'\n        \"\"\"\n\n        nestingResetTriggers = self.NESTABLE_TAGS.get(name)\n        isNestable = nestingResetTriggers != None\n        isResetNesting = self.RESET_NESTING_TAGS.has_key(name)\n        popTo = None\n        inclusive = True\n        for i in range(len(self.tagStack)-1, 0, -1):\n            p = self.tagStack[i]\n            if (not p or p.name == name) and not isNestable:\n                #Non-nestable tags get popped to the top or to their\n                #last occurance.\n                popTo = name\n                break\n            if (nestingResetTriggers != None\n                and p.name in nestingResetTriggers) \\\n                or (nestingResetTriggers == None and isResetNesting\n                    and self.RESET_NESTING_TAGS.has_key(p.name)):\n                \n                #If we encounter one of the nesting reset triggers\n                #peculiar to this tag, or we encounter another tag\n                #that causes nesting to reset, pop up to but not\n                #including that tag.\n                popTo = p.name\n                inclusive = False\n                break\n            p = p.parent\n        if popTo:\n            self._popToTag(popTo, inclusive)\n\n    def unknown_starttag(self, name, attrs, selfClosing=0):\n        #print \"Start tag %s: %s\" % (name, attrs)\n        if self.quoteStack:\n            #This is not a real tag.\n            #print \"<%s> is not real!\" % name\n            attrs = ''.join(map(lambda(x, y): ' %s=\"%s\"' % (x, y), attrs))\n            self.handle_data('<%s%s>' % (name, attrs))\n            return        \n        self.endData()\n\n        if not self.isSelfClosingTag(name) and not selfClosing:\n            self._smartPop(name)\n\n        if self.parseOnlyThese and len(self.tagStack) <= 1 \\\n               and (self.parseOnlyThese.text or not self.parseOnlyThese.searchTag(name, attrs)):\n            return\n\n        tag = Tag(self, name, attrs, self.currentTag, self.previous)\n        if self.previous:\n            self.previous.next = tag\n        self.previous = tag\n        self.pushTag(tag)\n        if selfClosing or self.isSelfClosingTag(name):\n            self.popTag()                \n        if name in self.QUOTE_TAGS:\n            #print \"Beginning quote (%s)\" % name\n            self.quoteStack.append(name)\n            self.literal = 1\n        return tag\n\n    def unknown_endtag(self, name):\n        #print \"End tag %s\" % name\n        if self.quoteStack and self.quoteStack[-1] != name:\n            #This is not a real end tag.\n            #print \"</%s> is not real!\" % name\n            self.handle_data('</%s>' % name)\n            return\n        self.endData()\n        self._popToTag(name)\n        if self.quoteStack and self.quoteStack[-1] == name:\n            self.quoteStack.pop()\n            self.literal = (len(self.quoteStack) > 0)\n\n    def handle_data(self, data):\n        self.currentData.append(data)\n\n    def _toStringSubclass(self, text, subclass):\n        \"\"\"Adds a certain piece of text to the tree as a NavigableString\n        subclass.\"\"\"\n        self.endData()\n        self.handle_data(text)\n        self.endData(subclass)\n\n    def handle_pi(self, text):\n        \"\"\"Handle a processing instruction as a ProcessingInstruction\n        object, possibly one with a %SOUP-ENCODING% slot into which an\n        encoding will be plugged later.\"\"\"\n        if text[:3] == \"xml\":\n            text = \"xml version='1.0' encoding='%SOUP-ENCODING%'\"\n        self._toStringSubclass(text, ProcessingInstruction)\n\n    def handle_comment(self, text):\n        \"Handle comments as Comment objects.\"\n        self._toStringSubclass(text, Comment)\n\n    def handle_charref(self, ref):\n        \"Handle character references as data.\"\n        if self.convertEntities in [self.HTML_ENTITIES,\n                                    self.XML_ENTITIES]:\n            data = unichr(int(ref))\n        else:\n            data = '&#%s;' % ref\n        self.handle_data(data)\n\n    def handle_entityref(self, ref):\n        \"\"\"Handle entity references as data, possibly converting known\n        HTML entity references to the corresponding Unicode\n        characters.\"\"\"\n        data = None\n        if self.convertEntities == self.HTML_ENTITIES or \\\n               (self.convertEntities == self.XML_ENTITIES and \\\n                self.XML_ENTITY_LIST.get(ref)):\n            try:\n                data = unichr(name2codepoint[ref])\n            except KeyError:\n                pass\n        if not data:\n            data = '&%s;' % ref\n        self.handle_data(data)\n        \n    def handle_decl(self, data):\n        \"Handle DOCTYPEs and the like as Declaration objects.\"\n        self._toStringSubclass(data, Declaration)\n\n    def parse_declaration(self, i):\n        \"\"\"Treat a bogus SGML declaration as raw data. Treat a CDATA\n        declaration as a CData object.\"\"\"\n        j = None\n        if self.rawdata[i:i+9] == '<![CDATA[':\n             k = self.rawdata.find(']]>', i)\n             if k == -1:\n                 k = len(self.rawdata)\n             data = self.rawdata[i+9:k]\n             j = k+3\n             self._toStringSubclass(data, CData)\n        else:\n            try:\n                j = SGMLParser.parse_declaration(self, i)\n            except SGMLParseError:\n                toHandle = self.rawdata[i:]\n                self.handle_data(toHandle)\n                j = i + len(toHandle)\n        return j\n\nclass BeautifulSoup(BeautifulStoneSoup):\n\n    \"\"\"This parser knows the following facts about HTML:\n\n    * Some tags have no closing tag and should be interpreted as being\n      closed as soon as they are encountered.\n\n    * The text inside some tags (ie. 'script') may contain tags which\n      are not really part of the document and which should be parsed\n      as text, not tags. If you want to parse the text as tags, you can\n      always fetch it and parse it explicitly.\n\n    * Tag nesting rules:\n\n      Most tags can't be nested at all. For instance, the occurance of\n      a <p> tag should implicitly close the previous <p> tag.\n\n       <p>Para1<p>Para2\n        should be transformed into:\n       <p>Para1</p><p>Para2\n\n      Some tags can be nested arbitrarily. For instance, the occurance\n      of a <blockquote> tag should _not_ implicitly close the previous\n      <blockquote> tag.\n\n       Alice said: <blockquote>Bob said: <blockquote>Blah\n        should NOT be transformed into:\n       Alice said: <blockquote>Bob said: </blockquote><blockquote>Blah\n\n      Some tags can be nested, but the nesting is reset by the\n      interposition of other tags. For instance, a <tr> tag should\n      implicitly close the previous <tr> tag within the same <table>,\n      but not close a <tr> tag in another table.\n\n       <table><tr>Blah<tr>Blah\n        should be transformed into:\n       <table><tr>Blah</tr><tr>Blah\n        but,\n       <tr>Blah<table><tr>Blah\n        should NOT be transformed into\n       <tr>Blah<table></tr><tr>Blah\n\n    Differing assumptions about tag nesting rules are a major source\n    of problems with the BeautifulSoup class. If BeautifulSoup is not\n    treating as nestable a tag your page author treats as nestable,\n    try ICantBelieveItsBeautifulSoup, MinimalSoup, or\n    BeautifulStoneSoup before writing your own subclass.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        if not kwargs.has_key('smartQuotesTo'):\n            kwargs['smartQuotesTo'] = self.HTML_ENTITIES\n        BeautifulStoneSoup.__init__(self, *args, **kwargs)\n\n    SELF_CLOSING_TAGS = buildTagMap(None,\n                                    ['br' , 'hr', 'input', 'img', 'meta',\n                                    'spacer', 'link', 'frame', 'base'])\n\n    QUOTE_TAGS = {'script': None}\n    \n    #According to the HTML standard, each of these inline tags can\n    #contain another tag of the same type. Furthermore, it's common\n    #to actually use these tags this way.\n    NESTABLE_INLINE_TAGS = ['span', 'font', 'q', 'object', 'bdo', 'sub', 'sup',\n                            'center']\n\n    #According to the HTML standard, these block tags can contain\n    #another tag of the same type. Furthermore, it's common\n    #to actually use these tags this way.\n    NESTABLE_BLOCK_TAGS = ['blockquote', 'div', 'fieldset', 'ins', 'del']\n\n    #Lists can contain other lists, but there are restrictions.    \n    NESTABLE_LIST_TAGS = { 'ol' : [],\n                           'ul' : [],\n                           'li' : ['ul', 'ol'],\n                           'dl' : [],\n                           'dd' : ['dl'],\n                           'dt' : ['dl'] }\n\n    #Tables can contain other tables, but there are restrictions.    \n    NESTABLE_TABLE_TAGS = {'table' : [], \n                           'tr' : ['table', 'tbody', 'tfoot', 'thead'],\n                           'td' : ['tr'],\n                           'th' : ['tr'],\n                           'thead' : ['table'],\n                           'tbody' : ['table'],\n                           'tfoot' : ['table'],\n                           }\n\n    NON_NESTABLE_BLOCK_TAGS = ['address', 'form', 'p', 'pre']\n\n    #If one of these tags is encountered, all tags up to the next tag of\n    #this type are popped.\n    RESET_NESTING_TAGS = buildTagMap(None, NESTABLE_BLOCK_TAGS, 'noscript',\n                                     NON_NESTABLE_BLOCK_TAGS,\n                                     NESTABLE_LIST_TAGS,\n                                     NESTABLE_TABLE_TAGS)\n\n    NESTABLE_TAGS = buildTagMap([], NESTABLE_INLINE_TAGS, NESTABLE_BLOCK_TAGS,\n                                NESTABLE_LIST_TAGS, NESTABLE_TABLE_TAGS)\n\n    # Used to detect the charset in a META tag; see start_meta\n    CHARSET_RE = re.compile(\"((^|;)\\s*charset=)([^;]*)\")\n\n    def start_meta(self, attrs):\n        \"\"\"Beautiful Soup can detect a charset included in a META tag,\n        try to convert the document to that charset, and re-parse the\n        document from the beginning.\"\"\"\n        httpEquiv = None\n        contentType = None\n        contentTypeIndex = None\n        tagNeedsEncodingSubstitution = False\n\n        for i in range(0, len(attrs)):\n            key, value = attrs[i]\n            key = key.lower()\n            if key == 'http-equiv':\n                httpEquiv = value\n            elif key == 'content':\n                contentType = value\n                contentTypeIndex = i\n\n        if httpEquiv and contentType: # It's an interesting meta tag.\n            match = self.CHARSET_RE.search(contentType)\n            if match:\n                if getattr(self, 'declaredHTMLEncoding') or \\\n                       (self.originalEncoding == self.fromEncoding):\n                    # This is our second pass through the document, or\n                    # else an encoding was specified explicitly and it\n                    # worked. Rewrite the meta tag.\n                    newAttr = self.CHARSET_RE.sub\\\n                              (lambda(match):match.group(1) +\n                               \"%SOUP-ENCODING%\", value)\n                    attrs[contentTypeIndex] = (attrs[contentTypeIndex][0],\n                                               newAttr)\n                    tagNeedsEncodingSubstitution = True\n                else:\n                    # This is our first pass through the document.\n                    # Go through it again with the new information.\n                    newCharset = match.group(3)\n                    if newCharset and newCharset != self.originalEncoding:\n                        self.declaredHTMLEncoding = newCharset\n                        self._feed(self.declaredHTMLEncoding)\n                        raise StopParsing\n        tag = self.unknown_starttag(\"meta\", attrs)\n        if tag and tagNeedsEncodingSubstitution:\n            tag.containsSubstitutions = True\n\nclass StopParsing(Exception):\n    pass\n   \nclass ICantBelieveItsBeautifulSoup(BeautifulSoup):\n\n    \"\"\"The BeautifulSoup class is oriented towards skipping over\n    common HTML errors like unclosed tags. However, sometimes it makes\n    errors of its own. For instance, consider this fragment:\n\n     <b>Foo<b>Bar</b></b>\n\n    This is perfectly valid (if bizarre) HTML. However, the\n    BeautifulSoup class will implicitly close the first b tag when it\n    encounters the second 'b'. It will think the author wrote\n    \"<b>Foo<b>Bar\", and didn't close the first 'b' tag, because\n    there's no real-world reason to bold something that's already\n    bold. When it encounters '</b></b>' it will close two more 'b'\n    tags, for a grand total of three tags closed instead of two. This\n    can throw off the rest of your document structure. The same is\n    true of a number of other tags, listed below.\n\n    It's much more common for someone to forget to close a 'b' tag\n    than to actually use nested 'b' tags, and the BeautifulSoup class\n    handles the common case. This class handles the not-co-common\n    case: where you can't believe someone wrote what they did, but\n    it's valid HTML and BeautifulSoup screwed up by assuming it\n    wouldn't be.\"\"\"\n\n    I_CANT_BELIEVE_THEYRE_NESTABLE_INLINE_TAGS = \\\n     ['em', 'big', 'i', 'small', 'tt', 'abbr', 'acronym', 'strong',\n      'cite', 'code', 'dfn', 'kbd', 'samp', 'strong', 'var', 'b',\n      'big']\n\n    I_CANT_BELIEVE_THEYRE_NESTABLE_BLOCK_TAGS = ['noscript']\n\n    NESTABLE_TAGS = buildTagMap([], BeautifulSoup.NESTABLE_TAGS,\n                                I_CANT_BELIEVE_THEYRE_NESTABLE_BLOCK_TAGS,\n                                I_CANT_BELIEVE_THEYRE_NESTABLE_INLINE_TAGS)\n\nclass MinimalSoup(BeautifulSoup):\n    \"\"\"The MinimalSoup class is for parsing HTML that contains\n    pathologically bad markup. It makes no assumptions about tag\n    nesting, but it does know which tags are self-closing, that\n    <script> tags contain Javascript and should not be parsed, that\n    META tags may contain encoding information, and so on.\n\n    This also makes it better for subclassing than BeautifulStoneSoup\n    or BeautifulSoup.\"\"\"\n    \n    RESET_NESTING_TAGS = buildTagMap('noscript')\n    NESTABLE_TAGS = {}\n\nclass BeautifulSOAP(BeautifulStoneSoup):\n    \"\"\"This class will push a tag with only a single string child into\n    the tag's parent as an attribute. The attribute's name is the tag\n    name, and the value is the string child. An example should give\n    the flavor of the change:\n\n    <foo><bar>baz</bar></foo>\n     =>\n    <foo bar=\"baz\"><bar>baz</bar></foo>\n\n    You can then access fooTag['bar'] instead of fooTag.barTag.string.\n\n    This is, of course, useful for scraping structures that tend to\n    use subelements instead of attributes, such as SOAP messages. Note\n    that it modifies its input, so don't print the modified version\n    out.\n\n    I'm not sure how many people really want to use this class; let me\n    know if you do. Mainly I like the name.\"\"\"\n\n    def popTag(self):\n        if len(self.tagStack) > 1:\n            tag = self.tagStack[-1]\n            parent = self.tagStack[-2]\n            parent._getAttrMap()\n            if (isinstance(tag, Tag) and len(tag.contents) == 1 and\n                isinstance(tag.contents[0], NavigableString) and \n                not parent.attrMap.has_key(tag.name)):\n                parent[tag.name] = tag.contents[0]\n        BeautifulStoneSoup.popTag(self)\n\n#Enterprise class names! It has come to our attention that some people\n#think the names of the Beautiful Soup parser classes are too silly\n#and \"unprofessional\" for use in enterprise screen-scraping. We feel\n#your pain! For such-minded folk, the Beautiful Soup Consortium And\n#All-Night Kosher Bakery recommends renaming this file to\n#\"RobustParser.py\" (or, in cases of extreme enterprisness,\n#\"RobustParserBeanInterface.class\") and using the following\n#enterprise-friendly class aliases:\nclass RobustXMLParser(BeautifulStoneSoup):\n    pass\nclass RobustHTMLParser(BeautifulSoup):\n    pass\nclass RobustWackAssHTMLParser(ICantBelieveItsBeautifulSoup):\n    pass\nclass RobustInsanelyWackAssHTMLParser(MinimalSoup):\n    pass\nclass SimplifyingSOAPParser(BeautifulSOAP):\n    pass\n\n######################################################\n#\n# Bonus library: Unicode, Dammit\n#\n# This class forces XML data into a standard format (usually to UTF-8\n# or Unicode).  It is heavily based on code from Mark Pilgrim's\n# Universal Feed Parser. It does not rewrite the XML or HTML to\n# reflect a new encoding: that happens in BeautifulStoneSoup.handle_pi\n# (XML) and BeautifulSoup.start_meta (HTML).\n\n# Autodetects character encodings.\n# Download from http://chardet.feedparser.org/\ntry:\n    import chardet\n#    import chardet.constants\n#    chardet.constants._debug = 1\nexcept:\n    chardet = None\nchardet = None\n\n# cjkcodecs and iconv_codec make Python know about more character encodings.\n# Both are available from http://cjkpython.i18n.org/\n# They're built in if you use Python 2.4.\ntry:\n    import cjkcodecs.aliases\nexcept:\n    pass\ntry:\n    import iconv_codec\nexcept:\n    pass\n\nclass UnicodeDammit:\n    \"\"\"A class for detecting the encoding of a *ML document and\n    converting it to a Unicode string. If the source encoding is\n    windows-1252, can replace MS smart quotes with their HTML or XML\n    equivalents.\"\"\"\n\n    # This dictionary maps commonly seen values for \"charset\" in HTML\n    # meta tags to the corresponding Python codec names. It only covers\n    # values that aren't in Python's aliases and can't be determined\n    # by the heuristics in find_codec.\n    CHARSET_ALIASES = { \"macintosh\" : \"mac-roman\",\n                        \"x-sjis\" : \"shift-jis\" }\n\n    def __init__(self, markup, overrideEncodings=[],\n                 smartQuotesTo='xml'):\n        self.markup, documentEncoding, sniffedEncoding = \\\n                     self._detectEncoding(markup)\n        self.smartQuotesTo = smartQuotesTo\n        self.triedEncodings = []\n        if markup == '' or isinstance(markup, unicode):\n            self.originalEncoding = None\n            self.unicode = unicode(markup)            \n            return\n        \n        u = None\n        for proposedEncoding in overrideEncodings:\n            u = self._convertFrom(proposedEncoding)\n            if u: break\n        if not u:\n            for proposedEncoding in (documentEncoding, sniffedEncoding):\n                u = self._convertFrom(proposedEncoding)\n                if u: break\n                \n        # If no luck and we have auto-detection library, try that:\n        if not u and chardet and not isinstance(self.markup, unicode):\n            u = self._convertFrom(chardet.detect(self.markup)['encoding'])\n\n        # As a last resort, try utf-8 and windows-1252:\n        if not u:\n            for proposed_encoding in (\"utf-8\", \"windows-1252\"):\n                u = self._convertFrom(proposed_encoding)\n                if u: break\n        self.unicode = u\n        if not u: self.originalEncoding = None\n\n    def _subMSChar(self, orig):\n        \"\"\"Changes a MS smart quote character to an XML or HTML\n        entity.\"\"\"\n        sub = self.MS_CHARS.get(orig)\n        if type(sub) == types.TupleType:\n            if self.smartQuotesTo == 'xml':\n                sub = '&#x%s;' % sub[1]\n            else:\n                sub = '&%s;' % sub[0]\n        return sub            \n\n    def _convertFrom(self, proposed):        \n        proposed = self.find_codec(proposed)\n        if not proposed or proposed in self.triedEncodings:\n            return None\n        self.triedEncodings.append(proposed)\n        markup = self.markup\n\n        # Convert smart quotes to HTML if coming from an encoding\n        # that might have them.\n        if self.smartQuotesTo and proposed.lower() in(\"windows-1252\",\n                                                      \"iso-8859-1\",\n                                                      \"iso-8859-2\"):\n            markup = re.compile(\"([\\x80-\\x9f])\").sub \\\n                     (lambda(x): self._subMSChar(x.group(1)),\n                      markup)\n\n        try:\n            # print \"Trying to convert document to %s\" % proposed\n            u = self._toUnicode(markup, proposed)\n            self.markup = u       \n            self.originalEncoding = proposed\n        except Exception, e:\n            # print \"That didn't work!\"\n            # print e\n            return None        \n        #print \"Correct encoding: %s\" % proposed\n        return self.markup\n\n    def _toUnicode(self, data, encoding):\n        '''Given a string and its encoding, decodes the string into Unicode.\n        %encoding is a string recognized by encodings.aliases'''\n\n        # strip Byte Order Mark (if present)\n        if (len(data) >= 4) and (data[:2] == '\\xfe\\xff') \\\n               and (data[2:4] != '\\x00\\x00'):\n            encoding = 'utf-16be'\n            data = data[2:]\n        elif (len(data) >= 4) and (data[:2] == '\\xff\\xfe') \\\n                 and (data[2:4] != '\\x00\\x00'):\n            encoding = 'utf-16le'\n            data = data[2:]\n        elif data[:3] == '\\xef\\xbb\\xbf':\n            encoding = 'utf-8'\n            data = data[3:]\n        elif data[:4] == '\\x00\\x00\\xfe\\xff':\n            encoding = 'utf-32be'\n            data = data[4:]\n        elif data[:4] == '\\xff\\xfe\\x00\\x00':\n            encoding = 'utf-32le'\n            data = data[4:]\n        newdata = unicode(data, encoding)\n        return newdata\n    \n    def _detectEncoding(self, xml_data):\n        \"\"\"Given a document, tries to detect its XML encoding.\"\"\"\n        xml_encoding = sniffed_xml_encoding = None\n        try:\n            if xml_data[:4] == '\\x4c\\x6f\\xa7\\x94':\n                # EBCDIC\n                xml_data = self._ebcdic_to_ascii(xml_data)\n            elif xml_data[:4] == '\\x00\\x3c\\x00\\x3f':\n                # UTF-16BE\n                sniffed_xml_encoding = 'utf-16be'\n                xml_data = unicode(xml_data, 'utf-16be').encode('utf-8')\n            elif (len(xml_data) >= 4) and (xml_data[:2] == '\\xfe\\xff') \\\n                     and (xml_data[2:4] != '\\x00\\x00'):\n                # UTF-16BE with BOM\n                sniffed_xml_encoding = 'utf-16be'\n                xml_data = unicode(xml_data[2:], 'utf-16be').encode('utf-8')\n            elif xml_data[:4] == '\\x3c\\x00\\x3f\\x00':\n                # UTF-16LE\n                sniffed_xml_encoding = 'utf-16le'\n                xml_data = unicode(xml_data, 'utf-16le').encode('utf-8')\n            elif (len(xml_data) >= 4) and (xml_data[:2] == '\\xff\\xfe') and \\\n                     (xml_data[2:4] != '\\x00\\x00'):\n                # UTF-16LE with BOM\n                sniffed_xml_encoding = 'utf-16le'\n                xml_data = unicode(xml_data[2:], 'utf-16le').encode('utf-8')\n            elif xml_data[:4] == '\\x00\\x00\\x00\\x3c':\n                # UTF-32BE\n                sniffed_xml_encoding = 'utf-32be'\n                xml_data = unicode(xml_data, 'utf-32be').encode('utf-8')\n            elif xml_data[:4] == '\\x3c\\x00\\x00\\x00':\n                # UTF-32LE\n                sniffed_xml_encoding = 'utf-32le'\n                xml_data = unicode(xml_data, 'utf-32le').encode('utf-8')\n            elif xml_data[:4] == '\\x00\\x00\\xfe\\xff':\n                # UTF-32BE with BOM\n                sniffed_xml_encoding = 'utf-32be'\n                xml_data = unicode(xml_data[4:], 'utf-32be').encode('utf-8')\n            elif xml_data[:4] == '\\xff\\xfe\\x00\\x00':\n                # UTF-32LE with BOM\n                sniffed_xml_encoding = 'utf-32le'\n                xml_data = unicode(xml_data[4:], 'utf-32le').encode('utf-8')\n            elif xml_data[:3] == '\\xef\\xbb\\xbf':\n                # UTF-8 with BOM\n                sniffed_xml_encoding = 'utf-8'\n                xml_data = unicode(xml_data[3:], 'utf-8').encode('utf-8')\n            else:\n                sniffed_xml_encoding = 'ascii'\n                pass\n            xml_encoding_match = re.compile \\\n                                 ('^<\\?.*encoding=[\\'\"](.*?)[\\'\"].*\\?>')\\\n                                 .match(xml_data)\n        except:\n            xml_encoding_match = None\n        if xml_encoding_match:\n            xml_encoding = xml_encoding_match.groups()[0].lower()\n            if sniffed_xml_encoding and \\\n               (xml_encoding in ('iso-10646-ucs-2', 'ucs-2', 'csunicode',\n                                 'iso-10646-ucs-4', 'ucs-4', 'csucs4',\n                                 'utf-16', 'utf-32', 'utf_16', 'utf_32',\n                                 'utf16', 'u16')):\n                xml_encoding = sniffed_xml_encoding\n        return xml_data, xml_encoding, sniffed_xml_encoding\n\n\n    def find_codec(self, charset):\n        return self._codec(self.CHARSET_ALIASES.get(charset, charset)) \\\n               or (charset and self._codec(charset.replace(\"-\", \"\"))) \\\n               or (charset and self._codec(charset.replace(\"-\", \"_\"))) \\\n               or charset\n\n    def _codec(self, charset):\n        if not charset: return charset \n        codec = None\n        try:\n            codecs.lookup(charset)\n            codec = charset\n        except LookupError:\n            pass\n        return codec\n\n    EBCDIC_TO_ASCII_MAP = None\n    def _ebcdic_to_ascii(self, s):\n        c = self.__class__\n        if not c.EBCDIC_TO_ASCII_MAP:\n            emap = (0,1,2,3,156,9,134,127,151,141,142,11,12,13,14,15,\n                    16,17,18,19,157,133,8,135,24,25,146,143,28,29,30,31,\n                    128,129,130,131,132,10,23,27,136,137,138,139,140,5,6,7,\n                    144,145,22,147,148,149,150,4,152,153,154,155,20,21,158,26,\n                    32,160,161,162,163,164,165,166,167,168,91,46,60,40,43,33,\n                    38,169,170,171,172,173,174,175,176,177,93,36,42,41,59,94,\n                    45,47,178,179,180,181,182,183,184,185,124,44,37,95,62,63,\n                    186,187,188,189,190,191,192,193,194,96,58,35,64,39,61,34,\n                    195,97,98,99,100,101,102,103,104,105,196,197,198,199,200,\n                    201,202,106,107,108,109,110,111,112,113,114,203,204,205,\n                    206,207,208,209,126,115,116,117,118,119,120,121,122,210,\n                    211,212,213,214,215,216,217,218,219,220,221,222,223,224,\n                    225,226,227,228,229,230,231,123,65,66,67,68,69,70,71,72,\n                    73,232,233,234,235,236,237,125,74,75,76,77,78,79,80,81,\n                    82,238,239,240,241,242,243,92,159,83,84,85,86,87,88,89,\n                    90,244,245,246,247,248,249,48,49,50,51,52,53,54,55,56,57,\n                    250,251,252,253,254,255)\n            import string\n            c.EBCDIC_TO_ASCII_MAP = string.maketrans( \\\n            ''.join(map(chr, range(256))), ''.join(map(chr, emap)))\n        return s.translate(c.EBCDIC_TO_ASCII_MAP)\n\n    MS_CHARS = { '\\x80' : ('euro', '20AC'),\n                 '\\x81' : ' ',\n                 '\\x82' : ('sbquo', '201A'),\n                 '\\x83' : ('fnof', '192'),\n                 '\\x84' : ('bdquo', '201E'),\n                 '\\x85' : ('hellip', '2026'),\n                 '\\x86' : ('dagger', '2020'),\n                 '\\x87' : ('Dagger', '2021'),\n                 '\\x88' : ('circ', '2C6'),\n                 '\\x89' : ('permil', '2030'),\n                 '\\x8A' : ('Scaron', '160'),\n                 '\\x8B' : ('lsaquo', '2039'),\n                 '\\x8C' : ('OElig', '152'),\n                 '\\x8D' : '?',\n                 '\\x8E' : ('#x17D', '17D'),\n                 '\\x8F' : '?',\n                 '\\x90' : '?',\n                 '\\x91' : ('lsquo', '2018'),\n                 '\\x92' : ('rsquo', '2019'),\n                 '\\x93' : ('ldquo', '201C'),\n                 '\\x94' : ('rdquo', '201D'),\n                 '\\x95' : ('bull', '2022'),\n                 '\\x96' : ('ndash', '2013'),\n                 '\\x97' : ('mdash', '2014'),\n                 '\\x98' : ('tilde', '2DC'),\n                 '\\x99' : ('trade', '2122'),\n                 '\\x9a' : ('scaron', '161'),\n                 '\\x9b' : ('rsaquo', '203A'),\n                 '\\x9c' : ('oelig', '153'),\n                 '\\x9d' : '?',\n                 '\\x9e' : ('#x17E', '17E'),\n                 '\\x9f' : ('Yuml', ''),}\n\n#######################################################################\n\n\n#By default, act as an HTML pretty-printer.\nif __name__ == '__main__':\n    import sys\n    soup = BeautifulSoup(sys.stdin.read())\n    print soup.prettify()\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tools/README.txt",
    "content": "This directory contains tools used in the packaging or deployment of OpenLayers.\n\nJavascript minimizing tools:\n\n * jsmin.c, jsmin.py:\n   jsmin.py is a direct translation of the jsmin.c code into Python. jsmin.py\n   will therefore run anyplace Python runs... but at significantly slower speed.\n \n * shrinksafe.py\n   shrinksafe.py calls out to a third party javascript shrinking service. This \n   creates file sizes about 4% smaller (as of commit 501) of the OpenLayers \n   code. However, this also has the side effect of making you dependent on the \n   web service -- and since that service sometimes goes dead, it's risky to \n   depend on it.\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tools/closure_library_jscompiler.py",
    "content": "# Copyright 2010 The Closure Library Authors. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS-IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\n\"\"\"Utility to use the Closure Compiler CLI from Python.\"\"\"\n\nimport distutils.version\nimport logging\nimport re\nimport subprocess\n\n\n# Pulls a version number from the first line of 'java -version'\n# See http://java.sun.com/j2se/versioning_naming.html to learn more about the\n# command's output format.\n_VERSION_REGEX = re.compile('\"([0-9][.0-9]*)')\n\n\ndef _GetJavaVersion():\n  \"\"\"Returns the string for the current version of Java installed.\"\"\"\n  proc = subprocess.Popen(['java', '-version'], stderr=subprocess.PIPE)\n  unused_stdoutdata, stderrdata = proc.communicate()\n  version_line = stderrdata.splitlines()[0]\n  return _VERSION_REGEX.search(version_line).group(1)\n\n\ndef Compile(compiler_jar_path, source_paths, flags=None):\n  \"\"\"Prepares command-line call to Closure Compiler.\n\n  Args:\n    compiler_jar_path: Path to the Closure compiler .jar file.\n    source_paths: Source paths to build, in order.\n    flags: A list of additional flags to pass on to Closure Compiler.\n\n  Returns:\n    The compiled source, as a string, or None if compilation failed.\n  \"\"\"\n\n  # User friendly version check.\n  if not (distutils.version.LooseVersion(_GetJavaVersion()) >=\n          distutils.version.LooseVersion('1.6')):\n    logging.error('Closure Compiler requires Java 1.6 or higher. '\n                  'Please visit http://www.java.com/getjava')\n    return\n\n  args = ['java', '-jar', compiler_jar_path]\n  for path in source_paths:\n    args += ['--js', path]\n\n  if flags:\n    args += flags\n\n  logging.info('Compiling with the following command: %s', ' '.join(args))\n\n  proc = subprocess.Popen(args, stdout=subprocess.PIPE)\n  stdoutdata, unused_stderrdata = proc.communicate()\n\n  if proc.returncode != 0:\n    return\n\n  return stdoutdata\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tools/closure_ws.py",
    "content": "#!/usr/bin/python\n\nimport httplib, urllib, sys\nimport time\n# Define the parameters for the POST request and encode them in\n# a URL-safe format.\n\ndef minimize(code):\n\n    params = urllib.urlencode([\n        ('js_code', code),\n        ('compilation_level', 'SIMPLE_OPTIMIZATIONS'),\n        ('output_format', 'text'),\n        ('output_info', 'compiled_code'),\n      ])\n    \n    t = time.time()\n    # Always use the following value for the Content-type header.\n    headers = { \"Content-type\": \"application/x-www-form-urlencoded\" }\n    conn = httplib.HTTPConnection('closure-compiler.appspot.com')\n    conn.request('POST', '/compile', params, headers)\n    response = conn.getresponse()\n    data = response.read()\n    conn.close()\n    if data.startswith(\"Error\"):\n        raise Exception(data)\n    print \"%.3f seconds to compile\" % (time.time() - t) \n    return data\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tools/exampleparser.py",
    "content": "#!/usr/bin/env python\n\nimport sys\nimport os\nimport re\nimport time\nfrom xml.dom.minidom import Document\n\ntry:\n    import xml.etree.ElementTree as ElementTree \nexcept ImportError:\n    try:\n        import cElementTree as ElementTree\n    except ImportError:\n        try:\n            import elementtree.ElementTree as ElementTree\n        except ImportError:\n            import lxml.etree as ElementTree\n\nmissing_deps = False\ntry:\n    import json\nexcept ImportError:\n    try:\n        import simplejson as json\n    except ImportError, E:\n        missing_deps = E \n    \ntry:\n    from BeautifulSoup import BeautifulSoup\nexcept ImportError, E:\n    missing_deps = E \n\nfeedName = \"example-list.xml\"\nfeedPath = \"http://openlayers.org/dev/examples/\"\n\ndef getListOfExamples(relPath):\n    \"\"\"\n    returns list of .html filenames within a given path - excludes example-list.html\n    \"\"\"\n    examples = os.listdir(relPath)\n    examples = [example for example in examples if example.endswith('.html') and example != \"example-list.html\"]\n    return examples\n    \n\ndef getExampleHtml(path):\n    \"\"\"\n    returns html of a specific example\n    \"\"\"\n    print '.',\n    f = open(path)\n    html = f.read()\n    f.close()\n    return html\n        \n    \ndef extractById(soup, tagId, value=None):\n    \"\"\"\n    returns full contents of a particular tag id\n    \"\"\"\n    beautifulTag = soup.find(id=tagId)\n    if beautifulTag:\n        if beautifulTag.contents: \n            value = str(beautifulTag.renderContents()).strip()\n            value = value.replace('\\t','')\n            value = value.replace('\\n','')\n    return value\n\ndef getRelatedClasses(html):\n    \"\"\"\n    parses the html, and returns a list of all OpenLayers Classes \n    used within (ie what parts of OL the javascript uses).  \n    \"\"\"\n    rawstr = r'''(?P<class>OpenLayers\\..*?)\\('''\n    return re.findall(rawstr, html)\n\ndef parseHtml(html,ids):\n    \"\"\"\n    returns dictionary of items of interest\n    \"\"\"\n    soup = BeautifulSoup(html)\n    d = {}\n    for tagId in ids:\n        d[tagId] = extractById(soup,tagId)\n    #classes should eventually be parsed from docs - not automatically created.\n    classes = getRelatedClasses(html)\n    d['classes'] = classes\n    return d\n\ndef getGitInfo(exampleDir, exampleName):\n    orig = os.getcwd()\n    os.chdir(exampleDir)\n    h = os.popen(\"git log -n 1 --pretty=format:'%an|%ai' \" + exampleName)\n    os.chdir(orig)\n    log = h.read()\n    h.close()\n    d = {}\n    parts = log.split(\"|\")\n    d[\"author\"] = parts[0]\n    # compensate for spaces in git log time\n    td = parts[1].split(\" \")\n    td.insert(1, \"T\")\n    d[\"date\"] = \"\".join(td)\n    return d\n    \ndef createFeed(examples):\n    doc = Document()\n    atomuri = \"http://www.w3.org/2005/Atom\"\n    feed = doc.createElementNS(atomuri, \"feed\")\n    feed.setAttribute(\"xmlns\", atomuri)\n    title = doc.createElementNS(atomuri, \"title\")\n    title.appendChild(doc.createTextNode(\"OpenLayers Examples\"))\n    feed.appendChild(title)\n    link = doc.createElementNS(atomuri, \"link\")\n    link.setAttribute(\"rel\", \"self\")\n    link.setAttribute(\"href\", feedPath + feedName)\n    \n    modtime = time.strftime(\"%Y-%m-%dT%I:%M:%SZ\", time.gmtime())\n    id = doc.createElementNS(atomuri, \"id\")\n    id.appendChild(doc.createTextNode(\"%s%s#%s\" % (feedPath, feedName, modtime)))\n    feed.appendChild(id)\n    \n    updated = doc.createElementNS(atomuri, \"updated\")\n    updated.appendChild(doc.createTextNode(modtime))\n    feed.appendChild(updated)\n\n    examples.sort(key=lambda x:x[\"modified\"])\n    for example in sorted(examples, key=lambda x:x[\"modified\"], reverse=True):\n        entry = doc.createElementNS(atomuri, \"entry\")\n        \n        title = doc.createElementNS(atomuri, \"title\")\n        title.appendChild(doc.createTextNode(example[\"title\"] or example[\"example\"]))\n        entry.appendChild(title)\n              \n        tags = doc.createElementNS(atomuri, \"tags\")\n        tags.appendChild(doc.createTextNode(example[\"tags\"] or example[\"example\"]))\n        entry.appendChild(tags)\n        \n        link = doc.createElementNS(atomuri, \"link\")\n        link.setAttribute(\"href\", \"%s%s\" % (feedPath, example[\"example\"]))\n        entry.appendChild(link)\n    \n        summary = doc.createElementNS(atomuri, \"summary\")\n        summary.appendChild(doc.createTextNode(example[\"shortdesc\"] or example[\"example\"]))\n        entry.appendChild(summary)\n        \n        updated = doc.createElementNS(atomuri, \"updated\")\n        updated.appendChild(doc.createTextNode(example[\"modified\"]))\n        entry.appendChild(updated)\n        \n        author = doc.createElementNS(atomuri, \"author\")\n        name = doc.createElementNS(atomuri, \"name\")\n        name.appendChild(doc.createTextNode(example[\"author\"]))\n        author.appendChild(name)\n        entry.appendChild(author)\n        \n        id = doc.createElementNS(atomuri, \"id\")\n        id.appendChild(doc.createTextNode(\"%s%s#%s\" % (feedPath, example[\"example\"], example[\"modified\"])))\n        entry.appendChild(id)\n        \n        feed.appendChild(entry)\n\n    doc.appendChild(feed)\n    return doc    \n    \ndef wordIndex(examples):\n    \"\"\"\n    Create an inverted index based on words in title and shortdesc.  Keys are\n    lower cased words.  Values are dictionaries with example index keys and\n    count values.\n    \"\"\"\n    index = {}\n    unword = re.compile(\"\\\\W+\")\n    keys = [\"shortdesc\", \"title\", \"tags\"]\n    for i in range(len(examples)):\n        for key in keys:\n            text = examples[i][key]\n            if text:\n                words = unword.split(text)\n                for word in words:\n                    if word:\n                        word = word.lower()\n                        if index.has_key(word):\n                            if index[word].has_key(i):\n                                index[word][i] += 1\n                            else:\n                                index[word][i] = 1\n                        else:\n                            index[word] = {i: 1}\n    return index\n    \nif __name__ == \"__main__\":\n\n    if missing_deps:\n        print \"This script requires json or simplejson and BeautifulSoup. You don't have them. \\n(%s)\" % E\n        sys.exit()\n    \n    if len(sys.argv) == 3:\n        inExampleDir = sys.argv[1]\n        outExampleDir = sys.argv[2]\n    else:\n        inExampleDir = \"../examples\"\n        outExampleDir = \"../examples\"\n    \n    outFile = open(os.path.join(outExampleDir, \"example-list.js\"), \"w\")\n    \n    print 'Reading examples from %s and writing out to %s' % (inExampleDir, outFile.name)\n   \n    exampleList = []\n    docIds = ['title','shortdesc','tags']\n   \n    examples = getListOfExamples(inExampleDir)\n\n    modtime = time.strftime(\"%Y-%m-%dT%I:%M:%SZ\", time.gmtime())\n\n    for example in examples:\n        path = os.path.join(inExampleDir, example)\n        html = getExampleHtml(path)\n        tagvalues = parseHtml(html,docIds)\n        tagvalues['example'] = example\n        # add in author/date info\n        d = getGitInfo(inExampleDir, example)\n        tagvalues[\"author\"] = d[\"author\"] or \"anonymous\"\n        tagvalues[\"modified\"] = d[\"date\"] or modtime\n        tagvalues['link'] = example\n\n        exampleList.append(tagvalues)\n        \n    print\n    \n    exampleList.sort(key=lambda x:x['example'].lower())\n    \n    index = wordIndex(exampleList)\n\n    json = json.dumps({\"examples\": exampleList, \"index\": index})\n    #give the json a global variable we can use in our js.  This should be replaced or made optional.\n    json = 'var info=' + json \n    outFile.write(json)\n    outFile.close()\n\n    outFeedPath = os.path.join(outExampleDir, feedName);\n    print \"writing feed to %s \" % outFeedPath\n    atom = open(outFeedPath, 'w')\n    doc = createFeed(exampleList)\n    atom.write(doc.toxml())\n    atom.close()\n\n\n    print 'complete'\n\n    \n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tools/jsmin.c",
    "content": "/* jsmin.c\n   2006-05-04\n\nCopyright (c) 2002 Douglas Crockford  (www.crockford.com)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nThe Software shall be used for Good, not Evil.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n*/\n\n#include <stdlib.h>\n#include <stdio.h>\n\nstatic int   theA;\nstatic int   theB;\nstatic int   theLookahead = EOF;\n\n\n/* isAlphanum -- return true if the character is a letter, digit, underscore,\n        dollar sign, or non-ASCII character.\n*/\n\nstatic int\nisAlphanum(int c)\n{\n    return ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') ||\n        (c >= 'A' && c <= 'Z') || c == '_' || c == '$' || c == '\\\\' ||\n        c > 126);\n}\n\n\n/* get -- return the next character from stdin. Watch out for lookahead. If\n        the character is a control character, translate it to a space or\n        linefeed.\n*/\n\nstatic int\nget()\n{\n    int c = theLookahead;\n    theLookahead = EOF;\n    if (c == EOF) {\n        c = getc(stdin);\n    }\n    if (c >= ' ' || c == '\\n' || c == EOF) {\n        return c;\n    }\n    if (c == '\\r') {\n        return '\\n';\n    }\n    return ' ';\n}\n\n\n/* peek -- get the next character without getting it.\n*/\n\nstatic int\npeek()\n{\n    theLookahead = get();\n    return theLookahead;\n}\n\n\n/* next -- get the next character, excluding comments. peek() is used to see\n        if a '/' is followed by a '/' or '*'.\n*/\n\nstatic int\nnext()\n{\n    int c = get();\n    if  (c == '/') {\n        switch (peek()) {\n        case '/':\n            for (;;) {\n                c = get();\n                if (c <= '\\n') {\n                    return c;\n                }\n            }\n        case '*':\n            get();\n            for (;;) {\n                switch (get()) {\n                case '*':\n                    if (peek() == '/') {\n                        get();\n                        return ' ';\n                    }\n                    break;\n                case EOF:\n                    fprintf(stderr, \"Error: JSMIN Unterminated comment.\\n\");\n                    exit(1);\n                }\n            }\n        default:\n            return c;\n        }\n    }\n    return c;\n}\n\n\n/* action -- do something! What you do is determined by the argument:\n        1   Output A. Copy B to A. Get the next B.\n        2   Copy B to A. Get the next B. (Delete A).\n        3   Get the next B. (Delete B).\n   action treats a string as a single character. Wow!\n   action recognizes a regular expression if it is preceded by ( or , or =.\n*/\n\nstatic void\naction(int d)\n{\n    switch (d) {\n    case 1:\n        putc(theA, stdout);\n    case 2:\n        theA = theB;\n        if (theA == '\\'' || theA == '\"') {\n            for (;;) {\n                putc(theA, stdout);\n                theA = get();\n                if (theA == theB) {\n                    break;\n                }\n                if (theA <= '\\n') {\n                    fprintf(stderr,\n\"Error: JSMIN unterminated string literal: %c\\n\", theA);\n                    exit(1);\n                }\n                if (theA == '\\\\') {\n                    putc(theA, stdout);\n                    theA = get();\n                }\n            }\n        }\n    case 3:\n        theB = next();\n        if (theB == '/' && (theA == '(' || theA == ',' || theA == '=' ||\n                theA == ':' || theA == '[' || theA == '!' || theA == '&' || \n                theA == '|')) {\n            putc(theA, stdout);\n            putc(theB, stdout);\n            for (;;) {\n                theA = get();\n                if (theA == '/') {\n                    break;\n                } else if (theA =='\\\\') {\n                    putc(theA, stdout);\n                    theA = get();\n                } else if (theA <= '\\n') {\n                    fprintf(stderr,\n\"Error: JSMIN unterminated Regular Expression literal.\\n\", theA);\n                    exit(1);\n                }\n                putc(theA, stdout);\n            }\n            theB = next();\n        }\n    }\n}\n\n\n/* jsmin -- Copy the input to the output, deleting the characters which are\n        insignificant to JavaScript. Comments will be removed. Tabs will be\n        replaced with spaces. Carriage returns will be replaced with linefeeds.\n        Most spaces and linefeeds will be removed.\n*/\n\nstatic void\njsmin()\n{\n    theA = '\\n';\n    action(3);\n    while (theA != EOF) {\n        switch (theA) {\n        case ' ':\n            if (isAlphanum(theB)) {\n                action(1);\n            } else {\n                action(2);\n            }\n            break;\n        case '\\n':\n            switch (theB) {\n            case '{':\n            case '[':\n            case '(':\n            case '+':\n            case '-':\n                action(1);\n                break;\n            case ' ':\n                action(3);\n                break;\n            default:\n                if (isAlphanum(theB)) {\n                    action(1);\n                } else {\n                    action(2);\n                }\n            }\n            break;\n        default:\n            switch (theB) {\n            case ' ':\n                if (isAlphanum(theA)) {\n                    action(1);\n                    break;\n                }\n                action(3);\n                break;\n            case '\\n':\n                switch (theA) {\n                case '}':\n                case ']':\n                case ')':\n                case '+':\n                case '-':\n                case '\"':\n                case '\\'':\n                    action(1);\n                    break;\n                default:\n                    if (isAlphanum(theA)) {\n                        action(1);\n                    } else {\n                        action(3);\n                    }\n                }\n                break;\n            default:\n                action(1);\n                break;\n            }\n        }\n    }\n}\n\n\n/* main -- Output any command line arguments as comments\n        and then minify the input.\n*/\nextern int\nmain(int argc, char* argv[])\n{\n    int i;\n    for (i = 1; i < argc; i += 1) {\n        fprintf(stdout, \"// %s\\n\", argv[i]);\n    }\n    jsmin();\n    return 0;\n}\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tools/jsmin.py",
    "content": "#!/usr/bin/python\n\n# This code is original from jsmin by Douglas Crockford, it was translated to\n# Python by Baruch Even. The original code had the following copyright and\n# license.\n#\n# /* jsmin.c\n#    2007-01-08\n#\n# Copyright (c) 2002 Douglas Crockford  (www.crockford.com)\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy of\n# this software and associated documentation files (the \"Software\"), to deal in\n# the Software without restriction, including without limitation the rights to\n# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n# of the Software, and to permit persons to whom the Software is furnished to do\n# so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in all\n# copies or substantial portions of the Software.\n#\n# The Software shall be used for Good, not Evil.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n# */\n\nfrom StringIO import StringIO\n\ndef jsmin(js):\n    ins = StringIO(js)\n    outs = StringIO()\n    JavascriptMinify().minify(ins, outs)\n    str = outs.getvalue()\n    if len(str) > 0 and str[0] == '\\n':\n        str = str[1:]\n    return str\n\ndef isAlphanum(c):\n    \"\"\"return true if the character is a letter, digit, underscore,\n           dollar sign, or non-ASCII character.\n    \"\"\"\n    return ((c >= 'a' and c <= 'z') or (c >= '0' and c <= '9') or\n            (c >= 'A' and c <= 'Z') or c == '_' or c == '$' or c == '\\\\' or (c is not None and ord(c) > 126));\n\nclass UnterminatedComment(Exception):\n    pass\n\nclass UnterminatedStringLiteral(Exception):\n    pass\n\nclass UnterminatedRegularExpression(Exception):\n    pass\n\nclass JavascriptMinify(object):\n\n    def _outA(self):\n        self.outstream.write(self.theA)\n    def _outB(self):\n        self.outstream.write(self.theB)\n\n    def _get(self):\n        \"\"\"return the next character from stdin. Watch out for lookahead. If\n           the character is a control character, translate it to a space or\n           linefeed.\n        \"\"\"\n        c = self.theLookahead\n        self.theLookahead = None\n        if c == None:\n            c = self.instream.read(1)\n        if c >= ' ' or c == '\\n':\n            return c\n        if c == '': # EOF\n            return '\\000'\n        if c == '\\r':\n            return '\\n'\n        return ' '\n\n    def _peek(self):\n        self.theLookahead = self._get()\n        return self.theLookahead\n\n    def _next(self):\n        \"\"\"get the next character, excluding comments. peek() is used to see\n           if a '/' is followed by a '/' or '*'.\n        \"\"\"\n        c = self._get()\n        if c == '/':\n            p = self._peek()\n            if p == '/':\n                c = self._get()\n                while c > '\\n':\n                    c = self._get()\n                return c\n            if p == '*':\n                c = self._get()\n                while 1:\n                    c = self._get()\n                    if c == '*':\n                        if self._peek() == '/':\n                            self._get()\n                            return ' '\n                    if c == '\\000':\n                        raise UnterminatedComment()\n\n        return c\n\n    def _action(self, action):\n        \"\"\"do something! What you do is determined by the argument:\n           1   Output A. Copy B to A. Get the next B.\n           2   Copy B to A. Get the next B. (Delete A).\n           3   Get the next B. (Delete B).\n           action treats a string as a single character. Wow!\n           action recognizes a regular expression if it is preceded by ( or , or =.\n        \"\"\"\n        if action <= 1:\n            self._outA()\n\n        if action <= 2:\n            self.theA = self.theB\n            if self.theA == \"'\" or self.theA == '\"':\n                while 1:\n                    self._outA()\n                    self.theA = self._get()\n                    if self.theA == self.theB:\n                        break\n                    if self.theA <= '\\n':\n                        raise UnterminatedStringLiteral()\n                    if self.theA == '\\\\':\n                        self._outA()\n                        self.theA = self._get()\n\n\n        if action <= 3:\n            self.theB = self._next()\n            if self.theB == '/' and (self.theA == '(' or self.theA == ',' or\n                                     self.theA == '=' or self.theA == ':' or\n                                     self.theA == '[' or self.theA == '?' or\n                                     self.theA == '!' or self.theA == '&' or\n                                     self.theA == '|'):\n                self._outA()\n                self._outB()\n                while 1:\n                    self.theA = self._get()\n                    if self.theA == '/':\n                        break\n                    elif self.theA == '\\\\':\n                        self._outA()\n                        self.theA = self._get()\n                    elif self.theA <= '\\n':\n                        raise UnterminatedRegularExpression()\n                    self._outA()\n                self.theB = self._next()\n\n\n    def _jsmin(self):\n        \"\"\"Copy the input to the output, deleting the characters which are\n           insignificant to JavaScript. Comments will be removed. Tabs will be\n           replaced with spaces. Carriage returns will be replaced with linefeeds.\n           Most spaces and linefeeds will be removed.\n        \"\"\"\n        self.theA = '\\n'\n        self._action(3)\n\n        while self.theA != '\\000':\n            if self.theA == ' ':\n                if isAlphanum(self.theB):\n                    self._action(1)\n                else:\n                    self._action(2)\n            elif self.theA == '\\n':\n                if self.theB in ['{', '[', '(', '+', '-']:\n                    self._action(1)\n                elif self.theB == ' ':\n                    self._action(3)\n                else:\n                    if isAlphanum(self.theB):\n                        self._action(1)\n                    else:\n                        self._action(2)\n            else:\n                if self.theB == ' ':\n                    if isAlphanum(self.theA):\n                        self._action(1)\n                    else:\n                        self._action(3)\n                elif self.theB == '\\n':\n                    if self.theA in ['}', ']', ')', '+', '-', '\"', '\\'']:\n                        self._action(1)\n                    else:\n                        if isAlphanum(self.theA):\n                            self._action(1)\n                        else:\n                            self._action(3)\n                else:\n                    self._action(1)\n\n    def minify(self, instream, outstream):\n        self.instream = instream\n        self.outstream = outstream\n        self.theA = None\n        self.thaB = None\n        self.theLookahead = None\n\n        self._jsmin()\n        self.instream.close()\n\nif __name__ == '__main__':\n    import sys\n    jsm = JavascriptMinify()\n    jsm.minify(sys.stdin, sys.stdout)\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tools/mergejs.py",
    "content": "#!/usr/bin/env python\n#\n# Merge multiple JavaScript source code files into one.\n#\n# Usage:\n# This script requires source files to have dependencies specified in them.\n#\n# Dependencies are specified with a comment of the form:\n#\n#     // @requires <file path>\n#\n#  e.g.\n#\n#    // @requires Geo/DataSource.js\n#\n# This script should be executed like so:\n#\n#     mergejs.py <output.js> <directory> [...]\n#\n# e.g.\n#\n#     mergejs.py openlayers.js Geo/ CrossBrowser/\n#\n#  This example will cause the script to walk the `Geo` and\n#  `CrossBrowser` directories--and subdirectories thereof--and import\n#  all `*.js` files encountered. The dependency declarations will be extracted\n#  and then the source code from imported files will be output to \n#  a file named `openlayers.js` in an order which fulfils the dependencies\n#  specified.\n#\n#\n# Note: This is a very rough initial version of this code.\n#\n# -- Copyright 2005-2013 OpenLayers contributors / OpenLayers project --\n#\n\n# TODO: Allow files to be excluded. e.g. `Crossbrowser/DebugMode.js`?\n# TODO: Report error when dependency can not be found rather than KeyError.\n\nimport re\nimport os\nimport sys\n\nSUFFIX_JAVASCRIPT = \".js\"\n\nRE_REQUIRE = \"@requires?:?\\s+(\\S*)\\s*\\n\" # TODO: Ensure in comment?\n\nclass MissingImport(Exception):\n    \"\"\"Exception raised when a listed import is not found in the lib.\"\"\"\n\nclass SourceFile:\n    \"\"\"\n    Represents a Javascript source code file.\n    \"\"\"\n\n    def __init__(self, filepath, source, cfgExclude):\n        \"\"\"\n        \"\"\"\n        self.filepath = filepath\n        self.source = source\n\n        self.excludedFiles = [] \n        self.requiredFiles = [] \n        auxReq = re.findall(RE_REQUIRE, self.source) \n        for filename in auxReq: \n            if undesired(filename, cfgExclude): \n                self.excludedFiles.append(filename) \n            else: \n                self.requiredFiles.append(filename) \n\n        self.requiredBy = []\n\n\n    def _getRequirements(self):\n        \"\"\"\n        Extracts the dependencies specified in the source code and returns\n        a list of them.\n        \"\"\"\n        return self.requiredFiles\n\n    requires = property(fget=_getRequirements, doc=\"\")\n\n\n\ndef usage(filename):\n    \"\"\"\n    Displays a usage message.\n    \"\"\"\n    print \"%s [-c <config file>] <output.js> <directory> [...]\" % filename\n\n\nclass Config:\n    \"\"\"\n    Represents a parsed configuration file.\n\n    A configuration file should be of the following form:\n\n        [first]\n        3rd/prototype.js\n        core/application.js\n        core/params.js\n        # A comment\n\n        [last]\n        core/api.js # Another comment\n\n        [exclude]\n        3rd/logger.js\n        exclude/this/dir\n\n    All headings are required.\n\n    The files listed in the `first` section will be forced to load\n    *before* all other files (in the order listed). The files in `last`\n    section will be forced to load *after* all the other files (in the\n    order listed).\n\n    The files list in the `exclude` section will not be imported.\n\n    Any text appearing after a # symbol indicates a comment.\n    \n    \"\"\"\n\n    def __init__(self, filename):\n        \"\"\"\n        Parses the content of the named file and stores the values.\n        \"\"\"\n        lines = [re.sub(\"#.*?$\", \"\", line).strip() # Assumes end-of-line character is present\n                 for line in open(filename)\n                 if line.strip() and not line.strip().startswith(\"#\")] # Skip blank lines and comments\n\n        self.forceFirst = lines[lines.index(\"[first]\") + 1:lines.index(\"[last]\")]\n\n        self.forceLast = lines[lines.index(\"[last]\") + 1:lines.index(\"[include]\")]\n        self.include =  lines[lines.index(\"[include]\") + 1:lines.index(\"[exclude]\")]\n        self.exclude =  lines[lines.index(\"[exclude]\") + 1:]\n\ndef undesired(filepath, excludes):\n    # exclude file if listed\n    exclude = filepath in excludes\n    if not exclude:\n        # check if directory is listed\n        for excludepath in excludes:\n            if not excludepath.endswith(\"/\"):\n                excludepath += \"/\"\n            if filepath.startswith(excludepath):\n                exclude = True\n                break\n    return exclude\n\n\ndef getNames (sourceDirectory, configFile = None):\n    return run(sourceDirectory, None, configFile, True)\n            \n\ndef run (sourceDirectory, outputFilename = None, configFile = None,\n                                                returnAsListOfNames = False):\n    cfg = None\n    if configFile:\n        cfg = Config(configFile)\n\n    allFiles = []\n\n    ## Find all the Javascript source files\n    for root, dirs, files in os.walk(sourceDirectory):\n        for filename in files:\n            if filename.endswith(SUFFIX_JAVASCRIPT) and not filename.startswith(\".\"):\n                filepath = os.path.join(root, filename)[len(sourceDirectory)+1:]\n                filepath = filepath.replace(\"\\\\\", \"/\")\n                if cfg and cfg.include:\n                    if filepath in cfg.include or filepath in cfg.forceFirst:\n                        allFiles.append(filepath)\n                elif (not cfg) or (not undesired(filepath, cfg.exclude)):\n                    allFiles.append(filepath)\n\n    ## Header inserted at the start of each file in the output\n    HEADER = \"/* \" + \"=\" * 70 + \"\\n    %s\\n\" + \"   \" + \"=\" * 70 + \" */\\n\\n\"\n\n    files = {}\n\n    ## Import file source code\n    ## TODO: Do import when we walk the directories above?\n    for filepath in allFiles:\n        print \"Importing: %s\" % filepath\n        fullpath = os.path.join(sourceDirectory, filepath).strip()\n        content = open(fullpath, \"U\").read() # TODO: Ensure end of line @ EOF?\n        files[filepath] = SourceFile(filepath, content, cfg.exclude) # TODO: Chop path?\n\n    print\n\n    from toposort import toposort\n\n    complete = False\n    resolution_pass = 1\n\n    while not complete:\n        complete = True\n\n        ## Resolve the dependencies\n        print \"Resolution pass %s... \" % resolution_pass\n        resolution_pass += 1 \n\n        for filepath, info in files.items():\n            for path in info.requires:\n                if not files.has_key(path):\n                    complete = False\n                    fullpath = os.path.join(sourceDirectory, path).strip()\n                    if os.path.exists(fullpath):\n                        print \"Importing: %s\" % path\n                        content = open(fullpath, \"U\").read() # TODO: Ensure end of line @ EOF?\n                        files[path] = SourceFile(path, content, cfg.exclude) # TODO: Chop path?\n                    else:\n                        raise MissingImport(\"File '%s' not found (required by '%s').\" % (path, filepath))\n        \n    # create dictionary of dependencies\n    dependencies = {}\n    for filepath, info in files.items():\n        dependencies[filepath] = info.requires\n\n    print \"Sorting...\"\n    order = toposort(dependencies) #[x for x in toposort(dependencies)]\n\n    ## Move forced first and last files to the required position\n    if cfg:\n        print \"Re-ordering files...\"\n        order = cfg.forceFirst + [item\n                     for item in order\n                     if ((item not in cfg.forceFirst) and\n                         (item not in cfg.forceLast))] + cfg.forceLast\n    \n    print\n    ## Output the files in the determined order\n    result = []\n\n    # Return as a list of filenames\n    if returnAsListOfNames:\n        for fp in order:\n            fName = os.path.normpath(os.path.join(sourceDirectory, fp)).replace(\"\\\\\",\"/\")\n            print \"Append: \", fName\n            f = files[fp]\n            for fExclude in f.excludedFiles: \n                print \"  Required file \\\"%s\\\" is excluded.\" % fExclude \n            result.append(fName)\n        print \"\\nTotal files: %d \" % len(result)\n        return result\n        \n    # Return as merged source code\n    for fp in order:\n        f = files[fp]\n        print \"Exporting: \", f.filepath\n        for fExclude in f.excludedFiles: \n            print \"  Required file \\\"%s\\\" is excluded.\" % fExclude \n        result.append(HEADER % f.filepath)\n        source = f.source\n        result.append(source)\n        if not source.endswith(\"\\n\"):\n            result.append(\"\\n\")\n\n    print \"\\nTotal files merged: %d \" % len(files)\n\n    if outputFilename:\n        print \"\\nGenerating: %s\" % (outputFilename)\n        open(outputFilename, \"w\").write(\"\".join(result))\n    return \"\".join(result)\n\nif __name__ == \"__main__\":\n    import getopt\n\n    options, args = getopt.getopt(sys.argv[1:], \"-c:\")\n    \n    try:\n        outputFilename = args[0]\n    except IndexError:\n        usage(sys.argv[0])\n        raise SystemExit\n    else:\n        sourceDirectory = args[1]\n        if not sourceDirectory:\n            usage(sys.argv[0])\n            raise SystemExit\n\n    configFile = None\n    if options and options[0][0] == \"-c\":\n        configFile = options[0][1]\n        print \"Parsing configuration file: %s\" % filename\n\n    run( sourceDirectory, outputFilename, configFile )\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tools/minimize.py",
    "content": "# Minimal Python Minimizer\n# Copyright 2008, Christopher Schmidt\n# Released under the MIT License\n#\n# Taken from: http://svn.crschmidt.net/personal/python/minimize.py\n# $Id: minimize.py 6 2008-01-03 06:33:35Z crschmidt $\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n# \n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n# \n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n# THE SOFTWARE.\n\nimport re\n\ndef strip_comments_helper(data):\n    \"\"\"remove all /* */ format comments and surrounding whitespace.\"\"\"\n    p = re.compile(r'[\\s]*/\\*.*?\\*/[\\s]*', re.DOTALL)\n    return p.sub('',data)\n\ndef minimize(data, exclude=None):\n    \"\"\"Central function call. This will call all other compression\n       functions. To add further compression algorithms, simply add\n       functions whose names end in _helper which take a string as input \n       and return a more compressed string as output.\"\"\"\n    for key, item in globals().iteritems():\n        if key.endswith(\"_helper\"):\n            func_key = key[:-7]\n            if not exclude or not func_key in exclude:   \n                data = item(data)\n    return data   \n\nif __name__ == \"__main__\":\n    import sys\n    print minimize(open(sys.argv[1]).read())\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tools/oldot.py",
    "content": "import re\nimport os    \ndef run():\n    sourceDirectory = \"../lib/OpenLayers\"    \n    allFiles = []\n    SUFFIX_JAVASCRIPT = \".js\"\n    ## Find all the Javascript source files\n    for root, dirs, files in os.walk(sourceDirectory):\n        for filename in files:\n            if filename.endswith(SUFFIX_JAVASCRIPT) and not filename.startswith(\".\"):\n                filepath = os.path.join(root, filename)[len(sourceDirectory)+1:]\n                filepath = filepath.replace(\"\\\\\", \"/\")\n                data = open(os.path.join(sourceDirectory, filepath)).read()\n                parents = re.search(\"OpenLayers.Class\\((.*?){\", data, \n                      re.DOTALL)\n                if parents:\n                    parents = [x.strip() for x in parents.group(1).strip().strip(\",\").split(\",\")]\n                else: \n                    parents = []\n                cls = \"OpenLayers.%s\" % filepath.strip(\".js\").replace(\"/\", \".\")\n                allFiles.append([cls, parents])\n    return allFiles\nprint \"\"\"\ndigraph name {\n  fontname = \"Helvetica\"\n  fontsize = 8\n  K = 0.6\n\n  node [\n    fontname = \"Helvetica\"\n    fontsize = 8\n    shape = \"plaintext\"\n  ]\n\"\"\"\n\nfor i in run():\n    print i[0].replace(\".\", \"_\")\n    for item in i[1]:\n        if not item: continue\n        print \"%s -> %s\" % (i[0].replace(\".\",\"_\"), item.replace(\".\", \"_\"))\n    print \"; \"\n\nprint \"\"\"}\"\"\"\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tools/release.sh",
    "content": "#!/bin/sh\n\n#\n#\n# Usage:\n# $ ./release.sh <release_number>\n#\n# Example:\n# $ ./release.sh 2.12-rc7\n#\n# This script should be run on the www.openlayers.org server.\n#\n# What the script does:\n#\n# 1. Download release tarball from from GitHub.\n# 2. Create builds using the Closure Compiler.\n# 3. Run the exampleparser.py script to create the examples index.\n# 4. Run csstidy for each CSS file in theme/default.\n# 5. Publish builds and resources on api.openlayers.org.\n# 6. Build the API docs.\n# 7. Create release archives\n# 8. Make the release archives available on openlayers.org/downloads.\n#\n#\n\nVERSION=$1\n\nwget -c http://closure-compiler.googlecode.com/files/compiler-latest.zip\nunzip compiler-latest.zip \n\nwget -O release-${VERSION}.tar.gz https://github.com/openlayers/openlayers/tarball/release-${VERSION}\ntar xvzf release-${VERSION}.tar.gz\nmv openlayers-openlayers-* OpenLayers-${VERSION}\ncd OpenLayers-${VERSION}/build\n\nmv ../../compiler.jar ../tools/closure-compiler.jar\n./build.py -c closure full\n./build.py -c closure mobile OpenLayers.mobile.js\n./build.py -c closure light OpenLayers.light.js\n./build.py -c none full OpenLayers.debug.js\n./build.py -c none mobile OpenLayers.mobile.debug.js\n./build.py -c none light OpenLayers.light.debug.js\nmv OpenLayers*.js ../\nrm ../tools/closure-compiler.jar\n\ncd ..\ncd tools\npython exampleparser.py\ncd ..\nfor i in google ie6-style style style.mobile; do\n    csstidy theme/default/$i.css --template=highest theme/default/$i.tidy.css\ndone    \n\nmkdir -p doc/devdocs\nmkdir -p doc/apidocs\nrm tools/*.pyc\n\nmkdir -p /osgeo/openlayers/sites/openlayers.org/api/$VERSION\ncp OpenLayers*.js /osgeo/openlayers/sites/openlayers.org/api/$VERSION\ncp -a img/ /osgeo/openlayers/sites/openlayers.org/api/$VERSION\ncp -a theme/ /osgeo/openlayers/sites/openlayers.org/api/$VERSION\n\ncd ..\n\nnaturaldocs -i OpenLayers-$VERSION/lib -o HTML OpenLayers-$VERSION/doc/devdocs -p OpenLayers-$VERSION/doc_config -s Small OL\nnaturaldocs -i OpenLayers-$VERSION/lib -o HTML OpenLayers-$VERSION/doc/apidocs -p OpenLayers-$VERSION/apidoc_config -s Small OL\n\ntar cvfz OpenLayers-$VERSION.tar.gz OpenLayers-$VERSION/\nzip -9r OpenLayers-$VERSION.zip OpenLayers-$VERSION/\n\ncp OpenLayers-$VERSION.* /osgeo/openlayers/sites/openlayers.org/download\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tools/shrinksafe.py",
    "content": "#!/usr/bin/env python\n#\n# Script to provide a wrapper around the ShrinkSafe \"web service\"\n# <http://shrinksafe.dojotoolkit.org/>\n#\n\n#\n# We use this script for two reasons:\n#\n#  * This avoids having to install and configure Java and the standalone\n#    ShrinkSafe utility.\n#\n#  * The current ShrinkSafe standalone utility was broken when we last\n#    used it.\n#\n\nimport sys\n\nimport urllib\nimport urllib2\n\nURL_SHRINK_SAFE = \"http://shrinksafe.dojotoolkit.org/shrinksafe.php\"\n\n# This would normally be dynamically generated:\nBOUNDARY_MARKER = \"---------------------------72288400411964641492083565382\"\n                   \nif __name__ == \"__main__\":\n    ## Grab the source code\n    try:\n        sourceFilename = sys.argv[1]\n    except:\n        print \"Usage: %s (<source filename>|-)\" % sys.argv[0]\n        raise SystemExit\n\n    if sourceFilename == \"-\":\n        sourceCode = sys.stdin.read()\n        sourceFilename = \"stdin.js\"\n    else:\n        sourceCode = open(sourceFilename).read()\n        \n    ## Create the request replicating posting of the form from the web page\n    request = urllib2.Request(url=URL_SHRINK_SAFE)\n    request.add_header(\"Content-Type\",\n                       \"multipart/form-data; boundary=%s\" % BOUNDARY_MARKER)\n    request.add_data(\"\"\"\n--%s\nContent-Disposition: form-data; name=\"shrinkfile[]\"; filename=\"%s\"\nContent-Type: application/x-javascript\n\n%s\n\"\"\" % (BOUNDARY_MARKER, sourceFilename, sourceCode))\n\n    ## Deliver the result\n    print urllib2.urlopen(request).read(),\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tools/toposort.py",
    "content": "\"\"\"\ntoposort.py\nSorts dictionary keys based on lists of dependencies.\n\"\"\"\n\nclass MissingDependency(Exception):\n    \"\"\"Exception raised when a listed dependency is not in the dictionary.\"\"\"\n\nclass Sorter(object):\n    def __init__(self, dependencies):\n        self.dependencies = dependencies\n        self.visited = set()\n        self.sorted = ()\n    \n    def sort(self):\n        for key in self.dependencies:\n            self._visit(key)\n        return self.sorted\n    \n    def _visit(self, key):\n        if key not in self.visited:\n            self.visited.add(key)\n            if not self.dependencies.has_key(key):\n                raise MissingDependency(key)\n            for depends in self.dependencies[key]:\n                self._visit(depends)\n            self.sorted += (key,)\n\ndef toposort(dependencies):\n    \"\"\"Returns a tuple of the dependencies dictionary keys sorted by entries\n    in the dependency lists.  Given circular dependencies, sort will impose\n    an order.  Raises MissingDependency if a key is not found.\n    \"\"\"\n    s = Sorter(dependencies)\n    return s.sort()\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tools/uglify_js.py",
    "content": "\"\"\"Utility to use the Uglify JS Compiler CLI from Python.\"\"\"\n\nimport logging\nimport subprocess\n\n\ndef check_available():\n    \"\"\" Returns whether the uglify-js tool is available. \"\"\"\n    subprocess.check_output(['which', 'uglifyjs'])\n\n\ndef compile(source_paths, flags=None):\n    \"\"\"\n    Prepares command-line call to uglify-js compiler.\n\n    Args:\n      source_paths: Source paths to build, in order.\n      flags: A list of additional flags to pass on to uglify-js.\n\n    Returns:\n      The compiled source, as a string, or None if compilation failed.\n    \"\"\"\n\n    args = ['uglifyjs']\n    args.extend(source_paths)\n    args.extend(['-c', '-m'])\n    if flags:\n        args += flags\n\n    logging.info('Compiling with the following command: %s', ' '.join(args))\n\n    try:\n        return subprocess.check_output(args)\n    except subprocess.CalledProcessError:\n        return\n"
  },
  {
    "path": "web/src/main/webapp/assets/bower_components/openlayers/tools/update_dev_dir.sh",
    "content": "#!/bin/sh\n\n# check to see if the hosted examples or API docs need an update\ncd /osgeo/openlayers/repos/openlayers\nREMOTE_HEAD=`git ls-remote https://github.com/openlayers/openlayers/ | grep HEAD | awk '{print $1}'`\nLOCAL_HEAD=`git rev-parse HEAD`\n\n# if there's something different in the remote, update and build\nif [ ! o$REMOTE_HEAD = o$LOCAL_HEAD ]; then\n    \n    git checkout master\n    git clean -f\n    git pull origin master\n    \n    # copy everything over to the dev dir within the website (keep the clone clean)\n    rsync -r --exclude=.git . /osgeo/openlayers/sites/openlayers.org/dev\n    \n    # make examples use built lib\n    cd /osgeo/openlayers/sites/openlayers.org/dev/tools\n\n    python exampleparser.py /osgeo/openlayers/repos/openlayers/examples /osgeo/openlayers/sites/openlayers.org/dev/examples\n    \n    if [ ! -f closure-compiler.jar ]; then\n        wget -c http://closure-compiler.googlecode.com/files/compiler-latest.zip\n        unzip compiler-latest.zip \n        mv compiler.jar closure-compiler.jar\n    fi\n\n    cd /osgeo/openlayers/sites/openlayers.org/dev/build\n    ./build.py -c closure tests.cfg\n    ./build.py -c closure mobile.cfg OpenLayers.mobile.js\n    ./build.py -c closure light.cfg OpenLayers.light.js\n    ./build.py -c none tests.cfg OpenLayers.debug.js\n    ./build.py -c none mobile.cfg OpenLayers.mobile.debug.js\n    ./build.py -c none light.cfg OpenLayers.light.debug.js\n    cp OpenLayers*.js ..\n\n    cd /osgeo/openlayers/sites/openlayers.org/dev\n    sed -i -e 's!../lib/OpenLayers.js?mobile!../OpenLayers.mobile.js!' examples/*.html\n    sed -i -e 's!../lib/OpenLayers.js!../OpenLayers.js!' examples/*.html\n\n    # update the API docs\n    if [ ! -d /osgeo/openlayers/sites/dev.openlayers.org/apidocs ]; then\n        mkdir -p /osgeo/openlayers/sites/dev.openlayers.org/apidocs\n    fi\n    if [ ! -d /osgeo/openlayers/sites/dev.openlayers.org/docs ]; then\n        mkdir -p /osgeo/openlayers/sites/dev.openlayers.org/docs\n    fi\n    naturaldocs --input lib --output HTML /osgeo/openlayers/sites/dev.openlayers.org/apidocs -p apidoc_config -s Default OL\n    naturaldocs --input lib --output HTML /osgeo/openlayers/sites/dev.openlayers.org/docs -p doc_config -s Default OL\n\nfi\n\n# check to see if the website needs an update\ncd /osgeo/openlayers/repos/website\nREMOTE_HEAD=`git ls-remote https://github.com/openlayers/website/ | grep HEAD | awk '{print $1}'`\nLOCAL_HEAD=`git rev-parse HEAD`\n\n# if there's something different in the remote, update the clone\nif [ ! o$REMOTE_HEAD = o$LOCAL_HEAD ]; then\n    \n    git checkout master\n    git clean -f\n    git pull origin master\n    \n    # copy everything over to the website dir (keep the clone clean)\n    # can't use --delete here because of nested dev dir from above\n    rsync -r --exclude=.git . /osgeo/openlayers/sites/openlayers.org\n    \nfi\n\n# check to see if prose docs need an update\ncd /osgeo/openlayers/repos/docs\nREMOTE_HEAD=`git ls-remote https://github.com/openlayers/docs/ | grep HEAD | awk '{print $1}'`\nLOCAL_HEAD=`git rev-parse HEAD`\n\n# if there's something different in the remote, update the clone\nif [ ! o$REMOTE_HEAD = o$LOCAL_HEAD ]; then\n    \n    git checkout master\n    git clean -f\n    git pull origin master\n\n    mkdir -p /osgeo/openlayers/sites/docs.openlayers.org /tmp/ol/docs/build/doctrees\n    sphinx-build -b html -d /tmp/ol/docs/build/doctrees . /osgeo/openlayers/sites/docs.openlayers.org\n    \nfi\n\n## UPDATES FROM THE OLD SVN REPO\n\n# Get current 'Last Changed Rev'\nSVNREV=`svn info http://svn.openlayers.org/ | grep 'Revision' | awk '{print $2}'`\n\n# Get the last svn rev\ntouch /tmp/ol_svn_rev\nOLD_SVNREV=\"o`cat /tmp/ol_svn_rev`\"\n\n# If they're not equal, do some work.\nif [ ! o$SVNREV = $OLD_SVNREV ]; then\n    svn up /osgeo/openlayers/repos/old_svn_repo/\n    # Record the revision\n    echo -n $SVNREV > /tmp/ol_svn_rev\nfi\n"
  },
  {
    "path": "web/src/main/webapp/assets/css/ie-only.css",
    "content": ".navbar-brand {\n\twidth: 150px;\n}\n\nselect,\ntextarea,\ninput[type=\"text\"],\ninput[type=\"password\"],\ninput[type=\"datetime\"],\ninput[type=\"datetime-local\"],\ninput[type=\"date\"],\ninput[type=\"month\"],\ninput[type=\"time\"],\ninput[type=\"week\"],\ninput[type=\"number\"],\ninput[type=\"email\"],\ninput[type=\"url\"],\ninput[type=\"search\"],\ninput[type=\"tel\"],\ninput[type=\"color\"] {\n\tmin-height: inherit;\n}"
  },
  {
    "path": "web/src/main/webapp/assets/css/tatami.css",
    "content": ".indent {\n    padding-left: 50px;\n}\n\n#logout, #help-tour {\n    cursor: pointer;\n}\n\n.status-top-rounded {\n    border-radius: 5px 5px 0 0;\n}\n\n.status-bottom-rounded {\n    border-radius: 0 0 5px 5px;\n}\n\n.status-both-rounded {\n    border-radius: 5px 5px 5px 5px;\n}\n\n@media screen and (max-width: 767px) {\n    .navbar .nav, .navbar .navbar-form {\n        float: none;\n    }\n\n    .nav > li > .dropdown-menu {\n        position: static;\n        float: none;\n    }\n\n    .nav li.dropdown-submenu > ul.dropdown-menu {\n        position: initial;\n        z-index: 0;\n        float: none;\n        margin: 0;\n    }\n\n    #tatamiBody {\n        padding: 0;\n    }\n}\n\n.noRadius {\n    border-radius: 0;\n}\n\n.noCollapse {\n    border-collapse: separate;\n}\n\n.noBorder {\n    border-top: 0;\n}\n\n.noRadius {\n    border-radius: 0;\n}\n\n#basicMap {\n    width: 100%;\n    height: 100%;\n    margin: 0;\n}\n\n#geolocMapPreview {\n    width: 100%;\n    height: 100%;\n    margin: 0;\n}\n\n.alertColor {\n    padding: 8px 15px 8px 14px;\n    margin-bottom: 20px;\n    color: #c09853;\n    background-color: #fcf8e3;\n    border: 1px solid #fbeed5;\n    border-radius: 4px;\n}\n\n@media screen and (min-width: 767px) {\n    #tatamiBody {\n        padding: 10px 15px 10px 0;\n    }\n}\n\nbody {\n    background-image: url(/assets/img/wallpaper.jpg);\n}\n\nh4 {\n    font-size: inherit;\n}\n\n.well {\n    box-shadow: none;\n    border-radius: 5px;\n}\n\n.well h4 {\n    margin: 0;\n}\n\n.labelSizeNormal {\n    font-size: 100%;\n}\n\n.tabMenu {\n    margin-bottom: 15px;\n    margin-top: 10px;\n}\n\n.navbar {\n    background-color: black;\n}\n\n.control-group {\n    padding-bottom: 10px;\n}\n\n.quota {\n    color: #333333;\n    font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n    font-size: 14px;\n}\n\n.nomargin {\n    margin: 0;\n}\n\n.file-table {\n    display: block;\n}\n\n.displayBlock {\n    display: block;\n}\n\n.fileItem {\n    width: 100%;\n    display: inline-table;\n    border-top: 1px solid #dddddd;\n    padding: 8px;\n}\n\ndiv.jGrowl-notification {\n    background-color : transparent;\n    opacity : 1;\n}\n\n.little-marge-right {\n    margin-right: 20px\n}\n\n.mediumHeight {\n    height: 13px;\n}\n\n.smallPaddingLeft {\n    padding-left: 10px;\n}\n\n.little-height {\n    height: 10px;\n}\n\n.littleMargeBot {\n    margin-bottom: 10px;\n}\n\n.little-padding-top,\n.little-padding-bottom {\n    padding-top: 3px;\n}\n\n.little-marge-top {\n    margin-top: 5px;\n}\n\n.little-padding {\n    padding: 0.10em 0.6em;\n}\n\n#updateAvatar {\n    position: relative;\n    cursor: hand;\n    cursor: pointer;\n}\n\n#updateAvatar input[type=file] {\n    opacity: 0;\n    position: absolute;\n    top: 0;\n    left: 0;\n    height: 210px;\n    width: 550px;\n\n}\n\n.avatar-float-left-container {\n    margin-left: 15px;\n    margin-top: 15px;\n    margin-bottom: 0;\n    margin-right: 15px;\n}\n\n.navbar .nav > li > a {\n    color: #CCCCCC;\n}\n\n.navbar .nav > li > a:focus {\n    color: #CCCCCC;\n}\n\n.navbar .nav > li > a:hover {\n    color: white;\n}\n\n.navbar .nav li.dropdown > .dropdown-toggle .caret {\n    border-top-color: #CCCCCC; \n    border-bottom-color: #CCCCCC; \n}\n\n.navbar .nav li.dropdown > .dropdown-toggle .caret:hover {\n    border-top-color: white; \n    border-bottom-color: white;\n}\n\n.navbar .nav li.dropdown.open > .dropdown-toggle {\n    color: white;\n    background-color: inherit;\n}\n\n.img {\n    width: 50px;\n    height: 50px;\n    display: inline-block;\n}\n\n.img-small {\n    width: 30px;\n    height: 30px;\n    background-position: center center;\n    background-size: cover;\n    -ms-behavior: url(/assets/vendor/backgroundsize.min.htc);\n}\n\n.img-reply {\n    width: 35px;\n    height: 35px;\n    margin-left: 10px;\n    background-position: center center;\n    background-size: cover;\n    -ms-behavior: url(/assets/vendor/backgroundsize.min.htc);\n}\n\n.img-medium {\n    width: 50px;\n    height: 50px;\n    background-position: center center;\n    background-size: cover;\n    -ms-behavior: url(/assets/vendor/backgroundsize.min.htc);\n}\n\n.img-medium-big {\n    width: 150px;\n    height: 150px;\n    background-position: center center;\n    background-size: cover;\n    -ms-behavior: url(/assets/vendor/backgroundsize.min.htc);\n}\n\n.img-big {\n    width: 200px;\n    height: 200px;\n    background-position: center center;\n    background-size: cover;\n    -ms-behavior: url(/assets/vendor/backgroundsize.min.htc);\n}\n\n.navbar-edit {\n    line-height: 14px;\n    left: 10px;\n    width: 48px;\n    padding: 4px 13px 3px;\n    background-color: #428bca;\n}\n\n.navbar-edit:hover,\n.navbar-edit:focus {\n    background-color: #ddd;\n}\n\n.page-header {\n    margin-top: 0;\n    margin-bottom: 0;\n    padding-bottom: 0;\n}\n\n.img-rounded {\n    /*border-radius: 15px;*/\n}\n\n.navbar .btn-navbar.fix-navbar {\n    height: 14px;\n    padding-top: 6px;\n    line-height: 14px;\n    font-size: 12px;\n}\n\n.tatam *, .trends *, .profile *, .preview-tatam *, .profile-card, .wrap * {\n    /* white-space: normal; */\n    word-wrap: break-word;\n}\n\n.status-actions {\n    margin-left: -60px;\n}\n\n.status-action {\n    padding: 0;\n    margin: 0;\n}\n\n.status-action:hover {\n    text-decoration: none;\n}\n\n.profile-card > .img {\n    margin-right: 5px;\n}\n\n/*.tatam, .useritem {*/\n.useritem {\n    padding: 0 5px 0 0;\n    overflow: hidden;\n    display: none;\n    border: 1px solid #CCCCCC;\n    background-color: white;\n    margin-bottom: -1px;\n}\n\n.desactivated {\n    /* Fallback for web browsers that don't support RGBa */\n    background-color: rgb(255,64,64);\n    /* RGBa with 0.6 opacity */\n    background-color: rgba(241, 241, 241, 0.65) !important;\n}\n\n.useritemmini {\n    padding: 0 5px 1px 35px;\n    overflow: hidden;\n    display: none;\n}\n\n.user-profile {\n    margin:0px;\n    color:#252525;\n}\n\n.useritemmini h6 {\n    margin-top: 5px;\n    margin-bottom: 5px;\n    line-height: 12px\n}\n\n.useritem, .useritemmini {\n    display: block;\n    padding: 5px;\n}\n\n.mention-share {\n    font-size: 80%;\n    color: #888888;\n}\n\n.tatam.favorite {\n    background-image: url(/assets/css/img/favorite.png);\n    background-repeat: no-repeat;\n    background-position: right top;\n}\n\n.favorite {\n    background-image: url(/assets/css/img/favorite.png);\n    background-repeat: no-repeat;\n    background-position: right top;\n}\n\n.tatam.share {\n    background-image: url(/assets/css/img/shared.png);\n    background-repeat: no-repeat;\n    background-position: right top;\n}\n\n.share {\n    background-image: url(/assets/css/img/shared.png);\n    background-repeat: no-repeat;\n    background-position: right top;\n}\n\n.tatam.both {\n    background-image: url(/assets/css/img/both.png);\n    background-repeat: no-repeat;\n    background-position: right top;\n}\n\n.both {\n    background-image: url(/assets/css/img/both.png);\n    background-repeat: no-repeat;\n    background-position: right top;\n}\n\n.pointer {\n    cursor: pointer;\n}\n\n.tatam > div:first-child, .useritem > div:first-child {\n    /*margin-left: -60px;*/\n    padding: 5px;\n}\n\n.useritemmini > div:first-child {\n    margin-left: -35px;\n    padding: 5px;\n}\n\n.tatam > header {\n    padding-bottom: 0;\n    margin-bottom: 0;\n}\n\n.tatams {\n    /*margin-bottom: 5px;*/\n}\n\n.tatam > div:first-child, .useritem > div:first-child {\n    padding: 5px 10px 0 10px;\n}\n\n.tatams > * {\n    margin-bottom: 0;\n    padding-bottom: 0;\n}\n\n@media screen and (min-width: 767px) {\n    .tatam-hover:hover{\n        background-color: #ECF1F7;\n    }\n}\n\n.tatams > *:last-child {\n    margin-bottom: 0;\n}\n\n.tatams-share {\n    padding-top: 5px;\n    /*border-top: 2px solid #bcbcbc;*/\n}\n\n.tatams-share-title {\n    border-right: 2px solid #bcbcbc;\n    padding-right: 5px;\n    margin: 5px;\n}\n\n.tatams-share-img {\n    margin-top: 5px;\n}\n\n/*\n.tatams-discussion {\n    margin-top: 0;\n    margin-left: -60px;\n}\n*/\n\n.tatams-discussion > .tatam > header {\n    margin-top: 0;\n    margin-bottom: 0;\n}\n\n.edit-tatam-float-right {\n    position: absolute;\n    right: 0;\n    margin-right: 40px;\n    padding: 2px;\n}\n\n.refresh-button {\n\n}\n\n.refresh-button-style {\n    border-top: 1px solid #CCCCCC;\n    border-left: 1px solid #CCCCCC;\n    border-right: 1px solid #CCCCCC;\n    border-bottom: 1px solid #CCCCCC;\n    margin-bottom: -1px;\n    padding: 10px;    \n    box-shadow: inset 0 3px 8px rgba(0,0,0,.05);\n}\n\n.dropzone {\n    line-height: 50px;\n    text-align: center;\n    font-weight: bold;\n    border-style: dashed;\n    border-width: 2px;\n    border-color: #808080;\n}\n\n.dropzone.in {\n    border-style: dashed;\n    border-width: 2px;\n    border-color: #0088cc;\n}\n\n/* Style for degradated fileUpload on IE8 */\n.controlsIE {\n    text-align: left;\n    vertical-align: middle;\n    margin-bottom: 20px;\n}\n\n.controlsIE p {\n    font-size: 1.1em;\n}\n\n.controlsIE span.glyphicon, span.upload-ko, span.upload-ok {\n    padding-left: 15px;\n    margin-top: 10px;\n}\n\n.controlsIE span.upload-ko, .controlsIE span.upload-ok, span.hidden-label {\n    display: none;\n}\n\n.tatam {\n    background-color: white;\n    border-top: 1px solid #CCCCCC;\n    border-bottom: 1px solid #CCCCCC;\n    padding: 0;\n    margin-bottom: -1px;\n    overflow: hidden;\n    display: none;\n}\n\n.tatam-border-lr {\n    border-right: 1px solid #CCCCCC;\n    border-left: 1px solid #CCCCCC;\n    margin-bottom: 5px;\n}\n\n.tatam-first {\n    border-top: 0;\n}\n\n.tatam-last {\n    border-bottom: 0;\n}\n\n@media screen and (min-width: 767px) {\n    .tatams-margin {\n        margin-top: 10px;\n    }\n}\n\n@media screen and (max-width: 767px) {\n    .tatams-margin {\n        margin-top: -1px;\n    }\n}\n\n.tatam blockquote p {\n    font-size: 0.8em;\n}\n\n.tatams-content-title {\n    border-top: 1px solid #CCCCCC;\n    border-left: 1px solid #CCCCCC;\n    border-right: 1px solid #CCCCCC;\n    background-color: white;\n    margin-bottom: 0;\n    border-radius: 5px 5px 0 0;\n}\n\n.tatams-content h3 {\n    padding: 5px 10px 5px 10px;\n    margin: 0;\n    font-weight: normal;\n    font-size: 1.4em;\n}\n\n.btn-title {\n    margin-top: 2px;\n    margin-left: 5px;\n}\n\n.tatams-content hr {\n    padding: 0;\n    margin: 0;\n    border-top: 1px solid #CCCCCC;\n    margin-bottom: -2px;\n    margin-top: 0;\n}\n\n.tatams-container {\n    min-height: 75px;\n    background-image: url(/assets/img/wallpaper.jpg);\n}\n\n.tatam-expand-container {\n    border-top: 1px solid #CCCCCC;\n    border-bottom: 1px solid #CCCCCC;\n    border-radius: 5px;\n}\n\n.tatam-background {\n    background-color: #ECF1F7;\n}\n\n.homebody-nav {\n    background-color: white;\n}\n\n.nav-justified {\n    border-collapse: collapse;\n}\n\n.nav-justified > li {\n    border: 1px solid #CCCCCC;\n    padding: 0;\n}\n\n.nav-tabs > li > a {\n    border-radius: 0;\n}\n\n.homebody-nav {\n    background-color: white;\n}\n\n.homebody-nav .active a {\n    color: #333333;\n}\n\n.nav-tabs.nav-justified > .active > a {\n    border-bottom-color: #CCCCCC;\n}\n\n/**\n* Search Engine\n**/\n\n.typeahead.dropdown-menu.hasCategory {\n    /*width: 280px;*/\n    background: #EDEDED;\n    padding: 0;\n}\n\n@media screen and (max-width: 767px) {\n    .typeahead.dropdown-menu.hasCategory {\n        position: static;\n        width: 100%;\n    }\n}\n\n@media (min-width: 979px) {\n    .typeahead.dropdown-menu.hasCategory {\n        margin-left: -53px;\n    }\n\n    #searchHeader {\n        width: 320px;\n    }\n}\n\n.hasCategory .item {\n    height: 100%;\n    margin-left: 40px;\n    background: #FFFFFF;\n    cursor: pointer;\n}\n\n.hasCategory .category {\n    cursor: default;\n    height: auto;\n    background: #EDEDED;\n    padding: 6px 5px 5px 13px;\n    width:30px;\n}\n\n.hasCategory li.first {\n    margin-top:-31px;\n}\n\n.hasCategory li.first, .hasCategory .category {\n    /*border-top: 1px solid #CCCCCC;*/\n}\n\n.hasCategory li.item.active a {\n    height: 24px;\n    padding:0;\n}\n\n.hasCategory li:first-child {\n    border-top: none;\n}\n\n.hasCategory li.item img {\n    display: block;\n    float: left;\n    margin: 2px 8px 0 3px;\n    border-radius: 3px;\n    -moz-border-radius: 3px;\n    -webkit-border-radius: 3px;\n}\n\n.hasCategory li.item h4 {\n    font-size: 12px;\n    margin: 0 1px 0 0;\n}\n\n.hasCategory li.item h4 a {\n    color:#000;\n    padding:0;\n}\n\n.hasCategory li.item p {\n    font-size: 11px;\n    margin: 0;\n    overflow: hidden;\n    height: auto;\n    line-height: 11px;\n}\n\n.hasCategory li.item.users, .hasCategory li.item.groups {\n    padding: 3px 0 4px 5px;\n}\n\n.hasCategory li.item.active,\n.hasCategory li.item:hover {\n    color: #ffffff;\n    text-decoration: none;\n    background-color: #0081c2;\n    background-image: -moz-linear-gradient(top, #0088cc, #0077b3);\n    background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));\n    background-image: -webkit-linear-gradient(top, #0088cc, #0077b3);\n    background-image: -o-linear-gradient(top, #0088cc, #0077b3);\n    background-image: linear-gradient(to bottom, #0088cc, #0077b3);\n    background-repeat: repeat-x;\n    outline: 0;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);\n}\n\n.hasCategory li.item a:hover {\n    text-decoration: none;\n}\n\n.hasCategory li.tags a {\n    padding: 3px 10px;\n}\n\n.hasCategory li.groups p {\n    margin-left: 10px;\n    margin-top: -2px;\n}\n\n.box-info {\n    background: none;\n    border: none;\n    box-shadow: none;\n}\n\n.nav-collapse .dropdown-menu .divider {\n    display: block;\n    height: 0;\n    border-bottom: 1px solid #CCCCCC;\n    -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n    -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n\n.background-image-fffix {\n    overflow: auto;\n}\n\n.share-img-fffix{\n    display: inline-block;\n}\n\n.background-image-fffix img {\n    display: block;\n}\n\n.searchbody h3 {\n    padding: 0;\n    margin: 0;\n    font-weight: normal;\n    font-size: 1.4em;\n}\n\n.searchbody hr {\n    padding: 0;\n    margin: 0;\n    border-top: 1px solid #CCCCCC;\n    margin-top: 10px;\n}\n\n.deleteicon {\n    position: absolute;\n    display: block;\n    top: 9px;\n    right: 22px;\n    cursor: pointer;\n}\n\n.statusitem-name {\n    padding: 0;\n    margin: 0;\n    /*margin-top: -4px;*/\n    /*margin-bottom: 7px;*/\n}\n\n.statusitem-content {\n    margin-bottom: 5px;\n}\n\n.statusitem-footer {\n    padding: 0;   \n}\n\n.markdown p {\n    margin: 0 0 0.5em 0;\n}\n\n#current {\n    padding: 10px;\n    padding-top : 7px;\n}\n\n#before {\n    padding: 0;\n    margin: 0;\n}\n\n#after {\n\n}\n\n.status-content-container {\n    margin-left: 65px;\n    margin-right: 30px;\n}\n\n.statusitem-img {\n    margin-bottom: 5px;\n}\n\n.attachments {\n    margin-top: 5px;\n}\n\n@media screen and (min-width: 767px) {\n    .buttons {\n        clear: both;\n        margin-left: 60px;\n    }\n}\n\n@media screen and (max-width: 767px) {\n    .buttons {\n        clear: both;\n    }\n\n    .statusitem-footer {\n        background-color: #ECF1F7;\n        border-top: 1px solid #CCCCCC;\n        padding-left: 8px;\n    }\n\n    .button-ios {\n        margin-left: -2px;\n        margin-right: -2px;\n        margin: 2px 4px 2px 0; \n    }\n\n    .button-ios-right {\n        border-right: 1px solid #CCCCCC;\n    }\n\n}\n\n.image-preview-template {\n    margin-top: 5px;\n    margin-bottom: 5px;\n}\n\n.image-preview-container {\n    display: table;\n    margin: 0 auto;\n    max-width: 500px;\n}\n\n.image-preview-element {\n    margin-left: 5px;\n    margin-bottom: 5px;\n    float: left;\n}\n\n.image-preview-element img {\n    max-width: 245px;\n    max-height: 195px;\n}\n\n.image-preview-element-1 {\n    margin-left: 5px;\n    margin-bottom: 5px;\n}\n\n.image-preview-element-1 img {\n    max-width: 500px;\n    max-height: 400px;\n}\n\n@media screen and (min-width: 767px) {\n    .slider-container {\n        display: table;\n        margin: 0 auto;\n        margin-top: 20px;\n        background-color: black;\n        position: relative;\n        width: 900px;\n        height: 550px;\n    }\n\n    .slider-container .slider-container-img {\n        background-color: black;\n        text-align: center;   \n        width: 900px;\n        line-height: 550px;\n        height: 550px;\n    }\n\n    .slider-container .slider-container-img img {\n        vertical-align: middle;\n        max-width: 900px;\n        max-height: 550px;\n    }\n}\n\n@media screen and (max-width: 767px) {\n    .slider-container {\n        display: table;\n        margin: 0 auto;\n        margin-top: 20px;\n        background-color: black;\n        position: relative;\n        width: 500px;\n        height: 550px;\n    }\n\n    .slider-container .slider-container-img {\n        background-color: black;\n        text-align: center;   \n        width: 500px;\n        line-height: 550px;\n        height: 550px;\n    }\n\n    .slider-container .slider-container-img img {\n        vertical-align: middle;\n        max-width: 500px;\n        max-height: 550px;\n    }\n}\n\n.slider-container .slider-container-header {\n    height: 0;\n    text-align: right;\n    margin-right: 5px;\n}\n\n.slider-container .slider-container-left {\n\n}\n\n.slider-container .slider-container-right {\n\n}\n\n.slider-container .slider-button {\n    color: white;\n    text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;\n    padding: 0;\n    cursor: pointer;\n    background: transparent;\n    opacity: 0.6;\n    border: 0;\n    font-size: 2em;\n    font-weight: bold;\n}\n\n.slider-container .slider-button-close {\n\n}\n\n.slider-container .slider-button-left {\n    position: absolute;\n    left: 10px;\n    bottom: 50%;\n}\n\n.slider-container .slider-button-right {\n    position: absolute;\n    right: 10px;\n    bottom: 50%;\n}"
  },
  {
    "path": "web/src/main/webapp/assets/vendor/backgroundsize.min.htc",
    "content": "<!-- background-size-polyfill v0.2.0 | (c) 2012-2013 Louis-Rémi Babé | MIT License -->\n<PUBLIC:COMPONENT lightWeight=\"true\">\n<PUBLIC:ATTACH EVENT=\"oncontentready\" ONEVENT=\"o.init()\" />\n<PUBLIC:ATTACH EVENT=\"ondocumentready\" ONEVENT=\"o.init()\" />\n<PUBLIC:ATTACH EVENT=\"onpropertychange\" ONEVENT=\"o.handlePropertychange()\" />\n<PUBLIC:ATTACH EVENT=\"ondetach\" ONEVENT=\"o.restore()\" />\n<PUBLIC:ATTACH EVENT=\"onresize\" FOR=\"window\" ONEVENT=\"o.handleResize()\" />\n<PUBLIC:EVENT NAME=\"onbackgroundupdate\" ID=\"updateEvent\" />\n<script type=\"text/javascript\">\nvar o;!function(a,b){var c=/url\\([\"']?(.*?)[\"']?\\)/,d=/^\\s\\s*/,e=/\\s\\s*$/,f=/\\s\\s*/g,g=/%$/,h={top:0,left:0,bottom:1,right:1,center:.5},i=a.document,j=\"data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\",k=\"background-size-polyfill\",l=function(){},m=100,n,p,q,r;function s(){var b=i.createElement(\"div\"),c=i.createElement(\"img\"),d=b.style,e=a.style,f=a.currentStyle,g=a.bgsExpando,h=a.firstChild;g&&(g.restore&&(e.backgroundImage=g.restore.backgroundImage,e.position=g.restore.position,e.zIndex=g.restore.zIndex),h&&\"DIV\"===(h.nodeName||\"\").toUpperCase()&&h.className===k&&a.removeChild(h)),t(b),b.className=k,d.top=d.right=d.bottom=d.left=0,d.position=\"fixed\",t(c),c.alt=\"\",b.appendChild(c),a.insertBefore(b,a.firstChild),a.bgsExpando=g={wrapper:b,img:c,restore:{backgroundImage:e.backgroundImage,position:e.position,zIndex:e.zIndex},current:{},next:null,processing:!1,loadImg:null,display:!1,changed:!1,ignore:!1,canFixed:\"BODY\"===a.nodeName.toUpperCase()&&b.offsetHeight>0},d.position=\"absolute\",\"auto\"===f.zIndex&&(e.zIndex=0),\"static\"===f.position&&(e.position=\"relative\"),o={init:l,handlePropertychange:D,restore:F,handleResize:E},D()}function t(a){var b=a.style;b.position=\"absolute\",b.display=\"block\",b.zIndex=-1,b.overflow=\"hidden\",b.visibility=\"inherit\",b.width=b.height=b.top=b.right=b.bottom=b.left=b.cursor=\"auto\",b.margin=b.padding=b.border=b.outline=b.minWidth=b.minHeight=0,b.background=b.maxWidth=b.maxHeight=\"none\",b.fontSize=b.lineHeight=\"1em\"}function u(a,c,d){var e;c?(e=i.createElement(\"img\"),e.onload=e.onerror=function(){var c=this.width,e=this.height;\"error\"===b.event.type&&(c=e=0),a.loadImg=this.onload=this.onerror=null,d(c,e)},e.src=c):e={callbackId:b.setTimeout(function(){a.loadImg=null,d(0,0)},0)},a.loadImg=e,e=null}function v(a){var b=o.handlePropertychange;o.handlePropertychange=l,a(),o.handlePropertychange=b}function w(a,b){var c=a.currentStyle.display;return c!==b.display&&(b.display=c,b.changed=!0),\"none\"!==c}function x(a,b){var d=a.style,e=a.currentStyle,f=b.restore,i=y(e[\"background-size\"]),k=i.split(\" \"),l={innerWidth:a.offsetWidth-(parseFloat(e.borderLeftWidth)||0)-(parseFloat(e.borderRightWidth)||0),innerHeight:a.offsetHeight-(parseFloat(e.borderTopWidth)||0)-(parseFloat(e.borderBottomWidth)||0),size:i,sizeIsKeyword:\"contain\"===i||\"cover\"===i,sizeX:k[0],sizeY:k.length>1?k[1]:\"auto\",posX:e.backgroundPositionX,posY:e.backgroundPositionY,attachment:e.backgroundAttachment,src:\"\",imgWidth:0,imgHeight:0};return l.sizeIsKeyword||((parseFloat(l.sizeX)>=0||\"auto\"===l.sizeX)&&(parseFloat(l.sizeY)>=0||\"auto\"===l.sizeY)||(l.sizeX=l.sizeY=\"auto\"),g.test(l.sizeX)&&(l.sizeX=(l.innerWidth*parseFloat(l.sizeX)/100||0)+\"px\"),g.test(l.sizeY)&&(l.sizeY=(l.innerHeight*parseFloat(l.sizeY)/100||0)+\"px\")),(l.posX in h||g.test(l.posX))&&(l.posX=h[l.posX]||parseFloat(l.posX)/100||0),(l.posY in h||g.test(l.posY))&&(l.posY=h[l.posY]||parseFloat(l.posY)/100||0),(c.exec(d.backgroundImage)||[])[1]===j?v(function(){d.backgroundImage=f.backgroundImage}):f.backgroundImage=d.backgroundImage,l.src=(c.exec(e.backgroundImage)||[])[1],v(function(){d.backgroundImage=\"url(\"+j+\")\"}),l}function y(a){return String(a).replace(d,\"\").replace(e,\"\").replace(f,\" \")}function z(a,c){var d=c.next;function e(){p=b.setTimeout(function(){c.processing=!1,z(a,c)},0)}!c.processing&&d&&(c.next=null,c.processing=!0,u(c,d.src,function(b,f){d.imgWidth=b,d.imgHeight=f,A(c,d)?B(a,c,d,e):e()}))}function A(a,b){var c=a.current,d=!1,e;if(a.changed)a.changed=!1,d=!0;else for(e in b)if(b[e]!==c[e]){d=!0;break}return d}function B(a,c,d,e){var f=c.img,g=f.style,h=d.size,i=d.innerWidth,j=d.innerHeight,k=d.imgWidth,l=d.imgHeight,m=d.posX,n=d.posY,o=\"number\"==typeof m,p=\"number\"==typeof n,s=\"none\",t=0,u=0,v=\"auto\",w=\"auto\",x=\"px\",y=\"100%\",z,A;i&&j&&k&&l&&(c.wrapper.style.position=\"fixed\"===d.attachment&&c.canFixed?\"fixed\":\"absolute\",f.src=d.src,d.sizeIsKeyword?(z=i/j,A=k/l,\"contain\"===h&&A>z||\"cover\"===h&&z>A?(u=C((j-i/A)*n)+x,v=y):(t=C((i-j*A)*m)+x,w=y),g.left=o?t:m,g.top=p?u:n,g.width=v,g.height=w,s=\"block\"):(g.display=\"block\",g.width=d.sizeX,g.height=d.sizeY,k=f.width,l=f.height,k&&l&&(g.left=o?C((i-k)*m)+x:m,g.top=p?C((j-l)*n)+x:n,s=\"block\"))),g.display=s,c.current=d,q=b.setTimeout(function(){r=b.setTimeout(e,0),updateEvent.fire()},0)}function C(a){var b=0>a;return a=Math.floor(Math.abs(a)),b?-a:a}function D(){var c=a.bgsExpando,d=(b.event||{}).propertyName,e=\"style.backgroundImage\";c.ignore&&(c.ignore=!1,d===e)||(d===e&&a.style.backgroundImage&&(c.ignore=!0),w(a,c)&&(c.next=x(a,c),z(a,c)))}function E(){b.clearTimeout(n),n=b.setTimeout(D,m)}function F(){var c=a.bgsExpando,d,e,f;o={init:l,handlePropertychange:l,restore:l,handleResize:l},b.clearTimeout(n),b.clearTimeout(p),b.clearTimeout(q),b.clearTimeout(r);try{c&&(d=c.loadImg,d&&(d.onload=d.onerror=null,b.clearTimeout(d.callbackId)),e=a.style,f=c.restore,e&&(e.backgroundImage=f.backgroundImage,e.position=f.position,e.zIndex=f.zIndex),a.removeChild(c.wrapper)),a.bgsExpando=null}catch(g){}a=b=i=l=null}o={init:\"print\"!==i.media?s:l,handlePropertychange:l,restore:l,handleResize:l},\"complete\"===a.readyState&&o.init()}(element,window);</script>\n<script type=\"text/vbscript\"></script>\n</PUBLIC:COMPONENT>\n"
  },
  {
    "path": "web/src/main/webapp/assets/vendor/css/bootstrap/css/bootstrap.css",
    "content": "/*!\n * Bootstrap v3.0.0\n *\n * Copyright 2013 Twitter, Inc\n * Licensed under the Apache License v2.0\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Designed and built with all the love in the world by @mdo and @fat.\n */\n\n/*! normalize.css v2.1.0 | MIT License | git.io/normalize */\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nnav,\nsection,\nsummary {\n  display: block;\n}\n\naudio,\ncanvas,\nvideo {\n  display: inline-block;\n}\n\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n\n[hidden] {\n  display: none;\n}\n\nhtml {\n  font-family: sans-serif;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\n\nbody {\n  margin: 0;\n}\n\na:focus {\n  outline: thin dotted;\n}\n\na:active,\na:hover {\n  outline: 0;\n}\n\nh1 {\n  margin: 0.67em 0;\n  font-size: 2em;\n}\n\nabbr[title] {\n  border-bottom: 1px dotted;\n}\n\nb,\nstrong {\n  font-weight: bold;\n}\n\ndfn {\n  font-style: italic;\n}\n\nhr {\n  height: 0;\n  -moz-box-sizing: content-box;\n       box-sizing: content-box;\n}\n\nmark {\n  color: #000;\n  background: #ff0;\n}\n\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, serif;\n  font-size: 1em;\n}\n\npre {\n  white-space: pre-wrap;\n}\n\nq {\n  quotes: \"\\201C\" \"\\201D\" \"\\2018\" \"\\2019\";\n}\n\nsmall {\n  font-size: 80%;\n}\n\nsub,\nsup {\n  position: relative;\n  font-size: 75%;\n  line-height: 0;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\nimg {\n  border: 0;\n}\n\nsvg:not(:root) {\n  overflow: hidden;\n}\n\nfigure {\n  margin: 0;\n}\n\nfieldset {\n  padding: 0.35em 0.625em 0.75em;\n  margin: 0 2px;\n  border: 1px solid #c0c0c0;\n}\n\nlegend {\n  padding: 0;\n  border: 0;\n}\n\nbutton,\ninput,\nselect,\ntextarea {\n  margin: 0;\n  font-family: inherit;\n  font-size: 100%;\n}\n\nbutton,\ninput {\n  line-height: normal;\n}\n\nbutton,\nselect {\n  text-transform: none;\n}\n\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  cursor: pointer;\n  -webkit-appearance: button;\n}\n\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  padding: 0;\n  box-sizing: border-box;\n}\n\ninput[type=\"search\"] {\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n  -webkit-appearance: textfield;\n}\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  padding: 0;\n  border: 0;\n}\n\ntextarea {\n  overflow: auto;\n  vertical-align: top;\n}\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\n@media print {\n  * {\n    color: #000 !important;\n    text-shadow: none !important;\n    background: transparent !important;\n    box-shadow: none !important;\n  }\n  a,\n  a:visited {\n    text-decoration: underline;\n  }\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n  .ir a:after,\n  a[href^=\"javascript:\"]:after,\n  a[href^=\"#\"]:after {\n    content: \"\";\n  }\n  pre,\n  blockquote {\n    border: 1px solid #999;\n    page-break-inside: avoid;\n  }\n  thead {\n    display: table-header-group;\n  }\n  tr,\n  img {\n    page-break-inside: avoid;\n  }\n  img {\n    max-width: 100% !important;\n  }\n  @page  {\n    margin: 0.5cm;\n  }\n  p,\n  h2,\n  h3 {\n    orphans: 3;\n    widows: 3;\n  }\n  h2,\n  h3 {\n    page-break-after: avoid;\n  }\n  .navbar-toggle {\n    display: none;\n  }\n}\n\n* {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n\nhtml {\n  font-size: 62.5%;\n  -webkit-overflow-scrolling: touch;\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\n@media screen and (max-device-width: 480px) {\n  html {\n    -webkit-text-size-adjust: 100%;\n        -ms-text-size-adjust: 100%;\n  }\n}\n\nbody {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  /*line-height: 20px;   */\n  color: #333333;\n  background-color: #ffffff;\n}\n\ninput,\nbutton,\nselect,\ntextarea {\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\n\na {\n  color: #428bca;\n  text-decoration: none;\n}\n\na:hover,\na:focus {\n  color: #2a6496;\n  text-decoration: underline;\n}\n\na:focus {\n  outline: thin dotted #333;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n\nimg {\n  height: auto;\n  max-width: 100%;\n  vertical-align: middle;\n}\n\n.img-rounded {\n  border-radius: 6px;\n}\n\n.img-circle {\n  border-radius: 500px;\n}\n\np {\n  margin: 0 0 10px;\n}\n\n.lead {\n  margin-bottom: 20px;\n  font-size: 21px;\n  font-weight: 200;\n  line-height: 1.4;\n}\n\nsmall {\n  font-size: 85%;\n}\n\nstrong {\n  font-weight: bold;\n}\n\nem {\n  font-style: italic;\n}\n\ncite {\n  font-style: normal;\n}\n\n.text-muted {\n  color: #999999;\n}\n\na.text-muted:hover,\na.text-muted:focus {\n  color: #808080;\n}\n\n.text-warning {\n  color: #c09853;\n}\n\na.text-warning:hover,\na.text-warning:focus {\n  color: #a47e3c;\n}\n\n.text-danger {\n  color: #b94a48;\n}\n\na.text-danger:hover,\na.text-danger:focus {\n  color: #953b39;\n}\n\n.text-success {\n  color: #468847;\n}\n\na.text-success:hover,\na.text-success:focus {\n  color: #356635;\n}\n\n.text-left {\n  text-align: left;\n}\n\n.text-right {\n  text-align: right;\n}\n\n.text-center {\n  text-align: center;\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n  font-family: inherit;\n /* font-weight: 500;*/\n  line-height: 20px;\n}\n\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small {\n  font-weight: normal;\n  line-height: 1;\n  color: #999999;\n}\n\nh1,\nh2,\nh3 {\n  margin-top: 20px;\n  margin-bottom: 10px;\n  line-height: 40px;\n}\n\nh3 {\n  line-height: 30px;\n}\n\nh4,\nh5,\nh6 {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n\nh1,\n.h1 {\n  font-size: 38.5px;\n}\n\nh2,\n.h2 {\n  font-size: 31.5px;\n}\n\nh3,\n.h3 {\n  font-size: 24.5px;\n}\n\nh4,\n.h4 {\n  font-size: 17.5px;\n}\n\nh5,\n.h5 {\n  font-size: 14px;\n}\n\nh6,\n.h6 {\n  font-size: 11.9px;\n}\n\nh1 small,\n.h1 small {\n  font-size: 24.5px;\n}\n\nh2 small,\n.h2 small {\n  font-size: 17.5px;\n}\n\nh3 small,\n.h3 small {\n  font-size: 14px;\n}\n\nh4 small,\n.h4 small {\n  font-size: 14px;\n}\n\n.page-header {\n  padding-bottom: 9px;\n  margin: 40px 0 20px;\n  border-bottom: 1px solid #eeeeee;\n}\n\nul,\nol {\n  padding: 0;\n  margin: 0 0 10px 25px;\n}\n\nul ul,\nul ol,\nol ol,\nol ul {\n  margin-bottom: 0;\n}\n\nli {\n  line-height: 20px;\n}\n\n.list-unstyled {\n  margin-left: 0;\n  list-style: none;\n}\n\n.list-inline {\n  margin-left: 0;\n  list-style: none;\n}\n\n.list-inline > li {\n  display: inline-block;\n  padding-right: 5px;\n  padding-left: 5px;\n}\n\ndl {\n  margin-bottom: 20px;\n}\n\ndt,\ndd {\n  line-height: 20px;\n}\n\ndt {\n  font-weight: bold;\n}\n\ndd {\n  margin-left: 10px;\n}\n\n.dl-horizontal:before,\n.dl-horizontal:after {\n  display: table;\n  content: \" \";\n}\n\n.dl-horizontal:after {\n  clear: both;\n}\n\n.dl-horizontal:before,\n.dl-horizontal:after {\n  display: table;\n  content: \" \";\n}\n\n.dl-horizontal:after {\n  clear: both;\n}\n\n.dl-horizontal dt {\n  float: left;\n  width: 160px;\n  overflow: hidden;\n  clear: left;\n  text-align: right;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.dl-horizontal dd {\n  margin-left: 180px;\n}\n\nhr {\n  margin: 20px 0;\n  border: 0;\n  border-top: 1px solid #eeeeee;\n  border-bottom: 1px solid #fff;\n  border-bottom: 1px solid rgba(255, 255, 255, 0.5);\n}\n\nabbr[title],\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted #999999;\n}\n\nabbr.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\n\nblockquote {\n  padding: 10px 20px;\n  margin: 0 0 20px;\n  border-left: 5px solid #eeeeee;\n}\n\nblockquote p {\n  font-size: 17.5px;\n  font-weight: 300;\n  line-height: 1.25;\n}\n\nblockquote p:last-child {\n  margin-bottom: 0;\n}\n\nblockquote small {\n  display: block;\n  line-height: 20px;\n  color: #999999;\n}\n\nblockquote small:before {\n  content: '\\2014 \\00A0';\n}\n\nblockquote.pull-right {\n  float: right;\n  padding-right: 15px;\n  padding-left: 0;\n  border-right: 5px solid #eeeeee;\n  border-left: 0;\n}\n\nblockquote.pull-right p,\nblockquote.pull-right small {\n  text-align: right;\n}\n\nblockquote.pull-right small:before {\n  content: '';\n}\n\nblockquote.pull-right small:after {\n  content: '\\00A0 \\2014';\n}\n\nq:before,\nq:after,\nblockquote:before,\nblockquote:after {\n  content: \"\";\n}\n\naddress {\n  display: block;\n  margin-bottom: 20px;\n  font-style: normal;\n  line-height: 20px;\n}\n\ncode,\npre {\n  padding: 0 3px 2px;\n  font-family: Monaco, Menlo, Consolas, \"Courier New\", monospace;\n  font-size: 12px;\n  color: #333333;\n  border-radius: 4px;\n}\n\ncode {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #c7254e;\n  white-space: nowrap;\n  background-color: #f9f2f4;\n}\n\npre {\n  display: block;\n  padding: 9.5px;\n  margin: 0 0 10px;\n  font-size: 13px;\n  line-height: 20px;\n  word-break: break-all;\n  word-wrap: break-word;\n  white-space: pre;\n  white-space: pre-wrap;\n  background-color: #f5f5f5;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.15);\n  border-radius: 4px;\n}\n\npre.prettyprint {\n  margin-bottom: 20px;\n}\n\npre code {\n  padding: 0;\n  color: inherit;\n  white-space: pre;\n  white-space: pre-wrap;\n  background-color: transparent;\n  border: 0;\n}\n\n.pre-scrollable {\n  max-height: 340px;\n  overflow-y: scroll;\n}\n\n.container {\n  margin-right: auto;\n  margin-left: auto;\n}\n\n.container:before,\n.container:after {\n  display: table;\n  content: \" \";\n}\n\n.container:after {\n  clear: both;\n}\n\n.container:before,\n.container:after {\n  display: table;\n  content: \" \";\n}\n\n.container:after {\n  clear: both;\n}\n\n.row:before,\n.row:after {\n  display: table;\n  content: \" \";\n}\n\n.row:after {\n  clear: both;\n}\n\n.row:before,\n.row:after {\n  display: table;\n  content: \" \";\n}\n\n.row:after {\n  clear: both;\n}\n\n.row .row {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n\n[class*=\"col-span-\"],\n[class*=\"col-small-\"] {\n  position: relative;\n  min-height: 1px;\n  padding-right: 15px;\n  padding-left: 15px;\n}\n\n[class*=\"col-small-\"] {\n  float: left;\n}\n\n.col-small-span-12 {\n  width: 100%;\n}\n\n.col-small-span-11 {\n  width: 91.66666666666666%;\n}\n\n.col-small-span-10 {\n  width: 83.33333333333334%;\n}\n\n.col-small-span-9 {\n  width: 75%;\n}\n\n.col-small-span-8 {\n  width: 66.66666666666666%;\n}\n\n.col-small-span-7 {\n  width: 58.333333333333336%;\n}\n\n.col-small-span-6 {\n  width: 50%;\n}\n\n.col-small-span-5 {\n  width: 41.66666666666667%;\n}\n\n.col-small-span-4 {\n  width: 33.33333333333333%;\n}\n\n.col-small-span-3 {\n  width: 25%;\n}\n\n.col-small-span-2 {\n  width: 16.666666666666664%;\n}\n\n.col-small-span-1 {\n  width: 8.333333333333332%;\n}\n\n@media screen and (min-width: 768px) {\n  .container {\n    max-width: 728px;\n  }\n  [class*=\"col-span-\"] {\n    float: left;\n  }\n  .col-span-12 {\n    width: 100%;\n  }\n  .col-span-11 {\n    width: 91.66666666666666%;\n  }\n  .col-span-10 {\n    width: 83.33333333333334%;\n  }\n  .col-span-9 {\n    width: 75%;\n  }\n  .col-span-8 {\n    width: 66.66666666666666%;\n  }\n  .col-span-7 {\n    width: 58.333333333333336%;\n  }\n  .col-span-6 {\n    width: 50%;\n  }\n  .col-span-5 {\n    width: 41.66666666666667%;\n  }\n  .col-span-4 {\n    width: 33.33333333333333%;\n  }\n  .col-span-3 {\n    width: 25%;\n  }\n  .col-span-2 {\n    width: 16.666666666666664%;\n  }\n  .col-span-1 {\n    width: 8.333333333333332%;\n  }\n  .col-offset-12 {\n    margin-left: 100%;\n  }\n  .col-offset-11 {\n    margin-left: 91.66666666666666%;\n  }\n  .col-offset-10 {\n    margin-left: 83.33333333333334%;\n  }\n  .col-offset-9 {\n    margin-left: 75%;\n  }\n  .col-offset-8 {\n    margin-left: 66.66666666666666%;\n  }\n  .col-offset-7 {\n    margin-left: 58.333333333333336%;\n  }\n  .col-offset-6 {\n    margin-left: 50%;\n  }\n  .col-offset-5 {\n    margin-left: 41.66666666666667%;\n  }\n  .col-offset-4 {\n    margin-left: 33.33333333333333%;\n  }\n  .col-offset-3 {\n    margin-left: 25%;\n  }\n  .col-offset-2 {\n    margin-left: 16.666666666666664%;\n  }\n  .col-offset-1 {\n    margin-left: 8.333333333333332%;\n  }\n  .col-push-12 {\n    left: 100%;\n  }\n  .col-push-11 {\n    left: 91.66666666666666%;\n  }\n  .col-push-10 {\n    left: 83.33333333333334%;\n  }\n  .col-push-9 {\n    left: 75%;\n  }\n  .col-push-8 {\n    left: 66.66666666666666%;\n  }\n  .col-push-7 {\n    left: 58.333333333333336%;\n  }\n  .col-push-6 {\n    left: 50%;\n  }\n  .col-push-5 {\n    left: 41.66666666666667%;\n  }\n  .col-push-4 {\n    left: 33.33333333333333%;\n  }\n  .col-push-3 {\n    left: 25%;\n  }\n  .col-push-2 {\n    left: 16.666666666666664%;\n  }\n  .col-push-1 {\n    left: 8.333333333333332%;\n  }\n  .col-pull-12 {\n    right: 100%;\n  }\n  .col-pull-11 {\n    right: 91.66666666666666%;\n  }\n  .col-pull-10 {\n    right: 83.33333333333334%;\n  }\n  .col-pull-9 {\n    right: 75%;\n  }\n  .col-pull-8 {\n    right: 66.66666666666666%;\n  }\n  .col-pull-7 {\n    right: 58.333333333333336%;\n  }\n  .col-pull-6 {\n    right: 50%;\n  }\n  .col-pull-5 {\n    right: 41.66666666666667%;\n  }\n  .col-pull-4 {\n    right: 33.33333333333333%;\n  }\n  .col-pull-3 {\n    right: 25%;\n  }\n  .col-pull-2 {\n    right: 16.666666666666664%;\n  }\n  .col-pull-1 {\n    right: 8.333333333333332%;\n  }\n}\n\n@media screen and (min-width: 992px) {\n  .container {\n    max-width: 940px;\n  }\n}\n\n@media screen and (min-width: 1200px) {\n  .container {\n    max-width: 1170px;\n  }\n}\n\n[class*=\"col-span-\"].pull-right {\n  float: right;\n}\n\ntable {\n  max-width: 100%;\n  background-color: transparent;\n}\n\nth {\n  text-align: left;\n}\n\n.table {\n  width: 100%;\n  margin-bottom: 20px;\n  margin-top: 20px;\n  margin-left: 5px;\n}\n\n.table thead > tr > th,\n.table tbody > tr > th,\n.table thead > tr > td,\n.table tbody > tr > td {\n  padding: 8px;\n  line-height: 20px;\n  vertical-align: top;\n  border-top: 1px solid #dddddd;\n}\n\n.table thead > tr > th {\n  vertical-align: bottom;\n}\n\n.table caption + thead tr:first-child th,\n.table caption + thead tr:first-child td,\n.table colgroup + thead tr:first-child th,\n.table colgroup + thead tr:first-child td,\n.table thead:first-child tr:first-child th,\n.table thead:first-child tr:first-child td {\n  border-top: 0;\n}\n\n.table tbody + tbody {\n  border-top: 2px solid #dddddd;\n}\n\n.table .table {\n  background-color: #ffffff;\n}\n\n.table-condensed thead > tr > th,\n.table-condensed tbody > tr > th,\n.table-condensed thead > tr > td,\n.table-condensed tbody > tr > td {\n  padding: 4px 5px;\n}\n\n.table-bordered {\n  border: 1px solid #dddddd;\n  border-collapse: separate;\n  border-left: 0;\n  border-radius: 4px;\n}\n\n.table-bordered thead > tr > th,\n.table-bordered tbody > tr > th,\n.table-bordered thead > tr > td,\n.table-bordered tbody > tr > td {\n  border-left: 1px solid #dddddd;\n}\n\n.table-bordered caption + thead > tr:first-child th,\n.table-bordered caption + tbody > tr:first-child th,\n.table-bordered caption + tbody > tr:first-child td,\n.table-bordered colgroup + thead > tr:first-child th,\n.table-bordered colgroup + tbody > tr:first-child th,\n.table-bordered colgroup + tbody > tr:first-child td,\n.table-bordered thead:first-child > tr:first-child th,\n.table-bordered tbody:first-child > tr:first-child th,\n.table-bordered tbody:first-child > tr:first-child td {\n  border-top: 0;\n}\n\n.table-bordered thead:first-child > tr:first-child > th:first-child,\n.table-bordered tbody:first-child > tr:first-child > td:first-child,\n.table-bordered tbody:first-child > tr:first-child > th:first-child {\n  border-top-left-radius: 4px;\n}\n\n.table-bordered thead:first-child > tr:first-child > th:last-child,\n.table-bordered tbody:first-child > tr:first-child > td:last-child,\n.table-bordered tbody:first-child > tr:first-child > th:last-child {\n  border-top-right-radius: 4px;\n}\n\n.table-bordered thead:last-child > tr:last-child > th:first-child,\n.table-bordered tbody:last-child > tr:last-child > td:first-child,\n.table-bordered tbody:last-child > tr:last-child > th:first-child,\n.table-bordered tfoot:last-child > tr:last-child > td:first-child,\n.table-bordered tfoot:last-child > tr:last-child > th:first-child {\n  border-bottom-left-radius: 4px;\n}\n\n.table-bordered thead:last-child > tr:last-child > th:last-child,\n.table-bordered tbody:last-child > tr:last-child > td:last-child,\n.table-bordered tbody:last-child > tr:last-child > th:last-child,\n.table-bordered tfoot:last-child > tr:last-child > td:last-child,\n.table-bordered tfoot:last-child > tr:last-child > th:last-child {\n  border-bottom-right-radius: 4px;\n}\n\n.table-bordered tfoot + tbody:last-child > tr:last-child > td:first-child {\n  border-bottom-left-radius: 0;\n}\n\n.table-bordered tfoot + tbody:last-child > tr:last-child > td:last-child {\n  border-bottom-right-radius: 0;\n}\n\n.table-bordered caption + thead > tr:first-child > th:first-child,\n.table-bordered caption + tbody > tr:first-child > td:first-child,\n.table-bordered colgroup + thead > tr:first-child > th:first-child,\n.table-bordered colgroup + tbody > tr:first-child > td:first-child {\n  border-top-left-radius: 4px;\n}\n\n.table-bordered caption + thead > tr:first-child > th:last-child,\n.table-bordered caption + tbody > tr:first-child > td:last-child,\n.table-bordered colgroup + thead > tr:first-child > th:last-child,\n.table-bordered colgroup + tbody > tr:first-child > td:last-child {\n  border-top-right-radius: 4px;\n}\n\n.table-striped > tbody > tr:nth-child(odd) > td,\n.table-striped > tbody > tr:nth-child(odd) > th {\n  background-color: #f9f9f9;\n}\n\n.table-hover > tbody > tr:hover > td,\n.table-hover > tbody > tr:hover > th {\n  background-color: #f5f5f5;\n}\n\ntable col[class*=\"col-span-\"] {\n  display: table-column;\n  float: none;\n}\n\ntable td[class*=\"col-span-\"],\ntable th[class*=\"col-span-\"] {\n  display: table-cell;\n  float: none;\n  border-top: 1px solid #dddddd;\n}\n\n.table > tbody > tr > td.success,\n.table > tbody > tr > th.success,\n.table > tbody > tr.success > td {\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n\n.table > tbody > tr > td.danger,\n.table > tbody > tr > th.danger,\n.table > tbody > tr.danger > td {\n  background-color: #f2dede;\n  border-color: #eed3d7;\n}\n\n.table > tbody > tr > td.warning,\n.table > tbody > tr > th.warning,\n.table > tbody > tr.warning > td {\n  background-color: #fcf8e3;\n  border-color: #fbeed5;\n}\n\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td {\n  background-color: #d0e9c6;\n  border-color: #c9e2b3;\n}\n\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td {\n  background-color: #ebcccc;\n  border-color: #e6c1c7;\n}\n\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td {\n  background-color: #faf2cc;\n  border-color: #f8e5be;\n}\n\nform {\n  margin: 0;\n}\n\nfieldset {\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\n\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 20px;\n  font-size: 21px;\n  line-height: 40px;\n  color: #333333;\n  border: 0;\n  border-bottom: 1px solid #e5e5e5;\n}\n\nlabel {\n  display: inline-block;\n  margin-bottom: 5px;\n  /*font-weight: bold;*/\n}\n\nselect,\ntextarea,\ninput[type=\"text\"],\ninput[type=\"password\"],\ninput[type=\"datetime\"],\ninput[type=\"datetime-local\"],\ninput[type=\"date\"],\ninput[type=\"month\"],\ninput[type=\"time\"],\ninput[type=\"week\"],\ninput[type=\"number\"],\ninput[type=\"email\"],\ninput[type=\"url\"],\ninput[type=\"search\"],\ninput[type=\"tel\"],\ninput[type=\"color\"] {\n  display: inline-block;\n  min-height: 34px;\n  padding: 6px 9px;\n  font-size: 14px;\n  line-height: 20px;\n  color: #555555;\n  vertical-align: middle;\n  background-color: #ffffff;\n  border: 1px solid #cccccc;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;\n     -moz-transition: border linear 0.2s, box-shadow linear 0.2s;\n       -o-transition: border linear 0.2s, box-shadow linear 0.2s;\n          transition: border linear 0.2s, box-shadow linear 0.2s;\n}\n\ninput,\nselect,\ntextarea {\n  width: 100%;\n}\n\ninput[type=\"file\"],\ninput[type=\"image\"],\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"],\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  width: auto;\n}\n\ninput[type=\"search\"] {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n\ntextarea {\n  height: auto;\n}\n\ntextarea:focus,\ninput[type=\"text\"]:focus,\ninput[type=\"password\"]:focus,\ninput[type=\"datetime\"]:focus,\ninput[type=\"datetime-local\"]:focus,\ninput[type=\"date\"]:focus,\ninput[type=\"month\"]:focus,\ninput[type=\"time\"]:focus,\ninput[type=\"week\"]:focus,\ninput[type=\"number\"]:focus,\ninput[type=\"email\"]:focus,\ninput[type=\"url\"]:focus,\ninput[type=\"search\"]:focus,\ninput[type=\"tel\"]:focus,\ninput[type=\"color\"]:focus {\n  border-color: rgba(82, 168, 236, 0.8);\n  outline: 0;\n  outline: thin dotted \\9;\n  /* IE6-9 */\n\n  -webkit-box-shadow: 0 0 8px rgba(82, 168, 236, 0.6);\n          box-shadow: 0 0 8px rgba(82, 168, 236, 0.6);\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9;\n  /* IE8-9 */\n\n  line-height: normal;\n}\n\nselect,\ninput[type=\"file\"] {\n  height: 34px;\n  /* In IE7, the height of the select element cannot be changed by height, only font-size. TODO: Check if this is still needed when dropping IE7 support */\n\n  line-height: 34px;\n}\n\nselect[multiple],\nselect[size] {\n  height: auto;\n}\n\nselect:focus,\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  outline: thin dotted #333;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n\ninput:-moz-placeholder,\ntextarea:-moz-placeholder {\n  color: #999999;\n}\n\ninput::-moz-placeholder,\ntextarea::-moz-placeholder {\n  color: #999999;\n}\n\ninput:-ms-input-placeholder,\ntextarea:-ms-input-placeholder {\n  color: #999999;\n}\n\ninput::-webkit-input-placeholder,\ntextarea::-webkit-input-placeholder {\n  color: #999999;\n}\n\n.radio,\n.checkbox {\n  display: block;\n  min-height: 20px;\n  padding-left: 20px;\n  margin-bottom: 10px;\n}\n\n.radio label,\n.checkbox label {\n  display: inline;\n  margin-bottom: 0;\n  font-weight: normal;\n}\n\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  float: left;\n  margin-left: -20px;\n}\n\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px;\n}\n\n.controls > .radio:first-child,\n.controls > .checkbox:first-child {\n  padding-top: 5px;\n}\n\n.radio-inline,\n.checkbox-inline {\n  display: inline-block;\n  padding-top: 5px;\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n  vertical-align: middle;\n}\n\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px;\n}\n\nselect.input-large,\ntextarea.input-large,\ninput[type=\"text\"].input-large,\ninput[type=\"password\"].input-large,\ninput[type=\"datetime\"].input-large,\ninput[type=\"datetime-local\"].input-large,\ninput[type=\"date\"].input-large,\ninput[type=\"month\"].input-large,\ninput[type=\"time\"].input-large,\ninput[type=\"week\"].input-large,\ninput[type=\"number\"].input-large,\ninput[type=\"email\"].input-large,\ninput[type=\"url\"].input-large,\ninput[type=\"search\"].input-large,\ninput[type=\"tel\"].input-large,\ninput[type=\"color\"].input-large {\n  padding: 11px 14px;\n  font-size: 17.5px;\n  border-radius: 6px;\n}\n\nselect.input-small,\ntextarea.input-small,\ninput[type=\"text\"].input-small,\ninput[type=\"password\"].input-small,\ninput[type=\"datetime\"].input-small,\ninput[type=\"datetime-local\"].input-small,\ninput[type=\"date\"].input-small,\ninput[type=\"month\"].input-small,\ninput[type=\"time\"].input-small,\ninput[type=\"week\"].input-small,\ninput[type=\"number\"].input-small,\ninput[type=\"email\"].input-small,\ninput[type=\"url\"].input-small,\ninput[type=\"search\"].input-small,\ninput[type=\"tel\"].input-small,\ninput[type=\"color\"].input-small {\n  min-height: 26px;\n  padding: 2px 10px;\n  font-size: 11.9px;\n  border-radius: 3px;\n}\n\ninput[class*=\"span\"],\nselect[class*=\"span\"],\ntextarea[class*=\"span\"] {\n  float: none;\n  margin-right: 0;\n  margin-left: 0;\n}\n\n.input-append input[class*=\"span\"],\n.input-prepend input[class*=\"span\"] {\n  display: inline-block;\n}\n\ninput[class*=\"span\"],\nselect[class*=\"span\"],\ntextarea[class*=\"span\"] {\n  height: 34px;\n}\n\ninput[disabled],\nselect[disabled],\ntextarea[disabled],\ninput[readonly],\nselect[readonly],\ntextarea[readonly],\nfieldset[disabled] input,\nfieldset[disabled] select,\nfieldset[disabled] textarea {\n  cursor: not-allowed;\n  background-color: #eeeeee;\n}\n\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"][readonly],\ninput[type=\"checkbox\"][readonly],\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n  background-color: transparent;\n}\n\n.has-warning .control-label {\n  color: #c09853;\n}\n\n.has-warning .input-with-feedback {\n  padding-right: 32px;\n  border-color: #c09853;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n\n.has-warning .input-with-feedback:focus {\n  border-color: #a47e3c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;\n}\n\n.has-error .control-label {\n  color: #b94a48;\n}\n\n.has-error .input-with-feedback {\n  padding-right: 32px;\n  border-color: #b94a48;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n\n.has-error .input-with-feedback:focus {\n  border-color: #953b39;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;\n}\n\n.has-success .control-label {\n  color: #468847;\n}\n\n.has-success .input-with-feedback {\n  padding-right: 32px;\n  border-color: #468847;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n\n.has-success .input-with-feedback:focus {\n  border-color: #356635;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;\n}\n\ninput:focus:invalid,\ntextarea:focus:invalid,\nselect:focus:invalid {\n  color: #b94a48;\n  border-color: #ee5f5b;\n}\n\ninput:focus:invalid:focus,\ntextarea:focus:invalid:focus,\nselect:focus:invalid:focus {\n  border-color: #e9322d;\n  -webkit-box-shadow: 0 0 6px #f8b9b7;\n          box-shadow: 0 0 6px #f8b9b7;\n}\n\n.form-actions {\n  padding: 19px 20px 20px;\n  margin-top: 20px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border-top: 1px solid #e5e5e5;\n}\n\n.form-actions:before,\n.form-actions:after {\n  display: table;\n  content: \" \";\n}\n\n.form-actions:after {\n  clear: both;\n}\n\n.form-actions:before,\n.form-actions:after {\n  display: table;\n  content: \" \";\n}\n\n.form-actions:after {\n  clear: both;\n}\n\n.help-block,\n.help-inline {\n  color: #737373;\n}\n\n.help-block {\n  display: block;\n  margin-bottom: 10px;\n}\n\n.help-inline {\n  display: inline-block;\n  padding-left: 5px;\n  vertical-align: middle;\n}\n\n.input-group {\n  display: table;\n}\n\n.input-group[class*=\"span\"] {\n  float: none;\n  padding: 0;\n}\n\n.input-group input,\n.input-group select {\n  width: 100%;\n}\n\n.input-group-addon,\n.input-group-btn,\n.input-group input {\n  display: table-cell;\n  margin: 0;\n  border-radius: 0;\n}\n\n.input-group-addon.input-small,\n.input-group-btn.input-small,\n.input-group input.input-small {\n  border-radius: 0;\n}\n\n.input-group-addon.input-large,\n.input-group-btn.input-large,\n.input-group input.input-large {\n  border-radius: 0;\n}\n\n.input-group-addon,\n.input-group-btn {\n  width: 1%;\n  vertical-align: middle;\n}\n\n.input-group-addon {\n  padding: 6px 8px;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n  text-align: center;\n  text-shadow: 0 1px 0 #fff;\n  background-color: #eeeeee;\n  border: 1px solid #ccc;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n\n.input-group-addon.input-small {\n  padding: 2px 10px;\n  font-size: 11.9px;\n}\n\n.input-group-addon.input-large {\n  padding: 11px 14px;\n  font-size: 17.5px;\n}\n\n.input-group input:first-child,\n.input-group-addon:first-child {\n  border-bottom-left-radius: 4px;\n  border-top-left-radius: 4px;\n}\n\n.input-group input:first-child.input-small,\n.input-group-addon:first-child.input-small {\n  border-bottom-left-radius: 3px;\n  border-top-left-radius: 3px;\n}\n\n.input-group input:first-child.input-large,\n.input-group-addon:first-child.input-large {\n  border-bottom-left-radius: 6px;\n  border-top-left-radius: 6px;\n}\n\n.input-group-addon:first-child {\n  border-right: 0;\n}\n\n.input-group input:last-child,\n.input-group-addon:last-child {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n\n.input-group input:last-child.input-small,\n.input-group-addon:last-child.input-small {\n  border-top-right-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n\n.input-group input:last-child.input-large,\n.input-group-addon:last-child.input-large {\n  border-top-right-radius: 6px;\n  border-bottom-right-radius: 6px;\n}\n\n.input-group-addon:last-child {\n  border-left: 0;\n}\n\n.input-group-btn {\n  position: relative;\n  white-space: nowrap;\n}\n\n.input-group-btn > .btn {\n  position: relative;\n  float: left;\n  border-radius: 0;\n}\n\n.input-group-btn > .btn + .btn {\n  margin-left: -1px;\n}\n\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:active {\n  z-index: 2;\n}\n\n.input-group-btn:first-child > .btn:first-child,\n.input-group-btn:first-child > .dropdown-toggle:first-child {\n  border-bottom-left-radius: 4px;\n  border-top-left-radius: 4px;\n}\n\n.input-group-btn:first-child > .btn:first-child.btn-large,\n.input-group-btn:first-child > .dropdown-toggle:first-child.btn-large {\n  border-bottom-left-radius: 6px;\n  border-top-left-radius: 6px;\n}\n\n.input-group-btn:first-child > .btn:first-child.btn-small,\n.input-group-btn:first-child > .dropdown-toggle:first-child.btn-small {\n  border-bottom-left-radius: 3px;\n  border-top-left-radius: 3px;\n}\n\n.input-group-btn:last-child > .btn:last-child,\n.input-group-btn:last-child > .dropdown-toggle {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n\n.input-group-btn:last-child > .btn:last-child.btn-large,\n.input-group-btn:last-child > .dropdown-toggle.btn-large {\n  border-top-right-radius: 6px;\n  border-bottom-right-radius: 6px;\n}\n\n.input-group-btn:last-child > .btn:last-child.btn-small,\n.input-group-btn:last-child > .dropdown-toggle.btn-small {\n  border-top-right-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n\n@media screen and (min-width: 768px) {\n  .form-horizontal .control-group {\n    position: relative;\n    margin-bottom: 20px;\n  }\n  .form-horizontal .control-group:before,\n  .form-horizontal .control-group:after {\n    display: table;\n    content: \" \";\n  }\n  .form-horizontal .control-group:after {\n    clear: both;\n  }\n  .form-horizontal .control-group:before,\n  .form-horizontal .control-group:after {\n    display: table;\n    content: \" \";\n  }\n  .form-horizontal .control-group:after {\n    clear: both;\n  }\n  .form-horizontal .control-group input,\n  .form-horizontal .control-group select,\n  .form-horizontal .control-group textarea {\n    margin-bottom: 0;\n  }\n  .form-horizontal .control-group > .control-label {\n    float: left;\n    width: 160px;\n    padding-top: 6px;\n    text-align: right;\n  }\n  .form-horizontal .control-group > .controls {\n    margin-left: 180px;\n  }\n  .form-horizontal .form-actions {\n    padding-left: 180px;\n  }\n}\n\n.btn {\n  display: inline-block;\n  padding: 6px 12px;\n  margin-bottom: 0;\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 20px;\n  text-align: center;\n  /*white-space: nowrap;*/\n  vertical-align: middle;\n  cursor: pointer;\n  border: 1px solid #a7a9aa;\n  border-radius: 4px;\n}\n\n.btn:focus {\n  outline: thin dotted #333;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n\n.btn:hover,\n.btn:focus {\n  color: #fff;\n  text-decoration: none;\n}\n\n.btn:active,\n.btn.active {\n  background-image: none;\n  outline: 0;\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n  pointer-events: none;\n  cursor: default;\n  opacity: 0.65;\n  filter: alpha(opacity=65);\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n\n.btn-large {\n  padding: 11px 14px;\n  font-size: 17.5px;\n  border-radius: 6px;\n}\n\n.btn-small {\n  padding: 2px 10px;\n  font-size: 11.9px;\n  border-radius: 3px;\n}\n\n.btn-mini {\n    padding: 5px 5px 0px;\n    font-size: 13px;\n    border-radius: 3px;\n    width: 130px;\n    height: 40px;\n}\n\n.btn-block {\n  display: block;\n  width: 100%;\n  padding-right: 0;\n  padding-left: 0;\n}\n\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\n\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n  width: 100%;\n}\n\n.btn {\n  color: #ffffff;\n  background-color: #a7a9aa;\n  border-color: #a7a9aa;\n}\n\n.btn:hover,\n.btn:focus,\n.btn:active,\n.btn.active {\n  background-color: #9a9c9d;\n  border-color: #8d9091;\n}\n\n.btn.disabled:hover,\n.btn[disabled]:hover,\nfieldset[disabled] .btn:hover,\n.btn.disabled:focus,\n.btn[disabled]:focus,\nfieldset[disabled] .btn:focus,\n.btn.disabled:active,\n.btn[disabled]:active,\nfieldset[disabled] .btn:active,\n.btn.disabled.active,\n.btn[disabled].active,\nfieldset[disabled] .btn.active {\n  background-color: #a7a9aa;\n  border-color: #a7a9aa;\n}\n\n.btn-primary {\n  background-color: #428bca;\n  border-color: #428bca;\n}\n\n.btn-primary:hover,\n.btn-primary:focus,\n.btn-primary:active,\n.btn-primary.active {\n  background-color: #357ebd;\n  border-color: #3071a9;\n}\n\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n  background-color: #428bca;\n  border-color: #428bca;\n}\n\n.btn-warning {\n  background-color: #f0ad4e;\n  border-color: #f0ad4e;\n}\n\n.btn-warning:hover,\n.btn-warning:focus,\n.btn-warning:active,\n.btn-warning.active {\n  background-color: #eea236;\n  border-color: #ec971f;\n}\n\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n  background-color: #f0ad4e;\n  border-color: #f0ad4e;\n}\n\n.btn-danger {\n  background-color: #d9534f;\n  border-color: #d9534f;\n}\n\n.btn-danger:hover,\n.btn-danger:focus,\n.btn-danger:active,\n.btn-danger.active {\n  background-color: #d43f3a;\n  border-color: #c9302c;\n}\n\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n  background-color: #d9534f;\n  border-color: #d9534f;\n}\n\n.btn-success {\n  background-color: #5cb85c;\n  border-color: #5cb85c;\n}\n\n.btn-success:hover,\n.btn-success:focus,\n.btn-success:active,\n.btn-success.active {\n  background-color: #4cae4c;\n  border-color: #449d44;\n}\n\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n  background-color: #5cb85c;\n  border-color: #5cb85c;\n}\n\n.btn-info {\n  background-color: #5bc0de;\n  border-color: #5bc0de;\n}\n\n.btn-info:hover,\n.btn-info:focus,\n.btn-info:active,\n.btn-info.active {\n  background-color: #46b8da;\n  border-color: #31b0d5;\n}\n\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n  background-color: #5bc0de;\n  border-color: #5bc0de;\n}\n\n.btn-link,\n.btn-link:active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n  background-color: transparent;\n  background-image: none;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n  border-color: transparent;\n}\n\n.btn-link {\n  font-weight: normal;\n  color: #428bca;\n  cursor: pointer;\n  border-radius: 0;\n}\n\n.btn-link:hover,\n.btn-link:focus {\n  color: #2a6496;\n  text-decoration: underline;\n  background-color: transparent;\n}\n\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n  color: #333333;\n  text-decoration: none;\n}\n\n.fade {\n  opacity: 0;\n  -webkit-transition: opacity 0.15s linear;\n     -moz-transition: opacity 0.15s linear;\n       -o-transition: opacity 0.15s linear;\n          transition: opacity 0.15s linear;\n}\n\n.fade.in {\n  opacity: 1;\n}\n\n/*.collapse {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  .transition(height .35s ease);\n  &.in {\n    height: auto;\n  }\n}*/\n\n.collapse {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  -webkit-transition: height 0.35s ease;\n     -moz-transition: height 0.35s ease;\n       -o-transition: height 0.35s ease;\n          transition: height 0.35s ease;\n}\n\n.collapse.in {\n  height: auto;\n  overflow: visible;\n}\n\n@font-face {\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  font-weight: normal;\n  src: url('/assets/vendor/css/bootstrap/fonts/glyphiconshalflings-regular.eot');\n  src: url('/assets/vendor/css/bootstrap/fonts/glyphiconshalflings-regular.eot?#iefix') format('embedded-opentype'), url('/assets/vendor/css/bootstrap/fonts/glyphiconshalflings-regular.woff') format('woff'), url('/assets/vendor/css/bootstrap/fonts/glyphiconshalflings-regular.ttf') format('truetype'), url('/assets/vendor/css/bootstrap/fonts/glyphiconshalflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n\n.glyphicon:before {\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  line-height: 1;\n}\n\n.glyphicon-glass:before {\n  content: \"\\e001\";\n}\n\n.glyphicon-music:before {\n  content: \"\\e002\";\n}\n\n.glyphicon-search:before {\n  content: \"\\e003\";\n}\n\n.glyphicon-envelope:before {\n  content: \"\\2709\";\n}\n\n.glyphicon-heart:before {\n  content: \"\\e005\";\n}\n\n.glyphicon-star:before {\n  content: \"\\e006\";\n}\n\n.glyphicon-star-empty:before {\n  content: \"\\e007\";\n}\n\n.glyphicon-user:before {\n  content: \"\\e008\";\n}\n\n.glyphicon-film:before {\n  content: \"\\e009\";\n}\n\n.glyphicon-th-large:before {\n  content: \"\\e010\";\n}\n\n.glyphicon-th:before {\n  content: \"\\e011\";\n}\n\n.glyphicon-th-list:before {\n  content: \"\\e012\";\n}\n\n.glyphicon-ok:before {\n  content: \"\\e013\";\n}\n\n.glyphicon-remove:before {\n  content: \"\\e014\";\n}\n\n.glyphicon-zoom-in:before {\n  content: \"\\e015\";\n}\n\n.glyphicon-zoom-out:before {\n  content: \"\\e016\";\n}\n\n.glyphicon-off:before {\n  content: \"\\e017\";\n}\n\n.glyphicon-signal:before {\n  content: \"\\e018\";\n}\n\n.glyphicon-cog:before {\n  content: \"\\e019\";\n}\n\n.glyphicon-trash:before {\n  content: \"\\e020\";\n}\n\n.glyphicon-home:before {\n  content: \"\\e021\";\n}\n\n.glyphicon-file:before {\n  content: \"\\e022\";\n}\n\n.glyphicon-time:before {\n  content: \"\\e023\";\n}\n\n.glyphicon-road:before {\n  content: \"\\e024\";\n}\n\n.glyphicon-download-alt:before {\n  content: \"\\e025\";\n}\n\n.glyphicon-download:before {\n  content: \"\\e026\";\n}\n\n.glyphicon-upload:before {\n  content: \"\\e027\";\n}\n\n.glyphicon-inbox:before {\n  content: \"\\e028\";\n}\n\n.glyphicon-play-circle:before {\n  content: \"\\e029\";\n}\n\n.glyphicon-repeat:before {\n  content: \"\\e030\";\n}\n\n.glyphicon-refresh:before {\n  content: \"\\e031\";\n}\n\n.glyphicon-list-alt:before {\n  content: \"\\e032\";\n}\n\n.glyphicon-lock:before {\n  content: \"\\e033\";\n}\n\n.glyphicon-flag:before {\n  content: \"\\e034\";\n}\n\n.glyphicon-headphones:before {\n  content: \"\\e035\";\n}\n\n.glyphicon-volume-off:before {\n  content: \"\\e036\";\n}\n\n.glyphicon-volume-down:before {\n  content: \"\\e037\";\n}\n\n.glyphicon-volume-up:before {\n  content: \"\\e038\";\n}\n\n.glyphicon-qrcode:before {\n  content: \"\\e039\";\n}\n\n.glyphicon-barcode:before {\n  content: \"\\e040\";\n}\n\n.glyphicon-tag:before {\n  content: \"\\e041\";\n}\n\n.glyphicon-tags:before {\n  content: \"\\e042\";\n}\n\n.glyphicon-book:before {\n  content: \"\\e043\";\n}\n\n.glyphicon-bookmark:before {\n  content: \"\\e044\";\n}\n\n.glyphicon-print:before {\n  content: \"\\e045\";\n}\n\n.glyphicon-camera:before {\n  content: \"\\e046\";\n}\n\n.glyphicon-font:before {\n  content: \"\\e047\";\n}\n\n.glyphicon-bold:before {\n  content: \"\\e048\";\n}\n\n.glyphicon-italic:before {\n  content: \"\\e049\";\n}\n\n.glyphicon-text-height:before {\n  content: \"\\e050\";\n}\n\n.glyphicon-text-width:before {\n  content: \"\\e051\";\n}\n\n.glyphicon-align-left:before {\n  content: \"\\e052\";\n}\n\n.glyphicon-align-center:before {\n  content: \"\\e053\";\n}\n\n.glyphicon-align-right:before {\n  content: \"\\e054\";\n}\n\n.glyphicon-align-justify:before {\n  content: \"\\e055\";\n}\n\n.glyphicon-list:before {\n  content: \"\\e056\";\n}\n\n.glyphicon-indent-left:before {\n  content: \"\\e057\";\n}\n\n.glyphicon-indent-right:before {\n  content: \"\\e058\";\n}\n\n.glyphicon-facetime-video:before {\n  content: \"\\e059\";\n}\n\n.glyphicon-picture:before {\n  content: \"\\e060\";\n}\n\n.glyphicon-pencil:before {\n  content: \"\\270f\";\n}\n\n.glyphicon-map-marker:before {\n  content: \"\\e062\";\n}\n\n.glyphicon-adjust:before {\n  content: \"\\e063\";\n}\n\n.glyphicon-tint:before {\n  content: \"\\e064\";\n}\n\n.glyphicon-edit:before {\n  content: \"\\e065\";\n}\n\n.glyphicon-share:before {\n  content: \"\\e066\";\n}\n\n.glyphicon-check:before {\n  content: \"\\e067\";\n}\n\n.glyphicon-move:before {\n  content: \"\\e068\";\n}\n\n.glyphicon-step-backward:before {\n  content: \"\\e069\";\n}\n\n.glyphicon-fast-backward:before {\n  content: \"\\e070\";\n}\n\n.glyphicon-backward:before {\n  content: \"\\e071\";\n}\n\n.glyphicon-play:before {\n  content: \"\\e072\";\n}\n\n.glyphicon-pause:before {\n  content: \"\\e073\";\n}\n\n.glyphicon-stop:before {\n  content: \"\\e074\";\n}\n\n.glyphicon-forward:before {\n  content: \"\\e075\";\n}\n\n.glyphicon-fast-forward:before {\n  content: \"\\e076\";\n}\n\n.glyphicon-step-forward:before {\n  content: \"\\e077\";\n}\n\n.glyphicon-eject:before {\n  content: \"\\e078\";\n}\n\n.glyphicon-chevron-left:before {\n  content: \"\\e079\";\n}\n\n.glyphicon-chevron-right:before {\n  content: \"\\e080\";\n}\n\n.glyphicon-plus-sign:before {\n  content: \"\\e081\";\n}\n\n.glyphicon-minus-sign:before {\n  content: \"\\e082\";\n}\n\n.glyphicon-remove-sign:before {\n  content: \"\\e083\";\n}\n\n.glyphicon-ok-sign:before {\n  content: \"\\e084\";\n}\n\n.glyphicon-question-sign:before {\n  content: \"\\e085\";\n}\n\n.glyphicon-info-sign:before {\n  content: \"\\e086\";\n}\n\n.glyphicon-screenshot:before {\n  content: \"\\e087\";\n}\n\n.glyphicon-remove-circle:before {\n  content: \"\\e088\";\n}\n\n.glyphicon-ok-circle:before {\n  content: \"\\e089\";\n}\n\n.glyphicon-ban-circle:before {\n  content: \"\\e090\";\n}\n\n.glyphicon-arrow-left:before {\n  content: \"\\e091\";\n}\n\n.glyphicon-arrow-right:before {\n  content: \"\\e092\";\n}\n\n.glyphicon-arrow-up:before {\n  content: \"\\e093\";\n}\n\n.glyphicon-arrow-down:before {\n  content: \"\\e094\";\n}\n\n.glyphicon-share-alt:before {\n  content: \"\\e095\";\n}\n\n.glyphicon-resize-full:before {\n  content: \"\\e096\";\n}\n\n.glyphicon-resize-small:before {\n  content: \"\\e097\";\n}\n\n.glyphicon-plus:before {\n  content: \"\\002b\";\n}\n\n.glyphicon-minus:before {\n  content: \"\\2212\";\n}\n\n.glyphicon-asterisk:before {\n  content: \"\\002a\";\n}\n\n.glyphicon-exclamation-sign:before {\n  content: \"\\e101\";\n}\n\n.glyphicon-gift:before {\n  content: \"\\e102\";\n}\n\n.glyphicon-leaf:before {\n  content: \"\\e103\";\n}\n\n.glyphicon-fire:before {\n  content: \"\\e104\";\n}\n\n.glyphicon-eye-open:before {\n  content: \"\\e105\";\n}\n\n.glyphicon-eye-close:before {\n  content: \"\\e106\";\n}\n\n.glyphicon-warning-sign:before {\n  content: \"\\e107\";\n}\n\n.glyphicon-plane:before {\n  content: \"\\e108\";\n}\n\n.glyphicon-calendar:before {\n  content: \"\\e109\";\n}\n\n.glyphicon-random:before {\n  content: \"\\e110\";\n}\n\n.glyphicon-comment:before {\n  content: \"\\e111\";\n}\n\n.glyphicon-magnet:before {\n  content: \"\\e112\";\n}\n\n.glyphicon-chevron-up:before {\n  content: \"\\e113\";\n}\n\n.glyphicon-chevron-down:before {\n  content: \"\\e114\";\n}\n\n.glyphicon-retweet:before {\n  content: \"\\e115\";\n}\n\n.glyphicon-shopping-cart:before {\n  content: \"\\e116\";\n}\n\n.glyphicon-folder-close:before {\n  content: \"\\e117\";\n}\n\n.glyphicon-folder-open:before {\n  content: \"\\e118\";\n}\n\n.glyphicon-resize-vertical:before {\n  content: \"\\e119\";\n}\n\n.glyphicon-resize-horizontal:before {\n  content: \"\\e120\";\n}\n\n.glyphicon-hdd:before {\n  content: \"\\e121\";\n}\n\n.glyphicon-bullhorn:before {\n  content: \"\\e122\";\n}\n\n.glyphicon-bell:before {\n  content: \"\\e123\";\n}\n\n.glyphicon-certificate:before {\n  content: \"\\e124\";\n}\n\n.glyphicon-thumbs-up:before {\n  content: \"\\e125\";\n}\n\n.glyphicon-thumbs-down:before {\n  content: \"\\e126\";\n}\n\n.glyphicon-hand-right:before {\n  content: \"\\e127\";\n}\n\n.glyphicon-hand-left:before {\n  content: \"\\e128\";\n}\n\n.glyphicon-hand-up:before {\n  content: \"\\e129\";\n}\n\n.glyphicon-hand-down:before {\n  content: \"\\e130\";\n}\n\n.glyphicon-circle-arrow-right:before {\n  content: \"\\e131\";\n}\n\n.glyphicon-circle-arrow-left:before {\n  content: \"\\e132\";\n}\n\n.glyphicon-circle-arrow-up:before {\n  content: \"\\e133\";\n}\n\n.glyphicon-circle-arrow-down:before {\n  content: \"\\e134\";\n}\n\n.glyphicon-globe:before {\n  content: \"\\e135\";\n}\n\n.glyphicon-wrench:before {\n  content: \"\\e136\";\n}\n\n.glyphicon-tasks:before {\n  content: \"\\e137\";\n}\n\n.glyphicon-filter:before {\n  content: \"\\e138\";\n}\n\n.glyphicon-briefcase:before {\n  content: \"\\e139\";\n}\n\n.glyphicon-fullscreen:before {\n  content: \"\\e140\";\n}\n\n.glyphicon-dashboard:before {\n  content: \"\\e141\";\n}\n\n.glyphicon-paperclip:before {\n  content: \"\\e142\";\n}\n\n.glyphicon-heart-empty:before {\n  content: \"\\e143\";\n}\n\n.glyphicon-link:before {\n  content: \"\\e144\";\n}\n\n.glyphicon-phone:before {\n  content: \"\\e145\";\n}\n\n.glyphicon-pushpin:before {\n  content: \"\\e146\";\n}\n\n.glyphicon-euro:before {\n  content: \"\\20ac\";\n}\n\n.glyphicon-usd:before {\n  content: \"\\e148\";\n}\n\n.glyphicon-gbp:before {\n  content: \"\\e149\";\n}\n\n.glyphicon-sort:before {\n  content: \"\\e150\";\n}\n\n.glyphicon-sort-by-alphabet:before {\n  content: \"\\e151\";\n}\n\n.glyphicon-sort-by-alphabet-alt:before {\n  content: \"\\e152\";\n}\n\n.glyphicon-sort-by-order:before {\n  content: \"\\e153\";\n}\n\n.glyphicon-sort-by-order-alt:before {\n  content: \"\\e154\";\n}\n\n.glyphicon-sort-by-attributes:before {\n  content: \"\\e155\";\n}\n\n.glyphicon-sort-by-attributes-alt:before {\n  content: \"\\e156\";\n}\n\n.glyphicon-unchecked:before {\n  content: \"\\e157\";\n}\n\n.glyphicon-expand:before {\n  content: \"\\e158\";\n}\n\n.glyphicon-collapse:before {\n  content: \"\\e159\";\n}\n\n.glyphicon-collapse-top:before {\n  content: \"\\e160\";\n}\n\n.dropup,\n.dropdown {\n  position: relative;\n}\n\n.dropdown-toggle:active,\n.open .dropdown-toggle {\n  outline: 0;\n}\n\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  vertical-align: top;\n  border-top: 4px solid #000;\n  border-right: 4px solid transparent;\n  border-left: 4px solid transparent;\n  content: \"\";\n}\n\n.dropdown .caret {\n  margin-top: 8px;\n  margin-left: 2px;\n}\n\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 1000;\n  display: none;\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0;\n  list-style: none;\n  background-color: #ffffff;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.15);\n  border-radius: 4px;\n  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n          box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n  -webkit-background-clip: padding-box;\n     -moz-background-clip: padding-box;\n          background-clip: padding-box;\n}\n\n.dropdown-menu.pull-right {\n  right: 0;\n  left: auto;\n}\n\n.dropdown-menu .divider {\n  height: 2px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n  border-bottom: 1px solid #ffffff;\n}\n\n.dropdown-menu > li > a {\n  display: block;\n  padding: 3px 20px;\n  clear: both;\n  font-weight: normal;\n  line-height: 20px;\n  color: #333333;\n  white-space: nowrap;\n}\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus,\n.dropdown-submenu:hover > a,\n.dropdown-submenu:focus > a {\n  color: #ffffff;\n  text-decoration: none;\n  background-color: #357ebd;\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#428bca), to(#357ebd));\n  background-image: -webkit-linear-gradient(top, #428bca, #357ebd);\n  background-image: -moz-linear-gradient(top, #428bca, #357ebd);\n  background-image: linear-gradient(to bottom, #428bca, #357ebd);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);\n}\n\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  color: #ffffff;\n  text-decoration: none;\n  background-color: #357ebd;\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#428bca), to(#357ebd));\n  background-image: -webkit-linear-gradient(top, #428bca, #357ebd);\n  background-image: -moz-linear-gradient(top, #428bca, #357ebd);\n  background-image: linear-gradient(to bottom, #428bca, #357ebd);\n  background-repeat: repeat-x;\n  outline: 0;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);\n}\n\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  color: #999999;\n}\n\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  text-decoration: none;\n  cursor: default;\n  background-color: transparent;\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n\n.open > .dropdown-menu {\n  display: block;\n}\n\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n  border-top: 0;\n  border-bottom: 4px solid #000;\n  content: \"\";\n}\n\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n  top: auto;\n  bottom: 100%;\n  margin-bottom: 1px;\n}\n\n.dropdown-submenu {\n  position: relative;\n}\n\n.dropdown-submenu > .dropdown-menu {\n  top: 0;\n  left: 100%;\n  margin-top: -6px;\n  margin-left: -1px;\n  border-top-left-radius: 0;\n}\n\n.dropdown-submenu:hover > .dropdown-menu {\n  display: block;\n}\n\n.dropup .dropdown-submenu > .dropdown-menu {\n  top: auto;\n  bottom: 0;\n  margin-top: 0;\n  margin-bottom: -2px;\n  border-bottom-left-radius: 0;\n}\n\n.dropdown-submenu > a:after {\n  display: block;\n  float: right;\n  width: 0;\n  height: 0;\n  margin-top: 5px;\n  margin-right: -10px;\n  border-color: transparent;\n  border-left-color: #cccccc;\n  border-style: solid;\n  border-width: 5px 0 5px 5px;\n  content: \" \";\n}\n\n.dropdown-submenu:hover > a:after {\n  border-left-color: #ffffff;\n}\n\n.dropdown-submenu.pull-left {\n  float: none;\n}\n\n.dropdown-submenu.pull-left > .dropdown-menu {\n  left: -100%;\n  margin-left: 10px;\n  border-top-right-radius: 0;\n}\n\n.dropdown .dropdown-menu .nav-header {\n  padding-right: 20px;\n  padding-left: 20px;\n}\n\n.typeahead {\n  z-index: 1051;\n}\n\n.list-group {\n  margin: 0 0 20px;\n  background-color: #ffffff;\n}\n\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 10px 30px 10px 15px;\n  margin-bottom: -1px;\n  border: 1px solid #dddddd;\n}\n\n.list-group-item:first-child {\n  border-top-right-radius: 4px;\n  border-top-left-radius: 4px;\n}\n\n.list-group-item:last-child {\n  margin-bottom: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n\n.list-group-item-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n\n.list-group-item-text {\n  margin-bottom: 0;\n  line-height: 1.3;\n}\n\na.list-group-item .list-group-item-heading {\n  color: #333;\n}\n\na.list-group-item .list-group-item-text {\n  color: #555;\n}\n\na.list-group-item:hover,\na.list-group-item:focus {\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\n\na.list-group-item.active {\n  z-index: 2;\n  color: #ffffff;\n  background-color: #428bca;\n  border-color: #428bca;\n}\n\na.list-group-item.active .list-group-item-heading {\n  color: inherit;\n}\n\na.list-group-item.active .list-group-item-text {\n  color: #e1edf7;\n}\n\n.list-group-item > .badge,\n.list-group-item > .glyphicon-chevron-right {\n  float: right;\n  margin-right: -15px;\n}\n\n.list-group-item > .glyphicon-chevron-right {\n  margin-right: -15px;\n}\n\n.list-group-item > .glyphicon + .badge {\n  margin-right: 5px;\n}\n\n.panel {\n  padding: 15px;\n  margin-bottom: 20px;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n          box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n\n.panel-heading {\n  padding: 10px 15px;\n  margin: -15px -15px 15px;\n  font-size: 17.5px;\n  font-weight: 500;\n  background-color: #f5f5f5;\n  border-bottom: 1px solid #dddddd;\n  border-top-right-radius: 3px;\n  border-top-left-radius: 3px;\n}\n\n.panel-primary {\n  border-color: #428bca;\n}\n\n.panel-primary .panel-heading {\n  color: #ffffff;\n  background-color: #428bca;\n  border-color: #428bca;\n}\n\n.panel-success {\n  border-color: #d6e9c6;\n}\n\n.panel-success .panel-heading {\n  color: #468847;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n\n.panel-warning {\n  border-color: #fbeed5;\n}\n\n.panel-warning .panel-heading {\n  color: #c09853;\n  background-color: #fcf8e3;\n  border-color: #fbeed5;\n}\n\n.panel-danger {\n  border-color: #eed3d7;\n}\n\n.panel-danger .panel-heading {\n  color: #b94a48;\n  background-color: #f2dede;\n  border-color: #eed3d7;\n}\n\n.panel-info {\n  border-color: #bce8f1;\n}\n\n.panel-info .panel-heading {\n  color: #3a87ad;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n\n.list-group-flush {\n  margin: 15px -15px -15px;\n}\n\n.list-group-flush .list-group-item {\n  border-width: 1px 0;\n}\n\n.list-group-flush .list-group-item:first-child {\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n\n.list-group-flush .list-group-item:last-child {\n  border-bottom: 0;\n}\n\n.well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n\n.well blockquote {\n  border-color: #ddd;\n  border-color: rgba(0, 0, 0, 0.15);\n}\n\n.well-large {\n  padding: 24px;\n  border-radius: 6px;\n}\n\n.well-small {\n  padding: 9px;\n  border-radius: 3px;\n}\n\n.close {\n  float: right;\n  font-size: 20px;\n  font-weight: bold;\n  line-height: 20px;\n  color: #000;\n  text-shadow: 0 1px 0 #ffffff;\n  opacity: 0.2;\n  filter: alpha(opacity=20);\n}\n\n.close:hover,\n.close:focus {\n  color: #000;\n  text-decoration: none;\n  cursor: pointer;\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\n\nbutton.close {\n  padding: 0;\n  cursor: pointer;\n  background: transparent;\n  border: 0;\n  -webkit-appearance: none;\n}\n\n.nav {\n  padding-left: 0;\n  margin-bottom: 0;\n  margin-left: 0;\n  list-style: none;\n}\n\n.nav:before,\n.nav:after {\n  display: table;\n  content: \" \";\n}\n\n.nav:after {\n  clear: both;\n}\n\n.nav:before,\n.nav:after {\n  display: table;\n  content: \" \";\n}\n\n.nav:after {\n  clear: both;\n}\n\n.nav > li {\n  display: block;\n}\n\n.nav > li > a {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n}\n\n.nav > li > a:hover,\n.nav > li > a:focus {\n  text-decoration: none;\n  background-color: #eeeeee;\n}\n\n.nav > li.disabled > a {\n  color: #999999;\n}\n\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n  color: #999999;\n  text-decoration: none;\n  cursor: default;\n  background-color: transparent;\n}\n\n.nav > li + .nav-header {\n  margin-top: 9px;\n}\n\n.nav > .pull-right {\n  float: right;\n}\n\n.nav .divider {\n  height: 2px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n  border-bottom: 1px solid #ffffff;\n}\n\n.nav-tabs {\n  border-bottom: 1px solid #ddd;\n}\n\n.nav-tabs > li {\n  float: left;\n  margin-bottom: -1px;\n}\n\n.nav-tabs > li > a {\n  margin-right: 2px;\n  line-height: 20px;\n  border: 1px solid transparent;\n  border-radius: 4px 4px 0 0;\n}\n\n.nav-tabs > li > a:hover {\n  border-color: #eeeeee #eeeeee #dddddd;\n}\n\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n  color: #555555;\n  cursor: default;\n  background-color: #ffffff;\n  border: 1px solid #ddd;\n  border-bottom-color: transparent;\n}\n\n.nav-tabs.nav-justified {\n  width: 100%;\n  border-bottom: 0;\n}\n\n.nav-tabs.nav-justified > li {\n  display: table-cell;\n  float: none;\n  width: 1%;\n  text-align: center;\n}\n\n.nav-tabs.nav-justified > li > a {\n  margin-right: 0;\n  border-bottom: 1px solid #ddd;\n}\n\n.nav-tabs.nav-justified > .active > a {\n  border-bottom-color: #ffffff;\n}\n\n.nav-pills > li {\n  float: left;\n}\n\n.nav-pills > li > a {\n  border-radius: 5px;\n  padding-top: 5px;\n  padding-bottom: 5px;\n}\n\n.nav-pills > li + li > a {\n  margin-left: 2px;\n}\n\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n  color: #fff;\n  background-color: #428bca;\n}\n\n.nav-stacked > li {\n  float: none;\n}\n\n.nav-stacked > li + li > a {\n  margin-top: 2px;\n  margin-left: 0;\n}\n\n.nav-justified {\n  width: 100%;\n}\n\n.nav-justified > li {\n  display: table-cell;\n  float: none;\n  width: 1%;\n  text-align: center;\n}\n\n.nav-header {\n  display: block;\n  padding: 3px 15px;\n  font-size: 11px;\n  font-weight: bold;\n  line-height: 20px;\n  color: #999999;\n  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);\n  text-transform: uppercase;\n}\n\n.tabbable:before,\n.tabbable:after {\n  display: table;\n  content: \" \";\n}\n\n.tabbable:after {\n  clear: both;\n}\n\n.tabbable:before,\n.tabbable:after {\n  display: table;\n  content: \" \";\n}\n\n.tabbable:after {\n  clear: both;\n}\n\n.tab-content > .tab-pane,\n.pill-content > .pill-pane {\n  display: none;\n}\n\n.tab-content > .active,\n.pill-content > .active {\n  display: block;\n}\n\n/*\n// Prevent IE8 from misplacing imgs\n// See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n.nav > li > a > img {\n  max-width: none;\n}\n\n// Dropdowns\n// -------------------------\n\n.nav-tabs .dropdown-menu {\n  // Remove the top rounded corners here since there is a hard edge above the menu\n  .border-top-radius(0);\n}\n\n// Default dropdown links\n// -------------------------\n// Make carets use linkColor to start\n.nav .dropdown-toggle .caret {\n  border-top-color: @link-color;\n  border-bottom-color: @link-color;\n  margin-top: 8px;\n}\n.nav .dropdown-toggle:hover .caret {\n  border-top-color: @link-hover-color;\n  border-bottom-color: @link-hover-color;\n}\n\n// Active dropdown links\n// -------------------------\n.nav .active .dropdown-toggle .caret {\n  border-top-color: #fff;\n  border-bottom-color: #fff;\n}\n.nav-tabs .active .dropdown-toggle .caret {\n  border-top-color: @gray;\n  border-bottom-color: @gray;\n}\n\n// Active:hover dropdown links\n// -------------------------\n.nav > .dropdown.active > a:hover {\n  cursor: pointer;\n}\n\n// Open dropdowns\n// -------------------------\n.nav-tabs .open .dropdown-toggle,\n.nav-pills .open .dropdown-toggle,\n.nav > li.dropdown.open.active > a:hover {\n  color: #fff;\n  background-color: @gray-light;\n  border-color: @gray-light;\n}\n.nav li.dropdown.open .caret,\n.nav li.dropdown.open.active .caret,\n.nav li.dropdown.open a:hover .caret {\n  border-top-color: #fff;\n  border-bottom-color: #fff;\n  .opacity(1);\n}\n\n// Dropdowns in stacked tabs\n.tabs-stacked .open > a:hover {\n  border-color: @gray-light;\n}\n\n*/\n\n.navbar {\n  position: relative;\n  padding: 10px 15px;\n  background-color: #eeeeee;\n  border-radius: 4px;\n}\n\n.navbar:before,\n.navbar:after {\n  display: table;\n  content: \" \";\n}\n\n.navbar:after {\n  clear: both;\n}\n\n.navbar:before,\n.navbar:after {\n  display: table;\n  content: \" \";\n}\n\n.navbar:after {\n  clear: both;\n}\n\n.navbar .nav {\n  margin-top: 15px;\n}\n\n.navbar .nav > li > a {\n  padding-top: 15px;\n  padding-bottom: 15px;\n  line-height: 20px;\n  color: #777777;\n}\n\n.navbar .nav > li > a:hover,\n.navbar .nav > li > a:focus {\n  color: #333333;\n  background-color: transparent;\n}\n\n.navbar .nav > .active > a,\n.navbar .nav > .active > a:hover,\n.navbar .nav > .active > a:focus {\n  color: #555555;\n  background-color: #d5d5d5;\n}\n\n.navbar .nav > .disabled > a,\n.navbar .nav > .disabled > a:hover,\n.navbar .nav > .disabled > a:focus {\n  color: #cccccc;\n  background-color: transparent;\n}\n\n.navbar-static-top {\n  border-radius: 0;\n}\n\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: 1030;\n  border-radius: 0;\n}\n\n.navbar-fixed-top {\n  top: 0;\n}\n\n.navbar-fixed-bottom {\n  bottom: 0;\n}\n\n.navbar-brand {\n  display: block;\n  max-width: 200px;\n  padding: 7px 15px;\n  margin-right: auto;\n  margin-left: auto;\n  font-size: 18px;\n  font-weight: 500;\n  line-height: 20px;\n  color: #777777;\n  text-align: center;\n}\n\n.navbar-brand:hover,\n.navbar-brand:focus {\n  color: #5e5e5e;\n  text-decoration: none;\n  background-color: transparent;\n}\n\n.navbar-toggle {\n  position: absolute;\n  top: 10px;\n  right: 10px;\n  padding: 8px 12px;\n  background-color: transparent;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n}\n\n.navbar-toggle:hover,\n.navbar-toggle:focus {\n  background-color: #ddd;\n}\n\n.navbar-toggle .icon-bar {\n  display: block;\n  width: 22px;\n  height: 2px;\n  background-color: #ccc;\n  border-radius: 1px;\n}\n\n.navbar-toggle .icon-bar + .icon-bar {\n  margin-top: 4px;\n}\n\n.navbar .nav > .divider {\n  height: 2px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e1e1e1;\n  border-bottom: 1px solid #fbfbfb;\n}\n\n.navbar-form {\n  margin-top: 8px;\n  margin-bottom: 8px;\n}\n\n.navbar .nav > li > .dropdown-menu {\n  margin-top: 0;\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n\n.navbar-fixed-bottom .nav > li > .dropdown-menu {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n\n.navbar .nav li.dropdown > a:hover .caret,\n.navbar .nav li.dropdown > a:focus .caret {\n  border-top-color: #333333;\n  border-bottom-color: #333333;\n}\n\n.navbar .nav li.dropdown.open > .dropdown-toggle,\n.navbar .nav li.dropdown.active > .dropdown-toggle,\n.navbar .nav li.dropdown.open.active > .dropdown-toggle {\n  color: #555555;\n  background-color: #d5d5d5;\n}\n\n.navbar .nav li.dropdown > .dropdown-toggle .caret {\n  border-top-color: #777777;\n  border-bottom-color: #777777;\n}\n\n.navbar .nav li.dropdown.open > .dropdown-toggle .caret,\n.navbar .nav li.dropdown.active > .dropdown-toggle .caret,\n.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret {\n  border-top-color: #555555;\n  border-bottom-color: #555555;\n}\n\n.navbar .pull-right > li > .dropdown-menu,\n.navbar .nav > li > .dropdown-menu.pull-right {\n  right: 0;\n  left: auto;\n}\n\n.navbar-inverse {\n  background-color: #222222;\n}\n\n.navbar-inverse .navbar-brand {\n  color: #999999;\n}\n\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n  color: #ffffff;\n  background-color: transparent;\n}\n\n.navbar-inverse .navbar-text {\n  color: #999999;\n}\n\n.navbar-inverse .nav > li > a {\n  color: #999999;\n}\n\n.navbar-inverse .nav > li > a:hover,\n.navbar-inverse .nav > li > a:focus {\n  color: #ffffff;\n  background-color: transparent;\n}\n\n.navbar-inverse .nav > .active > a,\n.navbar-inverse .nav > .active > a:hover,\n.navbar-inverse .nav > .active > a:focus {\n  color: #ffffff;\n  background-color: #080808;\n}\n\n.navbar-inverse .nav > .disabled > a,\n.navbar-inverse .nav > .disabled > a:hover,\n.navbar-inverse .nav > .disabled > a:focus {\n  color: #444444;\n  background-color: transparent;\n}\n\n.navbar-inverse .navbar-toggle {\n  border-color: #333;\n}\n\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n  background-color: #333;\n}\n\n.navbar-inverse .navbar-toggle .icon-bar {\n  background-color: #fff;\n}\n\n.navbar-inverse .nav > .divider {\n  background-color: #151515;\n  border-bottom-color: #2f2f2f;\n}\n\n.navbar-inverse .nav li.dropdown.open > .dropdown-toggle,\n.navbar-inverse .nav li.dropdown.active > .dropdown-toggle,\n.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle {\n  color: #ffffff;\n  background-color: #080808;\n}\n\n.navbar-inverse .nav li.dropdown > a:hover .caret {\n  border-top-color: #ffffff;\n  border-bottom-color: #ffffff;\n}\n\n.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret {\n  border-top-color: #999999;\n  border-bottom-color: #999999;\n}\n\n.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret,\n.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret,\n.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret {\n  border-top-color: #ffffff;\n  border-bottom-color: #ffffff;\n}\n\n@media screen and (min-width: 768px) {\n  .navbar {\n    padding-top: 0;\n    padding-bottom: 0;\n  }\n  .navbar-brand {\n    float: left;\n    padding-top: 15px;\n    padding-bottom: 15px;\n    margin-left: -10px;\n  }\n  .navbar .nav {\n    float: left;\n    margin-top: 0;\n  }\n  .navbar .nav:before,\n  .navbar .nav:after {\n    display: table;\n    content: \" \";\n  }\n  .navbar .nav:after {\n    clear: both;\n  }\n  .navbar .nav:before,\n  .navbar .nav:after {\n    display: table;\n    content: \" \";\n  }\n  .navbar .nav:after {\n    clear: both;\n  }\n  .navbar .nav.pull-right {\n    float: right;\n  }\n  .navbar .nav > li {\n    float: left;\n  }\n  .navbar .nav > .divider {\n    width: 1px;\n    height: 30px;\n    margin: 10px 9px;\n    border-right: 1px solid #fbfbfb;\n    border-bottom: 0;\n  }\n  .navbar-inverse .nav > .divider {\n    border-right-color: #2f2f2f;\n  }\n  .navbar-fixed-left {\n    padding-right: 0;\n    padding-left: 0;\n  }\n  .navbar-fixed-left .navbar-brand,\n  .navbar-fixed-left .nav,\n  .navbar-fixed-left .nav > li {\n    float: none;\n  }\n  .navbar-toggle {\n    position: relative;\n    top: auto;\n    left: auto;\n    display: none;\n  }\n  .nav-collapse.collapse {\n    height: auto !important;\n    overflow: visible !important;\n  }\n}\n\n/*\n\n// Janky solution for now to account for links outside the .nav\n// -------------------------\n.navbar-link {\n  color: @navbar-link-color;\n  &:hover {\n    color: @navbar-link-hover-color;\n  }\n}\n\n// Buttons in navbar\n// -------------------------\n.navbar .btn,\n.navbar .btn-group {\n  .navbarVerticalAlign(30px); // Vertically center in navbar\n}\n.navbar .btn-group .btn,\n.navbar .input-prepend .btn,\n.navbar .input-append .btn {\n  margin-top: 0; // then undo the margin here so we don't accidentally double it\n}\n\n// Navbar forms\n// -------------------------\n.navbar-form {\n  margin-bottom: 0; // remove default bottom margin\n  .clearfix();\n  input,\n  select,\n  .radio,\n  .checkbox {\n    .navbarVerticalAlign(30px); // Vertically center in navbar\n  }\n  input,\n  select,\n  .btn {\n    display: inline-block;\n    margin-bottom: 0;\n  }\n  input[type=\"image\"],\n  input[type=\"checkbox\"],\n  input[type=\"radio\"] {\n    margin-top: 3px;\n  }\n  .input-append,\n  .input-prepend {\n    margin-top: 5px;\n    white-space: nowrap; // preven two  items from separating within a .navbar-form that has .pull-left\n    input {\n      margin-top: 0; // remove the margin on top since it's on the parent\n    }\n  }\n}\n\n*/\n\n.btn .caret {\n  border-top-color: #ffffff;\n}\n\n.dropup .btn .caret {\n  border-bottom-color: #ffffff;\n}\n\n.btn-group {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle;\n}\n\n.btn-group > .btn {\n  position: relative;\n  float: left;\n}\n\n.btn-group > .btn + btn {\n  margin-left: -1px;\n}\n\n.btn-group > .btn:hover,\n.btn-group > .btn:active {\n  z-index: 2;\n}\n\n.btn-toolbar:before,\n.btn-toolbar:after {\n  display: table;\n  content: \" \";\n}\n\n.btn-toolbar:after {\n  clear: both;\n}\n\n.btn-toolbar:before,\n.btn-toolbar:after {\n  display: table;\n  content: \" \";\n}\n\n.btn-toolbar:after {\n  clear: both;\n}\n\n.btn-toolbar .btn-group {\n  float: left;\n}\n\n.btn-toolbar > .btn + .btn,\n.btn-toolbar > .btn-group + .btn,\n.btn-toolbar > .btn + .btn-group,\n.btn-toolbar > .btn-group + .btn-group {\n  margin-left: 5px;\n}\n\n.btn-group > .btn {\n  position: relative;\n  border-radius: 0;\n}\n\n.btn-group > .btn:first-child {\n  margin-left: 0;\n  border-bottom-left-radius: 4px;\n  border-top-left-radius: 4px;\n}\n\n.btn-group > .btn:last-child,\n.btn-group > .dropdown-toggle {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n\n.btn-group > .btn.large:first-child {\n  margin-left: 0;\n  border-bottom-left-radius: 6px;\n  border-top-left-radius: 6px;\n}\n\n.btn-group > .btn.large:last-child,\n.btn-group > .large.dropdown-toggle {\n  border-top-right-radius: 6px;\n  border-bottom-right-radius: 6px;\n}\n\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n\n.btn-group > .btn + .dropdown-toggle {\n  padding-right: 8px;\n  padding-left: 8px;\n}\n\n.btn-group > .btn-mini + .dropdown-toggle {\n  padding-right: 5px;\n  padding-left: 5px;\n}\n\n.btn-group > .btn-large + .dropdown-toggle {\n  padding-right: 12px;\n  padding-left: 12px;\n}\n\n.btn-group.open .dropdown-toggle {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n\n.btn .caret {\n  margin-top: 8px;\n  margin-left: 0;\n}\n\n.btn-large .caret {\n  border-width: 5px;\n}\n\n.dropup .btn-large .caret {\n  border-bottom-width: 5px;\n}\n\n.btn-group-vertical > .btn {\n  display: block;\n  float: none;\n  width: 100%;\n  max-width: 100%;\n}\n\n.btn-group-vertical .btn:first-child {\n  border-radius: 0;\n  border-top-right-radius: 4px;\n  border-top-left-radius: 4px;\n}\n\n.btn-group-vertical .btn:last-child {\n  border-radius: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n\n.btn-group-vertical .btn-large:first-child {\n  border-top-right-radius: 6px;\n  border-top-left-radius: 6px;\n}\n\n.btn-group-vertical .btn-large:last-child {\n  border-bottom-right-radius: 6px;\n  border-bottom-left-radius: 6px;\n}\n\n.btn-group-justified {\n  display: table;\n  width: 100%;\n}\n\n.btn-group-justified .btn {\n  display: table-cell;\n  float: none;\n  width: 1%;\n}\n\n.btn-group[data-toggle=\"buttons-radio\"] > .btn > input[type=\"radio\"],\n.btn-group[data-toggle=\"buttons-checkbox\"] > .btn > input[type=\"checkbox\"] {\n  display: none;\n}\n\n.breadcrumb {\n  padding: 8px 15px;\n  margin: 0 0 20px;\n  list-style: none;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n}\n\n.breadcrumb > li {\n  display: inline-block;\n  text-shadow: 0 1px 0 #fff;\n}\n\n.breadcrumb > li:after {\n  display: inline-block;\n  padding: 0 5px;\n  color: #ccc;\n  content: \"\\00a0 /\";\n}\n\n.breadcrumb > li:last-child:after {\n  content: \"\";\n}\n\n.breadcrumb > .active {\n  color: #999999;\n}\n\n.pagination {\n  display: inline-block;\n  margin: 20px 0;\n  border-radius: 4px;\n}\n\n.pagination > li {\n  display: inline;\n}\n\n.pagination > li > a,\n.pagination > li > span {\n  float: left;\n  padding: 4px 12px;\n  line-height: 20px;\n  text-decoration: none;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-left-width: 0;\n}\n\n.pagination > li > a:hover,\n.pagination > li > a:focus,\n.pagination > .active > a,\n.pagination > .active > span {\n  background-color: #f5f5f5;\n}\n\n.pagination > .active > a,\n.pagination > .active > span {\n  color: #999999;\n  cursor: default;\n}\n\n.pagination > .disabled > span,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n  color: #999999;\n  cursor: default;\n  background-color: #ffffff;\n}\n\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n  border-left-width: 1px;\n  border-bottom-left-radius: 4px;\n  border-top-left-radius: 4px;\n}\n\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n\n.pagination-large > li > a,\n.pagination-large > li > span {\n  padding: 11px 14px;\n  font-size: 17.5px;\n}\n\n.pagination-large > li:first-child > a,\n.pagination-large > li:first-child > span {\n  border-bottom-left-radius: 6px;\n  border-top-left-radius: 6px;\n}\n\n.pagination-large > li:last-child > a,\n.pagination-large > li:last-child > span {\n  border-top-right-radius: 6px;\n  border-bottom-right-radius: 6px;\n}\n\n.pagination-mini > li:first-child > a,\n.pagination-small > li:first-child > a,\n.pagination-mini > li:first-child > span,\n.pagination-small > li:first-child > span {\n  border-bottom-left-radius: 3px;\n  border-top-left-radius: 3px;\n}\n\n.pagination-mini > li:last-child > a,\n.pagination-small > li:last-child > a,\n.pagination-mini > li:last-child > span,\n.pagination-small > li:last-child > span {\n  border-top-right-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n\n.pagination-small > li > a,\n.pagination-small > li > span {\n  padding: 2px 10px;\n  font-size: 11.9px;\n}\n\n.pagination-mini > li > a,\n.pagination-mini > li > span {\n  padding: 0 6px;\n  font-size: 10.5px;\n}\n\n.pager {\n  margin: 20px 0;\n  text-align: center;\n  list-style: none;\n}\n\n.pager:before,\n.pager:after {\n  display: table;\n  content: \" \";\n}\n\n.pager:after {\n  clear: both;\n}\n\n.pager:before,\n.pager:after {\n  display: table;\n  content: \" \";\n}\n\n.pager:after {\n  clear: both;\n}\n\n.pager li {\n  display: inline;\n}\n\n.pager li > a,\n.pager li > span {\n  display: inline-block;\n  padding: 5px 14px;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-radius: 15px;\n}\n\n.pager li > a:hover,\n.pager li > a:focus {\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\n\n.pager .next > a,\n.pager .next > span {\n  float: right;\n}\n\n.pager .previous > a,\n.pager .previous > span {\n  float: left;\n}\n\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n  color: #999999;\n  cursor: default;\n  background-color: #ffffff;\n}\n\n.modal-open {\n  overflow: hidden;\n}\n\n.modal {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1040;\n  display: none;\n  overflow: auto;\n  overflow-y: scroll;\n  -webkit-overflow-scrolling: touch;\n}\n\n.modal.fade {\n  top: -25%;\n  -webkit-transition: opacity 0.3s linear, top 0.3s ease-out;\n     -moz-transition: opacity 0.3s linear, top 0.3s ease-out;\n       -o-transition: opacity 0.3s linear, top 0.3s ease-out;\n          transition: opacity 0.3s linear, top 0.3s ease-out;\n}\n\n.modal.fade.in {\n  top: 0;\n}\n\n.modal-dialog {\n  position: relative;\n  top: 0;\n  right: 0;\n  left: 0;\n  z-index: 1050;\n  width: auto;\n  padding: 10px;\n}\n\n.modal-content {\n  position: relative;\n  background-color: #fff;\n  border: 1px solid #999;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 6px;\n  outline: none;\n  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n          box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n  -webkit-background-clip: padding-box;\n     -moz-background-clip: padding-box;\n          background-clip: padding-box;\n}\n\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1030;\n  background-color: #000;\n}\n\n.modal-backdrop.fade {\n  opacity: 0;\n  filter: alpha(opacity=0);\n}\n\n.modal-backdrop.fade.in {\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\n\n.modal-header {\n  min-height: 35px;\n  padding: 15px;\n  border-bottom: 1px solid #e5e5e5;\n}\n\n.modal-header .close {\n  margin-top: -2px;\n}\n\n.modal-title {\n  margin: 0;\n  line-height: 20px;\n}\n\n.modal-body {\n  position: relative;\n  padding: 20px;\n}\n\n.modal-footer {\n  padding: 19px 20px 20px;\n  margin-top: 15px;\n  text-align: right;\n  border-top: 1px solid #e5e5e5;\n}\n\n.modal-footer:before,\n.modal-footer:after {\n  display: table;\n  content: \" \";\n}\n\n.modal-footer:after {\n  clear: both;\n}\n\n.modal-footer:before,\n.modal-footer:after {\n  display: table;\n  content: \" \";\n}\n\n.modal-footer:after {\n  clear: both;\n}\n\n.modal-footer .btn + .btn {\n  margin-bottom: 0;\n  margin-left: 5px;\n}\n\n.modal-footer .btn-group .btn + .btn {\n  margin-left: -1px;\n}\n\n.modal-footer .btn-block + .btn-block {\n  margin-left: 0;\n}\n\n@media screen and (min-width: 768px) {\n  .modal-dialog {\n    right: auto;\n    left: 50%;\n    width: 560px;\n    padding-top: 30px;\n    padding-bottom: 30px;\n    margin-left: -280px;\n  }\n  .modal-content {\n    -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n  }\n}\n\n.tooltip {\n  position: absolute;\n  z-index: 1030;\n  display: block;\n  font-size: 11px;\n  line-height: 1.4;\n  opacity: 0;\n  filter: alpha(opacity=0);\n  visibility: visible;\n}\n\n.tooltip.in {\n  opacity: 1;\n  filter: alpha(opacity=100);\n}\n\n.tooltip.top {\n  padding: 5px 0;\n  margin-top: -3px;\n}\n\n.tooltip.right {\n  padding: 0 5px;\n  margin-left: 3px;\n}\n\n.tooltip.bottom {\n  padding: 5px 0;\n  margin-top: 3px;\n}\n\n.tooltip.left {\n  padding: 0 5px;\n  margin-left: -3px;\n}\n\n.tooltip-inner {\n  max-width: 200px;\n  padding: 3px 8px;\n  color: #ffffff;\n  text-align: center;\n  text-decoration: none;\n  background-color: rgba(0, 0, 0, 0.9);\n  border-radius: 4px;\n}\n\n.tooltip-arrow {\n  position: absolute;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n\n.tooltip.top .tooltip-arrow {\n  bottom: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-top-color: rgba(0, 0, 0, 0.9);\n  border-width: 5px 5px 0;\n}\n\n.tooltip.right .tooltip-arrow {\n  top: 50%;\n  left: 0;\n  margin-top: -5px;\n  border-right-color: rgba(0, 0, 0, 0.9);\n  border-width: 5px 5px 5px 0;\n}\n\n.tooltip.left .tooltip-arrow {\n  top: 50%;\n  right: 0;\n  margin-top: -5px;\n  border-left-color: rgba(0, 0, 0, 0.9);\n  border-width: 5px 0 5px 5px;\n}\n\n.tooltip.bottom .tooltip-arrow {\n  top: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-bottom-color: rgba(0, 0, 0, 0.9);\n  border-width: 0 5px 5px;\n}\n\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 1010;\n  display: none;\n  max-width: 276px;\n  padding: 1px;\n  text-align: left;\n  white-space: normal;\n  background-color: #ffffff;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 6px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n          box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  background-clip: padding-box;\n  -webkit-bg-clip: padding-box;\n     -moz-bg-clip: padding;\n}\n\n.popover.top {\n  margin-top: -10px;\n}\n\n.popover.right {\n  margin-left: 10px;\n}\n\n.popover.bottom {\n  margin-top: 10px;\n}\n\n.popover.left {\n  margin-left: -10px;\n}\n\n.popover-title {\n  padding: 8px 14px;\n  margin: 0;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 18px;\n  background-color: #f7f7f7;\n  border-bottom: 1px solid #ebebeb;\n  border-radius: 5px 5px 0 0;\n}\n\n.popover-title:empty {\n  display: none;\n}\n\n.popover-content {\n  padding: 9px 14px;\n}\n\n.popover .arrow,\n.popover .arrow:after {\n  position: absolute;\n  display: block;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n\n.popover .arrow {\n  border-width: 11px;\n}\n\n.popover .arrow:after {\n  border-width: 10px;\n  content: \"\";\n}\n\n.popover.top .arrow {\n  bottom: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-top-color: #999;\n  border-top-color: rgba(0, 0, 0, 0.25);\n  border-bottom-width: 0;\n}\n\n.popover.top .arrow:after {\n  bottom: 1px;\n  margin-left: -10px;\n  border-top-color: #ffffff;\n  border-bottom-width: 0;\n}\n\n.popover.right .arrow {\n  top: 50%;\n  left: -11px;\n  margin-top: -11px;\n  border-right-color: #999;\n  border-right-color: rgba(0, 0, 0, 0.25);\n  border-left-width: 0;\n}\n\n.popover.right .arrow:after {\n  bottom: -10px;\n  left: 1px;\n  border-right-color: #ffffff;\n  border-left-width: 0;\n}\n\n.popover.bottom .arrow {\n  top: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-bottom-color: #999;\n  border-bottom-color: rgba(0, 0, 0, 0.25);\n  border-top-width: 0;\n}\n\n.popover.bottom .arrow:after {\n  top: 1px;\n  margin-left: -10px;\n  border-bottom-color: #ffffff;\n  border-top-width: 0;\n}\n\n.popover.left .arrow {\n  top: 50%;\n  right: -11px;\n  margin-top: -11px;\n  border-left-color: #999;\n  border-left-color: rgba(0, 0, 0, 0.25);\n  border-right-width: 0;\n}\n\n.popover.left .arrow:after {\n  right: 1px;\n  bottom: -10px;\n  border-left-color: #ffffff;\n  border-right-width: 0;\n}\n\n.alert {\n  padding: 8px 15px 8px 14px;\n  margin-bottom: 20px;\n  /*color: #c09853;*/\n  background-color: #fcfcfc;\n  border: 1px solid #e6e6e6;\n  border-radius: 4px;\n}\n\n.alert h4 {\n  margin-top: 0;\n  color: inherit;\n}\n\n.alert hr {\n  border-top-color: #f8e5be;\n}\n\n.alert > a,\n.alert > p > a {\n  font-weight: 500;\n  color: #a47e3c;\n}\n\n.alert .close {\n  position: relative;\n  top: -2px;\n  /*right: -21px;*/ /*Décalage lors de l'ouverture d'un tatam*/\n  color: inherit;\n}\n\n.alert-success {\n  color: #468847;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n\n.alert-success hr {\n  border-top-color: #c9e2b3;\n}\n\n.alert-success > a,\n.alert-success > p > a {\n  color: #356635;\n}\n\n.alert-danger {\n  color: #b94a48;\n  background-color: #f2dede;\n  border-color: #eed3d7;\n}\n\n.alert-danger hr {\n  border-top-color: #e6c1c7;\n}\n\n.alert-danger > a,\n.alert-danger > p > a {\n  color: #953b39;\n}\n\n.alert-info {\n  color: #3a87ad;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n\n.alert-info hr {\n  border-top-color: #a6e1ec;\n}\n\n.alert-info > a,\n.alert-info > p > a {\n  color: #2d6987;\n}\n\n.alert-block {\n  padding-top: 14px;\n  padding-bottom: 14px;\n}\n\n.alert-block > p,\n.alert-block > ul {\n  margin-bottom: 0;\n}\n\n.alert-block p + p {\n  margin-top: 5px;\n}\n\n.thumbnail,\n.img-thumbnail {\n  padding: 4px;\n  line-height: 20px;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-radius: 4px;\n  -webkit-transition: all 0.2s ease-in-out;\n     -moz-transition: all 0.2s ease-in-out;\n       -o-transition: all 0.2s ease-in-out;\n          transition: all 0.2s ease-in-out;\n}\n\n.thumbnail {\n  display: block;\n}\n\n.img-thumbnail {\n  display: inline-block;\n}\n\na.thumbnail:hover,\na.thumbnail:focus {\n  border-color: #428bca;\n}\n\n.thumbnail > img {\n  display: block;\n  max-width: 100%;\n  margin-right: auto;\n  margin-left: auto;\n}\n\n.thumbnail .caption {\n  padding: 9px;\n  color: #333333;\n}\n\n.media,\n.media-body {\n  overflow: hidden;\n  zoom: 1;\n}\n\n.media,\n.media .media {\n  margin-top: 15px;\n}\n\n.media:first-child {\n  margin-top: 0;\n}\n\n.media-object {\n  display: block;\n}\n\n.media-heading {\n  margin: 0 0 5px;\n}\n\n.media > .pull-left {\n  margin-right: 10px;\n}\n\n.media > .pull-right {\n  margin-left: 10px;\n}\n\n.media-list {\n  margin-left: 0;\n  list-style: none;\n}\n\n.label {\n  padding: .25em .6em;\n  font-size: 75%;\n  font-weight: 500;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  background-color: #999999;\n  border-radius: .25em;\n}\n\na.label:hover,\na.label:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n\n.label-danger {\n  background-color: #d9534f;\n}\n\n.label-danger[href] {\n  background-color: #c9302c;\n}\n\n.label-warning {\n  background-color: #f0ad4e;\n}\n\n.label-warning[href] {\n  background-color: #ec971f;\n}\n\n.label-success {\n  background-color: #5cb85c;\n}\n\n.label-success[href] {\n  background-color: #449d44;\n}\n\n.label-info {\n  background-color: #5bc0de;\n}\n\n.label-info[href] {\n  background-color: #31b0d5;\n}\n\n.badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: 12px;\n  font-weight: bold;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  background-color: #999999;\n  border-radius: 10px;\n}\n\n.badge:empty {\n  display: none;\n}\n\na.badge:hover,\na.badge:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n\n.btn .badge {\n  position: relative;\n  top: -1px;\n}\n\n.btn-mini .badge {\n  top: 0;\n}\n\na.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n  color: #428bca;\n  background-color: #fff;\n}\n\n.nav-pills > li > a > .badge {\n  margin-left: 3px;\n}\n\n@-webkit-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n\n@-moz-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n\n@-ms-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n\n@-o-keyframes progress-bar-stripes {\n  from {\n    background-position: 0 0;\n  }\n  to {\n    background-position: 40px 0;\n  }\n}\n\n@keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n\n.progress {\n  height: 20px;\n  margin-bottom: 20px;\n  overflow: hidden;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n          box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n\n.progress-bar {\n  float: left;\n  width: 0;\n  height: 100%;\n  font-size: 12px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n  background-color: #428bca;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n  -webkit-transition: width 0.6s ease;\n     -moz-transition: width 0.6s ease;\n       -o-transition: width 0.6s ease;\n          transition: width 0.6s ease;\n}\n\n.progress-striped .progress-bar {\n  background-color: #428bca;\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  -webkit-background-size: 40px 40px;\n     -moz-background-size: 40px 40px;\n       -o-background-size: 40px 40px;\n          background-size: 40px 40px;\n}\n\n.progress.active .progress-bar {\n  -webkit-animation: progress-bar-stripes 2s linear infinite;\n     -moz-animation: progress-bar-stripes 2s linear infinite;\n      -ms-animation: progress-bar-stripes 2s linear infinite;\n       -o-animation: progress-bar-stripes 2s linear infinite;\n          animation: progress-bar-stripes 2s linear infinite;\n}\n\n.progress-bar-danger {\n  background-color: #d9534f;\n}\n\n.progress-striped .progress-bar-danger {\n  background-color: #d9534f;\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n\n.progress-bar-success {\n  background-color: #5cb85c;\n}\n\n.progress-striped .progress-bar-success {\n  background-color: #5cb85c;\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n\n.progress-bar-warning {\n  background-color: #f0ad4e;\n}\n\n.progress-striped .progress-bar-warning {\n  background-color: #f0ad4e;\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n\n.progress-bar-info {\n  background-color: #5bc0de;\n}\n\n.progress-striped .progress-bar-info {\n  background-color: #5bc0de;\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n\n.accordion {\n  margin-bottom: 20px;\n}\n\n.accordion-group {\n  margin-bottom: 2px;\n  border: 1px solid #e5e5e5;\n  border-radius: 4px;\n}\n\n.accordion-heading {\n  border-bottom: 0;\n}\n\n.accordion-heading .accordion-toggle {\n  display: block;\n  padding: 8px 15px;\n}\n\n.accordion-toggle {\n  cursor: pointer;\n}\n\n.accordion-inner {\n  padding: 9px 15px;\n  border-top: 1px solid #e5e5e5;\n}\n\n.carousel {\n  position: relative;\n}\n\n.carousel-inner {\n  position: relative;\n  width: 100%;\n  overflow: hidden;\n}\n\n.carousel-inner > .item {\n  position: relative;\n  display: none;\n  -webkit-transition: 0.6s ease-in-out left;\n     -moz-transition: 0.6s ease-in-out left;\n       -o-transition: 0.6s ease-in-out left;\n          transition: 0.6s ease-in-out left;\n}\n\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  display: block;\n  line-height: 1;\n}\n\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  display: block;\n}\n\n.carousel-inner > .active {\n  left: 0;\n}\n\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  position: absolute;\n  top: 0;\n  width: 100%;\n}\n\n.carousel-inner > .next {\n  left: 100%;\n}\n\n.carousel-inner > .prev {\n  left: -100%;\n}\n\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n  left: 0;\n}\n\n.carousel-inner > .active.left {\n  left: -100%;\n}\n\n.carousel-inner > .active.right {\n  left: 100%;\n}\n\n.carousel-control {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  width: 15%;\n  font-size: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\n\n.carousel-control.left {\n  background-color: rgba(0, 0, 0, 0.0001);\n  background-color: transparent;\n  background-image: -webkit-gradient(linear, 0 0, 100% 0, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001)));\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.0001));\n  background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.0001));\n  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.0001));\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n\n.carousel-control.right {\n  right: 0;\n  left: auto;\n  background-color: rgba(0, 0, 0, 0.5);\n  background-color: transparent;\n  background-image: -webkit-gradient(linear, 0 0, 100% 0, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5)));\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001), rgba(0, 0, 0, 0.5));\n  background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.0001), rgba(0, 0, 0, 0.5));\n  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001), rgba(0, 0, 0, 0.5));\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n\n.carousel-control:hover,\n.carousel-control:focus {\n  color: #fff;\n  text-decoration: none;\n  opacity: 0.9;\n  filter: alpha(opacity=90);\n}\n\n.carousel-control .glyphicon {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  z-index: 5;\n  display: inline-block;\n  width: 20px;\n  height: 20px;\n  margin-top: -10px;\n  margin-left: -10px;\n}\n\n.carousel-indicators {\n  position: absolute;\n  bottom: 20px;\n  left: 50%;\n  z-index: 5;\n  width: 100px;\n  margin: 0 0 0 -50px;\n  text-align: center;\n  list-style: none;\n}\n\n.carousel-indicators li {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  margin-right: 0;\n  margin-left: 0;\n  text-indent: -999px;\n  cursor: pointer;\n  border: 1px solid #fff;\n  border-radius: 5px;\n}\n\n.carousel-indicators .active {\n  background-color: #fff;\n}\n\n.carousel-caption {\n  position: absolute;\n  right: 15%;\n  bottom: 20px;\n  left: 15%;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n\n.carousel-caption .btn {\n  text-shadow: none;\n}\n\n@media screen and (min-width: 768px) {\n  .carousel-control .glyphicon {\n    width: 30px;\n    height: 30px;\n    margin-top: -15px;\n    margin-left: -15px;\n    font-size: 30px;\n  }\n  .carousel-caption {\n    right: 20%;\n    left: 20%;\n    padding-bottom: 30px;\n  }\n}\n\n.jumbotron {\n  padding: 30px;\n  margin-bottom: 30px;\n  font-size: 21px;\n  font-weight: 200;\n  line-height: 30px;\n  color: inherit;\n  background-color: #eeeeee;\n}\n\n.jumbotron h1 {\n  line-height: 1;\n  color: inherit;\n}\n\n.jumbotron p {\n  line-height: 1.4;\n}\n\n@media screen and (min-width: 768px) {\n  .jumbotron {\n    padding: 50px 60px;\n    border-radius: 6px;\n  }\n  .jumbotron h1 {\n    font-size: 60px;\n  }\n}\n\n.clearfix:before,\n.clearfix:after {\n  display: table;\n  content: \" \";\n}\n\n.clearfix:after {\n  clear: both;\n}\n\n.pull-right {\n  float: right;\n}\n\n.pull-left {\n  float: left;\n}\n\n.hide {\n  display: none ;\n}\n\n.show {\n  display: block !important;\n}\n\n.invisible {\n  visibility: hidden;\n}\n\n.text-hide {\n  font: 0/0 a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n\n.affix {\n  position: fixed;\n}\n\n@-ms-viewport {\n  width: device-width;\n}\n\n@media screen and (max-width: 400px) {\n  @-ms-viewport {\n    width: 320px;\n  }\n}\n\n.hidden {\n  display: none;\n  visibility: hidden;\n}\n\n.visible-phone {\n  display: inherit !important;\n}\n\n.visible-tablet {\n  display: none !important;\n}\n\n.visible-desktop {\n  display: none !important;\n}\n\n.hidden-phone {\n  display: none !important;\n}\n\n.hidden-tablet {\n  display: inherit !important;\n}\n\n.hidden-desktop {\n  display: inherit !important;\n}\n\n@media (min-width: 768px) and (max-width: 979px) {\n  .visible-phone {\n    display: none !important;\n  }\n  .visible-tablet {\n    display: inherit !important;\n  }\n  .visible-desktop {\n    display: none !important;\n  }\n  .hidden-phone {\n    display: inherit !important;\n  }\n  .hidden-tablet {\n    display: none !important;\n  }\n  .hidden-desktop {\n    display: inherit !important;\n  }\n}\n\n@media (min-width: 980px) {\n  .visible-phone {\n    display: none !important;\n  }\n  .visible-tablet {\n    display: none !important;\n  }\n  .visible-desktop {\n    display: inherit !important;\n  }\n  .hidden-phone {\n    display: inherit !important;\n  }\n  .hidden-tablet {\n    display: inherit !important;\n  }\n  .hidden-desktop {\n    display: none !important;\n  }\n}\n\n.visible-print {\n  display: none !important;\n}\n\n@media print {\n  .visible-print {\n    display: inherit !important;\n  }\n  \n"
  },
  {
    "path": "web/src/main/webapp/assets/vendor/css/bootstrap/js/bootstrap.js",
    "content": "/* ===================================================\n * bootstrap-transition.js v3.0.0\n * http://twitter.github.com/bootstrap/javascript.html#transitions\n * ===================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ========================================================== */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n  /* CSS TRANSITION SUPPORT (http://www.modernizr.com/)\n   * ======================================================= */\n\n  $(function () {\n\n    $.support.transition = (function () {\n\n      var transitionEnd = (function () {\n\n        var el = document.createElement('bootstrap')\n          , transEndEventNames = {\n               'WebkitTransition' : 'webkitTransitionEnd'\n            ,  'MozTransition'    : 'transitionend'\n            ,  'OTransition'      : 'oTransitionEnd otransitionend'\n            ,  'transition'       : 'transitionend'\n            }\n          , name\n\n        for (name in transEndEventNames){\n          if (el.style[name] !== undefined) {\n            return transEndEventNames[name]\n          }\n        }\n\n      }())\n\n      return transitionEnd && {\n        end: transitionEnd\n      }\n\n    })()\n\n  })\n\n}(window.jQuery);/* ==========================================================\n * bootstrap-alert.js v3.0.0\n * http://twitter.github.com/bootstrap/javascript.html#alerts\n * ==========================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ========================================================== */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* ALERT CLASS DEFINITION\n  * ====================== */\n\n  var dismiss = '[data-dismiss=\"alert\"]'\n    , Alert = function (el) {\n        $(el).on('click', dismiss, this.close)\n      }\n\n  Alert.prototype.close = function (e) {\n    var $this = $(this)\n      , selector = $this.attr('data-target')\n      , $parent\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') //strip for ie7\n    }\n\n    $parent = $(selector)\n\n    e && e.preventDefault()\n\n    $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())\n\n    $parent.trigger(e = $.Event('close'))\n\n    if (e.isDefaultPrevented()) return\n\n    $parent.removeClass('in')\n\n    function removeElement() {\n      $parent\n        .trigger('closed')\n        .remove()\n    }\n\n    $.support.transition && $parent.hasClass('fade') ?\n      $parent.on($.support.transition.end, removeElement) :\n      removeElement()\n  }\n\n\n /* ALERT PLUGIN DEFINITION\n  * ======================= */\n\n  var old = $.fn.alert\n\n  $.fn.alert = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('alert')\n      if (!data) $this.data('alert', (data = new Alert(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  $.fn.alert.Constructor = Alert\n\n\n /* ALERT NO CONFLICT\n  * ================= */\n\n  $.fn.alert.noConflict = function () {\n    $.fn.alert = old\n    return this\n  }\n\n\n /* ALERT DATA-API\n  * ============== */\n\n  $(document).on('click.alert.data-api', dismiss, Alert.prototype.close)\n\n}(window.jQuery);/* ============================================================\n * bootstrap-button.js v3.0.0\n * http://twitter.github.com/bootstrap/javascript.html#buttons\n * ============================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ============================================================ */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* BUTTON PUBLIC CLASS DEFINITION\n  * ============================== */\n\n  var Button = function (element, options) {\n    this.$element = $(element)\n    this.options = $.extend({}, $.fn.button.defaults, options)\n  }\n\n  Button.prototype.setState = function (state) {\n    var d = 'disabled'\n      , $el = this.$element\n      , data = $el.data()\n      , val = $el.is('input') ? 'val' : 'html'\n\n    state = state + 'Text'\n    data.resetText || $el.data('resetText', $el[val]())\n\n    $el[val](data[state] || this.options[state])\n\n    // push to event loop to allow forms to submit\n    setTimeout(function () {\n      state == 'loadingText' ?\n        $el.addClass(d).attr(d, d) :\n        $el.removeClass(d).removeAttr(d)\n    }, 0)\n  }\n\n  Button.prototype.toggle = function () {\n    var $parent = this.$element.closest('[data-toggle=\"buttons-radio\"]')\n\n    $parent && $parent\n      .find('.active')\n      .removeClass('active')\n\n    this.$element.toggleClass('active')\n  }\n\n\n /* BUTTON PLUGIN DEFINITION\n  * ======================== */\n\n  var old = $.fn.button\n\n  $.fn.button = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('button')\n        , options = typeof option == 'object' && option\n      if (!data) $this.data('button', (data = new Button(this, options)))\n      if (option == 'toggle') data.toggle()\n      else if (option) data.setState(option)\n    })\n  }\n\n  $.fn.button.defaults = {\n    loadingText: 'loading...'\n  }\n\n  $.fn.button.Constructor = Button\n\n\n /* BUTTON NO CONFLICT\n  * ================== */\n\n  $.fn.button.noConflict = function () {\n    $.fn.button = old\n    return this\n  }\n\n\n /* BUTTON DATA-API\n  * =============== */\n\n  $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) {\n    var $btn = $(e.target)\n    if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')\n    $btn.button('toggle')\n  })\n\n}(window.jQuery);/* ==========================================================\n * bootstrap-carousel.js v3.0.0\n * http://twitter.github.com/bootstrap/javascript.html#carousel\n * ==========================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ========================================================== */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* CAROUSEL CLASS DEFINITION\n  * ========================= */\n\n  var Carousel = function (element, options) {\n    this.$element = $(element)\n    this.$indicators = this.$element.find('.carousel-indicators')\n    this.options = options\n    this.options.pause == 'hover' && this.$element\n      .on('mouseenter', $.proxy(this.pause, this))\n      .on('mouseleave', $.proxy(this.cycle, this))\n  }\n\n  Carousel.prototype = {\n\n    cycle: function (e) {\n      if (!e) this.paused = false\n      if (this.interval) clearInterval(this.interval);\n      this.options.interval\n        && !this.paused\n        && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))\n      return this\n    }\n\n  , getActiveIndex: function () {\n      this.$active = this.$element.find('.item.active')\n      this.$items = this.$active.parent().children()\n      return this.$items.index(this.$active)\n    }\n\n  , to: function (pos) {\n      var activeIndex = this.getActiveIndex()\n        , that = this\n\n      if (pos > (this.$items.length - 1) || pos < 0) return\n\n      if (this.sliding) {\n        return this.$element.one('slid', function () {\n          that.to(pos)\n        })\n      }\n\n      if (activeIndex == pos) {\n        return this.pause().cycle()\n      }\n\n      return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))\n    }\n\n  , pause: function (e) {\n      if (!e) this.paused = true\n      if (this.$element.find('.next, .prev').length && $.support.transition.end) {\n        this.$element.trigger($.support.transition.end)\n        this.cycle(true)\n      }\n      clearInterval(this.interval)\n      this.interval = null\n      return this\n    }\n\n  , next: function () {\n      if (this.sliding) return\n      return this.slide('next')\n    }\n\n  , prev: function () {\n      if (this.sliding) return\n      return this.slide('prev')\n    }\n\n  , slide: function (type, next) {\n      var $active = this.$element.find('.item.active')\n        , $next = next || $active[type]()\n        , isCycling = this.interval\n        , direction = type == 'next' ? 'left' : 'right'\n        , fallback  = type == 'next' ? 'first' : 'last'\n        , that = this\n        , e\n\n      this.sliding = true\n\n      isCycling && this.pause()\n\n      $next = $next.length ? $next : this.$element.find('.item')[fallback]()\n\n      e = $.Event('slide', {\n        relatedTarget: $next[0]\n      , direction: direction\n      })\n\n      if ($next.hasClass('active')) return\n\n      if (this.$indicators.length) {\n        this.$indicators.find('.active').removeClass('active')\n        this.$element.one('slid', function () {\n          var $nextIndicator = $(that.$indicators.children()[that.getActiveIndex()])\n          $nextIndicator && $nextIndicator.addClass('active')\n        })\n      }\n\n      if ($.support.transition && this.$element.hasClass('slide')) {\n        this.$element.trigger(e)\n        if (e.isDefaultPrevented()) return\n        $next.addClass(type)\n        $next[0].offsetWidth // force reflow\n        $active.addClass(direction)\n        $next.addClass(direction)\n        this.$element.one($.support.transition.end, function () {\n          $next.removeClass([type, direction].join(' ')).addClass('active')\n          $active.removeClass(['active', direction].join(' '))\n          that.sliding = false\n          setTimeout(function () { that.$element.trigger('slid') }, 0)\n        })\n      } else {\n        this.$element.trigger(e)\n        if (e.isDefaultPrevented()) return\n        $active.removeClass('active')\n        $next.addClass('active')\n        this.sliding = false\n        this.$element.trigger('slid')\n      }\n\n      isCycling && this.cycle()\n\n      return this\n    }\n\n  }\n\n\n /* CAROUSEL PLUGIN DEFINITION\n  * ========================== */\n\n  var old = $.fn.carousel\n\n  $.fn.carousel = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('carousel')\n        , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)\n        , action = typeof option == 'string' ? option : options.slide\n      if (!data) $this.data('carousel', (data = new Carousel(this, options)))\n      if (typeof option == 'number') data.to(option)\n      else if (action) data[action]()\n      else if (options.interval) data.pause().cycle()\n    })\n  }\n\n  $.fn.carousel.defaults = {\n    interval: 5000\n  , pause: 'hover'\n  }\n\n  $.fn.carousel.Constructor = Carousel\n\n\n /* CAROUSEL NO CONFLICT\n  * ==================== */\n\n  $.fn.carousel.noConflict = function () {\n    $.fn.carousel = old\n    return this\n  }\n\n /* CAROUSEL DATA-API\n  * ================= */\n\n  $(document).on('click.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {\n    var $this = $(this), href\n      , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) //strip for ie7\n      , options = $.extend({}, $target.data(), $this.data())\n      , slideIndex\n\n    $target.carousel(options)\n\n    if (slideIndex = $this.attr('data-slide-to')) {\n      $target.data('carousel').pause().to(slideIndex).cycle()\n    }\n\n    e.preventDefault()\n  })\n\n}(window.jQuery);/* =============================================================\n * bootstrap-collapse.js v3.0.0\n * http://twitter.github.com/bootstrap/javascript.html#collapse\n * =============================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ============================================================ */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* COLLAPSE PUBLIC CLASS DEFINITION\n  * ================================ */\n\n  var Collapse = function (element, options) {\n    this.$element = $(element)\n    this.options = $.extend({}, $.fn.collapse.defaults, options)\n\n    if (this.options.parent) {\n      this.$parent = $(this.options.parent)\n    }\n\n    this.options.toggle && this.toggle()\n  }\n\n  Collapse.prototype = {\n\n    constructor: Collapse\n\n  , dimension: function () {\n      var hasWidth = this.$element.hasClass('width')\n      return hasWidth ? 'width' : 'height'\n    }\n\n  , show: function () {\n      var dimension\n        , scroll\n        , actives\n        , hasData\n\n      if (this.transitioning || this.$element.hasClass('in')) return\n\n      dimension = this.dimension()\n      scroll = $.camelCase(['scroll', dimension].join('-'))\n      actives = this.$parent && this.$parent.find('> .accordion-group > .in')\n\n      if (actives && actives.length) {\n        hasData = actives.data('collapse')\n        if (hasData && hasData.transitioning) return\n        actives.collapse('hide')\n        hasData || actives.data('collapse', null)\n      }\n\n      this.$element[dimension](0)\n      this.transition('addClass', $.Event('show'), 'shown')\n      $.support.transition && this.$element[dimension](this.$element[0][scroll])\n    }\n\n  , hide: function () {\n      var dimension\n      if (this.transitioning || !this.$element.hasClass('in')) return\n      dimension = this.dimension()\n      this.reset(this.$element[dimension]())\n      this.transition('removeClass', $.Event('hide'), 'hidden')\n      this.$element[dimension](0)\n    }\n\n  , reset: function (size) {\n      var dimension = this.dimension()\n\n      this.$element\n        .removeClass('collapse')\n        [dimension](size || 'auto')\n        [0].offsetWidth\n\n      this.$element[size !== null ? 'addClass' : 'removeClass']('collapse')\n\n      return this\n    }\n\n  , transition: function (method, startEvent, completeEvent) {\n      var that = this\n        , complete = function () {\n            if (startEvent.type == 'show') that.reset()\n            that.transitioning = 0\n            that.$element.trigger(completeEvent)\n          }\n\n      this.$element.trigger(startEvent)\n\n      if (startEvent.isDefaultPrevented()) return\n\n      this.transitioning = 1\n\n      this.$element[method]('in')\n\n      $.support.transition && this.$element.hasClass('collapse') ?\n        this.$element.one($.support.transition.end, complete) :\n        complete()\n    }\n\n  , toggle: function () {\n      this[this.$element.hasClass('in') ? 'hide' : 'show']()\n    }\n\n  }\n\n\n /* COLLAPSE PLUGIN DEFINITION\n  * ========================== */\n\n  var old = $.fn.collapse\n\n  $.fn.collapse = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('collapse')\n        , options = $.extend({}, $.fn.collapse.defaults, $this.data(), typeof option == 'object' && option)\n      if (!data) $this.data('collapse', (data = new Collapse(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.collapse.defaults = {\n    toggle: true\n  }\n\n  $.fn.collapse.Constructor = Collapse\n\n\n /* COLLAPSE NO CONFLICT\n  * ==================== */\n\n  $.fn.collapse.noConflict = function () {\n    $.fn.collapse = old\n    return this\n  }\n\n\n /* COLLAPSE DATA-API\n  * ================= */\n\n  $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) {\n    var $this = $(this), href\n      , target = $this.attr('data-target')\n        || e.preventDefault()\n        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '') //strip for ie7\n      , option = $(target).data('collapse') ? 'toggle' : $this.data()\n    $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed')\n    $(target).collapse(option)\n  })\n\n}(window.jQuery);/* ============================================================\n * bootstrap-dropdown.js v3.0.0\n * http://twitter.github.com/bootstrap/javascript.html#dropdowns\n * ============================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ============================================================ */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* DROPDOWN CLASS DEFINITION\n  * ========================= */\n\n  var toggle = '[data-toggle=dropdown]'\n    , Dropdown = function (element) {\n        var $el = $(element).on('click.dropdown.data-api', this.toggle)\n        $('html').on('click.dropdown.data-api', function () {\n          $el.parent().removeClass('open')\n        })\n      }\n\n  Dropdown.prototype = {\n\n    constructor: Dropdown\n\n  , toggle: function (e) {\n      var $this = $(this)\n        , $parent\n        , isActive\n\n      if ($this.is('.disabled, :disabled')) return\n\n      $parent = getParent($this)\n\n      isActive = $parent.hasClass('open')\n\n      clearMenus()\n\n      if (!isActive) {\n        $parent.toggleClass('open')\n      }\n\n      $this.focus()\n\n      return false\n    }\n\n  , keydown: function (e) {\n      var $this\n        , $items\n        , $active\n        , $parent\n        , isActive\n        , index\n\n      if (!/(38|40|27)/.test(e.keyCode)) return\n\n      $this = $(this)\n\n      e.preventDefault()\n      e.stopPropagation()\n\n      if ($this.is('.disabled, :disabled')) return\n\n      $parent = getParent($this)\n\n      isActive = $parent.hasClass('open')\n\n      if (!isActive || (isActive && e.keyCode == 27)) {\n        if (e.which == 27) $parent.find(toggle).focus()\n        return $this.click()\n      }\n\n      $items = $('[role=menu] li:not(.divider):visible a', $parent)\n\n      if (!$items.length) return\n\n      index = $items.index($items.filter(':focus'))\n\n      if (e.keyCode == 38 && index > 0) index--                                        // up\n      if (e.keyCode == 40 && index < $items.length - 1) index++                        // down\n      if (!~index) index = 0\n\n      $items\n        .eq(index)\n        .focus()\n    }\n\n  }\n\n  function clearMenus() {\n    $(toggle).each(function () {\n      getParent($(this)).removeClass('open')\n    })\n  }\n\n  function getParent($this) {\n    var selector = $this.attr('data-target')\n      , $parent\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\\s]*$)/, '') //strip for ie7\n    }\n\n    $parent = selector && $(selector)\n\n    if (!$parent || !$parent.length) $parent = $this.parent()\n\n    return $parent\n  }\n\n\n  /* DROPDOWN PLUGIN DEFINITION\n   * ========================== */\n\n  var old = $.fn.dropdown\n\n  $.fn.dropdown = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('dropdown')\n      if (!data) $this.data('dropdown', (data = new Dropdown(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  $.fn.dropdown.Constructor = Dropdown\n\n\n /* DROPDOWN NO CONFLICT\n  * ==================== */\n\n  $.fn.dropdown.noConflict = function () {\n    $.fn.dropdown = old\n    return this\n  }\n\n\n  /* APPLY TO STANDARD DROPDOWN ELEMENTS\n   * =================================== */\n\n  $(document)\n    .on('click.dropdown.data-api', clearMenus)\n    .on('click.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })\n    .on('click.dropdown-menu', function (e) { e.stopPropagation() })\n    .on('click.dropdown.data-api'  , toggle, Dropdown.prototype.toggle)\n    .on('keydown.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)\n\n}(window.jQuery);\n/* =========================================================\n * bootstrap-modal.js v3.0.0\n * http://twitter.github.com/bootstrap/javascript.html#modals\n * =========================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ========================================================= */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* MODAL CLASS DEFINITION\n  * ====================== */\n\n  var Modal = function (element, options) {\n    this.options = options\n    this.$element = $(element)\n      .delegate('[data-dismiss=\"modal\"]', 'click.dismiss.modal', $.proxy(this.hide, this))\n    this.options.remote && this.$element.find('.modal-body').load(this.options.remote)\n  }\n\n  Modal.prototype = {\n\n      constructor: Modal\n\n    , toggle: function () {\n        return this[!this.isShown ? 'show' : 'hide']()\n      }\n\n    , show: function () {\n        var that = this\n          , e = $.Event('show')\n\n        this.$element.trigger(e)\n\n        if (this.isShown || e.isDefaultPrevented()) return\n\n        this.isShown = true\n\n        this.escape()\n\n        this.backdrop(function () {\n          var transition = $.support.transition && that.$element.hasClass('fade')\n\n          if (!that.$element.parent().length) {\n            that.$element.appendTo(document.body) //don't move modals dom position\n          }\n\n          that.$element.show()\n\n          if (transition) {\n            that.$element[0].offsetWidth // force reflow\n          }\n\n          that.$element\n            .addClass('in')\n            .attr('aria-hidden', false)\n\n          that.enforceFocus()\n\n          transition ?\n            that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) :\n            that.$element.focus().trigger('shown')\n\n        })\n      }\n\n    , hide: function (e) {\n        e && e.preventDefault()\n\n        var that = this\n\n        e = $.Event('hide')\n\n        this.$element.trigger(e)\n\n        if (!this.isShown || e.isDefaultPrevented()) return\n\n        this.isShown = false\n\n        this.escape()\n\n        $(document).off('focusin.modal')\n\n        this.$element\n          .removeClass('in')\n          .attr('aria-hidden', true)\n\n        $.support.transition && this.$element.hasClass('fade') ?\n          this.hideWithTransition() :\n          this.hideModal()\n      }\n\n    , enforceFocus: function () {\n        var that = this\n        $(document).on('focusin.modal', function (e) {\n          if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {\n            that.$element.focus()\n          }\n        })\n      }\n\n    , escape: function () {\n        var that = this\n        if (this.isShown && this.options.keyboard) {\n          this.$element.on('keyup.dismiss.modal', function ( e ) {\n            e.which == 27 && that.hide()\n          })\n        } else if (!this.isShown) {\n          this.$element.off('keyup.dismiss.modal')\n        }\n      }\n\n    , hideWithTransition: function () {\n        var that = this\n          , timeout = setTimeout(function () {\n              that.$element.off($.support.transition.end)\n              that.hideModal()\n            }, 500)\n\n        this.$element.one($.support.transition.end, function () {\n          clearTimeout(timeout)\n          that.hideModal()\n        })\n      }\n\n    , hideModal: function () {\n        var that = this\n        this.$element.hide()\n        this.backdrop(function () {\n          that.removeBackdrop()\n          that.$element.trigger('hidden')\n        })\n      }\n\n    , removeBackdrop: function () {\n        this.$backdrop && this.$backdrop.remove()\n        this.$backdrop = null\n      }\n\n    , backdrop: function (callback) {\n        var that = this\n          , animate = this.$element.hasClass('fade') ? 'fade' : ''\n\n        if (this.isShown && this.options.backdrop) {\n          var doAnimate = $.support.transition && animate\n\n          this.$backdrop = $('<div class=\"modal-backdrop ' + animate + '\" />')\n            .appendTo(document.body)\n\n          this.$backdrop.click(\n            this.options.backdrop == 'static' ?\n              $.proxy(this.$element[0].focus, this.$element[0])\n            : $.proxy(this.hide, this)\n          )\n\n          if (doAnimate) this.$backdrop[0].offsetWidth // force reflow\n\n          this.$backdrop.addClass('in')\n\n          if (!callback) return\n\n          doAnimate ?\n            this.$backdrop.one($.support.transition.end, callback) :\n            callback()\n\n        } else if (!this.isShown && this.$backdrop) {\n          this.$backdrop.removeClass('in')\n\n          $.support.transition && this.$element.hasClass('fade')?\n            this.$backdrop.one($.support.transition.end, callback) :\n            callback()\n\n        } else if (callback) {\n          callback()\n        }\n      }\n  }\n\n\n /* MODAL PLUGIN DEFINITION\n  * ======================= */\n\n  var old = $.fn.modal\n\n  $.fn.modal = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('modal')\n        , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)\n      if (!data) $this.data('modal', (data = new Modal(this, options)))\n      if (typeof option == 'string') data[option]()\n      else if (options.show) data.show()\n    })\n  }\n\n  $.fn.modal.defaults = {\n      backdrop: true\n    , keyboard: true\n    , show: true\n  }\n\n  $.fn.modal.Constructor = Modal\n\n\n /* MODAL NO CONFLICT\n  * ================= */\n\n  $.fn.modal.noConflict = function () {\n    $.fn.modal = old\n    return this\n  }\n\n\n /* MODAL DATA-API\n  * ============== */\n\n  $(document).on('click.modal.data-api', '[data-toggle=\"modal\"]', function (e) {\n    var $this = $(this)\n      , href = $this.attr('href')\n      , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\\s]+$)/, ''))) //strip for ie7\n      , option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data())\n\n    e.preventDefault()\n\n    $target\n      .modal(option)\n      .one('hide', function () {\n        $this.focus()\n      })\n    })\n\n    var $body = $(document.body)\n      .on('shown', '.modal', function () { $body.addClass('modal-open') })\n      .on('hidden', '.modal', function () { $body.removeClass('modal-open') })\n\n}(window.jQuery);\n/* ===========================================================\n * bootstrap-tooltip.js v3.0.0\n * http://twitter.github.com/bootstrap/javascript.html#tooltips\n * Inspired by the original jQuery.tipsy by Jason Frame\n * ===========================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ========================================================== */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* TOOLTIP PUBLIC CLASS DEFINITION\n  * =============================== */\n\n  var Tooltip = function (element, options) {\n    this.init('tooltip', element, options)\n  }\n\n  Tooltip.prototype = {\n\n    constructor: Tooltip\n\n  , init: function (type, element, options) {\n      var eventIn\n        , eventOut\n        , triggers\n        , trigger\n        , i\n\n      this.type = type\n      this.$element = $(element)\n      this.options = this.getOptions(options)\n      this.enabled = true\n\n      triggers = this.options.trigger.split(' ')\n\n      for (i = triggers.length; i--;) {\n        trigger = triggers[i]\n        if (trigger == 'click') {\n          this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))\n        } else if (trigger != 'manual') {\n          eventIn = trigger == 'hover' ? 'mouseenter' : 'focus'\n          eventOut = trigger == 'hover' ? 'mouseleave' : 'blur'\n          this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))\n          this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))\n        }\n      }\n\n      this.options.selector ?\n        (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :\n        this.fixTitle()\n    }\n\n  , getOptions: function (options) {\n      options = $.extend({}, $.fn[this.type].defaults, this.$element.data(), options)\n\n      if (options.delay && typeof options.delay == 'number') {\n        options.delay = {\n          show: options.delay\n        , hide: options.delay\n        }\n      }\n\n      return options\n    }\n\n  , enter: function (e) {\n      var defaults = $.fn[this.type].defaults\n        , options = {}\n        , self\n\n      this._options && $.each(this._options, function (key, value) {\n        if (defaults[key] != value) options[key] = value\n      }, this)\n\n      self = $(e.currentTarget)[this.type](options).data(this.type)\n\n      if (!self.options.delay || !self.options.delay.show) return self.show()\n\n      clearTimeout(this.timeout)\n      self.hoverState = 'in'\n      this.timeout = setTimeout(function() {\n        if (self.hoverState == 'in') self.show()\n      }, self.options.delay.show)\n    }\n\n  , leave: function (e) {\n      var self = $(e.currentTarget)[this.type](this._options).data(this.type)\n\n      if (this.timeout) clearTimeout(this.timeout)\n      if (!self.options.delay || !self.options.delay.hide) return self.hide()\n\n      self.hoverState = 'out'\n      this.timeout = setTimeout(function() {\n        if (self.hoverState == 'out') self.hide()\n      }, self.options.delay.hide)\n    }\n\n  , show: function () {\n      var $tip\n        , pos\n        , actualWidth\n        , actualHeight\n        , placement\n        , tp\n        , e = $.Event('show')\n\n      if (this.hasContent() && this.enabled) {\n        this.$element.trigger(e)\n        if (e.isDefaultPrevented()) return\n        $tip = this.tip()\n        this.setContent()\n\n        if (this.options.animation) {\n          $tip.addClass('fade')\n        }\n\n        placement = typeof this.options.placement == 'function' ?\n          this.options.placement.call(this, $tip[0], this.$element[0]) :\n          this.options.placement\n\n        $tip\n          .detach()\n          .css({ top: 0, left: 0, display: 'block' })\n\n        this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)\n\n        pos = this.getPosition()\n\n        actualWidth = $tip[0].offsetWidth\n        actualHeight = $tip[0].offsetHeight\n\n        switch (placement) {\n          case 'bottom':\n            tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}\n            break\n          case 'top':\n            tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}\n            break\n          case 'left':\n            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}\n            break\n          case 'right':\n            tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}\n            break\n        }\n\n        this.applyPlacement(tp, placement)\n        this.$element.trigger('shown')\n      }\n    }\n\n  , applyPlacement: function(offset, placement){\n      var $tip = this.tip()\n        , width = $tip[0].offsetWidth\n        , height = $tip[0].offsetHeight\n        , actualWidth\n        , actualHeight\n        , delta\n        , replace\n\n      $tip\n        .offset(offset)\n        .addClass(placement)\n        .addClass('in')\n\n      actualWidth = $tip[0].offsetWidth\n      actualHeight = $tip[0].offsetHeight\n\n      if (placement == 'top' && actualHeight != height) {\n        offset.top = offset.top + height - actualHeight\n        replace = true\n      }\n\n      if (placement == 'bottom' || placement == 'top') {\n        delta = 0\n\n        if (offset.left < 0){\n          delta = offset.left * -2\n          offset.left = 0\n          $tip.offset(offset)\n          actualWidth = $tip[0].offsetWidth\n          actualHeight = $tip[0].offsetHeight\n        }\n\n        this.replaceArrow(delta - width + actualWidth, actualWidth, 'left')\n      } else {\n        this.replaceArrow(actualHeight - height, actualHeight, 'top')\n      }\n\n      if (replace) $tip.offset(offset)\n    }\n\n  , replaceArrow: function(delta, dimension, position){\n      this\n        .arrow()\n        .css(position, delta ? (50 * (1 - delta / dimension) + \"%\") : '')\n    }\n\n  , setContent: function () {\n      var $tip = this.tip()\n        , title = this.getTitle()\n\n      $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)\n      $tip.removeClass('fade in top bottom left right')\n    }\n\n  , hide: function () {\n      var that = this\n        , $tip = this.tip()\n        , e = $.Event('hide')\n\n      this.$element.trigger(e)\n      if (e.isDefaultPrevented()) return\n\n      $tip.removeClass('in')\n\n      function removeWithAnimation() {\n        var timeout = setTimeout(function () {\n          $tip.off($.support.transition.end).detach()\n        }, 500)\n\n        $tip.one($.support.transition.end, function () {\n          clearTimeout(timeout)\n          $tip.detach()\n        })\n      }\n\n      $.support.transition && this.$tip.hasClass('fade') ?\n        removeWithAnimation() :\n        $tip.detach()\n\n      this.$element.trigger('hidden')\n\n      return this\n    }\n\n  , fixTitle: function () {\n      var $e = this.$element\n      if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {\n        $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')\n      }\n    }\n\n  , hasContent: function () {\n      return this.getTitle()\n    }\n\n  , getPosition: function () {\n      var el = this.$element[0]\n      return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : {\n        width: el.offsetWidth\n      , height: el.offsetHeight\n      }, this.$element.offset())\n    }\n\n  , getTitle: function () {\n      var title\n        , $e = this.$element\n        , o = this.options\n\n      title = $e.attr('data-original-title')\n        || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)\n\n      return title\n    }\n\n  , tip: function () {\n      return this.$tip = this.$tip || $(this.options.template)\n    }\n\n  , arrow: function(){\n      return this.$arrow = this.$arrow || this.tip().find(\".tooltip-arrow\")\n    }\n\n  , validate: function () {\n      if (!this.$element[0].parentNode) {\n        this.hide()\n        this.$element = null\n        this.options = null\n      }\n    }\n\n  , enable: function () {\n      this.enabled = true\n    }\n\n  , disable: function () {\n      this.enabled = false\n    }\n\n  , toggleEnabled: function () {\n      this.enabled = !this.enabled\n    }\n\n  , toggle: function (e) {\n      var self = e ? $(e.currentTarget)[this.type](this._options).data(this.type) : this\n      self.tip().hasClass('in') ? self.hide() : self.show()\n    }\n\n  , destroy: function () {\n      this.hide().$element.off('.' + this.type).removeData(this.type)\n    }\n\n  }\n\n\n /* TOOLTIP PLUGIN DEFINITION\n  * ========================= */\n\n  var old = $.fn.tooltip\n\n  $.fn.tooltip = function ( option ) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('tooltip')\n        , options = typeof option == 'object' && option\n      if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.tooltip.Constructor = Tooltip\n\n  $.fn.tooltip.defaults = {\n    animation: true\n  , placement: 'top'\n  , selector: false\n  , template: '<div class=\"tooltip\"><div class=\"tooltip-arrow\"></div><div class=\"tooltip-inner\"></div></div>'\n  , trigger: 'hover focus'\n  , title: ''\n  , delay: 0\n  , html: false\n  , container: false\n  }\n\n\n /* TOOLTIP NO CONFLICT\n  * =================== */\n\n  $.fn.tooltip.noConflict = function () {\n    $.fn.tooltip = old\n    return this\n  }\n\n}(window.jQuery);\n/* ===========================================================\n * bootstrap-popover.js v3.0.0\n * http://twitter.github.com/bootstrap/javascript.html#popovers\n * ===========================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * =========================================================== */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* POPOVER PUBLIC CLASS DEFINITION\n  * =============================== */\n\n  var Popover = function (element, options) {\n    this.init('popover', element, options)\n  }\n\n\n  /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js\n     ========================================== */\n\n  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {\n\n    constructor: Popover\n\n  , setContent: function () {\n      var $tip = this.tip()\n        , title = this.getTitle()\n        , content = this.getContent()\n\n      $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)\n      $tip.find('.popover-content')[this.options.html ? 'html' : 'text'](content)\n\n      $tip.removeClass('fade top bottom left right in')\n    }\n\n  , hasContent: function () {\n      return this.getTitle() || this.getContent()\n    }\n\n  , getContent: function () {\n      var content\n        , $e = this.$element\n        , o = this.options\n\n      content = (typeof o.content == 'function' ? o.content.call($e[0]) :  o.content)\n        || $e.attr('data-content')\n\n      return content\n    }\n\n  , tip: function () {\n      if (!this.$tip) {\n        this.$tip = $(this.options.template)\n      }\n      return this.$tip\n    }\n\n  , destroy: function () {\n      this.hide().$element.off('.' + this.type).removeData(this.type)\n    }\n\n  })\n\n\n /* POPOVER PLUGIN DEFINITION\n  * ======================= */\n\n  var old = $.fn.popover\n\n  $.fn.popover = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('popover')\n        , options = typeof option == 'object' && option\n      if (!data) $this.data('popover', (data = new Popover(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.popover.Constructor = Popover\n\n  $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {\n    placement: 'right'\n  , trigger: 'click'\n  , content: ''\n  , template: '<div class=\"popover\"><div class=\"arrow\"></div><h3 class=\"popover-title\"></h3><div class=\"popover-content\"></div></div>'\n  })\n\n\n /* POPOVER NO CONFLICT\n  * =================== */\n\n  $.fn.popover.noConflict = function () {\n    $.fn.popover = old\n    return this\n  }\n\n}(window.jQuery);\n/* =============================================================\n * bootstrap-scrollspy.js v3.0.0\n * http://twitter.github.com/bootstrap/javascript.html#scrollspy\n * =============================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ============================================================== */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* SCROLLSPY CLASS DEFINITION\n  * ========================== */\n\n  function ScrollSpy(element, options) {\n    var process = $.proxy(this.process, this)\n      , $element = $(element).is('body') ? $(window) : $(element)\n      , href\n    this.options = $.extend({}, $.fn.scrollspy.defaults, options)\n    this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process)\n    this.selector = (this.options.target\n      || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) //strip for ie7\n      || '') + ' .nav li > a'\n    this.$body = $('body')\n    this.refresh()\n    this.process()\n  }\n\n  ScrollSpy.prototype = {\n\n      constructor: ScrollSpy\n\n    , refresh: function () {\n        var self = this\n          , $targets\n\n        this.offsets = $([])\n        this.targets = $([])\n\n        $targets = this.$body\n          .find(this.selector)\n          .map(function () {\n            var $el = $(this)\n              , href = $el.data('target') || $el.attr('href')\n              , $href = /^#\\w/.test(href) && $(href)\n            return ( $href\n              && $href.length\n              && [[ $href.position().top + (!$.isWindow(self.$scrollElement.get(0)) && self.$scrollElement.scrollTop()), href ]] ) || null\n          })\n          .sort(function (a, b) { return a[0] - b[0] })\n          .each(function () {\n            self.offsets.push(this[0])\n            self.targets.push(this[1])\n          })\n      }\n\n    , process: function () {\n        var scrollTop = this.$scrollElement.scrollTop() + this.options.offset\n          , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight\n          , maxScroll = scrollHeight - this.$scrollElement.height()\n          , offsets = this.offsets\n          , targets = this.targets\n          , activeTarget = this.activeTarget\n          , i\n\n        if (scrollTop >= maxScroll) {\n          return activeTarget != (i = targets.last()[0])\n            && this.activate ( i )\n        }\n\n        for (i = offsets.length; i--;) {\n          activeTarget != targets[i]\n            && scrollTop >= offsets[i]\n            && (!offsets[i + 1] || scrollTop <= offsets[i + 1])\n            && this.activate( targets[i] )\n        }\n      }\n\n    , activate: function (target) {\n        var active\n          , selector\n\n        this.activeTarget = target\n\n        $(this.selector)\n          .parents('.active')\n          .removeClass('active')\n\n        selector = this.selector\n          + '[data-target=\"' + target + '\"],'\n          + this.selector + '[href=\"' + target + '\"]'\n\n        active = $(selector)\n          .parents('li')\n          .addClass('active')\n\n        if (active.parent('.dropdown-menu').length)  {\n          active = active.closest('li.dropdown').addClass('active')\n        }\n\n        active.trigger('activate')\n      }\n\n  }\n\n\n /* SCROLLSPY PLUGIN DEFINITION\n  * =========================== */\n\n  var old = $.fn.scrollspy\n\n  $.fn.scrollspy = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('scrollspy')\n        , options = typeof option == 'object' && option\n      if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.scrollspy.Constructor = ScrollSpy\n\n  $.fn.scrollspy.defaults = {\n    offset: 10\n  }\n\n\n /* SCROLLSPY NO CONFLICT\n  * ===================== */\n\n  $.fn.scrollspy.noConflict = function () {\n    $.fn.scrollspy = old\n    return this\n  }\n\n\n /* SCROLLSPY DATA-API\n  * ================== */\n\n  $(window).on('load', function () {\n    $('[data-spy=\"scroll\"]').each(function () {\n      var $spy = $(this)\n      $spy.scrollspy($spy.data())\n    })\n  })\n\n}(window.jQuery);/* ========================================================\n * bootstrap-tab.js v3.0.0\n * http://twitter.github.com/bootstrap/javascript.html#tabs\n * ========================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ======================================================== */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* TAB CLASS DEFINITION\n  * ==================== */\n\n  var Tab = function (element) {\n    this.element = $(element)\n  }\n\n  Tab.prototype = {\n\n    constructor: Tab\n\n  , show: function () {\n      var $this = this.element\n        , $ul = $this.closest('ul:not(.dropdown-menu)')\n        , selector = $this.attr('data-target')\n        , previous\n        , $target\n        , e\n\n      if (!selector) {\n        selector = $this.attr('href')\n        selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') //strip for ie7\n      }\n\n      if ( $this.parent('li').hasClass('active') ) return\n\n      previous = $ul.find('.active:last a')[0]\n\n      e = $.Event('show', {\n        relatedTarget: previous\n      })\n\n      $this.trigger(e)\n\n      if (e.isDefaultPrevented()) return\n\n      $target = $(selector)\n\n      this.activate($this.parent('li'), $ul)\n      this.activate($target, $target.parent(), function () {\n        $this.trigger({\n          type: 'shown'\n        , relatedTarget: previous\n        })\n      })\n    }\n\n  , activate: function ( element, container, callback) {\n      var $active = container.find('> .active')\n        , transition = callback\n            && $.support.transition\n            && $active.hasClass('fade')\n\n      function next() {\n        $active\n          .removeClass('active')\n          .find('> .dropdown-menu > .active')\n          .removeClass('active')\n\n        element.addClass('active')\n\n        if (transition) {\n          element[0].offsetWidth // reflow for transition\n          element.addClass('in')\n        } else {\n          element.removeClass('fade')\n        }\n\n        if ( element.parent('.dropdown-menu') ) {\n          element.closest('li.dropdown').addClass('active')\n        }\n\n        callback && callback()\n      }\n\n      transition ?\n        $active.one($.support.transition.end, next) :\n        next()\n\n      $active.removeClass('in')\n    }\n  }\n\n\n /* TAB PLUGIN DEFINITION\n  * ===================== */\n\n  var old = $.fn.tab\n\n  $.fn.tab = function ( option ) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('tab')\n      if (!data) $this.data('tab', (data = new Tab(this)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.tab.Constructor = Tab\n\n\n /* TAB NO CONFLICT\n  * =============== */\n\n  $.fn.tab.noConflict = function () {\n    $.fn.tab = old\n    return this\n  }\n\n\n /* TAB DATA-API\n  * ============ */\n\n  $(document).on('click.tab.data-api', '[data-toggle=\"tab\"], [data-toggle=\"pill\"]', function (e) {\n    e.preventDefault()\n    $(this).tab('show')\n  })\n\n}(window.jQuery);/* =============================================================\n * bootstrap-typeahead.js v3.0.0\n * http://twitter.github.com/bootstrap/javascript.html#typeahead\n * =============================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ============================================================ */\n\n\n!function($){\n\n  \"use strict\"; // jshint ;_;\n\n\n /* TYPEAHEAD PUBLIC CLASS DEFINITION\n  * ================================= */\n\n  var Typeahead = function (element, options) {\n    this.$element = $(element)\n    this.options = $.extend({}, $.fn.typeahead.defaults, options)\n    this.matcher = this.options.matcher || this.matcher\n    this.sorter = this.options.sorter || this.sorter\n    this.highlighter = this.options.highlighter || this.highlighter\n    this.updater = this.options.updater || this.updater\n    this.render = this.options.render || this.render\n    this.next = this.options.next || this.next\n    this.prev = this.options.prev || this.prev\n    this.source = this.options.source\n    this.$menu = $(this.options.menu)\n    this.select = this.options.select || this.select\n    this.shown = false\n    this.listen()\n  }\n\n  Typeahead.prototype = {\n\n    constructor: Typeahead\n\n  , select: function () {\n      var val = this.$menu.find('.active').attr('data-value')\n      this.$element\n        .val(this.updater(val))\n        .change()\n      return this.hide()\n    }\n\n  , updater: function (item) {\n      return item\n    }\n\n  , show: function () {\n      var pos = $.extend({}, this.$element.position(), {\n        height: this.$element[0].offsetHeight\n      })\n\n      this.$menu\n        .insertAfter(this.$element)\n        .css({\n          top: pos.top + pos.height\n        , left: pos.left\n        })\n        .show()\n\n      this.shown = true\n      return this\n    }\n\n  , hide: function () {\n      this.$menu.hide()\n      this.shown = false\n      return this\n    }\n\n  , lookup: function (event) {\n      var items\n\n      this.query = this.$element.val()\n\n      if (!this.query || this.query.length < this.options.minLength) {\n        return this.shown ? this.hide() : this\n      }\n\n      items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source\n\n      return items ? this.process(items) : this\n    }\n\n  , process: function (items) {\n      var that = this\n\n      items = $.grep(items, function (item) {\n        return that.matcher(item)\n      })\n\n      items = this.sorter(items)\n\n      if (!items.length) {\n        return this.shown ? this.hide() : this\n      }\n\n      return this.render(items.slice(0, this.options.items)).show()\n    }\n\n  , matcher: function (item) {\n      return ~item.toLowerCase().indexOf(this.query.toLowerCase())\n    }\n\n  , sorter: function (items) {\n      var beginswith = []\n        , caseSensitive = []\n        , caseInsensitive = []\n        , item\n\n      while (item = items.shift()) {\n        if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)\n        else if (~item.indexOf(this.query)) caseSensitive.push(item)\n        else caseInsensitive.push(item)\n      }\n\n      return beginswith.concat(caseSensitive, caseInsensitive)\n    }\n\n  , highlighter: function (item) {\n      var query = this.query.replace(/[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, '\\\\$&')\n      return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {\n        return '<strong>' + match + '</strong>'\n      })\n    }\n\n  , render: function (items) {\n      var that = this\n\n      items = $(items).map(function (i, item) {\n        i = $(that.options.item).attr('data-value', item)\n        i.find('a').html(that.highlighter(item))\n        return i[0]\n      })\n\n      items.first().addClass('active')\n      this.$menu.html(items)\n      return this\n    }\n\n  , next: function (event) {\n      var active = this.$menu.find('.active').removeClass('active')\n        , next = active.next()\n\n      if (!next.length) {\n        next = $(this.$menu.find('li')[0])\n      }\n\n      next.addClass('active')\n    }\n\n  , prev: function (event) {\n      var active = this.$menu.find('.active').removeClass('active')\n        , prev = active.prev()\n\n      if (!prev.length) {\n        prev = this.$menu.find('li').last()\n      }\n\n      prev.addClass('active')\n    }\n\n  , listen: function () {\n      this.$element\n        .on('focus',    $.proxy(this.focus, this))\n        .on('blur',     $.proxy(this.blur, this))\n        .on('keypress', $.proxy(this.keypress, this))\n        .on('keyup',    $.proxy(this.keyup, this))\n\n      if (this.eventSupported('keydown')) {\n        this.$element.on('keydown', $.proxy(this.keydown, this))\n      }\n\n      this.$menu\n        .on('click', $.proxy(this.click, this))\n        .on('mouseenter', 'li', $.proxy(this.mouseenter, this))\n        .on('mouseleave', 'li', $.proxy(this.mouseleave, this))\n    }\n\n  , eventSupported: function(eventName) {\n      var isSupported = eventName in this.$element\n      if (!isSupported) {\n        this.$element.setAttribute(eventName, 'return;')\n        isSupported = typeof this.$element[eventName] === 'function'\n      }\n      return isSupported\n    }\n\n  , move: function (e) {\n      if (!this.shown) return\n\n      switch(e.keyCode) {\n        case 9: // tab\n        case 13: // enter\n        case 27: // escape\n          e.preventDefault()\n          break\n\n        case 38: // up arrow\n          e.preventDefault()\n          this.prev()\n          break\n\n        case 40: // down arrow\n          e.preventDefault()\n          this.next()\n          break\n      }\n\n      e.stopPropagation()\n    }\n\n  , keydown: function (e) {\n      this.suppressKeyPressRepeat = ~$.inArray(e.keyCode, [40,38,9,13,27])\n      this.move(e)\n    }\n\n  , keypress: function (e) {\n      if (this.suppressKeyPressRepeat) return\n      this.move(e)\n    }\n\n  , keyup: function (e) {\n      switch(e.keyCode) {\n        case 40: // down arrow\n        case 38: // up arrow\n        case 16: // shift\n        case 17: // ctrl\n        case 18: // alt\n          break\n\n        case 9: // tab\n        case 13: // enter\n          if (!this.shown) return\n          this.select()\n          break\n\n        case 27: // escape\n          if (!this.shown) return\n          this.hide()\n          break\n\n        default:\n          this.lookup()\n      }\n\n      e.stopPropagation()\n      e.preventDefault()\n  }\n\n  , focus: function (e) {\n      this.focused = true\n    }\n\n  , blur: function (e) {\n      this.focused = false\n      if (!this.mousedover && this.shown) this.hide()\n    }\n\n  , click: function (e) {\n      e.stopPropagation()\n      e.preventDefault()\n      this.select()\n      this.$element.focus()\n    }\n\n  , mouseenter: function (e) {\n      this.mousedover = true\n      this.$menu.find('.active').removeClass('active')\n      $(e.currentTarget).addClass('active')\n    }\n\n  , mouseleave: function (e) {\n      this.mousedover = false\n      if (!this.focused && this.shown) this.hide()\n    }\n\n  }\n\n\n  /* TYPEAHEAD PLUGIN DEFINITION\n   * =========================== */\n\n  var old = $.fn.typeahead\n\n  $.fn.typeahead = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('typeahead')\n        , options = typeof option == 'object' && option\n      if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.typeahead.defaults = {\n    source: []\n  , items: 8\n  , menu: '<ul class=\"typeahead dropdown-menu\"></ul>'\n  , item: '<li><a href=\"#\"></a></li>'\n  , minLength: 1\n  }\n\n  $.fn.typeahead.Constructor = Typeahead\n\n\n /* TYPEAHEAD NO CONFLICT\n  * =================== */\n\n  $.fn.typeahead.noConflict = function () {\n    $.fn.typeahead = old\n    return this\n  }\n\n\n /* TYPEAHEAD DATA-API\n  * ================== */\n\n  $(document).on('focus.typeahead.data-api', '[data-provide=\"typeahead\"]', function (e) {\n    var $this = $(this)\n    if ($this.data('typeahead')) return\n    $this.typeahead($this.data())\n  })\n\n}(window.jQuery);\n/* ==========================================================\n * bootstrap-affix.js v3.0.0\n * http://twitter.github.com/bootstrap/javascript.html#affix\n * ==========================================================\n * Copyright 2012 Twitter, Inc.\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ========================================================== */\n\n\n!function ($) {\n\n  \"use strict\"; // jshint ;_;\n\n\n /* AFFIX CLASS DEFINITION\n  * ====================== */\n\n  var Affix = function (element, options) {\n    this.options = $.extend({}, $.fn.affix.defaults, options)\n    this.$window = $(window)\n      .on('scroll.affix.data-api', $.proxy(this.checkPosition, this))\n      .on('click.affix.data-api',  $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this))\n    this.$element = $(element)\n    this.checkPosition()\n  }\n\n  Affix.prototype.checkPosition = function () {\n    if (!this.$element.is(':visible')) return\n\n    var scrollHeight = $(document).height()\n      , scrollTop = this.$window.scrollTop()\n      , position = this.$element.offset()\n      , offset = this.options.offset\n      , offsetBottom = offset.bottom\n      , offsetTop = offset.top\n      , reset = 'affix affix-top affix-bottom'\n      , affix\n\n    if (typeof offset != 'object') offsetBottom = offsetTop = offset\n    if (typeof offsetTop == 'function') offsetTop = offset.top()\n    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()\n\n    affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ?\n      false    : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ?\n      'bottom' : offsetTop != null && scrollTop <= offsetTop ?\n      'top'    : false\n\n    if (this.affixed === affix) return\n\n    this.affixed = affix\n    this.unpin = affix == 'bottom' ? position.top - scrollTop : null\n\n    this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))\n  }\n\n\n /* AFFIX PLUGIN DEFINITION\n  * ======================= */\n\n  var old = $.fn.affix\n\n  $.fn.affix = function (option) {\n    return this.each(function () {\n      var $this = $(this)\n        , data = $this.data('affix')\n        , options = typeof option == 'object' && option\n      if (!data) $this.data('affix', (data = new Affix(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  $.fn.affix.Constructor = Affix\n\n  $.fn.affix.defaults = {\n    offset: 0\n  }\n\n\n /* AFFIX NO CONFLICT\n  * ================= */\n\n  $.fn.affix.noConflict = function () {\n    $.fn.affix = old\n    return this\n  }\n\n\n /* AFFIX DATA-API\n  * ============== */\n\n  $(window).on('load', function () {\n    $('[data-spy=\"affix\"]').each(function () {\n      var $spy = $(this)\n        , data = $spy.data()\n\n      data.offset = data.offset || {}\n\n      data.offsetBottom && (data.offset.bottom = data.offsetBottom)\n      data.offsetTop && (data.offset.top = data.offsetTop)\n\n      $spy.affix(data)\n    })\n  })\n\n\n}(window.jQuery);"
  },
  {
    "path": "web/src/main/webapp/assets/vendor/js/marked/marked.js",
    "content": "/**\n * marked - a markdown parser\n * Copyright (c) 2011-2013, Christopher Jeffrey. (MIT Licensed)\n * https://github.com/chjj/marked\n */\n\n;(function() {\n\n/**\n * Block-Level Grammar\n */\n\nvar block = {\n  newline: /^\\n+/,\n  code: /^( {4}[^\\n]+\\n*)+/,\n  fences: noop,\n  hr: /^( *[-*_]){3,} *(?:\\n+|$)/,\n  heading: /^ *(#{1,6} ) *([^\\n]+?) *#* *(?:\\n+|$)/,\n  nptable: noop,\n  lheading: /^([^\\n]+)\\n *(=|-){3,} *\\n*/,\n  blockquote: /^( *>[^\\n]+(\\n[^\\n]+)*\\n*)+/,\n  list: /^( *)(bull) [\\s\\S]+?(?:hr|\\n{2,}(?! )(?!\\1bull )\\n*|\\s*$)/,\n  html: /^ *(?:comment|closed|closing) *(?:\\n{2,}|\\s*$)/,\n  def: /^ *\\[([^\\]]+)\\]: *<?([^\\s>]+)>?(?: +[\"(]([^\\n]+)[\")])? *(?:\\n+|$)/,\n  table: noop,\n  paragraph: /^((?:[^\\n]+\\n?(?!hr|heading|lheading|blockquote|tag|def))+)\\n*/,\n  text: /^[^\\n]+/\n};\n\nblock.bullet = /(?:[*+-]|\\d+\\.)/;\nblock.item = /^( *)(bull) [^\\n]*(?:\\n(?!\\1bull )[^\\n]*)*/;\nblock.item = replace(block.item, 'gm')\n  (/bull/g, block.bullet)\n  ();\n\nblock.list = replace(block.list)\n  (/bull/g, block.bullet)\n  ('hr', /\\n+(?=(?: *[-*_]){3,} *(?:\\n+|$))/)\n  ();\n\nblock._tag = '(?!(?:'\n  + 'a|em|strong|small|s|cite|q|dfn|abbr|data|time|code'\n  + '|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo'\n  + '|span|br|wbr|ins|del|img)\\\\b)\\\\w+(?!:/|@)\\\\b';\n\nblock.html = replace(block.html)\n  ('comment', /<!--[\\s\\S]*?-->/)\n  ('closed', /<(tag)[\\s\\S]+?<\\/\\1>/)\n  ('closing', /<tag(?:\"[^\"]*\"|'[^']*'|[^'\">])*?>/)\n  (/tag/g, block._tag)\n  ();\n\nblock.paragraph = replace(block.paragraph)\n  ('hr', block.hr)\n  ('heading', block.heading)\n  ('lheading', block.lheading)\n  ('blockquote', block.blockquote)\n  ('tag', '<' + block._tag)\n  ('def', block.def)\n  ();\n\n/**\n * Normal Block Grammar\n */\n\nblock.normal = merge({}, block);\n\n/**\n * GFM Block Grammar\n */\n\nblock.gfm = merge({}, block.normal, {\n  fences: /^ *(`{3,}|~{3,}) *(\\w+)? *\\n([\\s\\S]+?)\\s*\\1 *(?:\\n+|$)/,\n  paragraph: /^/\n});\n\nblock.gfm.paragraph = replace(block.paragraph)\n  ('(?!', '(?!' + block.gfm.fences.source.replace('\\\\1', '\\\\2') + '|')\n  ();\n\n/**\n * GFM + Tables Block Grammar\n */\n\nblock.tables = merge({}, block.gfm, {\n  nptable: /^ *(\\S.*\\|.*)\\n *([-:]+ *\\|[-| :]*)\\n((?:.*\\|.*(?:\\n|$))*)\\n*/,\n  table: /^ *\\|(.+)\\n *\\|( *[-:]+[-| :]*)\\n((?: *\\|.*(?:\\n|$))*)\\n*/\n});\n\n/**\n * Block Lexer\n */\n\nfunction Lexer(options) {\n  this.tokens = [];\n  this.tokens.links = {};\n  this.options = options || marked.defaults;\n  this.rules = block.normal;\n\n  if (this.options.gfm) {\n    if (this.options.tables) {\n      this.rules = block.tables;\n    } else {\n      this.rules = block.gfm;\n    }\n  }\n}\n\n/**\n * Expose Block Rules\n */\n\nLexer.rules = block;\n\n/**\n * Static Lex Method\n */\n\nLexer.lex = function(src, options) {\n  var lexer = new Lexer(options);\n  return lexer.lex(src);\n};\n\n/**\n * Preprocessing\n */\n\nLexer.prototype.lex = function(src) {\n  src = src\n    .replace(/\\r\\n|\\r/g, '\\n')\n    .replace(/\\t/g, '    ')\n    .replace(/\\u00a0/g, ' ')\n    .replace(/\\u2424/g, '\\n');\n\n  return this.token(src, true);\n};\n\n/**\n * Lexing\n */\n\nLexer.prototype.token = function(src, top) {\n  var src = src.replace(/^ +$/gm, '')\n    , next\n    , loose\n    , cap\n    , bull\n    , b\n    , item\n    , space\n    , i\n    , l;\n\n  while (src) {\n    // newline\n    if (cap = this.rules.newline.exec(src)) {\n      src = src.substring(cap[0].length);\n      if (cap[0].length > 1) {\n        this.tokens.push({\n          type: 'space'\n        });\n      }\n    }\n\n    // code\n    if (cap = this.rules.code.exec(src)) {\n      src = src.substring(cap[0].length);\n      cap = cap[0].replace(/^ {4}/gm, '');\n      this.tokens.push({\n        type: 'code',\n        text: !this.options.pedantic\n          ? cap.replace(/\\n+$/, '')\n          : cap\n      });\n      continue;\n    }\n\n    // fences (gfm)\n    if (cap = this.rules.fences.exec(src)) {\n      src = src.substring(cap[0].length);\n      this.tokens.push({\n        type: 'code',\n        lang: cap[2],\n        text: cap[3]\n      });\n      continue;\n    }\n\n    // heading\n    if (cap = this.rules.heading.exec(src)) {\n      src = src.substring(cap[0].length);\n      this.tokens.push({\n        type: 'heading',\n        depth: cap[1].length,\n        text: cap[2]\n      });\n      continue;\n    }\n\n    // table no leading pipe (gfm)\n    if (top && (cap = this.rules.nptable.exec(src))) {\n      src = src.substring(cap[0].length);\n\n      item = {\n        type: 'table',\n        header: cap[1].replace(/^ *| *\\| *$/g, '').split(/ *\\| */),\n        align: cap[2].replace(/^ *|\\| *$/g, '').split(/ *\\| */),\n        cells: cap[3].replace(/\\n$/, '').split('\\n')\n      };\n\n      for (i = 0; i < item.align.length; i++) {\n        if (/^ *-+: *$/.test(item.align[i])) {\n          item.align[i] = 'right';\n        } else if (/^ *:-+: *$/.test(item.align[i])) {\n          item.align[i] = 'center';\n        } else if (/^ *:-+ *$/.test(item.align[i])) {\n          item.align[i] = 'left';\n        } else {\n          item.align[i] = null;\n        }\n      }\n\n      for (i = 0; i < item.cells.length; i++) {\n        item.cells[i] = item.cells[i].split(/ *\\| */);\n      }\n\n      this.tokens.push(item);\n\n      continue;\n    }\n\n    // lheading\n    if (cap = this.rules.lheading.exec(src)) {\n      src = src.substring(cap[0].length);\n      this.tokens.push({\n        type: 'heading',\n        depth: cap[2] === '=' ? 1 : 2,\n        text: cap[1]\n      });\n      continue;\n    }\n\n    // hr\n    if (cap = this.rules.hr.exec(src)) {\n      src = src.substring(cap[0].length);\n      this.tokens.push({\n        type: 'hr'\n      });\n      continue;\n    }\n\n    // blockquote\n    if (cap = this.rules.blockquote.exec(src)) {\n      src = src.substring(cap[0].length);\n\n      this.tokens.push({\n        type: 'blockquote_start'\n      });\n\n      cap = cap[0].replace(/^ *> ?/gm, '');\n\n      // Pass `top` to keep the current\n      // \"toplevel\" state. This is exactly\n      // how markdown.pl works.\n      this.token(cap, top);\n\n      this.tokens.push({\n        type: 'blockquote_end'\n      });\n\n      continue;\n    }\n\n    // list\n    if (cap = this.rules.list.exec(src)) {\n      src = src.substring(cap[0].length);\n\n      this.tokens.push({\n        type: 'list_start',\n        ordered: isFinite(cap[2])\n      });\n\n      // Get each top-level item.\n      cap = cap[0].match(this.rules.item);\n\n      // Get bullet.\n      if (this.options.smartLists) {\n        bull = block.bullet.exec(cap[0])[0];\n      }\n\n      next = false;\n      l = cap.length;\n      i = 0;\n\n      for (; i < l; i++) {\n        item = cap[i];\n\n        // Remove the list item's bullet\n        // so it is seen as the next token.\n        space = item.length;\n        item = item.replace(/^ *([*+-]|\\d+\\.) +/, '');\n\n        // Outdent whatever the\n        // list item contains. Hacky.\n        if (~item.indexOf('\\n ')) {\n          space -= item.length;\n          item = !this.options.pedantic\n            ? item.replace(new RegExp('^ {1,' + space + '}', 'gm'), '')\n            : item.replace(/^ {1,4}/gm, '');\n        }\n\n        // Determine whether the next list item belongs here.\n        // Backpedal if it does not belong in this list.\n        if (this.options.smartLists && i !== l - 1) {\n          b = block.bullet.exec(cap[i+1])[0];\n          if (bull !== b && !(bull[1] === '.' && b[1] === '.')) {\n            src = cap.slice(i + 1).join('\\n') + src;\n            i = l - 1;\n          }\n        }\n\n        // Determine whether item is loose or not.\n        // Use: /(^|\\n)(?! )[^\\n]+\\n\\n(?!\\s*$)/\n        // for discount behavior.\n        loose = next || /\\n\\n(?!\\s*$)/.test(item);\n        if (i !== l - 1) {\n          next = item[item.length-1] === '\\n';\n          if (!loose) loose = next;\n        }\n\n        this.tokens.push({\n          type: loose\n            ? 'loose_item_start'\n            : 'list_item_start'\n        });\n\n        // Recurse.\n        this.token(item, false);\n\n        this.tokens.push({\n          type: 'list_item_end'\n        });\n      }\n\n      this.tokens.push({\n        type: 'list_end'\n      });\n\n      continue;\n    }\n\n    // html\n    if (cap = this.rules.html.exec(src)) {\n      src = src.substring(cap[0].length);\n      this.tokens.push({\n        type: this.options.sanitize\n          ? 'paragraph'\n          : 'html',\n        pre: cap[1] === 'pre',\n        text: cap[0]\n      });\n      continue;\n    }\n\n    // def\n    if (top && (cap = this.rules.def.exec(src))) {\n      src = src.substring(cap[0].length);\n      this.tokens.links[cap[1].toLowerCase()] = {\n        href: cap[2],\n        title: cap[3]\n      };\n      continue;\n    }\n\n    // table (gfm)\n    if (top && (cap = this.rules.table.exec(src))) {\n      src = src.substring(cap[0].length);\n\n      item = {\n        type: 'table',\n        header: cap[1].replace(/^ *| *\\| *$/g, '').split(/ *\\| */),\n        align: cap[2].replace(/^ *|\\| *$/g, '').split(/ *\\| */),\n        cells: cap[3].replace(/(?: *\\| *)?\\n$/, '').split('\\n')\n      };\n\n      for (i = 0; i < item.align.length; i++) {\n        if (/^ *-+: *$/.test(item.align[i])) {\n          item.align[i] = 'right';\n        } else if (/^ *:-+: *$/.test(item.align[i])) {\n          item.align[i] = 'center';\n        } else if (/^ *:-+ *$/.test(item.align[i])) {\n          item.align[i] = 'left';\n        } else {\n          item.align[i] = null;\n        }\n      }\n\n      for (i = 0; i < item.cells.length; i++) {\n        item.cells[i] = item.cells[i]\n          .replace(/^ *\\| *| *\\| *$/g, '')\n          .split(/ *\\| */);\n      }\n\n      this.tokens.push(item);\n\n      continue;\n    }\n\n    // top-level paragraph\n    if (top && (cap = this.rules.paragraph.exec(src))) {\n      src = src.substring(cap[0].length);\n      this.tokens.push({\n        type: 'paragraph',\n        text: cap[1][cap[1].length-1] === '\\n'\n          ? cap[1].slice(0, -1)\n          : cap[1]\n      });\n      continue;\n    }\n\n    // text\n    if (cap = this.rules.text.exec(src)) {\n      // Top-level should never reach here.\n      src = src.substring(cap[0].length);\n      this.tokens.push({\n        type: 'text',\n        text: cap[0]\n      });\n      continue;\n    }\n\n    if (src) {\n      throw new\n        Error('Infinite loop on byte: ' + src.charCodeAt(0));\n    }\n  }\n\n  return this.tokens;\n};\n\n/**\n * Inline-Level Grammar\n */\n\nvar inline = {\n  escape: /^\\\\([\\\\`*{}\\[\\]()#+\\-.!_>])/,\n  autolink: /^<([^ >]+(@|:\\/)[^ >]+)>/,\n  url: noop,\n  tag: /^<!--[\\s\\S]*?-->|^<\\/?\\w+(?:\"[^\"]*\"|'[^']*'|[^'\">])*?>/,\n  link: /^!?\\[(inside)\\]\\(href\\)/,\n  reflink: /^!?\\[(inside)\\]\\s*\\[([^\\]]*)\\]/,\n  nolink: /^!?\\[((?:\\[[^\\]]*\\]|[^\\[\\]])*)\\]/,\n  strong: /^__([\\s\\S]+?)__(?!_)|^\\*\\*([\\s\\S]+?)\\*\\*(?!\\*)/,\n  em: /^\\b_((?:__|[\\s\\S])+?)_\\b|^\\*((?:\\*\\*|[\\s\\S])+?)\\*(?!\\*)/,\n  code: /^(`+)\\s*([\\s\\S]*?[^`])\\s*\\1(?!`)/,\n  br: /^ {2,}\\n(?!\\s*$)/,\n  mail: /^([^\\s !\"#$%'()*+,.\\/:;<=>?@\\\\\\[\\]\\^_`{|}~-]+(@|:\\/)[^\\s !\"#$%'()*+,.\\/:;<=>?@\\\\\\[\\]\\^_`{|}~-]+.[^\\s !\"#$%'()*+,.\\/:;<=>?@\\\\\\[\\]\\^_`{|}~-]+)/,\n  mention: /^@([A-Za-z0-9!#$%&'*+\\/=?\\^_`{|}~\\-]+(?:\\.[A-Za-z0-9!#$%&'*+\\/=?\\^_`{|}~\\-]+)*(?!\\*))/,\n  tags:   /^#([^\\s!\"#$%'()*+,.\\/:;<=>?@\\\\\\[\\]\\^_`{|}~-]+(?:\\.[\\^!\"#$%'()*+,.\\/:;<=>?@\\\\\\[\\]\\^_`{|}~-]+)*)(?!\\*)/,\n  del: noop,\n  text: /^[\\s\\S]+?(?=[\\\\<!\\[_*`]| {2,}\\n|$)/\n};\n\ninline._inside = /(?:\\[[^\\]]*\\]|[^\\]]|\\](?=[^\\[]*\\]))*/;\ninline._href = /\\s*<?([^\\s]*?)>?(?:\\s+['\"]([\\s\\S]*?)['\"])?\\s*/;\n\ninline.link = replace(inline.link)\n  ('inside', inline._inside)\n  ('href', inline._href)\n  ();\n\ninline.reflink = replace(inline.reflink)\n  ('inside', inline._inside)\n  ();\n\n/**\n * Normal Inline Grammar\n */\n\ninline.normal = merge({}, inline);\n\n/**\n * Pedantic Inline Grammar\n */\n\ninline.pedantic = merge({}, inline.normal, {\n  strong: /^__(?=\\S)([\\s\\S]*?\\S)__(?!_)|^\\*\\*(?=\\S)([\\s\\S]*?\\S)\\*\\*(?!\\*)/,\n  em: /^_(?=\\S)([\\s\\S]*?\\S)_(?!_)|^\\*(?=\\S)([\\s\\S]*?\\S)\\*(?!\\*)/\n});\n\n/**\n * GFM Inline Grammar\n */\n\ninline.gfm = merge({}, inline.normal, {\n  escape: replace(inline.escape)('])', '~|])')(),\n  url: /^(https?:\\/\\/[^\\s<]+[^<.,:;\"')\\]\\s])/,\n  del: /^~~(?=\\S)([\\s\\S]*?\\S)~~/,\n  text: replace(inline.text)\n    (']|', '#@~]|')\n    ('|', '|https?://|')\n    ('|', '||')\n    ()\n});\n\n/**\n * GFM + Line Breaks Inline Grammar\n */\n\ninline.breaks = merge({}, inline.gfm, {\n  br: replace(inline.br)('{2,}', '*')(),\n  text: replace(inline.gfm.text)('{2,}', '*')()\n});\n\n/**\n * Inline Lexer & Compiler\n */\n\nfunction InlineLexer(links, options) {\n  this.options = options || marked.defaults;\n  this.links = links;\n  this.rules = inline.normal;\n\n  if (!this.links) {\n    throw new\n      Error('Tokens array requires a `links` property.');\n  }\n\n  if (this.options.gfm) {\n    if (this.options.breaks) {\n      this.rules = inline.breaks;\n    } else {\n      this.rules = inline.gfm;\n    }\n  } else if (this.options.pedantic) {\n    this.rules = inline.pedantic;\n  }\n}\n\n/**\n * Expose Inline Rules\n */\n\nInlineLexer.rules = inline;\n\n/**\n * Static Lexing/Compiling Method\n */\n\nInlineLexer.output = function(src, links, options) {\n  var inline = new InlineLexer(links, options);\n  return inline.output(src);\n};\n\n/**\n * Lexing/Compiling\n */\n\nInlineLexer.prototype.output = function(src) {\n  var out = ''\n    , link\n    , text\n    , href\n    , cap;\n\n  while (src) {\n    // escape\n    if (cap = this.rules.escape.exec(src)) {\n      src = src.substring(cap[0].length);\n      out += cap[1];\n      continue;\n    }\n\n    // autolink\n    if (cap = this.rules.autolink.exec(src)) {\n      src = src.substring(cap[0].length);\n      if (cap[2] === '@') {\n        text = cap[1][6] === ':'\n          ? this.mangle(cap[1].substring(7))\n          : this.mangle(cap[1]);\n        href = this.mangle('mailto:') + text;\n      } else {\n        href = escape(cap[1]);\n        text = shortenUrl(href);\n      }\n      out += '<a href=\"'\n        + href\n        + '\" target=\"_blank\">'\n        + text\n        + '</a>';\n      continue;\n    }\n\n    // autolink\n    if (cap = this.rules.mail.exec(src)) {\n      src = src.substring(cap[0].length);\n      if (cap[2] === '@') {\n        text = cap[1][6] === ':'\n          ? this.mangle(cap[1].substring(7))\n          : this.mangle(cap[1]);\n        href = this.mangle('mailto:') + text;\n      } else {\n        href = escape(cap[1]);\n        text = shortenUrl(href);\n      }\n      out += '<a href=\"'\n        + href\n        + '\" target=\"_blank\">'\n        + text\n        + '</a>';\n      continue;\n    }\n\n    // url (gfm)\n    if (cap = this.rules.url.exec(src)) {\n      var html;\n      src = src.substring(cap[0].length);\n      href = escape(cap[1]);\n      text = shortenUrl(href);\n      for(var key in this.options.urls){\n        html = this.options.urls[key](text, href);\n        if(html){\n          out += html;\n          break;\n        }\n      }\n      if(!html)\n        out += '<a target=\"_blank\" href=\"'\n          + href\n          + '\" target=\"_blank\">'\n          + text\n          + '</a>';\n      continue;\n    }\n\n    // tag\n    if (cap = this.rules.tag.exec(src)) {\n      src = src.substring(cap[0].length);\n      out += this.options.sanitize\n        ? escape(cap[0])\n        : cap[0];\n      continue;\n    }\n\n    // link\n    if (cap = this.rules.link.exec(src)) {\n      src = src.substring(cap[0].length);\n      out += this.outputLink(cap, {\n        href: cap[2],\n        title: cap[3]\n      });\n      continue;\n    }\n\n    // reflink, nolink\n    if ((cap = this.rules.reflink.exec(src))\n        || (cap = this.rules.nolink.exec(src))) {\n      src = src.substring(cap[0].length);\n      link = (cap[2] || cap[1]).replace(/\\s+/g, ' ');\n      link = this.links[link.toLowerCase()];\n      if (!link || !link.href) {\n        out += cap[0][0];\n        src = cap[0].substring(1) + src;\n        continue;\n      }\n      out += this.outputLink(cap, link);\n      continue;\n    }\n\n    // strong\n    if (cap = this.rules.strong.exec(src)) {\n      src = src.substring(cap[0].length);\n      out += '<strong>'\n        + this.output(cap[2] || cap[1])\n        + '</strong>';\n      continue;\n    }\n\n    // em\n    if (cap = this.rules.em.exec(src)) {\n      src = src.substring(cap[0].length);\n      out += '<em>'\n        + this.output(cap[2] || cap[1])\n        + '</em>';\n      continue;\n    }\n\n    // code\n    if (cap = this.rules.code.exec(src)) {\n      src = src.substring(cap[0].length);\n      out += '<code>'\n        + escape(cap[2], true)\n        + '</code>';\n      continue;\n    }\n\n    // mention\n    if (cap = inline.mention.exec(src)) {\n      src = src.substring(cap[0].length);\n      out += '<a ui-sref=\"home.profile.statuses({ username: \\'' + cap[1] + '\\' })\"'\n      out += ' href=\"#/home/profile/' + cap[1] + '/statuses\">'\n        + cap[0]\n        + '</a>';\n      continue;\n    }\n\n    // tags\n    if (cap = inline.tags.exec(src)) {\n      src = src.substring(cap[0].length);\n      out += '<a ui-sref=\"home.home.tag({ tag: \\'' + cap[1] + '\\' })\"'\n      out += ' href=\"#/home/tag/' + cap[1] + '\">'\n        + cap[0]\n        + '</a>';\n      continue;\n    }\n\n    // br\n    if (cap = this.rules.br.exec(src)) {\n      src = src.substring(cap[0].length);\n      out += '<br>';\n      continue;\n    }\n\n    // del (gfm)\n    if (cap = this.rules.del.exec(src)) {\n      src = src.substring(cap[0].length);\n      out += '<del>'\n        + this.output(cap[1])\n        + '</del>';\n      continue;\n    }\n\n    // text\n    if (cap = this.rules.text.exec(src)) {\n      src = src.substring(cap[0].length);\n      out += escape(cap[0]);\n      continue;\n    }\n\n    if (src) {\n      throw new\n        Error('Infinite loop on byte: ' + src.charCodeAt(0));\n    }\n  }\n\n  return out;\n};\n\n/**\n * Compile Link\n */\n\nInlineLexer.prototype.outputLink = function(cap, link) {\n  if (cap[0][0] !== '!') {\n    return '<a target=\"_blank\" href=\"'\n      + escape(link.href)\n      + '\"'\n      + (link.title\n      ? ' title=\"'\n      + escape(link.title)\n      + '\"'\n      : '')\n      + '>'\n      + this.output(cap[1])\n      + '</a>';\n  } else {\n    return '<img src=\"'\n      + escape(link.href)\n      + '\" alt=\"'\n      + escape(cap[1])\n      + '\"'\n      + (link.title\n      ? ' title=\"'\n      + escape(link.title)\n      + '\"'\n      : '')\n      + '>';\n  }\n};\n\n/**\n * Mangle Links\n */\n\nInlineLexer.prototype.mangle = function(text) {\n  var out = ''\n    , l = text.length\n    , i = 0\n    , ch;\n\n  for (; i < l; i++) {\n    ch = text.charCodeAt(i);\n    if (Math.random() > 0.5) {\n      ch = 'x' + ch.toString(16);\n    }\n    out += '&#' + ch + ';';\n  }\n\n  return out;\n};\n\n/**\n * Parsing & Compiling\n */\n\nfunction Parser(options) {\n  this.tokens = [];\n  this.token = null;\n  this.options = options || marked.defaults;\n}\n\n/**\n * Static Parse Method\n */\n\nParser.parse = function(src, options) {\n  var parser = new Parser(options);\n  return parser.parse(src);\n};\n\n/**\n * Parse Loop\n */\n\nParser.prototype.parse = function(src) {\n  this.inline = new InlineLexer(src.links, this.options);\n  this.tokens = src.reverse();\n\n  var out = '';\n  while (this.next()) {\n    out += this.tok();\n  }\n\n  return out;\n};\n\n/**\n * Next Token\n */\n\nParser.prototype.next = function() {\n  return this.token = this.tokens.pop();\n};\n\n/**\n * Preview Next Token\n */\n\nParser.prototype.peek = function() {\n  return this.tokens[this.tokens.length-1] || 0;\n};\n\n/**\n * Parse Text Tokens\n */\n\nParser.prototype.parseText = function() {\n  var body = this.token.text;\n\n  while (this.peek().type === 'text') {\n    body += '\\n' + this.next().text;\n  }\n\n  return this.inline.output(body);\n};\n\n/**\n * Parse Current Token\n */\n\nParser.prototype.tok = function() {\n  switch (this.token.type) {\n    case 'space': {\n      return '';\n    }\n    case 'hr': {\n      return '<hr>\\n';\n    }\n    case 'heading': {\n      return '<h'\n        + this.token.depth\n        + '>'\n        + this.inline.output(this.token.text)\n        + '</h'\n        + this.token.depth\n        + '>\\n';\n    }\n    case 'code': {\n      if (this.options.highlight) {\n        var code = this.options.highlight(this.token.text, this.token.lang);\n        if (code != null && code !== this.token.text) {\n          this.token.escaped = true;\n          this.token.text = code;\n        }\n      }\n\n      if (!this.token.escaped) {\n        this.token.text = escape(this.token.text, true);\n      }\n\n      return '<pre><code'\n        + (this.token.lang\n        ? ' class=\"'\n        + this.options.langPrefix\n        + this.token.lang\n        + '\"'\n        : '')\n        + '>'\n        + this.token.text\n        + '</code></pre>\\n';\n    }\n    case 'table': {\n      var body = ''\n        , heading\n        , i\n        , row\n        , cell\n        , j;\n\n      // header\n      body += '<thead>\\n<tr>\\n';\n      for (i = 0; i < this.token.header.length; i++) {\n        heading = this.inline.output(this.token.header[i]);\n        body += this.token.align[i]\n          ? '<th align=\"' + this.token.align[i] + '\">' + heading + '</th>\\n'\n          : '<th>' + heading + '</th>\\n';\n      }\n      body += '</tr>\\n</thead>\\n';\n\n      // body\n      body += '<tbody>\\n'\n      for (i = 0; i < this.token.cells.length; i++) {\n        row = this.token.cells[i];\n        body += '<tr>\\n';\n        for (j = 0; j < row.length; j++) {\n          cell = this.inline.output(row[j]);\n          body += this.token.align[j]\n            ? '<td align=\"' + this.token.align[j] + '\">' + cell + '</td>\\n'\n            : '<td>' + cell + '</td>\\n';\n        }\n        body += '</tr>\\n';\n      }\n      body += '</tbody>\\n';\n\n      return '<table>\\n'\n        + body\n        + '</table>\\n';\n    }\n    case 'blockquote_start': {\n      var body = '';\n\n      while (this.next().type !== 'blockquote_end') {\n        body += this.tok();\n      }\n\n      return '<blockquote>\\n'\n        + body\n        + '</blockquote>\\n';\n    }\n    case 'list_start': {\n      var type = this.token.ordered ? 'ol' : 'ul'\n        , body = '';\n\n      while (this.next().type !== 'list_end') {\n        body += this.tok();\n      }\n\n      return '<'\n        + type\n        + '>\\n'\n        + body\n        + '</'\n        + type\n        + '>\\n';\n    }\n    case 'list_item_start': {\n      var body = '';\n\n      while (this.next().type !== 'list_item_end') {\n        body += this.token.type === 'text'\n          ? this.parseText()\n          : this.tok();\n      }\n\n      return '<li>'\n        + body\n        + '</li>\\n';\n    }\n    case 'loose_item_start': {\n      var body = '';\n\n      while (this.next().type !== 'list_item_end') {\n        body += this.tok();\n      }\n\n      return '<li>'\n        + body\n        + '</li>\\n';\n    }\n    case 'html': {\n      return !this.token.pre && !this.options.pedantic\n        ? this.inline.output(this.token.text)\n        : this.token.text;\n    }\n    case 'paragraph': {\n      return '<p>'\n        + this.inline.output(this.token.text)\n        + '</p>\\n';\n    }\n    case 'text': {\n      return '<p>'\n        + this.parseText()\n        + '</p>\\n';\n    }\n  }\n};\n\n/**\n * Helpers\n */\n\nfunction escape(html, encode) {\n  return html\n    .replace(!encode ? /&(?!#?\\w+;)/g : /&/g, '&amp;')\n    .replace(/</g, '&lt;')\n    .replace(/>/g, '&gt;')\n    .replace(/\"/g, '&quot;')\n    .replace(/'/g, '&#39;');\n}\n\nfunction shortenUrl(url) {\n    if (url.length < 67) {\n        return url;\n    } else {\n        return url.substring(0, 64) + \"...\";\n    }\n}\n\nfunction replace(regex, opt) {\n  regex = regex.source;\n  opt = opt || '';\n  return function self(name, val) {\n    if (!name) return new RegExp(regex, opt);\n    val = val.source || val;\n    val = val.replace(/(^|[^\\[])\\^/g, '$1');\n    regex = regex.replace(name, val);\n    return self;\n  };\n}\n\nfunction noop() {}\nnoop.exec = noop;\n\nfunction merge(obj) {\n  var i = 1\n    , target\n    , key;\n\n  for (; i < arguments.length; i++) {\n    target = arguments[i];\n    for (key in target) {\n      if (Object.prototype.hasOwnProperty.call(target, key)) {\n        obj[key] = target[key];\n      }\n    }\n  }\n\n  return obj;\n}\n\n/**\n * Marked\n */\n\nfunction marked(src, opt) {\n  try {\n    if (opt) opt = merge({}, marked.defaults, opt);\n    return Parser.parse(Lexer.lex(src, opt), opt);\n  } catch (e) {\n    e.message += '\\nPlease report this to https://github.com/chjj/marked.';\n    if ((opt || marked.defaults).silent) {\n      return '<p>An error occured:</p><pre>'\n        + escape(e.message + '', true)\n        + '</pre>';\n    }\n    throw e;\n  }\n}\n\n/**\n * Options\n */\n\nmarked.options =\nmarked.setOptions = function(opt) {\n  merge(marked.defaults, opt);\n  return marked;\n};\n\nmarked.defaults = {\n  gfm: true,\n  tables: true,\n  breaks: false,\n  pedantic: false,\n  sanitize: false,\n  // urls : [function(text, url){ return 'html'; }]\n  smartLists: false,\n  silent: false,\n  highlight: null,\n  langPrefix: 'lang-'\n};\n\n/**\n * Expose\n */\n\nmarked.Parser = Parser;\nmarked.parser = Parser.parse;\n\nmarked.Lexer = Lexer;\nmarked.lexer = Lexer.lex;\n\nmarked.InlineLexer = InlineLexer;\nmarked.inlineLexer = InlineLexer.output;\n\nmarked.parse = marked;\n\nif (typeof exports === 'object') {\n  module.exports = marked;\n} else if (typeof define === 'function' && define.amd) {\n  define(function() { return marked; });\n} else {\n  this.marked = marked;\n}\n\n}).call(function() {\n  return this || (typeof window !== 'undefined' ? window : global);\n}());\n"
  },
  {
    "path": "web/src/main/webapp/assets/vendor/js/respond/respond.js",
    "content": "/*! Respond.js v1.4.2: min/max-width media query polyfill\n * Copyright 2013 Scott Jehl\n * Licensed under MIT\n * http://j.mp/respondjs */\n\n!function(a){\"use strict\";a.matchMedia=a.matchMedia||function(a){var b,c=a.documentElement,d=c.firstElementChild||c.firstChild,e=a.createElement(\"body\"),f=a.createElement(\"div\");return f.id=\"mq-test-1\",f.style.cssText=\"position:absolute;top:-100em\",e.style.background=\"none\",e.appendChild(f),function(a){return f.innerHTML='&shy;<style media=\"'+a+'\"> #mq-test-1 { width: 42px; }</style>',c.insertBefore(e,d),b=42===f.offsetWidth,c.removeChild(e),{matches:b,media:a}}}(a.document)}(this),function(a){\"use strict\";function b(){v(!0)}var c={};a.respond=c,c.update=function(){};var d=[],e=function(){var b=!1;try{b=new a.XMLHttpRequest}catch(c){b=new a.ActiveXObject(\"Microsoft.XMLHTTP\")}return function(){return b}}(),f=function(a,b){var c=e();c&&(c.open(\"GET\",a,!0),c.onreadystatechange=function(){4!==c.readyState||200!==c.status&&304!==c.status||b(c.responseText)},4!==c.readyState&&c.send(null))},g=function(a){return a.replace(c.regex.minmaxwh,\"\").match(c.regex.other)};if(c.ajax=f,c.queue=d,c.unsupportedmq=g,c.regex={media:/@media[^\\{]+\\{([^\\{\\}]*\\{[^\\}\\{]*\\})+/gi,keyframes:/@(?:\\-(?:o|moz|webkit)\\-)?keyframes[^\\{]+\\{(?:[^\\{\\}]*\\{[^\\}\\{]*\\})+[^\\}]*\\}/gi,comments:/\\/\\*[^*]*\\*+([^/][^*]*\\*+)*\\//gi,urls:/(url\\()['\"]?([^\\/\\)'\"][^:\\)'\"]+)['\"]?(\\))/g,findStyles:/@media *([^\\{]+)\\{([\\S\\s]+?)$/,only:/(only\\s+)?([a-zA-Z]+)\\s?/,minw:/\\(\\s*min\\-width\\s*:\\s*(\\s*[0-9\\.]+)(px|em)\\s*\\)/,maxw:/\\(\\s*max\\-width\\s*:\\s*(\\s*[0-9\\.]+)(px|em)\\s*\\)/,minmaxwh:/\\(\\s*m(in|ax)\\-(height|width)\\s*:\\s*(\\s*[0-9\\.]+)(px|em)\\s*\\)/gi,other:/\\([^\\)]*\\)/g},c.mediaQueriesSupported=a.matchMedia&&null!==a.matchMedia(\"only all\")&&a.matchMedia(\"only all\").matches,!c.mediaQueriesSupported){var h,i,j,k=a.document,l=k.documentElement,m=[],n=[],o=[],p={},q=30,r=k.getElementsByTagName(\"head\")[0]||l,s=k.getElementsByTagName(\"base\")[0],t=r.getElementsByTagName(\"link\"),u=function(){var a,b=k.createElement(\"div\"),c=k.body,d=l.style.fontSize,e=c&&c.style.fontSize,f=!1;return b.style.cssText=\"position:absolute;font-size:1em;width:1em\",c||(c=f=k.createElement(\"body\"),c.style.background=\"none\"),l.style.fontSize=\"100%\",c.style.fontSize=\"100%\",c.appendChild(b),f&&l.insertBefore(c,l.firstChild),a=b.offsetWidth,f?l.removeChild(c):c.removeChild(b),l.style.fontSize=d,e&&(c.style.fontSize=e),a=j=parseFloat(a)},v=function(b){var c=\"clientWidth\",d=l[c],e=\"CSS1Compat\"===k.compatMode&&d||k.body[c]||d,f={},g=t[t.length-1],p=(new Date).getTime();if(b&&h&&q>p-h)return a.clearTimeout(i),i=a.setTimeout(v,q),void 0;h=p;for(var s in m)if(m.hasOwnProperty(s)){var w=m[s],x=w.minw,y=w.maxw,z=null===x,A=null===y,B=\"em\";x&&(x=parseFloat(x)*(x.indexOf(B)>-1?j||u():1)),y&&(y=parseFloat(y)*(y.indexOf(B)>-1?j||u():1)),w.hasquery&&(z&&A||!(z||e>=x)||!(A||y>=e))||(f[w.media]||(f[w.media]=[]),f[w.media].push(n[w.rules]))}for(var C in o)o.hasOwnProperty(C)&&o[C]&&o[C].parentNode===r&&r.removeChild(o[C]);o.length=0;for(var D in f)if(f.hasOwnProperty(D)){var E=k.createElement(\"style\"),F=f[D].join(\"\\n\");E.type=\"text/css\",E.media=D,r.insertBefore(E,g.nextSibling),E.styleSheet?E.styleSheet.cssText=F:E.appendChild(k.createTextNode(F)),o.push(E)}},w=function(a,b,d){var e=a.replace(c.regex.comments,\"\").replace(c.regex.keyframes,\"\").match(c.regex.media),f=e&&e.length||0;b=b.substring(0,b.lastIndexOf(\"/\"));var h=function(a){return a.replace(c.regex.urls,\"$1\"+b+\"$2$3\")},i=!f&&d;b.length&&(b+=\"/\"),i&&(f=1);for(var j=0;f>j;j++){var k,l,o,p;i?(k=d,n.push(h(a))):(k=e[j].match(c.regex.findStyles)&&RegExp.$1,n.push(RegExp.$2&&h(RegExp.$2))),o=k.split(\",\"),p=o.length;for(var q=0;p>q;q++)l=o[q],g(l)||m.push({media:l.split(\"(\")[0].match(c.regex.only)&&RegExp.$2||\"all\",rules:n.length-1,hasquery:l.indexOf(\"(\")>-1,minw:l.match(c.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||\"\"),maxw:l.match(c.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||\"\")})}v()},x=function(){if(d.length){var b=d.shift();f(b.href,function(c){w(c,b.href,b.media),p[b.href]=!0,a.setTimeout(function(){x()},0)})}},y=function(){for(var b=0;b<t.length;b++){var c=t[b],e=c.href,f=c.media,g=c.rel&&\"stylesheet\"===c.rel.toLowerCase();e&&g&&!p[e]&&(c.styleSheet&&c.styleSheet.rawCssText?(w(c.styleSheet.rawCssText,e,f),p[e]=!0):(!/^([a-zA-Z:]*\\/\\/)/.test(e)&&!s||e.replace(RegExp.$1,\"\").split(\"/\")[0]===a.location.host)&&(\"//\"===e.substring(0,2)&&(e=a.location.protocol+e),d.push({href:e,media:f})))}x()};y(),c.update=y,c.getEmValue=u,a.addEventListener?a.addEventListener(\"resize\",b,!1):a.attachEvent&&a.attachEvent(\"onresize\",b)}}(this);"
  },
  {
    "path": "web/src/main/webapp/css/ie-only.css",
    "content": ".navbar-brand {\n\twidth: 150px;\n}\n\nselect,\ntextarea,\ninput[type=\"text\"],\ninput[type=\"password\"],\ninput[type=\"datetime\"],\ninput[type=\"datetime-local\"],\ninput[type=\"date\"],\ninput[type=\"month\"],\ninput[type=\"time\"],\ninput[type=\"week\"],\ninput[type=\"number\"],\ninput[type=\"email\"],\ninput[type=\"url\"],\ninput[type=\"search\"],\ninput[type=\"tel\"],\ninput[type=\"color\"] {\n\tmin-height: inherit;\n}"
  },
  {
    "path": "web/src/main/webapp/css/tatami.css",
    "content": "@media screen and (max-width: 767px) {\n    .navbar .nav, .navbar .navbar-form {\n        float: none;\n    }\n\n    .nav > li > .dropdown-menu {\n        position: static;\n        float: none;\n\n    }\n\n    .nav li.dropdown-submenu > ul.dropdown-menu {\n        position: initial;\n        z-index: 0;\n        float: none;\n        margin: 0;\n\n    }\n\n    #tatamiBody {\n        padding: 0;\n    }\n}\n.noRadius\n{\n    border-radius: 0;\n}\n\n.noCollapse\n{\n    border-collapse: separate;\n}\n\n.noBorder{\n    border-top : 0;\n}\n\n.noRadius {\n    border-radius: 0;\n}\n\n\n#basicMap {\n    width: 100%;\n    height: 100%;\n    margin: 0;\n}\n\n#geolocMapPreview {\n    width: 100%;\n    height: 100%;\n    margin: 0;\n}\n\n.alertColor{\n    padding: 8px 15px 8px 14px;\n    margin-bottom: 20px;\n    color: #c09853;\n    background-color: #fcf8e3;\n    border: 1px solid #fbeed5;\n    border-radius: 4px;\n}\n@media screen and (min-width: 767px) {\n    #tatamiBody {\n        padding: 10px 15px 10px 0;\n    }\n}\n\nbody {\n    background-image: url(/img/wallpaper.jpg);\n}\n\nh4 {\n    font-size: inherit;\n}\n\n.well {\n    box-shadow: none;\n    border-radius: 5px;\n}\n\n.well h4 {\n    margin: 0;\n}\n\n.labelSizeNormal{\n    font-size: 100%;\n}\n\n.tabMenu{\n    margin-bottom: 15px;\n    margin-top: 10px;\n}\n\n.navbar {\n    background-color: black;\n}\n.controle-group\n{\n  padding: 0 0 5px;\n    padding-top: 10px;\n    }\n.quota {\n    color: #333333;\n    font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n    font-size: 14px;\n;\n}\n\n.nomargin {\n      margin: 0;\n}\n\n.file-table\n{\ndisplay: block;\n}\n\n.displayBlock\n{\n    display: block;\n}\n\n.fileItem\n{\n    width: 100%;\n    display: inline-table;\n    border-top: 1px solid #dddddd;\n    padding: 8px;\n}\n\n\ndiv.jGrowl-notification{\n    background-color : transparent;\n    opacity : 1;\n}\n\n.little-marge-right{\n    margin-right: 20px\n}\n\n.mediumHeight{\n    height: 13px;\n}\n\n.smallPaddingLeft {\n    padding-left: 10px;\n}\n\n.little-height{\n    height: 10px;\n}\n\n.littleMargeBot{\n    margin-bottom: 10px;\n}\n\n.little-padding-top{\n    padding-top: 3px;\n}\n.little-marge-top{\n    margin-top: 5px;\n}\n\n.little-padding\n{\n    padding: 0.10em 0.6em;\n}\n#updateAvatar{\n    position: relative;\n    cursor: hand;\n    cursor: pointer;\n}\n\n#updateAvatar input[type=file] {\n    opacity: 0;\n    position: absolute;\n    top: 0;\n    left: 0;\n    height: 210px;\n    width: 550px;\n\n}\n\n\n.avatar-float-left-container  {\n    margin-left: 15px;\n    margin-top: 15px;\n    margin-bottom: 0;\n    margin-right: 15px;\n}\n\n.navbar .nav > li > a {\n    color: #CCCCCC;\n}\n\n.navbar .nav > li > a:hover {\n    color: white;\n}\n\n.navbar .nav li.dropdown > .dropdown-toggle .caret {\n    border-top-color: #CCCCCC;\n    border-bottom-color: #CCCCCC;\n}\n\n.navbar .nav li.dropdown > .dropdown-toggle .caret:hover {\n    border-top-color: white;\n    border-bottom-color: white;\n}\n\n.navbar .nav li.dropdown.open > .dropdown-toggle {\n    color: white;\n    background-color: inherit;\n}\n\n.img {\n    width: 50px;\n    height: 50px;\n    display: inline-block;\n}\n\n.img-small {\n    width: 25px;\n    height: 25px;\n    background-position: center center;\n    background-size: cover;\n    -ms-behavior: url(/css/vendor/backgroundsize.min.htc);\n}\n\n.img-reply {\n    width: 35px;\n    height: 35px;\n    margin-left: 10px;\n    background-position: center center;\n    background-size: cover;\n    -ms-behavior: url(/css/vendor/backgroundsize.min.htc);\n}\n\n.img-medium {\n    width: 50px;\n    height: 50px;\n    background-position: center center;\n    background-size: cover;\n    -ms-behavior: url(/css/vendor/backgroundsize.min.htc);\n}\n\n.img-big {\n    width: 70px;\n    height: 70px;\n    background-position: center center;\n    background-size: cover;\n    -ms-behavior: url(/css/vendor/backgroundsize.min.htc);\n}\n\n.navbar-edit {\n    line-height: 14px;\n    left: 10px;\n    width: 48px;\n    padding: 4px 13px 3px;\n    background-color: #428bca;\n}\n\n.navbar-edit:hover,\n.navbar-edit:focus {\n    background-color: #ddd;\n}\n\n.page-header {\n    margin-top: 0;\n    margin-bottom: 0;\n    padding-bottom: 0;\n}\n\n.img-rounded {\n    /*border-radius: 15px;*/\n}\n\n.navbar .btn-navbar.fix-navbar {\n    height: 14px;\n    padding-top: 6px;\n    line-height: 14px;\n    font-size: 12px;\n}\n\n.tatam *, .trends *, .profile *, .preview-tatam *, .profile-card, .wrap * {\n    /* white-space: normal; */\n    word-wrap: break-word;\n}\n\n\n.status-actions {\n    margin-left: -60px;\n}\n\n.status-action {\n    padding: 0;\n    margin: 0;\n}\n\n.status-action:hover {\n    text-decoration: none;\n}\n\n.profile-card > .img {\n    margin-right: 5px;\n    background-size: contain;\n}\n\n/*.tatam, .useritem {*/\n.useritem {\n    padding: 0 5px 0 0;\n    overflow: hidden;\n    display: none;\n    border: 1px solid #CCCCCC;\n    background-color: white;\n    margin-bottom: -1px;\n}\n.desactivated {\n    /* Fallback for web browsers that don't support RGBa */\n    background-color: rgb(255,64,64);\n    /* RGBa with 0.6 opacity */\n    background-color: rgba(241, 241, 241, 0.65) !important;\n}\n.useritemmini {\n    padding: 0 5px 1px 35px;\n    overflow: hidden;\n    display: none;\n}\n\n.user-profile {\n    margin:0px;\n    color:#252525;\n}\n\n.useritemmini h6 {\n    margin-top: 5px;\n    margin-bottom: 5px;\n    line-height: 12px\n}\n\n.useritem, .useritemmini {\n    display: block;\n    padding: 5px;\n}\n\n.mention-share {\n    font-size: 80%;\n    color: #888888;\n}\n\n.tatam.favorite {\n    background-image: url(img/favorite.png);\n    background-repeat: no-repeat;\n    background-position: right top;\n}\n\n.favorite {\n    background-image: url(img/favorite.png);\n    background-repeat: no-repeat;\n    background-position: right top;\n}\n\n.tatam.share {\n    background-image: url(img/shared.png);\n    background-repeat: no-repeat;\n    background-position: right top;\n}\n\n.share {\n    background-image: url(img/shared.png);\n    background-repeat: no-repeat;\n    background-position: right top;\n}\n\n.tatam.both {\n    background-image: url(img/both.png);\n    background-repeat: no-repeat;\n    background-position: right top;\n}\n\n.both {\n    background-image: url(img/both.png);\n    background-repeat: no-repeat;\n    background-position: right top;\n}\n\n.pointer {\n    cursor: pointer;\n}\n\n.tatam > div:first-child, .useritem > div:first-child {\n    /*margin-left: -60px;*/\n    padding: 5px;\n}\n\n.useritemmini > div:first-child {\n    margin-left: -35px;\n    padding: 5px;\n}\n\n.tatam > header {\n    padding-bottom: 0;\n    margin-bottom: 0;\n}\n\n.tatams {\n    /*margin-bottom: 15px;*/\n}\n\n.tatam > div:first-child, .useritem > div:first-child {\n    padding: 5px 10px 0 10px;\n}\n\n.tatams > * {\n    margin-bottom: 0;\n    padding-bottom: 0;\n}\n\n@media screen and (min-width: 767px) {\n    .tatam-hover:hover{\n        background-color: #ECF1F7;\n    }\n}\n\n.tatams > *:last-child {\n    margin-bottom: 0;\n}\n\n.tatams-share {\n    padding-top: 5px;\n    /*border-top: 2px solid #bcbcbc;*/\n}\n\n.tatams-share-title {\n    border-right: 2px solid #bcbcbc;\n    padding-right: 5px;\n    margin: 5px;\n}\n\n.tatams-share-img {\n    margin-top: 5px;\n}\n\n/*.tatams-discussion {\n    margin-top: 0;\n    margin-left: -60px;\n}*/\n\n.tatams-discussion > .tatam > header {\n    margin-top: 0;\n    margin-bottom: 0;\n}\n\n.edit-tatam-float-right {\n    position: absolute;\n    right: 0;\n    margin-right: 40px;\n    padding: 2px;\n}\n\n.refresh-button {\n\n}\n\n.refresh-button-style {\n    border-top: 1px solid #CCCCCC;\n    border-left: 1px solid #CCCCCC;\n    border-right: 1px solid #CCCCCC;\n    border-bottom: 1px solid #CCCCCC;\n    margin-bottom: -1px;\n    padding: 10px;\n    box-shadow: inset 0 3px 8px rgba(0,0,0,.05);\n}\n\n.dropzone {\n    line-height: 50px;\n    text-align: center;\n    font-weight: bold;\n    border-style: dashed;\n    border-width: 2px;\n    border-color: #808080;\n}\n\n.dropzone.in {\n    border-style: dashed;\n    border-width: 2px;\n    border-color: #0088cc;\n}\n\n/* Style for degradated fileUpload on IE8 */\n.controlsIE {\ntext-align: left;\nvertical-align: middle;\nmargin-bottom: 20px;\n}\n\n.controlsIE p {\n    font-size: 1.1em;\n}\n\n.controlsIE span.glyphicon, span.upload-ko, span.upload-ok {\n    padding-left: 15px;\n    margin-top: 10px;\n\n}\n\n.controlsIE span.upload-ko, .controlsIE span.upload-ok, span.hidden-label {\n    display: none;\n}\n\n.tatam {\n    background-color: white;\n    border-top: 1px solid #CCCCCC;\n    border-bottom: 1px solid #CCCCCC;\n    padding: 0;\n    margin-bottom: -1px;\n    overflow: hidden;\n    display: none;\n}\n\n.tatam-border-lr {\n    border-right: 1px solid #CCCCCC;\n    border-left: 1px solid #CCCCCC;\n    margin-bottom: 5px;\n}\n\n.tatam-first {\n    border-top: 0;\n}\n\n.tatam-last {\n    border-bottom: 0;\n}\n\n@media screen and (min-width: 767px) {\n    .tatams-margin {\n        margin-top: 10px;\n    }\n}\n\n@media screen and (max-width: 767px) {\n    .tatams-margin {\n        margin-top: -1px;\n    }\n}\n\n.tatam blockquote p {\n    font-size: 0.8em;\n}\n\n.tatams-content-title {\n    border-top: 1px solid #CCCCCC;\n    border-left: 1px solid #CCCCCC;\n    border-right: 1px solid #CCCCCC;\n    background-color: white;\n    margin-bottom: 0;\n    border-radius: 5px 5px 0 0;\n}\n\n.tatams-content h3 {\n    padding: 5px 10px 5px 10px;\n    margin: 0;\n    font-weight: normal;\n    font-size: 1.4em;\n}\n\n.btn-title {\n    margin-top: 2px;\n    margin-left: 5px;\n}\n\n.tatams-content hr {\n    padding: 0;\n    margin: 0;\n    border-top: 1px solid #CCCCCC;\n    margin-bottom: -2px;\n}\n\n.tatams-container {\n    min-height: 75px;\n    background-image: url(/img/wallpaper.jpg);\n}\n\n.tatam-expand-container {\n    border-top: 1px solid #CCCCCC;\n    border-bottom: 1px solid #CCCCCC;\n    border-radius: 5px;\n}\n\n.tatam-background {\n    background-color: #ECF1F7;\n}\n\n.homebody-nav {\n    background-color: white;\n}\n\n.nav-justified {\n    border-collapse: collapse;\n}\n\n.nav-justified > li {\n    border: 1px solid #CCCCCC;\n    padding: 0;\n}\n\n.nav-tabs > li > a {\n    border-radius: 0;\n}\n\n.homebody-nav {\n    background-color: white;\n}\n\n.homebody-nav .active a {\n    color: #333333;\n}\n\n.nav-tabs.nav-justified > .active > a {\n    border-bottom-color: #CCCCCC;\n}\n\n/**\n* Search Engine\n**/\n\n.typeahead.dropdown-menu.hasCategory{\n    /*width: 280px;*/\n    background: #EDEDED;\n    padding: 0;\n}\n\n@media screen and (max-width: 767px) {\n    .typeahead.dropdown-menu.hasCategory{\n        position: static;\n        width: 100%;\n    }\n}\n\n@media (min-width: 979px) {\n  .typeahead.dropdown-menu.hasCategory{\n    margin-left: -53px;\n  }\n\n  #searchHeader{\n    width: 320px;\n  }\n}\n\n.hasCategory .item{\n    height: 100%;\n    margin-left: 40px;\n    background: #FFFFFF;\n    cursor: pointer;\n}\n.hasCategory .category{\n    cursor: default;\n    height: auto;\n    background: #EDEDED;\n    padding: 6px 5px 5px 13px;\n    width:30px;\n}\n.hasCategory li.first{\n    margin-top:-31px;\n}\n.hasCategory li.first, .hasCategory .category{\n    /*border-top: 1px solid #CCCCCC;*/\n}\n.hasCategory li.item.active a{\n    height: 24px;\n    padding:0;\n}\n.hasCategory li:first-child{\n    border-top: none;\n}\n.hasCategory li.item img{\n    display: block;\n    float: left;\n    margin: 2px 8px 0 3px;\n    border-radius: 3px;\n    -moz-border-radius: 3px;\n    -webkit-border-radius: 3px;\n}\n.hasCategory li.item h4{\n    font-size: 12px;\n    margin: 0 1px 0 0;\n}\n.hasCategory li.item h4 a{\n    color:#000;\n    padding:0;\n}\n.hasCategory li.item p{\n    font-size: 11px;\n    margin: 0;\n    overflow: hidden;\n    height: auto;\n    line-height: 11px;\n}\n.hasCategory li.item.users, .hasCategory li.item.groups{\n    padding: 3px 0 4px 5px;\n}\n.hasCategory li.item.active,\n.hasCategory li.item:hover {\n    color: #ffffff;\n    text-decoration: none;\n    background-color: #0081c2;\n    background-image: -moz-linear-gradient(top, #0088cc, #0077b3);\n    background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));\n    background-image: -webkit-linear-gradient(top, #0088cc, #0077b3);\n    background-image: -o-linear-gradient(top, #0088cc, #0077b3);\n    background-image: linear-gradient(to bottom, #0088cc, #0077b3);\n    background-repeat: repeat-x;\n    outline: 0;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);\n}\n.hasCategory li.item a:hover{\n    text-decoration: none;\n}\n.hasCategory li.tags a{\n    padding: 3px 10px;\n}\n.hasCategory li.groups p{\n    margin-left: 10px;\n    margin-top: -2px;\n}\n.box-info{\n    background: none;\n    border: none;\n    box-shadow: none;\n}\n\n.nav-collapse .dropdown-menu .divider {\n  display: block;\n  height: 0;\n  border-bottom: 1px solid #CCCCCC;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n  -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);\n}\n\n.background-image-fffix {\n    overflow: auto;\n}\n\n.share-img-fffix{\n    display: inline-block;\n}\n\n.background-image-fffix img {\n    display: block;\n}\n\n.searchbody h3 {\n    padding: 0;\n    margin: 0;\n    font-weight: normal;\n    font-size: 1.4em;\n}\n\n.searchbody hr {\n    padding: 0;\n    margin: 0;\n    border-top: 1px solid #CCCCCC;\n    margin-top: 10px;\n}\n\n.deleteicon {\n    position: absolute;\n    display: block;\n    top: 9px;\n    right: 22px;\n    cursor: pointer;\n}\n\n.statusitem-name {\n    padding: 0;\n    margin: 0;\n    margin-top: -4px;\n    margin-bottom: 7px;\n}\n\n.statusitem-content {\n    margin-bottom: 5px;\n\n}\n\n.statusitem-footer {\n    padding: 0;\n}\n\n.markdown p {\n    margin: 0 0 0.5em 0;\n}\n\n#current {\n    padding: 10px;\n    padding-top : 7px;\n}\n\n#before{\n    padding: 0;\n    margin: 0;\n}\n\n#after {\n\n}\n\n#status-content-container {\n    margin-left: 65px;\n    margin-right: 30px;\n}\n\n.statusitem-img {\n    margin-bottom: 5px;\n    margin-right: 5px;\n}\n\n.attachments {\n    margin-top: 5px;\n}\n\n@media screen and (min-width: 767px) {\n    #buttons {\n        clear: both;\n        margin-left: 60px;\n    }\n}\n@media screen and (max-width: 767px) {\n    #buttons {\n        clear: both;\n    }\n\n    .statusitem-footer {\n        background-color: #ECF1F7;\n        border-top: 1px solid #CCCCCC;\n        padding-left: 8px;\n    }\n\n    .button-ios {\n        margin-left: -2px;\n        margin-right: -2px;\n        margin: 2px 4px 2px 0;\n    }\n\n    .button-ios-right {\n        border-right: 1px solid #CCCCCC;\n    }\n\n}\n\n.image-preview-template {\n    margin-top: 5px;\n    margin-bottom: 5px;\n}\n\n.image-preview-container {\n    display: table;\n    margin: 0 auto;\n    max-width: 500px;\n}\n\n.image-preview-element {\n    margin-left: 5px;\n    margin-bottom: 5px;\n    float: left;\n}\n\n.image-preview-element img {\n    max-width: 245px;\n    max-height: 195px;\n}\n\n.image-preview-element-1 {\n    margin-left: 5px;\n    margin-bottom: 5px;\n}\n\n.image-preview-element-1 img {\n    max-width: 500px;\n    max-height: 400px;\n}\n\n@media screen and (min-width: 767px) {\n\n    .slider-container {\n        display: table;\n        margin: 0 auto;\n        margin-top: 20px;\n        background-color: black;\n        position: relative;\n        width: 900px;\n        height: 550px;\n    }\n\n    .slider-container .slider-container-img {\n        background-color: black;\n        text-align: center;\n        width: 900px;\n        line-height: 550px;\n        height: 550px;\n    }\n\n    .slider-container .slider-container-img img {\n        vertical-align: middle;\n        max-width: 900px;\n        max-height: 550px;\n    }\n\n}\n\n@media screen and (max-width: 767px) {\n\n    .slider-container {\n        display: table;\n        margin: 0 auto;\n        margin-top: 20px;\n        background-color: black;\n        position: relative;\n        width: 500px;\n        height: 550px;\n    }\n\n    .slider-container .slider-container-img {\n        background-color: black;\n        text-align: center;\n        width: 500px;\n        line-height: 550px;\n        height: 550px;\n    }\n\n    .slider-container .slider-container-img img {\n        vertical-align: middle;\n        max-width: 500px;\n        max-height: 550px;\n    }\n\n}\n\n\n\n\n.slider-container .slider-container-header {\n    height: 0;\n    text-align: right;\n    margin-right: 5px;\n}\n\n.slider-container .slider-container-left {\n\n}\n\n\n.slider-container .slider-container-right {\n\n}\n\n.slider-container .slider-button {\n    color: white;\n    text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black;\n    padding: 0;\n    cursor: pointer;\n    background: transparent;\n    opacity: 0.6;\n    border: 0;\n    font-size: 2em;\n    font-weight: bold;\n}\n\n.slider-container .slider-button-close {\n\n}\n\n.slider-container .slider-button-left {\n    position: absolute;\n    left: 10px;\n    bottom: 50%;\n}\n\n.slider-container .slider-button-right {\n    position: absolute;\n    right: 10px;\n    bottom: 50%;\n}\n\n"
  },
  {
    "path": "web/src/main/webapp/css/vendor/backgroundsize.min.htc",
    "content": "<!-- background-size-polyfill v0.2.0 | (c) 2012-2013 Louis-Rémi Babé | MIT License -->\n<PUBLIC:COMPONENT lightWeight=\"true\">\n<PUBLIC:ATTACH EVENT=\"oncontentready\" ONEVENT=\"o.init()\" />\n<PUBLIC:ATTACH EVENT=\"ondocumentready\" ONEVENT=\"o.init()\" />\n<PUBLIC:ATTACH EVENT=\"onpropertychange\" ONEVENT=\"o.handlePropertychange()\" />\n<PUBLIC:ATTACH EVENT=\"ondetach\" ONEVENT=\"o.restore()\" />\n<PUBLIC:ATTACH EVENT=\"onresize\" FOR=\"window\" ONEVENT=\"o.handleResize()\" />\n<PUBLIC:EVENT NAME=\"onbackgroundupdate\" ID=\"updateEvent\" />\n<script type=\"text/javascript\">\nvar o;!function(a,b){var c=/url\\([\"']?(.*?)[\"']?\\)/,d=/^\\s\\s*/,e=/\\s\\s*$/,f=/\\s\\s*/g,g=/%$/,h={top:0,left:0,bottom:1,right:1,center:.5},i=a.document,j=\"data:image/gif;base64,R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\",k=\"background-size-polyfill\",l=function(){},m=100,n,p,q,r;function s(){var b=i.createElement(\"div\"),c=i.createElement(\"img\"),d=b.style,e=a.style,f=a.currentStyle,g=a.bgsExpando,h=a.firstChild;g&&(g.restore&&(e.backgroundImage=g.restore.backgroundImage,e.position=g.restore.position,e.zIndex=g.restore.zIndex),h&&\"DIV\"===(h.nodeName||\"\").toUpperCase()&&h.className===k&&a.removeChild(h)),t(b),b.className=k,d.top=d.right=d.bottom=d.left=0,d.position=\"fixed\",t(c),c.alt=\"\",b.appendChild(c),a.insertBefore(b,a.firstChild),a.bgsExpando=g={wrapper:b,img:c,restore:{backgroundImage:e.backgroundImage,position:e.position,zIndex:e.zIndex},current:{},next:null,processing:!1,loadImg:null,display:!1,changed:!1,ignore:!1,canFixed:\"BODY\"===a.nodeName.toUpperCase()&&b.offsetHeight>0},d.position=\"absolute\",\"auto\"===f.zIndex&&(e.zIndex=0),\"static\"===f.position&&(e.position=\"relative\"),o={init:l,handlePropertychange:D,restore:F,handleResize:E},D()}function t(a){var b=a.style;b.position=\"absolute\",b.display=\"block\",b.zIndex=-1,b.overflow=\"hidden\",b.visibility=\"inherit\",b.width=b.height=b.top=b.right=b.bottom=b.left=b.cursor=\"auto\",b.margin=b.padding=b.border=b.outline=b.minWidth=b.minHeight=0,b.background=b.maxWidth=b.maxHeight=\"none\",b.fontSize=b.lineHeight=\"1em\"}function u(a,c,d){var e;c?(e=i.createElement(\"img\"),e.onload=e.onerror=function(){var c=this.width,e=this.height;\"error\"===b.event.type&&(c=e=0),a.loadImg=this.onload=this.onerror=null,d(c,e)},e.src=c):e={callbackId:b.setTimeout(function(){a.loadImg=null,d(0,0)},0)},a.loadImg=e,e=null}function v(a){var b=o.handlePropertychange;o.handlePropertychange=l,a(),o.handlePropertychange=b}function w(a,b){var c=a.currentStyle.display;return c!==b.display&&(b.display=c,b.changed=!0),\"none\"!==c}function x(a,b){var d=a.style,e=a.currentStyle,f=b.restore,i=y(e[\"background-size\"]),k=i.split(\" \"),l={innerWidth:a.offsetWidth-(parseFloat(e.borderLeftWidth)||0)-(parseFloat(e.borderRightWidth)||0),innerHeight:a.offsetHeight-(parseFloat(e.borderTopWidth)||0)-(parseFloat(e.borderBottomWidth)||0),size:i,sizeIsKeyword:\"contain\"===i||\"cover\"===i,sizeX:k[0],sizeY:k.length>1?k[1]:\"auto\",posX:e.backgroundPositionX,posY:e.backgroundPositionY,attachment:e.backgroundAttachment,src:\"\",imgWidth:0,imgHeight:0};return l.sizeIsKeyword||((parseFloat(l.sizeX)>=0||\"auto\"===l.sizeX)&&(parseFloat(l.sizeY)>=0||\"auto\"===l.sizeY)||(l.sizeX=l.sizeY=\"auto\"),g.test(l.sizeX)&&(l.sizeX=(l.innerWidth*parseFloat(l.sizeX)/100||0)+\"px\"),g.test(l.sizeY)&&(l.sizeY=(l.innerHeight*parseFloat(l.sizeY)/100||0)+\"px\")),(l.posX in h||g.test(l.posX))&&(l.posX=h[l.posX]||parseFloat(l.posX)/100||0),(l.posY in h||g.test(l.posY))&&(l.posY=h[l.posY]||parseFloat(l.posY)/100||0),(c.exec(d.backgroundImage)||[])[1]===j?v(function(){d.backgroundImage=f.backgroundImage}):f.backgroundImage=d.backgroundImage,l.src=(c.exec(e.backgroundImage)||[])[1],v(function(){d.backgroundImage=\"url(\"+j+\")\"}),l}function y(a){return String(a).replace(d,\"\").replace(e,\"\").replace(f,\" \")}function z(a,c){var d=c.next;function e(){p=b.setTimeout(function(){c.processing=!1,z(a,c)},0)}!c.processing&&d&&(c.next=null,c.processing=!0,u(c,d.src,function(b,f){d.imgWidth=b,d.imgHeight=f,A(c,d)?B(a,c,d,e):e()}))}function A(a,b){var c=a.current,d=!1,e;if(a.changed)a.changed=!1,d=!0;else for(e in b)if(b[e]!==c[e]){d=!0;break}return d}function B(a,c,d,e){var f=c.img,g=f.style,h=d.size,i=d.innerWidth,j=d.innerHeight,k=d.imgWidth,l=d.imgHeight,m=d.posX,n=d.posY,o=\"number\"==typeof m,p=\"number\"==typeof n,s=\"none\",t=0,u=0,v=\"auto\",w=\"auto\",x=\"px\",y=\"100%\",z,A;i&&j&&k&&l&&(c.wrapper.style.position=\"fixed\"===d.attachment&&c.canFixed?\"fixed\":\"absolute\",f.src=d.src,d.sizeIsKeyword?(z=i/j,A=k/l,\"contain\"===h&&A>z||\"cover\"===h&&z>A?(u=C((j-i/A)*n)+x,v=y):(t=C((i-j*A)*m)+x,w=y),g.left=o?t:m,g.top=p?u:n,g.width=v,g.height=w,s=\"block\"):(g.display=\"block\",g.width=d.sizeX,g.height=d.sizeY,k=f.width,l=f.height,k&&l&&(g.left=o?C((i-k)*m)+x:m,g.top=p?C((j-l)*n)+x:n,s=\"block\"))),g.display=s,c.current=d,q=b.setTimeout(function(){r=b.setTimeout(e,0),updateEvent.fire()},0)}function C(a){var b=0>a;return a=Math.floor(Math.abs(a)),b?-a:a}function D(){var c=a.bgsExpando,d=(b.event||{}).propertyName,e=\"style.backgroundImage\";c.ignore&&(c.ignore=!1,d===e)||(d===e&&a.style.backgroundImage&&(c.ignore=!0),w(a,c)&&(c.next=x(a,c),z(a,c)))}function E(){b.clearTimeout(n),n=b.setTimeout(D,m)}function F(){var c=a.bgsExpando,d,e,f;o={init:l,handlePropertychange:l,restore:l,handleResize:l},b.clearTimeout(n),b.clearTimeout(p),b.clearTimeout(q),b.clearTimeout(r);try{c&&(d=c.loadImg,d&&(d.onload=d.onerror=null,b.clearTimeout(d.callbackId)),e=a.style,f=c.restore,e&&(e.backgroundImage=f.backgroundImage,e.position=f.position,e.zIndex=f.zIndex),a.removeChild(c.wrapper)),a.bgsExpando=null}catch(g){}a=b=i=l=null}o={init:\"print\"!==i.media?s:l,handlePropertychange:l,restore:l,handleResize:l},\"complete\"===a.readyState&&o.init()}(element,window);</script>\n<script type=\"text/vbscript\"></script>\n</PUBLIC:COMPONENT>\n"
  },
  {
    "path": "web/src/main/webapp/css/vendor/css/bootstrap.css",
    "content": "/*!\n * Bootstrap v3.0.0\n *\n * Copyright 2013 Twitter, Inc\n * Licensed under the Apache License v2.0\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Designed and built with all the love in the world by @mdo and @fat.\n */\n\n/*! normalize.css v2.1.0 | MIT License | git.io/normalize */\n\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nnav,\nsection,\nsummary {\n  display: block;\n}\n\naudio,\ncanvas,\nvideo {\n  display: inline-block;\n}\n\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n\n[hidden] {\n  display: none;\n}\n\nhtml {\n  font-family: sans-serif;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\n\nbody {\n  margin: 0;\n}\n\na:focus {\n  outline: thin dotted;\n}\n\na:active,\na:hover {\n  outline: 0;\n}\n\nh1 {\n  margin: 0.67em 0;\n  font-size: 2em;\n}\n\nabbr[title] {\n  border-bottom: 1px dotted;\n}\n\nb,\nstrong {\n  font-weight: bold;\n}\n\ndfn {\n  font-style: italic;\n}\n\nhr {\n  height: 0;\n  -moz-box-sizing: content-box;\n       box-sizing: content-box;\n}\n\nmark {\n  color: #000;\n  background: #ff0;\n}\n\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, serif;\n  font-size: 1em;\n}\n\npre {\n  white-space: pre-wrap;\n}\n\nq {\n  quotes: \"\\201C\" \"\\201D\" \"\\2018\" \"\\2019\";\n}\n\nsmall {\n  font-size: 80%;\n}\n\nsub,\nsup {\n  position: relative;\n  font-size: 75%;\n  line-height: 0;\n  vertical-align: baseline;\n}\n\nsup {\n  top: -0.5em;\n}\n\nsub {\n  bottom: -0.25em;\n}\n\nimg {\n  border: 0;\n}\n\nsvg:not(:root) {\n  overflow: hidden;\n}\n\nfigure {\n  margin: 0;\n}\n\nfieldset {\n  padding: 0.35em 0.625em 0.75em;\n  margin: 0 2px;\n  border: 1px solid #c0c0c0;\n}\n\nlegend {\n  padding: 0;\n  border: 0;\n}\n\nbutton,\ninput,\nselect,\ntextarea {\n  margin: 0;\n  font-family: inherit;\n  font-size: 100%;\n}\n\nbutton,\ninput {\n  line-height: normal;\n}\n\nbutton,\nselect {\n  text-transform: none;\n}\n\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  cursor: pointer;\n  -webkit-appearance: button;\n}\n\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\n\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  padding: 0;\n  box-sizing: border-box;\n}\n\ninput[type=\"search\"] {\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n  -webkit-appearance: textfield;\n}\n\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\n\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  padding: 0;\n  border: 0;\n}\n\ntextarea {\n  overflow: auto;\n  vertical-align: top;\n}\n\ntable {\n  border-collapse: collapse;\n  border-spacing: 0;\n}\n\n@media print {\n  * {\n    color: #000 !important;\n    text-shadow: none !important;\n    background: transparent !important;\n    box-shadow: none !important;\n  }\n  a,\n  a:visited {\n    text-decoration: underline;\n  }\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n  .ir a:after,\n  a[href^=\"javascript:\"]:after,\n  a[href^=\"#\"]:after {\n    content: \"\";\n  }\n  pre,\n  blockquote {\n    border: 1px solid #999;\n    page-break-inside: avoid;\n  }\n  thead {\n    display: table-header-group;\n  }\n  tr,\n  img {\n    page-break-inside: avoid;\n  }\n  img {\n    max-width: 100% !important;\n  }\n  @page  {\n    margin: 0.5cm;\n  }\n  p,\n  h2,\n  h3 {\n    orphans: 3;\n    widows: 3;\n  }\n  h2,\n  h3 {\n    page-break-after: avoid;\n  }\n  .navbar-toggle {\n    display: none;\n  }\n}\n\n* {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n\nhtml {\n  font-size: 62.5%;\n  -webkit-overflow-scrolling: touch;\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\n\n@media screen and (max-device-width: 480px) {\n  html {\n    -webkit-text-size-adjust: 100%;\n        -ms-text-size-adjust: 100%;\n  }\n}\n\nbody {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  /*line-height: 20px;   */\n  color: #333333;\n  background-color: #ffffff;\n}\n\ninput,\nbutton,\nselect,\ntextarea {\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\n\na {\n  color: #428bca;\n  text-decoration: none;\n}\n\na:hover,\na:focus {\n  color: #2a6496;\n  text-decoration: underline;\n}\n\na:focus {\n  outline: thin dotted #333;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n\nimg {\n  height: auto;\n  max-width: 100%;\n  vertical-align: middle;\n}\n\n.img-rounded {\n  border-radius: 6px;\n}\n\n.img-circle {\n  border-radius: 500px;\n}\n\np {\n  margin: 0 0 10px;\n}\n\n.lead {\n  margin-bottom: 20px;\n  font-size: 21px;\n  font-weight: 200;\n  line-height: 1.4;\n}\n\nsmall {\n  font-size: 85%;\n}\n\nstrong {\n  font-weight: bold;\n}\n\nem {\n  font-style: italic;\n}\n\ncite {\n  font-style: normal;\n}\n\n.text-muted {\n  color: #999999;\n}\n\na.text-muted:hover,\na.text-muted:focus {\n  color: #808080;\n}\n\n.text-warning {\n  color: #c09853;\n}\n\na.text-warning:hover,\na.text-warning:focus {\n  color: #a47e3c;\n}\n\n.text-danger {\n  color: #b94a48;\n}\n\na.text-danger:hover,\na.text-danger:focus {\n  color: #953b39;\n}\n\n.text-success {\n  color: #468847;\n}\n\na.text-success:hover,\na.text-success:focus {\n  color: #356635;\n}\n\n.text-left {\n  text-align: left;\n}\n\n.text-right {\n  text-align: right;\n}\n\n.text-center {\n  text-align: center;\n}\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n  font-family: inherit;\n /* font-weight: 500;*/\n  line-height: 20px;\n}\n\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small {\n  font-weight: normal;\n  line-height: 1;\n  color: #999999;\n}\n\nh1,\nh2,\nh3 {\n  margin-top: 20px;\n  margin-bottom: 10px;\n  line-height: 40px;\n}\n\nh3 {\n  line-height: 30px;\n}\n\nh4,\nh5,\nh6 {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n\nh1,\n.h1 {\n  font-size: 38.5px;\n}\n\nh2,\n.h2 {\n  font-size: 31.5px;\n}\n\nh3,\n.h3 {\n  font-size: 24.5px;\n}\n\nh4,\n.h4 {\n  font-size: 17.5px;\n}\n\nh5,\n.h5 {\n  font-size: 14px;\n}\n\nh6,\n.h6 {\n  font-size: 11.9px;\n}\n\nh1 small,\n.h1 small {\n  font-size: 24.5px;\n}\n\nh2 small,\n.h2 small {\n  font-size: 17.5px;\n}\n\nh3 small,\n.h3 small {\n  font-size: 14px;\n}\n\nh4 small,\n.h4 small {\n  font-size: 14px;\n}\n\n.page-header {\n  padding-bottom: 9px;\n  margin: 40px 0 20px;\n  border-bottom: 1px solid #eeeeee;\n}\n\nul,\nol {\n  padding: 0;\n  margin: 0 0 10px 25px;\n}\n\nul ul,\nul ol,\nol ol,\nol ul {\n  margin-bottom: 0;\n}\n\nli {\n  line-height: 20px;\n}\n\n.list-unstyled {\n  margin-left: 0;\n  list-style: none;\n}\n\n.list-inline {\n  margin-left: 0;\n  list-style: none;\n}\n\n.list-inline > li {\n  display: inline-block;\n  padding-right: 5px;\n  padding-left: 5px;\n}\n\ndl {\n  margin-bottom: 20px;\n}\n\ndt,\ndd {\n  line-height: 20px;\n}\n\ndt {\n  font-weight: bold;\n}\n\ndd {\n  margin-left: 10px;\n}\n\n.dl-horizontal:before,\n.dl-horizontal:after {\n  display: table;\n  content: \" \";\n}\n\n.dl-horizontal:after {\n  clear: both;\n}\n\n.dl-horizontal:before,\n.dl-horizontal:after {\n  display: table;\n  content: \" \";\n}\n\n.dl-horizontal:after {\n  clear: both;\n}\n\n.dl-horizontal dt {\n  float: left;\n  width: 160px;\n  overflow: hidden;\n  clear: left;\n  text-align: right;\n  text-overflow: ellipsis;\n  white-space: nowrap;\n}\n\n.dl-horizontal dd {\n  margin-left: 180px;\n}\n\nhr {\n  margin: 20px 0;\n  border: 0;\n  border-top: 1px solid #eeeeee;\n  border-bottom: 1px solid #fff;\n  border-bottom: 1px solid rgba(255, 255, 255, 0.5);\n}\n\nabbr[title],\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted #999999;\n}\n\nabbr.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\n\nblockquote {\n  padding: 10px 20px;\n  margin: 0 0 20px;\n  border-left: 5px solid #eeeeee;\n}\n\nblockquote p {\n  font-size: 17.5px;\n  font-weight: 300;\n  line-height: 1.25;\n}\n\nblockquote p:last-child {\n  margin-bottom: 0;\n}\n\nblockquote small {\n  display: block;\n  line-height: 20px;\n  color: #999999;\n}\n\nblockquote small:before {\n  content: '\\2014 \\00A0';\n}\n\nblockquote.pull-right {\n  float: right;\n  padding-right: 15px;\n  padding-left: 0;\n  border-right: 5px solid #eeeeee;\n  border-left: 0;\n}\n\nblockquote.pull-right p,\nblockquote.pull-right small {\n  text-align: right;\n}\n\nblockquote.pull-right small:before {\n  content: '';\n}\n\nblockquote.pull-right small:after {\n  content: '\\00A0 \\2014';\n}\n\nq:before,\nq:after,\nblockquote:before,\nblockquote:after {\n  content: \"\";\n}\n\naddress {\n  display: block;\n  margin-bottom: 20px;\n  font-style: normal;\n  line-height: 20px;\n}\n\ncode,\npre {\n  padding: 0 3px 2px;\n  font-family: Monaco, Menlo, Consolas, \"Courier New\", monospace;\n  font-size: 12px;\n  color: #333333;\n  border-radius: 4px;\n}\n\ncode {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #c7254e;\n  white-space: nowrap;\n  background-color: #f9f2f4;\n}\n\npre {\n  display: block;\n  padding: 9.5px;\n  margin: 0 0 10px;\n  font-size: 13px;\n  line-height: 20px;\n  word-break: break-all;\n  word-wrap: break-word;\n  white-space: pre;\n  white-space: pre-wrap;\n  background-color: #f5f5f5;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.15);\n  border-radius: 4px;\n}\n\npre.prettyprint {\n  margin-bottom: 20px;\n}\n\npre code {\n  padding: 0;\n  color: inherit;\n  white-space: pre;\n  white-space: pre-wrap;\n  background-color: transparent;\n  border: 0;\n}\n\n.pre-scrollable {\n  max-height: 340px;\n  overflow-y: scroll;\n}\n\n.container {\n  margin-right: auto;\n  margin-left: auto;\n}\n\n.container:before,\n.container:after {\n  display: table;\n  content: \" \";\n}\n\n.container:after {\n  clear: both;\n}\n\n.container:before,\n.container:after {\n  display: table;\n  content: \" \";\n}\n\n.container:after {\n  clear: both;\n}\n\n.row:before,\n.row:after {\n  display: table;\n  content: \" \";\n}\n\n.row:after {\n  clear: both;\n}\n\n.row:before,\n.row:after {\n  display: table;\n  content: \" \";\n}\n\n.row:after {\n  clear: both;\n}\n\n.row .row {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n\n[class*=\"col-span-\"],\n[class*=\"col-small-\"] {\n  position: relative;\n  min-height: 1px;\n  padding-right: 15px;\n  padding-left: 15px;\n}\n\n[class*=\"col-small-\"] {\n  float: left;\n}\n\n.col-small-span-12 {\n  width: 100%;\n}\n\n.col-small-span-11 {\n  width: 91.66666666666666%;\n}\n\n.col-small-span-10 {\n  width: 83.33333333333334%;\n}\n\n.col-small-span-9 {\n  width: 75%;\n}\n\n.col-small-span-8 {\n  width: 66.66666666666666%;\n}\n\n.col-small-span-7 {\n  width: 58.333333333333336%;\n}\n\n.col-small-span-6 {\n  width: 50%;\n}\n\n.col-small-span-5 {\n  width: 41.66666666666667%;\n}\n\n.col-small-span-4 {\n  width: 33.33333333333333%;\n}\n\n.col-small-span-3 {\n  width: 25%;\n}\n\n.col-small-span-2 {\n  width: 16.666666666666664%;\n}\n\n.col-small-span-1 {\n  width: 8.333333333333332%;\n}\n\n@media screen and (min-width: 768px) {\n  .container {\n    max-width: 728px;\n  }\n  [class*=\"col-span-\"] {\n    float: left;\n  }\n  .col-span-12 {\n    width: 100%;\n  }\n  .col-span-11 {\n    width: 91.66666666666666%;\n  }\n  .col-span-10 {\n    width: 83.33333333333334%;\n  }\n  .col-span-9 {\n    width: 75%;\n  }\n  .col-span-8 {\n    width: 66.66666666666666%;\n  }\n  .col-span-7 {\n    width: 58.333333333333336%;\n  }\n  .col-span-6 {\n    width: 50%;\n  }\n  .col-span-5 {\n    width: 41.66666666666667%;\n  }\n  .col-span-4 {\n    width: 33.33333333333333%;\n  }\n  .col-span-3 {\n    width: 25%;\n  }\n  .col-span-2 {\n    width: 16.666666666666664%;\n  }\n  .col-span-1 {\n    width: 8.333333333333332%;\n  }\n  .col-offset-12 {\n    margin-left: 100%;\n  }\n  .col-offset-11 {\n    margin-left: 91.66666666666666%;\n  }\n  .col-offset-10 {\n    margin-left: 83.33333333333334%;\n  }\n  .col-offset-9 {\n    margin-left: 75%;\n  }\n  .col-offset-8 {\n    margin-left: 66.66666666666666%;\n  }\n  .col-offset-7 {\n    margin-left: 58.333333333333336%;\n  }\n  .col-offset-6 {\n    margin-left: 50%;\n  }\n  .col-offset-5 {\n    margin-left: 41.66666666666667%;\n  }\n  .col-offset-4 {\n    margin-left: 33.33333333333333%;\n  }\n  .col-offset-3 {\n    margin-left: 25%;\n  }\n  .col-offset-2 {\n    margin-left: 16.666666666666664%;\n  }\n  .col-offset-1 {\n    margin-left: 8.333333333333332%;\n  }\n  .col-push-12 {\n    left: 100%;\n  }\n  .col-push-11 {\n    left: 91.66666666666666%;\n  }\n  .col-push-10 {\n    left: 83.33333333333334%;\n  }\n  .col-push-9 {\n    left: 75%;\n  }\n  .col-push-8 {\n    left: 66.66666666666666%;\n  }\n  .col-push-7 {\n    left: 58.333333333333336%;\n  }\n  .col-push-6 {\n    left: 50%;\n  }\n  .col-push-5 {\n    left: 41.66666666666667%;\n  }\n  .col-push-4 {\n    left: 33.33333333333333%;\n  }\n  .col-push-3 {\n    left: 25%;\n  }\n  .col-push-2 {\n    left: 16.666666666666664%;\n  }\n  .col-push-1 {\n    left: 8.333333333333332%;\n  }\n  .col-pull-12 {\n    right: 100%;\n  }\n  .col-pull-11 {\n    right: 91.66666666666666%;\n  }\n  .col-pull-10 {\n    right: 83.33333333333334%;\n  }\n  .col-pull-9 {\n    right: 75%;\n  }\n  .col-pull-8 {\n    right: 66.66666666666666%;\n  }\n  .col-pull-7 {\n    right: 58.333333333333336%;\n  }\n  .col-pull-6 {\n    right: 50%;\n  }\n  .col-pull-5 {\n    right: 41.66666666666667%;\n  }\n  .col-pull-4 {\n    right: 33.33333333333333%;\n  }\n  .col-pull-3 {\n    right: 25%;\n  }\n  .col-pull-2 {\n    right: 16.666666666666664%;\n  }\n  .col-pull-1 {\n    right: 8.333333333333332%;\n  }\n}\n\n@media screen and (min-width: 992px) {\n  .container {\n    max-width: 940px;\n  }\n}\n\n@media screen and (min-width: 1200px) {\n  .container {\n    max-width: 1170px;\n  }\n}\n\n[class*=\"col-span-\"].pull-right {\n  float: right;\n}\n\ntable {\n  max-width: 100%;\n  background-color: transparent;\n}\n\nth {\n  text-align: left;\n}\n\n.table {\n  width: 100%;\n  margin-bottom: 20px;\n  margin-top: 20px;\n  margin-left: 5px;\n}\n\n.table thead > tr > th,\n.table tbody > tr > th,\n.table thead > tr > td,\n.table tbody > tr > td {\n  padding: 8px;\n  line-height: 20px;\n  vertical-align: top;\n  border-top: 1px solid #dddddd;\n}\n\n.table thead > tr > th {\n  vertical-align: bottom;\n}\n\n.table caption + thead tr:first-child th,\n.table caption + thead tr:first-child td,\n.table colgroup + thead tr:first-child th,\n.table colgroup + thead tr:first-child td,\n.table thead:first-child tr:first-child th,\n.table thead:first-child tr:first-child td {\n  border-top: 0;\n}\n\n.table tbody + tbody {\n  border-top: 2px solid #dddddd;\n}\n\n.table .table {\n  background-color: #ffffff;\n}\n\n.table-condensed thead > tr > th,\n.table-condensed tbody > tr > th,\n.table-condensed thead > tr > td,\n.table-condensed tbody > tr > td {\n  padding: 4px 5px;\n}\n\n.table-bordered {\n  border: 1px solid #dddddd;\n  border-collapse: separate;\n  border-left: 0;\n  border-radius: 4px;\n}\n\n.table-bordered thead > tr > th,\n.table-bordered tbody > tr > th,\n.table-bordered thead > tr > td,\n.table-bordered tbody > tr > td {\n  border-left: 1px solid #dddddd;\n}\n\n.table-bordered caption + thead > tr:first-child th,\n.table-bordered caption + tbody > tr:first-child th,\n.table-bordered caption + tbody > tr:first-child td,\n.table-bordered colgroup + thead > tr:first-child th,\n.table-bordered colgroup + tbody > tr:first-child th,\n.table-bordered colgroup + tbody > tr:first-child td,\n.table-bordered thead:first-child > tr:first-child th,\n.table-bordered tbody:first-child > tr:first-child th,\n.table-bordered tbody:first-child > tr:first-child td {\n  border-top: 0;\n}\n\n.table-bordered thead:first-child > tr:first-child > th:first-child,\n.table-bordered tbody:first-child > tr:first-child > td:first-child,\n.table-bordered tbody:first-child > tr:first-child > th:first-child {\n  border-top-left-radius: 4px;\n}\n\n.table-bordered thead:first-child > tr:first-child > th:last-child,\n.table-bordered tbody:first-child > tr:first-child > td:last-child,\n.table-bordered tbody:first-child > tr:first-child > th:last-child {\n  border-top-right-radius: 4px;\n}\n\n.table-bordered thead:last-child > tr:last-child > th:first-child,\n.table-bordered tbody:last-child > tr:last-child > td:first-child,\n.table-bordered tbody:last-child > tr:last-child > th:first-child,\n.table-bordered tfoot:last-child > tr:last-child > td:first-child,\n.table-bordered tfoot:last-child > tr:last-child > th:first-child {\n  border-bottom-left-radius: 4px;\n}\n\n.table-bordered thead:last-child > tr:last-child > th:last-child,\n.table-bordered tbody:last-child > tr:last-child > td:last-child,\n.table-bordered tbody:last-child > tr:last-child > th:last-child,\n.table-bordered tfoot:last-child > tr:last-child > td:last-child,\n.table-bordered tfoot:last-child > tr:last-child > th:last-child {\n  border-bottom-right-radius: 4px;\n}\n\n.table-bordered tfoot + tbody:last-child > tr:last-child > td:first-child {\n  border-bottom-left-radius: 0;\n}\n\n.table-bordered tfoot + tbody:last-child > tr:last-child > td:last-child {\n  border-bottom-right-radius: 0;\n}\n\n.table-bordered caption + thead > tr:first-child > th:first-child,\n.table-bordered caption + tbody > tr:first-child > td:first-child,\n.table-bordered colgroup + thead > tr:first-child > th:first-child,\n.table-bordered colgroup + tbody > tr:first-child > td:first-child {\n  border-top-left-radius: 4px;\n}\n\n.table-bordered caption + thead > tr:first-child > th:last-child,\n.table-bordered caption + tbody > tr:first-child > td:last-child,\n.table-bordered colgroup + thead > tr:first-child > th:last-child,\n.table-bordered colgroup + tbody > tr:first-child > td:last-child {\n  border-top-right-radius: 4px;\n}\n\n.table-striped > tbody > tr:nth-child(odd) > td,\n.table-striped > tbody > tr:nth-child(odd) > th {\n  background-color: #f9f9f9;\n}\n\n.table-hover > tbody > tr:hover > td,\n.table-hover > tbody > tr:hover > th {\n  background-color: #f5f5f5;\n}\n\ntable col[class*=\"col-span-\"] {\n  display: table-column;\n  float: none;\n}\n\ntable td[class*=\"col-span-\"],\ntable th[class*=\"col-span-\"] {\n  display: table-cell;\n  float: none;\n  border-top: 1px solid #dddddd;\n}\n\n.table > tbody > tr > td.success,\n.table > tbody > tr > th.success,\n.table > tbody > tr.success > td {\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n\n.table > tbody > tr > td.danger,\n.table > tbody > tr > th.danger,\n.table > tbody > tr.danger > td {\n  background-color: #f2dede;\n  border-color: #eed3d7;\n}\n\n.table > tbody > tr > td.warning,\n.table > tbody > tr > th.warning,\n.table > tbody > tr.warning > td {\n  background-color: #fcf8e3;\n  border-color: #fbeed5;\n}\n\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td {\n  background-color: #d0e9c6;\n  border-color: #c9e2b3;\n}\n\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td {\n  background-color: #ebcccc;\n  border-color: #e6c1c7;\n}\n\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td {\n  background-color: #faf2cc;\n  border-color: #f8e5be;\n}\n\nform {\n  margin: 0;\n}\n\nfieldset {\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\n\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 20px;\n  font-size: 21px;\n  line-height: 40px;\n  color: #333333;\n  border: 0;\n  border-bottom: 1px solid #e5e5e5;\n}\n\nlabel {\n  display: inline-block;\n  margin-bottom: 5px;\n  /*font-weight: bold;*/\n}\n\nselect,\ntextarea,\ninput[type=\"text\"],\ninput[type=\"password\"],\ninput[type=\"datetime\"],\ninput[type=\"datetime-local\"],\ninput[type=\"date\"],\ninput[type=\"month\"],\ninput[type=\"time\"],\ninput[type=\"week\"],\ninput[type=\"number\"],\ninput[type=\"email\"],\ninput[type=\"url\"],\ninput[type=\"search\"],\ninput[type=\"tel\"],\ninput[type=\"color\"] {\n  display: inline-block;\n  min-height: 34px;\n  padding: 6px 9px;\n  font-size: 14px;\n  line-height: 20px;\n  color: #555555;\n  vertical-align: middle;\n  background-color: #ffffff;\n  border: 1px solid #cccccc;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n  -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;\n     -moz-transition: border linear 0.2s, box-shadow linear 0.2s;\n       -o-transition: border linear 0.2s, box-shadow linear 0.2s;\n          transition: border linear 0.2s, box-shadow linear 0.2s;\n}\n\ninput,\nselect,\ntextarea {\n  width: 100%;\n}\n\ninput[type=\"file\"],\ninput[type=\"image\"],\ninput[type=\"submit\"],\ninput[type=\"reset\"],\ninput[type=\"button\"],\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  width: auto;\n}\n\ninput[type=\"search\"] {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n\ntextarea {\n  height: auto;\n}\n\ntextarea:focus,\ninput[type=\"text\"]:focus,\ninput[type=\"password\"]:focus,\ninput[type=\"datetime\"]:focus,\ninput[type=\"datetime-local\"]:focus,\ninput[type=\"date\"]:focus,\ninput[type=\"month\"]:focus,\ninput[type=\"time\"]:focus,\ninput[type=\"week\"]:focus,\ninput[type=\"number\"]:focus,\ninput[type=\"email\"]:focus,\ninput[type=\"url\"]:focus,\ninput[type=\"search\"]:focus,\ninput[type=\"tel\"]:focus,\ninput[type=\"color\"]:focus {\n  border-color: rgba(82, 168, 236, 0.8);\n  outline: 0;\n  outline: thin dotted \\9;\n  /* IE6-9 */\n\n  -webkit-box-shadow: 0 0 8px rgba(82, 168, 236, 0.6);\n          box-shadow: 0 0 8px rgba(82, 168, 236, 0.6);\n}\n\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9;\n  /* IE8-9 */\n\n  line-height: normal;\n}\n\nselect,\ninput[type=\"file\"] {\n  height: 34px;\n  /* In IE7, the height of the select element cannot be changed by height, only font-size. TODO: Check if this is still needed when dropping IE7 support */\n\n  line-height: 34px;\n}\n\nselect[multiple],\nselect[size] {\n  height: auto;\n}\n\nselect:focus,\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  outline: thin dotted #333;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n\ninput:-moz-placeholder,\ntextarea:-moz-placeholder {\n  color: #999999;\n}\n\ninput::-moz-placeholder,\ntextarea::-moz-placeholder {\n  color: #999999;\n}\n\ninput:-ms-input-placeholder,\ntextarea:-ms-input-placeholder {\n  color: #999999;\n}\n\ninput::-webkit-input-placeholder,\ntextarea::-webkit-input-placeholder {\n  color: #999999;\n}\n\n.radio,\n.checkbox {\n  display: block;\n  min-height: 20px;\n  padding-left: 20px;\n  margin-bottom: 10px;\n}\n\n.radio label,\n.checkbox label {\n  display: inline;\n  margin-bottom: 0;\n  font-weight: normal;\n}\n\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  float: left;\n  margin-left: -20px;\n}\n\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px;\n}\n\n.controls > .radio:first-child,\n.controls > .checkbox:first-child {\n  padding-top: 5px;\n}\n\n.radio-inline,\n.checkbox-inline {\n  display: inline-block;\n  padding-top: 5px;\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n  vertical-align: middle;\n}\n\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px;\n}\n\nselect.input-large,\ntextarea.input-large,\ninput[type=\"text\"].input-large,\ninput[type=\"password\"].input-large,\ninput[type=\"datetime\"].input-large,\ninput[type=\"datetime-local\"].input-large,\ninput[type=\"date\"].input-large,\ninput[type=\"month\"].input-large,\ninput[type=\"time\"].input-large,\ninput[type=\"week\"].input-large,\ninput[type=\"number\"].input-large,\ninput[type=\"email\"].input-large,\ninput[type=\"url\"].input-large,\ninput[type=\"search\"].input-large,\ninput[type=\"tel\"].input-large,\ninput[type=\"color\"].input-large {\n  padding: 11px 14px;\n  font-size: 17.5px;\n  border-radius: 6px;\n}\n\nselect.input-small,\ntextarea.input-small,\ninput[type=\"text\"].input-small,\ninput[type=\"password\"].input-small,\ninput[type=\"datetime\"].input-small,\ninput[type=\"datetime-local\"].input-small,\ninput[type=\"date\"].input-small,\ninput[type=\"month\"].input-small,\ninput[type=\"time\"].input-small,\ninput[type=\"week\"].input-small,\ninput[type=\"number\"].input-small,\ninput[type=\"email\"].input-small,\ninput[type=\"url\"].input-small,\ninput[type=\"search\"].input-small,\ninput[type=\"tel\"].input-small,\ninput[type=\"color\"].input-small {\n  min-height: 26px;\n  padding: 2px 10px;\n  font-size: 11.9px;\n  border-radius: 3px;\n}\n\ninput[class*=\"span\"],\nselect[class*=\"span\"],\ntextarea[class*=\"span\"] {\n  float: none;\n  margin-right: 0;\n  margin-left: 0;\n}\n\n.input-append input[class*=\"span\"],\n.input-prepend input[class*=\"span\"] {\n  display: inline-block;\n}\n\ninput[class*=\"span\"],\nselect[class*=\"span\"],\ntextarea[class*=\"span\"] {\n  height: 34px;\n}\n\ninput[disabled],\nselect[disabled],\ntextarea[disabled],\ninput[readonly],\nselect[readonly],\ntextarea[readonly],\nfieldset[disabled] input,\nfieldset[disabled] select,\nfieldset[disabled] textarea {\n  cursor: not-allowed;\n  background-color: #eeeeee;\n}\n\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"][readonly],\ninput[type=\"checkbox\"][readonly],\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n  background-color: transparent;\n}\n\n.has-warning .control-label {\n  color: #c09853;\n}\n\n.has-warning .input-with-feedback {\n  padding-right: 32px;\n  border-color: #c09853;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n\n.has-warning .input-with-feedback:focus {\n  border-color: #a47e3c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;\n}\n\n.has-error .control-label {\n  color: #b94a48;\n}\n\n.has-error .input-with-feedback {\n  padding-right: 32px;\n  border-color: #b94a48;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n\n.has-error .input-with-feedback:focus {\n  border-color: #953b39;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;\n}\n\n.has-success .control-label {\n  color: #468847;\n}\n\n.has-success .input-with-feedback {\n  padding-right: 32px;\n  border-color: #468847;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);\n}\n\n.has-success .input-with-feedback:focus {\n  border-color: #356635;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;\n}\n\ninput:focus:invalid,\ntextarea:focus:invalid,\nselect:focus:invalid {\n  color: #b94a48;\n  border-color: #ee5f5b;\n}\n\ninput:focus:invalid:focus,\ntextarea:focus:invalid:focus,\nselect:focus:invalid:focus {\n  border-color: #e9322d;\n  -webkit-box-shadow: 0 0 6px #f8b9b7;\n          box-shadow: 0 0 6px #f8b9b7;\n}\n\n.form-actions {\n  padding: 19px 20px 20px;\n  margin-top: 20px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border-top: 1px solid #e5e5e5;\n}\n\n.form-actions:before,\n.form-actions:after {\n  display: table;\n  content: \" \";\n}\n\n.form-actions:after {\n  clear: both;\n}\n\n.form-actions:before,\n.form-actions:after {\n  display: table;\n  content: \" \";\n}\n\n.form-actions:after {\n  clear: both;\n}\n\n.help-block,\n.help-inline {\n  color: #737373;\n}\n\n.help-block {\n  display: block;\n  margin-bottom: 10px;\n}\n\n.help-inline {\n  display: inline-block;\n  padding-left: 5px;\n  vertical-align: middle;\n}\n\n.input-group {\n  display: table;\n}\n\n.input-group[class*=\"span\"] {\n  float: none;\n  padding: 0;\n}\n\n.input-group input,\n.input-group select {\n  width: 100%;\n}\n\n.input-group-addon,\n.input-group-btn,\n.input-group input {\n  display: table-cell;\n  margin: 0;\n  border-radius: 0;\n}\n\n.input-group-addon.input-small,\n.input-group-btn.input-small,\n.input-group input.input-small {\n  border-radius: 0;\n}\n\n.input-group-addon.input-large,\n.input-group-btn.input-large,\n.input-group input.input-large {\n  border-radius: 0;\n}\n\n.input-group-addon,\n.input-group-btn {\n  width: 1%;\n  vertical-align: middle;\n}\n\n.input-group-addon {\n  padding: 6px 8px;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 20px;\n  text-align: center;\n  text-shadow: 0 1px 0 #fff;\n  background-color: #eeeeee;\n  border: 1px solid #ccc;\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n\n.input-group-addon.input-small {\n  padding: 2px 10px;\n  font-size: 11.9px;\n}\n\n.input-group-addon.input-large {\n  padding: 11px 14px;\n  font-size: 17.5px;\n}\n\n.input-group input:first-child,\n.input-group-addon:first-child {\n  border-bottom-left-radius: 4px;\n  border-top-left-radius: 4px;\n}\n\n.input-group input:first-child.input-small,\n.input-group-addon:first-child.input-small {\n  border-bottom-left-radius: 3px;\n  border-top-left-radius: 3px;\n}\n\n.input-group input:first-child.input-large,\n.input-group-addon:first-child.input-large {\n  border-bottom-left-radius: 6px;\n  border-top-left-radius: 6px;\n}\n\n.input-group-addon:first-child {\n  border-right: 0;\n}\n\n.input-group input:last-child,\n.input-group-addon:last-child {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n\n.input-group input:last-child.input-small,\n.input-group-addon:last-child.input-small {\n  border-top-right-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n\n.input-group input:last-child.input-large,\n.input-group-addon:last-child.input-large {\n  border-top-right-radius: 6px;\n  border-bottom-right-radius: 6px;\n}\n\n.input-group-addon:last-child {\n  border-left: 0;\n}\n\n.input-group-btn {\n  position: relative;\n  white-space: nowrap;\n}\n\n.input-group-btn > .btn {\n  position: relative;\n  float: left;\n  border-radius: 0;\n}\n\n.input-group-btn > .btn + .btn {\n  margin-left: -1px;\n}\n\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:active {\n  z-index: 2;\n}\n\n.input-group-btn:first-child > .btn:first-child,\n.input-group-btn:first-child > .dropdown-toggle:first-child {\n  border-bottom-left-radius: 4px;\n  border-top-left-radius: 4px;\n}\n\n.input-group-btn:first-child > .btn:first-child.btn-large,\n.input-group-btn:first-child > .dropdown-toggle:first-child.btn-large {\n  border-bottom-left-radius: 6px;\n  border-top-left-radius: 6px;\n}\n\n.input-group-btn:first-child > .btn:first-child.btn-small,\n.input-group-btn:first-child > .dropdown-toggle:first-child.btn-small {\n  border-bottom-left-radius: 3px;\n  border-top-left-radius: 3px;\n}\n\n.input-group-btn:last-child > .btn:last-child,\n.input-group-btn:last-child > .dropdown-toggle {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n\n.input-group-btn:last-child > .btn:last-child.btn-large,\n.input-group-btn:last-child > .dropdown-toggle.btn-large {\n  border-top-right-radius: 6px;\n  border-bottom-right-radius: 6px;\n}\n\n.input-group-btn:last-child > .btn:last-child.btn-small,\n.input-group-btn:last-child > .dropdown-toggle.btn-small {\n  border-top-right-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n\n@media screen and (min-width: 768px) {\n  .form-horizontal .control-group {\n    position: relative;\n    margin-bottom: 20px;\n  }\n  .form-horizontal .control-group:before,\n  .form-horizontal .control-group:after {\n    display: table;\n    content: \" \";\n  }\n  .form-horizontal .control-group:after {\n    clear: both;\n  }\n  .form-horizontal .control-group:before,\n  .form-horizontal .control-group:after {\n    display: table;\n    content: \" \";\n  }\n  .form-horizontal .control-group:after {\n    clear: both;\n  }\n  .form-horizontal .control-group input,\n  .form-horizontal .control-group select,\n  .form-horizontal .control-group textarea {\n    margin-bottom: 0;\n  }\n  .form-horizontal .control-group > .control-label {\n    float: left;\n    width: 160px;\n    padding-top: 6px;\n    text-align: right;\n  }\n  .form-horizontal .control-group > .controls {\n    margin-left: 180px;\n  }\n  .form-horizontal .form-actions {\n    padding-left: 180px;\n  }\n}\n\n.btn {\n  display: inline-block;\n  padding: 6px 12px;\n  margin-bottom: 0;\n  font-size: 14px;\n  font-weight: 500;\n  line-height: 20px;\n  text-align: center;\n  /*white-space: nowrap;*/\n  vertical-align: middle;\n  cursor: pointer;\n  border: 1px solid #a7a9aa;\n  border-radius: 4px;\n}\n\n.btn:focus {\n  outline: thin dotted #333;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n\n.btn:hover,\n.btn:focus {\n  color: #fff;\n  text-decoration: none;\n}\n\n.btn:active,\n.btn.active {\n  background-image: none;\n  outline: 0;\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n  pointer-events: none;\n  cursor: default;\n  opacity: 0.65;\n  filter: alpha(opacity=65);\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n\n.btn-large {\n  padding: 11px 14px;\n  font-size: 17.5px;\n  border-radius: 6px;\n}\n\n.btn-small {\n  padding: 2px 10px;\n  font-size: 11.9px;\n  border-radius: 3px;\n}\n\n.btn-mini {\n    padding: 5px 5px 0px;\n    font-size: 13px;\n    border-radius: 3px;\n    width: 130px;\n    height: 40px;\n}\n\n.btn-block {\n  display: block;\n  width: 100%;\n  padding-right: 0;\n  padding-left: 0;\n}\n\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\n\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n  width: 100%;\n}\n\n.btn {\n  color: #ffffff;\n  background-color: #a7a9aa;\n  border-color: #a7a9aa;\n}\n\n.btn:hover,\n.btn:focus,\n.btn:active,\n.btn.active {\n  background-color: #9a9c9d;\n  border-color: #8d9091;\n}\n\n.btn.disabled:hover,\n.btn[disabled]:hover,\nfieldset[disabled] .btn:hover,\n.btn.disabled:focus,\n.btn[disabled]:focus,\nfieldset[disabled] .btn:focus,\n.btn.disabled:active,\n.btn[disabled]:active,\nfieldset[disabled] .btn:active,\n.btn.disabled.active,\n.btn[disabled].active,\nfieldset[disabled] .btn.active {\n  background-color: #a7a9aa;\n  border-color: #a7a9aa;\n}\n\n.btn-primary {\n  background-color: #428bca;\n  border-color: #428bca;\n}\n\n.btn-primary:hover,\n.btn-primary:focus,\n.btn-primary:active,\n.btn-primary.active {\n  background-color: #357ebd;\n  border-color: #3071a9;\n}\n\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled:active,\n.btn-primary[disabled]:active,\nfieldset[disabled] .btn-primary:active,\n.btn-primary.disabled.active,\n.btn-primary[disabled].active,\nfieldset[disabled] .btn-primary.active {\n  background-color: #428bca;\n  border-color: #428bca;\n}\n\n.btn-warning {\n  background-color: #f0ad4e;\n  border-color: #f0ad4e;\n}\n\n.btn-warning:hover,\n.btn-warning:focus,\n.btn-warning:active,\n.btn-warning.active {\n  background-color: #eea236;\n  border-color: #ec971f;\n}\n\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled:active,\n.btn-warning[disabled]:active,\nfieldset[disabled] .btn-warning:active,\n.btn-warning.disabled.active,\n.btn-warning[disabled].active,\nfieldset[disabled] .btn-warning.active {\n  background-color: #f0ad4e;\n  border-color: #f0ad4e;\n}\n\n.btn-danger {\n  background-color: #d9534f;\n  border-color: #d9534f;\n}\n\n.btn-danger:hover,\n.btn-danger:focus,\n.btn-danger:active,\n.btn-danger.active {\n  background-color: #d43f3a;\n  border-color: #c9302c;\n}\n\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled:active,\n.btn-danger[disabled]:active,\nfieldset[disabled] .btn-danger:active,\n.btn-danger.disabled.active,\n.btn-danger[disabled].active,\nfieldset[disabled] .btn-danger.active {\n  background-color: #d9534f;\n  border-color: #d9534f;\n}\n\n.btn-success {\n  background-color: #5cb85c;\n  border-color: #5cb85c;\n}\n\n.btn-success:hover,\n.btn-success:focus,\n.btn-success:active,\n.btn-success.active {\n  background-color: #4cae4c;\n  border-color: #449d44;\n}\n\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled:active,\n.btn-success[disabled]:active,\nfieldset[disabled] .btn-success:active,\n.btn-success.disabled.active,\n.btn-success[disabled].active,\nfieldset[disabled] .btn-success.active {\n  background-color: #5cb85c;\n  border-color: #5cb85c;\n}\n\n.btn-info {\n  background-color: #5bc0de;\n  border-color: #5bc0de;\n}\n\n.btn-info:hover,\n.btn-info:focus,\n.btn-info:active,\n.btn-info.active {\n  background-color: #46b8da;\n  border-color: #31b0d5;\n}\n\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled:active,\n.btn-info[disabled]:active,\nfieldset[disabled] .btn-info:active,\n.btn-info.disabled.active,\n.btn-info[disabled].active,\nfieldset[disabled] .btn-info.active {\n  background-color: #5bc0de;\n  border-color: #5bc0de;\n}\n\n.btn-link,\n.btn-link:active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n  background-color: transparent;\n  background-image: none;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n  border-color: transparent;\n}\n\n.btn-link {\n  font-weight: normal;\n  color: #428bca;\n  cursor: pointer;\n  border-radius: 0;\n}\n\n.btn-link:hover,\n.btn-link:focus {\n  color: #2a6496;\n  text-decoration: underline;\n  background-color: transparent;\n}\n\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n  color: #333333;\n  text-decoration: none;\n}\n\n.fade {\n  opacity: 0;\n  -webkit-transition: opacity 0.15s linear;\n     -moz-transition: opacity 0.15s linear;\n       -o-transition: opacity 0.15s linear;\n          transition: opacity 0.15s linear;\n}\n\n.fade.in {\n  opacity: 1;\n}\n\n/*.collapse {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  .transition(height .35s ease);\n  &.in {\n    height: auto;\n  }\n}*/\n\n.collapse {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  -webkit-transition: height 0.35s ease;\n     -moz-transition: height 0.35s ease;\n       -o-transition: height 0.35s ease;\n          transition: height 0.35s ease;\n}\n\n.collapse.in {\n  height: auto;\n  overflow: visible;\n}\n\n@font-face {\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  font-weight: normal;\n  src: url('../fonts/glyphiconshalflings-regular.eot');\n  src: url('../fonts/glyphiconshalflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphiconshalflings-regular.woff') format('woff'), url('../fonts/glyphiconshalflings-regular.ttf') format('truetype'), url('../fonts/glyphiconshalflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n\n.glyphicon:before {\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  line-height: 1;\n}\n\n.glyphicon-glass:before {\n  content: \"\\e001\";\n}\n\n.glyphicon-music:before {\n  content: \"\\e002\";\n}\n\n.glyphicon-search:before {\n  content: \"\\e003\";\n}\n\n.glyphicon-envelope:before {\n  content: \"\\2709\";\n}\n\n.glyphicon-heart:before {\n  content: \"\\e005\";\n}\n\n.glyphicon-star:before {\n  content: \"\\e006\";\n}\n\n.glyphicon-star-empty:before {\n  content: \"\\e007\";\n}\n\n.glyphicon-user:before {\n  content: \"\\e008\";\n}\n\n.glyphicon-film:before {\n  content: \"\\e009\";\n}\n\n.glyphicon-th-large:before {\n  content: \"\\e010\";\n}\n\n.glyphicon-th:before {\n  content: \"\\e011\";\n}\n\n.glyphicon-th-list:before {\n  content: \"\\e012\";\n}\n\n.glyphicon-ok:before {\n  content: \"\\e013\";\n}\n\n.glyphicon-remove:before {\n  content: \"\\e014\";\n}\n\n.glyphicon-zoom-in:before {\n  content: \"\\e015\";\n}\n\n.glyphicon-zoom-out:before {\n  content: \"\\e016\";\n}\n\n.glyphicon-off:before {\n  content: \"\\e017\";\n}\n\n.glyphicon-signal:before {\n  content: \"\\e018\";\n}\n\n.glyphicon-cog:before {\n  content: \"\\e019\";\n}\n\n.glyphicon-trash:before {\n  content: \"\\e020\";\n}\n\n.glyphicon-home:before {\n  content: \"\\e021\";\n}\n\n.glyphicon-file:before {\n  content: \"\\e022\";\n}\n\n.glyphicon-time:before {\n  content: \"\\e023\";\n}\n\n.glyphicon-road:before {\n  content: \"\\e024\";\n}\n\n.glyphicon-download-alt:before {\n  content: \"\\e025\";\n}\n\n.glyphicon-download:before {\n  content: \"\\e026\";\n}\n\n.glyphicon-upload:before {\n  content: \"\\e027\";\n}\n\n.glyphicon-inbox:before {\n  content: \"\\e028\";\n}\n\n.glyphicon-play-circle:before {\n  content: \"\\e029\";\n}\n\n.glyphicon-repeat:before {\n  content: \"\\e030\";\n}\n\n.glyphicon-refresh:before {\n  content: \"\\e031\";\n}\n\n.glyphicon-list-alt:before {\n  content: \"\\e032\";\n}\n\n.glyphicon-lock:before {\n  content: \"\\e033\";\n}\n\n.glyphicon-flag:before {\n  content: \"\\e034\";\n}\n\n.glyphicon-headphones:before {\n  content: \"\\e035\";\n}\n\n.glyphicon-volume-off:before {\n  content: \"\\e036\";\n}\n\n.glyphicon-volume-down:before {\n  content: \"\\e037\";\n}\n\n.glyphicon-volume-up:before {\n  content: \"\\e038\";\n}\n\n.glyphicon-qrcode:before {\n  content: \"\\e039\";\n}\n\n.glyphicon-barcode:before {\n  content: \"\\e040\";\n}\n\n.glyphicon-tag:before {\n  content: \"\\e041\";\n}\n\n.glyphicon-tags:before {\n  content: \"\\e042\";\n}\n\n.glyphicon-book:before {\n  content: \"\\e043\";\n}\n\n.glyphicon-bookmark:before {\n  content: \"\\e044\";\n}\n\n.glyphicon-print:before {\n  content: \"\\e045\";\n}\n\n.glyphicon-camera:before {\n  content: \"\\e046\";\n}\n\n.glyphicon-font:before {\n  content: \"\\e047\";\n}\n\n.glyphicon-bold:before {\n  content: \"\\e048\";\n}\n\n.glyphicon-italic:before {\n  content: \"\\e049\";\n}\n\n.glyphicon-text-height:before {\n  content: \"\\e050\";\n}\n\n.glyphicon-text-width:before {\n  content: \"\\e051\";\n}\n\n.glyphicon-align-left:before {\n  content: \"\\e052\";\n}\n\n.glyphicon-align-center:before {\n  content: \"\\e053\";\n}\n\n.glyphicon-align-right:before {\n  content: \"\\e054\";\n}\n\n.glyphicon-align-justify:before {\n  content: \"\\e055\";\n}\n\n.glyphicon-list:before {\n  content: \"\\e056\";\n}\n\n.glyphicon-indent-left:before {\n  content: \"\\e057\";\n}\n\n.glyphicon-indent-right:before {\n  content: \"\\e058\";\n}\n\n.glyphicon-facetime-video:before {\n  content: \"\\e059\";\n}\n\n.glyphicon-picture:before {\n  content: \"\\e060\";\n}\n\n.glyphicon-pencil:before {\n  content: \"\\270f\";\n}\n\n.glyphicon-map-marker:before {\n  content: \"\\e062\";\n}\n\n.glyphicon-adjust:before {\n  content: \"\\e063\";\n}\n\n.glyphicon-tint:before {\n  content: \"\\e064\";\n}\n\n.glyphicon-edit:before {\n  content: \"\\e065\";\n}\n\n.glyphicon-share:before {\n  content: \"\\e066\";\n}\n\n.glyphicon-check:before {\n  content: \"\\e067\";\n}\n\n.glyphicon-move:before {\n  content: \"\\e068\";\n}\n\n.glyphicon-step-backward:before {\n  content: \"\\e069\";\n}\n\n.glyphicon-fast-backward:before {\n  content: \"\\e070\";\n}\n\n.glyphicon-backward:before {\n  content: \"\\e071\";\n}\n\n.glyphicon-play:before {\n  content: \"\\e072\";\n}\n\n.glyphicon-pause:before {\n  content: \"\\e073\";\n}\n\n.glyphicon-stop:before {\n  content: \"\\e074\";\n}\n\n.glyphicon-forward:before {\n  content: \"\\e075\";\n}\n\n.glyphicon-fast-forward:before {\n  content: \"\\e076\";\n}\n\n.glyphicon-step-forward:before {\n  content: \"\\e077\";\n}\n\n.glyphicon-eject:before {\n  content: \"\\e078\";\n}\n\n.glyphicon-chevron-left:before {\n  content: \"\\e079\";\n}\n\n.glyphicon-chevron-right:before {\n  content: \"\\e080\";\n}\n\n.glyphicon-plus-sign:before {\n  content: \"\\e081\";\n}\n\n.glyphicon-minus-sign:before {\n  content: \"\\e082\";\n}\n\n.glyphicon-remove-sign:before {\n  content: \"\\e083\";\n}\n\n.glyphicon-ok-sign:before {\n  content: \"\\e084\";\n}\n\n.glyphicon-question-sign:before {\n  content: \"\\e085\";\n}\n\n.glyphicon-info-sign:before {\n  content: \"\\e086\";\n}\n\n.glyphicon-screenshot:before {\n  content: \"\\e087\";\n}\n\n.glyphicon-remove-circle:before {\n  content: \"\\e088\";\n}\n\n.glyphicon-ok-circle:before {\n  content: \"\\e089\";\n}\n\n.glyphicon-ban-circle:before {\n  content: \"\\e090\";\n}\n\n.glyphicon-arrow-left:before {\n  content: \"\\e091\";\n}\n\n.glyphicon-arrow-right:before {\n  content: \"\\e092\";\n}\n\n.glyphicon-arrow-up:before {\n  content: \"\\e093\";\n}\n\n.glyphicon-arrow-down:before {\n  content: \"\\e094\";\n}\n\n.glyphicon-share-alt:before {\n  content: \"\\e095\";\n}\n\n.glyphicon-resize-full:before {\n  content: \"\\e096\";\n}\n\n.glyphicon-resize-small:before {\n  content: \"\\e097\";\n}\n\n.glyphicon-plus:before {\n  content: \"\\002b\";\n}\n\n.glyphicon-minus:before {\n  content: \"\\2212\";\n}\n\n.glyphicon-asterisk:before {\n  content: \"\\002a\";\n}\n\n.glyphicon-exclamation-sign:before {\n  content: \"\\e101\";\n}\n\n.glyphicon-gift:before {\n  content: \"\\e102\";\n}\n\n.glyphicon-leaf:before {\n  content: \"\\e103\";\n}\n\n.glyphicon-fire:before {\n  content: \"\\e104\";\n}\n\n.glyphicon-eye-open:before {\n  content: \"\\e105\";\n}\n\n.glyphicon-eye-close:before {\n  content: \"\\e106\";\n}\n\n.glyphicon-warning-sign:before {\n  content: \"\\e107\";\n}\n\n.glyphicon-plane:before {\n  content: \"\\e108\";\n}\n\n.glyphicon-calendar:before {\n  content: \"\\e109\";\n}\n\n.glyphicon-random:before {\n  content: \"\\e110\";\n}\n\n.glyphicon-comment:before {\n  content: \"\\e111\";\n}\n\n.glyphicon-magnet:before {\n  content: \"\\e112\";\n}\n\n.glyphicon-chevron-up:before {\n  content: \"\\e113\";\n}\n\n.glyphicon-chevron-down:before {\n  content: \"\\e114\";\n}\n\n.glyphicon-retweet:before {\n  content: \"\\e115\";\n}\n\n.glyphicon-shopping-cart:before {\n  content: \"\\e116\";\n}\n\n.glyphicon-folder-close:before {\n  content: \"\\e117\";\n}\n\n.glyphicon-folder-open:before {\n  content: \"\\e118\";\n}\n\n.glyphicon-resize-vertical:before {\n  content: \"\\e119\";\n}\n\n.glyphicon-resize-horizontal:before {\n  content: \"\\e120\";\n}\n\n.glyphicon-hdd:before {\n  content: \"\\e121\";\n}\n\n.glyphicon-bullhorn:before {\n  content: \"\\e122\";\n}\n\n.glyphicon-bell:before {\n  content: \"\\e123\";\n}\n\n.glyphicon-certificate:before {\n  content: \"\\e124\";\n}\n\n.glyphicon-thumbs-up:before {\n  content: \"\\e125\";\n}\n\n.glyphicon-thumbs-down:before {\n  content: \"\\e126\";\n}\n\n.glyphicon-hand-right:before {\n  content: \"\\e127\";\n}\n\n.glyphicon-hand-left:before {\n  content: \"\\e128\";\n}\n\n.glyphicon-hand-up:before {\n  content: \"\\e129\";\n}\n\n.glyphicon-hand-down:before {\n  content: \"\\e130\";\n}\n\n.glyphicon-circle-arrow-right:before {\n  content: \"\\e131\";\n}\n\n.glyphicon-circle-arrow-left:before {\n  content: \"\\e132\";\n}\n\n.glyphicon-circle-arrow-up:before {\n  content: \"\\e133\";\n}\n\n.glyphicon-circle-arrow-down:before {\n  content: \"\\e134\";\n}\n\n.glyphicon-globe:before {\n  content: \"\\e135\";\n}\n\n.glyphicon-wrench:before {\n  content: \"\\e136\";\n}\n\n.glyphicon-tasks:before {\n  content: \"\\e137\";\n}\n\n.glyphicon-filter:before {\n  content: \"\\e138\";\n}\n\n.glyphicon-briefcase:before {\n  content: \"\\e139\";\n}\n\n.glyphicon-fullscreen:before {\n  content: \"\\e140\";\n}\n\n.glyphicon-dashboard:before {\n  content: \"\\e141\";\n}\n\n.glyphicon-paperclip:before {\n  content: \"\\e142\";\n}\n\n.glyphicon-heart-empty:before {\n  content: \"\\e143\";\n}\n\n.glyphicon-link:before {\n  content: \"\\e144\";\n}\n\n.glyphicon-phone:before {\n  content: \"\\e145\";\n}\n\n.glyphicon-pushpin:before {\n  content: \"\\e146\";\n}\n\n.glyphicon-euro:before {\n  content: \"\\20ac\";\n}\n\n.glyphicon-usd:before {\n  content: \"\\e148\";\n}\n\n.glyphicon-gbp:before {\n  content: \"\\e149\";\n}\n\n.glyphicon-sort:before {\n  content: \"\\e150\";\n}\n\n.glyphicon-sort-by-alphabet:before {\n  content: \"\\e151\";\n}\n\n.glyphicon-sort-by-alphabet-alt:before {\n  content: \"\\e152\";\n}\n\n.glyphicon-sort-by-order:before {\n  content: \"\\e153\";\n}\n\n.glyphicon-sort-by-order-alt:before {\n  content: \"\\e154\";\n}\n\n.glyphicon-sort-by-attributes:before {\n  content: \"\\e155\";\n}\n\n.glyphicon-sort-by-attributes-alt:before {\n  content: \"\\e156\";\n}\n\n.glyphicon-unchecked:before {\n  content: \"\\e157\";\n}\n\n.glyphicon-expand:before {\n  content: \"\\e158\";\n}\n\n.glyphicon-collapse:before {\n  content: \"\\e159\";\n}\n\n.glyphicon-collapse-top:before {\n  content: \"\\e160\";\n}\n\n.dropup,\n.dropdown {\n  position: relative;\n}\n\n.dropdown-toggle:active,\n.open .dropdown-toggle {\n  outline: 0;\n}\n\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  vertical-align: top;\n  border-top: 4px solid #000;\n  border-right: 4px solid transparent;\n  border-left: 4px solid transparent;\n  content: \"\";\n}\n\n.dropdown .caret {\n  margin-top: 8px;\n  margin-left: 2px;\n}\n\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 1000;\n  display: none;\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0;\n  list-style: none;\n  background-color: #ffffff;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.15);\n  border-radius: 4px;\n  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n          box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);\n  -webkit-background-clip: padding-box;\n     -moz-background-clip: padding-box;\n          background-clip: padding-box;\n}\n\n.dropdown-menu.pull-right {\n  right: 0;\n  left: auto;\n}\n\n.dropdown-menu .divider {\n  height: 2px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n  border-bottom: 1px solid #ffffff;\n}\n\n.dropdown-menu > li > a {\n  display: block;\n  padding: 3px 20px;\n  clear: both;\n  font-weight: normal;\n  line-height: 20px;\n  color: #333333;\n  white-space: nowrap;\n}\n\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus,\n.dropdown-submenu:hover > a,\n.dropdown-submenu:focus > a {\n  color: #ffffff;\n  text-decoration: none;\n  background-color: #357ebd;\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#428bca), to(#357ebd));\n  background-image: -webkit-linear-gradient(top, #428bca, #357ebd);\n  background-image: -moz-linear-gradient(top, #428bca, #357ebd);\n  background-image: linear-gradient(to bottom, #428bca, #357ebd);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);\n}\n\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  color: #ffffff;\n  text-decoration: none;\n  background-color: #357ebd;\n  background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#428bca), to(#357ebd));\n  background-image: -webkit-linear-gradient(top, #428bca, #357ebd);\n  background-image: -moz-linear-gradient(top, #428bca, #357ebd);\n  background-image: linear-gradient(to bottom, #428bca, #357ebd);\n  background-repeat: repeat-x;\n  outline: 0;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff428bca', endColorstr='#ff357ebd', GradientType=0);\n}\n\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  color: #999999;\n}\n\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  text-decoration: none;\n  cursor: default;\n  background-color: transparent;\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n\n.open > .dropdown-menu {\n  display: block;\n}\n\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n  border-top: 0;\n  border-bottom: 4px solid #000;\n  content: \"\";\n}\n\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n  top: auto;\n  bottom: 100%;\n  margin-bottom: 1px;\n}\n\n.dropdown-submenu {\n  position: relative;\n}\n\n.dropdown-submenu > .dropdown-menu {\n  top: 0;\n  left: 100%;\n  margin-top: -6px;\n  margin-left: -1px;\n  border-top-left-radius: 0;\n}\n\n.dropdown-submenu:hover > .dropdown-menu {\n  display: block;\n}\n\n.dropup .dropdown-submenu > .dropdown-menu {\n  top: auto;\n  bottom: 0;\n  margin-top: 0;\n  margin-bottom: -2px;\n  border-bottom-left-radius: 0;\n}\n\n.dropdown-submenu > a:after {\n  display: block;\n  float: right;\n  width: 0;\n  height: 0;\n  margin-top: 5px;\n  margin-right: -10px;\n  border-color: transparent;\n  border-left-color: #cccccc;\n  border-style: solid;\n  border-width: 5px 0 5px 5px;\n  content: \" \";\n}\n\n.dropdown-submenu:hover > a:after {\n  border-left-color: #ffffff;\n}\n\n.dropdown-submenu.pull-left {\n  float: none;\n}\n\n.dropdown-submenu.pull-left > .dropdown-menu {\n  left: -100%;\n  margin-left: 10px;\n  border-top-right-radius: 0;\n}\n\n.dropdown .dropdown-menu .nav-header {\n  padding-right: 20px;\n  padding-left: 20px;\n}\n\n.typeahead {\n  z-index: 1051;\n}\n\n.list-group {\n  margin: 0 0 20px;\n  background-color: #ffffff;\n}\n\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 10px 30px 10px 15px;\n  margin-bottom: -1px;\n  border: 1px solid #dddddd;\n}\n\n.list-group-item:first-child {\n  border-top-right-radius: 4px;\n  border-top-left-radius: 4px;\n}\n\n.list-group-item:last-child {\n  margin-bottom: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n\n.list-group-item-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n\n.list-group-item-text {\n  margin-bottom: 0;\n  line-height: 1.3;\n}\n\na.list-group-item .list-group-item-heading {\n  color: #333;\n}\n\na.list-group-item .list-group-item-text {\n  color: #555;\n}\n\na.list-group-item:hover,\na.list-group-item:focus {\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\n\na.list-group-item.active {\n  z-index: 2;\n  color: #ffffff;\n  background-color: #428bca;\n  border-color: #428bca;\n}\n\na.list-group-item.active .list-group-item-heading {\n  color: inherit;\n}\n\na.list-group-item.active .list-group-item-text {\n  color: #e1edf7;\n}\n\n.list-group-item > .badge,\n.list-group-item > .glyphicon-chevron-right {\n  float: right;\n  margin-right: -15px;\n}\n\n.list-group-item > .glyphicon-chevron-right {\n  margin-right: -15px;\n}\n\n.list-group-item > .glyphicon + .badge {\n  margin-right: 5px;\n}\n\n.panel {\n  padding: 15px;\n  margin-bottom: 20px;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n          box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n\n.panel-heading {\n  padding: 10px 15px;\n  margin: -15px -15px 15px;\n  font-size: 17.5px;\n  font-weight: 500;\n  background-color: #f5f5f5;\n  border-bottom: 1px solid #dddddd;\n  border-top-right-radius: 3px;\n  border-top-left-radius: 3px;\n}\n\n.panel-primary {\n  border-color: #428bca;\n}\n\n.panel-primary .panel-heading {\n  color: #ffffff;\n  background-color: #428bca;\n  border-color: #428bca;\n}\n\n.panel-success {\n  border-color: #d6e9c6;\n}\n\n.panel-success .panel-heading {\n  color: #468847;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n\n.panel-warning {\n  border-color: #fbeed5;\n}\n\n.panel-warning .panel-heading {\n  color: #c09853;\n  background-color: #fcf8e3;\n  border-color: #fbeed5;\n}\n\n.panel-danger {\n  border-color: #eed3d7;\n}\n\n.panel-danger .panel-heading {\n  color: #b94a48;\n  background-color: #f2dede;\n  border-color: #eed3d7;\n}\n\n.panel-info {\n  border-color: #bce8f1;\n}\n\n.panel-info .panel-heading {\n  color: #3a87ad;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n\n.list-group-flush {\n  margin: 15px -15px -15px;\n}\n\n.list-group-flush .list-group-item {\n  border-width: 1px 0;\n}\n\n.list-group-flush .list-group-item:first-child {\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n\n.list-group-flush .list-group-item:last-child {\n  border-bottom: 0;\n}\n\n.well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);\n}\n\n.well blockquote {\n  border-color: #ddd;\n  border-color: rgba(0, 0, 0, 0.15);\n}\n\n.well-large {\n  padding: 24px;\n  border-radius: 6px;\n}\n\n.well-small {\n  padding: 9px;\n  border-radius: 3px;\n}\n\n.close {\n  float: right;\n  font-size: 20px;\n  font-weight: bold;\n  line-height: 20px;\n  color: #000;\n  text-shadow: 0 1px 0 #ffffff;\n  opacity: 0.2;\n  filter: alpha(opacity=20);\n}\n\n.close:hover,\n.close:focus {\n  color: #000;\n  text-decoration: none;\n  cursor: pointer;\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\n\nbutton.close {\n  padding: 0;\n  cursor: pointer;\n  background: transparent;\n  border: 0;\n  -webkit-appearance: none;\n}\n\n.nav {\n  padding-left: 0;\n  margin-bottom: 0;\n  margin-left: 0;\n  list-style: none;\n}\n\n.nav:before,\n.nav:after {\n  display: table;\n  content: \" \";\n}\n\n.nav:after {\n  clear: both;\n}\n\n.nav:before,\n.nav:after {\n  display: table;\n  content: \" \";\n}\n\n.nav:after {\n  clear: both;\n}\n\n.nav > li {\n  display: block;\n}\n\n.nav > li > a {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n}\n\n.nav > li > a:hover,\n.nav > li > a:focus {\n  text-decoration: none;\n  background-color: #eeeeee;\n}\n\n.nav > li.disabled > a {\n  color: #999999;\n}\n\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n  color: #999999;\n  text-decoration: none;\n  cursor: default;\n  background-color: transparent;\n}\n\n.nav > li + .nav-header {\n  margin-top: 9px;\n}\n\n.nav > .pull-right {\n  float: right;\n}\n\n.nav .divider {\n  height: 2px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n  border-bottom: 1px solid #ffffff;\n}\n\n.nav-tabs {\n  border-bottom: 1px solid #ddd;\n}\n\n.nav-tabs > li {\n  float: left;\n  margin-bottom: -1px;\n}\n\n.nav-tabs > li > a {\n  margin-right: 2px;\n  line-height: 20px;\n  border: 1px solid transparent;\n  border-radius: 4px 4px 0 0;\n}\n\n.nav-tabs > li > a:hover {\n  border-color: #eeeeee #eeeeee #dddddd;\n}\n\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n  color: #555555;\n  cursor: default;\n  background-color: #ffffff;\n  border: 1px solid #ddd;\n  border-bottom-color: transparent;\n}\n\n.nav-tabs.nav-justified {\n  width: 100%;\n  border-bottom: 0;\n}\n\n.nav-tabs.nav-justified > li {\n  display: table-cell;\n  float: none;\n  width: 1%;\n  text-align: center;\n}\n\n.nav-tabs.nav-justified > li > a {\n  margin-right: 0;\n  border-bottom: 1px solid #ddd;\n}\n\n.nav-tabs.nav-justified > .active > a {\n  border-bottom-color: #ffffff;\n}\n\n.nav-pills > li {\n  float: left;\n}\n\n.nav-pills > li > a {\n  border-radius: 5px;\n  padding-top: 5px;\n  padding-bottom: 5px;\n}\n\n.nav-pills > li + li > a {\n  margin-left: 2px;\n}\n\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n  color: #fff;\n  background-color: #428bca;\n}\n\n.nav-stacked > li {\n  float: none;\n}\n\n.nav-stacked > li + li > a {\n  margin-top: 2px;\n  margin-left: 0;\n}\n\n.nav-justified {\n  width: 100%;\n}\n\n.nav-justified > li {\n  display: table-cell;\n  float: none;\n  width: 1%;\n  text-align: center;\n}\n\n.nav-header {\n  display: block;\n  padding: 3px 15px;\n  font-size: 11px;\n  font-weight: bold;\n  line-height: 20px;\n  color: #999999;\n  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);\n  text-transform: uppercase;\n}\n\n.tabbable:before,\n.tabbable:after {\n  display: table;\n  content: \" \";\n}\n\n.tabbable:after {\n  clear: both;\n}\n\n.tabbable:before,\n.tabbable:after {\n  display: table;\n  content: \" \";\n}\n\n.tabbable:after {\n  clear: both;\n}\n\n.tab-content > .tab-pane,\n.pill-content > .pill-pane {\n  display: none;\n}\n\n.tab-content > .active,\n.pill-content > .active {\n  display: block;\n}\n\n/*\n// Prevent IE8 from misplacing imgs\n// See https://github.com/h5bp/html5-boilerplate/issues/984#issuecomment-3985989\n.nav > li > a > img {\n  max-width: none;\n}\n\n// Dropdowns\n// -------------------------\n\n.nav-tabs .dropdown-menu {\n  // Remove the top rounded corners here since there is a hard edge above the menu\n  .border-top-radius(0);\n}\n\n// Default dropdown links\n// -------------------------\n// Make carets use linkColor to start\n.nav .dropdown-toggle .caret {\n  border-top-color: @link-color;\n  border-bottom-color: @link-color;\n  margin-top: 8px;\n}\n.nav .dropdown-toggle:hover .caret {\n  border-top-color: @link-hover-color;\n  border-bottom-color: @link-hover-color;\n}\n\n// Active dropdown links\n// -------------------------\n.nav .active .dropdown-toggle .caret {\n  border-top-color: #fff;\n  border-bottom-color: #fff;\n}\n.nav-tabs .active .dropdown-toggle .caret {\n  border-top-color: @gray;\n  border-bottom-color: @gray;\n}\n\n// Active:hover dropdown links\n// -------------------------\n.nav > .dropdown.active > a:hover {\n  cursor: pointer;\n}\n\n// Open dropdowns\n// -------------------------\n.nav-tabs .open .dropdown-toggle,\n.nav-pills .open .dropdown-toggle,\n.nav > li.dropdown.open.active > a:hover {\n  color: #fff;\n  background-color: @gray-light;\n  border-color: @gray-light;\n}\n.nav li.dropdown.open .caret,\n.nav li.dropdown.open.active .caret,\n.nav li.dropdown.open a:hover .caret {\n  border-top-color: #fff;\n  border-bottom-color: #fff;\n  .opacity(1);\n}\n\n// Dropdowns in stacked tabs\n.tabs-stacked .open > a:hover {\n  border-color: @gray-light;\n}\n\n*/\n\n.navbar {\n  position: relative;\n  padding: 10px 15px;\n  background-color: #eeeeee;\n  border-radius: 4px;\n}\n\n.navbar:before,\n.navbar:after {\n  display: table;\n  content: \" \";\n}\n\n.navbar:after {\n  clear: both;\n}\n\n.navbar:before,\n.navbar:after {\n  display: table;\n  content: \" \";\n}\n\n.navbar:after {\n  clear: both;\n}\n\n.navbar .nav {\n  margin-top: 15px;\n}\n\n.navbar .nav > li > a {\n  padding-top: 15px;\n  padding-bottom: 15px;\n  line-height: 20px;\n  color: #777777;\n}\n\n.navbar .nav > li > a:hover,\n.navbar .nav > li > a:focus {\n  color: #333333;\n  background-color: transparent;\n}\n\n.navbar .nav > .active > a,\n.navbar .nav > .active > a:hover,\n.navbar .nav > .active > a:focus {\n  color: #555555;\n  background-color: #d5d5d5;\n}\n\n.navbar .nav > .disabled > a,\n.navbar .nav > .disabled > a:hover,\n.navbar .nav > .disabled > a:focus {\n  color: #cccccc;\n  background-color: transparent;\n}\n\n.navbar-static-top {\n  border-radius: 0;\n}\n\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: 1030;\n  border-radius: 0;\n}\n\n.navbar-fixed-top {\n  top: 0;\n}\n\n.navbar-fixed-bottom {\n  bottom: 0;\n}\n\n.navbar-brand {\n  display: block;\n  max-width: 200px;\n  padding: 7px 15px;\n  margin-right: auto;\n  margin-left: auto;\n  font-size: 18px;\n  font-weight: 500;\n  line-height: 20px;\n  color: #777777;\n  text-align: center;\n}\n\n.navbar-brand:hover,\n.navbar-brand:focus {\n  color: #5e5e5e;\n  text-decoration: none;\n  background-color: transparent;\n}\n\n.navbar-toggle {\n  position: absolute;\n  top: 10px;\n  right: 10px;\n  padding: 8px 12px;\n  background-color: transparent;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n}\n\n.navbar-toggle:hover,\n.navbar-toggle:focus {\n  background-color: #ddd;\n}\n\n.navbar-toggle .icon-bar {\n  display: block;\n  width: 22px;\n  height: 2px;\n  background-color: #ccc;\n  border-radius: 1px;\n}\n\n.navbar-toggle .icon-bar + .icon-bar {\n  margin-top: 4px;\n}\n\n.navbar .nav > .divider {\n  height: 2px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e1e1e1;\n  border-bottom: 1px solid #fbfbfb;\n}\n\n.navbar-form {\n  margin-top: 8px;\n  margin-bottom: 8px;\n}\n\n.navbar .nav > li > .dropdown-menu {\n  margin-top: 0;\n  border-top-right-radius: 0;\n  border-top-left-radius: 0;\n}\n\n.navbar-fixed-bottom .nav > li > .dropdown-menu {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n\n.navbar .nav li.dropdown > a:hover .caret,\n.navbar .nav li.dropdown > a:focus .caret {\n  border-top-color: #333333;\n  border-bottom-color: #333333;\n}\n\n.navbar .nav li.dropdown.open > .dropdown-toggle,\n.navbar .nav li.dropdown.active > .dropdown-toggle,\n.navbar .nav li.dropdown.open.active > .dropdown-toggle {\n  color: #555555;\n  background-color: #d5d5d5;\n}\n\n.navbar .nav li.dropdown > .dropdown-toggle .caret {\n  border-top-color: #777777;\n  border-bottom-color: #777777;\n}\n\n.navbar .nav li.dropdown.open > .dropdown-toggle .caret,\n.navbar .nav li.dropdown.active > .dropdown-toggle .caret,\n.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret {\n  border-top-color: #555555;\n  border-bottom-color: #555555;\n}\n\n.navbar .pull-right > li > .dropdown-menu,\n.navbar .nav > li > .dropdown-menu.pull-right {\n  right: 0;\n  left: auto;\n}\n\n.navbar-inverse {\n  background-color: #222222;\n}\n\n.navbar-inverse .navbar-brand {\n  color: #999999;\n}\n\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n  color: #ffffff;\n  background-color: transparent;\n}\n\n.navbar-inverse .navbar-text {\n  color: #999999;\n}\n\n.navbar-inverse .nav > li > a {\n  color: #999999;\n}\n\n.navbar-inverse .nav > li > a:hover,\n.navbar-inverse .nav > li > a:focus {\n  color: #ffffff;\n  background-color: transparent;\n}\n\n.navbar-inverse .nav > .active > a,\n.navbar-inverse .nav > .active > a:hover,\n.navbar-inverse .nav > .active > a:focus {\n  color: #ffffff;\n  background-color: #080808;\n}\n\n.navbar-inverse .nav > .disabled > a,\n.navbar-inverse .nav > .disabled > a:hover,\n.navbar-inverse .nav > .disabled > a:focus {\n  color: #444444;\n  background-color: transparent;\n}\n\n.navbar-inverse .navbar-toggle {\n  border-color: #333;\n}\n\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n  background-color: #333;\n}\n\n.navbar-inverse .navbar-toggle .icon-bar {\n  background-color: #fff;\n}\n\n.navbar-inverse .nav > .divider {\n  background-color: #151515;\n  border-bottom-color: #2f2f2f;\n}\n\n.navbar-inverse .nav li.dropdown.open > .dropdown-toggle,\n.navbar-inverse .nav li.dropdown.active > .dropdown-toggle,\n.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle {\n  color: #ffffff;\n  background-color: #080808;\n}\n\n.navbar-inverse .nav li.dropdown > a:hover .caret {\n  border-top-color: #ffffff;\n  border-bottom-color: #ffffff;\n}\n\n.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret {\n  border-top-color: #999999;\n  border-bottom-color: #999999;\n}\n\n.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret,\n.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret,\n.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret {\n  border-top-color: #ffffff;\n  border-bottom-color: #ffffff;\n}\n\n@media screen and (min-width: 768px) {\n  .navbar {\n    padding-top: 0;\n    padding-bottom: 0;\n  }\n  .navbar-brand {\n    float: left;\n    padding-top: 15px;\n    padding-bottom: 15px;\n    margin-left: -10px;\n  }\n  .navbar .nav {\n    float: left;\n    margin-top: 0;\n  }\n  .navbar .nav:before,\n  .navbar .nav:after {\n    display: table;\n    content: \" \";\n  }\n  .navbar .nav:after {\n    clear: both;\n  }\n  .navbar .nav:before,\n  .navbar .nav:after {\n    display: table;\n    content: \" \";\n  }\n  .navbar .nav:after {\n    clear: both;\n  }\n  .navbar .nav.pull-right {\n    float: right;\n  }\n  .navbar .nav > li {\n    float: left;\n  }\n  .navbar .nav > .divider {\n    width: 1px;\n    height: 30px;\n    margin: 10px 9px;\n    border-right: 1px solid #fbfbfb;\n    border-bottom: 0;\n  }\n  .navbar-inverse .nav > .divider {\n    border-right-color: #2f2f2f;\n  }\n  .navbar-fixed-left {\n    padding-right: 0;\n    padding-left: 0;\n  }\n  .navbar-fixed-left .navbar-brand,\n  .navbar-fixed-left .nav,\n  .navbar-fixed-left .nav > li {\n    float: none;\n  }\n  .navbar-toggle {\n    position: relative;\n    top: auto;\n    left: auto;\n    display: none;\n  }\n  .nav-collapse.collapse {\n    height: auto !important;\n    overflow: visible !important;\n  }\n}\n\n/*\n\n// Janky solution for now to account for links outside the .nav\n// -------------------------\n.navbar-link {\n  color: @navbar-link-color;\n  &:hover {\n    color: @navbar-link-hover-color;\n  }\n}\n\n// Buttons in navbar\n// -------------------------\n.navbar .btn,\n.navbar .btn-group {\n  .navbarVerticalAlign(30px); // Vertically center in navbar\n}\n.navbar .btn-group .btn,\n.navbar .input-prepend .btn,\n.navbar .input-append .btn {\n  margin-top: 0; // then undo the margin here so we don't accidentally double it\n}\n\n// Navbar forms\n// -------------------------\n.navbar-form {\n  margin-bottom: 0; // remove default bottom margin\n  .clearfix();\n  input,\n  select,\n  .radio,\n  .checkbox {\n    .navbarVerticalAlign(30px); // Vertically center in navbar\n  }\n  input,\n  select,\n  .btn {\n    display: inline-block;\n    margin-bottom: 0;\n  }\n  input[type=\"image\"],\n  input[type=\"checkbox\"],\n  input[type=\"radio\"] {\n    margin-top: 3px;\n  }\n  .input-append,\n  .input-prepend {\n    margin-top: 5px;\n    white-space: nowrap; // preven two  items from separating within a .navbar-form that has .pull-left\n    input {\n      margin-top: 0; // remove the margin on top since it's on the parent\n    }\n  }\n}\n\n*/\n\n.btn .caret {\n  border-top-color: #ffffff;\n}\n\n.dropup .btn .caret {\n  border-bottom-color: #ffffff;\n}\n\n.btn-group {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle;\n}\n\n.btn-group > .btn {\n  position: relative;\n  float: left;\n}\n\n.btn-group > .btn + btn {\n  margin-left: -1px;\n}\n\n.btn-group > .btn:hover,\n.btn-group > .btn:active {\n  z-index: 2;\n}\n\n.btn-toolbar:before,\n.btn-toolbar:after {\n  display: table;\n  content: \" \";\n}\n\n.btn-toolbar:after {\n  clear: both;\n}\n\n.btn-toolbar:before,\n.btn-toolbar:after {\n  display: table;\n  content: \" \";\n}\n\n.btn-toolbar:after {\n  clear: both;\n}\n\n.btn-toolbar .btn-group {\n  float: left;\n}\n\n.btn-toolbar > .btn + .btn,\n.btn-toolbar > .btn-group + .btn,\n.btn-toolbar > .btn + .btn-group,\n.btn-toolbar > .btn-group + .btn-group {\n  margin-left: 5px;\n}\n\n.btn-group > .btn {\n  position: relative;\n  border-radius: 0;\n}\n\n.btn-group > .btn:first-child {\n  margin-left: 0;\n  border-bottom-left-radius: 4px;\n  border-top-left-radius: 4px;\n}\n\n.btn-group > .btn:last-child,\n.btn-group > .dropdown-toggle {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n\n.btn-group > .btn.large:first-child {\n  margin-left: 0;\n  border-bottom-left-radius: 6px;\n  border-top-left-radius: 6px;\n}\n\n.btn-group > .btn.large:last-child,\n.btn-group > .large.dropdown-toggle {\n  border-top-right-radius: 6px;\n  border-bottom-right-radius: 6px;\n}\n\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n\n.btn-group > .btn + .dropdown-toggle {\n  padding-right: 8px;\n  padding-left: 8px;\n}\n\n.btn-group > .btn-mini + .dropdown-toggle {\n  padding-right: 5px;\n  padding-left: 5px;\n}\n\n.btn-group > .btn-large + .dropdown-toggle {\n  padding-right: 12px;\n  padding-left: 12px;\n}\n\n.btn-group.open .dropdown-toggle {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n}\n\n.btn .caret {\n  margin-top: 8px;\n  margin-left: 0;\n}\n\n.btn-large .caret {\n  border-width: 5px;\n}\n\n.dropup .btn-large .caret {\n  border-bottom-width: 5px;\n}\n\n.btn-group-vertical > .btn {\n  display: block;\n  float: none;\n  width: 100%;\n  max-width: 100%;\n}\n\n.btn-group-vertical .btn:first-child {\n  border-radius: 0;\n  border-top-right-radius: 4px;\n  border-top-left-radius: 4px;\n}\n\n.btn-group-vertical .btn:last-child {\n  border-radius: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n\n.btn-group-vertical .btn-large:first-child {\n  border-top-right-radius: 6px;\n  border-top-left-radius: 6px;\n}\n\n.btn-group-vertical .btn-large:last-child {\n  border-bottom-right-radius: 6px;\n  border-bottom-left-radius: 6px;\n}\n\n.btn-group-justified {\n  display: table;\n  width: 100%;\n}\n\n.btn-group-justified .btn {\n  display: table-cell;\n  float: none;\n  width: 1%;\n}\n\n.btn-group[data-toggle=\"buttons-radio\"] > .btn > input[type=\"radio\"],\n.btn-group[data-toggle=\"buttons-checkbox\"] > .btn > input[type=\"checkbox\"] {\n  display: none;\n}\n\n.breadcrumb {\n  padding: 8px 15px;\n  margin: 0 0 20px;\n  list-style: none;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n}\n\n.breadcrumb > li {\n  display: inline-block;\n  text-shadow: 0 1px 0 #fff;\n}\n\n.breadcrumb > li:after {\n  display: inline-block;\n  padding: 0 5px;\n  color: #ccc;\n  content: \"\\00a0 /\";\n}\n\n.breadcrumb > li:last-child:after {\n  content: \"\";\n}\n\n.breadcrumb > .active {\n  color: #999999;\n}\n\n.pagination {\n  display: inline-block;\n  margin: 20px 0;\n  border-radius: 4px;\n}\n\n.pagination > li {\n  display: inline;\n}\n\n.pagination > li > a,\n.pagination > li > span {\n  float: left;\n  padding: 4px 12px;\n  line-height: 20px;\n  text-decoration: none;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-left-width: 0;\n}\n\n.pagination > li > a:hover,\n.pagination > li > a:focus,\n.pagination > .active > a,\n.pagination > .active > span {\n  background-color: #f5f5f5;\n}\n\n.pagination > .active > a,\n.pagination > .active > span {\n  color: #999999;\n  cursor: default;\n}\n\n.pagination > .disabled > span,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n  color: #999999;\n  cursor: default;\n  background-color: #ffffff;\n}\n\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n  border-left-width: 1px;\n  border-bottom-left-radius: 4px;\n  border-top-left-radius: 4px;\n}\n\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n\n.pagination-large > li > a,\n.pagination-large > li > span {\n  padding: 11px 14px;\n  font-size: 17.5px;\n}\n\n.pagination-large > li:first-child > a,\n.pagination-large > li:first-child > span {\n  border-bottom-left-radius: 6px;\n  border-top-left-radius: 6px;\n}\n\n.pagination-large > li:last-child > a,\n.pagination-large > li:last-child > span {\n  border-top-right-radius: 6px;\n  border-bottom-right-radius: 6px;\n}\n\n.pagination-mini > li:first-child > a,\n.pagination-small > li:first-child > a,\n.pagination-mini > li:first-child > span,\n.pagination-small > li:first-child > span {\n  border-bottom-left-radius: 3px;\n  border-top-left-radius: 3px;\n}\n\n.pagination-mini > li:last-child > a,\n.pagination-small > li:last-child > a,\n.pagination-mini > li:last-child > span,\n.pagination-small > li:last-child > span {\n  border-top-right-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n\n.pagination-small > li > a,\n.pagination-small > li > span {\n  padding: 2px 10px;\n  font-size: 11.9px;\n}\n\n.pagination-mini > li > a,\n.pagination-mini > li > span {\n  padding: 0 6px;\n  font-size: 10.5px;\n}\n\n.pager {\n  margin: 20px 0;\n  text-align: center;\n  list-style: none;\n}\n\n.pager:before,\n.pager:after {\n  display: table;\n  content: \" \";\n}\n\n.pager:after {\n  clear: both;\n}\n\n.pager:before,\n.pager:after {\n  display: table;\n  content: \" \";\n}\n\n.pager:after {\n  clear: both;\n}\n\n.pager li {\n  display: inline;\n}\n\n.pager li > a,\n.pager li > span {\n  display: inline-block;\n  padding: 5px 14px;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-radius: 15px;\n}\n\n.pager li > a:hover,\n.pager li > a:focus {\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\n\n.pager .next > a,\n.pager .next > span {\n  float: right;\n}\n\n.pager .previous > a,\n.pager .previous > span {\n  float: left;\n}\n\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n  color: #999999;\n  cursor: default;\n  background-color: #ffffff;\n}\n\n.modal-open {\n  overflow: hidden;\n}\n\n.modal {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1040;\n  display: none;\n  overflow: auto;\n  overflow-y: scroll;\n  -webkit-overflow-scrolling: touch;\n}\n\n.modal.fade {\n  top: -25%;\n  -webkit-transition: opacity 0.3s linear, top 0.3s ease-out;\n     -moz-transition: opacity 0.3s linear, top 0.3s ease-out;\n       -o-transition: opacity 0.3s linear, top 0.3s ease-out;\n          transition: opacity 0.3s linear, top 0.3s ease-out;\n}\n\n.modal.fade.in {\n  top: 0;\n}\n\n.modal-dialog {\n  position: relative;\n  top: 0;\n  right: 0;\n  left: 0;\n  z-index: 1050;\n  width: auto;\n  padding: 10px;\n}\n\n.modal-content {\n  position: relative;\n  background-color: #fff;\n  border: 1px solid #999;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 6px;\n  outline: none;\n  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n          box-shadow: 0 3px 9px rgba(0, 0, 0, 0.5);\n  -webkit-background-clip: padding-box;\n     -moz-background-clip: padding-box;\n          background-clip: padding-box;\n}\n\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1030;\n  background-color: #000;\n}\n\n.modal-backdrop.fade {\n  opacity: 0;\n  filter: alpha(opacity=0);\n}\n\n.modal-backdrop.fade.in {\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\n\n.modal-header {\n  min-height: 35px;\n  padding: 15px;\n  border-bottom: 1px solid #e5e5e5;\n}\n\n.modal-header .close {\n  margin-top: -2px;\n}\n\n.modal-title {\n  margin: 0;\n  line-height: 20px;\n}\n\n.modal-body {\n  position: relative;\n  padding: 20px;\n}\n\n.modal-footer {\n  padding: 19px 20px 20px;\n  margin-top: 15px;\n  text-align: right;\n  border-top: 1px solid #e5e5e5;\n}\n\n.modal-footer:before,\n.modal-footer:after {\n  display: table;\n  content: \" \";\n}\n\n.modal-footer:after {\n  clear: both;\n}\n\n.modal-footer:before,\n.modal-footer:after {\n  display: table;\n  content: \" \";\n}\n\n.modal-footer:after {\n  clear: both;\n}\n\n.modal-footer .btn + .btn {\n  margin-bottom: 0;\n  margin-left: 5px;\n}\n\n.modal-footer .btn-group .btn + .btn {\n  margin-left: -1px;\n}\n\n.modal-footer .btn-block + .btn-block {\n  margin-left: 0;\n}\n\n@media screen and (min-width: 768px) {\n  .modal-dialog {\n    right: auto;\n    left: 50%;\n    width: 560px;\n    padding-top: 30px;\n    padding-bottom: 30px;\n    margin-left: -280px;\n  }\n  .modal-content {\n    -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n            box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);\n  }\n}\n\n.tooltip {\n  position: absolute;\n  z-index: 1030;\n  display: block;\n  font-size: 11px;\n  line-height: 1.4;\n  opacity: 0;\n  filter: alpha(opacity=0);\n  visibility: visible;\n}\n\n.tooltip.in {\n  opacity: 1;\n  filter: alpha(opacity=100);\n}\n\n.tooltip.top {\n  padding: 5px 0;\n  margin-top: -3px;\n}\n\n.tooltip.right {\n  padding: 0 5px;\n  margin-left: 3px;\n}\n\n.tooltip.bottom {\n  padding: 5px 0;\n  margin-top: 3px;\n}\n\n.tooltip.left {\n  padding: 0 5px;\n  margin-left: -3px;\n}\n\n.tooltip-inner {\n  max-width: 200px;\n  padding: 3px 8px;\n  color: #ffffff;\n  text-align: center;\n  text-decoration: none;\n  background-color: rgba(0, 0, 0, 0.9);\n  border-radius: 4px;\n}\n\n.tooltip-arrow {\n  position: absolute;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n\n.tooltip.top .tooltip-arrow {\n  bottom: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-top-color: rgba(0, 0, 0, 0.9);\n  border-width: 5px 5px 0;\n}\n\n.tooltip.right .tooltip-arrow {\n  top: 50%;\n  left: 0;\n  margin-top: -5px;\n  border-right-color: rgba(0, 0, 0, 0.9);\n  border-width: 5px 5px 5px 0;\n}\n\n.tooltip.left .tooltip-arrow {\n  top: 50%;\n  right: 0;\n  margin-top: -5px;\n  border-left-color: rgba(0, 0, 0, 0.9);\n  border-width: 5px 0 5px 5px;\n}\n\n.tooltip.bottom .tooltip-arrow {\n  top: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-bottom-color: rgba(0, 0, 0, 0.9);\n  border-width: 0 5px 5px;\n}\n\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 1010;\n  display: none;\n  max-width: 276px;\n  padding: 1px;\n  text-align: left;\n  white-space: normal;\n  background-color: #ffffff;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 6px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n          box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  background-clip: padding-box;\n  -webkit-bg-clip: padding-box;\n     -moz-bg-clip: padding;\n}\n\n.popover.top {\n  margin-top: -10px;\n}\n\n.popover.right {\n  margin-left: 10px;\n}\n\n.popover.bottom {\n  margin-top: 10px;\n}\n\n.popover.left {\n  margin-left: -10px;\n}\n\n.popover-title {\n  padding: 8px 14px;\n  margin: 0;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 18px;\n  background-color: #f7f7f7;\n  border-bottom: 1px solid #ebebeb;\n  border-radius: 5px 5px 0 0;\n}\n\n.popover-title:empty {\n  display: none;\n}\n\n.popover-content {\n  padding: 9px 14px;\n}\n\n.popover .arrow,\n.popover .arrow:after {\n  position: absolute;\n  display: block;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n\n.popover .arrow {\n  border-width: 11px;\n}\n\n.popover .arrow:after {\n  border-width: 10px;\n  content: \"\";\n}\n\n.popover.top .arrow {\n  bottom: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-top-color: #999;\n  border-top-color: rgba(0, 0, 0, 0.25);\n  border-bottom-width: 0;\n}\n\n.popover.top .arrow:after {\n  bottom: 1px;\n  margin-left: -10px;\n  border-top-color: #ffffff;\n  border-bottom-width: 0;\n}\n\n.popover.right .arrow {\n  top: 50%;\n  left: -11px;\n  margin-top: -11px;\n  border-right-color: #999;\n  border-right-color: rgba(0, 0, 0, 0.25);\n  border-left-width: 0;\n}\n\n.popover.right .arrow:after {\n  bottom: -10px;\n  left: 1px;\n  border-right-color: #ffffff;\n  border-left-width: 0;\n}\n\n.popover.bottom .arrow {\n  top: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-bottom-color: #999;\n  border-bottom-color: rgba(0, 0, 0, 0.25);\n  border-top-width: 0;\n}\n\n.popover.bottom .arrow:after {\n  top: 1px;\n  margin-left: -10px;\n  border-bottom-color: #ffffff;\n  border-top-width: 0;\n}\n\n.popover.left .arrow {\n  top: 50%;\n  right: -11px;\n  margin-top: -11px;\n  border-left-color: #999;\n  border-left-color: rgba(0, 0, 0, 0.25);\n  border-right-width: 0;\n}\n\n.popover.left .arrow:after {\n  right: 1px;\n  bottom: -10px;\n  border-left-color: #ffffff;\n  border-right-width: 0;\n}\n\n.alert {\n  padding: 8px 15px 8px 14px;\n  margin-bottom: 20px;\n  /*color: #c09853;*/\n  background-color: #fcfcfc;\n  border: 1px solid #e6e6e6;\n  border-radius: 4px;\n}\n\n.alert h4 {\n  margin-top: 0;\n  color: inherit;\n}\n\n.alert hr {\n  border-top-color: #f8e5be;\n}\n\n.alert > a,\n.alert > p > a {\n  font-weight: 500;\n  color: #a47e3c;\n}\n\n.alert .close {\n  position: relative;\n  top: -2px;\n  /*right: -21px;*/ /*Décalage lors de l'ouverture d'un tatam*/\n  color: inherit;\n}\n\n.alert-success {\n  color: #468847;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n\n.alert-success hr {\n  border-top-color: #c9e2b3;\n}\n\n.alert-success > a,\n.alert-success > p > a {\n  color: #356635;\n}\n\n.alert-danger {\n  color: #b94a48;\n  background-color: #f2dede;\n  border-color: #eed3d7;\n}\n\n.alert-danger hr {\n  border-top-color: #e6c1c7;\n}\n\n.alert-danger > a,\n.alert-danger > p > a {\n  color: #953b39;\n}\n\n.alert-info {\n  color: #3a87ad;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n\n.alert-info hr {\n  border-top-color: #a6e1ec;\n}\n\n.alert-info > a,\n.alert-info > p > a {\n  color: #2d6987;\n}\n\n.alert-block {\n  padding-top: 14px;\n  padding-bottom: 14px;\n}\n\n.alert-block > p,\n.alert-block > ul {\n  margin-bottom: 0;\n}\n\n.alert-block p + p {\n  margin-top: 5px;\n}\n\n.thumbnail,\n.img-thumbnail {\n  padding: 4px;\n  line-height: 20px;\n  background-color: #ffffff;\n  border: 1px solid #dddddd;\n  border-radius: 4px;\n  -webkit-transition: all 0.2s ease-in-out;\n     -moz-transition: all 0.2s ease-in-out;\n       -o-transition: all 0.2s ease-in-out;\n          transition: all 0.2s ease-in-out;\n}\n\n.thumbnail {\n  display: block;\n}\n\n.img-thumbnail {\n  display: inline-block;\n}\n\na.thumbnail:hover,\na.thumbnail:focus {\n  border-color: #428bca;\n}\n\n.thumbnail > img {\n  display: block;\n  max-width: 100%;\n  margin-right: auto;\n  margin-left: auto;\n}\n\n.thumbnail .caption {\n  padding: 9px;\n  color: #333333;\n}\n\n.media,\n.media-body {\n  overflow: hidden;\n  zoom: 1;\n}\n\n.media,\n.media .media {\n  margin-top: 15px;\n}\n\n.media:first-child {\n  margin-top: 0;\n}\n\n.media-object {\n  display: block;\n}\n\n.media-heading {\n  margin: 0 0 5px;\n}\n\n.media > .pull-left {\n  margin-right: 10px;\n}\n\n.media > .pull-right {\n  margin-left: 10px;\n}\n\n.media-list {\n  margin-left: 0;\n  list-style: none;\n}\n\n.label {\n  padding: .25em .6em;\n  font-size: 75%;\n  font-weight: 500;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  background-color: #999999;\n  border-radius: .25em;\n}\n\na.label:hover,\na.label:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n\n.label-danger {\n  background-color: #d9534f;\n}\n\n.label-danger[href] {\n  background-color: #c9302c;\n}\n\n.label-warning {\n  background-color: #f0ad4e;\n}\n\n.label-warning[href] {\n  background-color: #ec971f;\n}\n\n.label-success {\n  background-color: #5cb85c;\n}\n\n.label-success[href] {\n  background-color: #449d44;\n}\n\n.label-info {\n  background-color: #5bc0de;\n}\n\n.label-info[href] {\n  background-color: #31b0d5;\n}\n\n.badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: 12px;\n  font-weight: bold;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  background-color: #999999;\n  border-radius: 10px;\n}\n\n.badge:empty {\n  display: none;\n}\n\na.badge:hover,\na.badge:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n\n.btn .badge {\n  position: relative;\n  top: -1px;\n}\n\n.btn-mini .badge {\n  top: 0;\n}\n\na.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n  color: #428bca;\n  background-color: #fff;\n}\n\n.nav-pills > li > a > .badge {\n  margin-left: 3px;\n}\n\n@-webkit-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n\n@-moz-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n\n@-ms-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n\n@-o-keyframes progress-bar-stripes {\n  from {\n    background-position: 0 0;\n  }\n  to {\n    background-position: 40px 0;\n  }\n}\n\n@keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n\n.progress {\n  height: 20px;\n  margin-bottom: 20px;\n  overflow: hidden;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n          box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n}\n\n.progress-bar {\n  float: left;\n  width: 0;\n  height: 100%;\n  font-size: 12px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n  background-color: #428bca;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n  -webkit-transition: width 0.6s ease;\n     -moz-transition: width 0.6s ease;\n       -o-transition: width 0.6s ease;\n          transition: width 0.6s ease;\n}\n\n.progress-striped .progress-bar {\n  background-color: #428bca;\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  -webkit-background-size: 40px 40px;\n     -moz-background-size: 40px 40px;\n       -o-background-size: 40px 40px;\n          background-size: 40px 40px;\n}\n\n.progress.active .progress-bar {\n  -webkit-animation: progress-bar-stripes 2s linear infinite;\n     -moz-animation: progress-bar-stripes 2s linear infinite;\n      -ms-animation: progress-bar-stripes 2s linear infinite;\n       -o-animation: progress-bar-stripes 2s linear infinite;\n          animation: progress-bar-stripes 2s linear infinite;\n}\n\n.progress-bar-danger {\n  background-color: #d9534f;\n}\n\n.progress-striped .progress-bar-danger {\n  background-color: #d9534f;\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n\n.progress-bar-success {\n  background-color: #5cb85c;\n}\n\n.progress-striped .progress-bar-success {\n  background-color: #5cb85c;\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n\n.progress-bar-warning {\n  background-color: #f0ad4e;\n}\n\n.progress-striped .progress-bar-warning {\n  background-color: #f0ad4e;\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n\n.progress-bar-info {\n  background-color: #5bc0de;\n}\n\n.progress-striped .progress-bar-info {\n  background-color: #5bc0de;\n  background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n}\n\n.accordion {\n  margin-bottom: 20px;\n}\n\n.accordion-group {\n  margin-bottom: 2px;\n  border: 1px solid #e5e5e5;\n  border-radius: 4px;\n}\n\n.accordion-heading {\n  border-bottom: 0;\n}\n\n.accordion-heading .accordion-toggle {\n  display: block;\n  padding: 8px 15px;\n}\n\n.accordion-toggle {\n  cursor: pointer;\n}\n\n.accordion-inner {\n  padding: 9px 15px;\n  border-top: 1px solid #e5e5e5;\n}\n\n.carousel {\n  position: relative;\n}\n\n.carousel-inner {\n  position: relative;\n  width: 100%;\n  overflow: hidden;\n}\n\n.carousel-inner > .item {\n  position: relative;\n  display: none;\n  -webkit-transition: 0.6s ease-in-out left;\n     -moz-transition: 0.6s ease-in-out left;\n       -o-transition: 0.6s ease-in-out left;\n          transition: 0.6s ease-in-out left;\n}\n\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  display: block;\n  line-height: 1;\n}\n\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  display: block;\n}\n\n.carousel-inner > .active {\n  left: 0;\n}\n\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  position: absolute;\n  top: 0;\n  width: 100%;\n}\n\n.carousel-inner > .next {\n  left: 100%;\n}\n\n.carousel-inner > .prev {\n  left: -100%;\n}\n\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n  left: 0;\n}\n\n.carousel-inner > .active.left {\n  left: -100%;\n}\n\n.carousel-inner > .active.right {\n  left: 100%;\n}\n\n.carousel-control {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  width: 15%;\n  font-size: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\n\n.carousel-control.left {\n  background-color: rgba(0, 0, 0, 0.0001);\n  background-color: transparent;\n  background-image: -webkit-gradient(linear, 0 0, 100% 0, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0.0001)));\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.0001));\n  background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.0001));\n  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0.0001));\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n}\n\n.carousel-control.right {\n  right: 0;\n  left: auto;\n  background-color: rgba(0, 0, 0, 0.5);\n  background-color: transparent;\n  background-image: -webkit-gradient(linear, 0 0, 100% 0, from(rgba(0, 0, 0, 0.0001)), to(rgba(0, 0, 0, 0.5)));\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.0001), rgba(0, 0, 0, 0.5));\n  background-image: -moz-linear-gradient(left, rgba(0, 0, 0, 0.0001), rgba(0, 0, 0, 0.5));\n  background-image: linear-gradient(to right, rgba(0, 0, 0, 0.0001), rgba(0, 0, 0, 0.5));\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n}\n\n.carousel-control:hover,\n.carousel-control:focus {\n  color: #fff;\n  text-decoration: none;\n  opacity: 0.9;\n  filter: alpha(opacity=90);\n}\n\n.carousel-control .glyphicon {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  z-index: 5;\n  display: inline-block;\n  width: 20px;\n  height: 20px;\n  margin-top: -10px;\n  margin-left: -10px;\n}\n\n.carousel-indicators {\n  position: absolute;\n  bottom: 20px;\n  left: 50%;\n  z-index: 5;\n  width: 100px;\n  margin: 0 0 0 -50px;\n  text-align: center;\n  list-style: none;\n}\n\n.carousel-indicators li {\n  display: inline-block;\n  width: 8px;\n  height: 8px;\n  margin-right: 0;\n  margin-left: 0;\n  text-indent: -999px;\n  cursor: pointer;\n  border: 1px solid #fff;\n  border-radius: 5px;\n}\n\n.carousel-indicators .active {\n  background-color: #fff;\n}\n\n.carousel-caption {\n  position: absolute;\n  right: 15%;\n  bottom: 20px;\n  left: 15%;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);\n}\n\n.carousel-caption .btn {\n  text-shadow: none;\n}\n\n@media screen and (min-width: 768px) {\n  .carousel-control .glyphicon {\n    width: 30px;\n    height: 30px;\n    margin-top: -15px;\n    margin-left: -15px;\n    font-size: 30px;\n  }\n  .carousel-caption {\n    right: 20%;\n    left: 20%;\n    padding-bottom: 30px;\n  }\n}\n\n.jumbotron {\n  padding: 30px;\n  margin-bottom: 30px;\n  font-size: 21px;\n  font-weight: 200;\n  line-height: 30px;\n  color: inherit;\n  background-color: #eeeeee;\n}\n\n.jumbotron h1 {\n  line-height: 1;\n  color: inherit;\n}\n\n.jumbotron p {\n  line-height: 1.4;\n}\n\n@media screen and (min-width: 768px) {\n  .jumbotron {\n    padding: 50px 60px;\n    border-radius: 6px;\n  }\n  .jumbotron h1 {\n    font-size: 60px;\n  }\n}\n\n.clearfix:before,\n.clearfix:after {\n  display: table;\n  content: \" \";\n}\n\n.clearfix:after {\n  clear: both;\n}\n\n.pull-right {\n  float: right;\n}\n\n.pull-left {\n  float: left;\n}\n\n.hide {\n  display: none ;\n}\n\n.show {\n  display: block !important;\n}\n\n.invisible {\n  visibility: hidden;\n}\n\n.text-hide {\n  font: 0/0 a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n\n.affix {\n  position: fixed;\n}\n\n@-ms-viewport {\n  width: device-width;\n}\n\n@media screen and (max-width: 400px) {\n  @-ms-viewport {\n    width: 320px;\n  }\n}\n\n.hidden {\n  display: none;\n  visibility: hidden;\n}\n\n.visible-phone {\n  display: inherit !important;\n}\n\n.visible-tablet {\n  display: none !important;\n}\n\n.visible-desktop {\n  display: none !important;\n}\n\n.hidden-phone {\n  display: none !important;\n}\n\n.hidden-tablet {\n  display: inherit !important;\n}\n\n.hidden-desktop {\n  display: inherit !important;\n}\n\n@media (min-width: 768px) and (max-width: 979px) {\n  .visible-phone {\n    display: none !important;\n  }\n  .visible-tablet {\n    display: inherit !important;\n  }\n  .visible-desktop {\n    display: none !important;\n  }\n  .hidden-phone {\n    display: inherit !important;\n  }\n  .hidden-tablet {\n    display: none !important;\n  }\n  .hidden-desktop {\n    display: inherit !important;\n  }\n}\n\n@media (min-width: 980px) {\n  .visible-phone {\n    display: none !important;\n  }\n  .visible-tablet {\n    display: none !important;\n  }\n  .visible-desktop {\n    display: inherit !important;\n  }\n  .hidden-phone {\n    display: inherit !important;\n  }\n  .hidden-tablet {\n    display: inherit !important;\n  }\n  .hidden-desktop {\n    display: none !important;\n  }\n}\n\n.visible-print {\n  display: none !important;\n}\n\n@media print {\n  .visible-print {\n    display: inherit !important;\n  }\n}\n  \n"
  },
  {
    "path": "web/src/main/webapp/css/vendor/css/jQueryjGrowl.css",
    "content": "\ndiv.jGrowl {\n\tz-index: \t\t\t9999;\n\tcolor: \t\t\t\t#fff;\n\tfont-size: \t\t\t12px;\n}\n\n/** Special IE6 Style Positioning **/\ndiv.ie6 {\n\tposition: \t\t\tabsolute;\n}\n\ndiv.ie6.top-right {\n\tright: \t\t\t\tauto;\n\tbottom: \t\t\tauto;\n\tleft: \t\t\t\texpression( ( 0 - jGrowl.offsetWidth + ( document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth ) + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );\n\ttop: \t\t\t\texpression( ( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );\n}\n\ndiv.ie6.top-left {\n\tleft: \t\t\t\texpression( ( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );\n\ttop: \t\t\t\texpression( ( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );\n}\n\ndiv.ie6.bottom-right {\n\tleft: \t\t\t\texpression( ( 0 - jGrowl.offsetWidth + ( document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth ) + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );\n\ttop: \t\t\t\texpression( ( 0 - jGrowl.offsetHeight + ( document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );\n}\n\ndiv.ie6.bottom-left {\n\tleft: \t\t\t\texpression( ( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );\n\ttop: \t\t\t\texpression( ( 0 - jGrowl.offsetHeight + ( document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight ) + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );\n}\n\ndiv.ie6.center {\n\tleft: \t\t\t\texpression( ( 0 + ( ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft ) ) + 'px' );\n\ttop: \t\t\t\texpression( ( 0 + ( ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop ) ) + 'px' );\n\twidth: \t\t\t\t100%;\n}\n\n/** Normal Style Positions **/\ndiv.jGrowl {\n\tposition:\t\t\tabsolute;\n}\n\nbody > div.jGrowl {\n\tposition:\t\t\tfixed;\n}\n\ndiv.jGrowl.top-left {\n\tleft: \t\t\t\t0px;\n\ttop: \t\t\t\t0px;\n}\n\ndiv.jGrowl.top-right {\n\tright: \t\t\t\t0px;\n\ttop: \t\t\t\t0px;\n}\n\ndiv.jGrowl.bottom-left {\n\tleft: \t\t\t\t0px;\n\tbottom:\t\t\t\t0px;\n}\n\ndiv.jGrowl.bottom-right {\n\tright: \t\t\t\t0px;\n\tbottom: \t\t\t0px;\n}\n\ndiv.jGrowl.center {\n\ttop: \t\t\t\t0px;\n\twidth: \t\t\t\t50%;\n\tleft: \t\t\t\t25%;\n}\n\n/** Cross Browser Styling **/\ndiv.center div.jGrowl-notification, div.center div.jGrowl-closer {\n\tmargin-left: \t\tauto;\n\tmargin-right: \t\tauto;\n}\n\ndiv.jGrowl div.jGrowl-notification, div.jGrowl div.jGrowl-closer {\n\t-ms-filter: \t\t\t\"progid:DXImageTransform.Microsoft.Alpha(Opacity=85)\"; \n\tfilter: \t\t\t\tprogid:DXImageTransform.Microsoft.Alpha(Opacity=85); \n\tzoom: \t\t\t\t\t1;\n\twidth: \t\t\t\t\t400px;\n\tpadding: \t\t\t\t10px;\n\tmargin-top: \t\t\t5px;\n\tmargin-bottom: \t\t\t5px;\n\tfont-family: \t\t\tTahoma, Arial, Helvetica, sans-serif;\n\tfont-size: \t\t\t\t1.4em;\n\ttext-align: \t\t\tleft;\n\tdisplay: \t\t\t\tnone;\n\t-moz-border-radius: \t5px;\n\t-webkit-border-radius:\t5px;\n}\n\ndiv.jGrowl-closer {\n\tbackground-color: \t\t#000;\n\topacity: \t\t\t\t.85;\n}\n\ndiv.jGrowl div.jGrowl-notification {\n\tmin-height: \t\t\t40px;\n}\n\ndiv.jGrowl div.jGrowl-notification,\ndiv.jGrowl div.jGrowl-closer {\n\tmargin: \t\t\t\t10px;\n}\n\ndiv.jGrowl div.jGrowl-notification div.jGrowl-header {\n\tfont-weight: \t\t\tbold;\n\tfont-size:\t\t\t\t.85em;\n}\n\ndiv.jGrowl div.jGrowl-notification div.jGrowl-close {\n\tz-index:\t\t\t\t99;\n\tfloat: \t\t\t\t\tright;\n\tfont-weight: \t\t\tbold;\n\tfont-size: \t\t\t\t1em;\n\tcursor:\t\t\t\t\tpointer;\n}\n\ndiv.jGrowl div.jGrowl-closer {\n\tpadding-top: \t\t\t4px;\n\tpadding-bottom: \t\t4px;\n\tcursor: \t\t\t\tpointer;\n\tfont-size:\t\t\t\t.9em;\n\tfont-weight: \t\t\tbold;\n\ttext-align: \t\t\tcenter;\n}\n\n/** Hide jGrowl when printing **/\n@media print {\n\tdiv.jGrowl {\n\t\tdisplay: \t\t\tnone;\n\t}\n}"
  },
  {
    "path": "web/src/main/webapp/index.html",
    "content": "<!DOCTYPE html>\n<head>\n    <meta charset=\"utf-8\">\n    <title>Tatami</title>\n    <meta name=\"author\" content=\"Ippon Technologies\">\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/assets/img/company-logo.ico\">\n    <link href=\"assets/bower_components/ment.io/ment.io/styles.css\" rel=\"stylesheet\" type=\"text/css\">\n\t<link href=\"assets/bower_components/ngtoast/dist/ngToast.min.css\" rel=\"stylesheet\" type=\"text/css\">\n\t<link href=\"assets/vendor/css/bootstrap/css/bootstrap.css\" rel=\"stylesheet\" type=\"text/css\">\n\t<link href=\"assets/bower_components/bootstrap-tour/build/css/bootstrap-tour.css\" rel=\"stylesheet\" type=\"text/css\">\n    <link href=\"/assets/css/tatami.css\" rel=\"stylesheet\" type=\"text/css\">\n\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no, maximum-scale=1.0\">\n    <!--<meta name=\"description\" content=\"\">-->\n\n    <!-- Touch Icons -->\n    <link rel=\"apple-touch-icon\" href=\"/assets/img/apple-touch-icon.png\">\n    <link rel=\"apple-touch-startup-image\" href=\"/assets/img/startup.png\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n\n    <!-- Needed if using HTML5 History API and relative links (Angular routing) -->\n    <!--<base href=\"/\">-->\n\n    <!--[if IE]>\n        <link rel=\"stylesheet\" type=\"text/css\" href=\"/assets/css/ie-only.css\" />\n    <![endif]-->\n    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->\n    <!--[if lt IE 7]>\n    <link rel=\"stylesheet\" href=\"http://blueimp.github.com/cdn/css/bootstrap-ie6.min.css\">\n    <![endif]-->\n    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->\n    <!--[if lt IE 9]>\n    <script src=\"/assets/vendor/js/respond/respond.js\"></script>\n    <script src=\"//html5shim.googlecode.com/svn/trunk/html5.js\"></script>\n    <![endif]-->\n    \n</head>\n<body ng-app=\"TatamiApp\" tour>\n    <toast></toast>\n    <div ui-view=\"topMenu\"></div>\n    <div ui-view></div>\n    <div ui-view=\"footer\"></div>\n    <script src=\"/assets/bower_components/angular/angular.min.js\"></script>\n\t<script src=\"/assets/bower_components/angular-touch/angular-touch.min.js\"></script>\n\t<script src=\"/assets/bower_components/angular-resource/angular-resource.min.js\"></script>\n\t<script src=\"/assets/bower_components/angular-sanitize/angular-sanitize.min.js\"></script>\n\t<script src=\"/assets/bower_components/angular-ui-router/release/angular-ui-router.min.js\"></script>\n\t<script src=\"/assets/bower_components/angular-translate/angular-translate.min.js\"></script>\n\t<script src=\"/assets/bower_components/angular-cookies/angular-cookies.min.js\"></script>\n\t<script src=\"/assets/bower_components/angular-translate-storage-cookie/angular-translate-storage-cookie.min.js\"></script>\n\t<script src=\"/assets/vendor/js/marked/marked.min.js\"></script>\n\t<script src=\"/assets/bower_components/moment/min/moment.min.js\"></script>\n\t<script src=\"/assets/bower_components/moment/locale/fr.js\"></script>\n\t<script src=\"/assets/bower_components/angular-moment/angular-moment.min.js\"></script>\n\t<script src=\"/assets/bower_components/ngInfiniteScroll/build/ng-infinite-scroll.min.js\"></script>\n\t<script src=\"/assets/bower_components/angular-bootstrap/ui-bootstrap.min.js\"></script>\n\t<script src=\"/assets/bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js\"></script>\n\t<script src=\"/assets/bower_components/ment.io/dist/mentio.js\"></script>\n\t<script src=\"/assets/bower_components/angular-animate/angular-animate.min.js\"></script>\n\t<script src=\"/assets/bower_components/ngtoast/dist/ngToast.min.js\"></script>\n\t<script src=\"/assets/bower_components/ng-file-upload/angular-file-upload-shim.min.js\"></script>\n\t<script src=\"/assets/bower_components/ng-file-upload/angular-file-upload.min.js\"></script>\n\t<script src=\"/assets/bower_components/openlayers/OpenLayers.min.js\"></script>\n\t<script src=\"/assets/bower_components/angular-local-storage/dist/angular-local-storage.min.js\"></script>\n\t<script src=\"/assets/bower_components/jquery/dist/jquery.min.js\"></script>\n\t<script src=\"/assets/vendor/css/bootstrap/js/bootstrap.min.js\"></script>\n\t<script src=\"/assets/bower_components/bootstrap-tour/build/js/bootstrap-tour.min.js\"></script>\n\t<script src=\"/assets/bower_components/angular-bootstrap-tour/dist/angular-bootstrap-tour.js\"></script>\n\t<script src=\"/app/TatamiApp.js\"></script>\n\t<script src=\"/app/shared/topMenu/TopMenuModule.js\"></script>\n\t<script src=\"/app/components/login/LoginModule.js\"></script>\n\t<script src=\"/app/components/about/AboutModule.js\"></script>\n\t<script src=\"/app/components/home/HomeModule.js\"></script>\n\t<script src=\"/app/components/account/AccountModule.js\"></script>\n\t<script src=\"/app/components/admin/AdminModule.js\"></script>\n\t<script src=\"/app/components/about/license/LicenseController.js\"></script>\n\t<script src=\"/app/shared/sidebars/home/HomeSidebarModule.js\"></script>\n\t<script src=\"/app/shared/sidebars/home/HomeSidebarController.js\"></script>\n\t<script src=\"/app/shared/sidebars/profile/ProfileSidebarModule.js\"></script>\n\t<script src=\"/app/shared/sidebars/profile/ProfileSidebarController.js\"></script>\n\t<script src=\"/app/components/home/tag/TagHeaderController.js\"></script>\n\t<script src=\"/app/components/home/search/SearchHeaderController.js\"></script>\n\t<script src=\"/app/components/home/group/GroupHeaderController.js\"></script>\n\t<script src=\"/app/components/home/profile/ProfileHeaderController.js\"></script>\n\t<script src=\"/app/components/home/status/StatusController.js\"></script>\n\t<script src=\"/app/shared/lists/status/withoutContext/StatusListController.js\"></script>\n\t<script src=\"/app/shared/lists/user/UserListController.js\"></script>\n\t<script src=\"/app/shared/topMenu/post/PostModule.js\"></script>\n\t<script src=\"/app/shared/topMenu/post/PostController.js\"></script>\n\t<script src=\"/app/shared/footer/FooterModule.js\"></script>\n\t<script src=\"/app/shared/footer/FooterController.js\"></script>\n\t<script src=\"/app/components/home/welcome/WelcomeController.js\"></script>\n\t<script src=\"/app/components/admin/AdminController.js\"></script>\n\t<script src=\"/app/components/admin/AdminService.js\"></script>\n\t<script src=\"/app/components/account/AccountController.js\"></script>\n\t<script src=\"/app/components/account/FormController.js\"></script>\n\t<script src=\"/app/components/account/profile/ProfileModule.js\"></script>\n\t<script src=\"/app/components/account/profile/ProfileController.js\"></script>\n\t<script src=\"/app/components/account/preferences/PreferencesModule.js\"></script>\n\t<script src=\"/app/components/account/preferences/PreferencesController.js\"></script>\n\t<script src=\"/app/components/account/preferences/PreferencesService.js\"></script>\n\t<script src=\"/app/components/account/password/PasswordModule.js\"></script>\n\t<script src=\"/app/components/account/password/PasswordController.js\"></script>\n\t<script src=\"/app/components/account/password/PasswordService.js\"></script>\n\t<script src=\"/app/components/account/files/FilesModule.js\"></script>\n\t<script src=\"/app/components/account/files/FilesController.js\"></script>\n\t<script src=\"/app/components/account/files/FilesService.js\"></script>\n\t<script src=\"/app/components/account/users/UsersModule.js\"></script>\n\t<script src=\"/app/components/account/users/UsersController.js\"></script>\n\t<script src=\"/app/components/account/groups/GroupsModule.js\"></script>\n\t<script src=\"/app/components/account/groups/GroupsController.js\"></script>\n\t<script src=\"/app/components/account/groups/manage/GroupsManageController.js\"></script>\n\t<script src=\"/app/components/account/groups/creation/GroupsCreateController.js\"></script>\n\t<script src=\"/app/components/account/groups/list/GroupListController.js\"></script>\n\t<script src=\"/app/components/account/tags/TagsModule.js\"></script>\n\t<script src=\"/app/components/account/tags/TagsController.js\"></script>\n\t<script src=\"/app/components/account/topPosters/TopPostersModule.js\"></script>\n\t<script src=\"/app/components/account/topPosters/TopPostersController.js\"></script>\n\t<script src=\"/app/components/login/LoginModule.js\"></script>\n\t<script src=\"/app/components/login/manual/ManualLoginController.js\"></script>\n\t<script src=\"/app/components/login/recoverPassword/RecoverPasswordController.js\"></script>\n\t<script src=\"/app/components/login/register/RegisterController.js\"></script>\n\t<script src=\"/app/components/login/google/GoogleLoginController.js\"></script>\n\t<script src=\"/app/components/login/email/EmailRegistrationController.js\"></script>\n\t<script src=\"/app/components/login/RegistrationService.js\"></script>\n\t<script src=\"/app/shared/configs/MarkedConfig.js\"></script>\n\t<script src=\"/app/shared/configs/MomentConfig.js\"></script>\n\t<script src=\"/app/shared/configs/TranslateConfig.js\"></script>\n\t<script src=\"/app/shared/filters/MarkdownFilter.js\"></script>\n\t<script src=\"/app/shared/filters/EmoticonFilter.js\"></script>\n\t<script src=\"/app/shared/filters/PlaceholderFilter.js\"></script>\n\t<script src=\"/app/shared/services/HomeService.js\"></script>\n\t<script src=\"/app/shared/services/StatusService.js\"></script>\n\t<script src=\"/app/shared/services/ProfileService.js\"></script>\n\t<script src=\"/app/shared/services/UserService.js\"></script>\n\t<script src=\"/app/shared/services/GroupService.js\"></script>\n\t<script src=\"/app/shared/services/TagService.js\"></script>\n\t<script src=\"/app/shared/services/GeolocService.js\"></script>\n\t<script src=\"/app/shared/services/SearchService.js\"></script>\n\t<script src=\"/app/shared/services/TopPostersService.js\"></script>\n\t<script src=\"/app/shared/services/UserSession.js\"></script>\n\t<script src=\"/app/shared/services/AuthenticationService.js\"></script>\n\t<script src=\"/app/shared/topMenu/TopMenuController.js\"></script>\n</body>\n</html>"
  },
  {
    "path": "web/src/main/webapp/index.html.tpl",
    "content": "<!DOCTYPE html>\n<head>\n    <meta charset=\"utf-8\">\n    <title>Tatami</title>\n    <meta name=\"author\" content=\"Ippon Technologies\">\n    <link rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/assets/img/company-logo.ico\">\n    <%= cssTags %>\n    <link href=\"/assets/css/tatami.css\" rel=\"stylesheet\" type=\"text/css\">\n\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no, maximum-scale=1.0\">\n    <!--<meta name=\"description\" content=\"\">-->\n\n    <!-- Touch Icons -->\n    <link rel=\"apple-touch-icon\" href=\"/assets/img/apple-touch-icon.png\">\n    <link rel=\"apple-touch-startup-image\" href=\"/assets/img/startup.png\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\" />\n\n    <!-- Needed if using HTML5 History API and relative links (Angular routing) -->\n    <!--<base href=\"/\">-->\n\n    <!--[if IE]>\n        <link rel=\"stylesheet\" type=\"text/css\" href=\"/assets/css/ie-only.css\" />\n    <![endif]-->\n    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->\n    <!--[if lt IE 7]>\n    <link rel=\"stylesheet\" href=\"http://blueimp.github.com/cdn/css/bootstrap-ie6.min.css\">\n    <![endif]-->\n    <!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->\n    <!--[if lt IE 9]>\n    <script src=\"/assets/vendor/js/respond/respond.js\"></script>\n    <script src=\"//html5shim.googlecode.com/svn/trunk/html5.js\"></script>\n    <![endif]-->\n    \n</head>\n<body ng-app=\"TatamiApp\" tour>\n    <toast></toast>\n    <div ui-view=\"topMenu\"></div>\n    <div ui-view></div>\n    <div ui-view=\"footer\"></div>\n    <%= jsTags %>\n</body>\n</html>"
  },
  {
    "path": "web/src/main/webapp/index.jsp",
    "content": "<%@ page language=\"java\" pageEncoding=\"UTF-8\" contentType=\"text/html; charset=utf-8\" %>\n<html>\n<head>\n    <title></title>\n    <script type=\"text/javascript\">window.location.href = '<%=request.getContextPath()%>/tatami/'</script>\n</head>\n<body>\nIf you are not redirected automatically, click\n<a href=\"<%=request.getContextPath()%>/tatami/\">here</a>.\n</body>\n</html>\n"
  },
  {
    "path": "web/src/main/webapp/robots.txt",
    "content": "User-agent: *\nDisallow: /tatami/authentication\nDisallow: /tatami/rest\nDisallow: /tatami/account"
  },
  {
    "path": "web/src/main/webapp/sitemap.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset\n      xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\"\n      xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n      xsi:schemaLocation=\"http://www.sitemaps.org/schemas/sitemap/0.9\n            http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd\">\n\n\t<url>\n\t\t<loc>https://tatami.ippon.fr/tatami/login</loc>\n\t\t<priority>1.0</priority>\n   </url>\n   <url>\n\t\t<loc>https://tatami.ippon.fr/tatami/presentation</loc>\n\t\t<priority>0.8</priority>\n   </url>\n   <url>\n\t\t<loc>https://tatami.ippon.fr/tatami/tos</loc>\n\t\t<priority>0.5</priority>\n   </url>\n   <url>\n\t\t<loc>https://tatami.ippon.fr/tatami/license</loc>\n\t\t<priority>0.5</priority>\n   </url>\n</urlset>"
  },
  {
    "path": "web/src/test/java/fr/ippon/tatami/web/rest/GroupControllerTest.java",
    "content": "package fr.ippon.tatami.web.rest;\n\nimport com.fasterxml.jackson.core.type.TypeReference;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport fr.ippon.tatami.AbstractCassandraTatamiTest;\nimport fr.ippon.tatami.domain.Group;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.GroupService;\nimport fr.ippon.tatami.service.UserService;\nimport fr.ippon.tatami.service.dto.UserGroupDTO;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.springframework.http.MediaType;\nimport org.springframework.test.util.ReflectionTestUtils;\nimport org.springframework.test.web.servlet.MockMvc;\nimport org.springframework.test.web.servlet.setup.MockMvcBuilders;\n\nimport javax.inject.Inject;\nimport java.util.Collection;\nimport java.util.List;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertTrue;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\nimport static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;\nimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;\n\npublic class GroupControllerTest extends AbstractCassandraTatamiTest {\n\n    private MockMvc mockMvc;\n\n    @Inject\n    private GroupService groupService;\n\n    @Inject\n    private UserService userService;\n\n    @Before\n    public void setup() {\n\n        GroupController groupController = new GroupController();\n\n        User authenticateUser = constructAUser(\"userWhoHasGroup@ippon.fr\");\n        AuthenticationService mockAuthenticationService = mock(AuthenticationService.class);\n        when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser);\n        ReflectionTestUtils.setField(groupController, \"authenticationService\", mockAuthenticationService);\n        ReflectionTestUtils.setField(groupController, \"groupService\", groupService);\n        ReflectionTestUtils.setField(groupController, \"userService\", userService);\n\n        ReflectionTestUtils.setField(groupService, \"authenticationService\", mockAuthenticationService);\n        ReflectionTestUtils.setField(userService, \"authenticationService\", mockAuthenticationService);\n\n        this.mockMvc = MockMvcBuilders.standaloneSetup(groupController).build();\n    }\n\n    @Test\n    public void testCreateAndArchiveGroup() throws Exception {\n\n        // Test group creation\n        mockMvc.perform(post(\"/rest/groups\")\n                .contentType(MediaType.APPLICATION_JSON)\n                .content(\"{\\\"publicGroup\\\":false,\\\"archivedGroup\\\":false,\\\"name\\\":\\\"Test group\\\",\" +\n                        \"\\\"description\\\":\\\"This is a test group\\\"}\"))\n                .andExpect(status().isOk());\n\n        String groupsAsJson = mockMvc.perform(get(\"/rest/groupmemberships/lookup\")\n                .param(\"screen_name\", \"userWhoHasGroup\")\n                .accept(MediaType.APPLICATION_JSON))\n                .andExpect(status().isOk())\n                .andExpect(content().contentType(\"application/json\"))\n                .andExpect(jsonPath(\"$.[0].name\").value(\"Test group\"))\n                .andReturn().getResponse().getContentAsString();\n\n        Collection<Group> groups =\n                new ObjectMapper().readValue(groupsAsJson, new TypeReference<List<Group>>() {\n\n                });\n\n        assertEquals(1, groups.size());\n\n        String groupId = groups.iterator().next().getGroupId();\n\n        mockMvc.perform(get(\"/rest/groups/\" + groupId)\n                .accept(MediaType.APPLICATION_JSON))\n                .andExpect(status().isOk())\n                .andExpect(content().contentType(\"application/json\"))\n                .andExpect(jsonPath(\"$.name\").value(\"Test group\"));\n\n        // Test group update\n\n        mockMvc.perform(put(\"/rest/groups/\" + groupId)\n                .contentType(MediaType.APPLICATION_JSON)\n                .content(\"{\\\"publicGroup\\\":false,\\\"archivedGroup\\\":false,\\\"name\\\":\\\"Updated test group\\\",\" +\n                        \"\\\"description\\\":\\\"This is a test group\\\"}\")\n                .accept(MediaType.APPLICATION_JSON))\n                .andExpect(status().isOk());\n\n        mockMvc.perform(get(\"/rest/groups/\" + groupId)\n                .accept(MediaType.APPLICATION_JSON))\n                .andExpect(status().isOk())\n                .andExpect(content().contentType(\"application/json\"))\n                .andExpect(jsonPath(\"$.name\").value(\"Updated test group\"));\n\n        // Test adding and removing a user\n        assertEquals(1, groupSize(groupId));\n\n        mockMvc.perform(put(\"/rest/groups/\" + groupId + \"/members/uuser\")\n                .contentType(MediaType.APPLICATION_JSON)\n                .accept(MediaType.APPLICATION_JSON))\n                .andExpect(status().isOk());\n\n        assertEquals(2, groupSize(groupId));\n\n        mockMvc.perform(delete(\"/rest/groups/\" + groupId + \"/members/uuser\")\n                .contentType(MediaType.APPLICATION_JSON)\n                .accept(MediaType.APPLICATION_JSON))\n                .andExpect(status().isOk());\n\n        assertEquals(1, groupSize(groupId));\n\n        // Test group archive\n\n        mockMvc.perform(put(\"/rest/groups/\" + groupId)\n                .contentType(MediaType.APPLICATION_JSON)\n                .content(\"{\\\"publicGroup\\\":false,\\\"archivedGroup\\\":true,\\\"name\\\":\\\"Updated test group\\\",\" +\n                        \"\\\"description\\\":\\\"This is a test group\\\"}\")\n                .accept(MediaType.APPLICATION_JSON))\n                .andExpect(status().isOk());\n\n        groupsAsJson = mockMvc.perform(get(\"/rest/groupmemberships/lookup\")\n                .param(\"screen_name\", \"userWhoHasGroup\")\n                .accept(MediaType.APPLICATION_JSON))\n                .andExpect(status().isOk())\n                .andExpect(content().contentType(\"application/json\"))\n                .andReturn().getResponse().getContentAsString();\n\n        groups = new ObjectMapper().readValue(groupsAsJson, new TypeReference<List<Group>>() {\n\n        });\n\n        assertTrue(groups.iterator().next().isArchivedGroup());\n    }\n\n    private int groupSize(String groupId) throws Exception {\n        String usersAsJson = mockMvc.perform(get(\"/rest/groups/\" + groupId + \"/members/\")\n                .accept(MediaType.APPLICATION_JSON))\n                .andExpect(status().isOk())\n                .andExpect(content().contentType(\"application/json\"))\n                .andExpect(jsonPath(\"$.[0].lastName\").value(\"WhoHasGroup\"))\n                .andExpect(jsonPath(\"$.[0].isMember\").value(true))\n                .andReturn().getResponse().getContentAsString();\n\n        Collection<UserGroupDTO> userGroupDTOs =\n                new ObjectMapper().readValue(usersAsJson, new TypeReference<List<UserGroupDTO>>() {\n\n                });\n\n        return userGroupDTOs.size();\n    }\n}\n"
  },
  {
    "path": "web/src/test/java/fr/ippon/tatami/web/rest/TagControllerTest.java",
    "content": "package fr.ippon.tatami.web.rest;\n\nimport fr.ippon.tatami.AbstractCassandraTatamiTest;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.UserTagRepository;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.StatusUpdateService;\nimport fr.ippon.tatami.service.TagMembershipService;\nimport fr.ippon.tatami.service.TimelineService;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.springframework.http.MediaType;\nimport org.springframework.test.util.ReflectionTestUtils;\nimport org.springframework.test.web.servlet.MockMvc;\nimport org.springframework.test.web.servlet.setup.MockMvcBuilders;\n\nimport javax.inject.Inject;\n\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\nimport static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;\nimport static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;\nimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;\n\npublic class TagControllerTest extends AbstractCassandraTatamiTest {\n\n    @Inject\n    private TimelineService timelineService;\n\n    @Inject\n    private StatusUpdateService statusUpdateService;\n\n    @Inject\n    private TagMembershipService tagMembershipService;\n\n    @Inject\n    private UserTagRepository userTagRepository;\n\n    private MockMvc mockMvc;\n\n    private MockMvc timelineMockMvc;\n\n    private static final String username = \"timelineUser\";\n\n    @Before\n    public void setup() {\n\n        TagController tagController = new TagController();\n        ReflectionTestUtils.setField(tagController, \"timelineService\", timelineService);\n        ReflectionTestUtils.setField(tagController, \"tagMembershipService\", tagMembershipService);\n        ReflectionTestUtils.setField(tagController, \"userTagRepository\", userTagRepository);\n\n        User authenticateUser = constructAUser(username + \"@ippon.fr\");\n        AuthenticationService mockAuthenticationService = mock(AuthenticationService.class);\n        when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser);\n        ReflectionTestUtils.setField(tagController, \"authenticationService\", mockAuthenticationService);\n        ReflectionTestUtils.setField(timelineService, \"authenticationService\", mockAuthenticationService);\n        ReflectionTestUtils.setField(statusUpdateService, \"authenticationService\", mockAuthenticationService);\n        ReflectionTestUtils.setField(tagMembershipService, \"authenticationService\", mockAuthenticationService);\n        this.mockMvc = MockMvcBuilders.standaloneSetup(tagController).build();\n\n        TimelineController timelineController = new TimelineController();\n        ReflectionTestUtils.setField(timelineController, \"timelineService\", timelineService);\n        ReflectionTestUtils.setField(timelineController, \"statusUpdateService\", statusUpdateService);\n        this.timelineMockMvc = MockMvcBuilders.standaloneSetup(timelineController).build();\n    }\n\n    @Test\n    public void testTagline() throws Exception {\n        mockMvc.perform(get(\"/rest/tags/testTag/tag_timeline\")\n                .accept(MediaType.APPLICATION_JSON))\n                .andExpect(status().isOk())\n                .andExpect(content().contentType(\"application/json\"))\n                .andExpect(jsonPath(\"$.[0]\").doesNotExist());\n\n        timelineMockMvc.perform(post(\"/rest/statuses/\")\n                .contentType(MediaType.APPLICATION_JSON)\n                .content(\"{\\\"content\\\":\\\"Test status with a tag #testTag\\\"}\"))\n                .andExpect(status().isOk());\n\n        mockMvc.perform(get(\"/rest/tags/testTag/tag_timeline\")\n                .accept(MediaType.APPLICATION_JSON))\n                .andExpect(status().isOk())\n                .andExpect(content().contentType(\"application/json\"))\n                .andExpect(jsonPath(\"$.[0].content\").value(\"Test status with a tag #testTag\"));\n\n    }\n\n    @Test\n    public void testTagMembership() throws Exception {\n\n        mockMvc.perform(get(\"/rest/tagmemberships/list\")\n                .accept(MediaType.APPLICATION_JSON))\n                .andExpect(status().isOk())\n                .andExpect(content().contentType(\"application/json\"))\n                .andExpect(jsonPath(\"$.[0]\").doesNotExist());\n\n        mockMvc.perform(post(\"/rest/tagmemberships/create\")\n                .contentType(MediaType.APPLICATION_JSON)\n                .content(\"{\\\"name\\\":\\\"testTag\\\"}\"))\n                .andExpect(status().isOk());\n\n        mockMvc.perform(get(\"/rest/tagmemberships/list\")\n                .accept(MediaType.APPLICATION_JSON))\n                .andExpect(status().isOk())\n                .andExpect(content().contentType(\"application/json\"))\n                .andExpect(jsonPath(\"$.[0].name\").value(\"testTag\"));\n\n        mockMvc.perform(post(\"/rest/tagmemberships/destroy\")\n                .contentType(MediaType.APPLICATION_JSON)\n                .content(\"{\\\"name\\\":\\\"testTag\\\"}\"))\n                .andExpect(status().isOk());\n\n        mockMvc.perform(get(\"/rest/tagmemberships/list\")\n                .accept(MediaType.APPLICATION_JSON))\n                .andExpect(status().isOk())\n                .andExpect(content().contentType(\"application/json\"))\n                .andExpect(jsonPath(\"$.[0]\").doesNotExist());\n    }\n}\n"
  },
  {
    "path": "web/src/test/java/fr/ippon/tatami/web/rest/TimelineControllerTest.java",
    "content": "package fr.ippon.tatami.web.rest;\n\nimport com.fasterxml.jackson.core.type.TypeReference;\nimport com.fasterxml.jackson.databind.ObjectMapper;\nimport fr.ippon.tatami.AbstractCassandraTatamiTest;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.GroupService;\nimport fr.ippon.tatami.service.StatusUpdateService;\nimport fr.ippon.tatami.service.TimelineService;\nimport fr.ippon.tatami.service.dto.StatusDTO;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.springframework.http.MediaType;\nimport org.springframework.test.util.ReflectionTestUtils;\nimport org.springframework.test.web.servlet.MockMvc;\nimport org.springframework.test.web.servlet.setup.MockMvcBuilders;\n\nimport javax.inject.Inject;\nimport java.util.Collection;\nimport java.util.List;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\nimport static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;\nimport static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;\nimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;\n\npublic class TimelineControllerTest  extends AbstractCassandraTatamiTest{\n\n    @Inject\n    private TimelineService timelineService;\n\n    @Inject\n    private StatusUpdateService statusUpdateService;\n\n    @Inject\n    private GroupService groupService;\n\n    private MockMvc mockMvc;\n\n    private static final String username = \"timelineUser\";\n\n    @Before\n    public void setup() {\n\n        TimelineController timelineController = new TimelineController();\n        ReflectionTestUtils.setField(timelineController, \"timelineService\", timelineService);\n        ReflectionTestUtils.setField(timelineController, \"statusUpdateService\", statusUpdateService);\n        ReflectionTestUtils.setField(timelineController, \"groupService\", groupService);\n\n        User authenticateUser = constructAUser(username + \"@ippon.fr\");\n        AuthenticationService mockAuthenticationService = mock(AuthenticationService.class);\n        when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser);\n        ReflectionTestUtils.setField(timelineController, \"authenticationService\", mockAuthenticationService);\n        ReflectionTestUtils.setField(timelineService, \"authenticationService\", mockAuthenticationService);\n        ReflectionTestUtils.setField(statusUpdateService, \"authenticationService\", mockAuthenticationService);\n        this.mockMvc = MockMvcBuilders.standaloneSetup(timelineController).build();\n    }\n\n    @Test\n    public void testStatusUpdate() throws Exception {\n        mockMvc.perform(post(\"/rest/statuses/\")\n                .contentType(MediaType.APPLICATION_JSON)\n                .content(\"{\\\"content\\\":\\\"Test status with Spring TestContext\\\"}\"))\n                .andExpect(status().isOk());\n\n        mockMvc.perform(get(\"/rest/statuses/home_timeline\")\n                .accept(MediaType.APPLICATION_JSON))\n                .andExpect(status().isOk())\n                .andExpect(content().contentType(\"application/json\"))\n                .andExpect(jsonPath(\"$.[0].content\").value(\"Test status with Spring TestContext\"));\n\n        mockMvc.perform(get(\"/rest/statuses/\" + username + \"/timeline\")\n                .accept(MediaType.APPLICATION_JSON))\n                .andExpect(status().isOk())\n                .andExpect(content().contentType(\"application/json\"))\n                .andExpect(jsonPath(\"$.[0].content\").value(\"Test status with Spring TestContext\"));\n    }\n\n    @Test\n    public void testStatusReply() throws Exception {\n        //Create status\n        mockMvc.perform(post(\"/rest/statuses/\")\n                .contentType(MediaType.APPLICATION_JSON)\n                .content(\"{\\\"content\\\":\\\"Test discussion\\\"}\"))\n                .andExpect(status().isOk());\n\n        String statusAsJson = mockMvc.perform(get(\"/rest/statuses/home_timeline\")\n                .accept(MediaType.APPLICATION_JSON))\n                .andExpect(status().isOk())\n                .andExpect(content().contentType(\"application/json\"))\n                .andReturn().getResponse().getContentAsString();\n\n        Collection<StatusDTO> statusDTOs = new ObjectMapper().readValue(statusAsJson,\n                new TypeReference<List<StatusDTO>>() {\n\n                });\n\n        String statusId = statusDTOs.iterator().next().getStatusId();\n\n        mockMvc.perform(post(\"/rest/statuses/\")\n                .contentType(MediaType.APPLICATION_JSON)\n                .content(\"{\\\"replyTo\\\":\\\"\" + statusId + \"\\\", \\\"content\\\":\\\"Reply discussion\\\"}\"))\n                .andExpect(status().isOk());\n\n        String replyAsJson = mockMvc.perform(get(\"/rest/statuses/home_timeline\")\n                .accept(MediaType.APPLICATION_JSON))\n                .andExpect(status().isOk())\n                .andExpect(content().contentType(\"application/json\"))\n                .andReturn().getResponse().getContentAsString();\n\n        statusDTOs = new ObjectMapper().readValue(replyAsJson,\n                new TypeReference<List<StatusDTO>>() {\n\n                });\n\n        StatusDTO statusDTO = statusDTOs.iterator().next();\n        assertEquals(\"Reply discussion\", statusDTO.getContent());\n        assertEquals(statusId, statusDTO.getReplyTo());\n    }\n}\n"
  },
  {
    "path": "web/src/test/java/fr/ippon/tatami/web/rest/UserControllerTest.java",
    "content": "package fr.ippon.tatami.web.rest;\n\nimport fr.ippon.tatami.AbstractCassandraTatamiTest;\nimport fr.ippon.tatami.domain.User;\nimport fr.ippon.tatami.repository.RegistrationRepository;\nimport fr.ippon.tatami.security.AuthenticationService;\nimport fr.ippon.tatami.service.UserService;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.springframework.http.MediaType;\nimport org.springframework.test.util.ReflectionTestUtils;\nimport org.springframework.test.web.servlet.MockMvc;\nimport org.springframework.test.web.servlet.setup.MockMvcBuilders;\n\nimport javax.inject.Inject;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertNotNull;\nimport static org.mockito.Mockito.mock;\nimport static org.mockito.Mockito.when;\nimport static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;\nimport static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;\nimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;\n\npublic class UserControllerTest extends AbstractCassandraTatamiTest {\n\n    @Inject\n    private UserService userService;\n\n    @Inject\n    private RegistrationRepository registrationRepository;\n\n    private MockMvc restUserMockMvc;\n\n    @Before\n    public void setup() {\n        mockAuthentication(\"jdubois@ippon.fr\");\n        UserController userController = new UserController();\n        ReflectionTestUtils.setField(userController, \"userService\", userService);\n        this.restUserMockMvc = MockMvcBuilders.standaloneSetup(userController).build();\n    }\n\n    @Test\n    public void testUsersShow() throws Exception {\n        restUserMockMvc.perform(get(\"/rest/users/jdubois\")\n                .accept(MediaType.APPLICATION_JSON))\n                .andExpect(status().isOk())\n                .andExpect(content().contentType(\"application/json\"))\n                .andExpect(jsonPath(\"$.firstName\").value(\"Julien\"));\n    }\n\n    @Test\n    public void testUserRegistration() throws Exception {\n        // existing user\n        restUserMockMvc.perform(post(\"/rest/users?email=uuser@ippon.fr\")\n                .contentType(MediaType.APPLICATION_JSON))\n                .andExpect(status().isNotModified());\n\n        // new user\n        String newUserLogin = \"registrationUser@ippon.fr\";\n        restUserMockMvc.perform(post(\"/rest/users?email=\" + newUserLogin)\n                .contentType(MediaType.APPLICATION_JSON))\n                .andExpect(status().isCreated());\n\n        String registrationKey = registrationRepository._getAllRegistrationKeyByLogin().get(newUserLogin.toLowerCase());\n        assertNotNull(registrationKey);\n\n        String validatedLogin = userService.validateRegistration(registrationKey);\n        assertEquals(newUserLogin.toLowerCase(), validatedLogin);\n\n        User validatedUser = userService.getUserByLogin(validatedLogin);\n        assertNotNull(validatedUser);\n    }\n\n    private void mockAuthentication(String login) {\n        User authenticateUser = constructAUser(login);\n        AuthenticationService mockAuthenticationService = mock(AuthenticationService.class);\n        when(mockAuthenticationService.getCurrentUser()).thenReturn(authenticateUser);\n        ReflectionTestUtils.setField(userService, \"authenticationService\", mockAuthenticationService);\n    }\n}\n"
  },
  {
    "path": "web/src/test/javascript/webapp/app/components/about/license/LicenseController_spec.js",
    "content": "describe(\"License controller test\", function() {\n    beforeEach(module('ui.router'));\n    beforeEach(module('AboutModule'));\n\n    beforeEach(inject(function(_$controller_) {\n       $controller = _$controller_; \n    }));\n    it('SANITY', function(){\n        expect(true).toBeTruthy();\n    });\n    it('Checks that LicenseController injects current year in the copyright', function() {\n        var $scope = {};\n        var controller = $controller('LicenseController', {$scope: $scope});\n        expect($scope.time).toBe(\" 2012-\"+new Date().getFullYear()+\" \");\n    });\n\n});\n"
  },
  {
    "path": "web/src/test/javascript/webapp/app/components/account/PasswordModule_spec.js",
    "content": "describe(\"Password controller test\", function() {\n    var ctrl, passService;\n    beforeEach(module('ui.router'));\n    beforeEach(module('PasswordModule'));\n    beforeEach(module('pascalprecht.translate'));\n    \n    //Mocked password service:\n    beforeEach(module({\n        PasswordService: {\n            save: function() {\n            }\n        }\n    }));\n\n\n    //mocking ngToast\n    beforeEach(module({\n        ngToast: {\n            create: function() { \n            }\n        }\n    }));\n\n\n    beforeEach(inject(function($rootScope, _$controller_, _$translate_, _PasswordService_, _ngToast_) {\n        $scope = $rootScope.$new();\n        $translate = _$translate_;\n        $controller = _$controller_;\n        passService = _PasswordService_;\n        spyOn(passService, 'save');\n        ctrl = $controller('PasswordController', {\n            $scope : $scope,\n            $translate : $translate,\n            'PasswordService' : passService,\n            'ngToast': _ngToast_,\n        });\n    }));\n\n\n    it('default password view', function() {\n       expect($scope.status.oldEmpty).toBeFalsy();\n       expect($scope.status.newEmpty).toBeFalsy();\n       expect($scope.status.confirmWrong).toBeFalsy();\n       expect($scope.status.confirmChange).toBeFalsy();\n    });\n\n    it('Empty old password', function() {\n        $scope.changePassword();\n        \n        expect($scope.status.oldEmpty).toBeTruthy();\n        expect($scope.status.newEmpty).toBeFalsy();\n        expect($scope.status.confirmWrong).toBeFalsy();\n        expect($scope.status.confirmChange).toBeFalsy();\n    });\n\n\n    it('Empty new password', function() {\n        $scope.password.oldPassword = \"oldy\";\n        $scope.changePassword();\n      \n        expect($scope.status.oldEmpty).toBeFalsy();\n        expect($scope.status.newEmpty).toBeTruthy();\n        expect($scope.status.confirmWrong).toBeFalsy();\n        expect($scope.status.confirmChange).toBeFalsy();\n        expect(passService.save).not.toHaveBeenCalled();\n    });\n\n    it('Password mismatch', function() {\n        $scope.password.oldPassword = \"oldy\";\n        $scope.password.newPassword = \"but\";\n        $scope.password.newPasswordConfirmation = \"goody\";\n        $scope.changePassword();\n       \n        expect($scope.status.oldEmpty).toBeFalsy();\n        expect($scope.status.newEmpty).toBeFalsy();\n        expect($scope.status.confirmWrong).toBeTruthy();\n        expect($scope.status.confirmChange).toBeFalsy();\n        expect(passService.save).not.toHaveBeenCalled();\n    });\n\n    \n    it('Successful password change', function() {\n        $scope.password.oldPassword = \"oldy\";\n        $scope.password.newPassword = \"newer\";\n        $scope.password.newPasswordConfirmation = \"newer\";\n        $scope.changePassword();\n\n        expect(passService.save).toHaveBeenCalled();\n    });\n\n    it('Reset', function() {\n        $scope.password.oldPassword = \"oldy\";\n        $scope.password.newPassword = \"newer\";\n        $scope.password.newPasswordConfirmation = \"test\";\n        $scope.changePassword();\n\n        expect($scope.status.oldEmpty).toBeFalsy();\n        expect($scope.status.newEmpty).toBeFalsy();\n        expect($scope.status.confirmWrong).toBeTruthy();\n        expect($scope.status.confirmChange).toBeFalsy();\n   \n        $scope.reset();\n\n        expect($scope.status.oldEmpty).toBeFalsy();\n        expect($scope.status.newEmpty).toBeFalsy();\n        expect($scope.status.confirmWrong).toBeFalsy();\n        expect($scope.status.confirmChange).toBeFalsy();\n    });\n});\n"
  },
  {
    "path": "web/src/test/javascript/webapp/app/components/account/preferences/Preferences_spec.js",
    "content": "describe(\"Preferences Tests\", function() {\n    var ctrl, preferencesService;\n    beforeEach(module('ui.router'));\n    beforeEach(module('PreferencesModule'));\n    beforeEach(module('pascalprecht.translate'));\n\n    //mocking ngToast\n    beforeEach(module({\n        ngToast: {\n            create: function() { \n            }\n        },\n        PreferencesService : {\n            save: function(){\n\n            }\n        }\n    }));\n\n\n    beforeEach(inject(function($rootScope, _$controller_, _$translate_, _PreferencesService_, _ngToast_) {\n        $scope = $rootScope.$new();\n        $translate = _$translate_;\n        $controller = _$controller_;\n        preferencesService = _PreferencesService_;\n        var prefs = {\n            test : \"accepted\"\n        };\n\n        spyOn(preferencesService, 'save');\n        ctrl = $controller('PreferencesController', {\n            $scope : $scope,\n            $translate : $translate,\n            'prefs' : prefs,\n            'PreferencesService' : preferencesService,\n            'ngToast': _ngToast_\n        });\n    }));\n\n    //Tests that the test can be run, even if nonsensical\n    it('sanity check', function() {\n           expect(true).toBeTruthy();\n    });\n    //this proves that the controller is loading properly, and tests below are valid.\n    it ('test working properly', function(){\n        console.log(\"Scope prefs: \" + $scope.prefs.test);\n        expect($scope.prefs!==null);\n        expect($scope.prefs.test===\"accepted\");\n\n    });\n    it ('can save preferences', function(){\n        $scope.savePrefs();\n        expect(preferencesService.save).toHaveBeenCalled();\n    });\n});\n"
  },
  {
    "path": "web/src/test/javascript/webapp/app/components/home/status/StatusController_spec.js",
    "content": "describe(\"Status Controller Test\", function () {\n    var ctrl, statusService;\n    beforeEach(module('ui.router'));\n    beforeEach(module('HomeModule'));\n\n    beforeEach(module('pascalprecht.translate'));\n\n\n    //Mocked password service:\n    beforeEach(module({\n            UserSession: {\n                isAuthenticated: function () {\n                    return \"true\";\n                },\n\n                isUserResolved: function () {\n                    return true;\n                },\n\n                setLoginState: function (loggedIn) {\n                },\n\n                clearSession: function () {\n                },\n\n                getUser: function () {\n                },\n\n                authenticate: function (force) {\n                }\n            },\n            StatusService: {\n                save: function () {\n                }\n            }\n            ,\n            localStorageService: {\n                clearAll: function () {\n\n                }\n                ,\n                get: function (token) {\n                    return true;\n                }\n            }\n        })\n    );\n\n\n    beforeEach(inject(function ($rootScope, _$controller_, _$translate_, _StatusService_, _localStorageService_) {\n        $scope = $rootScope.$new();\n        $translate = _$translate_;\n        statusService = _StatusService_;\n        var storageService = _localStorageService_;\n        spyOn(statusService, 'save');\n        ctrl = _$controller_('StatusController', {\n            $scope: $scope,\n            $translate: $translate,\n            'StatusService': statusService,\n            'localStorageService': storageService,\n            'profile': {},\n            'status': 'teehee',\n            'context': {discussionStatuses: []},\n            'userRoles': {roles: ['', '', 'ROLE_ADMIN']}\n        });\n    }));\n\n\n    it('SANITY', function () {\n        expect(true).toBeTruthy();\n    });\n    it('Is Admin check', function () {\n        expect($scope.isAdmin).toBeTruthy();\n    });\n    it('Status accepted without discussion', function () {\n        expect($scope.statuses[0] == 'teehee').toBeTruthy();\n    });\n})\n;\n"
  }
]